aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-05-07 19:03:56 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-05-07 19:03:56 +0000
commitb381dc0b97225555c902ffffec1019cd2e0aebba (patch)
tree2aa58321c58cd5abcc8428026cfd53eff9d33cd0
parentfebb2a7e4b2b3dce7e5b92b0f5ffc197a31fc56a (diff)
parent71ebe1e7cefc719adbb4ab6da53162ed2d4cce81 (diff)
Creating tag for the release of asterisk-1.4.20-rc2
git-svn-id: http://svn.digium.com/svn/asterisk/tags/1.4.20-rc2@115530 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--1.4/.cleancount1
-rw-r--r--1.4/BUGS22
-rw-r--r--1.4/CHANGES345
-rw-r--r--1.4/COPYING341
-rw-r--r--1.4/CREDITS215
-rw-r--r--1.4/LICENSE68
-rw-r--r--1.4/Makefile777
-rw-r--r--1.4/Makefile.moddir_rules118
-rw-r--r--1.4/Makefile.rules73
-rw-r--r--1.4/README262
-rw-r--r--1.4/UPGRADE.txt495
-rw-r--r--1.4/acinclude.m4986
-rw-r--r--1.4/agi/DialAnMp3.agi82
-rw-r--r--1.4/agi/Makefile47
-rw-r--r--1.4/agi/agi-test.agi79
-rw-r--r--1.4/agi/eagi-sphinx-test.c222
-rw-r--r--1.4/agi/eagi-test.c165
-rw-r--r--1.4/agi/fastagi-test94
-rwxr-xr-x1.4/agi/jukebox.agi488
-rw-r--r--1.4/agi/numeralize44
-rw-r--r--1.4/apps/Makefile47
-rw-r--r--1.4/apps/app_adsiprog.c1590
-rw-r--r--1.4/apps/app_alarmreceiver.c841
-rw-r--r--1.4/apps/app_amd.c430
-rw-r--r--1.4/apps/app_authenticate.c252
-rw-r--r--1.4/apps/app_cdr.c78
-rw-r--r--1.4/apps/app_chanisavail.c173
-rw-r--r--1.4/apps/app_channelredirect.c140
-rw-r--r--1.4/apps/app_chanspy.c856
-rw-r--r--1.4/apps/app_controlplayback.c168
-rw-r--r--1.4/apps/app_db.c167
-rw-r--r--1.4/apps/app_dial.c1894
-rw-r--r--1.4/apps/app_dictate.c349
-rw-r--r--1.4/apps/app_directed_pickup.c181
-rw-r--r--1.4/apps/app_directory.c704
-rw-r--r--1.4/apps/app_disa.c393
-rw-r--r--1.4/apps/app_dumpchan.c176
-rw-r--r--1.4/apps/app_echo.c104
-rw-r--r--1.4/apps/app_exec.c221
-rw-r--r--1.4/apps/app_externalivr.c578
-rw-r--r--1.4/apps/app_festival.c553
-rw-r--r--1.4/apps/app_flash.c125
-rw-r--r--1.4/apps/app_followme.c1113
-rw-r--r--1.4/apps/app_forkcdr.c114
-rw-r--r--1.4/apps/app_getcpeid.c148
-rw-r--r--1.4/apps/app_hasnewvoicemail.c225
-rw-r--r--1.4/apps/app_ices.c223
-rw-r--r--1.4/apps/app_image.c125
-rw-r--r--1.4/apps/app_ivrdemo.c132
-rw-r--r--1.4/apps/app_lookupblacklist.c160
-rw-r--r--1.4/apps/app_lookupcidname.c103
-rw-r--r--1.4/apps/app_macro.c557
-rw-r--r--1.4/apps/app_meetme.c4882
-rw-r--r--1.4/apps/app_milliwatt.c153
-rw-r--r--1.4/apps/app_mixmonitor.c446
-rw-r--r--1.4/apps/app_morsecode.c179
-rw-r--r--1.4/apps/app_mp3.c255
-rw-r--r--1.4/apps/app_nbscat.c237
-rw-r--r--1.4/apps/app_osplookup.c1677
-rw-r--r--1.4/apps/app_page.c203
-rw-r--r--1.4/apps/app_parkandannounce.c260
-rw-r--r--1.4/apps/app_playback.c494
-rw-r--r--1.4/apps/app_privacy.c232
-rw-r--r--1.4/apps/app_queue.c4959
-rw-r--r--1.4/apps/app_random.c108
-rw-r--r--1.4/apps/app_read.c234
-rw-r--r--1.4/apps/app_readfile.c120
-rw-r--r--1.4/apps/app_realtime.c261
-rw-r--r--1.4/apps/app_record.c386
-rw-r--r--1.4/apps/app_rpt.c11928
-rw-r--r--1.4/apps/app_sayunixtime.c126
-rw-r--r--1.4/apps/app_senddtmf.c143
-rw-r--r--1.4/apps/app_sendtext.c130
-rw-r--r--1.4/apps/app_setcallerid.c162
-rw-r--r--1.4/apps/app_setcdruserfield.c175
-rw-r--r--1.4/apps/app_settransfercapability.c136
-rw-r--r--1.4/apps/app_skel.c133
-rw-r--r--1.4/apps/app_sms.c1536
-rw-r--r--1.4/apps/app_softhangup.c121
-rw-r--r--1.4/apps/app_speech_utils.c866
-rw-r--r--1.4/apps/app_stack.c174
-rw-r--r--1.4/apps/app_system.c162
-rw-r--r--1.4/apps/app_talkdetect.c227
-rw-r--r--1.4/apps/app_test.c512
-rw-r--r--1.4/apps/app_transfer.c156
-rw-r--r--1.4/apps/app_url.c173
-rw-r--r--1.4/apps/app_userevent.c109
-rw-r--r--1.4/apps/app_verbose.c168
-rw-r--r--1.4/apps/app_voicemail.c9143
-rw-r--r--1.4/apps/app_waitforring.c136
-rw-r--r--1.4/apps/app_waitforsilence.c205
-rw-r--r--1.4/apps/app_while.c335
-rw-r--r--1.4/apps/app_zapateller.c120
-rw-r--r--1.4/apps/app_zapbarge.c318
-rw-r--r--1.4/apps/app_zapras.c258
-rw-r--r--1.4/apps/app_zapscan.c381
-rw-r--r--1.4/apps/enter.h287
-rw-r--r--1.4/apps/leave.h207
-rw-r--r--1.4/apps/rpt_flow.pdfbin51935 -> 0 bytes
-rwxr-xr-x1.4/bootstrap.sh40
-rw-r--r--1.4/build_tools/cflags-devmode.xml17
-rw-r--r--1.4/build_tools/cflags.xml19
-rw-r--r--1.4/build_tools/embed_modules.xml26
-rw-r--r--1.4/build_tools/get_makeopts3
-rw-r--r--1.4/build_tools/get_moduleinfo3
-rwxr-xr-x1.4/build_tools/make_build_h20
-rwxr-xr-x1.4/build_tools/make_buildopts_h29
-rwxr-xr-x1.4/build_tools/make_defaults_h26
-rwxr-xr-x1.4/build_tools/make_sample_voicemail25
-rwxr-xr-x1.4/build_tools/make_version83
-rwxr-xr-x1.4/build_tools/make_version_h25
-rw-r--r--1.4/build_tools/menuselect-deps.in41
-rwxr-xr-x1.4/build_tools/mkpkgconfig50
-rwxr-xr-x1.4/build_tools/prep_tarball9
-rwxr-xr-x1.4/build_tools/strip_nonapi37
-rw-r--r--1.4/cdr/Makefile32
-rw-r--r--1.4/cdr/cdr_csv.c365
-rw-r--r--1.4/cdr/cdr_custom.c174
-rw-r--r--1.4/cdr/cdr_manager.c170
-rw-r--r--1.4/cdr/cdr_odbc.c468
-rw-r--r--1.4/cdr/cdr_pgsql.c336
-rw-r--r--1.4/cdr/cdr_radius.c273
-rw-r--r--1.4/cdr/cdr_sqlite.c217
-rw-r--r--1.4/cdr/cdr_tds.c529
-rw-r--r--1.4/channels/DialTone.h252
-rw-r--r--1.4/channels/Makefile127
-rw-r--r--1.4/channels/answer.h237
-rw-r--r--1.4/channels/chan_agent.c2774
-rw-r--r--1.4/channels/chan_alsa.c1377
-rw-r--r--1.4/channels/chan_features.c580
-rw-r--r--1.4/channels/chan_gtalk.c2049
-rw-r--r--1.4/channels/chan_h323.c3275
-rw-r--r--1.4/channels/chan_iax2.c11131
-rw-r--r--1.4/channels/chan_local.c764
-rw-r--r--1.4/channels/chan_mgcp.c4430
-rw-r--r--1.4/channels/chan_misdn.c5700
-rw-r--r--1.4/channels/chan_nbs.c302
-rw-r--r--1.4/channels/chan_oss.c1887
-rw-r--r--1.4/channels/chan_phone.c1433
-rw-r--r--1.4/channels/chan_sip.c18276
-rw-r--r--1.4/channels/chan_skinny.c5008
-rw-r--r--1.4/channels/chan_vpb.cc2905
-rw-r--r--1.4/channels/chan_zap.c11583
-rw-r--r--1.4/channels/gentone-ulaw.c157
-rw-r--r--1.4/channels/gentone.c95
-rw-r--r--1.4/channels/h323/ChangeLog43
-rw-r--r--1.4/channels/h323/INSTALL.openh32318
-rw-r--r--1.4/channels/h323/Makefile.in48
-rw-r--r--1.4/channels/h323/README144
-rw-r--r--1.4/channels/h323/TODO9
-rw-r--r--1.4/channels/h323/ast_h323.cxx2475
-rw-r--r--1.4/channels/h323/ast_h323.h166
-rw-r--r--1.4/channels/h323/caps_h323.cxx239
-rw-r--r--1.4/channels/h323/caps_h323.h124
-rw-r--r--1.4/channels/h323/chan_h323.h254
-rw-r--r--1.4/channels/h323/cisco-h225.asn74
-rw-r--r--1.4/channels/h323/cisco-h225.cxx853
-rw-r--r--1.4/channels/h323/cisco-h225.h299
-rw-r--r--1.4/channels/h323/compat_h323.cxx138
-rw-r--r--1.4/channels/h323/compat_h323.h80
-rw-r--r--1.4/channels/h323/noexport.map5
-rw-r--r--1.4/channels/iax2-parser.c1042
-rw-r--r--1.4/channels/iax2-parser.h160
-rw-r--r--1.4/channels/iax2-provision.c540
-rw-r--r--1.4/channels/iax2-provision.h53
-rw-r--r--1.4/channels/iax2.h237
-rw-r--r--1.4/channels/misdn/Makefile17
-rw-r--r--1.4/channels/misdn/chan_misdn_config.h152
-rw-r--r--1.4/channels/misdn/ie.c1422
-rw-r--r--1.4/channels/misdn/isdn_lib.c4574
-rw-r--r--1.4/channels/misdn/isdn_lib.h476
-rw-r--r--1.4/channels/misdn/isdn_lib_intern.h122
-rw-r--r--1.4/channels/misdn/isdn_msg_parser.c1348
-rw-r--r--1.4/channels/misdn/portinfo.c198
-rw-r--r--1.4/channels/misdn_config.c1150
-rw-r--r--1.4/channels/ring10.h1752
-rw-r--r--1.4/codecs/Makefile61
-rw-r--r--1.4/codecs/adpcm_slin_ex.h25
-rw-r--r--1.4/codecs/codec_a_mu.c168
-rw-r--r--1.4/codecs/codec_adpcm.c404
-rw-r--r--1.4/codecs/codec_alaw.c189
-rw-r--r--1.4/codecs/codec_g726.c964
-rw-r--r--1.4/codecs/codec_gsm.c290
-rw-r--r--1.4/codecs/codec_ilbc.c248
-rw-r--r--1.4/codecs/codec_lpc10.c317
-rw-r--r--1.4/codecs/codec_speex.c522
-rw-r--r--1.4/codecs/codec_ulaw.c201
-rw-r--r--1.4/codecs/codec_zap.c512
-rw-r--r--1.4/codecs/g726_slin_ex.h25
-rw-r--r--1.4/codecs/gsm/COPYRIGHT16
-rw-r--r--1.4/codecs/gsm/Makefile543
-rw-r--r--1.4/codecs/gsm/README37
-rw-r--r--1.4/codecs/gsm/inc/config.h51
-rw-r--r--1.4/codecs/gsm/inc/gsm.h71
-rw-r--r--1.4/codecs/gsm/inc/private.h312
-rw-r--r--1.4/codecs/gsm/inc/proto.h65
-rw-r--r--1.4/codecs/gsm/inc/unproto.h23
-rw-r--r--1.4/codecs/gsm/libgsm.vcproj253
-rw-r--r--1.4/codecs/gsm/src/add.c235
-rw-r--r--1.4/codecs/gsm/src/code.c97
-rw-r--r--1.4/codecs/gsm/src/debug.c76
-rw-r--r--1.4/codecs/gsm/src/decode.c62
-rw-r--r--1.4/codecs/gsm/src/gsm_create.c45
-rw-r--r--1.4/codecs/gsm/src/gsm_decode.c361
-rw-r--r--1.4/codecs/gsm/src/gsm_destroy.c26
-rw-r--r--1.4/codecs/gsm/src/gsm_encode.c451
-rw-r--r--1.4/codecs/gsm/src/gsm_explode.c417
-rw-r--r--1.4/codecs/gsm/src/gsm_implode.c515
-rw-r--r--1.4/codecs/gsm/src/gsm_option.c69
-rw-r--r--1.4/codecs/gsm/src/gsm_print.c167
-rw-r--r--1.4/codecs/gsm/src/k6opt.h84
-rw-r--r--1.4/codecs/gsm/src/k6opt.s739
-rw-r--r--1.4/codecs/gsm/src/long_term.c955
-rw-r--r--1.4/codecs/gsm/src/lpc.c372
-rw-r--r--1.4/codecs/gsm/src/preprocess.c127
-rw-r--r--1.4/codecs/gsm/src/rpe.c490
-rw-r--r--1.4/codecs/gsm/src/short_term.c448
-rw-r--r--1.4/codecs/gsm/src/table.c63
-rw-r--r--1.4/codecs/gsm_slin_ex.h16
-rw-r--r--1.4/codecs/ilbc/Makefile20
-rw-r--r--1.4/codecs/ilbc_slin_ex.h17
-rw-r--r--1.4/codecs/log2comp.h74
-rw-r--r--1.4/codecs/lpc10/Makefile77
-rw-r--r--1.4/codecs/lpc10/README89
-rw-r--r--1.4/codecs/lpc10/analys.c649
-rw-r--r--1.4/codecs/lpc10/bsynz.c447
-rw-r--r--1.4/codecs/lpc10/chanwr.c232
-rw-r--r--1.4/codecs/lpc10/dcbias.c107
-rw-r--r--1.4/codecs/lpc10/decode.c625
-rw-r--r--1.4/codecs/lpc10/deemp.c154
-rw-r--r--1.4/codecs/lpc10/difmag.c133
-rw-r--r--1.4/codecs/lpc10/dyptrk.c405
-rw-r--r--1.4/codecs/lpc10/encode.c373
-rw-r--r--1.4/codecs/lpc10/energy.c103
-rw-r--r--1.4/codecs/lpc10/f2c.h325
-rw-r--r--1.4/codecs/lpc10/f2clib.c85
-rw-r--r--1.4/codecs/lpc10/ham84.c126
-rw-r--r--1.4/codecs/lpc10/hp100.c169
-rw-r--r--1.4/codecs/lpc10/invert.c193
-rw-r--r--1.4/codecs/lpc10/irc2pc.c151
-rw-r--r--1.4/codecs/lpc10/ivfilt.c136
-rw-r--r--1.4/codecs/lpc10/liblpc10.vcproj305
-rw-r--r--1.4/codecs/lpc10/lpc10.h256
-rw-r--r--1.4/codecs/lpc10/lpcdec.c297
-rw-r--r--1.4/codecs/lpc10/lpcenc.c181
-rw-r--r--1.4/codecs/lpc10/lpcini.c446
-rw-r--r--1.4/codecs/lpc10/lpfilt.c125
-rw-r--r--1.4/codecs/lpc10/median.c89
-rw-r--r--1.4/codecs/lpc10/mload.c163
-rw-r--r--1.4/codecs/lpc10/onset.c324
-rw-r--r--1.4/codecs/lpc10/pitsyn.c583
-rw-r--r--1.4/codecs/lpc10/placea.c242
-rw-r--r--1.4/codecs/lpc10/placev.c275
-rw-r--r--1.4/codecs/lpc10/preemp.c144
-rw-r--r--1.4/codecs/lpc10/prepro.c116
-rw-r--r--1.4/codecs/lpc10/random.c125
-rw-r--r--1.4/codecs/lpc10/rcchk.c119
-rw-r--r--1.4/codecs/lpc10/synths.c425
-rw-r--r--1.4/codecs/lpc10/tbdm.c188
-rw-r--r--1.4/codecs/lpc10/voicin.c786
-rw-r--r--1.4/codecs/lpc10/vparms.c255
-rw-r--r--1.4/codecs/lpc10_slin_ex.h13
-rw-r--r--1.4/codecs/slin_adpcm_ex.h25
-rw-r--r--1.4/codecs/slin_g726_ex.h25
-rw-r--r--1.4/codecs/slin_gsm_ex.h28
-rw-r--r--1.4/codecs/slin_ilbc_ex.h28
-rw-r--r--1.4/codecs/slin_lpc10_ex.h21
-rw-r--r--1.4/codecs/slin_speex_ex.h262
-rw-r--r--1.4/codecs/slin_ulaw_ex.h25
-rw-r--r--1.4/codecs/speex_slin_ex.h16
-rw-r--r--1.4/codecs/ulaw_slin_ex.h25
-rwxr-xr-x1.4/config.guess1495
-rwxr-xr-x1.4/config.sub1609
-rw-r--r--1.4/configs/adsi.conf.sample8
-rw-r--r--1.4/configs/adtranvofr.conf.sample39
-rw-r--r--1.4/configs/agents.conf.sample105
-rw-r--r--1.4/configs/alarmreceiver.conf.sample80
-rw-r--r--1.4/configs/alsa.conf.sample62
-rw-r--r--1.4/configs/amd.conf.sample18
-rw-r--r--1.4/configs/asterisk.adsi159
-rw-r--r--1.4/configs/cdr.conf.sample148
-rw-r--r--1.4/configs/cdr_custom.conf.sample10
-rw-r--r--1.4/configs/cdr_manager.conf.sample6
-rw-r--r--1.4/configs/cdr_odbc.conf.sample12
-rw-r--r--1.4/configs/cdr_pgsql.conf.sample9
-rw-r--r--1.4/configs/cdr_tds.conf.sample11
-rw-r--r--1.4/configs/codecs.conf.sample65
-rw-r--r--1.4/configs/dnsmgr.conf.sample5
-rw-r--r--1.4/configs/dundi.conf.sample239
-rw-r--r--1.4/configs/enum.conf.sample22
-rw-r--r--1.4/configs/extconfig.conf.sample58
-rw-r--r--1.4/configs/extensions.ael.sample448
-rw-r--r--1.4/configs/extensions.conf.sample614
-rw-r--r--1.4/configs/features.conf.sample98
-rw-r--r--1.4/configs/festival.conf.sample35
-rw-r--r--1.4/configs/followme.conf.sample86
-rw-r--r--1.4/configs/func_odbc.conf.sample41
-rw-r--r--1.4/configs/gtalk.conf.sample19
-rw-r--r--1.4/configs/h323.conf.sample193
-rw-r--r--1.4/configs/http.conf.sample40
-rw-r--r--1.4/configs/iax.conf.sample406
-rw-r--r--1.4/configs/iaxprov.conf.sample81
-rw-r--r--1.4/configs/indications.conf.sample733
-rw-r--r--1.4/configs/jabber.conf.sample18
-rw-r--r--1.4/configs/logger.conf.sample69
-rw-r--r--1.4/configs/manager.conf.sample56
-rw-r--r--1.4/configs/meetme.conf.sample26
-rw-r--r--1.4/configs/mgcp.conf.sample104
-rw-r--r--1.4/configs/misdn.conf.sample429
-rw-r--r--1.4/configs/modules.conf.sample35
-rw-r--r--1.4/configs/musiconhold.conf.sample66
-rw-r--r--1.4/configs/muted.conf.sample39
-rw-r--r--1.4/configs/osp.conf.sample72
-rw-r--r--1.4/configs/oss.conf.sample75
-rw-r--r--1.4/configs/phone.conf.sample49
-rw-r--r--1.4/configs/privacy.conf.sample3
-rw-r--r--1.4/configs/queues.conf.sample308
-rw-r--r--1.4/configs/res_odbc.conf.sample49
-rw-r--r--1.4/configs/res_pgsql.conf.sample14
-rw-r--r--1.4/configs/res_snmp.conf.sample10
-rw-r--r--1.4/configs/rpt.conf.sample193
-rw-r--r--1.4/configs/rtp.conf.sample22
-rw-r--r--1.4/configs/say.conf.sample171
-rw-r--r--1.4/configs/sip.conf.sample664
-rw-r--r--1.4/configs/sip_notify.conf.sample22
-rw-r--r--1.4/configs/skinny.conf.sample96
-rw-r--r--1.4/configs/sla.conf.sample140
-rw-r--r--1.4/configs/smdi.conf.sample75
-rw-r--r--1.4/configs/telcordia-1.adsi83
-rw-r--r--1.4/configs/udptl.conf.sample30
-rw-r--r--1.4/configs/users.conf.sample79
-rw-r--r--1.4/configs/voicemail.conf.sample248
-rw-r--r--1.4/configs/vpb.conf.sample108
-rw-r--r--1.4/configs/zapata.conf.sample671
-rwxr-xr-x1.4/configure36856
-rw-r--r--1.4/configure.ac1596
-rw-r--r--1.4/contrib/README.festival47
-rw-r--r--1.4/contrib/asterisk-doxygen-header10
-rw-r--r--1.4/contrib/asterisk-ices.xml93
-rw-r--r--1.4/contrib/asterisk-ng-doxygen1230
-rw-r--r--1.4/contrib/dictionary.digium31
-rw-r--r--1.4/contrib/festival-1.4.1-diff76
-rw-r--r--1.4/contrib/festival-1.4.2.diff75
-rw-r--r--1.4/contrib/festival-1.4.3.diff93
-rw-r--r--1.4/contrib/festival-1.95.diff107
-rw-r--r--1.4/contrib/firmware/iax/iaxy.binbin39402 -> 0 bytes
-rw-r--r--1.4/contrib/i18n.testsuite.conf136
-rwxr-xr-x1.4/contrib/init.d/rc.debian.asterisk94
-rwxr-xr-x1.4/contrib/init.d/rc.gentoo.asterisk26
-rwxr-xr-x1.4/contrib/init.d/rc.mandrake.asterisk193
-rwxr-xr-x1.4/contrib/init.d/rc.mandrake.zaptel108
-rwxr-xr-x1.4/contrib/init.d/rc.redhat.asterisk144
-rwxr-xr-x1.4/contrib/init.d/rc.slackware.asterisk51
-rwxr-xr-x1.4/contrib/init.d/rc.suse.asterisk136
-rw-r--r--1.4/contrib/scripts/README.messages-expire20
-rw-r--r--1.4/contrib/scripts/agents.php73
-rw-r--r--1.4/contrib/scripts/ast_grab_core70
-rw-r--r--1.4/contrib/scripts/astgenkey61
-rw-r--r--1.4/contrib/scripts/astgenkey.8144
-rw-r--r--1.4/contrib/scripts/autosupport230
-rw-r--r--1.4/contrib/scripts/autosupport.841
-rwxr-xr-x1.4/contrib/scripts/get_ilbc_source.sh33
-rw-r--r--1.4/contrib/scripts/iax-friends.sql54
-rw-r--r--1.4/contrib/scripts/loadtest.tcl148
-rw-r--r--1.4/contrib/scripts/lookup.agi90
-rw-r--r--1.4/contrib/scripts/managerproxy.pl242
-rw-r--r--1.4/contrib/scripts/meetme.sql12
-rw-r--r--1.4/contrib/scripts/messages-expire.pl96
-rw-r--r--1.4/contrib/scripts/postgres_cdr.sql33
-rw-r--r--1.4/contrib/scripts/qview.pl100
-rw-r--r--1.4/contrib/scripts/realtime_pgsql.sql141
-rw-r--r--1.4/contrib/scripts/retrieve_extensions_from_mysql.pl113
-rw-r--r--1.4/contrib/scripts/retrieve_extensions_from_sql.pl158
-rw-r--r--1.4/contrib/scripts/retrieve_sip_conf_from_mysql.pl93
-rw-r--r--1.4/contrib/scripts/safe_asterisk178
-rw-r--r--1.4/contrib/scripts/safe_asterisk.869
-rw-r--r--1.4/contrib/scripts/safe_asterisk_restart110
-rw-r--r--1.4/contrib/scripts/sip-friends.sql54
-rw-r--r--1.4/contrib/scripts/vmail.cgi1107
-rw-r--r--1.4/contrib/scripts/vmdb.sql64
-rw-r--r--1.4/contrib/thirdparty/spexxilbcfix_xlite.regbin452 -> 0 bytes
-rw-r--r--1.4/contrib/thirdparty/spexxilbcfix_xpro.regbin450 -> 0 bytes
-rw-r--r--1.4/contrib/utils/README.rawplayer37
-rw-r--r--1.4/contrib/utils/rawplayer.c46
-rw-r--r--1.4/contrib/utils/zones2indications.c153
-rw-r--r--1.4/contrib/valgrind-RedHat-8.0.supp41
-rw-r--r--1.4/doc/00README.1st74
-rw-r--r--1.4/doc/CODING-GUIDELINES543
-rw-r--r--1.4/doc/PEERING499
-rw-r--r--1.4/doc/ael.txt1260
-rw-r--r--1.4/doc/ajam.txt91
-rw-r--r--1.4/doc/app-sms.txt470
-rw-r--r--1.4/doc/apps.txt10
-rw-r--r--1.4/doc/asterisk-conf.txt83
-rw-r--r--1.4/doc/asterisk-mib.txt739
-rw-r--r--1.4/doc/asterisk.8195
-rw-r--r--1.4/doc/asterisk.sgml364
-rw-r--r--1.4/doc/backtrace.txt191
-rw-r--r--1.4/doc/billing.txt105
-rw-r--r--1.4/doc/callfiles.txt139
-rw-r--r--1.4/doc/callingpres.txt18
-rw-r--r--1.4/doc/cdrdriver.txt215
-rw-r--r--1.4/doc/chaniax.txt369
-rw-r--r--1.4/doc/channels.txt44
-rw-r--r--1.4/doc/channelvariables.txt815
-rw-r--r--1.4/doc/cliprompt.txt29
-rw-r--r--1.4/doc/configuration.txt180
-rw-r--r--1.4/doc/cygwin.txt9
-rw-r--r--1.4/doc/datastores.txt63
-rw-r--r--1.4/doc/digium-mib.txt17
-rw-r--r--1.4/doc/dundi.txt26
-rw-r--r--1.4/doc/enum.txt308
-rw-r--r--1.4/doc/extconfig.txt91
-rw-r--r--1.4/doc/extensions.txt58
-rw-r--r--1.4/doc/externalivr.txt109
-rw-r--r--1.4/doc/freetds.txt18
-rw-r--r--1.4/doc/h323.txt22
-rw-r--r--1.4/doc/hardware.txt74
-rw-r--r--1.4/doc/iax.txt67
-rw-r--r--1.4/doc/ices.txt12
-rw-r--r--1.4/doc/imapstorage.txt213
-rw-r--r--1.4/doc/ip-tos.txt81
-rw-r--r--1.4/doc/jabber.txt15
-rw-r--r--1.4/doc/jingle.txt11
-rw-r--r--1.4/doc/jitterbuffer.txt137
-rw-r--r--1.4/doc/linkedlists.txt98
-rw-r--r--1.4/doc/localchannel.txt49
-rw-r--r--1.4/doc/macroexclusive.txt78
-rw-r--r--1.4/doc/manager.txt311
-rw-r--r--1.4/doc/math.txt69
-rw-r--r--1.4/doc/misdn.txt291
-rw-r--r--1.4/doc/model.txt15
-rw-r--r--1.4/doc/modules.txt26
-rw-r--r--1.4/doc/mp3.txt13
-rw-r--r--1.4/doc/musiconhold-fpm.txt8
-rw-r--r--1.4/doc/mysql.txt15
-rw-r--r--1.4/doc/odbcstorage.txt30
-rw-r--r--1.4/doc/osp.txt421
-rw-r--r--1.4/doc/privacy.txt361
-rw-r--r--1.4/doc/queuelog.txt99
-rw-r--r--1.4/doc/queues-with-callback-members.txt521
-rw-r--r--1.4/doc/radius.txt203
-rw-r--r--1.4/doc/realtime.txt138
-rw-r--r--1.4/doc/rtp-packetization.txt73
-rw-r--r--1.4/doc/security.txt80
-rw-r--r--1.4/doc/sla.pdfbin68499 -> 0 bytes
-rw-r--r--1.4/doc/sla.tex378
-rw-r--r--1.4/doc/smdi.txt25
-rw-r--r--1.4/doc/sms.txt147
-rw-r--r--1.4/doc/snmp.txt39
-rw-r--r--1.4/doc/speechrec.txt295
-rw-r--r--1.4/doc/valgrind.txt26
-rw-r--r--1.4/doc/video.txt46
-rw-r--r--1.4/doc/voicemail_odbc_postgresql.txt453
-rw-r--r--1.4/formats/Makefile32
-rw-r--r--1.4/formats/format_g723.c163
-rw-r--r--1.4/formats/format_g726.c277
-rw-r--r--1.4/formats/format_g729.c159
-rw-r--r--1.4/formats/format_gsm.c181
-rw-r--r--1.4/formats/format_h263.c197
-rw-r--r--1.4/formats/format_h264.c186
-rw-r--r--1.4/formats/format_ilbc.c157
-rw-r--r--1.4/formats/format_jpeg.c127
-rw-r--r--1.4/formats/format_ogg_vorbis.c564
-rw-r--r--1.4/formats/format_pcm.c506
-rw-r--r--1.4/formats/format_sln.c141
-rw-r--r--1.4/formats/format_vox.c146
-rw-r--r--1.4/formats/format_wav.c528
-rw-r--r--1.4/formats/format_wav_gsm.c560
-rw-r--r--1.4/formats/msgsm.h689
-rw-r--r--1.4/funcs/Makefile32
-rw-r--r--1.4/funcs/func_base64.c94
-rw-r--r--1.4/funcs/func_callerid.c164
-rw-r--r--1.4/funcs/func_cdr.c167
-rw-r--r--1.4/funcs/func_channel.c202
-rw-r--r--1.4/funcs/func_curl.c210
-rw-r--r--1.4/funcs/func_cut.c332
-rw-r--r--1.4/funcs/func_db.c231
-rw-r--r--1.4/funcs/func_enum.c198
-rw-r--r--1.4/funcs/func_env.c158
-rw-r--r--1.4/funcs/func_global.c86
-rw-r--r--1.4/funcs/func_groupcount.c236
-rw-r--r--1.4/funcs/func_language.c90
-rw-r--r--1.4/funcs/func_logic.c214
-rw-r--r--1.4/funcs/func_math.c268
-rw-r--r--1.4/funcs/func_md5.c120
-rw-r--r--1.4/funcs/func_moh.c87
-rw-r--r--1.4/funcs/func_odbc.c651
-rw-r--r--1.4/funcs/func_rand.c104
-rw-r--r--1.4/funcs/func_realtime.c175
-rw-r--r--1.4/funcs/func_sha1.c83
-rw-r--r--1.4/funcs/func_strings.c641
-rw-r--r--1.4/funcs/func_timeout.c194
-rw-r--r--1.4/funcs/func_uri.c101
-rw-r--r--1.4/images/animlogo.gifbin63968 -> 0 bytes
-rw-r--r--1.4/images/asterisk-intro.jpgbin6143 -> 0 bytes
-rw-r--r--1.4/images/play.gifbin341 -> 0 bytes
-rw-r--r--1.4/include/asterisk.h213
-rw-r--r--1.4/include/asterisk/abstract_jb.h220
-rw-r--r--1.4/include/asterisk/acl.h57
-rw-r--r--1.4/include/asterisk/adsi.h353
-rw-r--r--1.4/include/asterisk/ael_structs.h195
-rw-r--r--1.4/include/asterisk/aes.h170
-rw-r--r--1.4/include/asterisk/agi.h57
-rw-r--r--1.4/include/asterisk/alaw.h43
-rw-r--r--1.4/include/asterisk/app.h426
-rw-r--r--1.4/include/asterisk/ast_expr.h32
-rw-r--r--1.4/include/asterisk/astdb.h52
-rw-r--r--1.4/include/asterisk/astmm.h89
-rw-r--r--1.4/include/asterisk/astobj.h822
-rw-r--r--1.4/include/asterisk/astobj2.h541
-rw-r--r--1.4/include/asterisk/astosp.h31
-rw-r--r--1.4/include/asterisk/audiohook.h361
-rw-r--r--1.4/include/asterisk/autoconfig.h.in689
-rw-r--r--1.4/include/asterisk/callerid.h339
-rw-r--r--1.4/include/asterisk/causes.h82
-rw-r--r--1.4/include/asterisk/cdr.h316
-rw-r--r--1.4/include/asterisk/channel.h1420
-rw-r--r--1.4/include/asterisk/chanvars.h42
-rw-r--r--1.4/include/asterisk/cli.h183
-rw-r--r--1.4/include/asterisk/compat.h130
-rw-r--r--1.4/include/asterisk/compiler.h62
-rw-r--r--1.4/include/asterisk/config.h206
-rw-r--r--1.4/include/asterisk/crypto.h112
-rw-r--r--1.4/include/asterisk/devicestate.h133
-rw-r--r--1.4/include/asterisk/dial.h151
-rw-r--r--1.4/include/asterisk/dlfcn-compat.h88
-rw-r--r--1.4/include/asterisk/dns.h39
-rw-r--r--1.4/include/asterisk/dnsmgr.h62
-rw-r--r--1.4/include/asterisk/doxyref.h488
-rw-r--r--1.4/include/asterisk/dsp.h124
-rw-r--r--1.4/include/asterisk/dundi.h226
-rw-r--r--1.4/include/asterisk/endian.h62
-rw-r--r--1.4/include/asterisk/enum.h59
-rw-r--r--1.4/include/asterisk/features.h97
-rw-r--r--1.4/include/asterisk/file.h419
-rw-r--r--1.4/include/asterisk/frame.h593
-rw-r--r--1.4/include/asterisk/fskmodem.h72
-rw-r--r--1.4/include/asterisk/global_datastores.h36
-rw-r--r--1.4/include/asterisk/http.h65
-rw-r--r--1.4/include/asterisk/image.h96
-rw-r--r--1.4/include/asterisk/indications.h89
-rw-r--r--1.4/include/asterisk/inline_api.h66
-rw-r--r--1.4/include/asterisk/io.h145
-rw-r--r--1.4/include/asterisk/jabber.h146
-rw-r--r--1.4/include/asterisk/jingle.h45
-rw-r--r--1.4/include/asterisk/linkedlists.h761
-rw-r--r--1.4/include/asterisk/localtime.h30
-rw-r--r--1.4/include/asterisk/lock.h1213
-rw-r--r--1.4/include/asterisk/logger.h139
-rw-r--r--1.4/include/asterisk/manager.h148
-rw-r--r--1.4/include/asterisk/md5.h40
-rw-r--r--1.4/include/asterisk/module.h292
-rw-r--r--1.4/include/asterisk/monitor.h66
-rw-r--r--1.4/include/asterisk/musiconhold.h59
-rw-r--r--1.4/include/asterisk/netsock.h68
-rw-r--r--1.4/include/asterisk/options.h131
-rw-r--r--1.4/include/asterisk/paths.h43
-rw-r--r--1.4/include/asterisk/pbx.h884
-rw-r--r--1.4/include/asterisk/plc.h161
-rw-r--r--1.4/include/asterisk/poll-compat.h111
-rw-r--r--1.4/include/asterisk/privacy.h46
-rw-r--r--1.4/include/asterisk/res_odbc.h103
-rw-r--r--1.4/include/asterisk/rtp.h265
-rw-r--r--1.4/include/asterisk/say.h158
-rw-r--r--1.4/include/asterisk/sched.h177
-rw-r--r--1.4/include/asterisk/sha1.h81
-rw-r--r--1.4/include/asterisk/slinfactory.h57
-rw-r--r--1.4/include/asterisk/smdi.h195
-rw-r--r--1.4/include/asterisk/speech.h152
-rw-r--r--1.4/include/asterisk/srv.h45
-rw-r--r--1.4/include/asterisk/stringfields.h389
-rw-r--r--1.4/include/asterisk/strings.h285
-rw-r--r--1.4/include/asterisk/tdd.h82
-rw-r--r--1.4/include/asterisk/term.h76
-rw-r--r--1.4/include/asterisk/threadstorage.h498
-rw-r--r--1.4/include/asterisk/time.h144
-rw-r--r--1.4/include/asterisk/transcap.h42
-rw-r--r--1.4/include/asterisk/translate.h273
-rw-r--r--1.4/include/asterisk/udptl.h120
-rw-r--r--1.4/include/asterisk/ulaw.h43
-rw-r--r--1.4/include/asterisk/unaligned.h102
-rw-r--r--1.4/include/asterisk/utils.h565
-rw-r--r--1.4/include/jitterbuf.h162
-rw-r--r--1.4/include/solaris-compat/compat.h46
-rw-r--r--1.4/include/solaris-compat/sys/cdefs.h10
-rw-r--r--1.4/include/solaris-compat/sys/queue.h540
-rwxr-xr-x1.4/install-sh269
-rw-r--r--1.4/keys/freeworlddialup.pub6
-rw-r--r--1.4/keys/iaxtel.pub6
-rw-r--r--1.4/main/Makefile161
-rw-r--r--1.4/main/abstract_jb.c781
-rw-r--r--1.4/main/acl.c590
-rw-r--r--1.4/main/aescrypt.c317
-rw-r--r--1.4/main/aeskey.c469
-rw-r--r--1.4/main/aesopt.h1029
-rw-r--r--1.4/main/aestab.c232
-rw-r--r--1.4/main/alaw.c101
-rw-r--r--1.4/main/app.c1427
-rw-r--r--1.4/main/ast_expr2.c2859
-rw-r--r--1.4/main/ast_expr2.fl414
-rw-r--r--1.4/main/ast_expr2.h112
-rw-r--r--1.4/main/ast_expr2.y1045
-rw-r--r--1.4/main/ast_expr2f.c2478
-rw-r--r--1.4/main/asterisk.c3105
-rw-r--r--1.4/main/astmm.c480
-rw-r--r--1.4/main/astobj2.c719
-rw-r--r--1.4/main/audiohook.c659
-rw-r--r--1.4/main/autoservice.c288
-rw-r--r--1.4/main/buildinfo.c33
-rw-r--r--1.4/main/callerid.c1109
-rw-r--r--1.4/main/cdr.c1446
-rw-r--r--1.4/main/channel.c4695
-rw-r--r--1.4/main/chanvars.c87
-rw-r--r--1.4/main/cli.c2037
-rw-r--r--1.4/main/coef_in.h13
-rw-r--r--1.4/main/coef_out.h4
-rw-r--r--1.4/main/config.c1514
-rw-r--r--1.4/main/cryptostub.c95
-rw-r--r--1.4/main/db.c592
-rw-r--r--1.4/main/db1-ast/Makefile71
-rw-r--r--1.4/main/db1-ast/btree/bt_close.c182
-rw-r--r--1.4/main/db1-ast/btree/bt_conv.c221
-rw-r--r--1.4/main/db1-ast/btree/bt_debug.c329
-rw-r--r--1.4/main/db1-ast/btree/bt_delete.c657
-rw-r--r--1.4/main/db1-ast/btree/bt_get.c105
-rw-r--r--1.4/main/db1-ast/btree/bt_open.c458
-rw-r--r--1.4/main/db1-ast/btree/bt_overflow.c228
-rw-r--r--1.4/main/db1-ast/btree/bt_page.c100
-rw-r--r--1.4/main/db1-ast/btree/bt_put.c321
-rw-r--r--1.4/main/db1-ast/btree/bt_search.c213
-rw-r--r--1.4/main/db1-ast/btree/bt_seq.c460
-rw-r--r--1.4/main/db1-ast/btree/bt_split.c829
-rw-r--r--1.4/main/db1-ast/btree/bt_utils.c260
-rw-r--r--1.4/main/db1-ast/btree/btree.h391
-rw-r--r--1.4/main/db1-ast/btree/extern.h70
-rw-r--r--1.4/main/db1-ast/db/db.c103
-rw-r--r--1.4/main/db1-ast/hash/README72
-rw-r--r--1.4/main/db1-ast/hash/extern.h65
-rw-r--r--1.4/main/db1-ast/hash/hash.c999
-rw-r--r--1.4/main/db1-ast/hash/hash.h293
-rw-r--r--1.4/main/db1-ast/hash/hash_bigkey.c668
-rw-r--r--1.4/main/db1-ast/hash/hash_buf.c355
-rw-r--r--1.4/main/db1-ast/hash/hash_func.c225
-rw-r--r--1.4/main/db1-ast/hash/hash_log2.c56
-rw-r--r--1.4/main/db1-ast/hash/hash_page.c944
-rw-r--r--1.4/main/db1-ast/hash/hsearch.c107
-rw-r--r--1.4/main/db1-ast/hash/ndbm.c235
-rw-r--r--1.4/main/db1-ast/hash/page.h92
-rw-r--r--1.4/main/db1-ast/hash/search.h51
-rw-r--r--1.4/main/db1-ast/include/circ-queue.h131
-rw-r--r--1.4/main/db1-ast/include/compat.h49
-rw-r--r--1.4/main/db1-ast/include/db.h250
-rw-r--r--1.4/main/db1-ast/include/mpool.h115
-rw-r--r--1.4/main/db1-ast/include/ndbm.h79
-rw-r--r--1.4/main/db1-ast/libdb.map11
-rw-r--r--1.4/main/db1-ast/mpool/README7
-rw-r--r--1.4/main/db1-ast/mpool/mpool.c498
-rw-r--r--1.4/main/db1-ast/recno/extern.h54
-rw-r--r--1.4/main/db1-ast/recno/rec_close.c183
-rw-r--r--1.4/main/db1-ast/recno/rec_delete.c197
-rw-r--r--1.4/main/db1-ast/recno/rec_get.c311
-rw-r--r--1.4/main/db1-ast/recno/rec_open.c241
-rw-r--r--1.4/main/db1-ast/recno/rec_put.c280
-rw-r--r--1.4/main/db1-ast/recno/rec_search.c126
-rw-r--r--1.4/main/db1-ast/recno/rec_seq.c131
-rw-r--r--1.4/main/db1-ast/recno/rec_utils.c122
-rw-r--r--1.4/main/db1-ast/recno/recno.h39
-rw-r--r--1.4/main/devicestate.c392
-rw-r--r--1.4/main/dial.c894
-rw-r--r--1.4/main/dlfcn.c1314
-rw-r--r--1.4/main/dns.c292
-rw-r--r--1.4/main/dnsmgr.c420
-rw-r--r--1.4/main/dsp.c1819
-rw-r--r--1.4/main/ecdisa.h15
-rw-r--r--1.4/main/editline/CHANGES42
-rw-r--r--1.4/main/editline/INSTALL64
-rw-r--r--1.4/main/editline/Makefile.in234
-rw-r--r--1.4/main/editline/PLATFORMS13
-rw-r--r--1.4/main/editline/README11
-rw-r--r--1.4/main/editline/TEST/test.c268
-rw-r--r--1.4/main/editline/chared.c695
-rw-r--r--1.4/main/editline/chared.h159
-rw-r--r--1.4/main/editline/common.c951
-rwxr-xr-x1.4/main/editline/config.guess1449
-rw-r--r--1.4/main/editline/config.h.in21
-rwxr-xr-x1.4/main/editline/config.sub1412
-rwxr-xr-x1.4/main/editline/configure2421
-rw-r--r--1.4/main/editline/configure.in276
-rw-r--r--1.4/main/editline/editline.3646
-rw-r--r--1.4/main/editline/editrc.5491
-rw-r--r--1.4/main/editline/el.c509
-rw-r--r--1.4/main/editline/el.h145
-rw-r--r--1.4/main/editline/emacs.c488
-rw-r--r--1.4/main/editline/hist.c197
-rw-r--r--1.4/main/editline/hist.h80
-rw-r--r--1.4/main/editline/histedit.h197
-rw-r--r--1.4/main/editline/history.c875
-rwxr-xr-x1.4/main/editline/install-sh250
-rw-r--r--1.4/main/editline/key.c687
-rw-r--r--1.4/main/editline/key.h79
-rw-r--r--1.4/main/editline/makelist254
-rw-r--r--1.4/main/editline/map.c1418
-rw-r--r--1.4/main/editline/map.h79
-rw-r--r--1.4/main/editline/np/fgetln.c88
-rw-r--r--1.4/main/editline/np/strlcat.c75
-rw-r--r--1.4/main/editline/np/strlcpy.c75
-rw-r--r--1.4/main/editline/np/unvis.c322
-rw-r--r--1.4/main/editline/np/vis.c347
-rw-r--r--1.4/main/editline/np/vis.h96
-rw-r--r--1.4/main/editline/parse.c259
-rw-r--r--1.4/main/editline/parse.h52
-rw-r--r--1.4/main/editline/prompt.c174
-rw-r--r--1.4/main/editline/prompt.h62
-rw-r--r--1.4/main/editline/read.c555
-rw-r--r--1.4/main/editline/read.h55
-rw-r--r--1.4/main/editline/readline.c1664
-rw-r--r--1.4/main/editline/readline/readline.h118
-rw-r--r--1.4/main/editline/refresh.c1104
-rw-r--r--1.4/main/editline/refresh.h63
-rw-r--r--1.4/main/editline/search.c649
-rw-r--r--1.4/main/editline/search.h70
-rw-r--r--1.4/main/editline/sig.c198
-rw-r--r--1.4/main/editline/sig.h72
-rw-r--r--1.4/main/editline/sys.h133
-rw-r--r--1.4/main/editline/term.c1587
-rw-r--r--1.4/main/editline/term.h124
-rw-r--r--1.4/main/editline/tokenizer.c397
-rw-r--r--1.4/main/editline/tokenizer.h54
-rw-r--r--1.4/main/editline/tty.c1182
-rw-r--r--1.4/main/editline/tty.h484
-rw-r--r--1.4/main/editline/vi.c941
-rw-r--r--1.4/main/enum.c671
-rw-r--r--1.4/main/file.c1343
-rw-r--r--1.4/main/fixedjitterbuf.c351
-rw-r--r--1.4/main/fixedjitterbuf.h93
-rw-r--r--1.4/main/frame.c1617
-rw-r--r--1.4/main/fskmodem.c309
-rw-r--r--1.4/main/global_datastores.c83
-rw-r--r--1.4/main/http.c745
-rw-r--r--1.4/main/image.c225
-rw-r--r--1.4/main/indications.c600
-rw-r--r--1.4/main/io.c371
-rw-r--r--1.4/main/jitterbuf.c839
-rw-r--r--1.4/main/loader.c978
-rw-r--r--1.4/main/logger.c939
-rw-r--r--1.4/main/manager.c3068
-rw-r--r--1.4/main/md5.c267
-rw-r--r--1.4/main/netsock.c217
-rw-r--r--1.4/main/pbx.c6415
-rw-r--r--1.4/main/plc.c251
-rw-r--r--1.4/main/poll.c306
-rw-r--r--1.4/main/privacy.c119
-rw-r--r--1.4/main/rtp.c3824
-rw-r--r--1.4/main/say.c6959
-rw-r--r--1.4/main/sched.c400
-rw-r--r--1.4/main/sha1.c385
-rw-r--r--1.4/main/slinfactory.c177
-rw-r--r--1.4/main/srv.c246
-rw-r--r--1.4/main/stdtime/Makefile29
-rw-r--r--1.4/main/stdtime/localtime.c1650
-rw-r--r--1.4/main/stdtime/private.h358
-rw-r--r--1.4/main/stdtime/test.c21
-rw-r--r--1.4/main/stdtime/tzfile.h184
-rw-r--r--1.4/main/strcompat.c472
-rw-r--r--1.4/main/tdd.c328
-rw-r--r--1.4/main/term.c303
-rw-r--r--1.4/main/threadstorage.c229
-rw-r--r--1.4/main/translate.c972
-rw-r--r--1.4/main/udptl.c1250
-rw-r--r--1.4/main/ulaw.c106
-rw-r--r--1.4/main/utils.c1364
-rw-r--r--1.4/makeopts.in191
-rwxr-xr-x1.4/missing198
-rwxr-xr-x1.4/mkinstalldirs40
-rw-r--r--1.4/pbx/Makefile59
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest10/extensions.ael131
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest12/extensions.ael13
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/extensions.ael7
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/qq.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t1/a.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t1/b.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t1/c.ael13
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t2/d.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t2/e.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t2/f.ael9
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t3/g.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t3/h.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t3/i.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest22/t3/j.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/extensions.ael7
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/qq.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t1/a.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t1/b.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t1/c.ael13
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t2/d.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t2/e.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t2/f.ael9
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t3/g.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t3/h.ael6
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t3/i.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-ntest23/t3/j.ael6
-rwxr-xr-x1.4/pbx/ael/ael-test/ael-ntest9/extensions.ael12
-rw-r--r--1.4/pbx/ael/ael-test/ael-test1/extensions.ael163
-rw-r--r--1.4/pbx/ael/ael-test/ael-test11/extensions.ael56
-rw-r--r--1.4/pbx/ael/ael-test/ael-test14/extensions.ael20
-rw-r--r--1.4/pbx/ael/ael-test/ael-test15/extensions.ael17
-rw-r--r--1.4/pbx/ael/ael-test/ael-test16/extensions.ael4
-rw-r--r--1.4/pbx/ael/ael-test/ael-test18/extensions.ael40
-rw-r--r--1.4/pbx/ael/ael-test/ael-test19/extensions.ael377
-rw-r--r--1.4/pbx/ael/ael-test/ael-test2/apptest.ael2146
-rw-r--r--1.4/pbx/ael/ael-test/ael-test2/extensions.ael8
-rw-r--r--1.4/pbx/ael/ael-test/ael-test20/extensions.ael8
-rwxr-xr-x1.4/pbx/ael/ael-test/ael-test3/extensions.ael3183
-rw-r--r--1.4/pbx/ael/ael-test/ael-test3/include1.ael23
-rw-r--r--1.4/pbx/ael/ael-test/ael-test3/include2.ael24
-rw-r--r--1.4/pbx/ael/ael-test/ael-test3/include3.ael22
-rw-r--r--1.4/pbx/ael/ael-test/ael-test3/include4.ael22
-rw-r--r--1.4/pbx/ael/ael-test/ael-test3/include5.ael21
-rwxr-xr-x1.4/pbx/ael/ael-test/ael-test3/telemarket_torture.ael2812
-rw-r--r--1.4/pbx/ael/ael-test/ael-test4/apptest.ael2146
-rw-r--r--1.4/pbx/ael/ael-test/ael-test4/extensions.ael8
-rw-r--r--1.4/pbx/ael/ael-test/ael-test5/extensions.ael833
-rw-r--r--1.4/pbx/ael/ael-test/ael-test6/extensions.ael833
-rw-r--r--1.4/pbx/ael/ael-test/ael-test7/extensions.ael460
-rw-r--r--1.4/pbx/ael/ael-test/ael-test8/extensions.ael27
-rwxr-xr-x1.4/pbx/ael/ael-test/ael-vtest13/extensions.ael3183
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest13/include1.ael23
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest13/include2.ael24
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest13/include3.ael22
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest13/include4.ael22
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest13/include5.ael21
-rwxr-xr-x1.4/pbx/ael/ael-test/ael-vtest13/telemarket_torture.ael2812
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest17/extensions.ael116
-rw-r--r--1.4/pbx/ael/ael-test/ael-vtest21/extensions.ael14
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-ntest10158
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-ntest1231
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-ntest2255
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-ntest2325
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-ntest924
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test115
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test1114
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test1412
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test1513
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test1613
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test1812
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test1914
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test221
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test2012
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test318
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test421
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test512
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test617
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test714
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-test812
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-vtest132951
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-vtest1770
-rw-r--r--1.4/pbx/ael/ael-test/ref.ael-vtest219
-rwxr-xr-x1.4/pbx/ael/ael-test/runtests56
-rwxr-xr-x1.4/pbx/ael/ael-test/setref7
-rw-r--r--1.4/pbx/ael/ael.flex689
-rw-r--r--1.4/pbx/ael/ael.tab.c3374
-rw-r--r--1.4/pbx/ael/ael.tab.h152
-rw-r--r--1.4/pbx/ael/ael.y824
-rw-r--r--1.4/pbx/ael/ael_lex.c3119
-rw-r--r--1.4/pbx/dundi-parser.c831
-rw-r--r--1.4/pbx/dundi-parser.h88
-rw-r--r--1.4/pbx/pbx_ael.c4625
-rw-r--r--1.4/pbx/pbx_config.c2492
-rw-r--r--1.4/pbx/pbx_dundi.c4615
-rw-r--r--1.4/pbx/pbx_gtkconsole.c511
-rw-r--r--1.4/pbx/pbx_loopback.c183
-rw-r--r--1.4/pbx/pbx_realtime.c258
-rw-r--r--1.4/pbx/pbx_spool.c507
-rw-r--r--1.4/redhat/asterisk.spec137
-rw-r--r--1.4/redhat/rpmmacros3
-rw-r--r--1.4/redhat/rpmrc3
-rw-r--r--1.4/res/Makefile39
-rw-r--r--1.4/res/res_adsi.c1132
-rw-r--r--1.4/res/res_agi.c2193
-rw-r--r--1.4/res/res_clioriginate.c175
-rw-r--r--1.4/res/res_config_odbc.c562
-rw-r--r--1.4/res/res_config_pgsql.c842
-rw-r--r--1.4/res/res_convert.c224
-rw-r--r--1.4/res/res_crypto.c628
-rw-r--r--1.4/res/res_features.c2508
-rw-r--r--1.4/res/res_indications.c406
-rw-r--r--1.4/res/res_jabber.c2508
-rw-r--r--1.4/res/res_monitor.c714
-rw-r--r--1.4/res/res_musiconhold.c1353
-rw-r--r--1.4/res/res_odbc.c724
-rw-r--r--1.4/res/res_smdi.c1313
-rw-r--r--1.4/res/res_snmp.c115
-rw-r--r--1.4/res/res_speech.c404
-rw-r--r--1.4/res/snmp/agent.c823
-rw-r--r--1.4/res/snmp/agent.h40
-rw-r--r--1.4/sample.call80
-rw-r--r--1.4/sounds/Makefile158
-rw-r--r--1.4/sounds/sounds.xml68
-rw-r--r--1.4/static-http/ajamdemo.html219
-rw-r--r--1.4/static-http/astman.css34
-rw-r--r--1.4/static-http/astman.js262
-rw-r--r--1.4/static-http/prototype.js1781
-rw-r--r--1.4/utils/Makefile128
-rw-r--r--1.4/utils/ael_main.c585
-rw-r--r--1.4/utils/astman.1102
-rw-r--r--1.4/utils/astman.c746
-rw-r--r--1.4/utils/check_expr.c355
-rw-r--r--1.4/utils/expr2.testinput92
-rw-r--r--1.4/utils/frame.c1034
-rw-r--r--1.4/utils/frame.h300
-rw-r--r--1.4/utils/muted.c704
-rw-r--r--1.4/utils/smsq.c765
-rw-r--r--1.4/utils/stereorize.c159
-rw-r--r--1.4/utils/streamplayer.c121
915 files changed, 0 insertions, 448776 deletions
diff --git a/1.4/.cleancount b/1.4/.cleancount
deleted file mode 100644
index f5c89552b..000000000
--- a/1.4/.cleancount
+++ /dev/null
@@ -1 +0,0 @@
-32
diff --git a/1.4/BUGS b/1.4/BUGS
deleted file mode 100644
index 96b55e655..000000000
--- a/1.4/BUGS
+++ /dev/null
@@ -1,22 +0,0 @@
-Asterisk Bug Tracking Information
-=================================
-
-To learn about and report Asterisk bugs, please visit
-the official Asterisk Bug Tracker at:
-
- http://bugs.digium.com
-
-For more information on using the bug tracker, or to
-learn how you can contribute by acting as a bug marshal
-please see:
-
- http://www.asterisk.org/developers/bug-guidelines
-
-If you would like to submit a feature request, please
-resist the temptation to post it to the bug tracker.
-Feature requests should be posted to the asterisk-dev
-mailing list, located at:
-
- http://lists.digium.com
-
-Thank you!
diff --git a/1.4/CHANGES b/1.4/CHANGES
deleted file mode 100644
index 5b25d6959..000000000
--- a/1.4/CHANGES
+++ /dev/null
@@ -1,345 +0,0 @@
-Changes since Asterisk 1.2:
-
- * over 4,000 commits since 1.2
- * queue member naming
- * CLI commands rework
- o Change the way CLI commands are structured.
- o Most commands are now <module> <verb> <args>
- * chan_h323 update
- * RTP packetization
- * SLA (Shared Line Appearance) support
- * T.38 Passthrough Support for faxing in SIP
- * Generic channel jitterbuffer (spawned from RTP)
- * Variable Length DTMF for better DTMF compatibility
- * Improved chan_iax2 scalability by using multithreading
- * AEL2 has replaced the original implementation of AEL. The "2" is removed. For more details,
- read: http://www.voip-info.org/wiki/view/Asterisk+AEL2
- AEL is no longer considered experimental.
- * New sounds; English, Spanish, and French prompts, as well as music on hold files, in
- multiple Asterisk native formats.
- * IMAP storage of voicemail
- * Jabber/GoogleTalk integration
- * New speech recognition API for interfacing to different Voice Recognition software packages
- * much more customizable and portable build system
- o also for asterisk-addons
- * Radius CDR logging
- * SNMP support
- * SMDI (Simplified Message Desk Interface) support
- * Redesign of MusicOnHold configuration settings
- * Manager over HTTP
- * Significant chan_skinny updates
- * Significant chan_misdn updates
- * Improved SIP transfers
- * SIP MWI subscription support
- * Much improved support for SIP video
- * Control over SIP transfers and subscriptions (enable/disable per device)
- * ChanSpy whisper mode (Whisper Paging)
- * Configurable language support for saying dates and times
- * Significant architecture improvements for memory usage and performance
- * Media-only IAX2 transfers
- * Updates to the Radio Repeater app code
- * Deprecation of AgentCallbackLogin in favor of a dialplan-based solution
- * uClibc builds supported
- * Work done for freeBSD portability
- * Work done for Solaris portability
- * FreeTDS-based database can be used with Realtime
- * New internal data structure, stringfields, is implemented in IAX and SIP, reducing memory consumption by about 50%.
- * Use of thread local storage for reduced memory allocation/freeing and lower stack consumption
- * Reorganized files into docs/ main/ configs/, including name changes in some cases
- * Much effort was expended in arranging documentation in source files in doxygen format
- * Improved IP TOS support for IAX and SIP
- * Builtin mini HTTP server
- * Added support for Sigma Designs cards.
- * Frame header caching to reduce memory allocation/freeing
- * Passthrough and record/playback support for G.722 wideband audio
- * using mpg123 to play MP3 files for music-on-hold will be deprecated in 1.4 (start using the "native support")
- * New Apps:
- 1. AMD() ;; Answering Machine Detection
- 2. ChannelRedirect() ;; asynch goto, redirect chan to context/exten/priority
- 3. ContinueWhile() ;; Addition to the While() suite. Acts like "continue".
- 4. ExitWhile() ;; Addition to the While() suite. Acts like "break".
- 5. ExtenSpy() ;; A close cousin to ChanSpy().
- 6. FollowMe() ;; findme/followme call redirect app
- 7. Log() ;; Send a message to the log, based on severity level.
- 8. MacroExclusive() ;; No more than one invocation of this macro allowed at any one time.
- 9. MorseCode() ;; turns strings into dits and dahs. A playground for ham radio licensees!
- 10. OSPAuth() ;; OSP authentication
- 11. QueueLog() ;; allows you to write your own events into the queue log
- 12. SLAStation() ;; Shared Line Appearance
- 13. SLATrunk() ;; Shared Line Appearance
- 14. SpeechCreate() ;; Voice Recognition Engine interface...
- 15. SpeechActivateGrammar()
- 16. SpeechStart()
- 17. SpeechBackground
- 18. SpeechDeactivateGrammar()
- 19. SpeechProcessingSound()
- 20. SpeechDestroy()
- 21. SpeechLoadGrammar()
- 22. SpeechUnloadGrammar()
- 23. StopMixMonitor() ;; to stop the MixMonitor App.
- 24. TryExec() ;; execute dialplan app without fatal consequences
- * Apps removed:
- 1. CheckGroup -- do a comparison to ${GROUP()}
- 2. Curl -- use the function CURL() instead
- 3. Cut -- use the function CUT() instead
- 4. DateTime -- use sayunixtime() app instead.
- 5. DBget -- deprecated in 1.2, now removed.
- 6. DBput -- deprecated in 1.2, now removed.
- 7. Enumlookup -- use the function ENUMLOOKUP() instead
- 8. Eval -- use the function EVAL() instead
- 9. GetGroupCount -- use the function GROUP_COUNT() instead
- 10. GetGroupMatchCount -- use the function GROUP_MATCH_COUNT() instead
- 11. Intercom -- use the chan_oss module instead
- 12. Math -- use the function MATH() instead
- 13. MD5 -- use the function MD5() instead
- 14. SetCIDname -- use the function CALLERID(name) instead
- 15. SetCIDnum -- use the function CALLERID(number) instead
- 16. SetGroup -- use Set(GROUP=group) instead
- 17. SetRDNIS -- use the function CALLERID(rdnis) instead
- 18. Sql_postgres -- was deprecated in 1.2, now removed
- 19. Txtcidname -- use the function TXTCIDNAME instead
- * New Dialplan Functions:
- 1. ARRAY()
- 2. BASE_64_DECODE()
- 3. BASE_64_ENCODE()
- 4. CHANNEL()
- 5. CURL()
- 6. CUT()
- 7. DB_DELETE()
- 8. FILTER()
- 9. GLOBAL()
- 10. IFTIME()
- 11. KEYPADHASH()
- 12. ODBC()
- 13. QUOTE()
- 14. RAND()
- 15. REALTIME()
- 16. SHA1()
- 17. SORT()
- 18. SPRINTF()
- 19. SQL_ESC()
- 20. STAT()
- 21. STRPTIME()
- * Apps that have changes to their interface:
- 1. Authenticate() -- optional maxdigits argument added.
- 2. ChanSpy() -- new options:
- o w -- Enable 'whisper' mode, so the spying channel can talk to...
- o W -- Enable 'private whisper' mode, so the spying channel can...
- 3. DBdel() -- now marked as DEPRECATED in favor of the DB_DELETE func
- 4. Dial()
- o New Option: O([x]) for Zaptel operator mode
- o New Option: K/k parking via dtmf tones
- 5. Dictate() -- optional filename argument added.
- 6. Directory() -- new option: e - In addition to the name, also read the extension number...
- 7. Meetme() -- new options:
- o 'I' -- announce user join/leave without review
- o 'l' -- set listen only mode (Listen only, no talking)
- o 'o' -- set talker optimization - treats talkers who aren't speaking as...
- o '1' -- do not play message when first person enters
- 8. MeetmeAdmin() -- new options:
- o 'r' -- Reset one user's volume settings
- o 'R' -- Reset all users volume settings
- o 's' -- Lower entire conference speaking volume
- o 'S' -- Raise entire conference speaking volume
- o 't' -- Lower one user's talk volume
- o 'T' -- Lower all users talk volume
- o 'u' -- Lower one user's listen volume
- o 'U' -- Lower all users listen volume
- o 'v' -- Lower entire conference listening volume
- o 'V' -- Raise entire conference listening volume
- 9. OSPFinish() : now also can return ERROR result.
- 10. OSPLookup() : Sets more variables, also now returns ERROR result.
- 11. Page() -- New option: r - record the page into a file (see 'r' for app_meetme)
- 12. Pickup() -- multiple extensions, PICKUPMARK; read the description!
- 13. Queue()
- o New Argument: AGI
- o New option: i
- 14. Random() -- is now deprecated in 1.4
- 15. Read() -- replace 'skip' and 'noanswer' options with 's', 'n', add 'i' option.
- 16. Record() -- New option: 'x' : ignore all terminator keys (DTMF) and keep recording until hangup
- 17. UserEvent() -- slight change in behavior. Read the description.
- 18. VoiceMailMain() -- new a(#) option, goes to folder # directly.
- 19. WaitForSilence() -- new optional 3rd arg, time delay before returning.
- * Functions that have changes to their interfaces:
- 1. CDR -- new option: u
- 2. LANGUAGE -- Deprecated. Use CHANNEL(language) instead.
- 3. MUSICCLASS -- Deprecated. Use CHANNEL(musicclass) instead.
- * Configuration File Changes:
- 1. NEW config files:
- 1. amd.conf -- Answering Machine Detection parameters
- 2. followme.conf -- parameters for the findme/followme call forwarding
- 3. func_odbc.conf -- define sql access functions here
- 4. gtalk.conf -- how to handle gtalk protocol calls
- 5. h323.conf -- h323 configuration
- 6. http.conf -- config for the builtin mini-http server in asterisk
- 7. jabber.conf -- jabber interface
- 8. jingle.conf -- jingle protocol interface config
- 10. res_snmp.conf -- to enable snmp in asterisk, and define full/sub agent status
- 11. say.conf -- define per-language rules for numbers, dates, etc.
- 12. skinny.conf -- for those special skinny phones you want to use...
- 13. sla.conf -- Shared Line Appearance config
- 14. smdi.conf -- SMDI messaging config
- 15. udptl.conf -- T38's udptl transport config
- 16. users.conf -- user config
- 2. Changes to Existing Config files:
- 1. In General:
- o Jitterbuffer support added to several channels. Usually adds these variables to a config file:
- 1. jbenable
- 2. jbmaxsize
- 3. jbresyncthreshold
- 4. jbimpl
- 5. jblog
- o MusicOnHold upgrade introduces two new variables:
- 1. mohinterpret
- 2. mohsuggest
- 2. agents.conf
- o maxlogintries variable added
- o autologoffunavail variable added
- o endcall variable added
- o agentgoodbye variable added
- o createlink variable REMOVED
- 3. alsa.conf
- o mohinterpret variable added
- o Jitterbuffer variables added
- 4. cdr.conf
- o endbeforehexten variable added
- o sections for csv and radius added, with variables usegmtime, loguniqueid,
- loguserfield, and radiuscfg variables.
- 5. cdr_tds.conf
- o table variable added
- 6. extensions.ael
- o Many upgrades. See the info at http://www.voip-info.org/wiki/view/Asterisk+AEL2
- 7. extensions.conf
- o autofallthru now set to "yes" by default
- o userscontext variable added
- o added info/examples on paging and hints.
- 8. features.conf
- o parkedplay variable added (who to beep at)
- o parkedmusicclass
- o atxfernoanswertimeout variable added
- o parkcall variable added (one step parking)
- o improved documentation for dynamic feature declarations!
- 9. iax.conf
- o adsi variable added
- o mohinterpret variable added
- o mohsuggest variable added
- o jitterbuffer updates
- o iaxthreadcount variable added
- o iaxmaxthreadcount variable added
- o the way to specify TOS has changed.
- o mailboxdetail variable has been REMOVED.
- 10. indications.conf
- o [bg] entry added (Bulgaria).
- o [il] entry added (Israel)
- o [in] entry added (India)
- o [jp] entry added (Japan)
- o [my] entry added (Malaysia)
- o [th] entry added (Thailand)
- 11. manager.conf
- o webenabled variable added
- o httptimeout variable added
- o timestampevents variable added
- 12. mgcp.conf
- o Jitterbuffer support added
- 13. misdn.conf
- o l1watcher_timeout variable added
- o pp_l2_check variable added
- o echocancelwhenbridged variable added
- o echotraining variable added
- o max_incoming variable added
- o max_outgoing variable added
- 14. modules.conf
- o a comment for preloading res_speech.so is added
- o mention of global symbols is removed
- o obsolesced entries for chan_modem_* and app_intercom have been removed
- 15. musiconhold.conf
- o the default is now to do native moh from /var/lib/asterisk/moh
- 16. osp.conf
- o authpolicy variable added
- 17. oss.conf
- o debug variable added
- o device variable added
- o mixer variable added
- o boost variable added
- o callerid variable added
- o autohangup variable added
- o queuesize variable added
- o frags variable added
- o JitterBuffer support
- o sections to define alternate sound cards
- 18. queues.conf
- o autofill variable added
- o monitor-type variable added
- o musiconhold is now musicclass, with a difference in interpretation
- o autofill variable added
- o autopause variable added
- o setinterfacevar variable added
- o ringinuse variable added
- 19. res_odbc.conf
- o pooling variable added
- 20. rpt.conf
- o duplex variable added
- o tailmessagetime variable added
- o tailsquashedtime variable added
- o tailmessages variable added
- 21. rtp.conf
- o rtcpinterval varaible added
- 22. sip.conf
- o allowoverlap variable added
- o allowtransfer variable added
- o tos variable REMOVED
- o tos_sip variable added
- o tos_audio variable added
- o tos_video variable added
- o minexpiry variable added
- o t1min variable added
- o musicclass variable REMOVED
- o mohinterpret variable added
- o maxcallbitratesuggest variable added
- o allowsubscribe variable added
- o videosupport variable added
- o maxcallbitrate variable added
- o g726nonstandard variable added
- o dumphistory variable added
- o allowsubscribe variable added
- o t38pt_udptl variable added
- o canreinvite variable can also now be set to 'nonat'
- o rtsavesysname variable added
- o JitterBuffer support added
- 23. skinny.conf
- o port variable renamed to bindport
- o JitterBuffer support added
- o model variable REMOVED
- o mohinterpret variable added
- o mohsuggest variable added
- o speeddial variable added
- o addon variable added
- 24. voicemail.conf
- o userscontext variable added
- o smdiport variable added
- o attachfmt variable added
- o volgain variable added
- o tempgreetwarn variable added
- 25. zapata.conf
- o pritimer variable has improved documentation
- o New signalling method: fgccama
- o New signalling method: fgccamamf
- o outsignalling variable added
- o distinctiveringaftercid variable added
- o cidsignalling now also accepts v23_jp, and smdi
- o usesmdi variable added
- o smdiport variable added
- o mohinterpret variable added
- o mohsuggest variable added
- o JitterBuffer support added
- * Removed Codecs/Channels:
- 1. codec_g723 was removed because the actual codec implementation it was designed to use is not distributable
- 2. chan_modem_* and related modules are gone because the kernel support for those interfaces is old, buggy and unsupported
- * New Utils:
- 1. aelparse -- compile .ael files outside of asterisk
- * New manager events:
- 1. OriginateResponse event comes to replace OriginateSuccess and OriginateFailure
- * iLBC source code no longer included (see UPGRADE.txt for details)
- * New CLI command "pri show version" that shows the current version of libpri
- that the library was built against (requires a version of libpri since this API
- feature was added).
diff --git a/1.4/COPYING b/1.4/COPYING
deleted file mode 100644
index aa2ebac66..000000000
--- a/1.4/COPYING
+++ /dev/null
@@ -1,341 +0,0 @@
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/1.4/CREDITS b/1.4/CREDITS
deleted file mode 100644
index a51638214..000000000
--- a/1.4/CREDITS
+++ /dev/null
@@ -1,215 +0,0 @@
-
-=== DEVELOPMENT SUPPORT ===
-We'd like to thank the following companies for helping fund development of
-Asterisk:
-
-Pilosoft, Inc. - for supporting ADSI development in Asterisk
-
-Asterlink, Inc. - for supporting broad Asterisk development
-
-GFS - for supporting ALSA development
-
-Telesthetic - for supporting SIP development
-
-Christos Ricudis - for substantial code contributions
-
-nic.at - ENUM support in Asterisk
-
-Paul Bagyenda, Digital Solutions - for initial Voicetronix driver development
-
-=== WISHLIST CONTRIBUTERS ===
-Jeremy McNamara - SpeeX support
-Nick Seraphin - RDNIS support
-Gary - Phonejack ADSI (in progress)
-Wasim - Hangup detect
-
-=== HARDWARE DONORS ===
-* Thanks to QuickNet Technologies for their donation of an Internet
-PhoneJack and Linejack card to the project. (http://www.quicknet.net)
-
-* Thanks to VoipSupply for their donation of Sipura ATAs to the project for
-T.38 testing. (http://www.voipsupply.com)
-
-* Thanks to Grandstream for their donation of ATAs to the project for
-T.38 testing. (http://www.grandstream.com)
-
-=== MISCELLANEOUS PATCHES ===
-Jim Dixon - Zapata Telephony and app_rpt
- http://www.zapatatelephony.org/app_rpt.html
-
-Russell Bryant - Asterisk 1.0 maintainer and misc. enhancements
- russelb@clemson.edu
-
-Anthony Minessale II - Countless big and small fixes, and relentless forward push
- ChanSpy, ForkCDR, ControlPlayback, While/EndWhile, DumpChan, Dictate,
- MacroIf, ExecIf, ExecIfTime, RetryDial, MixMonitor applications; many realtime
- concepts and implementation pieces, including res_config_odbc; format_slin;
- cdr_custom; several features in Dial including L(), G() and enhancements to
- M() and D(); several CDR enhancements including CDR variables; attended
- transfer; one touch record; native MOH; manager eventmask; command line '-t'
- flag to allow recording/voicemail on nfs shares; #exec command and multiline
- comments in config files; setvar in iax and sip configs.
- anthmct@yahoo.com http://www.asterlink.com
-
-James Golovich - Innumerable contributions
- You can find him and asterisk-perl at http://asterisk.gnuinter.net
-
-Andre Bierwirth - Extension hints and status
-
-Oliver Daudey - ISDN4Linux fixes
-
-Pauline Middelink - ISDN4Linux patches and some general patches.
- She can be found at http://www.polyware.nl/~middelink/En/
-
-Jean-Denis Girard - Various contributions from the South Pacific Islands
- jd-girard@esoft.pf http://www.esoft.pf
-
-William Jordan / Vonage - MySQL enhancements to Voicemail
- wjordan@vonage.com
-
-Jac Kersing - Various fixes
-
-Steven Critchfield - Seek and Trunc functions for playback and recording
- critch@basesys.com
-
-Jefferson Noxon - app_lookupcidname, app_db, and various other contributions
-
-Klaus-Peter Junghanns - in-band DTMF on SIP and MGCP
-
-Ross Finlayson - Dynamic RTP payload support
-
-Mahmut Fettahlioglu - Audio recording, music-on-hold changes, alaw file
- format, and various fixes. Can be contacted at mahmut@oa.com.au
-
-James Dennis - Cisco SIP compatibility patches to work with SIP service
- providers. Can be contacted at asterisk@jdennis.net
-
-Tilghman Lesher - ast_localtime(); ast_say_date_with_format();
- GotoIfTime, Random, SayUnixTime, HasNewVoicemail applications;
- CUT, SORT, EVAL, CURL, FIELDQTY, STRFTIME, QUEUEAGENT* functions;
- and other innumerable bug fixes. http://asterisk.drunkcoder.com/
-
-Jayson Vantuyl - Manager protocol changes, various other bugs.
- jvantuyl@computingedge.net
-
-Thorsten Lockert - OpenBSD, FreeBSD ports, making MacOS X port run on 10.3,
- dialplan include verification, route lookup on OpenBSD, SNMP agent
- support (res_snmp), various other bugs. tholo@sigmasoft.com
-
-Brian West - ODBC support and Bug Marshaling
-
-Josh Roberson - chan_zap reload support, Advanced Voicemail Features, other misc. patches,
- and Bug Marshalling. - josh@asteriasgi.com, http://www.asteriasgi.com
-
-William Waites - syslog support, SIP NAT traversal for SIP-UA. ww@styx.org
-
-Rich Murphey - Porting to FreeBSD, NetBSD, OpenBSD, and Darwin.
- rich@whiteoaklabs.com http://whiteoaklabs.com
-
-Simon Lockhart - Porting to Solaris (based on work of Logan ???)
- simon@slimey.org
-
-Olle E. Johansson - SIP RFC compliance, documentation and testing, testing, testing
- oej@edvina.net, http://edvina.net
-
-Steve Kann - new jitter buffer for IAX2
- stevek@stevek.com
-
-Constantine Filin - major contributions to the Asterisk Realtime Architecture
-
-Steve Murphy - privacy support, $[ ] parser upgrade, AEL2 parser upgrade
-
-Claude Patry - bug fixes, feature enhancements, and bug marshalling
- cpatry@gmail.com
-
-Miroslav Nachev, miro@space-comm.com COSMOS Software Enterprises, Ltd.
- - for Variable for No Answer Timeout for Attended Transfer
-
-Slav Klenov & Vanheuverzwijn Joachim - development of the generic jitterbuffer
- Securax Ltd. info@securax.be
-
-Roy Sigurd Karlsbakk - providing funding for generic jitterbuffer development
- roy@karlsbakk.net, Briiz Telecom AS
-
-Voop A/S, Nuvio Inc, Inotel S.A and Foniris Telecom A/S - funding for rewrite of SIP transfers
-
-Philippe Sultan - RADIUS CDR module
- INRIA, http://www.inria.fr/
-
-John Martin, Aupix - Improved video support in the SIP channel
-
-Steve Underwood - Provided T.38 pass through support.
-
-George Konstantoulakis - Support for Greek in voicemail added by InAccess Networks (work funded by HOL, www.hol.gr) gkon@inaccessnetworks.com
-
-Daniel Nylander - Support for Swedish and Norwegian languages in voicemail. http://www.danielnylander.se/
-
-Stojan Sljivic - An option for maximum number of messsages per mailbox in voicemail. Also an issue with voicemail synchronization has been fixed. GDS Partners www.gdspartners.com . stojan.sljivic@gdspartners.com
-
-Bartosz Supczinski - Support for Polish added by DIR (www.dir.pl) Bartosz.Supczinski@dir.pl
-
-James Rothenberger - Support for IMAP storage integration added by OneBizTone LLC Work funded by University of Pennsylvania jar@onebiztone.com
-
-Paul Cadach - Bringing chan_h323 up to date, bug fixes, and more!
-
-=== OTHER CONTRIBUTIONS ===
-John Todd - Monkey sounds and associated teletorture prompt
-Michael Jerris - bug marshaling
-Leif Madsen, Jared Smith and Jim van Meggelen - the Asterisk book
- available under a Creative Commons License at http://www.asteriskdocs.org
-Brian M. Clapper - poll.c emulation
- This product includes software developed by Brian M. Clapper <bmc@clapper.org>
-
-=== HOLD MUSIC ===
-Music provided by www.freeplaymusic.com
-
-=== OTHER SOURCE CODE IN ASTERISK ===
-Asterisk uses libedit, the lightweight readline replacement from NetBSD.
-The cdr_radius module uses libradiusclient-ng, which is also from NetBSD.
-They are BSD-licensed and require the following statement:
-
- This product includes software developed by the NetBSD
- Foundation, Inc. and its contributors.
-
-Digium did not implement the codecs in Asterisk. Here is the copyright on the
-GSM source:
-
-Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
-Technische Universitaet Berlin
-
-Any use of this software is permitted provided that this notice is not
-removed and that neither the authors nor the Technische Universitaet Berlin
-are deemed to have made any representations as to the suitability of this
-software for any purpose nor are held responsible for any defects of
-this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
-
-As a matter of courtesy, the authors request to be informed about uses
-this software has found, about bugs in this software, and about any
-improvements that may be of general interest.
-
-Berlin, 28.11.1994
-Jutta Degener
-Carsten Bormann
-
-And the copyright on the ADPCM source:
-
-Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Stichting Mathematisch
-Centrum or CWI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/1.4/LICENSE b/1.4/LICENSE
deleted file mode 100644
index 4818d15d6..000000000
--- a/1.4/LICENSE
+++ /dev/null
@@ -1,68 +0,0 @@
-Asterisk is distributed under the GNU General Public License version 2
-and is also available under alternative licenses negotiated directly
-with Digium, Inc. If you obtained Asterisk under the GPL, then the GPL
-applies to all loadable Asterisk modules used on your system as well,
-except as defined below. The GPL (version 2) is included in this
-source tree in the file COPYING.
-
-This package also includes various components that are not part of
-Asterisk itself; these components are in the 'contrib' directory
-and its subdirectories. Most of these components are also
-distributed under the GPL version 2 as well, except for the following:
-
-contrib/firmware/iax/iaxy.bin:
- This file is Copyright (C) Digium, Inc. and is licensed for
- use with Digium IAXy hardware devices only. It can be
- distributed freely as long as the distribution is in the
- original form present in this package (not reformatted or
- modified).
-
-Digium, Inc. (formerly Linux Support Services) holds copyright
-and/or sufficient licenses to all components of the Asterisk
-package, and therefore can grant, at its sole discretion, the ability
-for companies, individuals, or organizations to create proprietary or
-Open Source (even if not GPL) modules which may be dynamically linked at
-runtime with the portions of Asterisk which fall under our
-copyright/license umbrella, or are distributed under more flexible
-licenses than GPL.
-
-If you wish to use our code in other GPL programs, don't worry --
-there is no requirement that you provide the same exception in your
-GPL'd products (although if you've written a module for Asterisk we
-would strongly encourage you to make the same exception that we do).
-
-Specific permission is also granted to link Asterisk with OpenSSL and
-OpenH323 and distribute the resulting binary files.
-
-In addition, Asterisk implements two management/control protocols: the
-Asterisk Manager Interface (AMI) and the Asterisk Gateway Interface
-(AGI). It is our belief that applications using these protocols to
-manage or control an Asterisk instance do not have to be licensed
-under the GPL or a compatible license, as we believe these protocols
-do not create a 'derivative work' as referred to in the GPL. However,
-should any court or other judiciary body find that these protocols do
-fall under the terms of the GPL, then we hereby grant you a license to
-use these protocols in combination with Asterisk in external
-applications licensed under any license you wish.
-
-The 'Asterisk' name and logos are trademarks owned by Digium, Inc.,
-and use of them is subject to our trademark licensing policies. If you
-wish to use these trademarks for purposes other than simple
-redistribution of Asterisk source code obtained from Digium, you
-should contact our licensing department to determine the necessary
-steps you must take. For more information on this policy, please read
-http://www.digium.com/en/company/profile/trademarkpolicy.php
-
-If you have any questions regarding our licensing policy, please
-contact us:
-
-+1.877.344.4861 (via telephone in the USA)
-+1.256.428.6000 (via telephone outside the USA)
-+1.256.864.0464 (via FAX inside or outside the USA)
-IAX2/misery.digium.com/6000 (via IAX2)
-licensing@digium.com (via email)
-
-Digium, Inc.
-445 Jan Davis Drive
-Huntsville, AL 35806
-USA
diff --git a/1.4/Makefile b/1.4/Makefile
deleted file mode 100644
index 11e35e10b..000000000
--- a/1.4/Makefile
+++ /dev/null
@@ -1,777 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Top level Makefile
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# Mark Spencer <markster@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
-# All Makefiles use the following variables:
-#
-# ASTCFLAGS - compiler options
-# ASTLDFLAGS - linker flags (not libraries)
-# AST_LIBS - libraries to build binaries XXX
-# LIBS - additional libraries, at top-level for all links,
-# on a single object just for that object
-# SOLINK - linker flags used only for creating shared objects (.so files),
-# used for all .so links
-#
-# Default values fo ASTCFLAGS and ASTLDFLAGS can be specified in the
-# environment when running make, as follows:
-#
-# $ ASTCFLAGS="-Werror" make
-
-export ASTTOPDIR
-export ASTERISKVERSION
-export ASTERISKVERSIONNUM
-export INSTALL_PATH
-export ASTETCDIR
-export ASTVARRUNDIR
-export MODULES_DIR
-export ASTSPOOLDIR
-export ASTVARLIBDIR
-export ASTDATADIR
-export ASTLOGDIR
-export ASTLIBDIR
-export ASTMANDIR
-export ASTHEADERDIR
-export ASTBINDIR
-export ASTSBINDIR
-export AGI_DIR
-export ASTCONFPATH
-export NOISY_BUILD
-export MENUSELECT_CFLAGS
-export CC
-export CXX
-export AR
-export RANLIB
-export HOST_CC
-export STATIC_BUILD
-export INSTALL
-export DESTDIR
-export PROC
-export SOLINK
-export STRIP
-export DOWNLOAD
-export AWK
-export GREP
-export ID
-export OSARCH
-export CURSES_DIR
-export NCURSES_DIR
-export TERMCAP_DIR
-export TINFO_DIR
-export GTK2_LIB
-export GTK2_INCLUDE
-
-# even though we could use '-include makeopts' here, use a wildcard
-# lookup anyway, so that make won't try to build makeopts if it doesn't
-# exist (other rules will force it to be built if needed)
-ifneq ($(wildcard makeopts),)
- include makeopts
-endif
-
-# Some build systems, such as the one in openwrt, like to pass custom target
-# CFLAGS and LDFLAGS in the COPTS and LDOPTS variables.
-ASTCFLAGS+=$(COPTS)
-ASTLDFLAGS+=$(LDOPTS)
-
-#Uncomment this to see all build commands instead of 'quiet' output
-#NOISY_BUILD=yes
-
-# Create OPTIONS variable
-OPTIONS=
-
-empty:=
-space:=$(empty) $(empty)
-ASTTOPDIR:=$(subst $(space),\$(space),$(CURDIR))
-
-# Overwite config files on "make samples"
-OVERWRITE=y
-
-# Include debug and macro symbols in the executables (-g) and profiling info (-pg)
-DEBUG=-g3
-
-# Staging directory
-# Files are copied here temporarily during the install process
-# For example, make DESTDIR=/tmp/asterisk woud put things in
-# /tmp/asterisk/etc/asterisk
-# !!! Watch out, put no spaces or comments after the value !!!
-#DESTDIR?=/tmp/asterisk
-
-# Define standard directories for various platforms
-# These apply if they are not redefined in asterisk.conf
-ifeq ($(OSARCH),SunOS)
- ASTETCDIR=/var/etc/asterisk
- ASTLIBDIR=/opt/asterisk/lib
- ASTVARLIBDIR=/var/opt/asterisk
- ASTSPOOLDIR=/var/spool/asterisk
- ASTLOGDIR=/var/log/asterisk
- ASTHEADERDIR=/opt/asterisk/include
- ASTBINDIR=/opt/asterisk/bin
- ASTSBINDIR=/opt/asterisk/sbin
- ASTVARRUNDIR=/var/run/asterisk
- ASTMANDIR=/opt/asterisk/man
-else
- ASTETCDIR=$(sysconfdir)/asterisk
- ASTLIBDIR=$(libdir)/asterisk
- ASTHEADERDIR=$(includedir)/asterisk
- ASTBINDIR=$(bindir)
- ASTSBINDIR=$(sbindir)
- ASTSPOOLDIR=$(localstatedir)/spool/asterisk
- ASTLOGDIR=$(localstatedir)/log/asterisk
- ASTVARRUNDIR=$(localstatedir)/run
- ASTMANDIR=$(mandir)
-ifneq ($(findstring BSD,$(OSARCH)),)
- ASTVARLIBDIR=$(prefix)/share/asterisk
- ASTVARRUNDIR=$(localstatedir)/run/asterisk
-else
- ASTVARLIBDIR=$(localstatedir)/lib/asterisk
-endif
-endif
-ifeq ($(ASTDATADIR),)
- ASTDATADIR:=$(ASTVARLIBDIR)
-endif
-
-# Asterisk.conf is located in ASTETCDIR or by using the -C flag
-# when starting Asterisk
-ASTCONFPATH=$(ASTETCDIR)/asterisk.conf
-MODULES_DIR=$(ASTLIBDIR)/modules
-AGI_DIR=$(ASTDATADIR)/agi-bin
-
-# If you use Apache, you may determine by a grep 'DocumentRoot' of your httpd.conf file
-HTTP_DOCSDIR=/var/www/html
-# Determine by a grep 'ScriptAlias' of your Apache httpd.conf file
-HTTP_CGIDIR=/var/www/cgi-bin
-
-# Uncomment this to use the older DSP routines
-#ASTCFLAGS+=-DOLD_DSP_ROUTINES
-
-# If the file .asterisk.makeopts is present in your home directory, you can
-# include all of your favorite menuselect options so that every time you download
-# a new version of Asterisk, you don't have to run menuselect to set them.
-# The file /etc/asterisk.makeopts will also be included but can be overridden
-# by the file in your home directory.
-
-GLOBAL_MAKEOPTS=$(wildcard /etc/asterisk.makeopts)
-USER_MAKEOPTS=$(wildcard ~/.asterisk.makeopts)
-
-MOD_SUBDIR_CFLAGS=-I$(ASTTOPDIR)/include
-OTHER_SUBDIR_CFLAGS=-I$(ASTTOPDIR)/include
-
-ifeq ($(OSARCH),linux-gnu)
- ifeq ($(PROC),x86_64)
- # You must have GCC 3.4 to use k8, otherwise use athlon
- PROC=k8
- #PROC=athlon
- endif
-
- ifeq ($(PROC),sparc64)
- #The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
- #This works for even old (2.96) versions of gcc and provides a small boost either way.
- #A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesn't support it.
- #So we go lowest common available by gcc and go a step down, still a step up from
- #the default as we now have a better instruction set to work with. - Belgarath
- PROC=ultrasparc
- OPTIONS+=$(shell if $(CC) -mtune=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mtune=$(PROC)"; fi)
- OPTIONS+=$(shell if $(CC) -mcpu=v8 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mcpu=v8"; fi)
- OPTIONS+=-fomit-frame-pointer
- endif
-
- ifeq ($(PROC),arm)
- # The Cirrus logic is the only heavily shipping arm processor with a real floating point unit
- ifeq ($(SUB_PROC),maverick)
- OPTIONS+=-fsigned-char -mcpu=ep9312
- else
- ifeq ($(SUB_PROC),xscale)
- OPTIONS+=-fsigned-char -mcpu=xscale
- else
- OPTIONS+=-fsigned-char
- endif
- endif
- endif
-endif
-
-ifeq ($(findstring -save-temps,$(ASTCFLAGS)),)
-ASTCFLAGS+=-pipe
-endif
-
-ASTCFLAGS+=-Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(DEBUG)
-
-ASTCFLAGS+=-include $(ASTTOPDIR)/include/asterisk/autoconfig.h
-
-ifeq ($(AST_DEVMODE),yes)
- ASTCFLAGS+=-Werror -Wunused $(AST_DECLARATION_AFTER_STATEMENT)
-endif
-
-ifneq ($(findstring BSD,$(OSARCH)),)
- ASTCFLAGS+=-I/usr/local/include
- ASTLDFLAGS+=-L/usr/local/lib
-endif
-
-ifneq ($(PROC),ultrasparc)
- ASTCFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
-endif
-
-ifeq ($(PROC),ppc)
- ASTCFLAGS+=-fsigned-char
-endif
-
-ifeq ($(OSARCH),FreeBSD)
- # -V is understood by BSD Make, not by GNU make.
- BSDVERSION=$(shell make -V OSVERSION -f /usr/share/mk/bsd.port.subdir.mk)
- ASTCFLAGS+=$(shell if test $(BSDVERSION) -lt 500016 ; then echo "-D_THREAD_SAFE"; fi)
- AST_LIBS+=$(shell if test $(BSDVERSION) -lt 502102 ; then echo "-lc_r"; else echo "-pthread"; fi)
-endif
-
-ifeq ($(OSARCH),NetBSD)
- ASTCFLAGS+=-pthread -I/usr/pkg/include
-endif
-
-ifeq ($(OSARCH),OpenBSD)
- ASTCFLAGS+=-pthread
-endif
-
-ifeq ($(OSARCH),SunOS)
- ASTCFLAGS+=-Wcast-align -DSOLARIS -I../include/solaris-compat -I/opt/ssl/include -I/usr/local/ssl/include
-endif
-
-ASTERISKVERSION:=$(shell GREP=$(GREP) AWK=$(AWK) build_tools/make_version .)
-
-ifneq ($(wildcard .version),)
- ASTERISKVERSIONNUM:=$(shell $(AWK) -F. '{printf "%01d%02d%02d", $$1, $$2, $$3}' .version)
- RPMVERSION:=$(shell sed 's/[-\/:]/_/g' .version)
-else
- RPMVERSION=unknown
-endif
-
-ifneq ($(wildcard .svn),)
- ASTERISKVERSIONNUM=999999
-endif
-
-ASTCFLAGS+=$(MALLOC_DEBUG)$(BUSYDETECT)$(OPTIONS)
-
-MOD_SUBDIRS:=res channels pbx apps codecs formats cdr funcs main
-OTHER_SUBDIRS:=utils agi
-SUBDIRS:=$(OTHER_SUBDIRS) $(MOD_SUBDIRS)
-SUBDIRS_INSTALL:=$(SUBDIRS:%=%-install)
-SUBDIRS_CLEAN:=$(SUBDIRS:%=%-clean)
-SUBDIRS_DIST_CLEAN:=$(SUBDIRS:%=%-dist-clean)
-SUBDIRS_UNINSTALL:=$(SUBDIRS:%=%-uninstall)
-MOD_SUBDIRS_EMBED_LDSCRIPT:=$(MOD_SUBDIRS:%=%-embed-ldscript)
-MOD_SUBDIRS_EMBED_LDFLAGS:=$(MOD_SUBDIRS:%=%-embed-ldflags)
-MOD_SUBDIRS_EMBED_LIBS:=$(MOD_SUBDIRS:%=%-embed-libs)
-MOD_SUBDIRS_MENUSELECT_TREE:=$(MOD_SUBDIRS:%=%-menuselect-tree)
-
-ifneq ($(findstring darwin,$(OSARCH)),)
- ASTCFLAGS+=-D__Darwin__
- AUDIO_LIBS=-framework CoreAudio
- SOLINK=-dynamic -bundle -undefined suppress -force_flat_namespace
-else
-# These are used for all but Darwin
- SOLINK=-shared -Xlinker -x
- ifneq ($(findstring BSD,$(OSARCH)),)
- LDFLAGS+=-L/usr/local/lib
- endif
-endif
-
-ifeq ($(OSARCH),SunOS)
- SOLINK=-shared -fpic -L/usr/local/ssl/lib
-endif
-
-SUBMAKE=$(MAKE) --quiet --no-print-directory
-
-# This is used when generating the doxygen documentation
-ifneq ($(DOT),:)
- HAVEDOT=yes
-else
- HAVEDOT=no
-endif
-
-all: _all
- @echo " +--------- Asterisk Build Complete ---------+"
- @echo " + Asterisk has successfully been built, and +"
- @echo " + can be installed by running: +"
- @echo " + +"
-ifeq ($(MAKE), gmake)
- @echo " + $(MAKE) install +"
-else
- @echo " + $(MAKE) install +"
-endif
- @echo " +-------------------------------------------+"
-
-_all: cleantest $(SUBDIRS)
-
-makeopts: configure
- @echo "****"
- @echo "**** The configure script must be executed before running '$(MAKE)'."
- @echo "**** Please run \"./configure\"."
- @echo "****"
- @exit 1
-
-menuselect.makeopts: menuselect/menuselect menuselect-tree
- menuselect/menuselect --check-deps menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS)
-
-$(MOD_SUBDIRS_EMBED_LDSCRIPT):
- @echo "EMBED_LDSCRIPTS+="`$(SUBMAKE) -C $(@:-embed-ldscript=) SUBDIR=$(@:-embed-ldscript=) __embed_ldscript` >> makeopts.embed_rules
-
-$(MOD_SUBDIRS_EMBED_LDFLAGS):
- @echo "EMBED_LDFLAGS+="`$(SUBMAKE) -C $(@:-embed-ldflags=) SUBDIR=$(@:-embed-ldflags=) __embed_ldflags` >> makeopts.embed_rules
-
-$(MOD_SUBDIRS_EMBED_LIBS):
- @echo "EMBED_LIBS+="`$(SUBMAKE) -C $(@:-embed-libs=) SUBDIR=$(@:-embed-libs=) __embed_libs` >> makeopts.embed_rules
-
-$(MOD_SUBDIRS_MENUSELECT_TREE):
- @$(SUBMAKE) -C $(@:-menuselect-tree=) SUBDIR=$(@:-menuselect-tree=) moduleinfo
- @$(SUBMAKE) -C $(@:-menuselect-tree=) SUBDIR=$(@:-menuselect-tree=) makeopts
-
-makeopts.embed_rules: menuselect.makeopts
- @echo "Generating embedded module rules ..."
- @rm -f $@
- @$(MAKE) --no-print-directory $(MOD_SUBDIRS_EMBED_LDSCRIPT)
- @$(MAKE) --no-print-directory $(MOD_SUBDIRS_EMBED_LDFLAGS)
- @$(MAKE) --no-print-directory $(MOD_SUBDIRS_EMBED_LIBS)
-
-$(SUBDIRS): include/asterisk/version.h include/asterisk/buildopts.h defaults.h makeopts.embed_rules
-
-# ensure that all module subdirectories are processed before 'main' during
-# a parallel build, since if there are modules selected to be embedded the
-# directories containing them must be completed before the main Asterisk
-# binary can be built
-main: $(filter-out main,$(MOD_SUBDIRS))
-
-$(MOD_SUBDIRS):
- @ASTCFLAGS="$(MOD_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" AST_LIBS="$(AST_LIBS)" $(MAKE) --no-print-directory --no-builtin-rules -C $@ SUBDIR=$@ all
-
-$(OTHER_SUBDIRS):
- @ASTCFLAGS="$(OTHER_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" AUDIO_LIBS="$(AUDIO_LIBS)" $(MAKE) --no-print-directory --no-builtin-rules -C $@ SUBDIR=$@ all
-
-defaults.h: makeopts
- @build_tools/make_defaults_h > $@.tmp
- @if cmp -s $@.tmp $@ ; then : ; else \
- mv $@.tmp $@ ; \
- fi
- @rm -f $@.tmp
-
-include/asterisk/version.h:
- @build_tools/make_version_h > $@.tmp
- @if cmp -s $@.tmp $@ ; then : ; else \
- mv $@.tmp $@ ; \
- fi
- @rm -f $@.tmp
-
-include/asterisk/buildopts.h: menuselect.makeopts
- @build_tools/make_buildopts_h > $@.tmp
- @if cmp -s $@.tmp $@ ; then : ; else \
- mv $@.tmp $@ ; \
- fi
- @rm -f $@.tmp
-
-$(SUBDIRS_CLEAN):
- @$(MAKE) --no-print-directory -C $(@:-clean=) clean
-
-$(SUBDIRS_DIST_CLEAN):
- @$(MAKE) --no-print-directory -C $(@:-dist-clean=) dist-clean
-
-clean: $(SUBDIRS_CLEAN)
- rm -f defaults.h
- rm -f include/asterisk/build.h
- rm -f include/asterisk/version.h
- @$(MAKE) -C menuselect clean
- cp -f .cleancount .lastclean
-
-dist-clean: distclean
-
-distclean: $(SUBDIRS_DIST_CLEAN) clean
- @$(MAKE) -C menuselect dist-clean
- @$(MAKE) -C sounds dist-clean
- rm -f menuselect.makeopts makeopts menuselect-tree menuselect.makedeps
- rm -f makeopts.embed_rules
- rm -f config.log config.status
- rm -rf autom4te.cache
- rm -f include/asterisk/autoconfig.h
- rm -f include/asterisk/buildopts.h
- rm -rf doc/api
- rm -f build_tools/menuselect-deps
-
-datafiles: _all
- if [ x`$(ID) -un` = xroot ]; then CFLAGS="$(ASTCFLAGS)" sh build_tools/mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig; fi
-# Should static HTTP be installed during make samples or even with its own target ala
-# webvoicemail? There are portions here that *could* be customized but might also be
-# improved a lot. I'll put it here for now.
- mkdir -p $(DESTDIR)$(ASTDATADIR)/static-http
- for x in static-http/*; do \
- $(INSTALL) -m 644 $$x $(DESTDIR)$(ASTDATADIR)/static-http ; \
- done
- mkdir -p $(DESTDIR)$(ASTDATADIR)/images
- for x in images/*.jpg; do \
- $(INSTALL) -m 644 $$x $(DESTDIR)$(ASTDATADIR)/images ; \
- done
- mkdir -p $(DESTDIR)$(AGI_DIR)
- $(MAKE) -C sounds install
-
-update:
- @if [ -d .svn ]; then \
- echo "Updating from Subversion..." ; \
- svn update | tee update.out; \
- rm -f .version; \
- if [ `grep -c ^C update.out` -gt 0 ]; then \
- echo ; echo "The following files have conflicts:" ; \
- grep ^C update.out | cut -b4- ; \
- fi ; \
- rm -f update.out; \
- else \
- echo "Not under version control"; \
- fi
-
-NEWHEADERS=$(notdir $(wildcard include/asterisk/*.h))
-OLDHEADERS=$(filter-out $(NEWHEADERS),$(notdir $(wildcard $(DESTDIR)$(ASTHEADERDIR)/*.h)))
-
-installdirs:
- mkdir -p $(DESTDIR)$(MODULES_DIR)
- mkdir -p $(DESTDIR)$(ASTSBINDIR)
- mkdir -p $(DESTDIR)$(ASTETCDIR)
- mkdir -p $(DESTDIR)$(ASTBINDIR)
- mkdir -p $(DESTDIR)$(ASTVARRUNDIR)
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/dictate
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/system
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/tmp
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/meetme
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/monitor
-
-bininstall: _all installdirs $(SUBDIRS_INSTALL)
- $(INSTALL) -m 755 main/asterisk $(DESTDIR)$(ASTSBINDIR)/
- $(LN) -sf asterisk $(DESTDIR)$(ASTSBINDIR)/rasterisk
- $(INSTALL) -m 755 contrib/scripts/astgenkey $(DESTDIR)$(ASTSBINDIR)/
- $(INSTALL) -m 755 contrib/scripts/autosupport $(DESTDIR)$(ASTSBINDIR)/
- if [ ! -f $(DESTDIR)$(ASTSBINDIR)/safe_asterisk ]; then \
- cat contrib/scripts/safe_asterisk | sed 's|__ASTERISK_SBIN_DIR__|$(ASTSBINDIR)|;s|__ASTERISK_VARRUN_DIR__|$(ASTVARRUNDIR)|;' > $(DESTDIR)$(ASTSBINDIR)/safe_asterisk ;\
- chmod 755 $(DESTDIR)$(ASTSBINDIR)/safe_asterisk;\
- fi
- $(INSTALL) -d $(DESTDIR)$(ASTHEADERDIR)
- $(INSTALL) -m 644 include/asterisk.h $(DESTDIR)$(includedir)
- $(INSTALL) -m 644 include/asterisk/*.h $(DESTDIR)$(ASTHEADERDIR)
- if [ -n "$(OLDHEADERS)" ]; then \
- rm -f $(addprefix $(DESTDIR)$(ASTHEADERDIR)/,$(OLDHEADERS)) ;\
- fi
- mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-csv
- mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-custom
- mkdir -p $(DESTDIR)$(ASTDATADIR)/keys
- mkdir -p $(DESTDIR)$(ASTDATADIR)/firmware
- mkdir -p $(DESTDIR)$(ASTDATADIR)/firmware/iax
- mkdir -p $(DESTDIR)$(ASTMANDIR)/man8
- $(INSTALL) -m 644 keys/iaxtel.pub $(DESTDIR)$(ASTDATADIR)/keys
- $(INSTALL) -m 644 keys/freeworlddialup.pub $(DESTDIR)$(ASTDATADIR)/keys
- $(INSTALL) -m 644 doc/asterisk.8 $(DESTDIR)$(ASTMANDIR)/man8
- $(INSTALL) -m 644 contrib/scripts/astgenkey.8 $(DESTDIR)$(ASTMANDIR)/man8
- $(INSTALL) -m 644 contrib/scripts/autosupport.8 $(DESTDIR)$(ASTMANDIR)/man8
- $(INSTALL) -m 644 contrib/scripts/safe_asterisk.8 $(DESTDIR)$(ASTMANDIR)/man8
- if [ -f contrib/firmware/iax/iaxy.bin ] ; then \
- $(INSTALL) -m 644 contrib/firmware/iax/iaxy.bin $(DESTDIR)$(ASTDATADIR)/firmware/iax/iaxy.bin; \
- fi
-
-$(SUBDIRS_INSTALL):
- @DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" $(MAKE) -C $(@:-install=) install
-
-NEWMODS=$(notdir $(wildcard */*.so))
-OLDMODS=$(filter-out $(NEWMODS),$(notdir $(wildcard $(DESTDIR)$(MODULES_DIR)/*.so)))
-
-oldmodcheck:
- @if [ -n "$(OLDMODS)" ]; then \
- echo " WARNING WARNING WARNING" ;\
- echo "" ;\
- echo " Your Asterisk modules directory, located at" ;\
- echo " $(DESTDIR)$(MODULES_DIR)" ;\
- echo " contains modules that were not installed by this " ;\
- echo " version of Asterisk. Please ensure that these" ;\
- echo " modules are compatible with this version before" ;\
- echo " attempting to run Asterisk." ;\
- echo "" ;\
- for f in $(OLDMODS); do \
- echo " $$f" ;\
- done ;\
- echo "" ;\
- echo " WARNING WARNING WARNING" ;\
- fi
-
-badshell:
-ifneq ($(findstring ~,$(DESTDIR)),)
- @echo "Your shell doesn't do ~ expansion when expected (specifically, when doing \"make install DESTDIR=~/path\")."
- @echo "Try replacing ~ with \$$HOME, as in \"make install DESTDIR=\$$HOME/path\"."
- @exit 1
-endif
-
-install: badshell datafiles bininstall
- @if [ -x /usr/sbin/asterisk-post-install ]; then \
- /usr/sbin/asterisk-post-install $(DESTDIR) . ; \
- fi
- @echo " +---- Asterisk Installation Complete -------+"
- @echo " + +"
- @echo " + YOU MUST READ THE SECURITY DOCUMENT +"
- @echo " + +"
- @echo " + Asterisk has successfully been installed. +"
- @echo " + If you would like to install the sample +"
- @echo " + configuration files (overwriting any +"
- @echo " + existing config files), run: +"
- @echo " + +"
-ifeq ($(MAKE), gmake)
- @echo " + $(MAKE) samples +"
-else
- @echo " + $(MAKE) samples +"
-endif
- @echo " + +"
- @echo " +----------------- or ---------------------+"
- @echo " + +"
- @echo " + You can go ahead and install the asterisk +"
- @echo " + program documentation now or later run: +"
- @echo " + +"
-ifeq ($(MAKE), gmake)
- @echo " + $(MAKE) progdocs +"
-else
- @echo " + $(MAKE) progdocs +"
-endif
- @echo " + +"
- @echo " + **Note** This requires that you have +"
- @echo " + doxygen installed on your local system +"
- @echo " +-------------------------------------------+"
- @$(MAKE) -s oldmodcheck
-
-upgrade: bininstall
-
-adsi:
- mkdir -p $(DESTDIR)$(ASTETCDIR)
- for x in configs/*.adsi; do \
- if [ ! -f $(DESTDIR)$(ASTETCDIR)/$$x ]; then \
- $(INSTALL) -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x` ; \
- fi ; \
- done
-
-samples: adsi
- mkdir -p $(DESTDIR)$(ASTETCDIR)
- for x in configs/*.sample; do \
- if [ -f $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` ]; then \
- if [ "$(OVERWRITE)" = "y" ]; then \
- if cmp -s $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` $$x ; then \
- echo "Config file $$x is unchanged"; \
- continue; \
- fi ; \
- mv -f $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample`.old ; \
- else \
- echo "Skipping config file $$x"; \
- continue; \
- fi ;\
- fi ; \
- $(INSTALL) -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` ;\
- done
- if [ "$(OVERWRITE)" = "y" ] || [ ! -f $(DESTDIR)$(ASTCONFPATH) ]; then \
- ( \
- echo "[directories]" ; \
- echo "astetcdir => $(ASTETCDIR)" ; \
- echo "astmoddir => $(MODULES_DIR)" ; \
- echo "astvarlibdir => $(ASTVARLIBDIR)" ; \
- echo "astdatadir => $(ASTDATADIR)" ; \
- echo "astagidir => $(AGI_DIR)" ; \
- echo "astspooldir => $(ASTSPOOLDIR)" ; \
- echo "astrundir => $(ASTVARRUNDIR)" ; \
- echo "astlogdir => $(ASTLOGDIR)" ; \
- echo "" ; \
- echo ";[options]" ; \
- echo ";verbose = 3" ; \
- echo ";debug = 3" ; \
- echo ";alwaysfork = yes ; same as -F at startup" ; \
- echo ";nofork = yes ; same as -f at startup" ; \
- echo ";quiet = yes ; same as -q at startup" ; \
- echo ";timestamp = yes ; same as -T at startup" ; \
- echo ";execincludes = yes ; support #exec in config files" ; \
- echo ";console = yes ; Run as console (same as -c at startup)" ; \
- echo ";highpriority = yes ; Run realtime priority (same as -p at startup)" ; \
- echo ";initcrypto = yes ; Initialize crypto keys (same as -i at startup)" ; \
- echo ";nocolor = yes ; Disable console colors" ; \
- echo ";dontwarn = yes ; Disable some warnings" ; \
- echo ";dumpcore = yes ; Dump core on crash (same as -g at startup)" ; \
- echo ";languageprefix = yes ; Use the new sound prefix path syntax" ; \
- echo ";internal_timing = yes" ; \
- echo ";systemname = my_system_name ; prefix uniqueid with a system name for global uniqueness issues" ; \
- echo ";maxcalls = 10 ; Maximum amount of calls allowed" ; \
- echo ";maxload = 0.9 ; Asterisk stops accepting new calls if the load average exceed this limit" ; \
- echo ";cache_record_files = yes ; Cache recorded sound files to another directory during recording" ; \
- echo ";record_cache_dir = /tmp ; Specify cache directory (used in cnjunction with cache_record_files)" ; \
- echo ";transmit_silence_during_record = yes ; Transmit SLINEAR silence while a channel is being recorded" ; \
- echo ";transmit_silence = yes ; Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated" ; \
- echo ";transcode_via_sln = yes ; Build transcode paths via SLINEAR, instead of directly" ; \
- echo ";runuser = asterisk ; The user to run as" ; \
- echo ";rungroup = asterisk ; The group to run as" ; \
- echo "" ; \
- echo "; Changing the following lines may compromise your security." ; \
- echo ";[files]" ; \
- echo ";astctlpermissions = 0660" ; \
- echo ";astctlowner = root" ; \
- echo ";astctlgroup = apache" ; \
- echo ";astctl = asterisk.ctl" ; \
- ) > $(DESTDIR)$(ASTCONFPATH) ; \
- else \
- echo "Skipping asterisk.conf creation"; \
- fi
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/INBOX
- build_tools/make_sample_voicemail $(DESTDIR)/$(ASTDATADIR) $(DESTDIR)/$(ASTSPOOLDIR)
-
-webvmail:
- @[ -d $(DESTDIR)$(HTTP_DOCSDIR)/ ] || ( printf "http docs directory not found.\nUpdate assignment of variable HTTP_DOCSDIR in Makefile!\n" && exit 1 )
- @[ -d $(DESTDIR)$(HTTP_CGIDIR) ] || ( printf "cgi-bin directory not found.\nUpdate assignment of variable HTTP_CGIDIR in Makefile!\n" && exit 1 )
- $(INSTALL) -m 4755 -o root -g root contrib/scripts/vmail.cgi $(DESTDIR)$(HTTP_CGIDIR)/vmail.cgi
- mkdir -p $(DESTDIR)$(HTTP_DOCSDIR)/_asterisk
- for x in images/*.gif; do \
- $(INSTALL) -m 644 $$x $(DESTDIR)$(HTTP_DOCSDIR)/_asterisk/; \
- done
- @echo " +--------- Asterisk Web Voicemail ----------+"
- @echo " + +"
- @echo " + Asterisk Web Voicemail is installed in +"
- @echo " + your cgi-bin directory: +"
- @echo " + $(DESTDIR)$(HTTP_CGIDIR)"
- @echo " + IT USES A SETUID ROOT PERL SCRIPT, SO +"
- @echo " + IF YOU DON'T LIKE THAT, UNINSTALL IT! +"
- @echo " + +"
- @echo " + Other static items have been stored in: +"
- @echo " + $(DESTDIR)$(HTTP_DOCSDIR)"
- @echo " + +"
- @echo " + If these paths do not match your httpd +"
- @echo " + installation, correct the definitions +"
- @echo " + in your Makefile of HTTP_CGIDIR and +"
- @echo " + HTTP_DOCSDIR +"
- @echo " + +"
- @echo " +-------------------------------------------+"
-
-spec:
- sed "s/^Version:.*/Version: $(RPMVERSION)/g" redhat/asterisk.spec > asterisk.spec ; \
-
-rpm: __rpm
-
-__rpm: include/asterisk/version.h include/asterisk/buildopts.h spec
- rm -rf /tmp/asterisk ; \
- mkdir -p /tmp/asterisk/redhat/RPMS/i386 ; \
- $(MAKE) DESTDIR=/tmp/asterisk install ; \
- $(MAKE) DESTDIR=/tmp/asterisk samples ; \
- mkdir -p /tmp/asterisk/etc/rc.d/init.d ; \
- cp -f contrib/init.d/rc.redhat.asterisk /tmp/asterisk/etc/rc.d/init.d/asterisk ; \
- rpmbuild --rcfile /usr/lib/rpm/rpmrc:redhat/rpmrc -bb asterisk.spec
-
-progdocs:
- (cat contrib/asterisk-ng-doxygen; echo "HAVE_DOT=$(HAVEDOT)"; \
- echo "PROJECT_NUMBER=$(ASTERISKVERSION)") | doxygen -
-
-config:
- @if [ "${OSARCH}" = "linux-gnu" ]; then \
- if [ -f /etc/redhat-release -o -f /etc/fedora-release ]; then \
- $(INSTALL) -m 755 contrib/init.d/rc.redhat.asterisk $(DESTDIR)/etc/rc.d/init.d/asterisk; \
- if [ -z "$(DESTDIR)" ]; then /sbin/chkconfig --add asterisk; fi; \
- elif [ -f /etc/debian_version ]; then \
- $(INSTALL) -m 755 contrib/init.d/rc.debian.asterisk $(DESTDIR)/etc/init.d/asterisk; \
- if [ -z "$(DESTDIR)" ]; then /usr/sbin/update-rc.d asterisk start 50 2 3 4 5 . stop 91 2 3 4 5 .; fi; \
- elif [ -f /etc/gentoo-release ]; then \
- $(INSTALL) -m 755 contrib/init.d/rc.gentoo.asterisk $(DESTDIR)/etc/init.d/asterisk; \
- if [ -z "$(DESTDIR)" ]; then /sbin/rc-update add asterisk default; fi; \
- elif [ -f /etc/mandrake-release -o -f /etc/mandriva-release ]; then \
- $(INSTALL) -m 755 contrib/init.d/rc.mandrake.asterisk $(DESTDIR)/etc/rc.d/init.d/asterisk; \
- if [ -z "$(DESTDIR)" ]; then /sbin/chkconfig --add asterisk; fi; \
- elif [ -f /etc/SuSE-release -o -f /etc/novell-release ]; then \
- $(INSTALL) -m 755 contrib/init.d/rc.suse.asterisk $(DESTDIR)/etc/init.d/asterisk; \
- if [ -z "$(DESTDIR)" ]; then /sbin/chkconfig --add asterisk; fi; \
- elif [ -f /etc/slackware-version ]; then \
- echo "Slackware is not currently supported, although an init script does exist for it." \
- else \
- echo "We could not install init scripts for your distribution."; \
- fi \
- else \
- echo "We could not install init scripts for your operating system."; \
- fi
-
-sounds:
- $(MAKE) -C sounds all
-
-# If the cleancount has been changed, force a make clean.
-# .cleancount is the global clean count, and .lastclean is the
-# last clean count we had
-
-cleantest:
- @cmp -s .cleancount .lastclean || $(MAKE) clean
-
-$(SUBDIRS_UNINSTALL):
- @$(MAKE) --no-print-directory -C $(@:-uninstall=) uninstall
-
-_uninstall: $(SUBDIRS_UNINSTALL)
- rm -f $(DESTDIR)$(MODULES_DIR)/*
- rm -f $(DESTDIR)$(ASTSBINDIR)/*asterisk*
- rm -f $(DESTDIR)$(ASTSBINDIR)/astgenkey
- rm -f $(DESTDIR)$(ASTSBINDIR)/autosupport
- rm -rf $(DESTDIR)$(ASTHEADERDIR)
- rm -rf $(DESTDIR)$(ASTDATADIR)/firmware
- rm -f $(DESTDIR)$(ASTMANDIR)/man8/asterisk.8
- rm -f $(DESTDIR)$(ASTMANDIR)/man8/astgenkey.8
- rm -f $(DESTDIR)$(ASTMANDIR)/man8/autosupport.8
- rm -f $(DESTDIR)$(ASTMANDIR)/man8/safe_asterisk.8
- $(MAKE) -C sounds uninstall
-
-uninstall: _uninstall
- @echo " +--------- Asterisk Uninstall Complete -----+"
- @echo " + Asterisk binaries, sounds, man pages, +"
- @echo " + headers, modules, and firmware builds, +"
- @echo " + have all been uninstalled. +"
- @echo " + +"
- @echo " + To remove ALL traces of Asterisk, +"
- @echo " + including configuration, spool +"
- @echo " + directories, and logs, run the following +"
- @echo " + command: +"
- @echo " + +"
-ifeq ($(MAKE), gmake)
- @echo " + $(MAKE) uninstall-all +"
-else
- @echo " + $(MAKE) uninstall-all +"
-endif
- @echo " +-------------------------------------------+"
-
-uninstall-all: _uninstall
- rm -rf $(DESTDIR)$(ASTLIBDIR)
- rm -rf $(DESTDIR)$(ASTVARLIBDIR)
- rm -rf $(DESTDIR)$(ASTDATADIR)
- rm -rf $(DESTDIR)$(ASTSPOOLDIR)
- rm -rf $(DESTDIR)$(ASTETCDIR)
- rm -rf $(DESTDIR)$(ASTLOGDIR)
-
-menuconfig: menuselect
-
-gmenuconfig: gmenuselect
-
-menuselect: menuselect/menuselect menuselect-tree
- -@menuselect/menuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && (echo "menuselect changes saved!"; rm -f channels/h323/Makefile.ast main/asterisk) || echo "menuselect changes NOT saved!"
-
-gmenuselect: menuselect/gmenuselect menuselect-tree
- -@menuselect/gmenuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && (echo "menuselect changes saved!"; rm -f channels/h323/Makefile.ast main/asterisk) || echo "menuselect changes NOT saved!"
-
-menuselect/menuselect: makeopts menuselect/menuselect.c menuselect/menuselect_curses.c menuselect/menuselect_stub.c menuselect/menuselect.h menuselect/linkedlists.h makeopts
- @CC="$(HOST_CC)" LD="" AR="" RANLIB="" CFLAGS="" $(MAKE) -C menuselect CONFIGURE_SILENT="--silent"
-
-menuselect/gmenuselect: makeopts menuselect/menuselect.c menuselect/menuselect_gtk.c menuselect/menuselect_stub.c menuselect/menuselect.h menuselect/linkedlists.h makeopts
- @CC="$(HOST_CC)" CXX="$(CXX)" LD="" AR="" RANLIB="" CFLAGS="" $(MAKE) -C menuselect _gmenuselect CONFIGURE_SILENT="--silent"
-
-menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc)) build_tools/cflags.xml build_tools/cflags-devmode.xml sounds/sounds.xml build_tools/embed_modules.xml configure
- @echo "Generating input for menuselect ..."
- @echo "<?xml version=\"1.0\"?>" > $@
- @echo >> $@
- @echo "<menu name=\"Asterisk Module and Build Option Selection\">" >> $@
- @for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} moduleinfo >> $@; done
- @for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} makeopts >> $@; done
- @cat build_tools/cflags.xml >> $@
- @if [ "${AST_DEVMODE}" = "yes" ]; then \
- cat build_tools/cflags-devmode.xml >> $@; \
- fi
- @cat build_tools/embed_modules.xml >> $@
- @cat sounds/sounds.xml >> $@
- @echo "</menu>" >> $@
-
-.PHONY: menuselect main sounds clean dist-clean distclean all prereqs cleantest uninstall _uninstall uninstall-all dont-optimize $(SUBDIRS_INSTALL) $(SUBDIRS_DIST_CLEAN) $(SUBDIRS_CLEAN) $(SUBDIRS_UNINSTALL) $(SUBDIRS) $(MOD_SUBDIRS_EMBED_LDSCRIPT) $(MOD_SUBDIRS_EMBED_LDFLAGS) $(MOD_SUBDIRS_EMBED_LIBS) badshell menuselect.makeopts include/asterisk/version.h installdirs
diff --git a/1.4/Makefile.moddir_rules b/1.4/Makefile.moddir_rules
deleted file mode 100644
index f73bc83e9..000000000
--- a/1.4/Makefile.moddir_rules
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile rules for subdirectories containing modules
-#
-# Copyright (C) 2006, Digium, Inc.
-#
-# Kevin P. Fleming <kpfleming@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
-ifneq ($(findstring MALLOC_DEBUG,$(MENUSELECT_CFLAGS)),)
- ifeq ($(findstring astmm.h,$(ASTCFLAGS)),)
- ASTCFLAGS+=-include $(ASTTOPDIR)/include/asterisk/astmm.h
- endif
-endif
-
-ifeq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)
- ASTCFLAGS+=${GC_CFLAGS}
-endif
-
-ifneq ($(findstring STATIC_BUILD,$(MENUSELECT_CFLAGS)),)
- STATIC_BUILD=-static
-endif
-
-include $(ASTTOPDIR)/Makefile.rules
-
-comma:=,
-
-$(addsuffix .o,$(C_MODS)): ASTCFLAGS+=-DAST_MODULE=\"$*\" $(MENUSELECT_OPTS_$*:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_INCLUDE))
-$(addsuffix .oo,$(CC_MODS)): ASTCFLAGS+=-DAST_MODULE=\"$*\" $(MENUSELECT_OPTS_$*:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_INCLUDE))
-
-$(LOADABLE_MODS:%=%.so): ASTCFLAGS+=-fPIC
-$(LOADABLE_MODS:%=%.so): LIBS+=$(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_LIB))
-$(LOADABLE_MODS:%=%.so): ASTLDFLAGS+=$(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_LDFLAGS))
-
-$(addsuffix .so,$(filter $(LOADABLE_MODS),$(C_MODS))): %.so: %.o
-$(addsuffix .so,$(filter $(LOADABLE_MODS),$(CC_MODS))): %.so: %.oo
-
-modules.link: $(addsuffix .o,$(filter $(EMBEDDED_MODS),$(C_MODS)))
-modules.link: $(addsuffix .oo,$(filter $(EMBEDDED_MODS),$(CC_MODS)))
-
-.PHONY: clean uninstall _all moduleinfo makeopts
-
-ifneq ($(LOADABLE_MODS),)
-_all: $(LOADABLE_MODS:%=%.so)
-endif
-
-ifneq ($(EMBEDDED_MODS),)
-_all: modules.link
-__embed_ldscript:
- @echo "../$(SUBDIR)/modules.link"
-__embed_ldflags:
- @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(C_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LDFLAGS))"
- @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(CC_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LDFLAGS))"
-__embed_libs:
- @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(C_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LIB))"
- @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(CC_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LIB))"
-else
-__embed_ldscript:
-__embed_ldflags:
-__embed_libs:
-endif
-
-modules.link:
- @rm -f $@
- @for file in $(patsubst %,$(SUBDIR)/%,$(filter %.o,$^)); do echo "INPUT (../$${file})" >> $@; done
- @for file in $(patsubst %,$(SUBDIR)/%,$(filter-out %.o,$^)); do echo "INPUT (../$${file})" >> $@; done
-
-clean::
- rm -f *.so *.o *.oo *.s *.i
- rm -f .*.o.d .*.oo.d
- rm -f modules.link
-
-install:: all
- for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
-
-uninstall::
-
-dist-clean::
- rm -f .*.moduleinfo .moduleinfo
- rm -f .*.makeopts .makeopts
-
-.%.moduleinfo: %.c
- @echo "<member name=\"$*\" displayname=\"$(shell $(GREP) -e AST_MODULE_INFO $< | head -n 1 | cut -d '"' -f 2)\" remove_on_change=\"$(SUBDIR)/$*.o $(SUBDIR)/$*.so\">" > $@
- $(AWK) -f $(ASTTOPDIR)/build_tools/get_moduleinfo $< >> $@
- echo "</member>" >> $@
-
-.%.moduleinfo: %.cc
- @echo "<member name=\"$*\" displayname=\"$(shell $(GREP) -e AST_MODULE_INFO $< | head -n 1 | cut -d '"' -f 2)\" remove_on_change=\"$(SUBDIR)/$*.oo $(SUBDIR)/$*.so\">" > $@
- $(AWK) -f $(ASTTOPDIR)/build_tools/get_moduleinfo $< >> $@
- echo "</member>" >> $@
-
-.moduleinfo:: $(addsuffix .moduleinfo,$(addprefix .,$(ALL_C_MODS) $(ALL_CC_MODS)))
- @echo "<category name=\"MENUSELECT_$(MENUSELECT_CATEGORY)\" displayname=\"$(MENUSELECT_DESCRIPTION)\" remove_on_change=\"$(SUBDIR)/modules.link\">" > $@
- @cat $^ >> $@
- @echo "</category>" >> $@
-
-moduleinfo: .moduleinfo
- @cat $<
-
-.%.makeopts: %.c
- @$(AWK) -f $(ASTTOPDIR)/build_tools/get_makeopts $< > $@
-
-.%.makeopts: %.cc
- @$(AWK) -f $(ASTTOPDIR)/build_tools/get_makeopts $< > $@
-
-.makeopts:: $(addsuffix .makeopts,$(addprefix .,$(ALL_C_MODS) $(ALL_CC_MODS)))
- @cat $^ > $@
-
-makeopts: .makeopts
- @cat $<
-
-ifneq ($(wildcard .*.d),)
- include .*.d
-endif
diff --git a/1.4/Makefile.rules b/1.4/Makefile.rules
deleted file mode 100644
index d5025bbc9..000000000
--- a/1.4/Makefile.rules
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile rules
-#
-# Copyright (C) 2006, Digium, Inc.
-#
-# Kevin P. Fleming <kpfleming@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
-# Each command is preceded by a short comment on what to do.
-# Prefixing one or the other with @\# or @ or nothing makes the desired
-# behaviour. ECHO_PREFIX prefixes the comment, CMD_PREFIX prefixes the command.
-
--include $(ASTTOPDIR)/makeopts
-
-.PHONY: dist-clean
-
-ifeq ($(NOISY_BUILD),)
- ECHO_PREFIX=@
- CMD_PREFIX=@
-else
- ECHO_PREFIX=@\#
- CMD_PREFIX=
-endif
-
-ifeq ($(findstring DONT_OPTIMIZE,$(MENUSELECT_CFLAGS)),)
-# More GSM codec optimization
-# Uncomment to enable MMXTM optimizations for x86 architecture CPU's
-# which support MMX instructions. This should be newer pentiums,
-# ppro's, etc, as well as the AMD K6 and K7.
-#K6OPT=-DK6OPT
-
-OPTIMIZE?=-O6
-ASTCFLAGS+=$(OPTIMIZE)
-endif
-
-%.o: %.c
- $(ECHO_PREFIX) echo " [CC] $< -> $@"
- $(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) -MD -MT $@ -MF .$(subst /,_,$@).d -MP
-
-%.o: %.s
- $(ECHO_PREFIX) echo " [AS] $< -> $@"
- $(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) -MD -MT $@ -MF .$(subst /,_,$@).d -MP
-
-%.oo: %.cc
- $(ECHO_PREFIX) echo " [CXX] $< -> $@"
- $(CMD_PREFIX) $(CXX) -o $@ -c $< $(PTHREAD_CFLAGS) $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(AST_DECLARATION_AFTER_STATEMENT),$(ASTCFLAGS)) -MD -MT $@ -MF .$(subst /,_,$@).d -MP
-
-%.c: %.y
- $(ECHO_PREFIX) echo " [BISON] $< -> $@"
- $(CMD_PREFIX) bison -o $@ -d --name-prefix=ast_yy $<
-
-%.c: %.fl
- $(ECHO_PREFIX) echo " [FLEX] $< -> $@"
- $(CMD_PREFIX) flex -o $@ --full $<
-
-%.so: %.o
- $(ECHO_PREFIX) echo " [LD] $^ -> $@"
- $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) $^ $(PTHREAD_LIBS) $(LIBS)
-
-%.so: %.oo
- $(ECHO_PREFIX) echo " [LDXX] $^ -> $@"
- $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) $^ $(PTHREAD_LIBS) $(LIBS)
-
-%: %.o
- $(ECHO_PREFIX) echo " [LD] $^ -> $@"
- $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $^ $(PTHREAD_LIBS) $(LIBS)
-
-dist-clean::
diff --git a/1.4/README b/1.4/README
deleted file mode 100644
index 176bfca44..000000000
--- a/1.4/README
+++ /dev/null
@@ -1,262 +0,0 @@
-The Asterisk(R) Open Source PBX
-by Mark Spencer <markster@digium.com>
-and the Asterisk.org developer community
-
-Copyright (C) 2001-2006 Digium, Inc.
-and other copyright holders.
-================================================================
-
-* SECURITY
- It is imperative that you read and fully understand the contents of
-the security information file (doc/security.txt) before you attempt
-to configure and run an Asterisk server.
-
-* WHAT IS ASTERISK ?
- Asterisk is an Open Source PBX and telephony toolkit. It is, in a
-sense, middleware between Internet and telephony channels on the bottom,
-and Internet and telephony applications at the top. For more information
-on the project itself, please visit the Asterisk home page at:
-
- http://www.asterisk.org
-
-In addition you'll find lots of information compiled by the Asterisk
-community on this Wiki:
-
- http://www.voip-info.org/wiki-Asterisk
-
-There is a book on Asterisk published by O'Reilly under the
-Creative Commons License. It is available in book stores as well
-as in a downloadable version on the http://www.asteriskdocs.org
-web site.
-
-* SUPPORTED OPERATING SYSTEMS
-
-== Linux ==
- The Asterisk Open Source PBX is developed and tested primarily on the
-GNU/Linux operating system, and is supported on every major GNU/Linux
-distribution.
-
-== Others ==
- Asterisk has also been 'ported' and reportedly runs properly on other
-operating systems as well, including Sun Solaris, Apple's Mac OS X, and
-the BSD variants.
-
-* GETTING STARTED
-
- First, be sure you've got supported hardware (but note that you don't need
-ANY special hardware, not even a soundcard) to install and run Asterisk.
-
- Supported telephony hardware includes:
-
- * All Wildcard (tm) products from Digium (www.digium.com)
- * QuickNet Internet PhoneJack and LineJack (http://www.quicknet.net)
- * any full duplex sound card supported by ALSA or OSS
- * any ISDN card supported by mISDN on Linux (BRI)
- * The Xorcom AstriBank channel bank
- * VoiceTronix OpenLine products
-
-The are several drivers for ISDN BRI cards available from third party sources.
-Check the voip-info.org wiki for more information on chan_capi and
-zaphfc.
-
-* UPGRADING FROM AN EARLIER VERSION
-
- If you are updating from a previous version of Asterisk, make sure you
-read the UPGRADE.txt file in the source directory. There are some files
-and configuration options that you will have to change, even though we
-made every effort possible to maintain backwards compatibility.
-
- In order to discover new features to use, please check the configuration
-examples in the /configs directory of the source code distribution.
-To discover the major new features of Asterisk 1.2, please visit
-http://edvina.net/asterisk1-2/
-
-* NEW INSTALLATIONS
-
- Ensure that your system contains a compatible compiler and development
-libraries. Asterisk requires either the GNU Compiler Collection (GCC) version
-3.0 or higher, or a compiler that supports the C99 specification and some of
-the gcc language extensions. In addition, your system needs to have the C
-library headers available, and the headers and libraries for OpenSSL,
-ncurses and zlib.
-On many distributions, these files are installed by packages with names like
-'glibc-devel', 'ncurses-devel', 'openssl-devel' and 'zlib-devel' or similar.
-
- So let's proceed:
-
-1) Read this README file.
-
- There are more documents than this one in the doc/ directory.
-You may also want to check the configuration files that contain
-examples and reference guides. They are all in the configs/
-directory.
-
-2) Run "./configure"
-
- Execute the configure script to guess values for system-dependent
-variables used during compilation.
-
-3) Run "make menuselect" [optional]
-
- This is needed if you want to select the modules that will be
-compiled and to check modules dependencies.
-
-4) Run "make"
-
- Assuming the build completes successfully:
-
-5) Run "make install"
-
- Each time you update or checkout from the repository, you are strongly
-encouraged to ensure all previous object files are removed to avoid internal
-inconsistency in Asterisk. Normally, this is automatically done with
-the presence of the file .cleancount, which increments each time a 'make clean'
-is required, and the file .lastclean, which contains the last .cleancount used.
-
- If this is your first time working with Asterisk, you may wish to install
-the sample PBX, with demonstration extensions, etc. If so, run:
-
-6) "make samples"
-
- Doing so will overwrite any existing config files you have.
-
- Finally, you can launch Asterisk in the foreground mode (not a daemon)
-with:
-
-# asterisk -vvvc
-
- You'll see a bunch of verbose messages fly by your screen as Asterisk
-initializes (that's the "very very verbose" mode). When it's ready, if
-you specified the "c" then you'll get a command line console, that looks
-like this:
-
-*CLI>
-
- You can type "help" at any time to get help with the system. For help
-with a specific command, type "help <command>". To start the PBX using
-your sound card, you can type "dial" to dial the PBX. Then you can use
-"answer", "hangup", and "dial" to simulate the actions of a telephone.
-Remember that if you don't have a full duplex sound card (and Asterisk
-will tell you somewhere in its verbose messages if you do/don't) then it
-won't work right (not yet).
-
- "man asterisk" at the Unix/Linux command prompt will give you detailed
-information on how to start and stop Asterisk, as well as all the command
-line options for starting Asterisk.
-
- Feel free to look over the configuration files in /etc/asterisk, where
-you'll find a lot of information about what you can do with Asterisk.
-
-* ABOUT CONFIGURATION FILES
-
- All Asterisk configuration files share a common format. Comments are
-delimited by ';' (since '#' of course, being a DTMF digit, may occur in
-many places). A configuration file is divided into sections whose names
-appear in []'s. Each section typically contains two types of statements,
-those of the form 'variable = value', and those of the form 'object =>
-parameters'. Internally the use of '=' and '=>' is exactly the same, so
-they're used only to help make the configuration file easier to
-understand, and do not affect how it is actually parsed.
-
- Entries of the form 'variable=value' set the value of some parameter in
-asterisk. For example, in zapata.conf, one might specify:
-
- switchtype=national
-
-in order to indicate to Asterisk that the switch they are connecting to is
-of the type "national". In general, the parameter will apply to
-instantiations which occur below its specification. For example, if the
-configuration file read:
-
- switchtype = national
- channel => 1-4
- channel => 10-12
- switchtype = dms100
- channel => 25-47
-
-the "national" switchtype would be applied to channels one through
-four and channels 10 through 12, whereas the "dms100" switchtype would
-apply to channels 25 through 47.
-
- The "object => parameters" instantiates an object with the given
-parameters. For example, the line "channel => 25-47" creates objects for
-the channels 25 through 47 of the card, obtaining the settings
-from the variables specified above.
-
-* SPECIAL NOTE ON TIME
-
- Those using SIP phones should be aware that Asterisk is sensitive to
-large jumps in time. Manually changing the system time using date(1)
-(or other similar commands) may cause SIP registrations and other
-internal processes to fail. If your system cannot keep accurate time
-by itself use NTP (http://www.ntp.org/) to keep the system clock
-synchronized to "real time". NTP is designed to keep the system clock
-synchronized by speeding up or slowing down the system clock until it
-is synchronized to "real time" rather than by jumping the time and
-causing discontinuities. Most Linux distributions include precompiled
-versions of NTP. Beware of some time synchronization methods that get
-the correct real time periodically and then manually set the system
-clock.
-
- Apparent time changes due to daylight savings time are just that,
-apparent. The use of daylight savings time in a Linux system is
-purely a user interface issue and does not affect the operation of the
-Linux kernel or Asterisk. The system clock on Linux kernels operates
-on UTC. UTC does not use daylight savings time.
-
- Also note that this issue is separate from the clocking of TDM
-channels, and is known to at least affect SIP registrations.
-
-* FILE DESCRIPTORS
-
- Depending on the size of your system and your configuration,
-Asterisk can consume a large number of file descriptors. In UNIX,
-file descriptors are used for more than just files on disk. File
-descriptors are also used for handling network communication
-(e.g. SIP, IAX2, or H.323 calls) and hardware access (e.g. analog and
-digital trunk hardware). Asterisk accesses many on-disk files for
-everything from configuration information to voicemail storage.
-
- Most systems limit the number of file descriptors that Asterisk can
-have open at one time. This can limit the number of simultaneous
-calls that your system can handle. For example, if the limit is set
-at 1024 (a common default value) Asterisk can handle approxiately 150
-SIP calls simultaneously. To change the number of file descriptors
-follow the instructions for your system below:
-
-== PAM-based Linux System ==
-
- If your system uses PAM (Pluggable Authentication Modules) edit
-/etc/security/limits.conf. Add these lines to the bottom of the file:
-
-root soft nofile 4096
-root hard nofile 8196
-asterisk soft nofile 4096
-asterisk hard nofile 8196
-
-(adjust the numbers to taste). You may need to reboot the system for
-these changes to take effect.
-
-== Generic UNIX System ==
-
- If there are no instructions specifically adapted to your system
-above you can try adding the command "ulimit -n 8192" to the script
-that starts Asterisk.
-
-* MORE INFORMATION
-
- See the doc directory for more documentation on various features. Again,
-please read all the configuration samples that include documentation on
-the configuration options.
-
- Finally, you may wish to visit the web site and join the mailing list if
-you're interested in getting more information.
-
- http://www.asterisk.org/support
-
- Welcome to the growing worldwide community of Asterisk users!
-
-Mark Spencer
-
-----
-Asterisk is a trademark belonging to Digium, inc
diff --git a/1.4/UPGRADE.txt b/1.4/UPGRADE.txt
deleted file mode 100644
index 53f047eae..000000000
--- a/1.4/UPGRADE.txt
+++ /dev/null
@@ -1,495 +0,0 @@
-Information for Upgrading From Previous Asterisk Releases
-=========================================================
-
-Build Process (configure script):
-
-Asterisk now uses an autoconf-generated configuration script to learn how it
-should build itself for your system. As it is a standard script, running:
-
-$ ./configure --help
-
-will show you all the options available. This script can be used to tell the
-build process what libraries you have on your system (if it cannot find them
-automatically), which libraries you wish to have ignored even though they may
-be present, etc.
-
-You must run the configure script before Asterisk will build, although it will
-attempt to automatically run it for you with no options specified; for most
-users, that will result in a similar build to what they would have had before
-the configure script was added to the build process (except for having to run
-'make' again after the configure script is run). Note that the configure script
-does NOT need to be re-run just to rebuild Asterisk; you only need to re-run it
-when your system configuration changes or you wish to build Asterisk with
-different options.
-
-Build Process (module selection):
-
-The Asterisk source tree now includes a basic module selection and build option
-selection tool called 'menuselect'. Run 'make menuselect' to make your choices.
-In this tool, you can disable building of modules that you don't care about,
-turn on/off global options for the build and see which modules will not
-(and cannot) be built because your system does not have the required external
-dependencies installed.
-
-The resulting file from menuselect is called 'menuselect.makeopts'. Note that
-the resulting menuselect.makeopts file generally contains which modules *not*
-to build. The modules listed in this file indicate which modules have unmet
-dependencies, a present conflict, or have been disabled by the user in the
-menuselect interface. Compiler Flags can also be set in the menuselect
-interface. In this case, the resulting file contains which CFLAGS are in use,
-not which ones are not in use.
-
-If you would like to save your choices and have them applied against all
-builds, the file can be copied to '~/.asterisk.makeopts' or
-'/etc/asterisk.makeopts'.
-
-Build Process (Makefile targets):
-
-The 'valgrind' and 'dont-optimize' targets have been removed; their functionality
-is available by enabling the DONT_OPTIMIZE setting in the 'Compiler Flags' menu
-in the menuselect tool.
-
-It is now possible to run most make targets against a single subdirectory; from
-the top level directory, for example, 'make channels' will run 'make all' in the
-'channels' subdirectory. This also is true for 'clean', 'distclean' and 'depend'.
-
-Sound (prompt) and Music On Hold files:
-
-Beginning with Asterisk 1.4, the sound files and music on hold files supplied for
-use with Asterisk have been replaced with new versions produced from high quality
-master recordings, and are available in three languages (English, French and
-Spanish) and in five formats (WAV (uncompressed), mu-Law, a-Law, GSM and G.729).
-In addition, the music on hold files provided by FreePlay Music are now available
-in the same five formats, but no longer available in MP3 format.
-
-The Asterisk 1.4 tarball packages will only include English prompts in GSM format,
-(as were supplied with previous releases) and the FreePlay MOH files in WAV format.
-All of the other variations can be installed by running 'make menuselect' and
-selecting the packages you wish to install; when you run 'make install', those
-packages will be downloaded and installed along with the standard files included
-in the tarball.
-
-If for some reason you expect to not have Internet access at the time you will be
-running 'make install', you can make your package selections using menuselect and
-then run 'make sounds' to download (only) the sound packages; this will leave the
-sound packages in the 'sounds' subdirectory to be used later during installation.
-
-WARNING: Asterisk 1.4 supports a new layout for sound files in multiple languages;
-instead of the alternate-language files being stored in subdirectories underneath
-the existing files (for French, that would be digits/fr, letters/fr, phonetic/fr,
-etc.) the new layout creates one directory under /var/lib/asterisk/sounds for the
-language itself, then places all the sound files for that language under that
-directory and its subdirectories. This is the layout that will be created if you
-select non-English languages to be installed via menuselect, HOWEVER Asterisk does
-not default to this layout and will not find the files in the places it expects them
-to be. If you wish to use this layout, make sure you put 'languageprefix=yes' in your
-/etc/asterisk/asterisk.conf file, so that Asterisk will know how the files were
-installed.
-
-PBX Core:
-
-* The (very old and undocumented) ability to use BYEXTENSION for dialing
- instead of ${EXTEN} has been removed.
-
-* Builtin (res_features) transfer functionality attempts to use the context
- defined in TRANSFER_CONTEXT variable of the transferer channel first. If
- not set, it uses the transferee variable. If not set in any channel, it will
- attempt to use the last non macro context. If not possible, it will default
- to the current context.
-
-* The autofallthrough setting introduced in Asterisk 1.2 now defaults to 'yes';
- if your dialplan relies on the ability to 'run off the end' of an extension
- and wait for a new extension without using WaitExten() to accomplish that,
- you will need set autofallthrough to 'no' in your extensions.conf file.
-
-Command Line Interface:
-
-* 'show channels concise', designed to be used by applications that will parse
- its output, previously used ':' characters to separate fields. However, some
- of those fields can easily contain that character, making the output not
- parseable. The delimiter has been changed to '!'.
-
-Applications:
-
-* In previous Asterisk releases, many applications would jump to priority n+101
- to indicate some kind of status or error condition. This functionality was
- marked deprecated in Asterisk 1.2. An option to disable it was provided with
- the default value set to 'on'. The default value for the global priority
- jumping option is now 'off'.
-
-* The applications Cut, Sort, DBGet, DBPut, SetCIDNum, SetCIDName, SetRDNIS,
- AbsoluteTimeout, DigitTimeout, ResponseTimeout, SetLanguage, GetGroupCount,
- and GetGroupMatchCount were all deprecated in version 1.2, and therefore have
- been removed in this version. You should use the equivalent dialplan
- function in places where you have previously used one of these applications.
-
-* The application SetGlobalVar has been deprecated. You should replace uses
- of this application with the following combination of Set and GLOBAL():
- Set(GLOBAL(name)=value). You may also access global variables exclusively by
- using the GLOBAL() dialplan function, instead of relying on variable
- interpolation falling back to globals when no channel variable is set.
-
-* The application SetVar has been renamed to Set. The syntax SetVar was marked
- deprecated in version 1.2 and is no longer recognized in this version. The
- use of Set with multiple argument pairs has also been deprecated. Please
- separate each name/value pair into its own dialplan line.
-
-* app_read has been updated to use the newer options codes, using "skip" or
- "noanswer" will not work. Use s or n. Also there is a new feature i, for
- using indication tones, so typing in skip would give you unexpected results.
-
-* OSPAuth is added to authenticate OSP tokens in in_bound call setup messages.
-
-* The CONNECT event in the queue_log from app_queue now has a second field
- in addition to the holdtime field. It contains the unique ID of the
- queue member channel that is taking the call. This is useful when trying
- to link recording filenames back to a particular call from the queue.
-
-* The old/current behavior of app_queue has a serial type behavior
- in that the queue will make all waiting callers wait in the queue
- even if there is more than one available member ready to take
- calls until the head caller is connected with the member they
- were trying to get to. The next waiting caller in line then
- becomes the head caller, and they are then connected with the
- next available member and all available members and waiting callers
- waits while this happens. This cycle continues until there are
- no more available members or waiting callers, whichever comes first.
- The new behavior, enabled by setting autofill=yes in queues.conf
- either at the [general] level to default for all queues or
- to set on a per-queue level, makes sure that when the waiting
- callers are connecting with available members in a parallel fashion
- until there are no more available members or no more waiting callers,
- whichever comes first. This is probably more along the lines of how
- one would expect a queue should work and in most cases, you will want
- to enable this new behavior. If you do not specify or comment out this
- option, it will default to "no" to keep backward compatability with the old
- behavior.
-
-* Queues depend on the channel driver reporting the proper state
- for each member of the queue. To get proper signalling on
- queue members that use the SIP channel driver, you need to
- enable a call limit (could be set to a high value so it
- is not put into action) and also make sure that both inbound
- and outbound calls are accounted for.
-
- Example:
-
- [general]
- limitonpeer = yes
-
- [peername]
- type=friend
- call-limit=10
-
-
-* The app_queue application now has the ability to use MixMonitor to
- record conversations queue members are having with queue callers. Please
- see configs/queues.conf.sample for more information on this option.
-
-* The app_queue application strategy called 'roundrobin' has been deprecated
- for this release. Users are encouraged to use 'rrmemory' instead, since it
- provides more 'true' round-robin call delivery. For the Asterisk 1.6 release,
- 'rrmemory' will be renamed 'roundrobin'.
-
-* The app_queue application option called 'monitor-join' has been deprecated
- for this release. Users are encouraged to use 'monitor-type=mixmonitor' instead,
- since it provides the same functionality but is not dependent on soxmix or some
- other external program in order to mix the audio.
-
-* app_meetme: The 'm' option (monitor) is renamed to 'l' (listen only), and
- the 'm' option now provides the functionality of "initially muted".
- In practice, most existing dialplans using the 'm' flag should not notice
- any difference, unless the keypad menu is enabled, allowing the user
- to unmute themsleves.
-
-* ast_play_and_record would attempt to cancel the recording if a DTMF
- '0' was received. This behavior was not documented in most of the
- applications that used ast_play_and_record and the return codes from
- ast_play_and_record weren't checked for properly.
- ast_play_and_record has been changed so that '0' no longer cancels a
- recording. If you want to allow DTMF digits to cancel an
- in-progress recording use ast_play_and_record_full which allows you
- to specify which DTMF digits can be used to accept a recording and
- which digits can be used to cancel a recording.
-
-* ast_app_messagecount has been renamed to ast_app_inboxcount. There is now a
- new ast_app_messagecount function which takes a single context/mailbox/folder
- mailbox specification and returns the message count for that folder only.
- This addresses the deficiency of not being able to count the number of
- messages in folders other than INBOX and Old.
-
-* The exit behavior of the AGI applications has changed. Previously, when
- a connection to an AGI server failed, the application would cause the channel
- to immediately stop dialplan execution and hangup. Now, the only time that
- the AGI applications will cause the channel to stop dialplan execution is
- when the channel itself requests hangup. The AGI applications now set an
- AGISTATUS variable which will allow you to find out whether running the AGI
- was successful or not.
-
- Previously, there was no way to handle the case where Asterisk was unable to
- locally execute an AGI script for some reason. In this case, dialplan
- execution will continue as it did before, but the AGISTATUS variable will be
- set to "FAILURE".
-
- A locally executed AGI script can now exit with a non-zero exit code and this
- failure will be detected by Asterisk. If an AGI script exits with a non-zero
- exit code, the AGISTATUS variable will be set to "FAILURE" as opposed to
- "SUCCESS".
-
-* app_voicemail: The ODBC_STORAGE capability now requires the extended table format
- previously used only by EXTENDED_ODBC_STORAGE. This means that you will need to update
- your table format using the schema provided in doc/odbcstorage.txt
-
-* app_waitforsilence: Fixes have been made to this application which changes the
- default behavior with how quickly it returns. You can maintain "old-style" behavior
- with the addition/use of a third "timeout" parameter.
- Please consult the application documentation and make changes to your dialplan
- if appropriate.
-
-Manager:
-
-* After executing the 'status' manager action, the "Status" manager events
- included the header "CallerID:" which was actually only the CallerID number,
- and not the full CallerID string. This header has been renamed to
- "CallerIDNum". For compatibility purposes, the CallerID parameter will remain
- until after the release of 1.4, when it will be removed. Please use the time
- during the 1.4 release to make this transition.
-
-* The AgentConnect event now has an additional field called "BridgedChannel"
- which contains the unique ID of the queue member channel that is taking the
- call. This is useful when trying to link recording filenames back to
- a particular call from the queue.
-
-* app_userevent has been modified to always send Event: UserEvent with the
- additional header UserEvent: <userspec>. Also, the Channel and UniqueID
- headers are not automatically sent, unless you specify them as separate
- arguments. Please see the application help for the new syntax.
-
-* app_meetme: Mute and Unmute events are now reported via the Manager API.
- Native Manager API commands MeetMeMute and MeetMeUnmute are provided, which
- are easier to use than "Action Command:". The MeetMeStopTalking event has
- also been deprecated in favor of the already existing MeetmeTalking event
- with a "Status" of "on" or "off" added.
-
-* OriginateFailure and OriginateSuccess events were replaced by event
- OriginateResponse with a header named "Response" to indicate success or
- failure
-
-Variables:
-
-* The builtin variables ${CALLERID}, ${CALLERIDNAME}, ${CALLERIDNUM},
- ${CALLERANI}, ${DNID}, ${RDNIS}, ${DATETIME}, ${TIMESTAMP}, ${ACCOUNTCODE},
- and ${LANGUAGE} have all been deprecated in favor of their related dialplan
- functions. You are encouraged to move towards the associated dialplan
- function, as these variables will be removed in a future release.
-
-* The CDR-CSV variables uniqueid, userfield, and basing time on GMT are now
- adjustable from cdr.conf, instead of recompiling.
-
-* OSP applications exports several new variables, ${OSPINHANDLE},
- ${OSPOUTHANDLE}, ${OSPINTOKEN}, ${OSPOUTTOKEN}, ${OSPCALLING},
- ${OSPINTIMELIMIT}, and ${OSPOUTTIMELIMIT}
-
-* Builtin transfer functionality sets the variable ${TRANSFERERNAME} in the new
- created channel. This variables holds the channel name of the transferer.
-
-* The dial plan variable PRI_CAUSE will be removed from future versions
- of Asterisk.
- It is replaced by adding a cause value to the hangup() application.
-
-Functions:
-
-* The function ${CHECK_MD5()} has been deprecated in favor of using an
- expression: $[${MD5(<string>)} = ${saved_md5}].
-
-* The 'builtin' functions that used to be combined in pbx_functions.so are
- now built as separate modules. If you are not using 'autoload=yes' in your
- modules.conf file then you will need to explicitly load the modules that
- contain the functions you want to use.
-
-* The ENUMLOOKUP() function with the 'c' option (for counting the number of
- records), but the lookup fails to match any records, the returned value will
- now be "0" instead of blank.
-
-* The REALTIME() function is now available in version 1.4 and app_realtime has
- been deprecated in favor of the new function. app_realtime will be removed
- completely with the version 1.6 release so please take the time between
- releases to make any necessary changes
-
-* The QUEUEAGENTCOUNT() function has been deprecated in favor of
- QUEUE_MEMBER_COUNT().
-
-The IAX2 channel:
-
-* It is possible that previous configurations depended on the order in which
- peers and users were specified in iax.conf for forcing the order in which
- chan_iax2 matched against them. This behavior is going away and is considered
- deprecated in this version. Avoid having ambiguous peer and user entries and
- to make things easy on yourself, always set the "username" option for users
- so that the remote end can match on that exactly instead of trying to infer
- which user you want based on host.
-
- If you would like to go ahead and use the new behavior which doesn't use the
- order in the config file to influence matching order, then change the
- MAX_PEER_BUCKETS define in chan_iax2.c to a value greater than one. An
- example is provided there. By changing this, you will get *much* better
- performance on systems that do a lot of peer and user lookups as they will be
- stored in memory in a much more efficient manner.
-
-* The "mailboxdetail" option has been deprecated. Previously, if this option
- was not enabled, the 2 byte MSGCOUNT information element would be set to all
- 1's to indicate there there is some number of messages waiting. With this
- option enabled, the number of new messages were placed in one byte and the
- number of old messages are placed in the other. This is now the default
- (and the only) behavior.
-
-The SIP channel:
-
-* The "incominglimit" setting is replaced by the "call-limit" setting in
- sip.conf.
-
-* OSP support code is removed from SIP channel to OSP applications. ospauth
- option in sip.conf is removed to osp.conf as authpolicy. allowguest option
- in sip.conf cannot be set as osp anymore.
-
-* The Asterisk RTP stack has been changed in regards to RFC2833 reception
- and transmission. Packets will now be sent with proper duration instead of all
- at once. If you are receiving calls from a pre-1.4 Asterisk installation you
- will want to turn on the rfc2833compensate option. Without this option your
- DTMF reception may act poorly.
-
-* The $SIPUSERAGENT dialplan variable is deprecated and will be removed
- in coming versions of Asterisk. Please use the dialplan function
- SIPCHANINFO(useragent) instead.
-
-* The ALERT_INFO dialplan variable is deprecated and will be removed
- in coming versions of Asterisk. Please use the dialplan application
- sipaddheader() to add the "Alert-Info" header to the outbound invite.
-
-* The "canreinvite" option has changed. canreinvite=yes used to disable
- re-invites if you had NAT=yes. In 1.4, you need to set canreinvite=nonat
- to disable re-invites when NAT=yes. This is propably what you want.
- The settings are now: "yes", "no", "nonat", "update". Please consult
- sip.conf.sample for detailed information.
-
-The Zap channel:
-
-* Support for MFC/R2 has been removed, as it has not been functional for some
- time and it has no maintainer.
-
-The Agent channel:
-
-* Callback mode (AgentCallbackLogin) is now deprecated, since the entire function
- it provided can be done using dialplan logic, without requiring additional
- channel and module locks (which frequently caused deadlocks). An example of
- how to do this using AEL dialplan is in doc/queues-with-callback-members.txt.
-
-The G726-32 codec:
-
-* It has been determined that previous versions of Asterisk used the wrong codeword
- packing order for G726-32 data. This version supports both available packing orders,
- and can transcode between them. It also now selects the proper order when
- negotiating with a SIP peer based on the codec name supplied in the SDP. However,
- there are existing devices that improperly request one order and then use another;
- Sipura and Grandstream ATAs are known to do this, and there may be others. To
- be able to continue to use these devices with this version of Asterisk and the
- G726-32 codec, a configuration parameter called 'g726nonstandard' has been added
- to sip.conf, so that Asterisk can use the packing order expected by the device (even
- though it requested a different order). In addition, the internal format number for
- G726-32 has been changed, and the old number is now assigned to AAL2-G726-32. The
- result of this is that this version of Asterisk will be able to interoperate over
- IAX2 with older versions of Asterisk, as long as this version is told to allow
- 'g726aal2' instead of 'g726' as the codec for the call.
-
-Installation:
-
-* On BSD systems, the installation directories have changed to more "FreeBSDish"
- directories. On startup, Asterisk will look for the main configuration in
- /usr/local/etc/asterisk/asterisk.conf
- If you have an old installation, you might want to remove the binaries and
- move the configuration files to the new locations. The following directories
- are now default:
- ASTLIBDIR /usr/local/lib/asterisk
- ASTVARLIBDIR /usr/local/share/asterisk
- ASTETCDIR /usr/local/etc/asterisk
- ASTBINDIR /usr/local/bin/asterisk
- ASTSBINDIR /usr/local/sbin/asterisk
-
-Music on Hold:
-
-* The music on hold handling has been changed in some significant ways in hopes
- to make it work in a way that is much less confusing to users. Behavior will
- not change if the same configuration is used from older versions of Asterisk.
- However, there are some new configuration options that will make things work
- in a way that makes more sense.
-
- Previously, many of the channel drivers had an option called "musicclass" or
- something similar. This option set what music on hold class this channel
- would *hear* when put on hold. Some people expected (with good reason) that
- this option was to configure what music on hold class to play when putting
- the bridged channel on hold. This option has now been deprecated.
-
- Two new music on hold related configuration options for channel drivers have
- been introduced. Some channel drivers support both options, some just one,
- and some support neither of them. Check the sample configuration files to see
- which options apply to which channel driver.
-
- The "mohsuggest" option specifies which music on hold class to suggest to the
- bridged channel when putting them on hold. The only way that this class can
- be overridden is if the bridged channel has a specific music class set that
- was done in the dialplan using Set(CHANNEL(musicclass)=something).
-
- The "mohinterpret" option is similar to the old "musicclass" option. It
- specifies which music on hold class this channel would like to listen to when
- put on hold. This music class is only effective if this channel has no music
- class set on it from the dialplan and the bridged channel putting this one on
- hold had no "mohsuggest" setting.
-
- The IAX2 and Zap channel drivers have an additional feature for the
- "mohinterpret" option. If this option is set to "passthrough", then these
- channel drivers will pass through the HOLD message in signalling instead of
- starting music on hold on the channel. An example for how this would be
- useful is in an enterprise network of Asterisk servers. When one phone on one
- server puts a phone on a different server on hold, the remote server will be
- responsible for playing the hold music to its local phone that was put on
- hold instead of the far end server across the network playing the music.
-
-CDR Records:
-
-* The behavior of the "clid" field of the CDR has always been that it will
- contain the callerid ANI if it is set, or the callerid number if ANI was not
- set. When using the "callerid" option for various channel drivers, some
- would set ANI and some would not. This has been cleared up so that all
- channel drivers set ANI. If you would like to change the callerid number
- on the channel from the dialplan and have that change also show up in the
- CDR, then you *must* set CALLERID(ANI) as well as CALLERID(num).
-
-API:
-
-* There are some API functions that were not previously prefixed with the 'ast_'
- prefix but now are; these include the ADSI, ODBC and AGI interfaces. If you
- have a module that uses the services provided by res_adsi, res_odbc, or
- res_agi, you will need to add ast_ prefixes to the functions that you call
- from those modules.
-
-Formats:
-
-* format_wav: The GAIN preprocessor definition has been changed from 2 to 0
- in Asterisk 1.4. This change was made in response to user complaints of
- choppiness or the clipping of loud signal peaks. The GAIN preprocessor
- definition will be retained in Asterisk 1.4, but will be removed in a
- future release. The use of GAIN for the increasing of voicemail message
- volume should use the 'volgain' option in voicemail.conf
-
-iLBC Codec:
-
-* Previously, the Asterisk source code distribution included the iLBC
- encoder/decoder source code, from Global IP Solutions
- (http://www.gipscorp.com). This code is not licensed for
- distribution, and thus has been removed from the Asterisk source
- code distribution. If you wish to use codec_ilbc to support iLBC
- channels in Asterisk, you can run the contrib/scripts/get_ilbc_source.sh
- script to download the source and put it in the proper place in
- the Asterisk build tree. Once that is done you can follow your normal
- steps of building Asterisk. You will need to run 'menuselect' and enable
- the iLBC codec in the 'Codec Translators' category.
diff --git a/1.4/acinclude.m4 b/1.4/acinclude.m4
deleted file mode 100644
index 0fa4e546e..000000000
--- a/1.4/acinclude.m4
+++ /dev/null
@@ -1,986 +0,0 @@
-# AST_GCC_ATTRIBUTE([attribute name])
-
-AC_DEFUN([AST_GCC_ATTRIBUTE],
-[
-AC_MSG_CHECKING(for compiler 'attribute $1' support)
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-AC_COMPILE_IFELSE(
- AC_LANG_PROGRAM([static void __attribute__(($1)) *test(void *muffin, ...) {}],
- []),
- AC_MSG_RESULT(yes)
- AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_$1], 1, [Define to 1 if your GCC C compiler supports the '$1' attribute.]),
- AC_MSG_RESULT(no))
-]
-CFLAGS="$saved_CFLAGS"
-)
-
-# AST_EXT_LIB_SETUP([package symbol name], [package friendly name], [package option name], [additional help text])
-
-AC_DEFUN([AST_EXT_LIB_SETUP],
-[
-$1_DESCRIP="$2"
-$1_OPTION="$3"
-AC_ARG_WITH([$3], AC_HELP_STRING([--with-$3=PATH],[use $2 files in PATH $4]),[
-case ${withval} in
- n|no)
- USE_$1=no
- ;;
- y|ye|yes)
- $1_MANDATORY="yes"
- ;;
- *)
- $1_DIR="${withval}"
- $1_MANDATORY="yes"
- ;;
-esac
-])
-PBX_$1=0
-AC_SUBST([$1_LIB])
-AC_SUBST([$1_INCLUDE])
-AC_SUBST([$1_DIR])
-AC_SUBST([PBX_$1])
-])
-
-# AST_EXT_LIB_CHECK([package symbol name], [package library name], [function to check], [package header], [additional LIB data])
-
-AC_DEFUN([AST_EXT_LIB_CHECK],
-[
-if test "${USE_$1}" != "no"; then
- pbxlibdir=""
- if test "x${$1_DIR}" != "x"; then
- if test -d ${$1_DIR}/lib; then
- pbxlibdir="-L${$1_DIR}/lib"
- else
- pbxlibdir="-L${$1_DIR}"
- fi
- fi
- AC_CHECK_LIB([$2], [$3], [AST_$1_FOUND=yes], [AST_$1_FOUND=no], ${pbxlibdir} $5)
-
- if test "${AST_$1_FOUND}" = "yes"; then
- $1_LIB="-l$2 $5"
- $1_HEADER_FOUND="1"
- if test "x${$1_DIR}" != "x"; then
- $1_LIB="${pbxlibdir} ${$1_LIB}"
- $1_INCLUDE="-I${$1_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${$1_DIR}/include"
- if test "x$4" != "x" ; then
- AC_CHECK_HEADER([${$1_DIR}/include/$4], [$1_HEADER_FOUND=1], [$1_HEADER_FOUND=0])
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "x$4" != "x" ; then
- AC_CHECK_HEADER([$4], [$1_HEADER_FOUND=1], [$1_HEADER_FOUND=0])
- fi
- fi
- if test "x${$1_HEADER_FOUND}" = "x0" ; then
- if test -n "${$1_MANDATORY}" ;
- then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** It appears that you do not have the $2 development package installed.])
- AC_MSG_NOTICE([*** Please install it to include ${$1_DESCRIP} support, or re-run configure])
- AC_MSG_NOTICE([*** without explicitly specifying --with-${$1_OPTION}])
- exit 1
- fi
- $1_LIB=""
- $1_INCLUDE=""
- PBX_$1=0
- else
- PBX_$1=1
- AC_DEFINE_UNQUOTED([HAVE_$1], 1, [Define to indicate the ${$1_DESCRIP} library])
- fi
- elif test -n "${$1_MANDATORY}";
- then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The ${$1_DESCRIP} installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** without explicitly specifying --with-${$1_OPTION}])
- exit 1
- fi
-fi
-])
-
-# AST_C_COMPILE_CHECK can be used for testing for various items in header files
-
-# AST_C_COMPILE_CHECK([package], [expression], [header file], [version])
-AC_DEFUN([AST_C_COMPILE_CHECK],
-[
- if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then
- AC_MSG_CHECKING([if "$2" compiles using $3])
- saved_cppflags="${CPPFLAGS}"
- if test "x${$1_DIR}" != "x"; then
- $1_INCLUDE="-I${$1_DIR}/include"
- fi
- CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}"
-
- AC_COMPILE_IFELSE(
- [ AC_LANG_PROGRAM( [#include <$3>],
- [ $2; ]
- )],
- [ AC_MSG_RESULT(yes)
- PBX_$1=1
- AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.])
- AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version])
- ],
- [ AC_MSG_RESULT(no) ]
- )
- CPPFLAGS="${saved_cppflags}"
- fi
-])
-
-AC_DEFUN(
-[AST_CHECK_GNU_MAKE], [AC_CACHE_CHECK(for GNU make, GNU_MAKE,
- GNU_MAKE='Not Found' ;
- GNU_MAKE_VERSION_MAJOR=0 ;
- GNU_MAKE_VERSION_MINOR=0 ;
- for a in make gmake gnumake ; do
- if test -z "$a" ; then continue ; fi ;
- if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
- GNU_MAKE=$a ;
- GNU_MAKE_VERSION_MAJOR=`$GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'`
- GNU_MAKE_VERSION_MINOR=`$GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2`
- break;
- fi
- done ;
-) ;
-if test "x$GNU_MAKE" = "xNot Found" ; then
- AC_MSG_ERROR( *** Please install GNU make. It is required to build Asterisk!)
- exit 1
-fi
-AC_SUBST([GNU_MAKE])
-])
-
-
-AC_DEFUN(
-[AST_CHECK_PWLIB], [
-PWLIB_INCDIR=
-PWLIB_LIBDIR=
-AC_LANG_PUSH([C++])
-if test "${PWLIBDIR:-unset}" != "unset" ; then
- AC_CHECK_HEADER(${PWLIBDIR}/version.h, HAS_PWLIB=1, )
-fi
-if test "${HAS_PWLIB:-unset}" = "unset" ; then
- if test "${OPENH323DIR:-unset}" != "unset"; then
- AC_CHECK_HEADER(${OPENH323DIR}/../pwlib/version.h, HAS_PWLIB=1, )
- fi
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- PWLIBDIR="${OPENH323DIR}/../pwlib"
- else
- AC_CHECK_HEADER(${HOME}/pwlib/include/ptlib.h, HAS_PWLIB=1, )
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- PWLIBDIR="${HOME}/pwlib"
- else
- AC_CHECK_HEADER(/usr/local/include/ptlib.h, HAS_PWLIB=1, )
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin)
- if test "${PTLIB_CONFIG:-unset}" = "unset" ; then
- AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/share/pwlib/make)
- fi
- PWLIB_INCDIR="/usr/local/include"
- PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir`
- if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/local/lib64"
- else
- PWLIB_LIBDIR="/usr/local/lib"
- fi
- fi
- PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs`
- PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`"
- else
- AC_CHECK_HEADER(/usr/include/ptlib.h, HAS_PWLIB=1, )
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/share/pwlib/make)
- PWLIB_INCDIR="/usr/include"
- PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir`
- if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/lib64"
- else
- PWLIB_LIBDIR="/usr/lib"
- fi
- fi
- PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs`
- PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`"
- fi
- fi
- fi
- fi
-fi
-
-#if test "${HAS_PWLIB:-unset}" = "unset" ; then
-# echo "Cannot find pwlib - please install or set PWLIBDIR and try again"
-# exit
-#fi
-
-if test "${HAS_PWLIB:-unset}" != "unset" ; then
- if test "${PWLIBDIR:-unset}" = "unset" ; then
- if test "${PTLIB_CONFIG:-unset}" != "unset" ; then
- PWLIBDIR=`$PTLIB_CONFIG --prefix`
- else
- echo "Cannot find ptlib-config - please install and try again"
- exit
- fi
- fi
-
- if test "x$PWLIBDIR" = "x/usr" -o "x$PWLIBDIR" = "x/usr/"; then
- PWLIBDIR="/usr/share/pwlib"
- PWLIB_INCDIR="/usr/include"
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/lib64"
- else
- PWLIB_LIBDIR="/usr/lib"
- fi
- fi
- if test "x$PWLIBDIR" = "x/usr/local" -o "x$PWLIBDIR" = "x/usr/"; then
- PWLIBDIR="/usr/local/share/pwlib"
- PWLIB_INCDIR="/usr/local/include"
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/local/lib64"
- else
- PWLIB_LIBDIR="/usr/local/lib"
- fi
- fi
-
- if test "${PWLIB_INCDIR:-unset}" = "unset"; then
- PWLIB_INCDIR="${PWLIBDIR}/include"
- fi
- if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
- PWLIB_LIBDIR="${PWLIBDIR}/lib"
- fi
-
- AC_SUBST([PWLIBDIR])
- AC_SUBST([PWLIB_INCDIR])
- AC_SUBST([PWLIB_LIBDIR])
-fi
- AC_LANG_POP([C++])
-])
-
-
-AC_DEFUN(
-[AST_CHECK_OPENH323_PLATFORM], [
-PWLIB_OSTYPE=
-case "$host_os" in
- linux*) PWLIB_OSTYPE=linux ;
- ;;
- freebsd* ) PWLIB_OSTYPE=FreeBSD ;
- ;;
- openbsd* ) PWLIB_OSTYPE=OpenBSD ;
- ENDLDLIBS="-lossaudio" ;
- ;;
- netbsd* ) PWLIB_OSTYPE=NetBSD ;
- ENDLDLIBS="-lossaudio" ;
- ;;
- solaris* | sunos* ) PWLIB_OSTYPE=solaris ;
- ;;
- darwin* ) PWLIB_OSTYPE=Darwin ;
- ;;
- beos*) PWLIB_OSTYPE=beos ;
- STDCCFLAGS="$STDCCFLAGS -D__BEOS__"
- ;;
- cygwin*) PWLIB_OSTYPE=cygwin ;
- ;;
- mingw*) PWLIB_OSTYPE=mingw ;
- STDCCFLAGS="$STDCCFLAGS -mms-bitfields" ;
- ENDLDLIBS="-lwinmm -lwsock32 -lsnmpapi -lmpr -lcomdlg32 -lgdi32 -lavicap32" ;
- ;;
- * ) PWLIB_OSTYPE="$host_os" ;
- AC_MSG_WARN("OS $PWLIB_OSTYPE not recognized - proceed with caution!") ;
- ;;
-esac
-
-PWLIB_MACHTYPE=
-case "$host_cpu" in
- x86 | i686 | i586 | i486 | i386 ) PWLIB_MACHTYPE=x86
- ;;
-
- x86_64) PWLIB_MACHTYPE=x86_64 ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- alpha | alphaev56 | alphaev6 | alphaev67 | alphaev7) PWLIB_MACHTYPE=alpha ;
- P_64BIT=1 ;
- ;;
-
- sparc ) PWLIB_MACHTYPE=sparc ;
- ;;
-
- powerpc ) PWLIB_MACHTYPE=ppc ;
- ;;
-
- ppc ) PWLIB_MACHTYPE=ppc ;
- ;;
-
- powerpc64 ) PWLIB_MACHTYPE=ppc64 ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- ppc64 ) PWLIB_MACHTYPE=ppc64 ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- ia64) PWLIB_MACHTYPE=ia64 ;
- P_64BIT=1 ;
- ;;
-
- s390x) PWLIB_MACHTYPE=s390x ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- s390) PWLIB_MACHTYPE=s390 ;
- ;;
-
- * ) PWLIB_MACHTYPE="$host_cpu";
- AC_MSG_WARN("CPU $PWLIB_MACHTYPE not recognized - proceed with caution!") ;;
-esac
-
-PWLIB_PLATFORM="${PWLIB_OSTYPE}_${PWLIB_MACHTYPE}"
-
-AC_SUBST([PWLIB_PLATFORM])
-])
-
-
-AC_DEFUN(
-[AST_CHECK_OPENH323], [
-OPENH323_INCDIR=
-OPENH323_LIBDIR=
-AC_LANG_PUSH([C++])
-if test "${OPENH323DIR:-unset}" != "unset" ; then
- AC_CHECK_HEADER(${OPENH323DIR}/version.h, HAS_OPENH323=1, )
-fi
-if test "${HAS_OPENH323:-unset}" = "unset" ; then
- AC_CHECK_HEADER(${PWLIBDIR}/../openh323/version.h, OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1, )
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="${PWLIBDIR}/../openh323"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${PWLIB_INCDIR}/openh323 -I${PWLIB_INCDIR}"
- AC_CHECK_HEADER(${OPENH323DIR}/include/h323.h, , OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}", [#include <ptlib.h>])
- CPPFLAGS="${saved_cppflags}"
- else
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${HOME}/openh323/include -I${PWLIB_INCDIR}"
- AC_CHECK_HEADER(${HOME}/openh323/include/h323.h, HAS_OPENH323=1, )
- CPPFLAGS="${saved_cppflags}"
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="${HOME}/openh323"
- else
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I/usr/local/include/openh323 -I${PWLIB_INCDIR}"
- AC_CHECK_HEADER(/usr/local/include/openh323/h323.h, HAS_OPENH323=1, )
- CPPFLAGS="${saved_cppflags}"
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="/usr/local/share/openh323"
- OPENH323_INCDIR="/usr/local/include/openh323"
- if test "x$LIB64" != "x"; then
- OPENH323_LIBDIR="/usr/local/lib64"
- else
- OPENH323_LIBDIR="/usr/local/lib"
- fi
- else
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I/usr/include/openh323 -I${PWLIB_INCDIR}"
- AC_CHECK_HEADER(/usr/include/openh323/h323.h, HAS_OPENH323=1, , [#include <ptlib.h>])
- CPPFLAGS="${saved_cppflags}"
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="/usr/share/openh323"
- OPENH323_INCDIR="/usr/include/openh323"
- if test "x$LIB64" != "x"; then
- OPENH323_LIBDIR="/usr/lib64"
- else
- OPENH323_LIBDIR="/usr/lib"
- fi
- fi
- fi
- fi
- fi
-fi
-
-if test "${HAS_OPENH323:-unset}" != "unset" ; then
- if test "${OPENH323_INCDIR:-unset}" = "unset"; then
- OPENH323_INCDIR="${OPENH323DIR}/include"
- fi
- if test "${OPENH323_LIBDIR:-unset}" = "unset"; then
- OPENH323_LIBDIR="${OPENH323DIR}/lib"
- fi
-
- OPENH323_LIBDIR="`cd ${OPENH323_LIBDIR}; pwd`"
- OPENH323_INCDIR="`cd ${OPENH323_INCDIR}; pwd`"
- OPENH323DIR="`cd ${OPENH323DIR}; pwd`"
-
- AC_SUBST([OPENH323DIR])
- AC_SUBST([OPENH323_INCDIR])
- AC_SUBST([OPENH323_LIBDIR])
-fi
- AC_LANG_POP([C++])
-])
-
-
-AC_DEFUN(
-[AST_CHECK_PWLIB_VERSION], [
- if test "${HAS_$2:-unset}" != "unset"; then
- $2_VERSION=`grep "$2_VERSION" ${$2_INCDIR}/$3 | cut -f2 -d ' ' | sed -e 's/"//g'`
- $2_MAJOR_VERSION=`echo ${$2_VERSION} | cut -f1 -d.`
- $2_MINOR_VERSION=`echo ${$2_VERSION} | cut -f2 -d.`
- $2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.`
- let $2_VER=${$2_MAJOR_VERSION}*10000+${$2_MINOR_VERSION}*100+${$2_BUILD_NUMBER}
- let $2_REQ=$4*10000+$5*100+$6
-
- AC_MSG_CHECKING(if $1 version ${$2_VERSION} is compatible with chan_h323)
- if test ${$2_VER} -lt ${$2_REQ}; then
- AC_MSG_RESULT(no)
- unset HAS_$2
- else
- AC_MSG_RESULT(yes)
- fi
- fi
-])
-
-
-AC_DEFUN(
-[AST_CHECK_PWLIB_BUILD], [
- if test "${HAS_$2:-unset}" != "unset"; then
- AC_MSG_CHECKING($1 installation validity)
-
- saved_cppflags="${CPPFLAGS}"
- saved_libs="${LIBS}"
- if test "${$2_LIB:-unset}" != "unset"; then
- LIBS="${LIBS} ${$2_LIB} $7"
- else
- LIBS="${LIBS} -L${$2_LIBDIR} -l${PLATFORM_$2} $7"
- fi
- CPPFLAGS="${CPPFLAGS} -I${$2_INCDIR} $6"
-
- AC_LANG_PUSH([C++])
-
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([$4],[$5])],
- [ AC_MSG_RESULT(yes)
- ac_cv_lib_$2="yes"
- ],
- [ AC_MSG_RESULT(no)
- ac_cv_lib_$2="no"
- ]
- )
-
- AC_LANG_POP([C++])
-
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
-
- if test "${ac_cv_lib_$2}" = "yes"; then
- if test "${$2_LIB:-undef}" = "undef"; then
- if test "${$2_LIBDIR}" != "" -a "${$2_LIBDIR}" != "/usr/lib"; then
- $2_LIB="-L${$2_LIBDIR} -l${PLATFORM_$2}"
- else
- $2_LIB="-l${PLATFORM_$2}"
- fi
- fi
- if test "${$2_INCDIR}" != "" -a "${$2_INCDIR}" != "/usr/include"; then
- $2_INCLUDE="-I${$2_INCDIR}"
- fi
- PBX_$2=1
- AC_DEFINE([HAVE_$2], 1, [$3])
- fi
- fi
-])
-
-AC_DEFUN(
-[AST_CHECK_OPENH323_BUILD], [
- if test "${HAS_OPENH323:-unset}" != "unset"; then
- AC_MSG_CHECKING(OpenH323 build option)
- OPENH323_SUFFIX=
- prefixes="h323_${PWLIB_PLATFORM}_ h323_ openh323"
- for pfx in $prefixes; do
- files=`ls -l ${OPENH323_LIBDIR}/lib${pfx}*.so* 2>/dev/null`
- libfile=
- if test -n "$files"; then
- for f in $files; do
- if test -f $f -a ! -L $f; then
- libfile=`basename $f`
- break;
- fi
- done
- fi
- if test -n "$libfile"; then
- OPENH323_PREFIX=$pfx
- break;
- fi
- done
- if test "${libfile:-unset}" != "unset"; then
- OPENH323_SUFFIX=`eval "echo ${libfile} | sed -e 's/lib${OPENH323_PREFIX}\(@<:@^.@:>@*\)\..*/\1/'"`
- fi
- case "${OPENH323_SUFFIX}" in
- n)
- OPENH323_BUILD="notrace";;
- r)
- OPENH323_BUILD="opt";;
- d)
- OPENH323_BUILD="debug";;
- *)
- if test "${OPENH323_PREFIX:-undef}" = "openh323"; then
- notrace=`eval "grep NOTRACE ${OPENH323DIR}/openh323u.mak | grep = | sed -e 's/@<:@A-Z0-9_@:>@*@<:@ @:>@*=@<:@ @:>@*//'"`
- if test "x$notrace" = "x"; then
- notrace="0"
- fi
- if test "$notrace" -ne 0; then
- OPENH323_BUILD="notrace"
- else
- OPENH323_BUILD="opt"
- fi
- OPENH323_LIB="-l${OPENH323_PREFIX}"
- else
- OPENH323_BUILD="notrace"
- fi
- ;;
- esac
- AC_MSG_RESULT(${OPENH323_BUILD})
-
- AC_SUBST([OPENH323_SUFFIX])
- AC_SUBST([OPENH323_BUILD])
- fi
-])
-
-
-# AST_FUNC_FORK
-# -------------
-AN_FUNCTION([fork], [AST_FUNC_FORK])
-AN_FUNCTION([vfork], [AST_FUNC_FORK])
-AC_DEFUN([AST_FUNC_FORK],
-[AC_REQUIRE([AC_TYPE_PID_T])dnl
-AC_CHECK_HEADERS(vfork.h)
-AC_CHECK_FUNCS(fork vfork)
-if test "x$ac_cv_func_fork" = xyes; then
- _AST_FUNC_FORK
-else
- ac_cv_func_fork_works=$ac_cv_func_fork
-fi
-if test "x$ac_cv_func_fork_works" = xcross; then
- case $host in
- *-*-amigaos* | *-*-msdosdjgpp* | *-*-uclinux* | *-*-linux-uclibc* )
- # Override, as these systems have only a dummy fork() stub
- ac_cv_func_fork_works=no
- ;;
- *)
- ac_cv_func_fork_works=yes
- ;;
- esac
- AC_MSG_WARN([result $ac_cv_func_fork_works guessed because of cross compilation])
-fi
-ac_cv_func_vfork_works=$ac_cv_func_vfork
-if test "x$ac_cv_func_vfork" = xyes; then
- _AC_FUNC_VFORK
-fi;
-if test "x$ac_cv_func_fork_works" = xcross; then
- ac_cv_func_vfork_works=$ac_cv_func_vfork
- AC_MSG_WARN([result $ac_cv_func_vfork_works guessed because of cross compilation])
-fi
-
-if test "x$ac_cv_func_vfork_works" = xyes; then
- AC_DEFINE(HAVE_WORKING_VFORK, 1, [Define to 1 if `vfork' works.])
-else
- AC_DEFINE(vfork, fork, [Define as `fork' if `vfork' does not work.])
-fi
-if test "x$ac_cv_func_fork_works" = xyes; then
- AC_DEFINE(HAVE_WORKING_FORK, 1, [Define to 1 if `fork' works.])
-fi
-])# AST_FUNC_FORK
-
-
-# _AST_FUNC_FORK
-# -------------
-AC_DEFUN([_AST_FUNC_FORK],
- [AC_CACHE_CHECK(for working fork, ac_cv_func_fork_works,
- [AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
- [
- /* By Ruediger Kuhlmann. */
- return fork () < 0;
- ])],
- [ac_cv_func_fork_works=yes],
- [ac_cv_func_fork_works=no],
- [ac_cv_func_fork_works=cross])])]
-)# _AST_FUNC_FORK
-
-# AST_PROG_LD
-# ----------
-# find the pathname to the GNU or non-GNU linker
-AC_DEFUN([AST_PROG_LD],
-[AC_ARG_WITH([gnu-ld],
- [AC_HELP_STRING([--with-gnu-ld],
- [assume the C compiler uses GNU ld @<:@default=no@:>@])],
- [test "$withval" = no || with_gnu_ld=yes],
- [with_gnu_ld=no])
-AC_REQUIRE([AST_PROG_SED])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- AC_MSG_CHECKING([for ld used by $CC])
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [[\\/]]* | ?:[[\\/]]*)
- re_direlt='/[[^/]][[^/]]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- AC_MSG_CHECKING([for GNU ld])
-else
- AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(lt_cv_path_LD,
-[if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- AC_MSG_RESULT($LD)
-else
- AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AST_PROG_LD_GNU
-])# AST_PROG_LD
-
-
-# AST_PROG_LD_GNU
-# --------------
-AC_DEFUN([AST_PROG_LD_GNU],
-[AC_REQUIRE([AST_PROG_EGREP])dnl
-AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac])
-with_gnu_ld=$lt_cv_prog_gnu_ld
-])# AST_PROG_LD_GNU
-
-# AST_PROG_EGREP
-# -------------
-m4_ifndef([AST_PROG_EGREP], [AC_DEFUN([AST_PROG_EGREP],
-[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
- [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi])
- EGREP=$ac_cv_prog_egrep
- AC_SUBST([EGREP])
-])]) # AST_PROG_EGREP
-
-# AST_PROG_SED
-# -----------
-# Check for a fully functional sed program that truncates
-# as few characters as possible. Prefer GNU sed if found.
-AC_DEFUN([AST_PROG_SED],
-[AC_CACHE_CHECK([for a sed that does not truncate output], ac_cv_path_SED,
- [dnl ac_script should not contain more than 99 commands (for HP-UX sed),
- dnl but more than about 7000 bytes, to catch a limit in Solaris 8 /usr/ucb/sed.
- ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for ac_i in 1 2 3 4 5 6 7; do
- ac_script="$ac_script$as_nl$ac_script"
- done
- echo "$ac_script" | sed 99q >conftest.sed
- $as_unset ac_script || ac_script=
- _AC_PATH_PROG_FEATURE_CHECK(SED, [sed gsed],
- [_AC_FEATURE_CHECK_LENGTH([ac_path_SED], [ac_cv_path_SED],
- ["$ac_path_SED" -f conftest.sed])])])
- SED="$ac_cv_path_SED"
- AC_SUBST([SED])dnl
- rm -f conftest.sed
-])# AST_PROG_SED
-
-dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-dnl
-dnl @summary figure out how to build C programs using POSIX threads
-dnl
-dnl This macro figures out how to build C programs using POSIX threads.
-dnl It sets the PTHREAD_LIBS output variable to the threads library and
-dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
-dnl C compiler flags that are needed. (The user can also force certain
-dnl compiler flags/libs to be tested by setting these environment
-dnl variables.)
-dnl
-dnl Also sets PTHREAD_CC to any special C compiler that is needed for
-dnl multi-threaded programs (defaults to the value of CC otherwise).
-dnl (This is necessary on AIX to use the special cc_r compiler alias.)
-dnl
-dnl NOTE: You are assumed to not only compile your program with these
-dnl flags, but also link it with them as well. e.g. you should link
-dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
-dnl $LIBS
-dnl
-dnl If you are only building threads programs, you may wish to use
-dnl these variables in your default LIBS, CFLAGS, and CC:
-dnl
-dnl LIBS="$PTHREAD_LIBS $LIBS"
-dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-dnl CC="$PTHREAD_CC"
-dnl
-dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
-dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
-dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-dnl
-dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
-dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
-dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
-dnl default action will define HAVE_PTHREAD.
-dnl
-dnl Please let the authors know if this macro fails on any platform, or
-dnl if you have any other suggestions or comments. This macro was based
-dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
-dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
-dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
-dnl We are also grateful for the helpful feedback of numerous users.
-dnl
-dnl @category InstalledPackages
-dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
-dnl @version 2006-05-29
-dnl @license GPLWithACException
-
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
- AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
- AC_MSG_RESULT($acx_pthread_ok)
- if test x"$acx_pthread_ok" = xno; then
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- fi
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important. Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-# other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-# doesn't hurt to check since this sometimes defines pthreads too;
-# also defines -D_REENTRANT)
-# ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
- *solaris*)
-
- # On Solaris (at least, for some versions), libc contains stubbed
- # (non-functional) versions of the pthreads routines, so link-based
- # tests will erroneously succeed. (We need to link with -pthreads/-mt/
- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
- # a function called by this macro, so we could check for that, but
- # who knows whether they'll stub that too in a future libc.) So,
- # we'll just look for -pthreads and -lpthread first:
-
- acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
- ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
- case $flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
- -*)
- AC_MSG_CHECKING([whether pthreads work with $flag])
- PTHREAD_CFLAGS="$flag"
- ;;
-
- pthread-config)
- AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
- if test x"$acx_pthread_config" = xno; then continue; fi
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
- AC_MSG_CHECKING([for the pthreads library -l$flag])
- PTHREAD_LIBS="-l$flag"
- ;;
- esac
-
- save_LIBS="$LIBS"
- save_CFLAGS="$CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
- AC_TRY_LINK([#include <pthread.h>],
- [pthread_t th; pthread_join(th, 0);
- pthread_attr_init(0); pthread_cleanup_push(0, 0);
- pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
- [acx_pthread_ok=yes])
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- AC_MSG_RESULT($acx_pthread_ok)
- if test "x$acx_pthread_ok" = xyes; then
- break;
- fi
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
- AC_MSG_CHECKING([for joinable pthread attribute])
- attr_name=unknown
- for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
- AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
- [attr_name=$attr; break])
- done
- AC_MSG_RESULT($attr_name)
- if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
- AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
- [Define to necessary symbol if this constant
- uses a non-standard name on your system.])
- fi
-
- AC_MSG_CHECKING([if more special flags are required for pthreads])
- flag=no
- case "${host_cpu}-${host_os}" in
- *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
- *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
- esac
- AC_MSG_RESULT(${flag})
- if test "x$flag" != xno; then
- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
- fi
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- # More AIX lossage: must compile with xlc_r or cc_r
- if test x"$GCC" != xyes; then
- AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
- else
- PTHREAD_CC=$CC
- fi
-else
- PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
- ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
- :
-else
- acx_pthread_ok=no
- $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD
diff --git a/1.4/agi/DialAnMp3.agi b/1.4/agi/DialAnMp3.agi
deleted file mode 100644
index 59a54265e..000000000
--- a/1.4/agi/DialAnMp3.agi
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/perl
-#
-# Simple AGI application to play mp3's selected by a user both using
-# xmms and over the phone itself.
-#
-$|=1;
-while(<STDIN>) {
- chomp;
- last unless length($_);
- if (/^agi_(\w+)\:\s+(.*)$/) {
- $AGI{$1} = $2;
- }
-}
-
-print STDERR "AGI Environment Dump:\n";
-foreach $i (sort keys %AGI) {
- print STDERR " -- $i = $AGI{$i}\n";
-}
-
-dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
-
-sub checkresult {
- my ($res) = @_;
- my $retval;
- $tests++;
- chomp $res;
- if ($res =~ /^200/) {
- $res =~ /result=(-?[\w\*\#]+)/;
- return $1;
- } else {
- return -1;
- }
-}
-
-#print STDERR "1. Playing beep...\n";
-#print "STREAM FILE beep \"\"\n";
-#$result = <STDIN>;
-#checkresult($result);
-
-print STDERR "2. Getting song name...\n";
-print "GET DATA demo-enterkeywords\n";
-$result = <STDIN>;
-$digitstr = checkresult($result);
-if ($digitstr < 0) {
- exit(1);
-}
-$digitstr =~ s/\*/ /g;
-
-print STDERR "Resulting songname is $digitstr\n";
-@searchwords = split (/\s+/, $digitstr);
-print STDERR "Searchwords: " . join(':', @searchwords) . "\n";
-
-foreach $key (sort keys %DIGITS) {
- @words = split(/\s+/, $DIGITS{$key});
- $match = 1;
- foreach $search (@searchwords) {
- $match = 0 unless grep(/$search/, @words);
- }
- if ($match > 0) {
- print STDERR "File $key matches\n";
- # Play a beep
- print "STREAM FILE beep \"\"\n";
- system("xmms", $key);
- $result = <STDIN>;
- if (&checkresult($result) < 0) {
- exit 0;
- }
- print "EXEC MP3Player \"$key\"\n";
-# print "WAIT FOR DIGIT 60000\n";
- $result = <STDIN>;
- if (&checkresult($result) < 0) {
- exit 0;
- }
- print STDERR "Got here...\n";
- }
-}
-
-print STDERR "4. Testing 'saynumber' of $digitstr...\n";
-print "STREAM FILE demo-nomatch\"\"\n";
-$result = <STDIN>;
-checkresult($result);
-
diff --git a/1.4/agi/Makefile b/1.4/agi/Makefile
deleted file mode 100644
index c24c7f100..000000000
--- a/1.4/agi/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for AGI-related stuff
-#
-# Copyright (C) 1999-2006, Digium
-#
-# Mark Spencer <markster@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
-.PHONY: clean all uninstall
-
-AGIS=agi-test.agi eagi-test eagi-sphinx-test jukebox.agi
-
-ifeq ($(OSARCH),SunOS)
- LIBS+=-lsocket -lnsl
-endif
-
-include $(ASTTOPDIR)/Makefile.rules
-
-all: $(AGIS)
-
-strcompat.c: ../main/strcompat.c
- @cp $< $@
-
-eagi-test: eagi-test.o strcompat.o
-
-eagi-sphinx-test: eagi-sphinx-test.o
-
-install: all
- mkdir -p $(DESTDIR)$(AGI_DIR)
- for x in $(AGIS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(AGI_DIR) ; done
-
-uninstall:
- for x in $(AGIS); do rm -f $(DESTDIR)$(AGI_DIR)/$$x ; done
-
-clean:
- rm -f *.so *.o look eagi-test eagi-sphinx-test
- rm -f .*.o.d .*.oo.d *.s *.i
- rm -f strcompat.c
-
-ifneq ($(wildcard .*.d),)
- include .*.d
-endif
diff --git a/1.4/agi/agi-test.agi b/1.4/agi/agi-test.agi
deleted file mode 100644
index 4fc36eda8..000000000
--- a/1.4/agi/agi-test.agi
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/perl
-use strict;
-
-$|=1;
-
-# Setup some variables
-my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-
-while(<STDIN>) {
- chomp;
- last unless length($_);
- if (/^agi_(\w+)\:\s+(.*)$/) {
- $AGI{$1} = $2;
- }
-}
-
-print STDERR "AGI Environment Dump:\n";
-foreach my $i (sort keys %AGI) {
- print STDERR " -- $i = $AGI{$i}\n";
-}
-
-sub checkresult {
- my ($res) = @_;
- my $retval;
- $tests++;
- chomp $res;
- if ($res =~ /^200/) {
- $res =~ /result=(-?\d+)/;
- if (!length($1)) {
- print STDERR "FAIL ($res)\n";
- $fail++;
- } else {
- print STDERR "PASS ($1)\n";
- $pass++;
- }
- } else {
- print STDERR "FAIL (unexpected result '$res')\n";
- $fail++;
- }
-}
-
-print STDERR "1. Testing 'sendfile'...";
-print "STREAM FILE beep \"\"\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "2. Testing 'sendtext'...";
-print "SEND TEXT \"hello world\"\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "3. Testing 'sendimage'...";
-print "SEND IMAGE asterisk-image\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "4. Testing 'saynumber'...";
-print "SAY NUMBER 192837465 \"\"\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "5. Testing 'waitdtmf'...";
-print "WAIT FOR DIGIT 1000\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "6. Testing 'record'...";
-print "RECORD FILE testagi gsm 1234 3000\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "6a. Testing 'record' playback...";
-print "STREAM FILE testagi \"\"\n";
-my $result = <STDIN>;
-&checkresult($result);
-
-print STDERR "================== Complete ======================\n";
-print STDERR "$tests tests completed, $pass passed, $fail failed\n";
-print STDERR "==================================================\n";
diff --git a/1.4/agi/eagi-sphinx-test.c b/1.4/agi/eagi-sphinx-test.c
deleted file mode 100644
index 0ad12c787..000000000
--- a/1.4/agi/eagi-sphinx-test.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Extended AGI test application
- *
- * This code is released into public domain
- * without any warranty of any kind.
- *
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include "asterisk.h"
-
-#include "asterisk/compat.h"
-
-#define AUDIO_FILENO (STDERR_FILENO + 1)
-
-#define SPHINX_HOST "192.168.1.108"
-#define SPHINX_PORT 3460
-
-static int sphinx_sock = -1;
-
-static int connect_sphinx(void)
-{
- struct hostent *hp;
- struct sockaddr_in sin;
- int res;
- hp = gethostbyname(SPHINX_HOST);
- if (!hp) {
- fprintf(stderr, "Unable to resolve '%s'\n", SPHINX_HOST);
- return -1;
- }
- sphinx_sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sphinx_sock < 0) {
- fprintf(stderr, "Unable to allocate socket: %s\n", strerror(errno));
- return -1;
- }
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(SPHINX_PORT);
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- if (connect(sphinx_sock, (struct sockaddr *)&sin, sizeof(sin))) {
- fprintf(stderr, "Unable to connect on socket: %s\n", strerror(errno));
- close(sphinx_sock);
- sphinx_sock = -1;
- return -1;
- }
- res = fcntl(sphinx_sock, F_GETFL);
- if ((res < 0) || (fcntl(sphinx_sock, F_SETFL, res | O_NONBLOCK) < 0)) {
- fprintf(stderr, "Unable to set flags on socket: %s\n", strerror(errno));
- close(sphinx_sock);
- sphinx_sock = -1;
- return -1;
- }
- return 0;
-}
-
-static int read_environment(void)
-{
- char buf[256];
- char *val;
- /* Read environment */
- for(;;) {
- fgets(buf, sizeof(buf), stdin);
- if (feof(stdin))
- return -1;
- buf[strlen(buf) - 1] = '\0';
- /* Check for end of environment */
- if (!strlen(buf))
- return 0;
- val = strchr(buf, ':');
- if (!val) {
- fprintf(stderr, "Invalid environment: '%s'\n", buf);
- return -1;
- }
- *val = '\0';
- val++;
- val++;
- /* Skip space */
- fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
-
- /* Load into normal environment */
- setenv(buf, val, 1);
-
- }
- /* Never reached */
- return 0;
-}
-
-static char *wait_result(void)
-{
- fd_set fds;
- int res;
- int max;
- static char astresp[256];
- static char sphinxresp[256];
- char audiobuf[4096];
- for (;;) {
- FD_ZERO(&fds);
- FD_SET(STDIN_FILENO, &fds);
- FD_SET(AUDIO_FILENO, &fds);
- max = AUDIO_FILENO;
- if (sphinx_sock > -1) {
- FD_SET(sphinx_sock, &fds);
- if (sphinx_sock > max)
- max = sphinx_sock;
- }
- /* Wait for *some* sort of I/O */
- res = select(max + 1, &fds, NULL, NULL, NULL);
- if (res < 0) {
- fprintf(stderr, "Error in select: %s\n", strerror(errno));
- return NULL;
- }
- if (FD_ISSET(STDIN_FILENO, &fds)) {
- fgets(astresp, sizeof(astresp), stdin);
- if (feof(stdin)) {
- fprintf(stderr, "Got hungup on apparently\n");
- return NULL;
- }
- astresp[strlen(astresp) - 1] = '\0';
- fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
- return astresp;
- }
- if (FD_ISSET(AUDIO_FILENO, &fds)) {
- res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
- if (res > 0) {
- if (sphinx_sock > -1)
- write(sphinx_sock, audiobuf, res);
- }
- }
- if ((sphinx_sock > -1) && FD_ISSET(sphinx_sock, &fds)) {
- res = read(sphinx_sock, sphinxresp, sizeof(sphinxresp));
- if (res > 0) {
- fprintf(stderr, "Oooh, Sphinx found a token: '%s'\n", sphinxresp);
- return sphinxresp;
- } else if (res == 0) {
- fprintf(stderr, "Hrm, lost sphinx, guess we're on our own\n");
- close(sphinx_sock);
- sphinx_sock = -1;
- }
- }
- }
-
-}
-
-static char *run_command(char *command)
-{
- fprintf(stdout, "%s\n", command);
- return wait_result();
-}
-
-static int run_script(void)
-{
- char *res;
- res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "1. Result is '%s'\n", res);
- res = run_command("STREAM FILE demo-nomatch 0123456789*#");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "2. Result is '%s'\n", res);
- res = run_command("SAY NUMBER 23452345 0123456789*#");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "3. Result is '%s'\n", res);
- res = run_command("GET DATA demo-enterkeywords");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "4. Result is '%s'\n", res);
- res = run_command("STREAM FILE auth-thankyou \"\"");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "5. Result is '%s'\n", res);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- char *tmp;
- int ver = 0;
- int subver = 0;
- /* Setup stdin/stdout for line buffering */
- setlinebuf(stdin);
- setlinebuf(stdout);
- if (read_environment()) {
- fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
- exit(1);
- }
- connect_sphinx();
- tmp = getenv("agi_enhanced");
- if (tmp) {
- if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
- ver = 0;
- }
- if (ver < 1) {
- fprintf(stderr, "No enhanced AGI services available. Use EAGI, not AGI\n");
- exit(1);
- }
- if (run_script())
- return -1;
- exit(0);
-}
diff --git a/1.4/agi/eagi-test.c b/1.4/agi/eagi-test.c
deleted file mode 100644
index 7745d18ae..000000000
--- a/1.4/agi/eagi-test.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Extended AGI test application
- *
- * This code is released into the public domain
- * with no warranty of any kind
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/select.h>
-
-#include "asterisk.h"
-
-#include "asterisk/compat.h"
-
-#define AUDIO_FILENO (STDERR_FILENO + 1)
-
-static int read_environment(void)
-{
- char buf[256];
- char *val;
- /* Read environment */
- for(;;) {
- fgets(buf, sizeof(buf), stdin);
- if (feof(stdin))
- return -1;
- buf[strlen(buf) - 1] = '\0';
- /* Check for end of environment */
- if (!strlen(buf))
- return 0;
- val = strchr(buf, ':');
- if (!val) {
- fprintf(stderr, "Invalid environment: '%s'\n", buf);
- return -1;
- }
- *val = '\0';
- val++;
- val++;
- /* Skip space */
- fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
-
- /* Load into normal environment */
- setenv(buf, val, 1);
-
- }
- /* Never reached */
- return 0;
-}
-
-static char *wait_result(void)
-{
- fd_set fds;
- int res;
- int bytes = 0;
- static char astresp[256];
- char audiobuf[4096];
- for (;;) {
- FD_ZERO(&fds);
- FD_SET(STDIN_FILENO, &fds);
- FD_SET(AUDIO_FILENO, &fds);
- /* Wait for *some* sort of I/O */
- res = select(AUDIO_FILENO + 1, &fds, NULL, NULL, NULL);
- if (res < 0) {
- fprintf(stderr, "Error in select: %s\n", strerror(errno));
- return NULL;
- }
- if (FD_ISSET(STDIN_FILENO, &fds)) {
- fgets(astresp, sizeof(astresp), stdin);
- if (feof(stdin)) {
- fprintf(stderr, "Got hungup on apparently\n");
- return NULL;
- }
- astresp[strlen(astresp) - 1] = '\0';
- fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
- return astresp;
- }
- if (FD_ISSET(AUDIO_FILENO, &fds)) {
- res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
- if (res > 0) {
- /* XXX Process the audio with sphinx here XXX */
-#if 0
- fprintf(stderr, "Got %d/%d bytes of audio\n", res, bytes);
-#endif
- bytes += res;
- /* Prentend we detected some audio after 3 seconds */
- if (bytes > 16000 * 3) {
- return "Sample Message";
- bytes = 0;
- }
- }
- }
- }
-
-}
-
-static char *run_command(char *command)
-{
- fprintf(stdout, "%s\n", command);
- return wait_result();
-}
-
-static int run_script(void)
-{
- char *res;
- res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "1. Result is '%s'\n", res);
- res = run_command("STREAM FILE demo-nomatch 0123456789*#");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "2. Result is '%s'\n", res);
- res = run_command("SAY NUMBER 23452345 0123456789*#");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "3. Result is '%s'\n", res);
- res = run_command("GET DATA demo-enterkeywords");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "4. Result is '%s'\n", res);
- res = run_command("STREAM FILE auth-thankyou \"\"");
- if (!res) {
- fprintf(stderr, "Failed to execute command\n");
- return -1;
- }
- fprintf(stderr, "5. Result is '%s'\n", res);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- char *tmp;
- int ver = 0;
- int subver = 0;
- /* Setup stdin/stdout for line buffering */
- setlinebuf(stdin);
- setlinebuf(stdout);
- if (read_environment()) {
- fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
- exit(1);
- }
- tmp = getenv("agi_enhanced");
- if (tmp) {
- if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
- ver = 0;
- }
- if (ver < 1) {
- fprintf(stderr, "No enhanced AGI services available. Use EAGI, not AGI\n");
- exit(1);
- }
- if (run_script())
- return -1;
- exit(0);
-}
diff --git a/1.4/agi/fastagi-test b/1.4/agi/fastagi-test
deleted file mode 100644
index d3f13cf6b..000000000
--- a/1.4/agi/fastagi-test
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use Socket;
-use Carp;
-use IO::Handle;
-
-my $port = 4573;
-
-$|=1;
-
-# Setup some variables
-my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-
-sub checkresult {
- my ($res) = @_;
- my $retval;
- $tests++;
- chomp $res;
- if ($res =~ /^200/) {
- $res =~ /result=(-?\d+)/;
- if (!length($1)) {
- print STDERR "FAIL ($res)\n";
- $fail++;
- } else {
- print STDERR "PASS ($1)\n";
- $pass++;
- }
- } else {
- print STDERR "FAIL (unexpected result '$res')\n";
- $fail++;
- }
-}
-
-socket(SERVER, PF_INET, SOCK_STREAM, 0);
-setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
-bind(SERVER, sockaddr_in($port, INADDR_ANY)) || die("can't bind\n");
-listen(SERVER, SOMAXCONN);
-
-for(;;) {
- my $raddr = accept(CLIENT, SERVER);
- my ($s, $p) = sockaddr_in($raddr);
- CLIENT->autoflush(1);
- while(<CLIENT>) {
- chomp;
- last unless length($_);
- if (/^agi_(\w+)\:\s+(.*)$/) {
- $AGI{$1} = $2;
- }
- }
- print STDERR "AGI Environment Dump from $s:$p --\n";
- foreach my $i (sort keys %AGI) {
- print STDERR " -- $i = $AGI{$i}\n";
- }
-
- print STDERR "1. Testing 'sendfile'...";
- print CLIENT "STREAM FILE beep \"\"\n";
- my $result = <CLIENT>;
- &checkresult($result);
-
- print STDERR "2. Testing 'sendtext'...";
- print CLIENT "SEND TEXT \"hello world\"\n";
- my $result = <CLIENT>;
- &checkresult($result);
-
- print STDERR "3. Testing 'sendimage'...";
- print CLIENT "SEND IMAGE asterisk-image\n";
- my $result = <CLIENT>;
- &checkresult($result);
-
- print STDERR "4. Testing 'saynumber'...";
- print CLIENT "SAY NUMBER 192837465 \"\"\n";
- my $result = <CLIENT>;
- &checkresult($result);
-
- print STDERR "5. Testing 'waitdtmf'...";
- print CLIENT "WAIT FOR DIGIT 1000\n";
- my $result = <CLIENT>;
- &checkresult($result);
-
- print STDERR "6. Testing 'record'...";
- print CLIENT "RECORD FILE testagi gsm 1234 3000\n";
- my $result = <CLIENT>;
- &checkresult($result);
-
- print STDERR "6a. Testing 'record' playback...";
- print CLIENT "STREAM FILE testagi \"\"\n";
- my $result = <CLIENT>;
- &checkresult($result);
- close(CLIENT);
- print STDERR "================== Complete ======================\n";
- print STDERR "$tests tests completed, $pass passed, $fail failed\n";
- print STDERR "==================================================\n";
-}
-
diff --git a/1.4/agi/jukebox.agi b/1.4/agi/jukebox.agi
deleted file mode 100755
index 7bd9c10f9..000000000
--- a/1.4/agi/jukebox.agi
+++ /dev/null
@@ -1,488 +0,0 @@
-#!/usr/bin/perl
-#
-# Jukebox 0.2
-#
-# A music manager for Asterisk.
-#
-# Copyright (C) 2005-2006, Justin Tunney
-#
-# Justin Tunney <jesuscyborg@gmail.com>
-#
-# This program is free software, distributed under the terms of the
-# GNU General Public License v2.
-#
-# Keep it open source pigs
-#
-# --------------------------------------------------------------------
-#
-# Uses festival to list off all your MP3 music files over a channel in
-# a hierarchical fashion. Put this file in your agi-bin folder which
-# is located at: /var/lib/asterisk/agi-bin Be sure to chmod +x it!
-#
-# Invocation Example:
-# exten => 68742,1,Answer()
-# exten => 68742,2,agi,jukebox.agi|/home/justin/Music
-# exten => 68742,3,Hangup()
-#
-# exten => 68742,1,Answer()
-# exten => 68742,2,agi,jukebox.agi|/home/justin/Music|pm
-# exten => 68742,3,Hangup()
-#
-# Options:
-# p - Precache text2wave outputs for every possible filename.
-# It is much better to set this option because if a caller
-# presses a key during a cache operation, it will be ignored.
-# m - Go back to menu after playing song
-# g - Do not play the greeting message
-#
-# Usage Instructions:
-# - Press '*' to go up a directory. If you are in the root music
-# folder you will be exitted from the script.
-# - If you have a really long list of files, you can filter the list
-# at any time by pressing '#' and spelling out a few letters you
-# expect the files to start with. For example, if you wanted to
-# know what extension 'Requiem For A Dream' was, you'd type:
-# '#737'. Note, phone keypads don't include Q and Z. Q is 7 and
-# Z is 9.
-#
-# Notes:
-# - This AGI script uses the MP3Player command which uses the
-# mpg123 Program. Grab yourself a copy of this program by
-# going to http://www.mpg123.de/cgi-bin/sitexplorer.cgi?/mpg123/
-# Be sure to download mpg123-0.59r.tar.gz because it is known to
-# work with Asterisk and hopefully isn't the release with that
-# awful security problem. If you're using Fedora Core 3 with
-# Alsa like me, make linux-alsa isn't going to work. Do make
-# linux-devel and you're peachy keen.
-#
-# - You won't get nifty STDERR debug messages if you're using a
-# remote asterisk shell.
-#
-# - For some reason, caching certain files will generate the
-# error: 'using default diphone ax-ax for y-pau'. Example:
-# # echo "Depeche Mode - CUW - 05 - The Meaning of Love" | text2wave -o /var/jukeboxcache/jukeboxcache/Depeche_Mode/Depeche_Mode_-_CUW_-_05_-_The_Meaning_of_Love.mp3.ul -otype ulaw -
-# The temporary work around is to just touch these files.
-#
-# - The background app doesn't like to get more than 2031 chars
-# of input.
-#
-
-use strict;
-
-$|=1;
-
-# Setup some variables
-my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-my @masterCacheList = ();
-my $maxNumber = 10;
-
-while (<STDIN>) {
- chomp;
- last unless length($_);
- if (/^agi_(\w+)\:\s+(.*)$/) {
- $AGI{$1} = $2;
- }
-}
-
-# setup options
-my $SHOWGREET = 1;
-my $PRECACHE = 0;
-my $MENUAFTERSONG = 0;
-
-$PRECACHE = 1 if $ARGV[1] =~ /p/;
-$MENUAFTERSONG = 1 if $ARGV[1] =~ /m/;
-$SHOWGREET = 0 if $ARGV[1] =~ /g/;
-
-# setup folders
-my $MUSIC = $ARGV[0];
-$MUSIC = &rmts($MUSIC);
-my $FESTIVALCACHE = "/var/jukeboxcache";
-if (! -e $FESTIVALCACHE) {
- `mkdir -p -m0776 $FESTIVALCACHE`;
-}
-
-# make sure we have some essential files
-if (! -e "$FESTIVALCACHE/jukebox_greet.ul") {
- `echo "Welcome to the Asterisk Jukebox" | text2wave -o $FESTIVALCACHE/jukebox_greet.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_press.ul") {
- `echo "Press" | text2wave -o $FESTIVALCACHE/jukebox_press.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_for.ul") {
- `echo "For" | text2wave -o $FESTIVALCACHE/jukebox_for.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_toplay.ul") {
- `echo "To play" | text2wave -o $FESTIVALCACHE/jukebox_toplay.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_nonefound.ul") {
- `echo "There were no music files found in this folder" | text2wave -o $FESTIVALCACHE/jukebox_nonefound.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_percent.ul") {
- `echo "Percent" | text2wave -o $FESTIVALCACHE/jukebox_percent.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_generate.ul") {
- `echo "Please wait while Astrisk Jukebox cashes the files of your music collection" | text2wave -o $FESTIVALCACHE/jukebox_generate.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_invalid.ul") {
- `echo "You have entered an invalid selection" | text2wave -o $FESTIVALCACHE/jukebox_invalid.ul -otype ulaw -`;
-}
-if (! -e "$FESTIVALCACHE/jukebox_thankyou.ul") {
- `echo "Thank you for using Astrisk Jukebox, Goodbye" | text2wave -o $FESTIVALCACHE/jukebox_thankyou.ul -otype ulaw -`;
-}
-
-# greet the user
-if ($SHOWGREET) {
- print "EXEC Playback \"$FESTIVALCACHE/jukebox_greet\"\n";
- my $result = <STDIN>; &check_result($result);
-}
-
-# go through the directories
-music_dir_cache() if $PRECACHE;
-music_dir_menu('/');
-
-exit 0;
-
-##########################################################################
-
-sub music_dir_menu {
- my $dir = shift;
-
-# generate a list of mp3's and directories and assign each one it's
-# own selection number. Then make sure that we've got a sound clip
-# for the file name
- if (!opendir(THEDIR, rmts($MUSIC.$dir))) {
- print STDERR "Failed to open music directory: $dir\n";
- exit 1;
- }
- my @files = sort readdir THEDIR;
- my $cnt = 1;
- my @masterBgList = ();
-
- foreach my $file (@files) {
- chomp($file);
- if ($file ne '.' && $file ne '..' && $file ne 'festivalcache') { # ignore special files
- my $real_version = &rmts($MUSIC.$dir).'/'.$file;
- my $cache_version = &rmts($FESTIVALCACHE.$dir).'/'.$file.'.ul';
- my $cache_version2 = &rmts($FESTIVALCACHE.$dir).'/'.$file;
- my $cache_version_esc = &clean_file($cache_version);
- my $cache_version2_esc = &clean_file($cache_version2);
-
- if (-d $real_version) {
-# 0:id 1:type 2:text2wav-file 3:for-filtering 4:the-directory 5:text2wav echo
- push(@masterBgList, [$cnt++, 1, $cache_version2_esc, &remove_special_chars($file), $file, "for the $file folder"]);
- } elsif ($real_version =~ /\.mp3$/) {
-# 0:id 1:type 2:text2wav-file 3:for-filtering 4:the-mp3
- push(@masterBgList, [$cnt++, 2, $cache_version2_esc, &remove_special_chars($file), $real_version, "to play $file"]);
- }
- }
- }
- close(THEDIR);
-
- my @filterList = @masterBgList;
-
- if (@filterList == 0) {
- print "EXEC Playback \"$FESTIVALCACHE/jukebox_nonefound\"\n";
- my $result = <STDIN>; &check_result($result);
- return 0;
- }
-
- for (;;) {
-MYCONTINUE:
-
-# play bg selections and figure out their selection
- my $digit = '';
- my $digitstr = '';
- for (my $n=0; $n<@filterList; $n++) {
- &cache_speech(&remove_file_extension($filterList[$n][5]), "$filterList[$n][2].ul") if ! -e "$filterList[$n][2].ul";
- &cache_speech("Press $filterList[$n][0]", "$FESTIVALCACHE/jukebox_$filterList[$n][0].ul") if ! -e "$FESTIVALCACHE/jukebox_$filterList[$n][0].ul";
- print "EXEC Background \"$filterList[$n][2]&$FESTIVALCACHE/jukebox_$filterList[$n][0]\"\n";
- my $result = <STDIN>;
- $digit = &check_result($result);
- if ($digit > 0) {
- $digitstr .= chr($digit);
- last;
- }
- }
- for (;;) {
- print "WAIT FOR DIGIT 3000\n";
- my $result = <STDIN>;
- $digit = &check_result($result);
- last if $digit <= 0;
- $digitstr .= chr($digit);
- }
-
-# see if it's a valid selection
- print STDERR "Digits Entered: '$digitstr'\n";
- exit 0 if $digitstr eq '';
- my $found = 0;
- goto EXITSUB if $digitstr =~ /\*/;
-
-# filter the list
- if ($digitstr =~ /^\#\d+/) {
- my $regexp = '';
- for (my $n=1; $n<length($digitstr); $n++) {
- my $d = substr($digitstr, $n, 1);
- if ($d == 2) {
- $regexp .= '[abc]';
- } elsif ($d == 3) {
- $regexp .= '[def]';
- } elsif ($d == 4) {
- $regexp .= '[ghi]';
- } elsif ($d == 5) {
- $regexp .= '[jkl]';
- } elsif ($d == 6) {
- $regexp .= '[mno]';
- } elsif ($d == 7) {
- $regexp .= '[pqrs]';
- } elsif ($d == 8) {
- $regexp .= '[tuv]';
- } elsif ($d == 9) {
- $regexp .= '[wxyz]';
- }
- }
- @filterList = ();
- for (my $n=1; $n<@masterBgList; $n++) {
- push(@filterList, $masterBgList[$n]) if $masterBgList[$n][3] =~ /^$regexp/i;
- }
- goto MYCONTINUE;
- }
-
- for (my $n=0; $n<@masterBgList; $n++) {
- if ($digitstr == $masterBgList[$n][0]) {
- if ($masterBgList[$n][1] == 1) { # a folder
- &music_dir_menu(rmts($dir).'/'.$masterBgList[$n][4]);
- @filterList = @masterBgList;
- goto MYCONTINUE;
- } elsif ($masterBgList[$n][1] == 2) { # a file
-# because *'s scripting language is crunk and won't allow us to escape
-# funny filenames, we need to create a temporary symlink to the mp3
-# file
- my $mp3 = &escape_file($masterBgList[$n][4]);
- my $link = `mktemp`;
- chomp($link);
- $link .= '.mp3';
- print STDERR "ln -s $mp3 $link\n";
- my $cmdr = `ln -s $mp3 $link`;
- chomp($cmdr);
- print "Failed to create symlink to mp3: $cmdr\n" if $cmdr ne '';
-
- print "EXEC MP3Player \"$link\"\n";
- my $result = <STDIN>; &check_result($result);
-
- `rm $link`;
-
- if (!$MENUAFTERSONG) {
- print "EXEC Playback \"$FESTIVALCACHE/jukebox_thankyou\"\n";
- my $result = <STDIN>; &check_result($result);
- exit 0;
- } else {
- goto MYCONTINUE;
- }
- }
- }
- }
- print "EXEC Playback \"$FESTIVALCACHE/jukebox_invalid\"\n";
- my $result = <STDIN>; &check_result($result);
- }
- EXITSUB:
-}
-
-sub cache_speech {
- my $speech = shift;
- my $file = shift;
-
- my $theDir = extract_file_dir($file);
- `mkdir -p -m0776 $theDir`;
-
- print STDERR "echo \"$speech\" | text2wave -o $file -otype ulaw -\n";
- my $cmdr = `echo "$speech" | text2wave -o $file -otype ulaw -`;
- chomp($cmdr);
- if ($cmdr =~ /using default diphone/) {
-# temporary bug work around....
- `touch $file`;
- } elsif ($cmdr ne '') {
- print STDERR "Command Failed\n";
- exit 1;
- }
-}
-
-sub music_dir_cache {
-# generate list of text2speech files to generate
- if (!music_dir_cache_genlist('/')) {
- print STDERR "Horrible Dreadful Error: No Music Found in $MUSIC!";
- exit 1;
- }
-
-# add to list how many 'number' files we have to generate. We can't
-# use the SayNumber app in Asterisk because we want to chain all
-# talking in one Background command. We also want a consistent
-# voice...
- for (my $n=1; $n<=$maxNumber; $n++) {
- push(@masterCacheList, [3, "Press $n", "$FESTIVALCACHE/jukebox_$n.ul"]) if ! -e "$FESTIVALCACHE/jukebox_$n.ul";
- }
-
-# now generate all these darn text2speech files
- if (@masterCacheList > 5) {
- print "EXEC Playback \"$FESTIVALCACHE/jukebox_generate\"\n";
- my $result = <STDIN>; &check_result($result);
- }
- my $theTime = time();
- for (my $n=0; $n < @masterCacheList; $n++) {
- my $cmdr = '';
- if ($masterCacheList[$n][0] == 1) { # directory
- &cache_speech("for folder $masterCacheList[$n][1]", $masterCacheList[$n][2]);
- } elsif ($masterCacheList[$n][0] == 2) { # file
- &cache_speech("to play $masterCacheList[$n][1]", $masterCacheList[$n][2]);
- } elsif ($masterCacheList[$n][0] == 3) { # number
- &cache_speech($masterCacheList[$n][1], $masterCacheList[$n][2]);
- }
- if (time() >= $theTime + 30) {
- my $percent = int($n / @masterCacheList * 100);
- print "SAY NUMBER $percent \"\"\n";
- my $result = <STDIN>; &check_result($result);
- print "EXEC Playback \"$FESTIVALCACHE/jukebox_percent\"\n";
- my $result = <STDIN>; &check_result($result);
- $theTime = time();
- }
- }
-}
-
-# this function will fill the @masterCacheList of all the files that
-# need to have text2speeced ulaw files of their names generated
-sub music_dir_cache_genlist {
- my $dir = shift;
- if (!opendir(THEDIR, rmts($MUSIC.$dir))) {
- print STDERR "Failed to open music directory: $dir\n";
- exit 1;
- }
- my @files = sort readdir THEDIR;
- my $foundFiles = 0;
- my $tmpMaxNum = 0;
- foreach my $file (@files) {
- chomp;
- if ($file ne '.' && $file ne '..' && $file ne 'festivalcache') { # ignore special files
- my $real_version = &rmts($MUSIC.$dir).'/'.$file;
- my $cache_version = &rmts($FESTIVALCACHE.$dir).'/'.$file.'.ul';
- my $cache_version2 = &rmts($FESTIVALCACHE.$dir).'/'.$file;
- my $cache_version_esc = &clean_file($cache_version);
- my $cache_version2_esc = &clean_file($cache_version2);
-
- if (-d $real_version) {
- if (music_dir_cache_genlist(rmts($dir).'/'.$file)) {
- $tmpMaxNum++;
- $maxNumber = $tmpMaxNum if $tmpMaxNum > $maxNumber;
- push(@masterCacheList, [1, $file, $cache_version_esc]) if ! -e $cache_version_esc;
- $foundFiles = 1;
- }
- } elsif ($real_version =~ /\.mp3$/) {
- $tmpMaxNum++;
- $maxNumber = $tmpMaxNum if $tmpMaxNum > $maxNumber;
- push(@masterCacheList, [2, &remove_file_extension($file), $cache_version_esc]) if ! -e $cache_version_esc;
- $foundFiles = 1;
- }
- }
- }
- close(THEDIR);
- return $foundFiles;
-}
-
-sub rmts { # remove trailing slash
- my $hog = shift;
- $hog =~ s/\/$//;
- return $hog;
-}
-
-sub extract_file_name {
- my $hog = shift;
- $hog =~ /\/?([^\/]+)$/;
- return $1;
-}
-
-sub extract_file_dir {
- my $hog = shift;
- return $hog if ! ($hog =~ /\//);
- $hog =~ /(.*)\/[^\/]*$/;
- return $1;
-}
-
-sub remove_file_extension {
- my $hog = shift;
- return $hog if ! ($hog =~ /\./);
- $hog =~ /(.*)\.[^.]*$/;
- return $1;
-}
-
-sub clean_file {
- my $hog = shift;
- $hog =~ s/\\/_/g;
- $hog =~ s/ /_/g;
- $hog =~ s/\t/_/g;
- $hog =~ s/\'/_/g;
- $hog =~ s/\"/_/g;
- $hog =~ s/\(/_/g;
- $hog =~ s/\)/_/g;
- $hog =~ s/&/_/g;
- $hog =~ s/\[/_/g;
- $hog =~ s/\]/_/g;
- $hog =~ s/\$/_/g;
- $hog =~ s/\|/_/g;
- $hog =~ s/\^/_/g;
- return $hog;
-}
-
-sub remove_special_chars {
- my $hog = shift;
- $hog =~ s/\\//g;
- $hog =~ s/ //g;
- $hog =~ s/\t//g;
- $hog =~ s/\'//g;
- $hog =~ s/\"//g;
- $hog =~ s/\(//g;
- $hog =~ s/\)//g;
- $hog =~ s/&//g;
- $hog =~ s/\[//g;
- $hog =~ s/\]//g;
- $hog =~ s/\$//g;
- $hog =~ s/\|//g;
- $hog =~ s/\^//g;
- return $hog;
-}
-
-sub escape_file {
- my $hog = shift;
- $hog =~ s/\\/\\\\/g;
- $hog =~ s/ /\\ /g;
- $hog =~ s/\t/\\\t/g;
- $hog =~ s/\'/\\\'/g;
- $hog =~ s/\"/\\\"/g;
- $hog =~ s/\(/\\\(/g;
- $hog =~ s/\)/\\\)/g;
- $hog =~ s/&/\\&/g;
- $hog =~ s/\[/\\\[/g;
- $hog =~ s/\]/\\\]/g;
- $hog =~ s/\$/\\\$/g;
- $hog =~ s/\|/\\\|/g;
- $hog =~ s/\^/\\\^/g;
- return $hog;
-}
-
-sub check_result {
- my ($res) = @_;
- my $retval;
- $tests++;
- chomp $res;
- if ($res =~ /^200/) {
- $res =~ /result=(-?\d+)/;
- if (!length($1)) {
- print STDERR "FAIL ($res)\n";
- $fail++;
- exit 1;
- } else {
- print STDERR "PASS ($1)\n";
- return $1;
- }
- } else {
- print STDERR "FAIL (unexpected result '$res')\n";
- exit 1;
- }
-}
diff --git a/1.4/agi/numeralize b/1.4/agi/numeralize
deleted file mode 100644
index 5ca51913d..000000000
--- a/1.4/agi/numeralize
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/perl
-#
-# Build a database linking filenames to their numerical representations
-# using a keypad for the DialAnMp3 application
-#
-
-$mp3dir="/usr/media/mpeg3";
-
-dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
-sub process_dir {
- my ($dir) = @_;
- my $file;
- my $digits;
- my @entries;
- opendir(DIR, $dir);
- @entries = readdir(DIR);
- closedir(DIR);
- foreach $_ (@entries) {
- if (!/^\./) {
- $file = "$dir/$_";
- if (-d "$file") {
- process_dir("$file");
- } else {
- $digits = $_;
- $digits =~ s/[^ \w]+//g;
- $digits =~ s/\_/ /g;
- $digits =~ tr/[a-z]/[A-Z]/;
- $digits =~ tr/[A-C]/2/;
- $digits =~ tr/[D-F]/3/;
- $digits =~ tr/[G-I]/4/;
- $digits =~ tr/[J-L]/5/;
- $digits =~ tr/[M-O]/6/;
- $digits =~ tr/[P-S]/7/;
- $digits =~ tr/[T-V]/8/;
- $digits =~ tr/[W-Z]/9/;
- $digits =~ s/\s+/ /;
- print "File: $file, digits: $digits\n";
- $DIGITS{$file} = $digits;
- }
- }
- }
-}
-
-process_dir($mp3dir);
diff --git a/1.4/apps/Makefile b/1.4/apps/Makefile
deleted file mode 100644
index 4006c9a5b..000000000
--- a/1.4/apps/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for PBX applications
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=APPS
-MENUSELECT_DESCRIPTION=Applications
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard app_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard app_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_APPS),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_APPS),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring apps,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-MENUSELECT_OPTS_app_directory:=$(MENUSELECT_OPTS_app_voicemail)
-ifneq ($(findstring ODBC_STORAGE,$(MENUSELECT_OPTS_app_voicemail)),)
-MENUSELECT_DEPENDS_app_voicemail+=$(MENUSELECT_DEPENDS_ODBC_STORAGE)
-MENUSELECT_DEPENDS_app_directory+=$(MENUSELECT_DEPENDS_ODBC_STORAGE)
-endif
-ifneq ($(findstring IMAP_STORAGE,$(MENUSELECT_OPTS_app_voicemail)),)
-MENUSELECT_DEPENDS_app_voicemail+=$(MENUSELECT_DEPENDS_IMAP_STORAGE)
-MENUSELECT_DEPENDS_app_directory+=$(MENUSELECT_DEPENDS_IMAP_STORAGE)
-endif
-
-ifeq (SunOS,$(shell uname))
-MENUSELECT_DEPENDS_app_chanspy+=RT
-RT_LIB=-lrt
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
diff --git a/1.4/apps/app_adsiprog.c b/1.4/apps/app_adsiprog.c
deleted file mode 100644
index 40330152b..000000000
--- a/1.4/apps/app_adsiprog.c
+++ /dev/null
@@ -1,1590 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Program Asterisk ADSI Scripts into phone
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>res_adsi</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/adsi.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-static char *app = "ADSIProg";
-
-static char *synopsis = "Load Asterisk ADSI Scripts into phone";
-
-/* #define DUMP_MESSAGES */
-
-static char *descrip =
-" ADSIProg(script): This application programs an ADSI Phone with the given\n"
-"script. If nothing is specified, the default script (asterisk.adsi) is used.\n";
-
-struct adsi_event {
- int id;
- char *name;
-};
-
-static struct adsi_event events[] = {
- { 1, "CALLERID" },
- { 2, "VMWI" },
- { 3, "NEARANSWER" },
- { 4, "FARANSWER" },
- { 5, "ENDOFRING" },
- { 6, "IDLE" },
- { 7, "OFFHOOK" },
- { 8, "CIDCW" },
- { 9, "BUSY" },
- { 10, "FARRING" },
- { 11, "DIALTONE" },
- { 12, "RECALL" },
- { 13, "MESSAGE" },
- { 14, "REORDER" },
- { 15, "DISTINCTIVERING" },
- { 16, "RING" },
- { 17, "REMINDERRING" },
- { 18, "SPECIALRING" },
- { 19, "CODEDRING" },
- { 20, "TIMER" },
- { 21, "INUSE" },
- { 22, "EVENT22" },
- { 23, "EVENT23" },
- { 24, "CPEID" },
-};
-
-static struct adsi_event justify[] = {
- { 0, "CENTER" },
- { 1, "RIGHT" },
- { 2, "LEFT" },
- { 3, "INDENT" },
-};
-
-#define STATE_NORMAL 0
-#define STATE_INKEY 1
-#define STATE_INSUB 2
-#define STATE_INIF 3
-
-#define MAX_RET_CODE 20
-#define MAX_SUB_LEN 255
-#define MAX_MAIN_LEN 1600
-
-#define ARG_STRING (1 << 0)
-#define ARG_NUMBER (1 << 1)
-
-struct adsi_soft_key {
- char vname[40]; /* Which "variable" is associated with it */
- int retstrlen; /* Length of return string */
- int initlen; /* initial length */
- int id;
- int defined;
- char retstr[80]; /* Return string data */
-};
-
-struct adsi_subscript {
- char vname[40];
- int id;
- int defined;
- int datalen;
- int inscount;
- int ifinscount;
- char *ifdata;
- char data[2048];
-};
-
-struct adsi_state {
- char vname[40];
- int id;
-};
-
-struct adsi_flag {
- char vname[40];
- int id;
-};
-
-struct adsi_display {
- char vname[40];
- int id;
- char data[70];
- int datalen;
-};
-
-struct adsi_script {
- int state;
- int numkeys;
- int numsubs;
- int numstates;
- int numdisplays;
- int numflags;
- struct adsi_soft_key *key;
- struct adsi_subscript *sub;
- /* Pre-defined displays */
- struct adsi_display displays[63];
- /* ADSI States 1 (initial) - 254 */
- struct adsi_state states[256];
- /* Keys 2-63 */
- struct adsi_soft_key keys[62];
- /* Subscripts 0 (main) to 127 */
- struct adsi_subscript subs[128];
- /* Flags 1-7 */
- struct adsi_flag flags[7];
-
- /* Stuff from adsi script */
- unsigned char sec[5];
- char desc[19];
- unsigned char fdn[5];
- int ver;
-};
-
-
-static int process_token(void *out, char *src, int maxlen, int argtype)
-{
- if ((strlen(src) > 1) && src[0] == '\"') {
- /* This is a quoted string */
- if (!(argtype & ARG_STRING))
- return -1;
- src++;
- /* Don't take more than what's there */
- if (maxlen > strlen(src) - 1)
- maxlen = strlen(src) - 1;
- memcpy(out, src, maxlen);
- ((char *)out)[maxlen] = '\0';
- } else if (!ast_strlen_zero(src) && (src[0] == '\\')) {
- if (!(argtype & ARG_NUMBER))
- return -1;
- /* Octal value */
- if (sscanf(src, "%o", (int *)out) != 1)
- return -1;
- if (argtype & ARG_STRING) {
- /* Convert */
- *((unsigned int *)out) = htonl(*((unsigned int *)out));
- }
- } else if ((strlen(src) > 2) && (src[0] == '0') && (tolower(src[1]) == 'x')) {
- if (!(argtype & ARG_NUMBER))
- return -1;
- /* Hex value */
- if (sscanf(src + 2, "%x", (unsigned int *)out) != 1)
- return -1;
- if (argtype & ARG_STRING) {
- /* Convert */
- *((unsigned int *)out) = htonl(*((unsigned int *)out));
- }
- } else if ((!ast_strlen_zero(src) && isdigit(src[0]))) {
- if (!(argtype & ARG_NUMBER))
- return -1;
- /* Hex value */
- if (sscanf(src, "%d", (int *)out) != 1)
- return -1;
- if (argtype & ARG_STRING) {
- /* Convert */
- *((unsigned int *)out) = htonl(*((unsigned int *)out));
- }
- } else
- return -1;
- return 0;
-}
-
-static char *get_token(char **buf, char *script, int lineno)
-{
- char *tmp = *buf;
- char *keyword;
- int quoted = 0;
- /* Advance past any white space */
- while(*tmp && (*tmp < 33))
- tmp++;
- if (!*tmp)
- return NULL;
- keyword = tmp;
- while(*tmp && ((*tmp > 32) || quoted)) {
- if (*tmp == '\"') {
- quoted = !quoted;
- }
- tmp++;
- }
- if (quoted) {
- ast_log(LOG_WARNING, "Mismatched quotes at line %d of %s\n", lineno, script);
- return NULL;
- }
- *tmp = '\0';
- tmp++;
- while(*tmp && (*tmp < 33))
- tmp++;
- /* Note where we left off */
- *buf = tmp;
- return keyword;
-}
-
-static char *validdtmf = "123456789*0#ABCD";
-
-static int send_dtmf(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char dtmfstr[80];
- char *a;
- int bytes=0;
- a = get_token(&args, script, lineno);
- if (!a) {
- ast_log(LOG_WARNING, "Expecting something to send for SENDDTMF at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(dtmfstr, a, sizeof(dtmfstr) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid token for SENDDTMF at line %d of %s\n", lineno, script);
- return 0;
- }
- a = dtmfstr;
- while(*a) {
- if (strchr(validdtmf, *a)) {
- *buf = *a;
- buf++;
- bytes++;
- } else
- ast_log(LOG_WARNING, "'%c' is not a valid DTMF tone at line %d of %s\n", *a, lineno, script);
- a++;
- }
- return bytes;
-}
-
-static int goto_line(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *page;
- char *gline;
- int line;
- unsigned char cmd;
- page = get_token(&args, script, lineno);
- gline = get_token(&args, script, lineno);
- if (!page || !gline) {
- ast_log(LOG_WARNING, "Expecting page and line number for GOTOLINE at line %d of %s\n", lineno, script);
- return 0;
- }
- if (!strcasecmp(page, "INFO")) {
- cmd = 0;
- } else if (!strcasecmp(page, "COMM")) {
- cmd = 0x80;
- } else {
- ast_log(LOG_WARNING, "Expecting either 'INFO' or 'COMM' page, got got '%s' at line %d of %s\n", page, lineno, script);
- return 0;
- }
- if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
- return 0;
- }
- cmd |= line;
- buf[0] = 0x8b;
- buf[1] = cmd;
- return 2;
-}
-
-static int goto_line_rel(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *dir;
- char *gline;
- int line;
- unsigned char cmd;
- dir = get_token(&args, script, lineno);
- gline = get_token(&args, script, lineno);
- if (!dir || !gline) {
- ast_log(LOG_WARNING, "Expecting direction and number of lines for GOTOLINEREL at line %d of %s\n", lineno, script);
- return 0;
- }
- if (!strcasecmp(dir, "UP")) {
- cmd = 0;
- } else if (!strcasecmp(dir, "DOWN")) {
- cmd = 0x20;
- } else {
- ast_log(LOG_WARNING, "Expecting either 'UP' or 'DOWN' direction, got '%s' at line %d of %s\n", dir, lineno, script);
- return 0;
- }
- if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
- return 0;
- }
- cmd |= line;
- buf[0] = 0x8c;
- buf[1] = cmd;
- return 2;
-}
-
-static int send_delay(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *gtime;
- int ms;
- gtime = get_token(&args, script, lineno);
- if (!gtime) {
- ast_log(LOG_WARNING, "Expecting number of milliseconds to wait at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(&ms, gtime, sizeof(ms), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid delay milliseconds '%s' at line %d of %s\n", gtime, lineno, script);
- return 0;
- }
- buf[0] = 0x90;
- if (id == 11)
- buf[1] = ms / 100;
- else
- buf[1] = ms / 10;
- return 2;
-}
-
-static int set_state(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *gstate;
- int state;
- gstate = get_token(&args, script, lineno);
- if (!gstate) {
- ast_log(LOG_WARNING, "Expecting state number at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(&state, gstate, sizeof(state), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid state number '%s' at line %d of %s\n", gstate, lineno, script);
- return 0;
- }
- buf[0] = id;
- buf[1] = state;
- return 2;
-}
-
-static int cleartimer(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *tok;
- tok = get_token(&args, script, lineno);
- if (tok)
- ast_log(LOG_WARNING, "Clearing timer requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
-
- buf[0] = id;
- /* For some reason the clear code is different slightly */
- if (id == 7)
- buf[1] = 0x10;
- else
- buf[1] = 0x00;
- return 2;
-}
-
-static struct adsi_flag *getflagbyname(struct adsi_script *state, char *name, char *script, int lineno, int create)
-{
- int x;
- for (x=0;x<state->numflags;x++)
- if (!strcasecmp(state->flags[x].vname, name))
- return &state->flags[x];
- /* Return now if we're not allowed to create */
- if (!create)
- return NULL;
- if (state->numflags > 6) {
- ast_log(LOG_WARNING, "No more flag space at line %d of %s\n", lineno, script);
- return NULL;
- }
- ast_copy_string(state->flags[state->numflags].vname, name, sizeof(state->flags[state->numflags].vname));
- state->flags[state->numflags].id = state->numflags + 1;
- state->numflags++;
- return &state->flags[state->numflags-1];
-}
-
-static int setflag(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *tok;
- char sname[80];
- struct adsi_flag *flag;
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Setting flag requires a flag number at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
- return 0;
- }
- flag = getflagbyname(state, sname, script, lineno, 0);
- if (!flag) {
- ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
- return 0;
- }
- buf[0] = id;
- buf[1] = ((flag->id & 0x7) << 4) | 1;
- return 2;
-}
-
-static int clearflag(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *tok;
- struct adsi_flag *flag;
- char sname[80];
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Clearing flag requires a flag number at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
- return 0;
- }
- flag = getflagbyname(state, sname, script, lineno, 0);
- if (!flag) {
- ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
- return 0;
- }
- buf[0] = id;
- buf[1] = ((flag->id & 0x7) << 4);
- return 2;
-}
-
-static int starttimer(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *tok;
- int secs;
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Missing number of seconds at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(&secs, tok, sizeof(secs), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
- return 0;
- }
- buf[0] = id;
- buf[1] = 0x1;
- buf[2] = secs;
- return 3;
-}
-
-static int geteventbyname(char *name)
-{
- int x;
- for (x=0;x<sizeof(events) / sizeof(events[0]); x++) {
- if (!strcasecmp(events[x].name, name))
- return events[x].id;
- }
- return 0;
-}
-
-static int getjustifybyname(char *name)
-{
- int x;
- for (x=0;x<sizeof(justify) / sizeof(justify[0]); x++) {
- if (!strcasecmp(justify[x].name, name))
- return justify[x].id;
- }
- return -1;
-}
-
-static struct adsi_soft_key *getkeybyname(struct adsi_script *state, char *name, char *script, int lineno)
-{
- int x;
- for (x=0;x<state->numkeys;x++)
- if (!strcasecmp(state->keys[x].vname, name))
- return &state->keys[x];
- if (state->numkeys > 61) {
- ast_log(LOG_WARNING, "No more key space at line %d of %s\n", lineno, script);
- return NULL;
- }
- ast_copy_string(state->keys[state->numkeys].vname, name, sizeof(state->keys[state->numkeys].vname));
- state->keys[state->numkeys].id = state->numkeys + 2;
- state->numkeys++;
- return &state->keys[state->numkeys-1];
-}
-
-static struct adsi_subscript *getsubbyname(struct adsi_script *state, char *name, char *script, int lineno)
-{
- int x;
- for (x=0;x<state->numsubs;x++)
- if (!strcasecmp(state->subs[x].vname, name))
- return &state->subs[x];
- if (state->numsubs > 127) {
- ast_log(LOG_WARNING, "No more subscript space at line %d of %s\n", lineno, script);
- return NULL;
- }
- ast_copy_string(state->subs[state->numsubs].vname, name, sizeof(state->subs[state->numsubs].vname));
- state->subs[state->numsubs].id = state->numsubs;
- state->numsubs++;
- return &state->subs[state->numsubs-1];
-}
-
-static struct adsi_state *getstatebyname(struct adsi_script *state, char *name, char *script, int lineno, int create)
-{
- int x;
- for (x=0;x<state->numstates;x++)
- if (!strcasecmp(state->states[x].vname, name))
- return &state->states[x];
- /* Return now if we're not allowed to create */
- if (!create)
- return NULL;
- if (state->numstates > 253) {
- ast_log(LOG_WARNING, "No more state space at line %d of %s\n", lineno, script);
- return NULL;
- }
- ast_copy_string(state->states[state->numstates].vname, name, sizeof(state->states[state->numstates].vname));
- state->states[state->numstates].id = state->numstates + 1;
- state->numstates++;
- return &state->states[state->numstates-1];
-}
-
-static struct adsi_display *getdisplaybyname(struct adsi_script *state, char *name, char *script, int lineno, int create)
-{
- int x;
- for (x=0;x<state->numdisplays;x++)
- if (!strcasecmp(state->displays[x].vname, name))
- return &state->displays[x];
- /* Return now if we're not allowed to create */
- if (!create)
- return NULL;
- if (state->numdisplays > 61) {
- ast_log(LOG_WARNING, "No more display space at line %d of %s\n", lineno, script);
- return NULL;
- }
- ast_copy_string(state->displays[state->numdisplays].vname, name, sizeof(state->displays[state->numdisplays].vname));
- state->displays[state->numdisplays].id = state->numdisplays + 1;
- state->numdisplays++;
- return &state->displays[state->numdisplays-1];
-}
-
-static int showkeys(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *tok;
- char newkey[80];
- int bytes;
- unsigned char keyid[6];
- int x;
- int flagid=0;
- struct adsi_soft_key *key;
- struct adsi_flag *flag;
-
- for (x=0;x<7;x++) {
- /* Up to 6 key arguments */
- tok = get_token(&args, script, lineno);
- if (!tok)
- break;
- if (!strcasecmp(tok, "UNLESS")) {
- /* Check for trailing UNLESS flag */
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
- } else if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid flag name '%s' at line %d of %s\n", tok, lineno, script);
- } else if (!(flag = getflagbyname(state, newkey, script, lineno, 0))) {
- ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", newkey, lineno, script);
- } else
- flagid = flag->id;
- if ((tok = get_token(&args, script, lineno)))
- ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
- break;
- }
- if (x > 5) {
- ast_log(LOG_WARNING, "Only 6 keys can be defined, ignoring '%s' at line %d of %s\n", tok, lineno, script);
- break;
- }
- if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid token for key name: %s\n", tok);
- continue;
- }
-
- key = getkeybyname(state, newkey, script, lineno);
- if (!key)
- break;
- keyid[x] = key->id;
- }
- buf[0] = id;
- buf[1] = (flagid & 0x7) << 3 | (x & 0x7);
- for (bytes=0;bytes<x;bytes++) {
- buf[bytes + 2] = keyid[bytes];
- }
- return 2 + x;
-}
-
-static int showdisplay(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *tok;
- char dispname[80];
- int line=0;
- int flag=0;
- int cmd = 3;
- struct adsi_display *disp;
-
- /* Get display */
- tok = get_token(&args, script, lineno);
- if (!tok || process_token(dispname, tok, sizeof(dispname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid display name: %s at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
- return 0;
- }
- disp = getdisplaybyname(state, dispname, script, lineno, 0);
- if (!disp) {
- ast_log(LOG_WARNING, "Display '%s' is undefined at line %d of %s\n", dispname, lineno, script);
- return 0;
- }
-
- tok = get_token(&args, script, lineno);
- if (!tok || strcasecmp(tok, "AT")) {
- ast_log(LOG_WARNING, "Missing token 'AT' at line %d of %s\n", lineno, script);
- return 0;
- }
- /* Get line number */
- tok = get_token(&args, script, lineno);
- if (!tok || process_token(&line, tok, sizeof(line), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid line: '%s' at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
- return 0;
- }
- tok = get_token(&args, script, lineno);
- if (tok && !strcasecmp(tok, "NOUPDATE")) {
- cmd = 1;
- tok = get_token(&args, script, lineno);
- }
- if (tok && !strcasecmp(tok, "UNLESS")) {
- /* Check for trailing UNLESS flag */
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
- } else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER)) {
- ast_log(LOG_WARNING, "Invalid flag number '%s' at line %d of %s\n", tok, lineno, script);
- }
- if ((tok = get_token(&args, script, lineno)))
- ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
- }
-
- buf[0] = id;
- buf[1] = (cmd << 6) | (disp->id & 0x3f);
- buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
- return 3;
-}
-
-static int cleardisplay(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *tok;
- tok = get_token(&args, script, lineno);
- if (tok)
- ast_log(LOG_WARNING, "Clearing display requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
-
- buf[0] = id;
- buf[1] = 0x00;
- return 2;
-}
-
-static int digitdirect(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *tok;
- tok = get_token(&args, script, lineno);
- if (tok)
- ast_log(LOG_WARNING, "Digitdirect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
-
- buf[0] = id;
- buf[1] = 0x7;
- return 2;
-}
-
-static int clearcbone(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *tok;
- tok = get_token(&args, script, lineno);
- if (tok)
- ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
-
- buf[0] = id;
- buf[1] = 0;
- return 2;
-}
-
-static int digitcollect(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
-{
- char *tok;
- tok = get_token(&args, script, lineno);
- if (tok)
- ast_log(LOG_WARNING, "Digitcollect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
-
- buf[0] = id;
- buf[1] = 0xf;
- return 2;
-}
-
-static int subscript(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *tok;
- char subscript[80];
- struct adsi_subscript *sub;
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(subscript, tok, sizeof(subscript) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
- return 0;
- }
- sub = getsubbyname(state, subscript, script, lineno);
- if (!sub)
- return 0;
- buf[0] = 0x9d;
- buf[1] = sub->id;
- return 2;
-}
-
-static int onevent(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
-{
- char *tok;
- char subscript[80];
- char sname[80];
- int sawin=0;
- int event;
- int snums[8];
- int scnt = 0;
- int x;
- struct adsi_subscript *sub;
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Missing event for 'ONEVENT' at line %d of %s\n", lineno, script);
- return 0;
- }
- event = geteventbyname(tok);
- if (event < 1) {
- ast_log(LOG_WARNING, "'%s' is not a valid event name, at line %d of %s\n", args, lineno, script);
- return 0;
- }
- tok = get_token(&args, script, lineno);
- while ((!sawin && !strcasecmp(tok, "IN")) ||
- (sawin && !strcasecmp(tok, "OR"))) {
- sawin = 1;
- if (scnt > 7) {
- ast_log(LOG_WARNING, "No more than 8 states may be specified for inclusion at line %d of %s\n", lineno, script);
- return 0;
- }
- /* Process 'in' things */
- tok = get_token(&args, script, lineno);
- if (process_token(sname, tok, sizeof(sname), ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid state name at line %d of %s\n", tok, lineno, script);
- return 0;
- }
- if ((snums[scnt] = getstatebyname(state, sname, script, lineno, 0) < 0)) {
- ast_log(LOG_WARNING, "State '%s' not declared at line %d of %s\n", sname, lineno, script);
- return 0;
- }
- scnt++;
- tok = get_token(&args, script, lineno);
- if (!tok)
- break;
- }
- if (!tok || strcasecmp(tok, "GOTO")) {
- if (!tok)
- tok = "<nothing>";
- if (sawin)
- ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'OR' at line %d of %s\n", tok, lineno, script);
- else
- ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'IN' at line %d of %s\n", tok, lineno, script);
- }
- tok = get_token(&args, script, lineno);
- if (!tok) {
- ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
- return 0;
- }
- if (process_token(subscript, tok, sizeof(subscript) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Invalid subscript '%s' at line %d of %s\n", tok, lineno, script);
- return 0;
- }
- sub = getsubbyname(state, subscript, script, lineno);
- if (!sub)
- return 0;
- buf[0] = 8;
- buf[1] = event;
- buf[2] = sub->id | 0x80;
- for (x=0;x<scnt;x++)
- buf[3 + x] = snums[x];
- return 3 + scnt;
-}
-
-struct adsi_key_cmd {
- char *name;
- int id;
- int (*add_args)(char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno);
-};
-
-static struct adsi_key_cmd kcmds[] = {
- { "SENDDTMF", 0, send_dtmf },
- /* Encoded DTMF would go here */
- { "ONHOOK", 0x81 },
- { "OFFHOOK", 0x82 },
- { "FLASH", 0x83 },
- { "WAITDIALTONE", 0x84 },
- /* Send line number */
- { "BLANK", 0x86 },
- { "SENDCHARS", 0x87 },
- { "CLEARCHARS", 0x88 },
- { "BACKSPACE", 0x89 },
- /* Tab column */
- { "GOTOLINE", 0x8b, goto_line },
- { "GOTOLINEREL", 0x8c, goto_line_rel },
- { "PAGEUP", 0x8d },
- { "PAGEDOWN", 0x8e },
- /* Extended DTMF */
- { "DELAY", 0x90, send_delay },
- { "DIALPULSEONE", 0x91 },
- { "DATAMODE", 0x92 },
- { "VOICEMODE", 0x93 },
- /* Display call buffer 'n' */
- /* Clear call buffer 'n' */
- { "CLEARCB1", 0x95, clearcbone },
- { "DIGITCOLLECT", 0x96, digitcollect },
- { "DIGITDIRECT", 0x96, digitdirect },
- { "CLEAR", 0x97 },
- { "SHOWDISPLAY", 0x98, showdisplay },
- { "CLEARDISPLAY", 0x98, cleardisplay },
- { "SHOWKEYS", 0x99, showkeys },
- { "SETSTATE", 0x9a, set_state },
- { "TIMERSTART", 0x9b, starttimer },
- { "TIMERCLEAR", 0x9b, cleartimer },
- { "SETFLAG", 0x9c, setflag },
- { "CLEARFLAG", 0x9c, clearflag },
- { "GOTO", 0x9d, subscript },
- { "EVENT22", 0x9e },
- { "EVENT23", 0x9f },
- { "EXIT", 0xa0 },
-};
-
-static struct adsi_key_cmd opcmds[] = {
-
- /* 1 - Branch on event -- handled specially */
- { "SHOWKEYS", 2, showkeys },
- /* Display Control */
- { "SHOWDISPLAY", 3, showdisplay },
- { "CLEARDISPLAY", 3, cleardisplay },
- { "CLEAR", 5 },
- { "SETSTATE", 6, set_state },
- { "TIMERSTART", 7, starttimer },
- { "TIMERCLEAR", 7, cleartimer },
- { "ONEVENT", 8, onevent },
- /* 9 - Subroutine label, treated specially */
- { "SETFLAG", 10, setflag },
- { "CLEARFLAG", 10, clearflag },
- { "DELAY", 11, send_delay },
- { "EXIT", 12 },
-};
-
-
-static int process_returncode(struct adsi_soft_key *key, char *code, char *args, struct adsi_script *state, char *script, int lineno)
-{
- int x;
- char *unused;
- int res;
- for (x=0;x<sizeof(kcmds) / sizeof(kcmds[0]);x++) {
- if ((kcmds[x].id > -1) && !strcasecmp(kcmds[x].name, code)) {
- if (kcmds[x].add_args) {
- res = kcmds[x].add_args(key->retstr + key->retstrlen,
- code, kcmds[x].id, args, state, script, lineno);
- if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE)
- key->retstrlen += res;
- else
- ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", kcmds[x].name, key->vname, lineno, script);
- } else {
- if ((unused = get_token(&args, script, lineno)))
- ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", kcmds[x].name, lineno, script, unused);
- if ((key->retstrlen + 1 - key->initlen) <= MAX_RET_CODE) {
- key->retstr[key->retstrlen] = kcmds[x].id;
- key->retstrlen++;
- } else
- ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", kcmds[x].name, key->vname, lineno, script);
- }
- return 0;
- }
- }
- return -1;
-}
-
-static int process_opcode(struct adsi_subscript *sub, char *code, char *args, struct adsi_script *state, char *script, int lineno)
-{
- int x;
- char *unused;
- int res;
- int max = sub->id ? MAX_SUB_LEN : MAX_MAIN_LEN;
- for (x=0;x<sizeof(opcmds) / sizeof(opcmds[0]);x++) {
- if ((opcmds[x].id > -1) && !strcasecmp(opcmds[x].name, code)) {
- if (opcmds[x].add_args) {
- res = opcmds[x].add_args(sub->data + sub->datalen,
- code, opcmds[x].id, args, state, script, lineno);
- if ((sub->datalen + res + 1) <= max)
- sub->datalen += res;
- else {
- ast_log(LOG_WARNING, "No space for '%s' code in subscript '%s' at line %d of %s\n", opcmds[x].name, sub->vname, lineno, script);
- return -1;
- }
- } else {
- if ((unused = get_token(&args, script, lineno)))
- ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", opcmds[x].name, lineno, script, unused);
- if ((sub->datalen + 2) <= max) {
- sub->data[sub->datalen] = opcmds[x].id;
- sub->datalen++;
- } else {
- ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", opcmds[x].name, sub->vname, lineno, script);
- return -1;
- }
- }
- /* Separate commands with 0xff */
- sub->data[sub->datalen] = 0xff;
- sub->datalen++;
- sub->inscount++;
- return 0;
- }
- }
- return -1;
-}
-
-static int adsi_process(struct adsi_script *state, char *buf, char *script, int lineno)
-{
- char *keyword;
- char *args;
- char vname[256];
- char tmp[80];
- char tmp2[80];
- int lrci;
- int wi;
- int event;
- struct adsi_display *disp;
- struct adsi_subscript *newsub;
- /* Find the first keyword */
- keyword = get_token(&buf, script, lineno);
- if (!keyword)
- return 0;
- switch(state->state) {
- case STATE_NORMAL:
- if (!strcasecmp(keyword, "DESCRIPTION")) {
- args = get_token(&buf, script, lineno);
- if (args) {
- if (process_token(state->desc, args, sizeof(state->desc) - 1, ARG_STRING))
- ast_log(LOG_WARNING, "'%s' is not a valid token for DESCRIPTION at line %d of %s\n", args, lineno, script);
- } else
- ast_log(LOG_WARNING, "Missing argument for DESCRIPTION at line %d of %s\n", lineno, script);
- } else if (!strcasecmp(keyword, "VERSION")) {
- args = get_token(&buf, script, lineno);
- if (args) {
- if (process_token(&state->ver, args, sizeof(state->ver) - 1, ARG_NUMBER))
- ast_log(LOG_WARNING, "'%s' is not a valid token for VERSION at line %d of %s\n", args, lineno, script);
- } else
- ast_log(LOG_WARNING, "Missing argument for VERSION at line %d of %s\n", lineno, script);
- } else if (!strcasecmp(keyword, "SECURITY")) {
- args = get_token(&buf, script, lineno);
- if (args) {
- if (process_token(state->sec, args, sizeof(state->sec) - 1, ARG_STRING | ARG_NUMBER))
- ast_log(LOG_WARNING, "'%s' is not a valid token for SECURITY at line %d of %s\n", args, lineno, script);
- } else
- ast_log(LOG_WARNING, "Missing argument for SECURITY at line %d of %s\n", lineno, script);
- } else if (!strcasecmp(keyword, "FDN")) {
- args = get_token(&buf, script, lineno);
- if (args) {
- if (process_token(state->fdn, args, sizeof(state->fdn) - 1, ARG_STRING | ARG_NUMBER))
- ast_log(LOG_WARNING, "'%s' is not a valid token for FDN at line %d of %s\n", args, lineno, script);
- } else
- ast_log(LOG_WARNING, "Missing argument for FDN at line %d of %s\n", lineno, script);
- } else if (!strcasecmp(keyword, "KEY")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "KEY definition missing name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
- break;
- }
- state->key = getkeybyname(state, vname, script, lineno);
- if (!state->key) {
- ast_log(LOG_WARNING, "Out of key space at line %d of %s\n", lineno, script);
- break;
- }
- if (state->key->defined) {
- ast_log(LOG_WARNING, "Cannot redefine key '%s' at line %d of %s\n", vname, lineno, script);
- break;
- }
- args = get_token(&buf, script, lineno);
- if (!args || strcasecmp(args, "IS")) {
- ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script);
- break;
- }
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "KEY definition missing short name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY short name at line %d of %s\n", args, lineno, script);
- break;
- }
- args = get_token(&buf, script, lineno);
- if (args) {
- if (strcasecmp(args, "OR")) {
- ast_log(LOG_WARNING, "Expecting 'OR' but got '%s' instead at line %d of %s\n", args, lineno, script);
- break;
- }
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "KEY definition missing optional long name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(tmp2, args, sizeof(tmp2) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY long name at line %d of %s\n", args, lineno, script);
- break;
- }
- } else {
- ast_copy_string(tmp2, tmp, sizeof(tmp2));
- }
- if (strlen(tmp2) > 18) {
- ast_log(LOG_WARNING, "Truncating full name to 18 characters at line %d of %s\n", lineno, script);
- tmp2[18] = '\0';
- }
- if (strlen(tmp) > 7) {
- ast_log(LOG_WARNING, "Truncating short name to 7 bytes at line %d of %s\n", lineno, script);
- tmp[7] = '\0';
- }
- /* Setup initial stuff */
- state->key->retstr[0] = 128;
- /* 1 has the length */
- state->key->retstr[2] = state->key->id;
- /* Put the Full name in */
- memcpy(state->key->retstr + 3, tmp2, strlen(tmp2));
- /* Update length */
- state->key->retstrlen = strlen(tmp2) + 3;
- /* Put trailing 0xff */
- state->key->retstr[state->key->retstrlen++] = 0xff;
- /* Put the short name */
- memcpy(state->key->retstr + state->key->retstrlen, tmp, strlen(tmp));
- /* Update length */
- state->key->retstrlen += strlen(tmp);
- /* Put trailing 0xff */
- state->key->retstr[state->key->retstrlen++] = 0xff;
- /* Record initial length */
- state->key->initlen = state->key->retstrlen;
- state->state = STATE_INKEY;
- } else if (!strcasecmp(keyword, "SUB")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
- break;
- }
- state->sub = getsubbyname(state, vname, script, lineno);
- if (!state->sub) {
- ast_log(LOG_WARNING, "Out of subroutine space at line %d of %s\n", lineno, script);
- break;
- }
- if (state->sub->defined) {
- ast_log(LOG_WARNING, "Cannot redefine subroutine '%s' at line %d of %s\n", vname, lineno, script);
- break;
- }
- /* Setup sub */
- state->sub->data[0] = 130;
- /* 1 is the length */
- state->sub->data[2] = 0x0; /* Clear extensibility bit */
- state->sub->datalen = 3;
- if (state->sub->id) {
- /* If this isn't the main subroutine, make a subroutine label for it */
- state->sub->data[3] = 9;
- state->sub->data[4] = state->sub->id;
- /* 5 is length */
- state->sub->data[6] = 0xff;
- state->sub->datalen = 7;
- }
- args = get_token(&buf, script, lineno);
- if (!args || strcasecmp(args, "IS")) {
- ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script);
- break;
- }
- state->state = STATE_INSUB;
- } else if (!strcasecmp(keyword, "STATE")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "STATE definition missing name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a STATE name at line %d of %s\n", args, lineno, script);
- break;
- }
- if (getstatebyname(state, vname, script, lineno, 0)) {
- ast_log(LOG_WARNING, "State '%s' is already defined at line %d of %s\n", vname, lineno, script);
- break;
- }
- getstatebyname(state, vname, script, lineno, 1);
- } else if (!strcasecmp(keyword, "FLAG")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "FLAG definition missing name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a FLAG name at line %d of %s\n", args, lineno, script);
- break;
- }
- if (getflagbyname(state, vname, script, lineno, 0)) {
- ast_log(LOG_WARNING, "Flag '%s' is already defined\n", vname);
- break;
- }
- getflagbyname(state, vname, script, lineno, 1);
- } else if (!strcasecmp(keyword, "DISPLAY")) {
- lrci = 0;
- wi = 0;
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
- break;
- }
- if (getdisplaybyname(state, vname, script, lineno, 0)) {
- ast_log(LOG_WARNING, "State '%s' is already defined\n", vname);
- break;
- }
- disp = getdisplaybyname(state, vname, script, lineno, 1);
- if (!disp)
- break;
- args = get_token(&buf, script, lineno);
- if (!args || strcasecmp(args, "IS")) {
- ast_log(LOG_WARNING, "Missing 'IS' at line %d of %s\n", lineno, script);
- break;
- }
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "Missing Column 1 text at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "Token '%s' is not valid column 1 text at line %d of %s\n", args, lineno, script);
- break;
- }
- if (strlen(tmp) > 20) {
- ast_log(LOG_WARNING, "Truncating column one to 20 characters at line %d of %s\n", lineno, script);
- tmp[20] = '\0';
- }
- memcpy(disp->data + 5, tmp, strlen(tmp));
- disp->datalen = strlen(tmp) + 5;
- disp->data[disp->datalen++] = 0xff;
-
- args = get_token(&buf, script, lineno);
- if (args && !process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
- /* Got a column two */
- if (strlen(tmp) > 20) {
- ast_log(LOG_WARNING, "Truncating column two to 20 characters at line %d of %s\n", lineno, script);
- tmp[20] = '\0';
- }
- memcpy(disp->data + disp->datalen, tmp, strlen(tmp));
- disp->datalen += strlen(tmp);
- args = get_token(&buf, script, lineno);
- }
- while(args) {
- if (!strcasecmp(args, "JUSTIFY")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "Qualifier 'JUSTIFY' requires an argument at line %d of %s\n", lineno, script);
- break;
- }
- lrci = getjustifybyname(args);
- if (lrci < 0) {
- ast_log(LOG_WARNING, "'%s' is not a valid justification at line %d of %s\n", args, lineno, script);
- break;
- }
- } else if (!strcasecmp(args, "WRAP")) {
- wi = 0x80;
- } else {
- ast_log(LOG_WARNING, "'%s' is not a known qualifier at line %d of %s\n", args, lineno, script);
- break;
- }
- args = get_token(&buf, script, lineno);
- }
- if (args) {
- /* Something bad happened */
- break;
- }
- disp->data[0] = 129;
- disp->data[1] = disp->datalen - 2;
- disp->data[2] = ((lrci & 0x3) << 6) | disp->id;
- disp->data[3] = wi;
- disp->data[4] = 0xff;
- } else {
- ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in PROGRAM\n", keyword);
- }
- break;
- case STATE_INKEY:
- if (process_returncode(state->key, keyword, buf, state, script, lineno)) {
- if (!strcasecmp(keyword, "ENDKEY")) {
- /* Return to normal operation and increment current key */
- state->state = STATE_NORMAL;
- state->key->defined = 1;
- state->key->retstr[1] = state->key->retstrlen - 2;
- state->key = NULL;
- } else {
- ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SOFTKEY definition at line %d of %s\n", keyword, lineno, script);
- }
- }
- break;
- case STATE_INIF:
- if (process_opcode(state->sub, keyword, buf, state, script, lineno)) {
- if (!strcasecmp(keyword, "ENDIF")) {
- /* Return to normal SUB operation and increment current key */
- state->state = STATE_INSUB;
- state->sub->defined = 1;
- /* Store the proper number of instructions */
- state->sub->ifdata[2] = state->sub->ifinscount;
- } else if (!strcasecmp(keyword, "GOTO")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "GOTO clause missing Subscript name at line %d of %s\n", lineno, script);
- break;
- }
- if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
- ast_log(LOG_WARNING, "'%s' is not a valid subscript name token at line %d of %s\n", args, lineno, script);
- break;
- }
- newsub = getsubbyname(state, tmp, script, lineno);
- if (!newsub)
- break;
- /* Somehow you use GOTO to go to another place */
- state->sub->data[state->sub->datalen++] = 0x8;
- state->sub->data[state->sub->datalen++] = state->sub->ifdata[1];
- state->sub->data[state->sub->datalen++] = newsub->id;
- /* Terminate */
- state->sub->data[state->sub->datalen++] = 0xff;
- /* Increment counters */
- state->sub->inscount++;
- state->sub->ifinscount++;
- } else {
- ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in IF clause at line %d of %s\n", keyword, lineno, script);
- }
- } else
- state->sub->ifinscount++;
- break;
- case STATE_INSUB:
- if (process_opcode(state->sub, keyword, buf, state, script, lineno)) {
- if (!strcasecmp(keyword, "ENDSUB")) {
- /* Return to normal operation and increment current key */
- state->state = STATE_NORMAL;
- state->sub->defined = 1;
- /* Store the proper length */
- state->sub->data[1] = state->sub->datalen - 2;
- if (state->sub->id) {
- /* if this isn't main, store number of instructions, too */
- state->sub->data[5] = state->sub->inscount;
- }
- state->sub = NULL;
- } else if (!strcasecmp(keyword, "IFEVENT")) {
- args = get_token(&buf, script, lineno);
- if (!args) {
- ast_log(LOG_WARNING, "IFEVENT clause missing Event name at line %d of %s\n", lineno, script);
- break;
- }
- event = geteventbyname(args);
- if (event < 1) {
- ast_log(LOG_WARNING, "'%s' is not a valid event\n", args);
- break;
- }
- args = get_token(&buf, script, lineno);
- if (!args || strcasecmp(args, "THEN")) {
- ast_log(LOG_WARNING, "IFEVENT clause missing 'THEN' at line %d of %s\n", lineno, script);
- break;
- }
- state->sub->ifinscount = 0;
- state->sub->ifdata = state->sub->data +
- state->sub->datalen;
- /* Reserve header and insert op codes */
- state->sub->ifdata[0] = 0x1;
- state->sub->ifdata[1] = event;
- /* 2 is for the number of instructions */
- state->sub->ifdata[3] = 0xff;
- state->sub->datalen += 4;
- /* Update Subscript instruction count */
- state->sub->inscount++;
- state->state = STATE_INIF;
- } else {
- ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SUB definition at line %d of %s\n", keyword, lineno, script);
- }
- }
- break;
- default:
- ast_log(LOG_WARNING, "Can't process keyword '%s' in weird state %d\n", keyword, state->state);
- }
- return 0;
-}
-
-static struct adsi_script *compile_script(char *script)
-{
- FILE *f;
- char fn[256];
- char buf[256];
- char *c;
- int lineno=0;
- int x, err;
- struct adsi_script *scr;
- if (script[0] == '/')
- ast_copy_string(fn, script, sizeof(fn));
- else
- snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, script);
- f = fopen(fn, "r");
- if (!f) {
- ast_log(LOG_WARNING, "Can't open file '%s'\n", fn);
- return NULL;
- }
- if (!(scr = ast_calloc(1, sizeof(*scr)))) {
- fclose(f);
- return NULL;
- }
- /* Create "main" as first subroutine */
- getsubbyname(scr, "main", NULL, 0);
- while(!feof(f)) {
- fgets(buf, sizeof(buf), f);
- if (!feof(f)) {
- lineno++;
- /* Trim off trailing return */
- buf[strlen(buf) - 1] = '\0';
- c = strchr(buf, ';');
- /* Strip comments */
- if (c)
- *c = '\0';
- if (!ast_strlen_zero(buf))
- adsi_process(scr, buf, script, lineno);
- }
- }
- fclose(f);
- /* Make sure we're in the main routine again */
- switch(scr->state) {
- case STATE_NORMAL:
- break;
- case STATE_INSUB:
- ast_log(LOG_WARNING, "Missing ENDSUB at end of file %s\n", script);
- free(scr);
- return NULL;
- case STATE_INKEY:
- ast_log(LOG_WARNING, "Missing ENDKEY at end of file %s\n", script);
- free(scr);
- return NULL;
- }
- err = 0;
-
- /* Resolve all keys and record their lengths */
- for (x=0;x<scr->numkeys;x++) {
- if (!scr->keys[x].defined) {
- ast_log(LOG_WARNING, "Key '%s' referenced but never defined in file %s\n", scr->keys[x].vname, fn);
- err++;
- }
- }
-
- /* Resolve all subs */
- for (x=0;x<scr->numsubs;x++) {
- if (!scr->subs[x].defined) {
- ast_log(LOG_WARNING, "Subscript '%s' referenced but never defined in file %s\n", scr->subs[x].vname, fn);
- err++;
- }
- if (x == (scr->numsubs - 1)) {
- /* Clear out extension bit on last message */
- scr->subs[x].data[2] = 0x80;
- }
- }
-
- if (err) {
- free(scr);
- return NULL;
- }
- return scr;
-}
-
-#ifdef DUMP_MESSAGES
-static void dump_message(char *type, char *vname, unsigned char *buf, int buflen)
-{
- int x;
- printf("%s %s: [ ", type, vname);
- for (x=0;x<buflen;x++)
- printf("%02x ", buf[x]);
- printf("]\n");
-}
-#endif
-
-static int adsi_prog(struct ast_channel *chan, char *script)
-{
- struct adsi_script *scr;
- int x;
- unsigned char buf[1024];
- int bytes;
- scr = compile_script(script);
- if (!scr)
- return -1;
-
- /* Start an empty ADSI Session */
- if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
- return -1;
-
- /* Now begin the download attempt */
- if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
- /* User rejected us for some reason */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User rejected download attempt\n");
- ast_log(LOG_NOTICE, "User rejected download on channel %s\n", chan->name);
- free(scr);
- return -1;
- }
-
- bytes = 0;
- /* Start with key definitions */
- for (x=0;x<scr->numkeys;x++) {
- if (bytes + scr->keys[x].retstrlen > 253) {
- /* Send what we've collected so far */
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
- ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
- return -1;
- }
- bytes =0;
- }
- memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
- bytes += scr->keys[x].retstrlen;
-#ifdef DUMP_MESSAGES
- dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
-#endif
- }
- if (bytes) {
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
- ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
- return -1;
- }
- }
-
- bytes = 0;
- /* Continue with the display messages */
- for (x=0;x<scr->numdisplays;x++) {
- if (bytes + scr->displays[x].datalen > 253) {
- /* Send what we've collected so far */
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
- ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
- return -1;
- }
- bytes =0;
- }
- memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
- bytes += scr->displays[x].datalen;
-#ifdef DUMP_MESSAGES
- dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
-#endif
- }
- if (bytes) {
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
- ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
- return -1;
- }
- }
-
- bytes = 0;
- /* Send subroutines */
- for (x=0;x<scr->numsubs;x++) {
- if (bytes + scr->subs[x].datalen > 253) {
- /* Send what we've collected so far */
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
- ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
- return -1;
- }
- bytes =0;
- }
- memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen);
- bytes += scr->subs[x].datalen;
-#ifdef DUMP_MESSAGES
- dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen);
-#endif
- }
- if (bytes) {
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
- ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
- return -1;
- }
- }
-
-
- bytes = 0;
- bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
- bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1);
- if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0)
- return -1;
- if (ast_adsi_end_download(chan)) {
- /* Download failed for some reason */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Download attempt failed\n");
- ast_log(LOG_NOTICE, "Download failed on %s\n", chan->name);
- free(scr);
- return -1;
- }
- free(scr);
- ast_adsi_unload_session(chan);
- return 0;
-}
-
-static int adsi_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- if (ast_strlen_zero(data))
- data = "asterisk.adsi";
-
- if (!ast_adsi_available(chan)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "ADSI Unavailable on CPE. Not bothering to try.\n");
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "ADSI Available on CPE. Attempting Upload.\n");
- res = adsi_prog(chan, data);
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- ast_module_user_hangup_all();
-
- res = ast_unregister_application(app);
-
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, adsi_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Asterisk ADSI Programming Application");
diff --git a/1.4/apps/app_alarmreceiver.c b/1.4/apps/app_alarmreceiver.c
deleted file mode 100644
index 8afce25d5..000000000
--- a/1.4/apps/app_alarmreceiver.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005 Steve Rodgers
- *
- * Steve Rodgers <hwstar@rodgers.sdcoxmail.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.
- */
-
-/*! \file
- * \brief Central Station Alarm receiver for Ademco Contact ID
- * \author Steve Rodgers <hwstar@rodgers.sdcoxmail.com>
- *
- * *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
- *
- * Use at your own risk. Please consult the GNU GPL license document included with Asterisk. *
- *
- * *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/config.h"
-#include "asterisk/localtime.h"
-#include "asterisk/callerid.h"
-#include "asterisk/astdb.h"
-#include "asterisk/utils.h"
-
-#define ALMRCV_CONFIG "alarmreceiver.conf"
-#define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID"
-
-struct event_node{
- char data[17];
- struct event_node *next;
-};
-
-typedef struct event_node event_node_t;
-
-static char *app = "AlarmReceiver";
-
-static char *synopsis = "Provide support for receiving alarm reports from a burglar or fire alarm panel";
-static char *descrip =
-" AlarmReceiver(): Only 1 signalling format is supported at this time: Ademco\n"
-"Contact ID. This application should be called whenever there is an alarm\n"
-"panel calling in to dump its events. The application will handshake with the\n"
-"alarm panel, and receive events, validate them, handshake them, and store them\n"
-"until the panel hangs up. Once the panel hangs up, the application will run the\n"
-"system command specified by the eventcmd setting in alarmreceiver.conf and pipe\n"
-"the events to the standard input of the application. The configuration file also\n"
-"contains settings for DTMF timing, and for the loudness of the acknowledgement\n"
-"tones.\n";
-
-/* Config Variables */
-
-static int fdtimeout = 2000;
-static int sdtimeout = 200;
-static int toneloudness = 4096;
-static int log_individual_events = 0;
-static char event_spool_dir[128] = {'\0'};
-static char event_app[128] = {'\0'};
-static char db_family[128] = {'\0'};
-static char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"};
-
-/* Misc variables */
-
-static char event_file[14] = "/event-XXXXXX";
-
-/*
-* Attempt to access a database variable and increment it,
-* provided that the user defined db-family in alarmreceiver.conf
-* The alarmreceiver app will write statistics to a few variables
-* in this family if it is defined. If the new key doesn't exist in the
-* family, then create it and set its value to 1.
-*/
-
-static void database_increment( char *key )
-{
- int res = 0;
- unsigned v;
- char value[16];
-
-
- if (ast_strlen_zero(db_family))
- return; /* If not defined, don't do anything */
-
- res = ast_db_get(db_family, key, value, sizeof(value) - 1);
-
- if(res){
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
- /* Guess we have to create it */
- res = ast_db_put(db_family, key, "1");
- return;
- }
-
- sscanf(value, "%u", &v);
- v++;
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: New value for %s: %u\n", key, v);
-
- snprintf(value, sizeof(value), "%u", v);
-
- res = ast_db_put(db_family, key, value);
-
- if((res)&&(option_verbose >= 4))
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: database_increment write error\n");
-
- return;
-}
-
-
-/*
-* Build a MuLaw data block for a single frequency tone
-*/
-
-static void make_tone_burst(unsigned char *data, float freq, float loudness, int len, int *x)
-{
- int i;
- float val;
-
- for(i = 0; i < len; i++){
- val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0);
- data[i] = AST_LIN2MU((int)val);
- }
-
- /* wrap back around from 8000 */
-
- if (*x >= 8000) *x = 0;
- return;
-}
-
-/*
-* Send a single tone burst for a specifed duration and frequency.
-* Returns 0 if successful
-*/
-
-static int send_tone_burst(struct ast_channel *chan, float freq, int duration, int tldn)
-{
- int res = 0;
- int i = 0;
- int x = 0;
- struct ast_frame *f, wf;
-
- struct {
- unsigned char offset[AST_FRIENDLY_OFFSET];
- unsigned char buf[640];
- } tone_block;
-
- for(;;)
- {
-
- if (ast_waitfor(chan, -1) < 0){
- res = -1;
- break;
- }
-
- f = ast_read(chan);
- if (!f){
- res = -1;
- break;
- }
-
- if (f->frametype == AST_FRAME_VOICE) {
- wf.frametype = AST_FRAME_VOICE;
- wf.subclass = AST_FORMAT_ULAW;
- wf.offset = AST_FRIENDLY_OFFSET;
- wf.mallocd = 0;
- wf.data = tone_block.buf;
- wf.datalen = f->datalen;
- wf.samples = wf.datalen;
-
- make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x);
-
- i += wf.datalen / 8;
- if (i > duration) {
- ast_frfree(f);
- break;
- }
- if (ast_write(chan, &wf)){
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Failed to write frame on %s\n", chan->name);
- ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name);
- res = -1;
- ast_frfree(f);
- break;
- }
- }
-
- ast_frfree(f);
- }
- return res;
-}
-
-/*
-* Receive a string of DTMF digits where the length of the digit string is known in advance. Do not give preferential
-* treatment to any digit value, and allow separate time out values to be specified for the first digit and all subsequent
-* digits.
-*
-* Returns 0 if all digits successfully received.
-* Returns 1 if a digit time out occurred
-* Returns -1 if the caller hung up or there was a channel error.
-*
-*/
-
-static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int length, int fdto, int sdto)
-{
- int res = 0;
- int i = 0;
- int r;
- struct ast_frame *f;
- struct timeval lastdigittime;
-
- lastdigittime = ast_tvnow();
- for(;;){
- /* if outa time, leave */
- if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) >
- ((i > 0) ? sdto : fdto)){
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name);
-
- ast_log(LOG_DEBUG,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name);
-
- res = 1;
- break;
- }
-
- if ((r = ast_waitfor(chan, -1) < 0)) {
- ast_log(LOG_DEBUG, "Waitfor returned %d\n", r);
- continue;
- }
-
- f = ast_read(chan);
-
- if (f == NULL){
- res = -1;
- break;
- }
-
- /* If they hung up, leave */
- if ((f->frametype == AST_FRAME_CONTROL) &&
- (f->subclass == AST_CONTROL_HANGUP)){
- ast_frfree(f);
- res = -1;
- break;
- }
-
- /* if not DTMF, just do it again */
- if (f->frametype != AST_FRAME_DTMF){
- ast_frfree(f);
- continue;
- }
-
- digit_string[i++] = f->subclass; /* save digit */
-
- ast_frfree(f);
-
- /* If we have all the digits we expect, leave */
- if(i >= length)
- break;
-
- lastdigittime = ast_tvnow();
- }
-
- digit_string[i] = '\0'; /* Nul terminate the end of the digit string */
- return res;
-
-}
-
-/*
-* Write the metadata to the log file
-*/
-
-static int write_metadata( FILE *logfile, char *signalling_type, struct ast_channel *chan)
-{
- int res = 0;
- time_t t;
- struct tm now;
- char *cl,*cn;
- char workstring[80];
- char timestamp[80];
-
- /* Extract the caller ID location */
- if (chan->cid.cid_num)
- ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring));
- workstring[sizeof(workstring) - 1] = '\0';
-
- ast_callerid_parse(workstring, &cn, &cl);
- if (cl)
- ast_shrink_phone_number(cl);
-
-
- /* Get the current time */
-
- time(&t);
- ast_localtime(&t, &now, NULL);
-
- /* Format the time */
-
- strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
-
-
- res = fprintf(logfile, "\n\n[metadata]\n\n");
-
- if(res >= 0)
- res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type);
-
- if(res >= 0)
- res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl);
-
- if(res >- 0)
- res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn);
-
- if(res >= 0)
- res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp);
-
- if(res >= 0)
- res = fprintf(logfile, "[events]\n\n");
-
- if(res < 0){
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't write metadata\n");
-
- ast_log(LOG_DEBUG,"AlarmReceiver: can't write metadata\n");
- }
- else
- res = 0;
-
- return res;
-}
-
-/*
-* Write a single event to the log file
-*/
-
-static int write_event( FILE *logfile, event_node_t *event)
-{
- int res = 0;
-
- if( fprintf(logfile, "%s\n", event->data) < 0)
- res = -1;
-
- return res;
-}
-
-
-/*
-* If we are configured to log events, do so here.
-*
-*/
-
-static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event)
-{
-
- int res = 0;
- char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = "";
- int fd;
- FILE *logfile;
- event_node_t *elp = event;
-
- if (!ast_strlen_zero(event_spool_dir)) {
-
- /* Make a template */
-
- ast_copy_string(workstring, event_spool_dir, sizeof(workstring));
- strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1);
-
- /* Make the temporary file */
-
- fd = mkstemp(workstring);
-
- if(fd == -1){
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't make temporary file\n");
- ast_log(LOG_DEBUG,"AlarmReceiver: can't make temporary file\n");
- res = -1;
- }
-
- if(!res){
- logfile = fdopen(fd, "w");
- if(logfile){
- /* Write the file */
- res = write_metadata(logfile, signalling_type, chan);
- if(!res)
- while((!res) && (elp != NULL)){
- res = write_event(logfile, elp);
- elp = elp->next;
- }
- if(!res){
- if(fflush(logfile) == EOF)
- res = -1;
- if(!res){
- if(fclose(logfile) == EOF)
- res = -1;
- }
- }
- }
- else
- res = -1;
- }
- }
-
- return res;
-}
-
-/*
-* This function implements the logic to receive the Ademco contact ID format.
-*
-* The function will return 0 when the caller hangs up, else a -1 if there was a problem.
-*/
-
-static int receive_ademco_contact_id( struct ast_channel *chan, void *data, int fdto, int sdto, int tldn, event_node_t **ehead)
-{
- int i,j;
- int res = 0;
- int checksum;
- char event[17];
- event_node_t *enew, *elp;
- int got_some_digits = 0;
- int events_received = 0;
- int ack_retries = 0;
-
- static char digit_map[15] = "0123456789*#ABC";
- static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15};
-
- database_increment("calls-received");
-
- /* Wait for first event */
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for first event from panel\n");
-
- while(res >= 0){
-
- if(got_some_digits == 0){
-
- /* Send ACK tone sequence */
-
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
-
-
- res = send_tone_burst(chan, 1400.0, 100, tldn);
-
- if(!res)
- res = ast_safe_sleep(chan, 100);
-
- if(!res){
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
-
- res = send_tone_burst(chan, 2300.0, 100, tldn);
- }
-
- }
-
- if( res >= 0)
- res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto);
-
- if (res < 0){
-
- if(events_received == 0)
- /* Hangup with no events received should be logged in the DB */
- database_increment("no-events-received");
- else{
- if(ack_retries){
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
-
- database_increment("ack-retries");
- }
- }
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: App exiting...\n");
- res = -1;
- break;
- }
-
- if(res != 0){
- /* Didn't get all of the digits */
- if(option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Incomplete string: %s, trying again...\n", event);
-
- if(!got_some_digits){
- got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0;
- ack_retries++;
- }
- continue;
- }
-
- got_some_digits = 1;
-
- if(option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Received Event %s\n", event);
- ast_log(LOG_DEBUG, "AlarmReceiver: Received event: %s\n", event);
-
- /* Calculate checksum */
-
- for(j = 0, checksum = 0; j < 16; j++){
- for(i = 0 ; i < sizeof(digit_map) ; i++){
- if(digit_map[i] == event[j])
- break;
- }
-
- if(i == 16)
- break;
-
- checksum += digit_weights[i];
- }
-
- if(i == 16){
- if(option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
- continue; /* Bad character */
- }
-
- /* Checksum is mod(15) of the total */
-
- checksum = checksum % 15;
-
- if (checksum) {
- database_increment("checksum-errors");
- if (option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Nonzero checksum\n");
- ast_log(LOG_DEBUG, "AlarmReceiver: Nonzero checksum\n");
- continue;
- }
-
- /* Check the message type for correctness */
-
- if(strncmp(event + 4, "18", 2)){
- if(strncmp(event + 4, "98", 2)){
- database_increment("format-errors");
- if(option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Wrong message type\n");
- ast_log(LOG_DEBUG, "AlarmReceiver: Wrong message type\n");
- continue;
- }
- }
-
- events_received++;
-
- /* Queue the Event */
- if (!(enew = ast_calloc(1, sizeof(*enew)))) {
- res = -1;
- break;
- }
-
- enew->next = NULL;
- ast_copy_string(enew->data, event, sizeof(enew->data));
-
- /*
- * Insert event onto end of list
- */
-
- if(*ehead == NULL){
- *ehead = enew;
- }
- else{
- for(elp = *ehead; elp->next != NULL; elp = elp->next)
- ;
-
- elp->next = enew;
- }
-
- if(res > 0)
- res = 0;
-
- /* Let the user have the option of logging the single event before sending the kissoff tone */
-
- if((res == 0) && (log_individual_events))
- res = log_events(chan, ADEMCO_CONTACT_ID, enew);
-
- /* Wait 200 msec before sending kissoff */
-
- if(res == 0)
- res = ast_safe_sleep(chan, 200);
-
- /* Send the kissoff tone */
-
- if(res == 0)
- res = send_tone_burst(chan, 1400.0, 900, tldn);
- }
-
-
- return res;
-}
-
-
-/*
-* This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.
-* This function will always return 0.
-*/
-
-static int alarmreceiver_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- event_node_t *elp, *efree;
- char signalling_type[64] = "";
-
- event_node_t *event_head = NULL;
-
- u = ast_module_user_add(chan);
-
- /* Set write and read formats to ULAW */
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Setting read and write formats to ULAW\n");
-
- if (ast_set_write_format(chan,AST_FORMAT_ULAW)){
- ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name);
- ast_module_user_remove(u);
- return -1;
- }
-
- if (ast_set_read_format(chan,AST_FORMAT_ULAW)){
- ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name);
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Set default values for this invokation of the application */
-
- ast_copy_string(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type));
-
-
- /* Answer the channel if it is not already */
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Answering channel\n");
-
- if (chan->_state != AST_STATE_UP) {
-
- res = ast_answer(chan);
-
- if (res) {
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- /* Wait for the connection to settle post-answer */
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for connection to stabilize\n");
-
- res = ast_safe_sleep(chan, 1250);
-
- /* Attempt to receive the events */
-
- if(!res){
-
- /* Determine the protocol to receive in advance */
- /* Note: Ademco contact is the only one supported at this time */
- /* Others may be added later */
-
- if(!strcmp(signalling_type, ADEMCO_CONTACT_ID))
- receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head);
- else
- res = -1;
- }
-
-
-
- /* Events queued by receiver, write them all out here if so configured */
-
- if((!res) && (log_individual_events == 0)){
- res = log_events(chan, signalling_type, event_head);
-
- }
-
- /*
- * Do we exec a command line at the end?
- */
-
- if((!res) && (!ast_strlen_zero(event_app)) && (event_head)){
- ast_log(LOG_DEBUG,"Alarmreceiver: executing: %s\n", event_app);
- ast_safe_system(event_app);
- }
-
- /*
- * Free up the data allocated in our linked list
- */
-
- for(elp = event_head; (elp != NULL);){
- efree = elp;
- elp = elp->next;
- free(efree);
- }
-
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-/*
-* Load the configuration from the configuration file
-*/
-
-static int load_config(void)
-{
- struct ast_config *cfg;
- const char *p;
-
- /* Read in the config file */
-
- cfg = ast_config_load(ALMRCV_CONFIG);
-
- if(!cfg){
-
- if(option_verbose >= 4)
- ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: No config file\n");
- return 0;
- }
- else{
-
-
- p = ast_variable_retrieve(cfg, "general", "eventcmd");
-
- if(p){
- ast_copy_string(event_app, p, sizeof(event_app));
- event_app[sizeof(event_app) - 1] = '\0';
- }
-
- p = ast_variable_retrieve(cfg, "general", "loudness");
- if(p){
- toneloudness = atoi(p);
- if(toneloudness < 100)
- toneloudness = 100;
- if(toneloudness > 8192)
- toneloudness = 8192;
- }
- p = ast_variable_retrieve(cfg, "general", "fdtimeout");
- if(p){
- fdtimeout = atoi(p);
- if(fdtimeout < 1000)
- fdtimeout = 1000;
- if(fdtimeout > 10000)
- fdtimeout = 10000;
- }
-
- p = ast_variable_retrieve(cfg, "general", "sdtimeout");
- if(p){
- sdtimeout = atoi(p);
- if(sdtimeout < 110)
- sdtimeout = 110;
- if(sdtimeout > 4000)
- sdtimeout = 4000;
-
- }
-
- p = ast_variable_retrieve(cfg, "general", "logindividualevents");
- if(p){
- log_individual_events = ast_true(p);
-
- }
-
- p = ast_variable_retrieve(cfg, "general", "eventspooldir");
-
- if(p){
- ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir));
- event_spool_dir[sizeof(event_spool_dir) - 1] = '\0';
- }
-
- p = ast_variable_retrieve(cfg, "general", "timestampformat");
-
- if(p){
- ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format));
- time_stamp_format[sizeof(time_stamp_format) - 1] = '\0';
- }
-
- p = ast_variable_retrieve(cfg, "general", "db-family");
-
- if(p){
- ast_copy_string(db_family, p, sizeof(db_family));
- db_family[sizeof(db_family) - 1] = '\0';
- }
- ast_config_destroy(cfg);
- }
- return 1;
-
-}
-
-/*
-* These functions are required to implement an Asterisk App.
-*/
-
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- if(load_config())
- return ast_register_application(app, alarmreceiver_exec, synopsis, descrip);
- else
- return AST_MODULE_LOAD_DECLINE;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Alarm Receiver for Asterisk");
diff --git a/1.4/apps/app_amd.c b/1.4/apps/app_amd.c
deleted file mode 100644
index 52f474048..000000000
--- a/1.4/apps/app_amd.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2003 - 2006, Aheeva Technology.
- *
- * Claude Klimos (claude.klimos@aheeva.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.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/dsp.h"
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/app.h"
-
-
-static char *app = "AMD";
-static char *synopsis = "Attempts to detect answering machines";
-static char *descrip =
-" AMD([initialSilence][|greeting][|afterGreetingSilence][|totalAnalysisTime]\n"
-" [|minimumWordLength][|betweenWordsSilence][|maximumNumberOfWords]\n"
-" [|silenceThreshold])\n"
-" This application attempts to detect answering machines at the beginning\n"
-" of outbound calls. Simply call this application after the call\n"
-" has been answered (outbound only, of course).\n"
-" When loaded, AMD reads amd.conf and uses the parameters specified as\n"
-" default values. Those default values get overwritten when calling AMD\n"
-" with parameters.\n"
-"- 'initialSilence' is the maximum silence duration before the greeting. If\n"
-" exceeded then MACHINE.\n"
-"- 'greeting' is the maximum length of a greeting. If exceeded then MACHINE.\n"
-"- 'afterGreetingSilence' is the silence after detecting a greeting.\n"
-" If exceeded then HUMAN.\n"
-"- 'totalAnalysisTime' is the maximum time allowed for the algorithm to decide\n"
-" on a HUMAN or MACHINE.\n"
-"- 'minimumWordLength'is the minimum duration of Voice to considered as a word.\n"
-"- 'betweenWordsSilence' is the minimum duration of silence after a word to \n"
-" consider the audio that follows as a new word.\n"
-"- 'maximumNumberOfWords'is the maximum number of words in the greeting. \n"
-" If exceeded then MACHINE.\n"
-"- 'silenceThreshold' is the silence threshold.\n"
-"This application sets the following channel variable upon completion:\n"
-" AMDSTATUS - This is the status of the answering machine detection.\n"
-" Possible values are:\n"
-" MACHINE | HUMAN | NOTSURE | HANGUP\n"
-" AMDCAUSE - Indicates the cause that led to the conclusion.\n"
-" Possible values are:\n"
-" TOOLONG-<%d total_time>\n"
-" INITIALSILENCE-<%d silenceDuration>-<%d initialSilence>\n"
-" HUMAN-<%d silenceDuration>-<%d afterGreetingSilence>\n"
-" MAXWORDS-<%d wordsCount>-<%d maximumNumberOfWords>\n"
-" LONGGREETING-<%d voiceDuration>-<%d greeting>\n";
-
-#define STATE_IN_WORD 1
-#define STATE_IN_SILENCE 2
-
-/* Some default values for the algorithm parameters. These defaults will be overwritten from amd.conf */
-static int dfltInitialSilence = 2500;
-static int dfltGreeting = 1500;
-static int dfltAfterGreetingSilence = 800;
-static int dfltTotalAnalysisTime = 5000;
-static int dfltMinimumWordLength = 100;
-static int dfltBetweenWordsSilence = 50;
-static int dfltMaximumNumberOfWords = 3;
-static int dfltSilenceThreshold = 256;
-
-/* Set to the lowest ms value provided in amd.conf or application parameters */
-static int dfltMaxWaitTimeForFrame = 50;
-
-static void isAnsweringMachine(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_frame *f = NULL;
- struct ast_dsp *silenceDetector = NULL;
- int dspsilence = 0, readFormat, framelength = 0;
- int inInitialSilence = 1;
- int inGreeting = 0;
- int voiceDuration = 0;
- int silenceDuration = 0;
- int iTotalTime = 0;
- int iWordsCount = 0;
- int currentState = STATE_IN_WORD;
- int previousState = STATE_IN_SILENCE;
- int consecutiveVoiceDuration = 0;
- char amdCause[256] = "", amdStatus[256] = "";
- char *parse = ast_strdupa(data);
-
- /* Lets set the initial values of the variables that will control the algorithm.
- The initial values are the default ones. If they are passed as arguments
- when invoking the application, then the default values will be overwritten
- by the ones passed as parameters. */
- int initialSilence = dfltInitialSilence;
- int greeting = dfltGreeting;
- int afterGreetingSilence = dfltAfterGreetingSilence;
- int totalAnalysisTime = dfltTotalAnalysisTime;
- int minimumWordLength = dfltMinimumWordLength;
- int betweenWordsSilence = dfltBetweenWordsSilence;
- int maximumNumberOfWords = dfltMaximumNumberOfWords;
- int silenceThreshold = dfltSilenceThreshold;
- int maxWaitTimeForFrame = dfltMaxWaitTimeForFrame;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(argInitialSilence);
- AST_APP_ARG(argGreeting);
- AST_APP_ARG(argAfterGreetingSilence);
- AST_APP_ARG(argTotalAnalysisTime);
- AST_APP_ARG(argMinimumWordLength);
- AST_APP_ARG(argBetweenWordsSilence);
- AST_APP_ARG(argMaximumNumberOfWords);
- AST_APP_ARG(argSilenceThreshold);
- );
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, chan->readformat);
-
- /* Lets parse the arguments. */
- if (!ast_strlen_zero(parse)) {
- /* Some arguments have been passed. Lets parse them and overwrite the defaults. */
- AST_STANDARD_APP_ARGS(args, parse);
- if (!ast_strlen_zero(args.argInitialSilence))
- initialSilence = atoi(args.argInitialSilence);
- if (!ast_strlen_zero(args.argGreeting))
- greeting = atoi(args.argGreeting);
- if (!ast_strlen_zero(args.argAfterGreetingSilence))
- afterGreetingSilence = atoi(args.argAfterGreetingSilence);
- if (!ast_strlen_zero(args.argTotalAnalysisTime))
- totalAnalysisTime = atoi(args.argTotalAnalysisTime);
- if (!ast_strlen_zero(args.argMinimumWordLength))
- minimumWordLength = atoi(args.argMinimumWordLength);
- if (!ast_strlen_zero(args.argBetweenWordsSilence))
- betweenWordsSilence = atoi(args.argBetweenWordsSilence);
- if (!ast_strlen_zero(args.argMaximumNumberOfWords))
- maximumNumberOfWords = atoi(args.argMaximumNumberOfWords);
- if (!ast_strlen_zero(args.argSilenceThreshold))
- silenceThreshold = atoi(args.argSilenceThreshold);
- } else if (option_debug)
- ast_log(LOG_DEBUG, "AMD using the default parameters.\n");
-
- /* Find lowest ms value, that will be max wait time for a frame */
- if (maxWaitTimeForFrame > initialSilence)
- maxWaitTimeForFrame = initialSilence;
- if (maxWaitTimeForFrame > greeting)
- maxWaitTimeForFrame = greeting;
- if (maxWaitTimeForFrame > afterGreetingSilence)
- maxWaitTimeForFrame = afterGreetingSilence;
- if (maxWaitTimeForFrame > totalAnalysisTime)
- maxWaitTimeForFrame = totalAnalysisTime;
- if (maxWaitTimeForFrame > minimumWordLength)
- maxWaitTimeForFrame = minimumWordLength;
- if (maxWaitTimeForFrame > betweenWordsSilence)
- maxWaitTimeForFrame = betweenWordsSilence;
-
- /* Now we're ready to roll! */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
- "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
- initialSilence, greeting, afterGreetingSilence, totalAnalysisTime,
- minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold );
-
- /* Set read format to signed linear so we get signed linear frames in */
- readFormat = chan->readformat;
- if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0 ) {
- ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to set to linear mode, giving up\n", chan->name );
- pbx_builtin_setvar_helper(chan , "AMDSTATUS", "");
- pbx_builtin_setvar_helper(chan , "AMDCAUSE", "");
- return;
- }
-
- /* Create a new DSP that will detect the silence */
- if (!(silenceDetector = ast_dsp_new())) {
- ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to create silence detector :(\n", chan->name );
- pbx_builtin_setvar_helper(chan , "AMDSTATUS", "");
- pbx_builtin_setvar_helper(chan , "AMDCAUSE", "");
- return;
- }
-
- /* Set silence threshold to specified value */
- ast_dsp_set_threshold(silenceDetector, silenceThreshold);
-
- /* Now we go into a loop waiting for frames from the channel */
- while ((res = ast_waitfor(chan, 2 * maxWaitTimeForFrame)) > -1) {
-
- /* If we fail to read in a frame, that means they hung up */
- if (!(f = ast_read(chan))) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: HANGUP\n");
- if (option_debug)
- ast_log(LOG_DEBUG, "Got hangup\n");
- strcpy(amdStatus, "HANGUP");
- break;
- }
-
- if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_NULL || f->frametype == AST_FRAME_CNG) {
- /* If the total time exceeds the analysis time then give up as we are not too sure */
- if (f->frametype == AST_FRAME_VOICE)
- framelength = (ast_codec_get_samples(f) / DEFAULT_SAMPLES_PER_MS);
- else
- framelength += 2 * maxWaitTimeForFrame;
-
- iTotalTime += framelength;
- if (iTotalTime >= totalAnalysisTime) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name );
- ast_frfree(f);
- strcpy(amdStatus , "NOTSURE");
- sprintf(amdCause , "TOOLONG-%d", iTotalTime);
- break;
- }
-
- /* Feed the frame of audio into the silence detector and see if we get a result */
- if (f->frametype != AST_FRAME_VOICE)
- dspsilence += 2 * maxWaitTimeForFrame;
- else {
- dspsilence = 0;
- ast_dsp_silence(silenceDetector, f, &dspsilence);
- }
-
- if (dspsilence > 0) {
- silenceDuration = dspsilence;
-
- if (silenceDuration >= betweenWordsSilence) {
- if (currentState != STATE_IN_SILENCE ) {
- previousState = currentState;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: Changed state to STATE_IN_SILENCE\n");
- }
- currentState = STATE_IN_SILENCE;
- consecutiveVoiceDuration = 0;
- }
-
- if (inInitialSilence == 1 && silenceDuration >= initialSilence) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: silenceDuration:%d initialSilence:%d\n",
- silenceDuration, initialSilence);
- ast_frfree(f);
- strcpy(amdStatus , "MACHINE");
- sprintf(amdCause , "INITIALSILENCE-%d-%d", silenceDuration, initialSilence);
- res = 1;
- break;
- }
-
- if (silenceDuration >= afterGreetingSilence && inGreeting == 1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: HUMAN: silenceDuration:%d afterGreetingSilence:%d\n",
- silenceDuration, afterGreetingSilence);
- ast_frfree(f);
- strcpy(amdStatus , "HUMAN");
- sprintf(amdCause , "HUMAN-%d-%d", silenceDuration, afterGreetingSilence);
- res = 1;
- break;
- }
-
- } else {
- consecutiveVoiceDuration += framelength;
- voiceDuration += framelength;
-
- /* If I have enough consecutive voice to say that I am in a Word, I can only increment the
- number of words if my previous state was Silence, which means that I moved into a word. */
- if (consecutiveVoiceDuration >= minimumWordLength && currentState == STATE_IN_SILENCE) {
- iWordsCount++;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: Word detected. iWordsCount:%d\n", iWordsCount);
- previousState = currentState;
- currentState = STATE_IN_WORD;
- }
-
- if (iWordsCount >= maximumNumberOfWords) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: iWordsCount:%d\n", iWordsCount);
- ast_frfree(f);
- strcpy(amdStatus , "MACHINE");
- sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords);
- res = 1;
- break;
- }
-
- if (inGreeting == 1 && voiceDuration >= greeting) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: voiceDuration:%d greeting:%d\n", voiceDuration, greeting);
- ast_frfree(f);
- strcpy(amdStatus , "MACHINE");
- sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting);
- res = 1;
- break;
- }
-
- if (voiceDuration >= minimumWordLength ) {
- silenceDuration = 0;
- inInitialSilence = 0;
- inGreeting = 1;
- }
-
- }
- }
- ast_frfree(f);
- }
-
- if (!res) {
- /* It took too long to get a frame back. Giving up. */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name);
- strcpy(amdStatus , "NOTSURE");
- sprintf(amdCause , "TOOLONG-%d", iTotalTime);
- }
-
- /* Set the status and cause on the channel */
- pbx_builtin_setvar_helper(chan , "AMDSTATUS" , amdStatus);
- pbx_builtin_setvar_helper(chan , "AMDCAUSE" , amdCause);
-
- /* Restore channel read format */
- if (readFormat && ast_set_read_format(chan, readFormat))
- ast_log(LOG_WARNING, "AMD: Unable to restore read format on '%s'\n", chan->name);
-
- /* Free the DSP used to detect silence */
- ast_dsp_free(silenceDetector);
-
- return;
-}
-
-
-static int amd_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u = NULL;
-
- u = ast_module_user_add(chan);
- isAnsweringMachine(chan, data);
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static void load_config(void)
-{
- struct ast_config *cfg = NULL;
- char *cat = NULL;
- struct ast_variable *var = NULL;
-
- if (!(cfg = ast_config_load("amd.conf"))) {
- ast_log(LOG_ERROR, "Configuration file amd.conf missing.\n");
- return;
- }
-
- cat = ast_category_browse(cfg, NULL);
-
- while (cat) {
- if (!strcasecmp(cat, "general") ) {
- var = ast_variable_browse(cfg, cat);
- while (var) {
- if (!strcasecmp(var->name, "initial_silence")) {
- dfltInitialSilence = atoi(var->value);
- } else if (!strcasecmp(var->name, "greeting")) {
- dfltGreeting = atoi(var->value);
- } else if (!strcasecmp(var->name, "after_greeting_silence")) {
- dfltAfterGreetingSilence = atoi(var->value);
- } else if (!strcasecmp(var->name, "silence_threshold")) {
- dfltSilenceThreshold = atoi(var->value);
- } else if (!strcasecmp(var->name, "total_analysis_time")) {
- dfltTotalAnalysisTime = atoi(var->value);
- } else if (!strcasecmp(var->name, "min_word_length")) {
- dfltMinimumWordLength = atoi(var->value);
- } else if (!strcasecmp(var->name, "between_words_silence")) {
- dfltBetweenWordsSilence = atoi(var->value);
- } else if (!strcasecmp(var->name, "maximum_number_of_words")) {
- dfltMaximumNumberOfWords = atoi(var->value);
- } else {
- ast_log(LOG_WARNING, "%s: Cat:%s. Unknown keyword %s at line %d of amd.conf\n",
- app, cat, var->name, var->lineno);
- }
- var = var->next;
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
-
- ast_config_destroy(cfg);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AMD defaults: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
- "totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
- dfltInitialSilence, dfltGreeting, dfltAfterGreetingSilence, dfltTotalAnalysisTime,
- dfltMinimumWordLength, dfltBetweenWordsSilence, dfltMaximumNumberOfWords, dfltSilenceThreshold );
-
- return;
-}
-
-static int unload_module(void)
-{
- ast_module_user_hangup_all();
- return ast_unregister_application(app);
-}
-
-static int load_module(void)
-{
- load_config();
- return ast_register_application(app, amd_exec, synopsis, descrip);
-}
-
-static int reload(void)
-{
- load_config();
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Answering Machine Detection Application",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/apps/app_authenticate.c b/1.4/apps/app_authenticate.c
deleted file mode 100644
index 56f53b8ad..000000000
--- a/1.4/apps/app_authenticate.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Execute arbitrary authenticate commands
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/app.h"
-#include "asterisk/astdb.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-
-enum {
- OPT_ACCOUNT = (1 << 0),
- OPT_DATABASE = (1 << 1),
- OPT_JUMP = (1 << 2),
- OPT_MULTIPLE = (1 << 3),
- OPT_REMOVE = (1 << 4),
-} auth_option_flags;
-
-AST_APP_OPTIONS(auth_app_options, {
- AST_APP_OPTION('a', OPT_ACCOUNT),
- AST_APP_OPTION('d', OPT_DATABASE),
- AST_APP_OPTION('j', OPT_JUMP),
- AST_APP_OPTION('m', OPT_MULTIPLE),
- AST_APP_OPTION('r', OPT_REMOVE),
-});
-
-
-static char *app = "Authenticate";
-
-static char *synopsis = "Authenticate a user";
-
-static char *descrip =
-" Authenticate(password[|options[|maxdigits]]): This application asks the caller\n"
-"to enter a given password in order to continue dialplan execution. If the password\n"
-"begins with the '/' character, it is interpreted as a file which contains a list of\n"
-"valid passwords, listed 1 password per line in the file.\n"
-" When using a database key, the value associated with the key can be anything.\n"
-"Users have three attempts to authenticate before the channel is hung up. If the\n"
-"passsword is invalid, the 'j' option is specified, and priority n+101 exists,\n"
-"dialplan execution will continnue at this location.\n"
-" Options:\n"
-" a - Set the channels' account code to the password that is entered\n"
-" d - Interpret the given path as database key, not a literal file\n"
-" j - Support jumping to n+101 if authentication fails\n"
-" m - Interpret the given path as a file which contains a list of account\n"
-" codes and password hashes delimited with ':', listed one per line in\n"
-" the file. When one of the passwords is matched, the channel will have\n"
-" its account code set to the corresponding account code in the file.\n"
-" r - Remove the database key upon successful entry (valid with 'd' only)\n"
-" maxdigits - maximum acceptable number of digits. Stops reading after\n"
-" maxdigits have been entered (without requiring the user to\n"
-" press the '#' key).\n"
-" Defaults to 0 - no limit - wait for the user press the '#' key.\n"
-;
-
-static int auth_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- int retries;
- struct ast_module_user *u;
- char passwd[256];
- char *prompt;
- int maxdigits;
- char *argcopy =NULL;
- struct ast_flags flags = {0};
-
- AST_DECLARE_APP_ARGS(arglist,
- AST_APP_ARG(password);
- AST_APP_ARG(options);
- AST_APP_ARG(maxdigits);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (chan->_state != AST_STATE_UP) {
- res = ast_answer(chan);
- if (res) {
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- argcopy = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(arglist,argcopy);
-
- if (!ast_strlen_zero(arglist.options)) {
- ast_app_parse_options(auth_app_options, &flags, NULL, arglist.options);
- }
-
- if (!ast_strlen_zero(arglist.maxdigits)) {
- maxdigits = atoi(arglist.maxdigits);
- if ((maxdigits<1) || (maxdigits>sizeof(passwd)-2))
- maxdigits = sizeof(passwd) - 2;
- } else {
- maxdigits = sizeof(passwd) - 2;
- }
-
- /* Start asking for password */
- prompt = "agent-pass";
- for (retries = 0; retries < 3; retries++) {
- res = ast_app_getdata(chan, prompt, passwd, maxdigits, 0);
- if (res < 0)
- break;
- res = 0;
- if (arglist.password[0] == '/') {
- if (ast_test_flag(&flags,OPT_DATABASE)) {
- char tmp[256];
- /* Compare against a database key */
- if (!ast_db_get(arglist.password + 1, passwd, tmp, sizeof(tmp))) {
- /* It's a good password */
- if (ast_test_flag(&flags,OPT_REMOVE)) {
- ast_db_del(arglist.password + 1, passwd);
- }
- break;
- }
- } else {
- /* Compare against a file */
- FILE *f;
- f = fopen(arglist.password, "r");
- if (f) {
- char buf[256] = "";
- char md5passwd[33] = "";
- char *md5secret = NULL;
-
- while (!feof(f)) {
- fgets(buf, sizeof(buf), f);
- if (!ast_strlen_zero(buf)) {
- size_t len = strlen(buf);
- if (buf[len - 1] == '\n')
- buf[len - 1] = '\0';
- if (ast_test_flag(&flags,OPT_MULTIPLE)) {
- md5secret = strchr(buf, ':');
- if (md5secret == NULL)
- continue;
- *md5secret = '\0';
- md5secret++;
- ast_md5_hash(md5passwd, passwd);
- if (!strcmp(md5passwd, md5secret)) {
- if (ast_test_flag(&flags,OPT_ACCOUNT))
- ast_cdr_setaccount(chan, buf);
- break;
- }
- } else {
- if (!strcmp(passwd, buf)) {
- if (ast_test_flag(&flags,OPT_ACCOUNT))
- ast_cdr_setaccount(chan, buf);
- break;
- }
- }
- }
- }
- fclose(f);
- if (!ast_strlen_zero(buf)) {
- if (ast_test_flag(&flags,OPT_MULTIPLE)) {
- if (md5secret && !strcmp(md5passwd, md5secret))
- break;
- } else {
- if (!strcmp(passwd, buf))
- break;
- }
- }
- } else
- ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", arglist.password, strerror(errno));
- }
- } else {
- /* Compare against a fixed password */
- if (!strcmp(passwd, arglist.password))
- break;
- }
- prompt="auth-incorrect";
- }
- if ((retries < 3) && !res) {
- if (ast_test_flag(&flags,OPT_ACCOUNT) && !ast_test_flag(&flags,OPT_MULTIPLE))
- ast_cdr_setaccount(chan, passwd);
- res = ast_streamfile(chan, "auth-thankyou", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- } else {
- if (ast_test_flag(&flags,OPT_JUMP) && ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101) == 0) {
- res = 0;
- } else {
- if (!ast_streamfile(chan, "vm-goodbye", chan->language))
- res = ast_waitstream(chan, "");
- res = -1;
- }
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- ast_module_user_hangup_all();
-
- res = ast_unregister_application(app);
-
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, auth_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Authentication Application");
diff --git a/1.4/apps/app_cdr.c b/1.4/apps/app_cdr.c
deleted file mode 100644
index a70d9d2f5..000000000
--- a/1.4/apps/app_cdr.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Martin Pycko <martinp@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.
- */
-
-/*! \file
- *
- * \brief Applications connected with CDR engine
- *
- * Martin Pycko <martinp@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/pbx.h"
-
-static char *nocdr_descrip =
-" NoCDR(): This application will tell Asterisk not to maintain a CDR for the\n"
-"current call.\n";
-
-static char *nocdr_app = "NoCDR";
-static char *nocdr_synopsis = "Tell Asterisk to not maintain a CDR for the current call";
-
-
-static int nocdr_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- if (chan->cdr) {
- ast_set_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED);
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(nocdr_app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(nocdr_app, nocdr_exec, nocdr_synopsis, nocdr_descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Tell Asterisk to not maintain a CDR for the current call");
diff --git a/1.4/apps/app_chanisavail.c b/1.4/apps/app_chanisavail.c
deleted file mode 100644
index c6931d8db..000000000
--- a/1.4/apps/app_chanisavail.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
-* Asterisk -- An open source telephony toolkit.
-*
-* Copyright (C) 1999 - 2005, Digium, Inc.
-*
-* Mark Spencer <markster@digium.com>
-* James Golovich <james@gnuinter.net>
-*
-* See http://www.asterisk.org for more information about
-* the Asterisk project. Please do not directly contact
-* any of the maintainers of this project for assistance;
-* the project provides a web site, mailing lists and IRC
-* channels for your use.
-*
-* This program is free software, distributed under the terms of
-* the GNU General Public License Version 2. See the LICENSE file
-* at the top of the source tree.
-*/
-
-/*! \file
- *
- * \brief Check if Channel is Available
- *
- * \author Mark Spencer <markster@digium.com>
- * \author James Golovich <james@gnuinter.net>
-
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/app.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/options.h"
-
-static char *app = "ChanIsAvail";
-
-static char *synopsis = "Check channel availability";
-
-static char *descrip =
-" ChanIsAvail(Technology/resource[&Technology2/resource2...][|options]): \n"
-"This application will check to see if any of the specified channels are\n"
-"available. The following variables will be set by this application:\n"
-" ${AVAILCHAN} - the name of the available channel, if one exists\n"
-" ${AVAILORIGCHAN} - the canonical channel name that was used to create the channel\n"
-" ${AVAILSTATUS} - the status code for the available channel\n"
-" Options:\n"
-" s - Consider the channel unavailable if the channel is in use at all\n"
-" j - Support jumping to priority n+101 if no channel is available\n";
-
-
-static int chanavail_exec(struct ast_channel *chan, void *data)
-{
- int res=-1, inuse=-1, option_state=0, priority_jump=0;
- int status;
- struct ast_module_user *u;
- char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
- struct ast_channel *tempchan;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(reqchans);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- info = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, info);
-
- if (args.options) {
- if (strchr(args.options, 's'))
- option_state = 1;
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
- peers = args.reqchans;
- if (peers) {
- cur = peers;
- do {
- /* remember where to start next time */
- rest = strchr(cur, '&');
- if (rest) {
- *rest = 0;
- rest++;
- }
- tech = cur;
- number = strchr(tech, '/');
- if (!number) {
- ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
- ast_module_user_remove(u);
- return -1;
- }
- *number = '\0';
- number++;
-
- if (option_state) {
- /* If the pbx says in use then don't bother trying further.
- This is to permit testing if someone's on a call, even if the
- channel can permit more calls (ie callwaiting, sip calls, etc). */
-
- snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
- status = inuse = ast_device_state(trychan);
- }
- if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
- pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
- /* Store the originally used channel too */
- snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
- pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
- snprintf(tmp, sizeof(tmp), "%d", status);
- pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
- ast_hangup(tempchan);
- tempchan = NULL;
- res = 1;
- break;
- } else {
- snprintf(tmp, sizeof(tmp), "%d", status);
- pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
- }
- cur = rest;
- } while (cur);
- }
- if (res < 1) {
- pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
- pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
- if (priority_jump || ast_opt_priority_jumping) {
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
- ast_module_user_remove(u);
- return -1;
- }
- }
- }
-
- ast_module_user_remove(u);
- return 0;
-}
-
-static int unload_module(void)
-{
- int res = 0;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, chanavail_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Check channel availability");
diff --git a/1.4/apps/app_channelredirect.c b/1.4/apps/app_channelredirect.c
deleted file mode 100644
index a8eedf9b4..000000000
--- a/1.4/apps/app_channelredirect.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Sergey Basmanov
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ChannelRedirect application
- *
- * \author Sergey Basmanov <sergey_basmanov@mail.ru>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-#include "asterisk/features.h"
-#include "asterisk/options.h"
-
-static char *app = "ChannelRedirect";
-static char *synopsis = "Redirects given channel to a dialplan target.";
-static char *descrip =
-"ChannelRedirect(channel|[[context|]extension|]priority):\n"
-" Sends the specified channel to the specified extension priority\n";
-
-
-static int asyncgoto_exec(struct ast_channel *chan, void *data)
-{
- int res = -1;
- struct ast_module_user *u;
- char *info, *context, *exten, *priority;
- int prio = 1;
- struct ast_channel *chan2 = NULL;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(channel);
- AST_APP_ARG(label);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s requires an argument (channel|[[context|]exten|]priority)\n", app);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- info = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, info);
-
- if (ast_strlen_zero(args.channel) || ast_strlen_zero(args.label)) {
- ast_log(LOG_WARNING, "%s requires an argument (channel|[[context|]exten|]priority)\n", app);
- goto quit;
- }
-
- chan2 = ast_get_channel_by_name_locked(args.channel);
- if (!chan2) {
- ast_log(LOG_WARNING, "No such channel: %s\n", args.channel);
- goto quit;
- }
-
- /* Parsed right to left, so standard parsing won't work */
- context = strsep(&args.label, "|");
- exten = strsep(&args.label, "|");
- if (exten) {
- priority = strsep(&args.label, "|");
- if (!priority) {
- priority = exten;
- exten = context;
- context = NULL;
- }
- } else {
- priority = context;
- context = NULL;
- }
-
- /* ast_findlabel_extension does not convert numeric priorities; it only does a lookup */
- if (!(prio = atoi(priority)) && !(prio = ast_findlabel_extension(chan2, S_OR(context, chan2->context),
- S_OR(exten, chan2->exten), priority, chan2->cid.cid_num))) {
- ast_log(LOG_WARNING, "'%s' is not a known priority or label\n", priority);
- goto chanquit;
- }
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Attempting async goto (%s) to %s|%s|%d\n", args.channel, S_OR(context, chan2->context), S_OR(exten, chan2->exten), prio);
-
- if (ast_async_goto_if_exists(chan2, S_OR(context, chan2->context), S_OR(exten, chan2->exten), prio))
- ast_log(LOG_WARNING, "%s failed for %s\n", app, args.channel);
- else
- res = 0;
-
- chanquit:
- ast_mutex_unlock(&chan2->lock);
- quit:
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, asyncgoto_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel Redirect");
diff --git a/1.4/apps/app_chanspy.c b/1.4/apps/app_chanspy.c
deleted file mode 100644
index b58b6d1ef..000000000
--- a/1.4/apps/app_chanspy.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005 Anthony Minessale II (anthmct@yahoo.com)
- * Copyright (C) 2005 - 2008, Digium, Inc.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ChanSpy: Listen in on any channel.
- *
- * \author Anthony Minessale II <anthmct@yahoo.com>
- * \author Joshua Colp <jcolp@digium.com>
- * \author Russell Bryant <russell@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/audiohook.h"
-#include "asterisk/features.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-#include "asterisk/utils.h"
-#include "asterisk/say.h"
-#include "asterisk/pbx.h"
-#include "asterisk/translate.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-
-#define AST_NAME_STRLEN 256
-
-static const char *tdesc = "Listen to a channel, and optionally whisper into it";
-static const char *app_chan = "ChanSpy";
-static const char *desc_chan =
-" ChanSpy([chanprefix][|options]): This application is used to listen to the\n"
-"audio from an Asterisk channel. This includes the audio coming in and\n"
-"out of the channel being spied on. If the 'chanprefix' parameter is specified,\n"
-"only channels beginning with this string will be spied upon.\n"
-" While spying, the following actions may be performed:\n"
-" - Dialing # cycles the volume level.\n"
-" - Dialing * will stop spying and look for another channel to spy on.\n"
-" - Dialing a series of digits followed by # builds a channel name to append\n"
-" to 'chanprefix'. For example, executing ChanSpy(Agent) and then dialing\n"
-" the digits '1234#' while spying will begin spying on the channel\n"
-" 'Agent/1234'.\n"
-" Options:\n"
-" b - Only spy on channels involved in a bridged call.\n"
-" g(grp) - Match only channels where their ${SPYGROUP} variable is set to\n"
-" contain 'grp' in an optional : delimited list.\n"
-" q - Don't play a beep when beginning to spy on a channel, or speak the\n"
-" selected channel name.\n"
-" r[(basename)] - Record the session to the monitor spool directory. An\n"
-" optional base for the filename may be specified. The\n"
-" default is 'chanspy'.\n"
-" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n"
-" negative value refers to a quieter setting.\n"
-" w - Enable 'whisper' mode, so the spying channel can talk to\n"
-" the spied-on channel.\n"
-" W - Enable 'private whisper' mode, so the spying channel can\n"
-" talk to the spied-on channel but cannot listen to that\n"
-" channel.\n"
-;
-
-static const char *app_ext = "ExtenSpy";
-static const char *desc_ext =
-" ExtenSpy(exten[@context][|options]): This application is used to listen to the\n"
-"audio from an Asterisk channel. This includes the audio coming in and\n"
-"out of the channel being spied on. Only channels created by outgoing calls for the\n"
-"specified extension will be selected for spying. If the optional context is not\n"
-"supplied, the current channel's context will be used.\n"
-" While spying, the following actions may be performed:\n"
-" - Dialing # cycles the volume level.\n"
-" - Dialing * will stop spying and look for another channel to spy on.\n"
-" Options:\n"
-" b - Only spy on channels involved in a bridged call.\n"
-" g(grp) - Match only channels where their ${SPYGROUP} variable is set to\n"
-" contain 'grp' in an optional : delimited list.\n"
-" q - Don't play a beep when beginning to spy on a channel, or speak the\n"
-" selected channel name.\n"
-" r[(basename)] - Record the session to the monitor spool directory. An\n"
-" optional base for the filename may be specified. The\n"
-" default is 'chanspy'.\n"
-" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n"
-" negative value refers to a quieter setting.\n"
-" w - Enable 'whisper' mode, so the spying channel can talk to\n"
-" the spied-on channel.\n"
-" W - Enable 'private whisper' mode, so the spying channel can\n"
-" talk to the spied-on channel but cannot listen to that\n"
-" channel.\n"
-;
-
-enum {
- OPTION_QUIET = (1 << 0), /* Quiet, no announcement */
- OPTION_BRIDGED = (1 << 1), /* Only look at bridged calls */
- OPTION_VOLUME = (1 << 2), /* Specify initial volume */
- OPTION_GROUP = (1 << 3), /* Only look at channels in group */
- OPTION_RECORD = (1 << 4),
- OPTION_WHISPER = (1 << 5),
- OPTION_PRIVATE = (1 << 6), /* Private Whisper mode */
-} chanspy_opt_flags;
-
-enum {
- OPT_ARG_VOLUME = 0,
- OPT_ARG_GROUP,
- OPT_ARG_RECORD,
- OPT_ARG_ARRAY_SIZE,
-} chanspy_opt_args;
-
-AST_APP_OPTIONS(spy_opts, {
- AST_APP_OPTION('q', OPTION_QUIET),
- AST_APP_OPTION('b', OPTION_BRIDGED),
- AST_APP_OPTION('w', OPTION_WHISPER),
- AST_APP_OPTION('W', OPTION_PRIVATE),
- AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME),
- AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
- AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
-});
-
-
-struct chanspy_translation_helper {
- /* spy data */
- struct ast_audiohook spy_audiohook;
- struct ast_audiohook whisper_audiohook;
- int fd;
- int volfactor;
-};
-
-static void *spy_alloc(struct ast_channel *chan, void *data)
-{
- /* just store the data pointer in the channel structure */
- return data;
-}
-
-static void spy_release(struct ast_channel *chan, void *data)
-{
- /* nothing to do */
-}
-
-static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct chanspy_translation_helper *csth = data;
- struct ast_frame *f;
-
- ast_audiohook_lock(&csth->spy_audiohook);
- if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
- ast_audiohook_unlock(&csth->spy_audiohook);
- return -1;
- }
-
- f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
-
- ast_audiohook_unlock(&csth->spy_audiohook);
-
- if (!f)
- return 0;
-
- if (ast_write(chan, f)) {
- ast_frfree(f);
- return -1;
- }
-
- if (csth->fd)
- write(csth->fd, f->data, f->datalen);
-
- ast_frfree(f);
-
- return 0;
-}
-
-static struct ast_generator spygen = {
- .alloc = spy_alloc,
- .release = spy_release,
- .generate = spy_generate,
-};
-
-static int start_spying(struct ast_channel *chan, const char *spychan_name, struct ast_audiohook *audiohook)
-{
- int res;
- struct ast_channel *peer;
-
- ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, chan->name);
-
- res = ast_audiohook_attach(chan, audiohook);
-
- if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) {
- ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);
- }
- return res;
-}
-
-struct chanspy_ds {
- struct ast_channel *chan;
- ast_mutex_t lock;
-};
-
-static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chanspy_ds,
- int *volfactor, int fd, const struct ast_flags *flags)
-{
- struct chanspy_translation_helper csth;
- int running = 0, res, x = 0;
- char inp[24] = {0};
- char *name;
- struct ast_frame *f;
- struct ast_silence_generator *silgen = NULL;
- struct ast_channel *spyee = NULL;
- const char *spyer_name;
-
- ast_channel_lock(chan);
- spyer_name = ast_strdupa(chan->name);
- ast_channel_unlock(chan);
-
- ast_mutex_lock(&spyee_chanspy_ds->lock);
- if (spyee_chanspy_ds->chan) {
- spyee = spyee_chanspy_ds->chan;
- ast_channel_lock(spyee);
- }
- ast_mutex_unlock(&spyee_chanspy_ds->lock);
-
- if (!spyee)
- return 0;
-
- /* We now hold the channel lock on spyee */
-
- if (ast_check_hangup(chan) || ast_check_hangup(spyee)) {
- ast_channel_unlock(spyee);
- return 0;
- }
-
- name = ast_strdupa(spyee->name);
- if (option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "Spying on channel %s\n", name);
-
- memset(&csth, 0, sizeof(csth));
-
- ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy");
-
- if (start_spying(spyee, spyer_name, &csth.spy_audiohook)) {
- ast_audiohook_destroy(&csth.spy_audiohook);
- ast_channel_unlock(spyee);
- return 0;
- }
-
- if (ast_test_flag(flags, OPTION_WHISPER)) {
- ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy");
- start_spying(spyee, spyer_name, &csth.whisper_audiohook);
- }
-
- ast_channel_unlock(spyee);
- spyee = NULL;
-
- csth.volfactor = *volfactor;
-
- if (csth.volfactor) {
- csth.spy_audiohook.options.read_volume = csth.volfactor;
- csth.spy_audiohook.options.write_volume = csth.volfactor;
- }
-
- csth.fd = fd;
-
- if (ast_test_flag(flags, OPTION_PRIVATE))
- silgen = ast_channel_start_silence_generator(chan);
- else
- ast_activate_generator(chan, &spygen, &csth);
-
- /* We can no longer rely on 'spyee' being an actual channel;
- it can be hung up and freed out from under us. However, the
- channel destructor will put NULL into our csth.spy.chan
- field when that happens, so that is our signal that the spyee
- channel has gone away.
- */
-
- /* Note: it is very important that the ast_waitfor() be the first
- condition in this expression, so that if we wait for some period
- of time before receiving a frame from our spying channel, we check
- for hangup on the spied-on channel _after_ knowing that a frame
- has arrived, since the spied-on channel could have gone away while
- we were waiting
- */
- while ((res = ast_waitfor(chan, -1) > -1) && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
- if (!(f = ast_read(chan)) || ast_check_hangup(chan)) {
- running = -1;
- break;
- }
-
- if (ast_test_flag(flags, OPTION_WHISPER) && (f->frametype == AST_FRAME_VOICE)) {
- ast_audiohook_lock(&csth.whisper_audiohook);
- ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
- ast_audiohook_unlock(&csth.whisper_audiohook);
- ast_frfree(f);
- continue;
- }
-
- res = (f->frametype == AST_FRAME_DTMF) ? f->subclass : 0;
- ast_frfree(f);
- if (!res)
- continue;
-
- if (x == sizeof(inp))
- x = 0;
-
- if (res < 0) {
- running = -1;
- break;
- }
-
- if (res == '*') {
- running = 0;
- break;
- } else if (res == '#') {
- if (!ast_strlen_zero(inp)) {
- running = atoi(inp);
- break;
- }
-
- (*volfactor)++;
- if (*volfactor > 4)
- *volfactor = -4;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting spy volume on %s to %d\n", chan->name, *volfactor);
- csth.volfactor = *volfactor;
- csth.spy_audiohook.options.read_volume = csth.volfactor;
- csth.spy_audiohook.options.write_volume = csth.volfactor;
- } else if (res >= '0' && res <= '9') {
- inp[x++] = res;
- }
- }
-
- if (ast_test_flag(flags, OPTION_PRIVATE))
- ast_channel_stop_silence_generator(chan, silgen);
- else
- ast_deactivate_generator(chan);
-
- if (ast_test_flag(flags, OPTION_WHISPER)) {
- ast_audiohook_lock(&csth.whisper_audiohook);
- ast_audiohook_detach(&csth.whisper_audiohook);
- ast_audiohook_unlock(&csth.whisper_audiohook);
- ast_audiohook_destroy(&csth.whisper_audiohook);
- }
-
- ast_audiohook_lock(&csth.spy_audiohook);
- ast_audiohook_detach(&csth.spy_audiohook);
- ast_audiohook_unlock(&csth.spy_audiohook);
- ast_audiohook_destroy(&csth.spy_audiohook);
-
- if (option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name);
-
- return running;
-}
-
-/*!
- * \note This relies on the embedded lock to be recursive, as it may be called
- * due to a call to chanspy_ds_free with the lock held there.
- */
-static void chanspy_ds_destroy(void *data)
-{
- struct chanspy_ds *chanspy_ds = data;
-
- /* Setting chan to be NULL is an atomic operation, but we don't want this
- * value to change while this lock is held. The lock is held elsewhere
- * while it performs non-atomic operations with this channel pointer */
-
- ast_mutex_lock(&chanspy_ds->lock);
- chanspy_ds->chan = NULL;
- ast_mutex_unlock(&chanspy_ds->lock);
-}
-
-static void chanspy_ds_chan_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
-{
- struct chanspy_ds *chanspy_ds = data;
-
- ast_mutex_lock(&chanspy_ds->lock);
- chanspy_ds->chan = new_chan;
- ast_mutex_unlock(&chanspy_ds->lock);
-}
-
-static const struct ast_datastore_info chanspy_ds_info = {
- .type = "chanspy",
- .destroy = chanspy_ds_destroy,
- .chan_fixup = chanspy_ds_chan_fixup,
-};
-
-static struct chanspy_ds *chanspy_ds_free(struct chanspy_ds *chanspy_ds)
-{
- if (!chanspy_ds)
- return NULL;
-
- ast_mutex_lock(&chanspy_ds->lock);
- if (chanspy_ds->chan) {
- struct ast_datastore *datastore;
- struct ast_channel *chan;
-
- chan = chanspy_ds->chan;
-
- ast_channel_lock(chan);
- if ((datastore = ast_channel_datastore_find(chan, &chanspy_ds_info, NULL))) {
- ast_channel_datastore_remove(chan, datastore);
- /* chanspy_ds->chan is NULL after this call */
- chanspy_ds_destroy(datastore->data);
- datastore->data = NULL;
- ast_channel_datastore_free(datastore);
- }
- ast_channel_unlock(chan);
- }
- ast_mutex_unlock(&chanspy_ds->lock);
-
- return NULL;
-}
-
-/*! \note Returns the channel in the chanspy_ds locked as well as the chanspy_ds locked */
-static struct chanspy_ds *setup_chanspy_ds(struct ast_channel *chan, struct chanspy_ds *chanspy_ds)
-{
- struct ast_datastore *datastore = NULL;
-
- ast_mutex_lock(&chanspy_ds->lock);
-
- if (!(datastore = ast_channel_datastore_alloc(&chanspy_ds_info, NULL))) {
- ast_mutex_unlock(&chanspy_ds->lock);
- chanspy_ds = chanspy_ds_free(chanspy_ds);
- ast_channel_unlock(chan);
- return NULL;
- }
-
- chanspy_ds->chan = chan;
- datastore->data = chanspy_ds;
- ast_channel_datastore_add(chan, datastore);
-
- return chanspy_ds;
-}
-
-static struct chanspy_ds *next_channel(struct ast_channel *chan,
- const struct ast_channel *last, const char *spec,
- const char *exten, const char *context, struct chanspy_ds *chanspy_ds)
-{
- struct ast_channel *this;
-
-redo:
- if (spec)
- this = ast_walk_channel_by_name_prefix_locked(last, spec, strlen(spec));
- else if (exten)
- this = ast_walk_channel_by_exten_locked(last, exten, context);
- else
- this = ast_channel_walk_locked(last);
-
- if (!this)
- return NULL;
-
- if (!strncmp(this->name, "Zap/pseudo", 10)) {
- ast_channel_unlock(this);
- goto redo;
- } else if (this == chan) {
- last = this;
- ast_channel_unlock(this);
- goto redo;
- }
-
- return setup_chanspy_ds(this, chanspy_ds);
-}
-
-static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
- int volfactor, const int fd, const char *mygroup, const char *spec,
- const char *exten, const char *context)
-{
- char nameprefix[AST_NAME_STRLEN];
- char peer_name[AST_NAME_STRLEN + 5];
- signed char zero_volume = 0;
- int waitms;
- int res;
- char *ptr;
- int num;
- int num_spyed_upon = 1;
- struct chanspy_ds chanspy_ds;
-
- ast_mutex_init(&chanspy_ds.lock);
-
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
-
- waitms = 100;
-
- for (;;) {
- struct chanspy_ds *peer_chanspy_ds = NULL, *next_chanspy_ds = NULL;
- struct ast_channel *prev = NULL, *peer = NULL;
-
- if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
- res = ast_streamfile(chan, "beep", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- else if (res < 0) {
- ast_clear_flag(chan, AST_FLAG_SPYING);
- break;
- }
- }
-
- res = ast_waitfordigit(chan, waitms);
- if (res < 0) {
- ast_clear_flag(chan, AST_FLAG_SPYING);
- break;
- }
-
- /* reset for the next loop around, unless overridden later */
- waitms = 100;
- num_spyed_upon = 0;
-
- for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds);
- peer_chanspy_ds;
- chanspy_ds_free(peer_chanspy_ds), prev = peer,
- peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds :
- next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) {
- const char *group;
- int igrp = !mygroup;
- char *groups[25];
- int num_groups = 0;
- char *dup_group;
- int x;
- char *s;
-
- peer = peer_chanspy_ds->chan;
-
- ast_mutex_unlock(&peer_chanspy_ds->lock);
-
- if (peer == prev) {
- ast_channel_unlock(peer);
- chanspy_ds_free(peer_chanspy_ds);
- break;
- }
-
- if (ast_check_hangup(chan)) {
- ast_channel_unlock(peer);
- chanspy_ds_free(peer_chanspy_ds);
- break;
- }
-
- if (ast_test_flag(flags, OPTION_BRIDGED) && !ast_bridged_channel(peer)) {
- ast_channel_unlock(peer);
- continue;
- }
-
- if (ast_check_hangup(peer) || ast_test_flag(peer, AST_FLAG_SPYING)) {
- ast_channel_unlock(peer);
- continue;
- }
-
- if (mygroup) {
- if ((group = pbx_builtin_getvar_helper(peer, "SPYGROUP"))) {
- dup_group = ast_strdupa(group);
- num_groups = ast_app_separate_args(dup_group, ':', groups,
- sizeof(groups) / sizeof(groups[0]));
- }
-
- for (x = 0; x < num_groups; x++) {
- if (!strcmp(mygroup, groups[x])) {
- igrp = 1;
- break;
- }
- }
- }
-
- if (!igrp) {
- ast_channel_unlock(peer);
- continue;
- }
-
- strcpy(peer_name, "spy-");
- strncat(peer_name, peer->name, AST_NAME_STRLEN - 4 - 1);
- ptr = strchr(peer_name, '/');
- *ptr++ = '\0';
-
- for (s = peer_name; s < ptr; s++)
- *s = tolower(*s);
-
- /* We have to unlock the peer channel here to avoid a deadlock.
- * So, when we need to dereference it again, we have to lock the
- * datastore and get the pointer from there to see if the channel
- * is still valid. */
- ast_channel_unlock(peer);
-
- if (!ast_test_flag(flags, OPTION_QUIET)) {
- if (ast_fileexists(peer_name, NULL, NULL) != -1) {
- res = ast_streamfile(chan, peer_name, chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- if (res) {
- chanspy_ds_free(peer_chanspy_ds);
- break;
- }
- } else
- res = ast_say_character_str(chan, peer_name, "", chan->language);
- if ((num = atoi(ptr)))
- ast_say_digits(chan, atoi(ptr), "", chan->language);
- }
-
- res = channel_spy(chan, peer_chanspy_ds, &volfactor, fd, flags);
- num_spyed_upon++;
-
- if (res == -1) {
- chanspy_ds_free(peer_chanspy_ds);
- break;
- } else if (res > 1 && spec) {
- struct ast_channel *next;
-
- snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
-
- if ((next = ast_get_channel_by_name_prefix_locked(nameprefix, strlen(nameprefix)))) {
- peer_chanspy_ds = chanspy_ds_free(peer_chanspy_ds);
- next_chanspy_ds = setup_chanspy_ds(next, &chanspy_ds);
- } else {
- /* stay on this channel, if it is still valid */
-
- ast_mutex_lock(&peer_chanspy_ds->lock);
- if (peer_chanspy_ds->chan) {
- ast_channel_lock(peer_chanspy_ds->chan);
- next_chanspy_ds = peer_chanspy_ds;
- peer_chanspy_ds = NULL;
- } else {
- /* the channel is gone */
- ast_mutex_unlock(&peer_chanspy_ds->lock);
- next_chanspy_ds = NULL;
- }
- }
-
- peer = NULL;
- }
- }
- if (res == -1 || ast_check_hangup(chan))
- break;
- }
-
- ast_clear_flag(chan, AST_FLAG_SPYING);
-
- ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
-
- ast_mutex_destroy(&chanspy_ds.lock);
-
- return res;
-}
-
-static int chanspy_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *options = NULL;
- char *spec = NULL;
- char *argv[2];
- char *mygroup = NULL;
- char *recbase = NULL;
- int fd = 0;
- struct ast_flags flags;
- int oldwf = 0;
- int argc = 0;
- int volfactor = 0;
- int res;
-
- data = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
-
- if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
- spec = argv[0];
- if (argc > 1)
- options = argv[1];
-
- if (ast_strlen_zero(spec) || !strcmp(spec, "all"))
- spec = NULL;
- }
-
- if (options) {
- char *opts[OPT_ARG_ARRAY_SIZE];
-
- ast_app_parse_options(spy_opts, &flags, opts, options);
- if (ast_test_flag(&flags, OPTION_GROUP))
- mygroup = opts[OPT_ARG_GROUP];
-
- if (ast_test_flag(&flags, OPTION_RECORD) &&
- !(recbase = opts[OPT_ARG_RECORD]))
- recbase = "chanspy";
-
- if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
- int vol;
-
- if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
- ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
- else
- volfactor = vol;
- }
-
- if (ast_test_flag(&flags, OPTION_PRIVATE))
- ast_set_flag(&flags, OPTION_WHISPER);
- } else
- ast_clear_flag(&flags, AST_FLAGS_ALL);
-
- oldwf = chan->writeformat;
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
- ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if (recbase) {
- char filename[PATH_MAX];
-
- snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
- if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644)) <= 0) {
- ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
- fd = 0;
- }
- }
-
- res = common_exec(chan, &flags, volfactor, fd, mygroup, spec, NULL, NULL);
-
- if (fd)
- close(fd);
-
- if (oldwf && ast_set_write_format(chan, oldwf) < 0)
- ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int extenspy_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *options = NULL;
- char *exten = NULL;
- char *context = NULL;
- char *argv[2];
- char *mygroup = NULL;
- char *recbase = NULL;
- int fd = 0;
- struct ast_flags flags;
- int oldwf = 0;
- int argc = 0;
- int volfactor = 0;
- int res;
-
- data = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
-
- if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
- context = argv[0];
- if (!ast_strlen_zero(argv[0]))
- exten = strsep(&context, "@");
- if (ast_strlen_zero(context))
- context = ast_strdupa(chan->context);
- if (argc > 1)
- options = argv[1];
- }
-
- if (options) {
- char *opts[OPT_ARG_ARRAY_SIZE];
-
- ast_app_parse_options(spy_opts, &flags, opts, options);
- if (ast_test_flag(&flags, OPTION_GROUP))
- mygroup = opts[OPT_ARG_GROUP];
-
- if (ast_test_flag(&flags, OPTION_RECORD) &&
- !(recbase = opts[OPT_ARG_RECORD]))
- recbase = "chanspy";
-
- if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
- int vol;
-
- if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
- ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
- else
- volfactor = vol;
- }
-
- if (ast_test_flag(&flags, OPTION_PRIVATE))
- ast_set_flag(&flags, OPTION_WHISPER);
- } else
- ast_clear_flag(&flags, AST_FLAGS_ALL);
-
- oldwf = chan->writeformat;
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
- ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if (recbase) {
- char filename[PATH_MAX];
-
- snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
- if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644)) <= 0) {
- ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
- fd = 0;
- }
- }
-
- res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, exten, context);
-
- if (fd)
- close(fd);
-
- if (oldwf && ast_set_write_format(chan, oldwf) < 0)
- ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_unregister_application(app_chan);
- res |= ast_unregister_application(app_ext);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_register_application(app_chan, chanspy_exec, tdesc, desc_chan);
- res |= ast_register_application(app_ext, extenspy_exec, tdesc, desc_ext);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");
diff --git a/1.4/apps/app_controlplayback.c b/1.4/apps/app_controlplayback.c
deleted file mode 100644
index 6f2c03315..000000000
--- a/1.4/apps/app_controlplayback.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Trivial application to control playback of a sound file
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/app.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-
-static const char *app = "ControlPlayback";
-
-static const char *synopsis = "Play a file with fast forward and rewind";
-
-static const char *descrip =
-" ControlPlayback(file[|skipms[|ff[|rew[|stop[|pause[|restart|options]]]]]]]):\n"
-"This application will play back the given filename. By default, the '*' key\n"
-"can be used to rewind, and the '#' key can be used to fast-forward.\n"
-"Parameters:\n"
-" skipms - This is number of milliseconds to skip when rewinding or\n"
-" fast-forwarding.\n"
-" ff - Fast-forward when this DTMF digit is received.\n"
-" rew - Rewind when this DTMF digit is received.\n"
-" stop - Stop playback when this DTMF digit is received.\n"
-" pause - Pause playback when this DTMF digit is received.\n"
-" restart - Restart playback when this DTMF digit is received.\n"
-"Options:\n"
-" j - Jump to priority n+101 if the requested file is not found.\n"
-"This application sets the following channel variable upon completion:\n"
-" CPLAYBACKSTATUS - This variable contains the status of the attempt as a text\n"
-" string, one of: SUCCESS | USERSTOPPED | ERROR\n";
-
-
-static int is_on_phonepad(char key)
-{
- return key == 35 || key == 42 || (key >= 48 && key <= 57);
-}
-
-static int controlplayback_exec(struct ast_channel *chan, void *data)
-{
- int res = 0, priority_jump = 0;
- int skipms = 0;
- struct ast_module_user *u;
- char *tmp;
- int argc;
- char *argv[8];
- enum arg_ids {
- arg_file = 0,
- arg_skip = 1,
- arg_fwd = 2,
- arg_rev = 3,
- arg_stop = 4,
- arg_pause = 5,
- arg_restart = 6,
- options = 7,
- };
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- tmp = ast_strdupa(data);
- memset(argv, 0, sizeof(argv));
-
- argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
-
- if (argc < 1) {
- ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- skipms = argv[arg_skip] ? atoi(argv[arg_skip]) : 3000;
- if (!skipms)
- skipms = 3000;
-
- if (!argv[arg_fwd] || !is_on_phonepad(*argv[arg_fwd]))
- argv[arg_fwd] = "#";
- if (!argv[arg_rev] || !is_on_phonepad(*argv[arg_rev]))
- argv[arg_rev] = "*";
- if (argv[arg_stop] && !is_on_phonepad(*argv[arg_stop]))
- argv[arg_stop] = NULL;
- if (argv[arg_pause] && !is_on_phonepad(*argv[arg_pause]))
- argv[arg_pause] = NULL;
- if (argv[arg_restart] && !is_on_phonepad(*argv[arg_restart]))
- argv[arg_restart] = NULL;
-
- if (argv[options]) {
- if (strchr(argv[options], 'j'))
- priority_jump = 1;
- }
-
- res = ast_control_streamfile(chan, argv[arg_file], argv[arg_fwd], argv[arg_rev], argv[arg_stop], argv[arg_pause], argv[arg_restart], skipms);
-
- /* If we stopped on one of our stop keys, return 0 */
- if (res > 0 && argv[arg_stop] && strchr(argv[arg_stop], res)) {
- res = 0;
- pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
- } else {
- if (res < 0) {
- if (priority_jump || ast_opt_priority_jumping) {
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
- ast_log(LOG_WARNING, "ControlPlayback tried to jump to priority n+101 as requested, but priority didn't exist\n");
- }
- }
- res = 0;
- pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "ERROR");
- } else
- pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS");
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
- res = ast_unregister_application(app);
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, controlplayback_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Control Playback Application");
diff --git a/1.4/apps/app_db.c b/1.4/apps/app_db.c
deleted file mode 100644
index 0c8d0585b..000000000
--- a/1.4/apps/app_db.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- * Copyright (C) 2003, Jefferson Noxon
- *
- * Mark Spencer <markster@digium.com>
- * Jefferson Noxon <jeff@debian.org>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Database access functions
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Jefferson Noxon <jeff@debian.org>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "asterisk/options.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/astdb.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-
-/*! \todo XXX Remove this application after 1.4 is relased */
-static char *d_descrip =
-" DBdel(family/key): This application will delete a key from the Asterisk\n"
-"database.\n"
-" This application has been DEPRECATED in favor of the DB_DELETE function.\n";
-
-static char *dt_descrip =
-" DBdeltree(family[/keytree]): This application will delete a family or keytree\n"
-"from the Asterisk database\n";
-
-static char *d_app = "DBdel";
-static char *dt_app = "DBdeltree";
-
-static char *d_synopsis = "Delete a key from the database";
-static char *dt_synopsis = "Delete a family or keytree from the database";
-
-
-static int deltree_exec(struct ast_channel *chan, void *data)
-{
- char *argv, *family, *keytree;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- argv = ast_strdupa(data);
-
- if (strchr(argv, '/')) {
- family = strsep(&argv, "/");
- keytree = strsep(&argv, "\0");
- if (!family || !keytree) {
- ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
- ast_module_user_remove(u);
- return 0;
- }
- if (ast_strlen_zero(keytree))
- keytree = 0;
- } else {
- family = argv;
- keytree = 0;
- }
-
- if (option_verbose > 2) {
- if (keytree)
- ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: family=%s, keytree=%s\n", family, keytree);
- else
- ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: family=%s\n", family);
- }
-
- if (ast_db_deltree(family, keytree)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "DBdeltree: Error deleting key from database.\n");
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int del_exec(struct ast_channel *chan, void *data)
-{
- char *argv, *family, *key;
- struct ast_module_user *u;
- static int deprecation_warning = 0;
-
- u = ast_module_user_add(chan);
-
- if (!deprecation_warning) {
- deprecation_warning = 1;
- ast_log(LOG_WARNING, "The DBdel application has been deprecated in favor of the DB_DELETE dialplan function!\n");
- }
-
- argv = ast_strdupa(data);
-
- if (strchr(argv, '/')) {
- family = strsep(&argv, "/");
- key = strsep(&argv, "\0");
- if (!family || !key) {
- ast_log(LOG_DEBUG, "Ignoring; Syntax error in argument\n");
- ast_module_user_remove(u);
- return 0;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "DBdel: family=%s, key=%s\n", family, key);
- if (ast_db_del(family, key)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "DBdel: Error deleting key from database.\n");
- }
- } else {
- ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int retval;
-
- retval = ast_unregister_application(dt_app);
- retval |= ast_unregister_application(d_app);
-
- return retval;
-}
-
-static int load_module(void)
-{
- int retval;
-
- retval = ast_register_application(d_app, del_exec, d_synopsis, d_descrip);
- retval |= ast_register_application(dt_app, deltree_exec, dt_synopsis, dt_descrip);
-
- return retval;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Database Access Functions");
diff --git a/1.4/apps/app_dial.c b/1.4/apps/app_dial.c
deleted file mode 100644
index e9189b4bf..000000000
--- a/1.4/apps/app_dial.c
+++ /dev/null
@@ -1,1894 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>chan_local</depend>
- ***/
-
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/say.h"
-#include "asterisk/config.h"
-#include "asterisk/features.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/callerid.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/causes.h"
-#include "asterisk/rtp.h"
-#include "asterisk/cdr.h"
-#include "asterisk/manager.h"
-#include "asterisk/privacy.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/global_datastores.h"
-
-static char *app = "Dial";
-
-static char *synopsis = "Place a call and connect to the current channel";
-
-static char *descrip =
-" Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
-"This application will place calls to one or more specified channels. As soon\n"
-"as one of the requested channels answers, the originating channel will be\n"
-"answered, if it has not already been answered. These two channels will then\n"
-"be active in a bridged call. All other channels that were requested will then\n"
-"be hung up.\n"
-" Unless there is a timeout specified, the Dial application will wait\n"
-"indefinitely until one of the called channels answers, the user hangs up, or\n"
-"if all of the called channels are busy or unavailable. Dialplan executing will\n"
-"continue if no requested channels can be called, or if the timeout expires.\n\n"
-" This application sets the following channel variables upon completion:\n"
-" DIALEDTIME - This is the time from dialing a channel until when it\n"
-" is disconnected.\n"
-" ANSWEREDTIME - This is the amount of time for actual call.\n"
-" DIALSTATUS - This is the status of the call:\n"
-" CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
-" DONTCALL | TORTURE | INVALIDARGS\n"
-" For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
-"DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
-"script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
-"wants to send the caller to the 'torture' script.\n"
-" This application will report normal termination if the originating channel\n"
-"hangs up, or if the call is bridged and either of the parties in the bridge\n"
-"ends the call.\n"
-" The optional URL will be sent to the called party if the channel supports it.\n"
-" If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
-"application will be put into that group (as in Set(GROUP()=...).\n"
-" If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
-"application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
-"however, the variable will be unset after use.\n\n"
-" Options:\n"
-" A(x) - Play an announcement to the called party, using 'x' as the file.\n"
-" C - Reset the CDR for this call.\n"
-" d - Allow the calling user to dial a 1 digit extension while waiting for\n"
-" a call to be answered. Exit to that extension if it exists in the\n"
-" current context, or the context defined in the EXITCONTEXT variable,\n"
-" if it exists.\n"
-" D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
-" party has answered, but before the call gets bridged. The 'called'\n"
-" DTMF string is sent to the called party, and the 'calling' DTMF\n"
-" string is sent to the calling party. Both parameters can be used\n"
-" alone.\n"
-" f - Force the callerid of the *calling* channel to be set as the\n"
-" extension associated with the channel using a dialplan 'hint'.\n"
-" For example, some PSTNs do not allow CallerID to be set to anything\n"
-" other than the number assigned to the caller.\n"
-" g - Proceed with dialplan execution at the current extension if the\n"
-" destination channel hangs up.\n"
-" G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
-" the specified priority and the called party to the specified priority+1.\n"
-" Optionally, an extension, or extension and context may be specified. \n"
-" Otherwise, the current extension is used. You cannot use any additional\n"
-" action post answer options in conjunction with this option.\n"
-" h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
-" H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
-" i - Asterisk will ignore any forwarding requests it may receive on this\n"
-" dial attempt.\n"
-" j - Jump to priority n+101 if all of the requested channels were busy.\n"
-" k - Allow the called party to enable parking of the call by sending\n"
-" the DTMF sequence defined for call parking in features.conf.\n"
-" K - Allow the calling party to enable parking of the call by sending\n"
-" the DTMF sequence defined for call parking in features.conf.\n"
-" L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
-" left. Repeat the warning every 'z' ms. The following special\n"
-" variables can be used with this option:\n"
-" * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
-" Play sounds to the caller.\n"
-" * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
-" Play sounds to the callee.\n"
-" * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
-" * LIMIT_CONNECT_FILE File to play when call begins.\n"
-" * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
-" The default is to say the time remaining.\n"
-" m([class]) - Provide hold music to the calling party until a requested\n"
-" channel answers. A specific MusicOnHold class can be\n"
-" specified.\n"
-" M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
-" to the calling channel. Arguments can be specified to the Macro\n"
-" using '^' as a delimeter. The Macro can set the variable\n"
-" MACRO_RESULT to specify the following actions after the Macro is\n"
-" finished executing.\n"
-" * ABORT Hangup both legs of the call.\n"
-" * CONGESTION Behave as if line congestion was encountered.\n"
-" * BUSY Behave as if a busy signal was encountered. This will also\n"
-" have the application jump to priority n+101 if the\n"
-" 'j' option is set.\n"
-" * CONTINUE Hangup the called party and allow the calling party\n"
-" to continue dialplan execution at the next priority.\n"
-" * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
-" specified priority. Optionally, an extension, or\n"
-" extension and priority can be specified.\n"
-" You cannot use any additional action post answer options in conjunction\n"
-" with this option. Also, pbx services are not run on the peer (called) channel,\n"
-" so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
-" n - This option is a modifier for the screen/privacy mode. It specifies\n"
-" that no introductions are to be saved in the priv-callerintros\n"
-" directory.\n"
-" N - This option is a modifier for the screen/privacy mode. It specifies\n"
-" that if callerID is present, do not screen the call.\n"
-" o - Specify that the CallerID that was present on the *calling* channel\n"
-" be set as the CallerID on the *called* channel. This was the\n"
-" behavior of Asterisk 1.0 and earlier.\n"
-" O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
-" only, if specified on non-Zaptel interface, it will be ignored).\n"
-" When the destination answers (presumably an operator services\n"
-" station), the originator no longer has control of their line.\n"
-" They may hang up, but the switch will not release their line\n"
-" until the destination party hangs up (the operator). Specified\n"
-" without an arg, or with 1 as an arg, the originator hanging up\n"
-" will cause the phone to ring back immediately. With a 2 specified,\n"
-" when the \"operator\" flashes the trunk, it will ring their phone\n"
-" back.\n"
-" p - This option enables screening mode. This is basically Privacy mode\n"
-" without memory.\n"
-" P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
-" it is provided. The current extension is used if a database\n"
-" family/key is not specified.\n"
-" r - Indicate ringing to the calling party. Pass no audio to the calling\n"
-" party until the called channel has answered.\n"
-" S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
-" answered the call.\n"
-" t - Allow the called party to transfer the calling party by sending the\n"
-" DTMF sequence defined in features.conf.\n"
-" T - Allow the calling party to transfer the called party by sending the\n"
-" DTMF sequence defined in features.conf.\n"
-" w - Allow the called party to enable recording of the call by sending\n"
-" the DTMF sequence defined for one-touch recording in features.conf.\n"
-" W - Allow the calling party to enable recording of the call by sending\n"
-" the DTMF sequence defined for one-touch recording in features.conf.\n";
-
-/* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
-static char *rapp = "RetryDial";
-static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
-static char *rdescrip =
-" RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
-"place a call using the normal Dial application. If no channel can be reached,\n"
-"the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
-"seconds before retying the call. After 'retires' number of attempts, the\n"
-"calling channel will continue at the next priority in the dialplan. If the\n"
-"'retries' setting is set to 0, this application will retry endlessly.\n"
-" While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
-"extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
-"one, The call will jump to that extension immediately.\n"
-" The 'dialargs' are specified in the same format that arguments are provided\n"
-"to the Dial application.\n";
-
-enum {
- OPT_ANNOUNCE = (1 << 0),
- OPT_RESETCDR = (1 << 1),
- OPT_DTMF_EXIT = (1 << 2),
- OPT_SENDDTMF = (1 << 3),
- OPT_FORCECLID = (1 << 4),
- OPT_GO_ON = (1 << 5),
- OPT_CALLEE_HANGUP = (1 << 6),
- OPT_CALLER_HANGUP = (1 << 7),
- OPT_PRIORITY_JUMP = (1 << 8),
- OPT_DURATION_LIMIT = (1 << 9),
- OPT_MUSICBACK = (1 << 10),
- OPT_CALLEE_MACRO = (1 << 11),
- OPT_SCREEN_NOINTRO = (1 << 12),
- OPT_SCREEN_NOCLID = (1 << 13),
- OPT_ORIGINAL_CLID = (1 << 14),
- OPT_SCREENING = (1 << 15),
- OPT_PRIVACY = (1 << 16),
- OPT_RINGBACK = (1 << 17),
- OPT_DURATION_STOP = (1 << 18),
- OPT_CALLEE_TRANSFER = (1 << 19),
- OPT_CALLER_TRANSFER = (1 << 20),
- OPT_CALLEE_MONITOR = (1 << 21),
- OPT_CALLER_MONITOR = (1 << 22),
- OPT_GOTO = (1 << 23),
- OPT_OPERMODE = (1 << 24),
- OPT_CALLEE_PARK = (1 << 25),
- OPT_CALLER_PARK = (1 << 26),
- OPT_IGNORE_FORWARDING = (1 << 27),
-} dial_exec_option_flags;
-
-#define DIAL_STILLGOING (1 << 30)
-#define DIAL_NOFORWARDHTML (1 << 31)
-
-enum {
- OPT_ARG_ANNOUNCE = 0,
- OPT_ARG_SENDDTMF,
- OPT_ARG_GOTO,
- OPT_ARG_DURATION_LIMIT,
- OPT_ARG_MUSICBACK,
- OPT_ARG_CALLEE_MACRO,
- OPT_ARG_PRIVACY,
- OPT_ARG_DURATION_STOP,
- OPT_ARG_OPERMODE,
- /* note: this entry _MUST_ be the last one in the enum */
- OPT_ARG_ARRAY_SIZE,
-} dial_exec_option_args;
-
-AST_APP_OPTIONS(dial_exec_options, {
- AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
- AST_APP_OPTION('C', OPT_RESETCDR),
- AST_APP_OPTION('d', OPT_DTMF_EXIT),
- AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
- AST_APP_OPTION('f', OPT_FORCECLID),
- AST_APP_OPTION('g', OPT_GO_ON),
- AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
- AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
- AST_APP_OPTION('H', OPT_CALLER_HANGUP),
- AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
- AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
- AST_APP_OPTION('k', OPT_CALLEE_PARK),
- AST_APP_OPTION('K', OPT_CALLER_PARK),
- AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
- AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
- AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
- AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
- AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
- AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
- AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
- AST_APP_OPTION('p', OPT_SCREENING),
- AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
- AST_APP_OPTION('r', OPT_RINGBACK),
- AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
- AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
- AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
- AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
- AST_APP_OPTION('W', OPT_CALLER_MONITOR),
-});
-
-#define CAN_EARLY_BRIDGE(flags) (!ast_test_flag(flags, OPT_CALLEE_HANGUP | \
- OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
- OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK))
-
-/* We define a custom "local user" structure because we
- use it not only for keeping track of what is in use but
- also for keeping track of who we're dialing. */
-
-struct dial_localuser {
- struct ast_channel *chan;
- unsigned int flags;
- struct dial_localuser *next;
-};
-
-
-static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
-{
- /* Hang up a tree of stuff */
- struct dial_localuser *oo;
- while (outgoing) {
- /* Hangup any existing lines we have open */
- if (outgoing->chan && (outgoing->chan != exception))
- ast_hangup(outgoing->chan);
- oo = outgoing;
- outgoing=outgoing->next;
- free(oo);
- }
-}
-
-#define AST_MAX_WATCHERS 256
-
-#define HANDLE_CAUSE(cause, chan) do { \
- switch(cause) { \
- case AST_CAUSE_BUSY: \
- if (chan->cdr) \
- ast_cdr_busy(chan->cdr); \
- numbusy++; \
- break; \
- case AST_CAUSE_CONGESTION: \
- if (chan->cdr) \
- ast_cdr_failed(chan->cdr); \
- numcongestion++; \
- break; \
- case AST_CAUSE_UNREGISTERED: \
- if (chan->cdr) \
- ast_cdr_failed(chan->cdr); \
- numnochan++; \
- break; \
- case AST_CAUSE_NORMAL_CLEARING: \
- break; \
- default: \
- numnochan++; \
- break; \
- } \
-} while (0)
-
-
-static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
-{
- char rexten[2] = { exten, '\0' };
-
- if (context) {
- if (!ast_goto_if_exists(chan, context, rexten, pri))
- return 1;
- } else {
- if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
- return 1;
- else if (!ast_strlen_zero(chan->macrocontext)) {
- if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
- return 1;
- }
- }
- return 0;
-}
-
-
-static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
-{
- const char *context = S_OR(chan->macrocontext, chan->context);
- const char *exten = S_OR(chan->macroexten, chan->exten);
-
- return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
-}
-
-static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
-{
- /* XXX do we need also CallerIDnum ? */
- manager_event(EVENT_FLAG_CALL, "Dial",
- "Source: %s\r\n"
- "Destination: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n"
- "SrcUniqueID: %s\r\n"
- "DestUniqueID: %s\r\n",
- src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
- S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
- dst->uniqueid);
-}
-
-static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
-{
- int numbusy = busystart;
- int numcongestion = congestionstart;
- int numnochan = nochanstart;
- int prestart = busystart + congestionstart + nochanstart;
- int orig = *to;
- struct ast_channel *peer = NULL;
- /* single is set if only one destination is enabled */
- int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
-
- if (single) {
- /* Turn off hold music, etc */
- ast_deactivate_generator(in);
- /* If we are calling a single channel, make them compatible for in-band tone purpose */
- ast_channel_make_compatible(outgoing->chan, in);
- }
-
-
- while (*to && !peer) {
- struct dial_localuser *o;
- int pos = 0; /* how many channels do we handle */
- int numlines = prestart;
- struct ast_channel *winner;
- struct ast_channel *watchers[AST_MAX_WATCHERS];
-
- watchers[pos++] = in;
- for (o = outgoing; o; o = o->next) {
- /* Keep track of important channels */
- if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
- watchers[pos++] = o->chan;
- numlines++;
- }
- if (pos == 1) { /* only the input channel is available */
- if (numlines == (numbusy + numcongestion + numnochan)) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
- if (numbusy)
- strcpy(status, "BUSY");
- else if (numcongestion)
- strcpy(status, "CONGESTION");
- else if (numnochan)
- strcpy(status, "CHANUNAVAIL");
- if (ast_opt_priority_jumping || priority_jump)
- ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
- }
- *to = 0;
- return NULL;
- }
- winner = ast_waitfor_n(watchers, pos, to);
- for (o = outgoing; o; o = o->next) {
- struct ast_frame *f;
- struct ast_channel *c = o->chan;
-
- if (c == NULL)
- continue;
- if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
- if (!peer) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
- peer = c;
- ast_copy_flags(peerflags, o,
- OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
- OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
- OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
- OPT_CALLEE_PARK | OPT_CALLER_PARK |
- DIAL_NOFORWARDHTML);
- ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
- ast_copy_string(c->exten, "", sizeof(c->exten));
- }
- continue;
- }
- if (c != winner)
- continue;
- if (!ast_strlen_zero(c->call_forward)) {
- char tmpchan[256];
- char *stuff;
- char *tech;
- int cause;
-
- ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
- if ((stuff = strchr(tmpchan, '/'))) {
- *stuff++ = '\0';
- tech = tmpchan;
- } else {
- const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
- snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
- stuff = tmpchan;
- tech = "Local";
- }
- /* Before processing channel, go ahead and check for forwarding */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
- /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
- if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
- c = o->chan = NULL;
- cause = AST_CAUSE_BUSY;
- } else {
- /* Setup parameters */
- if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) {
- if (single)
- ast_channel_make_compatible(o->chan, in);
- ast_channel_inherit_variables(in, o->chan);
- ast_channel_datastore_inherit(in, o->chan);
- } else
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
- }
- if (!c) {
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(cause, in);
- } else {
- ast_rtp_make_compatible(c, in, single);
- if (c->cid.cid_num)
- free(c->cid.cid_num);
- c->cid.cid_num = NULL;
- if (c->cid.cid_name)
- free(c->cid.cid_name);
- c->cid.cid_name = NULL;
-
- if (ast_test_flag(o, OPT_FORCECLID)) {
- c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
- ast_string_field_set(c, accountcode, winner->accountcode);
- c->cdrflags = winner->cdrflags;
- } else {
- c->cid.cid_num = ast_strdup(in->cid.cid_num);
- c->cid.cid_name = ast_strdup(in->cid.cid_name);
- ast_string_field_set(c, accountcode, in->accountcode);
- c->cdrflags = in->cdrflags;
- }
-
- if (in->cid.cid_ani) {
- if (c->cid.cid_ani)
- free(c->cid.cid_ani);
- c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
- }
- if (c->cid.cid_rdnis)
- free(c->cid.cid_rdnis);
- c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
- if (ast_call(c, tmpchan, 0)) {
- ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
- ast_clear_flag(o, DIAL_STILLGOING);
- ast_hangup(c);
- c = o->chan = NULL;
- numnochan++;
- } else {
- senddialevent(in, c);
- /* After calling, set callerid to extension */
- if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
- char cidname[AST_MAX_EXTENSION] = "";
- ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
- }
- }
- }
- /* Hangup the original channel now, in case we needed it */
- ast_hangup(winner);
- continue;
- }
- f = ast_read(winner);
- if (!f) {
- in->hangupcause = c->hangupcause;
- ast_hangup(c);
- c = o->chan = NULL;
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(in->hangupcause, in);
- continue;
- }
- if (f->frametype == AST_FRAME_CONTROL) {
- switch(f->subclass) {
- case AST_CONTROL_ANSWER:
- /* This is our guy if someone answered. */
- if (!peer) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
- peer = c;
- ast_copy_flags(peerflags, o,
- OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
- OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
- OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
- OPT_CALLEE_PARK | OPT_CALLER_PARK |
- DIAL_NOFORWARDHTML);
- ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
- ast_copy_string(c->exten, "", sizeof(c->exten));
- /* Setup RTP early bridge if appropriate */
- if (CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, peer);
- }
- /* If call has been answered, then the eventual hangup is likely to be normal hangup */
- in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
- in->hangupcause = c->hangupcause;
- ast_hangup(c);
- c = o->chan = NULL;
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(AST_CAUSE_BUSY, in);
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
- in->hangupcause = c->hangupcause;
- ast_hangup(c);
- c = o->chan = NULL;
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
- /* Setup early media if appropriate */
- if (single && CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, c);
- if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
- ast_indicate(in, AST_CONTROL_RINGING);
- (*sentringing)++;
- }
- break;
- case AST_CONTROL_PROGRESS:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
- /* Setup early media if appropriate */
- if (single && CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, c);
- if (!ast_test_flag(outgoing, OPT_RINGBACK))
- ast_indicate(in, AST_CONTROL_PROGRESS);
- break;
- case AST_CONTROL_VIDUPDATE:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
- ast_indicate(in, AST_CONTROL_VIDUPDATE);
- break;
- case AST_CONTROL_SRCUPDATE:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name);
- ast_indicate(in, AST_CONTROL_SRCUPDATE);
- break;
- case AST_CONTROL_PROCEEDING:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
- if (single && CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, c);
- if (!ast_test_flag(outgoing, OPT_RINGBACK))
- ast_indicate(in, AST_CONTROL_PROCEEDING);
- break;
- case AST_CONTROL_HOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
- ast_indicate(in, AST_CONTROL_HOLD);
- break;
- case AST_CONTROL_UNHOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
- ast_indicate(in, AST_CONTROL_UNHOLD);
- break;
- case AST_CONTROL_OFFHOOK:
- case AST_CONTROL_FLASH:
- /* Ignore going off hook and flash */
- break;
- case -1:
- if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
- ast_indicate(in, -1);
- (*sentringing) = 0;
- }
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
- }
- } else if (single) {
- /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
- if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
- if (ast_write(in, f))
- ast_log(LOG_WARNING, "Unable to forward voice frame\n");
- } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
- if (ast_write(in, f))
- ast_log(LOG_WARNING, "Unable to forward image\n");
- } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
- if (ast_write(in, f))
- ast_log(LOG_WARNING, "Unable to send text\n");
- } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
- if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
- ast_log(LOG_WARNING, "Unable to send URL\n");
- }
- }
- ast_frfree(f);
- } /* end for */
- if (winner == in) {
- struct ast_frame *f = ast_read(in);
-#if 0
- if (f && (f->frametype != AST_FRAME_VOICE))
- printf("Frame type: %d, %d\n", f->frametype, f->subclass);
- else if (!f || (f->frametype != AST_FRAME_VOICE))
- printf("Hangup received on %s\n", in->name);
-#endif
- if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
- /* Got hung up */
- *to = -1;
- ast_cdr_noanswer(in->cdr);
- strcpy(status, "CANCEL");
- if (f)
- ast_frfree(f);
- return NULL;
- }
-
- if (f && (f->frametype == AST_FRAME_DTMF)) {
- if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
- const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
- if (onedigit_goto(in, context, (char) f->subclass, 1)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
- *to=0;
- ast_cdr_noanswer(in->cdr);
- *result = f->subclass;
- strcpy(status, "CANCEL");
- ast_frfree(f);
- return NULL;
- }
- }
-
- if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
- (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
- *to=0;
- ast_cdr_noanswer(in->cdr);
- strcpy(status, "CANCEL");
- ast_frfree(f);
- return NULL;
- }
- }
-
- /* Forward HTML stuff */
- if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
- if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
- ast_log(LOG_WARNING, "Unable to send URL\n");
-
-
- if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
- if (ast_write(outgoing->chan, f))
- ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
- }
- if (single && (f->frametype == AST_FRAME_CONTROL) &&
- ((f->subclass == AST_CONTROL_HOLD) ||
- (f->subclass == AST_CONTROL_UNHOLD) ||
- (f->subclass == AST_CONTROL_VIDUPDATE) ||
- (f->subclass == AST_CONTROL_SRCUPDATE))) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
- ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
- }
- ast_frfree(f);
- }
- if (!*to && (option_verbose > 2))
- ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
- if (!*to || ast_check_hangup(in)) {
- ast_cdr_noanswer(in->cdr);
- }
-
- }
-
- return peer;
-}
-
-static void replace_macro_delimiter(char *s)
-{
- for (; *s; s++)
- if (*s == '^')
- *s = '|';
-}
-
-
-/* returns true if there is a valid privacy reply */
-static int valid_priv_reply(struct ast_flags *opts, int res)
-{
- if (res < '1')
- return 0;
- if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
- return 1;
- if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
- return 1;
- return 0;
-}
-
-static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
-{
- int res = -1;
- struct ast_module_user *u;
- char *rest, *cur;
- struct dial_localuser *outgoing = NULL;
- struct ast_channel *peer;
- int to;
- int numbusy = 0;
- int numcongestion = 0;
- int numnochan = 0;
- int cause;
- char numsubst[256];
- char cidname[AST_MAX_EXTENSION] = "";
- int privdb_val = 0;
- unsigned int calldurationlimit = 0;
- long timelimit = 0;
- long play_warning = 0;
- long warning_freq = 0;
- const char *warning_sound = NULL;
- const char *end_sound = NULL;
- const char *start_sound = NULL;
- char *dtmfcalled = NULL, *dtmfcalling = NULL;
- char status[256] = "INVALIDARGS";
- int play_to_caller = 0, play_to_callee = 0;
- int sentringing = 0, moh = 0;
- const char *outbound_group = NULL;
- int result = 0;
- time_t start_time;
- char privintro[1024];
- char privcid[256];
- char *parse;
- int opermode = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(peers);
- AST_APP_ARG(timeout);
- AST_APP_ARG(options);
- AST_APP_ARG(url);
- );
- struct ast_flags opts = { 0, };
- char *opt_args[OPT_ARG_ARRAY_SIZE];
- struct ast_datastore *datastore = NULL;
- int fulldial = 0, num_dialed = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
- pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (!ast_strlen_zero(args.options) &&
- ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
- pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
- goto done;
- }
-
- if (ast_strlen_zero(args.peers)) {
- ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
- pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
- goto done;
- }
-
- if (ast_test_flag(&opts, OPT_OPERMODE)) {
- if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
- opermode = 1;
- else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
- }
-
- if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
- calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
- if (!calldurationlimit) {
- ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
- pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
- goto done;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
- }
-
- if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
- dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
- dtmfcalled = strsep(&dtmfcalling, ":");
- }
-
- if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
- char *limit_str, *warning_str, *warnfreq_str;
- const char *var;
-
- warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
- limit_str = strsep(&warnfreq_str, ":");
- warning_str = strsep(&warnfreq_str, ":");
-
- timelimit = atol(limit_str);
- if (warning_str)
- play_warning = atol(warning_str);
- if (warnfreq_str)
- warning_freq = atol(warnfreq_str);
-
- if (!timelimit) {
- ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
- goto done;
- } else if (play_warning > timelimit) {
- /* If the first warning is requested _after_ the entire call would end,
- and no warning frequency is requested, then turn off the warning. If
- a warning frequency is requested, reduce the 'first warning' time by
- that frequency until it falls within the call's total time limit.
- */
-
- if (!warning_freq) {
- play_warning = 0;
- } else {
- /* XXX fix this!! */
- while (play_warning > timelimit)
- play_warning -= warning_freq;
- if (play_warning < 1)
- play_warning = warning_freq = 0;
- }
- }
-
- var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
- play_to_caller = var ? ast_true(var) : 1;
-
- var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
- play_to_callee = var ? ast_true(var) : 0;
-
- if (!play_to_caller && !play_to_callee)
- play_to_caller = 1;
-
- var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
- warning_sound = S_OR(var, "timeleft");
-
- var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
- end_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
-
- var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
- start_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
-
- /* undo effect of S(x) in case they are both used */
- calldurationlimit = 0;
- /* more efficient to do it like S(x) does since no advanced opts */
- if (!play_warning && !start_sound && !end_sound && timelimit) {
- calldurationlimit = timelimit / 1000;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
- timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
- } else if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
- ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", timelimit);
- ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", play_warning);
- ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
- ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
- ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", warning_freq);
- ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", start_sound);
- ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", warning_sound);
- ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", end_sound);
- }
- }
-
- if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
- ast_cdr_reset(chan->cdr, NULL);
- if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
- opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
- if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
- char callerid[60];
- char *l = chan->cid.cid_num; /* XXX watch out, we are overwriting it */
- if (!ast_strlen_zero(l)) {
- ast_shrink_phone_number(l);
- if( ast_test_flag(&opts, OPT_PRIVACY) ) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
- opt_args[OPT_ARG_PRIVACY], l);
- privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
- }
- else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
- privdb_val = AST_PRIVACY_UNKNOWN;
- }
- } else {
- char *tnam, *tn2;
-
- tnam = ast_strdupa(chan->name);
- /* clean the channel name so slashes don't try to end up in disk file name */
- for(tn2 = tnam; *tn2; tn2++) {
- if( *tn2=='/')
- *tn2 = '='; /* any other chars to be afraid of? */
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
-
- snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
- l = callerid;
- privdb_val = AST_PRIVACY_UNKNOWN;
- }
-
- ast_copy_string(privcid,l,sizeof(privcid));
-
- if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", privcid);
- privdb_val = AST_PRIVACY_ALLOW;
- }
- else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
- }
-
- if(privdb_val == AST_PRIVACY_DENY ) {
- ast_copy_string(status, "NOANSWER", sizeof(status));
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
- res=0;
- goto out;
- }
- else if(privdb_val == AST_PRIVACY_KILL ) {
- ast_copy_string(status, "DONTCALL", sizeof(status));
- if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
- }
- res = 0;
- goto out; /* Is this right? */
- }
- else if(privdb_val == AST_PRIVACY_TORTURE ) {
- ast_copy_string(status, "TORTURE", sizeof(status));
- if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
- }
- res = 0;
- goto out; /* is this right??? */
- }
- else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
- /* Get the user's intro, store it in priv-callerintros/$CID,
- unless it is already there-- this should be done before the
- call is actually dialed */
-
- /* make sure the priv-callerintros dir actually exists */
- snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
- if (mkdir(privintro, 0755) && errno != EEXIST) {
- ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
- res = -1;
- goto out;
- }
-
- snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
- if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
- /* the DELUX version of this code would allow this caller the
- option to hear and retape their previously recorded intro.
- */
- }
- else {
- int duration; /* for feedback from play_and_wait */
- /* the file doesn't exist yet. Let the caller submit his
- vocal intro for posterity */
- /* priv-recordintro script:
-
- "At the tone, please say your name:"
-
- */
- ast_answer(chan);
- res = ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
- /* don't think we'll need a lock removed, we took care of
- conflicts by naming the privintro file */
- if (res == -1) {
- /* Delete the file regardless since they hung up during recording */
- ast_filedelete(privintro, NULL);
- if( ast_fileexists(privintro,NULL,NULL ) > 0 )
- ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
- else if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
- goto out;
- }
- if( !ast_streamfile(chan, "vm-dialout", chan->language) )
- ast_waitstream(chan, "");
- }
- }
- }
-
- if (continue_exec)
- *continue_exec = 0;
-
- /* If a channel group has been specified, get it for use when we create peer channels */
- if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
- outbound_group = ast_strdupa(outbound_group);
- pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
- } else {
- outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
- }
-
- ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
- /* loop through the list of dial destinations */
- rest = args.peers;
- while ((cur = strsep(&rest, "&")) ) {
- struct dial_localuser *tmp;
- /* Get a technology/[device:]number pair */
- char *number = cur;
- char *interface = ast_strdupa(number);
- char *tech = strsep(&number, "/");
- /* find if we already dialed this interface */
- struct ast_dialed_interface *di;
- AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
- num_dialed++;
- if (!number) {
- ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
- goto out;
- }
- if (!(tmp = ast_calloc(1, sizeof(*tmp))))
- goto out;
- if (opts.flags) {
- ast_copy_flags(tmp, &opts,
- OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
- OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
- OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
- OPT_CALLEE_PARK | OPT_CALLER_PARK |
- OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
- ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
- }
- ast_copy_string(numsubst, number, sizeof(numsubst));
- /* Request the peer */
-
- ast_channel_lock(chan);
- datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
- ast_channel_unlock(chan);
-
- if (datastore)
- dialed_interfaces = datastore->data;
- else {
- if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
- ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
- free(tmp);
- goto out;
- }
-
- datastore->inheritance = DATASTORE_INHERIT_FOREVER;
-
- if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
- free(tmp);
- goto out;
- }
-
- datastore->data = dialed_interfaces;
- AST_LIST_HEAD_INIT(dialed_interfaces);
-
- ast_channel_lock(chan);
- ast_channel_datastore_add(chan, datastore);
- ast_channel_unlock(chan);
- }
-
- AST_LIST_LOCK(dialed_interfaces);
- AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
- if (!strcasecmp(di->interface, interface)) {
- ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
- di->interface);
- break;
- }
- }
- AST_LIST_UNLOCK(dialed_interfaces);
-
- if (di) {
- fulldial++;
- free(tmp);
- continue;
- }
-
- /* It is always ok to dial a Local interface. We only keep track of
- * which "real" interfaces have been dialed. The Local channel will
- * inherit this list so that if it ends up dialing a real interface,
- * it won't call one that has already been called. */
- if (strcasecmp(tech, "Local")) {
- if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
- AST_LIST_UNLOCK(dialed_interfaces);
- free(tmp);
- goto out;
- }
- strcpy(di->interface, interface);
-
- AST_LIST_LOCK(dialed_interfaces);
- AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
- AST_LIST_UNLOCK(dialed_interfaces);
- }
-
- tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
- if (!tmp->chan) {
- /* If we can't, just go on to the next call */
- ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
- HANDLE_CAUSE(cause, chan);
- if (!rest) /* we are on the last destination */
- chan->hangupcause = cause;
- free(tmp);
- continue;
- }
-
- pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
-
- /* Setup outgoing SDP to match incoming one */
- ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
-
- /* Inherit specially named variables from parent channel */
- ast_channel_inherit_variables(chan, tmp->chan);
-
- tmp->chan->appl = "AppDial";
- tmp->chan->data = "(Outgoing Line)";
- tmp->chan->whentohangup = 0;
-
- if (tmp->chan->cid.cid_num)
- free(tmp->chan->cid.cid_num);
- tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
-
- if (tmp->chan->cid.cid_name)
- free(tmp->chan->cid.cid_name);
- tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
-
- if (tmp->chan->cid.cid_ani)
- free(tmp->chan->cid.cid_ani);
- tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
-
- /* Copy language from incoming to outgoing */
- ast_string_field_set(tmp->chan, language, chan->language);
- ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
- tmp->chan->cdrflags = chan->cdrflags;
- if (ast_strlen_zero(tmp->chan->musicclass))
- ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
- /* XXX don't we free previous values ? */
- tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
- /* Pass callingpres setting */
- tmp->chan->cid.cid_pres = chan->cid.cid_pres;
- /* Pass type of number */
- tmp->chan->cid.cid_ton = chan->cid.cid_ton;
- /* Pass type of tns */
- tmp->chan->cid.cid_tns = chan->cid.cid_tns;
- /* Presense of ADSI CPE on outgoing channel follows ours */
- tmp->chan->adsicpe = chan->adsicpe;
- /* Pass the transfer capability */
- tmp->chan->transfercapability = chan->transfercapability;
-
- /* If we have an outbound group, set this peer channel to it */
- if (outbound_group)
- ast_app_group_set_channel(tmp->chan, outbound_group);
-
- /* Inherit context and extension */
- if (!ast_strlen_zero(chan->macrocontext))
- ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
- else
- ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
- if (!ast_strlen_zero(chan->macroexten))
- ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
- else
- ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
-
- /* Place the call, but don't wait on the answer */
- res = ast_call(tmp->chan, numsubst, 0);
-
- /* Save the info in cdr's that we called them */
- if (chan->cdr)
- ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
-
- /* check the results of ast_call */
- if (res) {
- /* Again, keep going even if there's an error */
- if (option_debug)
- ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
- ast_hangup(tmp->chan);
- tmp->chan = NULL;
- free(tmp);
- continue;
- } else {
- senddialevent(chan, tmp->chan);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
- if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
- ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
- }
- /* Put them in the list of outgoing thingies... We're ready now.
- XXX If we're forcibly removed, these outgoing calls won't get
- hung up XXX */
- ast_set_flag(tmp, DIAL_STILLGOING);
- tmp->next = outgoing;
- outgoing = tmp;
- /* If this line is up, don't try anybody else */
- if (outgoing->chan->_state == AST_STATE_UP)
- break;
- }
-
- if (ast_strlen_zero(args.timeout)) {
- to = -1;
- } else {
- to = atoi(args.timeout);
- if (to > 0)
- to *= 1000;
- else
- ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
- }
-
- if (!outgoing) {
- strcpy(status, "CHANUNAVAIL");
- if(fulldial == num_dialed) {
- res = -1;
- goto out;
- }
- } else {
- /* Our status will at least be NOANSWER */
- strcpy(status, "NOANSWER");
- if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
- moh = 1;
- if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
- char *original_moh = ast_strdupa(chan->musicclass);
- ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
- ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
- ast_string_field_set(chan, musicclass, original_moh);
- } else {
- ast_moh_start(chan, NULL, NULL);
- }
- ast_indicate(chan, AST_CONTROL_PROGRESS);
- } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
- ast_indicate(chan, AST_CONTROL_RINGING);
- sentringing++;
- }
- }
-
- time(&start_time);
- peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
-
- /* The ast_channel_datastore_remove() function could fail here if the
- * datastore was moved to another channel during a masquerade. If this is
- * the case, don't free the datastore here because later, when the channel
- * to which the datastore was moved hangs up, it will attempt to free this
- * datastore again, causing a crash
- */
- if (!ast_channel_datastore_remove(chan, datastore))
- ast_channel_datastore_free(datastore);
- if (!peer) {
- if (result) {
- res = result;
- } else if (to) { /* Musta gotten hung up */
- res = -1;
- } else { /* Nobody answered, next please? */
- res = 0;
- }
- /* almost done, although the 'else' block is 400 lines */
- } else {
- const char *number;
- time_t end_time, answer_time = time(NULL);
-
- strcpy(status, "ANSWER");
- /* Ah ha! Someone answered within the desired timeframe. Of course after this
- we will always return with -1 so that it is hung up properly after the
- conversation. */
- hanguptree(outgoing, peer);
- outgoing = NULL;
- /* If appropriate, log that we have a destination channel */
- if (chan->cdr)
- ast_cdr_setdestchan(chan->cdr, peer->name);
- if (peer->name)
- pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
-
- number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
- if (!number)
- number = numsubst;
- pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
- if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
- if (option_debug)
- ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
- ast_channel_sendurl( peer, args.url );
- }
- if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
- int res2;
- int loopcount = 0;
-
- /* Get the user's intro, store it in priv-callerintros/$CID,
- unless it is already there-- this should be done before the
- call is actually dialed */
-
- /* all ring indications and moh for the caller has been halted as soon as the
- target extension was picked up. We are going to have to kill some
- time and make the caller believe the peer hasn't picked up yet */
-
- if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
- char *original_moh = ast_strdupa(chan->musicclass);
- ast_indicate(chan, -1);
- ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
- ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
- ast_string_field_set(chan, musicclass, original_moh);
- } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
- ast_indicate(chan, AST_CONTROL_RINGING);
- sentringing++;
- }
-
- /* Start autoservice on the other chan ?? */
- res2 = ast_autoservice_start(chan);
- /* Now Stream the File */
- for (loopcount = 0; loopcount < 3; loopcount++) {
- if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
- break;
- if (!res2) /* on timeout, play the message again */
- res2 = ast_play_and_wait(peer,"priv-callpending");
- if (!valid_priv_reply(&opts, res2))
- res2 = 0;
- /* priv-callpending script:
- "I have a caller waiting, who introduces themselves as:"
- */
- if (!res2)
- res2 = ast_play_and_wait(peer,privintro);
- if (!valid_priv_reply(&opts, res2))
- res2 = 0;
- /* now get input from the called party, as to their choice */
- if( !res2 ) {
- /* XXX can we have both, or they are mutually exclusive ? */
- if( ast_test_flag(&opts, OPT_PRIVACY) )
- res2 = ast_play_and_wait(peer,"priv-callee-options");
- if( ast_test_flag(&opts, OPT_SCREENING) )
- res2 = ast_play_and_wait(peer,"screen-callee-options");
- }
- /*! \page DialPrivacy Dial Privacy scripts
- \par priv-callee-options script:
- "Dial 1 if you wish this caller to reach you directly in the future,
- and immediately connect to their incoming call
- Dial 2 if you wish to send this caller to voicemail now and
- forevermore.
- Dial 3 to send this caller to the torture menus, now and forevermore.
- Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
- Dial 5 to allow this caller to come straight thru to you in the future,
- but right now, just this once, send them to voicemail."
- \par screen-callee-options script:
- "Dial 1 if you wish to immediately connect to the incoming call
- Dial 2 if you wish to send this caller to voicemail.
- Dial 3 to send this caller to the torture menus.
- Dial 4 to send this caller to a simple "go away" menu.
- */
- if (valid_priv_reply(&opts, res2))
- break;
- /* invalid option */
- res2 = ast_play_and_wait(peer, "vm-sorry");
- }
-
- if (ast_test_flag(&opts, OPT_MUSICBACK)) {
- ast_moh_stop(chan);
- } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
- ast_indicate(chan, -1);
- sentringing=0;
- }
- ast_autoservice_stop(chan);
-
- switch (res2) {
- case '1':
- if( ast_test_flag(&opts, OPT_PRIVACY) ) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
- opt_args[OPT_ARG_PRIVACY], privcid);
- ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
- }
- break;
- case '2':
- if( ast_test_flag(&opts, OPT_PRIVACY) ) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
- opt_args[OPT_ARG_PRIVACY], privcid);
- ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
- }
- ast_copy_string(status, "NOANSWER", sizeof(status));
- ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
- res=0;
- goto out;
- case '3':
- if( ast_test_flag(&opts, OPT_PRIVACY) ) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
- opt_args[OPT_ARG_PRIVACY], privcid);
- ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
- }
- ast_copy_string(status, "TORTURE", sizeof(status));
-
- res = 0;
- ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
- goto out; /* Is this right? */
- case '4':
- if( ast_test_flag(&opts, OPT_PRIVACY) ) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
- opt_args[OPT_ARG_PRIVACY], privcid);
- ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
- }
-
- ast_copy_string(status, "DONTCALL", sizeof(status));
- res = 0;
- ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
- goto out; /* Is this right? */
- case '5':
- if( ast_test_flag(&opts, OPT_PRIVACY) ) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
- opt_args[OPT_ARG_PRIVACY], privcid);
- ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
- ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
- res=0;
- goto out;
- } /* if not privacy, then 5 is the same as "default" case */
- default: /* bad input or -1 if failure to start autoservice */
- /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
- /* well, there seems basically two choices. Just patch the caller thru immediately,
- or,... put 'em thru to voicemail. */
- /* since the callee may have hung up, let's do the voicemail thing, no database decision */
- ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
- ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
- res=0;
- goto out;
- }
-
- /* XXX once again, this path is only taken in the case '1', so it could be
- * moved there, although i am not really sure that this is correct - maybe
- * the check applies to other cases as well.
- */
- /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
- just clog things up, and it's not useful information, not being tied to a CID */
- if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
- ast_filedelete(privintro, NULL);
- if( ast_fileexists(privintro, NULL, NULL ) > 0 )
- ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
- else if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
- }
- }
- if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
- res = 0;
- } else {
- int digit = 0;
- /* Start autoservice on the other chan */
- res = ast_autoservice_start(chan);
- /* Now Stream the File */
- if (!res)
- res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
- if (!res) {
- digit = ast_waitstream(peer, AST_DIGIT_ANY);
- }
- /* Ok, done. stop autoservice */
- res = ast_autoservice_stop(chan);
- if (digit > 0 && !res)
- res = ast_senddigit(chan, digit);
- else
- res = digit;
-
- }
-
- if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
- replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
- ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
- /* peer goes to the same context and extension as chan, so just copy info from chan*/
- ast_copy_string(peer->context, chan->context, sizeof(peer->context));
- ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
- peer->priority = chan->priority + 2;
- ast_pbx_start(peer);
- hanguptree(outgoing, NULL);
- if (continue_exec)
- *continue_exec = 1;
- res = 0;
- goto done;
- }
-
- if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
- struct ast_app *theapp;
- const char *macro_result;
-
- res = ast_autoservice_start(chan);
- if (res) {
- ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
- res = -1;
- }
-
- theapp = pbx_findapp("Macro");
-
- if (theapp && !res) { /* XXX why check res here ? */
- replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
- res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
- ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
- res = 0;
- } else {
- ast_log(LOG_ERROR, "Could not find application Macro\n");
- res = -1;
- }
-
- if (ast_autoservice_stop(chan) < 0) {
- ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
- res = -1;
- }
-
- if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
- char *macro_transfer_dest;
-
- if (!strcasecmp(macro_result, "BUSY")) {
- ast_copy_string(status, macro_result, sizeof(status));
- if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
- if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
- ast_set_flag(peerflags, OPT_GO_ON);
- }
- } else
- ast_set_flag(peerflags, OPT_GO_ON);
- res = -1;
- } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
- ast_copy_string(status, macro_result, sizeof(status));
- ast_set_flag(peerflags, OPT_GO_ON);
- res = -1;
- } else if (!strcasecmp(macro_result, "CONTINUE")) {
- /* hangup peer and keep chan alive assuming the macro has changed
- the context / exten / priority or perhaps
- the next priority in the current exten is desired.
- */
- ast_set_flag(peerflags, OPT_GO_ON);
- res = -1;
- } else if (!strcasecmp(macro_result, "ABORT")) {
- /* Hangup both ends unless the caller has the g flag */
- res = -1;
- } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
- res = -1;
- /* perform a transfer to a new extension */
- if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
- replace_macro_delimiter(macro_transfer_dest);
- if (!ast_parseable_goto(chan, macro_transfer_dest))
- ast_set_flag(peerflags, OPT_GO_ON);
-
- }
- }
- }
- }
-
- if (!res) {
- if (calldurationlimit > 0) {
- peer->whentohangup = time(NULL) + calldurationlimit;
- }
- if (!ast_strlen_zero(dtmfcalled)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
- res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
- }
- if (!ast_strlen_zero(dtmfcalling)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
- res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
- }
- }
-
- if (!res) {
- struct ast_bridge_config config;
-
- memset(&config,0,sizeof(struct ast_bridge_config));
- if (play_to_caller)
- ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
- if (play_to_callee)
- ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
- if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
- ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
- if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
- ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
- if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
- ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
- if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
- ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
- if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
- ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
- if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
- ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
- if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
- ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
- if (ast_test_flag(peerflags, OPT_CALLER_PARK))
- ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
-
- config.timelimit = timelimit;
- config.play_warning = play_warning;
- config.warning_freq = warning_freq;
- config.warning_sound = warning_sound;
- config.end_sound = end_sound;
- config.start_sound = start_sound;
- if (moh) {
- moh = 0;
- ast_moh_stop(chan);
- } else if (sentringing) {
- sentringing = 0;
- ast_indicate(chan, -1);
- }
- /* Be sure no generators are left on it */
- ast_deactivate_generator(chan);
- /* Make sure channels are compatible */
- res = ast_channel_make_compatible(chan, peer);
- if (res < 0) {
- ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
- ast_hangup(peer);
- res = -1;
- goto done;
- }
- if (opermode && (!strncmp(chan->name,"Zap",3)) &&
- (!strncmp(peer->name,"Zap",3)))
- {
- struct oprmode oprmode;
-
- oprmode.peer = peer;
- oprmode.mode = opermode;
-
- ast_channel_setoption(chan,
- AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
- }
- res = ast_bridge_call(chan,peer,&config);
- time(&end_time);
- {
- char toast[80];
- snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
- pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
- }
- } else {
- time(&end_time);
- res = -1;
- }
- {
- char toast[80];
- snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
- pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
- }
-
- if (res != AST_PBX_NO_HANGUP_PEER) {
- if (!chan->_softhangup)
- chan->hangupcause = peer->hangupcause;
- ast_hangup(peer);
- }
- }
-out:
- if (moh) {
- moh = 0;
- ast_moh_stop(chan);
- } else if (sentringing) {
- sentringing = 0;
- ast_indicate(chan, -1);
- }
- ast_rtp_early_bridge(chan, NULL);
- hanguptree(outgoing, NULL);
- pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
- if (option_debug)
- ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
-
- if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
- if (calldurationlimit)
- chan->whentohangup = 0;
- res = 0;
- }
-
-done:
- ast_module_user_remove(u);
- return res;
-}
-
-static int dial_exec(struct ast_channel *chan, void *data)
-{
- struct ast_flags peerflags;
-
- memset(&peerflags, 0, sizeof(peerflags));
-
- return dial_exec_full(chan, data, &peerflags, NULL);
-}
-
-static int retrydial_exec(struct ast_channel *chan, void *data)
-{
- char *announce = NULL, *dialdata = NULL;
- const char *context = NULL;
- int sleep = 0, loops = 0, res = -1;
- struct ast_module_user *u;
- struct ast_flags peerflags;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- announce = ast_strdupa(data);
-
- memset(&peerflags, 0, sizeof(peerflags));
-
- if ((dialdata = strchr(announce, '|'))) {
- *dialdata++ = '\0';
- if (sscanf(dialdata, "%d", &sleep) == 1) {
- sleep *= 1000;
- } else {
- ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
- goto done;
- }
- if ((dialdata = strchr(dialdata, '|'))) {
- *dialdata++ = '\0';
- if (sscanf(dialdata, "%d", &loops) != 1) {
- ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
- goto done;
- }
- }
- }
-
- if ((dialdata = strchr(dialdata, '|'))) {
- *dialdata++ = '\0';
- } else {
- ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
- goto done;
- }
-
- if (sleep < 1000)
- sleep = 10000;
-
- if (!loops)
- loops = -1; /* run forever */
-
- context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
-
- res = 0;
- while (loops) {
- int continue_exec;
-
- chan->data = "Retrying";
- if (ast_test_flag(chan, AST_FLAG_MOH))
- ast_moh_stop(chan);
-
- res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
- if (continue_exec)
- break;
-
- if (res == 0) {
- if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
- if (!ast_strlen_zero(announce)) {
- if (ast_fileexists(announce, NULL, chan->language) > 0) {
- if(!(res = ast_streamfile(chan, announce, chan->language)))
- ast_waitstream(chan, AST_DIGIT_ANY);
- } else
- ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
- }
- if (!res && sleep) {
- if (!ast_test_flag(chan, AST_FLAG_MOH))
- ast_moh_start(chan, NULL, NULL);
- res = ast_waitfordigit(chan, sleep);
- }
- } else {
- if (!ast_strlen_zero(announce)) {
- if (ast_fileexists(announce, NULL, chan->language) > 0) {
- if (!(res = ast_streamfile(chan, announce, chan->language)))
- res = ast_waitstream(chan, "");
- } else
- ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
- }
- if (sleep) {
- if (!ast_test_flag(chan, AST_FLAG_MOH))
- ast_moh_start(chan, NULL, NULL);
- if (!res)
- res = ast_waitfordigit(chan, sleep);
- }
- }
- }
-
- if (res < 0)
- break;
- else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
- if (onedigit_goto(chan, context, (char) res, 1)) {
- res = 0;
- break;
- }
- }
- loops--;
- }
- if (loops == 0)
- res = 0;
- else if (res == 1)
- res = 0;
-
- if (ast_test_flag(chan, AST_FLAG_MOH))
- ast_moh_stop(chan);
- done:
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
- res |= ast_unregister_application(rapp);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(app, dial_exec, synopsis, descrip);
- res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");
diff --git a/1.4/apps/app_dictate.c b/1.4/apps/app_dictate.c
deleted file mode 100644
index 7db747e12..000000000
--- a/1.4/apps/app_dictate.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Anthony Minessale II
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- * Donated by Sangoma Technologies <http://www.samgoma.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.
- */
-
-/*! \file
- *
- * \brief Virtual Dictation Machine Application For Asterisk
- *
- * \author Anthony Minessale II <anthmct@yahoo.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/say.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-
-static char *app = "Dictate";
-static char *synopsis = "Virtual Dictation Machine";
-static char *desc = " Dictate([<base_dir>[|<filename>]])\n"
-"Start dictation machine using optional base dir for files.\n";
-
-
-typedef enum {
- DFLAG_RECORD = (1 << 0),
- DFLAG_PLAY = (1 << 1),
- DFLAG_TRUNC = (1 << 2),
- DFLAG_PAUSE = (1 << 3),
-} dflags;
-
-typedef enum {
- DMODE_INIT,
- DMODE_RECORD,
- DMODE_PLAY
-} dmodes;
-
-#define ast_toggle_flag(it,flag) if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag)
-
-static int play_and_wait(struct ast_channel *chan, char *file, char *digits)
-{
- int res = -1;
- if (!ast_streamfile(chan, file, chan->language)) {
- res = ast_waitstream(chan, digits);
- }
- return res;
-}
-
-static int dictate_exec(struct ast_channel *chan, void *data)
-{
- char *path = NULL, filein[256], *filename = "";
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(base);
- AST_APP_ARG(filename);
- );
- char dftbase[256];
- char *base;
- struct ast_flags flags = {0};
- struct ast_filestream *fs;
- struct ast_frame *f = NULL;
- struct ast_module_user *u;
- int ffactor = 320 * 80,
- res = 0,
- done = 0,
- oldr = 0,
- lastop = 0,
- samples = 0,
- speed = 1,
- digit = 0,
- len = 0,
- maxlen = 0,
- mode = 0;
-
- u = ast_module_user_add(chan);
-
- snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
- if (!ast_strlen_zero(data)) {
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
- } else
- args.argc = 0;
-
- if (args.argc && !ast_strlen_zero(args.base)) {
- base = args.base;
- } else {
- base = dftbase;
- }
- if (args.argc > 1 && args.filename) {
- filename = args.filename;
- }
- oldr = chan->readformat;
- if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
- ast_log(LOG_WARNING, "Unable to set to linear mode.\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_answer(chan);
- ast_safe_sleep(chan, 200);
- for (res = 0; !res;) {
- if (ast_strlen_zero(filename)) {
- if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) ||
- ast_strlen_zero(filein)) {
- res = -1;
- break;
- }
- } else {
- ast_copy_string(filein, filename, sizeof(filein));
- filename = "";
- }
- mkdir(base, 0755);
- len = strlen(base) + strlen(filein) + 2;
- if (!path || len > maxlen) {
- path = alloca(len);
- memset(path, 0, len);
- maxlen = len;
- } else {
- memset(path, 0, maxlen);
- }
-
- snprintf(path, len, "%s/%s", base, filein);
- fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, 0700);
- mode = DMODE_PLAY;
- memset(&flags, 0, sizeof(flags));
- ast_set_flag(&flags, DFLAG_PAUSE);
- digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY);
- done = 0;
- speed = 1;
- res = 0;
- lastop = 0;
- samples = 0;
- while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) {
- if (digit) {
- struct ast_frame fr = {AST_FRAME_DTMF, digit};
- ast_queue_frame(chan, &fr);
- digit = 0;
- }
- if ((f->frametype == AST_FRAME_DTMF)) {
- int got = 1;
- switch(mode) {
- case DMODE_PLAY:
- switch(f->subclass) {
- case '1':
- ast_set_flag(&flags, DFLAG_PAUSE);
- mode = DMODE_RECORD;
- break;
- case '2':
- speed++;
- if (speed > 4) {
- speed = 1;
- }
- res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, (char *) NULL);
- break;
- case '7':
- samples -= ffactor;
- if(samples < 0) {
- samples = 0;
- }
- ast_seekstream(fs, samples, SEEK_SET);
- break;
- case '8':
- samples += ffactor;
- ast_seekstream(fs, samples, SEEK_SET);
- break;
-
- default:
- got = 0;
- }
- break;
- case DMODE_RECORD:
- switch(f->subclass) {
- case '1':
- ast_set_flag(&flags, DFLAG_PAUSE);
- mode = DMODE_PLAY;
- break;
- case '8':
- ast_toggle_flag(&flags, DFLAG_TRUNC);
- lastop = 0;
- break;
- default:
- got = 0;
- }
- break;
- default:
- got = 0;
- }
- if (!got) {
- switch(f->subclass) {
- case '#':
- done = 1;
- continue;
- break;
- case '*':
- ast_toggle_flag(&flags, DFLAG_PAUSE);
- if (ast_test_flag(&flags, DFLAG_PAUSE)) {
- digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY);
- } else {
- digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY);
- }
- break;
- case '0':
- ast_set_flag(&flags, DFLAG_PAUSE);
- digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
- switch(mode) {
- case DMODE_PLAY:
- digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY);
- break;
- case DMODE_RECORD:
- digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY);
- break;
- }
- if (digit == 0) {
- digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY);
- } else if (digit < 0) {
- done = 1;
- break;
- }
- break;
- }
- }
-
- } else if (f->frametype == AST_FRAME_VOICE) {
- switch(mode) {
- struct ast_frame *fr;
- int x;
- case DMODE_PLAY:
- if (lastop != DMODE_PLAY) {
- if (ast_test_flag(&flags, DFLAG_PAUSE)) {
- digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY);
- if (digit == 0) {
- digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
- } else if (digit < 0) {
- break;
- }
- }
- if (lastop != DFLAG_PLAY) {
- lastop = DFLAG_PLAY;
- ast_closestream(fs);
- if (!(fs = ast_openstream(chan, path, chan->language)))
- break;
- ast_seekstream(fs, samples, SEEK_SET);
- chan->stream = NULL;
- }
- lastop = DMODE_PLAY;
- }
-
- if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
- for (x = 0; x < speed; x++) {
- if ((fr = ast_readframe(fs))) {
- ast_write(chan, fr);
- samples += fr->samples;
- ast_frfree(fr);
- fr = NULL;
- } else {
- samples = 0;
- ast_seekstream(fs, 0, SEEK_SET);
- }
- }
- }
- break;
- case DMODE_RECORD:
- if (lastop != DMODE_RECORD) {
- int oflags = O_CREAT | O_WRONLY;
- if (ast_test_flag(&flags, DFLAG_PAUSE)) {
- digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY);
- if (digit == 0) {
- digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
- } else if (digit < 0) {
- break;
- }
- }
- lastop = DMODE_RECORD;
- ast_closestream(fs);
- if ( ast_test_flag(&flags, DFLAG_TRUNC)) {
- oflags |= O_TRUNC;
- digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY);
- } else {
- oflags |= O_APPEND;
- }
- fs = ast_writefile(path, "raw", NULL, oflags, 0, 0700);
- if (ast_test_flag(&flags, DFLAG_TRUNC)) {
- ast_seekstream(fs, 0, SEEK_SET);
- ast_clear_flag(&flags, DFLAG_TRUNC);
- } else {
- ast_seekstream(fs, 0, SEEK_END);
- }
- }
- if (!ast_test_flag(&flags, DFLAG_PAUSE)) {
- res = ast_writestream(fs, f);
- }
- break;
- }
-
- }
-
- ast_frfree(f);
- }
- }
- if (oldr) {
- ast_set_read_format(chan, oldr);
- }
- ast_module_user_remove(u);
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
- res = ast_unregister_application(app);
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, dictate_exec, synopsis, desc);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Virtual Dictation Machine");
diff --git a/1.4/apps/app_directed_pickup.c b/1.4/apps/app_directed_pickup.c
deleted file mode 100644
index 1d5318f56..000000000
--- a/1.4/apps/app_directed_pickup.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Joshua Colp
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- *
- * \brief Directed Call Pickup Support
- *
- * \author Joshua Colp <jcolp@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-
-#define PICKUPMARK "PICKUPMARK"
-
-static const char *app = "Pickup";
-static const char *synopsis = "Directed Call Pickup";
-static const char *descrip =
-" Pickup(extension[@context][&extension2@context...]): This application can pickup any ringing channel\n"
-"that is calling the specified extension. If no context is specified, the current\n"
-"context will be used. If you use the special string \"PICKUPMARK\" for the context parameter, for example\n"
-"10@PICKUPMARK, this application tries to find a channel which has defined a channel variable with the same content\n"
-"as \"extension\".";
-
-/* Perform actual pickup between two channels */
-static int pickup_do(struct ast_channel *chan, struct ast_channel *target)
-{
- int res = 0;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Call pickup on '%s' by '%s'\n", target->name, chan->name);
-
- if ((res = ast_answer(chan))) {
- ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
- return -1;
- }
-
- if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) {
- ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
- return -1;
- }
-
- if ((res = ast_channel_masquerade(target, chan))) {
- ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
- return -1;
- }
-
- return res;
-}
-
-/* Helper function that determines whether a channel is capable of being picked up */
-static int can_pickup(struct ast_channel *chan)
-{
- if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING))
- return 1;
- else
- return 0;
-}
-
-/* Attempt to pick up specified extension with context */
-static int pickup_by_exten(struct ast_channel *chan, char *exten, char *context)
-{
- int res = -1;
- struct ast_channel *target = NULL;
-
- while ((target = ast_channel_walk_locked(target))) {
- if ((!strcasecmp(target->macroexten, exten) || !strcasecmp(target->exten, exten)) &&
- !strcasecmp(target->dialcontext, context) &&
- can_pickup(target)) {
- res = pickup_do(chan, target);
- ast_channel_unlock(target);
- break;
- }
- ast_channel_unlock(target);
- }
-
- return res;
-}
-
-/* Attempt to pick up specified mark */
-static int pickup_by_mark(struct ast_channel *chan, char *mark)
-{
- int res = -1;
- const char *tmp = NULL;
- struct ast_channel *target = NULL;
-
- while ((target = ast_channel_walk_locked(target))) {
- if ((tmp = pbx_builtin_getvar_helper(target, PICKUPMARK)) &&
- !strcasecmp(tmp, mark) &&
- can_pickup(target)) {
- res = pickup_do(chan, target);
- ast_channel_unlock(target);
- break;
- }
- ast_channel_unlock(target);
- }
-
- return res;
-}
-
-/* Main application entry point */
-static int pickup_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- char *tmp = ast_strdupa(data);
- char *exten = NULL, *context = NULL;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Pickup requires an argument (extension)!\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- /* Parse extension (and context if there) */
- while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
- if ((context = strchr(exten, '@')))
- *context++ = '\0';
- if (context && !strcasecmp(context, PICKUPMARK)) {
- if (!pickup_by_mark(chan, exten))
- break;
- } else {
- if (!pickup_by_exten(chan, exten, context ? context : chan->context))
- break;
- }
- ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, pickup_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Directed Call Pickup Application");
diff --git a/1.4/apps/app_directory.c b/1.4/apps/app_directory.c
deleted file mode 100644
index f0236d1f0..000000000
--- a/1.4/apps/app_directory.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Provide a directory of extensions
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/say.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-#ifdef ODBC_STORAGE
-#include <errno.h>
-#include <sys/mman.h>
-#include "asterisk/res_odbc.h"
-
-static char odbc_database[80] = "asterisk";
-static char odbc_table[80] = "voicemessages";
-static char vmfmts[80] = "wav";
-#endif
-
-static char *app = "Directory";
-
-static char *synopsis = "Provide directory of voicemail extensions";
-static char *descrip =
-" Directory(vm-context[|dial-context[|options]]): This application will present\n"
-"the calling channel with a directory of extensions from which they can search\n"
-"by name. The list of names and corresponding extensions is retrieved from the\n"
-"voicemail configuration file, voicemail.conf.\n"
-" This application will immediately exit if one of the following DTMF digits are\n"
-"received and the extension to jump to exists:\n"
-" 0 - Jump to the 'o' extension, if it exists.\n"
-" * - Jump to the 'a' extension, if it exists.\n\n"
-" Parameters:\n"
-" vm-context - This is the context within voicemail.conf to use for the\n"
-" Directory.\n"
-" dial-context - This is the dialplan context to use when looking for an\n"
-" extension that the user has selected, or when jumping to the\n"
-" 'o' or 'a' extension.\n\n"
-" Options:\n"
-" e - In addition to the name, also read the extension number to the\n"
-" caller before presenting dialing options.\n"
-" f - Allow the caller to enter the first name of a user in the directory\n"
-" instead of using the last name.\n";
-
-/* For simplicity, I'm keeping the format compatible with the voicemail config,
- but i'm open to suggestions for isolating it */
-
-#define VOICEMAIL_CONFIG "voicemail.conf"
-
-/* How many digits to read in */
-#define NUMDIGITS 3
-
-
-#ifdef ODBC_STORAGE
-struct generic_prepare_struct {
- const char *sql;
- const char *param;
-};
-
-static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
-{
- struct generic_prepare_struct *gps = data;
- SQLHSTMT stmt;
- int res;
-
- res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
- return NULL;
- }
-
- res = SQLPrepare(stmt, (unsigned char *)gps->sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", (char *)gps->sql);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- return NULL;
- }
-
- if (!ast_strlen_zero(gps->param))
- SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(gps->param), 0, (void *)gps->param, 0, NULL);
-
- return stmt;
-}
-
-static void retrieve_file(char *dir)
-{
- int x = 0;
- int res;
- int fd=-1;
- size_t fdlen = 0;
- void *fdm = MAP_FAILED;
- SQLHSTMT stmt;
- char sql[256];
- char fmt[80]="", empty[10] = "";
- char *c;
- SQLLEN colsize;
- char full_fn[256];
- struct odbc_obj *obj;
- struct generic_prepare_struct gps = { .sql = sql, .param = dir };
-
- obj = ast_odbc_request_obj(odbc_database, 1);
- if (obj) {
- do {
- ast_copy_string(fmt, vmfmts, sizeof(fmt));
- c = strchr(fmt, '|');
- if (c)
- *c = '\0';
- if (!strcasecmp(fmt, "wav49"))
- strcpy(fmt, "WAV");
- snprintf(full_fn, sizeof(full_fn), "%s.%s", dir, fmt);
- snprintf(sql, sizeof(sql), "SELECT recording FROM %s WHERE dir=? AND msgnum=-1", odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
-
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- break;
- }
- res = SQLFetch(stmt);
- if (res == SQL_NO_DATA) {
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- break;
- } else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- break;
- }
- fd = open(full_fn, O_RDWR | O_CREAT | O_TRUNC, 0770);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Failed to write '%s': %s\n", full_fn, strerror(errno));
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- break;
- }
-
- res = SQLGetData(stmt, 1, SQL_BINARY, empty, 0, &colsize);
- fdlen = colsize;
- if (fd > -1) {
- char tmp[1]="";
- lseek(fd, fdlen - 1, SEEK_SET);
- if (write(fd, tmp, 1) != 1) {
- close(fd);
- fd = -1;
- break;
- }
- if (fd > -1)
- fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- }
- if (fdm != MAP_FAILED) {
- memset(fdm, 0, fdlen);
- res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, fdlen, &colsize);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- break;
- }
- }
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- } while (0);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
- if (fdm != MAP_FAILED)
- munmap(fdm, fdlen);
- if (fd > -1)
- close(fd);
- return;
-}
-#endif
-
-static char *convert(const char *lastname)
-{
- char *tmp;
- int lcount = 0;
- tmp = ast_malloc(NUMDIGITS + 1);
- if (tmp) {
- while((*lastname > 32) && lcount < NUMDIGITS) {
- switch(toupper(*lastname)) {
- case '1':
- tmp[lcount++] = '1';
- break;
- case '2':
- case 'A':
- case 'B':
- case 'C':
- tmp[lcount++] = '2';
- break;
- case '3':
- case 'D':
- case 'E':
- case 'F':
- tmp[lcount++] = '3';
- break;
- case '4':
- case 'G':
- case 'H':
- case 'I':
- tmp[lcount++] = '4';
- break;
- case '5':
- case 'J':
- case 'K':
- case 'L':
- tmp[lcount++] = '5';
- break;
- case '6':
- case 'M':
- case 'N':
- case 'O':
- tmp[lcount++] = '6';
- break;
- case '7':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- tmp[lcount++] = '7';
- break;
- case '8':
- case 'T':
- case 'U':
- case 'V':
- tmp[lcount++] = '8';
- break;
- case '9':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- tmp[lcount++] = '9';
- break;
- }
- lastname++;
- }
- tmp[lcount] = '\0';
- }
- return tmp;
-}
-
-/* play name of mailbox owner.
- * returns: -1 for bad or missing extension
- * '1' for selected entry from directory
- * '*' for skipped entry from directory
- */
-static int play_mailbox_owner(struct ast_channel *chan, char *context,
- char *dialcontext, char *ext, char *name, int readext,
- int fromappvm)
-{
- int res = 0;
- int loop;
- char fn[256];
-
- /* Check for the VoiceMail2 greeting first */
- snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/greet",
- ast_config_AST_SPOOL_DIR, context, ext);
-#ifdef ODBC_STORAGE
- retrieve_file(fn);
-#endif
-
- if (ast_fileexists(fn, NULL, chan->language) <= 0) {
- /* no file, check for an old-style Voicemail greeting */
- snprintf(fn, sizeof(fn), "%s/vm/%s/greet",
- ast_config_AST_SPOOL_DIR, ext);
- }
-#ifdef ODBC_STORAGE
- retrieve_file(fn);
-#endif
-
- if (ast_fileexists(fn, NULL, chan->language) > 0) {
- res = ast_stream_and_wait(chan, fn, chan->language, AST_DIGIT_ANY);
- ast_stopstream(chan);
- /* If Option 'e' was specified, also read the extension number with the name */
- if (readext) {
- ast_stream_and_wait(chan, "vm-extension", chan->language, AST_DIGIT_ANY);
- res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, chan->language);
- }
- } else {
- res = ast_say_character_str(chan, S_OR(name, ext), AST_DIGIT_ANY, chan->language);
- if (!ast_strlen_zero(name) && readext) {
- ast_stream_and_wait(chan, "vm-extension", chan->language, AST_DIGIT_ANY);
- res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, chan->language);
- }
- }
-#ifdef ODBC_STORAGE
- ast_filedelete(fn, NULL);
-#endif
-
- for (loop = 3 ; loop > 0; loop--) {
- if (!res)
- res = ast_stream_and_wait(chan, "dir-instr", chan->language, AST_DIGIT_ANY);
- if (!res)
- res = ast_waitfordigit(chan, 3000);
- ast_stopstream(chan);
-
- if (res < 0) /* User hungup, so jump out now */
- break;
- if (res == '1') { /* Name selected */
- if (fromappvm) {
- /* We still want to set the exten though */
- ast_copy_string(chan->exten, ext, sizeof(chan->exten));
- } else {
- if (ast_goto_if_exists(chan, dialcontext, ext, 1)) {
- ast_log(LOG_WARNING,
- "Can't find extension '%s' in context '%s'. "
- "Did you pass the wrong context to Directory?\n",
- ext, dialcontext);
- res = -1;
- }
- }
- break;
- }
- if (res == '*') /* Skip to next match in list */
- break;
-
- /* Not '1', or '*', so decrement number of tries */
- res = 0;
- }
-
- return(res);
-}
-
-static struct ast_config *realtime_directory(char *context)
-{
- struct ast_config *cfg;
- struct ast_config *rtdata;
- struct ast_category *cat;
- struct ast_variable *var;
- char *mailbox;
- const char *fullname;
- const char *hidefromdir;
- char tmp[100];
-
- /* Load flat file config. */
- cfg = ast_config_load(VOICEMAIL_CONFIG);
-
- if (!cfg) {
- /* Loading config failed. */
- ast_log(LOG_WARNING, "Loading config failed.\n");
- return NULL;
- }
-
- /* Get realtime entries, categorized by their mailbox number
- and present in the requested context */
- rtdata = ast_load_realtime_multientry("voicemail", "mailbox LIKE", "%", "context", context, NULL);
-
- /* if there are no results, just return the entries from the config file */
- if (!rtdata)
- return cfg;
-
- /* Does the context exist within the config file? If not, make one */
- cat = ast_category_get(cfg, context);
- if (!cat) {
- cat = ast_category_new(context);
- if (!cat) {
- ast_log(LOG_WARNING, "Out of memory\n");
- ast_config_destroy(cfg);
- return NULL;
- }
- ast_category_append(cfg, cat);
- }
-
- mailbox = NULL;
- while ( (mailbox = ast_category_browse(rtdata, mailbox)) ) {
- fullname = ast_variable_retrieve(rtdata, mailbox, "fullname");
- hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir");
- snprintf(tmp, sizeof(tmp), "no-password,%s,hidefromdir=%s",
- fullname ? fullname : "",
- hidefromdir ? hidefromdir : "no");
- var = ast_variable_new(mailbox, tmp);
- if (var)
- ast_variable_append(cat, var);
- else
- ast_log(LOG_WARNING, "Out of memory adding mailbox '%s'\n", mailbox);
- }
- ast_config_destroy(rtdata);
-
- return cfg;
-}
-
-static int do_directory(struct ast_channel *chan, struct ast_config *cfg, struct ast_config *ucfg, char *context, char *dialcontext, char digit, int last, int readext, int fromappvm)
-{
- /* Read in the first three digits.. "digit" is the first digit, already read */
- char ext[NUMDIGITS + 1], *cat;
- char name[80] = "";
- struct ast_variable *v;
- int res;
- int found=0;
- int lastuserchoice = 0;
- char *start, *conv, *stringp = NULL;
- const char *pos;
- int breakout = 0;
-
- if (ast_strlen_zero(context)) {
- ast_log(LOG_WARNING,
- "Directory must be called with an argument "
- "(context in which to interpret extensions)\n");
- return -1;
- }
- if (digit == '0') {
- if (!ast_goto_if_exists(chan, dialcontext, "o", 1) ||
- (!ast_strlen_zero(chan->macrocontext) &&
- !ast_goto_if_exists(chan, chan->macrocontext, "o", 1))) {
- return 0;
- } else {
- ast_log(LOG_WARNING, "Can't find extension 'o' in current context. "
- "Not Exiting the Directory!\n");
- res = 0;
- }
- }
- if (digit == '*') {
- if (!ast_goto_if_exists(chan, dialcontext, "a", 1) ||
- (!ast_strlen_zero(chan->macrocontext) &&
- !ast_goto_if_exists(chan, chan->macrocontext, "a", 1))) {
- return 0;
- } else {
- ast_log(LOG_WARNING, "Can't find extension 'a' in current context. "
- "Not Exiting the Directory!\n");
- res = 0;
- }
- }
- memset(ext, 0, sizeof(ext));
- ext[0] = digit;
- res = 0;
- if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1;
- if (!res) {
- /* Search for all names which start with those digits */
- v = ast_variable_browse(cfg, context);
- while(v && !res) {
- /* Find all candidate extensions */
- while(v) {
- /* Find a candidate extension */
- start = strdup(v->value);
- if (start && !strcasestr(start, "hidefromdir=yes")) {
- stringp=start;
- strsep(&stringp, ",");
- pos = strsep(&stringp, ",");
- if (pos) {
- ast_copy_string(name, pos, sizeof(name));
- /* Grab the last name */
- if (last && strrchr(pos,' '))
- pos = strrchr(pos, ' ') + 1;
- conv = convert(pos);
- if (conv) {
- if (!strncmp(conv, ext, strlen(ext))) {
- /* Match! */
- found++;
- free(conv);
- free(start);
- break;
- }
- free(conv);
- }
- }
- free(start);
- }
- v = v->next;
- }
-
- if (v) {
- /* We have a match -- play a greeting if they have it */
- res = play_mailbox_owner(chan, context, dialcontext, v->name, name, readext, fromappvm);
- switch (res) {
- case -1:
- /* user pressed '1' but extension does not exist, or
- * user hungup
- */
- lastuserchoice = 0;
- break;
- case '1':
- /* user pressed '1' and extensions exists;
- play_mailbox_owner will already have done
- a goto() on the channel
- */
- lastuserchoice = res;
- break;
- case '*':
- /* user pressed '*' to skip something found */
- lastuserchoice = res;
- res = 0;
- break;
- default:
- break;
- }
- v = v->next;
- }
- }
-
- if (!res && ucfg) {
- /* Search users.conf for all names which start with those digits */
- for (cat = ast_category_browse(ucfg, NULL); cat && !res ; cat = ast_category_browse(ucfg, cat)) {
- if (!strcasecmp(cat, "general"))
- continue;
- if (!ast_true(ast_config_option(ucfg, cat, "hasdirectory")))
- continue;
-
- /* Find all candidate extensions */
- if ((pos = ast_variable_retrieve(ucfg, cat, "fullname"))) {
- ast_copy_string(name, pos, sizeof(name));
- /* Grab the last name */
- if (last && strrchr(pos,' '))
- pos = strrchr(pos, ' ') + 1;
- conv = convert(pos);
- if (conv) {
- if (!strcmp(conv, ext)) {
- /* Match! */
- found++;
- /* We have a match -- play a greeting if they have it */
- res = play_mailbox_owner(chan, context, dialcontext, cat, name, readext, fromappvm);
- switch (res) {
- case -1:
- /* user pressed '1' but extension does not exist, or
- * user hungup
- */
- lastuserchoice = 0;
- breakout = 1;
- break;
- case '1':
- /* user pressed '1' and extensions exists;
- play_mailbox_owner will already have done
- a goto() on the channel
- */
- lastuserchoice = res;
- breakout = 1;
- break;
- case '*':
- /* user pressed '*' to skip something found */
- lastuserchoice = res;
- breakout = 0;
- res = 0;
- break;
- default:
- breakout = 1;
- break;
- }
- free(conv);
- if (breakout)
- break;
- }
- else
- free(conv);
- }
- }
- }
- }
-
- if (lastuserchoice != '1') {
- res = ast_streamfile(chan, found ? "dir-nomore" : "dir-nomatch", chan->language);
- if (!res)
- res = 1;
- return res;
- }
- return 0;
- }
- return res;
-}
-
-static int directory_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- struct ast_config *cfg, *ucfg;
- int last = 1;
- int readext = 0;
- int fromappvm = 0;
- const char *dirintro;
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(vmcontext);
- AST_APP_ARG(dialcontext);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Directory requires an argument (context[,dialcontext])\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.options) {
- if (strchr(args.options, 'f'))
- last = 0;
- if (strchr(args.options, 'e'))
- readext = 1;
- if (strchr(args.options, 'v'))
- fromappvm = 1;
- }
-
- if (ast_strlen_zero(args.dialcontext))
- args.dialcontext = args.vmcontext;
-
- cfg = realtime_directory(args.vmcontext);
- if (!cfg) {
- ast_log(LOG_ERROR, "Unable to read the configuration data!\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- ucfg = ast_config_load("users.conf");
-
- dirintro = ast_variable_retrieve(cfg, args.vmcontext, "directoryintro");
- if (ast_strlen_zero(dirintro))
- dirintro = ast_variable_retrieve(cfg, "general", "directoryintro");
- if (ast_strlen_zero(dirintro))
- dirintro = last ? "dir-intro" : "dir-intro-fn";
-
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
-
- for (;;) {
- if (!res)
- res = ast_stream_and_wait(chan, dirintro, chan->language, AST_DIGIT_ANY);
- ast_stopstream(chan);
- if (!res)
- res = ast_waitfordigit(chan, 5000);
- if (res > 0) {
- res = do_directory(chan, cfg, ucfg, args.vmcontext, args.dialcontext, res, last, readext, fromappvm);
- if (res > 0) {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- if (res >= 0)
- continue;
- }
- }
- break;
- }
- if (ucfg)
- ast_config_destroy(ucfg);
- ast_config_destroy(cfg);
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
- res = ast_unregister_application(app);
- return res;
-}
-
-static int load_module(void)
-{
-#ifdef ODBC_STORAGE
- struct ast_config *cfg = ast_config_load(VOICEMAIL_CONFIG);
- const char *tmp;
-
- if (cfg) {
- if ((tmp = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
- ast_copy_string(odbc_database, tmp, sizeof(odbc_database));
- }
- if ((tmp = ast_variable_retrieve(cfg, "general", "odbctable"))) {
- ast_copy_string(odbc_table, tmp, sizeof(odbc_table));
- }
- if ((tmp = ast_variable_retrieve(cfg, "general", "format"))) {
- ast_copy_string(vmfmts, tmp, sizeof(vmfmts));
- }
- ast_config_destroy(cfg);
- } else
- ast_log(LOG_WARNING, "Unable to load " VOICEMAIL_CONFIG " - ODBC defaults will be used\n");
-#endif
-
- return ast_register_application(app, directory_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Extension Directory");
diff --git a/1.4/apps/app_disa.c b/1.4/apps/app_disa.c
deleted file mode 100644
index 4b7852a13..000000000
--- a/1.4/apps/app_disa.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- *
- * Made only slightly more sane by 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.
- */
-
-/*! \file
- *
- * \brief DISA -- Direct Inward System Access Application
- *
- * \author Jim Dixon <jim@lambdatel.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <sys/time.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/app.h"
-#include "asterisk/indications.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/callerid.h"
-#include "asterisk/stringfields.h"
-
-static char *app = "DISA";
-
-static char *synopsis = "DISA (Direct Inward System Access)";
-
-static char *descrip =
- "DISA(<numeric passcode>[|<context>]) or DISA(<filename>)\n"
- "The DISA, Direct Inward System Access, application allows someone from \n"
- "outside the telephone switch (PBX) to obtain an \"internal\" system \n"
- "dialtone and to place calls from it as if they were placing a call from \n"
- "within the switch.\n"
- "DISA plays a dialtone. The user enters their numeric passcode, followed by\n"
- "the pound sign (#). If the passcode is correct, the user is then given\n"
- "system dialtone on which a call may be placed. Obviously, this type\n"
- "of access has SERIOUS security implications, and GREAT care must be\n"
- "taken NOT to compromise your security.\n\n"
- "There is a possibility of accessing DISA without password. Simply\n"
- "exchange your password with \"no-password\".\n\n"
- " Example: exten => s,1,DISA(no-password|local)\n\n"
- "Be aware that using this compromises the security of your PBX.\n\n"
- "The arguments to this application (in extensions.conf) allow either\n"
- "specification of a single global passcode (that everyone uses), or\n"
- "individual passcodes contained in a file. It also allows specification\n"
- "of the context on which the user will be dialing. If no context is\n"
- "specified, the DISA application defaults the context to \"disa\".\n"
- "Presumably a normal system will have a special context set up\n"
- "for DISA use with some or a lot of restrictions. \n\n"
- "The file that contains the passcodes (if used) allows specification\n"
- "of either just a passcode (defaulting to the \"disa\" context, or\n"
- "passcode|context on each line of the file. The file may contain blank\n"
- "lines, or comments starting with \"#\" or \";\". In addition, the\n"
- "above arguments may have |new-callerid-string appended to them, to\n"
- "specify a new (different) callerid to be used for this call, for\n"
- "example: numeric-passcode|context|\"My Phone\" <(234) 123-4567> or \n"
- "full-pathname-of-passcode-file|\"My Phone\" <(234) 123-4567>. Last\n"
- "but not least, |mailbox[@context] may be appended, which will cause\n"
- "a stutter-dialtone (indication \"dialrecall\") to be used, if the\n"
- "specified mailbox contains any new messages, for example:\n"
- "numeric-passcode|context||1234 (w/a changing callerid). Note that\n"
- "in the case of specifying the numeric-passcode, the context must be\n"
- "specified if the callerid is specified also.\n\n"
- "If login is successful, the application looks up the dialed number in\n"
- "the specified (or default) context, and executes it if found.\n"
- "If the user enters an invalid extension and extension \"i\" (invalid) \n"
- "exists in the context, it will be used. Also, if you set the 5th argument\n"
- "to 'NOANSWER', the DISA application will not answer initially.\n";
-
-
-static void play_dialtone(struct ast_channel *chan, char *mailbox)
-{
- const struct tone_zone_sound *ts = NULL;
- if(ast_app_has_voicemail(mailbox, NULL))
- ts = ast_get_indication_tone(chan->zone, "dialrecall");
- else
- ts = ast_get_indication_tone(chan->zone, "dial");
- if (ts)
- ast_playtones_start(chan, 0, ts->data, 0);
- else
- ast_tonepair_start(chan, 350, 440, 0, 0);
-}
-
-static int disa_exec(struct ast_channel *chan, void *data)
-{
- int i,j,k,x,did_ignore,special_noanswer;
- int firstdigittimeout = 20000;
- int digittimeout = 10000;
- struct ast_module_user *u;
- char *tmp, exten[AST_MAX_EXTENSION],acctcode[20]="";
- char pwline[256];
- char ourcidname[256],ourcidnum[256];
- struct ast_frame *f;
- struct timeval lastdigittime;
- int res;
- time_t rstart;
- FILE *fp;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(passcode);
- AST_APP_ARG(context);
- AST_APP_ARG(cid);
- AST_APP_ARG(mailbox);
- AST_APP_ARG(noanswer);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "DISA requires an argument (passcode/passcode file)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (chan->pbx) {
- firstdigittimeout = chan->pbx->rtimeout*1000;
- digittimeout = chan->pbx->dtimeout*1000;
- }
-
- if (ast_set_write_format(chan,AST_FORMAT_ULAW)) {
- ast_log(LOG_WARNING, "Unable to set write format to Mu-law on %s\n", chan->name);
- ast_module_user_remove(u);
- return -1;
- }
- if (ast_set_read_format(chan,AST_FORMAT_ULAW)) {
- ast_log(LOG_WARNING, "Unable to set read format to Mu-law on %s\n", chan->name);
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_log(LOG_DEBUG, "Digittimeout: %d\n", digittimeout);
- ast_log(LOG_DEBUG, "Responsetimeout: %d\n", firstdigittimeout);
-
- tmp = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, tmp);
-
- if (ast_strlen_zero(args.context))
- args.context = "disa";
- if (ast_strlen_zero(args.mailbox))
- args.mailbox = "";
-
- ast_log(LOG_DEBUG, "Mailbox: %s\n",args.mailbox);
-
-
- special_noanswer = 0;
- if ((!args.noanswer) || strcmp(args.noanswer,"NOANSWER"))
- {
- if (chan->_state != AST_STATE_UP) {
- /* answer */
- ast_answer(chan);
- }
- } else special_noanswer = 1;
- i = k = x = 0; /* k is 0 for pswd entry, 1 for ext entry */
- did_ignore = 0;
- exten[0] = 0;
- acctcode[0] = 0;
- /* can we access DISA without password? */
-
- ast_log(LOG_DEBUG, "Context: %s\n",args.context);
-
- if (!strcasecmp(args.passcode, "no-password")) {
- k |= 1; /* We have the password */
- ast_log(LOG_DEBUG, "DISA no-password login success\n");
- }
- lastdigittime = ast_tvnow();
-
- play_dialtone(chan, args.mailbox);
-
- for (;;) {
- /* if outa time, give em reorder */
- if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) >
- ((k&2) ? digittimeout : firstdigittimeout)) {
- ast_log(LOG_DEBUG,"DISA %s entry timeout on chan %s\n",
- ((k&1) ? "extension" : "password"),chan->name);
- break;
- }
- if ((res = ast_waitfor(chan, -1) < 0)) {
- ast_log(LOG_DEBUG, "Waitfor returned %d\n", res);
- continue;
- }
-
- f = ast_read(chan);
- if (f == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
- if ((f->frametype == AST_FRAME_CONTROL) &&
- (f->subclass == AST_CONTROL_HANGUP)) {
- ast_frfree(f);
- ast_module_user_remove(u);
- return -1;
- }
- if (f->frametype == AST_FRAME_VOICE) {
- ast_frfree(f);
- continue;
- }
-
- /* if not DTMF, just do it again */
- if (f->frametype != AST_FRAME_DTMF) {
- ast_frfree(f);
- continue;
- }
-
- j = f->subclass; /* save digit */
- ast_frfree(f);
- if (i == 0) {
- k|=2; /* We have the first digit */
- ast_playtones_stop(chan);
- }
- lastdigittime = ast_tvnow();
- /* got a DTMF tone */
- if (i < AST_MAX_EXTENSION) { /* if still valid number of digits */
- if (!(k&1)) { /* if in password state */
- if (j == '#') { /* end of password */
- /* see if this is an integer */
- if (sscanf(args.passcode,"%d",&j) < 1) { /* nope, it must be a filename */
- fp = fopen(args.passcode,"r");
- if (!fp) {
- ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,chan->name);
- ast_module_user_remove(u);
- return -1;
- }
- pwline[0] = 0;
- while(fgets(pwline,sizeof(pwline) - 1,fp)) {
- if (!pwline[0])
- continue;
- if (pwline[strlen(pwline) - 1] == '\n')
- pwline[strlen(pwline) - 1] = 0;
- if (!pwline[0])
- continue;
- /* skip comments */
- if (pwline[0] == '#')
- continue;
- if (pwline[0] == ';')
- continue;
-
- AST_STANDARD_APP_ARGS(args, pwline);
-
- ast_log(LOG_DEBUG, "Mailbox: %s\n",args.mailbox);
-
- /* password must be in valid format (numeric) */
- if (sscanf(args.passcode,"%d", &j) < 1)
- continue;
- /* if we got it */
- if (!strcmp(exten,args.passcode)) {
- if (ast_strlen_zero(args.context))
- args.context = "disa";
- if (ast_strlen_zero(args.mailbox))
- args.mailbox = "";
- break;
- }
- }
- fclose(fp);
- }
- /* compare the two */
- if (strcmp(exten,args.passcode)) {
- ast_log(LOG_WARNING,"DISA on chan %s got bad password %s\n",chan->name,exten);
- goto reorder;
-
- }
- /* password good, set to dial state */
- ast_log(LOG_DEBUG,"DISA on chan %s password is good\n",chan->name);
- play_dialtone(chan, args.mailbox);
-
- k|=1; /* In number mode */
- i = 0; /* re-set buffer pointer */
- exten[sizeof(acctcode)] = 0;
- ast_copy_string(acctcode, exten, sizeof(acctcode));
- exten[0] = 0;
- ast_log(LOG_DEBUG,"Successful DISA log-in on chan %s\n", chan->name);
- continue;
- }
- } else {
- if (j == '#') { /* end of extension */
- break;
- }
- }
-
- exten[i++] = j; /* save digit */
- exten[i] = 0;
- if (!(k&1))
- continue; /* if getting password, continue doing it */
- /* if this exists */
-
- if (ast_ignore_pattern(args.context, exten)) {
- play_dialtone(chan, "");
- did_ignore = 1;
- } else
- if (did_ignore) {
- ast_playtones_stop(chan);
- did_ignore = 0;
- }
-
- /* if can do some more, do it */
- if (!ast_matchmore_extension(chan,args.context,exten,1, chan->cid.cid_num)) {
- break;
- }
- }
- }
-
- if (k == 3) {
- int recheck = 0;
- struct ast_flags flags = { AST_CDR_FLAG_POSTED };
-
- if (!ast_exists_extension(chan, args.context, exten, 1, chan->cid.cid_num)) {
- pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
- exten[0] = 'i';
- exten[1] = '\0';
- recheck = 1;
- }
- if (!recheck || ast_exists_extension(chan, args.context, exten, 1, chan->cid.cid_num)) {
- ast_playtones_stop(chan);
- /* We're authenticated and have a target extension */
- if (!ast_strlen_zero(args.cid)) {
- ast_callerid_split(args.cid, ourcidname, sizeof(ourcidname), ourcidnum, sizeof(ourcidnum));
- ast_set_callerid(chan, ourcidnum, ourcidname, ourcidnum);
- }
-
- if (!ast_strlen_zero(acctcode))
- ast_string_field_set(chan, accountcode, acctcode);
-
- if (special_noanswer) flags.flags = 0;
- ast_cdr_reset(chan->cdr, &flags);
- ast_explicit_goto(chan, args.context, exten, 1);
- ast_module_user_remove(u);
- return 0;
- }
- }
-
- /* Received invalid, but no "i" extension exists in the given context */
-
-reorder:
-
- ast_indicate(chan,AST_CONTROL_CONGESTION);
- /* something is invalid, give em reorder for several seconds */
- time(&rstart);
- while(time(NULL) < rstart + 10) {
- if (ast_waitfor(chan, -1) < 0)
- break;
- f = ast_read(chan);
- if (!f)
- break;
- ast_frfree(f);
- }
- ast_playtones_stop(chan);
- ast_module_user_remove(u);
- return -1;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, disa_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "DISA (Direct Inward System Access) Application");
diff --git a/1.4/apps/app_dumpchan.c b/1.4/apps/app_dumpchan.c
deleted file mode 100644
index 426ba4eab..000000000
--- a/1.4/apps/app_dumpchan.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005, Anthony Minessale II.
- *
- * Anthony Minessale <anthmct@yahoo.com>
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Application to dump channel variables
- *
- * \author Anthony Minessale <anthmct@yahoo.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-static char *app = "DumpChan";
-static char *synopsis = "Dump Info About The Calling Channel";
-static char *desc =
- " DumpChan([<min_verbose_level>])\n"
- "Displays information on channel and listing of all channel\n"
- "variables. If min_verbose_level is specified, output is only\n"
- "displayed when the verbose level is currently set to that number\n"
- "or greater. \n";
-
-
-static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
-{
- struct timeval now;
- long elapsed_seconds = 0;
- int hour = 0, min = 0, sec = 0;
- char cgrp[BUFSIZ/2];
- char pgrp[BUFSIZ/2];
- char formatbuf[BUFSIZ/2];
-
- now = ast_tvnow();
- memset(buf, 0, size);
- if (!c)
- return 0;
-
- if (c->cdr) {
- elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
- hour = elapsed_seconds / 3600;
- min = (elapsed_seconds % 3600) / 60;
- sec = elapsed_seconds % 60;
- }
-
- snprintf(buf,size,
- "Name= %s\n"
- "Type= %s\n"
- "UniqueID= %s\n"
- "CallerID= %s\n"
- "CallerIDName= %s\n"
- "DNIDDigits= %s\n"
- "RDNIS= %s\n"
- "State= %s (%d)\n"
- "Rings= %d\n"
- "NativeFormat= %s\n"
- "WriteFormat= %s\n"
- "ReadFormat= %s\n"
- "1stFileDescriptor= %d\n"
- "Framesin= %d %s\n"
- "Framesout= %d %s\n"
- "TimetoHangup= %ld\n"
- "ElapsedTime= %dh%dm%ds\n"
- "Context= %s\n"
- "Extension= %s\n"
- "Priority= %d\n"
- "CallGroup= %s\n"
- "PickupGroup= %s\n"
- "Application= %s\n"
- "Data= %s\n"
- "Blocking_in= %s\n",
- c->name,
- c->tech->type,
- c->uniqueid,
- S_OR(c->cid.cid_num, "(N/A)"),
- S_OR(c->cid.cid_name, "(N/A)"),
- S_OR(c->cid.cid_dnid, "(N/A)"),
- S_OR(c->cid.cid_rdnis, "(N/A)"),
- ast_state2str(c->_state),
- c->_state,
- c->rings,
- ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->nativeformats),
- ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->writeformat),
- ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->readformat),
- c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
- c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup,
- hour,
- min,
- sec,
- c->context,
- c->exten,
- c->priority,
- ast_print_group(cgrp, sizeof(cgrp), c->callgroup),
- ast_print_group(pgrp, sizeof(pgrp), c->pickupgroup),
- ( c->appl ? c->appl : "(N/A)" ),
- ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
- (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
-
- return 0;
-}
-
-static int dumpchan_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char vars[BUFSIZ * 4];
- char info[1024];
- int level = 0;
- static char *line = "================================================================================";
-
- u = ast_module_user_add(chan);
-
- if (!ast_strlen_zero(data))
- level = atoi(data);
-
- pbx_builtin_serialize_variables(chan, vars, sizeof(vars));
- serialize_showchan(chan, info, sizeof(info));
- if (option_verbose >= level)
- ast_verbose("\nDumping Info For Channel: %s:\n%s\nInfo:\n%s\nVariables:\n%s%s\n", chan->name, line, info, vars, line);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, dumpchan_exec, synopsis, desc);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dump Info About The Calling Channel");
diff --git a/1.4/apps/app_echo.c b/1.4/apps/app_echo.c
deleted file mode 100644
index 14f7c6d65..000000000
--- a/1.4/apps/app_echo.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Echo application -- play back what you hear to evaluate latency
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-
-static char *app = "Echo";
-
-static char *synopsis = "Echo audio, video, or DTMF back to the calling party";
-
-static char *descrip =
-" Echo(): This application will echo any audio, video, or DTMF frames read from\n"
-"the calling channel back to itself. If the DTMF digit '#' is received, the\n"
-"application will exit.\n";
-
-
-static int echo_exec(struct ast_channel *chan, void *data)
-{
- int res = -1;
- int format;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- format = ast_best_codec(chan->nativeformats);
- ast_set_write_format(chan, format);
- ast_set_read_format(chan, format);
-
- while (ast_waitfor(chan, -1) > -1) {
- struct ast_frame *f = ast_read(chan);
- if (!f)
- break;
- f->delivery.tv_sec = 0;
- f->delivery.tv_usec = 0;
- if (ast_write(chan, f)) {
- ast_frfree(f);
- goto end;
- }
- if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
- res = 0;
- ast_frfree(f);
- goto end;
- }
- ast_frfree(f);
- }
-end:
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, echo_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple Echo Application");
diff --git a/1.4/apps/app_exec.c b/1.4/apps/app_exec.c
deleted file mode 100644
index 2ab96f593..000000000
--- a/1.4/apps/app_exec.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2004 - 2005, Tilghman Lesher. All rights reserved.
- * Portions copyright (c) 2006, Philipp Dunkel.
- *
- * Tilghman Lesher <app_exec__v002@the-tilghman.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief Exec application
- *
- * \author Tilghman Lesher <app_exec__v002@the-tilghman.com>
- * \author Philipp Dunkel <philipp.dunkel@ebox.at>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-
-/* Maximum length of any variable */
-#define MAXRESULT 1024
-
-/*! Note
- *
- * The key difference between these two apps is exit status. In a
- * nutshell, Exec tries to be transparent as possible, behaving
- * in exactly the same way as if the application it calls was
- * directly invoked from the dialplan.
- *
- * TryExec, on the other hand, provides a way to execute applications
- * and catch any possible fatal error without actually fatally
- * affecting the dialplan.
- */
-
-static char *app_exec = "Exec";
-static char *exec_synopsis = "Executes dialplan application";
-static char *exec_descrip =
-"Usage: Exec(appname(arguments))\n"
-" Allows an arbitrary application to be invoked even when not\n"
-"hardcoded into the dialplan. If the underlying application\n"
-"terminates the dialplan, or if the application cannot be found,\n"
-"Exec will terminate the dialplan.\n"
-" To invoke external applications, see the application System.\n"
-" If you would like to catch any error instead, see TryExec.\n";
-
-static char *app_tryexec = "TryExec";
-static char *tryexec_synopsis = "Executes dialplan application, always returning";
-static char *tryexec_descrip =
-"Usage: TryExec(appname(arguments))\n"
-" Allows an arbitrary application to be invoked even when not\n"
-"hardcoded into the dialplan. To invoke external applications\n"
-"see the application System. Always returns to the dialplan.\n"
-"The channel variable TRYSTATUS will be set to:\n"
-" SUCCESS if the application returned zero\n"
-" FAILED if the application returned non-zero\n"
-" NOAPP if the application was not found or was not specified\n";
-
-static char *app_execif = "ExecIf";
-static char *execif_synopsis = "Executes dialplan application, conditionally";
-static char *execif_descrip =
-"Usage: ExecIF (<expr>|<app>|<data>)\n"
-"If <expr> is true, execute and return the result of <app>(<data>).\n"
-"If <expr> is true, but <app> is not found, then the application\n"
-"will return a non-zero value.\n";
-
-static int exec_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
- char *s, *appname, *endargs, args[MAXRESULT] = "";
- struct ast_app *app;
-
- u = ast_module_user_add(chan);
-
- /* Check and parse arguments */
- if (data) {
- s = ast_strdupa(data);
- appname = strsep(&s, "(");
- if (s) {
- endargs = strrchr(s, ')');
- if (endargs)
- *endargs = '\0';
- pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
- }
- if (appname) {
- app = pbx_findapp(appname);
- if (app) {
- res = pbx_exec(chan, app, args);
- } else {
- ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
- res = -1;
- }
- }
- }
-
- ast_module_user_remove(u);
- return res;
-}
-
-static int tryexec_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
- char *s, *appname, *endargs, args[MAXRESULT] = "";
- struct ast_app *app;
-
- u = ast_module_user_add(chan);
-
- /* Check and parse arguments */
- if (data) {
- s = ast_strdupa(data);
- appname = strsep(&s, "(");
- if (s) {
- endargs = strrchr(s, ')');
- if (endargs)
- *endargs = '\0';
- pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
- }
- if (appname) {
- app = pbx_findapp(appname);
- if (app) {
- res = pbx_exec(chan, app, args);
- pbx_builtin_setvar_helper(chan, "TRYSTATUS", res ? "FAILED" : "SUCCESS");
- } else {
- ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
- pbx_builtin_setvar_helper(chan, "TRYSTATUS", "NOAPP");
- }
- }
- }
-
- ast_module_user_remove(u);
- return 0;
-}
-
-static int execif_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *myapp = NULL;
- char *mydata = NULL;
- char *expr = NULL;
- struct ast_app *app = NULL;
-
- u = ast_module_user_add(chan);
-
- expr = ast_strdupa(data);
-
- if ((myapp = strchr(expr,'|'))) {
- *myapp = '\0';
- myapp++;
- if ((mydata = strchr(myapp,'|'))) {
- *mydata = '\0';
- mydata++;
- } else
- mydata = "";
-
- if (pbx_checkcondition(expr)) {
- if ((app = pbx_findapp(myapp))) {
- res = pbx_exec(chan, app, mydata);
- } else {
- ast_log(LOG_WARNING, "Could not find application! (%s)\n", myapp);
- res = -1;
- }
- }
- } else {
- ast_log(LOG_ERROR,"Invalid Syntax.\n");
- res = -1;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_exec);
- res |= ast_unregister_application(app_tryexec);
- res |= ast_unregister_application(app_execif);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = ast_register_application(app_exec, exec_exec, exec_synopsis, exec_descrip);
- res |= ast_register_application(app_tryexec, tryexec_exec, tryexec_synopsis, tryexec_descrip);
- res |= ast_register_application(app_execif, execif_exec, execif_synopsis, execif_descrip);
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Executes dialplan applications");
diff --git a/1.4/apps/app_externalivr.c b/1.4/apps/app_externalivr.c
deleted file mode 100644
index de905997e..000000000
--- a/1.4/apps/app_externalivr.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@digium.com>
- *
- * Portions taken from the file-based music-on-hold work
- * created by Anthony Minessale II in res_musiconhold.c
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief External IVR application interface
- *
- * \author Kevin P. Fleming <kpfleming@digium.com>
- *
- * \note Portions taken from the file-based music-on-hold work
- * created by Anthony Minessale II in res_musiconhold.c
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/app.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-
-static const char *app = "ExternalIVR";
-
-static const char *synopsis = "Interfaces with an external IVR application";
-
-static const char *descrip =
-" ExternalIVR(command[|arg[|arg...]]): Forks a process to run the supplied command,\n"
-"and starts a generator on the channel. The generator's play list is\n"
-"controlled by the external application, which can add and clear entries\n"
-"via simple commands issued over its stdout. The external application\n"
-"will receive all DTMF events received on the channel, and notification\n"
-"if the channel is hung up. The application will not be forcibly terminated\n"
-"when the channel is hung up.\n"
-"See doc/externalivr.txt for a protocol specification.\n";
-
-/* XXX the parser in gcc 2.95 gets confused if you don't put a space between 'name' and the comma */
-#define ast_chan_log(level, channel, format, ...) ast_log(level, "%s: " format, channel->name , ## __VA_ARGS__)
-
-struct playlist_entry {
- AST_LIST_ENTRY(playlist_entry) list;
- char filename[1];
-};
-
-struct ivr_localuser {
- struct ast_channel *chan;
- AST_LIST_HEAD(playlist, playlist_entry) playlist;
- AST_LIST_HEAD(finishlist, playlist_entry) finishlist;
- int abort_current_sound;
- int playing_silence;
- int option_autoclear;
-};
-
-
-struct gen_state {
- struct ivr_localuser *u;
- struct ast_filestream *stream;
- struct playlist_entry *current;
- int sample_queue;
-};
-
-static void send_child_event(FILE *handle, const char event, const char *data,
- const struct ast_channel *chan)
-{
- char tmp[256];
-
- if (!data) {
- snprintf(tmp, sizeof(tmp), "%c,%10d", event, (int)time(NULL));
- } else {
- snprintf(tmp, sizeof(tmp), "%c,%10d,%s", event, (int)time(NULL), data);
- }
-
- fprintf(handle, "%s\n", tmp);
- ast_chan_log(LOG_DEBUG, chan, "sent '%s'\n", tmp);
-}
-
-static void *gen_alloc(struct ast_channel *chan, void *params)
-{
- struct ivr_localuser *u = params;
- struct gen_state *state;
-
- if (!(state = ast_calloc(1, sizeof(*state))))
- return NULL;
-
- state->u = u;
-
- return state;
-}
-
-static void gen_closestream(struct gen_state *state)
-{
- if (!state->stream)
- return;
-
- ast_closestream(state->stream);
- state->u->chan->stream = NULL;
- state->stream = NULL;
-}
-
-static void gen_release(struct ast_channel *chan, void *data)
-{
- struct gen_state *state = data;
-
- gen_closestream(state);
- free(data);
-}
-
-/* caller has the playlist locked */
-static int gen_nextfile(struct gen_state *state)
-{
- struct ivr_localuser *u = state->u;
- char *file_to_stream;
-
- u->abort_current_sound = 0;
- u->playing_silence = 0;
- gen_closestream(state);
-
- while (!state->stream) {
- state->current = AST_LIST_REMOVE_HEAD(&u->playlist, list);
- if (state->current) {
- file_to_stream = state->current->filename;
- } else {
- file_to_stream = "silence/10";
- u->playing_silence = 1;
- }
-
- if (!(state->stream = ast_openstream_full(u->chan, file_to_stream, u->chan->language, 1))) {
- ast_chan_log(LOG_WARNING, u->chan, "File '%s' could not be opened: %s\n", file_to_stream, strerror(errno));
- if (!u->playing_silence) {
- continue;
- } else {
- break;
- }
- }
- }
-
- return (!state->stream);
-}
-
-static struct ast_frame *gen_readframe(struct gen_state *state)
-{
- struct ast_frame *f = NULL;
- struct ivr_localuser *u = state->u;
-
- if (u->abort_current_sound ||
- (u->playing_silence && AST_LIST_FIRST(&u->playlist))) {
- gen_closestream(state);
- AST_LIST_LOCK(&u->playlist);
- gen_nextfile(state);
- AST_LIST_UNLOCK(&u->playlist);
- }
-
- if (!(state->stream && (f = ast_readframe(state->stream)))) {
- if (state->current) {
- AST_LIST_LOCK(&u->finishlist);
- AST_LIST_INSERT_TAIL(&u->finishlist, state->current, list);
- AST_LIST_UNLOCK(&u->finishlist);
- state->current = NULL;
- }
- if (!gen_nextfile(state))
- f = ast_readframe(state->stream);
- }
-
- return f;
-}
-
-static int gen_generate(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct gen_state *state = data;
- struct ast_frame *f = NULL;
- int res = 0;
-
- state->sample_queue += samples;
-
- while (state->sample_queue > 0) {
- if (!(f = gen_readframe(state)))
- return -1;
-
- res = ast_write(chan, f);
- ast_frfree(f);
- if (res < 0) {
- ast_chan_log(LOG_WARNING, chan, "Failed to write frame: %s\n", strerror(errno));
- return -1;
- }
- state->sample_queue -= f->samples;
- }
-
- return res;
-}
-
-static struct ast_generator gen =
-{
- alloc: gen_alloc,
- release: gen_release,
- generate: gen_generate,
-};
-
-static struct playlist_entry *make_entry(const char *filename)
-{
- struct playlist_entry *entry;
-
- if (!(entry = ast_calloc(1, sizeof(*entry) + strlen(filename) + 10))) /* XXX why 10 ? */
- return NULL;
-
- strcpy(entry->filename, filename);
-
- return entry;
-}
-
-static int app_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *lu;
- struct playlist_entry *entry;
- const char *args = data;
- int child_stdin[2] = { 0,0 };
- int child_stdout[2] = { 0,0 };
- int child_stderr[2] = { 0,0 };
- int res = -1;
- int gen_active = 0;
- int pid;
- char *argv[32];
- int argc = 1;
- char *buf, *command;
- FILE *child_commands = NULL;
- FILE *child_errors = NULL;
- FILE *child_events = NULL;
- struct ivr_localuser foo = {
- .playlist = AST_LIST_HEAD_INIT_VALUE,
- .finishlist = AST_LIST_HEAD_INIT_VALUE,
- };
- struct ivr_localuser *u = &foo;
- sigset_t fullset, oldset;
-
- lu = ast_module_user_add(chan);
-
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
-
- u->abort_current_sound = 0;
- u->chan = chan;
-
- if (ast_strlen_zero(args)) {
- ast_log(LOG_WARNING, "ExternalIVR requires a command to execute\n");
- ast_module_user_remove(lu);
- return -1;
- }
-
- buf = ast_strdupa(data);
-
- argc = ast_app_separate_args(buf, '|', argv, sizeof(argv) / sizeof(argv[0]));
-
- if (pipe(child_stdin)) {
- ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno));
- goto exit;
- }
-
- if (pipe(child_stdout)) {
- ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child output: %s\n", strerror(errno));
- goto exit;
- }
-
- if (pipe(child_stderr)) {
- ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child errors: %s\n", strerror(errno));
- goto exit;
- }
-
- if (chan->_state != AST_STATE_UP) {
- ast_answer(chan);
- }
-
- if (ast_activate_generator(chan, &gen, u) < 0) {
- ast_chan_log(LOG_WARNING, chan, "Failed to activate generator\n");
- goto exit;
- } else
- gen_active = 1;
-
- pid = fork();
- if (pid < 0) {
- ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
- goto exit;
- }
-
- if (!pid) {
- /* child process */
- int i;
-
- signal(SIGPIPE, SIG_DFL);
- pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
-
- if (ast_opt_high_priority)
- ast_set_priority(0);
-
- dup2(child_stdin[0], STDIN_FILENO);
- dup2(child_stdout[1], STDOUT_FILENO);
- dup2(child_stderr[1], STDERR_FILENO);
- for (i = STDERR_FILENO + 1; i < 1024; i++)
- close(i);
- execv(argv[0], argv);
- fprintf(stderr, "Failed to execute '%s': %s\n", argv[0], strerror(errno));
- _exit(1);
- } else {
- /* parent process */
- int child_events_fd = child_stdin[1];
- int child_commands_fd = child_stdout[0];
- int child_errors_fd = child_stderr[0];
- struct ast_frame *f;
- int ms;
- int exception;
- int ready_fd;
- int waitfds[2] = { child_errors_fd, child_commands_fd };
- struct ast_channel *rchan;
-
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-
- close(child_stdin[0]);
- child_stdin[0] = 0;
- close(child_stdout[1]);
- child_stdout[1] = 0;
- close(child_stderr[1]);
- child_stderr[1] = 0;
-
- if (!(child_events = fdopen(child_events_fd, "w"))) {
- ast_chan_log(LOG_WARNING, chan, "Could not open stream for child events\n");
- goto exit;
- }
-
- if (!(child_commands = fdopen(child_commands_fd, "r"))) {
- ast_chan_log(LOG_WARNING, chan, "Could not open stream for child commands\n");
- goto exit;
- }
-
- if (!(child_errors = fdopen(child_errors_fd, "r"))) {
- ast_chan_log(LOG_WARNING, chan, "Could not open stream for child errors\n");
- goto exit;
- }
-
- setvbuf(child_events, NULL, _IONBF, 0);
- setvbuf(child_commands, NULL, _IONBF, 0);
- setvbuf(child_errors, NULL, _IONBF, 0);
-
- res = 0;
-
- while (1) {
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
- ast_chan_log(LOG_NOTICE, chan, "Is a zombie\n");
- res = -1;
- break;
- }
-
- if (ast_check_hangup(chan)) {
- ast_chan_log(LOG_NOTICE, chan, "Got check_hangup\n");
- send_child_event(child_events, 'H', NULL, chan);
- res = -1;
- break;
- }
-
- ready_fd = 0;
- ms = 100;
- errno = 0;
- exception = 0;
-
- rchan = ast_waitfor_nandfds(&chan, 1, waitfds, 2, &exception, &ready_fd, &ms);
-
- if (!AST_LIST_EMPTY(&u->finishlist)) {
- AST_LIST_LOCK(&u->finishlist);
- while ((entry = AST_LIST_REMOVE_HEAD(&u->finishlist, list))) {
- send_child_event(child_events, 'F', entry->filename, chan);
- free(entry);
- }
- AST_LIST_UNLOCK(&u->finishlist);
- }
-
- if (rchan) {
- /* the channel has something */
- f = ast_read(chan);
- if (!f) {
- ast_chan_log(LOG_NOTICE, chan, "Returned no frame\n");
- send_child_event(child_events, 'H', NULL, chan);
- res = -1;
- break;
- }
-
- if (f->frametype == AST_FRAME_DTMF) {
- send_child_event(child_events, f->subclass, NULL, chan);
- if (u->option_autoclear) {
- if (!u->abort_current_sound && !u->playing_silence)
- send_child_event(child_events, 'T', NULL, chan);
- AST_LIST_LOCK(&u->playlist);
- while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
- send_child_event(child_events, 'D', entry->filename, chan);
- free(entry);
- }
- if (!u->playing_silence)
- u->abort_current_sound = 1;
- AST_LIST_UNLOCK(&u->playlist);
- }
- } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
- ast_chan_log(LOG_NOTICE, chan, "Got AST_CONTROL_HANGUP\n");
- send_child_event(child_events, 'H', NULL, chan);
- ast_frfree(f);
- res = -1;
- break;
- }
- ast_frfree(f);
- } else if (ready_fd == child_commands_fd) {
- char input[1024];
-
- if (exception || feof(child_commands)) {
- ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
- res = -1;
- break;
- }
-
- if (!fgets(input, sizeof(input), child_commands))
- continue;
-
- command = ast_strip(input);
-
- ast_chan_log(LOG_DEBUG, chan, "got command '%s'\n", input);
-
- if (strlen(input) < 4)
- continue;
-
- if (input[0] == 'S') {
- if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
- ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
- send_child_event(child_events, 'Z', NULL, chan);
- strcpy(&input[2], "exception");
- }
- if (!u->abort_current_sound && !u->playing_silence)
- send_child_event(child_events, 'T', NULL, chan);
- AST_LIST_LOCK(&u->playlist);
- while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
- send_child_event(child_events, 'D', entry->filename, chan);
- free(entry);
- }
- if (!u->playing_silence)
- u->abort_current_sound = 1;
- entry = make_entry(&input[2]);
- if (entry)
- AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
- AST_LIST_UNLOCK(&u->playlist);
- } else if (input[0] == 'A') {
- if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
- ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
- send_child_event(child_events, 'Z', NULL, chan);
- strcpy(&input[2], "exception");
- }
- entry = make_entry(&input[2]);
- if (entry) {
- AST_LIST_LOCK(&u->playlist);
- AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
- AST_LIST_UNLOCK(&u->playlist);
- }
- } else if (input[0] == 'H') {
- ast_chan_log(LOG_NOTICE, chan, "Hanging up: %s\n", &input[2]);
- send_child_event(child_events, 'H', NULL, chan);
- break;
- } else if (input[0] == 'O') {
- if (!strcasecmp(&input[2], "autoclear"))
- u->option_autoclear = 1;
- else if (!strcasecmp(&input[2], "noautoclear"))
- u->option_autoclear = 0;
- else
- ast_chan_log(LOG_WARNING, chan, "Unknown option requested '%s'\n", &input[2]);
- }
- } else if (ready_fd == child_errors_fd) {
- char input[1024];
-
- if (exception || feof(child_errors)) {
- ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
- res = -1;
- break;
- }
-
- if (fgets(input, sizeof(input), child_errors)) {
- command = ast_strip(input);
- ast_chan_log(LOG_NOTICE, chan, "stderr: %s\n", command);
- }
- } else if ((ready_fd < 0) && ms) {
- if (errno == 0 || errno == EINTR)
- continue;
-
- ast_chan_log(LOG_WARNING, chan, "Wait failed (%s)\n", strerror(errno));
- break;
- }
- }
- }
-
- exit:
- if (gen_active)
- ast_deactivate_generator(chan);
-
- if (child_events)
- fclose(child_events);
-
- if (child_commands)
- fclose(child_commands);
-
- if (child_errors)
- fclose(child_errors);
-
- if (child_stdin[0])
- close(child_stdin[0]);
-
- if (child_stdin[1])
- close(child_stdin[1]);
-
- if (child_stdout[0])
- close(child_stdout[0]);
-
- if (child_stdout[1])
- close(child_stdout[1]);
-
- if (child_stderr[0])
- close(child_stderr[0]);
-
- if (child_stderr[1])
- close(child_stderr[1]);
-
- while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
- free(entry);
-
- ast_module_user_remove(lu);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, app_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "External IVR Interface Application");
diff --git a/1.4/apps/app_festival.c b/1.4/apps/app_festival.c
deleted file mode 100644
index 2aceceefd..000000000
--- a/1.4/apps/app_festival.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2002, Christos Ricudis
- *
- * Christos Ricudis <ricudis@itc.auth.gr>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Connect to festival
- *
- * \author Christos Ricudis <ricudis@itc.auth.gr>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/md5.h"
-#include "asterisk/config.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-
-#define FESTIVAL_CONFIG "festival.conf"
-
-static char *app = "Festival";
-
-static char *synopsis = "Say text to the user";
-
-static char *descrip =
-" Festival(text[|intkeys]): Connect to Festival, send the argument, get back the waveform,"
-"play it to the user, allowing any given interrupt keys to immediately terminate and return\n"
-"the value, or 'any' to allow any number back (useful in dialplan)\n";
-
-
-static char *socket_receive_file_to_buff(int fd,int *size)
-{
- /* Receive file (probably a waveform file) from socket using */
- /* Festival key stuff technique, but long winded I know, sorry */
- /* but will receive any file without closeing the stream or */
- /* using OOB data */
- static char *file_stuff_key = "ft_StUfF_key"; /* must == Festival's key */
- char *buff;
- int bufflen;
- int n,k,i;
- char c;
-
- bufflen = 1024;
- if (!(buff = ast_malloc(bufflen)))
- {
- /* TODO: Handle memory allocation failure */
- }
- *size=0;
-
- for (k=0; file_stuff_key[k] != '\0';)
- {
- n = read(fd,&c,1);
- if (n==0) break; /* hit stream eof before end of file */
- if ((*size)+k+1 >= bufflen)
- { /* +1 so you can add a NULL if you want */
- bufflen += bufflen/4;
- if (!(buff = ast_realloc(buff, bufflen)))
- {
- /* TODO: Handle memory allocation failure */
- }
- }
- if (file_stuff_key[k] == c)
- k++;
- else if ((c == 'X') && (file_stuff_key[k+1] == '\0'))
- { /* It looked like the key but wasn't */
- for (i=0; i < k; i++,(*size)++)
- buff[*size] = file_stuff_key[i];
- k=0;
- /* omit the stuffed 'X' */
- }
- else
- {
- for (i=0; i < k; i++,(*size)++)
- buff[*size] = file_stuff_key[i];
- k=0;
- buff[*size] = c;
- (*size)++;
- }
-
- }
-
- return buff;
-}
-
-static int send_waveform_to_fd(char *waveform, int length, int fd) {
-
- int res;
- int x;
-#ifdef __PPC__
- char c;
-#endif
- sigset_t fullset, oldset;
-
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
-
- res = fork();
- if (res < 0)
- ast_log(LOG_WARNING, "Fork failed\n");
- if (res) {
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- return res;
- }
- for (x=0;x<256;x++) {
- if (x != fd)
- close(x);
- }
- if (ast_opt_high_priority)
- ast_set_priority(0);
- signal(SIGPIPE, SIG_DFL);
- pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
-/*IAS */
-#ifdef __PPC__
- for( x=0; x<length; x+=2)
- {
- c = *(waveform+x+1);
- *(waveform+x+1)=*(waveform+x);
- *(waveform+x)=c;
- }
-#endif
-
- write(fd,waveform,length);
- close(fd);
- exit(0);
-}
-
-
-static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, int length, char *intkeys) {
- int res=0;
- int fds[2];
- int ms = -1;
- int pid = -1;
- int needed = 0;
- int owriteformat;
- struct ast_frame *f;
- struct myframe {
- struct ast_frame f;
- char offset[AST_FRIENDLY_OFFSET];
- char frdata[2048];
- } myf = {
- .f = { 0, },
- };
-
- if (pipe(fds)) {
- ast_log(LOG_WARNING, "Unable to create pipe\n");
- return -1;
- }
-
- /* Answer if it's not already going */
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
- ast_stopstream(chan);
- ast_indicate(chan, -1);
-
- owriteformat = chan->writeformat;
- res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
- return -1;
- }
-
- res=send_waveform_to_fd(waveform,length,fds[1]);
- if (res >= 0) {
- pid = res;
- /* Order is important -- there's almost always going to be mp3... we want to prioritize the
- user */
- for (;;) {
- ms = 1000;
- res = ast_waitfor(chan, ms);
- if (res < 1) {
- res = -1;
- break;
- }
- f = ast_read(chan);
- if (!f) {
- ast_log(LOG_WARNING, "Null frame == hangup() detected\n");
- res = -1;
- break;
- }
- if (f->frametype == AST_FRAME_DTMF) {
- ast_log(LOG_DEBUG, "User pressed a key\n");
- if (intkeys && strchr(intkeys, f->subclass)) {
- res = f->subclass;
- ast_frfree(f);
- break;
- }
- }
- if (f->frametype == AST_FRAME_VOICE) {
- /* Treat as a generator */
- needed = f->samples * 2;
- if (needed > sizeof(myf.frdata)) {
- ast_log(LOG_WARNING, "Only able to deliver %d of %d requested samples\n",
- (int)sizeof(myf.frdata) / 2, needed/2);
- needed = sizeof(myf.frdata);
- }
- res = read(fds[0], myf.frdata, needed);
- if (res > 0) {
- myf.f.frametype = AST_FRAME_VOICE;
- myf.f.subclass = AST_FORMAT_SLINEAR;
- myf.f.datalen = res;
- myf.f.samples = res / 2;
- myf.f.offset = AST_FRIENDLY_OFFSET;
- myf.f.src = __PRETTY_FUNCTION__;
- myf.f.data = myf.frdata;
- if (ast_write(chan, &myf.f) < 0) {
- res = -1;
- ast_frfree(f);
- break;
- }
- if (res < needed) { /* last frame */
- ast_log(LOG_DEBUG, "Last frame\n");
- res=0;
- ast_frfree(f);
- break;
- }
- } else {
- ast_log(LOG_DEBUG, "No more waveform\n");
- res = 0;
- }
- }
- ast_frfree(f);
- }
- }
- close(fds[0]);
- close(fds[1]);
-
-/* if (pid > -1) */
-/* kill(pid, SIGKILL); */
- if (!res && owriteformat)
- ast_set_write_format(chan, owriteformat);
- return res;
-}
-
-#define MAXLEN 180
-#define MAXFESTLEN 2048
-
-
-
-
-static int festival_exec(struct ast_channel *chan, void *vdata)
-{
- int usecache;
- int res=0;
- struct ast_module_user *u;
- struct sockaddr_in serv_addr;
- struct hostent *serverhost;
- struct ast_hostent ahp;
- int fd;
- FILE *fs;
- const char *host;
- const char *cachedir;
- const char *temp;
- const char *festivalcommand;
- int port=1314;
- int n;
- char ack[4];
- char *waveform;
- int filesize;
- int wave;
- char bigstring[MAXFESTLEN];
- int i;
- struct MD5Context md5ctx;
- unsigned char MD5Res[16];
- char MD5Hex[33] = "";
- char koko[4] = "";
- char cachefile[MAXFESTLEN]="";
- int readcache=0;
- int writecache=0;
- int strln;
- int fdesc = -1;
- char buffer[16384];
- int seekpos = 0;
- char *data;
- char *intstr;
- struct ast_config *cfg;
- char *newfestivalcommand;
-
- if (ast_strlen_zero(vdata)) {
- ast_log(LOG_WARNING, "festival requires an argument (text)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- cfg = ast_config_load(FESTIVAL_CONFIG);
- if (!cfg) {
- ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
- ast_module_user_remove(u);
- return -1;
- }
- if (!(host = ast_variable_retrieve(cfg, "general", "host"))) {
- host = "localhost";
- }
- if (!(temp = ast_variable_retrieve(cfg, "general", "port"))) {
- port = 1314;
- } else {
- port = atoi(temp);
- }
- if (!(temp = ast_variable_retrieve(cfg, "general", "usecache"))) {
- usecache=0;
- } else {
- usecache = ast_true(temp);
- }
- if (!(cachedir = ast_variable_retrieve(cfg, "general", "cachedir"))) {
- cachedir = "/tmp/";
- }
- if (!(festivalcommand = ast_variable_retrieve(cfg, "general", "festivalcommand"))) {
- festivalcommand = "(tts_textasterisk \"%s\" 'file)(quit)\n";
- } else { /* This else parses the festivalcommand that we're sent from the config file for \n's, etc */
- int i, j;
- newfestivalcommand = alloca(strlen(festivalcommand) + 1);
-
- for (i = 0, j = 0; i < strlen(festivalcommand); i++) {
- if (festivalcommand[i] == '\\' && festivalcommand[i + 1] == 'n') {
- newfestivalcommand[j++] = '\n';
- i++;
- } else if (festivalcommand[i] == '\\') {
- newfestivalcommand[j++] = festivalcommand[i + 1];
- i++;
- } else
- newfestivalcommand[j++] = festivalcommand[i];
- }
- newfestivalcommand[j] = '\0';
- festivalcommand = newfestivalcommand;
- }
-
- data = ast_strdupa(vdata);
-
- intstr = strchr(data, '|');
- if (intstr) {
- *intstr = '\0';
- intstr++;
- if (!strcasecmp(intstr, "any"))
- intstr = AST_DIGIT_ANY;
- }
-
- ast_log(LOG_DEBUG, "Text passed to festival server : %s\n",(char *)data);
- /* Connect to local festival server */
-
- fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- if (fd < 0) {
- ast_log(LOG_WARNING,"festival_client: can't get socket\n");
- ast_config_destroy(cfg);
- ast_module_user_remove(u);
- return -1;
- }
- memset(&serv_addr, 0, sizeof(serv_addr));
- if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
- /* its a name rather than an ipnum */
- serverhost = ast_gethostbyname(host, &ahp);
- if (serverhost == (struct hostent *)0) {
- ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n");
- ast_config_destroy(cfg);
- ast_module_user_remove(u);
- return -1;
- }
- memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
- }
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(port);
-
- if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
- ast_log(LOG_WARNING,"festival_client: connect to server failed\n");
- ast_config_destroy(cfg);
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Compute MD5 sum of string */
- MD5Init(&md5ctx);
- MD5Update(&md5ctx,(unsigned char const *)data,strlen(data));
- MD5Final(MD5Res,&md5ctx);
- MD5Hex[0] = '\0';
-
- /* Convert to HEX and look if there is any matching file in the cache
- directory */
- for (i=0;i<16;i++) {
- snprintf(koko, sizeof(koko), "%X",MD5Res[i]);
- strncat(MD5Hex, koko, sizeof(MD5Hex) - strlen(MD5Hex) - 1);
- }
- readcache=0;
- writecache=0;
- if (strlen(cachedir)+strlen(MD5Hex)+1<=MAXFESTLEN && (usecache==-1)) {
- snprintf(cachefile, sizeof(cachefile), "%s/%s", cachedir, MD5Hex);
- fdesc=open(cachefile,O_RDWR);
- if (fdesc==-1) {
- fdesc=open(cachefile,O_CREAT|O_RDWR,0777);
- if (fdesc!=-1) {
- writecache=1;
- strln=strlen((char *)data);
- ast_log(LOG_DEBUG,"line length : %d\n",strln);
- write(fdesc,&strln,sizeof(int));
- write(fdesc,data,strln);
- seekpos=lseek(fdesc,0,SEEK_CUR);
- ast_log(LOG_DEBUG,"Seek position : %d\n",seekpos);
- }
- } else {
- read(fdesc,&strln,sizeof(int));
- ast_log(LOG_DEBUG,"Cache file exists, strln=%d, strlen=%d\n",strln,(int)strlen((char *)data));
- if (strlen((char *)data)==strln) {
- ast_log(LOG_DEBUG,"Size OK\n");
- read(fdesc,&bigstring,strln);
- bigstring[strln] = 0;
- if (strcmp(bigstring,data)==0) {
- readcache=1;
- } else {
- ast_log(LOG_WARNING,"Strings do not match\n");
- }
- } else {
- ast_log(LOG_WARNING,"Size mismatch\n");
- }
- }
- }
-
- if (readcache==1) {
- close(fd);
- fd=fdesc;
- ast_log(LOG_DEBUG,"Reading from cache...\n");
- } else {
- ast_log(LOG_DEBUG,"Passing text to festival...\n");
- fs=fdopen(dup(fd),"wb");
- fprintf(fs,festivalcommand,(char *)data);
- fflush(fs);
- fclose(fs);
- }
-
- /* Write to cache and then pass it down */
- if (writecache==1) {
- ast_log(LOG_DEBUG,"Writing result to cache...\n");
- while ((strln=read(fd,buffer,16384))!=0) {
- write(fdesc,buffer,strln);
- }
- close(fd);
- close(fdesc);
- fd=open(cachefile,O_RDWR);
- lseek(fd,seekpos,SEEK_SET);
- }
-
- ast_log(LOG_DEBUG,"Passing data to channel...\n");
-
- /* Read back info from server */
- /* This assumes only one waveform will come back, also LP is unlikely */
- wave = 0;
- do {
- int read_data;
- for (n=0; n < 3; )
- {
- read_data = read(fd,ack+n,3-n);
- /* this avoids falling in infinite loop
- * in case that festival server goes down
- * */
- if ( read_data == -1 )
- {
- ast_log(LOG_WARNING,"Unable to read from cache/festival fd\n");
- close(fd);
- ast_config_destroy(cfg);
- ast_module_user_remove(u);
- return -1;
- }
- n += read_data;
- }
- ack[3] = '\0';
- if (strcmp(ack,"WV\n") == 0) { /* receive a waveform */
- ast_log(LOG_DEBUG,"Festival WV command\n");
- waveform = socket_receive_file_to_buff(fd,&filesize);
- res = send_waveform_to_channel(chan,waveform,filesize, intstr);
- free(waveform);
- break;
- }
- else if (strcmp(ack,"LP\n") == 0) { /* receive an s-expr */
- ast_log(LOG_DEBUG,"Festival LP command\n");
- waveform = socket_receive_file_to_buff(fd,&filesize);
- waveform[filesize]='\0';
- ast_log(LOG_WARNING,"Festival returned LP : %s\n",waveform);
- free(waveform);
- } else if (strcmp(ack,"ER\n") == 0) { /* server got an error */
- ast_log(LOG_WARNING,"Festival returned ER\n");
- res=-1;
- break;
- }
- } while (strcmp(ack,"OK\n") != 0);
- close(fd);
- ast_config_destroy(cfg);
- ast_module_user_remove(u);
- return res;
-
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- struct ast_config *cfg = ast_config_load(FESTIVAL_CONFIG);
- if (!cfg) {
- ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
- return AST_MODULE_LOAD_DECLINE;
- }
- ast_config_destroy(cfg);
- return ast_register_application(app, festival_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple Festival Interface");
diff --git a/1.4/apps/app_flash.c b/1.4/apps/app_flash.c
deleted file mode 100644
index 1aa099d71..000000000
--- a/1.4/apps/app_flash.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to flash a zap trunk
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <zaptel/zaptel.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/options.h"
-
-static char *app = "Flash";
-
-static char *synopsis = "Flashes a Zap Trunk";
-
-static char *descrip =
-"Performs a flash on a zap trunk. This can be used\n"
-"to access features provided on an incoming analogue circuit\n"
-"such as conference and call waiting. Use with SendDTMF() to\n"
-"perform external transfers\n";
-
-
-static inline int zt_wait_event(int fd)
-{
- /* Avoid the silly zt_waitevent which ignores a bunch of events */
- int i,j=0;
- i = ZT_IOMUX_SIGEVENT;
- if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1;
- if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
- return j;
-}
-
-static int flash_exec(struct ast_channel *chan, void *data)
-{
- int res = -1;
- int x;
- struct ast_module_user *u;
- struct zt_params ztp;
- u = ast_module_user_add(chan);
- if (!strcasecmp(chan->tech->type, "Zap")) {
- memset(&ztp, 0, sizeof(ztp));
- res = ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp);
- if (!res) {
- if (ztp.sigtype & __ZT_SIG_FXS) {
- x = ZT_FLASH;
- res = ioctl(chan->fds[0], ZT_HOOK, &x);
- if (!res || (errno == EINPROGRESS)) {
- if (res) {
- /* Wait for the event to finish */
- zt_wait_event(chan->fds[0]);
- }
- res = ast_safe_sleep(chan, 1000);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Flashed channel %s\n", chan->name);
- } else
- ast_log(LOG_WARNING, "Unable to flash channel %s: %s\n", chan->name, strerror(errno));
- } else
- ast_log(LOG_WARNING, "%s is not an FXO Channel\n", chan->name);
- } else
- ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", chan->name, strerror(errno));
- } else
- ast_log(LOG_WARNING, "%s is not a Zap channel\n", chan->name);
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, flash_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Flash channel application");
-
diff --git a/1.4/apps/app_followme.c b/1.4/apps/app_followme.c
deleted file mode 100644
index d383cf989..000000000
--- a/1.4/apps/app_followme.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * A full-featured Find-Me/Follow-Me Application
- *
- * Copyright (C) 2005-2006, BJ Weschke All Rights Reserved.
- *
- * BJ Weschke <bweschke@btwtech.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief Find-Me Follow-Me application
- *
- * \author BJ Weschke <bweschke@btwtech.com>
- *
- * \arg See \ref Config_followme
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>chan_local</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/say.h"
-#include "asterisk/features.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/cli.h"
-#include "asterisk/manager.h"
-#include "asterisk/config.h"
-#include "asterisk/monitor.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/astdb.h"
-#include "asterisk/app.h"
-
-static char *app = "FollowMe";
-static char *synopsis = "Find-Me/Follow-Me application";
-static char *descrip =
-" FollowMe(followmeid|options):\n"
-"This application performs Find-Me/Follow-Me functionality for the caller\n"
-"as defined in the profile matching the <followmeid> parameter in\n"
-"followme.conf. If the specified <followmeid> profile doesn't exist in\n"
-"followme.conf, execution will be returned to the dialplan and call\n"
-"execution will continue at the next priority.\n\n"
-" Options:\n"
-" s - Playback the incoming status message prior to starting the follow-me step(s)\n"
-" a - Record the caller's name so it can be announced to the callee on each step\n"
-" n - Playback the unreachable status message if we've run out of steps to reach the\n"
-" or the callee has elected not to be reachable.\n"
-"Returns -1 on hangup\n";
-
-/*! \brief Number structure */
-struct number {
- char number[512]; /*!< Phone Number(s) and/or Extension(s) */
- long timeout; /*!< Dial Timeout, if used. */
- char language[MAX_LANGUAGE]; /*!< The language to be used on this dial, if used. */
- int order; /*!< The order to dial in */
- AST_LIST_ENTRY(number) entry; /*!< Next Number record */
-};
-
-/*! \brief Data structure for followme scripts */
-struct call_followme {
- ast_mutex_t lock;
- char name[AST_MAX_EXTENSION]; /*!< Name - FollowMeID */
- char moh[AST_MAX_CONTEXT]; /*!< Music On Hold Class to be used */
- char context[AST_MAX_CONTEXT]; /*!< Context to dial from */
- unsigned int active; /*!< Profile is active (1), or disabled (0). */
- char takecall[20]; /*!< Digit mapping to take a call */
- char nextindp[20]; /*!< Digit mapping to decline a call */
- char callfromprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char norecordingprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char optionsprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char plsholdprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char statusprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char sorryprompt[PATH_MAX]; /*!< Sound prompt name and path */
-
- AST_LIST_HEAD_NOLOCK(numbers, number) numbers; /*!< Head of the list of follow-me numbers */
- AST_LIST_HEAD_NOLOCK(blnumbers, number) blnumbers; /*!< Head of the list of black-listed numbers */
- AST_LIST_HEAD_NOLOCK(wlnumbers, number) wlnumbers; /*!< Head of the list of white-listed numbers */
- AST_LIST_ENTRY(call_followme) entry; /*!< Next Follow-Me record */
-};
-
-struct fm_args {
- struct ast_channel *chan;
- char *mohclass;
- AST_LIST_HEAD_NOLOCK(cnumbers, number) cnumbers;
- int status;
- char context[AST_MAX_CONTEXT];
- char namerecloc[AST_MAX_CONTEXT];
- struct ast_channel *outbound;
- char takecall[20]; /*!< Digit mapping to take a call */
- char nextindp[20]; /*!< Digit mapping to decline a call */
- char callfromprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char norecordingprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char optionsprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char plsholdprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char statusprompt[PATH_MAX]; /*!< Sound prompt name and path */
- char sorryprompt[PATH_MAX]; /*!< Sound prompt name and path */
- struct ast_flags followmeflags;
-};
-
-struct findme_user {
- struct ast_channel *ochan;
- int state;
- char dialarg[256];
- char yn[10];
- int ynidx;
- long digts;
- int cleared;
- AST_LIST_ENTRY(findme_user) entry;
-};
-
-enum {
- FOLLOWMEFLAG_STATUSMSG = (1 << 0),
- FOLLOWMEFLAG_RECORDNAME = (1 << 1),
- FOLLOWMEFLAG_UNREACHABLEMSG = (1 << 2)
-};
-
-AST_APP_OPTIONS(followme_opts, {
- AST_APP_OPTION('s', FOLLOWMEFLAG_STATUSMSG ),
- AST_APP_OPTION('a', FOLLOWMEFLAG_RECORDNAME ),
- AST_APP_OPTION('n', FOLLOWMEFLAG_UNREACHABLEMSG ),
-});
-
-static int ynlongest = 0;
-static time_t start_time, answer_time, end_time;
-
-static const char *featuredigittostr;
-static int featuredigittimeout = 5000; /*!< Feature Digit Timeout */
-static const char *defaultmoh = "default"; /*!< Default Music-On-Hold Class */
-
-static char takecall[20] = "1", nextindp[20] = "2";
-static char callfromprompt[PATH_MAX] = "followme/call-from";
-static char norecordingprompt[PATH_MAX] = "followme/no-recording";
-static char optionsprompt[PATH_MAX] = "followme/options";
-static char plsholdprompt[PATH_MAX] = "followme/pls-hold-while-try";
-static char statusprompt[PATH_MAX] = "followme/status";
-static char sorryprompt[PATH_MAX] = "followme/sorry";
-
-
-static AST_LIST_HEAD_STATIC(followmes, call_followme);
-AST_LIST_HEAD_NOLOCK(findme_user_listptr, findme_user);
-
-static void free_numbers(struct call_followme *f)
-{
- /* Free numbers attached to the profile */
- struct number *prev;
-
- while ((prev = AST_LIST_REMOVE_HEAD(&f->numbers, entry)))
- /* Free the number */
- free(prev);
- AST_LIST_HEAD_INIT_NOLOCK(&f->numbers);
-
- while ((prev = AST_LIST_REMOVE_HEAD(&f->blnumbers, entry)))
- /* Free the blacklisted number */
- free(prev);
- AST_LIST_HEAD_INIT_NOLOCK(&f->blnumbers);
-
- while ((prev = AST_LIST_REMOVE_HEAD(&f->wlnumbers, entry)))
- /* Free the whitelisted number */
- free(prev);
- AST_LIST_HEAD_INIT_NOLOCK(&f->wlnumbers);
-
-}
-
-
-/*! \brief Allocate and initialize followme profile */
-static struct call_followme *alloc_profile(const char *fmname)
-{
- struct call_followme *f;
-
- if (!(f = ast_calloc(1, sizeof(*f))))
- return NULL;
-
- ast_mutex_init(&f->lock);
- ast_copy_string(f->name, fmname, sizeof(f->name));
- f->moh[0] = '\0';
- f->context[0] = '\0';
- ast_copy_string(f->takecall, takecall, sizeof(f->takecall));
- ast_copy_string(f->nextindp, nextindp, sizeof(f->nextindp));
- ast_copy_string(f->callfromprompt, callfromprompt, sizeof(f->callfromprompt));
- ast_copy_string(f->norecordingprompt, norecordingprompt, sizeof(f->norecordingprompt));
- ast_copy_string(f->optionsprompt, optionsprompt, sizeof(f->optionsprompt));
- ast_copy_string(f->plsholdprompt, plsholdprompt, sizeof(f->plsholdprompt));
- ast_copy_string(f->statusprompt, statusprompt, sizeof(f->statusprompt));
- ast_copy_string(f->sorryprompt, sorryprompt, sizeof(f->sorryprompt));
- AST_LIST_HEAD_INIT_NOLOCK(&f->numbers);
- AST_LIST_HEAD_INIT_NOLOCK(&f->blnumbers);
- AST_LIST_HEAD_INIT_NOLOCK(&f->wlnumbers);
- return f;
-}
-
-static void init_profile(struct call_followme *f)
-{
- f->active = 1;
- ast_copy_string(f->moh, defaultmoh, sizeof(f->moh));
-}
-
-
-
-/*! \brief Set parameter in profile from configuration file */
-static void profile_set_param(struct call_followme *f, const char *param, const char *val, int linenum, int failunknown)
-{
-
- if (!strcasecmp(param, "musicclass") || !strcasecmp(param, "musiconhold") || !strcasecmp(param, "music"))
- ast_copy_string(f->moh, val, sizeof(f->moh));
- else if (!strcasecmp(param, "context"))
- ast_copy_string(f->context, val, sizeof(f->context));
- else if (!strcasecmp(param, "takecall"))
- ast_copy_string(f->takecall, val, sizeof(f->takecall));
- else if (!strcasecmp(param, "declinecall"))
- ast_copy_string(f->nextindp, val, sizeof(f->nextindp));
- else if (!strcasecmp(param, "call-from-prompt"))
- ast_copy_string(f->callfromprompt, val, sizeof(f->callfromprompt));
- else if (!strcasecmp(param, "followme-norecording-prompt"))
- ast_copy_string(f->norecordingprompt, val, sizeof(f->norecordingprompt));
- else if (!strcasecmp(param, "followme-options-prompt"))
- ast_copy_string(f->optionsprompt, val, sizeof(f->optionsprompt));
- else if (!strcasecmp(param, "followme-pls-hold-prompt"))
- ast_copy_string(f->plsholdprompt, val, sizeof(f->plsholdprompt));
- else if (!strcasecmp(param, "followme-status-prompt"))
- ast_copy_string(f->statusprompt, val, sizeof(f->statusprompt));
- else if (!strcasecmp(param, "followme-sorry-prompt"))
- ast_copy_string(f->sorryprompt, val, sizeof(f->sorryprompt));
- else if (failunknown) {
- if (linenum >= 0)
- ast_log(LOG_WARNING, "Unknown keyword in profile '%s': %s at line %d of followme.conf\n", f->name, param, linenum);
- else
- ast_log(LOG_WARNING, "Unknown keyword in profile '%s': %s\n", f->name, param);
- }
-}
-
-/*! \brief Add a new number */
-static struct number *create_followme_number(char *number, char *language, int timeout, int numorder)
-{
- struct number *cur;
- char *tmp;
-
-
- if (!(cur = ast_calloc(1, sizeof(*cur))))
- return NULL;
-
- cur->timeout = timeout;
- if ((tmp = strchr(number, ',')))
- *tmp = '\0';
- ast_copy_string(cur->number, number, sizeof(cur->number));
- ast_copy_string(cur->language, language, sizeof(cur->language));
- cur->order = numorder;
- if (option_debug)
- ast_log(LOG_DEBUG, "Created a number, %s, order of , %d, with a timeout of %ld.\n", cur->number, cur->order, cur->timeout);
-
- return cur;
-}
-
-/*! \brief Reload followme application module */
-static int reload_followme(void)
-{
- struct call_followme *f;
- struct ast_config *cfg;
- char *cat = NULL, *tmp;
- struct ast_variable *var;
- struct number *cur, *nm;
- int new, idx;
- char numberstr[90];
- int timeout;
- char *timeoutstr;
- int numorder;
- const char *takecallstr;
- const char *declinecallstr;
- const char *tmpstr;
-
- cfg = ast_config_load("followme.conf");
- if (!cfg) {
- ast_log(LOG_WARNING, "No follow me config file (followme.conf), so no follow me\n");
- return 0;
- }
-
- AST_LIST_LOCK(&followmes);
-
- /* Reset Global Var Values */
- featuredigittimeout = 5000;
-
- /* Mark all profiles as inactive for the moment */
- AST_LIST_TRAVERSE(&followmes, f, entry) {
- f->active = 0;
- }
- featuredigittostr = ast_variable_retrieve(cfg, "general", "featuredigittimeout");
-
- if (!ast_strlen_zero(featuredigittostr)) {
- if (!sscanf(featuredigittostr, "%d", &featuredigittimeout))
- featuredigittimeout = 5000;
- }
-
- takecallstr = ast_variable_retrieve(cfg, "general", "takecall");
- if (!ast_strlen_zero(takecallstr))
- ast_copy_string(takecall, takecallstr, sizeof(takecall));
-
- declinecallstr = ast_variable_retrieve(cfg, "general", "declinecall");
- if (!ast_strlen_zero(declinecallstr))
- ast_copy_string(nextindp, declinecallstr, sizeof(nextindp));
-
- tmpstr = ast_variable_retrieve(cfg, "general", "call-from-prompt");
- if (!ast_strlen_zero(tmpstr))
- ast_copy_string(callfromprompt, tmpstr, sizeof(callfromprompt));
-
- tmpstr = ast_variable_retrieve(cfg, "general", "norecording-prompt");
- if (!ast_strlen_zero(tmpstr))
- ast_copy_string(norecordingprompt, tmpstr, sizeof(norecordingprompt));
-
- tmpstr = ast_variable_retrieve(cfg, "general", "options-prompt");
- if (!ast_strlen_zero(tmpstr))
- ast_copy_string(optionsprompt, tmpstr, sizeof(optionsprompt));
-
- tmpstr = ast_variable_retrieve(cfg, "general", "pls-hold-prompt");
- if (!ast_strlen_zero(tmpstr))
- ast_copy_string(plsholdprompt, tmpstr, sizeof(plsholdprompt));
-
- tmpstr = ast_variable_retrieve(cfg, "general", "status-prompt");
- if (!ast_strlen_zero(tmpstr))
- ast_copy_string(statusprompt, tmpstr, sizeof(statusprompt));
-
- tmpstr = ast_variable_retrieve(cfg, "general", "sorry-prompt");
- if (!ast_strlen_zero(tmpstr))
- ast_copy_string(sorryprompt, tmpstr, sizeof(sorryprompt));
-
- /* Chug through config file */
- while ((cat = ast_category_browse(cfg, cat))) {
- if (!strcasecmp(cat, "general"))
- continue;
- /* Define a new profile */
- /* Look for an existing one */
- AST_LIST_TRAVERSE(&followmes, f, entry) {
- if (!strcasecmp(f->name, cat))
- break;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "New profile %s.\n", cat);
- if (!f) {
- /* Make one then */
- f = alloc_profile(cat);
- new = 1;
- } else
- new = 0;
-
- if (f) {
- if (!new)
- ast_mutex_lock(&f->lock);
- /* Re-initialize the profile */
- init_profile(f);
- free_numbers(f);
- var = ast_variable_browse(cfg, cat);
- while(var) {
- if (!strcasecmp(var->name, "number")) {
- /* Add a new number */
- ast_copy_string(numberstr, var->value, sizeof(numberstr));
- if ((tmp = strchr(numberstr, ','))) {
- *tmp = '\0';
- tmp++;
- timeoutstr = ast_strdupa(tmp);
- if ((tmp = strchr(timeoutstr, ','))) {
- *tmp = '\0';
- tmp++;
- numorder = atoi(tmp);
- if (numorder < 0)
- numorder = 0;
- } else
- numorder = 0;
- timeout = atoi(timeoutstr);
- if (timeout < 0)
- timeout = 25;
- } else {
- timeout = 25;
- numorder = 0;
- }
-
- if (!numorder) {
- idx = 1;
- AST_LIST_TRAVERSE(&f->numbers, nm, entry)
- idx++;
- numorder = idx;
- }
- cur = create_followme_number(numberstr, "", timeout, numorder);
- AST_LIST_INSERT_TAIL(&f->numbers, cur, entry);
- } else {
- profile_set_param(f, var->name, var->value, var->lineno, 1);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Logging parameter %s with value %s from lineno %d\n", var->name, var->value, var->lineno);
- }
- var = var->next;
- } /* End while(var) loop */
-
- if (!new)
- ast_mutex_unlock(&f->lock);
- else
- AST_LIST_INSERT_HEAD(&followmes, f, entry);
- }
- }
- ast_config_destroy(cfg);
-
- AST_LIST_UNLOCK(&followmes);
-
- return 1;
-}
-
-static void clear_caller(struct findme_user *tmpuser)
-{
- struct ast_channel *outbound;
-
- if (tmpuser && tmpuser->ochan && tmpuser->state >= 0) {
- outbound = tmpuser->ochan;
- if (!outbound->cdr) {
- outbound->cdr = ast_cdr_alloc();
- if (outbound->cdr)
- ast_cdr_init(outbound->cdr, outbound);
- }
- if (outbound->cdr) {
- char tmp[256];
-
- snprintf(tmp, sizeof(tmp), "%s/%s", "Local", tmpuser->dialarg);
- ast_cdr_setapp(outbound->cdr, "FollowMe", tmp);
- ast_cdr_update(outbound);
- ast_cdr_start(outbound->cdr);
- ast_cdr_end(outbound->cdr);
- /* If the cause wasn't handled properly */
- if (ast_cdr_disposition(outbound->cdr, outbound->hangupcause))
- ast_cdr_failed(outbound->cdr);
- } else
- ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
- ast_hangup(tmpuser->ochan);
- }
-
-}
-
-static void clear_calling_tree(struct findme_user_listptr *findme_user_list)
-{
- struct findme_user *tmpuser;
-
- AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry) {
- clear_caller(tmpuser);
- tmpuser->cleared = 1;
- }
-
-}
-
-
-
-static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_user_list, struct number *nm, struct ast_channel *caller, char *namerecloc, int *status, struct fm_args *tpargs)
-{
- struct ast_channel *watchers[256];
- int pos;
- struct ast_channel *winner;
- struct ast_frame *f;
- int ctstatus;
- int dg;
- struct findme_user *tmpuser;
- int to = 0;
- int livechannels = 0;
- int tmpto;
- long totalwait = 0, wtd, towas = 0;
- char *callfromname;
- char *pressbuttonname;
-
- /* ------------ wait_for_winner_channel start --------------- */
-
- callfromname = ast_strdupa(tpargs->callfromprompt);
- pressbuttonname = ast_strdupa(tpargs->optionsprompt);
-
- if (!AST_LIST_EMPTY(findme_user_list)) {
- if (!caller) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Original caller hungup. Cleanup.\n");
- clear_calling_tree(findme_user_list);
- return NULL;
- }
- ctstatus = 0;
- totalwait = nm->timeout * 1000;
- wtd = 0;
- while (!ctstatus) {
- to = 1000;
- pos = 1;
- livechannels = 0;
- watchers[0] = caller;
-
- dg = 0;
- winner = NULL;
- AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry) {
- if (tmpuser->state >= 0 && tmpuser->ochan) {
- if (tmpuser->state == 3)
- tmpuser->digts += (towas - wtd);
- if (tmpuser->digts && (tmpuser->digts > featuredigittimeout)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "We've been waiting for digits longer than we should have.\n");
- if (!ast_strlen_zero(namerecloc)) {
- tmpuser->state = 1;
- tmpuser->digts = 0;
- if (!ast_streamfile(tmpuser->ochan, callfromname, tmpuser->ochan->language)) {
- ast_sched_runq(tmpuser->ochan->sched);
- } else {
- ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);
- return NULL;
- }
- } else {
- tmpuser->state = 2;
- tmpuser->digts = 0;
- if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, tmpuser->ochan->language))
- ast_sched_runq(tmpuser->ochan->sched);
- else {
- ast_log(LOG_WARNING, "Unable to playback %s.\n", tpargs->norecordingprompt);
- return NULL;
- }
- }
- }
- if (tmpuser->ochan->stream) {
- ast_sched_runq(tmpuser->ochan->sched);
- tmpto = ast_sched_wait(tmpuser->ochan->sched);
- if (tmpto > 0 && tmpto < to)
- to = tmpto;
- else if (tmpto < 0 && !tmpuser->ochan->timingfunc) {
- ast_stopstream(tmpuser->ochan);
- if (tmpuser->state == 1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playback of the call-from file appears to be done.\n");
- if (!ast_streamfile(tmpuser->ochan, namerecloc, tmpuser->ochan->language)) {
- tmpuser->state = 2;
- } else {
- ast_log(LOG_NOTICE, "Unable to playback %s. Maybe the caller didn't record their name?\n", namerecloc);
- memset(tmpuser->yn, 0, sizeof(tmpuser->yn));
- tmpuser->ynidx = 0;
- if (!ast_streamfile(tmpuser->ochan, pressbuttonname, tmpuser->ochan->language))
- tmpuser->state = 3;
- else {
- ast_log(LOG_WARNING, "Unable to playback %s.\n", pressbuttonname);
- return NULL;
- }
- }
- } else if (tmpuser->state == 2) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playback of name file appears to be done.\n");
- memset(tmpuser->yn, 0, sizeof(tmpuser->yn));
- tmpuser->ynidx = 0;
- if (!ast_streamfile(tmpuser->ochan, pressbuttonname, tmpuser->ochan->language)) {
- tmpuser->state = 3;
-
- } else {
- return NULL;
- }
- } else if (tmpuser->state == 3) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playback of the next step file appears to be done.\n");
- tmpuser->digts = 0;
- }
- }
- }
- watchers[pos++] = tmpuser->ochan;
- livechannels++;
- }
- }
-
- tmpto = to;
- if (to < 0) {
- to = 1000;
- tmpto = 1000;
- }
- towas = to;
- winner = ast_waitfor_n(watchers, pos, &to);
- tmpto -= to;
- totalwait -= tmpto;
- wtd = to;
- if (totalwait <= 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "We've hit our timeout for this step. Drop everyone and move on to the next one. %ld\n", totalwait);
- clear_calling_tree(findme_user_list);
- return NULL;
- }
- if (winner) {
- /* Need to find out which channel this is */
- dg = 0;
- while ((winner != watchers[dg]) && (dg < 256))
- dg++;
- AST_LIST_TRAVERSE(findme_user_list, tmpuser, entry)
- if (tmpuser->ochan == winner)
- break;
- f = ast_read(winner);
- if (f) {
- if (f->frametype == AST_FRAME_CONTROL) {
- switch(f->subclass) {
- case AST_CONTROL_HANGUP:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s received a hangup frame.\n", winner->name);
- if (dg == 0) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "The calling channel hungup. Need to drop everyone else.\n");
- clear_calling_tree(findme_user_list);
- ctstatus = -1;
- }
- break;
- case AST_CONTROL_ANSWER:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", winner->name, caller->name);
- /* If call has been answered, then the eventual hangup is likely to be normal hangup */
- winner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- caller->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Starting playback of %s\n", callfromname);
- if (dg > 0) {
- if (!ast_strlen_zero(namerecloc)) {
- if (!ast_streamfile(winner, callfromname, winner->language)) {
- ast_sched_runq(winner->sched);
- tmpuser->state = 1;
- } else {
- ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);
- ast_frfree(f);
- return NULL;
- }
- } else {
- tmpuser->state = 2;
- if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, tmpuser->ochan->language))
- ast_sched_runq(tmpuser->ochan->sched);
- else {
- ast_log(LOG_WARNING, "Unable to playback %s.\n", tpargs->norecordingprompt);
- ast_frfree(f);
- return NULL;
- }
- }
- }
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", winner->name);
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", winner->name);
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", winner->name);
- break;
- case AST_CONTROL_PROGRESS:
- if (option_verbose > 2)
- ast_verbose ( VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", winner->name, caller->name);
- break;
- case AST_CONTROL_VIDUPDATE:
- if (option_verbose > 2)
- ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", winner->name, caller->name);
- break;
- case AST_CONTROL_SRCUPDATE:
- if (option_verbose > 2)
- ast_verbose ( VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", winner->name, caller->name);
- break;
- case AST_CONTROL_PROCEEDING:
- if (option_verbose > 2)
- ast_verbose ( VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", winner->name,caller->name);
- break;
- case AST_CONTROL_HOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", winner->name);
- break;
- case AST_CONTROL_UNHOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", winner->name);
- break;
- case AST_CONTROL_OFFHOOK:
- case AST_CONTROL_FLASH:
- /* Ignore going off hook and flash */
- break;
- case -1:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", winner->name);
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
- break;
- }
- }
- if (tmpuser && tmpuser->state == 3 && f->frametype == AST_FRAME_DTMF) {
- if (winner->stream)
- ast_stopstream(winner);
- tmpuser->digts = 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "DTMF received: %c\n",(char) f->subclass);
- tmpuser->yn[tmpuser->ynidx] = (char) f->subclass;
- tmpuser->ynidx++;
- if (option_debug)
- ast_log(LOG_DEBUG, "DTMF string: %s\n", tmpuser->yn);
- if (tmpuser->ynidx >= ynlongest) {
- if (option_debug)
- ast_log(LOG_DEBUG, "reached longest possible match - doing evals\n");
- if (!strcmp(tmpuser->yn, tpargs->takecall)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Match to take the call!\n");
- ast_frfree(f);
- return tmpuser->ochan;
- }
- if (!strcmp(tmpuser->yn, tpargs->nextindp)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Next in dial plan step requested.\n");
- *status = 1;
- ast_frfree(f);
- return NULL;
- }
-
- }
- }
-
- ast_frfree(f);
- } else {
- if (winner) {
- if (option_debug)
- ast_log(LOG_DEBUG, "we didn't get a frame. hanging up. dg is %d\n",dg);
- if (!dg) {
- clear_calling_tree(findme_user_list);
- return NULL;
- } else {
- tmpuser->state = -1;
- ast_hangup(winner);
- livechannels--;
- if (option_debug)
- ast_log(LOG_DEBUG, "live channels left %d\n", livechannels);
- if (!livechannels) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "no live channels left. exiting.\n");
- return NULL;
- }
- }
- }
- }
-
- } else
- if (option_debug)
- ast_log(LOG_DEBUG, "timed out waiting for action\n");
- }
-
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "couldn't reach at this number.\n");
- }
-
- /* --- WAIT FOR WINNER NUMBER END! -----------*/
- return NULL;
-}
-
-static void findmeexec(struct fm_args *tpargs)
-{
- struct number *nm;
- struct ast_channel *outbound;
- struct ast_channel *caller;
- struct ast_channel *winner = NULL;
- char dialarg[512];
- int dg, idx;
- char *rest, *number;
- struct findme_user *tmpuser;
- struct findme_user *fmuser;
- struct findme_user *headuser;
- struct findme_user_listptr *findme_user_list;
- int status;
-
- findme_user_list = ast_calloc(1, sizeof(*findme_user_list));
- AST_LIST_HEAD_INIT_NOLOCK(findme_user_list);
-
- /* We're going to figure out what the longest possible string of digits to collect is */
- ynlongest = 0;
- if (strlen(tpargs->takecall) > ynlongest)
- ynlongest = strlen(tpargs->takecall);
- if (strlen(tpargs->nextindp) > ynlongest)
- ynlongest = strlen(tpargs->nextindp);
-
- idx = 1;
- caller = tpargs->chan;
- AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry)
- if (nm->order == idx)
- break;
-
- while (nm) {
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Number %s timeout %ld\n", nm->number,nm->timeout);
- time(&start_time);
-
- number = ast_strdupa(nm->number);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "examining %s\n", number);
- do {
- rest = strchr(number, '&');
- if (rest) {
- *rest = 0;
- rest++;
- }
-
- if (!strcmp(tpargs->context, ""))
- snprintf(dialarg, sizeof(dialarg), "%s", number);
- else
- snprintf(dialarg, sizeof(dialarg), "%s@%s", number, tpargs->context);
-
- tmpuser = ast_calloc(1, sizeof(*tmpuser));
- if (!tmpuser) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- free(findme_user_list);
- return;
- }
-
- outbound = ast_request("Local", ast_best_codec(caller->nativeformats), dialarg, &dg);
- if (outbound) {
- ast_set_callerid(outbound, caller->cid.cid_num, caller->cid.cid_name, caller->cid.cid_num);
- ast_channel_inherit_variables(tpargs->chan, outbound);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "calling %s\n", dialarg);
- if (!ast_call(outbound,dialarg,0)) {
- tmpuser->ochan = outbound;
- tmpuser->state = 0;
- tmpuser->cleared = 0;
- ast_copy_string(tmpuser->dialarg, dialarg, sizeof(dialarg));
- AST_LIST_INSERT_TAIL(findme_user_list, tmpuser, entry);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "couldn't reach at this number.\n");
- if (outbound) {
- if (!outbound->cdr)
- outbound->cdr = ast_cdr_alloc();
- if (outbound->cdr) {
- char tmp[256];
-
- ast_cdr_init(outbound->cdr, outbound);
- snprintf(tmp, sizeof(tmp), "%s/%s", "Local", dialarg);
- ast_cdr_setapp(outbound->cdr, "FollowMe", tmp);
- ast_cdr_update(outbound);
- ast_cdr_start(outbound->cdr);
- ast_cdr_end(outbound->cdr);
- /* If the cause wasn't handled properly */
- if (ast_cdr_disposition(outbound->cdr,outbound->hangupcause))
- ast_cdr_failed(outbound->cdr);
- } else {
- ast_log(LOG_ERROR, "Unable to create Call Detail Record\n");
- ast_hangup(outbound);
- outbound = NULL;
- }
- }
-
- }
- } else
- ast_log(LOG_WARNING, "Unable to allocate a channel for Local/%s cause: %s\n", dialarg, ast_cause2str(dg));
-
- number = rest;
- } while (number);
-
- status = 0;
- if (!AST_LIST_EMPTY(findme_user_list))
- winner = wait_for_winner(findme_user_list, nm, caller, tpargs->namerecloc, &status, tpargs);
-
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(findme_user_list, fmuser, entry) {
- if (!fmuser->cleared && fmuser->ochan != winner)
- clear_caller(fmuser);
- AST_LIST_REMOVE_CURRENT(findme_user_list, entry);
- free(fmuser);
- }
- AST_LIST_TRAVERSE_SAFE_END
- fmuser = NULL;
- tmpuser = NULL;
- headuser = NULL;
- if (winner)
- break;
-
- if (!caller) {
- tpargs->status = 1;
- free(findme_user_list);
- return;
- }
-
- idx++;
- AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry)
- if (nm->order == idx)
- break;
-
- }
- free(findme_user_list);
- if (!winner)
- tpargs->status = 1;
- else {
- tpargs->status = 100;
- tpargs->outbound = winner;
- }
-
-
- return;
-
-}
-
-static int app_exec(struct ast_channel *chan, void *data)
-{
- struct fm_args targs;
- struct ast_bridge_config config;
- struct call_followme *f;
- struct number *nm, *newnm;
- int res = 0;
- struct ast_module_user *u;
- char *argstr;
- char namerecloc[255];
- char *fname = NULL;
- int duration = 0;
- struct ast_channel *caller;
- struct ast_channel *outbound;
- static char toast[80];
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(followmeid);
- AST_APP_ARG(options);
- );
-
- if (!(argstr = ast_strdupa((char *)data))) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- return -1;
- }
-
- if (!data) {
- ast_log(LOG_WARNING, "%s requires an argument (followmeid)\n",app);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- AST_STANDARD_APP_ARGS(args, argstr);
-
- if (!ast_strlen_zero(args.followmeid))
- AST_LIST_LOCK(&followmes);
- AST_LIST_TRAVERSE(&followmes, f, entry) {
- if (!strcasecmp(f->name, args.followmeid) && (f->active))
- break;
- }
- AST_LIST_UNLOCK(&followmes);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "New profile %s.\n", args.followmeid);
- if (!f) {
- ast_log(LOG_WARNING, "Profile requested, %s, not found in the configuration.\n", args.followmeid);
- res = 0;
- } else {
- /* XXX TODO: Reinsert the db check value to see whether or not follow-me is on or off */
-
-
- if (args.options)
- ast_app_parse_options(followme_opts, &targs.followmeflags, NULL, args.options);
-
- /* Lock the profile lock and copy out everything we need to run with before unlocking it again */
- ast_mutex_lock(&f->lock);
- targs.mohclass = ast_strdupa(f->moh);
- ast_copy_string(targs.context, f->context, sizeof(targs.context));
- ast_copy_string(targs.takecall, f->takecall, sizeof(targs.takecall));
- ast_copy_string(targs.nextindp, f->nextindp, sizeof(targs.nextindp));
- ast_copy_string(targs.callfromprompt, f->callfromprompt, sizeof(targs.callfromprompt));
- ast_copy_string(targs.norecordingprompt, f->norecordingprompt, sizeof(targs.norecordingprompt));
- ast_copy_string(targs.optionsprompt, f->optionsprompt, sizeof(targs.optionsprompt));
- ast_copy_string(targs.plsholdprompt, f->plsholdprompt, sizeof(targs.plsholdprompt));
- ast_copy_string(targs.statusprompt, f->statusprompt, sizeof(targs.statusprompt));
- ast_copy_string(targs.sorryprompt, f->sorryprompt, sizeof(targs.sorryprompt));
- /* Copy the numbers we're going to use into another list in case the master list should get modified
- (and locked) while we're trying to do a follow-me */
- AST_LIST_HEAD_INIT_NOLOCK(&targs.cnumbers);
- AST_LIST_TRAVERSE(&f->numbers, nm, entry) {
- newnm = create_followme_number(nm->number, "", nm->timeout, nm->order);
- AST_LIST_INSERT_TAIL(&targs.cnumbers, newnm, entry);
- }
- ast_mutex_unlock(&f->lock);
-
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_STATUSMSG))
- ast_stream_and_wait(chan, targs.statusprompt, chan->language, "");
-
- snprintf(namerecloc,sizeof(namerecloc),"%s/followme.%s",ast_config_AST_SPOOL_DIR,chan->uniqueid);
- duration = 5;
-
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_RECORDNAME))
- if (ast_play_and_record(chan, "vm-rec-name", namerecloc, 5, "sln", &duration, 128, 0, NULL) < 0)
- goto outrun;
-
- if (!ast_fileexists(namerecloc, NULL, chan->language))
- ast_copy_string(namerecloc, "", sizeof(namerecloc));
-
- if (ast_streamfile(chan, targs.plsholdprompt, chan->language))
- goto outrun;
- if (ast_waitstream(chan, "") < 0)
- goto outrun;
- ast_moh_start(chan, S_OR(targs.mohclass, NULL), NULL);
-
- targs.status = 0;
- targs.chan = chan;
- ast_copy_string(targs.namerecloc, namerecloc, sizeof(targs.namerecloc));
-
- findmeexec(&targs);
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&targs.cnumbers, nm, entry) {
- AST_LIST_REMOVE_CURRENT(&targs.cnumbers, entry);
- free(nm);
- }
- AST_LIST_TRAVERSE_SAFE_END
- if (targs.status != 100) {
- ast_moh_stop(chan);
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_UNREACHABLEMSG))
- ast_stream_and_wait(chan, targs.sorryprompt, chan->language, "");
- res = 0;
- } else {
- caller = chan;
- outbound = targs.outbound;
- /* Bridge the two channels. */
-
- memset(&config,0,sizeof(struct ast_bridge_config));
- ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
- ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
- ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
-
- ast_moh_stop(caller);
- /* Be sure no generators are left on it */
- ast_deactivate_generator(caller);
- /* Make sure channels are compatible */
- res = ast_channel_make_compatible(caller, outbound);
- if (res < 0) {
- ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", caller->name, outbound->name);
- ast_hangup(outbound);
- goto outrun;
- }
- time(&answer_time);
- res = ast_bridge_call(caller,outbound,&config);
- time(&end_time);
- snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
- pbx_builtin_setvar_helper(caller, "DIALEDTIME", toast);
- snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
- pbx_builtin_setvar_helper(caller, "ANSWEREDTIME", toast);
- if (outbound)
- ast_hangup(outbound);
- }
- }
- outrun:
-
- if (!ast_strlen_zero(namerecloc)){
- fname = alloca(strlen(namerecloc) + 5);
- sprintf(fname, "%s.sln", namerecloc);
- unlink(fname);
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- struct call_followme *f;
-
- ast_module_user_hangup_all();
-
- ast_unregister_application(app);
-
- /* Free Memory. Yeah! I'm free! */
- AST_LIST_LOCK(&followmes);
- while ((f = AST_LIST_REMOVE_HEAD(&followmes, entry))) {
- free_numbers(f);
- free(f);
- }
-
- AST_LIST_UNLOCK(&followmes);
-
- return 0;
-}
-
-static int load_module(void)
-{
- if(!reload_followme())
- return AST_MODULE_LOAD_DECLINE;
-
- return ast_register_application(app, app_exec, synopsis, descrip);
-}
-
-static int reload(void)
-{
- reload_followme();
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Find-Me/Follow-Me Application",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/apps/app_forkcdr.c b/1.4/apps/app_forkcdr.c
deleted file mode 100644
index d9c5b293f..000000000
--- a/1.4/apps/app_forkcdr.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Anthony Minessale anthmct@yahoo.com
- * Development of this app Sponsered/Funded by TAAN Softworks Corp
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Fork CDR application
- *
- * \author Anthony Minessale anthmct@yahoo.com
- *
- * \note Development of this app Sponsored/Funded by TAAN Softworks Corp
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-
-static char *app = "ForkCDR";
-static char *synopsis =
-"Forks the Call Data Record";
-static char *descrip =
-" ForkCDR([options]): Causes the Call Data Record to fork an additional\n"
- "cdr record starting from the time of the fork call\n"
-"If the option 'v' is passed all cdr variables will be passed along also.\n";
-
-
-static void ast_cdr_fork(struct ast_channel *chan)
-{
- struct ast_cdr *cdr;
- struct ast_cdr *newcdr;
- struct ast_flags flags = { AST_CDR_FLAG_KEEP_VARS };
-
- cdr = chan->cdr;
-
- while (cdr->next)
- cdr = cdr->next;
-
- if (!(newcdr = ast_cdr_dup(cdr)))
- return;
-
- ast_cdr_append(cdr, newcdr);
- ast_cdr_reset(newcdr, &flags);
-
- if (!ast_test_flag(cdr, AST_CDR_FLAG_KEEP_VARS))
- ast_cdr_free_vars(cdr, 0);
-
- ast_set_flag(cdr, AST_CDR_FLAG_CHILD | AST_CDR_FLAG_LOCKED);
-}
-
-static int forkcdr_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
-
- if (!chan->cdr) {
- ast_log(LOG_WARNING, "Channel does not have a CDR\n");
- return 0;
- }
-
- u = ast_module_user_add(chan);
-
- if (!ast_strlen_zero(data))
- ast_set2_flag(chan->cdr, strchr(data, 'v'), AST_CDR_FLAG_KEEP_VARS);
-
- ast_cdr_fork(chan);
-
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, forkcdr_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Fork The CDR into 2 separate entities");
diff --git a/1.4/apps/app_getcpeid.c b/1.4/apps/app_getcpeid.c
deleted file mode 100644
index f0c5d1b07..000000000
--- a/1.4/apps/app_getcpeid.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Get ADSI CPE ID
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/adsi.h"
-#include "asterisk/options.h"
-
-static char *app = "GetCPEID";
-
-static char *synopsis = "Get ADSI CPE ID";
-
-static char *descrip =
-" GetCPEID: Obtains and displays ADSI CPE ID and other information in order\n"
-"to properly setup zapata.conf for on-hook operations.\n";
-
-
-static int cpeid_setstatus(struct ast_channel *chan, char *stuff[], int voice)
-{
- int justify[5] = { ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_JUST_LEFT, ADSI_JUST_LEFT };
- char *tmp[5];
- int x;
- for (x=0;x<4;x++)
- tmp[x] = stuff[x];
- tmp[4] = NULL;
- return ast_adsi_print(chan, tmp, justify, voice);
-}
-
-static int cpeid_exec(struct ast_channel *chan, void *idata)
-{
- int res=0;
- struct ast_module_user *u;
- unsigned char cpeid[4];
- int gotgeometry = 0;
- int gotcpeid = 0;
- int width, height, buttons;
- char *data[4];
- unsigned int x;
-
- u = ast_module_user_add(chan);
-
- for (x = 0; x < 4; x++)
- data[x] = alloca(80);
-
- strcpy(data[0], "** CPE Info **");
- strcpy(data[1], "Identifying CPE...");
- strcpy(data[2], "Please wait...");
- res = ast_adsi_load_session(chan, NULL, 0, 1);
- if (res > 0) {
- cpeid_setstatus(chan, data, 0);
- res = ast_adsi_get_cpeid(chan, cpeid, 0);
- if (res > 0) {
- gotcpeid = 1;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Got CPEID of '%02x:%02x:%02x:%02x' on '%s'\n", cpeid[0], cpeid[1], cpeid[2], cpeid[3], chan->name);
- }
- if (res > -1) {
- strcpy(data[1], "Measuring CPE...");
- strcpy(data[2], "Please wait...");
- cpeid_setstatus(chan, data, 0);
- res = ast_adsi_get_cpeinfo(chan, &width, &height, &buttons, 0);
- if (res > -1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CPE has %d lines, %d columns, and %d buttons on '%s'\n", height, width, buttons, chan->name);
- gotgeometry = 1;
- }
- }
- if (res > -1) {
- if (gotcpeid)
- snprintf(data[1], 80, "CPEID: %02x:%02x:%02x:%02x", cpeid[0], cpeid[1], cpeid[2], cpeid[3]);
- else
- strcpy(data[1], "CPEID Unknown");
- if (gotgeometry)
- snprintf(data[2], 80, "Geom: %dx%d, %d buttons", width, height, buttons);
- else
- strcpy(data[2], "Geometry unknown");
- strcpy(data[3], "Press # to exit");
- cpeid_setstatus(chan, data, 1);
- for(;;) {
- res = ast_waitfordigit(chan, 1000);
- if (res < 0)
- break;
- if (res == '#') {
- res = 0;
- break;
- }
- }
- ast_adsi_unload_session(chan);
- }
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, cpeid_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Get ADSI CPE ID");
diff --git a/1.4/apps/app_hasnewvoicemail.c b/1.4/apps/app_hasnewvoicemail.c
deleted file mode 100644
index 8f3d33504..000000000
--- a/1.4/apps/app_hasnewvoicemail.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Changes Copyright (c) 2004 - 2006 Todd Freeman <freeman@andrews.edu>
- *
- * 95% based on HasNewVoicemail by:
- *
- * Copyright (c) 2003 Tilghman Lesher. All rights reserved.
- *
- * Tilghman Lesher <asterisk-hasnewvoicemail-app@the-tilghman.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.
- */
-
-/*! \file
- *
- * \brief HasVoicemail application
- *
- * \author Todd Freeman <freeman@andrews.edu>
- *
- * \note 95% based on HasNewVoicemail by
- * Tilghman Lesher <asterisk-hasnewvoicemail-app@the-tilghman.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/types.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-
-static char *app_hasvoicemail = "HasVoicemail";
-static char *hasvoicemail_synopsis = "Conditionally branches to priority + 101 with the right options set";
-static char *hasvoicemail_descrip =
-"HasVoicemail(vmbox[/folder][@context][|varname[|options]])\n"
-" Optionally sets <varname> to the number of messages in that folder."
-" Assumes folder of INBOX if not specified.\n"
-" The option string may contain zero or the following character:\n"
-" 'j' -- jump to priority n+101, if there is voicemail in the folder indicated.\n"
-" This application sets the following channel variable upon completion:\n"
-" HASVMSTATUS The result of the voicemail check returned as a text string as follows\n"
-" <# of messages in the folder, 0 for NONE>\n"
-"\nThis application has been deprecated in favor of the VMCOUNT() function\n";
-
-static char *app_hasnewvoicemail = "HasNewVoicemail";
-static char *hasnewvoicemail_synopsis = "Conditionally branches to priority + 101 with the right options set";
-static char *hasnewvoicemail_descrip =
-"HasNewVoicemail(vmbox[/folder][@context][|varname[|options]])\n"
-"Assumes folder 'INBOX' if folder is not specified. Optionally sets <varname> to the number of messages\n"
-"in that folder.\n"
-" The option string may contain zero of the following character:\n"
-" 'j' -- jump to priority n+101, if there is new voicemail in folder 'folder' or INBOX\n"
-" This application sets the following channel variable upon completion:\n"
-" HASVMSTATUS The result of the new voicemail check returned as a text string as follows\n"
-" <# of messages in the folder, 0 for NONE>\n"
-"\nThis application has been deprecated in favor of the VMCOUNT() function\n";
-
-
-static int hasvoicemail_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *input, *varname = NULL, *vmbox, *context = "default";
- char *vmfolder;
- int vmcount = 0;
- static int dep_warning = 0;
- int priority_jump = 0;
- char tmp[12];
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(vmbox);
- AST_APP_ARG(varname);
- AST_APP_ARG(options);
- );
-
- if (!dep_warning) {
- ast_log(LOG_WARNING, "The applications HasVoicemail and HasNewVoicemail have been deprecated. Please use the VMCOUNT() function instead.\n");
- dep_warning = 1;
- }
-
- if (!data) {
- ast_log(LOG_WARNING, "HasVoicemail requires an argument (vm-box[/folder][@context][|varname[|options]])\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- input = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, input);
-
- vmbox = strsep(&args.vmbox, "@");
-
- if (!ast_strlen_zero(args.vmbox))
- context = args.vmbox;
-
- vmfolder = strchr(vmbox, '/');
- if (vmfolder) {
- *vmfolder = '\0';
- vmfolder++;
- } else {
- vmfolder = "INBOX";
- }
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- vmcount = ast_app_messagecount(context, vmbox, vmfolder);
- /* Set the count in the channel variable */
- if (varname) {
- snprintf(tmp, sizeof(tmp), "%d", vmcount);
- pbx_builtin_setvar_helper(chan, varname, tmp);
- }
-
- if (vmcount > 0) {
- /* Branch to the next extension */
- if (priority_jump || ast_opt_priority_jumping) {
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
- ast_log(LOG_WARNING, "VM box %s@%s has new voicemail, but extension %s, priority %d doesn't exist\n", vmbox, context, chan->exten, chan->priority + 101);
- }
- }
-
- snprintf(tmp, sizeof(tmp), "%d", vmcount);
- pbx_builtin_setvar_helper(chan, "HASVMSTATUS", tmp);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *argsstr, char *buf, size_t len)
-{
- struct ast_module_user *u;
- char *context;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(vmbox);
- AST_APP_ARG(folder);
- );
-
- if (ast_strlen_zero(argsstr))
- return -1;
-
- u = ast_module_user_add(chan);
-
- buf[0] = '\0';
-
- AST_STANDARD_APP_ARGS(args, argsstr);
-
- if (strchr(args.vmbox, '@')) {
- context = args.vmbox;
- args.vmbox = strsep(&context, "@");
- } else {
- context = "default";
- }
-
- if (ast_strlen_zero(args.folder)) {
- args.folder = "INBOX";
- }
-
- snprintf(buf, len, "%d", ast_app_messagecount(context, args.vmbox, args.folder));
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-struct ast_custom_function acf_vmcount = {
- .name = "VMCOUNT",
- .synopsis = "Counts the voicemail in a specified mailbox",
- .syntax = "VMCOUNT(vmbox[@context][|folder])",
- .desc =
- " context - defaults to \"default\"\n"
- " folder - defaults to \"INBOX\"\n",
- .read = acf_vmcount_exec,
-};
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_custom_function_unregister(&acf_vmcount);
- res |= ast_unregister_application(app_hasvoicemail);
- res |= ast_unregister_application(app_hasnewvoicemail);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_custom_function_register(&acf_vmcount);
- res |= ast_register_application(app_hasvoicemail, hasvoicemail_exec, hasvoicemail_synopsis, hasvoicemail_descrip);
- res |= ast_register_application(app_hasnewvoicemail, hasvoicemail_exec, hasnewvoicemail_synopsis, hasnewvoicemail_descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Indicator for whether a voice mailbox has messages in a given folder.");
diff --git a/1.4/apps/app_ices.c b/1.4/apps/app_ices.c
deleted file mode 100644
index 8c6d5e7e5..000000000
--- a/1.4/apps/app_ices.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Stream to an icecast server via ICES (see contrib/asterisk-ices.xml)
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <errno.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/frame.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/options.h"
-
-#define ICES "/usr/bin/ices"
-#define LOCAL_ICES "/usr/local/bin/ices"
-
-static char *app = "ICES";
-
-static char *synopsis = "Encode and stream using 'ices'";
-
-static char *descrip =
-" ICES(config.xml) Streams to an icecast server using ices\n"
-"(available separately). A configuration file must be supplied\n"
-"for ices (see examples/asterisk-ices.conf). \n";
-
-
-static int icesencode(char *filename, int fd)
-{
- int res;
- int x;
- sigset_t fullset, oldset;
-
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
-
- res = fork();
- if (res < 0)
- ast_log(LOG_WARNING, "Fork failed\n");
- if (res) {
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- return res;
- }
-
- /* Stop ignoring PIPE */
- signal(SIGPIPE, SIG_DFL);
- pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
-
- if (ast_opt_high_priority)
- ast_set_priority(0);
- dup2(fd, STDIN_FILENO);
- for (x=STDERR_FILENO + 1;x<1024;x++) {
- if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
- close(x);
- }
- /* Most commonly installed in /usr/local/bin */
- execl(ICES, "ices", filename, (char *)NULL);
- /* But many places has it in /usr/bin */
- execl(LOCAL_ICES, "ices", filename, (char *)NULL);
- /* As a last-ditch effort, try to use PATH */
- execlp("ices", "ices", filename, (char *)NULL);
- ast_log(LOG_WARNING, "Execute of ices failed\n");
- _exit(0);
-}
-
-static int ices_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
- int fds[2];
- int ms = -1;
- int pid = -1;
- int flags;
- int oreadformat;
- struct timeval last;
- struct ast_frame *f;
- char filename[256]="";
- char *c;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- last = ast_tv(0, 0);
-
- if (pipe(fds)) {
- ast_log(LOG_WARNING, "Unable to create pipe\n");
- ast_module_user_remove(u);
- return -1;
- }
- flags = fcntl(fds[1], F_GETFL);
- fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
-
- ast_stopstream(chan);
-
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
-
- if (res) {
- close(fds[0]);
- close(fds[1]);
- ast_log(LOG_WARNING, "Answer failed!\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- oreadformat = chan->readformat;
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- close(fds[0]);
- close(fds[1]);
- ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
- ast_module_user_remove(u);
- return -1;
- }
- if (((char *)data)[0] == '/')
- ast_copy_string(filename, (char *) data, sizeof(filename));
- else
- snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data);
- /* Placeholder for options */
- c = strchr(filename, '|');
- if (c)
- *c = '\0';
- res = icesencode(filename, fds[0]);
- close(fds[0]);
- if (res >= 0) {
- pid = res;
- for (;;) {
- /* Wait for audio, and stream */
- ms = ast_waitfor(chan, -1);
- if (ms < 0) {
- ast_log(LOG_DEBUG, "Hangup detected\n");
- res = -1;
- break;
- }
- f = ast_read(chan);
- if (!f) {
- ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
- res = -1;
- break;
- }
- if (f->frametype == AST_FRAME_VOICE) {
- res = write(fds[1], f->data, f->datalen);
- if (res < 0) {
- if (errno != EAGAIN) {
- ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
- res = -1;
- ast_frfree(f);
- break;
- }
- }
- }
- ast_frfree(f);
- }
- }
- close(fds[1]);
-
- if (pid > -1)
- kill(pid, SIGKILL);
- if (!res && oreadformat)
- ast_set_read_format(chan, oreadformat);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, ices_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Encode and Stream via icecast and ices");
diff --git a/1.4/apps/app_image.c b/1.4/apps/app_image.c
deleted file mode 100644
index f5f327197..000000000
--- a/1.4/apps/app_image.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to transmit an image
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-
-static char *app = "SendImage";
-
-static char *synopsis = "Send an image file";
-
-static char *descrip =
-" SendImage(filename): Sends an image on a channel. \n"
-"If the channel supports image transport but the image send\n"
-"fails, the channel will be hung up. Otherwise, the dialplan\n"
-"continues execution.\n"
-"The option string may contain the following character:\n"
-" 'j' -- jump to priority n+101 if the channel doesn't support image transport\n"
-"This application sets the following channel variable upon completion:\n"
-" SENDIMAGESTATUS The status is the result of the attempt as a text string, one of\n"
-" OK | NOSUPPORT \n";
-
-
-static int sendimage_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *parse;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(filename);
- AST_APP_ARG(options);
- );
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.filename)) {
- ast_log(LOG_WARNING, "SendImage requires an argument (filename[|options])\n");
- return -1;
- }
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- if (!ast_supports_images(chan)) {
- /* Does not support transport */
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "SENDIMAGESTATUS", "NOSUPPORT");
- ast_module_user_remove(u);
- return 0;
- }
-
- res = ast_send_image(chan, args.filename);
-
- if (!res)
- pbx_builtin_setvar_helper(chan, "SENDIMAGESTATUS", "OK");
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, sendimage_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Image Transmission Application");
diff --git a/1.4/apps/app_ivrdemo.c b/1.4/apps/app_ivrdemo.c
deleted file mode 100644
index 933ae9040..000000000
--- a/1.4/apps/app_ivrdemo.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief IVR Demo application
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <defaultenabled>no</defaultenabled>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-
-static char *tdesc = "IVR Demo Application";
-static char *app = "IVRDemo";
-static char *synopsis =
-" This is a skeleton application that shows you the basic structure to create your\n"
-"own asterisk applications and demonstrates the IVR demo.\n";
-
-static int ivr_demo_func(struct ast_channel *chan, void *data)
-{
- ast_verbose("IVR Demo, data is %s!\n", (char *)data);
- return 0;
-}
-
-AST_IVR_DECLARE_MENU(ivr_submenu, "IVR Demo Sub Menu", 0,
-{
- { "s", AST_ACTION_BACKGROUND, "demo-abouttotry" },
- { "s", AST_ACTION_WAITOPTION },
- { "1", AST_ACTION_PLAYBACK, "digits/1" },
- { "1", AST_ACTION_PLAYBACK, "digits/1" },
- { "1", AST_ACTION_RESTART },
- { "2", AST_ACTION_PLAYLIST, "digits/2;digits/3" },
- { "3", AST_ACTION_CALLBACK, ivr_demo_func },
- { "4", AST_ACTION_TRANSFER, "demo|s|1" },
- { "*", AST_ACTION_REPEAT },
- { "#", AST_ACTION_UPONE },
- { NULL }
-});
-
-AST_IVR_DECLARE_MENU(ivr_demo, "IVR Demo Main Menu", 0,
-{
- { "s", AST_ACTION_BACKGROUND, "demo-congrats" },
- { "g", AST_ACTION_BACKGROUND, "demo-instruct" },
- { "g", AST_ACTION_WAITOPTION },
- { "1", AST_ACTION_PLAYBACK, "digits/1" },
- { "1", AST_ACTION_RESTART },
- { "2", AST_ACTION_MENU, &ivr_submenu },
- { "2", AST_ACTION_RESTART },
- { "i", AST_ACTION_PLAYBACK, "invalid" },
- { "i", AST_ACTION_REPEAT, (void *)(unsigned long)2 },
- { "#", AST_ACTION_EXIT },
- { NULL },
-});
-
-
-static int skel_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "skel requires an argument (filename)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- /* Do our thing here */
-
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
- if (!res)
- res = ast_ivr_menu_run(chan, &ivr_demo, data);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, skel_exec, tdesc, synopsis);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "IVR Demo Application");
diff --git a/1.4/apps/app_lookupblacklist.c b/1.4/apps/app_lookupblacklist.c
deleted file mode 100644
index 88ed52d86..000000000
--- a/1.4/apps/app_lookupblacklist.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to lookup the callerid number, and see if it is blacklisted
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/callerid.h"
-#include "asterisk/astdb.h"
-#include "asterisk/options.h"
-
-static char *app = "LookupBlacklist";
-
-static char *synopsis = "Look up Caller*ID name/number from blacklist database";
-
-static char *descrip =
- " LookupBlacklist(options): Looks up the Caller*ID number on the active\n"
- "channel in the Asterisk database (family 'blacklist'). \n"
- "The option string may contain the following character:\n"
- " 'j' -- jump to n+101 priority if the number/name is found in the blacklist\n"
- "This application sets the following channel variable upon completion:\n"
- " LOOKUPBLSTATUS The status of the Blacklist lookup as a text string, one of\n"
- " FOUND | NOTFOUND\n"
- "Example: exten => 1234,1,LookupBlacklist()\n\n"
- "This application is deprecated and may be removed from a future release.\n"
- "Please use the dialplan function BLACKLIST() instead.\n";
-
-
-static int blacklist_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- char blacklist[1];
- int bl = 0;
-
- if (chan->cid.cid_num) {
- if (!ast_db_get("blacklist", chan->cid.cid_num, blacklist, sizeof (blacklist)))
- bl = 1;
- }
- if (chan->cid.cid_name) {
- if (!ast_db_get("blacklist", chan->cid.cid_name, blacklist, sizeof (blacklist)))
- bl = 1;
- }
-
- snprintf(buf, len, "%d", bl);
- return 0;
-}
-
-static struct ast_custom_function blacklist_function = {
- .name = "BLACKLIST",
- .synopsis = "Check if the callerid is on the blacklist",
- .desc = "Uses astdb to check if the Caller*ID is in family 'blacklist'. Returns 1 or 0.\n",
- .syntax = "BLACKLIST()",
- .read = blacklist_read,
-};
-
-static int
-lookupblacklist_exec (struct ast_channel *chan, void *data)
-{
- char blacklist[1];
- struct ast_module_user *u;
- int bl = 0;
- int priority_jump = 0;
- static int dep_warning = 0;
-
- u = ast_module_user_add(chan);
-
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "LookupBlacklist is deprecated. Please use ${BLACKLIST()} instead.\n");
- }
-
- if (!ast_strlen_zero(data)) {
- if (strchr(data, 'j'))
- priority_jump = 1;
- }
-
- if (chan->cid.cid_num) {
- if (!ast_db_get("blacklist", chan->cid.cid_num, blacklist, sizeof (blacklist))) {
- if (option_verbose > 2)
- ast_log(LOG_NOTICE, "Blacklisted number %s found\n",chan->cid.cid_num);
- bl = 1;
- }
- }
- if (chan->cid.cid_name) {
- if (!ast_db_get("blacklist", chan->cid.cid_name, blacklist, sizeof (blacklist))) {
- if (option_verbose > 2)
- ast_log (LOG_NOTICE,"Blacklisted name \"%s\" found\n",chan->cid.cid_name);
- bl = 1;
- }
- }
-
- if (bl) {
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "LOOKUPBLSTATUS", "FOUND");
- } else
- pbx_builtin_setvar_helper(chan, "LOOKUPBLSTATUS", "NOTFOUND");
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
- res |= ast_custom_function_unregister(&blacklist_function);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = ast_custom_function_register(&blacklist_function);
- res |= ast_register_application (app, lookupblacklist_exec, synopsis,descrip);
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Look up Caller*ID name/number from blacklist database");
diff --git a/1.4/apps/app_lookupcidname.c b/1.4/apps/app_lookupcidname.c
deleted file mode 100644
index 8b8d5207a..000000000
--- a/1.4/apps/app_lookupcidname.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to set callerid name from database, based on directory number
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/callerid.h"
-#include "asterisk/astdb.h"
-
-static char *app = "LookupCIDName";
-
-static char *synopsis = "Look up CallerID Name from local database";
-
-static char *descrip =
- " LookupCIDName: Looks up the Caller*ID number on the active\n"
- "channel in the Asterisk database (family 'cidname') and sets the\n"
- "Caller*ID name. Does nothing if no Caller*ID was received on the\n"
- "channel. This is useful if you do not subscribe to Caller*ID\n"
- "name delivery, or if you want to change the names on some incoming\n"
- "calls.\n\n"
- "LookupCIDName is deprecated. Please use ${DB(cidname/${CALLERID(num)})}\n"
- "instead.\n";
-
-
-static int lookupcidname_exec (struct ast_channel *chan, void *data)
-{
- char dbname[64];
- struct ast_module_user *u;
- static int dep_warning = 0;
-
- u = ast_module_user_add(chan);
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "LookupCIDName is deprecated. Please use ${DB(cidname/${CALLERID(num)})} instead.\n");
- }
- if (chan->cid.cid_num) {
- if (!ast_db_get ("cidname", chan->cid.cid_num, dbname, sizeof (dbname))) {
- ast_set_callerid (chan, NULL, dbname, NULL);
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID name to %s\n",
- dbname);
- }
- }
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application (app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application (app, lookupcidname_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Look up CallerID Name from local database");
diff --git a/1.4/apps/app_macro.c b/1.4/apps/app_macro.c
deleted file mode 100644
index 7906ed4b2..000000000
--- a/1.4/apps/app_macro.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Dial plan macro Implementation
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/config.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-#define MAX_ARGS 80
-
-/* special result value used to force macro exit */
-#define MACRO_EXIT_RESULT 1024
-
-static char *descrip =
-" Macro(macroname|arg1|arg2...): Executes a macro using the context\n"
-"'macro-<macroname>', jumping to the 's' extension of that context and\n"
-"executing each step, then returning when the steps end. \n"
-"The calling extension, context, and priority are stored in ${MACRO_EXTEN}, \n"
-"${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become\n"
-"${ARG1}, ${ARG2}, etc in the macro context.\n"
-"If you Goto out of the Macro context, the Macro will terminate and control\n"
-"will be returned at the location of the Goto.\n"
-"If ${MACRO_OFFSET} is set at termination, Macro will attempt to continue\n"
-"at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\n"
-"Extensions: While a macro is being executed, it becomes the current context.\n"
-" This means that if a hangup occurs, for instance, that the macro\n"
-" will be searched for an 'h' extension, NOT the context from which\n"
-" the macro was called. So, make sure to define all appropriate\n"
-" extensions in your macro! (you can use 'catch' in AEL) \n"
-"WARNING: Because of the way Macro is implemented (it executes the priorities\n"
-" contained within it via sub-engine), and a fixed per-thread\n"
-" memory stack allowance, macros are limited to 7 levels\n"
-" of nesting (macro calling macro calling macro, etc.); It\n"
-" may be possible that stack-intensive applications in deeply nested macros\n"
-" could cause asterisk to crash earlier than this limit.\n";
-
-static char *if_descrip =
-" MacroIf(<expr>?macroname_a[|arg1][:macroname_b[|arg1]])\n"
-"Executes macro defined in <macroname_a> if <expr> is true\n"
-"(otherwise <macroname_b> if provided)\n"
-"Arguments and return values as in application macro()\n";
-
-static char *exclusive_descrip =
-" MacroExclusive(macroname|arg1|arg2...):\n"
-"Executes macro defined in the context 'macro-macroname'\n"
-"Only one call at a time may run the macro.\n"
-"(we'll wait if another call is busy executing in the Macro)\n"
-"Arguments and return values as in application Macro()\n";
-
-static char *exit_descrip =
-" MacroExit():\n"
-"Causes the currently running macro to exit as if it had\n"
-"ended normally by running out of priorities to execute.\n"
-"If used outside a macro, will likely cause unexpected\n"
-"behavior.\n";
-
-static char *app = "Macro";
-static char *if_app = "MacroIf";
-static char *exclusive_app = "MacroExclusive";
-static char *exit_app = "MacroExit";
-
-static char *synopsis = "Macro Implementation";
-static char *if_synopsis = "Conditional Macro Implementation";
-static char *exclusive_synopsis = "Exclusive Macro Implementation";
-static char *exit_synopsis = "Exit From Macro";
-
-
-static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid)
-{
- struct ast_exten *e;
- struct ast_include *i;
- struct ast_context *c2;
-
- for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
- if (ast_extension_match(ast_get_extension_name(e), exten)) {
- int needmatch = ast_get_extension_matchcid(e);
- if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) ||
- (!needmatch)) {
- /* This is the matching extension we want */
- struct ast_exten *p;
- for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) {
- if (priority != ast_get_extension_priority(p))
- continue;
- return p;
- }
- }
- }
- }
-
- /* No match; run through includes */
- for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) {
- for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
- if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
- e = find_matching_priority(c2, exten, priority, callerid);
- if (e)
- return e;
- }
- }
- }
- return NULL;
-}
-
-static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
-{
- const char *s;
- char *tmp;
- char *cur, *rest;
- char *macro;
- char fullmacro[80];
- char varname[80];
- char runningapp[80], runningdata[1024];
- char *oldargs[MAX_ARGS + 1] = { NULL, };
- int argc, x;
- int res=0;
- char oldexten[256]="";
- int oldpriority, gosub_level = 0;
- char pc[80], depthc[12];
- char oldcontext[AST_MAX_CONTEXT] = "";
- const char *inhangupc;
- int offset, depth = 0, maxdepth = 7;
- int setmacrocontext=0;
- int autoloopflag, dead = 0, inhangup = 0;
-
- char *save_macro_exten;
- char *save_macro_context;
- char *save_macro_priority;
- char *save_macro_offset;
- struct ast_module_user *u;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Macro() requires arguments. See \"show application macro\" for help.\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- /* does the user want a deeper rabbit hole? */
- s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION");
- if (s)
- sscanf(s, "%d", &maxdepth);
-
- /* Count how many levels deep the rabbit hole goes */
- s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH");
- if (s)
- sscanf(s, "%d", &depth);
- /* Used for detecting whether to return when a Macro is called from another Macro after hangup */
- if (strcmp(chan->exten, "h") == 0)
- pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1");
- inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP");
- if (!ast_strlen_zero(inhangupc))
- sscanf(inhangupc, "%d", &inhangup);
-
- if (depth >= maxdepth) {
- ast_log(LOG_ERROR, "Macro(): possible infinite loop detected. Returning early.\n");
- ast_module_user_remove(u);
- return 0;
- }
- snprintf(depthc, sizeof(depthc), "%d", depth + 1);
- pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
-
- tmp = ast_strdupa(data);
- rest = tmp;
- macro = strsep(&rest, "|");
- if (ast_strlen_zero(macro)) {
- ast_log(LOG_WARNING, "Invalid macro name specified\n");
- ast_module_user_remove(u);
- return 0;
- }
-
- snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
- if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->cid.cid_num)) {
- if (!ast_context_find(fullmacro))
- ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro);
- else
- ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro);
- ast_module_user_remove(u);
- return 0;
- }
-
- /* If we are to run the macro exclusively, take the mutex */
- if (exclusive) {
- ast_log(LOG_DEBUG, "Locking macrolock for '%s'\n", fullmacro);
- ast_autoservice_start(chan);
- if (ast_context_lockmacro(fullmacro)) {
- ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro);
- ast_autoservice_stop(chan);
- ast_module_user_remove(u);
-
- return 0;
- }
- ast_autoservice_stop(chan);
- }
-
- /* Save old info */
- oldpriority = chan->priority;
- ast_copy_string(oldexten, chan->exten, sizeof(oldexten));
- ast_copy_string(oldcontext, chan->context, sizeof(oldcontext));
- if (ast_strlen_zero(chan->macrocontext)) {
- ast_copy_string(chan->macrocontext, chan->context, sizeof(chan->macrocontext));
- ast_copy_string(chan->macroexten, chan->exten, sizeof(chan->macroexten));
- chan->macropriority = chan->priority;
- setmacrocontext=1;
- }
- argc = 1;
- /* Save old macro variables */
- save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN"));
- pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten);
-
- save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"));
- pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext);
-
- save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY"));
- snprintf(pc, sizeof(pc), "%d", oldpriority);
- pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc);
-
- save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"));
- pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL);
-
- /* Setup environment for new run */
- chan->exten[0] = 's';
- chan->exten[1] = '\0';
- ast_copy_string(chan->context, fullmacro, sizeof(chan->context));
- chan->priority = 1;
-
- while((cur = strsep(&rest, "|")) && (argc < MAX_ARGS)) {
- const char *s;
- /* Save copy of old arguments if we're overwriting some, otherwise
- let them pass through to the other macro */
- snprintf(varname, sizeof(varname), "ARG%d", argc);
- s = pbx_builtin_getvar_helper(chan, varname);
- if (s)
- oldargs[argc] = ast_strdup(s);
- pbx_builtin_setvar_helper(chan, varname, cur);
- argc++;
- }
- autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
- ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
- while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
- struct ast_context *c;
- struct ast_exten *e;
- runningapp[0] = '\0';
- runningdata[0] = '\0';
-
- /* What application will execute? */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- } else {
- for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) {
- if (!strcmp(ast_get_context_name(c), chan->context)) {
- if (ast_lock_context(c)) {
- ast_log(LOG_WARNING, "Unable to lock context?\n");
- } else {
- e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num);
- if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */
- ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp));
- ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata));
- }
- ast_unlock_context(c);
- }
- break;
- }
- }
- }
- ast_unlock_contexts();
-
- /* Reset the macro depth, if it was changed in the last iteration */
- pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
-
- if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num))) {
- /* Something bad happened, or a hangup has been requested. */
- if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
- (res == '*') || (res == '#')) {
- /* Just return result as to the previous application as if it had been dialed */
- ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
- break;
- }
- switch(res) {
- case MACRO_EXIT_RESULT:
- res = 0;
- goto out;
- case AST_PBX_KEEPALIVE:
- if (option_debug)
- ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
- else if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
- goto out;
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
- else if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
- dead = 1;
- goto out;
- }
- }
-
- ast_log(LOG_DEBUG, "Executed application: %s\n", runningapp);
-
- if (!strcasecmp(runningapp, "GOSUB")) {
- gosub_level++;
- ast_log(LOG_DEBUG, "Incrementing gosub_level\n");
- } else if (!strcasecmp(runningapp, "GOSUBIF")) {
- char tmp2[1024] = "", *cond, *app, *app2 = tmp2;
- pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1);
- cond = strsep(&app2, "?");
- app = strsep(&app2, ":");
- if (pbx_checkcondition(cond)) {
- if (!ast_strlen_zero(app)) {
- gosub_level++;
- ast_log(LOG_DEBUG, "Incrementing gosub_level\n");
- }
- } else {
- if (!ast_strlen_zero(app2)) {
- gosub_level++;
- ast_log(LOG_DEBUG, "Incrementing gosub_level\n");
- }
- }
- } else if (!strcasecmp(runningapp, "RETURN")) {
- gosub_level--;
- ast_log(LOG_DEBUG, "Decrementing gosub_level\n");
- } else if (!strcasecmp(runningapp, "STACKPOP")) {
- gosub_level--;
- ast_log(LOG_DEBUG, "Decrementing gosub_level\n");
- } else if (!strncasecmp(runningapp, "EXEC", 4)) {
- /* Must evaluate args to find actual app */
- char tmp2[1024] = "", *tmp3 = NULL;
- pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1);
- if (!strcasecmp(runningapp, "EXECIF")) {
- tmp3 = strchr(tmp2, '|');
- if (tmp3)
- *tmp3++ = '\0';
- if (!pbx_checkcondition(tmp2))
- tmp3 = NULL;
- } else
- tmp3 = tmp2;
-
- if (tmp3)
- ast_log(LOG_DEBUG, "Last app: %s\n", tmp3);
-
- if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) {
- gosub_level++;
- ast_log(LOG_DEBUG, "Incrementing gosub_level\n");
- } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) {
- gosub_level--;
- ast_log(LOG_DEBUG, "Decrementing gosub_level\n");
- } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) {
- gosub_level--;
- ast_log(LOG_DEBUG, "Decrementing gosub_level\n");
- }
- }
-
- if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Channel '%s' jumping out of macro '%s'\n", chan->name, macro);
- break;
- }
-
- /* don't stop executing extensions when we're in "h" */
- if (chan->_softhangup && !inhangup) {
- ast_log(LOG_DEBUG, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n",
- chan->exten, chan->macroexten, chan->priority);
- goto out;
- }
- chan->priority++;
- }
- out:
- /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */
- snprintf(depthc, sizeof(depthc), "%d", depth);
- if (!dead) {
- pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
- ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
- }
-
- for (x = 1; x < argc; x++) {
- /* Restore old arguments and delete ours */
- snprintf(varname, sizeof(varname), "ARG%d", x);
- if (oldargs[x]) {
- if (!dead)
- pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
- free(oldargs[x]);
- } else if (!dead) {
- pbx_builtin_setvar_helper(chan, varname, NULL);
- }
- }
-
- /* Restore macro variables */
- if (!dead) {
- pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
- pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
- pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
- }
- if (save_macro_exten)
- free(save_macro_exten);
- if (save_macro_context)
- free(save_macro_context);
- if (save_macro_priority)
- free(save_macro_priority);
-
- if (!dead && setmacrocontext) {
- chan->macrocontext[0] = '\0';
- chan->macroexten[0] = '\0';
- chan->macropriority = 0;
- }
-
- if (!dead && !strcasecmp(chan->context, fullmacro)) {
- /* If we're leaving the macro normally, restore original information */
- chan->priority = oldpriority;
- ast_copy_string(chan->context, oldcontext, sizeof(chan->context));
- if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
- /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
- const char *offsets;
- ast_copy_string(chan->exten, oldexten, sizeof(chan->exten));
- if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
- /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
- normally if there is any problem */
- if (sscanf(offsets, "%d", &offset) == 1) {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) {
- chan->priority += offset;
- }
- }
- }
- }
- }
-
- if (!dead)
- pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
- if (save_macro_offset)
- free(save_macro_offset);
-
- /* Unlock the macro */
- if (exclusive) {
- ast_log(LOG_DEBUG, "Unlocking macrolock for '%s'\n", fullmacro);
- if (ast_context_unlockmacro(fullmacro)) {
- ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro);
- res = 0;
- }
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int macro_exec(struct ast_channel *chan, void *data)
-{
- return _macro_exec(chan, data, 0);
-}
-
-static int macroexclusive_exec(struct ast_channel *chan, void *data)
-{
- return _macro_exec(chan, data, 1);
-}
-
-static int macroif_exec(struct ast_channel *chan, void *data)
-{
- char *expr = NULL, *label_a = NULL, *label_b = NULL;
- int res = 0;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- if (!(expr = ast_strdupa(data))) {
- ast_module_user_remove(u);
- return -1;
- }
-
- if ((label_a = strchr(expr, '?'))) {
- *label_a = '\0';
- label_a++;
- if ((label_b = strchr(label_a, ':'))) {
- *label_b = '\0';
- label_b++;
- }
- if (pbx_checkcondition(expr))
- res = macro_exec(chan, label_a);
- else if (label_b)
- res = macro_exec(chan, label_b);
- } else
- ast_log(LOG_WARNING, "Invalid Syntax.\n");
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int macro_exit_exec(struct ast_channel *chan, void *data)
-{
- return MACRO_EXIT_RESULT;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(if_app);
- res |= ast_unregister_application(exit_app);
- res |= ast_unregister_application(app);
- res |= ast_unregister_application(exclusive_app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(exit_app, macro_exit_exec, exit_synopsis, exit_descrip);
- res |= ast_register_application(if_app, macroif_exec, if_synopsis, if_descrip);
- res |= ast_register_application(exclusive_app, macroexclusive_exec, exclusive_synopsis, exclusive_descrip);
- res |= ast_register_application(app, macro_exec, synopsis, descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Extension Macros");
diff --git a/1.4/apps/app_meetme.c b/1.4/apps/app_meetme.c
deleted file mode 100644
index 1a2b8da5c..000000000
--- a/1.4/apps/app_meetme.c
+++ /dev/null
@@ -1,4882 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * SLA Implementation by:
- * Russell Bryant <russell@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.
- */
-
-/*! \file
- *
- * \brief Meet me conference bridge and Shared Line Appearances
- *
- * \author Mark Spencer <markster@digium.com>
- * \author (SLA) Russell Bryant <russell@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <zaptel/zaptel.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/manager.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/say.h"
-#include "asterisk/utils.h"
-#include "asterisk/translate.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/astobj.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/dial.h"
-#include "asterisk/causes.h"
-
-#include "enter.h"
-#include "leave.h"
-
-#define CONFIG_FILE_NAME "meetme.conf"
-#define SLA_CONFIG_FILE "sla.conf"
-
-/*! each buffer is 20ms, so this is 640ms total */
-#define DEFAULT_AUDIO_BUFFERS 32
-
-enum {
- ADMINFLAG_MUTED = (1 << 1), /*!< User is muted */
- ADMINFLAG_SELFMUTED = (1 << 2), /*!< User muted self */
- ADMINFLAG_KICKME = (1 << 3) /*!< User has been kicked */
-};
-
-#define MEETME_DELAYDETECTTALK 300
-#define MEETME_DELAYDETECTENDTALK 1000
-
-#define AST_FRAME_BITS 32
-
-enum volume_action {
- VOL_UP,
- VOL_DOWN
-};
-
-enum entrance_sound {
- ENTER,
- LEAVE
-};
-
-enum recording_state {
- MEETME_RECORD_OFF,
- MEETME_RECORD_STARTED,
- MEETME_RECORD_ACTIVE,
- MEETME_RECORD_TERMINATE
-};
-
-#define CONF_SIZE 320
-
-enum {
- /*! user has admin access on the conference */
- CONFFLAG_ADMIN = (1 << 0),
- /*! If set the user can only receive audio from the conference */
- CONFFLAG_MONITOR = (1 << 1),
- /*! If set asterisk will exit conference when '#' is pressed */
- CONFFLAG_POUNDEXIT = (1 << 2),
- /*! If set asterisk will provide a menu to the user when '*' is pressed */
- CONFFLAG_STARMENU = (1 << 3),
- /*! If set the use can only send audio to the conference */
- CONFFLAG_TALKER = (1 << 4),
- /*! If set there will be no enter or leave sounds */
- CONFFLAG_QUIET = (1 << 5),
- /*! If set, when user joins the conference, they will be told the number
- * of users that are already in */
- CONFFLAG_ANNOUNCEUSERCOUNT = (1 << 6),
- /*! Set to run AGI Script in Background */
- CONFFLAG_AGI = (1 << 7),
- /*! Set to have music on hold when user is alone in conference */
- CONFFLAG_MOH = (1 << 8),
- /*! If set the MeetMe will return if all marked with this flag left */
- CONFFLAG_MARKEDEXIT = (1 << 9),
- /*! If set, the MeetMe will wait until a marked user enters */
- CONFFLAG_WAITMARKED = (1 << 10),
- /*! If set, the MeetMe will exit to the specified context */
- CONFFLAG_EXIT_CONTEXT = (1 << 11),
- /*! If set, the user will be marked */
- CONFFLAG_MARKEDUSER = (1 << 12),
- /*! If set, user will be ask record name on entry of conference */
- CONFFLAG_INTROUSER = (1 << 13),
- /*! If set, the MeetMe will be recorded */
- CONFFLAG_RECORDCONF = (1<< 14),
- /*! If set, the user will be monitored if the user is talking or not */
- CONFFLAG_MONITORTALKER = (1 << 15),
- CONFFLAG_DYNAMIC = (1 << 16),
- CONFFLAG_DYNAMICPIN = (1 << 17),
- CONFFLAG_EMPTY = (1 << 18),
- CONFFLAG_EMPTYNOPIN = (1 << 19),
- CONFFLAG_ALWAYSPROMPT = (1 << 20),
- /*! If set, treats talking users as muted users */
- CONFFLAG_OPTIMIZETALKER = (1 << 21),
- /*! If set, won't speak the extra prompt when the first person
- * enters the conference */
- CONFFLAG_NOONLYPERSON = (1 << 22),
- /*! If set, user will be asked to record name on entry of conference
- * without review */
- CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
- /*! If set, the user will be initially self-muted */
- CONFFLAG_STARTMUTED = (1 << 24),
- /*! Pass DTMF through the conference */
- CONFFLAG_PASS_DTMF = (1 << 25),
- /*! This is a SLA station. (Only for use by the SLA applications.) */
- CONFFLAG_SLA_STATION = (1 << 26),
- /*! This is a SLA trunk. (Only for use by the SLA applications.) */
- CONFFLAG_SLA_TRUNK = (1 << 27),
-};
-
-enum {
- OPT_ARG_WAITMARKED = 0,
- OPT_ARG_ARRAY_SIZE = 1,
-};
-
-AST_APP_OPTIONS(meetme_opts, BEGIN_OPTIONS
- AST_APP_OPTION('A', CONFFLAG_MARKEDUSER ),
- AST_APP_OPTION('a', CONFFLAG_ADMIN ),
- AST_APP_OPTION('b', CONFFLAG_AGI ),
- AST_APP_OPTION('c', CONFFLAG_ANNOUNCEUSERCOUNT ),
- AST_APP_OPTION('D', CONFFLAG_DYNAMICPIN ),
- AST_APP_OPTION('d', CONFFLAG_DYNAMIC ),
- AST_APP_OPTION('E', CONFFLAG_EMPTYNOPIN ),
- AST_APP_OPTION('e', CONFFLAG_EMPTY ),
- AST_APP_OPTION('F', CONFFLAG_PASS_DTMF ),
- AST_APP_OPTION('i', CONFFLAG_INTROUSER ),
- AST_APP_OPTION('I', CONFFLAG_INTROUSERNOREVIEW ),
- AST_APP_OPTION('M', CONFFLAG_MOH ),
- AST_APP_OPTION('m', CONFFLAG_STARTMUTED ),
- AST_APP_OPTION('o', CONFFLAG_OPTIMIZETALKER ),
- AST_APP_OPTION('P', CONFFLAG_ALWAYSPROMPT ),
- AST_APP_OPTION('p', CONFFLAG_POUNDEXIT ),
- AST_APP_OPTION('q', CONFFLAG_QUIET ),
- AST_APP_OPTION('r', CONFFLAG_RECORDCONF ),
- AST_APP_OPTION('s', CONFFLAG_STARMENU ),
- AST_APP_OPTION('T', CONFFLAG_MONITORTALKER ),
- AST_APP_OPTION('l', CONFFLAG_MONITOR ),
- AST_APP_OPTION('t', CONFFLAG_TALKER ),
- AST_APP_OPTION_ARG('w', CONFFLAG_WAITMARKED, OPT_ARG_WAITMARKED ),
- AST_APP_OPTION('X', CONFFLAG_EXIT_CONTEXT ),
- AST_APP_OPTION('x', CONFFLAG_MARKEDEXIT ),
- AST_APP_OPTION('1', CONFFLAG_NOONLYPERSON ),
-END_OPTIONS );
-
-static const char *app = "MeetMe";
-static const char *app2 = "MeetMeCount";
-static const char *app3 = "MeetMeAdmin";
-static const char *slastation_app = "SLAStation";
-static const char *slatrunk_app = "SLATrunk";
-
-static const char *synopsis = "MeetMe conference bridge";
-static const char *synopsis2 = "MeetMe participant count";
-static const char *synopsis3 = "MeetMe conference Administration";
-static const char *slastation_synopsis = "Shared Line Appearance Station";
-static const char *slatrunk_synopsis = "Shared Line Appearance Trunk";
-
-static const char *descrip =
-" MeetMe([confno][,[options][,pin]]): Enters the user into a specified MeetMe\n"
-"conference. If the conference number is omitted, the user will be prompted\n"
-"to enter one. User can exit the conference by hangup, or if the 'p' option\n"
-"is specified, by pressing '#'.\n"
-"Please note: The Zaptel kernel modules and at least one hardware driver (or ztdummy)\n"
-" must be present for conferencing to operate properly. In addition, the chan_zap\n"
-" channel driver must be loaded for the 'i' and 'r' options to operate at all.\n\n"
-"The option string may contain zero or more of the following characters:\n"
-" 'a' -- set admin mode\n"
-" 'A' -- set marked mode\n"
-" 'b' -- run AGI script specified in ${MEETME_AGI_BACKGROUND}\n"
-" Default: conf-background.agi (Note: This does not work with\n"
-" non-Zap channels in the same conference)\n"
-" 'c' -- announce user(s) count on joining a conference\n"
-" 'd' -- dynamically add conference\n"
-" 'D' -- dynamically add conference, prompting for a PIN\n"
-" 'e' -- select an empty conference\n"
-" 'E' -- select an empty pinless conference\n"
-" 'F' -- Pass DTMF through the conference.\n"
-" 'i' -- announce user join/leave with review\n"
-" 'I' -- announce user join/leave without review\n"
-" 'l' -- set listen only mode (Listen only, no talking)\n"
-" 'm' -- set initially muted\n"
-" 'M' -- enable music on hold when the conference has a single caller\n"
-" 'o' -- set talker optimization - treats talkers who aren't speaking as\n"
-" being muted, meaning (a) No encode is done on transmission and\n"
-" (b) Received audio that is not registered as talking is omitted\n"
-" causing no buildup in background noise. Note that this option\n"
-" will be removed in 1.6 and enabled by default.\n"
-" 'p' -- allow user to exit the conference by pressing '#'\n"
-" 'P' -- always prompt for the pin even if it is specified\n"
-" 'q' -- quiet mode (don't play enter/leave sounds)\n"
-" 'r' -- Record conference (records as ${MEETME_RECORDINGFILE}\n"
-" using format ${MEETME_RECORDINGFORMAT}). Default filename is\n"
-" meetme-conf-rec-${CONFNO}-${UNIQUEID} and the default format is\n"
-" wav.\n"
-" 's' -- Present menu (user or admin) when '*' is received ('send' to menu)\n"
-" 't' -- set talk only mode. (Talk only, no listening)\n"
-" 'T' -- set talker detection (sent to manager interface and meetme list)\n"
-" 'w[(<secs>)]'\n"
-" -- wait until the marked user enters the conference\n"
-" 'x' -- close the conference when last marked user exits\n"
-" 'X' -- allow user to exit the conference by entering a valid single\n"
-" digit extension ${MEETME_EXIT_CONTEXT} or the current context\n"
-" if that variable is not defined.\n"
-" '1' -- do not play message when first person enters\n";
-
-static const char *descrip2 =
-" MeetMeCount(confno[|var]): Plays back the number of users in the specified\n"
-"MeetMe conference. If var is specified, playback will be skipped and the value\n"
-"will be returned in the variable. Upon app completion, MeetMeCount will hangup\n"
-"the channel, unless priority n+1 exists, in which case priority progress will\n"
-"continue.\n"
-"A ZAPTEL INTERFACE MUST BE INSTALLED FOR CONFERENCING FUNCTIONALITY.\n";
-
-static const char *descrip3 =
-" MeetMeAdmin(confno,command[,user]): Run admin command for conference\n"
-" 'e' -- Eject last user that joined\n"
-" 'k' -- Kick one user out of conference\n"
-" 'K' -- Kick all users out of conference\n"
-" 'l' -- Unlock conference\n"
-" 'L' -- Lock conference\n"
-" 'm' -- Unmute one user\n"
-" 'M' -- Mute one user\n"
-" 'n' -- Unmute all users in the conference\n"
-" 'N' -- Mute all non-admin users in the conference\n"
-" 'r' -- Reset one user's volume settings\n"
-" 'R' -- Reset all users volume settings\n"
-" 's' -- Lower entire conference speaking volume\n"
-" 'S' -- Raise entire conference speaking volume\n"
-" 't' -- Lower one user's talk volume\n"
-" 'T' -- Raise one user's talk volume\n"
-" 'u' -- Lower one user's listen volume\n"
-" 'U' -- Raise one user's listen volume\n"
-" 'v' -- Lower entire conference listening volume\n"
-" 'V' -- Raise entire conference listening volume\n"
-"";
-
-static const char *slastation_desc =
-" SLAStation(station):\n"
-"This application should be executed by an SLA station. The argument depends\n"
-"on how the call was initiated. If the phone was just taken off hook, then\n"
-"the argument \"station\" should be just the station name. If the call was\n"
-"initiated by pressing a line key, then the station name should be preceded\n"
-"by an underscore and the trunk name associated with that line button.\n"
-"For example: \"station1_line1\"."
-" On exit, this application will set the variable SLASTATION_STATUS to\n"
-"one of the following values:\n"
-" FAILURE | CONGESTION | SUCCESS\n"
-"";
-
-static const char *slatrunk_desc =
-" SLATrunk(trunk):\n"
-"This application should be executed by an SLA trunk on an inbound call.\n"
-"The channel calling this application should correspond to the SLA trunk\n"
-"with the name \"trunk\" that is being passed as an argument.\n"
-" On exit, this application will set the variable SLATRUNK_STATUS to\n"
-"one of the following values:\n"
-" FAILURE | SUCCESS | UNANSWERED | RINGTIMEOUT\n"
-"";
-
-#define MAX_CONFNUM 80
-#define MAX_PIN 80
-
-/*! \brief The MeetMe Conference object */
-struct ast_conference {
- ast_mutex_t playlock; /*!< Conference specific lock (players) */
- ast_mutex_t listenlock; /*!< Conference specific lock (listeners) */
- char confno[MAX_CONFNUM]; /*!< Conference */
- struct ast_channel *chan; /*!< Announcements channel */
- struct ast_channel *lchan; /*!< Listen/Record channel */
- int fd; /*!< Announcements fd */
- int zapconf; /*!< Zaptel Conf # */
- int users; /*!< Number of active users */
- int markedusers; /*!< Number of marked users */
- time_t start; /*!< Start time (s) */
- int refcount; /*!< reference count of usage */
- enum recording_state recording:2; /*!< recording status */
- unsigned int isdynamic:1; /*!< Created on the fly? */
- unsigned int locked:1; /*!< Is the conference locked? */
- pthread_t recordthread; /*!< thread for recording */
- ast_mutex_t recordthreadlock; /*!< control threads trying to start recordthread */
- pthread_attr_t attr; /*!< thread attribute */
- const char *recordingfilename; /*!< Filename to record the Conference into */
- const char *recordingformat; /*!< Format to record the Conference in */
- char pin[MAX_PIN]; /*!< If protected by a PIN */
- char pinadmin[MAX_PIN]; /*!< If protected by a admin PIN */
- struct ast_frame *transframe[32];
- struct ast_frame *origframe;
- struct ast_trans_pvt *transpath[32];
- AST_LIST_HEAD_NOLOCK(, ast_conf_user) userlist;
- AST_LIST_ENTRY(ast_conference) list;
-};
-
-static AST_LIST_HEAD_STATIC(confs, ast_conference);
-
-static unsigned int conf_map[1024] = {0, };
-
-struct volume {
- int desired; /*!< Desired volume adjustment */
- int actual; /*!< Actual volume adjustment (for channels that can't adjust) */
-};
-
-struct ast_conf_user {
- int user_no; /*!< User Number */
- int userflags; /*!< Flags as set in the conference */
- int adminflags; /*!< Flags set by the Admin */
- struct ast_channel *chan; /*!< Connected channel */
- int talking; /*!< Is user talking */
- int zapchannel; /*!< Is a Zaptel channel */
- char usrvalue[50]; /*!< Custom User Value */
- char namerecloc[PATH_MAX]; /*!< Name Recorded file Location */
- time_t jointime; /*!< Time the user joined the conference */
- struct volume talk;
- struct volume listen;
- AST_LIST_ENTRY(ast_conf_user) list;
-};
-
-enum sla_which_trunk_refs {
- ALL_TRUNK_REFS,
- INACTIVE_TRUNK_REFS,
-};
-
-enum sla_trunk_state {
- SLA_TRUNK_STATE_IDLE,
- SLA_TRUNK_STATE_RINGING,
- SLA_TRUNK_STATE_UP,
- SLA_TRUNK_STATE_ONHOLD,
- SLA_TRUNK_STATE_ONHOLD_BYME,
-};
-
-enum sla_hold_access {
- /*! This means that any station can put it on hold, and any station
- * can retrieve the call from hold. */
- SLA_HOLD_OPEN,
- /*! This means that only the station that put the call on hold may
- * retrieve it from hold. */
- SLA_HOLD_PRIVATE,
-};
-
-struct sla_trunk_ref;
-
-struct sla_station {
- AST_RWLIST_ENTRY(sla_station) entry;
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(device);
- AST_STRING_FIELD(autocontext);
- );
- AST_LIST_HEAD_NOLOCK(, sla_trunk_ref) trunks;
- struct ast_dial *dial;
- /*! Ring timeout for this station, for any trunk. If a ring timeout
- * is set for a specific trunk on this station, that will take
- * priority over this value. */
- unsigned int ring_timeout;
- /*! Ring delay for this station, for any trunk. If a ring delay
- * is set for a specific trunk on this station, that will take
- * priority over this value. */
- unsigned int ring_delay;
- /*! This option uses the values in the sla_hold_access enum and sets the
- * access control type for hold on this station. */
- unsigned int hold_access:1;
-};
-
-struct sla_station_ref {
- AST_LIST_ENTRY(sla_station_ref) entry;
- struct sla_station *station;
-};
-
-struct sla_trunk {
- AST_RWLIST_ENTRY(sla_trunk) entry;
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(device);
- AST_STRING_FIELD(autocontext);
- );
- AST_LIST_HEAD_NOLOCK(, sla_station_ref) stations;
- /*! Number of stations that use this trunk */
- unsigned int num_stations;
- /*! Number of stations currently on a call with this trunk */
- unsigned int active_stations;
- /*! Number of stations that have this trunk on hold. */
- unsigned int hold_stations;
- struct ast_channel *chan;
- unsigned int ring_timeout;
- /*! If set to 1, no station will be able to join an active call with
- * this trunk. */
- unsigned int barge_disabled:1;
- /*! This option uses the values in the sla_hold_access enum and sets the
- * access control type for hold on this trunk. */
- unsigned int hold_access:1;
- /*! Whether this trunk is currently on hold, meaning that once a station
- * connects to it, the trunk channel needs to have UNHOLD indicated to it. */
- unsigned int on_hold:1;
-};
-
-struct sla_trunk_ref {
- AST_LIST_ENTRY(sla_trunk_ref) entry;
- struct sla_trunk *trunk;
- enum sla_trunk_state state;
- struct ast_channel *chan;
- /*! Ring timeout to use when this trunk is ringing on this specific
- * station. This takes higher priority than a ring timeout set at
- * the station level. */
- unsigned int ring_timeout;
- /*! Ring delay to use when this trunk is ringing on this specific
- * station. This takes higher priority than a ring delay set at
- * the station level. */
- unsigned int ring_delay;
-};
-
-static AST_RWLIST_HEAD_STATIC(sla_stations, sla_station);
-static AST_RWLIST_HEAD_STATIC(sla_trunks, sla_trunk);
-
-static const char sla_registrar[] = "SLA";
-
-/*! \brief Event types that can be queued up for the SLA thread */
-enum sla_event_type {
- /*! A station has put the call on hold */
- SLA_EVENT_HOLD,
- /*! The state of a dial has changed */
- SLA_EVENT_DIAL_STATE,
- /*! The state of a ringing trunk has changed */
- SLA_EVENT_RINGING_TRUNK,
-};
-
-struct sla_event {
- enum sla_event_type type;
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref;
- AST_LIST_ENTRY(sla_event) entry;
-};
-
-/*! \brief A station that failed to be dialed
- * \note Only used by the SLA thread. */
-struct sla_failed_station {
- struct sla_station *station;
- struct timeval last_try;
- AST_LIST_ENTRY(sla_failed_station) entry;
-};
-
-/*! \brief A trunk that is ringing */
-struct sla_ringing_trunk {
- struct sla_trunk *trunk;
- /*! The time that this trunk started ringing */
- struct timeval ring_begin;
- AST_LIST_HEAD_NOLOCK(, sla_station_ref) timed_out_stations;
- AST_LIST_ENTRY(sla_ringing_trunk) entry;
-};
-
-enum sla_station_hangup {
- SLA_STATION_HANGUP_NORMAL,
- SLA_STATION_HANGUP_TIMEOUT,
-};
-
-/*! \brief A station that is ringing */
-struct sla_ringing_station {
- struct sla_station *station;
- /*! The time that this station started ringing */
- struct timeval ring_begin;
- AST_LIST_ENTRY(sla_ringing_station) entry;
-};
-
-/*!
- * \brief A structure for data used by the sla thread
- */
-static struct {
- /*! The SLA thread ID */
- pthread_t thread;
- ast_cond_t cond;
- ast_mutex_t lock;
- AST_LIST_HEAD_NOLOCK(, sla_ringing_trunk) ringing_trunks;
- AST_LIST_HEAD_NOLOCK(, sla_ringing_station) ringing_stations;
- AST_LIST_HEAD_NOLOCK(, sla_failed_station) failed_stations;
- AST_LIST_HEAD_NOLOCK(, sla_event) event_q;
- unsigned int stop:1;
- /*! Attempt to handle CallerID, even though it is known not to work
- * properly in some situations. */
- unsigned int attempt_callerid:1;
-} sla = {
- .thread = AST_PTHREADT_NULL,
-};
-
-/*! The number of audio buffers to be allocated on pseudo channels
- * when in a conference */
-static int audio_buffers;
-
-/*! Map 'volume' levels from -5 through +5 into
- * decibel (dB) settings for channel drivers
- * Note: these are not a straight linear-to-dB
- * conversion... the numbers have been modified
- * to give the user a better level of adjustability
- */
-static char const gain_map[] = {
- -15,
- -13,
- -10,
- -6,
- 0,
- 0,
- 0,
- 6,
- 10,
- 13,
- 15,
-};
-
-
-static int admin_exec(struct ast_channel *chan, void *data);
-static void *recordthread(void *args);
-
-static char *istalking(int x)
-{
- if (x > 0)
- return "(talking)";
- else if (x < 0)
- return "(unmonitored)";
- else
- return "(not talking)";
-}
-
-static int careful_write(int fd, unsigned char *data, int len, int block)
-{
- int res;
- int x;
-
- while (len) {
- if (block) {
- x = ZT_IOMUX_WRITE | ZT_IOMUX_SIGEVENT;
- res = ioctl(fd, ZT_IOMUX, &x);
- } else
- res = 0;
- if (res >= 0)
- res = write(fd, data, len);
- if (res < 1) {
- if (errno != EAGAIN) {
- ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
- return -1;
- } else
- return 0;
- }
- len -= res;
- data += res;
- }
-
- return 0;
-}
-
-static int set_talk_volume(struct ast_conf_user *user, int volume)
-{
- char gain_adjust;
-
- /* attempt to make the adjustment in the channel driver;
- if successful, don't adjust in the frame reading routine
- */
- gain_adjust = gain_map[volume + 5];
-
- return ast_channel_setoption(user->chan, AST_OPTION_RXGAIN, &gain_adjust, sizeof(gain_adjust), 0);
-}
-
-static int set_listen_volume(struct ast_conf_user *user, int volume)
-{
- char gain_adjust;
-
- /* attempt to make the adjustment in the channel driver;
- if successful, don't adjust in the frame reading routine
- */
- gain_adjust = gain_map[volume + 5];
-
- return ast_channel_setoption(user->chan, AST_OPTION_TXGAIN, &gain_adjust, sizeof(gain_adjust), 0);
-}
-
-static void tweak_volume(struct volume *vol, enum volume_action action)
-{
- switch (action) {
- case VOL_UP:
- switch (vol->desired) {
- case 5:
- break;
- case 0:
- vol->desired = 2;
- break;
- case -2:
- vol->desired = 0;
- break;
- default:
- vol->desired++;
- break;
- }
- break;
- case VOL_DOWN:
- switch (vol->desired) {
- case -5:
- break;
- case 2:
- vol->desired = 0;
- break;
- case 0:
- vol->desired = -2;
- break;
- default:
- vol->desired--;
- break;
- }
- }
-}
-
-static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
-{
- tweak_volume(&user->talk, action);
- /* attempt to make the adjustment in the channel driver;
- if successful, don't adjust in the frame reading routine
- */
- if (!set_talk_volume(user, user->talk.desired))
- user->talk.actual = 0;
- else
- user->talk.actual = user->talk.desired;
-}
-
-static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
-{
- tweak_volume(&user->listen, action);
- /* attempt to make the adjustment in the channel driver;
- if successful, don't adjust in the frame reading routine
- */
- if (!set_listen_volume(user, user->listen.desired))
- user->listen.actual = 0;
- else
- user->listen.actual = user->listen.desired;
-}
-
-static void reset_volumes(struct ast_conf_user *user)
-{
- signed char zero_volume = 0;
-
- ast_channel_setoption(user->chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
- ast_channel_setoption(user->chan, AST_OPTION_RXGAIN, &zero_volume, sizeof(zero_volume), 0);
-}
-
-static void conf_play(struct ast_channel *chan, struct ast_conference *conf, enum entrance_sound sound)
-{
- unsigned char *data;
- int len;
- int res = -1;
-
- if (!chan->_softhangup)
- res = ast_autoservice_start(chan);
-
- AST_LIST_LOCK(&confs);
-
- switch(sound) {
- case ENTER:
- data = enter;
- len = sizeof(enter);
- break;
- case LEAVE:
- data = leave;
- len = sizeof(leave);
- break;
- default:
- data = NULL;
- len = 0;
- }
- if (data) {
- careful_write(conf->fd, data, len, 1);
- }
-
- AST_LIST_UNLOCK(&confs);
-
- if (!res)
- ast_autoservice_stop(chan);
-}
-
-/*!
- * \brief Find or create a conference
- *
- * \param confno The conference name/number
- * \param pin The regular user pin
- * \param pinadmin The admin pin
- * \param make Make the conf if it doesn't exist
- * \param dynamic Mark the newly created conference as dynamic
- * \param refcount How many references to mark on the conference
- *
- * \return A pointer to the conference struct, or NULL if it wasn't found and
- * make or dynamic were not set.
- */
-static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin, int make, int dynamic, int refcount)
-{
- struct ast_conference *cnf;
- struct zt_confinfo ztc = { 0, };
- int confno_int = 0;
-
- AST_LIST_LOCK(&confs);
-
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strcmp(confno, cnf->confno))
- break;
- }
-
- if (cnf || (!make && !dynamic))
- goto cnfout;
-
- /* Make a new one */
- if (!(cnf = ast_calloc(1, sizeof(*cnf))))
- goto cnfout;
-
- ast_mutex_init(&cnf->playlock);
- ast_mutex_init(&cnf->listenlock);
- cnf->recordthread = AST_PTHREADT_NULL;
- ast_mutex_init(&cnf->recordthreadlock);
- ast_copy_string(cnf->confno, confno, sizeof(cnf->confno));
- ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
- ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
-
- /* Setup a new zap conference */
- ztc.confno = -1;
- ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
- cnf->fd = open("/dev/zap/pseudo", O_RDWR);
- if (cnf->fd < 0 || ioctl(cnf->fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Unable to open pseudo device\n");
- if (cnf->fd >= 0)
- close(cnf->fd);
- free(cnf);
- cnf = NULL;
- goto cnfout;
- }
-
- cnf->zapconf = ztc.confno;
-
- /* Setup a new channel for playback of audio files */
- cnf->chan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL);
- if (cnf->chan) {
- ast_set_read_format(cnf->chan, AST_FORMAT_SLINEAR);
- ast_set_write_format(cnf->chan, AST_FORMAT_SLINEAR);
- ztc.chan = 0;
- ztc.confno = cnf->zapconf;
- ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
- if (ioctl(cnf->chan->fds[0], ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- if (cnf->chan)
- ast_hangup(cnf->chan);
- else
- close(cnf->fd);
- free(cnf);
- cnf = NULL;
- goto cnfout;
- }
- }
-
- /* Fill the conference struct */
- cnf->start = time(NULL);
- cnf->isdynamic = dynamic ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Created MeetMe conference %d for conference '%s'\n", cnf->zapconf, cnf->confno);
- AST_LIST_INSERT_HEAD(&confs, cnf, list);
-
- /* Reserve conference number in map */
- if ((sscanf(cnf->confno, "%d", &confno_int) == 1) && (confno_int >= 0 && confno_int < 1024))
- conf_map[confno_int] = 1;
-
-cnfout:
- if (cnf)
- ast_atomic_fetchadd_int(&cnf->refcount, refcount);
-
- AST_LIST_UNLOCK(&confs);
-
- return cnf;
-}
-
-static int meetme_cmd(int fd, int argc, char **argv)
-{
- /* Process the command */
- struct ast_conference *cnf;
- struct ast_conf_user *user;
- int hr, min, sec;
- int i = 0, total = 0;
- time_t now;
- char *header_format = "%-14s %-14s %-10s %-8s %-8s\n";
- char *data_format = "%-12.12s %4.4d %4.4s %02d:%02d:%02d %-8s\n";
- char cmdline[1024] = "";
-
- if (argc > 8)
- ast_cli(fd, "Invalid Arguments.\n");
- /* Check for length so no buffer will overflow... */
- for (i = 0; i < argc; i++) {
- if (strlen(argv[i]) > 100)
- ast_cli(fd, "Invalid Arguments.\n");
- }
- if (argc == 1) {
- /* 'MeetMe': List all the conferences */
- now = time(NULL);
- AST_LIST_LOCK(&confs);
- if (AST_LIST_EMPTY(&confs)) {
- ast_cli(fd, "No active MeetMe conferences.\n");
- AST_LIST_UNLOCK(&confs);
- return RESULT_SUCCESS;
- }
- ast_cli(fd, header_format, "Conf Num", "Parties", "Marked", "Activity", "Creation");
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (cnf->markedusers == 0)
- strcpy(cmdline, "N/A ");
- else
- snprintf(cmdline, sizeof(cmdline), "%4.4d", cnf->markedusers);
- hr = (now - cnf->start) / 3600;
- min = ((now - cnf->start) % 3600) / 60;
- sec = (now - cnf->start) % 60;
-
- ast_cli(fd, data_format, cnf->confno, cnf->users, cmdline, hr, min, sec, cnf->isdynamic ? "Dynamic" : "Static");
-
- total += cnf->users;
- }
- AST_LIST_UNLOCK(&confs);
- ast_cli(fd, "* Total number of MeetMe users: %d\n", total);
- return RESULT_SUCCESS;
- }
- if (argc < 3)
- return RESULT_SHOWUSAGE;
- ast_copy_string(cmdline, argv[2], sizeof(cmdline)); /* Argv 2: conference number */
- if (strstr(argv[1], "lock")) {
- if (strcmp(argv[1], "lock") == 0) {
- /* Lock */
- strncat(cmdline, "|L", sizeof(cmdline) - strlen(cmdline) - 1);
- } else {
- /* Unlock */
- strncat(cmdline, "|l", sizeof(cmdline) - strlen(cmdline) - 1);
- }
- } else if (strstr(argv[1], "mute")) {
- if (argc < 4)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[1], "mute") == 0) {
- /* Mute */
- if (strcmp(argv[3], "all") == 0) {
- strncat(cmdline, "|N", sizeof(cmdline) - strlen(cmdline) - 1);
- } else {
- strncat(cmdline, "|M|", sizeof(cmdline) - strlen(cmdline) - 1);
- strncat(cmdline, argv[3], sizeof(cmdline) - strlen(cmdline) - 1);
- }
- } else {
- /* Unmute */
- if (strcmp(argv[3], "all") == 0) {
- strncat(cmdline, "|n", sizeof(cmdline) - strlen(cmdline) - 1);
- } else {
- strncat(cmdline, "|m|", sizeof(cmdline) - strlen(cmdline) - 1);
- strncat(cmdline, argv[3], sizeof(cmdline) - strlen(cmdline) - 1);
- }
- }
- } else if (strcmp(argv[1], "kick") == 0) {
- if (argc < 4)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[3], "all") == 0) {
- /* Kick all */
- strncat(cmdline, "|K", sizeof(cmdline) - strlen(cmdline) - 1);
- } else {
- /* Kick a single user */
- strncat(cmdline, "|k|", sizeof(cmdline) - strlen(cmdline) - 1);
- strncat(cmdline, argv[3], sizeof(cmdline) - strlen(cmdline) - 1);
- }
- } else if(strcmp(argv[1], "list") == 0) {
- int concise = ( 4 == argc && ( !strcasecmp(argv[3], "concise") ) );
- /* List all the users in a conference */
- if (AST_LIST_EMPTY(&confs)) {
- if ( !concise )
- ast_cli(fd, "No active conferences.\n");
- return RESULT_SUCCESS;
- }
- /* Find the right conference */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (strcmp(cnf->confno, argv[2]) == 0)
- break;
- }
- if (!cnf) {
- if ( !concise )
- ast_cli(fd, "No such conference: %s.\n",argv[2]);
- AST_LIST_UNLOCK(&confs);
- return RESULT_SUCCESS;
- }
- /* Show all the users */
- time(&now);
- AST_LIST_TRAVERSE(&cnf->userlist, user, list) {
- hr = (now - user->jointime) / 3600;
- min = ((now - user->jointime) % 3600) / 60;
- sec = (now - user->jointime) % 60;
- if ( !concise )
- ast_cli(fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %02d:%02d:%02d\n",
- user->user_no,
- S_OR(user->chan->cid.cid_num, "<unknown>"),
- S_OR(user->chan->cid.cid_name, "<no name>"),
- user->chan->name,
- user->userflags & CONFFLAG_ADMIN ? "(Admin)" : "",
- user->userflags & CONFFLAG_MONITOR ? "(Listen only)" : "",
- user->adminflags & ADMINFLAG_MUTED ? "(Admin Muted)" : user->adminflags & ADMINFLAG_SELFMUTED ? "(Muted)" : "",
- istalking(user->talking), hr, min, sec);
- else
- ast_cli(fd, "%d!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n",
- user->user_no,
- S_OR(user->chan->cid.cid_num, ""),
- S_OR(user->chan->cid.cid_name, ""),
- user->chan->name,
- user->userflags & CONFFLAG_ADMIN ? "1" : "",
- user->userflags & CONFFLAG_MONITOR ? "1" : "",
- user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED) ? "1" : "",
- user->talking, hr, min, sec);
-
- }
- if ( !concise )
- ast_cli(fd,"%d users in that conference.\n",cnf->users);
- AST_LIST_UNLOCK(&confs);
- return RESULT_SUCCESS;
- } else
- return RESULT_SHOWUSAGE;
- ast_log(LOG_DEBUG, "Cmdline: %s\n", cmdline);
- admin_exec(NULL, cmdline);
-
- return 0;
-}
-
-static char *complete_meetmecmd(const char *line, const char *word, int pos, int state)
-{
- static char *cmds[] = {"lock", "unlock", "mute", "unmute", "kick", "list", NULL};
-
- int len = strlen(word);
- int which = 0;
- struct ast_conference *cnf = NULL;
- struct ast_conf_user *usr = NULL;
- char *confno = NULL;
- char usrno[50] = "";
- char *myline, *ret = NULL;
-
- if (pos == 1) { /* Command */
- return ast_cli_complete(word, cmds, state);
- } else if (pos == 2) { /* Conference Number */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strncasecmp(word, cnf->confno, len) && ++which > state) {
- ret = cnf->confno;
- break;
- }
- }
- ret = ast_strdup(ret); /* dup before releasing the lock */
- AST_LIST_UNLOCK(&confs);
- return ret;
- } else if (pos == 3) {
- /* User Number || Conf Command option*/
- if (strstr(line, "mute") || strstr(line, "kick")) {
- if (state == 0 && (strstr(line, "kick") || strstr(line,"mute")) && !strncasecmp(word, "all", len))
- return strdup("all");
- which++;
- AST_LIST_LOCK(&confs);
-
- /* TODO: Find the conf number from the cmdline (ignore spaces) <- test this and make it fail-safe! */
- myline = ast_strdupa(line);
- if (strsep(&myline, " ") && strsep(&myline, " ") && !confno) {
- while((confno = strsep(&myline, " ")) && (strcmp(confno, " ") == 0))
- ;
- }
-
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strcmp(confno, cnf->confno))
- break;
- }
-
- if (cnf) {
- /* Search for the user */
- AST_LIST_TRAVERSE(&cnf->userlist, usr, list) {
- snprintf(usrno, sizeof(usrno), "%d", usr->user_no);
- if (!strncasecmp(word, usrno, len) && ++which > state)
- break;
- }
- }
- AST_LIST_UNLOCK(&confs);
- return usr ? strdup(usrno) : NULL;
- } else if ( strstr(line, "list") && ( 0 == state ) )
- return strdup("concise");
- }
-
- return NULL;
-}
-
-static char meetme_usage[] =
-"Usage: meetme (un)lock|(un)mute|kick|list [concise] <confno> <usernumber>\n"
-" Executes a command for the conference or on a conferee\n";
-
-static const char *sla_hold_str(unsigned int hold_access)
-{
- const char *hold = "Unknown";
-
- switch (hold_access) {
- case SLA_HOLD_OPEN:
- hold = "Open";
- break;
- case SLA_HOLD_PRIVATE:
- hold = "Private";
- default:
- break;
- }
-
- return hold;
-}
-
-static int sla_show_trunks(int fd, int argc, char **argv)
-{
- const struct sla_trunk *trunk;
-
- ast_cli(fd, "\n"
- "=============================================================\n"
- "=== Configured SLA Trunks ===================================\n"
- "=============================================================\n"
- "===\n");
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
- struct sla_station_ref *station_ref;
- char ring_timeout[16] = "(none)";
- if (trunk->ring_timeout)
- snprintf(ring_timeout, sizeof(ring_timeout), "%u Seconds", trunk->ring_timeout);
- ast_cli(fd, "=== ---------------------------------------------------------\n"
- "=== Trunk Name: %s\n"
- "=== ==> Device: %s\n"
- "=== ==> AutoContext: %s\n"
- "=== ==> RingTimeout: %s\n"
- "=== ==> BargeAllowed: %s\n"
- "=== ==> HoldAccess: %s\n"
- "=== ==> Stations ...\n",
- trunk->name, trunk->device,
- S_OR(trunk->autocontext, "(none)"),
- ring_timeout,
- trunk->barge_disabled ? "No" : "Yes",
- sla_hold_str(trunk->hold_access));
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry)
- ast_cli(fd, "=== ==> Station name: %s\n", station_ref->station->name);
- AST_RWLIST_UNLOCK(&sla_stations);
- ast_cli(fd, "=== ---------------------------------------------------------\n"
- "===\n");
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
- ast_cli(fd, "=============================================================\n"
- "\n");
-
- return RESULT_SUCCESS;
-}
-
-static const char *trunkstate2str(enum sla_trunk_state state)
-{
-#define S(e) case e: return # e;
- switch (state) {
- S(SLA_TRUNK_STATE_IDLE)
- S(SLA_TRUNK_STATE_RINGING)
- S(SLA_TRUNK_STATE_UP)
- S(SLA_TRUNK_STATE_ONHOLD)
- S(SLA_TRUNK_STATE_ONHOLD_BYME)
- }
- return "Uknown State";
-#undef S
-}
-
-static const char sla_show_trunks_usage[] =
-"Usage: sla show trunks\n"
-" This will list all trunks defined in sla.conf\n";
-
-static int sla_show_stations(int fd, int argc, char **argv)
-{
- const struct sla_station *station;
-
- ast_cli(fd, "\n"
- "=============================================================\n"
- "=== Configured SLA Stations =================================\n"
- "=============================================================\n"
- "===\n");
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
- struct sla_trunk_ref *trunk_ref;
- char ring_timeout[16] = "(none)";
- char ring_delay[16] = "(none)";
- if (station->ring_timeout) {
- snprintf(ring_timeout, sizeof(ring_timeout),
- "%u", station->ring_timeout);
- }
- if (station->ring_delay) {
- snprintf(ring_delay, sizeof(ring_delay),
- "%u", station->ring_delay);
- }
- ast_cli(fd, "=== ---------------------------------------------------------\n"
- "=== Station Name: %s\n"
- "=== ==> Device: %s\n"
- "=== ==> AutoContext: %s\n"
- "=== ==> RingTimeout: %s\n"
- "=== ==> RingDelay: %s\n"
- "=== ==> HoldAccess: %s\n"
- "=== ==> Trunks ...\n",
- station->name, station->device,
- S_OR(station->autocontext, "(none)"),
- ring_timeout, ring_delay,
- sla_hold_str(station->hold_access));
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->ring_timeout) {
- snprintf(ring_timeout, sizeof(ring_timeout),
- "%u", trunk_ref->ring_timeout);
- } else
- strcpy(ring_timeout, "(none)");
- if (trunk_ref->ring_delay) {
- snprintf(ring_delay, sizeof(ring_delay),
- "%u", trunk_ref->ring_delay);
- } else
- strcpy(ring_delay, "(none)");
- ast_cli(fd, "=== ==> Trunk Name: %s\n"
- "=== ==> State: %s\n"
- "=== ==> RingTimeout: %s\n"
- "=== ==> RingDelay: %s\n",
- trunk_ref->trunk->name,
- trunkstate2str(trunk_ref->state),
- ring_timeout, ring_delay);
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
- ast_cli(fd, "=== ---------------------------------------------------------\n"
- "===\n");
- }
- AST_RWLIST_UNLOCK(&sla_stations);
- ast_cli(fd, "============================================================\n"
- "\n");
-
- return RESULT_SUCCESS;
-}
-
-static const char sla_show_stations_usage[] =
-"Usage: sla show stations\n"
-" This will list all stations defined in sla.conf\n";
-
-static struct ast_cli_entry cli_meetme[] = {
- { { "meetme", NULL, NULL },
- meetme_cmd, "Execute a command on a conference or conferee",
- meetme_usage, complete_meetmecmd },
-
- { { "sla", "show", "trunks", NULL },
- sla_show_trunks, "Show SLA Trunks",
- sla_show_trunks_usage, NULL },
-
- { { "sla", "show", "stations", NULL },
- sla_show_stations, "Show SLA Stations",
- sla_show_stations_usage, NULL },
-};
-
-static void conf_flush(int fd, struct ast_channel *chan)
-{
- int x;
-
- /* read any frames that may be waiting on the channel
- and throw them away
- */
- if (chan) {
- struct ast_frame *f;
-
- /* when no frames are available, this will wait
- for 1 millisecond maximum
- */
- while (ast_waitfor(chan, 1)) {
- f = ast_read(chan);
- if (f)
- ast_frfree(f);
- else /* channel was hung up or something else happened */
- break;
- }
- }
-
- /* flush any data sitting in the pseudo channel */
- x = ZT_FLUSH_ALL;
- if (ioctl(fd, ZT_FLUSH, &x))
- ast_log(LOG_WARNING, "Error flushing channel\n");
-
-}
-
-/* Remove the conference from the list and free it.
- We assume that this was called while holding conflock. */
-static int conf_free(struct ast_conference *conf)
-{
- int x;
-
- AST_LIST_REMOVE(&confs, conf, list);
-
- if (conf->recording == MEETME_RECORD_ACTIVE) {
- conf->recording = MEETME_RECORD_TERMINATE;
- AST_LIST_UNLOCK(&confs);
- while (1) {
- usleep(1);
- AST_LIST_LOCK(&confs);
- if (conf->recording == MEETME_RECORD_OFF)
- break;
- AST_LIST_UNLOCK(&confs);
- }
- }
-
- for (x=0;x<AST_FRAME_BITS;x++) {
- if (conf->transframe[x])
- ast_frfree(conf->transframe[x]);
- if (conf->transpath[x])
- ast_translator_free_path(conf->transpath[x]);
- }
- if (conf->origframe)
- ast_frfree(conf->origframe);
- if (conf->lchan)
- ast_hangup(conf->lchan);
- if (conf->chan)
- ast_hangup(conf->chan);
- if (conf->fd >= 0)
- close(conf->fd);
-
- ast_mutex_destroy(&conf->playlock);
- ast_mutex_destroy(&conf->listenlock);
- ast_mutex_destroy(&conf->recordthreadlock);
- free(conf);
-
- return 0;
-}
-
-static void conf_queue_dtmf(const struct ast_conference *conf,
- const struct ast_conf_user *sender, struct ast_frame *f)
-{
- struct ast_conf_user *user;
-
- AST_LIST_TRAVERSE(&conf->userlist, user, list) {
- if (user == sender)
- continue;
- if (ast_write(user->chan, f) < 0)
- ast_log(LOG_WARNING, "Error writing frame to channel %s\n", user->chan->name);
- }
-}
-
-static void sla_queue_event_full(enum sla_event_type type,
- struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
-{
- struct sla_event *event;
-
- if (!(event = ast_calloc(1, sizeof(*event))))
- return;
-
- event->type = type;
- event->trunk_ref = trunk_ref;
- event->station = station;
-
- if (!lock) {
- AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
- return;
- }
-
- ast_mutex_lock(&sla.lock);
- AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
- ast_cond_signal(&sla.cond);
- ast_mutex_unlock(&sla.lock);
-}
-
-static void sla_queue_event_nolock(enum sla_event_type type)
-{
- sla_queue_event_full(type, NULL, NULL, 0);
-}
-
-static void sla_queue_event(enum sla_event_type type)
-{
- sla_queue_event_full(type, NULL, NULL, 1);
-}
-
-/*! \brief Queue a SLA event from the conference */
-static void sla_queue_event_conf(enum sla_event_type type, struct ast_channel *chan,
- struct ast_conference *conf)
-{
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref = NULL;
- char *trunk_name;
-
- trunk_name = ast_strdupa(conf->confno);
- strsep(&trunk_name, "_");
- if (ast_strlen_zero(trunk_name)) {
- ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", conf->confno);
- return;
- }
-
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name))
- break;
- }
- if (trunk_ref)
- break;
- }
- AST_RWLIST_UNLOCK(&sla_stations);
-
- if (!trunk_ref) {
- ast_log(LOG_DEBUG, "Trunk not found for event!\n");
- return;
- }
-
- sla_queue_event_full(type, trunk_ref, station, 1);
-}
-
-/* Decrement reference counts, as incremented by find_conf() */
-static int dispose_conf(struct ast_conference *conf)
-{
- int res = 0;
- int confno_int = 0;
-
- AST_LIST_LOCK(&confs);
- if (ast_atomic_dec_and_test(&conf->refcount)) {
- /* Take the conference room number out of an inuse state */
- if ((sscanf(conf->confno, "%d", &confno_int) == 1) && (confno_int >= 0 && confno_int < 1024))
- conf_map[confno_int] = 0;
- conf_free(conf);
- res = 1;
- }
- AST_LIST_UNLOCK(&confs);
-
- return res;
-}
-
-
-static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags, char *optargs[])
-{
- struct ast_conf_user *user = NULL;
- struct ast_conf_user *usr = NULL;
- int fd;
- struct zt_confinfo ztc, ztc_empty;
- struct ast_frame *f;
- struct ast_channel *c;
- struct ast_frame fr;
- int outfd;
- int ms;
- int nfds;
- int res;
- int flags;
- int retryzap;
- int origfd;
- int musiconhold = 0;
- int firstpass = 0;
- int lastmarked = 0;
- int currentmarked = 0;
- int ret = -1;
- int x;
- int menu_active = 0;
- int using_pseudo = 0;
- int duration=20;
- int hr, min, sec;
- int sent_event = 0;
- time_t now;
- struct ast_dsp *dsp=NULL;
- struct ast_app *app;
- const char *agifile;
- const char *agifiledefault = "conf-background.agi";
- char meetmesecs[30] = "";
- char exitcontext[AST_MAX_CONTEXT] = "";
- char recordingtmp[AST_MAX_EXTENSION] = "";
- char members[10] = "";
- int dtmf, opt_waitmarked_timeout = 0;
- time_t timeout = 0;
- ZT_BUFFERINFO bi;
- char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
- char *buf = __buf + AST_FRIENDLY_OFFSET;
- int setusercount = 0;
-
- if (!(user = ast_calloc(1, sizeof(*user))))
- return ret;
-
- /* Possible timeout waiting for marked user */
- if ((confflags & CONFFLAG_WAITMARKED) &&
- !ast_strlen_zero(optargs[OPT_ARG_WAITMARKED]) &&
- (sscanf(optargs[OPT_ARG_WAITMARKED], "%d", &opt_waitmarked_timeout) == 1) &&
- (opt_waitmarked_timeout > 0)) {
- timeout = time(NULL) + opt_waitmarked_timeout;
- }
-
- if (confflags & CONFFLAG_RECORDCONF) {
- if (!conf->recordingfilename) {
- conf->recordingfilename = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE");
- if (!conf->recordingfilename) {
- snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, chan->uniqueid);
- conf->recordingfilename = ast_strdupa(recordingtmp);
- }
- conf->recordingformat = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT");
- if (!conf->recordingformat) {
- snprintf(recordingtmp, sizeof(recordingtmp), "wav");
- conf->recordingformat = ast_strdupa(recordingtmp);
- }
- ast_verbose(VERBOSE_PREFIX_4 "Starting recording of MeetMe Conference %s into file %s.%s.\n",
- conf->confno, conf->recordingfilename, conf->recordingformat);
- }
- }
-
- ast_mutex_lock(&conf->recordthreadlock);
- if ((conf->recordthread == AST_PTHREADT_NULL) && (confflags & CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL)))) {
- ast_set_read_format(conf->lchan, AST_FORMAT_SLINEAR);
- ast_set_write_format(conf->lchan, AST_FORMAT_SLINEAR);
- ztc.chan = 0;
- ztc.confno = conf->zapconf;
- ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
- if (ioctl(conf->lchan->fds[0], ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error starting listen channel\n");
- ast_hangup(conf->lchan);
- conf->lchan = NULL;
- } else {
- pthread_attr_init(&conf->attr);
- pthread_attr_setdetachstate(&conf->attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create_background(&conf->recordthread, &conf->attr, recordthread, conf);
- pthread_attr_destroy(&conf->attr);
- }
- }
- ast_mutex_unlock(&conf->recordthreadlock);
-
- time(&user->jointime);
-
- if (conf->locked && (!(confflags & CONFFLAG_ADMIN))) {
- /* Sorry, but this confernce is locked! */
- if (!ast_streamfile(chan, "conf-locked", chan->language))
- ast_waitstream(chan, "");
- goto outrun;
- }
-
- ast_mutex_lock(&conf->playlock);
-
- if (AST_LIST_EMPTY(&conf->userlist))
- user->user_no = 1;
- else
- user->user_no = AST_LIST_LAST(&conf->userlist)->user_no + 1;
-
- AST_LIST_INSERT_TAIL(&conf->userlist, user, list);
-
- user->chan = chan;
- user->userflags = confflags;
- user->adminflags = (confflags & CONFFLAG_STARTMUTED) ? ADMINFLAG_SELFMUTED : 0;
- user->talking = -1;
-
- ast_mutex_unlock(&conf->playlock);
-
- if (!(confflags & CONFFLAG_QUIET) && ((confflags & CONFFLAG_INTROUSER) || (confflags & CONFFLAG_INTROUSERNOREVIEW))) {
- char destdir[PATH_MAX];
-
- snprintf(destdir, sizeof(destdir), "%s/meetme", ast_config_AST_SPOOL_DIR);
-
- if (mkdir(destdir, 0777) && errno != EEXIST) {
- ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
- goto outrun;
- }
-
- snprintf(user->namerecloc, sizeof(user->namerecloc),
- "%s/meetme-username-%s-%d", destdir,
- conf->confno, user->user_no);
- if (confflags & CONFFLAG_INTROUSERNOREVIEW)
- res = ast_play_and_record(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, 128, 0, NULL);
- else
- res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL);
- if (res == -1)
- goto outrun;
- }
-
- ast_mutex_lock(&conf->playlock);
-
- if (confflags & CONFFLAG_MARKEDUSER)
- conf->markedusers++;
- conf->users++;
- /* Update table */
- snprintf(members, sizeof(members), "%d", conf->users);
- ast_update_realtime("meetme", "confno", conf->confno, "members", members , NULL);
- setusercount = 1;
-
- /* This device changed state now - if this is the first user */
- if (conf->users == 1)
- ast_device_state_changed("meetme:%s", conf->confno);
-
- ast_mutex_unlock(&conf->playlock);
-
- if (confflags & CONFFLAG_EXIT_CONTEXT) {
- if ((agifile = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT")))
- ast_copy_string(exitcontext, agifile, sizeof(exitcontext));
- else if (!ast_strlen_zero(chan->macrocontext))
- ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext));
- else
- ast_copy_string(exitcontext, chan->context, sizeof(exitcontext));
- }
-
- if ( !(confflags & (CONFFLAG_QUIET | CONFFLAG_NOONLYPERSON)) ) {
- if (conf->users == 1 && !(confflags & CONFFLAG_WAITMARKED))
- if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
- ast_waitstream(chan, "");
- if ((confflags & CONFFLAG_WAITMARKED) && conf->markedusers == 0)
- if (!ast_streamfile(chan, "conf-waitforleader", chan->language))
- ast_waitstream(chan, "");
- }
-
- if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_ANNOUNCEUSERCOUNT) && conf->users > 1) {
- int keepplaying = 1;
-
- if (conf->users == 2) {
- if (!ast_streamfile(chan,"conf-onlyone",chan->language)) {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- if (res > 0)
- keepplaying=0;
- else if (res == -1)
- goto outrun;
- }
- } else {
- if (!ast_streamfile(chan, "conf-thereare", chan->language)) {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- if (res > 0)
- keepplaying=0;
- else if (res == -1)
- goto outrun;
- }
- if (keepplaying) {
- res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
- if (res > 0)
- keepplaying=0;
- else if (res == -1)
- goto outrun;
- }
- if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", chan->language)) {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- if (res > 0)
- keepplaying=0;
- else if (res == -1)
- goto outrun;
- }
- }
- }
-
- ast_indicate(chan, -1);
-
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
- ast_log(LOG_WARNING, "Unable to set '%s' to write linear mode\n", chan->name);
- goto outrun;
- }
-
- if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
- ast_log(LOG_WARNING, "Unable to set '%s' to read linear mode\n", chan->name);
- goto outrun;
- }
-
- retryzap = (strcasecmp(chan->tech->type, "Zap") || (chan->audiohooks || chan->monitor) ? 1 : 0);
- user->zapchannel = !retryzap;
-
- zapretry:
- origfd = chan->fds[0];
- if (retryzap) {
- fd = open("/dev/zap/pseudo", O_RDWR);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
- goto outrun;
- }
- using_pseudo = 1;
- /* Make non-blocking */
- flags = fcntl(fd, F_GETFL);
- if (flags < 0) {
- ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
- ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- /* Setup buffering information */
- memset(&bi, 0, sizeof(bi));
- bi.bufsize = CONF_SIZE/2;
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = audio_buffers;
- if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
- ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- x = 1;
- if (ioctl(fd, ZT_SETLINEAR, &x)) {
- ast_log(LOG_WARNING, "Unable to set linear mode: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- nfds = 1;
- } else {
- /* XXX Make sure we're not running on a pseudo channel XXX */
- fd = chan->fds[0];
- nfds = 0;
- }
- memset(&ztc, 0, sizeof(ztc));
- memset(&ztc_empty, 0, sizeof(ztc_empty));
- /* Check to see if we're in a conference... */
- ztc.chan = 0;
- if (ioctl(fd, ZT_GETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error getting conference\n");
- close(fd);
- goto outrun;
- }
- if (ztc.confmode) {
- /* Whoa, already in a conference... Retry... */
- if (!retryzap) {
- ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
- retryzap = 1;
- goto zapretry;
- }
- }
- memset(&ztc, 0, sizeof(ztc));
- /* Add us to the conference */
- ztc.chan = 0;
- ztc.confno = conf->zapconf;
-
- ast_mutex_lock(&conf->playlock);
-
- if (!(confflags & CONFFLAG_QUIET) && ((confflags & CONFFLAG_INTROUSER) || (confflags & CONFFLAG_INTROUSERNOREVIEW)) && conf->users > 1) {
- if (conf->chan && ast_fileexists(user->namerecloc, NULL, NULL)) {
- if (!ast_streamfile(conf->chan, user->namerecloc, chan->language))
- ast_waitstream(conf->chan, "");
- if (!ast_streamfile(conf->chan, "conf-hasjoin", chan->language))
- ast_waitstream(conf->chan, "");
- }
- }
-
- if (confflags & CONFFLAG_WAITMARKED && !conf->markedusers)
- ztc.confmode = ZT_CONF_CONF;
- else if (confflags & CONFFLAG_MONITOR)
- ztc.confmode = ZT_CONF_CONFMON | ZT_CONF_LISTENER;
- else if (confflags & CONFFLAG_TALKER)
- ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER;
- else
- ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
-
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- ast_mutex_unlock(&conf->playlock);
- goto outrun;
- }
- ast_log(LOG_DEBUG, "Placed channel %s in ZAP conf %d\n", chan->name, conf->zapconf);
-
- if (!sent_event) {
- manager_event(EVENT_FLAG_CALL, "MeetmeJoin",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %d\r\n",
- chan->name, chan->uniqueid, conf->confno, user->user_no);
- sent_event = 1;
- }
-
- if (!firstpass && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN)) {
- firstpass = 1;
- if (!(confflags & CONFFLAG_QUIET))
- if (!(confflags & CONFFLAG_WAITMARKED) || ((confflags & CONFFLAG_MARKEDUSER) && (conf->markedusers >= 1)))
- conf_play(chan, conf, ENTER);
- }
-
- ast_mutex_unlock(&conf->playlock);
-
- conf_flush(fd, chan);
-
- if (confflags & CONFFLAG_AGI) {
- /* Get name of AGI file to run from $(MEETME_AGI_BACKGROUND)
- or use default filename of conf-background.agi */
-
- agifile = pbx_builtin_getvar_helper(chan, "MEETME_AGI_BACKGROUND");
- if (!agifile)
- agifile = agifiledefault;
-
- if (user->zapchannel) {
- /* Set CONFMUTE mode on Zap channel to mute DTMF tones */
- x = 1;
- ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
- }
- /* Find a pointer to the agi app and execute the script */
- app = pbx_findapp("agi");
- if (app) {
- char *s = ast_strdupa(agifile);
- ret = pbx_exec(chan, app, s);
- } else {
- ast_log(LOG_WARNING, "Could not find application (agi)\n");
- ret = -2;
- }
- if (user->zapchannel) {
- /* Remove CONFMUTE mode on Zap channel */
- x = 0;
- ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
- }
- } else {
- if (user->zapchannel && (confflags & CONFFLAG_STARMENU)) {
- /* Set CONFMUTE mode on Zap channel to mute DTMF tones when the menu is enabled */
- x = 1;
- ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
- }
- if (confflags & (CONFFLAG_MONITORTALKER | CONFFLAG_OPTIMIZETALKER) && !(dsp = ast_dsp_new())) {
- ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
- res = -1;
- }
- for(;;) {
- int menu_was_active = 0;
-
- outfd = -1;
- ms = -1;
-
- if (timeout && time(NULL) >= timeout)
- break;
-
- /* if we have just exited from the menu, and the user had a channel-driver
- volume adjustment, restore it
- */
- if (!menu_active && menu_was_active && user->listen.desired && !user->listen.actual)
- set_talk_volume(user, user->listen.desired);
-
- menu_was_active = menu_active;
-
- currentmarked = conf->markedusers;
- if (!(confflags & CONFFLAG_QUIET) &&
- (confflags & CONFFLAG_MARKEDUSER) &&
- (confflags & CONFFLAG_WAITMARKED) &&
- lastmarked == 0) {
- if (currentmarked == 1 && conf->users > 1) {
- ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
- if (conf->users - 1 == 1) {
- if (!ast_streamfile(chan, "conf-userwilljoin", chan->language))
- ast_waitstream(chan, "");
- } else {
- if (!ast_streamfile(chan, "conf-userswilljoin", chan->language))
- ast_waitstream(chan, "");
- }
- }
- if (conf->users == 1 && ! (confflags & CONFFLAG_MARKEDUSER))
- if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
- ast_waitstream(chan, "");
- }
-
- c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
-
-
- /* Update the struct with the actual confflags */
- user->userflags = confflags;
-
- if (confflags & CONFFLAG_WAITMARKED) {
- if(currentmarked == 0) {
- if (lastmarked != 0) {
- if (!(confflags & CONFFLAG_QUIET))
- if (!ast_streamfile(chan, "conf-leaderhasleft", chan->language))
- ast_waitstream(chan, "");
- if(confflags & CONFFLAG_MARKEDEXIT)
- break;
- else {
- ztc.confmode = ZT_CONF_CONF;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- goto outrun;
- }
- }
- }
- if (musiconhold == 0 && (confflags & CONFFLAG_MOH)) {
- ast_moh_start(chan, NULL, NULL);
- musiconhold = 1;
- }
- } else if(currentmarked >= 1 && lastmarked == 0) {
- /* Marked user entered, so cancel timeout */
- timeout = 0;
- if (confflags & CONFFLAG_MONITOR)
- ztc.confmode = ZT_CONF_CONFMON | ZT_CONF_LISTENER;
- else if (confflags & CONFFLAG_TALKER)
- ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER;
- else
- ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- goto outrun;
- }
- if (musiconhold && (confflags & CONFFLAG_MOH)) {
- ast_moh_stop(chan);
- musiconhold = 0;
- }
- if ( !(confflags & CONFFLAG_QUIET) && !(confflags & CONFFLAG_MARKEDUSER)) {
- if (!ast_streamfile(chan, "conf-placeintoconf", chan->language))
- ast_waitstream(chan, "");
- conf_play(chan, conf, ENTER);
- }
- }
- }
-
- /* trying to add moh for single person conf */
- if ((confflags & CONFFLAG_MOH) && !(confflags & CONFFLAG_WAITMARKED)) {
- if (conf->users == 1) {
- if (musiconhold == 0) {
- ast_moh_start(chan, NULL, NULL);
- musiconhold = 1;
- }
- } else {
- if (musiconhold) {
- ast_moh_stop(chan);
- musiconhold = 0;
- }
- }
- }
-
- /* Leave if the last marked user left */
- if (currentmarked == 0 && lastmarked != 0 && (confflags & CONFFLAG_MARKEDEXIT)) {
- ret = -1;
- break;
- }
-
- /* Check if my modes have changed */
-
- /* If I should be muted but am still talker, mute me */
- if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && (ztc.confmode & ZT_CONF_TALKER)) {
- ztc.confmode ^= ZT_CONF_TALKER;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
- ret = -1;
- break;
- }
-
- manager_event(EVENT_FLAG_CALL, "MeetmeMute",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %i\r\n"
- "Status: on\r\n",
- chan->name, chan->uniqueid, conf->confno, user->user_no);
- }
-
- /* If I should be un-muted but am not talker, un-mute me */
- if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && !(confflags & CONFFLAG_MONITOR) && !(ztc.confmode & ZT_CONF_TALKER)) {
- ztc.confmode |= ZT_CONF_TALKER;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
- ret = -1;
- break;
- }
-
- manager_event(EVENT_FLAG_CALL, "MeetmeMute",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %i\r\n"
- "Status: off\r\n",
- chan->name, chan->uniqueid, conf->confno, user->user_no);
- }
-
- /* If I have been kicked, exit the conference */
- if (user->adminflags & ADMINFLAG_KICKME) {
- //You have been kicked.
- if (!(confflags & CONFFLAG_QUIET) &&
- !ast_streamfile(chan, "conf-kicked", chan->language)) {
- ast_waitstream(chan, "");
- }
- ret = 0;
- break;
- }
-
- /* Perform an extra hangup check just in case */
- if (ast_check_hangup(chan))
- break;
-
- if (c) {
- if (c->fds[0] != origfd || (user->zapchannel && (c->audiohooks || c->monitor))) {
- if (using_pseudo) {
- /* Kill old pseudo */
- close(fd);
- using_pseudo = 0;
- }
- ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
- retryzap = (strcasecmp(c->tech->type, "Zap") || (c->audiohooks || c->monitor) ? 1 : 0);
- user->zapchannel = !retryzap;
- goto zapretry;
- }
- if ((confflags & CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)))
- f = ast_read_noaudio(c);
- else
- f = ast_read(c);
- if (!f)
- break;
- if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
- if (user->talk.actual)
- ast_frame_adjust_volume(f, user->talk.actual);
-
- if (confflags & (CONFFLAG_MONITORTALKER | CONFFLAG_OPTIMIZETALKER)) {
- int totalsilence;
-
- if (user->talking == -1)
- user->talking = 0;
-
- res = ast_dsp_silence(dsp, f, &totalsilence);
- if (!user->talking && totalsilence < MEETME_DELAYDETECTTALK) {
- user->talking = 1;
- if (confflags & CONFFLAG_MONITORTALKER)
- manager_event(EVENT_FLAG_CALL, "MeetmeTalking",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %d\r\n"
- "Status: on\r\n",
- chan->name, chan->uniqueid, conf->confno, user->user_no);
- }
- if (user->talking && totalsilence > MEETME_DELAYDETECTENDTALK) {
- user->talking = 0;
- if (confflags & CONFFLAG_MONITORTALKER)
- manager_event(EVENT_FLAG_CALL, "MeetmeTalking",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %d\r\n"
- "Status: off\r\n",
- chan->name, chan->uniqueid, conf->confno, user->user_no);
- }
- }
- if (using_pseudo) {
- /* Absolutely do _not_ use careful_write here...
- it is important that we read data from the channel
- as fast as it arrives, and feed it into the conference.
- The buffering in the pseudo channel will take care of any
- timing differences, unless they are so drastic as to lose
- audio frames (in which case carefully writing would only
- have delayed the audio even further).
- */
- /* As it turns out, we do want to use careful write. We just
- don't want to block, but we do want to at least *try*
- to write out all the samples.
- */
- if (user->talking || !(confflags & CONFFLAG_OPTIMIZETALKER))
- careful_write(fd, f->data, f->datalen, 0);
- }
- } else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
- char tmp[2];
-
- if (confflags & CONFFLAG_PASS_DTMF)
- conf_queue_dtmf(conf, user, f);
-
- tmp[0] = f->subclass;
- tmp[1] = '\0';
- if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
- ast_log(LOG_DEBUG, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
- ret = 0;
- ast_frfree(f);
- break;
- } else if (option_debug > 1)
- ast_log(LOG_DEBUG, "Exit by single digit did not work in meetme. Extension %s does not exist in context %s\n", tmp, exitcontext);
- } else if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#') && (confflags & CONFFLAG_POUNDEXIT)) {
- if (confflags & CONFFLAG_PASS_DTMF)
- conf_queue_dtmf(conf, user, f);
- ret = 0;
- ast_frfree(f);
- break;
- } else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*') && (confflags & CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_active)) {
- if (confflags & CONFFLAG_PASS_DTMF)
- conf_queue_dtmf(conf, user, f);
- if (ioctl(fd, ZT_SETCONF, &ztc_empty)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- ast_frfree(f);
- goto outrun;
- }
-
- /* if we are entering the menu, and the user has a channel-driver
- volume adjustment, clear it
- */
- if (!menu_active && user->talk.desired && !user->talk.actual)
- set_talk_volume(user, 0);
-
- if (musiconhold) {
- ast_moh_stop(chan);
- }
- if ((confflags & CONFFLAG_ADMIN)) {
- /* Admin menu */
- if (!menu_active) {
- menu_active = 1;
- /* Record this sound! */
- if (!ast_streamfile(chan, "conf-adminmenu", chan->language)) {
- dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- } else
- dtmf = 0;
- } else
- dtmf = f->subclass;
- if (dtmf) {
- switch(dtmf) {
- case '1': /* Un/Mute */
- menu_active = 0;
-
- /* for admin, change both admin and use flags */
- if (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))
- user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
- else
- user->adminflags |= (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
-
- if ((confflags & CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))) {
- if (!ast_streamfile(chan, "conf-muted", chan->language))
- ast_waitstream(chan, "");
- } else {
- if (!ast_streamfile(chan, "conf-unmuted", chan->language))
- ast_waitstream(chan, "");
- }
- break;
- case '2': /* Un/Lock the Conference */
- menu_active = 0;
- if (conf->locked) {
- conf->locked = 0;
- if (!ast_streamfile(chan, "conf-unlockednow", chan->language))
- ast_waitstream(chan, "");
- } else {
- conf->locked = 1;
- if (!ast_streamfile(chan, "conf-lockednow", chan->language))
- ast_waitstream(chan, "");
- }
- break;
- case '3': /* Eject last user */
- menu_active = 0;
- usr = AST_LIST_LAST(&conf->userlist);
- if ((usr->chan->name == chan->name)||(usr->userflags & CONFFLAG_ADMIN)) {
- if(!ast_streamfile(chan, "conf-errormenu", chan->language))
- ast_waitstream(chan, "");
- } else
- usr->adminflags |= ADMINFLAG_KICKME;
- ast_stopstream(chan);
- break;
- case '4':
- tweak_listen_volume(user, VOL_DOWN);
- break;
- case '6':
- tweak_listen_volume(user, VOL_UP);
- break;
- case '7':
- tweak_talk_volume(user, VOL_DOWN);
- break;
- case '8':
- menu_active = 0;
- break;
- case '9':
- tweak_talk_volume(user, VOL_UP);
- break;
- default:
- menu_active = 0;
- /* Play an error message! */
- if (!ast_streamfile(chan, "conf-errormenu", chan->language))
- ast_waitstream(chan, "");
- break;
- }
- }
- } else {
- /* User menu */
- if (!menu_active) {
- menu_active = 1;
- if (!ast_streamfile(chan, "conf-usermenu", chan->language)) {
- dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- } else
- dtmf = 0;
- } else
- dtmf = f->subclass;
- if (dtmf) {
- switch(dtmf) {
- case '1': /* Un/Mute */
- menu_active = 0;
-
- /* user can only toggle the self-muted state */
- user->adminflags ^= ADMINFLAG_SELFMUTED;
-
- /* they can't override the admin mute state */
- if ((confflags & CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))) {
- if (!ast_streamfile(chan, "conf-muted", chan->language))
- ast_waitstream(chan, "");
- } else {
- if (!ast_streamfile(chan, "conf-unmuted", chan->language))
- ast_waitstream(chan, "");
- }
- break;
- case '4':
- tweak_listen_volume(user, VOL_DOWN);
- break;
- case '6':
- tweak_listen_volume(user, VOL_UP);
- break;
- case '7':
- tweak_talk_volume(user, VOL_DOWN);
- break;
- case '8':
- menu_active = 0;
- break;
- case '9':
- tweak_talk_volume(user, VOL_UP);
- break;
- default:
- menu_active = 0;
- if (!ast_streamfile(chan, "conf-errormenu", chan->language))
- ast_waitstream(chan, "");
- break;
- }
- }
- }
- if (musiconhold)
- ast_moh_start(chan, NULL, NULL);
-
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- ast_frfree(f);
- goto outrun;
- }
-
- conf_flush(fd, chan);
- } else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
- && confflags & CONFFLAG_PASS_DTMF) {
- conf_queue_dtmf(conf, user, f);
- } else if ((confflags & CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
- switch (f->subclass) {
- case AST_CONTROL_HOLD:
- sla_queue_event_conf(SLA_EVENT_HOLD, chan, conf);
- break;
- default:
- break;
- }
- } else if (f->frametype == AST_FRAME_NULL) {
- /* Ignore NULL frames. It is perfectly normal to get these if the person is muted. */
- } else if (option_debug) {
- ast_log(LOG_DEBUG,
- "Got unrecognized frame on channel %s, f->frametype=%d,f->subclass=%d\n",
- chan->name, f->frametype, f->subclass);
- }
- ast_frfree(f);
- } else if (outfd > -1) {
- res = read(outfd, buf, CONF_SIZE);
- if (res > 0) {
- memset(&fr, 0, sizeof(fr));
- fr.frametype = AST_FRAME_VOICE;
- fr.subclass = AST_FORMAT_SLINEAR;
- fr.datalen = res;
- fr.samples = res/2;
- fr.data = buf;
- fr.offset = AST_FRIENDLY_OFFSET;
- if (!user->listen.actual &&
- ((confflags & CONFFLAG_MONITOR) ||
- (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) ||
- (!user->talking && (confflags & CONFFLAG_OPTIMIZETALKER))
- )) {
- int index;
- for (index=0;index<AST_FRAME_BITS;index++)
- if (chan->rawwriteformat & (1 << index))
- break;
- if (index >= AST_FRAME_BITS)
- goto bailoutandtrynormal;
- ast_mutex_lock(&conf->listenlock);
- if (!conf->transframe[index]) {
- if (conf->origframe) {
- if (!conf->transpath[index])
- conf->transpath[index] = ast_translator_build_path((1 << index), AST_FORMAT_SLINEAR);
- if (conf->transpath[index]) {
- conf->transframe[index] = ast_translate(conf->transpath[index], conf->origframe, 0);
- if (!conf->transframe[index])
- conf->transframe[index] = &ast_null_frame;
- }
- }
- }
- if (conf->transframe[index]) {
- if (conf->transframe[index]->frametype != AST_FRAME_NULL) {
- if (ast_write(chan, conf->transframe[index]))
- ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", chan->name);
- }
- } else {
- ast_mutex_unlock(&conf->listenlock);
- goto bailoutandtrynormal;
- }
- ast_mutex_unlock(&conf->listenlock);
- } else {
-bailoutandtrynormal:
- if (user->listen.actual)
- ast_frame_adjust_volume(&fr, user->listen.actual);
- if (ast_write(chan, &fr) < 0) {
- ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", chan->name);
- }
- }
- } else
- ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
- }
- lastmarked = currentmarked;
- }
- }
-
- if (musiconhold)
- ast_moh_stop(chan);
-
- if (using_pseudo)
- close(fd);
- else {
- /* Take out of conference */
- ztc.chan = 0;
- ztc.confno = 0;
- ztc.confmode = 0;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- }
- }
-
- reset_volumes(user);
-
- AST_LIST_LOCK(&confs);
- if (!(confflags & CONFFLAG_QUIET) && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN))
- conf_play(chan, conf, LEAVE);
-
- if (!(confflags & CONFFLAG_QUIET) && ((confflags & CONFFLAG_INTROUSER) || (confflags & CONFFLAG_INTROUSERNOREVIEW))) {
- if (ast_fileexists(user->namerecloc, NULL, NULL)) {
- if ((conf->chan) && (conf->users > 1)) {
- if (!ast_streamfile(conf->chan, user->namerecloc, chan->language))
- ast_waitstream(conf->chan, "");
- if (!ast_streamfile(conf->chan, "conf-hasleft", chan->language))
- ast_waitstream(conf->chan, "");
- }
- ast_filedelete(user->namerecloc, NULL);
- }
- }
- AST_LIST_UNLOCK(&confs);
-
- outrun:
- AST_LIST_LOCK(&confs);
-
- if (dsp)
- ast_dsp_free(dsp);
-
- if (user->user_no) { /* Only cleanup users who really joined! */
- now = time(NULL);
- hr = (now - user->jointime) / 3600;
- min = ((now - user->jointime) % 3600) / 60;
- sec = (now - user->jointime) % 60;
-
- if (sent_event) {
- manager_event(EVENT_FLAG_CALL, "MeetmeLeave",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %d\r\n"
- "CallerIDnum: %s\r\n"
- "CallerIDname: %s\r\n"
- "Duration: %ld\r\n",
- chan->name, chan->uniqueid, conf->confno,
- user->user_no,
- S_OR(user->chan->cid.cid_num, "<unknown>"),
- S_OR(user->chan->cid.cid_name, "<unknown>"),
- (long)(now - user->jointime));
- }
-
- if (setusercount) {
- conf->users--;
- /* Update table */
- snprintf(members, sizeof(members), "%d", conf->users);
- ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
- if (confflags & CONFFLAG_MARKEDUSER)
- conf->markedusers--;
- }
- /* Remove ourselves from the list */
- AST_LIST_REMOVE(&conf->userlist, user, list);
-
- /* Change any states */
- if (!conf->users)
- ast_device_state_changed("meetme:%s", conf->confno);
-
- /* Return the number of seconds the user was in the conf */
- snprintf(meetmesecs, sizeof(meetmesecs), "%d", (int) (time(NULL) - user->jointime));
- pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
- }
- free(user);
- AST_LIST_UNLOCK(&confs);
-
- return ret;
-}
-
-static struct ast_conference *find_conf_realtime(struct ast_channel *chan, char *confno, int make, int dynamic,
- char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags *confflags)
-{
- struct ast_variable *var;
- struct ast_conference *cnf;
-
- /* Check first in the conference list */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strcmp(confno, cnf->confno))
- break;
- }
- if (cnf) {
- cnf->refcount += refcount;
- }
- AST_LIST_UNLOCK(&confs);
-
- if (!cnf) {
- char *pin = NULL, *pinadmin = NULL; /* For temp use */
-
- var = ast_load_realtime("meetme", "confno", confno, NULL);
-
- if (!var)
- return NULL;
-
- while (var) {
- if (!strcasecmp(var->name, "pin")) {
- pin = ast_strdupa(var->value);
- } else if (!strcasecmp(var->name, "adminpin")) {
- pinadmin = ast_strdupa(var->value);
- }
- var = var->next;
- }
- ast_variables_destroy(var);
-
- cnf = build_conf(confno, pin ? pin : "", pinadmin ? pinadmin : "", make, dynamic, refcount);
- }
-
- if (cnf) {
- if (confflags && !cnf->chan &&
- !ast_test_flag(confflags, CONFFLAG_QUIET) &&
- ast_test_flag(confflags, CONFFLAG_INTROUSER)) {
- ast_log(LOG_WARNING, "No Zap channel available for conference, user introduction disabled (is chan_zap loaded?)\n");
- ast_clear_flag(confflags, CONFFLAG_INTROUSER);
- }
-
- if (confflags && !cnf->chan &&
- ast_test_flag(confflags, CONFFLAG_RECORDCONF)) {
- ast_log(LOG_WARNING, "No Zap channel available for conference, conference recording disabled (is chan_zap loaded?)\n");
- ast_clear_flag(confflags, CONFFLAG_RECORDCONF);
- }
- }
-
- return cnf;
-}
-
-
-static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, int make, int dynamic,
- char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags *confflags)
-{
- struct ast_config *cfg;
- struct ast_variable *var;
- struct ast_conference *cnf;
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(confno);
- AST_APP_ARG(pin);
- AST_APP_ARG(pinadmin);
- );
-
- /* Check first in the conference list */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strcmp(confno, cnf->confno))
- break;
- }
- if (cnf){
- cnf->refcount += refcount;
- }
- AST_LIST_UNLOCK(&confs);
-
- if (!cnf) {
- if (dynamic) {
- /* No need to parse meetme.conf */
- ast_log(LOG_DEBUG, "Building dynamic conference '%s'\n", confno);
- if (dynamic_pin) {
- if (dynamic_pin[0] == 'q') {
- /* Query the user to enter a PIN */
- if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, pin_buf_len - 1, 0) < 0)
- return NULL;
- }
- cnf = build_conf(confno, dynamic_pin, "", make, dynamic, refcount);
- } else {
- cnf = build_conf(confno, "", "", make, dynamic, refcount);
- }
- } else {
- /* Check the config */
- cfg = ast_config_load(CONFIG_FILE_NAME);
- if (!cfg) {
- ast_log(LOG_WARNING, "No %s file :(\n", CONFIG_FILE_NAME);
- return NULL;
- }
- for (var = ast_variable_browse(cfg, "rooms"); var; var = var->next) {
- if (strcasecmp(var->name, "conf"))
- continue;
-
- if (!(parse = ast_strdupa(var->value)))
- return NULL;
-
- AST_NONSTANDARD_APP_ARGS(args, parse, ',');
- if (!strcasecmp(args.confno, confno)) {
- /* Bingo it's a valid conference */
- cnf = build_conf(args.confno,
- S_OR(args.pin, ""),
- S_OR(args.pinadmin, ""),
- make, dynamic, refcount);
- break;
- }
- }
- if (!var) {
- ast_log(LOG_DEBUG, "%s isn't a valid conference\n", confno);
- }
- ast_config_destroy(cfg);
- }
- } else if (dynamic_pin) {
- /* Correct for the user selecting 'D' instead of 'd' to have
- someone join into a conference that has already been created
- with a pin. */
- if (dynamic_pin[0] == 'q')
- dynamic_pin[0] = '\0';
- }
-
- if (cnf) {
- if (confflags && !cnf->chan &&
- !ast_test_flag(confflags, CONFFLAG_QUIET) &&
- ast_test_flag(confflags, CONFFLAG_INTROUSER)) {
- ast_log(LOG_WARNING, "No Zap channel available for conference, user introduction disabled (is chan_zap loaded?)\n");
- ast_clear_flag(confflags, CONFFLAG_INTROUSER);
- }
-
- if (confflags && !cnf->chan &&
- ast_test_flag(confflags, CONFFLAG_RECORDCONF)) {
- ast_log(LOG_WARNING, "No Zap channel available for conference, conference recording disabled (is chan_zap loaded?)\n");
- ast_clear_flag(confflags, CONFFLAG_RECORDCONF);
- }
- }
-
- return cnf;
-}
-
-/*! \brief The MeetmeCount application */
-static int count_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- int res = 0;
- struct ast_conference *conf;
- int count;
- char *localdata;
- char val[80] = "0";
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(confno);
- AST_APP_ARG(varname);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "MeetMeCount requires an argument (conference number)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (!(localdata = ast_strdupa(data))) {
- ast_module_user_remove(u);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, localdata);
-
- conf = find_conf(chan, args.confno, 0, 0, NULL, 0, 1, NULL);
-
- if (conf) {
- count = conf->users;
- dispose_conf(conf);
- conf = NULL;
- } else
- count = 0;
-
- if (!ast_strlen_zero(args.varname)){
- /* have var so load it and exit */
- snprintf(val, sizeof(val), "%d",count);
- pbx_builtin_setvar_helper(chan, args.varname, val);
- } else {
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
- res = ast_say_number(chan, count, "", chan->language, (char *) NULL); /* Needs gender */
- }
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief The meetme() application */
-static int conf_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- struct ast_module_user *u;
- char confno[MAX_CONFNUM] = "";
- int allowretry = 0;
- int retrycnt = 0;
- struct ast_conference *cnf = NULL;
- struct ast_flags confflags = {0};
- int dynamic = 0;
- int empty = 0, empty_no_pin = 0;
- int always_prompt = 0;
- char *notdata, *info, the_pin[MAX_PIN] = "";
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(confno);
- AST_APP_ARG(options);
- AST_APP_ARG(pin);
- );
- char *optargs[OPT_ARG_ARRAY_SIZE] = { NULL, };
-
- u = ast_module_user_add(chan);
-
- if (ast_strlen_zero(data)) {
- allowretry = 1;
- notdata = "";
- } else {
- notdata = data;
- }
-
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- info = ast_strdupa(notdata);
-
- AST_STANDARD_APP_ARGS(args, info);
-
- if (args.confno) {
- ast_copy_string(confno, args.confno, sizeof(confno));
- if (ast_strlen_zero(confno)) {
- allowretry = 1;
- }
- }
-
- if (args.pin)
- ast_copy_string(the_pin, args.pin, sizeof(the_pin));
-
- if (args.options) {
- ast_app_parse_options(meetme_opts, &confflags, optargs, args.options);
- dynamic = ast_test_flag(&confflags, CONFFLAG_DYNAMIC | CONFFLAG_DYNAMICPIN);
- if (ast_test_flag(&confflags, CONFFLAG_DYNAMICPIN) && !args.pin)
- strcpy(the_pin, "q");
-
- empty = ast_test_flag(&confflags, CONFFLAG_EMPTY | CONFFLAG_EMPTYNOPIN);
- empty_no_pin = ast_test_flag(&confflags, CONFFLAG_EMPTYNOPIN);
- always_prompt = ast_test_flag(&confflags, CONFFLAG_ALWAYSPROMPT);
- }
-
- do {
- if (retrycnt > 3)
- allowretry = 0;
- if (empty) {
- int i;
- struct ast_config *cfg;
- struct ast_variable *var;
- int confno_int;
-
- /* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */
- if ((empty_no_pin) || (!dynamic)) {
- cfg = ast_config_load(CONFIG_FILE_NAME);
- if (cfg) {
- var = ast_variable_browse(cfg, "rooms");
- while (var) {
- if (!strcasecmp(var->name, "conf")) {
- char *stringp = ast_strdupa(var->value);
- if (stringp) {
- char *confno_tmp = strsep(&stringp, "|,");
- int found = 0;
- if (!dynamic) {
- /* For static: run through the list and see if this conference is empty */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strcmp(confno_tmp, cnf->confno)) {
- /* The conference exists, therefore it's not empty */
- found = 1;
- break;
- }
- }
- AST_LIST_UNLOCK(&confs);
- if (!found) {
- /* At this point, we have a confno_tmp (static conference) that is empty */
- if ((empty_no_pin && ast_strlen_zero(stringp)) || (!empty_no_pin)) {
- /* Case 1: empty_no_pin and pin is nonexistent (NULL)
- * Case 2: empty_no_pin and pin is blank (but not NULL)
- * Case 3: not empty_no_pin
- */
- ast_copy_string(confno, confno_tmp, sizeof(confno));
- break;
- /* XXX the map is not complete (but we do have a confno) */
- }
- }
- }
- }
- }
- var = var->next;
- }
- ast_config_destroy(cfg);
- }
- }
-
- /* Select first conference number not in use */
- if (ast_strlen_zero(confno) && dynamic) {
- AST_LIST_LOCK(&confs);
- for (i = 0; i < sizeof(conf_map) / sizeof(conf_map[0]); i++) {
- if (!conf_map[i]) {
- snprintf(confno, sizeof(confno), "%d", i);
- conf_map[i] = 1;
- break;
- }
- }
- AST_LIST_UNLOCK(&confs);
- }
-
- /* Not found? */
- if (ast_strlen_zero(confno)) {
- res = ast_streamfile(chan, "conf-noempty", chan->language);
- if (!res)
- ast_waitstream(chan, "");
- } else {
- if (sscanf(confno, "%d", &confno_int) == 1) {
- res = ast_streamfile(chan, "conf-enteringno", chan->language);
- if (!res) {
- ast_waitstream(chan, "");
- res = ast_say_digits(chan, confno_int, "", chan->language);
- }
- } else {
- ast_log(LOG_ERROR, "Could not scan confno '%s'\n", confno);
- }
- }
- }
-
- while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) {
- /* Prompt user for conference number */
- res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0);
- if (res < 0) {
- /* Don't try to validate when we catch an error */
- confno[0] = '\0';
- allowretry = 0;
- break;
- }
- }
- if (!ast_strlen_zero(confno)) {
- /* Check the validity of the conference */
- cnf = find_conf(chan, confno, 1, dynamic, the_pin,
- sizeof(the_pin), 1, &confflags);
- if (!cnf) {
- cnf = find_conf_realtime(chan, confno, 1, dynamic,
- the_pin, sizeof(the_pin), 1, &confflags);
- }
-
- if (!cnf) {
- res = ast_streamfile(chan, "conf-invalid", chan->language);
- if (!res)
- ast_waitstream(chan, "");
- res = -1;
- if (allowretry)
- confno[0] = '\0';
- } else {
- if ((!ast_strlen_zero(cnf->pin) &&
- !ast_test_flag(&confflags, CONFFLAG_ADMIN)) ||
- (!ast_strlen_zero(cnf->pinadmin) &&
- ast_test_flag(&confflags, CONFFLAG_ADMIN))) {
- char pin[MAX_PIN] = "";
- int j;
-
- /* Allow the pin to be retried up to 3 times */
- for (j = 0; j < 3; j++) {
- if (*the_pin && (always_prompt == 0)) {
- ast_copy_string(pin, the_pin, sizeof(pin));
- res = 0;
- } else {
- /* Prompt user for pin if pin is required */
- res = ast_app_getdata(chan, "conf-getpin", pin + strlen(pin), sizeof(pin) - 1 - strlen(pin), 0);
- }
- if (res >= 0) {
- if (!strcasecmp(pin, cnf->pin) ||
- (!ast_strlen_zero(cnf->pinadmin) &&
- !strcasecmp(pin, cnf->pinadmin))) {
- /* Pin correct */
- allowretry = 0;
- if (!ast_strlen_zero(cnf->pinadmin) && !strcasecmp(pin, cnf->pinadmin))
- ast_set_flag(&confflags, CONFFLAG_ADMIN);
- /* Run the conference */
- res = conf_run(chan, cnf, confflags.flags, optargs);
- break;
- } else {
- /* Pin invalid */
- if (!ast_streamfile(chan, "conf-invalidpin", chan->language)) {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- }
- else {
- ast_log(LOG_WARNING, "Couldn't play invalid pin msg!\n");
- break;
- }
- if (res < 0)
- break;
- pin[0] = res;
- pin[1] = '\0';
- res = -1;
- if (allowretry)
- confno[0] = '\0';
- }
- } else {
- /* failed when getting the pin */
- res = -1;
- allowretry = 0;
- /* see if we need to get rid of the conference */
- break;
- }
-
- /* Don't retry pin with a static pin */
- if (*the_pin && (always_prompt==0)) {
- break;
- }
- }
- } else {
- /* No pin required */
- allowretry = 0;
-
- /* Run the conference */
- res = conf_run(chan, cnf, confflags.flags, optargs);
- }
- dispose_conf(cnf);
- cnf = NULL;
- }
- }
- } while (allowretry);
-
- if (cnf)
- dispose_conf(cnf);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static struct ast_conf_user *find_user(struct ast_conference *conf, char *callerident)
-{
- struct ast_conf_user *user = NULL;
- int cid;
-
- sscanf(callerident, "%i", &cid);
- if (conf && callerident) {
- AST_LIST_TRAVERSE(&conf->userlist, user, list) {
- if (cid == user->user_no)
- return user;
- }
- }
- return NULL;
-}
-
-/*! \brief The MeetMeadmin application */
-/* MeetMeAdmin(confno, command, caller) */
-static int admin_exec(struct ast_channel *chan, void *data) {
- char *params;
- struct ast_conference *cnf;
- struct ast_conf_user *user = NULL;
- struct ast_module_user *u;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(confno);
- AST_APP_ARG(command);
- AST_APP_ARG(user);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "MeetMeAdmin requires an argument!\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- AST_LIST_LOCK(&confs);
-
- params = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, params);
-
- if (!args.command) {
- ast_log(LOG_WARNING, "MeetmeAdmin requires a command!\n");
- AST_LIST_UNLOCK(&confs);
- ast_module_user_remove(u);
- return -1;
- }
- AST_LIST_TRAVERSE(&confs, cnf, list) {
- if (!strcmp(cnf->confno, args.confno))
- break;
- }
-
- if (!cnf) {
- ast_log(LOG_WARNING, "Conference number '%s' not found!\n", args.confno);
- AST_LIST_UNLOCK(&confs);
- ast_module_user_remove(u);
- return 0;
- }
-
- ast_atomic_fetchadd_int(&cnf->refcount, 1);
-
- if (args.user)
- user = find_user(cnf, args.user);
-
- switch (*args.command) {
- case 76: /* L: Lock */
- cnf->locked = 1;
- break;
- case 108: /* l: Unlock */
- cnf->locked = 0;
- break;
- case 75: /* K: kick all users */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- user->adminflags |= ADMINFLAG_KICKME;
- break;
- case 101: /* e: Eject last user*/
- user = AST_LIST_LAST(&cnf->userlist);
- if (!(user->userflags & CONFFLAG_ADMIN))
- user->adminflags |= ADMINFLAG_KICKME;
- else
- ast_log(LOG_NOTICE, "Not kicking last user, is an Admin!\n");
- break;
- case 77: /* M: Mute */
- if (user) {
- user->adminflags |= ADMINFLAG_MUTED;
- } else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 78: /* N: Mute all (non-admin) users */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list) {
- if (!(user->userflags & CONFFLAG_ADMIN))
- user->adminflags |= ADMINFLAG_MUTED;
- }
- break;
- case 109: /* m: Unmute */
- if (user) {
- user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
- } else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 110: /* n: Unmute all users */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
- break;
- case 107: /* k: Kick user */
- if (user)
- user->adminflags |= ADMINFLAG_KICKME;
- else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 118: /* v: Lower all users listen volume */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- tweak_listen_volume(user, VOL_DOWN);
- break;
- case 86: /* V: Raise all users listen volume */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- tweak_listen_volume(user, VOL_UP);
- break;
- case 115: /* s: Lower all users speaking volume */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- tweak_talk_volume(user, VOL_DOWN);
- break;
- case 83: /* S: Raise all users speaking volume */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- tweak_talk_volume(user, VOL_UP);
- break;
- case 82: /* R: Reset all volume levels */
- AST_LIST_TRAVERSE(&cnf->userlist, user, list)
- reset_volumes(user);
- break;
- case 114: /* r: Reset user's volume level */
- if (user)
- reset_volumes(user);
- else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 85: /* U: Raise user's listen volume */
- if (user)
- tweak_listen_volume(user, VOL_UP);
- else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 117: /* u: Lower user's listen volume */
- if (user)
- tweak_listen_volume(user, VOL_DOWN);
- else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 84: /* T: Raise user's talk volume */
- if (user)
- tweak_talk_volume(user, VOL_UP);
- else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- case 116: /* t: Lower user's talk volume */
- if (user)
- tweak_talk_volume(user, VOL_DOWN);
- else
- ast_log(LOG_NOTICE, "Specified User not found!\n");
- break;
- }
-
- AST_LIST_UNLOCK(&confs);
-
- dispose_conf(cnf);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int meetmemute(struct mansession *s, const struct message *m, int mute)
-{
- struct ast_conference *conf;
- struct ast_conf_user *user;
- const char *confid = astman_get_header(m, "Meetme");
- char *userid = ast_strdupa(astman_get_header(m, "Usernum"));
- int userno;
-
- if (ast_strlen_zero(confid)) {
- astman_send_error(s, m, "Meetme conference not specified");
- return 0;
- }
-
- if (ast_strlen_zero(userid)) {
- astman_send_error(s, m, "Meetme user number not specified");
- return 0;
- }
-
- userno = strtoul(userid, &userid, 10);
-
- if (*userid) {
- astman_send_error(s, m, "Invalid user number");
- return 0;
- }
-
- /* Look in the conference list */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, conf, list) {
- if (!strcmp(confid, conf->confno))
- break;
- }
-
- if (!conf) {
- AST_LIST_UNLOCK(&confs);
- astman_send_error(s, m, "Meetme conference does not exist");
- return 0;
- }
-
- AST_LIST_TRAVERSE(&conf->userlist, user, list)
- if (user->user_no == userno)
- break;
-
- if (!user) {
- AST_LIST_UNLOCK(&confs);
- astman_send_error(s, m, "User number not found");
- return 0;
- }
-
- if (mute)
- user->adminflags |= ADMINFLAG_MUTED; /* request user muting */
- else
- user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED); /* request user unmuting */
-
- AST_LIST_UNLOCK(&confs);
-
- ast_log(LOG_NOTICE, "Requested to %smute conf %s user %d userchan %s uniqueid %s\n", mute ? "" : "un", conf->confno, user->user_no, user->chan->name, user->chan->uniqueid);
-
- astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
- return 0;
-}
-
-static int action_meetmemute(struct mansession *s, const struct message *m)
-{
- return meetmemute(s, m, 1);
-}
-
-static int action_meetmeunmute(struct mansession *s, const struct message *m)
-{
- return meetmemute(s, m, 0);
-}
-
-static void *recordthread(void *args)
-{
- struct ast_conference *cnf = args;
- struct ast_frame *f=NULL;
- int flags;
- struct ast_filestream *s=NULL;
- int res=0;
- int x;
- const char *oldrecordingfilename = NULL;
-
- if (!cnf || !cnf->lchan) {
- pthread_exit(0);
- }
-
- ast_stopstream(cnf->lchan);
- flags = O_CREAT|O_TRUNC|O_WRONLY;
-
-
- cnf->recording = MEETME_RECORD_ACTIVE;
- while (ast_waitfor(cnf->lchan, -1) > -1) {
- if (cnf->recording == MEETME_RECORD_TERMINATE) {
- AST_LIST_LOCK(&confs);
- AST_LIST_UNLOCK(&confs);
- break;
- }
- if (!s && cnf->recordingfilename && (cnf->recordingfilename != oldrecordingfilename)) {
- s = ast_writefile(cnf->recordingfilename, cnf->recordingformat, NULL, flags, 0, 0644);
- oldrecordingfilename = cnf->recordingfilename;
- }
-
- f = ast_read(cnf->lchan);
- if (!f) {
- res = -1;
- break;
- }
- if (f->frametype == AST_FRAME_VOICE) {
- ast_mutex_lock(&cnf->listenlock);
- for (x=0;x<AST_FRAME_BITS;x++) {
- /* Free any translations that have occured */
- if (cnf->transframe[x]) {
- ast_frfree(cnf->transframe[x]);
- cnf->transframe[x] = NULL;
- }
- }
- if (cnf->origframe)
- ast_frfree(cnf->origframe);
- cnf->origframe = ast_frdup(f);
- ast_mutex_unlock(&cnf->listenlock);
- if (s)
- res = ast_writestream(s, f);
- if (res) {
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- }
- cnf->recording = MEETME_RECORD_OFF;
- if (s)
- ast_closestream(s);
-
- pthread_exit(0);
-}
-
-/*! \brief Callback for devicestate providers */
-static int meetmestate(const char *data)
-{
- struct ast_conference *conf;
-
- /* Find conference */
- AST_LIST_LOCK(&confs);
- AST_LIST_TRAVERSE(&confs, conf, list) {
- if (!strcmp(data, conf->confno))
- break;
- }
- AST_LIST_UNLOCK(&confs);
- if (!conf)
- return AST_DEVICE_INVALID;
-
-
- /* SKREP to fill */
- if (!conf->users)
- return AST_DEVICE_NOT_INUSE;
-
- return AST_DEVICE_INUSE;
-}
-
-static void load_config_meetme(void)
-{
- struct ast_config *cfg;
- const char *val;
-
- audio_buffers = DEFAULT_AUDIO_BUFFERS;
-
- if (!(cfg = ast_config_load(CONFIG_FILE_NAME)))
- return;
-
- if ((val = ast_variable_retrieve(cfg, "general", "audiobuffers"))) {
- if ((sscanf(val, "%d", &audio_buffers) != 1)) {
- ast_log(LOG_WARNING, "audiobuffers setting must be a number, not '%s'\n", val);
- audio_buffers = DEFAULT_AUDIO_BUFFERS;
- } else if ((audio_buffers < ZT_DEFAULT_NUM_BUFS) || (audio_buffers > ZT_MAX_NUM_BUFS)) {
- ast_log(LOG_WARNING, "audiobuffers setting must be between %d and %d\n",
- ZT_DEFAULT_NUM_BUFS, ZT_MAX_NUM_BUFS);
- audio_buffers = DEFAULT_AUDIO_BUFFERS;
- }
- if (audio_buffers != DEFAULT_AUDIO_BUFFERS)
- ast_log(LOG_NOTICE, "Audio buffers per channel set to %d\n", audio_buffers);
- }
-
- ast_config_destroy(cfg);
-}
-
-/*! \brief Find an SLA trunk by name
- * \note This must be called with the sla_trunks container locked
- */
-static struct sla_trunk *sla_find_trunk(const char *name)
-{
- struct sla_trunk *trunk = NULL;
-
- AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
- if (!strcasecmp(trunk->name, name))
- break;
- }
-
- return trunk;
-}
-
-/*! \brief Find an SLA station by name
- * \note This must be called with the sla_stations container locked
- */
-static struct sla_station *sla_find_station(const char *name)
-{
- struct sla_station *station = NULL;
-
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
- if (!strcasecmp(station->name, name))
- break;
- }
-
- return station;
-}
-
-static int sla_check_station_hold_access(const struct sla_trunk *trunk,
- const struct sla_station *station)
-{
- struct sla_station_ref *station_ref;
- struct sla_trunk_ref *trunk_ref;
-
- /* For each station that has this call on hold, check for private hold. */
- AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
- AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
- if (trunk_ref->trunk != trunk || station_ref->station == station)
- continue;
- if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME &&
- station_ref->station->hold_access == SLA_HOLD_PRIVATE)
- return 1;
- return 0;
- }
- }
-
- return 0;
-}
-
-/*! \brief Find a trunk reference on a station by name
- * \param station the station
- * \param name the trunk's name
- * \return a pointer to the station's trunk reference. If the trunk
- * is not found, it is not idle and barge is disabled, or if
- * it is on hold and private hold is set, then NULL will be returned.
- */
-static struct sla_trunk_ref *sla_find_trunk_ref_byname(const struct sla_station *station,
- const char *name)
-{
- struct sla_trunk_ref *trunk_ref = NULL;
-
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (strcasecmp(trunk_ref->trunk->name, name))
- continue;
-
- if ( (trunk_ref->trunk->barge_disabled
- && trunk_ref->state == SLA_TRUNK_STATE_UP) ||
- (trunk_ref->trunk->hold_stations
- && trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE
- && trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) ||
- sla_check_station_hold_access(trunk_ref->trunk, station) )
- {
- trunk_ref = NULL;
- }
-
- break;
- }
-
- return trunk_ref;
-}
-
-static struct sla_station_ref *sla_create_station_ref(struct sla_station *station)
-{
- struct sla_station_ref *station_ref;
-
- if (!(station_ref = ast_calloc(1, sizeof(*station_ref))))
- return NULL;
-
- station_ref->station = station;
-
- return station_ref;
-}
-
-static struct sla_ringing_station *sla_create_ringing_station(struct sla_station *station)
-{
- struct sla_ringing_station *ringing_station;
-
- if (!(ringing_station = ast_calloc(1, sizeof(*ringing_station))))
- return NULL;
-
- ringing_station->station = station;
- ringing_station->ring_begin = ast_tvnow();
-
- return ringing_station;
-}
-
-static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state,
- enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
-{
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref;
-
- AST_LIST_TRAVERSE(&sla_stations, station, entry) {
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0)
- || trunk_ref == exclude)
- continue;
- trunk_ref->state = state;
- ast_device_state_changed("SLA:%s_%s", station->name, trunk->name);
- break;
- }
- }
-}
-
-struct run_station_args {
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref;
- ast_mutex_t *cond_lock;
- ast_cond_t *cond;
-};
-
-static void *run_station(void *data)
-{
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref;
- char conf_name[MAX_CONFNUM];
- struct ast_flags conf_flags = { 0 };
- struct ast_conference *conf;
-
- {
- struct run_station_args *args = data;
- station = args->station;
- trunk_ref = args->trunk_ref;
- ast_mutex_lock(args->cond_lock);
- ast_cond_signal(args->cond);
- ast_mutex_unlock(args->cond_lock);
- /* args is no longer valid here. */
- }
-
- ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1);
- snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
- ast_set_flag(&conf_flags,
- CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
- ast_answer(trunk_ref->chan);
- conf = build_conf(conf_name, "", "", 0, 0, 1);
- if (conf) {
- conf_run(trunk_ref->chan, conf, conf_flags.flags, NULL);
- dispose_conf(conf);
- conf = NULL;
- }
- trunk_ref->chan = NULL;
- if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
- trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
- strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
- admin_exec(NULL, conf_name);
- trunk_ref->trunk->hold_stations = 0;
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
- }
-
- ast_dial_join(station->dial);
- ast_dial_destroy(station->dial);
- station->dial = NULL;
-
- return NULL;
-}
-
-static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
-{
- char buf[80];
- struct sla_station_ref *station_ref;
-
- snprintf(buf, sizeof(buf), "SLA_%s|K", ringing_trunk->trunk->name);
- admin_exec(NULL, buf);
- sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
-
- while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry)))
- free(station_ref);
-
- free(ringing_trunk);
-}
-
-static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station,
- enum sla_station_hangup hangup)
-{
- struct sla_ringing_trunk *ringing_trunk;
- struct sla_trunk_ref *trunk_ref;
- struct sla_station_ref *station_ref;
-
- ast_dial_join(ringing_station->station->dial);
- ast_dial_destroy(ringing_station->station->dial);
- ringing_station->station->dial = NULL;
-
- if (hangup == SLA_STATION_HANGUP_NORMAL)
- goto done;
-
- /* If the station is being hung up because of a timeout, then add it to the
- * list of timed out stations on each of the ringing trunks. This is so
- * that when doing further processing to figure out which stations should be
- * ringing, which trunk to answer, determining timeouts, etc., we know which
- * ringing trunks we should ignore. */
- AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
- AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
- if (ringing_trunk->trunk == trunk_ref->trunk)
- break;
- }
- if (!trunk_ref)
- continue;
- if (!(station_ref = sla_create_station_ref(ringing_station->station)))
- continue;
- AST_LIST_INSERT_TAIL(&ringing_trunk->timed_out_stations, station_ref, entry);
- }
-
-done:
- free(ringing_station);
-}
-
-static void sla_dial_state_callback(struct ast_dial *dial)
-{
- sla_queue_event(SLA_EVENT_DIAL_STATE);
-}
-
-/*! \brief Check to see if dialing this station already timed out for this ringing trunk
- * \note Assumes sla.lock is locked
- */
-static int sla_check_timed_out_station(const struct sla_ringing_trunk *ringing_trunk,
- const struct sla_station *station)
-{
- struct sla_station_ref *timed_out_station;
-
- AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, timed_out_station, entry) {
- if (station == timed_out_station->station)
- return 1;
- }
-
- return 0;
-}
-
-/*! \brief Choose the highest priority ringing trunk for a station
- * \param station the station
- * \param remove remove the ringing trunk once selected
- * \param trunk_ref a place to store the pointer to this stations reference to
- * the selected trunk
- * \return a pointer to the selected ringing trunk, or NULL if none found
- * \note Assumes that sla.lock is locked
- */
-static struct sla_ringing_trunk *sla_choose_ringing_trunk(struct sla_station *station,
- struct sla_trunk_ref **trunk_ref, int remove)
-{
- struct sla_trunk_ref *s_trunk_ref;
- struct sla_ringing_trunk *ringing_trunk = NULL;
-
- AST_LIST_TRAVERSE(&station->trunks, s_trunk_ref, entry) {
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
- /* Make sure this is the trunk we're looking for */
- if (s_trunk_ref->trunk != ringing_trunk->trunk)
- continue;
-
- /* This trunk on the station is ringing. But, make sure this station
- * didn't already time out while this trunk was ringing. */
- if (sla_check_timed_out_station(ringing_trunk, station))
- continue;
-
- if (remove)
- AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
-
- if (trunk_ref)
- *trunk_ref = s_trunk_ref;
-
- break;
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- if (ringing_trunk)
- break;
- }
-
- return ringing_trunk;
-}
-
-static void sla_handle_dial_state_event(void)
-{
- struct sla_ringing_station *ringing_station;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
- struct sla_trunk_ref *s_trunk_ref = NULL;
- struct sla_ringing_trunk *ringing_trunk = NULL;
- struct run_station_args args;
- enum ast_dial_result dial_res;
- pthread_attr_t attr;
- pthread_t dont_care;
- ast_mutex_t cond_lock;
- ast_cond_t cond;
-
- switch ((dial_res = ast_dial_state(ringing_station->station->dial))) {
- case AST_DIAL_RESULT_HANGUP:
- case AST_DIAL_RESULT_INVALID:
- case AST_DIAL_RESULT_FAILED:
- case AST_DIAL_RESULT_TIMEOUT:
- case AST_DIAL_RESULT_UNANSWERED:
- AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
- sla_stop_ringing_station(ringing_station, SLA_STATION_HANGUP_NORMAL);
- break;
- case AST_DIAL_RESULT_ANSWERED:
- AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
- /* Find the appropriate trunk to answer. */
- ast_mutex_lock(&sla.lock);
- ringing_trunk = sla_choose_ringing_trunk(ringing_station->station, &s_trunk_ref, 1);
- ast_mutex_unlock(&sla.lock);
- if (!ringing_trunk) {
- ast_log(LOG_DEBUG, "Found no ringing trunk for station '%s' to answer!\n",
- ringing_station->station->name);
- break;
- }
- /* Track the channel that answered this trunk */
- s_trunk_ref->chan = ast_dial_answered(ringing_station->station->dial);
- /* Actually answer the trunk */
- ast_answer(ringing_trunk->trunk->chan);
- sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
- /* Now, start a thread that will connect this station to the trunk. The rest of
- * the code here sets up the thread and ensures that it is able to save the arguments
- * before they are no longer valid since they are allocated on the stack. */
- args.trunk_ref = s_trunk_ref;
- args.station = ringing_station->station;
- args.cond = &cond;
- args.cond_lock = &cond_lock;
- free(ringing_trunk);
- free(ringing_station);
- ast_mutex_init(&cond_lock);
- ast_cond_init(&cond, NULL);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_mutex_lock(&cond_lock);
- ast_pthread_create_background(&dont_care, &attr, run_station, &args);
- ast_cond_wait(&cond, &cond_lock);
- ast_mutex_unlock(&cond_lock);
- ast_mutex_destroy(&cond_lock);
- ast_cond_destroy(&cond);
- pthread_attr_destroy(&attr);
- break;
- case AST_DIAL_RESULT_TRYING:
- case AST_DIAL_RESULT_RINGING:
- case AST_DIAL_RESULT_PROGRESS:
- case AST_DIAL_RESULT_PROCEEDING:
- break;
- }
- if (dial_res == AST_DIAL_RESULT_ANSWERED) {
- /* Queue up reprocessing ringing trunks, and then ringing stations again */
- sla_queue_event(SLA_EVENT_RINGING_TRUNK);
- sla_queue_event(SLA_EVENT_DIAL_STATE);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-}
-
-/*! \brief Check to see if this station is already ringing
- * \note Assumes sla.lock is locked
- */
-static int sla_check_ringing_station(const struct sla_station *station)
-{
- struct sla_ringing_station *ringing_station;
-
- AST_LIST_TRAVERSE(&sla.ringing_stations, ringing_station, entry) {
- if (station == ringing_station->station)
- return 1;
- }
-
- return 0;
-}
-
-/*! \brief Check to see if this station has failed to be dialed in the past minute
- * \note assumes sla.lock is locked
- */
-static int sla_check_failed_station(const struct sla_station *station)
-{
- struct sla_failed_station *failed_station;
- int res = 0;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.failed_stations, failed_station, entry) {
- if (station != failed_station->station)
- continue;
- if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
- AST_LIST_REMOVE_CURRENT(&sla.failed_stations, entry);
- free(failed_station);
- break;
- }
- res = 1;
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- return res;
-}
-
-/*! \brief Ring a station
- * \note Assumes sla.lock is locked
- */
-static int sla_ring_station(struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
-{
- char *tech, *tech_data;
- struct ast_dial *dial;
- struct sla_ringing_station *ringing_station;
- const char *cid_name = NULL, *cid_num = NULL;
- enum ast_dial_result res;
-
- if (!(dial = ast_dial_create()))
- return -1;
-
- ast_dial_set_state_callback(dial, sla_dial_state_callback);
- tech_data = ast_strdupa(station->device);
- tech = strsep(&tech_data, "/");
-
- if (ast_dial_append(dial, tech, tech_data) == -1) {
- ast_dial_destroy(dial);
- return -1;
- }
-
- if (!sla.attempt_callerid && !ast_strlen_zero(ringing_trunk->trunk->chan->cid.cid_name)) {
- cid_name = ast_strdupa(ringing_trunk->trunk->chan->cid.cid_name);
- free(ringing_trunk->trunk->chan->cid.cid_name);
- ringing_trunk->trunk->chan->cid.cid_name = NULL;
- }
- if (!sla.attempt_callerid && !ast_strlen_zero(ringing_trunk->trunk->chan->cid.cid_num)) {
- cid_num = ast_strdupa(ringing_trunk->trunk->chan->cid.cid_num);
- free(ringing_trunk->trunk->chan->cid.cid_num);
- ringing_trunk->trunk->chan->cid.cid_num = NULL;
- }
-
- res = ast_dial_run(dial, ringing_trunk->trunk->chan, 1);
-
- if (cid_name)
- ringing_trunk->trunk->chan->cid.cid_name = ast_strdup(cid_name);
- if (cid_num)
- ringing_trunk->trunk->chan->cid.cid_num = ast_strdup(cid_num);
-
- if (res != AST_DIAL_RESULT_TRYING) {
- struct sla_failed_station *failed_station;
- ast_dial_destroy(dial);
- if (!(failed_station = ast_calloc(1, sizeof(*failed_station))))
- return -1;
- failed_station->station = station;
- failed_station->last_try = ast_tvnow();
- AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
- return -1;
- }
- if (!(ringing_station = sla_create_ringing_station(station))) {
- ast_dial_join(dial);
- ast_dial_destroy(dial);
- return -1;
- }
-
- station->dial = dial;
-
- AST_LIST_INSERT_HEAD(&sla.ringing_stations, ringing_station, entry);
-
- return 0;
-}
-
-/*! \brief Check to see if a station is in use
- */
-static int sla_check_inuse_station(const struct sla_station *station)
-{
- struct sla_trunk_ref *trunk_ref;
-
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->chan)
- return 1;
- }
-
- return 0;
-}
-
-static struct sla_trunk_ref *sla_find_trunk_ref(const struct sla_station *station,
- const struct sla_trunk *trunk)
-{
- struct sla_trunk_ref *trunk_ref = NULL;
-
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->trunk == trunk)
- break;
- }
-
- return trunk_ref;
-}
-
-/*! \brief Calculate the ring delay for a given ringing trunk on a station
- * \param station the station
- * \param trunk the trunk. If NULL, the highest priority ringing trunk will be used
- * \return the number of ms left before the delay is complete, or INT_MAX if there is no delay
- */
-static int sla_check_station_delay(struct sla_station *station,
- struct sla_ringing_trunk *ringing_trunk)
-{
- struct sla_trunk_ref *trunk_ref;
- unsigned int delay = UINT_MAX;
- int time_left, time_elapsed;
-
- if (!ringing_trunk)
- ringing_trunk = sla_choose_ringing_trunk(station, &trunk_ref, 0);
- else
- trunk_ref = sla_find_trunk_ref(station, ringing_trunk->trunk);
-
- if (!ringing_trunk || !trunk_ref)
- return delay;
-
- /* If this station has a ring delay specific to the highest priority
- * ringing trunk, use that. Otherwise, use the ring delay specified
- * globally for the station. */
- delay = trunk_ref->ring_delay;
- if (!delay)
- delay = station->ring_delay;
- if (!delay)
- return INT_MAX;
-
- time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
- time_left = (delay * 1000) - time_elapsed;
-
- return time_left;
-}
-
-/*! \brief Ring stations based on current set of ringing trunks
- * \note Assumes that sla.lock is locked
- */
-static void sla_ring_stations(void)
-{
- struct sla_station_ref *station_ref;
- struct sla_ringing_trunk *ringing_trunk;
-
- /* Make sure that every station that uses at least one of the ringing
- * trunks, is ringing. */
- AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
- AST_LIST_TRAVERSE(&ringing_trunk->trunk->stations, station_ref, entry) {
- int time_left;
-
- /* Is this station already ringing? */
- if (sla_check_ringing_station(station_ref->station))
- continue;
-
- /* Is this station already in a call? */
- if (sla_check_inuse_station(station_ref->station))
- continue;
-
- /* Did we fail to dial this station earlier? If so, has it been
- * a minute since we tried? */
- if (sla_check_failed_station(station_ref->station))
- continue;
-
- /* If this station already timed out while this trunk was ringing,
- * do not dial it again for this ringing trunk. */
- if (sla_check_timed_out_station(ringing_trunk, station_ref->station))
- continue;
-
- /* Check for a ring delay in progress */
- time_left = sla_check_station_delay(station_ref->station, ringing_trunk);
- if (time_left != INT_MAX && time_left > 0)
- continue;
-
- /* It is time to make this station begin to ring. Do it! */
- sla_ring_station(ringing_trunk, station_ref->station);
- }
- }
- /* Now, all of the stations that should be ringing, are ringing. */
-}
-
-static void sla_hangup_stations(void)
-{
- struct sla_trunk_ref *trunk_ref;
- struct sla_ringing_station *ringing_station;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
- AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
- struct sla_ringing_trunk *ringing_trunk;
- ast_mutex_lock(&sla.lock);
- AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
- if (trunk_ref->trunk == ringing_trunk->trunk)
- break;
- }
- ast_mutex_unlock(&sla.lock);
- if (ringing_trunk)
- break;
- }
- if (!trunk_ref) {
- AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
- ast_dial_join(ringing_station->station->dial);
- ast_dial_destroy(ringing_station->station->dial);
- ringing_station->station->dial = NULL;
- free(ringing_station);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-}
-
-static void sla_handle_ringing_trunk_event(void)
-{
- ast_mutex_lock(&sla.lock);
- sla_ring_stations();
- ast_mutex_unlock(&sla.lock);
-
- /* Find stations that shouldn't be ringing anymore. */
- sla_hangup_stations();
-}
-
-static void sla_handle_hold_event(struct sla_event *event)
-{
- ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
- event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
- ast_device_state_changed("SLA:%s_%s",
- event->station->name, event->trunk_ref->trunk->name);
- sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD,
- INACTIVE_TRUNK_REFS, event->trunk_ref);
-
- if (event->trunk_ref->trunk->active_stations == 1) {
- /* The station putting it on hold is the only one on the call, so start
- * Music on hold to the trunk. */
- event->trunk_ref->trunk->on_hold = 1;
- ast_indicate(event->trunk_ref->trunk->chan, AST_CONTROL_HOLD);
- }
-
- ast_softhangup(event->trunk_ref->chan, AST_CAUSE_NORMAL);
- event->trunk_ref->chan = NULL;
-}
-
-/*! \brief Process trunk ring timeouts
- * \note Called with sla.lock locked
- * \return non-zero if a change to the ringing trunks was made
- */
-static int sla_calc_trunk_timeouts(unsigned int *timeout)
-{
- struct sla_ringing_trunk *ringing_trunk;
- int res = 0;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
- int time_left, time_elapsed;
- if (!ringing_trunk->trunk->ring_timeout)
- continue;
- time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
- time_left = (ringing_trunk->trunk->ring_timeout * 1000) - time_elapsed;
- if (time_left <= 0) {
- pbx_builtin_setvar_helper(ringing_trunk->trunk->chan, "SLATRUNK_STATUS", "RINGTIMEOUT");
- AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
- sla_stop_ringing_trunk(ringing_trunk);
- res = 1;
- continue;
- }
- if (time_left < *timeout)
- *timeout = time_left;
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- return res;
-}
-
-/*! \brief Process station ring timeouts
- * \note Called with sla.lock locked
- * \return non-zero if a change to the ringing stations was made
- */
-static int sla_calc_station_timeouts(unsigned int *timeout)
-{
- struct sla_ringing_trunk *ringing_trunk;
- struct sla_ringing_station *ringing_station;
- int res = 0;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
- unsigned int ring_timeout = 0;
- int time_elapsed, time_left = INT_MAX, final_trunk_time_left = INT_MIN;
- struct sla_trunk_ref *trunk_ref;
-
- /* If there are any ring timeouts specified for a specific trunk
- * on the station, then use the highest per-trunk ring timeout.
- * Otherwise, use the ring timeout set for the entire station. */
- AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
- struct sla_station_ref *station_ref;
- int trunk_time_elapsed, trunk_time_left;
-
- AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
- if (ringing_trunk->trunk == trunk_ref->trunk)
- break;
- }
- if (!ringing_trunk)
- continue;
-
- /* If there is a trunk that is ringing without a timeout, then the
- * only timeout that could matter is a global station ring timeout. */
- if (!trunk_ref->ring_timeout)
- break;
-
- /* This trunk on this station is ringing and has a timeout.
- * However, make sure this trunk isn't still ringing from a
- * previous timeout. If so, don't consider it. */
- AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, station_ref, entry) {
- if (station_ref->station == ringing_station->station)
- break;
- }
- if (station_ref)
- continue;
-
- trunk_time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
- trunk_time_left = (trunk_ref->ring_timeout * 1000) - trunk_time_elapsed;
- if (trunk_time_left > final_trunk_time_left)
- final_trunk_time_left = trunk_time_left;
- }
-
- /* No timeout was found for ringing trunks, and no timeout for the entire station */
- if (final_trunk_time_left == INT_MIN && !ringing_station->station->ring_timeout)
- continue;
-
- /* Compute how much time is left for a global station timeout */
- if (ringing_station->station->ring_timeout) {
- ring_timeout = ringing_station->station->ring_timeout;
- time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_station->ring_begin);
- time_left = (ring_timeout * 1000) - time_elapsed;
- }
-
- /* If the time left based on the per-trunk timeouts is smaller than the
- * global station ring timeout, use that. */
- if (final_trunk_time_left > INT_MIN && final_trunk_time_left < time_left)
- time_left = final_trunk_time_left;
-
- /* If there is no time left, the station needs to stop ringing */
- if (time_left <= 0) {
- AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
- sla_stop_ringing_station(ringing_station, SLA_STATION_HANGUP_TIMEOUT);
- res = 1;
- continue;
- }
-
- /* There is still some time left for this station to ring, so save that
- * timeout if it is the first event scheduled to occur */
- if (time_left < *timeout)
- *timeout = time_left;
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- return res;
-}
-
-/*! \brief Calculate the ring delay for a station
- * \note Assumes sla.lock is locked
- */
-static int sla_calc_station_delays(unsigned int *timeout)
-{
- struct sla_station *station;
- int res = 0;
-
- AST_LIST_TRAVERSE(&sla_stations, station, entry) {
- struct sla_ringing_trunk *ringing_trunk;
- int time_left;
-
- /* Ignore stations already ringing */
- if (sla_check_ringing_station(station))
- continue;
-
- /* Ignore stations already on a call */
- if (sla_check_inuse_station(station))
- continue;
-
- /* Ignore stations that don't have one of their trunks ringing */
- if (!(ringing_trunk = sla_choose_ringing_trunk(station, NULL, 0)))
- continue;
-
- if ((time_left = sla_check_station_delay(station, ringing_trunk)) == INT_MAX)
- continue;
-
- /* If there is no time left, then the station needs to start ringing.
- * Return non-zero so that an event will be queued up an event to
- * make that happen. */
- if (time_left <= 0) {
- res = 1;
- continue;
- }
-
- if (time_left < *timeout)
- *timeout = time_left;
- }
-
- return res;
-}
-
-/*! \brief Calculate the time until the next known event
- * \note Called with sla.lock locked */
-static int sla_process_timers(struct timespec *ts)
-{
- unsigned int timeout = UINT_MAX;
- struct timeval tv;
- unsigned int change_made = 0;
-
- /* Check for ring timeouts on ringing trunks */
- if (sla_calc_trunk_timeouts(&timeout))
- change_made = 1;
-
- /* Check for ring timeouts on ringing stations */
- if (sla_calc_station_timeouts(&timeout))
- change_made = 1;
-
- /* Check for station ring delays */
- if (sla_calc_station_delays(&timeout))
- change_made = 1;
-
- /* queue reprocessing of ringing trunks */
- if (change_made)
- sla_queue_event_nolock(SLA_EVENT_RINGING_TRUNK);
-
- /* No timeout */
- if (timeout == UINT_MAX)
- return 0;
-
- if (ts) {
- tv = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1000));
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
- }
-
- return 1;
-}
-
-static void *sla_thread(void *data)
-{
- struct sla_failed_station *failed_station;
- struct sla_ringing_station *ringing_station;
-
- ast_mutex_lock(&sla.lock);
-
- while (!sla.stop) {
- struct sla_event *event;
- struct timespec ts = { 0, };
- unsigned int have_timeout = 0;
-
- if (AST_LIST_EMPTY(&sla.event_q)) {
- if ((have_timeout = sla_process_timers(&ts)))
- ast_cond_timedwait(&sla.cond, &sla.lock, &ts);
- else
- ast_cond_wait(&sla.cond, &sla.lock);
- if (sla.stop)
- break;
- }
-
- if (have_timeout)
- sla_process_timers(NULL);
-
- while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
- ast_mutex_unlock(&sla.lock);
- switch (event->type) {
- case SLA_EVENT_HOLD:
- sla_handle_hold_event(event);
- break;
- case SLA_EVENT_DIAL_STATE:
- sla_handle_dial_state_event();
- break;
- case SLA_EVENT_RINGING_TRUNK:
- sla_handle_ringing_trunk_event();
- break;
- }
- free(event);
- ast_mutex_lock(&sla.lock);
- }
- }
-
- ast_mutex_unlock(&sla.lock);
-
- while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry)))
- free(ringing_station);
-
- while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry)))
- free(failed_station);
-
- return NULL;
-}
-
-struct dial_trunk_args {
- struct sla_trunk_ref *trunk_ref;
- struct sla_station *station;
- ast_mutex_t *cond_lock;
- ast_cond_t *cond;
-};
-
-static void *dial_trunk(void *data)
-{
- struct dial_trunk_args *args = data;
- struct ast_dial *dial;
- char *tech, *tech_data;
- enum ast_dial_result dial_res;
- char conf_name[MAX_CONFNUM];
- struct ast_conference *conf;
- struct ast_flags conf_flags = { 0 };
- struct sla_trunk_ref *trunk_ref = args->trunk_ref;
- const char *cid_name = NULL, *cid_num = NULL;
-
- if (!(dial = ast_dial_create())) {
- ast_mutex_lock(args->cond_lock);
- ast_cond_signal(args->cond);
- ast_mutex_unlock(args->cond_lock);
- return NULL;
- }
-
- tech_data = ast_strdupa(trunk_ref->trunk->device);
- tech = strsep(&tech_data, "/");
- if (ast_dial_append(dial, tech, tech_data) == -1) {
- ast_mutex_lock(args->cond_lock);
- ast_cond_signal(args->cond);
- ast_mutex_unlock(args->cond_lock);
- ast_dial_destroy(dial);
- return NULL;
- }
-
- if (!sla.attempt_callerid && !ast_strlen_zero(trunk_ref->chan->cid.cid_name)) {
- cid_name = ast_strdupa(trunk_ref->chan->cid.cid_name);
- free(trunk_ref->chan->cid.cid_name);
- trunk_ref->chan->cid.cid_name = NULL;
- }
- if (!sla.attempt_callerid && !ast_strlen_zero(trunk_ref->chan->cid.cid_num)) {
- cid_num = ast_strdupa(trunk_ref->chan->cid.cid_num);
- free(trunk_ref->chan->cid.cid_num);
- trunk_ref->chan->cid.cid_num = NULL;
- }
-
- dial_res = ast_dial_run(dial, trunk_ref->chan, 1);
-
- if (cid_name)
- trunk_ref->chan->cid.cid_name = ast_strdup(cid_name);
- if (cid_num)
- trunk_ref->chan->cid.cid_num = ast_strdup(cid_num);
-
- if (dial_res != AST_DIAL_RESULT_TRYING) {
- ast_mutex_lock(args->cond_lock);
- ast_cond_signal(args->cond);
- ast_mutex_unlock(args->cond_lock);
- ast_dial_destroy(dial);
- return NULL;
- }
-
- for (;;) {
- unsigned int done = 0;
- switch ((dial_res = ast_dial_state(dial))) {
- case AST_DIAL_RESULT_ANSWERED:
- trunk_ref->trunk->chan = ast_dial_answered(dial);
- case AST_DIAL_RESULT_HANGUP:
- case AST_DIAL_RESULT_INVALID:
- case AST_DIAL_RESULT_FAILED:
- case AST_DIAL_RESULT_TIMEOUT:
- case AST_DIAL_RESULT_UNANSWERED:
- done = 1;
- case AST_DIAL_RESULT_TRYING:
- case AST_DIAL_RESULT_RINGING:
- case AST_DIAL_RESULT_PROGRESS:
- case AST_DIAL_RESULT_PROCEEDING:
- break;
- }
- if (done)
- break;
- }
-
- if (!trunk_ref->trunk->chan) {
- ast_mutex_lock(args->cond_lock);
- ast_cond_signal(args->cond);
- ast_mutex_unlock(args->cond_lock);
- ast_dial_join(dial);
- ast_dial_destroy(dial);
- return NULL;
- }
-
- snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
- ast_set_flag(&conf_flags,
- CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER |
- CONFFLAG_PASS_DTMF | CONFFLAG_SLA_TRUNK);
- conf = build_conf(conf_name, "", "", 1, 1, 1);
-
- ast_mutex_lock(args->cond_lock);
- ast_cond_signal(args->cond);
- ast_mutex_unlock(args->cond_lock);
-
- if (conf) {
- conf_run(trunk_ref->trunk->chan, conf, conf_flags.flags, NULL);
- dispose_conf(conf);
- conf = NULL;
- }
-
- /* If the trunk is going away, it is definitely now IDLE. */
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
-
- trunk_ref->trunk->chan = NULL;
- trunk_ref->trunk->on_hold = 0;
-
- ast_dial_join(dial);
- ast_dial_destroy(dial);
-
- return NULL;
-}
-
-/*! \brief For a given station, choose the highest priority idle trunk
- */
-static struct sla_trunk_ref *sla_choose_idle_trunk(const struct sla_station *station)
-{
- struct sla_trunk_ref *trunk_ref = NULL;
-
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->state == SLA_TRUNK_STATE_IDLE)
- break;
- }
-
- return trunk_ref;
-}
-
-static int sla_station_exec(struct ast_channel *chan, void *data)
-{
- char *station_name, *trunk_name;
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref = NULL;
- char conf_name[MAX_CONFNUM];
- struct ast_flags conf_flags = { 0 };
- struct ast_conference *conf;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
- pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
- return 0;
- }
-
- trunk_name = ast_strdupa(data);
- station_name = strsep(&trunk_name, "_");
-
- if (ast_strlen_zero(station_name)) {
- ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
- pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
- return 0;
- }
-
- AST_RWLIST_RDLOCK(&sla_stations);
- station = sla_find_station(station_name);
- AST_RWLIST_UNLOCK(&sla_stations);
-
- if (!station) {
- ast_log(LOG_WARNING, "Station '%s' not found!\n", station_name);
- pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
- return 0;
- }
-
- AST_RWLIST_RDLOCK(&sla_trunks);
- if (!ast_strlen_zero(trunk_name)) {
- trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
- } else
- trunk_ref = sla_choose_idle_trunk(station);
- AST_RWLIST_UNLOCK(&sla_trunks);
-
- if (!trunk_ref) {
- if (ast_strlen_zero(trunk_name))
- ast_log(LOG_NOTICE, "No trunks available for call.\n");
- else {
- ast_log(LOG_NOTICE, "Can't join existing call on trunk "
- "'%s' due to access controls.\n", trunk_name);
- }
- pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
- return 0;
- }
-
- if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME) {
- if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->hold_stations) == 1)
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
- else {
- trunk_ref->state = SLA_TRUNK_STATE_UP;
- ast_device_state_changed("SLA:%s_%s", station->name, trunk_ref->trunk->name);
- }
- } else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
- struct sla_ringing_trunk *ringing_trunk;
-
- ast_mutex_lock(&sla.lock);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
- if (ringing_trunk->trunk == trunk_ref->trunk) {
- AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- ast_mutex_unlock(&sla.lock);
-
- if (ringing_trunk) {
- ast_answer(ringing_trunk->trunk->chan);
- sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
-
- free(ringing_trunk);
-
- /* Queue up reprocessing ringing trunks, and then ringing stations again */
- sla_queue_event(SLA_EVENT_RINGING_TRUNK);
- sla_queue_event(SLA_EVENT_DIAL_STATE);
- }
- }
-
- trunk_ref->chan = chan;
-
- if (!trunk_ref->trunk->chan) {
- ast_mutex_t cond_lock;
- ast_cond_t cond;
- pthread_t dont_care;
- pthread_attr_t attr;
- struct dial_trunk_args args = {
- .trunk_ref = trunk_ref,
- .station = station,
- .cond_lock = &cond_lock,
- .cond = &cond,
- };
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
- /* Create a thread to dial the trunk and dump it into the conference.
- * However, we want to wait until the trunk has been dialed and the
- * conference is created before continuing on here. */
- ast_autoservice_start(chan);
- ast_mutex_init(&cond_lock);
- ast_cond_init(&cond, NULL);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_mutex_lock(&cond_lock);
- ast_pthread_create_background(&dont_care, &attr, dial_trunk, &args);
- ast_cond_wait(&cond, &cond_lock);
- ast_mutex_unlock(&cond_lock);
- ast_mutex_destroy(&cond_lock);
- ast_cond_destroy(&cond);
- pthread_attr_destroy(&attr);
- ast_autoservice_stop(chan);
- if (!trunk_ref->trunk->chan) {
- ast_log(LOG_DEBUG, "Trunk didn't get created. chan: %lx\n", (long) trunk_ref->trunk->chan);
- pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
- trunk_ref->chan = NULL;
- return 0;
- }
- }
-
- if (ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1) == 0 &&
- trunk_ref->trunk->on_hold) {
- trunk_ref->trunk->on_hold = 0;
- ast_indicate(trunk_ref->trunk->chan, AST_CONTROL_UNHOLD);
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
- }
-
- snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
- ast_set_flag(&conf_flags,
- CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
- ast_answer(chan);
- conf = build_conf(conf_name, "", "", 0, 0, 1);
- if (conf) {
- conf_run(chan, conf, conf_flags.flags, NULL);
- dispose_conf(conf);
- conf = NULL;
- }
- trunk_ref->chan = NULL;
- if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
- trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
- strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
- admin_exec(NULL, conf_name);
- trunk_ref->trunk->hold_stations = 0;
- sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
- }
-
- pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
-
- return 0;
-}
-
-static struct sla_trunk_ref *create_trunk_ref(struct sla_trunk *trunk)
-{
- struct sla_trunk_ref *trunk_ref;
-
- if (!(trunk_ref = ast_calloc(1, sizeof(*trunk_ref))))
- return NULL;
-
- trunk_ref->trunk = trunk;
-
- return trunk_ref;
-}
-
-static struct sla_ringing_trunk *queue_ringing_trunk(struct sla_trunk *trunk)
-{
- struct sla_ringing_trunk *ringing_trunk;
-
- if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk))))
- return NULL;
-
- ringing_trunk->trunk = trunk;
- ringing_trunk->ring_begin = ast_tvnow();
-
- sla_change_trunk_state(trunk, SLA_TRUNK_STATE_RINGING, ALL_TRUNK_REFS, NULL);
-
- ast_mutex_lock(&sla.lock);
- AST_LIST_INSERT_HEAD(&sla.ringing_trunks, ringing_trunk, entry);
- ast_mutex_unlock(&sla.lock);
-
- sla_queue_event(SLA_EVENT_RINGING_TRUNK);
-
- return ringing_trunk;
-}
-
-static int sla_trunk_exec(struct ast_channel *chan, void *data)
-{
- const char *trunk_name = data;
- char conf_name[MAX_CONFNUM];
- struct ast_conference *conf;
- struct ast_flags conf_flags = { 0 };
- struct sla_trunk *trunk;
- struct sla_ringing_trunk *ringing_trunk;
-
- AST_RWLIST_RDLOCK(&sla_trunks);
- trunk = sla_find_trunk(trunk_name);
- AST_RWLIST_UNLOCK(&sla_trunks);
- if (!trunk) {
- ast_log(LOG_ERROR, "SLA Trunk '%s' not found!\n", trunk_name);
- pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- return 0;
- }
- if (trunk->chan) {
- ast_log(LOG_ERROR, "Call came in on %s, but the trunk is already in use!\n",
- trunk_name);
- pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- return 0;
- }
- trunk->chan = chan;
-
- if (!(ringing_trunk = queue_ringing_trunk(trunk))) {
- pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- return 0;
- }
-
- snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_name);
- conf = build_conf(conf_name, "", "", 1, 1, 1);
- if (!conf) {
- pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- return 0;
- }
- ast_set_flag(&conf_flags,
- CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF);
- ast_indicate(chan, AST_CONTROL_RINGING);
- conf_run(chan, conf, conf_flags.flags, NULL);
- dispose_conf(conf);
- conf = NULL;
- trunk->chan = NULL;
- trunk->on_hold = 0;
-
- sla_change_trunk_state(trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
-
- if (!pbx_builtin_getvar_helper(chan, "SLATRUNK_STATUS"))
- pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");
-
- /* Remove the entry from the list of ringing trunks if it is still there. */
- ast_mutex_lock(&sla.lock);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
- if (ringing_trunk->trunk == trunk) {
- AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- ast_mutex_unlock(&sla.lock);
- if (ringing_trunk) {
- free(ringing_trunk);
- pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "UNANSWERED");
- /* Queue reprocessing of ringing trunks to make stations stop ringing
- * that shouldn't be ringing after this trunk stopped. */
- sla_queue_event(SLA_EVENT_RINGING_TRUNK);
- }
-
- return 0;
-}
-
-static int sla_state(const char *data)
-{
- char *buf, *station_name, *trunk_name;
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref;
- int res = AST_DEVICE_INVALID;
-
- trunk_name = buf = ast_strdupa(data);
- station_name = strsep(&trunk_name, "_");
-
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_LIST_TRAVERSE(&sla_stations, station, entry) {
- if (strcasecmp(station_name, station->name))
- continue;
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (!strcasecmp(trunk_name, trunk_ref->trunk->name))
- break;
- }
- if (!trunk_ref) {
- AST_RWLIST_UNLOCK(&sla_trunks);
- break;
- }
- switch (trunk_ref->state) {
- case SLA_TRUNK_STATE_IDLE:
- res = AST_DEVICE_NOT_INUSE;
- break;
- case SLA_TRUNK_STATE_RINGING:
- res = AST_DEVICE_RINGING;
- break;
- case SLA_TRUNK_STATE_UP:
- res = AST_DEVICE_INUSE;
- break;
- case SLA_TRUNK_STATE_ONHOLD:
- case SLA_TRUNK_STATE_ONHOLD_BYME:
- res = AST_DEVICE_ONHOLD;
- break;
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
- }
- AST_RWLIST_UNLOCK(&sla_stations);
-
- if (res == AST_DEVICE_INVALID) {
- ast_log(LOG_ERROR, "Could not determine state for trunk %s on station %s!\n",
- trunk_name, station_name);
- }
-
- return res;
-}
-
-static void destroy_trunk(struct sla_trunk *trunk)
-{
- struct sla_station_ref *station_ref;
-
- if (!ast_strlen_zero(trunk->autocontext))
- ast_context_remove_extension(trunk->autocontext, "s", 1, sla_registrar);
-
- while ((station_ref = AST_LIST_REMOVE_HEAD(&trunk->stations, entry)))
- free(station_ref);
-
- ast_string_field_free_memory(trunk);
- free(trunk);
-}
-
-static void destroy_station(struct sla_station *station)
-{
- struct sla_trunk_ref *trunk_ref;
-
- if (!ast_strlen_zero(station->autocontext)) {
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- char exten[AST_MAX_EXTENSION];
- char hint[AST_MAX_APP];
- snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
- snprintf(hint, sizeof(hint), "SLA:%s", exten);
- ast_context_remove_extension(station->autocontext, exten,
- 1, sla_registrar);
- ast_context_remove_extension(station->autocontext, hint,
- PRIORITY_HINT, sla_registrar);
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
- }
-
- while ((trunk_ref = AST_LIST_REMOVE_HEAD(&station->trunks, entry)))
- free(trunk_ref);
-
- ast_string_field_free_memory(station);
- free(station);
-}
-
-static void sla_destroy(void)
-{
- struct sla_trunk *trunk;
- struct sla_station *station;
-
- AST_RWLIST_WRLOCK(&sla_trunks);
- while ((trunk = AST_RWLIST_REMOVE_HEAD(&sla_trunks, entry)))
- destroy_trunk(trunk);
- AST_RWLIST_UNLOCK(&sla_trunks);
-
- AST_RWLIST_WRLOCK(&sla_stations);
- while ((station = AST_RWLIST_REMOVE_HEAD(&sla_stations, entry)))
- destroy_station(station);
- AST_RWLIST_UNLOCK(&sla_stations);
-
- if (sla.thread != AST_PTHREADT_NULL) {
- ast_mutex_lock(&sla.lock);
- sla.stop = 1;
- ast_cond_signal(&sla.cond);
- ast_mutex_unlock(&sla.lock);
- pthread_join(sla.thread, NULL);
- }
-
- /* Drop any created contexts from the dialplan */
- ast_context_destroy(NULL, sla_registrar);
-
- ast_mutex_destroy(&sla.lock);
- ast_cond_destroy(&sla.cond);
-}
-
-static int sla_check_device(const char *device)
-{
- char *tech, *tech_data;
-
- tech_data = ast_strdupa(device);
- tech = strsep(&tech_data, "/");
-
- if (ast_strlen_zero(tech) || ast_strlen_zero(tech_data))
- return -1;
-
- return 0;
-}
-
-static int sla_build_trunk(struct ast_config *cfg, const char *cat)
-{
- struct sla_trunk *trunk;
- struct ast_variable *var;
- const char *dev;
-
- if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
- ast_log(LOG_ERROR, "SLA Trunk '%s' defined with no device!\n", cat);
- return -1;
- }
-
- if (sla_check_device(dev)) {
- ast_log(LOG_ERROR, "SLA Trunk '%s' define with invalid device '%s'!\n",
- cat, dev);
- return -1;
- }
-
- if (!(trunk = ast_calloc(1, sizeof(*trunk))))
- return -1;
- if (ast_string_field_init(trunk, 32)) {
- free(trunk);
- return -1;
- }
-
- ast_string_field_set(trunk, name, cat);
- ast_string_field_set(trunk, device, dev);
-
- for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
- if (!strcasecmp(var->name, "autocontext"))
- ast_string_field_set(trunk, autocontext, var->value);
- else if (!strcasecmp(var->name, "ringtimeout")) {
- if (sscanf(var->value, "%u", &trunk->ring_timeout) != 1) {
- ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for trunk '%s'\n",
- var->value, trunk->name);
- trunk->ring_timeout = 0;
- }
- } else if (!strcasecmp(var->name, "barge"))
- trunk->barge_disabled = ast_false(var->value);
- else if (!strcasecmp(var->name, "hold")) {
- if (!strcasecmp(var->value, "private"))
- trunk->hold_access = SLA_HOLD_PRIVATE;
- else if (!strcasecmp(var->value, "open"))
- trunk->hold_access = SLA_HOLD_OPEN;
- else {
- ast_log(LOG_WARNING, "Invalid value '%s' for hold on trunk %s\n",
- var->value, trunk->name);
- }
- } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
- ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
- var->name, var->lineno, SLA_CONFIG_FILE);
- }
- }
-
- if (!ast_strlen_zero(trunk->autocontext)) {
- struct ast_context *context;
- context = ast_context_find_or_create(NULL, trunk->autocontext, sla_registrar);
- if (!context) {
- ast_log(LOG_ERROR, "Failed to automatically find or create "
- "context '%s' for SLA!\n", trunk->autocontext);
- destroy_trunk(trunk);
- return -1;
- }
- if (ast_add_extension2(context, 0 /* don't replace */, "s", 1,
- NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free, sla_registrar)) {
- ast_log(LOG_ERROR, "Failed to automatically create extension "
- "for trunk '%s'!\n", trunk->name);
- destroy_trunk(trunk);
- return -1;
- }
- }
-
- AST_RWLIST_WRLOCK(&sla_trunks);
- AST_RWLIST_INSERT_TAIL(&sla_trunks, trunk, entry);
- AST_RWLIST_UNLOCK(&sla_trunks);
-
- return 0;
-}
-
-static void sla_add_trunk_to_station(struct sla_station *station, struct ast_variable *var)
-{
- struct sla_trunk *trunk;
- struct sla_trunk_ref *trunk_ref;
- struct sla_station_ref *station_ref;
- char *trunk_name, *options, *cur;
-
- options = ast_strdupa(var->value);
- trunk_name = strsep(&options, ",");
-
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
- if (!strcasecmp(trunk->name, trunk_name))
- break;
- }
-
- AST_RWLIST_UNLOCK(&sla_trunks);
- if (!trunk) {
- ast_log(LOG_ERROR, "Trunk '%s' not found!\n", var->value);
- return;
- }
- if (!(trunk_ref = create_trunk_ref(trunk)))
- return;
- trunk_ref->state = SLA_TRUNK_STATE_IDLE;
-
- while ((cur = strsep(&options, ","))) {
- char *name, *value = cur;
- name = strsep(&value, "=");
- if (!strcasecmp(name, "ringtimeout")) {
- if (sscanf(value, "%u", &trunk_ref->ring_timeout) != 1) {
- ast_log(LOG_WARNING, "Invalid ringtimeout value '%s' for "
- "trunk '%s' on station '%s'\n", value, trunk->name, station->name);
- trunk_ref->ring_timeout = 0;
- }
- } else if (!strcasecmp(name, "ringdelay")) {
- if (sscanf(value, "%u", &trunk_ref->ring_delay) != 1) {
- ast_log(LOG_WARNING, "Invalid ringdelay value '%s' for "
- "trunk '%s' on station '%s'\n", value, trunk->name, station->name);
- trunk_ref->ring_delay = 0;
- }
- } else {
- ast_log(LOG_WARNING, "Invalid option '%s' for "
- "trunk '%s' on station '%s'\n", name, trunk->name, station->name);
- }
- }
-
- if (!(station_ref = sla_create_station_ref(station))) {
- free(trunk_ref);
- return;
- }
- ast_atomic_fetchadd_int((int *) &trunk->num_stations, 1);
- AST_RWLIST_WRLOCK(&sla_trunks);
- AST_LIST_INSERT_TAIL(&trunk->stations, station_ref, entry);
- AST_RWLIST_UNLOCK(&sla_trunks);
- AST_LIST_INSERT_TAIL(&station->trunks, trunk_ref, entry);
-}
-
-static int sla_build_station(struct ast_config *cfg, const char *cat)
-{
- struct sla_station *station;
- struct ast_variable *var;
- const char *dev;
-
- if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
- ast_log(LOG_ERROR, "SLA Station '%s' defined with no device!\n", cat);
- return -1;
- }
-
- if (!(station = ast_calloc(1, sizeof(*station))))
- return -1;
- if (ast_string_field_init(station, 32)) {
- free(station);
- return -1;
- }
-
- ast_string_field_set(station, name, cat);
- ast_string_field_set(station, device, dev);
-
- for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
- if (!strcasecmp(var->name, "trunk"))
- sla_add_trunk_to_station(station, var);
- else if (!strcasecmp(var->name, "autocontext"))
- ast_string_field_set(station, autocontext, var->value);
- else if (!strcasecmp(var->name, "ringtimeout")) {
- if (sscanf(var->value, "%u", &station->ring_timeout) != 1) {
- ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for station '%s'\n",
- var->value, station->name);
- station->ring_timeout = 0;
- }
- } else if (!strcasecmp(var->name, "ringdelay")) {
- if (sscanf(var->value, "%u", &station->ring_delay) != 1) {
- ast_log(LOG_WARNING, "Invalid ringdelay '%s' specified for station '%s'\n",
- var->value, station->name);
- station->ring_delay = 0;
- }
- } else if (!strcasecmp(var->name, "hold")) {
- if (!strcasecmp(var->value, "private"))
- station->hold_access = SLA_HOLD_PRIVATE;
- else if (!strcasecmp(var->value, "open"))
- station->hold_access = SLA_HOLD_OPEN;
- else {
- ast_log(LOG_WARNING, "Invalid value '%s' for hold on station %s\n",
- var->value, station->name);
- }
-
- } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
- ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
- var->name, var->lineno, SLA_CONFIG_FILE);
- }
- }
-
- if (!ast_strlen_zero(station->autocontext)) {
- struct ast_context *context;
- struct sla_trunk_ref *trunk_ref;
- context = ast_context_find_or_create(NULL, station->autocontext, sla_registrar);
- if (!context) {
- ast_log(LOG_ERROR, "Failed to automatically find or create "
- "context '%s' for SLA!\n", station->autocontext);
- destroy_station(station);
- return -1;
- }
- /* The extension for when the handset goes off-hook.
- * exten => station1,1,SLAStation(station1) */
- if (ast_add_extension2(context, 0 /* don't replace */, station->name, 1,
- NULL, NULL, slastation_app, ast_strdup(station->name), ast_free, sla_registrar)) {
- ast_log(LOG_ERROR, "Failed to automatically create extension "
- "for trunk '%s'!\n", station->name);
- destroy_station(station);
- return -1;
- }
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- char exten[AST_MAX_EXTENSION];
- char hint[AST_MAX_APP];
- snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
- snprintf(hint, sizeof(hint), "SLA:%s", exten);
- /* Extension for this line button
- * exten => station1_line1,1,SLAStation(station1_line1) */
- if (ast_add_extension2(context, 0 /* don't replace */, exten, 1,
- NULL, NULL, slastation_app, ast_strdup(exten), ast_free, sla_registrar)) {
- ast_log(LOG_ERROR, "Failed to automatically create extension "
- "for trunk '%s'!\n", station->name);
- destroy_station(station);
- return -1;
- }
- /* Hint for this line button
- * exten => station1_line1,hint,SLA:station1_line1 */
- if (ast_add_extension2(context, 0 /* don't replace */, exten, PRIORITY_HINT,
- NULL, NULL, hint, NULL, NULL, sla_registrar)) {
- ast_log(LOG_ERROR, "Failed to automatically create hint "
- "for trunk '%s'!\n", station->name);
- destroy_station(station);
- return -1;
- }
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
- }
-
- AST_RWLIST_WRLOCK(&sla_stations);
- AST_RWLIST_INSERT_TAIL(&sla_stations, station, entry);
- AST_RWLIST_UNLOCK(&sla_stations);
-
- return 0;
-}
-
-static int sla_load_config(void)
-{
- struct ast_config *cfg;
- const char *cat = NULL;
- int res = 0;
- const char *val;
-
- ast_mutex_init(&sla.lock);
- ast_cond_init(&sla.cond, NULL);
-
- if (!(cfg = ast_config_load(SLA_CONFIG_FILE)))
- return 0; /* Treat no config as normal */
-
- if ((val = ast_variable_retrieve(cfg, "general", "attemptcallerid")))
- sla.attempt_callerid = ast_true(val);
-
- while ((cat = ast_category_browse(cfg, cat)) && !res) {
- const char *type;
- if (!strcasecmp(cat, "general"))
- continue;
- if (!(type = ast_variable_retrieve(cfg, cat, "type"))) {
- ast_log(LOG_WARNING, "Invalid entry in %s defined with no type!\n",
- SLA_CONFIG_FILE);
- continue;
- }
- if (!strcasecmp(type, "trunk"))
- res = sla_build_trunk(cfg, cat);
- else if (!strcasecmp(type, "station"))
- res = sla_build_station(cfg, cat);
- else {
- ast_log(LOG_WARNING, "Entry in %s defined with invalid type '%s'!\n",
- SLA_CONFIG_FILE, type);
- }
- }
-
- ast_config_destroy(cfg);
-
- if (!AST_LIST_EMPTY(&sla_stations) || !AST_LIST_EMPTY(&sla_stations))
- ast_pthread_create(&sla.thread, NULL, sla_thread, NULL);
-
- return res;
-}
-
-static int load_config(int reload)
-{
- int res = 0;
-
- load_config_meetme();
- if (!reload)
- res = sla_load_config();
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res = 0;
-
- ast_cli_unregister_multiple(cli_meetme, ARRAY_LEN(cli_meetme));
- res = ast_manager_unregister("MeetmeMute");
- res |= ast_manager_unregister("MeetmeUnmute");
- res |= ast_unregister_application(app3);
- res |= ast_unregister_application(app2);
- res |= ast_unregister_application(app);
- res |= ast_unregister_application(slastation_app);
- res |= ast_unregister_application(slatrunk_app);
-
- ast_devstate_prov_del("Meetme");
- ast_devstate_prov_del("SLA");
-
- ast_module_user_hangup_all();
-
- sla_destroy();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= load_config(0);
-
- ast_cli_register_multiple(cli_meetme, ARRAY_LEN(cli_meetme));
- res |= ast_manager_register("MeetmeMute", EVENT_FLAG_CALL,
- action_meetmemute, "Mute a Meetme user");
- res |= ast_manager_register("MeetmeUnmute", EVENT_FLAG_CALL,
- action_meetmeunmute, "Unmute a Meetme user");
- res |= ast_register_application(app3, admin_exec, synopsis3, descrip3);
- res |= ast_register_application(app2, count_exec, synopsis2, descrip2);
- res |= ast_register_application(app, conf_exec, synopsis, descrip);
- res |= ast_register_application(slastation_app, sla_station_exec,
- slastation_synopsis, slastation_desc);
- res |= ast_register_application(slatrunk_app, sla_trunk_exec,
- slatrunk_synopsis, slatrunk_desc);
-
- res |= ast_devstate_prov_add("Meetme", meetmestate);
- res |= ast_devstate_prov_add("SLA", sla_state);
-
- return res;
-}
-
-static int reload(void)
-{
- return load_config(1);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "MeetMe conference bridge",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
diff --git a/1.4/apps/app_milliwatt.c b/1.4/apps/app_milliwatt.c
deleted file mode 100644
index 8b0456014..000000000
--- a/1.4/apps/app_milliwatt.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Digital Milliwatt Test
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/utils.h"
-
-static char *app = "Milliwatt";
-
-static char *synopsis = "Generate a Constant 1000Hz tone at 0dbm (mu-law)";
-
-static char *descrip =
-"Milliwatt(): Generate a Constant 1000Hz tone at 0dbm (mu-law)\n";
-
-
-static char digital_milliwatt[] = {0x1e,0x0b,0x0b,0x1e,0x9e,0x8b,0x8b,0x9e} ;
-
-static void *milliwatt_alloc(struct ast_channel *chan, void *params)
-{
- return ast_calloc(1, sizeof(int));
-}
-
-static void milliwatt_release(struct ast_channel *chan, void *data)
-{
- free(data);
- return;
-}
-
-static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
-{
- unsigned char buf[AST_FRIENDLY_OFFSET + 640];
- const int maxsamples = sizeof (buf) / sizeof (buf[0]);
- int i, *indexp = (int *) data;
- struct ast_frame wf = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_ULAW,
- .offset = AST_FRIENDLY_OFFSET,
- .data = buf + AST_FRIENDLY_OFFSET,
- .src = __FUNCTION__,
- };
-
- /* Instead of len, use samples, because channel.c generator_force
- * generate(chan, tmp, 0, 160) ignores len. In any case, len is
- * a multiple of samples, given by number of samples times bytes per
- * sample. In the case of ulaw, len = samples. for signed linear
- * len = 2 * samples */
-
- if (samples > maxsamples) {
- ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n", maxsamples, samples);
- samples = maxsamples;
- }
- len = samples * sizeof (buf[0]);
- wf.datalen = len;
- wf.samples = samples;
- /* create a buffer containing the digital milliwatt pattern */
- for(i = 0; i < len; i++)
- {
- buf[AST_FRIENDLY_OFFSET + i] = digital_milliwatt[(*indexp)++];
- *indexp &= 7;
- }
- if (ast_write(chan,&wf) < 0)
- {
- ast_log(LOG_WARNING,"Failed to write frame to '%s': %s\n",chan->name,strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static struct ast_generator milliwattgen =
-{
- alloc: milliwatt_alloc,
- release: milliwatt_release,
- generate: milliwatt_generate,
-} ;
-
-static int milliwatt_exec(struct ast_channel *chan, void *data)
-{
-
- struct ast_module_user *u;
- u = ast_module_user_add(chan);
- ast_set_write_format(chan, AST_FORMAT_ULAW);
- ast_set_read_format(chan, AST_FORMAT_ULAW);
- if (chan->_state != AST_STATE_UP)
- {
- ast_answer(chan);
- }
- if (ast_activate_generator(chan,&milliwattgen,"milliwatt") < 0)
- {
- ast_log(LOG_WARNING,"Failed to activate generator on '%s'\n",chan->name);
- ast_module_user_remove(u);
- return -1;
- }
- while(!ast_safe_sleep(chan, 10000));
- ast_deactivate_generator(chan);
- ast_module_user_remove(u);
- return -1;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, milliwatt_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Digital Milliwatt (mu-law) Test Application");
diff --git a/1.4/apps/app_mixmonitor.c b/1.4/apps/app_mixmonitor.c
deleted file mode 100644
index 3cf79b1fc..000000000
--- a/1.4/apps/app_mixmonitor.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Anthony Minessale II
- * Copyright (C) 2005 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@digium.com>
- *
- * Based on app_muxmon.c provided by
- * Anthony Minessale II <anthmct@yahoo.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.
- */
-
-/*! \file
- *
- * \brief MixMonitor() - Record a call and mix the audio during the recording
- * \ingroup applications
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Kevin P. Fleming <kpfleming@digium.com>
- *
- * \note Based on app_muxmon.c provided by
- * Anthony Minessale II <anthmct@yahoo.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/audiohook.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/cli.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/utils.h"
-
-#define get_volfactor(x) x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0
-
-static const char *app = "MixMonitor";
-static const char *synopsis = "Record a call and mix the audio during the recording";
-static const char *desc = ""
-" MixMonitor(<file>.<ext>[|<options>[|<command>]])\n\n"
-"Records the audio on the current channel to the specified file.\n"
-"If the filename is an absolute path, uses that path, otherwise\n"
-"creates the file in the configured monitoring directory from\n"
-"asterisk.conf.\n\n"
-"Valid options:\n"
-" a - Append to the file instead of overwriting it.\n"
-" b - Only save audio to the file while the channel is bridged.\n"
-" Note: Does not include conferences or sounds played to each bridged\n"
-" party.\n"
-" v(<x>) - Adjust the heard volume by a factor of <x> (range -4 to 4)\n"
-" V(<x>) - Adjust the spoken volume by a factor of <x> (range -4 to 4)\n"
-" W(<x>) - Adjust the both heard and spoken volumes by a factor of <x>\n"
-" (range -4 to 4)\n\n"
-"<command> will be executed when the recording is over\n"
-"Any strings matching ^{X} will be unescaped to ${X}.\n"
-"All variables will be evaluated at the time MixMonitor is called.\n"
-"The variable MIXMONITOR_FILENAME will contain the filename used to record.\n"
-"";
-
-static const char *stop_app = "StopMixMonitor";
-static const char *stop_synopsis = "Stop recording a call through MixMonitor";
-static const char *stop_desc = ""
-" StopMixMonitor()\n\n"
-"Stops the audio recording that was started with a call to MixMonitor()\n"
-"on the current channel.\n"
-"";
-
-struct module_symbols *me;
-
-static const char *mixmonitor_spy_type = "MixMonitor";
-
-struct mixmonitor {
- struct ast_audiohook audiohook;
- char *filename;
- char *post_process;
- char *name;
- unsigned int flags;
- struct ast_channel *chan;
-};
-
-enum {
- MUXFLAG_APPEND = (1 << 1),
- MUXFLAG_BRIDGED = (1 << 2),
- MUXFLAG_VOLUME = (1 << 3),
- MUXFLAG_READVOLUME = (1 << 4),
- MUXFLAG_WRITEVOLUME = (1 << 5),
-} mixmonitor_flags;
-
-enum {
- OPT_ARG_READVOLUME = 0,
- OPT_ARG_WRITEVOLUME,
- OPT_ARG_VOLUME,
- OPT_ARG_ARRAY_SIZE,
-} mixmonitor_args;
-
-AST_APP_OPTIONS(mixmonitor_opts, {
- AST_APP_OPTION('a', MUXFLAG_APPEND),
- AST_APP_OPTION('b', MUXFLAG_BRIDGED),
- AST_APP_OPTION_ARG('v', MUXFLAG_READVOLUME, OPT_ARG_READVOLUME),
- AST_APP_OPTION_ARG('V', MUXFLAG_WRITEVOLUME, OPT_ARG_WRITEVOLUME),
- AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME),
-});
-
-static int startmon(struct ast_channel *chan, struct ast_audiohook *audiohook)
-{
- struct ast_channel *peer;
- int res;
-
- if (!chan)
- return -1;
-
- res = ast_audiohook_attach(chan, audiohook);
-
- if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan)))
- ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);
-
- return res;
-}
-
-#define SAMPLES_PER_FRAME 160
-
-static void *mixmonitor_thread(void *obj)
-{
- struct mixmonitor *mixmonitor = obj;
- struct ast_filestream *fs = NULL;
- unsigned int oflags;
- char *ext;
- int errflag = 0;
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Begin MixMonitor Recording %s\n", mixmonitor->name);
-
- ast_audiohook_lock(&mixmonitor->audiohook);
-
- while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
- struct ast_frame *fr = NULL;
-
- ast_audiohook_trigger_wait(&mixmonitor->audiohook);
-
- if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING)
- break;
-
- if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR)))
- continue;
-
- if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || ast_bridged_channel(mixmonitor->chan)) {
- /* Initialize the file if not already done so */
- if (!fs && !errflag) {
- oflags = O_CREAT | O_WRONLY;
- oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
-
- if ((ext = strrchr(mixmonitor->filename, '.')))
- *(ext++) = '\0';
- else
- ext = "raw";
-
- if (!(fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0644))) {
- ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext);
- errflag = 1;
- }
- }
-
- /* Write out the frame */
- if (fs)
- ast_writestream(fs, fr);
- }
-
- /* All done! free it. */
- ast_frame_free(fr, 0);
- }
-
- ast_audiohook_detach(&mixmonitor->audiohook);
- ast_audiohook_unlock(&mixmonitor->audiohook);
- ast_audiohook_destroy(&mixmonitor->audiohook);
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name);
-
- if (fs)
- ast_closestream(fs);
-
- if (mixmonitor->post_process) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "Executing [%s]\n", mixmonitor->post_process);
- ast_safe_system(mixmonitor->post_process);
- }
-
- free(mixmonitor);
-
-
- return NULL;
-}
-
-static void launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags,
- int readvol, int writevol, const char *post_process)
-{
- pthread_attr_t attr;
- pthread_t thread;
- struct mixmonitor *mixmonitor;
- char postprocess2[1024] = "";
- size_t len;
-
- len = sizeof(*mixmonitor) + strlen(chan->name) + strlen(filename) + 2;
-
- /* If a post process system command is given attach it to the structure */
- if (!ast_strlen_zero(post_process)) {
- char *p1, *p2;
-
- p1 = ast_strdupa(post_process);
- for (p2 = p1; *p2 ; p2++) {
- if (*p2 == '^' && *(p2+1) == '{') {
- *p2 = '$';
- }
- }
-
- pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1);
- if (!ast_strlen_zero(postprocess2))
- len += strlen(postprocess2) + 1;
- }
-
- /* Pre-allocate mixmonitor structure and spy */
- if (!(mixmonitor = calloc(1, len))) {
- return;
- }
-
- /* Copy over flags and channel name */
- mixmonitor->flags = flags;
- mixmonitor->chan = chan;
- mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
- strcpy(mixmonitor->name, chan->name);
- if (!ast_strlen_zero(postprocess2)) {
- mixmonitor->post_process = mixmonitor->name + strlen(mixmonitor->name) + strlen(filename) + 2;
- strcpy(mixmonitor->post_process, postprocess2);
- }
-
- mixmonitor->filename = (char *) mixmonitor + sizeof(*mixmonitor) + strlen(chan->name) + 1;
- strcpy(mixmonitor->filename, filename);
-
- /* Setup the actual spy before creating our thread */
- if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
- free(mixmonitor);
- return;
- }
-
- ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
-
- if (readvol)
- mixmonitor->audiohook.options.read_volume = readvol;
- if (writevol)
- mixmonitor->audiohook.options.write_volume = writevol;
-
- if (startmon(chan, &mixmonitor->audiohook)) {
- ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n",
- mixmonitor_spy_type, chan->name);
- /* Since we couldn't add ourselves - bail out! */
- ast_audiohook_destroy(&mixmonitor->audiohook);
- free(mixmonitor);
- return;
- }
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create_background(&thread, &attr, mixmonitor_thread, mixmonitor);
- pthread_attr_destroy(&attr);
-
-}
-
-static int mixmonitor_exec(struct ast_channel *chan, void *data)
-{
- int x, readvol = 0, writevol = 0;
- struct ast_module_user *u;
- struct ast_flags flags = {0};
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(filename);
- AST_APP_ARG(options);
- AST_APP_ARG(post_process);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.filename)) {
- ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if (args.options) {
- char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
-
- ast_app_parse_options(mixmonitor_opts, &flags, opts, args.options);
-
- if (ast_test_flag(&flags, MUXFLAG_READVOLUME)) {
- if (ast_strlen_zero(opts[OPT_ARG_READVOLUME])) {
- ast_log(LOG_WARNING, "No volume level was provided for the heard volume ('v') option.\n");
- } else if ((sscanf(opts[OPT_ARG_READVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
- ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_READVOLUME]);
- } else {
- readvol = get_volfactor(x);
- }
- }
-
- if (ast_test_flag(&flags, MUXFLAG_WRITEVOLUME)) {
- if (ast_strlen_zero(opts[OPT_ARG_WRITEVOLUME])) {
- ast_log(LOG_WARNING, "No volume level was provided for the spoken volume ('V') option.\n");
- } else if ((sscanf(opts[OPT_ARG_WRITEVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
- ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_WRITEVOLUME]);
- } else {
- writevol = get_volfactor(x);
- }
- }
-
- if (ast_test_flag(&flags, MUXFLAG_VOLUME)) {
- if (ast_strlen_zero(opts[OPT_ARG_VOLUME])) {
- ast_log(LOG_WARNING, "No volume level was provided for the combined volume ('W') option.\n");
- } else if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
- ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_VOLUME]);
- } else {
- readvol = writevol = get_volfactor(x);
- }
- }
- }
-
- /* if not provided an absolute path, use the system-configured monitoring directory */
- if (args.filename[0] != '/') {
- char *build;
-
- build = alloca(strlen(ast_config_AST_MONITOR_DIR) + strlen(args.filename) + 3);
- sprintf(build, "%s/%s", ast_config_AST_MONITOR_DIR, args.filename);
- args.filename = build;
- }
-
- pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
- launch_monitor_thread(chan, args.filename, flags.flags, readvol, writevol, args.post_process);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int stop_mixmonitor_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- ast_audiohook_detach_source(chan, mixmonitor_spy_type);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int mixmonitor_cli(int fd, int argc, char **argv)
-{
- struct ast_channel *chan;
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
-
- if (!(chan = ast_get_channel_by_name_prefix_locked(argv[2], strlen(argv[2])))) {
- ast_cli(fd, "No channel matching '%s' found.\n", argv[2]);
- return RESULT_SUCCESS;
- }
-
- if (!strcasecmp(argv[1], "start"))
- mixmonitor_exec(chan, argv[3]);
- else if (!strcasecmp(argv[1], "stop"))
- ast_audiohook_detach_source(chan, mixmonitor_spy_type);
-
- ast_channel_unlock(chan);
-
- return RESULT_SUCCESS;
-}
-
-static char *complete_mixmonitor_cli(const char *line, const char *word, int pos, int state)
-{
- return ast_complete_channels(line, word, pos, state, 2);
-}
-
-static struct ast_cli_entry cli_mixmonitor[] = {
- { { "mixmonitor", NULL, NULL },
- mixmonitor_cli, "Execute a MixMonitor command.",
- "mixmonitor <start|stop> <chan_name> [args]\n\n"
- "The optional arguments are passed to the\n"
- "MixMonitor application when the 'start' command is used.\n",
- complete_mixmonitor_cli },
-};
-
-static int unload_module(void)
-{
- int res;
-
- ast_cli_unregister_multiple(cli_mixmonitor, sizeof(cli_mixmonitor) / sizeof(struct ast_cli_entry));
- res = ast_unregister_application(stop_app);
- res |= ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- ast_cli_register_multiple(cli_mixmonitor, sizeof(cli_mixmonitor) / sizeof(struct ast_cli_entry));
- res = ast_register_application(app, mixmonitor_exec, synopsis, desc);
- res |= ast_register_application(stop_app, stop_mixmonitor_exec, stop_synopsis, stop_desc);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Mixed Audio Monitoring Application");
diff --git a/1.4/apps/app_morsecode.c b/1.4/apps/app_morsecode.c
deleted file mode 100644
index aec946a09..000000000
--- a/1.4/apps/app_morsecode.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2006, Tilghman Lesher. All rights reserved.
- *
- * Tilghman Lesher <app_morsecode__v001@the-tilghman.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief Morsecode application
- *
- * \author Tilghman Lesher <app_morsecode__v001@the-tilghman.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/indications.h"
-
-static char *app_morsecode = "Morsecode";
-
-static char *morsecode_synopsis = "Plays morse code";
-
-static char *morsecode_descrip =
-"Usage: Morsecode(<string>)\n"
-"Plays the Morse code equivalent of the passed string. If the variable\n"
-"MORSEDITLEN is set, it will use that value for the length (in ms) of the dit\n"
-"(defaults to 80). Additionally, if MORSETONE is set, it will use that tone\n"
-"(in Hz). The tone default is 800.\n";
-
-
-static char *morsecode[] = {
- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* 0-15 */
- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* 16-31 */
- " ", /* 32 - <space> */
- ".-.-.-", /* 33 - ! */
- ".-..-.", /* 34 - " */
- "", /* 35 - # */
- "", /* 36 - $ */
- "", /* 37 - % */
- "", /* 38 - & */
- ".----.", /* 39 - ' */
- "-.--.-", /* 40 - ( */
- "-.--.-", /* 41 - ) */
- "", /* 42 - * */
- "", /* 43 - + */
- "--..--", /* 44 - , */
- "-....-", /* 45 - - */
- ".-.-.-", /* 46 - . */
- "-..-.", /* 47 - / */
- "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", /* 48-57 - 0-9 */
- "---...", /* 58 - : */
- "-.-.-.", /* 59 - ; */
- "", /* 60 - < */
- "-...-", /* 61 - = */
- "", /* 62 - > */
- "..--..", /* 63 - ? */
- ".--.-.", /* 64 - @ */
- ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
- "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
- "-.--.-", /* 91 - [ (really '(') */
- "-..-.", /* 92 - \ (really '/') */
- "-.--.-", /* 93 - ] (really ')') */
- "", /* 94 - ^ */
- "..--.-", /* 95 - _ */
- ".----.", /* 96 - ` */
- ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
- "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
- "-.--.-", /* 123 - { (really '(') */
- "", /* 124 - | */
- "-.--.-", /* 125 - } (really ')') */
- "-..-.", /* 126 - ~ (really bar) */
- ". . .", /* 127 - <del> (error) */
-};
-
-static void playtone(struct ast_channel *chan, int tone, int len)
-{
- char dtmf[20];
- snprintf(dtmf, sizeof(dtmf), "%d/%d", tone, len);
- ast_playtones_start(chan, 0, dtmf, 0);
- ast_safe_sleep(chan, len);
- ast_playtones_stop(chan);
-}
-
-static int morsecode_exec(struct ast_channel *chan, void *data)
-{
- int res=0, ditlen, tone;
- char *digit;
- const char *ditlenc, *tonec;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: Morsecode(<string>) - no argument found\n");
- ast_module_user_remove(u);
- return 0;
- }
-
- /* Use variable MORESEDITLEN, if set (else 80) */
- ditlenc = pbx_builtin_getvar_helper(chan, "MORSEDITLEN");
- if (ast_strlen_zero(ditlenc) || (sscanf(ditlenc, "%d", &ditlen) != 1)) {
- ditlen = 80;
- }
-
- /* Use variable MORSETONE, if set (else 800) */
- tonec = pbx_builtin_getvar_helper(chan, "MORSETONE");
- if (ast_strlen_zero(tonec) || (sscanf(tonec, "%d", &tone) != 1)) {
- tone = 800;
- }
-
- for (digit = data; *digit; digit++) {
- int digit2 = *digit;
- char *dahdit;
- if (digit2 < 0) {
- continue;
- }
- for (dahdit = morsecode[digit2]; *dahdit; dahdit++) {
- if (*dahdit == '-') {
- playtone(chan, tone, 3 * ditlen);
- } else if (*dahdit == '.') {
- playtone(chan, tone, 1 * ditlen);
- } else {
- /* Account for ditlen of silence immediately following */
- playtone(chan, 0, 2 * ditlen);
- }
-
- /* Pause slightly between each dit and dah */
- playtone(chan, 0, 1 * ditlen);
- }
- /* Pause between characters */
- playtone(chan, 0, 2 * ditlen);
- }
-
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_morsecode);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app_morsecode, morsecode_exec, morsecode_synopsis, morsecode_descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Morse code");
diff --git a/1.4/apps/app_mp3.c b/1.4/apps/app_mp3.c
deleted file mode 100644
index 55d50f011..000000000
--- a/1.4/apps/app_mp3.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Silly application to play an MP3 file -- uses mpg123
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/frame.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/options.h"
-
-#define LOCAL_MPG_123 "/usr/local/bin/mpg123"
-#define MPG_123 "/usr/bin/mpg123"
-
-static char *app = "MP3Player";
-
-static char *synopsis = "Play an MP3 file or stream";
-
-static char *descrip =
-" MP3Player(location) Executes mpg123 to play the given location,\n"
-"which typically would be a filename or a URL. User can exit by pressing\n"
-"any key on the dialpad, or by hanging up.";
-
-
-static int mp3play(char *filename, int fd)
-{
- int res;
- int x;
- sigset_t fullset, oldset;
-
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
-
- res = fork();
- if (res < 0)
- ast_log(LOG_WARNING, "Fork failed\n");
- if (res) {
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- return res;
- }
- if (ast_opt_high_priority)
- ast_set_priority(0);
- signal(SIGPIPE, SIG_DFL);
- pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
-
- dup2(fd, STDOUT_FILENO);
- for (x=STDERR_FILENO + 1;x<256;x++) {
- if (x != STDOUT_FILENO)
- close(x);
- }
- /* Execute mpg123, but buffer if it's a net connection */
- if (!strncasecmp(filename, "http://", 7)) {
- /* Most commonly installed in /usr/local/bin */
- execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
- /* But many places has it in /usr/bin */
- execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
- /* As a last-ditch effort, try to use PATH */
- execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
- }
- else {
- /* Most commonly installed in /usr/local/bin */
- execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
- /* But many places has it in /usr/bin */
- execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
- /* As a last-ditch effort, try to use PATH */
- execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
- }
- ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
- _exit(0);
-}
-
-static int timed_read(int fd, void *data, int datalen, int timeout)
-{
- int res;
- struct pollfd fds[1];
- fds[0].fd = fd;
- fds[0].events = POLLIN;
- res = poll(fds, 1, timeout);
- if (res < 1) {
- ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res);
- return -1;
- }
- return read(fd, data, datalen);
-
-}
-
-static int mp3_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
- int fds[2];
- int ms = -1;
- int pid = -1;
- int owriteformat;
- int timeout = 2000;
- struct timeval next;
- struct ast_frame *f;
- struct myframe {
- struct ast_frame f;
- char offset[AST_FRIENDLY_OFFSET];
- short frdata[160];
- } myf;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (pipe(fds)) {
- ast_log(LOG_WARNING, "Unable to create pipe\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_stopstream(chan);
-
- owriteformat = chan->writeformat;
- res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- res = mp3play((char *)data, fds[1]);
- if (!strncasecmp((char *)data, "http://", 7)) {
- timeout = 10000;
- }
- /* Wait 1000 ms first */
- next = ast_tvnow();
- next.tv_sec += 1;
- if (res >= 0) {
- pid = res;
- /* Order is important -- there's almost always going to be mp3... we want to prioritize the
- user */
- for (;;) {
- ms = ast_tvdiff_ms(next, ast_tvnow());
- if (ms <= 0) {
- res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
- if (res > 0) {
- myf.f.frametype = AST_FRAME_VOICE;
- myf.f.subclass = AST_FORMAT_SLINEAR;
- myf.f.datalen = res;
- myf.f.samples = res / 2;
- myf.f.mallocd = 0;
- myf.f.offset = AST_FRIENDLY_OFFSET;
- myf.f.src = __PRETTY_FUNCTION__;
- myf.f.delivery.tv_sec = 0;
- myf.f.delivery.tv_usec = 0;
- myf.f.data = myf.frdata;
- if (ast_write(chan, &myf.f) < 0) {
- res = -1;
- break;
- }
- } else {
- ast_log(LOG_DEBUG, "No more mp3\n");
- res = 0;
- break;
- }
- next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
- } else {
- ms = ast_waitfor(chan, ms);
- if (ms < 0) {
- ast_log(LOG_DEBUG, "Hangup detected\n");
- res = -1;
- break;
- }
- if (ms) {
- f = ast_read(chan);
- if (!f) {
- ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
- res = -1;
- break;
- }
- if (f->frametype == AST_FRAME_DTMF) {
- ast_log(LOG_DEBUG, "User pressed a key\n");
- ast_frfree(f);
- res = 0;
- break;
- }
- ast_frfree(f);
- }
- }
- }
- }
- close(fds[0]);
- close(fds[1]);
-
- if (pid > -1)
- kill(pid, SIGKILL);
- if (!res && owriteformat)
- ast_set_write_format(chan, owriteformat);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, mp3_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Silly MP3 Application");
diff --git a/1.4/apps/app_nbscat.c b/1.4/apps/app_nbscat.c
deleted file mode 100644
index 5f3000404..000000000
--- a/1.4/apps/app_nbscat.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Silly application to play an NBScat file -- uses nbscat8k
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/frame.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/options.h"
-
-#define LOCAL_NBSCAT "/usr/local/bin/nbscat8k"
-#define NBSCAT "/usr/bin/nbscat8k"
-
-#ifndef AF_LOCAL
-#define AF_LOCAL AF_UNIX
-#endif
-
-static char *app = "NBScat";
-
-static char *synopsis = "Play an NBS local stream";
-
-static char *descrip =
-" NBScat: Executes nbscat to listen to the local NBS stream.\n"
-"User can exit by pressing any key\n.";
-
-
-static int NBScatplay(int fd)
-{
- int res;
- int x;
- sigset_t fullset, oldset;
-
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
-
- res = fork();
- if (res < 0)
- ast_log(LOG_WARNING, "Fork failed\n");
- if (res) {
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- return res;
- }
- signal(SIGPIPE, SIG_DFL);
- pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
-
- if (ast_opt_high_priority)
- ast_set_priority(0);
-
- dup2(fd, STDOUT_FILENO);
- for (x = STDERR_FILENO + 1; x < 1024; x++) {
- if (x != STDOUT_FILENO)
- close(x);
- }
- /* Most commonly installed in /usr/local/bin */
- execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
- execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
- ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
- _exit(0);
-}
-
-static int timed_read(int fd, void *data, int datalen)
-{
- int res;
- struct pollfd fds[1];
- fds[0].fd = fd;
- fds[0].events = POLLIN;
- res = poll(fds, 1, 2000);
- if (res < 1) {
- ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res);
- return -1;
- }
- return read(fd, data, datalen);
-
-}
-
-static int NBScat_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
- int fds[2];
- int ms = -1;
- int pid = -1;
- int owriteformat;
- struct timeval next;
- struct ast_frame *f;
- struct myframe {
- struct ast_frame f;
- char offset[AST_FRIENDLY_OFFSET];
- short frdata[160];
- } myf;
-
- u = ast_module_user_add(chan);
-
- if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
- ast_log(LOG_WARNING, "Unable to create socketpair\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_stopstream(chan);
-
- owriteformat = chan->writeformat;
- res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- res = NBScatplay(fds[1]);
- /* Wait 1000 ms first */
- next = ast_tvnow();
- next.tv_sec += 1;
- if (res >= 0) {
- pid = res;
- /* Order is important -- there's almost always going to be mp3... we want to prioritize the
- user */
- for (;;) {
- ms = ast_tvdiff_ms(next, ast_tvnow());
- if (ms <= 0) {
- res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
- if (res > 0) {
- myf.f.frametype = AST_FRAME_VOICE;
- myf.f.subclass = AST_FORMAT_SLINEAR;
- myf.f.datalen = res;
- myf.f.samples = res / 2;
- myf.f.mallocd = 0;
- myf.f.offset = AST_FRIENDLY_OFFSET;
- myf.f.src = __PRETTY_FUNCTION__;
- myf.f.delivery.tv_sec = 0;
- myf.f.delivery.tv_usec = 0;
- myf.f.data = myf.frdata;
- if (ast_write(chan, &myf.f) < 0) {
- res = -1;
- break;
- }
- } else {
- ast_log(LOG_DEBUG, "No more mp3\n");
- res = 0;
- break;
- }
- next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
- } else {
- ms = ast_waitfor(chan, ms);
- if (ms < 0) {
- ast_log(LOG_DEBUG, "Hangup detected\n");
- res = -1;
- break;
- }
- if (ms) {
- f = ast_read(chan);
- if (!f) {
- ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
- res = -1;
- break;
- }
- if (f->frametype == AST_FRAME_DTMF) {
- ast_log(LOG_DEBUG, "User pressed a key\n");
- ast_frfree(f);
- res = 0;
- break;
- }
- ast_frfree(f);
- }
- }
- }
- }
- close(fds[0]);
- close(fds[1]);
-
- if (pid > -1)
- kill(pid, SIGKILL);
- if (!res && owriteformat)
- ast_set_write_format(chan, owriteformat);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, NBScat_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Silly NBS Stream Application");
diff --git a/1.4/apps/app_osplookup.c b/1.4/apps/app_osplookup.c
deleted file mode 100644
index ad2ce5065..000000000
--- a/1.4/apps/app_osplookup.c
+++ /dev/null
@@ -1,1677 +0,0 @@
-/*
- * 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.
- */
-
-/*!
- * \file
- * \brief Open Settlement Protocol (OSP) Applications
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>osptk</depend>
- <depend>ssl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <osp/osp.h>
-#include <osp/osputils.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/config.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/channel.h"
-#include "asterisk/app.h"
-#include "asterisk/module.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/logger.h"
-#include "asterisk/astosp.h"
-
-/* OSP Buffer Sizes */
-#define OSP_INTSTR_SIZE ((unsigned int)16) /* OSP signed/unsigned int string buffer size */
-#define OSP_NORSTR_SIZE ((unsigned int)256) /* OSP normal string buffer size */
-#define OSP_TOKSTR_SIZE ((unsigned int)4096) /* OSP token string buffer size */
-
-/* OSP Constants */
-#define OSP_INVALID_HANDLE ((int)-1) /* Invalid OSP handle, provider, transaction etc. */
-#define OSP_CONFIG_FILE ((const char*)"osp.conf") /* OSP configuration file name */
-#define OSP_GENERAL_CAT ((const char*)"general") /* OSP global configuration context name */
-#define OSP_DEF_PROVIDER ((const char*)"default") /* OSP default provider context name */
-#define OSP_MAX_CERTS ((unsigned int)10) /* OSP max number of cacerts */
-#define OSP_MAX_SRVS ((unsigned int)10) /* OSP max number of service points */
-#define OSP_DEF_MAXCONNECTIONS ((unsigned int)20) /* OSP default max_connections */
-#define OSP_MIN_MAXCONNECTIONS ((unsigned int)1) /* OSP min max_connections */
-#define OSP_MAX_MAXCONNECTIONS ((unsigned int)1000) /* OSP max max_connections */
-#define OSP_DEF_RETRYDELAY ((unsigned int)0) /* OSP default retry delay */
-#define OSP_MIN_RETRYDELAY ((unsigned int)0) /* OSP min retry delay */
-#define OSP_MAX_RETRYDELAY ((unsigned int)10) /* OSP max retry delay */
-#define OSP_DEF_RETRYLIMIT ((unsigned int)2) /* OSP default retry times */
-#define OSP_MIN_RETRYLIMIT ((unsigned int)0) /* OSP min retry times */
-#define OSP_MAX_RETRYLIMIT ((unsigned int)100) /* OSP max retry times */
-#define OSP_DEF_TIMEOUT ((unsigned int)500) /* OSP default timeout in ms */
-#define OSP_MIN_TIMEOUT ((unsigned int)200) /* OSP min timeout in ms */
-#define OSP_MAX_TIMEOUT ((unsigned int)10000) /* OSP max timeout in ms */
-#define OSP_DEF_AUTHPOLICY ((enum osp_authpolicy)OSP_AUTH_YES)
-#define OSP_AUDIT_URL ((const char*)"localhost") /* OSP default Audit URL */
-#define OSP_LOCAL_VALIDATION ((int)1) /* Validate OSP token locally */
-#define OSP_SSL_LIFETIME ((unsigned int)300) /* SSL life time, in seconds */
-#define OSP_HTTP_PERSISTENCE ((int)1) /* In seconds */
-#define OSP_CUSTOMER_ID ((const char*)"") /* OSP customer ID */
-#define OSP_DEVICE_ID ((const char*)"") /* OSP device ID */
-#define OSP_DEF_DESTINATIONS ((unsigned int)5) /* OSP default max number of destinations */
-#define OSP_DEF_TIMELIMIT ((unsigned int)0) /* OSP default duration limit, no limit */
-
-/* OSP Authentication Policy */
-enum osp_authpolicy {
- OSP_AUTH_NO, /* Accept any call */
- OSP_AUTH_YES, /* Accept call with valid OSP token or without OSP token */
- OSP_AUTH_EXCLUSIVE /* Only accept call with valid OSP token */
-};
-
-/* OSP Provider */
-struct osp_provider {
- char name[OSP_NORSTR_SIZE]; /* OSP provider context name */
- char privatekey[OSP_NORSTR_SIZE]; /* OSP private key file name */
- char localcert[OSP_NORSTR_SIZE]; /* OSP local cert file name */
- unsigned int cacount; /* Number of cacerts */
- char cacerts[OSP_MAX_CERTS][OSP_NORSTR_SIZE]; /* Cacert file names */
- unsigned int spcount; /* Number of service points */
- char srvpoints[OSP_MAX_SRVS][OSP_NORSTR_SIZE]; /* Service point URLs */
- int maxconnections; /* Max number of connections */
- int retrydelay; /* Retry delay */
- int retrylimit; /* Retry limit */
- int timeout; /* Timeout in ms */
- char source[OSP_NORSTR_SIZE]; /* IP of self */
- enum osp_authpolicy authpolicy; /* OSP authentication policy */
- OSPTPROVHANDLE handle; /* OSP provider handle */
- struct osp_provider* next; /* Pointer to next OSP provider */
-};
-
-/* OSP Application In/Output Results */
-struct osp_result {
- int inhandle; /* Inbound transaction handle */
- int outhandle; /* Outbound transaction handle */
- unsigned int intimelimit; /* Inbound duration limit */
- unsigned int outtimelimit; /* Outbound duration limit */
- char tech[20]; /* Asterisk TECH string */
- char dest[OSP_NORSTR_SIZE]; /* Destination in called@IP format */
- char calling[OSP_NORSTR_SIZE]; /* Calling number, may be translated */
- char token[OSP_TOKSTR_SIZE]; /* Outbound OSP token */
- unsigned int numresults; /* Number of remain destinations */
-};
-
-/* OSP Module Global Variables */
-AST_MUTEX_DEFINE_STATIC(osplock); /* Lock of OSP provider list */
-static int osp_initialized = 0; /* Init flag */
-static int osp_hardware = 0; /* Hardware accelleration flag */
-static struct osp_provider* ospproviders = NULL; /* OSP provider list */
-static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED; /* Token format supported */
-
-/* OSP Client Wrapper APIs */
-
-/*!
- * \brief Create OSP provider handle according to configuration
- * \param cfg OSP configuration
- * \param provider OSP provider context name
- * \return 1 Success, 0 Failed, -1 Error
- */
-static int osp_create_provider(struct ast_config* cfg, const char* provider)
-{
- int res;
- unsigned int t, i, j;
- struct osp_provider* p;
- struct ast_variable* v;
- OSPTPRIVATEKEY privatekey;
- OSPTCERT localcert;
- const char* psrvpoints[OSP_MAX_SRVS];
- OSPTCERT cacerts[OSP_MAX_CERTS];
- const OSPTCERT* pcacerts[OSP_MAX_CERTS];
- int error = OSPC_ERR_NO_ERROR;
-
- if (!(p = ast_calloc(1, sizeof(*p)))) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return -1;
- }
-
- ast_copy_string(p->name, provider, sizeof(p->name));
- snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, provider);
- snprintf(p->localcert, sizeof(p->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, provider);
- p->maxconnections = OSP_DEF_MAXCONNECTIONS;
- p->retrydelay = OSP_DEF_RETRYDELAY;
- p->retrylimit = OSP_DEF_RETRYLIMIT;
- p->timeout = OSP_DEF_TIMEOUT;
- p->authpolicy = OSP_DEF_AUTHPOLICY;
- p->handle = OSP_INVALID_HANDLE;
-
- v = ast_variable_browse(cfg, provider);
- while(v) {
- if (!strcasecmp(v->name, "privatekey")) {
- if (v->value[0] == '/') {
- ast_copy_string(p->privatekey, v->value, sizeof(p->privatekey));
- } else {
- snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s", ast_config_AST_KEY_DIR, v->value);
- }
- ast_log(LOG_DEBUG, "OSP: privatekey '%s'\n", p->privatekey);
- } else if (!strcasecmp(v->name, "localcert")) {
- if (v->value[0] == '/') {
- ast_copy_string(p->localcert, v->value, sizeof(p->localcert));
- } else {
- snprintf(p->localcert, sizeof(p->localcert), "%s/%s", ast_config_AST_KEY_DIR, v->value);
- }
- ast_log(LOG_DEBUG, "OSP: localcert '%s'\n", p->localcert);
- } else if (!strcasecmp(v->name, "cacert")) {
- if (p->cacount < OSP_MAX_CERTS) {
- if (v->value[0] == '/') {
- ast_copy_string(p->cacerts[p->cacount], v->value, sizeof(p->cacerts[0]));
- } else {
- snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s", ast_config_AST_KEY_DIR, v->value);
- }
- ast_log(LOG_DEBUG, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
- p->cacount++;
- } else {
- ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", v->lineno);
- }
- } else if (!strcasecmp(v->name, "servicepoint")) {
- if (p->spcount < OSP_MAX_SRVS) {
- ast_copy_string(p->srvpoints[p->spcount], v->value, sizeof(p->srvpoints[0]));
- ast_log(LOG_DEBUG, "OSP: servicepoint[%d]: '%s'\n", p->spcount, p->srvpoints[p->spcount]);
- p->spcount++;
- } else {
- ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", v->lineno);
- }
- } else if (!strcasecmp(v->name, "maxconnections")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_MAXCONNECTIONS) && (t <= OSP_MAX_MAXCONNECTIONS)) {
- p->maxconnections = t;
- ast_log(LOG_DEBUG, "OSP: maxconnections '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: maxconnections should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_MAXCONNECTIONS, OSP_MAX_MAXCONNECTIONS, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "retrydelay")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_RETRYDELAY) && (t <= OSP_MAX_RETRYDELAY)) {
- p->retrydelay = t;
- ast_log(LOG_DEBUG, "OSP: retrydelay '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "retrylimit")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_RETRYLIMIT) && (t <= OSP_MAX_RETRYLIMIT)) {
- p->retrylimit = t;
- ast_log(LOG_DEBUG, "OSP: retrylimit '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "timeout")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_TIMEOUT) && (t <= OSP_MAX_TIMEOUT)) {
- p->timeout = t;
- ast_log(LOG_DEBUG, "OSP: timeout '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "source")) {
- ast_copy_string(p->source, v->value, sizeof(p->source));
- ast_log(LOG_DEBUG, "OSP: source '%s'\n", p->source);
- } else if (!strcasecmp(v->name, "authpolicy")) {
- if ((sscanf(v->value, "%d", &t) == 1) && ((t == OSP_AUTH_NO) || (t == OSP_AUTH_YES) || (t == OSP_AUTH_EXCLUSIVE))) {
- p->authpolicy = t;
- ast_log(LOG_DEBUG, "OSP: authpolicy '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
- OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXCLUSIVE, v->value, v->lineno);
- }
- }
- v = v->next;
- }
-
- error = OSPPUtilLoadPEMPrivateKey((unsigned char *) p->privatekey, &privatekey);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s', error '%d'\n", p->privatekey, error);
- free(p);
- return 0;
- }
-
- error = OSPPUtilLoadPEMCert((unsigned char *) p->localcert, &localcert);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s', error '%d'\n", p->localcert, error);
- if (privatekey.PrivateKeyData) {
- free(privatekey.PrivateKeyData);
- }
- free(p);
- return 0;
- }
-
- if (p->cacount < 1) {
- snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s-cacert.pem", ast_config_AST_KEY_DIR, provider);
- ast_log(LOG_DEBUG, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
- p->cacount++;
- }
- for (i = 0; i < p->cacount; i++) {
- error = OSPPUtilLoadPEMCert((unsigned char *) p->cacerts[i], &cacerts[i]);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s', error '%d'\n", p->cacerts[i], error);
- for (j = 0; j < i; j++) {
- if (cacerts[j].CertData) {
- free(cacerts[j].CertData);
- }
- }
- if (localcert.CertData) {
- free(localcert.CertData);
- }
- if (privatekey.PrivateKeyData) {
- free(privatekey.PrivateKeyData);
- }
- free(p);
- return 0;
- }
- pcacerts[i] = &cacerts[i];
- }
-
- for (i = 0; i < p->spcount; i++) {
- psrvpoints[i] = p->srvpoints[i];
- }
-
- error = OSPPProviderNew(p->spcount, psrvpoints, NULL, OSP_AUDIT_URL, &privatekey, &localcert, p->cacount, pcacerts, OSP_LOCAL_VALIDATION,
- OSP_SSL_LIFETIME, p->maxconnections, OSP_HTTP_PERSISTENCE, p->retrydelay, p->retrylimit,p->timeout, OSP_CUSTOMER_ID,
- OSP_DEVICE_ID, &p->handle);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to create provider '%s', error '%d'\n", provider, error);
- free(p);
- res = -1;
- } else {
- ast_log(LOG_DEBUG, "OSP: provider '%s'\n", provider);
- ast_mutex_lock(&osplock);
- p->next = ospproviders;
- ospproviders = p;
- ast_mutex_unlock(&osplock);
- res = 1;
- }
-
- for (i = 0; i < p->cacount; i++) {
- if (cacerts[i].CertData) {
- free(cacerts[i].CertData);
- }
- }
- if (localcert.CertData) {
- free(localcert.CertData);
- }
- if (privatekey.PrivateKeyData) {
- free(privatekey.PrivateKeyData);
- }
-
- return res;
-}
-
-/*!
- * \brief Get OSP authenticiation policy of provider
- * \param provider OSP provider context name
- * \param policy OSP authentication policy, output
- * \return 1 Success, 0 Failed, -1 Error
- */
-static int osp_get_policy(const char* provider, int* policy)
-{
- int res = 0;
- struct osp_provider* p;
-
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- if (!strcasecmp(p->name, provider)) {
- *policy = p->authpolicy;
- ast_log(LOG_DEBUG, "OSP: authpolicy '%d'\n", *policy);
- res = 1;
- break;
- }
- p = p->next;
- }
- ast_mutex_unlock(&osplock);
-
- return res;
-}
-
-/*!
- * \brief Create OSP transaction handle
- * \param provider OSP provider context name
- * \param transaction OSP transaction handle, output
- * \param sourcesize Size of source buffer, in/output
- * \param source Source of provider, output
- * \return 1 Success, 0 Failed, -1 Error
- */
-static int osp_create_transaction(const char* provider, int* transaction, unsigned int sourcesize, char* source)
-{
- int res = 0;
- struct osp_provider* p;
- int error;
-
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- if (!strcasecmp(p->name, provider)) {
- error = OSPPTransactionNew(p->handle, transaction);
- if (error == OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: transaction '%d'\n", *transaction);
- ast_copy_string(source, p->source, sourcesize);
- ast_log(LOG_DEBUG, "OSP: source '%s'\n", source);
- res = 1;
- } else {
- *transaction = OSP_INVALID_HANDLE;
- ast_log(LOG_DEBUG, "OSP: Unable to create transaction handle, error '%d'\n", error);
- res = -1;
- }
- break;
- }
- p = p->next;
- }
- ast_mutex_unlock(&osplock);
-
- return res;
-}
-
-/*!
- * \brief Convert address to "[x.x.x.x]" or "host.domain" format
- * \param src Source address string
- * \param dst Destination address string
- * \param buffersize Size of dst buffer
- */
-static void osp_convert_address(
- const char* src,
- char* dst,
- int buffersize)
-{
- struct in_addr inp;
-
- if (inet_aton(src, &inp) != 0) {
- snprintf(dst, buffersize, "[%s]", src);
- } else {
- snprintf(dst, buffersize, "%s", src);
- }
-}
-
-/*!
- * \brief Validate OSP token of inbound call
- * \param transaction OSP transaction handle
- * \param source Source of inbound call
- * \param dest Destination of inbound call
- * \param calling Calling number
- * \param called Called number
- * \param token OSP token, may be empty
- * \param timelimit Call duration limit, output
- * \return 1 Success, 0 Failed, -1 Error
- */
-static int osp_validate_token(int transaction, const char* source, const char* dest, const char* calling, const char* called, const char* token, unsigned int* timelimit)
-{
- int res;
- int tokenlen;
- unsigned char tokenstr[OSP_TOKSTR_SIZE];
- char src[OSP_NORSTR_SIZE];
- char dst[OSP_NORSTR_SIZE];
- unsigned int authorised;
- unsigned int dummy = 0;
- int error;
-
- tokenlen = ast_base64decode(tokenstr, token, strlen(token));
- osp_convert_address(source, src, sizeof(src));
- osp_convert_address(dest, dst, sizeof(dst));
- error = OSPPTransactionValidateAuthorisation(
- transaction,
- src, dst, NULL, NULL,
- calling ? calling : "", OSPC_E164,
- called, OSPC_E164,
- 0, NULL,
- tokenlen, (char *) tokenstr,
- &authorised,
- timelimit,
- &dummy, NULL,
- osp_tokenformat);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Unable to validate inbound token\n");
- res = -1;
- } else if (authorised) {
- ast_log(LOG_DEBUG, "OSP: Authorised\n");
- res = 1;
- } else {
- ast_log(LOG_DEBUG, "OSP: Unauthorised\n");
- res = 0;
- }
-
- return res;
-}
-
-/*!
- * \brief Choose min duration limit
- * \param in Inbound duration limit
- * \param out Outbound duration limit
- * \return min duration limit
- */
-static unsigned int osp_choose_timelimit(unsigned int in, unsigned int out)
-{
- if (in == OSP_DEF_TIMELIMIT) {
- return out;
- } else if (out == OSP_DEF_TIMELIMIT) {
- return in;
- } else {
- return in < out ? in : out;
- }
-}
-
-/*!
- * \brief Choose min duration limit
- * \param called Called number
- * \param calling Calling number
- * \param destination Destination IP in '[x.x.x.x]' format
- * \param tokenlen OSP token length
- * \param token OSP token
- * \param reason Failure reason, output
- * \param result OSP lookup results, in/output
- * \return 1 Success, 0 Failed, -1 Error
- */
-static int osp_check_destination(const char* called, const char* calling, char* destination, unsigned int tokenlen, const char* token, enum OSPEFAILREASON* reason, struct osp_result* result)
-{
- int res;
- OSPE_DEST_OSP_ENABLED enabled;
- OSPE_DEST_PROT protocol;
- int error;
-
- if (strlen(destination) <= 2) {
- ast_log(LOG_DEBUG, "OSP: Wrong destination format '%s'\n", destination);
- *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
- return -1;
- }
-
- if ((error = OSPPTransactionIsDestOSPEnabled(result->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Unable to get destination OSP version, error '%d'\n", error);
- *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
- return -1;
- }
-
- if (enabled == OSPE_OSP_FALSE) {
- result->token[0] = '\0';
- } else {
- ast_base64encode(result->token, (const unsigned char *) token, tokenlen, sizeof(result->token) - 1);
- }
-
- if ((error = OSPPTransactionGetDestProtocol(result->outhandle, &protocol)) != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Unable to get destination protocol, error '%d'\n", error);
- *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
- result->token[0] = '\0';
- return -1;
- }
-
- res = 1;
- /* Strip leading and trailing brackets */
- destination[strlen(destination) - 1] = '\0';
- switch(protocol) {
- case OSPE_DEST_PROT_H323_SETUP:
- ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
- ast_copy_string(result->tech, "H323", sizeof(result->tech));
- snprintf(result->dest, sizeof(result->dest), "%s@%s", called, destination + 1);
- ast_copy_string(result->calling, calling, sizeof(result->calling));
- break;
- case OSPE_DEST_PROT_SIP:
- ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
- ast_copy_string(result->tech, "SIP", sizeof(result->tech));
- snprintf(result->dest, sizeof(result->dest), "%s@%s", called, destination + 1);
- ast_copy_string(result->calling, calling, sizeof(result->calling));
- break;
- case OSPE_DEST_PROT_IAX:
- ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
- ast_copy_string(result->tech, "IAX", sizeof(result->tech));
- snprintf(result->dest, sizeof(result->dest), "%s@%s", called, destination + 1);
- ast_copy_string(result->calling, calling, sizeof(result->calling));
- break;
- default:
- ast_log(LOG_DEBUG, "OSP: Unknown protocol '%d'\n", protocol);
- *reason = OSPC_FAIL_PROTOCOL_ERROR;
- result->token[0] = '\0';
- res = 0;
- }
-
- return res;
-}
-
-/*!
- * \brief Convert Asterisk status to TC code
- * \param cause Asterisk hangup cause
- * \return OSP TC code
- */
-static enum OSPEFAILREASON asterisk2osp(int cause)
-{
- return (enum OSPEFAILREASON)cause;
-}
-
-/*!
- * \brief OSP Authentication function
- * \param provider OSP provider context name
- * \param transaction OSP transaction handle, output
- * \param source Source of inbound call
- * \param calling Calling number
- * \param called Called number
- * \param token OSP token, may be empty
- * \param timelimit Call duration limit, output
- * \return 1 Authenricated, 0 Unauthenticated, -1 Error
- */
-static int osp_auth(const char* provider, int* transaction, const char* source, const char* calling, const char* called, const char* token, unsigned int* timelimit)
-{
- int res;
- int policy = OSP_AUTH_YES;
- char dest[OSP_NORSTR_SIZE];
-
- *transaction = OSP_INVALID_HANDLE;
- *timelimit = OSP_DEF_TIMELIMIT;
- res = osp_get_policy(provider, &policy);
- if (!res) {
- ast_log(LOG_DEBUG, "OSP: Unabe to find OSP authentication policy\n");
- return res;
- }
-
- switch (policy) {
- case OSP_AUTH_NO:
- res = 1;
- break;
- case OSP_AUTH_EXCLUSIVE:
- if (ast_strlen_zero(token)) {
- res = 0;
- } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
- ast_log(LOG_DEBUG, "OSP: Unable to generate transaction handle\n");
- *transaction = OSP_INVALID_HANDLE;
- res = 0;
- } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
- OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
- }
- break;
- case OSP_AUTH_YES:
- default:
- if (ast_strlen_zero(token)) {
- res = 1;
- } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
- ast_log(LOG_DEBUG, "OSP: Unable to generate transaction handle\n");
- *transaction = OSP_INVALID_HANDLE;
- res = 0;
- } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
- OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
- }
- break;
- }
-
- return res;
-}
-
-/*!
- * \brief OSP Lookup function
- * \param provider OSP provider context name
- * \param srcdev Source device of outbound call
- * \param calling Calling number
- * \param called Called number
- * \param result Lookup results
- * \return 1 Found , 0 No route, -1 Error
- */
-static int osp_lookup(const char* provider, const char* srcdev, const char* calling, const char* called, struct osp_result* result)
-{
- int res;
- char source[OSP_NORSTR_SIZE];
- unsigned int callidlen;
- char callid[OSPC_CALLID_MAXSIZE];
- char callingnum[OSP_NORSTR_SIZE];
- char callednum[OSP_NORSTR_SIZE];
- char destination[OSP_NORSTR_SIZE];
- unsigned int tokenlen;
- char token[OSP_TOKSTR_SIZE];
- char src[OSP_NORSTR_SIZE];
- char dev[OSP_NORSTR_SIZE];
- unsigned int dummy = 0;
- enum OSPEFAILREASON reason;
- int error;
-
- result->outhandle = OSP_INVALID_HANDLE;
- result->tech[0] = '\0';
- result->dest[0] = '\0';
- result->calling[0] = '\0';
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
-
- if ((res = osp_create_transaction(provider, &result->outhandle, sizeof(source), source)) <= 0) {
- ast_log(LOG_DEBUG, "OSP: Unable to generate transaction handle\n");
- result->outhandle = OSP_INVALID_HANDLE;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- }
- return -1;
- }
-
- osp_convert_address(source, src, sizeof(src));
- osp_convert_address(srcdev, dev, sizeof(dev));
- result->numresults = OSP_DEF_DESTINATIONS;
- error = OSPPTransactionRequestAuthorisation(result->outhandle, src, dev, calling ? calling : "",
- OSPC_E164, called, OSPC_E164, NULL, 0, NULL, NULL, &result->numresults, &dummy, NULL);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Unable to request authorization\n");
- result->numresults = 0;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- }
- return -1;
- }
-
- if (!result->numresults) {
- ast_log(LOG_DEBUG, "OSP: No more destination\n");
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- return 0;
- }
-
- callidlen = sizeof(callid);
- tokenlen = sizeof(token);
- error = OSPPTransactionGetFirstDestination(result->outhandle, 0, NULL, NULL, &result->outtimelimit, &callidlen, callid,
- sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Unable to get first route\n");
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- return -1;
- }
-
- result->numresults--;
- result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
- ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
- ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
- ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
-
- if ((res = osp_check_destination(callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
- return 1;
- }
-
- if (!result->numresults) {
- ast_log(LOG_DEBUG, "OSP: No more destination\n");
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- OSPPTransactionRecordFailure(result->outhandle, reason);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- return 0;
- }
-
- while(result->numresults) {
- callidlen = sizeof(callid);
- tokenlen = sizeof(token);
- error = OSPPTransactionGetNextDestination(result->outhandle, reason, 0, NULL, NULL, &result->outtimelimit, &callidlen, callid,
- sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token);
- if (error == OSPC_ERR_NO_ERROR) {
- result->numresults--;
- result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
- ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
- ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
- ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
- if ((res = osp_check_destination(callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
- break;
- } else if (!result->numresults) {
- ast_log(LOG_DEBUG, "OSP: No more destination\n");
- OSPPTransactionRecordFailure(result->outhandle, reason);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- res = 0;
- break;
- }
- } else {
- ast_log(LOG_DEBUG, "OSP: Unable to get route, error '%d'\n", error);
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- }
- res = -1;
- break;
- }
- }
- return res;
-}
-
-/*!
- * \brief OSP Lookup Next function
- * \param cause Asterisk hangup cuase
- * \param result Lookup results, in/output
- * \return 1 Found , 0 No route, -1 Error
- */
-static int osp_next(int cause, struct osp_result* result)
-{
- int res;
- unsigned int callidlen;
- char callid[OSPC_CALLID_MAXSIZE];
- char callingnum[OSP_NORSTR_SIZE];
- char callednum[OSP_NORSTR_SIZE];
- char destination[OSP_NORSTR_SIZE];
- unsigned int tokenlen;
- char token[OSP_TOKSTR_SIZE];
- enum OSPEFAILREASON reason;
- int error;
-
- result->tech[0] = '\0';
- result->dest[0] = '\0';
- result->calling[0] = '\0';
- result->token[0] = '\0';
- result->outtimelimit = OSP_DEF_TIMELIMIT;
-
- if (result->outhandle == OSP_INVALID_HANDLE) {
- ast_log(LOG_DEBUG, "OSP: Transaction handle undefined\n");
- result->numresults = 0;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- }
- return -1;
- }
-
- reason = asterisk2osp(cause);
-
- if (!result->numresults) {
- ast_log(LOG_DEBUG, "OSP: No more destination\n");
- OSPPTransactionRecordFailure(result->outhandle, reason);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- return 0;
- }
-
- while(result->numresults) {
- callidlen = sizeof(callid);
- tokenlen = sizeof(token);
- error = OSPPTransactionGetNextDestination(result->outhandle, reason, 0, NULL, NULL, &result->outtimelimit, &callidlen,
- callid, sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token);
- if (error == OSPC_ERR_NO_ERROR) {
- result->numresults--;
- result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
- ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
- ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
- ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
- if ((res = osp_check_destination(callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
- res = 1;
- break;
- } else if (!result->numresults) {
- ast_log(LOG_DEBUG, "OSP: No more destination\n");
- OSPPTransactionRecordFailure(result->outhandle, reason);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- res = 0;
- break;
- }
- } else {
- ast_log(LOG_DEBUG, "OSP: Unable to get route, error '%d'\n", error);
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- }
- res = -1;
- break;
- }
- }
-
- return res;
-}
-
-/*!
- * \brief OSP Finish function
- * \param handle OSP in/outbound transaction handle
- * \param recorded If failure reason has been recorded
- * \param cause Asterisk hangup cause
- * \param start Call start time
- * \param connect Call connect time
- * \param end Call end time
- * \param release Who release first, 0 source, 1 destination
- * \return 1 Success, 0 Failed, -1 Error
- */
-static int osp_finish(int handle, int recorded, int cause, time_t start, time_t connect, time_t end, unsigned int release)
-{
- int res;
- enum OSPEFAILREASON reason;
- time_t alert = 0;
- unsigned isPddInfoPresent = 0;
- unsigned pdd = 0;
- unsigned int dummy = 0;
- int error;
-
- if (handle == OSP_INVALID_HANDLE) {
- return 0;
- }
-
- if (!recorded) {
- reason = asterisk2osp(cause);
- OSPPTransactionRecordFailure(handle, reason);
- }
-
- error = OSPPTransactionReportUsage(handle, difftime(end, connect), start, end, alert, connect, isPddInfoPresent, pdd,
- release, (unsigned char *) "", 0, 0, 0, 0, &dummy, NULL);
- if (error == OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Usage reported\n");
- res = 1;
- } else {
- ast_log(LOG_DEBUG, "OSP: Unable to report usage, error '%d'\n", error);
- res = -1;
- }
- OSPPTransactionDelete(handle);
-
- return res;
-}
-
-/* OSP Application APIs */
-
-/*!
- * \brief OSP Application OSPAuth
- * \param chan Channel
- * \param data Parameter
- * \return 0 Success, -1 Failed
- */
-static int ospauth_exec(struct ast_channel* chan, void* data)
-{
- int res;
- struct ast_module_user *u;
- const char* provider = OSP_DEF_PROVIDER;
- int priority_jump = 0;
- struct varshead *headp;
- struct ast_var_t *current;
- const char *source = "";
- const char *token = "";
- int handle;
- unsigned int timelimit;
- char buffer[OSP_INTSTR_SIZE];
- const char *status;
- char *tmp;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(provider);
- AST_APP_ARG(options);
- );
-
- u = ast_module_user_add(chan);
-
- if (!(tmp = ast_strdupa(data))) {
- ast_log(LOG_ERROR, "Out of memory\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, tmp);
-
- if (!ast_strlen_zero(args.provider)) {
- provider = args.provider;
- }
- ast_log(LOG_DEBUG, "OSPAuth: provider '%s'\n", provider);
-
- if ((args.options) && (strchr(args.options, 'j'))) {
- priority_jump = 1;
- }
- ast_log(LOG_DEBUG, "OSPAuth: priority jump '%d'\n", priority_jump);
-
- headp = &chan->varshead;
- AST_LIST_TRAVERSE(headp, current, entries) {
- if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
- source = ast_var_value(current);
- } else if (!strcasecmp(ast_var_name(current), "OSPINTOKEN")) {
- token = ast_var_value(current);
- }
- }
- ast_log(LOG_DEBUG, "OSPAuth: source '%s'\n", source);
- ast_log(LOG_DEBUG, "OSPAuth: token size '%zd'\n", strlen(token));
-
-
- if ((res = osp_auth(provider, &handle, source, chan->cid.cid_num, chan->exten, token, &timelimit)) > 0) {
- status = AST_OSP_SUCCESS;
- } else {
- timelimit = OSP_DEF_TIMELIMIT;
- if (!res) {
- status = AST_OSP_FAILED;
- } else {
- status = AST_OSP_ERROR;
- }
- }
-
- snprintf(buffer, sizeof(buffer), "%d", handle);
- pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
- ast_log(LOG_DEBUG, "OSPAuth: OSPINHANDLE '%s'\n", buffer);
- snprintf(buffer, sizeof(buffer), "%d", timelimit);
- pbx_builtin_setvar_helper(chan, "OSPINTIMELIMIT", buffer);
- ast_log(LOG_DEBUG, "OSPAuth: OSPINTIMELIMIT '%s'\n", buffer);
- pbx_builtin_setvar_helper(chan, "OSPAUTHSTATUS", status);
- ast_log(LOG_DEBUG, "OSPAuth: %s\n", status);
-
- if(res <= 0) {
- if (priority_jump || ast_opt_priority_jumping) {
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- } else {
- res = -1;
- }
- } else {
- res = 0;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*!
- * \brief OSP Application OSPLookup
- * \param chan Channel
- * \param data Parameter
- * \return 0 Success, -1 Failed
- */
-static int osplookup_exec(struct ast_channel* chan, void* data)
-{
- int res, cres;
- struct ast_module_user *u;
- const char *provider = OSP_DEF_PROVIDER;
- int priority_jump = 0;
- struct varshead *headp;
- struct ast_var_t* current;
- const char *srcdev = "";
- char buffer[OSP_TOKSTR_SIZE];
- struct osp_result result;
- const char *status;
- char *tmp;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(exten);
- AST_APP_ARG(provider);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "OSPLookup: Arg required, OSPLookup(exten[|provider[|options]])\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (!(tmp = ast_strdupa(data))) {
- ast_log(LOG_ERROR, "Out of memory\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, tmp);
-
- ast_log(LOG_DEBUG, "OSPLookup: exten '%s'\n", args.exten);
-
- if (!ast_strlen_zero(args.provider)) {
- provider = args.provider;
- }
- ast_log(LOG_DEBUG, "OSPlookup: provider '%s'\n", provider);
-
- if ((args.options) && (strchr(args.options, 'j'))) {
- priority_jump = 1;
- }
- ast_log(LOG_DEBUG, "OSPLookup: priority jump '%d'\n", priority_jump);
-
- result.inhandle = OSP_INVALID_HANDLE;
- result.intimelimit = OSP_DEF_TIMELIMIT;
-
- headp = &chan->varshead;
- AST_LIST_TRAVERSE(headp, current, entries) {
- if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
- if (sscanf(ast_var_value(current), "%d", &result.inhandle) != 1) {
- result.inhandle = OSP_INVALID_HANDLE;
- }
- } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
- if (sscanf(ast_var_value(current), "%d", &result.intimelimit) != 1) {
- result.intimelimit = OSP_DEF_TIMELIMIT;
- }
- } else if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
- srcdev = ast_var_value(current);
- }
- }
- ast_log(LOG_DEBUG, "OSPLookup: OSPINHANDLE '%d'\n", result.inhandle);
- ast_log(LOG_DEBUG, "OSPLookup: OSPINTIMELIMIT '%d'\n", result.intimelimit);
- ast_log(LOG_DEBUG, "OSPLookup: source device '%s'\n", srcdev);
-
- if ((cres = ast_autoservice_start(chan)) < 0) {
- ast_module_user_remove(u);
- return -1;
- }
-
- if ((res = osp_lookup(provider, srcdev, chan->cid.cid_num, args.exten, &result)) > 0) {
- status = AST_OSP_SUCCESS;
- } else {
- result.tech[0] = '\0';
- result.dest[0] = '\0';
- result.calling[0] = '\0';
- result.token[0] = '\0';
- result.numresults = 0;
- result.outtimelimit = OSP_DEF_TIMELIMIT;
- if (!res) {
- status = AST_OSP_FAILED;
- } else {
- status = AST_OSP_ERROR;
- }
- }
-
- snprintf(buffer, sizeof(buffer), "%d", result.outhandle);
- pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
- ast_log(LOG_DEBUG, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer);
- pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
- ast_log(LOG_DEBUG, "OSPLookup: OSPTECH '%s'\n", result.tech);
- pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
- ast_log(LOG_DEBUG, "OSPLookup: OSPDEST '%s'\n", result.dest);
- pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling);
- ast_log(LOG_DEBUG, "OSPLookup: OSPCALLING '%s'\n", result.calling);
- pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token);
- ast_log(LOG_DEBUG, "OSPLookup: OSPOUTTOKEN size '%zd'\n", strlen(result.token));
- snprintf(buffer, sizeof(buffer), "%d", result.numresults);
- pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
- ast_log(LOG_DEBUG, "OSPLookup: OSPRESULTS '%s'\n", buffer);
- snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit);
- pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
- ast_log(LOG_DEBUG, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer);
- pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status);
- ast_log(LOG_DEBUG, "OSPLookup: %s\n", status);
-
- if (!strcasecmp(result.tech, "SIP")) {
- if (!ast_strlen_zero(result.token)) {
- snprintf(buffer, sizeof(buffer), "P-OSP-Auth-Token: %s", result.token);
- pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
- ast_log(LOG_DEBUG, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
- }
- } else if (!strcasecmp(result.tech, "H323")) {
- } else if (!strcasecmp(result.tech, "IAX")) {
- }
-
- if ((cres = ast_autoservice_stop(chan)) < 0) {
- ast_module_user_remove(u);
- return -1;
- }
-
- if(res <= 0) {
- if (priority_jump || ast_opt_priority_jumping) {
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- } else {
- res = -1;
- }
- } else {
- res = 0;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*!
- * \brief OSP Application OSPNext
- * \param chan Channel
- * \param data Parameter
- * \return 0 Success, -1 Failed
- */
-static int ospnext_exec(struct ast_channel* chan, void* data)
-{
- int res;
- struct ast_module_user *u;
- int priority_jump = 0;
- int cause = 0;
- struct varshead* headp;
- struct ast_var_t* current;
- struct osp_result result;
- char buffer[OSP_TOKSTR_SIZE];
- const char* status;
- char* tmp;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(cause);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "OSPNext: Arg required, OSPNext(cause[|options])\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (!(tmp = ast_strdupa(data))) {
- ast_log(LOG_ERROR, "Out of memory\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, tmp);
-
- if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%d", &cause) != 1) {
- cause = 0;
- }
- ast_log(LOG_DEBUG, "OSPNext: cause '%d'\n", cause);
-
- if ((args.options) && (strchr(args.options, 'j'))) {
- priority_jump = 1;
- }
- ast_log(LOG_DEBUG, "OSPNext: priority jump '%d'\n", priority_jump);
-
- result.inhandle = OSP_INVALID_HANDLE;
- result.outhandle = OSP_INVALID_HANDLE;
- result.intimelimit = OSP_DEF_TIMELIMIT;
- result.numresults = 0;
-
- headp = &chan->varshead;
- AST_LIST_TRAVERSE(headp, current, entries) {
- if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
- if (sscanf(ast_var_value(current), "%d", &result.inhandle) != 1) {
- result.inhandle = OSP_INVALID_HANDLE;
- }
- } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
- if (sscanf(ast_var_value(current), "%d", &result.outhandle) != 1) {
- result.outhandle = OSP_INVALID_HANDLE;
- }
- } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
- if (sscanf(ast_var_value(current), "%d", &result.intimelimit) != 1) {
- result.intimelimit = OSP_DEF_TIMELIMIT;
- }
- } else if (!strcasecmp(ast_var_name(current), "OSPRESULTS")) {
- if (sscanf(ast_var_value(current), "%d", &result.numresults) != 1) {
- result.numresults = 0;
- }
- }
- }
- ast_log(LOG_DEBUG, "OSPNext: OSPINHANDLE '%d'\n", result.inhandle);
- ast_log(LOG_DEBUG, "OSPNext: OSPOUTHANDLE '%d'\n", result.outhandle);
- ast_log(LOG_DEBUG, "OSPNext: OSPINTIMELIMIT '%d'\n", result.intimelimit);
- ast_log(LOG_DEBUG, "OSPNext: OSPRESULTS '%d'\n", result.numresults);
-
- if ((res = osp_next(cause, &result)) > 0) {
- status = AST_OSP_SUCCESS;
- } else {
- result.tech[0] = '\0';
- result.dest[0] = '\0';
- result.calling[0] = '\0';
- result.token[0] = '\0';
- result.numresults = 0;
- result.outtimelimit = OSP_DEF_TIMELIMIT;
- if (!res) {
- status = AST_OSP_FAILED;
- } else {
- status = AST_OSP_ERROR;
- }
- }
-
- pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
- ast_log(LOG_DEBUG, "OSPNext: OSPTECH '%s'\n", result.tech);
- pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
- ast_log(LOG_DEBUG, "OSPNext: OSPDEST '%s'\n", result.dest);
- pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling);
- ast_log(LOG_DEBUG, "OSPNext: OSPCALLING '%s'\n", result.calling);
- pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token);
- ast_log(LOG_DEBUG, "OSPNext: OSPOUTTOKEN size '%zd'\n", strlen(result.token));
- snprintf(buffer, sizeof(buffer), "%d", result.numresults);
- pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
- ast_log(LOG_DEBUG, "OSPNext: OSPRESULTS '%s'\n", buffer);
- snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit);
- pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
- ast_log(LOG_DEBUG, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer);
- pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status);
- ast_log(LOG_DEBUG, "OSPNext: %s\n", status);
-
- if (!strcasecmp(result.tech, "SIP")) {
- if (!ast_strlen_zero(result.token)) {
- snprintf(buffer, sizeof(buffer), "P-OSP-Auth-Token: %s", result.token);
- pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
- ast_log(LOG_DEBUG, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
- }
- } else if (!strcasecmp(result.tech, "H323")) {
- } else if (!strcasecmp(result.tech, "IAX")) {
- }
-
- if(res <= 0) {
- if (priority_jump || ast_opt_priority_jumping) {
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- } else {
- res = -1;
- }
- } else {
- res = 0;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*!
- * \brief OSP Application OSPFinish
- * \param chan Channel
- * \param data Parameter
- * \return 0 Success, -1 Failed
- */
-static int ospfinished_exec(struct ast_channel* chan, void* data)
-{
- int res = 1;
- struct ast_module_user *u;
- int priority_jump = 0;
- int cause = 0;
- struct varshead *headp;
- struct ast_var_t *current;
- int inhandle = OSP_INVALID_HANDLE;
- int outhandle = OSP_INVALID_HANDLE;
- int recorded = 0;
- time_t start, connect, end;
- unsigned int release;
- char buffer[OSP_INTSTR_SIZE];
- const char *status;
- char *tmp;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(cause);
- AST_APP_ARG(options);
- );
-
- u = ast_module_user_add(chan);
-
- if (!(tmp = ast_strdupa(data))) {
- ast_log(LOG_ERROR, "Out of memory\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, tmp);
-
- if ((args.options) && (strchr(args.options, 'j'))) {
- priority_jump = 1;
- }
- ast_log(LOG_DEBUG, "OSPFinish: priority jump '%d'\n", priority_jump);
-
- headp = &chan->varshead;
- AST_LIST_TRAVERSE(headp, current, entries) {
- if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
- if (sscanf(ast_var_value(current), "%d", &inhandle) != 1) {
- inhandle = OSP_INVALID_HANDLE;
- }
- } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
- if (sscanf(ast_var_value(current), "%d", &outhandle) != 1) {
- outhandle = OSP_INVALID_HANDLE;
- }
- } else if (!recorded &&
- (!strcasecmp(ast_var_name(current), "OSPAUTHSTATUS") ||
- !strcasecmp(ast_var_name(current), "OSPLOOKUPSTATUS") ||
- !strcasecmp(ast_var_name(current), "OSPNEXTSTATUS")))
- {
- if (strcasecmp(ast_var_value(current), AST_OSP_SUCCESS)) {
- recorded = 1;
- }
- }
- }
- ast_log(LOG_DEBUG, "OSPFinish: OSPINHANDLE '%d'\n", inhandle);
- ast_log(LOG_DEBUG, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle);
- ast_log(LOG_DEBUG, "OSPFinish: recorded '%d'\n", recorded);
-
- if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%d", &cause) != 1) {
- cause = 0;
- }
- ast_log(LOG_DEBUG, "OSPFinish: cause '%d'\n", cause);
-
- if (chan->cdr) {
- start = chan->cdr->start.tv_sec;
- connect = chan->cdr->answer.tv_sec;
- if (connect) {
- end = time(NULL);
- } else {
- end = connect;
- }
- } else {
- start = 0;
- connect = 0;
- end = 0;
- }
- ast_log(LOG_DEBUG, "OSPFinish: start '%ld'\n", start);
- ast_log(LOG_DEBUG, "OSPFinish: connect '%ld'\n", connect);
- ast_log(LOG_DEBUG, "OSPFinish: end '%ld'\n", end);
-
- release = chan->_softhangup ? 0 : 1;
-
- if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
- ast_log(LOG_DEBUG, "OSPFinish: Unable to report usage for outbound call\n");
- }
- switch (cause) {
- case AST_CAUSE_NORMAL_CLEARING:
- break;
- default:
- cause = AST_CAUSE_NO_ROUTE_DESTINATION;
- break;
- }
- if (osp_finish(inhandle, recorded, cause, start, connect, end, release) <= 0) {
- ast_log(LOG_DEBUG, "OSPFinish: Unable to report usage for inbound call\n");
- }
- snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE);
- pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
- pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
-
- if (res > 0) {
- status = AST_OSP_SUCCESS;
- } else if (!res) {
- status = AST_OSP_FAILED;
- } else {
- status = AST_OSP_ERROR;
- }
- pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", status);
-
- if(!res) {
- if (priority_jump || ast_opt_priority_jumping) {
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- } else {
- res = -1;
- }
- } else {
- res = 0;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/* OSP Module APIs */
-
-static int osp_load(void)
-{
- const char* t;
- unsigned int v;
- struct ast_config* cfg;
- int error = OSPC_ERR_NO_ERROR;
-
- cfg = ast_config_load(OSP_CONFIG_FILE);
- if (cfg) {
- t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate");
- if (t && ast_true(t)) {
- if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to enable hardware accelleration\n");
- OSPPInit(0);
- } else {
- osp_hardware = 1;
- }
- } else {
- OSPPInit(0);
- }
- ast_log(LOG_DEBUG, "OSP: osp_hardware '%d'\n", osp_hardware);
-
- t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "tokenformat");
- if (t) {
- if ((sscanf(t, "%d", &v) == 1) &&
- ((v == TOKEN_ALGO_SIGNED) || (v == TOKEN_ALGO_UNSIGNED) || (v == TOKEN_ALGO_BOTH)))
- {
- osp_tokenformat = v;
- } else {
- ast_log(LOG_WARNING, "tokenformat should be an integer from %d, %d or %d, not '%s'\n",
- TOKEN_ALGO_SIGNED, TOKEN_ALGO_UNSIGNED, TOKEN_ALGO_BOTH, t);
- }
- }
- ast_log(LOG_DEBUG, "OSP: osp_tokenformat '%d'\n", osp_tokenformat);
-
- t = ast_category_browse(cfg, NULL);
- while(t) {
- if (strcasecmp(t, OSP_GENERAL_CAT)) {
- osp_create_provider(cfg, t);
- }
- t = ast_category_browse(cfg, t);
- }
-
- osp_initialized = 1;
-
- ast_config_destroy(cfg);
- } else {
- ast_log(LOG_WARNING, "OSP: Unable to find configuration. OSP support disabled\n");
- return 0;
- }
- ast_log(LOG_DEBUG, "OSP: osp_initialized '%d'\n", osp_initialized);
-
- return 1;
-}
-
-static int osp_unload(void)
-{
- struct osp_provider* p;
- struct osp_provider* next;
-
- if (osp_initialized) {
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- next = p->next;
- OSPPProviderDelete(p->handle, 0);
- free(p);
- p = next;
- }
- ospproviders = NULL;
- ast_mutex_unlock(&osplock);
-
- OSPPCleanup();
-
- osp_tokenformat = TOKEN_ALGO_SIGNED;
- osp_hardware = 0;
- osp_initialized = 0;
- }
- return 0;
-}
-
-static int osp_show(int fd, int argc, char* argv[])
-{
- int i;
- int found = 0;
- struct osp_provider* p;
- const char* provider = NULL;
- const char* tokenalgo;
-
- if ((argc < 2) || (argc > 3)) {
- return RESULT_SHOWUSAGE;
- }
- if (argc > 2) {
- provider = argv[2];
- }
- if (!provider) {
- switch (osp_tokenformat) {
- case TOKEN_ALGO_BOTH:
- tokenalgo = "Both";
- break;
- case TOKEN_ALGO_UNSIGNED:
- tokenalgo = "Unsigned";
- break;
- case TOKEN_ALGO_SIGNED:
- default:
- tokenalgo = "Signed";
- break;
- }
- ast_cli(fd, "OSP: %s %s %s\n",
- osp_initialized ? "Initialized" : "Uninitialized", osp_hardware ? "Accelerated" : "Normal", tokenalgo);
- }
-
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- if (!provider || !strcasecmp(p->name, provider)) {
- if (found) {
- ast_cli(fd, "\n");
- }
- ast_cli(fd, " == OSP Provider '%s' == \n", p->name);
- ast_cli(fd, "Local Private Key: %s\n", p->privatekey);
- ast_cli(fd, "Local Certificate: %s\n", p->localcert);
- for (i = 0; i < p->cacount; i++) {
- ast_cli(fd, "CA Certificate %d: %s\n", i + 1, p->cacerts[i]);
- }
- for (i = 0; i < p->spcount; i++) {
- ast_cli(fd, "Service Point %d: %s\n", i + 1, p->srvpoints[i]);
- }
- ast_cli(fd, "Max Connections: %d\n", p->maxconnections);
- ast_cli(fd, "Retry Delay: %d seconds\n", p->retrydelay);
- ast_cli(fd, "Retry Limit: %d\n", p->retrylimit);
- ast_cli(fd, "Timeout: %d milliseconds\n", p->timeout);
- ast_cli(fd, "Source: %s\n", strlen(p->source) ? p->source : "<unspecified>");
- ast_cli(fd, "Auth Policy %d\n", p->authpolicy);
- ast_cli(fd, "OSP Handle: %d\n", p->handle);
- found++;
- }
- p = p->next;
- }
- ast_mutex_unlock(&osplock);
-
- if (!found) {
- if (provider) {
- ast_cli(fd, "Unable to find OSP provider '%s'\n", provider);
- } else {
- ast_cli(fd, "No OSP providers configured\n");
- }
- }
- return RESULT_SUCCESS;
-}
-
-static const char* app1= "OSPAuth";
-static const char* synopsis1 = "OSP authentication";
-static const char* descrip1 =
-" OSPAuth([provider[|options]]): Authenticate a SIP INVITE by OSP and sets\n"
-"the variables:\n"
-" ${OSPINHANDLE}: The inbound call transaction handle\n"
-" ${OSPINTIMELIMIT}: The inbound call duration limit in seconds\n"
-"\n"
-"The option string may contain the following character:\n"
-" 'j' -- jump to n+101 priority if the authentication was NOT successful\n"
-"This application sets the following channel variable upon completion:\n"
-" OSPAUTHSTATUS The status of the OSP Auth attempt as a text string, one of\n"
-" SUCCESS | FAILED | ERROR\n";
-
-static const char* app2= "OSPLookup";
-static const char* synopsis2 = "Lookup destination by OSP";
-static const char* descrip2 =
-" OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n"
-"the variables, where 'n' is the number of the result beginning with 1:\n"
-" ${OSPOUTHANDLE}: The OSP Handle for anything remaining\n"
-" ${OSPTECH}: The technology to use for the call\n"
-" ${OSPDEST}: The destination to use for the call\n"
-" ${OSPCALLING}: The calling number to use for the call\n"
-" ${OSPOUTTOKEN}: The actual OSP token as a string\n"
-" ${OSPOUTTIMELIMIT}: The outbound call duration limit in seconds\n"
-" ${OSPRESULTS}: The number of OSP results total remaining\n"
-"\n"
-"The option string may contain the following character:\n"
-" 'j' -- jump to n+101 priority if the lookup was NOT successful\n"
-"This application sets the following channel variable upon completion:\n"
-" OSPLOOKUPSTATUS The status of the OSP Lookup attempt as a text string, one of\n"
-" SUCCESS | FAILED | ERROR\n";
-
-static const char* app3 = "OSPNext";
-static const char* synopsis3 = "Lookup next destination by OSP";
-static const char* descrip3 =
-" OSPNext(cause[|options]): Looks up the next OSP Destination for ${OSPOUTHANDLE}\n"
-"See OSPLookup for more information\n"
-"\n"
-"The option string may contain the following character:\n"
-" 'j' -- jump to n+101 priority if the lookup was NOT successful\n"
-"This application sets the following channel variable upon completion:\n"
-" OSPNEXTSTATUS The status of the OSP Next attempt as a text string, one of\n"
-" SUCCESS | FAILED |ERROR\n";
-
-static const char* app4 = "OSPFinish";
-static const char* synopsis4 = "Record OSP entry";
-static const char* descrip4 =
-" OSPFinish([status[|options]]): Records call state for ${OSPINHANDLE}, according to\n"
-"status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or CHANUNAVAIL\n"
-"or coincidentally, just what the Dial application stores in its ${DIALSTATUS}.\n"
-"\n"
-"The option string may contain the following character:\n"
-" 'j' -- jump to n+101 priority if the finish attempt was NOT successful\n"
-"This application sets the following channel variable upon completion:\n"
-" OSPFINISHSTATUS The status of the OSP Finish attempt as a text string, one of\n"
-" SUCCESS | FAILED |ERROR \n";
-
-static const char osp_usage[] =
-"Usage: osp show\n"
-" Displays information on Open Settlement Protocol support\n";
-
-static struct ast_cli_entry cli_osp[] = {
- { { "osp", "show", NULL},
- osp_show, "Displays OSP information",
- osp_usage },
-};
-
-static int load_module(void)
-{
- int res;
-
- if(!osp_load())
- return AST_MODULE_LOAD_DECLINE;
-
- ast_cli_register_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
- res = ast_register_application(app1, ospauth_exec, synopsis1, descrip1);
- res |= ast_register_application(app2, osplookup_exec, synopsis2, descrip2);
- res |= ast_register_application(app3, ospnext_exec, synopsis3, descrip3);
- res |= ast_register_application(app4, ospfinished_exec, synopsis4, descrip4);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app4);
- res |= ast_unregister_application(app3);
- res |= ast_unregister_application(app2);
- res |= ast_unregister_application(app1);
- ast_cli_unregister_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
- osp_unload();
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int reload(void)
-{
- osp_unload();
- osp_load();
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Open Settlement Protocol Applications",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/apps/app_page.c b/1.4/apps/app_page.c
deleted file mode 100644
index 00574b943..000000000
--- a/1.4/apps/app_page.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2004 - 2006 Digium, Inc. All rights reserved.
- *
- * Mark Spencer <markster@digium.com>
- *
- * This code is released under the GNU General Public License
- * version 2.0. See LICENSE for more information.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief page() - Paging application
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- <depend>app_meetme</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/file.h"
-#include "asterisk/app.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/utils.h"
-#include "asterisk/dial.h"
-#include "asterisk/devicestate.h"
-
-static const char *app_page= "Page";
-
-static const char *page_synopsis = "Pages phones";
-
-static const char *page_descrip =
-"Page(Technology/Resource&Technology2/Resource2[|options])\n"
-" Places outbound calls to the given technology / resource and dumps\n"
-"them into a conference bridge as muted participants. The original\n"
-"caller is dumped into the conference as a speaker and the room is\n"
-"destroyed when the original caller leaves. Valid options are:\n"
-" d - full duplex audio\n"
-" q - quiet, do not play beep to caller\n"
-" r - record the page into a file (see 'r' for app_meetme)\n";
-
-enum {
- PAGE_DUPLEX = (1 << 0),
- PAGE_QUIET = (1 << 1),
- PAGE_RECORD = (1 << 2),
-} page_opt_flags;
-
-AST_APP_OPTIONS(page_opts, {
- AST_APP_OPTION('d', PAGE_DUPLEX),
- AST_APP_OPTION('q', PAGE_QUIET),
- AST_APP_OPTION('r', PAGE_RECORD),
-});
-
-#define MAX_DIALS 128
-
-static int page_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *options, *tech, *resource, *tmp;
- char meetmeopts[88], originator[AST_CHANNEL_NAME];
- struct ast_flags flags = { 0 };
- unsigned int confid = ast_random();
- struct ast_app *app;
- int res = 0, pos = 0, i = 0;
- struct ast_dial *dials[MAX_DIALS];
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (!(app = pbx_findapp("MeetMe"))) {
- ast_log(LOG_WARNING, "There is no MeetMe application available!\n");
- ast_module_user_remove(u);
- return -1;
- };
-
- options = ast_strdupa(data);
-
- ast_copy_string(originator, chan->name, sizeof(originator));
- if ((tmp = strchr(originator, '-')))
- *tmp = '\0';
-
- tmp = strsep(&options, "|");
- if (options)
- ast_app_parse_options(page_opts, &flags, NULL, options);
-
- snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe|%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"),
- (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
-
- /* Go through parsing/calling each device */
- while ((tech = strsep(&tmp, "&"))) {
- struct ast_dial *dial = NULL;
-
- /* don't call the originating device */
- if (!strcasecmp(tech, originator))
- continue;
-
- /* If no resource is available, continue on */
- if (!(resource = strchr(tech, '/'))) {
- ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech);
- continue;
- }
-
- *resource++ = '\0';
-
- /* Create a dialing structure */
- if (!(dial = ast_dial_create())) {
- ast_log(LOG_WARNING, "Failed to create dialing structure.\n");
- continue;
- }
-
- /* Append technology and resource */
- ast_dial_append(dial, tech, resource);
-
- /* Set ANSWER_EXEC as global option */
- ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, meetmeopts);
-
- /* Run this dial in async mode */
- ast_dial_run(dial, chan, 1);
-
- /* Put in our dialing array */
- dials[pos++] = dial;
- }
-
- if (!ast_test_flag(&flags, PAGE_QUIET)) {
- res = ast_streamfile(chan, "beep", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- }
-
- if (!res) {
- snprintf(meetmeopts, sizeof(meetmeopts), "%ud|A%s%sqxd", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"),
- (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
- pbx_exec(chan, app, meetmeopts);
- }
-
- /* Go through each dial attempt cancelling, joining, and destroying */
- for (i = 0; i < pos; i++) {
- struct ast_dial *dial = dials[i];
-
- /* We have to wait for the async thread to exit as it's possible Meetme won't throw them out immediately */
- ast_dial_join(dial);
-
- /* Hangup all channels */
- ast_dial_hangup(dial);
-
- /* Destroy dialing structure */
- ast_dial_destroy(dial);
- }
-
- ast_module_user_remove(u);
-
- return -1;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_page);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app_page, page_exec, page_synopsis, page_descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Page Multiple Phones");
-
diff --git a/1.4/apps/app_parkandannounce.c b/1.4/apps/app_parkandannounce.c
deleted file mode 100644
index 0e89c73ac..000000000
--- a/1.4/apps/app_parkandannounce.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Author: Ben Miller <bgmiller@dccinc.com>
- * With TONS of help from Mark!
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ParkAndAnnounce application for Asterisk
- *
- * \author Ben Miller <bgmiller@dccinc.com>
- * \arg With TONS of help from Mark!
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/features.h"
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/say.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-static char *app = "ParkAndAnnounce";
-
-static char *synopsis = "Park and Announce";
-
-static char *descrip =
-" ParkAndAnnounce(announce:template|timeout|dial|[return_context]):\n"
-"Park a call into the parkinglot and announce the call to another channel.\n"
-"\n"
-"announce template: Colon-separated list of files to announce. The word PARKED\n"
-" will be replaced by a say_digits of the extension in which\n"
-" the call is parked.\n"
-"timeout: Time in seconds before the call returns into the return\n"
-" context.\n"
-"dial: The app_dial style resource to call to make the\n"
-" announcement. Console/dsp calls the console.\n"
-"return_context: The goto-style label to jump the call back into after\n"
-" timeout. Default <priority+1>.\n"
-"\n"
-"The variable ${PARKEDAT} will contain the parking extension into which the\n"
-"call was placed. Use with the Local channel to allow the dialplan to make\n"
-"use of this information.\n";
-
-
-static int parkandannounce_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- char *return_context;
- int lot, timeout = 0, dres;
- char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr;
- char *template, *tpl_working, *tpl_current;
- char *tmp[100];
- char buf[13];
- int looptemp=0,i=0;
- char *s;
-
- struct ast_channel *dchan;
- struct outgoing_helper oh;
- int outstate;
-
- struct ast_module_user *u;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- s = ast_strdupa(data);
-
- template=strsep(&s,"|");
- if(! template) {
- ast_log(LOG_WARNING, "PARK: An announce template must be defined\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if(s) {
- timeout = atoi(strsep(&s, "|"));
- timeout *= 1000;
- }
- dial=strsep(&s, "|");
- if(!dial) {
- ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
- ast_module_user_remove(u);
- return -1;
- } else {
- dialtech=strsep(&dial, "/");
- dialstr=dial;
- ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr);
- }
-
- return_context = s;
-
- if(return_context != NULL) {
- /* set the return context. Code borrowed from the Goto builtin */
-
- working = return_context;
- context = strsep(&working, "|");
- exten = strsep(&working, "|");
- if(!exten) {
- /* Only a priority in this one */
- priority = context;
- exten = NULL;
- context = NULL;
- } else {
- priority = strsep(&working, "|");
- if(!priority) {
- /* Only an extension and priority in this one */
- priority = exten;
- exten = context;
- context = NULL;
- }
- }
- if(atoi(priority) < 0) {
- ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
- ast_module_user_remove(u);
- return -1;
- }
- /* At this point we have a priority and maybe an extension and a context */
- chan->priority = atoi(priority);
- if (exten)
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- if (context)
- ast_copy_string(chan->context, context, sizeof(chan->context));
- } else { /* increment the priority by default*/
- chan->priority++;
- }
-
- if(option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
- if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
- ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
- }
- }
-
- /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
- before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
-
- ast_masq_park_call(chan, NULL, timeout, &lot);
-
- res=-1;
-
- ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
-
- /* Now place the call to the extention */
-
- snprintf(buf, sizeof(buf), "%d", lot);
- memset(&oh, 0, sizeof(oh));
- oh.parent_channel = chan;
- oh.vars = ast_variable_new("_PARKEDAT", buf);
- dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
-
- if(dchan) {
- if(dchan->_state == AST_STATE_UP) {
- if(option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", dchan->name);
- } else {
- if(option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", dchan->name);
- ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
- ast_hangup(dchan);
- ast_module_user_remove(u);
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_stopstream(dchan);
-
- /* now we have the call placed and are ready to play stuff to it */
-
- ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template);
-
- tpl_working = template;
- tpl_current=strsep(&tpl_working, ":");
-
- while(tpl_current && looptemp < ARRAY_LEN(tmp)) {
- tmp[looptemp]=tpl_current;
- looptemp++;
- tpl_current=strsep(&tpl_working,":");
- }
-
- for(i=0; i<looptemp; i++) {
- ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
- if(!strcmp(tmp[i], "PARKED")) {
- ast_say_digits(dchan, lot, "", dchan->language);
- } else {
- dres = ast_streamfile(dchan, tmp[i], dchan->language);
- if(!dres) {
- dres = ast_waitstream(dchan, "");
- } else {
- ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
- dres = 0;
- }
- }
- }
-
- ast_stopstream(dchan);
- ast_hangup(dchan);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- /* return ast_register_application(app, park_exec); */
- return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Parking and Announce Application");
diff --git a/1.4/apps/app_playback.c b/1.4/apps/app_playback.c
deleted file mode 100644
index 8f78bef78..000000000
--- a/1.4/apps/app_playback.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Trivial application to playback a sound file
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-#include "asterisk/cli.h"
-#include "asterisk/localtime.h"
-#include "asterisk/say.h"
-
-static char *app = "Playback";
-
-static char *synopsis = "Play a file";
-
-static char *descrip =
-" Playback(filename[&filename2...][|option]): Plays back given filenames (do not put\n"
-"extension). Options may also be included following a pipe symbol. The 'skip'\n"
-"option causes the playback of the message to be skipped if the channel\n"
-"is not in the 'up' state (i.e. it hasn't been answered yet). If 'skip' is \n"
-"specified, the application will return immediately should the channel not be\n"
-"off hook. Otherwise, unless 'noanswer' is specified, the channel will\n"
-"be answered before the sound is played. Not all channels support playing\n"
-"messages while still on hook. If 'j' is specified, the application\n"
-"will jump to priority n+101 if present when a file specified to be played\n"
-"does not exist.\n"
-"This application sets the following channel variable upon completion:\n"
-" PLAYBACKSTATUS The status of the playback attempt as a text string, one of\n"
-" SUCCESS | FAILED\n"
-"See Also: Background (application) -- for playing soundfiles that are interruptible\n"
-" WaitExten (application) -- wait for digits from caller, optionally play music on hold\n"
-;
-
-
-static struct ast_config *say_cfg = NULL;
-/* save the say' api calls.
- * The first entry is NULL if we have the standard source,
- * otherwise we are sourcing from here.
- * 'say load [new|old]' will enable the new or old method, or report status
- */
-static const void * say_api_buf[40];
-static const char *say_old = "old";
-static const char *say_new = "new";
-
-static void save_say_mode(const void *arg)
-{
- int i = 0;
- say_api_buf[i++] = arg;
-
- say_api_buf[i++] = ast_say_number_full;
- say_api_buf[i++] = ast_say_enumeration_full;
- say_api_buf[i++] = ast_say_digit_str_full;
- say_api_buf[i++] = ast_say_character_str_full;
- say_api_buf[i++] = ast_say_phonetic_str_full;
- say_api_buf[i++] = ast_say_datetime;
- say_api_buf[i++] = ast_say_time;
- say_api_buf[i++] = ast_say_date;
- say_api_buf[i++] = ast_say_datetime_from_now;
- say_api_buf[i++] = ast_say_date_with_format;
-}
-
-static void restore_say_mode(void *arg)
-{
- int i = 0;
- say_api_buf[i++] = arg;
-
- ast_say_number_full = say_api_buf[i++];
- ast_say_enumeration_full = say_api_buf[i++];
- ast_say_digit_str_full = say_api_buf[i++];
- ast_say_character_str_full = say_api_buf[i++];
- ast_say_phonetic_str_full = say_api_buf[i++];
- ast_say_datetime = say_api_buf[i++];
- ast_say_time = say_api_buf[i++];
- ast_say_date = say_api_buf[i++];
- ast_say_datetime_from_now = say_api_buf[i++];
- ast_say_date_with_format = say_api_buf[i++];
-}
-
-/*
- * Typical 'say' arguments in addition to the date or number or string
- * to say. We do not include 'options' because they may be different
- * in recursive calls, and so they are better left as an external
- * parameter.
- */
-typedef struct {
- struct ast_channel *chan;
- const char *ints;
- const char *language;
- int audiofd;
- int ctrlfd;
-} say_args_t;
-
-static int s_streamwait3(const say_args_t *a, const char *fn)
-{
- int res = ast_streamfile(a->chan, fn, a->language);
- if (res) {
- ast_log(LOG_WARNING, "Unable to play message %s\n", fn);
- return res;
- }
- res = (a->audiofd > -1 && a->ctrlfd > -1) ?
- ast_waitstream_full(a->chan, a->ints, a->audiofd, a->ctrlfd) :
- ast_waitstream(a->chan, a->ints);
- ast_stopstream(a->chan);
- return res;
-}
-
-/*
- * the string is 'prefix:data' or prefix:fmt:data'
- * with ':' being invalid in strings.
- */
-static int do_say(say_args_t *a, const char *s, const char *options, int depth)
-{
- struct ast_variable *v;
- char *lang, *x, *rule = NULL;
- int ret = 0;
- struct varshead head = { .first = NULL, .last = NULL };
- struct ast_var_t *n;
-
- if (depth++ > 10) {
- ast_log(LOG_WARNING, "recursion too deep, exiting\n");
- return -1;
- } else if (!say_cfg) {
- ast_log(LOG_WARNING, "no say.conf, cannot spell '%s'\n", s);
- return -1;
- }
-
- /* scan languages same as in file.c */
- if (a->language == NULL)
- a->language = "en"; /* default */
- lang = ast_strdupa(a->language);
- for (;;) {
- for (v = ast_variable_browse(say_cfg, lang); v ; v = v->next) {
- if (ast_extension_match(v->name, s)) {
- rule = ast_strdupa(v->value);
- break;
- }
- }
- if (rule)
- break;
- if ( (x = strchr(lang, '_')) )
- *x = '\0'; /* try without suffix */
- else if (strcmp(lang, "en"))
- lang = "en"; /* last resort, try 'en' if not done yet */
- else
- break;
- }
- if (!rule)
- return 0;
-
- /* skip up to two prefixes to get the value */
- if ( (x = strchr(s, ':')) )
- s = x + 1;
- if ( (x = strchr(s, ':')) )
- s = x + 1;
- n = ast_var_assign("SAY", s);
- AST_LIST_INSERT_HEAD(&head, n, entries);
-
- /* scan the body, one piece at a time */
- while ( !ret && (x = strsep(&rule, ",")) ) { /* exit on key */
- char fn[128];
- const char *p, *fmt, *data; /* format and data pointers */
-
- /* prepare a decent file name */
- x = ast_skip_blanks(x);
- ast_trim_blanks(x);
-
- /* replace variables */
- memset(fn, 0, sizeof(fn)); /* XXX why isn't done in pbx_substitute_variables_helper! */
- pbx_substitute_variables_varshead(&head, x, fn, sizeof(fn));
-
- /* locate prefix and data, if any */
- fmt = index(fn, ':');
- if (!fmt || fmt == fn) { /* regular filename */
- ret = s_streamwait3(a, fn);
- continue;
- }
- fmt++;
- data = index(fmt, ':'); /* colon before data */
- if (!data || data == fmt) { /* simple prefix-fmt */
- ret = do_say(a, fn, options, depth);
- continue;
- }
- /* prefix:fmt:data */
- for (p = fmt; p < data && ret <= 0; p++) {
- char fn2[sizeof(fn)];
- if (*p == ' ' || *p == '\t') /* skip blanks */
- continue;
- if (*p == '\'') {/* file name - we trim them */
- char *y;
- strcpy(fn2, ast_skip_blanks(p+1)); /* make a full copy */
- y = index(fn2, '\'');
- if (!y) {
- p = data; /* invalid. prepare to end */
- break;
- }
- *y = '\0';
- ast_trim_blanks(fn2);
- p = index(p+1, '\'');
- ret = s_streamwait3(a, fn2);
- } else {
- int l = fmt-fn;
- strcpy(fn2, fn); /* copy everything */
- /* after prefix, append the format */
- fn2[l++] = *p;
- strcpy(fn2 + l, data);
- ret = do_say(a, fn2, options, depth);
- }
-
- if (ret) {
- break;
- }
- }
- }
- ast_var_delete(n);
- return ret;
-}
-
-static int say_full(struct ast_channel *chan, const char *string,
- const char *ints, const char *lang, const char *options,
- int audiofd, int ctrlfd)
-{
- say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
- return do_say(&a, string, options, 0);
-}
-
-static int say_number_full(struct ast_channel *chan, int num,
- const char *ints, const char *lang, const char *options,
- int audiofd, int ctrlfd)
-{
- char buf[64];
- say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
- snprintf(buf, sizeof(buf), "num:%d", num);
- return do_say(&a, buf, options, 0);
-}
-
-static int say_enumeration_full(struct ast_channel *chan, int num,
- const char *ints, const char *lang, const char *options,
- int audiofd, int ctrlfd)
-{
- char buf[64];
- say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
- snprintf(buf, sizeof(buf), "enum:%d", num);
- return do_say(&a, buf, options, 0);
-}
-
-static int say_date_generic(struct ast_channel *chan, time_t t,
- const char *ints, const char *lang, const char *format, const char *timezone, const char *prefix)
-{
- char buf[128];
- struct tm tm;
- say_args_t a = { chan, ints, lang, -1, -1 };
- if (format == NULL)
- format = "";
-
- ast_localtime(&t, &tm, NULL);
- snprintf(buf, sizeof(buf), "%s:%s:%04d%02d%02d%02d%02d.%02d-%d-%3d",
- prefix,
- format,
- tm.tm_year+1900,
- tm.tm_mon+1,
- tm.tm_mday,
- tm.tm_hour,
- tm.tm_min,
- tm.tm_sec,
- tm.tm_wday,
- tm.tm_yday);
- return do_say(&a, buf, NULL, 0);
-}
-
-static int say_date_with_format(struct ast_channel *chan, time_t t,
- const char *ints, const char *lang, const char *format, const char *timezone)
-{
- return say_date_generic(chan, t, ints, lang, format, timezone, "datetime");
-}
-
-static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- return say_date_generic(chan, t, ints, lang, "", NULL, "date");
-}
-
-static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- return say_date_generic(chan, t, ints, lang, "", NULL, "time");
-}
-
-static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- return say_date_generic(chan, t, ints, lang, "", NULL, "datetime");
-}
-
-/*
- * remap the 'say' functions to use those in this file
- */
-static int __say_init(int fd, int argc, char *argv[])
-{
- const char *old_mode = say_api_buf[0] ? say_new : say_old;
- char *mode;
-
- if (argc == 2) {
- ast_cli(fd, "say mode is [%s]\n", old_mode);
- return RESULT_SUCCESS;
- } else if (argc != 3)
- return RESULT_SHOWUSAGE;
- mode = argv[2];
-
- ast_log(LOG_WARNING, "init say.c from %s to %s\n", old_mode, mode);
-
- if (!strcmp(mode, old_mode)) {
- ast_log(LOG_WARNING, "say mode is %s already\n", mode);
- } else if (!strcmp(mode, say_new)) {
- if (say_cfg == NULL)
- say_cfg = ast_config_load("say.conf");
- save_say_mode(say_new);
- ast_say_number_full = say_number_full;
-
- ast_say_enumeration_full = say_enumeration_full;
-#if 0
- ast_say_digits_full = say_digits_full;
- ast_say_digit_str_full = say_digit_str_full;
- ast_say_character_str_full = say_character_str_full;
- ast_say_phonetic_str_full = say_phonetic_str_full;
- ast_say_datetime_from_now = say_datetime_from_now;
-#endif
- ast_say_datetime = say_datetime;
- ast_say_time = say_time;
- ast_say_date = say_date;
- ast_say_date_with_format = say_date_with_format;
- } else if (!strcmp(mode, say_old) && say_api_buf[0] == say_new) {
- restore_say_mode(NULL);
- } else {
- ast_log(LOG_WARNING, "unrecognized mode %s\n", mode);
- }
- return RESULT_SUCCESS;
-}
-
-static struct ast_cli_entry cli_playback[] = {
- { { "say", "load", NULL },
- __say_init, "set/show the say mode",
- "Usage: say load [new|old]\n Set/show the say mode\n" },
-};
-
-static int playback_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- int mres = 0;
- struct ast_module_user *u;
- char *tmp;
- int option_skip=0;
- int option_say=0;
- int option_noanswer = 0;
- int priority_jump = 0;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(filenames);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
- return -1;
- }
-
- tmp = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
- AST_STANDARD_APP_ARGS(args, tmp);
-
- if (args.options) {
- if (strcasestr(args.options, "skip"))
- option_skip = 1;
- if (strcasestr(args.options, "say"))
- option_say = 1;
- if (strcasestr(args.options, "noanswer"))
- option_noanswer = 1;
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- if (chan->_state != AST_STATE_UP) {
- if (option_skip) {
- /* At the user's option, skip if the line is not up */
- goto done;
- } else if (!option_noanswer)
- /* Otherwise answer unless we're supposed to send this while on-hook */
- res = ast_answer(chan);
- }
- if (!res) {
- char *back = args.filenames;
- char *front;
-
- ast_stopstream(chan);
- while (!res && (front = strsep(&back, "&"))) {
- if (option_say)
- res = say_full(chan, front, "", chan->language, NULL, -1, -1);
- else
- res = ast_streamfile(chan, front, chan->language);
- if (!res) {
- res = ast_waitstream(chan, "");
- ast_stopstream(chan);
- } else {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- mres = 1;
- }
- }
- }
-done:
- pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", mres ? "FAILED" : "SUCCESS");
- ast_module_user_remove(u);
- return res;
-}
-
-static int reload(void)
-{
- if (say_cfg) {
- ast_config_destroy(say_cfg);
- ast_log(LOG_NOTICE, "Reloading say.conf\n");
- }
- say_cfg = ast_config_load("say.conf");
- /*
- * XXX here we should sort rules according to the same order
- * we have in pbx.c so we have the same matching behaviour.
- */
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_cli_unregister_multiple(cli_playback, sizeof(cli_playback) / sizeof(struct ast_cli_entry));
-
- ast_module_user_hangup_all();
-
- if (say_cfg)
- ast_config_destroy(say_cfg);
-
- return res;
-}
-
-static int load_module(void)
-{
- say_cfg = ast_config_load("say.conf");
- ast_cli_register_multiple(cli_playback, sizeof(cli_playback) / sizeof(struct ast_cli_entry));
- return ast_register_application(app, playback_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Sound File Playback Application",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/apps/app_privacy.c b/1.4/apps/app_privacy.c
deleted file mode 100644
index 5da93eb40..000000000
--- a/1.4/apps/app_privacy.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Block all calls without Caller*ID, require phone # to be entered
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/utils.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/callerid.h"
-#include "asterisk/app.h"
-#include "asterisk/config.h"
-
-#define PRIV_CONFIG "privacy.conf"
-
-static char *app = "PrivacyManager";
-
-static char *synopsis = "Require phone number to be entered, if no CallerID sent";
-
-static char *descrip =
- " PrivacyManager([maxretries[|minlength[|options]]]): If no Caller*ID \n"
- "is sent, PrivacyManager answers the channel and asks the caller to\n"
- "enter their phone number. The caller is given 3 attempts to do so.\n"
- "The application does nothing if Caller*ID was received on the channel.\n"
- " Configuration file privacy.conf contains two variables:\n"
- " maxretries default 3 -maximum number of attempts the caller is allowed \n"
- " to input a callerid.\n"
- " minlength default 10 -minimum allowable digits in the input callerid number.\n"
- "If you don't want to use the config file and have an i/o operation with\n"
- "every call, you can also specify maxretries and minlength as application\n"
- "parameters. Doing so supercedes any values set in privacy.conf.\n"
- "The option string may contain the following character: \n"
- " 'j' -- jump to n+101 priority after <maxretries> failed attempts to collect\n"
- " the minlength number of digits.\n"
- "The application sets the following channel variable upon completion: \n"
- "PRIVACYMGRSTATUS The status of the privacy manager's attempt to collect \n"
- " a phone number from the user. A text string that is either:\n"
- " SUCCESS | FAILED \n"
-;
-
-
-static int privacy_exec (struct ast_channel *chan, void *data)
-{
- int res=0;
- int retries;
- int maxretries = 3;
- int minlength = 10;
- int x = 0;
- const char *s;
- char phone[30];
- struct ast_module_user *u;
- struct ast_config *cfg = NULL;
- char *parse = NULL;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(maxretries);
- AST_APP_ARG(minlength);
- AST_APP_ARG(options);
- );
-
- u = ast_module_user_add(chan);
-
- if (!ast_strlen_zero(chan->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
- } else {
- /*Answer the channel if it is not already*/
- if (chan->_state != AST_STATE_UP) {
- res = ast_answer(chan);
- if (res) {
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- if (!ast_strlen_zero(data)) {
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.maxretries) {
- if (sscanf(args.maxretries, "%d", &x) == 1)
- maxretries = x;
- else
- ast_log(LOG_WARNING, "Invalid max retries argument\n");
- }
- if (args.minlength) {
- if (sscanf(args.minlength, "%d", &x) == 1)
- minlength = x;
- else
- ast_log(LOG_WARNING, "Invalid min length argument\n");
- }
- if (args.options)
- if (strchr(args.options, 'j'))
- priority_jump = 1;
-
- }
-
- if (!x)
- {
- /*Read in the config file*/
- cfg = ast_config_load(PRIV_CONFIG);
-
- if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
- if (sscanf(s, "%d", &x) == 1)
- maxretries = x;
- else
- ast_log(LOG_WARNING, "Invalid max retries argument\n");
- }
-
- if (cfg && (s = ast_variable_retrieve(cfg, "general", "minlength"))) {
- if (sscanf(s, "%d", &x) == 1)
- minlength = x;
- else
- ast_log(LOG_WARNING, "Invalid min length argument\n");
- }
- }
-
- /*Play unidentified call*/
- res = ast_safe_sleep(chan, 1000);
- if (!res)
- res = ast_streamfile(chan, "privacy-unident", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
-
- /*Ask for 10 digit number, give 3 attempts*/
- for (retries = 0; retries < maxretries; retries++) {
- if (!res)
- res = ast_streamfile(chan, "privacy-prompt", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
-
- if (!res )
- res = ast_readstring(chan, phone, sizeof(phone) - 1, /* digit timeout ms */ 3200, /* first digit timeout */ 5000, "#");
-
- if (res < 0)
- break;
-
- /*Make sure we get at least digits*/
- if (strlen(phone) >= minlength )
- break;
- else {
- res = ast_streamfile(chan, "privacy-incorrect", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- }
- }
-
- /*Got a number, play sounds and send them on their way*/
- if ((retries < maxretries) && res >= 0 ) {
- res = ast_streamfile(chan, "privacy-thankyou", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
-
- ast_set_callerid (chan, phone, "Privacy Manager", NULL);
-
- /* Clear the unavailable presence bit so if it came in on PRI
- * the caller id will now be passed out to other channels
- */
- chan->cid.cid_pres &= (AST_PRES_UNAVAILABLE ^ 0xFF);
-
- if (option_verbose > 2) {
- ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s, callerpres to %d\n",phone,chan->cid.cid_pres);
- }
- pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
- } else {
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "FAILED");
- }
- if (cfg)
- ast_config_destroy(cfg);
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application (app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application (app, privacy_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Require phone number to be entered, if no CallerID sent");
diff --git a/1.4/apps/app_queue.c b/1.4/apps/app_queue.c
deleted file mode 100644
index ce74c3f38..000000000
--- a/1.4/apps/app_queue.c
+++ /dev/null
@@ -1,4959 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief True call queues with optional send URL on answer
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg Config in \ref Config_qu queues.conf
- *
- * \par Development notes
- * \note 2004-11-25: Persistent Dynamic Members added by:
- * NetNation Communications (www.netnation.com)
- * Kevin Lindsay <kevinl@netnation.com>
- *
- * Each dynamic agent in each queue is now stored in the astdb.
- * When asterisk is restarted, each agent will be automatically
- * readded into their recorded queues. This feature can be
- * configured with the 'persistent_members=<1|0>' setting in the
- * '[general]' category in queues.conf. The default is on.
- *
- * \note 2004-06-04: Priorities in queues added by inAccess Networks (work funded by Hellas On Line (HOL) www.hol.gr).
- *
- * \note These features added by David C. Troy <dave@toad.net>:
- * - Per-queue holdtime calculation
- * - Estimated holdtime announcement
- * - Position announcement
- * - Abandoned/completed call counters
- * - Failout timer passed as optional app parameter
- * - Optional monitoring of calls, started when call is answered
- *
- * Patch Version 1.07 2003-12-24 01
- *
- * Added servicelevel statistic by Michiel Betel <michiel@betel.nl>
- * Added Priority jumping code for adding and removing queue members by Jonathan Stanton <asterisk@doilooklikeicare.com>
- *
- * Fixed to work with CVS as of 2004-02-25 and released as 1.07a
- * by Matthew Enger <m.enger@xi.com.au>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>res_monitor</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <netinet/in.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/say.h"
-#include "asterisk/features.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/cli.h"
-#include "asterisk/manager.h"
-#include "asterisk/config.h"
-#include "asterisk/monitor.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/astdb.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/astobj2.h"
-#include "asterisk/global_datastores.h"
-
-/* Please read before modifying this file.
- * There are three locks which are regularly used
- * throughout this file, the queue list lock, the lock
- * for each individual queue, and the interface list lock.
- * Please be extra careful to always lock in the following order
- * 1) queue list lock
- * 2) individual queue lock
- * 3) interface list lock
- * This order has sort of "evolved" over the lifetime of this
- * application, but it is now in place this way, so please adhere
- * to this order!
- */
-
-
-enum {
- QUEUE_STRATEGY_RINGALL = 0,
- QUEUE_STRATEGY_ROUNDROBIN,
- QUEUE_STRATEGY_LEASTRECENT,
- QUEUE_STRATEGY_FEWESTCALLS,
- QUEUE_STRATEGY_RANDOM,
- QUEUE_STRATEGY_RRMEMORY
-};
-
-static struct strategy {
- int strategy;
- char *name;
-} strategies[] = {
- { QUEUE_STRATEGY_RINGALL, "ringall" },
- { QUEUE_STRATEGY_ROUNDROBIN, "roundrobin" },
- { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
- { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
- { QUEUE_STRATEGY_RANDOM, "random" },
- { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
-};
-
-#define DEFAULT_RETRY 5
-#define DEFAULT_TIMEOUT 15
-#define RECHECK 1 /* Recheck every second to see we we're at the top yet */
-#define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
-
-#define RES_OKAY 0 /* Action completed */
-#define RES_EXISTS (-1) /* Entry already exists */
-#define RES_OUTOFMEMORY (-2) /* Out of memory */
-#define RES_NOSUCHQUEUE (-3) /* No such queue */
-#define RES_NOT_DYNAMIC (-4) /* Member is not dynamic */
-
-static char *app = "Queue";
-
-static char *synopsis = "Queue a call for a call queue";
-
-static char *descrip =
-" Queue(queuename[|options[|URL][|announceoverride][|timeout][|AGI]):\n"
-"Queues an incoming call in a particular call queue as defined in queues.conf.\n"
-"This application will return to the dialplan if the queue does not exist, or\n"
-"any of the join options cause the caller to not enter the queue.\n"
-"The option string may contain zero or more of the following characters:\n"
-" 'd' -- data-quality (modem) call (minimum delay).\n"
-" 'h' -- allow callee to hang up by hitting *.\n"
-" 'H' -- allow caller to hang up by hitting *.\n"
-" 'n' -- no retries on the timeout; will exit this application and \n"
-" go to the next step.\n"
-" 'i' -- ignore call forward requests from queue members and do nothing\n"
-" when they are requested.\n"
-" 'r' -- ring instead of playing MOH\n"
-" 't' -- allow the called user transfer the calling user\n"
-" 'T' -- to allow the calling user to transfer the call.\n"
-" 'w' -- allow the called user to write the conversation to disk via Monitor\n"
-" 'W' -- allow the calling user to write the conversation to disk via Monitor\n"
-" In addition to transferring the call, a call may be parked and then picked\n"
-"up by another user.\n"
-" The optional URL will be sent to the called party if the channel supports\n"
-"it.\n"
-" The optional AGI parameter will setup an AGI script to be executed on the \n"
-"calling party's channel once they are connected to a queue member.\n"
-" The timeout will cause the queue to fail out after a specified number of\n"
-"seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
-" This application sets the following channel variable upon completion:\n"
-" QUEUESTATUS The status of the call as a text string, one of\n"
-" TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL\n";
-
-static char *app_aqm = "AddQueueMember" ;
-static char *app_aqm_synopsis = "Dynamically adds queue members" ;
-static char *app_aqm_descrip =
-" AddQueueMember(queuename[|interface[|penalty[|options[|membername]]]]):\n"
-"Dynamically adds interface to an existing queue.\n"
-"If the interface is already in the queue and there exists an n+101 priority\n"
-"then it will then jump to this priority. Otherwise it will return an error\n"
-"The option string may contain zero or more of the following characters:\n"
-" 'j' -- jump to +101 priority when appropriate.\n"
-" This application sets the following channel variable upon completion:\n"
-" AQMSTATUS The status of the attempt to add a queue member as a \n"
-" text string, one of\n"
-" ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
-"Example: AddQueueMember(techsupport|SIP/3000)\n"
-"";
-
-static char *app_rqm = "RemoveQueueMember" ;
-static char *app_rqm_synopsis = "Dynamically removes queue members" ;
-static char *app_rqm_descrip =
-" RemoveQueueMember(queuename[|interface[|options]]):\n"
-"Dynamically removes interface to an existing queue\n"
-"If the interface is NOT in the queue and there exists an n+101 priority\n"
-"then it will then jump to this priority. Otherwise it will return an error\n"
-"The option string may contain zero or more of the following characters:\n"
-" 'j' -- jump to +101 priority when appropriate.\n"
-" This application sets the following channel variable upon completion:\n"
-" RQMSTATUS The status of the attempt to remove a queue member as a\n"
-" text string, one of\n"
-" REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
-"Example: RemoveQueueMember(techsupport|SIP/3000)\n"
-"";
-
-static char *app_pqm = "PauseQueueMember" ;
-static char *app_pqm_synopsis = "Pauses a queue member" ;
-static char *app_pqm_descrip =
-" PauseQueueMember([queuename]|interface[|options]):\n"
-"Pauses (blocks calls for) a queue member.\n"
-"The given interface will be paused in the given queue. This prevents\n"
-"any calls from being sent from the queue to the interface until it is\n"
-"unpaused with UnpauseQueueMember or the manager interface. If no\n"
-"queuename is given, the interface is paused in every queue it is a\n"
-"member of. If the interface is not in the named queue, or if no queue\n"
-"is given and the interface is not in any queue, it will jump to\n"
-"priority n+101, if it exists and the appropriate options are set.\n"
-"The application will fail if the interface is not found and no extension\n"
-"to jump to exists.\n"
-"The option string may contain zero or more of the following characters:\n"
-" 'j' -- jump to +101 priority when appropriate.\n"
-" This application sets the following channel variable upon completion:\n"
-" PQMSTATUS The status of the attempt to pause a queue member as a\n"
-" text string, one of\n"
-" PAUSED | NOTFOUND\n"
-"Example: PauseQueueMember(|SIP/3000)\n";
-
-static char *app_upqm = "UnpauseQueueMember" ;
-static char *app_upqm_synopsis = "Unpauses a queue member" ;
-static char *app_upqm_descrip =
-" UnpauseQueueMember([queuename]|interface[|options]):\n"
-"Unpauses (resumes calls to) a queue member.\n"
-"This is the counterpart to PauseQueueMember and operates exactly the\n"
-"same way, except it unpauses instead of pausing the given interface.\n"
-"The option string may contain zero or more of the following characters:\n"
-" 'j' -- jump to +101 priority when appropriate.\n"
-" This application sets the following channel variable upon completion:\n"
-" UPQMSTATUS The status of the attempt to unpause a queue \n"
-" member as a text string, one of\n"
-" UNPAUSED | NOTFOUND\n"
-"Example: UnpauseQueueMember(|SIP/3000)\n";
-
-static char *app_ql = "QueueLog" ;
-static char *app_ql_synopsis = "Writes to the queue_log" ;
-static char *app_ql_descrip =
-" QueueLog(queuename|uniqueid|agent|event[|additionalinfo]):\n"
-"Allows you to write your own events into the queue log\n"
-"Example: QueueLog(101|${UNIQUEID}|${AGENT}|WENTONBREAK|600)\n";
-
-/*! \brief Persistent Members astdb family */
-static const char *pm_family = "Queue/PersistentMembers";
-/* The maximum length of each persistent member queue database entry */
-#define PM_MAX_LEN 8192
-
-/*! \brief queues.conf [general] option */
-static int queue_persistent_members = 0;
-
-/*! \brief queues.conf per-queue weight option */
-static int use_weight = 0;
-
-/*! \brief queues.conf [general] option */
-static int autofill_default = 0;
-
-/*! \brief queues.conf [general] option */
-static int montype_default = 0;
-
-enum queue_result {
- QUEUE_UNKNOWN = 0,
- QUEUE_TIMEOUT = 1,
- QUEUE_JOINEMPTY = 2,
- QUEUE_LEAVEEMPTY = 3,
- QUEUE_JOINUNAVAIL = 4,
- QUEUE_LEAVEUNAVAIL = 5,
- QUEUE_FULL = 6,
-};
-
-const struct {
- enum queue_result id;
- char *text;
-} queue_results[] = {
- { QUEUE_UNKNOWN, "UNKNOWN" },
- { QUEUE_TIMEOUT, "TIMEOUT" },
- { QUEUE_JOINEMPTY,"JOINEMPTY" },
- { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
- { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
- { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
- { QUEUE_FULL, "FULL" },
-};
-
-/*! \brief We define a custom "local user" structure because we
- use it not only for keeping track of what is in use but
- also for keeping track of who we're dialing.
-
- There are two "links" defined in this structure, q_next and call_next.
- q_next links ALL defined callattempt structures into a linked list. call_next is
- a link which allows for a subset of the callattempts to be traversed. This subset
- is used in wait_for_answer so that irrelevant callattempts are not traversed. This
- also is helpful so that queue logs are always accurate in the case where a call to
- a member times out, especially if using the ringall strategy. */
-
-struct callattempt {
- struct callattempt *q_next;
- struct callattempt *call_next;
- struct ast_channel *chan;
- char interface[256];
- int stillgoing;
- int metric;
- int oldstatus;
- time_t lastcall;
- struct member *member;
-};
-
-
-struct queue_ent {
- struct call_queue *parent; /*!< What queue is our parent */
- char moh[80]; /*!< Name of musiconhold to be used */
- char announce[80]; /*!< Announcement to play for member when call is answered */
- char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */
- char digits[AST_MAX_EXTENSION]; /*!< Digits entered while in queue */
- int valid_digits; /*!< Digits entered correspond to valid extension. Exited */
- int pos; /*!< Where we are in the queue */
- int prio; /*!< Our priority */
- int last_pos_said; /*!< Last position we told the user */
- time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
- int last_periodic_announce_sound; /*!< The last periodic announcement we made */
- time_t last_pos; /*!< Last time we told the user their position */
- int opos; /*!< Where we started in the queue */
- int handled; /*!< Whether our call was handled */
- int pending; /*!< Non-zero if we are attempting to call a member */
- int max_penalty; /*!< Limit the members that can take this call to this penalty or lower */
- time_t start; /*!< When we started holding */
- time_t expire; /*!< When this entry should expire (time out of queue) */
- struct ast_channel *chan; /*!< Our channel */
- struct queue_ent *next; /*!< The next queue entry */
-};
-
-struct member {
- char interface[80]; /*!< Technology/Location */
- char membername[80]; /*!< Member name to use in queue logs */
- int penalty; /*!< Are we a last resort? */
- int calls; /*!< Number of calls serviced by this member */
- int dynamic; /*!< Are we dynamically added? */
- int realtime; /*!< Is this member realtime? */
- int status; /*!< Status of queue member */
- int paused; /*!< Are we paused (not accepting calls)? */
- time_t lastcall; /*!< When last successful call was hungup */
- unsigned int dead:1; /*!< Used to detect members deleted in realtime */
- unsigned int delme:1; /*!< Flag to delete entry on reload */
-};
-
-struct member_interface {
- char interface[80];
- AST_LIST_ENTRY(member_interface) list; /*!< Next call queue */
-};
-
-static AST_LIST_HEAD_STATIC(interfaces, member_interface);
-
-/* values used in multi-bit flags in call_queue */
-#define QUEUE_EMPTY_NORMAL 1
-#define QUEUE_EMPTY_STRICT 2
-#define ANNOUNCEHOLDTIME_ALWAYS 1
-#define ANNOUNCEHOLDTIME_ONCE 2
-#define QUEUE_EVENT_VARIABLES 3
-
-struct call_queue {
- ast_mutex_t lock;
- char name[80]; /*!< Name */
- char moh[80]; /*!< Music On Hold class to be used */
- char announce[80]; /*!< Announcement to play when call is answered */
- char context[AST_MAX_CONTEXT]; /*!< Exit context */
- unsigned int monjoin:1;
- unsigned int dead:1;
- unsigned int joinempty:2;
- unsigned int eventwhencalled:2;
- unsigned int leavewhenempty:2;
- unsigned int ringinuse:1;
- unsigned int setinterfacevar:1;
- unsigned int reportholdtime:1;
- unsigned int wrapped:1;
- unsigned int timeoutrestart:1;
- unsigned int announceholdtime:2;
- int strategy:4;
- unsigned int maskmemberstatus:1;
- unsigned int realtime:1;
- unsigned int found:1;
- int announcefrequency; /*!< How often to announce their position */
- int periodicannouncefrequency; /*!< How often to play periodic announcement */
- int roundingseconds; /*!< How many seconds do we round to? */
- int holdtime; /*!< Current avg holdtime, based on recursive boxcar filter */
- int callscompleted; /*!< Number of queue calls completed */
- int callsabandoned; /*!< Number of queue calls abandoned */
- int servicelevel; /*!< seconds setting for servicelevel*/
- int callscompletedinsl; /*!< Number of calls answered with servicelevel*/
- char monfmt[8]; /*!< Format to use when recording calls */
- int montype; /*!< Monitor type Monitor vs. MixMonitor */
- char sound_next[80]; /*!< Sound file: "Your call is now first in line" (def. queue-youarenext) */
- char sound_thereare[80]; /*!< Sound file: "There are currently" (def. queue-thereare) */
- char sound_calls[80]; /*!< Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
- char sound_holdtime[80]; /*!< Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
- char sound_minutes[80]; /*!< Sound file: "minutes." (def. queue-minutes) */
- char sound_lessthan[80]; /*!< Sound file: "less-than" (def. queue-lessthan) */
- char sound_seconds[80]; /*!< Sound file: "seconds." (def. queue-seconds) */
- char sound_thanks[80]; /*!< Sound file: "Thank you for your patience." (def. queue-thankyou) */
- char sound_reporthold[80]; /*!< Sound file: "Hold time" (def. queue-reporthold) */
- char sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS][80];/*!< Sound files: Custom announce, no default */
-
- int count; /*!< How many entries */
- int maxlen; /*!< Max number of entries */
- int wrapuptime; /*!< Wrapup Time */
-
- int retry; /*!< Retry calling everyone after this amount of time */
- int timeout; /*!< How long to wait for an answer */
- int weight; /*!< Respective weight */
- int autopause; /*!< Auto pause queue members if they fail to answer */
-
- /* Queue strategy things */
- int rrpos; /*!< Round Robin - position */
- int memberdelay; /*!< Seconds to delay connecting member to caller */
- int autofill; /*!< Ignore the head call status and ring an available agent */
-
- struct ao2_container *members; /*!< Head of the list of members */
- /*!
- * \brief Number of members _logged in_
- * \note There will be members in the members container that are not logged
- * in, so this can not simply be replaced with ao2_container_count().
- */
- int membercount;
- struct queue_ent *head; /*!< Head of the list of callers */
- AST_LIST_ENTRY(call_queue) list; /*!< Next call queue */
-};
-
-static AST_LIST_HEAD_STATIC(queues, call_queue);
-
-static int set_member_paused(const char *queuename, const char *interface, int paused);
-
-static void rr_dep_warning(void)
-{
- static unsigned int warned = 0;
-
- if (!warned) {
- ast_log(LOG_NOTICE, "The 'roundrobin' queue strategy is deprecated. Please use the 'rrmemory' strategy instead.\n");
- warned = 1;
- }
-}
-
-static void monjoin_dep_warning(void)
-{
- static unsigned int warned = 0;
- if (!warned) {
- ast_log(LOG_NOTICE, "The 'monitor-join' queue option is deprecated. Please use monitor-type=mixmonitor instead.\n");
- warned = 1;
- }
-}
-/*! \brief sets the QUEUESTATUS channel variable */
-static void set_queue_result(struct ast_channel *chan, enum queue_result res)
-{
- int i;
-
- for (i = 0; i < sizeof(queue_results) / sizeof(queue_results[0]); i++) {
- if (queue_results[i].id == res) {
- pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
- return;
- }
- }
-}
-
-static char *int2strat(int strategy)
-{
- int x;
-
- for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
- if (strategy == strategies[x].strategy)
- return strategies[x].name;
- }
-
- return "<unknown>";
-}
-
-static int strat2int(const char *strategy)
-{
- int x;
-
- for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
- if (!strcasecmp(strategy, strategies[x].name))
- return strategies[x].strategy;
- }
-
- return -1;
-}
-
-/*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
-static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
-{
- struct queue_ent *cur;
-
- if (!q || !new)
- return;
- if (prev) {
- cur = prev->next;
- prev->next = new;
- } else {
- cur = q->head;
- q->head = new;
- }
- new->next = cur;
- new->parent = q;
- new->pos = ++(*pos);
- new->opos = *pos;
-}
-
-enum queue_member_status {
- QUEUE_NO_MEMBERS,
- QUEUE_NO_REACHABLE_MEMBERS,
- QUEUE_NORMAL
-};
-
-/*! \brief Check if members are available
- *
- * This function checks to see if members are available to be called. If any member
- * is available, the function immediately returns QUEUE_NORMAL. If no members are available,
- * the appropriate reason why is returned
- */
-static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty)
-{
- struct member *member;
- struct ao2_iterator mem_iter;
- enum queue_member_status result = QUEUE_NO_MEMBERS;
-
- ast_mutex_lock(&q->lock);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((member = ao2_iterator_next(&mem_iter))) {
- if (max_penalty && (member->penalty > max_penalty)) {
- ao2_ref(member, -1);
- continue;
- }
-
- if (member->paused) {
- ao2_ref(member, -1);
- continue;
- }
-
- switch (member->status) {
- case AST_DEVICE_INVALID:
- /* nothing to do */
- ao2_ref(member, -1);
- break;
- case AST_DEVICE_UNAVAILABLE:
- result = QUEUE_NO_REACHABLE_MEMBERS;
- ao2_ref(member, -1);
- break;
- default:
- ast_mutex_unlock(&q->lock);
- ao2_ref(member, -1);
- return QUEUE_NORMAL;
- }
- }
-
- ast_mutex_unlock(&q->lock);
- return result;
-}
-
-struct statechange {
- AST_LIST_ENTRY(statechange) entry;
- int state;
- char dev[0];
-};
-
-static int update_status(const char *interface, const int status)
-{
- struct member *cur;
- struct ao2_iterator mem_iter;
- struct call_queue *q;
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((cur = ao2_iterator_next(&mem_iter))) {
- char *tmp_interface;
- char *slash_pos;
- tmp_interface = ast_strdupa(cur->interface);
- if ((slash_pos = strchr(tmp_interface, '/')))
- if ((slash_pos = strchr(slash_pos + 1, '/')))
- *slash_pos = '\0';
-
- if (strcasecmp(interface, tmp_interface)) {
- ao2_ref(cur, -1);
- continue;
- }
-
- if (cur->status != status) {
- cur->status = status;
- if (q->maskmemberstatus) {
- ao2_ref(cur, -1);
- continue;
- }
-
- manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "MemberName: %s\r\n"
- "Membership: %s\r\n"
- "Penalty: %d\r\n"
- "CallsTaken: %d\r\n"
- "LastCall: %d\r\n"
- "Status: %d\r\n"
- "Paused: %d\r\n",
- q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
- cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
- }
- ao2_ref(cur, -1);
- }
- ast_mutex_unlock(&q->lock);
- }
- AST_LIST_UNLOCK(&queues);
-
- return 0;
-}
-
-/*! \brief set a member's status based on device state of that member's interface*/
-static void *handle_statechange(struct statechange *sc)
-{
- struct member_interface *curint;
- char *loc;
- char *technology;
-
- technology = ast_strdupa(sc->dev);
- loc = strchr(technology, '/');
- if (loc) {
- *loc++ = '\0';
- } else {
- return NULL;
- }
-
- AST_LIST_LOCK(&interfaces);
- AST_LIST_TRAVERSE(&interfaces, curint, list) {
- char *interface;
- char *slash_pos;
- interface = ast_strdupa(curint->interface);
- if ((slash_pos = strchr(interface, '/')))
- if ((slash_pos = strchr(slash_pos + 1, '/')))
- *slash_pos = '\0';
-
- if (!strcasecmp(interface, sc->dev))
- break;
- }
- AST_LIST_UNLOCK(&interfaces);
-
- if (!curint) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
- return NULL;
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
-
- update_status(sc->dev, sc->state);
-
- return NULL;
-}
-
-/*!
- * \brief Data used by the device state thread
- */
-static struct {
- /*! Set to 1 to stop the thread */
- unsigned int stop:1;
- /*! The device state monitoring thread */
- pthread_t thread;
- /*! Lock for the state change queue */
- ast_mutex_t lock;
- /*! Condition for the state change queue */
- ast_cond_t cond;
- /*! Queue of state changes */
- AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
-} device_state = {
- .thread = AST_PTHREADT_NULL,
-};
-
-/*! \brief Consumer of the statechange queue */
-static void *device_state_thread(void *data)
-{
- struct statechange *sc = NULL;
-
- while (!device_state.stop) {
- ast_mutex_lock(&device_state.lock);
- if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
- ast_cond_wait(&device_state.cond, &device_state.lock);
- sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
- }
- ast_mutex_unlock(&device_state.lock);
-
- /* Check to see if we were woken up to see the request to stop */
- if (device_state.stop)
- break;
-
- if (!sc)
- continue;
-
- handle_statechange(sc);
-
- free(sc);
- sc = NULL;
- }
-
- if (sc)
- free(sc);
-
- while ((sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry)))
- free(sc);
-
- return NULL;
-}
-/*! \brief Producer of the statechange queue */
-static int statechange_queue(const char *dev, int state, void *ign)
-{
- struct statechange *sc;
-
- if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
- return 0;
-
- sc->state = state;
- strcpy(sc->dev, dev);
-
- ast_mutex_lock(&device_state.lock);
- AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
- ast_cond_signal(&device_state.cond);
- ast_mutex_unlock(&device_state.lock);
-
- return 0;
-}
-/*! \brief allocate space for new queue member and set fields based on parameters passed */
-static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused)
-{
- struct member *cur;
-
- if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
- cur->penalty = penalty;
- cur->paused = paused;
- ast_copy_string(cur->interface, interface, sizeof(cur->interface));
- if (!ast_strlen_zero(membername))
- ast_copy_string(cur->membername, membername, sizeof(cur->membername));
- else
- ast_copy_string(cur->membername, interface, sizeof(cur->membername));
- if (!strchr(cur->interface, '/'))
- ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
- cur->status = ast_device_state(interface);
- }
-
- return cur;
-}
-
-static struct call_queue *alloc_queue(const char *queuename)
-{
- struct call_queue *q;
-
- if ((q = ast_calloc(1, sizeof(*q)))) {
- ast_mutex_init(&q->lock);
- ast_copy_string(q->name, queuename, sizeof(q->name));
- }
- return q;
-}
-
-static int compress_char(const char c)
-{
- if (c < 32)
- return 0;
- else if (c > 96)
- return c - 64;
- else
- return c - 32;
-}
-
-static int member_hash_fn(const void *obj, const int flags)
-{
- const struct member *mem = obj;
- const char *chname = strchr(mem->interface, '/');
- int ret = 0, i;
- if (!chname)
- chname = mem->interface;
- for (i = 0; i < 5 && chname[i]; i++)
- ret += compress_char(chname[i]) << (i * 6);
- return ret;
-}
-
-static int member_cmp_fn(void *obj1, void *obj2, int flags)
-{
- struct member *mem1 = obj1, *mem2 = obj2;
- return strcmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
-}
-
-static void init_queue(struct call_queue *q)
-{
- int i;
-
- q->dead = 0;
- q->retry = DEFAULT_RETRY;
- q->timeout = -1;
- q->maxlen = 0;
- q->announcefrequency = 0;
- q->announceholdtime = 0;
- q->roundingseconds = 0; /* Default - don't announce seconds */
- q->servicelevel = 0;
- q->ringinuse = 1;
- q->setinterfacevar = 0;
- q->autofill = autofill_default;
- q->montype = montype_default;
- q->moh[0] = '\0';
- q->announce[0] = '\0';
- q->context[0] = '\0';
- q->monfmt[0] = '\0';
- q->periodicannouncefrequency = 0;
- q->reportholdtime = 0;
- q->monjoin = 0;
- q->wrapuptime = 0;
- q->joinempty = 0;
- q->leavewhenempty = 0;
- q->memberdelay = 0;
- q->maskmemberstatus = 0;
- q->eventwhencalled = 0;
- q->weight = 0;
- q->timeoutrestart = 0;
- if (!q->members)
- q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn);
- q->membercount = 0;
- q->found = 1;
- ast_copy_string(q->sound_next, "queue-youarenext", sizeof(q->sound_next));
- ast_copy_string(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare));
- ast_copy_string(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls));
- ast_copy_string(q->sound_holdtime, "queue-holdtime", sizeof(q->sound_holdtime));
- ast_copy_string(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes));
- ast_copy_string(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds));
- ast_copy_string(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks));
- ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan));
- ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold));
- ast_copy_string(q->sound_periodicannounce[0], "queue-periodic-announce", sizeof(q->sound_periodicannounce[0]));
- for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
- q->sound_periodicannounce[i][0]='\0';
- }
-}
-
-static void clear_queue(struct call_queue *q)
-{
- q->holdtime = 0;
- q->callscompleted = 0;
- q->callsabandoned = 0;
- q->callscompletedinsl = 0;
- q->wrapuptime = 0;
-}
-
-static int add_to_interfaces(const char *interface)
-{
- struct member_interface *curint;
-
- AST_LIST_LOCK(&interfaces);
- AST_LIST_TRAVERSE(&interfaces, curint, list) {
- if (!strcasecmp(curint->interface, interface))
- break;
- }
-
- if (curint) {
- AST_LIST_UNLOCK(&interfaces);
- return 0;
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
-
- if ((curint = ast_calloc(1, sizeof(*curint)))) {
- ast_copy_string(curint->interface, interface, sizeof(curint->interface));
- AST_LIST_INSERT_HEAD(&interfaces, curint, list);
- }
- AST_LIST_UNLOCK(&interfaces);
-
- return 0;
-}
-
-static int interface_exists_global(const char *interface)
-{
- struct call_queue *q;
- struct member *mem, tmpmem;
- int ret = 0;
-
- ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
- if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
- ao2_ref(mem, -1);
- ret = 1;
- }
- ast_mutex_unlock(&q->lock);
- if (ret)
- break;
- }
- AST_LIST_UNLOCK(&queues);
-
- return ret;
-}
-
-static int remove_from_interfaces(const char *interface)
-{
- struct member_interface *curint;
-
- if (interface_exists_global(interface))
- return 0;
-
- AST_LIST_LOCK(&interfaces);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
- if (!strcasecmp(curint->interface, interface)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
- AST_LIST_REMOVE_CURRENT(&interfaces, list);
- free(curint);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&interfaces);
-
- return 0;
-}
-
-static void clear_and_free_interfaces(void)
-{
- struct member_interface *curint;
-
- AST_LIST_LOCK(&interfaces);
- while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
- free(curint);
- AST_LIST_UNLOCK(&interfaces);
-}
-
-/*! \brief Configure a queue parameter.
-\par
- For error reporting, line number is passed for .conf static configuration.
- For Realtime queues, linenum is -1.
- The failunknown flag is set for config files (and static realtime) to show
- errors for unknown parameters. It is cleared for dynamic realtime to allow
- extra fields in the tables. */
-static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
-{
- if (!strcasecmp(param, "musicclass") ||
- !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
- ast_copy_string(q->moh, val, sizeof(q->moh));
- } else if (!strcasecmp(param, "announce")) {
- ast_copy_string(q->announce, val, sizeof(q->announce));
- } else if (!strcasecmp(param, "context")) {
- ast_copy_string(q->context, val, sizeof(q->context));
- } else if (!strcasecmp(param, "timeout")) {
- q->timeout = atoi(val);
- if (q->timeout < 0)
- q->timeout = DEFAULT_TIMEOUT;
- } else if (!strcasecmp(param, "ringinuse")) {
- q->ringinuse = ast_true(val);
- } else if (!strcasecmp(param, "setinterfacevar")) {
- q->setinterfacevar = ast_true(val);
- } else if (!strcasecmp(param, "monitor-join")) {
- monjoin_dep_warning();
- q->monjoin = ast_true(val);
- } else if (!strcasecmp(param, "monitor-format")) {
- ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
- } else if (!strcasecmp(param, "queue-youarenext")) {
- ast_copy_string(q->sound_next, val, sizeof(q->sound_next));
- } else if (!strcasecmp(param, "queue-thereare")) {
- ast_copy_string(q->sound_thereare, val, sizeof(q->sound_thereare));
- } else if (!strcasecmp(param, "queue-callswaiting")) {
- ast_copy_string(q->sound_calls, val, sizeof(q->sound_calls));
- } else if (!strcasecmp(param, "queue-holdtime")) {
- ast_copy_string(q->sound_holdtime, val, sizeof(q->sound_holdtime));
- } else if (!strcasecmp(param, "queue-minutes")) {
- ast_copy_string(q->sound_minutes, val, sizeof(q->sound_minutes));
- } else if (!strcasecmp(param, "queue-seconds")) {
- ast_copy_string(q->sound_seconds, val, sizeof(q->sound_seconds));
- } else if (!strcasecmp(param, "queue-lessthan")) {
- ast_copy_string(q->sound_lessthan, val, sizeof(q->sound_lessthan));
- } else if (!strcasecmp(param, "queue-thankyou")) {
- ast_copy_string(q->sound_thanks, val, sizeof(q->sound_thanks));
- } else if (!strcasecmp(param, "queue-reporthold")) {
- ast_copy_string(q->sound_reporthold, val, sizeof(q->sound_reporthold));
- } else if (!strcasecmp(param, "announce-frequency")) {
- q->announcefrequency = atoi(val);
- } else if (!strcasecmp(param, "announce-round-seconds")) {
- q->roundingseconds = atoi(val);
- if (q->roundingseconds>60 || q->roundingseconds<0) {
- if (linenum >= 0) {
- ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
- "using 0 instead for queue '%s' at line %d of queues.conf\n",
- val, param, q->name, linenum);
- } else {
- ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
- "using 0 instead for queue '%s'\n", val, param, q->name);
- }
- q->roundingseconds=0;
- }
- } else if (!strcasecmp(param, "announce-holdtime")) {
- if (!strcasecmp(val, "once"))
- q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
- else if (ast_true(val))
- q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
- else
- q->announceholdtime = 0;
- } else if (!strcasecmp(param, "periodic-announce")) {
- if (strchr(val, '|')) {
- char *s, *buf = ast_strdupa(val);
- unsigned int i = 0;
-
- while ((s = strsep(&buf, "|"))) {
- ast_copy_string(q->sound_periodicannounce[i], s, sizeof(q->sound_periodicannounce[i]));
- i++;
- if (i == MAX_PERIODIC_ANNOUNCEMENTS)
- break;
- }
- } else {
- ast_copy_string(q->sound_periodicannounce[0], val, sizeof(q->sound_periodicannounce[0]));
- }
- } else if (!strcasecmp(param, "periodic-announce-frequency")) {
- q->periodicannouncefrequency = atoi(val);
- } else if (!strcasecmp(param, "retry")) {
- q->retry = atoi(val);
- if (q->retry <= 0)
- q->retry = DEFAULT_RETRY;
- } else if (!strcasecmp(param, "wrapuptime")) {
- q->wrapuptime = atoi(val);
- } else if (!strcasecmp(param, "autofill")) {
- q->autofill = ast_true(val);
- } else if (!strcasecmp(param, "monitor-type")) {
- if (!strcasecmp(val, "mixmonitor"))
- q->montype = 1;
- } else if (!strcasecmp(param, "autopause")) {
- q->autopause = ast_true(val);
- } else if (!strcasecmp(param, "maxlen")) {
- q->maxlen = atoi(val);
- if (q->maxlen < 0)
- q->maxlen = 0;
- } else if (!strcasecmp(param, "servicelevel")) {
- q->servicelevel= atoi(val);
- } else if (!strcasecmp(param, "strategy")) {
- q->strategy = strat2int(val);
- if (q->strategy < 0) {
- ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
- val, q->name);
- q->strategy = QUEUE_STRATEGY_RINGALL;
- }
- } else if (!strcasecmp(param, "joinempty")) {
- if (!strcasecmp(val, "strict"))
- q->joinempty = QUEUE_EMPTY_STRICT;
- else if (ast_true(val))
- q->joinempty = QUEUE_EMPTY_NORMAL;
- else
- q->joinempty = 0;
- } else if (!strcasecmp(param, "leavewhenempty")) {
- if (!strcasecmp(val, "strict"))
- q->leavewhenempty = QUEUE_EMPTY_STRICT;
- else if (ast_true(val))
- q->leavewhenempty = QUEUE_EMPTY_NORMAL;
- else
- q->leavewhenempty = 0;
- } else if (!strcasecmp(param, "eventmemberstatus")) {
- q->maskmemberstatus = !ast_true(val);
- } else if (!strcasecmp(param, "eventwhencalled")) {
- if (!strcasecmp(val, "vars")) {
- q->eventwhencalled = QUEUE_EVENT_VARIABLES;
- } else {
- q->eventwhencalled = ast_true(val) ? 1 : 0;
- }
- } else if (!strcasecmp(param, "reportholdtime")) {
- q->reportholdtime = ast_true(val);
- } else if (!strcasecmp(param, "memberdelay")) {
- q->memberdelay = atoi(val);
- } else if (!strcasecmp(param, "weight")) {
- q->weight = atoi(val);
- if (q->weight)
- use_weight++;
- /* With Realtime queues, if the last queue using weights is deleted in realtime,
- we will not see any effect on use_weight until next reload. */
- } else if (!strcasecmp(param, "timeoutrestart")) {
- q->timeoutrestart = ast_true(val);
- } else if (failunknown) {
- if (linenum >= 0) {
- ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
- q->name, param, linenum);
- } else {
- ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
- }
- }
-}
-
-static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str)
-{
- struct member *m, tmpmem;
- int penalty = 0;
- int paused = 0;
-
- if (penalty_str) {
- penalty = atoi(penalty_str);
- if (penalty < 0)
- penalty = 0;
- }
-
- if (paused_str) {
- paused = atoi(paused_str);
- if (paused < 0)
- paused = 0;
- }
-
- /* Find the member, or the place to put a new one. */
- ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
- m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
-
- /* Create a new one if not found, else update penalty */
- if (!m) {
- if ((m = create_queue_member(interface, membername, penalty, paused))) {
- m->dead = 0;
- m->realtime = 1;
- add_to_interfaces(interface);
- ao2_link(q->members, m);
- ao2_ref(m, -1);
- m = NULL;
- q->membercount++;
- }
- } else {
- m->dead = 0; /* Do not delete this one. */
- if (paused_str)
- m->paused = paused;
- m->penalty = penalty;
- ao2_ref(m, -1);
- }
-}
-
-static void free_members(struct call_queue *q, int all)
-{
- /* Free non-dynamic members */
- struct member *cur;
- struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
-
- while ((cur = ao2_iterator_next(&mem_iter))) {
- if (all || !cur->dynamic) {
- ao2_unlink(q->members, cur);
- remove_from_interfaces(cur->interface);
- q->membercount--;
- }
- ao2_ref(cur, -1);
- }
-}
-
-static void destroy_queue(struct call_queue *q)
-{
- free_members(q, 1);
- ast_mutex_destroy(&q->lock);
- ao2_ref(q->members, -1);
- free(q);
-}
-
-/*!\brief Reload a single queue via realtime.
- \return Return the queue, or NULL if it doesn't exist.
- \note Should be called with the global qlock locked. */
-static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
-{
- struct ast_variable *v;
- struct call_queue *q;
- struct member *m;
- struct ao2_iterator mem_iter;
- char *interface = NULL;
- char *tmp, *tmp_name;
- char tmpbuf[64]; /* Must be longer than the longest queue param name. */
-
- /* Find the queue in the in-core list (we will create a new one if not found). */
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!strcasecmp(q->name, queuename))
- break;
- }
-
- /* Static queues override realtime. */
- if (q) {
- ast_mutex_lock(&q->lock);
- if (!q->realtime) {
- if (q->dead) {
- ast_mutex_unlock(&q->lock);
- return NULL;
- } else {
- ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
- ast_mutex_unlock(&q->lock);
- return q;
- }
- }
- } else if (!member_config)
- /* Not found in the list, and it's not realtime ... */
- return NULL;
-
- /* Check if queue is defined in realtime. */
- if (!queue_vars) {
- /* Delete queue from in-core list if it has been deleted in realtime. */
- if (q) {
- /*! \note Hmm, can't seem to distinguish a DB failure from a not
- found condition... So we might delete an in-core queue
- in case of DB failure. */
- ast_log(LOG_DEBUG, "Queue %s not found in realtime.\n", queuename);
-
- q->dead = 1;
- /* Delete if unused (else will be deleted when last caller leaves). */
- if (!q->count) {
- /* Delete. */
- AST_LIST_REMOVE(&queues, q, list);
- ast_mutex_unlock(&q->lock);
- destroy_queue(q);
- } else
- ast_mutex_unlock(&q->lock);
- }
- return NULL;
- }
-
- /* Create a new queue if an in-core entry does not exist yet. */
- if (!q) {
- if (!(q = alloc_queue(queuename)))
- return NULL;
- ast_mutex_lock(&q->lock);
- clear_queue(q);
- q->realtime = 1;
- init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
- AST_LIST_INSERT_HEAD(&queues, q, list);
- }
-
- memset(tmpbuf, 0, sizeof(tmpbuf));
- for (v = queue_vars; v; v = v->next) {
- /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
- if ((tmp = strchr(v->name, '_'))) {
- ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
- tmp_name = tmpbuf;
- tmp = tmp_name;
- while ((tmp = strchr(tmp, '_')))
- *tmp++ = '-';
- } else
- tmp_name = v->name;
-
- if (!ast_strlen_zero(v->value)) {
- /* Don't want to try to set the option if the value is empty */
- queue_set_param(q, tmp_name, v->value, -1, 0);
- }
- }
-
- if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN)
- rr_dep_warning();
-
- /* Temporarily set realtime members dead so we can detect deleted ones.
- * Also set the membercount correctly for realtime*/
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- q->membercount++;
- if (m->realtime)
- m->dead = 1;
- ao2_ref(m, -1);
- }
-
- while ((interface = ast_category_browse(member_config, interface))) {
- rt_handle_member_record(q, interface,
- ast_variable_retrieve(member_config, interface, "membername"),
- ast_variable_retrieve(member_config, interface, "penalty"),
- ast_variable_retrieve(member_config, interface, "paused"));
- }
-
- /* Delete all realtime members that have been deleted in DB. */
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- if (m->dead) {
- ao2_unlink(q->members, m);
- ast_mutex_unlock(&q->lock);
- remove_from_interfaces(m->interface);
- ast_mutex_lock(&q->lock);
- q->membercount--;
- }
- ao2_ref(m, -1);
- }
-
- ast_mutex_unlock(&q->lock);
-
- return q;
-}
-
-static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
-{
- struct ast_variable *var;
- int ret = -1;
-
- if (!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
- return ret;
- while (var) {
- if (!strcmp(var->name, "uniqueid"))
- break;
- var = var->next;
- }
- if (var && !ast_strlen_zero(var->value)) {
- if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
- ret = 0;
- }
- return ret;
-}
-
-static void update_realtime_members(struct call_queue *q)
-{
- struct ast_config *member_config = NULL;
- struct member *m;
- char *interface = NULL;
- struct ao2_iterator mem_iter;
-
- if (!(member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL))) {
- /*This queue doesn't have realtime members*/
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Queue %s has no realtime members defined. No need for update\n", q->name);
- return;
- }
-
- ast_mutex_lock(&q->lock);
-
- /* Temporarily set realtime members dead so we can detect deleted ones.*/
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- if (m->realtime)
- m->dead = 1;
- ao2_ref(m, -1);
- }
-
- while ((interface = ast_category_browse(member_config, interface))) {
- rt_handle_member_record(q, interface,
- S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
- ast_variable_retrieve(member_config, interface, "penalty"),
- ast_variable_retrieve(member_config, interface, "paused"));
- }
-
- /* Delete all realtime members that have been deleted in DB. */
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- if (m->dead) {
- ao2_unlink(q->members, m);
- ast_mutex_unlock(&q->lock);
- remove_from_interfaces(m->interface);
- ast_mutex_lock(&q->lock);
- q->membercount--;
- }
- ao2_ref(m, -1);
- }
- ast_mutex_unlock(&q->lock);
- ast_config_destroy(member_config);
-}
-
-static struct call_queue *load_realtime_queue(const char *queuename)
-{
- struct ast_variable *queue_vars;
- struct ast_config *member_config = NULL;
- struct call_queue *q;
-
- /* Find the queue in the in-core list first. */
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!strcasecmp(q->name, queuename)) {
- break;
- }
- }
- AST_LIST_UNLOCK(&queues);
-
- if (!q || q->realtime) {
- /*! \note Load from realtime before taking the global qlock, to avoid blocking all
- queue operations while waiting for the DB.
-
- This will be two separate database transactions, so we might
- see queue parameters as they were before another process
- changed the queue and member list as it was after the change.
- Thus we might see an empty member list when a queue is
- deleted. In practise, this is unlikely to cause a problem. */
-
- queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
- if (queue_vars) {
- member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
- if (!member_config) {
- ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
- ast_variables_destroy(queue_vars);
- return NULL;
- }
- }
-
- AST_LIST_LOCK(&queues);
-
- q = find_queue_by_name_rt(queuename, queue_vars, member_config);
- if (member_config)
- ast_config_destroy(member_config);
- if (queue_vars)
- ast_variables_destroy(queue_vars);
-
- AST_LIST_UNLOCK(&queues);
- } else {
- update_realtime_members(q);
- }
- return q;
-}
-
-static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
-{
- struct call_queue *q;
- struct queue_ent *cur, *prev = NULL;
- int res = -1;
- int pos = 0;
- int inserted = 0;
- enum queue_member_status stat;
-
- if (!(q = load_realtime_queue(queuename)))
- return res;
-
- AST_LIST_LOCK(&queues);
- ast_mutex_lock(&q->lock);
-
- /* This is our one */
- stat = get_member_status(q, qe->max_penalty);
- if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
- *reason = QUEUE_JOINEMPTY;
- else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
- *reason = QUEUE_JOINUNAVAIL;
- else if (q->maxlen && (q->count >= q->maxlen))
- *reason = QUEUE_FULL;
- else {
- /* There's space for us, put us at the right position inside
- * the queue.
- * Take into account the priority of the calling user */
- inserted = 0;
- prev = NULL;
- cur = q->head;
- while (cur) {
- /* We have higher priority than the current user, enter
- * before him, after all the other users with priority
- * higher or equal to our priority. */
- if ((!inserted) && (qe->prio > cur->prio)) {
- insert_entry(q, prev, qe, &pos);
- inserted = 1;
- }
- cur->pos = ++pos;
- prev = cur;
- cur = cur->next;
- }
- /* No luck, join at the end of the queue */
- if (!inserted)
- insert_entry(q, prev, qe, &pos);
- ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
- ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
- ast_copy_string(qe->context, q->context, sizeof(qe->context));
- q->count++;
- res = 0;
- manager_event(EVENT_FLAG_CALL, "Join",
- "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
- qe->chan->name,
- S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
- S_OR(qe->chan->cid.cid_name, "unknown"),
- q->name, qe->pos, q->count, qe->chan->uniqueid );
- if (option_debug)
- ast_log(LOG_DEBUG, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
- }
- ast_mutex_unlock(&q->lock);
- AST_LIST_UNLOCK(&queues);
-
- return res;
-}
-
-static int play_file(struct ast_channel *chan, char *filename)
-{
- int res;
-
- ast_stopstream(chan);
-
- res = ast_streamfile(chan, filename, chan->language);
- if (!res)
- res = ast_waitstream(chan, AST_DIGIT_ANY);
-
- ast_stopstream(chan);
-
- return res;
-}
-
-static int valid_exit(struct queue_ent *qe, char digit)
-{
- int digitlen = strlen(qe->digits);
-
- /* Prevent possible buffer overflow */
- if (digitlen < sizeof(qe->digits) - 2) {
- qe->digits[digitlen] = digit;
- qe->digits[digitlen + 1] = '\0';
- } else {
- qe->digits[0] = '\0';
- return 0;
- }
-
- /* If there's no context to goto, short-circuit */
- if (ast_strlen_zero(qe->context))
- return 0;
-
- /* If the extension is bad, then reset the digits to blank */
- if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
- qe->digits[0] = '\0';
- return 0;
- }
-
- /* We have an exact match */
- if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
- qe->valid_digits = 1;
- /* Return 1 on a successful goto */
- return 1;
- }
-
- return 0;
-}
-
-static int say_position(struct queue_ent *qe)
-{
- int res = 0, avgholdmins, avgholdsecs;
- time_t now;
-
- /* Check to see if this is ludicrous -- if we just announced position, don't do it again*/
- time(&now);
- if ((now - qe->last_pos) < 15)
- return 0;
-
- /* If either our position has changed, or we are over the freq timer, say position */
- if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
- return 0;
-
- ast_moh_stop(qe->chan);
- /* Say we're next, if we are */
- if (qe->pos == 1) {
- res = play_file(qe->chan, qe->parent->sound_next);
- if (res)
- goto playout;
- else
- goto posout;
- } else {
- res = play_file(qe->chan, qe->parent->sound_thereare);
- if (res)
- goto playout;
- res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
- if (res)
- goto playout;
- res = play_file(qe->chan, qe->parent->sound_calls);
- if (res)
- goto playout;
- }
- /* Round hold time to nearest minute */
- avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
-
- /* If they have specified a rounding then round the seconds as well */
- if (qe->parent->roundingseconds) {
- avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
- avgholdsecs *= qe->parent->roundingseconds;
- } else {
- avgholdsecs = 0;
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
-
- /* If the hold time is >1 min, if it's enabled, and if it's not
- supposed to be only once and we have already said it, say it */
- if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
- (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
- res = play_file(qe->chan, qe->parent->sound_holdtime);
- if (res)
- goto playout;
-
- if (avgholdmins > 0) {
- if (avgholdmins < 2) {
- res = play_file(qe->chan, qe->parent->sound_lessthan);
- if (res)
- goto playout;
-
- res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
- if (res)
- goto playout;
- } else {
- res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
- if (res)
- goto playout;
- }
-
- res = play_file(qe->chan, qe->parent->sound_minutes);
- if (res)
- goto playout;
- }
- if (avgholdsecs>0) {
- res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
- if (res)
- goto playout;
-
- res = play_file(qe->chan, qe->parent->sound_seconds);
- if (res)
- goto playout;
- }
-
- }
-
-posout:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n",
- qe->chan->name, qe->parent->name, qe->pos);
- res = play_file(qe->chan, qe->parent->sound_thanks);
-
-playout:
- if ((res > 0 && !valid_exit(qe, res)) || res < 0)
- res = 0;
-
- /* Set our last_pos indicators */
- qe->last_pos = now;
- qe->last_pos_said = qe->pos;
-
- /* Don't restart music on hold if we're about to exit the caller from the queue */
- if (!res)
- ast_moh_start(qe->chan, qe->moh, NULL);
-
- return res;
-}
-
-static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
-{
- int oldvalue;
-
- /* Calculate holdtime using a recursive boxcar filter */
- /* Thanks to SRT for this contribution */
- /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
-
- ast_mutex_lock(&qe->parent->lock);
- oldvalue = qe->parent->holdtime;
- qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
- ast_mutex_unlock(&qe->parent->lock);
-}
-
-
-static void leave_queue(struct queue_ent *qe)
-{
- struct call_queue *q;
- struct queue_ent *cur, *prev = NULL;
- int pos = 0;
-
- if (!(q = qe->parent))
- return;
- ast_mutex_lock(&q->lock);
-
- prev = NULL;
- for (cur = q->head; cur; cur = cur->next) {
- if (cur == qe) {
- q->count--;
-
- /* Take us out of the queue */
- manager_event(EVENT_FLAG_CALL, "Leave",
- "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
- qe->chan->name, q->name, q->count, qe->chan->uniqueid);
- if (option_debug)
- ast_log(LOG_DEBUG, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
- /* Take us out of the queue */
- if (prev)
- prev->next = cur->next;
- else
- q->head = cur->next;
- } else {
- /* Renumber the people after us in the queue based on a new count */
- cur->pos = ++pos;
- prev = cur;
- }
- }
- ast_mutex_unlock(&q->lock);
-
- if (q->dead && !q->count) {
- /* It's dead and nobody is in it, so kill it */
- AST_LIST_LOCK(&queues);
- AST_LIST_REMOVE(&queues, q, list);
- AST_LIST_UNLOCK(&queues);
- destroy_queue(q);
- }
-}
-
-/* Hang up a list of outgoing calls */
-static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
-{
- struct callattempt *oo;
-
- while (outgoing) {
- /* Hangup any existing lines we have open */
- if (outgoing->chan && (outgoing->chan != exception))
- ast_hangup(outgoing->chan);
- oo = outgoing;
- outgoing = outgoing->q_next;
- if (oo->member)
- ao2_ref(oo->member, -1);
- free(oo);
- }
-}
-
-
-/* traverse all defined queues which have calls waiting and contain this member
- return 0 if no other queue has precedence (higher weight) or 1 if found */
-static int compare_weight(struct call_queue *rq, struct member *member)
-{
- struct call_queue *q;
- struct member *mem;
- int found = 0;
-
- /* &qlock and &rq->lock already set by try_calling()
- * to solve deadlock */
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (q == rq) /* don't check myself, could deadlock */
- continue;
- ast_mutex_lock(&q->lock);
- if (q->count && q->members) {
- if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
- ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
- if (q->weight > rq->weight) {
- ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
- found = 1;
- }
- ao2_ref(mem, -1);
- }
- }
- ast_mutex_unlock(&q->lock);
- if (found)
- break;
- }
- return found;
-}
-
-/*! \brief common hangup actions */
-static void do_hang(struct callattempt *o)
-{
- o->stillgoing = 0;
- ast_hangup(o->chan);
- o->chan = NULL;
-}
-
-static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
-{
- char *tmp = alloca(len);
-
- if (pbx_builtin_serialize_variables(chan, tmp, len)) {
- int i, j;
-
- /* convert "\n" to "\nVariable: " */
- strcpy(vars, "Variable: ");
-
- for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
- vars[j] = tmp[i];
-
- if (tmp[i + 1] == '\0')
- break;
- if (tmp[i] == '\n') {
- vars[j++] = '\r';
- vars[j++] = '\n';
-
- ast_copy_string(&(vars[j]), "Variable: ", len - j);
- j += 9;
- }
- }
- if (j > len - 3)
- j = len - 3;
- vars[j++] = '\r';
- vars[j++] = '\n';
- vars[j] = '\0';
- } else {
- /* there are no channel variables; leave it blank */
- *vars = '\0';
- }
- return vars;
-}
-
-/*! \brief Part 2 of ring_one
- *
- * Does error checking before attempting to request a channel and call a member. This
- * function is only called from ring_one
- */
-static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
-{
- int res;
- int status;
- char tech[256];
- char *location;
- const char *macrocontext, *macroexten;
-
- /* on entry here, we know that tmp->chan == NULL */
- if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface);
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
- (*busies)++;
- return 0;
- }
-
- if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "%s in use, can't receive call\n", tmp->interface);
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
- return 0;
- }
-
- if (tmp->member->paused) {
- if (option_debug)
- ast_log(LOG_DEBUG, "%s paused, can't receive call\n", tmp->interface);
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
- return 0;
- }
- if (use_weight && compare_weight(qe->parent,tmp->member)) {
- ast_log(LOG_DEBUG, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
- (*busies)++;
- return 0;
- }
-
- ast_copy_string(tech, tmp->interface, sizeof(tech));
- if ((location = strchr(tech, '/')))
- *location++ = '\0';
- else
- location = "";
-
- /* Request the peer */
- tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
- if (!tmp->chan) { /* If we can't, just go on to the next call */
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
-
- update_status(tmp->member->interface, ast_device_state(tmp->member->interface));
-
- ast_mutex_lock(&qe->parent->lock);
- qe->parent->rrpos++;
- ast_mutex_unlock(&qe->parent->lock);
-
- (*busies)++;
- return 0;
- }
-
- tmp->chan->appl = "AppQueue";
- tmp->chan->data = "(Outgoing Line)";
- tmp->chan->whentohangup = 0;
- if (tmp->chan->cid.cid_num)
- free(tmp->chan->cid.cid_num);
- tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
- if (tmp->chan->cid.cid_name)
- free(tmp->chan->cid.cid_name);
- tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
- if (tmp->chan->cid.cid_ani)
- free(tmp->chan->cid.cid_ani);
- tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
-
- /* Inherit specially named variables from parent channel */
- ast_channel_inherit_variables(qe->chan, tmp->chan);
-
- /* Presense of ADSI CPE on outgoing channel follows ours */
- tmp->chan->adsicpe = qe->chan->adsicpe;
-
- /* Inherit context and extension */
- ast_channel_lock(qe->chan);
- macrocontext = pbx_builtin_getvar_helper(qe->chan, "MACRO_CONTEXT");
- if (!ast_strlen_zero(macrocontext))
- ast_copy_string(tmp->chan->dialcontext, macrocontext, sizeof(tmp->chan->dialcontext));
- else
- ast_copy_string(tmp->chan->dialcontext, qe->chan->context, sizeof(tmp->chan->dialcontext));
- macroexten = pbx_builtin_getvar_helper(qe->chan, "MACRO_EXTEN");
- if (!ast_strlen_zero(macroexten))
- ast_copy_string(tmp->chan->exten, macroexten, sizeof(tmp->chan->exten));
- else
- ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
- ast_channel_unlock(qe->chan);
-
- /* Place the call, but don't wait on the answer */
- if ((res = ast_call(tmp->chan, location, 0))) {
- /* Again, keep going even if there's an error */
- if (option_debug)
- ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface);
- do_hang(tmp);
- (*busies)++;
- return 0;
- } else if (qe->parent->eventwhencalled) {
- char vars[2048];
-
- manager_event(EVENT_FLAG_AGENT, "AgentCalled",
- "AgentCalled: %s\r\n"
- "AgentName: %s\r\n"
- "ChannelCalling: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n"
- "Context: %s\r\n"
- "Extension: %s\r\n"
- "Priority: %d\r\n"
- "%s",
- tmp->interface, tmp->member->membername, qe->chan->name,
- tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
- tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
- qe->chan->context, qe->chan->exten, qe->chan->priority,
- qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface);
- }
-
- return 1;
-}
-
-/*! \brief find the entry with the best metric, or NULL */
-static struct callattempt *find_best(struct callattempt *outgoing)
-{
- struct callattempt *best = NULL, *cur;
-
- for (cur = outgoing; cur; cur = cur->q_next) {
- if (cur->stillgoing && /* Not already done */
- !cur->chan && /* Isn't already going */
- (!best || cur->metric < best->metric)) { /* We haven't found one yet, or it's better */
- best = cur;
- }
- }
-
- return best;
-}
-
-/*! \brief Place a call to a queue member
- *
- * Once metrics have been calculated for each member, this function is used
- * to place a call to the appropriate member (or members). The low-level
- * channel-handling and error detection is handled in ring_entry
- *
- * Returns 1 if a member was called successfully, 0 otherwise
- */
-static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
-{
- int ret = 0;
-
- while (ret == 0) {
- struct callattempt *best = find_best(outgoing);
- if (!best) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Nobody left to try ringing in queue\n");
- break;
- }
- if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
- struct callattempt *cur;
- /* Ring everyone who shares this best metric (for ringall) */
- for (cur = outgoing; cur; cur = cur->q_next) {
- if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
- if (option_debug)
- ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
- ret |= ring_entry(qe, cur, busies);
- }
- }
- } else {
- /* Ring just the best channel */
- if (option_debug)
- ast_log(LOG_DEBUG, "Trying '%s' with metric %d\n", best->interface, best->metric);
- ret = ring_entry(qe, best, busies);
- }
- }
-
- return ret;
-}
-
-static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
-{
- struct callattempt *best = find_best(outgoing);
-
- if (best) {
- /* Ring just the best channel */
- if (option_debug)
- ast_log(LOG_DEBUG, "Next is '%s' with metric %d\n", best->interface, best->metric);
- qe->parent->rrpos = best->metric % 1000;
- } else {
- /* Just increment rrpos */
- if (qe->parent->wrapped) {
- /* No more channels, start over */
- qe->parent->rrpos = 0;
- } else {
- /* Prioritize next entry */
- qe->parent->rrpos++;
- }
- }
- qe->parent->wrapped = 0;
-
- return 0;
-}
-
-static int say_periodic_announcement(struct queue_ent *qe)
-{
- int res = 0;
- time_t now;
-
- /* Get the current time */
- time(&now);
-
- /* Check to see if it is time to announce */
- if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
- return 0;
-
- /* Stop the music on hold so we can play our own file */
- ast_moh_stop(qe->chan);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playing periodic announcement\n");
-
- /* Check to make sure we have a sound file. If not, reset to the first sound file */
- if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS || !strlen(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound])) {
- qe->last_periodic_announce_sound = 0;
- }
-
- /* play the announcement */
- res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]);
-
- if ((res > 0 && !valid_exit(qe, res)) || res < 0)
- res = 0;
-
- /* Resume Music on Hold if the caller is going to stay in the queue */
- if (!res)
- ast_moh_start(qe->chan, qe->moh, NULL);
-
- /* update last_periodic_announce_time */
- qe->last_periodic_announce_time = now;
-
- /* Update the current periodic announcement to the next announcement */
- qe->last_periodic_announce_sound++;
-
- return res;
-}
-
-static void record_abandoned(struct queue_ent *qe)
-{
- ast_mutex_lock(&qe->parent->lock);
- manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
- "Queue: %s\r\n"
- "Uniqueid: %s\r\n"
- "Position: %d\r\n"
- "OriginalPosition: %d\r\n"
- "HoldTime: %d\r\n",
- qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
-
- qe->parent->callsabandoned++;
- ast_mutex_unlock(&qe->parent->lock);
-}
-
-/*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
-static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
-{
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", rnatime);
- ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
- if (qe->parent->autopause) {
- if (!set_member_paused(qe->parent->name, interface, 1)) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
- } else {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
- }
- }
- return;
-}
-
-#define AST_MAX_WATCHERS 256
-/*! \brief Wait for a member to answer the call
- *
- * \param[in] qe the queue_ent corresponding to the caller in the queue
- * \param[in] outgoing the list of callattempts. Relevant ones will have their chan and stillgoing parameters non-zero
- * \param[in] to the amount of time (in milliseconds) to wait for a response
- * \param[out] digit if a user presses a digit to exit the queue, this is the digit the caller pressed
- * \param[in] prebusies number of busy members calculated prior to calling wait_for_answer
- * \param[in] caller_disconnect if the 'H' option is used when calling Queue(), this is used to detect if the caller pressed * to disconnect the call
- * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
- */
-static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
-{
- char *queue = qe->parent->name;
- struct callattempt *o, *start = NULL, *prev = NULL;
- int status;
- int numbusies = prebusies;
- int numnochan = 0;
- int stillgoing = 0;
- int orig = *to;
- struct ast_frame *f;
- struct callattempt *peer = NULL;
- struct ast_channel *winner;
- struct ast_channel *in = qe->chan;
- char on[80] = "";
- char membername[80] = "";
- long starttime = 0;
- long endtime = 0;
-
- starttime = (long) time(NULL);
-
- while (*to && !peer) {
- int numlines, retry, pos = 1;
- struct ast_channel *watchers[AST_MAX_WATCHERS];
- watchers[0] = in;
- start = NULL;
-
- for (retry = 0; retry < 2; retry++) {
- numlines = 0;
- for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
- if (o->stillgoing) { /* Keep track of important channels */
- stillgoing = 1;
- if (o->chan) {
- watchers[pos++] = o->chan;
- if (!start)
- start = o;
- else
- prev->call_next = o;
- prev = o;
- }
- }
- numlines++;
- }
- if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
- (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
- break;
- /* On "ringall" strategy we only move to the next penalty level
- when *all* ringing phones are done in the current penalty level */
- ring_one(qe, outgoing, &numbusies);
- /* and retry... */
- }
- if (pos == 1 /* not found */) {
- if (numlines == (numbusies + numnochan)) {
- ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
- } else {
- ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
- }
- *to = 0;
- return NULL;
- }
- winner = ast_waitfor_n(watchers, pos, to);
- for (o = start; o; o = o->call_next) {
- if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) {
- if (!peer) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
- peer = o;
- }
- } else if (o->chan && (o->chan == winner)) {
-
- ast_copy_string(on, o->member->interface, sizeof(on));
- ast_copy_string(membername, o->member->membername, sizeof(membername));
-
- if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
- numnochan++;
- do_hang(o);
- winner = NULL;
- continue;
- } else if (!ast_strlen_zero(o->chan->call_forward)) {
- char tmpchan[256];
- char *stuff;
- char *tech;
-
- ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
- if ((stuff = strchr(tmpchan, '/'))) {
- *stuff++ = '\0';
- tech = tmpchan;
- } else {
- snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
- stuff = tmpchan;
- tech = "Local";
- }
- /* Before processing channel, go ahead and check for forwarding */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
- /* Setup parameters */
- o->chan = ast_request(tech, in->nativeformats, stuff, &status);
- if (!o->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
- o->stillgoing = 0;
- numnochan++;
- } else {
- ast_channel_inherit_variables(in, o->chan);
- ast_channel_datastore_inherit(in, o->chan);
- if (o->chan->cid.cid_num)
- free(o->chan->cid.cid_num);
- o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
-
- if (o->chan->cid.cid_name)
- free(o->chan->cid.cid_name);
- o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
-
- ast_string_field_set(o->chan, accountcode, in->accountcode);
- o->chan->cdrflags = in->cdrflags;
-
- if (in->cid.cid_ani) {
- if (o->chan->cid.cid_ani)
- free(o->chan->cid.cid_ani);
- o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
- }
- if (o->chan->cid.cid_rdnis)
- free(o->chan->cid.cid_rdnis);
- o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
- if (ast_call(o->chan, tmpchan, 0)) {
- ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
- do_hang(o);
- numnochan++;
- }
- }
- /* Hangup the original channel now, in case we needed it */
- ast_hangup(winner);
- continue;
- }
- f = ast_read(winner);
- if (f) {
- if (f->frametype == AST_FRAME_CONTROL) {
- switch (f->subclass) {
- case AST_CONTROL_ANSWER:
- /* This is our guy if someone answered. */
- if (!peer) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
- peer = o;
- }
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
- if (in->cdr)
- ast_cdr_busy(in->cdr);
- do_hang(o);
- endtime = (long)time(NULL);
- endtime -= starttime;
- rna(endtime*1000, qe, on, membername);
- if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
- if (qe->parent->timeoutrestart)
- *to = orig;
- ring_one(qe, outgoing, &numbusies);
- }
- numbusies++;
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
- if (in->cdr)
- ast_cdr_busy(in->cdr);
- endtime = (long)time(NULL);
- endtime -= starttime;
- rna(endtime*1000, qe, on, membername);
- do_hang(o);
- if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
- if (qe->parent->timeoutrestart)
- *to = orig;
- ring_one(qe, outgoing, &numbusies);
- }
- numbusies++;
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
- break;
- case AST_CONTROL_OFFHOOK:
- /* Ignore going off hook */
- break;
- default:
- ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
- }
- }
- ast_frfree(f);
- } else {
- endtime = (long) time(NULL) - starttime;
- rna(endtime * 1000, qe, on, membername);
- do_hang(o);
- if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
- if (qe->parent->timeoutrestart)
- *to = orig;
- ring_one(qe, outgoing, &numbusies);
- }
- }
- }
- }
- if (winner == in) {
- f = ast_read(in);
- if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
- /* Got hung up */
- *to = -1;
- if (f)
- ast_frfree(f);
- return NULL;
- }
- if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
- *to = 0;
- ast_frfree(f);
- return NULL;
- }
- if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c\n", f->subclass);
- *to = 0;
- *digit = f->subclass;
- ast_frfree(f);
- return NULL;
- }
- ast_frfree(f);
- }
- if (!*to) {
- for (o = start; o; o = o->call_next)
- rna(orig, qe, o->interface, o->member->membername);
- }
- }
-
- return peer;
-}
-/*! \brief Check if we should start attempting to call queue members
- *
- * The behavior of this function is dependent first on whether autofill is enabled
- * and second on whether the ring strategy is ringall. If autofill is not enabled,
- * then return true if we're the head of the queue. If autofill is enabled, then
- * we count the available members and see if the number of available members is enough
- * that given our position in the queue, we would theoretically be able to connect to
- * one of those available members
- */
-static int is_our_turn(struct queue_ent *qe)
-{
- struct queue_ent *ch;
- struct member *cur;
- int avl = 0;
- int idx = 0;
- int res;
-
- if (!qe->parent->autofill) {
- /* Atomically read the parent head -- does not need a lock */
- ch = qe->parent->head;
- /* If we are now at the top of the head, break out */
- if (ch == qe) {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
- res = 1;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
- res = 0;
- }
-
- } else {
- /* This needs a lock. How many members are available to be served? */
- ast_mutex_lock(&qe->parent->lock);
-
- ch = qe->parent->head;
-
- if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Even though there may be multiple members available, the strategy is ringall so only the head call is allowed in\n");
- avl = 1;
- } else {
- struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
- while ((cur = ao2_iterator_next(&mem_iter))) {
- switch (cur->status) {
- case AST_DEVICE_INUSE:
- if (!qe->parent->ringinuse)
- break;
- /* else fall through */
- case AST_DEVICE_NOT_INUSE:
- case AST_DEVICE_UNKNOWN:
- if (!cur->paused)
- avl++;
- break;
- }
- ao2_ref(cur, -1);
- }
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "There are %d available members.\n", avl);
-
- while ((idx < avl) && (ch) && (ch != qe)) {
- if (!ch->pending)
- idx++;
- ch = ch->next;
- }
-
- /* If the queue entry is within avl [the number of available members] calls from the top ... */
- if (ch && idx < avl) {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
- res = 1;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
- res = 0;
- }
-
- ast_mutex_unlock(&qe->parent->lock);
- }
-
- return res;
-}
-/*! \brief The waiting areas for callers who are not actively calling members
- *
- * This function is one large loop. This function will return if a caller
- * either exits the queue or it becomes that caller's turn to attempt calling
- * queue members. Inside the loop, we service the caller with periodic announcements,
- * holdtime announcements, etc. as configured in queues.conf
- *
- * \retval 0 if the caller's turn has arrived
- * \retval -1 if the caller should exit the queue.
- */
-static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
-{
- int res = 0;
-
- /* This is the holding pen for callers 2 through maxlen */
- for (;;) {
- enum queue_member_status stat;
-
- if (is_our_turn(qe))
- break;
-
- /* If we have timed out, break out */
- if (qe->expire && (time(NULL) > qe->expire)) {
- *reason = QUEUE_TIMEOUT;
- break;
- }
-
- stat = get_member_status(qe->parent, qe->max_penalty);
-
- /* leave the queue if no agents, if enabled */
- if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
- *reason = QUEUE_LEAVEEMPTY;
- ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
- leave_queue(qe);
- break;
- }
-
- /* leave the queue if no reachable agents, if enabled */
- if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
- *reason = QUEUE_LEAVEUNAVAIL;
- ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
- leave_queue(qe);
- break;
- }
-
- /* Make a position announcement, if enabled */
- if (qe->parent->announcefrequency && !ringing &&
- (res = say_position(qe)))
- break;
-
- /* Make a periodic announcement, if enabled */
- if (qe->parent->periodicannouncefrequency && !ringing &&
- (res = say_periodic_announcement(qe)))
- break;
-
- /* Wait a second before checking again */
- if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
- if (res > 0 && !valid_exit(qe, res))
- res = 0;
- else
- break;
- }
- }
-
- return res;
-}
-
-static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
-{
- ast_mutex_lock(&q->lock);
- time(&member->lastcall);
- member->calls++;
- q->callscompleted++;
- if (callcompletedinsl)
- q->callscompletedinsl++;
- ast_mutex_unlock(&q->lock);
- return 0;
-}
-
-/*! \brief Calculate the metric of each member in the outgoing callattempts
- *
- * A numeric metric is given to each member depending on the ring strategy used
- * by the queue. Members with lower metrics will be called before members with
- * higher metrics
- */
-static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
-{
- if (qe->max_penalty && (mem->penalty > qe->max_penalty))
- return -1;
-
- switch (q->strategy) {
- case QUEUE_STRATEGY_RINGALL:
- /* Everyone equal, except for penalty */
- tmp->metric = mem->penalty * 1000000;
- break;
- case QUEUE_STRATEGY_ROUNDROBIN:
- if (!pos) {
- if (!q->wrapped) {
- /* No more channels, start over */
- q->rrpos = 0;
- } else {
- /* Prioritize next entry */
- q->rrpos++;
- }
- q->wrapped = 0;
- }
- /* Fall through */
- case QUEUE_STRATEGY_RRMEMORY:
- if (pos < q->rrpos) {
- tmp->metric = 1000 + pos;
- } else {
- if (pos > q->rrpos)
- /* Indicate there is another priority */
- q->wrapped = 1;
- tmp->metric = pos;
- }
- tmp->metric += mem->penalty * 1000000;
- break;
- case QUEUE_STRATEGY_RANDOM:
- tmp->metric = ast_random() % 1000;
- tmp->metric += mem->penalty * 1000000;
- break;
- case QUEUE_STRATEGY_FEWESTCALLS:
- tmp->metric = mem->calls;
- tmp->metric += mem->penalty * 1000000;
- break;
- case QUEUE_STRATEGY_LEASTRECENT:
- if (!mem->lastcall)
- tmp->metric = 0;
- else
- tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
- tmp->metric += mem->penalty * 1000000;
- break;
- default:
- ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
- break;
- }
- return 0;
-}
-/*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
- *
- * Here is the process of this function
- * 1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
- * 2. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
- * iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
- * member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
- * during each iteration, we call calc_metric to determine which members should be rung when.
- * 3. Call ring_one to place a call to the appropriate member(s)
- * 4. Call wait_for_answer to wait for an answer. If no one answers, return.
- * 5. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
- * 6. Start the monitor or mixmonitor if the option is set
- * 7. Remove the caller from the queue to allow other callers to advance
- * 8. Bridge the call.
- * 9. Do any post processing after the call has disconnected.
- *
- * \param[in] qe the queue_ent structure which corresponds to the caller attempting to reach members
- * \param[in] options the options passed as the third parameter to the Queue() application
- * \param[in] url the url passed as the fourth parameter to the Queue() application
- * \param[in,out] tries the number of times we have tried calling queue members
- * \param[out] noption set if the call to Queue() has the 'n' option set.
- * \param[in] agi the agi passed as the fifth parameter to the Queue() application
- */
-
-static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *tries, int *noption, const char *agi)
-{
- struct member *cur;
- struct callattempt *outgoing = NULL; /* the list of calls we are building */
- int to;
- char oldexten[AST_MAX_EXTENSION]="";
- char oldcontext[AST_MAX_CONTEXT]="";
- char queuename[256]="";
- struct ast_channel *peer;
- struct ast_channel *which;
- struct callattempt *lpeer;
- struct member *member;
- struct ast_app *app;
- int res = 0, bridge = 0;
- int numbusies = 0;
- int x=0;
- char *announce = NULL;
- char digit = 0;
- time_t callstart;
- time_t now = time(NULL);
- struct ast_bridge_config bridge_config;
- char nondataquality = 1;
- char *agiexec = NULL;
- int ret = 0;
- const char *monitorfilename;
- const char *monitor_exec;
- const char *monitor_options;
- char tmpid[256], tmpid2[256];
- char meid[1024], meid2[1024];
- char mixmonargs[1512];
- struct ast_app *mixmonapp = NULL;
- char *p;
- char vars[2048];
- int forwardsallowed = 1;
- int callcompletedinsl;
- struct ao2_iterator memi;
- struct ast_datastore *datastore;
-
- ast_channel_lock(qe->chan);
- datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
- ast_channel_unlock(qe->chan);
-
- memset(&bridge_config, 0, sizeof(bridge_config));
- time(&now);
-
- for (; options && *options; options++)
- switch (*options) {
- case 't':
- ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
- break;
- case 'T':
- ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
- break;
- case 'w':
- ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
- break;
- case 'W':
- ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
- break;
- case 'd':
- nondataquality = 0;
- break;
- case 'h':
- ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
- break;
- case 'H':
- ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
- break;
- case 'n':
- if (qe->parent->strategy == QUEUE_STRATEGY_ROUNDROBIN || qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY)
- (*tries)++;
- else
- *tries = qe->parent->membercount;
- *noption = 1;
- break;
- case 'i':
- forwardsallowed = 0;
- break;
- }
-
- /* Hold the lock while we setup the outgoing calls */
- if (use_weight)
- AST_LIST_LOCK(&queues);
- ast_mutex_lock(&qe->parent->lock);
- if (option_debug)
- ast_log(LOG_DEBUG, "%s is trying to call a queue member.\n",
- qe->chan->name);
- ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
- if (!ast_strlen_zero(qe->announce))
- announce = qe->announce;
- if (!ast_strlen_zero(announceoverride))
- announce = announceoverride;
-
- memi = ao2_iterator_init(qe->parent->members, 0);
- while ((cur = ao2_iterator_next(&memi))) {
- struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
- struct ast_dialed_interface *di;
- AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
- if (!tmp) {
- ao2_ref(cur, -1);
- ast_mutex_unlock(&qe->parent->lock);
- if (use_weight)
- AST_LIST_UNLOCK(&queues);
- goto out;
- }
- if (!datastore) {
- if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
- ao2_ref(cur, -1);
- ast_mutex_unlock(&qe->parent->lock);
- if (use_weight)
- AST_LIST_UNLOCK(&queues);
- free(tmp);
- goto out;
- }
- datastore->inheritance = DATASTORE_INHERIT_FOREVER;
- if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
- ao2_ref(cur, -1);
- ast_mutex_unlock(&qe->parent->lock);
- if (use_weight)
- AST_LIST_UNLOCK(&queues);
- free(tmp);
- goto out;
- }
- datastore->data = dialed_interfaces;
- AST_LIST_HEAD_INIT(dialed_interfaces);
-
- ast_channel_lock(qe->chan);
- ast_channel_datastore_add(qe->chan, datastore);
- ast_channel_unlock(qe->chan);
- } else
- dialed_interfaces = datastore->data;
-
- AST_LIST_LOCK(dialed_interfaces);
- AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
- if (!strcasecmp(cur->interface, di->interface)) {
- ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n",
- di->interface);
- break;
- }
- }
- AST_LIST_UNLOCK(dialed_interfaces);
-
- if (di) {
- free(tmp);
- continue;
- }
-
- /* It is always ok to dial a Local interface. We only keep track of
- * which "real" interfaces have been dialed. The Local channel will
- * inherit this list so that if it ends up dialing a real interface,
- * it won't call one that has already been called. */
- if (strncasecmp(cur->interface, "Local/", 6)) {
- if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
- ao2_ref(cur, -1);
- ast_mutex_unlock(&qe->parent->lock);
- if (use_weight)
- AST_LIST_UNLOCK(&queues);
- free(tmp);
- goto out;
- }
- strcpy(di->interface, cur->interface);
-
- AST_LIST_LOCK(dialed_interfaces);
- AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
- AST_LIST_UNLOCK(dialed_interfaces);
- }
-
- tmp->stillgoing = -1;
- tmp->member = cur;
- tmp->oldstatus = cur->status;
- tmp->lastcall = cur->lastcall;
- ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
- /* Special case: If we ring everyone, go ahead and ring them, otherwise
- just calculate their metric for the appropriate strategy */
- if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
- /* Put them in the list of outgoing thingies... We're ready now.
- XXX If we're forcibly removed, these outgoing calls won't get
- hung up XXX */
- tmp->q_next = outgoing;
- outgoing = tmp;
- /* If this line is up, don't try anybody else */
- if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
- break;
- } else {
- ao2_ref(cur, -1);
- free(tmp);
- }
- }
- if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
- to = (qe->expire - now) * 1000;
- else
- to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
- ++qe->pending;
- ast_mutex_unlock(&qe->parent->lock);
- ring_one(qe, outgoing, &numbusies);
- if (use_weight)
- AST_LIST_UNLOCK(&queues);
- lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
- /* The ast_channel_datastore_remove() function could fail here if the
- * datastore was moved to another channel during a masquerade. If this is
- * the case, don't free the datastore here because later, when the channel
- * to which the datastore was moved hangs up, it will attempt to free this
- * datastore again, causing a crash
- */
- if (datastore && !ast_channel_datastore_remove(qe->chan, datastore)) {
- ast_channel_datastore_free(datastore);
- }
- ast_mutex_lock(&qe->parent->lock);
- if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
- store_next(qe, outgoing);
- }
- ast_mutex_unlock(&qe->parent->lock);
- peer = lpeer ? lpeer->chan : NULL;
- if (!peer) {
- qe->pending = 0;
- if (to) {
- /* Must gotten hung up */
- res = -1;
- } else {
- /* User exited by pressing a digit */
- res = digit;
- }
- if (option_debug && res == -1)
- ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name);
- } else { /* peer is valid */
- /* Ah ha! Someone answered within the desired timeframe. Of course after this
- we will always return with -1 so that it is hung up properly after the
- conversation. */
- if (!strcmp(qe->chan->tech->type, "Zap"))
- ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
- if (!strcmp(peer->tech->type, "Zap"))
- ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
- /* Update parameters for the queue */
- time(&now);
- recalc_holdtime(qe, (now - qe->start));
- ast_mutex_lock(&qe->parent->lock);
- callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
- ast_mutex_unlock(&qe->parent->lock);
- member = lpeer->member;
- /* Increment the refcount for this member, since we're going to be using it for awhile in here. */
- ao2_ref(member, 1);
- hangupcalls(outgoing, peer);
- outgoing = NULL;
- if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
- int res2;
-
- res2 = ast_autoservice_start(qe->chan);
- if (!res2) {
- if (qe->parent->memberdelay) {
- ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
- res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
- }
- if (!res2 && announce) {
- play_file(peer, announce);
- }
- if (!res2 && qe->parent->reportholdtime) {
- if (!play_file(peer, qe->parent->sound_reporthold)) {
- int holdtime;
-
- time(&now);
- holdtime = abs((now - qe->start) / 60);
- if (holdtime < 2) {
- play_file(peer, qe->parent->sound_lessthan);
- ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
- } else
- ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
- play_file(peer, qe->parent->sound_minutes);
- }
- }
- }
- res2 |= ast_autoservice_stop(qe->chan);
- if (peer->_softhangup) {
- /* Agent must have hung up */
- ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
- if (qe->parent->eventwhencalled)
- manager_event(EVENT_FLAG_AGENT, "AgentDump",
- "Queue: %s\r\n"
- "Uniqueid: %s\r\n"
- "Channel: %s\r\n"
- "Member: %s\r\n"
- "MemberName: %s\r\n"
- "%s",
- queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
- qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
- ast_hangup(peer);
- ao2_ref(member, -1);
- goto out;
- } else if (res2) {
- /* Caller must have hung up just before being connected*/
- ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
- record_abandoned(qe);
- ast_hangup(peer);
- ao2_ref(member, -1);
- return -1;
- }
- }
- /* Stop music on hold */
- ast_moh_stop(qe->chan);
- /* If appropriate, log that we have a destination channel */
- if (qe->chan->cdr)
- ast_cdr_setdestchan(qe->chan->cdr, peer->name);
- /* Make sure channels are compatible */
- res = ast_channel_make_compatible(qe->chan, peer);
- if (res < 0) {
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
- ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
- record_abandoned(qe);
- ast_hangup(peer);
- ao2_ref(member, -1);
- return -1;
- }
-
- if (qe->parent->setinterfacevar)
- pbx_builtin_setvar_helper(qe->chan, "MEMBERINTERFACE", member->interface);
-
- /* Begin Monitoring */
- if (qe->parent->monfmt && *qe->parent->monfmt) {
- if (!qe->parent->montype) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Starting Monitor as requested.\n");
- monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
- if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
- which = qe->chan;
- else
- which = peer;
- if (monitorfilename)
- ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1 );
- else if (qe->chan->cdr)
- ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
- else {
- /* Last ditch effort -- no CDR, make up something */
- snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
- ast_monitor_start(which, qe->parent->monfmt, tmpid, 1 );
- }
- if (qe->parent->monjoin)
- ast_monitor_setjoinfiles(which, 1);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Starting MixMonitor as requested.\n");
- monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
- if (!monitorfilename) {
- if (qe->chan->cdr)
- ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
- else
- snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
- } else {
- ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
- for (p = tmpid2; *p ; p++) {
- if (*p == '^' && *(p+1) == '{') {
- *p = '$';
- }
- }
-
- memset(tmpid, 0, sizeof(tmpid));
- pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
- }
-
- monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
- monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
-
- if (monitor_exec) {
- ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
- for (p = meid2; *p ; p++) {
- if (*p == '^' && *(p+1) == '{') {
- *p = '$';
- }
- }
-
- memset(meid, 0, sizeof(meid));
- pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
- }
-
- snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
-
- mixmonapp = pbx_findapp("MixMonitor");
-
- if (strchr(tmpid2, '|')) {
- ast_log(LOG_WARNING, "monitor-format (in queues.conf) and MONITOR_FILENAME cannot contain a '|'! Not recording.\n");
- mixmonapp = NULL;
- }
-
- if (!monitor_options)
- monitor_options = "";
-
- if (strchr(monitor_options, '|')) {
- ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
- mixmonapp = NULL;
- }
-
- if (mixmonapp) {
- if (!ast_strlen_zero(monitor_exec))
- snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
- else
- snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
- /* We purposely lock the CDR so that pbx_exec does not update the application data */
- if (qe->chan->cdr)
- ast_set_flag(qe->chan->cdr, AST_CDR_FLAG_LOCKED);
- ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
- if (qe->chan->cdr)
- ast_clear_flag(qe->chan->cdr, AST_CDR_FLAG_LOCKED);
-
- } else
- ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
-
- }
- }
- /* Drop out of the queue at this point, to prepare for next caller */
- leave_queue(qe);
- if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "app_queue: sendurl=%s.\n", url);
- ast_channel_sendurl(peer, url);
- }
- if (!ast_strlen_zero(agi)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "app_queue: agi=%s.\n", agi);
- app = pbx_findapp("agi");
- if (app) {
- agiexec = ast_strdupa(agi);
- ret = pbx_exec(qe->chan, app, agiexec);
- } else
- ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
- }
- qe->handled++;
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s", (long)time(NULL) - qe->start, peer->uniqueid);
- if (qe->parent->eventwhencalled)
- manager_event(EVENT_FLAG_AGENT, "AgentConnect",
- "Queue: %s\r\n"
- "Uniqueid: %s\r\n"
- "Channel: %s\r\n"
- "Member: %s\r\n"
- "MemberName: %s\r\n"
- "Holdtime: %ld\r\n"
- "BridgedChannel: %s\r\n"
- "%s",
- queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
- (long)time(NULL) - qe->start, peer->uniqueid,
- qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
- ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
- ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
- time(&callstart);
-
- if (member->status == AST_DEVICE_NOT_INUSE)
- ast_log(LOG_WARNING, "The device state of this queue member, %s, is still 'Not in Use' when it probably should not be! Please check UPGRADE.txt for correct configuration settings.\n", member->membername);
-
-
- bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
-
- if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "TRANSFER", "%s|%s|%ld|%ld",
- qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
- (long) (time(NULL) - callstart));
- } else if (qe->chan->_softhangup) {
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
- (long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
- if (qe->parent->eventwhencalled)
- manager_event(EVENT_FLAG_AGENT, "AgentComplete",
- "Queue: %s\r\n"
- "Uniqueid: %s\r\n"
- "Channel: %s\r\n"
- "Member: %s\r\n"
- "MemberName: %s\r\n"
- "HoldTime: %ld\r\n"
- "TalkTime: %ld\r\n"
- "Reason: caller\r\n"
- "%s",
- queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
- (long)(callstart - qe->start), (long)(time(NULL) - callstart),
- qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
- } else {
- ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETEAGENT", "%ld|%ld|%d",
- (long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
- if (qe->parent->eventwhencalled)
- manager_event(EVENT_FLAG_AGENT, "AgentComplete",
- "Queue: %s\r\n"
- "Uniqueid: %s\r\n"
- "Channel: %s\r\n"
- "MemberName: %s\r\n"
- "HoldTime: %ld\r\n"
- "TalkTime: %ld\r\n"
- "Reason: agent\r\n"
- "%s",
- queuename, qe->chan->uniqueid, peer->name, member->membername, (long)(callstart - qe->start),
- (long)(time(NULL) - callstart),
- qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
- }
-
- if (bridge != AST_PBX_NO_HANGUP_PEER)
- ast_hangup(peer);
- update_queue(qe->parent, member, callcompletedinsl);
- res = bridge ? bridge : 1;
- ao2_ref(member, -1);
- }
-out:
- hangupcalls(outgoing, NULL);
-
- return res;
-}
-
-static int wait_a_bit(struct queue_ent *qe)
-{
- /* Don't need to hold the lock while we setup the outgoing calls */
- int retrywait = qe->parent->retry * 1000;
-
- int res = ast_waitfordigit(qe->chan, retrywait);
- if (res > 0 && !valid_exit(qe, res))
- res = 0;
-
- return res;
-}
-
-static struct member *interface_exists(struct call_queue *q, const char *interface)
-{
- struct member *mem;
- struct ao2_iterator mem_iter;
-
- if (!q)
- return NULL;
-
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((mem = ao2_iterator_next(&mem_iter))) {
- if (!strcasecmp(interface, mem->interface))
- return mem;
- ao2_ref(mem, -1);
- }
-
- return NULL;
-}
-
-
-/* Dump all members in a specific queue to the database
- *
- * <pm_family>/<queuename> = <interface>;<penalty>;<paused>[|...]
- *
- */
-static void dump_queue_members(struct call_queue *pm_queue)
-{
- struct member *cur_member;
- char value[PM_MAX_LEN];
- int value_len = 0;
- int res;
- struct ao2_iterator mem_iter;
-
- memset(value, 0, sizeof(value));
-
- if (!pm_queue)
- return;
-
- mem_iter = ao2_iterator_init(pm_queue->members, 0);
- while ((cur_member = ao2_iterator_next(&mem_iter))) {
- if (!cur_member->dynamic) {
- ao2_ref(cur_member, -1);
- continue;
- }
-
- res = snprintf(value + value_len, sizeof(value) - value_len, "%s%s;%d;%d;%s",
- value_len ? "|" : "", cur_member->interface, cur_member->penalty, cur_member->paused, cur_member->membername);
-
- ao2_ref(cur_member, -1);
-
- if (res != strlen(value + value_len)) {
- ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
- break;
- }
- value_len += res;
- }
-
- if (value_len && !cur_member) {
- if (ast_db_put(pm_family, pm_queue->name, value))
- ast_log(LOG_WARNING, "failed to create persistent dynamic entry!\n");
- } else
- /* Delete the entry if the queue is empty or there is an error */
- ast_db_del(pm_family, pm_queue->name);
-}
-
-static int remove_from_queue(const char *queuename, const char *interface)
-{
- struct call_queue *q;
- struct member *mem, tmpmem;
- int res = RES_NOSUCHQUEUE;
-
- ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
- if (strcmp(q->name, queuename)) {
- ast_mutex_unlock(&q->lock);
- continue;
- }
-
- if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
- /* XXX future changes should beware of this assumption!! */
- if (!mem->dynamic) {
- res = RES_NOT_DYNAMIC;
- ao2_ref(mem, -1);
- ast_mutex_unlock(&q->lock);
- break;
- }
- q->membercount--;
- manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "MemberName: %s\r\n",
- q->name, mem->interface, mem->membername);
- ao2_unlink(q->members, mem);
- ao2_ref(mem, -1);
-
- if (queue_persistent_members)
- dump_queue_members(q);
-
- res = RES_OKAY;
- } else {
- res = RES_EXISTS;
- }
- ast_mutex_unlock(&q->lock);
- break;
- }
-
- if (res == RES_OKAY)
- remove_from_interfaces(interface);
-
- AST_LIST_UNLOCK(&queues);
-
- return res;
-}
-
-
-static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump)
-{
- struct call_queue *q;
- struct member *new_member, *old_member;
- int res = RES_NOSUCHQUEUE;
-
- /* \note Ensure the appropriate realtime queue is loaded. Note that this
- * short-circuits if the queue is already in memory. */
- if (!(q = load_realtime_queue(queuename)))
- return res;
-
- AST_LIST_LOCK(&queues);
-
- ast_mutex_lock(&q->lock);
- if ((old_member = interface_exists(q, interface)) == NULL) {
- add_to_interfaces(interface);
- if ((new_member = create_queue_member(interface, membername, penalty, paused))) {
- new_member->dynamic = 1;
- ao2_link(q->members, new_member);
- q->membercount++;
- manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "MemberName: %s\r\n"
- "Membership: %s\r\n"
- "Penalty: %d\r\n"
- "CallsTaken: %d\r\n"
- "LastCall: %d\r\n"
- "Status: %d\r\n"
- "Paused: %d\r\n",
- q->name, new_member->interface, new_member->membername,
- "dynamic",
- new_member->penalty, new_member->calls, (int) new_member->lastcall,
- new_member->status, new_member->paused);
-
- ao2_ref(new_member, -1);
- new_member = NULL;
-
- if (dump)
- dump_queue_members(q);
-
- res = RES_OKAY;
- } else {
- res = RES_OUTOFMEMORY;
- }
- } else {
- ao2_ref(old_member, -1);
- res = RES_EXISTS;
- }
- ast_mutex_unlock(&q->lock);
- AST_LIST_UNLOCK(&queues);
-
- return res;
-}
-
-static int set_member_paused(const char *queuename, const char *interface, int paused)
-{
- int found = 0;
- struct call_queue *q;
- struct member *mem;
-
- /* Special event for when all queues are paused - individual events still generated */
- /* XXX In all other cases, we use the membername, but since this affects all queues, we cannot */
- if (ast_strlen_zero(queuename))
- ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
- if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
- if ((mem = interface_exists(q, interface))) {
- found++;
- if (mem->paused == paused)
- ast_log(LOG_DEBUG, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
- mem->paused = paused;
-
- if (queue_persistent_members)
- dump_queue_members(q);
-
- if (mem->realtime)
- update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0");
-
- ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", "");
-
- manager_event(EVENT_FLAG_AGENT, "QueueMemberPaused",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "MemberName: %s\r\n"
- "Paused: %d\r\n",
- q->name, mem->interface, mem->membername, paused);
- ao2_ref(mem, -1);
- }
- }
- ast_mutex_unlock(&q->lock);
- }
- AST_LIST_UNLOCK(&queues);
-
- return found ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-/* Reload dynamic queue members persisted into the astdb */
-static void reload_queue_members(void)
-{
- char *cur_ptr;
- char *queue_name;
- char *member;
- char *interface;
- char *membername = NULL;
- char *penalty_tok;
- int penalty = 0;
- char *paused_tok;
- int paused = 0;
- struct ast_db_entry *db_tree;
- struct ast_db_entry *entry;
- struct call_queue *cur_queue;
- char queue_data[PM_MAX_LEN];
-
- AST_LIST_LOCK(&queues);
-
- /* Each key in 'pm_family' is the name of a queue */
- db_tree = ast_db_gettree(pm_family, NULL);
- for (entry = db_tree; entry; entry = entry->next) {
-
- queue_name = entry->key + strlen(pm_family) + 2;
-
- AST_LIST_TRAVERSE(&queues, cur_queue, list) {
- ast_mutex_lock(&cur_queue->lock);
- if (!strcmp(queue_name, cur_queue->name))
- break;
- ast_mutex_unlock(&cur_queue->lock);
- }
-
- if (!cur_queue)
- cur_queue = load_realtime_queue(queue_name);
-
- if (!cur_queue) {
- /* If the queue no longer exists, remove it from the
- * database */
- ast_log(LOG_WARNING, "Error loading persistent queue: '%s': it does not exist\n", queue_name);
- ast_db_del(pm_family, queue_name);
- continue;
- } else
- ast_mutex_unlock(&cur_queue->lock);
-
- if (ast_db_get(pm_family, queue_name, queue_data, PM_MAX_LEN))
- continue;
-
- cur_ptr = queue_data;
- while ((member = strsep(&cur_ptr, "|"))) {
- if (ast_strlen_zero(member))
- continue;
-
- interface = strsep(&member, ";");
- penalty_tok = strsep(&member, ";");
- paused_tok = strsep(&member, ";");
- membername = strsep(&member, ";");
-
- if (!penalty_tok) {
- ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name);
- break;
- }
- penalty = strtol(penalty_tok, NULL, 10);
- if (errno == ERANGE) {
- ast_log(LOG_WARNING, "Error converting penalty: %s: Out of range.\n", penalty_tok);
- break;
- }
-
- if (!paused_tok) {
- ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (paused)\n", queue_name);
- break;
- }
- paused = strtol(paused_tok, NULL, 10);
- if ((errno == ERANGE) || paused < 0 || paused > 1) {
- ast_log(LOG_WARNING, "Error converting paused: %s: Expected 0 or 1.\n", paused_tok);
- break;
- }
- if (ast_strlen_zero(membername))
- membername = interface;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Reload Members: Queue: %s Member: %s Name: %s Penalty: %d Paused: %d\n", queue_name, interface, membername, penalty, paused);
-
- if (add_to_queue(queue_name, interface, membername, penalty, paused, 0) == RES_OUTOFMEMORY) {
- ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n");
- break;
- }
- }
- }
-
- AST_LIST_UNLOCK(&queues);
- if (db_tree) {
- ast_log(LOG_NOTICE, "Queue members successfully reloaded from database.\n");
- ast_db_freetree(db_tree);
- }
-}
-
-static int pqm_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *lu;
- char *parse;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(queuename);
- AST_APP_ARG(interface);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "PauseQueueMember requires an argument ([queuename]|interface[|options])\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- lu = ast_module_user_add(chan);
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- if (ast_strlen_zero(args.interface)) {
- ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n");
- ast_module_user_remove(lu);
- return -1;
- }
-
- if (set_member_paused(args.queuename, args.interface, 1)) {
- ast_log(LOG_WARNING, "Attempt to pause interface %s, not found\n", args.interface);
- if (priority_jump || ast_opt_priority_jumping) {
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
- pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
- ast_module_user_remove(lu);
- return 0;
- }
- }
- ast_module_user_remove(lu);
- pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
- return 0;
- }
-
- ast_module_user_remove(lu);
- pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED");
-
- return 0;
-}
-
-static int upqm_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *lu;
- char *parse;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(queuename);
- AST_APP_ARG(interface);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "UnpauseQueueMember requires an argument ([queuename]|interface[|options])\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- lu = ast_module_user_add(chan);
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- if (ast_strlen_zero(args.interface)) {
- ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n");
- ast_module_user_remove(lu);
- return -1;
- }
-
- if (set_member_paused(args.queuename, args.interface, 0)) {
- ast_log(LOG_WARNING, "Attempt to unpause interface %s, not found\n", args.interface);
- if (priority_jump || ast_opt_priority_jumping) {
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
- pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
- ast_module_user_remove(lu);
- return 0;
- }
- }
- ast_module_user_remove(lu);
- pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
- return 0;
- }
-
- ast_module_user_remove(lu);
- pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED");
-
- return 0;
-}
-
-static int rqm_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- struct ast_module_user *lu;
- char *parse, *temppos = NULL;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(queuename);
- AST_APP_ARG(interface);
- AST_APP_ARG(options);
- );
-
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "RemoveQueueMember requires an argument (queuename[|interface[|options]])\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- lu = ast_module_user_add(chan);
-
- if (ast_strlen_zero(args.interface)) {
- args.interface = ast_strdupa(chan->name);
- temppos = strrchr(args.interface, '-');
- if (temppos)
- *temppos = '\0';
- }
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- switch (remove_from_queue(args.queuename, args.interface)) {
- case RES_OKAY:
- ast_queue_log(args.queuename, chan->uniqueid, args.interface, "REMOVEMEMBER", "%s", "");
- ast_log(LOG_NOTICE, "Removed interface '%s' from queue '%s'\n", args.interface, args.queuename);
- pbx_builtin_setvar_helper(chan, "RQMSTATUS", "REMOVED");
- res = 0;
- break;
- case RES_EXISTS:
- ast_log(LOG_DEBUG, "Unable to remove interface '%s' from queue '%s': Not there\n", args.interface, args.queuename);
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOTINQUEUE");
- res = 0;
- break;
- case RES_NOSUCHQUEUE:
- ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': No such queue\n", args.queuename);
- pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOSUCHQUEUE");
- res = 0;
- break;
- case RES_NOT_DYNAMIC:
- ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': '%s' is not a dynamic member\n", args.queuename, args.interface);
- pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOTDYNAMIC");
- res = 0;
- break;
- }
-
- ast_module_user_remove(lu);
-
- return res;
-}
-
-static int aqm_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- struct ast_module_user *lu;
- char *parse, *temppos = NULL;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(queuename);
- AST_APP_ARG(interface);
- AST_APP_ARG(penalty);
- AST_APP_ARG(options);
- AST_APP_ARG(membername);
- );
- int penalty = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[|[interface]|[penalty][|options][|membername]])\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- lu = ast_module_user_add(chan);
-
- if (ast_strlen_zero(args.interface)) {
- args.interface = ast_strdupa(chan->name);
- temppos = strrchr(args.interface, '-');
- if (temppos)
- *temppos = '\0';
- }
-
- if (!ast_strlen_zero(args.penalty)) {
- if ((sscanf(args.penalty, "%d", &penalty) != 1) || penalty < 0) {
- ast_log(LOG_WARNING, "Penalty '%s' is invalid, must be an integer >= 0\n", args.penalty);
- penalty = 0;
- }
- }
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, queue_persistent_members)) {
- case RES_OKAY:
- ast_queue_log(args.queuename, chan->uniqueid, args.interface, "ADDMEMBER", "%s", "");
- ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", args.interface, args.queuename);
- pbx_builtin_setvar_helper(chan, "AQMSTATUS", "ADDED");
- res = 0;
- break;
- case RES_EXISTS:
- ast_log(LOG_WARNING, "Unable to add interface '%s' to queue '%s': Already there\n", args.interface, args.queuename);
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "AQMSTATUS", "MEMBERALREADY");
- res = 0;
- break;
- case RES_NOSUCHQUEUE:
- ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", args.queuename);
- pbx_builtin_setvar_helper(chan, "AQMSTATUS", "NOSUCHQUEUE");
- res = 0;
- break;
- case RES_OUTOFMEMORY:
- ast_log(LOG_ERROR, "Out of memory adding member %s to queue %s\n", args.interface, args.queuename);
- break;
- }
-
- ast_module_user_remove(lu);
-
- return res;
-}
-
-static int ql_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *parse;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(queuename);
- AST_APP_ARG(uniqueid);
- AST_APP_ARG(membername);
- AST_APP_ARG(event);
- AST_APP_ARG(params);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "QueueLog requires arguments (queuename|uniqueid|membername|event[|additionalinfo]\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.queuename) || ast_strlen_zero(args.uniqueid)
- || ast_strlen_zero(args.membername) || ast_strlen_zero(args.event)) {
- ast_log(LOG_WARNING, "QueueLog requires arguments (queuename|uniqueid|membername|event[|additionalinfo])\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_queue_log(args.queuename, args.uniqueid, args.membername, args.event,
- "%s", args.params ? args.params : "");
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-/*!\brief The starting point for all queue calls
- *
- * The process involved here is to
- * 1. Parse the options specified in the call to Queue()
- * 2. Join the queue
- * 3. Wait in a loop until it is our turn to try calling a queue member
- * 4. Attempt to call a queue member
- * 5. If 4. did not result in a bridged call, then check for between
- * call options such as periodic announcements etc.
- * 6. Try 4 again uless some condition (such as an expiration time) causes us to
- * exit the queue.
- */
-static int queue_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- int ringing=0;
- struct ast_module_user *lu;
- const char *user_priority;
- const char *max_penalty_str;
- int prio;
- int max_penalty;
- enum queue_result reason = QUEUE_UNKNOWN;
- /* whether to exit Queue application after the timeout hits */
- int tries = 0;
- int noption = 0;
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(queuename);
- AST_APP_ARG(options);
- AST_APP_ARG(url);
- AST_APP_ARG(announceoverride);
- AST_APP_ARG(queuetimeoutstr);
- AST_APP_ARG(agi);
- );
- /* Our queue entry */
- struct queue_ent qe;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Queue requires an argument: queuename[|options[|URL[|announceoverride[|timeout[|agi]]]]]\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
-
- lu = ast_module_user_add(chan);
-
- /* Setup our queue entry */
- memset(&qe, 0, sizeof(qe));
- qe.start = time(NULL);
-
- /* set the expire time based on the supplied timeout; */
- if (!ast_strlen_zero(args.queuetimeoutstr))
- qe.expire = qe.start + atoi(args.queuetimeoutstr);
- else
- qe.expire = 0;
-
- /* Get the priority from the variable ${QUEUE_PRIO} */
- user_priority = pbx_builtin_getvar_helper(chan, "QUEUE_PRIO");
- if (user_priority) {
- if (sscanf(user_priority, "%d", &prio) == 1) {
- if (option_debug)
- ast_log(LOG_DEBUG, "%s: Got priority %d from ${QUEUE_PRIO}.\n",
- chan->name, prio);
- } else {
- ast_log(LOG_WARNING, "${QUEUE_PRIO}: Invalid value (%s), channel %s.\n",
- user_priority, chan->name);
- prio = 0;
- }
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "NO QUEUE_PRIO variable found. Using default.\n");
- prio = 0;
- }
-
- /* Get the maximum penalty from the variable ${QUEUE_MAX_PENALTY} */
- if ((max_penalty_str = pbx_builtin_getvar_helper(chan, "QUEUE_MAX_PENALTY"))) {
- if (sscanf(max_penalty_str, "%d", &max_penalty) == 1) {
- if (option_debug)
- ast_log(LOG_DEBUG, "%s: Got max penalty %d from ${QUEUE_MAX_PENALTY}.\n",
- chan->name, max_penalty);
- } else {
- ast_log(LOG_WARNING, "${QUEUE_MAX_PENALTY}: Invalid value (%s), channel %s.\n",
- max_penalty_str, chan->name);
- max_penalty = 0;
- }
- } else {
- max_penalty = 0;
- }
-
- if (args.options && (strchr(args.options, 'r')))
- ringing = 1;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "queue: %s, options: %s, url: %s, announce: %s, expires: %ld, priority: %d\n",
- args.queuename, args.options, args.url, args.announceoverride, (long)qe.expire, prio);
-
- qe.chan = chan;
- qe.prio = prio;
- qe.max_penalty = max_penalty;
- qe.last_pos_said = 0;
- qe.last_pos = 0;
- qe.last_periodic_announce_time = time(NULL);
- qe.last_periodic_announce_sound = 0;
- qe.valid_digits = 0;
- if (!join_queue(args.queuename, &qe, &reason)) {
- int makeannouncement = 0;
-
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", S_OR(args.url, ""),
- S_OR(chan->cid.cid_num, ""));
-check_turns:
- if (ringing) {
- ast_indicate(chan, AST_CONTROL_RINGING);
- } else {
- ast_moh_start(chan, qe.moh, NULL);
- }
-
- /* This is the wait loop for callers 2 through maxlen */
- res = wait_our_turn(&qe, ringing, &reason);
- if (res)
- goto stop;
-
- for (;;) {
- /* This is the wait loop for the head caller*/
- /* To exit, they may get their call answered; */
- /* they may dial a digit from the queue context; */
- /* or, they may timeout. */
-
- enum queue_member_status stat;
-
- /* Leave if we have exceeded our queuetimeout */
- if (qe.expire && (time(NULL) > qe.expire)) {
- record_abandoned(&qe);
- reason = QUEUE_TIMEOUT;
- res = 0;
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
- break;
- }
-
- if (makeannouncement) {
- /* Make a position announcement, if enabled */
- if (qe.parent->announcefrequency && !ringing)
- if ((res = say_position(&qe)))
- goto stop;
-
- }
- makeannouncement = 1;
-
- /* Make a periodic announcement, if enabled */
- if (qe.parent->periodicannouncefrequency && !ringing)
- if ((res = say_periodic_announcement(&qe)))
- goto stop;
-
- /* Try calling all queue members for 'timeout' seconds */
- res = try_calling(&qe, args.options, args.announceoverride, args.url, &tries, &noption, args.agi);
- if (res)
- goto stop;
-
- stat = get_member_status(qe.parent, qe.max_penalty);
-
- /* exit after 'timeout' cycle if 'n' option enabled */
- if (noption && tries >= qe.parent->membercount) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Exiting on time-out cycle\n");
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
- record_abandoned(&qe);
- reason = QUEUE_TIMEOUT;
- res = 0;
- break;
- }
-
- /* leave the queue if no agents, if enabled */
- if (qe.parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
- record_abandoned(&qe);
- reason = QUEUE_LEAVEEMPTY;
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe.pos, qe.opos, (long)(time(NULL) - qe.start));
- res = 0;
- break;
- }
-
- /* leave the queue if no reachable agents, if enabled */
- if ((qe.parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
- record_abandoned(&qe);
- reason = QUEUE_LEAVEUNAVAIL;
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe.pos, qe.opos, (long)(time(NULL) - qe.start));
- res = 0;
- break;
- }
-
- /* Leave if we have exceeded our queuetimeout */
- if (qe.expire && (time(NULL) > qe.expire)) {
- record_abandoned(&qe);
- reason = QUEUE_TIMEOUT;
- res = 0;
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
- break;
- }
-
- /* If using dynamic realtime members, we should regenerate the member list for this queue */
- update_realtime_members(qe.parent);
-
- /* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
- res = wait_a_bit(&qe);
- if (res)
- goto stop;
-
-
- /* Since this is a priority queue and
- * it is not sure that we are still at the head
- * of the queue, go and check for our turn again.
- */
- if (!is_our_turn(&qe)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Darn priorities, going back in queue (%s)!\n",
- qe.chan->name);
- goto check_turns;
- }
- }
-
-stop:
- if (res) {
- if (res < 0) {
- if (!qe.handled) {
- record_abandoned(&qe);
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON",
- "%d|%d|%ld", qe.pos, qe.opos,
- (long) time(NULL) - qe.start);
- }
- res = -1;
- } else if (qe.valid_digits) {
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY",
- "%s|%d", qe.digits, qe.pos);
- }
- }
-
- /* Don't allow return code > 0 */
- if (res >= 0 && res != AST_PBX_KEEPALIVE) {
- res = 0;
- if (ringing) {
- ast_indicate(chan, -1);
- } else {
- ast_moh_stop(chan);
- }
- ast_stopstream(chan);
- }
- leave_queue(&qe);
- if (reason != QUEUE_UNKNOWN)
- set_queue_result(chan, reason);
- } else {
- ast_log(LOG_WARNING, "Unable to join queue '%s'\n", args.queuename);
- set_queue_result(chan, reason);
- res = 0;
- }
- ast_module_user_remove(lu);
-
- return res;
-}
-
-static int queue_function_qac(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- int count = 0;
- struct call_queue *q;
- struct ast_module_user *lu;
- struct member *m;
- struct ao2_iterator mem_iter;
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
- return -1;
- }
-
- lu = ast_module_user_add(chan);
-
- if ((q = load_realtime_queue(data))) {
- ast_mutex_lock(&q->lock);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- /* Count the agents who are logged in and presently answering calls */
- if ((m->status != AST_DEVICE_UNAVAILABLE) && (m->status != AST_DEVICE_INVALID)) {
- count++;
- }
- ao2_ref(m, -1);
- }
- ast_mutex_unlock(&q->lock);
- } else
- ast_log(LOG_WARNING, "queue %s was not found\n", data);
-
- snprintf(buf, len, "%d", count);
- ast_module_user_remove(lu);
-
- return 0;
-}
-
-static int queue_function_queuewaitingcount(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- int count = 0;
- struct call_queue *q;
- struct ast_module_user *lu;
- struct ast_variable *var = NULL;
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
- return -1;
- }
-
- lu = ast_module_user_add(chan);
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!strcasecmp(q->name, data)) {
- ast_mutex_lock(&q->lock);
- break;
- }
- }
- AST_LIST_UNLOCK(&queues);
-
- if (q) {
- count = q->count;
- ast_mutex_unlock(&q->lock);
- } else if ((var = ast_load_realtime("queues", "name", data, NULL))) {
- /* if the queue is realtime but was not found in memory, this
- * means that the queue had been deleted from memory since it was
- * "dead." This means it has a 0 waiting count
- */
- count = 0;
- ast_variables_destroy(var);
- } else
- ast_log(LOG_WARNING, "queue %s was not found\n", data);
-
- snprintf(buf, len, "%d", count);
- ast_module_user_remove(lu);
- return 0;
-}
-
-static int queue_function_queuememberlist(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct ast_module_user *u;
- struct call_queue *q;
- struct member *m;
-
- /* Ensure an otherwise empty list doesn't return garbage */
- buf[0] = '\0';
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "QUEUE_MEMBER_LIST requires an argument: queuename\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!strcasecmp(q->name, data)) {
- ast_mutex_lock(&q->lock);
- break;
- }
- }
- AST_LIST_UNLOCK(&queues);
-
- if (q) {
- int buflen = 0, count = 0;
- struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
-
- while ((m = ao2_iterator_next(&mem_iter))) {
- /* strcat() is always faster than printf() */
- if (count++) {
- strncat(buf + buflen, ",", len - buflen - 1);
- buflen++;
- }
- strncat(buf + buflen, m->membername, len - buflen - 1);
- buflen += strlen(m->membername);
- /* Safeguard against overflow (negative length) */
- if (buflen >= len - 2) {
- ao2_ref(m, -1);
- ast_log(LOG_WARNING, "Truncating list\n");
- break;
- }
- ao2_ref(m, -1);
- }
- ast_mutex_unlock(&q->lock);
- } else
- ast_log(LOG_WARNING, "queue %s was not found\n", data);
-
- /* We should already be terminated, but let's make sure. */
- buf[len - 1] = '\0';
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static struct ast_custom_function queueagentcount_function = {
- .name = "QUEUEAGENTCOUNT",
- .synopsis = "Count number of agents answering a queue",
- .syntax = "QUEUEAGENTCOUNT(<queuename>)",
- .desc =
-"Returns the number of members currently associated with the specified queue.\n"
-"This function is deprecated. You should use QUEUE_MEMBER_COUNT() instead.\n",
- .read = queue_function_qac,
-};
-
-static struct ast_custom_function queuemembercount_function = {
- .name = "QUEUE_MEMBER_COUNT",
- .synopsis = "Count number of members answering a queue",
- .syntax = "QUEUE_MEMBER_COUNT(<queuename>)",
- .desc =
-"Returns the number of members currently associated with the specified queue.\n",
- .read = queue_function_qac,
-};
-
-static struct ast_custom_function queuewaitingcount_function = {
- .name = "QUEUE_WAITING_COUNT",
- .synopsis = "Count number of calls currently waiting in a queue",
- .syntax = "QUEUE_WAITING_COUNT(<queuename>)",
- .desc =
-"Returns the number of callers currently waiting in the specified queue.\n",
- .read = queue_function_queuewaitingcount,
-};
-
-static struct ast_custom_function queuememberlist_function = {
- .name = "QUEUE_MEMBER_LIST",
- .synopsis = "Returns a list of interfaces on a queue",
- .syntax = "QUEUE_MEMBER_LIST(<queuename>)",
- .desc =
-"Returns a comma-separated list of members associated with the specified queue.\n",
- .read = queue_function_queuememberlist,
-};
-
-static int reload_queues(void)
-{
- struct call_queue *q;
- struct ast_config *cfg;
- char *cat, *tmp;
- struct ast_variable *var;
- struct member *cur, *newm;
- struct ao2_iterator mem_iter;
- int new;
- const char *general_val = NULL;
- char parse[80];
- char *interface;
- char *membername = NULL;
- int penalty;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(interface);
- AST_APP_ARG(penalty);
- AST_APP_ARG(membername);
- );
-
- if (!(cfg = ast_config_load("queues.conf"))) {
- ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
- return 0;
- }
- AST_LIST_LOCK(&queues);
- use_weight=0;
- /* Mark all non-realtime queues as dead for the moment */
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!q->realtime) {
- q->dead = 1;
- q->found = 0;
- }
- }
-
- /* Chug through config file */
- cat = NULL;
- while ((cat = ast_category_browse(cfg, cat)) ) {
- if (!strcasecmp(cat, "general")) {
- /* Initialize global settings */
- queue_persistent_members = 0;
- if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers")))
- queue_persistent_members = ast_true(general_val);
- autofill_default = 0;
- if ((general_val = ast_variable_retrieve(cfg, "general", "autofill")))
- autofill_default = ast_true(general_val);
- montype_default = 0;
- if ((general_val = ast_variable_retrieve(cfg, "general", "monitor-type")))
- if (!strcasecmp(general_val, "mixmonitor"))
- montype_default = 1;
- } else { /* Define queue */
- /* Look for an existing one */
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!strcmp(q->name, cat))
- break;
- }
- if (!q) {
- /* Make one then */
- if (!(q = alloc_queue(cat))) {
- /* TODO: Handle memory allocation failure */
- }
- new = 1;
- } else
- new = 0;
- if (q) {
- if (!new)
- ast_mutex_lock(&q->lock);
- /* Check if a queue with this name already exists */
- if (q->found) {
- ast_log(LOG_WARNING, "Queue '%s' already defined! Skipping!\n", cat);
- if (!new)
- ast_mutex_unlock(&q->lock);
- continue;
- }
- /* Re-initialize the queue, and clear statistics */
- init_queue(q);
- clear_queue(q);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((cur = ao2_iterator_next(&mem_iter))) {
- if (!cur->dynamic) {
- cur->delme = 1;
- }
- ao2_ref(cur, -1);
- }
- for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
- if (!strcasecmp(var->name, "member")) {
- struct member tmpmem;
- membername = NULL;
-
- /* Add a new member */
- ast_copy_string(parse, var->value, sizeof(parse));
-
- AST_NONSTANDARD_APP_ARGS(args, parse, ',');
-
- interface = args.interface;
- if (!ast_strlen_zero(args.penalty)) {
- tmp = args.penalty;
- while (*tmp && *tmp < 33) tmp++;
- penalty = atoi(tmp);
- if (penalty < 0) {
- penalty = 0;
- }
- } else
- penalty = 0;
-
- if (!ast_strlen_zero(args.membername)) {
- membername = args.membername;
- while (*membername && *membername < 33) membername++;
- }
-
- /* Find the old position in the list */
- ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
- cur = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK);
-
- newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0);
- ao2_link(q->members, newm);
- ao2_ref(newm, -1);
- newm = NULL;
-
- if (cur)
- ao2_ref(cur, -1);
- else {
- /* Add them to the master int list if necessary */
- add_to_interfaces(interface);
- q->membercount++;
- }
- } else {
- queue_set_param(q, var->name, var->value, var->lineno, 1);
- }
- }
-
- /* Free remaining members marked as delme */
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((cur = ao2_iterator_next(&mem_iter))) {
- if (! cur->delme) {
- ao2_ref(cur, -1);
- continue;
- }
-
- q->membercount--;
- ao2_unlink(q->members, cur);
- remove_from_interfaces(cur->interface);
- ao2_ref(cur, -1);
- }
-
- if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN)
- rr_dep_warning();
-
- if (new) {
- AST_LIST_INSERT_HEAD(&queues, q, list);
- } else
- ast_mutex_unlock(&q->lock);
- }
- }
- }
- ast_config_destroy(cfg);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&queues, q, list) {
- if (q->dead) {
- AST_LIST_REMOVE_CURRENT(&queues, list);
- if (!q->count)
- destroy_queue(q);
- else
- ast_log(LOG_DEBUG, "XXX Leaking a little memory :( XXX\n");
- } else {
- ast_mutex_lock(&q->lock);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((cur = ao2_iterator_next(&mem_iter))) {
- if (cur->dynamic)
- q->membercount++;
- cur->status = ast_device_state(cur->interface);
- ao2_ref(cur, -1);
- }
- ast_mutex_unlock(&q->lock);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&queues);
- return 1;
-}
-
-static int __queues_show(struct mansession *s, int manager, int fd, int argc, char **argv)
-{
- struct call_queue *q;
- struct queue_ent *qe;
- struct member *mem;
- int pos, queue_show;
- time_t now;
- char max_buf[80];
- char *max;
- size_t max_left;
- float sl = 0;
- char *term = manager ? "\r\n" : "\n";
- struct ao2_iterator mem_iter;
-
- time(&now);
- if (argc == 2)
- queue_show = 0;
- else if (argc == 3)
- queue_show = 1;
- else
- return RESULT_SHOWUSAGE;
-
- /* We only want to load realtime queues when a specific queue is asked for. */
- if (queue_show)
- load_realtime_queue(argv[2]);
-
- AST_LIST_LOCK(&queues);
- if (AST_LIST_EMPTY(&queues)) {
- AST_LIST_UNLOCK(&queues);
- if (queue_show) {
- if (s)
- astman_append(s, "No such queue: %s.%s",argv[2], term);
- else
- ast_cli(fd, "No such queue: %s.%s",argv[2], term);
- } else {
- if (s)
- astman_append(s, "No queues.%s", term);
- else
- ast_cli(fd, "No queues.%s", term);
- }
- return RESULT_SUCCESS;
- }
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
- if (queue_show) {
- if (strcasecmp(q->name, argv[2]) != 0) {
- ast_mutex_unlock(&q->lock);
- if (!AST_LIST_NEXT(q, list)) {
- ast_cli(fd, "No such queue: %s.%s",argv[2], term);
- break;
- }
- continue;
- }
- }
- max_buf[0] = '\0';
- max = max_buf;
- max_left = sizeof(max_buf);
- if (q->maxlen)
- ast_build_string(&max, &max_left, "%d", q->maxlen);
- else
- ast_build_string(&max, &max_left, "unlimited");
- sl = 0;
- if (q->callscompleted > 0)
- sl = 100 * ((float) q->callscompletedinsl / (float) q->callscompleted);
- if (s)
- astman_append(s, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s",
- q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight,
- q->callscompleted, q->callsabandoned,sl,q->servicelevel, term);
- else
- ast_cli(fd, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s",
- q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight, q->callscompleted, q->callsabandoned,sl,q->servicelevel, term);
- if (ao2_container_count(q->members)) {
- if (s)
- astman_append(s, " Members: %s", term);
- else
- ast_cli(fd, " Members: %s", term);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((mem = ao2_iterator_next(&mem_iter))) {
- max_buf[0] = '\0';
- max = max_buf;
- max_left = sizeof(max_buf);
- if (mem->penalty)
- ast_build_string(&max, &max_left, " with penalty %d", mem->penalty);
- if (mem->dynamic)
- ast_build_string(&max, &max_left, " (dynamic)");
- if (mem->realtime)
- ast_build_string(&max, &max_left, " (realtime)");
- if (mem->paused)
- ast_build_string(&max, &max_left, " (paused)");
- ast_build_string(&max, &max_left, " (%s)", devstate2str(mem->status));
- if (mem->calls) {
- ast_build_string(&max, &max_left, " has taken %d calls (last was %ld secs ago)",
- mem->calls, (long) (time(NULL) - mem->lastcall));
- } else
- ast_build_string(&max, &max_left, " has taken no calls yet");
- if (s)
- astman_append(s, " %s%s%s", mem->membername, max_buf, term);
- else
- ast_cli(fd, " %s%s%s", mem->membername, max_buf, term);
- ao2_ref(mem, -1);
- }
- } else if (s)
- astman_append(s, " No Members%s", term);
- else
- ast_cli(fd, " No Members%s", term);
- if (q->head) {
- pos = 1;
- if (s)
- astman_append(s, " Callers: %s", term);
- else
- ast_cli(fd, " Callers: %s", term);
- for (qe = q->head; qe; qe = qe->next) {
- if (s)
- astman_append(s, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s",
- pos++, qe->chan->name, (long) (now - qe->start) / 60,
- (long) (now - qe->start) % 60, qe->prio, term);
- else
- ast_cli(fd, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s", pos++,
- qe->chan->name, (long) (now - qe->start) / 60,
- (long) (now - qe->start) % 60, qe->prio, term);
- }
- } else if (s)
- astman_append(s, " No Callers%s", term);
- else
- ast_cli(fd, " No Callers%s", term);
- if (s)
- astman_append(s, "%s", term);
- else
- ast_cli(fd, "%s", term);
- ast_mutex_unlock(&q->lock);
- if (queue_show)
- break;
- }
- AST_LIST_UNLOCK(&queues);
- return RESULT_SUCCESS;
-}
-
-static int queue_show(int fd, int argc, char **argv)
-{
- return __queues_show(NULL, 0, fd, argc, argv);
-}
-
-static char *complete_queue(const char *line, const char *word, int pos, int state)
-{
- struct call_queue *q;
- char *ret = NULL;
- int which = 0;
- int wordlen = strlen(word);
-
- AST_LIST_LOCK(&queues);
- AST_LIST_TRAVERSE(&queues, q, list) {
- if (!strncasecmp(word, q->name, wordlen) && ++which > state) {
- ret = ast_strdup(q->name);
- break;
- }
- }
- AST_LIST_UNLOCK(&queues);
-
- return ret;
-}
-
-static char *complete_queue_show(const char *line, const char *word, int pos, int state)
-{
- if (pos == 2)
- return complete_queue(line, word, pos, state);
- return NULL;
-}
-
-/*!\brief callback to display queues status in manager
- \addtogroup Group_AMI
- */
-static int manager_queues_show(struct mansession *s, const struct message *m)
-{
- char *a[] = { "queue", "show" };
-
- __queues_show(s, 1, -1, 2, a);
- astman_append(s, "\r\n\r\n"); /* Properly terminate Manager output */
-
- return RESULT_SUCCESS;
-}
-
-/* Dump queue status */
-static int manager_queues_status(struct mansession *s, const struct message *m)
-{
- time_t now;
- int pos;
- const char *id = astman_get_header(m,"ActionID");
- const char *queuefilter = astman_get_header(m,"Queue");
- const char *memberfilter = astman_get_header(m,"Member");
- char idText[256] = "";
- struct call_queue *q;
- struct queue_ent *qe;
- float sl = 0;
- struct member *mem;
- struct ao2_iterator mem_iter;
-
- astman_send_ack(s, m, "Queue status will follow");
- time(&now);
- AST_LIST_LOCK(&queues);
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
-
- /* List queue properties */
- if (ast_strlen_zero(queuefilter) || !strcmp(q->name, queuefilter)) {
- sl = ((q->callscompleted > 0) ? 100 * ((float)q->callscompletedinsl / (float)q->callscompleted) : 0);
- astman_append(s, "Event: QueueParams\r\n"
- "Queue: %s\r\n"
- "Max: %d\r\n"
- "Calls: %d\r\n"
- "Holdtime: %d\r\n"
- "Completed: %d\r\n"
- "Abandoned: %d\r\n"
- "ServiceLevel: %d\r\n"
- "ServicelevelPerf: %2.1f\r\n"
- "Weight: %d\r\n"
- "%s"
- "\r\n",
- q->name, q->maxlen, q->count, q->holdtime, q->callscompleted,
- q->callsabandoned, q->servicelevel, sl, q->weight, idText);
- /* List Queue Members */
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((mem = ao2_iterator_next(&mem_iter))) {
- if (ast_strlen_zero(memberfilter) || !strcmp(mem->interface, memberfilter)) {
- astman_append(s, "Event: QueueMember\r\n"
- "Queue: %s\r\n"
- "Name: %s\r\n"
- "Location: %s\r\n"
- "Membership: %s\r\n"
- "Penalty: %d\r\n"
- "CallsTaken: %d\r\n"
- "LastCall: %d\r\n"
- "Status: %d\r\n"
- "Paused: %d\r\n"
- "%s"
- "\r\n",
- q->name, mem->membername, mem->interface, mem->dynamic ? "dynamic" : "static",
- mem->penalty, mem->calls, (int)mem->lastcall, mem->status, mem->paused, idText);
- }
- ao2_ref(mem, -1);
- }
- /* List Queue Entries */
- pos = 1;
- for (qe = q->head; qe; qe = qe->next) {
- astman_append(s, "Event: QueueEntry\r\n"
- "Queue: %s\r\n"
- "Position: %d\r\n"
- "Channel: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n"
- "Wait: %ld\r\n"
- "%s"
- "\r\n",
- q->name, pos++, qe->chan->name,
- S_OR(qe->chan->cid.cid_num, "unknown"),
- S_OR(qe->chan->cid.cid_name, "unknown"),
- (long) (now - qe->start), idText);
- }
- }
- ast_mutex_unlock(&q->lock);
- }
-
- astman_append(s,
- "Event: QueueStatusComplete\r\n"
- "%s"
- "\r\n",idText);
-
- AST_LIST_UNLOCK(&queues);
-
-
- return RESULT_SUCCESS;
-}
-
-static int manager_add_queue_member(struct mansession *s, const struct message *m)
-{
- const char *queuename, *interface, *penalty_s, *paused_s, *membername;
- int paused, penalty = 0;
-
- queuename = astman_get_header(m, "Queue");
- interface = astman_get_header(m, "Interface");
- penalty_s = astman_get_header(m, "Penalty");
- paused_s = astman_get_header(m, "Paused");
- membername = astman_get_header(m, "MemberName");
-
- if (ast_strlen_zero(queuename)) {
- astman_send_error(s, m, "'Queue' not specified.");
- return 0;
- }
-
- if (ast_strlen_zero(interface)) {
- astman_send_error(s, m, "'Interface' not specified.");
- return 0;
- }
-
- if (ast_strlen_zero(penalty_s))
- penalty = 0;
- else if (sscanf(penalty_s, "%d", &penalty) != 1 || penalty < 0)
- penalty = 0;
-
- if (ast_strlen_zero(paused_s))
- paused = 0;
- else
- paused = abs(ast_true(paused_s));
-
- switch (add_to_queue(queuename, interface, membername, penalty, paused, queue_persistent_members)) {
- case RES_OKAY:
- ast_queue_log(queuename, "MANAGER", interface, "ADDMEMBER", "%s", "");
- astman_send_ack(s, m, "Added interface to queue");
- break;
- case RES_EXISTS:
- astman_send_error(s, m, "Unable to add interface: Already there");
- break;
- case RES_NOSUCHQUEUE:
- astman_send_error(s, m, "Unable to add interface to queue: No such queue");
- break;
- case RES_OUTOFMEMORY:
- astman_send_error(s, m, "Out of memory");
- break;
- }
-
- return 0;
-}
-
-static int manager_remove_queue_member(struct mansession *s, const struct message *m)
-{
- const char *queuename, *interface;
-
- queuename = astman_get_header(m, "Queue");
- interface = astman_get_header(m, "Interface");
-
- if (ast_strlen_zero(queuename) || ast_strlen_zero(interface)) {
- astman_send_error(s, m, "Need 'Queue' and 'Interface' parameters.");
- return 0;
- }
-
- switch (remove_from_queue(queuename, interface)) {
- case RES_OKAY:
- ast_queue_log(queuename, "MANAGER", interface, "REMOVEMEMBER", "%s", "");
- astman_send_ack(s, m, "Removed interface from queue");
- break;
- case RES_EXISTS:
- astman_send_error(s, m, "Unable to remove interface: Not there");
- break;
- case RES_NOSUCHQUEUE:
- astman_send_error(s, m, "Unable to remove interface from queue: No such queue");
- break;
- case RES_OUTOFMEMORY:
- astman_send_error(s, m, "Out of memory");
- break;
- case RES_NOT_DYNAMIC:
- astman_send_error(s, m, "Member not dynamic");
- break;
- }
-
- return 0;
-}
-
-static int manager_pause_queue_member(struct mansession *s, const struct message *m)
-{
- const char *queuename, *interface, *paused_s;
- int paused;
-
- interface = astman_get_header(m, "Interface");
- paused_s = astman_get_header(m, "Paused");
- queuename = astman_get_header(m, "Queue"); /* Optional - if not supplied, pause the given Interface in all queues */
-
- if (ast_strlen_zero(interface) || ast_strlen_zero(paused_s)) {
- astman_send_error(s, m, "Need 'Interface' and 'Paused' parameters.");
- return 0;
- }
-
- paused = abs(ast_true(paused_s));
-
- if (set_member_paused(queuename, interface, paused))
- astman_send_error(s, m, "Interface not found");
- else
- astman_send_ack(s, m, paused ? "Interface paused successfully" : "Interface unpaused successfully");
- return 0;
-}
-
-static int handle_queue_add_member(int fd, int argc, char *argv[])
-{
- char *queuename, *interface, *membername = NULL;
- int penalty;
-
- if ((argc != 6) && (argc != 8) && (argc != 10)) {
- return RESULT_SHOWUSAGE;
- } else if (strcmp(argv[4], "to")) {
- return RESULT_SHOWUSAGE;
- } else if ((argc == 8) && strcmp(argv[6], "penalty")) {
- return RESULT_SHOWUSAGE;
- } else if ((argc == 10) && strcmp(argv[8], "as")) {
- return RESULT_SHOWUSAGE;
- }
-
- queuename = argv[5];
- interface = argv[3];
- if (argc >= 8) {
- if (sscanf(argv[7], "%d", &penalty) == 1) {
- if (penalty < 0) {
- ast_cli(fd, "Penalty must be >= 0\n");
- penalty = 0;
- }
- } else {
- ast_cli(fd, "Penalty must be an integer >= 0\n");
- penalty = 0;
- }
- } else {
- penalty = 0;
- }
-
- if (argc >= 10) {
- membername = argv[9];
- }
-
- switch (add_to_queue(queuename, interface, membername, penalty, 0, queue_persistent_members)) {
- case RES_OKAY:
- ast_queue_log(queuename, "CLI", interface, "ADDMEMBER", "%s", "");
- ast_cli(fd, "Added interface '%s' to queue '%s'\n", interface, queuename);
- return RESULT_SUCCESS;
- case RES_EXISTS:
- ast_cli(fd, "Unable to add interface '%s' to queue '%s': Already there\n", interface, queuename);
- return RESULT_FAILURE;
- case RES_NOSUCHQUEUE:
- ast_cli(fd, "Unable to add interface to queue '%s': No such queue\n", queuename);
- return RESULT_FAILURE;
- case RES_OUTOFMEMORY:
- ast_cli(fd, "Out of memory\n");
- return RESULT_FAILURE;
- default:
- return RESULT_FAILURE;
- }
-}
-
-static char *complete_queue_add_member(const char *line, const char *word, int pos, int state)
-{
- /* 0 - queue; 1 - add; 2 - member; 3 - <interface>; 4 - to; 5 - <queue>; 6 - penalty; 7 - <penalty>; 8 - as; 9 - <membername> */
- switch (pos) {
- case 3: /* Don't attempt to complete name of interface (infinite possibilities) */
- return NULL;
- case 4: /* only one possible match, "to" */
- return state == 0 ? ast_strdup("to") : NULL;
- case 5: /* <queue> */
- return complete_queue(line, word, pos, state);
- case 6: /* only one possible match, "penalty" */
- return state == 0 ? ast_strdup("penalty") : NULL;
- case 7:
- if (state < 100) { /* 0-99 */
- char *num;
- if ((num = ast_malloc(3))) {
- sprintf(num, "%d", state);
- }
- return num;
- } else {
- return NULL;
- }
- case 8: /* only one possible match, "as" */
- return state == 0 ? ast_strdup("as") : NULL;
- case 9: /* Don't attempt to complete name of member (infinite possibilities) */
- return NULL;
- default:
- return NULL;
- }
-}
-
-static int handle_queue_remove_member(int fd, int argc, char *argv[])
-{
- char *queuename, *interface;
-
- if (argc != 6) {
- return RESULT_SHOWUSAGE;
- } else if (strcmp(argv[4], "from")) {
- return RESULT_SHOWUSAGE;
- }
-
- queuename = argv[5];
- interface = argv[3];
-
- switch (remove_from_queue(queuename, interface)) {
- case RES_OKAY:
- ast_queue_log(queuename, "CLI", interface, "REMOVEMEMBER", "%s", "");
- ast_cli(fd, "Removed interface '%s' from queue '%s'\n", interface, queuename);
- return RESULT_SUCCESS;
- case RES_EXISTS:
- ast_cli(fd, "Unable to remove interface '%s' from queue '%s': Not there\n", interface, queuename);
- return RESULT_FAILURE;
- case RES_NOSUCHQUEUE:
- ast_cli(fd, "Unable to remove interface from queue '%s': No such queue\n", queuename);
- return RESULT_FAILURE;
- case RES_OUTOFMEMORY:
- ast_cli(fd, "Out of memory\n");
- return RESULT_FAILURE;
- case RES_NOT_DYNAMIC:
- ast_cli(fd, "Member not dynamic\n");
- return RESULT_FAILURE;
- default:
- return RESULT_FAILURE;
- }
-}
-
-static char *complete_queue_remove_member(const char *line, const char *word, int pos, int state)
-{
- int which = 0;
- struct call_queue *q;
- struct member *m;
- struct ao2_iterator mem_iter;
-
- /* 0 - queue; 1 - remove; 2 - member; 3 - <member>; 4 - from; 5 - <queue> */
- if (pos > 5 || pos < 3)
- return NULL;
- if (pos == 4) /* only one possible match, 'from' */
- return state == 0 ? ast_strdup("from") : NULL;
-
- if (pos == 5) /* No need to duplicate code */
- return complete_queue(line, word, pos, state);
-
- /* here is the case for 3, <member> */
- if (!AST_LIST_EMPTY(&queues)) { /* XXX unnecessary ? the traverse does that for us */
- AST_LIST_TRAVERSE(&queues, q, list) {
- ast_mutex_lock(&q->lock);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- if (++which > state) {
- char *tmp;
- ast_mutex_unlock(&q->lock);
- tmp = m->membername;
- ao2_ref(m, -1);
- return ast_strdup(tmp);
- }
- ao2_ref(m, -1);
- }
- ast_mutex_unlock(&q->lock);
- }
- }
-
- return NULL;
-}
-
-static char queue_show_usage[] =
-"Usage: queue show\n"
-" Provides summary information on a specified queue.\n";
-
-static char qam_cmd_usage[] =
-"Usage: queue add member <channel> to <queue> [penalty <penalty>]\n";
-
-static char qrm_cmd_usage[] =
-"Usage: queue remove member <channel> from <queue>\n";
-
-static struct ast_cli_entry cli_show_queue_deprecated = {
- { "show", "queue", NULL },
- queue_show, NULL,
- NULL, complete_queue_show };
-
-static struct ast_cli_entry cli_add_queue_member_deprecated = {
- { "add", "queue", "member", NULL },
- handle_queue_add_member, NULL,
- NULL, complete_queue_add_member };
-
-static struct ast_cli_entry cli_remove_queue_member_deprecated = {
- { "remove", "queue", "member", NULL },
- handle_queue_remove_member, NULL,
- NULL, complete_queue_remove_member };
-
-static struct ast_cli_entry cli_queue[] = {
- /* Deprecated */
- { { "show", "queues", NULL },
- queue_show, NULL,
- NULL, NULL },
-
- { { "queue", "show", NULL },
- queue_show, "Show status of a specified queue",
- queue_show_usage, complete_queue_show, &cli_show_queue_deprecated },
-
- { { "queue", "add", "member", NULL },
- handle_queue_add_member, "Add a channel to a specified queue",
- qam_cmd_usage, complete_queue_add_member, &cli_add_queue_member_deprecated },
-
- { { "queue", "remove", "member", NULL },
- handle_queue_remove_member, "Removes a channel from a specified queue",
- qrm_cmd_usage, complete_queue_remove_member, &cli_remove_queue_member_deprecated },
-};
-
-static int unload_module(void)
-{
- int res;
-
- if (device_state.thread != AST_PTHREADT_NULL) {
- device_state.stop = 1;
- ast_mutex_lock(&device_state.lock);
- ast_cond_signal(&device_state.cond);
- ast_mutex_unlock(&device_state.lock);
- pthread_join(device_state.thread, NULL);
- }
-
- ast_cli_unregister_multiple(cli_queue, sizeof(cli_queue) / sizeof(struct ast_cli_entry));
- res = ast_manager_unregister("QueueStatus");
- res |= ast_manager_unregister("Queues");
- res |= ast_manager_unregister("QueueStatus");
- res |= ast_manager_unregister("QueueAdd");
- res |= ast_manager_unregister("QueueRemove");
- res |= ast_manager_unregister("QueuePause");
- res |= ast_unregister_application(app_aqm);
- res |= ast_unregister_application(app_rqm);
- res |= ast_unregister_application(app_pqm);
- res |= ast_unregister_application(app_upqm);
- res |= ast_unregister_application(app_ql);
- res |= ast_unregister_application(app);
- res |= ast_custom_function_unregister(&queueagentcount_function);
- res |= ast_custom_function_unregister(&queuemembercount_function);
- res |= ast_custom_function_unregister(&queuememberlist_function);
- res |= ast_custom_function_unregister(&queuewaitingcount_function);
- ast_devstate_del(statechange_queue, NULL);
-
- ast_module_user_hangup_all();
-
- clear_and_free_interfaces();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- if (!reload_queues())
- return AST_MODULE_LOAD_DECLINE;
-
- if (queue_persistent_members)
- reload_queue_members();
-
- ast_mutex_init(&device_state.lock);
- ast_cond_init(&device_state.cond, NULL);
- ast_pthread_create(&device_state.thread, NULL, device_state_thread, NULL);
-
- ast_cli_register_multiple(cli_queue, sizeof(cli_queue) / sizeof(struct ast_cli_entry));
- res = ast_register_application(app, queue_exec, synopsis, descrip);
- res |= ast_register_application(app_aqm, aqm_exec, app_aqm_synopsis, app_aqm_descrip);
- res |= ast_register_application(app_rqm, rqm_exec, app_rqm_synopsis, app_rqm_descrip);
- res |= ast_register_application(app_pqm, pqm_exec, app_pqm_synopsis, app_pqm_descrip);
- res |= ast_register_application(app_upqm, upqm_exec, app_upqm_synopsis, app_upqm_descrip);
- res |= ast_register_application(app_ql, ql_exec, app_ql_synopsis, app_ql_descrip);
- res |= ast_manager_register("Queues", 0, manager_queues_show, "Queues");
- res |= ast_manager_register("QueueStatus", 0, manager_queues_status, "Queue Status");
- res |= ast_manager_register("QueueAdd", EVENT_FLAG_AGENT, manager_add_queue_member, "Add interface to queue.");
- res |= ast_manager_register("QueueRemove", EVENT_FLAG_AGENT, manager_remove_queue_member, "Remove interface from queue.");
- res |= ast_manager_register("QueuePause", EVENT_FLAG_AGENT, manager_pause_queue_member, "Makes a queue member temporarily unavailable");
- res |= ast_custom_function_register(&queueagentcount_function);
- res |= ast_custom_function_register(&queuemembercount_function);
- res |= ast_custom_function_register(&queuememberlist_function);
- res |= ast_custom_function_register(&queuewaitingcount_function);
- res |= ast_devstate_add(statechange_queue, NULL);
-
- return res;
-}
-
-static int reload(void)
-{
- reload_queues();
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "True Call Queueing",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
diff --git a/1.4/apps/app_random.c b/1.4/apps/app_random.c
deleted file mode 100644
index 8484f656d..000000000
--- a/1.4/apps/app_random.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2003 - 2005 Tilghman Lesher. All rights reserved.
- *
- * Tilghman Lesher <asterisk__app_random__200508@the-tilghman.com>
- *
- * This code is released by the author with no restrictions on usage or distribution.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief Random application
- *
- * \author Tilghman Lesher <asterisk__app_random__200508@the-tilghman.com>
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-
-/*! \todo The Random() app should be removed from trunk following the release of 1.4 */
-
-static char *app_random = "Random";
-
-static char *random_synopsis = "Conditionally branches, based upon a probability";
-
-static char *random_descrip =
-"Random([probability]:[[context|]extension|]priority)\n"
-" probability := INTEGER in the range 1 to 100\n"
-"DEPRECATED: Use GotoIf($[${RAND(1,100)} > <number>]?<label>)\n";
-
-
-static int random_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
-
- char *s;
- char *prob;
- int probint;
- static int deprecated = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Random requires an argument ([probability]:[[context|]extension|]priority)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- s = ast_strdupa(data);
-
- prob = strsep(&s,":");
- if ((!prob) || (sscanf(prob, "%d", &probint) != 1))
- probint = 0;
-
- if (!deprecated) {
- deprecated = 1;
- ast_log(LOG_WARNING, "Random is deprecated in Asterisk 1.4. Replace with GotoIf($[${RAND(0,99)} + %d >= 100]?%s)\n", probint, s);
- }
-
- if ((ast_random() % 100) + probint >= 100) {
- res = ast_parseable_goto(chan, s);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Random branches to (%s,%s,%d)\n",
- chan->context,chan->exten, chan->priority+1);
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_random);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app_random, random_exec, random_synopsis, random_descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Random goto");
diff --git a/1.4/apps/app_read.c b/1.4/apps/app_read.c
deleted file mode 100644
index bb3dd669b..000000000
--- a/1.4/apps/app_read.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Trivial application to read a variable
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/app.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/indications.h"
-
-enum {
- OPT_SKIP = (1 << 0),
- OPT_INDICATION = (1 << 1),
- OPT_NOANSWER = (1 << 2),
-} read_option_flags;
-
-AST_APP_OPTIONS(read_app_options, {
- AST_APP_OPTION('s', OPT_SKIP),
- AST_APP_OPTION('i', OPT_INDICATION),
- AST_APP_OPTION('n', OPT_NOANSWER),
-});
-
-static char *app = "Read";
-
-static char *synopsis = "Read a variable";
-
-static char *descrip =
-" Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"
-"Reads a #-terminated string of digits a certain number of times from the\n"
-"user in to the given variable.\n"
-" filename -- file to play before reading digits or tone with option i\n"
-" maxdigits -- maximum acceptable number of digits. Stops reading after\n"
-" maxdigits have been entered (without requiring the user to\n"
-" press the '#' key).\n"
-" Defaults to 0 - no limit - wait for the user press the '#' key.\n"
-" Any value below 0 means the same. Max accepted value is 255.\n"
-" option -- options are 's' , 'i', 'n'\n"
-" 's' to return immediately if the line is not up,\n"
-" 'i' to play filename as an indication tone from your indications.conf\n"
-" 'n' to read digits even if the line is not up.\n"
-" attempts -- if greater than 1, that many attempts will be made in the \n"
-" event no data is entered.\n"
-" timeout -- An integer number of seconds to wait for a digit response. If greater\n"
-" than 0, that value will override the default timeout.\n\n"
-"Read should disconnect if the function fails or errors out.\n";
-
-
-#define ast_next_data(instr,ptr,delim) if((ptr=strchr(instr,delim))) { *(ptr) = '\0' ; ptr++;}
-
-static int read_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char tmp[256] = "";
- int maxdigits = 255;
- int tries = 1, to = 0, x = 0;
- char *argcopy = NULL;
- struct tone_zone_sound *ts;
- struct ast_flags flags = {0};
-
- AST_DECLARE_APP_ARGS(arglist,
- AST_APP_ARG(variable);
- AST_APP_ARG(filename);
- AST_APP_ARG(maxdigits);
- AST_APP_ARG(options);
- AST_APP_ARG(attempts);
- AST_APP_ARG(timeout);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- argcopy = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(arglist, argcopy);
-
- if (!ast_strlen_zero(arglist.options)) {
- ast_app_parse_options(read_app_options, &flags, NULL, arglist.options);
- }
-
- if (!ast_strlen_zero(arglist.attempts)) {
- tries = atoi(arglist.attempts);
- if (tries <= 0)
- tries = 1;
- }
-
- if (!ast_strlen_zero(arglist.timeout)) {
- to = atoi(arglist.timeout);
- if (to <= 0)
- to = 0;
- else
- to *= 1000;
- }
-
- if (ast_strlen_zero(arglist.filename)) {
- arglist.filename = NULL;
- }
- if (!ast_strlen_zero(arglist.maxdigits)) {
- maxdigits = atoi(arglist.maxdigits);
- if ((maxdigits<1) || (maxdigits>255)) {
- maxdigits = 255;
- } else if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %d digits.\n", maxdigits);
- }
- if (ast_strlen_zero(arglist.variable)) {
- ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n");
- ast_module_user_remove(u);
- return -1;
- }
- ts=NULL;
- if (ast_test_flag(&flags,OPT_INDICATION)) {
- if (!ast_strlen_zero(arglist.filename)) {
- ts = ast_get_indication_tone(chan->zone,arglist.filename);
- }
- }
- if (chan->_state != AST_STATE_UP) {
- if (ast_test_flag(&flags,OPT_SKIP)) {
- /* At the user's option, skip if the line is not up */
- pbx_builtin_setvar_helper(chan, arglist.variable, "\0");
- ast_module_user_remove(u);
- return 0;
- } else if (!ast_test_flag(&flags,OPT_NOANSWER)) {
- /* Otherwise answer unless we're supposed to read while on-hook */
- res = ast_answer(chan);
- }
- }
- if (!res) {
- while (tries && !res) {
- ast_stopstream(chan);
- if (ts && ts->data[0]) {
- if (!to)
- to = chan->pbx ? chan->pbx->rtimeout * 1000 : 6000;
- res = ast_playtones_start(chan, 0, ts->data, 0);
- for (x = 0; x < maxdigits; ) {
- res = ast_waitfordigit(chan, to);
- ast_playtones_stop(chan);
- if (res < 1) {
- tmp[x]='\0';
- break;
- }
- tmp[x++] = res;
- if (tmp[x-1] == '#') {
- tmp[x-1] = '\0';
- break;
- }
- }
- } else {
- res = ast_app_getdata(chan, arglist.filename, tmp, maxdigits, to);
- }
- if (res > -1) {
- pbx_builtin_setvar_helper(chan, arglist.variable, tmp);
- if (!ast_strlen_zero(tmp)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
- tries = 0;
- } else {
- tries--;
- if (option_verbose > 2) {
- if (tries)
- ast_verbose(VERBOSE_PREFIX_3 "User entered nothing, %d chance%s left\n", tries, (tries != 1) ? "s" : "");
- else
- ast_verbose(VERBOSE_PREFIX_3 "User entered nothing.\n");
- }
- }
- res = 0;
- } else {
- pbx_builtin_setvar_helper(chan, arglist.variable, tmp);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
- }
- }
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, read_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Read Variable Application");
diff --git a/1.4/apps/app_readfile.c b/1.4/apps/app_readfile.c
deleted file mode 100644
index 7e43a3806..000000000
--- a/1.4/apps/app_readfile.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Matt O'Gorman <mogorman@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.
- */
-
-/*! \file
- *
- * \brief ReadFile application -- Reads in a File for you.
- *
- * \author Matt O'Gorman <mogorman@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/app.h"
-#include "asterisk/module.h"
-
-static char *app_readfile = "ReadFile";
-
-static char *readfile_synopsis = "ReadFile(varname=file,length)";
-
-static char *readfile_descrip =
-"ReadFile(varname=file,length)\n"
-" Varname - Result stored here.\n"
-" File - The name of the file to read.\n"
-" Length - Maximum number of characters to capture.\n";
-
-
-static int readfile_exec(struct ast_channel *chan, void *data)
-{
- int res=0;
- struct ast_module_user *u;
- char *s, *varname=NULL, *file=NULL, *length=NULL, *returnvar=NULL;
- int len=0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "ReadFile require an argument!\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- s = ast_strdupa(data);
-
- varname = strsep(&s, "=");
- file = strsep(&s, "|");
- length = s;
-
- if (!varname || !file) {
- ast_log(LOG_ERROR, "No file or variable specified!\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if (length) {
- if ((sscanf(length, "%d", &len) != 1) || (len < 0)) {
- ast_log(LOG_WARNING, "%s is not a positive number, defaulting length to max\n", length);
- len = 0;
- }
- }
-
- if ((returnvar = ast_read_textfile(file))) {
- if (len > 0) {
- if (len < strlen(returnvar))
- returnvar[len]='\0';
- else
- ast_log(LOG_WARNING, "%s is longer than %d, and %d \n", file, len, (int)strlen(returnvar));
- }
- pbx_builtin_setvar_helper(chan, varname, returnvar);
- free(returnvar);
- }
- ast_module_user_remove(u);
- return res;
-}
-
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_readfile);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app_readfile, readfile_exec, readfile_synopsis, readfile_descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Stores output of file into a variable");
diff --git a/1.4/apps/app_realtime.c b/1.4/apps/app_realtime.c
deleted file mode 100644
index 48e1dca5b..000000000
--- a/1.4/apps/app_realtime.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Anthony Minessale <anthmct@yahoo.com>
- * 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.
- */
-
-/*! \file
- *
- * \brief RealTime App
- *
- * \author Anthony Minessale <anthmct@yahoo.com>
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/cli.h"
-
-#define next_one(var) var = var->next
-#define crop_data(str) { *(str) = '\0' ; (str)++; }
-
-static char *app = "RealTime";
-static char *uapp = "RealTimeUpdate";
-static char *synopsis = "Realtime Data Lookup";
-static char *usynopsis = "Realtime Data Rewrite";
-static char *USAGE = "RealTime(<family>|<colmatch>|<value>[|<prefix>])";
-static char *UUSAGE = "RealTimeUpdate(<family>|<colmatch>|<value>|<newcol>|<newval>)";
-static char *desc =
-"Use the RealTime config handler system to read data into channel variables.\n"
-"RealTime(<family>|<colmatch>|<value>[|<prefix>])\n\n"
-"All unique column names will be set as channel variables with optional prefix\n"
-"to the name. For example, a prefix of 'var_' would make the column 'name'\n"
-"become the variable ${var_name}. REALTIMECOUNT will be set with the number\n"
-"of values read.\n";
-static char *udesc = "Use the RealTime config handler system to update a value\n"
-"RealTimeUpdate(<family>|<colmatch>|<value>|<newcol>|<newval>)\n\n"
-"The column <newcol> in 'family' matching column <colmatch>=<value> will be\n"
-"updated to <newval>. REALTIMECOUNT will be set with the number of rows\n"
-"updated or -1 if an error occurs.\n";
-
-
-static int cli_realtime_load(int fd, int argc, char **argv)
-{
- char *header_format = "%30s %-30s\n";
- struct ast_variable *var=NULL;
-
- if(argc<5) {
- ast_cli(fd, "You must supply a family name, a column to match on, and a value to match to.\n");
- return RESULT_FAILURE;
- }
-
- var = ast_load_realtime(argv[2], argv[3], argv[4], NULL);
-
- if(var) {
- ast_cli(fd, header_format, "Column Name", "Column Value");
- ast_cli(fd, header_format, "--------------------", "--------------------");
- while(var) {
- ast_cli(fd, header_format, var->name, var->value);
- var = var->next;
- }
- } else {
- ast_cli(fd, "No rows found matching search criteria.\n");
- }
- return RESULT_SUCCESS;
-}
-
-static int cli_realtime_update(int fd, int argc, char **argv) {
- int res = 0;
-
- if(argc<7) {
- ast_cli(fd, "You must supply a family name, a column to update on, a new value, column to match, and value to to match.\n");
- ast_cli(fd, "Ex: realtime update sipfriends name bobsphone port 4343\n will execute SQL as UPDATE sipfriends SET port = 4343 WHERE name = bobsphone\n");
- return RESULT_FAILURE;
- }
-
- res = ast_update_realtime(argv[2], argv[3], argv[4], argv[5], argv[6], NULL);
-
- if(res < 0) {
- ast_cli(fd, "Failed to update. Check the debug log for possible SQL related entries.\n");
- return RESULT_SUCCESS;
- }
-
- ast_cli(fd, "Updated %d RealTime record%s.\n", res, (res != 1) ? "s" : "");
-
- return RESULT_SUCCESS;
-}
-
-static char cli_realtime_load_usage[] =
-"Usage: realtime load <family> <colmatch> <value>\n"
-" Prints out a list of variables using the RealTime driver.\n";
-
-static char cli_realtime_update_usage[] =
-"Usage: realtime update <family> <colmatch> <value>\n"
-" Update a single variable using the RealTime driver.\n";
-
-static struct ast_cli_entry cli_realtime[] = {
- { { "realtime", "load", NULL, NULL },
- cli_realtime_load, "Used to print out RealTime variables.",
- cli_realtime_load_usage, NULL },
-
- { { "realtime", "update", NULL, NULL },
- cli_realtime_update, "Used to update RealTime variables.",
- cli_realtime_update_usage, NULL },
-};
-
-static int realtime_update_exec(struct ast_channel *chan, void *data)
-{
- char *family=NULL, *colmatch=NULL, *value=NULL, *newcol=NULL, *newval=NULL;
- struct ast_module_user *u;
- int res = 0, count = 0;
- char countc[13];
-
- ast_log(LOG_WARNING, "The RealTimeUpdate application has been deprecated in favor of the REALTIME dialplan function.\n");
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR,"Invalid input: usage %s\n",UUSAGE);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- family = ast_strdupa(data);
- if ((colmatch = strchr(family,'|'))) {
- crop_data(colmatch);
- if ((value = strchr(colmatch,'|'))) {
- crop_data(value);
- if ((newcol = strchr(value,'|'))) {
- crop_data(newcol);
- if ((newval = strchr(newcol,'|')))
- crop_data(newval);
- }
- }
- }
- if (! (family && value && colmatch && newcol && newval) ) {
- ast_log(LOG_ERROR,"Invalid input: usage %s\n",UUSAGE);
- res = -1;
- } else {
- count = ast_update_realtime(family,colmatch,value,newcol,newval,NULL);
- }
-
- snprintf(countc, sizeof(countc), "%d", count);
- pbx_builtin_setvar_helper(chan, "REALTIMECOUNT", countc);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-
-static int realtime_exec(struct ast_channel *chan, void *data)
-{
- int res=0, count=0;
- struct ast_module_user *u;
- struct ast_variable *var, *itt;
- char *family=NULL, *colmatch=NULL, *value=NULL, *prefix=NULL, *vname=NULL;
- char countc[13];
- size_t len;
-
- ast_log(LOG_WARNING, "The RealTime application has been deprecated in favor of the REALTIME dialplan function.\n");
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR,"Invalid input: usage %s\n",USAGE);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- family = ast_strdupa(data);
- if ((colmatch = strchr(family,'|'))) {
- crop_data(colmatch);
- if ((value = strchr(colmatch,'|'))) {
- crop_data(value);
- if ((prefix = strchr(value,'|')))
- crop_data(prefix);
- }
- }
- if (! (family && value && colmatch) ) {
- ast_log(LOG_ERROR,"Invalid input: usage %s\n",USAGE);
- res = -1;
- } else {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4"Realtime Lookup: family:'%s' colmatch:'%s' value:'%s'\n",family,colmatch,value);
- if ((var = ast_load_realtime(family, colmatch, value, NULL))) {
- for (itt = var; itt; itt = itt->next) {
- if(prefix) {
- len = strlen(prefix) + strlen(itt->name) + 2;
- vname = alloca(len);
- snprintf(vname,len,"%s%s",prefix,itt->name);
-
- } else
- vname = itt->name;
-
- pbx_builtin_setvar_helper(chan, vname, itt->value);
- count++;
- }
- ast_variables_destroy(var);
- } else if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4"No Realtime Matches Found.\n");
- }
- snprintf(countc, sizeof(countc), "%d", count);
- pbx_builtin_setvar_helper(chan, "REALTIMECOUNT", countc);
-
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- ast_cli_unregister_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
- res = ast_unregister_application(uapp);
- res |= ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- ast_cli_register_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
- res = ast_register_application(uapp, realtime_update_exec, usynopsis, udesc);
- res |= ast_register_application(app, realtime_exec, synopsis, desc);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Realtime Data Lookup/Rewrite");
diff --git a/1.4/apps/app_record.c b/1.4/apps/app_record.c
deleted file mode 100644
index 23e1a9a85..000000000
--- a/1.4/apps/app_record.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Matthew Fredrickson <creslin@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.
- */
-
-/*! \file
- *
- * \brief Trivial application to record a sound file
- *
- * \author Matthew Fredrickson <creslin@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/dsp.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-
-
-static char *app = "Record";
-
-static char *synopsis = "Record to a file";
-
-static char *descrip =
-" Record(filename.format|silence[|maxduration][|options])\n\n"
-"Records from the channel into a given filename. If the file exists it will\n"
-"be overwritten.\n"
-"- 'format' is the format of the file type to be recorded (wav, gsm, etc).\n"
-"- 'silence' is the number of seconds of silence to allow before returning.\n"
-"- 'maxduration' is the maximum recording duration in seconds. If missing\n"
-"or 0 there is no maximum.\n"
-"- 'options' may contain any of the following letters:\n"
-" 'a' : append to existing recording rather than replacing\n"
-" 'n' : do not answer, but record anyway if line not yet answered\n"
-" 'q' : quiet (do not play a beep tone)\n"
-" 's' : skip recording if the line is not yet answered\n"
-" 't' : use alternate '*' terminator key (DTMF) instead of default '#'\n"
-" 'x' : ignore all terminator keys (DTMF) and keep recording until hangup\n"
-"\n"
-"If filename contains '%d', these characters will be replaced with a number\n"
-"incremented by one each time the file is recorded. A channel variable\n"
-"named RECORDED_FILE will also be set, which contains the final filemname.\n\n"
-"Use 'core show file formats' to see the available formats on your system\n\n"
-"User can press '#' to terminate the recording and continue to the next priority.\n\n"
-"If the user should hangup during a recording, all data will be lost and the\n"
-"application will teminate. \n";
-
-
-static int record_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- int count = 0;
- int percentflag = 0;
- char *filename, *ext = NULL, *silstr, *maxstr, *options;
- char *vdata, *p;
- int i = 0;
- char tmp[256];
-
- struct ast_filestream *s = '\0';
- struct ast_module_user *u;
- struct ast_frame *f = NULL;
-
- struct ast_dsp *sildet = NULL; /* silence detector dsp */
- int totalsilence = 0;
- int dspsilence = 0;
- int silence = 0; /* amount of silence to allow */
- int gotsilence = 0; /* did we timeout for silence? */
- int maxduration = 0; /* max duration of recording in milliseconds */
- int gottimeout = 0; /* did we timeout for maxduration exceeded? */
- int option_skip = 0;
- int option_noanswer = 0;
- int option_append = 0;
- int terminator = '#';
- int option_quiet = 0;
- int rfmt = 0;
- int flags;
- int waitres;
- struct ast_silence_generator *silgen = NULL;
-
- /* The next few lines of code parse out the filename and header from the input string */
- if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
- ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- /* Yay for strsep being easy */
- vdata = ast_strdupa(data);
-
- p = vdata;
- filename = strsep(&p, "|");
- silstr = strsep(&p, "|");
- maxstr = strsep(&p, "|");
- options = strsep(&p, "|");
-
- if (filename) {
- if (strstr(filename, "%d"))
- percentflag = 1;
- ext = strrchr(filename, '.'); /* to support filename with a . in the filename, not format */
- if (!ext)
- ext = strchr(filename, ':');
- if (ext) {
- *ext = '\0';
- ext++;
- }
- }
- if (!ext) {
- ast_log(LOG_WARNING, "No extension specified to filename!\n");
- ast_module_user_remove(u);
- return -1;
- }
- if (silstr) {
- if ((sscanf(silstr, "%d", &i) == 1) && (i > -1)) {
- silence = i * 1000;
- } else if (!ast_strlen_zero(silstr)) {
- ast_log(LOG_WARNING, "'%s' is not a valid silence duration\n", silstr);
- }
- }
-
- if (maxstr) {
- if ((sscanf(maxstr, "%d", &i) == 1) && (i > -1))
- /* Convert duration to milliseconds */
- maxduration = i * 1000;
- else if (!ast_strlen_zero(maxstr))
- ast_log(LOG_WARNING, "'%s' is not a valid maximum duration\n", maxstr);
- }
- if (options) {
- /* Retain backwards compatibility with old style options */
- if (!strcasecmp(options, "skip"))
- option_skip = 1;
- else if (!strcasecmp(options, "noanswer"))
- option_noanswer = 1;
- else {
- if (strchr(options, 's'))
- option_skip = 1;
- if (strchr(options, 'n'))
- option_noanswer = 1;
- if (strchr(options, 'a'))
- option_append = 1;
- if (strchr(options, 't'))
- terminator = '*';
- if (strchr(options, 'x'))
- terminator = 0;
- if (strchr(options, 'q'))
- option_quiet = 1;
- }
- }
-
- /* done parsing */
-
- /* these are to allow the use of the %d in the config file for a wild card of sort to
- create a new file with the inputed name scheme */
- if (percentflag) {
- AST_DECLARE_APP_ARGS(fname,
- AST_APP_ARG(piece)[100];
- );
- char *tmp2 = ast_strdupa(filename);
- char countstring[15];
- int i;
-
- /* Separate each piece out by the format specifier */
- AST_NONSTANDARD_APP_ARGS(fname, tmp2, '%');
- do {
- int tmplen;
- /* First piece has no leading percent, so it's copied verbatim */
- ast_copy_string(tmp, fname.piece[0], sizeof(tmp));
- tmplen = strlen(tmp);
- for (i = 1; i < fname.argc; i++) {
- if (fname.piece[i][0] == 'd') {
- /* Substitute the count */
- snprintf(countstring, sizeof(countstring), "%d", count);
- ast_copy_string(tmp + tmplen, countstring, sizeof(tmp) - tmplen);
- tmplen += strlen(countstring);
- } else if (tmplen + 2 < sizeof(tmp)) {
- /* Unknown format specifier - just copy it verbatim */
- tmp[tmplen++] = '%';
- tmp[tmplen++] = fname.piece[i][0];
- }
- /* Copy the remaining portion of the piece */
- ast_copy_string(tmp + tmplen, &(fname.piece[i][1]), sizeof(tmp) - tmplen);
- }
- count++;
- } while (ast_fileexists(tmp, ext, chan->language) > 0);
- pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
- } else
- ast_copy_string(tmp, filename, sizeof(tmp));
- /* end of routine mentioned */
-
-
-
- if (chan->_state != AST_STATE_UP) {
- if (option_skip) {
- /* At the user's option, skip if the line is not up */
- ast_module_user_remove(u);
- return 0;
- } else if (!option_noanswer) {
- /* Otherwise answer unless we're supposed to record while on-hook */
- res = ast_answer(chan);
- }
- }
-
- if (res) {
- ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
- goto out;
- }
-
- if (!option_quiet) {
- /* Some code to play a nice little beep to signify the start of the record operation */
- res = ast_streamfile(chan, "beep", chan->language);
- if (!res) {
- res = ast_waitstream(chan, "");
- } else {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
- }
- ast_stopstream(chan);
- }
-
- /* The end of beep code. Now the recording starts */
-
- if (silence > 0) {
- rfmt = chan->readformat;
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
- ast_module_user_remove(u);
- return -1;
- }
- sildet = ast_dsp_new();
- if (!sildet) {
- ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
- ast_module_user_remove(u);
- return -1;
- }
- ast_dsp_set_threshold(sildet, 256);
- }
-
-
- flags = option_append ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
- s = ast_writefile( tmp, ext, NULL, flags , 0, 0644);
-
- if (!s) {
- ast_log(LOG_WARNING, "Could not create file %s\n", filename);
- goto out;
- }
-
- if (ast_opt_transmit_silence)
- silgen = ast_channel_start_silence_generator(chan);
-
- /* Request a video update */
- ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-
- if (maxduration <= 0)
- maxduration = -1;
-
- while ((waitres = ast_waitfor(chan, maxduration)) > -1) {
- if (maxduration > 0) {
- if (waitres == 0) {
- gottimeout = 1;
- break;
- }
- maxduration = waitres;
- }
-
- f = ast_read(chan);
- if (!f) {
- res = -1;
- break;
- }
- if (f->frametype == AST_FRAME_VOICE) {
- res = ast_writestream(s, f);
-
- if (res) {
- ast_log(LOG_WARNING, "Problem writing frame\n");
- ast_frfree(f);
- break;
- }
-
- if (silence > 0) {
- dspsilence = 0;
- ast_dsp_silence(sildet, f, &dspsilence);
- if (dspsilence) {
- totalsilence = dspsilence;
- } else {
- totalsilence = 0;
- }
- if (totalsilence > silence) {
- /* Ended happily with silence */
- ast_frfree(f);
- gotsilence = 1;
- break;
- }
- }
- } else if (f->frametype == AST_FRAME_VIDEO) {
- res = ast_writestream(s, f);
-
- if (res) {
- ast_log(LOG_WARNING, "Problem writing frame\n");
- ast_frfree(f);
- break;
- }
- } else if ((f->frametype == AST_FRAME_DTMF) &&
- (f->subclass == terminator)) {
- ast_frfree(f);
- break;
- }
- ast_frfree(f);
- }
- if (!f) {
- ast_log(LOG_DEBUG, "Got hangup\n");
- res = -1;
- }
-
- if (gotsilence) {
- ast_stream_rewind(s, silence-1000);
- ast_truncstream(s);
- } else if (!gottimeout) {
- /* Strip off the last 1/4 second of it */
- ast_stream_rewind(s, 250);
- ast_truncstream(s);
- }
- ast_closestream(s);
-
- if (silgen)
- ast_channel_stop_silence_generator(chan, silgen);
-
- out:
- if ((silence > 0) && rfmt) {
- res = ast_set_read_format(chan, rfmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
- if (sildet)
- ast_dsp_free(sildet);
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, record_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Trivial Record Application");
diff --git a/1.4/apps/app_rpt.c b/1.4/apps/app_rpt.c
deleted file mode 100644
index 952fdd0b1..000000000
--- a/1.4/apps/app_rpt.c
+++ /dev/null
@@ -1,11928 +0,0 @@
-/* #define OLD_ASTERISK */
-#define OLDKEY
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2002-2007, Jim Dixon, WB6NIL
- *
- * Jim Dixon, WB6NIL <jim@lambdatel.com>
- * Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.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.
- */
-/*! \file
- *
- * \brief Radio Repeater / Remote Base program
- * version 0.73 09/04/07
- *
- * \author Jim Dixon, WB6NIL <jim@lambdatel.com>
- *
- * \note Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
- *
- * See http://www.zapatatelephony.org/app_rpt.html
- *
- *
- * Repeater / Remote Functions:
- * "Simple" Mode: * - autopatch access, # - autopatch hangup
- * Normal mode:
- * See the function list in rpt.conf (autopatchup, autopatchdn)
- * autopatchup can optionally take comma delimited setting=value pairs:
- *
- *
- * context=string : Override default context with "string"
- * dialtime=ms : Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second)
- * farenddisconnect=1 : Automatically disconnect when called party hangs up
- * noct=1 : Don't send repeater courtesy tone during autopatch calls
- * quiet=1 : Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up
- *
- *
- * Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1
- *
- * To send an asterisk (*) while dialing or talking on phone,
- * use the autopatch acess code.
- *
- *
- * status cmds:
- *
- * 1 - Force ID
- * 2 - Give Time of Day
- * 3 - Give software Version
- *
- * cop (control operator) cmds:
- *
- * 1 - System warm boot
- * 2 - System enable
- * 3 - System disable
- * 4 - Test Tone On/Off
- * 5 - Dump System Variables on Console (debug)
- * 6 - PTT (phone mode only)
- * 7 - Time out timer enable
- * 8 - Time out timer disable
- * 9 - Autopatch enable
- * 10 - Autopatch disable
- * 11 - Link enable
- * 12 - Link disable
- * 13 - Query System State
- * 14 - Change System State
- * 15 - Scheduler Enable
- * 16 - Scheduler Disable
- * 17 - User functions (time, id, etc) enable
- * 18 - User functions (time, id, etc) disable
- * 19 - Select alternate hang timer
- * 20 - Select standard hang timer
- *
- * ilink cmds:
- *
- * 1 - Disconnect specified link
- * 2 - Connect specified link -- monitor only
- * 3 - Connect specified link -- tranceive
- * 4 - Enter command mode on specified link
- * 5 - System status
- * 6 - Disconnect all links
- * 11 - Disconnect a previously permanently connected link
- * 12 - Permanently connect specified link -- monitor only
- * 13 - Permanently connect specified link -- tranceive
- * 15 - Full system status (all nodes)
- * 16 - Reconnect links disconnected with "disconnect all links"
- * 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
- *
- * remote cmds:
- *
- * 1 - Recall Memory MM (*000-*099) (Gets memory from rpt.conf)
- * 2 - Set VFO MMMMM*KKK*O (Mhz digits, Khz digits, Offset)
- * 3 - Set Rx PL Tone HHH*D*
- * 4 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1)
- * 5 - Link Status (long)
- * 6 - Set operating mode M (FM, USB, LSB, AM, etc)
- * 100 - RX PL off (Default)
- * 101 - RX PL On
- * 102 - TX PL Off (Default)
- * 103 - TX PL On
- * 104 - Low Power
- * 105 - Med Power
- * 106 - Hi Power
- * 107 - Bump Down 20 Hz
- * 108 - Bump Down 100 Hz
- * 109 - Bump Down 500 Hz
- * 110 - Bump Up 20 Hz
- * 111 - Bump Up 100 Hz
- * 112 - Bump Up 500 Hz
- * 113 - Scan Down Slow
- * 114 - Scan Down Medium
- * 115 - Scan Down Fast
- * 116 - Scan Up Slow
- * 117 - Scan Up Medium
- * 118 - Scan Up Fast
- * 119 - Transmit allowing auto-tune
- * 140 - Link Status (brief)
- * 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
- *
- *
- * 'duplex' modes: (defaults to duplex=2)
- *
- * 0 - Only remote links key Tx and no main repeat audio.
- * 1 - Everything other then main Rx keys Tx, no main repeat audio.
- * 2 - Normal mode
- * 3 - Normal except no main repeat audio.
- * 4 - Normal except no main repeat audio during autopatch only
- *
-*/
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- <depend>tonezone</depend>
- <defaultenabled>no</defaultenabled>
- ***/
-
-/* Un-comment the following to include support for MDC-1200 digital tone
- signalling protocol (using KA6SQG's GPL'ed implementation) */
-/* #include "mdc_decode.c" */
-
-/* Un-comment the following to include support for notch filters in the
- rx audio stream (using Tony Fisher's mknotch (mkfilter) implementation) */
-/* #include "rpt_notch.c" */
-
-/* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */
-
-#define MAXDTMF 32
-#define MAXMACRO 2048
-#define MAXLINKLIST 512
-#define LINKLISTTIME 10000
-#define LINKLISTSHORTTIME 200
-#define MACROTIME 100
-#define MACROPTIME 500
-#define DTMF_TIMEOUT 3
-#define KENWOOD_RETRIES 5
-
-#define AUTHTELLTIME 7000
-#define AUTHTXTIME 1000
-#define AUTHLOGOUTTIME 25000
-
-#ifdef __RPT_NOTCH
-#define MAXFILTERS 10
-#endif
-
-#define DISC_TIME 10000 /* report disc after 10 seconds of no connect */
-#define MAX_RETRIES 5
-#define MAX_RETRIES_PERM 1000000000
-
-#define REDUNDANT_TX_TIME 2000
-
-#define RETRY_TIMER_MS 5000
-
-#define START_DELAY 2
-
-#define MAXPEERSTR 31
-#define MAXREMSTR 15
-
-#define DELIMCHR ','
-#define QUOTECHR 34
-
-#define MONITOR_DISK_BLOCKS_PER_MINUTE 38
-
-#define DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000
-#define DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60)
-#define DEFAULT_REMOTE_TIMEOUT (60 * 60)
-#define DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60)
-#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30
-
-#define NODES "nodes"
-#define EXTNODES "extnodes"
-#define MEMORY "memory"
-#define MACRO "macro"
-#define FUNCTIONS "functions"
-#define TELEMETRY "telemetry"
-#define MORSE "morse"
-#define FUNCCHAR '*'
-#define ENDCHAR '#'
-#define EXTNODEFILE "/var/lib/asterisk/rpt_extnodes"
-
-#define DEFAULT_IOBASE 0x378
-
-#define DEFAULT_CIV_ADDR 0x58
-
-#define MAXCONNECTTIME 5000
-
-#define MAXNODESTR 300
-
-#define MAXPATCHCONTEXT 100
-
-#define ACTIONSIZE 32
-
-#define TELEPARAMSIZE 256
-
-#define REM_SCANTIME 100
-
-#define DTMF_LOCAL_TIME 250
-#define DTMF_LOCAL_STARTTIME 500
-
-#define IC706_PL_MEMORY_OFFSET 50
-
-#define ALLOW_LOCAL_CHANNELS
-
-enum {REM_OFF,REM_MONITOR,REM_TX};
-
-enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
- CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
- STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
- TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS,
- MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS,
- REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE,
- TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX};
-
-
-enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
-
-enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR};
-
-enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY};
-
-enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
-
-enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY};
-
-enum {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
-
-enum {HF_SCAN_OFF,HF_SCAN_DOWN_SLOW,HF_SCAN_DOWN_QUICK,
- HF_SCAN_DOWN_FAST,HF_SCAN_UP_SLOW,HF_SCAN_UP_QUICK,HF_SCAN_UP_FAST};
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <search.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/io.h>
-#include <sys/vfs.h>
-#include <math.h>
-#ifdef OLD_ASTERISK
-#include <linux/zaptel.h>
-#include <tonezone.h>
-#else
-#include <zaptel/zaptel.h>
-#include <zaptel/tonezone.h>
-#endif
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/callerid.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/features.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/config.h"
-#include "asterisk/say.h"
-#include "asterisk/localtime.h"
-#include "asterisk/cdr.h"
-#include "asterisk/options.h"
-#include <termios.h>
-
-/* Start a tone-list going */
-int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
-/*! Stop the tones from playing */
-void ast_playtones_stop(struct ast_channel *chan);
-
-static char *tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007";
-
-static char *app = "Rpt";
-
-static char *synopsis = "Radio Repeater/Remote Base Control System";
-
-static char *descrip =
-" Rpt(nodename[|options]): Radio Remote Link or Remote Base Link Endpoint Process.\n"
-"\n"
-" Not specifying an option puts it in normal endpoint mode (where source\n"
-" IP and nodename are verified).\n"
-"\n"
-" Options are as follows:\n"
-"\n"
-" X - Normal endpoint mode WITHOUT security check. Only specify\n"
-" this if you have checked security already (like with an IAX2\n"
-" user/password or something).\n"
-"\n"
-" Rannounce-string[|timeout[|timeout-destination]] - Amateur Radio\n"
-" Reverse Autopatch. Caller is put on hold, and announcement (as\n"
-" specified by the 'announce-string') is played on radio system.\n"
-" Users of radio system can access autopatch, dial specified\n"
-" code, and pick up call. Announce-string is list of names of\n"
-" recordings, or \"PARKED\" to substitute code for un-parking,\n"
-" or \"NODE\" to substitute node number.\n"
-"\n"
-" P - Phone Control mode. This allows a regular phone user to have\n"
-" full control and audio access to the radio system. For the\n"
-" user to have DTMF control, the 'phone_functions' parameter\n"
-" must be specified for the node in 'rpt.conf'. An additional\n"
-" function (cop,6) must be listed so that PTT control is available.\n"
-"\n"
-" D - Dumb Phone Control mode. This allows a regular phone user to\n"
-" have full control and audio access to the radio system. In this\n"
-" mode, the PTT is activated for the entire length of the call.\n"
-" For the user to have DTMF control (not generally recomended in\n"
-" this mode), the 'dphone_functions' parameter must be specified\n"
-" for the node in 'rpt.conf'. Otherwise no DTMF control will be\n"
-" available to the phone user.\n"
-"\n";
-
-static int debug = 0; /* Set this >0 for extra debug output */
-static int nrpts = 0;
-
-static char remdtmfstr[] = "0123456789*#ABCD";
-
-enum {TOP_TOP,TOP_WON,WON_BEFREAD,BEFREAD_AFTERREAD};
-
-int max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000};
-
-#define NRPTSTAT 7
-
-struct rpt_chan_stat
-{
- struct timeval last;
- long long total;
- unsigned long count;
- unsigned long largest;
- struct timeval largest_time;
-};
-
-char *discstr = "!!DISCONNECT!!";
-static char *remote_rig_ft897="ft897";
-static char *remote_rig_rbi="rbi";
-static char *remote_rig_kenwood="kenwood";
-static char *remote_rig_ic706="ic706";
-
-#ifdef OLD_ASTERISK
-STANDARD_LOCAL_USER;
-LOCAL_USER_DECL;
-#endif
-
-#define MSWAIT 200
-#define HANGTIME 5000
-#define TOTIME 180000
-#define IDTIME 300000
-#define MAXRPTS 20
-#define MAX_STAT_LINKS 32
-#define POLITEID 30000
-#define FUNCTDELAY 1500
-
-#define MAXXLAT 20
-#define MAXXLATTIME 3
-
-#define MAX_SYSSTATES 10
-
-struct rpt_xlat
-{
-char funccharseq[MAXXLAT];
-char endcharseq[MAXXLAT];
-char passchars[MAXXLAT];
-int funcindex;
-int endindex;
-time_t lastone;
-} ;
-
-static time_t starttime = 0;
-
-static pthread_t rpt_master_thread;
-
-struct rpt;
-
-struct rpt_link
-{
- struct rpt_link *next;
- struct rpt_link *prev;
- char mode; /* 1 if in tx mode */
- char isremote;
- char phonemode;
- char name[MAXNODESTR]; /* identifier (routing) string */
- char lasttx;
- char lastrx;
- char lastrx1;
- char connected;
- char hasconnected;
- char perma;
- char thisconnected;
- char outbound;
- char disced;
- char killme;
- long elaptime;
- long disctime;
- long retrytimer;
- long retxtimer;
- long rerxtimer;
- int retries;
- int max_retries;
- int reconnects;
- long long connecttime;
- struct ast_channel *chan;
- struct ast_channel *pchan;
- char linklist[MAXLINKLIST];
- time_t linklistreceived;
- long linklisttimer;
- int dtmfed;
- int linkunkeytocttimer;
- struct ast_frame *lastf1,*lastf2;
- struct rpt_chan_stat chan_stat[NRPTSTAT];
-} ;
-
-struct rpt_lstat
-{
- struct rpt_lstat *next;
- struct rpt_lstat *prev;
- char peer[MAXPEERSTR];
- char name[MAXNODESTR];
- char mode;
- char outbound;
- char reconnects;
- char thisconnected;
- long long connecttime;
- struct rpt_chan_stat chan_stat[NRPTSTAT];
-} ;
-
-struct rpt_tele
-{
- struct rpt_tele *next;
- struct rpt_tele *prev;
- struct rpt *rpt;
- struct ast_channel *chan;
- int mode;
- struct rpt_link mylink;
- char param[TELEPARAMSIZE];
- int submode;
- pthread_t threadid;
-} ;
-
-struct function_table_tag
-{
- char action[ACTIONSIZE];
- int (*function)(struct rpt *myrpt, char *param, char *digitbuf,
- int command_source, struct rpt_link *mylink);
-} ;
-
-/* Used to store the morse code patterns */
-
-struct morse_bits
-{
- int len;
- int ddcomb;
-} ;
-
-struct telem_defaults
-{
- char name[20];
- char value[80];
-} ;
-
-
-struct sysstate
-{
- char txdisable;
- char totdisable;
- char linkfundisable;
- char autopatchdisable;
- char schedulerdisable;
- char userfundisable;
- char alternatetail;
-};
-
-static struct rpt
-{
- ast_mutex_t lock;
- ast_mutex_t remlock;
- struct ast_config *cfg;
- char reload;
-
- char *name;
- char *rxchanname;
- char *txchanname;
- char *remote;
- struct rpt_chan_stat chan_stat[NRPTSTAT];
- unsigned int scram;
-
- struct {
- char *ourcontext;
- char *ourcallerid;
- char *acctcode;
- char *ident;
- char *tonezone;
- char simple;
- char *functions;
- char *link_functions;
- char *phone_functions;
- char *dphone_functions;
- char *nodes;
- char *extnodes;
- char *extnodefile;
- int hangtime;
- int althangtime;
- int totime;
- int idtime;
- int tailmessagetime;
- int tailsquashedtime;
- int duplex;
- int politeid;
- char *tailmessages[500];
- int tailmessagemax;
- char *memory;
- char *macro;
- char *startupmacro;
- int iobase;
- char *ioport;
- char funcchar;
- char endchar;
- char nobusyout;
- char notelemtx;
- char propagate_dtmf;
- char propagate_phonedtmf;
- char linktolink;
- unsigned char civaddr;
- struct rpt_xlat inxlat;
- struct rpt_xlat outxlat;
- char *archivedir;
- int authlevel;
- char *csstanzaname;
- char *skedstanzaname;
- char *txlimitsstanzaname;
- long monminblocks;
- int remoteinacttimeout;
- int remotetimeout;
- int remotetimeoutwarning;
- int remotetimeoutwarningfreq;
- int sysstate_cur;
- struct sysstate s[MAX_SYSSTATES];
- } p;
- struct rpt_link links;
- int unkeytocttimer;
- char keyed;
- char exttx;
- char localtx;
- char remoterx;
- char remotetx;
- char remoteon;
- char remtxfreqok;
- char tounkeyed;
- char tonotify;
- char dtmfbuf[MAXDTMF];
- char macrobuf[MAXMACRO];
- char rem_dtmfbuf[MAXDTMF];
- char lastdtmfcommand[MAXDTMF];
- char cmdnode[50];
- struct ast_channel *rxchannel,*txchannel, *monchannel;
- struct ast_channel *pchannel,*txpchannel, *zaprxchannel, *zaptxchannel;
- struct ast_frame *lastf1,*lastf2;
- struct rpt_tele tele;
- struct timeval lasttv,curtv;
- pthread_t rpt_call_thread,rpt_thread;
- time_t dtmf_time,rem_dtmf_time,dtmf_time_rem;
- int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer,tmsgtimer,skedtimer;
- int mustid,tailid;
- int tailevent;
- int telemrefcount;
- int dtmfidx,rem_dtmfidx;
- int dailytxtime,dailykerchunks,totalkerchunks,dailykeyups,totalkeyups,timeouts;
- int totalexecdcommands, dailyexecdcommands;
- long retxtimer;
- long rerxtimer;
- long long totaltxtime;
- char mydtmf;
- char exten[AST_MAX_EXTENSION];
- char freq[MAXREMSTR],rxpl[MAXREMSTR],txpl[MAXREMSTR];
- char offset;
- char powerlevel;
- char txplon;
- char rxplon;
- char remmode;
- char tunerequest;
- char hfscanmode;
- int hfscanstatus;
- char hfscanstop;
- char lastlinknode[MAXNODESTR];
- char savednodes[MAXNODESTR];
- int stopgen;
- char patchfarenddisconnect;
- char patchnoct;
- char patchquiet;
- char patchcontext[MAXPATCHCONTEXT];
- int patchdialtime;
- int macro_longest;
- int phone_longestfunc;
- int dphone_longestfunc;
- int link_longestfunc;
- int longestfunc;
- int longestnode;
- int threadrestarts;
- int tailmessagen;
- time_t disgorgetime;
- time_t lastthreadrestarttime;
- long macrotimer;
- char lastnodewhichkeyedusup[MAXNODESTR];
- int dtmf_local_timer;
- char dtmf_local_str[100];
- struct ast_filestream *monstream;
- char loginuser[50];
- char loginlevel[10];
- long authtelltimer;
- long authtimer;
- int iofd;
- time_t start_time,last_activity_time;
-#ifdef __RPT_NOTCH
- struct rptfilter
- {
- char desc[100];
- float x0;
- float x1;
- float x2;
- float y0;
- float y1;
- float y2;
- float gain;
- float const0;
- float const1;
- float const2;
- } filters[MAXFILTERS];
-#endif
-#ifdef _MDC_DECODE_H_
- mdc_decoder_t *mdc;
- unsigned short lastunit;
-#endif
-} rpt_vars[MAXRPTS];
-
-struct nodelog {
-struct nodelog *next;
-struct nodelog *prev;
-time_t timestamp;
-char archivedir[MAXNODESTR];
-char str[MAXNODESTR * 2];
-} nodelog;
-
-static int service_scan(struct rpt *myrpt);
-static int set_mode_ft897(struct rpt *myrpt, char newmode);
-static int set_mode_ic706(struct rpt *myrpt, char newmode);
-static int simple_command_ft897(struct rpt *myrpt, char command);
-static int setrem(struct rpt *myrpt);
-
-AST_MUTEX_DEFINE_STATIC(nodeloglock);
-
-AST_MUTEX_DEFINE_STATIC(nodelookuplock);
-
-#ifdef APP_RPT_LOCK_DEBUG
-
-#warning COMPILING WITH LOCK-DEBUGGING ENABLED!!
-
-#define MAXLOCKTHREAD 100
-
-#define rpt_mutex_lock(x) _rpt_mutex_lock(x,myrpt,__LINE__)
-#define rpt_mutex_unlock(x) _rpt_mutex_unlock(x,myrpt,__LINE__)
-
-struct lockthread
-{
- pthread_t id;
- int lockcount;
- int lastlock;
- int lastunlock;
-} lockthreads[MAXLOCKTHREAD];
-
-
-struct by_lightning
-{
- int line;
- struct timeval tv;
- struct rpt *rpt;
- struct lockthread lockthread;
-} lock_ring[32];
-
-int lock_ring_index = 0;
-
-AST_MUTEX_DEFINE_STATIC(locklock);
-
-static struct lockthread *get_lockthread(pthread_t id)
-{
-int i;
-
- for(i = 0; i < MAXLOCKTHREAD; i++)
- {
- if (lockthreads[i].id == id) return(&lockthreads[i]);
- }
- return(NULL);
-}
-
-static struct lockthread *put_lockthread(pthread_t id)
-{
-int i;
-
- for(i = 0; i < MAXLOCKTHREAD; i++)
- {
- if (lockthreads[i].id == id)
- return(&lockthreads[i]);
- }
- for(i = 0; i < MAXLOCKTHREAD; i++)
- {
- if (!lockthreads[i].id)
- {
- lockthreads[i].lockcount = 0;
- lockthreads[i].lastlock = 0;
- lockthreads[i].lastunlock = 0;
- lockthreads[i].id = id;
- return(&lockthreads[i]);
- }
- }
- return(NULL);
-}
-
-
-static void rpt_mutex_spew(void)
-{
- struct by_lightning lock_ring_copy[32];
- int lock_ring_index_copy;
- int i,j;
- long long diff;
- char a[100];
- struct timeval lasttv;
-
- ast_mutex_lock(&locklock);
- memcpy(&lock_ring_copy, &lock_ring, sizeof(lock_ring_copy));
- lock_ring_index_copy = lock_ring_index;
- ast_mutex_unlock(&locklock);
-
- lasttv.tv_sec = lasttv.tv_usec = 0;
- for(i = 0 ; i < 32 ; i++)
- {
- j = (i + lock_ring_index_copy) % 32;
- strftime(a,sizeof(a) - 1,"%m/%d/%Y %H:%M:%S",
- localtime(&lock_ring_copy[j].tv.tv_sec));
- diff = 0;
- if(lasttv.tv_sec)
- {
- diff = (lock_ring_copy[j].tv.tv_sec - lasttv.tv_sec)
- * 1000000;
- diff += (lock_ring_copy[j].tv.tv_usec - lasttv.tv_usec);
- }
- lasttv.tv_sec = lock_ring_copy[j].tv.tv_sec;
- lasttv.tv_usec = lock_ring_copy[j].tv.tv_usec;
- if (!lock_ring_copy[j].tv.tv_sec) continue;
- if (lock_ring_copy[j].line < 0)
- {
- ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] UNLOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
- i - 31,-lock_ring_copy[j].line,lock_ring_copy[j].rpt->name,(int) lock_ring_copy[j].lockthread.id,diff,a,(int)lock_ring_copy[j].tv.tv_usec);
- }
- else
- {
- ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] LOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
- i - 31,lock_ring_copy[j].line,lock_ring_copy[j].rpt->name,(int) lock_ring_copy[j].lockthread.id,diff,a,(int)lock_ring_copy[j].tv.tv_usec);
- }
- }
-}
-
-
-static void _rpt_mutex_lock(ast_mutex_t *lockp, struct rpt *myrpt, int line)
-{
-struct lockthread *t;
-pthread_t id;
-
- id = pthread_self();
- ast_mutex_lock(&locklock);
- t = put_lockthread(id);
- if (!t)
- {
- ast_mutex_unlock(&locklock);
- return;
- }
- if (t->lockcount)
- {
- int lastline = t->lastlock;
- ast_mutex_unlock(&locklock);
- ast_log(LOG_NOTICE,"rpt_mutex_lock: Double lock request line %d node %s pid %x, last lock was line %d\n",line,myrpt->name,(int) t->id,lastline);
- rpt_mutex_spew();
- return;
- }
- t->lastlock = line;
- t->lockcount = 1;
- gettimeofday(&lock_ring[lock_ring_index].tv, NULL);
- lock_ring[lock_ring_index].rpt = myrpt;
- memcpy(&lock_ring[lock_ring_index].lockthread,t,sizeof(struct lockthread));
- lock_ring[lock_ring_index++].line = line;
- if(lock_ring_index == 32)
- lock_ring_index = 0;
- ast_mutex_unlock(&locklock);
- ast_mutex_lock(lockp);
-}
-
-
-static void _rpt_mutex_unlock(ast_mutex_t *lockp, struct rpt *myrpt, int line)
-{
-struct lockthread *t;
-pthread_t id;
-
- id = pthread_self();
- ast_mutex_lock(&locklock);
- t = put_lockthread(id);
- if (!t)
- {
- ast_mutex_unlock(&locklock);
- return;
- }
- if (!t->lockcount)
- {
- int lastline = t->lastunlock;
- ast_mutex_unlock(&locklock);
- ast_log(LOG_NOTICE,"rpt_mutex_lock: Double un-lock request line %d node %s pid %x, last un-lock was line %d\n",line,myrpt->name,(int) t->id,lastline);
- rpt_mutex_spew();
- return;
- }
- t->lastunlock = line;
- t->lockcount = 0;
- gettimeofday(&lock_ring[lock_ring_index].tv, NULL);
- lock_ring[lock_ring_index].rpt = myrpt;
- memcpy(&lock_ring[lock_ring_index].lockthread,t,sizeof(struct lockthread));
- lock_ring[lock_ring_index++].line = -line;
- if(lock_ring_index == 32)
- lock_ring_index = 0;
- ast_mutex_unlock(&locklock);
- ast_mutex_unlock(lockp);
-}
-
-#else /* APP_RPT_LOCK_DEBUG */
-
-#define rpt_mutex_lock(x) ast_mutex_lock(x)
-#define rpt_mutex_unlock(x) ast_mutex_unlock(x)
-
-#endif /* APP_RPT_LOCK_DEBUG */
-
-/*
-* Return 1 if rig is multimode capable
-*/
-
-static int multimode_capable(struct rpt *myrpt)
-{
- if(!strcmp(myrpt->remote, remote_rig_ft897))
- return 1;
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- return 1;
- return 0;
-}
-
-/*
-* CLI extensions
-*/
-
-/* Debug mode */
-static int rpt_do_debug(int fd, int argc, char *argv[]);
-static int rpt_do_dump(int fd, int argc, char *argv[]);
-static int rpt_do_stats(int fd, int argc, char *argv[]);
-static int rpt_do_lstats(int fd, int argc, char *argv[]);
-static int rpt_do_nodes(int fd, int argc, char *argv[]);
-static int rpt_do_reload(int fd, int argc, char *argv[]);
-static int rpt_do_restart(int fd, int argc, char *argv[]);
-static int rpt_do_fun(int fd, int argc, char *argv[]);
-
-static char debug_usage[] =
-"Usage: rpt debug level {0-7}\n"
-" Enables debug messages in app_rpt\n";
-
-static char dump_usage[] =
-"Usage: rpt dump <nodename>\n"
-" Dumps struct debug info to log\n";
-
-static char dump_stats[] =
-"Usage: rpt stats <nodename>\n"
-" Dumps node statistics to console\n";
-
-static char dump_lstats[] =
-"Usage: rpt lstats <nodename>\n"
-" Dumps link statistics to console\n";
-
-static char dump_nodes[] =
-"Usage: rpt nodes <nodename>\n"
-" Dumps a list of directly and indirectly connected nodes to the console\n";
-
-static char reload_usage[] =
-"Usage: rpt reload\n"
-" Reloads app_rpt running config parameters\n";
-
-static char restart_usage[] =
-"Usage: rpt restart\n"
-" Restarts app_rpt\n";
-
-static char fun_usage[] =
-"Usage: rpt fun <nodename> <command>\n"
-" Send a DTMF function to a node\n";
-
-
-static struct ast_cli_entry cli_debug =
- { { "rpt", "debug", "level" }, rpt_do_debug,
- "Enable app_rpt debugging", debug_usage };
-
-static struct ast_cli_entry cli_dump =
- { { "rpt", "dump" }, rpt_do_dump,
- "Dump app_rpt structs for debugging", dump_usage };
-
-static struct ast_cli_entry cli_stats =
- { { "rpt", "stats" }, rpt_do_stats,
- "Dump node statistics", dump_stats };
-
-static struct ast_cli_entry cli_nodes =
- { { "rpt", "nodes" }, rpt_do_nodes,
- "Dump node list", dump_nodes };
-
-static struct ast_cli_entry cli_lstats =
- { { "rpt", "lstats" }, rpt_do_lstats,
- "Dump link statistics", dump_lstats };
-
-static struct ast_cli_entry cli_reload =
- { { "rpt", "reload" }, rpt_do_reload,
- "Reload app_rpt config", reload_usage };
-
-static struct ast_cli_entry cli_restart =
- { { "rpt", "restart" }, rpt_do_restart,
- "Restart app_rpt", restart_usage };
-
-static struct ast_cli_entry cli_fun =
- { { "rpt", "fun" }, rpt_do_fun,
- "Execute a DTMF function", fun_usage };
-
-/*
-* Telemetry defaults
-*/
-
-
-static struct telem_defaults tele_defs[] = {
- {"ct1","|t(350,0,100,3072)(500,0,100,3072)(660,0,100,3072)"},
- {"ct2","|t(660,880,150,3072)"},
- {"ct3","|t(440,0,150,3072)"},
- {"ct4","|t(550,0,150,3072)"},
- {"ct5","|t(660,0,150,3072)"},
- {"ct6","|t(880,0,150,3072)"},
- {"ct7","|t(660,440,150,3072)"},
- {"ct8","|t(700,1100,150,3072)"},
- {"remotemon","|t(1600,0,75,2048)"},
- {"remotetx","|t(2000,0,75,2048)(0,0,75,0)(1600,0,75,2048)"},
- {"cmdmode","|t(900,904,200,2048)"},
- {"functcomplete","|t(1000,0,100,2048)(0,0,100,0)(1000,0,100,2048)"}
-} ;
-
-/*
-* Forward decl's - these suppress compiler warnings when funcs coded further down the file than thier invokation
-*/
-
-static int setrbi(struct rpt *myrpt);
-static int set_ft897(struct rpt *myrpt);
-static int set_ic706(struct rpt *myrpt);
-static int setkenwood(struct rpt *myrpt);
-static int setrbi_check(struct rpt *myrpt);
-
-
-
-/*
-* Define function protos for function table here
-*/
-
-static int function_ilink(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-static int function_autopatchup(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-static int function_autopatchdn(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-static int function_macro(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
-/*
-* Function table
-*/
-
-static struct function_table_tag function_table[] = {
- {"cop", function_cop},
- {"autopatchup", function_autopatchup},
- {"autopatchdn", function_autopatchdn},
- {"ilink", function_ilink},
- {"status", function_status},
- {"remote", function_remote},
- {"macro", function_macro}
-} ;
-
-static long diskavail(struct rpt *myrpt)
-{
-struct statfs statfsbuf;
-
- if (!myrpt->p.archivedir) return(0);
- if (statfs(myrpt->p.archivedir,&statfsbuf) == -1)
- {
- ast_log(LOG_WARNING,"Cannot get filesystem size for %s node %s\n",
- myrpt->p.archivedir,myrpt->name);
- return(-1);
- }
- return(statfsbuf.f_bavail);
-}
-
-static void do_dtmf_phone(struct rpt *myrpt, struct rpt_link *mylink, char c)
-{
-struct rpt_link *l;
-
- l = myrpt->links.next;
- /* go thru all the links */
- while(l != &myrpt->links)
- {
- if (!l->phonemode)
- {
- l = l->next;
- continue;
- }
- /* dont send to self */
- if (mylink && (l == mylink))
- {
- l = l->next;
- continue;
- }
- if (l->chan) ast_senddigit(l->chan,c);
- l = l->next;
- }
- return;
-}
-
-/* node logging function */
-static void donodelog(struct rpt *myrpt,char *str)
-{
-struct nodelog *nodep;
-char datestr[100];
-
- if (!myrpt->p.archivedir) return;
- nodep = (struct nodelog *)malloc(sizeof(struct nodelog));
- if (nodep == NULL)
- {
- ast_log(LOG_ERROR,"Cannot get memory for node log");
- return;
- }
- time(&nodep->timestamp);
- strncpy(nodep->archivedir,myrpt->p.archivedir,
- sizeof(nodep->archivedir) - 1);
- strftime(datestr,sizeof(datestr) - 1,"%Y%m%d%H%M%S",
- localtime(&nodep->timestamp));
- snprintf(nodep->str,sizeof(nodep->str) - 1,"%s %s,%s\n",
- myrpt->name,datestr,str);
- ast_mutex_lock(&nodeloglock);
- insque((struct qelem *) nodep, (struct qelem *) nodelog.prev);
- ast_mutex_unlock(&nodeloglock);
-}
-
-/* must be called locked */
-static void do_dtmf_local(struct rpt *myrpt, char c)
-{
-int i;
-char digit;
-static const char* dtmf_tones[] = {
- "!941+1336/200,!0/200", /* 0 */
- "!697+1209/200,!0/200", /* 1 */
- "!697+1336/200,!0/200", /* 2 */
- "!697+1477/200,!0/200", /* 3 */
- "!770+1209/200,!0/200", /* 4 */
- "!770+1336/200,!0/200", /* 5 */
- "!770+1477/200,!0/200", /* 6 */
- "!852+1209/200,!0/200", /* 7 */
- "!852+1336/200,!0/200", /* 8 */
- "!852+1477/200,!0/200", /* 9 */
- "!697+1633/200,!0/200", /* A */
- "!770+1633/200,!0/200", /* B */
- "!852+1633/200,!0/200", /* C */
- "!941+1633/200,!0/200", /* D */
- "!941+1209/200,!0/200", /* * */
- "!941+1477/200,!0/200" }; /* # */
-
-
- if (c)
- {
- snprintf(myrpt->dtmf_local_str + strlen(myrpt->dtmf_local_str),sizeof(myrpt->dtmf_local_str) - 1,"%c",c);
- if (!myrpt->dtmf_local_timer)
- myrpt->dtmf_local_timer = DTMF_LOCAL_STARTTIME;
- }
- /* if at timeout */
- if (myrpt->dtmf_local_timer == 1)
- {
- /* if anything in the string */
- if (myrpt->dtmf_local_str[0])
- {
- digit = myrpt->dtmf_local_str[0];
- myrpt->dtmf_local_str[0] = 0;
- for(i = 1; myrpt->dtmf_local_str[i]; i++)
- {
- myrpt->dtmf_local_str[i - 1] =
- myrpt->dtmf_local_str[i];
- }
- myrpt->dtmf_local_str[i - 1] = 0;
- myrpt->dtmf_local_timer = DTMF_LOCAL_TIME;
- rpt_mutex_unlock(&myrpt->lock);
- if (digit >= '0' && digit <='9')
- ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'0'], 0);
- else if (digit >= 'A' && digit <= 'D')
- ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'A'+10], 0);
- else if (digit == '*')
- ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[14], 0);
- else if (digit == '#')
- ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[15], 0);
- else {
- /* not handled */
- ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, myrpt->txchannel->name);
- }
- rpt_mutex_lock(&myrpt->lock);
- }
- else
- {
- myrpt->dtmf_local_timer = 0;
- }
- }
-}
-
-static int openserial(char *fname)
-{
- struct termios mode;
- int fd;
-
- fd = open(fname,O_RDWR);
- if (fd == -1)
- {
- ast_log(LOG_WARNING,"Cannot open serial port %s\n",fname);
- return -1;
- }
- memset(&mode, 0, sizeof(mode));
- if (tcgetattr(fd, &mode)) {
- ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", fname, strerror(errno));
- return -1;
- }
-#ifndef SOLARIS
- cfmakeraw(&mode);
-#else
- mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- mode.c_oflag &= ~OPOST;
- mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- mode.c_cflag &= ~(CSIZE|PARENB|CRTSCTS);
- mode.c_cflag |= CS8;
- mode.c_cc[TIME] = 3;
- mode.c_cc[MAX] = 1;
-#endif
-
- cfsetispeed(&mode, B9600);
- cfsetospeed(&mode, B9600);
- if (tcsetattr(fd, TCSANOW, &mode))
- ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno));
- return(fd);
-}
-
-static void mdc1200_notify(struct rpt *myrpt,char *fromnode, unsigned int unit)
-{
- if (!fromnode)
- {
- ast_verbose("Got MDC-1200 ID %04X from local system (%s)\n",
- unit,myrpt->name);
- }
- else
- {
- ast_verbose("Got MDC-1200 ID %04X from node %s (%s)\n",
- unit,fromnode,myrpt->name);
- }
-}
-
-#ifdef _MDC_DECODE_H_
-
-static void mdc1200_send(struct rpt *myrpt, unsigned int unit)
-{
-struct rpt_link *l;
-struct ast_frame wf;
-char str[200];
-
-
- sprintf(str,"I %s %04X",myrpt->name,unit);
-
- wf.frametype = AST_FRAME_TEXT;
- wf.subclass = 0;
- wf.offset = 0;
- wf.mallocd = 0;
- wf.datalen = strlen(str) + 1;
- wf.samples = 0;
-
-
- l = myrpt->links.next;
- /* otherwise, send it to all of em */
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- wf.data = str;
- if (l->chan) ast_write(l->chan,&wf);
- l = l->next;
- }
- return;
-}
-
-#endif
-
-static char func_xlat(struct rpt *myrpt,char c,struct rpt_xlat *xlat)
-{
-time_t now;
-int gotone;
-
- time(&now);
- gotone = 0;
- /* if too much time, reset the skate machine */
- if ((now - xlat->lastone) > MAXXLATTIME)
- {
- xlat->funcindex = xlat->endindex = 0;
- }
- if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++]))
- {
- time(&xlat->lastone);
- gotone = 1;
- if (!xlat->funccharseq[xlat->funcindex])
- {
- xlat->funcindex = xlat->endindex = 0;
- return(myrpt->p.funcchar);
- }
- } else xlat->funcindex = 0;
- if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++]))
- {
- time(&xlat->lastone);
- gotone = 1;
- if (!xlat->endcharseq[xlat->endindex])
- {
- xlat->funcindex = xlat->endindex = 0;
- return(myrpt->p.endchar);
- }
- } else xlat->endindex = 0;
- /* if in middle of decode seq, send nothing back */
- if (gotone) return(0);
- /* if no pass chars specified, return em all */
- if (!xlat->passchars[0]) return(c);
- /* if a "pass char", pass it */
- if (strchr(xlat->passchars,c)) return(c);
- return(0);
-}
-
-/*
- * Return a pointer to the first non-whitespace character
- */
-
-static char *eatwhite(char *s)
-{
- while((*s == ' ') || (*s == 0x09)){ /* get rid of any leading white space */
- if(!*s)
- break;
- s++;
- }
- return s;
-}
-
-/*
-* Break up a delimited string into a table of substrings
-*
-* str - delimited string ( will be modified )
-* strp- list of pointers to substrings (this is built by this function), NULL will be placed at end of list
-* limit- maximum number of substrings to process
-*/
-
-
-
-static int finddelim(char *str, char *strp[], int limit)
-{
-int i,l,inquo;
-
- inquo = 0;
- i = 0;
- strp[i++] = str;
- if (!*str)
- {
- strp[0] = 0;
- return(0);
- }
- for(l = 0; *str && (l < limit) ; str++)
- {
- if (*str == QUOTECHR)
- {
- if (inquo)
- {
- *str = 0;
- inquo = 0;
- }
- else
- {
- strp[i - 1] = str + 1;
- inquo = 1;
- }
- }
- if ((*str == DELIMCHR) && (!inquo))
- {
- *str = 0;
- l++;
- strp[i++] = str + 1;
- }
- }
- strp[i] = 0;
- return(i);
-
-}
-
-/* must be called locked */
-static void __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf)
-{
-struct rpt_link *l;
-char mode;
-int i,spos;
-
- buf[0] = 0; /* clear output buffer */
- /* go thru all links */
- for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
- {
- /* if is not a real link, ignore it */
- if (l->name[0] == '0') continue;
- /* dont count our stuff */
- if (l == mylink) continue;
- if (mylink && (!strcmp(l->name,mylink->name))) continue;
- /* figure out mode to report */
- mode = 'T'; /* use Tranceive by default */
- if (!l->mode) mode = 'R'; /* indicate RX for our mode */
- if (!l->thisconnected) mode = 'C'; /* indicate connecting */
- spos = strlen(buf); /* current buf size (b4 we add our stuff) */
- if (spos)
- {
- strcat(buf,",");
- spos++;
- }
- /* add nodes into buffer */
- if (l->linklist[0])
- {
- snprintf(buf + spos,MAXLINKLIST - spos,
- "%c%s,%s",mode,l->name,l->linklist);
- }
- else /* if no nodes, add this node into buffer */
- {
- snprintf(buf + spos,MAXLINKLIST - spos,
- "%c%s",mode,l->name);
- }
- /* if we are in tranceive mode, let all modes stand */
- if (mode == 'T') continue;
- /* downgrade everyone on this node if appropriate */
- for(i = spos; buf[i]; i++)
- {
- if (buf[i] == 'T') buf[i] = mode;
- if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode;
- }
- }
- return;
-}
-
-/* must be called locked */
-static void __kickshort(struct rpt *myrpt)
-{
-struct rpt_link *l;
-
- for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
- {
- /* if is not a real link, ignore it */
- if (l->name[0] == '0') continue;
- l->linklisttimer = LINKLISTSHORTTIME;
- }
- return;
-}
-
-static char *node_lookup(struct rpt *myrpt,char *digitbuf)
-{
-
-char *val;
-int longestnode,j;
-struct stat mystat;
-static time_t last = 0;
-static struct ast_config *ourcfg = NULL;
-struct ast_variable *vp;
-
- /* try to look it up locally first */
- val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf);
- if (val) return(val);
- ast_mutex_lock(&nodelookuplock);
- /* if file does not exist */
- if (stat(myrpt->p.extnodefile,&mystat) == -1)
- {
- if (ourcfg) ast_config_destroy(ourcfg);
- ourcfg = NULL;
- ast_mutex_unlock(&nodelookuplock);
- return(NULL);
- }
- /* if we need to reload */
- if (mystat.st_mtime > last)
- {
- if (ourcfg) ast_config_destroy(ourcfg);
- ourcfg = ast_config_load(myrpt->p.extnodefile);
- /* if file not there, just bail */
- if (!ourcfg)
- {
- ast_mutex_unlock(&nodelookuplock);
- return(NULL);
- }
- /* reset "last" time */
- last = mystat.st_mtime;
-
- /* determine longest node length again */
- longestnode = 0;
- vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes);
- while(vp){
- j = strlen(vp->name);
- if (j > longestnode)
- longestnode = j;
- vp = vp->next;
- }
-
- vp = ast_variable_browse(ourcfg, myrpt->p.extnodes);
- while(vp){
- j = strlen(vp->name);
- if (j > longestnode)
- longestnode = j;
- vp = vp->next;
- }
-
- myrpt->longestnode = longestnode;
- }
- val = NULL;
- if (ourcfg)
- val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf);
- ast_mutex_unlock(&nodelookuplock);
- return(val);
-}
-
-/*
-* Match a keyword in a list, and return index of string plus 1 if there was a match,* else return 0.
-* If param is passed in non-null, then it will be set to the first character past the match
-*/
-
-static int matchkeyword(char *string, char **param, char *keywords[])
-{
-int i,ls;
- for( i = 0 ; keywords[i] ; i++){
- ls = strlen(keywords[i]);
- if(!ls){
- *param = NULL;
- return 0;
- }
- if(!strncmp(string, keywords[i], ls)){
- if(param)
- *param = string + ls;
- return i + 1;
- }
- }
- param = NULL;
- return 0;
-}
-
-/*
-* Skip characters in string which are in charlist, and return a pointer to the
-* first non-matching character
-*/
-
-static char *skipchars(char *string, char *charlist)
-{
-int i;
- while(*string){
- for(i = 0; charlist[i] ; i++){
- if(*string == charlist[i]){
- string++;
- break;
- }
- }
- if(!charlist[i])
- return string;
- }
- return string;
-}
-
-
-
-static int myatoi(char *str)
-{
-int ret;
-
- if (str == NULL) return -1;
- /* leave this %i alone, non-base-10 input is useful here */
- if (sscanf(str,"%i",&ret) != 1) return -1;
- return ret;
-}
-
-static int mycompar(const void *a, const void *b)
-{
-char **x = (char **) a;
-char **y = (char **) b;
-int xoff,yoff;
-
- if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
- if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
- return(strcmp((*x) + xoff,(*y) + yoff));
-}
-
-#ifdef __RPT_NOTCH
-
-/* rpt filter routine */
-static void rpt_filter(struct rpt *myrpt, volatile short *buf, int len)
-{
-int i,j;
-struct rptfilter *f;
-
- for(i = 0; i < len; i++)
- {
- for(j = 0; j < MAXFILTERS; j++)
- {
- f = &myrpt->filters[j];
- if (!*f->desc) continue;
- f->x0 = f->x1; f->x1 = f->x2;
- f->x2 = ((float)buf[i]) / f->gain;
- f->y0 = f->y1; f->y1 = f->y2;
- f->y2 = (f->x0 + f->x2) + f->const0 * f->x1
- + (f->const1 * f->y0) + (f->const2 * f->y1);
- buf[i] = (short)f->y2;
- }
- }
-}
-
-#endif
-
-
-/*
- Get the time for the machine's time zone
- Note: Asterisk requires a copy of localtime
- in the /etc directory for this to work properly.
- If /etc/localtime is not present, you will get
- GMT time! This is especially important on systems
- running embedded linux distributions as they don't usually
- have support for locales.
-
- If OLD_ASTERISK is defined, then the older localtime_r
- function will be used. The /etc/localtime file is not
- required in this case. This provides backward compatibility
- with Asterisk 1.2 systems.
-
-*/
-
-static void rpt_localtime( time_t * t, struct tm *lt)
-{
-#ifdef OLD_ASTERISK
- localtime_r(t, lt);
-#else
- ast_localtime(t, lt, NULL);
-#endif
-}
-
-/* Retrieve an int from a config file */
-
-static int retrieve_astcfgint(struct rpt *myrpt,char *category, char *name, int min, int max, int defl)
-{
- char *var;
- int ret;
- char include_zero = 0;
-
- if(min < 0){ /* If min is negative, this means include 0 as a valid entry */
- min = -min;
- include_zero = 1;
- }
-
- var = (char *) ast_variable_retrieve(myrpt->cfg, category, name);
- if(var){
- ret = myatoi(var);
- if(include_zero && !ret)
- return 0;
- if(ret < min)
- ret = min;
- if(ret > max)
- ret = max;
- }
- else
- ret = defl;
- return ret;
-}
-
-
-static void load_rpt_vars(int n,int init)
-{
-char *this,*val;
-int i,j,longestnode;
-struct ast_variable *vp;
-struct ast_config *cfg;
-char *strs[100];
-char s1[256];
-static char *cs_keywords[] = {"rptena","rptdis","apena","apdis","lnkena","lnkdis","totena","totdis","skena","skdis",
- "ufena","ufdis","atena","atdis",NULL};
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n",
- (init) ? "Loading initial" : "Re-Loading",rpt_vars[n].name);
- ast_mutex_lock(&rpt_vars[n].lock);
- if (rpt_vars[n].cfg) ast_config_destroy(rpt_vars[n].cfg);
- cfg = ast_config_load("rpt.conf");
- if (!cfg) {
- ast_mutex_unlock(&rpt_vars[n].lock);
- ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n");
- pthread_exit(NULL);
- }
- rpt_vars[n].cfg = cfg;
- this = rpt_vars[n].name;
- memset(&rpt_vars[n].p,0,sizeof(rpt_vars[n].p));
- if (init)
- {
- /* clear all the fields in the structure after 'p' */
- memset(&rpt_vars[n].p + sizeof(rpt_vars[0].p), 0, sizeof(rpt_vars[0]) - sizeof(rpt_vars[0].p) - offsetof(typeof(rpt_vars[0]), p));
- rpt_vars[n].tele.next = &rpt_vars[n].tele;
- rpt_vars[n].tele.prev = &rpt_vars[n].tele;
- rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
- rpt_vars[n].tailmessagen = 0;
- }
-#ifdef __RPT_NOTCH
- /* zot out filters stuff */
- memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters));
-#endif
- val = (char *) ast_variable_retrieve(cfg,this,"context");
- if (val) rpt_vars[n].p.ourcontext = val;
- else rpt_vars[n].p.ourcontext = this;
- val = (char *) ast_variable_retrieve(cfg,this,"callerid");
- if (val) rpt_vars[n].p.ourcallerid = val;
- val = (char *) ast_variable_retrieve(cfg,this,"accountcode");
- if (val) rpt_vars[n].p.acctcode = val;
- val = (char *) ast_variable_retrieve(cfg,this,"idrecording");
- if (val) rpt_vars[n].p.ident = val;
- val = (char *) ast_variable_retrieve(cfg,this,"hangtime");
- if (val) rpt_vars[n].p.hangtime = atoi(val);
- else rpt_vars[n].p.hangtime = HANGTIME;
- val = (char *) ast_variable_retrieve(cfg,this,"althangtime");
- if (val) rpt_vars[n].p.althangtime = atoi(val);
- else rpt_vars[n].p.althangtime = HANGTIME;
- val = (char *) ast_variable_retrieve(cfg,this,"totime");
- if (val) rpt_vars[n].p.totime = atoi(val);
- else rpt_vars[n].p.totime = TOTIME;
- rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0);
- rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0);
- rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2);
- rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME); /* Enforce a min max including zero */
- rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */
- val = (char *) ast_variable_retrieve(cfg,this,"tonezone");
- if (val) rpt_vars[n].p.tonezone = val;
- rpt_vars[n].p.tailmessages[0] = 0;
- rpt_vars[n].p.tailmessagemax = 0;
- val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist");
- if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500);
- val = (char *) ast_variable_retrieve(cfg,this,"memory");
- if (!val) val = MEMORY;
- rpt_vars[n].p.memory = val;
- val = (char *) ast_variable_retrieve(cfg,this,"macro");
- if (!val) val = MACRO;
- rpt_vars[n].p.macro = val;
- val = (char *) ast_variable_retrieve(cfg,this,"startup_macro");
- if (val) rpt_vars[n].p.startupmacro = val;
- val = (char *) ast_variable_retrieve(cfg,this,"iobase");
- /* do not use atoi() here, we need to be able to have
- the input specified in hex or decimal so we use
- sscanf with a %i */
- if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1))
- rpt_vars[n].p.iobase = DEFAULT_IOBASE;
- val = (char *) ast_variable_retrieve(cfg,this,"ioport");
- rpt_vars[n].p.ioport = val;
- val = (char *) ast_variable_retrieve(cfg,this,"functions");
- if (!val)
- {
- val = FUNCTIONS;
- rpt_vars[n].p.simple = 1;
- }
- rpt_vars[n].p.functions = val;
- val = (char *) ast_variable_retrieve(cfg,this,"link_functions");
- if (val) rpt_vars[n].p.link_functions = val;
- else
- rpt_vars[n].p.link_functions = rpt_vars[n].p.functions;
- val = (char *) ast_variable_retrieve(cfg,this,"phone_functions");
- if (val) rpt_vars[n].p.phone_functions = val;
- val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions");
- if (val) rpt_vars[n].p.dphone_functions = val;
- val = (char *) ast_variable_retrieve(cfg,this,"funcchar");
- if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else
- rpt_vars[n].p.funcchar = *val;
- val = (char *) ast_variable_retrieve(cfg,this,"endchar");
- if (!val) rpt_vars[n].p.endchar = ENDCHAR; else
- rpt_vars[n].p.endchar = *val;
- val = (char *) ast_variable_retrieve(cfg,this,"nobusyout");
- if (val) rpt_vars[n].p.nobusyout = ast_true(val);
- val = (char *) ast_variable_retrieve(cfg,this,"notelemtx");
- if (val) rpt_vars[n].p.notelemtx = ast_true(val);
- val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf");
- if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val);
- val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf");
- if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val);
- val = (char *) ast_variable_retrieve(cfg,this,"linktolink");
- if (val) rpt_vars[n].p.linktolink = ast_true(val);
- val = (char *) ast_variable_retrieve(cfg,this,"nodes");
- if (!val) val = NODES;
- rpt_vars[n].p.nodes = val;
- val = (char *) ast_variable_retrieve(cfg,this,"extnodes");
- if (!val) val = EXTNODES;
- rpt_vars[n].p.extnodes = val;
- val = (char *) ast_variable_retrieve(cfg,this,"extnodefile");
- if (!val) val = EXTNODEFILE;
- rpt_vars[n].p.extnodefile = val;
- val = (char *) ast_variable_retrieve(cfg,this,"archivedir");
- if (val) rpt_vars[n].p.archivedir = val;
- val = (char *) ast_variable_retrieve(cfg,this,"authlevel");
- if (val) rpt_vars[n].p.authlevel = atoi(val);
- else rpt_vars[n].p.authlevel = 0;
- val = (char *) ast_variable_retrieve(cfg,this,"monminblocks");
- if (val) rpt_vars[n].p.monminblocks = atol(val);
- else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS;
- val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout");
- if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val);
- else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT;
- val = (char *) ast_variable_retrieve(cfg,this,"civaddr");
- if (val) rpt_vars[n].p.civaddr = atoi(val);
- else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR;
- val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout");
- if (val) rpt_vars[n].p.remotetimeout = atoi(val);
- else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT;
- val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning");
- if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val);
- else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING;
- val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq");
- if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val);
- else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ;
-#ifdef __RPT_NOTCH
- val = (char *) ast_variable_retrieve(cfg,this,"rxnotch");
- if (val) {
- i = finddelim(val,strs,MAXFILTERS * 2);
- i &= ~1; /* force an even number, rounded down */
- if (i >= 2) for(j = 0; j < i; j += 2)
- {
- rpt_mknotch(atof(strs[j]),atof(strs[j + 1]),
- &rpt_vars[n].filters[j >> 1].gain,
- &rpt_vars[n].filters[j >> 1].const0,
- &rpt_vars[n].filters[j >> 1].const1,
- &rpt_vars[n].filters[j >> 1].const2);
- sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s",
- strs[j],strs[j + 1]);
- }
-
- }
-#endif
- val = (char *) ast_variable_retrieve(cfg,this,"inxlat");
- if (val) {
- memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat));
- i = finddelim(val,strs,3);
- if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1);
- if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1);
- if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1);
- }
- val = (char *) ast_variable_retrieve(cfg,this,"outxlat");
- if (val) {
- memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat));
- i = finddelim(val,strs,3);
- if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1);
- if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1);
- if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1);
- }
- /* retreive the stanza name for the control states if there is one */
- val = (char *) ast_variable_retrieve(cfg,this,"controlstates");
- rpt_vars[n].p.csstanzaname = val;
-
- /* retreive the stanza name for the scheduler if there is one */
- val = (char *) ast_variable_retrieve(cfg,this,"scheduler");
- rpt_vars[n].p.skedstanzaname = val;
-
- /* retreive the stanza name for the txlimits */
- val = (char *) ast_variable_retrieve(cfg,this,"txlimits");
- rpt_vars[n].p.txlimitsstanzaname = val;
-
- longestnode = 0;
-
- vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes);
-
- while(vp){
- j = strlen(vp->name);
- if (j > longestnode)
- longestnode = j;
- vp = vp->next;
- }
-
- rpt_vars[n].longestnode = longestnode;
-
- /*
- * For this repeater, Determine the length of the longest function
- */
- rpt_vars[n].longestfunc = 0;
- vp = ast_variable_browse(cfg, rpt_vars[n].p.functions);
- while(vp){
- j = strlen(vp->name);
- if (j > rpt_vars[n].longestfunc)
- rpt_vars[n].longestfunc = j;
- vp = vp->next;
- }
- /*
- * For this repeater, Determine the length of the longest function
- */
- rpt_vars[n].link_longestfunc = 0;
- vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions);
- while(vp){
- j = strlen(vp->name);
- if (j > rpt_vars[n].link_longestfunc)
- rpt_vars[n].link_longestfunc = j;
- vp = vp->next;
- }
- rpt_vars[n].phone_longestfunc = 0;
- if (rpt_vars[n].p.phone_functions)
- {
- vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions);
- while(vp){
- j = strlen(vp->name);
- if (j > rpt_vars[n].phone_longestfunc)
- rpt_vars[n].phone_longestfunc = j;
- vp = vp->next;
- }
- }
- rpt_vars[n].dphone_longestfunc = 0;
- if (rpt_vars[n].p.dphone_functions)
- {
- vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions);
- while(vp){
- j = strlen(vp->name);
- if (j > rpt_vars[n].dphone_longestfunc)
- rpt_vars[n].dphone_longestfunc = j;
- vp = vp->next;
- }
- }
- rpt_vars[n].macro_longest = 1;
- vp = ast_variable_browse(cfg, rpt_vars[n].p.macro);
- while(vp){
- j = strlen(vp->name);
- if (j > rpt_vars[n].macro_longest)
- rpt_vars[n].macro_longest = j;
- vp = vp->next;
- }
-
- /* Browse for control states */
- if(rpt_vars[n].p.csstanzaname)
- vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname);
- else
- vp = NULL;
- for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */
- int k,nukw,statenum;
- statenum=atoi(vp->name);
- strncpy(s1, vp->value, 255);
- s1[255] = 0;
- nukw = finddelim(s1,strs,32);
-
- for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */
- for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */
- if(!strcmp(strs[k],cs_keywords[j])){
- switch(j){
- case 0: /* rptena */
- rpt_vars[n].p.s[statenum].txdisable = 0;
- break;
- case 1: /* rptdis */
- rpt_vars[n].p.s[statenum].txdisable = 1;
- break;
-
- case 2: /* apena */
- rpt_vars[n].p.s[statenum].autopatchdisable = 0;
- break;
-
- case 3: /* apdis */
- rpt_vars[n].p.s[statenum].autopatchdisable = 1;
- break;
-
- case 4: /* lnkena */
- rpt_vars[n].p.s[statenum].linkfundisable = 0;
- break;
-
- case 5: /* lnkdis */
- rpt_vars[n].p.s[statenum].linkfundisable = 1;
- break;
-
- case 6: /* totena */
- rpt_vars[n].p.s[statenum].totdisable = 0;
- break;
-
- case 7: /* totdis */
- rpt_vars[n].p.s[statenum].totdisable = 1;
- break;
-
- case 8: /* skena */
- rpt_vars[n].p.s[statenum].schedulerdisable = 0;
- break;
-
- case 9: /* skdis */
- rpt_vars[n].p.s[statenum].schedulerdisable = 1;
- break;
-
- case 10: /* ufena */
- rpt_vars[n].p.s[statenum].userfundisable = 0;
- break;
-
- case 11: /* ufdis */
- rpt_vars[n].p.s[statenum].userfundisable = 1;
- break;
-
- case 12: /* atena */
- rpt_vars[n].p.s[statenum].alternatetail = 1;
- break;
-
- case 13: /* atdis */
- rpt_vars[n].p.s[statenum].alternatetail = 0;
- break;
-
- default:
- ast_log(LOG_WARNING,
- "Unhandled control state keyword %s", cs_keywords[i]);
- break;
- }
- }
- }
- }
- vp = vp->next;
- }
- ast_mutex_unlock(&rpt_vars[n].lock);
-}
-
-/*
-* Enable or disable debug output at a given level at the console
-*/
-
-static int rpt_do_debug(int fd, int argc, char *argv[])
-{
- int newlevel;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- newlevel = myatoi(argv[3]);
- if((newlevel < 0) || (newlevel > 7))
- return RESULT_SHOWUSAGE;
- if(newlevel)
- ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
- else
- ast_cli(fd, "app_rpt Debugging disabled\n");
-
- debug = newlevel;
- return RESULT_SUCCESS;
-}
-
-/*
-* Dump rpt struct debugging onto console
-*/
-
-static int rpt_do_dump(int fd, int argc, char *argv[])
-{
- int i;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- for(i = 0; i < nrpts; i++)
- {
- if (!strcmp(argv[2],rpt_vars[i].name))
- {
- rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
- ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
- return RESULT_SUCCESS;
- }
- }
- return RESULT_FAILURE;
-}
-
-/*
-* Dump statistics onto console
-*/
-
-static int rpt_do_stats(int fd, int argc, char *argv[])
-{
- int i,j;
- int dailytxtime, dailykerchunks;
- int totalkerchunks, dailykeyups, totalkeyups, timeouts;
- int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds;
- long long totaltxtime;
- struct rpt_link *l;
- char *listoflinks[MAX_STAT_LINKS];
- char *lastnodewhichkeyedusup, *lastdtmfcommand;
- char *tot_state, *ider_state, *patch_state;
- char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena;
- char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type;
- struct rpt *myrpt;
-
- static char *not_applicable = "N/A";
-
- if(argc != 3)
- return RESULT_SHOWUSAGE;
-
- for(i = 0 ; i < MAX_STAT_LINKS; i++)
- listoflinks[i] = NULL;
-
- tot_state = ider_state =
- patch_state = reverse_patch_state =
- input_signal = called_number =
- lastdtmfcommand = not_applicable;
-
- for(i = 0; i < nrpts; i++)
- {
- if (!strcmp(argv[2],rpt_vars[i].name)){
- /* Make a copy of all stat variables while locked */
- myrpt = &rpt_vars[i];
- rpt_mutex_lock(&myrpt->lock); /* LOCK */
-
- dailytxtime = myrpt->dailytxtime;
- totaltxtime = myrpt->totaltxtime;
- dailykeyups = myrpt->dailykeyups;
- totalkeyups = myrpt->totalkeyups;
- dailykerchunks = myrpt->dailykerchunks;
- totalkerchunks = myrpt->totalkerchunks;
- dailyexecdcommands = myrpt->dailyexecdcommands;
- totalexecdcommands = myrpt->totalexecdcommands;
- timeouts = myrpt->timeouts;
-
- /* Traverse the list of connected nodes */
- reverse_patch_state = "DOWN";
- j = 0;
- l = myrpt->links.next;
- while(l && (l != &myrpt->links)){
- if (l->name[0] == '0'){ /* Skip '0' nodes */
- reverse_patch_state = "UP";
- l = l->next;
- continue;
- }
- listoflinks[j] = ast_strdupa(l->name);
- if(listoflinks[j])
- j++;
- l = l->next;
- }
-
- lastnodewhichkeyedusup = ast_strdupa(myrpt->lastnodewhichkeyedusup);
- if((!lastnodewhichkeyedusup) || (!strlen(lastnodewhichkeyedusup)))
- lastnodewhichkeyedusup = not_applicable;
-
- if(myrpt->keyed)
- input_signal = "YES";
- else
- input_signal = "NO";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable)
- sys_ena = "DISABLED";
- else
- sys_ena = "ENABLED";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable)
- tot_ena = "DISABLED";
- else
- tot_ena = "ENABLED";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable)
- link_ena = "DISABLED";
- else
- link_ena = "ENABLED";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
- patch_ena = "DISABLED";
- else
- patch_ena = "ENABLED";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable)
- sch_ena = "DISABLED";
- else
- sch_ena = "ENABLED";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)
- user_funs = "DISABLED";
- else
- user_funs = "ENABLED";
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail)
- tail_type = "ALTERNATE";
- else
- tail_type = "STANDARD";
-
- if(!myrpt->totimer)
- tot_state = "TIMED OUT!";
- else if(myrpt->totimer != myrpt->p.totime)
- tot_state = "ARMED";
- else
- tot_state = "RESET";
-
- if(myrpt->tailid)
- ider_state = "QUEUED IN TAIL";
- else if(myrpt->mustid)
- ider_state = "QUEUED FOR CLEANUP";
- else
- ider_state = "CLEAN";
-
- switch(myrpt->callmode){
- case 1:
- patch_state = "DIALING";
- break;
- case 2:
- patch_state = "CONNECTING";
- break;
- case 3:
- patch_state = "UP";
- break;
-
- case 4:
- patch_state = "CALL FAILED";
- break;
-
- default:
- patch_state = "DOWN";
- }
-
- if(strlen(myrpt->exten)){
- called_number = ast_strdupa(myrpt->exten);
- if(!called_number)
- called_number = not_applicable;
- }
-
- if(strlen(myrpt->lastdtmfcommand)){
- lastdtmfcommand = ast_strdupa(myrpt->lastdtmfcommand);
- if(!lastdtmfcommand)
- lastdtmfcommand = not_applicable;
- }
-
- rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
-
- ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name);
- ast_cli(fd, "Selected system state............................: %d\n", myrpt->p.sysstate_cur);
- ast_cli(fd, "Signal on input..................................: %s\n", input_signal);
- ast_cli(fd, "System...........................................: %s\n", sys_ena);
- ast_cli(fd, "Scheduler........................................: %s\n", sch_ena);
- ast_cli(fd, "Tail Time........................................: %s\n", tail_type);
- ast_cli(fd, "Time out timer...................................: %s\n", tot_ena);
- ast_cli(fd, "Time out timer state.............................: %s\n", tot_state);
- ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts);
- ast_cli(fd, "Identifier state.................................: %s\n", ider_state);
- ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks);
- ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks);
- ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups);
- ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups);
- ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands);
- ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands);
- ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand);
- hours = dailytxtime/3600000;
- dailytxtime %= 3600000;
- minutes = dailytxtime/60000;
- dailytxtime %= 60000;
- seconds = dailytxtime/1000;
- dailytxtime %= 1000;
-
- ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n",
- hours, minutes, seconds, dailytxtime);
-
- hours = (int) totaltxtime/3600000;
- totaltxtime %= 3600000;
- minutes = (int) totaltxtime/60000;
- totaltxtime %= 60000;
- seconds = (int) totaltxtime/1000;
- totaltxtime %= 1000;
-
- ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n",
- hours, minutes, seconds, (int) totaltxtime);
- ast_cli(fd, "Nodes currently connected to us..................: ");
- for(j = 0 ;; j++){
- if(!listoflinks[j]){
- if(!j){
- ast_cli(fd,"<NONE>");
- }
- break;
- }
- ast_cli(fd, "%s", listoflinks[j]);
- if(j % 4 == 3){
- ast_cli(fd, "\n");
- ast_cli(fd, " : ");
- }
- else{
- if(listoflinks[j + 1])
- ast_cli(fd, ", ");
- }
- }
- ast_cli(fd,"\n");
-
- ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup);
- ast_cli(fd, "Autopatch........................................: %s\n", patch_ena);
- ast_cli(fd, "Autopatch state..................................: %s\n", patch_state);
- ast_cli(fd, "Autopatch called number..........................: %s\n", called_number);
- ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n", reverse_patch_state);
- ast_cli(fd, "User linking commands............................: %s\n", link_ena);
- ast_cli(fd, "User functions...................................: %s\n\n", user_funs);
- return RESULT_SUCCESS;
- }
- }
- return RESULT_FAILURE;
-}
-
-/*
-* Link stats function
-*/
-
-static int rpt_do_lstats(int fd, int argc, char *argv[])
-{
- int i,j;
- char *connstate;
- struct rpt *myrpt;
- struct rpt_link *l;
- struct rpt_lstat *s,*t;
- struct rpt_lstat s_head;
- if(argc != 3)
- return RESULT_SHOWUSAGE;
-
- s = NULL;
- s_head.next = &s_head;
- s_head.prev = &s_head;
-
- for(i = 0; i < nrpts; i++)
- {
- if (!strcmp(argv[2],rpt_vars[i].name)){
- /* Make a copy of all stat variables while locked */
- myrpt = &rpt_vars[i];
- rpt_mutex_lock(&myrpt->lock); /* LOCK */
- /* Traverse the list of connected nodes */
- j = 0;
- l = myrpt->links.next;
- while(l && (l != &myrpt->links)){
- if (l->name[0] == '0'){ /* Skip '0' nodes */
- l = l->next;
- continue;
- }
- if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){
- ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n");
- rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
- return RESULT_FAILURE;
- }
- memset(s, 0, sizeof(struct rpt_lstat));
- strncpy(s->name, l->name, MAXREMSTR - 1);
- if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1);
- else strcpy(s->peer,"(none)");
- s->mode = l->mode;
- s->outbound = l->outbound;
- s->reconnects = l->reconnects;
- s->connecttime = l->connecttime;
- s->thisconnected = l->thisconnected;
- memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat));
- insque((struct qelem *) s, (struct qelem *) s_head.next);
- memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat));
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
- ast_cli(fd, "NODE PEER RECONNECTS DIRECTION CONNECT TIME CONNECT STATE\n");
- ast_cli(fd, "---- ---- ---------- --------- ------------ -------------\n");
-
- for(s = s_head.next; s != &s_head; s = s->next){
- int hours, minutes, seconds;
- long long connecttime = s->connecttime;
- char conntime[21];
- hours = (int) connecttime/3600000;
- connecttime %= 3600000;
- minutes = (int) connecttime/60000;
- connecttime %= 60000;
- seconds = (int) connecttime/1000;
- connecttime %= 1000;
- snprintf(conntime, 20, "%02d:%02d:%02d.%d",
- hours, minutes, seconds, (int) connecttime);
- conntime[20] = 0;
- if(s->thisconnected)
- connstate = "ESTABLISHED";
- else
- connstate = "CONNECTING";
- ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n",
- s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate);
- }
- /* destroy our local link queue */
- s = s_head.next;
- while(s != &s_head){
- t = s;
- s = s->next;
- remque((struct qelem *)t);
- free(t);
- }
- return RESULT_SUCCESS;
- }
- }
- return RESULT_FAILURE;
-}
-
-/*
-* List all nodes connected, directly or indirectly
-*/
-
-static int rpt_do_nodes(int fd, int argc, char *argv[])
-{
- int i,j;
- char ns;
- char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
- struct rpt *myrpt;
- if(argc != 3)
- return RESULT_SHOWUSAGE;
-
- for(i = 0; i < nrpts; i++)
- {
- if (!strcmp(argv[2],rpt_vars[i].name)){
- /* Make a copy of all stat variables while locked */
- myrpt = &rpt_vars[i];
- rpt_mutex_lock(&myrpt->lock); /* LOCK */
- __mklinklist(myrpt,NULL,lbuf);
- rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
- /* parse em */
- ns = finddelim(lbuf,strs,MAXLINKLIST);
- /* sort em */
- if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
- ast_cli(fd,"\n");
- ast_cli(fd, "************************* CONNECTED NODES *************************\n\n");
- for(j = 0 ;; j++){
- if(!strs[j]){
- if(!j){
- ast_cli(fd,"<NONE>");
- }
- break;
- }
- ast_cli(fd, "%s", strs[j]);
- if(j % 8 == 7){
- ast_cli(fd, "\n");
- }
- else{
- if(strs[j + 1])
- ast_cli(fd, ", ");
- }
- }
- ast_cli(fd,"\n\n");
- return RESULT_SUCCESS;
- }
- }
- return RESULT_FAILURE;
-}
-
-/*
-* reload vars
-*/
-
-static int rpt_do_reload(int fd, int argc, char *argv[])
-{
-int n;
-
- if (argc > 2) return RESULT_SHOWUSAGE;
-
- for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
-
- return RESULT_FAILURE;
-}
-
-/*
-* restart app_rpt
-*/
-
-static int rpt_do_restart(int fd, int argc, char *argv[])
-{
-int i;
-
- if (argc > 2) return RESULT_SHOWUSAGE;
- for(i = 0; i < nrpts; i++)
- {
- if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
- }
- return RESULT_FAILURE;
-}
-
-
-/*
-* send an app_rpt DTMF function from the CLI
-*/
-
-static int rpt_do_fun(int fd, int argc, char *argv[])
-{
- int i,busy=0;
-
- if (argc != 4) return RESULT_SHOWUSAGE;
-
- for(i = 0; i < nrpts; i++){
- if(!strcmp(argv[2], rpt_vars[i].name)){
- struct rpt *myrpt = &rpt_vars[i];
- rpt_mutex_lock(&myrpt->lock);
- if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){
- rpt_mutex_unlock(&myrpt->lock);
- busy=1;
- }
- if(!busy){
- myrpt->macrotimer = MACROTIME;
- strncat(myrpt->macrobuf, argv[3], MAXMACRO - strlen(myrpt->macrobuf) - 1);
- }
- rpt_mutex_unlock(&myrpt->lock);
- }
- }
- if(busy){
- ast_cli(fd, "Function decoder busy");
- }
- return RESULT_FAILURE;
-}
-
-
-
-static int play_tone_pair(struct ast_channel *chan, int f1, int f2, int duration, int amplitude)
-{
- int res;
-
- if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
- return res;
-
- while(chan->generatordata) {
- if (ast_safe_sleep(chan,1)) return -1;
- }
-
- return 0;
-}
-
-static int play_tone(struct ast_channel *chan, int freq, int duration, int amplitude)
-{
- return play_tone_pair(chan, freq, 0, duration, amplitude);
-}
-
-static int play_silence(struct ast_channel *chan, int duration)
-{
- return play_tone_pair(chan, 0, 0, duration, 0);
-}
-
-
-static int send_morse(struct ast_channel *chan, char *string, int speed, int freq, int amplitude)
-{
-
-static struct morse_bits mbits[] = {
- {0, 0}, /* SPACE */
- {0, 0},
- {6, 18},/* " */
- {0, 0},
- {7, 72},/* $ */
- {0, 0},
- {0, 0},
- {6, 30},/* ' */
- {5, 13},/* ( */
- {6, 29},/* ) */
- {0, 0},
- {5, 10},/* + */
- {6, 51},/* , */
- {6, 33},/* - */
- {6, 42},/* . */
- {5, 9}, /* / */
- {5, 31},/* 0 */
- {5, 30},/* 1 */
- {5, 28},/* 2 */
- {5, 24},/* 3 */
- {5, 16},/* 4 */
- {5, 0}, /* 5 */
- {5, 1}, /* 6 */
- {5, 3}, /* 7 */
- {5, 7}, /* 8 */
- {5, 15},/* 9 */
- {6, 7}, /* : */
- {6, 21},/* ; */
- {0, 0},
- {5, 33},/* = */
- {0, 0},
- {6, 12},/* ? */
- {0, 0},
- {2, 2}, /* A */
- {4, 1}, /* B */
- {4, 5}, /* C */
- {3, 1}, /* D */
- {1, 0}, /* E */
- {4, 4}, /* F */
- {3, 3}, /* G */
- {4, 0}, /* H */
- {2, 0}, /* I */
- {4, 14},/* J */
- {3, 5}, /* K */
- {4, 2}, /* L */
- {2, 3}, /* M */
- {2, 1}, /* N */
- {3, 7}, /* O */
- {4, 6}, /* P */
- {4, 11},/* Q */
- {3, 2}, /* R */
- {3, 0}, /* S */
- {1, 1}, /* T */
- {3, 4}, /* U */
- {4, 8}, /* V */
- {3, 6}, /* W */
- {4, 9}, /* X */
- {4, 13},/* Y */
- {4, 3} /* Z */
- };
-
-
- int dottime;
- int dashtime;
- int intralettertime;
- int interlettertime;
- int interwordtime;
- int len, ddcomb;
- int res;
- int c;
- int i;
- int flags;
-
- res = 0;
-
- /* Approximate the dot time from the speed arg. */
-
- dottime = 900/speed;
-
- /* Establish timing releationships */
-
- dashtime = 3 * dottime;
- intralettertime = dottime;
- interlettertime = dottime * 4 ;
- interwordtime = dottime * 7;
-
- for(;(*string) && (!res); string++){
-
- c = *string;
-
- /* Convert lower case to upper case */
-
- if((c >= 'a') && (c <= 'z'))
- c -= 0x20;
-
- /* Can't deal with any char code greater than Z, skip it */
-
- if(c > 'Z')
- continue;
-
- /* If space char, wait the inter word time */
-
- if(c == ' '){
- if(!res)
- res = play_silence(chan, interwordtime);
- continue;
- }
-
- /* Subtract out control char offset to match our table */
-
- c -= 0x20;
-
- /* Get the character data */
-
- len = mbits[c].len;
- ddcomb = mbits[c].ddcomb;
-
- /* Send the character */
-
- for(; len ; len--){
- if(!res)
- res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude);
- if(!res)
- res = play_silence(chan, intralettertime);
- ddcomb >>= 1;
- }
-
- /* Wait the interletter time */
-
- if(!res)
- res = play_silence(chan, interlettertime - intralettertime);
- }
-
- /* Wait for all the frames to be sent */
-
- if (!res)
- res = ast_waitstream(chan, "");
- ast_stopstream(chan);
-
- /*
- * Wait for the zaptel driver to physically write the tone blocks to the hardware
- */
-
- for(i = 0; i < 20 ; i++){
- flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT;
- res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
- if(flags & ZT_IOMUX_WRITEEMPTY)
- break;
- if( ast_safe_sleep(chan, 50)){
- res = -1;
- break;
- }
- }
-
-
- return res;
-}
-
-static int send_tone_telemetry(struct ast_channel *chan, char *tonestring)
-{
- char *stringp;
- char *tonesubset;
- int f1,f2;
- int duration;
- int amplitude;
- int res;
- int i;
- int flags;
-
- res = 0;
-
- stringp = ast_strdupa(tonestring);
-
- for(;tonestring;){
- tonesubset = strsep(&stringp,")");
- if(!tonesubset)
- break;
- if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &amplitude) != 4)
- break;
- res = play_tone_pair(chan, f1, f2, duration, amplitude);
- if(res)
- break;
- }
- if(!res)
- res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */
-
- if (!res)
- res = ast_waitstream(chan, "");
- ast_stopstream(chan);
-
- /*
- * Wait for the zaptel driver to physically write the tone blocks to the hardware
- */
-
- for(i = 0; i < 20 ; i++){
- flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT;
- res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
- if(flags & ZT_IOMUX_WRITEEMPTY)
- break;
- if( ast_safe_sleep(chan, 50)){
- res = -1;
- break;
- }
- }
-
- return res;
-
-}
-
-static int sayfile(struct ast_channel *mychannel,char *fname)
-{
-int res;
-
- res = ast_streamfile(mychannel, fname, mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- return res;
-}
-
-static int saycharstr(struct ast_channel *mychannel,char *str)
-{
-int res;
-
- res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- return res;
-}
-
-static int saynum(struct ast_channel *mychannel, int num)
-{
- int res;
- res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
- if(!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- return res;
-}
-
-
-static int telem_any(struct rpt *myrpt,struct ast_channel *chan, char *entry)
-{
- int res;
- char c;
-
- static int morsespeed;
- static int morsefreq;
- static int morseampl;
- static int morseidfreq = 0;
- static int morseidampl;
- static char mcat[] = MORSE;
-
- res = 0;
-
- if(!morseidfreq){ /* Get the morse parameters if not already loaded */
- morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20);
- morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800);
- morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096);
- morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048);
- morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330);
- }
-
- /* Is it a file, or a tone sequence? */
-
- if(entry[0] == '|'){
- c = entry[1];
- if((c >= 'a')&&(c <= 'z'))
- c -= 0x20;
-
- switch(c){
- case 'I': /* Morse ID */
- res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
- break;
-
- case 'M': /* Morse Message */
- res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
- break;
-
- case 'T': /* Tone sequence */
- res = send_tone_telemetry(chan, entry + 2);
- break;
- default:
- res = -1;
- }
- }
- else
- res = sayfile(chan, entry); /* File */
- return res;
-}
-
-/*
-* This function looks up a telemetry name in the config file, and does a telemetry response as configured.
-*
-* 4 types of telemtry are handled: Morse ID, Morse Message, Tone Sequence, and a File containing a recording.
-*/
-
-static int telem_lookup(struct rpt *myrpt,struct ast_channel *chan, char *node, char *name)
-{
-
- int res;
- int i;
- char *entry;
- char *telemetry;
- char *telemetry_save;
-
- res = 0;
- telemetry_save = NULL;
- entry = NULL;
-
- /* Retrieve the section name for telemetry from the node section */
- telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY);
- if(telemetry ){
- telemetry_save = ast_strdupa(telemetry);
- if(!telemetry_save){
- ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
- return res;
- }
- entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name);
- }
-
- /* Try to look up the telemetry name */
-
- if(!entry){
- /* Telemetry name wasn't found in the config file, use the default */
- for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
- if(!strcasecmp(tele_defs[i].name, name))
- entry = tele_defs[i].value;
- }
- }
- if(entry){
- if(strlen(entry))
- telem_any(myrpt,chan, entry);
- }
- else{
- res = -1;
- }
- return res;
-}
-
-/*
-* Retrieve a wait interval
-*/
-
-static int get_wait_interval(struct rpt *myrpt, int type)
-{
- int interval;
- char *wait_times;
- char *wait_times_save;
-
- wait_times_save = NULL;
- wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times");
-
- if(wait_times){
- wait_times_save = ast_strdupa(wait_times);
- if(!wait_times_save){
- ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
- wait_times = NULL;
- }
- }
-
- switch(type){
- case DLY_TELEM:
- if(wait_times)
- interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000);
- else
- interval = 1000;
- break;
-
- case DLY_ID:
- if(wait_times)
- interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500);
- else
- interval = 500;
- break;
-
- case DLY_UNKEY:
- if(wait_times)
- interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",500,5000,1000);
- else
- interval = 1000;
- break;
-
- case DLY_LINKUNKEY:
- if(wait_times)
- interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000);
- else
- interval = 1000;
- break;
-
- case DLY_CALLTERM:
- if(wait_times)
- interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500);
- else
- interval = 1500;
- break;
-
- case DLY_COMP:
- if(wait_times)
- interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200);
- else
- interval = 200;
- break;
-
- default:
- return 0;
- }
- return interval;
-}
-
-
-/*
-* Wait a configurable interval of time
-*/
-
-
-static void wait_interval(struct rpt *myrpt, int type, struct ast_channel *chan)
-{
- int interval;
- interval = get_wait_interval(myrpt, type);
- if(debug)
- ast_log(LOG_NOTICE," Delay interval = %d\n", interval);
- if(interval)
- ast_safe_sleep(chan,interval);
- if(debug)
- ast_log(LOG_NOTICE,"Delay complete\n");
- return;
-}
-
-static int split_freq(char *mhz, char *decimals, char *freq);
-
-static void *rpt_tele_thread(void *this)
-{
-ZT_CONFINFO ci; /* conference info */
-int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x;
-struct rpt_tele *mytele = (struct rpt_tele *)this;
-struct rpt_tele *tlist;
-struct rpt *myrpt;
-struct rpt_link *l,*l1,linkbase;
-struct ast_channel *mychannel;
-int vmajor, vminor, m;
-char *p,*ct,*ct_copy,*ident, *nodename,*cp;
-time_t t;
-struct tm localtm;
-char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
-int i,ns,rbimode;
-char mhz[MAXREMSTR];
-char decimals[MAXREMSTR];
-struct zt_params par;
-
-
- /* get a pointer to myrpt */
- myrpt = mytele->rpt;
-
- /* Snag copies of a few key myrpt variables */
- rpt_mutex_lock(&myrpt->lock);
- nodename = ast_strdupa(myrpt->name);
- if (myrpt->p.ident) ident = ast_strdupa(myrpt->p.ident);
- else ident = "";
- rpt_mutex_unlock(&myrpt->lock);
-
- /* allocate a pseudo-channel thru asterisk */
- mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!mychannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- rpt_mutex_lock(&myrpt->lock);
- remque((struct qelem *)mytele);
- ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
- rpt_mutex_unlock(&myrpt->lock);
- free(mytele);
- pthread_exit(NULL);
- }
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- rpt_mutex_lock(&myrpt->lock);
- mytele->chan = mychannel;
- rpt_mutex_unlock(&myrpt->lock);
- /* make a conference for the tx */
- ci.chan = 0;
- /* If there's an ID queued, or tail message queued, */
- /* only connect the ID audio to the local tx conference so */
- /* linked systems can't hear it */
- ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) ||
- (mytele->mode == TAILMSG) || (mytele->mode == LINKUNKEY)) || (mytele->mode == TIMEOUT) ?
- myrpt->txconf : myrpt->conf);
- ci.confmode = ZT_CONF_CONFANN;
- /* first put the channel on the conference in announce mode */
- if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_lock(&myrpt->lock);
- remque((struct qelem *)mytele);
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
- free(mytele);
- ast_hangup(mychannel);
- pthread_exit(NULL);
- }
- ast_stopstream(mychannel);
- switch(mytele->mode)
- {
- case ID:
- case ID1:
- /* wait a bit */
- wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel);
- res = telem_any(myrpt,mychannel, ident);
- imdone=1;
- break;
-
- case TAILMSG:
- res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language);
- break;
-
- case IDTALKOVER:
- p = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover");
- if(p)
- res = telem_any(myrpt,mychannel, p);
- imdone=1;
- break;
-
- case PROC:
- /* wait a little bit longer */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup");
- if(res < 0){ /* Then default message */
- res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language);
- }
- break;
- case TERM:
- /* wait a little bit longer */
- wait_interval(myrpt, DLY_CALLTERM, mychannel);
- res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown");
- if(res < 0){ /* Then default message */
- res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language);
- }
- break;
- case COMPLETE:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
- break;
- case MACRO_NOTFOUND:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language);
- break;
- case MACRO_BUSY:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language);
- break;
- case UNKEY:
- if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
- imdone = 1;
- break;
- }
-
- /*
- * Reset the Unkey to CT timer
- */
-
- x = get_wait_interval(myrpt, DLY_UNKEY);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */
- rpt_mutex_unlock(&myrpt->lock);
-
- /*
- * If there's one already queued, don't do another
- */
-
- tlist = myrpt->tele.next;
- unkeys_queued = 0;
- if (tlist != &myrpt->tele)
- {
- rpt_mutex_lock(&myrpt->lock);
- while(tlist != &myrpt->tele){
- if (tlist->mode == UNKEY) unkeys_queued++;
- tlist = tlist->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- }
- if( unkeys_queued > 1){
- imdone = 1;
- break;
- }
-
- /* Wait for the telemetry timer to expire */
- /* Periodically check the timer since it can be re-initialized above */
- while(myrpt->unkeytocttimer)
- {
- int ctint;
- if(myrpt->unkeytocttimer > 100)
- ctint = 100;
- else
- ctint = myrpt->unkeytocttimer;
- ast_safe_sleep(mychannel, ctint);
- rpt_mutex_lock(&myrpt->lock);
- if(myrpt->unkeytocttimer < ctint)
- myrpt->unkeytocttimer = 0;
- else
- myrpt->unkeytocttimer -= ctint;
- rpt_mutex_unlock(&myrpt->lock);
- }
-
- /*
- * Now, the carrier on the rptr rx should be gone.
- * If it re-appeared, then forget about sending the CT
- */
- if(myrpt->keyed){
- imdone = 1;
- break;
- }
-
- rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */
- myrpt->dailykerchunks++;
- myrpt->totalkerchunks++;
- rpt_mutex_unlock(&myrpt->lock);
-
- haslink = 0;
- hastx = 0;
- hasremote = 0;
- l = myrpt->links.next;
- if (l != &myrpt->links)
- {
- rpt_mutex_lock(&myrpt->lock);
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- haslink = 1;
- if (l->mode) {
- hastx++;
- if (l->isremote) hasremote++;
- }
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- }
- if (haslink)
- {
-
- res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx");
- if(res)
- ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name);
-
-
- /* if in remote cmd mode, indicate it */
- if (myrpt->cmdnode[0])
- {
- ast_safe_sleep(mychannel,200);
- res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode");
- if(res)
- ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- }
- }
- else if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */
- ct_copy = ast_strdupa(ct);
- res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
- if(res)
- ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
- }
- if (hasremote && (!myrpt->cmdnode[0]))
- {
- /* set for all to hear */
- ci.chan = 0;
- ci.confno = myrpt->conf;
- ci.confmode = ZT_CONF_CONFANN;
- /* first put the channel on the conference in announce mode */
- if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_lock(&myrpt->lock);
- remque((struct qelem *)mytele);
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
- free(mytele);
- ast_hangup(mychannel);
- pthread_exit(NULL);
- }
- if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */
- ast_safe_sleep(mychannel,200);
- ct_copy = ast_strdupa(ct);
- res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
- if(res)
- ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
- }
- }
-#if defined(_MDC_DECODE_H_) && defined(MDC_SAY_WHEN_DOING_CT)
- if (myrpt->lastunit)
- {
- char mystr[10];
-
- ast_safe_sleep(mychannel,200);
- /* set for all to hear */
- ci.chan = 0;
- ci.confno = myrpt->txconf;
- ci.confmode = ZT_CONF_CONFANN;
- /* first put the channel on the conference in announce mode */
- if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_lock(&myrpt->lock);
- remque((struct qelem *)mytele);
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
- free(mytele);
- ast_hangup(mychannel);
- pthread_exit(NULL);
- }
- sprintf(mystr,"%04x",myrpt->lastunit);
- myrpt->lastunit = 0;
- ast_say_character_str(mychannel,mystr,NULL,mychannel->language);
- break;
- }
-#endif
- imdone = 1;
- break;
- case LINKUNKEY:
- if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
- imdone = 1;
- break;
- }
-
- /*
- * Reset the Unkey to CT timer
- */
-
- x = get_wait_interval(myrpt, DLY_LINKUNKEY);
- mytele->mylink.linkunkeytocttimer = x; /* Must be protected as it is changed below */
-
- /*
- * If there's one already queued, don't do another
- */
-
- tlist = myrpt->tele.next;
- unkeys_queued = 0;
- if (tlist != &myrpt->tele)
- {
- rpt_mutex_lock(&myrpt->lock);
- while(tlist != &myrpt->tele){
- if (tlist->mode == LINKUNKEY) unkeys_queued++;
- tlist = tlist->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- }
- if( unkeys_queued > 1){
- imdone = 1;
- break;
- }
-
- /* Wait for the telemetry timer to expire */
- /* Periodically check the timer since it can be re-initialized above */
- while(mytele->mylink.linkunkeytocttimer)
- {
- int ctint;
- if(mytele->mylink.linkunkeytocttimer > 100)
- ctint = 100;
- else
- ctint = mytele->mylink.linkunkeytocttimer;
- ast_safe_sleep(mychannel, ctint);
- rpt_mutex_lock(&myrpt->lock);
- if(mytele->mylink.linkunkeytocttimer < ctint)
- mytele->mylink.linkunkeytocttimer = 0;
- else
- mytele->mylink.linkunkeytocttimer -= ctint;
- rpt_mutex_unlock(&myrpt->lock);
- }
-
- if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "linkunkeyct"))){ /* Unlinked Courtesy Tone */
- ct_copy = ast_strdupa(ct);
- res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
- if(res)
- ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
- }
- imdone = 1;
- break;
- case REMDISC:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- l = myrpt->links.next;
- haslink = 0;
- /* dont report if a link for this one still on system */
- if (l != &myrpt->links)
- {
- rpt_mutex_lock(&myrpt->lock);
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- if (!strcmp(l->name,mytele->mylink.name))
- {
- haslink = 1;
- break;
- }
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- }
- if (haslink)
- {
- imdone = 1;
- break;
- }
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
- res = ast_streamfile(mychannel, ((mytele->mylink.hasconnected) ?
- "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language);
- break;
- case REMALREADY:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language);
- break;
- case REMNOTFOUND:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language);
- break;
- case REMGO:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language);
- break;
- case CONNECTED:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
- res = ast_streamfile(mychannel, "rpt/connected", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- res = ast_streamfile(mychannel, "digits/2", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
- imdone = 1;
- break;
- case CONNFAIL:
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
- res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language);
- break;
- case MEMNOTFOUND:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/memory_notfound", mychannel->language);
- break;
- case SETREMOTE:
- ast_mutex_lock(&myrpt->remlock);
- res = 0;
- if(!strcmp(myrpt->remote, remote_rig_ft897))
- {
- res = set_ft897(myrpt);
- }
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- {
- res = set_ic706(myrpt);
- }
- else if(!strcmp(myrpt->remote, remote_rig_rbi))
- {
- if (ioperm(myrpt->p.iobase,1,1) == -1)
- {
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
- res = -1;
- }
- else res = setrbi(myrpt);
- }
- else if(!strcmp(myrpt->remote, remote_rig_kenwood))
- {
- res = setkenwood(myrpt);
- if (ast_safe_sleep(mychannel,200) == -1)
- {
- ast_mutex_unlock(&myrpt->remlock);
- res = -1;
- break;
- }
- i = ZT_FLUSH_EVENT;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_FLUSH,&i) == -1)
- {
- ast_mutex_unlock(&myrpt->remlock);
- ast_log(LOG_ERROR,"Cant flush events");
- res = -1;
- break;
- }
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) == -1)
- {
- ast_mutex_unlock(&myrpt->remlock);
- ast_log(LOG_ERROR,"Cant get params");
- res = -1;
- break;
- }
- myrpt->remoterx =
- (par.rxisoffhook || (myrpt->tele.next != &myrpt->tele));
- }
- ast_mutex_unlock(&myrpt->remlock);
- if (!res)
- {
- imdone = 1;
- break;
- }
- /* fall thru to invalid freq */
- case INVFREQ:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/invalid-freq", mychannel->language);
- break;
- case REMMODE:
- cp = 0;
- wait_interval(myrpt, DLY_TELEM, mychannel);
- switch(myrpt->remmode)
- {
- case REM_MODE_FM:
- saycharstr(mychannel,"FM");
- break;
- case REM_MODE_USB:
- saycharstr(mychannel,"USB");
- break;
- case REM_MODE_LSB:
- saycharstr(mychannel,"LSB");
- break;
- case REM_MODE_AM:
- saycharstr(mychannel,"AM");
- break;
- }
- wait_interval(myrpt, DLY_COMP, mychannel);
- if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
- break;
- case LOGINREQ:
- wait_interval(myrpt, DLY_TELEM, mychannel);
- sayfile(mychannel,"rpt/login");
- saycharstr(mychannel,myrpt->name);
- break;
- case REMLOGIN:
- wait_interval(myrpt, DLY_TELEM, mychannel);
- saycharstr(mychannel,myrpt->loginuser);
- sayfile(mychannel,"rpt/node");
- saycharstr(mychannel,myrpt->name);
- wait_interval(myrpt, DLY_COMP, mychannel);
- if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
- break;
- case REMXXX:
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = 0;
- switch(mytele->submode)
- {
- case 100: /* RX PL Off */
- sayfile(mychannel, "rpt/rxpl");
- sayfile(mychannel, "rpt/off");
- break;
- case 101: /* RX PL On */
- sayfile(mychannel, "rpt/rxpl");
- sayfile(mychannel, "rpt/on");
- break;
- case 102: /* TX PL Off */
- sayfile(mychannel, "rpt/txpl");
- sayfile(mychannel, "rpt/off");
- break;
- case 103: /* TX PL On */
- sayfile(mychannel, "rpt/txpl");
- sayfile(mychannel, "rpt/on");
- break;
- case 104: /* Low Power */
- sayfile(mychannel, "rpt/lopwr");
- break;
- case 105: /* Medium Power */
- sayfile(mychannel, "rpt/medpwr");
- break;
- case 106: /* Hi Power */
- sayfile(mychannel, "rpt/hipwr");
- break;
- case 113: /* Scan down slow */
- sayfile(mychannel,"rpt/down");
- sayfile(mychannel, "rpt/slow");
- break;
- case 114: /* Scan down quick */
- sayfile(mychannel,"rpt/down");
- sayfile(mychannel, "rpt/quick");
- break;
- case 115: /* Scan down fast */
- sayfile(mychannel,"rpt/down");
- sayfile(mychannel, "rpt/fast");
- break;
- case 116: /* Scan up slow */
- sayfile(mychannel,"rpt/up");
- sayfile(mychannel, "rpt/slow");
- break;
- case 117: /* Scan up quick */
- sayfile(mychannel,"rpt/up");
- sayfile(mychannel, "rpt/quick");
- break;
- case 118: /* Scan up fast */
- sayfile(mychannel,"rpt/up");
- sayfile(mychannel, "rpt/fast");
- break;
- default:
- res = -1;
- }
- wait_interval(myrpt, DLY_COMP, mychannel);
- if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
- break;
- case SCAN:
- ast_mutex_lock(&myrpt->remlock);
- if (myrpt->hfscanstop)
- {
- myrpt->hfscanstatus = 0;
- myrpt->hfscanmode = 0;
- myrpt->hfscanstop = 0;
- mytele->mode = SCANSTAT;
- ast_mutex_unlock(&myrpt->remlock);
- if (ast_safe_sleep(mychannel,1000) == -1) break;
- sayfile(mychannel, "rpt/stop");
- imdone = 1;
- break;
- }
- if (myrpt->hfscanstatus > -2) service_scan(myrpt);
- i = myrpt->hfscanstatus;
- myrpt->hfscanstatus = 0;
- if (i) mytele->mode = SCANSTAT;
- ast_mutex_unlock(&myrpt->remlock);
- if (i < 0) sayfile(mychannel, "rpt/stop");
- else if (i > 0) saynum(mychannel,i);
- imdone = 1;
- break;
- case TUNE:
- ast_mutex_lock(&myrpt->remlock);
- if (!strcmp(myrpt->remote,remote_rig_ic706))
- {
- set_mode_ic706(myrpt, REM_MODE_AM);
- if(play_tone(mychannel, 800, 6000, 8192) == -1) break;
- ast_safe_sleep(mychannel,500);
- set_mode_ic706(myrpt, myrpt->remmode);
- myrpt->tunerequest = 0;
- ast_mutex_unlock(&myrpt->remlock);
- imdone = 1;
- break;
- }
- set_mode_ft897(myrpt, REM_MODE_AM);
- simple_command_ft897(myrpt, 8);
- if(play_tone(mychannel, 800, 6000, 8192) == -1) break;
- simple_command_ft897(myrpt, 0x88);
- ast_safe_sleep(mychannel,500);
- set_mode_ft897(myrpt, myrpt->remmode);
- myrpt->tunerequest = 0;
- ast_mutex_unlock(&myrpt->remlock);
- imdone = 1;
- break;
- case REMSHORTSTATUS:
- case REMLONGSTATUS:
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = sayfile(mychannel,"rpt/node");
- if(!res)
- res = saycharstr(mychannel, myrpt->name);
- if(!res)
- res = sayfile(mychannel,"rpt/frequency");
- if(!res)
- res = split_freq(mhz, decimals, myrpt->freq);
- if (!multimode_capable(myrpt)) decimals[3] = 0;
- if(!res){
- m = atoi(mhz);
- if(m < 100)
- res = saynum(mychannel, m);
- else
- res = saycharstr(mychannel, mhz);
- }
- if(!res)
- res = sayfile(mychannel, "letters/dot");
- if(!res)
- res = saycharstr(mychannel, decimals);
-
- if(res) break;
- if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */
- switch(myrpt->offset){
-
- case REM_MINUS:
- res = sayfile(mychannel,"rpt/minus");
- break;
-
- case REM_SIMPLEX:
- res = sayfile(mychannel,"rpt/simplex");
- break;
-
- case REM_PLUS:
- res = sayfile(mychannel,"rpt/plus");
- break;
-
- default:
- break;
- }
- }
- else{ /* Must be USB, LSB, or AM */
- switch(myrpt->remmode){
-
- case REM_MODE_USB:
- res = saycharstr(mychannel, "USB");
- break;
-
- case REM_MODE_LSB:
- res = saycharstr(mychannel, "LSB");
- break;
-
- case REM_MODE_AM:
- res = saycharstr(mychannel, "AM");
- break;
-
-
- default:
- break;
- }
- }
-
- if (res == -1) break;
-
- if(mytele->mode == REMSHORTSTATUS){ /* Short status? */
- wait_interval(myrpt, DLY_COMP, mychannel);
- if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
- break;
- }
-
- if (strcmp(myrpt->remote,remote_rig_ic706))
- {
- switch(myrpt->powerlevel){
-
- case REM_LOWPWR:
- res = sayfile(mychannel,"rpt/lopwr") ;
- break;
- case REM_MEDPWR:
- res = sayfile(mychannel,"rpt/medpwr");
- break;
- case REM_HIPWR:
- res = sayfile(mychannel,"rpt/hipwr");
- break;
- }
- }
-
- rbimode = ((!strncmp(myrpt->remote,remote_rig_rbi,3))
- || (!strncmp(myrpt->remote,remote_rig_ic706,3)));
- if (res || (sayfile(mychannel,"rpt/rxpl") == -1)) break;
- if (rbimode && (sayfile(mychannel,"rpt/txpl") == -1)) break;
- if ((sayfile(mychannel,"rpt/frequency") == -1) ||
- (saycharstr(mychannel,myrpt->rxpl) == -1)) break;
- if ((!rbimode) && ((sayfile(mychannel,"rpt/txpl") == -1) ||
- (sayfile(mychannel,"rpt/frequency") == -1) ||
- (saycharstr(mychannel,myrpt->txpl) == -1))) break;
- if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */
- if ((sayfile(mychannel,"rpt/rxpl") == -1) ||
- (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1) ||
- (sayfile(mychannel,"rpt/txpl") == -1) ||
- (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1))
- {
- break;
- }
- }
- wait_interval(myrpt, DLY_COMP, mychannel);
- if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
- break;
- case STATUS:
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- hastx = 0;
- linkbase.next = &linkbase;
- linkbase.prev = &linkbase;
- rpt_mutex_lock(&myrpt->lock);
- /* make our own list of links */
- l = myrpt->links.next;
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- l1 = malloc(sizeof(struct rpt_link));
- if (!l1)
- {
- ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
- remque((struct qelem *)mytele);
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
- free(mytele);
- ast_hangup(mychannel);
- pthread_exit(NULL);
- }
- memcpy(l1,l,sizeof(struct rpt_link));
- l1->next = l1->prev = NULL;
- insque((struct qelem *)l1,(struct qelem *)linkbase.next);
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- if (myrpt->callmode)
- {
- hastx = 1;
- res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- }
- l = linkbase.next;
- while(l != &linkbase)
- {
- char *s;
-
- hastx = 1;
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,l->name,NULL,mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- s = "rpt/tranceive";
- if (!l->mode) s = "rpt/monitor";
- if (!l->thisconnected) s = "rpt/connecting";
- res = ast_streamfile(mychannel, s, mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- l = l->next;
- }
- if (!hastx)
- {
- res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- }
- /* destroy our local link queue */
- l = linkbase.next;
- while(l != &linkbase)
- {
- l1 = l;
- l = l->next;
- remque((struct qelem *)l1);
- free(l1);
- }
- imdone = 1;
- break;
- case FULLSTATUS:
- rpt_mutex_lock(&myrpt->lock);
- /* get all the nodes */
- __mklinklist(myrpt,NULL,lbuf);
- rpt_mutex_unlock(&myrpt->lock);
- /* parse em */
- ns = finddelim(lbuf,strs,MAXLINKLIST);
- /* sort em */
- if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
- /* wait a little bit */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- hastx = 0;
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- if (myrpt->callmode)
- {
- hastx = 1;
- res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- }
- /* go thru all the nodes in list */
- for(i = 0; i < ns; i++)
- {
- char *s,mode = 'T';
-
- /* if a mode spec at first, handle it */
- if ((*strs[i] < '0') || (*strs[i] > '9'))
- {
- mode = *strs[i];
- strs[i]++;
- }
-
- hastx = 1;
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,strs[i],NULL,mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- s = "rpt/tranceive";
- if (mode == 'R') s = "rpt/monitor";
- if (mode == 'C') s = "rpt/connecting";
- res = ast_streamfile(mychannel, s, mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- }
- if (!hastx)
- {
- res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- }
- imdone = 1;
- break;
-
- case LASTNODEKEY: /* Identify last node which keyed us up */
- rpt_mutex_lock(&myrpt->lock);
- if(myrpt->lastnodewhichkeyedusup)
- p = ast_strdupa(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */
- else
- p = NULL;
- rpt_mutex_unlock(&myrpt->lock);
- if(!p){
- imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */
- break;
- }
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel, p, NULL, mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- imdone = 1;
- break;
-
- case UNAUTHTX: /* Say unauthorized transmit frequency */
- wait_interval(myrpt, DLY_TELEM, mychannel);
- res = ast_streamfile(mychannel, "rpt/unauthtx", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- imdone = 1;
- break;
-
-
- case TIMEOUT:
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
- res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language);
- break;
-
- case TIMEOUT_WARNING:
- time(&t);
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
- res = ast_streamfile(mychannel, "rpt/timeout-warning", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- if(!res) /* Say number of seconds */
- ast_say_number(mychannel, myrpt->p.remotetimeout -
- (t - myrpt->last_activity_time),
- "", mychannel->language, (char *) NULL);
- if (!res)
- res = ast_waitstream(mychannel, "");
- ast_stopstream(mychannel);
- res = ast_streamfile(mychannel, "queue-seconds", mychannel->language);
- break;
-
- case ACT_TIMEOUT_WARNING:
- time(&t);
- res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
- res = ast_streamfile(mychannel, "rpt/act-timeout-warning", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- ast_stopstream(mychannel);
- if(!res) /* Say number of seconds */
- ast_say_number(mychannel, myrpt->p.remoteinacttimeout -
- (t - myrpt->last_activity_time),
- "", mychannel->language, (char *) NULL);
- if (!res)
- res = ast_waitstream(mychannel, "");
- ast_stopstream(mychannel);
- res = ast_streamfile(mychannel, "queue-seconds", mychannel->language);
- break;
-
- case STATS_TIME:
- wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
- t = time(NULL);
- rpt_localtime(&t, &localtm);
- /* Say the phase of the day is before the time */
- if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12))
- p = "rpt/goodmorning";
- else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18))
- p = "rpt/goodafternoon";
- else
- p = "rpt/goodevening";
- if (sayfile(mychannel,p) == -1)
- {
- imdone = 1;
- break;
- }
- /* Say the time is ... */
- if (sayfile(mychannel,"rpt/thetimeis") == -1)
- {
- imdone = 1;
- break;
- }
- /* Say the time */
- res = ast_say_time(mychannel, t, "", mychannel->language);
- if (!res)
- res = ast_waitstream(mychannel, "");
- ast_stopstream(mychannel);
- imdone = 1;
- break;
- case STATS_VERSION:
- p = strstr(tdesc, "version");
- if(!p)
- break;
- if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
- break;
- wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
- /* Say "version" */
- if (sayfile(mychannel,"rpt/version") == -1)
- {
- imdone = 1;
- break;
- }
- if(!res) /* Say "X" */
- ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL);
- if (!res)
- res = ast_waitstream(mychannel, "");
- ast_stopstream(mychannel);
- if (saycharstr(mychannel,".") == -1)
- {
- imdone = 1;
- break;
- }
- if(!res) /* Say "Y" */
- ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL);
- if (!res){
- res = ast_waitstream(mychannel, "");
- ast_stopstream(mychannel);
- }
- else
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- imdone = 1;
- break;
- case ARB_ALPHA:
- wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
- if(mytele->param)
- saycharstr(mychannel, mytele->param);
- imdone = 1;
- break;
- case REV_PATCH:
- wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
- if(mytele->param) {
-
- /* Parts of this section taken from app_parkandannounce */
- char *tpl_working, *tpl_current;
- char *tmp[100], *myparm;
- int looptemp=0,i=0, dres = 0;
-
-
- tpl_working = strdupa(mytele->param);
- myparm = strsep(&tpl_working,",");
- tpl_current=strsep(&tpl_working, ":");
-
- while(tpl_current && looptemp < sizeof(tmp)) {
- tmp[looptemp]=tpl_current;
- looptemp++;
- tpl_current=strsep(&tpl_working,":");
- }
-
- for(i=0; i<looptemp; i++) {
- if(!strcmp(tmp[i], "PARKED")) {
- ast_say_digits(mychannel, atoi(myparm), "", mychannel->language);
- } else if(!strcmp(tmp[i], "NODE")) {
- ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language);
- } else {
- dres = ast_streamfile(mychannel, tmp[i], mychannel->language);
- if(!dres) {
- dres = ast_waitstream(mychannel, "");
- } else {
- ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name);
- dres = 0;
- }
- }
- }
- }
- imdone = 1;
- break;
- case TEST_TONE:
- imdone = 1;
- if (myrpt->stopgen) break;
- myrpt->stopgen = -1;
- if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0)))
- {
- myrpt->stopgen = 0;
- break;
- }
- while(mychannel->generatordata && (myrpt->stopgen <= 0)) {
- if (ast_safe_sleep(mychannel,1)) break;
- imdone = 1;
- }
- myrpt->stopgen = 0;
- break;
- default:
- break;
- }
- if (!imdone)
- {
- if (!res)
- res = ast_waitstream(mychannel, "");
- else {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
- res = 0;
- }
- }
- ast_stopstream(mychannel);
- rpt_mutex_lock(&myrpt->lock);
- if (mytele->mode == TAILMSG)
- {
- if (!res)
- {
- myrpt->tailmessagen++;
- if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0;
- }
- else
- {
- myrpt->tmsgtimer = myrpt->p.tailsquashedtime;
- }
- }
- remque((struct qelem *)mytele);
- rpt_mutex_unlock(&myrpt->lock);
- free(mytele);
- ast_hangup(mychannel);
-#ifdef APP_RPT_LOCK_DEBUG
- {
- struct lockthread *t;
-
- sleep(5);
- ast_mutex_lock(&locklock);
- t = get_lockthread(pthread_self());
- if (t) memset(t,0,sizeof(struct lockthread));
- ast_mutex_unlock(&locklock);
- }
-#endif
- pthread_exit(NULL);
-}
-
-static void rpt_telemetry(struct rpt *myrpt,int mode, void *data)
-{
-struct rpt_tele *tele;
-struct rpt_link *mylink = (struct rpt_link *) data;
-int res;
-pthread_attr_t attr;
-
- tele = malloc(sizeof(struct rpt_tele));
- if (!tele)
- {
- ast_log(LOG_WARNING, "Unable to allocate memory\n");
- pthread_exit(NULL);
- return;
- }
- /* zero it out */
- memset((char *)tele,0,sizeof(struct rpt_tele));
- tele->rpt = myrpt;
- tele->mode = mode;
- rpt_mutex_lock(&myrpt->lock);
- if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) ||
- (mode == LINKUNKEY)){
- memset(&tele->mylink,0,sizeof(struct rpt_link));
- if (mylink){
- memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
- }
- }
- else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) {
- strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
- tele->param[TELEPARAMSIZE - 1] = 0;
- }
- if (mode == REMXXX) tele->submode = (int) data;
- insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next);
- rpt_mutex_unlock(&myrpt->lock);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
- if(res < 0){
- rpt_mutex_lock(&myrpt->lock);
- remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res));
- }
- return;
-}
-
-static void *rpt_call(void *this)
-{
-ZT_CONFINFO ci; /* conference info */
-struct rpt *myrpt = (struct rpt *)this;
-int res;
-int stopped,congstarted,dialtimer,lastcidx,aborted;
-struct ast_channel *mychannel,*genchannel;
-
-
- myrpt->mydtmf = 0;
- /* allocate a pseudo-channel thru asterisk */
- mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!mychannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- pthread_exit(NULL);
- }
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- ci.chan = 0;
- ci.confno = myrpt->conf; /* use the pseudo conference */
- ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
- | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
- /* first put the channel on the conference */
- if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- ast_hangup(mychannel);
- myrpt->callmode = 0;
- pthread_exit(NULL);
- }
- /* allocate a pseudo-channel thru asterisk */
- genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!genchannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- ast_hangup(mychannel);
- pthread_exit(NULL);
- }
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(genchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- ci.chan = 0;
- ci.confno = myrpt->conf;
- ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
- | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
- /* first put the channel on the conference */
- if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- myrpt->callmode = 0;
- pthread_exit(NULL);
- }
- if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1))
- {
- ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- myrpt->callmode = 0;
- pthread_exit(NULL);
- }
- if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1))
- {
- ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- myrpt->callmode = 0;
- pthread_exit(NULL);
- }
- /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */
- if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0))
- {
- ast_log(LOG_WARNING, "Cannot start dialtone\n");
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- myrpt->callmode = 0;
- pthread_exit(NULL);
- }
- stopped = 0;
- congstarted = 0;
- dialtimer = 0;
- lastcidx = 0;
- aborted = 0;
-
-
- while ((myrpt->callmode == 1) || (myrpt->callmode == 4))
- {
-
- if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){
- dialtimer = 0;
- lastcidx = myrpt->cidx;
- }
-
- if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){
- rpt_mutex_lock(&myrpt->lock);
- aborted = 1;
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- break;
- }
-
- if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0))
- {
- stopped = 1;
- /* stop dial tone */
- tone_zone_play_tone(mychannel->fds[0],-1);
- }
- if (myrpt->callmode == 4)
- {
- if(!congstarted){
- congstarted = 1;
- /* start congestion tone */
- tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION);
- }
- }
- res = ast_safe_sleep(mychannel, MSWAIT);
- if (res < 0)
- {
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- pthread_exit(NULL);
- }
- dialtimer += MSWAIT;
- }
- /* stop any tone generation */
- tone_zone_play_tone(mychannel->fds[0],-1);
- /* end if done */
- if (!myrpt->callmode)
- {
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- if((!myrpt->patchquiet) && aborted)
- rpt_telemetry(myrpt, TERM, NULL);
- pthread_exit(NULL);
- }
-
- if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){
- char *name, *loc, *instr;
- instr = strdup(myrpt->p.ourcallerid);
- if(instr){
- ast_callerid_parse(instr, &name, &loc);
- if(loc){
- if(mychannel->cid.cid_num)
- free(mychannel->cid.cid_num);
- mychannel->cid.cid_num = strdup(loc);
- }
- if(name){
- if(mychannel->cid.cid_name)
- free(mychannel->cid.cid_name);
- mychannel->cid.cid_name = strdup(name);
- }
- free(instr);
- }
- }
-
- ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1);
- ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1);
-
- if (myrpt->p.acctcode)
- ast_cdr_setaccount(mychannel,myrpt->p.acctcode);
- mychannel->priority = 1;
- ast_channel_undefer_dtmf(mychannel);
- if (ast_pbx_start(mychannel) < 0)
- {
- ast_log(LOG_WARNING, "Unable to start PBX!!\n");
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- pthread_exit(NULL);
- }
- usleep(10000);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->callmode = 3;
- /* set appropriate conference for the pseudo */
- ci.chan = 0;
- ci.confno = myrpt->conf;
- ci.confmode = (myrpt->p.duplex == 2) ? ZT_CONF_CONFANNMON :
- (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
- /* first put the channel on the conference in announce mode */
- if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- ast_hangup(mychannel);
- ast_hangup(genchannel);
- myrpt->callmode = 0;
- pthread_exit(NULL);
- }
- while(myrpt->callmode)
- {
- if ((!mychannel->pbx) && (myrpt->callmode != 4))
- {
- if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */
- myrpt->callmode = 0;
- if(!myrpt->patchquiet){
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt, TERM, NULL);
- rpt_mutex_lock(&myrpt->lock);
- }
- }
- else{ /* Send congestion until patch is downed by command */
- myrpt->callmode = 4;
- rpt_mutex_unlock(&myrpt->lock);
- /* start congestion tone */
- tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION);
- rpt_mutex_lock(&myrpt->lock);
- }
- }
- if (myrpt->mydtmf)
- {
- struct ast_frame wf = {AST_FRAME_DTMF, } ;
- wf.subclass = myrpt->mydtmf;
- rpt_mutex_unlock(&myrpt->lock);
- ast_queue_frame(mychannel,&wf);
- ast_senddigit(genchannel,myrpt->mydtmf);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->mydtmf = 0;
- }
- rpt_mutex_unlock(&myrpt->lock);
- usleep(MSWAIT * 1000);
- rpt_mutex_lock(&myrpt->lock);
- }
- rpt_mutex_unlock(&myrpt->lock);
- tone_zone_play_tone(genchannel->fds[0],-1);
- if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV);
- ast_hangup(genchannel);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- /* set appropriate conference for the pseudo */
- ci.chan = 0;
- ci.confno = myrpt->conf;
- ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON :
- (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
- /* first put the channel on the conference in announce mode */
- if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- }
- pthread_exit(NULL);
-}
-
-static void send_link_dtmf(struct rpt *myrpt,char c)
-{
-char str[300];
-struct ast_frame wf;
-struct rpt_link *l;
-
- snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c);
- wf.frametype = AST_FRAME_TEXT;
- wf.subclass = 0;
- wf.offset = 0;
- wf.mallocd = 0;
- wf.datalen = strlen(str) + 1;
- wf.samples = 0;
- l = myrpt->links.next;
- /* first, see if our dude is there */
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- /* if we found it, write it and were done */
- if (!strcmp(l->name,myrpt->cmdnode))
- {
- wf.data = str;
- if (l->chan) ast_write(l->chan,&wf);
- return;
- }
- l = l->next;
- }
- l = myrpt->links.next;
- /* if not, give it to everyone */
- while(l != &myrpt->links)
- {
- wf.data = str;
- if (l->chan) ast_write(l->chan,&wf);
- l = l->next;
- }
- return;
-}
-
-/*
- * Connect a link
- *
- * Return values:
- * -1: Error
- * 0: Success
- * 1: No match yet
- * 2: Already connected to this node
- */
-
-static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
-{
- char *val, *s, *s1, *s2, *tele;
- char lstr[MAXLINKLIST],*strs[MAXLINKLIST];
- char tmp[300], deststr[300] = "",modechange = 0;
- struct rpt_link *l;
- int reconnects = 0;
- int i,n;
- ZT_CONFINFO ci; /* conference info */
-
- val = node_lookup(myrpt,node);
- if (!val){
- if(strlen(node) >= myrpt->longestnode)
- return -1; /* No such node */
- return 1; /* No match yet */
- }
- if(debug > 3){
- ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node);
- ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor");
- ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal");
- }
-
- strncpy(tmp,val,sizeof(tmp) - 1);
- s = tmp;
- s1 = strsep(&s,",");
- s2 = strsep(&s,",");
- rpt_mutex_lock(&myrpt->lock);
- l = myrpt->links.next;
- /* try to find this one in queue */
- while(l != &myrpt->links){
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- /* if found matching string */
- if (!strcmp(l->name, node))
- break;
- l = l->next;
- }
- /* if found */
- if (l != &myrpt->links){
- /* if already in this mode, just ignore */
- if ((l->mode) || (!l->chan)) {
- rpt_mutex_unlock(&myrpt->lock);
- return 2; /* Already linked */
- }
- reconnects = l->reconnects;
- rpt_mutex_unlock(&myrpt->lock);
- if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
- l->retries = l->max_retries + 1;
- l->disced = 2;
- modechange = 1;
- } else
- {
- __mklinklist(myrpt,NULL,lstr);
- rpt_mutex_unlock(&myrpt->lock);
- n = finddelim(lstr,strs,MAXLINKLIST);
- for(i = 0; i < n; i++)
- {
- if ((*strs[i] < '0') ||
- (*strs[i] > '9')) strs[i]++;
- if (!strcmp(strs[i],node))
- {
- return 2; /* Already linked */
- }
- }
- }
- strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1);
- /* establish call */
- l = malloc(sizeof(struct rpt_link));
- if (!l)
- {
- ast_log(LOG_WARNING, "Unable to malloc\n");
- return -1;
- }
- /* zero the silly thing */
- memset((char *)l,0,sizeof(struct rpt_link));
- l->mode = mode;
- l->outbound = 1;
- l->thisconnected = 0;
- strncpy(l->name, node, MAXNODESTR - 1);
- l->isremote = (s && ast_true(s));
- if (modechange) l->connected = 1;
- l->hasconnected = l->perma = perma;
-#ifdef ALLOW_LOCAL_CHANNELS
- if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0))
- strncpy(deststr, s1, sizeof(deststr));
- else
- snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
-#else
- snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
-#endif
- tele = strchr(deststr, '/');
- if (!tele){
- ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr);
- free(l);
- return -1;
- }
- *tele++ = 0;
- l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
- if (l->chan){
- ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
- ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- l->chan->whentohangup = 0;
- l->chan->appl = "Apprpt";
- l->chan->data = "(Remote Rx)";
- if (debug > 3)
- ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n",
- deststr, tele, l->chan->name);
- if(l->chan->cid.cid_num)
- free(l->chan->cid.cid_num);
- l->chan->cid.cid_num = strdup(myrpt->name);
- ast_call(l->chan,tele,999);
- }
- else {
- if(debug > 3)
- ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n",
- deststr,tele,l->chan->name);
- if (myrpt->p.archivedir)
- {
- char str[100];
- sprintf(str,"LINKFAIL,%s",l->name);
- donodelog(myrpt,str);
- }
- free(l);
- return -1;
- }
- /* allocate a pseudo-channel thru asterisk */
- l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!l->pchan){
- ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n");
- ast_hangup(l->chan);
- free(l);
- return -1;
- }
- ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
- ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- /* make a conference for the tx */
- ci.chan = 0;
- ci.confno = myrpt->conf;
- ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
- /* first put the channel on the conference in proper mode */
- if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- ast_hangup(l->chan);
- ast_hangup(l->pchan);
- free(l);
- return -1;
- }
- rpt_mutex_lock(&myrpt->lock);
- l->reconnects = reconnects;
- /* insert at end of queue */
- l->max_retries = MAX_RETRIES;
- if (perma)
- l->max_retries = MAX_RETRIES_PERM;
- if (l->isremote) l->retries = l->max_retries + 1;
- insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
- __kickshort(myrpt);
- rpt_mutex_unlock(&myrpt->lock);
- return 0;
-}
-
-
-
-/*
-* Internet linking function
-*/
-
-static int function_ilink(struct rpt *myrpt, char *param, char *digits, int command_source, struct rpt_link *mylink)
-{
-
- char *val, *s, *s1, *s2;
- char tmp[300];
- char digitbuf[MAXNODESTR],*strs[MAXLINKLIST];
- char mode,perma;
- struct rpt_link *l;
- int i,r;
-
- if(!param)
- return DC_ERROR;
-
-
- if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable )
- return DC_ERROR;
-
- strncpy(digitbuf,digits,MAXNODESTR - 1);
-
- if(debug > 6)
- printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
-
- switch(myatoi(param)){
- case 11: /* Perm Link off */
- case 1: /* Link off */
- if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
- strcpy(digitbuf,myrpt->lastlinknode);
- val = node_lookup(myrpt,digitbuf);
- if (!val){
- if(strlen(digitbuf) >= myrpt->longestnode)
- return DC_ERROR;
- break;
- }
- strncpy(tmp,val,sizeof(tmp) - 1);
- s = tmp;
- s1 = strsep(&s,",");
- s2 = strsep(&s,",");
- rpt_mutex_lock(&myrpt->lock);
- l = myrpt->links.next;
- /* try to find this one in queue */
- while(l != &myrpt->links){
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- /* if found matching string */
- if (!strcmp(l->name, digitbuf))
- break;
- l = l->next;
- }
- if (l != &myrpt->links){ /* if found */
- struct ast_frame wf;
-
- /* must use perm command on perm link */
- if ((myatoi(param) < 10) &&
- (l->max_retries > MAX_RETRIES))
- {
- rpt_mutex_unlock(&myrpt->lock);
- return DC_COMPLETE;
- }
- strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
- l->retries = l->max_retries + 1;
- l->disced = 1;
- rpt_mutex_unlock(&myrpt->lock);
- wf.frametype = AST_FRAME_TEXT;
- wf.subclass = 0;
- wf.offset = 0;
- wf.mallocd = 0;
- wf.datalen = strlen(discstr) + 1;
- wf.samples = 0;
- wf.data = discstr;
- if (l->chan)
- {
- ast_write(l->chan,&wf);
- if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR;
- ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
- }
- rpt_telemetry(myrpt, COMPLETE, NULL);
- return DC_COMPLETE;
- }
- rpt_mutex_unlock(&myrpt->lock);
- return DC_COMPLETE;
- case 2: /* Link Monitor */
- case 3: /* Link transceive */
- case 12: /* Link Monitor permanent */
- case 13: /* Link transceive permanent */
- if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
- strcpy(digitbuf,myrpt->lastlinknode);
- /* Attempt connection */
- perma = (atoi(param) > 10) ? 1 : 0;
- mode = (atoi(param) & 1) ? 1 : 0;
- r = connect_link(myrpt, digitbuf, mode, perma);
- switch(r){
- case 0:
- rpt_telemetry(myrpt, COMPLETE, NULL);
- return DC_COMPLETE;
-
- case 1:
- break;
-
- case 2:
- rpt_telemetry(myrpt, REMALREADY, NULL);
- return DC_COMPLETE;
-
- default:
- rpt_telemetry(myrpt, CONNFAIL, NULL);
- return DC_COMPLETE;
- }
- break;
-
- case 4: /* Enter Command Mode */
-
- /* if doesnt allow link cmd, or no links active, return */
- if (((command_source != SOURCE_RPT) &&
- (command_source != SOURCE_PHONE) &&
- (command_source != SOURCE_DPHONE)) ||
- (myrpt->links.next == &myrpt->links))
- return DC_COMPLETE;
-
- /* if already in cmd mode, or selected self, fughetabahtit */
- if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){
-
- rpt_telemetry(myrpt, REMALREADY, NULL);
- return DC_COMPLETE;
- }
- if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
- strcpy(digitbuf,myrpt->lastlinknode);
- /* node must at least exist in list */
- val = node_lookup(myrpt,digitbuf);
- if (!val){
- if(strlen(digitbuf) >= myrpt->longestnode)
- return DC_ERROR;
- break;
-
- }
- rpt_mutex_lock(&myrpt->lock);
- strcpy(myrpt->lastlinknode,digitbuf);
- strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt, REMGO, NULL);
- return DC_COMPLETE;
-
- case 5: /* Status */
- rpt_telemetry(myrpt, STATUS, NULL);
- return DC_COMPLETE;
-
- case 15: /* Full Status */
- rpt_telemetry(myrpt, FULLSTATUS, NULL);
- return DC_COMPLETE;
-
-
- case 6: /* All Links Off, including permalinks */
- rpt_mutex_lock(&myrpt->lock);
- myrpt->savednodes[0] = 0;
- l = myrpt->links.next;
- /* loop through all links */
- while(l != &myrpt->links){
- struct ast_frame wf;
- if (l->name[0] == '0') /* Skip any IAXRPT monitoring */
- {
- l = l->next;
- continue;
- }
- /* Make a string of disconnected nodes for possible restoration */
- sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name);
- if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){
- if(myrpt->savednodes[0])
- strcat(myrpt->savednodes, ",");
- strcat(myrpt->savednodes, tmp);
- }
- l->retries = l->max_retries + 1;
- l->disced = 2; /* Silently disconnect */
- rpt_mutex_unlock(&myrpt->lock);
- /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */
-
- wf.frametype = AST_FRAME_TEXT;
- wf.subclass = 0;
- wf.offset = 0;
- wf.mallocd = 0;
- wf.datalen = strlen(discstr) + 1;
- wf.samples = 0;
- wf.data = discstr;
- if (l->chan)
- {
- ast_write(l->chan,&wf);
- ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */
- ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
- }
- rpt_mutex_lock(&myrpt->lock);
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- if(debug > 3)
- ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes);
- rpt_telemetry(myrpt, COMPLETE, NULL);
- return DC_COMPLETE;
-
- case 7: /* Identify last node which keyed us up */
- rpt_telemetry(myrpt, LASTNODEKEY, NULL);
- break;
-
-
-#ifdef _MDC_DECODE_H_
- case 8:
- myrpt->lastunit = 0xd00d;
- mdc1200_notify(myrpt,NULL,myrpt->lastunit);
- mdc1200_send(myrpt,myrpt->lastunit);
- break;
-#endif
-
- case 16: /* Restore links disconnected with "disconnect all links" command */
- strcpy(tmp, myrpt->savednodes); /* Make a copy */
- finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */
- for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){
- s1 = strs[i];
- mode = (s1[0] == 'X') ? 1 : 0;
- perma = (s1[1] == 'P') ? 1 : 0;
- connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */
- }
- rpt_telemetry(myrpt, COMPLETE, NULL);
- break;
-
- case 200:
- case 201:
- case 202:
- case 203:
- case 204:
- case 205:
- case 206:
- case 207:
- case 208:
- case 209:
- case 210:
- case 211:
- case 212:
- case 213:
- case 214:
- case 215:
- if (((myrpt->p.propagate_dtmf) &&
- (command_source == SOURCE_LNK)) ||
- ((myrpt->p.propagate_phonedtmf) &&
- ((command_source == SOURCE_PHONE) ||
- (command_source == SOURCE_DPHONE))))
- do_dtmf_local(myrpt,
- remdtmfstr[myatoi(param) - 200]);
- default:
- return DC_ERROR;
-
- }
-
- return DC_INDETERMINATE;
-}
-
-/*
-* Autopatch up
-*/
-
-static int function_autopatchup(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
-{
- pthread_attr_t attr;
- int i, index, paramlength;
- char *lparam;
- char *value = NULL;
- char *paramlist[20];
-
- static char *keywords[] = {
- "context",
- "dialtime",
- "farenddisconnect",
- "noct",
- "quiet",
- NULL
- };
-
- if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
- return DC_ERROR;
-
- if(debug)
- printf("@@@@ Autopatch up\n");
-
- if(!myrpt->callmode){
- /* Set defaults */
- myrpt->patchnoct = 0;
- myrpt->patchdialtime = 0;
- myrpt->patchfarenddisconnect = 0;
- myrpt->patchquiet = 0;
- strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
-
- if(param){
- /* Process parameter list */
- lparam = ast_strdupa(param);
- if(!lparam){
- ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__);
- return DC_ERROR;
- }
- paramlength = finddelim(lparam, paramlist, 20);
- for(i = 0; i < paramlength; i++){
- index = matchkeyword(paramlist[i], &value, keywords);
- if(value)
- value = skipchars(value, "= ");
- switch(index){
-
- case 1: /* context */
- strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ;
- break;
-
- case 2: /* dialtime */
- myrpt->patchdialtime = atoi(value);
- break;
-
- case 3: /* farenddisconnect */
- myrpt->patchfarenddisconnect = atoi(value);
- break;
-
- case 4: /* noct */
- myrpt->patchnoct = atoi(value);
- break;
-
- case 5: /* quiet */
- myrpt->patchquiet = atoi(value);
- break;
-
- default:
- break;
- }
- }
- }
- }
-
- rpt_mutex_lock(&myrpt->lock);
-
- /* if on call, force * into current audio stream */
-
- if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
- myrpt->mydtmf = myrpt->p.endchar;
- }
- if (myrpt->callmode){
- rpt_mutex_unlock(&myrpt->lock);
- return DC_COMPLETE;
- }
- myrpt->callmode = 1;
- myrpt->cidx = 0;
- myrpt->exten[myrpt->cidx] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
- return DC_COMPLETE;
-}
-
-/*
-* Autopatch down
-*/
-
-static int function_autopatchdn(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
-{
- if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
- return DC_ERROR;
-
- if(debug)
- printf("@@@@ Autopatch down\n");
-
- rpt_mutex_lock(&myrpt->lock);
-
- if (!myrpt->callmode){
- rpt_mutex_unlock(&myrpt->lock);
- return DC_COMPLETE;
- }
-
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt, TERM, NULL);
- return DC_COMPLETE;
-}
-
-/*
-* Status
-*/
-
-static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
-{
-
- if (!param)
- return DC_ERROR;
-
- if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable))
- return DC_ERROR;
-
- if(debug)
- printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
-
- switch(myatoi(param)){
- case 1: /* System ID */
- rpt_telemetry(myrpt, ID1, NULL);
- return DC_COMPLETE;
- case 2: /* System Time */
- rpt_telemetry(myrpt, STATS_TIME, NULL);
- return DC_COMPLETE;
- case 3: /* app_rpt.c version */
- rpt_telemetry(myrpt, STATS_VERSION, NULL);
- default:
- return DC_ERROR;
- }
- return DC_INDETERMINATE;
-}
-
-/*
-* Macro-oni (without Salami)
-*/
-
-static int function_macro(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
-{
-
-char *val;
-int i;
- if (myrpt->remote)
- return DC_ERROR;
-
- if(debug)
- printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
-
- if(strlen(digitbuf) < 1) /* needs 1 digit */
- return DC_INDETERMINATE;
-
- for(i = 0 ; i < digitbuf[i] ; i++) {
- if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
- return DC_ERROR;
- }
-
- if (*digitbuf == '0') val = myrpt->p.startupmacro;
- else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf);
- /* param was 1 for local buf */
- if (!val){
- if (strlen(digitbuf) < myrpt->macro_longest)
- return DC_INDETERMINATE;
- rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL);
- return DC_COMPLETE;
- }
- rpt_mutex_lock(&myrpt->lock);
- if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val))
- {
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt, MACRO_BUSY, NULL);
- return DC_ERROR;
- }
- myrpt->macrotimer = MACROTIME;
- strncat(myrpt->macrobuf, val, MAXMACRO - strlen(myrpt->macrobuf) - 1);
- rpt_mutex_unlock(&myrpt->lock);
- return DC_COMPLETE;
-}
-
-/*
-* COP - Control operator
-*/
-
-static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
-{
- char string[16];
-
- if(!param)
- return DC_ERROR;
-
- switch(myatoi(param)){
- case 1: /* System reset */
- system("killall -9 asterisk");
- return DC_COMPLETE;
-
- case 2:
- myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA");
- return DC_COMPLETE;
-
- case 3:
- myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1;
- return DC_COMPLETE;
-
- case 4: /* test tone on */
- if (myrpt->stopgen < 0)
- {
- myrpt->stopgen = 1;
- }
- else
- {
- myrpt->stopgen = 0;
- rpt_telemetry(myrpt, TEST_TONE, NULL);
- }
- return DC_COMPLETE;
-
- case 5: /* Disgorge variables to log for debug purposes */
- myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
- return DC_COMPLETE;
-
- case 6: /* Simulate COR being activated (phone only) */
- if (command_source != SOURCE_PHONE) return DC_INDETERMINATE;
- return DC_DOKEY;
-
-
- case 7: /* Time out timer enable */
- myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA");
- return DC_COMPLETE;
-
- case 8: /* Time out timer disable */
- myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS");
- return DC_COMPLETE;
-
- case 9: /* Autopatch enable */
- myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA");
- return DC_COMPLETE;
-
- case 10: /* Autopatch disable */
- myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS");
- return DC_COMPLETE;
-
- case 11: /* Link Enable */
- myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA");
- return DC_COMPLETE;
-
- case 12: /* Link Disable */
- myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS");
- return DC_COMPLETE;
-
- case 13: /* Query System State */
- string[0] = string[1] = 'S';
- string[2] = myrpt->p.sysstate_cur + '0';
- string[3] = '\0';
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
- return DC_COMPLETE;
-
- case 14: /* Change System State */
- if(strlen(digitbuf) == 0)
- break;
- if((digitbuf[0] < '0') || (digitbuf[0] > '9'))
- return DC_ERROR;
- myrpt->p.sysstate_cur = digitbuf[0] - '0';
- string[0] = string[1] = 'S';
- string[2] = myrpt->p.sysstate_cur + '0';
- string[3] = '\0';
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
- return DC_COMPLETE;
-
- case 15: /* Scheduler Enable */
- myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA");
- return DC_COMPLETE;
-
- case 16: /* Scheduler Disable */
- myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS");
- return DC_COMPLETE;
-
- case 17: /* User functions Enable */
- myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA");
- return DC_COMPLETE;
-
- case 18: /* User Functions Disable */
- myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS");
- return DC_COMPLETE;
-
- case 19: /* Alternate Tail Enable */
- myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA");
- return DC_COMPLETE;
-
- case 20: /* Alternate Tail Disable */
- myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0;
- rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS");
- return DC_COMPLETE;
- }
- return DC_INDETERMINATE;
-}
-
-/*
-* Collect digits one by one until something matches
-*/
-
-static int collect_function_digits(struct rpt *myrpt, char *digits,
- int command_source, struct rpt_link *mylink)
-{
- int i;
- char *stringp,*action,*param,*functiondigits;
- char function_table_name[30] = "";
- char workstring[200];
-
- struct ast_variable *vp;
-
- if(debug)
- printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source);
-
- if (command_source == SOURCE_DPHONE) {
- if (!myrpt->p.dphone_functions) return DC_INDETERMINATE;
- strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1);
- }
- else if (command_source == SOURCE_PHONE) {
- if (!myrpt->p.phone_functions) return DC_INDETERMINATE;
- strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1);
- }
- else if (command_source == SOURCE_LNK)
- strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1);
- else
- strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1);
- vp = ast_variable_browse(myrpt->cfg, function_table_name);
- while(vp) {
- if(!strncasecmp(vp->name, digits, strlen(vp->name)))
- break;
- vp = vp->next;
- }
- if(!vp) {
- int n;
-
- n = myrpt->longestfunc;
- if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc;
- else
- if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc;
- else
- if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc;
-
- if(strlen(digits) >= n)
- return DC_ERROR;
- else
- return DC_INDETERMINATE;
- }
- /* Found a match, retrieve value part and parse */
- strncpy(workstring, vp->value, sizeof(workstring) - 1 );
- stringp = workstring;
- action = strsep(&stringp, ",");
- param = stringp;
- if(debug)
- printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)");
- /* Look up the action */
- for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){
- if(!strncasecmp(action, function_table[i].action, strlen(action)))
- break;
- }
- if(debug)
- printf("@@@@ table index i = %d\n",i);
- if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){
- /* Error, action not in table */
- return DC_ERROR;
- }
- if(function_table[i].function == NULL){
- /* Error, function undefined */
- if(debug)
- printf("@@@@ NULL for action: %s\n",action);
- return DC_ERROR;
- }
- functiondigits = digits + strlen(vp->name);
- return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink);
-}
-
-
-static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink,
- char *str)
-{
-char tmp[512],cmd[300] = "",dest[300],src[300],c;
-int seq, res;
-struct rpt_link *l;
-struct ast_frame wf;
-
- wf.frametype = AST_FRAME_TEXT;
- wf.subclass = 0;
- wf.offset = 0;
- wf.mallocd = 0;
- wf.datalen = strlen(str) + 1;
- wf.samples = 0;
- /* put string in our buffer */
- strncpy(tmp,str,sizeof(tmp) - 1);
-
- if (!strcmp(tmp,discstr))
- {
- mylink->disced = 1;
- mylink->retries = mylink->max_retries + 1;
- ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV);
- return;
- }
- if (tmp[0] == 'L')
- {
- rpt_mutex_lock(&myrpt->lock);
- strcpy(mylink->linklist,tmp + 2);
- time(&mylink->linklistreceived);
- rpt_mutex_unlock(&myrpt->lock);
- if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s recieved node list %s from node %s\n",
- myrpt->name,tmp,mylink->name);
- return;
- }
- if (tmp[0] == 'I')
- {
- if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
- {
- ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
- return;
- }
- mdc1200_notify(myrpt,src,seq);
- strcpy(dest,"*");
- }
- else
- {
- if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
- {
- ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
- return;
- }
- if (strcmp(cmd,"D"))
- {
- ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
- return;
- }
- }
- if (dest[0] == '0')
- {
- strcpy(dest,myrpt->name);
- }
-
- /* if not for me, redistribute to all links */
- if (strcmp(dest,myrpt->name))
- {
- l = myrpt->links.next;
- /* see if this is one in list */
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- /* dont send back from where it came */
- if ((l == mylink) || (!strcmp(l->name,mylink->name)))
- {
- l = l->next;
- continue;
- }
- /* if it is, send it and we're done */
- if (!strcmp(l->name,dest))
- {
- /* send, but not to src */
- if (strcmp(l->name,src)) {
- wf.data = str;
- if (l->chan) ast_write(l->chan,&wf);
- }
- return;
- }
- l = l->next;
- }
- l = myrpt->links.next;
- /* otherwise, send it to all of em */
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- /* dont send back from where it came */
- if ((l == mylink) || (!strcmp(l->name,mylink->name)))
- {
- l = l->next;
- continue;
- }
- /* send, but not to src */
- if (strcmp(l->name,src)) {
- wf.data = str;
- if (l->chan) ast_write(l->chan,&wf);
- }
- l = l->next;
- }
- return;
- }
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"DTMF,%s,%c",mylink->name,c);
- donodelog(myrpt,str);
- }
- c = func_xlat(myrpt,c,&myrpt->p.outxlat);
- if (!c) return;
- rpt_mutex_lock(&myrpt->lock);
- if (c == myrpt->p.endchar) myrpt->stopgen = 1;
- if (myrpt->callmode == 1)
- {
- myrpt->exten[myrpt->cidx++] = c;
- myrpt->exten[myrpt->cidx] = 0;
- /* if this exists */
- if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
- {
- myrpt->callmode = 2;
- if(!myrpt->patchquiet){
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,PROC,NULL);
- rpt_mutex_lock(&myrpt->lock);
- }
- }
- /* if can continue, do so */
- if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
- {
- /* call has failed, inform user */
- myrpt->callmode = 4;
- }
- }
- if (c == myrpt->p.funcchar)
- {
- myrpt->rem_dtmfidx = 0;
- myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
- time(&myrpt->rem_dtmf_time);
- rpt_mutex_unlock(&myrpt->lock);
- return;
- }
- else if (myrpt->rem_dtmfidx < 0)
- {
- if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
- {
- myrpt->mydtmf = c;
- }
- if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c);
- if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c);
- rpt_mutex_unlock(&myrpt->lock);
- return;
- }
- else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0))
- {
- time(&myrpt->rem_dtmf_time);
- if (myrpt->rem_dtmfidx < MAXDTMF)
- {
- myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
- myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
-
- rpt_mutex_unlock(&myrpt->lock);
- strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
- res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink);
- rpt_mutex_lock(&myrpt->lock);
-
- switch(res){
-
- case DC_INDETERMINATE:
- break;
-
- case DC_REQ_FLUSH:
- myrpt->rem_dtmfidx = 0;
- myrpt->rem_dtmfbuf[0] = 0;
- break;
-
-
- case DC_COMPLETE:
- case DC_COMPLETEQUIET:
- myrpt->totalexecdcommands++;
- myrpt->dailyexecdcommands++;
- strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
- myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
- myrpt->rem_dtmfbuf[0] = 0;
- myrpt->rem_dtmfidx = -1;
- myrpt->rem_dtmf_time = 0;
- break;
-
- case DC_ERROR:
- default:
- myrpt->rem_dtmfbuf[0] = 0;
- myrpt->rem_dtmfidx = -1;
- myrpt->rem_dtmf_time = 0;
- break;
- }
- }
-
- }
- rpt_mutex_unlock(&myrpt->lock);
- return;
-}
-
-static void handle_link_phone_dtmf(struct rpt *myrpt, struct rpt_link *mylink,
- char c)
-{
-
-char cmd[300];
-int res;
-
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"DTMF(P),%s,%c",mylink->name,c);
- donodelog(myrpt,str);
- }
- rpt_mutex_lock(&myrpt->lock);
- if (c == myrpt->p.endchar)
- {
- if (mylink->lastrx)
- {
- mylink->lastrx = 0;
- rpt_mutex_unlock(&myrpt->lock);
- return;
- }
- myrpt->stopgen = 1;
- if (myrpt->cmdnode[0])
- {
- myrpt->cmdnode[0] = 0;
- myrpt->dtmfidx = -1;
- myrpt->dtmfbuf[0] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,COMPLETE,NULL);
- return;
- }
- }
- if (myrpt->cmdnode[0])
- {
- rpt_mutex_unlock(&myrpt->lock);
- send_link_dtmf(myrpt,c);
- return;
- }
- if (myrpt->callmode == 1)
- {
- myrpt->exten[myrpt->cidx++] = c;
- myrpt->exten[myrpt->cidx] = 0;
- /* if this exists */
- if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
- {
- myrpt->callmode = 2;
- if(!myrpt->patchquiet){
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,PROC,NULL);
- rpt_mutex_lock(&myrpt->lock);
- }
- }
- /* if can continue, do so */
- if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
- {
- /* call has failed, inform user */
- myrpt->callmode = 4;
- }
- }
- if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
- {
- myrpt->mydtmf = c;
- }
- if (c == myrpt->p.funcchar)
- {
- myrpt->rem_dtmfidx = 0;
- myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
- time(&myrpt->rem_dtmf_time);
- rpt_mutex_unlock(&myrpt->lock);
- return;
- }
- else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0))
- {
- time(&myrpt->rem_dtmf_time);
- if (myrpt->rem_dtmfidx < MAXDTMF)
- {
- myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
- myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
-
- rpt_mutex_unlock(&myrpt->lock);
- strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
- switch(mylink->phonemode)
- {
- case 1:
- res = collect_function_digits(myrpt, cmd,
- SOURCE_PHONE, mylink);
- break;
- case 2:
- res = collect_function_digits(myrpt, cmd,
- SOURCE_DPHONE,mylink);
- break;
- default:
- res = collect_function_digits(myrpt, cmd,
- SOURCE_LNK, mylink);
- break;
- }
-
- rpt_mutex_lock(&myrpt->lock);
-
- switch(res){
-
- case DC_INDETERMINATE:
- break;
-
- case DC_DOKEY:
- mylink->lastrx = 1;
- break;
-
- case DC_REQ_FLUSH:
- myrpt->rem_dtmfidx = 0;
- myrpt->rem_dtmfbuf[0] = 0;
- break;
-
-
- case DC_COMPLETE:
- case DC_COMPLETEQUIET:
- myrpt->totalexecdcommands++;
- myrpt->dailyexecdcommands++;
- strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
- myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
- myrpt->rem_dtmfbuf[0] = 0;
- myrpt->rem_dtmfidx = -1;
- myrpt->rem_dtmf_time = 0;
- break;
-
- case DC_ERROR:
- default:
- myrpt->rem_dtmfbuf[0] = 0;
- myrpt->rem_dtmfidx = -1;
- myrpt->rem_dtmf_time = 0;
- break;
- }
- }
-
- }
- rpt_mutex_unlock(&myrpt->lock);
- return;
-}
-
-/* Doug Hall RBI-1 serial data definitions:
- *
- * Byte 0: Expansion external outputs
- * Byte 1:
- * Bits 0-3 are BAND as follows:
- * Bits 4-5 are POWER bits as follows:
- * 00 - Low Power
- * 01 - Hi Power
- * 02 - Med Power
- * Bits 6-7 are always set
- * Byte 2:
- * Bits 0-3 MHZ in BCD format
- * Bits 4-5 are offset as follows:
- * 00 - minus
- * 01 - plus
- * 02 - simplex
- * 03 - minus minus (whatever that is)
- * Bit 6 is the 0/5 KHZ bit
- * Bit 7 is always set
- * Byte 3:
- * Bits 0-3 are 10 KHZ in BCD format
- * Bits 4-7 are 100 KHZ in BCD format
- * Byte 4: PL Tone code and encode/decode enable bits
- * Bits 0-5 are PL tone code (comspec binary codes)
- * Bit 6 is encode enable/disable
- * Bit 7 is decode enable/disable
- */
-
-/* take the frequency from the 10 mhz digits (and up) and convert it
- to a band number */
-
-static int rbi_mhztoband(char *str)
-{
-int i;
-
- i = atoi(str) / 10; /* get the 10's of mhz */
- switch(i)
- {
- case 2:
- return 10;
- case 5:
- return 11;
- case 14:
- return 2;
- case 22:
- return 3;
- case 44:
- return 4;
- case 124:
- return 0;
- case 125:
- return 1;
- case 126:
- return 8;
- case 127:
- return 5;
- case 128:
- return 6;
- case 129:
- return 7;
- default:
- break;
- }
- return -1;
-}
-
-/* take a PL frequency and turn it into a code */
-static int rbi_pltocode(char *str)
-{
-int i;
-char *s;
-
- s = strchr(str,'.');
- i = 0;
- if (s) i = atoi(s + 1);
- i += atoi(str) * 10;
- switch(i)
- {
- case 670:
- return 0;
- case 719:
- return 1;
- case 744:
- return 2;
- case 770:
- return 3;
- case 797:
- return 4;
- case 825:
- return 5;
- case 854:
- return 6;
- case 885:
- return 7;
- case 915:
- return 8;
- case 948:
- return 9;
- case 974:
- return 10;
- case 1000:
- return 11;
- case 1035:
- return 12;
- case 1072:
- return 13;
- case 1109:
- return 14;
- case 1148:
- return 15;
- case 1188:
- return 16;
- case 1230:
- return 17;
- case 1273:
- return 18;
- case 1318:
- return 19;
- case 1365:
- return 20;
- case 1413:
- return 21;
- case 1462:
- return 22;
- case 1514:
- return 23;
- case 1567:
- return 24;
- case 1622:
- return 25;
- case 1679:
- return 26;
- case 1738:
- return 27;
- case 1799:
- return 28;
- case 1862:
- return 29;
- case 1928:
- return 30;
- case 2035:
- return 31;
- case 2107:
- return 32;
- case 2181:
- return 33;
- case 2257:
- return 34;
- case 2336:
- return 35;
- case 2418:
- return 36;
- case 2503:
- return 37;
- }
- return -1;
-}
-
-/*
-* Shift out a formatted serial bit stream
-*/
-
-static void rbi_out_parallel(struct rpt *myrpt,unsigned char *data)
- {
-#ifdef __i386__
- int i,j;
- unsigned char od,d;
- static volatile long long delayvar;
-
- for(i = 0 ; i < 5 ; i++){
- od = *data++;
- for(j = 0 ; j < 8 ; j++){
- d = od & 1;
- outb(d,myrpt->p.iobase);
- /* >= 15 us */
- for(delayvar = 1; delayvar < 15000; delayvar++);
- od >>= 1;
- outb(d | 2,myrpt->p.iobase);
- /* >= 30 us */
- for(delayvar = 1; delayvar < 30000; delayvar++);
- outb(d,myrpt->p.iobase);
- /* >= 10 us */
- for(delayvar = 1; delayvar < 10000; delayvar++);
- }
- }
- /* >= 50 us */
- for(delayvar = 1; delayvar < 50000; delayvar++);
-#endif
- }
-
-static void rbi_out(struct rpt *myrpt,unsigned char *data)
-{
-struct zt_radio_param r;
-
- memset(&r,0,sizeof(struct zt_radio_param));
- r.radpar = ZT_RADPAR_REMMODE;
- r.data = ZT_RADPAR_REM_RBI1;
- /* if setparam ioctl fails, its probably not a pciradio card */
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
- {
- rbi_out_parallel(myrpt,data);
- return;
- }
- r.radpar = ZT_RADPAR_REMCOMMAND;
- memcpy(&r.data,data,5);
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
- {
- ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name);
- return;
- }
-}
-
-static int serial_remote_io(struct rpt *myrpt, unsigned char *txbuf, int txbytes,
- unsigned char *rxbuf, int rxmaxbytes, int asciiflag)
-{
- int i,j,index,oldmode,olddata;
- struct zt_radio_param prm;
- char c;
-
- if(debug){
- printf("String output was: ");
- for(i = 0; i < txbytes; i++)
- printf("%02X ", (unsigned char ) txbuf[i]);
- printf("\n");
- }
- if (myrpt->iofd > 0) /* if to do out a serial port */
- {
- if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH);
- if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1;
- if ((!rxmaxbytes) || (rxbuf == NULL)) return(0);
- memset(rxbuf,0,rxmaxbytes);
- for(i = 0; i < rxmaxbytes; i++)
- {
- j = read(myrpt->iofd,&c,1);
- if (j < 1) return(i);
- rxbuf[i] = c;
- if (asciiflag & 1)
- {
- rxbuf[i + 1] = 0;
- if (c == '\r') break;
- }
- }
- if(debug){
- printf("String returned was: ");
- for(j = 0; j < i; j++)
- printf("%02X ", (unsigned char ) rxbuf[j]);
- printf("\n");
- }
- return(i);
- }
-
- /* if not a zap channel, cant use pciradio stuff */
- if (myrpt->rxchannel != myrpt->zaprxchannel) return -1;
-
- prm.radpar = ZT_RADPAR_UIOMODE;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
- oldmode = prm.data;
- prm.radpar = ZT_RADPAR_UIODATA;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
- olddata = prm.data;
- prm.radpar = ZT_RADPAR_REMMODE;
- if (asciiflag & 1) prm.data = ZT_RADPAR_REM_SERIAL_ASCII;
- else prm.data = ZT_RADPAR_REM_SERIAL;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
- if (asciiflag & 2)
- {
- i = ZT_ONHOOK;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
- usleep(100000);
- }
- prm.radpar = ZT_RADPAR_REMCOMMAND;
- prm.data = rxmaxbytes;
- memcpy(prm.buf,txbuf,txbytes);
- prm.index = txbytes;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
- if (rxbuf)
- {
- *rxbuf = 0;
- memcpy(rxbuf,prm.buf,prm.index);
- }
- index = prm.index;
- prm.radpar = ZT_RADPAR_REMMODE;
- prm.data = ZT_RADPAR_REM_NONE;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
- if (asciiflag & 2)
- {
- i = ZT_OFFHOOK;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
- }
- prm.radpar = ZT_RADPAR_UIOMODE;
- prm.data = oldmode;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
- prm.radpar = ZT_RADPAR_UIODATA;
- prm.data = olddata;
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
- return(index);
-}
-
-static int civ_cmd(struct rpt *myrpt,unsigned char *cmd, int cmdlen)
-{
-unsigned char rxbuf[100];
-int i,rv ;
-
- rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0);
- if (rv == -1) return(-1);
- if (rv != (cmdlen + 6)) return(1);
- for(i = 0; i < 6; i++)
- if (rxbuf[i] != cmd[i]) return(1);
- if (rxbuf[cmdlen] != 0xfe) return(1);
- if (rxbuf[cmdlen + 1] != 0xfe) return(1);
- if (rxbuf[cmdlen + 4] != 0xfb) return(1);
- if (rxbuf[cmdlen + 5] != 0xfd) return(1);
- return(0);
-}
-
-static int sendkenwood(struct rpt *myrpt,char *txstr, char *rxstr)
-{
-int i;
-
- if (debug) printf("Send to kenwood: %s\n",txstr);
- i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr),
- (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3);
- if (i < 0) return -1;
- if ((i > 0) && (rxstr[i - 1] == '\r'))
- rxstr[i-- - 1] = 0;
- if (debug) printf("Got from kenwood: %s\n",rxstr);
- return(i);
-}
-
-/* take a PL frequency and turn it into a code */
-static int kenwood_pltocode(char *str)
-{
-int i;
-char *s;
-
- s = strchr(str,'.');
- i = 0;
- if (s) i = atoi(s + 1);
- i += atoi(str) * 10;
- switch(i)
- {
- case 670:
- return 1;
- case 719:
- return 3;
- case 744:
- return 4;
- case 770:
- return 5;
- case 797:
- return 6;
- case 825:
- return 7;
- case 854:
- return 8;
- case 885:
- return 9;
- case 915:
- return 10;
- case 948:
- return 11;
- case 974:
- return 12;
- case 1000:
- return 13;
- case 1035:
- return 14;
- case 1072:
- return 15;
- case 1109:
- return 16;
- case 1148:
- return 17;
- case 1188:
- return 18;
- case 1230:
- return 19;
- case 1273:
- return 20;
- case 1318:
- return 21;
- case 1365:
- return 22;
- case 1413:
- return 23;
- case 1462:
- return 24;
- case 1514:
- return 25;
- case 1567:
- return 26;
- case 1622:
- return 27;
- case 1679:
- return 28;
- case 1738:
- return 29;
- case 1799:
- return 30;
- case 1862:
- return 31;
- case 1928:
- return 32;
- case 2035:
- return 33;
- case 2107:
- return 34;
- case 2181:
- return 35;
- case 2257:
- return 36;
- case 2336:
- return 37;
- case 2418:
- return 38;
- case 2503:
- return 39;
- }
- return -1;
-}
-
-static int sendrxkenwood(struct rpt *myrpt, char *txstr, char *rxstr,
- char *cmpstr)
-{
-int i,j;
-
- for(i = 0;i < KENWOOD_RETRIES;i++)
- {
- j = sendkenwood(myrpt,txstr,rxstr);
- if (j < 0) return(j);
- if (j == 0) continue;
- if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0);
- }
- return(-1);
-}
-
-static int setkenwood(struct rpt *myrpt)
-{
-char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20];
-char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2;
-
-int offsets[] = {0,2,1};
-int powers[] = {2,1,0};
-
- if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1;
- split_freq(mhz, decimals, myrpt->freq);
- if (atoi(mhz) > 400)
- {
- band = '6';
- band1 = '1';
- band2 = '5';
- strcpy(offset,"005000000");
- }
- else
- {
- band = '2';
- band1 = '0';
- band2 = '2';
- strcpy(offset,"000600000");
- }
- strcpy(freq,"000000");
- strncpy(freq,decimals,strlen(decimals));
- sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r",
- band,atoi(mhz),freq,offsets[(int)myrpt->offset],
- (myrpt->txplon != 0),(myrpt->rxplon != 0),
- kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl),
- offset);
- if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1;
- sprintf(txstr,"RBN %c\r",band2);
- if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1;
- sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]);
- if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1;
- return 0;
-}
-
-static int setrbi(struct rpt *myrpt)
-{
-char tmp[MAXREMSTR] = "",*s;
-unsigned char rbicmd[5];
-int band,txoffset = 0,txpower = 0,rxpl;
-
- /* must be a remote system */
- if (!myrpt->remote) return(0);
- /* must have rbi hardware */
- if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0);
- if (setrbi_check(myrpt) == -1) return(-1);
- strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
- s = strchr(tmp,'.');
- /* if no decimal, is invalid */
-
- if (s == NULL){
- if(debug)
- printf("@@@@ Frequency needs a decimal\n");
- return -1;
- }
-
- *s++ = 0;
- if (strlen(tmp) < 2){
- if(debug)
- printf("@@@@ Bad MHz digits: %s\n", tmp);
- return -1;
- }
-
- if (strlen(s) < 3){
- if(debug)
- printf("@@@@ Bad KHz digits: %s\n", s);
- return -1;
- }
-
- if ((s[2] != '0') && (s[2] != '5')){
- if(debug)
- printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
- return -1;
- }
-
- band = rbi_mhztoband(tmp);
- if (band == -1){
- if(debug)
- printf("@@@@ Bad Band: %s\n", tmp);
- return -1;
- }
-
- rxpl = rbi_pltocode(myrpt->rxpl);
-
- if (rxpl == -1){
- if(debug)
- printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl);
- return -1;
- }
-
-
- switch(myrpt->offset)
- {
- case REM_MINUS:
- txoffset = 0;
- break;
- case REM_PLUS:
- txoffset = 0x10;
- break;
- case REM_SIMPLEX:
- txoffset = 0x20;
- break;
- }
- switch(myrpt->powerlevel)
- {
- case REM_LOWPWR:
- txpower = 0;
- break;
- case REM_MEDPWR:
- txpower = 0x20;
- break;
- case REM_HIPWR:
- txpower = 0x10;
- break;
- }
- rbicmd[0] = 0;
- rbicmd[1] = band | txpower | 0xc0;
- rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80;
- if (s[2] == '5') rbicmd[2] |= 0x40;
- rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0');
- rbicmd[4] = rxpl;
- if (myrpt->txplon) rbicmd[4] |= 0x40;
- if (myrpt->rxplon) rbicmd[4] |= 0x80;
- rbi_out(myrpt,rbicmd);
- return 0;
-}
-
-static int setrbi_check(struct rpt *myrpt)
-{
-char tmp[MAXREMSTR] = "",*s;
-int band,txpl;
-
- /* must be a remote system */
- if (!myrpt->remote) return(0);
- /* must have rbi hardware */
- if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0);
- strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
- s = strchr(tmp,'.');
- /* if no decimal, is invalid */
-
- if (s == NULL){
- if(debug)
- printf("@@@@ Frequency needs a decimal\n");
- return -1;
- }
-
- *s++ = 0;
- if (strlen(tmp) < 2){
- if(debug)
- printf("@@@@ Bad MHz digits: %s\n", tmp);
- return -1;
- }
-
- if (strlen(s) < 3){
- if(debug)
- printf("@@@@ Bad KHz digits: %s\n", s);
- return -1;
- }
-
- if ((s[2] != '0') && (s[2] != '5')){
- if(debug)
- printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
- return -1;
- }
-
- band = rbi_mhztoband(tmp);
- if (band == -1){
- if(debug)
- printf("@@@@ Bad Band: %s\n", tmp);
- return -1;
- }
-
- txpl = rbi_pltocode(myrpt->txpl);
-
- if (txpl == -1){
- if(debug)
- printf("@@@@ Bad TX PL: %s\n", myrpt->txpl);
- return -1;
- }
- return 0;
-}
-
-static int check_freq_kenwood(int m, int d, int *defmode)
-{
- int dflmd = REM_MODE_FM;
-
- if (m == 144){ /* 2 meters */
- if(d < 10100)
- return -1;
- }
- else if((m >= 145) && (m < 148)){
- ;
- }
- else if((m >= 430) && (m < 450)){ /* 70 centimeters */
- ;
- }
- else
- return -1;
-
- if(defmode)
- *defmode = dflmd;
-
-
- return 0;
-}
-
-
-/* Check for valid rbi frequency */
-/* Hard coded limits now, configurable later, maybe? */
-
-static int check_freq_rbi(int m, int d, int *defmode)
-{
- int dflmd = REM_MODE_FM;
-
- if(m == 50){ /* 6 meters */
- if(d < 10100)
- return -1;
- }
- else if((m >= 51) && ( m < 54)){
- ;
- }
- else if(m == 144){ /* 2 meters */
- if(d < 10100)
- return -1;
- }
- else if((m >= 145) && (m < 148)){
- ;
- }
- else if((m >= 222) && (m < 225)){ /* 1.25 meters */
- ;
- }
- else if((m >= 430) && (m < 450)){ /* 70 centimeters */
- ;
- }
- else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */
- ;
- }
- else
- return -1;
-
- if(defmode)
- *defmode = dflmd;
-
-
- return 0;
-}
-
-/*
- * Convert decimals of frequency to int
- */
-
-static int decimals2int(char *fraction)
-{
- int i;
- char len = strlen(fraction);
- int multiplier = 100000;
- int res = 0;
-
- if(!len)
- return 0;
- for( i = 0 ; i < len ; i++, multiplier /= 10)
- res += (fraction[i] - '0') * multiplier;
- return res;
-}
-
-
-/*
-* Split frequency into mhz and decimals
-*/
-
-static int split_freq(char *mhz, char *decimals, char *freq)
-{
- char freq_copy[MAXREMSTR];
- char *decp;
-
- decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
- if(decp){
- *decp++ = 0;
- strncpy(mhz, freq_copy, MAXREMSTR);
- strcpy(decimals, "00000");
- strncpy(decimals, decp, strlen(decp));
- decimals[5] = 0;
- return 0;
- }
- else
- return -1;
-
-}
-
-/*
-* Split ctcss frequency into hertz and decimal
-*/
-
-static int split_ctcss_freq(char *hertz, char *decimal, char *freq)
-{
- char freq_copy[MAXREMSTR];
- char *decp;
-
- decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
- if(decp){
- *decp++ = 0;
- strncpy(hertz, freq_copy, MAXREMSTR);
- strncpy(decimal, decp, strlen(decp));
- decimal[strlen(decp)] = '\0';
- return 0;
- }
- else
- return -1;
-}
-
-
-
-/*
-* FT-897 I/O handlers
-*/
-
-/* Check to see that the frequency is valid */
-/* Hard coded limits now, configurable later, maybe? */
-
-
-static int check_freq_ft897(int m, int d, int *defmode)
-{
- int dflmd = REM_MODE_FM;
-
- if(m == 1){ /* 160 meters */
- dflmd = REM_MODE_LSB;
- if(d < 80000)
- return -1;
- }
- else if(m == 3){ /* 80 meters */
- dflmd = REM_MODE_LSB;
- if(d < 50000)
- return -1;
- }
- else if(m == 7){ /* 40 meters */
- dflmd = REM_MODE_LSB;
- if(d > 30000)
- return -1;
- }
- else if(m == 14){ /* 20 meters */
- dflmd = REM_MODE_USB;
- if(d > 35000)
- return -1;
- }
- else if(m == 18){ /* 17 meters */
- dflmd = REM_MODE_USB;
- if((d < 6800) || (d > 16800))
- return -1;
- }
- else if(m == 21){ /* 15 meters */
- dflmd = REM_MODE_USB;
- if((d < 20000) || (d > 45000))
- return -1;
- }
- else if(m == 24){ /* 12 meters */
- dflmd = REM_MODE_USB;
- if((d < 89000) || (d > 99000))
- return -1;
- }
- else if(m == 28){ /* 10 meters */
- dflmd = REM_MODE_USB;
- }
- else if(m == 29){
- if(d >= 51000)
- dflmd = REM_MODE_FM;
- else
- dflmd = REM_MODE_USB;
- if(d > 70000)
- return -1;
- }
- else if(m == 50){ /* 6 meters */
- if(d >= 30000)
- dflmd = REM_MODE_FM;
- else
- dflmd = REM_MODE_USB;
-
- }
- else if((m >= 51) && ( m < 54)){
- dflmd = REM_MODE_FM;
- }
- else if(m == 144){ /* 2 meters */
- if(d >= 30000)
- dflmd = REM_MODE_FM;
- else
- dflmd = REM_MODE_USB;
- }
- else if((m >= 145) && (m < 148)){
- dflmd = REM_MODE_FM;
- }
- else if((m >= 430) && (m < 450)){ /* 70 centimeters */
- if(m < 438)
- dflmd = REM_MODE_USB;
- else
- dflmd = REM_MODE_FM;
- ;
- }
- else
- return -1;
-
- if(defmode)
- *defmode = dflmd;
-
- return 0;
-}
-
-/*
-* Set a new frequency for the FT897
-*/
-
-static int set_freq_ft897(struct rpt *myrpt, char *newfreq)
-{
- unsigned char cmdstr[5];
- int fd,m,d;
- char mhz[MAXREMSTR];
- char decimals[MAXREMSTR];
-
- fd = 0;
- if(debug)
- printf("New frequency: %s\n",newfreq);
-
- if(split_freq(mhz, decimals, newfreq))
- return -1;
-
- m = atoi(mhz);
- d = atoi(decimals);
-
- /* The FT-897 likes packed BCD frequencies */
-
- cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10); /* 100MHz 10Mhz */
- cmdstr[1] = ((m % 10) << 4) + (d / 10000); /* 1MHz 100KHz */
- cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100); /* 10KHz 1KHz */
- cmdstr[3] = (((d % 100)/10) << 4) + (d % 10); /* 100Hz 10Hz */
- cmdstr[4] = 0x01; /* command */
-
- return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
-
-}
-
-/* ft-897 simple commands */
-
-static int simple_command_ft897(struct rpt *myrpt, char command)
-{
- unsigned char cmdstr[5];
-
- memset(cmdstr, 0, 5);
-
- cmdstr[4] = command;
-
- return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
-
-}
-
-/* ft-897 offset */
-
-static int set_offset_ft897(struct rpt *myrpt, char offset)
-{
- unsigned char cmdstr[5];
-
- memset(cmdstr, 0, 5);
-
- switch(offset){
- case REM_SIMPLEX:
- cmdstr[0] = 0x89;
- break;
-
- case REM_MINUS:
- cmdstr[0] = 0x09;
- break;
-
- case REM_PLUS:
- cmdstr[0] = 0x49;
- break;
-
- default:
- return -1;
- }
-
- cmdstr[4] = 0x09;
-
- return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
-}
-
-/* ft-897 mode */
-
-static int set_mode_ft897(struct rpt *myrpt, char newmode)
-{
- unsigned char cmdstr[5];
-
- memset(cmdstr, 0, 5);
-
- switch(newmode){
- case REM_MODE_FM:
- cmdstr[0] = 0x08;
- break;
-
- case REM_MODE_USB:
- cmdstr[0] = 0x01;
- break;
-
- case REM_MODE_LSB:
- cmdstr[0] = 0x00;
- break;
-
- case REM_MODE_AM:
- cmdstr[0] = 0x04;
- break;
-
- default:
- return -1;
- }
- cmdstr[4] = 0x07;
-
- return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
-}
-
-/* Set tone encode and decode modes */
-
-static int set_ctcss_mode_ft897(struct rpt *myrpt, char txplon, char rxplon)
-{
- unsigned char cmdstr[5];
-
- memset(cmdstr, 0, 5);
-
- if(rxplon && txplon)
- cmdstr[0] = 0x2A; /* Encode and Decode */
- else if (!rxplon && txplon)
- cmdstr[0] = 0x4A; /* Encode only */
- else if (rxplon && !txplon)
- cmdstr[0] = 0x3A; /* Encode only */
- else
- cmdstr[0] = 0x8A; /* OFF */
-
- cmdstr[4] = 0x0A;
-
- return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
-}
-
-
-/* Set transmit and receive ctcss tone frequencies */
-
-static int set_ctcss_freq_ft897(struct rpt *myrpt, char *txtone, char *rxtone)
-{
- unsigned char cmdstr[5];
- char hertz[MAXREMSTR],decimal[MAXREMSTR];
- int h,d;
-
- memset(cmdstr, 0, 5);
-
- if(split_ctcss_freq(hertz, decimal, txtone))
- return -1;
-
- h = atoi(hertz);
- d = atoi(decimal);
-
- cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10;
- cmdstr[1] = ((h % 10) << 4) + (d % 10);
-
- if(rxtone){
-
- if(split_ctcss_freq(hertz, decimal, rxtone))
- return -1;
-
- h = atoi(hertz);
- d = atoi(decimal);
-
- cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10;
- cmdstr[3] = ((h % 10) << 4) + (d % 10);
- }
- cmdstr[4] = 0x0B;
-
- return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
-}
-
-
-
-static int set_ft897(struct rpt *myrpt)
-{
- int res;
-
- if(debug)
- printf("@@@@ lock on\n");
-
- res = simple_command_ft897(myrpt, 0x00); /* LOCK on */
-
- if(debug)
- printf("@@@@ ptt off\n");
-
- if(!res)
- res = simple_command_ft897(myrpt, 0x88); /* PTT off */
-
- if(debug)
- printf("Modulation mode\n");
-
- if(!res)
- res = set_mode_ft897(myrpt, myrpt->remmode); /* Modulation mode */
-
- if(debug)
- printf("Split off\n");
-
- if(!res)
- simple_command_ft897(myrpt, 0x82); /* Split off */
-
- if(debug)
- printf("Frequency\n");
-
- if(!res)
- res = set_freq_ft897(myrpt, myrpt->freq); /* Frequency */
- if((myrpt->remmode == REM_MODE_FM)){
- if(debug)
- printf("Offset\n");
- if(!res)
- res = set_offset_ft897(myrpt, myrpt->offset); /* Offset if FM */
- if((!res)&&(myrpt->rxplon || myrpt->txplon)){
- if(debug)
- printf("CTCSS tone freqs.\n");
- res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */
- }
- if(!res){
- if(debug)
- printf("CTCSS mode\n");
- res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
- }
- }
- if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){
- if(debug)
- printf("Clarifier off\n");
- simple_command_ft897(myrpt, 0x85); /* Clarifier off if LSB or USB */
- }
- return res;
-}
-
-static int closerem_ft897(struct rpt *myrpt)
-{
- simple_command_ft897(myrpt, 0x88); /* PTT off */
- return 0;
-}
-
-/*
-* Bump frequency up or down by a small amount
-* Return 0 if the new frequnecy is valid, or -1 if invalid
-* Interval is in Hz, resolution is 10Hz
-*/
-
-static int multimode_bump_freq_ft897(struct rpt *myrpt, int interval)
-{
- int m,d;
- char mhz[MAXREMSTR], decimals[MAXREMSTR];
-
- if(debug)
- printf("Before bump: %s\n", myrpt->freq);
-
- if(split_freq(mhz, decimals, myrpt->freq))
- return -1;
-
- m = atoi(mhz);
- d = atoi(decimals);
-
- d += (interval / 10); /* 10Hz resolution */
- if(d < 0){
- m--;
- d += 100000;
- }
- else if(d >= 100000){
- m++;
- d -= 100000;
- }
-
- if(check_freq_ft897(m, d, NULL)){
- if(debug)
- printf("Bump freq invalid\n");
- return -1;
- }
-
- snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
-
- if(debug)
- printf("After bump: %s\n", myrpt->freq);
-
- return set_freq_ft897(myrpt, myrpt->freq);
-}
-
-
-
-/*
-* IC-706 I/O handlers
-*/
-
-/* Check to see that the frequency is valid */
-/* Hard coded limits now, configurable later, maybe? */
-
-
-static int check_freq_ic706(int m, int d, int *defmode)
-{
- int dflmd = REM_MODE_FM;
-
- if(m == 1){ /* 160 meters */
- dflmd = REM_MODE_LSB;
- if(d < 80000)
- return -1;
- }
- else if(m == 3){ /* 80 meters */
- dflmd = REM_MODE_LSB;
- if(d < 50000)
- return -1;
- }
- else if(m == 7){ /* 40 meters */
- dflmd = REM_MODE_LSB;
- if(d > 30000)
- return -1;
- }
- else if(m == 14){ /* 20 meters */
- dflmd = REM_MODE_USB;
- if(d > 35000)
- return -1;
- }
- else if(m == 18){ /* 17 meters */
- dflmd = REM_MODE_USB;
- if((d < 6800) || (d > 16800))
- return -1;
- }
- else if(m == 21){ /* 15 meters */
- dflmd = REM_MODE_USB;
- if((d < 20000) || (d > 45000))
- return -1;
- }
- else if(m == 24){ /* 12 meters */
- dflmd = REM_MODE_USB;
- if((d < 89000) || (d > 99000))
- return -1;
- }
- else if(m == 28){ /* 10 meters */
- dflmd = REM_MODE_USB;
- }
- else if(m == 29){
- if(d >= 51000)
- dflmd = REM_MODE_FM;
- else
- dflmd = REM_MODE_USB;
- if(d > 70000)
- return -1;
- }
- else if(m == 50){ /* 6 meters */
- if(d >= 30000)
- dflmd = REM_MODE_FM;
- else
- dflmd = REM_MODE_USB;
-
- }
- else if((m >= 51) && ( m < 54)){
- dflmd = REM_MODE_FM;
- }
- else if(m == 144){ /* 2 meters */
- if(d >= 30000)
- dflmd = REM_MODE_FM;
- else
- dflmd = REM_MODE_USB;
- }
- else if((m >= 145) && (m < 148)){
- dflmd = REM_MODE_FM;
- }
- else if((m >= 430) && (m < 450)){ /* 70 centimeters */
- if(m < 438)
- dflmd = REM_MODE_USB;
- else
- dflmd = REM_MODE_FM;
- ;
- }
- else
- return -1;
-
- if(defmode)
- *defmode = dflmd;
-
- return 0;
-}
-
-/* take a PL frequency and turn it into a code */
-static int ic706_pltocode(char *str)
-{
-int i;
-char *s;
-
- s = strchr(str,'.');
- i = 0;
- if (s) i = atoi(s + 1);
- i += atoi(str) * 10;
- switch(i)
- {
- case 670:
- return 0;
- case 693:
- return 1;
- case 719:
- return 2;
- case 744:
- return 3;
- case 770:
- return 4;
- case 797:
- return 5;
- case 825:
- return 6;
- case 854:
- return 7;
- case 885:
- return 8;
- case 915:
- return 9;
- case 948:
- return 10;
- case 974:
- return 11;
- case 1000:
- return 12;
- case 1035:
- return 13;
- case 1072:
- return 14;
- case 1109:
- return 15;
- case 1148:
- return 16;
- case 1188:
- return 17;
- case 1230:
- return 18;
- case 1273:
- return 19;
- case 1318:
- return 20;
- case 1365:
- return 21;
- case 1413:
- return 22;
- case 1462:
- return 23;
- case 1514:
- return 24;
- case 1567:
- return 25;
- case 1598:
- return 26;
- case 1622:
- return 27;
- case 1655:
- return 28;
- case 1679:
- return 29;
- case 1713:
- return 30;
- case 1738:
- return 31;
- case 1773:
- return 32;
- case 1799:
- return 33;
- case 1835:
- return 34;
- case 1862:
- return 35;
- case 1899:
- return 36;
- case 1928:
- return 37;
- case 1966:
- return 38;
- case 1995:
- return 39;
- case 2035:
- return 40;
- case 2065:
- return 41;
- case 2107:
- return 42;
- case 2181:
- return 43;
- case 2257:
- return 44;
- case 2291:
- return 45;
- case 2336:
- return 46;
- case 2418:
- return 47;
- case 2503:
- return 48;
- case 2541:
- return 49;
- }
- return -1;
-}
-
-/* ic-706 simple commands */
-
-static int simple_command_ic706(struct rpt *myrpt, char command, char subcommand)
-{
- unsigned char cmdstr[10];
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = command;
- cmdstr[5] = subcommand;
- cmdstr[6] = 0xfd;
-
- return(civ_cmd(myrpt,cmdstr,7));
-}
-
-/*
-* Set a new frequency for the ic706
-*/
-
-static int set_freq_ic706(struct rpt *myrpt, char *newfreq)
-{
- unsigned char cmdstr[20];
- char mhz[MAXREMSTR], decimals[MAXREMSTR];
- int fd,m,d;
-
- fd = 0;
- if(debug)
- printf("New frequency: %s\n",newfreq);
-
- if(split_freq(mhz, decimals, newfreq))
- return -1;
-
- m = atoi(mhz);
- d = atoi(decimals);
-
- /* The ic-706 likes packed BCD frequencies */
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 5;
- cmdstr[5] = ((d % 10) << 4);
- cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
- cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
- cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
- cmdstr[9] = (m / 100);
- cmdstr[10] = 0xfd;
-
- return(civ_cmd(myrpt,cmdstr,11));
-}
-
-/* ic-706 offset */
-
-static int set_offset_ic706(struct rpt *myrpt, char offset)
-{
- unsigned char c;
-
- switch(offset){
- case REM_SIMPLEX:
- c = 0x10;
- break;
-
- case REM_MINUS:
- c = 0x11;
- break;
-
- case REM_PLUS:
- c = 0x12;
- break;
-
- default:
- return -1;
- }
-
- return simple_command_ic706(myrpt,0x0f,c);
-
-}
-
-/* ic-706 mode */
-
-static int set_mode_ic706(struct rpt *myrpt, char newmode)
-{
- unsigned char c;
-
- switch(newmode){
- case REM_MODE_FM:
- c = 5;
- break;
-
- case REM_MODE_USB:
- c = 1;
- break;
-
- case REM_MODE_LSB:
- c = 0;
- break;
-
- case REM_MODE_AM:
- c = 2;
- break;
-
- default:
- return -1;
- }
- return simple_command_ic706(myrpt,6,c);
-}
-
-/* Set tone encode and decode modes */
-
-static int set_ctcss_mode_ic706(struct rpt *myrpt, char txplon, char rxplon)
-{
- unsigned char cmdstr[10];
- int rv;
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 0x16;
- cmdstr[5] = 0x42;
- cmdstr[6] = (txplon != 0);
- cmdstr[7] = 0xfd;
-
- rv = civ_cmd(myrpt,cmdstr,8);
- if (rv) return(-1);
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 0x16;
- cmdstr[5] = 0x43;
- cmdstr[6] = (rxplon != 0);
- cmdstr[7] = 0xfd;
-
- return(civ_cmd(myrpt,cmdstr,8));
-}
-
-#if 0
-/* Set transmit and receive ctcss tone frequencies */
-
-static int set_ctcss_freq_ic706(struct rpt *myrpt, char *txtone, char *rxtone)
-{
- unsigned char cmdstr[10];
- char hertz[MAXREMSTR],decimal[MAXREMSTR];
- int h,d,rv;
-
- memset(cmdstr, 0, 5);
-
- if(split_ctcss_freq(hertz, decimal, txtone))
- return -1;
-
- h = atoi(hertz);
- d = atoi(decimal);
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 0x1b;
- cmdstr[5] = 0;
- cmdstr[6] = ((h / 100) << 4) + (h % 100)/ 10;
- cmdstr[7] = ((h % 10) << 4) + (d % 10);
- cmdstr[8] = 0xfd;
-
- rv = civ_cmd(myrpt,cmdstr,9);
- if (rv) return(-1);
-
- if (!rxtone) return(0);
-
- if(split_ctcss_freq(hertz, decimal, rxtone))
- return -1;
-
- h = atoi(hertz);
- d = atoi(decimal);
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 0x1b;
- cmdstr[5] = 1;
- cmdstr[6] = ((h / 100) << 4) + (h % 100)/ 10;
- cmdstr[7] = ((h % 10) << 4) + (d % 10);
- cmdstr[8] = 0xfd;
- return(civ_cmd(myrpt,cmdstr,9));
-}
-#endif
-
-static int vfo_ic706(struct rpt *myrpt)
-{
- unsigned char cmdstr[10];
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 7;
- cmdstr[5] = 0xfd;
-
- return(civ_cmd(myrpt,cmdstr,6));
-}
-
-static int mem2vfo_ic706(struct rpt *myrpt)
-{
- unsigned char cmdstr[10];
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 0x0a;
- cmdstr[5] = 0xfd;
-
- return(civ_cmd(myrpt,cmdstr,6));
-}
-
-static int select_mem_ic706(struct rpt *myrpt, int slot)
-{
- unsigned char cmdstr[10];
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 8;
- cmdstr[5] = 0;
- cmdstr[6] = ((slot / 10) << 4) + (slot % 10);
- cmdstr[7] = 0xfd;
-
- return(civ_cmd(myrpt,cmdstr,8));
-}
-
-static int set_ic706(struct rpt *myrpt)
-{
- int res = 0,i;
-
- if(debug)
- printf("Set to VFO A\n");
-
- if (!res)
- res = simple_command_ic706(myrpt,7,0);
-
-
- if((myrpt->remmode == REM_MODE_FM))
- {
- i = ic706_pltocode(myrpt->rxpl);
- if (i == -1) return -1;
- if(debug)
- printf("Select memory number\n");
- if (!res)
- res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET);
- if(debug)
- printf("Transfer memory to VFO\n");
- if (!res)
- res = mem2vfo_ic706(myrpt);
- }
-
- if(debug)
- printf("Set to VFO\n");
-
- if (!res)
- res = vfo_ic706(myrpt);
-
- if(debug)
- printf("Modulation mode\n");
-
- if (!res)
- res = set_mode_ic706(myrpt, myrpt->remmode); /* Modulation mode */
-
- if(debug)
- printf("Split off\n");
-
- if(!res)
- simple_command_ic706(myrpt, 0x82,0); /* Split off */
-
- if(debug)
- printf("Frequency\n");
-
- if(!res)
- res = set_freq_ic706(myrpt, myrpt->freq); /* Frequency */
- if((myrpt->remmode == REM_MODE_FM)){
- if(debug)
- printf("Offset\n");
- if(!res)
- res = set_offset_ic706(myrpt, myrpt->offset); /* Offset if FM */
- if(!res){
- if(debug)
- printf("CTCSS mode\n");
- res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
- }
- }
- return res;
-}
-
-/*
-* Bump frequency up or down by a small amount
-* Return 0 if the new frequnecy is valid, or -1 if invalid
-* Interval is in Hz, resolution is 10Hz
-*/
-
-static int multimode_bump_freq_ic706(struct rpt *myrpt, int interval)
-{
- int m,d;
- char mhz[MAXREMSTR], decimals[MAXREMSTR];
- unsigned char cmdstr[20];
-
- if(debug)
- printf("Before bump: %s\n", myrpt->freq);
-
- if(split_freq(mhz, decimals, myrpt->freq))
- return -1;
-
- m = atoi(mhz);
- d = atoi(decimals);
-
- d += (interval / 10); /* 10Hz resolution */
- if(d < 0){
- m--;
- d += 100000;
- }
- else if(d >= 100000){
- m++;
- d -= 100000;
- }
-
- if(check_freq_ic706(m, d, NULL)){
- if(debug)
- printf("Bump freq invalid\n");
- return -1;
- }
-
- snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
-
- if(debug)
- printf("After bump: %s\n", myrpt->freq);
-
- /* The ic-706 likes packed BCD frequencies */
-
- cmdstr[0] = cmdstr[1] = 0xfe;
- cmdstr[2] = myrpt->p.civaddr;
- cmdstr[3] = 0xe0;
- cmdstr[4] = 0;
- cmdstr[5] = ((d % 10) << 4);
- cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
- cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
- cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
- cmdstr[9] = (m / 100);
- cmdstr[10] = 0xfd;
-
- return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0));
-}
-
-
-
-/*
-* Dispatch to correct I/O handler
-*/
-
-static int setrem(struct rpt *myrpt)
-{
-char str[300];
-char *offsets[] = {"MINUS","SIMPLEX","PLUS"};
-char *powerlevels[] = {"LOW","MEDIUM","HIGH"};
-char *modes[] = {"FM","USB","LSB","AM"};
-int res = -1;
-
- if (myrpt->p.archivedir)
- {
- sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq,
- modes[(int)myrpt->remmode],
- myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset],
- powerlevels[(int)myrpt->powerlevel],myrpt->txplon,
- myrpt->rxplon);
- donodelog(myrpt,str);
- }
- if(!strcmp(myrpt->remote, remote_rig_ft897))
- {
- rpt_telemetry(myrpt,SETREMOTE,NULL);
- res = 0;
- }
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- {
- rpt_telemetry(myrpt,SETREMOTE,NULL);
- res = 0;
- }
- else if(!strcmp(myrpt->remote, remote_rig_rbi))
- {
- res = setrbi_check(myrpt);
- if (!res)
- {
- rpt_telemetry(myrpt,SETREMOTE,NULL);
- res = 0;
- }
- }
- else if(!strcmp(myrpt->remote, remote_rig_kenwood)) {
- rpt_telemetry(myrpt,SETREMOTE,NULL);
- res = 0;
- }
- else
- res = 0;
-
- if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name);
-
- return res;
-}
-
-static int closerem(struct rpt *myrpt)
-{
- if(!strcmp(myrpt->remote, remote_rig_ft897))
- return closerem_ft897(myrpt);
- else
- return 0;
-}
-
-/*
-* Dispatch to correct RX frequency checker
-*/
-
-static int check_freq(struct rpt *myrpt, int m, int d, int *defmode)
-{
- if(!strcmp(myrpt->remote, remote_rig_ft897))
- return check_freq_ft897(m, d, defmode);
- else if(!strcmp(myrpt->remote, remote_rig_ic706))
- return check_freq_ic706(m, d, defmode);
- else if(!strcmp(myrpt->remote, remote_rig_rbi))
- return check_freq_rbi(m, d, defmode);
- else if(!strcmp(myrpt->remote, remote_rig_kenwood))
- return check_freq_kenwood(m, d, defmode);
- else
- return -1;
-}
-
-/*
- * Check TX frequency before transmitting
- */
-
-static char check_tx_freq(struct rpt *myrpt)
-{
- int i;
- int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals;
- char radio_mhz_char[MAXREMSTR];
- char radio_decimals_char[MAXREMSTR];
- char limit_mhz_char[MAXREMSTR];
- char limit_decimals_char[MAXREMSTR];
- char limits[256];
- char *limit_ranges[40];
- struct ast_variable *limitlist;
-
-
- /* Must have user logged in and tx_limits defined */
-
- if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){
- if(debug > 3){
- ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in\n");
- }
- return 1; /* Assume it's ok otherwise */
- }
-
- /* Retrieve the band table for the loginlevel */
- limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname);
-
- if(!limitlist){
- ast_log(LOG_WARNING, "No entries in %s band table stanza\n", myrpt->p.txlimitsstanzaname);
- return 0;
- }
-
- split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq);
- radio_mhz = atoi(radio_mhz_char);
- radio_decimals = decimals2int(radio_decimals_char);
-
-
- if(debug > 3){
- ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel);
- }
-
- /* Find our entry */
-
- for(;limitlist; limitlist=limitlist->next){
- if(!strcmp(limitlist->name, myrpt->loginlevel))
- break;
- }
-
- if(!limitlist){
- ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname);
- return 0;
- }
-
- if(debug > 3){
- ast_log(LOG_NOTICE, "Auth %s = %s\n", limitlist->name, limitlist->value);
- }
-
- /* Parse the limits */
-
- strncpy(limits, limitlist->value, 256);
- limits[255] = 0;
- finddelim(limits, limit_ranges, 40);
- for(i = 0; i < 40 && limit_ranges[i] ; i++){
- char range[40];
- char *r,*s;
- strncpy(range, limit_ranges[i], 40);
- range[39] = 0;
- if(debug > 3){
- ast_log(LOG_NOTICE, "Checking to see if %s is within limits of %s\n", myrpt->freq, range);
- }
-
- r = strchr(range, '-');
- if(!r){
- ast_log(LOG_WARNING, "Malformed range in %s tx band table entry\n", limitlist->name);
- return 0;
- }
- *r++ = 0;
- s = eatwhite(range);
- r = eatwhite(r);
- split_freq(limit_mhz_char, limit_decimals_char, s);
- llimit_mhz = atoi(limit_mhz_char);
- llimit_decimals = decimals2int(limit_decimals_char);
- split_freq(limit_mhz_char, limit_decimals_char, r);
- ulimit_mhz = atoi(limit_mhz_char);
- ulimit_decimals = decimals2int(limit_decimals_char);
-
- if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){
- if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */
- if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */
- if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */
- if(radio_decimals <= ulimit_decimals){
- return 1;
- }
- else{
- if(debug > 3)
- ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n");
- return 0;
- }
- }
- else{
- return 1;
- }
- }
- else{ /* Is below llimit decimals */
- if(debug > 3)
- ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n");
- return 0;
- }
- }
- else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */
- if(radio_decimals <= ulimit_decimals){
- return 1;
- }
- else{ /* Is above ulimit decimals */
- if(debug > 3)
- ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n");
- return 0;
- }
- }
- else /* CASE 3: TX freq within a multi-Mhz band and ok */
- return 1;
- }
- }
- if(debug > 3) /* No match found in TX band table */
- ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 4\n");
- return 0;
-}
-
-
-/*
-* Dispatch to correct frequency bumping function
-*/
-
-static int multimode_bump_freq(struct rpt *myrpt, int interval)
-{
- if(!strcmp(myrpt->remote, remote_rig_ft897))
- return multimode_bump_freq_ft897(myrpt, interval);
- else if(!strcmp(myrpt->remote, remote_rig_ic706))
- return multimode_bump_freq_ic706(myrpt, interval);
- else
- return -1;
-}
-
-
-/*
-* Queue announcment that scan has been stopped
-*/
-
-static void stop_scan(struct rpt *myrpt)
-{
- myrpt->hfscanstop = 1;
- rpt_telemetry(myrpt,SCAN,0);
-}
-
-/*
-* This is called periodically when in scan mode
-*/
-
-
-static int service_scan(struct rpt *myrpt)
-{
- int res, interval;
- char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0;
-
- switch(myrpt->hfscanmode){
-
- case HF_SCAN_DOWN_SLOW:
- interval = -10; /* 100Hz /sec */
- break;
-
- case HF_SCAN_DOWN_QUICK:
- interval = -50; /* 500Hz /sec */
- break;
-
- case HF_SCAN_DOWN_FAST:
- interval = -200; /* 2KHz /sec */
- break;
-
- case HF_SCAN_UP_SLOW:
- interval = 10; /* 100Hz /sec */
- break;
-
- case HF_SCAN_UP_QUICK:
- interval = 50; /* 500 Hz/sec */
- break;
-
- case HF_SCAN_UP_FAST:
- interval = 200; /* 2KHz /sec */
- break;
-
- default:
- myrpt->hfscanmode = 0; /* Huh? */
- return -1;
- }
-
- res = split_freq(mhz, decimals, myrpt->freq);
-
- if(!res){
- k100 =decimals[0];
- k10 = decimals[1];
- res = multimode_bump_freq(myrpt, interval);
- }
-
- if(!res)
- res = split_freq(mhz, decimals, myrpt->freq);
-
-
- if(res){
- myrpt->hfscanmode = 0;
- myrpt->hfscanstatus = -2;
- return -1;
- }
-
- /* Announce 10KHz boundaries */
- if(k10 != decimals[1]){
- int myhund = (interval < 0) ? k100 : decimals[0];
- int myten = (interval < 0) ? k10 : decimals[1];
- myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10;
- } else myrpt->hfscanstatus = 0;
- return res;
-
-}
-
-/*
- * Retrieve a memory channel
- * Return 0 if sucessful,
- * -1 if channel not found,
- * 1 if parse error
- */
-
-static int retreive_memory(struct rpt *myrpt, char *memory)
-{
- char tmp[30], *s, *s1, *val;
-
- val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory);
- if (!val){
- return -1;
- }
- strncpy(tmp,val,sizeof(tmp) - 1);
- tmp[sizeof(tmp)-1] = 0;
-
- s = strchr(tmp,',');
- if (!s)
- return 1;
- *s++ = 0;
- s1 = strchr(s,',');
- if (!s1)
- return 1;
- *s1++ = 0;
- strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1);
- strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1);
- strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1);
- myrpt->remmode = REM_MODE_FM;
- myrpt->offset = REM_SIMPLEX;
- myrpt->powerlevel = REM_MEDPWR;
- myrpt->txplon = myrpt->rxplon = 0;
- while(*s1){
- switch(*s1++){
- case 'A':
- case 'a':
- strcpy(myrpt->rxpl, "100.0");
- strcpy(myrpt->txpl, "100.0");
- myrpt->remmode = REM_MODE_AM;
- break;
- case 'B':
- case 'b':
- strcpy(myrpt->rxpl, "100.0");
- strcpy(myrpt->txpl, "100.0");
- myrpt->remmode = REM_MODE_LSB;
- break;
- case 'F':
- myrpt->remmode = REM_MODE_FM;
- break;
- case 'L':
- case 'l':
- myrpt->powerlevel = REM_LOWPWR;
- break;
- case 'H':
- case 'h':
- myrpt->powerlevel = REM_HIPWR;
- break;
-
- case 'M':
- case 'm':
- myrpt->powerlevel = REM_MEDPWR;
- break;
-
- case '-':
- myrpt->offset = REM_MINUS;
- break;
-
- case '+':
- myrpt->offset = REM_PLUS;
- break;
-
- case 'S':
- case 's':
- myrpt->offset = REM_SIMPLEX;
- break;
-
- case 'T':
- case 't':
- myrpt->txplon = 1;
- break;
-
- case 'R':
- case 'r':
- myrpt->rxplon = 1;
- break;
-
- case 'U':
- case 'u':
- strcpy(myrpt->rxpl, "100.0");
- strcpy(myrpt->txpl, "100.0");
- myrpt->remmode = REM_MODE_USB;
- break;
- default:
- return 1;
- }
- }
- return 0;
-}
-
-
-
-/*
-* Remote base function
-*/
-
-static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
-{
- char *s,*s1,*s2;
- int i,j,p,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode;
- char multimode = 0;
- char oc,*cp,*cp1,*cp2;
- char tmp[20], freq[20] = "", savestr[20] = "";
- char mhz[MAXREMSTR], decimals[MAXREMSTR];
-
- if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK))
- return DC_ERROR;
-
- p = myatoi(param);
-
- if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel &&
- (!myrpt->loginlevel[0])) return DC_ERROR;
- multimode = multimode_capable(myrpt);
-
- switch(p){
-
- case 1: /* retrieve memory */
- if(strlen(digitbuf) < 2) /* needs 2 digits */
- break;
-
- for(i = 0 ; i < 2 ; i++){
- if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
- return DC_ERROR;
- }
-
- r = retreive_memory(myrpt, digitbuf);
- if (r < 0){
- rpt_telemetry(myrpt,MEMNOTFOUND,NULL);
- return DC_COMPLETE;
- }
- if (r > 0){
- return DC_ERROR;
- }
- if (setrem(myrpt) == -1) return DC_ERROR;
- return DC_COMPLETE;
-
- case 2: /* set freq and offset */
-
-
- for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */
- if(digitbuf[i] == '*'){
- j++;
- continue;
- }
- if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
- goto invalid_freq;
- else{
- if(j == 0)
- l++; /* # of digits before first * */
- if(j == 1)
- k++; /* # of digits after first * */
- }
- }
-
- i = strlen(digitbuf) - 1;
- if(multimode){
- if((j > 2) || (l > 3) || (k > 6))
- goto invalid_freq; /* &^@#! */
- }
- else{
- if((j > 2) || (l > 4) || (k > 3))
- goto invalid_freq; /* &^@#! */
- }
-
- /* Wait for M+*K+* */
-
- if(j < 2)
- break; /* Not yet */
-
- /* We have a frequency */
-
- strncpy(tmp, digitbuf ,sizeof(tmp) - 1);
-
- s = tmp;
- s1 = strsep(&s, "*"); /* Pick off MHz */
- s2 = strsep(&s,"*"); /* Pick off KHz and Hz */
- ls2 = strlen(s2);
-
- switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */
- case 1:
- ht = 0;
- k = 100 * atoi(s2);
- break;
-
- case 2:
- ht = 0;
- k = 10 * atoi(s2);
- break;
-
- case 3:
- if(!multimode){
- if((s2[2] != '0')&&(s2[2] != '5'))
- goto invalid_freq;
- }
- ht = 0;
- k = atoi(s2);
- break;
- case 4:
- k = atoi(s2)/10;
- ht = 10 * (atoi(s2+(ls2-1)));
- break;
-
- case 5:
- k = atoi(s2)/100;
- ht = (atoi(s2+(ls2-2)));
- break;
-
- default:
- goto invalid_freq;
- }
-
- /* Check frequency for validity and establish a default mode */
-
- snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht);
-
- if(debug)
- printf("New frequency: %s\n", freq);
-
- split_freq(mhz, decimals, freq);
- m = atoi(mhz);
- d = atoi(decimals);
-
- if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */
- goto invalid_freq;
-
-
- if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */
- break; /* Not yet */
-
-
- offset = REM_SIMPLEX; /* Assume simplex */
-
- if(defmode == REM_MODE_FM){
- oc = *s; /* Pick off offset */
-
- if (oc){
- switch(oc){
- case '1':
- offset = REM_MINUS;
- break;
-
- case '2':
- offset = REM_SIMPLEX;
- break;
-
- case '3':
- offset = REM_PLUS;
- break;
-
- default:
- goto invalid_freq;
- }
- }
- }
- offsave = myrpt->offset;
- modesave = myrpt->remmode;
- strncpy(savestr, myrpt->freq, sizeof(savestr) - 1);
- strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
- myrpt->offset = offset;
- myrpt->remmode = defmode;
-
- if (setrem(myrpt) == -1){
- myrpt->offset = offsave;
- myrpt->remmode = modesave;
- strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1);
- goto invalid_freq;
- }
-
- return DC_COMPLETE;
-
-invalid_freq:
- rpt_telemetry(myrpt,INVFREQ,NULL);
- return DC_ERROR;
-
- case 3: /* set rx PL tone */
- for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
- if(digitbuf[i] == '*'){
- j++;
- continue;
- }
- if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
- return DC_ERROR;
- else{
- if(j)
- l++;
- else
- k++;
- }
- }
- if((j > 1) || (k > 3) || (l > 1))
- return DC_ERROR; /* &$@^! */
- i = strlen(digitbuf) - 1;
- if((j != 1) || (k < 2)|| (l != 1))
- break; /* Not yet */
- if(debug)
- printf("PL digits entered %s\n", digitbuf);
-
- strncpy(tmp, digitbuf, sizeof(tmp) - 1);
- /* see if we have at least 1 */
- s = strchr(tmp,'*');
- if(s)
- *s = '.';
- strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1);
- strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1);
- if(!strcmp(myrpt->remote, remote_rig_rbi))
- {
- strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
- }
- if (setrem(myrpt) == -1){
- strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1);
- return DC_ERROR;
- }
-
-
- return DC_COMPLETE;
-
- case 4: /* set tx PL tone */
- /* cant set tx tone on RBI (rx tone does both) */
- if(!strcmp(myrpt->remote, remote_rig_rbi))
- return DC_ERROR;
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- return DC_ERROR;
- for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
- if(digitbuf[i] == '*'){
- j++;
- continue;
- }
- if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
- return DC_ERROR;
- else{
- if(j)
- l++;
- else
- k++;
- }
- }
- if((j > 1) || (k > 3) || (l > 1))
- return DC_ERROR; /* &$@^! */
- i = strlen(digitbuf) - 1;
- if((j != 1) || (k < 2)|| (l != 1))
- break; /* Not yet */
- if(debug)
- printf("PL digits entered %s\n", digitbuf);
-
- strncpy(tmp, digitbuf, sizeof(tmp) - 1);
- /* see if we have at least 1 */
- s = strchr(tmp,'*');
- if(s)
- *s = '.';
- strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1);
- strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
-
- if (setrem(myrpt) == -1){
- strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1);
- return DC_ERROR;
- }
-
-
- return DC_COMPLETE;
-
-
- case 6: /* MODE (FM,USB,LSB,AM) */
- if(strlen(digitbuf) < 1)
- break;
-
- if(!multimode)
- return DC_ERROR; /* Multimode radios only */
-
- switch(*digitbuf){
- case '1':
- split_freq(mhz, decimals, myrpt->freq);
- m=atoi(mhz);
- if(m < 29) /* No FM allowed below 29MHz! */
- return DC_ERROR;
- myrpt->remmode = REM_MODE_FM;
-
- rpt_telemetry(myrpt,REMMODE,NULL);
- break;
-
- case '2':
- myrpt->remmode = REM_MODE_USB;
- rpt_telemetry(myrpt,REMMODE,NULL);
- break;
-
- case '3':
- myrpt->remmode = REM_MODE_LSB;
- rpt_telemetry(myrpt,REMMODE,NULL);
- break;
-
- case '4':
- myrpt->remmode = REM_MODE_AM;
- rpt_telemetry(myrpt,REMMODE,NULL);
- break;
-
- default:
- return DC_ERROR;
- }
-
- if(setrem(myrpt))
- return DC_ERROR;
- return DC_COMPLETEQUIET;
- case 99:
- /* cant log in when logged in */
- if (myrpt->loginlevel[0])
- return DC_ERROR;
- *myrpt->loginuser = 0;
- myrpt->loginlevel[0] = 0;
- cp = strdup(param);
- cp1 = strchr(cp,',');
- ast_mutex_lock(&myrpt->lock);
- if (cp1)
- {
- *cp1 = 0;
- cp2 = strchr(cp1 + 1,',');
- if (cp2)
- {
- *cp2 = 0;
- strncpy(myrpt->loginlevel,cp2 + 1,
- sizeof(myrpt->loginlevel) - 1);
- }
- strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser));
- ast_mutex_unlock(&myrpt->lock);
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"LOGIN,%s,%s",
- myrpt->loginuser,myrpt->loginlevel);
- donodelog(myrpt,str);
- }
- if (debug)
- printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel);
- rpt_telemetry(myrpt,REMLOGIN,NULL);
- }
- free(cp);
- return DC_COMPLETEQUIET;
- case 100: /* RX PL Off */
- myrpt->rxplon = 0;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 101: /* RX PL On */
- myrpt->rxplon = 1;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 102: /* TX PL Off */
- myrpt->txplon = 0;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 103: /* TX PL On */
- myrpt->txplon = 1;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 104: /* Low Power */
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- return DC_ERROR;
- myrpt->powerlevel = REM_LOWPWR;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 105: /* Medium Power */
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- return DC_ERROR;
- myrpt->powerlevel = REM_MEDPWR;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 106: /* Hi Power */
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- return DC_ERROR;
- myrpt->powerlevel = REM_HIPWR;
- setrem(myrpt);
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 107: /* Bump down 20Hz */
- multimode_bump_freq(myrpt, -20);
- return DC_COMPLETE;
- case 108: /* Bump down 100Hz */
- multimode_bump_freq(myrpt, -100);
- return DC_COMPLETE;
- case 109: /* Bump down 500Hz */
- multimode_bump_freq(myrpt, -500);
- return DC_COMPLETE;
- case 110: /* Bump up 20Hz */
- multimode_bump_freq(myrpt, 20);
- return DC_COMPLETE;
- case 111: /* Bump up 100Hz */
- multimode_bump_freq(myrpt, 100);
- return DC_COMPLETE;
- case 112: /* Bump up 500Hz */
- multimode_bump_freq(myrpt, 500);
- return DC_COMPLETE;
- case 113: /* Scan down slow */
- myrpt->scantimer = REM_SCANTIME;
- myrpt->hfscanmode = HF_SCAN_DOWN_SLOW;
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 114: /* Scan down quick */
- myrpt->scantimer = REM_SCANTIME;
- myrpt->hfscanmode = HF_SCAN_DOWN_QUICK;
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 115: /* Scan down fast */
- myrpt->scantimer = REM_SCANTIME;
- myrpt->hfscanmode = HF_SCAN_DOWN_FAST;
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 116: /* Scan up slow */
- myrpt->scantimer = REM_SCANTIME;
- myrpt->hfscanmode = HF_SCAN_UP_SLOW;
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 117: /* Scan up quick */
- myrpt->scantimer = REM_SCANTIME;
- myrpt->hfscanmode = HF_SCAN_UP_QUICK;
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 118: /* Scan up fast */
- myrpt->scantimer = REM_SCANTIME;
- myrpt->hfscanmode = HF_SCAN_UP_FAST;
- rpt_telemetry(myrpt,REMXXX,(void *)p);
- return DC_COMPLETEQUIET;
- case 119: /* Tune Request */
- /* if not currently going, and valid to do */
- if((!myrpt->tunerequest) &&
- ((!strcmp(myrpt->remote, remote_rig_ft897) ||
- !strcmp(myrpt->remote, remote_rig_ic706)) )) {
- myrpt->remotetx = 0;
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
- myrpt->tunerequest = 1;
- rpt_telemetry(myrpt,TUNE,NULL);
- return DC_COMPLETEQUIET;
- }
- return DC_ERROR;
- case 5: /* Long Status */
- rpt_telemetry(myrpt,REMLONGSTATUS,NULL);
- return DC_COMPLETEQUIET;
- case 140: /* Short Status */
- rpt_telemetry(myrpt,REMSHORTSTATUS,NULL);
- return DC_COMPLETEQUIET;
- case 200:
- case 201:
- case 202:
- case 203:
- case 204:
- case 205:
- case 206:
- case 207:
- case 208:
- case 209:
- case 210:
- case 211:
- case 212:
- case 213:
- case 214:
- case 215:
- do_dtmf_local(myrpt,remdtmfstr[p - 200]);
- return DC_COMPLETEQUIET;
- default:
- break;
- }
- return DC_INDETERMINATE;
-}
-
-
-static int handle_remote_dtmf_digit(struct rpt *myrpt,char c, char *keyed, int phonemode)
-{
-time_t now;
-int ret,res = 0,src;
-
- time(&myrpt->last_activity_time);
- /* Stop scan mode if in scan mode */
- if(myrpt->hfscanmode){
- stop_scan(myrpt);
- return 0;
- }
-
- time(&now);
- /* if timed-out */
- if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now)
- {
- myrpt->dtmfidx = -1;
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmf_time_rem = 0;
- }
- /* if decode not active */
- if (myrpt->dtmfidx == -1)
- {
- /* if not lead-in digit, dont worry */
- if (c != myrpt->p.funcchar)
- {
- if (!myrpt->p.propagate_dtmf)
- {
- rpt_mutex_lock(&myrpt->lock);
- do_dtmf_local(myrpt,c);
- rpt_mutex_unlock(&myrpt->lock);
- }
- return 0;
- }
- myrpt->dtmfidx = 0;
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmf_time_rem = now;
- return 0;
- }
- /* if too many in buffer, start over */
- if (myrpt->dtmfidx >= MAXDTMF)
- {
- myrpt->dtmfidx = 0;
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmf_time_rem = now;
- }
- if (c == myrpt->p.funcchar)
- {
- /* if star at beginning, or 2 together, erase buffer */
- if ((myrpt->dtmfidx < 1) ||
- (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar))
- {
- myrpt->dtmfidx = 0;
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmf_time_rem = now;
- return 0;
- }
- }
- myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
- myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
- myrpt->dtmf_time_rem = now;
-
-
- src = SOURCE_RMT;
- if (phonemode > 1) src = SOURCE_DPHONE;
- else if (phonemode) src = SOURCE_PHONE;
- ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL);
-
- switch(ret){
-
- case DC_INDETERMINATE:
- res = 0;
- break;
-
- case DC_DOKEY:
- if (keyed) *keyed = 1;
- res = 0;
- break;
-
- case DC_REQ_FLUSH:
- myrpt->dtmfidx = 0;
- myrpt->dtmfbuf[0] = 0;
- res = 0;
- break;
-
-
- case DC_COMPLETE:
- res = 1;
- case DC_COMPLETEQUIET:
- myrpt->totalexecdcommands++;
- myrpt->dailyexecdcommands++;
- strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1);
- myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmfidx = -1;
- myrpt->dtmf_time_rem = 0;
- break;
-
- case DC_ERROR:
- default:
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmfidx = -1;
- myrpt->dtmf_time_rem = 0;
- res = 0;
- break;
- }
-
- return res;
-}
-
-static int handle_remote_data(struct rpt *myrpt, char *str)
-{
-char tmp[300],cmd[300],dest[300],src[300],c;
-int seq,res;
-
- /* put string in our buffer */
- strncpy(tmp,str,sizeof(tmp) - 1);
- if (!strcmp(tmp,discstr)) return 0;
-
-#ifndef DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
- if (tmp[0] == 'I')
- {
- if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
- {
- ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
- return 0;
- }
- mdc1200_notify(myrpt,src,seq);
- return 0;
- }
-#endif
- if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
- {
- ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
- return 0;
- }
- if (strcmp(cmd,"D"))
- {
- ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
- return 0;
- }
- /* if not for me, ignore */
- if (strcmp(dest,myrpt->name)) return 0;
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"DTMF,%c",c);
- donodelog(myrpt,str);
- }
- c = func_xlat(myrpt,c,&myrpt->p.outxlat);
- if (!c) return(0);
- res = handle_remote_dtmf_digit(myrpt,c, NULL, 0);
- if (res != 1)
- return res;
- rpt_telemetry(myrpt,COMPLETE,NULL);
- return 0;
-}
-
-static int handle_remote_phone_dtmf(struct rpt *myrpt, char c, char *keyed, int phonemode)
-{
-int res;
-
-
- if (keyed && *keyed && (c == myrpt->p.endchar))
- {
- *keyed = 0;
- return DC_INDETERMINATE;
- }
-
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"DTMF(P),%c",c);
- donodelog(myrpt,str);
- }
- res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
- if (res != 1)
- return res;
- rpt_telemetry(myrpt,COMPLETE,NULL);
- return 0;
-}
-
-static int attempt_reconnect(struct rpt *myrpt, struct rpt_link *l)
-{
- char *val, *s, *s1, *s2, *tele;
- char tmp[300], deststr[300] = "";
-
- val = node_lookup(myrpt,l->name);
- if (!val)
- {
- fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name);
- return -1;
- }
-
- rpt_mutex_lock(&myrpt->lock);
- /* remove from queue */
- remque((struct qelem *) l);
- rpt_mutex_unlock(&myrpt->lock);
- strncpy(tmp,val,sizeof(tmp) - 1);
- s = tmp;
- s1 = strsep(&s,",");
- s2 = strsep(&s,",");
- snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
- tele = strchr(deststr, '/');
- if (!tele) {
- fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr);
- return -1;
- }
- *tele++ = 0;
- l->elaptime = 0;
- l->connecttime = 0;
- l->thisconnected = 0;
- l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
- if (l->chan){
- ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
- ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
- l->chan->whentohangup = 0;
- l->chan->appl = "Apprpt";
- l->chan->data = "(Remote Rx)";
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n",
- deststr, tele, l->chan->name);
- if(l->chan->cid.cid_num)
- free(l->chan->cid.cid_num);
- l->chan->cid.cid_num = strdup(myrpt->name);
- ast_call(l->chan,tele,999);
-
- }
- else
- {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
- deststr,tele,l->chan->name);
- return -1;
- }
- rpt_mutex_lock(&myrpt->lock);
- /* put back in queue */
- insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name);
- return 0;
-}
-
-/* 0 return=continue, 1 return = break, -1 return = error */
-static void local_dtmf_helper(struct rpt *myrpt,char c)
-{
-int res;
-pthread_attr_t attr;
-char cmd[MAXDTMF+1] = "";
-
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"DTMF,MAIN,%c",c);
- donodelog(myrpt,str);
- }
- if (c == myrpt->p.endchar)
- {
- /* if in simple mode, kill autopatch */
- if (myrpt->p.simple && myrpt->callmode)
- {
- rpt_mutex_lock(&myrpt->lock);
- myrpt->callmode = 0;
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,TERM,NULL);
- return;
- }
- rpt_mutex_lock(&myrpt->lock);
- myrpt->stopgen = 1;
- if (myrpt->cmdnode[0])
- {
- myrpt->cmdnode[0] = 0;
- myrpt->dtmfidx = -1;
- myrpt->dtmfbuf[0] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,COMPLETE,NULL);
- }
- else
- {
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->p.propagate_phonedtmf)
- do_dtmf_phone(myrpt,NULL,c);
- }
- return;
- }
- rpt_mutex_lock(&myrpt->lock);
- if (myrpt->cmdnode[0])
- {
- rpt_mutex_unlock(&myrpt->lock);
- send_link_dtmf(myrpt,c);
- return;
- }
- if (!myrpt->p.simple)
- {
- if (c == myrpt->p.funcchar)
- {
- myrpt->dtmfidx = 0;
- myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- time(&myrpt->dtmf_time);
- return;
- }
- else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0))
- {
- time(&myrpt->dtmf_time);
-
- if (myrpt->dtmfidx < MAXDTMF)
- {
- myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
- myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
-
- strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
-
- rpt_mutex_unlock(&myrpt->lock);
- res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL);
- rpt_mutex_lock(&myrpt->lock);
- switch(res){
- case DC_INDETERMINATE:
- break;
- case DC_REQ_FLUSH:
- myrpt->dtmfidx = 0;
- myrpt->dtmfbuf[0] = 0;
- break;
- case DC_COMPLETE:
- case DC_COMPLETEQUIET:
- myrpt->totalexecdcommands++;
- myrpt->dailyexecdcommands++;
- strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
- myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmfidx = -1;
- myrpt->dtmf_time = 0;
- break;
-
- case DC_ERROR:
- default:
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmfidx = -1;
- myrpt->dtmf_time = 0;
- break;
- }
- if(res != DC_INDETERMINATE) {
- rpt_mutex_unlock(&myrpt->lock);
- return;
- }
- }
- }
- }
- else /* if simple */
- {
- if ((!myrpt->callmode) && (c == myrpt->p.funcchar))
- {
- myrpt->callmode = 1;
- myrpt->patchnoct = 0;
- myrpt->patchquiet = 0;
- myrpt->patchfarenddisconnect = 0;
- myrpt->patchdialtime = 0;
- strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
- myrpt->cidx = 0;
- myrpt->exten[myrpt->cidx] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt);
- return;
- }
- }
- if (myrpt->callmode == 1)
- {
- myrpt->exten[myrpt->cidx++] = c;
- myrpt->exten[myrpt->cidx] = 0;
- /* if this exists */
- if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
- {
- myrpt->callmode = 2;
- rpt_mutex_unlock(&myrpt->lock);
- if(!myrpt->patchquiet)
- rpt_telemetry(myrpt,PROC,NULL);
- return;
- }
- /* if can continue, do so */
- if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
- {
- /* call has failed, inform user */
- myrpt->callmode = 4;
- }
- rpt_mutex_unlock(&myrpt->lock);
- return;
- }
- if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
- {
- myrpt->mydtmf = c;
- }
- rpt_mutex_unlock(&myrpt->lock);
- if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf)
- do_dtmf_phone(myrpt,NULL,c);
- return;
-}
-
-
-/* place an ID event in the telemetry queue */
-
-static void queue_id(struct rpt *myrpt)
-{
- if(myrpt->p.idtime){ /* ID time must be non-zero */
- myrpt->mustid = myrpt->tailid = 0;
- myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,ID,NULL);
- rpt_mutex_lock(&myrpt->lock);
- }
-}
-
-/* Scheduler */
-/* must be called locked */
-
-static void do_scheduler(struct rpt *myrpt)
-{
- int i,res;
- struct tm tmnow;
- struct ast_variable *skedlist;
- char *strs[5],*vp,*val,value[100];
-
- memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval));
-
- if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0)
- ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res));
-
- /* Try to get close to a 1 second resolution */
-
- if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec)
- return;
-
- rpt_localtime(&myrpt->curtv.tv_sec, &tmnow);
-
- /* If midnight, then reset all daily statistics */
-
- if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){
- myrpt->dailykeyups = 0;
- myrpt->dailytxtime = 0;
- myrpt->dailykerchunks = 0;
- myrpt->dailyexecdcommands = 0;
- }
-
- if(tmnow.tm_sec != 0)
- return;
-
- /* Code below only executes once per minute */
-
-
- /* Don't schedule if remote */
-
- if (myrpt->remote)
- return;
-
- /* Don't schedule if disabled */
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){
- if(debug > 6)
- ast_log(LOG_NOTICE, "Scheduler disabled\n");
- return;
- }
-
- if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */
- if(debug > 6)
- ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n");
- return;
- }
-
- /* get pointer to linked list of scheduler entries */
- skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname);
-
- if(debug > 6){
- ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n",
- tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday);
- }
- /* walk the list */
- for(; skedlist; skedlist = skedlist->next){
- if(debug > 6)
- ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value);
- strncpy(value,skedlist->value,99);
- value[99] = 0;
- /* point to the substrings for minute, hour, dom, month, and dow */
- for( i = 0, vp = value ; i < 5; i++){
- if(!*vp)
- break;
- while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */
- vp++;
- strs[i] = vp; /* save pointer to beginning of substring */
- while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */
- vp++;
- if(*vp)
- *vp++ = 0; /* mark end of substring */
- }
- if(debug > 6)
- ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i,
- strs[0], strs[1], strs[2], strs[3], strs[4]);
- if(i == 5){
- if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min))
- continue;
- if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour))
- continue;
- if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday))
- continue;
- if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1))
- continue;
- if(atoi(strs[4]) == 7)
- strs[4] = "0";
- if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday))
- continue;
- if(debug)
- ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value);
- if(atoi(skedlist->name) == 0)
- return; /* Zero is reserved for the startup macro */
- val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name);
- if (!val){
- ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name);
- return; /* Macro not found */
- }
- if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){
- ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n",
- skedlist->name);
- return; /* Macro buffer full */
- }
- myrpt->macrotimer = MACROTIME;
- strncat(myrpt->macrobuf,val,MAXMACRO - strlen(myrpt->macrobuf) - 1);
- }
- else{
- ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n",
- skedlist->name, skedlist->value);
- }
- }
-
-}
-
-/* single thread with one file (request) to dial */
-static void *rpt(void *this)
-{
-struct rpt *myrpt = (struct rpt *)this;
-char *tele,*idtalkover,c;
-int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued;
-int tailmessagequeued,ctqueued,dtmfed;
-struct ast_channel *who;
-ZT_CONFINFO ci; /* conference info */
-time_t t;
-struct rpt_link *l,*m;
-struct rpt_tele *telem;
-char tmpstr[300],lstr[MAXLINKLIST];
-
-
- if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600);
- sprintf(tmpstr,"%s/%s",myrpt->p.archivedir,myrpt->name);
- mkdir(tmpstr,0600);
- rpt_mutex_lock(&myrpt->lock);
-
- telem = myrpt->tele.next;
- while(telem != &myrpt->tele)
- {
- ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
- telem = telem->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- /* find our index, and load the vars initially */
- for(i = 0; i < nrpts; i++)
- {
- if (&rpt_vars[i] == myrpt)
- {
- load_rpt_vars(i,0);
- break;
- }
- }
- rpt_mutex_lock(&myrpt->lock);
- strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1);
- tele = strchr(tmpstr,'/');
- if (!tele)
- {
- fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname);
- rpt_mutex_unlock(&myrpt->lock);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- *tele++ = 0;
- myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
- myrpt->zaprxchannel = NULL;
- if (!strcasecmp(tmpstr,"Zap"))
- myrpt->zaprxchannel = myrpt->rxchannel;
- if (myrpt->rxchannel)
- {
- if (myrpt->rxchannel->_state == AST_STATE_BUSY)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- myrpt->rxchannel->whentohangup = 0;
- myrpt->rxchannel->appl = "Apprpt";
- myrpt->rxchannel->data = "(Repeater Rx)";
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
- tmpstr,tele,myrpt->rxchannel->name);
- ast_call(myrpt->rxchannel,tele,999);
- if (myrpt->rxchannel->_state != AST_STATE_UP)
- {
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- }
- else
- {
- fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- myrpt->zaptxchannel = NULL;
- if (myrpt->txchanname)
- {
- strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1);
- tele = strchr(tmpstr,'/');
- if (!tele)
- {
- fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname);
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- *tele++ = 0;
- myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
- if (!strcasecmp(tmpstr,"Zap"))
- myrpt->zaptxchannel = myrpt->txchannel;
- if (myrpt->txchannel)
- {
- if (myrpt->txchannel->_state == AST_STATE_BUSY)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- myrpt->txchannel->whentohangup = 0;
- myrpt->txchannel->appl = "Apprpt";
- myrpt->txchannel->data = "(Repeater Tx)";
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
- tmpstr,tele,myrpt->txchannel->name);
- ast_call(myrpt->txchannel,tele,999);
- if (myrpt->rxchannel->_state != AST_STATE_UP)
- {
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- ast_hangup(myrpt->txchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- }
- else
- {
- fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- }
- else
- {
- myrpt->txchannel = myrpt->rxchannel;
- }
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
- /* allocate a pseudo-channel thru asterisk */
- myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!myrpt->pchannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel;
- if (!myrpt->zaptxchannel)
- {
- /* allocate a pseudo-channel thru asterisk */
- myrpt->zaptxchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!myrpt->zaptxchannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- ast_set_read_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->zaptxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- }
- /* allocate a pseudo-channel thru asterisk */
- myrpt->monchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!myrpt->monchannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- /* make a conference for the tx */
- ci.chan = 0;
- ci.confno = -1; /* make a new conf */
- ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER;
- /* first put the channel on the conference in proper mode */
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- ast_hangup(myrpt->monchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- /* save tx conference number */
- myrpt->txconf = ci.confno;
- /* make a conference for the pseudo */
- ci.chan = 0;
- ci.confno = -1; /* make a new conf */
- ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON :
- (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
- /* first put the channel on the conference in announce mode */
- if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- ast_hangup(myrpt->monchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- /* save pseudo channel conference number */
- myrpt->conf = ci.confno;
- /* make a conference for the pseudo */
- ci.chan = 0;
- if ((strstr(myrpt->txchannel->name,"pseudo") == NULL) &&
- (myrpt->zaptxchannel == myrpt->txchannel))
- {
- /* get tx channel's port number */
- if (ioctl(myrpt->txchannel->fds[0],ZT_CHANNO,&ci.confno) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set tx channel's chan number\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- ast_hangup(myrpt->monchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- ci.confmode = ZT_CONF_MONITORTX;
- }
- else
- {
- ci.confno = myrpt->txconf;
- ci.confmode = ZT_CONF_CONFANNMON;
- }
- /* first put the channel on the conference in announce mode */
- if (ioctl(myrpt->monchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode for monitor\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- ast_hangup(myrpt->monchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- /* allocate a pseudo-channel thru asterisk */
- myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!myrpt->txpchannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- ast_hangup(myrpt->monchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->txpchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- /* make a conference for the tx */
- ci.chan = 0;
- ci.confno = myrpt->txconf;
- ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ;
- /* first put the channel on the conference in proper mode */
- if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->txpchannel);
- ast_hangup(myrpt->monchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- }
- /* Now, the idea here is to copy from the physical rx channel buffer
- into the pseudo tx buffer, and from the pseudo rx buffer into the
- tx channel buffer */
- myrpt->links.next = &myrpt->links;
- myrpt->links.prev = &myrpt->links;
- myrpt->tailtimer = 0;
- myrpt->totimer = 0;
- myrpt->tmsgtimer = myrpt->p.tailmessagetime;
- myrpt->idtimer = myrpt->p.politeid;
- myrpt->mustid = myrpt->tailid = 0;
- myrpt->callmode = 0;
- myrpt->tounkeyed = 0;
- myrpt->tonotify = 0;
- myrpt->retxtimer = 0;
- myrpt->rerxtimer = 0;
- myrpt->skedtimer = 0;
- myrpt->tailevent = 0;
- lasttx = 0;
- myrpt->keyed = 0;
- idtalkover = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover");
- myrpt->dtmfidx = -1;
- myrpt->dtmfbuf[0] = 0;
- myrpt->rem_dtmfidx = -1;
- myrpt->rem_dtmfbuf[0] = 0;
- myrpt->dtmf_time = 0;
- myrpt->rem_dtmf_time = 0;
- myrpt->disgorgetime = 0;
- myrpt->lastnodewhichkeyedusup[0] = '\0';
- myrpt->dailytxtime = 0;
- myrpt->totaltxtime = 0;
- myrpt->dailykeyups = 0;
- myrpt->totalkeyups = 0;
- myrpt->dailykerchunks = 0;
- myrpt->totalkerchunks = 0;
- myrpt->dailyexecdcommands = 0;
- myrpt->totalexecdcommands = 0;
- myrpt->timeouts = 0;
- myrpt->exten[0] = '\0';
- myrpt->lastdtmfcommand[0] = '\0';
- if (myrpt->p.startupmacro)
- {
- snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
- }
- rpt_mutex_unlock(&myrpt->lock);
- val = 1;
- ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0);
- val = 1;
- ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
- if (myrpt->p.archivedir) donodelog(myrpt,"STARTUP");
- dtmfed = 0;
- while (ms >= 0)
- {
- struct ast_frame *f,*f1,*f2;
- struct ast_channel *cs[300],*cs1[300];
- int totx=0,elap=0,n,x,toexit=0;
-
- /* DEBUG Dump */
- if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){
- struct rpt_link *zl;
- struct rpt_tele *zt;
-
- myrpt->disgorgetime = 0;
- ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n");
- ast_log(LOG_NOTICE,"totx = %d\n",totx);
- ast_log(LOG_NOTICE,"remrx = %d\n",remrx);
- ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx);
- ast_log(LOG_NOTICE,"elap = %d\n",elap);
- ast_log(LOG_NOTICE,"toexit = %d\n",toexit);
-
- ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed);
- ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx);
- ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode);
- ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid);
- ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed);
- ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify);
- ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer);
- ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer);
- ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer);
- ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent);
-
- zl = myrpt->links.next;
- while(zl != &myrpt->links){
- ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name);
- ast_log(LOG_NOTICE," link->lasttx %d\n",zl->lasttx);
- ast_log(LOG_NOTICE," link->lastrx %d\n",zl->lastrx);
- ast_log(LOG_NOTICE," link->connected %d\n",zl->connected);
- ast_log(LOG_NOTICE," link->hasconnected %d\n",zl->hasconnected);
- ast_log(LOG_NOTICE," link->outbound %d\n",zl->outbound);
- ast_log(LOG_NOTICE," link->disced %d\n",zl->disced);
- ast_log(LOG_NOTICE," link->killme %d\n",zl->killme);
- ast_log(LOG_NOTICE," link->disctime %ld\n",zl->disctime);
- ast_log(LOG_NOTICE," link->retrytimer %ld\n",zl->retrytimer);
- ast_log(LOG_NOTICE," link->retries = %d\n",zl->retries);
- ast_log(LOG_NOTICE," link->reconnects = %d\n",zl->reconnects);
- zl = zl->next;
- }
-
- zt = myrpt->tele.next;
- if(zt != &myrpt->tele)
- ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n");
- while(zt != &myrpt->tele){
- ast_log(LOG_NOTICE," Telemetry mode: %d\n",zt->mode);
- zt = zt->next;
- }
- ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n");
-
- }
-
-
- if (myrpt->reload)
- {
- struct rpt_tele *telem;
-
- rpt_mutex_lock(&myrpt->lock);
- telem = myrpt->tele.next;
- while(telem != &myrpt->tele)
- {
- ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
- telem = telem->next;
- }
- myrpt->reload = 0;
- rpt_mutex_unlock(&myrpt->lock);
- usleep(10000);
- /* find our index, and load the vars */
- for(i = 0; i < nrpts; i++)
- {
- if (&rpt_vars[i] == myrpt)
- {
- load_rpt_vars(i,0);
- break;
- }
- }
- }
-
- rpt_mutex_lock(&myrpt->lock);
- if (ast_check_hangup(myrpt->rxchannel)) break;
- if (ast_check_hangup(myrpt->txchannel)) break;
- if (ast_check_hangup(myrpt->pchannel)) break;
- if (ast_check_hangup(myrpt->monchannel)) break;
- if (ast_check_hangup(myrpt->txpchannel)) break;
- if (myrpt->zaptxchannel && ast_check_hangup(myrpt->zaptxchannel)) break;
-
- /* Set local tx with keyed */
- myrpt->localtx = myrpt->keyed;
- /* If someone's connected, and they're transmitting from their end to us, set remrx true */
- l = myrpt->links.next;
- remrx = 0;
- while(l != &myrpt->links)
- {
- if (l->lastrx){
- remrx = 1;
- if(l->name[0] != '0') /* Ignore '0' nodes */
- strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */
- }
- l = l->next;
- }
- /* Create a "must_id" flag for the cleanup ID */
- if(myrpt->p.idtime) /* ID time must be non-zero */
- myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ;
- /* Build a fresh totx from myrpt->keyed and autopatch activated */
- totx = myrpt->callmode;
- /* If full duplex, add local tx to totx */
- if (myrpt->p.duplex > 1)
- {
- totx = totx || myrpt->localtx;
- }
- /* Traverse the telemetry list to see what's queued */
- identqueued = 0;
- othertelemqueued = 0;
- tailmessagequeued = 0;
- ctqueued = 0;
- telem = myrpt->tele.next;
- while(telem != &myrpt->tele)
- {
- if((telem->mode == ID) || (telem->mode == IDTALKOVER)){
- identqueued = 1; /* Identification telemetry */
- }
- else if(telem->mode == TAILMSG)
- {
- tailmessagequeued = 1; /* Tail message telemetry */
- }
- else
- {
- if ((telem->mode != UNKEY) && (telem->mode != LINKUNKEY))
- othertelemqueued = 1; /* Other telemetry */
- else
- ctqueued = 1; /* Courtesy tone telemetry */
- }
- telem = telem->next;
- }
-
- /* Add in any "other" telemetry, unless specified otherwise */
- if (!myrpt->p.notelemtx) totx = totx || othertelemqueued;
- /* Update external (to links) transmitter PTT state with everything but ID, CT, and tailmessage telemetry */
- myrpt->exttx = totx;
- totx = totx || myrpt->dtmf_local_timer;
- /* If half or 3/4 duplex, add localtx to external link tx */
- if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx;
- /* Add in ID telemetry to local transmitter */
- totx = totx || remrx;
- /* If 3/4 or full duplex, add in ident and CT telemetry */
- if (myrpt->p.duplex > 0)
- totx = totx || identqueued || ctqueued;
- /* If full duplex, add local dtmf stuff active */
- if (myrpt->p.duplex > 1)
- {
- totx = totx || (myrpt->dtmfidx > -1) ||
- myrpt->cmdnode[0];
- }
- /* Reset time out timer variables if there is no activity */
- if (!totx)
- {
- myrpt->totimer = myrpt->p.totime;
- myrpt->tounkeyed = 0;
- myrpt->tonotify = 0;
- }
- else{
- myrpt->tailtimer = myrpt->p.s[myrpt->p.sysstate_cur].alternatetail ?
- myrpt->p.althangtime : /* Initialize tail timer */
- myrpt->p.hangtime;
- }
- /* Disable the local transmitter if we are timed out */
- totx = totx && myrpt->totimer;
- /* if timed-out and not said already, say it */
- if ((!myrpt->totimer) && (!myrpt->tonotify))
- {
- myrpt->tonotify = 1;
- myrpt->timeouts++;
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt,TIMEOUT,NULL);
- rpt_mutex_lock(&myrpt->lock);
- }
-
- /* If unkey and re-key, reset time out timer */
- if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed))
- {
- myrpt->tounkeyed = 1;
- }
- if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed)
- {
- myrpt->totimer = myrpt->p.totime;
- myrpt->tounkeyed = 0;
- myrpt->tonotify = 0;
- rpt_mutex_unlock(&myrpt->lock);
- continue;
- }
- /* if timed-out and in circuit busy after call */
- if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4))
- {
- myrpt->callmode = 0;
- }
- /* get rid of tail if timed out */
- if (!myrpt->totimer) myrpt->tailtimer = 0;
- /* if not timed-out, add in tail */
- if (myrpt->totimer) totx = totx || myrpt->tailtimer;
- /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */
- /* If tail message, kill the message if someone keys up over it */
- if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) {
- int hasid = 0,hastalkover = 0;
-
- telem = myrpt->tele.next;
- while(telem != &myrpt->tele){
- if(telem->mode == ID){
- if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
- hasid = 1;
- }
- if(telem->mode == TAILMSG){
- if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
- }
- if (telem->mode == IDTALKOVER) hastalkover = 1;
- telem = telem->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */
- rpt_mutex_lock(&myrpt->lock);
- }
- /* Try to be polite */
- /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/
- /* If within 30 seconds of the time to ID, try do it in the tail */
- /* else if at ID time limit, do it right over the top of them */
- /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */
- if(myrpt->mustid && (!myrpt->idtimer))
- queue_id(myrpt);
-
- if ((myrpt->p.idtime && totx && (!myrpt->exttx) &&
- (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) /* ID time must be non-zero */
- {
- myrpt->tailid = 1;
- }
-
- /* If tail timer expires, then check for tail messages */
-
- if(myrpt->tailevent){
- myrpt->tailevent = 0;
- if(myrpt->tailid){
- totx = 1;
- queue_id(myrpt);
- }
- else if ((myrpt->p.tailmessages[0]) &&
- (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){
- totx = 1;
- myrpt->tmsgtimer = myrpt->p.tailmessagetime;
- rpt_mutex_unlock(&myrpt->lock);
- rpt_telemetry(myrpt, TAILMSG, NULL);
- rpt_mutex_lock(&myrpt->lock);
- }
- }
-
- /* Main TX control */
-
- /* let telemetry transmit anyway (regardless of timeout) */
- if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele);
- if (totx && (!lasttx))
- {
- char mydate[100],myfname[100];
- time_t myt;
-
- if (myrpt->monstream) ast_closestream(myrpt->monstream);
- if (myrpt->p.archivedir)
- {
- long blocksleft;
-
- time(&myt);
- strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
- localtime(&myt));
- sprintf(myfname,"%s/%s/%s",myrpt->p.archivedir,
- myrpt->name,mydate);
- myrpt->monstream = ast_writefile(myfname,"wav49",
- "app_rpt Air Archive",O_CREAT | O_APPEND,0,0600);
- if (myrpt->p.monminblocks)
- {
- blocksleft = diskavail(myrpt);
- if (blocksleft >= myrpt->p.monminblocks)
- donodelog(myrpt,"TXKEY,MAIN");
- } else donodelog(myrpt,"TXKEY,MAIN");
- }
- lasttx = 1;
- myrpt->dailykeyups++;
- myrpt->totalkeyups++;
- rpt_mutex_unlock(&myrpt->lock);
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
- rpt_mutex_lock(&myrpt->lock);
- }
- totx = totx && !myrpt->p.s[myrpt->p.sysstate_cur].txdisable;
- if ((!totx) && lasttx)
- {
- if (myrpt->monstream) ast_closestream(myrpt->monstream);
- myrpt->monstream = NULL;
-
- lasttx = 0;
- rpt_mutex_unlock(&myrpt->lock);
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
- rpt_mutex_lock(&myrpt->lock);
- donodelog(myrpt,"TXUNKEY,MAIN");
- }
- time(&t);
- /* if DTMF timeout */
- if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t))
- {
- myrpt->dtmfidx = -1;
- myrpt->dtmfbuf[0] = 0;
- }
- /* if remote DTMF timeout */
- if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t))
- {
- myrpt->rem_dtmfidx = -1;
- myrpt->rem_dtmfbuf[0] = 0;
- }
-
- /* Reconnect */
-
- l = myrpt->links.next;
- while(l != &myrpt->links)
- {
- if (l->killme)
- {
- /* remove from queue */
- remque((struct qelem *) l);
- if (!strcmp(myrpt->cmdnode,l->name))
- myrpt->cmdnode[0] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- /* hang-up on call to device */
- if (l->chan) ast_hangup(l->chan);
- ast_hangup(l->pchan);
- free(l);
- rpt_mutex_lock(&myrpt->lock);
- /* re-start link traversal */
- l = myrpt->links.next;
- continue;
- }
- l = l->next;
- }
- n = 0;
- cs[n++] = myrpt->rxchannel;
- cs[n++] = myrpt->pchannel;
- cs[n++] = myrpt->monchannel;
- cs[n++] = myrpt->txpchannel;
- if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel;
- if (myrpt->zaptxchannel != myrpt->txchannel)
- cs[n++] = myrpt->zaptxchannel;
- l = myrpt->links.next;
- while(l != &myrpt->links)
- {
- if ((!l->killme) && (!l->disctime) && l->chan)
- {
- cs[n++] = l->chan;
- cs[n++] = l->pchan;
- }
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- ms = MSWAIT;
- for(x = 0; x < n; x++)
- {
- int s = -(-x - myrpt->scram - 1) % n;
- cs1[x] = cs[s];
- }
- myrpt->scram++;
- who = ast_waitfor_n(cs1,n,&ms);
- if (who == NULL) ms = 0;
- elap = MSWAIT - ms;
- rpt_mutex_lock(&myrpt->lock);
- l = myrpt->links.next;
- while(l != &myrpt->links)
- {
- if (l->linklisttimer)
- {
- l->linklisttimer -= elap;
- if (l->linklisttimer < 0) l->linklisttimer = 0;
- }
- if ((!l->linklisttimer) && (l->name[0] != '0') && (!l->isremote))
- {
- struct ast_frame lf;
-
- memset(&lf,0,sizeof(lf));
- lf.frametype = AST_FRAME_TEXT;
- lf.subclass = 0;
- lf.offset = 0;
- lf.mallocd = 0;
- lf.samples = 0;
- l->linklisttimer = LINKLISTTIME;
- strcpy(lstr,"L ");
- __mklinklist(myrpt,l,lstr + 2);
- if (l->chan)
- {
- lf.datalen = strlen(lstr) + 1;
- lf.data = lstr;
- ast_write(l->chan,&lf);
- if (debug > 6) ast_log(LOG_NOTICE,
- "@@@@ node %s sent node string %s to node %s\n",
- myrpt->name,lstr,l->name);
- }
- }
-#ifndef OLDKEY
- if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME)
- {
- l->retxtimer = 0;
- if (l->chan && l->phonemode == 0)
- {
- if (l->lasttx)
- ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
- else
- ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
- }
- }
- if ((l->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 5))
- {
- if (debug == 7) printf("@@@@ rx un-key\n");
- l->lastrx = 0;
- l->rerxtimer = 0;
- if(myrpt->p.duplex)
- rpt_telemetry(myrpt,LINKUNKEY,l);
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- l->lastrx1 = 0;
- sprintf(str,"RXUNKEY(T),%s",l->name);
- donodelog(myrpt,str);
- }
- }
-#endif
- if (l->disctime) /* Disconnect timer active on a channel ? */
- {
- l->disctime -= elap;
- if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */
- l->disctime = 0; /* Yep */
- }
-
- if (l->retrytimer)
- {
- l->retrytimer -= elap;
- if (l->retrytimer < 0) l->retrytimer = 0;
- }
-
- /* Tally connect time */
- l->connecttime += elap;
-
- /* ignore non-timing channels */
- if (l->elaptime < 0)
- {
- l = l->next;
- continue;
- }
- l->elaptime += elap;
- /* if connection has taken too long */
- if ((l->elaptime > MAXCONNECTTIME) &&
- ((!l->chan) || (l->chan->_state != AST_STATE_UP)))
- {
- l->elaptime = 0;
- rpt_mutex_unlock(&myrpt->lock);
- if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if ((!l->chan) && (!l->retrytimer) && l->outbound &&
- (l->retries++ < l->max_retries) && (l->hasconnected))
- {
- if (l->chan) ast_hangup(l->chan);
- l->chan = 0;
- rpt_mutex_unlock(&myrpt->lock);
- if ((l->name[0] != '0') && (!l->isremote))
- {
- if (attempt_reconnect(myrpt,l) == -1)
- {
- l->retrytimer = RETRY_TIMER_MS;
- }
- }
- else
- {
- l->retrytimer = l->max_retries + 1;
- }
-
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if ((!l->chan) && (!l->retrytimer) && l->outbound &&
- (l->retries >= l->max_retries))
- {
- /* remove from queue */
- remque((struct qelem *) l);
- if (!strcmp(myrpt->cmdnode,l->name))
- myrpt->cmdnode[0] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- if (l->name[0] != '0')
- {
- if (!l->hasconnected)
- rpt_telemetry(myrpt,CONNFAIL,l);
- else rpt_telemetry(myrpt,REMDISC,l);
- }
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- if (!l->hasconnected)
- sprintf(str,"LINKFAIL,%s",l->name);
- else
- sprintf(str,"LINKDISC,%s",l->name);
- donodelog(myrpt,str);
- }
- /* hang-up on call to device */
- ast_hangup(l->pchan);
- free(l);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if ((!l->chan) && (!l->disctime) && (!l->outbound))
- {
- /* remove from queue */
- remque((struct qelem *) l);
- if (!strcmp(myrpt->cmdnode,l->name))
- myrpt->cmdnode[0] = 0;
- rpt_mutex_unlock(&myrpt->lock);
- if (l->name[0] != '0')
- {
- rpt_telemetry(myrpt,REMDISC,l);
- }
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"LINKDISC,%s",l->name);
- donodelog(myrpt,str);
- }
- /* hang-up on call to device */
- ast_hangup(l->pchan);
- free(l);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- l = l->next;
- }
- if(totx){
- myrpt->dailytxtime += elap;
- myrpt->totaltxtime += elap;
- }
- i = myrpt->tailtimer;
- if (myrpt->tailtimer) myrpt->tailtimer -= elap;
- if (myrpt->tailtimer < 0) myrpt->tailtimer = 0;
- if((i) && (myrpt->tailtimer == 0))
- myrpt->tailevent = 1;
- if ((!myrpt->p.s[myrpt->p.sysstate_cur].totdisable) && myrpt->totimer) myrpt->totimer -= elap;
- if (myrpt->totimer < 0) myrpt->totimer = 0;
- if (myrpt->idtimer) myrpt->idtimer -= elap;
- if (myrpt->idtimer < 0) myrpt->idtimer = 0;
- if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap;
- if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0;
- /* do macro timers */
- if (myrpt->macrotimer) myrpt->macrotimer -= elap;
- if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
- /* do local dtmf timer */
- if (myrpt->dtmf_local_timer)
- {
- if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
- if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
- }
- do_dtmf_local(myrpt,0);
- /* Execute scheduler appx. every 2 tenths of a second */
- if (myrpt->skedtimer <= 0){
- myrpt->skedtimer = 200;
- do_scheduler(myrpt);
- }
- else
- myrpt->skedtimer -=elap;
- if (!ms)
- {
- rpt_mutex_unlock(&myrpt->lock);
- continue;
- }
- c = myrpt->macrobuf[0];
- time(&t);
- if (c && (!myrpt->macrotimer) &&
- starttime && (t > (starttime + START_DELAY)))
- {
- myrpt->macrotimer = MACROTIME;
- memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
- if ((c == 'p') || (c == 'P'))
- myrpt->macrotimer = MACROPTIME;
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- sprintf(str,"DTMF(M),MAIN,%c",c);
- donodelog(myrpt,str);
- }
- local_dtmf_helper(myrpt,c);
- } else rpt_mutex_unlock(&myrpt->lock);
- if (who == myrpt->rxchannel) /* if it was a read from rx */
- {
- int ismuted;
-
- f = ast_read(myrpt->rxchannel);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
-#ifdef _MDC_DECODE_H_
- unsigned char ubuf[2560];
- short *sp;
- int n;
-#endif
-
- if ((!myrpt->localtx) && (!myrpt->p.linktolink)) {
- memset(f->data,0,f->datalen);
- }
-
-#ifdef _MDC_DECODE_H_
- sp = (short *) f->data;
- /* convert block to unsigned char */
- for(n = 0; n < f->datalen / 2; n++)
- {
- ubuf[n] = (*sp++ >> 8) + 128;
- }
- n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2);
- if (n == 1)
- {
- unsigned char op,arg;
- unsigned short unitID;
-
- mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID);
- if (debug > 2)
- {
- ast_log(LOG_NOTICE,"Got (single-length) packet:\n");
- ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n",
- op & 255,arg & 255,unitID);
- }
- if ((op == 1) && (arg == 0))
- {
- myrpt->lastunit = unitID;
- mdc1200_notify(myrpt,NULL,myrpt->lastunit);
- mdc1200_send(myrpt,myrpt->lastunit);
- }
- }
- if ((debug > 2) && (i == 2))
- {
- unsigned char op,arg,ex1,ex2,ex3,ex4;
- unsigned short unitID;
-
- mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID,
- &ex1,&ex2,&ex3,&ex4);
- ast_log(LOG_NOTICE,"Got (double-length) packet:\n");
- ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n",
- op & 255,arg & 255,unitID);
- ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n",
- ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255);
- }
-#endif
-#ifdef __RPT_NOTCH
- /* apply inbound filters, if any */
- rpt_filter(myrpt,f->data,f->datalen / 2);
-#endif
- if (ioctl(myrpt->zaprxchannel->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
- {
- ismuted = 0;
- }
- if (dtmfed) ismuted = 1;
- dtmfed = 0;
- if (ismuted)
- {
- memset(f->data,0,f->datalen);
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- }
- if (f) f2 = ast_frdup(f);
- else f2 = NULL;
- f1 = myrpt->lastf2;
- myrpt->lastf2 = myrpt->lastf1;
- myrpt->lastf1 = f2;
- if (ismuted)
- {
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- }
- if (f1)
- {
- ast_write(myrpt->pchannel,f1);
- ast_frfree(f1);
- }
- }
-#ifndef OLD_ASTERISK
- else if (f->frametype == AST_FRAME_DTMF_BEGIN)
- {
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- dtmfed = 1;
- }
-#endif
- else if (f->frametype == AST_FRAME_DTMF)
- {
- c = (char) f->subclass; /* get DTMF char */
- ast_frfree(f);
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- dtmfed = 1;
- if (!myrpt->keyed) continue;
- c = func_xlat(myrpt,c,&myrpt->p.inxlat);
- if (c) local_dtmf_helper(myrpt,c);
- continue;
- }
- else if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- /* if RX key */
- if (f->subclass == AST_CONTROL_RADIO_KEY)
- {
- if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink))
- {
- if (debug == 7) printf("@@@@ rx key\n");
- myrpt->keyed = 1;
- }
- if (myrpt->p.archivedir)
- {
- donodelog(myrpt,"RXKEY,MAIN");
- }
- }
- /* if RX un-key */
- if (f->subclass == AST_CONTROL_RADIO_UNKEY)
- {
- if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink))
- {
- if (debug == 7) printf("@@@@ rx un-key\n");
- if(myrpt->p.duplex && myrpt->keyed) {
- rpt_telemetry(myrpt,UNKEY,NULL);
- }
- }
- myrpt->keyed = 0;
- if (myrpt->p.archivedir)
- {
- donodelog(myrpt,"RXUNKEY,MAIN");
- }
- }
- }
- ast_frfree(f);
- continue;
- }
- if (who == myrpt->pchannel) /* if it was a read from pseudo */
- {
- f = ast_read(myrpt->pchannel);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- ast_write(myrpt->txpchannel,f);
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- if (who == myrpt->txchannel) /* if it was a read from tx */
- {
- f = ast_read(myrpt->txchannel);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- if (who == myrpt->zaptxchannel) /* if it was a read from pseudo-tx */
- {
- f = ast_read(myrpt->zaptxchannel);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- ast_write(myrpt->txchannel,f);
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- toexit = 0;
- rpt_mutex_lock(&myrpt->lock);
- l = myrpt->links.next;
- while(l != &myrpt->links)
- {
- if (l->disctime)
- {
- l = l->next;
- continue;
- }
- if (who == l->chan) /* if it was a read from rx */
- {
- int remnomute;
-
- remrx = 0;
- /* see if any other links are receiving */
- m = myrpt->links.next;
- while(m != &myrpt->links)
- {
- /* if not us, count it */
- if ((m != l) && (m->lastrx)) remrx = 1;
- m = m->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- remnomute = myrpt->localtx &&
- (!(myrpt->cmdnode[0] ||
- (myrpt->dtmfidx > -1)));
- totx = (((l->isremote) ? (remnomute) :
- myrpt->exttx) || remrx) && l->mode;
- if (l->phonemode == 0 && l->chan && (l->lasttx != totx))
- {
- if (totx)
- {
- ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
- }
- else
- {
- ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
- }
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- if (totx)
- sprintf(str,"TXKEY,%s",l->name);
- else
- sprintf(str,"TXUNKEY,%s",l->name);
- donodelog(myrpt,str);
- }
- }
- l->lasttx = totx;
- f = ast_read(l->chan);
- if (!f)
- {
- rpt_mutex_lock(&myrpt->lock);
- __kickshort(myrpt);
- rpt_mutex_unlock(&myrpt->lock);
- if ((!l->disced) && (!l->outbound))
- {
- if ((l->name[0] == '0') || l->isremote)
- l->disctime = 1;
- else
- l->disctime = DISC_TIME;
- rpt_mutex_lock(&myrpt->lock);
- ast_hangup(l->chan);
- l->chan = 0;
- break;
- }
-
- if (l->retrytimer)
- {
- ast_hangup(l->chan);
- l->chan = 0;
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected))
- {
- rpt_mutex_lock(&myrpt->lock);
- if (l->chan) ast_hangup(l->chan);
- l->chan = 0;
- l->hasconnected = 1;
- l->retrytimer = RETRY_TIMER_MS;
- l->elaptime = 0;
- l->connecttime = 0;
- l->thisconnected = 0;
- break;
- }
- rpt_mutex_lock(&myrpt->lock);
- /* remove from queue */
- remque((struct qelem *) l);
- if (!strcmp(myrpt->cmdnode,l->name))
- myrpt->cmdnode[0] = 0;
- __kickshort(myrpt);
- rpt_mutex_unlock(&myrpt->lock);
- if (!l->hasconnected)
- rpt_telemetry(myrpt,CONNFAIL,l);
- else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- if (!l->hasconnected)
- sprintf(str,"LINKFAIL,%s",l->name);
- else
- sprintf(str,"LINKDISC,%s",l->name);
- donodelog(myrpt,str);
- }
- if (l->lastf1) ast_frfree(l->lastf1);
- l->lastf1 = NULL;
- if (l->lastf2) ast_frfree(l->lastf2);
- l->lastf2 = NULL;
- /* hang-up on call to device */
- ast_hangup(l->chan);
- ast_hangup(l->pchan);
- free(l);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- int ismuted;
-
- if (l->phonemode)
- {
- if (ioctl(l->chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
- {
- ismuted = 0;
- }
- /* if not receiving, zero-out audio */
- ismuted |= (!l->lastrx);
- if (l->dtmfed && l->phonemode) ismuted = 1;
- l->dtmfed = 0;
- if (ismuted)
- {
- memset(f->data,0,f->datalen);
- if (l->lastf1)
- memset(l->lastf1->data,0,l->lastf1->datalen);
- if (l->lastf2)
- memset(l->lastf2->data,0,l->lastf2->datalen);
- }
- if (f) f2 = ast_frdup(f);
- else f2 = NULL;
- f1 = l->lastf2;
- l->lastf2 = l->lastf1;
- l->lastf1 = f2;
- if (ismuted)
- {
- if (l->lastf1)
- memset(l->lastf1->data,0,l->lastf1->datalen);
- if (l->lastf2)
- memset(l->lastf2->data,0,l->lastf2->datalen);
- }
- if (f1)
- {
- ast_write(l->pchan,f1);
- ast_frfree(f1);
- }
- }
- else
- {
- if (!l->lastrx)
- memset(f->data,0,f->datalen);
- ast_write(l->pchan,f);
- }
- }
-#ifndef OLD_ASTERISK
- else if (f->frametype == AST_FRAME_DTMF_BEGIN)
- {
- if (l->lastf1)
- memset(l->lastf1->data,0,l->lastf1->datalen);
- if (l->lastf2)
- memset(l->lastf2->data,0,l->lastf2->datalen);
- l->dtmfed = 1;
- }
-#endif
-
- if (f->frametype == AST_FRAME_TEXT)
- {
- handle_link_data(myrpt,l,f->data);
- }
- if (f->frametype == AST_FRAME_DTMF)
- {
- if (l->lastf1)
- memset(l->lastf1->data,0,l->lastf1->datalen);
- if (l->lastf2)
- memset(l->lastf2->data,0,l->lastf2->datalen);
- l->dtmfed = 1;
- handle_link_phone_dtmf(myrpt,l,f->subclass);
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_ANSWER)
- {
- char lconnected = l->connected;
-
- __kickshort(myrpt);
- l->connected = 1;
- l->hasconnected = 1;
- l->thisconnected = 1;
- l->elaptime = -1;
- if (!l->isremote) l->retries = 0;
- if (!lconnected)
- {
- rpt_telemetry(myrpt,CONNECTED,l);
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- if (l->mode)
- sprintf(str,"LINKTRX,%s",l->name);
- else
- sprintf(str,"LINKMONITOR,%s",l->name);
- donodelog(myrpt,str);
- }
- }
- else
- l->reconnects++;
- }
- /* if RX key */
- if (f->subclass == AST_CONTROL_RADIO_KEY)
- {
- if (debug == 7 ) printf("@@@@ rx key\n");
- l->lastrx = 1;
- l->rerxtimer = 0;
- if (myrpt->p.archivedir && (!l->lastrx1))
- {
- char str[100];
-
- l->lastrx1 = 1;
- sprintf(str,"RXKEY,%s",l->name);
- donodelog(myrpt,str);
- }
- }
- /* if RX un-key */
- if (f->subclass == AST_CONTROL_RADIO_UNKEY)
- {
- if (debug == 7) printf("@@@@ rx un-key\n");
- l->lastrx = 0;
- l->rerxtimer = 0;
- if(myrpt->p.duplex)
- rpt_telemetry(myrpt,LINKUNKEY,l);
- if (myrpt->p.archivedir && (l->lastrx1))
- {
- char str[100];
-
- l->lastrx1 = 0;
- sprintf(str,"RXUNKEY,%s",l->name);
- donodelog(myrpt,str);
- }
- }
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- ast_frfree(f);
- rpt_mutex_lock(&myrpt->lock);
- __kickshort(myrpt);
- rpt_mutex_unlock(&myrpt->lock);
- if ((!l->outbound) && (!l->disced))
- {
- if ((l->name[0] == '0') || l->isremote)
- l->disctime = 1;
- else
- l->disctime = DISC_TIME;
- rpt_mutex_lock(&myrpt->lock);
- ast_hangup(l->chan);
- l->chan = 0;
- break;
- }
- if (l->retrytimer)
- {
- if (l->chan) ast_hangup(l->chan);
- l->chan = 0;
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected))
- {
- rpt_mutex_lock(&myrpt->lock);
- if (l->chan) ast_hangup(l->chan);
- l->chan = 0;
- l->hasconnected = 1;
- l->elaptime = 0;
- l->retrytimer = RETRY_TIMER_MS;
- l->connecttime = 0;
- l->thisconnected = 0;
- break;
- }
- rpt_mutex_lock(&myrpt->lock);
- /* remove from queue */
- remque((struct qelem *) l);
- if (!strcmp(myrpt->cmdnode,l->name))
- myrpt->cmdnode[0] = 0;
- __kickshort(myrpt);
- rpt_mutex_unlock(&myrpt->lock);
- if (!l->hasconnected)
- rpt_telemetry(myrpt,CONNFAIL,l);
- else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- if (!l->hasconnected)
- sprintf(str,"LINKFAIL,%s",l->name);
- else
- sprintf(str,"LINKDISC,%s",l->name);
- donodelog(myrpt,str);
- }
- if (l->lastf1) ast_frfree(l->lastf1);
- l->lastf1 = NULL;
- if (l->lastf2) ast_frfree(l->lastf2);
- l->lastf2 = NULL;
- /* hang-up on call to device */
- ast_hangup(l->chan);
- ast_hangup(l->pchan);
- free(l);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- }
- ast_frfree(f);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if (who == l->pchan)
- {
- rpt_mutex_unlock(&myrpt->lock);
- f = ast_read(l->pchan);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- toexit = 1;
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- if (l->chan) ast_write(l->chan,f);
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- toexit = 1;
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- }
- ast_frfree(f);
- rpt_mutex_lock(&myrpt->lock);
- break;
- }
- l = l->next;
- }
- rpt_mutex_unlock(&myrpt->lock);
- if (toexit) break;
- if (who == myrpt->monchannel)
- {
- f = ast_read(myrpt->monchannel);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- if (myrpt->monstream)
- ast_writestream(myrpt->monstream,f);
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- if (who == myrpt->txpchannel) /* if it was a read from remote tx */
- {
- f = ast_read(myrpt->txpchannel);
- if (!f)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- }
- usleep(100000);
- ast_hangup(myrpt->pchannel);
- ast_hangup(myrpt->monchannel);
- ast_hangup(myrpt->txpchannel);
- if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
- if (myrpt->zaptxchannel != myrpt->txchannel) ast_hangup(myrpt->zaptxchannel);
- if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
- myrpt->lastf1 = NULL;
- if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
- myrpt->lastf2 = NULL;
- ast_hangup(myrpt->rxchannel);
- rpt_mutex_lock(&myrpt->lock);
- l = myrpt->links.next;
- while(l != &myrpt->links)
- {
- struct rpt_link *ll = l;
- /* remove from queue */
- remque((struct qelem *) l);
- /* hang-up on call to device */
- if (l->chan) ast_hangup(l->chan);
- ast_hangup(l->pchan);
- l = l->next;
- free(ll);
- }
- rpt_mutex_unlock(&myrpt->lock);
- if (debug) printf("@@@@ rpt:Hung up channel\n");
- myrpt->rpt_thread = AST_PTHREADT_STOP;
- pthread_exit(NULL);
- return NULL;
-}
-
-
-static void *rpt_master(void *ignore)
-{
-int i,n;
-pthread_attr_t attr;
-struct ast_config *cfg;
-char *this,*val;
-
- /* init nodelog queue */
- nodelog.next = nodelog.prev = &nodelog;
- /* go thru all the specified repeaters */
- this = NULL;
- n = 0;
- /* wait until asterisk starts */
- while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED))
- usleep(250000);
- rpt_vars[n].cfg = ast_config_load("rpt.conf");
- cfg = rpt_vars[n].cfg;
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n");
- pthread_exit(NULL);
- }
- while((this = ast_category_browse(cfg,this)) != NULL)
- {
- for(i = 0 ; i < strlen(this) ; i++){
- if((this[i] < '0') || (this[i] > '9'))
- break;
- }
- if(i != strlen(this)) continue; /* Not a node defn */
- memset(&rpt_vars[n],0,sizeof(rpt_vars[n]));
- rpt_vars[n].name = strdup(this);
- val = (char *) ast_variable_retrieve(cfg,this,"rxchannel");
- if (val) rpt_vars[n].rxchanname = strdup(val);
- val = (char *) ast_variable_retrieve(cfg,this,"txchannel");
- if (val) rpt_vars[n].txchanname = strdup(val);
- val = (char *) ast_variable_retrieve(cfg,this,"remote");
- if (val) rpt_vars[n].remote = strdup(val);
- ast_mutex_init(&rpt_vars[n].lock);
- ast_mutex_init(&rpt_vars[n].remlock);
- rpt_vars[n].tele.next = &rpt_vars[n].tele;
- rpt_vars[n].tele.prev = &rpt_vars[n].tele;
- rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
- rpt_vars[n].tailmessagen = 0;
-#ifdef _MDC_DECODE_H_
- rpt_vars[n].mdc = mdc_decoder_new(8000);
-#endif
- n++;
- }
- nrpts = n;
- ast_config_destroy(cfg);
-
- /* start em all */
- for(i = 0; i < n; i++)
- {
- load_rpt_vars(i,1);
-
- /* if is a remote, dont start one for it */
- if (rpt_vars[i].remote)
- {
- if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */
- strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1);
- strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
-
- strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1);
- rpt_vars[i].remmode = REM_MODE_FM;
- rpt_vars[i].offset = REM_SIMPLEX;
- rpt_vars[i].powerlevel = REM_MEDPWR;
- }
- continue;
- }
- if (!rpt_vars[i].p.ident)
- {
- ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name);
- ast_config_destroy(cfg);
- pthread_exit(NULL);
- }
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
- }
- usleep(500000);
- time(&starttime);
- for(;;)
- {
- /* Now monitor each thread, and restart it if necessary */
- for(i = 0; i < n; i++)
- {
- int rv;
- if (rpt_vars[i].remote) continue;
- if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP)
- rv = -1;
- else
- rv = pthread_kill(rpt_vars[i].rpt_thread,0);
- if (rv)
- {
- if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15)
- {
- if(rpt_vars[i].threadrestarts >= 5)
- {
- ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n");
- exit(1); /* Stuck in a restart loop, kill Asterisk and start over */
- }
- else
- {
- ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name);
- rpt_vars[i].threadrestarts++;
- }
- }
- else
- rpt_vars[i].threadrestarts = 0;
-
- rpt_vars[i].lastthreadrestarttime = time(NULL);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
- ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name);
- }
-
- }
- for(;;)
- {
- struct nodelog *nodep;
- char *space,datestr[100],fname[300];
- int fd;
-
- ast_mutex_lock(&nodeloglock);
- nodep = nodelog.next;
- if(nodep == &nodelog) /* if nothing in queue */
- {
- ast_mutex_unlock(&nodeloglock);
- break;
- }
- remque((struct qelem *)nodep);
- ast_mutex_unlock(&nodeloglock);
- space = strchr(nodep->str,' ');
- if (!space)
- {
- free(nodep);
- continue;
- }
- *space = 0;
- strftime(datestr,sizeof(datestr) - 1,"%Y%m%d",
- localtime(&nodep->timestamp));
- sprintf(fname,"%s/%s/%s.txt",nodep->archivedir,
- nodep->str,datestr);
- fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600);
- if (fd == -1)
- {
- ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1);
- free(nodep);
- continue;
- }
- if (write(fd,space + 1,strlen(space + 1)) !=
- strlen(space + 1))
- {
- ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1);
- free(nodep);
- continue;
- }
- close(fd);
- free(nodep);
- }
- usleep(2000000);
- }
- ast_config_destroy(cfg);
- pthread_exit(NULL);
-}
-
-static int rpt_exec(struct ast_channel *chan, void *data)
-{
- int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0;
- int iskenwood_pci4,authtold,authreq,setting,notremming,reming;
- int ismuted,dtmfed;
-#ifdef OLD_ASTERISK
- struct localuser *u;
-#endif
- char tmp[256], keyed = 0,keyed1 = 0;
- char *options,*stringp,*tele,c;
- struct rpt *myrpt;
- struct ast_frame *f,*f1,*f2;
- struct ast_channel *who;
- struct ast_channel *cs[20];
- struct rpt_link *l;
- ZT_CONFINFO ci; /* conference info */
- ZT_PARAMS par;
- int ms,elap,nullfd;
- time_t t,last_timeout_warning;
- struct zt_radio_param z;
- struct rpt_tele *telem;
-
- nullfd = open("/dev/null",O_RDWR);
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n");
- return -1;
- }
-
- strncpy(tmp, (char *)data, sizeof(tmp)-1);
- time(&t);
- /* if time has externally shifted negative, screw it */
- if (t < starttime) t = starttime + START_DELAY;
- if ((!starttime) || (t < (starttime + START_DELAY)))
- {
- ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp);
- ast_safe_sleep(chan,3000);
- return -1;
- }
- stringp=tmp;
- strsep(&stringp, "|");
- options = stringp;
- myrpt = NULL;
- /* see if we can find our specified one */
- for(i = 0; i < nrpts; i++)
- {
- /* if name matches, assign it and exit loop */
- if (!strcmp(tmp,rpt_vars[i].name))
- {
- myrpt = &rpt_vars[i];
- break;
- }
- }
- if (myrpt == NULL)
- {
- ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp);
- return -1;
- }
-
- if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming connections if disabled */
- ast_log(LOG_NOTICE, "Connect attempt to node %s with tx disabled", myrpt->name);
- return -1;
- }
-
- /* if not phone access, must be an IAX connection */
- if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R')))
- {
- int val;
-
- phone_mode = 1;
- if (*options == 'D') phone_mode = 2;
- ast_set_callerid(chan,"0","app_rpt user","0");
- val = 1;
- ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
- }
- else
- {
-#ifdef ALLOW_LOCAL_CHANNELS
- /* Check to insure the connection is IAX2 or Local*/
- if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) {
- ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n");
- return -1;
- }
-#else
- if (strncmp(chan->name,"IAX2",4))
- {
- ast_log(LOG_WARNING, "We only accept links via IAX2!!\n");
- return -1;
- }
-#endif
- }
- if (options && (*options == 'R'))
- {
-
- /* Parts of this section taken from app_parkandannounce */
- char *return_context;
- int l, m, lot, timeout = 0;
- char tmp[256],*template;
- char *working, *context, *exten, *priority;
- char *s,*orig_s;
-
-
- rpt_mutex_lock(&myrpt->lock);
- m = myrpt->callmode;
- rpt_mutex_unlock(&myrpt->lock);
-
- if ((!myrpt->p.nobusyout) && m)
- {
- if (chan->_state != AST_STATE_UP)
- {
- ast_indicate(chan,AST_CONTROL_BUSY);
- }
- while(ast_safe_sleep(chan,10000) != -1);
- return -1;
- }
-
- if (chan->_state != AST_STATE_UP)
- {
- ast_answer(chan);
- }
-
- l=strlen(options)+2;
- orig_s=malloc(l);
- if(!orig_s) {
- ast_log(LOG_WARNING, "Out of memory\n");
- return -1;
- }
- s=orig_s;
- strncpy(s,options,l);
-
- template=strsep(&s,"|");
- if(!template) {
- ast_log(LOG_WARNING, "An announce template must be defined\n");
- free(orig_s);
- return -1;
- }
-
- if(s) {
- timeout = atoi(strsep(&s, "|"));
- timeout *= 1000;
- }
-
- return_context = s;
-
- if(return_context != NULL) {
- /* set the return context. Code borrowed from the Goto builtin */
-
- working = return_context;
- context = strsep(&working, "|");
- exten = strsep(&working, "|");
- if(!exten) {
- /* Only a priority in this one */
- priority = context;
- exten = NULL;
- context = NULL;
- } else {
- priority = strsep(&working, "|");
- if(!priority) {
- /* Only an extension and priority in this one */
- priority = exten;
- exten = context;
- context = NULL;
- }
- }
- if(atoi(priority) < 0) {
- ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
- free(orig_s);
- return -1;
- }
- /* At this point we have a priority and maybe an extension and a context */
- chan->priority = atoi(priority);
-#ifdef OLD_ASTERISK
- if(exten && strcasecmp(exten, "BYEXTENSION"))
-#else
- if(exten)
-#endif
- strncpy(chan->exten, exten, sizeof(chan->exten)-1);
- if(context)
- strncpy(chan->context, context, sizeof(chan->context)-1);
- } else { /* increment the priority by default*/
- chan->priority++;
- }
-
- if(option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
- if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
- ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
- }
- }
-
- /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
- before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
-
- ast_masq_park_call(chan, NULL, timeout, &lot);
-
- if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
-
- snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1);
-
- rpt_telemetry(myrpt,REV_PATCH,tmp);
-
- free(orig_s);
-
- return 0;
-
- }
-
- if (!options)
- {
- struct ast_hostent ahp;
- struct hostent *hp;
- struct in_addr ia;
- char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1;
-
- /* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
- {
- ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
- return -1;
- }
-
- /* get his IP from IAX2 module */
- memset(hisip,0,sizeof(hisip));
-#ifdef ALLOW_LOCAL_CHANNELS
- /* set IP address if this is a local connection*/
- if (strncmp(chan->name,"Local",5)==0) {
- strcpy(hisip,"127.0.0.1");
- } else {
- pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
- }
-#else
- pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
-#endif
-
- if (!hisip[0])
- {
- ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n");
- return -1;
- }
-
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
- ast_shrink_phone_number(b1);
- if (!strcmp(myrpt->name,b1))
- {
- ast_log(LOG_WARNING, "Trying to link to self!!\n");
- return -1;
- }
-
- if (*b1 < '1')
- {
- ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1);
- return -1;
- }
-
-
- /* look for his reported node string */
- val = node_lookup(myrpt,b1);
- if (!val)
- {
- ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1);
- return -1;
- }
- strncpy(tmp,val,sizeof(tmp) - 1);
- s = tmp;
- s1 = strsep(&s,",");
- s2 = strsep(&s,",");
- if (!s2)
- {
- ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1);
- return -1;
- }
- if (strcmp(s2,"NONE")) {
- hp = ast_gethostbyname(s2, &ahp);
- if (!hp)
- {
- ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2);
- return -1;
- }
- memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
-#ifdef OLD_ASTERISK
- ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
-#else
- strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
-#endif
- if (strcmp(hisip,nodeip))
- {
- char *s3 = strchr(s1,'@');
- if (s3) s1 = s3 + 1;
- s3 = strchr(s1,'/');
- if (s3) *s3 = 0;
- hp = ast_gethostbyname(s1, &ahp);
- if (!hp)
- {
- ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1);
- return -1;
- }
- memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
-#ifdef OLD_ASTERISK
- ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
-#else
- strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
-#endif
- if (strcmp(hisip,nodeip))
- {
- ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip);
- return -1;
- }
- }
- }
- }
-
- /* if is not a remote */
- if (!myrpt->remote)
- {
-
- char *b,*b1;
- int reconnects = 0;
-
- /* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
- {
- ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
- return -1;
- }
-
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
- ast_shrink_phone_number(b1);
- if (!strcmp(myrpt->name,b1))
- {
- ast_log(LOG_WARNING, "Trying to link to self!!\n");
- return -1;
- }
- rpt_mutex_lock(&myrpt->lock);
- l = myrpt->links.next;
- /* try to find this one in queue */
- while(l != &myrpt->links)
- {
- if (l->name[0] == '0')
- {
- l = l->next;
- continue;
- }
- /* if found matching string */
- if (!strcmp(l->name,b1)) break;
- l = l->next;
- }
- /* if found */
- if (l != &myrpt->links)
- {
- l->killme = 1;
- l->retries = l->max_retries + 1;
- l->disced = 2;
- reconnects = l->reconnects;
- reconnects++;
- rpt_mutex_unlock(&myrpt->lock);
- usleep(500000);
- } else
- rpt_mutex_unlock(&myrpt->lock);
- /* establish call in tranceive mode */
- l = malloc(sizeof(struct rpt_link));
- if (!l)
- {
- ast_log(LOG_WARNING, "Unable to malloc\n");
- pthread_exit(NULL);
- }
- /* zero the silly thing */
- memset((char *)l,0,sizeof(struct rpt_link));
- l->mode = 1;
- strncpy(l->name,b1,MAXNODESTR - 1);
- l->isremote = 0;
- l->chan = chan;
- l->connected = 1;
- l->thisconnected = 1;
- l->hasconnected = 1;
- l->reconnects = reconnects;
- l->phonemode = phone_mode;
- l->lastf1 = NULL;
- l->lastf2 = NULL;
- l->dtmfed = 0;
- ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
- ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
- /* allocate a pseudo-channel thru asterisk */
- l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!l->pchan)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- pthread_exit(NULL);
- }
- ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
- ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- /* make a conference for the tx */
- ci.chan = 0;
- ci.confno = myrpt->conf;
- ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
- /* first put the channel on the conference in proper mode */
- if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- pthread_exit(NULL);
- }
- rpt_mutex_lock(&myrpt->lock);
- if (phone_mode > 1) l->lastrx = 1;
- l->max_retries = MAX_RETRIES;
- /* insert at end of queue */
- insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
- __kickshort(myrpt);
- rpt_mutex_unlock(&myrpt->lock);
- if (chan->_state != AST_STATE_UP) {
- ast_answer(chan);
- }
- if (myrpt->p.archivedir)
- {
- char str[100];
-
- if (l->phonemode)
- sprintf(str,"LINK(P),%s",l->name);
- else
- sprintf(str,"LINK,%s",l->name);
- donodelog(myrpt,str);
- }
- return AST_PBX_KEEPALIVE;
- }
- /* well, then it is a remote */
- rpt_mutex_lock(&myrpt->lock);
- /* if remote, error if anyone else already linked */
- if (myrpt->remoteon)
- {
- rpt_mutex_unlock(&myrpt->lock);
- usleep(500000);
- if (myrpt->remoteon)
- {
- ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp);
- return -1;
- }
- rpt_mutex_lock(&myrpt->lock);
- }
- if ((!strcmp(myrpt->remote, remote_rig_rbi)) &&
- (ioperm(myrpt->p.iobase,1,1) == -1))
- {
- rpt_mutex_unlock(&myrpt->lock);
- ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
- return -1;
- }
- myrpt->remoteon = 1;
-#ifdef OLD_ASTERISK
- LOCAL_USER_ADD(u);
-#endif
- rpt_mutex_unlock(&myrpt->lock);
- /* find our index, and load the vars initially */
- for(i = 0; i < nrpts; i++)
- {
- if (&rpt_vars[i] == myrpt)
- {
- load_rpt_vars(i,0);
- break;
- }
- }
- rpt_mutex_lock(&myrpt->lock);
- tele = strchr(myrpt->rxchanname,'/');
- if (!tele)
- {
- fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
- rpt_mutex_unlock(&myrpt->lock);
- pthread_exit(NULL);
- }
- *tele++ = 0;
- myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL);
- myrpt->zaprxchannel = NULL;
- if (!strcasecmp(myrpt->rxchanname,"Zap"))
- myrpt->zaprxchannel = myrpt->rxchannel;
- if (myrpt->rxchannel)
- {
- ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- myrpt->rxchannel->whentohangup = 0;
- myrpt->rxchannel->appl = "Apprpt";
- myrpt->rxchannel->data = "(Link Rx)";
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
- myrpt->rxchanname,tele,myrpt->rxchannel->name);
- rpt_mutex_unlock(&myrpt->lock);
- ast_call(myrpt->rxchannel,tele,999);
- rpt_mutex_lock(&myrpt->lock);
- }
- else
- {
- fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- pthread_exit(NULL);
- }
- *--tele = '/';
- myrpt->zaptxchannel = NULL;
- if (myrpt->txchanname)
- {
- tele = strchr(myrpt->txchanname,'/');
- if (!tele)
- {
- fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- pthread_exit(NULL);
- }
- *tele++ = 0;
- myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL);
- if (!strcasecmp(myrpt->txchanname,"Zap"))
- myrpt->zaptxchannel = myrpt->txchannel;
- if (myrpt->txchannel)
- {
- ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- myrpt->txchannel->whentohangup = 0;
- myrpt->txchannel->appl = "Apprpt";
- myrpt->txchannel->data = "(Link Tx)";
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
- myrpt->txchanname,tele,myrpt->txchannel->name);
- rpt_mutex_unlock(&myrpt->lock);
- ast_call(myrpt->txchannel,tele,999);
- rpt_mutex_lock(&myrpt->lock);
- }
- else
- {
- fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->rxchannel);
- pthread_exit(NULL);
- }
- *--tele = '/';
- }
- else
- {
- myrpt->txchannel = myrpt->rxchannel;
- }
- /* allocate a pseudo-channel thru asterisk */
- myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
- if (!myrpt->pchannel)
- {
- fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- pthread_exit(NULL);
- }
- ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
- ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
-#ifdef AST_CDR_FLAG_POST_DISABLED
- ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
-#endif
- if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel;
- if (!myrpt->zaptxchannel) myrpt->zaptxchannel = myrpt->pchannel;
- /* make a conference for the pseudo */
- ci.chan = 0;
- ci.confno = -1; /* make a new conf */
- ci.confmode = ZT_CONF_CONFANNMON ;
- /* first put the channel on the conference in announce/monitor mode */
- if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
- {
- ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- pthread_exit(NULL);
- }
- /* save pseudo channel conference number */
- myrpt->conf = myrpt->txconf = ci.confno;
- /* if serial io port, open it */
- myrpt->iofd = -1;
- if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1))
- {
- rpt_mutex_unlock(&myrpt->lock);
- ast_hangup(myrpt->pchannel);
- if (myrpt->txchannel != myrpt->rxchannel)
- ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- pthread_exit(NULL);
- }
- iskenwood_pci4 = 0;
- memset(&z,0,sizeof(z));
- if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->zaptxchannel))
- {
- z.radpar = ZT_RADPAR_REMMODE;
- z.data = ZT_RADPAR_REM_NONE;
- res = ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z);
- /* if PCIRADIO and kenwood selected */
- if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood)))
- {
- z.radpar = ZT_RADPAR_UIOMODE;
- z.data = 1;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
- return -1;
- }
- z.radpar = ZT_RADPAR_UIODATA;
- z.data = 3;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIODATA\n");
- return -1;
- }
- i = ZT_OFFHOOK;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set hook\n");
- return -1;
- }
- iskenwood_pci4 = 1;
- }
- }
- if (myrpt->txchannel == myrpt->zaptxchannel)
- {
- i = ZT_ONHOOK;
- ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i);
- /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */
- if ((myrpt->iofd < 1) && (!res) &&
- (!strcmp(myrpt->remote,remote_rig_ft897) ||
- (!strcmp(myrpt->remote,remote_rig_ic706))))
- {
- z.radpar = ZT_RADPAR_UIOMODE;
- z.data = 1;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
- return -1;
- }
- z.radpar = ZT_RADPAR_UIODATA;
- z.data = 3;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIODATA\n");
- return -1;
- }
- }
- }
- myrpt->remoterx = 0;
- myrpt->remotetx = 0;
- myrpt->retxtimer = 0;
- myrpt->rerxtimer = 0;
- myrpt->remoteon = 1;
- myrpt->dtmfidx = -1;
- myrpt->dtmfbuf[0] = 0;
- myrpt->dtmf_time_rem = 0;
- myrpt->hfscanmode = 0;
- myrpt->hfscanstatus = 0;
- if (myrpt->p.startupmacro)
- {
- snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
- }
- time(&myrpt->start_time);
- myrpt->last_activity_time = myrpt->start_time;
- last_timeout_warning = 0;
- myrpt->reload = 0;
- myrpt->tele.next = &myrpt->tele;
- myrpt->tele.prev = &myrpt->tele;
- rpt_mutex_unlock(&myrpt->lock);
- ast_set_write_format(chan, AST_FORMAT_SLINEAR);
- ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- rem_rx = 0;
- remkeyed = 0;
- /* if we are on 2w loop and are a remote, turn EC on */
- if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel))
- {
- i = 128;
- ioctl(myrpt->zaprxchannel->fds[0],ZT_ECHOCANCEL,&i);
- }
- if (chan->_state != AST_STATE_UP) {
- ast_answer(chan);
- }
-
- if (myrpt->rxchannel == myrpt->zaprxchannel)
- {
- if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) != -1)
- {
- if (par.rxisoffhook)
- {
- ast_indicate(chan,AST_CONTROL_RADIO_KEY);
- myrpt->remoterx = 1;
- remkeyed = 1;
- }
- }
- }
- if (myrpt->p.archivedir)
- {
- char mycmd[100],mydate[100],*b,*b1;
- time_t myt;
- long blocksleft;
-
-
- mkdir(myrpt->p.archivedir,0600);
- sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name);
- mkdir(mycmd,0600);
- time(&myt);
- strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
- localtime(&myt));
- sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name,
- myrpt->p.archivedir,myrpt->name,mydate);
- if (myrpt->p.monminblocks)
- {
- blocksleft = diskavail(myrpt);
- if (myrpt->p.remotetimeout)
- {
- blocksleft -= (myrpt->p.remotetimeout *
- MONITOR_DISK_BLOCKS_PER_MINUTE) / 60;
- }
- if (blocksleft >= myrpt->p.monminblocks)
- ast_cli_command(nullfd,mycmd);
- } else ast_cli_command(nullfd,mycmd);
- /* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
- {
- b1 = "0";
- } else {
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
- ast_shrink_phone_number(b1);
- }
- sprintf(mycmd,"CONNECT,%s",b1);
- donodelog(myrpt,mycmd);
- }
- myrpt->loginuser[0] = 0;
- myrpt->loginlevel[0] = 0;
- myrpt->authtelltimer = 0;
- myrpt->authtimer = 0;
- authtold = 0;
- authreq = 0;
- if (myrpt->p.authlevel > 1) authreq = 1;
- setrem(myrpt);
- n = 0;
- dtmfed = 0;
- cs[n++] = chan;
- cs[n++] = myrpt->rxchannel;
- cs[n++] = myrpt->pchannel;
- if (myrpt->rxchannel != myrpt->txchannel)
- cs[n++] = myrpt->txchannel;
- /* start un-locked */
- for(;;)
- {
- if (ast_check_hangup(chan)) break;
- if (ast_check_hangup(myrpt->rxchannel)) break;
- notremming = 0;
- setting = 0;
- reming = 0;
- telem = myrpt->tele.next;
- while(telem != &myrpt->tele)
- {
- if (telem->mode == SETREMOTE) setting = 1;
- if ((telem->mode == SETREMOTE) ||
- (telem->mode == SCAN) ||
- (telem->mode == TUNE)) reming = 1;
- else notremming = 1;
- telem = telem->next;
- }
- if (myrpt->reload)
- {
- myrpt->reload = 0;
- /* find our index, and load the vars */
- for(i = 0; i < nrpts; i++)
- {
- if (&rpt_vars[i] == myrpt)
- {
- load_rpt_vars(i,0);
- break;
- }
- }
- }
- time(&t);
- if (myrpt->p.remotetimeout)
- {
- time_t r;
-
- r = (t - myrpt->start_time);
- if (r >= myrpt->p.remotetimeout)
- {
- sayfile(chan,"rpt/node");
- ast_say_character_str(chan,myrpt->name,NULL,chan->language);
- sayfile(chan,"rpt/timeout");
- ast_safe_sleep(chan,1000);
- break;
- }
- if ((myrpt->p.remotetimeoutwarning) &&
- (r >= (myrpt->p.remotetimeout -
- myrpt->p.remotetimeoutwarning)) &&
- (r <= (myrpt->p.remotetimeout -
- myrpt->p.remotetimeoutwarningfreq)))
- {
- if (myrpt->p.remotetimeoutwarningfreq)
- {
- if ((t - last_timeout_warning) >=
- myrpt->p.remotetimeoutwarningfreq)
- {
- time(&last_timeout_warning);
- rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
- }
- }
- else
- {
- if (!last_timeout_warning)
- {
- time(&last_timeout_warning);
- rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
- }
- }
- }
- }
- if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time)
- {
- time_t r;
-
- r = (t - myrpt->last_activity_time);
- if (r >= myrpt->p.remoteinacttimeout)
- {
- sayfile(chan,"rpt/node");
- ast_say_character_str(chan,myrpt->name,NULL,chan->language);
- sayfile(chan,"rpt/timeout");
- ast_safe_sleep(chan,1000);
- break;
- }
- if ((myrpt->p.remotetimeoutwarning) &&
- (r >= (myrpt->p.remoteinacttimeout -
- myrpt->p.remotetimeoutwarning)) &&
- (r <= (myrpt->p.remoteinacttimeout -
- myrpt->p.remotetimeoutwarningfreq)))
- {
- if (myrpt->p.remotetimeoutwarningfreq)
- {
- if ((t - last_timeout_warning) >=
- myrpt->p.remotetimeoutwarningfreq)
- {
- time(&last_timeout_warning);
- rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
- }
- }
- else
- {
- if (!last_timeout_warning)
- {
- time(&last_timeout_warning);
- rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
- }
- }
- }
- }
- ms = MSWAIT;
- who = ast_waitfor_n(cs,n,&ms);
- if (who == NULL) ms = 0;
- elap = MSWAIT - ms;
- if (myrpt->macrotimer) myrpt->macrotimer -= elap;
- if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
- if (!ms) continue;
- /* do local dtmf timer */
- if (myrpt->dtmf_local_timer)
- {
- if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
- if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
- }
- rpt_mutex_lock(&myrpt->lock);
- do_dtmf_local(myrpt,0);
- rpt_mutex_unlock(&myrpt->lock);
- rem_totx = myrpt->dtmf_local_timer && (!phone_mode);
- rem_totx |= keyed && (!myrpt->tunerequest);
- rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele);
- if(!strcmp(myrpt->remote, remote_rig_ic706))
- rem_totx |= myrpt->tunerequest;
- if (keyed && (!keyed1))
- {
- keyed1 = 1;
- }
-
- if (!keyed && (keyed1))
- {
- time_t myt;
-
- keyed1 = 0;
- time(&myt);
- /* if login necessary, and not too soon */
- if ((myrpt->p.authlevel) &&
- (!myrpt->loginlevel[0]) &&
- (myt > (t + 3)))
- {
- authreq = 1;
- authtold = 0;
- myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME;
- }
- }
-
-
- if (rem_rx && (!myrpt->remoterx))
- {
- myrpt->remoterx = 1;
- ast_indicate(chan,AST_CONTROL_RADIO_KEY);
- }
- if ((!rem_rx) && (myrpt->remoterx))
- {
- myrpt->remoterx = 0;
- ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
- }
- /* if auth requested, and not authed yet */
- if (authreq && (!myrpt->loginlevel[0]))
- {
- if ((!authtold) && ((myrpt->authtelltimer += elap)
- >= AUTHTELLTIME))
- {
- authtold = 1;
- rpt_telemetry(myrpt,LOGINREQ,NULL);
- }
- if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME)
- {
- break; /* if not logged in, hang up after a time */
- }
- }
-#ifndef OLDKEY
- if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME)
- {
- myrpt->retxtimer = 0;
- if ((myrpt->remoterx) && (!myrpt->remotetx))
- ast_indicate(chan,AST_CONTROL_RADIO_KEY);
- else
- ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
- }
-
- if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2))
- {
- keyed = 0;
- myrpt->rerxtimer = 0;
- }
-#endif
- if (rem_totx && (!myrpt->remotetx))
- {
- /* if not authed, and needed, dont transmit */
- if ((!myrpt->p.authlevel) || myrpt->loginlevel[0])
- {
- myrpt->remotetx = 1;
- if((myrpt->remtxfreqok = check_tx_freq(myrpt)))
- {
- time(&myrpt->last_activity_time);
- if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
- {
- z.radpar = ZT_RADPAR_UIODATA;
- z.data = 1;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIODATA\n");
- return -1;
- }
- }
- else
- {
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
- }
- if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY");
- }
- }
- }
- if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */
- {
- myrpt->remotetx = 0;
- if(!myrpt->remtxfreqok){
- rpt_telemetry(myrpt,UNAUTHTX,NULL);
- }
- if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
- {
- z.radpar = ZT_RADPAR_UIODATA;
- z.data = 3;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIODATA\n");
- return -1;
- }
- }
- else
- {
- ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
- }
- if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY");
- }
- if (myrpt->hfscanmode){
- myrpt->scantimer -= elap;
- if(myrpt->scantimer <= 0){
- if (!reming)
- {
- myrpt->scantimer = REM_SCANTIME;
- rpt_telemetry(myrpt,SCAN,0);
- } else myrpt->scantimer = 1;
- }
- }
- rpt_mutex_lock(&myrpt->lock);
- c = myrpt->macrobuf[0];
- if (c && (!myrpt->macrotimer))
- {
- myrpt->macrotimer = MACROTIME;
- memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
- if ((c == 'p') || (c == 'P'))
- myrpt->macrotimer = MACROPTIME;
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->p.archivedir)
- {
- char str[100];
- sprintf(str,"DTMF(M),%c",c);
- donodelog(myrpt,str);
- }
- if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break;
- continue;
- } else rpt_mutex_unlock(&myrpt->lock);
- if (who == chan) /* if it was a read from incomming */
- {
- f = ast_read(chan);
- if (!f)
- {
- if (debug) printf("@@@@ link:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- if (ioctl(chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
- {
- ismuted = 0;
- }
- /* if not transmitting, zero-out audio */
- ismuted |= (!myrpt->remotetx);
- if (dtmfed && phone_mode) ismuted = 1;
- dtmfed = 0;
- if (ismuted)
- {
- memset(f->data,0,f->datalen);
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- }
- if (f) f2 = ast_frdup(f);
- else f2 = NULL;
- f1 = myrpt->lastf2;
- myrpt->lastf2 = myrpt->lastf1;
- myrpt->lastf1 = f2;
- if (ismuted)
- {
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- }
- if (f1)
- {
- if (phone_mode)
- ast_write(myrpt->txchannel,f1);
- else
- ast_write(myrpt->txchannel,f);
- ast_frfree(f1);
- }
- }
-#ifndef OLD_ASTERISK
- else if (f->frametype == AST_FRAME_DTMF_BEGIN)
- {
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- dtmfed = 1;
- }
-#endif
- if (f->frametype == AST_FRAME_DTMF)
- {
- if (myrpt->lastf1)
- memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
- if (myrpt->lastf2)
- memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
- dtmfed = 1;
- if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- if (f->frametype == AST_FRAME_TEXT)
- {
- if (handle_remote_data(myrpt,f->data) == -1)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- /* if RX key */
- if (f->subclass == AST_CONTROL_RADIO_KEY)
- {
- if (debug == 7) printf("@@@@ rx key\n");
- keyed = 1;
- myrpt->rerxtimer = 0;
- }
- /* if RX un-key */
- if (f->subclass == AST_CONTROL_RADIO_UNKEY)
- {
- myrpt->rerxtimer = 0;
- if (debug == 7) printf("@@@@ rx un-key\n");
- keyed = 0;
- }
- }
- ast_frfree(f);
- continue;
- }
- if (who == myrpt->rxchannel) /* if it was a read from radio */
- {
- f = ast_read(myrpt->rxchannel);
- if (!f)
- {
- if (debug) printf("@@@@ link:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- int myreming = 0;
-
- if(!strcmp(myrpt->remote, remote_rig_kenwood))
- myreming = reming;
-
- if (myreming || (!remkeyed) ||
- ((myrpt->remote) && (myrpt->remotetx)) ||
- ((myrpt->remmode != REM_MODE_FM) &&
- notremming))
- memset(f->data,0,f->datalen);
- ast_write(myrpt->pchannel,f);
- }
- else if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- /* if RX key */
- if (f->subclass == AST_CONTROL_RADIO_KEY)
- {
- if (debug == 7) printf("@@@@ remote rx key\n");
- if (!myrpt->remotetx)
- {
- remkeyed = 1;
- }
- }
- /* if RX un-key */
- if (f->subclass == AST_CONTROL_RADIO_UNKEY)
- {
- if (debug == 7) printf("@@@@ remote rx un-key\n");
- if (!myrpt->remotetx)
- {
- remkeyed = 0;
- }
- }
- }
- ast_frfree(f);
- continue;
- }
- if (who == myrpt->pchannel) /* if is remote mix output */
- {
- f = ast_read(myrpt->pchannel);
- if (!f)
- {
- if (debug) printf("@@@@ link:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_VOICE)
- {
- ast_write(chan,f);
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- if ((myrpt->rxchannel != myrpt->txchannel) &&
- (who == myrpt->txchannel)) /* do this cuz you have to */
- {
- f = ast_read(myrpt->txchannel);
- if (!f)
- {
- if (debug) printf("@@@@ link:Hung Up\n");
- break;
- }
- if (f->frametype == AST_FRAME_CONTROL)
- {
- if (f->subclass == AST_CONTROL_HANGUP)
- {
- if (debug) printf("@@@@ rpt:Hung Up\n");
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- continue;
- }
- }
- if (myrpt->p.archivedir)
- {
- char mycmd[100],*b,*b1;
-
- /* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
- {
- b1 = "0";
- } else {
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
- ast_shrink_phone_number(b1);
- }
- sprintf(mycmd,"DISCONNECT,%s",b1);
- donodelog(myrpt,mycmd);
- }
- /* wait for telem to be done */
- while(myrpt->tele.next != &myrpt->tele) usleep(100000);
- sprintf(tmp,"mixmonitor stop %s",chan->name);
- ast_cli_command(nullfd,tmp);
- close(nullfd);
- rpt_mutex_lock(&myrpt->lock);
- myrpt->hfscanmode = 0;
- myrpt->hfscanstatus = 0;
- myrpt->remoteon = 0;
- rpt_mutex_unlock(&myrpt->lock);
- if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
- myrpt->lastf1 = NULL;
- if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
- myrpt->lastf2 = NULL;
- if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
- {
- z.radpar = ZT_RADPAR_UIOMODE;
- z.data = 3;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
- return -1;
- }
- z.radpar = ZT_RADPAR_UIODATA;
- z.data = 3;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIODATA\n");
- return -1;
- }
- i = ZT_OFFHOOK;
- if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set hook\n");
- return -1;
- }
- }
- if (myrpt->iofd) close(myrpt->iofd);
- myrpt->iofd = -1;
- ast_hangup(myrpt->pchannel);
- if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel);
- ast_hangup(myrpt->rxchannel);
- closerem(myrpt);
-#ifdef OLD_ASTERISK
- LOCAL_USER_REMOVE(u);
-#endif
- return res;
-}
-
-#ifdef OLD_ASTERISK
-int unload_module()
-#else
-static int unload_module(void)
-#endif
-{
- int i;
-
-#ifdef OLD_ASTERISK
- STANDARD_HANGUP_LOCALUSERS;
-#endif
- for(i = 0; i < nrpts; i++) {
- if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue;
- ast_mutex_destroy(&rpt_vars[i].lock);
- ast_mutex_destroy(&rpt_vars[i].remlock);
- }
- i = ast_unregister_application(app);
-
- /* Unregister cli extensions */
- ast_cli_unregister(&cli_debug);
- ast_cli_unregister(&cli_dump);
- ast_cli_unregister(&cli_stats);
- ast_cli_unregister(&cli_lstats);
- ast_cli_unregister(&cli_nodes);
- ast_cli_unregister(&cli_reload);
- ast_cli_unregister(&cli_restart);
- ast_cli_unregister(&cli_fun);
-
- return i;
-}
-
-#ifdef OLD_ASTERISK
-int load_module()
-#else
-static int load_module(void)
-#endif
-{
- ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL);
-
- /* Register cli extensions */
- ast_cli_register(&cli_debug);
- ast_cli_register(&cli_dump);
- ast_cli_register(&cli_stats);
- ast_cli_register(&cli_lstats);
- ast_cli_register(&cli_nodes);
- ast_cli_register(&cli_reload);
- ast_cli_register(&cli_restart);
- ast_cli_register(&cli_fun);
-
- return ast_register_application(app, rpt_exec, synopsis, descrip);
-}
-
-#ifdef OLD_ASTERISK
-char *description()
-{
- return tdesc;
-}
-int usecount(void)
-{
- int res;
- STANDARD_USECOUNT(res);
- return res;
-}
-
-char *key()
-{
- return ASTERISK_GPL_KEY;
-}
-#endif
-
-#ifdef OLD_ASTERISK
-int reload()
-#else
-static int reload(void)
-#endif
-{
-int n;
-
- for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
- return(0);
-}
-
-#ifndef OLD_ASTERISK
-/* STD_MOD(MOD_1, reload, NULL, NULL); */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Radio Repeater/Remote Base Application",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
-#endif
-
diff --git a/1.4/apps/app_sayunixtime.c b/1.4/apps/app_sayunixtime.c
deleted file mode 100644
index 2e9c9b323..000000000
--- a/1.4/apps/app_sayunixtime.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2003, 2006 Tilghman Lesher. All rights reserved.
- * Copyright (c) 2006 Digium, Inc.
- *
- * Tilghman Lesher <app_sayunixtime__200309@the-tilghman.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief SayUnixTime application
- *
- * \author Tilghman Lesher <app_sayunixtime__200309@the-tilghman.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/say.h"
-#include "asterisk/app.h"
-
-static char *app_sayunixtime = "SayUnixTime";
-static char *app_datetime = "DateTime";
-
-static char *sayunixtime_synopsis = "Says a specified time in a custom format";
-
-static char *sayunixtime_descrip =
-"SayUnixTime([unixtime][|[timezone][|format]])\n"
-" unixtime: time, in seconds since Jan 1, 1970. May be negative.\n"
-" defaults to now.\n"
-" timezone: timezone, see /usr/share/zoneinfo for a list.\n"
-" defaults to machine default.\n"
-" format: a format the time is to be said in. See voicemail.conf.\n"
-" defaults to \"ABdY 'digits/at' IMp\"\n";
-static char *datetime_descrip =
-"DateTime([unixtime][|[timezone][|format]])\n"
-" unixtime: time, in seconds since Jan 1, 1970. May be negative.\n"
-" defaults to now.\n"
-" timezone: timezone, see /usr/share/zoneinfo for a list.\n"
-" defaults to machine default.\n"
-" format: a format the time is to be said in. See voicemail.conf.\n"
-" defaults to \"ABdY 'digits/at' IMp\"\n";
-
-
-static int sayunixtime_exec(struct ast_channel *chan, void *data)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(timeval);
- AST_APP_ARG(timezone);
- AST_APP_ARG(format);
- );
- char *parse;
- int res = 0;
- struct ast_module_user *u;
- time_t unixtime;
-
- if (!data)
- return 0;
-
- parse = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- ast_get_time_t(args.timeval, &unixtime, time(NULL), NULL);
-
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
-
- if (!res)
- res = ast_say_date_with_format(chan, unixtime, AST_DIGIT_ANY,
- chan->language, args.format, args.timezone);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_sayunixtime);
- res |= ast_unregister_application(app_datetime);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(app_sayunixtime, sayunixtime_exec, sayunixtime_synopsis, sayunixtime_descrip);
- res |= ast_register_application(app_datetime, sayunixtime_exec, sayunixtime_synopsis, datetime_descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Say time");
diff --git a/1.4/apps/app_senddtmf.c b/1.4/apps/app_senddtmf.c
deleted file mode 100644
index e48ba4fe0..000000000
--- a/1.4/apps/app_senddtmf.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to send DTMF digits
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/manager.h"
-
-static char *app = "SendDTMF";
-
-static char *synopsis = "Sends arbitrary DTMF digits";
-
-static char *descrip =
-" SendDTMF(digits[|timeout_ms]): Sends DTMF digits on a channel. \n"
-" Accepted digits: 0-9, *#abcd, w (.5s pause)\n"
-" The application will either pass the assigned digits or terminate if it\n"
-" encounters an error.\n";
-
-
-static int senddtmf_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *digits = NULL, *to = NULL;
- int timeout = 250;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
- return 0;
- }
-
- u = ast_module_user_add(chan);
-
- digits = ast_strdupa(data);
-
- if ((to = strchr(digits,'|'))) {
- *to = '\0';
- to++;
- timeout = atoi(to);
- }
-
- if (timeout <= 0)
- timeout = 250;
-
- res = ast_dtmf_stream(chan,NULL,digits,timeout);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static char mandescr_playdtmf[] =
-"Description: Plays a dtmf digit on the specified channel.\n"
-"Variables: (all are required)\n"
-" Channel: Channel name to send digit to\n"
-" Digit: The dtmf digit to play\n";
-
-static int manager_play_dtmf(struct mansession *s, const struct message *m)
-{
- const char *channel = astman_get_header(m, "Channel");
- const char *digit = astman_get_header(m, "Digit");
- struct ast_channel *chan = ast_get_channel_by_name_locked(channel);
-
- if (!chan) {
- astman_send_error(s, m, "Channel not specified");
- return 0;
- }
- if (!digit) {
- astman_send_error(s, m, "No digit specified");
- ast_mutex_unlock(&chan->lock);
- return 0;
- }
-
- ast_senddigit(chan, *digit);
-
- ast_mutex_unlock(&chan->lock);
- astman_send_ack(s, m, "DTMF successfully queued");
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
- res |= ast_manager_unregister("PlayDTMF");
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_manager_register2( "PlayDTMF", EVENT_FLAG_CALL, manager_play_dtmf, "Play DTMF signal on a specific channel.", mandescr_playdtmf );
- res |= ast_register_application(app, senddtmf_exec, synopsis, descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send DTMF digits Application");
diff --git a/1.4/apps/app_sendtext.c b/1.4/apps/app_sendtext.c
deleted file mode 100644
index 6828e3f76..000000000
--- a/1.4/apps/app_sendtext.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to transmit a text message
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note Requires support of sending text messages from channel driver
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-
-static const char *app = "SendText";
-
-static const char *synopsis = "Send a Text Message";
-
-static const char *descrip =
-" SendText(text[|options]): Sends text to current channel (callee).\n"
-"Result of transmission will be stored in the SENDTEXTSTATUS\n"
-"channel variable:\n"
-" SUCCESS Transmission succeeded\n"
-" FAILURE Transmission failed\n"
-" UNSUPPORTED Text transmission not supported by channel\n"
-"\n"
-"At this moment, text is supposed to be 7 bit ASCII in most channels.\n"
-"The option string many contain the following character:\n"
-"'j' -- jump to n+101 priority if the channel doesn't support\n"
-" text transport\n";
-
-
-static int sendtext_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *status = "UNSUPPORTED";
- char *parse = NULL;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(text);
- AST_APP_ARG(options);
- );
-
- u = ast_module_user_add(chan);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SendText requires an argument (text[|options])\n");
- ast_module_user_remove(u);
- return -1;
- } else
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- ast_channel_lock(chan);
- if (!chan->tech->send_text) {
- ast_channel_unlock(chan);
- /* Does not support transport */
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- ast_module_user_remove(u);
- return 0;
- }
- status = "FAILURE";
- ast_channel_unlock(chan);
- res = ast_sendtext(chan, args.text);
- if (!res)
- status = "SUCCESS";
- pbx_builtin_setvar_helper(chan, "SENDTEXTSTATUS", status);
- ast_module_user_remove(u);
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, sendtext_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send Text Applications");
diff --git a/1.4/apps/app_setcallerid.c b/1.4/apps/app_setcallerid.c
deleted file mode 100644
index fb060f11b..000000000
--- a/1.4/apps/app_setcallerid.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to set callerid
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/callerid.h"
-
-static char *app2 = "SetCallerPres";
-
-static char *synopsis2 = "Set CallerID Presentation";
-
-
-static char *descrip2 =
-" SetCallerPres(presentation): Set Caller*ID presentation on a call.\n"
-" Valid presentations are:\n"
-"\n"
-" allowed_not_screened : Presentation Allowed, Not Screened\n"
-" allowed_passed_screen : Presentation Allowed, Passed Screen\n"
-" allowed_failed_screen : Presentation Allowed, Failed Screen\n"
-" allowed : Presentation Allowed, Network Number\n"
-" prohib_not_screened : Presentation Prohibited, Not Screened\n"
-" prohib_passed_screen : Presentation Prohibited, Passed Screen\n"
-" prohib_failed_screen : Presentation Prohibited, Failed Screen\n"
-" prohib : Presentation Prohibited, Network Number\n"
-" unavailable : Number Unavailable\n"
-"\n"
-;
-
-static int setcallerid_pres_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- int pres = -1;
-
- u = ast_module_user_add(chan);
-
- /* For interface consistency, permit the argument to be specified as a number */
- if (sscanf(data, "%d", &pres) != 1 || pres < 0 || pres > 255 || (pres & 0x9c)) {
- pres = ast_parse_caller_presentation(data);
- }
-
- if (pres < 0) {
- ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show application SetCallerPres')\n",
- (char *) data);
- ast_module_user_remove(u);
- return 0;
- }
-
- chan->cid.cid_pres = pres;
- ast_module_user_remove(u);
- return 0;
-}
-
-static char *app = "SetCallerID";
-
-static char *synopsis = "Set CallerID";
-
-static char *descrip =
-" SetCallerID(clid[|a]): Set Caller*ID on a call to a new\n"
-"value. Sets ANI as well if a flag is used. \n";
-
-static int setcallerid_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- char *tmp = NULL;
- char name[256];
- char num[256];
- struct ast_module_user *u;
- char *opt;
- int anitoo = 0;
- static int dep_warning = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SetCallerID requires an argument!\n");
- return 0;
- }
-
- u = ast_module_user_add(chan);
-
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "SetCallerID is deprecated. Please use Set(CALLERID(all)=...) or Set(CALLERID(ani)=...) instead.\n");
- }
-
- tmp = ast_strdupa(data);
-
- opt = strchr(tmp, '|');
- if (opt) {
- *opt = '\0';
- opt++;
- if (*opt == 'a')
- anitoo = 1;
- }
-
- ast_callerid_split(tmp, name, sizeof(name), num, sizeof(num));
- ast_set_callerid(chan, num, name, anitoo ? num : NULL);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app2);
- res |= ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(app2, setcallerid_pres_exec, synopsis2, descrip2);
- res |= ast_register_application(app, setcallerid_exec, synopsis, descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Set CallerID Application");
diff --git a/1.4/apps/app_setcdruserfield.c b/1.4/apps/app_setcdruserfield.c
deleted file mode 100644
index ccfbcedd2..000000000
--- a/1.4/apps/app_setcdruserfield.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Justin Huff <jjhuff@mspin.net>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Applictions connected with CDR engine
- *
- * \author Justin Huff <jjhuff@mspin.net>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/config.h"
-#include "asterisk/manager.h"
-#include "asterisk/utils.h"
-
-
-static char *setcdruserfield_descrip =
- "[Synopsis]\n"
- "SetCDRUserField(value)\n\n"
- "[Description]\n"
- "SetCDRUserField(value): Set the CDR 'user field' to value\n"
- " The Call Data Record (CDR) user field is an extra field you\n"
- " can use for data not stored anywhere else in the record.\n"
- " CDR records can be used for billing or storing other arbitrary data\n"
- " (I.E. telephone survey responses)\n"
- " Also see AppendCDRUserField().\n"
- "\nThis application is deprecated in favor of Set(CDR(userfield)=...)\n";
-
-
-static char *setcdruserfield_app = "SetCDRUserField";
-static char *setcdruserfield_synopsis = "Set the CDR user field";
-
-static char *appendcdruserfield_descrip =
- "[Synopsis]\n"
- "AppendCDRUserField(value)\n\n"
- "[Description]\n"
- "AppendCDRUserField(value): Append value to the CDR user field\n"
- " The Call Data Record (CDR) user field is an extra field you\n"
- " can use for data not stored anywhere else in the record.\n"
- " CDR records can be used for billing or storing other arbitrary data\n"
- " (I.E. telephone survey responses)\n"
- " Also see SetCDRUserField().\n"
- "\nThis application is deprecated in favor of Set(CDR(userfield)=...)\n";
-
-static char *appendcdruserfield_app = "AppendCDRUserField";
-static char *appendcdruserfield_synopsis = "Append to the CDR user field";
-
-
-static int action_setcdruserfield(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *userfield = astman_get_header(m, "UserField");
- const char *channel = astman_get_header(m, "Channel");
- const char *append = astman_get_header(m, "Append");
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "No Channel specified");
- return 0;
- }
- if (ast_strlen_zero(userfield)) {
- astman_send_error(s, m, "No UserField specified");
- return 0;
- }
- c = ast_get_channel_by_name_locked(channel);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- if (ast_true(append))
- ast_cdr_appenduserfield(c, userfield);
- else
- ast_cdr_setuserfield(c, userfield);
- ast_mutex_unlock(&c->lock);
- astman_send_ack(s, m, "CDR Userfield Set");
- return 0;
-}
-
-static int setcdruserfield_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- int res = 0;
- static int dep_warning = 0;
-
- u = ast_module_user_add(chan);
-
- if (chan->cdr && data) {
- ast_cdr_setuserfield(chan, (char*)data);
- }
-
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "SetCDRUserField is deprecated. Please use CDR(userfield) instead.\n");
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int appendcdruserfield_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- int res = 0;
- static int dep_warning = 0;
-
- u = ast_module_user_add(chan);
-
- if (chan->cdr && data) {
- ast_cdr_appenduserfield(chan, (char*)data);
- }
-
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "AppendCDRUserField is deprecated. Please use CDR(userfield) instead.\n");
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(setcdruserfield_app);
- res |= ast_unregister_application(appendcdruserfield_app);
- res |= ast_manager_unregister("SetCDRUserField");
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(setcdruserfield_app, setcdruserfield_exec, setcdruserfield_synopsis, setcdruserfield_descrip);
- res |= ast_register_application(appendcdruserfield_app, appendcdruserfield_exec, appendcdruserfield_synopsis, appendcdruserfield_descrip);
- res |= ast_manager_register("SetCDRUserField", EVENT_FLAG_CALL, action_setcdruserfield, "Set the CDR UserField");
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR user field apps");
diff --git a/1.4/apps/app_settransfercapability.c b/1.4/apps/app_settransfercapability.c
deleted file mode 100644
index e29b44e22..000000000
--- a/1.4/apps/app_settransfercapability.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Frank Sautter, levigo holding gmbh, www.levigo.de
- *
- * Frank Sautter - asterisk+at+sautter+dot+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.
- */
-
-/*! \file
- *
- * \brief App to set the ISDN Transfer Capability
- *
- * \author Frank Sautter - asterisk+at+sautter+dot+com
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/transcap.h"
-
-
-static char *app = "SetTransferCapability";
-
-static char *synopsis = "Set ISDN Transfer Capability";
-
-
-static struct { int val; char *name; } transcaps[] = {
- { AST_TRANS_CAP_SPEECH, "SPEECH" },
- { AST_TRANS_CAP_DIGITAL, "DIGITAL" },
- { AST_TRANS_CAP_RESTRICTED_DIGITAL, "RESTRICTED_DIGITAL" },
- { AST_TRANS_CAP_3_1K_AUDIO, "3K1AUDIO" },
- { AST_TRANS_CAP_DIGITAL_W_TONES, "DIGITAL_W_TONES" },
- { AST_TRANS_CAP_VIDEO, "VIDEO" },
-};
-
-static char *descrip =
-" SetTransferCapability(transfercapability): Set the ISDN Transfer \n"
-"Capability of a call to a new value.\n"
-"Valid Transfer Capabilities are:\n"
-"\n"
-" SPEECH : 0x00 - Speech (default, voice calls)\n"
-" DIGITAL : 0x08 - Unrestricted digital information (data calls)\n"
-" RESTRICTED_DIGITAL : 0x09 - Restricted digital information\n"
-" 3K1AUDIO : 0x10 - 3.1kHz Audio (fax calls)\n"
-" DIGITAL_W_TONES : 0x11 - Unrestricted digital information with tones/announcements\n"
-" VIDEO : 0x18 - Video\n"
-"\n"
-"This application is deprecated in favor of Set(CHANNEL(transfercapability)=...)\n"
-;
-
-static int settransfercapability_exec(struct ast_channel *chan, void *data)
-{
- char *tmp = NULL;
- struct ast_module_user *u;
- int x;
- char *opts;
- int transfercapability = -1;
- static int dep_warning = 0;
-
- u = ast_module_user_add(chan);
-
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "SetTransferCapability is deprecated. Please use CHANNEL(transfercapability) instead.\n");
- }
-
- if (data)
- tmp = ast_strdupa(data);
- else
- tmp = "";
-
- opts = strchr(tmp, '|');
- if (opts)
- *opts = '\0';
-
- for (x = 0; x < (sizeof(transcaps) / sizeof(transcaps[0])); x++) {
- if (!strcasecmp(transcaps[x].name, tmp)) {
- transfercapability = transcaps[x].val;
- break;
- }
- }
- if (transfercapability < 0) {
- ast_log(LOG_WARNING, "'%s' is not a valid transfer capability (see 'show application SetTransferCapability')\n", tmp);
- ast_module_user_remove(u);
- return 0;
- }
-
- chan->transfercapability = (unsigned short)transfercapability;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting transfer capability to: 0x%.2x - %s.\n", transfercapability, tmp);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, settransfercapability_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Set ISDN Transfer Capability");
diff --git a/1.4/apps/app_skel.c b/1.4/apps/app_skel.c
deleted file mode 100644
index 55830ebee..000000000
--- a/1.4/apps/app_skel.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) <Year>, <Your Name Here>
- *
- * <Your Name Here> <<Your Email Here>>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Skeleton application
- *
- * \author <Your Name Here> <<Your Email Here>>
- *
- * This is a skeleton for development of an Asterisk application
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <defaultenabled>no</defaultenabled>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-
-static char *app = "Skel";
-static char *synopsis =
-"Skeleton application.";
-static char *descrip = "This application is a template to build other applications from.\n"
- " It shows you the basic structure to create your own Asterisk applications.\n";
-
-enum {
- OPTION_A = (1 << 0),
- OPTION_B = (1 << 1),
- OPTION_C = (1 << 2),
-} option_flags;
-
-enum {
- OPTION_ARG_B = 0,
- OPTION_ARG_C = 1,
- /* This *must* be the last value in this enum! */
- OPTION_ARG_ARRAY_SIZE = 2,
-} option_args;
-
-AST_APP_OPTIONS(app_opts,{
- AST_APP_OPTION('a', OPTION_A),
- AST_APP_OPTION_ARG('b', OPTION_B, OPTION_ARG_B),
- AST_APP_OPTION_ARG('c', OPTION_C, OPTION_ARG_C),
-});
-
-
-static int app_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_flags flags;
- struct ast_module_user *u;
- char *parse, *opts[OPTION_ARG_ARRAY_SIZE];
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(dummy);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s requires an argument (dummy|[options])\n", app);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- /* Do our thing here */
-
- /* We need to make a copy of the input string if we are going to modify it! */
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.argc == 2)
- ast_app_parse_options(app_opts, &flags, opts, args.options);
-
- if (!ast_strlen_zero(args.dummy))
- ast_log(LOG_NOTICE, "Dummy value is : %s\n", args.dummy);
-
- if (ast_test_flag(&flags, OPTION_A))
- ast_log(LOG_NOTICE, "Option A is set\n");
-
- if (ast_test_flag(&flags, OPTION_B))
- ast_log(LOG_NOTICE, "Option B is set with : %s\n", opts[OPTION_ARG_B] ? opts[OPTION_ARG_B] : "<unspecified>");
-
- if (ast_test_flag(&flags, OPTION_C))
- ast_log(LOG_NOTICE, "Option C is set with : %s\n", opts[OPTION_ARG_C] ? opts[OPTION_ARG_C] : "<unspecified>");
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
- res = ast_unregister_application(app);
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, app_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Skeleton (sample) Application");
diff --git a/1.4/apps/app_sms.c b/1.4/apps/app_sms.c
deleted file mode 100644
index 53e8590df..000000000
--- a/1.4/apps/app_sms.c
+++ /dev/null
@@ -1,1536 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005, Adrian Kennard, rights assigned to Digium
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief SMS application - ETSI ES 201 912 protocol 1 implimentation
- * \ingroup applications
- *
- * \author Adrian Kennard
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/alaw.h"
-#include "asterisk/callerid.h"
-
-/* output using Alaw rather than linear */
-/* #define OUTALAW */
-
-/* ToDo */
-/* Add full VP support */
-/* Handle status report messages (generation and reception) */
-/* Time zones on time stamps */
-/* user ref field */
-
-static volatile unsigned char message_ref; /* arbitary message ref */
-static volatile unsigned int seq; /* arbitrary message sequence number for unqiue files */
-
-static char log_file[255];
-static char spool_dir[255];
-
-static char *app = "SMS";
-
-static char *synopsis = "Communicates with SMS service centres and SMS capable analogue phones";
-
-static char *descrip =
- " SMS(name|[a][s]): SMS handles exchange of SMS data with a call to/from SMS capabale\n"
- "phone or SMS PSTN service center. Can send and/or receive SMS messages.\n"
- "Works to ETSI ES 201 912 compatible with BT SMS PSTN service in UK\n"
- "Typical usage is to use to handle called from the SMS service centre CLI,\n"
- "or to set up a call using 'outgoing' or manager interface to connect\n"
- "service centre to SMS()\n"
- "name is the name of the queue used in /var/spool/asterisk/sms\n"
- "Arguments:\n"
- " a: answer, i.e. send initial FSK packet.\n"
- " s: act as service centre talking to a phone.\n"
- "Messages are processed as per text file message queues.\n"
- "smsq (a separate software) is a command to generate message\n"
- "queues and send messages.\n";
-
-static signed short wave[] = {
- 0, 392, 782, 1167, 1545, 1913, 2270, 2612, 2939, 3247, 3536, 3802, 4045, 4263, 4455, 4619, 4755, 4862, 4938, 4985,
- 5000, 4985, 4938, 4862, 4755, 4619, 4455, 4263, 4045, 3802, 3536, 3247, 2939, 2612, 2270, 1913, 1545, 1167, 782, 392,
- 0, -392, -782, -1167,
- -1545, -1913, -2270, -2612, -2939, -3247, -3536, -3802, -4045, -4263, -4455, -4619, -4755, -4862, -4938, -4985, -5000,
- -4985, -4938, -4862,
- -4755, -4619, -4455, -4263, -4045, -3802, -3536, -3247, -2939, -2612, -2270, -1913, -1545, -1167, -782, -392
-};
-
-#ifdef OUTALAW
-static unsigned char wavea[80];
-#endif
-
-
-/* SMS 7 bit character mapping to UCS-2 */
-static const unsigned short defaultalphabet[] = {
- 0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
- 0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
- 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
- 0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
- ' ', '!', '"', '#', 164, '%', '&', 39, '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
- 161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
- 191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 228, 246, 241, 252, 224,
-};
-
-static const unsigned short escapes[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x000C, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0x005E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0x007B, 0x007D, 0, 0, 0, 0, 0, 0x005C,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x005B, 0x007E, 0x005D, 0,
- 0x007C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0x20AC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-#define SMSLEN 160 /* max SMS length */
-
-typedef struct sms_s
-{
- unsigned char hangup; /* we are done... */
- unsigned char err; /* set for any errors */
- unsigned char smsc:1; /* we are SMSC */
- unsigned char rx:1; /* this is a received message */
- char queue[30]; /* queue name */
- char oa[20]; /* originating address */
- char da[20]; /* destination address */
- time_t scts; /* time stamp, UTC */
- unsigned char pid; /* protocol ID */
- unsigned char dcs; /* data coding scheme */
- short mr; /* message reference - actually a byte, but usde -1 for not set */
- int udl; /* user data length */
- int udhl; /* user data header length */
- unsigned char srr:1; /* Status Report request */
- unsigned char udhi:1; /* User Data Header required, even if length 0 */
- unsigned char rp:1; /* Reply Path */
- unsigned int vp; /* validity period in minutes, 0 for not set */
- unsigned short ud[SMSLEN]; /* user data (message), UCS-2 coded */
- unsigned char udh[SMSLEN]; /* user data header */
- char cli[20]; /* caller ID */
- unsigned char ophase; /* phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
- unsigned char ophasep; /* phase (0-79) for 1200 bps */
- unsigned char obyte; /* byte being sent */
- unsigned int opause; /* silent pause before sending (in sample periods) */
- unsigned char obitp; /* bit in byte */
- unsigned char osync; /* sync bits to send */
- unsigned char obytep; /* byte in data */
- unsigned char obyten; /* bytes in data */
- unsigned char omsg[256]; /* data buffer (out) */
- unsigned char imsg[200]; /* data buffer (in) */
- signed long long ims0,
- imc0,
- ims1,
- imc1; /* magnitude averages sin/cos 0/1 */
- unsigned int idle;
- unsigned short imag; /* signal level */
- unsigned char ips0,
- ips1,
- ipc0,
- ipc1; /* phase sin/cos 0/1 */
- unsigned char ibitl; /* last bit */
- unsigned char ibitc; /* bit run length count */
- unsigned char iphasep; /* bit phase (0-79) for 1200 bps */
- unsigned char ibitn; /* bit number in byte being received */
- unsigned char ibytev; /* byte value being received */
- unsigned char ibytep; /* byte pointer in messafe */
- unsigned char ibytec; /* byte checksum for message */
- unsigned char ierr; /* error flag */
- unsigned char ibith; /* history of last bits */
- unsigned char ibitt; /* total of 1's in last 3 bites */
- /* more to go here */
-} sms_t;
-
-/* different types of encoding */
-#define is7bit(dcs) (((dcs)&0xC0)?(!((dcs)&4)):(!((dcs)&12)))
-#define is8bit(dcs) (((dcs)&0xC0)?(((dcs)&4)):(((dcs)&12)==4))
-#define is16bit(dcs) (((dcs)&0xC0)?0:(((dcs)&12)==8))
-
-static void *sms_alloc (struct ast_channel *chan, void *params)
-{
- return params;
-}
-
-static void sms_release (struct ast_channel *chan, void *data)
-{
- return;
-}
-
-static void sms_messagetx (sms_t * h);
-
-/*! \brief copy number, skipping non digits apart from leading + */
-static void numcpy (char *d, char *s)
-{
- if (*s == '+')
- *d++ = *s++;
- while (*s) {
- if (isdigit (*s))
- *d++ = *s;
- s++;
- }
- *d = 0;
-}
-
-/*! \brief static, return a date/time in ISO format */
-static char * isodate (time_t t)
-{
- static char date[20];
- strftime (date, sizeof (date), "%Y-%m-%dT%H:%M:%S", localtime (&t));
- return date;
-}
-
-/*! \brief reads next UCS character from null terminated UTF-8 string and advanced pointer */
-/* for non valid UTF-8 sequences, returns character as is */
-/* Does not advance pointer for null termination */
-static long utf8decode (unsigned char **pp)
-{
- unsigned char *p = *pp;
- if (!*p)
- return 0; /* null termination of string */
- (*pp)++;
- if (*p < 0xC0)
- return *p; /* ascii or continuation character */
- if (*p < 0xE0) {
- if (*p < 0xC2 || (p[1] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp)++;
- return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
- }
- if (*p < 0xF0) {
- if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 2;
- return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
- }
- if (*p < 0xF8) {
- if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 3;
- return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
- }
- if (*p < 0xFC) {
- if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
- || (p[4] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 4;
- return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
- }
- if (*p < 0xFE) {
- if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
- || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 5;
- return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) + (p[5] & 0x3F);
- }
- return *p; /* not sensible */
-}
-
-/*! \brief takes a binary header (udhl bytes at udh) and UCS-2 message (udl characters at ud) and packs in to o using SMS 7 bit character codes */
-/* The return value is the number of septets packed in to o, which is internally limited to SMSLEN */
-/* o can be null, in which case this is used to validate or count only */
-/* if the input contains invalid characters then the return value is -1 */
-static int packsms7 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
-{
- unsigned char p = 0, b = 0, n = 0;
-
- if (udhl) { /* header */
- if (o)
- o[p++] = udhl;
- b = 1;
- n = 1;
- while (udhl--) {
- if (o)
- o[p++] = *udh++;
- b += 8;
- while (b >= 7) {
- b -= 7;
- n++;
- }
- if (n >= SMSLEN)
- return n;
- }
- if (b) {
- b = 7 - b;
- if (++n >= SMSLEN)
- return n;
- }; /* filling to septet boundary */
- }
- if (o)
- o[p] = 0;
- /* message */
- while (udl--) {
- long u;
- unsigned char v;
- u = *ud++;
- for (v = 0; v < 128 && defaultalphabet[v] != u; v++);
- if (v == 128 && u && n + 1 < SMSLEN) {
- for (v = 0; v < 128 && escapes[v] != u; v++);
- if (v < 128) { /* escaped sequence */
- if (o)
- o[p] |= (27 << b);
- b += 7;
- if (b >= 8) {
- b -= 8;
- p++;
- if (o)
- o[p] = (27 >> (7 - b));
- }
- n++;
- }
- }
- if (v == 128)
- return -1; /* invalid character */
- if (o)
- o[p] |= (v << b);
- b += 7;
- if (b >= 8) {
- b -= 8;
- p++;
- if (o)
- o[p] = (v >> (7 - b));
- }
- if (++n >= SMSLEN)
- return n;
- }
- return n;
-}
-
-/*! \brief takes a binary header (udhl bytes at udh) and UCS-2 message (udl characters at ud) and packs in to o using 8 bit character codes */
-/* The return value is the number of bytes packed in to o, which is internally limited to 140 */
-/* o can be null, in which case this is used to validate or count only */
-/* if the input contains invalid characters then the return value is -1 */
-static int packsms8 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
-{
- unsigned char p = 0;
-
- /* header - no encoding */
- if (udhl) {
- if (o)
- o[p++] = udhl;
- while (udhl--) {
- if (o)
- o[p++] = *udh++;
- if (p >= 140)
- return p;
- }
- }
- while (udl--) {
- long u;
- u = *ud++;
- if (u < 0 || u > 0xFF)
- return -1; /* not valid */
- if (o)
- o[p++] = u;
- if (p >= 140)
- return p;
- }
- return p;
-}
-
-/*! \brief takes a binary header (udhl bytes at udh) and UCS-2
- message (udl characters at ud) and packs in to o using 16 bit
- UCS-2 character codes
- The return value is the number of bytes packed in to o, which is
- internally limited to 140
- o can be null, in which case this is used to validate or count
- only if the input contains invalid characters then
- the return value is -1 */
-static int packsms16 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
-{
- unsigned char p = 0;
- /* header - no encoding */
- if (udhl) {
- if (o)
- o[p++] = udhl;
- while (udhl--) {
- if (o)
- o[p++] = *udh++;
- if (p >= 140)
- return p;
- }
- }
- while (udl--) {
- long u;
- u = *ud++;
- if (o)
- o[p++] = (u >> 8);
- if (p >= 140)
- return p - 1; /* could not fit last character */
- if (o)
- o[p++] = u;
- if (p >= 140)
- return p;
- }
- return p;
-}
-
-/*! \brief general pack, with length and data,
- returns number of bytes of target used */
-static int packsms (unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud)
-{
- unsigned char *p = base;
- if (udl) {
- int l = 0;
- if (is7bit (dcs)) { /* 7 bit */
- l = packsms7 (p + 1, udhl, udh, udl, ud);
- if (l < 0)
- l = 0;
- *p++ = l;
- p += (l * 7 + 7) / 8;
- } else if (is8bit (dcs)) { /* 8 bit */
- l = packsms8 (p + 1, udhl, udh, udl, ud);
- if (l < 0)
- l = 0;
- *p++ = l;
- p += l;
- } else { /* UCS-2 */
- l = packsms16 (p + 1, udhl, udh, udl, ud);
- if (l < 0)
- l = 0;
- *p++ = l;
- p += l;
- }
- } else
- *p++ = 0; /* no user data */
- return p - base;
-}
-
-
-/*! \brief pack a date and return */
-static void packdate (unsigned char *o, time_t w)
-{
- struct tm *t = localtime (&w);
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
- int z = -t->tm_gmtoff / 60 / 15;
-#else
- int z = timezone / 60 / 15;
-#endif
- *o++ = ((t->tm_year % 10) << 4) + (t->tm_year % 100) / 10;
- *o++ = (((t->tm_mon + 1) % 10) << 4) + (t->tm_mon + 1) / 10;
- *o++ = ((t->tm_mday % 10) << 4) + t->tm_mday / 10;
- *o++ = ((t->tm_hour % 10) << 4) + t->tm_hour / 10;
- *o++ = ((t->tm_min % 10) << 4) + t->tm_min / 10;
- *o++ = ((t->tm_sec % 10) << 4) + t->tm_sec / 10;
- if (z < 0)
- *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
- else
- *o++ = ((z % 10) << 4) + z / 10;
-}
-
-/*! \brief unpack a date and return */
-static time_t unpackdate (unsigned char *i)
-{
- struct tm t;
- t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
- t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
- t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
- t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
- t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
- t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
- t.tm_isdst = 0;
- if (i[6] & 0x08)
- t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
- else
- t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
- return ast_mktime(&t, NULL);
-}
-
-/*! \brief unpacks bytes (7 bit encoding) at i, len l septets,
- and places in udh and ud setting udhl and udl. udh not used
- if udhi not set */
-static void unpacksms7 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
-{
- unsigned char b = 0, p = 0;
- unsigned short *o = ud;
- *udhl = 0;
- if (udhi && l) { /* header */
- int h = i[p];
- *udhl = h;
- if (h) {
- b = 1;
- p++;
- l--;
- while (h-- && l) {
- *udh++ = i[p++];
- b += 8;
- while (b >= 7) {
- b -= 7;
- l--;
- if (!l)
- break;
- }
- }
- /* adjust for fill, septets */
- if (b) {
- b = 7 - b;
- l--;
- }
- }
- }
- while (l--) {
- unsigned char v;
- if (b < 2)
- v = ((i[p] >> b) & 0x7F);
- else
- v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
- b += 7;
- if (b >= 8) {
- b -= 8;
- p++;
- }
- if (o > ud && o[-1] == 0x00A0 && escapes[v])
- o[-1] = escapes[v];
- else
- *o++ = defaultalphabet[v];
- }
- *udl = (o - ud);
-}
-
-/*! \brief unpacks bytes (8 bit encoding) at i, len l septets,
- and places in udh and ud setting udhl and udl. udh not used
- if udhi not set */
-static void unpacksms8 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
-{
- unsigned short *o = ud;
- *udhl = 0;
- if (udhi) {
- int n = *i;
- *udhl = n;
- if (n) {
- i++;
- l--;
- while (l && n) {
- l--;
- n--;
- *udh++ = *i++;
- }
- }
- }
- while (l--)
- *o++ = *i++; /* not to UTF-8 as explicitely 8 bit coding in DCS */
- *udl = (o - ud);
-}
-
-/*! \brief unpacks bytes (16 bit encoding) at i, len l septets,
- and places in udh and ud setting udhl and udl.
- udh not used if udhi not set */
-static void unpacksms16 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
-{
- unsigned short *o = ud;
- *udhl = 0;
- if (udhi) {
- int n = *i;
- *udhl = n;
- if (n) {
- i++;
- l--;
- while (l && n) {
- l--;
- n--;
- *udh++ = *i++;
- }
- }
- }
- while (l--) {
- int v = *i++;
- if (l--)
- v = (v << 8) + *i++;
- *o++ = v;
- }
- *udl = (o - ud);
-}
-
-/*! \brief general unpack - starts with length byte (octet or septet) and returns number of bytes used, inc length */
-static int unpacksms (unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
-{
- int l = *i++;
- if (is7bit (dcs)) {
- unpacksms7 (i, l, udh, udhl, ud, udl, udhi);
- l = (l * 7 + 7) / 8; /* adjust length to return */
- } else if (is8bit (dcs))
- unpacksms8 (i, l, udh, udhl, ud, udl, udhi);
- else
- unpacksms16 (i, l, udh, udhl, ud, udl, udhi);
- return l + 1;
-}
-
-/*! \brief unpack an address from i, return byte length, unpack to o */
-static unsigned char unpackaddress (char *o, unsigned char *i)
-{
- unsigned char l = i[0],
- p;
- if (i[1] == 0x91)
- *o++ = '+';
- for (p = 0; p < l; p++) {
- if (p & 1)
- *o++ = (i[2 + p / 2] >> 4) + '0';
- else
- *o++ = (i[2 + p / 2] & 0xF) + '0';
- }
- *o = 0;
- return (l + 5) / 2;
-}
-
-/*! \brief store an address at o, and return number of bytes used */
-static unsigned char packaddress (unsigned char *o, char *i)
-{
- unsigned char p = 2;
- o[0] = 0;
- if (*i == '+') {
- i++;
- o[1] = 0x91;
- } else
- o[1] = 0x81;
- while (*i)
- if (isdigit (*i)) {
- if (o[0] & 1)
- o[p++] |= ((*i & 0xF) << 4);
- else
- o[p] = (*i & 0xF);
- o[0]++;
- i++;
- } else
- i++;
- if (o[0] & 1)
- o[p++] |= 0xF0; /* pad */
- return p;
-}
-
-/*! \brief Log the output, and remove file */
-static void sms_log (sms_t * h, char status)
-{
- if (*h->oa || *h->da) {
- int o = open (log_file, O_CREAT | O_APPEND | O_WRONLY, 0666);
- if (o >= 0) {
- char line[1000], mrs[3] = "", *p;
- unsigned char n;
-
- if (h->mr >= 0)
- snprintf (mrs, sizeof (mrs), "%02X", h->mr);
- snprintf (line, sizeof (line), "%s %c%c%c%s %s %s %s ",
- isodate (time (0)), status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue, *h->oa ? h->oa : "-",
- *h->da ? h->da : "-");
- p = line + strlen (line);
- for (n = 0; n < h->udl; n++)
- if (h->ud[n] == '\\') {
- *p++ = '\\';
- *p++ = '\\';
- } else if (h->ud[n] == '\n') {
- *p++ = '\\';
- *p++ = 'n';
- } else if (h->ud[n] == '\r') {
- *p++ = '\\';
- *p++ = 'r';
- } else if (h->ud[n] < 32 || h->ud[n] == 127)
- *p++ = 191;
- else
- *p++ = h->ud[n];
- *p++ = '\n';
- *p = 0;
- write (o, line, strlen (line));
- close (o);
- }
- *h->oa = *h->da = h->udl = 0;
- }
-}
-
-/*! \brief parse and delete a file */
-static void sms_readfile (sms_t * h, char *fn)
-{
- char line[1000];
- FILE *s;
- char dcsset = 0; /* if DSC set */
- ast_log (LOG_EVENT, "Sending %s\n", fn);
- h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
- h->mr = -1;
- h->dcs = 0xF1; /* normal messages class 1 */
- h->scts = time (0);
- s = fopen (fn, "r");
- if (s)
- {
- if (unlink (fn))
- { /* concurrent access, we lost */
- fclose (s);
- return;
- }
- while (fgets (line, sizeof (line), s))
- { /* process line in file */
- char *p;
- void *pp = &p;
- for (p = line; *p && *p != '\n' && *p != '\r'; p++);
- *p = 0; /* strip eoln */
- p = line;
- if (!*p || *p == ';')
- continue; /* blank line or comment, ignore */
- while (isalnum (*p))
- {
- *p = tolower (*p);
- p++;
- }
- while (isspace (*p))
- *p++ = 0;
- if (*p == '=')
- {
- *p++ = 0;
- if (!strcmp (line, "ud"))
- { /* parse message (UTF-8) */
- unsigned char o = 0;
- while (*p && o < SMSLEN)
- h->ud[o++] = utf8decode(pp);
- h->udl = o;
- if (*p)
- ast_log (LOG_WARNING, "UD too long in %s\n", fn);
- } else
- {
- while (isspace (*p))
- p++;
- if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa))
- numcpy (h->oa, p);
- else if (!strcmp (line, "da") && strlen (p) < sizeof (h->oa))
- numcpy (h->da, p);
- else if (!strcmp (line, "pid"))
- h->pid = atoi (p);
- else if (!strcmp (line, "dcs"))
- {
- h->dcs = atoi (p);
- dcsset = 1;
- } else if (!strcmp (line, "mr"))
- h->mr = atoi (p);
- else if (!strcmp (line, "srr"))
- h->srr = (atoi (p) ? 1 : 0);
- else if (!strcmp (line, "vp"))
- h->vp = atoi (p);
- else if (!strcmp (line, "rp"))
- h->rp = (atoi (p) ? 1 : 0);
- else if (!strcmp (line, "scts"))
- { /* get date/time */
- int Y,
- m,
- d,
- H,
- M,
- S;
- if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6)
- {
- struct tm t;
- t.tm_year = Y - 1900;
- t.tm_mon = m - 1;
- t.tm_mday = d;
- t.tm_hour = H;
- t.tm_min = M;
- t.tm_sec = S;
- t.tm_isdst = -1;
- h->scts = ast_mktime(&t, NULL);
- if (h->scts == (time_t) - 1)
- ast_log (LOG_WARNING, "Bad date/timein %s: %s", fn, p);
- }
- } else
- ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
- }
- } else if (*p == '#')
- { /* raw hex format */
- *p++ = 0;
- if (*p == '#')
- {
- p++;
- if (!strcmp (line, "ud"))
- { /* user data */
- int o = 0;
- while (*p && o < SMSLEN)
- {
- if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3]))
- {
- h->ud[o++] =
- (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
- (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
- (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF));
- p += 4;
- } else
- break;
- }
- h->udl = o;
- if (*p)
- ast_log (LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
- } else
- ast_log (LOG_WARNING, "Only ud can use ## format, %s\n", fn);
- } else if (!strcmp (line, "ud"))
- { /* user data */
- int o = 0;
- while (*p && o < SMSLEN)
- {
- if (isxdigit (*p) && isxdigit (p[1]))
- {
- h->ud[o++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
- p += 2;
- } else
- break;
- }
- h->udl = o;
- if (*p)
- ast_log (LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
- } else if (!strcmp (line, "udh"))
- { /* user data header */
- unsigned char o = 0;
- h->udhi = 1;
- while (*p && o < SMSLEN)
- {
- if (isxdigit (*p) && isxdigit (p[1]))
- {
- h->udh[o] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
- o++;
- p += 2;
- } else
- break;
- }
- h->udhl = o;
- if (*p)
- ast_log (LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
- } else
- ast_log (LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
- } else
- ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
- }
- fclose (s);
- if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
- {
- if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
- {
- if (packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
- ast_log (LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
- else
- {
- h->dcs = 0x08; /* default to 16 bit */
- ast_log (LOG_WARNING, "Sending in 16 bit format (%s)\n", fn);
- }
- } else
- {
- h->dcs = 0xF5; /* default to 8 bit */
- ast_log (LOG_WARNING, "Sending in 8 bit format (%s)\n", fn);
- }
- }
- if (is7bit (h->dcs) && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
- ast_log (LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
- if (is8bit (h->dcs) && packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
- ast_log (LOG_WARNING, "Invalid 8 bit data %s\n", fn);
- if (is16bit (h->dcs) && packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
- ast_log (LOG_WARNING, "Invalid 16 bit data %s\n", fn);
- }
-}
-
-/*! \brief white a received text message to a file */
-static void sms_writefile (sms_t * h)
-{
- char fn[200] = "", fn2[200] = "";
- FILE *o;
- ast_copy_string (fn, spool_dir, sizeof (fn));
- mkdir (fn, 0777); /* ensure it exists */
- snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
- mkdir (fn, 0777); /* ensure it exists */
- ast_copy_string (fn2, fn, sizeof (fn2));
- snprintf (fn2 + strlen (fn2), sizeof (fn2) - strlen (fn2), "/%s.%s-%d", h->queue, isodate (h->scts), seq++);
- snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/.%s", fn2 + strlen (fn) + 1);
- o = fopen (fn, "w");
- if (o) {
- if (*h->oa)
- fprintf (o, "oa=%s\n", h->oa);
- if (*h->da)
- fprintf (o, "da=%s\n", h->da);
- if (h->udhi) {
- unsigned int p;
- fprintf (o, "udh#");
- for (p = 0; p < h->udhl; p++)
- fprintf (o, "%02X", h->udh[p]);
- fprintf (o, "\n");
- }
- if (h->udl) {
- unsigned int p;
- for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
- if (p < h->udl)
- fputc (';', o); /* cannot use ud=, but include as a comment for human readable */
- fprintf (o, "ud=");
- for (p = 0; p < h->udl; p++) {
- unsigned short v = h->ud[p];
- if (v < 32)
- fputc (191, o);
- else if (v < 0x80)
- fputc (v, o);
- else if (v < 0x800)
- {
- fputc (0xC0 + (v >> 6), o);
- fputc (0x80 + (v & 0x3F), o);
- } else
- {
- fputc (0xE0 + (v >> 12), o);
- fputc (0x80 + ((v >> 6) & 0x3F), o);
- fputc (0x80 + (v & 0x3F), o);
- }
- }
- fprintf (o, "\n");
- for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
- if (p < h->udl) {
- for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
- if (p == h->udl) { /* can write in ucs-1 hex */
- fprintf (o, "ud#");
- for (p = 0; p < h->udl; p++)
- fprintf (o, "%02X", h->ud[p]);
- fprintf (o, "\n");
- } else { /* write in UCS-2 */
- fprintf (o, "ud##");
- for (p = 0; p < h->udl; p++)
- fprintf (o, "%04X", h->ud[p]);
- fprintf (o, "\n");
- }
- }
- }
- if (h->scts)
- fprintf (o, "scts=%s\n", isodate (h->scts));
- if (h->pid)
- fprintf (o, "pid=%d\n", h->pid);
- if (h->dcs != 0xF1)
- fprintf (o, "dcs=%d\n", h->dcs);
- if (h->vp)
- fprintf (o, "vp=%d\n", h->vp);
- if (h->srr)
- fprintf (o, "srr=1\n");
- if (h->mr >= 0)
- fprintf (o, "mr=%d\n", h->mr);
- if (h->rp)
- fprintf (o, "rp=1\n");
- fclose (o);
- if (rename (fn, fn2))
- unlink (fn);
- else
- ast_log (LOG_EVENT, "Received to %s\n", fn2);
- }
-}
-
-/*! \brief read dir skipping dot files... */
-static struct dirent *readdirqueue (DIR * d, char *queue)
-{
- struct dirent *f;
- do {
- f = readdir (d);
- } while (f && (*f->d_name == '.' || strncmp (f->d_name, queue, strlen (queue)) || f->d_name[strlen (queue)] != '.'));
- return f;
-}
-
-/*! \brief handle the incoming message */
-static unsigned char sms_handleincoming (sms_t * h)
-{
- unsigned char p = 3;
- if (h->smsc) { /* SMSC */
- if ((h->imsg[2] & 3) == 1) { /* SMS-SUBMIT */
- h->udhl = h->udl = 0;
- h->vp = 0;
- h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
- h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
- h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
- ast_copy_string (h->oa, h->cli, sizeof (h->oa));
- h->scts = time (0);
- h->mr = h->imsg[p++];
- p += unpackaddress (h->da, h->imsg + p);
- h->pid = h->imsg[p++];
- h->dcs = h->imsg[p++];
- if ((h->imsg[2] & 0x18) == 0x10) { /* relative VP */
- if (h->imsg[p] < 144)
- h->vp = (h->imsg[p] + 1) * 5;
- else if (h->imsg[p] < 168)
- h->vp = 720 + (h->imsg[p] - 143) * 30;
- else if (h->imsg[p] < 197)
- h->vp = (h->imsg[p] - 166) * 1440;
- else
- h->vp = (h->imsg[p] - 192) * 10080;
- p++;
- } else if (h->imsg[2] & 0x18)
- p += 7; /* ignore enhanced / absolute VP */
- p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
- h->rx = 1; /* received message */
- sms_writefile (h); /* write the file */
- if (p != h->imsg[1] + 2) {
- ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
- return 0xFF; /* duh! */
- }
- } else {
- ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
- return 0xFF;
- }
- } else { /* client */
- if (!(h->imsg[2] & 3)) { /* SMS-DELIVER */
- *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
- h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
- h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
- h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
- h->mr = -1;
- p += unpackaddress (h->oa, h->imsg + p);
- h->pid = h->imsg[p++];
- h->dcs = h->imsg[p++];
- h->scts = unpackdate (h->imsg + p);
- p += 7;
- p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
- h->rx = 1; /* received message */
- sms_writefile (h); /* write the file */
- if (p != h->imsg[1] + 2) {
- ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
- return 0xFF; /* duh! */
- }
- } else {
- ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
- return 0xFF;
- }
- }
- return 0; /* no error */
-}
-
-#ifdef SOLARIS
-#define NAME_MAX 1024
-#endif
-
-/*! \brief find and fill in next message, or send a REL if none waiting */
-static void sms_nextoutgoing (sms_t * h)
-{
- char fn[100 + NAME_MAX] = "";
- DIR *d;
- char more = 0;
- ast_copy_string (fn, spool_dir, sizeof (fn));
- mkdir (fn, 0777); /* ensure it exists */
- h->rx = 0; /* outgoing message */
- snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx");
- mkdir (fn, 0777); /* ensure it exists */
- d = opendir (fn);
- if (d) {
- struct dirent *f = readdirqueue (d, h->queue);
- if (f) {
- snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", f->d_name);
- sms_readfile (h, fn);
- if (readdirqueue (d, h->queue))
- more = 1; /* more to send */
- }
- closedir (d);
- }
- if (*h->da || *h->oa) { /* message to send */
- unsigned char p = 2;
- h->omsg[0] = 0x91; /* SMS_DATA */
- if (h->smsc) { /* deliver */
- h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
- p += packaddress (h->omsg + p, h->oa);
- h->omsg[p++] = h->pid;
- h->omsg[p++] = h->dcs;
- packdate (h->omsg + p, h->scts);
- p += 7;
- p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
- } else { /* submit */
- h->omsg[p++] =
- 0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
- if (h->mr < 0)
- h->mr = message_ref++;
- h->omsg[p++] = h->mr;
- p += packaddress (h->omsg + p, h->da);
- h->omsg[p++] = h->pid;
- h->omsg[p++] = h->dcs;
- if (h->vp) { /* relative VP */
- if (h->vp < 720)
- h->omsg[p++] = (h->vp + 4) / 5 - 1;
- else if (h->vp < 1440)
- h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
- else if (h->vp < 43200)
- h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
- else if (h->vp < 635040)
- h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
- else
- h->omsg[p++] = 255; /* max */
- }
- p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
- }
- h->omsg[1] = p - 2;
- sms_messagetx (h);
- } else { /* no message */
- h->omsg[0] = 0x94; /* SMS_REL */
- h->omsg[1] = 0;
- sms_messagetx (h);
- }
-}
-
-static void sms_debug (char *dir, unsigned char *msg)
-{
- char txt[259 * 3 + 1],
- *p = txt; /* always long enough */
- int n = msg[1] + 3,
- q = 0;
- while (q < n && q < 30) {
- sprintf (p, " %02X", msg[q++]);
- p += 3;
- }
- if (q < n)
- sprintf (p, "...");
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "SMS %s%s\n", dir, txt);
-}
-
-static void sms_messagerx(sms_t * h)
-{
- sms_debug ("RX", h->imsg);
- /* testing */
- switch (h->imsg[0]) {
- case 0x91: /* SMS_DATA */
- {
- unsigned char cause = sms_handleincoming (h);
- if (!cause) {
- sms_log (h, 'Y');
- h->omsg[0] = 0x95; /* SMS_ACK */
- h->omsg[1] = 0x02;
- h->omsg[2] = 0x00; /* deliver report */
- h->omsg[3] = 0x00; /* no parameters */
- } else { /* NACK */
- sms_log (h, 'N');
- h->omsg[0] = 0x96; /* SMS_NACK */
- h->omsg[1] = 3;
- h->omsg[2] = 0; /* delivery report */
- h->omsg[3] = cause; /* cause */
- h->omsg[4] = 0; /* no parameters */
- }
- sms_messagetx (h);
- }
- break;
- case 0x92: /* SMS_ERROR */
- h->err = 1;
- sms_messagetx (h); /* send whatever we sent again */
- break;
- case 0x93: /* SMS_EST */
- sms_nextoutgoing (h);
- break;
- case 0x94: /* SMS_REL */
- h->hangup = 1; /* hangup */
- break;
- case 0x95: /* SMS_ACK */
- sms_log (h, 'Y');
- sms_nextoutgoing (h);
- break;
- case 0x96: /* SMS_NACK */
- h->err = 1;
- sms_log (h, 'N');
- sms_nextoutgoing (h);
- break;
- default: /* Unknown */
- h->omsg[0] = 0x92; /* SMS_ERROR */
- h->omsg[1] = 1;
- h->omsg[2] = 3; /* unknown message type; */
- sms_messagetx (h);
- break;
- }
-}
-
-static void sms_messagetx(sms_t * h)
-{
- unsigned char c = 0, p;
- for (p = 0; p < h->omsg[1] + 2; p++)
- c += h->omsg[p];
- h->omsg[h->omsg[1] + 2] = 0 - c;
- sms_debug ("TX", h->omsg);
- h->obyte = 1;
- h->opause = 200;
- if (h->omsg[0] == 0x93)
- h->opause = 2400; /* initial message delay 300ms (for BT) */
- h->obytep = 0;
- h->obitp = 0;
- h->osync = 80;
- h->obyten = h->omsg[1] + 3;
-}
-
-static int sms_generate (struct ast_channel *chan, void *data, int len, int samples)
-{
- struct ast_frame f = { 0 };
-#define MAXSAMPLES (800)
-#ifdef OUTALAW
- unsigned char *buf;
-#else
- short *buf;
-#endif
-#define SAMPLE2LEN sizeof(*buf)
- sms_t *h = data;
- int i;
-
- if (samples > MAXSAMPLES) {
- ast_log (LOG_WARNING, "Only doing %d samples (%d requested)\n",
- MAXSAMPLES, samples);
- samples = MAXSAMPLES;
- }
- len = samples * SAMPLE2LEN + AST_FRIENDLY_OFFSET;
- buf = alloca(len);
-
- f.frametype = AST_FRAME_VOICE;
-#ifdef OUTALAW
- f.subclass = AST_FORMAT_ALAW;
-#else
- f.subclass = AST_FORMAT_SLINEAR;
-#endif
- f.datalen = samples * SAMPLE2LEN;
- f.offset = AST_FRIENDLY_OFFSET;
- f.mallocd = 0;
- f.data = buf;
- f.samples = samples;
- f.src = "app_sms";
- /* create a buffer containing the digital sms pattern */
- for (i = 0; i < samples; i++) {
-#ifdef OUTALAW
- buf[i] = wavea[0];
-#else
- buf[i] = wave[0];
-#endif
- if (h->opause)
- h->opause--;
- else if (h->obyten || h->osync) { /* sending data */
-#ifdef OUTALAW
- buf[i] = wavea[h->ophase];
-#else
- buf[i] = wave[h->ophase];
-#endif
- if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80)
- h->ophase -= 80;
- if ((h->ophasep += 12) >= 80) { /* next bit */
- h->ophasep -= 80;
- if (h->osync)
- h->osync--; /* sending sync bits */
- else {
- h->obyte >>= 1;
- h->obitp++;
- if (h->obitp == 1)
- h->obyte = 0; /* start bit; */
- else if (h->obitp == 2)
- h->obyte = h->omsg[h->obytep];
- else if (h->obitp == 10) {
- h->obyte = 1; /* stop bit */
- h->obitp = 0;
- h->obytep++;
- if (h->obytep == h->obyten) {
- h->obytep = h->obyten = 0; /* sent */
- h->osync = 10; /* trailing marks */
- }
- }
- }
- }
- }
- }
- if (ast_write (chan, &f) < 0) {
- ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror (errno));
- return -1;
- }
- return 0;
-#undef SAMPLE2LEN
-#undef MAXSAMPLES
-}
-
-static void sms_process (sms_t * h, int samples, signed short *data)
-{
- if (h->obyten || h->osync)
- return; /* sending */
- while (samples--) {
- unsigned long long m0, m1;
- if (abs (*data) > h->imag)
- h->imag = abs (*data);
- else
- h->imag = h->imag * 7 / 8;
- if (h->imag > 500) {
- h->idle = 0;
- h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
- h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
- h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
- h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
- m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
- m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
- if ((h->ips0 += 21) >= 80)
- h->ips0 -= 80;
- if ((h->ipc0 += 21) >= 80)
- h->ipc0 -= 80;
- if ((h->ips1 += 13) >= 80)
- h->ips1 -= 80;
- if ((h->ipc1 += 13) >= 80)
- h->ipc1 -= 80;
- {
- char bit;
- h->ibith <<= 1;
- if (m1 > m0)
- h->ibith |= 1;
- if (h->ibith & 8)
- h->ibitt--;
- if (h->ibith & 1)
- h->ibitt++;
- bit = ((h->ibitt > 1) ? 1 : 0);
- if (bit != h->ibitl)
- h->ibitc = 1;
- else
- h->ibitc++;
- h->ibitl = bit;
- if (!h->ibitn && h->ibitc == 4 && !bit) {
- h->ibitn = 1;
- h->iphasep = 0;
- }
- if (bit && h->ibitc == 200) { /* sync, restart message */
- h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
- }
- if (h->ibitn) {
- h->iphasep += 12;
- if (h->iphasep >= 80) { /* next bit */
- h->iphasep -= 80;
- if (h->ibitn++ == 9) { /* end of byte */
- if (!bit) /* bad stop bit */
- h->ierr = 0xFF; /* unknown error */
- else {
- if (h->ibytep < sizeof (h->imsg)) {
- h->imsg[h->ibytep] = h->ibytev;
- h->ibytec += h->ibytev;
- h->ibytep++;
- } else if (h->ibytep == sizeof (h->imsg))
- h->ierr = 2; /* bad message length */
- if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
- if (!h->ibytec)
- sms_messagerx (h);
- else
- h->ierr = 1; /* bad checksum */
- }
- }
- h->ibitn = 0;
- }
- h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
- }
- }
- }
- } else { /* lost carrier */
- if (h->idle++ == 80000) { /* nothing happening */
- ast_log (LOG_EVENT, "No data, hanging up\n");
- h->hangup = 1;
- h->err = 1;
- }
- if (h->ierr) { /* error */
- h->err = 1;
- h->omsg[0] = 0x92; /* error */
- h->omsg[1] = 1;
- h->omsg[2] = h->ierr;
- sms_messagetx (h); /* send error */
- }
- h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
- }
- data++;
- }
-}
-
-static struct ast_generator smsgen = {
- alloc:sms_alloc,
- release:sms_release,
- generate:sms_generate,
-};
-
-static int sms_exec (struct ast_channel *chan, void *data)
-{
- int res = -1;
- struct ast_module_user *u;
- struct ast_frame *f;
- sms_t h = { 0 };
-
- u = ast_module_user_add(chan);
-
- h.ipc0 = h.ipc1 = 20; /* phase for cosine */
- h.dcs = 0xF1; /* default */
- if (!data) {
- ast_log (LOG_ERROR, "Requires queue name at least\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if (chan->cid.cid_num)
- ast_copy_string (h.cli, chan->cid.cid_num, sizeof (h.cli));
-
- {
- unsigned char *p;
- unsigned char *d = data,
- answer = 0;
- if (!*d || *d == '|') {
- ast_log (LOG_ERROR, "Requires queue name\n");
- ast_module_user_remove(u);
- return -1;
- }
- for (p = d; *p && *p != '|'; p++);
- if (p - d >= sizeof (h.queue)) {
- ast_log (LOG_ERROR, "Queue name too long\n");
- ast_module_user_remove(u);
- return -1;
- }
- strncpy(h.queue, (char *)d, p - d);
- if (*p == '|')
- p++;
- d = p;
- for (p = (unsigned char *)h.queue; *p; p++)
- if (!isalnum (*p))
- *p = '-'; /* make very safe for filenames */
- while (*d && *d != '|') {
- switch (*d) {
- case 'a': /* we have to send the initial FSK sequence */
- answer = 1;
- break;
- case 's': /* we are acting as a service centre talking to a phone */
- h.smsc = 1;
- break;
- /* the following apply if there is an arg3/4 and apply to the created message file */
- case 'r':
- h.srr = 1;
- break;
- case 'o':
- h.dcs |= 4; /* octets */
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7': /* set the pid for saved local message */
- h.pid = 0x40 + (*d & 0xF);
- break;
- }
- d++;
- }
- if (*d == '|') {
- /* submitting a message, not taking call. */
- /* deprecated, use smsq instead */
- d++;
- h.scts = time (0);
- for (p = d; *p && *p != '|'; p++);
- if (*p)
- *p++ = 0;
- if (strlen ((char *)d) >= sizeof (h.oa)) {
- ast_log (LOG_ERROR, "Address too long %s\n", d);
- return 0;
- }
- if (h.smsc) {
- ast_copy_string (h.oa, (char *)d, sizeof (h.oa));
- } else {
- ast_copy_string (h.da, (char *)d, sizeof (h.da));
- }
- if (!h.smsc)
- ast_copy_string (h.oa, h.cli, sizeof (h.oa));
- d = p;
- h.udl = 0;
- while (*p && h.udl < SMSLEN)
- h.ud[h.udl++] = utf8decode(&p);
- if (is7bit (h.dcs) && packsms7 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
- ast_log (LOG_WARNING, "Invalid 7 bit GSM data\n");
- if (is8bit (h.dcs) && packsms8 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
- ast_log (LOG_WARNING, "Invalid 8 bit data\n");
- if (is16bit (h.dcs) && packsms16 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
- ast_log (LOG_WARNING, "Invalid 16 bit data\n");
- h.rx = 0; /* sent message */
- h.mr = -1;
- sms_writefile (&h);
- ast_module_user_remove(u);
- return 0;
- }
-
- if (answer) {
- /* set up SMS_EST initial message */
- h.omsg[0] = 0x93;
- h.omsg[1] = 0;
- sms_messagetx (&h);
- }
- }
-
- if (chan->_state != AST_STATE_UP)
- ast_answer (chan);
-
-#ifdef OUTALAW
- res = ast_set_write_format (chan, AST_FORMAT_ALAW);
-#else
- res = ast_set_write_format (chan, AST_FORMAT_SLINEAR);
-#endif
- if (res >= 0)
- res = ast_set_read_format (chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log (LOG_ERROR, "Unable to set to linear mode, giving up\n");
- ast_module_user_remove(u);
- return -1;
- }
-
- if (ast_activate_generator (chan, &smsgen, &h) < 0) {
- ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Do our thing here */
- while (ast_waitfor (chan, -1) > -1 && !h.hangup)
- {
- f = ast_read (chan);
- if (!f)
- break;
- if (f->frametype == AST_FRAME_VOICE) {
- sms_process (&h, f->samples, f->data);
- }
-
- ast_frfree (f);
- }
-
- sms_log (&h, '?'); /* log incomplete message */
-
- ast_module_user_remove(u);
- return (h.err);
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application (app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
-#ifdef OUTALAW
- {
- int p;
- for (p = 0; p < 80; p++)
- wavea[p] = AST_LIN2A (wave[p]);
- }
-#endif
- snprintf (log_file, sizeof (log_file), "%s/sms", ast_config_AST_LOG_DIR);
- snprintf (spool_dir, sizeof (spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR);
- return ast_register_application (app, sms_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");
diff --git a/1.4/apps/app_softhangup.c b/1.4/apps/app_softhangup.c
deleted file mode 100644
index 018edc07d..000000000
--- a/1.4/apps/app_softhangup.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief SoftHangup application
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-
-static char *synopsis = "Soft Hangup Application";
-
-static char *desc = " SoftHangup(Technology/resource|options)\n"
-"Hangs up the requested channel. If there are no channels to hangup,\n"
-"the application will report it.\n"
-"- 'options' may contain the following letter:\n"
-" 'a' : hang up all channels on a specified device instead of a single resource\n";
-
-static char *app = "SoftHangup";
-
-
-static int softhangup_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- struct ast_channel *c=NULL;
- char *options, *cut, *cdata, *match;
- char name[AST_CHANNEL_NAME] = "";
- int all = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
- return 0;
- }
-
- u = ast_module_user_add(chan);
-
- cdata = ast_strdupa(data);
- match = strsep(&cdata, "|");
- options = strsep(&cdata, "|");
- all = options && strchr(options,'a');
- c = ast_channel_walk_locked(NULL);
- while (c) {
- ast_copy_string(name, c->name, sizeof(name));
- ast_mutex_unlock(&c->lock);
- /* XXX watch out, i think it is wrong to access c-> after unlocking! */
- if (all) {
- /* CAPI is set up like CAPI[foo/bar]/clcnt */
- if (!strcmp(c->tech->type, "CAPI"))
- cut = strrchr(name,'/');
- /* Basically everything else is Foo/Bar-Z */
- else
- cut = strchr(name,'-');
- /* Get rid of what we've cut */
- if (cut)
- *cut = 0;
- }
- if (!strcasecmp(name, match)) {
- ast_log(LOG_WARNING, "Soft hanging %s up.\n",c->name);
- ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
- if(!all)
- break;
- }
- c = ast_channel_walk_locked(c);
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, softhangup_exec, synopsis, desc);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Hangs up the requested channel");
diff --git a/1.4/apps/app_speech_utils.c b/1.4/apps/app_speech_utils.c
deleted file mode 100644
index 64d0f1bc4..000000000
--- a/1.4/apps/app_speech_utils.c
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- *
- * \brief Speech Recognition Utility Applications
- *
- * \author Joshua Colp <jcolp@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-#include "asterisk/speech.h"
-
-/* Descriptions for each application */
-static char *speechcreate_descrip =
-"SpeechCreate(engine name)\n"
-"This application creates information to be used by all the other applications. It must be called before doing any speech recognition activities such as activating a grammar.\n"
-"It takes the engine name to use as the argument, if not specified the default engine will be used.\n";
-
-static char *speechactivategrammar_descrip =
-"SpeechActivateGrammar(Grammar Name)\n"
-"This activates the specified grammar to be recognized by the engine. A grammar tells the speech recognition engine what to recognize, \n"
- "and how to portray it back to you in the dialplan. The grammar name is the only argument to this application.\n";
-
-static char *speechstart_descrip =
-"SpeechStart()\n"
- "Tell the speech recognition engine that it should start trying to get results from audio being fed to it. This has no arguments.\n";
-
-static char *speechbackground_descrip =
-"SpeechBackground(Sound File|Timeout)\n"
-"This application plays a sound file and waits for the person to speak. Once they start speaking playback of the file stops, and silence is heard.\n"
-"Once they stop talking the processing sound is played to indicate the speech recognition engine is working.\n"
-"Once results are available the application returns and results (score and text) are available using dialplan functions.\n"
-"The first text and score are ${SPEECH_TEXT(0)} AND ${SPEECH_SCORE(0)} while the second are ${SPEECH_TEXT(1)} and ${SPEECH_SCORE(1)}.\n"
-"The first argument is the sound file and the second is the timeout. Note the timeout will only start once the sound file has stopped playing.\n";
-
-static char *speechdeactivategrammar_descrip =
-"SpeechDeactivateGrammar(Grammar Name)\n"
- "This deactivates the specified grammar so that it is no longer recognized. The only argument is the grammar name to deactivate.\n";
-
-static char *speechprocessingsound_descrip =
-"SpeechProcessingSound(Sound File)\n"
-"This changes the processing sound that SpeechBackground plays back when the speech recognition engine is processing and working to get results.\n"
- "It takes the sound file as the only argument.\n";
-
-static char *speechdestroy_descrip =
-"SpeechDestroy()\n"
-"This destroys the information used by all the other speech recognition applications.\n"
-"If you call this application but end up wanting to recognize more speech, you must call SpeechCreate\n"
- "again before calling any other application. It takes no arguments.\n";
-
-static char *speechload_descrip =
-"SpeechLoadGrammar(Grammar Name|Path)\n"
-"Load a grammar only on the channel, not globally.\n"
-"It takes the grammar name as first argument and path as second.\n";
-
-static char *speechunload_descrip =
-"SpeechUnloadGrammar(Grammar Name)\n"
-"Unload a grammar. It takes the grammar name as the only argument.\n";
-
-/*! \brief Helper function used by datastores to destroy the speech structure upon hangup */
-static void destroy_callback(void *data)
-{
- struct ast_speech *speech = (struct ast_speech*)data;
-
- if (speech == NULL) {
- return;
- }
-
- /* Deallocate now */
- ast_speech_destroy(speech);
-
- return;
-}
-
-/*! \brief Static structure for datastore information */
-static const struct ast_datastore_info speech_datastore = {
- .type = "speech",
- .destroy = destroy_callback
-};
-
-/*! \brief Helper function used to find the speech structure attached to a channel */
-static struct ast_speech *find_speech(struct ast_channel *chan)
-{
- struct ast_speech *speech = NULL;
- struct ast_datastore *datastore = NULL;
-
- datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
- if (datastore == NULL) {
- return NULL;
- }
- speech = datastore->data;
-
- return speech;
-}
-
-/* Helper function to find a specific speech recognition result by number and nbest alternative */
-static struct ast_speech_result *find_result(struct ast_speech_result *results, char *result_num)
-{
- struct ast_speech_result *result = results;
- char *tmp = NULL;
- int nbest_num = 0, wanted_num = 0, i = 0;
-
- if (!result)
- return NULL;
-
- if ((tmp = strchr(result_num, '/'))) {
- *tmp++ = '\0';
- nbest_num = atoi(result_num);
- wanted_num = atoi(tmp);
- } else {
- wanted_num = atoi(result_num);
- }
-
- do {
- if (result->nbest_num != nbest_num)
- continue;
- if (i == wanted_num)
- break;
- i++;
- } while ((result = result->next));
-
- return result;
-}
-
-/*! \brief SPEECH_SCORE() Dialplan Function */
-static int speech_score(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- struct ast_speech_result *result = NULL;
- struct ast_speech *speech = find_speech(chan);
- char tmp[128] = "";
-
- if (data == NULL || speech == NULL || !(result = find_result(speech->results, data)))
- return -1;
-
- snprintf(tmp, sizeof(tmp), "%d", result->score);
-
- ast_copy_string(buf, tmp, len);
-
- return 0;
-}
-
-static struct ast_custom_function speech_score_function = {
- .name = "SPEECH_SCORE",
- .synopsis = "Gets the confidence score of a result.",
- .syntax = "SPEECH_SCORE([nbest number/]result number)",
- .desc =
- "Gets the confidence score of a result.\n",
- .read = speech_score,
- .write = NULL,
-};
-
-/*! \brief SPEECH_TEXT() Dialplan Function */
-static int speech_text(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- struct ast_speech_result *result = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- if (data == NULL || speech == NULL || !(result = find_result(speech->results, data)))
- return -1;
-
- if (result->text != NULL)
- ast_copy_string(buf, result->text, len);
-
- return 0;
-}
-
-static struct ast_custom_function speech_text_function = {
- .name = "SPEECH_TEXT",
- .synopsis = "Gets the recognized text of a result.",
- .syntax = "SPEECH_TEXT([nbest number/]result number)",
- .desc =
- "Gets the recognized text of a result.\n",
- .read = speech_text,
- .write = NULL,
-};
-
-/*! \brief SPEECH_GRAMMAR() Dialplan Function */
-static int speech_grammar(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- struct ast_speech_result *result = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- if (data == NULL || speech == NULL || !(result = find_result(speech->results, data)))
- return -1;
-
- if (result->grammar != NULL)
- ast_copy_string(buf, result->grammar, len);
-
- return 0;
-}
-
-static struct ast_custom_function speech_grammar_function = {
- .name = "SPEECH_GRAMMAR",
- .synopsis = "Gets the matched grammar of a result if available.",
- .syntax = "SPEECH_GRAMMAR([nbest number/]result number)",
- .desc =
- "Gets the matched grammar of a result if available.\n",
- .read = speech_grammar,
- .write = NULL,
-};
-
-/*! \brief SPEECH_ENGINE() Dialplan Function */
-static int speech_engine_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
-{
- struct ast_speech *speech = find_speech(chan);
-
- if (data == NULL || speech == NULL)
- return -1;
-
- ast_speech_change(speech, data, value);
-
- return 0;
-}
-
-static struct ast_custom_function speech_engine_function = {
- .name = "SPEECH_ENGINE",
- .synopsis = "Change a speech engine specific attribute.",
- .syntax = "SPEECH_ENGINE(name)=value",
- .desc =
- "Changes a speech engine specific attribute.\n",
- .read = NULL,
- .write = speech_engine_write,
-};
-
-/*! \brief SPEECH_RESULTS_TYPE() Dialplan Function */
-static int speech_results_type_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
-{
- struct ast_speech *speech = find_speech(chan);
-
- if (data == NULL || speech == NULL)
- return -1;
-
- if (!strcasecmp(value, "normal"))
- ast_speech_change_results_type(speech, AST_SPEECH_RESULTS_TYPE_NORMAL);
- else if (!strcasecmp(value, "nbest"))
- ast_speech_change_results_type(speech, AST_SPEECH_RESULTS_TYPE_NBEST);
-
- return 0;
-}
-
-static struct ast_custom_function speech_results_type_function = {
- .name = "SPEECH_RESULTS_TYPE",
- .synopsis = "Sets the type of results that will be returned.",
- .syntax = "SPEECH_RESULTS_TYPE()=results type",
- .desc =
- "Sets the type of results that will be returned. Valid options are normal or nbest.",
- .read = NULL,
- .write = speech_results_type_write,
-};
-
-/*! \brief SPEECH() Dialplan Function */
-static int speech_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- int results = 0;
- struct ast_speech_result *result = NULL;
- struct ast_speech *speech = find_speech(chan);
- char tmp[128] = "";
-
- /* Now go for the various options */
- if (!strcasecmp(data, "status")) {
- if (speech != NULL)
- ast_copy_string(buf, "1", len);
- else
- ast_copy_string(buf, "0", len);
- return 0;
- }
-
- /* Make sure we have a speech structure for everything else */
- if (speech == NULL) {
- return -1;
- }
-
- /* Check to see if they are checking for silence */
- if (!strcasecmp(data, "spoke")) {
- if (ast_test_flag(speech, AST_SPEECH_SPOKE))
- ast_copy_string(buf, "1", len);
- else
- ast_copy_string(buf, "0", len);
- } else if (!strcasecmp(data, "results")) {
- /* Count number of results */
- result = speech->results;
- while (result) {
- results++;
- result = result->next;
- }
- snprintf(tmp, sizeof(tmp), "%d", results);
- ast_copy_string(buf, tmp, len);
- }
-
- return 0;
-}
-
-static struct ast_custom_function speech_function = {
- .name = "SPEECH",
- .synopsis = "Gets information about speech recognition results.",
- .syntax = "SPEECH(argument)",
- .desc =
- "Gets information about speech recognition results.\n"
- "status: Returns 1 upon speech object existing, or 0 if not\n"
- "spoke: Returns 1 if spoker spoke, or 0 if not\n"
- "results: Returns number of results that were recognized\n",
- .read = speech_read,
- .write = NULL,
-};
-
-
-
-/*! \brief SpeechCreate() Dialplan Application */
-static int speech_create(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = NULL;
- struct ast_datastore *datastore = NULL;
-
- u = ast_module_user_add(chan);
-
- /* Request a speech object */
- speech = ast_speech_new(data, AST_FORMAT_SLINEAR);
- if (speech == NULL) {
- /* Not available */
- pbx_builtin_setvar_helper(chan, "ERROR", "1");
- ast_module_user_remove(u);
- return 0;
- }
-
- datastore = ast_channel_datastore_alloc(&speech_datastore, NULL);
- if (datastore == NULL) {
- ast_speech_destroy(speech);
- pbx_builtin_setvar_helper(chan, "ERROR", "1");
- ast_module_user_remove(u);
- return 0;
- }
- datastore->data = speech;
- ast_channel_datastore_add(chan, datastore);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-/*! \brief SpeechLoadGrammar(Grammar Name|Path) Dialplan Application */
-static int speech_load(struct ast_channel *chan, void *data)
-{
- int res = 0, argc = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
- char *argv[2], *args = NULL, *name = NULL, *path = NULL;
-
- args = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Parse out arguments */
- argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
- if (argc != 2) {
- ast_module_user_remove(u);
- return -1;
- }
- name = argv[0];
- path = argv[1];
-
- /* Load the grammar locally on the object */
- res = ast_speech_grammar_load(speech, name, path);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief SpeechUnloadGrammar(Grammar Name) Dialplan Application */
-static int speech_unload(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Unload the grammar */
- res = ast_speech_grammar_unload(speech, data);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief SpeechDeactivateGrammar(Grammar Name) Dialplan Application */
-static int speech_deactivate(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Deactivate the grammar on the speech object */
- res = ast_speech_grammar_deactivate(speech, data);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief SpeechActivateGrammar(Grammar Name) Dialplan Application */
-static int speech_activate(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Activate the grammar on the speech object */
- res = ast_speech_grammar_activate(speech, data);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief SpeechStart() Dialplan Application */
-static int speech_start(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- ast_speech_start(speech);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief SpeechProcessingSound(Sound File) Dialplan Application */
-static int speech_processing_sound(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- if (speech->processing_sound != NULL) {
- free(speech->processing_sound);
- speech->processing_sound = NULL;
- }
-
- speech->processing_sound = strdup(data);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief Helper function used by speech_background to playback a soundfile */
-static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
-{
- struct ast_filestream *fs = NULL;
-
- if (!(fs = ast_openstream(chan, filename, preflang)))
- return -1;
-
- if (ast_applystream(chan, fs))
- return -1;
-
- ast_playstream(fs);
-
- return 0;
-}
-
-/*! \brief SpeechBackground(Sound File|Timeout) Dialplan Application */
-static int speech_background(struct ast_channel *chan, void *data)
-{
- unsigned int timeout = 0;
- int res = 0, done = 0, argc = 0, started = 0, quieted = 0, max_dtmf_len = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
- struct ast_frame *f = NULL;
- int oldreadformat = AST_FORMAT_SLINEAR;
- char dtmf[AST_MAX_EXTENSION] = "";
- time_t start, current;
- struct ast_datastore *datastore = NULL;
- char *argv[2], *args = NULL, *filename_tmp = NULL, *filename = NULL, tmp[2] = "", dtmf_terminator = '#';
- const char *tmp2 = NULL;
-
- args = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* If channel is not already answered, then answer it */
- if (chan->_state != AST_STATE_UP && ast_answer(chan)) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Record old read format */
- oldreadformat = chan->readformat;
-
- /* Change read format to be signed linear */
- if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Parse out options */
- argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
- if (argc > 0) {
- /* Yay sound file */
- filename_tmp = ast_strdupa(argv[0]);
- if (!ast_strlen_zero(argv[1])) {
- if ((timeout = atoi(argv[1])) == 0)
- timeout = -1;
- } else
- timeout = 0;
- }
-
- /* See if the maximum DTMF length variable is set... we use a variable in case they want to carry it through their entire dialplan */
- if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_MAXLEN")) && !ast_strlen_zero(tmp2))
- max_dtmf_len = atoi(tmp2);
-
- /* See if a terminator is specified */
- if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_TERMINATOR"))) {
- if (ast_strlen_zero(tmp2))
- dtmf_terminator = '\0';
- else
- dtmf_terminator = tmp2[0];
- }
-
- /* Before we go into waiting for stuff... make sure the structure is ready, if not - start it again */
- if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
- ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
- ast_speech_start(speech);
- }
-
- /* Ensure no streams are currently running */
- ast_stopstream(chan);
-
- /* Okay it's streaming so go into a loop grabbing frames! */
- while (done == 0) {
- /* If the filename is null and stream is not running, start up a new sound file */
- if (!quieted && (chan->streamid == -1 && chan->timingfunc == NULL) && (filename = strsep(&filename_tmp, "&"))) {
- /* Discard old stream information */
- ast_stopstream(chan);
- /* Start new stream */
- speech_streamfile(chan, filename, chan->language);
- }
-
- /* Run scheduled stuff */
- ast_sched_runq(chan->sched);
-
- /* Yay scheduling */
- res = ast_sched_wait(chan->sched);
- if (res < 0) {
- res = 1000;
- }
-
- /* If there is a frame waiting, get it - if not - oh well */
- if (ast_waitfor(chan, res) > 0) {
- f = ast_read(chan);
- if (f == NULL) {
- /* The channel has hung up most likely */
- done = 3;
- break;
- }
- }
-
- /* Do timeout check (shared between audio/dtmf) */
- if ((!quieted || strlen(dtmf)) && started == 1) {
- time(&current);
- if ((current-start) >= timeout) {
- done = 1;
- if (f)
- ast_frfree(f);
- break;
- }
- }
-
- /* Do checks on speech structure to see if it's changed */
- ast_mutex_lock(&speech->lock);
- if (ast_test_flag(speech, AST_SPEECH_QUIET)) {
- if (chan->stream)
- ast_stopstream(chan);
- ast_clear_flag(speech, AST_SPEECH_QUIET);
- quieted = 1;
- }
- /* Check state so we can see what to do */
- switch (speech->state) {
- case AST_SPEECH_STATE_READY:
- /* If audio playback has stopped do a check for timeout purposes */
- if (chan->streamid == -1 && chan->timingfunc == NULL)
- ast_stopstream(chan);
- if (!quieted && chan->stream == NULL && timeout && started == 0 && !filename_tmp) {
- if (timeout == -1) {
- done = 1;
- if (f)
- ast_frfree(f);
- break;
- }
- time(&start);
- started = 1;
- }
- /* Write audio frame out to speech engine if no DTMF has been received */
- if (!strlen(dtmf) && f != NULL && f->frametype == AST_FRAME_VOICE) {
- ast_speech_write(speech, f->data, f->datalen);
- }
- break;
- case AST_SPEECH_STATE_WAIT:
- /* Cue up waiting sound if not already playing */
- if (!strlen(dtmf)) {
- if (chan->stream == NULL) {
- if (speech->processing_sound != NULL) {
- if (strlen(speech->processing_sound) > 0 && strcasecmp(speech->processing_sound,"none")) {
- speech_streamfile(chan, speech->processing_sound, chan->language);
- }
- }
- } else if (chan->streamid == -1 && chan->timingfunc == NULL) {
- ast_stopstream(chan);
- if (speech->processing_sound != NULL) {
- if (strlen(speech->processing_sound) > 0 && strcasecmp(speech->processing_sound,"none")) {
- speech_streamfile(chan, speech->processing_sound, chan->language);
- }
- }
- }
- }
- break;
- case AST_SPEECH_STATE_DONE:
- /* Now that we are done... let's switch back to not ready state */
- ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
- if (!strlen(dtmf)) {
- /* Copy to speech structure the results, if available */
- speech->results = ast_speech_results_get(speech);
- /* Break out of our background too */
- done = 1;
- /* Stop audio playback */
- if (chan->stream != NULL) {
- ast_stopstream(chan);
- }
- }
- break;
- default:
- break;
- }
- ast_mutex_unlock(&speech->lock);
-
- /* Deal with other frame types */
- if (f != NULL) {
- /* Free the frame we received */
- switch (f->frametype) {
- case AST_FRAME_DTMF:
- if (dtmf_terminator != '\0' && f->subclass == dtmf_terminator) {
- done = 1;
- } else {
- if (chan->stream != NULL) {
- ast_stopstream(chan);
- }
- if (!started) {
- /* Change timeout to be 5 seconds for DTMF input */
- timeout = (chan->pbx && chan->pbx->dtimeout) ? chan->pbx->dtimeout : 5;
- started = 1;
- }
- time(&start);
- snprintf(tmp, sizeof(tmp), "%c", f->subclass);
- strncat(dtmf, tmp, sizeof(dtmf) - strlen(dtmf) - 1);
- /* If the maximum length of the DTMF has been reached, stop now */
- if (max_dtmf_len && strlen(dtmf) == max_dtmf_len)
- done = 1;
- }
- break;
- case AST_FRAME_CONTROL:
- switch (f->subclass) {
- case AST_CONTROL_HANGUP:
- /* Since they hung up we should destroy the speech structure */
- done = 3;
- default:
- break;
- }
- default:
- break;
- }
- ast_frfree(f);
- f = NULL;
- }
- }
-
- if (strlen(dtmf)) {
- /* We sort of make a results entry */
- speech->results = ast_calloc(1, sizeof(*speech->results));
- if (speech->results != NULL) {
- ast_speech_dtmf(speech, dtmf);
- speech->results->score = 1000;
- speech->results->text = strdup(dtmf);
- speech->results->grammar = strdup("dtmf");
- }
- }
-
- /* See if it was because they hung up */
- if (done == 3) {
- /* Destroy speech structure */
- ast_speech_destroy(speech);
- datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
- if (datastore != NULL) {
- ast_channel_datastore_remove(chan, datastore);
- }
- } else {
- /* Channel is okay so restore read format */
- ast_set_read_format(chan, oldreadformat);
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-
-/*! \brief SpeechDestroy() Dialplan Application */
-static int speech_destroy(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u = NULL;
- struct ast_speech *speech = find_speech(chan);
- struct ast_datastore *datastore = NULL;
-
- u = ast_module_user_add(chan);
-
- if (speech == NULL) {
- ast_module_user_remove(u);
- return -1;
- }
-
- /* Destroy speech structure */
- ast_speech_destroy(speech);
-
- datastore = ast_channel_datastore_find(chan, &speech_datastore, NULL);
- if (datastore != NULL) {
- ast_channel_datastore_remove(chan, datastore);
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res = 0;
-
- res = ast_unregister_application("SpeechCreate");
- res |= ast_unregister_application("SpeechLoadGrammar");
- res |= ast_unregister_application("SpeechUnloadGrammar");
- res |= ast_unregister_application("SpeechActivateGrammar");
- res |= ast_unregister_application("SpeechDeactivateGrammar");
- res |= ast_unregister_application("SpeechStart");
- res |= ast_unregister_application("SpeechBackground");
- res |= ast_unregister_application("SpeechDestroy");
- res |= ast_unregister_application("SpeechProcessingSound");
- res |= ast_custom_function_unregister(&speech_function);
- res |= ast_custom_function_unregister(&speech_score_function);
- res |= ast_custom_function_unregister(&speech_text_function);
- res |= ast_custom_function_unregister(&speech_grammar_function);
- res |= ast_custom_function_unregister(&speech_engine_function);
- res |= ast_custom_function_unregister(&speech_results_type_function);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res = ast_register_application("SpeechCreate", speech_create, "Create a Speech Structure", speechcreate_descrip);
- res |= ast_register_application("SpeechLoadGrammar", speech_load, "Load a Grammar", speechload_descrip);
- res |= ast_register_application("SpeechUnloadGrammar", speech_unload, "Unload a Grammar", speechunload_descrip);
- res |= ast_register_application("SpeechActivateGrammar", speech_activate, "Activate a Grammar", speechactivategrammar_descrip);
- res |= ast_register_application("SpeechDeactivateGrammar", speech_deactivate, "Deactivate a Grammar", speechdeactivategrammar_descrip);
- res |= ast_register_application("SpeechStart", speech_start, "Start recognizing voice in the audio stream", speechstart_descrip);
- res |= ast_register_application("SpeechBackground", speech_background, "Play a sound file and wait for speech to be recognized", speechbackground_descrip);
- res |= ast_register_application("SpeechDestroy", speech_destroy, "End speech recognition", speechdestroy_descrip);
- res |= ast_register_application("SpeechProcessingSound", speech_processing_sound, "Change background processing sound", speechprocessingsound_descrip);
- res |= ast_custom_function_register(&speech_function);
- res |= ast_custom_function_register(&speech_score_function);
- res |= ast_custom_function_register(&speech_text_function);
- res |= ast_custom_function_register(&speech_grammar_function);
- res |= ast_custom_function_register(&speech_engine_function);
- res |= ast_custom_function_register(&speech_results_type_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialplan Speech Applications");
diff --git a/1.4/apps/app_stack.c b/1.4/apps/app_stack.c
deleted file mode 100644
index ace440a63..000000000
--- a/1.4/apps/app_stack.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2004-2006 Tilghman Lesher <app_stack_v002@the-tilghman.com>.
- *
- * This code is released by the author with no restrictions on usage.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Stack applications Gosub, Return, etc.
- *
- * \author Tilghman Lesher <app_stack_v002@the-tilghman.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-
-#define STACKVAR "~GOSUB~STACK~"
-
-
-static const char *app_gosub = "Gosub";
-static const char *app_gosubif = "GosubIf";
-static const char *app_return = "Return";
-static const char *app_pop = "StackPop";
-
-static const char *gosub_synopsis = "Jump to label, saving return address";
-static const char *gosubif_synopsis = "Conditionally jump to label, saving return address";
-static const char *return_synopsis = "Return from gosub routine";
-static const char *pop_synopsis = "Remove one address from gosub stack";
-
-static const char *gosub_descrip =
-"Gosub([[context|]exten|]priority)\n"
-" Jumps to the label specified, saving the return address.\n";
-static const char *gosubif_descrip =
-"GosubIf(condition?labeliftrue[:labeliffalse])\n"
-" If the condition is true, then jump to labeliftrue. If false, jumps to\n"
-"labeliffalse, if specified. In either case, a jump saves the return point\n"
-"in the dialplan, to be returned to with a Return.\n";
-static const char *return_descrip =
-"Return()\n"
-" Jumps to the last label on the stack, removing it.\n";
-static const char *pop_descrip =
-"StackPop()\n"
-" Removes last label on the stack, discarding it.\n";
-
-
-static int pop_exec(struct ast_channel *chan, void *data)
-{
- pbx_builtin_setvar_helper(chan, STACKVAR, NULL);
-
- return 0;
-}
-
-static int return_exec(struct ast_channel *chan, void *data)
-{
- const char *label = pbx_builtin_getvar_helper(chan, STACKVAR);
-
- if (ast_strlen_zero(label)) {
- ast_log(LOG_ERROR, "Return without Gosub: stack is empty\n");
- return -1;
- } else if (ast_parseable_goto(chan, label)) {
- ast_log(LOG_WARNING, "No next statement after Gosub?\n");
- return -1;
- }
-
- pbx_builtin_setvar_helper(chan, STACKVAR, NULL);
- return 0;
-}
-
-static int gosub_exec(struct ast_channel *chan, void *data)
-{
- char newlabel[AST_MAX_EXTENSION * 2 + 3 + 11];
- struct ast_module_user *u;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "%s requires an argument: %s([[context|]exten|]priority)\n", app_gosub, app_gosub);
- return -1;
- }
-
- u = ast_module_user_add(chan);
- snprintf(newlabel, sizeof(newlabel), "%s|%s|%d", chan->context, chan->exten, chan->priority + 1);
-
- if (ast_parseable_goto(chan, data)) {
- ast_module_user_remove(u);
- return -1;
- }
-
- pbx_builtin_pushvar_helper(chan, STACKVAR, newlabel);
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int gosubif_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *condition="", *label1, *label2, *args;
- int res=0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "GosubIf requires an argument\n");
- return 0;
- }
-
- args = ast_strdupa(data);
-
- u = ast_module_user_add(chan);
-
- condition = strsep(&args, "?");
- label1 = strsep(&args, ":");
- label2 = args;
-
- if (pbx_checkcondition(condition)) {
- if (!ast_strlen_zero(label1)) {
- res = gosub_exec(chan, label1);
- }
- } else if (!ast_strlen_zero(label2)) {
- res = gosub_exec(chan, label2);
- }
-
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- ast_unregister_application(app_return);
- ast_unregister_application(app_pop);
- ast_unregister_application(app_gosubif);
- ast_unregister_application(app_gosub);
-
- ast_module_user_hangup_all();
-
- return 0;
-}
-
-static int load_module(void)
-{
- ast_register_application(app_pop, pop_exec, pop_synopsis, pop_descrip);
- ast_register_application(app_return, return_exec, return_synopsis, return_descrip);
- ast_register_application(app_gosubif, gosubif_exec, gosubif_synopsis, gosubif_descrip);
- ast_register_application(app_gosub, gosub_exec, gosub_synopsis, gosub_descrip);
-
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Stack Routines");
diff --git a/1.4/apps/app_system.c b/1.4/apps/app_system.c
deleted file mode 100644
index b60e11c5a..000000000
--- a/1.4/apps/app_system.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Execute arbitrary system commands
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-
-static char *app = "System";
-
-static char *app2 = "TrySystem";
-
-static char *synopsis = "Execute a system command";
-
-static char *synopsis2 = "Try executing a system command";
-
-static char *chanvar = "SYSTEMSTATUS";
-
-static char *descrip =
-" System(command): Executes a command by using system(). If the command\n"
-"fails, the console should report a fallthrough. \n"
-"Result of execution is returned in the SYSTEMSTATUS channel variable:\n"
-" FAILURE Could not execute the specified command\n"
-" SUCCESS Specified command successfully executed\n"
-"\n"
-"Old behaviour:\n"
-"If the command itself executes but is in error, and if there exists\n"
-"a priority n + 101, where 'n' is the priority of the current instance,\n"
-"then the channel will be setup to continue at that priority level.\n"
-"Note that this jump functionality has been deprecated and will only occur\n"
-"if the global priority jumping option is enabled in extensions.conf.\n";
-
-static char *descrip2 =
-" TrySystem(command): Executes a command by using system().\n"
-"on any situation.\n"
-"Result of execution is returned in the SYSTEMSTATUS channel variable:\n"
-" FAILURE Could not execute the specified command\n"
-" SUCCESS Specified command successfully executed\n"
-" APPERROR Specified command successfully executed, but returned error code\n"
-"\n"
-"Old behaviour:\nIf the command itself executes but is in error, and if\n"
-"there exists a priority n + 101, where 'n' is the priority of the current\n"
-"instance, then the channel will be setup to continue at that\n"
-"priority level. Otherwise, System will terminate.\n";
-
-
-static int system_exec_helper(struct ast_channel *chan, void *data, int failmode)
-{
- int res=0;
- struct ast_module_user *u;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "System requires an argument(command)\n");
- pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
- return failmode;
- }
-
- u = ast_module_user_add(chan);
-
- ast_autoservice_start(chan);
-
- /* Do our thing here */
- res = ast_safe_system((char *)data);
- if ((res < 0) && (errno != ECHILD)) {
- ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
- pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
- res = failmode;
- } else if (res == 127) {
- ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
- pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
- res = failmode;
- } else {
- if (res < 0)
- res = 0;
- if (ast_opt_priority_jumping && res)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
-
- if (res != 0)
- pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
- else
- pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
- res = 0;
- }
-
- ast_autoservice_stop(chan);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int system_exec(struct ast_channel *chan, void *data)
-{
- return system_exec_helper(chan, data, -1);
-}
-
-static int trysystem_exec(struct ast_channel *chan, void *data)
-{
- return system_exec_helper(chan, data, 0);
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
- res |= ast_unregister_application(app2);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(app2, trysystem_exec, synopsis2, descrip2);
- res |= ast_register_application(app, system_exec, synopsis, descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Generic System() application");
diff --git a/1.4/apps/app_talkdetect.c b/1.4/apps/app_talkdetect.c
deleted file mode 100644
index 79cbbd5d0..000000000
--- a/1.4/apps/app_talkdetect.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Playback a file with audio detect
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/utils.h"
-#include "asterisk/dsp.h"
-
-static char *app = "BackgroundDetect";
-
-static char *synopsis = "Background a file with talk detect";
-
-static char *descrip =
-" BackgroundDetect(filename[|sil[|min|[max]]]): Plays back a given\n"
-"filename, waiting for interruption from a given digit (the digit must\n"
-"start the beginning of a valid extension, or it will be ignored).\n"
-"During the playback of the file, audio is monitored in the receive\n"
-"direction, and if a period of non-silence which is greater than 'min' ms\n"
-"yet less than 'max' ms is followed by silence for at least 'sil' ms then\n"
-"the audio playback is aborted and processing jumps to the 'talk' extension\n"
-"if available. If unspecified, sil, min, and max default to 1000, 100, and\n"
-"infinity respectively.\n";
-
-
-static int background_detect_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *tmp;
- char *options;
- char *stringp;
- struct ast_frame *fr;
- int notsilent=0;
- struct timeval start = { 0, 0};
- int sil = 1000;
- int min = 100;
- int max = -1;
- int x;
- int origrformat=0;
- struct ast_dsp *dsp;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- tmp = ast_strdupa(data);
-
- stringp=tmp;
- strsep(&stringp, "|");
- options = strsep(&stringp, "|");
- if (options) {
- if ((sscanf(options, "%d", &x) == 1) && (x > 0))
- sil = x;
- options = strsep(&stringp, "|");
- if (options) {
- if ((sscanf(options, "%d", &x) == 1) && (x > 0))
- min = x;
- options = strsep(&stringp, "|");
- if (options) {
- if ((sscanf(options, "%d", &x) == 1) && (x > 0))
- max = x;
- }
- }
- }
- ast_log(LOG_DEBUG, "Preparing detect of '%s', sil=%d,min=%d,max=%d\n",
- tmp, sil, min, max);
- if (chan->_state != AST_STATE_UP) {
- /* Otherwise answer unless we're supposed to send this while on-hook */
- res = ast_answer(chan);
- }
- if (!res) {
- origrformat = chan->readformat;
- if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)))
- ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
- }
- if (!(dsp = ast_dsp_new())) {
- ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
- res = -1;
- }
- if (!res) {
- ast_stopstream(chan);
- res = ast_streamfile(chan, tmp, chan->language);
- if (!res) {
- while(chan->stream) {
- res = ast_sched_wait(chan->sched);
- if ((res < 0) && !chan->timingfunc) {
- res = 0;
- break;
- }
- if (res < 0)
- res = 1000;
- res = ast_waitfor(chan, res);
- if (res < 0) {
- ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
- break;
- } else if (res > 0) {
- fr = ast_read(chan);
- if (!fr) {
- res = -1;
- break;
- } else if (fr->frametype == AST_FRAME_DTMF) {
- char t[2];
- t[0] = fr->subclass;
- t[1] = '\0';
- if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) {
- /* They entered a valid extension, or might be anyhow */
- res = fr->subclass;
- ast_frfree(fr);
- break;
- }
- } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
- int totalsilence;
- int ms;
- res = ast_dsp_silence(dsp, fr, &totalsilence);
- if (res && (totalsilence > sil)) {
- /* We've been quiet a little while */
- if (notsilent) {
- /* We had heard some talking */
- ms = ast_tvdiff_ms(ast_tvnow(), start);
- ms -= sil;
- if (ms < 0)
- ms = 0;
- if ((ms > min) && ((max < 0) || (ms < max))) {
- char ms_str[10];
- ast_log(LOG_DEBUG, "Found qualified token of %d ms\n", ms);
-
- /* Save detected talk time (in milliseconds) */
- sprintf(ms_str, "%d", ms );
- pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
-
- ast_goto_if_exists(chan, chan->context, "talk", 1);
- res = 0;
- ast_frfree(fr);
- break;
- } else
- ast_log(LOG_DEBUG, "Found unqualified token of %d ms\n", ms);
- notsilent = 0;
- }
- } else {
- if (!notsilent) {
- /* Heard some audio, mark the begining of the token */
- start = ast_tvnow();
- ast_log(LOG_DEBUG, "Start of voice token!\n");
- notsilent = 1;
- }
- }
-
- }
- ast_frfree(fr);
- }
- ast_sched_runq(chan->sched);
- }
- ast_stopstream(chan);
- } else {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
- res = 0;
- }
- }
- if (res > -1) {
- if (origrformat && ast_set_read_format(chan, origrformat)) {
- ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n",
- chan->name, ast_getformatname(origrformat));
- }
- }
- if (dsp)
- ast_dsp_free(dsp);
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, background_detect_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Playback with Talk Detection");
diff --git a/1.4/apps/app_test.c b/1.4/apps/app_test.c
deleted file mode 100644
index b38fe4ca7..000000000
--- a/1.4/apps/app_test.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Russell Bryant <russelb@clemson.edu>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Applications to test connection and produce report in text file
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Russell Bryant <russelb@clemson.edu>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-#include "asterisk/pbx.h"
-#include "asterisk/utils.h"
-
-static char *tests_descrip =
- "TestServer(): Perform test server function and write call report.\n"
- "Results stored in /var/log/asterisk/testreports/<testid>-server.txt";
-static char *tests_app = "TestServer";
-static char *tests_synopsis = "Execute Interface Test Server";
-
-static char *testc_descrip =
- "TestClient(testid): Executes test client with given testid.\n"
- "Results stored in /var/log/asterisk/testreports/<testid>-client.txt";
-
-static char *testc_app = "TestClient";
-static char *testc_synopsis = "Execute Interface Test Client";
-
-static int measurenoise(struct ast_channel *chan, int ms, char *who)
-{
- int res=0;
- int mssofar;
- int noise=0;
- int samples=0;
- int x;
- short *foo;
- struct timeval start;
- struct ast_frame *f;
- int rformat;
- rformat = chan->readformat;
- if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
- ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
- return -1;
- }
- start = ast_tvnow();
- for(;;) {
- mssofar = ast_tvdiff_ms(ast_tvnow(), start);
- if (mssofar > ms)
- break;
- res = ast_waitfor(chan, ms - mssofar);
- if (res < 1)
- break;
- f = ast_read(chan);
- if (!f) {
- res = -1;
- break;
- }
- if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
- foo = (short *)f->data;
- for (x=0;x<f->samples;x++) {
- noise += abs(foo[x]);
- samples++;
- }
- }
- ast_frfree(f);
- }
-
- if (rformat) {
- if (ast_set_read_format(chan, rformat)) {
- ast_log(LOG_NOTICE, "Unable to restore original format!\n");
- return -1;
- }
- }
- if (res < 0)
- return res;
- if (!samples) {
- ast_log(LOG_NOTICE, "No samples were received from the other side!\n");
- return -1;
- }
- ast_log(LOG_DEBUG, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples);
- return (noise / samples);
-}
-
-static int sendnoise(struct ast_channel *chan, int ms)
-{
- int res;
- res = ast_tonepair_start(chan, 1537, 2195, ms, 8192);
- if (!res) {
- res = ast_waitfordigit(chan, ms);
- ast_tonepair_stop(chan);
- }
- return res;
-}
-
-static int testclient_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- int res = 0;
- char *testid=data;
- char fn[80];
- char serverver[80];
- FILE *f;
-
- /* Check for test id */
- if (ast_strlen_zero(testid)) {
- ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
-
- /* Wait a few just to be sure things get started */
- res = ast_safe_sleep(chan, 3000);
- /* Transmit client version */
- if (!res)
- res = ast_dtmf_stream(chan, NULL, "8378*1#", 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "Transmit client version\n");
-
- /* Read server version */
- if (option_debug)
- ast_log(LOG_DEBUG, "Read server version\n");
- if (!res)
- res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0);
- if (res > 0)
- res = 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "server version: %s\n", serverver);
-
- if (res > 0)
- res = 0;
-
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- /* Send test id */
- if (!res)
- res = ast_dtmf_stream(chan, NULL, testid, 0);
- if (!res)
- res = ast_dtmf_stream(chan, NULL, "#", 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "send test identifier: %s\n", testid);
-
- if ((res >=0) && (!ast_strlen_zero(testid))) {
- /* Make the directory to hold the test results in case it's not there */
- snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
- mkdir(fn, 0777);
- snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid);
- if ((f = fopen(fn, "w+"))) {
- setlinebuf(f);
- fprintf(f, "CLIENTCHAN: %s\n", chan->name);
- fprintf(f, "CLIENTTEST ID: %s\n", testid);
- fprintf(f, "ANSWER: PASS\n");
- res = 0;
-
- if (!res) {
- /* Step 1: Wait for "1" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 2. Wait DTMF 1\n");
- res = ast_waitfordigit(chan, 3000);
- fprintf(f, "WAIT DTMF 1: %s\n", (res != '1') ? "FAIL" : "PASS");
- if (res == '1')
- res = 0;
- else
- res = -1;
- }
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- if (!res) {
- /* Step 2: Send "2" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 2. Send DTMF 2\n");
- res = ast_dtmf_stream(chan, NULL, "2", 0);
- fprintf(f, "SEND DTMF 2: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 3: Wait one second */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 3. Wait one second\n");
- res = ast_safe_sleep(chan, 1000);
- fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 4: Measure noise */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 4. Measure noise\n");
- res = measurenoise(chan, 5000, "TestClient");
- fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 5: Wait for "4" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 5. Wait DTMF 4\n");
- res = ast_waitfordigit(chan, 3000);
- fprintf(f, "WAIT DTMF 4: %s\n", (res != '4') ? "FAIL" : "PASS");
- if (res == '4')
- res = 0;
- else
- res = -1;
- }
- if (!res) {
- /* Step 6: Transmit tone noise */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 6. Transmit tone\n");
- res = sendnoise(chan, 6000);
- fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
- }
- if (!res || (res == '5')) {
- /* Step 7: Wait for "5" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 7. Wait DTMF 5\n");
- if (!res)
- res = ast_waitfordigit(chan, 3000);
- fprintf(f, "WAIT DTMF 5: %s\n", (res != '5') ? "FAIL" : "PASS");
- if (res == '5')
- res = 0;
- else
- res = -1;
- }
- if (!res) {
- /* Step 8: Wait one second */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 8. Wait one second\n");
- res = ast_safe_sleep(chan, 1000);
- fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 9: Measure noise */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 6. Measure tone\n");
- res = measurenoise(chan, 4000, "TestClient");
- fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 10: Send "7" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 7. Send DTMF 7\n");
- res = ast_dtmf_stream(chan, NULL, "7", 0);
- fprintf(f, "SEND DTMF 7: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res =0;
- }
- if (!res) {
- /* Step 11: Wait for "8" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestClient: 11. Wait DTMF 8\n");
- res = ast_waitfordigit(chan, 3000);
- fprintf(f, "WAIT DTMF 8: %s\n", (res != '8') ? "FAIL" : "PASS");
- if (res == '8')
- res = 0;
- else
- res = -1;
- }
- if (option_debug && !res ) {
- /* Step 12: Hangup! */
- ast_log(LOG_DEBUG, "TestClient: 12. Hangup\n");
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "-- TEST COMPLETE--\n");
- fprintf(f, "-- END TEST--\n");
- fclose(f);
- res = -1;
- } else
- res = -1;
- } else {
- ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
- res = -1;
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int testserver_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- int res = 0;
- char testid[80]="";
- char fn[80];
- FILE *f;
- u = ast_module_user_add(chan);
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
- /* Read version */
- if (option_debug)
- ast_log(LOG_DEBUG, "Read client version\n");
- if (!res)
- res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
- if (res > 0)
- res = 0;
- if (option_debug) {
- ast_log(LOG_DEBUG, "client version: %s\n", testid);
- ast_log(LOG_DEBUG, "Transmit server version\n");
- }
- res = ast_safe_sleep(chan, 1000);
- if (!res)
- res = ast_dtmf_stream(chan, NULL, "8378*1#", 0);
- if (res > 0)
- res = 0;
-
- if (!res)
- res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "read test identifier: %s\n", testid);
- /* Check for sneakyness */
- if (strchr(testid, '/'))
- res = -1;
- if ((res >=0) && (!ast_strlen_zero(testid))) {
- /* Got a Test ID! Whoo hoo! */
- /* Make the directory to hold the test results in case it's not there */
- snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
- mkdir(fn, 0777);
- snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid);
- if ((f = fopen(fn, "w+"))) {
- setlinebuf(f);
- fprintf(f, "SERVERCHAN: %s\n", chan->name);
- fprintf(f, "SERVERTEST ID: %s\n", testid);
- fprintf(f, "ANSWER: PASS\n");
- ast_log(LOG_DEBUG, "Processing Test ID '%s'\n", testid);
- res = ast_safe_sleep(chan, 1000);
- if (!res) {
- /* Step 1: Send "1" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 1. Send DTMF 1\n");
- res = ast_dtmf_stream(chan, NULL, "1", 0);
- fprintf(f, "SEND DTMF 1: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 2: Wait for "2" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 2. Wait DTMF 2\n");
- res = ast_waitfordigit(chan, 3000);
- fprintf(f, "WAIT DTMF 2: %s\n", (res != '2') ? "FAIL" : "PASS");
- if (res == '2')
- res = 0;
- else
- res = -1;
- }
- if (!res) {
- /* Step 3: Measure noise */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 3. Measure noise\n");
- res = measurenoise(chan, 6000, "TestServer");
- fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 4: Send "4" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 4. Send DTMF 4\n");
- res = ast_dtmf_stream(chan, NULL, "4", 0);
- fprintf(f, "SEND DTMF 4: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
-
- if (!res) {
- /* Step 5: Wait one second */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 5. Wait one second\n");
- res = ast_safe_sleep(chan, 1000);
- fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
-
- if (!res) {
- /* Step 6: Measure noise */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 6. Measure tone\n");
- res = measurenoise(chan, 4000, "TestServer");
- fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
- if (res > 0)
- res = 0;
- }
-
- if (!res) {
- /* Step 7: Send "5" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 7. Send DTMF 5\n");
- res = ast_dtmf_stream(chan, NULL, "5", 0);
- fprintf(f, "SEND DTMF 5: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
-
- if (!res) {
- /* Step 8: Transmit tone noise */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 8. Transmit tone\n");
- res = sendnoise(chan, 6000);
- fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
- }
-
- if (!res || (res == '7')) {
- /* Step 9: Wait for "7" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 9. Wait DTMF 7\n");
- if (!res)
- res = ast_waitfordigit(chan, 3000);
- fprintf(f, "WAIT DTMF 7: %s\n", (res != '7') ? "FAIL" : "PASS");
- if (res == '7')
- res = 0;
- else
- res = -1;
- }
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- if (!res) {
- /* Step 10: Send "8" */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 10. Send DTMF 8\n");
- res = ast_dtmf_stream(chan, NULL, "8", 0);
- fprintf(f, "SEND DTMF 8: %s\n", (res < 0) ? "FAIL" : "PASS");
- if (res > 0)
- res = 0;
- }
- if (!res) {
- /* Step 11: Wait for hangup to arrive! */
- if (option_debug)
- ast_log(LOG_DEBUG, "TestServer: 11. Waiting for hangup\n");
- res = ast_safe_sleep(chan, 10000);
- fprintf(f, "WAIT HANGUP: %s\n", (res < 0) ? "PASS" : "FAIL");
- }
-
- ast_log(LOG_NOTICE, "-- TEST COMPLETE--\n");
- fprintf(f, "-- END TEST--\n");
- fclose(f);
- res = -1;
- } else
- res = -1;
- } else {
- ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
- res = -1;
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(testc_app);
- res |= ast_unregister_application(tests_app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(testc_app, testclient_exec, testc_synopsis, testc_descrip);
- res |= ast_register_application(tests_app, testserver_exec, tests_synopsis, tests_descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Interface Test Application");
diff --git a/1.4/apps/app_transfer.c b/1.4/apps/app_transfer.c
deleted file mode 100644
index cda2914c7..000000000
--- a/1.4/apps/app_transfer.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Transfer a caller
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * Requires transfer support from channel driver
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/app.h"
-
-
-static const char *app = "Transfer";
-
-static const char *synopsis = "Transfer caller to remote extension";
-
-static const char *descrip =
-" Transfer([Tech/]dest[|options]): Requests the remote caller be transferred\n"
-"to a given destination. If TECH (SIP, IAX2, LOCAL etc) is used, only\n"
-"an incoming call with the same channel technology will be transfered.\n"
-"Note that for SIP, if you transfer before call is setup, a 302 redirect\n"
-"SIP message will be returned to the caller.\n"
-"\nThe result of the application will be reported in the TRANSFERSTATUS\n"
-"channel variable:\n"
-" SUCCESS Transfer succeeded\n"
-" FAILURE Transfer failed\n"
-" UNSUPPORTED Transfer unsupported by channel driver\n"
-"The option string many contain the following character:\n"
-"'j' -- jump to n+101 priority if the channel transfer attempt\n"
-" fails\n";
-
-static int transfer_exec(struct ast_channel *chan, void *data)
-{
- int res;
- int len;
- struct ast_module_user *u;
- char *slash;
- char *tech = NULL;
- char *dest = NULL;
- char *status;
- char *parse;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(dest);
- AST_APP_ARG(options);
- );
-
- u = ast_module_user_add(chan);
-
- if (ast_strlen_zero((char *)data)) {
- ast_log(LOG_WARNING, "Transfer requires an argument ([Tech/]destination[|options])\n");
- ast_module_user_remove(u);
- pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
- return 0;
- } else
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- dest = args.dest;
-
- if ((slash = strchr(dest, '/')) && (len = (slash - dest))) {
- tech = dest;
- dest = slash + 1;
- /* Allow execution only if the Tech/destination agrees with the type of the channel */
- if (strncasecmp(chan->tech->type, tech, len)) {
- pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
- ast_module_user_remove(u);
- return 0;
- }
- }
-
- /* Check if the channel supports transfer before we try it */
- if (!chan->tech->transfer) {
- pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "UNSUPPORTED");
- ast_module_user_remove(u);
- return 0;
- }
-
- res = ast_transfer(chan, dest);
-
- if (res < 0) {
- status = "FAILURE";
- if (priority_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- } else {
- status = "SUCCESS";
- res = 0;
- }
-
- pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", status);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, transfer_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Transfer");
diff --git a/1.4/apps/app_url.c b/1.4/apps/app_url.c
deleted file mode 100644
index a1f295a32..000000000
--- a/1.4/apps/app_url.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief App to transmit a URL
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/image.h"
-#include "asterisk/options.h"
-
-static char *app = "SendURL";
-
-static char *synopsis = "Send a URL";
-
-static char *descrip =
-" SendURL(URL[|option]): Requests client go to URL (IAX2) or sends the \n"
-"URL to the client (other channels).\n"
-"Result is returned in the SENDURLSTATUS channel variable:\n"
-" SUCCESS URL successfully sent to client\n"
-" FAILURE Failed to send URL\n"
-" NOLOAD Client failed to load URL (wait enabled)\n"
-" UNSUPPORTED Channel does not support URL transport\n"
-"\n"
-"If the option 'wait' is specified, execution will wait for an\n"
-"acknowledgement that the URL has been loaded before continuing\n"
-"\n"
-"If jumping is specified as an option (the 'j' flag), the client does not\n"
-"support Asterisk \"html\" transport, and there exists a step with priority\n"
-"n + 101, then execution will continue at that step.\n"
-"\n"
-"SendURL continues normally if the URL was sent correctly or if the channel\n"
-"does not support HTML transport. Otherwise, the channel is hung up.\n";
-
-
-static int sendurl_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *tmp;
- char *options;
- int local_option_wait=0;
- int local_option_jump = 0;
- struct ast_frame *f;
- char *stringp=NULL;
- char *status = "FAILURE";
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
- pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", status);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- tmp = ast_strdupa(data);
-
- stringp=tmp;
- strsep(&stringp, "|");
- options = strsep(&stringp, "|");
- if (options && !strcasecmp(options, "wait"))
- local_option_wait = 1;
- if (options && !strcasecmp(options, "j"))
- local_option_jump = 1;
-
- if (!ast_channel_supports_html(chan)) {
- /* Does not support transport */
- if (local_option_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "UNSUPPORTED");
- ast_module_user_remove(u);
- return 0;
- }
- res = ast_channel_sendurl(chan, tmp);
- if (res == -1) {
- pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "FAILURE");
- ast_module_user_remove(u);
- return res;
- }
- status = "SUCCESS";
- if (local_option_wait) {
- for(;;) {
- /* Wait for an event */
- res = ast_waitfor(chan, -1);
- if (res < 0)
- break;
- f = ast_read(chan);
- if (!f) {
- res = -1;
- status = "FAILURE";
- break;
- }
- if (f->frametype == AST_FRAME_HTML) {
- switch(f->subclass) {
- case AST_HTML_LDCOMPLETE:
- res = 0;
- ast_frfree(f);
- status = "NOLOAD";
- goto out;
- break;
- case AST_HTML_NOSUPPORT:
- /* Does not support transport */
- status ="UNSUPPORTED";
- if (local_option_jump || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- res = 0;
- ast_frfree(f);
- goto out;
- break;
- default:
- ast_log(LOG_WARNING, "Don't know what to do with HTML subclass %d\n", f->subclass);
- };
- }
- ast_frfree(f);
- }
- }
-out:
- pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", status);
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, sendurl_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send URL Applications");
diff --git a/1.4/apps/app_userevent.c b/1.4/apps/app_userevent.c
deleted file mode 100644
index df7bc58a7..000000000
--- a/1.4/apps/app_userevent.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief UserEvent application -- send manager event
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/manager.h"
-#include "asterisk/app.h"
-
-static char *app = "UserEvent";
-
-static char *synopsis = "Send an arbitrary event to the manager interface";
-
-static char *descrip =
-" UserEvent(eventname[|body]): Sends an arbitrary event to the manager\n"
-"interface, with an optional body representing additional arguments. The\n"
-"body may be specified as a | delimeted list of headers. Each additional\n"
-"argument will be placed on a new line in the event. The format of the\n"
-"event will be:\n"
-" Event: UserEvent\n"
-" UserEvent: <specified event name>\n"
-" [body]\n"
-"If no body is specified, only Event and UserEvent headers will be present.\n";
-
-
-static int userevent_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *parse, buf[2048] = "";
- int x, buflen = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(eventname);
- AST_APP_ARG(extra)[100];
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "UserEvent requires an argument (eventname|optional event body)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- for (x = 0; x < args.argc - 1; x++) {
- ast_copy_string(buf + buflen, args.extra[x], sizeof(buf) - buflen - 2);
- buflen += strlen(args.extra[x]);
- ast_copy_string(buf + buflen, "\r\n", 3);
- buflen += 2;
- }
-
- manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", args.eventname, buf);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, userevent_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Custom User Event Application");
diff --git a/1.4/apps/app_verbose.c b/1.4/apps/app_verbose.c
deleted file mode 100644
index f9bcfd116..000000000
--- a/1.4/apps/app_verbose.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2004 - 2005 Tilghman Lesher. All rights reserved.
- *
- * Tilghman Lesher <app_verbose_v001@the-tilghman.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief Verbose logging application
- *
- * \author Tilghman Lesher <app_verbose_v001@the-tilghman.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-
-static char *app_verbose = "Verbose";
-static char *verbose_synopsis = "Send arbitrary text to verbose output";
-static char *verbose_descrip =
-"Verbose([<level>|]<message>)\n"
-" level must be an integer value. If not specified, defaults to 0.\n";
-
-static char *app_log = "Log";
-static char *log_synopsis = "Send arbitrary text to a selected log level";
-static char *log_descrip =
-"Log(<level>|<message>)\n"
-" level must be one of ERROR, WARNING, NOTICE, DEBUG, VERBOSE, DTMF\n";
-
-
-static int verbose_exec(struct ast_channel *chan, void *data)
-{
- char *vtext;
- int vsize;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- if (data) {
- char *tmp;
- vtext = ast_strdupa(data);
- tmp = strsep(&vtext, "|");
- if (vtext) {
- if (sscanf(tmp, "%d", &vsize) != 1) {
- vsize = 0;
- ast_log(LOG_WARNING, "'%s' is not a verboser number\n", vtext);
- }
- } else {
- vtext = tmp;
- vsize = 0;
- }
- if (option_verbose >= vsize) {
- switch (vsize) {
- case 0:
- ast_verbose("%s\n", vtext);
- break;
- case 1:
- ast_verbose(VERBOSE_PREFIX_1 "%s\n", vtext);
- break;
- case 2:
- ast_verbose(VERBOSE_PREFIX_2 "%s\n", vtext);
- break;
- case 3:
- ast_verbose(VERBOSE_PREFIX_3 "%s\n", vtext);
- break;
- default:
- ast_verbose(VERBOSE_PREFIX_4 "%s\n", vtext);
- }
- }
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static int log_exec(struct ast_channel *chan, void *data)
-{
- char *level, *ltext;
- struct ast_module_user *u;
- int lnum = -1;
- char extension[AST_MAX_EXTENSION + 5], context[AST_MAX_EXTENSION + 2];
-
- u = ast_module_user_add(chan);
- if (ast_strlen_zero(data)) {
- ast_module_user_remove(u);
- return 0;
- }
-
- ltext = ast_strdupa(data);
-
- level = strsep(&ltext, "|");
-
- if (!strcasecmp(level, "ERROR")) {
- lnum = __LOG_ERROR;
- } else if (!strcasecmp(level, "WARNING")) {
- lnum = __LOG_WARNING;
- } else if (!strcasecmp(level, "NOTICE")) {
- lnum = __LOG_NOTICE;
- } else if (!strcasecmp(level, "DEBUG")) {
- lnum = __LOG_DEBUG;
- } else if (!strcasecmp(level, "VERBOSE")) {
- lnum = __LOG_VERBOSE;
- } else if (!strcasecmp(level, "DTMF")) {
- lnum = __LOG_DTMF;
- } else if (!strcasecmp(level, "EVENT")) {
- lnum = __LOG_EVENT;
- } else {
- ast_log(LOG_ERROR, "Unknown log level: '%s'\n", level);
- }
-
- if (lnum > -1) {
- snprintf(context, sizeof(context), "@ %s", chan->context);
- snprintf(extension, sizeof(extension), "Ext. %s", chan->exten);
-
- ast_log(lnum, extension, chan->priority, context, "%s\n", ltext);
- }
- ast_module_user_remove(u);
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app_verbose);
- res |= ast_unregister_application(app_log);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(app_log, log_exec, log_synopsis, log_descrip);
- res |= ast_register_application(app_verbose, verbose_exec, verbose_synopsis, verbose_descrip);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Send verbose output");
diff --git a/1.4/apps/app_voicemail.c b/1.4/apps/app_voicemail.c
deleted file mode 100644
index 8118a49e0..000000000
--- a/1.4/apps/app_voicemail.c
+++ /dev/null
@@ -1,9143 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Comedian Mail - Voicemail System
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \par See also
- * \arg \ref Config_vm
- * \ingroup applications
- * \note This module requires res_adsi to load.
- */
-
-/*** MODULEINFO
- <depend>res_adsi</depend>
- <depend>res_smdi</depend>
- ***/
-
-/*** MAKEOPTS
-<category name="MENUSELECT_OPTS_app_voicemail" displayname="Voicemail Build Options" positive_output="yes" remove_on_change="apps/app_voicemail.o apps/app_directory.o">
- <member name="ODBC_STORAGE" displayname="Storage of Voicemail using ODBC">
- <depend>unixodbc</depend>
- <depend>ltdl</depend>
- <conflict>IMAP_STORAGE</conflict>
- <defaultenabled>no</defaultenabled>
- </member>
- <member name="IMAP_STORAGE" displayname="Storage of Voicemail using IMAP4">
- <depend>imap_tk</depend>
- <conflict>ODBC_STORAGE</conflict>
- <use>ssl</use>
- <defaultenabled>no</defaultenabled>
- </member>
-</category>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <time.h>
-#include <dirent.h>
-#ifdef IMAP_STORAGE
-#include <ctype.h>
-#include <signal.h>
-#include <pwd.h>
-#ifdef USE_SYSTEM_IMAP
-#include <imap/c-client.h>
-#include <imap/imap4r1.h>
-#include <imap/linkage.h>
-#elif defined (USE_SYSTEM_CCLIENT)
-#include <c-client/c-client.h>
-#include <c-client/imap4r1.h>
-#include <c-client/linkage.h>
-#else
-#include "c-client.h"
-#include "imap4r1.h"
-#include "linkage.h"
-#endif
-#endif
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/config.h"
-#include "asterisk/say.h"
-#include "asterisk/module.h"
-#include "asterisk/adsi.h"
-#include "asterisk/app.h"
-#include "asterisk/manager.h"
-#include "asterisk/dsp.h"
-#include "asterisk/localtime.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/smdi.h"
-#ifdef ODBC_STORAGE
-#include "asterisk/res_odbc.h"
-#endif
-
-#ifdef IMAP_STORAGE
-AST_MUTEX_DEFINE_STATIC(imaptemp_lock);
-static char imaptemp[1024];
-
-static char imapserver[48];
-static char imapport[8];
-static char imapflags[128];
-static char imapfolder[64];
-static char authuser[32];
-static char authpassword[42];
-
-static int expungeonhangup = 1;
-static char delimiter = '\0';
-
-struct vm_state;
-struct ast_vm_user;
-
-static int init_mailstream (struct vm_state *vms, int box);
-static void write_file (char *filename, char *buffer, unsigned long len);
-/*static void status (MAILSTREAM *stream); */ /* No need for this. */
-static char *get_header_by_tag(char *header, char *tag);
-static void vm_imap_delete(int msgnum, struct vm_state *vms);
-static char *get_user_by_mailbox(char *mailbox);
-static struct vm_state *get_vm_state_by_imapuser(char *user, int interactive);
-static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, int interactive);
-static void vmstate_insert(struct vm_state *vms);
-static void vmstate_delete(struct vm_state *vms);
-static void set_update(MAILSTREAM * stream);
-static void init_vm_state(struct vm_state *vms);
-static void check_msgArray(struct vm_state *vms);
-static void copy_msgArray(struct vm_state *dst, struct vm_state *src);
-static int save_body(BODY *body, struct vm_state *vms, char *section, char *format);
-static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num);
-static void get_mailbox_delimiter(MAILSTREAM *stream);
-static void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota);
-static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int box, int target);
-static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms);
-static void check_quota(struct vm_state *vms, char *mailbox);
-static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box);
-struct vmstate {
- struct vm_state *vms;
- struct vmstate *next;
-};
-AST_MUTEX_DEFINE_STATIC(vmstate_lock);
-static struct vmstate *vmstates = NULL;
-#endif
-
-#define SMDI_MWI_WAIT_TIMEOUT 1000 /* 1 second */
-
-#define COMMAND_TIMEOUT 5000
-/* Don't modify these here; set your umask at runtime instead */
-#define VOICEMAIL_DIR_MODE 0777
-#define VOICEMAIL_FILE_MODE 0666
-#define CHUNKSIZE 65536
-
-#define VOICEMAIL_CONFIG "voicemail.conf"
-#define ASTERISK_USERNAME "asterisk"
-
-/* Default mail command to mail voicemail. Change it with the
- mailcmd= command in voicemail.conf */
-#define SENDMAIL "/usr/sbin/sendmail -t"
-
-#define INTRO "vm-intro"
-
-#define MAXMSG 100
-#ifndef IMAP_STORAGE
-#define MAXMSGLIMIT 9999
-#else
-#define MAXMSGLIMIT 255
-#endif
-
-#define BASEMAXINLINE 256
-#define BASELINELEN 72
-#define BASEMAXINLINE 256
-#define eol "\r\n"
-
-#define MAX_DATETIME_FORMAT 512
-#define MAX_NUM_CID_CONTEXTS 10
-
-#define VM_REVIEW (1 << 0)
-#define VM_OPERATOR (1 << 1)
-#define VM_SAYCID (1 << 2)
-#define VM_SVMAIL (1 << 3)
-#define VM_ENVELOPE (1 << 4)
-#define VM_SAYDURATION (1 << 5)
-#define VM_SKIPAFTERCMD (1 << 6)
-#define VM_FORCENAME (1 << 7) /*!< Have new users record their name */
-#define VM_FORCEGREET (1 << 8) /*!< Have new users record their greetings */
-#define VM_PBXSKIP (1 << 9)
-#define VM_DIRECFORWARD (1 << 10) /*!< directory_forward */
-#define VM_ATTACH (1 << 11)
-#define VM_DELETE (1 << 12)
-#define VM_ALLOCED (1 << 13)
-#define VM_SEARCH (1 << 14)
-#define VM_TEMPGREETWARN (1 << 15) /*!< Remind user tempgreeting is set */
-#define ERROR_LOCK_PATH -100
-#define ERROR_MAILBOX_FULL -200
-
-
-enum {
- OPT_SILENT = (1 << 0),
- OPT_BUSY_GREETING = (1 << 1),
- OPT_UNAVAIL_GREETING = (1 << 2),
- OPT_RECORDGAIN = (1 << 3),
- OPT_PREPEND_MAILBOX = (1 << 4),
- OPT_PRIORITY_JUMP = (1 << 5),
- OPT_AUTOPLAY = (1 << 6),
-} vm_option_flags;
-
-enum {
- OPT_ARG_RECORDGAIN = 0,
- OPT_ARG_PLAYFOLDER = 1,
- /* This *must* be the last value in this enum! */
- OPT_ARG_ARRAY_SIZE = 2,
-} vm_option_args;
-
-AST_APP_OPTIONS(vm_app_options, {
- AST_APP_OPTION('s', OPT_SILENT),
- AST_APP_OPTION('b', OPT_BUSY_GREETING),
- AST_APP_OPTION('u', OPT_UNAVAIL_GREETING),
- AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN),
- AST_APP_OPTION('p', OPT_PREPEND_MAILBOX),
- AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
- AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),
-});
-
-static int load_config(void);
-
-/*! \page vmlang Voicemail Language Syntaxes Supported
-
- \par Syntaxes supported, not really language codes.
- \arg \b en - English
- \arg \b de - German
- \arg \b es - Spanish
- \arg \b fr - French
- \arg \b it = Italian
- \arg \b nl - Dutch
- \arg \b pt - Polish
- \arg \b pt - Portuguese
- \arg \b pt_BR - Portuguese (Brazil)
- \arg \b gr - Greek
- \arg \b no - Norwegian
- \arg \b se - Swedish
- \arg \b ua - Ukrainian
-
-German requires the following additional soundfile:
-\arg \b 1F einE (feminine)
-
-Spanish requires the following additional soundfile:
-\arg \b 1M un (masculine)
-
-Dutch, Portuguese & Spanish require the following additional soundfiles:
-\arg \b vm-INBOXs singular of 'new'
-\arg \b vm-Olds singular of 'old/heard/read'
-
-NB these are plural:
-\arg \b vm-INBOX nieuwe (nl)
-\arg \b vm-Old oude (nl)
-
-Polish uses:
-\arg \b vm-new-a 'new', feminine singular accusative
-\arg \b vm-new-e 'new', feminine plural accusative
-\arg \b vm-new-ych 'new', feminine plural genitive
-\arg \b vm-old-a 'old', feminine singular accusative
-\arg \b vm-old-e 'old', feminine plural accusative
-\arg \b vm-old-ych 'old', feminine plural genitive
-\arg \b digits/1-a 'one', not always same as 'digits/1'
-\arg \b digits/2-ie 'two', not always same as 'digits/2'
-
-Swedish uses:
-\arg \b vm-nytt singular of 'new'
-\arg \b vm-nya plural of 'new'
-\arg \b vm-gammalt singular of 'old'
-\arg \b vm-gamla plural of 'old'
-\arg \b digits/ett 'one', not always same as 'digits/1'
-
-Norwegian uses:
-\arg \b vm-ny singular of 'new'
-\arg \b vm-nye plural of 'new'
-\arg \b vm-gammel singular of 'old'
-\arg \b vm-gamle plural of 'old'
-
-Dutch also uses:
-\arg \b nl-om 'at'?
-
-Spanish also uses:
-\arg \b vm-youhaveno
-
-Ukrainian requires the following additional soundfile:
-\arg \b vm-nove 'nove'
-\arg \b vm-stare 'stare'
-\arg \b digits/ua/1e 'odne'
-
-Italian requires the following additional soundfile:
-
-For vm_intro_it:
-\arg \b vm-nuovo new
-\arg \b vm-nuovi new plural
-\arg \b vm-vecchio old
-\arg \b vm-vecchi old plural
-
-\note Don't use vm-INBOX or vm-Old, because they are the name of the INBOX and Old folders,
-spelled among others when you have to change folder. For the above reasons, vm-INBOX
-and vm-Old are spelled plural, to make them sound more as folder name than an adjective.
-
-*/
-
-struct baseio {
- int iocp;
- int iolen;
- int linelength;
- int ateof;
- unsigned char iobuf[BASEMAXINLINE];
-};
-
-/*! Structure for linked list of users */
-struct ast_vm_user {
- char context[AST_MAX_CONTEXT]; /*!< Voicemail context */
- char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox id, unique within vm context */
- char password[80]; /*!< Secret pin code, numbers only */
- char fullname[80]; /*!< Full name, for directory app */
- char email[80]; /*!< E-mail address */
- char pager[80]; /*!< E-mail address to pager (no attachment) */
- char serveremail[80]; /*!< From: Mail address */
- char mailcmd[160]; /*!< Configurable mail command */
- char language[MAX_LANGUAGE]; /*!< Config: Language setting */
- char zonetag[80]; /*!< Time zone */
- char callback[80];
- char dialout[80];
- char uniqueid[80]; /*!< Unique integer identifier */
- char exit[80];
- char attachfmt[20]; /*!< Attachment format */
- unsigned int flags; /*!< VM_ flags */
- int saydurationm;
- int maxmsg; /*!< Maximum number of msgs per folder for this mailbox */
-#ifdef IMAP_STORAGE
- char imapuser[80]; /* IMAP server login */
- char imappassword[80]; /* IMAP server password if authpassword not defined */
-#endif
- double volgain; /*!< Volume gain for voicemails sent via email */
- AST_LIST_ENTRY(ast_vm_user) list;
-};
-
-struct vm_zone {
- AST_LIST_ENTRY(vm_zone) list;
- char name[80];
- char timezone[80];
- char msg_format[512];
-};
-
-struct vm_state {
- char curbox[80];
- char username[80];
- char curdir[PATH_MAX];
- char vmbox[PATH_MAX];
- char fn[PATH_MAX];
- char fn2[PATH_MAX];
- int *deleted;
- int *heard;
- int curmsg;
- int lastmsg;
- int newmessages;
- int oldmessages;
- int starting;
- int repeats;
-#ifdef IMAP_STORAGE
- ast_mutex_t lock;
- int updated; /* decremented on each mail check until 1 -allows delay */
- long msgArray[256];
- MAILSTREAM *mailstream;
- int vmArrayIndex;
- char imapuser[80]; /* IMAP server login */
- int interactive;
- unsigned int quota_limit;
- unsigned int quota_usage;
- struct vm_state *persist_vms;
-#endif
-};
-static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain);
-static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context);
-static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime,
- char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir,
- signed char record_gain, struct vm_state *vms);
-static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain);
-static int vm_play_folder_name(struct ast_channel *chan, char *mbox);
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
-static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap);
-#if !(defined(ODBC_STORAGE) || defined(IMAP_STORAGE))
-static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit);
-#endif
-static void apply_options(struct ast_vm_user *vmu, const char *options);
-
-#ifdef ODBC_STORAGE
-static char odbc_database[80];
-static char odbc_table[80];
-#define RETRIEVE(a,b) retrieve_file(a,b)
-#define DISPOSE(a,b) remove_file(a,b)
-#define STORE(a,b,c,d,e,f,g,h,i) store_file(a,b,c,d)
-#define EXISTS(a,b,c,d) (message_exists(a,b))
-#define RENAME(a,b,c,d,e,f,g,h) (rename_file(a,b,c,d,e,f))
-#define COPY(a,b,c,d,e,f,g,h) (copy_file(a,b,c,d,e,f))
-#define DELETE(a,b,c) (delete_file(a,b))
-#else
-#ifdef IMAP_STORAGE
-#define RETRIEVE(a,b)
-#define DISPOSE(a,b)
-#define STORE(a,b,c,d,e,f,g,h,i) (imap_store_file(a,b,c,d,e,f,g,h,i))
-#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0)
-#define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h));
-#define COPY(a,b,c,d,e,f,g,h) (copy_file(g,h));
-#define IMAP_DELETE(a,b,c,d) (vm_imap_delete(b,d))
-#define DELETE(a,b,c) (vm_delete(c))
-#else
-#define RETRIEVE(a,b)
-#define DISPOSE(a,b)
-#define STORE(a,b,c,d,e,f,g,h,i)
-#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0)
-#define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h));
-#define COPY(a,b,c,d,e,f,g,h) (copy_plain_file(g,h));
-#define DELETE(a,b,c) (vm_delete(c))
-#endif
-#endif
-
-static char VM_SPOOL_DIR[PATH_MAX];
-
-static char ext_pass_cmd[128];
-
-int my_umask;
-
-#if ODBC_STORAGE
-#define tdesc "Comedian Mail (Voicemail System) with ODBC Storage"
-#elif IMAP_STORAGE
-#define tdesc "Comedian Mail (Voicemail System) with IMAP Storage"
-#else
-#define tdesc "Comedian Mail (Voicemail System)"
-#endif
-
-static char userscontext[AST_MAX_EXTENSION] = "default";
-
-static char *addesc = "Comedian Mail";
-
-static char *synopsis_vm =
-"Leave a Voicemail message";
-
-static char *descrip_vm =
-" VoiceMail(mailbox[@context][&mailbox[@context]][...][|options]): This\n"
-"application allows the calling party to leave a message for the specified\n"
-"list of mailboxes. When multiple mailboxes are specified, the greeting will\n"
-"be taken from the first mailbox specified. Dialplan execution will stop if the\n"
-"specified mailbox does not exist.\n"
-" The Voicemail application will exit if any of the following DTMF digits are\n"
-"received:\n"
-" 0 - Jump to the 'o' extension in the current dialplan context.\n"
-" * - Jump to the 'a' extension in the current dialplan context.\n"
-" This application will set the following channel variable upon completion:\n"
-" VMSTATUS - This indicates the status of the execution of the VoiceMail\n"
-" application. The possible values are:\n"
-" SUCCESS | USEREXIT | FAILED\n\n"
-" Options:\n"
-" b - Play the 'busy' greeting to the calling party.\n"
-" g(#) - Use the specified amount of gain when recording the voicemail\n"
-" message. The units are whole-number decibels (dB).\n"
-" s - Skip the playback of instructions for leaving a message to the\n"
-" calling party.\n"
-" u - Play the 'unavailable' greeting.\n"
-" j - Jump to priority n+101 if the mailbox is not found or some other\n"
-" error occurs.\n";
-
-static char *synopsis_vmain =
-"Check Voicemail messages";
-
-static char *descrip_vmain =
-" VoiceMailMain([mailbox][@context][|options]): This application allows the\n"
-"calling party to check voicemail messages. A specific mailbox, and optional\n"
-"corresponding context, may be specified. If a mailbox is not provided, the\n"
-"calling party will be prompted to enter one. If a context is not specified,\n"
-"the 'default' context will be used.\n\n"
-" Options:\n"
-" p - Consider the mailbox parameter as a prefix to the mailbox that\n"
-" is entered by the caller.\n"
-" g(#) - Use the specified amount of gain when recording a voicemail\n"
-" message. The units are whole-number decibels (dB).\n"
-" s - Skip checking the passcode for the mailbox.\n"
-" a(#) - Skip folder prompt and go directly to folder specified.\n"
-" Defaults to INBOX\n";
-
-static char *synopsis_vm_box_exists =
-"Check to see if Voicemail mailbox exists";
-
-static char *descrip_vm_box_exists =
-" MailboxExists(mailbox[@context][|options]): Check to see if the specified\n"
-"mailbox exists. If no voicemail context is specified, the 'default' context\n"
-"will be used.\n"
-" This application will set the following channel variable upon completion:\n"
-" VMBOXEXISTSSTATUS - This will contain the status of the execution of the\n"
-" MailboxExists application. Possible values include:\n"
-" SUCCESS | FAILED\n\n"
-" Options:\n"
-" j - Jump to priority n+101 if the mailbox is found.\n";
-
-static char *synopsis_vmauthenticate =
-"Authenticate with Voicemail passwords";
-
-static char *descrip_vmauthenticate =
-" VMAuthenticate([mailbox][@context][|options]): This application behaves the\n"
-"same way as the Authenticate application, but the passwords are taken from\n"
-"voicemail.conf.\n"
-" If the mailbox is specified, only that mailbox's password will be considered\n"
-"valid. If the mailbox is not specified, the channel variable AUTH_MAILBOX will\n"
-"be set with the authenticated mailbox.\n\n"
-" Options:\n"
-" s - Skip playing the initial prompts.\n";
-
-/* Leave a message */
-static char *app = "VoiceMail";
-
-/* Check mail, control, etc */
-static char *app2 = "VoiceMailMain";
-
-static char *app3 = "MailboxExists";
-static char *app4 = "VMAuthenticate";
-
-static AST_LIST_HEAD_STATIC(users, ast_vm_user);
-static AST_LIST_HEAD_STATIC(zones, vm_zone);
-static int maxsilence;
-static int maxmsg;
-static int silencethreshold = 128;
-static char serveremail[80];
-static char mailcmd[160]; /* Configurable mail cmd */
-static char externnotify[160];
-static struct ast_smdi_interface *smdi_iface = NULL;
-static char vmfmts[80];
-static double volgain;
-static int vmminmessage;
-static int vmmaxmessage;
-static int maxgreet;
-static int skipms;
-static int maxlogins;
-
-static struct ast_flags globalflags = {0};
-
-static int saydurationminfo;
-
-static char dialcontext[AST_MAX_CONTEXT];
-static char callcontext[AST_MAX_CONTEXT];
-static char exitcontext[AST_MAX_CONTEXT];
-
-static char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64];
-
-
-static char *emailbody = NULL;
-static char *emailsubject = NULL;
-static char *pagerbody = NULL;
-static char *pagersubject = NULL;
-static char fromstring[100];
-static char pagerfromstring[100];
-static char emailtitle[100];
-static char charset[32] = "ISO-8859-1";
-
-static unsigned char adsifdn[4] = "\x00\x00\x00\x0F";
-static unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC";
-static int adsiver = 1;
-static char emaildateformat[32] = "%A, %B %d, %Y at %r";
-
-
-static void populate_defaults(struct ast_vm_user *vmu)
-{
- ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);
- if (saydurationminfo)
- vmu->saydurationm = saydurationminfo;
- ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
- ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
- ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
- if (maxmsg)
- vmu->maxmsg = maxmsg;
- vmu->volgain = volgain;
-}
-
-static void apply_option(struct ast_vm_user *vmu, const char *var, const char *value)
-{
- int x;
- if (!strcasecmp(var, "attach")) {
- ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
- } else if (!strcasecmp(var, "attachfmt")) {
- ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
- } else if (!strcasecmp(var, "serveremail")) {
- ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
- } else if (!strcasecmp(var, "language")) {
- ast_copy_string(vmu->language, value, sizeof(vmu->language));
- } else if (!strcasecmp(var, "tz")) {
- ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
-#ifdef IMAP_STORAGE
- } else if (!strcasecmp(var, "imapuser")) {
- ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
- } else if (!strcasecmp(var, "imappassword")) {
- ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
-#endif
- } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
- ast_set2_flag(vmu, ast_true(value), VM_DELETE);
- } else if (!strcasecmp(var, "saycid")){
- ast_set2_flag(vmu, ast_true(value), VM_SAYCID);
- } else if (!strcasecmp(var,"sendvoicemail")){
- ast_set2_flag(vmu, ast_true(value), VM_SVMAIL);
- } else if (!strcasecmp(var, "review")){
- ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
- } else if (!strcasecmp(var, "tempgreetwarn")){
- ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);
- } else if (!strcasecmp(var, "operator")){
- ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);
- } else if (!strcasecmp(var, "envelope")){
- ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);
- } else if (!strcasecmp(var, "sayduration")){
- ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);
- } else if (!strcasecmp(var, "saydurationm")){
- if (sscanf(value, "%d", &x) == 1) {
- vmu->saydurationm = x;
- } else {
- ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
- }
- } else if (!strcasecmp(var, "forcename")){
- ast_set2_flag(vmu, ast_true(value), VM_FORCENAME);
- } else if (!strcasecmp(var, "forcegreetings")){
- ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);
- } else if (!strcasecmp(var, "callback")) {
- ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
- } else if (!strcasecmp(var, "dialout")) {
- ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
- } else if (!strcasecmp(var, "exitcontext")) {
- ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
- } else if (!strcasecmp(var, "maxmsg")) {
- vmu->maxmsg = atoi(value);
- if (vmu->maxmsg <= 0) {
- ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
- vmu->maxmsg = MAXMSG;
- } else if (vmu->maxmsg > MAXMSGLIMIT) {
- ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
- vmu->maxmsg = MAXMSGLIMIT;
- }
- } else if (!strcasecmp(var, "volgain")) {
- sscanf(value, "%lf", &vmu->volgain);
- } else if (!strcasecmp(var, "options")) {
- apply_options(vmu, value);
- }
-}
-
-static int change_password_realtime(struct ast_vm_user *vmu, const char *password)
-{
- int res;
- if (!ast_strlen_zero(vmu->uniqueid)) {
- res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
- if (res > 0) {
- ast_copy_string(vmu->password, password, sizeof(vmu->password));
- res = 0;
- } else if (!res) {
- res = -1;
- }
- return res;
- }
- return -1;
-}
-
-static void apply_options(struct ast_vm_user *vmu, const char *options)
-{ /* Destructively Parse options and apply */
- char *stringp;
- char *s;
- char *var, *value;
- stringp = ast_strdupa(options);
- while ((s = strsep(&stringp, "|"))) {
- value = s;
- if ((var = strsep(&value, "=")) && value) {
- apply_option(vmu, var, value);
- }
- }
-}
-
-static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *var)
-{
- struct ast_variable *tmp;
- tmp = var;
- while (tmp) {
- if (!strcasecmp(tmp->name, "vmsecret")) {
- ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
- } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
- if (ast_strlen_zero(retval->password))
- ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
- } else if (!strcasecmp(tmp->name, "uniqueid")) {
- ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
- } else if (!strcasecmp(tmp->name, "pager")) {
- ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
- } else if (!strcasecmp(tmp->name, "email")) {
- ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
- } else if (!strcasecmp(tmp->name, "fullname")) {
- ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
- } else if (!strcasecmp(tmp->name, "context")) {
- ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
-#ifdef IMAP_STORAGE
- } else if (!strcasecmp(tmp->name, "imapuser")) {
- ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
- } else if (!strcasecmp(tmp->name, "imappassword")) {
- ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
-#endif
- } else
- apply_option(retval, tmp->name, tmp->value);
- tmp = tmp->next;
- }
-}
-
-static struct ast_vm_user *find_user_realtime(struct ast_vm_user *ivm, const char *context, const char *mailbox)
-{
- struct ast_variable *var;
- struct ast_vm_user *retval;
-
- if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
- if (!ivm)
- ast_set_flag(retval, VM_ALLOCED);
- else
- memset(retval, 0, sizeof(*retval));
- if (mailbox)
- ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
- populate_defaults(retval);
- if (!context && ast_test_flag((&globalflags), VM_SEARCH))
- var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
- else
- var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
- if (var) {
- apply_options_full(retval, var);
- ast_variables_destroy(var);
- } else {
- if (!ivm)
- free(retval);
- retval = NULL;
- }
- }
- return retval;
-}
-
-static struct ast_vm_user *find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
-{
- /* This function could be made to generate one from a database, too */
- struct ast_vm_user *vmu=NULL, *cur;
- AST_LIST_LOCK(&users);
-
- if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
- context = "default";
-
- AST_LIST_TRAVERSE(&users, cur, list) {
- if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
- break;
- if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
- break;
- }
- if (cur) {
- /* Make a copy, so that on a reload, we have no race */
- if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
- memcpy(vmu, cur, sizeof(*vmu));
- ast_set2_flag(vmu, !ivm, VM_ALLOCED);
- AST_LIST_NEXT(vmu, list) = NULL;
- }
- } else
- vmu = find_user_realtime(ivm, context, mailbox);
- AST_LIST_UNLOCK(&users);
- return vmu;
-}
-
-static int reset_user_pw(const char *context, const char *mailbox, const char *newpass)
-{
- /* This function could be made to generate one from a database, too */
- struct ast_vm_user *cur;
- int res = -1;
- AST_LIST_LOCK(&users);
- AST_LIST_TRAVERSE(&users, cur, list) {
- if ((!context || !strcasecmp(context, cur->context)) &&
- (!strcasecmp(mailbox, cur->mailbox)))
- break;
- }
- if (cur) {
- ast_copy_string(cur->password, newpass, sizeof(cur->password));
- res = 0;
- }
- AST_LIST_UNLOCK(&users);
- return res;
-}
-
-static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
-{
- struct ast_config *cfg=NULL;
- struct ast_variable *var=NULL;
- struct ast_category *cat=NULL;
- char *category=NULL, *value=NULL, *new=NULL;
- const char *tmp=NULL;
-
- if (!change_password_realtime(vmu, newpassword))
- return;
-
- /* check voicemail.conf */
- if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
- while ((category = ast_category_browse(cfg, category))) {
- if (!strcasecmp(category, vmu->context)) {
- tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
- if (!tmp) {
- ast_log(LOG_WARNING, "We could not find the mailbox.\n");
- break;
- }
- value = strstr(tmp,",");
- if (!value) {
- ast_log(LOG_WARNING, "variable has bad format.\n");
- break;
- }
- new = alloca((strlen(value)+strlen(newpassword)+1));
- sprintf(new,"%s%s", newpassword, value);
- if (!(cat = ast_category_get(cfg, category))) {
- ast_log(LOG_WARNING, "Failed to get category structure.\n");
- break;
- }
- ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
- }
- }
- /* save the results */
- reset_user_pw(vmu->context, vmu->mailbox, newpassword);
- ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
- config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
- }
- category = NULL;
- var = NULL;
- /* check users.conf and update the password stored for the mailbox*/
- /* if no vmsecret entry exists create one. */
- if ((cfg = ast_config_load_with_comments("users.conf"))) {
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
- while ((category = ast_category_browse(cfg, category))) {
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "users.conf: %s\n", category);
- if (!strcasecmp(category, vmu->mailbox)) {
- if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
- var = ast_variable_new("vmsecret", newpassword);
- }
- new = alloca(strlen(newpassword)+1);
- sprintf(new, "%s", newpassword);
- if (!(cat = ast_category_get(cfg, category))) {
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "failed to get category!\n");
- break;
- }
- if (!var)
- ast_variable_update(cat, "vmsecret", new, NULL, 0);
- else
- ast_variable_append(cat, var);
- }
- }
- /* save the results and clean things up */
- reset_user_pw(vmu->context, vmu->mailbox, newpassword);
- ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
- config_text_file_save("users.conf", cfg, "AppVoicemail");
- }
-}
-
-static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
-{
- char buf[255];
- snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
- if (!ast_safe_system(buf)) {
- ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
- /* Reset the password in memory, too */
- reset_user_pw(vmu->context, vmu->mailbox, newpassword);
- }
-}
-
-static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
-{
- return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
-}
-
-#ifdef IMAP_STORAGE
-static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num)
-{
- if (mkdir(dir, 01777) && (errno != EEXIST)) {
- ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
- return snprintf(dest, len, "%s/msg%04d", dir, num);
- }
- return snprintf(dest, len, "%s/msg%04d", dir, num);
-}
-
-static void vm_imap_delete(int msgnum, struct vm_state *vms)
-{
- unsigned long messageNum = 0;
- char arg[10];
-
- /* find real message number based on msgnum */
- /* this may be an index into vms->msgArray based on the msgnum. */
-
- messageNum = vms->msgArray[msgnum];
- if (messageNum == 0) {
- ast_log(LOG_WARNING, "msgnum %d, mailbox message %lu is zero.\n",msgnum,messageNum);
- return;
- }
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "deleting msgnum %d, which is mailbox message %lu\n",msgnum,messageNum);
- /* delete message */
- snprintf (arg, sizeof(arg), "%lu",messageNum);
- mail_setflag (vms->mailstream,arg,"\\DELETED");
-}
-
-#endif
-static int make_file(char *dest, int len, char *dir, int num)
-{
- return snprintf(dest, len, "%s/msg%04d", dir, num);
-}
-
-/*! \brief basically mkdir -p $dest/$context/$ext/$folder
- * \param dest String. base directory.
- * \param len Length of dest.
- * \param context String. Ignored if is null or empty string.
- * \param ext String. Ignored if is null or empty string.
- * \param folder String. Ignored if is null or empty string.
- * \return -1 on failure, 0 on success.
- */
-static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
-{
- mode_t mode = VOICEMAIL_DIR_MODE;
-
- if (!ast_strlen_zero(context)) {
- make_dir(dest, len, context, "", "");
- if (mkdir(dest, mode) && errno != EEXIST) {
- ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
- return -1;
- }
- }
- if (!ast_strlen_zero(ext)) {
- make_dir(dest, len, context, ext, "");
- if (mkdir(dest, mode) && errno != EEXIST) {
- ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
- return -1;
- }
- }
- if (!ast_strlen_zero(folder)) {
- make_dir(dest, len, context, ext, folder);
- if (mkdir(dest, mode) && errno != EEXIST) {
- ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
-/* only return failure if ast_lock_path returns 'timeout',
- not if the path does not exist or any other reason
-*/
-static int vm_lock_path(const char *path)
-{
- switch (ast_lock_path(path)) {
- case AST_LOCK_TIMEOUT:
- return -1;
- default:
- return 0;
- }
-}
-
-
-#ifdef ODBC_STORAGE
-struct generic_prepare_struct {
- char *sql;
- int argc;
- char **argv;
-};
-
-static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
-{
- struct generic_prepare_struct *gps = data;
- int res, i;
- SQLHSTMT stmt;
-
- res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
- return NULL;
- }
- res = SQLPrepare(stmt, (unsigned char *)gps->sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", gps->sql);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- return NULL;
- }
- for (i = 0; i < gps->argc; i++)
- SQLBindParameter(stmt, i + 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(gps->argv[i]), 0, gps->argv[i], 0, NULL);
-
- return stmt;
-}
-
-static int retrieve_file(char *dir, int msgnum)
-{
- int x = 0;
- int res;
- int fd=-1;
- size_t fdlen = 0;
- void *fdm = MAP_FAILED;
- SQLSMALLINT colcount=0;
- SQLHSTMT stmt;
- char sql[PATH_MAX];
- char fmt[80]="";
- char *c;
- char coltitle[256];
- SQLSMALLINT collen;
- SQLSMALLINT datatype;
- SQLSMALLINT decimaldigits;
- SQLSMALLINT nullable;
- SQLULEN colsize;
- SQLLEN colsize2;
- FILE *f=NULL;
- char rowdata[80];
- char fn[PATH_MAX];
- char full_fn[PATH_MAX];
- char msgnums[80];
- char *argv[] = { dir, msgnums };
- struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
-
- struct odbc_obj *obj;
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- ast_copy_string(fmt, vmfmts, sizeof(fmt));
- c = strchr(fmt, '|');
- if (c)
- *c = '\0';
- if (!strcasecmp(fmt, "wav49"))
- strcpy(fmt, "WAV");
- snprintf(msgnums, sizeof(msgnums),"%d", msgnum);
- if (msgnum > -1)
- make_file(fn, sizeof(fn), dir, msgnum);
- else
- ast_copy_string(fn, dir, sizeof(fn));
- snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);
-
- if (!(f = fopen(full_fn, "w+"))) {
- ast_log(LOG_WARNING, "Failed to open/create '%s'\n", full_fn);
- goto yuck;
- }
-
- snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?",odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLFetch(stmt);
- if (res == SQL_NO_DATA) {
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- fd = open(full_fn, O_RDWR | O_CREAT | O_TRUNC, 0770);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Failed to write '%s': %s\n", full_fn, strerror(errno));
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLNumResultCols(stmt, &colcount);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (f)
- fprintf(f, "[message]\n");
- for (x=0;x<colcount;x++) {
- rowdata[0] = '\0';
- collen = sizeof(coltitle);
- res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen,
- &datatype, &colsize, &decimaldigits, &nullable);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (!strcasecmp(coltitle, "recording")) {
- off_t offset;
- res = SQLGetData(stmt, x + 1, SQL_BINARY, rowdata, 0, &colsize2);
- fdlen = colsize2;
- if (fd > -1) {
- char tmp[1]="";
- lseek(fd, fdlen - 1, SEEK_SET);
- if (write(fd, tmp, 1) != 1) {
- close(fd);
- fd = -1;
- continue;
- }
- /* Read out in small chunks */
- for (offset = 0; offset < colsize2; offset += CHUNKSIZE) {
- if ((fdm = mmap(NULL, CHUNKSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) {
- ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- } else {
- res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE, NULL);
- munmap(fdm, CHUNKSIZE);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- unlink(full_fn);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- }
- }
- truncate(full_fn, fdlen);
- }
- } else {
- res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (strcasecmp(coltitle, "msgnum") && strcasecmp(coltitle, "dir") && f)
- fprintf(f, "%s=%s\n", coltitle, rowdata);
- }
- }
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:
- if (f)
- fclose(f);
- if (fd > -1)
- close(fd);
- return x - 1;
-}
-
-static int remove_file(char *dir, int msgnum)
-{
- char fn[PATH_MAX];
- char full_fn[PATH_MAX];
- char msgnums[80];
-
- if (msgnum > -1) {
- snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
- make_file(fn, sizeof(fn), dir, msgnum);
- } else
- ast_copy_string(fn, dir, sizeof(fn));
- ast_filedelete(fn, NULL);
- snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);
- unlink(full_fn);
- return 0;
-}
-
-static int last_message_index(struct ast_vm_user *vmu, char *dir)
-{
- int x = 0;
- int res;
- SQLHSTMT stmt;
- char sql[PATH_MAX];
- char rowdata[20];
- char *argv[] = { dir };
- struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };
-
- struct odbc_obj *obj;
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?",odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLFetch(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (sscanf(rowdata, "%d", &x) != 1)
- ast_log(LOG_WARNING, "Failed to read message count!\n");
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:
- return x - 1;
-}
-
-static int message_exists(char *dir, int msgnum)
-{
- int x = 0;
- int res;
- SQLHSTMT stmt;
- char sql[PATH_MAX];
- char rowdata[20];
- char msgnums[20];
- char *argv[] = { dir, msgnums };
- struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
-
- struct odbc_obj *obj;
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?",odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLFetch(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (sscanf(rowdata, "%d", &x) != 1)
- ast_log(LOG_WARNING, "Failed to read message count!\n");
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:
- return x;
-}
-
-static int count_messages(struct ast_vm_user *vmu, char *dir)
-{
- return last_message_index(vmu, dir) + 1;
-}
-
-static void delete_file(char *sdir, int smsg)
-{
- SQLHSTMT stmt;
- char sql[PATH_MAX];
- char msgnums[20];
- char *argv[] = { sdir, msgnums };
- struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
-
- struct odbc_obj *obj;
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(msgnums, sizeof(msgnums), "%d", smsg);
- snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?",odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt)
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- else
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
- return;
-}
-
-static void copy_file(char *sdir, int smsg, char *ddir, int dmsg, char *dmailboxuser, char *dmailboxcontext)
-{
- SQLHSTMT stmt;
- char sql[512];
- char msgnums[20];
- char msgnumd[20];
- struct odbc_obj *obj;
- char *argv[] = { ddir, msgnumd, dmailboxuser, dmailboxcontext, sdir, msgnums };
- struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv };
-
- delete_file(ddir, dmsg);
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(msgnums, sizeof(msgnums), "%d", smsg);
- snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);
- snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, context, macrocontext, callerid, origtime, duration, recording, mailboxuser, mailboxcontext) SELECT ?,?,context,macrocontext,callerid,origtime,duration,recording,?,? FROM %s WHERE dir=? AND msgnum=?",odbc_table,odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt)
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);
- else
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
- return;
-}
-
-static int store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum)
-{
- int x = 0;
- int res;
- int fd = -1;
- void *fdm = MAP_FAILED;
- size_t fdlen = -1;
- SQLHSTMT stmt;
- SQLLEN len;
- char sql[PATH_MAX];
- char msgnums[20];
- char fn[PATH_MAX];
- char full_fn[PATH_MAX];
- char fmt[80]="";
- char *c;
- const char *context="", *macrocontext="", *callerid="", *origtime="", *duration="";
- const char *category = "";
- struct ast_config *cfg=NULL;
- struct odbc_obj *obj;
-
- delete_file(dir, msgnum);
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- ast_copy_string(fmt, vmfmts, sizeof(fmt));
- c = strchr(fmt, '|');
- if (c)
- *c = '\0';
- if (!strcasecmp(fmt, "wav49"))
- strcpy(fmt, "WAV");
- snprintf(msgnums, sizeof(msgnums),"%d", msgnum);
- if (msgnum > -1)
- make_file(fn, sizeof(fn), dir, msgnum);
- else
- ast_copy_string(fn, dir, sizeof(fn));
- snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);
- cfg = ast_config_load(full_fn);
- snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);
- fd = open(full_fn, O_RDWR);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Open of sound file '%s' failed: %s\n", full_fn, strerror(errno));
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (cfg) {
- context = ast_variable_retrieve(cfg, "message", "context");
- if (!context) context = "";
- macrocontext = ast_variable_retrieve(cfg, "message", "macrocontext");
- if (!macrocontext) macrocontext = "";
- callerid = ast_variable_retrieve(cfg, "message", "callerid");
- if (!callerid) callerid = "";
- origtime = ast_variable_retrieve(cfg, "message", "origtime");
- if (!origtime) origtime = "";
- duration = ast_variable_retrieve(cfg, "message", "duration");
- if (!duration) duration = "";
- category = ast_variable_retrieve(cfg, "message", "category");
- if (!category) category = "";
- }
- fdlen = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
- printf("Length is %zd\n", fdlen);
- fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
- if (fdm == MAP_FAILED) {
- ast_log(LOG_WARNING, "Memory map failed!\n");
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- if (!ast_strlen_zero(category))
- snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,category) VALUES (?,?,?,?,?,?,?,?,?,?,?)",odbc_table);
- else
- snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext) VALUES (?,?,?,?,?,?,?,?,?,?)",odbc_table);
- res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- len = fdlen; /* SQL_LEN_DATA_AT_EXEC(fdlen); */
- SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(dir), 0, (void *)dir, 0, NULL);
- SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL);
- SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, fdlen, 0, (void *)fdm, fdlen, &len);
- SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(context), 0, (void *)context, 0, NULL);
- SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(macrocontext), 0, (void *)macrocontext, 0, NULL);
- SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(callerid), 0, (void *)callerid, 0, NULL);
- SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(origtime), 0, (void *)origtime, 0, NULL);
- SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(duration), 0, (void *)duration, 0, NULL);
- SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(mailboxuser), 0, (void *)mailboxuser, 0, NULL);
- SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(mailboxcontext), 0, (void *)mailboxcontext, 0, NULL);
- if (!ast_strlen_zero(category))
- SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(category), 0, (void *)category, 0, NULL);
- res = ast_odbc_smart_execute(obj, stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:
- if (cfg)
- ast_config_destroy(cfg);
- if (fdm != MAP_FAILED)
- munmap(fdm, fdlen);
- if (fd > -1)
- close(fd);
- return x;
-}
-
-static void rename_file(char *sdir, int smsg, char *mailboxuser, char *mailboxcontext, char *ddir, int dmsg)
-{
- SQLHSTMT stmt;
- char sql[PATH_MAX];
- char msgnums[20];
- char msgnumd[20];
- struct odbc_obj *obj;
- char *argv[] = { ddir, msgnumd, mailboxuser, mailboxcontext, sdir, msgnums };
- struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv };
-
- delete_file(ddir, dmsg);
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(msgnums, sizeof(msgnums), "%d", smsg);
- snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);
- snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?",odbc_table);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt)
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- else
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
- return;
-}
-
-#else
-#ifndef IMAP_STORAGE
-static int count_messages(struct ast_vm_user *vmu, char *dir)
-{
- /* Find all .txt files - even if they are not in sequence from 0000 */
-
- int vmcount = 0;
- DIR *vmdir = NULL;
- struct dirent *vment = NULL;
-
- if (vm_lock_path(dir))
- return ERROR_LOCK_PATH;
-
- if ((vmdir = opendir(dir))) {
- while ((vment = readdir(vmdir))) {
- if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4))
- vmcount++;
- }
- closedir(vmdir);
- }
- ast_unlock_path(dir);
-
- return vmcount;
-}
-
-static void rename_file(char *sfn, char *dfn)
-{
- char stxt[PATH_MAX];
- char dtxt[PATH_MAX];
- ast_filerename(sfn,dfn,NULL);
- snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
- snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
- rename(stxt, dtxt);
-}
-#endif
-
-/*
- * A negative return value indicates an error.
- */
-#if (!defined(IMAP_STORAGE) && !defined(ODBC_STORAGE))
-static int last_message_index(struct ast_vm_user *vmu, char *dir)
-{
- int x;
- char fn[PATH_MAX];
-
- if (vm_lock_path(dir))
- return ERROR_LOCK_PATH;
-
- for (x = 0; x < vmu->maxmsg; x++) {
- make_file(fn, sizeof(fn), dir, x);
- if (ast_fileexists(fn, NULL, NULL) < 1)
- break;
- }
- ast_unlock_path(dir);
-
- return x - 1;
-}
-#endif
-#endif
-
-static int copy(char *infile, char *outfile)
-{
- int ifd;
- int ofd;
- int res;
- int len;
- char buf[4096];
-
-#ifdef HARDLINK_WHEN_POSSIBLE
- /* Hard link if possible; saves disk space & is faster */
- if (link(infile, outfile)) {
-#endif
- if ((ifd = open(infile, O_RDONLY)) < 0) {
- ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
- return -1;
- }
- if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
- ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
- close(ifd);
- return -1;
- }
- do {
- len = read(ifd, buf, sizeof(buf));
- if (len < 0) {
- ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
- close(ifd);
- close(ofd);
- unlink(outfile);
- }
- if (len) {
- res = write(ofd, buf, len);
- if (errno == ENOMEM || errno == ENOSPC || res != len) {
- ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
- close(ifd);
- close(ofd);
- unlink(outfile);
- }
- }
- } while (len);
- close(ifd);
- close(ofd);
- return 0;
-#ifdef HARDLINK_WHEN_POSSIBLE
- } else {
- /* Hard link succeeded */
- return 0;
- }
-#endif
-}
-
-static void copy_plain_file(char *frompath, char *topath)
-{
- char frompath2[PATH_MAX], topath2[PATH_MAX];
- ast_filecopy(frompath, topath, NULL);
- snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
- snprintf(topath2, sizeof(topath2), "%s.txt", topath);
- copy(frompath2, topath2);
-}
-
-static int vm_delete(char *file)
-{
- char *txt;
- int txtsize = 0;
-
- txtsize = (strlen(file) + 5)*sizeof(char);
- txt = alloca(txtsize);
- /* Sprintf here would safe because we alloca'd exactly the right length,
- * but trying to eliminate all sprintf's anyhow
- */
- snprintf(txt, txtsize, "%s.txt", file);
- unlink(txt);
- return ast_filedelete(file, NULL);
-}
-
-static int inbuf(struct baseio *bio, FILE *fi)
-{
- int l;
-
- if (bio->ateof)
- return 0;
-
- if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
- if (ferror(fi))
- return -1;
-
- bio->ateof = 1;
- return 0;
- }
-
- bio->iolen= l;
- bio->iocp= 0;
-
- return 1;
-}
-
-static int inchar(struct baseio *bio, FILE *fi)
-{
- if (bio->iocp>=bio->iolen) {
- if (!inbuf(bio, fi))
- return EOF;
- }
-
- return bio->iobuf[bio->iocp++];
-}
-
-static int ochar(struct baseio *bio, int c, FILE *so)
-{
- if (bio->linelength>=BASELINELEN) {
- if (fputs(eol,so)==EOF)
- return -1;
-
- bio->linelength= 0;
- }
-
- if (putc(((unsigned char)c),so)==EOF)
- return -1;
-
- bio->linelength++;
-
- return 1;
-}
-
-static int base_encode(char *filename, FILE *so)
-{
- unsigned char dtable[BASEMAXINLINE];
- int i,hiteof= 0;
- FILE *fi;
- struct baseio bio;
-
- memset(&bio, 0, sizeof(bio));
- bio.iocp = BASEMAXINLINE;
-
- if (!(fi = fopen(filename, "rb"))) {
- ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- for (i= 0;i<9;i++) {
- dtable[i]= 'A'+i;
- dtable[i+9]= 'J'+i;
- dtable[26+i]= 'a'+i;
- dtable[26+i+9]= 'j'+i;
- }
- for (i= 0;i<8;i++) {
- dtable[i+18]= 'S'+i;
- dtable[26+i+18]= 's'+i;
- }
- for (i= 0;i<10;i++) {
- dtable[52+i]= '0'+i;
- }
- dtable[62]= '+';
- dtable[63]= '/';
-
- while (!hiteof){
- unsigned char igroup[3],ogroup[4];
- int c,n;
-
- igroup[0]= igroup[1]= igroup[2]= 0;
-
- for (n= 0;n<3;n++) {
- if ((c = inchar(&bio, fi)) == EOF) {
- hiteof= 1;
- break;
- }
-
- igroup[n]= (unsigned char)c;
- }
-
- if (n> 0) {
- ogroup[0]= dtable[igroup[0]>>2];
- ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
- ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
- ogroup[3]= dtable[igroup[2]&0x3F];
-
- if (n<3) {
- ogroup[3]= '=';
-
- if (n<2)
- ogroup[2]= '=';
- }
-
- for (i= 0;i<4;i++)
- ochar(&bio, ogroup[i], so);
- }
- }
-
- fclose(fi);
-
- if (fputs(eol,so)==EOF)
- return 0;
-
- return 1;
-}
-
-static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category)
-{
- char callerid[256];
- /* Prepare variables for substition in email body and subject */
- pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
- pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
- snprintf(passdata, passdatasize, "%d", msgnum);
- pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
- pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
- pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
- pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
- pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
- pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
- pbx_builtin_setvar_helper(ast, "VM_DATE", date);
- pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
-}
-
-static char *quote(const char *from, char *to, size_t len)
-{
- char *ptr = to;
- *ptr++ = '"';
- for (; ptr < to + len - 1; from++) {
- if (*from == '"')
- *ptr++ = '\\';
- else if (*from == '\0')
- break;
- *ptr++ = *from;
- }
- if (ptr < to + len - 1)
- *ptr++ = '"';
- *ptr = '\0';
- return to;
-}
-/*
- * fill in *tm for current time according to the proper timezone, if any.
- * Return tm so it can be used as a function argument.
- */
-static const struct tm *vmu_tm(const struct ast_vm_user *vmu, struct tm *tm)
-{
- const struct vm_zone *z = NULL;
- time_t t = time(NULL);
-
- /* Does this user have a timezone specified? */
- if (!ast_strlen_zero(vmu->zonetag)) {
- /* Find the zone in the list */
- AST_LIST_LOCK(&zones);
- AST_LIST_TRAVERSE(&zones, z, list) {
- if (!strcmp(z->name, vmu->zonetag))
- break;
- }
- AST_LIST_UNLOCK(&zones);
- }
- ast_localtime(&t, tm, z ? z->timezone : NULL);
- return tm;
-}
-
-/* same as mkstemp, but return a FILE * */
-static FILE *vm_mkftemp(char *template)
-{
- FILE *p = NULL;
- int pfd = mkstemp(template);
- chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
- if (pfd > -1) {
- p = fdopen(pfd, "w+");
- if (!p) {
- close(pfd);
- pfd = -1;
- }
- }
- return p;
-}
-
-static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
-{
- char date[256];
- char host[MAXHOSTNAMELEN] = "";
- char who[256];
- char bound[256];
- char fname[256];
- char dur[256];
- char tmpcmd[256];
- struct tm tm;
- char *passdata2;
- size_t len_passdata;
-#ifdef IMAP_STORAGE
-#define ENDL "\r\n"
-#else
-#define ENDL "\n"
-#endif
-
- gethostname(host, sizeof(host) - 1);
- if (strchr(srcemail, '@'))
- ast_copy_string(who, srcemail, sizeof(who));
- else {
- snprintf(who, sizeof(who), "%s@%s", srcemail, host);
- }
- snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
- strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
- fprintf(p, "Date: %s" ENDL, date);
-
- /* Set date format for voicemail mail */
- strftime(date, sizeof(date), emaildateformat, &tm);
-
- if (*fromstring) {
- struct ast_channel *ast;
- if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
- char *passdata;
- int vmlen = strlen(fromstring)*3 + 200;
- if ((passdata = alloca(vmlen))) {
- memset(passdata, 0, vmlen);
- prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
- pbx_substitute_variables_helper(ast, fromstring, passdata, vmlen);
- len_passdata = strlen(passdata) * 2 + 3;
- passdata2 = alloca(len_passdata);
- fprintf(p, "From: %s <%s>" ENDL, quote(passdata, passdata2, len_passdata), who);
- } else
- ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
- ast_channel_free(ast);
- } else
- ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
- } else
- fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
- len_passdata = strlen(vmu->fullname) * 2 + 3;
- passdata2 = alloca(len_passdata);
- fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata), vmu->email);
- if (emailsubject) {
- struct ast_channel *ast;
- if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
- char *passdata;
- int vmlen = strlen(emailsubject)*3 + 200;
- if ((passdata = alloca(vmlen))) {
- memset(passdata, 0, vmlen);
- prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
- pbx_substitute_variables_helper(ast, emailsubject, passdata, vmlen);
- fprintf(p, "Subject: %s" ENDL, passdata);
- } else
- ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
- ast_channel_free(ast);
- } else
- ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
- } else if (*emailtitle) {
- fprintf(p, emailtitle, msgnum + 1, mailbox) ;
- fprintf(p, ENDL) ;
- } else if (ast_test_flag((&globalflags), VM_PBXSKIP))
- fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
- else
- fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
- fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
- if (imap) {
- /* additional information needed for IMAP searching */
- fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
- /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
- fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
- fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
- fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
- fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
- fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
- fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, cidnum);
- fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, cidname);
- fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
- if (!ast_strlen_zero(category))
- fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
- fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
- fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
- }
- if (!ast_strlen_zero(cidnum))
- fprintf(p, "X-Asterisk-CallerID: %s" ENDL, cidnum);
- if (!ast_strlen_zero(cidname))
- fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, cidname);
- fprintf(p, "MIME-Version: 1.0" ENDL);
- if (attach_user_voicemail) {
- /* Something unique. */
- snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
-
- fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
- fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
- fprintf(p, "--%s" ENDL, bound);
- }
- fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
- if (emailbody) {
- struct ast_channel *ast;
- if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
- char *passdata;
- int vmlen = strlen(emailbody)*3 + 200;
- if ((passdata = alloca(vmlen))) {
- memset(passdata, 0, vmlen);
- prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
- pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
- fprintf(p, "%s" ENDL, passdata);
- } else
- ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
- ast_channel_free(ast);
- } else
- ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
- } else {
- fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a %s long message (number %d)" ENDL
-
- "in mailbox %s from %s, on %s so you might" ENDL
- "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname,
- dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
- }
- if (attach_user_voicemail) {
- /* Eww. We want formats to tell us their own MIME type */
- char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
- char tmpdir[256], newtmp[256];
- int tmpfd = -1;
-
- if (vmu->volgain < -.001 || vmu->volgain > .001) {
- create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
- snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
- tmpfd = mkstemp(newtmp);
- chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
- if (tmpfd > -1) {
- snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
- ast_safe_system(tmpcmd);
- attach = newtmp;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
- }
- }
- fprintf(p, "--%s" ENDL, bound);
- fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
- fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
- fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
- fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
- snprintf(fname, sizeof(fname), "%s.%s", attach, format);
- base_encode(fname, p);
- fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
- if (tmpfd > -1) {
- unlink(fname);
- close(tmpfd);
- unlink(newtmp);
- }
- }
-#undef ENDL
-}
-static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category)
-{
- FILE *p=NULL;
- char tmp[80] = "/tmp/astmail-XXXXXX";
- char tmp2[256];
-
- if (vmu && ast_strlen_zero(vmu->email)) {
- ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox);
- return(0);
- }
- if (!strcmp(format, "wav49"))
- format = "WAV";
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
- /* Make a temporary file instead of piping directly to sendmail, in case the mail
- command hangs */
- if ((p = vm_mkftemp(tmp)) == NULL) {
- ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
- return -1;
- } else {
- make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
- fclose(p);
- snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
- ast_safe_system(tmp2);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
- }
- return 0;
-}
-
-static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category)
-{
- char date[256];
- char host[MAXHOSTNAMELEN] = "";
- char who[256];
- char dur[PATH_MAX];
- char tmp[80] = "/tmp/astmail-XXXXXX";
- char tmp2[PATH_MAX];
- struct tm tm;
- FILE *p;
-
- if ((p = vm_mkftemp(tmp)) == NULL) {
- ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
- return -1;
- } else {
- gethostname(host, sizeof(host)-1);
- if (strchr(srcemail, '@'))
- ast_copy_string(who, srcemail, sizeof(who));
- else {
- snprintf(who, sizeof(who), "%s@%s", srcemail, host);
- }
- snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
- strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
- fprintf(p, "Date: %s\n", date);
-
- if (*pagerfromstring) {
- struct ast_channel *ast;
- if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
- char *passdata;
- int vmlen = strlen(fromstring)*3 + 200;
- if ((passdata = alloca(vmlen))) {
- memset(passdata, 0, vmlen);
- prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
- pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
- fprintf(p, "From: %s <%s>\n", passdata, who);
- } else
- ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
- ast_channel_free(ast);
- } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
- } else
- fprintf(p, "From: Asterisk PBX <%s>\n", who);
- fprintf(p, "To: %s\n", pager);
- if (pagersubject) {
- struct ast_channel *ast;
- if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
- char *passdata;
- int vmlen = strlen(pagersubject) * 3 + 200;
- if ((passdata = alloca(vmlen))) {
- memset(passdata, 0, vmlen);
- prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
- pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
- fprintf(p, "Subject: %s\n\n", passdata);
- } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
- ast_channel_free(ast);
- } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
- } else
- fprintf(p, "Subject: New VM\n\n");
- strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
- if (pagerbody) {
- struct ast_channel *ast;
- if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
- char *passdata;
- int vmlen = strlen(pagerbody)*3 + 200;
- if ((passdata = alloca(vmlen))) {
- memset(passdata, 0, vmlen);
- prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
- pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
- fprintf(p, "%s\n", passdata);
- } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
- ast_channel_free(ast);
- } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
- } else {
- fprintf(p, "New %s long msg in box %s\n"
- "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
- }
- fclose(p);
- snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
- ast_safe_system(tmp2);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
- }
- return 0;
-}
-
-static int get_date(char *s, int len)
-{
- struct tm tm;
- time_t t;
-
- time(&t);
-
- ast_localtime(&t, &tm, NULL);
-
- return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
-}
-
-static int play_greeting(struct ast_channel *chan, struct ast_vm_user *vmu, char *filename, char *ecodes)
-{
- int res = -2;
-
-#ifdef ODBC_STORAGE
- int success =
-#endif
- RETRIEVE(filename, -1);
- if (ast_fileexists(filename, NULL, NULL) > 0) {
- res = ast_streamfile(chan, filename, chan->language);
- if (res > -1)
- res = ast_waitstream(chan, ecodes);
-#ifdef ODBC_STORAGE
- if (success == -1) {
- /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
- if (option_debug)
- ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
- store_file(filename, vmu->mailbox, vmu->context, -1);
- }
-#endif
- }
- DISPOSE(filename, -1);
-
- return res;
-}
-
-static int invent_message(struct ast_channel *chan, struct ast_vm_user *vmu, char *ext, int busy, char *ecodes)
-{
- int res;
- char fn[PATH_MAX];
- char dest[PATH_MAX];
-
- snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
-
- if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
- ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
- return -1;
- }
-
- res = play_greeting(chan, vmu, fn, ecodes);
- if (res == -2) {
- /* File did not exist */
- res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
- if (res)
- return res;
- res = ast_say_digit_str(chan, ext, ecodes, chan->language);
- }
-
- if (res)
- return res;
-
- res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
- return res;
-}
-
-static void free_user(struct ast_vm_user *vmu)
-{
- if (ast_test_flag(vmu, VM_ALLOCED))
- free(vmu);
-}
-
-static void free_zone(struct vm_zone *z)
-{
- free(z);
-}
-
-static const char *mbox(int id)
-{
- static const char *msgs[] = {
- "INBOX",
- "Old",
- "Work",
- "Family",
- "Friends",
- "Cust1",
- "Cust2",
- "Cust3",
- "Cust4",
- "Cust5",
- };
- return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
-}
-#ifdef IMAP_STORAGE
-static int folder_int(const char *folder)
-{
- /*assume a NULL folder means INBOX*/
- if (!folder)
- return 0;
- if (!strcasecmp(folder, "INBOX"))
- return 0;
- else if (!strcasecmp(folder, "Old"))
- return 1;
- else if (!strcasecmp(folder, "Work"))
- return 2;
- else if (!strcasecmp(folder, "Family"))
- return 3;
- else if (!strcasecmp(folder, "Friends"))
- return 4;
- else if (!strcasecmp(folder, "Cust1"))
- return 5;
- else if (!strcasecmp(folder, "Cust2"))
- return 6;
- else if (!strcasecmp(folder, "Cust3"))
- return 7;
- else if (!strcasecmp(folder, "Cust4"))
- return 8;
- else if (!strcasecmp(folder, "Cust5"))
- return 9;
- else /*assume they meant INBOX if folder is not found otherwise*/
- return 0;
-}
-#endif
-
-#ifdef ODBC_STORAGE
-/*! XXX \todo Fix this function to support multiple mailboxes in the intput string */
-static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
-{
- int x = -1;
- int res;
- SQLHSTMT stmt;
- char sql[PATH_MAX];
- char rowdata[20];
- char tmp[PATH_MAX] = "";
- struct odbc_obj *obj;
- char *context;
- struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };
-
- if (newmsgs)
- *newmsgs = 0;
- if (oldmsgs)
- *oldmsgs = 0;
-
- /* If no mailbox, return immediately */
- if (ast_strlen_zero(mailbox))
- return 0;
-
- ast_copy_string(tmp, mailbox, sizeof(tmp));
-
- context = strchr(tmp, '@');
- if (context) {
- *context = '\0';
- context++;
- } else
- context = "default";
-
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "INBOX");
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLFetch(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- *newmsgs = atoi(rowdata);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-
- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "Old");
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLFetch(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- *oldmsgs = atoi(rowdata);
- x = 0;
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-
-yuck:
- return x;
-}
-
-static int messagecount(const char *context, const char *mailbox, const char *folder)
-{
- struct odbc_obj *obj = NULL;
- int nummsgs = 0;
- int res;
- SQLHSTMT stmt = NULL;
- char sql[PATH_MAX];
- char rowdata[20];
- struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };
- if (!folder)
- folder = "INBOX";
- /* If no mailbox, return immediately */
- if (ast_strlen_zero(mailbox))
- return 0;
-
- obj = ast_odbc_request_obj(odbc_database, 0);
- if (obj) {
- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder);
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
- goto yuck;
- }
- res = SQLFetch(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- goto yuck;
- }
- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- goto yuck;
- }
- nummsgs = atoi(rowdata);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- } else
- ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-
-yuck:
- if (obj)
- ast_odbc_release_obj(obj);
- return nummsgs;
-}
-
-static int has_voicemail(const char *mailbox, const char *folder)
-{
- char tmp[256], *tmp2 = tmp, *mbox, *context;
- ast_copy_string(tmp, mailbox, sizeof(tmp));
- while ((context = mbox = strsep(&tmp2, ","))) {
- strsep(&context, "@");
- if (ast_strlen_zero(context))
- context = "default";
- if (messagecount(context, mbox, folder))
- return 1;
- }
- return 0;
-}
-
-#elif defined(IMAP_STORAGE)
-
-static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms)
-{
- char *myserveremail = serveremail;
- char fn[PATH_MAX];
- char mailbox[256];
- char *stringp;
- FILE *p=NULL;
- char tmp[80] = "/tmp/astmail-XXXXXX";
- long len;
- void *buf;
- int tempcopy = 0;
- STRING str;
-
- /*Greetings are not retrieved from IMAP, so there is no reason to attempt storing them there either*/
- if (msgnum < 0)
- return 0;
-
- /* Attach only the first format */
- fmt = ast_strdupa(fmt);
- stringp = fmt;
- strsep(&stringp, "|");
-
- if (!ast_strlen_zero(vmu->serveremail))
- myserveremail = vmu->serveremail;
-
- make_file(fn, sizeof(fn), dir, msgnum);
-
- if (ast_strlen_zero(vmu->email)) {
- /*we need the vmu->email to be set when we call make_email_file, but if we keep it set,
- * a duplicate e-mail will be created. So at the end of this function, we will revert back to an empty
- * string if tempcopy is 1
- */
- ast_copy_string(vmu->email, vmu->imapuser, sizeof(vmu->email));
- tempcopy = 1;
- }
-
- if (!strcmp(fmt, "wav49"))
- fmt = "WAV";
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Storing file '%s', format '%s'\n", fn, fmt);
- /* Make a temporary file instead of piping directly to sendmail, in case the mail
- command hangs */
- if ((p = vm_mkftemp(tmp)) == NULL) {
- ast_log(LOG_WARNING, "Unable to store '%s' (can't create temporary file)\n", fn);
- if (tempcopy)
- *(vmu->email) = '\0';
- return -1;
- } else {
- make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), fn, fmt, duration, 1, chan, NULL, 1);
- /* read mail file to memory */
- len = ftell(p);
- rewind(p);
- if ((buf = ast_malloc(len+1)) == NIL) {
- ast_log(LOG_ERROR, "Can't allocate %ld bytes to read message\n", len+1);
- fclose(p);
- return -1;
- }
- fread(buf, len, 1, p);
- ((char *)buf)[len] = '\0';
- INIT(&str, mail_string, buf, len);
- init_mailstream(vms, 0);
- imap_mailbox_name(mailbox, sizeof(mailbox), vms, 0, 1);
- if (!mail_append(vms->mailstream, mailbox, &str))
- ast_log(LOG_ERROR, "Error while sending the message to %s\n", mailbox);
- fclose(p);
- unlink(tmp);
- ast_free(buf);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "%s stored\n", fn);
- }
- if (tempcopy)
- *(vmu->email) = '\0';
- return 0;
-
-}
-
-static int messagecount(const char *context, const char *mailbox, const char *folder)
-{
- SEARCHPGM *pgm;
- SEARCHHEADER *hdr;
-
- struct ast_vm_user *vmu, vmus;
- struct vm_state *vms_p;
- int ret = 0;
- int fold = folder_int(folder);
-
- if (ast_strlen_zero(mailbox))
- return 0;
-
- /* We have to get the user before we can open the stream! */
- /* ast_log (LOG_DEBUG,"Before find_user, context is %s and mailbox is %s\n",context,mailbox); */
- vmu = find_user(&vmus, context, mailbox);
- if (!vmu) {
- ast_log (LOG_ERROR,"Couldn't find mailbox %s in context %s\n",mailbox,context);
- return -1;
- } else {
- /* No IMAP account available */
- if (vmu->imapuser[0] == '\0') {
- ast_log (LOG_WARNING,"IMAP user not set for mailbox %s\n",vmu->mailbox);
- return -1;
- }
- }
-
- /* check if someone is accessing this box right now... */
- vms_p = get_vm_state_by_imapuser(vmu->imapuser,1);
- if (!vms_p) {
- vms_p = get_vm_state_by_mailbox(mailbox,1);
- }
- if (vms_p) {
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Returning before search - user is logged in\n");
- if (fold == 0) {/*INBOX*/
- return vms_p->newmessages;
- }
- if (fold == 1) {/*Old messages*/
- return vms_p->oldmessages;
- }
- }
-
- /* add one if not there... */
- vms_p = get_vm_state_by_imapuser(vmu->imapuser,0);
- if (!vms_p) {
- vms_p = get_vm_state_by_mailbox(mailbox,0);
- }
-
- if (!vms_p) {
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
- if (!(vms_p = ast_calloc(1, sizeof(*vms_p)))) {
- return -1;
- }
- ast_copy_string(vms_p->imapuser,vmu->imapuser, sizeof(vms_p->imapuser));
- ast_copy_string(vms_p->username, mailbox, sizeof(vms_p->username)); /* save for access from interactive entry point */
- vms_p->mailstream = NIL; /* save for access from interactive entry point */
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Copied %s to %s\n",vmu->imapuser,vms_p->imapuser);
- vms_p->updated = 1;
- /* set mailbox to INBOX! */
- ast_copy_string(vms_p->curbox, mbox(fold), sizeof(vms_p->curbox));
- init_vm_state(vms_p);
- vmstate_insert(vms_p);
- }
- ret = init_mailstream(vms_p, fold);
- if (!vms_p->mailstream) {
- ast_log (LOG_ERROR,"IMAP mailstream is NULL\n");
- return -1;
- }
- if (ret == 0) {
- pgm = mail_newsearchpgm ();
- hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)mailbox);
- pgm->header = hdr;
- if (fold != 1) {
- pgm->unseen = 1;
- pgm->seen = 0;
- }
- /* In the special case where fold is 1 (old messages) we have to do things a bit
- * differently. Old messages are stored in the INBOX but are marked as "seen"
- */
- else {
- pgm->unseen = 0;
- pgm->seen = 1;
- }
- pgm->undeleted = 1;
- pgm->deleted = 0;
-
- vms_p->vmArrayIndex = 0;
- mail_search_full (vms_p->mailstream, NULL, pgm, NIL);
- if (fold == 0)
- vms_p->newmessages = vms_p->vmArrayIndex;
- if (fold == 1)
- vms_p->oldmessages = vms_p->vmArrayIndex;
- /*Freeing the searchpgm also frees the searchhdr*/
- mail_free_searchpgm(&pgm);
- vms_p->updated = 0;
- return vms_p->vmArrayIndex;
- } else {
- mail_ping(vms_p->mailstream);
- }
- return 0;
-}
-static int inboxcount(const char *mailbox_context, int *newmsgs, int *oldmsgs)
-{
- char tmp[PATH_MAX] = "";
- char *mailboxnc;
- char *context;
- char *mb;
- char *cur;
- if (newmsgs)
- *newmsgs = 0;
- if (oldmsgs)
- *oldmsgs = 0;
-
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Mailbox is set to %s\n",mailbox_context);
- /* If no mailbox, return immediately */
- if (ast_strlen_zero(mailbox_context))
- return 0;
-
- ast_copy_string(tmp, mailbox_context, sizeof(tmp));
- context = strchr(tmp, '@');
- if (strchr(mailbox_context, ',')) {
- int tmpnew, tmpold;
- ast_copy_string(tmp, mailbox_context, sizeof(tmp));
- mb = tmp;
- while ((cur = strsep(&mb, ", "))) {
- if (!ast_strlen_zero(cur)) {
- if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
- return -1;
- else {
- if (newmsgs)
- *newmsgs += tmpnew;
- if (oldmsgs)
- *oldmsgs += tmpold;
- }
- }
- }
- return 0;
- }
- if (context) {
- *context = '\0';
- mailboxnc = tmp;
- context++;
- } else {
- context = "default";
- mailboxnc = (char *)mailbox_context;
- }
- if (newmsgs) {
- if ((*newmsgs = messagecount(context, mailboxnc, "INBOX")) < 0)
- return -1;
- }
- if (oldmsgs) {
- if ((*oldmsgs = messagecount(context, mailboxnc, "Old")) < 0)
- return -1;
- }
- return 0;
-}
-
-
-static int has_voicemail(const char *mailbox, const char *folder)
-{
- char tmp[256], *tmp2, *mbox, *context;
- ast_copy_string(tmp, mailbox, sizeof(tmp));
- tmp2 = tmp;
- if (strchr(tmp2, ',')) {
- while ((mbox = strsep(&tmp2, ","))) {
- if (!ast_strlen_zero(mbox)) {
- if (has_voicemail(mbox, folder))
- return 1;
- }
- }
- }
- if ((context= strchr(tmp, '@')))
- *context++ = '\0';
- else
- context = "default";
- return messagecount(context, tmp, folder) ? 1 : 0;
-}
-
-static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
-{
- struct vm_state *sendvms = NULL, *destvms = NULL;
- char messagestring[10]; /*I guess this could be a problem if someone has more than 999999999 messages...*/
- if (msgnum >= recip->maxmsg) {
- ast_log(LOG_WARNING, "Unable to copy mail, mailbox %s is full\n", recip->mailbox);
- return -1;
- }
- if (!(sendvms = get_vm_state_by_imapuser(vmu->imapuser, 0))) {
- ast_log(LOG_ERROR, "Couldn't get vm_state for originator's mailbox!!\n");
- return -1;
- }
- if (!(destvms = get_vm_state_by_imapuser(recip->imapuser, 0))) {
- ast_log(LOG_ERROR, "Couldn't get vm_state for destination mailbox!\n");
- return -1;
- }
- snprintf(messagestring, sizeof(messagestring), "%ld", sendvms->msgArray[msgnum]);
- if ((mail_copy(sendvms->mailstream, messagestring, (char *) mbox(imbox)) == T))
- return 0;
- ast_log(LOG_WARNING, "Unable to copy message from mailbox %s to mailbox %s\n", vmu->mailbox, recip->mailbox);
- return -1;
-}
-
-#endif
-#ifndef IMAP_STORAGE
-/* copy message only used by file storage */
-static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
-{
- char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
- const char *frombox = mbox(imbox);
- int recipmsgnum;
-
- ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
-
- create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
-
- if (!dir)
- make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
- else
- ast_copy_string(fromdir, dir, sizeof(fromdir));
-
- make_file(frompath, sizeof(frompath), fromdir, msgnum);
-
- if (vm_lock_path(todir))
- return ERROR_LOCK_PATH;
-
- recipmsgnum = 0;
- do {
- make_file(topath, sizeof(topath), todir, recipmsgnum);
- if (!EXISTS(todir, recipmsgnum, topath, chan->language))
- break;
- recipmsgnum++;
- } while (recipmsgnum < recip->maxmsg);
- if (recipmsgnum < recip->maxmsg) {
- COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
- } else {
- ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
- }
- ast_unlock_path(todir);
- notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
-
- return 0;
-}
-#endif
-#if !(defined(IMAP_STORAGE) || defined(ODBC_STORAGE))
-static int messagecount(const char *context, const char *mailbox, const char *folder)
-{
- return __has_voicemail(context, mailbox, folder, 0);
-}
-
-
-static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
-{
- DIR *dir;
- struct dirent *de;
- char fn[256];
- int ret = 0;
- if (!folder)
- folder = "INBOX";
- /* If no mailbox, return immediately */
- if (ast_strlen_zero(mailbox))
- return 0;
- if (!context)
- context = "default";
- snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
- dir = opendir(fn);
- if (!dir)
- return 0;
- while ((de = readdir(dir))) {
- if (!strncasecmp(de->d_name, "msg", 3)) {
- if (shortcircuit) {
- ret = 1;
- break;
- } else if (!strncasecmp(de->d_name + 8, "txt", 3))
- ret++;
- }
- }
- closedir(dir);
- return ret;
-}
-
-
-static int has_voicemail(const char *mailbox, const char *folder)
-{
- char tmp[256], *tmp2 = tmp, *mbox, *context;
- ast_copy_string(tmp, mailbox, sizeof(tmp));
- while ((mbox = strsep(&tmp2, ","))) {
- if ((context = strchr(mbox, '@')))
- *context++ = '\0';
- else
- context = "default";
- if (__has_voicemail(context, mbox, folder, 1))
- return 1;
- }
- return 0;
-}
-
-
-static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
-{
- char tmp[256];
- char *context;
-
- if (newmsgs)
- *newmsgs = 0;
- if (oldmsgs)
- *oldmsgs = 0;
- /* If no mailbox, return immediately */
- if (ast_strlen_zero(mailbox))
- return 0;
- if (strchr(mailbox, ',')) {
- int tmpnew, tmpold;
- char *mb, *cur;
-
- ast_copy_string(tmp, mailbox, sizeof(tmp));
- mb = tmp;
- while ((cur = strsep(&mb, ", "))) {
- if (!ast_strlen_zero(cur)) {
- if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
- return -1;
- else {
- if (newmsgs)
- *newmsgs += tmpnew;
- if (oldmsgs)
- *oldmsgs += tmpold;
- }
- }
- }
- return 0;
- }
- ast_copy_string(tmp, mailbox, sizeof(tmp));
- context = strchr(tmp, '@');
- if (context) {
- *context = '\0';
- context++;
- } else
- context = "default";
- if (newmsgs)
- *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
- if (oldmsgs)
- *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
- return 0;
-}
-
-#endif
-
-static void run_externnotify(char *context, char *extension)
-{
- char arguments[255];
- char ext_context[256] = "";
- int newvoicemails = 0, oldvoicemails = 0;
- struct ast_smdi_mwi_message *mwi_msg;
-
- if (!ast_strlen_zero(context))
- snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
- else
- ast_copy_string(ext_context, extension, sizeof(ext_context));
-
- if (!strcasecmp(externnotify, "smdi")) {
- if (ast_app_has_voicemail(ext_context, NULL))
- ast_smdi_mwi_set(smdi_iface, extension);
- else
- ast_smdi_mwi_unset(smdi_iface, extension);
-
- if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
- ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
- if (!strncmp(mwi_msg->cause, "INV", 3))
- ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
- else if (!strncmp(mwi_msg->cause, "BLK", 3))
- ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
- ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
- ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
- }
- } else if (!ast_strlen_zero(externnotify)) {
- if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
- ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
- } else {
- snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
- if (option_debug)
- ast_log(LOG_DEBUG, "Executing %s\n", arguments);
- ast_safe_system(arguments);
- }
- }
-}
-
-struct leave_vm_options {
- unsigned int flags;
- signed char record_gain;
-};
-
-static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
-{
-#ifdef IMAP_STORAGE
- int newmsgs, oldmsgs;
- struct vm_state *vms = NULL;
-#endif
- char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
- char callerid[256];
- FILE *txt;
- char date[256];
- int txtdes;
- int res = 0;
- int msgnum;
- int duration = 0;
- int ausemacro = 0;
- int ousemacro = 0;
- int ouseexten = 0;
- char dir[PATH_MAX], tmpdir[PATH_MAX];
- char dest[PATH_MAX];
- char fn[PATH_MAX];
- char prefile[PATH_MAX] = "";
- char tempfile[PATH_MAX] = "";
- char ext_context[256] = "";
- char fmt[80];
- char *context;
- char ecodes[16] = "#";
- char tmp[1024] = "", *tmpptr;
- struct ast_vm_user *vmu;
- struct ast_vm_user svm;
- const char *category = NULL;
-
- ast_copy_string(tmp, ext, sizeof(tmp));
- ext = tmp;
- context = strchr(tmp, '@');
- if (context) {
- *context++ = '\0';
- tmpptr = strchr(context, '&');
- } else {
- tmpptr = strchr(ext, '&');
- }
-
- if (tmpptr)
- *tmpptr++ = '\0';
-
- category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Before find_user\n");
- if (!(vmu = find_user(&svm, context, ext))) {
- ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
- if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- return res;
- }
- /* Setup pre-file if appropriate */
- if (strcmp(vmu->context, "default"))
- snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
- else
- ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
- if (ast_test_flag(options, OPT_BUSY_GREETING)) {
- res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
- snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
- } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
- res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
- snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
- }
- snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
- if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
- ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
- return -1;
- }
- RETRIEVE(tempfile, -1);
- if (ast_fileexists(tempfile, NULL, NULL) > 0)
- ast_copy_string(prefile, tempfile, sizeof(prefile));
- DISPOSE(tempfile, -1);
- /* It's easier just to try to make it than to check for its existence */
- create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
- create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
-
- /* Check current or macro-calling context for special extensions */
- if (ast_test_flag(vmu, VM_OPERATOR)) {
- if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ouseexten = 1;
- }
- } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ouseexten = 1;
- }
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ousemacro = 1;
- }
- }
-
- if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- ausemacro = 1;
- }
-
- /* Play the beginning intro if desired */
- if (!ast_strlen_zero(prefile)) {
- res = play_greeting(chan, vmu, prefile, ecodes);
- if (res == -2) {
- /* The file did not exist */
- if (option_debug)
- ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
- res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
- }
- if (res < 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- return -1;
- }
- }
- if (res == '#') {
- /* On a '#' we skip the instructions */
- ast_set_flag(options, OPT_SILENT);
- res = 0;
- }
- if (!res && !ast_test_flag(options, OPT_SILENT)) {
- res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
- if (res == '#') {
- ast_set_flag(options, OPT_SILENT);
- res = 0;
- }
- }
- if (res > 0)
- ast_stopstream(chan);
- /* Check for a '*' here in case the caller wants to escape from voicemail to something
- other than the operator -- an automated attendant or mailbox login for example */
- if (res == '*') {
- chan->exten[0] = 'a';
- chan->exten[1] = '\0';
- if (!ast_strlen_zero(vmu->exit)) {
- ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
- } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
- ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
- }
- chan->priority = 0;
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- return 0;
- }
-
- /* Check for a '0' here */
- if (res == '0') {
- transfer:
- if (ouseexten || ousemacro) {
- chan->exten[0] = 'o';
- chan->exten[1] = '\0';
- if (!ast_strlen_zero(vmu->exit)) {
- ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
- } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
- ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
- }
- ast_play_and_wait(chan, "transfer");
- chan->priority = 0;
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- }
- return 0;
- }
- if (res < 0) {
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- return -1;
- }
- /* The meat of recording the message... All the announcements and beeps have been played*/
- ast_copy_string(fmt, vmfmts, sizeof(fmt));
- if (!ast_strlen_zero(fmt)) {
- msgnum = 0;
-
-#ifdef IMAP_STORAGE
- /* Is ext a mailbox? */
- /* must open stream for this user to get info! */
- res = inboxcount(ext_context, &newmsgs, &oldmsgs);
- if (res < 0) {
- ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
- return -1;
- }
- if (!(vms = get_vm_state_by_mailbox(ext,0))) {
- /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
- * rarely be used*/
- if (!(vms = ast_calloc(1, sizeof(*vms)))) {
- ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
- return -1;
- }
- ast_copy_string(vms->imapuser, vmu->imapuser, sizeof(vms->imapuser));
- ast_copy_string(vms->username, ext, sizeof(vms->username));
- vms->mailstream = NIL;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Copied %s to %s\n", vmu->imapuser, vms->imapuser);
- vms->updated=1;
- ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
- init_vm_state(vms);
- vmstate_insert(vms);
- vms = get_vm_state_by_mailbox(ext,0);
- }
- vms->newmessages++;
- /* here is a big difference! We add one to it later */
- msgnum = newmsgs + oldmsgs;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
- snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
- /* set variable for compatability */
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
-
- /* Check if mailbox is full */
- check_quota(vms, imapfolder);
- if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
- if (option_debug)
- ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
- ast_play_and_wait(chan, "vm-mailboxfull");
- return -1;
- }
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
- if (msgnum >= vmu->maxmsg) {
- res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- ast_log(LOG_WARNING, "No more messages possible\n");
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- goto leave_vm_out;
- }
-
- /* Check if we have exceeded maxmsg */
- if (msgnum >= vmu->maxmsg) {
- ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
- ast_play_and_wait(chan, "vm-mailboxfull");
- return -1;
- }
- /* here is a big difference! We add one to it later */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
-#else
- if (count_messages(vmu, dir) >= vmu->maxmsg) {
- res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- ast_log(LOG_WARNING, "No more messages possible\n");
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- goto leave_vm_out;
- }
-
-#endif
- snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
- txtdes = mkstemp(tmptxtfile);
- chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
- if (txtdes < 0) {
- res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- goto leave_vm_out;
- }
-
- /* Now play the beep once we have the message number for our next message. */
- if (res >= 0) {
- /* Unless we're *really* silent, try to send the beep */
- res = ast_stream_and_wait(chan, "beep", chan->language, "");
- }
-
- /* Store information */
- txt = fdopen(txtdes, "w+");
- if (txt) {
- get_date(date, sizeof(date));
- fprintf(txt,
- ";\n"
- "; Message Information file\n"
- ";\n"
- "[message]\n"
- "origmailbox=%s\n"
- "context=%s\n"
- "macrocontext=%s\n"
- "exten=%s\n"
- "priority=%d\n"
- "callerchan=%s\n"
- "callerid=%s\n"
- "origdate=%s\n"
- "origtime=%ld\n"
- "category=%s\n",
- ext,
- chan->context,
- chan->macrocontext,
- chan->exten,
- chan->priority,
- chan->name,
- ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
- date, (long)time(NULL),
- category ? category : "");
- } else
- ast_log(LOG_WARNING, "Error opening text file for output\n");
-#ifdef IMAP_STORAGE
- res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
-#else
- res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, NULL);
-#endif
-
- if (txt) {
- if (duration < vmminmessage) {
- fclose(txt);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
- ast_filedelete(tmptxtfile, NULL);
- unlink(tmptxtfile);
- } else {
- fprintf(txt, "duration=%d\n", duration);
- fclose(txt);
- if (vm_lock_path(dir)) {
- ast_log(LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir);
- /* Delete files */
- ast_filedelete(tmptxtfile, NULL);
- unlink(tmptxtfile);
- } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
- unlink(tmptxtfile);
- ast_unlock_path(dir);
- } else {
- for (;;) {
- make_file(fn, sizeof(fn), dir, msgnum);
- if (!EXISTS(dir, msgnum, fn, NULL))
- break;
- msgnum++;
- }
-
- /* assign a variable with the name of the voicemail file */
-#ifndef IMAP_STORAGE
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
-#else
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
-#endif
-
- snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
- ast_filerename(tmptxtfile, fn, NULL);
- rename(tmptxtfile, txtfile);
-
- ast_unlock_path(dir);
- /* We must store the file first, before copying the message, because
- * ODBC storage does the entire copy with SQL.
- */
- if (ast_fileexists(fn, NULL, NULL) > 0) {
- STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
- }
-
- /* Are there to be more recipients of this message? */
- while (tmpptr) {
- struct ast_vm_user recipu, *recip;
- char *exten, *context;
-
- exten = strsep(&tmpptr, "&");
- context = strchr(exten, '@');
- if (context) {
- *context = '\0';
- context++;
- }
- if ((recip = find_user(&recipu, context, exten))) {
- copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
- free_user(recip);
- }
- }
- /* Notification and disposal needs to happen after the copy, though. */
- if (ast_fileexists(fn, NULL, NULL)) {
- notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
- DISPOSE(dir, msgnum);
- }
- }
- }
- }
- if (res == '0') {
- goto transfer;
- } else if (res > 0)
- res = 0;
-
- if (duration < vmminmessage)
- /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- else
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
- } else
- ast_log(LOG_WARNING, "No format for saving voicemail?\n");
-leave_vm_out:
- free_user(vmu);
-
- return res;
-}
-
-#ifndef IMAP_STORAGE
-static int resequence_mailbox(struct ast_vm_user *vmu, char *dir)
-{
- /* we know max messages, so stop process when number is hit */
-
- int x,dest;
- char sfn[PATH_MAX];
- char dfn[PATH_MAX];
-
- if (vm_lock_path(dir))
- return ERROR_LOCK_PATH;
-
- for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
- make_file(sfn, sizeof(sfn), dir, x);
- if (EXISTS(dir, x, sfn, NULL)) {
-
- if (x != dest) {
- make_file(dfn, sizeof(dfn), dir, dest);
- RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
- }
-
- dest++;
- }
- }
- ast_unlock_path(dir);
-
- return 0;
-}
-#endif
-
-static int say_and_wait(struct ast_channel *chan, int num, const char *language)
-{
- int d;
- d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
- return d;
-}
-
-static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
-{
-#ifdef IMAP_STORAGE
- /* we must use mbox(x) folder names, and copy the message there */
- /* simple. huh? */
- long res;
- char sequence[10];
-
- /* if save to Old folder, just leave in INBOX */
- if (box == 1) return 10;
- /* get the real IMAP message number for this message */
- snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
- res = mail_copy(vms->mailstream,sequence,(char *) mbox(box));
- if (res == 1) return 0;
- return 1;
-#else
- char *dir = vms->curdir;
- char *username = vms->username;
- char *context = vmu->context;
- char sfn[PATH_MAX];
- char dfn[PATH_MAX];
- char ddir[PATH_MAX];
- const char *dbox = mbox(box);
- int x;
- make_file(sfn, sizeof(sfn), dir, msg);
- create_dirpath(ddir, sizeof(ddir), context, username, dbox);
-
- if (vm_lock_path(ddir))
- return ERROR_LOCK_PATH;
-
- for (x = 0; x < vmu->maxmsg; x++) {
- make_file(dfn, sizeof(dfn), ddir, x);
- if (!EXISTS(ddir, x, dfn, NULL))
- break;
- }
- if (x >= vmu->maxmsg) {
- ast_unlock_path(ddir);
- return ERROR_MAILBOX_FULL;
- }
- if (strcmp(sfn, dfn)) {
- COPY(dir, msg, ddir, x, username, context, sfn, dfn);
- }
- ast_unlock_path(ddir);
-#endif
- return 0;
-}
-
-static int adsi_logo(unsigned char *buf)
-{
- int bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
- return bytes;
-}
-
-static int adsi_load_vmail(struct ast_channel *chan, int *useadsi)
-{
- unsigned char buf[256];
- int bytes=0;
- int x;
- char num[5];
-
- *useadsi = 0;
- bytes += ast_adsi_data_mode(buf + bytes);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-
- bytes = 0;
- bytes += adsi_logo(buf);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
-#ifdef DISPLAY
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", "");
-#endif
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_data_mode(buf + bytes);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-
- if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
- bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
- return 0;
- }
-
-#ifdef DISPLAY
- /* Add a dot */
- bytes = 0;
- bytes += ast_adsi_logo(buf);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-#endif
- bytes = 0;
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
-
-#ifdef DISPLAY
- /* Add another dot */
- bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", "");
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-#endif
-
- bytes = 0;
- /* These buttons we load but don't use yet */
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
-
-#ifdef DISPLAY
- /* Add another dot */
- bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-#endif
-
- bytes = 0;
- for (x=0;x<5;x++) {
- snprintf(num, sizeof(num), "%d", x);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
- }
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
-
-#ifdef DISPLAY
- /* Add another dot */
- bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-#endif
-
- if (ast_adsi_end_download(chan)) {
- bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
- return 0;
- }
- bytes = 0;
- bytes += ast_adsi_download_disconnect(buf + bytes);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Done downloading scripts...\n");
-
-#ifdef DISPLAY
- /* Add last dot */
- bytes = 0;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
-#endif
- if (option_debug)
- ast_log(LOG_DEBUG, "Restarting session...\n");
-
- bytes = 0;
- /* Load the session now */
- if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
- *useadsi = 1;
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
- } else
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
- return 0;
-}
-
-static void adsi_begin(struct ast_channel *chan, int *useadsi)
-{
- int x;
- if (!ast_adsi_available(chan))
- return;
- x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
- if (x < 0)
- return;
- if (!x) {
- if (adsi_load_vmail(chan, useadsi)) {
- ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
- return;
- }
- } else
- *useadsi = 1;
-}
-
-static void adsi_login(struct ast_channel *chan)
-{
- unsigned char buf[256];
- int bytes=0;
- unsigned char keys[8];
- int x;
- if (!ast_adsi_available(chan))
- return;
-
- for (x=0;x<8;x++)
- keys[x] = 0;
- /* Set one key for next */
- keys[3] = ADSI_KEY_APPS + 3;
-
- bytes += adsi_logo(buf + bytes);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
- bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
- bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
- bytes += ast_adsi_set_keys(buf + bytes, keys);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-static void adsi_password(struct ast_channel *chan)
-{
- unsigned char buf[256];
- int bytes=0;
- unsigned char keys[8];
- int x;
- if (!ast_adsi_available(chan))
- return;
-
- for (x=0;x<8;x++)
- keys[x] = 0;
- /* Set one key for next */
- keys[3] = ADSI_KEY_APPS + 3;
-
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
- bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
- bytes += ast_adsi_set_keys(buf + bytes, keys);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-static void adsi_folders(struct ast_channel *chan, int start, char *label)
-{
- unsigned char buf[256];
- int bytes=0;
- unsigned char keys[8];
- int x,y;
-
- if (!ast_adsi_available(chan))
- return;
-
- for (x=0;x<5;x++) {
- y = ADSI_KEY_APPS + 12 + start + x;
- if (y > ADSI_KEY_APPS + 12 + 4)
- y = 0;
- keys[x] = ADSI_KEY_SKT | y;
- }
- keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
- keys[6] = 0;
- keys[7] = 0;
-
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_set_keys(buf + bytes, keys);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-static void adsi_message(struct ast_channel *chan, struct vm_state *vms)
-{
- int bytes=0;
- unsigned char buf[256];
- char buf1[256], buf2[256];
- char fn2[PATH_MAX];
-
- char cid[256]="";
- char *val;
- char *name, *num;
- char datetime[21]="";
- FILE *f;
-
- unsigned char keys[8];
-
- int x;
-
- if (!ast_adsi_available(chan))
- return;
-
- /* Retrieve important info */
- snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
- f = fopen(fn2, "r");
- if (f) {
- while (!feof(f)) {
- fgets((char *)buf, sizeof(buf), f);
- if (!feof(f)) {
- char *stringp=NULL;
- stringp = (char *)buf;
- strsep(&stringp, "=");
- val = strsep(&stringp, "=");
- if (!ast_strlen_zero(val)) {
- if (!strcmp((char *)buf, "callerid"))
- ast_copy_string(cid, val, sizeof(cid));
- if (!strcmp((char *)buf, "origdate"))
- ast_copy_string(datetime, val, sizeof(datetime));
- }
- }
- }
- fclose(f);
- }
- /* New meaning for keys */
- for (x=0;x<5;x++)
- keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
- keys[6] = 0x0;
- keys[7] = 0x0;
-
- if (!vms->curmsg) {
- /* No prev key, provide "Folder" instead */
- keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
- }
- if (vms->curmsg >= vms->lastmsg) {
- /* If last message ... */
- if (vms->curmsg) {
- /* but not only message, provide "Folder" instead */
- keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- } else {
- /* Otherwise if only message, leave blank */
- keys[3] = 1;
- }
- }
-
- if (!ast_strlen_zero(cid)) {
- ast_callerid_parse(cid, &name, &num);
- if (!name)
- name = num;
- } else
- name = "Unknown Caller";
-
- /* If deleted, show "undeleted" */
-
- if (vms->deleted[vms->curmsg])
- keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
-
- /* Except "Exit" */
- keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
- snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
- strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
- snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
-
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_set_keys(buf + bytes, keys);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-static void adsi_delete(struct ast_channel *chan, struct vm_state *vms)
-{
- int bytes=0;
- unsigned char buf[256];
- unsigned char keys[8];
-
- int x;
-
- if (!ast_adsi_available(chan))
- return;
-
- /* New meaning for keys */
- for (x=0;x<5;x++)
- keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
-
- keys[6] = 0x0;
- keys[7] = 0x0;
-
- if (!vms->curmsg) {
- /* No prev key, provide "Folder" instead */
- keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
- }
- if (vms->curmsg >= vms->lastmsg) {
- /* If last message ... */
- if (vms->curmsg) {
- /* but not only message, provide "Folder" instead */
- keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
- } else {
- /* Otherwise if only message, leave blank */
- keys[3] = 1;
- }
- }
-
- /* If deleted, show "undeleted" */
- if (vms->deleted[vms->curmsg])
- keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
-
- /* Except "Exit" */
- keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
- bytes += ast_adsi_set_keys(buf + bytes, keys);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-static void adsi_status(struct ast_channel *chan, struct vm_state *vms)
-{
- unsigned char buf[256] = "";
- char buf1[256] = "", buf2[256] = "";
- int bytes=0;
- unsigned char keys[8];
- int x;
-
- char *newm = (vms->newmessages == 1) ? "message" : "messages";
- char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
- if (!ast_adsi_available(chan))
- return;
- if (vms->newmessages) {
- snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
- if (vms->oldmessages) {
- strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
- snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
- } else {
- snprintf(buf2, sizeof(buf2), "%s.", newm);
- }
- } else if (vms->oldmessages) {
- snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
- snprintf(buf2, sizeof(buf2), "%s.", oldm);
- } else {
- strcpy(buf1, "You have no messages.");
- buf2[0] = ' ';
- buf2[1] = '\0';
- }
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
-
- for (x=0;x<6;x++)
- keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
- keys[6] = 0;
- keys[7] = 0;
-
- /* Don't let them listen if there are none */
- if (vms->lastmsg < 0)
- keys[0] = 1;
- bytes += ast_adsi_set_keys(buf + bytes, keys);
-
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-static void adsi_status2(struct ast_channel *chan, struct vm_state *vms)
-{
- unsigned char buf[256] = "";
- char buf1[256] = "", buf2[256] = "";
- int bytes=0;
- unsigned char keys[8];
- int x;
-
- char *mess = (vms->lastmsg == 0) ? "message" : "messages";
-
- if (!ast_adsi_available(chan))
- return;
-
- /* Original command keys */
- for (x=0;x<6;x++)
- keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
-
- keys[6] = 0;
- keys[7] = 0;
-
- if ((vms->lastmsg + 1) < 1)
- keys[0] = 0;
-
- snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
- strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
-
- if (vms->lastmsg + 1)
- snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
- else
- strcpy(buf2, "no messages.");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_set_keys(buf + bytes, keys);
-
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-
-}
-
-/*
-static void adsi_clear(struct ast_channel *chan)
-{
- char buf[256];
- int bytes=0;
- if (!ast_adsi_available(chan))
- return;
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-*/
-
-static void adsi_goodbye(struct ast_channel *chan)
-{
- unsigned char buf[256];
- int bytes=0;
-
- if (!ast_adsi_available(chan))
- return;
- bytes += adsi_logo(buf + bytes);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
-
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
-}
-
-/*--- get_folder: Folder menu ---*/
-/* Plays "press 1 for INBOX messages" etc
- Should possibly be internationalized
- */
-static int get_folder(struct ast_channel *chan, int start)
-{
- int x;
- int d;
- char fn[PATH_MAX];
- d = ast_play_and_wait(chan, "vm-press"); /* "Press" */
- if (d)
- return d;
- for (x = start; x< 5; x++) { /* For all folders */
- if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
- return d;
- d = ast_play_and_wait(chan, "vm-for"); /* "for" */
- if (d)
- return d;
- snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */
- d = vm_play_folder_name(chan, fn);
- if (d)
- return d;
- d = ast_waitfordigit(chan, 500);
- if (d)
- return d;
- }
- d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
- if (d)
- return d;
- d = ast_waitfordigit(chan, 4000);
- return d;
-}
-
-static int get_folder2(struct ast_channel *chan, char *fn, int start)
-{
- int res = 0;
- res = ast_play_and_wait(chan, fn); /* Folder name */
- while (((res < '0') || (res > '9')) &&
- (res != '#') && (res >= 0)) {
- res = get_folder(chan, 0);
- }
- return res;
-}
-
-static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts,
- char *context, signed char record_gain, long *duration, struct vm_state *vms)
-{
- int cmd = 0;
- int retries = 0, prepend_duration = 0, already_recorded = 0;
- signed char zero_gain = 0;
- struct ast_config *msg_cfg;
- const char *duration_str;
- char msgfile[PATH_MAX], backup[PATH_MAX];
- char textfile[PATH_MAX];
-
- /* Must always populate duration correctly */
- make_file(msgfile, sizeof(msgfile), curdir, curmsg);
- strcpy(textfile, msgfile);
- strcpy(backup, msgfile);
- strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
- strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
-
- if (!(msg_cfg = ast_config_load(textfile))) {
- return -1;
- }
-
- *duration = 0;
- if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
- *duration = atoi(duration_str);
-
- while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
- if (cmd)
- retries = 0;
- switch (cmd) {
- case '1':
- /* prepend a message to the current message, update the metadata and return */
- {
- prepend_duration = 0;
-
- /* if we can't read the message metadata, stop now */
- if (!msg_cfg) {
- cmd = 0;
- break;
- }
-
- /* Back up the original file, so we can retry the prepend */
- if (already_recorded)
- ast_filecopy(backup, msgfile, NULL);
- else
- ast_filecopy(msgfile, backup, NULL);
- already_recorded = 1;
-
- if (record_gain)
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
-
- cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
- if (record_gain)
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
-
- if (prepend_duration) {
- struct ast_category *msg_cat;
- /* need enough space for a maximum-length message duration */
- char duration_str[12];
-
- prepend_duration += *duration;
- msg_cat = ast_category_get(msg_cfg, "message");
- snprintf(duration_str, 11, "%d", prepend_duration);
- if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
- config_text_file_save(textfile, msg_cfg, "app_voicemail");
- STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, prepend_duration, vms);
- }
- }
-
- break;
- }
- case '2':
- cmd = 't';
- break;
- case '*':
- cmd = '*';
- break;
- default:
- cmd = ast_play_and_wait(chan,"vm-forwardoptions");
- /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
- if (!cmd)
- cmd = ast_play_and_wait(chan,"vm-starmain");
- /* "press star to return to the main menu" */
- if (!cmd)
- cmd = ast_waitfordigit(chan,6000);
- if (!cmd)
- retries++;
- if (retries > 3)
- cmd = 't';
- }
- }
-
- ast_config_destroy(msg_cfg);
- if (already_recorded)
- ast_filedelete(backup, NULL);
- if (prepend_duration)
- *duration = prepend_duration;
-
- if (cmd == 't' || cmd == 'S')
- cmd = 0;
- return cmd;
-}
-
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
-{
- char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
- int newmsgs = 0, oldmsgs = 0;
- const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
-
- make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
- make_file(fn, sizeof(fn), todir, msgnum);
- snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
-
- if (!ast_strlen_zero(vmu->attachfmt)) {
- if (strstr(fmt, vmu->attachfmt)) {
- fmt = vmu->attachfmt;
- } else {
- ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'. Falling back to default format for '%s@%s'.\n", vmu->attachfmt, fmt, vmu->mailbox, vmu->context);
- }
- }
-
- /* Attach only the first format */
- fmt = ast_strdupa(fmt);
- stringp = fmt;
- strsep(&stringp, "|");
-
- if (!ast_strlen_zero(vmu->email)) {
- int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
- char *myserveremail = serveremail;
- attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
- if (!ast_strlen_zero(vmu->serveremail))
- myserveremail = vmu->serveremail;
-
- if (attach_user_voicemail)
- RETRIEVE(todir, msgnum);
-
- /*XXX possible imap issue, should category be NULL XXX*/
- sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
-
- if (attach_user_voicemail)
- DISPOSE(todir, msgnum);
- }
-
- if (!ast_strlen_zero(vmu->pager)) {
- char *myserveremail = serveremail;
- if (!ast_strlen_zero(vmu->serveremail))
- myserveremail = vmu->serveremail;
- sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
- }
-
- if (ast_test_flag(vmu, VM_DELETE)) {
- DELETE(todir, msgnum, fn);
- }
-
-#ifdef IMAP_STORAGE
- DELETE(todir, msgnum, fn);
-#endif
- /* Leave voicemail for someone */
- if (ast_app_has_voicemail(ext_context, NULL)) {
- ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
- }
- manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
- run_externnotify(vmu->context, vmu->mailbox);
- return 0;
-}
-
-static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
-{
-#ifdef IMAP_STORAGE
- BODY *body;
- char *header_content;
- char *temp;
- char todir[256];
- int todircount=0;
- struct vm_state *dstvms;
-#endif
- char username[70]="";
- int res = 0, cmd = 0;
- struct ast_vm_user *receiver = NULL, *vmtmp;
- AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
- char *stringp;
- const char *s;
- int saved_messages = 0, found = 0;
- int valid_extensions = 0;
- char *dir;
- int curmsg;
-
- if (vms == NULL) return -1;
- dir = vms->curdir;
- curmsg = vms->curmsg;
-
- while (!res && !valid_extensions) {
- int use_directory = 0;
- if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
- int done = 0;
- int retries = 0;
- cmd=0;
- while ((cmd >= 0) && !done ){
- if (cmd)
- retries = 0;
- switch (cmd) {
- case '1':
- use_directory = 0;
- done = 1;
- break;
- case '2':
- use_directory = 1;
- done=1;
- break;
- case '*':
- cmd = 't';
- done = 1;
- break;
- default:
- /* Press 1 to enter an extension press 2 to use the directory */
- cmd = ast_play_and_wait(chan,"vm-forward");
- if (!cmd)
- cmd = ast_waitfordigit(chan,3000);
- if (!cmd)
- retries++;
- if (retries > 3)
- {
- cmd = 't';
- done = 1;
- }
-
- }
- }
- if (cmd < 0 || cmd == 't')
- break;
- }
-
- if (use_directory) {
- /* use app_directory */
-
- char old_context[sizeof(chan->context)];
- char old_exten[sizeof(chan->exten)];
- int old_priority;
- struct ast_app* app;
-
-
- app = pbx_findapp("Directory");
- if (app) {
- char vmcontext[256];
- /* make backup copies */
- memcpy(old_context, chan->context, sizeof(chan->context));
- memcpy(old_exten, chan->exten, sizeof(chan->exten));
- old_priority = chan->priority;
-
- /* call the the Directory, changes the channel */
- snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
- res = pbx_exec(chan, app, vmcontext);
-
- ast_copy_string(username, chan->exten, sizeof(username));
-
- /* restore the old context, exten, and priority */
- memcpy(chan->context, old_context, sizeof(chan->context));
- memcpy(chan->exten, old_exten, sizeof(chan->exten));
- chan->priority = old_priority;
-
- } else {
- ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
- ast_clear_flag((&globalflags), VM_DIRECFORWARD);
- }
- } else {
- /* Ask for an extension */
- res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
- if (res)
- break;
- if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
- break;
- }
-
- /* start all over if no username */
- if (ast_strlen_zero(username))
- continue;
- stringp = username;
- s = strsep(&stringp, "*");
- /* start optimistic */
- valid_extensions = 1;
- while (s) {
- /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1). find_user is going to malloc since we have a NULL as first argument */
- if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
- AST_LIST_INSERT_HEAD(&extensions, receiver, list);
- found++;
- } else {
- valid_extensions = 0;
- break;
- }
- s = strsep(&stringp, "*");
- }
- /* break from the loop of reading the extensions */
- if (valid_extensions)
- break;
- /* "I am sorry, that's not a valid extension. Please try again." */
- res = ast_play_and_wait(chan, "pbx-invalid");
- }
- /* check if we're clear to proceed */
- if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
- return res;
- if (flag==1) {
- struct leave_vm_options leave_options;
- char mailbox[AST_MAX_EXTENSION * 2 + 2];
- /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
- if (context)
- snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
- else
- ast_copy_string(mailbox, username, sizeof(mailbox));
-
- /* Send VoiceMail */
- memset(&leave_options, 0, sizeof(leave_options));
- leave_options.record_gain = record_gain;
- cmd = leave_voicemail(chan, mailbox, &leave_options);
- } else {
- /* Forward VoiceMail */
- long duration = 0;
- char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
- struct vm_state vmstmp;
-
- memcpy(&vmstmp, vms, sizeof(vmstmp));
-
- make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
- create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
- make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
-
- RETRIEVE(dir, curmsg);
-
- /* Alter a surrogate file, only */
- copy_plain_file(origmsgfile, msgfile);
-
- cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
- if (!cmd) {
- AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
-#ifdef IMAP_STORAGE
- char *myserveremail;
- int attach_user_voicemail;
- /* Need to get message content */
- if (option_debug > 2)
- ast_log (LOG_DEBUG, "Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n", vms->curmsg, vms->msgArray[vms->curmsg]);
- if (vms->msgArray[vms->curmsg] == 0) {
- ast_log (LOG_WARNING,"Trying to access unknown message\n");
- return -1;
- }
-
- /* This will only work for new messages... */
- header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
- /* empty string means no valid header */
- if (ast_strlen_zero(header_content)) {
- ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
- return -1;
- }
- /* Get header info needed by sendmail */
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
- if (temp)
- duration = atoi(temp);
- else
- duration = 0;
-
- /* Attach only the first format */
- fmt = ast_strdupa(fmt);
- if (fmt) {
- stringp = fmt;
- strsep(&stringp, "|");
- } else {
- ast_log (LOG_ERROR,"audio format not set. Default to WAV\n");
- fmt = "WAV";
- }
- if (!strcasecmp(fmt, "wav49"))
- fmt = "WAV";
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"**** format set to %s, vmfmts set to %s\n",fmt,vmfmts);
- /* ast_copy_string(fmt, vmfmts, sizeof(fmt));*/
- /* if (!ast_strlen_zero(fmt)) { */
- snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
- make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
- /*mail_fetchstructure (mailstream, vmArray[0], &body); */
- mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
- save_body(body,vms,"3","gsm");
- /* should not assume "fmt" here! */
- save_body(body,vms,"2",fmt);
-
- /* get destination mailbox */
- dstvms = get_vm_state_by_mailbox(vmtmp->mailbox,0);
- if (dstvms) {
- init_mailstream(dstvms, 0);
- if (!dstvms->mailstream) {
- ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
- } else {
- STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
- run_externnotify(vmtmp->context, vmtmp->mailbox);
- }
- } else {
- ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
- }
-
- myserveremail = serveremail;
- if (!ast_strlen_zero(vmtmp->serveremail))
- myserveremail = vmtmp->serveremail;
- attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
- attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
- /* NULL category for IMAP storage */
- sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
-#else
- copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
-#endif
- saved_messages++;
- AST_LIST_REMOVE_CURRENT(&extensions, list);
- free_user(vmtmp);
- if (res)
- break;
- }
- AST_LIST_TRAVERSE_SAFE_END;
- if (saved_messages > 0) {
- /* give confirmation that the message was saved */
- /* commented out since we can't forward batches yet
- if (saved_messages == 1)
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-saved"); */
- res = ast_play_and_wait(chan, "vm-msgsaved");
- }
- }
-
- /* Remove surrogate file */
- vm_delete(msgfile);
- }
-
- /* If anything failed above, we still have this list to free */
- while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
- free_user(vmtmp);
- return res ? res : cmd;
-}
-
-static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
-{
- int res;
- if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0)
- ast_log(LOG_WARNING, "Unable to play message %s\n", file);
- return res;
-}
-
-static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file)
-{
- return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
-}
-
-static int play_message_category(struct ast_channel *chan, const char *category)
-{
- int res = 0;
-
- if (!ast_strlen_zero(category))
- res = ast_play_and_wait(chan, category);
-
- if (res) {
- ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
- res = 0;
- }
-
- return res;
-}
-
-static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
-{
- int res = 0;
- struct vm_zone *the_zone = NULL;
- time_t t;
-
- if (ast_get_time_t(origtime, &t, 0, NULL)) {
- ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
- return 0;
- }
-
- /* Does this user have a timezone specified? */
- if (!ast_strlen_zero(vmu->zonetag)) {
- /* Find the zone in the list */
- struct vm_zone *z;
- AST_LIST_LOCK(&zones);
- AST_LIST_TRAVERSE(&zones, z, list) {
- if (!strcmp(z->name, vmu->zonetag)) {
- the_zone = z;
- break;
- }
- }
- AST_LIST_UNLOCK(&zones);
- }
-
-/* No internal variable parsing for now, so we'll comment it out for the time being */
-#if 0
- /* Set the DIFF_* variables */
- ast_localtime(&t, &time_now, NULL);
- tv_now = ast_tvnow();
- tnow = tv_now.tv_sec;
- ast_localtime(&tnow, &time_then, NULL);
-
- /* Day difference */
- if (time_now.tm_year == time_then.tm_year)
- snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
- else
- snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
- pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
-
- /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
-#endif
- if (the_zone)
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
- else if (!strcasecmp(chan->language,"pl")) /* POLISH syntax */
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
- else if (!strcasecmp(chan->language,"se")) /* SWEDISH syntax */
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
- else if (!strcasecmp(chan->language,"no")) /* NORWEGIAN syntax */
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
- else if (!strcasecmp(chan->language,"de")) /* GERMAN syntax */
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
- else if (!strcasecmp(chan->language,"nl")) /* DUTCH syntax */
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
- else if (!strcasecmp(chan->language,"it")) /* ITALIAN syntax */
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
- else if (!strcasecmp(chan->language,"gr"))
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL);
- else if (!strcasecmp(chan->language,"pt_BR"))
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);
- else
- res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
-#if 0
- pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
-#endif
- return res;
-}
-
-
-
-static int play_message_callerid(struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
-{
- int res = 0;
- int i;
- char *callerid, *name;
- char prefile[PATH_MAX] = "";
-
-
- /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
- /* BB: Still need to change this so that if this function is called by the message envelope (and someone is explicitly requesting to hear the CID), it does not check to see if CID is enabled in the config file */
- if ((cid == NULL)||(context == NULL))
- return res;
-
- /* Strip off caller ID number from name */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
- ast_callerid_parse(cid, &name, &callerid);
- if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
- /* Check for internal contexts and only */
- /* say extension when the call didn't come from an internal context in the list */
- for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
- if ((strcmp(cidinternalcontexts[i], context) == 0))
- break;
- }
- if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
- if (!res) {
- snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
- if (!ast_strlen_zero(prefile)) {
- /* See if we can find a recorded name for this person instead of their extension number */
- if (ast_fileexists(prefile, NULL, NULL) > 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
- if (!callback)
- res = wait_file2(chan, vms, "vm-from");
- res = ast_stream_and_wait(chan, prefile, chan->language, "");
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
- /* BB: Say "from extension" as one saying to sound smoother */
- if (!callback)
- res = wait_file2(chan, vms, "vm-from-extension");
- res = ast_say_digit_str(chan, callerid, "", chan->language);
- }
- }
- }
- }
-
- else if (!res){
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
- /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
- if (!callback)
- res = wait_file2(chan, vms, "vm-from-phonenumber");
- res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
- }
- } else {
- /* Number unknown */
- if (option_debug)
- ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
- /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
- res = wait_file2(chan, vms, "vm-unknown-caller");
- }
- return res;
-}
-
-static int play_message_duration(struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
-{
- int res = 0;
- int durationm;
- int durations;
- /* Verify that we have a duration for the message */
- if (duration == NULL)
- return res;
-
- /* Convert from seconds to minutes */
- durations=atoi(duration);
- durationm=(durations / 60);
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
-
- if ((!res) && (durationm >= minduration)) {
- res = wait_file2(chan, vms, "vm-duration");
-
- /* POLISH syntax */
- if (!strcasecmp(chan->language, "pl")) {
- div_t num = div(durationm, 10);
-
- if (durationm == 1) {
- res = ast_play_and_wait(chan, "digits/1z");
- res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
- } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
- if (num.rem == 2) {
- if (!num.quot) {
- res = ast_play_and_wait(chan, "digits/2-ie");
- } else {
- res = say_and_wait(chan, durationm - 2 , chan->language);
- res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
- }
- } else {
- res = say_and_wait(chan, durationm, chan->language);
- }
- res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
- } else {
- res = say_and_wait(chan, durationm, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
- }
- /* DEFAULT syntax */
- } else {
- res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
- res = wait_file2(chan, vms, "vm-minutes");
- }
- }
- return res;
-}
-
-#ifdef IMAP_STORAGE
-static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
-{
- BODY *body;
- char *header_content;
- char cid[256];
- char context[256];
- char origtime[32];
- char duration[16];
- char category[32];
- char todir[PATH_MAX];
- int res = 0;
- char *attachedfilefmt;
- char *temp;
-
- vms->starting = 0;
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
- if (vms->msgArray[vms->curmsg] == 0) {
- ast_log (LOG_WARNING,"Trying to access unknown message\n");
- return -1;
- }
-
- /* This will only work for new messages... */
- header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
- /* empty string means no valid header */
- if (ast_strlen_zero(header_content)) {
- ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
- return -1;
- }
- snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
- make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
-
- mail_fetchstructure (vms->mailstream,vms->msgArray[vms->curmsg],&body);
-
- /* We have the body, now we extract the file name of the first attachment. */
- if (body->nested.part && body->nested.part->next && body->nested.part->next->body.parameter->value) {
- attachedfilefmt = ast_strdupa(body->nested.part->next->body.parameter->value);
- } else {
- ast_log(LOG_ERROR, "There is no file attached to this IMAP message.\n");
- return -1;
- }
-
- /* Find the format of the attached file */
-
- strsep(&attachedfilefmt, ".");
- if (!attachedfilefmt) {
- ast_log(LOG_ERROR, "File format could not be obtained from IMAP message attachment\n");
- return -1;
- }
- save_body(body, vms, "2", attachedfilefmt);
-
- adsi_message(chan, vms);
- if (!vms->curmsg)
- res = wait_file2(chan, vms, "vm-first"); /* "First" */
- else if (vms->curmsg == vms->lastmsg)
- res = wait_file2(chan, vms, "vm-last"); /* "last" */
- if (!res) {
- res = wait_file2(chan, vms, "vm-message"); /* "message" */
- if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
- if (!res)
- res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
- }
- }
-
- /* Get info from headers!! */
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
-
- if (temp)
- ast_copy_string(cid, temp, sizeof(cid));
- else
- cid[0] = '\0';
-
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
-
- if (temp)
- ast_copy_string(context, temp, sizeof(context));
- else
- context[0] = '\0';
-
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
-
- if (temp)
- ast_copy_string(origtime, temp, sizeof(origtime));
- else
- origtime[0] = '\0';
-
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
-
- if (temp)
- ast_copy_string(duration,temp, sizeof(duration));
- else
- duration[0] = '\0';
-
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Category:");
-
- if (temp)
- ast_copy_string(category,temp, sizeof(category));
- else
- category[0] = '\0';
-
- /*if (!strncasecmp("macro",context,5)) Macro names in contexts are useless for our needs */
- /* context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); */
- if (res == '1')
- res = 0;
-
- if ((!res) && !ast_strlen_zero(category)) {
- res = play_message_category(chan, category);
- }
-
- if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)) && origtime[0] != '\0')
- res = play_message_datetime(chan, vmu, origtime, "IMAP_STORAGE");
- if ((!res) && (ast_test_flag(vmu, VM_SAYCID)) && cid[0] !='\0' && context[0] !='\0')
- res = play_message_callerid(chan, vms, cid, context, 0);
-
- if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)) && duration[0] != '\0')
- res = play_message_duration(chan, vms, duration, vmu->saydurationm);
-
- /* Allow pressing '1' to skip envelope / callerid */
- /* if (res == '1')
- res = 0;
- */
- /*ast_config_destroy(msg_cfg);*/
- res = 0;
-
- if (!res) {
- vms->heard[vms->curmsg] = 1;
- res = wait_file(chan, vms, vms->fn);
- }
- DISPOSE(vms->curdir, vms->curmsg);
- DELETE(0, 0, vms->fn);
- return res;
-}
-#else
-static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
-{
- int res = 0;
- char filename[256], *cid;
- const char *origtime, *context, *category, *duration;
- struct ast_config *msg_cfg;
-
- vms->starting = 0;
- make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
- adsi_message(chan, vms);
- if (!vms->curmsg)
- res = wait_file2(chan, vms, "vm-first"); /* "First" */
- else if (vms->curmsg == vms->lastmsg)
- res = wait_file2(chan, vms, "vm-last"); /* "last" */
- if (!res) {
- /* POLISH syntax */
- if (!strcasecmp(chan->language, "pl")) {
- if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
- int ten, one;
- char nextmsg[256];
- ten = (vms->curmsg + 1) / 10;
- one = (vms->curmsg + 1) % 10;
-
- if (vms->curmsg < 20) {
- snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
- res = wait_file2(chan, vms, nextmsg);
- } else {
- snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
- res = wait_file2(chan, vms, nextmsg);
- if (one > 0) {
- if (!res) {
- snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
- res = wait_file2(chan, vms, nextmsg);
- }
- }
- }
- }
- if (!res)
- res = wait_file2(chan, vms, "vm-message");
- } else {
- if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
- res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */
- else /* DEFAULT syntax */
- res = wait_file2(chan, vms, "vm-message");
- if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
- if (!res)
- res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
- }
- }
- }
-
- /* Retrieve info from VM attribute file */
- make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
- snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
- RETRIEVE(vms->curdir, vms->curmsg);
- msg_cfg = ast_config_load(filename);
- if (!msg_cfg) {
- ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
- return 0;
- }
-
- if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
- ast_log(LOG_WARNING, "No origtime?!\n");
- DISPOSE(vms->curdir, vms->curmsg);
- ast_config_destroy(msg_cfg);
- return 0;
- }
-
- cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
- duration = ast_variable_retrieve(msg_cfg, "message", "duration");
- category = ast_variable_retrieve(msg_cfg, "message", "category");
-
- context = ast_variable_retrieve(msg_cfg, "message", "context");
- if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
- context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
- if (!res)
- res = play_message_category(chan, category);
- if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
- res = play_message_datetime(chan, vmu, origtime, filename);
- if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
- res = play_message_callerid(chan, vms, cid, context, 0);
- if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
- res = play_message_duration(chan, vms, duration, vmu->saydurationm);
- /* Allow pressing '1' to skip envelope / callerid */
- if (res == '1')
- res = 0;
- ast_config_destroy(msg_cfg);
-
- if (!res) {
- make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
- vms->heard[vms->curmsg] = 1;
- if ((res = wait_file(chan, vms, vms->fn)) < 0) {
- ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
- res = 0;
- }
- }
- DISPOSE(vms->curdir, vms->curmsg);
- return res;
-}
-#endif
-
-#ifdef IMAP_STORAGE
-static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int box, int use_folder)
-{
- char tmp[256], *t = tmp;
- size_t left = sizeof(tmp);
-
- if (box == 1) {
- ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
- snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", mbox(1));
- } else {
- ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
- snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
- }
-
- /* Build up server information */
- ast_build_string(&t, &left, "{%s:%s/imap", imapserver, imapport);
-
- /* Add authentication user if present */
- if (!ast_strlen_zero(authuser))
- ast_build_string(&t, &left, "/authuser=%s", authuser);
-
- /* Add flags if present */
- if (!ast_strlen_zero(imapflags))
- ast_build_string(&t, &left, "/%s", imapflags);
-
- /* End with username */
- ast_build_string(&t, &left, "/user=%s}", vms->imapuser);
-
- if (box == 0 || box == 1)
- snprintf(spec, len, "%s%s", tmp, use_folder? imapfolder: "INBOX");
- else
- snprintf(spec, len, "%s%s%c%s", tmp, imapfolder, delimiter, mbox(box));
-}
-
-static int init_mailstream(struct vm_state *vms, int box)
-{
- MAILSTREAM *stream = NIL;
- long debug;
- char tmp[256];
-
- if (!vms) {
- ast_log (LOG_ERROR,"vm_state is NULL!\n");
- return -1;
- }
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"vm_state user is:%s\n",vms->imapuser);
- if (vms->mailstream == NIL || !vms->mailstream) {
- if (option_debug)
- ast_log (LOG_DEBUG,"mailstream not set.\n");
- } else {
- stream = vms->mailstream;
- }
- /* debug = T; user wants protocol telemetry? */
- debug = NIL; /* NO protocol telemetry? */
-
- if (delimiter == '\0') { /* did not probe the server yet */
- char *cp;
-#ifdef USE_SYSTEM_IMAP
-#include <imap/linkage.c>
-#elif defined(USE_SYSTEM_CCLIENT)
-#include <c-client/linkage.c>
-#else
-#include "linkage.c"
-#endif
- /* Connect to INBOX first to get folders delimiter */
- imap_mailbox_name(tmp, sizeof(tmp), vms, 0, 1);
- ast_mutex_lock(&vms->lock);
- stream = mail_open (stream, tmp, debug ? OP_DEBUG : NIL);
- ast_mutex_unlock(&vms->lock);
- if (stream == NIL) {
- ast_log (LOG_ERROR, "Can't connect to imap server %s\n", tmp);
- return -1;
- }
- get_mailbox_delimiter(stream);
- /* update delimiter in imapfolder */
- for (cp = imapfolder; *cp; cp++)
- if (*cp == '/')
- *cp = delimiter;
- }
- /* Now connect to the target folder */
- imap_mailbox_name(tmp, sizeof(tmp), vms, box, 1);
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Before mail_open, server: %s, box:%d\n", tmp, box);
- ast_mutex_lock(&vms->lock);
- vms->mailstream = mail_open (stream, tmp, debug ? OP_DEBUG : NIL);
- ast_mutex_unlock(&vms->lock);
- if (vms->mailstream == NIL) {
- return -1;
- } else {
- return 0;
- }
-}
-
-static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box)
-{
- SEARCHPGM *pgm;
- SEARCHHEADER *hdr;
- int ret;
-
- ast_copy_string(vms->imapuser,vmu->imapuser, sizeof(vms->imapuser));
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"Before init_mailstream, user is %s\n",vmu->imapuser);
- ret = init_mailstream(vms, box);
- if (ret != 0 || !vms->mailstream) {
- ast_log (LOG_ERROR,"Could not initialize mailstream\n");
- return -1;
- }
-
- /* Check Quota */
- if (box == 0) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Mailbox name set to: %s, about to check quotas\n", mbox(box));
- check_quota(vms,(char *)mbox(box));
- }
-
- pgm = mail_newsearchpgm();
-
- /* Check IMAP folder for Asterisk messages only... */
- hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", vmu->mailbox);
- pgm->header = hdr;
- pgm->deleted = 0;
- pgm->undeleted = 1;
-
- /* if box = 0, check for new, if box = 1, check for read */
- if (box == 0) {
- pgm->unseen = 1;
- pgm->seen = 0;
- } else if (box == 1) {
- pgm->seen = 1;
- pgm->unseen = 0;
- }
-
- vms->vmArrayIndex = 0;
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"Before mail_search_full, user is %s\n",vmu->imapuser);
- mail_search_full (vms->mailstream, NULL, pgm, NIL);
-
-
- vms->lastmsg = vms->vmArrayIndex - 1;
-
- mail_free_searchpgm(&pgm);
- return 0;
-}
-#else
-static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
-{
- int res = 0;
- int count_msg, last_msg;
-
- ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
-
- /* Rename the member vmbox HERE so that we don't try to return before
- * we know what's going on.
- */
- snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
-
- /* Faster to make the directory than to check if it exists. */
- create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
-
- count_msg = count_messages(vmu, vms->curdir);
- if (count_msg < 0)
- return count_msg;
- else
- vms->lastmsg = count_msg - 1;
-
- /*
- The following test is needed in case sequencing gets messed up.
- There appears to be more than one way to mess up sequence, so
- we will not try to find all of the root causes--just fix it when
- detected.
- */
-
- last_msg = last_message_index(vmu, vms->curdir);
- if (last_msg < 0)
- return last_msg;
- else if (vms->lastmsg != last_msg)
- {
- ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
- res = resequence_mailbox(vmu, vms->curdir);
- if (res)
- return res;
- }
-
- return 0;
-}
-#endif
-
-static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
-{
- int x = 0;
-#ifndef IMAP_STORAGE
- int res = 0, nummsg;
-#endif
-
- if (vms->lastmsg <= -1)
- goto done;
-
- vms->curmsg = -1;
-#ifndef IMAP_STORAGE
- /* Get the deleted messages fixed */
- if (vm_lock_path(vms->curdir))
- return ERROR_LOCK_PATH;
-
- for (x = 0; x < vmu->maxmsg; x++) {
- if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) {
- /* Save this message. It's not in INBOX or hasn't been heard */
- make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
- if (!EXISTS(vms->curdir, x, vms->fn, NULL))
- break;
- vms->curmsg++;
- make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
- if (strcmp(vms->fn, vms->fn2)) {
- RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
- }
- } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) {
- /* Move to old folder before deleting */
- res = save_to_folder(vmu, vms, x, 1);
- if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
- /* If save failed do not delete the message */
- ast_log(LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
- vms->deleted[x] = 0;
- vms->heard[x] = 0;
- --x;
- }
- }
- }
-
- /* Delete ALL remaining messages */
- nummsg = x - 1;
- for (x = vms->curmsg + 1; x <= nummsg; x++) {
- make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
- if (EXISTS(vms->curdir, x, vms->fn, NULL))
- DELETE(vms->curdir, x, vms->fn);
- }
- ast_unlock_path(vms->curdir);
-#else
- if (vms->deleted) {
- for (x=0;x < vmu->maxmsg;x++) {
- if (vms->deleted[x]) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
- IMAP_DELETE(vms->curdir, x, vms->fn, vms);
- }
- }
- }
-#endif
-
-done:
- if (vms->deleted)
- memset(vms->deleted, 0, vmu->maxmsg * sizeof(int));
- if (vms->heard)
- memset(vms->heard, 0, vmu->maxmsg * sizeof(int));
-
- return 0;
-}
-
-/* In Greek even though we CAN use a syntax like "friends messages"
- * ("filika mynhmata") it is not elegant. This also goes for "work/family messages"
- * ("ergasiaka/oikogeniaka mynhmata"). Therefore it is better to use a reversed
- * syntax for the above three categories which is more elegant.
- */
-
-static int vm_play_folder_name_gr(struct ast_channel *chan, char *mbox)
-{
- int cmd;
- char *buf;
-
- buf = alloca(strlen(mbox)+2);
- strcpy(buf, mbox);
- strcat(buf,"s");
-
- if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
- cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
- return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
- } else {
- cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
- return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
- }
-}
-
-static int vm_play_folder_name_pl(struct ast_channel *chan, char *mbox)
-{
- int cmd;
-
- if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
- if (!strcasecmp(mbox, "vm-INBOX"))
- cmd = ast_play_and_wait(chan, "vm-new-e");
- else
- cmd = ast_play_and_wait(chan, "vm-old-e");
- return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
- } else {
- cmd = ast_play_and_wait(chan, "vm-messages");
- return cmd ? cmd : ast_play_and_wait(chan, mbox);
- }
-}
-
-static int vm_play_folder_name_ua(struct ast_channel *chan, char *mbox)
-{
- int cmd;
-
- if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
- cmd = ast_play_and_wait(chan, "vm-messages");
- return cmd ? cmd : ast_play_and_wait(chan, mbox);
- } else {
- cmd = ast_play_and_wait(chan, mbox);
- return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
- }
-}
-
-static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
-{
- int cmd;
-
- if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
- cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
- return cmd ? cmd : ast_play_and_wait(chan, mbox);
- } else if (!strcasecmp(chan->language, "gr")){
- return vm_play_folder_name_gr(chan, mbox);
- } else if (!strcasecmp(chan->language, "pl")){
- return vm_play_folder_name_pl(chan, mbox);
- } else if (!strcasecmp(chan->language, "ua")){ /* Ukrainian syntax */
- return vm_play_folder_name_ua(chan, mbox);
- } else { /* Default English */
- cmd = ast_play_and_wait(chan, mbox);
- return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
- }
-}
-
-/* GREEK SYNTAX
- In greek the plural for old/new is
- different so we need the following files
- We also need vm-denExeteMynhmata because
- this syntax is different.
-
- -> vm-Olds.wav : "Palia"
- -> vm-INBOXs.wav : "Nea"
- -> vm-denExeteMynhmata : "den exete mynhmata"
-*/
-
-
-static int vm_intro_gr(struct ast_channel *chan, struct vm_state *vms)
-{
- int res = 0;
-
- if (vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res)
- res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
- if (!res) {
- if ((vms->newmessages == 1)) {
- res = ast_play_and_wait(chan, "vm-INBOX");
- if (!res)
- res = ast_play_and_wait(chan, "vm-message");
- } else {
- res = ast_play_and_wait(chan, "vm-INBOXs");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- } else if (vms->oldmessages){
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res)
- res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
- if ((vms->oldmessages == 1)){
- res = ast_play_and_wait(chan, "vm-Old");
- if (!res)
- res = ast_play_and_wait(chan, "vm-message");
- } else {
- res = ast_play_and_wait(chan, "vm-Olds");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- } else if (!vms->oldmessages && !vms->newmessages)
- res = ast_play_and_wait(chan, "vm-denExeteMynhmata");
- return res;
-}
-
-/* Default English syntax */
-static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
-{
- int res;
-
- /* Introduce messages they have */
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res) {
- if (vms->newmessages) {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOX");
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- else if (!res) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
-
- }
- if (!res && vms->oldmessages) {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-Old");
- if (!res) {
- if (vms->oldmessages == 1)
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- if (!res) {
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- }
- return res;
-}
-
-/* ITALIAN syntax */
-static int vm_intro_it(struct ast_channel *chan, struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- if (!vms->oldmessages && !vms->newmessages)
- res = ast_play_and_wait(chan, "vm-no") ||
- ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res && vms->newmessages) {
- res = (vms->newmessages == 1) ?
- ast_play_and_wait(chan, "digits/un") ||
- ast_play_and_wait(chan, "vm-nuovo") ||
- ast_play_and_wait(chan, "vm-message") :
- /* 2 or more new messages */
- say_and_wait(chan, vms->newmessages, chan->language) ||
- ast_play_and_wait(chan, "vm-nuovi") ||
- ast_play_and_wait(chan, "vm-messages");
- if (!res && vms->oldmessages)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (!res && vms->oldmessages) {
- res = (vms->oldmessages == 1) ?
- ast_play_and_wait(chan, "digits/un") ||
- ast_play_and_wait(chan, "vm-vecchio") ||
- ast_play_and_wait(chan, "vm-message") :
- /* 2 or more old messages */
- say_and_wait(chan, vms->oldmessages, chan->language) ||
- ast_play_and_wait(chan, "vm-vecchi") ||
- ast_play_and_wait(chan, "vm-messages");
- }
- return res ? -1 : 0;
-}
-
-/* POLISH syntax */
-static int vm_intro_pl(struct ast_channel *chan, struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- div_t num;
-
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- return res;
- } else {
- res = ast_play_and_wait(chan, "vm-youhave");
- }
-
- if (vms->newmessages) {
- num = div(vms->newmessages, 10);
- if (vms->newmessages == 1) {
- res = ast_play_and_wait(chan, "digits/1-a");
- res = res ? res : ast_play_and_wait(chan, "vm-new-a");
- res = res ? res : ast_play_and_wait(chan, "vm-message");
- } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
- if (num.rem == 2) {
- if (!num.quot) {
- res = ast_play_and_wait(chan, "digits/2-ie");
- } else {
- res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
- res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
- }
- } else {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- }
- res = res ? res : ast_play_and_wait(chan, "vm-new-e");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- } else {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- }
- if (!res && vms->oldmessages)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (!res && vms->oldmessages) {
- num = div(vms->oldmessages, 10);
- if (vms->oldmessages == 1) {
- res = ast_play_and_wait(chan, "digits/1-a");
- res = res ? res : ast_play_and_wait(chan, "vm-old-a");
- res = res ? res : ast_play_and_wait(chan, "vm-message");
- } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
- if (num.rem == 2) {
- if (!num.quot) {
- res = ast_play_and_wait(chan, "digits/2-ie");
- } else {
- res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
- res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
- }
- } else {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- }
- res = res ? res : ast_play_and_wait(chan, "vm-old-e");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- } else {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- }
- }
-
- return res;
-}
-
-/* SWEDISH syntax */
-static int vm_intro_se(struct ast_channel *chan, struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
-
- res = ast_play_and_wait(chan, "vm-youhave");
- if (res)
- return res;
-
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- return res;
- }
-
- if (vms->newmessages) {
- if ((vms->newmessages == 1)) {
- res = ast_play_and_wait(chan, "digits/ett");
- res = res ? res : ast_play_and_wait(chan, "vm-nytt");
- res = res ? res : ast_play_and_wait(chan, "vm-message");
- } else {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-nya");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- }
- if (!res && vms->oldmessages)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (!res && vms->oldmessages) {
- if (vms->oldmessages == 1) {
- res = ast_play_and_wait(chan, "digits/ett");
- res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
- res = res ? res : ast_play_and_wait(chan, "vm-message");
- } else {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-gamla");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- }
- }
-
- return res;
-}
-
-/* NORWEGIAN syntax */
-static int vm_intro_no(struct ast_channel *chan,struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
-
- res = ast_play_and_wait(chan, "vm-youhave");
- if (res)
- return res;
-
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- return res;
- }
-
- if (vms->newmessages) {
- if ((vms->newmessages == 1)) {
- res = ast_play_and_wait(chan, "digits/1");
- res = res ? res : ast_play_and_wait(chan, "vm-ny");
- res = res ? res : ast_play_and_wait(chan, "vm-message");
- } else {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-nye");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- }
- if (!res && vms->oldmessages)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (!res && vms->oldmessages) {
- if (vms->oldmessages == 1) {
- res = ast_play_and_wait(chan, "digits/1");
- res = res ? res : ast_play_and_wait(chan, "vm-gamel");
- res = res ? res : ast_play_and_wait(chan, "vm-message");
- } else {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- res = res ? res : ast_play_and_wait(chan, "vm-gamle");
- res = res ? res : ast_play_and_wait(chan, "vm-messages");
- }
- }
-
- return res;
-}
-
-/* GERMAN syntax */
-static int vm_intro_de(struct ast_channel *chan,struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res) {
- if (vms->newmessages) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "digits/1F");
- else
- res = say_and_wait(chan, vms->newmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOX");
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- else if (!res) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
-
- }
- if (!res && vms->oldmessages) {
- if (vms->oldmessages == 1)
- res = ast_play_and_wait(chan, "digits/1F");
- else
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-Old");
- if (!res) {
- if (vms->oldmessages == 1)
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- if (!res) {
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- }
- return res;
-}
-
-/* SPANISH syntax */
-static int vm_intro_es(struct ast_channel *chan,struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-youhaveno");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- } else {
- res = ast_play_and_wait(chan, "vm-youhave");
- }
- if (!res) {
- if (vms->newmessages) {
- if (!res) {
- if ((vms->newmessages == 1)) {
- res = ast_play_and_wait(chan, "digits/1M");
- if (!res)
- res = ast_play_and_wait(chan, "vm-message");
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOXs");
- } else {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOX");
- }
- }
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (vms->oldmessages) {
- if (!res) {
- if (vms->oldmessages == 1) {
- res = ast_play_and_wait(chan, "digits/1M");
- if (!res)
- res = ast_play_and_wait(chan, "vm-message");
- if (!res)
- res = ast_play_and_wait(chan, "vm-Olds");
- } else {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-Old");
- }
- }
- }
- }
-return res;
-}
-
-/* BRAZILIAN PORTUGUESE syntax */
-static int vm_intro_pt_BR(struct ast_channel *chan,struct vm_state *vms) {
- /* Introduce messages they have */
- int res;
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-nomessages");
- return res;
- }
- else {
- res = ast_play_and_wait(chan, "vm-youhave");
- }
- if (vms->newmessages) {
- if (!res)
- res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
- if ((vms->newmessages == 1)) {
- if (!res)
- res = ast_play_and_wait(chan, "vm-message");
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOXs");
- }
- else {
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOX");
- }
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (vms->oldmessages) {
- if (!res)
- res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
- if (vms->oldmessages == 1) {
- if (!res)
- res = ast_play_and_wait(chan, "vm-message");
- if (!res)
- res = ast_play_and_wait(chan, "vm-Olds");
- }
- else {
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-Old");
- }
- }
- return res;
-}
-
-/* FRENCH syntax */
-static int vm_intro_fr(struct ast_channel *chan,struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res) {
- if (vms->newmessages) {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOX");
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- else if (!res) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
-
- }
- if (!res && vms->oldmessages) {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- if (!res)
- res = ast_play_and_wait(chan, "vm-Old");
- if (!res) {
- if (vms->oldmessages == 1)
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- if (!res) {
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- }
- return res;
-}
-
-/* DUTCH syntax */
-static int vm_intro_nl(struct ast_channel *chan,struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res) {
- if (vms->newmessages) {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- if (!res) {
- if (vms->newmessages == 1)
- res = ast_play_and_wait(chan, "vm-INBOXs");
- else
- res = ast_play_and_wait(chan, "vm-INBOX");
- }
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- else if (!res) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
-
- }
- if (!res && vms->oldmessages) {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- if (!res) {
- if (vms->oldmessages == 1)
- res = ast_play_and_wait(chan, "vm-Olds");
- else
- res = ast_play_and_wait(chan, "vm-Old");
- }
- if (!res) {
- if (vms->oldmessages == 1)
- res = ast_play_and_wait(chan, "vm-message");
- else
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- if (!res) {
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- }
- return res;
-}
-
-/* PORTUGUESE syntax */
-static int vm_intro_pt(struct ast_channel *chan,struct vm_state *vms)
-{
- /* Introduce messages they have */
- int res;
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res) {
- if (vms->newmessages) {
- res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
- if (!res) {
- if ((vms->newmessages == 1)) {
- res = ast_play_and_wait(chan, "vm-message");
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOXs");
- } else {
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-INBOX");
- }
- }
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- }
- if (!res && vms->oldmessages) {
- res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
- if (!res) {
- if (vms->oldmessages == 1) {
- res = ast_play_and_wait(chan, "vm-message");
- if (!res)
- res = ast_play_and_wait(chan, "vm-Olds");
- } else {
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, "vm-Old");
- }
- }
- }
- if (!res) {
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
- }
- }
- return res;
-}
-
-
-/* CZECH syntax */
-/* in czech there must be declension of word new and message
- * czech : english : czech : english
- * --------------------------------------------------------
- * vm-youhave : you have
- * vm-novou : one new : vm-zpravu : message
- * vm-nove : 2-4 new : vm-zpravy : messages
- * vm-novych : 5-infinite new : vm-zprav : messages
- * vm-starou : one old
- * vm-stare : 2-4 old
- * vm-starych : 5-infinite old
- * jednu : one - falling 4.
- * vm-no : no ( no messages )
- */
-
-static int vm_intro_cz(struct ast_channel *chan,struct vm_state *vms)
-{
- int res;
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res) {
- if (vms->newmessages) {
- if (vms->newmessages == 1) {
- res = ast_play_and_wait(chan, "digits/jednu");
- } else {
- res = say_and_wait(chan, vms->newmessages, chan->language);
- }
- if (!res) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "vm-novou");
- if ((vms->newmessages) > 1 && (vms->newmessages < 5))
- res = ast_play_and_wait(chan, "vm-nove");
- if (vms->newmessages > 4)
- res = ast_play_and_wait(chan, "vm-novych");
- }
- if (vms->oldmessages && !res)
- res = ast_play_and_wait(chan, "vm-and");
- else if (!res) {
- if ((vms->newmessages == 1))
- res = ast_play_and_wait(chan, "vm-zpravu");
- if ((vms->newmessages) > 1 && (vms->newmessages < 5))
- res = ast_play_and_wait(chan, "vm-zpravy");
- if (vms->newmessages > 4)
- res = ast_play_and_wait(chan, "vm-zprav");
- }
- }
- if (!res && vms->oldmessages) {
- res = say_and_wait(chan, vms->oldmessages, chan->language);
- if (!res) {
- if ((vms->oldmessages == 1))
- res = ast_play_and_wait(chan, "vm-starou");
- if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
- res = ast_play_and_wait(chan, "vm-stare");
- if (vms->oldmessages > 4)
- res = ast_play_and_wait(chan, "vm-starych");
- }
- if (!res) {
- if ((vms->oldmessages == 1))
- res = ast_play_and_wait(chan, "vm-zpravu");
- if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
- res = ast_play_and_wait(chan, "vm-zpravy");
- if (vms->oldmessages > 4)
- res = ast_play_and_wait(chan, "vm-zprav");
- }
- }
- if (!res) {
- if (!vms->oldmessages && !vms->newmessages) {
- res = ast_play_and_wait(chan, "vm-no");
- if (!res)
- res = ast_play_and_wait(chan, "vm-zpravy");
- }
- }
- }
- return res;
-}
-
-static int get_lastdigits(int num)
-{
- num %= 100;
- return (num < 20) ? num : num % 10;
-}
-
-static int vm_intro_ru(struct ast_channel *chan,struct vm_state *vms)
-{
- int res;
- int lastnum = 0;
- int dcnum;
-
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res && vms->newmessages) {
- lastnum = get_lastdigits(vms->newmessages);
- dcnum = vms->newmessages - lastnum;
- if (dcnum)
- res = say_and_wait(chan, dcnum, chan->language);
- if (!res && lastnum) {
- if (lastnum == 1)
- res = ast_play_and_wait(chan, "digits/odno");
- else
- res = say_and_wait(chan, lastnum, chan->language);
- }
-
- if (!res)
- res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-novoe" : "vm-novyh");
-
- if (!res && vms->oldmessages)
- res = ast_play_and_wait(chan, "vm-and");
- }
-
- if (!res && vms->oldmessages) {
- lastnum = get_lastdigits(vms->oldmessages);
- dcnum = vms->oldmessages - lastnum;
- if (dcnum)
- res = say_and_wait(chan, dcnum, chan->language);
- if (!res && lastnum) {
- if (lastnum == 1)
- res = ast_play_and_wait(chan, "digits/odno");
- else
- res = say_and_wait(chan, lastnum, chan->language);
- }
-
- if (!res)
- res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-staroe" : "vm-staryh");
- }
-
- if (!res && !vms->newmessages && !vms->oldmessages) {
- lastnum = 0;
- res = ast_play_and_wait(chan, "vm-no");
- }
-
- if (!res) {
- switch (lastnum) {
- case 1:
- res = ast_play_and_wait(chan, "vm-soobshenie");
- break;
- case 2:
- case 3:
- case 4:
- res = ast_play_and_wait(chan, "vm-soobsheniya");
- break;
- default:
- res = ast_play_and_wait(chan, "vm-soobsheniy");
- break;
- }
- }
-
- return res;
-}
-
-/* UKRAINIAN syntax */
-/* in ukrainian the syntax is different so we need the following files
- * --------------------------------------------------------
- * /digits/ua/1e 'odne'
- * vm-nove 'nove'
- * vm-stare 'stare'
- */
-
-static int vm_intro_ua(struct ast_channel *chan,struct vm_state *vms)
-{
- int res;
- int lastnum = 0;
- int dcnum;
-
- res = ast_play_and_wait(chan, "vm-youhave");
- if (!res && vms->newmessages) {
- lastnum = get_lastdigits(vms->newmessages);
- dcnum = vms->newmessages - lastnum;
- if (dcnum)
- res = say_and_wait(chan, dcnum, chan->language);
- if (!res && lastnum) {
- if (lastnum == 1)
- res = ast_play_and_wait(chan, "digits/ua/1e");
- else
- res = say_and_wait(chan, lastnum, chan->language);
- }
-
- if (!res)
- res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-nove" : "vm-INBOX");
-
- if (!res && vms->oldmessages)
- res = ast_play_and_wait(chan, "vm-and");
- }
-
- if (!res && vms->oldmessages) {
- lastnum = get_lastdigits(vms->oldmessages);
- dcnum = vms->oldmessages - lastnum;
- if (dcnum)
- res = say_and_wait(chan, dcnum, chan->language);
- if (!res && lastnum) {
- if (lastnum == 1)
- res = ast_play_and_wait(chan, "digits/ua/1e");
- else
- res = say_and_wait(chan, lastnum, chan->language);
- }
-
- if (!res)
- res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-stare" : "vm-Old");
- }
-
- if (!res && !vms->newmessages && !vms->oldmessages) {
- lastnum = 0;
- res = ast_play_and_wait(chan, "vm-no");
- }
-
- if (!res) {
- switch (lastnum) {
- case 1:
- case 2:
- case 3:
- case 4:
- res = ast_play_and_wait(chan, "vm-message");
- break;
- default:
- res = ast_play_and_wait(chan, "vm-messages");
- break;
- }
- }
-
- return res;
-}
-
-
-static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
-{
- char prefile[256];
-
- /* Notify the user that the temp greeting is set and give them the option to remove it */
- snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
- if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
- if (ast_fileexists(prefile, NULL, NULL) > 0)
- ast_play_and_wait(chan, "vm-tempgreetactive");
- }
-
- /* Play voicemail intro - syntax is different for different languages */
- if (!strcasecmp(chan->language, "de")) { /* GERMAN syntax */
- return vm_intro_de(chan, vms);
- } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
- return vm_intro_es(chan, vms);
- } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
- return vm_intro_it(chan, vms);
- } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
- return vm_intro_fr(chan, vms);
- } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
- return vm_intro_nl(chan, vms);
- } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
- return vm_intro_pt(chan, vms);
- } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
- return vm_intro_pt_BR(chan, vms);
- } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
- return vm_intro_cz(chan, vms);
- } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
- return vm_intro_gr(chan, vms);
- } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */
- return vm_intro_pl(chan, vms);
- } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
- return vm_intro_se(chan, vms);
- } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
- return vm_intro_no(chan, vms);
- } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */
- return vm_intro_ru(chan, vms);
- } else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */
- return vm_intro_ua(chan, vms);
- } else { /* Default to ENGLISH */
- return vm_intro_en(chan, vms);
- }
-}
-
-static int vm_instructions(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
-{
- int res = 0;
- /* Play instructions and wait for new command */
- while (!res) {
- if (vms->starting) {
- if (vms->lastmsg > -1) {
- res = ast_play_and_wait(chan, "vm-onefor");
- if (!res)
- res = vm_play_folder_name(chan, vms->vmbox);
- }
- if (!res)
- res = ast_play_and_wait(chan, "vm-opts");
- } else {
- if (vms->curmsg)
- res = ast_play_and_wait(chan, "vm-prev");
- if (!res && !skipadvanced)
- res = ast_play_and_wait(chan, "vm-advopts");
- if (!res)
- res = ast_play_and_wait(chan, "vm-repeat");
- if (!res && (vms->curmsg != vms->lastmsg))
- res = ast_play_and_wait(chan, "vm-next");
- if (!res) {
- if (!vms->deleted[vms->curmsg])
- res = ast_play_and_wait(chan, "vm-delete");
- else
- res = ast_play_and_wait(chan, "vm-undelete");
- if (!res)
- res = ast_play_and_wait(chan, "vm-toforward");
- if (!res)
- res = ast_play_and_wait(chan, "vm-savemessage");
- }
- }
- if (!res)
- res = ast_play_and_wait(chan, "vm-helpexit");
- if (!res)
- res = ast_waitfordigit(chan, 6000);
- if (!res) {
- vms->repeats++;
- if (vms->repeats > 2) {
- res = 't';
- }
- }
- }
- return res;
-}
-
-static int vm_newuser(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
-{
- int cmd = 0;
- int duration = 0;
- int tries = 0;
- char newpassword[80] = "";
- char newpassword2[80] = "";
- char prefile[PATH_MAX] = "";
- unsigned char buf[256];
- int bytes=0;
-
- if (ast_adsi_available(chan)) {
- bytes += adsi_logo(buf + bytes);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
- }
-
- /* First, have the user change their password
- so they won't get here again */
- for (;;) {
- newpassword[1] = '\0';
- newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
- if (cmd == '#')
- newpassword[0] = '\0';
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- newpassword2[1] = '\0';
- newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
- if (cmd == '#')
- newpassword2[0] = '\0';
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- if (!strcmp(newpassword, newpassword2))
- break;
- ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
- cmd = ast_play_and_wait(chan, "vm-mismatch");
- if (++tries == 3)
- return -1;
- }
- if (ast_strlen_zero(ext_pass_cmd))
- vm_change_password(vmu,newpassword);
- else
- vm_change_password_shell(vmu,newpassword);
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
- cmd = ast_play_and_wait(chan,"vm-passchanged");
-
- /* If forcename is set, have the user record their name */
- if (ast_test_flag(vmu, VM_FORCENAME)) {
- snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
- if (ast_fileexists(prefile, NULL, NULL) < 1) {
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- }
- }
-
- /* If forcegreetings is set, have the user record their greetings */
- if (ast_test_flag(vmu, VM_FORCEGREET)) {
- snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
- if (ast_fileexists(prefile, NULL, NULL) < 1) {
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- }
-
- snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
- if (ast_fileexists(prefile, NULL, NULL) < 1) {
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- if (cmd < 0 || cmd == 't' || cmd == '#')
- return cmd;
- }
- }
-
- return cmd;
-}
-
-static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
-{
- int cmd = 0;
- int retries = 0;
- int duration = 0;
- char newpassword[80] = "";
- char newpassword2[80] = "";
- char prefile[PATH_MAX] = "";
- unsigned char buf[256];
- int bytes=0;
-
- if (ast_adsi_available(chan))
- {
- bytes += adsi_logo(buf + bytes);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
- }
- while ((cmd >= 0) && (cmd != 't')) {
- if (cmd)
- retries = 0;
- switch (cmd) {
- case '1':
- snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- break;
- case '2':
- snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- break;
- case '3':
- snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- break;
- case '4':
- cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
- break;
- case '5':
- if (vmu->password[0] == '-') {
- cmd = ast_play_and_wait(chan, "vm-no");
- break;
- }
- newpassword[1] = '\0';
- newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
- if (cmd == '#')
- newpassword[0] = '\0';
- else {
- if (cmd < 0)
- break;
- if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
- break;
- }
- }
- newpassword2[1] = '\0';
- newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
- if (cmd == '#')
- newpassword2[0] = '\0';
- else {
- if (cmd < 0)
- break;
-
- if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
- break;
- }
- }
- if (strcmp(newpassword, newpassword2)) {
- ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
- cmd = ast_play_and_wait(chan, "vm-mismatch");
- break;
- }
- if (ast_strlen_zero(ext_pass_cmd))
- vm_change_password(vmu,newpassword);
- else
- vm_change_password_shell(vmu,newpassword);
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
- cmd = ast_play_and_wait(chan,"vm-passchanged");
- break;
- case '*':
- cmd = 't';
- break;
- default:
- cmd = 0;
- snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
- if (ast_fileexists(prefile, NULL, NULL))
- cmd = ast_play_and_wait(chan, "vm-tmpexists");
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-options");
- if (!cmd)
- cmd = ast_waitfordigit(chan,6000);
- if (!cmd)
- retries++;
- if (retries > 3)
- cmd = 't';
- }
- }
- if (cmd == 't')
- cmd = 0;
- return cmd;
-}
-
-static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
-{
- int res;
- int cmd = 0;
- int retries = 0;
- int duration = 0;
- char prefile[PATH_MAX] = "";
- unsigned char buf[256];
- char dest[PATH_MAX];
- int bytes = 0;
-
- if (ast_adsi_available(chan)) {
- bytes += adsi_logo(buf + bytes);
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
- bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
- }
-
- snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
- if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
- ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
- return -1;
- }
- while ((cmd >= 0) && (cmd != 't')) {
- if (cmd)
- retries = 0;
- RETRIEVE(prefile, -1);
- if (ast_fileexists(prefile, NULL, NULL) <= 0) {
-#ifndef IMAP_STORAGE
- play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- cmd = 't';
- } else {
- switch (cmd) {
- case '1':
-#ifndef IMAP_STORAGE
- cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
-#else
- cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
-#endif
- break;
- case '2':
- DELETE(prefile, -1, prefile);
- ast_play_and_wait(chan, "vm-tempremoved");
- cmd = 't';
- break;
- case '*':
- cmd = 't';
- break;
- default:
- cmd = ast_play_and_wait(chan,
- ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
- "vm-tempgreeting2" : "vm-tempgreeting");
- if (!cmd)
- cmd = ast_waitfordigit(chan,6000);
- if (!cmd)
- retries++;
- if (retries > 3)
- cmd = 't';
- }
- }
- DISPOSE(prefile, -1);
- }
- if (cmd == 't')
- cmd = 0;
- return cmd;
-}
-
-/* GREEK SYNTAX */
-
-static int vm_browse_messages_gr(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
-{
- int cmd=0;
-
- if (vms->lastmsg > -1) {
- cmd = play_message(chan, vmu, vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-youhaveno");
- if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
- if (!cmd) {
- snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
- cmd = ast_play_and_wait(chan, vms->fn);
- }
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- } else {
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- if (!cmd) {
- snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
- cmd = ast_play_and_wait(chan, vms->fn);
- }
- }
- }
- return cmd;
-}
-
-/* Default English syntax */
-static int vm_browse_messages_en(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
-{
- int cmd=0;
-
- if (vms->lastmsg > -1) {
- cmd = play_message(chan, vmu, vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-youhave");
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-no");
- if (!cmd) {
- snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
- cmd = ast_play_and_wait(chan, vms->fn);
- }
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- }
- return cmd;
-}
-
-/* ITALIAN syntax */
-static int vm_browse_messages_it(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
-{
- int cmd=0;
-
- if (vms->lastmsg > -1) {
- cmd = play_message(chan, vmu, vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-no");
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-message");
- if (!cmd) {
- snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
- cmd = ast_play_and_wait(chan, vms->fn);
- }
- }
- return cmd;
-}
-
-/* SPANISH syntax */
-static int vm_browse_messages_es(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
-{
- int cmd=0;
-
- if (vms->lastmsg > -1) {
- cmd = play_message(chan, vmu, vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-youhaveno");
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- if (!cmd) {
- snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
- cmd = ast_play_and_wait(chan, vms->fn);
- }
- }
- return cmd;
-}
-
-/* PORTUGUESE syntax */
-static int vm_browse_messages_pt(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
-{
- int cmd=0;
-
- if (vms->lastmsg > -1) {
- cmd = play_message(chan, vmu, vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-no");
- if (!cmd) {
- snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
- cmd = ast_play_and_wait(chan, vms->fn);
- }
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- }
- return cmd;
-}
-
-static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
-{
- if (!strcasecmp(chan->language, "es")) { /* SPANISH */
- return vm_browse_messages_es(chan, vms, vmu);
- } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
- return vm_browse_messages_it(chan, vms, vmu);
- } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* PORTUGUESE */
- return vm_browse_messages_pt(chan, vms, vmu);
- } else if (!strcasecmp(chan->language, "gr")){
- return vm_browse_messages_gr(chan, vms, vmu); /* GREEK */
- } else { /* Default to English syntax */
- return vm_browse_messages_en(chan, vms, vmu);
- }
-}
-
-static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size,
- struct ast_vm_user *res_vmu, const char *context, const char *prefix,
- int skipuser, int maxlogins, int silent)
-{
- int useadsi=0, valid=0, logretries=0;
- char password[AST_MAX_EXTENSION]="", *passptr;
- struct ast_vm_user vmus, *vmu = NULL;
-
- /* If ADSI is supported, setup login screen */
- adsi_begin(chan, &useadsi);
- if (!skipuser && useadsi)
- adsi_login(chan);
- if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
- ast_log(LOG_WARNING, "Couldn't stream login file\n");
- return -1;
- }
-
- /* Authenticate them and get their mailbox/password */
-
- while (!valid && (logretries < maxlogins)) {
- /* Prompt for, and read in the username */
- if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
- ast_log(LOG_WARNING, "Couldn't read username\n");
- return -1;
- }
- if (ast_strlen_zero(mailbox)) {
- if (chan->cid.cid_num) {
- ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
- return -1;
- }
- }
- if (useadsi)
- adsi_password(chan);
-
- if (!ast_strlen_zero(prefix)) {
- char fullusername[80] = "";
- ast_copy_string(fullusername, prefix, sizeof(fullusername));
- strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
- ast_copy_string(mailbox, fullusername, mailbox_size);
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
- vmu = find_user(&vmus, context, mailbox);
- if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
- /* saved password is blank, so don't bother asking */
- password[0] = '\0';
- } else {
- if (ast_streamfile(chan, "vm-password", chan->language)) {
- ast_log(LOG_WARNING, "Unable to stream password file\n");
- return -1;
- }
- if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
- ast_log(LOG_WARNING, "Unable to read password\n");
- return -1;
- }
- }
-
- if (vmu) {
- passptr = vmu->password;
- if (passptr[0] == '-') passptr++;
- }
- if (vmu && !strcmp(passptr, password))
- valid++;
- else {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
- if (!ast_strlen_zero(prefix))
- mailbox[0] = '\0';
- }
- logretries++;
- if (!valid) {
- if (skipuser || logretries >= maxlogins) {
- if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
- ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
- return -1;
- }
- } else {
- if (useadsi)
- adsi_login(chan);
- if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
- ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
- return -1;
- }
- }
- if (ast_waitstream(chan, "")) /* Channel is hung up */
- return -1;
- }
- }
- if (!valid && (logretries >= maxlogins)) {
- ast_stopstream(chan);
- ast_play_and_wait(chan, "vm-goodbye");
- return -1;
- }
- if (vmu && !skipuser) {
- memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
- }
- return 0;
-}
-
-static int vm_execmain(struct ast_channel *chan, void *data)
-{
- /* XXX This is, admittedly, some pretty horrendus code. For some
- reason it just seemed a lot easier to do with GOTO's. I feel
- like I'm back in my GWBASIC days. XXX */
- int res=-1;
- int cmd=0;
- int valid = 0;
- struct ast_module_user *u;
- char prefixstr[80] ="";
- char ext_context[256]="";
- int box;
- int useadsi = 0;
- int skipuser = 0;
- struct vm_state vms;
- struct ast_vm_user *vmu = NULL, vmus;
- char *context=NULL;
- int silentexit = 0;
- struct ast_flags flags = { 0 };
- signed char record_gain = 0;
- int play_auto = 0;
- int play_folder = 0;
-#ifdef IMAP_STORAGE
- int deleted = 0;
-#endif
- u = ast_module_user_add(chan);
-
- /* Add the vm_state to the active list and keep it active */
- memset(&vms, 0, sizeof(vms));
- vms.lastmsg = -1;
-
- memset(&vmus, 0, sizeof(vmus));
-
- if (chan->_state != AST_STATE_UP) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Before ast_answer\n");
- ast_answer(chan);
- }
-
- if (!ast_strlen_zero(data)) {
- char *opts[OPT_ARG_ARRAY_SIZE];
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(argv0);
- AST_APP_ARG(argv1);
- );
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.argc == 2) {
- if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
- ast_module_user_remove(u);
- return -1;
- }
- if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
- int gain;
- if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
- if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
- ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
- ast_module_user_remove(u);
- return -1;
- } else {
- record_gain = (signed char) gain;
- }
- } else {
- ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
- }
- }
- if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
- play_auto = 1;
- if (opts[OPT_ARG_PLAYFOLDER]) {
- if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
- ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
- }
- } else {
- ast_log(LOG_WARNING, "Invalid folder set with option a\n");
- }
- if ( play_folder > 9 || play_folder < 0) {
- ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
- play_folder = 0;
- }
- }
- } else {
- /* old style options parsing */
- while (*(args.argv0)) {
- if (*(args.argv0) == 's')
- ast_set_flag(&flags, OPT_SILENT);
- else if (*(args.argv0) == 'p')
- ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
- else
- break;
- (args.argv0)++;
- }
-
- }
-
- valid = ast_test_flag(&flags, OPT_SILENT);
-
- if ((context = strchr(args.argv0, '@')))
- *context++ = '\0';
-
- if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
- ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
- else
- ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
-
- if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
- skipuser++;
- else
- valid = 0;
- }
-
- if (!valid)
- res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "After vm_authenticate\n");
- if (!res) {
- valid = 1;
- if (!skipuser)
- vmu = &vmus;
- } else {
- res = 0;
- }
-
- /* If ADSI is supported, setup login screen */
- adsi_begin(chan, &useadsi);
-
-#ifdef IMAP_STORAGE
- vms.interactive = 1;
- vms.updated = 1;
- vmstate_insert(&vms);
- init_vm_state(&vms);
-#endif
- if (!valid)
- goto out;
-
- if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
- /* TODO: Handle memory allocation failure */
- }
- if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
- /* TODO: Handle memory allocation failure */
- }
-
- /* Set language from config to override channel language */
- if (!ast_strlen_zero(vmu->language))
- ast_string_field_set(chan, language, vmu->language);
- create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
- /* Retrieve old and new message counts */
- if (option_debug)
- ast_log(LOG_DEBUG, "Before open_mailbox\n");
- res = open_mailbox(&vms, vmu, 1);
- if (res == ERROR_LOCK_PATH)
- goto out;
- vms.oldmessages = vms.lastmsg + 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
- /* Start in INBOX */
- res = open_mailbox(&vms, vmu, 0);
- if (res == ERROR_LOCK_PATH)
- goto out;
- vms.newmessages = vms.lastmsg + 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
-
- /* Select proper mailbox FIRST!! */
- if (play_auto) {
- res = open_mailbox(&vms, vmu, play_folder);
- if (res == ERROR_LOCK_PATH)
- goto out;
-
- /* If there are no new messages, inform the user and hangup */
- if (vms.lastmsg == -1) {
- cmd = vm_browse_messages(chan, &vms, vmu);
- res = 0;
- goto out;
- }
- } else {
- if (!vms.newmessages && vms.oldmessages) {
- /* If we only have old messages start here */
- res = open_mailbox(&vms, vmu, 1);
- play_folder = 1;
- if (res == ERROR_LOCK_PATH)
- goto out;
- }
- }
-
- if (useadsi)
- adsi_status(chan, &vms);
- res = 0;
-
- /* Check to see if this is a new user */
- if (!strcasecmp(vmu->mailbox, vmu->password) &&
- (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
- if (ast_play_and_wait(chan, "vm-newuser") == -1)
- ast_log(LOG_WARNING, "Couldn't stream new user file\n");
- cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
- if ((cmd == 't') || (cmd == '#')) {
- /* Timeout */
- res = 0;
- goto out;
- } else if (cmd < 0) {
- /* Hangup */
- res = -1;
- goto out;
- }
- }
-#ifdef IMAP_STORAGE
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
- if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
- if (option_debug)
- ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
- cmd = ast_play_and_wait(chan, "vm-mailboxfull");
- }
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
- if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
- ast_log(LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
- cmd = ast_play_and_wait(chan, "vm-mailboxfull");
- }
-#endif
- if (play_auto) {
- cmd = '1';
- } else {
- cmd = vm_intro(chan, vmu, &vms);
- }
-
- vms.repeats = 0;
- vms.starting = 1;
- while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
- /* Run main menu */
- switch (cmd) {
- case '1':
- vms.curmsg = 0;
- /* Fall through */
- case '5':
- cmd = vm_browse_messages(chan, &vms, vmu);
- break;
- case '2': /* Change folders */
- if (useadsi)
- adsi_folders(chan, 0, "Change to folder...");
- cmd = get_folder2(chan, "vm-changeto", 0);
- if (cmd == '#') {
- cmd = 0;
- } else if (cmd > 0) {
- cmd = cmd - '0';
- res = close_mailbox(&vms, vmu);
- if (res == ERROR_LOCK_PATH)
- goto out;
- res = open_mailbox(&vms, vmu, cmd);
- if (res == ERROR_LOCK_PATH)
- goto out;
- play_folder = cmd;
- cmd = 0;
- }
- if (useadsi)
- adsi_status2(chan, &vms);
-
- if (!cmd)
- cmd = vm_play_folder_name(chan, vms.vmbox);
-
- vms.starting = 1;
- break;
- case '3': /* Advanced options */
- cmd = 0;
- vms.repeats = 0;
- while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
- switch (cmd) {
- case '1': /* Reply */
- if (vms.lastmsg > -1 && !vms.starting) {
- cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
- if (cmd == ERROR_LOCK_PATH) {
- res = cmd;
- goto out;
- }
- } else
- cmd = ast_play_and_wait(chan, "vm-sorry");
- cmd = 't';
- break;
- case '2': /* Callback */
- if (option_verbose > 2 && !vms.starting)
- ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
- if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
- cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
- if (cmd == 9) {
- silentexit = 1;
- goto out;
- } else if (cmd == ERROR_LOCK_PATH) {
- res = cmd;
- goto out;
- }
- }
- else
- cmd = ast_play_and_wait(chan, "vm-sorry");
- cmd = 't';
- break;
- case '3': /* Envelope */
- if (vms.lastmsg > -1 && !vms.starting) {
- cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
- if (cmd == ERROR_LOCK_PATH) {
- res = cmd;
- goto out;
- }
- } else
- cmd = ast_play_and_wait(chan, "vm-sorry");
- cmd = 't';
- break;
- case '4': /* Dialout */
- if (!ast_strlen_zero(vmu->dialout)) {
- cmd = dialout(chan, vmu, NULL, vmu->dialout);
- if (cmd == 9) {
- silentexit = 1;
- goto out;
- }
- }
- else
- cmd = ast_play_and_wait(chan, "vm-sorry");
- cmd = 't';
- break;
-
- case '5': /* Leave VoiceMail */
- if (ast_test_flag(vmu, VM_SVMAIL)) {
- cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
- if (cmd == ERROR_LOCK_PATH) {
- res = cmd;
- ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
- goto out;
- }
- } else
- cmd = ast_play_and_wait(chan,"vm-sorry");
- cmd='t';
- break;
-
- case '*': /* Return to main menu */
- cmd = 't';
- break;
-
- default:
- cmd = 0;
- if (!vms.starting) {
- cmd = ast_play_and_wait(chan, "vm-toreply");
- }
- if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
- cmd = ast_play_and_wait(chan, "vm-tocallback");
- }
- if (!cmd && !vms.starting) {
- cmd = ast_play_and_wait(chan, "vm-tohearenv");
- }
- if (!ast_strlen_zero(vmu->dialout) && !cmd) {
- cmd = ast_play_and_wait(chan, "vm-tomakecall");
- }
- if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
- cmd=ast_play_and_wait(chan, "vm-leavemsg");
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-starmain");
- if (!cmd)
- cmd = ast_waitfordigit(chan,6000);
- if (!cmd)
- vms.repeats++;
- if (vms.repeats > 3)
- cmd = 't';
- }
- }
- if (cmd == 't') {
- cmd = 0;
- vms.repeats = 0;
- }
- break;
- case '4':
- if (vms.curmsg > 0) {
- vms.curmsg--;
- cmd = play_message(chan, vmu, &vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-nomore");
- }
- break;
- case '6':
- if (vms.curmsg < vms.lastmsg) {
- vms.curmsg++;
- cmd = play_message(chan, vmu, &vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-nomore");
- }
- break;
- case '7':
- if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
- vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
- if (useadsi)
- adsi_delete(chan, &vms);
- if (vms.deleted[vms.curmsg]) {
- if (play_folder == 0)
- vms.newmessages--;
- else if (play_folder == 1)
- vms.oldmessages--;
- cmd = ast_play_and_wait(chan, "vm-deleted");
- }
- else {
- if (play_folder == 0)
- vms.newmessages++;
- else if (play_folder == 1)
- vms.oldmessages++;
- cmd = ast_play_and_wait(chan, "vm-undeleted");
- }
- if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
- if (vms.curmsg < vms.lastmsg) {
- vms.curmsg++;
- cmd = play_message(chan, vmu, &vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-nomore");
- }
- }
- } else /* Delete not valid if we haven't selected a message */
- cmd = 0;
-#ifdef IMAP_STORAGE
- deleted = 1;
-#endif
- break;
-
- case '8':
- if (vms.lastmsg > -1) {
- cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
- if (cmd == ERROR_LOCK_PATH) {
- res = cmd;
- goto out;
- }
- } else
- cmd = ast_play_and_wait(chan, "vm-nomore");
- break;
- case '9':
- if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
- /* No message selected */
- cmd = 0;
- break;
- }
- if (useadsi)
- adsi_folders(chan, 1, "Save to folder...");
- cmd = get_folder2(chan, "vm-savefolder", 1);
- box = 0; /* Shut up compiler */
- if (cmd == '#') {
- cmd = 0;
- break;
- } else if (cmd > 0) {
- box = cmd = cmd - '0';
- cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
- if (cmd == ERROR_LOCK_PATH) {
- res = cmd;
- goto out;
-#ifdef IMAP_STORAGE
- } else if (cmd == 10) {
- goto out;
-#endif
- } else if (!cmd) {
- vms.deleted[vms.curmsg] = 1;
- } else {
- vms.deleted[vms.curmsg] = 0;
- vms.heard[vms.curmsg] = 0;
- }
- }
- make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
- if (useadsi)
- adsi_message(chan, &vms);
- snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
- if (!cmd) {
- cmd = ast_play_and_wait(chan, "vm-message");
- if (!cmd)
- cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-savedto");
- if (!cmd)
- cmd = vm_play_folder_name(chan, vms.fn);
- } else {
- cmd = ast_play_and_wait(chan, "vm-mailboxfull");
- }
- if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
- if (vms.curmsg < vms.lastmsg) {
- vms.curmsg++;
- cmd = play_message(chan, vmu, &vms);
- } else {
- cmd = ast_play_and_wait(chan, "vm-nomore");
- }
- }
- break;
- case '*':
- if (!vms.starting) {
- cmd = ast_play_and_wait(chan, "vm-onefor");
- if (!cmd)
- cmd = vm_play_folder_name(chan, vms.vmbox);
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-opts");
- if (!cmd)
- cmd = vm_instructions(chan, &vms, 1);
- } else
- cmd = 0;
- break;
- case '0':
- cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
- if (useadsi)
- adsi_status(chan, &vms);
- break;
- default: /* Nothing */
- cmd = vm_instructions(chan, &vms, 0);
- break;
- }
- }
- if ((cmd == 't') || (cmd == '#')) {
- /* Timeout */
- res = 0;
- } else {
- /* Hangup */
- res = -1;
- }
-
-out:
- if (res > -1) {
- ast_stopstream(chan);
- adsi_goodbye(chan);
- if (valid) {
- if (silentexit)
- res = ast_play_and_wait(chan, "vm-dialout");
- else
- res = ast_play_and_wait(chan, "vm-goodbye");
- if (res > 0)
- res = 0;
- }
- if (useadsi)
- ast_adsi_unload_session(chan);
- }
- if (vmu)
- close_mailbox(&vms, vmu);
- if (valid) {
- snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
- manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
- run_externnotify(vmu->context, vmu->mailbox);
- }
-#ifdef IMAP_STORAGE
- /* expunge message - use UID Expunge if supported on IMAP server*/
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
- if (vmu && deleted == 1 && expungeonhangup == 1) {
-#ifdef HAVE_IMAP_TK2006
- if (LEVELUIDPLUS (vms.mailstream)) {
- mail_expunge_full(vms.mailstream,NIL,EX_UID);
- } else
-#endif
- mail_expunge(vms.mailstream);
- }
- /* before we delete the state, we should copy pertinent info
- * back to the persistent model */
- vmstate_delete(&vms);
-#endif
- if (vmu)
- free_user(vmu);
- if (vms.deleted)
- free(vms.deleted);
- if (vms.heard)
- free(vms.heard);
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int vm_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- char *tmp;
- struct leave_vm_options leave_options;
- struct ast_flags flags = { 0 };
- static int deprecate_warning = 0;
- char *opts[OPT_ARG_ARRAY_SIZE];
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(argv0);
- AST_APP_ARG(argv1);
- );
-
- u = ast_module_user_add(chan);
-
- memset(&leave_options, 0, sizeof(leave_options));
-
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- if (!ast_strlen_zero(data)) {
- tmp = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, tmp);
- if (args.argc == 2) {
- if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
- ast_module_user_remove(u);
- return -1;
- }
- ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
- if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
- int gain;
-
- if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
- ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
- ast_module_user_remove(u);
- return -1;
- } else {
- leave_options.record_gain = (signed char) gain;
- }
- }
- } else {
- /* old style options parsing */
- int old = 0;
- char *orig_argv0 = args.argv0;
- while (*(args.argv0)) {
- if (*(args.argv0) == 's') {
- old = 1;
- ast_set_flag(&leave_options, OPT_SILENT);
- } else if (*(args.argv0) == 'b') {
- old = 1;
- ast_set_flag(&leave_options, OPT_BUSY_GREETING);
- } else if (*(args.argv0) == 'u') {
- old = 1;
- ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
- } else if (*(args.argv0) == 'j') {
- old = 1;
- ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
- } else
- break;
- (args.argv0)++;
- }
- if (!deprecate_warning && old) {
- deprecate_warning = 1;
- ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
- ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
- }
- }
- } else {
- char tmp[256];
- res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
- if (res < 0) {
- ast_module_user_remove(u);
- return res;
- }
- if (ast_strlen_zero(tmp)) {
- ast_module_user_remove(u);
- return 0;
- }
- args.argv0 = ast_strdupa(tmp);
- }
-
- res = leave_voicemail(chan, args.argv0, &leave_options);
-
- if (res == ERROR_LOCK_PATH) {
- ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
- /*Send the call to n+101 priority, where n is the current priority*/
- if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
- ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- res = 0;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static struct ast_vm_user *find_or_create(char *context, char *mbox)
-{
- struct ast_vm_user *vmu;
- AST_LIST_TRAVERSE(&users, vmu, list) {
- if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
- break;
- if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
- break;
- }
-
- if (!vmu) {
- if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
- ast_copy_string(vmu->context, context, sizeof(vmu->context));
- ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
- AST_LIST_INSERT_TAIL(&users, vmu, list);
- }
- }
- return vmu;
-}
-
-static int append_mailbox(char *context, char *mbox, char *data)
-{
- /* Assumes lock is already held */
- char *tmp;
- char *stringp;
- char *s;
- struct ast_vm_user *vmu;
-
- tmp = ast_strdupa(data);
-
- if ((vmu = find_or_create(context, mbox))) {
- populate_defaults(vmu);
-
- stringp = tmp;
- if ((s = strsep(&stringp, ",")))
- ast_copy_string(vmu->password, s, sizeof(vmu->password));
- if (stringp && (s = strsep(&stringp, ",")))
- ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
- if (stringp && (s = strsep(&stringp, ",")))
- ast_copy_string(vmu->email, s, sizeof(vmu->email));
- if (stringp && (s = strsep(&stringp, ",")))
- ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
- if (stringp && (s = strsep(&stringp, ",")))
- apply_options(vmu, s);
- }
- return 0;
-}
-
-static int vm_box_exists(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- struct ast_vm_user svm;
- char *context, *box;
- int priority_jump = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(mbox);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- box = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, box);
-
- if (args.options) {
- if (strchr(args.options, 'j'))
- priority_jump = 1;
- }
-
- if ((context = strchr(args.mbox, '@'))) {
- *context = '\0';
- context++;
- }
-
- if (find_user(&svm, context, args.mbox)) {
- pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
- if (priority_jump || ast_opt_priority_jumping)
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
- ast_log(LOG_WARNING, "VM box %s@%s exists, but extension %s, priority %d doesn't exist\n", box, context, chan->exten, chan->priority + 101);
- } else
- pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
- ast_module_user_remove(u);
- return 0;
-}
-
-static int vmauthenticate(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
- struct ast_vm_user vmus;
- char *options = NULL;
- int silent = 0, skipuser = 0;
- int res = -1;
-
- u = ast_module_user_add(chan);
-
- if (s) {
- s = ast_strdupa(s);
- user = strsep(&s, "|");
- options = strsep(&s, "|");
- if (user) {
- s = user;
- user = strsep(&s, "@");
- context = strsep(&s, "");
- if (!ast_strlen_zero(user))
- skipuser++;
- ast_copy_string(mailbox, user, sizeof(mailbox));
- }
- }
-
- if (options) {
- silent = (strchr(options, 's')) != NULL;
- }
-
- if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
- pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
- pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
- ast_play_and_wait(chan, "auth-thankyou");
- res = 0;
- }
-
- ast_module_user_remove(u);
- return res;
-}
-
-static char voicemail_show_users_help[] =
-"Usage: voicemail show users [for <context>]\n"
-" Lists all mailboxes currently set up\n";
-
-static char voicemail_show_zones_help[] =
-"Usage: voicemail show zones\n"
-" Lists zone message formats\n";
-
-static int handle_voicemail_show_users(int fd, int argc, char *argv[])
-{
- struct ast_vm_user *vmu;
- char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
-
- if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
- else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&users);
- if (!AST_LIST_EMPTY(&users)) {
- if (argc == 3)
- ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
- else {
- int count = 0;
- AST_LIST_TRAVERSE(&users, vmu, list) {
- if (!strcmp(argv[4],vmu->context))
- count++;
- }
- if (count) {
- ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
- } else {
- ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
- AST_LIST_UNLOCK(&users);
- return RESULT_FAILURE;
- }
- }
- AST_LIST_TRAVERSE(&users, vmu, list) {
- int newmsgs = 0, oldmsgs = 0;
- char count[12], tmp[256] = "";
-
- if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
- snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
- inboxcount(tmp, &newmsgs, &oldmsgs);
- snprintf(count,sizeof(count),"%d",newmsgs);
- ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
- }
- }
- } else {
- ast_cli(fd, "There are no voicemail users currently defined\n");
- AST_LIST_UNLOCK(&users);
- return RESULT_FAILURE;
- }
- AST_LIST_UNLOCK(&users);
- return RESULT_SUCCESS;
-}
-
-static int handle_voicemail_show_zones(int fd, int argc, char *argv[])
-{
- struct vm_zone *zone;
- char *output_format = "%-15s %-20s %-45s\n";
- int res = RESULT_SUCCESS;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&zones);
- if (!AST_LIST_EMPTY(&zones)) {
- ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
- AST_LIST_TRAVERSE(&zones, zone, list) {
- ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
- }
- } else {
- ast_cli(fd, "There are no voicemail zones currently defined\n");
- res = RESULT_FAILURE;
- }
- AST_LIST_UNLOCK(&zones);
-
- return res;
-}
-
-static char *complete_voicemail_show_users(const char *line, const char *word, int pos, int state)
-{
- int which = 0;
- int wordlen;
- struct ast_vm_user *vmu;
- const char *context = "";
-
- /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
- if (pos > 4)
- return NULL;
- if (pos == 3)
- return (state == 0) ? ast_strdup("for") : NULL;
- wordlen = strlen(word);
- AST_LIST_TRAVERSE(&users, vmu, list) {
- if (!strncasecmp(word, vmu->context, wordlen)) {
- if (context && strcmp(context, vmu->context) && ++which > state)
- return ast_strdup(vmu->context);
- /* ignore repeated contexts ? */
- context = vmu->context;
- }
- }
- return NULL;
-}
-
-static struct ast_cli_entry cli_show_voicemail_users_deprecated = {
- { "show", "voicemail", "users", NULL },
- handle_voicemail_show_users, NULL,
- NULL, complete_voicemail_show_users };
-
-static struct ast_cli_entry cli_show_voicemail_zones_deprecated = {
- { "show", "voicemail", "zones", NULL },
- handle_voicemail_show_zones, NULL,
- NULL, NULL };
-
-static struct ast_cli_entry cli_voicemail[] = {
- { { "voicemail", "show", "users", NULL },
- handle_voicemail_show_users, "List defined voicemail boxes",
- voicemail_show_users_help, complete_voicemail_show_users, &cli_show_voicemail_users_deprecated },
-
- { { "voicemail", "show", "zones", NULL },
- handle_voicemail_show_zones, "List zone message formats",
- voicemail_show_zones_help, NULL, &cli_show_voicemail_zones_deprecated },
-};
-
-static int load_config(void)
-{
- struct ast_vm_user *cur;
- struct vm_zone *zcur;
- struct ast_config *cfg, *ucfg;
- char *cat;
- struct ast_variable *var;
- const char *notifystr = NULL;
- const char *smdistr = NULL;
- const char *astattach;
- const char *astsearch;
- const char *astsaycid;
- const char *send_voicemail;
-#ifdef IMAP_STORAGE
- const char *imap_server;
- const char *imap_port;
- const char *imap_flags;
- const char *imap_folder;
- const char *auth_user;
- const char *auth_password;
- const char *expunge_on_hangup;
-#endif
- const char *astcallop;
- const char *astreview;
- const char *asttempgreetwarn;
- const char *astskipcmd;
- const char *asthearenv;
- const char *astsaydurationinfo;
- const char *astsaydurationminfo;
- const char *silencestr;
- const char *maxmsgstr;
- const char *astdirfwd;
- const char *thresholdstr;
- const char *fmt;
- const char *astemail;
- const char *ucontext;
- const char *astmailcmd = SENDMAIL;
- const char *astforcename;
- const char *astforcegreet;
- const char *s;
- char *q,*stringp;
- const char *dialoutcxt = NULL;
- const char *callbackcxt = NULL;
- const char *exitcxt = NULL;
- const char *extpc;
- const char *emaildateformatstr;
- const char *volgainstr;
- int x;
- int tmpadsi[4];
-
- cfg = ast_config_load(VOICEMAIL_CONFIG);
-
- AST_LIST_LOCK(&users);
- while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
- ast_set_flag(cur, VM_ALLOCED);
- free_user(cur);
- }
-
- AST_LIST_LOCK(&zones);
- while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list)))
- free_zone(zcur);
- AST_LIST_UNLOCK(&zones);
-
- memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
-
- if (cfg) {
- /* General settings */
-
- if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
- ucontext = "default";
- ast_copy_string(userscontext, ucontext, sizeof(userscontext));
- /* Attach voice message to mail message ? */
- if (!(astattach = ast_variable_retrieve(cfg, "general", "attach")))
- astattach = "yes";
- ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH);
-
- if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
- astsearch = "no";
- ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
-
- volgain = 0.0;
- if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
- sscanf(volgainstr, "%lf", &volgain);
-
-#ifdef ODBC_STORAGE
- strcpy(odbc_database, "asterisk");
- if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
- ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
- }
- strcpy(odbc_table, "voicemessages");
- if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
- ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
- }
-#endif
- /* Mail command */
- strcpy(mailcmd, SENDMAIL);
- if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
- ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
-
- maxsilence = 0;
- if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
- maxsilence = atoi(silencestr);
- if (maxsilence > 0)
- maxsilence *= 1000;
- }
-
- if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
- maxmsg = MAXMSG;
- } else {
- maxmsg = atoi(maxmsgstr);
- if (maxmsg <= 0) {
- ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
- maxmsg = MAXMSG;
- } else if (maxmsg > MAXMSGLIMIT) {
- ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
- maxmsg = MAXMSGLIMIT;
- }
- }
-
- /* Load date format config for voicemail mail */
- if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
- ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
- }
-
- /* External password changing command */
- if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
- ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
- }
-#ifdef IMAP_STORAGE
- /* IMAP server address */
- if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
- ast_copy_string(imapserver, imap_server, sizeof(imapserver));
- } else {
- ast_copy_string(imapserver,"localhost", sizeof(imapserver));
- }
- /* IMAP server port */
- if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
- ast_copy_string(imapport, imap_port, sizeof(imapport));
- } else {
- ast_copy_string(imapport,"143", sizeof(imapport));
- }
- /* IMAP server flags */
- if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
- ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
- }
- /* IMAP server master username */
- if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
- ast_copy_string(authuser, auth_user, sizeof(authuser));
- }
- /* IMAP server master password */
- if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
- ast_copy_string(authpassword, auth_password, sizeof(authpassword));
- }
- /* Expunge on exit */
- if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
- if (ast_false(expunge_on_hangup))
- expungeonhangup = 0;
- else
- expungeonhangup = 1;
- } else {
- expungeonhangup = 1;
- }
- /* IMAP voicemail folder */
- if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
- ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
- } else {
- ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
- }
-#endif
- /* External voicemail notify application */
-
- if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
- ast_copy_string(externnotify, notifystr, sizeof(externnotify));
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
- if (!strcasecmp(externnotify, "smdi")) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
- if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
- smdi_iface = ast_smdi_interface_find(smdistr);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
- smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
- }
-
- if (!smdi_iface) {
- ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
- externnotify[0] = '\0';
- }
- }
- } else {
- externnotify[0] = '\0';
- }
-
- /* Silence treshold */
- silencethreshold = 256;
- if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
- silencethreshold = atoi(thresholdstr);
-
- if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail")))
- astemail = ASTERISK_USERNAME;
- ast_copy_string(serveremail, astemail, sizeof(serveremail));
-
- vmmaxmessage = 0;
- if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
- if (sscanf(s, "%d", &x) == 1) {
- vmmaxmessage = x;
- } else {
- ast_log(LOG_WARNING, "Invalid max message time length\n");
- }
- }
-
- vmminmessage = 0;
- if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
- if (sscanf(s, "%d", &x) == 1) {
- vmminmessage = x;
- if (maxsilence <= vmminmessage)
- ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
- } else {
- ast_log(LOG_WARNING, "Invalid min message time length\n");
- }
- }
- fmt = ast_variable_retrieve(cfg, "general", "format");
- if (!fmt)
- fmt = "wav";
- ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
-
- skipms = 3000;
- if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
- if (sscanf(s, "%d", &x) == 1) {
- maxgreet = x;
- } else {
- ast_log(LOG_WARNING, "Invalid max message greeting length\n");
- }
- }
-
- if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
- if (sscanf(s, "%d", &x) == 1) {
- skipms = x;
- } else {
- ast_log(LOG_WARNING, "Invalid skipms value\n");
- }
- }
-
- maxlogins = 3;
- if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
- if (sscanf(s, "%d", &x) == 1) {
- maxlogins = x;
- } else {
- ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
- }
- }
-
- /* Force new user to record name ? */
- if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename")))
- astforcename = "no";
- ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
-
- /* Force new user to record greetings ? */
- if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings")))
- astforcegreet = "no";
- ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
-
- if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
- stringp = ast_strdupa(s);
- for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
- if (!ast_strlen_zero(stringp)) {
- q = strsep(&stringp,",");
- while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
- q++;
- ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
- } else {
- cidinternalcontexts[x][0] = '\0';
- }
- }
- }
- if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
- if (option_debug)
- ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
- astreview = "no";
- }
- ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW);
-
- /*Temperary greeting reminder */
- if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
- asttempgreetwarn = "no";
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
- }
- ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
-
- if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
- if (option_debug)
- ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
- astcallop = "no";
- }
- ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);
-
- if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
- if (option_debug)
- ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
- astsaycid = "no";
- }
- ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID);
-
- if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
- if (option_debug)
- ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
- send_voicemail = "no";
- }
- ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
-
- if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
- if (option_debug)
- ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
- asthearenv = "yes";
- }
- ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE);
-
- if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
- if (option_debug)
- ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
- astsaydurationinfo = "yes";
- }
- ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);
-
- saydurationminfo = 2;
- if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
- if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
- saydurationminfo = x;
- } else {
- ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
- }
- }
-
- if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
- if (option_debug)
- ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
- astskipcmd = "no";
- }
- ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
-
- if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
- ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
- if (option_debug)
- ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
- } else {
- dialcontext[0] = '\0';
- }
-
- if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
- ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
- if (option_debug)
- ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
- } else {
- callcontext[0] = '\0';
- }
-
- if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
- ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
- if (option_debug)
- ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
- } else {
- exitcontext[0] = '\0';
- }
-
- if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory")))
- astdirfwd = "no";
- ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD);
- if ((ucfg = ast_config_load("users.conf"))) {
- for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
- if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
- continue;
- if ((cur = find_or_create(userscontext, cat))) {
- populate_defaults(cur);
- apply_options_full(cur, ast_variable_browse(ucfg, cat));
- ast_copy_string(cur->context, userscontext, sizeof(cur->context));
- }
- }
- ast_config_destroy(ucfg);
- }
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- if (strcasecmp(cat, "general")) {
- var = ast_variable_browse(cfg, cat);
- if (strcasecmp(cat, "zonemessages")) {
- /* Process mailboxes in this context */
- while (var) {
- append_mailbox(cat, var->name, var->value);
- var = var->next;
- }
- } else {
- /* Timezones in this context */
- while (var) {
- struct vm_zone *z;
- if ((z = ast_malloc(sizeof(*z)))) {
- char *msg_format, *timezone;
- msg_format = ast_strdupa(var->value);
- timezone = strsep(&msg_format, "|");
- if (msg_format) {
- ast_copy_string(z->name, var->name, sizeof(z->name));
- ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
- ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
- AST_LIST_LOCK(&zones);
- AST_LIST_INSERT_HEAD(&zones, z, list);
- AST_LIST_UNLOCK(&zones);
- } else {
- ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
- free(z);
- }
- } else {
- free(z);
- AST_LIST_UNLOCK(&users);
- ast_config_destroy(cfg);
- return -1;
- }
- var = var->next;
- }
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
- memset(fromstring,0,sizeof(fromstring));
- memset(pagerfromstring,0,sizeof(pagerfromstring));
- memset(emailtitle,0,sizeof(emailtitle));
- strcpy(charset, "ISO-8859-1");
- if (emailbody) {
- free(emailbody);
- emailbody = NULL;
- }
- if (emailsubject) {
- free(emailsubject);
- emailsubject = NULL;
- }
- if (pagerbody) {
- free(pagerbody);
- pagerbody = NULL;
- }
- if (pagersubject) {
- free(pagersubject);
- pagersubject = NULL;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
- ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
- if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
- ast_copy_string(fromstring,s,sizeof(fromstring));
- if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
- ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
- if ((s = ast_variable_retrieve(cfg, "general", "charset")))
- ast_copy_string(charset,s,sizeof(charset));
- if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
- sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
- for (x = 0; x < 4; x++) {
- memcpy(&adsifdn[x], &tmpadsi[x], 1);
- }
- }
- if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
- sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
- for (x = 0; x < 4; x++) {
- memcpy(&adsisec[x], &tmpadsi[x], 1);
- }
- }
- if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
- if (atoi(s)) {
- adsiver = atoi(s);
- }
- if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
- ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
- ast_copy_string(emailtitle,s,sizeof(emailtitle));
- }
- if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
- emailsubject = ast_strdup(s);
- if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
- char *tmpread, *tmpwrite;
- emailbody = ast_strdup(s);
-
- /* substitute strings \t and \n into the appropriate characters */
- tmpread = tmpwrite = emailbody;
- while ((tmpwrite = strchr(tmpread,'\\'))) {
- switch (tmpwrite[1]) {
- case 'r':
- memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
- *tmpwrite = '\r';
- break;
- case 'n':
- memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
- *tmpwrite = '\n';
- break;
- case 't':
- memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
- *tmpwrite = '\t';
- break;
- default:
- ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
- }
- tmpread = tmpwrite + 1;
- }
- }
- if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
- pagersubject = ast_strdup(s);
- if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
- char *tmpread, *tmpwrite;
- pagerbody = ast_strdup(s);
-
- /* substitute strings \t and \n into the appropriate characters */
- tmpread = tmpwrite = pagerbody;
- while ((tmpwrite = strchr(tmpread, '\\'))) {
- switch (tmpwrite[1]) {
- case 'r':
- memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
- *tmpwrite = '\r';
- break;
- case 'n':
- memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
- *tmpwrite = '\n';
- break;
- case 't':
- memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
- *tmpwrite = '\t';
- break;
- default:
- ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
- }
- tmpread = tmpwrite + 1;
- }
- }
- AST_LIST_UNLOCK(&users);
- ast_config_destroy(cfg);
- return 0;
- } else {
- AST_LIST_UNLOCK(&users);
- ast_log(LOG_WARNING, "Failed to load configuration file.\n");
- return 0;
- }
-}
-
-static int reload(void)
-{
- return(load_config());
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
- res |= ast_unregister_application(app2);
- res |= ast_unregister_application(app3);
- res |= ast_unregister_application(app4);
- ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
- ast_uninstall_vm_functions();
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
- char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
- free(adsi_loaded);
- if (!adsi_loaded) {
- /* If embedded, res_adsi may be known as "res_adsi" not "res_adsi.so" */
- adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
- ast_free(adsi_loaded);
- if (!adsi_loaded) {
- ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
- return AST_MODULE_LOAD_DECLINE;
- }
- }
-
- my_umask = umask(0);
- umask(my_umask);
- res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
- res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
- res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
- res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
- if (res)
- return(res);
-
- if ((res=load_config())) {
- return(res);
- }
-
- ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
-
- /* compute the location of the voicemail spool directory */
- snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
-
- ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
-
- return res;
-}
-
-static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
-{
- int cmd = 0;
- char destination[80] = "";
- int retries = 0;
-
- if (!num) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
- while (retries < 3 && cmd != 't') {
- destination[1] = '\0';
- destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
- if (!cmd)
- destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
- if (!cmd)
- destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
- if (!cmd) {
- cmd = ast_waitfordigit(chan, 6000);
- if (cmd)
- destination[0] = cmd;
- }
- if (!cmd) {
- retries++;
- } else {
-
- if (cmd < 0)
- return 0;
- if (cmd == '*') {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
- return 0;
- }
- if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0)
- retries++;
- else
- cmd = 't';
- }
- }
- if (retries >= 3) {
- return 0;
- }
-
- } else {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
- ast_copy_string(destination, num, sizeof(destination));
- }
-
- if (!ast_strlen_zero(destination)) {
- if (destination[strlen(destination) -1 ] == '*')
- return 0;
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
- ast_copy_string(chan->exten, destination, sizeof(chan->exten));
- ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
- chan->priority = 0;
- return 9;
- }
- return 0;
-}
-
-static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
-{
- int res = 0;
-#ifdef IMAP_STORAGE
- char origtimeS[256],cidS[256],contextS[256];
- char *header_content,*temp;
-#endif
- char filename[PATH_MAX];
- struct ast_config *msg_cfg = NULL;
- const char *origtime, *context;
- char *cid, *name, *num;
- int retries = 0;
-
- vms->starting = 0;
-#ifdef IMAP_STORAGE
- /* START HERE */
- /* get the message info!! */
- if (option_debug > 2)
- ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
- if (vms->msgArray[vms->curmsg] == 0) {
- ast_log (LOG_WARNING,"Trying to access unknown message\n");
- return -1;
- }
-
- /* This will only work for new messages... */
- header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
- /* empty string means no valid header */
- if (ast_strlen_zero(header_content)) {
- ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
- return -1;
- }
-
- /* Get info from headers!! */
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
-
- if (temp)
- ast_copy_string(cidS,temp, sizeof(cidS));
- else
- cidS[0] = '\0';
-
- cid = &cidS[0];
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
-
- if (temp)
- ast_copy_string(contextS,temp, sizeof(contextS));
- else
- contextS[0] = '\0';
-
- context = &contextS[0];
- temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
-
- if (temp)
- ast_copy_string(origtimeS,temp, sizeof(origtimeS));
- else
- origtimeS[0] = '\0';
-
- origtime = &origtimeS[0];
-
- ast_copy_string(filename, "IMAP_STORAGE", sizeof(filename));
-#else
- make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
-
- /* Retrieve info from VM attribute file */
-
- make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
- snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
- RETRIEVE(vms->curdir, vms->curmsg);
- msg_cfg = ast_config_load(filename);
- DISPOSE(vms->curdir, vms->curmsg);
- if (!msg_cfg) {
- ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
- return 0;
- }
-
- if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
- ast_config_destroy(msg_cfg);
- return 0;
- }
-
- cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
-
- context = ast_variable_retrieve(msg_cfg, "message", "context");
- if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
- context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
-#endif
- switch (option) {
- case 3:
- if (!res)
- res = play_message_datetime(chan, vmu, origtime, filename);
- if (!res)
- res = play_message_callerid(chan, vms, cid, context, 0);
-
- res = 't';
- break;
-
- case 2: /* Call back */
-
- if (ast_strlen_zero(cid))
- break;
-
- ast_callerid_parse(cid, &name, &num);
- while ((res > -1) && (res != 't')) {
- switch (res) {
- case '1':
- if (num) {
- /* Dial the CID number */
- res = dialout(chan, vmu, num, vmu->callback);
- if (res) {
- ast_config_destroy(msg_cfg);
- return 9;
- }
- } else {
- res = '2';
- }
- break;
-
- case '2':
- /* Want to enter a different number, can only do this if there's a dialout context for this user */
- if (!ast_strlen_zero(vmu->dialout)) {
- res = dialout(chan, vmu, NULL, vmu->dialout);
- if (res) {
- ast_config_destroy(msg_cfg);
- return 9;
- }
- } else {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
- res = ast_play_and_wait(chan, "vm-sorry");
- }
- ast_config_destroy(msg_cfg);
- return res;
- case '*':
- res = 't';
- break;
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '0':
-
- res = ast_play_and_wait(chan, "vm-sorry");
- retries++;
- break;
- default:
- if (num) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
- res = ast_play_and_wait(chan, "vm-num-i-have");
- if (!res)
- res = play_message_callerid(chan, vms, num, vmu->context, 1);
- if (!res)
- res = ast_play_and_wait(chan, "vm-tocallnum");
- /* Only prompt for a caller-specified number if there is a dialout context specified */
- if (!ast_strlen_zero(vmu->dialout)) {
- if (!res)
- res = ast_play_and_wait(chan, "vm-calldiffnum");
- }
- } else {
- res = ast_play_and_wait(chan, "vm-nonumber");
- if (!ast_strlen_zero(vmu->dialout)) {
- if (!res)
- res = ast_play_and_wait(chan, "vm-toenternumber");
- }
- }
- if (!res)
- res = ast_play_and_wait(chan, "vm-star-cancel");
- if (!res)
- res = ast_waitfordigit(chan, 6000);
- if (!res) {
- retries++;
- if (retries > 3)
- res = 't';
- }
- break;
-
- }
- if (res == 't')
- res = 0;
- else if (res == '*')
- res = -1;
- }
- break;
-
- case 1: /* Reply */
- /* Send reply directly to sender */
- if (ast_strlen_zero(cid))
- break;
-
- ast_callerid_parse(cid, &name, &num);
- if (!num) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
- if (!res)
- res = ast_play_and_wait(chan, "vm-nonumber");
- ast_config_destroy(msg_cfg);
- return res;
- } else {
- struct ast_vm_user vmu2;
- if (find_user(&vmu2, vmu->context, num)) {
- struct leave_vm_options leave_options;
- char mailbox[AST_MAX_EXTENSION * 2 + 2];
- snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
-
- memset(&leave_options, 0, sizeof(leave_options));
- leave_options.record_gain = record_gain;
- res = leave_voicemail(chan, mailbox, &leave_options);
- if (!res)
- res = 't';
- ast_config_destroy(msg_cfg);
- return res;
- } else {
- /* Sender has no mailbox, can't reply */
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
- ast_play_and_wait(chan, "vm-nobox");
- res = 't';
- ast_config_destroy(msg_cfg);
- return res;
- }
- }
- res = 0;
-
- break;
- }
-
-#ifndef IMAP_STORAGE
- ast_config_destroy(msg_cfg);
-
- if (!res) {
- make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
- vms->heard[msg] = 1;
- res = wait_file(chan, vms, vms->fn);
- }
-#endif
- return res;
-}
-
-static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt,
- int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir,
- signed char record_gain, struct vm_state *vms)
-{
- /* Record message & let caller review or re-record it, or set options if applicable */
- int res = 0;
- int cmd = 0;
- int max_attempts = 3;
- int attempts = 0;
- int recorded = 0;
- int message_exists = 0;
- signed char zero_gain = 0;
- char tempfile[PATH_MAX];
- char *acceptdtmf = "#";
- char *canceldtmf = "";
-
- /* Note that urgent and private are for flagging messages as such in the future */
-
- /* barf if no pointer passed to store duration in */
- if (duration == NULL) {
- ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
- return -1;
- }
-
- if (!outsidecaller)
- snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
- else
- ast_copy_string(tempfile, recordfile, sizeof(tempfile));
-
- cmd = '3'; /* Want to start by recording */
-
- while ((cmd >= 0) && (cmd != 't')) {
- switch (cmd) {
- case '1':
- if (!message_exists) {
- /* In this case, 1 is to record a message */
- cmd = '3';
- break;
- } else {
- /* Otherwise 1 is to save the existing message */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
- if (!outsidecaller)
- ast_filerename(tempfile, recordfile, NULL);
- ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
- if (!outsidecaller) {
- STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
- DISPOSE(recordfile, -1);
- }
- cmd = 't';
- return res;
- }
- case '2':
- /* Review */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
- cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
- break;
- case '3':
- message_exists = 0;
- /* Record */
- if (recorded == 1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
- }
- if (recorded && outsidecaller) {
- cmd = ast_play_and_wait(chan, INTRO);
- cmd = ast_play_and_wait(chan, "beep");
- }
- recorded = 1;
- /* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */
- if (record_gain)
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
- if (ast_test_flag(vmu, VM_OPERATOR))
- canceldtmf = "0";
- cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
- if (record_gain)
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
- if (cmd == -1) {
- /* User has hung up, no options to give */
- if (!outsidecaller) {
- /* user was recording a greeting and they hung up, so let's delete the recording. */
- ast_filedelete(tempfile, NULL);
- }
- return cmd;
- }
- if (cmd == '0') {
- break;
- } else if (cmd == '*') {
- break;
- }
-#if 0
- else if (vmu->review && (*duration < 5)) {
- /* Message is too short */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
- cmd = ast_play_and_wait(chan, "vm-tooshort");
- cmd = ast_filedelete(tempfile, NULL);
- break;
- }
- else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
- /* Message is all silence */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
- cmd = ast_filedelete(tempfile, NULL);
- cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-speakup");
- break;
- }
-#endif
- else {
- /* If all is well, a message exists */
- message_exists = 1;
- cmd = 0;
- }
- break;
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '*':
- case '#':
- cmd = ast_play_and_wait(chan, "vm-sorry");
- break;
-#if 0
-/* XXX Commented out for the moment because of the dangers of deleting
- a message while recording (can put the message numbers out of sync) */
- case '*':
- /* Cancel recording, delete message, offer to take another message*/
- cmd = ast_play_and_wait(chan, "vm-deleted");
- cmd = ast_filedelete(tempfile, NULL);
- if (outsidecaller) {
- res = vm_exec(chan, NULL);
- return res;
- }
- else
- return 1;
-#endif
- case '0':
- if (!ast_test_flag(vmu, VM_OPERATOR)) {
- cmd = ast_play_and_wait(chan, "vm-sorry");
- break;
- }
- if (message_exists || recorded) {
- cmd = ast_play_and_wait(chan, "vm-saveoper");
- if (!cmd)
- cmd = ast_waitfordigit(chan, 3000);
- if (cmd == '1') {
- ast_play_and_wait(chan, "vm-msgsaved");
- cmd = '0';
- } else {
- ast_play_and_wait(chan, "vm-deleted");
- DELETE(recordfile, -1, recordfile);
- cmd = '0';
- }
- }
- return cmd;
- default:
- /* If the caller is an ouside caller, and the review option is enabled,
- allow them to review the message, but let the owner of the box review
- their OGM's */
- if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
- return cmd;
- if (message_exists) {
- cmd = ast_play_and_wait(chan, "vm-review");
- }
- else {
- cmd = ast_play_and_wait(chan, "vm-torerecord");
- if (!cmd)
- cmd = ast_waitfordigit(chan, 600);
- }
-
- if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
- cmd = ast_play_and_wait(chan, "vm-reachoper");
- if (!cmd)
- cmd = ast_waitfordigit(chan, 600);
- }
-#if 0
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
-#endif
- if (!cmd)
- cmd = ast_waitfordigit(chan, 6000);
- if (!cmd) {
- attempts++;
- }
- if (attempts > max_attempts) {
- cmd = 't';
- }
- }
- }
- if (outsidecaller)
- ast_play_and_wait(chan, "vm-goodbye");
- if (cmd == 't')
- cmd = 0;
- return cmd;
-}
-
-#ifdef IMAP_STORAGE
-
-static void write_file(char *filename, char *buffer, unsigned long len)
-{
- FILE *output;
-
- output = fopen (filename, "w");
- fwrite (buffer, len, 1, output);
- fclose (output);
-}
-
-void mm_searched(MAILSTREAM *stream, unsigned long number)
-{
- struct vm_state *vms;
- char *mailbox;
- char *user;
- mailbox = stream->mailbox;
- user = get_user_by_mailbox(mailbox);
- vms = get_vm_state_by_imapuser(user,2);
- if (vms) {
- if (option_debug > 2)
- ast_log (LOG_DEBUG, "saving mailbox message number %lu as message %d. Interactive set to %d\n",number,vms->vmArrayIndex,vms->interactive);
- vms->msgArray[vms->vmArrayIndex++] = number;
- } else {
- ast_log (LOG_ERROR, "No state found.\n");
- }
-}
-
-
-#if 0 /*No need for this. */
-/* MM status report
- * Accepts: MAIL stream
- */
-static void status(MAILSTREAM *stream)
-{
- unsigned long i;
- char *s, date[MAILTMPLEN];
- THREADER *thr;
- AUTHENTICATOR *auth;
- rfc822_date (date);
- ast_log (LOG_NOTICE,"%s\n",date);
- if (stream) {
- if (stream->mailbox)
- ast_log (LOG_NOTICE," %s mailbox: %s, %lu messages, %lu recent\n",
- stream->dtb->name, stream->mailbox, stream->nmsgs,stream->recent);
- else
- ast_log (LOG_NOTICE,"No mailbox is open on this stream\n");
- if (stream->user_flags[0]) {
- ast_log (LOG_NOTICE,"Keywords: %s\n", stream->user_flags[0]);
- for (i = 1; i < NUSERFLAGS && stream->user_flags[i]; ++i)
- ast_log (LOG_NOTICE," %s\n", stream->user_flags[i]);
- }
- if (!strcmp (stream->dtb->name, "imap")) {
- if (LEVELIMAP4rev1 (stream))
- s = "IMAP4rev1 (RFC 3501)";
- else if (LEVEL1730 (stream))
- s = "IMAP4 (RFC 1730)";
- else if (LEVELIMAP2bis (stream))
- s = "IMAP2bis";
- else if (LEVEL1176 (stream))
- s = "IMAP2 (RFC 1176)";
- else
- s = "IMAP2 (RFC 1064)";
- ast_log (LOG_NOTICE,"%s server %s\n", s, imap_host (stream));
- if (LEVELIMAP4 (stream)) {
- if ((i = (imap_cap(stream)->auth))) {
- s = "";
- ast_log (LOG_NOTICE,"Mutually-supported SASL mechanisms:\n");
- while ((auth = mail_lookup_auth (find_rightmost_bit (&i) + 1))) {
- ast_log (LOG_NOTICE," %s\n", auth->name);
- if (!strcmp (auth->name, "PLAIN"))
- s = "\n [LOGIN will not be listed here if PLAIN is supported]\n";
- }
- ast_log (LOG_NOTICE,s);
- }
- ast_log (LOG_NOTICE,"Supported standard extensions:\n");
- if (LEVELACL (stream))
- ast_log (LOG_NOTICE," Access Control lists (RFC 2086)\n");
- if (LEVELQUOTA (stream))
- ast_log (LOG_NOTICE," Quotas (RFC 2087)\n");
- if (LEVELLITERALPLUS (stream))
- ast_log (LOG_NOTICE," Non-synchronizing literals (RFC 2088)\n");
- if (LEVELIDLE (stream))
- ast_log (LOG_NOTICE," IDLE unsolicited update (RFC 2177)\n");
- if (LEVELMBX_REF (stream))
- ast_log (LOG_NOTICE," Mailbox referrals (RFC 2193)\n");
- if (LEVELLOG_REF (stream))
- ast_log (LOG_NOTICE," Login referrals (RFC 2221)\n");
- if (LEVELANONYMOUS (stream))
- ast_log (LOG_NOTICE," Anonymous access (RFC 2245)\n");
- if (LEVELNAMESPACE (stream))
- ast_log (LOG_NOTICE," Multiple namespaces (RFC 2342)\n");
- if (LEVELUIDPLUS (stream))
- ast_log (LOG_NOTICE," Extended UID behavior (RFC 2359)\n");
- if (LEVELSTARTTLS (stream))
- ast_log (LOG_NOTICE," Transport Layer Security (RFC 2595)\n");
- if (LEVELLOGINDISABLED (stream))
- ast_log (LOG_NOTICE," LOGIN command disabled (RFC 2595)\n");
- if (LEVELID (stream))
- ast_log (LOG_NOTICE," Implementation identity negotiation (RFC 2971)\n");
- if (LEVELCHILDREN (stream))
- ast_log (LOG_NOTICE," LIST children announcement (RFC 3348)\n");
- if (LEVELMULTIAPPEND (stream))
- ast_log (LOG_NOTICE," Atomic multiple APPEND (RFC 3502)\n");
- if (LEVELBINARY (stream))
- ast_log (LOG_NOTICE," Binary body content (RFC 3516)\n");
- ast_log (LOG_NOTICE,"Supported draft extensions:\n");
- if (LEVELUNSELECT (stream))
- ast_log (LOG_NOTICE," Mailbox unselect\n");
- if (LEVELSASLIR (stream))
- ast_log (LOG_NOTICE," SASL initial client response\n");
- if (LEVELSORT (stream))
- ast_log (LOG_NOTICE," Server-based sorting\n");
- if (LEVELTHREAD (stream)) {
- ast_log (LOG_NOTICE," Server-based threading:\n");
- for (thr = imap_cap(stream)->threader; thr; thr = thr->next)
- ast_log (LOG_NOTICE," %s\n", thr->name);
- }
- if (LEVELSCAN (stream))
- ast_log (LOG_NOTICE," Mailbox text scan\n");
- if ((i = imap_cap(stream)->extlevel)) {
- ast_log (LOG_NOTICE,"Supported BODYSTRUCTURE extensions:\n");
- switch (i) {
- case BODYEXTLOC:
- ast_log (LOG_NOTICE," location\n");
- case BODYEXTLANG:
- ast_log (LOG_NOTICE," language\n");
- case BODYEXTDSP:
- ast_log (LOG_NOTICE," disposition\n");
- case BODYEXTMD5:
- ast_log (LOG_NOTICE," MD5\n");
- }
- }
- }else
- ast_log (LOG_NOTICE,"\n");
- }
- }
-}
-#endif
-
-static struct ast_vm_user *find_user_realtime_imapuser(const char *imapuser)
-{
- struct ast_variable *var;
- struct ast_vm_user *vmu;
-
- vmu = ast_calloc(1, sizeof *vmu);
- if (!vmu)
- return NULL;
- ast_set_flag(vmu, VM_ALLOCED);
- populate_defaults(vmu);
-
- var = ast_load_realtime("voicemail", "imapuser", imapuser, NULL);
- if (var) {
- apply_options_full(vmu, var);
- ast_variables_destroy(var);
- return vmu;
- } else {
- free(vmu);
- return NULL;
- }
-}
-
-/* Interfaces to C-client */
-
-void mm_exists(MAILSTREAM * stream, unsigned long number)
-{
- /* mail_ping will callback here if new mail! */
- if (option_debug > 3)
- ast_log (LOG_DEBUG, "Entering EXISTS callback for message %ld\n", number);
- if (number == 0) return;
- set_update(stream);
-}
-
-
-void mm_expunged(MAILSTREAM * stream, unsigned long number)
-{
- /* mail_ping will callback here if expunged mail! */
- if (option_debug > 3)
- ast_log (LOG_DEBUG, "Entering EXPUNGE callback for message %ld\n", number);
- if (number == 0) return;
- set_update(stream);
-}
-
-
-void mm_flags(MAILSTREAM * stream, unsigned long number)
-{
- /* mail_ping will callback here if read mail! */
- if (option_debug > 3)
- ast_log (LOG_DEBUG, "Entering FLAGS callback for message %ld\n", number);
- if (number == 0) return;
- set_update(stream);
-}
-
-
-void mm_notify(MAILSTREAM * stream, char *string, long errflg)
-{
- mm_log (string, errflg);
-}
-
-
-void mm_list(MAILSTREAM * stream, int delim, char *mailbox, long attributes)
-{
- if (delimiter == '\0') {
- delimiter = delim;
- }
- if (option_debug > 4) {
- ast_log(LOG_DEBUG, "Delimiter set to %c and mailbox %s\n",delim, mailbox);
- if (attributes & LATT_NOINFERIORS)
- ast_log(LOG_DEBUG, "no inferiors\n");
- if (attributes & LATT_NOSELECT)
- ast_log(LOG_DEBUG, "no select\n");
- if (attributes & LATT_MARKED)
- ast_log(LOG_DEBUG, "marked\n");
- if (attributes & LATT_UNMARKED)
- ast_log(LOG_DEBUG, "unmarked\n");
- }
-}
-
-
-void mm_lsub(MAILSTREAM * stream, int delimiter, char *mailbox, long attributes)
-{
- if (option_debug > 4) {
- ast_log(LOG_DEBUG, "Delimiter set to %c and mailbox %s\n",delimiter, mailbox);
- if (attributes & LATT_NOINFERIORS)
- ast_log(LOG_DEBUG, "no inferiors\n");
- if (attributes & LATT_NOSELECT)
- ast_log(LOG_DEBUG, "no select\n");
- if (attributes & LATT_MARKED)
- ast_log(LOG_DEBUG, "marked\n");
- if (attributes & LATT_UNMARKED)
- ast_log(LOG_DEBUG, "unmarked\n");
- }
-}
-
-
-void mm_status(MAILSTREAM * stream, char *mailbox, MAILSTATUS * status)
-{
- ast_log (LOG_NOTICE," Mailbox %s", mailbox);
- if (status->flags & SA_MESSAGES)
- ast_log (LOG_NOTICE,", %lu messages", status->messages);
- if (status->flags & SA_RECENT)
- ast_log (LOG_NOTICE,", %lu recent", status->recent);
- if (status->flags & SA_UNSEEN)
- ast_log (LOG_NOTICE,", %lu unseen", status->unseen);
- if (status->flags & SA_UIDVALIDITY)
- ast_log (LOG_NOTICE,", %lu UID validity", status->uidvalidity);
- if (status->flags & SA_UIDNEXT)
- ast_log (LOG_NOTICE,", %lu next UID", status->uidnext);
- ast_log (LOG_NOTICE,"\n");
-}
-
-
-void mm_log(char *string, long errflg)
-{
- switch ((short) errflg) {
- case NIL:
- if (option_debug)
- ast_log(LOG_DEBUG,"IMAP Info: %s\n", string);
- break;
- case PARSE:
- case WARN:
- ast_log (LOG_WARNING,"IMAP Warning: %s\n", string);
- break;
- case ERROR:
- ast_log (LOG_ERROR,"IMAP Error: %s\n", string);
- break;
- }
-}
-
-
-void mm_dlog(char *string)
-{
- ast_log (LOG_NOTICE, "%s\n", string);
-}
-
-
-void mm_login(NETMBX * mb, char *user, char *pwd, long trial)
-{
- struct ast_vm_user *vmu;
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Entering callback mm_login\n");
-
- ast_copy_string(user, mb->user, MAILTMPLEN);
-
- /* We should only do this when necessary */
- if (!ast_strlen_zero(authpassword)) {
- ast_copy_string(pwd, authpassword, MAILTMPLEN);
- } else {
- AST_LIST_TRAVERSE(&users, vmu, list) {
- if (!strcasecmp(mb->user, vmu->imapuser)) {
- ast_copy_string(pwd, vmu->imappassword, MAILTMPLEN);
- break;
- }
- }
- if (!vmu) {
- if ((vmu = find_user_realtime_imapuser(mb->user))) {
- ast_copy_string(pwd, vmu->imappassword, MAILTMPLEN);
- free_user(vmu);
- }
- }
- }
-}
-
-
-void mm_critical(MAILSTREAM * stream)
-{
-}
-
-
-void mm_nocritical(MAILSTREAM * stream)
-{
-}
-
-
-long mm_diskerror(MAILSTREAM * stream, long errcode, long serious)
-{
- kill (getpid (), SIGSTOP);
- return NIL;
-}
-
-
-void mm_fatal(char *string)
-{
- ast_log(LOG_ERROR,"IMAP access FATAL error: %s\n", string);
-}
-
-/* C-client callback to handle quota */
-static void mm_parsequota(MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota)
-{
- struct vm_state *vms;
- char *mailbox;
- char *user;
- unsigned long usage = 0;
- unsigned long limit = 0;
-
- while (pquota) {
- usage = pquota->usage;
- limit = pquota->limit;
- pquota = pquota->next;
- }
-
- mailbox = stream->mailbox;
- user = get_user_by_mailbox(mailbox);
- vms = get_vm_state_by_imapuser(user,2);
- if (vms) {
- if (option_debug > 2)
- ast_log (LOG_DEBUG, "User %s usage is %lu, limit is %lu\n",user,usage,limit);
- vms->quota_usage = usage;
- vms->quota_limit = limit;
- } else {
- ast_log (LOG_ERROR, "No state found.\n");
- }
-}
-
-static char *get_header_by_tag(char *header, char *tag)
-{
- char *start;
- int taglen;
- char *eol_pnt;
-
- if (!header || !tag)
- return NULL;
-
- taglen = strlen(tag) + 1;
- if (taglen < 1)
- return NULL;
-
- start = strstr(header, tag);
- if (!start)
- return NULL;
-
- ast_mutex_lock(&imaptemp_lock);
- ast_copy_string(imaptemp, start+taglen, sizeof(imaptemp));
- ast_mutex_unlock(&imaptemp_lock);
- if ((eol_pnt = strchr(imaptemp,'\r')) || (eol_pnt = strchr(imaptemp,'\n')))
- *eol_pnt = '\0';
- return imaptemp;
-}
-
-static char *get_user_by_mailbox(char *mailbox)
-{
- char *start, *quote;
- char *eol_pnt;
-
- if (!mailbox)
- return NULL;
-
- start = strstr(mailbox,"/user=");
- if (!start)
- return NULL;
-
- ast_mutex_lock(&imaptemp_lock);
- ast_copy_string(imaptemp, start+6, sizeof(imaptemp));
- ast_mutex_unlock(&imaptemp_lock);
-
- quote = strchr(imaptemp,'\"');
- if (!quote) { /* if username is not in quotes */
- eol_pnt = strchr(imaptemp,'/');
- if (!eol_pnt) {
- eol_pnt = strchr(imaptemp,'}');
- }
- *eol_pnt = '\0';
- return imaptemp;
- } else {
- eol_pnt = strchr(imaptemp+1,'\"');
- *eol_pnt = '\0';
- return imaptemp+1;
- }
-}
-
-static struct vm_state *get_vm_state_by_imapuser(char *user, int interactive)
-{
- struct vmstate *vlist = NULL;
-
- ast_mutex_lock(&vmstate_lock);
- vlist = vmstates;
- while (vlist) {
- if (vlist->vms) {
- if (vlist->vms->imapuser) {
- if (!strcmp(vlist->vms->imapuser,user)) {
- if (interactive == 2) {
- ast_mutex_unlock(&vmstate_lock);
- return vlist->vms;
- } else if (vlist->vms->interactive == interactive) {
- ast_mutex_unlock(&vmstate_lock);
- return vlist->vms;
- }
- }
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, " error: imapuser is NULL for %s\n",user);
- }
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, " error: vms is NULL for %s\n",user);
- }
- vlist = vlist->next;
- }
- ast_mutex_unlock(&vmstate_lock);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "%s not found in vmstates\n",user);
- return NULL;
-}
-
-static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, int interactive)
-{
- struct vmstate *vlist = NULL;
-
- ast_mutex_lock(&vmstate_lock);
- vlist = vmstates;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Mailbox set to %s\n",mailbox);
- while (vlist) {
- if (vlist->vms) {
- if (vlist->vms->username) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, " comparing mailbox %s (i=%d) to vmstate mailbox %s (i=%d)\n",mailbox,interactive,vlist->vms->username,vlist->vms->interactive);
- if (!strcmp(vlist->vms->username,mailbox) && vlist->vms->interactive == interactive) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, " Found it!\n");
- ast_mutex_unlock(&vmstate_lock);
- return vlist->vms;
- }
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, " error: username is NULL for %s\n",mailbox);
- }
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, " error: vms is NULL for %s\n",mailbox);
- }
- vlist = vlist->next;
- }
- ast_mutex_unlock(&vmstate_lock);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "%s not found in vmstates\n",mailbox);
- return NULL;
-}
-
-static void vmstate_insert(struct vm_state *vms)
-{
- struct vmstate *v;
- struct vm_state *altvms;
-
- /* If interactive, it probably already exists, and we should
- use the one we already have since it is more up to date.
- We can compare the username to find the duplicate */
- if (vms->interactive == 1) {
- altvms = get_vm_state_by_mailbox(vms->username,0);
- if (altvms) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Duplicate mailbox %s, copying message info...\n",vms->username);
- vms->newmessages = altvms->newmessages;
- vms->oldmessages = altvms->oldmessages;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "check_msgArray before memcpy\n");
- check_msgArray(vms);
- /* memcpy(vms->msgArray, altvms->msgArray, sizeof(long)*256); */
- copy_msgArray(vms, altvms);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "check_msgArray after memcpy\n");
- check_msgArray(vms);
- vms->vmArrayIndex = altvms->vmArrayIndex;
- vms->lastmsg = altvms->lastmsg;
- vms->curmsg = altvms->curmsg;
- /* get a pointer to the persistent store */
- vms->persist_vms = altvms;
- /* Reuse the mailstream? */
- vms->mailstream = altvms->mailstream;
- /* vms->mailstream = NIL; */
- }
- }
-
- v = (struct vmstate *)malloc(sizeof(struct vmstate));
- if (!v) {
- ast_log(LOG_ERROR, "Out of memory\n");
- }
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Inserting vm_state for user:%s, mailbox %s\n",vms->imapuser,vms->username);
- ast_mutex_lock(&vmstate_lock);
- v->vms = vms;
- v->next = vmstates;
- vmstates = v;
- ast_mutex_unlock(&vmstate_lock);
-}
-
-static void vmstate_delete(struct vm_state *vms)
-{
- struct vmstate *vc, *vf = NULL, *vl = NULL;
- struct vm_state *altvms;
-
- /* If interactive, we should copy pertainent info
- back to the persistent state (to make update immediate) */
- if (vms->interactive == 1) {
- altvms = vms->persist_vms;
- if (altvms) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Duplicate mailbox %s, copying message info...\n",vms->username);
- altvms->newmessages = vms->newmessages;
- altvms->oldmessages = vms->oldmessages;
- altvms->updated = 1;
- }
- }
-
- ast_mutex_lock(&vmstate_lock);
- vc = vmstates;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Removing vm_state for user:%s, mailbox %s\n",vms->imapuser,vms->username);
- while (vc) {
- if (vc->vms == vms) {
- vf = vc;
- if (vl)
- vl->next = vc->next;
- else
- vmstates = vc->next;
- break;
- }
- vl = vc;
- vc = vc->next;
- }
- if (!vf) {
- ast_log(LOG_ERROR, "No vmstate found for user:%s, mailbox %s\n",vms->imapuser,vms->username);
- } else {
- ast_mutex_destroy(&vf->vms->lock);
- free(vf);
- }
- ast_mutex_unlock(&vmstate_lock);
-}
-
-static void set_update(MAILSTREAM * stream)
-{
- struct vm_state *vms;
- char *mailbox;
- char *user;
-
- mailbox = stream->mailbox;
- user = get_user_by_mailbox(mailbox);
- vms = get_vm_state_by_imapuser(user, 0);
- if (vms) {
- if (option_debug > 2)
- ast_log (LOG_DEBUG, "User %s mailbox set for update.\n",user);
- vms->updated = 1; /* set updated flag since mailbox changed */
- } else {
- if (option_debug > 2)
- ast_log (LOG_WARNING, "User %s mailbox not found for update.\n",user);
- }
-}
-
-static void init_vm_state(struct vm_state *vms)
-{
- int x;
- vms->vmArrayIndex = 0;
- for (x = 0; x < 256; x++) {
- vms->msgArray[x] = 0;
- }
- ast_mutex_init(&vms->lock);
-}
-
-static void check_msgArray(struct vm_state *vms)
-{
- int x;
- for (x = 0; x<256; x++) {
- if (vms->msgArray[x]!=0) {
- if (option_debug)
- ast_log (LOG_DEBUG, "Item %d set to %ld\n",x,vms->msgArray[x]);
- }
- }
-}
-
-static void copy_msgArray(struct vm_state *dst, struct vm_state *src)
-{
- int x;
- for (x = 0; x<256; x++) {
- dst->msgArray[x] = src->msgArray[x];
- }
-}
-
-static int save_body(BODY *body, struct vm_state *vms, char *section, char *format)
-{
- char *body_content;
- char *body_decoded;
- unsigned long len;
- unsigned long newlen;
- char filename[256];
-
- if (!body || body == NIL)
- return -1;
- body_content = mail_fetchbody (vms->mailstream, vms->msgArray[vms->curmsg], section, &len);
- if (body_content != NIL) {
- snprintf(filename, sizeof(filename), "%s.%s", vms->fn, format);
- /* ast_log (LOG_DEBUG,body_content); */
- body_decoded = rfc822_base64 ((unsigned char *)body_content, len, &newlen);
- write_file (filename, (char *) body_decoded, newlen);
- }
- return 0;
-}
-
-/* get delimiter via mm_list callback */
-static void get_mailbox_delimiter(MAILSTREAM *stream) {
- char tmp[50];
- snprintf(tmp, sizeof(tmp), "{%s}", imapserver);
- mail_list(stream, tmp, "*");
-}
-
-/* Check Quota for user */
-static void check_quota(struct vm_state *vms, char *mailbox) {
- mail_parameters(NULL, SET_QUOTA, (void *) mm_parsequota);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Mailbox name set to: %s, about to check quotas\n", mailbox);
- if (vms && vms->mailstream != NULL) {
- imap_getquotaroot(vms->mailstream, mailbox);
- } else {
- ast_log(LOG_WARNING,"Mailstream not available for mailbox: %s\n",mailbox);
- }
-}
-
-#endif /* IMAP_STORAGE */
-
-/* This is a workaround so that menuselect displays a proper description
- * AST_MODULE_INFO(, , "Comedian Mail (Voicemail System)"
- */
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/apps/app_waitforring.c b/1.4/apps/app_waitforring.c
deleted file mode 100644
index a4f69ae77..000000000
--- a/1.4/apps/app_waitforring.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Wait for Ring Application
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/lock.h"
-
-static char *synopsis = "Wait for Ring Application";
-
-static char *desc = " WaitForRing(timeout)\n"
-"Returns 0 after waiting at least timeout seconds. and\n"
-"only after the next ring has completed. Returns 0 on\n"
-"success or -1 on hangup\n";
-
-static char *app = "WaitForRing";
-
-
-static int waitforring_exec(struct ast_channel *chan, void *data)
-{
- struct ast_module_user *u;
- struct ast_frame *f;
- int res = 0;
- int ms;
-
- if (!data || (sscanf(data, "%d", &ms) != 1)) {
- ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
- return 0;
- }
-
- u = ast_module_user_add(chan);
-
- ms *= 1000;
- while(ms > 0) {
- ms = ast_waitfor(chan, ms);
- if (ms < 0) {
- res = ms;
- break;
- }
- if (ms > 0) {
- f = ast_read(chan);
- if (!f) {
- res = -1;
- break;
- }
- if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Got a ring but still waiting for timeout\n");
- }
- ast_frfree(f);
- }
- }
- /* Now we're really ready for the ring */
- if (!res) {
- ms = 99999999;
- while(ms > 0) {
- ms = ast_waitfor(chan, ms);
- if (ms < 0) {
- res = ms;
- break;
- }
- if (ms > 0) {
- f = ast_read(chan);
- if (!f) {
- res = -1;
- break;
- }
- if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Got a ring after the timeout\n");
- ast_frfree(f);
- break;
- }
- ast_frfree(f);
- }
- }
- }
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, waitforring_exec, synopsis, desc);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Waits until first ring after time");
diff --git a/1.4/apps/app_waitforsilence.c b/1.4/apps/app_waitforsilence.c
deleted file mode 100644
index ef0734cdc..000000000
--- a/1.4/apps/app_waitforsilence.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * WaitForSilence Application by David C. Troy <dave@popvox.com>
- * Version 1.11 2006-06-29
- *
- * 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.
- */
-
-/*! \file
- *
- * \brief Wait for Silence
- * - Waits for up to 'x' milliseconds of silence, 'y' times \n
- * - WaitForSilence(500,2) will wait for 1/2 second of silence, twice \n
- * - WaitForSilence(1000,1) will wait for 1 second of silence, once \n
- * - WaitForSilence(300,3,10) will wait for 300ms of silence, 3 times, and return after 10sec \n
- *
- * \author David C. Troy <dave@popvox.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/dsp.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-
-static char *app = "WaitForSilence";
-static char *synopsis = "Waits for a specified amount of silence";
-static char *descrip =
-" WaitForSilence(silencerequired[|iterations][|timeout]) \n"
-"Wait for Silence: Waits for up to 'silencerequired' \n"
-"milliseconds of silence, 'iterations' times or once if omitted.\n"
-"An optional timeout specified the number of seconds to return\n"
-"after, even if we do not receive the specified amount of silence.\n"
-"Use 'timeout' with caution, as it may defeat the purpose of this\n"
-"application, which is to wait indefinitely until silence is detected\n"
-"on the line. This is particularly useful for reverse-911-type\n"
-"call broadcast applications where you need to wait for an answering\n"
-"machine to complete its spiel before playing a message.\n"
-"The timeout parameter is specified only to avoid an infinite loop in\n"
-"cases where silence is never achieved. Typically you will want to\n"
-"include two or more calls to WaitForSilence when dealing with an answering\n"
-"machine; first waiting for the spiel to finish, then waiting for the beep, etc.\n\n"
- "Examples:\n"
-" - WaitForSilence(500|2) will wait for 1/2 second of silence, twice\n"
-" - WaitForSilence(1000) will wait for 1 second of silence, once\n"
-" - WaitForSilence(300|3|10) will wait for 300ms silence, 3 times,\n"
-" and returns after 10 sec, even if silence is not detected\n\n"
-"Sets the channel variable WAITSTATUS with to one of these values:\n"
-"SILENCE - if exited with silence detected\n"
-"TIMEOUT - if exited without silence detected after timeout\n";
-
-static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstart, int timeout) {
- struct ast_frame *f;
- int dspsilence = 0;
- static int silencethreshold = 128;
- int rfmt = 0;
- int res = 0;
- struct ast_dsp *sildet; /* silence detector dsp */
- time_t now;
-
- rfmt = chan->readformat; /* Set to linear mode */
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set channel to linear mode, giving up\n");
- return -1;
- }
-
- sildet = ast_dsp_new(); /* Create the silence detector */
- if (!sildet) {
- ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
- return -1;
- }
- ast_dsp_set_threshold(sildet, silencethreshold);
-
- /* Await silence... */
- f = NULL;
- for(;;) {
- /* Start with no silence received */
- dspsilence = 0;
-
- res = ast_waitfor(chan, silencereqd);
-
- /* Must have gotten a hangup; let's exit */
- if (res <= 0) {
- f = NULL;
- break;
- }
-
- /* We waited and got no frame; sounds like digital silence or a muted digital channel */
- if (!res) {
- dspsilence = silencereqd;
- } else {
- /* Looks like we did get a frame, so let's check it out */
- f = ast_read(chan);
- if (!f)
- break;
- if (f && f->frametype == AST_FRAME_VOICE) {
- ast_dsp_silence(sildet, f, &dspsilence);
- ast_frfree(f);
- }
- }
-
- if (option_verbose > 6)
- ast_verbose(VERBOSE_PREFIX_3 "Got %dms silence< %dms required\n", dspsilence, silencereqd);
-
- if (dspsilence >= silencereqd) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Exiting with %dms silence >= %dms required\n", dspsilence, silencereqd);
- /* Ended happily with silence */
- res = 1;
- pbx_builtin_setvar_helper(chan, "WAITSTATUS", "SILENCE");
- ast_log(LOG_DEBUG, "WAITSTATUS was set to SILENCE\n");
- break;
- }
-
- if ( timeout && (difftime(time(&now),waitstart) >= timeout) ) {
- pbx_builtin_setvar_helper(chan, "WAITSTATUS", "TIMEOUT");
- ast_log(LOG_DEBUG, "WAITSTATUS was set to TIMEOUT\n");
- res = 0;
- break;
- }
- }
-
-
- if (rfmt && ast_set_read_format(chan, rfmt)) {
- ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
- }
- ast_dsp_free(sildet);
- return res;
-}
-
-static int waitforsilence_exec(struct ast_channel *chan, void *data)
-{
- int res = 1;
- int silencereqd = 1000;
- int timeout = 0;
- int iterations = 1, i;
- time_t waitstart;
-
- res = ast_answer(chan); /* Answer the channel */
-
- if (!data || ( (sscanf(data, "%d|%d|%d", &silencereqd, &iterations, &timeout) != 3) &&
- (sscanf(data, "%d|%d", &silencereqd, &iterations) != 2) &&
- (sscanf(data, "%d", &silencereqd) != 1) ) ) {
- ast_log(LOG_WARNING, "Using default value of 1000ms, 1 iteration, no timeout\n");
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Waiting %d time(s) for %d ms silence with %d timeout\n", iterations, silencereqd, timeout);
-
- time(&waitstart);
- res = 1;
- for (i=0; (i<iterations) && (res == 1); i++) {
- res = do_waiting(chan, silencereqd, waitstart, timeout);
- }
- if (res > 0)
- res = 0;
- return res;
-}
-
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, waitforsilence_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Wait For Silence");
-
diff --git a/1.4/apps/app_while.c b/1.4/apps/app_while.c
deleted file mode 100644
index 8595916f3..000000000
--- a/1.4/apps/app_while.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright 2004 - 2005, Anthony Minessale <anthmct@yahoo.com>
- *
- * Anthony Minessale <anthmct@yahoo.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.
- */
-
-/*! \file
- *
- * \brief While Loop Implementation
- *
- * \author Anthony Minessale <anthmct@yahoo.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-#include "asterisk/config.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-
-#define ALL_DONE(u,ret) {ast_module_user_remove(u); return ret;}
-
-
-static char *start_app = "While";
-static char *start_desc =
-"Usage: While(<expr>)\n"
-"Start a While Loop. Execution will return to this point when\n"
-"EndWhile is called until expr is no longer true.\n";
-
-static char *start_synopsis = "Start a while loop";
-
-
-static char *stop_app = "EndWhile";
-static char *stop_desc =
-"Usage: EndWhile()\n"
-"Return to the previous called While\n";
-
-static char *stop_synopsis = "End a while loop";
-
-static char *exit_app = "ExitWhile";
-static char *exit_desc =
-"Usage: ExitWhile()\n"
-"Exits a While loop, whether or not the conditional has been satisfied.\n";
-static char *exit_synopsis = "End a While loop";
-
-static char *continue_app = "ContinueWhile";
-static char *continue_desc =
-"Usage: ContinueWhile()\n"
-"Returns to the top of the while loop and re-evaluates the conditional.\n";
-static char *continue_synopsis = "Restart a While loop";
-
-#define VAR_SIZE 64
-
-
-static const char *get_index(struct ast_channel *chan, const char *prefix, int index) {
- char varname[VAR_SIZE];
-
- snprintf(varname, VAR_SIZE, "%s_%d", prefix, index);
- return pbx_builtin_getvar_helper(chan, varname);
-}
-
-static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid)
-{
- struct ast_exten *e;
- struct ast_include *i;
- struct ast_context *c2;
-
- for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
- if (ast_extension_match(ast_get_extension_name(e), exten)) {
- int needmatch = ast_get_extension_matchcid(e);
- if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) ||
- (!needmatch)) {
- /* This is the matching extension we want */
- struct ast_exten *p;
- for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) {
- if (priority != ast_get_extension_priority(p))
- continue;
- return p;
- }
- }
- }
- }
-
- /* No match; run through includes */
- for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) {
- for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
- if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
- e = find_matching_priority(c2, exten, priority, callerid);
- if (e)
- return e;
- }
- }
- }
- return NULL;
-}
-
-static int find_matching_endwhile(struct ast_channel *chan)
-{
- struct ast_context *c;
- int res=-1;
-
- if (ast_lock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock contexts list\n");
- return -1;
- }
-
- for (c=ast_walk_contexts(NULL); c; c=ast_walk_contexts(c)) {
- struct ast_exten *e;
-
- if (!ast_lock_context(c)) {
- if (!strcmp(ast_get_context_name(c), chan->context)) {
- /* This is the matching context we want */
- int cur_priority = chan->priority + 1, level=1;
-
- for (e = find_matching_priority(c, chan->exten, cur_priority, chan->cid.cid_num); e; e = find_matching_priority(c, chan->exten, ++cur_priority, chan->cid.cid_num)) {
- if (!strcasecmp(ast_get_extension_app(e), "WHILE")) {
- level++;
- } else if (!strcasecmp(ast_get_extension_app(e), "ENDWHILE")) {
- level--;
- }
-
- if (level == 0) {
- res = cur_priority;
- break;
- }
- }
- }
- ast_unlock_context(c);
- if (res > 0) {
- break;
- }
- }
- }
- ast_unlock_contexts();
- return res;
-}
-
-static int _while_exec(struct ast_channel *chan, void *data, int end)
-{
- int res=0;
- struct ast_module_user *u;
- const char *while_pri = NULL;
- char *my_name = NULL;
- const char *condition = NULL, *label = NULL;
- char varname[VAR_SIZE], end_varname[VAR_SIZE];
- const char *prefix = "WHILE";
- size_t size=0;
- int used_index_i = -1, x=0;
- char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0";
-
- if (!chan) {
- /* huh ? */
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- /* dont want run away loops if the chan isn't even up
- this is up for debate since it slows things down a tad ......
- */
- if (ast_waitfordigit(chan,1) < 0)
- ALL_DONE(u,-1);
-
-
- for (x=0;;x++) {
- if (get_index(chan, prefix, x)) {
- used_index_i = x;
- } else
- break;
- }
-
- snprintf(used_index, VAR_SIZE, "%d", used_index_i);
- snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1);
-
- if (!end)
- condition = ast_strdupa(data);
-
- size = strlen(chan->context) + strlen(chan->exten) + 32;
- my_name = alloca(size);
- memset(my_name, 0, size);
- snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority);
-
- if (ast_strlen_zero(label)) {
- if (end)
- label = used_index;
- else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) {
- label = new_index;
- pbx_builtin_setvar_helper(chan, my_name, label);
- }
-
- }
-
- snprintf(varname, VAR_SIZE, "%s_%s", prefix, label);
- while_pri = pbx_builtin_getvar_helper(chan, varname);
-
- if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) {
- snprintf(end_varname,VAR_SIZE,"END_%s",varname);
- }
-
-
- if ((!end && !pbx_checkcondition(condition)) || (end == 2)) {
- /* Condition Met (clean up helper vars) */
- const char *goto_str;
- pbx_builtin_setvar_helper(chan, varname, NULL);
- pbx_builtin_setvar_helper(chan, my_name, NULL);
- snprintf(end_varname,VAR_SIZE,"END_%s",varname);
- if ((goto_str=pbx_builtin_getvar_helper(chan, end_varname))) {
- ast_parseable_goto(chan, goto_str);
- pbx_builtin_setvar_helper(chan, end_varname, NULL);
- } else {
- int pri = find_matching_endwhile(chan);
- if (pri > 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Jumping to priority %d\n", pri);
- chan->priority = pri;
- } else {
- ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority);
- }
- }
- ALL_DONE(u,res);
- }
-
- if (!end && !while_pri) {
- char *goto_str;
- size = strlen(chan->context) + strlen(chan->exten) + 32;
- goto_str = alloca(size);
- memset(goto_str, 0, size);
- snprintf(goto_str, size, "%s|%s|%d", chan->context, chan->exten, chan->priority);
- pbx_builtin_setvar_helper(chan, varname, goto_str);
- }
-
- else if (end && while_pri) {
- /* END of loop */
- snprintf(end_varname, VAR_SIZE, "END_%s", varname);
- if (! pbx_builtin_getvar_helper(chan, end_varname)) {
- char *goto_str;
- size = strlen(chan->context) + strlen(chan->exten) + 32;
- goto_str = alloca(size);
- memset(goto_str, 0, size);
- snprintf(goto_str, size, "%s|%s|%d", chan->context, chan->exten, chan->priority+1);
- pbx_builtin_setvar_helper(chan, end_varname, goto_str);
- }
- ast_parseable_goto(chan, while_pri);
- }
-
-
-
-
- ALL_DONE(u, res);
-}
-
-static int while_start_exec(struct ast_channel *chan, void *data) {
- return _while_exec(chan, data, 0);
-}
-
-static int while_end_exec(struct ast_channel *chan, void *data) {
- return _while_exec(chan, data, 1);
-}
-
-static int while_exit_exec(struct ast_channel *chan, void *data) {
- return _while_exec(chan, data, 2);
-}
-
-static int while_continue_exec(struct ast_channel *chan, void *data)
-{
- int x;
- const char *prefix = "WHILE", *while_pri=NULL;
-
- for (x = 0; ; x++) {
- const char *tmp = get_index(chan, prefix, x);
- if (tmp)
- while_pri = tmp;
- else
- break;
- }
-
- if (while_pri)
- ast_parseable_goto(chan, while_pri);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(start_app);
- res |= ast_unregister_application(stop_app);
- res |= ast_unregister_application(exit_app);
- res |= ast_unregister_application(continue_app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(start_app, while_start_exec, start_synopsis, start_desc);
- res |= ast_register_application(stop_app, while_end_exec, stop_synopsis, stop_desc);
- res |= ast_register_application(exit_app, while_exit_exec, exit_synopsis, exit_desc);
- res |= ast_register_application(continue_app, while_continue_exec, continue_synopsis, continue_desc);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "While Loops and Conditional Execution");
diff --git a/1.4/apps/app_zapateller.c b/1.4/apps/app_zapateller.c
deleted file mode 100644
index 5a209e315..000000000
--- a/1.4/apps/app_zapateller.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Playback the special information tone to get rid of telemarketers
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-
-static char *app = "Zapateller";
-
-static char *synopsis = "Block telemarketers with SIT";
-
-static char *descrip =
-" Zapateller(options): Generates special information tone to block\n"
-"telemarketers from calling you. Options is a pipe-delimited list of\n"
-"options. The following options are available:\n"
-"'answer' causes the line to be answered before playing the tone,\n"
-"'nocallerid' causes Zapateller to only play the tone if there\n"
-"is no callerid information available. Options should be separated by |\n"
-"characters\n";
-
-
-static int zapateller_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- int answer = 0, nocallerid = 0;
- char *c;
- char *stringp=NULL;
-
- u = ast_module_user_add(chan);
-
- stringp=data;
- c = strsep(&stringp, "|");
- while(!ast_strlen_zero(c)) {
- if (!strcasecmp(c, "answer"))
- answer = 1;
- else if (!strcasecmp(c, "nocallerid"))
- nocallerid = 1;
-
- c = strsep(&stringp, "|");
- }
-
- ast_stopstream(chan);
- if (chan->_state != AST_STATE_UP) {
-
- if (answer)
- res = ast_answer(chan);
- if (!res) {
- res = ast_safe_sleep(chan, 500);
- }
- }
- if (!ast_strlen_zero(chan->cid.cid_num) && nocallerid) {
- ast_module_user_remove(u);
- return res;
- }
- if (!res)
- res = ast_tonepair(chan, 950, 0, 330, 0);
- if (!res)
- res = ast_tonepair(chan, 1400, 0, 330, 0);
- if (!res)
- res = ast_tonepair(chan, 1800, 0, 330, 0);
- if (!res)
- res = ast_tonepair(chan, 0, 0, 1000, 0);
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, zapateller_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Block Telemarketers with Special Information Tone");
diff --git a/1.4/apps/app_zapbarge.c b/1.4/apps/app_zapbarge.c
deleted file mode 100644
index 735020f60..000000000
--- a/1.4/apps/app_zapbarge.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Special thanks to comphealth.com for sponsoring this
- * GPL application.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Zap Barge support
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note Special thanks to comphealth.com for sponsoring this
- * GPL application.
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <zaptel/zaptel.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/say.h"
-#include "asterisk/utils.h"
-
-static char *app = "ZapBarge";
-
-static char *synopsis = "Barge in (monitor) Zap channel";
-
-static char *descrip =
-" ZapBarge([channel]): Barges in on a specified zap\n"
-"channel or prompts if one is not specified. Returns\n"
-"-1 when caller user hangs up and is independent of the\n"
-"state of the channel being monitored.";
-
-
-#define CONF_SIZE 160
-
-static int careful_write(int fd, unsigned char *data, int len)
-{
- int res;
- while(len) {
- res = write(fd, data, len);
- if (res < 1) {
- if (errno != EAGAIN) {
- ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
- return -1;
- } else
- return 0;
- }
- len -= res;
- data += res;
- }
- return 0;
-}
-
-static int conf_run(struct ast_channel *chan, int confno, int confflags)
-{
- int fd;
- struct zt_confinfo ztc;
- struct ast_frame *f;
- struct ast_channel *c;
- struct ast_frame fr;
- int outfd;
- int ms;
- int nfds;
- int res;
- int flags;
- int retryzap;
- int origfd;
- int ret = -1;
-
- ZT_BUFFERINFO bi;
- char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
- char *buf = __buf + AST_FRIENDLY_OFFSET;
-
- /* Set it into U-law mode (write) */
- if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
- ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
- goto outrun;
- }
-
- /* Set it into U-law mode (read) */
- if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
- ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
- goto outrun;
- }
- ast_indicate(chan, -1);
- retryzap = strcasecmp(chan->tech->type, "Zap");
-zapretry:
- origfd = chan->fds[0];
- if (retryzap) {
- fd = open("/dev/zap/pseudo", O_RDWR);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
- goto outrun;
- }
- /* Make non-blocking */
- flags = fcntl(fd, F_GETFL);
- if (flags < 0) {
- ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
- ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- /* Setup buffering information */
- memset(&bi, 0, sizeof(bi));
- bi.bufsize = CONF_SIZE;
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = 4;
- if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
- ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- nfds = 1;
- } else {
- /* XXX Make sure we're not running on a pseudo channel XXX */
- fd = chan->fds[0];
- nfds = 0;
- }
- memset(&ztc, 0, sizeof(ztc));
- /* Check to see if we're in a conference... */
- ztc.chan = 0;
- if (ioctl(fd, ZT_GETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error getting conference\n");
- close(fd);
- goto outrun;
- }
- if (ztc.confmode) {
- /* Whoa, already in a conference... Retry... */
- if (!retryzap) {
- ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
- retryzap = 1;
- goto zapretry;
- }
- }
- memset(&ztc, 0, sizeof(ztc));
- /* Add us to the conference */
- ztc.chan = 0;
- ztc.confno = confno;
- ztc.confmode = ZT_CONF_MONITORBOTH;
-
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- goto outrun;
- }
- ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno);
-
- for(;;) {
- outfd = -1;
- ms = -1;
- c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
- if (c) {
- if (c->fds[0] != origfd) {
- if (retryzap) {
- /* Kill old pseudo */
- close(fd);
- }
- ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
- retryzap = 0;
- goto zapretry;
- }
- f = ast_read(c);
- if (!f)
- break;
- if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
- ret = 0;
- ast_frfree(f);
- break;
- } else if (fd != chan->fds[0]) {
- if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass == AST_FORMAT_ULAW) {
- /* Carefully write */
- careful_write(fd, f->data, f->datalen);
- } else
- ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass);
- }
- }
- ast_frfree(f);
- } else if (outfd > -1) {
- res = read(outfd, buf, CONF_SIZE);
- if (res > 0) {
- memset(&fr, 0, sizeof(fr));
- fr.frametype = AST_FRAME_VOICE;
- fr.subclass = AST_FORMAT_ULAW;
- fr.datalen = res;
- fr.samples = res;
- fr.data = buf;
- fr.offset = AST_FRIENDLY_OFFSET;
- if (ast_write(chan, &fr) < 0) {
- ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
- /* break; */
- }
- } else
- ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
- }
- }
- if (fd != chan->fds[0])
- close(fd);
- else {
- /* Take out of conference */
- /* Add us to the conference */
- ztc.chan = 0;
- ztc.confno = 0;
- ztc.confmode = 0;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- }
- }
-
-outrun:
-
- return ret;
-}
-
-static int conf_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- struct ast_module_user *u;
- int retrycnt = 0;
- int confflags = 0;
- int confno = 0;
- char confstr[80] = "";
-
- u = ast_module_user_add(chan);
-
- if (!ast_strlen_zero(data)) {
- if ((sscanf(data, "Zap/%d", &confno) != 1) &&
- (sscanf(data, "%d", &confno) != 1)) {
- ast_log(LOG_WARNING, "ZapBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data);
- ast_module_user_remove(u);
- return 0;
- }
- }
-
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- while(!confno && (++retrycnt < 4)) {
- /* Prompt user for conference number */
- confstr[0] = '\0';
- res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0);
- if (res <0) goto out;
- if (sscanf(confstr, "%d", &confno) != 1)
- confno = 0;
- }
- if (confno) {
- /* XXX Should prompt user for pin if pin is required XXX */
- /* Run the conference */
- res = conf_run(chan, confno, confflags);
- }
-out:
- /* Do the conference */
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, conf_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Barge in on Zap channel application");
diff --git a/1.4/apps/app_zapras.c b/1.4/apps/app_zapras.c
deleted file mode 100644
index c3ccf30d9..000000000
--- a/1.4/apps/app_zapras.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Execute an ISDN RAS
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#ifdef __linux__
-#include <sys/signal.h>
-#else
-#include <signal.h>
-#endif /* __linux__ */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <zaptel/zaptel.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-
-static char *app = "ZapRAS";
-
-static char *synopsis = "Executes Zaptel ISDN RAS application";
-
-static char *descrip =
-" ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
-"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
-"channel to be able to use this function (No modem emulation is included).\n"
-"Your pppd must be patched to be zaptel aware. Arguments should be\n"
-"separated by | characters.\n";
-
-
-#define PPP_MAX_ARGS 32
-#define PPP_EXEC "/usr/sbin/pppd"
-
-static pid_t spawn_ras(struct ast_channel *chan, char *args)
-{
- pid_t pid;
- int x;
- char *c;
-
- char *argv[PPP_MAX_ARGS];
- int argc = 0;
- char *stringp=NULL;
- sigset_t fullset, oldset;
-
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
-
- /* Start by forking */
- pid = fork();
- if (pid) {
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- return pid;
- }
-
- /* Restore original signal handlers */
- for (x=0;x<NSIG;x++)
- signal(x, SIG_DFL);
-
- pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
-
- /* Execute RAS on File handles */
- dup2(chan->fds[0], STDIN_FILENO);
-
- /* Drop high priority */
- if (ast_opt_high_priority)
- ast_set_priority(0);
-
- /* Close other file descriptors */
- for (x=STDERR_FILENO + 1;x<1024;x++)
- close(x);
-
- /* Reset all arguments */
- memset(argv, 0, sizeof(argv));
-
- /* First argument is executable, followed by standard
- arguments for zaptel PPP */
- argv[argc++] = PPP_EXEC;
- argv[argc++] = "nodetach";
-
- /* And all the other arguments */
- stringp=args;
- c = strsep(&stringp, "|");
- while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
- argv[argc++] = c;
- c = strsep(&stringp, "|");
- }
-
- argv[argc++] = "plugin";
- argv[argc++] = "zaptel.so";
- argv[argc++] = "stdin";
-
- /* Finally launch PPP */
- execv(PPP_EXEC, argv);
- fprintf(stderr, "Failed to exec PPPD!\n");
- exit(1);
-}
-
-static void run_ras(struct ast_channel *chan, char *args)
-{
- pid_t pid;
- int status;
- int res;
- int signalled = 0;
- struct zt_bufferinfo savebi;
- int x;
-
- res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &savebi);
- if(res) {
- ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
- return;
- }
-
- pid = spawn_ras(chan, args);
- if (pid < 0) {
- ast_log(LOG_WARNING, "Failed to spawn RAS\n");
- } else {
- for (;;) {
- res = wait4(pid, &status, WNOHANG, NULL);
- if (!res) {
- /* Check for hangup */
- if (chan->_softhangup && !signalled) {
- ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
- kill(pid, SIGTERM);
- signalled=1;
- }
- /* Try again */
- sleep(1);
- continue;
- }
- if (res < 0) {
- ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
- }
- if (option_verbose > 2) {
- if (WIFEXITED(status)) {
- ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n",
- chan->name, WTERMSIG(status));
- } else {
- ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
- }
- }
- /* Throw back into audio mode */
- x = 1;
- ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
-
- /* Restore saved values */
- res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &savebi);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
- }
- break;
- }
- }
-}
-
-static int zapras_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- char *args;
- struct ast_module_user *u;
- ZT_PARAMS ztp;
-
- if (!data)
- data = "";
-
- u = ast_module_user_add(chan);
-
- args = ast_strdupa(data);
-
- /* Answer the channel if it's not up */
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
- if (strcasecmp(chan->tech->type, "Zap")) {
- /* If it's not a zap channel, we're done. Wait a couple of
- seconds and then hangup... */
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
- sleep(2);
- } else {
- memset(&ztp, 0, sizeof(ztp));
- if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
- ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
- } else if (ztp.sigtype != ZT_SIG_CLEAR) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
- } else {
- /* Everything should be okay. Run PPP. */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
- /* Execute RAS */
- run_ras(chan, args);
- }
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, zapras_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Zap RAS Application");
-
diff --git a/1.4/apps/app_zapscan.c b/1.4/apps/app_zapscan.c
deleted file mode 100644
index 690d9a5cc..000000000
--- a/1.4/apps/app_zapscan.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Modified from app_zapbarge by David Troy <dave@toad.net>
- *
- * Special thanks to comphealth.com for sponsoring this
- * GPL application.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Zap Scanner
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup applications
- */
-
-/*** MODULEINFO
- <depend>zaptel</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <zaptel/zaptel.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/cli.h"
-#include "asterisk/say.h"
-
-static char *app = "ZapScan";
-
-static char *synopsis = "Scan Zap channels to monitor calls";
-
-static char *descrip =
-" ZapScan([group]) allows a call center manager to monitor Zap channels in\n"
-"a convenient way. Use '#' to select the next channel and use '*' to exit\n"
-"Limit scanning to a channel GROUP by setting the option group argument.\n";
-
-
-#define CONF_SIZE 160
-
-static struct ast_channel *get_zap_channel_locked(int num) {
- char name[80];
-
- snprintf(name,sizeof(name),"Zap/%d-1",num);
- return ast_get_channel_by_name_locked(name);
-}
-
-static int careful_write(int fd, unsigned char *data, int len)
-{
- int res;
- while(len) {
- res = write(fd, data, len);
- if (res < 1) {
- if (errno != EAGAIN) {
- ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
- return -1;
- } else
- return 0;
- }
- len -= res;
- data += res;
- }
- return 0;
-}
-
-static int conf_run(struct ast_channel *chan, int confno, int confflags)
-{
- int fd;
- struct zt_confinfo ztc;
- struct ast_frame *f;
- struct ast_channel *c;
- struct ast_frame fr;
- int outfd;
- int ms;
- int nfds;
- int res;
- int flags;
- int retryzap;
- int origfd;
- int ret = -1;
- char input[4];
- int ic=0;
-
- ZT_BUFFERINFO bi;
- char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
- char *buf = __buf + AST_FRIENDLY_OFFSET;
-
- /* Set it into U-law mode (write) */
- if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
- ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
- goto outrun;
- }
-
- /* Set it into U-law mode (read) */
- if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
- ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
- goto outrun;
- }
- ast_indicate(chan, -1);
- retryzap = strcasecmp(chan->tech->type, "Zap");
- zapretry:
- origfd = chan->fds[0];
- if (retryzap) {
- fd = open("/dev/zap/pseudo", O_RDWR);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
- goto outrun;
- }
- /* Make non-blocking */
- flags = fcntl(fd, F_GETFL);
- if (flags < 0) {
- ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
- ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- /* Setup buffering information */
- memset(&bi, 0, sizeof(bi));
- bi.bufsize = CONF_SIZE;
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = 4;
- if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
- ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
- close(fd);
- goto outrun;
- }
- nfds = 1;
- } else {
- /* XXX Make sure we're not running on a pseudo channel XXX */
- fd = chan->fds[0];
- nfds = 0;
- }
- memset(&ztc, 0, sizeof(ztc));
- /* Check to see if we're in a conference... */
- ztc.chan = 0;
- if (ioctl(fd, ZT_GETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error getting conference\n");
- close(fd);
- goto outrun;
- }
- if (ztc.confmode) {
- /* Whoa, already in a conference... Retry... */
- if (!retryzap) {
- ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
- retryzap = 1;
- goto zapretry;
- }
- }
- memset(&ztc, 0, sizeof(ztc));
- /* Add us to the conference */
- ztc.chan = 0;
- ztc.confno = confno;
- ztc.confmode = ZT_CONF_MONITORBOTH;
-
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- close(fd);
- goto outrun;
- }
- ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno);
-
- for(;;) {
- outfd = -1;
- ms = -1;
- c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
- if (c) {
- if (c->fds[0] != origfd) {
- if (retryzap) {
- /* Kill old pseudo */
- close(fd);
- }
- ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
- retryzap = 0;
- goto zapretry;
- }
- f = ast_read(c);
- if (!f)
- break;
- if(f->frametype == AST_FRAME_DTMF) {
- if(f->subclass == '#') {
- ret = 0;
- break;
- }
- else if (f->subclass == '*') {
- ret = -1;
- break;
-
- }
- else {
- input[ic++] = f->subclass;
- }
- if(ic == 3) {
- input[ic++] = '\0';
- ic=0;
- ret = atoi(input);
- ast_verbose(VERBOSE_PREFIX_3 "Zapscan: change channel to %d\n",ret);
- break;
- }
- }
-
- if (fd != chan->fds[0]) {
- if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass == AST_FORMAT_ULAW) {
- /* Carefully write */
- careful_write(fd, f->data, f->datalen);
- } else
- ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass);
- }
- }
- ast_frfree(f);
- } else if (outfd > -1) {
- res = read(outfd, buf, CONF_SIZE);
- if (res > 0) {
- memset(&fr, 0, sizeof(fr));
- fr.frametype = AST_FRAME_VOICE;
- fr.subclass = AST_FORMAT_ULAW;
- fr.datalen = res;
- fr.samples = res;
- fr.data = buf;
- fr.offset = AST_FRIENDLY_OFFSET;
- if (ast_write(chan, &fr) < 0) {
- ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
- /* break; */
- }
- } else
- ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
- }
- }
- if (f)
- ast_frfree(f);
- if (fd != chan->fds[0])
- close(fd);
- else {
- /* Take out of conference */
- /* Add us to the conference */
- ztc.chan = 0;
- ztc.confno = 0;
- ztc.confmode = 0;
- if (ioctl(fd, ZT_SETCONF, &ztc)) {
- ast_log(LOG_WARNING, "Error setting conference\n");
- }
- }
-
- outrun:
-
- return ret;
-}
-
-static int conf_exec(struct ast_channel *chan, void *data)
-{
- int res=-1;
- struct ast_module_user *u;
- int confflags = 0;
- int confno = 0;
- char confstr[80] = "", *tmp = NULL;
- struct ast_channel *tempchan = NULL, *lastchan = NULL,*ichan = NULL;
- struct ast_frame *f;
- char *desired_group;
- int input=0,search_group=0;
-
- u = ast_module_user_add(chan);
-
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- desired_group = ast_strdupa(data);
- if(!ast_strlen_zero(desired_group)) {
- ast_verbose(VERBOSE_PREFIX_3 "Scanning for group %s\n", desired_group);
- search_group = 1;
- }
-
- for (;;) {
- if (ast_waitfor(chan, 100) < 0)
- break;
-
- f = ast_read(chan);
- if (!f)
- break;
- if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
- ast_frfree(f);
- break;
- }
- ast_frfree(f);
- ichan = NULL;
- if(input) {
- ichan = get_zap_channel_locked(input);
- input = 0;
- }
-
- tempchan = ichan ? ichan : ast_channel_walk_locked(tempchan);
-
- if ( !tempchan && !lastchan )
- break;
-
- if (tempchan && search_group) {
- const char *mygroup;
- if((mygroup = pbx_builtin_getvar_helper(tempchan, "GROUP")) && (!strcmp(mygroup, desired_group))) {
- ast_verbose(VERBOSE_PREFIX_3 "Found Matching Channel %s in group %s\n", tempchan->name, desired_group);
- } else {
- ast_mutex_unlock(&tempchan->lock);
- lastchan = tempchan;
- continue;
- }
- }
- if (tempchan && (!strcmp(tempchan->tech->type, "Zap")) && (tempchan != chan) ) {
- ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
- ast_copy_string(confstr, tempchan->name, sizeof(confstr));
- ast_mutex_unlock(&tempchan->lock);
- if ((tmp = strchr(confstr,'-'))) {
- *tmp = '\0';
- }
- confno = atoi(strchr(confstr,'/') + 1);
- ast_stopstream(chan);
- ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
- res = conf_run(chan, confno, confflags);
- if (res<0) break;
- input = res;
- } else if (tempchan)
- ast_mutex_unlock(&tempchan->lock);
- lastchan = tempchan;
- }
- ast_module_user_remove(u);
- return res;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_application(app);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- return ast_register_application(app, conf_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Scan Zap channels application");
-
diff --git a/1.4/apps/enter.h b/1.4/apps/enter.h
deleted file mode 100644
index ac765984a..000000000
--- a/1.4/apps/enter.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * U-law 8-bit audio data
- *
- * Source: enter.raw
- *
- * Copyright (C) 1999, Mark Spencer and Linux Support Services
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char enter[] = {
-0xba, 0xba, 0xb0, 0xa6, 0xa9, 0xb8, 0xfe, 0x46, 0x42, 0x46,
-0x4a, 0xfe, 0xac, 0xa2, 0x9f, 0x9f, 0xa8, 0xb8, 0x3b, 0x29,
-0x35, 0x4a, 0xfe, 0xc1, 0xad, 0xa2, 0xad, 0xc5, 0x4e, 0x68,
-0x68, 0xe7, 0xb8, 0xb0, 0xb2, 0xc1, 0xc1, 0xb0, 0xae, 0xcd,
-0xfe, 0xfe, 0xcd, 0xcd, 0xfe, 0x68, 0xd3, 0xb2, 0xae, 0xab,
-0xb2, 0xfe, 0x35, 0x31, 0xdb, 0xac, 0xab, 0xaf, 0xab, 0xaa,
-0xb4, 0x68, 0x3b, 0x39, 0x3f, 0x68, 0xb4, 0xa8, 0xa8, 0xb0,
-0xbc, 0xbc, 0xc5, 0x3f, 0x31, 0x37, 0xfe, 0xc1, 0xbc, 0xb0,
-0xa5, 0xa2, 0xa8, 0xaf, 0xbe, 0x3b, 0x28, 0x26, 0x3d, 0xbc,
-0xb0, 0xae, 0xa2, 0x9f, 0xa2, 0xfe, 0x29, 0x24, 0x29, 0x4a,
-0xc5, 0xaa, 0xa8, 0xa9, 0xa8, 0xa5, 0xa7, 0xdb, 0x2c, 0x27,
-0x2d, 0x4a, 0xfe, 0xdb, 0xb2, 0xa2, 0x9f, 0x9f, 0xae, 0xe7,
-0x2c, 0x22, 0x2b, 0xfe, 0xba, 0xb0, 0xaa, 0x9f, 0xa3, 0xb0,
-0x5c, 0x33, 0x33, 0x39, 0x5c, 0xdb, 0xc1, 0xb4, 0xb0, 0xaa,
-0xad, 0xba, 0x54, 0x46, 0xfe, 0xe7, 0xfe, 0x54, 0xe7, 0xaf,
-0xa6, 0xa7, 0xb0, 0xfe, 0x46, 0x39, 0x5c, 0xe7, 0xdb, 0xfe,
-0xba, 0xac, 0xa8, 0xc5, 0x46, 0x33, 0x54, 0xc5, 0xae, 0xad,
-0xb2, 0xc1, 0xcd, 0xc1, 0xbc, 0xfe, 0x3f, 0x37, 0xfe, 0xb4,
-0xb6, 0xcd, 0xdb, 0xc1, 0xb0, 0xb6, 0xcd, 0x4e, 0x39, 0x37,
-0xfe, 0xb0, 0xab, 0xa9, 0xa9, 0xa9, 0xb0, 0x5c, 0x29, 0x25,
-0x31, 0xfe, 0xc1, 0xb4, 0xae, 0xab, 0xab, 0xb2, 0xcd, 0x3b,
-0x2a, 0x2c, 0x54, 0xb4, 0xb4, 0xba, 0xb2, 0xa3, 0x9f, 0xa8,
-0xfe, 0x33, 0x27, 0x2a, 0x39, 0xfe, 0xc1, 0xbe, 0xb0, 0xa2,
-0x9f, 0xb0, 0x33, 0x22, 0x25, 0x46, 0xc1, 0xb8, 0xb0, 0xab,
-0xa8, 0xa8, 0xb0, 0xbe, 0x42, 0x2c, 0x2e, 0x4a, 0xfe, 0x5c,
-0xfe, 0xb4, 0xa8, 0xa8, 0xba, 0xfe, 0x4a, 0x39, 0x39, 0x46,
-0xfe, 0xbc, 0xaf, 0xa5, 0xa5, 0xae, 0x68, 0x37, 0x4a, 0xfe,
-0xfe, 0x4a, 0x4a, 0xd3, 0xb0, 0xb0, 0xc1, 0x5c, 0x46, 0x46,
-0xd3, 0xb6, 0xbe, 0x54, 0x54, 0xc9, 0xab, 0xae, 0xc5, 0x46,
-0x4a, 0xfe, 0xcd, 0xc9, 0xcd, 0xe7, 0xe7, 0xc9, 0xb4, 0xc5,
-0x4a, 0x2c, 0x37, 0xc1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb6, 0xdb,
-0xfe, 0x4a, 0x46, 0x3f, 0x68, 0xba, 0xb2, 0xba, 0xc5, 0xb6,
-0xb2, 0xcd, 0x33, 0x2e, 0x39, 0x68, 0xfe, 0xe7, 0xba, 0xaf,
-0xa7, 0xa7, 0xad, 0xe7, 0x2d, 0x25, 0x2f, 0xd3, 0xbe, 0xcd,
-0xc5, 0xac, 0xa6, 0xac, 0xfe, 0x3b, 0x2c, 0x2d, 0x3d, 0xc1,
-0xb4, 0xbe, 0xcd, 0xaf, 0xa5, 0xa8, 0xe7, 0x31, 0x2f, 0x39,
-0x46, 0x5c, 0xdb, 0xbc, 0xba, 0xaf, 0xa9, 0xad, 0xfe, 0x2f,
-0x2d, 0xba, 0xad, 0xba, 0xfe, 0x3d, 0x42, 0x5c, 0xc9, 0xc1,
-0xcd, 0xfe, 0xc1, 0xae, 0xa6, 0xcd, 0x33, 0x25, 0x3b, 0xdb,
-0xb0, 0xb6, 0xb8, 0xb6, 0xb4, 0xb8, 0xba, 0xfe, 0x3d, 0x37,
-0xfe, 0xba, 0xc1, 0x54, 0x54, 0xd3, 0xb0, 0xb4, 0xe7, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xd3, 0xb6, 0xa9, 0xa7, 0xba,
-0x3d, 0x35, 0xfe, 0xc1, 0xcd, 0x4a, 0x54, 0xbe, 0xb2, 0xb8,
-0xfe, 0x46, 0x3b, 0xfe, 0xba, 0xab, 0xc5, 0x46, 0x3b, 0xbc,
-0xaa, 0xab, 0xd3, 0x68, 0xfe, 0xd3, 0xcd, 0xdb, 0x54, 0x3d,
-0x4a, 0xbc, 0xac, 0xb4, 0x3f, 0x2e, 0x3d, 0xba, 0xb0, 0xb8,
-0xba, 0xb6, 0xba, 0xcd, 0xfe, 0xfe, 0x5c, 0x54, 0xc9, 0xb4,
-0xbe, 0x54, 0x54, 0xcd, 0xb6, 0xc9, 0x46, 0x54, 0xcd, 0xc5,
-0xdb, 0xfe, 0xfe, 0xc1, 0xae, 0xa9, 0xac, 0xfe, 0x35, 0x2e,
-0xfe, 0xba, 0xc1, 0x5c, 0xfe, 0xb6, 0xaa, 0xb0, 0xe7, 0x35,
-0x2e, 0x39, 0xc1, 0xac, 0xb0, 0xfe, 0xfe, 0xbc, 0xa6, 0xac,
-0xc1, 0x42, 0x46, 0x54, 0xfe, 0xfe, 0xfe, 0xfe, 0xc9, 0xae,
-0xa9, 0xb0, 0x54, 0x35, 0x37, 0xfe, 0xd3, 0xd3, 0xb8, 0xae,
-0xab, 0xb6, 0xe7, 0xfe, 0xfe, 0x68, 0xfe, 0xfe, 0xfe, 0x4e,
-0xfe, 0xb0, 0xac, 0xb8, 0xfe, 0xfe, 0xc1, 0xb6, 0xc5, 0x46,
-0x3d, 0xe7, 0xb4, 0xa7, 0xab, 0xbc, 0x3f, 0x37, 0x54, 0xba,
-0xcd, 0x54, 0x42, 0xc5, 0xae, 0xac, 0xc9, 0x46, 0x3d, 0x54,
-0xba, 0xb0, 0xb0, 0xfe, 0x5c, 0xcd, 0xb0, 0xb0, 0xc9, 0x54,
-0x54, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xcd, 0xc1, 0xba, 0xc5,
-0xfe, 0x42, 0x46, 0xfe, 0xc5, 0xba, 0xb2, 0xa7, 0xa7, 0xb0,
-0xfe, 0x3d, 0x4a, 0x5c, 0xfe, 0xfe, 0xfe, 0xe7, 0xbc, 0xb0,
-0xae, 0xc5, 0x4e, 0x39, 0xfe, 0xc5, 0xbe, 0xfe, 0x54, 0xc9,
-0xa9, 0xa2, 0xa5, 0xbc, 0x3b, 0x2f, 0x35, 0xfe, 0xc9, 0xfe,
-0xfe, 0xc5, 0xa9, 0xa6, 0xb0, 0x54, 0x31, 0x31, 0x3f, 0xd3,
-0xbc, 0xc1, 0xcd, 0xb8, 0xae, 0xa8, 0xb4, 0xd3, 0x54, 0x4e,
-0x5c, 0x54, 0xfe, 0xdb, 0xba, 0xb4, 0xb4, 0xba, 0xcd, 0x5c,
-0x3d, 0x3f, 0x54, 0xfe, 0xcd, 0xaf, 0xa8, 0xac, 0xc5, 0xfe,
-0xfe, 0xe7, 0xdb, 0xfe, 0xfe, 0xfe, 0xe7, 0xb8, 0xaf, 0xb0,
-0xe7, 0x42, 0x4a, 0xcd, 0xbc, 0xdb, 0x46, 0x68, 0xcd, 0xb0,
-0xab, 0xbc, 0xfe, 0x3d, 0x46, 0xfe, 0xb8, 0xbc, 0xd3, 0xd3,
-0xb6, 0xb0, 0xb6, 0x5c, 0x3b, 0x35, 0x54, 0xdb, 0xba, 0xb4,
-0xc1, 0xc9, 0xc1, 0xba, 0xc9, 0x5c, 0x3d, 0x46, 0xfe, 0xcd,
-0xc5, 0xb8, 0xae, 0xaf, 0xb4, 0xd3, 0x54, 0x3d, 0x35, 0x46,
-0xfe, 0xdb, 0xbc, 0xb2, 0xa9, 0xab, 0xba, 0x3f, 0x31, 0x39,
-0xfe, 0xe7, 0xdb, 0xcd, 0xb8, 0xae, 0xab, 0xac, 0xe7, 0x3d,
-0x2d, 0x3f, 0xfe, 0xdb, 0xfe, 0xfe, 0xbc, 0xaa, 0xa8, 0xb0,
-0xfe, 0x31, 0x2d, 0x3d, 0xdb, 0xc5, 0xcd, 0xc9, 0xb4, 0xa8,
-0xad, 0xc5, 0x46, 0x39, 0x3f, 0x5c, 0xfe, 0xd3, 0xc5, 0xc1,
-0xb6, 0xb0, 0xbc, 0x68, 0x46, 0x4e, 0xe7, 0xfe, 0x5c, 0xfe,
-0xc1, 0xaf, 0xb0, 0xb8, 0xe7, 0x5c, 0x5c, 0xfe, 0xe7, 0xfe,
-0xfe, 0xe7, 0xb0, 0xab, 0xb2, 0x4a, 0x37, 0x3f, 0xcd, 0xbe,
-0xc1, 0xe7, 0xe7, 0xd3, 0xb6, 0xb4, 0xc9, 0x3b, 0x33, 0x4a,
-0xba, 0xb4, 0xc5, 0xfe, 0xc9, 0xb6, 0xb4, 0xcd, 0xfe, 0x3b,
-0x3b, 0xfe, 0xc1, 0xb6, 0xc5, 0xc5, 0xb8, 0xb0, 0xba, 0x4a,
-0x31, 0x35, 0x68, 0xcd, 0xc5, 0xba, 0xb4, 0xb0, 0xb0, 0xba,
-0x5c, 0x35, 0x2f, 0x4e, 0xd3, 0xc1, 0xdb, 0xd3, 0xb4, 0xa9,
-0xab, 0xcd, 0x3b, 0x2f, 0x35, 0xfe, 0xd3, 0xd3, 0xdb, 0xbc,
-0xad, 0xa4, 0xb0, 0xfe, 0x2d, 0x2f, 0x3f, 0xe7, 0xe7, 0xe7,
-0xcd, 0xb4, 0xaf, 0xad, 0xc5, 0x3d, 0x31, 0x3d, 0xe7, 0xd3,
-0xe7, 0xe7, 0xc1, 0xaf, 0xad, 0xb6, 0xfe, 0x4a, 0x42, 0x54,
-0xfe, 0x68, 0xfe, 0xd3, 0xb2, 0xae, 0xb4, 0xfe, 0x42, 0x4e,
-0xcd, 0xc5, 0xcd, 0xdb, 0xc9, 0xb4, 0xb0, 0xb6, 0xfe, 0x3b,
-0x42, 0xe7, 0xb0, 0xb8, 0xcd, 0xfe, 0xc9, 0xb6, 0xb8, 0xfe,
-0x42, 0x3d, 0xfe, 0xc1, 0xb0, 0xba, 0xd3, 0xfe, 0xc1, 0xb0,
-0xb6, 0xfe, 0x3b, 0x3f, 0xe7, 0xba, 0xb8, 0xbc, 0xc5, 0xc1,
-0xc1, 0xcd, 0xfe, 0x3b, 0x37, 0xfe, 0xc1, 0xb4, 0xb6, 0xb8,
-0xb6, 0xb8, 0xc5, 0x5c, 0x3f, 0x46, 0xfe, 0xcd, 0xc5, 0xcd,
-0xcd, 0xc1, 0xb2, 0xb2, 0xfe, 0x3f, 0x35, 0x54, 0xdb, 0xc1,
-0xcd, 0xcd, 0xbc, 0xaf, 0xac, 0xb6, 0x54, 0x35, 0x31, 0x68,
-0xba, 0xb8, 0xcd, 0xdb, 0xc9, 0xb2, 0xb4, 0xc9, 0x46, 0x39,
-0x42, 0xdb, 0xbc, 0xbc, 0xcd, 0xcd, 0xbe, 0xb2, 0xb8, 0xe7,
-0x54, 0x46, 0xfe, 0xfe, 0xdb, 0xc9, 0xc5, 0xbe, 0xbe, 0xc9,
-0xfe, 0x5c, 0x5c, 0xfe, 0xd3, 0xcd, 0xcd, 0xc5, 0xb6, 0xb2,
-0xc5, 0x68, 0x4e, 0xfe, 0xc5, 0xc1, 0xcd, 0x68, 0x5c, 0xe7,
-0xb8, 0xb6, 0xd3, 0x4a, 0x46, 0xfe, 0xbc, 0xb8, 0xc1, 0xe7,
-0xe7, 0xc1, 0xb4, 0xbe, 0xfe, 0x3f, 0x3f, 0xfe, 0xba, 0xb2,
-0xba, 0xe7, 0xfe, 0xcd, 0xcd, 0xfe, 0x4e, 0x46, 0xfe, 0xc5,
-0xb8, 0xb2, 0xba, 0xc1, 0xcd, 0xd3, 0xe7, 0xfe, 0x5c, 0x5c,
-0xfe, 0xe7, 0xc5, 0xbe, 0xb6, 0xba, 0xc5, 0xfe, 0x3f, 0x3f,
-0x54, 0xfe, 0xd3, 0xc1, 0xbc, 0xb6, 0xb0, 0xb0, 0xd3, 0x54,
-0x39, 0x46, 0xfe, 0xc1, 0xcd, 0xe7, 0xe7, 0xc5, 0xb8, 0xb4,
-0xd3, 0x54, 0x37, 0x42, 0xdb, 0xbe, 0xc1, 0xd3, 0xcd, 0xb8,
-0xb0, 0xb0, 0xcd, 0x4a, 0x3b, 0x42, 0xe7, 0xc5, 0xbe, 0xcd,
-0xe7, 0xd3, 0xc5, 0xcd, 0xfe, 0x54, 0x54, 0x68, 0xe7, 0xc5,
-0xc1, 0xc1, 0xcd, 0xcd, 0xc9, 0xc9, 0xcd, 0xe7, 0xfe, 0xfe,
-0xfe, 0xe7, 0xc5, 0xbe, 0xc1, 0xfe, 0x5c, 0x5c, 0xfe, 0xcd,
-0xcd, 0xcd, 0xdb, 0xd3, 0xc1, 0xbc, 0xbe, 0xfe, 0x4e, 0x54,
-0xcd, 0xb6, 0xb8, 0xd3, 0x5c, 0x5c, 0xfe, 0xc5, 0xc9, 0xfe,
-0x46, 0x4a, 0xe7, 0xb4, 0xb6, 0xc5, 0xfe, 0xe7, 0xcd, 0xc9,
-0xdb, 0xfe, 0x4e, 0x68, 0xd3, 0xb6, 0xb2, 0xbc, 0xfe, 0x68,
-0xfe, 0xfe, 0x68, 0x54, 0x68, 0xe7, 0xc5, 0xbc, 0xb8, 0xbe,
-0xcd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xd3, 0xd3, 0xcd,
-0xc1, 0xb8, 0xbc, 0xdb, 0x4e, 0x42, 0x4a, 0xfe, 0xc9, 0xc1,
-0xcd, 0xd3, 0xcd, 0xba, 0xb8, 0xcd, 0x46, 0x3b, 0xfe, 0xc9,
-0xba, 0xcd, 0xe7, 0xfe, 0xd3, 0xc1, 0xba, 0xdb, 0x54, 0x3d,
-0x68, 0xd3, 0xbc, 0xcd, 0xfe, 0xfe, 0xc5, 0xbe, 0xc1, 0xe7,
-0x54, 0x4a, 0xfe, 0xc9, 0xc1, 0xcd, 0xfe, 0xfe, 0xd3, 0xd3,
-0xd3, 0xfe, 0xe7, 0xe7, 0xe7, 0xdb, 0xd3, 0xe7, 0xe7, 0xe7,
-0xfe, 0xfe, 0xfe, 0xfe, 0xcd, 0xc9, 0xdb, 0xfe, 0xfe, 0xdb,
-0xbe, 0xc9, 0xfe, 0x5c, 0xfe, 0xc9, 0xbc, 0xbe, 0xdb, 0x68,
-0x5c, 0xdb, 0xc5, 0xd3, 0x54, 0x46, 0xfe, 0xbc, 0xb2, 0xb8,
-0xdb, 0x68, 0x68, 0xe7, 0xcd, 0xdb, 0x5c, 0x54, 0xfe, 0xc1,
-0xb8, 0xc1, 0xe7, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe,
-0xd3, 0xc5, 0xc1, 0xc5, 0xcd, 0xd3, 0xe7, 0xfe, 0x54, 0x4e,
-0xfe, 0xd3, 0xcd, 0xd3, 0xd3, 0xc5, 0xc1, 0xc1, 0xe7, 0x5c,
-0x4e, 0x5c, 0xd3, 0xc1, 0xcd, 0xfe, 0xfe, 0xcd, 0xba, 0xba,
-0xe7, 0x4a, 0x4a, 0x68, 0xcd, 0xc5, 0xcd, 0xfe, 0xfe, 0xcd,
-0xb8, 0xc1, 0xe7, 0x4e, 0x5c, 0xe7, 0xc1, 0xc9, 0xdb, 0xfe,
-0xe7, 0xc9, 0xc5, 0xd3, 0xfe, 0x68, 0xfe, 0xdb, 0xd3, 0xe7,
-0xfe, 0xfe, 0xcd, 0xc9, 0xcd, 0xd3, 0xd3, 0xd3, 0xcd, 0xe7,
-0xfe, 0xfe, 0xe7, 0xc5, 0xc5, 0xe7, 0x68, 0x68, 0xe7, 0xc1,
-0xc5, 0xfe, 0x5c, 0xfe, 0xd3, 0xc1, 0xd3, 0xfe, 0x68, 0xe7,
-0xc5, 0xb6, 0xc5, 0xe7, 0x68, 0xfe, 0xcd, 0xc5, 0xe7, 0xfe,
-0x54, 0xfe, 0xc9, 0xc5, 0xdb, 0xfe, 0xfe, 0xfe, 0xd3, 0xd3,
-0xfe, 0xfe, 0xfe, 0xcd, 0xc1, 0xc1, 0xc9, 0xd3, 0xd3, 0xe7,
-0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xd3, 0xdb, 0xe7, 0xe7, 0xd3,
-0xcd, 0xd3, 0xfe, 0xfe, 0xfe, 0xcd, 0xc5, 0xd3, 0xe7, 0xe7,
-0xc9, 0xbc, 0xbe, 0xe7, 0x68, 0x4a, 0xfe, 0xdb, 0xcd, 0xfe,
-0xfe, 0xfe, 0xcd, 0xc1, 0xc9, 0xfe, 0x54, 0x5c, 0xe7, 0xc9,
-0xc5, 0xe7, 0xfe, 0xfe, 0xcd, 0xc5, 0xc5, 0xe7, 0xfe, 0xfe,
-0xfe, 0xe7, 0xe7, 0xfe, 0xfe, 0xdb, 0xd3, 0xd3, 0xdb, 0xe7,
-0xfe, 0xfe, 0xe7, 0xe7, 0xdb, 0xd3, 0xc9, 0xd3, 0xe7, 0xfe,
-0xfe, 0xd3, 0xd3, 0xdb, 0xfe, 0xfe, 0xfe, 0xd3, 0xcd, 0xcd,
-0xfe, 0xfe, 0xe7, 0xc9, 0xc5, 0xd3, 0xfe, 0xfe, 0xfe, 0xcd,
-0xc9, 0xd3, 0xfe, 0xfe, 0xfe, 0xdb, 0xc9, 0xcd, 0xe7, 0xfe,
-0xe7, 0xcd, 0xcd, 0xe7, 0xfe, 0xfe, 0xe7, 0xd3, 0xc5, 0xcd,
-0xe7, 0xfe, 0xfe, 0xfe, 0xdb, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe,
-0xe7, 0xcd, 0xcd, 0xd3, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe,
-0xe7, 0xe7, 0xdb, 0xc9, 0xc1, 0xc5, 0xfe, 0x5c, 0x68, 0xfe,
-0xd3, 0xdb, 0xe7, 0xe7, 0xe7, 0xd3, 0xc5, 0xcd, 0xe7, 0x68,
-0xfe, 0xe7, 0xcd, 0xd3, 0xe7, 0xfe, 0xe7, 0xcd, 0xc1, 0xc1,
-0xdb, 0xfe, 0x54, 0xfe, 0xe7, 0xcd, 0xe7, 0xfe, 0xe7, 0xd3,
-0xcd, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xcd, 0xc5, 0xcd, 0xfe,
-0xfe, 0xe7, 0xcd, 0xd3, 0xdb, 0xe7, 0xfe, 0xfe, 0xfe, 0xe7,
-0xd3, 0xd3, 0xe7, 0xfe, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe,
-0xfe, 0xdb, 0xc5, 0xc1, 0xd3, 0xfe, 0xfe, 0xfe, 0xd3, 0xc9,
-0xcd, 0xe7, 0xfe, 0xfe, 0xd3, 0xcd, 0xdb, 0xfe, 0x5c, 0xfe,
-0xcd, 0xc9, 0xd3, 0xfe, 0xfe, 0xfe, 0xd3, 0xc9, 0xcd, 0xfe,
-0x68, 0xfe, 0xd3, 0xc1, 0xc1, 0xdb, 0xfe, 0xfe, 0xe7, 0xe7,
-0xfe, 0xfe, 0x68, 0xfe, 0xe7, 0xc5, 0xc9, 0xdb, 0xfe, 0xfe,
-0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xdb, 0xc5, 0xc5,
-0xd3, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xfe,
-0xc9, 0xc1, 0xc5, 0xfe, 0x54, 0x5c, 0xfe, 0xcd, 0xc5, 0xcd,
-0xfe, 0xfe, 0xdb, 0xc5, 0xc9, 0xfe, 0x5c, 0x68, 0xfe, 0xcd,
-0xcd, 0xfe, 0xfe, 0xfe, 0xe7, 0xc5, 0xc1, 0xd3, 0xfe, 0xfe,
-0xdb, 0xc9, 0xc5, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe,
-0xfe, 0xfe, 0xe7, 0xcd, 0xcd, 0xdb, 0xfe, 0xfe, 0xfe, 0xfe,
-0xe7, 0xd3, 0xcd, 0xd3, 0xfe, 0xfe, 0xdb, 0xcd, 0xd3, 0xe7,
-0xfe, 0xfe, 0xfe, 0xdb, 0xcd, 0xd3, 0xe7, 0xfe, 0xd3, 0xc5,
-0xc9, 0xfe, 0x5c, 0x54, 0xfe, 0xcd, 0xc1, 0xcd, 0xe7, 0xfe,
-0xfe, 0xd3, 0xcd, 0xfe, 0x54, 0x5c, 0xe7, 0xc1, 0xc1, 0xd3,
-0xfe, 0xfe, 0xe7, 0xd3, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xcd,
-0xc5, 0xcd, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xe7, 0xd3, 0xcd, 0xc9, 0xcd, 0xe7, 0xfe, 0xfe, 0xfe, 0xdb,
-0xc9, 0xcd, 0xe7, 0xfe, 0xe7, 0xc9, 0xc5, 0xdb, 0xfe, 0x5c,
-0xfe, 0xe7, 0xcd, 0xcd, 0xe7, 0xfe, 0xe7, 0xc5, 0xc1, 0xd3,
-0xfe, 0x5c, 0xfe, 0xcd, 0xc5, 0xcd, 0xe7, 0xfe, 0xfe, 0xe7,
-0xd3, 0xe7, 0xfe, 0xfe, 0xe7, 0xcd, 0xcd, 0xdb, 0xfe, 0xfe,
-0xfe, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xe7, 0xdb, 0xcd, 0xd3,
-0xd3, 0xdb, 0xfe, 0xfe, 0xfe, 0xfe, 0xdb, 0xd3, 0xdb, 0xe7,
-0xe7, 0xdb, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xe7, 0xc9, 0xc5,
-0xcd, 0xe7, 0xfe, 0xdb, 0xd3, 0xe7, 0xfe, 0x68, 0xfe, 0xe7,
-0xcd, 0xcd, 0xd3, 0xfe, 0xfe, 0xe7, 0xdb, 0xe7, 0xfe, 0x68,
-0xfe, 0xdb, 0xfe, 0x68, 0xbe, 0xb2, 0xae, 0xab, 0xb2, 0xfe,
-0x2f, 0x31, 0xdb, 0xac, 0xad, 0xaf, 0xab, 0xab, 0xb4, 0x68,
-0x37, 0x39, 0x3f, 0xe7, 0xb4, 0xa8, 0xaa, 0xb0, 0xbc, 0xbc,
-0xc5, 0x3f, 0x31, 0x3d, 0xfe, 0xc1, 0xb8, 0xb0, 0xa5, 0xa2,
-0xa8, 0xaf, 0xdb, 0x3b, 0x28, 0x2a, 0x3d, 0xbc, 0xb0, 0xaa,
-0xa2, 0x9f, 0xab, 0xfe, 0x29, 0x24, 0x29, 0x4a, 0xb4, 0xaa,
-0xa8, 0xa9, 0xa8, 0xa5, 0xac, 0xdb, 0x2c, 0x27, 0x35, 0x4a,
-0xfe, 0xcd, 0xb2, 0xa2, 0x9f, 0x9f, 0xae, 0x4e, 0x2c, 0x22,
-0x33, 0xfe, 0xba, 0xb0, 0xa6, 0x9f, 0xa3, 0xbc, 0x5c, 0x33,
-0x31, 0x39, 0x5c, 0xcd, 0xc1, 0xb4, 0xad, 0xaa, 0xad, 0xcd,
-0x54, 0x46, 0xfe, 0xe7, 0xfe, 0x54, 0xc5, 0xaf, 0xa6, 0xa9,
-0xb0, 0xfe, 0x3d, 0x39, 0x5c, 0xdb, 0xdb, 0xfe, 0xba, 0xac,
-0xa8, 0xc5, 0x39, 0x33, 0x54, 0xb8, 0xae, 0xad, 0xb8, 0xc1,
-0xcd, 0xbe, 0xbc, 0xfe, 0x39, 0x37, 0xfe, 0xb4, 0xba, 0xcd,
-0xdb, 0xb8, 0xb0, 0xb6, 0xfe, 0x4e, 0x39, 0x3d, 0xfe, 0xb0,
-0xaa, 0xa9, 0xa9, 0xaa, 0xb0, 0x5c, 0x29, 0x28, 0x31, 0xfe,
-0xba, 0xb4, 0xae, 0xab, 0xab, 0xb2, 0xfe, 0x3b, 0x2a, 0x2f,
-0x54, 0xb4, 0xb4, 0xba, 0xb2, 0xa3, 0x9f, 0xa8, 0xfe, 0x2c,
-0x27, 0x2a, 0x46, 0xfe, 0xc1, 0xbc, 0xb0, 0xa2, 0xa2, 0xb0,
-0x33, 0x22, 0x2b, 0x46, 0xc1, 0xb4, 0xb0, 0xab, 0xa8, 0xa8,
-0xb0, 0xdb, 0x42, 0x2c, 0x33, 0x4a, 0xfe, 0x5c, 0xdb, 0xb4,
-0xa8, 0xad, 0xba, 0xfe, 0x46, 0x39, 0x39, 0x4a, 0xfe, 0xbc,
-0xab, 0xa5, 0xa5, 0xb8, 0x68, 0x37, 0x4a, 0xe7, 0xfe, 0x4a,
-0x5c, 0xd3, 0xb0, 0xb2, 0xc1, 0x5c, 0x42, 0x46, 0xd3, 0xb4,
-0xbe, 0x54, 0x54, 0xb6, 0xab, 0xae, 0xe7, 0x46, 0x4a, 0xfe,
-0xcd, 0xc9, 0xd3, 0xe7, 0xe7, 0xbe, 0xb4, 0xc5, 0x37, 0x2c,
-0x37, 0xc1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb6, 0xdb, 0x54, 0x4a,
-0x46, 0x42, 0x68, 0xba, 0xb2, 0xba, 0xc5, 0xb6, 0xb6, 0xcd,
-0x33, 0x2f, 0x39, 0x68, 0xfe, 0xe7, 0xba, 0xac, 0xa7, 0xa7,
-0xb2, 0xe7, 0x2d, 0x25, 0x2f, 0xd3, 0xbe, 0xd3, 0xc5, 0xac,
-0xa6, 0xac, 0xfe, 0x33, 0x2c, 0x2d, 0x54, 0xc1, 0xb4, 0xcd,
-0xcd, 0xaf, 0xa4, 0xa8, 0xe7, 0x31, 0x31, 0x39, 0x46, 0xfe,
-0xdb, 0xbc, 0xb6, 0xaf, 0xa9, 0xb2, 0xfe, 0x2f, 0xfe, 0xba,
-0xad, 0xba, 0x4e, 0x3d, 0x42, 0xfe, 0xc9, 0xc1, 0xe7, 0xfe,
-0xc1, 0xa9, 0xa6, 0xcd, 0x2a, 0x25, 0x3b, 0xbc, 0xb0, 0xb6,
-0xb8, 0xb4, 0xb4, 0xb8, 0xc1, 0xfe, 0x3d, 0x3d, 0xfe, 0xba,
-0xd3, 0x54, 0x54, 0xbe, 0xb0, 0xb4, 0xe7, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xc5, 0xb6, 0xa9, 0xaa, 0xba, 0x3d, 0x39,
-0xfe, 0xc1, 0xfe, 0x4a, 0x54, 0xbe, 0xb2, 0xb8, 0xfe, 0x3d,
-0x3b, 0xfe, 0xb0, 0xab, 0xc5, 0x39, 0x3b, 0xbc, 0xa7, 0xab,
-0xd3, 0x68, 0xfe, 0xd3, 0xcd, 0xfe, 0x54, 0x3d, 0xfe, 0xbc,
-0xac, 0xc9, 0x3f, 0x2e, 0xfe, 0xba, 0xb0, 0xba, 0xba, 0xb6,
-0xba, 0xd3, 0xfe, 0xfe, 0x5c, 0x54, 0xc9, 0xb4, 0xbe, 0x54,
-0x68, 0xcd, 0xb6, 0xfe, 0x46, 0x54, 0xcd, 0xc5, 0xdb, 0xfe,
-0xe7, 0xc1, 0xae, 0xa8, 0xac, 0xfe, 0x2e, 0x2e, 0xfe, 0xb6,
-0xc1, 0x5c, 0xe7, 0xb6, 0xaa, 0xb0, 0x54, 0x35, 0x2e, 0x4a,
-0xc1, 0xac, 0xbc, 0xfe, 0xfe, 0xaf, 0xa6, 0xac, 0xfe, 0x42,
-0x46, 0x5c, 0xfe, 0xfe, 0xfe, 0xe7, 0xc9, 0xae, 0xa9, 0xb0,
-0x54, 0x31, 0x37, 0xfe, 0xd3, 0xd3, 0xb8, 0xac, 0xab, 0xb6,
-0xe7, 0xfe, 0xfe, 0x68, 0xfe, 0xfe, 0xfe, 0x54, 0xfe, 0xb0,
-0xae, 0xb8, 0xfe, 0xe7, 0xc1, 0xb6, 0xe7, 0x46, 0x3d, 0xe7,
-0xae, 0xa7, 0xab, 0xdb, 0x3f, 0x37, 0xfe, 0xba, 0xcd, 0x3f,
-0x42, 0xc5, 0xab, 0xac, 0xc9, 0x46, 0x3d, 0x54, 0xba, 0xad,
-0xb0, 0xfe, 0x68, 0xcd, 0xb0, 0xb0, 0xc9, 0x54, 0x54, 0xfe,
-0xfe, 0xfe, 0xfe, 0xe7, 0xcd, 0xbe, 0xba, 0xc5, 0x68, 0x42,
-0x46, 0xe7, 0xc5, 0xba, 0xaf, 0xa7, 0xa7, 0xbc, 0xfe, 0x3d,
-0x4a, 0x68, 0xfe, 0xfe, 0xfe, 0xe7, 0xbc, 0xaf, 0xae, 0xc5,
-0x3d, 0x39, 0xfe, 0xbc, 0xbe, 0xfe, 0x68, 0xc9, 0xa9, 0xa2,
-0xaa, 0xbc, 0x3b, 0x2d, 0x35, 0xfe, 0xcd, 0xfe, 0xfe, 0xb4,
-0xa9, 0xa6, 0xbc, 0x54, 0x31, 0x31, 0x54, 0xd3, 0xbc, 0xc5,
-0xcd, 0xb8, 0xab, 0xa8, 0xb4, 0xfe, 0x54, 0x4e, 0x68, 0x54,
-0xfe, 0xc9, 0xba, 0xb4, 0xb4, 0xba, 0xcd, 0x5c, 0x3b, 0x3f,
-0x54, 0xfe, 0xcd, 0xaf, 0xa8, 0xac, 0xc5, 0x68, 0xfe, 0xe7,
-0xdb, 0xfe, 0xfe, 0xfe, 0xcd, 0xb8, 0xaf, 0xb6, 0xe7, 0x42,
-0x5c, 0xcd, 0xbc, 0xfe, 0x46, 0x68, 0xba, 0xb0, 0xab, 0xbc,
-0x54, 0x3d, 0x46, 0xc9, 0xb8, 0xbc, 0xdb, 0xd3, 0xb6, 0xb0,
-0xb6, 0x5c, 0x37, 0x35, 0x54, 0xc9, 0xba, 0xb4, 0xc1, 0xc9,
-0xc1, 0xba, 0xe7, 0x5c, 0x3d, 0x54, 0xfe, 0xcd, 0xc5, 0xb8,
-0xae, 0xaf, 0xb4, 0xd3, 0x54, 0x3b, 0x35, 0x46, 0xfe, 0xdb,
-0xbc, 0xaf, 0xa9, 0xab, 0xd3, 0x3f, 0x31, 0x3f, 0xfe, 0xe7,
-0xdb, 0xcd, 0xb8, 0xae, 0xaa, 0xac, 0xe7, 0x33, 0x2d, 0x3f,
-0xd3, 0xdb, 0xfe, 0xfe, 0xbc, 0xaa, 0xa9, 0xb0, 0xfe, 0x31,
-0x2f, 0x3d, 0xdb, 0xc5, 0xcd, 0xc9, 0xae, 0xa8, 0xad, 0xfe,
-0x46, 0x39, 0x46, 0x5c, 0xfe, 0xcd, 0xc5, 0xc1, 0xb6, 0xb0,
-0xbc, 0x68, 0x42, 0x4e, 0xe7, 0xfe, 0x5c, 0xfe, 0xb6, 0xaf,
-0xb0, 0xc5, 0xe7, 0x5c, 0x5c, 0xfe, 0xe7, 0xfe, 0x68, 0xe7,
-0xb0, 0xac, 0xb2, 0x4a, 0x35, 0x3f, 0xcd, 0xbc, 0xc1, 0xe7,
-0xe7, 0xd3, 0xb6, 0xb4, 0xfe, 0x3b, 0x33, 0xfe, 0xba, 0xb4,
-0xd3, 0xfe, 0xc9, 0xb4, 0xb4, 0xcd, 0x4a, 0x3b, 0x3b, 0xfe,
-0xb8, 0xb6, 0xc5, 0xc5, 0xb8, 0xb0, 0xcd, 0x4a, 0x31, 0x3b,
-0x68, 0xcd, 0xc1, 0xba, 0xb4, 0xb0, 0xb0, 0xba, 0x5c, 0x2f,
-0x2f, 0x4e, 0xc9, 0xc1, 0xdb, 0xc9, 0xb4 };
diff --git a/1.4/apps/leave.h b/1.4/apps/leave.h
deleted file mode 100644
index 238976f20..000000000
--- a/1.4/apps/leave.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * U-law 8-bit audio data
- *
- * Source: leave.raw
- *
- * Copyright (C) 1999, Mark Spencer and Linux Support Services
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char leave[] = {
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xc1, 0x3d,
-0x42, 0x46, 0x3f, 0x3f, 0x46, 0x3f, 0x4e, 0xba, 0xbe, 0xbe,
-0xbc, 0xba, 0xbe, 0xc5, 0xb6, 0x2e, 0x2c, 0x33, 0x2f, 0x2e,
-0x2f, 0x33, 0x2b, 0x54, 0xac, 0xb0, 0xb0, 0xad, 0xaf, 0xb0,
-0xae, 0xcd, 0x3b, 0x2f, 0x31, 0x2e, 0x2f, 0x31, 0x2e, 0x46,
-0xc5, 0xaf, 0xb0, 0xaf, 0xae, 0xaf, 0xaf, 0xb0, 0xfe, 0x2d,
-0x31, 0x31, 0x2e, 0x31, 0x2f, 0x31, 0xfe, 0xae, 0xaf, 0xaf,
-0xae, 0xb0, 0xae, 0xaf, 0xfe, 0xdb, 0x2e, 0x2e, 0x31, 0x31,
-0x2d, 0x2e, 0xdb, 0x68, 0xaf, 0xad, 0xb0, 0xb0, 0xae, 0xaf,
-0x5c, 0xe7, 0x39, 0x2d, 0x31, 0x31, 0x31, 0x2d, 0xfe, 0xfe,
-0x68, 0xad, 0xaf, 0xb0, 0xaf, 0xac, 0xbc, 0xfe, 0xd3, 0x2f,
-0x2e, 0x33, 0x31, 0x2d, 0x4e, 0xdb, 0xfe, 0xfe, 0xac, 0xaf,
-0xb0, 0xac, 0xb6, 0x68, 0xe7, 0xdb, 0x2e, 0x2f, 0x35, 0x2f,
-0x31, 0xe7, 0xe7, 0x68, 0xad, 0xac, 0xb0, 0xae, 0xac, 0xfe,
-0xfe, 0xdb, 0xfe, 0x2d, 0x33, 0x31, 0x2e, 0xfe, 0xfe, 0xfe,
-0xfe, 0xbc, 0xaf, 0xb0, 0xad, 0xfe, 0xfe, 0xfe, 0xe7, 0x5c,
-0x2e, 0x33, 0x2e, 0x35, 0xe7, 0xfe, 0xfe, 0xfe, 0xad, 0xb0,
-0xaf, 0xc1, 0xfe, 0xe7, 0xfe, 0xe7, 0x3d, 0x31, 0x2f, 0x37,
-0xe7, 0xfe, 0xfe, 0xe7, 0xfe, 0xaf, 0xad, 0xbe, 0xfe, 0xdb,
-0xfe, 0xfe, 0xdb, 0x35, 0x2d, 0x39, 0xdb, 0xfe, 0xfe, 0xdb,
-0xfe, 0xfe, 0xad, 0xaf, 0xfe, 0xfe, 0xe7, 0x68, 0xfe, 0xd3,
-0x2e, 0x2c, 0xdb, 0xdb, 0x2c, 0x35, 0xd3, 0x68, 0xaf, 0xad,
-0xb0, 0xb0, 0xad, 0xba, 0x68, 0xe7, 0xe7, 0x2e, 0x2f, 0x33,
-0x31, 0x2d, 0xdb, 0xd3, 0x5c, 0xae, 0xaa, 0xe7, 0x68, 0xaa,
-0xe7, 0xfe, 0xdb, 0xe7, 0xfe, 0xe7, 0xd3, 0x2d, 0xfe, 0xdb,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xc5, 0xfe, 0xe7, 0xe7,
-0xfe, 0xfe, 0xe7, 0xe7, 0x3b, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xc5, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xfe, 0x3b,
-0xdb, 0xfe, 0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xb0, 0xfe, 0xfe,
-0xe7, 0xfe, 0xfe, 0xfe, 0xdb, 0x2e, 0x5c, 0xdb, 0xfe, 0xfe,
-0xe7, 0xe7, 0x68, 0xb0, 0xbe, 0x68, 0xe7, 0xe7, 0xfe, 0xfe,
-0xdb, 0x39, 0x2f, 0xdb, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xbe,
-0xaf, 0xe7, 0x68, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0x33, 0x33,
-0xdb, 0xfe, 0xfe, 0xdb, 0xe7, 0xfe, 0xb0, 0xb0, 0xfe, 0xfe,
-0xe7, 0xfe, 0xfe, 0xfe, 0x35, 0x33, 0xe7, 0xe7, 0xfe, 0xe7,
-0xe7, 0xfe, 0xb0, 0xb2, 0xb0, 0xfe, 0xfe, 0xe7, 0xfe, 0xe7,
-0x46, 0x35, 0x35, 0x3f, 0xe7, 0xfe, 0xe7, 0xfe, 0xb2, 0xb0,
-0xb2, 0xb0, 0xfe, 0xfe, 0xfe, 0xfe, 0x42, 0x35, 0x37, 0x33,
-0xe7, 0xfe, 0xfe, 0xfe, 0xb8, 0xb0, 0xb6, 0xb0, 0xba, 0xfe,
-0xfe, 0xe7, 0xe7, 0x33, 0x39, 0x39, 0x33, 0xe7, 0xdb, 0xfe,
-0xe7, 0xb0, 0xb4, 0xb6, 0xb0, 0xcd, 0xfe, 0xe7, 0xe7, 0x33,
-0x39, 0x3b, 0x33, 0x46, 0xd3, 0xfe, 0xfe, 0xb0, 0xb2, 0xb6,
-0xb4, 0xb0, 0xfe, 0xfe, 0xdb, 0x35, 0x37, 0x39, 0x39, 0x35,
-0x37, 0xdb, 0x68, 0xcd, 0xb2, 0xb6, 0xb6, 0xb4, 0xb4, 0x68,
-0xe7, 0x42, 0x37, 0x3b, 0x3b, 0x39, 0x37, 0xdb, 0xfe, 0xcd,
-0xb2, 0xb6, 0xb6, 0xb6, 0xb2, 0xb4, 0xfe, 0x54, 0x37, 0x3b,
-0x39, 0x3b, 0x3b, 0x39, 0xe7, 0xfe, 0xb6, 0xb6, 0xb6, 0xb4,
-0xb6, 0xb6, 0xbc, 0xfe, 0x3f, 0x3b, 0x3b, 0x39, 0x3b, 0x3b,
-0x39, 0xe7, 0xb6, 0xb8, 0xb8, 0xb6, 0xb8, 0xb8, 0xb4, 0xfe,
-0x3b, 0x3d, 0x3d, 0x3b, 0x39, 0x3d, 0x3b, 0x39, 0xbe, 0xb8,
-0xba, 0xb8, 0xb6, 0xb8, 0xba, 0xb4, 0xfe, 0x39, 0x3f, 0x3d,
-0x3b, 0x3d, 0x3f, 0x39, 0xdb, 0xb4, 0xba, 0xb8, 0xb6, 0xb8,
-0xbc, 0xb4, 0xba, 0x39, 0x42, 0x3f, 0x3d, 0x3d, 0x3f, 0x3f,
-0x3b, 0xb8, 0xb6, 0xbc, 0xb8, 0xb8, 0xba, 0xbc, 0xb8, 0xe7,
-0x3d, 0x42, 0x3f, 0x3d, 0x3f, 0x42, 0x3d, 0xfe, 0xb8, 0xbc,
-0xbc, 0xba, 0xba, 0xbc, 0xba, 0xe7, 0x3d, 0x3f, 0x42, 0x3f,
-0x3f, 0x42, 0x42, 0xfe, 0xfe, 0xbc, 0xbc, 0xbe, 0xbc, 0xbe,
-0xbc, 0xc5, 0xe7, 0x68, 0x42, 0x46, 0x42, 0x46, 0x42, 0x46,
-0xfe, 0xfe, 0xbc, 0xbe, 0xbe, 0xbe, 0xbc, 0xc5, 0xfe, 0xdb,
-0x46, 0x46, 0x4a, 0x4a, 0x46, 0x46, 0xe7, 0xfe, 0xd3, 0xbe,
-0xc9, 0xc9, 0xc5, 0xc5, 0xe7, 0xdb, 0xd3, 0x4a, 0x4e, 0x54,
-0x4e, 0x4e, 0xfe, 0x5c, 0x54, 0xd3, 0xcd, 0xd3, 0xd3, 0xcd,
-0xd3, 0xd3, 0xcd, 0xfe, 0x5c, 0x68, 0x5c, 0x5c, 0x5c, 0x68,
-0x5c, 0x5c, 0xcd, 0xcd, 0xd3, 0xcd, 0xdb, 0xe7, 0xe7, 0xdb,
-0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7,
-0xfe, 0x5c, 0x5c, 0xfe, 0xfe, 0xfe, 0xfe, 0x46, 0x35, 0x35,
-0x37, 0x39, 0x3b, 0x39, 0x35, 0x33, 0x35, 0x5c, 0xd3, 0xcd,
-0xdb, 0xfe, 0xfe, 0xd3, 0xb0, 0xb0, 0xb0, 0xb4, 0xb4, 0xb6,
-0xb2, 0xb0, 0xb0, 0xb6, 0xcd, 0x5c, 0x68, 0xfe, 0xfe, 0xfe,
-0x3b, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x39, 0x37, 0x35, 0x35,
-0x3f, 0xdb, 0xcd, 0xcd, 0xdb, 0xfe, 0xe7, 0xc5, 0xb0, 0xb0,
-0xb2, 0xb6, 0xb6, 0xb6, 0xb2, 0xb0, 0xb0, 0xcd, 0x5c, 0x5c,
-0xfe, 0xe7, 0xe7, 0xfe, 0x35, 0x35, 0x35, 0x39, 0x3b, 0x3b,
-0x39, 0x35, 0x33, 0x39, 0xdb, 0xcd, 0xd3, 0xe7, 0xfe, 0xfe,
-0xba, 0xb0, 0xb0, 0xb2, 0xb4, 0xb6, 0xb6, 0xb4, 0xb2, 0xb0,
-0xb4, 0xc9, 0x5c, 0x68, 0xfe, 0xfe, 0x5c, 0x3b, 0x35, 0x37,
-0x39, 0x3b, 0x3b, 0x3b, 0x39, 0x37, 0x37, 0x3d, 0xe7, 0xcd,
-0xdb, 0xfe, 0xe7, 0xbe, 0xb2, 0xb2, 0xb4, 0xb4, 0xb6, 0xb6,
-0xb6, 0xb4, 0xb0, 0xb0, 0xc5, 0x5c, 0x5c, 0xfe, 0xe7, 0xe7,
-0x4e, 0x35, 0x35, 0x37, 0x3b, 0x3b, 0x3b, 0x39, 0x37, 0x37,
-0x3b, 0xe7, 0xc9, 0xcd, 0xe7, 0xfe, 0xd3, 0xb4, 0xb2, 0xb2,
-0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb4, 0xb2, 0xb4, 0xc1, 0x68,
-0x68, 0xfe, 0xfe, 0x42, 0x39, 0x37, 0x39, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x39, 0x37, 0x3b, 0xfe, 0xd3, 0xdb, 0xfe, 0xcd,
-0xb4, 0xb2, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb4, 0xb2,
-0xb2, 0xc1, 0x5c, 0x5c, 0xfe, 0xfe, 0xfe, 0x3d, 0x37, 0x37,
-0x39, 0x3b, 0x3b, 0x3b, 0x3b, 0x37, 0x37, 0x39, 0xfe, 0xcd,
-0xd3, 0xfe, 0xfe, 0xc1, 0xb2, 0xb2, 0xb4, 0xb6, 0xb6, 0xb6,
-0xb6, 0xb6, 0xb6, 0xb4, 0xb4, 0xbc, 0x68, 0xfe, 0xfe, 0xfe,
-0x3b, 0x39, 0x39, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x39,
-0x39, 0x3b, 0xfe, 0xdb, 0xe7, 0xfe, 0xbc, 0xb6, 0xb6, 0xb6,
-0xb8, 0xb6, 0xb6, 0xb6, 0xb8, 0xb6, 0xb4, 0xb4, 0xbc, 0xfe,
-0x68, 0xfe, 0xe7, 0x5c, 0x3b, 0x39, 0x39, 0x3b, 0x3b, 0x3b,
-0x3d, 0x3d, 0x3b, 0x39, 0x3b, 0x68, 0xdb, 0xdb, 0xfe, 0xe7,
-0xb8, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb6,
-0xb4, 0xb6, 0xdb, 0x68, 0xfe, 0xfe, 0x46, 0x3b, 0x3b, 0x3b,
-0x3d, 0x3d, 0x3b, 0x3d, 0x3d, 0x3d, 0x3d, 0x3b, 0x3b, 0x5c,
-0xdb, 0xdb, 0xc9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbc, 0xcd, 0xfe, 0xfe, 0x3d,
-0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3b, 0x3d, 0x3d, 0x3d, 0x3d,
-0x3b, 0x3d, 0x46, 0xfe, 0xe7, 0xe7, 0xc5, 0xb8, 0xb8, 0xb8,
-0xba, 0xba, 0xb8, 0xb8, 0xba, 0xba, 0xb8, 0xb8, 0xb8, 0xcd,
-0xfe, 0xfe, 0x68, 0x3f, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-0x3d, 0x3d, 0x3f, 0x3f, 0x3d, 0x3b, 0x4a, 0xfe, 0xdb, 0xbc,
-0xb8, 0xba, 0xba, 0xba, 0xba, 0xb8, 0xb8, 0xb8, 0xba, 0xba,
-0xba, 0xba, 0xba, 0xc5, 0xfe, 0x54, 0x3f, 0x3f, 0x3f, 0x3f,
-0x3f, 0x3f, 0x3d, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x42,
-0xfe, 0xe7, 0xdb, 0xbc, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-0xba, 0xba, 0xbc, 0xba, 0xba, 0xba, 0xc5, 0xfe, 0xfe, 0x4e,
-0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x42,
-0x42, 0x42, 0x3f, 0x46, 0xfe, 0xcd, 0xb8, 0xba, 0xbc, 0xbc,
-0xbc, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xba, 0xb8,
-0xbe, 0xfe, 0x42, 0x3d, 0x3f, 0x42, 0x42, 0x42, 0x3f, 0x3f,
-0x3f, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x3f, 0x68, 0xdb, 0xc5,
-0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xba, 0xba, 0xba, 0xbc, 0xbc,
-0xbc, 0xbc, 0xba, 0xc1, 0xfe, 0xfe, 0x3f, 0x42, 0x46, 0x46,
-0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x46, 0x42, 0x3f,
-0x42, 0x68, 0xbe, 0xba, 0xbc, 0xbe, 0xbe, 0xbe, 0xbc, 0xbc,
-0xbc, 0xbc, 0xbe, 0xc1, 0xbe, 0xbc, 0xba, 0xbe, 0x68, 0x3f,
-0x42, 0x46, 0x4a, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x46, 0x46,
-0x46, 0x46, 0x42, 0x42, 0x68, 0xd3, 0xbc, 0xbc, 0xbe, 0xc1,
-0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc1, 0xbe, 0xbe,
-0xc1, 0xfe, 0x4e, 0x42, 0x46, 0x4a, 0x4a, 0x4a, 0x46, 0x46,
-0x46, 0x46, 0x4a, 0x4a, 0x4a, 0x46, 0x46, 0x68, 0xdb, 0xbe,
-0xbe, 0xc1, 0xc5, 0xc1, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xc1,
-0xc5, 0xc5, 0xbe, 0xbc, 0xc1, 0x4e, 0x46, 0x46, 0x4a, 0x4e,
-0x4e, 0x4a, 0x46, 0x46, 0x46, 0x4a, 0x4a, 0x4e, 0x4a, 0x46,
-0x46, 0xfe, 0xbe, 0xbe, 0xc1, 0xc9, 0xc5, 0xc5, 0xc1, 0xc1,
-0xc1, 0xc1, 0xc5, 0xc5, 0xc5, 0xc5, 0xbe, 0xc1, 0xfe, 0x4a,
-0x4a, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4a, 0x4a, 0x4a, 0x4e,
-0x54, 0x4e, 0x4a, 0x4a, 0x4e, 0xcd, 0xc1, 0xc5, 0xc5, 0xc9,
-0xc5, 0xc5, 0xc5, 0xc5, 0xc9, 0xcd, 0xcd, 0xcd, 0xcd, 0xc9,
-0xc9, 0xd3, 0x68, 0x54, 0x5c, 0x68, 0x68, 0x68, 0x5c, 0x5c,
-0x5c, 0x5c, 0x5c, 0x68, 0x68, 0x5c, 0x54, 0x5c, 0xdb, 0xcd,
-0xcd, 0xdb, 0xdb, 0xdb, 0xdb, 0xd3, 0xd3, 0xe7, 0xe7, 0xe7,
-0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
-0xfe, 0xfe, 0xfe };
diff --git a/1.4/apps/rpt_flow.pdf b/1.4/apps/rpt_flow.pdf
deleted file mode 100644
index 2085af0f2..000000000
--- a/1.4/apps/rpt_flow.pdf
+++ /dev/null
Binary files differ
diff --git a/1.4/bootstrap.sh b/1.4/bootstrap.sh
deleted file mode 100755
index d3d51ee76..000000000
--- a/1.4/bootstrap.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-
-check_for_app() {
- $1 --version 2>&1 >/dev/null
- if [ $? != 0 ]
- then
- echo "Please install $1 and run bootstrap.sh again!"
- exit 1
- fi
-}
-
-# On FreeBSD, multiple autoconf/automake versions have different names.
-# On linux, envitonment variables tell which one to use.
-
-uname -s | grep -q FreeBSD
-if [ $? = 0 ] ; then # FreeBSD case
- MY_AC_VER=259
- MY_AM_VER=19
-else # linux case
- MY_AC_VER=
- MY_AM_VER=
- AUTOCONF_VERSION=2.60
- AUTOMAKE_VERSION=1.9
- export AUTOCONF_VERSION
- export AUTOMAKE_VERSION
-fi
-
-check_for_app autoconf${MY_AC_VER}
-check_for_app autoheader${MY_AC_VER}
-check_for_app automake${MY_AM_VER}
-check_for_app aclocal${MY_AM_VER}
-
-echo "Generating the configure script ..."
-
-aclocal${MY_AM_VER} 2>/dev/null
-autoconf${MY_AC_VER}
-autoheader${MY_AC_VER}
-automake${MY_AM_VER} --add-missing --copy 2>/dev/null
-
-exit 0
diff --git a/1.4/build_tools/cflags-devmode.xml b/1.4/build_tools/cflags-devmode.xml
deleted file mode 100644
index 8be92e71f..000000000
--- a/1.4/build_tools/cflags-devmode.xml
+++ /dev/null
@@ -1,17 +0,0 @@
- <category name="MENUSELECT_CFLAGS" displayname="Compiler Flags - Development">
- <member name="DEBUG_SCHEDULER" displayname="Enable Scheduler Debugging Output">
- </member>
- <member name="DEBUG_THREADLOCALS" displayname="Enable Thread-Local-Storage Debugging">
- </member>
- <member name="DETECT_DEADLOCKS" displayname="Detect Deadlocks">
- <depend>DEBUG_THREADS</depend>
- </member>
- <member name="DO_CRASH" displayname="Crash on fatal errors">
- </member>
- <member name="DUMP_SCHEDULER" displayname="Dump Scheduler Contents for Debugging">
- </member>
- <member name="MTX_PROFILE" displayname="Enable Code Profiling Using TSC Counters">
- </member>
- <member name="TRACE_FRAMES" displayname="Trace Frame Allocations">
- </member>
- </category>
diff --git a/1.4/build_tools/cflags.xml b/1.4/build_tools/cflags.xml
deleted file mode 100644
index db140d6aa..000000000
--- a/1.4/build_tools/cflags.xml
+++ /dev/null
@@ -1,19 +0,0 @@
- <category name="MENUSELECT_CFLAGS" displayname="Compiler Flags" positive_output="yes" remove_on_change=".lastclean">
- <member name="DONT_OPTIMIZE" displayname="Disable Optimizations by the Compiler">
- </member>
- <member name="DEBUG_CHANNEL_LOCKS" displayname="Debug Channel Locking">
- </member>
- <member name="DEBUG_THREADS" displayname="Enable Thread Debugging">
- </member>
- <member name="LOW_MEMORY" displayname="Optimize for Low Memory Usage">
- </member>
- <member name="MALLOC_DEBUG" displayname="Keep Track of Memory Allocations">
- </member>
- <member name="RADIO_RELAX" displayname="Relax DTMF for Radio Applications">
- </member>
- <member name="STATIC_BUILD" displayname="Build static binaries">
- </member>
- <member name="LOADABLE_MODULES" displayname="Runtime module loading">
- <defaultenabled>yes</defaultenabled>
- </member>
- </category>
diff --git a/1.4/build_tools/embed_modules.xml b/1.4/build_tools/embed_modules.xml
deleted file mode 100644
index 54ae622ce..000000000
--- a/1.4/build_tools/embed_modules.xml
+++ /dev/null
@@ -1,26 +0,0 @@
- <category name="MENUSELECT_EMBED" displayname="Module Embedding" positive_output="yes" remove_on_change="main/asterisk">
- <member name="apps" displayname="Applications" remove_on_change="apps/*.o">
- <depend>gnu_ld</depend>
- </member>
- <member name="cdr" displayname="Call Detail Recording" remove_on_change="cdr/*.o">
- <depend>gnu_ld</depend>
- </member>
- <member name="channels" displayname="Channels" remove_on_change="channels/*.o channels/misdn/*.o">
- <depend>gnu_ld</depend>
- </member>
- <member name="codecs" displayname="Coders/Decoders" remove_on_change="codecs/*.o codecs/gsm/src/*.o codecs/ilbc/*.o codecs/lpc10/*.o codecs/gsm/lib/libgsm.a codecs/lpc10/liblpc10.a codecs/ilbc/libilbc.a">
- <depend>gnu_ld</depend>
- </member>
- <member name="formats" displayname="File Formats" remove_on_change="formats/*.o">
- <depend>gnu_ld</depend>
- </member>
- <member name="funcs" displayname="Dialplan Functions" remove_on_change="funcs/*.o">
- <depend>gnu_ld</depend>
- </member>
- <member name="pbx" displayname="PBX Functionality" remove_on_change="pbx/*.o pbx/ael/*.o">
- <depend>gnu_ld</depend>
- </member>
- <member name="res" displayname="Resource Modules" remove_on_change="res/*.o res/snmp/*.o">
- <depend>gnu_ld</depend>
- </member>
- </category>
diff --git a/1.4/build_tools/get_makeopts b/1.4/build_tools/get_makeopts
deleted file mode 100644
index e63622afd..000000000
--- a/1.4/build_tools/get_makeopts
+++ /dev/null
@@ -1,3 +0,0 @@
-/\/\*\*\* MAKEOPTS/ {printit=1; next}
-/\*\*\*\// {if (printit) exit}
-// {if (printit) print}
diff --git a/1.4/build_tools/get_moduleinfo b/1.4/build_tools/get_moduleinfo
deleted file mode 100644
index d17c28e06..000000000
--- a/1.4/build_tools/get_moduleinfo
+++ /dev/null
@@ -1,3 +0,0 @@
-/\/\*\*\* MODULEINFO/ {printit=1; next}
-/\*\*\*\// {if (printit) exit}
-// {if (printit) print}
diff --git a/1.4/build_tools/make_build_h b/1.4/build_tools/make_build_h
deleted file mode 100755
index b7dadfc33..000000000
--- a/1.4/build_tools/make_build_h
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-HOSTNAME=`uname -n`
-KERNEL=`uname -r`
-MACHINE=`uname -m`
-OS=`uname -s`
-USER=`${ID} -un`
-DATE=`date -u "+%Y-%m-%d %H:%M:%S"`
-cat << END
-/*
- * build.h
- * Automatically generated
- */
-#define BUILD_HOSTNAME "${HOSTNAME}"
-#define BUILD_KERNEL "${KERNEL}"
-#define BUILD_MACHINE "${MACHINE}"
-#define BUILD_OS "${OS}"
-#define BUILD_DATE "${DATE} UTC"
-#define BUILD_USER "${USER}"
-
-END
diff --git a/1.4/build_tools/make_buildopts_h b/1.4/build_tools/make_buildopts_h
deleted file mode 100755
index 531bb93a6..000000000
--- a/1.4/build_tools/make_buildopts_h
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-cat << END
-/*
- * buildopts.h
- * Automatically generated
- */
-
-END
-TMP=`${GREP} MENUSELECT_CFLAGS menuselect.makeopts | sed 's/MENUSELECT_CFLAGS\=//g' | sed 's/-D//g'`
-for x in ${TMP}; do
- echo "#define ${x} 1"
-done
-if ${GREP} AST_DEVMODE makeopts | ${GREP} -q yes
-then
- echo "#define AST_DEVMODE 1"
- TMP="${TMP} AST_DEVMODE"
-fi
-
-case ${OSARCH} in # actually we should check build_os
-*BSD|mingw|darwin*)
- BUILDSUM=`echo ${TMP} | md5 | cut -c1-32`
- ;;
-*)
- BUILDSUM=`echo ${TMP} | md5sum | cut -c1-32`
- ;;
-esac
-
-echo "#define AST_BUILDOPT_SUM \"${BUILDSUM}\""
diff --git a/1.4/build_tools/make_defaults_h b/1.4/build_tools/make_defaults_h
deleted file mode 100755
index dfd3bc2a6..000000000
--- a/1.4/build_tools/make_defaults_h
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-cat << END
-/*
- * defaults.h
- * Automatically generated
- */
-#define AST_CONFIG_DIR "${INSTALL_PATH}${ASTETCDIR}"
-#define AST_RUN_DIR "${INSTALL_PATH}${ASTVARRUNDIR}"
-#define AST_SOCKET "${INSTALL_PATH}${ASTVARRUNDIR}/asterisk.ctl"
-#define AST_PID "${INSTALL_PATH}${ASTVARRUNDIR}/asterisk.pid"
-#define AST_MODULE_DIR "${INSTALL_PATH}${MODULES_DIR}"
-#define AST_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}"
-#define AST_VAR_DIR "${INSTALL_PATH}${ASTVARLIBDIR}"
-#define AST_DATA_DIR "${INSTALL_PATH}${ASTDATADIR}"
-#define AST_LOG_DIR "${INSTALL_PATH}${ASTLOGDIR}"
-#define AST_AGI_DIR "${INSTALL_PATH}${AGI_DIR}"
-#define AST_KEY_DIR "${INSTALL_PATH}${ASTDATADIR}/keys"
-#define AST_DB "${INSTALL_PATH}${ASTVARLIBDIR}/astdb"
-#define AST_TMP_DIR "${INSTALL_PATH}${ASTSPOOLDIR}/tmp"
-
-#define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}"
-
-#define AST_SOUNDS "${INSTALL_PATH}${ASTDATADIR}/sounds"
-#define AST_IMAGES "${INSTALL_PATH}${ASTDATADIR}/images"
-
-END
diff --git a/1.4/build_tools/make_sample_voicemail b/1.4/build_tools/make_sample_voicemail
deleted file mode 100755
index 485a01d37..000000000
--- a/1.4/build_tools/make_sample_voicemail
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh -e
-
-for lang in / /fr/ /es/
- do
- for format in ulaw alaw wav gsm g729 g722
- do
- [ ! -f ${1}/sounds${lang}vm-isunavail.${format} ] && continue
-
- mkdir -p ${2}/voicemail/default/1234${lang}
-
- : > ${2}/voicemail/default/1234${lang}unavail.${format}
-
- for file in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail
- do
- cat ${1}/sounds${lang}${file}.${format} >> ${2}/voicemail/default/1234${lang}unavail.${format}
- done
-
- : > ${2}/voicemail/default/1234${lang}busy.${format}
-
- for file in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isonphone
- do
- cat ${1}/sounds${lang}${file}.${format} >> ${2}/voicemail/default/1234${lang}busy.${format}
- done
- done
-done
diff --git a/1.4/build_tools/make_version b/1.4/build_tools/make_version
deleted file mode 100755
index e55727f40..000000000
--- a/1.4/build_tools/make_version
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/sh
-
-if [ -f ${1}/.version ]; then
- cat ${1}/.version
-elif [ -d .svn ]; then
- PARTS=`LANG=C svn info ${1} | ${GREP} URL | ${AWK} '{print $2;}' | sed -e 's:^.*/svn/asterisk/::' | sed -e 's:/: :g'`
- BRANCH=0
- TEAM=0
- TAG=0
-
- REV=`svnversion -c ${1} | cut -d: -f2`
-
- BASE=`LANG=C svn pg svnmerge-integrated ${1} | cut -d: -f1`
-
- if [ "${PARTS}" = "trunk" ]
- then
- echo SVN-trunk-r${REV}
- exit 0
- fi
-
- for PART in $PARTS
- do
- if [ ${TAG} != 0 ]
- then
- if [ "${PART}" = "autotag_for_be" ] ; then
- continue
- fi
- if [ "${PART}" = "autotag_for_sx00i" ] ; then
- continue
- fi
- RESULT="${PART}"
- break
- fi
-
- if [ ${BRANCH} != 0 ]
- then
- if [ -z ${RESULT} ]
- then
- RESULT="${PART}"
- else
- RESULT="${RESULT}-${PART}"
- fi
- break
- fi
-
- if [ ${TEAM} != 0 ]
- then
- if [ -z ${RESULT} ]
- then
- RESULT="${PART}"
- else
- RESULT="${RESULT}-${PART}"
- fi
- continue
- fi
-
- if [ "${PART}" = "branches" ]
- then
- BRANCH=1
- RESULT="branch"
- continue
- fi
-
- if [ "${PART}" = "tags" ]
- then
- TAG=1
- continue
- fi
-
- if [ "${PART}" = "team" ]
- then
- TEAM=1
- continue
- fi
- done
-
- if [ ${TAG} != 0 ]
- then
- echo ${RESULT}
- else
- echo SVN-${RESULT}-r${REV}${BASE:+-${BASE}}
- fi
-fi
diff --git a/1.4/build_tools/make_version_h b/1.4/build_tools/make_version_h
deleted file mode 100755
index 0b651ad00..000000000
--- a/1.4/build_tools/make_version_h
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-if [ ! -f ../.flavor ]; then
- cat << END
-/*
- * version.h
- * Automatically generated
- */
-#define ASTERISK_VERSION "${ASTERISKVERSION}"
-#define ASTERISK_VERSION_NUM ${ASTERISKVERSIONNUM}
-
-END
-else
- aadkver=`cat ../.version`
- aadkflavor=`cat ../.flavor`
- cat << END
-/*
- * version.h
- * Automatically generated
- */
-#define ASTERISK_VERSION "${ASTERISKVERSION} (${aadkflavor} ${aadkver})"
-#define ASTERISK_VERSION_NUM ${ASTERISKVERSIONNUM}
-
-END
-fi
-
diff --git a/1.4/build_tools/menuselect-deps.in b/1.4/build_tools/menuselect-deps.in
deleted file mode 100644
index 3ffb565bf..000000000
--- a/1.4/build_tools/menuselect-deps.in
+++ /dev/null
@@ -1,41 +0,0 @@
-ASOUND=@PBX_ALSA@
-CURL=@PBX_CURL@
-FREETDS=@PBX_FREETDS@
-GSM=@PBX_GSM@
-GTK=@PBX_GTK@
-GTK2=@PBX_GTK2@
-H323=@PBX_H323@
-OPENH323=@PBX_OPENH323@
-IKSEMEL=@PBX_IKSEMEL@
-IMAP_TK=@PBX_IMAP_TK@
-IXJUSER=@PBX_IXJUSER@
-KDE=@PBX_KDE@
-LTDL=@PBX_LTDL@
-NBS=@PBX_NBS@
-NETSNMP=@PBX_NETSNMP@
-NEWT=@PBX_NEWT@
-OGG=@PBX_OGG@
-OSPTK=@PBX_OSPTK@
-OSSAUDIO=@PBX_OSS@
-PGSQL=@PBX_PGSQL@
-POPT=@PBX_POPT@
-PRI=@PBX_PRI@
-RADIUS=@PBX_RADIUS@
-SPEEX=@PBX_SPEEX@
-SPEEXDSP=@PBX_SPEEXDSP@
-SPEEX_PREPROCESS=@PBX_SPEEX_PREPROCESS@
-SQLITE=@PBX_SQLITE@
-SSL=@PBX_OPENSSL@
-TONEZONE=@PBX_TONEZONE@
-USB=@PBX_USB@
-UNIXODBC=@PBX_UNIXODBC@
-VORBIS=@PBX_VORBIS@
-VPBAPI=@PBX_VPB@
-ZAPTEL=@PBX_ZAPTEL@
-ZAPTEL_VLDTMF=@PBX_ZAPTEL_VLDTMF@
-ZAPTEL_TRANSCODE=@PBX_ZAPTEL_TRANSCODE@
-ZLIB=@PBX_ZLIB@
-ISDNNET=@PBX_ISDNNET@
-MISDN=@PBX_MISDN@
-SUPPSERV=@PBX_SUPPSERV@
-GNU_LD=@GNU_LD@
diff --git a/1.4/build_tools/mkpkgconfig b/1.4/build_tools/mkpkgconfig
deleted file mode 100755
index ceea7ebc0..000000000
--- a/1.4/build_tools/mkpkgconfig
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/bash
-PPATH=$1
-## Make sure we were called from Makefile
-
-if [ "x$ASTERISKVERSIONNUM" = "x" ]; then
- echo " ** Do not call this script directly"
- exit
-fi
-
-## Create a pkgconfig spec file for 3rd party modules (pkg-config asterisk --cflags)
-
-if [ ! -d $PPATH ]; then
- exit
-fi
-
-#Solaris (and some others) don't have sed -r. perl -p is equivalent
-if [[ `echo "xxx" | sed -r 's/x/y/g' 2>/dev/null | ${GREP} -c "yyy"` != 0 ]]; then
- EXTREGEX="sed -r -e"
-else
- EXTREGEX="perl -pe"
-fi
-
-## Clean out CFLAGS for the spec file.
-
-LOCAL_CFLAGS=`echo $CFLAGS | ${EXTREGEX} 's/\s*-pipe\s*//g' | ${EXTREGEX} 's/-[Wmp]\S*\s*//g' | \
- ${EXTREGEX} 's/-I(include|\.\.\/include) //g' | \
- ${EXTREGEX} 's/-DINSTALL_PREFIX=\S* //g' | \
- ${EXTREGEX} 's/-DASTERISK_VERSION=\S* //g' | \
- ${EXTREGEX} 's/-DAST(ETCDIR|LIBDIR|VARLIBDIR|VARRUNDIR|SPOOLDIR|LOGDIR|CONFPATH|MODDIR|AGIDIR)=\S* //g'`
-
-
-cat <<EOF > $PPATH/asterisk.pc
-install_prefix=$INSTALL_PREFIX
-version_number=$ASTERISKVERSIONNUM
-etcdir=$ASTETCDIR
-libdir=$ASTLIBDIR
-varlibdir=$ASTVARLIBDIR
-varrundir=$ASTVARRUNDIR
-spooldir=$ASTSPOOLDIR
-logdir=$ASTLOGDIR
-confpath=$ASTCONFPATH
-moddir=$MODULES_DIR
-agidir=$AGI_DIR
-
-Name: asterisk
-Description: Open Source PBX and telephony toolkit
-Version: $ASTERISKVERSION
-Libs: $LIBS
-Cflags: $LOCAL_CFLAGS
-EOF
diff --git a/1.4/build_tools/prep_tarball b/1.4/build_tools/prep_tarball
deleted file mode 100755
index b99c4c8f0..000000000
--- a/1.4/build_tools/prep_tarball
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh -e
-
-# This script will be executed by the 'mkrelease' script to do any tasks
-# necessary during tarball creation of this project.
-#
-# It will be executed from the top-level directory of the project.
-
-make -C sounds MENUSELECT_CORE_SOUNDS=CORE-SOUNDS-EN-GSM MENUSELECT_MOH=MOH-FREEPLAY-WAV WGET=wget DOWNLOAD=wget all
-make AWK=awk GREP=grep menuselect-tree
diff --git a/1.4/build_tools/strip_nonapi b/1.4/build_tools/strip_nonapi
deleted file mode 100755
index ba7482983..000000000
--- a/1.4/build_tools/strip_nonapi
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh -e
-
-# This script is designed to remove all non-API global symbols from an object
-# file. The only global symbols that should be retained are those that belong
-# to the official namespace. Unfortunately doing this is platform-specific, as
-# the object file manipulation tools are not consistent across platforms.
-#
-# On platforms where this script does not know what to do, the object file
-# will retain non-API global symbols, and this may have unpleasant side effects.
-#
-# Prefixes that belong to the official namespace are:
-# ast_
-# _ast_
-# __ast_
-# astman_
-# pbx_
-
-case "${PROC}" in
- powerpc64)
- TEXTSYM=" D "
- ;;
- *)
- TEXTSYM=" T "
- ;;
-esac
-
-FILTER="${GREP} -v -e ^ast_ -e ^_ast_ -e ^__ast_ -e ^astman_ -e ^pbx_"
-
-case "${OSARCH}" in
- linux-gnu)
- nm ${1} | ${GREP} -e "$TEXTSYM" | cut -d" " -f3 | ${FILTER} > striplist
- sed -e "s/^/-N /" striplist | xargs ${STRIP} ${1}
- rm -f striplist
- ;;
- *)
- ;;
-esac
diff --git a/1.4/cdr/Makefile b/1.4/cdr/Makefile
deleted file mode 100644
index b7e854468..000000000
--- a/1.4/cdr/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for CDR backends
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=CDR
-MENUSELECT_DESCRIPTION=Call Detail Recording
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard cdr_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard cdr_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_CDR),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_CDR),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring cdr,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
diff --git a/1.4/cdr/cdr_csv.c b/1.4/cdr/cdr_csv.c
deleted file mode 100644
index 527646e29..000000000
--- a/1.4/cdr/cdr_csv.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Comma Separated Value CDR records.
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg See also \ref AstCDR
- * \ingroup cdr_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "asterisk/config.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-#define CSV_LOG_DIR "/cdr-csv"
-#define CSV_MASTER "/Master.csv"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static int usegmtime = 0;
-static int loguniqueid = 0;
-static int loguserfield = 0;
-static int loaded = 0;
-static char *config = "cdr.conf";
-
-/* #define CSV_LOGUNIQUEID 1 */
-/* #define CSV_LOGUSERFIELD 1 */
-
-/*----------------------------------------------------
- The values are as follows:
-
-
- "accountcode", accountcode is the account name of detail records, Master.csv contains all records *
- Detail records are configured on a channel basis, IAX and SIP are determined by user *
- Zap is determined by channel in zaptel.conf
- "source",
- "destination",
- "destination context",
- "callerid",
- "channel",
- "destination channel", (if applicable)
- "last application", Last application run on the channel
- "last app argument", argument to the last channel
- "start time",
- "answer time",
- "end time",
- duration, Duration is the whole length that the entire call lasted. ie. call rx'd to hangup
- "end time" minus "start time"
- billable seconds, the duration that a call was up after other end answered which will be <= to duration
- "end time" minus "answer time"
- "disposition", ANSWERED, NO ANSWER, BUSY
- "amaflags", DOCUMENTATION, BILL, IGNORE etc, specified on a per channel basis like accountcode.
- "uniqueid", unique call identifier
- "userfield" user field set via SetCDRUserField
-----------------------------------------------------------*/
-
-static char *name = "csv";
-
-AST_MUTEX_DEFINE_STATIC(mf_lock);
-AST_MUTEX_DEFINE_STATIC(acf_lock);
-
-static int load_config(void)
-{
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *tmp;
-
- usegmtime = 0;
- loguniqueid = 0;
- loguserfield = 0;
-
- cfg = ast_config_load(config);
-
- if (!cfg) {
- ast_log(LOG_WARNING, "unable to load config: %s\n", config);
- return 0;
- }
-
- var = ast_variable_browse(cfg, "csv");
- if (!var) {
- ast_config_destroy(cfg);
- return 0;
- }
-
- tmp = ast_variable_retrieve(cfg, "csv", "usegmtime");
- if (tmp) {
- usegmtime = ast_true(tmp);
- if (usegmtime) {
- ast_log(LOG_DEBUG, "logging time in GMT\n");
- }
- }
-
- tmp = ast_variable_retrieve(cfg, "csv", "loguniqueid");
- if (tmp) {
- loguniqueid = ast_true(tmp);
- if (loguniqueid) {
- ast_log(LOG_DEBUG, "logging CDR field UNIQUEID\n");
- }
- }
-
- tmp = ast_variable_retrieve(cfg, "csv", "loguserfield");
- if (tmp) {
- loguserfield = ast_true(tmp);
- if (loguserfield) {
- ast_log(LOG_DEBUG, "logging CDR user-defined field\n");
- }
- }
-
- ast_config_destroy(cfg);
- return 1;
-}
-
-static int append_string(char *buf, char *s, size_t bufsize)
-{
- int pos = strlen(buf);
- int spos = 0;
- int error = 0;
- if (pos >= bufsize - 4)
- return -1;
- buf[pos++] = '\"';
- error = -1;
- while(pos < bufsize - 3) {
- if (!s[spos]) {
- error = 0;
- break;
- }
- if (s[spos] == '\"')
- buf[pos++] = '\"';
- buf[pos++] = s[spos];
- spos++;
- }
- buf[pos++] = '\"';
- buf[pos++] = ',';
- buf[pos++] = '\0';
- return error;
-}
-
-static int append_int(char *buf, int s, size_t bufsize)
-{
- char tmp[32];
- int pos = strlen(buf);
- snprintf(tmp, sizeof(tmp), "%d", s);
- if (pos + strlen(tmp) > bufsize - 3)
- return -1;
- strncat(buf, tmp, bufsize - strlen(buf) - 1);
- pos = strlen(buf);
- buf[pos++] = ',';
- buf[pos++] = '\0';
- return 0;
-}
-
-static int append_date(char *buf, struct timeval tv, size_t bufsize)
-{
- char tmp[80] = "";
- struct tm tm;
- time_t t;
- t = tv.tv_sec;
- if (strlen(buf) > bufsize - 3)
- return -1;
- if (ast_tvzero(tv)) {
- strncat(buf, ",", bufsize - strlen(buf) - 1);
- return 0;
- }
- if (usegmtime) {
- gmtime_r(&t,&tm);
- } else {
- ast_localtime(&t, &tm, NULL);
- }
- strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm);
- return append_string(buf, tmp, bufsize);
-}
-
-static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
-{
-
- buf[0] = '\0';
- /* Account code */
- append_string(buf, cdr->accountcode, bufsize);
- /* Source */
- append_string(buf, cdr->src, bufsize);
- /* Destination */
- append_string(buf, cdr->dst, bufsize);
- /* Destination context */
- append_string(buf, cdr->dcontext, bufsize);
- /* Caller*ID */
- append_string(buf, cdr->clid, bufsize);
- /* Channel */
- append_string(buf, cdr->channel, bufsize);
- /* Destination Channel */
- append_string(buf, cdr->dstchannel, bufsize);
- /* Last Application */
- append_string(buf, cdr->lastapp, bufsize);
- /* Last Data */
- append_string(buf, cdr->lastdata, bufsize);
- /* Start Time */
- append_date(buf, cdr->start, bufsize);
- /* Answer Time */
- append_date(buf, cdr->answer, bufsize);
- /* End Time */
- append_date(buf, cdr->end, bufsize);
- /* Duration */
- append_int(buf, cdr->duration, bufsize);
- /* Billable seconds */
- append_int(buf, cdr->billsec, bufsize);
- /* Disposition */
- append_string(buf, ast_cdr_disp2str(cdr->disposition), bufsize);
- /* AMA Flags */
- append_string(buf, ast_cdr_flags2str(cdr->amaflags), bufsize);
- /* Unique ID */
- if (loguniqueid)
- append_string(buf, cdr->uniqueid, bufsize);
- /* append the user field */
- if(loguserfield)
- append_string(buf, cdr->userfield,bufsize);
- /* If we hit the end of our buffer, log an error */
- if (strlen(buf) < bufsize - 5) {
- /* Trim off trailing comma */
- buf[strlen(buf) - 1] = '\0';
- strncat(buf, "\n", bufsize - strlen(buf) - 1);
- return 0;
- }
- return -1;
-}
-
-static int writefile(char *s, char *acc)
-{
- char tmp[PATH_MAX];
- FILE *f;
- if (strchr(acc, '/') || (acc[0] == '.')) {
- ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
- return -1;
- }
- snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", (char *)ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
-
- ast_mutex_lock(&acf_lock);
- f = fopen(tmp, "a");
- if (!f) {
- ast_mutex_unlock(&acf_lock);
- ast_log(LOG_ERROR, "Unable to open file %s : %s\n", tmp, strerror(errno));
- return -1;
- }
- fputs(s, f);
- fflush(f);
- fclose(f);
- ast_mutex_unlock(&acf_lock);
-
- return 0;
-}
-
-
-static int csv_log(struct ast_cdr *cdr)
-{
- FILE *mf = NULL;
- /* Make sure we have a big enough buf */
- char buf[1024];
- char csvmaster[PATH_MAX];
- snprintf(csvmaster, sizeof(csvmaster),"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER);
-#if 0
- printf("[CDR] %s ('%s' -> '%s') Dur: %ds Bill: %ds Disp: %s Flags: %s Account: [%s]\n", cdr->channel, cdr->src, cdr->dst, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->accountcode);
-#endif
- if (build_csv_record(buf, sizeof(buf), cdr)) {
- ast_log(LOG_WARNING, "Unable to create CSV record in %d bytes. CDR not recorded!\n", (int)sizeof(buf));
- } else {
- /* because of the absolutely unconditional need for the
- highest reliability possible in writing billing records,
- we open write and close the log file each time */
- ast_mutex_lock(&mf_lock);
- mf = fopen(csvmaster, "a");
- if (mf) {
- fputs(buf, mf);
- fflush(mf); /* be particularly anal here */
- fclose(mf);
- mf = NULL;
- ast_mutex_unlock(&mf_lock);
- } else {
- ast_mutex_unlock(&mf_lock);
- ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", csvmaster, strerror(errno));
- }
-
- if (!ast_strlen_zero(cdr->accountcode)) {
- if (writefile(buf, cdr->accountcode))
- ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", cdr->accountcode, strerror(errno));
- }
- }
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- loaded = 0;
- return 0;
-}
-
-static int load_module(void)
-{
- int res;
-
- if(!load_config())
- return AST_MODULE_LOAD_DECLINE;
-
- res = ast_cdr_register(name, ast_module_info->description, csv_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n");
- } else {
- loaded = 1;
- }
- return res;
-}
-
-static int reload(void)
-{
- if (load_config()) {
- loaded = 1;
- } else {
- loaded = 0;
- ast_log(LOG_WARNING, "No [csv] section in cdr.conf. Unregistering backend.\n");
- ast_cdr_unregister(name);
- }
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Comma Separated Values CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/cdr/cdr_custom.c b/1.4/cdr/cdr_custom.c
deleted file mode 100644
index c390b0499..000000000
--- a/1.4/cdr/cdr_custom.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Custom Comma Separated Value CDR records.
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg See also \ref AstCDR
- *
- * Logs in LOG_DIR/cdr_custom
- * \ingroup cdr_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-#define CUSTOM_LOG_DIR "/cdr_custom"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-AST_MUTEX_DEFINE_STATIC(lock);
-AST_MUTEX_DEFINE_STATIC(mf_lock);
-
-static char *name = "cdr-custom";
-
-static char master[PATH_MAX];
-static char format[1024]="";
-
-static int load_config(int reload)
-{
- struct ast_config *cfg;
- struct ast_variable *var;
- int res = -1;
-
- strcpy(format, "");
- strcpy(master, "");
- ast_mutex_lock(&lock);
- if((cfg = ast_config_load("cdr_custom.conf"))) {
- var = ast_variable_browse(cfg, "mappings");
- while(var) {
- if (!ast_strlen_zero(var->name) && !ast_strlen_zero(var->value)) {
- if (strlen(var->value) > (sizeof(format) - 1))
- ast_log(LOG_WARNING, "Format string too long, will be truncated, at line %d\n", var->lineno);
- ast_copy_string(format, var->value, sizeof(format) - 1);
- strcat(format,"\n");
- snprintf(master, sizeof(master),"%s/%s/%s", ast_config_AST_LOG_DIR, name, var->name);
- if (var->next) {
- ast_log(LOG_NOTICE, "Sorry, only one mapping is supported at this time, mapping '%s' will be ignored at line %d.\n", var->next->name, var->next->lineno);
- break;
- }
- } else
- ast_log(LOG_NOTICE, "Mapping must have both filename and format at line %d\n", var->lineno);
- var = var->next;
- }
- ast_config_destroy(cfg);
- res = 0;
- } else {
- if (reload)
- ast_log(LOG_WARNING, "Failed to reload configuration file.\n");
- else
- ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
- }
- ast_mutex_unlock(&lock);
-
- return res;
-}
-
-
-
-static int custom_log(struct ast_cdr *cdr)
-{
- FILE *mf = NULL;
-
- /* Make sure we have a big enough buf */
- char buf[2048];
- struct ast_channel dummy;
-
- /* Abort if no master file is specified */
- if (ast_strlen_zero(master))
- return 0;
-
- memset(buf, 0 , sizeof(buf));
- /* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
- memset(&dummy, 0, sizeof(dummy));
- dummy.cdr = cdr;
- pbx_substitute_variables_helper(&dummy, format, buf, sizeof(buf) - 1);
-
- /* because of the absolutely unconditional need for the
- highest reliability possible in writing billing records,
- we open write and close the log file each time */
- ast_mutex_lock(&mf_lock);
- mf = fopen(master, "a");
- if (mf) {
- fputs(buf, mf);
- fflush(mf); /* be particularly anal here */
- fclose(mf);
- mf = NULL;
- ast_mutex_unlock(&mf_lock);
- } else {
- ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
- ast_mutex_unlock(&mf_lock);
- }
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- if (!load_config(0)) {
- res = ast_cdr_register(name, ast_module_info->description, custom_log);
- if (res)
- ast_log(LOG_ERROR, "Unable to register custom CDR handling\n");
- return res;
- } else
- return AST_MODULE_LOAD_DECLINE;
-}
-
-static int reload(void)
-{
- return load_config(1);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Customizable Comma Separated Values CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
diff --git a/1.4/cdr/cdr_manager.c b/1.4/cdr/cdr_manager.c
deleted file mode 100644
index 352d7d400..000000000
--- a/1.4/cdr/cdr_manager.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Asterisk Call Manager CDR records.
- *
- * See also
- * \arg \ref AstCDR
- * \arg \ref AstAMI
- * \arg \ref Config_ami
- * \ingroup cdr_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <strings.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/manager.h"
-#include "asterisk/config.h"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-#define CONF_FILE "cdr_manager.conf"
-
-static char *name = "cdr_manager";
-
-static int enablecdr = 0;
-
-static int loadconfigurationfile(void)
-{
- char *cat;
- struct ast_config *cfg;
- struct ast_variable *v;
-
- cfg = ast_config_load(CONF_FILE);
- if (!cfg) {
- /* Standard configuration */
- enablecdr = 0;
- return 0;
- }
-
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- if (!strcasecmp(cat, "general")) {
- v = ast_variable_browse(cfg, cat);
- while (v) {
- if (!strcasecmp(v->name, "enabled")) {
- enablecdr = ast_true(v->value);
- }
-
- v = v->next;
- }
- }
-
- /* Next category */
- cat = ast_category_browse(cfg, cat);
- }
-
- ast_config_destroy(cfg);
- return 1;
-}
-
-static int manager_log(struct ast_cdr *cdr)
-{
- time_t t;
- struct tm timeresult;
- char strStartTime[80] = "";
- char strAnswerTime[80] = "";
- char strEndTime[80] = "";
-
- if (!enablecdr)
- return 0;
-
- t = cdr->start.tv_sec;
- ast_localtime(&t, &timeresult, NULL);
- strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
-
- if (cdr->answer.tv_sec) {
- t = cdr->answer.tv_sec;
- ast_localtime(&t, &timeresult, NULL);
- strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
- }
-
- t = cdr->end.tv_sec;
- ast_localtime(&t, &timeresult, NULL);
- strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);
-
- manager_event(EVENT_FLAG_CALL, "Cdr",
- "AccountCode: %s\r\n"
- "Source: %s\r\n"
- "Destination: %s\r\n"
- "DestinationContext: %s\r\n"
- "CallerID: %s\r\n"
- "Channel: %s\r\n"
- "DestinationChannel: %s\r\n"
- "LastApplication: %s\r\n"
- "LastData: %s\r\n"
- "StartTime: %s\r\n"
- "AnswerTime: %s\r\n"
- "EndTime: %s\r\n"
- "Duration: %ld\r\n"
- "BillableSeconds: %ld\r\n"
- "Disposition: %s\r\n"
- "AMAFlags: %s\r\n"
- "UniqueID: %s\r\n"
- "UserField: %s\r\n",
- cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
- cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
- cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),
- ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- int res;
-
- /* Configuration file */
- if (!loadconfigurationfile())
- return AST_MODULE_LOAD_DECLINE;
-
- res = ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CDR handling\n");
- }
-
- return res;
-}
-
-static int reload(void)
-{
- loadconfigurationfile();
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Manager Interface CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/cdr/cdr_odbc.c b/1.4/cdr/cdr_odbc.c
deleted file mode 100644
index 2cd559af8..000000000
--- a/1.4/cdr/cdr_odbc.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2003-2005, Digium, Inc.
- *
- * Brian K. West <brian@bkw.org>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ODBC CDR Backend
- *
- * \author Brian K. West <brian@bkw.org>
- *
- * See also:
- * \arg http://www.unixodbc.org
- * \arg \ref Config_cdr
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>unixodbc</depend>
- <depend>ltdl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#ifndef __CYGWIN__
-#include <sql.h>
-#include <sqlext.h>
-#include <sqltypes.h>
-#else
-#include <windows.h>
-#include <w32api/sql.h>
-#include <w32api/sqlext.h>
-#include <w32api/sqltypes.h>
-#endif
-
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static char *name = "ODBC";
-static char *config = "cdr_odbc.conf";
-static char *dsn = NULL, *username = NULL, *password = NULL, *table = NULL;
-static int loguniqueid = 0;
-static int usegmtime = 0;
-static int dispositionstring = 0;
-static int connected = 0;
-
-AST_MUTEX_DEFINE_STATIC(odbc_lock);
-
-static int odbc_do_query(void);
-static int odbc_init(void);
-
-static SQLHENV ODBC_env = SQL_NULL_HANDLE; /* global ODBC Environment */
-static SQLHDBC ODBC_con; /* global ODBC Connection Handle */
-static SQLHSTMT ODBC_stmt; /* global ODBC Statement Handle */
-
-static void odbc_disconnect(void)
-{
- SQLDisconnect(ODBC_con);
- SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
-}
-
-static int odbc_log(struct ast_cdr *cdr)
-{
- int ODBC_res;
- char sqlcmd[2048] = "", timestr[128];
- int res = 0;
- struct tm tm;
-
- if (usegmtime)
- gmtime_r(&cdr->start.tv_sec,&tm);
- else
- ast_localtime(&cdr->start.tv_sec, &tm, NULL);
-
- ast_mutex_lock(&odbc_lock);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- memset(sqlcmd,0,2048);
- if (loguniqueid) {
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
- "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,"
- "lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) "
- "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
- } else {
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
- "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,"
- "duration,billsec,disposition,amaflags,accountcode) "
- "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
- }
-
- if (!connected) {
- res = odbc_init();
- if (res < 0) {
- odbc_disconnect();
- ast_mutex_unlock(&odbc_lock);
- return 0;
- }
- }
-
- ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- ast_mutex_unlock(&odbc_lock);
- return 0;
- }
-
- /* We really should only have to do this once. But for some
- strange reason if I don't it blows holes in memory like
- like a shotgun. So we just do this so its safe. */
-
- ODBC_res = SQLPrepare(ODBC_stmt, (unsigned char *)sqlcmd, SQL_NTS);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in PREPARE %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- ast_mutex_unlock(&odbc_lock);
- return 0;
- }
-
- SQLBindParameter(ODBC_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(timestr), 0, &timestr, 0, NULL);
- SQLBindParameter(ODBC_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->clid), 0, cdr->clid, 0, NULL);
- SQLBindParameter(ODBC_stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL);
- SQLBindParameter(ODBC_stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL);
- SQLBindParameter(ODBC_stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL);
- SQLBindParameter(ODBC_stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL);
- SQLBindParameter(ODBC_stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL);
- SQLBindParameter(ODBC_stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL);
- SQLBindParameter(ODBC_stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL);
- SQLBindParameter(ODBC_stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL);
- SQLBindParameter(ODBC_stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL);
- if (dispositionstring)
- SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ast_cdr_disp2str(cdr->disposition)) + 1, 0, ast_cdr_disp2str(cdr->disposition), 0, NULL);
- else
- SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL);
- SQLBindParameter(ODBC_stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL);
- SQLBindParameter(ODBC_stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL);
-
- if (loguniqueid) {
- SQLBindParameter(ODBC_stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL);
- SQLBindParameter(ODBC_stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL);
- }
-
- if (connected) {
- res = odbc_do_query();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Reconnecting to dsn %s\n", dsn);
- SQLDisconnect(ODBC_con);
- res = odbc_init();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: %s has gone away!\n", dsn);
- odbc_disconnect();
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Trying Query again!\n");
- res = odbc_do_query();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
- }
- }
- }
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
- }
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ast_mutex_unlock(&odbc_lock);
- return 0;
-}
-
-static int odbc_unload_module(void)
-{
- ast_mutex_lock(&odbc_lock);
- if (connected) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Disconnecting from %s\n", dsn);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- }
- if (dsn) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free dsn\n");
- free(dsn);
- }
- if (username) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free username\n");
- free(username);
- }
- if (password) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free password\n");
- free(password);
- }
- if (table) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free table\n");
- free(table);
- }
-
- ast_cdr_unregister(name);
- ast_mutex_unlock(&odbc_lock);
- return 0;
-}
-
-static int odbc_load_module(void)
-{
- int res = 0;
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *tmp;
-
- ast_mutex_lock(&odbc_lock);
-
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
- res = AST_MODULE_LOAD_DECLINE;
- goto out;
- }
-
- var = ast_variable_browse(cfg, "global");
- if (!var) {
- /* nothing configured */
- goto out;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","dsn");
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"cdr_odbc: dsn not specified. Assuming asteriskdb\n");
- tmp = "asteriskdb";
- }
- dsn = strdup(tmp);
- if (dsn == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
- if (tmp) {
- dispositionstring = ast_true(tmp);
- } else {
- dispositionstring = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","username");
- if (tmp) {
- username = strdup(tmp);
- if (username == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
- }
-
- tmp = ast_variable_retrieve(cfg,"global","password");
- if (tmp) {
- password = strdup(tmp);
- if (password == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
- }
-
- tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
- if (tmp) {
- loguniqueid = ast_true(tmp);
- if (loguniqueid) {
- ast_log(LOG_DEBUG,"cdr_odbc: Logging uniqueid\n");
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
- }
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
- loguniqueid = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","usegmtime");
- if (tmp) {
- usegmtime = ast_true(tmp);
- if (usegmtime) {
- ast_log(LOG_DEBUG,"cdr_odbc: Logging in GMT\n");
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
- }
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
- usegmtime = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","table");
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"cdr_odbc: table not specified. Assuming cdr\n");
- tmp = "cdr";
- }
- table = strdup(tmp);
- if (table == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
-
- if (option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: dsn is %s\n",dsn);
- if (username)
- {
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: username is %s\n",username);
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: password is [secret]\n");
- }
- else
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: retreiving username and password from odbc config\n");
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: table is %s\n",table);
- }
-
- res = odbc_init();
- if (res < 0) {
- ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
- if (option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
- }
- }
- res = ast_cdr_register(name, ast_module_info->description, odbc_log);
- if (res) {
- ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
- }
-out:
- if (cfg)
- ast_config_destroy(cfg);
- ast_mutex_unlock(&odbc_lock);
- return res;
-}
-
-static int odbc_do_query(void)
-{
- int ODBC_res;
-
- ODBC_res = SQLExecute(ODBC_stmt);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in Query %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- return -1;
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query Successful!\n");
- connected = 1;
- }
- return 0;
-}
-
-static int odbc_init(void)
-{
- int ODBC_res;
-
- if (ODBC_env == SQL_NULL_HANDLE || connected == 0) {
- ODBC_res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &ODBC_env);
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error AllocHandle\n");
- connected = 0;
- return -1;
- }
-
- ODBC_res = SQLSetEnvAttr(ODBC_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error SetEnv\n");
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
- return -1;
- }
-
- ODBC_res = SQLAllocHandle(SQL_HANDLE_DBC, ODBC_env, &ODBC_con);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error AllocHDB %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
- return -1;
- }
- SQLSetConnectAttr(ODBC_con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)10, 0);
- }
-
- /* Note that the username and password could be NULL here, but that is allowed in ODBC.
- In this case, the default username and password will be used from odbc.conf */
- ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, (SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error SQLConnect %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
- return -1;
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Connected to %s\n", dsn);
- connected = 1;
- }
- return 0;
-}
-
-static int load_module(void)
-{
- return odbc_load_module();
-}
-
-static int unload_module(void)
-{
- return odbc_unload_module();
-}
-
-static int reload(void)
-{
- odbc_unload_module();
- return odbc_load_module();
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ODBC CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/cdr/cdr_pgsql.c b/1.4/cdr/cdr_pgsql.c
deleted file mode 100644
index a2144a712..000000000
--- a/1.4/cdr/cdr_pgsql.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2003 - 2006
- *
- * Matthew D. Hardeman <mhardemn@papersoft.com>
- * Adapted from the MySQL CDR logger originally by James Sharp
- *
- * Modified September 2003
- * Matthew D. Hardeman <mhardemn@papersoft.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.
- */
-
-/*! \file
- *
- * \brief PostgreSQL CDR logger
- *
- * \author Matthew D. Hardeman <mhardemn@papersoft.com>
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.postgresql.org/
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>pgsql</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <libpq-fe.h>
-
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk.h"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static char *name = "pgsql";
-static char *config = "cdr_pgsql.conf";
-static char *pghostname = NULL, *pgdbname = NULL, *pgdbuser = NULL, *pgpassword = NULL, *pgdbport = NULL, *table = NULL;
-static int connected = 0;
-
-AST_MUTEX_DEFINE_STATIC(pgsql_lock);
-
-static PGconn *conn = NULL;
-
-static int pgsql_log(struct ast_cdr *cdr)
-{
- struct tm tm;
- time_t t = cdr->start.tv_sec;
- char sqlcmd[2048] = "", timestr[128];
- char *pgerror;
- PGresult *result;
-
- ast_mutex_lock(&pgsql_lock);
-
- ast_localtime(&t, &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
-
- if ((!connected) && pghostname && pgdbuser && pgpassword && pgdbname) {
- conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
- if (PQstatus(conn) != CONNECTION_BAD) {
- connected = 1;
- } else {
- pgerror = PQerrorMessage(conn);
- ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s. Calls will not be logged!\n", pghostname);
- ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
- PQfinish(conn);
- conn = NULL;
- }
- }
-
- if (connected) {
- char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL;
- char *src=NULL, *dst=NULL, *uniqueid=NULL, *userfield=NULL;
- int pgerr;
-
- /* Maximum space needed would be if all characters needed to be escaped, plus a trailing NULL */
- if ((clid = alloca(strlen(cdr->clid) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, clid, cdr->clid, strlen(cdr->clid), &pgerr);
- if ((dcontext = alloca(strlen(cdr->dcontext) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dcontext, cdr->dcontext, strlen(cdr->dcontext), &pgerr);
- if ((channel = alloca(strlen(cdr->channel) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, channel, cdr->channel, strlen(cdr->channel), &pgerr);
- if ((dstchannel = alloca(strlen(cdr->dstchannel) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dstchannel, cdr->dstchannel, strlen(cdr->dstchannel), &pgerr);
- if ((lastapp = alloca(strlen(cdr->lastapp) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, lastapp, cdr->lastapp, strlen(cdr->lastapp), &pgerr);
- if ((lastdata = alloca(strlen(cdr->lastdata) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, lastdata, cdr->lastdata, strlen(cdr->lastdata), &pgerr);
- if ((uniqueid = alloca(strlen(cdr->uniqueid) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, uniqueid, cdr->uniqueid, strlen(cdr->uniqueid), &pgerr);
- if ((userfield = alloca(strlen(cdr->userfield) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, userfield, cdr->userfield, strlen(cdr->userfield), &pgerr);
- if ((src = alloca(strlen(cdr->src) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, src, cdr->src, strlen(cdr->src), &pgerr);
- if ((dst = alloca(strlen(cdr->dst) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dst, cdr->dst, strlen(cdr->dst), &pgerr);
-
- /* Check for all alloca failures above at once */
- if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield) || (!src) || (!dst)) {
- ast_log(LOG_ERROR, "cdr_pgsql: Out of memory error (insert fails)\n");
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "cdr_pgsql: inserting a CDR record.\n");
-
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,"
- "lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) VALUES"
- " ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s','%s')",
- table, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata,
- cdr->duration,cdr->billsec,ast_cdr_disp2str(cdr->disposition),cdr->amaflags, cdr->accountcode, uniqueid, userfield);
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "cdr_pgsql: SQL command executed: %s\n",sqlcmd);
-
- /* Test to be sure we're still connected... */
- /* If we're connected, and connection is working, good. */
- /* Otherwise, attempt reconnect. If it fails... sorry... */
- if (PQstatus(conn) == CONNECTION_OK) {
- connected = 1;
- } else {
- ast_log(LOG_ERROR, "cdr_pgsql: Connection was lost... attempting to reconnect.\n");
- PQreset(conn);
- if (PQstatus(conn) == CONNECTION_OK) {
- ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n");
- connected = 1;
- } else {
- pgerror = PQerrorMessage(conn);
- ast_log(LOG_ERROR, "cdr_pgsql: Unable to reconnect to database server %s. Calls will not be logged!\n", pghostname);
- ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
- PQfinish(conn);
- conn = NULL;
- connected = 0;
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
- }
- result = PQexec(conn, sqlcmd);
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- pgerror = PQresultErrorMessage(result);
- ast_log(LOG_ERROR,"cdr_pgsql: Failed to insert call detail record into database!\n");
- ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror);
- ast_log(LOG_ERROR,"cdr_pgsql: Connection may have been lost... attempting to reconnect.\n");
- PQreset(conn);
- if (PQstatus(conn) == CONNECTION_OK) {
- ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n");
- connected = 1;
- PQclear(result);
- result = PQexec(conn, sqlcmd);
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- pgerror = PQresultErrorMessage(result);
- ast_log(LOG_ERROR,"cdr_pgsql: HARD ERROR! Attempted reconnection failed. DROPPING CALL RECORD!\n");
- ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror);
- }
- }
- ast_mutex_unlock(&pgsql_lock);
- PQclear(result);
- return -1;
- }
- PQclear(result);
- }
- ast_mutex_unlock(&pgsql_lock);
- return 0;
-}
-
-static int my_unload_module(void)
-{
- PQfinish(conn);
- if (pghostname)
- free(pghostname);
- if (pgdbname)
- free(pgdbname);
- if (pgdbuser)
- free(pgdbuser);
- if (pgpassword)
- free(pgpassword);
- if (pgdbport)
- free(pgdbport);
- if (table)
- free(table);
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int process_my_load_module(struct ast_config *cfg)
-{
- struct ast_variable *var;
- char *pgerror;
- const char *tmp;
-
- if (!(var = ast_variable_browse(cfg, "global")))
- return 0;
-
- if (!(tmp = ast_variable_retrieve(cfg,"global","hostname"))) {
- ast_log(LOG_WARNING,"PostgreSQL server hostname not specified. Assuming unix socket connection\n");
- tmp = ""; /* connect via UNIX-socket by default */
- }
-
- if (!(pghostname = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "dbname"))) {
- ast_log(LOG_WARNING,"PostgreSQL database not specified. Assuming asterisk\n");
- tmp = "asteriskcdrdb";
- }
-
- if (!(pgdbname = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "user"))) {
- ast_log(LOG_WARNING,"PostgreSQL database user not specified. Assuming asterisk\n");
- tmp = "asterisk";
- }
-
- if (!(pgdbuser = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "password"))) {
- ast_log(LOG_WARNING,"PostgreSQL database password not specified. Assuming blank\n");
- tmp = "";
- }
-
- if (!(pgpassword = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg,"global","port"))) {
- ast_log(LOG_WARNING,"PostgreSQL database port not specified. Using default 5432.\n");
- tmp = "5432";
- }
-
- if (!(pgdbport = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "table"))) {
- ast_log(LOG_WARNING,"CDR table not specified. Assuming cdr\n");
- tmp = "cdr";
- }
-
- if (!(table = ast_strdup(tmp)))
- return -1;
-
- if (option_debug) {
- if (ast_strlen_zero(pghostname))
- ast_log(LOG_DEBUG, "cdr_pgsql: using default unix socket\n");
- else
- ast_log(LOG_DEBUG, "cdr_pgsql: got hostname of %s\n", pghostname);
- ast_log(LOG_DEBUG, "cdr_pgsql: got port of %s\n", pgdbport);
- ast_log(LOG_DEBUG, "cdr_pgsql: got user of %s\n", pgdbuser);
- ast_log(LOG_DEBUG, "cdr_pgsql: got dbname of %s\n", pgdbname);
- ast_log(LOG_DEBUG, "cdr_pgsql: got password of %s\n", pgpassword);
- ast_log(LOG_DEBUG, "cdr_pgsql: got sql table name of %s\n", table);
- }
-
- conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
- if (PQstatus(conn) != CONNECTION_BAD) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Successfully connected to PostgreSQL database.\n");
- connected = 1;
- } else {
- pgerror = PQerrorMessage(conn);
- ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s. CALLS WILL NOT BE LOGGED!!\n", pghostname);
- ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
- connected = 0;
- }
-
- return ast_cdr_register(name, ast_module_info->description, pgsql_log);
-}
-
-static int my_load_module(void)
-{
- struct ast_config *cfg;
- int res;
-
- if (!(cfg = ast_config_load(config))) {
- ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- res = process_my_load_module(cfg);
- ast_config_destroy(cfg);
-
- return res;
-}
-
-static int load_module(void)
-{
- return my_load_module();
-}
-
-static int unload_module(void)
-{
- return my_unload_module();
-}
-
-static int reload(void)
-{
- int res;
- ast_mutex_lock(&pgsql_lock);
- my_unload_module();
- res = my_load_module();
- ast_mutex_unlock(&pgsql_lock);
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "PostgreSQL CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/cdr/cdr_radius.c b/1.4/cdr/cdr_radius.c
deleted file mode 100644
index 6d890e764..000000000
--- a/1.4/cdr/cdr_radius.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief RADIUS CDR Support
- * \author Philippe Sultan
- *
- * \arg See also \ref AstCDR
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>radius</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Rev$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/types.h>
-#include <radiusclient-ng.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-
-/*! ISO 8601 standard format */
-#define DATE_FORMAT "%Y-%m-%d %T %z"
-
-#define VENDOR_CODE 22736
-
-enum {
- PW_AST_ACCT_CODE = 101,
- PW_AST_SRC = 102,
- PW_AST_DST = 103,
- PW_AST_DST_CTX = 104,
- PW_AST_CLID = 105,
- PW_AST_CHAN = 106,
- PW_AST_DST_CHAN = 107,
- PW_AST_LAST_APP = 108,
- PW_AST_LAST_DATA = 109,
- PW_AST_START_TIME = 110,
- PW_AST_ANSWER_TIME = 111,
- PW_AST_END_TIME = 112,
- PW_AST_DURATION = 113,
- PW_AST_BILL_SEC = 114,
- PW_AST_DISPOSITION = 115,
- PW_AST_AMA_FLAGS = 116,
- PW_AST_UNIQUE_ID = 117,
- PW_AST_USER_FIELD = 118
-};
-
-enum {
- /*! Log dates and times in UTC */
- RADIUS_FLAG_USEGMTIME = (1 << 0),
- /*! Log Unique ID */
- RADIUS_FLAG_LOGUNIQUEID = (1 << 1),
- /*! Log User Field */
- RADIUS_FLAG_LOGUSERFIELD = (1 << 2)
-};
-
-static char *desc = "RADIUS CDR Backend";
-static char *name = "radius";
-static char *cdr_config = "cdr.conf";
-
-static char radiuscfg[PATH_MAX] = "/etc/radiusclient-ng/radiusclient.conf";
-
-static struct ast_flags global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD };
-
-static rc_handle *rh = NULL;
-
-static int build_radius_record(VALUE_PAIR **send, struct ast_cdr *cdr)
-{
- int recordtype = PW_STATUS_STOP;
- struct tm tm;
- char timestr[128];
- char *tmp;
-
- if (!rc_avpair_add(rh, send, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0))
- return -1;
-
- /* Account code */
- if (!rc_avpair_add(rh, send, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE))
- return -1;
-
- /* Source */
- if (!rc_avpair_add(rh, send, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE))
- return -1;
-
- /* Destination */
- if (!rc_avpair_add(rh, send, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE))
- return -1;
-
- /* Destination context */
- if (!rc_avpair_add(rh, send, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE))
- return -1;
-
- /* Caller ID */
- if (!rc_avpair_add(rh, send, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE))
- return -1;
-
- /* Channel */
- if (!rc_avpair_add(rh, send, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE))
- return -1;
-
- /* Destination Channel */
- if (!rc_avpair_add(rh, send, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE))
- return -1;
-
- /* Last Application */
- if (!rc_avpair_add(rh, send, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE))
- return -1;
-
- /* Last Data */
- if (!rc_avpair_add(rh, send, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE))
- return -1;
-
-
- /* Start Time */
- if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
- gmtime_r(&(cdr->start.tv_sec), &tm);
- else
- ast_localtime(&(cdr->start.tv_sec), &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- if (!rc_avpair_add(rh, send, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE))
- return -1;
-
- /* Answer Time */
- if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
- gmtime_r(&(cdr->answer.tv_sec), &tm);
- else
- ast_localtime(&(cdr->answer.tv_sec), &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- if (!rc_avpair_add(rh, send, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE))
- return -1;
-
- /* End Time */
- if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
- gmtime_r(&(cdr->end.tv_sec), &tm);
- else
- ast_localtime(&(cdr->end.tv_sec), &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- if (!rc_avpair_add(rh, send, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE))
- return -1;
-
- /* Duration */
- if (!rc_avpair_add(rh, send, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE))
- return -1;
-
- /* Billable seconds */
- if (!rc_avpair_add(rh, send, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE))
- return -1;
-
- /* Disposition */
- tmp = ast_cdr_disp2str(cdr->disposition);
- if (!rc_avpair_add(rh, send, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE))
- return -1;
-
- /* AMA Flags */
- tmp = ast_cdr_flags2str(cdr->amaflags);
- if (!rc_avpair_add(rh, send, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE))
- return -1;
-
- if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) {
- /* Unique ID */
- if (!rc_avpair_add(rh, send, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE))
- return -1;
- }
-
- if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) {
- /* append the user field */
- if (!rc_avpair_add(rh, send, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE))
- return -1;
- }
-
- /* Setting Acct-Session-Id & User-Name attributes for proper generation
- of Acct-Unique-Session-Id on server side */
- /* Channel */
- if (!rc_avpair_add(rh, send, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0))
- return -1;
-
- /* Unique ID */
- if (!rc_avpair_add(rh, send, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0))
- return -1;
-
- return 0;
-}
-
-static int radius_log(struct ast_cdr *cdr)
-{
- int result = ERROR_RC;
- VALUE_PAIR *send = NULL;
-
- if (build_radius_record(&send, cdr)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to create RADIUS record. CDR not recorded!\n");
- return result;
- }
-
- result = rc_acct(rh, 0, send);
- if (result != OK_RC)
- ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");
-
- return result;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- struct ast_config *cfg;
- int res;
- const char *tmp;
-
- if ((cfg = ast_config_load(cdr_config))) {
- ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "usegmtime")), RADIUS_FLAG_USEGMTIME);
- ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguniqueid")), RADIUS_FLAG_LOGUNIQUEID);
- ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguserfield")), RADIUS_FLAG_LOGUSERFIELD);
- if ((tmp = ast_variable_retrieve(cfg, "radius", "radiuscfg")))
- ast_copy_string(radiuscfg, tmp, sizeof(radiuscfg));
- ast_config_destroy(cfg);
- } else
- return AST_MODULE_LOAD_DECLINE;
-
- /* start logging */
- rc_openlog("asterisk");
-
- /* read radiusclient-ng config file */
- if (!(rh = rc_read_config(radiuscfg))) {
- ast_log(LOG_NOTICE, "Cannot load radiusclient-ng configuration file %s.\n", radiuscfg);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- /* read radiusclient-ng dictionaries */
- if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) {
- ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- res = ast_cdr_register(name, desc, radius_log);
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "RADIUS CDR Backend");
diff --git a/1.4/cdr/cdr_sqlite.c b/1.4/cdr/cdr_sqlite.c
deleted file mode 100644
index 5aa8a5154..000000000
--- a/1.4/cdr/cdr_sqlite.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005, Holger Schurig
- *
- *
- * Ideas taken from other cdr_*.c files
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Store CDR records in a SQLite database.
- *
- * \author Holger Schurig <hs4233@mail.mn-solutions.de>
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.sqlite.org/
- *
- * Creates the database and table on-the-fly
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>sqlite</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqlite.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-
-#define LOG_UNIQUEID 0
-#define LOG_USERFIELD 0
-
-/* When you change the DATE_FORMAT, be sure to change the CHAR(19) below to something else */
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static char *name = "sqlite";
-static sqlite* db = NULL;
-
-AST_MUTEX_DEFINE_STATIC(sqlite_lock);
-
-/*! \brief SQL table format */
-static char sql_create_table[] = "CREATE TABLE cdr ("
-" AcctId INTEGER PRIMARY KEY,"
-" clid VARCHAR(80),"
-" src VARCHAR(80),"
-" dst VARCHAR(80),"
-" dcontext VARCHAR(80),"
-" channel VARCHAR(80),"
-" dstchannel VARCHAR(80),"
-" lastapp VARCHAR(80),"
-" lastdata VARCHAR(80),"
-" start CHAR(19),"
-" answer CHAR(19),"
-" end CHAR(19),"
-" duration INTEGER,"
-" billsec INTEGER,"
-" disposition INTEGER,"
-" amaflags INTEGER,"
-" accountcode VARCHAR(20)"
-#if LOG_UNIQUEID
-" ,uniqueid VARCHAR(32)"
-#endif
-#if LOG_USERFIELD
-" ,userfield VARCHAR(255)"
-#endif
-");";
-
-static int sqlite_log(struct ast_cdr *cdr)
-{
- int res = 0;
- char *zErr = 0;
- struct tm tm;
- time_t t;
- char startstr[80], answerstr[80], endstr[80];
- int count;
-
- ast_mutex_lock(&sqlite_lock);
-
- t = cdr->start.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
-
- t = cdr->answer.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm);
-
- t = cdr->end.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
-
- for(count=0; count<5; count++) {
- res = sqlite_exec_printf(db,
- "INSERT INTO cdr ("
- "clid,src,dst,dcontext,"
- "channel,dstchannel,lastapp,lastdata, "
- "start,answer,end,"
- "duration,billsec,disposition,amaflags, "
- "accountcode"
-# if LOG_UNIQUEID
- ",uniqueid"
-# endif
-# if LOG_USERFIELD
- ",userfield"
-# endif
- ") VALUES ("
- "'%q', '%q', '%q', '%q', "
- "'%q', '%q', '%q', '%q', "
- "'%q', '%q', '%q', "
- "%d, %d, %d, %d, "
- "'%q'"
-# if LOG_UNIQUEID
- ",'%q'"
-# endif
-# if LOG_USERFIELD
- ",'%q'"
-# endif
- ")", NULL, NULL, &zErr,
- cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
- cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
- startstr, answerstr, endstr,
- cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
- cdr->accountcode
-# if LOG_UNIQUEID
- ,cdr->uniqueid
-# endif
-# if LOG_USERFIELD
- ,cdr->userfield
-# endif
- );
- if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
- break;
- usleep(200);
- }
-
- if (zErr) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- free(zErr);
- }
-
- ast_mutex_unlock(&sqlite_lock);
- return res;
-}
-
-static int unload_module(void)
-{
- if (db)
- sqlite_close(db);
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- char *zErr;
- char fn[PATH_MAX];
- int res;
-
- /* is the database there? */
- snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
- db = sqlite_open(fn, 0660, &zErr);
- if (!db) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- free(zErr);
- return -1;
- }
-
- /* is the table there? */
- res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
- if (res) {
- res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
- if (res) {
- ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
- free(zErr);
- goto err;
- }
-
- /* TODO: here we should probably create an index */
- }
-
- res = ast_cdr_register(name, ast_module_info->description, sqlite_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
- return -1;
- }
- return 0;
-
-err:
- if (db)
- sqlite_close(db);
- return -1;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SQLite CDR Backend");
diff --git a/1.4/cdr/cdr_tds.c b/1.4/cdr/cdr_tds.c
deleted file mode 100644
index 2536fae07..000000000
--- a/1.4/cdr/cdr_tds.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief FreeTDS CDR logger
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.freetds.org/
- * \ingroup cdr_drivers
- */
-
-/*! \verbatim
- *
- * Table Structure for `cdr`
- *
- * Created on: 05/20/2004 16:16
- * Last changed on: 07/27/2004 20:01
-
-CREATE TABLE [dbo].[cdr] (
- [accountcode] [varchar] (20) NULL ,
- [src] [varchar] (80) NULL ,
- [dst] [varchar] (80) NULL ,
- [dcontext] [varchar] (80) NULL ,
- [clid] [varchar] (80) NULL ,
- [channel] [varchar] (80) NULL ,
- [dstchannel] [varchar] (80) NULL ,
- [lastapp] [varchar] (80) NULL ,
- [lastdata] [varchar] (80) NULL ,
- [start] [datetime] NULL ,
- [answer] [datetime] NULL ,
- [end] [datetime] NULL ,
- [duration] [int] NULL ,
- [billsec] [int] NULL ,
- [disposition] [varchar] (20) NULL ,
- [amaflags] [varchar] (16) NULL ,
- [uniqueid] [varchar] (32) NULL
-) ON [PRIMARY]
-
-\endverbatim
-
-*/
-
-/*** MODULEINFO
- <depend>freetds</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <math.h>
-
-#include <tds.h>
-#include <tdsconvert.h>
-#include <ctype.h>
-
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-
-#ifdef FREETDS_PRE_0_62
-#warning "You have older TDS, you should upgrade!"
-#endif
-
-#define DATE_FORMAT "%Y/%m/%d %T"
-
-static char *name = "mssql";
-static char *config = "cdr_tds.conf";
-
-static char *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *charset = NULL, *language = NULL;
-static char *table = NULL;
-
-static int connected = 0;
-
-AST_MUTEX_DEFINE_STATIC(tds_lock);
-
-static TDSSOCKET *tds;
-static TDSLOGIN *login;
-static TDSCONTEXT *context;
-
-static char *anti_injection(const char *, int);
-static void get_date(char *, struct timeval);
-
-static int mssql_connect(void);
-static int mssql_disconnect(void);
-
-static int tds_log(struct ast_cdr *cdr)
-{
- char sqlcmd[2048], start[80], answer[80], end[80];
- char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid;
- int res = 0;
- int retried = 0;
-#ifdef FREETDS_PRE_0_62
- TDS_INT result_type;
-#endif
-
- ast_mutex_lock(&tds_lock);
-
- memset(sqlcmd, 0, 2048);
-
- accountcode = anti_injection(cdr->accountcode, 20);
- src = anti_injection(cdr->src, 80);
- dst = anti_injection(cdr->dst, 80);
- dcontext = anti_injection(cdr->dcontext, 80);
- clid = anti_injection(cdr->clid, 80);
- channel = anti_injection(cdr->channel, 80);
- dstchannel = anti_injection(cdr->dstchannel, 80);
- lastapp = anti_injection(cdr->lastapp, 80);
- lastdata = anti_injection(cdr->lastdata, 80);
- uniqueid = anti_injection(cdr->uniqueid, 32);
-
- get_date(start, cdr->start);
- get_date(answer, cdr->answer);
- get_date(end, cdr->end);
-
- sprintf(
- sqlcmd,
- "INSERT INTO %s "
- "("
- "accountcode, "
- "src, "
- "dst, "
- "dcontext, "
- "clid, "
- "channel, "
- "dstchannel, "
- "lastapp, "
- "lastdata, "
- "start, "
- "answer, "
- "[end], "
- "duration, "
- "billsec, "
- "disposition, "
- "amaflags, "
- "uniqueid"
- ") "
- "VALUES "
- "("
- "'%s', " /* accountcode */
- "'%s', " /* src */
- "'%s', " /* dst */
- "'%s', " /* dcontext */
- "'%s', " /* clid */
- "'%s', " /* channel */
- "'%s', " /* dstchannel */
- "'%s', " /* lastapp */
- "'%s', " /* lastdata */
- "%s, " /* start */
- "%s, " /* answer */
- "%s, " /* end */
- "%ld, " /* duration */
- "%ld, " /* billsec */
- "'%s', " /* disposition */
- "'%s', " /* amaflags */
- "'%s'" /* uniqueid */
- ")",
- table,
- accountcode,
- src,
- dst,
- dcontext,
- clid,
- channel,
- dstchannel,
- lastapp,
- lastdata,
- start,
- answer,
- end,
- cdr->duration,
- cdr->billsec,
- ast_cdr_disp2str(cdr->disposition),
- ast_cdr_flags2str(cdr->amaflags),
- uniqueid
- );
-
- do {
- if (!connected) {
- if (mssql_connect())
- ast_log(LOG_ERROR, "Failed to reconnect to SQL database.\n");
- else
- ast_log(LOG_WARNING, "Reconnected to SQL database.\n");
-
- retried = 1; /* note that we have now tried */
- }
-
-#ifdef FREETDS_PRE_0_62
- if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
-#else
- if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
-#endif
- {
- ast_log(LOG_ERROR, "Failed to insert Call Data Record into SQL database.\n");
-
- mssql_disconnect(); /* this is ok even if we are already disconnected */
- }
- } while (!connected && !retried);
-
- free(accountcode);
- free(src);
- free(dst);
- free(dcontext);
- free(clid);
- free(channel);
- free(dstchannel);
- free(lastapp);
- free(lastdata);
- free(uniqueid);
-
- ast_mutex_unlock(&tds_lock);
-
- return res;
-}
-
-static char *anti_injection(const char *str, int len)
-{
- /* Reference to http://www.nextgenss.com/papers/advanced_sql_injection.pdf */
-
- char *buf;
- char *buf_ptr, *srh_ptr;
- char *known_bad[] = {"select", "insert", "update", "delete", "drop", ";", "--", "\0"};
- int idx;
-
- if ((buf = malloc(len + 1)) == NULL)
- {
- ast_log(LOG_ERROR, "cdr_tds: Out of memory error\n");
- return NULL;
- }
- memset(buf, 0, len);
-
- buf_ptr = buf;
-
- /* Escape single quotes */
- for (; *str && strlen(buf) < len; str++)
- {
- if (*str == '\'')
- *buf_ptr++ = '\'';
- *buf_ptr++ = *str;
- }
- *buf_ptr = '\0';
-
- /* Erase known bad input */
- for (idx=0; *known_bad[idx]; idx++)
- {
- while((srh_ptr = strcasestr(buf, known_bad[idx])))
- {
- memmove(srh_ptr, srh_ptr+strlen(known_bad[idx]), strlen(srh_ptr+strlen(known_bad[idx]))+1);
- }
- }
-
- return buf;
-}
-
-static void get_date(char *dateField, struct timeval tv)
-{
- struct tm tm;
- time_t t;
- char buf[80];
-
- /* To make sure we have date variable if not insert null to SQL */
- if (!ast_tvzero(tv))
- {
- t = tv.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(buf, 80, DATE_FORMAT, &tm);
- sprintf(dateField, "'%s'", buf);
- }
- else
- {
- strcpy(dateField, "null");
- }
-}
-
-static int mssql_disconnect(void)
-{
- if (tds) {
- tds_free_socket(tds);
- tds = NULL;
- }
-
- if (context) {
- tds_free_context(context);
- context = NULL;
- }
-
- if (login) {
- tds_free_login(login);
- login = NULL;
- }
-
- connected = 0;
-
- return 0;
-}
-
-static int mssql_connect(void)
-{
-#if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
- TDSCONNECTION *connection = NULL;
-#else
- TDSCONNECTINFO *connection = NULL;
-#endif
- char query[128];
-
- /* Connect to M$SQL Server */
- if (!(login = tds_alloc_login()))
- {
- ast_log(LOG_ERROR, "tds_alloc_login() failed.\n");
- return -1;
- }
-
- tds_set_server(login, hostname);
- tds_set_user(login, dbuser);
- tds_set_passwd(login, password);
- tds_set_app(login, "TSQL");
- tds_set_library(login, "TDS-Library");
-#ifndef FREETDS_PRE_0_62
- tds_set_client_charset(login, charset);
-#endif
- tds_set_language(login, language);
- tds_set_packet(login, 512);
- tds_set_version(login, 7, 0);
-
-#ifdef FREETDS_0_64
- if (!(context = tds_alloc_context(NULL)))
-#else
- if (!(context = tds_alloc_context()))
-#endif
- {
- ast_log(LOG_ERROR, "tds_alloc_context() failed.\n");
- goto connect_fail;
- }
-
- if (!(tds = tds_alloc_socket(context, 512))) {
- ast_log(LOG_ERROR, "tds_alloc_socket() failed.\n");
- goto connect_fail;
- }
-
- tds_set_parent(tds, NULL);
- connection = tds_read_config_info(tds, login, context->locale);
- if (!connection)
- {
- ast_log(LOG_ERROR, "tds_read_config() failed.\n");
- goto connect_fail;
- }
-
- if (tds_connect(tds, connection) == TDS_FAIL)
- {
- ast_log(LOG_ERROR, "Failed to connect to MSSQL server.\n");
- tds = NULL; /* freed by tds_connect() on error */
-#if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
- tds_free_connection(connection);
-#else
- tds_free_connect(connection);
-#endif
- connection = NULL;
- goto connect_fail;
- }
-#if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
- tds_free_connection(connection);
-#else
- tds_free_connect(connection);
-#endif
- connection = NULL;
-
- sprintf(query, "USE %s", dbname);
-#ifdef FREETDS_PRE_0_62
- if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
-#else
- if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
-#endif
- {
- ast_log(LOG_ERROR, "Could not change database (%s)\n", dbname);
- goto connect_fail;
- }
-
- connected = 1;
- return 0;
-
-connect_fail:
- mssql_disconnect();
- return -1;
-}
-
-static int tds_unload_module(void)
-{
- mssql_disconnect();
-
- ast_cdr_unregister(name);
-
- if (hostname) free(hostname);
- if (dbname) free(dbname);
- if (dbuser) free(dbuser);
- if (password) free(password);
- if (charset) free(charset);
- if (language) free(language);
- if (table) free(table);
-
- return 0;
-}
-
-static int tds_load_module(void)
-{
- int res = 0;
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *ptr = NULL;
-#ifdef FREETDS_PRE_0_62
- TDS_INT result_type;
-#endif
-
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config for MSSQL CDR's: %s\n", config);
- return 0;
- }
-
- var = ast_variable_browse(cfg, "global");
- if (!var) /* nothing configured */ {
- ast_config_destroy(cfg);
- return 0;
- }
-
- ptr = ast_variable_retrieve(cfg, "global", "hostname");
- if (ptr)
- hostname = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database server hostname not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "dbname");
- if (ptr)
- dbname = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database dbname not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "user");
- if (ptr)
- dbuser = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database dbuser not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "password");
- if (ptr)
- password = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database password not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "charset");
- if (ptr)
- charset = strdup(ptr);
- else
- charset = strdup("iso_1");
-
- ptr = ast_variable_retrieve(cfg, "global", "language");
- if (ptr)
- language = strdup(ptr);
- else
- language = strdup("us_english");
-
- ptr = ast_variable_retrieve(cfg,"global","table");
- if (ptr == NULL) {
- ast_log(LOG_DEBUG,"cdr_tds: table not specified. Assuming cdr\n");
- ptr = "cdr";
- }
- table = strdup(ptr);
-
- ast_config_destroy(cfg);
-
- mssql_connect();
-
- /* Register MSSQL CDR handler */
- res = ast_cdr_register(name, ast_module_info->description, tds_log);
- if (res)
- {
- ast_log(LOG_ERROR, "Unable to register MSSQL CDR handling\n");
- }
-
- return res;
-}
-
-static int reload(void)
-{
- tds_unload_module();
- return tds_load_module();
-}
-
-static int load_module(void)
-{
- if(!tds_load_module())
- return AST_MODULE_LOAD_DECLINE;
- else
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
- return tds_unload_module();
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "MSSQL CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/DialTone.h b/1.4/channels/DialTone.h
deleted file mode 100644
index 098ed44d7..000000000
--- a/1.4/channels/DialTone.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 8-bit raw data
- *
- * Source: DialTone.ulaw
- *
- * Copyright (C) 1999, Mark Spencer
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char DialTone[] = {
-0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa,
-0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c,
-0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3,
-0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47,
-0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49,
-0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf,
-0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24,
-0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e,
-0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b,
-0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c,
-0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f,
-0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9,
-0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41,
-0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b,
-0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5,
-0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b,
-0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96,
-0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14,
-0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95,
-0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a,
-0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5,
-0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43,
-0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32,
-0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e,
-0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16,
-0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91,
-0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10,
-0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92,
-0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19,
-0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4,
-0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a,
-0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d,
-0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c,
-0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15,
-0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90,
-0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10,
-0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93,
-0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a,
-0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8,
-0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a,
-0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c,
-0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d,
-0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16,
-0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93,
-0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13,
-0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97,
-0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e,
-0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad,
-0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9,
-0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e,
-0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0,
-0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b,
-0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a,
-0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b,
-0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e,
-0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28,
-0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9,
-0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0,
-0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36,
-0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab,
-0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27,
-0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6,
-0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29,
-0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae,
-0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a,
-0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd,
-0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7,
-0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c,
-0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7,
-0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a,
-0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5,
-0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78,
-0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d,
-0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6,
-0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e,
-0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64,
-0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7,
-0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39,
-0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf,
-0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b,
-0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa,
-0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c,
-0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3,
-0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47,
-0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49,
-0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf,
-0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24,
-0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e,
-0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b,
-0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c,
-0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f,
-0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9,
-0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41,
-0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b,
-0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5,
-0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b,
-0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96,
-0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14,
-0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95,
-0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a,
-0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5,
-0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43,
-0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32,
-0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e,
-0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16,
-0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91,
-0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10,
-0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92,
-0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19,
-0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4,
-0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a,
-0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d,
-0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c,
-0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15,
-0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90,
-0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10,
-0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93,
-0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a,
-0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8,
-0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a,
-0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c,
-0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d,
-0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16,
-0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93,
-0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13,
-0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97,
-0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e,
-0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad,
-0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9,
-0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e,
-0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0,
-0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b,
-0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a,
-0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b,
-0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e,
-0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28,
-0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9,
-0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0,
-0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36,
-0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab,
-0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27,
-0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6,
-0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29,
-0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae,
-0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a,
-0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd,
-0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7,
-0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c,
-0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7,
-0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a,
-0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5,
-0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78,
-0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d,
-0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6,
-0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e,
-0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64,
-0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7,
-0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39,
-0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf,
-0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b,
-0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa,
-0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c,
-0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3,
-0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47,
-0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49,
-0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf,
-0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24,
-0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e,
-0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b,
-0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c,
-0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f,
-0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9,
-0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41,
-0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b,
-0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5,
-0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b,
-0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96,
-0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14,
-0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95,
-0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a,
-0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5,
-0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43,
-0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32,
-0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e,
-0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16,
-0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91,
-0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10,
-0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92,
-0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19,
-0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4,
-0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a,
-0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d,
-0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c,
-0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15,
-0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90,
-0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10,
-0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93,
-0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a,
-0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8,
-0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a,
-0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c,
-0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d,
-0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16,
-0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93,
-0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13,
-0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97,
-0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e,
-0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad,
-0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9,
-0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e,
-0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0,
-0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b,
-0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a,
-0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b,
-0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e,
-0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28,
-0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9,
-0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0,
-0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36,
-0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab,
-0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27,
-0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6,
-0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29,
-0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae,
-0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a,
-0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd,
-0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7,
-0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c,
-0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7,
-0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a,
-0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5,
-0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78,
-0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d,
-0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6,
-0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e,
-0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64,
-0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7,
-0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39,
-0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf,
-0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b };
diff --git a/1.4/channels/Makefile b/1.4/channels/Makefile
deleted file mode 100644
index d46632e01..000000000
--- a/1.4/channels/Makefile
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for channel drivers
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=CHANNELS
-MENUSELECT_DESCRIPTION=Channel Drivers
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard chan_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard chan_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_CHANNELS),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_CHANNELS),$(ALL_CC_MODS))
-
-ifeq ($(OSARCH),OpenBSD)
- PTLIB=-lpt_OpenBSD_x86_r
- H323LIB=-lh323_OpenBSD_x86_r
-endif
-
-ifeq ($(OSARCH),linux-gnu)
- PTLIB=-lpt_linux_x86_r
- H323LIB=-lh323_linux_x86_r
- CHANH323LIB=-ldl
-endif
-
-ifeq ($(OSARCH),FreeBSD)
- PTLIB=-lpt_FreeBSD_x86_r
- H323LIB=-lh323_FreeBSD_x86_r
- CHANH323LIB=-pthread
-endif
-
-ifeq ($(OSARCH),NetBSD)
- PTLIB=-lpt_NetBSD_x86_r
- H323LIB=-lh323_NetBSD_x86_r
-endif
-
-ifeq ($(wildcard h323/libchanh323.a),)
- CC_MODS:=$(filter-out chan_h323,$(CC_MODS))
-endif
-
-ifndef OPENH323DIR
- OPENH323DIR=$(HOME)/openh323
-endif
-
-ifndef PWLIBDIR
- PWLIBDIR=$(HOME)/pwlib
-endif
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring channels,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
-
-clean::
- rm -f busy.h ringtone.h gentone
- $(MAKE) -C misdn clean
-
-ifneq ($(wildcard h323/Makefile.ast),)
- include h323/Makefile.ast
-H323LDFLAGS+=-Wl,--version-script=h323/noexport.map
-clean::
- if [ -f h323/Makefile ]; then $(MAKE) -C h323 clean; fi
-else
-h323/libchanh323.a h323/Makefile.ast:
- $(CMD_PREFIX) $(MAKE) -C h323
- $(CMD_PREFIX) rm -f ../main/asterisk
- $(CMD_PREFIX) echo "***************************************************************"
- $(CMD_PREFIX) echo
- $(CMD_PREFIX) echo "********** Re-run 'make' to pick up H.323 parameters **********"
- $(CMD_PREFIX) echo
- $(CMD_PREFIX) echo "***************************************************************"
- $(CMD_PREFIX) exit 1
-endif
-
-dist-clean::
- rm -f h323/Makefile
-
-gentone: gentone.c
- $(ECHO_PREFIX) echo " [LD] $^ -> $@"
- $(CMD_PREFIX) $(HOST_CC) $(STATIC_BUILD) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $^ $(LIBS)
-gentone: LIBS+=-lm
-
-busy.h: gentone
- ./gentone busy 480 620
-
-ringtone.h: gentone
- ./gentone ringtone 440 480
-
-chan_oss.o: busy.h ringtone.h
-
-$(if $(filter chan_iax2,$(EMBEDDED_MODS)),modules.link,chan_iax2.so): iax2-parser.o iax2-provision.o
-
-chan_alsa.o: busy.h ringtone.h
-
-ifeq ($(OSARCH),linux-gnu)
-chan_h323.so: chan_h323.o h323/libchanh323.a h323/Makefile.ast
- $(ECHO_PREFIX) echo " [LD] $^ -> $@"
- $(CMD_PREFIX) $(CXX) $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) $(H323LDFLAGS) -o $@ $< h323/libchanh323.a $(H323LDLIBS)
-else
-chan_h323.so: chan_h323.o h323/libchanh323.a
- $(ECHO_PREFIX) echo " [LD] $^ -> $@"
- $(CMD_PREFIX) $(CXX) $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) -o $@ $< h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat
-endif
-
-chan_misdn.o: ASTCFLAGS+=-Imisdn
-
-misdn_config.o: ASTCFLAGS+=-Imisdn
-
-misdn/isdn_lib.o: ASTCFLAGS+=-Wno-strict-aliasing
-
-misdn_config.o misdn/isdn_lib.o misdn/isdn_msg_parser.o: ASTCFLAGS+=$(MENUSELECT_OPTS_chan_misdn:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_chan_misdn),$(value $(dep)_INCLUDE))
-
-$(if $(filter chan_misdn,$(EMBEDDED_MODS)),modules.link,chan_misdn.so): chan_misdn.o misdn_config.o misdn/isdn_lib.o misdn/isdn_msg_parser.o
diff --git a/1.4/channels/answer.h b/1.4/channels/answer.h
deleted file mode 100644
index 4168c5012..000000000
--- a/1.4/channels/answer.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/*!\file
- * \brief Signed 16-bit audio data
- *
- * Source: answer.raw
- *
- * Copyright (C) 1999-2005, Digium, Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short answer[] = {
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 0x19b7, 0x0245, 0xeee5, 0xb875, 0xd9a4, 0x6018, 0x660a, 0xc3c6,
-0x8741, 0xff55, 0x4c2e, 0x2146, 0xfed2, 0xf079, 0xcbd4, 0xe561, 0x3c41, 0x3166,
-0xd425, 0xdc59, 0x2748, 0x087d, 0xc72b, 0xfe3a, 0x4681, 0x14c6, 0xcf45, 0xdd38,
-0xf8dd, 0x0a39, 0x3a5a, 0x32b9, 0xbfec, 0x957f, 0x15a3, 0x70f4, 0x1d95, 0xbfc4,
-0xd367, 0xfda0, 0x0dc0, 0x29eb, 0x1fc2, 0xd684, 0xcab1, 0x19c7, 0x29ef, 0xe679,
-0xe9d0, 0x2b82, 0x151a, 0xca9f, 0xdb68, 0x1f4a, 0x271c, 0x0e2a, 0xfb32, 0xd1b2,
-0xc8ff, 0x2382, 0x6380, 0x0a52, 0xa118, 0xccbf, 0x2ddc, 0x33fd, 0x0964, 0xf2a4,
-0xdd81, 0xe092, 0x1a00, 0x325c, 0xf5e3, 0xd6a1, 0x0b6c, 0x1c75, 0xe4f8, 0xe07c,
-0x2082, 0x2b3e, 0xf445, 0xdaa9, 0xea13, 0xff3c, 0x245c, 0x35c1, 0xf308, 0xab53,
-0xdf59, 0x4698, 0x3f3b, 0xe7f7, 0xca84, 0xed4d, 0x0c3f, 0x1e94, 0x1c2d, 0xf06f,
-0xd4df, 0xff34, 0x23d8, 0x001e, 0xe3f1, 0x0b15, 0x2113, 0xf3fd, 0xd768, 0xf9a0,
-0x1d31, 0x1c6e, 0x0797, 0xe3a0, 0xce6c, 0xfd7b, 0x422a, 0x2c4c, 0xd364, 0xbf42,
-0x0278, 0x303e, 0x1c51, 0xf737, 0xe25a, 0xe75f, 0x0a8f, 0x22ab, 0x05f4, 0xe3f9,
-0xf8c4, 0x1705, 0x0162, 0xe49f, 0xfb8b, 0x1e2b, 0x13ac, 0xf044, 0xe07b, 0xf01a,
-0x1567, 0x2cbf, 0x0b75, 0xd01b, 0xd206, 0x1563, 0x38d7, 0x0f2e, 0xdb32, 0xdc30,
-0x023b, 0x1e44, 0x16eb, 0xf5f7, 0xe425, 0xfa33, 0x14d5, 0x0968, 0xeff2, 0xf762,
-0x1137, 0x0e59, 0xf13a, 0xe651, 0xff41, 0x1d60, 0x18fd, 0xf1e6, 0xd75f, 0xf097,
-0x20ec, 0x27fa, 0xfba4, 0xd5b8, 0xe68e, 0x1657, 0x2518, 0x04f6, 0xe5a3, 0xe976,
-0x0578, 0x18fa, 0x0a92, 0xec0a, 0xef2a, 0x111f, 0x12f4, 0xeec3, 0xe95e, 0x0d3a,
-0x18fd, 0xff72, 0xeefc, 0xf114, 0xfaaa, 0x14ee, 0x21db, 0xf56e, 0xcb49, 0xf621,
-0x3323, 0x1947, 0xe017, 0xe7e9, 0x0819, 0x0707, 0x084c, 0x0f57, 0xf152, 0xdf92,
-0x104a, 0x28eb, 0xedcc, 0xd4ad, 0x1415, 0x296d, 0xed9a, 0xdf57, 0x0cc2, 0x0d95,
-0xf7b5, 0x0deb, 0x0b34, 0xd713, 0xea08, 0x38d6, 0x216d, 0xc727, 0xdc32, 0x2cd2,
-0x1822, 0xe2d5, 0xfeb3, 0x106c, 0xe6e5, 0xf81e, 0x2fe8, 0x01af, 0xc180, 0x037a,
-0x42d8, 0xf88d, 0xc344, 0x0a4f, 0x2c4e, 0xf19d, 0xebeb, 0x162c, 0xf9e9, 0xde93,
-0x1b56, 0x2c60, 0xd8aa, 0xce3e, 0x2a41, 0x2eeb, 0xdab1, 0xde32, 0x1c32, 0x0aba,
-0xeabe, 0x1008, 0x136d, 0xda2f, 0xec3b, 0x31dd, 0x1130, 0xca79, 0xf5b8, 0x3423,
-0x0274, 0xd27d, 0x035e, 0x1e68, 0xf641, 0xf904, 0x1691, 0xef7d, 0xd57a, 0x1c3b,
-0x3c23, 0xe881, 0xc274, 0x0af5, 0x2962, 0xfa34, 0xf676, 0x0f71, 0xefcc, 0xe01f,
-0x19e7, 0x276f, 0xe694, 0xe134, 0x1c3a, 0x0e8b, 0xd8e7, 0xfa81, 0x2f8b, 0x07c5,
-0xd904, 0xf6fa, 0x0ca5, 0xf9a2, 0x0dc7, 0x2623, 0xec54, 0xbe23, 0x02b6, 0x4296,
-0x10cd, 0xda61, 0xf11c, 0x0103, 0xf41c, 0x10b4, 0x2a03, 0xf63c, 0xce1a, 0xfdbd,
-0x1fb4, 0xfc51, 0xf727, 0x1c8a, 0x04ff, 0xcf41, 0xec05, 0x2913, 0x1ce8, 0xf70c,
-0xf744, 0xede8, 0xdd77, 0x0d99, 0x43f1, 0x119c, 0xc14f, 0xd60e, 0x17cb, 0x1e19,
-0x0d4e, 0x0c95, 0xeed1, 0xcdf4, 0xf7a5, 0x331f, 0x1cd0, 0xeb17, 0xf082, 0xfb19,
-0xe899, 0xfdeb, 0x323c, 0x2036, 0xdad3, 0xd134, 0xfd03, 0x1345, 0x1c10, 0x2239,
-0xf656, 0xbc22, 0xdc3f, 0x3392, 0x3d59, 0xfd77, 0xdb4d, 0xe23f, 0xedbe, 0x0f7e,
-0x35cc, 0x1947, 0xd5dc, 0xd1bf, 0x035d, 0x16fc, 0x1174, 0x1675, 0x0249, 0xd2d4,
-0xd851, 0x184d, 0x32fe, 0x0f91, 0xee14, 0xe1e6, 0xdf9b, 0x016b, 0x3668, 0x2b2b,
-0xe20c, 0xc554, 0xf257, 0x1c05, 0x1fc5, 0x14f0, 0xf891, 0xd41c, 0xdf83, 0x1865,
-0x2de1, 0x0b16, 0xed58, 0xea0c, 0xea79, 0xfbd9, 0x22af, 0x2732, 0xf62f, 0xd389,
-0xe7d9, 0x0b39, 0x1cdc, 0x1de3, 0x038a, 0xd809, 0xd5f7, 0x0b55, 0x305e, 0x1910,
-0xf02e, 0xe089, 0xe7c7, 0x0195, 0x2265, 0x21da, 0xf743, 0xd8f2, 0xe978, 0x09a1,
-0x190a, 0x17c5, 0x045a, 0xe46d, 0xdd06, 0xffb2, 0x2293, 0x1cfe, 0xfd4d, 0xe4f9,
-0xe310, 0xfaf1, 0x1d22, 0x2376, 0x0113, 0xde3a, 0xe21b, 0x0204, 0x1ba1, 0x1bd6,
-0x0333, 0xe563, 0xe104, 0xfd51, 0x1bc1, 0x1ccf, 0x0285, 0xe757, 0xe35e, 0xfaf2,
-0x185d, 0x1d46, 0x06b7, 0xec13, 0xe108, 0xef6e, 0x121d, 0x2a17, 0x16a6, 0xe32c,
-0xc9a9, 0xf070, 0x2f48, 0x3788, 0xfa4e, 0xc32a, 0xd9c2, 0x1fa1, 0x36fe, 0x07fa,
-0xd9e4, 0xe577, 0x0e5e, 0x1755, 0xfb53, 0xed71, 0x0540, 0x19e0, 0x0301, 0xdc97,
-0xe391, 0x1937, 0x367c, 0x0bc9, 0xca4c, 0xc96b, 0x105d, 0x461f, 0x2416, 0xd481,
-0xbc97, 0xf8b7, 0x39af, 0x2ec9, 0xecc6, 0xcb50, 0xeee3, 0x1ffe, 0x1e8e, 0xf700,
-0xe66a, 0xff58, 0x149f, 0x02e5, 0xe792, 0xf2d8, 0x1a4d, 0x225a, 0xf642, 0xce7f,
-0xe6a6, 0x25e2, 0x38f5, 0x01d0, 0xc50f, 0xd243, 0x19bd, 0x3fc6, 0x14f0, 0xd2d7,
-0xcdb6, 0x069a, 0x2ffe, 0x1847, 0xe6f8, 0xdf0a, 0x0337, 0x1a90, 0x067a, 0xeb5b,
-0xf541, 0x143b, 0x14f2, 0xf092, 0xdc02, 0xfb91, 0x28a3, 0x2274, 0xeaa8, 0xc9e7,
-0xef48, 0x2d01, 0x322e, 0xf6d2, 0xc7cb, 0xe13b, 0x1fda, 0x3217, 0x0458, 0xd690,
-0xe2bf, 0x11c4, 0x21d5, 0x0291, 0xe5c8, 0xf3a9, 0x12ba, 0x11aa, 0xf22b, 0xe627,
-0x03ec, 0x219a, 0x1036, 0xe2f2, 0xd93f, 0x059c, 0x2ed6, 0x1b75, 0xe227, 0xce55,
-0xfb19, 0x2de0, 0x2477, 0xed08, 0xd148, 0xf307, 0x21d4, 0x2002, 0xf543, 0xdeac,
-0xf7f9, 0x18a9, 0x11d6, 0xf0ef, 0xe8e4, 0x05ea, 0x1ba5, 0x0727, 0xe448, 0xe748,
-0x100e, 0x265e, 0x07fc, 0xdbae, 0xde78, 0x0efa, 0x2ce0, 0x0f94, 0xddf1, 0xd9ea,
-0x0797, 0x28f6, 0x12eb, 0xe60c, 0xdf46, 0x0469, 0x1fbb, 0x0ced, 0xe9f6, 0xe95f,
-0x09fe, 0x1ab9, 0x02cb, 0xe5a4, 0xef2a, 0x1327, 0x1d7b, 0xfd07, 0xde3d, 0xed9c,
-0x17e5, 0x22e7, 0xfe3a, 0xdb38, 0xe9b9, 0x161a, 0x2416, 0x0175, 0xde3d, 0xe9de,
-0x1294, 0x1fc9, 0x00ea, 0xe2a7, 0xeee2, 0x1298, 0x1a7d, 0xfc1d, 0xe3bb, 0xf47a,
-0x1642, 0x185e, 0xf727, 0xe1af, 0xf709, 0x19c3, 0x18e7, 0xf50d, 0xe010, 0xf75b,
-0x1a9c, 0x18d8, 0xf4c5, 0xe0c9, 0xf865, 0x1a1c, 0x16d5, 0xf3a6, 0xe257, 0xfaf2,
-0x1a44, 0x14d5, 0xf34f, 0xe4b6, 0xfc77, 0x17d5, 0x0ff8, 0xf133, 0xe8b7, 0x0344,
-0x1a37, 0x0ad5, 0xe95e, 0xe61a, 0x08a5, 0x227e, 0x0e33, 0xe4a7, 0xdd70, 0x03b0,
-0x25f4, 0x17b2, 0xec0a, 0xdb4e, 0xf898, 0x1ba3, 0x18f6, 0xf973, 0xe87f, 0xf77a,
-0x0b93, 0x096c, 0xfb0e, 0xfb03, 0x0896, 0x0940, 0xf51d, 0xe904, 0xfdc7, 0x1dda,
-0x1bf9, 0xf29b, 0xd37f, 0xea1b, 0x1f37, 0x3175, 0x07eb, 0xd3f7, 0xd46b, 0x077d,
-0x2eeb, 0x1e67, 0xeeae, 0xd8c7, 0xef85, 0x1119, 0x18d3, 0x088e, 0xf953, 0xf5ad,
-0xf556, 0xf63d, 0x0234, 0x167a, 0x19a1, 0xfbf9, 0xd873, 0xdd4b, 0x0f06, 0x3748,
-0x21e6, 0xe181, 0xc032, 0xe79a, 0x2bec, 0x3e76, 0x0b1b, 0xce41, 0xcb23, 0xff96,
-0x2d79, 0x26d1, 0xfcc7, 0xdf8a, 0xe525, 0xfd83, 0x10f1, 0x16d7, 0x0f50, 0xfaea,
-0xe3f1, 0xe20f, 0x0158, 0x27d9, 0x2866, 0xf96f, 0xcb34, 0xd563, 0x11d6, 0x3d25,
-0x2424, 0xe254, 0xc2c9, 0xe7cd, 0x248d, 0x34f5, 0x0c42, 0xdcd0, 0xd827, 0xfa65,
-0x19eb, 0x1b50, 0x0721, 0xf396, 0xeb9c, 0xefde, 0x0016, 0x1594, 0x1cc1, 0x0658,
-0xe22b, 0xd852, 0xfb3e, 0x2923, 0x2c78, 0xfc87, 0xcdb5, 0xd69c, 0x0e3c, 0x3527,
-0x201f, 0xe993, 0xcf9e, 0xeb21, 0x183f, 0x25ea, 0x0c93, 0xed4d, 0xe5f9, 0xf548,
-0x07fb, 0x117c, 0x0ff2, 0x0398, 0xf08c, 0xe628, 0xf489, 0x143b, 0x2419, 0x0ccf,
-0xe2cc, 0xd5a6, 0xf861, 0x2615, 0x2a1b, 0xfeb4, 0xd543, 0xdc53, 0x09b4, 0x2901,
-0x19ff, 0xf24a, 0xde86, 0xeec4, 0x0b7b, 0x1733, 0x0d0a, 0xfc24, 0xf1bb, 0xf110,
-0xfa03, 0x0a0f, 0x15d4, 0x0e21, 0xf435, 0xe17e, 0xee90, 0x1225, 0x2527, 0x0efa,
-0xe61f, 0xd916, 0xf7b8, 0x1f50, 0x2326, 0x0099, 0xe01e, 0xe473, 0x0491, 0x1b37,
-0x1360, 0xfb17, 0xecd9, 0xf20d, 0x0051, 0x0aec, 0x0d4a, 0x073d, 0xfa5a, 0xeeb8,
-0xf165, 0x0516, 0x17dc, 0x12da, 0xf71b, 0xe213, 0xed85, 0x0eef, 0x20c8, 0x0e09,
-0xebcc, 0xe0d4, 0xf848, 0x1637, 0x19d6, 0x026b, 0xec09, 0xed00, 0xff9b, 0x0e5a,
-0x0d6b, 0x026c, 0xf865, 0xf4da, 0xf888, 0x025a, 0x0cbb, 0x0d53, 0xff96, 0xeefa,
-0xee80, 0x021c, 0x15d6, 0x126a, 0xf9c1, 0xe724, 0xf017, 0x0aa1, 0x18b6, 0x0b4e,
-0xf2d7, 0xea91, 0xf957, 0x0cac, 0x1061, 0x03f4, 0xf6ad, 0xf476, 0xfbdf, 0x0489,
-0x08b1, 0x06df, 0xffcf, 0xf766, 0xf537, 0xfddf, 0x0ad4, 0x0e15, 0x01da, 0xf205,
-0xf0a0, 0x0082, 0x1066, 0x0e41, 0xfc71, 0xef1b, 0xf4ad, 0x05cd, 0x0f32, 0x07ed,
-0xf9c8, 0xf401, 0xfa93, 0x04af, 0x088c, 0x04a7, 0xfe15, 0xf9f1, 0xfa64, 0xff1e,
-0x0539, 0x078c, 0x02af, 0xfa1a, 0xf69d, 0xfd09, 0x075b, 0x0a3d, 0x01f2, 0xf761,
-0xf642, 0xffa7, 0x08f3, 0x0830, 0xff05, 0xf7db, 0xf9bc, 0x0174, 0x068b, 0x04b2,
-0xfeff, 0xfb39, 0xfc1a, 000000, 0x0371, 0x03d7, 0x00fe, 0xfd37, 0xfbe0, 0xfe78,
-0x02af, 0x044a, 0x0180, 0xfd43, 0xfc00, 0xfed1, 0x02aa, 0x0346, 0x00dd, 0xfde0,
-0xfbfe, 0x0114, 0x0987, 0x04bc, 0xf49d, 0xf23a, 0x06ab, 0x162e, 0x0544, 0xe76b,
-0xea25, 0x1015, 0x2474, 0x0431, 0xd7d3, 0xe1ec, 0x1923, 0x2df5, 0x01cd, 0xd386,
-0xe3d9, 0x1b9d, 0x2c62, 0xfeb8, 0xd31a, 0xe6ba, 0x1dbd, 0x2abb, 0xfbab, 0xd2ed,
-0xe9ab, 0x1fa7, 0x28ef, 0xf8b3, 0xd2f5, 0xeca5, 0x2160, 0x26fd, 0xf5d7, 0xd334,
-0xefa1, 0x22e5, 0x24ea, 0xf31b, 0xd3a9, 0xf29f, 0x2435, 0x22b6, 0xf07e, 0xd44e,
-0xf59b, 0x2551, 0x2067, 0xee08, 0xd527, 0xf88e, 0x2639, 0x1e00, 0xebb6, 0xd62d,
-0xfb77, 0x26eb, 0x1b85, 0xe98b, 0xd75f, 0xfe51, 0x276b, 0x18f9, 0xe78e, 0xd8b9,
-0x011a, 0x27b6, 0x1660, 0xe5bb, 0xda3a, 0x03cc, 0x27cf, 0x13bd, 0xe415, 0xdbdf,
-0x066a, 0x27b7, 0x1117, 0xe29e, 0xdda5, 0x08ec, 0x276e, 0x0e6d, 0xe154, 0xdf89,
-0x0b52, 0x26f6, 0x0bc7, 0xe039, 0xe185, 0x0d96, 0x2653, 0x0924, 0xdf4e, 0xe399,
-0x0fb9, 0x2584, 0x068b, 0xde93, 0xe5c0, 0x11b8, 0x248e, 0x03fd, 0xde08, 0xe7f8,
-0x1390, 0x2372, 0x0180, 0xddaa, 0xea3c, 0x1544, 0x2231, 0xff12, 0xdd7a, 0xec89,
-0x16cf, 0x20d0, 0xfcb9, 0xdd77, 0xeedb, 0x1831, 0x1f52, 0xfa77, 0xdd9f, 0xf132,
-0x1969, 0x1db7, 0xf850, 0xddf1, 0xf385, 0x1a75, 0x1c06, 0xf645, 0xde6b, 0xf5d7,
-0x1b5b, 0x1a3f, 0xf457, 0xdf0d, 0xf820, 0x1c13, 0x1867, 0xf288, 0xdfd2, 0xfa5f,
-0x1ca1, 0x167f, 0xf0db, 0xe0ba, 0xfc92, 0x1d06, 0x148b, 0xef50, 0xe1c1, 0xfeb5,
-0x1d43, 0x1290, 0xede9, 0xe2e6, 0x00c6, 0x1d58, 0x108e, 0xeca7, 0xe426, 0x02c4,
-0x1d45, 0x0e8a, 0xeb8a, 0xe57f, 0x04a9, 0x1d0e, 0x0c87, 0xea92, 0xe6ec, 0x0677,
-0x1cb2, 0x0a87, 0xe9be, 0xe86e, 0x082a, 0x1c34, 0x088b, 0xe912, 0xe9fe, 0x09c1,
-0x1b95, 0x069c, 0xe88c, 0xeb9c, 0x0b3a, 0x1ad9, 0x04b6, 0xe82a, 0xed43, 0x0c96,
-0x1a00, 0x02df, 0xe7eb, 0xeef3, 0x0dd0, 0x190d, 0x0116, 0xe7d0, 0xf0a8, 0x0eec,
-0x1804, 0xff61, 0xe7d8, 0xf25d, 0x0fe6, 0x16e3, 0xfdc0, 0xe800, 0xf412, 0x10bf,
-0x15b1, 0xfc36, 0xe848, 0xf5c5, 0x1176, 0x146e, 0xfac2, 0xe8ad, 0xf771, 0x120d,
-0x1320, 0xf969, 0xe92e, 0xf913, 0x1282, 0x11c4, 0xf828, 0xe9cb, 0xfaac, 0x12d8,
-0x1062, 0xf703, 0xea7e, 0xfc38, 0x130e, 0x0efa, 0xf5fb, 0xeb49, 0xfdb5, 0x1325,
-0x0d8e, 0xf50e, 0xec26, 0xff20, 0x131e, 0x0c21, 0xf43f, 0xed15, 0x007a, 0x12fa,
-0x0ab6, 0xf38d, 0xee15, 0x01be, 0x12bd, 0x094f, 0xf2f9, 0xef22, 0x02ef, 0x1265,
-0x07f0, 0xf283, 0xf037, 0x0408, 0x11f6, 0x0699, 0xf226, 0xf156, 0x050a, 0x1170,
-0x054b, 0xf1e8, 0xf27a, 0x05f4, 0x10d8, 0x040c, 0xf1c5, 0xf3a3, 0x06c2, 0x102c,
-0x02da, 0xf1bc, 0xf4cc, 0x0779, 0x0f71, 0x01b7, 0xf1cc, 0xf5f5, 0x0815, 0x0ea7,
-0x00a8, 0xf1f4, 0xf719, 0x0899, 0x0dd2, 0xffab, 0xf233, 0xf839, 0x0902, 0x0cf4,
-0xfec0, 0xf288, 0xf950, 0x0952, 0x0c0e, 0xfdec, 0xf2ee, 0xfa5d, 0x0989, 0x0b23,
-0xfd2d, 0xf368, 0xfb62, 0x09a7, 0x0a35, 0xfc85, 0xf3f1, 0xfc58, 0x09af, 0x0946,
-0xfbf2, 0xf488, 0xfd3f, 0x09a1, 0x0859, 0xfb77, 0xf52c, 0xfe17, 0x097d, 0x076f,
-0xfb14, 0xf5d8, 0xfede, 0x0945, 0x068a, 0xfac6, 0xf68d, 0xff93, 0x08fb, 0x05ad,
-0xfa8e, 0xf747, 0x0034, 0x08a1, 0x04da, 0xfa6f, 0xf805, 0x00c2, 0x0836, 0x0410,
-0xfa63, 0xf8c6, 0x013c, 0x07bf, 0x0354, 0xfa6c, 0xf985, 0x01a1, 0x073b, 0x02a4,
-0xfa8a, 0xfa43, 0x01f1, 0x06af, 0x0204, 0xfab9, 0xfafc, 0x022c, 0x0619, 0x0175,
-0xfafa, 0xfbae, 0x0252, 0x057f, 0x00f6, 0xfb4b, 0xfc5a, 0x0263, 0x04e0, 0x008b,
-0xfbaa, 0xfcfa, 0x0262, 0x0440, 0x0032, 0xfc16, 0xfd90, 0x024b, 0x03a0, 0xffec,
-0xfc8c, 0xfe19, 0x0225, 0x0301, 0xffb9, 0xfd0c, 0xfe93, 0x01ea, 0x0267, 0xff9c,
-0xfd95, 0xfefe, 0x01a0, 0x01d3, 0xff90, 0xfe22, 0xff5a, 0x0147, 0x0145, 0xff99,
-0xfeb3, 0xffa1, 0x00e0, 0x00c3, 0xffb6, 0xff46, 0xffd9, 0x006d, 0x004b, 0xffe5,
-0xffda, 0xfffc, 000000, 0xfffe, 000000, 0xffff, 000000, 0xffff, 0xffff, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000 };
diff --git a/1.4/channels/chan_agent.c b/1.4/channels/chan_agent.c
deleted file mode 100644
index ae6d093c7..000000000
--- a/1.4/channels/chan_agent.c
+++ /dev/null
@@ -1,2774 +0,0 @@
-/*
- * 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.
- */
-
-
-/*! \file
- *
- * \brief Implementation of Agents (proxy channel)
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * This file is the implementation of Agents modules.
- * It is a dynamic module that is loaded by Asterisk.
- * \par See also
- * \arg \ref Config_agent
- *
- * \ingroup channel_drivers
- */
-/*** MODULEINFO
- <depend>chan_local</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/signal.h>
-
-#include "asterisk/lock.h"
-#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/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/manager.h"
-#include "asterisk/features.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/astdb.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/monitor.h"
-#include "asterisk/stringfields.h"
-
-static const char tdesc[] = "Call Agent Proxy Channel";
-static const char config[] = "agents.conf";
-
-static const char app[] = "AgentLogin";
-static const char app2[] = "AgentCallbackLogin";
-static const char app3[] = "AgentMonitorOutgoing";
-
-static const char synopsis[] = "Call agent login";
-static const char synopsis2[] = "Call agent callback login";
-static const char synopsis3[] = "Record agent's outgoing call";
-
-static const char descrip[] =
-" AgentLogin([AgentNo][|options]):\n"
-"Asks the agent to login to the system. Always returns -1. While\n"
-"logged in, the agent can receive calls and will hear a 'beep'\n"
-"when a new call comes in. The agent can dump the call by pressing\n"
-"the star key.\n"
-"The option string may contain zero or more of the following characters:\n"
-" 's' -- silent login - do not announce the login ok segment after agent logged in/off\n";
-
-static const char descrip2[] =
-" AgentCallbackLogin([AgentNo][|[options][|[exten]@context]]):\n"
-"Asks the agent to login to the system with callback.\n"
-"The agent's callback extension is called (optionally with the specified\n"
-"context).\n"
-"The option string may contain zero or more of the following characters:\n"
-" 's' -- silent login - do not announce the login ok segment agent logged in/off\n";
-
-static const char descrip3[] =
-" AgentMonitorOutgoing([options]):\n"
-"Tries to figure out the id of the agent who is placing outgoing call based on\n"
-"comparison of the callerid of the current interface and the global variable \n"
-"placed by the AgentCallbackLogin application. That's why it should be used only\n"
-"with the AgentCallbackLogin app. Uses the monitoring functions in chan_agent \n"
-"instead of Monitor application. That have to be configured in the agents.conf file.\n"
-"\nReturn value:\n"
-"Normally the app returns 0 unless the options are passed. Also if the callerid or\n"
-"the agentid are not specified it'll look for n+101 priority.\n"
-"\nOptions:\n"
-" 'd' - make the app return -1 if there is an error condition and there is\n"
-" no extension n+101\n"
-" 'c' - change the CDR so that the source of the call is 'Agent/agent_id'\n"
-" 'n' - don't generate the warnings when there is no callerid or the\n"
-" agentid is not known.\n"
-" It's handy if you want to have one context for agent and non-agent calls.\n";
-
-static const char mandescr_agents[] =
-"Description: Will list info about all possible agents.\n"
-"Variables: NONE\n";
-
-static const char mandescr_agent_logoff[] =
-"Description: Sets an agent as no longer logged in.\n"
-"Variables: (Names marked with * are required)\n"
-" *Agent: Agent ID of the agent to log off\n"
-" Soft: Set to 'true' to not hangup existing calls\n";
-
-static const char mandescr_agent_callback_login[] =
-"Description: Sets an agent as logged in with callback.\n"
-"Variables: (Names marked with * are required)\n"
-" *Agent: Agent ID of the agent to login\n"
-" *Exten: Extension to use for callback\n"
-" Context: Context to use for callback\n"
-" AckCall: Set to 'true' to require an acknowledgement by '#' when agent is called back\n"
-" WrapupTime: the minimum amount of time after disconnecting before the caller can receive a new call\n";
-
-static char moh[80] = "default";
-
-#define AST_MAX_AGENT 80 /*!< Agent ID or Password max length */
-#define AST_MAX_BUF 256
-#define AST_MAX_FILENAME_LEN 256
-
-static const char pa_family[] = "Agents"; /*!< Persistent Agents astdb family */
-#define PA_MAX_LEN 2048 /*!< The maximum length of each persistent member agent database entry */
-
-static int persistent_agents = 0; /*!< queues.conf [general] option */
-static void dump_agents(void);
-
-static ast_group_t group;
-static int autologoff;
-static int wrapuptime;
-static int ackcall;
-static int endcall;
-static int multiplelogin = 1;
-static int autologoffunavail = 0;
-
-static int maxlogintries = 3;
-static char agentgoodbye[AST_MAX_FILENAME_LEN] = "vm-goodbye";
-
-static int recordagentcalls = 0;
-static char recordformat[AST_MAX_BUF] = "";
-static char recordformatext[AST_MAX_BUF] = "";
-static char urlprefix[AST_MAX_BUF] = "";
-static char savecallsin[AST_MAX_BUF] = "";
-static int updatecdr = 0;
-static char beep[AST_MAX_BUF] = "beep";
-
-#define GETAGENTBYCALLERID "AGENTBYCALLERID"
-
-/*! \brief Structure representing an agent. */
-struct agent_pvt {
- ast_mutex_t lock; /*!< Channel private lock */
- int dead; /*!< Poised for destruction? */
- int pending; /*!< Not a real agent -- just pending a match */
- int abouttograb; /*!< About to grab */
- int autologoff; /*!< Auto timeout time */
- int ackcall; /*!< ackcall */
- int deferlogoff; /*!< Defer logoff to hangup */
- time_t loginstart; /*!< When agent first logged in (0 when logged off) */
- time_t start; /*!< When call started */
- struct timeval lastdisc; /*!< When last disconnected */
- int wrapuptime; /*!< Wrapup time in ms */
- ast_group_t group; /*!< Group memberships */
- int acknowledged; /*!< Acknowledged */
- char moh[80]; /*!< Which music on hold */
- char agent[AST_MAX_AGENT]; /*!< Agent ID */
- char password[AST_MAX_AGENT]; /*!< Password for Agent login */
- char name[AST_MAX_AGENT];
- ast_mutex_t app_lock; /**< Synchronization between owning applications */
- volatile pthread_t owning_app; /**< Owning application thread id */
- volatile int app_sleep_cond; /**< Sleep condition for the login app */
- struct ast_channel *owner; /**< Agent */
- char loginchan[80]; /**< channel they logged in from */
- char logincallerid[80]; /**< Caller ID they had when they logged in */
- struct ast_channel *chan; /**< Channel we use */
- AST_LIST_ENTRY(agent_pvt) list; /**< Next Agent in the linked list. */
-};
-
-static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (loaded form agents.conf). */
-
-#define CHECK_FORMATS(ast, p) do { \
- if (p->chan) {\
- if (ast->nativeformats != p->chan->nativeformats) { \
- ast_log(LOG_DEBUG, "Native formats changing from %d to %d\n", ast->nativeformats, p->chan->nativeformats); \
- /* Native formats changed, reset things */ \
- ast->nativeformats = p->chan->nativeformats; \
- ast_log(LOG_DEBUG, "Resetting read to %d and write to %d\n", ast->readformat, ast->writeformat);\
- ast_set_read_format(ast, ast->readformat); \
- ast_set_write_format(ast, ast->writeformat); \
- } \
- if (p->chan->readformat != ast->rawreadformat && !p->chan->generator) \
- ast_set_read_format(p->chan, ast->rawreadformat); \
- if (p->chan->writeformat != ast->rawwriteformat && !p->chan->generator) \
- ast_set_write_format(p->chan, ast->rawwriteformat); \
- } \
-} while(0)
-
-/*! \brief Cleanup moves all the relevant FD's from the 2nd to the first, but retains things
- properly for a timingfd XXX This might need more work if agents were logged in as agents or other
- totally impractical combinations XXX */
-
-#define CLEANUP(ast, p) do { \
- int x; \
- if (p->chan) { \
- for (x=0;x<AST_MAX_FDS;x++) {\
- if (x != AST_TIMING_FD) \
- ast->fds[x] = p->chan->fds[x]; \
- } \
- ast->fds[AST_AGENT_FD] = p->chan->fds[AST_TIMING_FD]; \
- } \
-} while(0)
-
-/*--- Forward declarations */
-static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause);
-static int agent_devicestate(void *data);
-static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand);
-static int agent_digit_begin(struct ast_channel *ast, char digit);
-static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int agent_call(struct ast_channel *ast, char *dest, int timeout);
-static int agent_hangup(struct ast_channel *ast);
-static int agent_answer(struct ast_channel *ast);
-static struct ast_frame *agent_read(struct ast_channel *ast);
-static int agent_write(struct ast_channel *ast, struct ast_frame *f);
-static int agent_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
-static int agent_sendtext(struct ast_channel *ast, const char *text);
-static int agent_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
-static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
-static void set_agentbycallerid(const char *callerid, const char *agent);
-static struct ast_channel* agent_get_base_channel(struct ast_channel *chan);
-static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base);
-
-/*! \brief Channel interface description for PBX integration */
-static const struct ast_channel_tech agent_tech = {
- .type = "Agent",
- .description = tdesc,
- .capabilities = -1,
- .requester = agent_request,
- .devicestate = agent_devicestate,
- .send_digit_begin = agent_digit_begin,
- .send_digit_end = agent_digit_end,
- .call = agent_call,
- .hangup = agent_hangup,
- .answer = agent_answer,
- .read = agent_read,
- .write = agent_write,
- .write_video = agent_write,
- .send_html = agent_sendhtml,
- .send_text = agent_sendtext,
- .exception = agent_read,
- .indicate = agent_indicate,
- .fixup = agent_fixup,
- .bridged_channel = agent_bridgedchannel,
- .get_base_channel = agent_get_base_channel,
- .set_base_channel = agent_set_base_channel,
-};
-
-/*!
- * Adds an agent to the global list of agents.
- *
- * \param agent A string with the username, password and real name of an agent. As defined in agents.conf. Example: "13,169,John Smith"
- * \param pending If it is pending or not.
- * @return The just created agent.
- * \sa agent_pvt, agents.
- */
-static struct agent_pvt *add_agent(char *agent, int pending)
-{
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(agt);
- AST_APP_ARG(password);
- AST_APP_ARG(name);
- );
- char *password = NULL;
- char *name = NULL;
- char *agt = NULL;
- struct agent_pvt *p;
-
- parse = ast_strdupa(agent);
-
- /* Extract username (agt), password and name from agent (args). */
- AST_NONSTANDARD_APP_ARGS(args, parse, ',');
-
- if(args.argc == 0) {
- ast_log(LOG_WARNING, "A blank agent line!\n");
- return NULL;
- }
-
- if(ast_strlen_zero(args.agt) ) {
- ast_log(LOG_WARNING, "An agent line with no agentid!\n");
- return NULL;
- } else
- agt = args.agt;
-
- if(!ast_strlen_zero(args.password)) {
- password = args.password;
- while (*password && *password < 33) password++;
- }
- if(!ast_strlen_zero(args.name)) {
- name = args.name;
- while (*name && *name < 33) name++;
- }
-
- /* Are we searching for the agent here ? To see if it exists already ? */
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (!pending && !strcmp(p->agent, agt))
- break;
- }
- if (!p) {
- // Build the agent.
- if (!(p = ast_calloc(1, sizeof(*p))))
- return NULL;
- ast_copy_string(p->agent, agt, sizeof(p->agent));
- ast_mutex_init(&p->lock);
- ast_mutex_init(&p->app_lock);
- p->owning_app = (pthread_t) -1;
- p->app_sleep_cond = 1;
- p->group = group;
- p->pending = pending;
- AST_LIST_INSERT_TAIL(&agents, p, list);
- }
-
- ast_copy_string(p->password, password ? password : "", sizeof(p->password));
- ast_copy_string(p->name, name ? name : "", sizeof(p->name));
- ast_copy_string(p->moh, moh, sizeof(p->moh));
- p->ackcall = ackcall;
- p->autologoff = autologoff;
-
- /* If someone reduces the wrapuptime and reloads, we want it
- * to change the wrapuptime immediately on all calls */
- if (p->wrapuptime > wrapuptime) {
- struct timeval now = ast_tvnow();
- /* XXX check what is this exactly */
-
- /* We won't be pedantic and check the tv_usec val */
- if (p->lastdisc.tv_sec > (now.tv_sec + wrapuptime/1000)) {
- p->lastdisc.tv_sec = now.tv_sec + wrapuptime/1000;
- p->lastdisc.tv_usec = now.tv_usec;
- }
- }
- p->wrapuptime = wrapuptime;
-
- if (pending)
- p->dead = 1;
- else
- p->dead = 0;
- return p;
-}
-
-/*!
- * Deletes an agent after doing some clean up.
- * Further documentation: How safe is this function ? What state should the agent be to be cleaned.
- * \param p Agent to be deleted.
- * \returns Always 0.
- */
-static int agent_cleanup(struct agent_pvt *p)
-{
- struct ast_channel *chan = p->owner;
- p->owner = NULL;
- chan->tech_pvt = NULL;
- p->app_sleep_cond = 1;
- /* Release ownership of the agent to other threads (presumably running the login app). */
- ast_mutex_unlock(&p->app_lock);
- if (chan)
- ast_channel_free(chan);
- if (p->dead) {
- ast_mutex_destroy(&p->lock);
- ast_mutex_destroy(&p->app_lock);
- free(p);
- }
- return 0;
-}
-
-static int check_availability(struct agent_pvt *newlyavailable, int needlock);
-
-static int agent_answer(struct ast_channel *ast)
-{
- ast_log(LOG_WARNING, "Huh? Agent is being asked to answer?\n");
- return -1;
-}
-
-static int __agent_start_monitoring(struct ast_channel *ast, struct agent_pvt *p, int needlock)
-{
- char tmp[AST_MAX_BUF],tmp2[AST_MAX_BUF], *pointer;
- char filename[AST_MAX_BUF];
- int res = -1;
- if (!p)
- return -1;
- if (!ast->monitor) {
- snprintf(filename, sizeof(filename), "agent-%s-%s",p->agent, ast->uniqueid);
- /* substitute . for - */
- if ((pointer = strchr(filename, '.')))
- *pointer = '-';
- snprintf(tmp, sizeof(tmp), "%s%s", savecallsin, filename);
- ast_monitor_start(ast, recordformat, tmp, needlock);
- ast_monitor_setjoinfiles(ast, 1);
- snprintf(tmp2, sizeof(tmp2), "%s%s.%s", urlprefix, filename, recordformatext);
-#if 0
- ast_verbose("name is %s, link is %s\n",tmp, tmp2);
-#endif
- if (!ast->cdr)
- ast->cdr = ast_cdr_alloc();
- ast_cdr_setuserfield(ast, tmp2);
- res = 0;
- } else
- ast_log(LOG_ERROR, "Recording already started on that call.\n");
- return res;
-}
-
-static int agent_start_monitoring(struct ast_channel *ast, int needlock)
-{
- return __agent_start_monitoring(ast, ast->tech_pvt, needlock);
-}
-
-static struct ast_frame *agent_read(struct ast_channel *ast)
-{
- struct agent_pvt *p = ast->tech_pvt;
- struct ast_frame *f = NULL;
- static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- const char *status;
- ast_mutex_lock(&p->lock);
- CHECK_FORMATS(ast, p);
- if (p->chan) {
- ast_copy_flags(p->chan, ast, AST_FLAG_EXCEPTION);
- p->chan->fdno = (ast->fdno == AST_AGENT_FD) ? AST_TIMING_FD : ast->fdno;
- f = ast_read(p->chan);
- } else
- f = &ast_null_frame;
- if (!f) {
- /* If there's a channel, hang it up (if it's on a callback) make it NULL */
- if (p->chan) {
- p->chan->_bridge = NULL;
- /* Note that we don't hangup if it's not a callback because Asterisk will do it
- for us when the PBX instance that called login finishes */
- if (!ast_strlen_zero(p->loginchan)) {
- if (p->chan)
- ast_log(LOG_DEBUG, "Bridge on '%s' being cleared (2)\n", p->chan->name);
-
- status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
- if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
- long logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- ast_log(LOG_NOTICE, "Agent read: '%s' is not available now, auto logoff\n", p->name);
- agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail");
- }
- ast_hangup(p->chan);
- if (p->wrapuptime && p->acknowledged)
- p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
- }
- p->chan = NULL;
- p->acknowledged = 0;
- }
- } else {
- /* if acknowledgement is not required, and the channel is up, we may have missed
- an AST_CONTROL_ANSWER (if there was one), so mark the call acknowledged anyway */
- if (!p->ackcall && !p->acknowledged && p->chan && (p->chan->_state == AST_STATE_UP))
- p->acknowledged = 1;
- switch (f->frametype) {
- case AST_FRAME_CONTROL:
- if (f->subclass == AST_CONTROL_ANSWER) {
- if (p->ackcall) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s answered, waiting for '#' to acknowledge\n", p->chan->name);
- /* Don't pass answer along */
- ast_frfree(f);
- f = &ast_null_frame;
- } else {
- p->acknowledged = 1;
- /* Use the builtin answer frame for the
- recording start check below. */
- ast_frfree(f);
- f = &answer_frame;
- }
- }
- break;
- case AST_FRAME_DTMF_BEGIN:
- /*ignore DTMF begin's as it can cause issues with queue announce files*/
- if((!p->acknowledged && f->subclass == '#') || (f->subclass == '*' && endcall)){
- ast_frfree(f);
- f = &ast_null_frame;
- }
- break;
- case AST_FRAME_DTMF_END:
- if (!p->acknowledged && (f->subclass == '#')) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s acknowledged\n", p->chan->name);
- p->acknowledged = 1;
- ast_frfree(f);
- f = &answer_frame;
- } else if (f->subclass == '*' && endcall) {
- /* terminates call */
- ast_frfree(f);
- f = NULL;
- }
- break;
- case AST_FRAME_VOICE:
- case AST_FRAME_VIDEO:
- /* don't pass voice or video until the call is acknowledged */
- if (!p->acknowledged) {
- ast_frfree(f);
- f = &ast_null_frame;
- }
- default:
- /* pass everything else on through */
- break;
- }
- }
-
- CLEANUP(ast,p);
- if (p->chan && !p->chan->_bridge) {
- if (strcasecmp(p->chan->tech->type, "Local")) {
- p->chan->_bridge = ast;
- if (p->chan)
- ast_log(LOG_DEBUG, "Bridge on '%s' being set to '%s' (3)\n", p->chan->name, p->chan->_bridge->name);
- }
- }
- ast_mutex_unlock(&p->lock);
- if (recordagentcalls && f == &answer_frame)
- agent_start_monitoring(ast,0);
- return f;
-}
-
-static int agent_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
-{
- struct agent_pvt *p = ast->tech_pvt;
- int res = -1;
- ast_mutex_lock(&p->lock);
- if (p->chan)
- res = ast_channel_sendhtml(p->chan, subclass, data, datalen);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int agent_sendtext(struct ast_channel *ast, const char *text)
-{
- struct agent_pvt *p = ast->tech_pvt;
- int res = -1;
- ast_mutex_lock(&p->lock);
- if (p->chan)
- res = ast_sendtext(p->chan, text);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int agent_write(struct ast_channel *ast, struct ast_frame *f)
-{
- struct agent_pvt *p = ast->tech_pvt;
- int res = -1;
- CHECK_FORMATS(ast, p);
- ast_mutex_lock(&p->lock);
- if (!p->chan)
- res = 0;
- else {
- if ((f->frametype != AST_FRAME_VOICE) ||
- (f->frametype != AST_FRAME_VIDEO) ||
- (f->subclass == p->chan->writeformat)) {
- res = ast_write(p->chan, f);
- } else {
- ast_log(LOG_DEBUG, "Dropping one incompatible %s frame on '%s' to '%s'\n",
- f->frametype == AST_FRAME_VOICE ? "audio" : "video",
- ast->name, p->chan->name);
- res = 0;
- }
- }
- CLEANUP(ast, p);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct agent_pvt *p = newchan->tech_pvt;
- ast_mutex_lock(&p->lock);
- if (p->owner != oldchan) {
- ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- p->owner = newchan;
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int agent_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
-{
- struct agent_pvt *p = ast->tech_pvt;
- int res = -1;
- ast_mutex_lock(&p->lock);
- if (p->chan)
- res = p->chan->tech->indicate ? p->chan->tech->indicate(p->chan, condition, data, datalen) : -1;
- else
- res = 0;
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int agent_digit_begin(struct ast_channel *ast, char digit)
-{
- struct agent_pvt *p = ast->tech_pvt;
- ast_mutex_lock(&p->lock);
- if (p->chan) {
- ast_senddigit_begin(p->chan, digit);
- }
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct agent_pvt *p = ast->tech_pvt;
- ast_mutex_lock(&p->lock);
- if (p->chan) {
- ast_senddigit_end(p->chan, digit, duration);
- }
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int agent_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct agent_pvt *p = ast->tech_pvt;
- int res = -1;
- int newstate=0;
- ast_mutex_lock(&p->lock);
- p->acknowledged = 0;
- if (!p->chan) {
- if (p->pending) {
- ast_log(LOG_DEBUG, "Pretending to dial on pending agent\n");
- newstate = AST_STATE_DIALING;
- res = 0;
- } else {
- ast_log(LOG_NOTICE, "Whoa, they hung up between alloc and call... what are the odds of that?\n");
- res = -1;
- }
- ast_mutex_unlock(&p->lock);
- if (newstate)
- ast_setstate(ast, newstate);
- return res;
- } else if (!ast_strlen_zero(p->loginchan)) {
- time(&p->start);
- /* Call on this agent */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "outgoing agentcall, to agent '%s', on '%s'\n", p->agent, p->chan->name);
- ast_set_callerid(p->chan,
- ast->cid.cid_num, ast->cid.cid_name, NULL);
- ast_channel_inherit_variables(ast, p->chan);
- res = ast_call(p->chan, p->loginchan, 0);
- CLEANUP(ast,p);
- ast_mutex_unlock(&p->lock);
- return res;
- }
- ast_verbose( VERBOSE_PREFIX_3 "agent_call, call to agent '%s' call on '%s'\n", p->agent, p->chan->name);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Playing beep, lang '%s'\n", p->chan->language);
- res = ast_streamfile(p->chan, beep, p->chan->language);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Played beep, result '%d'\n", res);
- if (!res) {
- res = ast_waitstream(p->chan, "");
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Waited for stream, result '%d'\n", res);
- }
- if (!res) {
- res = ast_set_read_format(p->chan, ast_best_codec(p->chan->nativeformats));
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Set read format, result '%d'\n", res);
- if (res)
- ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats)));
- } else {
- /* Agent hung-up */
- p->chan = NULL;
- }
-
- if (!res) {
- res = ast_set_write_format(p->chan, ast_best_codec(p->chan->nativeformats));
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Set write format, result '%d'\n", res);
- if (res)
- ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats)));
- }
- if(!res) {
- /* Call is immediately up, or might need ack */
- if (p->ackcall > 1)
- newstate = AST_STATE_RINGING;
- else {
- newstate = AST_STATE_UP;
- if (recordagentcalls)
- agent_start_monitoring(ast, 0);
- p->acknowledged = 1;
- }
- res = 0;
- }
- CLEANUP(ast, p);
- ast_mutex_unlock(&p->lock);
- if (newstate)
- ast_setstate(ast, newstate);
- return res;
-}
-
-/*! \brief store/clear the global variable that stores agentid based on the callerid */
-static void set_agentbycallerid(const char *callerid, const char *agent)
-{
- char buf[AST_MAX_BUF];
-
- /* if there is no Caller ID, nothing to do */
- if (ast_strlen_zero(callerid))
- return;
-
- snprintf(buf, sizeof(buf), "%s_%s", GETAGENTBYCALLERID, callerid);
- pbx_builtin_setvar_helper(NULL, buf, agent);
-}
-
-/*! \brief return the channel or base channel if one exists. This function assumes the channel it is called on is already locked */
-struct ast_channel* agent_get_base_channel(struct ast_channel *chan)
-{
- struct agent_pvt *p = NULL;
- struct ast_channel *base = chan;
-
- /* chan is locked by the calling function */
- if (!chan || !chan->tech_pvt) {
- ast_log(LOG_ERROR, "whoa, you need a channel (0x%ld) with a tech_pvt (0x%ld) to get a base channel.\n", (long)chan, (chan)?(long)chan->tech_pvt:(long)NULL);
- return NULL;
- }
- p = chan->tech_pvt;
- if (p->chan)
- base = p->chan;
- return base;
-}
-
-int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base)
-{
- struct agent_pvt *p = NULL;
-
- if (!chan || !base) {
- ast_log(LOG_ERROR, "whoa, you need a channel (0x%ld) and a base channel (0x%ld) for setting.\n", (long)chan, (long)base);
- return -1;
- }
- p = chan->tech_pvt;
- if (!p) {
- ast_log(LOG_ERROR, "whoa, channel %s is missing his tech_pvt structure!!.\n", chan->name);
- return -1;
- }
- p->chan = base;
- return 0;
-}
-
-static int agent_hangup(struct ast_channel *ast)
-{
- struct agent_pvt *p = ast->tech_pvt;
- int howlong = 0;
- const char *status;
- ast_mutex_lock(&p->lock);
- p->owner = NULL;
- ast->tech_pvt = NULL;
- p->app_sleep_cond = 1;
- p->acknowledged = 0;
-
- /* if they really are hung up then set start to 0 so the test
- * later if we're called on an already downed channel
- * doesn't cause an agent to be logged out like when
- * agent_request() is followed immediately by agent_hangup()
- * as in apps/app_chanisavail.c:chanavail_exec()
- */
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Hangup called for state %s\n", ast_state2str(ast->_state));
- if (p->start && (ast->_state != AST_STATE_UP)) {
- howlong = time(NULL) - p->start;
- p->start = 0;
- } else if (ast->_state == AST_STATE_RESERVED)
- howlong = 0;
- else
- p->start = 0;
- if (p->chan) {
- p->chan->_bridge = NULL;
- /* If they're dead, go ahead and hang up on the agent now */
- if (!ast_strlen_zero(p->loginchan)) {
- /* Store last disconnect time */
- if (p->wrapuptime)
- p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
- else
- p->lastdisc = ast_tv(0,0);
- if (p->chan) {
- status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
- if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
- long logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- ast_log(LOG_NOTICE, "Agent hangup: '%s' is not available now, auto logoff\n", p->name);
- agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail");
- }
- /* Recognize the hangup and pass it along immediately */
- ast_hangup(p->chan);
- p->chan = NULL;
- }
- ast_log(LOG_DEBUG, "Hungup, howlong is %d, autologoff is %d\n", howlong, p->autologoff);
- if ((p->deferlogoff) || (howlong && p->autologoff && (howlong > p->autologoff))) {
- long logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- if (!p->deferlogoff)
- ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
- p->deferlogoff = 0;
- agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Autologoff");
- if (persistent_agents)
- dump_agents();
- }
- } else if (p->dead) {
- ast_channel_lock(p->chan);
- ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(p->chan);
- } else if (p->loginstart) {
- ast_channel_lock(p->chan);
- ast_indicate_data(p->chan, AST_CONTROL_HOLD,
- S_OR(p->moh, NULL),
- !ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
- ast_channel_unlock(p->chan);
- }
- }
- ast_mutex_unlock(&p->lock);
-
- /* Only register a device state change if the agent is still logged in */
- if (!p->loginstart) {
- p->loginchan[0] = '\0';
- p->logincallerid[0] = '\0';
- if (persistent_agents)
- dump_agents();
- } else {
- ast_device_state_changed("Agent/%s", p->agent);
- }
-
- if (p->pending) {
- AST_LIST_LOCK(&agents);
- AST_LIST_REMOVE(&agents, p, list);
- AST_LIST_UNLOCK(&agents);
- }
- if (p->abouttograb) {
- /* Let the "about to grab" thread know this isn't valid anymore, and let it
- kill it later */
- p->abouttograb = 0;
- } else if (p->dead) {
- ast_mutex_destroy(&p->lock);
- ast_mutex_destroy(&p->app_lock);
- free(p);
- } else {
- if (p->chan) {
- /* Not dead -- check availability now */
- ast_mutex_lock(&p->lock);
- /* Store last disconnect time */
- p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
- ast_mutex_unlock(&p->lock);
- }
- /* Release ownership of the agent to other threads (presumably running the login app). */
- if (ast_strlen_zero(p->loginchan))
- ast_mutex_unlock(&p->app_lock);
- }
- return 0;
-}
-
-static int agent_cont_sleep( void *data )
-{
- struct agent_pvt *p;
- int res;
-
- p = (struct agent_pvt *)data;
-
- ast_mutex_lock(&p->lock);
- res = p->app_sleep_cond;
- if (p->lastdisc.tv_sec) {
- if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0)
- res = 1;
- }
- ast_mutex_unlock(&p->lock);
-
- if(option_debug > 4 && !res )
- ast_log(LOG_DEBUG, "agent_cont_sleep() returning %d\n", res );
-
- return res;
-}
-
-static int agent_ack_sleep(void *data)
-{
- struct agent_pvt *p;
- int res=0;
- int to = 1000;
- struct ast_frame *f;
-
- /* Wait a second and look for something */
-
- p = (struct agent_pvt *) data;
- if (!p->chan)
- return -1;
-
- for(;;) {
- to = ast_waitfor(p->chan, to);
- if (to < 0)
- return -1;
- if (!to)
- return 0;
- f = ast_read(p->chan);
- if (!f)
- return -1;
- if (f->frametype == AST_FRAME_DTMF)
- res = f->subclass;
- else
- res = 0;
- ast_frfree(f);
- ast_mutex_lock(&p->lock);
- if (!p->app_sleep_cond) {
- ast_mutex_unlock(&p->lock);
- return 0;
- } else if (res == '#') {
- ast_mutex_unlock(&p->lock);
- return 1;
- }
- ast_mutex_unlock(&p->lock);
- res = 0;
- }
- return res;
-}
-
-static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
-{
- struct agent_pvt *p = bridge->tech_pvt;
- struct ast_channel *ret = NULL;
-
- if (p) {
- if (chan == p->chan)
- ret = bridge->_bridge;
- else if (chan == bridge->_bridge)
- ret = p->chan;
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Asked for bridged channel on '%s'/'%s', returning '%s'\n", chan->name, bridge->name, ret ? ret->name : "<none>");
- return ret;
-}
-
-/*! \brief Create new agent channel */
-static struct ast_channel *agent_new(struct agent_pvt *p, int state)
-{
- struct ast_channel *tmp;
-#if 0
- if (!p->chan) {
- ast_log(LOG_WARNING, "No channel? :(\n");
- return NULL;
- }
-#endif
- if (p->pending)
- tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", 0, "Agent/P%s-%d", p->agent, ast_random() & 0xffff);
- else
- tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", 0, "Agent/%s", p->agent);
- if (!tmp) {
- ast_log(LOG_WARNING, "Unable to allocate agent channel structure\n");
- return NULL;
- }
-
- tmp->tech = &agent_tech;
- if (p->chan) {
- tmp->nativeformats = p->chan->nativeformats;
- tmp->writeformat = p->chan->writeformat;
- tmp->rawwriteformat = p->chan->writeformat;
- tmp->readformat = p->chan->readformat;
- tmp->rawreadformat = p->chan->readformat;
- ast_string_field_set(tmp, language, p->chan->language);
- ast_copy_string(tmp->context, p->chan->context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, p->chan->exten, sizeof(tmp->exten));
- /* XXX Is this really all we copy form the originating channel?? */
- } else {
- tmp->nativeformats = AST_FORMAT_SLINEAR;
- tmp->writeformat = AST_FORMAT_SLINEAR;
- tmp->rawwriteformat = AST_FORMAT_SLINEAR;
- tmp->readformat = AST_FORMAT_SLINEAR;
- tmp->rawreadformat = AST_FORMAT_SLINEAR;
- }
- /* Safe, agentlock already held */
- tmp->tech_pvt = p;
- p->owner = tmp;
- /* XXX: this needs fixing */
-#if 0
- ast_atomic_fetchadd_int(&__mod_desc->usecnt, +1);
-#endif
- ast_update_use_count();
- tmp->priority = 1;
- /* Wake up and wait for other applications (by definition the login app)
- * to release this channel). Takes ownership of the agent channel
- * to this thread only.
- * For signalling the other thread, ast_queue_frame is used until we
- * can safely use signals for this purpose. The pselect() needs to be
- * implemented in the kernel for this.
- */
- p->app_sleep_cond = 0;
- if(ast_strlen_zero(p->loginchan) && ast_mutex_trylock(&p->app_lock)) {
- if (p->chan) {
- ast_queue_frame(p->chan, &ast_null_frame);
- ast_mutex_unlock(&p->lock); /* For other thread to read the condition. */
- ast_mutex_lock(&p->app_lock);
- ast_mutex_lock(&p->lock);
- } else {
- ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
- p->owner = NULL;
- tmp->tech_pvt = NULL;
- p->app_sleep_cond = 1;
- ast_channel_free( tmp );
- ast_mutex_unlock(&p->lock); /* For other thread to read the condition. */
- ast_mutex_unlock(&p->app_lock);
- return NULL;
- }
- } else if (!ast_strlen_zero(p->loginchan)) {
- if (p->chan)
- ast_queue_frame(p->chan, &ast_null_frame);
- if (!p->chan) {
- ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
- p->owner = NULL;
- tmp->tech_pvt = NULL;
- p->app_sleep_cond = 1;
- ast_channel_free( tmp );
- ast_mutex_unlock(&p->lock); /* For other thread to read the condition. */
- return NULL;
- }
- }
- if (p->chan)
- ast_indicate(p->chan, AST_CONTROL_UNHOLD);
- p->owning_app = pthread_self();
- /* After the above step, there should not be any blockers. */
- if (p->chan) {
- if (ast_test_flag(p->chan, AST_FLAG_BLOCKING)) {
- ast_log( LOG_ERROR, "A blocker exists after agent channel ownership acquired\n" );
- CRASH;
- }
- }
- return tmp;
-}
-
-
-/*!
- * Read configuration data. The file named agents.conf.
- *
- * \returns Always 0, or so it seems.
- */
-static int read_agent_config(void)
-{
- struct ast_config *cfg;
- struct ast_config *ucfg;
- struct ast_variable *v;
- struct agent_pvt *p;
- const char *general_val;
- const char *catname;
- const char *hasagent;
- int genhasagent;
-
- group = 0;
- autologoff = 0;
- wrapuptime = 0;
- ackcall = 0;
- endcall = 1;
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_NOTICE, "No agent configuration found -- agent support disabled\n");
- return 0;
- }
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- p->dead = 1;
- }
- strcpy(moh, "default");
- /* set the default recording values */
- recordagentcalls = 0;
- strcpy(recordformat, "wav");
- strcpy(recordformatext, "wav");
- urlprefix[0] = '\0';
- savecallsin[0] = '\0';
-
- /* Read in [general] section for persistence */
- if ((general_val = ast_variable_retrieve(cfg, "general", "persistentagents")))
- persistent_agents = ast_true(general_val);
- multiplelogin = ast_true(ast_variable_retrieve(cfg, "general", "multiplelogin"));
-
- /* Read in the [agents] section */
- v = ast_variable_browse(cfg, "agents");
- while(v) {
- /* Create the interface list */
- if (!strcasecmp(v->name, "agent")) {
- add_agent(v->value, 0);
- } else if (!strcasecmp(v->name, "group")) {
- group = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "autologoff")) {
- autologoff = atoi(v->value);
- if (autologoff < 0)
- autologoff = 0;
- } else if (!strcasecmp(v->name, "ackcall")) {
- if (!strcasecmp(v->value, "always"))
- ackcall = 2;
- else if (ast_true(v->value))
- ackcall = 1;
- else
- ackcall = 0;
- } else if (!strcasecmp(v->name, "endcall")) {
- endcall = ast_true(v->value);
- } else if (!strcasecmp(v->name, "wrapuptime")) {
- wrapuptime = atoi(v->value);
- if (wrapuptime < 0)
- wrapuptime = 0;
- } else if (!strcasecmp(v->name, "maxlogintries") && !ast_strlen_zero(v->value)) {
- maxlogintries = atoi(v->value);
- if (maxlogintries < 0)
- maxlogintries = 0;
- } else if (!strcasecmp(v->name, "goodbye") && !ast_strlen_zero(v->value)) {
- strcpy(agentgoodbye,v->value);
- } else if (!strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(moh, v->value, sizeof(moh));
- } else if (!strcasecmp(v->name, "updatecdr")) {
- if (ast_true(v->value))
- updatecdr = 1;
- else
- updatecdr = 0;
- } else if (!strcasecmp(v->name, "autologoffunavail")) {
- if (ast_true(v->value))
- autologoffunavail = 1;
- else
- autologoffunavail = 0;
- } else if (!strcasecmp(v->name, "recordagentcalls")) {
- recordagentcalls = ast_true(v->value);
- } else if (!strcasecmp(v->name, "recordformat")) {
- ast_copy_string(recordformat, v->value, sizeof(recordformat));
- if (!strcasecmp(v->value, "wav49"))
- strcpy(recordformatext, "WAV");
- else
- ast_copy_string(recordformatext, v->value, sizeof(recordformatext));
- } else if (!strcasecmp(v->name, "urlprefix")) {
- ast_copy_string(urlprefix, v->value, sizeof(urlprefix));
- if (urlprefix[strlen(urlprefix) - 1] != '/')
- strncat(urlprefix, "/", sizeof(urlprefix) - strlen(urlprefix) - 1);
- } else if (!strcasecmp(v->name, "savecallsin")) {
- if (v->value[0] == '/')
- ast_copy_string(savecallsin, v->value, sizeof(savecallsin));
- else
- snprintf(savecallsin, sizeof(savecallsin) - 2, "/%s", v->value);
- if (savecallsin[strlen(savecallsin) - 1] != '/')
- strncat(savecallsin, "/", sizeof(savecallsin) - strlen(savecallsin) - 1);
- } else if (!strcasecmp(v->name, "custom_beep")) {
- ast_copy_string(beep, v->value, sizeof(beep));
- }
- v = v->next;
- }
- if ((ucfg = ast_config_load("users.conf"))) {
- genhasagent = ast_true(ast_variable_retrieve(ucfg, "general", "hasagent"));
- catname = ast_category_browse(ucfg, NULL);
- while(catname) {
- if (strcasecmp(catname, "general")) {
- hasagent = ast_variable_retrieve(ucfg, catname, "hasagent");
- if (ast_true(hasagent) || (!hasagent && genhasagent)) {
- char tmp[256];
- const char *fullname = ast_variable_retrieve(ucfg, catname, "fullname");
- const char *secret = ast_variable_retrieve(ucfg, catname, "secret");
- if (!fullname)
- fullname = "";
- if (!secret)
- secret = "";
- snprintf(tmp, sizeof(tmp), "%s,%s,%s", catname, secret,fullname);
- add_agent(tmp, 0);
- }
- }
- catname = ast_category_browse(ucfg, catname);
- }
- ast_config_destroy(ucfg);
- }
- AST_LIST_TRAVERSE_SAFE_BEGIN(&agents, p, list) {
- if (p->dead) {
- AST_LIST_REMOVE_CURRENT(&agents, list);
- /* Destroy if appropriate */
- if (!p->owner) {
- if (!p->chan) {
- ast_mutex_destroy(&p->lock);
- ast_mutex_destroy(&p->app_lock);
- free(p);
- } else {
- /* Cause them to hang up */
- ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
- }
- }
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&agents);
- ast_config_destroy(cfg);
- return 1;
-}
-
-static int check_availability(struct agent_pvt *newlyavailable, int needlock)
-{
- struct ast_channel *chan=NULL, *parent=NULL;
- struct agent_pvt *p;
- int res;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Checking availability of '%s'\n", newlyavailable->agent);
- if (needlock)
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (p == newlyavailable) {
- continue;
- }
- ast_mutex_lock(&p->lock);
- if (!p->abouttograb && p->pending && ((p->group && (newlyavailable->group & p->group)) || !strcmp(p->agent, newlyavailable->agent))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Call '%s' looks like a winner for agent '%s'\n", p->owner->name, newlyavailable->agent);
- /* We found a pending call, time to merge */
- chan = agent_new(newlyavailable, AST_STATE_DOWN);
- parent = p->owner;
- p->abouttograb = 1;
- ast_mutex_unlock(&p->lock);
- break;
- }
- ast_mutex_unlock(&p->lock);
- }
- if (needlock)
- AST_LIST_UNLOCK(&agents);
- if (parent && chan) {
- if (newlyavailable->ackcall > 1) {
- /* Don't do beep here */
- res = 0;
- } else {
- if (option_debug > 2)
- ast_log( LOG_DEBUG, "Playing beep, lang '%s'\n", newlyavailable->chan->language);
- res = ast_streamfile(newlyavailable->chan, beep, newlyavailable->chan->language);
- if (option_debug > 2)
- ast_log( LOG_DEBUG, "Played beep, result '%d'\n", res);
- if (!res) {
- res = ast_waitstream(newlyavailable->chan, "");
- ast_log( LOG_DEBUG, "Waited for stream, result '%d'\n", res);
- }
- }
- if (!res) {
- /* Note -- parent may have disappeared */
- if (p->abouttograb) {
- newlyavailable->acknowledged = 1;
- /* Safe -- agent lock already held */
- ast_setstate(parent, AST_STATE_UP);
- ast_setstate(chan, AST_STATE_UP);
- ast_copy_string(parent->context, chan->context, sizeof(parent->context));
- /* Go ahead and mark the channel as a zombie so that masquerade will
- destroy it for us, and we need not call ast_hangup */
- ast_mutex_lock(&parent->lock);
- ast_set_flag(chan, AST_FLAG_ZOMBIE);
- ast_channel_masquerade(parent, chan);
- ast_mutex_unlock(&parent->lock);
- p->abouttograb = 0;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Sneaky, parent disappeared in the mean time...\n");
- agent_cleanup(newlyavailable);
- }
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ugh... Agent hung up at exactly the wrong time\n");
- agent_cleanup(newlyavailable);
- }
- }
- return 0;
-}
-
-static int check_beep(struct agent_pvt *newlyavailable, int needlock)
-{
- struct agent_pvt *p;
- int res=0;
-
- ast_log(LOG_DEBUG, "Checking beep availability of '%s'\n", newlyavailable->agent);
- if (needlock)
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (p == newlyavailable) {
- continue;
- }
- ast_mutex_lock(&p->lock);
- if (!p->abouttograb && p->pending && ((p->group && (newlyavailable->group & p->group)) || !strcmp(p->agent, newlyavailable->agent))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Call '%s' looks like a would-be winner for agent '%s'\n", p->owner->name, newlyavailable->agent);
- ast_mutex_unlock(&p->lock);
- break;
- }
- ast_mutex_unlock(&p->lock);
- }
- if (needlock)
- AST_LIST_UNLOCK(&agents);
- if (p) {
- ast_mutex_unlock(&newlyavailable->lock);
- if (option_debug > 2)
- ast_log( LOG_DEBUG, "Playing beep, lang '%s'\n", newlyavailable->chan->language);
- res = ast_streamfile(newlyavailable->chan, beep, newlyavailable->chan->language);
- if (option_debug > 2)
- ast_log( LOG_DEBUG, "Played beep, result '%d'\n", res);
- if (!res) {
- res = ast_waitstream(newlyavailable->chan, "");
- if (option_debug)
- ast_log( LOG_DEBUG, "Waited for stream, result '%d'\n", res);
- }
- ast_mutex_lock(&newlyavailable->lock);
- }
- return res;
-}
-
-/* return 1 if multiple login is fine, 0 if it is not and we find a match, -1 if multiplelogin is not allowed and we don't find a match. */
-static int allow_multiple_login(char *chan, char *context)
-{
- struct agent_pvt *p;
- char loginchan[80];
-
- if(multiplelogin)
- return 1;
- if(!chan)
- return 0;
-
- snprintf(loginchan, sizeof(loginchan), "%s@%s", chan, S_OR(context, "default"));
-
- AST_LIST_TRAVERSE(&agents, p, list) {
- if(!strcasecmp(chan, p->loginchan))
- return 0;
- }
- return -1;
-}
-
-/*! \brief Part of the Asterisk PBX interface */
-static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause)
-{
- struct agent_pvt *p;
- struct ast_channel *chan = NULL;
- char *s;
- ast_group_t groupmatch;
- int groupoff;
- int waitforagent=0;
- int hasagent = 0;
- struct timeval tv;
-
- s = data;
- if ((s[0] == '@') && (sscanf(s + 1, "%d", &groupoff) == 1)) {
- groupmatch = (1 << groupoff);
- } else if ((s[0] == ':') && (sscanf(s + 1, "%d", &groupoff) == 1)) {
- groupmatch = (1 << groupoff);
- waitforagent = 1;
- } else
- groupmatch = 0;
-
- /* Check actual logged in agents first */
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- ast_mutex_lock(&p->lock);
- if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent)) &&
- ast_strlen_zero(p->loginchan)) {
- if (p->chan)
- hasagent++;
- tv = ast_tvnow();
- if (!p->lastdisc.tv_sec || (tv.tv_sec >= p->lastdisc.tv_sec)) {
- p->lastdisc = ast_tv(0, 0);
- /* Agent must be registered, but not have any active call, and not be in a waiting state */
- if (!p->owner && p->chan) {
- /* Fixed agent */
- chan = agent_new(p, AST_STATE_DOWN);
- }
- if (chan) {
- ast_mutex_unlock(&p->lock);
- break;
- }
- }
- }
- ast_mutex_unlock(&p->lock);
- }
- if (!p) {
- AST_LIST_TRAVERSE(&agents, p, list) {
- ast_mutex_lock(&p->lock);
- if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent))) {
- if (p->chan || !ast_strlen_zero(p->loginchan))
- hasagent++;
- tv = ast_tvnow();
-#if 0
- ast_log(LOG_NOTICE, "Time now: %ld, Time of lastdisc: %ld\n", tv.tv_sec, p->lastdisc.tv_sec);
-#endif
- if (!p->lastdisc.tv_sec || (tv.tv_sec >= p->lastdisc.tv_sec)) {
- p->lastdisc = ast_tv(0, 0);
- /* Agent must be registered, but not have any active call, and not be in a waiting state */
- if (!p->owner && p->chan) {
- /* Could still get a fixed agent */
- chan = agent_new(p, AST_STATE_DOWN);
- } else if (!p->owner && !ast_strlen_zero(p->loginchan)) {
- /* Adjustable agent */
- p->chan = ast_request("Local", format, p->loginchan, cause);
- if (p->chan)
- chan = agent_new(p, AST_STATE_DOWN);
- }
- if (chan) {
- ast_mutex_unlock(&p->lock);
- break;
- }
- }
- }
- ast_mutex_unlock(&p->lock);
- }
- }
-
- if (!chan && waitforagent) {
- /* No agent available -- but we're requesting to wait for one.
- Allocate a place holder */
- if (hasagent) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Creating place holder for '%s'\n", s);
- p = add_agent(data, 1);
- p->group = groupmatch;
- chan = agent_new(p, AST_STATE_DOWN);
- if (!chan)
- ast_log(LOG_WARNING, "Weird... Fix this to drop the unused pending agent\n");
- } else
- ast_log(LOG_DEBUG, "Not creating place holder for '%s' since nobody logged in\n", s);
- }
- *cause = hasagent ? AST_CAUSE_BUSY : AST_CAUSE_UNREGISTERED;
- AST_LIST_UNLOCK(&agents);
- return chan;
-}
-
-static force_inline int powerof(unsigned int d)
-{
- int x = ffs(d);
-
- if (x)
- return x - 1;
-
- return 0;
-}
-
-/*!
- * Lists agents and their status to the Manager API.
- * It is registered on load_module() and it gets called by the manager backend.
- * \param s
- * \param m
- * \returns
- * \sa action_agent_logoff(), action_agent_callback_login(), load_module().
- */
-static int action_agents(struct mansession *s, const struct message *m)
-{
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
- char chanbuf[256];
- struct agent_pvt *p;
- char *username = NULL;
- char *loginChan = NULL;
- char *talkingtoChan = NULL;
- char *status = NULL;
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
- astman_send_ack(s, m, "Agents will follow");
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- ast_mutex_lock(&p->lock);
-
- /* Status Values:
- AGENT_LOGGEDOFF - Agent isn't logged in
- AGENT_IDLE - Agent is logged in, and waiting for call
- AGENT_ONCALL - Agent is logged in, and on a call
- AGENT_UNKNOWN - Don't know anything about agent. Shouldn't ever get this. */
-
- username = S_OR(p->name, "None");
-
- /* Set a default status. It 'should' get changed. */
- status = "AGENT_UNKNOWN";
-
- if (!ast_strlen_zero(p->loginchan) && !p->chan) {
- loginChan = p->loginchan;
- talkingtoChan = "n/a";
- status = "AGENT_IDLE";
- if (p->acknowledged) {
- snprintf(chanbuf, sizeof(chanbuf), " %s (Confirmed)", p->loginchan);
- loginChan = chanbuf;
- }
- } else if (p->chan) {
- loginChan = ast_strdupa(p->chan->name);
- if (p->owner && p->owner->_bridge) {
- if (ast_bridged_channel(p->owner)) {
- talkingtoChan = ast_strdupa(S_OR(ast_bridged_channel(p->owner)->cid.cid_num, ""));
- } else {
- talkingtoChan = "n/a";
- }
- status = "AGENT_ONCALL";
- } else {
- talkingtoChan = "n/a";
- status = "AGENT_IDLE";
- }
- } else {
- loginChan = "n/a";
- talkingtoChan = "n/a";
- status = "AGENT_LOGGEDOFF";
- }
-
- astman_append(s, "Event: Agents\r\n"
- "Agent: %s\r\n"
- "Name: %s\r\n"
- "Status: %s\r\n"
- "LoggedInChan: %s\r\n"
- "LoggedInTime: %d\r\n"
- "TalkingTo: %s\r\n"
- "%s"
- "\r\n",
- p->agent, username, status, loginChan, (int)p->loginstart, talkingtoChan, idText);
- ast_mutex_unlock(&p->lock);
- }
- AST_LIST_UNLOCK(&agents);
- astman_append(s, "Event: AgentsComplete\r\n"
- "%s"
- "\r\n",idText);
- return 0;
-}
-
-static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand)
-{
- char *tmp = NULL;
- char agent[AST_MAX_AGENT];
-
- if (!ast_strlen_zero(logcommand))
- tmp = logcommand;
- else
- tmp = ast_strdupa("");
-
- snprintf(agent, sizeof(agent), "Agent/%s", p->agent);
-
- if (!ast_strlen_zero(uniqueid)) {
- manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogoff",
- "Agent: %s\r\n"
- "Reason: %s\r\n"
- "Loginchan: %s\r\n"
- "Logintime: %ld\r\n"
- "Uniqueid: %s\r\n",
- p->agent, tmp, loginchan, logintime, uniqueid);
- } else {
- manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogoff",
- "Agent: %s\r\n"
- "Reason: %s\r\n"
- "Loginchan: %s\r\n"
- "Logintime: %ld\r\n",
- p->agent, tmp, loginchan, logintime);
- }
-
- ast_queue_log("NONE", ast_strlen_zero(uniqueid) ? "NONE" : uniqueid, agent, "AGENTCALLBACKLOGOFF", "%s|%ld|%s", loginchan, logintime, tmp);
- set_agentbycallerid(p->logincallerid, NULL);
- p->loginchan[0] ='\0';
- p->logincallerid[0] = '\0';
- ast_device_state_changed("Agent/%s", p->agent);
- if (persistent_agents)
- dump_agents();
-
-}
-
-static int agent_logoff(const char *agent, int soft)
-{
- struct agent_pvt *p;
- long logintime;
- int ret = -1; /* Return -1 if no agent if found */
-
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (!strcasecmp(p->agent, agent)) {
- ret = 0;
- if (p->owner || p->chan) {
- if (!soft) {
- ast_mutex_lock(&p->lock);
-
- while (p->owner && ast_channel_trylock(p->owner)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- }
- if (p->owner) {
- ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(p->owner);
- }
-
- while (p->chan && ast_channel_trylock(p->chan)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- }
- if (p->chan) {
- ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(p->chan);
- }
-
- ast_mutex_unlock(&p->lock);
- } else
- p->deferlogoff = 1;
- } else {
- logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- agent_logoff_maintenance(p, p->loginchan, logintime, NULL, "CommandLogoff");
- }
- break;
- }
- }
- AST_LIST_UNLOCK(&agents);
-
- return ret;
-}
-
-static int agent_logoff_cmd(int fd, int argc, char **argv)
-{
- int ret;
- char *agent;
-
- if (argc < 3 || argc > 4)
- return RESULT_SHOWUSAGE;
- if (argc == 4 && strcasecmp(argv[3], "soft"))
- return RESULT_SHOWUSAGE;
-
- agent = argv[2] + 6;
- ret = agent_logoff(agent, argc == 4);
- if (ret == 0)
- ast_cli(fd, "Logging out %s\n", agent);
-
- return RESULT_SUCCESS;
-}
-
-/*!
- * Sets an agent as no longer logged in in the Manager API.
- * It is registered on load_module() and it gets called by the manager backend.
- * \param s
- * \param m
- * \returns
- * \sa action_agents(), action_agent_callback_login(), load_module().
- */
-static int action_agent_logoff(struct mansession *s, const struct message *m)
-{
- const char *agent = astman_get_header(m, "Agent");
- const char *soft_s = astman_get_header(m, "Soft"); /* "true" is don't hangup */
- int soft;
- int ret; /* return value of agent_logoff */
-
- if (ast_strlen_zero(agent)) {
- astman_send_error(s, m, "No agent specified");
- return 0;
- }
-
- soft = ast_true(soft_s) ? 1 : 0;
- ret = agent_logoff(agent, soft);
- if (ret == 0)
- astman_send_ack(s, m, "Agent logged out");
- else
- astman_send_error(s, m, "No such agent");
-
- return 0;
-}
-
-static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state)
-{
- char *ret = NULL;
-
- if (pos == 2) {
- struct agent_pvt *p;
- char name[AST_MAX_AGENT];
- int which = 0, len = strlen(word);
-
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- snprintf(name, sizeof(name), "Agent/%s", p->agent);
- if (!strncasecmp(word, name, len) && ++which > state) {
- ret = ast_strdup(name);
- break;
- }
- }
- AST_LIST_UNLOCK(&agents);
- } else if (pos == 3 && state == 0)
- return ast_strdup("soft");
-
- return ret;
-}
-
-/*!
- * Show agents in cli.
- */
-static int agents_show(int fd, int argc, char **argv)
-{
- struct agent_pvt *p;
- char username[AST_MAX_BUF];
- char location[AST_MAX_BUF] = "";
- char talkingto[AST_MAX_BUF] = "";
- char moh[AST_MAX_BUF];
- int count_agents = 0; /*!< Number of agents configured */
- int online_agents = 0; /*!< Number of online agents */
- int offline_agents = 0; /*!< Number of offline agents */
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- ast_mutex_lock(&p->lock);
- if (p->pending) {
- if (p->group)
- ast_cli(fd, "-- Pending call to group %d\n", powerof(p->group));
- else
- ast_cli(fd, "-- Pending call to agent %s\n", p->agent);
- } else {
- if (!ast_strlen_zero(p->name))
- snprintf(username, sizeof(username), "(%s) ", p->name);
- else
- username[0] = '\0';
- if (p->chan) {
- snprintf(location, sizeof(location), "logged in on %s", p->chan->name);
- if (p->owner && ast_bridged_channel(p->owner))
- snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name);
- else
- strcpy(talkingto, " is idle");
- online_agents++;
- } else if (!ast_strlen_zero(p->loginchan)) {
- if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0 || !(p->lastdisc.tv_sec))
- snprintf(location, sizeof(location) - 20, "available at '%s'", p->loginchan);
- else
- snprintf(location, sizeof(location) - 20, "wrapping up at '%s'", p->loginchan);
- talkingto[0] = '\0';
- online_agents++;
- if (p->acknowledged)
- strncat(location, " (Confirmed)", sizeof(location) - strlen(location) - 1);
- } else {
- strcpy(location, "not logged in");
- talkingto[0] = '\0';
- offline_agents++;
- }
- if (!ast_strlen_zero(p->moh))
- snprintf(moh, sizeof(moh), " (musiconhold is '%s')", p->moh);
- ast_cli(fd, "%-12.12s %s%s%s%s\n", p->agent,
- username, location, talkingto, moh);
- count_agents++;
- }
- ast_mutex_unlock(&p->lock);
- }
- AST_LIST_UNLOCK(&agents);
- if ( !count_agents )
- ast_cli(fd, "No Agents are configured in %s\n",config);
- else
- ast_cli(fd, "%d agents configured [%d online , %d offline]\n",count_agents, online_agents, offline_agents);
- ast_cli(fd, "\n");
-
- return RESULT_SUCCESS;
-}
-
-
-static int agents_show_online(int fd, int argc, char **argv)
-{
- struct agent_pvt *p;
- char username[AST_MAX_BUF];
- char location[AST_MAX_BUF] = "";
- char talkingto[AST_MAX_BUF] = "";
- char moh[AST_MAX_BUF];
- int count_agents = 0; /* Number of agents configured */
- int online_agents = 0; /* Number of online agents */
- int agent_status = 0; /* 0 means offline, 1 means online */
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- agent_status = 0; /* reset it to offline */
- ast_mutex_lock(&p->lock);
- if (!ast_strlen_zero(p->name))
- snprintf(username, sizeof(username), "(%s) ", p->name);
- else
- username[0] = '\0';
- if (p->chan) {
- snprintf(location, sizeof(location), "logged in on %s", p->chan->name);
- if (p->owner && ast_bridged_channel(p->owner))
- snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name);
- else
- strcpy(talkingto, " is idle");
- agent_status = 1;
- online_agents++;
- } else if (!ast_strlen_zero(p->loginchan)) {
- snprintf(location, sizeof(location) - 20, "available at '%s'", p->loginchan);
- talkingto[0] = '\0';
- agent_status = 1;
- online_agents++;
- if (p->acknowledged)
- strncat(location, " (Confirmed)", sizeof(location) - strlen(location) - 1);
- }
- if (!ast_strlen_zero(p->moh))
- snprintf(moh, sizeof(moh), " (musiconhold is '%s')", p->moh);
- if (agent_status)
- ast_cli(fd, "%-12.12s %s%s%s%s\n", p->agent, username, location, talkingto, moh);
- count_agents++;
- ast_mutex_unlock(&p->lock);
- }
- AST_LIST_UNLOCK(&agents);
- if (!count_agents)
- ast_cli(fd, "No Agents are configured in %s\n", config);
- else
- ast_cli(fd, "%d agents online\n", online_agents);
- ast_cli(fd, "\n");
- return RESULT_SUCCESS;
-}
-
-
-
-static char show_agents_usage[] =
-"Usage: agent show\n"
-" Provides summary information on agents.\n";
-
-static char show_agents_online_usage[] =
-"Usage: agent show online\n"
-" Provides a list of all online agents.\n";
-
-static char agent_logoff_usage[] =
-"Usage: agent logoff <channel> [soft]\n"
-" Sets an agent as no longer logged in.\n"
-" If 'soft' is specified, do not hangup existing calls.\n";
-
-static struct ast_cli_entry cli_show_agents_deprecated = {
- { "show", "agents", NULL },
- agents_show, NULL,
- NULL, NULL };
-
-static struct ast_cli_entry cli_show_agents_online_deprecated = {
- { "show", "agents", "online" },
- agents_show_online, NULL,
- NULL, NULL };
-
-static struct ast_cli_entry cli_agents[] = {
- { { "agent", "show", NULL },
- agents_show, "Show status of agents",
- show_agents_usage, NULL, &cli_show_agents_deprecated },
-
- { { "agent", "show", "online" },
- agents_show_online, "Show all online agents",
- show_agents_online_usage, NULL, &cli_show_agents_online_deprecated },
-
- { { "agent", "logoff", NULL },
- agent_logoff_cmd, "Sets an agent offline",
- agent_logoff_usage, complete_agent_logoff_cmd },
-};
-
-/*!
- * \brief Log in agent application.
- *
- * \param chan
- * \param data
- * \param callbackmode non-zero for AgentCallbackLogin
- */
-static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
-{
- int res=0;
- int tries = 0;
- int max_login_tries = maxlogintries;
- struct agent_pvt *p;
- struct ast_module_user *u;
- int login_state = 0;
- char user[AST_MAX_AGENT] = "";
- char pass[AST_MAX_AGENT];
- char agent[AST_MAX_AGENT] = "";
- char xpass[AST_MAX_AGENT] = "";
- char *errmsg;
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(agent_id);
- AST_APP_ARG(options);
- AST_APP_ARG(extension);
- );
- const char *tmpoptions = NULL;
- char *context = NULL;
- int play_announcement = 1;
- char agent_goodbye[AST_MAX_FILENAME_LEN];
- int update_cdr = updatecdr;
- char *filename = "agent-loginok";
- char tmpchan[AST_MAX_BUF] = "";
-
- u = ast_module_user_add(chan);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- ast_copy_string(agent_goodbye, agentgoodbye, sizeof(agent_goodbye));
-
- /* Set Channel Specific Login Overrides */
- if (pbx_builtin_getvar_helper(chan, "AGENTLMAXLOGINTRIES") && strlen(pbx_builtin_getvar_helper(chan, "AGENTLMAXLOGINTRIES"))) {
- max_login_tries = atoi(pbx_builtin_getvar_helper(chan, "AGENTMAXLOGINTRIES"));
- if (max_login_tries < 0)
- max_login_tries = 0;
- tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTMAXLOGINTRIES");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTMAXLOGINTRIES=%s, setting max_login_tries to: %d on Channel '%s'.\n",tmpoptions,max_login_tries,chan->name);
- }
- if (pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR") && !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR"))) {
- if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR")))
- update_cdr = 1;
- else
- update_cdr = 0;
- tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTUPDATECDR=%s, setting update_cdr to: %d on Channel '%s'.\n",tmpoptions,update_cdr,chan->name);
- }
- if (pbx_builtin_getvar_helper(chan, "AGENTGOODBYE") && !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTGOODBYE"))) {
- strcpy(agent_goodbye, pbx_builtin_getvar_helper(chan, "AGENTGOODBYE"));
- tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTGOODBYE");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTGOODBYE=%s, setting agent_goodbye to: %s on Channel '%s'.\n",tmpoptions,agent_goodbye,chan->name);
- }
- /* End Channel Specific Login Overrides */
-
- if (callbackmode && args.extension) {
- parse = args.extension;
- args.extension = strsep(&parse, "@");
- context = parse;
- }
-
- if (!ast_strlen_zero(args.options)) {
- if (strchr(args.options, 's')) {
- play_announcement = 0;
- }
- }
-
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
- if (!res) {
- if (!ast_strlen_zero(args.agent_id))
- ast_copy_string(user, args.agent_id, AST_MAX_AGENT);
- else
- res = ast_app_getdata(chan, "agent-user", user, sizeof(user) - 1, 0);
- }
- while (!res && (max_login_tries==0 || tries < max_login_tries)) {
- tries++;
- /* Check for password */
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (!strcmp(p->agent, user) && !p->pending)
- ast_copy_string(xpass, p->password, sizeof(xpass));
- }
- AST_LIST_UNLOCK(&agents);
- if (!res) {
- if (!ast_strlen_zero(xpass))
- res = ast_app_getdata(chan, "agent-pass", pass, sizeof(pass) - 1, 0);
- else
- pass[0] = '\0';
- }
- errmsg = "agent-incorrect";
-
-#if 0
- ast_log(LOG_NOTICE, "user: %s, pass: %s\n", user, pass);
-#endif
-
- /* Check again for accuracy */
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- ast_mutex_lock(&p->lock);
- if (!strcmp(p->agent, user) &&
- !strcmp(p->password, pass) && !p->pending) {
- login_state = 1; /* Successful Login */
-
- /* Ensure we can't be gotten until we're done */
- gettimeofday(&p->lastdisc, NULL);
- p->lastdisc.tv_sec++;
-
- /* Set Channel Specific Agent Overrides */
- if (pbx_builtin_getvar_helper(chan, "AGENTACKCALL") && strlen(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"))) {
- if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"), "always"))
- p->ackcall = 2;
- else if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTACKCALL")))
- p->ackcall = 1;
- else
- p->ackcall = 0;
- tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTACKCALL");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'.\n",tmpoptions,p->ackcall,p->agent);
- }
- if (pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF") && strlen(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"))) {
- p->autologoff = atoi(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"));
- if (p->autologoff < 0)
- p->autologoff = 0;
- tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTAUTOLOGOFF=%s, setting autologff to: %d for Agent '%s'.\n",tmpoptions,p->autologoff,p->agent);
- }
- if (pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME") && strlen(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"))) {
- p->wrapuptime = atoi(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"));
- if (p->wrapuptime < 0)
- p->wrapuptime = 0;
- tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME");
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTWRAPUPTIME=%s, setting wrapuptime to: %d for Agent '%s'.\n",tmpoptions,p->wrapuptime,p->agent);
- }
- /* End Channel Specific Agent Overrides */
- if (!p->chan) {
- char last_loginchan[80] = "";
- long logintime;
- snprintf(agent, sizeof(agent), "Agent/%s", p->agent);
-
- if (callbackmode) {
- int pos = 0;
- /* Retrieve login chan */
- for (;;) {
- if (!ast_strlen_zero(args.extension)) {
- ast_copy_string(tmpchan, args.extension, sizeof(tmpchan));
- res = 0;
- } else
- res = ast_app_getdata(chan, "agent-newlocation", tmpchan+pos, sizeof(tmpchan) - 2, 0);
- if (ast_strlen_zero(tmpchan) )
- break;
- if(ast_exists_extension(chan, S_OR(context,"default"), tmpchan,1, NULL) ) {
- if(!allow_multiple_login(tmpchan,context) ) {
- args.extension = NULL;
- pos = 0;
- } else
- break;
- }
- if (args.extension) {
- ast_log(LOG_WARNING, "Extension '%s' is not valid for automatic login of agent '%s'\n", args.extension, p->agent);
- args.extension = NULL;
- pos = 0;
- } else {
- ast_log(LOG_WARNING, "Extension '%s@%s' is not valid for automatic login of agent '%s'\n", tmpchan, S_OR(context, "default"), p->agent);
- res = ast_streamfile(chan, "invalid", chan->language);
- if (!res)
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- if (res > 0) {
- tmpchan[0] = res;
- tmpchan[1] = '\0';
- pos = 1;
- } else {
- tmpchan[0] = '\0';
- pos = 0;
- }
- }
- }
- args.extension = tmpchan;
- if (!res) {
- set_agentbycallerid(p->logincallerid, NULL);
- if (!ast_strlen_zero(context) && !ast_strlen_zero(tmpchan))
- snprintf(p->loginchan, sizeof(p->loginchan), "%s@%s", tmpchan, context);
- else {
- ast_copy_string(last_loginchan, p->loginchan, sizeof(last_loginchan));
- ast_copy_string(p->loginchan, tmpchan, sizeof(p->loginchan));
- }
- p->acknowledged = 0;
- if (ast_strlen_zero(p->loginchan)) {
- login_state = 2;
- filename = "agent-loggedoff";
- } else {
- if (chan->cid.cid_num) {
- ast_copy_string(p->logincallerid, chan->cid.cid_num, sizeof(p->logincallerid));
- set_agentbycallerid(p->logincallerid, p->agent);
- } else
- p->logincallerid[0] = '\0';
- }
-
- if(update_cdr && chan->cdr)
- snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
-
- }
- } else {
- p->loginchan[0] = '\0';
- p->logincallerid[0] = '\0';
- p->acknowledged = 0;
- }
- ast_mutex_unlock(&p->lock);
- AST_LIST_UNLOCK(&agents);
- if( !res && play_announcement==1 )
- res = ast_streamfile(chan, filename, chan->language);
- if (!res)
- ast_waitstream(chan, "");
- AST_LIST_LOCK(&agents);
- ast_mutex_lock(&p->lock);
- if (!res) {
- res = ast_set_read_format(chan, ast_best_codec(chan->nativeformats));
- if (res)
- ast_log(LOG_WARNING, "Unable to set read format to %d\n", ast_best_codec(chan->nativeformats));
- }
- if (!res) {
- res = ast_set_write_format(chan, ast_best_codec(chan->nativeformats));
- if (res)
- ast_log(LOG_WARNING, "Unable to set write format to %d\n", ast_best_codec(chan->nativeformats));
- }
- /* Check once more just in case */
- if (p->chan)
- res = -1;
- if (callbackmode && !res) {
- /* Just say goodbye and be done with it */
- if (!ast_strlen_zero(p->loginchan)) {
- if (p->loginstart == 0)
- time(&p->loginstart);
- manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogin",
- "Agent: %s\r\n"
- "Loginchan: %s\r\n"
- "Uniqueid: %s\r\n",
- p->agent, p->loginchan, chan->uniqueid);
- ast_queue_log("NONE", chan->uniqueid, agent, "AGENTCALLBACKLOGIN", "%s", p->loginchan);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Callback Agent '%s' logged in on %s\n", p->agent, p->loginchan);
- ast_device_state_changed("Agent/%s", p->agent);
- if (persistent_agents)
- dump_agents();
- } else {
- logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
-
- agent_logoff_maintenance(p, last_loginchan, logintime, chan->uniqueid, NULL);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Callback Agent '%s' logged out\n", p->agent);
- }
- AST_LIST_UNLOCK(&agents);
- if (!res)
- res = ast_safe_sleep(chan, 500);
- ast_mutex_unlock(&p->lock);
- } else if (!res) {
- ast_indicate_data(chan, AST_CONTROL_HOLD,
- S_OR(p->moh, NULL),
- !ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
- if (p->loginstart == 0)
- time(&p->loginstart);
- manager_event(EVENT_FLAG_AGENT, "Agentlogin",
- "Agent: %s\r\n"
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n",
- p->agent, chan->name, chan->uniqueid);
- if (update_cdr && chan->cdr)
- snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
- ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGIN", "%s", chan->name);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Agent '%s' logged in (format %s/%s)\n", p->agent,
- ast_getformatname(chan->readformat), ast_getformatname(chan->writeformat));
- /* Login this channel and wait for it to go away */
- p->chan = chan;
- if (p->ackcall > 1)
- check_beep(p, 0);
- else
- check_availability(p, 0);
- ast_mutex_unlock(&p->lock);
- AST_LIST_UNLOCK(&agents);
- ast_device_state_changed("Agent/%s", p->agent);
- while (res >= 0) {
- ast_mutex_lock(&p->lock);
- if (p->deferlogoff && p->chan) {
- ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
- p->deferlogoff = 0;
- }
- if (p->chan != chan)
- res = -1;
- ast_mutex_unlock(&p->lock);
- /* Yield here so other interested threads can kick in. */
- sched_yield();
- if (res)
- break;
-
- AST_LIST_LOCK(&agents);
- ast_mutex_lock(&p->lock);
- if (p->lastdisc.tv_sec) {
- if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Wrapup time for %s expired!\n", p->agent);
- p->lastdisc = ast_tv(0, 0);
- ast_device_state_changed("Agent/%s", p->agent);
- if (p->ackcall > 1)
- check_beep(p, 0);
- else
- check_availability(p, 0);
- }
- }
- ast_mutex_unlock(&p->lock);
- AST_LIST_UNLOCK(&agents);
- /* Synchronize channel ownership between call to agent and itself. */
- ast_mutex_lock( &p->app_lock );
- ast_mutex_lock(&p->lock);
- p->owning_app = pthread_self();
- ast_mutex_unlock(&p->lock);
- if (p->ackcall > 1)
- res = agent_ack_sleep(p);
- else
- res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p );
- ast_mutex_unlock( &p->app_lock );
- if ((p->ackcall > 1) && (res == 1)) {
- AST_LIST_LOCK(&agents);
- ast_mutex_lock(&p->lock);
- check_availability(p, 0);
- ast_mutex_unlock(&p->lock);
- AST_LIST_UNLOCK(&agents);
- res = 0;
- }
- sched_yield();
- }
- ast_mutex_lock(&p->lock);
- if (res && p->owner)
- ast_log(LOG_WARNING, "Huh? We broke out when there was still an owner?\n");
- /* Log us off if appropriate */
- if (p->chan == chan)
- p->chan = NULL;
- p->acknowledged = 0;
- logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- ast_mutex_unlock(&p->lock);
- manager_event(EVENT_FLAG_AGENT, "Agentlogoff",
- "Agent: %s\r\n"
- "Logintime: %ld\r\n"
- "Uniqueid: %s\r\n",
- p->agent, logintime, chan->uniqueid);
- ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGOFF", "%s|%ld", chan->name, logintime);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Agent '%s' logged out\n", p->agent);
- /* If there is no owner, go ahead and kill it now */
- ast_device_state_changed("Agent/%s", p->agent);
- if (p->dead && !p->owner) {
- ast_mutex_destroy(&p->lock);
- ast_mutex_destroy(&p->app_lock);
- free(p);
- }
- }
- else {
- ast_mutex_unlock(&p->lock);
- p = NULL;
- }
- res = -1;
- } else {
- ast_mutex_unlock(&p->lock);
- errmsg = "agent-alreadyon";
- p = NULL;
- }
- break;
- }
- ast_mutex_unlock(&p->lock);
- }
- if (!p)
- AST_LIST_UNLOCK(&agents);
-
- if (!res && (max_login_tries==0 || tries < max_login_tries))
- res = ast_app_getdata(chan, errmsg, user, sizeof(user) - 1, 0);
- }
-
- if (!res)
- res = ast_safe_sleep(chan, 500);
-
- /* AgentLogin() exit */
- if (!callbackmode) {
- ast_module_user_remove(u);
- return -1;
- } else { /* AgentCallbackLogin() exit*/
- /* Set variables */
- if (login_state > 0) {
- pbx_builtin_setvar_helper(chan, "AGENTNUMBER", user);
- if (login_state==1) {
- pbx_builtin_setvar_helper(chan, "AGENTSTATUS", "on");
- pbx_builtin_setvar_helper(chan, "AGENTEXTEN", args.extension);
- } else
- pbx_builtin_setvar_helper(chan, "AGENTSTATUS", "off");
- } else {
- pbx_builtin_setvar_helper(chan, "AGENTSTATUS", "fail");
- }
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num)) {
- ast_module_user_remove(u);
- return 0;
- }
- /* Do we need to play agent-goodbye now that we will be hanging up? */
- if (play_announcement) {
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- res = ast_streamfile(chan, agent_goodbye, chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- }
- }
-
- ast_module_user_remove(u);
-
- /* We should never get here if next priority exists when in callbackmode */
- return -1;
-}
-
-/*!
- * Called by the AgentLogin application (from the dial plan).
- *
- * \param chan
- * \param data
- * \returns
- * \sa callback_login_exec(), agentmonitoroutgoing_exec(), load_module().
- */
-static int login_exec(struct ast_channel *chan, void *data)
-{
- return __login_exec(chan, data, 0);
-}
-
-static void callback_deprecated(void)
-{
- static int depwarning = 0;
-
- if (!depwarning) {
- depwarning = 1;
-
- ast_log(LOG_WARNING, "AgentCallbackLogin is deprecated and will be removed in a future release.\n");
- ast_log(LOG_WARNING, "See doc/queues-with-callback-members.txt for an example of how to achieve\n");
- ast_log(LOG_WARNING, "the same functionality using only dialplan logic.\n");
- }
-}
-
-/*!
- * Called by the AgentCallbackLogin application (from the dial plan).
- *
- * \param chan
- * \param data
- * \returns
- * \sa login_exec(), agentmonitoroutgoing_exec(), load_module().
- */
-static int callback_exec(struct ast_channel *chan, void *data)
-{
- callback_deprecated();
-
- return __login_exec(chan, data, 1);
-}
-
-/*!
- * Sets an agent as logged in by callback in the Manager API.
- * It is registered on load_module() and it gets called by the manager backend.
- * \param s
- * \param m
- * \returns
- * \sa action_agents(), action_agent_logoff(), load_module().
- */
-static int action_agent_callback_login(struct mansession *s, const struct message *m)
-{
- const char *agent = astman_get_header(m, "Agent");
- const char *exten = astman_get_header(m, "Exten");
- const char *context = astman_get_header(m, "Context");
- const char *wrapuptime_s = astman_get_header(m, "WrapupTime");
- const char *ackcall_s = astman_get_header(m, "AckCall");
- struct agent_pvt *p;
- int login_state = 0;
-
- callback_deprecated();
-
- if (ast_strlen_zero(agent)) {
- astman_send_error(s, m, "No agent specified");
- return 0;
- }
-
- if (ast_strlen_zero(exten)) {
- astman_send_error(s, m, "No extension specified");
- return 0;
- }
-
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (strcmp(p->agent, agent) || p->pending)
- continue;
- if (p->chan) {
- login_state = 2; /* already logged in (and on the phone)*/
- break;
- }
- ast_mutex_lock(&p->lock);
- login_state = 1; /* Successful Login */
-
- if (ast_strlen_zero(context))
- ast_copy_string(p->loginchan, exten, sizeof(p->loginchan));
- else
- snprintf(p->loginchan, sizeof(p->loginchan), "%s@%s", exten, context);
-
- if (!ast_strlen_zero(wrapuptime_s)) {
- p->wrapuptime = atoi(wrapuptime_s);
- if (p->wrapuptime < 0)
- p->wrapuptime = 0;
- }
-
- if (ast_true(ackcall_s))
- p->ackcall = 1;
- else
- p->ackcall = 0;
-
- if (p->loginstart == 0)
- time(&p->loginstart);
- manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogin",
- "Agent: %s\r\n"
- "Loginchan: %s\r\n",
- p->agent, p->loginchan);
- ast_queue_log("NONE", "NONE", agent, "AGENTCALLBACKLOGIN", "%s", p->loginchan);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Callback Agent '%s' logged in on %s\n", p->agent, p->loginchan);
- ast_device_state_changed("Agent/%s", p->agent);
- ast_mutex_unlock(&p->lock);
- if (persistent_agents)
- dump_agents();
- }
- AST_LIST_UNLOCK(&agents);
-
- if (login_state == 1)
- astman_send_ack(s, m, "Agent logged in");
- else if (login_state == 0)
- astman_send_error(s, m, "No such agent");
- else if (login_state == 2)
- astman_send_error(s, m, "Agent already logged in");
-
- return 0;
-}
-
-/*!
- * \brief Called by the AgentMonitorOutgoing application (from the dial plan).
- *
- * \param chan
- * \param data
- * \returns
- * \sa login_exec(), callback_login_exec(), load_module().
- */
-static int agentmonitoroutgoing_exec(struct ast_channel *chan, void *data)
-{
- int exitifnoagentid = 0;
- int nowarnings = 0;
- int changeoutgoing = 0;
- int res = 0;
- char agent[AST_MAX_AGENT];
-
- if (data) {
- if (strchr(data, 'd'))
- exitifnoagentid = 1;
- if (strchr(data, 'n'))
- nowarnings = 1;
- if (strchr(data, 'c'))
- changeoutgoing = 1;
- }
- if (chan->cid.cid_num) {
- const char *tmp;
- char agentvar[AST_MAX_BUF];
- snprintf(agentvar, sizeof(agentvar), "%s_%s", GETAGENTBYCALLERID, chan->cid.cid_num);
- if ((tmp = pbx_builtin_getvar_helper(NULL, agentvar))) {
- struct agent_pvt *p;
- ast_copy_string(agent, tmp, sizeof(agent));
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- if (!strcasecmp(p->agent, tmp)) {
- if (changeoutgoing) snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
- __agent_start_monitoring(chan, p, 1);
- break;
- }
- }
- AST_LIST_UNLOCK(&agents);
-
- } else {
- res = -1;
- if (!nowarnings)
- ast_log(LOG_WARNING, "Couldn't find the global variable %s, so I can't figure out which agent (if it's an agent) is placing outgoing call.\n", agentvar);
- }
- } else {
- res = -1;
- if (!nowarnings)
- ast_log(LOG_WARNING, "There is no callerid on that call, so I can't figure out which agent (if it's an agent) is placing outgoing call.\n");
- }
- /* check if there is n + 101 priority */
- /*! \todo XXX Needs to check option priorityjump etc etc */
- if (res) {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num)) {
- chan->priority+=100;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Going to %d priority because there is no callerid or the agentid cannot be found.\n",chan->priority);
- } else if (exitifnoagentid)
- return res;
- }
- return 0;
-}
-
-/*!
- * \brief Dump AgentCallbackLogin agents to the ASTdb database for persistence
- */
-static void dump_agents(void)
-{
- struct agent_pvt *cur_agent = NULL;
- char buf[256];
-
- AST_LIST_TRAVERSE(&agents, cur_agent, list) {
- if (cur_agent->chan)
- continue;
-
- if (!ast_strlen_zero(cur_agent->loginchan)) {
- snprintf(buf, sizeof(buf), "%s;%s", cur_agent->loginchan, cur_agent->logincallerid);
- if (ast_db_put(pa_family, cur_agent->agent, buf))
- ast_log(LOG_WARNING, "failed to create persistent entry in ASTdb for %s!\n", buf);
- else if (option_debug)
- ast_log(LOG_DEBUG, "Saved Agent: %s on %s\n", cur_agent->agent, cur_agent->loginchan);
- } else {
- /* Delete - no agent or there is an error */
- ast_db_del(pa_family, cur_agent->agent);
- }
- }
-}
-
-/*!
- * \brief Reload the persistent agents from astdb.
- */
-static void reload_agents(void)
-{
- char *agent_num;
- struct ast_db_entry *db_tree;
- struct ast_db_entry *entry;
- struct agent_pvt *cur_agent;
- char agent_data[256];
- char *parse;
- char *agent_chan;
- char *agent_callerid;
-
- db_tree = ast_db_gettree(pa_family, NULL);
-
- AST_LIST_LOCK(&agents);
- for (entry = db_tree; entry; entry = entry->next) {
- agent_num = entry->key + strlen(pa_family) + 2;
- AST_LIST_TRAVERSE(&agents, cur_agent, list) {
- ast_mutex_lock(&cur_agent->lock);
- if (strcmp(agent_num, cur_agent->agent) == 0)
- break;
- ast_mutex_unlock(&cur_agent->lock);
- }
- if (!cur_agent) {
- ast_db_del(pa_family, agent_num);
- continue;
- } else
- ast_mutex_unlock(&cur_agent->lock);
- if (!ast_db_get(pa_family, agent_num, agent_data, sizeof(agent_data)-1)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Reload Agent from AstDB: %s on %s\n", cur_agent->agent, agent_data);
- parse = agent_data;
- agent_chan = strsep(&parse, ";");
- agent_callerid = strsep(&parse, ";");
- ast_copy_string(cur_agent->loginchan, agent_chan, sizeof(cur_agent->loginchan));
- if (agent_callerid) {
- ast_copy_string(cur_agent->logincallerid, agent_callerid, sizeof(cur_agent->logincallerid));
- set_agentbycallerid(cur_agent->logincallerid, cur_agent->agent);
- } else
- cur_agent->logincallerid[0] = '\0';
- if (cur_agent->loginstart == 0)
- time(&cur_agent->loginstart);
- ast_device_state_changed("Agent/%s", cur_agent->agent);
- }
- }
- AST_LIST_UNLOCK(&agents);
- if (db_tree) {
- ast_log(LOG_NOTICE, "Agents successfully reloaded from database.\n");
- ast_db_freetree(db_tree);
- }
-}
-
-/*! \brief Part of PBX channel interface */
-static int agent_devicestate(void *data)
-{
- struct agent_pvt *p;
- char *s;
- ast_group_t groupmatch;
- int groupoff;
- int waitforagent=0;
- int res = AST_DEVICE_INVALID;
-
- s = data;
- if ((s[0] == '@') && (sscanf(s + 1, "%d", &groupoff) == 1))
- groupmatch = (1 << groupoff);
- else if ((s[0] == ':') && (sscanf(s + 1, "%d", &groupoff) == 1)) {
- groupmatch = (1 << groupoff);
- waitforagent = 1;
- } else
- groupmatch = 0;
-
- /* Check actual logged in agents first */
- AST_LIST_LOCK(&agents);
- AST_LIST_TRAVERSE(&agents, p, list) {
- ast_mutex_lock(&p->lock);
- if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent))) {
- if (p->owner) {
- if (res != AST_DEVICE_INUSE)
- res = AST_DEVICE_BUSY;
- } else {
- if (res == AST_DEVICE_BUSY)
- res = AST_DEVICE_INUSE;
- if (p->chan || !ast_strlen_zero(p->loginchan)) {
- if (res == AST_DEVICE_INVALID)
- res = AST_DEVICE_UNKNOWN;
- } else if (res == AST_DEVICE_INVALID)
- res = AST_DEVICE_UNAVAILABLE;
- }
- if (!strcmp(data, p->agent)) {
- ast_mutex_unlock(&p->lock);
- break;
- }
- }
- ast_mutex_unlock(&p->lock);
- }
- AST_LIST_UNLOCK(&agents);
- return res;
-}
-
-/*!
- * \note This function expects the agent list to be locked
- */
-static struct agent_pvt *find_agent(char *agentid)
-{
- struct agent_pvt *cur;
-
- AST_LIST_TRAVERSE(&agents, cur, list) {
- if (!strcmp(cur->agent, agentid))
- break;
- }
-
- return cur;
-}
-
-static int function_agent(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(agentid);
- AST_APP_ARG(item);
- );
- char *tmp;
- struct agent_pvt *agent;
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "The AGENT function requires an argument - agentid!\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_NONSTANDARD_APP_ARGS(args, parse, ':');
- if (!args.item)
- args.item = "status";
-
- AST_LIST_LOCK(&agents);
-
- if (!(agent = find_agent(args.agentid))) {
- AST_LIST_UNLOCK(&agents);
- ast_log(LOG_WARNING, "Agent '%s' not found!\n", args.agentid);
- return -1;
- }
-
- if (!strcasecmp(args.item, "status")) {
- char *status = "LOGGEDOUT";
- if (agent->chan || !ast_strlen_zero(agent->loginchan))
- status = "LOGGEDIN";
- ast_copy_string(buf, status, len);
- } else if (!strcasecmp(args.item, "password"))
- ast_copy_string(buf, agent->password, len);
- else if (!strcasecmp(args.item, "name"))
- ast_copy_string(buf, agent->name, len);
- else if (!strcasecmp(args.item, "mohclass"))
- ast_copy_string(buf, agent->moh, len);
- else if (!strcasecmp(args.item, "channel")) {
- if (agent->chan) {
- ast_copy_string(buf, agent->chan->name, len);
- tmp = strrchr(buf, '-');
- if (tmp)
- *tmp = '\0';
- }
- } else if (!strcasecmp(args.item, "exten"))
- ast_copy_string(buf, agent->loginchan, len);
-
- AST_LIST_UNLOCK(&agents);
-
- return 0;
-}
-
-struct ast_custom_function agent_function = {
- .name = "AGENT",
- .synopsis = "Gets information about an Agent",
- .syntax = "AGENT(<agentid>[:item])",
- .read = function_agent,
- .desc = "The valid items to retrieve are:\n"
- "- status (default) The status of the agent\n"
- " LOGGEDIN | LOGGEDOUT\n"
- "- password The password of the agent\n"
- "- name The name of the agent\n"
- "- mohclass MusicOnHold class\n"
- "- exten The callback extension for the Agent (AgentCallbackLogin)\n"
- "- channel The name of the active channel for the Agent (AgentLogin)\n"
-};
-
-
-/*!
- * \brief Initialize the Agents module.
- * This function is being called by Asterisk when loading the module.
- * Among other things it registers applications, cli commands and reads the cofiguration file.
- *
- * \returns int Always 0.
- */
-static int load_module(void)
-{
- /* Make sure we can register our agent channel type */
- if (ast_channel_register(&agent_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Agent'\n");
- return -1;
- }
- /* Read in the config */
- if (!read_agent_config())
- return AST_MODULE_LOAD_DECLINE;
- if (persistent_agents)
- reload_agents();
- /* Dialplan applications */
- ast_register_application(app, login_exec, synopsis, descrip);
- ast_register_application(app2, callback_exec, synopsis2, descrip2);
- ast_register_application(app3, agentmonitoroutgoing_exec, synopsis3, descrip3);
-
- /* Manager commands */
- ast_manager_register2("Agents", EVENT_FLAG_AGENT, action_agents, "Lists agents and their status", mandescr_agents);
- ast_manager_register2("AgentLogoff", EVENT_FLAG_AGENT, action_agent_logoff, "Sets an agent as no longer logged in", mandescr_agent_logoff);
- ast_manager_register2("AgentCallbackLogin", EVENT_FLAG_AGENT, action_agent_callback_login, "Sets an agent as logged in by callback", mandescr_agent_callback_login);
-
- /* CLI Commands */
- ast_cli_register_multiple(cli_agents, sizeof(cli_agents) / sizeof(struct ast_cli_entry));
-
- /* Dialplan Functions */
- ast_custom_function_register(&agent_function);
-
- return 0;
-}
-
-static int reload(void)
-{
- read_agent_config();
- if (persistent_agents)
- reload_agents();
- return 0;
-}
-
-static int unload_module(void)
-{
- struct agent_pvt *p;
- /* First, take us out of the channel loop */
- ast_channel_unregister(&agent_tech);
- /* Unregister dialplan functions */
- ast_custom_function_unregister(&agent_function);
- /* Unregister CLI commands */
- ast_cli_unregister_multiple(cli_agents, sizeof(cli_agents) / sizeof(struct ast_cli_entry));
- /* Unregister dialplan applications */
- ast_unregister_application(app);
- ast_unregister_application(app2);
- ast_unregister_application(app3);
- /* Unregister manager command */
- ast_manager_unregister("Agents");
- ast_manager_unregister("AgentLogoff");
- ast_manager_unregister("AgentCallbackLogin");
- /* Unregister channel */
- AST_LIST_LOCK(&agents);
- /* Hangup all interfaces if they have an owner */
- while ((p = AST_LIST_REMOVE_HEAD(&agents, list))) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- free(p);
- }
- AST_LIST_UNLOCK(&agents);
- AST_LIST_HEAD_DESTROY(&agents);
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Agent Proxy Channel",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/chan_alsa.c b/1.4/channels/chan_alsa.c
deleted file mode 100644
index 9a416837b..000000000
--- a/1.4/channels/chan_alsa.c
+++ /dev/null
@@ -1,1377 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * By Matthew Fredrickson <creslin@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.
- */
-
-/*! \file
- * \brief ALSA sound card channel driver
- *
- * \author Matthew Fredrickson <creslin@digium.com>
- *
- * \par See also
- * \arg Config_alsa
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>asound</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#define ALSA_PCM_NEW_SW_PARAMS_API
-#include <alsa/asoundlib.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/endian.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/musiconhold.h"
-
-#include "busy.h"
-#include "ringtone.h"
-#include "ring10.h"
-#include "answer.h"
-
-#ifdef ALSA_MONITOR
-#include "alsa-monitor.h"
-#endif
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf = {
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-#define DEBUG 0
-/* Which device to use */
-#define ALSA_INDEV "default"
-#define ALSA_OUTDEV "default"
-#define DESIRED_RATE 8000
-
-/* Lets use 160 sample frames, just like GSM. */
-#define FRAME_SIZE 160
-#define PERIOD_FRAMES 80 /* 80 Frames, at 2 bytes each */
-
-/* When you set the frame size, you have to come up with
- the right buffer format as well. */
-/* 5 64-byte frames = one frame */
-#define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006);
-
-/* Don't switch between read/write modes faster than every 300 ms */
-#define MIN_SWITCH_TIME 600
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-static snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
-#else
-static snd_pcm_format_t format = SND_PCM_FORMAT_S16_BE;
-#endif
-
-/* static int block = O_NONBLOCK; */
-static char indevname[50] = ALSA_INDEV;
-static char outdevname[50] = ALSA_OUTDEV;
-
-#if 0
-static struct timeval lasttime;
-#endif
-
-static int silencesuppression = 0;
-static int silencethreshold = 1000;
-
-AST_MUTEX_DEFINE_STATIC(alsalock);
-
-static const char tdesc[] = "ALSA Console Channel Driver";
-static const char config[] = "alsa.conf";
-
-static char context[AST_MAX_CONTEXT] = "default";
-static char language[MAX_LANGUAGE] = "";
-static char exten[AST_MAX_EXTENSION] = "s";
-static char mohinterpret[MAX_MUSICCLASS];
-
-static int hookstate = 0;
-
-static short silence[FRAME_SIZE] = { 0, };
-
-struct sound {
- int ind;
- short *data;
- int datalen;
- int samplen;
- int silencelen;
- int repeat;
-};
-
-static struct sound sounds[] = {
- {AST_CONTROL_RINGING, ringtone, sizeof(ringtone) / 2, 16000, 32000, 1},
- {AST_CONTROL_BUSY, busy, sizeof(busy) / 2, 4000, 4000, 1},
- {AST_CONTROL_CONGESTION, busy, sizeof(busy) / 2, 2000, 2000, 1},
- {AST_CONTROL_RING, ring10, sizeof(ring10) / 2, 16000, 32000, 1},
- {AST_CONTROL_ANSWER, answer, sizeof(answer) / 2, 2200, 0, 0},
-};
-
-/* Sound command pipe */
-static int sndcmd[2];
-
-static struct chan_alsa_pvt {
- /* We only have one ALSA structure -- near sighted perhaps, but it
- keeps this driver as simple as possible -- as it should be. */
- struct ast_channel *owner;
- char exten[AST_MAX_EXTENSION];
- char context[AST_MAX_CONTEXT];
-#if 0
- snd_pcm_t *card;
-#endif
- snd_pcm_t *icard, *ocard;
-
-} alsa;
-
-/* Number of buffers... Each is FRAMESIZE/8 ms long. For example
- with 160 sample frames, and a buffer size of 3, we have a 60ms buffer,
- usually plenty. */
-
-pthread_t sthread;
-
-#define MAX_BUFFER_SIZE 100
-
-/* File descriptors for sound device */
-static int readdev = -1;
-static int writedev = -1;
-
-static int autoanswer = 1;
-
-static int cursound = -1;
-static int sampsent = 0;
-static int silencelen = 0;
-static int offset = 0;
-static int nosound = 0;
-
-/* ZZ */
-static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause);
-static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
-static int alsa_text(struct ast_channel *c, const char *text);
-static int alsa_hangup(struct ast_channel *c);
-static int alsa_answer(struct ast_channel *c);
-static struct ast_frame *alsa_read(struct ast_channel *chan);
-static int alsa_call(struct ast_channel *c, char *dest, int timeout);
-static int alsa_write(struct ast_channel *chan, struct ast_frame *f);
-static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
-static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-
-static const struct ast_channel_tech alsa_tech = {
- .type = "Console",
- .description = tdesc,
- .capabilities = AST_FORMAT_SLINEAR,
- .requester = alsa_request,
- .send_digit_end = alsa_digit,
- .send_text = alsa_text,
- .hangup = alsa_hangup,
- .answer = alsa_answer,
- .read = alsa_read,
- .call = alsa_call,
- .write = alsa_write,
- .indicate = alsa_indicate,
- .fixup = alsa_fixup,
-};
-
-static int send_sound(void)
-{
- short myframe[FRAME_SIZE];
- int total = FRAME_SIZE;
- short *frame = NULL;
- int amt = 0, res, myoff;
- snd_pcm_state_t state;
-
- if (cursound == -1)
- return 0;
-
- res = total;
- if (sampsent < sounds[cursound].samplen) {
- myoff = 0;
- while (total) {
- amt = total;
- if (amt > (sounds[cursound].datalen - offset))
- amt = sounds[cursound].datalen - offset;
- memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
- total -= amt;
- offset += amt;
- sampsent += amt;
- myoff += amt;
- if (offset >= sounds[cursound].datalen)
- offset = 0;
- }
- /* Set it up for silence */
- if (sampsent >= sounds[cursound].samplen)
- silencelen = sounds[cursound].silencelen;
- frame = myframe;
- } else {
- if (silencelen > 0) {
- frame = silence;
- silencelen -= res;
- } else {
- if (sounds[cursound].repeat) {
- /* Start over */
- sampsent = 0;
- offset = 0;
- } else {
- cursound = -1;
- nosound = 0;
- }
- return 0;
- }
- }
-
- if (res == 0 || !frame)
- return 0;
-
-#ifdef ALSA_MONITOR
- alsa_monitor_write((char *) frame, res * 2);
-#endif
- state = snd_pcm_state(alsa.ocard);
- if (state == SND_PCM_STATE_XRUN)
- snd_pcm_prepare(alsa.ocard);
- res = snd_pcm_writei(alsa.ocard, frame, res);
- if (res > 0)
- return 0;
- return 0;
-}
-
-static void *sound_thread(void *unused)
-{
- fd_set rfds;
- fd_set wfds;
- int max, res;
-
- for (;;) {
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- max = sndcmd[0];
- FD_SET(sndcmd[0], &rfds);
- if (cursound > -1) {
- FD_SET(writedev, &wfds);
- if (writedev > max)
- max = writedev;
- }
-#ifdef ALSA_MONITOR
- if (!alsa.owner) {
- FD_SET(readdev, &rfds);
- if (readdev > max)
- max = readdev;
- }
-#endif
- res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
- if (res < 1) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
- continue;
- }
-#ifdef ALSA_MONITOR
- if (FD_ISSET(readdev, &rfds)) {
- /* Keep the pipe going with read audio */
- snd_pcm_state_t state;
- short buf[FRAME_SIZE];
- int r;
-
- state = snd_pcm_state(alsa.ocard);
- if (state == SND_PCM_STATE_XRUN) {
- snd_pcm_prepare(alsa.ocard);
- }
- r = snd_pcm_readi(alsa.icard, buf, FRAME_SIZE);
- if (r == -EPIPE) {
-#if DEBUG
- ast_log(LOG_ERROR, "XRUN read\n");
-#endif
- snd_pcm_prepare(alsa.icard);
- } else if (r == -ESTRPIPE) {
- ast_log(LOG_ERROR, "-ESTRPIPE\n");
- snd_pcm_prepare(alsa.icard);
- } else if (r < 0) {
- ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
- } else
- alsa_monitor_read((char *) buf, r * 2);
- }
-#endif
- if (FD_ISSET(sndcmd[0], &rfds)) {
- read(sndcmd[0], &cursound, sizeof(cursound));
- silencelen = 0;
- offset = 0;
- sampsent = 0;
- }
- if (FD_ISSET(writedev, &wfds))
- if (send_sound())
- ast_log(LOG_WARNING, "Failed to write sound\n");
- }
- /* Never reached */
- return NULL;
-}
-
-static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
-{
- int err;
- int direction;
- snd_pcm_t *handle = NULL;
- snd_pcm_hw_params_t *hwparams = NULL;
- snd_pcm_sw_params_t *swparams = NULL;
- struct pollfd pfd;
- snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4;
- /* int period_bytes = 0; */
- snd_pcm_uframes_t buffer_size = 0;
-
- unsigned int rate = DESIRED_RATE;
-#if 0
- unsigned int per_min = 1;
-#endif
- /* unsigned int per_max = 8; */
- snd_pcm_uframes_t start_threshold, stop_threshold;
-
- err = snd_pcm_open(&handle, dev, stream, O_NONBLOCK);
- if (err < 0) {
- ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err));
- return NULL;
- } else
- ast_log(LOG_DEBUG, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write");
-
- hwparams = alloca(snd_pcm_hw_params_sizeof());
- memset(hwparams, 0, snd_pcm_hw_params_sizeof());
- snd_pcm_hw_params_any(handle, hwparams);
-
- err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
- if (err < 0)
- ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err));
-
- err = snd_pcm_hw_params_set_format(handle, hwparams, format);
- if (err < 0)
- ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err));
-
- err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
- if (err < 0)
- ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
-
- direction = 0;
- err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
- if (rate != DESIRED_RATE)
- ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate);
-
- direction = 0;
- err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
- if (err < 0)
- ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err));
- else
- ast_log(LOG_DEBUG, "Period size is %d\n", err);
-
- buffer_size = 4096 * 2; /* period_size * 16; */
- err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
- if (err < 0)
- ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err));
- else
- ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err);
-
-#if 0
- direction = 0;
- err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction);
- if (err < 0)
- ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err));
-
- err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0);
- if (err < 0)
- ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err));
-#endif
-
- err = snd_pcm_hw_params(handle, hwparams);
- if (err < 0)
- ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err));
-
- swparams = alloca(snd_pcm_sw_params_sizeof());
- memset(swparams, 0, snd_pcm_sw_params_sizeof());
- snd_pcm_sw_params_current(handle, swparams);
-
-#if 1
- if (stream == SND_PCM_STREAM_PLAYBACK)
- start_threshold = period_size;
- else
- start_threshold = 1;
-
- err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
- if (err < 0)
- ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err));
-#endif
-
-#if 1
- if (stream == SND_PCM_STREAM_PLAYBACK)
- stop_threshold = buffer_size;
- else
- stop_threshold = buffer_size;
-
- err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
- if (err < 0)
- ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err));
-#endif
-#if 0
- err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES);
- if (err < 0)
- ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err));
-#endif
-
-#if 0
- err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold);
- if (err < 0)
- ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err));
-#endif
- err = snd_pcm_sw_params(handle, swparams);
- if (err < 0)
- ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
-
- err = snd_pcm_poll_descriptors_count(handle);
- if (err <= 0)
- ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
- if (err != 1)
- ast_log(LOG_DEBUG, "Can't handle more than one device\n");
-
- snd_pcm_poll_descriptors(handle, &pfd, err);
- ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd);
-
- if (stream == SND_PCM_STREAM_CAPTURE)
- readdev = pfd.fd;
- else
- writedev = pfd.fd;
-
- return handle;
-}
-
-static int soundcard_init(void)
-{
- alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE);
- alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK);
-
- if (!alsa.icard || !alsa.ocard) {
- ast_log(LOG_ERROR, "Problem opening alsa I/O devices\n");
- return -1;
- }
-
- return readdev;
-}
-
-static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration)
-{
- ast_mutex_lock(&alsalock);
- ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
- digit, duration);
- ast_mutex_unlock(&alsalock);
- return 0;
-}
-
-static int alsa_text(struct ast_channel *c, const char *text)
-{
- ast_mutex_lock(&alsalock);
- ast_verbose(" << Console Received text %s >> \n", text);
- ast_mutex_unlock(&alsalock);
- return 0;
-}
-
-static void grab_owner(void)
-{
- while (alsa.owner && ast_mutex_trylock(&alsa.owner->lock)) {
- ast_mutex_unlock(&alsalock);
- usleep(1);
- ast_mutex_lock(&alsalock);
- }
-}
-
-static int alsa_call(struct ast_channel *c, char *dest, int timeout)
-{
- int res = 3;
- struct ast_frame f = { AST_FRAME_CONTROL };
- ast_mutex_lock(&alsalock);
- ast_verbose(" << Call placed to '%s' on console >> \n", dest);
- if (autoanswer) {
- ast_verbose(" << Auto-answered >> \n");
- grab_owner();
- if (alsa.owner) {
- f.subclass = AST_CONTROL_ANSWER;
- ast_queue_frame(alsa.owner, &f);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- } else {
- ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
- grab_owner();
- if (alsa.owner) {
- f.subclass = AST_CONTROL_RINGING;
- ast_queue_frame(alsa.owner, &f);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- write(sndcmd[1], &res, sizeof(res));
- }
- snd_pcm_prepare(alsa.icard);
- snd_pcm_start(alsa.icard);
- ast_mutex_unlock(&alsalock);
- return 0;
-}
-
-static void answer_sound(void)
-{
- int res;
- nosound = 1;
- res = 4;
- write(sndcmd[1], &res, sizeof(res));
-
-}
-
-static int alsa_answer(struct ast_channel *c)
-{
- ast_mutex_lock(&alsalock);
- ast_verbose(" << Console call has been answered >> \n");
- answer_sound();
- ast_setstate(c, AST_STATE_UP);
- cursound = -1;
- snd_pcm_prepare(alsa.icard);
- snd_pcm_start(alsa.icard);
- ast_mutex_unlock(&alsalock);
- return 0;
-}
-
-static int alsa_hangup(struct ast_channel *c)
-{
- int res;
- ast_mutex_lock(&alsalock);
- cursound = -1;
- c->tech_pvt = NULL;
- alsa.owner = NULL;
- ast_verbose(" << Hangup on console >> \n");
- ast_module_unref(ast_module_info->self);
- if (hookstate) {
- hookstate = 0;
- if (!autoanswer) {
- /* Congestion noise */
- res = 2;
- write(sndcmd[1], &res, sizeof(res));
- }
- }
- snd_pcm_drop(alsa.icard);
- ast_mutex_unlock(&alsalock);
- return 0;
-}
-
-static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
-{
- static char sizbuf[8000];
- static int sizpos = 0;
- int len = sizpos;
- int pos;
- int res = 0;
- /* size_t frames = 0; */
- snd_pcm_state_t state;
-
- /* Immediately return if no sound is enabled */
- if (nosound)
- return 0;
-
- ast_mutex_lock(&alsalock);
- /* Stop any currently playing sound */
- if (cursound != -1) {
- snd_pcm_drop(alsa.ocard);
- snd_pcm_prepare(alsa.ocard);
- cursound = -1;
- }
-
-
- /* We have to digest the frame in 160-byte portions */
- if (f->datalen > sizeof(sizbuf) - sizpos) {
- ast_log(LOG_WARNING, "Frame too large\n");
- res = -1;
- } else {
- memcpy(sizbuf + sizpos, f->data, f->datalen);
- len += f->datalen;
- pos = 0;
-#ifdef ALSA_MONITOR
- alsa_monitor_write(sizbuf, len);
-#endif
- state = snd_pcm_state(alsa.ocard);
- if (state == SND_PCM_STATE_XRUN)
- snd_pcm_prepare(alsa.ocard);
- res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
- if (res == -EPIPE) {
-#if DEBUG
- ast_log(LOG_DEBUG, "XRUN write\n");
-#endif
- snd_pcm_prepare(alsa.ocard);
- res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
- if (res != len / 2) {
- ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res));
- res = -1;
- } else if (res < 0) {
- ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res));
- res = -1;
- }
- } else {
- if (res == -ESTRPIPE)
- ast_log(LOG_ERROR, "You've got some big problems\n");
- else if (res < 0)
- ast_log(LOG_NOTICE, "Error %d on write\n", res);
- }
- }
- ast_mutex_unlock(&alsalock);
- if (res > 0)
- res = 0;
- return res;
-}
-
-
-static struct ast_frame *alsa_read(struct ast_channel *chan)
-{
- static struct ast_frame f;
- static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2];
- short *buf;
- static int readpos = 0;
- static int left = FRAME_SIZE;
- snd_pcm_state_t state;
- int r = 0;
- int off = 0;
-
- ast_mutex_lock(&alsalock);
- /* Acknowledge any pending cmd */
- f.frametype = AST_FRAME_NULL;
- f.subclass = 0;
- f.samples = 0;
- f.datalen = 0;
- f.data = NULL;
- f.offset = 0;
- f.src = "Console";
- f.mallocd = 0;
- f.delivery.tv_sec = 0;
- f.delivery.tv_usec = 0;
-
- state = snd_pcm_state(alsa.icard);
- if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) {
- snd_pcm_prepare(alsa.icard);
- }
-
- buf = __buf + AST_FRIENDLY_OFFSET / 2;
-
- r = snd_pcm_readi(alsa.icard, buf + readpos, left);
- if (r == -EPIPE) {
-#if DEBUG
- ast_log(LOG_ERROR, "XRUN read\n");
-#endif
- snd_pcm_prepare(alsa.icard);
- } else if (r == -ESTRPIPE) {
- ast_log(LOG_ERROR, "-ESTRPIPE\n");
- snd_pcm_prepare(alsa.icard);
- } else if (r < 0) {
- ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
- } else if (r >= 0) {
- off -= r;
- }
- /* Update positions */
- readpos += r;
- left -= r;
-
- if (readpos >= FRAME_SIZE) {
- /* A real frame */
- readpos = 0;
- left = FRAME_SIZE;
- if (chan->_state != AST_STATE_UP) {
- /* Don't transmit unless it's up */
- ast_mutex_unlock(&alsalock);
- return &f;
- }
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.samples = FRAME_SIZE;
- f.datalen = FRAME_SIZE * 2;
- f.data = buf;
- f.offset = AST_FRIENDLY_OFFSET;
- f.src = "Console";
- f.mallocd = 0;
-#ifdef ALSA_MONITOR
- alsa_monitor_read((char *) buf, FRAME_SIZE * 2);
-#endif
-
- }
- ast_mutex_unlock(&alsalock);
- return &f;
-}
-
-static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct chan_alsa_pvt *p = newchan->tech_pvt;
- ast_mutex_lock(&alsalock);
- p->owner = newchan;
- ast_mutex_unlock(&alsalock);
- return 0;
-}
-
-static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
-{
- int res = 0;
-
- ast_mutex_lock(&alsalock);
-
- switch (cond) {
- case AST_CONTROL_BUSY:
- res = 1;
- break;
- case AST_CONTROL_CONGESTION:
- res = 2;
- break;
- case AST_CONTROL_RINGING:
- case AST_CONTROL_PROGRESS:
- break;
- case -1:
- res = -1;
- break;
- case AST_CONTROL_VIDUPDATE:
- res = -1;
- break;
- case AST_CONTROL_HOLD:
- ast_verbose(" << Console Has Been Placed on Hold >> \n");
- ast_moh_start(chan, data, mohinterpret);
- break;
- case AST_CONTROL_UNHOLD:
- ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
- ast_moh_stop(chan);
- break;
- case AST_CONTROL_SRCUPDATE:
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
- res = -1;
- }
-
- if (res > -1)
- write(sndcmd[1], &res, sizeof(res));
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
-{
- struct ast_channel *tmp = NULL;
-
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "ALSA/%s", indevname)))
- return NULL;
-
- tmp->tech = &alsa_tech;
- tmp->fds[0] = readdev;
- tmp->nativeformats = AST_FORMAT_SLINEAR;
- tmp->readformat = AST_FORMAT_SLINEAR;
- tmp->writeformat = AST_FORMAT_SLINEAR;
- tmp->tech_pvt = p;
- if (!ast_strlen_zero(p->context))
- ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
- if (!ast_strlen_zero(p->exten))
- ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten));
- if (!ast_strlen_zero(language))
- ast_string_field_set(tmp, language, language);
- p->owner = tmp;
- ast_module_ref(ast_module_info->self);
- ast_jb_configure(tmp, &global_jbconf);
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- tmp = NULL;
- }
- }
-
- return tmp;
-}
-
-static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause)
-{
- int oldformat = format;
- struct ast_channel *tmp = NULL;
-
- format &= AST_FORMAT_SLINEAR;
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat);
- return NULL;
- }
-
- ast_mutex_lock(&alsalock);
-
- if (alsa.owner) {
- ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
- *cause = AST_CAUSE_BUSY;
- } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN)))
- ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
-
- ast_mutex_unlock(&alsalock);
-
- return tmp;
-}
-
-static int console_autoanswer_deprecated(int fd, int argc, char *argv[])
-{
- int res = RESULT_SUCCESS;
-
- if ((argc != 1) && (argc != 2))
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (argc == 1) {
- ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
- } else {
- if (!strcasecmp(argv[1], "on"))
- autoanswer = -1;
- else if (!strcasecmp(argv[1], "off"))
- autoanswer = 0;
- else
- res = RESULT_SHOWUSAGE;
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static int console_autoanswer(int fd, int argc, char *argv[])
-{
- int res = RESULT_SUCCESS;;
- if ((argc != 2) && (argc != 3))
- return RESULT_SHOWUSAGE;
- ast_mutex_lock(&alsalock);
- if (argc == 2) {
- ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
- } else {
- if (!strcasecmp(argv[2], "on"))
- autoanswer = -1;
- else if (!strcasecmp(argv[2], "off"))
- autoanswer = 0;
- else
- res = RESULT_SHOWUSAGE;
- }
- ast_mutex_unlock(&alsalock);
- return res;
-}
-
-static char *autoanswer_complete(const char *line, const char *word, int pos, int state)
-{
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
- switch (state) {
- case 0:
- if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
- return ast_strdup("on");
- case 1:
- if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
- return ast_strdup("off");
- default:
- return NULL;
- }
- return NULL;
-}
-
-static const char autoanswer_usage[] =
- "Usage: console autoanswer [on|off]\n"
- " Enables or disables autoanswer feature. If used without\n"
- " argument, displays the current on/off status of autoanswer.\n"
- " The default value of autoanswer is in 'alsa.conf'.\n";
-
-static int console_answer_deprecated(int fd, int argc, char *argv[])
-{
- int res = RESULT_SUCCESS;
-
- if (argc != 1)
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (!alsa.owner) {
- ast_cli(fd, "No one is calling us\n");
- res = RESULT_FAILURE;
- } else {
- hookstate = 1;
- cursound = -1;
- grab_owner();
- if (alsa.owner) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- ast_queue_frame(alsa.owner, &f);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- answer_sound();
- }
-
- snd_pcm_prepare(alsa.icard);
- snd_pcm_start(alsa.icard);
-
- ast_mutex_unlock(&alsalock);
-
- return RESULT_SUCCESS;
-}
-
-static int console_answer(int fd, int argc, char *argv[])
-{
- int res = RESULT_SUCCESS;
-
- if (argc != 2)
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (!alsa.owner) {
- ast_cli(fd, "No one is calling us\n");
- res = RESULT_FAILURE;
- } else {
- hookstate = 1;
- cursound = -1;
- grab_owner();
- if (alsa.owner) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- ast_queue_frame(alsa.owner, &f);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- answer_sound();
- }
-
- snd_pcm_prepare(alsa.icard);
- snd_pcm_start(alsa.icard);
-
- ast_mutex_unlock(&alsalock);
-
- return RESULT_SUCCESS;
-}
-
-static char sendtext_usage[] =
- "Usage: console send text <message>\n"
- " Sends a text message for display on the remote terminal.\n";
-
-static int console_sendtext_deprecated(int fd, int argc, char *argv[])
-{
- int tmparg = 2;
- int res = RESULT_SUCCESS;
-
- if (argc < 2)
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (!alsa.owner) {
- ast_cli(fd, "No one is calling us\n");
- res = RESULT_FAILURE;
- } else {
- struct ast_frame f = { AST_FRAME_TEXT, 0 };
- char text2send[256] = "";
- text2send[0] = '\0';
- while (tmparg < argc) {
- strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
- strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
- }
- text2send[strlen(text2send) - 1] = '\n';
- f.data = text2send;
- f.datalen = strlen(text2send) + 1;
- grab_owner();
- if (alsa.owner) {
- ast_queue_frame(alsa.owner, &f);
- f.frametype = AST_FRAME_CONTROL;
- f.subclass = AST_CONTROL_ANSWER;
- f.data = NULL;
- f.datalen = 0;
- ast_queue_frame(alsa.owner, &f);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static int console_sendtext(int fd, int argc, char *argv[])
-{
- int tmparg = 3;
- int res = RESULT_SUCCESS;
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (!alsa.owner) {
- ast_cli(fd, "No one is calling us\n");
- res = RESULT_FAILURE;
- } else {
- struct ast_frame f = { AST_FRAME_TEXT, 0 };
- char text2send[256] = "";
- text2send[0] = '\0';
- while (tmparg < argc) {
- strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
- strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
- }
- text2send[strlen(text2send) - 1] = '\n';
- f.data = text2send;
- f.datalen = strlen(text2send) + 1;
- grab_owner();
- if (alsa.owner) {
- ast_queue_frame(alsa.owner, &f);
- f.frametype = AST_FRAME_CONTROL;
- f.subclass = AST_CONTROL_ANSWER;
- f.data = NULL;
- f.datalen = 0;
- ast_queue_frame(alsa.owner, &f);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static char answer_usage[] =
- "Usage: console answer\n"
- " Answers an incoming call on the console (ALSA) channel.\n";
-
-static int console_hangup_deprecated(int fd, int argc, char *argv[])
-{
- int res = RESULT_SUCCESS;
-
- if (argc != 1)
- return RESULT_SHOWUSAGE;
-
- cursound = -1;
-
- ast_mutex_lock(&alsalock);
-
- if (!alsa.owner && !hookstate) {
- ast_cli(fd, "No call to hangup up\n");
- res = RESULT_FAILURE;
- } else {
- hookstate = 0;
- grab_owner();
- if (alsa.owner) {
- ast_queue_hangup(alsa.owner);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static int console_hangup(int fd, int argc, char *argv[])
-{
- int res = RESULT_SUCCESS;
-
- if (argc != 2)
- return RESULT_SHOWUSAGE;
-
- cursound = -1;
-
- ast_mutex_lock(&alsalock);
-
- if (!alsa.owner && !hookstate) {
- ast_cli(fd, "No call to hangup up\n");
- res = RESULT_FAILURE;
- } else {
- hookstate = 0;
- grab_owner();
- if (alsa.owner) {
- ast_queue_hangup(alsa.owner);
- ast_mutex_unlock(&alsa.owner->lock);
- }
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static char hangup_usage[] =
- "Usage: console hangup\n"
- " Hangs up any call currently placed on the console.\n";
-
-static int console_dial_deprecated(int fd, int argc, char *argv[])
-{
- char tmp[256], *tmp2;
- char *mye, *myc;
- char *d;
- int res = RESULT_SUCCESS;
-
- if ((argc != 1) && (argc != 2))
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (alsa.owner) {
- if (argc == 2) {
- d = argv[1];
- grab_owner();
- if (alsa.owner) {
- struct ast_frame f = { AST_FRAME_DTMF };
- while (*d) {
- f.subclass = *d;
- ast_queue_frame(alsa.owner, &f);
- d++;
- }
- ast_mutex_unlock(&alsa.owner->lock);
- }
- } else {
- ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
- res = RESULT_FAILURE;
- }
- } else {
- mye = exten;
- myc = context;
- if (argc == 2) {
- char *stringp = NULL;
- ast_copy_string(tmp, argv[1], sizeof(tmp));
- stringp = tmp;
- strsep(&stringp, "@");
- tmp2 = strsep(&stringp, "@");
- if (!ast_strlen_zero(tmp))
- mye = tmp;
- if (!ast_strlen_zero(tmp2))
- myc = tmp2;
- }
- if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
- ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
- ast_copy_string(alsa.context, myc, sizeof(alsa.context));
- hookstate = 1;
- alsa_new(&alsa, AST_STATE_RINGING);
- } else
- ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static int console_dial(int fd, int argc, char *argv[])
-{
- char tmp[256], *tmp2;
- char *mye, *myc;
- char *d;
- int res = RESULT_SUCCESS;
-
- if ((argc != 2) && (argc != 3))
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&alsalock);
-
- if (alsa.owner) {
- if (argc == 3) {
- d = argv[2];
- grab_owner();
- if (alsa.owner) {
- struct ast_frame f = { AST_FRAME_DTMF };
- while (*d) {
- f.subclass = *d;
- ast_queue_frame(alsa.owner, &f);
- d++;
- }
- ast_mutex_unlock(&alsa.owner->lock);
- }
- } else {
- ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
- res = RESULT_FAILURE;
- }
- } else {
- mye = exten;
- myc = context;
- if (argc == 3) {
- char *stringp = NULL;
- ast_copy_string(tmp, argv[2], sizeof(tmp));
- stringp = tmp;
- strsep(&stringp, "@");
- tmp2 = strsep(&stringp, "@");
- if (!ast_strlen_zero(tmp))
- mye = tmp;
- if (!ast_strlen_zero(tmp2))
- myc = tmp2;
- }
- if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
- ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
- ast_copy_string(alsa.context, myc, sizeof(alsa.context));
- hookstate = 1;
- alsa_new(&alsa, AST_STATE_RINGING);
- } else
- ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
- }
-
- ast_mutex_unlock(&alsalock);
-
- return res;
-}
-
-static char dial_usage[] =
- "Usage: console dial [extension[@context]]\n"
- " Dials a given extension (and context if specified)\n";
-
-static struct ast_cli_entry cli_alsa_answer_deprecated = {
- { "answer", NULL },
- console_answer_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_alsa_hangup_deprecated = {
- { "hangup", NULL },
- console_hangup_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_alsa_dial_deprecated = {
- { "dial", NULL },
- console_dial_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_alsa_send_text_deprecated = {
- { "send", "text", NULL },
- console_sendtext_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_alsa_autoanswer_deprecated = {
- { "autoanswer", NULL },
- console_autoanswer_deprecated, NULL,
- NULL, autoanswer_complete };
-
-static struct ast_cli_entry cli_alsa[] = {
- { { "console", "answer", NULL },
- console_answer, "Answer an incoming console call",
- answer_usage, NULL, &cli_alsa_answer_deprecated },
-
- { { "console", "hangup", NULL },
- console_hangup, "Hangup a call on the console",
- hangup_usage, NULL, &cli_alsa_hangup_deprecated },
-
- { { "console", "dial", NULL },
- console_dial, "Dial an extension on the console",
- dial_usage, NULL, &cli_alsa_dial_deprecated },
-
- { { "console", "send", "text", NULL },
- console_sendtext, "Send text to the remote device",
- sendtext_usage, NULL, &cli_alsa_send_text_deprecated },
-
- { { "console", "autoanswer", NULL },
- console_autoanswer, "Sets/displays autoanswer",
- autoanswer_usage, autoanswer_complete, &cli_alsa_autoanswer_deprecated },
-};
-
-static int load_module(void)
-{
- int res;
- struct ast_config *cfg;
- struct ast_variable *v;
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- strcpy(mohinterpret, "default");
-
- if ((cfg = ast_config_load(config))) {
- v = ast_variable_browse(cfg, "general");
- for (; v; v = v->next) {
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
- continue;
-
- if (!strcasecmp(v->name, "autoanswer"))
- autoanswer = ast_true(v->value);
- else if (!strcasecmp(v->name, "silencesuppression"))
- silencesuppression = ast_true(v->value);
- else if (!strcasecmp(v->name, "silencethreshold"))
- silencethreshold = atoi(v->value);
- else if (!strcasecmp(v->name, "context"))
- ast_copy_string(context, v->value, sizeof(context));
- else if (!strcasecmp(v->name, "language"))
- ast_copy_string(language, v->value, sizeof(language));
- else if (!strcasecmp(v->name, "extension"))
- ast_copy_string(exten, v->value, sizeof(exten));
- else if (!strcasecmp(v->name, "input_device"))
- ast_copy_string(indevname, v->value, sizeof(indevname));
- else if (!strcasecmp(v->name, "output_device"))
- ast_copy_string(outdevname, v->value, sizeof(outdevname));
- else if (!strcasecmp(v->name, "mohinterpret"))
- ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
- }
- ast_config_destroy(cfg);
- }
- res = pipe(sndcmd);
- if (res) {
- ast_log(LOG_ERROR, "Unable to create pipe\n");
- return -1;
- }
- res = soundcard_init();
- if (res < 0) {
- if (option_verbose > 1) {
- ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
- ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
- }
- return 0;
- }
-
- res = ast_channel_register(&alsa_tech);
- if (res < 0) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
- return -1;
- }
- ast_cli_register_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
-
- ast_pthread_create_background(&sthread, NULL, sound_thread, NULL);
-#ifdef ALSA_MONITOR
- if (alsa_monitor_start())
- ast_log(LOG_ERROR, "Problem starting Monitoring\n");
-#endif
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_channel_unregister(&alsa_tech);
- ast_cli_unregister_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
-
- if (alsa.icard)
- snd_pcm_close(alsa.icard);
- if (alsa.ocard)
- snd_pcm_close(alsa.ocard);
- if (sndcmd[0] > 0) {
- close(sndcmd[0]);
- close(sndcmd[1]);
- }
- if (alsa.owner)
- ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
- if (alsa.owner)
- return -1;
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ALSA Console Channel Driver");
diff --git a/1.4/channels/chan_features.c b/1.4/channels/chan_features.c
deleted file mode 100644
index 043576623..000000000
--- a/1.4/channels/chan_features.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief feature Proxy Channel
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note *** Experimental code ****
- *
- * \ingroup channel_drivers
- */
-/*** MODULEINFO
- <defaultenabled>no</defaultenabled>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/signal.h>
-
-#include "asterisk/lock.h"
-#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/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/manager.h"
-#include "asterisk/stringfields.h"
-
-static const char tdesc[] = "Feature Proxy Channel Driver";
-
-#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
-
-struct feature_sub {
- struct ast_channel *owner;
- int inthreeway;
- int pfd;
- int timingfdbackup;
- int alertpipebackup[2];
-};
-
-struct feature_pvt {
- ast_mutex_t lock; /* Channel private lock */
- char tech[AST_MAX_EXTENSION]; /* Technology to abstract */
- char dest[AST_MAX_EXTENSION]; /* Destination to abstract */
- struct ast_channel *subchan;
- struct feature_sub subs[3]; /* Subs */
- struct ast_channel *owner; /* Current Master Channel */
- AST_LIST_ENTRY(feature_pvt) list; /* Next entity */
-};
-
-static AST_LIST_HEAD_STATIC(features, feature_pvt);
-
-#define SUB_REAL 0 /* Active call */
-#define SUB_CALLWAIT 1 /* Call-Waiting call on hold */
-#define SUB_THREEWAY 2 /* Three-way call */
-
-static struct ast_channel *features_request(const char *type, int format, void *data, int *cause);
-static int features_digit_begin(struct ast_channel *ast, char digit);
-static int features_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int features_call(struct ast_channel *ast, char *dest, int timeout);
-static int features_hangup(struct ast_channel *ast);
-static int features_answer(struct ast_channel *ast);
-static struct ast_frame *features_read(struct ast_channel *ast);
-static int features_write(struct ast_channel *ast, struct ast_frame *f);
-static int features_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
-static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-
-static const struct ast_channel_tech features_tech = {
- .type = "Feature",
- .description = tdesc,
- .capabilities = -1,
- .requester = features_request,
- .send_digit_begin = features_digit_begin,
- .send_digit_end = features_digit_end,
- .call = features_call,
- .hangup = features_hangup,
- .answer = features_answer,
- .read = features_read,
- .write = features_write,
- .exception = features_read,
- .indicate = features_indicate,
- .fixup = features_fixup,
-};
-
-static inline void init_sub(struct feature_sub *sub)
-{
- sub->inthreeway = 0;
- sub->pfd = -1;
- sub->timingfdbackup = -1;
- sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1;
-}
-
-static inline int indexof(struct feature_pvt *p, struct ast_channel *owner, int nullok)
-{
- int x;
- if (!owner) {
- ast_log(LOG_WARNING, "indexof called on NULL owner??\n");
- return -1;
- }
- for (x=0; x<3; x++) {
- if (owner == p->subs[x].owner)
- return x;
- }
- return -1;
-}
-
-#if 0
-static void wakeup_sub(struct feature_pvt *p, int a)
-{
- struct ast_frame null = { AST_FRAME_NULL, };
- for (;;) {
- if (p->subs[a].owner) {
- if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- } else {
- ast_queue_frame(p->subs[a].owner, &null);
- ast_mutex_unlock(&p->subs[a].owner->lock);
- break;
- }
- } else
- break;
- }
-}
-#endif
-
-static void restore_channel(struct feature_pvt *p, int index)
-{
- /* Restore timing/alertpipe */
- p->subs[index].owner->timingfd = p->subs[index].timingfdbackup;
- p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0];
- p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1];
- p->subs[index].owner->fds[AST_ALERT_FD] = p->subs[index].alertpipebackup[0];
- p->subs[index].owner->fds[AST_TIMING_FD] = p->subs[index].timingfdbackup;
-}
-
-static void update_features(struct feature_pvt *p, int index)
-{
- int x;
- if (p->subs[index].owner) {
- for (x=0; x<AST_MAX_FDS; x++) {
- if (index)
- p->subs[index].owner->fds[x] = -1;
- else
- p->subs[index].owner->fds[x] = p->subchan->fds[x];
- }
- if (!index) {
- /* Copy timings from master channel */
- p->subs[index].owner->timingfd = p->subchan->timingfd;
- p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0];
- p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1];
- if (p->subs[index].owner->nativeformats != p->subchan->readformat) {
- p->subs[index].owner->nativeformats = p->subchan->readformat;
- if (p->subs[index].owner->readformat)
- ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat);
- if (p->subs[index].owner->writeformat)
- ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat);
- }
- } else{
- restore_channel(p, index);
- }
- }
-}
-
-#if 0
-static void swap_subs(struct feature_pvt *p, int a, int b)
-{
- int tinthreeway;
- struct ast_channel *towner;
-
- ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
-
- towner = p->subs[a].owner;
- tinthreeway = p->subs[a].inthreeway;
-
- p->subs[a].owner = p->subs[b].owner;
- p->subs[a].inthreeway = p->subs[b].inthreeway;
-
- p->subs[b].owner = towner;
- p->subs[b].inthreeway = tinthreeway;
- update_features(p,a);
- update_features(p,b);
- wakeup_sub(p, a);
- wakeup_sub(p, b);
-}
-#endif
-
-static int features_answer(struct ast_channel *ast)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int res = -1;
- int x;
-
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan)
- res = ast_answer(p->subchan);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static struct ast_frame *features_read(struct ast_channel *ast)
-{
- struct feature_pvt *p = ast->tech_pvt;
- struct ast_frame *f;
- int x;
-
- f = &ast_null_frame;
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan) {
- update_features(p, x);
- f = ast_read(p->subchan);
- }
- ast_mutex_unlock(&p->lock);
- return f;
-}
-
-static int features_write(struct ast_channel *ast, struct ast_frame *f)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int res = -1;
- int x;
-
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan)
- res = ast_write(p->subchan, f);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct feature_pvt *p = newchan->tech_pvt;
- int x;
-
- ast_mutex_lock(&p->lock);
- if (p->owner == oldchan)
- p->owner = newchan;
- for (x = 0; x < 3; x++) {
- if (p->subs[x].owner == oldchan)
- p->subs[x].owner = newchan;
- }
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int features_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int res = -1;
- int x;
-
- /* Queue up a frame representing the indication as a control frame */
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan)
- res = ast_indicate(p->subchan, condition);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int features_digit_begin(struct ast_channel *ast, char digit)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int res = -1;
- int x;
-
- /* Queue up a frame representing the indication as a control frame */
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan)
- res = ast_senddigit_begin(p->subchan, digit);
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-static int features_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int res = -1;
- int x;
-
- /* Queue up a frame representing the indication as a control frame */
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan)
- res = ast_senddigit_end(p->subchan, digit, duration);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int features_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int res = -1;
- int x;
- char *dest2;
-
- dest2 = strchr(dest, '/');
- if (dest2) {
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (!x && p->subchan) {
- p->subchan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
- p->subchan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
- p->subchan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
- p->subchan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
-
- p->subchan->cid.cid_pres = p->owner->cid.cid_pres;
- ast_string_field_set(p->subchan, language, p->owner->language);
- ast_string_field_set(p->subchan, accountcode, p->owner->accountcode);
- p->subchan->cdrflags = p->owner->cdrflags;
- res = ast_call(p->subchan, dest2, timeout);
- update_features(p, x);
- } else
- ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n");
- ast_mutex_unlock(&p->lock);
- }
- return res;
-}
-
-static int features_hangup(struct ast_channel *ast)
-{
- struct feature_pvt *p = ast->tech_pvt;
- int x;
-
- ast_mutex_lock(&p->lock);
- x = indexof(p, ast, 0);
- if (x > -1) {
- restore_channel(p, x);
- p->subs[x].owner = NULL;
- /* XXX Re-arrange, unconference, etc XXX */
- }
- ast->tech_pvt = NULL;
-
- if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
- ast_mutex_unlock(&p->lock);
- /* Remove from list */
- AST_LIST_LOCK(&features);
- AST_LIST_REMOVE(&features, p, list);
- AST_LIST_UNLOCK(&features);
- ast_mutex_lock(&p->lock);
- /* And destroy */
- if (p->subchan)
- ast_hangup(p->subchan);
- ast_mutex_unlock(&p->lock);
- ast_mutex_destroy(&p->lock);
- free(p);
- return 0;
- }
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static struct feature_pvt *features_alloc(char *data, int format)
-{
- struct feature_pvt *tmp;
- char *dest=NULL;
- char *tech;
- int x;
- int status;
- struct ast_channel *chan;
-
- tech = ast_strdupa(data);
- if (tech) {
- dest = strchr(tech, '/');
- if (dest) {
- *dest = '\0';
- dest++;
- }
- }
- if (!tech || !dest) {
- ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n",
- data);
- return NULL;
- }
- AST_LIST_LOCK(&features);
- AST_LIST_TRAVERSE(&features, tmp, list) {
- if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest))
- break;
- }
- AST_LIST_UNLOCK(&features);
- if (!tmp) {
- chan = ast_request(tech, format, dest, &status);
- if (!chan) {
- ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest);
- return NULL;
- }
- tmp = malloc(sizeof(struct feature_pvt));
- if (tmp) {
- memset(tmp, 0, sizeof(struct feature_pvt));
- for (x=0;x<3;x++)
- init_sub(tmp->subs + x);
- ast_mutex_init(&tmp->lock);
- ast_copy_string(tmp->tech, tech, sizeof(tmp->tech));
- ast_copy_string(tmp->dest, dest, sizeof(tmp->dest));
- tmp->subchan = chan;
- AST_LIST_LOCK(&features);
- AST_LIST_INSERT_HEAD(&features, tmp, list);
- AST_LIST_UNLOCK(&features);
- }
- }
- return tmp;
-}
-
-static struct ast_channel *features_new(struct feature_pvt *p, int state, int index)
-{
- struct ast_channel *tmp;
- int x,y;
- char *b2 = 0;
- if (!p->subchan) {
- ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n");
- return NULL;
- }
- if (p->subs[index].owner) {
- ast_log(LOG_WARNING, "Called to put index %d already there!\n", index);
- return NULL;
- }
- /* figure out what you want the name to be */
- for (x=1;x<4;x++) {
- if (b2)
- free(b2);
- b2 = ast_safe_string_alloc("%s/%s-%d", p->tech, p->dest, x);
- for (y=0;y<3;y++) {
- if (y == index)
- continue;
- if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, b2))
- break;
- }
- if (y >= 3)
- break;
- }
- tmp = ast_channel_alloc(0, state, 0,0, "", "", "", 0, "Feature/%s", b2);
- /* free up the name, it was copied into the channel name */
- if (b2)
- free(b2);
- if (!tmp) {
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- return NULL;
- }
- tmp->tech = &features_tech;
- tmp->writeformat = p->subchan->writeformat;
- tmp->rawwriteformat = p->subchan->rawwriteformat;
- tmp->readformat = p->subchan->readformat;
- tmp->rawreadformat = p->subchan->rawreadformat;
- tmp->nativeformats = p->subchan->readformat;
- tmp->tech_pvt = p;
- p->subs[index].owner = tmp;
- if (!p->owner)
- p->owner = tmp;
- ast_module_ref(ast_module_info->self);
- return tmp;
-}
-
-
-static struct ast_channel *features_request(const char *type, int format, void *data, int *cause)
-{
- struct feature_pvt *p;
- struct ast_channel *chan = NULL;
-
- p = features_alloc(data, format);
- if (p && !p->subs[SUB_REAL].owner)
- chan = features_new(p, AST_STATE_DOWN, SUB_REAL);
- if (chan)
- update_features(p,SUB_REAL);
- return chan;
-}
-
-static int features_show(int fd, int argc, char **argv)
-{
- struct feature_pvt *p;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- if (AST_LIST_EMPTY(&features)) {
- ast_cli(fd, "No feature channels in use\n");
- return RESULT_SUCCESS;
- }
-
- AST_LIST_LOCK(&features);
- AST_LIST_TRAVERSE(&features, p, list) {
- ast_mutex_lock(&p->lock);
- ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest);
- ast_mutex_unlock(&p->lock);
- }
- AST_LIST_UNLOCK(&features);
- return RESULT_SUCCESS;
-}
-
-static char show_features_usage[] =
-"Usage: feature show channels\n"
-" Provides summary information on feature channels.\n";
-
-static struct ast_cli_entry cli_features[] = {
- { { "feature", "show", "channels", NULL },
- features_show, "List status of feature channels",
- show_features_usage },
-};
-
-static int load_module(void)
-{
- /* Make sure we can register our sip channel type */
- if (ast_channel_register(&features_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Feature'\n");
- return -1;
- }
- ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-static int unload_module(void)
-{
- struct feature_pvt *p;
-
- /* First, take us out of the channel loop */
- ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
- ast_channel_unregister(&features_tech);
-
- if (!AST_LIST_LOCK(&features))
- return -1;
- /* Hangup all interfaces if they have an owner */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&features, p, list) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- AST_LIST_REMOVE_CURRENT(&features, list);
- free(p);
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&features);
-
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Feature Proxy Channel");
-
diff --git a/1.4/channels/chan_gtalk.c b/1.4/channels/chan_gtalk.c
deleted file mode 100644
index 5ffcdde00..000000000
--- a/1.4/channels/chan_gtalk.c
+++ /dev/null
@@ -1,2049 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Matt O'Gorman <mogorman@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.
- */
-
-/*! \file
- *
- * \author Matt O'Gorman <mogorman@digium.com>
- *
- * \brief Gtalk Channel Driver, until google/libjingle works with jingle spec
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>iksemel</depend>
- <depend>res_jabber</depend>
- <use>gnutls</use>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/signal.h>
-#include <iksemel.h>
-#include <pthread.h>
-
-#ifdef HAVE_GNUTLS
-#include <gcrypt.h>
-GCRY_THREAD_OPTION_PTHREAD_IMPL;
-#endif /* HAVE_GNUTLS */
-
-#include "asterisk/lock.h"
-#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/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/manager.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/astobj.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/jabber.h"
-
-#define GOOGLE_CONFIG "gtalk.conf"
-
-#define GOOGLE_NS "http://www.google.com/session"
-
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-enum gtalk_protocol {
- AJI_PROTOCOL_UDP = 1,
- AJI_PROTOCOL_SSLTCP = 2,
-};
-
-enum gtalk_connect_type {
- AJI_CONNECT_STUN = 1,
- AJI_CONNECT_LOCAL = 2,
- AJI_CONNECT_RELAY = 3,
-};
-
-struct gtalk_pvt {
- ast_mutex_t lock; /*!< Channel private lock */
- time_t laststun;
- struct gtalk *parent; /*!< Parent client */
- char sid[100];
- char us[AJI_MAX_JIDLEN];
- char them[AJI_MAX_JIDLEN];
- char ring[10]; /*!< Message ID of ring */
- iksrule *ringrule; /*!< Rule for matching RING request */
- int initiator; /*!< If we're the initiator */
- int alreadygone;
- int capability;
- struct ast_codec_pref prefs;
- struct gtalk_candidate *theircandidates;
- struct gtalk_candidate *ourcandidates;
- char cid_num[80]; /*!< Caller ID num */
- char cid_name[80]; /*!< Caller ID name */
- char exten[80]; /*!< Called extension */
- struct ast_channel *owner; /*!< Master Channel */
- struct ast_rtp *rtp; /*!< RTP audio session */
- struct ast_rtp *vrtp; /*!< RTP video session */
- int jointcapability; /*!< Supported capability at both ends (codecs ) */
- int peercapability;
- struct gtalk_pvt *next; /* Next entity */
-};
-
-struct gtalk_candidate {
- char name[100];
- enum gtalk_protocol protocol;
- double preference;
- char username[100];
- char password[100];
- enum gtalk_connect_type type;
- char network[6];
- int generation;
- char ip[16];
- int port;
- int receipt;
- struct gtalk_candidate *next;
-};
-
-struct gtalk {
- ASTOBJ_COMPONENTS(struct gtalk);
- struct aji_client *connection;
- struct aji_buddy *buddy;
- struct gtalk_pvt *p;
- struct ast_codec_pref prefs;
- int amaflags; /*!< AMA Flags */
- char user[AJI_MAX_JIDLEN];
- char context[AST_MAX_CONTEXT];
- char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
- int capability;
- ast_group_t callgroup; /*!< Call group */
- ast_group_t pickupgroup; /*!< Pickup group */
- int callingpres; /*!< Calling presentation */
- int allowguest;
- char language[MAX_LANGUAGE]; /*!< Default language for prompts */
- char musicclass[MAX_MUSICCLASS]; /*!< Music on Hold class */
-};
-
-struct gtalk_container {
- ASTOBJ_CONTAINER_COMPONENTS(struct gtalk);
-};
-
-static const char desc[] = "Gtalk Channel";
-
-static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
-
-AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pvt's) */
-
-/* Forward declarations */
-static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause);
-static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);
-static int gtalk_digit_begin(struct ast_channel *ast, char digit);
-static int gtalk_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int gtalk_call(struct ast_channel *ast, char *dest, int timeout);
-static int gtalk_hangup(struct ast_channel *ast);
-static int gtalk_answer(struct ast_channel *ast);
-static int gtalk_action(struct gtalk *client, struct gtalk_pvt *p, const char *action);
-static void gtalk_free_pvt(struct gtalk *client, struct gtalk_pvt *p);
-static int gtalk_newcall(struct gtalk *client, ikspak *pak);
-static struct ast_frame *gtalk_read(struct ast_channel *ast);
-static int gtalk_write(struct ast_channel *ast, struct ast_frame *f);
-static int gtalk_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
-static int gtalk_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static int gtalk_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
-static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid);
-static int gtalk_do_reload(int fd, int argc, char **argv);
-static int gtalk_show_channels(int fd, int argc, char **argv);
-/*----- RTP interface functions */
-static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp,
- struct ast_rtp *vrtp, int codecs, int nat_active);
-static enum ast_rtp_get_result gtalk_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp);
-static int gtalk_get_codec(struct ast_channel *chan);
-
-/*! \brief PBX interface structure for channel registration */
-static const struct ast_channel_tech gtalk_tech = {
- .type = "Gtalk",
- .description = "Gtalk Channel Driver",
- .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
- .requester = gtalk_request,
- .send_digit_begin = gtalk_digit_begin,
- .send_digit_end = gtalk_digit_end,
- .bridge = ast_rtp_bridge,
- .call = gtalk_call,
- .hangup = gtalk_hangup,
- .answer = gtalk_answer,
- .read = gtalk_read,
- .write = gtalk_write,
- .exception = gtalk_read,
- .indicate = gtalk_indicate,
- .fixup = gtalk_fixup,
- .send_html = gtalk_sendhtml,
- .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
-};
-
-static struct sockaddr_in bindaddr = { 0, }; /*!< The address we bind to */
-
-static struct sched_context *sched; /*!< The scheduling context */
-static struct io_context *io; /*!< The IO context */
-static struct in_addr __ourip;
-
-
-/*! \brief RTP driver interface */
-static struct ast_rtp_protocol gtalk_rtp = {
- type: "Gtalk",
- get_rtp_info: gtalk_get_rtp_peer,
- set_rtp_peer: gtalk_set_rtp_peer,
- get_codec: gtalk_get_codec,
-};
-
-static char show_channels_usage[] =
-"Usage: gtalk show channels\n"
-" Shows current state of the Gtalk channels.\n";
-
-static char reload_usage[] =
-"Usage: gtalk reload\n"
-" Reload gtalk channel driver.\n";
-
-
-static struct ast_cli_entry gtalk_cli[] = {
- {{ "gtalk", "reload", NULL}, gtalk_do_reload, "Reload GoogleTalk configuration", reload_usage },
- {{ "gtalk", "show", "channels", NULL}, gtalk_show_channels, "Show GoogleTalk channels", show_channels_usage },
- };
-
-
-
-static char externip[16];
-
-static struct gtalk_container gtalk_list;
-
-static void gtalk_member_destroy(struct gtalk *obj)
-{
- free(obj);
-}
-
-static struct gtalk *find_gtalk(char *name, char *connection)
-{
- struct gtalk *gtalk = NULL;
- char *domain = NULL , *s = NULL;
-
- if(strchr(connection, '@')) {
- s = ast_strdupa(connection);
- domain = strsep(&s, "@");
- ast_verbose("OOOOH domain = %s\n", domain);
- }
- gtalk = ASTOBJ_CONTAINER_FIND(&gtalk_list, name);
- if (!gtalk && strchr(name, '@'))
- gtalk = ASTOBJ_CONTAINER_FIND_FULL(&gtalk_list, name, user,,, strcasecmp);
-
- if (!gtalk) { /* guest call */
- ASTOBJ_CONTAINER_TRAVERSE(&gtalk_list, 1, {
- ASTOBJ_RDLOCK(iterator);
- if (!strcasecmp(iterator->name, "guest")) {
- if (!strcasecmp(iterator->connection->jid->partial, connection)) {
- gtalk = iterator;
- } else if (!strcasecmp(iterator->connection->name, connection)) {
- gtalk = iterator;
- } else if (iterator->connection->component && !strcasecmp(iterator->connection->user,domain)) {
- gtalk = iterator;
- }
- }
- ASTOBJ_UNLOCK(iterator);
-
- if (gtalk)
- break;
- });
-
- }
- return gtalk;
-}
-
-
-static int add_codec_to_answer(const struct gtalk_pvt *p, int codec, iks *dcodecs)
-{
- int res = 0;
- char *format = ast_getformatname(codec);
-
- if (!strcasecmp("ulaw", format)) {
- iks *payload_eg711u, *payload_pcmu;
- payload_pcmu = iks_new("payload-type");
- payload_eg711u = iks_new("payload-type");
-
- if(!payload_eg711u || !payload_pcmu) {
- if(payload_pcmu)
- iks_delete(payload_pcmu);
- if(payload_eg711u)
- iks_delete(payload_eg711u);
- ast_log(LOG_WARNING,"Failed to allocate iks node");
- return -1;
- }
- iks_insert_attrib(payload_pcmu, "id", "0");
- iks_insert_attrib(payload_pcmu, "name", "PCMU");
- iks_insert_attrib(payload_pcmu, "clockrate","8000");
- iks_insert_attrib(payload_pcmu, "bitrate","64000");
- iks_insert_attrib(payload_eg711u, "id", "100");
- iks_insert_attrib(payload_eg711u, "name", "EG711U");
- iks_insert_attrib(payload_eg711u, "clockrate","8000");
- iks_insert_attrib(payload_eg711u, "bitrate","64000");
- iks_insert_node(dcodecs, payload_pcmu);
- iks_insert_node(dcodecs, payload_eg711u);
- res ++;
- }
- if (!strcasecmp("alaw", format)) {
- iks *payload_eg711a, *payload_pcma;
- payload_pcma = iks_new("payload-type");
- payload_eg711a = iks_new("payload-type");
- if(!payload_eg711a || !payload_pcma) {
- if(payload_eg711a)
- iks_delete(payload_eg711a);
- if(payload_pcma)
- iks_delete(payload_pcma);
- ast_log(LOG_WARNING,"Failed to allocate iks node");
- return -1;
- }
- iks_insert_attrib(payload_pcma, "id", "8");
- iks_insert_attrib(payload_pcma, "name", "PCMA");
- iks_insert_attrib(payload_pcma, "clockrate","8000");
- iks_insert_attrib(payload_pcma, "bitrate","64000");
- payload_eg711a = iks_new("payload-type");
- iks_insert_attrib(payload_eg711a, "id", "101");
- iks_insert_attrib(payload_eg711a, "name", "EG711A");
- iks_insert_attrib(payload_eg711a, "clockrate","8000");
- iks_insert_attrib(payload_eg711a, "bitrate","64000");
- iks_insert_node(dcodecs, payload_pcma);
- iks_insert_node(dcodecs, payload_eg711a);
- res ++;
- }
- if (!strcasecmp("ilbc", format)) {
- iks *payload_ilbc = iks_new("payload-type");
- if(!payload_ilbc) {
- ast_log(LOG_WARNING,"Failed to allocate iks node");
- return -1;
- }
- iks_insert_attrib(payload_ilbc, "id", "97");
- iks_insert_attrib(payload_ilbc, "name", "iLBC");
- iks_insert_attrib(payload_ilbc, "clockrate","8000");
- iks_insert_attrib(payload_ilbc, "bitrate","13300");
- iks_insert_node(dcodecs, payload_ilbc);
- res ++;
- }
- if (!strcasecmp("g723", format)) {
- iks *payload_g723 = iks_new("payload-type");
- if(!payload_g723) {
- ast_log(LOG_WARNING,"Failed to allocate iks node");
- return -1;
- }
- iks_insert_attrib(payload_g723, "id", "4");
- iks_insert_attrib(payload_g723, "name", "G723");
- iks_insert_attrib(payload_g723, "clockrate","8000");
- iks_insert_attrib(payload_g723, "bitrate","6300");
- iks_insert_node(dcodecs, payload_g723);
- res ++;
- }
- if (!strcasecmp("speex", format)) {
- iks *payload_speex = iks_new("payload-type");
- if(!payload_speex) {
- ast_log(LOG_WARNING,"Failed to allocate iks node");
- return -1;
- }
- iks_insert_attrib(payload_speex, "id", "110");
- iks_insert_attrib(payload_speex, "name", "speex");
- iks_insert_attrib(payload_speex, "clockrate","8000");
- iks_insert_attrib(payload_speex, "bitrate","11000");
- iks_insert_node(dcodecs, payload_speex);
- res++;
- }
- if (!strcasecmp("gsm", format)) {
- iks *payload_gsm = iks_new("payload-type");
- if(!payload_gsm) {
- ast_log(LOG_WARNING,"Failed to allocate iks node");
- return -1;
- }
- iks_insert_attrib(payload_gsm, "id", "103");
- iks_insert_attrib(payload_gsm, "name", "gsm");
- iks_insert_node(dcodecs, payload_gsm);
- res++;
- }
- ast_rtp_lookup_code(p->rtp, 1, codec);
- return res;
-}
-
-static int gtalk_invite(struct gtalk_pvt *p, char *to, char *from, char *sid, int initiator)
-{
- struct gtalk *client = p->parent;
- iks *iq, *gtalk, *dcodecs, *payload_telephone, *transport;
- int x;
- int pref_codec = 0;
- int alreadysent = 0;
- int codecs_num = 0;
-
- iq = iks_new("iq");
- gtalk = iks_new("session");
- dcodecs = iks_new("description");
- transport = iks_new("transport");
- payload_telephone = iks_new("payload-type");
- if (!(iq && gtalk && dcodecs && transport && payload_telephone)){
- if(iq)
- iks_delete(iq);
- if(gtalk)
- iks_delete(gtalk);
- if(dcodecs)
- iks_delete(dcodecs);
- if(transport)
- iks_delete(transport);
- if(payload_telephone)
- iks_delete(payload_telephone);
-
- ast_log(LOG_ERROR, "Could not allocate iksemel nodes\n");
- return 0;
- }
- iks_insert_attrib(dcodecs, "xmlns", "http://www.google.com/session/phone");
- iks_insert_attrib(dcodecs, "xml:lang", "en");
-
- for (x = 0; x < 32; x++) {
- if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
- break;
- if (!(client->capability & pref_codec))
- continue;
- if (alreadysent & pref_codec)
- continue;
- codecs_num = add_codec_to_answer(p, pref_codec, dcodecs);
- alreadysent |= pref_codec;
- }
-
- if (codecs_num) {
- /* only propose DTMF within an audio session */
- iks_insert_attrib(payload_telephone, "id", "106");
- iks_insert_attrib(payload_telephone, "name", "telephone-event");
- iks_insert_attrib(payload_telephone, "clockrate", "8000");
- }
- iks_insert_attrib(transport,"xmlns","http://www.google.com/transport/p2p");
-
- iks_insert_attrib(iq, "type", "set");
- iks_insert_attrib(iq, "to", to);
- iks_insert_attrib(iq, "from", from);
- iks_insert_attrib(iq, "id", client->connection->mid);
- ast_aji_increment_mid(client->connection->mid);
-
- iks_insert_attrib(gtalk, "xmlns", "http://www.google.com/session");
- iks_insert_attrib(gtalk, "type",initiator ? "initiate": "accept");
- iks_insert_attrib(gtalk, "initiator", initiator ? from : to);
- iks_insert_attrib(gtalk, "id", sid);
- iks_insert_node(iq, gtalk);
- iks_insert_node(gtalk, dcodecs);
- iks_insert_node(gtalk, transport);
- iks_insert_node(dcodecs, payload_telephone);
-
- iks_send(client->connection->p, iq);
- iks_delete(payload_telephone);
- iks_delete(transport);
- iks_delete(dcodecs);
- iks_delete(gtalk);
- iks_delete(iq);
- return 1;
-}
-
-static int gtalk_invite_response(struct gtalk_pvt *p, char *to , char *from, char *sid, int initiator)
-{
- iks *iq, *session, *transport;
- iq = iks_new("iq");
- session = iks_new("session");
- transport = iks_new("transport");
- if(!(iq && session && transport)) {
- if(iq)
- iks_delete(iq);
- if(session)
- iks_delete(session);
- if(transport)
- iks_delete(transport);
- ast_log(LOG_ERROR, " Unable to allocate IKS node\n");
- return -1;
- }
- iks_insert_attrib(iq, "from", from);
- iks_insert_attrib(iq, "to", to);
- iks_insert_attrib(iq, "type", "set");
- iks_insert_attrib(iq, "id",p->parent->connection->mid);
- ast_aji_increment_mid(p->parent->connection->mid);
- iks_insert_attrib(session, "type", "transport-accept");
- iks_insert_attrib(session, "id", sid);
- iks_insert_attrib(session, "initiator", initiator ? from : to);
- iks_insert_attrib(session, "xmlns", "http://www.google.com/session");
- iks_insert_attrib(transport, "xmlns", "http://www.google.com/transport/p2p");
- iks_insert_node(iq,session);
- iks_insert_node(session,transport);
- iks_send(p->parent->connection->p, iq);
- iks_delete(transport);
- iks_delete(session);
- iks_delete(iq);
- return 1;
-
-}
-
-static int gtalk_ringing_ack(void *data, ikspak *pak)
-{
- struct gtalk_pvt *p = data;
-
- if (p->ringrule)
- iks_filter_remove_rule(p->parent->connection->f, p->ringrule);
- p->ringrule = NULL;
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_RINGING);
- return IKS_FILTER_EAT;
-}
-
-static int gtalk_answer(struct ast_channel *ast)
-{
- struct gtalk_pvt *p = ast->tech_pvt;
- int res = 0;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Answer!\n");
- ast_mutex_lock(&p->lock);
- gtalk_invite(p, p->them, p->us,p->sid, 0);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static enum ast_rtp_get_result gtalk_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
-{
- struct gtalk_pvt *p = chan->tech_pvt;
- enum ast_rtp_get_result res = AST_RTP_GET_FAILED;
-
- if (!p)
- return res;
-
- ast_mutex_lock(&p->lock);
- if (p->rtp){
- *rtp = p->rtp;
- res = AST_RTP_TRY_PARTIAL;
- }
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-static int gtalk_get_codec(struct ast_channel *chan)
-{
- struct gtalk_pvt *p = chan->tech_pvt;
- return p->peercapability;
-}
-
-static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
-{
- struct gtalk_pvt *p;
-
- p = chan->tech_pvt;
- if (!p)
- return -1;
- ast_mutex_lock(&p->lock);
-
-/* if (rtp)
- ast_rtp_get_peer(rtp, &p->redirip);
- else
- memset(&p->redirip, 0, sizeof(p->redirip));
- p->redircodecs = codecs; */
-
- /* Reset lastrtprx timer */
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int gtalk_response(struct gtalk *client, char *from, ikspak *pak, const char *reasonstr, const char *reasonstr2)
-{
- iks *response = NULL, *error = NULL, *reason = NULL;
- int res = -1;
-
- response = iks_new("iq");
- if (response) {
- iks_insert_attrib(response, "type", "result");
- iks_insert_attrib(response, "from", from);
- iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from"));
- iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id"));
- if (reasonstr) {
- error = iks_new("error");
- if (error) {
- iks_insert_attrib(error, "type", "cancel");
- reason = iks_new(reasonstr);
- if (reason)
- iks_insert_node(error, reason);
- iks_insert_node(response, error);
- }
- }
- iks_send(client->connection->p, response);
- if (reason)
- iks_delete(reason);
- if (error)
- iks_delete(error);
- iks_delete(response);
- res = 0;
- }
- return res;
-}
-
-static int gtalk_is_answered(struct gtalk *client, ikspak *pak)
-{
- struct gtalk_pvt *tmp;
- char *from;
- iks *codec;
- char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ];
- int peernoncodeccapability;
-
- ast_log(LOG_DEBUG, "The client is %s\n", client->name);
- /* Make sure our new call doesn't exist yet */
- for (tmp = client->p; tmp; tmp = tmp->next) {
- if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))
- break;
- }
-
- /* codec points to the first <payload-type/> tag */
- codec = iks_child(iks_child(iks_child(pak->x)));
- while (codec) {
- ast_rtp_set_m_type(tmp->rtp, atoi(iks_find_attrib(codec, "id")));
- ast_rtp_set_rtpmap_type(tmp->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
- codec = iks_next(codec);
- }
-
- /* Now gather all of the codecs that we are asked for */
- ast_rtp_get_current_formats(tmp->rtp, &tmp->peercapability, &peernoncodeccapability);
-
- /* at this point, we received an awser from the remote Gtalk client,
- which allows us to compare capabilities */
- tmp->jointcapability = tmp->capability & tmp->peercapability;
- if (!tmp->jointcapability) {
- ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, tmp->capability),
- ast_getformatname_multiple(s2, BUFSIZ, tmp->peercapability),
- ast_getformatname_multiple(s3, BUFSIZ, tmp->jointcapability));
- /* close session if capabilities don't match */
- ast_queue_hangup(tmp->owner);
-
- return -1;
-
- }
-
- from = iks_find_attrib(pak->x, "to");
- if(!from)
- from = client->connection->jid->full;
-
- if (tmp) {
- if (tmp->owner)
- ast_queue_control(tmp->owner, AST_CONTROL_ANSWER);
- } else
- ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
- gtalk_response(client, from, pak, NULL, NULL);
- return 1;
-}
-
-static int gtalk_is_accepted(struct gtalk *client, ikspak *pak)
-{
- struct gtalk_pvt *tmp;
- char *from;
-
- ast_log(LOG_DEBUG, "The client is %s\n", client->name);
- /* find corresponding call */
- for (tmp = client->p; tmp; tmp = tmp->next) {
- if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))
- break;
- }
-
- from = iks_find_attrib(pak->x, "to");
- if(!from)
- from = client->connection->jid->full;
-
- if (!tmp)
- ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
-
- /* answer 'iq' packet to let the remote peer know that we're alive */
- gtalk_response(client, from, pak, NULL, NULL);
- return 1;
-}
-
-static int gtalk_handle_dtmf(struct gtalk *client, ikspak *pak)
-{
- struct gtalk_pvt *tmp;
- iks *dtmfnode = NULL, *dtmfchild = NULL;
- char *dtmf;
- char *from;
- /* Make sure our new call doesn't exist yet */
- for (tmp = client->p; tmp; tmp = tmp->next) {
- if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || iks_find_with_attrib(pak->x, "gtalk", "sid", tmp->sid))
- break;
- }
- from = iks_find_attrib(pak->x, "to");
- if(!from)
- from = client->connection->jid->full;
-
-
- if (tmp) {
- if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) {
- gtalk_response(client, from, pak,
- "feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
- "unsupported-dtmf-method xmlns='http://jabber.org/protocol/gtalk/info/dtmf#errors'");
- return -1;
- }
- if ((dtmfnode = iks_find(pak->x, "dtmf"))) {
- if((dtmf = iks_find_attrib(dtmfnode, "code"))) {
- if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-up")) {
- struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };
- f.subclass = dtmf[0];
- ast_queue_frame(tmp->owner, &f);
- ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);
- } else if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-down")) {
- struct ast_frame f = {AST_FRAME_DTMF_END, };
- f.subclass = dtmf[0];
- ast_queue_frame(tmp->owner, &f);
- ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);
- } else if(iks_find_attrib(pak->x, "dtmf")) { /* 250 millasecond default */
- struct ast_frame f = {AST_FRAME_DTMF, };
- f.subclass = dtmf[0];
- ast_queue_frame(tmp->owner, &f);
- ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);
- }
- }
- } else if ((dtmfnode = iks_find_with_attrib(pak->x, "gtalk", "action", "session-info"))) {
- if((dtmfchild = iks_find(dtmfnode, "dtmf"))) {
- if((dtmf = iks_find_attrib(dtmfchild, "code"))) {
- if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-up")) {
- struct ast_frame f = {AST_FRAME_DTMF_END, };
- f.subclass = dtmf[0];
- ast_queue_frame(tmp->owner, &f);
- ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);
- } else if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-down")) {
- struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };
- f.subclass = dtmf[0];
- ast_queue_frame(tmp->owner, &f);
- ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);
- }
- }
- }
- }
- gtalk_response(client, from, pak, NULL, NULL);
- return 1;
- } else
- ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
-
- gtalk_response(client, from, pak, NULL, NULL);
- return 1;
-}
-
-static int gtalk_hangup_farend(struct gtalk *client, ikspak *pak)
-{
- struct gtalk_pvt *tmp;
- char *from;
-
- ast_log(LOG_DEBUG, "The client is %s\n", client->name);
- /* Make sure our new call doesn't exist yet */
- for (tmp = client->p; tmp; tmp = tmp->next) {
- if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))
- break;
- }
- from = iks_find_attrib(pak->x, "to");
- if(!from)
- from = client->connection->jid->full;
-
- if (tmp) {
- tmp->alreadygone = 1;
- if (tmp->owner)
- ast_queue_hangup(tmp->owner);
- } else
- ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
- gtalk_response(client, from, pak, NULL, NULL);
- return 1;
-}
-
-static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, char *sid, char *from, char *to)
-{
- struct gtalk_candidate *tmp;
- struct aji_client *c = client->connection;
- struct gtalk_candidate *ours1 = NULL, *ours2 = NULL;
- struct sockaddr_in sin;
- struct sockaddr_in dest;
- struct in_addr us;
- iks *iq, *gtalk, *candidate, *transport;
- char user[17], pass[17], preference[5], port[7];
-
-
- iq = iks_new("iq");
- gtalk = iks_new("session");
- candidate = iks_new("candidate");
- transport = iks_new("transport");
- if (!iq || !gtalk || !candidate || !transport) {
- ast_log(LOG_ERROR, "Memory allocation error\n");
- goto safeout;
- }
- ours1 = ast_calloc(1, sizeof(*ours1));
- ours2 = ast_calloc(1, sizeof(*ours2));
- if (!ours1 || !ours2)
- goto safeout;
-
- iks_insert_attrib(transport, "xmlns","http://www.google.com/transport/p2p");
- iks_insert_node(iq, gtalk);
- iks_insert_node(gtalk,transport);
- iks_insert_node(transport, candidate);
-
- for (; p; p = p->next) {
- if (!strcasecmp(p->sid, sid))
- break;
- }
-
- if (!p) {
- ast_log(LOG_NOTICE, "No matching gtalk session - SID %s!\n", sid);
- goto safeout;
- }
-
- ast_rtp_get_us(p->rtp, &sin);
- ast_find_ourip(&us, bindaddr);
-
- /* Setup our gtalk candidates */
- ast_copy_string(ours1->name, "rtp", sizeof(ours1->name));
- ours1->port = ntohs(sin.sin_port);
- ours1->preference = 1;
- snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
- snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
- ast_copy_string(ours1->username, user, sizeof(ours1->username));
- ast_copy_string(ours1->password, pass, sizeof(ours1->password));
- ast_copy_string(ours1->ip, ast_inet_ntoa(us), sizeof(ours1->ip));
- ours1->protocol = AJI_PROTOCOL_UDP;
- ours1->type = AJI_CONNECT_LOCAL;
- ours1->generation = 0;
- p->ourcandidates = ours1;
-
- if (!ast_strlen_zero(externip)) {
- /* XXX We should really stun for this one not just go with externip XXX */
- snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
- snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
- ast_copy_string(ours2->username, user, sizeof(ours2->username));
- ast_copy_string(ours2->password, pass, sizeof(ours2->password));
- ast_copy_string(ours2->ip, externip, sizeof(ours2->ip));
- ast_copy_string(ours2->name, "rtp", sizeof(ours1->name));
- ours2->port = ntohs(sin.sin_port);
- ours2->preference = 0.9;
- ours2->protocol = AJI_PROTOCOL_UDP;
- ours2->type = AJI_CONNECT_STUN;
- ours2->generation = 0;
- ours1->next = ours2;
- ours2 = NULL;
- }
- ours1 = NULL;
- dest.sin_addr = __ourip;
- dest.sin_port = sin.sin_port;
-
-
- for (tmp = p->ourcandidates; tmp; tmp = tmp->next) {
- snprintf(port, sizeof(port), "%d", tmp->port);
- snprintf(preference, sizeof(preference), "%.2f", tmp->preference);
- iks_insert_attrib(iq, "from", to);
- iks_insert_attrib(iq, "to", from);
- iks_insert_attrib(iq, "type", "set");
- iks_insert_attrib(iq, "id", c->mid);
- ast_aji_increment_mid(c->mid);
- iks_insert_attrib(gtalk, "type", "transport-info");
- iks_insert_attrib(gtalk, "id", sid);
- iks_insert_attrib(gtalk, "initiator", (p->initiator) ? to : from);
- iks_insert_attrib(gtalk, "xmlns", GOOGLE_NS);
- iks_insert_attrib(candidate, "name", tmp->name);
- iks_insert_attrib(candidate, "address", tmp->ip);
- iks_insert_attrib(candidate, "port", port);
- iks_insert_attrib(candidate, "username", tmp->username);
- iks_insert_attrib(candidate, "password", tmp->password);
- iks_insert_attrib(candidate, "preference", preference);
- if (tmp->protocol == AJI_PROTOCOL_UDP)
- iks_insert_attrib(candidate, "protocol", "udp");
- if (tmp->protocol == AJI_PROTOCOL_SSLTCP)
- iks_insert_attrib(candidate, "protocol", "ssltcp");
- if (tmp->type == AJI_CONNECT_STUN)
- iks_insert_attrib(candidate, "type", "stun");
- if (tmp->type == AJI_CONNECT_LOCAL)
- iks_insert_attrib(candidate, "type", "local");
- if (tmp->type == AJI_CONNECT_RELAY)
- iks_insert_attrib(candidate, "type", "relay");
- iks_insert_attrib(candidate, "network", "0");
- iks_insert_attrib(candidate, "generation", "0");
- iks_send(c->p, iq);
- }
- p->laststun = 0;
-
-safeout:
- if (ours1)
- free(ours1);
- if (ours2)
- free(ours2);
- if (iq)
- iks_delete(iq);
- if (gtalk)
- iks_delete(gtalk);
- if (candidate)
- iks_delete(candidate);
- if(transport)
- iks_delete(transport);
- return 1;
-}
-
-static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid)
-{
- struct gtalk_pvt *tmp = NULL;
- struct aji_resource *resources = NULL;
- struct aji_buddy *buddy;
- char idroster[200];
- char *data, *exten = NULL;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "The client is %s for alloc\n", client->name);
- if (!sid && !strchr(them, '/')) { /* I started call! */
- if (!strcasecmp(client->name, "guest")) {
- buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, them);
- if (buddy)
- resources = buddy->resources;
- } else if (client->buddy)
- resources = client->buddy->resources;
- while (resources) {
- if (resources->cap->jingle) {
- break;
- }
- resources = resources->next;
- }
- if (resources)
- snprintf(idroster, sizeof(idroster), "%s/%s", them, resources->resource);
- else {
- ast_log(LOG_ERROR, "no gtalk capable clients to talk to.\n");
- return NULL;
- }
- }
- if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
- return NULL;
- }
- if (sid) {
- ast_copy_string(tmp->sid, sid, sizeof(tmp->sid));
- ast_copy_string(tmp->them, them, sizeof(tmp->them));
- ast_copy_string(tmp->us, us, sizeof(tmp->us));
- } else {
- snprintf(tmp->sid, sizeof(tmp->sid), "%08lx%08lx", ast_random(), ast_random());
- ast_copy_string(tmp->them, idroster, sizeof(tmp->them));
- ast_copy_string(tmp->us, us, sizeof(tmp->us));
- tmp->initiator = 1;
- }
- /* clear codecs */
- tmp->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
- ast_rtp_pt_clear(tmp->rtp);
-
- /* add user configured codec capabilites */
- if (client->capability)
- tmp->capability = client->capability;
- else if (global_capability)
- tmp->capability = global_capability;
-
- tmp->parent = client;
- if (!tmp->rtp) {
- ast_log(LOG_WARNING, "Out of RTP sessions?\n");
- free(tmp);
- return NULL;
- }
-
- /* Set CALLERID(name) to the full JID of the remote peer */
- ast_copy_string(tmp->cid_name, tmp->them, sizeof(tmp->cid_name));
-
- if(strchr(tmp->us, '/')) {
- data = ast_strdupa(tmp->us);
- exten = strsep(&data, "/");
- } else
- exten = tmp->us;
- ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
- ast_mutex_init(&tmp->lock);
- ast_mutex_lock(&gtalklock);
- tmp->next = client->p;
- client->p = tmp;
- ast_mutex_unlock(&gtalklock);
- return tmp;
-}
-
-/*! \brief Start new gtalk channel */
-static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title)
-{
- struct ast_channel *tmp;
- int fmt;
- int what;
- const char *n2;
-
- if (title)
- n2 = title;
- else
- n2 = i->us;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, client->accountcode, i->exten, client->context, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff);
- if (!tmp) {
- ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n");
- return NULL;
- }
- tmp->tech = &gtalk_tech;
-
- /* Select our native format based on codec preference until we receive
- something from another device to the contrary. */
- if (i->jointcapability)
- what = i->jointcapability;
- else if (i->capability)
- what = i->capability;
- else
- what = global_capability;
- tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
- fmt = ast_best_codec(tmp->nativeformats);
-
- if (i->rtp) {
- ast_rtp_setstun(i->rtp, 1);
- tmp->fds[0] = ast_rtp_fd(i->rtp);
- tmp->fds[1] = ast_rtcp_fd(i->rtp);
- }
- if (i->vrtp) {
- ast_rtp_setstun(i->rtp, 1);
- tmp->fds[2] = ast_rtp_fd(i->vrtp);
- tmp->fds[3] = ast_rtcp_fd(i->vrtp);
- }
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
- tmp->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp->rawreadformat = fmt;
- tmp->tech_pvt = i;
-
- tmp->callgroup = client->callgroup;
- tmp->pickupgroup = client->pickupgroup;
- tmp->cid.cid_pres = client->callingpres;
- if (!ast_strlen_zero(client->accountcode))
- ast_string_field_set(tmp, accountcode, client->accountcode);
- if (client->amaflags)
- tmp->amaflags = client->amaflags;
- if (!ast_strlen_zero(client->language))
- ast_string_field_set(tmp, language, client->language);
- if (!ast_strlen_zero(client->musicclass))
- ast_string_field_set(tmp, musicclass, client->musicclass);
- i->owner = tmp;
- ast_module_ref(ast_module_info->self);
- ast_copy_string(tmp->context, client->context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
-
- if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
- tmp->cid.cid_dnid = ast_strdup(i->exten);
- tmp->priority = 1;
- if (i->rtp)
- ast_jb_configure(tmp, &global_jbconf);
- if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- ast_hangup(tmp);
- tmp = NULL;
- }
-
- return tmp;
-}
-
-static int gtalk_action(struct gtalk *client, struct gtalk_pvt *p, const char *action)
-{
- iks *request, *session = NULL;
- int res = -1;
-
- request = iks_new("iq");
- if (request) {
- iks_insert_attrib(request, "type", "set");
- iks_insert_attrib(request, "from", p->us);
- iks_insert_attrib(request, "to", p->them);
- iks_insert_attrib(request, "id", client->connection->mid);
- ast_aji_increment_mid(client->connection->mid);
- session = iks_new("session");
- if (session) {
- iks_insert_attrib(session, "type", action);
- iks_insert_attrib(session, "id", p->sid);
- iks_insert_attrib(session, "initiator", p->initiator ? p->us : p->them);
- iks_insert_attrib(session, "xmlns", "http://www.google.com/session");
- iks_insert_node(request, session);
- iks_send(client->connection->p, request);
- iks_delete(session);
- res = 0;
- }
- iks_delete(request);
- }
- return res;
-}
-
-static void gtalk_free_candidates(struct gtalk_candidate *candidate)
-{
- struct gtalk_candidate *last;
- while (candidate) {
- last = candidate;
- candidate = candidate->next;
- free(last);
- }
-}
-
-static void gtalk_free_pvt(struct gtalk *client, struct gtalk_pvt *p)
-{
- struct gtalk_pvt *cur, *prev = NULL;
- cur = client->p;
- while (cur) {
- if (cur == p) {
- if (prev)
- prev->next = p->next;
- else
- client->p = p->next;
- break;
- }
- prev = cur;
- cur = cur->next;
- }
- if (p->ringrule)
- iks_filter_remove_rule(p->parent->connection->f, p->ringrule);
- if (p->owner)
- ast_log(LOG_WARNING, "Uh oh, there's an owner, this is going to be messy.\n");
- if (p->rtp)
- ast_rtp_destroy(p->rtp);
- if (p->vrtp)
- ast_rtp_destroy(p->vrtp);
- gtalk_free_candidates(p->theircandidates);
- free(p);
-}
-
-
-static int gtalk_newcall(struct gtalk *client, ikspak *pak)
-{
- struct gtalk_pvt *p, *tmp = client->p;
- struct ast_channel *chan;
- int res;
- iks *codec;
- char *from = NULL;
- char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ];
- int peernoncodeccapability;
-
- /* Make sure our new call doesn't exist yet */
- from = iks_find_attrib(pak->x,"to");
- if(!from)
- from = client->connection->jid->full;
-
- while (tmp) {
- if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid)) {
- ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid);
- gtalk_response(client, from, pak, "out-of-order", NULL);
- return -1;
- }
- tmp = tmp->next;
- }
-
- p = gtalk_alloc(client, from, pak->from->full, iks_find_attrib(pak->query, "id"));
- if (!p) {
- ast_log(LOG_WARNING, "Unable to allocate gtalk structure!\n");
- return -1;
- }
-
- chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user);
- if (!chan) {
- gtalk_free_pvt(client, p);
- return -1;
- }
-
- ast_mutex_lock(&p->lock);
- ast_copy_string(p->them, pak->from->full, sizeof(p->them));
- if (iks_find_attrib(pak->query, "id")) {
- ast_copy_string(p->sid, iks_find_attrib(pak->query, "id"),
- sizeof(p->sid));
- }
-
- /* codec points to the first <payload-type/> tag */
- codec = iks_child(iks_child(iks_child(pak->x)));
-
- while (codec) {
- ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id")));
- ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
- codec = iks_next(codec);
- }
-
- /* Now gather all of the codecs that we are asked for */
- ast_rtp_get_current_formats(p->rtp, &p->peercapability, &peernoncodeccapability);
- p->jointcapability = p->capability & p->peercapability;
- ast_mutex_unlock(&p->lock);
-
- ast_setstate(chan, AST_STATE_RING);
- if (!p->jointcapability) {
- ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->capability),
- ast_getformatname_multiple(s2, BUFSIZ, p->peercapability),
- ast_getformatname_multiple(s3, BUFSIZ, p->jointcapability));
- /* close session if capabilities don't match */
- gtalk_action(client, p, "reject");
- p->alreadygone = 1;
- gtalk_hangup(chan);
- ast_channel_free(chan);
- return -1;
- }
-
- res = ast_pbx_start(chan);
-
- switch (res) {
- case AST_PBX_FAILED:
- ast_log(LOG_WARNING, "Failed to start PBX :(\n");
- gtalk_response(client, from, pak, "service-unavailable", NULL);
- break;
- case AST_PBX_CALL_LIMIT:
- ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
- gtalk_response(client, from, pak, "service-unavailable", NULL);
- break;
- case AST_PBX_SUCCESS:
- gtalk_response(client, from, pak, NULL, NULL);
- gtalk_invite_response(p, p->them, p->us,p->sid, 0);
- gtalk_create_candidates(client, p, p->sid, p->them, p->us);
- /* nothing to do */
- break;
- }
-
- return 1;
-}
-
-static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p)
-{
- struct gtalk_candidate *tmp;
- struct hostent *hp;
- struct ast_hostent ahp;
- struct sockaddr_in sin;
- struct sockaddr_in aux;
-
- if (time(NULL) == p->laststun)
- return 0;
-
- tmp = p->theircandidates;
- p->laststun = time(NULL);
- while (tmp) {
- char username[256];
-
- /* Find the IP address of the host */
- hp = ast_gethostbyname(tmp->ip, &ahp);
- sin.sin_family = AF_INET;
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- sin.sin_port = htons(tmp->port);
- snprintf(username, sizeof(username), "%s%s", tmp->username,
- p->ourcandidates->username);
-
- /* Find out the result of the STUN */
- ast_rtp_get_peer(p->rtp, &aux);
-
- /* If the STUN result is different from the IP of the hostname,
- lock on the stun IP of the hostname advertised by the
- remote client */
- if (aux.sin_addr.s_addr &&
- aux.sin_addr.s_addr != sin.sin_addr.s_addr)
- ast_rtp_stun_request(p->rtp, &aux, username);
- else
- ast_rtp_stun_request(p->rtp, &sin, username);
-
- if (aux.sin_addr.s_addr && option_debug > 3) {
- ast_log(LOG_DEBUG, "Receiving RTP traffic from IP %s, matches with remote candidate's IP %s\n", ast_inet_ntoa(aux.sin_addr), tmp->ip);
- ast_log(LOG_DEBUG, "Sending STUN request to %s\n", tmp->ip);
- }
-
- tmp = tmp->next;
- }
- return 1;
-}
-
-static int gtalk_add_candidate(struct gtalk *client, ikspak *pak)
-{
- struct gtalk_pvt *p = NULL, *tmp = NULL;
- struct aji_client *c = client->connection;
- struct gtalk_candidate *newcandidate = NULL;
- iks *traversenodes = NULL, *receipt = NULL;
- char *from;
-
- from = iks_find_attrib(pak->x,"to");
- if(!from)
- from = c->jid->full;
-
- for (tmp = client->p; tmp; tmp = tmp->next) {
- if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid)) {
- p = tmp;
- break;
- }
- }
-
- if (!p)
- return -1;
-
- traversenodes = pak->query;
- while(traversenodes) {
- if(!strcasecmp(iks_name(traversenodes), "session")) {
- traversenodes = iks_child(traversenodes);
- continue;
- }
- if(!strcasecmp(iks_name(traversenodes), "transport")) {
- traversenodes = iks_child(traversenodes);
- continue;
- }
- if(!strcasecmp(iks_name(traversenodes), "candidate")) {
- newcandidate = ast_calloc(1, sizeof(*newcandidate));
- if (!newcandidate)
- return 0;
- ast_copy_string(newcandidate->name, iks_find_attrib(traversenodes, "name"),
- sizeof(newcandidate->name));
- ast_copy_string(newcandidate->ip, iks_find_attrib(traversenodes, "address"),
- sizeof(newcandidate->ip));
- newcandidate->port = atoi(iks_find_attrib(traversenodes, "port"));
- ast_copy_string(newcandidate->username, iks_find_attrib(traversenodes, "username"),
- sizeof(newcandidate->username));
- ast_copy_string(newcandidate->password, iks_find_attrib(traversenodes, "password"),
- sizeof(newcandidate->password));
- newcandidate->preference = atof(iks_find_attrib(traversenodes, "preference"));
- if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "udp"))
- newcandidate->protocol = AJI_PROTOCOL_UDP;
- if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "ssltcp"))
- newcandidate->protocol = AJI_PROTOCOL_SSLTCP;
-
- if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "stun"))
- newcandidate->type = AJI_CONNECT_STUN;
- if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "local"))
- newcandidate->type = AJI_CONNECT_LOCAL;
- if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "relay"))
- newcandidate->type = AJI_CONNECT_RELAY;
- ast_copy_string(newcandidate->network, iks_find_attrib(traversenodes, "network"),
- sizeof(newcandidate->network));
- newcandidate->generation = atoi(iks_find_attrib(traversenodes, "generation"));
- newcandidate->next = NULL;
-
- newcandidate->next = p->theircandidates;
- p->theircandidates = newcandidate;
- p->laststun = 0;
- gtalk_update_stun(p->parent, p);
- newcandidate = NULL;
- }
- traversenodes = iks_next(traversenodes);
- }
-
- receipt = iks_new("iq");
- iks_insert_attrib(receipt, "type", "result");
- iks_insert_attrib(receipt, "from", from);
- iks_insert_attrib(receipt, "to", iks_find_attrib(pak->x, "from"));
- iks_insert_attrib(receipt, "id", iks_find_attrib(pak->x, "id"));
- iks_send(c->p, receipt);
- iks_delete(receipt);
-
- return 1;
-}
-
-static struct ast_frame *gtalk_rtp_read(struct ast_channel *ast, struct gtalk_pvt *p)
-{
- struct ast_frame *f;
-
- if (!p->rtp)
- return &ast_null_frame;
- f = ast_rtp_read(p->rtp);
- gtalk_update_stun(p->parent, p);
- if (p->owner) {
- /* We already hold the channel lock */
- if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
- p->owner->nativeformats =
- (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
- ast_set_read_format(p->owner, p->owner->readformat);
- ast_set_write_format(p->owner, p->owner->writeformat);
- }
-/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
- f = ast_dsp_process(p->owner, p->vad, f);
- if (option_debug && f && (f->frametype == AST_FRAME_DTMF))
- ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
- } */
- }
- }
- return f;
-}
-
-static struct ast_frame *gtalk_read(struct ast_channel *ast)
-{
- struct ast_frame *fr;
- struct gtalk_pvt *p = ast->tech_pvt;
-
- ast_mutex_lock(&p->lock);
- fr = gtalk_rtp_read(ast, p);
- ast_mutex_unlock(&p->lock);
- return fr;
-}
-
-/*! \brief Send frame to media channel (rtp) */
-static int gtalk_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct gtalk_pvt *p = ast->tech_pvt;
- int res = 0;
-
- switch (frame->frametype) {
- case AST_FRAME_VOICE:
- if (!(frame->subclass & ast->nativeformats)) {
- ast_log(LOG_WARNING,
- "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
- frame->subclass, ast->nativeformats, ast->readformat,
- ast->writeformat);
- return 0;
- }
- if (p) {
- ast_mutex_lock(&p->lock);
- if (p->rtp) {
- res = ast_rtp_write(p->rtp, frame);
- }
- ast_mutex_unlock(&p->lock);
- }
- break;
- case AST_FRAME_VIDEO:
- if (p) {
- ast_mutex_lock(&p->lock);
- if (p->vrtp) {
- res = ast_rtp_write(p->vrtp, frame);
- }
- ast_mutex_unlock(&p->lock);
- }
- break;
- case AST_FRAME_IMAGE:
- return 0;
- break;
- default:
- ast_log(LOG_WARNING, "Can't send %d type frames with Gtalk write\n",
- frame->frametype);
- return 0;
- }
-
- return res;
-}
-
-static int gtalk_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct gtalk_pvt *p = newchan->tech_pvt;
- ast_mutex_lock(&p->lock);
-
- if ((p->owner != oldchan)) {
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- if (p->owner == oldchan)
- p->owner = newchan;
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int gtalk_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
-{
- int res = 0;
-
- switch (condition) {
- case AST_CONTROL_HOLD:
- ast_moh_start(ast, data, NULL);
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(ast);
- break;
- default:
- ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition);
- res = -1;
- }
-
- return res;
-}
-
-static int gtalk_digit_begin(struct ast_channel *chan, char digit)
-{
- return gtalk_digit(chan, digit, 0);
-}
-
-static int gtalk_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
-{
- return gtalk_digit(chan, digit, duration);
-}
-
-static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct gtalk_pvt *p = ast->tech_pvt;
- struct gtalk *client = p->parent;
- iks *iq, *gtalk, *dtmf;
- char buffer[2] = {digit, '\0'};
- iq = iks_new("iq");
- gtalk = iks_new("gtalk");
- dtmf = iks_new("dtmf");
- if(!iq || !gtalk || !dtmf) {
- if(iq)
- iks_delete(iq);
- if(gtalk)
- iks_delete(gtalk);
- if(dtmf)
- iks_delete(dtmf);
- ast_log(LOG_ERROR, "Did not send dtmf do to memory issue\n");
- return -1;
- }
-
- iks_insert_attrib(iq, "type", "set");
- iks_insert_attrib(iq, "to", p->them);
- iks_insert_attrib(iq, "from", p->us);
- iks_insert_attrib(iq, "id", client->connection->mid);
- ast_aji_increment_mid(client->connection->mid);
- iks_insert_attrib(gtalk, "xmlns", "http://jabber.org/protocol/gtalk");
- iks_insert_attrib(gtalk, "action", "session-info");
- iks_insert_attrib(gtalk, "initiator", p->initiator ? p->us: p->them);
- iks_insert_attrib(gtalk, "sid", p->sid);
- iks_insert_attrib(dtmf, "xmlns", "http://jabber.org/protocol/gtalk/info/dtmf");
- iks_insert_attrib(dtmf, "code", buffer);
- iks_insert_node(iq, gtalk);
- iks_insert_node(gtalk, dtmf);
-
- ast_mutex_lock(&p->lock);
- if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN || duration == 0) {
- iks_insert_attrib(dtmf, "action", "button-down");
- } else if (ast->dtmff.frametype == AST_FRAME_DTMF_END || duration != 0) {
- iks_insert_attrib(dtmf, "action", "button-up");
- }
- iks_send(client->connection->p, iq);
- iks_delete(iq);
- iks_delete(gtalk);
- iks_delete(dtmf);
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int gtalk_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
-{
- ast_log(LOG_NOTICE, "XXX Implement gtalk sendhtml XXX\n");
-
- return -1;
-}
-
-/* Not in use right now.
-static int gtalk_auto_congest(void *nothing)
-{
- struct gtalk_pvt *p = nothing;
-
- ast_mutex_lock(&p->lock);
- if (p->owner) {
- if (!ast_channel_trylock(p->owner)) {
- ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_channel_unlock(p->owner);
- }
- }
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-*/
-
-/*! \brief Initiate new call, part of PBX interface
- * dest is the dial string */
-static int gtalk_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct gtalk_pvt *p = ast->tech_pvt;
-
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "gtalk_call called on %s, neither down nor reserved\n", ast->name);
- return -1;
- }
-
- ast_setstate(ast, AST_STATE_RING);
- if (!p->ringrule) {
- ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring));
- p->ringrule = iks_filter_add_rule(p->parent->connection->f, gtalk_ringing_ack, p,
- IKS_RULE_ID, p->ring, IKS_RULE_DONE);
- } else
- ast_log(LOG_WARNING, "Whoa, already have a ring rule!\n");
-
- gtalk_invite(p, p->them, p->us, p->sid, 1);
- gtalk_create_candidates(p->parent, p, p->sid, p->them, p->us);
-
- return 0;
-}
-
-/*! \brief Hangup a call through the gtalk proxy channel */
-static int gtalk_hangup(struct ast_channel *ast)
-{
- struct gtalk_pvt *p = ast->tech_pvt;
- struct gtalk *client;
-
- ast_mutex_lock(&p->lock);
- client = p->parent;
- p->owner = NULL;
- ast->tech_pvt = NULL;
- if (!p->alreadygone)
- gtalk_action(client, p, "terminate");
- ast_mutex_unlock(&p->lock);
-
- gtalk_free_pvt(client, p);
- ast_module_unref(ast_module_info->self);
-
- return 0;
-}
-
-/*! \brief Part of PBX interface */
-static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause)
-{
- struct gtalk_pvt *p = NULL;
- struct gtalk *client = NULL;
- char *sender = NULL, *to = NULL, *s = NULL;
- struct ast_channel *chan = NULL;
-
- if (data) {
- s = ast_strdupa(data);
- if (s) {
- sender = strsep(&s, "/");
- if (sender && (sender[0] != '\0'))
- to = strsep(&s, "/");
- if (!to) {
- ast_log(LOG_ERROR, "Bad arguments in Gtalk Dialstring: %s\n", (char*) data);
- return NULL;
- }
- }
- }
- client = find_gtalk(to, sender);
- if (!client) {
- ast_log(LOG_WARNING, "Could not find recipient.\n");
- return NULL;
- }
- ASTOBJ_WRLOCK(client);
- p = gtalk_alloc(client, strchr(sender, '@') ? sender : client->connection->jid->full, strchr(to, '@') ? to : client->user, NULL);
- if (p)
- chan = gtalk_new(client, p, AST_STATE_DOWN, to);
-
- ASTOBJ_UNLOCK(client);
- return chan;
-}
-
-/*! \brief CLI command "gtalk show channels" */
-static int gtalk_show_channels(int fd, int argc, char **argv)
-{
-#define FORMAT "%-30.30s %-30.30s %-15.15s %-5.5s %-5.5s \n"
- struct gtalk_pvt *p;
- struct ast_channel *chan;
- int numchans = 0;
- char them[AJI_MAX_JIDLEN];
- char *jid = NULL;
- char *resource = NULL;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(&gtalklock);
- ast_cli(fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write");
- ASTOBJ_CONTAINER_TRAVERSE(&gtalk_list, 1, {
- ASTOBJ_WRLOCK(iterator);
- p = iterator->p;
- while(p) {
- chan = p->owner;
- ast_copy_string(them, p->them, sizeof(them));
- jid = them;
- resource = strchr(them, '/');
- if (!resource)
- resource = "None";
- else {
- *resource = '\0';
- resource ++;
- }
- if (chan)
- ast_cli(fd, FORMAT,
- chan->name,
- jid,
- resource,
- ast_getformatname(chan->readformat),
- ast_getformatname(chan->writeformat)
- );
- else
- ast_log(LOG_WARNING, "No available channel\n");
- numchans ++;
- p = p->next;
- }
- ASTOBJ_UNLOCK(iterator);
- });
-
- ast_mutex_unlock(&gtalklock);
-
- ast_cli(fd, "%d active gtalk channel%s\n", numchans, (numchans != 1) ? "s" : "");
- return RESULT_SUCCESS;
-#undef FORMAT
-}
-
-/*! \brief CLI command "gtalk show channels" */
-static int gtalk_do_reload(int fd, int argc, char **argv)
-{
- ast_verbose("IT DOES WORK!\n");
- return RESULT_SUCCESS;
-}
-
-static int gtalk_parser(void *data, ikspak *pak)
-{
- struct gtalk *client = ASTOBJ_REF((struct gtalk *) data);
-
- if (iks_find_with_attrib(pak->x, "session", "type", "initiate")) {
- /* New call */
- gtalk_newcall(client, pak);
- } else if (iks_find_with_attrib(pak->x, "session", "type", "candidates") || iks_find_with_attrib(pak->x, "session", "type", "transport-info")) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "About to add candidate!\n");
- gtalk_add_candidate(client, pak);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Candidate Added!\n");
- } else if (iks_find_with_attrib(pak->x, "session", "type", "accept")) {
- gtalk_is_answered(client, pak);
- } else if (iks_find_with_attrib(pak->x, "session", "type", "transport-accept")) {
- gtalk_is_accepted(client, pak);
- } else if (iks_find_with_attrib(pak->x, "session", "type", "content-info") || iks_find_with_attrib(pak->x, "gtalk", "action", "session-info")) {
- gtalk_handle_dtmf(client, pak);
- } else if (iks_find_with_attrib(pak->x, "session", "type", "terminate")) {
- gtalk_hangup_farend(client, pak);
- } else if (iks_find_with_attrib(pak->x, "session", "type", "reject")) {
- gtalk_hangup_farend(client, pak);
- }
- ASTOBJ_UNREF(client, gtalk_member_destroy);
- return IKS_FILTER_EAT;
-}
-
-/* Not using this anymore probably take out soon
-static struct gtalk_candidate *gtalk_create_candidate(char *args)
-{
- char *name, *type, *preference, *protocol;
- struct gtalk_candidate *res;
- res = malloc(sizeof(struct gtalk_candidate));
- memset(res, 0, sizeof(struct gtalk_candidate));
- if (args)
- name = args;
- if ((args = strchr(args, ','))) {
- *args = '\0';
- args++;
- preference = args;
- }
- if ((args = strchr(args, ','))) {
- *args = '\0';
- args++;
- protocol = args;
- }
- if ((args = strchr(args, ','))) {
- *args = '\0';
- args++;
- type = args;
- }
- if (name)
- ast_copy_string(res->name, name, sizeof(res->name));
- if (preference) {
- res->preference = atof(preference);
- }
- if (protocol) {
- if (!strcasecmp("udp", protocol))
- res->protocol = AJI_PROTOCOL_UDP;
- if (!strcasecmp("ssltcp", protocol))
- res->protocol = AJI_PROTOCOL_SSLTCP;
- }
- if (type) {
- if (!strcasecmp("stun", type))
- res->type = AJI_CONNECT_STUN;
- if (!strcasecmp("local", type))
- res->type = AJI_CONNECT_LOCAL;
- if (!strcasecmp("relay", type))
- res->type = AJI_CONNECT_RELAY;
- }
-
- return res;
-}
-*/
-
-static int gtalk_create_member(char *label, struct ast_variable *var, int allowguest,
- struct ast_codec_pref prefs, char *context,
- struct gtalk *member)
-{
- struct aji_client *client;
-
- if (!member)
- ast_log(LOG_WARNING, "Out of memory.\n");
-
- ast_copy_string(member->name, label, sizeof(member->name));
- ast_copy_string(member->user, label, sizeof(member->user));
- ast_copy_string(member->context, context, sizeof(member->context));
- member->allowguest = allowguest;
- member->prefs = prefs;
- while (var) {
-#if 0
- struct gtalk_candidate *candidate = NULL;
-#endif
- if (!strcasecmp(var->name, "username"))
- ast_copy_string(member->user, var->value, sizeof(member->user));
- else if (!strcasecmp(var->name, "disallow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
- else if (!strcasecmp(var->name, "allow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
- else if (!strcasecmp(var->name, "context"))
- ast_copy_string(member->context, var->value, sizeof(member->context));
-#if 0
- else if (!strcasecmp(var->name, "candidate")) {
- candidate = gtalk_create_candidate(var->value);
- if (candidate) {
- candidate->next = member->ourcandidates;
- member->ourcandidates = candidate;
- }
- }
-#endif
- else if (!strcasecmp(var->name, "connection")) {
- if ((client = ast_aji_get_client(var->value))) {
- member->connection = client;
- iks_filter_add_rule(client->f, gtalk_parser, member,
- IKS_RULE_TYPE, IKS_PAK_IQ,
- IKS_RULE_FROM_PARTIAL, member->user,
- IKS_RULE_NS, "http://www.google.com/session",
- IKS_RULE_DONE);
-
- } else {
- ast_log(LOG_ERROR, "connection referenced not found!\n");
- return 0;
- }
- }
- var = var->next;
- }
- if (member->connection && member->user)
- member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
- else {
- ast_log(LOG_ERROR, "No Connection or Username!\n");
- }
- return 1;
-}
-
-static int gtalk_load_config(void)
-{
- char *cat = NULL;
- struct ast_config *cfg = NULL;
- char context[AST_MAX_CONTEXT];
- int allowguest = 1;
- struct ast_variable *var;
- struct gtalk *member;
- struct ast_codec_pref prefs;
- struct aji_client_container *clients;
- struct gtalk_candidate *global_candidates = NULL;
- struct hostent *hp;
- struct ast_hostent ahp;
-
- cfg = ast_config_load(GOOGLE_CONFIG);
- if (!cfg)
- return 0;
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- cat = ast_category_browse(cfg, NULL);
- for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, var->name, var->value))
- continue;
-
- if (!strcasecmp(var->name, "allowguest"))
- allowguest =
- (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
- else if (!strcasecmp(var->name, "disallow"))
- ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
- else if (!strcasecmp(var->name, "allow"))
- ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
- else if (!strcasecmp(var->name, "context"))
- ast_copy_string(context, var->value, sizeof(context));
- else if (!strcasecmp(var->name, "bindaddr")) {
- if (!(hp = ast_gethostbyname(var->value, &ahp))) {
- ast_log(LOG_WARNING, "Invalid address: %s\n", var->value);
- } else {
- memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
- }
- }
-/* Idea to allow for custom candidates */
-/*
- else if (!strcasecmp(var->name, "candidate")) {
- candidate = gtalk_create_candidate(var->value);
- if (candidate) {
- candidate->next = global_candidates;
- global_candidates = candidate;
- }
- }
-*/
- }
- while (cat) {
- if (strcasecmp(cat, "general")) {
- var = ast_variable_browse(cfg, cat);
- member = (struct gtalk *) malloc(sizeof(struct gtalk));
- memset(member, 0, sizeof(struct gtalk));
- ASTOBJ_INIT(member);
- ASTOBJ_WRLOCK(member);
- if (!strcasecmp(cat, "guest")) {
- ast_copy_string(member->name, "guest", sizeof(member->name));
- ast_copy_string(member->user, "guest", sizeof(member->user));
- ast_copy_string(member->context, context, sizeof(member->context));
- member->allowguest = allowguest;
- member->prefs = prefs;
- while (var) {
- if (!strcasecmp(var->name, "disallow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability,
- var->value, 0);
- else if (!strcasecmp(var->name, "allow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability,
- var->value, 1);
- else if (!strcasecmp(var->name, "context"))
- ast_copy_string(member->context, var->value,
- sizeof(member->context));
-/* Idea to allow for custom candidates */
-/*
- else if (!strcasecmp(var->name, "candidate")) {
- candidate = gtalk_create_candidate(var->value);
- if (candidate) {
- candidate->next = member->ourcandidates;
- member->ourcandidates = candidate;
- }
- }
-*/
- var = var->next;
- }
- ASTOBJ_UNLOCK(member);
- clients = ast_aji_get_clients();
- if (clients) {
- ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
- ASTOBJ_WRLOCK(iterator);
- ASTOBJ_WRLOCK(member);
- member->connection = iterator;
- iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
- iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
- ASTOBJ_UNLOCK(member);
- ASTOBJ_CONTAINER_LINK(&gtalk_list, member);
- ASTOBJ_UNLOCK(iterator);
- });
- } else {
- ASTOBJ_UNLOCK(member);
- ASTOBJ_UNREF(member, gtalk_member_destroy);
- }
- } else {
- ASTOBJ_UNLOCK(member);
- if (gtalk_create_member(cat, var, allowguest, prefs, context, member))
- ASTOBJ_CONTAINER_LINK(&gtalk_list, member);
- ASTOBJ_UNREF(member, gtalk_member_destroy);
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
- gtalk_free_candidates(global_candidates);
- return 1;
-}
-
-/*! \brief Load module into PBX, register channel */
-static int load_module(void)
-{
- char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
- free(jabber_loaded);
- if (!jabber_loaded) {
- /* If embedded, check for a different module name */
- jabber_loaded = ast_module_helper("", "res_jabber", 0, 0, 0, 0);
- free(jabber_loaded);
- if (!jabber_loaded) {
- ast_log(LOG_ERROR, "chan_gtalk.so depends upon res_jabber.so\n");
- return AST_MODULE_LOAD_DECLINE;
- }
- }
-
-#ifdef HAVE_GNUTLS
- gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
-#endif /* HAVE_GNUTLS */
-
- ASTOBJ_CONTAINER_INIT(&gtalk_list);
- if (!gtalk_load_config()) {
- ast_log(LOG_ERROR, "Unable to read config file %s. Not loading module.\n", GOOGLE_CONFIG);
- return 0;
- }
-
- sched = sched_context_create();
- if (!sched)
- ast_log(LOG_WARNING, "Unable to create schedule context\n");
-
- io = io_context_create();
- if (!io)
- ast_log(LOG_WARNING, "Unable to create I/O context\n");
-
- if (ast_find_ourip(&__ourip, bindaddr)) {
- ast_log(LOG_WARNING, "Unable to get own IP address, Gtalk disabled\n");
- return 0;
- }
-
- ast_rtp_proto_register(&gtalk_rtp);
- ast_cli_register_multiple(gtalk_cli, sizeof(gtalk_cli) / sizeof(gtalk_cli[0]));
-
- /* Make sure we can register our channel type */
- if (ast_channel_register(&gtalk_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", gtalk_tech.type);
- return -1;
- }
- return 0;
-}
-
-/*! \brief Reload module */
-static int reload(void)
-{
- return 0;
-}
-
-/*! \brief Unload the gtalk channel from Asterisk */
-static int unload_module(void)
-{
- struct gtalk_pvt *privates = NULL;
- ast_cli_unregister_multiple(gtalk_cli, sizeof(gtalk_cli) / sizeof(gtalk_cli[0]));
- /* First, take us out of the channel loop */
- ast_channel_unregister(&gtalk_tech);
- ast_rtp_proto_unregister(&gtalk_rtp);
-
- if (!ast_mutex_lock(&gtalklock)) {
- /* Hangup all interfaces if they have an owner */
- ASTOBJ_CONTAINER_TRAVERSE(&gtalk_list, 1, {
- ASTOBJ_WRLOCK(iterator);
- privates = iterator->p;
- while(privates) {
- if (privates->owner)
- ast_softhangup(privates->owner, AST_SOFTHANGUP_APPUNLOAD);
- privates = privates->next;
- }
- iterator->p = NULL;
- ASTOBJ_UNLOCK(iterator);
- });
- ast_mutex_unlock(&gtalklock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- return -1;
- }
- ASTOBJ_CONTAINER_DESTROYALL(&gtalk_list, gtalk_member_destroy);
- ASTOBJ_CONTAINER_DESTROY(&gtalk_list);
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Gtalk Channel Driver",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/chan_h323.c b/1.4/channels/chan_h323.c
deleted file mode 100644
index 3ae300876..000000000
--- a/1.4/channels/chan_h323.c
+++ /dev/null
@@ -1,3275 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005
- *
- * OpenH323 Channel Driver for ASTERISK PBX.
- * By Jeremy McNamara
- * For The NuFone Network
- *
- * chan_h323 has been derived from code created by
- * Michael Manousos and Mark Spencer
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief This file is part of the chan_h323 driver for Asterisk
- *
- * \author Jeremy McNamara
- *
- * \par See also
- * \arg Config_h323
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>openh323</depend>
- <defaultenabled>yes</defaultenabled>
- ***/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#ifdef __cplusplus
-}
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <sys/param.h>
-#if defined(BSD) || defined(SOLARIS)
-#ifndef IPTOS_MINCOST
-#define IPTOS_MINCOST 0x02
-#endif
-#endif
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/cli.h"
-#include "asterisk/dsp.h"
-#include "asterisk/causes.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/astobj.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-#include "h323/chan_h323.h"
-
-receive_digit_cb on_receive_digit;
-on_rtp_cb on_external_rtp_create;
-start_rtp_cb on_start_rtp_channel;
-setup_incoming_cb on_incoming_call;
-setup_outbound_cb on_outgoing_call;
-chan_ringing_cb on_chan_ringing;
-con_established_cb on_connection_established;
-clear_con_cb on_connection_cleared;
-answer_call_cb on_answer_call;
-progress_cb on_progress;
-rfc2833_cb on_set_rfc2833_payload;
-hangup_cb on_hangup;
-setcapabilities_cb on_setcapabilities;
-setpeercapabilities_cb on_setpeercapabilities;
-
-/* global debug flag */
-int h323debug;
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-/** Variables required by Asterisk */
-static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
-static const char config[] = "h323.conf";
-static char default_context[AST_MAX_CONTEXT] = "default";
-static struct sockaddr_in bindaddr;
-
-#define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261)
-
-/** H.323 configuration values */
-static int h323_signalling_port = 1720;
-static char gatekeeper[100];
-static int gatekeeper_disable = 1;
-static int gatekeeper_discover = 0;
-static int gkroute = 0;
-/* Find user by alias (h.323 id) is default, alternative is the incomming call's source IP address*/
-static int userbyalias = 1;
-static int acceptAnonymous = 1;
-static int tos = 0;
-static char secret[50];
-static unsigned int unique = 0;
-
-static call_options_t global_options;
-
-/** Private structure of a OpenH323 channel */
-struct oh323_pvt {
- ast_mutex_t lock; /* Channel private lock */
- call_options_t options; /* Options to be used during call setup */
- int alreadygone; /* Whether or not we've already been destroyed by our peer */
- int needdestroy; /* if we need to be destroyed */
- call_details_t cd; /* Call details */
- struct ast_channel *owner; /* Who owns us */
- struct sockaddr_in sa; /* Our peer */
- struct sockaddr_in redirip; /* Where our RTP should be going if not to us */
- int nonCodecCapability; /* non-audio capability */
- int outgoing; /* Outgoing or incoming call? */
- char exten[AST_MAX_EXTENSION]; /* Requested extension */
- char context[AST_MAX_CONTEXT]; /* Context where to start */
- char accountcode[256]; /* Account code */
- char rdnis[80]; /* Referring DNIS, if available */
- int amaflags; /* AMA Flags */
- struct ast_rtp *rtp; /* RTP Session */
- struct ast_dsp *vad; /* Used for in-band DTMF detection */
- int nativeformats; /* Codec formats supported by a channel */
- int needhangup; /* Send hangup when Asterisk is ready */
- int hangupcause; /* Hangup cause from OpenH323 layer */
- int newstate; /* Pending state change */
- int newcontrol; /* Pending control to send */
- int newdigit; /* Pending DTMF digit to send */
- int newduration; /* Pending DTMF digit duration to send */
- int pref_codec; /* Preferred codec */
- int peercapability; /* Capabilities learned from peer */
- int jointcapability; /* Common capabilities for local and remote side */
- struct ast_codec_pref peer_prefs; /* Preferenced list of codecs which remote side supports */
- int dtmf_pt; /* Payload code used for RFC2833 messages */
- int curDTMF; /* DTMF tone being generated to Asterisk side */
- int DTMFsched; /* Scheduler descriptor for DTMF */
- int update_rtp_info; /* Configuration of fd's array is pending */
- int recvonly; /* Peer isn't wish to receive our voice stream */
- int txDtmfDigit; /* DTMF digit being to send to H.323 side */
- int noInbandDtmf; /* Inband DTMF processing by DSP isn't available */
- int connection_established; /* Call got CONNECT message */
- int got_progress; /* Call got PROGRESS message, pass inband audio */
- struct oh323_pvt *next; /* Next channel in list */
-} *iflist = NULL;
-
-static struct ast_user_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user);
-} userl;
-
-static struct ast_peer_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer);
-} peerl;
-
-static struct ast_alias_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias);
-} aliasl;
-
-/** Asterisk RTP stuff */
-static struct sched_context *sched;
-static struct io_context *io;
-
-/** Protect the interface list (oh323_pvt) */
-AST_MUTEX_DEFINE_STATIC(iflock);
-
-/* Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
-
-/* Protect the H.323 capabilities list, to avoid more than one channel to set the capabilities simultaneaously in the h323 stack. */
-AST_MUTEX_DEFINE_STATIC(caplock);
-
-/* Protect the reload process */
-AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
-static int h323_reloading = 0;
-
-/* This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-static int restart_monitor(void);
-static int h323_do_reload(void);
-
-static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause);
-static int oh323_digit_begin(struct ast_channel *c, char digit);
-static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
-static int oh323_call(struct ast_channel *c, char *dest, int timeout);
-static int oh323_hangup(struct ast_channel *c);
-static int oh323_answer(struct ast_channel *c);
-static struct ast_frame *oh323_read(struct ast_channel *c);
-static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
-static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
-static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-
-static const struct ast_channel_tech oh323_tech = {
- .type = "H323",
- .description = tdesc,
- .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
- .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
- .requester = oh323_request,
- .send_digit_begin = oh323_digit_begin,
- .send_digit_end = oh323_digit_end,
- .call = oh323_call,
- .hangup = oh323_hangup,
- .answer = oh323_answer,
- .read = oh323_read,
- .write = oh323_write,
- .indicate = oh323_indicate,
- .fixup = oh323_fixup,
- /* disable, for now */
-#if 0
- .bridge = ast_rtp_bridge,
-#endif
-};
-
-static const char* redirectingreason2str(int redirectingreason)
-{
- switch (redirectingreason) {
- case 0:
- return "UNKNOWN";
- case 1:
- return "BUSY";
- case 2:
- return "NO_REPLY";
- case 0xF:
- return "UNCONDITIONAL";
- default:
- return "NOREDIRECT";
- }
-}
-
-static void oh323_destroy_alias(struct oh323_alias *alias)
-{
- if (h323debug)
- ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name);
- free(alias);
-}
-
-static void oh323_destroy_user(struct oh323_user *user)
-{
- if (h323debug)
- ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name);
- ast_free_ha(user->ha);
- free(user);
-}
-
-static void oh323_destroy_peer(struct oh323_peer *peer)
-{
- if (h323debug)
- ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name);
- ast_free_ha(peer->ha);
- free(peer);
-}
-
-static int oh323_simulate_dtmf_end(const void *data)
-{
- struct oh323_pvt *pvt = (struct oh323_pvt *)data;
-
- if (pvt) {
- ast_mutex_lock(&pvt->lock);
- /* Don't hold pvt lock while trying to lock the channel */
- while(pvt->owner && ast_channel_trylock(pvt->owner)) {
- ast_mutex_unlock(&pvt->lock);
- usleep(1);
- ast_mutex_lock(&pvt->lock);
- }
-
- if (pvt->owner) {
- struct ast_frame f = {
- .frametype = AST_FRAME_DTMF_END,
- .subclass = pvt->curDTMF,
- .samples = 0,
- .src = "SIMULATE_DTMF_END",
- };
- ast_queue_frame(pvt->owner, &f);
- ast_channel_unlock(pvt->owner);
- }
-
- pvt->DTMFsched = -1;
- ast_mutex_unlock(&pvt->lock);
- }
-
- return 0;
-}
-
-/* Channel and private structures should be already locked */
-static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
-{
- if (c->nativeformats != pvt->nativeformats) {
- if (h323debug)
- ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name);
- c->nativeformats = pvt->nativeformats;
- ast_set_read_format(c, c->readformat);
- ast_set_write_format(c, c->writeformat);
- }
- if (pvt->needhangup) {
- if (h323debug)
- ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name);
- c->_softhangup |= AST_SOFTHANGUP_DEV;
- c->hangupcause = pvt->hangupcause;
- ast_queue_hangup(c);
- pvt->needhangup = 0;
- pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
- }
- if (pvt->newstate >= 0) {
- ast_setstate(c, pvt->newstate);
- pvt->newstate = -1;
- }
- if (pvt->newcontrol >= 0) {
- ast_queue_control(c, pvt->newcontrol);
- pvt->newcontrol = -1;
- }
- if (pvt->newdigit >= 0) {
- struct ast_frame f = {
- .frametype = AST_FRAME_DTMF_END,
- .subclass = pvt->newdigit,
- .samples = pvt->newduration * 8,
- .len = pvt->newduration,
- .src = "UPDATE_INFO",
- };
- if (pvt->newdigit == ' ') { /* signalUpdate message */
- f.subclass = pvt->curDTMF;
- if (pvt->DTMFsched >= 0) {
- AST_SCHED_DEL(sched, pvt->DTMFsched);
- }
- } else { /* Regular input or signal message */
- if (pvt->newduration) { /* This is a signal, signalUpdate follows */
- f.frametype = AST_FRAME_DTMF_BEGIN;
- AST_SCHED_DEL(sched, pvt->DTMFsched);
- pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt);
- if (h323debug)
- ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
- }
- pvt->curDTMF = pvt->newdigit;
- }
- ast_queue_frame(c, &f);
- pvt->newdigit = -1;
- }
- if (pvt->update_rtp_info > 0) {
- if (pvt->rtp) {
- ast_jb_configure(c, &global_jbconf);
- c->fds[0] = ast_rtp_fd(pvt->rtp);
- c->fds[1] = ast_rtcp_fd(pvt->rtp);
- ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */
- }
- pvt->update_rtp_info = -1;
- }
-}
-
-/* Only channel structure should be locked */
-static void oh323_update_info(struct ast_channel *c)
-{
- struct oh323_pvt *pvt = c->tech_pvt;
-
- if (pvt) {
- ast_mutex_lock(&pvt->lock);
- __oh323_update_info(c, pvt);
- ast_mutex_unlock(&pvt->lock);
- }
-}
-
-static void cleanup_call_details(call_details_t *cd)
-{
- if (cd->call_token) {
- free(cd->call_token);
- cd->call_token = NULL;
- }
- if (cd->call_source_aliases) {
- free(cd->call_source_aliases);
- cd->call_source_aliases = NULL;
- }
- if (cd->call_dest_alias) {
- free(cd->call_dest_alias);
- cd->call_dest_alias = NULL;
- }
- if (cd->call_source_name) {
- free(cd->call_source_name);
- cd->call_source_name = NULL;
- }
- if (cd->call_source_e164) {
- free(cd->call_source_e164);
- cd->call_source_e164 = NULL;
- }
- if (cd->call_dest_e164) {
- free(cd->call_dest_e164);
- cd->call_dest_e164 = NULL;
- }
- if (cd->sourceIp) {
- free(cd->sourceIp);
- cd->sourceIp = NULL;
- }
- if (cd->redirect_number) {
- free(cd->redirect_number);
- cd->redirect_number = NULL;
- }
-}
-
-static void __oh323_destroy(struct oh323_pvt *pvt)
-{
- struct oh323_pvt *cur, *prev = NULL;
-
- AST_SCHED_DEL(sched, pvt->DTMFsched);
-
- if (pvt->rtp) {
- ast_rtp_destroy(pvt->rtp);
- }
-
- /* Free dsp used for in-band DTMF detection */
- if (pvt->vad) {
- ast_dsp_free(pvt->vad);
- }
- cleanup_call_details(&pvt->cd);
-
- /* Unlink us from the owner if we have one */
- if (pvt->owner) {
- ast_channel_lock(pvt->owner);
- if (h323debug)
- ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name);
- pvt->owner->tech_pvt = NULL;
- ast_channel_unlock(pvt->owner);
- }
- cur = iflist;
- while(cur) {
- if (cur == pvt) {
- if (prev)
- prev->next = cur->next;
- else
- iflist = cur->next;
- break;
- }
- prev = cur;
- cur = cur->next;
- }
- if (!cur) {
- ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
- } else {
- ast_mutex_unlock(&pvt->lock);
- ast_mutex_destroy(&pvt->lock);
- free(pvt);
- }
-}
-
-static void oh323_destroy(struct oh323_pvt *pvt)
-{
- if (h323debug) {
- ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>"));
- }
- ast_mutex_lock(&iflock);
- ast_mutex_lock(&pvt->lock);
- __oh323_destroy(pvt);
- ast_mutex_unlock(&iflock);
-}
-
-static int oh323_digit_begin(struct ast_channel *c, char digit)
-{
- struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
- char *token;
-
- if (!pvt) {
- ast_log(LOG_ERROR, "No private structure?! This is bad\n");
- return -1;
- }
- ast_mutex_lock(&pvt->lock);
- if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
- /* out-of-band DTMF */
- if (h323debug) {
- ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name);
- }
- ast_rtp_senddigit_begin(pvt->rtp, digit);
- ast_mutex_unlock(&pvt->lock);
- } else if (pvt->txDtmfDigit != digit) {
- /* in-band DTMF */
- if (h323debug) {
- ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name);
- }
- pvt->txDtmfDigit = digit;
- token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
- ast_mutex_unlock(&pvt->lock);
- h323_send_tone(token, digit);
- if (token) {
- free(token);
- }
- } else
- ast_mutex_unlock(&pvt->lock);
- oh323_update_info(c);
- return 0;
-}
-
-/**
- * Send (play) the specified digit to the channel.
- *
- */
-static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
-{
- struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
- char *token;
-
- if (!pvt) {
- ast_log(LOG_ERROR, "No private structure?! This is bad\n");
- return -1;
- }
- ast_mutex_lock(&pvt->lock);
- if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
- /* out-of-band DTMF */
- if (h323debug) {
- ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration);
- }
- ast_rtp_senddigit_end(pvt->rtp, digit);
- ast_mutex_unlock(&pvt->lock);
- } else {
- /* in-band DTMF */
- if (h323debug) {
- ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration);
- }
- pvt->txDtmfDigit = ' ';
- token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
- ast_mutex_unlock(&pvt->lock);
- h323_send_tone(token, ' ');
- if (token) {
- free(token);
- }
- }
- oh323_update_info(c);
- return 0;
-}
-
-/**
- * Make a call over the specified channel to the specified
- * destination.
- * Returns -1 on error, 0 on success.
- */
-static int oh323_call(struct ast_channel *c, char *dest, int timeout)
-{
- int res = 0;
- struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
- const char *addr;
- char called_addr[1024];
-
- if (h323debug) {
- ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name);
- }
- if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name);
- return -1;
- }
- ast_mutex_lock(&pvt->lock);
- if (!gatekeeper_disable) {
- if (ast_strlen_zero(pvt->exten)) {
- ast_copy_string(called_addr, dest, sizeof(called_addr));
- } else {
- snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
- }
- } else {
- res = htons(pvt->sa.sin_port);
- addr = ast_inet_ntoa(pvt->sa.sin_addr);
- if (ast_strlen_zero(pvt->exten)) {
- snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
- } else {
- snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res);
- }
- }
- /* make sure null terminated */
- called_addr[sizeof(called_addr) - 1] = '\0';
-
- if (c->cid.cid_num)
- ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num));
-
- if (c->cid.cid_name)
- ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name));
-
- if (c->cid.cid_rdnis) {
- ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis));
- }
-
- pvt->options.presentation = c->cid.cid_pres;
- pvt->options.type_of_number = c->cid.cid_ton;
-
- if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
- if (!strcasecmp(addr, "UNKNOWN"))
- pvt->options.redirect_reason = 0;
- else if (!strcasecmp(addr, "BUSY"))
- pvt->options.redirect_reason = 1;
- else if (!strcasecmp(addr, "NO_REPLY"))
- pvt->options.redirect_reason = 2;
- else if (!strcasecmp(addr, "UNCONDITIONAL"))
- pvt->options.redirect_reason = 15;
- else
- pvt->options.redirect_reason = -1;
- } else
- pvt->options.redirect_reason = -1;
-
- pvt->options.transfer_capability = c->transfercapability;
-
- /* indicate that this is an outgoing call */
- pvt->outgoing = 1;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability));
- if (h323debug)
- ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
- ast_mutex_unlock(&pvt->lock);
- res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
- if (res) {
- ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
- return -1;
- }
- oh323_update_info(c);
- return 0;
-}
-
-static int oh323_answer(struct ast_channel *c)
-{
- int res;
- struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
- char *token;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Answering on %s\n", c->name);
-
- ast_mutex_lock(&pvt->lock);
- token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
- ast_mutex_unlock(&pvt->lock);
- res = h323_answering_call(token, 0);
- if (token)
- free(token);
-
- oh323_update_info(c);
- if (c->_state != AST_STATE_UP) {
- ast_setstate(c, AST_STATE_UP);
- }
- return res;
-}
-
-static int oh323_hangup(struct ast_channel *c)
-{
- struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
- int q931cause = AST_CAUSE_NORMAL_CLEARING;
- char *call_token;
-
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name);
-
- if (!c->tech_pvt) {
- ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
- return 0;
- }
- ast_mutex_lock(&pvt->lock);
- /* Determine how to disconnect */
- if (pvt->owner != c) {
- ast_log(LOG_WARNING, "Huh? We aren't the owner?\n");
- ast_mutex_unlock(&pvt->lock);
- return 0;
- }
-
- pvt->owner = NULL;
- c->tech_pvt = NULL;
-
- if (c->hangupcause) {
- q931cause = c->hangupcause;
- } else {
- const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS");
- if (cause) {
- if (!strcmp(cause, "CONGESTION")) {
- q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
- } else if (!strcmp(cause, "BUSY")) {
- q931cause = AST_CAUSE_USER_BUSY;
- } else if (!strcmp(cause, "CHANISUNVAIL")) {
- q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
- } else if (!strcmp(cause, "NOANSWER")) {
- q931cause = AST_CAUSE_NO_ANSWER;
- } else if (!strcmp(cause, "CANCEL")) {
- q931cause = AST_CAUSE_CALL_REJECTED;
- }
- }
- }
-
- /* Start the process if it's not already started */
- if (!pvt->alreadygone && !pvt->hangupcause) {
- call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
- if (call_token) {
- /* Release lock to eliminate deadlock */
- ast_mutex_unlock(&pvt->lock);
- if (h323_clear_call(call_token, q931cause)) {
- ast_log(LOG_WARNING, "ClearCall failed.\n");
- }
- free(call_token);
- ast_mutex_lock(&pvt->lock);
- }
- }
- pvt->needdestroy = 1;
- ast_mutex_unlock(&pvt->lock);
-
- /* Update usage counter */
- ast_module_unref(ast_module_info->self);
-
- return 0;
-}
-
-static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
-{
- /* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */
- struct ast_frame *f;
-
- /* Only apply it for the first packet, we just need the correct ip/port */
- if (pvt->options.nat) {
- ast_rtp_setnat(pvt->rtp, pvt->options.nat);
- pvt->options.nat = 0;
- }
-
- f = ast_rtp_read(pvt->rtp);
- /* Don't send RFC2833 if we're not supposed to */
- if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
- return &ast_null_frame;
- }
- if (pvt->owner) {
- /* We already hold the channel lock */
- if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass != pvt->owner->nativeformats) {
- /* Try to avoid deadlock */
- if (ast_channel_trylock(pvt->owner)) {
- ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
- return &ast_null_frame;
- }
- if (h323debug)
- ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
- pvt->owner->nativeformats = f->subclass;
- pvt->nativeformats = f->subclass;
- ast_set_read_format(pvt->owner, pvt->owner->readformat);
- ast_set_write_format(pvt->owner, pvt->owner->writeformat);
- ast_channel_unlock(pvt->owner);
- }
- /* Do in-band DTMF detection */
- if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
- if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) {
- if (!ast_channel_trylock(pvt->owner)) {
- f = ast_dsp_process(pvt->owner, pvt->vad, f);
- ast_channel_unlock(pvt->owner);
- }
- else
- ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
- } else if (pvt->nativeformats && !pvt->noInbandDtmf) {
- ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass));
- pvt->noInbandDtmf = 1;
- }
- if (f &&(f->frametype == AST_FRAME_DTMF)) {
- if (h323debug)
- ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass);
- }
- }
- }
- }
- return f;
-}
-
-static struct ast_frame *oh323_read(struct ast_channel *c)
-{
- struct ast_frame *fr;
- struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
- ast_mutex_lock(&pvt->lock);
- __oh323_update_info(c, pvt);
- switch(c->fdno) {
- case 0:
- fr = oh323_rtp_read(pvt);
- break;
- case 1:
- if (pvt->rtp)
- fr = ast_rtcp_read(pvt->rtp);
- else
- fr = &ast_null_frame;
- break;
- default:
- ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name);
- fr = &ast_null_frame;
- break;
- }
- ast_mutex_unlock(&pvt->lock);
- return fr;
-}
-
-static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
-{
- struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
- int res = 0;
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype == AST_FRAME_IMAGE) {
- return 0;
- } else {
- ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
- return 0;
- }
- } else {
- if (!(frame->subclass & c->nativeformats)) {
- ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
- frame->subclass, c->nativeformats, c->readformat, c->writeformat);
- return 0;
- }
- }
- if (pvt) {
- ast_mutex_lock(&pvt->lock);
- if (pvt->rtp && !pvt->recvonly)
- res = ast_rtp_write(pvt->rtp, frame);
- __oh323_update_info(c, pvt);
- ast_mutex_unlock(&pvt->lock);
- }
- return res;
-}
-
-static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
-{
-
- struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
- char *token = (char *)NULL;
- int res = -1;
- int got_progress;
-
- ast_mutex_lock(&pvt->lock);
- token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL);
- got_progress = pvt->got_progress;
- if (condition == AST_CONTROL_PROGRESS)
- pvt->got_progress = 1;
- else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION))
- pvt->alreadygone = 1;
- ast_mutex_unlock(&pvt->lock);
-
- if (h323debug)
- ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token);
-
- switch(condition) {
- case AST_CONTROL_RINGING:
- if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
- h323_send_alerting(token);
- res = (got_progress ? 0 : -1); /* Do not simulate any audio tones if we got PROGRESS message */
- }
- break;
- case AST_CONTROL_PROGRESS:
- if (c->_state != AST_STATE_UP) {
- /* Do not send PROGRESS message more than once */
- if (!got_progress)
- h323_send_progress(token);
- res = 0;
- }
- break;
- case AST_CONTROL_BUSY:
- if (c->_state != AST_STATE_UP) {
- h323_answering_call(token, 1);
- ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
- res = 0;
- }
- break;
- case AST_CONTROL_CONGESTION:
- if (c->_state != AST_STATE_UP) {
- h323_answering_call(token, 1);
- ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
- res = 0;
- }
- break;
- case AST_CONTROL_HOLD:
- ast_moh_start(c, data, NULL);
- res = 0;
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(c);
- res = 0;
- break;
- case AST_CONTROL_SRCUPDATE:
- ast_rtp_new_source(pvt->rtp);
- res = 0;
- break;
- case AST_CONTROL_PROCEEDING:
- case -1:
- break;
- default:
- ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);
- break;
- }
-
- if (h323debug)
- ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);
- if (token)
- free(token);
- oh323_update_info(c);
-
- return res;
-}
-
-static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
-
- ast_mutex_lock(&pvt->lock);
- if (pvt->owner != oldchan) {
- ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
- return -1;
- }
- pvt->owner = newchan;
- ast_mutex_unlock(&pvt->lock);
- return 0;
-}
-
-static int __oh323_rtp_create(struct oh323_pvt *pvt)
-{
- struct in_addr our_addr;
-
- if (pvt->rtp)
- return 0;
-
- if (ast_find_ourip(&our_addr, bindaddr)) {
- ast_mutex_unlock(&pvt->lock);
- ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
- return -1;
- }
- pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr);
- if (!pvt->rtp) {
- ast_mutex_unlock(&pvt->lock);
- ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
- return -1;
- }
- if (h323debug)
- ast_log(LOG_DEBUG, "Created RTP channel\n");
-
- ast_rtp_settos(pvt->rtp, tos);
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
- ast_rtp_setnat(pvt->rtp, pvt->options.nat);
-
- if (pvt->dtmf_pt > 0)
- ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0);
-
- if (pvt->peercapability)
- ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);
-
- if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
- ast_jb_configure(pvt->owner, &global_jbconf);
- pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp);
- pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp);
- ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */
- ast_channel_unlock(pvt->owner);
- } else
- pvt->update_rtp_info = 1;
-
- return 0;
-}
-
-/* Private structure should be locked on a call */
-static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host)
-{
- struct ast_channel *ch;
- char *cid_num, *cid_name;
- int fmt;
-
- if (!ast_strlen_zero(pvt->options.cid_num))
- cid_num = pvt->options.cid_num;
- else
- cid_num = pvt->cd.call_source_e164;
-
- if (!ast_strlen_zero(pvt->options.cid_name))
- cid_name = pvt->options.cid_name;
- else
- cid_name = pvt->cd.call_source_name;
-
- /* Don't hold a oh323_pvt lock while we allocate a chanel */
- ast_mutex_unlock(&pvt->lock);
- ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host);
- /* Update usage counter */
- ast_module_ref(ast_module_info->self);
- ast_mutex_lock(&pvt->lock);
- if (ch) {
- ch->tech = &oh323_tech;
- if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
- fmt = global_options.capability;
- ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
- pvt->nativeformats = ch->nativeformats;
- fmt = ast_best_codec(ch->nativeformats);
- ch->writeformat = fmt;
- ch->rawwriteformat = fmt;
- ch->readformat = fmt;
- ch->rawreadformat = fmt;
-#if 0
- ch->fds[0] = ast_rtp_fd(pvt->rtp);
- ch->fds[1] = ast_rtcp_fd(pvt->rtp);
-#endif
-#ifdef VIDEO_SUPPORT
- if (pvt->vrtp) {
- ch->fds[2] = ast_rtp_fd(pvt->vrtp);
- ch->fds[3] = ast_rtcp_fd(pvt->vrtp);
- }
-#endif
-#ifdef T38_SUPPORT
- if (pvt->udptl) {
- ch->fds[4] = ast_udptl_fd(pvt->udptl);
- }
-#endif
- if (state == AST_STATE_RING) {
- ch->rings = 1;
- }
- /* Allocate dsp for in-band DTMF support */
- if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
- pvt->vad = ast_dsp_new();
- ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);
- }
- /* Register channel functions. */
- ch->tech_pvt = pvt;
- /* Set the owner of this channel */
- pvt->owner = ch;
-
- ast_copy_string(ch->context, pvt->context, sizeof(ch->context));
- ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten));
- ch->priority = 1;
- if (!ast_strlen_zero(pvt->accountcode)) {
- ast_string_field_set(ch, accountcode, pvt->accountcode);
- }
- if (pvt->amaflags) {
- ch->amaflags = pvt->amaflags;
- }
-
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
- ch->cid.cid_ani = ast_strdup(cid_num);
-
- if (pvt->cd.redirect_reason >= 0) {
- ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number);
- pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
- }
- ch->cid.cid_pres = pvt->cd.presentation;
- ch->cid.cid_ton = pvt->cd.type_of_number;
-
- if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
- ch->cid.cid_dnid = strdup(pvt->exten);
- }
- if (pvt->cd.transfer_capability >= 0)
- ch->transfercapability = pvt->cd.transfer_capability;
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(ch)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
- ast_hangup(ch);
- ch = NULL;
- }
- }
- } else {
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- }
- return ch;
-}
-
-static struct oh323_pvt *oh323_alloc(int callid)
-{
- struct oh323_pvt *pvt;
-
- pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt));
- if (!pvt) {
- ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
- return NULL;
- }
- memset(pvt, 0, sizeof(struct oh323_pvt));
- pvt->cd.redirect_reason = -1;
- pvt->cd.transfer_capability = -1;
- /* Ensure the call token is allocated for outgoing call */
- if (!callid) {
- if ((pvt->cd).call_token == NULL) {
- (pvt->cd).call_token = (char *)malloc(128);
- }
- if (!pvt->cd.call_token) {
- ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
- ast_rtp_destroy(pvt->rtp);
- free(pvt);
- return NULL;
- }
- memset((char *)(pvt->cd).call_token, 0, 128);
- pvt->cd.call_reference = callid;
- }
- memcpy(&pvt->options, &global_options, sizeof(pvt->options));
- pvt->jointcapability = pvt->options.capability;
- if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
- pvt->nonCodecCapability |= AST_RTP_DTMF;
- } else {
- pvt->nonCodecCapability &= ~AST_RTP_DTMF;
- }
- ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
- pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;
- ast_mutex_init(&pvt->lock);
- /* Add to interface list */
- ast_mutex_lock(&iflock);
- pvt->next = iflist;
- iflist = pvt;
- ast_mutex_unlock(&iflock);
- return pvt;
-}
-
-static struct oh323_pvt *find_call_locked(int call_reference, const char *token)
-{
- struct oh323_pvt *pvt;
-
- ast_mutex_lock(&iflock);
- pvt = iflist;
- while(pvt) {
- if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
- /* Found the call */
- if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
- ast_mutex_lock(&pvt->lock);
- ast_mutex_unlock(&iflock);
- return pvt;
- } else if (token == NULL) {
- ast_log(LOG_WARNING, "Call Token is NULL\n");
- ast_mutex_lock(&pvt->lock);
- ast_mutex_unlock(&iflock);
- return pvt;
- }
- }
- pvt = pvt->next;
- }
- ast_mutex_unlock(&iflock);
- return NULL;
-}
-
-static int update_state(struct oh323_pvt *pvt, int state, int signal)
-{
- if (!pvt)
- return 0;
- if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
- if (state >= 0)
- ast_setstate(pvt->owner, state);
- if (signal >= 0)
- ast_queue_control(pvt->owner, signal);
- ast_channel_unlock(pvt->owner);
- return 1;
- }
- else {
- if (state >= 0)
- pvt->newstate = state;
- if (signal >= 0)
- pvt->newcontrol = signal;
- return 0;
- }
-}
-
-static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
-{
- struct oh323_alias *alias;
- int found = 0;
-
- alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
-
- if (alias)
- found++;
- else {
- if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias))))
- return NULL;
- ASTOBJ_INIT(alias);
- }
- if (!found && name)
- ast_copy_string(alias->name, name, sizeof(alias->name));
- for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
- if (!strcasecmp(v->name, "e164")) {
- ast_copy_string(alias->e164, v->value, sizeof(alias->e164));
- } else if (!strcasecmp(v->name, "prefix")) {
- ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(alias->context, v->value, sizeof(alias->context));
- } else if (!strcasecmp(v->name, "secret")) {
- ast_copy_string(alias->secret, v->value, sizeof(alias->secret));
- } else {
- if (strcasecmp(v->value, "h323")) {
- ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);
- }
- }
- }
- ASTOBJ_UNMARK(alias);
- return alias;
-}
-
-static struct oh323_alias *realtime_alias(const char *alias)
-{
- struct ast_variable *var, *tmp;
- struct oh323_alias *a;
-
- var = ast_load_realtime("h323", "name", alias, NULL);
-
- if (!var)
- return NULL;
-
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "type") &&
- !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {
- ast_variables_destroy(var);
- return NULL;
- }
- }
-
- a = build_alias(alias, var, NULL, 1);
-
- ast_variables_destroy(var);
-
- return a;
-}
-
-#define DEPRECATED(_v, _new_opt) \
- ast_log(LOG_WARNING, "Option %s found at line %d has beed deprecated. Use %s instead.\n", (_v)->name, (_v)->lineno, (_new_opt))
-
-static int update_common_options(struct ast_variable *v, struct call_options *options)
-{
- int tmp;
-
- if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
- } else if (!strcasecmp(v->name, "dtmfmode")) {
- if (!strcasecmp(v->value, "inband")) {
- options->dtmfmode = H323_DTMF_INBAND;
- } else if (!strcasecmp(v->value, "rfc2833")) {
- options->dtmfmode = H323_DTMF_RFC2833;
- } else {
- ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
- options->dtmfmode = H323_DTMF_RFC2833;
- }
- } else if (!strcasecmp(v->name, "dtmfcodec")) {
- tmp = atoi(v->value);
- if (tmp < 96)
- ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
- else
- options->dtmfcodec = tmp;
- } else if (!strcasecmp(v->name, "bridge")) {
- options->bridge = ast_true(v->value);
- } else if (!strcasecmp(v->name, "nat")) {
- options->nat = ast_true(v->value);
- } else if (!strcasecmp(v->name, "noFastStart")) {
- DEPRECATED(v, "fastStart");
- options->fastStart = !ast_true(v->value);
- } else if (!strcasecmp(v->name, "fastStart")) {
- options->fastStart = ast_true(v->value);
- } else if (!strcasecmp(v->name, "noH245Tunneling")) {
- DEPRECATED(v, "h245Tunneling");
- options->h245Tunneling = !ast_true(v->value);
- } else if (!strcasecmp(v->name, "h245Tunneling")) {
- options->h245Tunneling = ast_true(v->value);
- } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
- DEPRECATED(v, "silenceSuppression");
- options->silenceSuppression = !ast_true(v->value);
- } else if (!strcasecmp(v->name, "silenceSuppression")) {
- options->silenceSuppression = ast_true(v->value);
- } else if (!strcasecmp(v->name, "progress_setup")) {
- tmp = atoi(v->value);
- if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
- ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
- tmp = 0;
- }
- options->progress_setup = tmp;
- } else if (!strcasecmp(v->name, "progress_alert")) {
- tmp = atoi(v->value);
- if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {
- ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
- tmp = 0;
- }
- options->progress_alert = tmp;
- } else if (!strcasecmp(v->name, "progress_audio")) {
- options->progress_audio = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callerid")) {
- ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));
- } else if (!strcasecmp(v->name, "fullname")) {
- ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));
- } else if (!strcasecmp(v->name, "cid_number")) {
- ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));
- } else if (!strcasecmp(v->name, "tunneling")) {
- if (!strcasecmp(v->value, "none"))
- options->tunnelOptions = 0;
- else if (!strcasecmp(v->value, "cisco"))
- options->tunnelOptions |= H323_TUNNEL_CISCO;
- else if (!strcasecmp(v->value, "qsig"))
- options->tunnelOptions |= H323_TUNNEL_QSIG;
- else
- ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
- } else
- return 1;
-
- return 0;
-}
-#undef DEPRECATED
-
-static struct oh323_user *build_user(char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
-{
- struct oh323_user *user;
- struct ast_ha *oldha;
- int found = 0;
- int format;
-
- user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);
-
- if (user)
- found++;
- else {
- if (!(user = (struct oh323_user *)calloc(1, sizeof(*user))))
- return NULL;
- ASTOBJ_INIT(user);
- }
- oldha = user->ha;
- user->ha = (struct ast_ha *)NULL;
- memcpy(&user->options, &global_options, sizeof(user->options));
- /* Set default context */
- ast_copy_string(user->context, default_context, sizeof(user->context));
- if (user && !found)
- ast_copy_string(user->name, name, sizeof(user->name));
-
-#if 0 /* XXX Port channel variables functionality from chan_sip XXX */
- if (user->chanvars) {
- ast_variables_destroy(user->chanvars);
- user->chanvars = NULL;
- }
-#endif
-
- for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
- if (!update_common_options(v, &user->options))
- continue;
- if (!strcasecmp(v->name, "context")) {
- ast_copy_string(user->context, v->value, sizeof(user->context));
- } else if (!strcasecmp(v->name, "secret")) {
- ast_copy_string(user->secret, v->value, sizeof(user->secret));
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
- } else if (!strcasecmp(v->name, "host")) {
- if (!strcasecmp(v->value, "dynamic")) {
- ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
- ASTOBJ_UNREF(user, oh323_destroy_user);
- return NULL;
- } else if (ast_get_ip(&user->addr, v->value)) {
- ASTOBJ_UNREF(user, oh323_destroy_user);
- return NULL;
- }
- /* Let us know we need to use ip authentication */
- user->host = 1;
- } else if (!strcasecmp(v->name, "amaflags")) {
- format = ast_cdr_amaflags2int(v->value);
- if (format < 0) {
- ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
- } else {
- user->amaflags = format;
- }
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- user->ha = ast_append_ha(v->name, v->value, user->ha);
- }
- }
- ASTOBJ_UNMARK(user);
- ast_free_ha(oldha);
- return user;
-}
-
-static struct oh323_user *realtime_user(const call_details_t *cd)
-{
- struct ast_variable *var, *tmp;
- struct oh323_user *user;
- char *username;
-
- if (userbyalias)
- var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL);
- else {
- username = (char *)NULL;
- var = ast_load_realtime("h323", "host", cd->sourceIp, NULL);
- }
-
- if (!var)
- return NULL;
-
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "type") &&
- !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {
- ast_variables_destroy(var);
- return NULL;
- } else if (!username && !strcasecmp(tmp->name, "name"))
- username = tmp->value;
- }
-
- if (!username) {
- ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);
- ast_variables_destroy(var);
- return NULL;
- }
-
- user = build_user(username, var, NULL, 1);
-
- ast_variables_destroy(var);
-
- return user;
-}
-
-static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
-{
- struct oh323_peer *peer;
- struct ast_ha *oldha;
- int found = 0;
-
- peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
-
- if (peer)
- found++;
- else {
- if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer))))
- return NULL;
- ASTOBJ_INIT(peer);
- }
- oldha = peer->ha;
- peer->ha = NULL;
- memcpy(&peer->options, &global_options, sizeof(peer->options));
- peer->addr.sin_port = htons(h323_signalling_port);
- peer->addr.sin_family = AF_INET;
- if (!found && name)
- ast_copy_string(peer->name, name, sizeof(peer->name));
-
-#if 0 /* XXX Port channel variables functionality from chan_sip XXX */
- if (peer->chanvars) {
- ast_variables_destroy(peer->chanvars);
- peer->chanvars = NULL;
- }
-#endif
- /* Default settings for mailbox */
- peer->mailbox[0] = '\0';
-
- for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
- if (!update_common_options(v, &peer->options))
- continue;
- if (!strcasecmp(v->name, "host")) {
- if (!strcasecmp(v->value, "dynamic")) {
- ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
- ASTOBJ_UNREF(peer, oh323_destroy_peer);
- return NULL;
- }
- if (ast_get_ip(&peer->addr, v->value)) {
- ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
- ASTOBJ_UNREF(peer, oh323_destroy_peer);
- return NULL;
- }
- } else if (!strcasecmp(v->name, "port")) {
- peer->addr.sin_port = htons(atoi(v->value));
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- peer->ha = ast_append_ha(v->name, v->value, peer->ha);
- } else if (!strcasecmp(v->name, "mailbox")) {
- ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
- }
- }
- ASTOBJ_UNMARK(peer);
- ast_free_ha(oldha);
- return peer;
-}
-
-static struct oh323_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
-{
- struct oh323_peer *peer;
- struct ast_variable *var;
- struct ast_variable *tmp;
- const char *addr;
-
- /* First check on peer name */
- if (peername)
- var = ast_load_realtime("h323", "name", peername, addr = NULL);
- else if (sin) /* Then check on IP address for dynamic peers */
- var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL);
- else
- return NULL;
-
- if (!var)
- return NULL;
-
- for (tmp = var; tmp; tmp = tmp->next) {
- /* If this is type=user, then skip this object. */
- if (!strcasecmp(tmp->name, "type") &&
- !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) {
- ast_variables_destroy(var);
- return NULL;
- } else if (!peername && !strcasecmp(tmp->name, "name")) {
- peername = tmp->value;
- }
- }
-
- if (!peername) { /* Did not find peer in realtime */
- ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr);
- ast_variables_destroy(var);
- return NULL;
- }
-
- /* Peer found in realtime, now build it in memory */
- peer = build_peer(peername, var, NULL, 1);
-
- ast_variables_destroy(var);
-
- return peer;
-}
-
-static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
-{
- return strcmp(ast_inet_ntoa(inaddr), addr);
-}
-
-static struct oh323_user *find_user(const call_details_t *cd, int realtime)
-{
- struct oh323_user *u;
-
- if (userbyalias)
- u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases);
- else
- u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str);
-
- if (!u && realtime)
- u = realtime_user(cd);
-
- if (!u && h323debug)
- ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp);
-
- return u;
-}
-
-static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
-{
- int res;
-
- if (!sin)
- res = -1;
- else
- res = inaddrcmp(&addr , sin);
-
- return res;
-}
-
-static struct oh323_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
-{
- struct oh323_peer *p;
-
- if (peer)
- p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
- else
- p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);
-
- if (!p && realtime)
- p = realtime_peer(peer, sin);
-
- if (!p && h323debug)
- ast_log(LOG_DEBUG, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>"));
-
- return p;
-}
-
-static int create_addr(struct oh323_pvt *pvt, char *opeer)
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- struct oh323_peer *p;
- int portno;
- int found = 0;
- char *port;
- char *hostn;
- char peer[256] = "";
-
- ast_copy_string(peer, opeer, sizeof(peer));
- port = strchr(peer, ':');
- if (port) {
- *port = '\0';
- port++;
- }
- pvt->sa.sin_family = AF_INET;
- p = find_peer(peer, NULL, 1);
- if (p) {
- found++;
- memcpy(&pvt->options, &p->options, sizeof(pvt->options));
- pvt->jointcapability = pvt->options.capability;
- if (pvt->options.dtmfmode) {
- if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
- pvt->nonCodecCapability |= AST_RTP_DTMF;
- } else {
- pvt->nonCodecCapability &= ~AST_RTP_DTMF;
- }
- }
- if (p->addr.sin_addr.s_addr) {
- pvt->sa.sin_addr = p->addr.sin_addr;
- pvt->sa.sin_port = p->addr.sin_port;
- }
- ASTOBJ_UNREF(p, oh323_destroy_peer);
- }
- if (!p && !found) {
- hostn = peer;
- if (port) {
- portno = atoi(port);
- } else {
- portno = h323_signalling_port;
- }
- hp = ast_gethostbyname(hostn, &ahp);
- if (hp) {
- memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
- pvt->sa.sin_port = htons(portno);
- /* Look peer by address */
- p = find_peer(NULL, &pvt->sa, 1);
- memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options));
- pvt->jointcapability = pvt->options.capability;
- if (p) {
- ASTOBJ_UNREF(p, oh323_destroy_peer);
- }
- if (pvt->options.dtmfmode) {
- if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
- pvt->nonCodecCapability |= AST_RTP_DTMF;
- } else {
- pvt->nonCodecCapability &= ~AST_RTP_DTMF;
- }
- }
- return 0;
- } else {
- ast_log(LOG_WARNING, "No such host: %s\n", peer);
- return -1;
- }
- } else if (!found) {
- return -1;
- } else {
- return 0;
- }
-}
-static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause)
-{
- int oldformat;
- struct oh323_pvt *pvt;
- struct ast_channel *tmpc = NULL;
- char *dest = (char *)data;
- char *ext, *host;
- char *h323id = NULL;
- char tmp[256], tmp1[256];
-
- if (h323debug)
- ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);
-
- pvt = oh323_alloc(0);
- if (!pvt) {
- ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
- return NULL;
- }
- oldformat = format;
- format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
- oh323_destroy(pvt);
- if (cause)
- *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
- return NULL;
- }
- ast_copy_string(tmp, dest, sizeof(tmp));
- host = strchr(tmp, '@');
- if (host) {
- *host = '\0';
- host++;
- ext = tmp;
- } else {
- ext = strrchr(tmp, '/');
- if (ext)
- *ext++ = '\0';
- host = tmp;
- }
- strtok_r(host, "/", &(h323id));
- if (!ast_strlen_zero(h323id)) {
- h323_set_id(h323id);
- }
- if (ext) {
- ast_copy_string(pvt->exten, ext, sizeof(pvt->exten));
- }
- if (h323debug)
- ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host);
-
- if (gatekeeper_disable) {
- if (create_addr(pvt, host)) {
- oh323_destroy(pvt);
- if (cause)
- *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
- return NULL;
- }
- }
- else {
- memcpy(&pvt->options, &global_options, sizeof(pvt->options));
- pvt->jointcapability = pvt->options.capability;
- if (pvt->options.dtmfmode) {
- if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
- pvt->nonCodecCapability |= AST_RTP_DTMF;
- } else {
- pvt->nonCodecCapability &= ~AST_RTP_DTMF;
- }
- }
- }
-
- ast_mutex_lock(&caplock);
- /* Generate unique channel identifier */
- snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
- tmp1[sizeof(tmp1)-1] = '\0';
- ast_mutex_unlock(&caplock);
-
- ast_mutex_lock(&pvt->lock);
- tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1);
- ast_mutex_unlock(&pvt->lock);
- if (!tmpc) {
- oh323_destroy(pvt);
- if (cause)
- *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
- }
- ast_update_use_count();
- restart_monitor();
- return tmpc;
-}
-
-/** Find a call by alias */
-static struct oh323_alias *find_alias(const char *source_aliases, int realtime)
-{
- struct oh323_alias *a;
-
- a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
-
- if (!a && realtime)
- a = realtime_alias(source_aliases);
-
- return a;
-}
-
-/**
- * Callback for sending digits from H.323 up to asterisk
- *
- */
-static int receive_digit(unsigned call_reference, char digit, const char *token, int duration)
-{
- struct oh323_pvt *pvt;
- int res;
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token);
- return -1;
- }
- if (h323debug)
- ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token);
-
- if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
- if (digit == '!')
- res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH);
- else {
- struct ast_frame f = {
- .frametype = AST_FRAME_DTMF_END,
- .subclass = digit,
- .samples = duration * 8,
- .len = duration,
- .src = "SEND_DIGIT",
- };
- if (digit == ' ') { /* signalUpdate message */
- f.subclass = pvt->curDTMF;
- AST_SCHED_DEL(sched, pvt->DTMFsched);
- } else { /* Regular input or signal message */
- if (pvt->DTMFsched >= 0) {
- /* We still don't send DTMF END from previous event, send it now */
- AST_SCHED_DEL(sched, pvt->DTMFsched);
- f.subclass = pvt->curDTMF;
- f.samples = f.len = 0;
- ast_queue_frame(pvt->owner, &f);
- /* Restore values */
- f.subclass = digit;
- f.samples = duration * 8;
- f.len = duration;
- }
- if (duration) { /* This is a signal, signalUpdate follows */
- f.frametype = AST_FRAME_DTMF_BEGIN;
- pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt);
- if (h323debug)
- ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched);
- }
- pvt->curDTMF = digit;
- }
- res = ast_queue_frame(pvt->owner, &f);
- }
- ast_channel_unlock(pvt->owner);
- } else {
- if (digit == '!')
- pvt->newcontrol = AST_CONTROL_FLASH;
- else {
- pvt->newduration = duration;
- pvt->newdigit = digit;
- }
- res = 0;
- }
- ast_mutex_unlock(&pvt->lock);
- return res;
-}
-
-/**
- * Callback function used to inform the H.323 stack of the local rtp ip/port details
- *
- * Returns the local RTP information
- */
-static struct rtp_info *external_rtp_create(unsigned call_reference, const char * token)
-{
- struct oh323_pvt *pvt;
- struct sockaddr_in us;
- struct rtp_info *info;
-
- info = (struct rtp_info *)malloc(sizeof(struct rtp_info));
- if (!info) {
- ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
- return NULL;
- }
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- free(info);
- ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
- return NULL;
- }
- if (!pvt->rtp)
- __oh323_rtp_create(pvt);
- if (!pvt->rtp) {
- ast_mutex_unlock(&pvt->lock);
- free(info);
- ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference);
- return NULL;
- }
- /* figure out our local RTP port and tell the H.323 stack about it */
- ast_rtp_get_us(pvt->rtp, &us);
- ast_mutex_unlock(&pvt->lock);
-
- ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
- info->port = ntohs(us.sin_port);
- if (h323debug)
- ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
- return info;
-}
-
-/**
- * Definition taken from rtp.c for rtpPayloadType because we need it here.
- */
-struct rtpPayloadType {
- int isAstFormat; /* whether the following code is an AST_FORMAT */
- int code;
-};
-
-/**
- * Call-back function passing remote ip/port information from H.323 to asterisk
- *
- * Returns nothing
- */
-static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
-{
- struct oh323_pvt *pvt;
- struct sockaddr_in them;
- struct rtpPayloadType rtptype;
- int nativeformats_changed;
- enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token);
-
- /* Find the call or allocate a private structure if call not found */
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Something is wrong: rtp\n");
- return;
- }
- if (pvt->alreadygone) {
- ast_mutex_unlock(&pvt->lock);
- return;
- }
-
- if (!pvt->rtp)
- __oh323_rtp_create(pvt);
-
- them.sin_family = AF_INET;
- /* only works for IPv4 */
- them.sin_addr.s_addr = inet_addr(remoteIp);
- them.sin_port = htons(remotePort);
-
- if (them.sin_addr.s_addr) {
- ast_rtp_set_peer(pvt->rtp, &them);
- if (pvt->recvonly) {
- pvt->recvonly = 0;
- rtp_change = NEED_UNHOLD;
- }
- } else {
- ast_rtp_stop(pvt->rtp);
- if (!pvt->recvonly) {
- pvt->recvonly = 1;
- rtp_change = NEED_HOLD;
- }
- }
-
- /* Change native format to reflect information taken from OLC/OLCAck */
- nativeformats_changed = 0;
- if (pt != 128 && pvt->rtp) { /* Payload type is invalid, so try to use previously decided */
- rtptype = ast_rtp_lookup_pt(pvt->rtp, pt);
- if (h323debug)
- ast_log(LOG_DEBUG, "Native format is set to %d from %d by RTP payload type %d\n", rtptype.code, pvt->nativeformats, pt);
- if (pvt->nativeformats != rtptype.code) {
- pvt->nativeformats = rtptype.code;
- nativeformats_changed = 1;
- }
- } else if (h323debug)
- ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
-
- /* Don't try to lock the channel if nothing changed */
- if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
- if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
- /* Re-build translation path only if native format(s) has been changed */
- if (pvt->owner->nativeformats != pvt->nativeformats) {
- if (h323debug)
- ast_log(LOG_DEBUG, "Native format changed to %d from %d, read format is %d, write format is %d\n", pvt->nativeformats, pvt->owner->nativeformats, pvt->owner->readformat, pvt->owner->writeformat);
- pvt->owner->nativeformats = pvt->nativeformats;
- ast_set_read_format(pvt->owner, pvt->owner->readformat);
- ast_set_write_format(pvt->owner, pvt->owner->writeformat);
- }
- if (pvt->options.progress_audio)
- ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
- switch (rtp_change) {
- case NEED_HOLD:
- ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
- break;
- case NEED_UNHOLD:
- ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
- break;
- default:
- break;
- }
- ast_channel_unlock(pvt->owner);
- }
- else {
- if (pvt->options.progress_audio)
- pvt->newcontrol = AST_CONTROL_PROGRESS;
- else if (rtp_change == NEED_HOLD)
- pvt->newcontrol = AST_CONTROL_HOLD;
- else if (rtp_change == NEED_UNHOLD)
- pvt->newcontrol = AST_CONTROL_UNHOLD;
- if (h323debug)
- ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token);
- }
- }
- ast_mutex_unlock(&pvt->lock);
-
- if (h323debug)
- ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token);
-
- return;
-}
-
-/**
- * Call-back function to signal asterisk that the channel has been answered
- * Returns nothing
- */
-static void connection_made(unsigned call_reference, const char *token)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Call %s answered\n", token);
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Something is wrong: connection\n");
- return;
- }
-
- /* Inform asterisk about remote party connected only on outgoing calls */
- if (!pvt->outgoing) {
- ast_mutex_unlock(&pvt->lock);
- return;
- }
- /* Do not send ANSWER message more than once */
- if (!pvt->connection_established) {
- pvt->connection_established = 1;
- update_state(pvt, -1, AST_CONTROL_ANSWER);
- }
- ast_mutex_unlock(&pvt->lock);
- return;
-}
-
-static int progress(unsigned call_reference, const char *token, int inband)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Private structure not found in progress.\n");
- return -1;
- }
- if (!pvt->owner) {
- ast_mutex_unlock(&pvt->lock);
- ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
- return -1;
- }
- update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
- ast_mutex_unlock(&pvt->lock);
-
- return 0;
-}
-
-/**
- * Call-back function for incoming calls
- *
- * Returns 1 on success
- */
-static call_options_t *setup_incoming_call(call_details_t *cd)
-{
- struct oh323_pvt *pvt;
- struct oh323_user *user = NULL;
- struct oh323_alias *alias = NULL;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token);
-
- /* allocate the call*/
- pvt = oh323_alloc(cd->call_reference);
-
- if (!pvt) {
- ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
- cleanup_call_details(cd);
- return NULL;
- }
-
- /* Populate the call details in the private structure */
- memcpy(&pvt->cd, cd, sizeof(pvt->cd));
- memcpy(&pvt->options, &global_options, sizeof(pvt->options));
- pvt->jointcapability = pvt->options.capability;
-
- if (h323debug) {
- ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n");
- ast_verbose(VERBOSE_PREFIX_3 " \tCall token: [%s]\n", pvt->cd.call_token);
- ast_verbose(VERBOSE_PREFIX_3 " \tCalling party name: [%s]\n", pvt->cd.call_source_name);
- ast_verbose(VERBOSE_PREFIX_3 " \tCalling party number: [%s]\n", pvt->cd.call_source_e164);
- ast_verbose(VERBOSE_PREFIX_3 " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias);
- ast_verbose(VERBOSE_PREFIX_3 " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164);
- if (pvt->cd.redirect_reason >= 0)
- ast_verbose(VERBOSE_PREFIX_3 " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason);
- ast_verbose(VERBOSE_PREFIX_3 " \tCalling party IP: [%s]\n", pvt->cd.sourceIp);
- }
-
- /* Decide if we are allowing Gatekeeper routed calls*/
- if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) {
- if (!ast_strlen_zero(cd->call_dest_e164)) {
- ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
- ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
- } else {
- alias = find_alias(cd->call_dest_alias, 1);
- if (!alias) {
- ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
- oh323_destroy(pvt);
- return NULL;
- }
- ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten));
- ast_copy_string(pvt->context, alias->context, sizeof(pvt->context));
- }
- } else {
- /* Either this call is not from the Gatekeeper
- or we are not allowing gk routed calls */
- user = find_user(cd, 1);
- if (!user) {
- if (!acceptAnonymous) {
- ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
- oh323_destroy(pvt);
- return NULL;
- }
- if (ast_strlen_zero(default_context)) {
- ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
- oh323_destroy(pvt);
- return NULL;
- }
- ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
- if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
- ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
- } else {
- ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
- }
- if (h323debug)
- ast_log(LOG_DEBUG, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten);
- } else {
- if (user->host) {
- if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) {
- if (ast_strlen_zero(user->context)) {
- if (ast_strlen_zero(default_context)) {
- ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
- oh323_destroy(pvt);
- ASTOBJ_UNREF(user, oh323_destroy_user);
- return NULL;
- }
- ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
- } else {
- ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
- }
- pvt->exten[0] = 'i';
- pvt->exten[1] = '\0';
- ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
- oh323_destroy(pvt);
- ASTOBJ_UNREF(user, oh323_destroy_user);
- return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */
- }
- }
- ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
- memcpy(&pvt->options, &user->options, sizeof(pvt->options));
- pvt->jointcapability = pvt->options.capability;
- if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
- ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
- } else {
- ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
- }
- if (!ast_strlen_zero(user->accountcode)) {
- ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode));
- }
- if (user->amaflags) {
- pvt->amaflags = user->amaflags;
- }
- ASTOBJ_UNREF(user, oh323_destroy_user);
- }
- }
- return &pvt->options;
-}
-
-/**
- * Call-back function to start PBX when OpenH323 ready to serve incoming call
- *
- * Returns 1 on success
- */
-static int answer_call(unsigned call_reference, const char *token)
-{
- struct oh323_pvt *pvt;
- struct ast_channel *c = NULL;
- enum {ext_original, ext_s, ext_i, ext_notexists} try_exten;
- char tmp_exten[sizeof(pvt->exten)];
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token);
-
- /* Find the call or allocate a private structure if call not found */
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
- return 0;
- }
- /* Check if requested extension@context pair exists in the dialplan */
- ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten));
-
- /* Try to find best extension in specified context */
- if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) {
- if (tmp_exten[0] == 's')
- try_exten = ext_s;
- else if (tmp_exten[0] == 'i')
- try_exten = ext_i;
- else
- try_exten = ext_original;
- } else
- try_exten = ext_original;
- do {
- if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL))
- break;
- switch (try_exten) {
- case ext_original:
- tmp_exten[0] = 's';
- tmp_exten[1] = '\0';
- try_exten = ext_s;
- break;
- case ext_s:
- tmp_exten[0] = 'i';
- try_exten = ext_i;
- break;
- case ext_i:
- try_exten = ext_notexists;
- break;
- default:
- break;
- }
- } while (try_exten != ext_notexists);
-
- /* Drop the call if we don't have <exten>, s and i extensions */
- if (try_exten == ext_notexists) {
- ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context);
- ast_mutex_unlock(&pvt->lock);
- h323_clear_call(token, AST_CAUSE_UNALLOCATED);
- return 0;
- } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) {
- if (h323debug)
- ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context);
- ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten));
- }
-
- /* allocate a channel and tell asterisk about it */
- c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token);
-
- /* And release when done */
- ast_mutex_unlock(&pvt->lock);
- if (!c) {
- ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
- return 0;
- }
- return 1;
-}
-
-/**
- * Call-back function to establish an outgoing H.323 call
- *
- * Returns 1 on success
- */
-static int setup_outgoing_call(call_details_t *cd)
-{
- /* Use argument here or free it immediately */
- cleanup_call_details(cd);
-
- return 1;
-}
-
-/**
- * Call-back function to signal asterisk that the channel is ringing
- * Returns nothing
- */
-static void chan_ringing(unsigned call_reference, const char *token)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Ringing on %s\n", token);
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Something is wrong: ringing\n");
- return;
- }
- if (!pvt->owner) {
- ast_mutex_unlock(&pvt->lock);
- ast_log(LOG_ERROR, "Channel has no owner\n");
- return;
- }
- update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING);
- ast_mutex_unlock(&pvt->lock);
- return;
-}
-
-/**
- * Call-back function to cleanup communication
- * Returns nothing,
- */
-static void cleanup_connection(unsigned call_reference, const char *call_token)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token);
-
- while (1) {
- pvt = find_call_locked(call_reference, call_token);
- if (!pvt) {
- if (h323debug)
- ast_log(LOG_DEBUG, "No connection for %s\n", call_token);
- return;
- }
- if (!pvt->owner || !ast_channel_trylock(pvt->owner))
- break;
-#if 1
-#ifdef DEBUG_THREADS
- ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s, locked at %ld/%d by %s (%s:%d)\n", call_token, pvt->owner->lock.thread[0], pvt->owner->lock.reentrancy, pvt->owner->lock.func[0], pvt->owner->lock.file[0], pvt->owner->lock.lineno[0]);
-#else
- ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
-#endif
-#endif
- ast_mutex_unlock(&pvt->lock);
- usleep(1);
- }
- if (pvt->rtp) {
- /* Immediately stop RTP */
- ast_rtp_destroy(pvt->rtp);
- pvt->rtp = NULL;
- }
- /* Free dsp used for in-band DTMF detection */
- if (pvt->vad) {
- ast_dsp_free(pvt->vad);
- pvt->vad = NULL;
- }
- cleanup_call_details(&pvt->cd);
- pvt->alreadygone = 1;
- /* Send hangup */
- if (pvt->owner) {
- pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_queue_hangup(pvt->owner);
- ast_channel_unlock(pvt->owner);
- }
- ast_mutex_unlock(&pvt->lock);
- if (h323debug)
- ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token);
- return;
-}
-
-static void hangup_connection(unsigned int call_reference, const char *token, int cause)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug) {
- ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause);
- }
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- if (h323debug) {
- ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token);
- }
- return;
- }
- if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
- pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- pvt->owner->hangupcause = pvt->hangupcause = cause;
- ast_queue_hangup(pvt->owner);
- ast_channel_unlock(pvt->owner);
- }
- else {
- pvt->needhangup = 1;
- pvt->hangupcause = cause;
- if (h323debug)
- ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token);
- }
- ast_mutex_unlock(&pvt->lock);
-}
-
-static void set_dtmf_payload(unsigned call_reference, const char *token, int payload)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token);
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- return;
- }
- if (pvt->rtp) {
- ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0);
- }
- pvt->dtmf_pt = payload;
- ast_mutex_unlock(&pvt->lock);
- if (h323debug)
- ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload);
-}
-
-static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)
-{
- struct oh323_pvt *pvt;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Got remote capabilities from connection %s\n", token);
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt)
- return;
- pvt->peercapability = capabilities;
- pvt->jointcapability = pvt->options.capability & capabilities;
- if (prefs) {
- memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs));
- if (h323debug) {
- int i;
- for (i = 0; i < 32; ++i) {
- if (!prefs->order[i])
- break;
- ast_log(LOG_DEBUG, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]);
- }
- }
- if (pvt->rtp)
- ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);
- }
- ast_mutex_unlock(&pvt->lock);
-}
-
-static void set_local_capabilities(unsigned call_reference, const char *token)
-{
- struct oh323_pvt *pvt;
- int capability, dtmfmode, pref_codec;
- struct ast_codec_pref prefs;
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token);
-
- pvt = find_call_locked(call_reference, token);
- if (!pvt)
- return;
- capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability;
- dtmfmode = pvt->options.dtmfmode;
- prefs = pvt->options.prefs;
- pref_codec = pvt->pref_codec;
- ast_mutex_unlock(&pvt->lock);
- h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
-
- if (h323debug)
- ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
-}
-
-static void *do_monitor(void *data)
-{
- int res;
- int reloading;
- struct oh323_pvt *oh323 = NULL;
-
- for(;;) {
- /* Check for a reload request */
- ast_mutex_lock(&h323_reload_lock);
- reloading = h323_reloading;
- h323_reloading = 0;
- ast_mutex_unlock(&h323_reload_lock);
- if (reloading) {
- if (option_verbose > 0) {
- ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n");
- }
- h323_do_reload();
- }
- /* Check for interfaces needing to be killed */
- if (!ast_mutex_trylock(&iflock)) {
-#if 1
- do {
- for (oh323 = iflist; oh323; oh323 = oh323->next) {
- if (!ast_mutex_trylock(&oh323->lock)) {
- if (oh323->needdestroy) {
- __oh323_destroy(oh323);
- break;
- }
- ast_mutex_unlock(&oh323->lock);
- }
- }
- } while (/*oh323*/ 0);
-#else
-restartsearch:
- oh323 = iflist;
- while(oh323) {
- if (!ast_mutex_trylock(&oh323->lock)) {
- if (oh323->needdestroy) {
- __oh323_destroy(oh323);
- goto restartsearch;
- }
- ast_mutex_unlock(&oh323->lock);
- oh323 = oh323->next;
- }
- }
-#endif
- ast_mutex_unlock(&iflock);
- } else
- oh323 = (struct oh323_pvt *)1; /* Force fast loop */
- pthread_testcancel();
- /* Wait for sched or io */
- res = ast_sched_wait(sched);
- if ((res < 0) || (res > 1000)) {
- res = 1000;
- }
- /* Do not wait if some channel(s) is destroyed, probably, more available too */
- if (oh323)
- res = 1;
- res = ast_io_wait(io, res);
- pthread_testcancel();
- ast_mutex_lock(&monlock);
- if (res >= 0) {
- ast_sched_runq(sched);
- }
- ast_mutex_unlock(&monlock);
- }
- /* Never reached */
- return NULL;
-}
-
-static int restart_monitor(void)
-{
- pthread_attr_t attr;
- /* If we're supposed to be stopped -- stay stopped */
- if (ast_mutex_lock(&monlock)) {
- ast_log(LOG_WARNING, "Unable to lock monitor\n");
- return -1;
- }
- if (monitor_thread == AST_PTHREADT_STOP) {
- ast_mutex_unlock(&monlock);
- return 0;
- }
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
- /* Wake up the thread */
- pthread_kill(monitor_thread, SIGURG);
- } else {
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
- monitor_thread = AST_PTHREADT_NULL;
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- pthread_attr_destroy(&attr);
- return -1;
- }
- pthread_attr_destroy(&attr);
- }
- ast_mutex_unlock(&monlock);
- return 0;
-}
-
-static int h323_do_trace(int fd, int argc, char *argv[])
-{
- if (argc != 4) {
- return RESULT_SHOWUSAGE;
- }
- h323_debug(1, atoi(argv[3]));
- ast_cli(fd, "H.323 trace set to level %s\n", argv[2]);
- return RESULT_SUCCESS;
-}
-
-static int h323_no_trace(int fd, int argc, char *argv[])
-{
- if (argc < 3 || argc > 4) {
- return RESULT_SHOWUSAGE;
- }
- h323_debug(0,0);
- ast_cli(fd, "H.323 trace disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int h323_do_debug(int fd, int argc, char *argv[])
-{
- if (argc < 2 || argc > 3) {
- return RESULT_SHOWUSAGE;
- }
- h323debug = 1;
- ast_cli(fd, "H.323 debug enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int h323_no_debug(int fd, int argc, char *argv[])
-{
- if (argc < 3 || argc > 4) {
- return RESULT_SHOWUSAGE;
- }
- h323debug = 0;
- ast_cli(fd, "H.323 debug disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int h323_gk_cycle(int fd, int argc, char *argv[])
-{
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- h323_gk_urq();
-
- /* Possibly register with a GK */
- if (!gatekeeper_disable) {
- if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
- ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
- }
- }
- return RESULT_SUCCESS;
-}
-
-static int h323_ep_hangup(int fd, int argc, char *argv[])
-{
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- if (h323_soft_hangup(argv[2])) {
- ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]);
- } else {
- ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]);
- }
- return RESULT_SUCCESS;
-}
-
-static int h323_tokens_show(int fd, int argc, char *argv[])
-{
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- h323_show_tokens();
- return RESULT_SUCCESS;
-}
-
-static char trace_usage[] =
-"Usage: h.323 trace <level num>\n"
-" Enables H.323 stack tracing for debugging purposes\n";
-
-static char no_trace_usage[] =
-"Usage: h.323 trace off\n"
-" Disables H.323 stack tracing for debugging purposes\n";
-
-static char debug_usage[] =
-"Usage: h.323 debug\n"
-" Enables H.323 debug output\n";
-
-static char no_debug_usage[] =
-"Usage: h.323 debug off\n"
-" Disables H.323 debug output\n";
-
-static char show_cycle_usage[] =
-"Usage: h.323 gk cycle\n"
-" Manually re-register with the Gatekeper (Currently Disabled)\n";
-
-static char show_hangup_usage[] =
-"Usage: h.323 hangup <token>\n"
-" Manually try to hang up call identified by <token>\n";
-
-static char show_tokens_usage[] =
-"Usage: h.323 show tokens\n"
-" Print out all active call tokens\n";
-
-static char h323_reload_usage[] =
-"Usage: h323 reload\n"
-" Reloads H.323 configuration from h323.conf\n";
-
-static struct ast_cli_entry cli_h323_no_trace_deprecated = {
- { "h.323", "no", "trace", NULL },
- h323_no_trace, "Disable H.323 Stack Tracing",
- no_trace_usage };
-
-static struct ast_cli_entry cli_h323_no_debug_deprecated = {
- { "h.323", "no", "debug", NULL },
- h323_no_debug, "Disable H.323 debug",
- no_debug_usage };
-
-static struct ast_cli_entry cli_h323_debug_deprecated = {
- { "h.323", "debug", NULL },
- h323_do_debug, "Enable H.323 debug",
- debug_usage };
-
-static struct ast_cli_entry cli_h323_trace_deprecated = {
- { "h.323", "trace", NULL },
- h323_do_trace, "Enable H.323 Stack Tracing",
- trace_usage };
-
-static struct ast_cli_entry cli_h323_gk_cycle_deprecated = {
- { "h.323", "gk", "cycle", NULL },
- h323_gk_cycle, "Manually re-register with the Gatekeper",
- show_cycle_usage };
-
-static struct ast_cli_entry cli_h323[] = {
- { { "h323", "set", "trace", NULL },
- h323_do_trace, "Enable H.323 Stack Tracing",
- trace_usage, NULL, &cli_h323_trace_deprecated },
-
- { { "h323", "set", "trace", "off", NULL },
- h323_no_trace, "Disable H.323 Stack Tracing",
- no_trace_usage, NULL, &cli_h323_no_trace_deprecated },
-
- { { "h323", "set", "debug", NULL },
- h323_do_debug, "Enable H.323 debug",
- debug_usage, NULL, &cli_h323_debug_deprecated },
-
- { { "h323", "set", "debug", "off", NULL },
- h323_no_debug, "Disable H.323 debug",
- no_debug_usage, NULL, &cli_h323_no_debug_deprecated },
-
- { { "h323", "cycle", "gk", NULL },
- h323_gk_cycle, "Manually re-register with the Gatekeper",
- show_cycle_usage, NULL, &cli_h323_gk_cycle_deprecated },
-
- { { "h323", "hangup", NULL },
- h323_ep_hangup, "Manually try to hang up a call",
- show_hangup_usage },
-
- { { "h323", "show", "tokens", NULL },
- h323_tokens_show, "Show all active call tokens",
- show_tokens_usage },
-};
-
-static void delete_users(void)
-{
- int pruned = 0;
-
- /* Delete all users */
- ASTOBJ_CONTAINER_WRLOCK(&userl);
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- ASTOBJ_MARK(iterator);
- ++pruned;
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user);
- }
- ASTOBJ_CONTAINER_UNLOCK(&userl);
-
- ASTOBJ_CONTAINER_WRLOCK(&peerl);
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- ASTOBJ_MARK(iterator);
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- ASTOBJ_CONTAINER_UNLOCK(&peerl);
-}
-
-static void delete_aliases(void)
-{
- int pruned = 0;
-
- /* Delete all aliases */
- ASTOBJ_CONTAINER_WRLOCK(&aliasl);
- ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- ASTOBJ_MARK(iterator);
- ++pruned;
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias);
- }
- ASTOBJ_CONTAINER_UNLOCK(&aliasl);
-}
-
-static void prune_peers(void)
-{
- /* Prune peers who still are supposed to be deleted */
- ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer);
-}
-
-static int reload_config(int is_reload)
-{
- int format;
- struct ast_config *cfg, *ucfg;
- struct ast_variable *v;
- struct oh323_peer *peer = NULL;
- struct oh323_user *user = NULL;
- struct oh323_alias *alias = NULL;
- struct ast_hostent ahp; struct hostent *hp;
- char *cat;
- const char *utype;
- int is_user, is_peer, is_alias;
- char _gatekeeper[100];
- int gk_discover, gk_disable, gk_changed;
-
- cfg = ast_config_load(config);
-
- /* We *must* have a config file otherwise stop immediately */
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
- return 1;
- }
-
- if (is_reload) {
- delete_users();
- delete_aliases();
- prune_peers();
- }
-
- /* fire up the H.323 Endpoint */
- if (!h323_end_point_exist()) {
- h323_end_point_create();
- }
- ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper));
- gk_discover = gatekeeper_discover;
- gk_disable = gatekeeper_disable;
- memset(&bindaddr, 0, sizeof(bindaddr));
- memset(&global_options, 0, sizeof(global_options));
- global_options.fastStart = 1;
- global_options.h245Tunneling = 1;
- global_options.dtmfcodec = 101;
- global_options.dtmfmode = H323_DTMF_RFC2833;
- global_options.capability = GLOBAL_CAPABILITY;
- global_options.bridge = 1; /* Do native bridging by default */
- strcpy(default_context, "default");
- h323_signalling_port = 1720;
- gatekeeper_disable = 1;
- gatekeeper_discover = 0;
- gkroute = 0;
- userbyalias = 1;
- acceptAnonymous = 1;
- tos = 0;
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- /* Load configuration from users.conf */
- ucfg = ast_config_load("users.conf");
- if (ucfg) {
- struct ast_variable *gen;
- int genhas_h323;
- const char *has_h323;
-
- genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323"));
- gen = ast_variable_browse(ucfg, "general");
- for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) {
- if (strcasecmp(cat, "general")) {
- has_h323 = ast_variable_retrieve(ucfg, cat, "hash323");
- if (ast_true(has_h323) || (!has_h323 && genhas_h323)) {
- user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
- if (user) {
- ASTOBJ_CONTAINER_LINK(&userl, user);
- ASTOBJ_UNREF(user, oh323_destroy_user);
- }
- peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
- if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
- ASTOBJ_UNREF(peer, oh323_destroy_peer);
- }
- }
- }
- }
- ast_config_destroy(ucfg);
- }
-
- for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
- continue;
- /* Create the interface list */
- if (!strcasecmp(v->name, "port")) {
- h323_signalling_port = (int)strtol(v->value, NULL, 10);
- } else if (!strcasecmp(v->name, "bindaddr")) {
- if (!(hp = ast_gethostbyname(v->value, &ahp))) {
- ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
- } else {
- memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
- }
- } else if (!strcasecmp(v->name, "tos")) {
- if (sscanf(v->value, "%d", &format)) {
- tos = format & 0xff;
- } else if (!strcasecmp(v->value, "lowdelay")) {
- tos = IPTOS_LOWDELAY;
- } else if (!strcasecmp(v->value, "throughput")) {
- tos = IPTOS_THROUGHPUT;
- } else if (!strcasecmp(v->value, "reliability")) {
- tos = IPTOS_RELIABILITY;
- } else if (!strcasecmp(v->value, "mincost")) {
- tos = IPTOS_MINCOST;
- } else if (!strcasecmp(v->value, "none")) {
- tos = 0;
- } else {
- ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
- }
- } else if (!strcasecmp(v->name, "gatekeeper")) {
- if (!strcasecmp(v->value, "DISABLE")) {
- gatekeeper_disable = 1;
- } else if (!strcasecmp(v->value, "DISCOVER")) {
- gatekeeper_disable = 0;
- gatekeeper_discover = 1;
- } else {
- gatekeeper_disable = 0;
- ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper));
- }
- } else if (!strcasecmp(v->name, "secret")) {
- ast_copy_string(secret, v->value, sizeof(secret));
- } else if (!strcasecmp(v->name, "AllowGKRouted")) {
- gkroute = ast_true(v->value);
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(default_context, v->value, sizeof(default_context));
- ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context);
- } else if (!strcasecmp(v->name, "UserByAlias")) {
- userbyalias = ast_true(v->value);
- } else if (!strcasecmp(v->name, "AcceptAnonymous")) {
- acceptAnonymous = ast_true(v->value);
- } else if (!update_common_options(v, &global_options)) {
- /* dummy */
- }
- }
-
- for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
- if (strcasecmp(cat, "general")) {
- utype = ast_variable_retrieve(cfg, cat, "type");
- if (utype) {
- is_user = is_peer = is_alias = 0;
- if (!strcasecmp(utype, "user"))
- is_user = 1;
- else if (!strcasecmp(utype, "peer"))
- is_peer = 1;
- else if (!strcasecmp(utype, "friend"))
- is_user = is_peer = 1;
- else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias"))
- is_alias = 1;
- else {
- ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
- continue;
- }
- if (is_user) {
- user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (user) {
- ASTOBJ_CONTAINER_LINK(&userl, user);
- ASTOBJ_UNREF(user, oh323_destroy_user);
- }
- }
- if (is_peer) {
- peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
- ASTOBJ_UNREF(peer, oh323_destroy_peer);
- }
- }
- if (is_alias) {
- alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (alias) {
- ASTOBJ_CONTAINER_LINK(&aliasl, alias);
- ASTOBJ_UNREF(alias, oh323_destroy_alias);
- }
- }
- } else {
- ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
- }
- }
- }
- ast_config_destroy(cfg);
-
- /* Register our H.323 aliases if any*/
- ASTOBJ_CONTAINER_WRLOCK(&aliasl);
- ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (h323_set_alias(iterator)) {
- ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
- ASTOBJ_UNLOCK(iterator);
- continue;
- }
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- ASTOBJ_CONTAINER_UNLOCK(&aliasl);
-
- /* Don't touch GK if nothing changed because URQ will drop all existing calls */
- gk_changed = 0;
- if (gatekeeper_disable != gk_disable)
- gk_changed = is_reload;
- else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover))
- gk_changed = is_reload;
- else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0))
- gk_changed = is_reload;
- if (gk_changed) {
- if(!gk_disable)
- h323_gk_urq();
- if (!gatekeeper_disable) {
- if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
- ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
- gatekeeper_disable = 1;
- }
- }
- }
- return 0;
-}
-
-static int h323_reload(int fd, int argc, char *argv[])
-{
- ast_mutex_lock(&h323_reload_lock);
- if (h323_reloading) {
- ast_verbose("Previous H.323 reload not yet done\n");
- } else {
- h323_reloading = 1;
- }
- ast_mutex_unlock(&h323_reload_lock);
- restart_monitor();
- return 0;
-}
-
-static int h323_do_reload(void)
-{
- reload_config(1);
- return 0;
-}
-
-static int reload(void)
-{
- if (!sched || !io) {
- ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
- return 0;
- }
- return h323_reload(0, 0, NULL);
-}
-
-static struct ast_cli_entry cli_h323_reload =
- { { "h.323", "reload", NULL },
- h323_reload, "Reload H.323 configuration",
- h323_reload_usage
-};
-
-static enum ast_rtp_get_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
-{
- struct oh323_pvt *pvt;
- enum ast_rtp_get_result res = AST_RTP_GET_FAILED;
-
- if (!(pvt = (struct oh323_pvt *)chan->tech_pvt))
- return res;
-
- ast_mutex_lock(&pvt->lock);
- if (pvt->rtp && pvt->options.bridge) {
- *rtp = pvt->rtp;
- res = AST_RTP_TRY_NATIVE;
- }
- ast_mutex_unlock(&pvt->lock);
-
- return res;
-}
-
-static enum ast_rtp_get_result oh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
-{
- return AST_RTP_GET_FAILED;
-}
-
-static char *convertcap(int cap)
-{
- switch (cap) {
- case AST_FORMAT_G723_1:
- return "G.723";
- case AST_FORMAT_GSM:
- return "GSM";
- case AST_FORMAT_ULAW:
- return "ULAW";
- case AST_FORMAT_ALAW:
- return "ALAW";
- case AST_FORMAT_G722:
- return "G.722";
- case AST_FORMAT_ADPCM:
- return "G.728";
- case AST_FORMAT_G729A:
- return "G.729";
- case AST_FORMAT_SPEEX:
- return "SPEEX";
- case AST_FORMAT_ILBC:
- return "ILBC";
- default:
- ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap);
- return NULL;
- }
-}
-
-static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
-{
- /* XXX Deal with Video */
- struct oh323_pvt *pvt;
- struct sockaddr_in them;
- struct sockaddr_in us;
- char *mode;
-
- if (!rtp) {
- return 0;
- }
-
- mode = convertcap(chan->writeformat);
- pvt = (struct oh323_pvt *) chan->tech_pvt;
- if (!pvt) {
- ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
- return -1;
- }
- ast_rtp_get_peer(rtp, &them);
- ast_rtp_get_us(rtp, &us);
-#if 0 /* Native bridge still isn't ready */
- h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode);
-#endif
- return 0;
-}
-
-static struct ast_rtp_protocol oh323_rtp = {
- .type = "H323",
- .get_rtp_info = oh323_get_rtp_peer,
- .get_vrtp_info = oh323_get_vrtp_peer,
- .set_rtp_peer = oh323_set_rtp_peer,
-};
-
-static enum ast_module_load_result load_module(void)
-{
- int res;
-
- h323debug = 0;
- sched = sched_context_create();
- if (!sched) {
- ast_log(LOG_WARNING, "Unable to create schedule context\n");
- return AST_MODULE_LOAD_FAILURE;
- }
- io = io_context_create();
- if (!io) {
- ast_log(LOG_WARNING, "Unable to create I/O context\n");
- return AST_MODULE_LOAD_FAILURE;
- }
- ast_cli_register(&cli_h323_reload);
- ASTOBJ_CONTAINER_INIT(&userl);
- ASTOBJ_CONTAINER_INIT(&peerl);
- ASTOBJ_CONTAINER_INIT(&aliasl);
- res = reload_config(0);
- if (res) {
- /* No config entry */
- ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
- ast_cli_unregister(&cli_h323_reload);
- io_context_destroy(io);
- io = NULL;
- sched_context_destroy(sched);
- sched = NULL;
- ASTOBJ_CONTAINER_DESTROY(&userl);
- ASTOBJ_CONTAINER_DESTROY(&peerl);
- ASTOBJ_CONTAINER_DESTROY(&aliasl);
- return AST_MODULE_LOAD_DECLINE;
- } else {
- /* Make sure we can register our channel type */
- if (ast_channel_register(&oh323_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n");
- ast_cli_unregister(&cli_h323_reload);
- h323_end_process();
- io_context_destroy(io);
- sched_context_destroy(sched);
-
- ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
- ASTOBJ_CONTAINER_DESTROY(&userl);
- ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
- ASTOBJ_CONTAINER_DESTROY(&peerl);
- ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
- ASTOBJ_CONTAINER_DESTROY(&aliasl);
-
- return AST_MODULE_LOAD_FAILURE;
- }
- ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
-
- ast_rtp_proto_register(&oh323_rtp);
-
- /* Register our callback functions */
- h323_callback_register(setup_incoming_call,
- setup_outgoing_call,
- external_rtp_create,
- setup_rtp_connection,
- cleanup_connection,
- chan_ringing,
- connection_made,
- receive_digit,
- answer_call,
- progress,
- set_dtmf_payload,
- hangup_connection,
- set_local_capabilities,
- set_peer_capabilities);
- /* start the h.323 listener */
- if (h323_start_listener(h323_signalling_port, bindaddr)) {
- ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
- ast_rtp_proto_unregister(&oh323_rtp);
- ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
- ast_cli_unregister(&cli_h323_reload);
- h323_end_process();
- io_context_destroy(io);
- sched_context_destroy(sched);
-
- ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
- ASTOBJ_CONTAINER_DESTROY(&userl);
- ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
- ASTOBJ_CONTAINER_DESTROY(&peerl);
- ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
- ASTOBJ_CONTAINER_DESTROY(&aliasl);
-
- return AST_MODULE_LOAD_FAILURE;
- }
- /* Possibly register with a GK */
- if (!gatekeeper_disable) {
- if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
- ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
- gatekeeper_disable = 1;
- res = AST_MODULE_LOAD_SUCCESS;
- }
- }
- /* And start the monitor for the first time */
- restart_monitor();
- }
- return res;
-}
-
-static int unload_module(void)
-{
- struct oh323_pvt *p, *pl;
-
- /* unregister commands */
- ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
- ast_cli_unregister(&cli_h323_reload);
-
- ast_channel_unregister(&oh323_tech);
- ast_rtp_proto_unregister(&oh323_rtp);
-
- if (!ast_mutex_lock(&iflock)) {
- /* hangup all interfaces if they have an owner */
- p = iflist;
- while(p) {
- if (p->owner) {
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- }
- p = p->next;
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the interface list\n");
- return -1;
- }
- if (!ast_mutex_lock(&monlock)) {
- if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
- /* this causes a seg, anyone know why? */
- if (monitor_thread != pthread_self())
- pthread_cancel(monitor_thread);
- pthread_kill(monitor_thread, SIGURG);
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- return -1;
- }
- if (!ast_mutex_lock(&iflock)) {
- /* destroy all the interfaces and free their memory */
- p = iflist;
- while(p) {
- pl = p;
- p = p->next;
- /* free associated memory */
- ast_mutex_destroy(&pl->lock);
- free(pl);
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the interface list\n");
- return -1;
- }
- if (!gatekeeper_disable)
- h323_gk_urq();
- h323_end_process();
- if (io)
- io_context_destroy(io);
- if (sched)
- sched_context_destroy(sched);
-
- ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
- ASTOBJ_CONTAINER_DESTROY(&userl);
- ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
- ASTOBJ_CONTAINER_DESTROY(&peerl);
- ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
- ASTOBJ_CONTAINER_DESTROY(&aliasl);
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "The NuFone Network's OpenH323 Channel Driver",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
-);
diff --git a/1.4/channels/chan_iax2.c b/1.4/channels/chan_iax2.c
deleted file mode 100644
index 8c81ca73d..000000000
--- a/1.4/channels/chan_iax2.c
+++ /dev/null
@@ -1,11131 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Implementation of Inter-Asterisk eXchange Version 2
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \par See also
- * \arg \ref Config_iax
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <use>zaptel</use>
- <depend>res_features</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <dirent.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <signal.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <regex.h>
-
-#ifdef HAVE_ZAPTEL
-#include <sys/ioctl.h>
-#include <zaptel/zaptel.h>
-#endif
-
-#include "asterisk/lock.h"
-#include "asterisk/frame.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-#include "asterisk/pbx.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/translate.h"
-#include "asterisk/md5.h"
-#include "asterisk/cdr.h"
-#include "asterisk/crypto.h"
-#include "asterisk/acl.h"
-#include "asterisk/manager.h"
-#include "asterisk/callerid.h"
-#include "asterisk/app.h"
-#include "asterisk/astdb.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/features.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/localtime.h"
-#include "asterisk/aes.h"
-#include "asterisk/dnsmgr.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/netsock.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/astobj2.h"
-
-#include "iax2.h"
-#include "iax2-parser.h"
-#include "iax2-provision.h"
-#include "jitterbuf.h"
-
-/* Define SCHED_MULTITHREADED to run the scheduler in a special
- multithreaded mode. */
-#define SCHED_MULTITHREADED
-
-/* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
- thread is actually doing. */
-#define DEBUG_SCHED_MULTITHREAD
-
-#ifndef IPTOS_MINCOST
-#define IPTOS_MINCOST 0x02
-#endif
-
-#ifdef SO_NO_CHECK
-static int nochecksums = 0;
-#endif
-
-
-#define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
-#define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
-
-#define DEFAULT_THREAD_COUNT 10
-#define DEFAULT_MAX_THREAD_COUNT 100
-#define DEFAULT_RETRY_TIME 1000
-#define MEMORY_SIZE 100
-#define DEFAULT_DROP 3
-
-#define DEBUG_SUPPORT
-
-#define MIN_REUSE_TIME 60 /* Don't reuse a call number within 60 seconds */
-
-/* Sample over last 100 units to determine historic jitter */
-#define GAMMA (0.01)
-
-static struct ast_codec_pref prefs;
-
-static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
-
-static char context[80] = "default";
-
-static char language[MAX_LANGUAGE] = "";
-static char regcontext[AST_MAX_CONTEXT] = "";
-
-static int maxauthreq = 3;
-static int max_retries = 4;
-static int ping_time = 21;
-static int lagrq_time = 10;
-static int maxjitterbuffer=1000;
-static int resyncthreshold=1000;
-static int maxjitterinterps=10;
-static int trunkfreq = 20;
-static int authdebug = 1;
-static int autokill = 0;
-static int iaxcompat = 0;
-
-static int iaxdefaultdpcache=10 * 60; /* Cache dialplan entries for 10 minutes by default */
-
-static int iaxdefaulttimeout = 5; /* Default to wait no more than 5 seconds for a reply to come back */
-
-static unsigned int tos = 0;
-
-static int min_reg_expire;
-static int max_reg_expire;
-
-static int timingfd = -1; /* Timing file descriptor */
-
-static struct ast_netsock_list *netsock;
-static struct ast_netsock_list *outsock; /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
-static int defaultsockfd = -1;
-
-int (*iax2_regfunk)(const char *username, int onoff) = NULL;
-
-/* Ethernet, etc */
-#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
-/* T1, maybe ISDN */
-#define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
- ~AST_FORMAT_SLINEAR & \
- ~AST_FORMAT_ULAW & \
- ~AST_FORMAT_ALAW & \
- ~AST_FORMAT_G722)
-/* A modem */
-#define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
- ~AST_FORMAT_G726 & \
- ~AST_FORMAT_G726_AAL2 & \
- ~AST_FORMAT_ADPCM)
-
-#define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
- ~AST_FORMAT_G723_1)
-
-
-#define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
-#define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */
-#define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */
-
-static struct io_context *io;
-static struct sched_context *sched;
-
-static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
-
-static int iaxdebug = 0;
-
-static int iaxtrunkdebug = 0;
-
-static int test_losspct = 0;
-#ifdef IAXTESTS
-static int test_late = 0;
-static int test_resync = 0;
-static int test_jit = 0;
-static int test_jitpct = 0;
-#endif /* IAXTESTS */
-
-static char accountcode[AST_MAX_ACCOUNT_CODE];
-static char mohinterpret[MAX_MUSICCLASS];
-static char mohsuggest[MAX_MUSICCLASS];
-static int amaflags = 0;
-static int adsi = 0;
-static int delayreject = 0;
-static int iax2_encryption = 0;
-
-static struct ast_flags globalflags = { 0 };
-
-static pthread_t netthreadid = AST_PTHREADT_NULL;
-static pthread_t schedthreadid = AST_PTHREADT_NULL;
-AST_MUTEX_DEFINE_STATIC(sched_lock);
-static ast_cond_t sched_cond;
-
-enum {
- IAX_STATE_STARTED = (1 << 0),
- IAX_STATE_AUTHENTICATED = (1 << 1),
- IAX_STATE_TBD = (1 << 2),
- IAX_STATE_UNCHANGED = (1 << 3),
-} iax2_state;
-
-struct iax2_context {
- char context[AST_MAX_CONTEXT];
- struct iax2_context *next;
-};
-
-enum {
- IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */
- IAX_DELME = (1 << 1), /*!< Needs to be deleted */
- IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */
- IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */
- IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */
- IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */
- IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */
- IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */
- /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
- IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */
- IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */
- IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */
- IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */
- IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */
- IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */
- IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */
- IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/
- IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */
- IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */
- IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */
- IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
- IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */
- IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */
- IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */
- IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */
- IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a
- response, so that we've achieved a three-way handshake with
- them before sending voice or anything else*/
-} iax2_flags;
-
-static int global_rtautoclear = 120;
-
-static int reload_config(void);
-static int iax2_reload(int fd, int argc, char *argv[]);
-
-
-struct iax2_user {
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(secret);
- AST_STRING_FIELD(dbsecret);
- AST_STRING_FIELD(accountcode);
- AST_STRING_FIELD(mohinterpret);
- AST_STRING_FIELD(mohsuggest);
- AST_STRING_FIELD(inkeys); /*!< Key(s) this user can use to authenticate to us */
- AST_STRING_FIELD(language);
- AST_STRING_FIELD(cid_num);
- AST_STRING_FIELD(cid_name);
- );
-
- int authmethods;
- int encmethods;
- int amaflags;
- int adsi;
- unsigned int flags;
- int capability;
- int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
- int curauthreq; /*!< Current number of outstanding AUTHREQs */
- struct ast_codec_pref prefs;
- struct ast_ha *ha;
- struct iax2_context *contexts;
- struct ast_variable *vars;
-};
-
-struct iax2_peer {
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(username);
- AST_STRING_FIELD(secret);
- AST_STRING_FIELD(dbsecret);
- AST_STRING_FIELD(outkey); /*!< What key we use to talk to this peer */
-
- AST_STRING_FIELD(regexten); /*!< Extension to register (if regcontext is used) */
- AST_STRING_FIELD(context); /*!< For transfers only */
- AST_STRING_FIELD(peercontext); /*!< Context to pass to peer */
- AST_STRING_FIELD(mailbox); /*!< Mailbox */
- AST_STRING_FIELD(mohinterpret);
- AST_STRING_FIELD(mohsuggest);
- AST_STRING_FIELD(inkeys); /*!< Key(s) this peer can use to authenticate to us */
- /* Suggested caller id if registering */
- AST_STRING_FIELD(cid_num); /*!< Default context (for transfer really) */
- AST_STRING_FIELD(cid_name); /*!< Default context (for transfer really) */
- AST_STRING_FIELD(zonetag); /*!< Time Zone */
- );
- struct ast_codec_pref prefs;
- struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
- struct sockaddr_in addr;
- int formats;
- int sockfd; /*!< Socket to use for transmission */
- struct in_addr mask;
- int adsi;
- unsigned int flags;
-
- /* Dynamic Registration fields */
- struct sockaddr_in defaddr; /*!< Default address if there is one */
- int authmethods; /*!< Authentication methods (IAX_AUTH_*) */
- int encmethods; /*!< Encryption methods (IAX_ENCRYPT_*) */
-
- int expire; /*!< Schedule entry for expiry */
- int expiry; /*!< How soon to expire */
- int capability; /*!< Capability */
-
- /* Qualification */
- int callno; /*!< Call number of POKE request */
- int pokeexpire; /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
- int lastms; /*!< How long last response took (in ms), or -1 for no response */
- int maxms; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
-
- int pokefreqok; /*!< How often to check if the host is up */
- int pokefreqnotok; /*!< How often to check when the host has been determined to be down */
- int historicms; /*!< How long recent average responses took */
- int smoothing; /*!< Sample over how many units to determine historic ms */
-
- struct ast_ha *ha;
-};
-
-#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
-
-static struct iax2_trunk_peer {
- ast_mutex_t lock;
- int sockfd;
- struct sockaddr_in addr;
- struct timeval txtrunktime; /*!< Transmit trunktime */
- struct timeval rxtrunktime; /*!< Receive trunktime */
- struct timeval lasttxtime; /*!< Last transmitted trunktime */
- struct timeval trunkact; /*!< Last trunk activity */
- unsigned int lastsent; /*!< Last sent time */
- /* Trunk data and length */
- unsigned char *trunkdata;
- unsigned int trunkdatalen;
- unsigned int trunkdataalloc;
- struct iax2_trunk_peer *next;
- int trunkerror;
- int calls;
-} *tpeers = NULL;
-
-AST_MUTEX_DEFINE_STATIC(tpeerlock);
-
-struct iax_firmware {
- struct iax_firmware *next;
- int fd;
- int mmaplen;
- int dead;
- struct ast_iax2_firmware_header *fwh;
- unsigned char *buf;
-};
-
-enum iax_reg_state {
- REG_STATE_UNREGISTERED = 0,
- REG_STATE_REGSENT,
- REG_STATE_AUTHSENT,
- REG_STATE_REGISTERED,
- REG_STATE_REJECTED,
- REG_STATE_TIMEOUT,
- REG_STATE_NOAUTH
-};
-
-enum iax_transfer_state {
- TRANSFER_NONE = 0,
- TRANSFER_BEGIN,
- TRANSFER_READY,
- TRANSFER_RELEASED,
- TRANSFER_PASSTHROUGH,
- TRANSFER_MBEGIN,
- TRANSFER_MREADY,
- TRANSFER_MRELEASED,
- TRANSFER_MPASSTHROUGH,
- TRANSFER_MEDIA,
- TRANSFER_MEDIAPASS
-};
-
-struct iax2_registry {
- struct sockaddr_in addr; /*!< Who we connect to for registration purposes */
- char username[80];
- char secret[80]; /*!< Password or key name in []'s */
- char random[80];
- int expire; /*!< Sched ID of expiration */
- int refresh; /*!< How often to refresh */
- enum iax_reg_state regstate;
- int messages; /*!< Message count, low 8 bits = new, high 8 bits = old */
- int callno; /*!< Associated call number if applicable */
- struct sockaddr_in us; /*!< Who the server thinks we are */
- struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
- AST_LIST_ENTRY(iax2_registry) entry;
-};
-
-static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
-
-/* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
-#define MIN_RETRY_TIME 100
-#define MAX_RETRY_TIME 10000
-
-#define MAX_JITTER_BUFFER 50
-#define MIN_JITTER_BUFFER 10
-
-#define DEFAULT_TRUNKDATA 640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
-#define MAX_TRUNKDATA 640 * 200 /*!< 40ms, uncompressed linear * 200 channels */
-
-#define MAX_TIMESTAMP_SKEW 160 /*!< maximum difference between actual and predicted ts for sending */
-
-/* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
-#define TS_GAP_FOR_JB_RESYNC 5000
-
-static int iaxthreadcount = DEFAULT_THREAD_COUNT;
-static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
-static int iaxdynamicthreadcount = 0;
-static int iaxactivethreadcount = 0;
-
-struct iax_rr {
- int jitter;
- int losspct;
- int losscnt;
- int packets;
- int delay;
- int dropped;
- int ooo;
-};
-
-struct chan_iax2_pvt {
- /*! Socket to send/receive on for this call */
- int sockfd;
- /*! Last received voice format */
- int voiceformat;
- /*! Last received video format */
- int videoformat;
- /*! Last sent voice format */
- int svoiceformat;
- /*! Last sent video format */
- int svideoformat;
- /*! What we are capable of sending */
- int capability;
- /*! Last received timestamp */
- unsigned int last;
- /*! Last sent timestamp - never send the same timestamp twice in a single call */
- unsigned int lastsent;
- /*! Timestamp of the last video frame sent */
- unsigned int lastvsent;
- /*! Next outgoing timestamp if everything is good */
- unsigned int nextpred;
- /*! True if the last voice we transmitted was not silence/CNG */
- int notsilenttx;
- /*! Ping time */
- unsigned int pingtime;
- /*! Max time for initial response */
- int maxtime;
- /*! Peer Address */
- struct sockaddr_in addr;
- /*! Actual used codec preferences */
- struct ast_codec_pref prefs;
- /*! Requested codec preferences */
- struct ast_codec_pref rprefs;
- /*! Our call number */
- unsigned short callno;
- /*! Peer callno */
- unsigned short peercallno;
- /*! Negotiated format, this is only used to remember what format was
- chosen for an unauthenticated call so that the channel can get
- created later using the right format */
- int chosenformat;
- /*! Peer selected format */
- int peerformat;
- /*! Peer capability */
- int peercapability;
- /*! timeval that we base our transmission on */
- struct timeval offset;
- /*! timeval that we base our delivery on */
- struct timeval rxcore;
- /*! The jitterbuffer */
- jitterbuf *jb;
- /*! active jb read scheduler id */
- int jbid;
- /*! LAG */
- int lag;
- /*! Error, as discovered by the manager */
- int error;
- /*! Owner if we have one */
- struct ast_channel *owner;
- /*! What's our state? */
- struct ast_flags state;
- /*! Expiry (optional) */
- int expiry;
- /*! Next outgoing sequence number */
- unsigned char oseqno;
- /*! Next sequence number they have not yet acknowledged */
- unsigned char rseqno;
- /*! Next incoming sequence number */
- unsigned char iseqno;
- /*! Last incoming sequence number we have acknowledged */
- unsigned char aseqno;
-
- AST_DECLARE_STRING_FIELDS(
- /*! Peer name */
- AST_STRING_FIELD(peer);
- /*! Default Context */
- AST_STRING_FIELD(context);
- /*! Caller ID if available */
- AST_STRING_FIELD(cid_num);
- AST_STRING_FIELD(cid_name);
- /*! Hidden Caller ID (i.e. ANI) if appropriate */
- AST_STRING_FIELD(ani);
- /*! DNID */
- AST_STRING_FIELD(dnid);
- /*! RDNIS */
- AST_STRING_FIELD(rdnis);
- /*! Requested Extension */
- AST_STRING_FIELD(exten);
- /*! Expected Username */
- AST_STRING_FIELD(username);
- /*! Expected Secret */
- AST_STRING_FIELD(secret);
- /*! MD5 challenge */
- AST_STRING_FIELD(challenge);
- /*! Public keys permitted keys for incoming authentication */
- AST_STRING_FIELD(inkeys);
- /*! Private key for outgoing authentication */
- AST_STRING_FIELD(outkey);
- /*! Preferred language */
- AST_STRING_FIELD(language);
- /*! Hostname/peername for naming purposes */
- AST_STRING_FIELD(host);
-
- AST_STRING_FIELD(dproot);
- AST_STRING_FIELD(accountcode);
- AST_STRING_FIELD(mohinterpret);
- AST_STRING_FIELD(mohsuggest);
- );
-
- /*! permitted authentication methods */
- int authmethods;
- /*! permitted encryption methods */
- int encmethods;
- /*! Encryption AES-128 Key */
- aes_encrypt_ctx ecx;
- /*! Decryption AES-128 Key */
- aes_decrypt_ctx dcx;
- /*! 32 bytes of semi-random data */
- unsigned char semirand[32];
- /*! Associated registry */
- struct iax2_registry *reg;
- /*! Associated peer for poking */
- struct iax2_peer *peerpoke;
- /*! IAX_ flags */
- unsigned int flags;
- int adsi;
-
- /*! Transferring status */
- enum iax_transfer_state transferring;
- /*! Transfer identifier */
- int transferid;
- /*! Who we are IAX transfering to */
- struct sockaddr_in transfer;
- /*! What's the new call number for the transfer */
- unsigned short transfercallno;
- /*! Transfer decrypt AES-128 Key */
- aes_encrypt_ctx tdcx;
-
- /*! Status of knowledge of peer ADSI capability */
- int peeradsicpe;
-
- /*! Who we are bridged to */
- unsigned short bridgecallno;
-
- int pingid; /*!< Transmit PING request */
- int lagid; /*!< Retransmit lag request */
- int autoid; /*!< Auto hangup for Dialplan requestor */
- int authid; /*!< Authentication rejection ID */
- int authfail; /*!< Reason to report failure */
- int initid; /*!< Initial peer auto-congest ID (based on qualified peers) */
- int calling_ton;
- int calling_tns;
- int calling_pres;
- int amaflags;
- struct iax2_dpcache *dpentries;
- struct ast_variable *vars;
- /*! last received remote rr */
- struct iax_rr remote_rr;
- /*! Current base time: (just for stats) */
- int min;
- /*! Dropped frame count: (just for stats) */
- int frames_dropped;
- /*! received frame count: (just for stats) */
- int frames_received;
-};
-
-static struct ast_iax2_queue {
- AST_LIST_HEAD(, iax_frame) queue;
- int count;
-} iaxq;
-
-/*!
- * This module will get much higher performance when doing a lot of
- * user and peer lookups if the number of buckets is increased from 1.
- * However, to maintain old behavior for Asterisk 1.4, these are set to
- * 1 by default. When using multiple buckets, search order through these
- * containers is considered random, so you will not be able to depend on
- * the order the entires are specified in iax.conf for matching order. */
-#ifdef LOW_MEMORY
-#define MAX_PEER_BUCKETS 1
-/* #define MAX_PEER_BUCKETS 17 */
-#else
-#define MAX_PEER_BUCKETS 1
-/* #define MAX_PEER_BUCKETS 563 */
-#endif
-static struct ao2_container *peers;
-
-#define MAX_USER_BUCKETS MAX_PEER_BUCKETS
-static struct ao2_container *users;
-
-static struct ast_firmware_list {
- struct iax_firmware *wares;
- ast_mutex_t lock;
-} waresl;
-
-/*! Extension exists */
-#define CACHE_FLAG_EXISTS (1 << 0)
-/*! Extension is nonexistent */
-#define CACHE_FLAG_NONEXISTENT (1 << 1)
-/*! Extension can exist */
-#define CACHE_FLAG_CANEXIST (1 << 2)
-/*! Waiting to hear back response */
-#define CACHE_FLAG_PENDING (1 << 3)
-/*! Timed out */
-#define CACHE_FLAG_TIMEOUT (1 << 4)
-/*! Request transmitted */
-#define CACHE_FLAG_TRANSMITTED (1 << 5)
-/*! Timeout */
-#define CACHE_FLAG_UNKNOWN (1 << 6)
-/*! Matchmore */
-#define CACHE_FLAG_MATCHMORE (1 << 7)
-
-static struct iax2_dpcache {
- char peercontext[AST_MAX_CONTEXT];
- char exten[AST_MAX_EXTENSION];
- struct timeval orig;
- struct timeval expiry;
- int flags;
- unsigned short callno;
- int waiters[256];
- struct iax2_dpcache *next;
- struct iax2_dpcache *peer; /*!< For linking in peers */
-} *dpcache;
-
-AST_MUTEX_DEFINE_STATIC(dpcache_lock);
-
-static void reg_source_db(struct iax2_peer *p);
-static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
-
-static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
-
-#define IAX_IOSTATE_IDLE 0
-#define IAX_IOSTATE_READY 1
-#define IAX_IOSTATE_PROCESSING 2
-#define IAX_IOSTATE_SCHEDREADY 3
-
-#define IAX_TYPE_POOL 1
-#define IAX_TYPE_DYNAMIC 2
-
-struct iax2_pkt_buf {
- AST_LIST_ENTRY(iax2_pkt_buf) entry;
- size_t len;
- unsigned char buf[1];
-};
-
-struct iax2_thread {
- AST_LIST_ENTRY(iax2_thread) list;
- int type;
- int iostate;
-#ifdef SCHED_MULTITHREADED
- void (*schedfunc)(const void *);
- const void *scheddata;
-#endif
-#ifdef DEBUG_SCHED_MULTITHREAD
- char curfunc[80];
-#endif
- int actions;
- pthread_t threadid;
- int threadnum;
- struct sockaddr_in iosin;
- unsigned char readbuf[4096];
- unsigned char *buf;
- ssize_t buf_len;
- size_t buf_size;
- int iofd;
- time_t checktime;
- ast_mutex_t lock;
- ast_cond_t cond;
- unsigned int ready_for_signal:1;
- /*! if this thread is processing a full frame,
- some information about that frame will be stored
- here, so we can avoid dispatching any more full
- frames for that callno to other threads */
- struct {
- unsigned short callno;
- struct sockaddr_in sin;
- unsigned char type;
- unsigned char csub;
- } ffinfo;
- /*! Queued up full frames for processing. If more full frames arrive for
- * a call which this thread is already processing a full frame for, they
- * are queued up here. */
- AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
-};
-
-/* Thread lists */
-static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
-static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
-static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
-
-static void *iax2_process_thread(void *data);
-
-static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
-{
- ast_mutex_lock(lock);
- ast_cond_signal(cond);
- ast_mutex_unlock(lock);
-}
-
-static void iax_debug_output(const char *data)
-{
- if (iaxdebug)
- ast_verbose("%s", data);
-}
-
-static void iax_error_output(const char *data)
-{
- ast_log(LOG_WARNING, "%s", data);
-}
-
-static void jb_error_output(const char *fmt, ...)
-{
- va_list args;
- char buf[1024];
-
- va_start(args, fmt);
- vsnprintf(buf, 1024, fmt, args);
- va_end(args);
-
- ast_log(LOG_ERROR, buf);
-}
-
-static void jb_warning_output(const char *fmt, ...)
-{
- va_list args;
- char buf[1024];
-
- va_start(args, fmt);
- vsnprintf(buf, 1024, fmt, args);
- va_end(args);
-
- ast_log(LOG_WARNING, buf);
-}
-
-static void jb_debug_output(const char *fmt, ...)
-{
- va_list args;
- char buf[1024];
-
- va_start(args, fmt);
- vsnprintf(buf, 1024, fmt, args);
- va_end(args);
-
- ast_verbose(buf);
-}
-
-/* XXX We probably should use a mutex when working with this XXX */
-static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
-static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
-static struct timeval lastused[ARRAY_LEN(iaxs)];
-
-/*!
- * \brief Another container of iax2_pvt structures
- *
- * Active IAX2 pvt structs are also stored in this container, if they are a part
- * of an active call where we know the remote side's call number. The reason
- * for this is that incoming media frames do not contain our call number. So,
- * instead of having to iterate the entire iaxs array, we use this container to
- * look up calls where the remote side is using a given call number.
- */
-static struct ao2_container *iax_peercallno_pvts;
-
-/* Flag to use with trunk calls, keeping these calls high up. It halves our effective use
- but keeps the division between trunked and non-trunked better. */
-#define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
-
-static int maxtrunkcall = TRUNK_CALL_START;
-static int maxnontrunkcall = 1;
-
-static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-static int expire_registry(const void *data);
-static int iax2_answer(struct ast_channel *c);
-static int iax2_call(struct ast_channel *c, char *dest, int timeout);
-static int iax2_devicestate(void *data);
-static int iax2_digit_begin(struct ast_channel *c, char digit);
-static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
-static int iax2_do_register(struct iax2_registry *reg);
-static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
-static int iax2_hangup(struct ast_channel *c);
-static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
-static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
-static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
-static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
-static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
-static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
-static int iax2_sendtext(struct ast_channel *c, const char *text);
-static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
-static int iax2_transfer(struct ast_channel *c, const char *dest);
-static int iax2_write(struct ast_channel *c, struct ast_frame *f);
-static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
-static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
-static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
-static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
-static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
-static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
-static struct ast_frame *iax2_read(struct ast_channel *c);
-static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
-static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
-static void prune_peers(void);
-
-static const struct ast_channel_tech iax2_tech = {
- .type = "IAX2",
- .description = tdesc,
- .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
- .properties = AST_CHAN_TP_WANTSJITTER,
- .requester = iax2_request,
- .devicestate = iax2_devicestate,
- .send_digit_begin = iax2_digit_begin,
- .send_digit_end = iax2_digit_end,
- .send_text = iax2_sendtext,
- .send_image = iax2_sendimage,
- .send_html = iax2_sendhtml,
- .call = iax2_call,
- .hangup = iax2_hangup,
- .answer = iax2_answer,
- .read = iax2_read,
- .write = iax2_write,
- .write_video = iax2_write,
- .indicate = iax2_indicate,
- .setoption = iax2_setoption,
- .bridge = iax2_bridge,
- .transfer = iax2_transfer,
- .fixup = iax2_fixup,
-};
-
-/* WARNING: insert_idle_thread should only ever be called within the
- * context of an iax2_process_thread() thread.
- */
-static void insert_idle_thread(struct iax2_thread *thread)
-{
- if (thread->type == IAX_TYPE_DYNAMIC) {
- AST_LIST_LOCK(&dynamic_list);
- AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
- AST_LIST_UNLOCK(&dynamic_list);
- } else {
- AST_LIST_LOCK(&idle_list);
- AST_LIST_INSERT_TAIL(&idle_list, thread, list);
- AST_LIST_UNLOCK(&idle_list);
- }
-
- return;
-}
-
-static struct iax2_thread *find_idle_thread(void)
-{
- pthread_attr_t attr;
- struct iax2_thread *thread = NULL;
-
- /* Pop the head of the list off */
- AST_LIST_LOCK(&idle_list);
- thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
- AST_LIST_UNLOCK(&idle_list);
-
- /* If no idle thread is available from the regular list, try dynamic */
- if (thread == NULL) {
- AST_LIST_LOCK(&dynamic_list);
- thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
- /* Make sure we absolutely have a thread... if not, try to make one if allowed */
- if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
- /* We need to MAKE a thread! */
- if ((thread = ast_calloc(1, sizeof(*thread)))) {
- thread->threadnum = iaxdynamicthreadcount;
- thread->type = IAX_TYPE_DYNAMIC;
- ast_mutex_init(&thread->lock);
- ast_cond_init(&thread->cond, NULL);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
- free(thread);
- thread = NULL;
- } else {
- /* All went well and the thread is up, so increment our count */
- iaxdynamicthreadcount++;
-
- /* Wait for the thread to be ready before returning it to the caller */
- while (!thread->ready_for_signal)
- usleep(1);
- }
- }
- }
- AST_LIST_UNLOCK(&dynamic_list);
- }
-
- /* this thread is not processing a full frame (since it is idle),
- so ensure that the field for the full frame call number is empty */
- if (thread)
- memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
-
- return thread;
-}
-
-#ifdef SCHED_MULTITHREADED
-static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
-{
- struct iax2_thread *thread = NULL;
- static time_t lasterror;
- static time_t t;
-
- thread = find_idle_thread();
-
- if (thread != NULL) {
- thread->schedfunc = func;
- thread->scheddata = data;
- thread->iostate = IAX_IOSTATE_SCHEDREADY;
-#ifdef DEBUG_SCHED_MULTITHREAD
- ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
-#endif
- signal_condition(&thread->lock, &thread->cond);
- return 0;
- }
- time(&t);
- if (t != lasterror && option_debug)
- ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
- lasterror = t;
-
- return -1;
-}
-#define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
-#endif
-
-static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
-{
- int res;
-
- res = ast_sched_add(con, when, callback, data);
- signal_condition(&sched_lock, &sched_cond);
-
- return res;
-}
-
-static int send_ping(const void *data);
-
-static void __send_ping(const void *data)
-{
- int callno = (long)data;
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno] && iaxs[callno]->pingid != -1) {
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
- iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
- }
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static int send_ping(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__send_ping, data))
-#endif
- __send_ping(data);
- return 0;
-}
-
-static int get_encrypt_methods(const char *s)
-{
- int e;
- if (!strcasecmp(s, "aes128"))
- e = IAX_ENCRYPT_AES128;
- else if (ast_true(s))
- e = IAX_ENCRYPT_AES128;
- else
- e = 0;
- return e;
-}
-
-static int send_lagrq(const void *data);
-
-static void __send_lagrq(const void *data)
-{
- int callno = (long)data;
- /* Ping only if it's real not if it's bridged */
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno] && iaxs[callno]->lagid > -1) {
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
- iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
- }
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static int send_lagrq(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__send_lagrq, data))
-#endif
- __send_lagrq(data);
- return 0;
-}
-
-static unsigned char compress_subclass(int subclass)
-{
- int x;
- int power=-1;
- /* If it's 128 or smaller, just return it */
- if (subclass < IAX_FLAG_SC_LOG)
- return subclass;
- /* Otherwise find its power */
- for (x = 0; x < IAX_MAX_SHIFT; x++) {
- if (subclass & (1 << x)) {
- if (power > -1) {
- ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
- return 0;
- } else
- power = x;
- }
- }
- return power | IAX_FLAG_SC_LOG;
-}
-
-static int uncompress_subclass(unsigned char csub)
-{
- /* If the SC_LOG flag is set, return 2^csub otherwise csub */
- if (csub & IAX_FLAG_SC_LOG) {
- /* special case for 'compressed' -1 */
- if (csub == 0xff)
- return -1;
- else
- return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
- }
- else
- return csub;
-}
-
-/*!
- * \note The only member of the peer passed here guaranteed to be set is the name field
- */
-static int peer_hash_cb(const void *obj, const int flags)
-{
- const struct iax2_peer *peer = obj;
-
- return ast_str_hash(peer->name);
-}
-
-/*!
- * \note The only member of the peer passed here guaranteed to be set is the name field
- */
-static int peer_cmp_cb(void *obj, void *arg, int flags)
-{
- struct iax2_peer *peer = obj, *peer2 = arg;
-
- return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
-}
-
-/*!
- * \note The only member of the user passed here guaranteed to be set is the name field
- */
-static int user_hash_cb(const void *obj, const int flags)
-{
- const struct iax2_user *user = obj;
-
- return ast_str_hash(user->name);
-}
-
-/*!
- * \note The only member of the user passed here guaranteed to be set is the name field
- */
-static int user_cmp_cb(void *obj, void *arg, int flags)
-{
- struct iax2_user *user = obj, *user2 = arg;
-
- return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
-}
-
-/*!
- * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
- * so do not call it with a pvt lock held.
- */
-static struct iax2_peer *find_peer(const char *name, int realtime)
-{
- struct iax2_peer *peer = NULL;
- struct iax2_peer tmp_peer = {
- .name = name,
- };
-
- peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
-
- /* Now go for realtime if applicable */
- if(!peer && realtime)
- peer = realtime_peer(name, NULL);
-
- return peer;
-}
-
-static struct iax2_peer *peer_ref(struct iax2_peer *peer)
-{
- ao2_ref(peer, +1);
- return peer;
-}
-
-static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
-{
- ao2_ref(peer, -1);
- return NULL;
-}
-
-static inline struct iax2_user *user_ref(struct iax2_user *user)
-{
- ao2_ref(user, +1);
- return user;
-}
-
-static inline struct iax2_user *user_unref(struct iax2_user *user)
-{
- ao2_ref(user, -1);
- return NULL;
-}
-
-static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
-{
- struct iax2_peer *peer = NULL;
- int res = 0;
- struct ao2_iterator i;
-
- i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
- if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
- (peer->addr.sin_port == sin.sin_port)) {
- ast_copy_string(host, peer->name, len);
- peer_unref(peer);
- res = 1;
- break;
- }
- peer_unref(peer);
- }
-
- if (!peer) {
- peer = realtime_peer(NULL, &sin);
- if (peer) {
- ast_copy_string(host, peer->name, len);
- peer_unref(peer);
- res = 1;
- }
- }
-
- return res;
-}
-
-static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
-{
- /* Decrement AUTHREQ count if needed */
- if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
- struct iax2_user *user;
- struct iax2_user tmp_user = {
- .name = pvt->username,
- };
-
- user = ao2_find(users, &tmp_user, OBJ_POINTER);
- if (user) {
- ast_atomic_fetchadd_int(&user->curauthreq, -1);
- user = user_unref(user);
- }
-
- ast_clear_flag(pvt, IAX_MAXAUTHREQ);
- }
-
- /* No more pings or lagrq's */
- AST_SCHED_DEL(sched, pvt->pingid);
- AST_SCHED_DEL(sched, pvt->lagid);
- AST_SCHED_DEL(sched, pvt->autoid);
- AST_SCHED_DEL(sched, pvt->authid);
- AST_SCHED_DEL(sched, pvt->initid);
- AST_SCHED_DEL(sched, pvt->jbid);
-}
-
-static void store_by_peercallno(struct chan_iax2_pvt *pvt)
-{
- if (!pvt->peercallno) {
- ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
- return;
- }
-
- ao2_link(iax_peercallno_pvts, pvt);
-}
-
-static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
-{
- if (!pvt->peercallno) {
- ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
- return;
- }
-
- ao2_unlink(iax_peercallno_pvts, pvt);
-}
-
-static void update_max_trunk(void)
-{
- int max = TRUNK_CALL_START;
- int x;
-
- /* XXX Prolly don't need locks here XXX */
- for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
- if (iaxs[x]) {
- max = x + 1;
- }
- }
-
- maxtrunkcall = max;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
-}
-
-static void iax2_frame_free(struct iax_frame *fr)
-{
- AST_SCHED_DEL(sched, fr->retrans);
- iax_frame_free(fr);
-}
-
-static void iax2_destroy(int callno)
-{
- struct chan_iax2_pvt *pvt;
- struct ast_channel *owner;
-
-retry:
- pvt = iaxs[callno];
- gettimeofday(&lastused[callno], NULL);
-
- owner = pvt ? pvt->owner : NULL;
-
- if (owner) {
- if (ast_mutex_trylock(&owner->lock)) {
- ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
- ast_mutex_unlock(&iaxsl[callno]);
- usleep(1);
- ast_mutex_lock(&iaxsl[callno]);
- goto retry;
- }
- }
- if (!owner) {
- iaxs[callno] = NULL;
- }
-
- if (pvt) {
- if (!owner) {
- pvt->owner = NULL;
- } else {
- /* If there's an owner, prod it to give up */
- /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
- * because we already hold the owner channel lock. */
- ast_queue_hangup(owner);
- }
-
- if (pvt->peercallno) {
- remove_by_peercallno(pvt);
- }
-
- if (!owner) {
- ao2_ref(pvt, -1);
- pvt = NULL;
- }
- }
-
- if (owner) {
- ast_mutex_unlock(&owner->lock);
- }
-
- if (callno & 0x4000) {
- update_max_trunk();
- }
-}
-
-static void pvt_destructor(void *obj)
-{
- struct chan_iax2_pvt *pvt = obj;
- struct iax_frame *cur = NULL;
-
- iax2_destroy_helper(pvt);
-
- /* Already gone */
- ast_set_flag(pvt, IAX_ALREADYGONE);
-
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
- /* Cancel any pending transmissions */
- if (cur->callno == pvt->callno) {
- cur->retries = -1;
- }
- }
- AST_LIST_UNLOCK(&iaxq.queue);
-
- if (pvt->reg) {
- pvt->reg->callno = 0;
- }
-
- if (!pvt->owner) {
- jb_frame frame;
- if (pvt->vars) {
- ast_variables_destroy(pvt->vars);
- pvt->vars = NULL;
- }
-
- while (jb_getall(pvt->jb, &frame) == JB_OK) {
- iax2_frame_free(frame.data);
- }
-
- jb_destroy(pvt->jb);
- ast_string_field_free_memory(pvt);
- }
-}
-
-static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
-{
- struct chan_iax2_pvt *tmp;
- jb_conf jbconf;
-
- if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
- return NULL;
- }
-
- if (ast_string_field_init(tmp, 32)) {
- ao2_ref(tmp, -1);
- tmp = NULL;
- return NULL;
- }
-
- tmp->prefs = prefs;
- tmp->callno = 0;
- tmp->peercallno = 0;
- tmp->transfercallno = 0;
- tmp->bridgecallno = 0;
- tmp->pingid = -1;
- tmp->lagid = -1;
- tmp->autoid = -1;
- tmp->authid = -1;
- tmp->initid = -1;
-
- ast_string_field_set(tmp,exten, "s");
- ast_string_field_set(tmp,host, host);
-
- tmp->jb = jb_new();
- tmp->jbid = -1;
- jbconf.max_jitterbuf = maxjitterbuffer;
- jbconf.resync_threshold = resyncthreshold;
- jbconf.max_contig_interp = maxjitterinterps;
- jb_setconf(tmp->jb,&jbconf);
-
- return tmp;
-}
-
-static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
-{
- struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
- if (new) {
- size_t afdatalen = new->afdatalen;
- memcpy(new, fr, sizeof(*new));
- iax_frame_wrap(new, &fr->af);
- new->afdatalen = afdatalen;
- new->data = NULL;
- new->datalen = 0;
- new->direction = DIRECTION_INGRESS;
- new->retrans = -1;
- }
- return new;
-}
-
-#define NEW_PREVENT 0
-#define NEW_ALLOW 1
-#define NEW_FORCE 2
-
-static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int full_frame)
-{
- if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
- (cur->addr.sin_port == sin->sin_port)) {
- /* This is the main host */
- if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
- (full_frame ? dcallno == cur->callno : 1) ) {
- /* That's us. Be sure we keep track of the peer call number */
- return 1;
- }
- }
- if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
- (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
- /* We're transferring */
- if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
- return 1;
- }
- return 0;
-}
-
-static void update_max_nontrunk(void)
-{
- int max = 1;
- int x;
- /* XXX Prolly don't need locks here XXX */
- for (x=1;x<TRUNK_CALL_START - 1; x++) {
- if (iaxs[x])
- max = x + 1;
- }
- maxnontrunkcall = max;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
-}
-
-static int make_trunk(unsigned short callno, int locked)
-{
- int x;
- int res= 0;
- struct timeval now;
- if (iaxs[callno]->oseqno) {
- ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
- return -1;
- }
- if (callno & TRUNK_CALL_START) {
- ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
- return -1;
- }
- gettimeofday(&now, NULL);
- for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
- ast_mutex_lock(&iaxsl[x]);
- if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
- iaxs[x] = iaxs[callno];
- iaxs[x]->callno = x;
- iaxs[callno] = NULL;
- /* Update the two timers that should have been started */
- AST_SCHED_DEL(sched, iaxs[x]->pingid);
- AST_SCHED_DEL(sched, iaxs[x]->lagid);
- iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
- iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
- if (locked)
- ast_mutex_unlock(&iaxsl[callno]);
- res = x;
- if (!locked)
- ast_mutex_unlock(&iaxsl[x]);
- break;
- }
- ast_mutex_unlock(&iaxsl[x]);
- }
- if (x >= ARRAY_LEN(iaxs) - 1) {
- ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
- /* We move this call from a non-trunked to a trunked call */
- update_max_trunk();
- update_max_nontrunk();
- return res;
-}
-
-/*!
- * \note Calling this function while holding another pvt lock can cause a deadlock.
- */
-static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int full_frame)
-{
- int res = 0;
- int x;
- struct timeval now;
- char host[80];
-
- if (new <= NEW_ALLOW) {
- if (callno) {
- struct chan_iax2_pvt *pvt;
- struct chan_iax2_pvt tmp_pvt = {
- .callno = dcallno,
- .peercallno = callno,
- /* hack!! */
- .frames_received = full_frame,
- };
-
- memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
-
- if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
- if (return_locked) {
- ast_mutex_lock(&iaxsl[pvt->callno]);
- }
- res = pvt->callno;
- ao2_ref(pvt, -1);
- pvt = NULL;
- return res;
- }
- }
-
- /* Look for an existing connection first */
- for (x = 1; !res && x < maxnontrunkcall; x++) {
- ast_mutex_lock(&iaxsl[x]);
- if (iaxs[x]) {
- /* Look for an exact match */
- if (match(sin, callno, dcallno, iaxs[x], full_frame)) {
- res = x;
- }
- }
- if (!res || !return_locked)
- ast_mutex_unlock(&iaxsl[x]);
- }
- for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
- ast_mutex_lock(&iaxsl[x]);
- if (iaxs[x]) {
- /* Look for an exact match */
- if (match(sin, callno, dcallno, iaxs[x], full_frame)) {
- res = x;
- }
- }
- if (!res || !return_locked)
- ast_mutex_unlock(&iaxsl[x]);
- }
- }
- if (!res && (new >= NEW_ALLOW)) {
- int start, found = 0;
-
- /* It may seem odd that we look through the peer list for a name for
- * this *incoming* call. Well, it is weird. However, users don't
- * have an IP address/port number that we can match against. So,
- * this is just checking for a peer that has that IP/port and
- * assuming that we have a user of the same name. This isn't always
- * correct, but it will be changed if needed after authentication. */
- if (!iax2_getpeername(*sin, host, sizeof(host)))
- snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
-
- now = ast_tvnow();
- start = 1 + (ast_random() % (TRUNK_CALL_START - 1));
- for (x = start; 1; x++) {
- if (x == TRUNK_CALL_START) {
- x = 0;
- continue;
- }
-
- /* Find first unused call number that hasn't been used in a while */
- ast_mutex_lock(&iaxsl[x]);
- if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
- found = 1;
- break;
- }
- ast_mutex_unlock(&iaxsl[x]);
-
- if (x == start - 1) {
- break;
- }
- }
- /* We've still got lock held if we found a spot */
- if (x == start - 1 && !found) {
- ast_log(LOG_WARNING, "No more space\n");
- return 0;
- }
- iaxs[x] = new_iax(sin, host);
- update_max_nontrunk();
- if (iaxs[x]) {
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
- iaxs[x]->sockfd = sockfd;
- iaxs[x]->addr.sin_port = sin->sin_port;
- iaxs[x]->addr.sin_family = sin->sin_family;
- iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
- iaxs[x]->peercallno = callno;
- iaxs[x]->callno = x;
- iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
- iaxs[x]->expiry = min_reg_expire;
- iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
- iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
- iaxs[x]->amaflags = amaflags;
- ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
-
- ast_string_field_set(iaxs[x], accountcode, accountcode);
- ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
- ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
-
- if (iaxs[x]->peercallno) {
- store_by_peercallno(iaxs[x]);
- }
- } else {
- ast_log(LOG_WARNING, "Out of resources\n");
- ast_mutex_unlock(&iaxsl[x]);
- return 0;
- }
- if (!return_locked)
- ast_mutex_unlock(&iaxsl[x]);
- res = x;
- }
- return res;
-}
-
-static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
-
- return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
-}
-
-static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
-
- return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
-}
-
-/*!
- * \brief Queue a frame to a call's owning asterisk channel
- *
- * \pre This function assumes that iaxsl[callno] is locked when called.
- *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
- */
-static int iax2_queue_frame(int callno, struct ast_frame *f)
-{
- for (;;) {
- if (iaxs[callno] && iaxs[callno]->owner) {
- if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
- /* Avoid deadlock by pausing and trying again */
- ast_mutex_unlock(&iaxsl[callno]);
- usleep(1);
- ast_mutex_lock(&iaxsl[callno]);
- } else {
- ast_queue_frame(iaxs[callno]->owner, f);
- ast_mutex_unlock(&iaxs[callno]->owner->lock);
- break;
- }
- } else
- break;
- }
- return 0;
-}
-
-/*!
- * \brief Queue a hangup frame on the ast_channel owner
- *
- * This function queues a hangup frame on the owner of the IAX2 pvt struct that
- * is active for the given call number.
- *
- * \pre Assumes lock for callno is already held.
- *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
- */
-static int iax2_queue_hangup(int callno)
-{
- for (;;) {
- if (iaxs[callno] && iaxs[callno]->owner) {
- if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
- /* Avoid deadlock by pausing and trying again */
- ast_mutex_unlock(&iaxsl[callno]);
- usleep(1);
- ast_mutex_lock(&iaxsl[callno]);
- } else {
- ast_queue_hangup(iaxs[callno]->owner);
- ast_mutex_unlock(&iaxs[callno]->owner->lock);
- break;
- }
- } else
- break;
- }
- return 0;
-}
-
-/*!
- * \brief Queue a control frame on the ast_channel owner
- *
- * This function queues a control frame on the owner of the IAX2 pvt struct that
- * is active for the given call number.
- *
- * \pre Assumes lock for callno is already held.
- *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
- */
-static int iax2_queue_control_data(int callno,
- enum ast_control_frame_type control, const void *data, size_t datalen)
-{
- for (;;) {
- if (iaxs[callno] && iaxs[callno]->owner) {
- if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
- /* Avoid deadlock by pausing and trying again */
- ast_mutex_unlock(&iaxsl[callno]);
- usleep(1);
- ast_mutex_lock(&iaxsl[callno]);
- } else {
- ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
- ast_mutex_unlock(&iaxs[callno]->owner->lock);
- break;
- }
- } else
- break;
- }
- return 0;
-}
-static void destroy_firmware(struct iax_firmware *cur)
-{
- /* Close firmware */
- if (cur->fwh) {
- munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
- }
- close(cur->fd);
- free(cur);
-}
-
-static int try_firmware(char *s)
-{
- struct stat stbuf;
- struct iax_firmware *cur;
- int ifd;
- int fd;
- int res;
-
- struct ast_iax2_firmware_header *fwh, fwh2;
- struct MD5Context md5;
- unsigned char sum[16];
- unsigned char buf[1024];
- int len, chunk;
- char *s2;
- char *last;
- s2 = alloca(strlen(s) + 100);
- if (!s2) {
- ast_log(LOG_WARNING, "Alloca failed!\n");
- return -1;
- }
- last = strrchr(s, '/');
- if (last)
- last++;
- else
- last = s;
- snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
- res = stat(s, &stbuf);
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
- return -1;
- }
- /* Make sure it's not a directory */
- if (S_ISDIR(stbuf.st_mode))
- return -1;
- ifd = open(s, O_RDONLY);
- if (ifd < 0) {
- ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
- return -1;
- }
- fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
- close(ifd);
- return -1;
- }
- /* Unlink our newly created file */
- unlink(s2);
-
- /* Now copy the firmware into it */
- len = stbuf.st_size;
- while(len) {
- chunk = len;
- if (chunk > sizeof(buf))
- chunk = sizeof(buf);
- res = read(ifd, buf, chunk);
- if (res != chunk) {
- ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
- close(ifd);
- close(fd);
- return -1;
- }
- res = write(fd, buf, chunk);
- if (res != chunk) {
- ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
- close(ifd);
- close(fd);
- return -1;
- }
- len -= chunk;
- }
- close(ifd);
- /* Return to the beginning */
- lseek(fd, 0, SEEK_SET);
- if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
- ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
- close(fd);
- return -1;
- }
- if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
- ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
- close(fd);
- return -1;
- }
- if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
- ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
- close(fd);
- return -1;
- }
- if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
- ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
- close(fd);
- return -1;
- }
- fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (fwh == (void *) -1) {
- ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
- close(fd);
- return -1;
- }
- MD5Init(&md5);
- MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
- MD5Final(sum, &md5);
- if (memcmp(sum, fwh->chksum, sizeof(sum))) {
- ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
- munmap((void*)fwh, stbuf.st_size);
- close(fd);
- return -1;
- }
- cur = waresl.wares;
- while(cur) {
- if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
- /* Found a candidate */
- if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
- /* The version we have on loaded is older, load this one instead */
- break;
- /* This version is no newer than what we have. Don't worry about it.
- We'll consider it a proper load anyhow though */
- munmap((void*)fwh, stbuf.st_size);
- close(fd);
- return 0;
- }
- cur = cur->next;
- }
- if (!cur) {
- /* Allocate a new one and link it */
- if ((cur = ast_calloc(1, sizeof(*cur)))) {
- cur->fd = -1;
- cur->next = waresl.wares;
- waresl.wares = cur;
- }
- }
- if (cur) {
- if (cur->fwh) {
- munmap((void*)cur->fwh, cur->mmaplen);
- }
- if (cur->fd > -1)
- close(cur->fd);
- cur->fwh = fwh;
- cur->fd = fd;
- cur->mmaplen = stbuf.st_size;
- cur->dead = 0;
- }
- return 0;
-}
-
-static int iax_check_version(char *dev)
-{
- int res = 0;
- struct iax_firmware *cur;
- if (!ast_strlen_zero(dev)) {
- ast_mutex_lock(&waresl.lock);
- cur = waresl.wares;
- while(cur) {
- if (!strcmp(dev, (char *)cur->fwh->devname)) {
- res = ntohs(cur->fwh->version);
- break;
- }
- cur = cur->next;
- }
- ast_mutex_unlock(&waresl.lock);
- }
- return res;
-}
-
-static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
-{
- int res = -1;
- unsigned int bs = desc & 0xff;
- unsigned int start = (desc >> 8) & 0xffffff;
- unsigned int bytes;
- struct iax_firmware *cur;
- if (!ast_strlen_zero((char *)dev) && bs) {
- start *= bs;
- ast_mutex_lock(&waresl.lock);
- cur = waresl.wares;
- while(cur) {
- if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
- iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
- if (start < ntohl(cur->fwh->datalen)) {
- bytes = ntohl(cur->fwh->datalen) - start;
- if (bytes > bs)
- bytes = bs;
- iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
- } else {
- bytes = 0;
- iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
- }
- if (bytes == bs)
- res = 0;
- else
- res = 1;
- break;
- }
- cur = cur->next;
- }
- ast_mutex_unlock(&waresl.lock);
- }
- return res;
-}
-
-
-static void reload_firmware(int unload)
-{
- struct iax_firmware *cur, *curl, *curp;
- DIR *fwd;
- struct dirent *de;
- char dir[256];
- char fn[256];
- /* Mark all as dead */
- ast_mutex_lock(&waresl.lock);
- cur = waresl.wares;
- while(cur) {
- cur->dead = 1;
- cur = cur->next;
- }
-
- /* Now that we've freed them, load the new ones */
- if (!unload) {
- snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
- fwd = opendir(dir);
- if (fwd) {
- while((de = readdir(fwd))) {
- if (de->d_name[0] != '.') {
- snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
- if (!try_firmware(fn)) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
- }
- }
- }
- closedir(fwd);
- } else
- ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
- }
-
- /* Clean up leftovers */
- cur = waresl.wares;
- curp = NULL;
- while(cur) {
- curl = cur;
- cur = cur->next;
- if (curl->dead) {
- if (curp) {
- curp->next = cur;
- } else {
- waresl.wares = cur;
- }
- destroy_firmware(curl);
- } else {
- curp = cur;
- }
- }
- ast_mutex_unlock(&waresl.lock);
-}
-
-/*!
- * \note This function assumes that iaxsl[callno] is locked when called.
- *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function calls iax2_queue_frame(), which may unlock and lock the mutex
- * associated with this callno, meaning that another thread may grab it and destroy the call.
- */
-static int __do_deliver(void *data)
-{
- /* Just deliver the packet by using queueing. This is called by
- the IAX thread with the iaxsl lock held. */
- struct iax_frame *fr = data;
- fr->retrans = -1;
- ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
- if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
- iax2_queue_frame(fr->callno, &fr->af);
- /* Free our iax frame */
- iax2_frame_free(fr);
- /* And don't run again */
- return 0;
-}
-
-static int handle_error(void)
-{
- /* XXX Ideally we should figure out why an error occured and then abort those
- rather than continuing to try. Unfortunately, the published interface does
- not seem to work XXX */
-#if 0
- struct sockaddr_in *sin;
- int res;
- struct msghdr m;
- struct sock_extended_err e;
- m.msg_name = NULL;
- m.msg_namelen = 0;
- m.msg_iov = NULL;
- m.msg_control = &e;
- m.msg_controllen = sizeof(e);
- m.msg_flags = 0;
- res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
- if (res < 0)
- ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
- else {
- if (m.msg_controllen) {
- sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
- if (sin)
- ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
- else
- ast_log(LOG_WARNING, "No address detected??\n");
- } else {
- ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
- }
- }
-#endif
- return 0;
-}
-
-static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
-{
- int res;
- res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
- sizeof(*sin));
- if (res < 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
- handle_error();
- } else
- res = 0;
- return res;
-}
-
-static int send_packet(struct iax_frame *f)
-{
- int res;
- int callno = f->callno;
-
- /* Don't send if there was an error, but return error instead */
- if (!callno || !iaxs[callno] || iaxs[callno]->error)
- return -1;
-
- /* Called with iaxsl held */
- if (option_debug > 2 && iaxdebug)
- ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
- if (f->transfer) {
- if (iaxdebug)
- iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
- res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
- sizeof(iaxs[callno]->transfer));
- } else {
- if (iaxdebug)
- iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
- res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
- sizeof(iaxs[callno]->addr));
- }
- if (res < 0) {
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
- handle_error();
- } else
- res = 0;
- return res;
-}
-
-/*!
- * \note Since this function calls iax2_queue_hangup(), the pvt struct
- * for the given call number may disappear during its execution.
- */
-static int iax2_predestroy(int callno)
-{
- struct ast_channel *c;
- struct chan_iax2_pvt *pvt = iaxs[callno];
-
- if (!pvt)
- return -1;
- if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
- iax2_destroy_helper(pvt);
- ast_set_flag(pvt, IAX_ALREADYGONE);
- }
- c = pvt->owner;
- if (c) {
- c->tech_pvt = NULL;
- iax2_queue_hangup(callno);
- pvt->owner = NULL;
- ast_module_unref(ast_module_info->self);
- }
- return 0;
-}
-
-static int update_packet(struct iax_frame *f)
-{
- /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
- struct ast_iax2_full_hdr *fh = f->data;
- /* Mark this as a retransmission */
- fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
- /* Update iseqno */
- f->iseqno = iaxs[f->callno]->iseqno;
- fh->iseqno = f->iseqno;
- return 0;
-}
-
-static int attempt_transmit(const void *data);
-static void __attempt_transmit(const void *data)
-{
- /* Attempt to transmit the frame to the remote peer...
- Called without iaxsl held. */
- struct iax_frame *f = (struct iax_frame *)data;
- int freeme=0;
- int callno = f->callno;
- /* Make sure this call is still active */
- if (callno)
- ast_mutex_lock(&iaxsl[callno]);
- if (callno && iaxs[callno]) {
- if ((f->retries < 0) /* Already ACK'd */ ||
- (f->retries >= max_retries) /* Too many attempts */) {
- /* Record an error if we've transmitted too many times */
- if (f->retries >= max_retries) {
- if (f->transfer) {
- /* Transfer timeout */
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
- } else if (f->final) {
- if (f->final)
- iax2_destroy(callno);
- } else {
- if (iaxs[callno]->owner)
- ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
- iaxs[callno]->error = ETIMEDOUT;
- if (iaxs[callno]->owner) {
- struct ast_frame fr = { 0, };
- /* Hangup the fd */
- fr.frametype = AST_FRAME_CONTROL;
- fr.subclass = AST_CONTROL_HANGUP;
- iax2_queue_frame(callno, &fr); // XXX
- /* Remember, owner could disappear */
- if (iaxs[callno] && iaxs[callno]->owner)
- iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
- } else {
- if (iaxs[callno]->reg) {
- memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
- iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
- iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
- }
- iax2_destroy(callno);
- }
- }
-
- }
- freeme++;
- } else {
- /* Update it if it needs it */
- update_packet(f);
- /* Attempt transmission */
- send_packet(f);
- f->retries++;
- /* Try again later after 10 times as long */
- f->retrytime *= 10;
- if (f->retrytime > MAX_RETRY_TIME)
- f->retrytime = MAX_RETRY_TIME;
- /* Transfer messages max out at one second */
- if (f->transfer && (f->retrytime > 1000))
- f->retrytime = 1000;
- f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
- }
- } else {
- /* Make sure it gets freed */
- f->retries = -1;
- freeme++;
- }
- if (callno)
- ast_mutex_unlock(&iaxsl[callno]);
- /* Do not try again */
- if (freeme) {
- /* Don't attempt delivery, just remove it from the queue */
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_REMOVE(&iaxq.queue, f, list);
- iaxq.count--;
- AST_LIST_UNLOCK(&iaxq.queue);
- f->retrans = -1;
- /* Free the IAX frame */
- iax2_frame_free(f);
- }
-}
-
-static int attempt_transmit(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__attempt_transmit, data))
-#endif
- __attempt_transmit(data);
- return 0;
-}
-
-static int iax2_prune_realtime(int fd, int argc, char *argv[])
-{
- struct iax2_peer *peer;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (!strcmp(argv[3],"all")) {
- reload_config();
- ast_cli(fd, "OK cache is flushed.\n");
- } else if ((peer = find_peer(argv[3], 0))) {
- if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
- ast_set_flag(peer, IAX_RTAUTOCLEAR);
- expire_registry(peer_ref(peer));
- ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
- } else {
- ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
- }
- peer_unref(peer);
- } else {
- ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
- }
-
- return RESULT_SUCCESS;
-}
-
-static int iax2_test_losspct(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- test_losspct = atoi(argv[3]);
-
- return RESULT_SUCCESS;
-}
-
-#ifdef IAXTESTS
-static int iax2_test_late(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- test_late = atoi(argv[3]);
-
- return RESULT_SUCCESS;
-}
-
-static int iax2_test_resync(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- test_resync = atoi(argv[3]);
-
- return RESULT_SUCCESS;
-}
-
-static int iax2_test_jitter(int fd, int argc, char *argv[])
-{
- if (argc < 4 || argc > 5)
- return RESULT_SHOWUSAGE;
-
- test_jit = atoi(argv[3]);
- if (argc == 5)
- test_jitpct = atoi(argv[4]);
-
- return RESULT_SUCCESS;
-}
-#endif /* IAXTESTS */
-
-/*! \brief peer_status: Report Peer status in character string */
-/* returns 1 if peer is online, -1 if unmonitored */
-static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
-{
- int res = 0;
- if (peer->maxms) {
- if (peer->lastms < 0) {
- ast_copy_string(status, "UNREACHABLE", statuslen);
- } else if (peer->lastms > peer->maxms) {
- snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
- res = 1;
- } else if (peer->lastms) {
- snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
- res = 1;
- } else {
- ast_copy_string(status, "UNKNOWN", statuslen);
- }
- } else {
- ast_copy_string(status, "Unmonitored", statuslen);
- res = -1;
- }
- return res;
-}
-
-/*! \brief Show one peer in detail */
-static int iax2_show_peer(int fd, int argc, char *argv[])
-{
- char status[30];
- char cbuf[256];
- struct iax2_peer *peer;
- char codec_buf[512];
- int x = 0, codec = 0, load_realtime = 0;
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
-
- peer = find_peer(argv[3], load_realtime);
- if (peer) {
- ast_cli(fd,"\n\n");
- ast_cli(fd, " * Name : %s\n", peer->name);
- ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
- ast_cli(fd, " Context : %s\n", peer->context);
- ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
- ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
- ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
- ast_cli(fd, " Expire : %d\n", peer->expire);
- ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
- ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
- ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
- ast_cli(fd, " Username : %s\n", peer->username);
- ast_cli(fd, " Codecs : ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
- ast_cli(fd, "%s\n", codec_buf);
-
- ast_cli(fd, " Codec Order : (");
- for(x = 0; x < 32 ; x++) {
- codec = ast_codec_pref_index(&peer->prefs,x);
- if(!codec)
- break;
- ast_cli(fd, "%s", ast_getformatname(codec));
- if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
- ast_cli(fd, "|");
- }
-
- if (!x)
- ast_cli(fd, "none");
- ast_cli(fd, ")\n");
-
- ast_cli(fd, " Status : ");
- peer_status(peer, status, sizeof(status));
- ast_cli(fd, "%s\n",status);
- ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
- ast_cli(fd,"\n");
- peer_unref(peer);
- } else {
- ast_cli(fd,"Peer %s not found.\n", argv[3]);
- ast_cli(fd,"\n");
- }
-
- return RESULT_SUCCESS;
-}
-
-static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
-{
- int which = 0;
- struct iax2_peer *peer;
- char *res = NULL;
- int wordlen = strlen(word);
- struct ao2_iterator i;
-
- /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
- if (pos != 3)
- return NULL;
-
- i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
- if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
- res = ast_strdup(peer->name);
- peer_unref(peer);
- break;
- }
- peer_unref(peer);
- }
-
- return res;
-}
-
-static int iax2_show_stats(int fd, int argc, char *argv[])
-{
- struct iax_frame *cur;
- int cnt = 0, dead=0, final=0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
- if (cur->retries < 0)
- dead++;
- if (cur->final)
- final++;
- cnt++;
- }
- AST_LIST_UNLOCK(&iaxq.queue);
-
- ast_cli(fd, " IAX Statistics\n");
- ast_cli(fd, "---------------------\n");
- ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
- ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
-
- return RESULT_SUCCESS;
-}
-
-static int iax2_show_cache(int fd, int argc, char *argv[])
-{
- struct iax2_dpcache *dp;
- char tmp[1024], *pc;
- int s;
- int x,y;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- ast_mutex_lock(&dpcache_lock);
- dp = dpcache;
- ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
- while(dp) {
- s = dp->expiry.tv_sec - tv.tv_sec;
- tmp[0] = '\0';
- if (dp->flags & CACHE_FLAG_EXISTS)
- strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_NONEXISTENT)
- strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_CANEXIST)
- strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_PENDING)
- strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_TIMEOUT)
- strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_TRANSMITTED)
- strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_MATCHMORE)
- strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
- if (dp->flags & CACHE_FLAG_UNKNOWN)
- strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
- /* Trim trailing pipe */
- if (!ast_strlen_zero(tmp))
- tmp[strlen(tmp) - 1] = '\0';
- else
- ast_copy_string(tmp, "(none)", sizeof(tmp));
- y=0;
- pc = strchr(dp->peercontext, '@');
- if (!pc)
- pc = dp->peercontext;
- else
- pc++;
- for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
- if (dp->waiters[x] > -1)
- y++;
- if (s > 0)
- ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
- else
- ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
- dp = dp->next;
- }
- ast_mutex_unlock(&dpcache_lock);
- return RESULT_SUCCESS;
-}
-
-static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
-
-static void unwrap_timestamp(struct iax_frame *fr)
-{
- int x;
-
- if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
- x = fr->ts - iaxs[fr->callno]->last;
- if (x < -50000) {
- /* Sudden big jump backwards in timestamp:
- What likely happened here is that miniframe timestamp has circled but we haven't
- gotten the update from the main packet. We'll just pretend that we did, and
- update the timestamp appropriately. */
- fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
- }
- if (x > 50000) {
- /* Sudden apparent big jump forwards in timestamp:
- What's likely happened is this is an old miniframe belonging to the previous
- top-16-bit timestamp that has turned up out of order.
- Adjust the timestamp appropriately. */
- fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
- }
- }
-}
-
-static int get_from_jb(const void *p);
-
-static void update_jbsched(struct chan_iax2_pvt *pvt)
-{
- int when;
-
- when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
-
- when = jb_next(pvt->jb) - when;
-
- AST_SCHED_DEL(sched, pvt->jbid);
-
- if(when <= 0) {
- /* XXX should really just empty until when > 0.. */
- when = 1;
- }
-
- pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
-}
-
-static void __get_from_jb(const void *p)
-{
- int callno = PTR_TO_CALLNO(p);
- struct chan_iax2_pvt *pvt = NULL;
- struct iax_frame *fr;
- jb_frame frame;
- int ret;
- long now;
- long next;
- struct timeval tv;
-
- /* Make sure we have a valid private structure before going on */
- ast_mutex_lock(&iaxsl[callno]);
- pvt = iaxs[callno];
- if (!pvt) {
- /* No go! */
- ast_mutex_unlock(&iaxsl[callno]);
- return;
- }
-
- pvt->jbid = -1;
-
- gettimeofday(&tv,NULL);
- /* round up a millisecond since ast_sched_runq does; */
- /* prevents us from spinning while waiting for our now */
- /* to catch up with runq's now */
- tv.tv_usec += 1000;
-
- now = ast_tvdiff_ms(tv, pvt->rxcore);
-
- if(now >= (next = jb_next(pvt->jb))) {
- ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
- switch(ret) {
- case JB_OK:
- fr = frame.data;
- __do_deliver(fr);
- /* __do_deliver() can cause the call to disappear */
- pvt = iaxs[callno];
- break;
- case JB_INTERP:
- {
- struct ast_frame af = { 0, };
-
- /* create an interpolation frame */
- af.frametype = AST_FRAME_VOICE;
- af.subclass = pvt->voiceformat;
- af.samples = frame.ms * 8;
- af.src = "IAX2 JB interpolation";
- af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
- af.offset = AST_FRIENDLY_OFFSET;
-
- /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
- * which we'd need to malloc, and then it would free it. That seems like a drag */
- if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
- iax2_queue_frame(callno, &af);
- /* iax2_queue_frame() could cause the call to disappear */
- pvt = iaxs[callno];
- }
- }
- break;
- case JB_DROP:
- iax2_frame_free(frame.data);
- break;
- case JB_NOFRAME:
- case JB_EMPTY:
- /* do nothing */
- break;
- default:
- /* shouldn't happen */
- break;
- }
- }
- if (pvt)
- update_jbsched(pvt);
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static int get_from_jb(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__get_from_jb, data))
-#endif
- __get_from_jb(data);
- return 0;
-}
-
-/*!
- * \note This function assumes fr->callno is locked
- *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- */
-static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
-{
- int type, len;
- int ret;
- int needfree = 0;
- struct ast_channel *owner = NULL;
- struct ast_channel *bridge = NULL;
-
- /* Attempt to recover wrapped timestamps */
- unwrap_timestamp(fr);
-
- /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
- if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
- fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
- else {
-#if 0
- if (option_debug)
- ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
-#endif
- fr->af.delivery = ast_tv(0,0);
- }
-
- type = JB_TYPE_CONTROL;
- len = 0;
-
- if(fr->af.frametype == AST_FRAME_VOICE) {
- type = JB_TYPE_VOICE;
- len = ast_codec_get_samples(&fr->af) / 8;
- } else if(fr->af.frametype == AST_FRAME_CNG) {
- type = JB_TYPE_SILENCE;
- }
-
- if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
- if (tsout)
- *tsout = fr->ts;
- __do_deliver(fr);
- return -1;
- }
-
- if ((owner = iaxs[fr->callno]->owner))
- bridge = ast_bridged_channel(owner);
-
- /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
- * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
- if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
- jb_frame frame;
-
- /* deliver any frames in the jb */
- while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
- __do_deliver(frame.data);
- /* __do_deliver() can make the call disappear */
- if (!iaxs[fr->callno])
- return -1;
- }
-
- jb_reset(iaxs[fr->callno]->jb);
-
- AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
-
- /* deliver this frame now */
- if (tsout)
- *tsout = fr->ts;
- __do_deliver(fr);
- return -1;
- }
-
- /* insert into jitterbuffer */
- /* TODO: Perhaps we could act immediately if it's not droppable and late */
- ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
- calc_rxstamp(iaxs[fr->callno],fr->ts));
- if (ret == JB_DROP) {
- needfree++;
- } else if (ret == JB_SCHED) {
- update_jbsched(iaxs[fr->callno]);
- }
- if (tsout)
- *tsout = fr->ts;
- if (needfree) {
- /* Free our iax frame */
- iax2_frame_free(fr);
- return -1;
- }
- return 0;
-}
-
-static int iax2_transmit(struct iax_frame *fr)
-{
- /* Lock the queue and place this packet at the end */
- /* By setting this to 0, the network thread will send it for us, and
- queue retransmission if necessary */
- fr->sentyet = 0;
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
- iaxq.count++;
- AST_LIST_UNLOCK(&iaxq.queue);
- /* Wake up the network and scheduler thread */
- if (netthreadid != AST_PTHREADT_NULL)
- pthread_kill(netthreadid, SIGURG);
- signal_condition(&sched_lock, &sched_cond);
- return 0;
-}
-
-
-
-static int iax2_digit_begin(struct ast_channel *c, char digit)
-{
- return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
-}
-
-static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
-{
- return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
-}
-
-static int iax2_sendtext(struct ast_channel *c, const char *text)
-{
-
- return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
- 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
-}
-
-static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
-{
- return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
-}
-
-static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
-{
- return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
-}
-
-static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
-{
- unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno])
- iaxs[callno]->owner = newchan;
- else
- ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
- ast_mutex_unlock(&iaxsl[callno]);
- return 0;
-}
-
-/*!
- * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
- * so do not call this with a pvt lock held.
- */
-static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
-{
- struct ast_variable *var = NULL;
- struct ast_variable *tmp;
- struct iax2_peer *peer=NULL;
- time_t regseconds = 0, nowtime;
- int dynamic=0;
-
- if (peername) {
- var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
- if (!var && sin)
- var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
- } else if (sin) {
- char porta[25];
- sprintf(porta, "%d", ntohs(sin->sin_port));
- var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
- if (var) {
- /* We'll need the peer name in order to build the structure! */
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "name"))
- peername = tmp->value;
- }
- }
- }
- if (!var && peername) { /* Last ditch effort */
- var = ast_load_realtime("iaxpeers", "name", peername, NULL);
- /*!\note
- * If this one loaded something, then we need to ensure that the host
- * field matched. The only reason why we can't have this as a criteria
- * is because we only have the IP address and the host field might be
- * set as a name (and the reverse PTR might not match).
- */
- if (var && sin) {
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "host")) {
- struct ast_hostent ahp;
- struct hostent *hp;
- if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
- /* No match */
- ast_variables_destroy(var);
- var = NULL;
- }
- break;
- }
- }
- }
- }
- if (!var)
- return NULL;
-
- peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
-
- if (!peer) {
- ast_variables_destroy(var);
- return NULL;
- }
-
- for (tmp = var; tmp; tmp = tmp->next) {
- /* Make sure it's not a user only... */
- if (!strcasecmp(tmp->name, "type")) {
- if (strcasecmp(tmp->value, "friend") &&
- strcasecmp(tmp->value, "peer")) {
- /* Whoops, we weren't supposed to exist! */
- peer = peer_unref(peer);
- break;
- }
- } else if (!strcasecmp(tmp->name, "regseconds")) {
- ast_get_time_t(tmp->value, &regseconds, 0, NULL);
- } else if (!strcasecmp(tmp->name, "ipaddr")) {
- inet_aton(tmp->value, &(peer->addr.sin_addr));
- } else if (!strcasecmp(tmp->name, "port")) {
- peer->addr.sin_port = htons(atoi(tmp->value));
- } else if (!strcasecmp(tmp->name, "host")) {
- if (!strcasecmp(tmp->value, "dynamic"))
- dynamic = 1;
- }
- }
-
- ast_variables_destroy(var);
-
- if (!peer)
- return NULL;
-
- if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
- ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
- if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
- if (peer->expire > -1) {
- if (!ast_sched_del(sched, peer->expire)) {
- peer->expire = -1;
- peer_unref(peer);
- }
- }
- peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
- if (peer->expire == -1)
- peer_unref(peer);
- }
- ao2_link(peers, peer);
- if (ast_test_flag(peer, IAX_DYNAMIC))
- reg_source_db(peer);
- } else {
- ast_set_flag(peer, IAX_TEMPONLY);
- }
-
- if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
- time(&nowtime);
- if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
- memset(&peer->addr, 0, sizeof(peer->addr));
- realtime_update_peer(peer->name, &peer->addr, 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
- peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
- }
- else {
- if (option_debug)
- ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
- peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
- }
- }
-
- return peer;
-}
-
-static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
-{
- struct ast_variable *var;
- struct ast_variable *tmp;
- struct iax2_user *user=NULL;
-
- var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
- if (!var)
- var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
- if (!var && sin) {
- char porta[6];
- snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
- var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
- if (!var)
- var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
- }
- if (!var) { /* Last ditch effort */
- var = ast_load_realtime("iaxusers", "name", username, NULL);
- /*!\note
- * If this one loaded something, then we need to ensure that the host
- * field matched. The only reason why we can't have this as a criteria
- * is because we only have the IP address and the host field might be
- * set as a name (and the reverse PTR might not match).
- */
- if (var) {
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "host")) {
- struct ast_hostent ahp;
- struct hostent *hp;
- if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
- /* No match */
- ast_variables_destroy(var);
- var = NULL;
- }
- break;
- }
- }
- }
- }
- if (!var)
- return NULL;
-
- tmp = var;
- while(tmp) {
- /* Make sure it's not a peer only... */
- if (!strcasecmp(tmp->name, "type")) {
- if (strcasecmp(tmp->value, "friend") &&
- strcasecmp(tmp->value, "user")) {
- return NULL;
- }
- }
- tmp = tmp->next;
- }
-
- user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
-
- ast_variables_destroy(var);
-
- if (!user)
- return NULL;
-
- if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
- ast_set_flag(user, IAX_RTCACHEFRIENDS);
- ao2_link(users, user);
- } else {
- ast_set_flag(user, IAX_TEMPONLY);
- }
-
- return user;
-}
-
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
-{
- char port[10];
- char regseconds[20];
-
- snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
- snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
- ast_update_realtime("iaxpeers", "name", peername,
- "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
- "regseconds", regseconds, NULL);
-}
-
-struct create_addr_info {
- int capability;
- unsigned int flags;
- int maxtime;
- int encmethods;
- int found;
- int sockfd;
- int adsi;
- char username[80];
- char secret[80];
- char outkey[80];
- char timezone[80];
- char prefs[32];
- char context[AST_MAX_CONTEXT];
- char peercontext[AST_MAX_CONTEXT];
- char mohinterpret[MAX_MUSICCLASS];
- char mohsuggest[MAX_MUSICCLASS];
-};
-
-static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
-{
- struct ast_hostent ahp;
- struct hostent *hp;
- struct iax2_peer *peer;
- int res = -1;
- struct ast_codec_pref ourprefs;
-
- ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
- cai->sockfd = defaultsockfd;
- cai->maxtime = 0;
- sin->sin_family = AF_INET;
-
- if (!(peer = find_peer(peername, 1))) {
- cai->found = 0;
-
- hp = ast_gethostbyname(peername, &ahp);
- if (hp) {
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- sin->sin_port = htons(IAX_DEFAULT_PORTNO);
- /* use global iax prefs for unknown peer/user */
- /* But move the calling channel's native codec to the top of the preference list */
- memcpy(&ourprefs, &prefs, sizeof(ourprefs));
- if (c)
- ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
- ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
- return 0;
- } else {
- ast_log(LOG_WARNING, "No such host: %s\n", peername);
- return -1;
- }
- }
-
- cai->found = 1;
-
- /* if the peer has no address (current or default), return failure */
- if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
- goto return_unref;
-
- /* if the peer is being monitored and is currently unreachable, return failure */
- if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
- goto return_unref;
-
- ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
- cai->maxtime = peer->maxms;
- cai->capability = peer->capability;
- cai->encmethods = peer->encmethods;
- cai->sockfd = peer->sockfd;
- cai->adsi = peer->adsi;
- memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
- /* Move the calling channel's native codec to the top of the preference list */
- if (c) {
- ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
- ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
- }
- ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
- ast_copy_string(cai->context, peer->context, sizeof(cai->context));
- ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
- ast_copy_string(cai->username, peer->username, sizeof(cai->username));
- ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
- ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
- ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
- ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
- if (ast_strlen_zero(peer->dbsecret)) {
- ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
- } else {
- char *family;
- char *key = NULL;
-
- family = ast_strdupa(peer->dbsecret);
- key = strchr(family, '/');
- if (key)
- *key++ = '\0';
- if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
- ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
- goto return_unref;
- }
- }
-
- if (peer->addr.sin_addr.s_addr) {
- sin->sin_addr = peer->addr.sin_addr;
- sin->sin_port = peer->addr.sin_port;
- } else {
- sin->sin_addr = peer->defaddr.sin_addr;
- sin->sin_port = peer->defaddr.sin_port;
- }
-
- res = 0;
-
-return_unref:
- peer_unref(peer);
-
- return res;
-}
-
-static void __auto_congest(const void *nothing)
-{
- int callno = PTR_TO_CALLNO(nothing);
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno]) {
- iaxs[callno]->initid = -1;
- iax2_queue_frame(callno, &f);
- ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
- }
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static int auto_congest(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__auto_congest, data))
-#endif
- __auto_congest(data);
- return 0;
-}
-
-static unsigned int iax2_datetime(const char *tz)
-{
- time_t t;
- struct tm tm;
- unsigned int tmp;
- time(&t);
- if (!ast_strlen_zero(tz))
- ast_localtime(&t, &tm, tz);
- else
- ast_localtime(&t, &tm, NULL);
- tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */
- tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */
- tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */
- tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */
- tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */
- tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
- return tmp;
-}
-
-struct parsed_dial_string {
- char *username;
- char *password;
- char *key;
- char *peer;
- char *port;
- char *exten;
- char *context;
- char *options;
-};
-
-/*!
- * \brief Parses an IAX dial string into its component parts.
- * \param data the string to be parsed
- * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
- * \return nothing
- *
- * This function parses the string and fills the structure
- * with pointers to its component parts. The input string
- * will be modified.
- *
- * \note This function supports both plaintext passwords and RSA
- * key names; if the password string is formatted as '[keyname]',
- * then the keyname will be placed into the key field, and the
- * password field will be set to NULL.
- *
- * \note The dial string format is:
- * [username[:password]@]peer[:port][/exten[@@context]][/options]
- */
-static void parse_dial_string(char *data, struct parsed_dial_string *pds)
-{
- if (ast_strlen_zero(data))
- return;
-
- pds->peer = strsep(&data, "/");
- pds->exten = strsep(&data, "/");
- pds->options = data;
-
- if (pds->exten) {
- data = pds->exten;
- pds->exten = strsep(&data, "@");
- pds->context = data;
- }
-
- if (strchr(pds->peer, '@')) {
- data = pds->peer;
- pds->username = strsep(&data, "@");
- pds->peer = data;
- }
-
- if (pds->username) {
- data = pds->username;
- pds->username = strsep(&data, ":");
- pds->password = data;
- }
-
- data = pds->peer;
- pds->peer = strsep(&data, ":");
- pds->port = data;
-
- /* check for a key name wrapped in [] in the secret position, if found,
- move it to the key field instead
- */
- if (pds->password && (pds->password[0] == '[')) {
- pds->key = ast_strip_quoted(pds->password, "[", "]");
- pds->password = NULL;
- }
-}
-
-static int iax2_call(struct ast_channel *c, char *dest, int timeout)
-{
- struct sockaddr_in sin;
- char *l=NULL, *n=NULL, *tmpstr;
- struct iax_ie_data ied;
- char *defaultrdest = "s";
- unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
- struct parsed_dial_string pds;
- struct create_addr_info cai;
-
- if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
- return -1;
- }
-
- memset(&cai, 0, sizeof(cai));
- cai.encmethods = iax2_encryption;
-
- memset(&pds, 0, sizeof(pds));
- tmpstr = ast_strdupa(dest);
- parse_dial_string(tmpstr, &pds);
-
- if (ast_strlen_zero(pds.peer)) {
- ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
- return -1;
- }
-
- if (!pds.exten) {
- if (!ast_strlen_zero(c->exten))
- pds.exten = c->exten;
- else
- pds.exten = defaultrdest;
- }
-
- if (create_addr(pds.peer, c, &sin, &cai)) {
- ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
- return -1;
- }
-
- if (!pds.username && !ast_strlen_zero(cai.username))
- pds.username = cai.username;
- if (!pds.password && !ast_strlen_zero(cai.secret))
- pds.password = cai.secret;
- if (!pds.key && !ast_strlen_zero(cai.outkey))
- pds.key = cai.outkey;
- if (!pds.context && !ast_strlen_zero(cai.peercontext))
- pds.context = cai.peercontext;
-
- /* Keep track of the context for outgoing calls too */
- ast_copy_string(c->context, cai.context, sizeof(c->context));
-
- if (pds.port)
- sin.sin_port = htons(atoi(pds.port));
-
- l = c->cid.cid_num;
- n = c->cid.cid_name;
-
- /* Now build request */
- memset(&ied, 0, sizeof(ied));
-
- /* On new call, first IE MUST be IAX version of caller */
- iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
- iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
- if (pds.options && strchr(pds.options, 'a')) {
- /* Request auto answer */
- iax_ie_append(&ied, IAX_IE_AUTOANSWER);
- }
-
- iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
-
- if (l) {
- iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
- iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
- } else {
- if (n)
- iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
- else
- iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
- }
-
- iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
- iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
-
- if (n)
- iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
- if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
- iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
-
- if (!ast_strlen_zero(c->language))
- iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
- if (!ast_strlen_zero(c->cid.cid_dnid))
- iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
- if (!ast_strlen_zero(c->cid.cid_rdnis))
- iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
-
- if (pds.context)
- iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
-
- if (pds.username)
- iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
-
- if (cai.encmethods)
- iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
-
- ast_mutex_lock(&iaxsl[callno]);
-
- if (!ast_strlen_zero(c->context))
- ast_string_field_set(iaxs[callno], context, c->context);
-
- if (pds.username)
- ast_string_field_set(iaxs[callno], username, pds.username);
-
- iaxs[callno]->encmethods = cai.encmethods;
-
- iaxs[callno]->adsi = cai.adsi;
-
- ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
- ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
-
- if (pds.key)
- ast_string_field_set(iaxs[callno], outkey, pds.key);
- if (pds.password)
- ast_string_field_set(iaxs[callno], secret, pds.password);
-
- iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
- iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
- iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
- iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
-
- if (iaxs[callno]->maxtime) {
- /* Initialize pingtime and auto-congest time */
- iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
- iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
- } else if (autokill) {
- iaxs[callno]->pingtime = autokill / 2;
- iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
- }
-
- /* send the command using the appropriate socket for this peer */
- iaxs[callno]->sockfd = cai.sockfd;
-
- /* Transmit the string in a "NEW" request */
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
-
- ast_mutex_unlock(&iaxsl[callno]);
- ast_setstate(c, AST_STATE_RINGING);
-
- return 0;
-}
-
-static int iax2_hangup(struct ast_channel *c)
-{
- unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
- int alreadygone;
- struct iax_ie_data ied;
- memset(&ied, 0, sizeof(ied));
- ast_mutex_lock(&iaxsl[callno]);
- if (callno && iaxs[callno]) {
- if (option_debug)
- ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
- alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
- /* Send the hangup unless we have had a transmission error or are already gone */
- iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
- if (!iaxs[callno]->error && !alreadygone) {
- send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
- if (!iaxs[callno]) {
- ast_mutex_unlock(&iaxsl[callno]);
- return 0;
- }
- }
- /* Explicitly predestroy it */
- iax2_predestroy(callno);
- /* If we were already gone to begin with, destroy us now */
- if (alreadygone && iaxs[callno]) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
- iax2_destroy(callno);
- }
- }
- ast_mutex_unlock(&iaxsl[callno]);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
- return 0;
-}
-
-static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
-{
- struct ast_option_header *h;
- int res;
-
- switch (option) {
- case AST_OPTION_TXGAIN:
- case AST_OPTION_RXGAIN:
- /* these two cannot be sent, because they require a result */
- errno = ENOSYS;
- return -1;
- default:
- if (!(h = ast_malloc(datalen + sizeof(*h))))
- return -1;
-
- h->flag = AST_OPTION_FLAG_REQUEST;
- h->option = htons(option);
- memcpy(h->data, data, datalen);
- res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
- AST_CONTROL_OPTION, 0, (unsigned char *) h,
- datalen + sizeof(*h), -1);
- free(h);
- return res;
- }
-}
-
-static struct ast_frame *iax2_read(struct ast_channel *c)
-{
- ast_log(LOG_NOTICE, "I should never be called!\n");
- return &ast_null_frame;
-}
-
-static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
-{
- int res;
- struct iax_ie_data ied0;
- struct iax_ie_data ied1;
- unsigned int transferid = (unsigned int)ast_random();
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
- iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
- iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
-
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
- iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
-
- res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
- if (res)
- return -1;
- res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
- if (res)
- return -1;
- iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
- iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
- return 0;
-}
-
-static void lock_both(unsigned short callno0, unsigned short callno1)
-{
- ast_mutex_lock(&iaxsl[callno0]);
- while (ast_mutex_trylock(&iaxsl[callno1])) {
- ast_mutex_unlock(&iaxsl[callno0]);
- usleep(10);
- ast_mutex_lock(&iaxsl[callno0]);
- }
-}
-
-static void unlock_both(unsigned short callno0, unsigned short callno1)
-{
- ast_mutex_unlock(&iaxsl[callno1]);
- ast_mutex_unlock(&iaxsl[callno0]);
-}
-
-static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
-{
- struct ast_channel *cs[3];
- struct ast_channel *who, *other;
- int to = -1;
- int res = -1;
- int transferstarted=0;
- struct ast_frame *f;
- unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
- unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
- struct timeval waittimer = {0, 0}, tv;
-
- lock_both(callno0, callno1);
- if (!iaxs[callno0] || !iaxs[callno1]) {
- unlock_both(callno0, callno1);
- return AST_BRIDGE_FAILED;
- }
- /* Put them in native bridge mode */
- if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
- iaxs[callno0]->bridgecallno = callno1;
- iaxs[callno1]->bridgecallno = callno0;
- }
- unlock_both(callno0, callno1);
-
- /* If not, try to bridge until we can execute a transfer, if we can */
- cs[0] = c0;
- cs[1] = c1;
- for (/* ever */;;) {
- /* Check in case we got masqueraded into */
- if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
- /* Remove from native mode */
- if (c0->tech == &iax2_tech) {
- ast_mutex_lock(&iaxsl[callno0]);
- iaxs[callno0]->bridgecallno = 0;
- ast_mutex_unlock(&iaxsl[callno0]);
- }
- if (c1->tech == &iax2_tech) {
- ast_mutex_lock(&iaxsl[callno1]);
- iaxs[callno1]->bridgecallno = 0;
- ast_mutex_unlock(&iaxsl[callno1]);
- }
- return AST_BRIDGE_FAILED_NOWARN;
- }
- if (c0->nativeformats != c1->nativeformats) {
- if (option_verbose > 2) {
- char buf0[255];
- char buf1[255];
- ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
- ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
- ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
- }
- /* Remove from native mode */
- lock_both(callno0, callno1);
- if (iaxs[callno0])
- iaxs[callno0]->bridgecallno = 0;
- if (iaxs[callno1])
- iaxs[callno1]->bridgecallno = 0;
- unlock_both(callno0, callno1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
- /* check if transfered and if we really want native bridging */
- if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
- /* Try the transfer */
- if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
- ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
- ast_log(LOG_WARNING, "Unable to start the transfer\n");
- transferstarted = 1;
- }
- if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
- /* Call has been transferred. We're no longer involved */
- gettimeofday(&tv, NULL);
- if (ast_tvzero(waittimer)) {
- waittimer = tv;
- } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
- c0->_softhangup |= AST_SOFTHANGUP_DEV;
- c1->_softhangup |= AST_SOFTHANGUP_DEV;
- *fo = NULL;
- *rc = c0;
- res = AST_BRIDGE_COMPLETE;
- break;
- }
- }
- to = 1000;
- who = ast_waitfor_n(cs, 2, &to);
- if (timeoutms > -1) {
- timeoutms -= (1000 - to);
- if (timeoutms < 0)
- timeoutms = 0;
- }
- if (!who) {
- if (!timeoutms) {
- res = AST_BRIDGE_RETRY;
- break;
- }
- if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
- res = AST_BRIDGE_FAILED;
- break;
- }
- continue;
- }
- f = ast_read(who);
- if (!f) {
- *fo = NULL;
- *rc = who;
- res = AST_BRIDGE_COMPLETE;
- break;
- }
- if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
- *fo = f;
- *rc = who;
- res = AST_BRIDGE_COMPLETE;
- break;
- }
- other = (who == c0) ? c1 : c0; /* the 'other' channel */
- if ((f->frametype == AST_FRAME_VOICE) ||
- (f->frametype == AST_FRAME_TEXT) ||
- (f->frametype == AST_FRAME_VIDEO) ||
- (f->frametype == AST_FRAME_IMAGE) ||
- (f->frametype == AST_FRAME_DTMF)) {
- /* monitored dtmf take out of the bridge.
- * check if we monitor the specific source.
- */
- int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
- if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
- *rc = who;
- *fo = f;
- res = AST_BRIDGE_COMPLETE;
- /* Remove from native mode */
- break;
- }
- /* everything else goes to the other side */
- ast_write(other, f);
- }
- ast_frfree(f);
- /* Swap who gets priority */
- cs[2] = cs[0];
- cs[0] = cs[1];
- cs[1] = cs[2];
- }
- lock_both(callno0, callno1);
- if(iaxs[callno0])
- iaxs[callno0]->bridgecallno = 0;
- if(iaxs[callno1])
- iaxs[callno1]->bridgecallno = 0;
- unlock_both(callno0, callno1);
- return res;
-}
-
-static int iax2_answer(struct ast_channel *c)
-{
- unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
- if (option_debug)
- ast_log(LOG_DEBUG, "Answering IAX2 call\n");
- return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
-}
-
-static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
-{
- unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
- struct chan_iax2_pvt *pvt;
- int res = 0;
-
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
-
- ast_mutex_lock(&iaxsl[callno]);
- pvt = iaxs[callno];
-
- switch (condition) {
- case AST_CONTROL_HOLD:
- if (strcasecmp(pvt->mohinterpret, "passthrough")) {
- ast_moh_start(c, data, pvt->mohinterpret);
- goto done;
- }
- break;
- case AST_CONTROL_UNHOLD:
- if (strcasecmp(pvt->mohinterpret, "passthrough")) {
- ast_moh_stop(c);
- goto done;
- }
- }
-
- res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
-
-done:
- ast_mutex_unlock(&iaxsl[callno]);
-
- return res;
-}
-
-static int iax2_transfer(struct ast_channel *c, const char *dest)
-{
- unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
- struct iax_ie_data ied;
- char tmp[256], *context;
- ast_copy_string(tmp, dest, sizeof(tmp));
- context = strchr(tmp, '@');
- if (context) {
- *context = '\0';
- context++;
- }
- memset(&ied, 0, sizeof(ied));
- iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
- if (context)
- iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
- if (option_debug)
- ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
- return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
-}
-
-static int iax2_getpeertrunk(struct sockaddr_in sin)
-{
- struct iax2_peer *peer;
- int res = 0;
- struct ao2_iterator i;
-
- i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
- if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
- (peer->addr.sin_port == sin.sin_port)) {
- res = ast_test_flag(peer, IAX_TRUNK);
- peer_unref(peer);
- break;
- }
- peer_unref(peer);
- }
-
- return res;
-}
-
-/*! \brief Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
-{
- struct ast_channel *tmp;
- struct chan_iax2_pvt *i;
- struct ast_variable *v = NULL;
-
- if (!(i = iaxs[callno])) {
- ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
- return NULL;
- }
-
- /* Don't hold call lock */
- ast_mutex_unlock(&iaxsl[callno]);
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
- ast_mutex_lock(&iaxsl[callno]);
- if (!iaxs[callno]) {
- if (tmp) {
- ast_channel_free(tmp);
- }
- ast_mutex_unlock(&iaxsl[callno]);
- return NULL;
- }
-
- if (!tmp)
- return NULL;
- tmp->tech = &iax2_tech;
- /* We can support any format by default, until we get restricted */
- tmp->nativeformats = capability;
- tmp->readformat = ast_best_codec(capability);
- tmp->writeformat = ast_best_codec(capability);
- tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
-
- /* Don't use ast_set_callerid() here because it will
- * generate a NewCallerID event before the NewChannel event */
- if (!ast_strlen_zero(i->ani))
- tmp->cid.cid_ani = ast_strdup(i->ani);
- else
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
- tmp->cid.cid_dnid = ast_strdup(i->dnid);
- tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
- tmp->cid.cid_pres = i->calling_pres;
- tmp->cid.cid_ton = i->calling_ton;
- tmp->cid.cid_tns = i->calling_tns;
- if (!ast_strlen_zero(i->language))
- ast_string_field_set(tmp, language, i->language);
- if (!ast_strlen_zero(i->accountcode))
- ast_string_field_set(tmp, accountcode, i->accountcode);
- if (i->amaflags)
- tmp->amaflags = i->amaflags;
- ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
- if (i->adsi)
- tmp->adsicpe = i->peeradsicpe;
- else
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
- i->owner = tmp;
- i->capability = capability;
-
- for (v = i->vars ; v ; v = v->next)
- pbx_builtin_setvar_helper(tmp, v->name, v->value);
-
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- i->owner = NULL;
- return NULL;
- }
- }
-
- ast_module_ref(ast_module_info->self);
-
- return tmp;
-}
-
-static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
-{
- unsigned long int mssincetx; /* unsigned to handle overflows */
- long int ms, pred;
-
- tpeer->trunkact = *tv;
- mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
- if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
- /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
- tpeer->txtrunktime = *tv;
- tpeer->lastsent = 999999;
- }
- /* Update last transmit time now */
- tpeer->lasttxtime = *tv;
-
- /* Calculate ms offset */
- ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
- /* Predict from last value */
- pred = tpeer->lastsent + sampms;
- if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
- ms = pred;
-
- /* We never send the same timestamp twice, so fudge a little if we must */
- if (ms == tpeer->lastsent)
- ms = tpeer->lastsent + 1;
- tpeer->lastsent = ms;
- return ms;
-}
-
-static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
-{
- long ms; /* NOT unsigned */
- if (ast_tvzero(iaxs[callno]->rxcore)) {
- /* Initialize rxcore time if appropriate */
- gettimeofday(&iaxs[callno]->rxcore, NULL);
- /* Round to nearest 20ms so traces look pretty */
- iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
- }
- /* Calculate difference between trunk and channel */
- ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
- /* Return as the sum of trunk time and the difference between trunk and real time */
- return ms + ts;
-}
-
-static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
-{
- int ms;
- int voice = 0;
- int genuine = 0;
- int adjust;
- struct timeval *delivery = NULL;
-
-
- /* What sort of frame do we have?: voice is self-explanatory
- "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
- non-genuine frames are CONTROL frames [ringing etc], DTMF
- The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
- the others need a timestamp slaved to the voice frames so that they go in sequence
- */
- if (f) {
- if (f->frametype == AST_FRAME_VOICE) {
- voice = 1;
- delivery = &f->delivery;
- } else if (f->frametype == AST_FRAME_IAX) {
- genuine = 1;
- } else if (f->frametype == AST_FRAME_CNG) {
- p->notsilenttx = 0;
- }
- }
- if (ast_tvzero(p->offset)) {
- gettimeofday(&p->offset, NULL);
- /* Round to nearest 20ms for nice looking traces */
- p->offset.tv_usec -= p->offset.tv_usec % 20000;
- }
- /* If the timestamp is specified, just send it as is */
- if (ts)
- return ts;
- /* If we have a time that the frame arrived, always use it to make our timestamp */
- if (delivery && !ast_tvzero(*delivery)) {
- ms = ast_tvdiff_ms(*delivery, p->offset);
- if (option_debug > 2 && iaxdebug)
- ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
- } else {
- ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
- if (ms < 0)
- ms = 0;
- if (voice) {
- /* On a voice frame, use predicted values if appropriate */
- if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
- /* Adjust our txcore, keeping voice and non-voice synchronized */
- /* AN EXPLANATION:
- When we send voice, we usually send "calculated" timestamps worked out
- on the basis of the number of samples sent. When we send other frames,
- we usually send timestamps worked out from the real clock.
- The problem is that they can tend to drift out of step because the
- source channel's clock and our clock may not be exactly at the same rate.
- We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
- for this call. Moving it adjusts timestamps for non-voice frames.
- We make the adjustment in the style of a moving average. Each time we
- adjust p->offset by 10% of the difference between our clock-derived
- timestamp and the predicted timestamp. That's why you see "10000"
- below even though IAX2 timestamps are in milliseconds.
- The use of a moving average avoids offset moving too radically.
- Generally, "adjust" roams back and forth around 0, with offset hardly
- changing at all. But if a consistent different starts to develop it
- will be eliminated over the course of 10 frames (200-300msecs)
- */
- adjust = (ms - p->nextpred);
- if (adjust < 0)
- p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
- else if (adjust > 0)
- p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
-
- if (!p->nextpred) {
- p->nextpred = ms; /*f->samples / 8;*/
- if (p->nextpred <= p->lastsent)
- p->nextpred = p->lastsent + 3;
- }
- ms = p->nextpred;
- } else {
- /* in this case, just use the actual
- * time, since we're either way off
- * (shouldn't happen), or we're ending a
- * silent period -- and seed the next
- * predicted time. Also, round ms to the
- * next multiple of frame size (so our
- * silent periods are multiples of
- * frame size too) */
-
- if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
- ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
- abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
-
- if (f->samples >= 8) /* check to make sure we dont core dump */
- {
- int diff = ms % (f->samples / 8);
- if (diff)
- ms += f->samples/8 - diff;
- }
-
- p->nextpred = ms;
- p->notsilenttx = 1;
- }
- } else if ( f->frametype == AST_FRAME_VIDEO ) {
- /*
- * IAX2 draft 03 says that timestamps MUST be in order.
- * It does not say anything about several frames having the same timestamp
- * When transporting video, we can have a frame that spans multiple iax packets
- * (so called slices), so it would make sense to use the same timestamp for all of
- * them
- * We do want to make sure that frames don't go backwards though
- */
- if ( (unsigned int)ms < p->lastsent )
- ms = p->lastsent;
- } else {
- /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
- it's a genuine frame */
- if (genuine) {
- /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
- if (ms <= p->lastsent)
- ms = p->lastsent + 3;
- } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
- /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
- ms = p->lastsent + 3;
- }
- }
- }
- p->lastsent = ms;
- if (voice)
- p->nextpred = p->nextpred + f->samples / 8;
- return ms;
-}
-
-static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
-{
- /* Returns where in "receive time" we are. That is, how many ms
- since we received (or would have received) the frame with timestamp 0 */
- int ms;
-#ifdef IAXTESTS
- int jit;
-#endif /* IAXTESTS */
- /* Setup rxcore if necessary */
- if (ast_tvzero(p->rxcore)) {
- p->rxcore = ast_tvnow();
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
- p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
- p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
-#if 1
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
- p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
-#endif
- }
-
- ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
-#ifdef IAXTESTS
- if (test_jit) {
- if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
- jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
- if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
- jit = -jit;
- ms += jit;
- }
- }
- if (test_late) {
- ms += test_late;
- test_late = 0;
- }
-#endif /* IAXTESTS */
- return ms;
-}
-
-static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
-{
- struct iax2_trunk_peer *tpeer;
-
- /* Finds and locks trunk peer */
- ast_mutex_lock(&tpeerlock);
- for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
- /* We don't lock here because tpeer->addr *never* changes */
- if (!inaddrcmp(&tpeer->addr, sin)) {
- ast_mutex_lock(&tpeer->lock);
- break;
- }
- }
- if (!tpeer) {
- if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
- ast_mutex_init(&tpeer->lock);
- tpeer->lastsent = 9999;
- memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
- tpeer->trunkact = ast_tvnow();
- ast_mutex_lock(&tpeer->lock);
- tpeer->next = tpeers;
- tpeer->sockfd = fd;
- tpeers = tpeer;
-#ifdef SO_NO_CHECK
- setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
-#endif
- if (option_debug)
- ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
- }
- }
- ast_mutex_unlock(&tpeerlock);
- return tpeer;
-}
-
-static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
-{
- struct ast_frame *f;
- struct iax2_trunk_peer *tpeer;
- void *tmp, *ptr;
- struct ast_iax2_meta_trunk_entry *met;
- struct ast_iax2_meta_trunk_mini *mtm;
-
- f = &fr->af;
- tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
- if (tpeer) {
- if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
- /* Need to reallocate space */
- if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
- if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
- ast_mutex_unlock(&tpeer->lock);
- return -1;
- }
-
- tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
- tpeer->trunkdata = tmp;
- if (option_debug)
- ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
- } else {
- ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
- ast_mutex_unlock(&tpeer->lock);
- return -1;
- }
- }
-
- /* Append to meta frame */
- ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
- if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
- mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
- mtm->len = htons(f->datalen);
- mtm->mini.callno = htons(pvt->callno);
- mtm->mini.ts = htons(0xffff & fr->ts);
- ptr += sizeof(struct ast_iax2_meta_trunk_mini);
- tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
- } else {
- met = (struct ast_iax2_meta_trunk_entry *)ptr;
- /* Store call number and length in meta header */
- met->callno = htons(pvt->callno);
- met->len = htons(f->datalen);
- /* Advance pointers/decrease length past trunk entry header */
- ptr += sizeof(struct ast_iax2_meta_trunk_entry);
- tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
- }
- /* Copy actual trunk data */
- memcpy(ptr, f->data, f->datalen);
- tpeer->trunkdatalen += f->datalen;
-
- tpeer->calls++;
- ast_mutex_unlock(&tpeer->lock);
- }
- return 0;
-}
-
-static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
-{
- aes_encrypt_key128(digest, ecx);
- aes_decrypt_key128(digest, dcx);
-}
-
-static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
-{
-#if 0
- /* Debug with "fake encryption" */
- int x;
- if (len % 16)
- ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
- for (x=0;x<len;x++)
- dst[x] = src[x] ^ 0xff;
-#else
- unsigned char lastblock[16] = { 0 };
- int x;
- while(len > 0) {
- aes_decrypt(src, dst, dcx);
- for (x=0;x<16;x++)
- dst[x] ^= lastblock[x];
- memcpy(lastblock, src, sizeof(lastblock));
- dst += 16;
- src += 16;
- len -= 16;
- }
-#endif
-}
-
-static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
-{
-#if 0
- /* Debug with "fake encryption" */
- int x;
- if (len % 16)
- ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
- for (x=0;x<len;x++)
- dst[x] = src[x] ^ 0xff;
-#else
- unsigned char curblock[16] = { 0 };
- int x;
- while(len > 0) {
- for (x=0;x<16;x++)
- curblock[x] ^= src[x];
- aes_encrypt(curblock, dst, ecx);
- memcpy(curblock, dst, sizeof(curblock));
- dst += 16;
- src += 16;
- len -= 16;
- }
-#endif
-}
-
-static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
-{
- int padding;
- unsigned char *workspace;
-
- workspace = alloca(*datalen);
- memset(f, 0, sizeof(*f));
- if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
- struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
- if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
- return -1;
- /* Decrypt */
- memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
-
- padding = 16 + (workspace[15] & 0xf);
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
- if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
- return -1;
-
- *datalen -= padding;
- memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
- f->frametype = fh->type;
- if (f->frametype == AST_FRAME_VIDEO) {
- f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
- } else {
- f->subclass = uncompress_subclass(fh->csub);
- }
- } else {
- struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
- if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
- return -1;
- /* Decrypt */
- memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
- padding = 16 + (workspace[15] & 0x0f);
- if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
- return -1;
- *datalen -= padding;
- memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
- }
- return 0;
-}
-
-static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
-{
- int padding;
- unsigned char *workspace;
- workspace = alloca(*datalen + 32);
- if (!workspace)
- return -1;
- if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
- struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
- padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
- padding = 16 + (padding & 0xf);
- memcpy(workspace, poo, padding);
- memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
- workspace[15] &= 0xf0;
- workspace[15] |= (padding & 0xf);
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
- *datalen += padding;
- memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
- if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
- memcpy(poo, workspace + *datalen - 32, 32);
- } else {
- struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
- padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
- padding = 16 + (padding & 0xf);
- memcpy(workspace, poo, padding);
- memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
- workspace[15] &= 0xf0;
- workspace[15] |= (padding & 0x0f);
- *datalen += padding;
- memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
- if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
- memcpy(poo, workspace + *datalen - 32, 32);
- }
- return 0;
-}
-
-static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
-{
- int res=-1;
- if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
- /* Search for possible keys, given secrets */
- struct MD5Context md5;
- unsigned char digest[16];
- char *tmppw, *stringp;
-
- tmppw = ast_strdupa(iaxs[callno]->secret);
- stringp = tmppw;
- while ((tmppw = strsep(&stringp, ";"))) {
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
- MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
- MD5Final(digest, &md5);
- build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
- res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
- if (!res) {
- ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
- break;
- }
- }
- } else
- res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
- return res;
-}
-
-static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
-{
- /* Queue a packet for delivery on a given private structure. Use "ts" for
- timestamp, or calculate if ts is 0. Send immediately without retransmission
- or delayed, with retransmission */
- struct ast_iax2_full_hdr *fh;
- struct ast_iax2_mini_hdr *mh;
- struct ast_iax2_video_hdr *vh;
- struct {
- struct iax_frame fr2;
- unsigned char buffer[4096];
- } frb;
- struct iax_frame *fr;
- int res;
- int sendmini=0;
- unsigned int lastsent;
- unsigned int fts;
-
- frb.fr2.afdatalen = sizeof(frb.buffer);
-
- if (!pvt) {
- ast_log(LOG_WARNING, "No private structure for packet?\n");
- return -1;
- }
-
- lastsent = pvt->lastsent;
-
- /* Calculate actual timestamp */
- fts = calc_timestamp(pvt, ts, f);
-
- /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
- * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
- * increment the "predicted timestamps" for voice, if we're predecting */
- if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
- return 0;
-
-
- if ((ast_test_flag(pvt, IAX_TRUNK) ||
- (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
- ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
- /* High two bytes are the same on timestamp, or sending on a trunk */ &&
- (f->frametype == AST_FRAME_VOICE)
- /* is a voice frame */ &&
- (f->subclass == pvt->svoiceformat)
- /* is the same type */ ) {
- /* Force immediate rather than delayed transmission */
- now = 1;
- /* Mark that mini-style frame is appropriate */
- sendmini = 1;
- }
- if ( f->frametype == AST_FRAME_VIDEO ) {
- /*
- * If the lower 15 bits of the timestamp roll over, or if
- * the video format changed then send a full frame.
- * Otherwise send a mini video frame
- */
- if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
- ((f->subclass & ~0x1) == pvt->svideoformat)
- ) {
- now = 1;
- sendmini = 1;
- } else {
- now = 0;
- sendmini = 0;
- }
- pvt->lastvsent = fts;
- }
- /* Allocate an iax_frame */
- if (now) {
- fr = &frb.fr2;
- } else
- fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
- if (!fr) {
- ast_log(LOG_WARNING, "Out of memory\n");
- return -1;
- }
- /* Copy our prospective frame into our immediate or retransmitted wrapper */
- iax_frame_wrap(fr, f);
-
- fr->ts = fts;
- fr->callno = pvt->callno;
- fr->transfer = transfer;
- fr->final = final;
- if (!sendmini) {
- /* We need a full frame */
- if (seqno > -1)
- fr->oseqno = seqno;
- else
- fr->oseqno = pvt->oseqno++;
- fr->iseqno = pvt->iseqno;
- fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
- fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
- fh->ts = htonl(fr->ts);
- fh->oseqno = fr->oseqno;
- if (transfer) {
- fh->iseqno = 0;
- } else
- fh->iseqno = fr->iseqno;
- /* Keep track of the last thing we've acknowledged */
- if (!transfer)
- pvt->aseqno = fr->iseqno;
- fh->type = fr->af.frametype & 0xFF;
- if (fr->af.frametype == AST_FRAME_VIDEO)
- fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
- else
- fh->csub = compress_subclass(fr->af.subclass);
- if (transfer) {
- fr->dcallno = pvt->transfercallno;
- } else
- fr->dcallno = pvt->peercallno;
- fh->dcallno = htons(fr->dcallno);
- fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
- fr->data = fh;
- fr->retries = 0;
- /* Retry after 2x the ping time has passed */
- fr->retrytime = pvt->pingtime * 2;
- if (fr->retrytime < MIN_RETRY_TIME)
- fr->retrytime = MIN_RETRY_TIME;
- if (fr->retrytime > MAX_RETRY_TIME)
- fr->retrytime = MAX_RETRY_TIME;
- /* Acks' don't get retried */
- if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
- fr->retries = -1;
- else if (f->frametype == AST_FRAME_VOICE)
- pvt->svoiceformat = f->subclass;
- else if (f->frametype == AST_FRAME_VIDEO)
- pvt->svideoformat = f->subclass & ~0x1;
- if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
- if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
- if (iaxdebug) {
- if (fr->transfer)
- iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
- else
- iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
- }
- encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
- } else
- ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
- }
-
- if (now) {
- res = send_packet(fr);
- } else
- res = iax2_transmit(fr);
- } else {
- if (ast_test_flag(pvt, IAX_TRUNK)) {
- iax2_trunk_queue(pvt, fr);
- res = 0;
- } else if (fr->af.frametype == AST_FRAME_VIDEO) {
- /* Video frame have no sequence number */
- fr->oseqno = -1;
- fr->iseqno = -1;
- vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
- vh->zeros = 0;
- vh->callno = htons(0x8000 | fr->callno);
- vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
- fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
- fr->data = vh;
- fr->retries = -1;
- res = send_packet(fr);
- } else {
- /* Mini-frames have no sequence number */
- fr->oseqno = -1;
- fr->iseqno = -1;
- /* Mini frame will do */
- mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
- mh->callno = htons(fr->callno);
- mh->ts = htons(fr->ts & 0xFFFF);
- fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
- fr->data = mh;
- fr->retries = -1;
- if (pvt->transferring == TRANSFER_MEDIAPASS)
- fr->transfer = 1;
- if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
- if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
- encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
- } else
- ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
- }
- res = send_packet(fr);
- }
- }
- return res;
-}
-
-static int iax2_show_users(int fd, int argc, char *argv[])
-{
- regex_t regexbuf;
- int havepattern = 0;
-
-#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
-#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
-
- struct iax2_user *user = NULL;
- char auth[90];
- char *pstr = "";
- struct ao2_iterator i;
-
- switch (argc) {
- case 5:
- if (!strcasecmp(argv[3], "like")) {
- if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = 1;
- } else
- return RESULT_SHOWUSAGE;
- case 3:
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
- ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
- i = ao2_iterator_init(users, 0);
- for (user = ao2_iterator_next(&i); user;
- user_unref(user), user = ao2_iterator_next(&i)) {
- if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
- continue;
-
- if (!ast_strlen_zero(user->secret)) {
- ast_copy_string(auth,user->secret,sizeof(auth));
- } else if (!ast_strlen_zero(user->inkeys)) {
- snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
- } else
- ast_copy_string(auth, "-no secret-", sizeof(auth));
-
- if(ast_test_flag(user,IAX_CODEC_NOCAP))
- pstr = "REQ Only";
- else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
- pstr = "Disabled";
- else
- pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
-
- ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
- user->contexts ? user->contexts->context : context,
- user->ha ? "Yes" : "No", pstr);
- }
-
- if (havepattern)
- regfree(&regexbuf);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
-{
- regex_t regexbuf;
- int havepattern = 0;
- int total_peers = 0;
- int online_peers = 0;
- int offline_peers = 0;
- int unmonitored_peers = 0;
- struct ao2_iterator i;
-
-#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
-#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
-
- struct iax2_peer *peer = NULL;
- char name[256];
- int registeredonly=0;
- char *term = manager ? "\r\n" : "\n";
-
- switch (argc) {
- case 6:
- if (!strcasecmp(argv[3], "registered"))
- registeredonly = 1;
- else
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[4], "like")) {
- if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = 1;
- } else
- return RESULT_SHOWUSAGE;
- break;
- case 5:
- if (!strcasecmp(argv[3], "like")) {
- if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = 1;
- } else
- return RESULT_SHOWUSAGE;
- break;
- case 4:
- if (!strcasecmp(argv[3], "registered"))
- registeredonly = 1;
- else
- return RESULT_SHOWUSAGE;
- break;
- case 3:
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
-
- if (s)
- astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
- else
- ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
-
- i = ao2_iterator_init(peers, 0);
- for (peer = ao2_iterator_next(&i); peer;
- peer_unref(peer), peer = ao2_iterator_next(&i)) {
- char nm[20];
- char status[20];
- char srch[2000];
- int retstatus;
-
- if (registeredonly && !peer->addr.sin_addr.s_addr)
- continue;
- if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
- continue;
-
- if (!ast_strlen_zero(peer->username))
- snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
- else
- ast_copy_string(name, peer->name, sizeof(name));
-
- retstatus = peer_status(peer, status, sizeof(status));
- if (retstatus > 0)
- online_peers++;
- else if (!retstatus)
- offline_peers++;
- else
- unmonitored_peers++;
-
- ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
-
- snprintf(srch, sizeof(srch), FORMAT, name,
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
- ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
- nm,
- ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
- peer->encmethods ? "(E)" : " ", status, term);
-
- if (s)
- astman_append(s, FORMAT, name,
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
- ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
- nm,
- ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
- peer->encmethods ? "(E)" : " ", status, term);
- else
- ast_cli(fd, FORMAT, name,
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
- ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
- nm,
- ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
- peer->encmethods ? "(E)" : " ", status, term);
- total_peers++;
- }
-
- if (s)
- astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
- else
- ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
-
- if (havepattern)
- regfree(&regexbuf);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int iax2_show_threads(int fd, int argc, char *argv[])
-{
- struct iax2_thread *thread = NULL;
- time_t t;
- int threadcount = 0, dynamiccount = 0;
- char type;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- ast_cli(fd, "IAX2 Thread Information\n");
- time(&t);
- ast_cli(fd, "Idle Threads:\n");
- AST_LIST_LOCK(&idle_list);
- AST_LIST_TRAVERSE(&idle_list, thread, list) {
-#ifdef DEBUG_SCHED_MULTITHREAD
- ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
- thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
-#else
- ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
- thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
-#endif
- threadcount++;
- }
- AST_LIST_UNLOCK(&idle_list);
- ast_cli(fd, "Active Threads:\n");
- AST_LIST_LOCK(&active_list);
- AST_LIST_TRAVERSE(&active_list, thread, list) {
- if (thread->type == IAX_TYPE_DYNAMIC)
- type = 'D';
- else
- type = 'P';
-#ifdef DEBUG_SCHED_MULTITHREAD
- ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
- type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
-#else
- ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
- type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
-#endif
- threadcount++;
- }
- AST_LIST_UNLOCK(&active_list);
- ast_cli(fd, "Dynamic Threads:\n");
- AST_LIST_LOCK(&dynamic_list);
- AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
-#ifdef DEBUG_SCHED_MULTITHREAD
- ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
- thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
-#else
- ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
- thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
-#endif
- dynamiccount++;
- }
- AST_LIST_UNLOCK(&dynamic_list);
- ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
- return RESULT_SUCCESS;
-}
-
-static int iax2_show_peers(int fd, int argc, char *argv[])
-{
- return __iax2_show_peers(0, fd, NULL, argc, argv);
-}
-static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
-{
- ast_cli_netstats(s, -1, 0);
- astman_append(s, "\r\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_show_firmware(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
-#if !defined(__FreeBSD__)
-#define FORMAT "%-15.15s %-15d %-15d\n"
-#else /* __FreeBSD__ */
-#define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */
-#endif /* __FreeBSD__ */
- struct iax_firmware *cur;
- if ((argc != 3) && (argc != 4))
- return RESULT_SHOWUSAGE;
- ast_mutex_lock(&waresl.lock);
-
- ast_cli(fd, FORMAT2, "Device", "Version", "Size");
- for (cur = waresl.wares;cur;cur = cur->next) {
- if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
- ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
- (int)ntohl(cur->fwh->datalen));
- }
- ast_mutex_unlock(&waresl.lock);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-/* JDG: callback to display iax peers in manager */
-static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
-{
- char *a[] = { "iax2", "show", "users" };
- int ret;
- const char *id = astman_get_header(m,"ActionID");
-
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n",id);
- ret = __iax2_show_peers(1, -1, s, 3, a );
- astman_append(s, "\r\n\r\n" );
- return ret;
-} /* /JDG */
-
-static char *regstate2str(int regstate)
-{
- switch(regstate) {
- case REG_STATE_UNREGISTERED:
- return "Unregistered";
- case REG_STATE_REGSENT:
- return "Request Sent";
- case REG_STATE_AUTHSENT:
- return "Auth. Sent";
- case REG_STATE_REGISTERED:
- return "Registered";
- case REG_STATE_REJECTED:
- return "Rejected";
- case REG_STATE_TIMEOUT:
- return "Timeout";
- case REG_STATE_NOAUTH:
- return "No Authentication";
- default:
- return "Unknown";
- }
-}
-
-static int iax2_show_registry(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
-#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
- struct iax2_registry *reg = NULL;
-
- char host[80];
- char perceived[80];
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
- AST_LIST_LOCK(&registrations);
- AST_LIST_TRAVERSE(&registrations, reg, entry) {
- snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
- if (reg->us.sin_addr.s_addr)
- snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
- else
- ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
- ast_cli(fd, FORMAT, host,
- (reg->dnsmgr) ? "Y" : "N",
- reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
- }
- AST_LIST_UNLOCK(&registrations);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int iax2_show_channels(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
-#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
-#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
- int x;
- int numchans = 0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
- for (x = 0; x < ARRAY_LEN(iaxs); x++) {
- ast_mutex_lock(&iaxsl[x]);
- if (iaxs[x]) {
- int lag, jitter, localdelay;
- jb_info jbinfo;
-
- if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
- jb_getinfo(iaxs[x]->jb, &jbinfo);
- jitter = jbinfo.jitter;
- localdelay = jbinfo.current - jbinfo.min;
- } else {
- jitter = -1;
- localdelay = 0;
- }
- lag = iaxs[x]->remote_rr.delay;
- ast_cli(fd, FORMAT,
- iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
- ast_inet_ntoa(iaxs[x]->addr.sin_addr),
- S_OR(iaxs[x]->username, "(None)"),
- iaxs[x]->callno, iaxs[x]->peercallno,
- iaxs[x]->oseqno, iaxs[x]->iseqno,
- lag,
- jitter,
- localdelay,
- ast_getformatname(iaxs[x]->voiceformat) );
- numchans++;
- }
- ast_mutex_unlock(&iaxsl[x]);
- }
- ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-#undef FORMATB
-}
-
-static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
-{
- int x;
- int numchans = 0;
- for (x = 0; x < ARRAY_LEN(iaxs); x++) {
- ast_mutex_lock(&iaxsl[x]);
- if (iaxs[x]) {
- int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
- char *fmt;
- jb_info jbinfo;
-
- if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
- jb_getinfo(iaxs[x]->jb, &jbinfo);
- localjitter = jbinfo.jitter;
- localdelay = jbinfo.current - jbinfo.min;
- locallost = jbinfo.frames_lost;
- locallosspct = jbinfo.losspct/1000;
- localdropped = jbinfo.frames_dropped;
- localooo = jbinfo.frames_ooo;
- } else {
- localjitter = -1;
- localdelay = 0;
- locallost = -1;
- locallosspct = -1;
- localdropped = 0;
- localooo = -1;
- }
- if (limit_fmt)
- fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
- else
- fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
- if (s)
-
- astman_append(s, fmt,
- iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
- iaxs[x]->pingtime,
- localjitter,
- localdelay,
- locallost,
- locallosspct,
- localdropped,
- localooo,
- iaxs[x]->frames_received/1000,
- iaxs[x]->remote_rr.jitter,
- iaxs[x]->remote_rr.delay,
- iaxs[x]->remote_rr.losscnt,
- iaxs[x]->remote_rr.losspct,
- iaxs[x]->remote_rr.dropped,
- iaxs[x]->remote_rr.ooo,
- iaxs[x]->remote_rr.packets/1000);
- else
- ast_cli(fd, fmt,
- iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
- iaxs[x]->pingtime,
- localjitter,
- localdelay,
- locallost,
- locallosspct,
- localdropped,
- localooo,
- iaxs[x]->frames_received/1000,
- iaxs[x]->remote_rr.jitter,
- iaxs[x]->remote_rr.delay,
- iaxs[x]->remote_rr.losscnt,
- iaxs[x]->remote_rr.losspct,
- iaxs[x]->remote_rr.dropped,
- iaxs[x]->remote_rr.ooo,
- iaxs[x]->remote_rr.packets/1000
- );
- numchans++;
- }
- ast_mutex_unlock(&iaxsl[x]);
- }
- return numchans;
-}
-
-static int iax2_show_netstats(int fd, int argc, char *argv[])
-{
- int numchans = 0;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
- ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
- numchans = ast_cli_netstats(NULL, fd, 1);
- ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
- return RESULT_SUCCESS;
-}
-
-static int iax2_do_debug(int fd, int argc, char *argv[])
-{
- if (argc < 2 || argc > 3)
- return RESULT_SHOWUSAGE;
- iaxdebug = 1;
- ast_cli(fd, "IAX2 Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
-{
- if (argc < 3 || argc > 4)
- return RESULT_SHOWUSAGE;
- iaxtrunkdebug = 1;
- ast_cli(fd, "IAX2 Trunk Debug Requested\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_do_jb_debug(int fd, int argc, char *argv[])
-{
- if (argc < 3 || argc > 4)
- return RESULT_SHOWUSAGE;
- jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
- ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_no_debug(int fd, int argc, char *argv[])
-{
- if (argc < 3 || argc > 4)
- return RESULT_SHOWUSAGE;
- iaxdebug = 0;
- ast_cli(fd, "IAX2 Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
-{
- if (argc < 4 || argc > 5)
- return RESULT_SHOWUSAGE;
- iaxtrunkdebug = 0;
- ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_no_jb_debug(int fd, int argc, char *argv[])
-{
- if (argc < 4 || argc > 5)
- return RESULT_SHOWUSAGE;
- jb_setoutput(jb_error_output, jb_warning_output, NULL);
- jb_debug_output("\n");
- ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int iax2_write(struct ast_channel *c, struct ast_frame *f)
-{
- unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
- int res = -1;
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno]) {
- /* If there's an outstanding error, return failure now */
- if (!iaxs[callno]->error) {
- if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
- res = 0;
- /* Don't waste bandwidth sending null frames */
- else if (f->frametype == AST_FRAME_NULL)
- res = 0;
- else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
- res = 0;
- else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
- res = 0;
- else
- /* Simple, just queue for transmission */
- res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
- }
- }
- /* If it's already gone, just return */
- ast_mutex_unlock(&iaxsl[callno]);
- return res;
-}
-
-static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
- int now, int transfer, int final)
-{
- struct ast_frame f = { 0, };
-
- f.frametype = type;
- f.subclass = command;
- f.datalen = datalen;
- f.src = __FUNCTION__;
- f.data = (void *) data;
-
- return iax2_send(i, &f, ts, seqno, now, transfer, final);
-}
-
-static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
-{
- return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
-}
-
-static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
-{
- int res;
- ast_mutex_lock(&iaxsl[callno]);
- res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
- ast_mutex_unlock(&iaxsl[callno]);
- return res;
-}
-
-/*!
- * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
- * the pvt struct for the given call number may disappear during its
- * execution.
- */
-static int send_command_final(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
-{
- int call_num = i->callno;
- /* It is assumed that the callno has already been locked */
- iax2_predestroy(i->callno);
- if (!iaxs[call_num])
- return -1;
- return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
-}
-
-static int send_command_immediate(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
-{
- return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
-}
-
-static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
-{
- return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
-}
-
-static int apply_context(struct iax2_context *con, const char *context)
-{
- while(con) {
- if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
- return -1;
- con = con->next;
- }
- return 0;
-}
-
-
-static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
-{
- /* Start pessimistic */
- int res = -1;
- int version = 2;
- struct iax2_user *user = NULL, *best = NULL;
- int bestscore = 0;
- int gotcapability = 0;
- struct ast_variable *v = NULL, *tmpvar = NULL;
- struct ao2_iterator i;
-
- if (!iaxs[callno])
- return res;
- if (ies->called_number)
- ast_string_field_set(iaxs[callno], exten, ies->called_number);
- if (ies->calling_number) {
- ast_shrink_phone_number(ies->calling_number);
- ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
- }
- if (ies->calling_name)
- ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
- if (ies->calling_ani)
- ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
- if (ies->dnid)
- ast_string_field_set(iaxs[callno], dnid, ies->dnid);
- if (ies->rdnis)
- ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
- if (ies->called_context)
- ast_string_field_set(iaxs[callno], context, ies->called_context);
- if (ies->language)
- ast_string_field_set(iaxs[callno], language, ies->language);
- if (ies->username)
- ast_string_field_set(iaxs[callno], username, ies->username);
- if (ies->calling_ton > -1)
- iaxs[callno]->calling_ton = ies->calling_ton;
- if (ies->calling_tns > -1)
- iaxs[callno]->calling_tns = ies->calling_tns;
- if (ies->calling_pres > -1)
- iaxs[callno]->calling_pres = ies->calling_pres;
- if (ies->format)
- iaxs[callno]->peerformat = ies->format;
- if (ies->adsicpe)
- iaxs[callno]->peeradsicpe = ies->adsicpe;
- if (ies->capability) {
- gotcapability = 1;
- iaxs[callno]->peercapability = ies->capability;
- }
- if (ies->version)
- version = ies->version;
-
- /* Use provided preferences until told otherwise for actual preferences */
- if(ies->codec_prefs) {
- ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
- ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
- }
-
- if (!gotcapability)
- iaxs[callno]->peercapability = iaxs[callno]->peerformat;
- if (version > IAX_PROTO_VERSION) {
- ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
- ast_inet_ntoa(sin->sin_addr), version);
- return res;
- }
- /* Search the userlist for a compatible entry, and fill in the rest */
- i = ao2_iterator_init(users, 0);
- while ((user = ao2_iterator_next(&i))) {
- if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */
- !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
- && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */
- && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */
- apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
- if (!ast_strlen_zero(iaxs[callno]->username)) {
- /* Exact match, stop right now. */
- if (best)
- user_unref(best);
- best = user;
- break;
- } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
- /* No required authentication */
- if (user->ha) {
- /* There was host authentication and we passed, bonus! */
- if (bestscore < 4) {
- bestscore = 4;
- if (best)
- user_unref(best);
- best = user;
- continue;
- }
- } else {
- /* No host access, but no secret, either, not bad */
- if (bestscore < 3) {
- bestscore = 3;
- if (best)
- user_unref(best);
- best = user;
- continue;
- }
- }
- } else {
- if (user->ha) {
- /* Authentication, but host access too, eh, it's something.. */
- if (bestscore < 2) {
- bestscore = 2;
- if (best)
- user_unref(best);
- best = user;
- continue;
- }
- } else {
- /* Authentication and no host access... This is our baseline */
- if (bestscore < 1) {
- bestscore = 1;
- if (best)
- user_unref(best);
- best = user;
- continue;
- }
- }
- }
- }
- user_unref(user);
- }
- user = best;
- if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
- user = realtime_user(iaxs[callno]->username, sin);
- if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */
- !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */
- user = user_unref(user);
- }
- }
- if (user) {
- /* We found our match (use the first) */
- /* copy vars */
- for (v = user->vars ; v ; v = v->next) {
- if((tmpvar = ast_variable_new(v->name, v->value))) {
- tmpvar->next = iaxs[callno]->vars;
- iaxs[callno]->vars = tmpvar;
- }
- }
- /* If a max AUTHREQ restriction is in place, activate it */
- if (user->maxauthreq > 0)
- ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
- iaxs[callno]->prefs = user->prefs;
- ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
- ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
- ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
- iaxs[callno]->encmethods = user->encmethods;
- /* Store the requested username if not specified */
- if (ast_strlen_zero(iaxs[callno]->username))
- ast_string_field_set(iaxs[callno], username, user->name);
- /* Store whether this is a trunked call, too, of course, and move if appropriate */
- ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
- iaxs[callno]->capability = user->capability;
- /* And use the default context */
- if (ast_strlen_zero(iaxs[callno]->context)) {
- if (user->contexts)
- ast_string_field_set(iaxs[callno], context, user->contexts->context);
- else
- ast_string_field_set(iaxs[callno], context, context);
- }
- /* And any input keys */
- ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
- /* And the permitted authentication methods */
- iaxs[callno]->authmethods = user->authmethods;
- iaxs[callno]->adsi = user->adsi;
- /* If they have callerid, override the given caller id. Always store the ANI */
- if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
- if (ast_test_flag(user, IAX_HASCALLERID)) {
- iaxs[callno]->calling_tns = 0;
- iaxs[callno]->calling_ton = 0;
- ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
- ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
- iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
- }
- if (ast_strlen_zero(iaxs[callno]->ani))
- ast_string_field_set(iaxs[callno], ani, user->cid_num);
- } else {
- iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
- }
- if (!ast_strlen_zero(user->accountcode))
- ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
- if (!ast_strlen_zero(user->mohinterpret))
- ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
- if (!ast_strlen_zero(user->mohsuggest))
- ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
- if (user->amaflags)
- iaxs[callno]->amaflags = user->amaflags;
- if (!ast_strlen_zero(user->language))
- ast_string_field_set(iaxs[callno], language, user->language);
- ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
- /* Keep this check last */
- if (!ast_strlen_zero(user->dbsecret)) {
- char *family, *key=NULL;
- char buf[80];
- family = ast_strdupa(user->dbsecret);
- key = strchr(family, '/');
- if (key) {
- *key = '\0';
- key++;
- }
- if (!key || ast_db_get(family, key, buf, sizeof(buf)))
- ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
- else
- ast_string_field_set(iaxs[callno], secret, buf);
- } else
- ast_string_field_set(iaxs[callno], secret, user->secret);
- res = 0;
- user = user_unref(user);
- }
- ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
- return res;
-}
-
-static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
-{
- struct ast_iax2_full_hdr fh;
- fh.scallno = htons(src | IAX_FLAG_FULL);
- fh.dcallno = htons(dst);
- fh.ts = 0;
- fh.oseqno = 0;
- fh.iseqno = 0;
- fh.type = AST_FRAME_IAX;
- fh.csub = compress_subclass(IAX_COMMAND_INVAL);
- if (iaxdebug)
- iax_showframe(NULL, &fh, 0, sin, 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
- return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
-}
-
-static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
-{
- /* Select exactly one common encryption if there are any */
- p->encmethods &= enc;
- if (p->encmethods) {
- if (p->encmethods & IAX_ENCRYPT_AES128)
- p->encmethods = IAX_ENCRYPT_AES128;
- else
- p->encmethods = 0;
- }
-}
-
-/*!
- * \pre iaxsl[call_num] is locked
- *
- * \note Since this function calls send_command_final(), the pvt struct for the given
- * call number may disappear while executing this function.
- */
-static int authenticate_request(int call_num)
-{
- struct iax_ie_data ied;
- int res = -1, authreq_restrict = 0;
- char challenge[10];
- struct chan_iax2_pvt *p = iaxs[call_num];
-
- memset(&ied, 0, sizeof(ied));
-
- /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
- if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
- struct iax2_user *user, tmp_user = {
- .name = p->username,
- };
-
- user = ao2_find(users, &tmp_user, OBJ_POINTER);
- if (user) {
- if (user->curauthreq == user->maxauthreq)
- authreq_restrict = 1;
- else
- user->curauthreq++;
- user = user_unref(user);
- }
- }
-
- /* If the AUTHREQ limit test failed, send back an error */
- if (authreq_restrict) {
- iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
- iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
- send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
- return 0;
- }
-
- iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
- if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
- snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
- ast_string_field_set(p, challenge, challenge);
- /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
- iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
- }
- if (p->encmethods)
- iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
-
- iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
-
- res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
-
- if (p->encmethods)
- ast_set_flag(p, IAX_ENCRYPTED);
-
- return res;
-}
-
-static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
-{
- char requeststr[256];
- char md5secret[256] = "";
- char secret[256] = "";
- char rsasecret[256] = "";
- int res = -1;
- int x;
- struct iax2_user *user, tmp_user = {
- .name = p->username,
- };
-
- user = ao2_find(users, &tmp_user, OBJ_POINTER);
- if (user) {
- if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
- ast_atomic_fetchadd_int(&user->curauthreq, -1);
- ast_clear_flag(p, IAX_MAXAUTHREQ);
- }
- ast_string_field_set(p, host, user->name);
- user = user_unref(user);
- }
-
- if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
- return res;
- if (ies->password)
- ast_copy_string(secret, ies->password, sizeof(secret));
- if (ies->md5_result)
- ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
- if (ies->rsa_result)
- ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
- if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
- struct ast_key *key;
- char *keyn;
- char tmpkey[256];
- char *stringp=NULL;
- ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
- stringp=tmpkey;
- keyn = strsep(&stringp, ":");
- while(keyn) {
- key = ast_key_get(keyn, AST_KEY_PUBLIC);
- if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
- res = 0;
- break;
- } else if (!key)
- ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
- keyn = strsep(&stringp, ":");
- }
- } else if (p->authmethods & IAX_AUTH_MD5) {
- struct MD5Context md5;
- unsigned char digest[16];
- char *tmppw, *stringp;
-
- tmppw = ast_strdupa(p->secret);
- stringp = tmppw;
- while((tmppw = strsep(&stringp, ";"))) {
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
- MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
- MD5Final(digest, &md5);
- /* If they support md5, authenticate with it. */
- for (x=0;x<16;x++)
- sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
- if (!strcasecmp(requeststr, md5secret)) {
- res = 0;
- break;
- }
- }
- } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
- if (!strcmp(secret, p->secret))
- res = 0;
- }
- return res;
-}
-
-/*! \brief Verify inbound registration */
-static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
-{
- char requeststr[256] = "";
- char peer[256] = "";
- char md5secret[256] = "";
- char rsasecret[256] = "";
- char secret[256] = "";
- struct iax2_peer *p = NULL;
- struct ast_key *key;
- char *keyn;
- int x;
- int expire = 0;
- int res = -1;
-
- ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
- /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
- if (ies->username)
- ast_copy_string(peer, ies->username, sizeof(peer));
- if (ies->password)
- ast_copy_string(secret, ies->password, sizeof(secret));
- if (ies->md5_result)
- ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
- if (ies->rsa_result)
- ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
- if (ies->refresh)
- expire = ies->refresh;
-
- if (ast_strlen_zero(peer)) {
- ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
- return -1;
- }
-
- /* SLD: first call to lookup peer during registration */
- ast_mutex_unlock(&iaxsl[callno]);
- p = find_peer(peer, 1);
- ast_mutex_lock(&iaxsl[callno]);
- if (!p || !iaxs[callno]) {
- if (authdebug && !p)
- ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
- goto return_unref;
- }
-
- if (!ast_test_flag(p, IAX_DYNAMIC)) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
- goto return_unref;
- }
-
- if (!ast_apply_ha(p->ha, sin)) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
- goto return_unref;
- }
- if (!inaddrcmp(&p->addr, sin))
- ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
- ast_string_field_set(iaxs[callno], secret, p->secret);
- ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
- /* Check secret against what we have on file */
- if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
- if (!ast_strlen_zero(p->inkeys)) {
- char tmpkeys[256];
- char *stringp=NULL;
- ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
- stringp=tmpkeys;
- keyn = strsep(&stringp, ":");
- while(keyn) {
- key = ast_key_get(keyn, AST_KEY_PUBLIC);
- if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
- ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
- break;
- } else if (!key)
- ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
- keyn = strsep(&stringp, ":");
- }
- if (!keyn) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
- goto return_unref;
- }
- } else {
- if (authdebug)
- ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
- goto return_unref;
- }
- } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
- struct MD5Context md5;
- unsigned char digest[16];
- char *tmppw, *stringp;
-
- tmppw = ast_strdupa(p->secret);
- stringp = tmppw;
- while((tmppw = strsep(&stringp, ";"))) {
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
- MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
- MD5Final(digest, &md5);
- for (x=0;x<16;x++)
- sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
- if (!strcasecmp(requeststr, md5secret))
- break;
- }
- if (tmppw) {
- ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
- } else {
- if (authdebug)
- ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
- goto return_unref;
- }
- } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
- /* They've provided a plain text password and we support that */
- if (strcmp(secret, p->secret)) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
- goto return_unref;
- } else
- ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
- } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
- goto return_unref;
- }
- ast_string_field_set(iaxs[callno], peer, peer);
- /* Choose lowest expiry number */
- if (expire && (expire < iaxs[callno]->expiry))
- iaxs[callno]->expiry = expire;
-
- ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
-
- res = 0;
-
-return_unref:
- if (p)
- peer_unref(p);
-
- return res;
-}
-
-static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
-{
- int res = -1;
- int x;
- if (!ast_strlen_zero(keyn)) {
- if (!(authmethods & IAX_AUTH_RSA)) {
- if (ast_strlen_zero(secret))
- ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
- } else if (ast_strlen_zero(challenge)) {
- ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
- } else {
- char sig[256];
- struct ast_key *key;
- key = ast_key_get(keyn, AST_KEY_PRIVATE);
- if (!key) {
- ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
- } else {
- if (ast_sign(key, (char*)challenge, sig)) {
- ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
- res = -1;
- } else {
- iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
- res = 0;
- }
- }
- }
- }
- /* Fall back */
- if (res && !ast_strlen_zero(secret)) {
- if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
- struct MD5Context md5;
- unsigned char digest[16];
- char digres[128];
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
- MD5Update(&md5, (unsigned char *)secret, strlen(secret));
- MD5Final(digest, &md5);
- /* If they support md5, authenticate with it. */
- for (x=0;x<16;x++)
- sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */
- if (ecx && dcx)
- build_enc_keys(digest, ecx, dcx);
- iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
- res = 0;
- } else if (authmethods & IAX_AUTH_PLAINTEXT) {
- iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
- res = 0;
- } else
- ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
- }
- return res;
-}
-
-/*!
- * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
- * so do not call this function with a pvt lock held.
- */
-static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
-{
- struct iax2_peer *peer = NULL;
- /* Start pessimistic */
- int res = -1;
- int authmethods = 0;
- struct iax_ie_data ied;
- uint16_t callno = p->callno;
-
- memset(&ied, 0, sizeof(ied));
-
- if (ies->username)
- ast_string_field_set(p, username, ies->username);
- if (ies->challenge)
- ast_string_field_set(p, challenge, ies->challenge);
- if (ies->authmethods)
- authmethods = ies->authmethods;
- if (authmethods & IAX_AUTH_MD5)
- merge_encryption(p, ies->encmethods);
- else
- p->encmethods = 0;
-
- /* Check for override RSA authentication first */
- if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
- /* Normal password authentication */
- res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
- } else {
- struct ao2_iterator i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
- if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
- /* No peer specified at our end, or this is the peer */
- && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
- /* No username specified in peer rule, or this is the right username */
- && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr)))
- /* No specified host, or this is our host */
- ) {
- res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
- if (!res) {
- peer_unref(peer);
- break;
- }
- }
- peer_unref(peer);
- }
- if (!peer) {
- /* We checked our list and didn't find one. It's unlikely, but possible,
- that we're trying to authenticate *to* a realtime peer */
- const char *peer_name = ast_strdupa(p->peer);
- ast_mutex_unlock(&iaxsl[callno]);
- if ((peer = realtime_peer(peer_name, NULL))) {
- ast_mutex_lock(&iaxsl[callno]);
- if (!(p = iaxs[callno])) {
- peer_unref(peer);
- return -1;
- }
- res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
- peer_unref(peer);
- }
- if (!peer) {
- ast_mutex_lock(&iaxsl[callno]);
- if (!(p = iaxs[callno]))
- return -1;
- }
- }
- }
- if (ies->encmethods)
- ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
- if (!res)
- res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
- return res;
-}
-
-static int iax2_do_register(struct iax2_registry *reg);
-
-static void __iax2_do_register_s(const void *data)
-{
- struct iax2_registry *reg = (struct iax2_registry *)data;
- reg->expire = -1;
- iax2_do_register(reg);
-}
-
-static int iax2_do_register_s(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__iax2_do_register_s, data))
-#endif
- __iax2_do_register_s(data);
- return 0;
-}
-
-static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
-{
- int newcall = 0;
- char newip[256];
- struct iax_ie_data ied;
- struct sockaddr_in new;
-
-
- memset(&ied, 0, sizeof(ied));
- if (ies->apparent_addr)
- bcopy(ies->apparent_addr, &new, sizeof(new));
- if (ies->callno)
- newcall = ies->callno;
- if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
- ast_log(LOG_WARNING, "Invalid transfer request\n");
- return -1;
- }
- pvt->transfercallno = newcall;
- memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
- inet_aton(newip, &pvt->transfer.sin_addr);
- pvt->transfer.sin_family = AF_INET;
- pvt->transferring = TRANSFER_BEGIN;
- pvt->transferid = ies->transferid;
- if (ies->transferid)
- iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
- send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
- return 0;
-}
-
-static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
-{
- char exten[256] = "";
- int status = CACHE_FLAG_UNKNOWN;
- int expiry = iaxdefaultdpcache;
- int x;
- int matchmore = 0;
- struct iax2_dpcache *dp, *prev;
-
- if (ies->called_number)
- ast_copy_string(exten, ies->called_number, sizeof(exten));
-
- if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
- status = CACHE_FLAG_EXISTS;
- else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
- status = CACHE_FLAG_CANEXIST;
- else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
- status = CACHE_FLAG_NONEXISTENT;
-
- if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
- /* Don't really do anything with this */
- }
- if (ies->refresh)
- expiry = ies->refresh;
- if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
- matchmore = CACHE_FLAG_MATCHMORE;
- ast_mutex_lock(&dpcache_lock);
- prev = NULL;
- dp = pvt->dpentries;
- while(dp) {
- if (!strcmp(dp->exten, exten)) {
- /* Let them go */
- if (prev)
- prev->peer = dp->peer;
- else
- pvt->dpentries = dp->peer;
- dp->peer = NULL;
- dp->callno = 0;
- dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
- if (dp->flags & CACHE_FLAG_PENDING) {
- dp->flags &= ~CACHE_FLAG_PENDING;
- dp->flags |= status;
- dp->flags |= matchmore;
- }
- /* Wake up waiters */
- for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
- if (dp->waiters[x] > -1)
- write(dp->waiters[x], "asdf", 4);
- }
- prev = dp;
- dp = dp->peer;
- }
- ast_mutex_unlock(&dpcache_lock);
- return 0;
-}
-
-static int complete_transfer(int callno, struct iax_ies *ies)
-{
- int peercallno = 0;
- struct chan_iax2_pvt *pvt = iaxs[callno];
- struct iax_frame *cur;
- jb_frame frame;
-
- if (ies->callno)
- peercallno = ies->callno;
-
- if (peercallno < 1) {
- ast_log(LOG_WARNING, "Invalid transfer request\n");
- return -1;
- }
- memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
- memset(&pvt->transfer, 0, sizeof(pvt->transfer));
- /* Reset sequence numbers */
- pvt->oseqno = 0;
- pvt->rseqno = 0;
- pvt->iseqno = 0;
- pvt->aseqno = 0;
-
- if (pvt->peercallno) {
- remove_by_peercallno(pvt);
- }
- pvt->peercallno = peercallno;
- store_by_peercallno(pvt);
-
- pvt->transferring = TRANSFER_NONE;
- pvt->svoiceformat = -1;
- pvt->voiceformat = 0;
- pvt->svideoformat = -1;
- pvt->videoformat = 0;
- pvt->transfercallno = -1;
- memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
- memset(&pvt->offset, 0, sizeof(pvt->offset));
- /* reset jitterbuffer */
- while(jb_getall(pvt->jb,&frame) == JB_OK)
- iax2_frame_free(frame.data);
- jb_reset(pvt->jb);
- pvt->lag = 0;
- pvt->last = 0;
- pvt->lastsent = 0;
- pvt->nextpred = 0;
- pvt->pingtime = DEFAULT_RETRY_TIME;
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
- /* We must cancel any packets that would have been transmitted
- because now we're talking to someone new. It's okay, they
- were transmitted to someone that didn't care anyway. */
- if (callno == cur->callno)
- cur->retries = -1;
- }
- AST_LIST_UNLOCK(&iaxq.queue);
- return 0;
-}
-
-/*! \brief Acknowledgment received for OUR registration */
-static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
-{
- struct iax2_registry *reg;
- /* Start pessimistic */
- char peer[256] = "";
- char msgstatus[60];
- int refresh = 60;
- char ourip[256] = "<Unspecified>";
- struct sockaddr_in oldus;
- struct sockaddr_in us;
- int oldmsgs;
-
- memset(&us, 0, sizeof(us));
- if (ies->apparent_addr)
- bcopy(ies->apparent_addr, &us, sizeof(us));
- if (ies->username)
- ast_copy_string(peer, ies->username, sizeof(peer));
- if (ies->refresh)
- refresh = ies->refresh;
- if (ies->calling_number) {
- /* We don't do anything with it really, but maybe we should */
- }
- reg = iaxs[callno]->reg;
- if (!reg) {
- ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
- return -1;
- }
- memcpy(&oldus, &reg->us, sizeof(oldus));
- oldmsgs = reg->messages;
- if (inaddrcmp(&reg->addr, sin)) {
- ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
- return -1;
- }
- memcpy(&reg->us, &us, sizeof(reg->us));
- if (ies->msgcount >= 0)
- reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */
- /* always refresh the registration at the interval requested by the server
- we are registering to
- */
- reg->refresh = refresh;
- AST_SCHED_DEL(sched, reg->expire);
- reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
- if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
- if (option_verbose > 2) {
- if (reg->messages > 255)
- snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
- else if (reg->messages > 1)
- snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
- else if (reg->messages > 0)
- snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
- else
- snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
- snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
- ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
- }
- manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
- }
- reg->regstate = REG_STATE_REGISTERED;
- return 0;
-}
-
-static int iax2_register(char *value, int lineno)
-{
- struct iax2_registry *reg;
- char copy[256];
- char *username, *hostname, *secret;
- char *porta;
- char *stringp=NULL;
-
- if (!value)
- return -1;
- ast_copy_string(copy, value, sizeof(copy));
- stringp=copy;
- username = strsep(&stringp, "@");
- hostname = strsep(&stringp, "@");
- if (!hostname) {
- ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
- return -1;
- }
- stringp=username;
- username = strsep(&stringp, ":");
- secret = strsep(&stringp, ":");
- stringp=hostname;
- hostname = strsep(&stringp, ":");
- porta = strsep(&stringp, ":");
-
- if (porta && !atoi(porta)) {
- ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
- return -1;
- }
- if (!(reg = ast_calloc(1, sizeof(*reg))))
- return -1;
- if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
- free(reg);
- return -1;
- }
- ast_copy_string(reg->username, username, sizeof(reg->username));
- if (secret)
- ast_copy_string(reg->secret, secret, sizeof(reg->secret));
- reg->expire = -1;
- reg->refresh = IAX_DEFAULT_REG_EXPIRE;
- reg->addr.sin_family = AF_INET;
- reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
- AST_LIST_LOCK(&registrations);
- AST_LIST_INSERT_HEAD(&registrations, reg, entry);
- AST_LIST_UNLOCK(&registrations);
-
- return 0;
-}
-
-static void register_peer_exten(struct iax2_peer *peer, int onoff)
-{
- char multi[256];
- char *stringp, *ext;
- if (!ast_strlen_zero(regcontext)) {
- ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
- stringp = multi;
- while((ext = strsep(&stringp, "&"))) {
- if (onoff) {
- if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
- ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
- "Noop", ast_strdup(peer->name), ast_free, "IAX2");
- } else
- ast_context_remove_extension(regcontext, ext, 1, NULL);
- }
- }
-}
-static void prune_peers(void);
-
-static void unlink_peer(struct iax2_peer *peer)
-{
- if (peer->expire > -1) {
- if (!ast_sched_del(sched, peer->expire)) {
- peer->expire = -1;
- peer_unref(peer);
- }
- }
-
- if (peer->pokeexpire > -1) {
- if (!ast_sched_del(sched, peer->pokeexpire)) {
- peer->pokeexpire = -1;
- peer_unref(peer);
- }
- }
-
- ao2_unlink(peers, peer);
-}
-
-static void __expire_registry(const void *data)
-{
- struct iax2_peer *peer = (struct iax2_peer *) data;
-
- if (!peer)
- return;
-
- peer->expire = -1;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
- if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
- realtime_update_peer(peer->name, &peer->addr, 0);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
- /* Reset the address */
- memset(&peer->addr, 0, sizeof(peer->addr));
- /* Reset expiry value */
- peer->expiry = min_reg_expire;
- if (!ast_test_flag(peer, IAX_TEMPONLY))
- ast_db_del("IAX/Registry", peer->name);
- register_peer_exten(peer, 0);
- ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
- if (iax2_regfunk)
- iax2_regfunk(peer->name, 0);
-
- if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
- unlink_peer(peer);
-
- peer_unref(peer);
-}
-
-static int expire_registry(const void *data)
-{
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__expire_registry, data))
-#endif
- __expire_registry(data);
- return 0;
-}
-
-static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
-
-static void reg_source_db(struct iax2_peer *p)
-{
- char data[80];
- struct in_addr in;
- char *c, *d;
- if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
- c = strchr(data, ':');
- if (c) {
- *c = '\0';
- c++;
- if (inet_aton(data, &in)) {
- d = strchr(c, ':');
- if (d) {
- *d = '\0';
- d++;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
- ast_inet_ntoa(in), atoi(c), atoi(d));
- iax2_poke_peer(p, 0);
- p->expiry = atoi(d);
- memset(&p->addr, 0, sizeof(p->addr));
- p->addr.sin_family = AF_INET;
- p->addr.sin_addr = in;
- p->addr.sin_port = htons(atoi(c));
- if (p->expire > -1) {
- if (!ast_sched_del(sched, p->expire)) {
- p->expire = -1;
- peer_unref(p);
- }
- }
- ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
- p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
- if (p->expire == -1)
- peer_unref(p);
- if (iax2_regfunk)
- iax2_regfunk(p->name, 1);
- register_peer_exten(p, 1);
- }
-
- }
- }
- }
-}
-
-/*!
- * \pre iaxsl[callno] is locked
- *
- * \note Since this function calls send_command_final(), the pvt struct for
- * the given call number may disappear while executing this function.
- */
-static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
-{
- /* Called from IAX thread only, with proper iaxsl lock */
- struct iax_ie_data ied;
- struct iax2_peer *p;
- int msgcount;
- char data[80];
- int version;
- const char *peer_name;
- int res = -1;
-
- memset(&ied, 0, sizeof(ied));
-
- peer_name = ast_strdupa(iaxs[callno]->peer);
-
- /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
- ast_mutex_unlock(&iaxsl[callno]);
- if (!(p = find_peer(peer_name, 1))) {
- ast_mutex_lock(&iaxsl[callno]);
- ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
- return -1;
- }
- ast_mutex_lock(&iaxsl[callno]);
- if (!iaxs[callno])
- goto return_unref;
-
- if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
- if (sin->sin_addr.s_addr) {
- time_t nowtime;
- time(&nowtime);
- realtime_update_peer(peer_name, sin, nowtime);
- } else {
- realtime_update_peer(peer_name, sin, 0);
- }
- }
- if (inaddrcmp(&p->addr, sin)) {
- if (iax2_regfunk)
- iax2_regfunk(p->name, 1);
- /* Stash the IP address from which they registered */
- memcpy(&p->addr, sin, sizeof(p->addr));
- snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
- if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
- ast_db_put("IAX/Registry", p->name, data);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
- ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
- register_peer_exten(p, 1);
- ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
- } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
- ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
- register_peer_exten(p, 0);
- ast_db_del("IAX/Registry", p->name);
- ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
- }
- /* Update the host */
- /* Verify that the host is really there */
- iax2_poke_peer(p, callno);
- }
-
- /* Make sure our call still exists, an INVAL at the right point may make it go away */
- if (!iaxs[callno]) {
- res = 0;
- goto return_unref;
- }
-
- /* Store socket fd */
- p->sockfd = fd;
- /* Setup the expiry */
- if (p->expire > -1) {
- if (!ast_sched_del(sched, p->expire)) {
- p->expire = -1;
- peer_unref(p);
- }
- }
- /* treat an unspecified refresh interval as the minimum */
- if (!refresh)
- refresh = min_reg_expire;
- if (refresh > max_reg_expire) {
- ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
- p->name, max_reg_expire, refresh);
- p->expiry = max_reg_expire;
- } else if (refresh < min_reg_expire) {
- ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
- p->name, min_reg_expire, refresh);
- p->expiry = min_reg_expire;
- } else {
- p->expiry = refresh;
- }
- if (p->expiry && sin->sin_addr.s_addr) {
- p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
- if (p->expire == -1)
- peer_unref(p);
- }
- iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
- iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
- if (sin->sin_addr.s_addr) {
- iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
- iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
- if (!ast_strlen_zero(p->mailbox)) {
- int new, old;
- ast_app_inboxcount(p->mailbox, &new, &old);
- if (new > 255)
- new = 255;
- if (old > 255)
- old = 255;
- msgcount = (old << 8) | new;
- iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
- }
- if (ast_test_flag(p, IAX_HASCALLERID)) {
- iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
- iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
- }
- }
- version = iax_check_version(devtype);
- if (version)
- iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
-
- res = 0;
-
-return_unref:
- peer_unref(p);
-
- return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
-}
-
-static int registry_authrequest(int callno)
-{
- struct iax_ie_data ied;
- struct iax2_peer *p;
- char challenge[10];
- const char *peer_name;
- int res = -1;
-
- peer_name = ast_strdupa(iaxs[callno]->peer);
-
- /* SLD: third call to find_peer in registration */
- ast_mutex_unlock(&iaxsl[callno]);
- p = find_peer(peer_name, 1);
- ast_mutex_lock(&iaxsl[callno]);
- if (!iaxs[callno])
- goto return_unref;
- if (!p) {
- ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
- goto return_unref;
- }
-
- memset(&ied, 0, sizeof(ied));
- iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
- if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
- /* Build the challenge */
- snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
- ast_string_field_set(iaxs[callno], challenge, challenge);
- iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
- }
- iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
-
- res = 0;
-
-return_unref:
- peer_unref(p);
-
- return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
-}
-
-static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
-{
- struct iax2_registry *reg;
- /* Start pessimistic */
- struct iax_ie_data ied;
- char peer[256] = "";
- char challenge[256] = "";
- int res;
- int authmethods = 0;
- if (ies->authmethods)
- authmethods = ies->authmethods;
- if (ies->username)
- ast_copy_string(peer, ies->username, sizeof(peer));
- if (ies->challenge)
- ast_copy_string(challenge, ies->challenge, sizeof(challenge));
- memset(&ied, 0, sizeof(ied));
- reg = iaxs[callno]->reg;
- if (reg) {
- if (inaddrcmp(&reg->addr, sin)) {
- ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
- return -1;
- }
- if (ast_strlen_zero(reg->secret)) {
- ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
- reg->regstate = REG_STATE_NOAUTH;
- return -1;
- }
- iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
- iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
- if (reg->secret[0] == '[') {
- char tmpkey[256];
- ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
- tmpkey[strlen(tmpkey) - 1] = '\0';
- res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
- } else
- res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
- if (!res) {
- reg->regstate = REG_STATE_AUTHSENT;
- return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
- } else
- return -1;
- ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
- } else
- ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
- return -1;
-}
-
-static void stop_stuff(int callno)
-{
- iax2_destroy_helper(iaxs[callno]);
-}
-
-static void __auth_reject(const void *nothing)
-{
- /* Called from IAX thread only, without iaxs lock */
- int callno = (int)(long)(nothing);
- struct iax_ie_data ied;
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno]) {
- memset(&ied, 0, sizeof(ied));
- if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
- iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
- iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
- } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
- iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
- iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
- }
- send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
- }
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static int auth_reject(const void *data)
-{
- int callno = (int)(long)(data);
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno])
- iaxs[callno]->authid = -1;
- ast_mutex_unlock(&iaxsl[callno]);
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__auth_reject, data))
-#endif
- __auth_reject(data);
- return 0;
-}
-
-static int auth_fail(int callno, int failcode)
-{
- /* Schedule sending the authentication failure in one second, to prevent
- guessing */
- if (iaxs[callno]) {
- iaxs[callno]->authfail = failcode;
- if (delayreject) {
- AST_SCHED_DEL(sched, iaxs[callno]->authid);
- iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
- } else
- auth_reject((void *)(long)callno);
- }
- return 0;
-}
-
-static void __auto_hangup(const void *nothing)
-{
- /* Called from IAX thread only, without iaxs lock */
- int callno = (int)(long)(nothing);
- struct iax_ie_data ied;
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno]) {
- memset(&ied, 0, sizeof(ied));
- iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
- iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
- send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
- }
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static int auto_hangup(const void *data)
-{
- int callno = (int)(long)(data);
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno]) {
- iaxs[callno]->autoid = -1;
- }
- ast_mutex_unlock(&iaxsl[callno]);
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__auto_hangup, data))
-#endif
- __auto_hangup(data);
- return 0;
-}
-
-static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
-{
- struct iax_ie_data ied;
- /* Auto-hangup with 30 seconds of inactivity */
- AST_SCHED_DEL(sched, iaxs[callno]->autoid);
- iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
- memset(&ied, 0, sizeof(ied));
- iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
- dp->flags |= CACHE_FLAG_TRANSMITTED;
-}
-
-static int iax2_vnak(int callno)
-{
- return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
-}
-
-static void vnak_retransmit(int callno, int last)
-{
- struct iax_frame *f;
-
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
- /* Send a copy immediately */
- if ((f->callno == callno) && iaxs[f->callno] &&
- ((unsigned char ) (f->oseqno - last) < 128) &&
- (f->retries >= 0)) {
- send_packet(f);
- }
- }
- AST_LIST_UNLOCK(&iaxq.queue);
-}
-
-static void __iax2_poke_peer_s(const void *data)
-{
- struct iax2_peer *peer = (struct iax2_peer *)data;
- iax2_poke_peer(peer, 0);
- peer_unref(peer);
-}
-
-static int iax2_poke_peer_s(const void *data)
-{
- struct iax2_peer *peer = (struct iax2_peer *)data;
- peer->pokeexpire = -1;
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__iax2_poke_peer_s, data))
-#endif
- __iax2_poke_peer_s(data);
- return 0;
-}
-
-static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
-{
- int res = 0;
- struct iax_frame *fr;
- struct ast_iax2_meta_hdr *meta;
- struct ast_iax2_meta_trunk_hdr *mth;
- int calls = 0;
-
- /* Point to frame */
- fr = (struct iax_frame *)tpeer->trunkdata;
- /* Point to meta data */
- meta = (struct ast_iax2_meta_hdr *)fr->afdata;
- mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
- if (tpeer->trunkdatalen) {
- /* We're actually sending a frame, so fill the meta trunk header and meta header */
- meta->zeros = 0;
- meta->metacmd = IAX_META_TRUNK;
- if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
- meta->cmddata = IAX_META_TRUNK_MINI;
- else
- meta->cmddata = IAX_META_TRUNK_SUPERMINI;
- mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
- /* And the rest of the ast_iax2 header */
- fr->direction = DIRECTION_OUTGRESS;
- fr->retrans = -1;
- fr->transfer = 0;
- /* Any appropriate call will do */
- fr->data = fr->afdata;
- fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
- res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
- calls = tpeer->calls;
-#if 0
- if (option_debug)
- ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
-#endif
- /* Reset transmit trunk side data */
- tpeer->trunkdatalen = 0;
- tpeer->calls = 0;
- }
- if (res < 0)
- return res;
- return calls;
-}
-
-static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
-{
- /* Drop when trunk is about 5 seconds idle */
- if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
- return 1;
- return 0;
-}
-
-static int timing_read(int *id, int fd, short events, void *cbdata)
-{
- char buf[1024];
- int res;
- struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
- int processed = 0;
- int totalcalls = 0;
-#ifdef ZT_TIMERACK
- int x = 1;
-#endif
- struct timeval now;
- if (iaxtrunkdebug)
- ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
- gettimeofday(&now, NULL);
- if (events & AST_IO_PRI) {
-#ifdef ZT_TIMERACK
- /* Great, this is a timing interface, just call the ioctl */
- if (ioctl(fd, ZT_TIMERACK, &x)) {
- ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
- usleep(1);
- return -1;
- }
-#endif
- } else {
- /* Read and ignore from the pseudo channel for timing */
- res = read(fd, buf, sizeof(buf));
- if (res < 1) {
- ast_log(LOG_WARNING, "Unable to read from timing fd\n");
- return 1;
- }
- }
- /* For each peer that supports trunking... */
- ast_mutex_lock(&tpeerlock);
- tpeer = tpeers;
- while(tpeer) {
- processed++;
- res = 0;
- ast_mutex_lock(&tpeer->lock);
- /* We can drop a single tpeer per pass. That makes all this logic
- substantially easier */
- if (!drop && iax2_trunk_expired(tpeer, &now)) {
- /* Take it out of the list, but don't free it yet, because it
- could be in use */
- if (prev)
- prev->next = tpeer->next;
- else
- tpeers = tpeer->next;
- drop = tpeer;
- } else {
- res = send_trunk(tpeer, &now);
- if (iaxtrunkdebug)
- ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
- }
- totalcalls += res;
- res = 0;
- ast_mutex_unlock(&tpeer->lock);
- prev = tpeer;
- tpeer = tpeer->next;
- }
- ast_mutex_unlock(&tpeerlock);
- if (drop) {
- ast_mutex_lock(&drop->lock);
- /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
- because by the time they could get tpeerlock, we've already grabbed it */
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
- if (drop->trunkdata) {
- free(drop->trunkdata);
- drop->trunkdata = NULL;
- }
- ast_mutex_unlock(&drop->lock);
- ast_mutex_destroy(&drop->lock);
- free(drop);
-
- }
- if (iaxtrunkdebug)
- ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
- iaxtrunkdebug =0;
- return 1;
-}
-
-struct dpreq_data {
- int callno;
- char context[AST_MAX_EXTENSION];
- char callednum[AST_MAX_EXTENSION];
- char *callerid;
-};
-
-static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
-{
- unsigned short dpstatus = 0;
- struct iax_ie_data ied1;
- int mm;
-
- memset(&ied1, 0, sizeof(ied1));
- mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
- /* Must be started */
- if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
- dpstatus = IAX_DPSTATUS_EXISTS;
- } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
- dpstatus = IAX_DPSTATUS_CANEXIST;
- } else {
- dpstatus = IAX_DPSTATUS_NONEXISTENT;
- }
- if (ast_ignore_pattern(context, callednum))
- dpstatus |= IAX_DPSTATUS_IGNOREPAT;
- if (mm)
- dpstatus |= IAX_DPSTATUS_MATCHMORE;
- if (!skiplock)
- ast_mutex_lock(&iaxsl[callno]);
- if (iaxs[callno]) {
- iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
- iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
- iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
- }
- if (!skiplock)
- ast_mutex_unlock(&iaxsl[callno]);
-}
-
-static void *dp_lookup_thread(void *data)
-{
- /* Look up for dpreq */
- struct dpreq_data *dpr = data;
- dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
- if (dpr->callerid)
- free(dpr->callerid);
- free(dpr);
- return NULL;
-}
-
-static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
-{
- pthread_t newthread;
- struct dpreq_data *dpr;
- pthread_attr_t attr;
-
- if (!(dpr = ast_calloc(1, sizeof(*dpr))))
- return;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- dpr->callno = callno;
- ast_copy_string(dpr->context, context, sizeof(dpr->context));
- ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
- if (callerid)
- dpr->callerid = ast_strdup(callerid);
- if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
- ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
- }
-
- pthread_attr_destroy(&attr);
-}
-
-struct iax_dual {
- struct ast_channel *chan1;
- struct ast_channel *chan2;
-};
-
-static void *iax_park_thread(void *stuff)
-{
- struct ast_channel *chan1, *chan2;
- struct iax_dual *d;
- struct ast_frame *f;
- int ext;
- int res;
- d = stuff;
- chan1 = d->chan1;
- chan2 = d->chan2;
- free(d);
- f = ast_read(chan1);
- if (f)
- ast_frfree(f);
- res = ast_park_call(chan1, chan2, 0, &ext);
- ast_hangup(chan2);
- ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
- return NULL;
-}
-
-static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
-{
- struct iax_dual *d;
- struct ast_channel *chan1m, *chan2m;
- pthread_t th;
- chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
- chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
- if (chan2m && chan1m) {
- /* Make formats okay */
- chan1m->readformat = chan1->readformat;
- chan1m->writeformat = chan1->writeformat;
- ast_channel_masquerade(chan1m, chan1);
- /* Setup the extensions and such */
- ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
- ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
- chan1m->priority = chan1->priority;
-
- /* We make a clone of the peer channel too, so we can play
- back the announcement */
- /* Make formats okay */
- chan2m->readformat = chan2->readformat;
- chan2m->writeformat = chan2->writeformat;
- ast_channel_masquerade(chan2m, chan2);
- /* Setup the extensions and such */
- ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
- ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
- chan2m->priority = chan2->priority;
- if (ast_do_masquerade(chan2m)) {
- ast_log(LOG_WARNING, "Masquerade failed :(\n");
- ast_hangup(chan2m);
- return -1;
- }
- } else {
- if (chan1m)
- ast_hangup(chan1m);
- if (chan2m)
- ast_hangup(chan2m);
- return -1;
- }
- if ((d = ast_calloc(1, sizeof(*d)))) {
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- d->chan1 = chan1m;
- d->chan2 = chan2m;
- if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
- pthread_attr_destroy(&attr);
- return 0;
- }
- pthread_attr_destroy(&attr);
- free(d);
- }
- return -1;
-}
-
-
-static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
-
-static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
-{
- unsigned int ourver;
- char rsi[80];
- snprintf(rsi, sizeof(rsi), "si-%s", si);
- if (iax_provision_version(&ourver, rsi, 1))
- return 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
- if (ourver != ver)
- iax2_provision(sin, sockfd, NULL, rsi, 1);
- return 0;
-}
-
-static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
-{
- jb_info stats;
- jb_getinfo(pvt->jb, &stats);
-
- memset(iep, 0, sizeof(*iep));
-
- iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
- if(stats.frames_in == 0) stats.frames_in = 1;
- iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
- iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
- iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
- iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
- iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
-}
-
-static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
-{
- iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
- iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
- iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
- iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
- iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
- iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
- iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
-}
-
-static int socket_process(struct iax2_thread *thread);
-
-/*!
- * \brief Handle any deferred full frames for this thread
- */
-static void handle_deferred_full_frames(struct iax2_thread *thread)
-{
- struct iax2_pkt_buf *pkt_buf;
-
- ast_mutex_lock(&thread->lock);
-
- while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
- ast_mutex_unlock(&thread->lock);
-
- thread->buf = pkt_buf->buf;
- thread->buf_len = pkt_buf->len;
- thread->buf_size = pkt_buf->len + 1;
-
- socket_process(thread);
-
- thread->buf = NULL;
- ast_free(pkt_buf);
-
- ast_mutex_lock(&thread->lock);
- }
-
- ast_mutex_unlock(&thread->lock);
-}
-
-/*!
- * \brief Queue the last read full frame for processing by a certain thread
- *
- * If there are already any full frames queued, they are sorted
- * by sequence number.
- */
-static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
-{
- struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
- struct ast_iax2_full_hdr *fh, *cur_fh;
-
- if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
- return;
-
- pkt_buf->len = from_here->buf_len;
- memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
-
- fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
- ast_mutex_lock(&to_here->lock);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
- cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
- if (fh->oseqno < cur_fh->oseqno) {
- AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- if (!cur_pkt_buf)
- AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
-
- ast_mutex_unlock(&to_here->lock);
-}
-
-static int socket_read(int *id, int fd, short events, void *cbdata)
-{
- struct iax2_thread *thread;
- socklen_t len;
- time_t t;
- static time_t last_errtime = 0;
- struct ast_iax2_full_hdr *fh;
-
- if (!(thread = find_idle_thread())) {
- time(&t);
- if (t != last_errtime && option_debug)
- ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
- last_errtime = t;
- usleep(1);
- return 1;
- }
-
- len = sizeof(thread->iosin);
- thread->iofd = fd;
- thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
- thread->buf_size = sizeof(thread->readbuf);
- thread->buf = thread->readbuf;
- if (thread->buf_len < 0) {
- if (errno != ECONNREFUSED && errno != EAGAIN)
- ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
- handle_error();
- thread->iostate = IAX_IOSTATE_IDLE;
- signal_condition(&thread->lock, &thread->cond);
- return 1;
- }
- if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
- thread->iostate = IAX_IOSTATE_IDLE;
- signal_condition(&thread->lock, &thread->cond);
- return 1;
- }
-
- /* Determine if this frame is a full frame; if so, and any thread is currently
- processing a full frame for the same callno from this peer, then drop this
- frame (and the peer will retransmit it) */
- fh = (struct ast_iax2_full_hdr *) thread->buf;
- if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
- struct iax2_thread *cur = NULL;
- uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
-
- AST_LIST_LOCK(&active_list);
- AST_LIST_TRAVERSE(&active_list, cur, list) {
- if ((cur->ffinfo.callno == callno) &&
- !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
- break;
- }
- if (cur) {
- /* we found another thread processing a full frame for this call,
- so queue it up for processing later. */
- defer_full_frame(thread, cur);
- AST_LIST_UNLOCK(&active_list);
- thread->iostate = IAX_IOSTATE_IDLE;
- signal_condition(&thread->lock, &thread->cond);
- return 1;
- } else {
- /* this thread is going to process this frame, so mark it */
- thread->ffinfo.callno = callno;
- memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
- thread->ffinfo.type = fh->type;
- thread->ffinfo.csub = fh->csub;
- }
- AST_LIST_UNLOCK(&active_list);
- }
-
- /* Mark as ready and send on its way */
- thread->iostate = IAX_IOSTATE_READY;
-#ifdef DEBUG_SCHED_MULTITHREAD
- ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
-#endif
- signal_condition(&thread->lock, &thread->cond);
-
- return 1;
-}
-
-static int socket_process(struct iax2_thread *thread)
-{
- struct sockaddr_in sin;
- int res;
- int updatehistory=1;
- int new = NEW_PREVENT;
- void *ptr;
- int dcallno = 0;
- struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
- struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
- struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
- struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
- struct ast_iax2_meta_trunk_hdr *mth;
- struct ast_iax2_meta_trunk_entry *mte;
- struct ast_iax2_meta_trunk_mini *mtm;
- struct iax_frame *fr;
- struct iax_frame *cur;
- struct ast_frame f = { 0, };
- struct ast_channel *c;
- struct iax2_dpcache *dp;
- struct iax2_peer *peer;
- struct iax2_trunk_peer *tpeer;
- struct timeval rxtrunktime;
- struct iax_ies ies;
- struct iax_ie_data ied0, ied1;
- int format;
- int fd;
- int exists;
- int minivid = 0;
- unsigned int ts;
- char empty[32]=""; /* Safety measure */
- struct iax_frame *duped_fr;
- char host_pref_buf[128];
- char caller_pref_buf[128];
- struct ast_codec_pref pref;
- char *using_prefs = "mine";
-
- /* allocate an iax_frame with 4096 bytes of data buffer */
- fr = alloca(sizeof(*fr) + 4096);
- fr->callno = 0;
- fr->afdatalen = 4096; /* From alloca() above */
-
- /* Copy frequently used parameters to the stack */
- res = thread->buf_len;
- fd = thread->iofd;
- memcpy(&sin, &thread->iosin, sizeof(sin));
-
- if (res < sizeof(*mh)) {
- ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
- return 1;
- }
- if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
- if (res < sizeof(*vh)) {
- ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- return 1;
- }
-
- /* This is a video frame, get call number */
- fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
- minivid = 1;
- } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
- unsigned char metatype;
-
- if (res < sizeof(*meta)) {
- ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- return 1;
- }
-
- /* This is a meta header */
- switch(meta->metacmd) {
- case IAX_META_TRUNK:
- if (res < (sizeof(*meta) + sizeof(*mth))) {
- ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
- sizeof(*meta) + sizeof(*mth));
- return 1;
- }
- mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
- ts = ntohl(mth->ts);
- metatype = meta->cmddata;
- res -= (sizeof(*meta) + sizeof(*mth));
- ptr = mth->data;
- tpeer = find_tpeer(&sin, fd);
- if (!tpeer) {
- ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- return 1;
- }
- tpeer->trunkact = ast_tvnow();
- if (!ts || ast_tvzero(tpeer->rxtrunktime))
- tpeer->rxtrunktime = tpeer->trunkact;
- rxtrunktime = tpeer->rxtrunktime;
- ast_mutex_unlock(&tpeer->lock);
- while(res >= sizeof(*mte)) {
- /* Process channels */
- unsigned short callno, trunked_ts, len;
-
- if (metatype == IAX_META_TRUNK_MINI) {
- mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
- ptr += sizeof(*mtm);
- res -= sizeof(*mtm);
- len = ntohs(mtm->len);
- callno = ntohs(mtm->mini.callno);
- trunked_ts = ntohs(mtm->mini.ts);
- } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
- mte = (struct ast_iax2_meta_trunk_entry *)ptr;
- ptr += sizeof(*mte);
- res -= sizeof(*mte);
- len = ntohs(mte->len);
- callno = ntohs(mte->callno);
- trunked_ts = 0;
- } else {
- ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- break;
- }
- /* Stop if we don't have enough data */
- if (len > res)
- break;
- fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
- if (fr->callno) {
- /* If it's a valid call, deliver the contents. If not, we
- drop it, since we don't have a scallno to use for an INVAL */
- /* Process as a mini frame */
- memset(&f, 0, sizeof(f));
- f.frametype = AST_FRAME_VOICE;
- if (iaxs[fr->callno]) {
- if (iaxs[fr->callno]->voiceformat > 0) {
- f.subclass = iaxs[fr->callno]->voiceformat;
- f.datalen = len;
- if (f.datalen >= 0) {
- if (f.datalen)
- f.data = ptr;
- if(trunked_ts) {
- fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
- } else
- fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
- /* Don't pass any packets until we're started */
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
- /* Common things */
- f.src = "IAX2";
- if (f.datalen && (f.frametype == AST_FRAME_VOICE))
- f.samples = ast_codec_get_samples(&f);
- iax_frame_wrap(fr, &f);
- duped_fr = iaxfrdup2(fr);
- if (duped_fr) {
- schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
- }
- /* It is possible for the pvt structure to go away after we call schedule_delivery */
- if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
- iaxs[fr->callno]->last = fr->ts;
-#if 1
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
-#endif
- }
- }
- } else {
- ast_log(LOG_WARNING, "Datalen < 0?\n");
- }
- } else {
- ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
- iax2_vnak(fr->callno);
- }
- }
- ast_mutex_unlock(&iaxsl[fr->callno]);
- }
- ptr += len;
- res -= len;
- }
-
- }
- return 1;
- }
-
-#ifdef DEBUG_SUPPORT
- if (iaxdebug && (res >= sizeof(*fh)))
- iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
-#endif
- if (ntohs(mh->callno) & IAX_FLAG_FULL) {
- if (res < sizeof(*fh)) {
- ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- return 1;
- }
-
- /* Get the destination call number */
- dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
- /* Retrieve the type and subclass */
- f.frametype = fh->type;
- if (f.frametype == AST_FRAME_VIDEO) {
- f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
- } else {
- f.subclass = uncompress_subclass(fh->csub);
- }
- if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
- (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
- (f.subclass == IAX_COMMAND_REGREL)))
- new = NEW_ALLOW;
- } else {
- /* Don't know anything about it yet */
- f.frametype = AST_FRAME_NULL;
- f.subclass = 0;
- }
-
- if (!fr->callno)
- fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, ntohs(mh->callno) & IAX_FLAG_FULL);
-
- if (fr->callno > 0)
- ast_mutex_lock(&iaxsl[fr->callno]);
-
- if (!fr->callno || !iaxs[fr->callno]) {
- /* A call arrived for a nonexistent destination. Unless it's an "inval"
- frame, reply with an inval */
- if (ntohs(mh->callno) & IAX_FLAG_FULL) {
- /* We can only raw hangup control frames */
- if (((f.subclass != IAX_COMMAND_INVAL) &&
- (f.subclass != IAX_COMMAND_TXCNT) &&
- (f.subclass != IAX_COMMAND_TXACC) &&
- (f.subclass != IAX_COMMAND_FWDOWNL))||
- (f.frametype != AST_FRAME_IAX))
- raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
- fd);
- }
- if (fr->callno > 0)
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
- if (decrypt_frame(fr->callno, fh, &f, &res)) {
- ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
-#ifdef DEBUG_SUPPORT
- else if (iaxdebug)
- iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
-#endif
- }
-
- /* count this frame */
- iaxs[fr->callno]->frames_received++;
-
- if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
- f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */
- f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */
- unsigned short new_peercallno;
-
- new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
- if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
- if (iaxs[fr->callno]->peercallno) {
- remove_by_peercallno(iaxs[fr->callno]);
- }
- iaxs[fr->callno]->peercallno = new_peercallno;
- store_by_peercallno(iaxs[fr->callno]);
- }
- }
- if (ntohs(mh->callno) & IAX_FLAG_FULL) {
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
- /* Check if it's out of order (and not an ACK or INVAL) */
- fr->oseqno = fh->oseqno;
- fr->iseqno = fh->iseqno;
- fr->ts = ntohl(fh->ts);
-#ifdef IAXTESTS
- if (test_resync) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
- fr->ts += test_resync;
- }
-#endif /* IAXTESTS */
-#if 0
- if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
- ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
- (f.subclass == IAX_COMMAND_NEW ||
- f.subclass == IAX_COMMAND_AUTHREQ ||
- f.subclass == IAX_COMMAND_ACCEPT ||
- f.subclass == IAX_COMMAND_REJECT)) ) )
-#endif
- if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
- updatehistory = 0;
- if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
- (iaxs[fr->callno]->iseqno ||
- ((f.subclass != IAX_COMMAND_TXCNT) &&
- (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */
- (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */
- (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
- (f.subclass != IAX_COMMAND_TXACC)) ||
- (f.frametype != AST_FRAME_IAX))) {
- if (
- ((f.subclass != IAX_COMMAND_ACK) &&
- (f.subclass != IAX_COMMAND_INVAL) &&
- (f.subclass != IAX_COMMAND_TXCNT) &&
- (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */
- (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */
- (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
- (f.subclass != IAX_COMMAND_TXACC) &&
- (f.subclass != IAX_COMMAND_VNAK)) ||
- (f.frametype != AST_FRAME_IAX)) {
- /* If it's not an ACK packet, it's out of order. */
- if (option_debug)
- ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
- iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
- /* Check to see if we need to request retransmission,
- * and take sequence number wraparound into account */
- if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
- /* If we've already seen it, ack it XXX There's a border condition here XXX */
- if ((f.frametype != AST_FRAME_IAX) ||
- ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Acking anyway\n");
- /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
- we have anything to send, we'll retransmit and get an ACK back anyway XXX */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- }
- } else {
- /* Send a VNAK requesting retransmission */
- iax2_vnak(fr->callno);
- }
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- } else {
- /* Increment unless it's an ACK or VNAK */
- if (((f.subclass != IAX_COMMAND_ACK) &&
- (f.subclass != IAX_COMMAND_INVAL) &&
- (f.subclass != IAX_COMMAND_TXCNT) &&
- (f.subclass != IAX_COMMAND_TXACC) &&
- (f.subclass != IAX_COMMAND_VNAK)) ||
- (f.frametype != AST_FRAME_IAX))
- iaxs[fr->callno]->iseqno++;
- }
- /* A full frame */
- if (res < sizeof(*fh)) {
- ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- /* Ensure text frames are NULL-terminated */
- if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
- if (res < thread->buf_size)
- thread->buf[res++] = '\0';
- else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
- thread->buf[res - 1] = '\0';
- }
- f.datalen = res - sizeof(*fh);
-
- /* Handle implicit ACKing unless this is an INVAL, and only if this is
- from the real peer, not the transfer peer */
- if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
- ((f.subclass != IAX_COMMAND_INVAL) ||
- (f.frametype != AST_FRAME_IAX))) {
- unsigned char x;
- int call_to_destroy;
- /* XXX This code is not very efficient. Surely there is a better way which still
- properly handles boundary conditions? XXX */
- /* First we have to qualify that the ACKed value is within our window */
- for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
- if (fr->iseqno == x)
- break;
- if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
- /* The acknowledgement is within our window. Time to acknowledge everything
- that it says to */
- for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
- /* Ack the packet with the given timestamp */
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
- call_to_destroy = 0;
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
- /* If it's our call, and our timestamp, mark -1 retries */
- if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
- cur->retries = -1;
- /* Destroy call if this is the end */
- if (cur->final)
- call_to_destroy = fr->callno;
- }
- }
- AST_LIST_UNLOCK(&iaxq.queue);
- if (call_to_destroy) {
- if (iaxdebug && option_debug)
- ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
- ast_mutex_lock(&iaxsl[call_to_destroy]);
- iax2_destroy(call_to_destroy);
- ast_mutex_unlock(&iaxsl[call_to_destroy]);
- }
- }
- /* Note how much we've received acknowledgement for */
- if (iaxs[fr->callno])
- iaxs[fr->callno]->rseqno = fr->iseqno;
- else {
- /* Stop processing now */
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
- }
- if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
- ((f.frametype != AST_FRAME_IAX) ||
- ((f.subclass != IAX_COMMAND_TXACC) &&
- (f.subclass != IAX_COMMAND_TXCNT)))) {
- /* Only messages we accept from a transfer host are TXACC and TXCNT */
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
-
- if (f.datalen) {
- if (f.frametype == AST_FRAME_IAX) {
- if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
- ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- f.data = NULL;
- f.datalen = 0;
- } else
- f.data = thread->buf + sizeof(*fh);
- } else {
- if (f.frametype == AST_FRAME_IAX)
- f.data = NULL;
- else
- f.data = empty;
- memset(&ies, 0, sizeof(ies));
- }
-
- /* when we receive the first full frame for a new incoming channel,
- it is safe to start the PBX on the channel because we have now
- completed a 3-way handshake with the peer */
- if ((f.frametype == AST_FRAME_VOICE) ||
- (f.frametype == AST_FRAME_VIDEO) ||
- (f.frametype == AST_FRAME_IAX)) {
- if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
- ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
- if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- }
-
- if (f.frametype == AST_FRAME_VOICE) {
- if (f.subclass != iaxs[fr->callno]->voiceformat) {
- iaxs[fr->callno]->voiceformat = f.subclass;
- if (option_debug)
- ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
- if (iaxs[fr->callno]->owner) {
- int orignative;
-retryowner:
- if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- usleep(1);
- ast_mutex_lock(&iaxsl[fr->callno]);
- if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
- }
- if (iaxs[fr->callno]) {
- if (iaxs[fr->callno]->owner) {
- orignative = iaxs[fr->callno]->owner->nativeformats;
- iaxs[fr->callno]->owner->nativeformats = f.subclass;
- if (iaxs[fr->callno]->owner->readformat)
- ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
- iaxs[fr->callno]->owner->nativeformats = orignative;
- ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
- }
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- }
- }
- if (f.frametype == AST_FRAME_VIDEO) {
- if (f.subclass != iaxs[fr->callno]->videoformat) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
- iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
- }
- }
- if (f.frametype == AST_FRAME_IAX) {
- AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
- /* Handle the IAX pseudo frame itself */
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
-
- /* Update last ts unless the frame's timestamp originated with us. */
- if (iaxs[fr->callno]->last < fr->ts &&
- f.subclass != IAX_COMMAND_ACK &&
- f.subclass != IAX_COMMAND_PONG &&
- f.subclass != IAX_COMMAND_LAGRP) {
- iaxs[fr->callno]->last = fr->ts;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
- }
-
- switch(f.subclass) {
- case IAX_COMMAND_ACK:
- /* Do nothing */
- break;
- case IAX_COMMAND_QUELCH:
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
- /* Generate Manager Hold event, if necessary*/
- if (iaxs[fr->callno]->owner) {
- manager_event(EVENT_FLAG_CALL, "Hold",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n",
- iaxs[fr->callno]->owner->name,
- iaxs[fr->callno]->owner->uniqueid);
- }
-
- ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
- if (ies.musiconhold) {
- if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
- const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
- iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
- S_OR(mohsuggest, NULL),
- !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- }
- }
- break;
- case IAX_COMMAND_UNQUELCH:
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
- /* Generate Manager Unhold event, if necessary*/
- if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
- manager_event(EVENT_FLAG_CALL, "Unhold",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n",
- iaxs[fr->callno]->owner->name,
- iaxs[fr->callno]->owner->uniqueid);
- }
-
- ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
- if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
- iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- }
- break;
- case IAX_COMMAND_TXACC:
- if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
- /* Ack the packet with the given timestamp */
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
- /* Cancel any outstanding txcnt's */
- if ((fr->callno == cur->callno) && (cur->transfer))
- cur->retries = -1;
- }
- AST_LIST_UNLOCK(&iaxq.queue);
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
- iaxs[fr->callno]->transferring = TRANSFER_READY;
- }
- break;
- case IAX_COMMAND_NEW:
- /* Ignore if it's already up */
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
- break;
- if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- check_provisioning(&sin, fd, ies.serviceident, ies.provver);
- ast_mutex_lock(&iaxsl[fr->callno]);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
- if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
- int new_callno;
- if ((new_callno = make_trunk(fr->callno, 1)) != -1)
- fr->callno = new_callno;
- }
- /* For security, always ack immediately */
- if (delayreject)
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- if (check_access(fr->callno, &sin, &ies)) {
- /* They're not allowed on */
- auth_fail(fr->callno, IAX_COMMAND_REJECT);
- if (authdebug)
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
- break;
- }
- if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
- const char *context, *exten, *cid_num;
-
- context = ast_strdupa(iaxs[fr->callno]->context);
- exten = ast_strdupa(iaxs[fr->callno]->exten);
- cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
-
- /* This might re-enter the IAX code and need the lock */
- ast_mutex_unlock(&iaxsl[fr->callno]);
- exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
- ast_mutex_lock(&iaxsl[fr->callno]);
-
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- } else
- exists = 0;
- if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
- if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (authdebug)
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
- } else {
- /* Select an appropriate format */
-
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
- using_prefs = "reqonly";
- } else {
- using_prefs = "disabled";
- }
- format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
- memset(&pref, 0, sizeof(pref));
- strcpy(caller_pref_buf, "disabled");
- strcpy(host_pref_buf, "disabled");
- } else {
- using_prefs = "mine";
- /* If the information elements are in here... use them */
- if (ies.codec_prefs)
- ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
- /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
- if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
- pref = iaxs[fr->callno]->rprefs;
- using_prefs = "caller";
- } else {
- pref = iaxs[fr->callno]->prefs;
- }
- } else
- pref = iaxs[fr->callno]->prefs;
-
- format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
- ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
- ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
- }
- if (!format) {
- if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
- format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
- if (!format) {
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (authdebug) {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
- else
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
- }
- } else {
- /* Pick one... */
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
- if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
- format = 0;
- } else {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
- using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
- memset(&pref, 0, sizeof(pref));
- format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
- strcpy(caller_pref_buf,"disabled");
- strcpy(host_pref_buf,"disabled");
- } else {
- using_prefs = "mine";
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
- /* Do the opposite of what we tried above. */
- if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
- pref = iaxs[fr->callno]->prefs;
- } else {
- pref = iaxs[fr->callno]->rprefs;
- using_prefs = "caller";
- }
- format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
-
- } else /* if no codec_prefs IE do it the old way */
- format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
- }
- }
-
- if (!format) {
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (authdebug)
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
- ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
- break;
- }
- }
- }
- if (format) {
- /* No authentication required, let them in */
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
- if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
- "%srequested format = %s,\n"
- "%srequested prefs = %s,\n"
- "%sactual format = %s,\n"
- "%shost prefs = %s,\n"
- "%spriority = %s\n",
- ast_inet_ntoa(sin.sin_addr),
- VERBOSE_PREFIX_4,
- ast_getformatname(iaxs[fr->callno]->peerformat),
- VERBOSE_PREFIX_4,
- caller_pref_buf,
- VERBOSE_PREFIX_4,
- ast_getformatname(format),
- VERBOSE_PREFIX_4,
- host_pref_buf,
- VERBOSE_PREFIX_4,
- using_prefs);
-
- iaxs[fr->callno]->chosenformat = format;
- ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
- } else {
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
- /* If this is a TBD call, we're ready but now what... */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
- }
- }
- }
- break;
- }
- if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
- merge_encryption(iaxs[fr->callno],ies.encmethods);
- else
- iaxs[fr->callno]->encmethods = 0;
- if (!authenticate_request(fr->callno) && iaxs[fr->callno])
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- break;
- case IAX_COMMAND_DPREQ:
- /* Request status in the dialplan */
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
- !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
- if (iaxcompat) {
- /* Spawn a thread for the lookup */
- spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
- } else {
- /* Just look it up */
- dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
- }
- }
- break;
- case IAX_COMMAND_HANGUP:
- ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
- if (option_debug)
- ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
- /* Set hangup cause according to remote */
- if (ies.causecode && iaxs[fr->callno]->owner)
- iaxs[fr->callno]->owner->hangupcause = ies.causecode;
- /* Send ack immediately, before we destroy */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- iax2_destroy(fr->callno);
- break;
- case IAX_COMMAND_REJECT:
- /* Set hangup cause according to remote */
- if (ies.causecode && iaxs[fr->callno]->owner)
- iaxs[fr->callno]->owner->hangupcause = ies.causecode;
-
- if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
- if (iaxs[fr->callno]->owner && authdebug)
- ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
- ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
- ies.cause ? ies.cause : "<Unknown>");
- if (option_debug)
- ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
- fr->callno);
- }
- /* Send ack immediately, before we destroy */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
- fr->ts, NULL, 0, fr->iseqno);
- if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
- iaxs[fr->callno]->error = EPERM;
- iax2_destroy(fr->callno);
- break;
- case IAX_COMMAND_TRANSFER:
- {
- struct ast_channel *bridged_chan;
-
- if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
- /* Set BLINDTRANSFER channel variables */
-
- ast_mutex_unlock(&iaxsl[fr->callno]);
- pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
- ast_mutex_lock(&iaxsl[fr->callno]);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
-
- pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
- if (!strcmp(ies.called_number, ast_parking_ext())) {
- if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
- ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
- } else {
- ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
- }
- } else {
- if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
- ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
- ies.called_number, iaxs[fr->callno]->context);
- else
- ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
- ies.called_number, iaxs[fr->callno]->context);
- }
- } else
- ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
-
- break;
- }
- case IAX_COMMAND_ACCEPT:
- /* Ignore if call is already up or needs authentication or is a TBD */
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
- break;
- if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
- /* Send ack immediately, before we destroy */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- iax2_destroy(fr->callno);
- break;
- }
- if (ies.format) {
- iaxs[fr->callno]->peerformat = ies.format;
- } else {
- if (iaxs[fr->callno]->owner)
- iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
- else
- iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
- if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (authdebug)
- ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
- } else {
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (iaxs[fr->callno]->owner) {
- /* Switch us to use a compatible format */
- iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
-retryowner2:
- if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- usleep(1);
- ast_mutex_lock(&iaxsl[fr->callno]);
- if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
- }
-
- if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
- /* Setup read/write formats properly. */
- if (iaxs[fr->callno]->owner->writeformat)
- ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
- if (iaxs[fr->callno]->owner->readformat)
- ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
- ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
- }
- }
- }
- if (iaxs[fr->callno]) {
- ast_mutex_lock(&dpcache_lock);
- dp = iaxs[fr->callno]->dpentries;
- while(dp) {
- if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
- iax2_dprequest(dp, fr->callno);
- }
- dp = dp->peer;
- }
- ast_mutex_unlock(&dpcache_lock);
- }
- break;
- case IAX_COMMAND_POKE:
- /* Send back a pong packet with the original timestamp */
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- break;
- case IAX_COMMAND_PING:
- {
- struct iax_ie_data pingied;
- construct_rr(iaxs[fr->callno], &pingied);
- /* Send back a pong packet with the original timestamp */
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
- }
- break;
- case IAX_COMMAND_PONG:
- /* Calculate ping time */
- iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
- /* save RR info */
- save_rr(fr, &ies);
-
- if (iaxs[fr->callno]->peerpoke) {
- peer = iaxs[fr->callno]->peerpoke;
- if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
- if (iaxs[fr->callno]->pingtime <= peer->maxms) {
- ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
- ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
- }
- } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
- if (iaxs[fr->callno]->pingtime > peer->maxms) {
- ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
- ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
- }
- }
- peer->lastms = iaxs[fr->callno]->pingtime;
- if (peer->smoothing && (peer->lastms > -1))
- peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
- else if (peer->smoothing && peer->lastms < 0)
- peer->historicms = (0 + peer->historicms) / 2;
- else
- peer->historicms = iaxs[fr->callno]->pingtime;
-
- /* Remove scheduled iax2_poke_noanswer */
- if (peer->pokeexpire > -1) {
- if (!ast_sched_del(sched, peer->pokeexpire)) {
- peer_unref(peer);
- peer->pokeexpire = -1;
- }
- }
- /* Schedule the next cycle */
- if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
- peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
- else
- peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
- if (peer->pokeexpire == -1)
- peer_unref(peer);
- /* and finally send the ack */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- /* And wrap up the qualify call */
- iax2_destroy(fr->callno);
- peer->callno = 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
- }
- break;
- case IAX_COMMAND_LAGRQ:
- case IAX_COMMAND_LAGRP:
- f.src = "LAGRQ";
- f.mallocd = 0;
- f.offset = 0;
- f.samples = 0;
- iax_frame_wrap(fr, &f);
- if(f.subclass == IAX_COMMAND_LAGRQ) {
- /* Received a LAGRQ - echo back a LAGRP */
- fr->af.subclass = IAX_COMMAND_LAGRP;
- iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
- } else {
- /* Received LAGRP in response to our LAGRQ */
- unsigned int ts;
- /* This is a reply we've been given, actually measure the difference */
- ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
- iaxs[fr->callno]->lag = ts - fr->ts;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
- ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
- }
- break;
- case IAX_COMMAND_AUTHREQ:
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
- ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
- break;
- }
- if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
- struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
- .subclass = AST_CONTROL_HANGUP,
- };
- ast_log(LOG_WARNING,
- "I don't know how to authenticate %s to %s\n",
- ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
- iax2_queue_frame(fr->callno, &hangup_fr);
- }
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- break;
- case IAX_COMMAND_AUTHREP:
- /* For security, always ack immediately */
- if (delayreject)
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- /* Ignore once we've started */
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
- ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
- break;
- }
- if (authenticate_verify(iaxs[fr->callno], &ies)) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
- memset(&ied0, 0, sizeof(ied0));
- auth_fail(fr->callno, IAX_COMMAND_REJECT);
- break;
- }
- if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
- /* This might re-enter the IAX code and need the lock */
- exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
- } else
- exists = 0;
- if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- } else {
- /* Select an appropriate format */
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
- using_prefs = "reqonly";
- } else {
- using_prefs = "disabled";
- }
- format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
- memset(&pref, 0, sizeof(pref));
- strcpy(caller_pref_buf, "disabled");
- strcpy(host_pref_buf, "disabled");
- } else {
- using_prefs = "mine";
- if (ies.codec_prefs)
- ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
- if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
- pref = iaxs[fr->callno]->rprefs;
- using_prefs = "caller";
- } else {
- pref = iaxs[fr->callno]->prefs;
- }
- } else /* if no codec_prefs IE do it the old way */
- pref = iaxs[fr->callno]->prefs;
-
- format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
- ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
- ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
- }
- if (!format) {
- if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
- format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
- }
- if (!format) {
- if (authdebug) {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
- else
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
- }
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- } else {
- /* Pick one... */
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
- if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
- format = 0;
- } else {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
- using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
- memset(&pref, 0, sizeof(pref));
- format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
- iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
- strcpy(caller_pref_buf,"disabled");
- strcpy(host_pref_buf,"disabled");
- } else {
- using_prefs = "mine";
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
- /* Do the opposite of what we tried above. */
- if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
- pref = iaxs[fr->callno]->prefs;
- } else {
- pref = iaxs[fr->callno]->rprefs;
- using_prefs = "caller";
- }
- format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
- } else /* if no codec_prefs IE do it the old way */
- format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
- }
- }
- if (!format) {
- ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
- if (authdebug) {
- if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
- else
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
- }
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- }
- }
- if (format) {
- /* Authentication received */
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
- if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
- "%srequested format = %s,\n"
- "%srequested prefs = %s,\n"
- "%sactual format = %s,\n"
- "%shost prefs = %s,\n"
- "%spriority = %s\n",
- ast_inet_ntoa(sin.sin_addr),
- VERBOSE_PREFIX_4,
- ast_getformatname(iaxs[fr->callno]->peerformat),
- VERBOSE_PREFIX_4,
- caller_pref_buf,
- VERBOSE_PREFIX_4,
- ast_getformatname(format),
- VERBOSE_PREFIX_4,
- host_pref_buf,
- VERBOSE_PREFIX_4,
- using_prefs);
-
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
- iax2_destroy(fr->callno);
- } else {
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
- /* If this is a TBD call, we're ready but now what... */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
- }
- }
- }
- break;
- case IAX_COMMAND_DIAL:
- if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
- ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
- ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
- if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
- if (authdebug)
- ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- } else {
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
- if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
- iax2_destroy(fr->callno);
- }
- }
- break;
- case IAX_COMMAND_INVAL:
- iaxs[fr->callno]->error = ENOTCONN;
- if (option_debug)
- ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
- iax2_destroy(fr->callno);
- if (option_debug)
- ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
- break;
- case IAX_COMMAND_VNAK:
- if (option_debug)
- ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
- /* Force retransmission */
- vnak_retransmit(fr->callno, fr->iseqno);
- break;
- case IAX_COMMAND_REGREQ:
- case IAX_COMMAND_REGREL:
- /* For security, always ack immediately */
- if (delayreject)
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- if (register_verify(fr->callno, &sin, &ies)) {
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- /* Send delayed failure */
- auth_fail(fr->callno, IAX_COMMAND_REGREJ);
- break;
- }
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
- ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
- if (f.subclass == IAX_COMMAND_REGREL)
- memset(&sin, 0, sizeof(sin));
- if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
- ast_log(LOG_WARNING, "Registry error\n");
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- check_provisioning(&sin, fd, ies.serviceident, ies.provver);
- ast_mutex_lock(&iaxsl[fr->callno]);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- break;
- }
- registry_authrequest(fr->callno);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- break;
- case IAX_COMMAND_REGACK:
- if (iax2_ack_registry(&ies, &sin, fr->callno))
- ast_log(LOG_WARNING, "Registration failure\n");
- /* Send ack immediately, before we destroy */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- iax2_destroy(fr->callno);
- break;
- case IAX_COMMAND_REGREJ:
- if (iaxs[fr->callno]->reg) {
- if (authdebug) {
- ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
- manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
- }
- iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
- }
- /* Send ack immediately, before we destroy */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- iax2_destroy(fr->callno);
- break;
- case IAX_COMMAND_REGAUTH:
- /* Authentication request */
- if (registry_rerequest(&ies, fr->callno, &sin)) {
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- }
- break;
- case IAX_COMMAND_TXREJ:
- iaxs[fr->callno]->transferring = 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
- memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
- if (iaxs[fr->callno]->bridgecallno) {
- if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
- iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
- send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
- }
- }
- break;
- case IAX_COMMAND_TXREADY:
- if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
- (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
- if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
- iaxs[fr->callno]->transferring = TRANSFER_MREADY;
- else
- iaxs[fr->callno]->transferring = TRANSFER_READY;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
- if (iaxs[fr->callno]->bridgecallno) {
- if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
- (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
- /* They're both ready, now release them. */
- if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
- iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
-
- iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
- iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
-
- memset(&ied0, 0, sizeof(ied0));
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
- send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
- iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
-
- iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
- iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
- ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
- ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
-
- /* Stop doing lag & ping requests */
- stop_stuff(fr->callno);
- stop_stuff(iaxs[fr->callno]->bridgecallno);
-
- memset(&ied0, 0, sizeof(ied0));
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
- send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
- }
-
- }
- }
- }
- break;
- case IAX_COMMAND_TXREQ:
- try_transfer(iaxs[fr->callno], &ies);
- break;
- case IAX_COMMAND_TXCNT:
- if (iaxs[fr->callno]->transferring)
- send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
- break;
- case IAX_COMMAND_TXREL:
- /* Send ack immediately, rather than waiting until we've changed addresses */
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- complete_transfer(fr->callno, &ies);
- stop_stuff(fr->callno); /* for attended transfer to work with libiax */
- break;
- case IAX_COMMAND_TXMEDIA:
- if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
- AST_LIST_LOCK(&iaxq.queue);
- AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
- /* Cancel any outstanding frames and start anew */
- if ((fr->callno == cur->callno) && (cur->transfer)) {
- cur->retries = -1;
- }
- }
- AST_LIST_UNLOCK(&iaxq.queue);
- /* Start sending our media to the transfer address, but otherwise leave the call as-is */
- iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
- }
- break;
- case IAX_COMMAND_DPREP:
- complete_dpreply(iaxs[fr->callno], &ies);
- break;
- case IAX_COMMAND_UNSUPPORT:
- ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
- break;
- case IAX_COMMAND_FWDOWNL:
- /* Firmware download */
- memset(&ied0, 0, sizeof(ied0));
- res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
- if (res < 0)
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
- else if (res > 0)
- send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
- else
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
- if (!iaxs[fr->callno]) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
- memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
- }
- /* Don't actually pass these frames along */
- if ((f.subclass != IAX_COMMAND_ACK) &&
- (f.subclass != IAX_COMMAND_TXCNT) &&
- (f.subclass != IAX_COMMAND_TXACC) &&
- (f.subclass != IAX_COMMAND_INVAL) &&
- (f.subclass != IAX_COMMAND_VNAK)) {
- if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- }
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- /* Unless this is an ACK or INVAL frame, ack it */
- if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
- send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
- } else if (minivid) {
- f.frametype = AST_FRAME_VIDEO;
- if (iaxs[fr->callno]->videoformat > 0)
- f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
- else {
- ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
- iax2_vnak(fr->callno);
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- f.datalen = res - sizeof(*vh);
- if (f.datalen)
- f.data = thread->buf + sizeof(*vh);
- else
- f.data = NULL;
-#ifdef IAXTESTS
- if (test_resync) {
- fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
- } else
-#endif /* IAXTESTS */
- fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
- } else {
- /* A mini frame */
- f.frametype = AST_FRAME_VOICE;
- if (iaxs[fr->callno]->voiceformat > 0)
- f.subclass = iaxs[fr->callno]->voiceformat;
- else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
- iax2_vnak(fr->callno);
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
- if (f.datalen < 0) {
- ast_log(LOG_WARNING, "Datalen < 0?\n");
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- if (f.datalen)
- f.data = thread->buf + sizeof(*mh);
- else
- f.data = NULL;
-#ifdef IAXTESTS
- if (test_resync) {
- fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
- } else
-#endif /* IAXTESTS */
- fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
- /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
- }
- /* Don't pass any packets until we're started */
- if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
- }
- /* Common things */
- f.src = "IAX2";
- f.mallocd = 0;
- f.offset = 0;
- f.len = 0;
- if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
- f.samples = ast_codec_get_samples(&f);
- /* We need to byteswap incoming slinear samples from network byte order */
- if (f.subclass == AST_FORMAT_SLINEAR)
- ast_frame_byteswap_be(&f);
- } else
- f.samples = 0;
- iax_frame_wrap(fr, &f);
-
- /* If this is our most recent packet, use it as our basis for timestamping */
- if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
- /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
- fr->outoforder = 0;
- } else {
- if (option_debug && iaxdebug && iaxs[fr->callno])
- ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
- fr->outoforder = -1;
- }
- fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
- duped_fr = iaxfrdup2(fr);
- if (duped_fr) {
- schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
- }
- if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
- iaxs[fr->callno]->last = fr->ts;
-#if 1
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
-#endif
- }
-
- /* Always run again */
- ast_mutex_unlock(&iaxsl[fr->callno]);
- return 1;
-}
-
-/* Function to clean up process thread if it is cancelled */
-static void iax2_process_thread_cleanup(void *data)
-{
- struct iax2_thread *thread = data;
- ast_mutex_destroy(&thread->lock);
- ast_cond_destroy(&thread->cond);
- free(thread);
- ast_atomic_dec_and_test(&iaxactivethreadcount);
-}
-
-static void *iax2_process_thread(void *data)
-{
- struct iax2_thread *thread = data;
- struct timeval tv;
- struct timespec ts;
- int put_into_idle = 0;
-
- ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
- pthread_cleanup_push(iax2_process_thread_cleanup, data);
- for(;;) {
- /* Wait for something to signal us to be awake */
- ast_mutex_lock(&thread->lock);
-
- /* Flag that we're ready to accept signals */
- thread->ready_for_signal = 1;
-
- /* Put into idle list if applicable */
- if (put_into_idle)
- insert_idle_thread(thread);
-
- if (thread->type == IAX_TYPE_DYNAMIC) {
- struct iax2_thread *t = NULL;
- /* Wait to be signalled or time out */
- tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
- /* This thread was never put back into the available dynamic
- * thread list, so just go away. */
- if (!put_into_idle) {
- ast_mutex_unlock(&thread->lock);
- break;
- }
- AST_LIST_LOCK(&dynamic_list);
- /* Account for the case where this thread is acquired *right* after a timeout */
- if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
- iaxdynamicthreadcount--;
- AST_LIST_UNLOCK(&dynamic_list);
- if (t) {
- /* This dynamic thread timed out waiting for a task and was
- * not acquired immediately after the timeout,
- * so it's time to go away. */
- ast_mutex_unlock(&thread->lock);
- break;
- }
- /* Someone grabbed our thread *right* after we timed out.
- * Wait for them to set us up with something to do and signal
- * us to continue. */
- tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
- {
- ast_mutex_unlock(&thread->lock);
- break;
- }
- }
- } else {
- ast_cond_wait(&thread->cond, &thread->lock);
- }
-
- /* Go back into our respective list */
- put_into_idle = 1;
-
- ast_mutex_unlock(&thread->lock);
-
- if (thread->iostate == IAX_IOSTATE_IDLE)
- continue;
-
- /* Add ourselves to the active list now */
- AST_LIST_LOCK(&active_list);
- AST_LIST_INSERT_HEAD(&active_list, thread, list);
- AST_LIST_UNLOCK(&active_list);
-
- /* See what we need to do */
- switch(thread->iostate) {
- case IAX_IOSTATE_READY:
- thread->actions++;
- thread->iostate = IAX_IOSTATE_PROCESSING;
- socket_process(thread);
- handle_deferred_full_frames(thread);
- break;
- case IAX_IOSTATE_SCHEDREADY:
- thread->actions++;
- thread->iostate = IAX_IOSTATE_PROCESSING;
-#ifdef SCHED_MULTITHREADED
- thread->schedfunc(thread->scheddata);
-#endif
- break;
- }
- time(&thread->checktime);
- thread->iostate = IAX_IOSTATE_IDLE;
-#ifdef DEBUG_SCHED_MULTITHREAD
- thread->curfunc[0]='\0';
-#endif
-
- /* Now... remove ourselves from the active list, and return to the idle list */
- AST_LIST_LOCK(&active_list);
- AST_LIST_REMOVE(&active_list, thread, list);
- AST_LIST_UNLOCK(&active_list);
-
- /* Make sure another frame didn't sneak in there after we thought we were done. */
- handle_deferred_full_frames(thread);
- }
-
- /*!\note For some reason, idle threads are exiting without being removed
- * from an idle list, which is causing memory corruption. Forcibly remove
- * it from the list, if it's there.
- */
- AST_LIST_LOCK(&idle_list);
- AST_LIST_REMOVE(&idle_list, thread, list);
- AST_LIST_UNLOCK(&idle_list);
-
- AST_LIST_LOCK(&dynamic_list);
- AST_LIST_REMOVE(&dynamic_list, thread, list);
- AST_LIST_UNLOCK(&dynamic_list);
-
- /* I am exiting here on my own volition, I need to clean up my own data structures
- * Assume that I am no longer in any of the lists (idle, active, or dynamic)
- */
- pthread_cleanup_pop(1);
-
- return NULL;
-}
-
-static int iax2_do_register(struct iax2_registry *reg)
-{
- struct iax_ie_data ied;
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
-
- if (reg->dnsmgr &&
- ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
- /* Maybe the IP has changed, force DNS refresh */
- ast_dnsmgr_refresh(reg->dnsmgr);
- }
-
- /*
- * if IP has Changed, free allocated call to create a new one with new IP
- * call has the pointer to IP and must be updated to the new one
- */
- if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
- ast_mutex_lock(&iaxsl[reg->callno]);
- iax2_destroy(reg->callno);
- ast_mutex_unlock(&iaxsl[reg->callno]);
- reg->callno = 0;
- }
- if (!reg->addr.sin_addr.s_addr) {
- if (option_debug && iaxdebug)
- ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
- /* Setup the next registration attempt */
- AST_SCHED_DEL(sched, reg->expire);
- reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
- return -1;
- }
-
- if (!reg->callno) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Allocate call number\n");
- reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
- if (reg->callno < 1) {
- ast_log(LOG_WARNING, "Unable to create call for registration\n");
- return -1;
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
- iaxs[reg->callno]->reg = reg;
- ast_mutex_unlock(&iaxsl[reg->callno]);
- }
- /* Schedule the next registration attempt */
- AST_SCHED_DEL(sched, reg->expire);
- /* Setup the next registration a little early */
- reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
- /* Send the request */
- memset(&ied, 0, sizeof(ied));
- iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
- iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
- send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
- reg->regstate = REG_STATE_REGSENT;
- return 0;
-}
-
-static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
-{
- if (pos != 3)
- return NULL;
- return iax_prov_complete_template(line, word, pos, state);
-}
-
-static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
-{
- /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
- is found for template */
- struct iax_ie_data provdata;
- struct iax_ie_data ied;
- unsigned int sig;
- struct sockaddr_in sin;
- int callno;
- struct create_addr_info cai;
-
- memset(&cai, 0, sizeof(cai));
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
-
- if (iax_provision_build(&provdata, &sig, template, force)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
- return 0;
- }
-
- if (end) {
- memcpy(&sin, end, sizeof(sin));
- cai.sockfd = sockfd;
- } else if (create_addr(dest, NULL, &sin, &cai))
- return -1;
-
- /* Build the rest of the message */
- memset(&ied, 0, sizeof(ied));
- iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
-
- callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
- if (!callno)
- return -1;
-
- if (iaxs[callno]) {
- /* Schedule autodestruct in case they don't ever give us anything back */
- AST_SCHED_DEL(sched, iaxs[callno]->autoid);
- iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
- ast_set_flag(iaxs[callno], IAX_PROVISION);
- /* Got a call number now, so go ahead and send the provisioning information */
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
- }
- ast_mutex_unlock(&iaxsl[callno]);
-
- return 1;
-}
-
-static char *papp = "IAX2Provision";
-static char *psyn = "Provision a calling IAXy with a given template";
-static char *pdescrip =
-" IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
-"the calling entity is in fact an IAXy) with the given template or\n"
-"default if one is not specified. Returns -1 on error or 0 on success.\n";
-
-/*! iax2provision
-\ingroup applications
-*/
-static int iax2_prov_app(struct ast_channel *chan, void *data)
-{
- int res;
- char *sdata;
- char *opts;
- int force =0;
- unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
- if (ast_strlen_zero(data))
- data = "default";
- sdata = ast_strdupa(data);
- opts = strchr(sdata, '|');
- if (opts)
- *opts='\0';
-
- if (chan->tech != &iax2_tech) {
- ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
- return -1;
- }
- if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
- ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
- return -1;
- }
- res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
- ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
- sdata, res);
- return res;
-}
-
-
-static int iax2_prov_cmd(int fd, int argc, char *argv[])
-{
- int force = 0;
- int res;
- if (argc < 4)
- return RESULT_SHOWUSAGE;
- if ((argc > 4)) {
- if (!strcasecmp(argv[4], "forced"))
- force = 1;
- else
- return RESULT_SHOWUSAGE;
- }
- res = iax2_provision(NULL, -1, argv[2], argv[3], force);
- if (res < 0)
- ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
- else if (res < 1)
- ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
- else
- ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
- return RESULT_SUCCESS;
-}
-
-static void __iax2_poke_noanswer(const void *data)
-{
- struct iax2_peer *peer = (struct iax2_peer *)data;
- if (peer->lastms > -1) {
- ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
- ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
- }
- if (peer->callno > 0) {
- ast_mutex_lock(&iaxsl[peer->callno]);
- iax2_destroy(peer->callno);
- ast_mutex_unlock(&iaxsl[peer->callno]);
- }
- peer->callno = 0;
- peer->lastms = -1;
- /* Try again quickly */
- peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
- if (peer->pokeexpire == -1)
- peer_unref(peer);
-}
-
-static int iax2_poke_noanswer(const void *data)
-{
- struct iax2_peer *peer = (struct iax2_peer *)data;
- peer->pokeexpire = -1;
-#ifdef SCHED_MULTITHREADED
- if (schedule_action(__iax2_poke_noanswer, data))
-#endif
- __iax2_poke_noanswer(data);
- peer_unref(peer);
- return 0;
-}
-
-static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
-{
- struct iax2_peer *peer = obj;
-
- iax2_poke_peer(peer, 0);
-
- return 0;
-}
-
-static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
-{
- if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
- /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
- immediately after clearing things out */
- peer->lastms = 0;
- peer->historicms = 0;
- peer->pokeexpire = -1;
- peer->callno = 0;
- return 0;
- }
- if (peer->callno > 0) {
- ast_log(LOG_NOTICE, "Still have a callno...\n");
- ast_mutex_lock(&iaxsl[peer->callno]);
- iax2_destroy(peer->callno);
- ast_mutex_unlock(&iaxsl[peer->callno]);
- }
- if (heldcall)
- ast_mutex_unlock(&iaxsl[heldcall]);
- peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
- if (heldcall)
- ast_mutex_lock(&iaxsl[heldcall]);
- if (peer->callno < 1) {
- ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
- return -1;
- }
-
- /* Speed up retransmission times for this qualify call */
- iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
- iaxs[peer->callno]->peerpoke = peer;
-
- /* Remove any pending pokeexpire task */
- if (peer->pokeexpire > -1) {
- if (!ast_sched_del(sched, peer->pokeexpire)) {
- peer->pokeexpire = -1;
- peer_unref(peer);
- }
- }
-
- /* Queue up a new task to handle no reply */
- /* If the host is already unreachable then use the unreachable interval instead */
- if (peer->lastms < 0) {
- peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
- } else
- peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
-
- if (peer->pokeexpire == -1)
- peer_unref(peer);
-
- /* And send the poke */
- send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
-
- return 0;
-}
-
-static void free_context(struct iax2_context *con)
-{
- struct iax2_context *conl;
- while(con) {
- conl = con;
- con = con->next;
- free(conl);
- }
-}
-
-static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
-{
- int callno;
- int res;
- int fmt, native;
- struct sockaddr_in sin;
- struct ast_channel *c;
- struct parsed_dial_string pds;
- struct create_addr_info cai;
- char *tmpstr;
-
- memset(&pds, 0, sizeof(pds));
- tmpstr = ast_strdupa(data);
- parse_dial_string(tmpstr, &pds);
-
- if (ast_strlen_zero(pds.peer)) {
- ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
- return NULL;
- }
-
- memset(&cai, 0, sizeof(cai));
- cai.capability = iax2_capability;
-
- ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
-
- /* Populate our address from the given */
- if (create_addr(pds.peer, NULL, &sin, &cai)) {
- *cause = AST_CAUSE_UNREGISTERED;
- return NULL;
- }
-
- if (pds.port)
- sin.sin_port = htons(atoi(pds.port));
-
- callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
- if (callno < 1) {
- ast_log(LOG_WARNING, "Unable to create call\n");
- *cause = AST_CAUSE_CONGESTION;
- return NULL;
- }
-
- /* If this is a trunk, update it now */
- ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
- if (ast_test_flag(&cai, IAX_TRUNK)) {
- int new_callno;
- if ((new_callno = make_trunk(callno, 1)) != -1)
- callno = new_callno;
- }
- iaxs[callno]->maxtime = cai.maxtime;
- if (cai.found)
- ast_string_field_set(iaxs[callno], host, pds.peer);
-
- c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
-
- ast_mutex_unlock(&iaxsl[callno]);
-
- if (c) {
- /* Choose a format we can live with */
- if (c->nativeformats & format)
- c->nativeformats &= format;
- else {
- native = c->nativeformats;
- fmt = format;
- res = ast_translator_best_choice(&fmt, &native);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
- ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
- ast_hangup(c);
- return NULL;
- }
- c->nativeformats = native;
- }
- c->readformat = ast_best_codec(c->nativeformats);
- c->writeformat = c->readformat;
- }
-
- return c;
-}
-
-static void *sched_thread(void *ignore)
-{
- int count;
- int res;
- struct timeval tv;
- struct timespec ts;
-
- for (;;) {
- res = ast_sched_wait(sched);
- if ((res > 1000) || (res < 0))
- res = 1000;
- tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
-
- pthread_testcancel();
- ast_mutex_lock(&sched_lock);
- ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
- ast_mutex_unlock(&sched_lock);
- pthread_testcancel();
-
- count = ast_sched_runq(sched);
- if (option_debug && count >= 20)
- ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
- }
- return NULL;
-}
-
-static void *network_thread(void *ignore)
-{
- /* Our job is simple: Send queued messages, retrying if necessary. Read frames
- from the network, and queue them for delivery to the channels */
- int res, count, wakeup;
- struct iax_frame *f;
-
- if (timingfd > -1)
- ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
-
- for(;;) {
- pthread_testcancel();
-
- /* Go through the queue, sending messages which have not yet been
- sent, and scheduling retransmissions if appropriate */
- AST_LIST_LOCK(&iaxq.queue);
- count = 0;
- wakeup = -1;
- AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
- if (f->sentyet)
- continue;
-
- /* Try to lock the pvt, if we can't... don't fret - defer it till later */
- if (ast_mutex_trylock(&iaxsl[f->callno])) {
- wakeup = 1;
- continue;
- }
-
- f->sentyet++;
-
- if (iaxs[f->callno]) {
- send_packet(f);
- count++;
- }
-
- ast_mutex_unlock(&iaxsl[f->callno]);
-
- if (f->retries < 0) {
- /* This is not supposed to be retransmitted */
- AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
- iaxq.count--;
- /* Free the iax frame */
- iax_frame_free(f);
- } else {
- /* We need reliable delivery. Schedule a retransmission */
- f->retries++;
- f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&iaxq.queue);
-
- pthread_testcancel();
-
- if (option_debug && count >= 20)
- ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
-
- /* Now do the IO, and run scheduled tasks */
- res = ast_io_wait(io, wakeup);
- if (res >= 0) {
- if (option_debug && res >= 20)
- ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
- }
- }
- return NULL;
-}
-
-static int start_network_thread(void)
-{
- pthread_attr_t attr;
- int threadcount = 0;
- int x;
- for (x = 0; x < iaxthreadcount; x++) {
- struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
- if (thread) {
- thread->type = IAX_TYPE_POOL;
- thread->threadnum = ++threadcount;
- ast_mutex_init(&thread->lock);
- ast_cond_init(&thread->cond, NULL);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
- ast_log(LOG_WARNING, "Failed to create new thread!\n");
- free(thread);
- thread = NULL;
- }
- AST_LIST_LOCK(&idle_list);
- AST_LIST_INSERT_TAIL(&idle_list, thread, list);
- AST_LIST_UNLOCK(&idle_list);
- }
- }
- ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
- ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
- return 0;
-}
-
-static struct iax2_context *build_context(char *context)
-{
- struct iax2_context *con;
-
- if ((con = ast_calloc(1, sizeof(*con))))
- ast_copy_string(con->context, context, sizeof(con->context));
-
- return con;
-}
-
-static int get_auth_methods(char *value)
-{
- int methods = 0;
- if (strstr(value, "rsa"))
- methods |= IAX_AUTH_RSA;
- if (strstr(value, "md5"))
- methods |= IAX_AUTH_MD5;
- if (strstr(value, "plaintext"))
- methods |= IAX_AUTH_PLAINTEXT;
- return methods;
-}
-
-
-/*! \brief Check if address can be used as packet source.
- \return 0 address available, 1 address unavailable, -1 error
-*/
-static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
-{
- int sd;
- int res;
-
- sd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sd < 0) {
- ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
- return -1;
- }
-
- res = bind(sd, sa, salen);
- if (res < 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
- close(sd);
- return 1;
- }
-
- close(sd);
- return 0;
-}
-
-/*! \brief Parse the "sourceaddress" value,
- lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
- not found. */
-static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
-{
- struct sockaddr_in sin;
- int nonlocal = 1;
- int port = IAX_DEFAULT_PORTNO;
- int sockfd = defaultsockfd;
- char *tmp;
- char *addr;
- char *portstr;
-
- if (!(tmp = ast_strdupa(srcaddr)))
- return -1;
-
- addr = strsep(&tmp, ":");
- portstr = tmp;
-
- if (portstr) {
- port = atoi(portstr);
- if (port < 1)
- port = IAX_DEFAULT_PORTNO;
- }
-
- if (!ast_get_ip(&sin, addr)) {
- struct ast_netsock *sock;
- int res;
-
- sin.sin_port = 0;
- sin.sin_family = AF_INET;
- res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
- if (res == 0) {
- /* ip address valid. */
- sin.sin_port = htons(port);
- if (!(sock = ast_netsock_find(netsock, &sin)))
- sock = ast_netsock_find(outsock, &sin);
- if (sock) {
- sockfd = ast_netsock_sockfd(sock);
- nonlocal = 0;
- } else {
- unsigned int orig_saddr = sin.sin_addr.s_addr;
- /* INADDR_ANY matches anyway! */
- sin.sin_addr.s_addr = INADDR_ANY;
- if (ast_netsock_find(netsock, &sin)) {
- sin.sin_addr.s_addr = orig_saddr;
- sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
- if (sock) {
- sockfd = ast_netsock_sockfd(sock);
- ast_netsock_unref(sock);
- nonlocal = 0;
- } else {
- nonlocal = 2;
- }
- }
- }
- }
- }
-
- peer->sockfd = sockfd;
-
- if (nonlocal == 1) {
- ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
- srcaddr, peer->name);
- return -1;
- } else if (nonlocal == 2) {
- ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
- srcaddr, peer->name);
- return -1;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
- return 0;
- }
-}
-
-static void peer_destructor(void *obj)
-{
- struct iax2_peer *peer = obj;
-
- ast_free_ha(peer->ha);
-
- if (peer->callno > 0) {
- ast_mutex_lock(&iaxsl[peer->callno]);
- iax2_destroy(peer->callno);
- ast_mutex_unlock(&iaxsl[peer->callno]);
- }
-
- register_peer_exten(peer, 0);
-
- if (peer->dnsmgr)
- ast_dnsmgr_release(peer->dnsmgr);
-
- ast_string_field_free_memory(peer);
-}
-
-/*! \brief Create peer structure based on configuration */
-static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
-{
- struct iax2_peer *peer = NULL;
- struct ast_ha *oldha = NULL;
- int maskfound=0;
- int found=0;
- int firstpass=1;
- struct iax2_peer tmp_peer = {
- .name = name,
- };
-
- if (!temponly) {
- peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
- if (peer && !ast_test_flag(peer, IAX_DELME))
- firstpass = 0;
- }
-
- if (peer) {
- found++;
- if (firstpass) {
- oldha = peer->ha;
- peer->ha = NULL;
- }
- unlink_peer(peer);
- } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
- peer->expire = -1;
- peer->pokeexpire = -1;
- peer->sockfd = defaultsockfd;
- if (ast_string_field_init(peer, 32))
- peer = peer_unref(peer);
- }
-
- if (peer) {
- if (firstpass) {
- ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
- peer->encmethods = iax2_encryption;
- peer->adsi = adsi;
- ast_string_field_set(peer,secret,"");
- if (!found) {
- ast_string_field_set(peer, name, name);
- peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
- peer->expiry = min_reg_expire;
- }
- peer->prefs = prefs;
- peer->capability = iax2_capability;
- peer->smoothing = 0;
- peer->pokefreqok = DEFAULT_FREQ_OK;
- peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
- ast_string_field_set(peer,context,"");
- ast_string_field_set(peer,peercontext,"");
- ast_clear_flag(peer, IAX_HASCALLERID);
- ast_string_field_set(peer, cid_name, "");
- ast_string_field_set(peer, cid_num, "");
- }
-
- if (!v) {
- v = alt;
- alt = NULL;
- }
- while(v) {
- if (!strcasecmp(v->name, "secret")) {
- ast_string_field_set(peer, secret, v->value);
- } else if (!strcasecmp(v->name, "mailbox")) {
- ast_string_field_set(peer, mailbox, v->value);
- } else if (!strcasecmp(v->name, "mohinterpret")) {
- ast_string_field_set(peer, mohinterpret, v->value);
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_string_field_set(peer, mohsuggest, v->value);
- } else if (!strcasecmp(v->name, "dbsecret")) {
- ast_string_field_set(peer, dbsecret, v->value);
- } else if (!strcasecmp(v->name, "trunk")) {
- ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
- if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
- ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
- ast_clear_flag(peer, IAX_TRUNK);
- }
- } else if (!strcasecmp(v->name, "auth")) {
- peer->authmethods = get_auth_methods(v->value);
- } else if (!strcasecmp(v->name, "encryption")) {
- peer->encmethods = get_encrypt_methods(v->value);
- } else if (!strcasecmp(v->name, "notransfer")) {
- ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
- ast_clear_flag(peer, IAX_TRANSFERMEDIA);
- ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
- } else if (!strcasecmp(v->name, "transfer")) {
- if (!strcasecmp(v->value, "mediaonly")) {
- ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
- } else if (ast_true(v->value)) {
- ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
- } else
- ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
- } else if (!strcasecmp(v->name, "jitterbuffer")) {
- ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
- } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
- ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
- } else if (!strcasecmp(v->name, "host")) {
- if (!strcasecmp(v->value, "dynamic")) {
- /* They'll register with us */
- ast_set_flag(peer, IAX_DYNAMIC);
- if (!found) {
- /* Initialize stuff iff we're not found, otherwise
- we keep going with what we had */
- memset(&peer->addr.sin_addr, 0, 4);
- if (peer->addr.sin_port) {
- /* If we've already got a port, make it the default rather than absolute */
- peer->defaddr.sin_port = peer->addr.sin_port;
- peer->addr.sin_port = 0;
- }
- }
- } else {
- /* Non-dynamic. Make sure we become that way if we're not */
- AST_SCHED_DEL(sched, peer->expire);
- ast_clear_flag(peer, IAX_DYNAMIC);
- if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
- return peer_unref(peer);
- if (!peer->addr.sin_port)
- peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
- }
- if (!maskfound)
- inet_aton("255.255.255.255", &peer->mask);
- } else if (!strcasecmp(v->name, "defaultip")) {
- if (ast_get_ip(&peer->defaddr, v->value))
- return peer_unref(peer);
- } else if (!strcasecmp(v->name, "sourceaddress")) {
- peer_set_srcaddr(peer, v->value);
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- peer->ha = ast_append_ha(v->name, v->value, peer->ha);
- } else if (!strcasecmp(v->name, "mask")) {
- maskfound++;
- inet_aton(v->value, &peer->mask);
- } else if (!strcasecmp(v->name, "context")) {
- ast_string_field_set(peer, context, v->value);
- } else if (!strcasecmp(v->name, "regexten")) {
- ast_string_field_set(peer, regexten, v->value);
- } else if (!strcasecmp(v->name, "peercontext")) {
- ast_string_field_set(peer, peercontext, v->value);
- } else if (!strcasecmp(v->name, "port")) {
- if (ast_test_flag(peer, IAX_DYNAMIC))
- peer->defaddr.sin_port = htons(atoi(v->value));
- else
- peer->addr.sin_port = htons(atoi(v->value));
- } else if (!strcasecmp(v->name, "username")) {
- ast_string_field_set(peer, username, v->value);
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
- } else if (!strcasecmp(v->name, "callerid")) {
- if (!ast_strlen_zero(v->value)) {
- char name2[80];
- char num2[80];
- ast_callerid_split(v->value, name2, 80, num2, 80);
- ast_string_field_set(peer, cid_name, name2);
- ast_string_field_set(peer, cid_num, num2);
- ast_set_flag(peer, IAX_HASCALLERID);
- } else {
- ast_clear_flag(peer, IAX_HASCALLERID);
- ast_string_field_set(peer, cid_name, "");
- ast_string_field_set(peer, cid_num, "");
- }
- } else if (!strcasecmp(v->name, "fullname")) {
- if (!ast_strlen_zero(v->value)) {
- ast_string_field_set(peer, cid_name, v->value);
- ast_set_flag(peer, IAX_HASCALLERID);
- } else {
- ast_string_field_set(peer, cid_name, "");
- if (ast_strlen_zero(peer->cid_num))
- ast_clear_flag(peer, IAX_HASCALLERID);
- }
- } else if (!strcasecmp(v->name, "cid_number")) {
- if (!ast_strlen_zero(v->value)) {
- ast_string_field_set(peer, cid_num, v->value);
- ast_set_flag(peer, IAX_HASCALLERID);
- } else {
- ast_string_field_set(peer, cid_num, "");
- if (ast_strlen_zero(peer->cid_name))
- ast_clear_flag(peer, IAX_HASCALLERID);
- }
- } else if (!strcasecmp(v->name, "sendani")) {
- ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
- } else if (!strcasecmp(v->name, "inkeys")) {
- ast_string_field_set(peer, inkeys, v->value);
- } else if (!strcasecmp(v->name, "outkey")) {
- ast_string_field_set(peer, outkey, v->value);
- } else if (!strcasecmp(v->name, "qualify")) {
- if (!strcasecmp(v->value, "no")) {
- peer->maxms = 0;
- } else if (!strcasecmp(v->value, "yes")) {
- peer->maxms = DEFAULT_MAXMS;
- } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
- ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
- peer->maxms = 0;
- }
- } else if (!strcasecmp(v->name, "qualifysmoothing")) {
- peer->smoothing = ast_true(v->value);
- } else if (!strcasecmp(v->name, "qualifyfreqok")) {
- if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
- ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when OK should a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
- }
- } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
- if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
- ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when NOT OK should be a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
- } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
- } else if (!strcasecmp(v->name, "timezone")) {
- ast_string_field_set(peer, zonetag, v->value);
- } else if (!strcasecmp(v->name, "adsi")) {
- peer->adsi = ast_true(v->value);
- }/* else if (strcasecmp(v->name,"type")) */
- /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
- v = v->next;
- if (!v) {
- v = alt;
- alt = NULL;
- }
- }
- if (!peer->authmethods)
- peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
- ast_clear_flag(peer, IAX_DELME);
- /* Make sure these are IPv4 addresses */
- peer->addr.sin_family = AF_INET;
- }
- if (oldha)
- ast_free_ha(oldha);
- return peer;
-}
-
-static void user_destructor(void *obj)
-{
- struct iax2_user *user = obj;
-
- ast_free_ha(user->ha);
- free_context(user->contexts);
- if(user->vars) {
- ast_variables_destroy(user->vars);
- user->vars = NULL;
- }
- ast_string_field_free_memory(user);
-}
-
-/*! \brief Create in-memory user structure from configuration */
-static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
-{
- struct iax2_user *user = NULL;
- struct iax2_context *con, *conl = NULL;
- struct ast_ha *oldha = NULL;
- struct iax2_context *oldcon = NULL;
- int format;
- int firstpass=1;
- int oldcurauthreq = 0;
- char *varname = NULL, *varval = NULL;
- struct ast_variable *tmpvar = NULL;
- struct iax2_user tmp_user = {
- .name = name,
- };
-
- if (!temponly) {
- user = ao2_find(users, &tmp_user, OBJ_POINTER);
- if (user && !ast_test_flag(user, IAX_DELME))
- firstpass = 0;
- }
-
- if (user) {
- if (firstpass) {
- oldcurauthreq = user->curauthreq;
- oldha = user->ha;
- oldcon = user->contexts;
- user->ha = NULL;
- user->contexts = NULL;
- }
- /* Already in the list, remove it and it will be added back (or FREE'd) */
- ao2_unlink(users, user);
- } else {
- user = ao2_alloc(sizeof(*user), user_destructor);
- }
-
- if (user) {
- if (firstpass) {
- ast_string_field_free_memory(user);
- memset(user, 0, sizeof(struct iax2_user));
- if (ast_string_field_init(user, 32)) {
- user = user_unref(user);
- goto cleanup;
- }
- user->maxauthreq = maxauthreq;
- user->curauthreq = oldcurauthreq;
- user->prefs = prefs;
- user->capability = iax2_capability;
- user->encmethods = iax2_encryption;
- user->adsi = adsi;
- ast_string_field_set(user, name, name);
- ast_string_field_set(user, language, language);
- ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
- ast_clear_flag(user, IAX_HASCALLERID);
- ast_string_field_set(user, cid_name, "");
- ast_string_field_set(user, cid_num, "");
- }
- if (!v) {
- v = alt;
- alt = NULL;
- }
- while(v) {
- if (!strcasecmp(v->name, "context")) {
- con = build_context(v->value);
- if (con) {
- if (conl)
- conl->next = con;
- else
- user->contexts = con;
- conl = con;
- }
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- user->ha = ast_append_ha(v->name, v->value, user->ha);
- } else if (!strcasecmp(v->name, "setvar")) {
- varname = ast_strdupa(v->value);
- if (varname && (varval = strchr(varname,'='))) {
- *varval = '\0';
- varval++;
- if((tmpvar = ast_variable_new(varname, varval))) {
- tmpvar->next = user->vars;
- user->vars = tmpvar;
- }
- }
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
- } else if (!strcasecmp(v->name, "trunk")) {
- ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
- if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
- ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
- ast_clear_flag(user, IAX_TRUNK);
- }
- } else if (!strcasecmp(v->name, "auth")) {
- user->authmethods = get_auth_methods(v->value);
- } else if (!strcasecmp(v->name, "encryption")) {
- user->encmethods = get_encrypt_methods(v->value);
- } else if (!strcasecmp(v->name, "notransfer")) {
- ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
- ast_clear_flag(user, IAX_TRANSFERMEDIA);
- ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
- } else if (!strcasecmp(v->name, "transfer")) {
- if (!strcasecmp(v->value, "mediaonly")) {
- ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
- } else if (ast_true(v->value)) {
- ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
- } else
- ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
- } else if (!strcasecmp(v->name, "codecpriority")) {
- if(!strcasecmp(v->value, "caller"))
- ast_set_flag(user, IAX_CODEC_USER_FIRST);
- else if(!strcasecmp(v->value, "disabled"))
- ast_set_flag(user, IAX_CODEC_NOPREFS);
- else if(!strcasecmp(v->value, "reqonly")) {
- ast_set_flag(user, IAX_CODEC_NOCAP);
- ast_set_flag(user, IAX_CODEC_NOPREFS);
- }
- } else if (!strcasecmp(v->name, "jitterbuffer")) {
- ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
- } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
- ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
- } else if (!strcasecmp(v->name, "dbsecret")) {
- ast_string_field_set(user, dbsecret, v->value);
- } else if (!strcasecmp(v->name, "secret")) {
- if (!ast_strlen_zero(user->secret)) {
- char *old = ast_strdupa(user->secret);
-
- ast_string_field_build(user, secret, "%s;%s", old, v->value);
- } else
- ast_string_field_set(user, secret, v->value);
- } else if (!strcasecmp(v->name, "callerid")) {
- if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
- char name2[80];
- char num2[80];
- ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
- ast_string_field_set(user, cid_name, name2);
- ast_string_field_set(user, cid_num, num2);
- ast_set_flag(user, IAX_HASCALLERID);
- } else {
- ast_clear_flag(user, IAX_HASCALLERID);
- ast_string_field_set(user, cid_name, "");
- ast_string_field_set(user, cid_num, "");
- }
- } else if (!strcasecmp(v->name, "fullname")) {
- if (!ast_strlen_zero(v->value)) {
- ast_string_field_set(user, cid_name, v->value);
- ast_set_flag(user, IAX_HASCALLERID);
- } else {
- ast_string_field_set(user, cid_name, "");
- if (ast_strlen_zero(user->cid_num))
- ast_clear_flag(user, IAX_HASCALLERID);
- }
- } else if (!strcasecmp(v->name, "cid_number")) {
- if (!ast_strlen_zero(v->value)) {
- ast_string_field_set(user, cid_num, v->value);
- ast_set_flag(user, IAX_HASCALLERID);
- } else {
- ast_string_field_set(user, cid_num, "");
- if (ast_strlen_zero(user->cid_name))
- ast_clear_flag(user, IAX_HASCALLERID);
- }
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_string_field_set(user, accountcode, v->value);
- } else if (!strcasecmp(v->name, "mohinterpret")) {
- ast_string_field_set(user, mohinterpret, v->value);
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_string_field_set(user, mohsuggest, v->value);
- } else if (!strcasecmp(v->name, "language")) {
- ast_string_field_set(user, language, v->value);
- } else if (!strcasecmp(v->name, "amaflags")) {
- format = ast_cdr_amaflags2int(v->value);
- if (format < 0) {
- ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
- } else {
- user->amaflags = format;
- }
- } else if (!strcasecmp(v->name, "inkeys")) {
- ast_string_field_set(user, inkeys, v->value);
- } else if (!strcasecmp(v->name, "maxauthreq")) {
- user->maxauthreq = atoi(v->value);
- if (user->maxauthreq < 0)
- user->maxauthreq = 0;
- } else if (!strcasecmp(v->name, "adsi")) {
- user->adsi = ast_true(v->value);
- }/* else if (strcasecmp(v->name,"type")) */
- /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
- v = v->next;
- if (!v) {
- v = alt;
- alt = NULL;
- }
- }
- if (!user->authmethods) {
- if (!ast_strlen_zero(user->secret)) {
- user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
- if (!ast_strlen_zero(user->inkeys))
- user->authmethods |= IAX_AUTH_RSA;
- } else if (!ast_strlen_zero(user->inkeys)) {
- user->authmethods = IAX_AUTH_RSA;
- } else {
- user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
- }
- }
- ast_clear_flag(user, IAX_DELME);
- }
-cleanup:
- if (oldha)
- ast_free_ha(oldha);
- if (oldcon)
- free_context(oldcon);
- return user;
-}
-
-static int peer_delme_cb(void *obj, void *arg, int flags)
-{
- struct iax2_peer *peer = obj;
-
- ast_set_flag(peer, IAX_DELME);
-
- return 0;
-}
-
-static int user_delme_cb(void *obj, void *arg, int flags)
-{
- struct iax2_user *user = obj;
-
- ast_set_flag(user, IAX_DELME);
-
- return 0;
-}
-
-static void delete_users(void)
-{
- struct iax2_registry *reg;
-
- ao2_callback(users, 0, user_delme_cb, NULL);
-
- AST_LIST_LOCK(&registrations);
- while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
- ast_sched_del(sched, reg->expire);
- if (reg->callno) {
- ast_mutex_lock(&iaxsl[reg->callno]);
- if (iaxs[reg->callno]) {
- iaxs[reg->callno]->reg = NULL;
- iax2_destroy(reg->callno);
- }
- ast_mutex_unlock(&iaxsl[reg->callno]);
- }
- if (reg->dnsmgr)
- ast_dnsmgr_release(reg->dnsmgr);
- free(reg);
- }
- AST_LIST_UNLOCK(&registrations);
-
- ao2_callback(peers, 0, peer_delme_cb, NULL);
-}
-
-static void prune_users(void)
-{
- struct iax2_user *user;
- struct ao2_iterator i;
-
- i = ao2_iterator_init(users, 0);
- while ((user = ao2_iterator_next(&i))) {
- if (ast_test_flag(user, IAX_DELME))
- ao2_unlink(users, user);
- user_unref(user);
- }
-}
-
-/* Prune peers who still are supposed to be deleted */
-static void prune_peers(void)
-{
- struct iax2_peer *peer;
- struct ao2_iterator i;
-
- i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
- if (ast_test_flag(peer, IAX_DELME))
- unlink_peer(peer);
- peer_unref(peer);
- }
-}
-
-static void set_timing(void)
-{
-#ifdef HAVE_ZAPTEL
- int bs = trunkfreq * 8;
- if (timingfd > -1) {
- if (
-#ifdef ZT_TIMERACK
- ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
-#endif
- ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
- ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
- }
-#endif
-}
-
-static void set_config_destroy(void)
-{
- strcpy(accountcode, "");
- strcpy(language, "");
- strcpy(mohinterpret, "default");
- strcpy(mohsuggest, "");
- amaflags = 0;
- delayreject = 0;
- ast_clear_flag((&globalflags), IAX_NOTRANSFER);
- ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
- ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
- ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
- delete_users();
-}
-
-/*! \brief Load configuration */
-static int set_config(char *config_file, int reload)
-{
- struct ast_config *cfg, *ucfg;
- int capability=iax2_capability;
- struct ast_variable *v;
- char *cat;
- const char *utype;
- const char *tosval;
- int format;
- int portno = IAX_DEFAULT_PORTNO;
- int x;
- struct iax2_user *user;
- struct iax2_peer *peer;
- struct ast_netsock *ns;
-#if 0
- static unsigned short int last_port=0;
-#endif
-
- cfg = ast_config_load(config_file);
-
- if (!cfg) {
- ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
- return -1;
- }
-
- if (reload) {
- set_config_destroy();
- }
-
- /* Reset global codec prefs */
- memset(&prefs, 0 , sizeof(struct ast_codec_pref));
-
- /* Reset Global Flags */
- memset(&globalflags, 0, sizeof(globalflags));
- ast_set_flag(&globalflags, IAX_RTUPDATE);
-
-#ifdef SO_NO_CHECK
- nochecksums = 0;
-#endif
-
- min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
- max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
-
- maxauthreq = 3;
-
- v = ast_variable_browse(cfg, "general");
-
- /* Seed initial tos value */
- tosval = ast_variable_retrieve(cfg, "general", "tos");
- if (tosval) {
- if (ast_str2tos(tosval, &tos))
- ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
- }
- while(v) {
- if (!strcasecmp(v->name, "bindport")){
- if (reload)
- ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
- else
- portno = atoi(v->value);
- } else if (!strcasecmp(v->name, "pingtime"))
- ping_time = atoi(v->value);
- else if (!strcasecmp(v->name, "iaxthreadcount")) {
- if (reload) {
- if (atoi(v->value) != iaxthreadcount)
- ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
- } else {
- iaxthreadcount = atoi(v->value);
- if (iaxthreadcount < 1) {
- ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
- iaxthreadcount = 1;
- } else if (iaxthreadcount > 256) {
- ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
- iaxthreadcount = 256;
- }
- }
- } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
- if (reload) {
- AST_LIST_LOCK(&dynamic_list);
- iaxmaxthreadcount = atoi(v->value);
- AST_LIST_UNLOCK(&dynamic_list);
- } else {
- iaxmaxthreadcount = atoi(v->value);
- if (iaxmaxthreadcount < 0) {
- ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
- iaxmaxthreadcount = 0;
- } else if (iaxmaxthreadcount > 256) {
- ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
- iaxmaxthreadcount = 256;
- }
- }
- } else if (!strcasecmp(v->name, "nochecksums")) {
-#ifdef SO_NO_CHECK
- if (ast_true(v->value))
- nochecksums = 1;
- else
- nochecksums = 0;
-#else
- if (ast_true(v->value))
- ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
-#endif
- }
- else if (!strcasecmp(v->name, "maxjitterbuffer"))
- maxjitterbuffer = atoi(v->value);
- else if (!strcasecmp(v->name, "resyncthreshold"))
- resyncthreshold = atoi(v->value);
- else if (!strcasecmp(v->name, "maxjitterinterps"))
- maxjitterinterps = atoi(v->value);
- else if (!strcasecmp(v->name, "lagrqtime"))
- lagrq_time = atoi(v->value);
- else if (!strcasecmp(v->name, "maxregexpire"))
- max_reg_expire = atoi(v->value);
- else if (!strcasecmp(v->name, "minregexpire"))
- min_reg_expire = atoi(v->value);
- else if (!strcasecmp(v->name, "bindaddr")) {
- if (reload) {
- ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
- } else {
- if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
- ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
- } else {
- if (option_verbose > 1) {
- if (strchr(v->value, ':'))
- ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
- else
- ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
- }
- if (defaultsockfd < 0)
- defaultsockfd = ast_netsock_sockfd(ns);
- ast_netsock_unref(ns);
- }
- }
- } else if (!strcasecmp(v->name, "authdebug"))
- authdebug = ast_true(v->value);
- else if (!strcasecmp(v->name, "encryption"))
- iax2_encryption = get_encrypt_methods(v->value);
- else if (!strcasecmp(v->name, "notransfer")) {
- ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
- ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
- ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
- } else if (!strcasecmp(v->name, "transfer")) {
- if (!strcasecmp(v->value, "mediaonly")) {
- ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
- } else if (ast_true(v->value)) {
- ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
- } else
- ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
- } else if (!strcasecmp(v->name, "codecpriority")) {
- if(!strcasecmp(v->value, "caller"))
- ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
- else if(!strcasecmp(v->value, "disabled"))
- ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
- else if(!strcasecmp(v->value, "reqonly")) {
- ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
- ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
- }
- } else if (!strcasecmp(v->name, "jitterbuffer"))
- ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
- else if (!strcasecmp(v->name, "forcejitterbuffer"))
- ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
- else if (!strcasecmp(v->name, "delayreject"))
- delayreject = ast_true(v->value);
- else if (!strcasecmp(v->name, "rtcachefriends"))
- ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
- else if (!strcasecmp(v->name, "rtignoreregexpire"))
- ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
- else if (!strcasecmp(v->name, "rtupdate"))
- ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
- else if (!strcasecmp(v->name, "trunktimestamps"))
- ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
- else if (!strcasecmp(v->name, "rtautoclear")) {
- int i = atoi(v->value);
- if(i > 0)
- global_rtautoclear = i;
- else
- i = 0;
- ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
- } else if (!strcasecmp(v->name, "trunkfreq")) {
- trunkfreq = atoi(v->value);
- if (trunkfreq < 10)
- trunkfreq = 10;
- } else if (!strcasecmp(v->name, "autokill")) {
- if (sscanf(v->value, "%d", &x) == 1) {
- if (x >= 0)
- autokill = x;
- else
- ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
- } else if (ast_true(v->value)) {
- autokill = DEFAULT_MAXMS;
- } else {
- autokill = 0;
- }
- } else if (!strcasecmp(v->name, "bandwidth")) {
- if (!strcasecmp(v->value, "low")) {
- capability = IAX_CAPABILITY_LOWBANDWIDTH;
- } else if (!strcasecmp(v->value, "medium")) {
- capability = IAX_CAPABILITY_MEDBANDWIDTH;
- } else if (!strcasecmp(v->value, "high")) {
- capability = IAX_CAPABILITY_FULLBANDWIDTH;
- } else
- ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
- } else if (!strcasecmp(v->name, "register")) {
- iax2_register(v->value, v->lineno);
- } else if (!strcasecmp(v->name, "iaxcompat")) {
- iaxcompat = ast_true(v->value);
- } else if (!strcasecmp(v->name, "regcontext")) {
- ast_copy_string(regcontext, v->value, sizeof(regcontext));
- /* Create context if it doesn't exist already */
- if (!ast_context_find(regcontext))
- ast_context_create(NULL, regcontext, "IAX2");
- } else if (!strcasecmp(v->name, "tos")) {
- if (ast_str2tos(v->value, &tos))
- ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(accountcode, v->value, sizeof(accountcode));
- } else if (!strcasecmp(v->name, "mohinterpret")) {
- ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
- } else if (!strcasecmp(v->name, "amaflags")) {
- format = ast_cdr_amaflags2int(v->value);
- if (format < 0) {
- ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
- } else {
- amaflags = format;
- }
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(language, v->value, sizeof(language));
- } else if (!strcasecmp(v->name, "maxauthreq")) {
- maxauthreq = atoi(v->value);
- if (maxauthreq < 0)
- maxauthreq = 0;
- } else if (!strcasecmp(v->name, "adsi")) {
- adsi = ast_true(v->value);
- } /*else if (strcasecmp(v->name,"type")) */
- /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
- v = v->next;
- }
-
- if (defaultsockfd < 0) {
- if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
- ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
- } else {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
- defaultsockfd = ast_netsock_sockfd(ns);
- ast_netsock_unref(ns);
- }
- }
- if (reload) {
- ast_netsock_release(outsock);
- outsock = ast_netsock_list_alloc();
- if (!outsock) {
- ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
- return -1;
- }
- ast_netsock_init(outsock);
- }
-
- if (min_reg_expire > max_reg_expire) {
- ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
- min_reg_expire, max_reg_expire, max_reg_expire);
- min_reg_expire = max_reg_expire;
- }
- iax2_capability = capability;
-
- ucfg = ast_config_load("users.conf");
- if (ucfg) {
- struct ast_variable *gen;
- int genhasiax;
- int genregisteriax;
- const char *hasiax, *registeriax;
-
- genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
- genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
- gen = ast_variable_browse(ucfg, "general");
- cat = ast_category_browse(ucfg, NULL);
- while (cat) {
- if (strcasecmp(cat, "general")) {
- hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
- registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
- if (ast_true(hasiax) || (!hasiax && genhasiax)) {
- /* Start with general parameters, then specific parameters, user and peer */
- user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
- if (user) {
- __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
- user = user_unref(user);
- }
- peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
- if (peer) {
- if (ast_test_flag(peer, IAX_DYNAMIC))
- reg_source_db(peer);
- __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
- peer = peer_unref(peer);
- }
- }
- if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
- char tmp[256];
- const char *host = ast_variable_retrieve(ucfg, cat, "host");
- const char *username = ast_variable_retrieve(ucfg, cat, "username");
- const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
- if (!host)
- host = ast_variable_retrieve(ucfg, "general", "host");
- if (!username)
- username = ast_variable_retrieve(ucfg, "general", "username");
- if (!secret)
- secret = ast_variable_retrieve(ucfg, "general", "secret");
- if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
- if (!ast_strlen_zero(secret))
- snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
- else
- snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
- iax2_register(tmp, 0);
- }
- }
- }
- cat = ast_category_browse(ucfg, cat);
- }
- ast_config_destroy(ucfg);
- }
-
- cat = ast_category_browse(cfg, NULL);
- while(cat) {
- if (strcasecmp(cat, "general")) {
- utype = ast_variable_retrieve(cfg, cat, "type");
- if (utype) {
- if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
- user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (user) {
- __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
- user = user_unref(user);
- }
- }
- if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
- peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (peer) {
- if (ast_test_flag(peer, IAX_DYNAMIC))
- reg_source_db(peer);
- __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
- peer = peer_unref(peer);
- }
- } else if (strcasecmp(utype, "user")) {
- ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
- }
- } else
- ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
- }
- cat = ast_category_browse(cfg, cat);
- }
- ast_config_destroy(cfg);
- set_timing();
- return 1;
-}
-
-static void poke_all_peers(void)
-{
- struct ao2_iterator i;
- struct iax2_peer *peer;
-
- i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
- iax2_poke_peer(peer, 0);
- peer_unref(peer);
- }
-}
-static int reload_config(void)
-{
- char *config = "iax.conf";
- struct iax2_registry *reg;
-
- if (set_config(config, 1) > 0) {
- prune_peers();
- prune_users();
- AST_LIST_LOCK(&registrations);
- AST_LIST_TRAVERSE(&registrations, reg, entry)
- iax2_do_register(reg);
- AST_LIST_UNLOCK(&registrations);
- /* Qualify hosts, too */
- poke_all_peers();
- }
- reload_firmware(0);
- iax_provision_reload();
-
- return 0;
-}
-
-static int iax2_reload(int fd, int argc, char *argv[])
-{
- return reload_config();
-}
-
-static int reload(void)
-{
- return reload_config();
-}
-
-static int cache_get_callno_locked(const char *data)
-{
- struct sockaddr_in sin;
- int x;
- int callno;
- struct iax_ie_data ied;
- struct create_addr_info cai;
- struct parsed_dial_string pds;
- char *tmpstr;
-
- for (x = 0; x < ARRAY_LEN(iaxs); x++) {
- /* Look for an *exact match* call. Once a call is negotiated, it can only
- look up entries for a single context */
- if (!ast_mutex_trylock(&iaxsl[x])) {
- if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
- return x;
- ast_mutex_unlock(&iaxsl[x]);
- }
- }
-
- /* No match found, we need to create a new one */
-
- memset(&cai, 0, sizeof(cai));
- memset(&ied, 0, sizeof(ied));
- memset(&pds, 0, sizeof(pds));
-
- tmpstr = ast_strdupa(data);
- parse_dial_string(tmpstr, &pds);
-
- if (ast_strlen_zero(pds.peer)) {
- ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
- return -1;
- }
-
- /* Populate our address from the given */
- if (create_addr(pds.peer, NULL, &sin, &cai))
- return -1;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
- pds.peer, pds.username, pds.password, pds.context);
-
- callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
- if (callno < 1) {
- ast_log(LOG_WARNING, "Unable to create call\n");
- return -1;
- }
-
- ast_string_field_set(iaxs[callno], dproot, data);
- iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
-
- iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
- iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
- /* the string format is slightly different from a standard dial string,
- because the context appears in the 'exten' position
- */
- if (pds.exten)
- iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
- if (pds.username)
- iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
- iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
- iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
- /* Keep password handy */
- if (pds.password)
- ast_string_field_set(iaxs[callno], secret, pds.password);
- if (pds.key)
- ast_string_field_set(iaxs[callno], outkey, pds.key);
- /* Start the call going */
- send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
-
- return callno;
-}
-
-static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
-{
- struct iax2_dpcache *dp, *prev = NULL, *next;
- struct timeval tv;
- int x;
- int com[2];
- int timeout;
- int old=0;
- int outfd;
- int abort;
- int callno;
- struct ast_channel *c;
- struct ast_frame *f;
- gettimeofday(&tv, NULL);
- dp = dpcache;
- while(dp) {
- next = dp->next;
- /* Expire old caches */
- if (ast_tvcmp(tv, dp->expiry) > 0) {
- /* It's expired, let it disappear */
- if (prev)
- prev->next = dp->next;
- else
- dpcache = dp->next;
- if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
- /* Free memory and go again */
- free(dp);
- } else {
- ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
- }
- dp = next;
- continue;
- }
- /* We found an entry that matches us! */
- if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
- break;
- prev = dp;
- dp = next;
- }
- if (!dp) {
- /* No matching entry. Create a new one. */
- /* First, can we make a callno? */
- callno = cache_get_callno_locked(data);
- if (callno < 0) {
- ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
- return NULL;
- }
- if (!(dp = ast_calloc(1, sizeof(*dp)))) {
- ast_mutex_unlock(&iaxsl[callno]);
- return NULL;
- }
- ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
- ast_copy_string(dp->exten, exten, sizeof(dp->exten));
- gettimeofday(&dp->expiry, NULL);
- dp->orig = dp->expiry;
- /* Expires in 30 mins by default */
- dp->expiry.tv_sec += iaxdefaultdpcache;
- dp->next = dpcache;
- dp->flags = CACHE_FLAG_PENDING;
- for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
- dp->waiters[x] = -1;
- dpcache = dp;
- dp->peer = iaxs[callno]->dpentries;
- iaxs[callno]->dpentries = dp;
- /* Send the request if we're already up */
- if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
- iax2_dprequest(dp, callno);
- ast_mutex_unlock(&iaxsl[callno]);
- }
- /* By here we must have a dp */
- if (dp->flags & CACHE_FLAG_PENDING) {
- /* Okay, here it starts to get nasty. We need a pipe now to wait
- for a reply to come back so long as it's pending */
- for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
- /* Find an empty slot */
- if (dp->waiters[x] < 0)
- break;
- }
- if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
- ast_log(LOG_WARNING, "No more waiter positions available\n");
- return NULL;
- }
- if (pipe(com)) {
- ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
- return NULL;
- }
- dp->waiters[x] = com[1];
- /* Okay, now we wait */
- timeout = iaxdefaulttimeout * 1000;
- /* Temporarily unlock */
- ast_mutex_unlock(&dpcache_lock);
- /* Defer any dtmf */
- if (chan)
- old = ast_channel_defer_dtmf(chan);
- abort = 0;
- while(timeout) {
- c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
- if (outfd > -1) {
- break;
- }
- if (c) {
- f = ast_read(c);
- if (f)
- ast_frfree(f);
- else {
- /* Got hung up on, abort! */
- break;
- abort = 1;
- }
- }
- }
- if (!timeout) {
- ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
- }
- ast_mutex_lock(&dpcache_lock);
- dp->waiters[x] = -1;
- close(com[1]);
- close(com[0]);
- if (abort) {
- /* Don't interpret anything, just abort. Not sure what th epoint
- of undeferring dtmf on a hung up channel is but hey whatever */
- if (!old && chan)
- ast_channel_undefer_dtmf(chan);
- return NULL;
- }
- if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
- /* Now to do non-independent analysis the results of our wait */
- if (dp->flags & CACHE_FLAG_PENDING) {
- /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
- pending. Don't let it take as long to timeout. */
- dp->flags &= ~CACHE_FLAG_PENDING;
- dp->flags |= CACHE_FLAG_TIMEOUT;
- /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
- systems without leaving it unavailable once the server comes back online */
- dp->expiry.tv_sec = dp->orig.tv_sec + 60;
- for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
- if (dp->waiters[x] > -1)
- write(dp->waiters[x], "asdf", 4);
- }
- }
- /* Our caller will obtain the rest */
- if (!old && chan)
- ast_channel_undefer_dtmf(chan);
- }
- return dp;
-}
-
-/*! \brief Part of the IAX2 switch interface */
-static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- struct iax2_dpcache *dp;
- int res = 0;
-#if 0
- ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
-#endif
- if ((priority != 1) && (priority != 2))
- return 0;
- ast_mutex_lock(&dpcache_lock);
- dp = find_cache(chan, data, context, exten, priority);
- if (dp) {
- if (dp->flags & CACHE_FLAG_EXISTS)
- res= 1;
- }
- ast_mutex_unlock(&dpcache_lock);
- if (!dp) {
- ast_log(LOG_WARNING, "Unable to make DP cache\n");
- }
- return res;
-}
-
-/*! \brief part of the IAX2 dial plan switch interface */
-static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- int res = 0;
- struct iax2_dpcache *dp;
-#if 0
- ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
-#endif
- if ((priority != 1) && (priority != 2))
- return 0;
- ast_mutex_lock(&dpcache_lock);
- dp = find_cache(chan, data, context, exten, priority);
- if (dp) {
- if (dp->flags & CACHE_FLAG_CANEXIST)
- res= 1;
- }
- ast_mutex_unlock(&dpcache_lock);
- if (!dp) {
- ast_log(LOG_WARNING, "Unable to make DP cache\n");
- }
- return res;
-}
-
-/*! \brief Part of the IAX2 Switch interface */
-static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- int res = 0;
- struct iax2_dpcache *dp;
-#if 0
- ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
-#endif
- if ((priority != 1) && (priority != 2))
- return 0;
- ast_mutex_lock(&dpcache_lock);
- dp = find_cache(chan, data, context, exten, priority);
- if (dp) {
- if (dp->flags & CACHE_FLAG_MATCHMORE)
- res= 1;
- }
- ast_mutex_unlock(&dpcache_lock);
- if (!dp) {
- ast_log(LOG_WARNING, "Unable to make DP cache\n");
- }
- return res;
-}
-
-/*! \brief Execute IAX2 dialplan switch */
-static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- char odata[256];
- char req[256];
- char *ncontext;
- struct iax2_dpcache *dp;
- struct ast_app *dial;
-#if 0
- ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack);
-#endif
- if (priority == 2) {
- /* Indicate status, can be overridden in dialplan */
- const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
- if (dialstatus) {
- dial = pbx_findapp(dialstatus);
- if (dial)
- pbx_exec(chan, dial, "");
- }
- return -1;
- } else if (priority != 1)
- return -1;
- ast_mutex_lock(&dpcache_lock);
- dp = find_cache(chan, data, context, exten, priority);
- if (dp) {
- if (dp->flags & CACHE_FLAG_EXISTS) {
- ast_copy_string(odata, data, sizeof(odata));
- ncontext = strchr(odata, '/');
- if (ncontext) {
- *ncontext = '\0';
- ncontext++;
- snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
- } else {
- snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
- } else {
- ast_mutex_unlock(&dpcache_lock);
- ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
- return -1;
- }
- }
- ast_mutex_unlock(&dpcache_lock);
- dial = pbx_findapp("Dial");
- if (dial) {
- return pbx_exec(chan, dial, req);
- } else {
- ast_log(LOG_WARNING, "No dial application registered\n");
- }
- return -1;
-}
-
-static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct iax2_peer *peer;
- char *peername, *colname;
-
- peername = ast_strdupa(data);
-
- /* if our channel, return the IP address of the endpoint of current channel */
- if (!strcmp(peername,"CURRENTCHANNEL")) {
- unsigned short callno;
- if (chan->tech != &iax2_tech)
- return -1;
- callno = PTR_TO_CALLNO(chan->tech_pvt);
- ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
- return 0;
- }
-
- if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
- *colname++ = '\0';
- else if ((colname = strchr(peername, '|')))
- *colname++ = '\0';
- else
- colname = "ip";
-
- if (!(peer = find_peer(peername, 1)))
- return -1;
-
- if (!strcasecmp(colname, "ip")) {
- ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
- } else if (!strcasecmp(colname, "status")) {
- peer_status(peer, buf, len);
- } else if (!strcasecmp(colname, "mailbox")) {
- ast_copy_string(buf, peer->mailbox, len);
- } else if (!strcasecmp(colname, "context")) {
- ast_copy_string(buf, peer->context, len);
- } else if (!strcasecmp(colname, "expire")) {
- snprintf(buf, len, "%d", peer->expire);
- } else if (!strcasecmp(colname, "dynamic")) {
- ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
- } else if (!strcasecmp(colname, "callerid_name")) {
- ast_copy_string(buf, peer->cid_name, len);
- } else if (!strcasecmp(colname, "callerid_num")) {
- ast_copy_string(buf, peer->cid_num, len);
- } else if (!strcasecmp(colname, "codecs")) {
- ast_getformatname_multiple(buf, len -1, peer->capability);
- } else if (!strncasecmp(colname, "codec[", 6)) {
- char *codecnum, *ptr;
- int index = 0, codec = 0;
-
- codecnum = strchr(colname, '[');
- *codecnum = '\0';
- codecnum++;
- if ((ptr = strchr(codecnum, ']'))) {
- *ptr = '\0';
- }
- index = atoi(codecnum);
- if((codec = ast_codec_pref_index(&peer->prefs, index))) {
- ast_copy_string(buf, ast_getformatname(codec), len);
- }
- }
-
- peer_unref(peer);
-
- return 0;
-}
-
-struct ast_custom_function iaxpeer_function = {
- .name = "IAXPEER",
- .synopsis = "Gets IAX peer information",
- .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
- .read = function_iaxpeer,
- .desc = "If peername specified, valid items are:\n"
- "- ip (default) The IP address.\n"
- "- status The peer's status (if qualify=yes)\n"
- "- mailbox The configured mailbox.\n"
- "- context The configured context.\n"
- "- expire The epoch time of the next expire.\n"
- "- dynamic Is it dynamic? (yes/no).\n"
- "- callerid_name The configured Caller ID name.\n"
- "- callerid_num The configured Caller ID number.\n"
- "- codecs The configured codecs.\n"
- "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
- "\n"
- "If CURRENTCHANNEL specified, returns IP address of current channel\n"
- "\n"
-};
-
-
-/*! \brief Part of the device state notification system ---*/
-static int iax2_devicestate(void *data)
-{
- struct parsed_dial_string pds;
- char *tmp = ast_strdupa(data);
- struct iax2_peer *p;
- int res = AST_DEVICE_INVALID;
-
- memset(&pds, 0, sizeof(pds));
- parse_dial_string(tmp, &pds);
-
- if (ast_strlen_zero(pds.peer)) {
- ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
- return res;
- }
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
-
- /* SLD: FIXME: second call to find_peer during registration */
- if (!(p = find_peer(pds.peer, 1)))
- return res;
-
- res = AST_DEVICE_UNAVAILABLE;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
- pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
-
- if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
- (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
- /* Peer is registered, or have default IP address
- and a valid registration */
- if (p->historicms == 0 || p->historicms <= p->maxms)
- /* let the core figure out whether it is in use or not */
- res = AST_DEVICE_UNKNOWN;
- }
-
- peer_unref(p);
-
- return res;
-}
-
-static struct ast_switch iax2_switch =
-{
- name: "IAX2",
- description: "IAX Remote Dialplan Switch",
- exists: iax2_exists,
- canmatch: iax2_canmatch,
- exec: iax2_exec,
- matchmore: iax2_matchmore,
-};
-
-static char show_stats_usage[] =
-"Usage: iax2 show stats\n"
-" Display statistics on IAX channel driver.\n";
-
-static char show_cache_usage[] =
-"Usage: iax2 show cache\n"
-" Display currently cached IAX Dialplan results.\n";
-
-static char show_peer_usage[] =
-"Usage: iax2 show peer <name>\n"
-" Display details on specific IAX peer\n";
-
-static char prune_realtime_usage[] =
-"Usage: iax2 prune realtime [<peername>|all]\n"
-" Prunes object(s) from the cache\n";
-
-static char iax2_reload_usage[] =
-"Usage: iax2 reload\n"
-" Reloads IAX configuration from iax.conf\n";
-
-static char show_prov_usage[] =
-"Usage: iax2 provision <host> <template> [forced]\n"
-" Provisions the given peer or IP address using a template\n"
-" matching either 'template' or '*' if the template is not\n"
-" found. If 'forced' is specified, even empty provisioning\n"
-" fields will be provisioned as empty fields.\n";
-
-static char show_users_usage[] =
-"Usage: iax2 show users [like <pattern>]\n"
-" Lists all known IAX2 users.\n"
-" Optional regular expression pattern is used to filter the user list.\n";
-
-static char show_channels_usage[] =
-"Usage: iax2 show channels\n"
-" Lists all currently active IAX channels.\n";
-
-static char show_netstats_usage[] =
-"Usage: iax2 show netstats\n"
-" Lists network status for all currently active IAX channels.\n";
-
-static char show_threads_usage[] =
-"Usage: iax2 show threads\n"
-" Lists status of IAX helper threads\n";
-
-static char show_peers_usage[] =
-"Usage: iax2 show peers [registered] [like <pattern>]\n"
-" Lists all known IAX2 peers.\n"
-" Optional 'registered' argument lists only peers with known addresses.\n"
-" Optional regular expression pattern is used to filter the peer list.\n";
-
-static char show_firmware_usage[] =
-"Usage: iax2 show firmware\n"
-" Lists all known IAX firmware images.\n";
-
-static char show_reg_usage[] =
-"Usage: iax2 show registry\n"
-" Lists all registration requests and status.\n";
-
-static char debug_usage[] =
-"Usage: iax2 set debug\n"
-" Enables dumping of IAX packets for debugging purposes\n";
-
-static char no_debug_usage[] =
-"Usage: iax2 set debug off\n"
-" Disables dumping of IAX packets for debugging purposes\n";
-
-static char debug_trunk_usage[] =
-"Usage: iax2 set debug trunk\n"
-" Requests current status of IAX trunking\n";
-
-static char no_debug_trunk_usage[] =
-"Usage: iax2 set debug trunk off\n"
-" Requests current status of IAX trunking\n";
-
-static char debug_jb_usage[] =
-"Usage: iax2 set debug jb\n"
-" Enables jitterbuffer debugging information\n";
-
-static char no_debug_jb_usage[] =
-"Usage: iax2 set debug jb off\n"
-" Disables jitterbuffer debugging information\n";
-
-static char iax2_test_losspct_usage[] =
-"Usage: iax2 test losspct <percentage>\n"
-" For testing, throws away <percentage> percent of incoming packets\n";
-
-#ifdef IAXTESTS
-static char iax2_test_late_usage[] =
-"Usage: iax2 test late <ms>\n"
-" For testing, count the next frame as <ms> ms late\n";
-
-static char iax2_test_resync_usage[] =
-"Usage: iax2 test resync <ms>\n"
-" For testing, adjust all future frames by <ms> ms\n";
-
-static char iax2_test_jitter_usage[] =
-"Usage: iax2 test jitter <ms> <pct>\n"
-" For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
-#endif /* IAXTESTS */
-
-static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
- { "iax2", "trunk", "debug", NULL },
- iax2_do_trunk_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
- { "iax2", "jb", "debug", NULL },
- iax2_do_jb_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
- { "iax2", "no", "debug", NULL },
- iax2_no_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
- { "iax2", "no", "trunk", "debug", NULL },
- iax2_no_trunk_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
- { "iax2", "no", "jb", "debug", NULL },
- iax2_no_jb_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_iax2[] = {
- { { "iax2", "show", "cache", NULL },
- iax2_show_cache, "Display IAX cached dialplan",
- show_cache_usage, NULL, },
-
- { { "iax2", "show", "channels", NULL },
- iax2_show_channels, "List active IAX channels",
- show_channels_usage, NULL, },
-
- { { "iax2", "show", "firmware", NULL },
- iax2_show_firmware, "List available IAX firmwares",
- show_firmware_usage, NULL, },
-
- { { "iax2", "show", "netstats", NULL },
- iax2_show_netstats, "List active IAX channel netstats",
- show_netstats_usage, NULL, },
-
- { { "iax2", "show", "peers", NULL },
- iax2_show_peers, "List defined IAX peers",
- show_peers_usage, NULL, },
-
- { { "iax2", "show", "registry", NULL },
- iax2_show_registry, "Display IAX registration status",
- show_reg_usage, NULL, },
-
- { { "iax2", "show", "stats", NULL },
- iax2_show_stats, "Display IAX statistics",
- show_stats_usage, NULL, },
-
- { { "iax2", "show", "threads", NULL },
- iax2_show_threads, "Display IAX helper thread info",
- show_threads_usage, NULL, },
-
- { { "iax2", "show", "users", NULL },
- iax2_show_users, "List defined IAX users",
- show_users_usage, NULL, },
-
- { { "iax2", "prune", "realtime", NULL },
- iax2_prune_realtime, "Prune a cached realtime lookup",
- prune_realtime_usage, complete_iax2_show_peer },
-
- { { "iax2", "reload", NULL },
- iax2_reload, "Reload IAX configuration",
- iax2_reload_usage },
-
- { { "iax2", "show", "peer", NULL },
- iax2_show_peer, "Show details on specific IAX peer",
- show_peer_usage, complete_iax2_show_peer },
-
- { { "iax2", "set", "debug", NULL },
- iax2_do_debug, "Enable IAX debugging",
- debug_usage },
-
- { { "iax2", "set", "debug", "trunk", NULL },
- iax2_do_trunk_debug, "Enable IAX trunk debugging",
- debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
-
- { { "iax2", "set", "debug", "jb", NULL },
- iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
- debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
-
- { { "iax2", "set", "debug", "off", NULL },
- iax2_no_debug, "Disable IAX debugging",
- no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
-
- { { "iax2", "set", "debug", "trunk", "off", NULL },
- iax2_no_trunk_debug, "Disable IAX trunk debugging",
- no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
-
- { { "iax2", "set", "debug", "jb", "off", NULL },
- iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
- no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
-
- { { "iax2", "test", "losspct", NULL },
- iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
- iax2_test_losspct_usage },
-
- { { "iax2", "provision", NULL },
- iax2_prov_cmd, "Provision an IAX device",
- show_prov_usage, iax2_prov_complete_template_3rd },
-
-#ifdef IAXTESTS
- { { "iax2", "test", "late", NULL },
- iax2_test_late, "Test the receipt of a late frame",
- iax2_test_late_usage },
-
- { { "iax2", "test", "resync", NULL },
- iax2_test_resync, "Test a resync in received timestamps",
- iax2_test_resync_usage },
-
- { { "iax2", "test", "jitter", NULL },
- iax2_test_jitter, "Simulates jitter for testing",
- iax2_test_jitter_usage },
-#endif /* IAXTESTS */
-};
-
-static int __unload_module(void)
-{
- struct iax2_thread *thread = NULL;
- int x;
-
- /* Make sure threads do not hold shared resources when they are canceled */
-
- /* Grab the sched lock resource to keep it away from threads about to die */
- /* Cancel the network thread, close the net socket */
- if (netthreadid != AST_PTHREADT_NULL) {
- AST_LIST_LOCK(&iaxq.queue);
- ast_mutex_lock(&sched_lock);
- pthread_cancel(netthreadid);
- ast_cond_signal(&sched_cond);
- ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */
- AST_LIST_UNLOCK(&iaxq.queue);
- pthread_join(netthreadid, NULL);
- }
- if (schedthreadid != AST_PTHREADT_NULL) {
- ast_mutex_lock(&sched_lock);
- pthread_cancel(schedthreadid);
- ast_cond_signal(&sched_cond);
- ast_mutex_unlock(&sched_lock);
- pthread_join(schedthreadid, NULL);
- }
-
- /* Call for all threads to halt */
- AST_LIST_LOCK(&idle_list);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
- AST_LIST_REMOVE_CURRENT(&idle_list, list);
- pthread_cancel(thread->threadid);
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&idle_list);
-
- AST_LIST_LOCK(&active_list);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
- AST_LIST_REMOVE_CURRENT(&active_list, list);
- pthread_cancel(thread->threadid);
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&active_list);
-
- AST_LIST_LOCK(&dynamic_list);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
- AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
- pthread_cancel(thread->threadid);
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&dynamic_list);
-
- AST_LIST_HEAD_DESTROY(&iaxq.queue);
-
- /* Wait for threads to exit */
- while(0 < iaxactivethreadcount)
- usleep(10000);
-
- ast_netsock_release(netsock);
- ast_netsock_release(outsock);
- for (x = 0; x < ARRAY_LEN(iaxs); x++) {
- if (iaxs[x]) {
- iax2_destroy(x);
- }
- }
- ast_manager_unregister( "IAXpeers" );
- ast_manager_unregister( "IAXnetstats" );
- ast_unregister_application(papp);
- ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
- ast_unregister_switch(&iax2_switch);
- ast_channel_unregister(&iax2_tech);
- delete_users();
- iax_provision_unload();
- sched_context_destroy(sched);
- reload_firmware(1);
-
- ast_mutex_destroy(&waresl.lock);
-
- for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
- ast_mutex_destroy(&iaxsl[x]);
- }
-
- ao2_ref(peers, -1);
- ao2_ref(users, -1);
- ao2_ref(iax_peercallno_pvts, -1);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_custom_function_unregister(&iaxpeer_function);
- return __unload_module();
-}
-
-static int peer_set_sock_cb(void *obj, void *arg, int flags)
-{
- struct iax2_peer *peer = obj;
-
- if (peer->sockfd < 0)
- peer->sockfd = defaultsockfd;
-
- return 0;
-}
-
-static int pvt_hash_cb(const void *obj, const int flags)
-{
- const struct chan_iax2_pvt *pvt = obj;
-
- return pvt->peercallno;
-}
-
-static int pvt_cmp_cb(void *obj, void *arg, int flags)
-{
- struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
-
- /* The frames_received field is used to hold whether we're matching
- * against a full frame or not ... */
-
- return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
- pvt2->frames_received) ? CMP_MATCH : 0;
-}
-
-/*! \brief Load IAX2 module, load configuraiton ---*/
-static int load_module(void)
-{
- char *config = "iax.conf";
- int res = 0;
- int x;
- struct iax2_registry *reg = NULL;
-
- peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
- if (!peers)
- return AST_MODULE_LOAD_FAILURE;
- users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
- if (!users) {
- ao2_ref(peers, -1);
- return AST_MODULE_LOAD_FAILURE;
- }
- iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
- if (!iax_peercallno_pvts) {
- ao2_ref(peers, -1);
- ao2_ref(users, -1);
- return AST_MODULE_LOAD_FAILURE;
- }
-
- ast_custom_function_register(&iaxpeer_function);
-
- iax_set_output(iax_debug_output);
- iax_set_error(iax_error_output);
- jb_setoutput(jb_error_output, jb_warning_output, NULL);
-
-#ifdef HAVE_ZAPTEL
-#ifdef ZT_TIMERACK
- timingfd = open("/dev/zap/timer", O_RDWR);
- if (timingfd < 0)
-#endif
- timingfd = open("/dev/zap/pseudo", O_RDWR);
- if (timingfd < 0)
- ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
-#endif
-
- memset(iaxs, 0, sizeof(iaxs));
-
- for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
- ast_mutex_init(&iaxsl[x]);
- }
-
- ast_cond_init(&sched_cond, NULL);
-
- io = io_context_create();
- sched = sched_context_create();
-
- if (!io || !sched) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return -1;
- }
-
- netsock = ast_netsock_list_alloc();
- if (!netsock) {
- ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
- return -1;
- }
- ast_netsock_init(netsock);
-
- outsock = ast_netsock_list_alloc();
- if (!outsock) {
- ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
- return -1;
- }
- ast_netsock_init(outsock);
-
- ast_mutex_init(&waresl.lock);
-
- AST_LIST_HEAD_INIT(&iaxq.queue);
-
- ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
-
- ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
-
- ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
- ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
-
- if(set_config(config, 0) == -1)
- return AST_MODULE_LOAD_DECLINE;
-
- if (ast_channel_register(&iax2_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
- __unload_module();
- return -1;
- }
-
- if (ast_register_switch(&iax2_switch))
- ast_log(LOG_ERROR, "Unable to register IAX switch\n");
-
- res = start_network_thread();
- if (!res) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
- } else {
- ast_log(LOG_ERROR, "Unable to start network thread\n");
- ast_netsock_release(netsock);
- ast_netsock_release(outsock);
- }
-
- AST_LIST_LOCK(&registrations);
- AST_LIST_TRAVERSE(&registrations, reg, entry)
- iax2_do_register(reg);
- AST_LIST_UNLOCK(&registrations);
-
- ao2_callback(peers, 0, peer_set_sock_cb, NULL);
- ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
-
- reload_firmware(0);
- iax_provision_reload();
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/chan_local.c b/1.4/channels/chan_local.c
deleted file mode 100644
index b0e51f90d..000000000
--- a/1.4/channels/chan_local.c
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \brief Local Proxy Channel
- *
- * \ingroup channel_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/signal.h>
-
-#include "asterisk/lock.h"
-#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/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/manager.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/devicestate.h"
-
-static const char tdesc[] = "Local Proxy Channel Driver";
-
-#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
-
-static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
-static int local_digit_begin(struct ast_channel *ast, char digit);
-static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int local_call(struct ast_channel *ast, char *dest, int timeout);
-static int local_hangup(struct ast_channel *ast);
-static int local_answer(struct ast_channel *ast);
-static struct ast_frame *local_read(struct ast_channel *ast);
-static int local_write(struct ast_channel *ast, struct ast_frame *f);
-static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
-static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
-static int local_sendtext(struct ast_channel *ast, const char *text);
-static int local_devicestate(void *data);
-
-/* PBX interface structure for channel registration */
-static const struct ast_channel_tech local_tech = {
- .type = "Local",
- .description = tdesc,
- .capabilities = -1,
- .requester = local_request,
- .send_digit_begin = local_digit_begin,
- .send_digit_end = local_digit_end,
- .call = local_call,
- .hangup = local_hangup,
- .answer = local_answer,
- .read = local_read,
- .write = local_write,
- .write_video = local_write,
- .exception = local_read,
- .indicate = local_indicate,
- .fixup = local_fixup,
- .send_html = local_sendhtml,
- .send_text = local_sendtext,
- .devicestate = local_devicestate,
-};
-
-struct local_pvt {
- ast_mutex_t lock; /* Channel private lock */
- unsigned int flags; /* Private flags */
- char context[AST_MAX_CONTEXT]; /* Context to call */
- char exten[AST_MAX_EXTENSION]; /* Extension to call */
- int reqformat; /* Requested format */
- struct ast_channel *owner; /* Master Channel */
- struct ast_channel *chan; /* Outbound channel */
- struct ast_module_user *u_owner; /*! reference to keep the module loaded while in use */
- struct ast_module_user *u_chan; /*! reference to keep the module loaded while in use */
- AST_LIST_ENTRY(local_pvt) list; /* Next entity */
-};
-
-#define LOCAL_GLARE_DETECT (1 << 0) /*!< Detect glare on hangup */
-#define LOCAL_CANCEL_QUEUE (1 << 1) /*!< Cancel queue */
-#define LOCAL_ALREADY_MASQED (1 << 2) /*!< Already masqueraded */
-#define LOCAL_LAUNCHED_PBX (1 << 3) /*!< PBX was launched */
-#define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
-
-static AST_LIST_HEAD_STATIC(locals, local_pvt);
-
-/*! \brief Adds devicestate to local channels */
-static int local_devicestate(void *data)
-{
- char *exten = ast_strdupa(data);
- char *context = NULL, *opts = NULL;
- int res;
-
- if (!(context = strchr(exten, '@'))) {
- ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
- return AST_DEVICE_INVALID;
- }
-
- *context++ = '\0';
-
- /* Strip options if they exist */
- if ((opts = strchr(context, '/')))
- *opts = '\0';
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
- res = ast_exists_extension(NULL, context, exten, 1, NULL);
- if (!res)
- return AST_DEVICE_INVALID;
- else
- return AST_DEVICE_UNKNOWN;
-}
-
-/*!
- * \note Assumes the pvt is no longer in the pvts list
- */
-static struct local_pvt *local_pvt_destroy(struct local_pvt *pvt)
-{
- ast_mutex_destroy(&pvt->lock);
- free(pvt);
- return NULL;
-}
-
-static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
-{
- struct ast_channel *other = NULL;
-
- /* Recalculate outbound channel */
- other = isoutbound ? p->owner : p->chan;
-
- /* Set glare detection */
- ast_set_flag(p, LOCAL_GLARE_DETECT);
- if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
- /* We had a glare on the hangup. Forget all this business,
- return and destroy p. */
- ast_mutex_unlock(&p->lock);
- p = local_pvt_destroy(p);
- return -1;
- }
- if (!other) {
- ast_clear_flag(p, LOCAL_GLARE_DETECT);
- return 0;
- }
-
- /* Ensure that we have both channels locked */
- while (other && ast_channel_trylock(other)) {
- ast_mutex_unlock(&p->lock);
- if (us)
- ast_channel_unlock(us);
- usleep(1);
- if (us)
- ast_channel_lock(us);
- ast_mutex_lock(&p->lock);
- other = isoutbound ? p->owner : p->chan;
- }
-
- if (other) {
- ast_queue_frame(other, f);
- ast_channel_unlock(other);
- }
-
- ast_clear_flag(p, LOCAL_GLARE_DETECT);
-
- return 0;
-}
-
-static int local_answer(struct ast_channel *ast)
-{
- struct local_pvt *p = ast->tech_pvt;
- int isoutbound;
- int res = -1;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- if (isoutbound) {
- /* Pass along answer since somebody answered us */
- struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- res = local_queue_frame(p, isoutbound, &answer, ast);
- } else
- ast_log(LOG_WARNING, "Huh? Local is being asked to answer?\n");
- if (!res)
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static void check_bridge(struct local_pvt *p, int isoutbound)
-{
- struct ast_channel_monitor *tmp;
- if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan)))
- return;
-
- /* only do the masquerade if we are being called on the outbound channel,
- if it has been bridged to another channel and if there are no pending
- frames on the owner channel (because they would be transferred to the
- outbound channel during the masquerade)
- */
- if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
- /* Masquerade bridged channel into owner */
- /* Lock everything we need, one by one, and give up if
- we can't get everything. Remember, we'll get another
- chance in just a little bit */
- if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
- if (!p->chan->_bridge->_softhangup) {
- if (!ast_mutex_trylock(&p->owner->lock)) {
- if (!p->owner->_softhangup) {
- if(p->owner->monitor && !p->chan->_bridge->monitor) {
- /* If a local channel is being monitored, we don't want a masquerade
- * to cause the monitor to go away. Since the masquerade swaps the monitors,
- * pre-swapping the monitors before the masquerade will ensure that the monitor
- * ends up where it is expected.
- */
- tmp = p->owner->monitor;
- p->owner->monitor = p->chan->_bridge->monitor;
- p->chan->_bridge->monitor = tmp;
- }
- ast_channel_masquerade(p->owner, p->chan->_bridge);
- ast_set_flag(p, LOCAL_ALREADY_MASQED);
- }
- ast_mutex_unlock(&p->owner->lock);
- }
- ast_mutex_unlock(&(p->chan->_bridge)->lock);
- }
- }
- /* We only allow masquerading in one 'direction'... it's important to preserve the state
- (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
- when the local channels go away.
- */
-#if 0
- } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
- /* Masquerade bridged channel into chan */
- if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
- if (!p->owner->_bridge->_softhangup) {
- if (!ast_mutex_trylock(&p->chan->lock)) {
- if (!p->chan->_softhangup) {
- ast_channel_masquerade(p->chan, p->owner->_bridge);
- ast_set_flag(p, LOCAL_ALREADY_MASQED);
- }
- ast_mutex_unlock(&p->chan->lock);
- }
- }
- ast_mutex_unlock(&(p->owner->_bridge)->lock);
- }
-#endif
- }
-}
-
-static struct ast_frame *local_read(struct ast_channel *ast)
-{
- return &ast_null_frame;
-}
-
-static int local_write(struct ast_channel *ast, struct ast_frame *f)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res = -1;
- int isoutbound;
-
- if (!p)
- return -1;
-
- /* Just queue for delivery to the other side */
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
- check_bridge(p, isoutbound);
- if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
- res = local_queue_frame(p, isoutbound, f, ast);
- else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
- res = 0;
- }
- if (!res)
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct local_pvt *p = newchan->tech_pvt;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
-
- if ((p->owner != oldchan) && (p->chan != oldchan)) {
- ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- if (p->owner == oldchan)
- p->owner = newchan;
- else
- p->chan = newchan;
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res = 0;
- struct ast_frame f = { AST_FRAME_CONTROL, };
- int isoutbound;
-
- if (!p)
- return -1;
-
- /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
- if (condition == AST_CONTROL_HOLD) {
- ast_moh_start(ast, data, NULL);
- } else if (condition == AST_CONTROL_UNHOLD) {
- ast_moh_stop(ast);
- } else {
- /* Queue up a frame representing the indication as a control frame */
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- f.subclass = condition;
- f.data = (void*)data;
- f.datalen = datalen;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
- ast_mutex_unlock(&p->lock);
- }
-
- return res;
-}
-
-static int local_digit_begin(struct ast_channel *ast, char digit)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res = -1;
- struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
- int isoutbound;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- f.subclass = digit;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res = -1;
- struct ast_frame f = { AST_FRAME_DTMF_END, };
- int isoutbound;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- f.subclass = digit;
- f.len = duration;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-static int local_sendtext(struct ast_channel *ast, const char *text)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res = -1;
- struct ast_frame f = { AST_FRAME_TEXT, };
- int isoutbound;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- f.data = (char *) text;
- f.datalen = strlen(text) + 1;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res = -1;
- struct ast_frame f = { AST_FRAME_HTML, };
- int isoutbound;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- f.subclass = subclass;
- f.data = (char *)data;
- f.datalen = datalen;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-/*! \brief Initiate new call, part of PBX interface
- * dest is the dial string */
-static int local_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct local_pvt *p = ast->tech_pvt;
- int res;
- struct ast_var_t *varptr = NULL, *new;
- size_t len, namelen;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
-
- /*
- * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
- * call, so it's done here instead.
- */
- p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
- p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
- p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
- p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
- p->chan->cid.cid_pres = p->owner->cid.cid_pres;
- ast_string_field_set(p->chan, language, p->owner->language);
- ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
- ast_cdr_update(p->chan);
- p->chan->cdrflags = p->owner->cdrflags;
-
- /* copy the channel variables from the incoming channel to the outgoing channel */
- /* Note that due to certain assumptions, they MUST be in the same order */
- AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
- namelen = strlen(varptr->name);
- len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
- if ((new = ast_calloc(1, len))) {
- memcpy(new, varptr, len);
- new->value = &(new->name[0]) + namelen + 1;
- AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
- }
- }
- ast_channel_datastore_inherit(p->owner, p->chan);
-
- /* Start switch on sub channel */
- if (!(res = ast_pbx_start(p->chan)))
- ast_set_flag(p, LOCAL_LAUNCHED_PBX);
-
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-/*! \brief Hangup a call through the local proxy channel */
-static int local_hangup(struct ast_channel *ast)
-{
- struct local_pvt *p = ast->tech_pvt;
- int isoutbound;
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
- struct ast_channel *ochan = NULL;
- int glaredetect = 0, res = 0;
-
- if (!p)
- return -1;
-
- ast_mutex_lock(&p->lock);
- isoutbound = IS_OUTBOUND(ast, p);
- if (isoutbound) {
- const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
- if ((status) && (p->owner)) {
- /* Deadlock avoidance */
- while (p->owner && ast_channel_trylock(p->owner)) {
- ast_mutex_unlock(&p->lock);
- if (ast) {
- ast_channel_unlock(ast);
- }
- usleep(1);
- if (ast) {
- ast_channel_lock(ast);
- }
- ast_mutex_lock(&p->lock);
- }
- if (p->owner) {
- pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
- ast_channel_unlock(p->owner);
- }
- }
- p->chan = NULL;
- ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
- ast_module_user_remove(p->u_chan);
- } else {
- p->owner = NULL;
- ast_module_user_remove(p->u_owner);
- }
-
- ast->tech_pvt = NULL;
-
- if (!p->owner && !p->chan) {
- /* Okay, done with the private part now, too. */
- glaredetect = ast_test_flag(p, LOCAL_GLARE_DETECT);
- /* If we have a queue holding, don't actually destroy p yet, but
- let local_queue do it. */
- if (glaredetect)
- ast_set_flag(p, LOCAL_CANCEL_QUEUE);
- ast_mutex_unlock(&p->lock);
- /* Remove from list */
- AST_LIST_LOCK(&locals);
- AST_LIST_REMOVE(&locals, p, list);
- AST_LIST_UNLOCK(&locals);
- /* Grab / release lock just in case */
- ast_mutex_lock(&p->lock);
- ast_mutex_unlock(&p->lock);
- /* And destroy */
- if (!glaredetect) {
- p = local_pvt_destroy(p);
- }
- return 0;
- }
- if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX))
- /* Need to actually hangup since there is no PBX */
- ochan = p->chan;
- else
- res = local_queue_frame(p, isoutbound, &f, NULL);
- if (!res)
- ast_mutex_unlock(&p->lock);
- if (ochan)
- ast_hangup(ochan);
- return 0;
-}
-
-/*! \brief Create a call structure */
-static struct local_pvt *local_alloc(const char *data, int format)
-{
- struct local_pvt *tmp = NULL;
- char *c = NULL, *opts = NULL;
-
- if (!(tmp = ast_calloc(1, sizeof(*tmp))))
- return NULL;
-
- /* Initialize private structure information */
- ast_mutex_init(&tmp->lock);
- ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
-
- /* Look for options */
- if ((opts = strchr(tmp->exten, '/'))) {
- *opts++ = '\0';
- if (strchr(opts, 'n'))
- ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
- }
-
- /* Look for a context */
- if ((c = strchr(tmp->exten, '@')))
- *c++ = '\0';
-
- ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
-
- tmp->reqformat = format;
-
- if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
- ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
- tmp = local_pvt_destroy(tmp);
- } else {
- /* Add to list */
- AST_LIST_LOCK(&locals);
- AST_LIST_INSERT_HEAD(&locals, tmp, list);
- AST_LIST_UNLOCK(&locals);
- }
-
- return tmp;
-}
-
-/*! \brief Start new local channel */
-static struct ast_channel *local_new(struct local_pvt *p, int state)
-{
- struct ast_channel *tmp = NULL, *tmp2 = NULL;
- int randnum = ast_random() & 0xffff, fmt = 0;
- const char *t;
- int ama;
-
- /* Allocate two new Asterisk channels */
- /* safe accountcode */
- if (p->owner && p->owner->accountcode)
- t = p->owner->accountcode;
- else
- t = "";
-
- if (p->owner)
- ama = p->owner->amaflags;
- else
- ama = 0;
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x,1", p->exten, p->context, randnum))
- || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x,2", p->exten, p->context, randnum))) {
- if (tmp)
- ast_channel_free(tmp);
- if (tmp2)
- ast_channel_free(tmp2);
- ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
- return NULL;
- }
-
- tmp2->tech = tmp->tech = &local_tech;
-
- tmp->nativeformats = p->reqformat;
- tmp2->nativeformats = p->reqformat;
-
- /* Determine our read/write format and set it on each channel */
- fmt = ast_best_codec(p->reqformat);
- tmp->writeformat = fmt;
- tmp2->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp2->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp2->readformat = fmt;
- tmp->rawreadformat = fmt;
- tmp2->rawreadformat = fmt;
-
- tmp->tech_pvt = p;
- tmp2->tech_pvt = p;
-
- p->owner = tmp;
- p->chan = tmp2;
- p->u_owner = ast_module_user_add(p->owner);
- p->u_chan = ast_module_user_add(p->chan);
-
- ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
- ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
- ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
- tmp->priority = 1;
- tmp2->priority = 1;
-
- return tmp;
-}
-
-/*! \brief Part of PBX interface */
-static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
-{
- struct local_pvt *p = NULL;
- struct ast_channel *chan = NULL;
-
- /* Allocate a new private structure and then Asterisk channel */
- if ((p = local_alloc(data, format))) {
- if (!(chan = local_new(p, AST_STATE_DOWN))) {
- AST_LIST_LOCK(&locals);
- AST_LIST_REMOVE(&locals, p, list);
- AST_LIST_UNLOCK(&locals);
- p = local_pvt_destroy(p);
- }
- }
-
- return chan;
-}
-
-/*! \brief CLI command "local show channels" */
-static int locals_show(int fd, int argc, char **argv)
-{
- struct local_pvt *p = NULL;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&locals);
- if (!AST_LIST_EMPTY(&locals)) {
- AST_LIST_TRAVERSE(&locals, p, list) {
- ast_mutex_lock(&p->lock);
- ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
- ast_mutex_unlock(&p->lock);
- }
- } else
- ast_cli(fd, "No local channels in use\n");
- AST_LIST_UNLOCK(&locals);
-
- return RESULT_SUCCESS;
-}
-
-static char show_locals_usage[] =
-"Usage: local show channels\n"
-" Provides summary information on active local proxy channels.\n";
-
-static struct ast_cli_entry cli_local[] = {
- { { "local", "show", "channels", NULL },
- locals_show, "List status of local channels",
- show_locals_usage },
-};
-
-/*! \brief Load module into PBX, register channel */
-static int load_module(void)
-{
- /* Make sure we can register our channel type */
- if (ast_channel_register(&local_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
- return -1;
- }
- ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-/*! \brief Unload the local proxy channel from Asterisk */
-static int unload_module(void)
-{
- struct local_pvt *p = NULL;
-
- /* First, take us out of the channel loop */
- ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
- ast_channel_unregister(&local_tech);
- if (!AST_LIST_LOCK(&locals)) {
- /* Hangup all interfaces if they have an owner */
- AST_LIST_TRAVERSE(&locals, p, list) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- }
- AST_LIST_UNLOCK(&locals);
- AST_LIST_HEAD_DESTROY(&locals);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- return -1;
- }
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Local Proxy Channel (Note: used internally by other modules)");
diff --git a/1.4/channels/chan_mgcp.c b/1.4/channels/chan_mgcp.c
deleted file mode 100644
index bd57e54f3..000000000
--- a/1.4/channels/chan_mgcp.c
+++ /dev/null
@@ -1,4430 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Implementation of Media Gateway Control Protocol
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \par See also
- * \arg \ref Config_mgcp
- *
- * \ingroup channel_drivers
- */
-/*** MODULEINFO
- <depend>res_features</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <sys/signal.h>
-#include <signal.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-#include "asterisk/lock.h"
-#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/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/cli.h"
-#include "asterisk/say.h"
-#include "asterisk/cdr.h"
-#include "asterisk/astdb.h"
-#include "asterisk/features.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/dsp.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/abstract_jb.h"
-
-#ifndef IPTOS_MINCOST
-#define IPTOS_MINCOST 0x02
-#endif
-
-/*
- * Define to work around buggy dlink MGCP phone firmware which
- * appears not to know that "rt" is part of the "G" package.
- */
-/* #define DLINK_BUGGY_FIRMWARE */
-
-#define MGCPDUMPER
-#define DEFAULT_EXPIRY 120
-#define MAX_EXPIRY 3600
-#define CANREINVITE 1
-
-#ifndef INADDR_NONE
-#define INADDR_NONE (in_addr_t)(-1)
-#endif
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-static const char tdesc[] = "Media Gateway Control Protocol (MGCP)";
-static const char config[] = "mgcp.conf";
-
-#define MGCP_DTMF_RFC2833 (1 << 0)
-#define MGCP_DTMF_INBAND (1 << 1)
-#define MGCP_DTMF_HYBRID (1 << 2)
-
-#define DEFAULT_MGCP_GW_PORT 2427 /*!< From RFC 2705 */
-#define DEFAULT_MGCP_CA_PORT 2727 /*!< From RFC 2705 */
-#define MGCP_MAX_PACKET 1500 /*!< Also from RFC 2543, should sub headers tho */
-#define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit */
-#define MAX_RETRANS 5 /*!< Try only 5 times for retransmissions */
-
-/*! MGCP rtp stream modes { */
-#define MGCP_CX_SENDONLY 0
-#define MGCP_CX_RECVONLY 1
-#define MGCP_CX_SENDRECV 2
-#define MGCP_CX_CONF 3
-#define MGCP_CX_CONFERENCE 3
-#define MGCP_CX_MUTE 4
-#define MGCP_CX_INACTIVE 4
-/*! } */
-
-static char *mgcp_cxmodes[] = {
- "sendonly",
- "recvonly",
- "sendrecv",
- "confrnce",
- "inactive"
-};
-
-enum {
- MGCP_CMD_EPCF,
- MGCP_CMD_CRCX,
- MGCP_CMD_MDCX,
- MGCP_CMD_DLCX,
- MGCP_CMD_RQNT,
- MGCP_CMD_NTFY,
- MGCP_CMD_AUEP,
- MGCP_CMD_AUCX,
- MGCP_CMD_RSIP
-};
-
-static char context[AST_MAX_EXTENSION] = "default";
-
-static char language[MAX_LANGUAGE] = "";
-static char musicclass[MAX_MUSICCLASS] = "";
-static char cid_num[AST_MAX_EXTENSION] = "";
-static char cid_name[AST_MAX_EXTENSION] = "";
-
-static int dtmfmode = 0;
-static int nat = 0;
-
-static ast_group_t cur_callergroup = 0;
-static ast_group_t cur_pickupgroup = 0;
-
-static int tos = 0;
-
-static int immediate = 0;
-
-static int callwaiting = 0;
-
-static int callreturn = 0;
-
-static int slowsequence = 0;
-
-static int threewaycalling = 0;
-
-/*! This is for flashhook transfers */
-static int transfer = 0;
-
-static int cancallforward = 0;
-
-static int singlepath = 0;
-
-static int canreinvite = CANREINVITE;
-
-static char accountcode[AST_MAX_ACCOUNT_CODE] = "";
-
-static char mailbox[AST_MAX_EXTENSION];
-
-static int amaflags = 0;
-
-static int adsi = 0;
-
-static unsigned int oseq;
-
-/*! Wait up to 16 seconds for first digit (FXO logic) */
-static int firstdigittimeout = 16000;
-
-/*! How long to wait for following digits (FXO logic) */
-static int gendigittimeout = 8000;
-
-/*! How long to wait for an extra digit, if there is an ambiguous match */
-static int matchdigittimeout = 3000;
-
-/*! Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(netlock);
-
-AST_MUTEX_DEFINE_STATIC(monlock);
-
-/*! This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-
-static int restart_monitor(void);
-
-static int capability = AST_FORMAT_ULAW;
-static int nonCodecCapability = AST_RTP_DTMF;
-
-static char ourhost[MAXHOSTNAMELEN];
-static struct in_addr __ourip;
-static int ourport;
-
-static int mgcpdebug = 0;
-
-static struct sched_context *sched;
-static struct io_context *io;
-/*! The private structures of the mgcp channels are linked for
- ! selecting outgoing channels */
-
-#define MGCP_MAX_HEADERS 64
-#define MGCP_MAX_LINES 64
-
-struct mgcp_request {
- int len;
- char *verb;
- char *identifier;
- char *endpoint;
- char *version;
- int headers; /*!< MGCP Headers */
- char *header[MGCP_MAX_HEADERS];
- int lines; /*!< SDP Content */
- char *line[MGCP_MAX_LINES];
- char data[MGCP_MAX_PACKET];
- int cmd; /*!< int version of verb = command */
- unsigned int trid; /*!< int version of identifier = transaction id */
- struct mgcp_request *next; /*!< next in the queue */
-};
-
-/*! \brief mgcp_message: MGCP message for queuing up */
-struct mgcp_message {
- struct mgcp_endpoint *owner_ep;
- struct mgcp_subchannel *owner_sub;
- int retrans;
- unsigned long expire;
- unsigned int seqno;
- int len;
- struct mgcp_message *next;
- char buf[0];
-};
-
-#define RESPONSE_TIMEOUT 30 /*!< in seconds */
-
-struct mgcp_response {
- time_t whensent;
- int len;
- int seqno;
- struct mgcp_response *next;
- char buf[0];
-};
-
-#define MAX_SUBS 2
-
-#define SUB_REAL 0
-#define SUB_ALT 1
-
-struct mgcp_subchannel {
- /*! subchannel magic string.
- Needed to prove that any subchannel pointer passed by asterisk
- really points to a valid subchannel memory area.
- Ugly.. But serves the purpose for the time being.
- */
-#define MGCP_SUBCHANNEL_MAGIC "!978!"
- char magic[6];
- ast_mutex_t lock;
- int id;
- struct ast_channel *owner;
- struct mgcp_endpoint *parent;
- struct ast_rtp *rtp;
- struct sockaddr_in tmpdest;
- char txident[80]; /*! \todo FIXME txident is replaced by rqnt_ident in endpoint.
- This should be obsoleted */
- char cxident[80];
- char callid[80];
- int cxmode;
- struct mgcp_request *cx_queue; /*!< pending CX commands */
- ast_mutex_t cx_queue_lock; /*!< CX queue lock */
- int nat;
- int iseq; /*!< Not used? RTP? */
- int outgoing;
- int alreadygone;
- struct mgcp_subchannel *next; /*!< for out circular linked list */
-};
-
-#define MGCP_ONHOOK 1
-#define MGCP_OFFHOOK 2
-
-#define TYPE_TRUNK 1
-#define TYPE_LINE 2
-
-struct mgcp_endpoint {
- ast_mutex_t lock;
- char name[80];
- struct mgcp_subchannel *sub; /*!< Pointer to our current connection, channel and stuff */
- char accountcode[AST_MAX_ACCOUNT_CODE];
- char exten[AST_MAX_EXTENSION]; /*!< Extention where to start */
- char context[AST_MAX_EXTENSION];
- char language[MAX_LANGUAGE];
- char cid_num[AST_MAX_EXTENSION]; /*!< Caller*ID number */
- char cid_name[AST_MAX_EXTENSION]; /*!< Caller*ID name */
- char lastcallerid[AST_MAX_EXTENSION]; /*!< Last Caller*ID */
- char call_forward[AST_MAX_EXTENSION]; /*!< Last Caller*ID */
- char mailbox[AST_MAX_EXTENSION];
- char musicclass[MAX_MUSICCLASS];
- char curtone[80]; /*!< Current tone */
- char dtmf_buf[AST_MAX_EXTENSION]; /*!< place to collect digits be */
- ast_group_t callgroup;
- ast_group_t pickupgroup;
- int callwaiting;
- int hascallwaiting;
- int transfer;
- int threewaycalling;
- int singlepath;
- int cancallforward;
- int canreinvite;
- int callreturn;
- int dnd; /* How does this affect callwait? Do we just deny a mgcp_request if we're dnd? */
- int hascallerid;
- int hidecallerid;
- int dtmfmode;
- int amaflags;
- int type;
- int slowsequence; /*!< MS: Sequence the endpoint as a whole */
- int group;
- int iseq; /*!< Not used? */
- int lastout; /*!< tracking this on the subchannels. Is it needed here? */
- int needdestroy; /*!< Not used? */
- int capability;
- int nonCodecCapability;
- int onhooktime;
- int msgstate; /*!< voicemail message state */
- int immediate;
- int hookstate;
- int adsi;
- char rqnt_ident[80]; /*!< request identifier */
- struct mgcp_request *rqnt_queue; /*!< pending RQNT commands */
- ast_mutex_t rqnt_queue_lock;
- struct mgcp_request *cmd_queue; /*!< pending commands other than RQNT */
- ast_mutex_t cmd_queue_lock;
- int delme; /*!< needed for reload */
- int needaudit; /*!< needed for reload */
- struct ast_dsp *dsp; /*!< XXX Should there be a dsp/subchannel? XXX */
- /* owner is tracked on the subchannels, and the *sub indicates whos in charge */
- /* struct ast_channel *owner; */
- /* struct ast_rtp *rtp; */
- /* struct sockaddr_in tmpdest; */
- /* message go the the endpoint and not the channel so they stay here */
- struct mgcp_endpoint *next;
- struct mgcp_gateway *parent;
-};
-
-static struct mgcp_gateway {
- /* A gateway containing one or more endpoints */
- char name[80];
- int isnamedottedip; /*!< is the name FQDN or dotted ip */
- struct sockaddr_in addr;
- struct sockaddr_in defaddr;
- struct in_addr ourip;
- int dynamic;
- int expire; /*!< XXX Should we ever expire dynamic registrations? XXX */
- struct mgcp_endpoint *endpoints;
- struct ast_ha *ha;
-/* obsolete
- time_t lastouttime;
- int lastout;
- int messagepending;
-*/
-/* Wildcard endpoint name */
- char wcardep[30];
- struct mgcp_message *msgs; /*!< gw msg queue */
- ast_mutex_t msgs_lock; /*!< queue lock */
- int retransid; /*!< retrans timer id */
- int delme; /*!< needed for reload */
- struct mgcp_response *responses;
- struct mgcp_gateway *next;
-} *gateways;
-
-AST_MUTEX_DEFINE_STATIC(mgcp_reload_lock);
-static int mgcp_reloading = 0;
-
-/*! \brief gatelock: mutex for gateway/endpoint lists */
-AST_MUTEX_DEFINE_STATIC(gatelock);
-
-static int mgcpsock = -1;
-
-static struct sockaddr_in bindaddr;
-
-static struct ast_frame *mgcp_read(struct ast_channel *ast);
-static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest);
-static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);
-static int transmit_modify_request(struct mgcp_subchannel *sub);
-static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername);
-static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs);
-static int transmit_connection_del(struct mgcp_subchannel *sub);
-static int transmit_audit_endpoint(struct mgcp_endpoint *p);
-static void start_rtp(struct mgcp_subchannel *sub);
-static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- int result, unsigned int ident, struct mgcp_request *resp);
-static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);
-static int mgcp_do_reload(void);
-static int mgcp_reload(int fd, int argc, char *argv[]);
-
-static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause);
-static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
-static int mgcp_hangup(struct ast_channel *ast);
-static int mgcp_answer(struct ast_channel *ast);
-static struct ast_frame *mgcp_read(struct ast_channel *ast);
-static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame);
-static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);
-static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static int mgcp_senddigit_begin(struct ast_channel *ast, char digit);
-static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int mgcp_devicestate(void *data);
-static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp);
-
-static const struct ast_channel_tech mgcp_tech = {
- .type = "MGCP",
- .description = tdesc,
- .capabilities = AST_FORMAT_ULAW,
- .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
- .requester = mgcp_request,
- .devicestate = mgcp_devicestate,
- .call = mgcp_call,
- .hangup = mgcp_hangup,
- .answer = mgcp_answer,
- .read = mgcp_read,
- .write = mgcp_write,
- .indicate = mgcp_indicate,
- .fixup = mgcp_fixup,
- .send_digit_begin = mgcp_senddigit_begin,
- .send_digit_end = mgcp_senddigit_end,
- .bridge = ast_rtp_bridge,
-};
-
-static int has_voicemail(struct mgcp_endpoint *p)
-{
- return ast_app_has_voicemail(p->mailbox, NULL);
-}
-
-static int unalloc_sub(struct mgcp_subchannel *sub)
-{
- struct mgcp_endpoint *p = sub->parent;
- if (p->sub == sub) {
- ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, p->parent->name);
- return -1;
- }
- ast_log(LOG_DEBUG, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name);
-
- sub->owner = NULL;
- if (!ast_strlen_zero(sub->cxident)) {
- transmit_connection_del(sub);
- }
- sub->cxident[0] = '\0';
- sub->callid[0] = '\0';
- sub->cxmode = MGCP_CX_INACTIVE;
- sub->outgoing = 0;
- sub->alreadygone = 0;
- memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
- if (sub->rtp) {
- ast_rtp_destroy(sub->rtp);
- sub->rtp = NULL;
- }
- dump_cmd_queues(NULL, sub); /* SC */
- return 0;
-}
-
-/* modified for new transport mechanism */
-static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
-{
- int res;
- if (gw->addr.sin_addr.s_addr)
- res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in));
- else
- res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in));
- if (res != len) {
- ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno));
- }
- return res;
-}
-
-static int resend_response(struct mgcp_subchannel *sub, struct mgcp_response *resp)
-{
- struct mgcp_endpoint *p = sub->parent;
- int res;
- if (mgcpdebug) {
- ast_verbose("Retransmitting:\n%s\n to %s:%d\n", resp->buf, ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
- }
- res = __mgcp_xmit(p->parent, resp->buf, resp->len);
- if (res > 0)
- res = 0;
- return res;
-}
-
-static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req)
-{
- struct mgcp_endpoint *p = sub->parent;
- int res;
- if (mgcpdebug) {
- ast_verbose("Transmitting:\n%s\n to %s:%d\n", req->data, ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
- }
- res = __mgcp_xmit(p->parent, req->data, req->len);
- if (res > 0)
- res = 0;
- return res;
-}
-
-/* modified for new transport framework */
-static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
-{
- struct mgcp_message *cur, *q = NULL, *w, *prev;
-
- ast_mutex_lock(&gw->msgs_lock);
- prev = NULL, cur = gw->msgs;
- while (cur) {
- if (!p || cur->owner_ep == p) {
- if (prev)
- prev->next = cur->next;
- else
- gw->msgs = cur->next;
-
- ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n",
- gw->name, cur->seqno);
-
- w = cur;
- cur = cur->next;
- if (q) {
- w->next = q;
- } else {
- w->next = NULL;
- }
- q = w;
- } else {
- prev = cur, cur=cur->next;
- }
- }
- ast_mutex_unlock(&gw->msgs_lock);
-
- while (q) {
- cur = q;
- q = q->next;
- free(cur);
- }
-}
-
-static void mgcp_queue_frame(struct mgcp_subchannel *sub, struct ast_frame *f)
-{
- for(;;) {
- if (sub->owner) {
- if (!ast_mutex_trylock(&sub->owner->lock)) {
- ast_queue_frame(sub->owner, f);
- ast_mutex_unlock(&sub->owner->lock);
- break;
- } else {
- ast_mutex_unlock(&sub->lock);
- usleep(1);
- ast_mutex_lock(&sub->lock);
- }
- } else
- break;
- }
-}
-
-static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
-{
- for(;;) {
- if (sub->owner) {
- if (!ast_mutex_trylock(&sub->owner->lock)) {
- ast_queue_hangup(sub->owner);
- ast_mutex_unlock(&sub->owner->lock);
- break;
- } else {
- ast_mutex_unlock(&sub->lock);
- usleep(1);
- ast_mutex_lock(&sub->lock);
- }
- } else
- break;
- }
-}
-
-static void mgcp_queue_control(struct mgcp_subchannel *sub, int control)
-{
- struct ast_frame f = { AST_FRAME_CONTROL, };
- f.subclass = control;
- return mgcp_queue_frame(sub, &f);
-}
-
-static int retrans_pkt(const void *data)
-{
- struct mgcp_gateway *gw = (struct mgcp_gateway *)data;
- struct mgcp_message *cur, *exq = NULL, *w, *prev;
- int res = 0;
-
- /* find out expired msgs */
- ast_mutex_lock(&gw->msgs_lock);
-
- prev = NULL, cur = gw->msgs;
- while (cur) {
- if (cur->retrans < MAX_RETRANS) {
- cur->retrans++;
- if (mgcpdebug) {
- ast_verbose("Retransmitting #%d transaction %u on [%s]\n",
- cur->retrans, cur->seqno, gw->name);
- }
- __mgcp_xmit(gw, cur->buf, cur->len);
-
- prev = cur;
- cur = cur->next;
- } else {
- if (prev)
- prev->next = cur->next;
- else
- gw->msgs = cur->next;
-
- ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n",
- cur->seqno, gw->name);
-
- w = cur;
- cur = cur->next;
-
- if (exq) {
- w->next = exq;
- } else {
- w->next = NULL;
- }
- exq = w;
- }
- }
-
- if (!gw->msgs) {
- gw->retransid = -1;
- res = 0;
- } else {
- res = 1;
- }
- ast_mutex_unlock(&gw->msgs_lock);
-
- while (exq) {
- cur = exq;
- /* time-out transaction */
- handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL);
- exq = exq->next;
- free(cur);
- }
-
- return res;
-}
-
-/* modified for the new transaction mechanism */
-static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- char *data, int len, unsigned int seqno)
-{
- struct mgcp_message *msg = malloc(sizeof(struct mgcp_message) + len);
- struct mgcp_message *cur;
- struct mgcp_gateway *gw = ((p && p->parent) ? p->parent : NULL);
- struct timeval tv;
-
- if (!msg) {
- return -1;
- }
- if (!gw) {
- return -1;
- }
-/* SC
- time(&t);
- if (gw->messagepending && (gw->lastouttime + 20 < t)) {
- ast_log(LOG_NOTICE, "Timeout waiting for response to message:%d, lastouttime: %ld, now: %ld. Dumping pending queue\n",
- gw->msgs ? gw->msgs->seqno : -1, (long) gw->lastouttime, (long) t);
- dump_queue(sub->parent);
- }
-*/
- msg->owner_sub = sub;
- msg->owner_ep = p;
- msg->seqno = seqno;
- msg->next = NULL;
- msg->len = len;
- msg->retrans = 0;
- memcpy(msg->buf, data, msg->len);
-
- ast_mutex_lock(&gw->msgs_lock);
- cur = gw->msgs;
- if (cur) {
- while(cur->next)
- cur = cur->next;
- cur->next = msg;
- } else {
- gw->msgs = msg;
- }
-
- if (gettimeofday(&tv, NULL) < 0) {
- /* This shouldn't ever happen, but let's be sure */
- ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
- } else {
- msg->expire = tv.tv_sec * 1000 + tv.tv_usec / 1000 + DEFAULT_RETRANS;
-
- if (gw->retransid == -1)
- gw->retransid = ast_sched_add(sched, DEFAULT_RETRANS, retrans_pkt, (void *)gw);
- }
- ast_mutex_unlock(&gw->msgs_lock);
-/* SC
- if (!gw->messagepending) {
- gw->messagepending = 1;
- gw->lastout = seqno;
- gw->lastouttime = t;
-*/
- __mgcp_xmit(gw, msg->buf, msg->len);
- /* XXX Should schedule retransmission XXX */
-/* SC
- } else
- ast_log(LOG_DEBUG, "Deferring transmission of transaction %d\n", seqno);
-*/
- return 0;
-}
-
-/* modified for new transport */
-static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- struct mgcp_request *req, unsigned int seqno)
-{
- int res = 0;
- struct mgcp_request **queue, *q, *r, *t;
- ast_mutex_t *l;
-
- ast_log(LOG_DEBUG, "Slow sequence is %d\n", p->slowsequence);
- if (p->slowsequence) {
- queue = &p->cmd_queue;
- l = &p->cmd_queue_lock;
- ast_mutex_lock(l);
- } else {
- switch (req->cmd) {
- case MGCP_CMD_DLCX:
- queue = &sub->cx_queue;
- l = &sub->cx_queue_lock;
- ast_mutex_lock(l);
- q = sub->cx_queue;
- /* delete pending cx cmds */
- while (q) {
- r = q->next;
- free(q);
- q = r;
- }
- *queue = NULL;
- break;
-
- case MGCP_CMD_CRCX:
- case MGCP_CMD_MDCX:
- queue = &sub->cx_queue;
- l = &sub->cx_queue_lock;
- ast_mutex_lock(l);
- break;
-
- case MGCP_CMD_RQNT:
- queue = &p->rqnt_queue;
- l = &p->rqnt_queue_lock;
- ast_mutex_lock(l);
- break;
-
- default:
- queue = &p->cmd_queue;
- l = &p->cmd_queue_lock;
- ast_mutex_lock(l);
- break;
- }
- }
-
- r = (struct mgcp_request *) malloc (sizeof(struct mgcp_request));
- if (!r) {
- ast_log(LOG_WARNING, "Cannot post MGCP request: insufficient memory\n");
- ast_mutex_unlock(l);
- return -1;
- }
- memcpy(r, req, sizeof(struct mgcp_request));
-
- if (!(*queue)) {
- if (mgcpdebug) {
- ast_verbose("Posting Request:\n%s to %s:%d\n", req->data,
- ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
- }
-
- res = mgcp_postrequest(p, sub, req->data, req->len, seqno);
- } else {
- if (mgcpdebug) {
- ast_verbose("Queueing Request:\n%s to %s:%d\n", req->data,
- ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
- }
- }
-
- /* XXX find tail. We could also keep tail in the data struct for faster access */
- for (t = *queue; t && t->next; t = t->next);
-
- r->next = NULL;
- if (t)
- t->next = r;
- else
- *queue = r;
-
- ast_mutex_unlock(l);
-
- return res;
-}
-
-static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
-{
- int res;
- struct mgcp_endpoint *p;
- struct mgcp_subchannel *sub;
- char tone[50] = "";
- const char *distinctive_ring = NULL;
- struct varshead *headp;
- struct ast_var_t *current;
-
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_call(%s)\n", ast->name);
- }
- sub = ast->tech_pvt;
- p = sub->parent;
- headp = &ast->varshead;
- AST_LIST_TRAVERSE(headp,current,entries) {
- /* Check whether there is an ALERT_INFO variable */
- if (strcasecmp(ast_var_name(current),"ALERT_INFO") == 0) {
- distinctive_ring = ast_var_value(current);
- }
- }
-
- ast_mutex_lock(&sub->lock);
- switch (p->hookstate) {
- case MGCP_OFFHOOK:
- if (!ast_strlen_zero(distinctive_ring)) {
- snprintf(tone, sizeof(tone), "L/wt%s", distinctive_ring);
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP distinctive callwait %s\n", tone);
- }
- } else {
- snprintf(tone, sizeof(tone), "L/wt");
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP normal callwait %s\n", tone);
- }
- }
- break;
- case MGCP_ONHOOK:
- default:
- if (!ast_strlen_zero(distinctive_ring)) {
- snprintf(tone, sizeof(tone), "L/r%s", distinctive_ring);
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP distinctive ring %s\n", tone);
- }
- } else {
- snprintf(tone, sizeof(tone), "L/rg");
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP default ring\n");
- }
- }
- break;
- }
-
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name);
- ast_mutex_unlock(&sub->lock);
- return -1;
- }
-
- res = 0;
- sub->outgoing = 1;
- sub->cxmode = MGCP_CX_RECVONLY;
- if (p->type == TYPE_LINE) {
- if (!sub->rtp) {
- start_rtp(sub);
- } else {
- transmit_modify_request(sub);
- }
-
- if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
- /* try to prevent a callwait from disturbing the other connection */
- sub->next->cxmode = MGCP_CX_RECVONLY;
- transmit_modify_request(sub->next);
- }
-
- transmit_notify_request_with_callerid(sub, tone, ast->cid.cid_num, ast->cid.cid_name);
- ast_setstate(ast, AST_STATE_RINGING);
-
- if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
- /* Put the connection back in sendrecv */
- sub->next->cxmode = MGCP_CX_SENDRECV;
- transmit_modify_request(sub->next);
- }
- } else {
- ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n");
- res = -1;
- }
- ast_mutex_unlock(&sub->lock);
- ast_queue_control(ast, AST_CONTROL_RINGING);
- return res;
-}
-
-static int mgcp_hangup(struct ast_channel *ast)
-{
- struct mgcp_subchannel *sub = ast->tech_pvt;
- struct mgcp_endpoint *p = sub->parent;
-
- if (option_debug) {
- ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name);
- }
- if (!ast->tech_pvt) {
- ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
- return 0;
- }
- if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) {
- ast_log(LOG_DEBUG, "Invalid magic. MGCP subchannel freed up already.\n");
- return 0;
- }
- ast_mutex_lock(&sub->lock);
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name);
- }
-
- if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) {
- /* check whether other channel is active. */
- if (!sub->next->owner) {
- if (p->dtmfmode & MGCP_DTMF_HYBRID)
- p->dtmfmode &= ~MGCP_DTMF_INBAND;
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name);
- }
- ast_dsp_free(p->dsp);
- p->dsp = NULL;
- }
- }
-
- sub->owner = NULL;
- if (!ast_strlen_zero(sub->cxident)) {
- transmit_connection_del(sub);
- }
- sub->cxident[0] = '\0';
- if ((sub == p->sub) && sub->next->owner) {
- if (p->hookstate == MGCP_OFFHOOK) {
- if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
- transmit_notify_request_with_callerid(p->sub, "L/wt", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);
- }
- } else {
- /* set our other connection as the primary and swith over to it */
- p->sub = sub->next;
- p->sub->cxmode = MGCP_CX_RECVONLY;
- transmit_modify_request(p->sub);
- if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
- transmit_notify_request_with_callerid(p->sub, "L/rg", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);
- }
- }
-
- } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) {
- transmit_notify_request(sub, "L/v");
- } else if (p->hookstate == MGCP_OFFHOOK) {
- transmit_notify_request(sub, "L/ro");
- } else {
- transmit_notify_request(sub, "");
- }
-
- ast->tech_pvt = NULL;
- sub->alreadygone = 0;
- sub->outgoing = 0;
- sub->cxmode = MGCP_CX_INACTIVE;
- sub->callid[0] = '\0';
- if (p) {
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- }
- /* Reset temporary destination */
- memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
- if (sub->rtp) {
- ast_rtp_destroy(sub->rtp);
- sub->rtp = NULL;
- }
-
- ast_module_unref(ast_module_info->self);
-
- if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) {
- p->hidecallerid = 0;
- if (p->hascallwaiting && !p->callwaiting) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on %s\n", ast->name);
- p->callwaiting = -1;
- }
- if (has_voicemail(p)) {
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n",
- ast->name, p->name, p->parent->name);
- }
- transmit_notify_request(sub, "L/vmwi(+)");
- } else {
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n",
- ast->name, p->name, p->parent->name);
- }
- transmit_notify_request(sub, "L/vmwi(-)");
- }
- }
- ast_mutex_unlock(&sub->lock);
- return 0;
-}
-
-static int mgcp_show_endpoints(int fd, int argc, char *argv[])
-{
- struct mgcp_gateway *g;
- struct mgcp_endpoint *e;
- int hasendpoints = 0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_mutex_lock(&gatelock);
- g = gateways;
- while(g) {
- e = g->endpoints;
- ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? ast_inet_ntoa(g->addr.sin_addr) : ast_inet_ntoa(g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static");
- while(e) {
- /* Don't show wilcard endpoint */
- if (strcmp(e->name, g->wcardep) !=0)
- ast_cli(fd, " -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle");
- hasendpoints = 1;
- e = e->next;
- }
- if (!hasendpoints) {
- ast_cli(fd, " << No Endpoints Defined >> ");
- }
- g = g->next;
- }
- ast_mutex_unlock(&gatelock);
- return RESULT_SUCCESS;
-}
-
-static char show_endpoints_usage[] =
-"Usage: mgcp show endpoints\n"
-" Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";
-
-static char audit_endpoint_usage[] =
-"Usage: mgcp audit endpoint <endpointid>\n"
-" Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n"
-" mgcp debug MUST be on to see the results of this command.\n";
-
-static char debug_usage[] =
-"Usage: mgcp set debug\n"
-" Enables dumping of MGCP packets for debugging purposes\n";
-
-static char no_debug_usage[] =
-"Usage: mgcp set debug off\n"
-" Disables dumping of MGCP packets for debugging purposes\n";
-
-static char mgcp_reload_usage[] =
-"Usage: mgcp reload\n"
-" Reloads MGCP configuration from mgcp.conf\n"
-" Deprecated: please use 'reload chan_mgcp.so' instead.\n";
-
-static int mgcp_audit_endpoint(int fd, int argc, char *argv[])
-{
- struct mgcp_gateway *g;
- struct mgcp_endpoint *e;
- int found = 0;
- char *ename,*gname, *c;
-
- if (!mgcpdebug) {
- return RESULT_SHOWUSAGE;
- }
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- /* split the name into parts by null */
- ename = argv[3];
- gname = ename;
- while (*gname) {
- if (*gname == '@') {
- *gname = 0;
- gname++;
- break;
- }
- gname++;
- }
- if (gname[0] == '[')
- gname++;
- if ((c = strrchr(gname, ']')))
- *c = '\0';
- ast_mutex_lock(&gatelock);
- g = gateways;
- while(g) {
- if (!strcasecmp(g->name, gname)) {
- e = g->endpoints;
- while(e) {
- if (!strcasecmp(e->name, ename)) {
- found = 1;
- transmit_audit_endpoint(e);
- break;
- }
- e = e->next;
- }
- if (found) {
- break;
- }
- }
- g = g->next;
- }
- if (!found) {
- ast_cli(fd, " << Could not find endpoint >> ");
- }
- ast_mutex_unlock(&gatelock);
- return RESULT_SUCCESS;
-}
-
-static int mgcp_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- mgcpdebug = 1;
- ast_cli(fd, "MGCP Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int mgcp_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- mgcpdebug = 0;
- ast_cli(fd, "MGCP Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static struct ast_cli_entry cli_mgcp[] = {
- { { "mgcp", "audit", "endpoint", NULL },
- mgcp_audit_endpoint, "Audit specified MGCP endpoint",
- audit_endpoint_usage },
-
- { { "mgcp", "show", "endpoints", NULL },
- mgcp_show_endpoints, "List defined MGCP endpoints",
- show_endpoints_usage },
-
- { { "mgcp", "set", "debug", NULL },
- mgcp_do_debug, "Enable MGCP debugging",
- debug_usage },
-
- { { "mgcp", "set", "debug", "off", NULL },
- mgcp_no_debug, "Disable MGCP debugging",
- no_debug_usage },
-
- { { "mgcp", "reload", NULL },
- mgcp_reload, "Reload MGCP configuration",
- mgcp_reload_usage },
-};
-
-static int mgcp_answer(struct ast_channel *ast)
-{
- int res = 0;
- struct mgcp_subchannel *sub = ast->tech_pvt;
- struct mgcp_endpoint *p = sub->parent;
-
- ast_mutex_lock(&sub->lock);
- sub->cxmode = MGCP_CX_SENDRECV;
- if (!sub->rtp) {
- start_rtp(sub);
- } else {
- transmit_modify_request(sub);
- }
- /* verbose level check */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_answer(%s) on %s@%s-%d\n",
- ast->name, p->name, p->parent->name, sub->id);
- }
- if (ast->_state != AST_STATE_UP) {
- ast_setstate(ast, AST_STATE_UP);
- if (option_debug)
- ast_log(LOG_DEBUG, "mgcp_answer(%s)\n", ast->name);
- transmit_notify_request(sub, "");
- transmit_modify_request(sub);
- }
- ast_mutex_unlock(&sub->lock);
- return res;
-}
-
-static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
-{
- /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
- struct ast_frame *f;
-
- f = ast_rtp_read(sub->rtp);
- /* Don't send RFC2833 if we're not supposed to */
- if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833))
- return &ast_null_frame;
- if (sub->owner) {
- /* We already hold the channel lock */
- if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass != sub->owner->nativeformats) {
- ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
- sub->owner->nativeformats = f->subclass;
- ast_set_read_format(sub->owner, sub->owner->readformat);
- ast_set_write_format(sub->owner, sub->owner->writeformat);
- }
- /* Courtesy fearnor aka alex@pilosoft.com */
- if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
-#if 0
- ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n");
-#endif
- f = ast_dsp_process(sub->owner, sub->parent->dsp, f);
- }
- }
- }
- return f;
-}
-
-
-static struct ast_frame *mgcp_read(struct ast_channel *ast)
-{
- struct ast_frame *f;
- struct mgcp_subchannel *sub = ast->tech_pvt;
- ast_mutex_lock(&sub->lock);
- f = mgcp_rtp_read(sub);
- ast_mutex_unlock(&sub->lock);
- return f;
-}
-
-static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct mgcp_subchannel *sub = ast->tech_pvt;
- int res = 0;
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype == AST_FRAME_IMAGE)
- return 0;
- else {
- ast_log(LOG_WARNING, "Can't send %d type frames with MGCP write\n", frame->frametype);
- return 0;
- }
- } else {
- if (!(frame->subclass & ast->nativeformats)) {
- ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
- frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
- return -1;
- }
- }
- if (sub) {
- ast_mutex_lock(&sub->lock);
- if ((sub->parent->sub == sub) || !sub->parent->singlepath) {
- if (sub->rtp) {
- res = ast_rtp_write(sub->rtp, frame);
- }
- }
- ast_mutex_unlock(&sub->lock);
- }
- return res;
-}
-
-static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct mgcp_subchannel *sub = newchan->tech_pvt;
-
- ast_mutex_lock(&sub->lock);
- ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name);
- if (sub->owner != oldchan) {
- ast_mutex_unlock(&sub->lock);
- ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
- return -1;
- }
- sub->owner = newchan;
- ast_mutex_unlock(&sub->lock);
- return 0;
-}
-
-static int mgcp_senddigit_begin(struct ast_channel *ast, char digit)
-{
- struct mgcp_subchannel *sub = ast->tech_pvt;
- struct mgcp_endpoint *p = sub->parent;
- int res = 0;
-
- ast_mutex_lock(&sub->lock);
- if (p->dtmfmode & MGCP_DTMF_INBAND || p->dtmfmode & MGCP_DTMF_HYBRID) {
- ast_log(LOG_DEBUG, "Sending DTMF using inband/hybrid\n");
- res = -1; /* Let asterisk play inband indications */
- } else if (p->dtmfmode & MGCP_DTMF_RFC2833) {
- ast_log(LOG_DEBUG, "Sending DTMF using RFC2833");
- ast_rtp_senddigit_begin(sub->rtp, digit);
- } else {
- ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
- }
- ast_mutex_unlock(&sub->lock);
-
- return res;
-}
-
-static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct mgcp_subchannel *sub = ast->tech_pvt;
- struct mgcp_endpoint *p = sub->parent;
- int res = 0;
- char tmp[4];
-
- ast_mutex_lock(&sub->lock);
- if (p->dtmfmode & MGCP_DTMF_INBAND || p->dtmfmode & MGCP_DTMF_HYBRID) {
- ast_log(LOG_DEBUG, "Stopping DTMF using inband/hybrid\n");
- res = -1; /* Tell Asterisk to stop inband indications */
- } else if (p->dtmfmode & MGCP_DTMF_RFC2833) {
- ast_log(LOG_DEBUG, "Stopping DTMF using RFC2833\n");
- tmp[0] = 'D';
- tmp[1] = '/';
- tmp[2] = digit;
- tmp[3] = '\0';
- transmit_notify_request(sub, tmp);
- ast_rtp_senddigit_end(sub->rtp, digit);
- } else {
- ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
- }
- ast_mutex_unlock(&sub->lock);
-
- return res;
-}
-
-/*!
- * \brief mgcp_devicestate: channel callback for device status monitoring
- * \param data tech/resource name of MGCP device to query
- *
- * Callback for device state management in channel subsystem
- * to obtain device status (up/down) of a specific MGCP endpoint
- *
- * \return device status result (from devicestate.h) AST_DEVICE_INVALID (not available) or AST_DEVICE_UNKNOWN (available but unknown state)
- */
-static int mgcp_devicestate(void *data)
-{
- struct mgcp_gateway *g;
- struct mgcp_endpoint *e = NULL;
- char *tmp, *endpt, *gw;
- int ret = AST_DEVICE_INVALID;
-
- endpt = ast_strdupa(data);
- if ((tmp = strchr(endpt, '@'))) {
- *tmp++ = '\0';
- gw = tmp;
- } else
- goto error;
-
- ast_mutex_lock(&gatelock);
- g = gateways;
- while (g) {
- if (strcasecmp(g->name, gw) == 0) {
- e = g->endpoints;
- break;
- }
- g = g->next;
- }
-
- if (!e)
- goto error;
-
- while (e) {
- if (strcasecmp(e->name, endpt) == 0)
- break;
- e = e->next;
- }
-
- if (!e)
- goto error;
-
- /*
- * As long as the gateway/endpoint is valid, we'll
- * assume that the device is available and its state
- * can be tracked.
- */
- ret = AST_DEVICE_UNKNOWN;
-
-error:
- ast_mutex_unlock(&gatelock);
- return ret;
-}
-
-static char *control2str(int ind) {
- switch (ind) {
- case AST_CONTROL_HANGUP:
- return "Other end has hungup";
- case AST_CONTROL_RING:
- return "Local ring";
- case AST_CONTROL_RINGING:
- return "Remote end is ringing";
- case AST_CONTROL_ANSWER:
- return "Remote end has answered";
- case AST_CONTROL_BUSY:
- return "Remote end is busy";
- case AST_CONTROL_TAKEOFFHOOK:
- return "Make it go off hook";
- case AST_CONTROL_OFFHOOK:
- return "Line is off hook";
- case AST_CONTROL_CONGESTION:
- return "Congestion (circuits busy)";
- case AST_CONTROL_FLASH:
- return "Flash hook";
- case AST_CONTROL_WINK:
- return "Wink";
- case AST_CONTROL_OPTION:
- return "Set a low-level option";
- case AST_CONTROL_RADIO_KEY:
- return "Key Radio";
- case AST_CONTROL_RADIO_UNKEY:
- return "Un-Key Radio";
- }
- return "UNKNOWN";
-}
-
-static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
-{
- struct mgcp_subchannel *sub = ast->tech_pvt;
- int res = 0;
-
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP asked to indicate %d '%s' condition on channel %s\n",
- ind, control2str(ind), ast->name);
- }
- ast_mutex_lock(&sub->lock);
- switch(ind) {
- case AST_CONTROL_RINGING:
-#ifdef DLINK_BUGGY_FIRMWARE
- transmit_notify_request(sub, "rt");
-#else
- transmit_notify_request(sub, "G/rt");
-#endif
- break;
- case AST_CONTROL_BUSY:
- transmit_notify_request(sub, "L/bz");
- break;
- case AST_CONTROL_CONGESTION:
- transmit_notify_request(sub, "G/cg");
- break;
- case AST_CONTROL_HOLD:
- ast_moh_start(ast, data, NULL);
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(ast);
- break;
- case AST_CONTROL_SRCUPDATE:
- ast_rtp_new_source(sub->rtp);
- break;
- case -1:
- transmit_notify_request(sub, "");
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
- res = -1;
- }
- ast_mutex_unlock(&sub->lock);
- return res;
-}
-
-static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state)
-{
- struct ast_channel *tmp;
- struct mgcp_endpoint *i = sub->parent;
- int fmt;
-
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
- if (tmp) {
- tmp->tech = &mgcp_tech;
- tmp->nativeformats = i->capability;
- if (!tmp->nativeformats)
- tmp->nativeformats = capability;
- fmt = ast_best_codec(tmp->nativeformats);
- ast_string_field_build(tmp, name, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
- if (sub->rtp)
- tmp->fds[0] = ast_rtp_fd(sub->rtp);
- if (i->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID)) {
- i->dsp = ast_dsp_new();
- ast_dsp_set_features(i->dsp,DSP_FEATURE_DTMF_DETECT);
- /* this is to prevent clipping of dtmf tones during dsp processing */
- ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_NOQUELCH);
- } else {
- i->dsp = NULL;
- }
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp->rawreadformat = fmt;
- tmp->tech_pvt = sub;
- if (!ast_strlen_zero(i->language))
- ast_string_field_set(tmp, language, i->language);
- if (!ast_strlen_zero(i->accountcode))
- ast_string_field_set(tmp, accountcode, i->accountcode);
- if (i->amaflags)
- tmp->amaflags = i->amaflags;
- sub->owner = tmp;
- ast_module_ref(ast_module_info->self);
- tmp->callgroup = i->callgroup;
- tmp->pickupgroup = i->pickupgroup;
- ast_string_field_set(tmp, call_forward, i->call_forward);
- ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
-
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
-
- if (!i->adsi)
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
- tmp->priority = 1;
- if (sub->rtp)
- ast_jb_configure(tmp, &global_jbconf);
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- tmp = NULL;
- }
- }
- /* verbose level check */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_new(%s) created in state: %s\n",
- tmp->name, ast_state2str(state));
- }
- } else {
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- }
- return tmp;
-}
-
-static char* get_sdp_by_line(char* line, char *name, int nameLen)
-{
- if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
- char* r = line + nameLen + 1;
- while (*r && (*r < 33)) ++r;
- return r;
- }
- return "";
-}
-
-static char *get_sdp(struct mgcp_request *req, char *name)
-{
- int x;
- int len = strlen(name);
- char *r;
-
- for (x=0; x<req->lines; x++) {
- r = get_sdp_by_line(req->line[x], name, len);
- if (r[0] != '\0') return r;
- }
- return "";
-}
-
-static void sdpLineNum_iterator_init(int* iterator)
-{
- *iterator = 0;
-}
-
-static char* get_sdp_iterate(int* iterator, struct mgcp_request *req, char *name)
-{
- int len = strlen(name);
- char *r;
- while (*iterator < req->lines) {
- r = get_sdp_by_line(req->line[(*iterator)++], name, len);
- if (r[0] != '\0') return r;
- }
- return "";
-}
-
-static char *__get_header(struct mgcp_request *req, char *name, int *start)
-{
- int x;
- int len = strlen(name);
- char *r;
- for (x=*start;x<req->headers;x++) {
- if (!strncasecmp(req->header[x], name, len) &&
- (req->header[x][len] == ':')) {
- r = req->header[x] + len + 1;
- while(*r && (*r < 33))
- r++;
- *start = x+1;
- return r;
- }
- }
- /* Don't return NULL, so get_header is always a valid pointer */
- return "";
-}
-
-static char *get_header(struct mgcp_request *req, char *name)
-{
- int start = 0;
- return __get_header(req, name, &start);
-}
-
-/*! \brief get_csv: (SC:) get comma separated value */
-static char *get_csv(char *c, int *len, char **next)
-{
- char *s;
-
- *next = NULL, *len = 0;
- if (!c) return NULL;
-
- while (*c && (*c < 33 || *c == ','))
- c++;
-
- s = c;
- while (*c && (*c >= 33 && *c != ','))
- c++, (*len)++;
- *next = c;
-
- if (*len == 0)
- s = NULL, *next = NULL;
-
- return s;
-}
-
-static struct mgcp_subchannel *find_subchannel_and_lock(char *name, int msgid, struct sockaddr_in *sin)
-{
- struct mgcp_endpoint *p = NULL;
- struct mgcp_subchannel *sub = NULL;
- struct mgcp_gateway *g;
- char tmp[256] = "";
- char *at = NULL, *c;
- int found = 0;
- if (name) {
- ast_copy_string(tmp, name, sizeof(tmp));
- at = strchr(tmp, '@');
- if (!at) {
- ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name);
- return NULL;
- }
- *at++ = '\0';
- }
- ast_mutex_lock(&gatelock);
- if (at && (at[0] == '[')) {
- at++;
- c = strrchr(at, ']');
- if (c)
- *c = '\0';
- }
- g = gateways;
- while(g) {
- if ((!name || !strcasecmp(g->name, at)) &&
- (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) {
- /* Found the gateway. If it's dynamic, save it's address -- now for the endpoint */
- if (sin && g->dynamic && name) {
- if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
- (g->addr.sin_port != sin->sin_port)) {
- memcpy(&g->addr, sin, sizeof(g->addr));
- if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip))
- memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Registered MGCP gateway '%s' at %s port %d\n", g->name, ast_inet_ntoa(g->addr.sin_addr), ntohs(g->addr.sin_port));
- }
- }
- /* not dynamic, check if the name matches */
- else if (name) {
- if (strcasecmp(g->name, at)) {
- g = g->next;
- continue;
- }
- }
- /* not dynamic, no name, check if the addr matches */
- else if (!name && sin) {
- if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
- (g->addr.sin_port != sin->sin_port)) {
- g = g->next;
- continue;
- }
- } else {
- g = g->next;
- continue;
- }
- /* SC */
- p = g->endpoints;
- while(p) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Searching on %s@%s for subchannel\n",
- p->name, g->name);
- if (msgid) {
-#if 0 /* new transport mech */
- sub = p->sub;
- do {
- if (option_debug)
- ast_log(LOG_DEBUG, "Searching on %s@%s-%d for subchannel with lastout: %d\n",
- p->name, g->name, sub->id, msgid);
- if (sub->lastout == msgid) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Found subchannel sub%d to handle request %d sub->lastout: %d\n",
- sub->id, msgid, sub->lastout);
- found = 1;
- break;
- }
- sub = sub->next;
- } while (sub != p->sub);
- if (found) {
- break;
- }
-#endif
- /* SC */
- sub = p->sub;
- found = 1;
- /* SC */
- break;
- } else if (name && !strcasecmp(p->name, tmp)) {
- ast_log(LOG_DEBUG, "Coundn't determine subchannel, assuming current master %s@%s-%d\n",
- p->name, g->name, p->sub->id);
- sub = p->sub;
- found = 1;
- break;
- }
- p = p->next;
- }
- if (sub && found) {
- ast_mutex_lock(&sub->lock);
- break;
- }
- }
- g = g->next;
- }
- ast_mutex_unlock(&gatelock);
- if (!sub) {
- if (name) {
- if (g)
- ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp, at);
- else
- ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
- }
- }
- return sub;
-}
-
-static void parse(struct mgcp_request *req)
-{
- /* Divide fields by NULL's */
- char *c;
- int f = 0;
- c = req->data;
-
- /* First header starts immediately */
- req->header[f] = c;
- while(*c) {
- if (*c == '\n') {
- /* We've got a new header */
- *c = 0;
-#if 0
- printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f]));
-#endif
- if (ast_strlen_zero(req->header[f])) {
- /* Line by itself means we're now in content */
- c++;
- break;
- }
- if (f >= MGCP_MAX_HEADERS - 1) {
- ast_log(LOG_WARNING, "Too many MGCP headers...\n");
- } else
- f++;
- req->header[f] = c + 1;
- } else if (*c == '\r') {
- /* Ignore but eliminate \r's */
- *c = 0;
- }
- c++;
- }
- /* Check for last header */
- if (!ast_strlen_zero(req->header[f]))
- f++;
- req->headers = f;
- /* Now we process any mime content */
- f = 0;
- req->line[f] = c;
- while(*c) {
- if (*c == '\n') {
- /* We've got a new line */
- *c = 0;
-#if 0
- printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f]));
-#endif
- if (f >= MGCP_MAX_LINES - 1) {
- ast_log(LOG_WARNING, "Too many SDP lines...\n");
- } else
- f++;
- req->line[f] = c + 1;
- } else if (*c == '\r') {
- /* Ignore and eliminate \r's */
- *c = 0;
- }
- c++;
- }
- /* Check for last line */
- if (!ast_strlen_zero(req->line[f]))
- f++;
- req->lines = f;
- /* Parse up the initial header */
- c = req->header[0];
- while(*c && *c < 33) c++;
- /* First the verb */
- req->verb = c;
- while(*c && (*c > 32)) c++;
- if (*c) {
- *c = '\0';
- c++;
- while(*c && (*c < 33)) c++;
- req->identifier = c;
- while(*c && (*c > 32)) c++;
- if (*c) {
- *c = '\0';
- c++;
- while(*c && (*c < 33)) c++;
- req->endpoint = c;
- while(*c && (*c > 32)) c++;
- if (*c) {
- *c = '\0';
- c++;
- while(*c && (*c < 33)) c++;
- req->version = c;
- while(*c && (*c > 32)) c++;
- while(*c && (*c < 33)) c++;
- while(*c && (*c > 32)) c++;
- *c = '\0';
- }
- }
- }
-
- if (mgcpdebug) {
- ast_verbose("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
- req->verb, req->identifier, req->endpoint, req->version);
- ast_verbose("%d headers, %d lines\n", req->headers, req->lines);
- }
- if (*c)
- ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
-}
-
-static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
-{
- char *m;
- char *c;
- char *a;
- char host[258];
- int len;
- int portno;
- int peercapability, peerNonCodecCapability;
- struct sockaddr_in sin;
- char *codecs;
- struct ast_hostent ahp; struct hostent *hp;
- int codec, codec_count=0;
- int iterator;
- struct mgcp_endpoint *p = sub->parent;
-
- /* Get codec and RTP info from SDP */
- m = get_sdp(req, "m");
- c = get_sdp(req, "c");
- if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
- ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
- return -1;
- }
- if (sscanf(c, "IN IP4 %256s", host) != 1) {
- ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
- return -1;
- }
- /* XXX This could block for a long time, and block the main thread! XXX */
- hp = ast_gethostbyname(host, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
- return -1;
- }
- if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) {
- ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m);
- return -1;
- }
- sin.sin_family = AF_INET;
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- sin.sin_port = htons(portno);
- ast_rtp_set_peer(sub->rtp, &sin);
-#if 0
- printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-#endif
- /* Scan through the RTP payload types specified in a "m=" line: */
- ast_rtp_pt_clear(sub->rtp);
- codecs = ast_strdupa(m + len);
- while (!ast_strlen_zero(codecs)) {
- if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
- if (codec_count)
- break;
- ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs);
- return -1;
- }
- ast_rtp_set_m_type(sub->rtp, codec);
- codec_count++;
- codecs += len;
- }
-
- /* Next, scan through each "a=rtpmap:" line, noting each */
- /* specified RTP payload type (with corresponding MIME subtype): */
- sdpLineNum_iterator_init(&iterator);
- while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
- char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
- if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2)
- continue;
- /* Note: should really look at the 'freq' and '#chans' params too */
- ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype, 0);
- }
-
- /* Now gather all of the codecs that were asked for: */
- ast_rtp_get_current_formats(sub->rtp, &peercapability, &peerNonCodecCapability);
- p->capability = capability & peercapability;
- if (mgcpdebug) {
- ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n",
- capability, peercapability, p->capability);
- ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n",
- nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
- }
- if (!p->capability) {
- ast_log(LOG_WARNING, "No compatible codecs!\n");
- return -1;
- }
- return 0;
-}
-
-static int add_header(struct mgcp_request *req, char *var, char *value)
-{
- if (req->len >= sizeof(req->data) - 4) {
- ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
- return -1;
- }
- if (req->lines) {
- ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
- return -1;
- }
- req->header[req->headers] = req->data + req->len;
- snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);
- req->len += strlen(req->header[req->headers]);
- if (req->headers < MGCP_MAX_HEADERS)
- req->headers++;
- else {
- ast_log(LOG_WARNING, "Out of header space\n");
- return -1;
- }
- return 0;
-}
-
-static int add_line(struct mgcp_request *req, char *line)
-{
- if (req->len >= sizeof(req->data) - 4) {
- ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
- return -1;
- }
- if (!req->lines) {
- /* Add extra empty return */
- snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
- req->len += strlen(req->data + req->len);
- }
- req->line[req->lines] = req->data + req->len;
- snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
- req->len += strlen(req->line[req->lines]);
- if (req->lines < MGCP_MAX_LINES)
- req->lines++;
- else {
- ast_log(LOG_WARNING, "Out of line space\n");
- return -1;
- }
- return 0;
-}
-
-static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
-{
- /* Initialize a response */
- if (req->headers || req->len) {
- ast_log(LOG_WARNING, "Request already initialized?!?\n");
- return -1;
- }
- req->header[req->headers] = req->data + req->len;
- snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);
- req->len += strlen(req->header[req->headers]);
- if (req->headers < MGCP_MAX_HEADERS)
- req->headers++;
- else
- ast_log(LOG_WARNING, "Out of header space\n");
- return 0;
-}
-
-static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb)
-{
- /* Initialize a response */
- if (req->headers || req->len) {
- ast_log(LOG_WARNING, "Request already initialized?!?\n");
- return -1;
- }
- req->header[req->headers] = req->data + req->len;
- /* check if we need brackets around the gw name */
- if (p->parent->isnamedottedip)
- snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@[%s] MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name);
- else
- snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@%s MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name);
- req->len += strlen(req->header[req->headers]);
- if (req->headers < MGCP_MAX_HEADERS)
- req->headers++;
- else
- ast_log(LOG_WARNING, "Out of header space\n");
- return 0;
-}
-
-
-static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
-{
- memset(resp, 0, sizeof(*resp));
- init_resp(resp, msg, req, msgrest);
- return 0;
-}
-
-static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
-{
- memset(req, 0, sizeof(struct mgcp_request));
- oseq++;
- if (oseq > 999999999)
- oseq = 1;
- init_req(p, req, verb);
- return 0;
-}
-
-static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
-{
- struct mgcp_request resp;
- struct mgcp_endpoint *p = sub->parent;
- struct mgcp_response *mgr;
-
- respprep(&resp, p, msg, req, msgrest);
- mgr = malloc(sizeof(struct mgcp_response) + resp.len + 1);
- if (mgr) {
- /* Store MGCP response in case we have to retransmit */
- memset(mgr, 0, sizeof(struct mgcp_response));
- sscanf(req->identifier, "%d", &mgr->seqno);
- time(&mgr->whensent);
- mgr->len = resp.len;
- memcpy(mgr->buf, resp.data, resp.len);
- mgr->buf[resp.len] = '\0';
- mgr->next = p->parent->responses;
- p->parent->responses = mgr;
- }
- return send_response(sub, &resp);
-}
-
-
-static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp *rtp)
-{
- int len;
- int codec;
- char costr[80];
- struct sockaddr_in sin;
- char v[256];
- char s[256];
- char o[256];
- char c[256];
- char t[256];
- char m[256] = "";
- char a[1024] = "";
- int x;
- struct sockaddr_in dest;
- struct mgcp_endpoint *p = sub->parent;
- /* XXX We break with the "recommendation" and send our IP, in order that our
- peer doesn't have to ast_gethostbyname() us XXX */
- len = 0;
- if (!sub->rtp) {
- ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
- return -1;
- }
- ast_rtp_get_us(sub->rtp, &sin);
- if (rtp) {
- ast_rtp_get_peer(rtp, &dest);
- } else {
- if (sub->tmpdest.sin_addr.s_addr) {
- dest.sin_addr = sub->tmpdest.sin_addr;
- dest.sin_port = sub->tmpdest.sin_port;
- /* Reset temporary destination */
- memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));
- } else {
- dest.sin_addr = p->parent->ourip;
- dest.sin_port = sin.sin_port;
- }
- }
- if (mgcpdebug) {
- ast_verbose("We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
- }
- snprintf(v, sizeof(v), "v=0\r\n");
- snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
- snprintf(s, sizeof(s), "s=session\r\n");
- snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
- snprintf(t, sizeof(t), "t=0 0\r\n");
- snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
- for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) {
- if (p->capability & x) {
- if (mgcpdebug) {
- ast_verbose("Answering with capability %d\n", x);
- }
- codec = ast_rtp_lookup_code(sub->rtp, 1, x);
- if (codec > -1) {
- snprintf(costr, sizeof(costr), " %d", codec);
- strncat(m, costr, sizeof(m) - strlen(m) - 1);
- snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x, 0));
- strncat(a, costr, sizeof(a) - strlen(a) - 1);
- }
- }
- }
- for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
- if (p->nonCodecCapability & x) {
- if (mgcpdebug) {
- ast_verbose("Answering with non-codec capability %d\n", x);
- }
- codec = ast_rtp_lookup_code(sub->rtp, 0, x);
- if (codec > -1) {
- snprintf(costr, sizeof(costr), " %d", codec);
- strncat(m, costr, sizeof(m) - strlen(m) - 1);
- snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x, 0));
- strncat(a, costr, sizeof(a) - strlen(a) - 1);
- if (x == AST_RTP_DTMF) {
- /* Indicate we support DTMF... Not sure about 16,
- but MSN supports it so dang it, we will too... */
- snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec);
- strncat(a, costr, sizeof(a) - strlen(a) - 1);
- }
- }
- }
- }
- strncat(m, "\r\n", sizeof(m) - strlen(m) - 1);
- len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
- snprintf(costr, sizeof(costr), "%d", len);
- add_line(resp, v);
- add_line(resp, o);
- add_line(resp, s);
- add_line(resp, c);
- add_line(resp, t);
- add_line(resp, m);
- add_line(resp, a);
- return 0;
-}
-
-static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs)
-{
- struct mgcp_request resp;
- char local[256];
- char tmp[80];
- int x;
- int capability;
- struct mgcp_endpoint *p = sub->parent;
-
- capability = p->capability;
- if (codecs)
- capability = codecs;
- if (ast_strlen_zero(sub->cxident) && rtp) {
- /* We don't have a CXident yet, store the destination and
- wait a bit */
- ast_rtp_get_peer(rtp, &sub->tmpdest);
- return 0;
- }
- snprintf(local, sizeof(local), "p:20");
- for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
- if (p->capability & x) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x, 0));
- strncat(local, tmp, sizeof(local) - strlen(local) - 1);
- }
- }
- reqprep(&resp, p, "MDCX");
- add_header(&resp, "C", sub->callid);
- add_header(&resp, "L", local);
- add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
- /* X header should not be sent. kept for compatibility */
- add_header(&resp, "X", sub->txident);
- add_header(&resp, "I", sub->cxident);
- /*add_header(&resp, "S", "");*/
- add_sdp(&resp, sub, rtp);
- /* fill in new fields */
- resp.cmd = MGCP_CMD_MDCX;
- resp.trid = oseq;
- return send_request(p, sub, &resp, oseq); /* SC */
-}
-
-static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp)
-{
- struct mgcp_request resp;
- char local[256];
- char tmp[80];
- int x;
- struct mgcp_endpoint *p = sub->parent;
-
- snprintf(local, sizeof(local), "p:20");
- for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
- if (p->capability & x) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x, 0));
- strncat(local, tmp, sizeof(local) - strlen(local) - 1);
- }
- }
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
- p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
- }
- reqprep(&resp, p, "CRCX");
- add_header(&resp, "C", sub->callid);
- add_header(&resp, "L", local);
- add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
- /* X header should not be sent. kept for compatibility */
- add_header(&resp, "X", sub->txident);
- /*add_header(&resp, "S", "");*/
- add_sdp(&resp, sub, rtp);
- /* fill in new fields */
- resp.cmd = MGCP_CMD_CRCX;
- resp.trid = oseq;
- return send_request(p, sub, &resp, oseq); /* SC */
-}
-
-static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
-{
- struct mgcp_request resp;
- struct mgcp_endpoint *p = sub->parent;
-
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
- tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
- }
- ast_copy_string(p->curtone, tone, sizeof(p->curtone));
- reqprep(&resp, p, "RQNT");
- add_header(&resp, "X", p->rqnt_ident); /* SC */
- switch (p->hookstate) {
- case MGCP_ONHOOK:
- add_header(&resp, "R", "L/hd(N)");
- break;
- case MGCP_OFFHOOK:
- add_header_offhook(sub, &resp);
- break;
- }
- if (!ast_strlen_zero(tone)) {
- add_header(&resp, "S", tone);
- }
- /* fill in new fields */
- resp.cmd = MGCP_CMD_RQNT;
- resp.trid = oseq;
- return send_request(p, NULL, &resp, oseq); /* SC */
-}
-
-static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
-{
- struct mgcp_request resp;
- char tone2[256];
- char *l, *n;
- time_t t;
- struct tm tm;
- struct mgcp_endpoint *p = sub->parent;
-
- time(&t);
- ast_localtime(&t, &tm, NULL);
- n = callername;
- l = callernum;
- if (!n)
- n = "";
- if (!l)
- l = "";
-
- /* Keep track of last callerid for blacklist and callreturn */
- ast_copy_string(p->lastcallerid, l, sizeof(p->lastcallerid));
-
- snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone,
- tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
- ast_copy_string(p->curtone, tone, sizeof(p->curtone));
- reqprep(&resp, p, "RQNT");
- add_header(&resp, "X", p->rqnt_ident); /* SC */
- switch (p->hookstate) {
- case MGCP_ONHOOK:
- add_header(&resp, "R", "L/hd(N)");
- break;
- case MGCP_OFFHOOK:
- add_header_offhook(sub, &resp);
- break;
- }
- if (!ast_strlen_zero(tone2)) {
- add_header(&resp, "S", tone2);
- }
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
- tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
- }
- /* fill in new fields */
- resp.cmd = MGCP_CMD_RQNT;
- resp.trid = oseq;
- return send_request(p, NULL, &resp, oseq); /* SC */
-}
-
-static int transmit_modify_request(struct mgcp_subchannel *sub)
-{
- struct mgcp_request resp;
- struct mgcp_endpoint *p = sub->parent;
-
- if (ast_strlen_zero(sub->cxident)) {
- /* We don't have a CXident yet, store the destination and
- wait a bit */
- return 0;
- }
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n",
- p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
- }
- reqprep(&resp, p, "MDCX");
- add_header(&resp, "C", sub->callid);
- add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
- /* X header should not be sent. kept for compatibility */
- add_header(&resp, "X", sub->txident);
- add_header(&resp, "I", sub->cxident);
- switch (sub->parent->hookstate) {
- case MGCP_ONHOOK:
- add_header(&resp, "R", "L/hd(N)");
- break;
- case MGCP_OFFHOOK:
- add_header_offhook(sub, &resp);
- break;
- }
- /* fill in new fields */
- resp.cmd = MGCP_CMD_MDCX;
- resp.trid = oseq;
- return send_request(p, sub, &resp, oseq); /* SC */
-}
-
-
-static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp)
-{
- struct mgcp_endpoint *p = sub->parent;
-
- if (p && p->sub && p->sub->owner && p->sub->owner->_state >= AST_STATE_RINGING && (p->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID)))
- add_header(resp, "R", "L/hu(N),L/hf(N)");
- else
- add_header(resp, "R", "L/hu(N),L/hf(N),D/[0-9#*](N)");
-}
-
-static int transmit_audit_endpoint(struct mgcp_endpoint *p)
-{
- struct mgcp_request resp;
- reqprep(&resp, p, "AUEP");
- /* removed unknown param VS */
- /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/
- add_header(&resp, "F", "A");
- /* fill in new fields */
- resp.cmd = MGCP_CMD_AUEP;
- resp.trid = oseq;
- return send_request(p, NULL, &resp, oseq); /* SC */
-}
-
-static int transmit_connection_del(struct mgcp_subchannel *sub)
-{
- struct mgcp_endpoint *p = sub->parent;
- struct mgcp_request resp;
-
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n",
- sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
- }
- reqprep(&resp, p, "DLCX");
- /* check if call id is avail */
- if (sub->callid[0])
- add_header(&resp, "C", sub->callid);
- /* X header should not be sent. kept for compatibility */
- add_header(&resp, "X", sub->txident);
- /* check if cxident is avail */
- if (sub->cxident[0])
- add_header(&resp, "I", sub->cxident);
- /* fill in new fields */
- resp.cmd = MGCP_CMD_DLCX;
- resp.trid = oseq;
- return send_request(p, sub, &resp, oseq); /* SC */
-}
-
-static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
-{
- struct mgcp_request resp;
-
- if (mgcpdebug) {
- ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n",
- cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
- }
- reqprep(&resp, p, "DLCX");
- /* check if call id is avail */
- if (callid && *callid)
- add_header(&resp, "C", callid);
- /* check if cxident is avail */
- if (cxident && *cxident)
- add_header(&resp, "I", cxident);
- /* fill in new fields */
- resp.cmd = MGCP_CMD_DLCX;
- resp.trid = oseq;
- return send_request(p, p->sub, &resp, oseq);
-}
-
-/*! \brief dump_cmd_queues: (SC:) cleanup pending commands */
-static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
-{
- struct mgcp_request *t, *q;
-
- if (p) {
- ast_mutex_lock(&p->rqnt_queue_lock);
- for (q = p->rqnt_queue; q; t = q->next, free(q), q=t);
- p->rqnt_queue = NULL;
- ast_mutex_unlock(&p->rqnt_queue_lock);
-
- ast_mutex_lock(&p->cmd_queue_lock);
- for (q = p->cmd_queue; q; t = q->next, free(q), q=t);
- p->cmd_queue = NULL;
- ast_mutex_unlock(&p->cmd_queue_lock);
-
- ast_mutex_lock(&p->sub->cx_queue_lock);
- for (q = p->sub->cx_queue; q; t = q->next, free(q), q=t);
- p->sub->cx_queue = NULL;
- ast_mutex_unlock(&p->sub->cx_queue_lock);
-
- ast_mutex_lock(&p->sub->next->cx_queue_lock);
- for (q = p->sub->next->cx_queue; q; t = q->next, free(q), q=t);
- p->sub->next->cx_queue = NULL;
- ast_mutex_unlock(&p->sub->next->cx_queue_lock);
- } else if (sub) {
- ast_mutex_lock(&sub->cx_queue_lock);
- for (q = sub->cx_queue; q; t = q->next, free(q), q=t);
- sub->cx_queue = NULL;
- ast_mutex_unlock(&sub->cx_queue_lock);
- }
-}
-
-
-/*! \brief find_command: (SC:) remove command transaction from queue */
-static struct mgcp_request *find_command(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- struct mgcp_request **queue, ast_mutex_t *l, int ident)
-{
- struct mgcp_request *prev, *req;
-
- ast_mutex_lock(l);
- for (prev = NULL, req = *queue; req; prev = req, req = req->next) {
- if (req->trid == ident) {
- /* remove from queue */
- if (!prev)
- *queue = req->next;
- else
- prev->next = req->next;
-
- /* send next pending command */
- if (*queue) {
- if (mgcpdebug) {
- ast_verbose("Posting Queued Request:\n%s to %s:%d\n", (*queue)->data,
- ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
- }
-
- mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid);
- }
- break;
- }
- }
- ast_mutex_unlock(l);
- return req;
-}
-
-/* modified for new transport mechanism */
-static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- int result, unsigned int ident, struct mgcp_request *resp)
-{
- char *c;
- struct mgcp_request *req;
- struct mgcp_gateway *gw = p->parent;
-
- if (result < 200) {
- /* provisional response */
- return;
- }
-
- if (p->slowsequence)
- req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
- else if (sub)
- req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident);
- else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident)))
- req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident);
-
- if (!req) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "No command found on [%s] for transaction %d. Ignoring...\n",
- gw->name, ident);
- }
- return;
- }
-
- if (p && (result >= 400) && (result <= 599)) {
- switch (result) {
- case 401:
- p->hookstate = MGCP_OFFHOOK;
- break;
- case 402:
- p->hookstate = MGCP_ONHOOK;
- break;
- case 406:
- ast_log(LOG_NOTICE, "Transaction %d timed out\n", ident);
- break;
- case 407:
- ast_log(LOG_NOTICE, "Transaction %d aborted\n", ident);
- break;
- }
- if (sub) {
- if (sub->owner) {
- ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
- result, p->name, p->parent->name, sub ? sub->id:-1);
- mgcp_queue_hangup(sub);
- }
- } else {
- if (p->sub->next->owner) {
- ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
- result, p->name, p->parent->name, sub ? sub->id:-1);
- mgcp_queue_hangup(p->sub);
- }
-
- if (p->sub->owner) {
- ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n",
- result, p->name, p->parent->name, sub ? sub->id:-1);
- mgcp_queue_hangup(p->sub);
- }
-
- dump_cmd_queues(p, NULL);
- }
- }
-
- if (resp) {
- if (req->cmd == MGCP_CMD_CRCX) {
- if ((c = get_header(resp, "I"))) {
- if (!ast_strlen_zero(c) && sub) {
- /* if we are hanging up do not process this conn. */
- if (sub->owner) {
- if (!ast_strlen_zero(sub->cxident)) {
- if (strcasecmp(c, sub->cxident)) {
- ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c);
- }
- }
- ast_copy_string(sub->cxident, c, sizeof(sub->cxident));
- if (sub->tmpdest.sin_addr.s_addr) {
- transmit_modify_with_sdp(sub, NULL, 0);
- }
- } else {
- /* XXX delete this one
- callid and conn id may already be lost.
- so the following del conn may have a side effect of
- cleaning up the next subchannel */
- transmit_connection_del(sub);
- }
- }
- }
- }
-
- if (req->cmd == MGCP_CMD_AUEP) {
- /* check stale connection ids */
- if ((c = get_header(resp, "I"))) {
- char *v, *n;
- int len;
- while ((v = get_csv(c, &len, &n))) {
- if (len) {
- if (strncasecmp(v, p->sub->cxident, len) &&
- strncasecmp(v, p->sub->next->cxident, len)) {
- /* connection id not found. delete it */
- char cxident[80] = "";
-
- if (len > (sizeof(cxident) - 1))
- len = sizeof(cxident) - 1;
- ast_copy_string(cxident, v, len);
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Non existing connection id %s on %s@%s \n",
- cxident, p->name, gw->name);
- }
- transmit_connection_del_w_params(p, NULL, cxident);
- }
- }
- c = n;
- }
- }
-
- /* Try to determine the hookstate returned from an audit endpoint command */
- if ((c = get_header(resp, "ES"))) {
- if (!ast_strlen_zero(c)) {
- if (strstr(c, "hu")) {
- if (p->hookstate != MGCP_ONHOOK) {
- /* XXX cleanup if we think we are offhook XXX */
- if ((p->sub->owner || p->sub->next->owner ) &&
- p->hookstate == MGCP_OFFHOOK)
- mgcp_queue_hangup(sub);
- p->hookstate = MGCP_ONHOOK;
-
- /* update the requested events according to the new hookstate */
- transmit_notify_request(p->sub, "");
-
- /* verbose level check */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name);
- }
- }
- } else if (strstr(c, "hd")) {
- if (p->hookstate != MGCP_OFFHOOK) {
- p->hookstate = MGCP_OFFHOOK;
-
- /* update the requested events according to the new hookstate */
- transmit_notify_request(p->sub, "");
-
- /* verbose level check */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name);
- }
- }
- }
- }
- }
- }
-
- if (resp && resp->lines) {
- /* do not process sdp if we are hanging up. this may be a late response */
- if (sub && sub->owner) {
- if (!sub->rtp)
- start_rtp(sub);
- if (sub->rtp)
- process_sdp(sub, resp);
- }
- }
- }
-
- free(req);
-}
-
-static void start_rtp(struct mgcp_subchannel *sub)
-{
- ast_mutex_lock(&sub->lock);
- /* check again to be on the safe side */
- if (sub->rtp) {
- ast_rtp_destroy(sub->rtp);
- sub->rtp = NULL;
- }
- /* Allocate the RTP now */
- sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
- if (sub->rtp && sub->owner)
- sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
- if (sub->rtp)
- ast_rtp_setnat(sub->rtp, sub->nat);
-#if 0
- ast_rtp_set_callback(p->rtp, rtpready);
- ast_rtp_set_data(p->rtp, p);
-#endif
- /* Make a call*ID */
- snprintf(sub->callid, sizeof(sub->callid), "%08lx%s", ast_random(), sub->txident);
- /* Transmit the connection create */
- transmit_connect_with_sdp(sub, NULL);
- ast_mutex_unlock(&sub->lock);
-}
-
-static void *mgcp_ss(void *data)
-{
- struct ast_channel *chan = data;
- struct mgcp_subchannel *sub = chan->tech_pvt;
- struct mgcp_endpoint *p = sub->parent;
- /* char exten[AST_MAX_EXTENSION] = ""; */
- int len = 0;
- int timeout = firstdigittimeout;
- int res= 0;
- int getforward = 0;
- int loop_pause = 100;
-
- len = strlen(p->dtmf_buf);
-
- while(len < AST_MAX_EXTENSION-1) {
- res = 1; /* Assume that we will get a digit */
- while (strlen(p->dtmf_buf) == len){
- ast_safe_sleep(chan, loop_pause);
- timeout -= loop_pause;
- if (timeout <= 0){
- res = 0;
- break;
- }
- res = 1;
- }
-
- timeout = 0;
- len = strlen(p->dtmf_buf);
-
- if (!ast_ignore_pattern(chan->context, p->dtmf_buf)) {
- /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
- ast_indicate(chan, -1);
- } else {
- /* XXX Redundant? We should already be playing dialtone */
- /*tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/
- transmit_notify_request(sub, "L/dl");
- }
- if (ast_exists_extension(chan, chan->context, p->dtmf_buf, 1, p->cid_num)) {
- if (!res || !ast_matchmore_extension(chan, chan->context, p->dtmf_buf, 1, p->cid_num)) {
- if (getforward) {
- /* Record this as the forwarding extension */
- ast_copy_string(p->call_forward, p->dtmf_buf, sizeof(p->call_forward));
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n",
- p->call_forward, chan->name);
- }
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- if (res)
- break;
- usleep(500000);
- /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
- ast_indicate(chan, -1);
- sleep(1);
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/
- transmit_notify_request(sub, "L/dl");
- len = 0;
- getforward = 0;
- } else {
- /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
- ast_indicate(chan, -1);
- ast_copy_string(chan->exten, p->dtmf_buf, sizeof(chan->exten));
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- ast_set_callerid(chan,
- p->hidecallerid ? "" : p->cid_num,
- p->hidecallerid ? "" : p->cid_name,
- chan->cid.cid_ani ? NULL : p->cid_num);
- ast_setstate(chan, AST_STATE_RING);
- /*zt_enable_ec(p);*/
- if (p->dtmfmode & MGCP_DTMF_HYBRID) {
- p->dtmfmode |= MGCP_DTMF_INBAND;
- ast_indicate(chan, -1);
- }
- res = ast_pbx_run(chan);
- if (res) {
- ast_log(LOG_WARNING, "PBX exited non-zero\n");
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/
- /*transmit_notify_request(p, "nbz", 1);*/
- transmit_notify_request(sub, "G/cg");
- }
- return NULL;
- }
- } else {
- /* It's a match, but they just typed a digit, and there is an ambiguous match,
- so just set the timeout to matchdigittimeout and wait some more */
- timeout = matchdigittimeout;
- }
- } else if (res == 0) {
- ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/
- transmit_notify_request(sub, "G/cg");
- /*zt_wait_event(p->subs[index].zfd);*/
- ast_hangup(chan);
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- return NULL;
- } else if (p->hascallwaiting && p->callwaiting && !strcmp(p->dtmf_buf, "*70")) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
- }
- /* Disable call waiting if enabled */
- p->callwaiting = 0;
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- len = 0;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- timeout = firstdigittimeout;
- } else if (!strcmp(p->dtmf_buf,ast_pickup_ext())) {
- /* Scan all channels and see if any there
- * ringing channqels with that have call groups
- * that equal this channels pickup group
- */
- if (ast_pickup_call(chan)) {
- ast_log(LOG_WARNING, "No call pickup possible...\n");
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/
- transmit_notify_request(sub, "G/cg");
- }
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- ast_hangup(chan);
- return NULL;
- } else if (!p->hidecallerid && !strcmp(p->dtmf_buf, "*67")) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
- }
- /* Disable Caller*ID if enabled */
- p->hidecallerid = 1;
- ast_set_callerid(chan, "", "", NULL);
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- len = 0;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- timeout = firstdigittimeout;
- } else if (p->callreturn && !strcmp(p->dtmf_buf, "*69")) {
- res = 0;
- if (!ast_strlen_zero(p->lastcallerid)) {
- res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language);
- }
- if (!res)
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- break;
- } else if (!strcmp(p->dtmf_buf, "*78")) {
- /* Do not disturb */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name);
- }
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- p->dnd = 1;
- getforward = 0;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- len = 0;
- } else if (!strcmp(p->dtmf_buf, "*79")) {
- /* Do not disturb */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name);
- }
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- p->dnd = 0;
- getforward = 0;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- len = 0;
- } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*72")) {
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- getforward = 1;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- len = 0;
- } else if (p->cancallforward && !strcmp(p->dtmf_buf, "*73")) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name);
- }
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- memset(p->call_forward, 0, sizeof(p->call_forward));
- getforward = 0;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- len = 0;
- } else if (!strcmp(p->dtmf_buf, ast_parking_ext()) &&
- sub->next->owner && ast_bridged_channel(sub->next->owner)) {
- /* This is a three way call, the main call being a real channel,
- and we're parking the first call. */
- ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL);
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
- }
- break;
- } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(p->dtmf_buf, "*60")) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcallerid);
- }
- res = ast_db_put("blacklist", p->lastcallerid, "1");
- if (!res) {
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- len = 0;
- }
- } else if (p->hidecallerid && !strcmp(p->dtmf_buf, "*82")) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
- }
- /* Enable Caller*ID if enabled */
- p->hidecallerid = 0;
- ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
- /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/
- transmit_notify_request(sub, "L/sl");
- len = 0;
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- timeout = firstdigittimeout;
- } else if (!ast_canmatch_extension(chan, chan->context, p->dtmf_buf, 1, chan->cid.cid_num) &&
- ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", p->dtmf_buf, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
- break;
- }
- if (!timeout)
- timeout = gendigittimeout;
- if (len && !ast_ignore_pattern(chan->context, p->dtmf_buf))
- /*tone_zone_play_tone(p->subs[index].zfd, -1);*/
- ast_indicate(chan, -1);
- }
-#if 0
- for (;;) {
- res = ast_waitfordigit(chan, to);
- if (!res) {
- ast_log(LOG_DEBUG, "Timeout...\n");
- break;
- }
- if (res < 0) {
- ast_log(LOG_DEBUG, "Got hangup...\n");
- ast_hangup(chan);
- break;
- }
- exten[pos++] = res;
- if (!ast_ignore_pattern(chan->context, exten))
- ast_indicate(chan, -1);
- if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) {
- if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid))
- to = 3000;
- else
- to = 8000;
- } else
- break;
- }
- if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) {
- ast_copy_string(chan->exten, exten, sizeof(chan->exten)1);
- if (!p->rtp) {
- start_rtp(p);
- }
- ast_setstate(chan, AST_STATE_RING);
- chan->rings = 1;
- if (ast_pbx_run(chan)) {
- ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name);
- } else {
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- return NULL;
- }
- }
-#endif
- ast_hangup(chan);
- memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
- return NULL;
-}
-
-static int attempt_transfer(struct mgcp_endpoint *p)
-{
- /* *************************
- * I hope this works.
- * Copied out of chan_zap
- * Cross your fingers
- * *************************/
-
- /* In order to transfer, we need at least one of the channels to
- actually be in a call bridge. We can't conference two applications
- together (but then, why would we want to?) */
- if (ast_bridged_channel(p->sub->owner)) {
- /* The three-way person we're about to transfer to could still be in MOH, so
- stop if now if appropriate */
- if (ast_bridged_channel(p->sub->next->owner))
- ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
- if (p->sub->owner->_state == AST_STATE_RINGING) {
- ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING);
- }
- if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name);
- return -1;
- }
- /* Orphan the channel */
- unalloc_sub(p->sub->next);
- } else if (ast_bridged_channel(p->sub->next->owner)) {
- if (p->sub->owner->_state == AST_STATE_RINGING) {
- ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING);
- }
- ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
- if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name);
- return -1;
- }
- /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
- }
- p->sub = p->sub->next;
- unalloc_sub(p->sub->next);
- /* Tell the caller not to hangup */
- return 1;
- } else {
- ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
- p->sub->owner->name, p->sub->next->owner->name);
- p->sub->next->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- if (p->sub->next->owner) {
- p->sub->next->alreadygone = 1;
- mgcp_queue_hangup(p->sub->next);
- }
- }
- return 0;
-}
-
-static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
-{
- struct mgcp_endpoint *p = sub->parent;
- struct ast_channel *c;
- pthread_t t;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- /* Off hook / answer */
- if (sub->outgoing) {
- /* Answered */
- if (sub->owner) {
- if (ast_bridged_channel(sub->owner))
- ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
- sub->cxmode = MGCP_CX_SENDRECV;
- if (!sub->rtp) {
- start_rtp(sub);
- } else {
- transmit_modify_request(sub);
- }
- /*transmit_notify_request(sub, "aw");*/
- transmit_notify_request(sub, "");
- mgcp_queue_control(sub, AST_CONTROL_ANSWER);
- }
- } else {
- /* Start switch */
- /*sub->cxmode = MGCP_CX_SENDRECV;*/
- if (!sub->owner) {
- if (!sub->rtp) {
- start_rtp(sub);
- } else {
- transmit_modify_request(sub);
- }
- if (p->immediate) {
- /* The channel is immediately up. Start right away */
-#ifdef DLINK_BUGGY_FIRMWARE
- transmit_notify_request(sub, "rt");
-#else
- transmit_notify_request(sub, "G/rt");
-#endif
- c = mgcp_new(sub, AST_STATE_RING);
- if (!c) {
- ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
- transmit_notify_request(sub, "G/cg");
- ast_hangup(c);
- }
- } else {
- if (has_voicemail(p)) {
- transmit_notify_request(sub, "L/sl");
- } else {
- transmit_notify_request(sub, "L/dl");
- }
- c = mgcp_new(sub, AST_STATE_DOWN);
- if (c) {
- if (ast_pthread_create(&t, &attr, mgcp_ss, c)) {
- ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- } else {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name);
- }
- }
- } else {
- if (p->hookstate == MGCP_OFFHOOK) {
- ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name);
- } else {
- ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name);
- ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?\n");
- }
- if (ast_bridged_channel(sub->owner))
- ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
- sub->cxmode = MGCP_CX_SENDRECV;
- if (!sub->rtp) {
- start_rtp(sub);
- } else {
- transmit_modify_request(sub);
- }
- /*transmit_notify_request(sub, "aw");*/
- transmit_notify_request(sub, "");
- /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/
- }
- }
- pthread_attr_destroy(&attr);
-}
-
-static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
-{
- char *ev, *s;
- struct ast_frame f = { 0, };
- struct mgcp_endpoint *p = sub->parent;
- struct mgcp_gateway *g = NULL;
- int res;
-
- if (mgcpdebug) {
- ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name);
- }
- /* Clear out potential response */
- if (!strcasecmp(req->verb, "RSIP")) {
- /* Test if this RSIP request is just a keepalive */
- if(!strcasecmp( get_header(req, "RM"), "X-keepalive")) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Received keepalive request from %s@%s\n", p->name, p->parent->name);
- transmit_response(sub, "200", req, "OK");
- } else {
- dump_queue(p->parent, p);
- dump_cmd_queues(p, NULL);
-
- if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) {
- ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name);
- }
- /* For RSIP on wildcard we reset all endpoints */
- if (!strcmp(p->name, p->parent->wcardep)) {
- /* Reset all endpoints */
- struct mgcp_endpoint *tmp_ep;
-
- g = p->parent;
- tmp_ep = g->endpoints;
- while (tmp_ep) {
- /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/
- if (strcmp(tmp_ep->name, g->wcardep) != 0) {
- struct mgcp_subchannel *tmp_sub, *first_sub;
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name);
- }
-
- first_sub = tmp_ep->sub;
- tmp_sub = tmp_ep->sub;
- while (tmp_sub) {
- mgcp_queue_hangup(tmp_sub);
- tmp_sub = tmp_sub->next;
- if (tmp_sub == first_sub)
- break;
- }
- }
- tmp_ep = tmp_ep->next;
- }
- } else if (sub->owner) {
- mgcp_queue_hangup(sub);
- }
- transmit_response(sub, "200", req, "OK");
- /* We dont send NTFY or AUEP to wildcard ep */
- if (strcmp(p->name, p->parent->wcardep) != 0) {
- transmit_notify_request(sub, "");
- /* Audit endpoint.
- Idea is to prevent lost lines due to race conditions
- */
- transmit_audit_endpoint(p);
- }
- }
- } else if (!strcasecmp(req->verb, "NTFY")) {
- /* Acknowledge and be sure we keep looking for the same things */
- transmit_response(sub, "200", req, "OK");
- /* Notified of an event */
- ev = get_header(req, "O");
- s = strchr(ev, '/');
- if (s) ev = s + 1;
- ast_log(LOG_DEBUG, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev);
- /* Keep looking for events unless this was a hangup */
- if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) {
- transmit_notify_request(sub, p->curtone);
- }
- if (!strcasecmp(ev, "hd")) {
- p->hookstate = MGCP_OFFHOOK;
- sub->cxmode = MGCP_CX_SENDRECV;
- handle_hd_hf(sub, ev);
- } else if (!strcasecmp(ev, "hf")) {
- /* We can assume we are offhook if we received a hookflash */
- /* First let's just do call wait and ignore threeway */
- /* We're currently in charge */
- if (p->hookstate != MGCP_OFFHOOK) {
- /* Cisco c7940 sends hf even if the phone is onhook */
- /* Thanks to point on IRC for pointing this out */
- return -1;
- }
- /* do not let * conference two down channels */
- if (sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner)
- return -1;
-
- if (p->callwaiting || p->transfer || p->threewaycalling) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
- }
- p->sub = p->sub->next;
-
- /* transfer control to our next subchannel */
- if (!sub->next->owner) {
- /* plave the first call on hold and start up a new call */
- sub->cxmode = MGCP_CX_MUTE;
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
- }
- transmit_modify_request(sub);
- if (sub->owner && ast_bridged_channel(sub->owner))
- ast_queue_control(sub->owner, AST_CONTROL_HOLD);
- sub->next->cxmode = MGCP_CX_RECVONLY;
- handle_hd_hf(sub->next, ev);
- } else if (sub->owner && sub->next->owner) {
- /* We've got two active calls lets decide whether or not to conference or just flip flop */
- if ((!sub->outgoing) && (!sub->next->outgoing)) {
- /* We made both calls lets conferenct */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n",
- sub->id, sub->next->id, p->name, p->parent->name);
- }
- sub->cxmode = MGCP_CX_CONF;
- sub->next->cxmode = MGCP_CX_CONF;
- if (ast_bridged_channel(sub->next->owner))
- ast_queue_control(sub->next->owner, AST_CONTROL_UNHOLD);
- transmit_modify_request(sub);
- transmit_modify_request(sub->next);
- } else {
- /* Let's flipflop between calls */
- /* XXX Need to check for state up ??? */
- /* XXX Need a way to indicate the current call, or maybe the call that's waiting */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n",
- sub->id, sub->next->id, p->name, p->parent->name);
- }
- sub->cxmode = MGCP_CX_MUTE;
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
- }
- transmit_modify_request(sub);
- if (ast_bridged_channel(sub->owner))
- ast_queue_control(sub->owner, AST_CONTROL_HOLD);
-
- if (ast_bridged_channel(sub->next->owner))
- ast_queue_control(sub->next->owner, AST_CONTROL_HOLD);
-
- handle_hd_hf(sub->next, ev);
- }
- } else {
- /* We've most likely lost one of our calls find an active call and bring it up */
- if (sub->owner) {
- p->sub = sub;
- } else if (sub->next->owner) {
- p->sub = sub->next;
- } else {
- /* We seem to have lost both our calls */
- /* XXX - What do we do now? */
- return -1;
- }
- if (ast_bridged_channel(p->sub->owner))
- ast_queue_control(p->sub->owner, AST_CONTROL_UNHOLD);
- p->sub->cxmode = MGCP_CX_SENDRECV;
- transmit_modify_request(p->sub);
- }
- } else {
- ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n",
- p->name, p->parent->name);
- }
- } else if (!strcasecmp(ev, "hu")) {
- p->hookstate = MGCP_ONHOOK;
- sub->cxmode = MGCP_CX_RECVONLY;
- ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name);
- /* Do we need to send MDCX before a DLCX ?
- if (sub->rtp) {
- transmit_modify_request(sub);
- }
- */
- if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) {
- /* We're allowed to transfer, we have two avtive calls and */
- /* we made at least one of the calls. Let's try and transfer */
- ast_mutex_lock(&p->sub->next->lock);
- res = attempt_transfer(p);
- if (res < 0) {
- if (p->sub->next->owner) {
- sub->next->alreadygone = 1;
- mgcp_queue_hangup(sub->next);
- }
- } else if (res) {
- ast_log(LOG_WARNING, "Transfer attempt failed\n");
- ast_mutex_unlock(&p->sub->next->lock);
- return -1;
- }
- ast_mutex_unlock(&p->sub->next->lock);
- } else {
- /* Hangup the current call */
- /* If there is another active call, mgcp_hangup will ring the phone with the other call */
- if (sub->owner) {
- sub->alreadygone = 1;
- mgcp_queue_hangup(sub);
- } else {
- /* verbose level check */
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n",
- p->name, p->parent->name, sub->id);
- }
- /* Instruct the other side to remove the connection since it apparently *
- * still thinks the channel is active. *
- * For Cisco IAD2421 /BAK/ */
- transmit_connection_del(sub);
- }
- }
- if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) {
- p->hidecallerid = 0;
- if (p->hascallwaiting && !p->callwaiting) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id);
- p->callwaiting = -1;
- }
- if (has_voicemail(p)) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name);
- }
- transmit_notify_request(sub, "L/vmwi(+)");
- } else {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name);
- }
- transmit_notify_request(sub, "L/vmwi(-)");
- }
- }
- } else if ((strlen(ev) == 1) &&
- (((ev[0] >= '0') && (ev[0] <= '9')) ||
- ((ev[0] >= 'A') && (ev[0] <= 'D')) ||
- (ev[0] == '*') || (ev[0] == '#'))) {
- if (sub && sub->owner && (sub->owner->_state >= AST_STATE_UP)) {
- f.frametype = AST_FRAME_DTMF;
- f.subclass = ev[0];
- f.src = "mgcp";
- /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */
- mgcp_queue_frame(sub, &f);
- ast_mutex_lock(&sub->next->lock);
- if (sub->next->owner)
- mgcp_queue_frame(sub->next, &f);
- ast_mutex_unlock(&sub->next->lock);
- if (strstr(p->curtone, "wt") && (ev[0] == 'A')) {
- memset(p->curtone, 0, sizeof(p->curtone));
- }
- } else {
- p->dtmf_buf[strlen(p->dtmf_buf)] = ev[0];
- p->dtmf_buf[strlen(p->dtmf_buf)] = '\0';
- }
- } else if (!strcasecmp(ev, "T")) {
- /* Digit timeout -- unimportant */
- } else if (!strcasecmp(ev, "ping")) {
- /* ping -- unimportant */
- } else {
- ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name);
- }
- } else {
- ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(sin->sin_addr));
- transmit_response(sub, "510", req, "Unknown verb");
- }
- return 0;
-}
-
-static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *req)
-{
- int seqno=0;
- time_t now;
- struct mgcp_response *prev = NULL, *cur, *next, *answer=NULL;
- time(&now);
- if (sscanf(req->identifier, "%d", &seqno) != 1)
- seqno = 0;
- cur = sub->parent->parent->responses;
- while(cur) {
- next = cur->next;
- if (now - cur->whensent > RESPONSE_TIMEOUT) {
- /* Delete this entry */
- if (prev)
- prev->next = next;
- else
- sub->parent->parent->responses = next;
- free(cur);
- } else {
- if (seqno == cur->seqno)
- answer = cur;
- prev = cur;
- }
- cur = next;
- }
- if (answer) {
- resend_response(sub, answer);
- return 1;
- }
- return 0;
-}
-
-static int mgcpsock_read(int *id, int fd, short events, void *ignore)
-{
- struct mgcp_request req;
- struct sockaddr_in sin;
- struct mgcp_subchannel *sub;
- int res;
- socklen_t len;
- int result;
- int ident;
- len = sizeof(sin);
- memset(&req, 0, sizeof(req));
- res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
- if (res < 0) {
- if (errno != ECONNREFUSED)
- ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
- return 1;
- }
- req.data[res] = '\0';
- req.len = res;
- if (mgcpdebug) {
- ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- }
- parse(&req);
- if (req.headers < 1) {
- /* Must have at least one header */
- return 1;
- }
- if (ast_strlen_zero(req.identifier)) {
- ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin.sin_addr));
- return 1;
- }
-
- if (sscanf(req.verb, "%d", &result) && sscanf(req.identifier, "%d", &ident)) {
- /* Try to find who this message is for, if it's important */
- sub = find_subchannel_and_lock(NULL, ident, &sin);
- if (sub) {
- struct mgcp_gateway *gw = sub->parent->parent;
- struct mgcp_message *cur, *prev;
-
- ast_mutex_unlock(&sub->lock);
- ast_mutex_lock(&gw->msgs_lock);
- for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
- if (cur->seqno == ident) {
- ast_log(LOG_DEBUG, "Got response back on transaction %d\n", ident);
- if (prev)
- prev->next = cur->next;
- else
- gw->msgs = cur->next;
- break;
- }
- }
-
- /* stop retrans timer if the queue is empty */
- if (!gw->msgs) {
- AST_SCHED_DEL(sched, gw->retransid);
- }
-
- ast_mutex_unlock(&gw->msgs_lock);
- if (cur) {
- handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req);
- free(cur);
- return 1;
- }
-
- ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n",
- gw->name, ident);
- }
- } else {
- if (ast_strlen_zero(req.endpoint) ||
- ast_strlen_zero(req.version) ||
- ast_strlen_zero(req.verb)) {
- ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
- return 1;
- }
- /* Process request, with iflock held */
- sub = find_subchannel_and_lock(req.endpoint, 0, &sin);
- if (sub) {
- /* look first to find a matching response in the queue */
- if (!find_and_retrans(sub, &req))
- /* pass the request off to the currently mastering subchannel */
- handle_request(sub, &req, &sin);
- ast_mutex_unlock(&sub->lock);
- }
- }
- return 1;
-}
-
-static int *mgcpsock_read_id = NULL;
-
-static void *do_monitor(void *data)
-{
- int res;
- int reloading;
- /*struct mgcp_gateway *g;*/
- /*struct mgcp_endpoint *e;*/
- /*time_t thispass = 0, lastpass = 0;*/
-
- /* Add an I/O event to our UDP socket */
- if (mgcpsock > -1)
- mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL);
-
- /* This thread monitors all the frame relay interfaces which are not yet in use
- (and thus do not have a separate thread) indefinitely */
- /* From here on out, we die whenever asked */
- for(;;) {
- /* Check for a reload request */
- ast_mutex_lock(&mgcp_reload_lock);
- reloading = mgcp_reloading;
- mgcp_reloading = 0;
- ast_mutex_unlock(&mgcp_reload_lock);
- if (reloading) {
- if (option_verbose > 0)
- ast_verbose(VERBOSE_PREFIX_1 "Reloading MGCP\n");
- mgcp_do_reload();
- /* Add an I/O event to our UDP socket */
- if (mgcpsock > -1)
- mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL);
- }
-
- /* Check for interfaces needing to be killed */
- /* Don't let anybody kill us right away. Nobody should lock the interface list
- and wait for the monitor list, but the other way around is okay. */
- ast_mutex_lock(&monlock);
- /* Lock the network interface */
- ast_mutex_lock(&netlock);
-
-#if 0
- /* XXX THIS IS COMPLETELY HOSED */
- /* The gateway goes into a state of panic */
- /* If the vmwi indicator is sent while it is reseting interfaces */
- lastpass = thispass;
- thispass = time(NULL);
- g = gateways;
- while(g) {
- if (thispass != lastpass) {
- e = g->endpoints;
- while(e) {
- if (e->type == TYPE_LINE) {
- res = has_voicemail(e);
- if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){
- if (res) {
- transmit_notify_request(e, "L/vmwi(+)");
- } else {
- transmit_notify_request(e, "L/vmwi(-)");
- }
- e->msgstate = res;
- e->onhooktime = thispass;
- }
- }
- e = e->next;
- }
- }
- g = g->next;
- }
-#endif
- /* Okay, now that we know what to do, release the network lock */
- ast_mutex_unlock(&netlock);
- /* And from now on, we're okay to be killed, so release the monitor lock as well */
- ast_mutex_unlock(&monlock);
- pthread_testcancel();
- /* Wait for sched or io */
- res = ast_sched_wait(sched);
- /* copied from chan_sip.c */
- if ((res < 0) || (res > 1000))
- res = 1000;
- res = ast_io_wait(io, res);
- ast_mutex_lock(&monlock);
- if (res >= 0)
- ast_sched_runq(sched);
- ast_mutex_unlock(&monlock);
- }
- /* Never reached */
- return NULL;
-}
-
-static int restart_monitor(void)
-{
- /* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == AST_PTHREADT_STOP)
- return 0;
- if (ast_mutex_lock(&monlock)) {
- ast_log(LOG_WARNING, "Unable to lock monitor\n");
- return -1;
- }
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread != AST_PTHREADT_NULL) {
- /* Wake up the thread */
- pthread_kill(monitor_thread, SIGURG);
- } else {
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- return -1;
- }
- }
- ast_mutex_unlock(&monlock);
- return 0;
-}
-
-static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause)
-{
- int oldformat;
- struct mgcp_subchannel *sub;
- struct ast_channel *tmpc = NULL;
- char tmp[256];
- char *dest = data;
-
- oldformat = format;
- format &= capability;
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
- return NULL;
- }
- ast_copy_string(tmp, dest, sizeof(tmp));
- if (ast_strlen_zero(tmp)) {
- ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n");
- return NULL;
- }
- sub = find_subchannel_and_lock(tmp, 0, NULL);
- if (!sub) {
- ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
- *cause = AST_CAUSE_UNREGISTERED;
- return NULL;
- }
-
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_request(%s)\n", tmp);
- ast_verbose(VERBOSE_PREFIX_3 "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n",
- sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0);
- }
- /* Must be busy */
- if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) ||
- ((!sub->parent->callwaiting) && (sub->owner)) ||
- (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) {
- if (sub->parent->hookstate == MGCP_ONHOOK) {
- if (has_voicemail(sub->parent)) {
- transmit_notify_request(sub,"L/vmwi(+)");
- } else {
- transmit_notify_request(sub,"L/vmwi(-)");
- }
- }
- *cause = AST_CAUSE_BUSY;
- ast_mutex_unlock(&sub->lock);
- return NULL;
- }
- tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN);
- ast_mutex_unlock(&sub->lock);
- if (!tmpc)
- ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
- restart_monitor();
- return tmpc;
-}
-
-/* modified for reload support */
-/*! \brief build_gateway: parse mgcp.conf and create gateway/endpoint structures */
-static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
-{
- struct mgcp_gateway *gw;
- struct mgcp_endpoint *e;
- struct mgcp_subchannel *sub;
- /*char txident[80];*/
- int i=0, y=0;
- int gw_reload = 0;
- int ep_reload = 0;
- canreinvite = CANREINVITE;
-
- /* locate existing gateway */
- gw = gateways;
- while (gw) {
- if (!strcasecmp(cat, gw->name)) {
- /* gateway already exists */
- gw->delme = 0;
- gw_reload = 1;
- break;
- }
- gw = gw->next;
- }
-
- if (!gw)
- gw = malloc(sizeof(struct mgcp_gateway));
-
- if (gw) {
- if (!gw_reload) {
- memset(gw, 0, sizeof(struct mgcp_gateway));
- gw->expire = -1;
- gw->retransid = -1; /* SC */
- ast_mutex_init(&gw->msgs_lock);
- ast_copy_string(gw->name, cat, sizeof(gw->name));
- /* check if the name is numeric ip */
- if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE)
- gw->isnamedottedip = 1;
- }
- while(v) {
- if (!strcasecmp(v->name, "host")) {
- if (!strcasecmp(v->value, "dynamic")) {
- /* They'll register with us */
- gw->dynamic = 1;
- memset(&gw->addr.sin_addr, 0, 4);
- if (gw->addr.sin_port) {
- /* If we've already got a port, make it the default rather than absolute */
- gw->defaddr.sin_port = gw->addr.sin_port;
- gw->addr.sin_port = 0;
- }
- } else {
- /* Non-dynamic. Make sure we become that way if we're not */
- AST_SCHED_DEL(sched, gw->expire);
- gw->dynamic = 0;
- if (ast_get_ip(&gw->addr, v->value)) {
- if (!gw_reload) {
- ast_mutex_destroy(&gw->msgs_lock);
- free(gw);
- }
- return NULL;
- }
- }
- } else if (!strcasecmp(v->name, "defaultip")) {
- if (ast_get_ip(&gw->defaddr, v->value)) {
- if (!gw_reload) {
- ast_mutex_destroy(&gw->msgs_lock);
- free(gw);
- }
- return NULL;
- }
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- gw->ha = ast_append_ha(v->name, v->value, gw->ha);
- } else if (!strcasecmp(v->name, "port")) {
- gw->addr.sin_port = htons(atoi(v->value));
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(context, v->value, sizeof(context));
- } else if (!strcasecmp(v->name, "dtmfmode")) {
- if (!strcasecmp(v->value, "inband"))
- dtmfmode = MGCP_DTMF_INBAND;
- else if (!strcasecmp(v->value, "rfc2833"))
- dtmfmode = MGCP_DTMF_RFC2833;
- else if (!strcasecmp(v->value, "hybrid"))
- dtmfmode = MGCP_DTMF_HYBRID;
- else if (!strcasecmp(v->value, "none"))
- dtmfmode = 0;
- else
- ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno);
- } else if (!strcasecmp(v->name, "nat")) {
- nat = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callerid")) {
- if (!strcasecmp(v->value, "asreceived")) {
- cid_num[0] = '\0';
- cid_name[0] = '\0';
- } else {
- ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
- }
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(language, v->value, sizeof(language));
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(accountcode, v->value, sizeof(accountcode));
- } else if (!strcasecmp(v->name, "amaflags")) {
- y = ast_cdr_amaflags2int(v->value);
- if (y < 0) {
- ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
- } else {
- amaflags = y;
- }
- } else if (!strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(musicclass, v->value, sizeof(musicclass));
- } else if (!strcasecmp(v->name, "callgroup")) {
- cur_callergroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "pickupgroup")) {
- cur_pickupgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "immediate")) {
- immediate = ast_true(v->value);
- } else if (!strcasecmp(v->name, "cancallforward")) {
- cancallforward = ast_true(v->value);
- } else if (!strcasecmp(v->name, "singlepath")) {
- singlepath = ast_true(v->value);
- } else if (!strcasecmp(v->name, "canreinvite")) {
- canreinvite = ast_true(v->value);
- } else if (!strcasecmp(v->name, "mailbox")) {
- ast_copy_string(mailbox, v->value, sizeof(mailbox));
- } else if (!strcasecmp(v->name, "adsi")) {
- adsi = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callreturn")) {
- callreturn = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callwaiting")) {
- callwaiting = ast_true(v->value);
- } else if (!strcasecmp(v->name, "slowsequence")) {
- slowsequence = ast_true(v->value);
- } else if (!strcasecmp(v->name, "transfer")) {
- transfer = ast_true(v->value);
- } else if (!strcasecmp(v->name, "threewaycalling")) {
- threewaycalling = ast_true(v->value);
- } else if (!strcasecmp(v->name, "wcardep")) {
- /* locate existing endpoint */
- e = gw->endpoints;
- while (e) {
- if (!strcasecmp(v->value, e->name)) {
- /* endpoint already exists */
- e->delme = 0;
- ep_reload = 1;
- break;
- }
- e = e->next;
- }
-
- if (!e) {
- /* Allocate wildcard endpoint */
- e = malloc(sizeof(struct mgcp_endpoint));
- ep_reload = 0;
- }
-
- if (e) {
- if (!ep_reload) {
- memset(e, 0, sizeof(struct mgcp_endpoint));
- ast_mutex_init(&e->lock);
- ast_mutex_init(&e->rqnt_queue_lock);
- ast_mutex_init(&e->cmd_queue_lock);
- ast_copy_string(e->name, v->value, sizeof(e->name));
- e->needaudit = 1;
- }
- ast_copy_string(gw->wcardep, v->value, sizeof(gw->wcardep));
- /* XXX Should we really check for uniqueness?? XXX */
- ast_copy_string(e->accountcode, accountcode, sizeof(e->accountcode));
- ast_copy_string(e->context, context, sizeof(e->context));
- ast_copy_string(e->cid_num, cid_num, sizeof(e->cid_num));
- ast_copy_string(e->cid_name, cid_name, sizeof(e->cid_name));
- ast_copy_string(e->language, language, sizeof(e->language));
- ast_copy_string(e->musicclass, musicclass, sizeof(e->musicclass));
- ast_copy_string(e->mailbox, mailbox, sizeof(e->mailbox));
- snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", ast_random());
- e->msgstate = -1;
- e->amaflags = amaflags;
- e->capability = capability;
- e->parent = gw;
- e->dtmfmode = dtmfmode;
- if (!ep_reload && e->sub && e->sub->rtp)
- e->dtmfmode |= MGCP_DTMF_INBAND;
- e->adsi = adsi;
- e->type = TYPE_LINE;
- e->immediate = immediate;
- e->callgroup=cur_callergroup;
- e->pickupgroup=cur_pickupgroup;
- e->callreturn = callreturn;
- e->cancallforward = cancallforward;
- e->singlepath = singlepath;
- e->canreinvite = canreinvite;
- e->callwaiting = callwaiting;
- e->hascallwaiting = callwaiting;
- e->slowsequence = slowsequence;
- e->transfer = transfer;
- e->threewaycalling = threewaycalling;
- e->onhooktime = time(NULL);
- /* ASSUME we're onhook */
- e->hookstate = MGCP_ONHOOK;
- if (!ep_reload) {
- /*snprintf(txident, sizeof(txident), "%08lx", ast_random());*/
- for (i = 0; i < MAX_SUBS; i++) {
- sub = malloc(sizeof(struct mgcp_subchannel));
- if (sub) {
- ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name);
- memset(sub, 0, sizeof(struct mgcp_subchannel));
- ast_mutex_init(&sub->lock);
- ast_mutex_init(&sub->cx_queue_lock);
- sub->parent = e;
- sub->id = i;
- snprintf(sub->txident, sizeof(sub->txident), "%08lx", ast_random());
- /*stnrcpy(sub->txident, txident, sizeof(sub->txident) - 1);*/
- sub->cxmode = MGCP_CX_INACTIVE;
- sub->nat = nat;
- sub->next = e->sub;
- e->sub = sub;
- } else {
- /* XXX Should find a way to clean up our memory */
- ast_log(LOG_WARNING, "Out of memory allocating subchannel\n");
- return NULL;
- }
- }
- /* Make out subs a circular linked list so we can always sping through the whole bunch */
- sub = e->sub;
- /* find the end of the list */
- while(sub->next){
- sub = sub->next;
- }
- /* set the last sub->next to the first sub */
- sub->next = e->sub;
-
- e->next = gw->endpoints;
- gw->endpoints = e;
- }
- }
- } else if (!strcasecmp(v->name, "trunk") ||
- !strcasecmp(v->name, "line")) {
-
- /* locate existing endpoint */
- e = gw->endpoints;
- while (e) {
- if (!strcasecmp(v->value, e->name)) {
- /* endpoint already exists */
- e->delme = 0;
- ep_reload = 1;
- break;
- }
- e = e->next;
- }
-
- if (!e) {
- e = malloc(sizeof(struct mgcp_endpoint));
- ep_reload = 0;
- }
-
- if (e) {
- if (!ep_reload) {
- memset(e, 0, sizeof(struct mgcp_endpoint));
- ast_mutex_init(&e->lock);
- ast_mutex_init(&e->rqnt_queue_lock);
- ast_mutex_init(&e->cmd_queue_lock);
- ast_copy_string(e->name, v->value, sizeof(e->name));
- e->needaudit = 1;
- }
- /* XXX Should we really check for uniqueness?? XXX */
- ast_copy_string(e->accountcode, accountcode, sizeof(e->accountcode));
- ast_copy_string(e->context, context, sizeof(e->context));
- ast_copy_string(e->cid_num, cid_num, sizeof(e->cid_num));
- ast_copy_string(e->cid_name, cid_name, sizeof(e->cid_name));
- ast_copy_string(e->language, language, sizeof(e->language));
- ast_copy_string(e->musicclass, musicclass, sizeof(e->musicclass));
- ast_copy_string(e->mailbox, mailbox, sizeof(e->mailbox));
- if (!ast_strlen_zero(mailbox)) {
- ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, gw->name, e->name);
- }
- if (!ep_reload) {
- /* XXX potential issue due to reload */
- e->msgstate = -1;
- e->parent = gw;
- }
- e->amaflags = amaflags;
- e->capability = capability;
- e->dtmfmode = dtmfmode;
- e->adsi = adsi;
- if (!strcasecmp(v->name, "trunk"))
- e->type = TYPE_TRUNK;
- else
- e->type = TYPE_LINE;
-
- e->immediate = immediate;
- e->callgroup=cur_callergroup;
- e->pickupgroup=cur_pickupgroup;
- e->callreturn = callreturn;
- e->cancallforward = cancallforward;
- e->canreinvite = canreinvite;
- e->singlepath = singlepath;
- e->callwaiting = callwaiting;
- e->hascallwaiting = callwaiting;
- e->slowsequence = slowsequence;
- e->transfer = transfer;
- e->threewaycalling = threewaycalling;
- if (!ep_reload) {
- e->onhooktime = time(NULL);
- /* ASSUME we're onhook */
- e->hookstate = MGCP_ONHOOK;
- snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", ast_random());
- }
-
- for (i = 0, sub = NULL; i < MAX_SUBS; i++) {
- if (!ep_reload) {
- sub = malloc(sizeof(struct mgcp_subchannel));
- } else {
- if (!sub)
- sub = e->sub;
- else
- sub = sub->next;
- }
-
- if (sub) {
- if (!ep_reload) {
- ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name);
- memset(sub, 0, sizeof(struct mgcp_subchannel));
- ast_mutex_init(&sub->lock);
- ast_mutex_init(&sub->cx_queue_lock);
- ast_copy_string(sub->magic, MGCP_SUBCHANNEL_MAGIC, sizeof(sub->magic));
- sub->parent = e;
- sub->id = i;
- snprintf(sub->txident, sizeof(sub->txident), "%08lx", ast_random());
- sub->cxmode = MGCP_CX_INACTIVE;
- sub->next = e->sub;
- e->sub = sub;
- }
- sub->nat = nat;
- } else {
- /* XXX Should find a way to clean up our memory */
- ast_log(LOG_WARNING, "Out of memory allocating subchannel\n");
- return NULL;
- }
- }
- if (!ep_reload) {
- /* Make out subs a circular linked list so we can always sping through the whole bunch */
- sub = e->sub;
- /* find the end of the list */
- while (sub->next) {
- sub = sub->next;
- }
- /* set the last sub->next to the first sub */
- sub->next = e->sub;
-
- e->next = gw->endpoints;
- gw->endpoints = e;
- }
- }
- } else
- ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
- v = v->next;
- }
- }
- if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) {
- ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name);
- if (!gw_reload) {
- ast_mutex_destroy(&gw->msgs_lock);
- free(gw);
- }
- return NULL;
- }
- gw->defaddr.sin_family = AF_INET;
- gw->addr.sin_family = AF_INET;
- if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port))
- gw->defaddr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
- if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port))
- gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
- if (gw->addr.sin_addr.s_addr)
- if (ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip))
- memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
-
- return (gw_reload ? NULL : gw);
-}
-
-static enum ast_rtp_get_result mgcp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
-{
- struct mgcp_subchannel *sub = NULL;
-
- if (!(sub = chan->tech_pvt) || !(sub->rtp))
- return AST_RTP_GET_FAILED;
-
- *rtp = sub->rtp;
-
- if (sub->parent->canreinvite)
- return AST_RTP_TRY_NATIVE;
- else
- return AST_RTP_TRY_PARTIAL;
-}
-
-static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
-{
- /* XXX Is there such thing as video support with MGCP? XXX */
- struct mgcp_subchannel *sub;
- sub = chan->tech_pvt;
- if (sub && !sub->alreadygone) {
- transmit_modify_with_sdp(sub, rtp, codecs);
- return 0;
- }
- return -1;
-}
-
-static struct ast_rtp_protocol mgcp_rtp = {
- .type = "MGCP",
- .get_rtp_info = mgcp_get_rtp_peer,
- .set_rtp_peer = mgcp_set_rtp_peer,
-};
-
-static void destroy_endpoint(struct mgcp_endpoint *e)
-{
- struct mgcp_subchannel *sub = e->sub->next, *s;
- int i;
-
- for (i = 0; i < MAX_SUBS; i++) {
- ast_mutex_lock(&sub->lock);
- if (!ast_strlen_zero(sub->cxident)) {
- transmit_connection_del(sub);
- }
- if (sub->rtp) {
- ast_rtp_destroy(sub->rtp);
- sub->rtp = NULL;
- }
- memset(sub->magic, 0, sizeof(sub->magic));
- mgcp_queue_hangup(sub);
- dump_cmd_queues(NULL, sub);
- ast_mutex_unlock(&sub->lock);
- sub = sub->next;
- }
-
- if (e->dsp) {
- ast_dsp_free(e->dsp);
- }
-
- dump_queue(e->parent, e);
- dump_cmd_queues(e, NULL);
-
- sub = e->sub;
- for (i = 0; (i < MAX_SUBS) && sub; i++) {
- s = sub;
- sub = sub->next;
- ast_mutex_destroy(&s->lock);
- ast_mutex_destroy(&s->cx_queue_lock);
- free(s);
- }
- ast_mutex_destroy(&e->lock);
- ast_mutex_destroy(&e->rqnt_queue_lock);
- ast_mutex_destroy(&e->cmd_queue_lock);
- free(e);
-}
-
-static void destroy_gateway(struct mgcp_gateway *g)
-{
- if (g->ha)
- ast_free_ha(g->ha);
-
- dump_queue(g, NULL);
-
- free (g);
-}
-
-static void prune_gateways(void)
-{
- struct mgcp_gateway *g, *z, *r;
- struct mgcp_endpoint *e, *p, *t;
-
- ast_mutex_lock(&gatelock);
-
- /* prune gateways */
- for (z = NULL, g = gateways; g;) {
- /* prune endpoints */
- for (p = NULL, e = g->endpoints; e; ) {
- if (e->delme || g->delme) {
- t = e;
- e = e->next;
- if (!p)
- g->endpoints = e;
- else
- p->next = e;
- destroy_endpoint(t);
- } else {
- p = e;
- e = e->next;
- }
- }
-
- if (g->delme) {
- r = g;
- g = g->next;
- if (!z)
- gateways = g;
- else
- z->next = g;
-
- destroy_gateway(r);
- } else {
- z = g;
- g = g->next;
- }
- }
-
- ast_mutex_unlock(&gatelock);
-}
-
-static int reload_config(void)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- struct mgcp_gateway *g;
- struct mgcp_endpoint *e;
- char *cat;
- struct ast_hostent ahp;
- struct hostent *hp;
- int format;
-
- if (gethostname(ourhost, sizeof(ourhost)-1)) {
- ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n");
- return 0;
- }
- cfg = ast_config_load(config);
-
- /* We *must* have a config file otherwise stop immediately */
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config);
- return 0;
- }
- memset(&bindaddr, 0, sizeof(bindaddr));
- dtmfmode = 0;
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- v = ast_variable_browse(cfg, "general");
- while (v) {
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
- v = v->next;
- continue;
- }
-
- /* Create the interface list */
- if (!strcasecmp(v->name, "bindaddr")) {
- if (!(hp = ast_gethostbyname(v->value, &ahp))) {
- ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
- } else {
- memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
- }
- } else if (!strcasecmp(v->name, "allow")) {
- format = ast_getformatbyname(v->value);
- if (format < 1)
- ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
- else
- capability |= format;
- } else if (!strcasecmp(v->name, "disallow")) {
- format = ast_getformatbyname(v->value);
- if (format < 1)
- ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
- else
- capability &= ~format;
- } else if (!strcasecmp(v->name, "tos")) {
- if (sscanf(v->value, "%d", &format) == 1)
- tos = format & 0xff;
- else if (!strcasecmp(v->value, "lowdelay"))
- tos = IPTOS_LOWDELAY;
- else if (!strcasecmp(v->value, "throughput"))
- tos = IPTOS_THROUGHPUT;
- else if (!strcasecmp(v->value, "reliability"))
- tos = IPTOS_RELIABILITY;
- else if (!strcasecmp(v->value, "mincost"))
- tos = IPTOS_MINCOST;
- else if (!strcasecmp(v->value, "none"))
- tos = 0;
- else
- ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
- } else if (!strcasecmp(v->name, "port")) {
- if (sscanf(v->value, "%d", &ourport) == 1) {
- bindaddr.sin_port = htons(ourport);
- } else {
- ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
- }
- }
- v = v->next;
- }
-
- /* mark existing entries for deletion */
- ast_mutex_lock(&gatelock);
- g = gateways;
- while (g) {
- g->delme = 1;
- e = g->endpoints;
- while (e) {
- e->delme = 1;
- e = e->next;
- }
- g = g->next;
- }
- ast_mutex_unlock(&gatelock);
-
- cat = ast_category_browse(cfg, NULL);
- while(cat) {
- if (strcasecmp(cat, "general")) {
- ast_mutex_lock(&gatelock);
- g = build_gateway(cat, ast_variable_browse(cfg, cat));
- if (g) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Added gateway '%s'\n", g->name);
- }
- g->next = gateways;
- gateways = g;
- }
- ast_mutex_unlock(&gatelock);
-
- /* FS: process queue and IO */
- if (monitor_thread == pthread_self()) {
- if (sched) ast_sched_runq(sched);
- if (io) ast_io_wait(io, 10);
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
-
- /* prune deleted entries etc. */
- prune_gateways();
-
- if (ntohl(bindaddr.sin_addr.s_addr)) {
- memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip));
- } else {
- hp = ast_gethostbyname(ourhost, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n");
- ast_config_destroy(cfg);
- return 0;
- }
- memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
- }
- if (!ntohs(bindaddr.sin_port))
- bindaddr.sin_port = ntohs(DEFAULT_MGCP_CA_PORT);
- bindaddr.sin_family = AF_INET;
- ast_mutex_lock(&netlock);
- if (mgcpsock > -1)
- close(mgcpsock);
-
- if (mgcpsock_read_id != NULL)
- ast_io_remove(io, mgcpsock_read_id);
- mgcpsock_read_id = NULL;
-
- mgcpsock = socket(AF_INET, SOCK_DGRAM, 0);
- if (mgcpsock < 0) {
- ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno));
- } else {
- if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
- ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
- strerror(errno));
- close(mgcpsock);
- mgcpsock = -1;
- } else {
- if (option_verbose > 1) {
- ast_verbose(VERBOSE_PREFIX_2 "MGCP Listening on %s:%d\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
- ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos);
- }
- if (setsockopt(mgcpsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))
- ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
- }
- }
- ast_mutex_unlock(&netlock);
- ast_config_destroy(cfg);
-
- /* send audit only to the new endpoints */
- g = gateways;
- while (g) {
- e = g->endpoints;
- while (e && e->needaudit) {
- e->needaudit = 0;
- transmit_audit_endpoint(e);
- ast_verbose(VERBOSE_PREFIX_3 "MGCP Auditing endpoint %s@%s for hookstate\n", e->name, g->name);
- e = e->next;
- }
- g = g->next;
- }
-
- return 0;
-}
-
-/*! \brief load_module: PBX load module - initialization ---*/
-static int load_module(void)
-{
- if (!(sched = sched_context_create())) {
- ast_log(LOG_WARNING, "Unable to create schedule context\n");
- return AST_MODULE_LOAD_FAILURE;
- }
-
- if (!(io = io_context_create())) {
- ast_log(LOG_WARNING, "Unable to create I/O context\n");
- sched_context_destroy(sched);
- return AST_MODULE_LOAD_FAILURE;
- }
-
- if (reload_config())
- return AST_MODULE_LOAD_DECLINE;
-
- /* Make sure we can register our mgcp channel type */
- if (ast_channel_register(&mgcp_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'MGCP'\n");
- io_context_destroy(io);
- sched_context_destroy(sched);
- return AST_MODULE_LOAD_FAILURE;
- }
-
- ast_rtp_proto_register(&mgcp_rtp);
- ast_cli_register_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
-
- /* And start the monitor for the first time */
- restart_monitor();
-
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-/*! \brief mgcp_do_reload: Reload module */
-static int mgcp_do_reload(void)
-{
- reload_config();
- return 0;
-}
-
-static int mgcp_reload(int fd, int argc, char *argv[])
-{
- static int deprecated = 0;
- if (!deprecated && argc > 0) {
- ast_log(LOG_WARNING, "'mgcp reload' is deprecated. Please use 'reload chan_mgcp.so' instead.\n");
- deprecated = 1;
- }
-
- ast_mutex_lock(&mgcp_reload_lock);
- if (mgcp_reloading) {
- ast_verbose("Previous mgcp reload not yet done\n");
- } else
- mgcp_reloading = 1;
- ast_mutex_unlock(&mgcp_reload_lock);
- restart_monitor();
- return 0;
-}
-
-static int reload(void)
-{
- mgcp_reload(0, 0, NULL);
- return 0;
-}
-
-static int unload_module(void)
-{
- struct mgcp_endpoint *e;
- struct mgcp_gateway *g;
-
- /* Check to see if we're reloading */
- if (ast_mutex_trylock(&mgcp_reload_lock)) {
- ast_log(LOG_WARNING, "MGCP is currently reloading. Unable to remove module.\n");
- return -1;
- } else {
- mgcp_reloading = 1;
- ast_mutex_unlock(&mgcp_reload_lock);
- }
-
- /* First, take us out of the channel loop */
- ast_channel_unregister(&mgcp_tech);
-
- /* Shut down the monitoring thread */
- if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
- pthread_cancel(monitor_thread);
- pthread_kill(monitor_thread, SIGURG);
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- /* We always want to leave this in a consistent state */
- ast_channel_register(&mgcp_tech);
- mgcp_reloading = 0;
- mgcp_reload(0, 0, NULL);
- return -1;
- }
-
- if (!ast_mutex_lock(&gatelock)) {
- for (g = gateways; g; g = g->next) {
- g->delme = 1;
- for (e = g->endpoints; e; e = e->next)
- e->delme = 1;
- }
-
- prune_gateways();
- ast_mutex_unlock(&gatelock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the gateways list.\n");
- /* We always want to leave this in a consistent state */
- ast_channel_register(&mgcp_tech);
- /* Allow the monitor to restart */
- monitor_thread = AST_PTHREADT_NULL;
- mgcp_reloading = 0;
- mgcp_reload(0, 0, NULL);
- return -1;
- }
-
- close(mgcpsock);
- ast_rtp_proto_unregister(&mgcp_rtp);
- ast_cli_unregister_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
- sched_context_destroy(sched);
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Media Gateway Control Protocol (MGCP)",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/chan_misdn.c b/1.4/channels/chan_misdn.c
deleted file mode 100644
index bb31de0ba..000000000
--- a/1.4/channels/chan_misdn.c
+++ /dev/null
@@ -1,5700 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2006, Christian Richter
- *
- * Christian Richter <crich@beronet.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.
- *
- */
-
-/*!
- * \file
- *
- * \brief the chan_misdn channel driver for Asterisk
- * \author Christian Richter <crich@beronet.com>
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>isdnnet</depend>
- <depend>misdn</depend>
- <depend>suppserv</depend>
- ***/
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <pthread.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-#include <sys/file.h>
-#include <semaphore.h>
-
-#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/io.h"
-#include "asterisk/frame.h"
-#include "asterisk/translate.h"
-#include "asterisk/cli.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/dsp.h"
-#include "asterisk/translate.h"
-#include "asterisk/config.h"
-#include "asterisk/file.h"
-#include "asterisk/callerid.h"
-#include "asterisk/indications.h"
-#include "asterisk/app.h"
-#include "asterisk/features.h"
-#include "asterisk/term.h"
-#include "asterisk/sched.h"
-#include "asterisk/stringfields.h"
-
-#include "chan_misdn_config.h"
-#include "isdn_lib.h"
-
-char global_tracefile[BUFFERSIZE+1];
-
-static int g_config_initialized=0;
-
-struct misdn_jb{
- int size;
- int upper_threshold;
- char *samples, *ok;
- int wp,rp;
- int state_empty;
- int state_full;
- int state_buffer;
- int bytes_wrote;
- ast_mutex_t mutexjb;
-};
-
-
-
-/* allocates the jb-structure and initialise the elements*/
-struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
-
-/* frees the data and destroys the given jitterbuffer struct */
-void misdn_jb_destroy(struct misdn_jb *jb);
-
-/* fills the jitterbuffer with len data returns < 0 if there was an
-error (bufferoverun). */
-int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len);
-
-/* gets len bytes out of the jitterbuffer if available, else only the
-available data is returned and the return value indicates the number
-of data. */
-int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
-
-
-/* BEGIN: chan_misdn.h */
-
-ast_mutex_t release_lock;
-
-enum misdn_chan_state {
- MISDN_NOTHING=0, /*!< at beginning */
- MISDN_WAITING4DIGS, /*!< when waiting for infos */
- MISDN_EXTCANTMATCH, /*!< when asterisk couldnt match our ext */
- MISDN_INCOMING_SETUP, /*!< for incoming setups*/
- MISDN_DIALING, /*!< when pbx_start */
- MISDN_PROGRESS, /*!< we got a progress */
- MISDN_PROCEEDING, /*!< we got a progress */
- MISDN_CALLING, /*!< when misdn_call is called */
- MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */
- MISDN_ALERTING, /*!< when Alerting */
- MISDN_BUSY, /*!< when BUSY */
- MISDN_CONNECTED, /*!< when connected */
- MISDN_PRECONNECTED, /*!< when connected */
- MISDN_DISCONNECTED, /*!< when connected */
- MISDN_RELEASED, /*!< when connected */
- MISDN_BRIDGED, /*!< when bridged */
- MISDN_CLEANING, /*!< when hangup from * but we were connected before */
- MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP cam from misdn */
- MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */
- /* misdn_hangup */
- MISDN_HOLDED, /*!< if this chan is holded */
- MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */
-
-};
-
-#define ORG_AST 1
-#define ORG_MISDN 2
-
-struct hold_info {
- int port;
- int channel;
-};
-
-struct chan_list {
-
- char allowed_bearers[BUFFERSIZE+1];
-
- enum misdn_chan_state state;
- int need_queue_hangup;
- int need_hangup;
- int need_busy;
-
- int noautorespond_on_setup;
-
- int originator;
-
- int norxtone;
- int notxtone;
-
- int toggle_ec;
-
- int incoming_early_audio;
-
- int ignore_dtmf;
-
- int pipe[2];
- char ast_rd_buf[4096];
- struct ast_frame frame;
-
- int faxdetect; /* 0:no 1:yes 2:yes+nojump */
- int faxdetect_timeout;
- struct timeval faxdetect_tv;
- int faxhandled;
-
- int ast_dsp;
-
- int jb_len;
- int jb_upper_threshold;
- struct misdn_jb *jb;
-
- struct ast_dsp *dsp;
- struct ast_trans_pvt *trans;
-
- struct ast_channel * ast;
-
- int dummy;
-
- struct misdn_bchannel *bc;
-
- struct hold_info hold_info;
-
- unsigned int l3id;
- int addr;
-
- char context[BUFFERSIZE];
-
- int zero_read_cnt;
- int dropped_frame_cnt;
-
- int far_alerting;
-
- int nttimeout;
-
- int other_pid;
- struct chan_list *other_ch;
-
- const struct tone_zone_sound *ts;
-
- int overlap_dial;
- int overlap_dial_task;
- ast_mutex_t overlap_tv_lock;
- struct timeval overlap_tv;
-
- struct chan_list *peer;
- struct chan_list *next;
- struct chan_list *prev;
- struct chan_list *first;
-};
-
-
-
-void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
-void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
-
-struct robin_list {
- char *group;
- int port;
- int channel;
- struct robin_list *next;
- struct robin_list *prev;
-};
-static struct robin_list *robin = NULL;
-
-
-
-static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
-
-
-
-static inline void free_robin_list_r (struct robin_list *r)
-{
- if (r) {
- if (r->next) free_robin_list_r(r->next);
- if (r->group) free(r->group);
- free(r);
- }
-}
-
-static void free_robin_list ( void )
-{
- free_robin_list_r(robin);
- robin = NULL;
-}
-
-static struct robin_list* get_robin_position (char *group)
-{
- struct robin_list *new;
- struct robin_list *iter = robin;
- for (; iter; iter = iter->next) {
- if (!strcasecmp(iter->group, group))
- return iter;
- }
- new = (struct robin_list *)calloc(1, sizeof(struct robin_list));
- new->group = strndup(group, strlen(group));
- new->port = 0;
- new->channel = 0;
- if (robin) {
- new->next = robin;
- robin->prev = new;
- }
- robin = new;
- return robin;
-}
-
-
-/* the main schedule context for stuff like l1 watcher, overlap dial, ... */
-static struct sched_context *misdn_tasks = NULL;
-static pthread_t misdn_tasks_thread;
-
-static int *misdn_ports;
-
-static void chan_misdn_log(int level, int port, char *tmpl, ...);
-
-static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c);
-static void send_digit_to_chan(struct chan_list *cl, char digit );
-
-static void hangup_chan(struct chan_list *ch);
-static int pbx_start_chan(struct chan_list *ch);
-
-#define MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt
-#define MISDN_ASTERISK_PVT(ast) 1
-
-#include <asterisk/strings.h>
-
-/* #define MISDN_DEBUG 1 */
-
-static const char misdn_type[] = "mISDN";
-
-static int tracing = 0 ;
-
-/* Only alaw and mulaw is allowed for now */
-static int prefformat = AST_FORMAT_ALAW ; /* AST_FORMAT_SLINEAR ; AST_FORMAT_ULAW | */
-
-static int *misdn_debug;
-static int *misdn_debug_only;
-static int max_ports;
-
-static int *misdn_in_calls;
-static int *misdn_out_calls;
-
-
-struct chan_list dummy_cl;
-
-struct chan_list *cl_te=NULL;
-ast_mutex_t cl_te_lock;
-
-static enum event_response_e
-cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
-
-static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch);
-
-static void cl_queue_chan(struct chan_list **list, struct chan_list *chan);
-static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan);
-static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc);
-static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid);
-
-
-
-static int dialtone_indicate(struct chan_list *cl);
-static int hanguptone_indicate(struct chan_list *cl);
-static int stop_indicate(struct chan_list *cl);
-
-static int start_bc_tones(struct chan_list *cl);
-static int stop_bc_tones(struct chan_list *cl);
-static void release_chan(struct misdn_bchannel *bc);
-
-static int misdn_check_l2l1(struct ast_channel *chan, void *data);
-static int misdn_set_opt_exec(struct ast_channel *chan, void *data);
-static int misdn_facility_exec(struct ast_channel *chan, void *data);
-
-int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
-
-
-void debug_numplan(int port, int numplan, char *type);
-
-
-int add_out_calls(int port);
-int add_in_calls(int port);
-
-
-#ifdef MISDN_1_2
-static int update_pipeline_config(struct misdn_bchannel *bc);
-#else
-static int update_ec_config(struct misdn_bchannel *bc);
-#endif
-
-
-
-
-/*protos*/
-
-int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len);
-
-/*************** Helpers *****************/
-
-static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
-{
- struct chan_list *tmp;
-
- for (tmp=cl_te; tmp; tmp = tmp->next) {
- if ( tmp->ast == ast ) return tmp;
- }
-
- return NULL;
-}
-
-static struct chan_list * get_chan_by_ast_name(char *name)
-{
- struct chan_list *tmp;
-
- for (tmp=cl_te; tmp; tmp = tmp->next) {
- if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp;
- }
-
- return NULL;
-}
-
-
-
-struct allowed_bearers {
- int cap;
- int val;
- char *name;
-};
-
-struct allowed_bearers allowed_bearers_array[]={
- {INFO_CAPABILITY_SPEECH,1,"speech"},
- {INFO_CAPABILITY_AUDIO_3_1K,2,"3_1khz"},
- {INFO_CAPABILITY_DIGITAL_UNRESTRICTED,4,"digital_unrestricted"},
- {INFO_CAPABILITY_DIGITAL_RESTRICTED,8,"digital_restriced"},
- {INFO_CAPABILITY_VIDEO,16,"video"}
-};
-
-static char *bearer2str(int cap) {
- static char *bearers[]={
- "Speech",
- "Audio 3.1k",
- "Unres Digital",
- "Res Digital",
- "Video",
- "Unknown Bearer"
- };
-
- switch (cap) {
- case INFO_CAPABILITY_SPEECH:
- return bearers[0];
- break;
- case INFO_CAPABILITY_AUDIO_3_1K:
- return bearers[1];
- break;
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
- return bearers[2];
- break;
- case INFO_CAPABILITY_DIGITAL_RESTRICTED:
- return bearers[3];
- break;
- case INFO_CAPABILITY_VIDEO:
- return bearers[4];
- break;
- default:
- return bearers[5];
- break;
- }
-}
-
-
-static void print_facility(struct FacParm *fac, struct misdn_bchannel *bc)
-{
- switch (fac->Function) {
- case Fac_CD:
- chan_misdn_log(1,bc->port," --> calldeflect to: %s, screened: %s\n", fac->u.CDeflection.DeflectedToNumber,
- fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
- break;
- case Fac_AOCDCurrency:
- if (fac->u.AOCDcur.chargeNotAvailable)
- chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n");
- else if (fac->u.AOCDcur.freeOfCharge)
- chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n");
- else if (fac->u.AOCDchu.billingId >= 0)
- chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d billingId:%d\n",
- fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
- (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
- else
- chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d\n",
- fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
- (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
- break;
- case Fac_AOCDChargingUnit:
- if (fac->u.AOCDchu.chargeNotAvailable)
- chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n");
- else if (fac->u.AOCDchu.freeOfCharge)
- chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n");
- else if (fac->u.AOCDchu.billingId >= 0)
- chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
- fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
- else
- chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
- fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
- break;
- default:
- chan_misdn_log(1,bc->port," --> unknown\n");
- }
-}
-
-static void print_bearer(struct misdn_bchannel *bc)
-{
-
- chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
-
- switch(bc->law) {
- case INFO_CODEC_ALAW:
- chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
- break;
- case INFO_CODEC_ULAW:
- chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
- break;
- }
-}
-
-static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
-{
- char buf[128];
-
- if (!ast)
- return;
-
- if (originator == ORG_AST) {
- ast = ast_bridged_channel(ast);
- if (!ast)
- return;
- }
-
- switch (bc->AOCDtype) {
- case Fac_AOCDCurrency:
- pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency");
- if (bc->AOCD.currency.chargeNotAvailable)
- pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
- else {
- pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
- if (bc->AOCD.currency.freeOfCharge)
- pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
- else {
- pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
- if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
- pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf);
- if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf))
- pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
- }
- }
- }
- break;
- case Fac_AOCDChargingUnit:
- pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit");
- if (bc->AOCD.chargingUnit.chargeNotAvailable)
- pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
- else {
- pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
- if (bc->AOCD.chargingUnit.freeOfCharge)
- pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
- else {
- pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
- if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
- pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf);
- if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf))
- pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
- }
- }
- }
- break;
- default:
- break;
- }
-}
-
-/*************** Helpers END *************/
-
-static void sighandler(int sig)
-{}
-
-static void* misdn_tasks_thread_func (void *data)
-{
- int wait;
- struct sigaction sa;
-
- sa.sa_handler = sighandler;
- sa.sa_flags = SA_NODEFER;
- sigemptyset(&sa.sa_mask);
- sigaddset(&sa.sa_mask, SIGUSR1);
- sigaction(SIGUSR1, &sa, NULL);
-
- sem_post((sem_t *)data);
-
- while (1) {
- wait = ast_sched_wait(misdn_tasks);
- if (wait < 0)
- wait = 8000;
- if (poll(NULL, 0, wait) < 0)
- chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
- ast_sched_runq(misdn_tasks);
- }
- return NULL;
-}
-
-static void misdn_tasks_init (void)
-{
- sem_t blocker;
- int i = 5;
-
- if (sem_init(&blocker, 0, 0)) {
- perror("chan_misdn: Failed to initialize semaphore!");
- exit(1);
- }
-
- chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
-
- misdn_tasks = sched_context_create();
- pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
-
- while (sem_wait(&blocker) && --i);
- sem_destroy(&blocker);
-}
-
-static void misdn_tasks_destroy (void)
-{
- if (misdn_tasks) {
- chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
- if ( pthread_cancel(misdn_tasks_thread) == 0 ) {
- cb_log(4, 0, "Joining misdn_tasks thread\n");
- pthread_join(misdn_tasks_thread, NULL);
- }
- sched_context_destroy(misdn_tasks);
- }
-}
-
-static inline void misdn_tasks_wakeup (void)
-{
- pthread_kill(misdn_tasks_thread, SIGUSR1);
-}
-
-static inline int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable)
-{
- int task_id;
-
- if (!misdn_tasks) {
- misdn_tasks_init();
- }
- task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
- misdn_tasks_wakeup();
-
- return task_id;
-}
-
-static int misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data)
-{
- return _misdn_tasks_add_variable(timeout, callback, data, 0);
-}
-
-static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data)
-{
- return _misdn_tasks_add_variable(timeout, callback, data, 1);
-}
-
-static void misdn_tasks_remove (int task_id)
-{
- AST_SCHED_DEL(misdn_tasks, task_id);
-}
-
-static int misdn_l1_task (const void *data)
-{
- misdn_lib_isdn_l1watcher(*(int *)data);
- chan_misdn_log(5, *(int *)data, "L1watcher timeout\n");
- return 1;
-}
-
-static int misdn_overlap_dial_task (const void *data)
-{
- struct timeval tv_end, tv_now;
- int diff;
- struct chan_list *ch = (struct chan_list *)data;
-
- chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
-
- if (ch->state != MISDN_WAITING4DIGS) {
- ch->overlap_dial_task = -1;
- return 0;
- }
-
- ast_mutex_lock(&ch->overlap_tv_lock);
- tv_end = ch->overlap_tv;
- ast_mutex_unlock(&ch->overlap_tv_lock);
-
- tv_end.tv_sec += ch->overlap_dial;
- tv_now = ast_tvnow();
-
- diff = ast_tvdiff_ms(tv_end, tv_now);
-
- if (diff <= 100) {
- char *dad=ch->bc->dad, sexten[]="s";
- /* if we are 100ms near the timeout, we are satisfied.. */
- stop_indicate(ch);
-
- if (ast_strlen_zero(ch->bc->dad)) {
- dad=sexten;
- strcpy(ch->ast->exten, sexten);
- }
-
- if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) {
- ch->state=MISDN_DIALING;
- if (pbx_start_chan(ch) < 0) {
- chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
- goto misdn_overlap_dial_task_disconnect;
- }
- } else {
-misdn_overlap_dial_task_disconnect:
- hanguptone_indicate(ch);
- ch->bc->out_cause=1;
- ch->state=MISDN_CLEANING;
- misdn_lib_send_event(ch->bc, EVENT_DISCONNECT);
- }
- ch->overlap_dial_task = -1;
- return 0;
- } else
- return diff;
-}
-
-static void send_digit_to_chan(struct chan_list *cl, char digit )
-{
- static const char* dtmf_tones[] = {
- "!941+1336/100,!0/100", /* 0 */
- "!697+1209/100,!0/100", /* 1 */
- "!697+1336/100,!0/100", /* 2 */
- "!697+1477/100,!0/100", /* 3 */
- "!770+1209/100,!0/100", /* 4 */
- "!770+1336/100,!0/100", /* 5 */
- "!770+1477/100,!0/100", /* 6 */
- "!852+1209/100,!0/100", /* 7 */
- "!852+1336/100,!0/100", /* 8 */
- "!852+1477/100,!0/100", /* 9 */
- "!697+1633/100,!0/100", /* A */
- "!770+1633/100,!0/100", /* B */
- "!852+1633/100,!0/100", /* C */
- "!941+1633/100,!0/100", /* D */
- "!941+1209/100,!0/100", /* * */
- "!941+1477/100,!0/100" }; /* # */
- struct ast_channel *chan=cl->ast;
-
- if (digit >= '0' && digit <='9')
- ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
- else if (digit >= 'A' && digit <= 'D')
- ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
- else if (digit == '*')
- ast_playtones_start(chan,0,dtmf_tones[14], 0);
- else if (digit == '#')
- ast_playtones_start(chan,0,dtmf_tones[15], 0);
- else {
- /* not handled */
- ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
-
-
- }
-}
-/*** CLI HANDLING ***/
-static int misdn_set_debug(int fd, int argc, char *argv[])
-{
- int level;
-
- if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
- return RESULT_SHOWUSAGE;
-
- level = atoi(argv[3]);
-
- switch (argc) {
- case 4:
- case 5: {
- int i;
- int only = 0;
- if (argc == 5) {
- if (strncasecmp(argv[4], "only", strlen(argv[4])))
- return RESULT_SHOWUSAGE;
- else
- only = 1;
- }
- for (i=0; i<=max_ports; i++) {
- misdn_debug[i] = level;
- misdn_debug_only[i] = only;
- }
- ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
- }
- break;
- case 6:
- case 7: {
- int port;
- if (strncasecmp(argv[4], "port", strlen(argv[4])))
- return RESULT_SHOWUSAGE;
- port = atoi(argv[5]);
- if (port <= 0 || port > max_ports) {
- switch (max_ports) {
- case 0:
- ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
- break;
- case 1:
- ast_cli(fd, "port number not valid! only port 1 is availble.\n");
- break;
- default:
- ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
- }
- return 0;
- }
- if (argc == 7) {
- if (strncasecmp(argv[6], "only", strlen(argv[6])))
- return RESULT_SHOWUSAGE;
- else
- misdn_debug_only[port] = 1;
- } else
- misdn_debug_only[port] = 0;
- misdn_debug[port] = level;
- ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
- }
- }
- return 0;
-}
-
-static int misdn_set_crypt_debug(int fd, int argc, char *argv[])
-{
- if (argc != 5) return RESULT_SHOWUSAGE;
-
- return 0;
-}
-
-static int misdn_port_block(int fd, int argc, char *argv[])
-{
- int port;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- misdn_lib_port_block(port);
-
- return 0;
-}
-
-static int misdn_port_unblock(int fd, int argc, char *argv[])
-{
- int port;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- misdn_lib_port_unblock(port);
-
- return 0;
-}
-
-
-static int misdn_restart_port (int fd, int argc, char *argv[])
-{
- int port;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- misdn_lib_port_restart(port);
-
- return 0;
-}
-
-static int misdn_restart_pid (int fd, int argc, char *argv[])
-{
- int pid;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- pid = atoi(argv[3]);
-
- misdn_lib_pid_restart(pid);
-
- return 0;
-}
-
-static int misdn_port_up (int fd, int argc, char *argv[])
-{
- int port;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- misdn_lib_get_port_up(port);
-
- return 0;
-}
-
-static int misdn_port_down (int fd, int argc, char *argv[])
-{
- int port;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- misdn_lib_get_port_down(port);
-
- return 0;
-}
-
-static inline void show_config_description (int fd, enum misdn_cfg_elements elem)
-{
- char section[BUFFERSIZE];
- char name[BUFFERSIZE];
- char desc[BUFFERSIZE];
- char def[BUFFERSIZE];
- char tmp[BUFFERSIZE];
-
- misdn_cfg_get_name(elem, tmp, sizeof(tmp));
- term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
- misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
-
- if (elem < MISDN_CFG_LAST)
- term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
- else
- term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
-
- if (*def)
- ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc);
- else
- ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
-}
-
-static int misdn_show_config (int fd, int argc, char *argv[])
-{
- char buffer[BUFFERSIZE];
- enum misdn_cfg_elements elem;
- int linebreak;
- int onlyport = -1;
- int ok = 0;
-
- if (argc >= 4) {
- if (!strcmp(argv[3], "description")) {
- if (argc == 5) {
- enum misdn_cfg_elements elem = misdn_cfg_get_elem (argv[4]);
- if (elem == MISDN_CFG_FIRST)
- ast_cli(fd, "Unknown element: %s\n", argv[4]);
- else
- show_config_description(fd, elem);
- return 0;
- }
- return RESULT_SHOWUSAGE;
- }
- if (!strcmp(argv[3], "descriptions")) {
- if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) {
- for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
- show_config_description(fd, elem);
- ast_cli(fd, "\n");
- }
- ok = 1;
- }
- if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) {
- for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
- show_config_description(fd, elem);
- ast_cli(fd, "\n");
- }
- ok = 1;
- }
- return ok ? 0 : RESULT_SHOWUSAGE;
- }
- if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) {
- ast_cli(fd, "Unknown option: %s\n", argv[3]);
- return RESULT_SHOWUSAGE;
- }
- }
-
- if (argc == 3 || onlyport == 0) {
- ast_cli(fd,"Misdn General-Config: \n");
- for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
- misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE);
- ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
- }
- ast_cli(fd, "\n");
- }
-
- if (onlyport < 0) {
- int port = misdn_cfg_get_next_port(0);
- for (; port > 0; port = misdn_cfg_get_next_port(port)) {
- ast_cli(fd, "\n[PORT %d]\n", port);
- for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
- misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE);
- ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
- }
- ast_cli(fd, "\n");
- }
- }
-
- if (onlyport > 0) {
- if (misdn_cfg_is_port_valid(onlyport)) {
- ast_cli(fd, "[PORT %d]\n", onlyport);
- for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
- misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE);
- ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
- }
- ast_cli(fd, "\n");
- } else {
- ast_cli(fd, "Port %d is not active!\n", onlyport);
- }
- }
- return 0;
-}
-
-struct state_struct {
- enum misdn_chan_state state;
- char txt[255] ;
-} ;
-
-static struct state_struct state_array[] = {
- {MISDN_NOTHING,"NOTHING"}, /* at beginning */
- {MISDN_WAITING4DIGS,"WAITING4DIGS"}, /* when waiting for infos */
- {MISDN_EXTCANTMATCH,"EXTCANTMATCH"}, /* when asterisk couldnt match our ext */
- {MISDN_INCOMING_SETUP,"INCOMING SETUP"}, /* when pbx_start */
- {MISDN_DIALING,"DIALING"}, /* when pbx_start */
- {MISDN_PROGRESS,"PROGRESS"}, /* when pbx_start */
- {MISDN_PROCEEDING,"PROCEEDING"}, /* when pbx_start */
- {MISDN_CALLING,"CALLING"}, /* when misdn_call is called */
- {MISDN_CALLING_ACKNOWLEDGE,"CALLING_ACKNOWLEDGE"}, /* when misdn_call is called */
- {MISDN_ALERTING,"ALERTING"}, /* when Alerting */
- {MISDN_BUSY,"BUSY"}, /* when BUSY */
- {MISDN_CONNECTED,"CONNECTED"}, /* when connected */
- {MISDN_PRECONNECTED,"PRECONNECTED"}, /* when connected */
- {MISDN_DISCONNECTED,"DISCONNECTED"}, /* when connected */
- {MISDN_RELEASED,"RELEASED"}, /* when connected */
- {MISDN_BRIDGED,"BRIDGED"}, /* when bridged */
- {MISDN_CLEANING,"CLEANING"}, /* when hangup from * but we were connected before */
- {MISDN_HUNGUP_FROM_MISDN,"HUNGUP_FROM_MISDN"}, /* when DISCONNECT/RELEASE/REL_COMP cam from misdn */
- {MISDN_HOLDED,"HOLDED"}, /* when DISCONNECT/RELEASE/REL_COMP cam from misdn */
- {MISDN_HOLD_DISCONNECT,"HOLD_DISCONNECT"}, /* when DISCONNECT/RELEASE/REL_COMP cam from misdn */
- {MISDN_HUNGUP_FROM_AST,"HUNGUP_FROM_AST"} /* when DISCONNECT/RELEASE/REL_COMP came out of */
- /* misdn_hangup */
-};
-
-static char *misdn_get_ch_state(struct chan_list *p)
-{
- int i;
- static char state[8];
-
- if( !p) return NULL;
-
- for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) {
- if ( state_array[i].state == p->state) return state_array[i].txt;
- }
-
- sprintf(state,"%d",p->state) ;
-
- return state;
-}
-
-
-
-static void reload_config(void)
-{
- int i, cfg_debug;
-
- if (!g_config_initialized) {
- ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
- return ;
- }
-
- free_robin_list();
- misdn_cfg_reload();
- misdn_cfg_update_ptp();
- misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
- misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
-
- for (i = 0; i <= max_ports; i++) {
- misdn_debug[i] = cfg_debug;
- misdn_debug_only[i] = 0;
- }
-}
-
-static int misdn_reload (int fd, int argc, char *argv[])
-{
- ast_cli(fd, "Reloading mISDN Config\n");
- reload_config();
- return 0;
-}
-
-static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel* bc)
-{
- struct ast_channel *ast=help->ast;
- ast_cli(fd,
- "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
-
- bc->pid, bc->port, bc->channel,
- bc->nt?"NT":"TE",
- help->originator == ORG_AST?"*":"I",
- ast?ast->exten:NULL,
- ast?ast->cid.cid_num:NULL,
- bc->rad,
- ast?ast->context:NULL,
- misdn_get_ch_state(help)
- );
- if (misdn_debug[bc->port] > 0)
- ast_cli(fd,
- " --> astname: %s\n"
- " --> ch_l3id: %x\n"
- " --> ch_addr: %x\n"
- " --> bc_addr: %x\n"
- " --> bc_l3id: %x\n"
- " --> display: %s\n"
- " --> activated: %d\n"
- " --> state: %s\n"
- " --> capability: %s\n"
-#ifdef MISDN_1_2
- " --> pipeline: %s\n"
-#else
- " --> echo_cancel: %d\n"
-#endif
- " --> notone : rx %d tx:%d\n"
- " --> bc_hold: %d\n",
- help->ast->name,
- help->l3id,
- help->addr,
- bc->addr,
- bc?bc->l3_id:-1,
- bc->display,
-
- bc->active,
- bc_state2str(bc->bc_state),
- bearer2str(bc->capability),
-#ifdef MISDN_1_2
- bc->pipeline,
-#else
- bc->ec_enable,
-#endif
-
- help->norxtone,help->notxtone,
- bc->holded
- );
-
-}
-
-static int misdn_show_cls (int fd, int argc, char *argv[])
-{
- struct chan_list *help=cl_te;
-
- ast_cli(fd,"Chan List: %p\n",cl_te);
-
- for (;help; help=help->next) {
- struct misdn_bchannel *bc=help->bc;
- struct ast_channel *ast=help->ast;
- if (!ast) {
- if (!bc) {
- ast_cli(fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
- continue;
- }
- ast_cli(fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
- continue;
- }
- if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
- if (bc) {
- print_bc_info(fd, help, bc);
- } else {
- if (help->state == MISDN_HOLDED) {
- ast_cli(fd, "ITS A HOLDED BC:\n");
- ast_cli(fd, " --> l3_id: %x\n"
- " --> dad:%s oad:%s\n"
- " --> hold_port: %d\n"
- " --> hold_channel: %d\n"
-
- ,help->l3id
- ,ast->exten
- ,ast->cid.cid_num
- ,help->hold_info.port
- ,help->hold_info.channel
- );
- } else {
- ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
- }
- }
- }
-
- misdn_dump_chanlist();
- return 0;
-}
-
-static int misdn_show_cl (int fd, int argc, char *argv[])
-{
- struct chan_list *help=cl_te;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- for (;help; help=help->next) {
- struct misdn_bchannel *bc=help->bc;
- struct ast_channel *ast=help->ast;
-
- if (bc && ast) {
- if (!strcasecmp(ast->name,argv[3])) {
- print_bc_info(fd, help, bc);
- break;
- }
- }
- }
-
-
- return 0;
-}
-
-ast_mutex_t lock;
-int MAXTICS=8;
-
-static int misdn_set_tics (int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- MAXTICS=atoi(argv[3]);
-
- return 0;
-}
-
-static int misdn_show_stacks (int fd, int argc, char *argv[])
-{
- int port;
-
- ast_cli(fd, "BEGIN STACK_LIST:\n");
-
- for (port=misdn_cfg_get_next_port(0); port > 0;
- port=misdn_cfg_get_next_port(port)) {
- char buf[128];
- get_show_stack_details(port,buf);
- ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
- }
-
- return 0;
-}
-
-
-static int misdn_show_ports_stats (int fd, int argc, char *argv[])
-{
- int port;
-
- ast_cli(fd, "Port\tin_calls\tout_calls\n");
-
- for (port=misdn_cfg_get_next_port(0); port > 0;
- port=misdn_cfg_get_next_port(port)) {
- ast_cli(fd,"%d\t%d\t\t%d\n",port,misdn_in_calls[port],misdn_out_calls[port]);
- }
- ast_cli(fd,"\n");
-
- return 0;
-
-}
-
-
-static int misdn_show_port (int fd, int argc, char *argv[])
-{
- int port;
- char buf[128];
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- ast_cli(fd, "BEGIN STACK_LIST:\n");
-
- get_show_stack_details(port,buf);
- ast_cli(fd," %s Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
-
-
- return 0;
-}
-
-static int misdn_send_cd (int fd, int argc, char *argv[])
-{
- char *channame;
- char *nr;
-
- if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- channame = argv[3];
- nr = argv[4];
-
- ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame);
-
- {
- struct chan_list *tmp=get_chan_by_ast_name(channame);
-
- if (!tmp) {
- ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame);
- return 0;
- } else {
- if (strlen(nr) >= 15) {
- ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
- return 0;
- }
- tmp->bc->fac_out.Function = Fac_CD;
- strncpy((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
- misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
- }
- }
-
- return 0;
-}
-
-static int misdn_send_restart(int fd, int argc, char *argv[])
-{
- int port;
- int channel;
-
- if ( (argc < 4) || (argc > 5) )
- return RESULT_SHOWUSAGE;
-
- port = atoi(argv[3]);
-
- if (argc==5) {
- channel = atoi(argv[4]);
- misdn_lib_send_restart(port, channel);
- } else
- misdn_lib_send_restart(port, -1 );
-
- return 0;
-}
-
-static int misdn_send_digit (int fd, int argc, char *argv[])
-{
- char *channame;
- char *msg;
-
- if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- channame = argv[3];
- msg = argv[4];
-
- ast_cli(fd, "Sending %s to %s\n",msg, channame);
-
- {
- struct chan_list *tmp=get_chan_by_ast_name(channame);
-
- if (!tmp) {
- ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame);
- return 0;
- } else {
-#if 1
- int i;
- int msglen = strlen(msg);
- for (i=0; i<msglen; i++) {
- ast_cli(fd, "Sending: %c\n",msg[i]);
- send_digit_to_chan(tmp, msg[i]);
- /* res = ast_safe_sleep(tmp->ast, 250); */
- usleep(250000);
- /* res = ast_waitfor(tmp->ast,100); */
- }
-#else
- int res;
- res = ast_dtmf_stream(tmp->ast,NULL,msg,250);
-#endif
- }
- }
-
- return 0;
-}
-
-static int misdn_toggle_echocancel (int fd, int argc, char *argv[])
-{
- char *channame;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- channame = argv[3];
-
- ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
-
- {
- struct chan_list *tmp=get_chan_by_ast_name(channame);
-
- if (!tmp) {
- ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
- return 0;
- } else {
-
- tmp->toggle_ec=tmp->toggle_ec?0:1;
-
- if (tmp->toggle_ec) {
-#ifdef MISDN_1_2
- update_pipeline_config(tmp->bc);
-#else
- update_ec_config(tmp->bc);
-#endif
- manager_ec_enable(tmp->bc);
- } else {
- manager_ec_disable(tmp->bc);
- }
- }
- }
-
- return 0;
-}
-
-static int misdn_send_display (int fd, int argc, char *argv[])
-{
- char *channame;
- char *msg;
-
- if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- channame = argv[3];
- msg = argv[4];
-
- ast_cli(fd, "Sending %s to %s\n",msg, channame);
- {
- struct chan_list *tmp;
- tmp=get_chan_by_ast_name(channame);
-
- if (tmp && tmp->bc) {
- ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
- misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
- } else {
- ast_cli(fd,"No such channel %s\n",channame);
- return RESULT_FAILURE;
- }
- }
-
- return RESULT_SUCCESS ;
-}
-
-static char *complete_ch_helper(const char *line, const char *word, int pos, int state, int rpos)
-{
- struct ast_channel *c;
- int which=0;
- char *ret;
- if (pos != rpos)
- return NULL;
- c = ast_channel_walk_locked(NULL);
- while(c) {
- if (!strncasecmp(word, c->name, strlen(word))) {
- if (++which > state)
- break;
- }
- ast_mutex_unlock(&c->lock);
- c = ast_channel_walk_locked(c);
- }
- if (c) {
- ret = strdup(c->name);
- ast_mutex_unlock(&c->lock);
- } else
- ret = NULL;
- return ret;
-}
-
-static char *complete_ch(const char *line, const char *word, int pos, int state)
-{
- return complete_ch_helper(line, word, pos, state, 3);
-}
-
-static char *complete_debug_port (const char *line, const char *word, int pos, int state)
-{
- if (state)
- return NULL;
-
- switch (pos) {
- case 4: if (*word == 'p')
- return strdup("port");
- else if (*word == 'o')
- return strdup("only");
- break;
- case 6: if (*word == 'o')
- return strdup("only");
- break;
- }
- return NULL;
-}
-
-static char *complete_show_config (const char *line, const char *word, int pos, int state)
-{
- char buffer[BUFFERSIZE];
- enum misdn_cfg_elements elem;
- int wordlen = strlen(word);
- int which = 0;
- int port = 0;
-
- switch (pos) {
- case 3: if ((!strncmp(word, "description", wordlen)) && (++which > state))
- return strdup("description");
- if ((!strncmp(word, "descriptions", wordlen)) && (++which > state))
- return strdup("descriptions");
- if ((!strncmp(word, "0", wordlen)) && (++which > state))
- return strdup("0");
- while ((port = misdn_cfg_get_next_port(port)) != -1) {
- snprintf(buffer, sizeof(buffer), "%d", port);
- if ((!strncmp(word, buffer, wordlen)) && (++which > state)) {
- return strdup(buffer);
- }
- }
- break;
- case 4:
- if (strstr(line, "description ")) {
- for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
- if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST))
- continue;
- misdn_cfg_get_name(elem, buffer, BUFFERSIZE);
- if (!wordlen || !strncmp(word, buffer, wordlen)) {
- if (++which > state)
- return strdup(buffer);
- }
- }
- } else if (strstr(line, "descriptions ")) {
- if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state))
- return strdup("general");
- if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state))
- return strdup("ports");
- }
- break;
- }
- return NULL;
-}
-
-static struct ast_cli_entry chan_misdn_clis[] = {
- { {"misdn","send","calldeflect", NULL}, misdn_send_cd, "Sends CallDeflection to mISDN Channel",
- "Usage: misdn send calldeflect <channel> \"<nr>\" \n", complete_ch },
- { {"misdn","send","digit", NULL}, misdn_send_digit, "Sends DTMF Digit to mISDN Channel",
- "Usage: misdn send digit <channel> \"<msg>\" \n"
- " Send <digit> to <channel> as DTMF Tone\n"
- " when channel is a mISDN channel\n", complete_ch },
- { {"misdn","toggle","echocancel", NULL}, misdn_toggle_echocancel, "Toggles EchoCancel on mISDN Channel",
- "Usage: misdn toggle echocancel <channel>\n", complete_ch },
- { {"misdn","send","display", NULL}, misdn_send_display, "Sends Text to mISDN Channel",
- "Usage: misdn send display <channel> \"<msg>\" \n"
- " Send <msg> to <channel> as Display Message\n"
- " when channel is a mISDN channel\n", complete_ch },
- { {"misdn","show","config", NULL}, misdn_show_config, "Shows internal mISDN config, read from cfg-file",
- "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
- " Use 0 for <port> to only print the general config.\n", complete_show_config },
- { {"misdn","reload", NULL}, misdn_reload, "Reloads internal mISDN config, read from cfg-file",
- "Usage: misdn reload\n" },
- { {"misdn","set","tics", NULL}, misdn_set_tics, "",
- "\n" },
- { {"misdn","show","channels", NULL}, misdn_show_cls, "Shows internal mISDN chan_list",
- "Usage: misdn show channels\n" },
- { {"misdn","show","channel", NULL}, misdn_show_cl, "Shows internal mISDN chan_list",
- "Usage: misdn show channels\n", complete_ch },
- { {"misdn","port","block", NULL}, misdn_port_block, "Blocks the given port",
- "Usage: misdn port block\n" },
- { {"misdn","port","unblock", NULL}, misdn_port_unblock, "Unblocks the given port",
- "Usage: misdn port unblock\n" },
- { {"misdn","restart","port", NULL}, misdn_restart_port, "Restarts the given port",
- "Usage: misdn restart port\n" },
- { {"misdn","restart","pid", NULL}, misdn_restart_pid, "Restarts the given pid",
- "Usage: misdn restart pid\n" },
- { {"misdn","send","restart", NULL}, misdn_send_restart,
- "Sends a restart for every bchannel on the given port",
- "Usage: misdn send restart <port>\n"},
- { {"misdn","port","up", NULL}, misdn_port_up, "Tries to establish L1 on the given port",
- "Usage: misdn port up <port>\n" },
- { {"misdn","port","down", NULL}, misdn_port_down, "Tries to deacivate the L1 on the given port",
- "Usage: misdn port down <port>\n" },
- { {"misdn","show","stacks", NULL}, misdn_show_stacks, "Shows internal mISDN stack_list",
- "Usage: misdn show stacks\n" },
- { {"misdn","show","ports","stats", NULL}, misdn_show_ports_stats, "Shows chan_misdns call statistics per port",
- "Usage: misdn show port stats\n" },
- { {"misdn","show","port", NULL}, misdn_show_port, "Shows detailed information for given port",
- "Usage: misdn show port <port>\n" },
- { {"misdn","set","debug", NULL}, misdn_set_debug, "Sets Debuglevel of chan_misdn",
- "Usage: misdn set debug <level> [only] | [port <port> [only]]\n", complete_debug_port },
- { {"misdn","set","crypt","debug", NULL}, misdn_set_crypt_debug, "Sets CryptDebuglevel of chan_misdn, at the moment, level={1,2}",
- "Usage: misdn set crypt debug <level>\n" }
-};
-
-static int update_config (struct chan_list *ch, int orig)
-{
- struct ast_channel *ast=ch->ast;
- struct misdn_bchannel *bc=ch->bc;
- int port;
- int pres, screen;
- int hdlc=0;
-
- if (!ch) {
- ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
- return -1;
- }
-
- ast=ch->ast;
- bc=ch->bc;
- if (! ast || ! bc ) {
- ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
- return -1;
- }
-
- port=bc->port;
-
- chan_misdn_log(7,port,"update_config: Getting Config\n");
-
- misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
-
- if (hdlc) {
- switch (bc->capability) {
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
- case INFO_CAPABILITY_DIGITAL_RESTRICTED:
- chan_misdn_log(1,bc->port," --> CONF HDLC\n");
- bc->hdlc=1;
- break;
- }
-
- }
-
- misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int));
- chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen);
-
- if ( (pres + screen) < 0 ) {
-
- chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres);
-
- switch (ast->cid.cid_pres & 0x60){
-
- case AST_PRES_RESTRICTED:
- bc->pres=1;
- chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n");
- break;
-
-
- case AST_PRES_UNAVAILABLE:
- bc->pres=2;
- chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n");
- break;
-
- default:
- bc->pres=0;
- chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n");
- }
-
- switch (ast->cid.cid_pres & 0x3){
-
- case AST_PRES_USER_NUMBER_UNSCREENED:
- bc->screen=0;
- chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
- break;
-
- case AST_PRES_USER_NUMBER_PASSED_SCREEN:
- bc->screen=1;
- chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n");
- break;
- case AST_PRES_USER_NUMBER_FAILED_SCREEN:
- bc->screen=2;
- chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n");
- break;
-
- case AST_PRES_NETWORK_NUMBER:
- bc->screen=3;
- chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n");
- break;
-
- default:
- bc->screen=0;
- chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
- }
-
-
- } else {
- bc->screen=screen;
- bc->pres=pres;
- }
-
- return 0;
-
-}
-
-
-
-
-static void config_jitterbuffer(struct chan_list *ch)
-{
- struct misdn_bchannel *bc=ch->bc;
- int len=ch->jb_len, threshold=ch->jb_upper_threshold;
-
- chan_misdn_log(5,bc->port, "config_jb: Called\n");
-
- if ( ! len ) {
- chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n");
- bc->nojitter=1;
- } else {
-
- if (len <=100 || len > 8000) {
- chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
- len=1000;
- }
-
- if ( threshold > len ) {
- chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
- }
-
- if ( ch->jb) {
- cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n");
- misdn_jb_destroy(ch->jb);
- ch->jb=NULL;
- }
-
- ch->jb=misdn_jb_init(len, threshold);
-
- if (!ch->jb )
- bc->nojitter=1;
- }
-}
-
-
-void debug_numplan(int port, int numplan, char *type)
-{
- switch (numplan) {
- case NUMPLAN_INTERNATIONAL:
- chan_misdn_log(2, port, " --> %s: International\n",type);
- break;
- case NUMPLAN_NATIONAL:
- chan_misdn_log(2, port, " --> %s: National\n",type);
- break;
- case NUMPLAN_SUBSCRIBER:
- chan_misdn_log(2, port, " --> %s: Subscriber\n",type);
- break;
- case NUMPLAN_UNKNOWN:
- chan_misdn_log(2, port, " --> %s: Unknown\n",type);
- break;
- /* Maybe we should cut off the prefix if present ? */
- default:
- chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
- break;
- }
-}
-
-
-
-
-#ifdef MISDN_1_2
-static int update_pipeline_config(struct misdn_bchannel *bc)
-{
- int ec;
-
- misdn_cfg_get(bc->port, MISDN_CFG_PIPELINE, bc->pipeline, sizeof(bc->pipeline));
-
- if (*bc->pipeline)
- return 0;
-
- misdn_cfg_get(bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
- if (ec == 1)
- snprintf(bc->pipeline, sizeof(bc->pipeline) - 1, "mg2ec");
- else if (ec > 1)
- snprintf(bc->pipeline, sizeof(bc->pipeline) - 1, "mg2ec(deftaps=%d)", ec);
-
- return 0;
-}
-#else
-static int update_ec_config(struct misdn_bchannel *bc)
-{
- int ec;
- int port=bc->port;
-
- misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
-
- if (ec == 1 ) {
- bc->ec_enable=1;
- } else if ( ec > 1 ) {
- bc->ec_enable=1;
- bc->ec_deftaps=ec;
- }
-
- return 0;
-}
-#endif
-
-
-static int read_config(struct chan_list *ch, int orig)
-{
- struct ast_channel *ast;
- struct misdn_bchannel *bc;
- int port;
- char lang[BUFFERSIZE+1];
- char localmusicclass[BUFFERSIZE+1];
- char faxdetect[BUFFERSIZE+1];
- int hdlc = 0;
-
- if (!ch) {
- ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
- return -1;
- }
-
- ast=ch->ast;
- bc=ch->bc;
- if (! ast || ! bc ) {
- ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
- return -1;
- }
-
- port=bc->port;
-
-
- chan_misdn_log(1,port,"read_config: Getting Config\n");
-
- misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE);
- ast_string_field_set(ast, language, lang);
-
- misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, localmusicclass, BUFFERSIZE);
- ast_string_field_set(ast, musicclass, localmusicclass);
-
-
- misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int));
-
- misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int));
-
- misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int));
-
- misdn_cfg_get( port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
-
- if (ch->ast_dsp) {
- ch->ignore_dtmf=1;
- }
-
- misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int));
-
- misdn_cfg_get( port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int));
-
- misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
-
- misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
-
- misdn_cfg_get( port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE);
-
- misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
-
- if (hdlc) {
- switch (bc->capability) {
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
- case INFO_CAPABILITY_DIGITAL_RESTRICTED:
- chan_misdn_log(1,bc->port," --> CONF HDLC\n");
- bc->hdlc=1;
- break;
- }
-
- }
- /*Initialize new Jitterbuffer*/
- {
- misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int));
-
- config_jitterbuffer(ch);
- }
-
- misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
-
- ast_copy_string (ast->context,ch->context,sizeof(ast->context));
-
-#ifdef MISDN_1_2
- update_pipeline_config(bc);
-#else
- update_ec_config(bc);
-#endif
-
- {
- int eb3;
-
- misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
- bc->early_bconnect=eb3;
- }
-
- port=bc->port;
-
- {
- char buf[256];
- ast_group_t pg,cg;
-
- misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
- misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
-
- chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
- ast->pickupgroup=pg;
- ast->callgroup=cg;
- }
-
- if ( orig == ORG_AST) {
- misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
-
- if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
- if (strstr(faxdetect, "nojump"))
- ch->faxdetect=2;
- else
- ch->faxdetect=1;
- }
-
- {
- char callerid[BUFFERSIZE+1];
- misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
- if ( ! ast_strlen_zero(callerid) ) {
- chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
- {
- int l = sizeof(bc->oad);
- strncpy(bc->oad,callerid, l);
- bc->oad[l-1] = 0;
- }
-
- }
-
-
- misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
- debug_numplan(port, bc->dnumplan,"TON");
- debug_numplan(port, bc->onumplan,"LTON");
- debug_numplan(port, bc->cpnnumplan,"CTON");
- }
-
- ch->overlap_dial = 0;
- } else { /** ORIGINATOR MISDN **/
- char prefix[BUFFERSIZE+1]="";
- if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
- if (strstr(faxdetect, "nojump"))
- ch->faxdetect=2;
- else
- ch->faxdetect=1;
- }
-
- misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
- debug_numplan(port, bc->cpnnumplan,"CTON");
-
- switch( bc->onumplan ) {
- case NUMPLAN_INTERNATIONAL:
- misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
- break;
-
- case NUMPLAN_NATIONAL:
- misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
- break;
- default:
- break;
- }
-
- {
- int l = strlen(prefix) + strlen(bc->oad);
- char *tmp = alloca(l+1);
- strcpy(tmp,prefix);
- strcat(tmp,bc->oad);
- strcpy(bc->oad,tmp);
- }
-
- if (!ast_strlen_zero(bc->dad)) {
- ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad));
- }
-
- if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
- ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad));
- }
-
- prefix[0] = 0;
-
- switch( bc->dnumplan ) {
- case NUMPLAN_INTERNATIONAL:
- misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
- break;
- case NUMPLAN_NATIONAL:
- misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
- break;
- default:
- break;
- }
-
- {
- int l = strlen(prefix) + strlen(bc->dad);
- char *tmp = alloca(l+1);
- strcpy(tmp,prefix);
- strcat(tmp,bc->dad);
- strcpy(bc->dad,tmp);
- }
-
- if ( strcmp(bc->dad,ast->exten)) {
- ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
- }
-
- ast_set_callerid(ast, bc->oad, NULL, bc->oad);
-
- if ( !ast_strlen_zero(bc->rad) ) {
- if (ast->cid.cid_rdnis)
- free(ast->cid.cid_rdnis);
- ast->cid.cid_rdnis = strdup(bc->rad);
- }
-
- misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
- ast_mutex_init(&ch->overlap_tv_lock);
- } /* ORIG MISDN END */
-
- ch->overlap_dial_task = -1;
-
- if (ch->faxdetect || ch->ast_dsp) {
- misdn_cfg_get( port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
- if (!ch->dsp)
- ch->dsp = ast_dsp_new();
- if (ch->dsp) {
- if (ch->faxdetect)
- ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT);
- else
- ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT );
- }
- if (!ch->trans)
- ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
- }
-
- /* AOCD initialization */
- bc->AOCDtype = Fac_None;
-
- return 0;
-}
-
-
-/*****************************/
-/*** AST Indications Start ***/
-/*****************************/
-
-static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
-{
- int port=0;
- int r;
- int exceed;
- struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
- struct misdn_bchannel *newbc;
- char *opts=NULL, *ext;
-
- {
- ext = ast_strdupa(dest);
- strsep(&ext,"/");
- if (ext) {
- opts=ext;
- strsep(&opts,"/");
- } else {
- ast_log(LOG_WARNING, "Malformed dialstring\n");
- return -1;
- }
- }
-
- if (!ast) {
- ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
- return -1;
- }
-
- if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) {
- ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
- ast->hangupcause=41;
- ast_setstate(ast, AST_STATE_DOWN);
- return -1;
- }
-
- if (!ch) {
- ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
- ast->hangupcause=41;
- ast_setstate(ast, AST_STATE_DOWN);
- return -1;
- }
-
- newbc=ch->bc;
-
- if (!newbc) {
- ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
- ast->hangupcause=41;
- ast_setstate(ast, AST_STATE_DOWN);
- return -1;
- }
-
- port=newbc->port;
-
- if ((exceed=add_out_calls(port))) {
- char tmp[16];
- sprintf(tmp,"%d",exceed);
- pbx_builtin_setvar_helper(ast,"MAX_OVERFLOW",tmp);
- return -1;
- }
-
- chan_misdn_log(1, port, "* CALL: %s\n",dest);
-
- chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
-
- chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
- if (ast->exten) {
- int l = sizeof(newbc->dad);
- strncpy(ast->exten,ext,sizeof(ast->exten));
-
- strncpy(newbc->dad,ext,l);
-
- newbc->dad[l-1] = 0;
- }
-
- if (ast->cid.cid_rdnis)
- strcpy(newbc->rad, ast->cid.cid_rdnis);
- else
- newbc->rad[0]=0;
-
- chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",ast->cid.cid_num);
- if (ast_strlen_zero(newbc->oad) && ast->cid.cid_num ) {
-
- if (ast->cid.cid_num) {
- int l = sizeof(newbc->oad);
- strncpy(newbc->oad,ast->cid.cid_num, l);
- newbc->oad[l-1] = 0;
- }
- }
-
- {
- int bridging;
- struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
- if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}
-
- newbc->capability=ast->transfercapability;
- pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
- if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
- chan_misdn_log(2, port, " --> * Call with flag Digital\n");
- }
-
-
- /* update screening and presentation */
- update_config(ch,ORG_AST);
-
- /* fill in some ies from channel vary*/
- import_ch(ast, newbc, ch);
-
- /* Finally The Options Override Everything */
- if (opts)
- misdn_set_opt_exec(ast,opts);
- else
- chan_misdn_log(2,port,"NO OPTS GIVEN\n");
-
- /*check for bridging*/
- misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
- if (bridging && ch->other_ch) {
-#ifdef MISDN_1_2
- chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
- *ch->bc->pipeline=0;
- *ch->other_ch->bc->pipeline=0;
-#else
- chan_misdn_log(1, port, "Disabling EC on both Sides\n");
- ch->bc->ec_enable=0;
- ch->other_ch->bc->ec_enable=0;
-#endif
- }
-
- r=misdn_lib_send_event( newbc, EVENT_SETUP );
-
- /** we should have l3id after sending setup **/
- ch->l3id=newbc->l3_id;
- }
-
- if ( r == -ENOCHAN ) {
- chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
- chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
- ast->hangupcause=34;
- ast_setstate(ast, AST_STATE_DOWN);
- return -1;
- }
-
- chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
-
- ast_setstate(ast, AST_STATE_DIALING);
- ast->hangupcause=16;
-
- if (newbc->nt) stop_bc_tones(ch);
-
- ch->state=MISDN_CALLING;
-
- return 0;
-}
-
-
-static int misdn_answer(struct ast_channel *ast)
-{
- struct chan_list *p;
-
-
- if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
-
- chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");
-
- if (!p) {
- ast_log(LOG_WARNING, " --> Channel not connected ??\n");
- ast_queue_hangup(ast);
- }
-
- if (!p->bc) {
- chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");
-
- ast_queue_hangup(ast);
- }
-
- {
- const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
-
- if (tmp_key ) {
- chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
- {
- int l = sizeof(p->bc->crypt_key);
- strncpy(p->bc->crypt_key,tmp_key, l);
- p->bc->crypt_key[l-1] = 0;
- }
- } else {
- chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
- }
-
- }
-
- {
- const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
- if (nodsp) {
- chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
- p->bc->nodsp=1;
- p->bc->hdlc=0;
- p->bc->nojitter=1;
- }
- }
-
- p->state = MISDN_CONNECTED;
- stop_indicate(p);
-
- if ( ast_strlen_zero(p->bc->cad) ) {
- chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
- ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad));
- }
-
- misdn_lib_send_event( p->bc, EVENT_CONNECT);
- start_bc_tones(p);
-
- return 0;
-}
-
-static int misdn_digit_begin(struct ast_channel *chan, char digit)
-{
- /* XXX Modify this callback to support Asterisk controlling the length of DTMF */
- return 0;
-}
-
-static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct chan_list *p;
- struct misdn_bchannel *bc;
-
- if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1;
-
- bc=p->bc;
- chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);
-
- if (!bc) {
- ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n");
- return -1;
- }
-
- switch (p->state ) {
- case MISDN_CALLING:
- {
- int l;
- char buf[8];
- buf[0]=digit;
- buf[1]=0;
-
- l = sizeof(bc->infos_pending);
- strncat(bc->infos_pending, buf, l - strlen(bc->infos_pending) - 1);
- }
- break;
- case MISDN_CALLING_ACKNOWLEDGE:
- {
- bc->info_dad[0]=digit;
- bc->info_dad[1]=0;
-
- {
- int l = sizeof(bc->dad);
- strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1);
- }
- {
- int l = sizeof(p->ast->exten);
- strncpy(p->ast->exten, bc->dad, l);
- p->ast->exten[l-1] = 0;
- }
-
- misdn_lib_send_event( bc, EVENT_INFORMATION);
- }
- break;
-
- default:
- /* Do not send Digits in CONNECTED State, when
- * the other side is too mISDN. */
- if (p->other_ch )
- return 0;
-
- if ( bc->send_dtmf )
- send_digit_to_chan(p,digit);
- break;
- }
-
- return 0;
-}
-
-
-static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
-{
- struct chan_list *p;
-
- if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
-
- chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
-
- p->ast = ast ;
-
- return 0;
-}
-
-
-
-static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
-{
- struct chan_list *p;
-
-
- if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
- ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n");
- return -1;
- }
-
- if (!p->bc ) {
- chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten);
- ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
- return -1;
- }
-
- chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
-
- switch (cond) {
- case AST_CONTROL_BUSY:
- chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1);
- ast_setstate(ast,AST_STATE_BUSY);
-
- p->bc->out_cause=17;
- if (p->state != MISDN_CONNECTED) {
- start_bc_tones(p);
- misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
- } else {
- chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name);
- }
- return -1;
- break;
- case AST_CONTROL_RING:
- chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
- return -1;
- break;
-
- case AST_CONTROL_RINGING:
- chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
- switch (p->state) {
- case MISDN_ALERTING:
- chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
- break;
- case MISDN_CONNECTED:
- chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
- return -1;
- break;
- default:
- p->state=MISDN_ALERTING;
- chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
- misdn_lib_send_event( p->bc, EVENT_ALERTING);
-
- if (p->other_ch && p->other_ch->bc) {
- if (misdn_inband_avail(p->other_ch->bc)) {
- chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n");
- break;
- }
-
- if (!p->other_ch->bc->nt) {
- chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
- break;
- }
- }
-
- chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
- ast_setstate(ast,AST_STATE_RINGING);
-
- if ( !p->bc->nt && (p->originator==ORG_MISDN) && !p->incoming_early_audio )
- chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n");
- else
- return -1;
- }
- break;
- case AST_CONTROL_ANSWER:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1);
- start_bc_tones(p);
- break;
- case AST_CONTROL_TAKEOFFHOOK:
- chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1);
- return -1;
- break;
- case AST_CONTROL_OFFHOOK:
- chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1);
- return -1;
- break;
- case AST_CONTROL_FLASH:
- chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1);
- break;
- case AST_CONTROL_PROGRESS:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1);
- misdn_lib_send_event( p->bc, EVENT_PROGRESS);
- break;
- case AST_CONTROL_PROCEEDING:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1);
- misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
- break;
- case AST_CONTROL_CONGESTION:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1);
-
- p->bc->out_cause=42;
- start_bc_tones(p);
- misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
-
- if (p->bc->nt) {
- hanguptone_indicate(p);
- }
- break;
- case -1 :
- chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1);
-
- stop_indicate(p);
-
- if (p->state == MISDN_CONNECTED)
- start_bc_tones(p);
-
- break;
-
- case AST_CONTROL_HOLD:
- ast_moh_start(ast,data,ast->musicclass);
- chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1);
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(ast);
- chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
- break;
- default:
- chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
- }
-
- return 0;
-}
-
-static int misdn_hangup(struct ast_channel *ast)
-{
- struct chan_list *p;
- struct misdn_bchannel *bc=NULL;
-
- ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
-
- if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;
-
- if (!p) {
- chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");
- return 0 ;
- }
-
- bc=p->bc;
-
- if (bc) {
- const char *tmp=pbx_builtin_getvar_helper(ast,"MISDN_USERUSER");
- if (tmp) {
- ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
- strcpy(bc->uu, tmp);
- bc->uulen=strlen(bc->uu);
- }
- }
-
- MISDN_ASTERISK_TECH_PVT(ast)=NULL;
- p->ast=NULL;
-
- if (ast->_state == AST_STATE_RESERVED ||
- p->state == MISDN_NOTHING ||
- p->state == MISDN_HOLDED ||
- p->state == MISDN_HOLD_DISCONNECT ) {
-
- CLEAN_CH:
- /* between request and call */
- ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
- MISDN_ASTERISK_TECH_PVT(ast)=NULL;
-
- ast_mutex_lock(&release_lock);
- cl_dequeue_chan(&cl_te, p);
- close(p->pipe[0]);
- close(p->pipe[1]);
- free(p);
- ast_mutex_unlock(&release_lock);
-
- if (bc)
- misdn_lib_release(bc);
-
- return 0;
- }
-
- if (!bc) {
- ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);
- goto CLEAN_CH;
- }
-
-
- p->need_hangup=0;
- p->need_queue_hangup=0;
- p->need_busy=0;
-
-
- if (!p->bc->nt)
- stop_bc_tones(p);
-
-
- {
- const char *varcause=NULL;
- bc->out_cause=ast->hangupcause?ast->hangupcause:16;
-
- if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||
- (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {
- int tmpcause=atoi(varcause);
- bc->out_cause=tmpcause?tmpcause:16;
- }
-
- chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, ast->cid.cid_num, misdn_get_ch_state(p));
- chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id);
- chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause);
- chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause);
- chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
-
- switch (p->state) {
- case MISDN_CALLING:
- case MISDN_INCOMING_SETUP:
- /* This is the only place in misdn_hangup, where we
- * can call release_chan, else it might create lot's of trouble
- * */
- ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n");
- release_chan(bc);
-
- p->state=MISDN_CLEANING;
- if (bc->need_release_complete)
- misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
- break;
- case MISDN_HOLDED:
- case MISDN_DIALING:
- start_bc_tones(p);
- hanguptone_indicate(p);
-
- if (bc->need_disconnect)
- misdn_lib_send_event( bc, EVENT_DISCONNECT);
- break;
-
- case MISDN_CALLING_ACKNOWLEDGE:
- start_bc_tones(p);
- hanguptone_indicate(p);
-
- if (bc->need_disconnect)
- misdn_lib_send_event( bc, EVENT_DISCONNECT);
- break;
-
- case MISDN_ALERTING:
- case MISDN_PROGRESS:
- case MISDN_PROCEEDING:
- if (p->originator != ORG_AST)
- hanguptone_indicate(p);
-
- /*p->state=MISDN_CLEANING;*/
- if (bc->need_disconnect)
- misdn_lib_send_event( bc, EVENT_DISCONNECT);
- break;
- case MISDN_CONNECTED:
- case MISDN_PRECONNECTED:
- /* Alerting or Disconect */
- if (p->bc->nt) {
- start_bc_tones(p);
- hanguptone_indicate(p);
- p->bc->progress_indicator=8;
- }
- if (bc->need_disconnect)
- misdn_lib_send_event( bc, EVENT_DISCONNECT);
-
- /*p->state=MISDN_CLEANING;*/
- break;
- case MISDN_DISCONNECTED:
- if (bc->need_release)
- misdn_lib_send_event( bc, EVENT_RELEASE);
- p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */
- break;
-
- case MISDN_RELEASED:
- case MISDN_CLEANING:
- p->state=MISDN_CLEANING;
- break;
-
- case MISDN_BUSY:
- break;
-
- case MISDN_HOLD_DISCONNECT:
- /* need to send release here */
- chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause);
- chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause);
-
- bc->out_cause=-1;
- if (bc->need_release)
- misdn_lib_send_event(bc,EVENT_RELEASE);
- p->state=MISDN_CLEANING;
- break;
- default:
- if (bc->nt) {
- bc->out_cause=-1;
- if (bc->need_release)
- misdn_lib_send_event(bc, EVENT_RELEASE);
- p->state=MISDN_CLEANING;
- } else {
- if (bc->need_disconnect)
- misdn_lib_send_event(bc, EVENT_DISCONNECT);
- }
- }
-
- p->state=MISDN_CLEANING;
-
- }
-
-
- chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
-
- return 0;
-}
-
-
-static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
-{
- struct ast_frame *f,*f2;
-
- if (tmp->trans) {
- f2 = ast_translate(tmp->trans, frame, 0);
- f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
- } else {
- chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
- return NULL;
- }
-
-
- if (!f || (f->frametype != AST_FRAME_DTMF))
- return frame;
-
- ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass);
-
- if (tmp->faxdetect && (f->subclass == 'f')) {
- /* Fax tone -- Handle and return NULL */
- if (!tmp->faxhandled) {
- struct ast_channel *ast = tmp->ast;
- tmp->faxhandled++;
- chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
- tmp->bc->rxgain = 0;
- isdn_lib_update_rxgain(tmp->bc);
- tmp->bc->txgain = 0;
- isdn_lib_update_txgain(tmp->bc);
-#ifdef MISDN_1_2
- *tmp->bc->pipeline = 0;
-#else
- tmp->bc->ec_enable = 0;
-#endif
- isdn_lib_update_ec(tmp->bc);
- isdn_lib_stop_dtmf(tmp->bc);
- switch (tmp->faxdetect) {
- case 1:
- if (strcmp(ast->exten, "fax")) {
- char *context;
- char context_tmp[BUFFERSIZE];
- misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
- context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
- if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
- /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
- pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
- if (ast_async_goto(ast, context, "fax", 1))
- ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
- } else
- ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
- } else
- ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
- break;
- case 2:
- ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
- break;
- }
- } else
- ast_log(LOG_DEBUG, "Fax already handled\n");
- }
-
- if (tmp->ast_dsp && (f->subclass != 'f')) {
- chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass);
- }
-
- return f;
-}
-
-
-static struct ast_frame *misdn_read(struct ast_channel *ast)
-{
- struct chan_list *tmp;
- fd_set rrfs;
- struct timeval tv;
- int len, t;
-
- if (!ast) {
- chan_misdn_log(1,0,"misdn_read called without ast\n");
- return NULL;
- }
- if (!(tmp=MISDN_ASTERISK_TECH_PVT(ast))) {
- chan_misdn_log(1,0,"misdn_read called without ast->pvt\n");
- return NULL;
- }
-
- if (!tmp->bc && !(tmp->state==MISDN_HOLDED)) {
- chan_misdn_log(1,0,"misdn_read called without bc\n");
- return NULL;
- }
-
- tv.tv_sec=0;
- tv.tv_usec=20000;
-
- FD_ZERO(&rrfs);
- FD_SET(tmp->pipe[0],&rrfs);
-
- t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv);
-
- if (!t) {
- chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n");
- len=160;
- }
-
- if (t<0) {
- chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno));
- return NULL;
- }
-
- if (FD_ISSET(tmp->pipe[0],&rrfs)) {
- len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
-
- if (len<=0) {
- /* we hangup here, since our pipe is closed */
- chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
- return NULL;
- }
-
- } else {
- return NULL;
- }
-
- tmp->frame.frametype = AST_FRAME_VOICE;
- tmp->frame.subclass = AST_FORMAT_ALAW;
- tmp->frame.datalen = len;
- tmp->frame.samples = len;
- tmp->frame.mallocd = 0;
- tmp->frame.offset = 0;
- tmp->frame.delivery= ast_tv(0,0) ;
- tmp->frame.src = NULL;
- tmp->frame.data = tmp->ast_rd_buf;
-
- if (tmp->faxdetect && !tmp->faxhandled) {
- if (tmp->faxdetect_timeout) {
- if (ast_tvzero(tmp->faxdetect_tv)) {
- tmp->faxdetect_tv = ast_tvnow();
- chan_misdn_log(2,tmp->bc->port,"faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
- return process_ast_dsp(tmp, &tmp->frame);
- } else {
- struct timeval tv_now = ast_tvnow();
- int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
- if (diff <= (tmp->faxdetect_timeout * 1000)) {
- chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ...\n");
- return process_ast_dsp(tmp, &tmp->frame);
- } else {
- chan_misdn_log(2,tmp->bc->port,"faxdetect: stopping detection (time ran out) ...\n");
- tmp->faxdetect = 0;
- return &tmp->frame;
- }
- }
- } else {
- chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ... (no timeout)\n");
- return process_ast_dsp(tmp, &tmp->frame);
- }
- } else {
- if (tmp->ast_dsp)
- return process_ast_dsp(tmp, &tmp->frame);
- else
- return &tmp->frame;
- }
-}
-
-
-static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct chan_list *ch;
- int i = 0;
-
- if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
-
- if (ch->state == MISDN_HOLDED) {
- chan_misdn_log(7, 0, "misdn_write: Returning because holded\n");
- return 0;
- }
-
- if (!ch->bc ) {
- ast_log(LOG_WARNING, "private but no bc\n");
- return -1;
- }
-
- if (ch->notxtone) {
- chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxone\n");
- return 0;
- }
-
-
- if ( !frame->subclass) {
- chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
- return 0;
- }
-
- if ( !(frame->subclass & prefformat)) {
-
- chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
- return 0;
- }
-
-
- if ( !frame->samples ) {
- chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
-
- if (!strcmp(frame->src,"ast_prod")) {
- chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
-
- if (ch->ts) {
- chan_misdn_log(4,ch->bc->port,"Starting Playtones\n");
- misdn_lib_tone_generator_start(ch->bc);
- }
- return 0;
- }
-
- return -1;
- }
-
- if ( ! ch->bc->addr ) {
- chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
- return 0;
- }
-
-#if MISDN_DEBUG
- {
- int i, max=5>frame->samples?frame->samples:5;
-
- printf("write2mISDN %p %d bytes: ", p, frame->samples);
-
- for (i=0; i< max ; i++) printf("%2.2x ",((char*) frame->data)[i]);
- printf ("\n");
- }
-#endif
-
-
- switch (ch->bc->bc_state) {
- case BCHAN_ACTIVATED:
- case BCHAN_BRIDGED:
- break;
- default:
- if (!ch->dropped_frame_cnt)
- chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id);
-
- ch->dropped_frame_cnt++;
- if (ch->dropped_frame_cnt > 100) {
- ch->dropped_frame_cnt=0;
- chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x dropped > 100 frames!\n",frame->samples,ch->bc->addr);
-
- }
-
- return 0;
- }
-
- chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
- if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
- /* Buffered Transmit (triggert by read from isdn side)*/
- if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
- if (ch->bc->active)
- cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n");
- }
-
- } else {
- /*transmit without jitterbuffer*/
- i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
- }
-
-
-
- return 0;
-}
-
-
-
-
-static enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
- struct ast_channel *c1, int flags,
- struct ast_frame **fo,
- struct ast_channel **rc,
- int timeoutms)
-
-{
- struct chan_list *ch1,*ch2;
- struct ast_channel *carr[2], *who;
- int to=-1;
- struct ast_frame *f;
- int p1_b, p2_b;
- int bridging;
-
- ch1=get_chan_by_ast(c0);
- ch2=get_chan_by_ast(c1);
-
- carr[0]=c0;
- carr[1]=c1;
-
- if (ch1 && ch2 ) ;
- else
- return -1;
-
- misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int));
- misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int));
-
- if ( ! p1_b || ! p2_b) {
- ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
- return AST_BRIDGE_FAILED;
- }
-
- misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
- if (bridging) {
- /* trying to make a mISDN_dsp conference */
- chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1);
- misdn_lib_bridge(ch1->bc,ch2->bc);
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
-
- chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
-
- if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) )
- ch1->ignore_dtmf=1;
-
- if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) )
- ch2->ignore_dtmf=1;
-
- while(1) {
- to=-1;
- who = ast_waitfor_n(carr, 2, &to);
-
- if (!who) {
- ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
- break;
- }
- f = ast_read(who);
-
- if (!f || f->frametype == AST_FRAME_CONTROL) {
- /* got hangup .. */
-
- if (!f)
- chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n");
- else
- chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
-
- *fo=f;
- *rc=who;
-
- break;
- }
-
- if ( f->frametype == AST_FRAME_DTMF ) {
- chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten);
-
- *fo=f;
- *rc=who;
- break;
- }
-
-#if 0
- if (f->frametype == AST_FRAME_VOICE) {
- chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
-
- continue;
- }
-#endif
-
- if (who == c0) {
- ast_write(c1,f);
- }
- else {
- ast_write(c0,f);
- }
-
- }
-
- chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
-
- misdn_lib_split_bridge(ch1->bc,ch2->bc);
-
-
- return AST_BRIDGE_COMPLETE;
-}
-
-/** AST INDICATIONS END **/
-
-static int dialtone_indicate(struct chan_list *cl)
-{
- const struct tone_zone_sound *ts= NULL;
- struct ast_channel *ast=cl->ast;
- int nd=0;
-
- if (!ast) {
- chan_misdn_log(0,cl->bc->port,"No Ast in dialtone_indicate\n");
- return -1;
- }
-
- misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
-
- if (nd) {
- chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n");
- return 0;
- }
-
- chan_misdn_log(3,cl->bc->port," --> Dial\n");
- ts=ast_get_indication_tone(ast->zone,"dial");
- cl->ts=ts;
-
- if (ts) {
- cl->notxtone=0;
- cl->norxtone=0;
- /* This prods us in misdn_write */
- ast_playtones_start(ast,0, ts->data, 0);
- }
-
- return 0;
-}
-
-static int hanguptone_indicate(struct chan_list *cl)
-{
- misdn_lib_send_tone(cl->bc,TONE_HANGUP);
- return 0;
-}
-
-static int stop_indicate(struct chan_list *cl)
-{
- struct ast_channel *ast=cl->ast;
-
- if (!ast) {
- chan_misdn_log(0,cl->bc->port,"No Ast in stop_indicate\n");
- return -1;
- }
-
- chan_misdn_log(3,cl->bc->port," --> None\n");
- misdn_lib_tone_generator_stop(cl->bc);
- ast_playtones_stop(ast);
-
- cl->ts=NULL;
- /*ast_deactivate_generator(ast);*/
-
- return 0;
-}
-
-
-static int start_bc_tones(struct chan_list* cl)
-{
- misdn_lib_tone_generator_stop(cl->bc);
- cl->notxtone=0;
- cl->norxtone=0;
- return 0;
-}
-
-static int stop_bc_tones(struct chan_list *cl)
-{
- if (!cl) return -1;
-
- cl->notxtone=1;
- cl->norxtone=1;
-
- return 0;
-}
-
-
-static struct chan_list *init_chan_list(int orig)
-{
- struct chan_list *cl=malloc(sizeof(struct chan_list));
-
- if (!cl) {
- chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
- return NULL;
- }
-
- memset(cl,0,sizeof(struct chan_list));
-
- cl->originator=orig;
- cl->need_queue_hangup=1;
- cl->need_hangup=1;
- cl->need_busy=1;
- cl->overlap_dial_task=-1;
-
- return cl;
-
-}
-
-static struct ast_channel *misdn_request(const char *type, int format, void *data, int *cause)
-
-{
- struct ast_channel *tmp = NULL;
- char group[BUFFERSIZE+1]="";
- char buf[128];
- char buf2[128], *ext=NULL, *port_str;
- char *tokb=NULL, *p=NULL;
- int channel=0, port=0;
- struct misdn_bchannel *newbc = NULL;
- int dec=0;
-
- struct chan_list *cl=init_chan_list(ORG_AST);
-
- sprintf(buf,"%s/%s",misdn_type,(char*)data);
- ast_copy_string(buf2,data, 128);
-
- port_str=strtok_r(buf2,"/", &tokb);
-
- ext=strtok_r(NULL,"/", &tokb);
-
- if (port_str) {
- if (port_str[0]=='g' && port_str[1]==':' ) {
- /* We make a group call lets checkout which ports are in my group */
- port_str += 2;
- strncpy(group, port_str, BUFFERSIZE);
- group[127] = 0;
- chan_misdn_log(2, 0, " --> Group Call group: %s\n",group);
- }
- else if ((p = strchr(port_str, ':'))) {
- /* we have a preselected channel */
- *p = 0;
- channel = atoi(++p);
- port = atoi(port_str);
- chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
- }
- else {
- port = atoi(port_str);
- }
- } else {
- ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext);
- return NULL;
- }
-
- if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) {
- chan_misdn_log(4, port, " --> STARTING STANDARDDEC...\n");
- dec=1;
- }
-
- if (!ast_strlen_zero(group)) {
-
- char cfg_group[BUFFERSIZE+1];
- struct robin_list *rr = NULL;
-
- if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
- chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
- rr = get_robin_position(group);
- }
-
- if (rr) {
- int port_start = 0;
- int port_bak = rr->port;
- int chan_bak = rr->channel;
-
- if (!rr->port)
- rr->port = misdn_cfg_get_next_port_spin(rr->port);
-
- for (; rr->port > 0; rr->port = misdn_cfg_get_next_port_spin(rr->port)) {
- int port_up;
- int check;
- int max_chan;
- int last_chance = 0;
-
- misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
- if (strcasecmp(cfg_group, group))
- continue;
-
- misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
- port_up = misdn_lib_port_up(rr->port, check);
-
- if (check && !port_up)
- chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n");
-
- if (check && port_up < 0)
- ast_log(LOG_WARNING,"This port (%d) is blocked\n", rr->port);
-
- if ((port_start == rr->port) && (port_up <= 0))
- break;
-
- if (!port_start)
- port_start = rr->port;
-
- if (port_up <= 0)
- continue;
-
- max_chan = misdn_lib_get_maxchans(rr->port);
-
- for (++rr->channel; !last_chance && rr->channel <= max_chan; ++rr->channel) {
- if (rr->port == port_bak && rr->channel == chan_bak)
- last_chance = 1;
-
- chan_misdn_log(1, 0, "trying port:%d channel:%d\n", rr->port, rr->channel);
- newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0);
- if (newbc) {
- chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
- if (port_up)
- chan_misdn_log(4, rr->port, "portup:%d\n", port_up);
- port = rr->port;
- break;
- }
- }
-
- if (newbc || last_chance)
- break;
-
- rr->channel = 0;
- }
- if (!newbc) {
- rr->port = port_bak;
- rr->channel = chan_bak;
- }
- } else {
- for (port=misdn_cfg_get_next_port(0); port > 0;
- port=misdn_cfg_get_next_port(port)) {
-
- misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
-
- chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port);
- if (!strcasecmp(cfg_group, group)) {
- int port_up;
- int check;
- misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
- port_up = misdn_lib_port_up(port, check);
-
- chan_misdn_log(4, port, "portup:%d\n", port_up);
-
- if ( port_up>0 ) {
- newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
- if (newbc)
- break;
- }
- }
- }
- }
-
- /* Group dial failed ?*/
- if (!newbc) {
- ast_log(LOG_WARNING,
- "Could not Dial out on group '%s'.\n"
- "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
- "\tOr there was no free channel on none of the ports\n\n"
- , group);
- return NULL;
- }
- } else { /* 'Normal' Port dial * Port dial */
- if (channel)
- chan_misdn_log(1, port," --> preselected_channel: %d\n",channel);
- newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
-
- if (!newbc) {
- ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n",port,ext);
- return NULL;
- }
- }
-
-
- /* create ast_channel and link all the objects together */
- cl->bc=newbc;
-
- tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
- if (!tmp) {
- ast_log(LOG_ERROR,"Could not create Asterisk object\n");
- return NULL;
- }
-
- cl->ast=tmp;
-
- /* register chan in local list */
- cl_queue_chan(&cl_te, cl) ;
-
- /* fill in the config into the objects */
- read_config(cl, ORG_AST);
-
- /* important */
- cl->need_hangup=0;
-
- return tmp;
-}
-
-
-static int misdn_send_text (struct ast_channel *chan, const char *text)
-{
- struct chan_list *tmp=chan->tech_pvt;
-
- if (tmp && tmp->bc) {
- ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display));
- misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
- } else {
- ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
- return -1;
- }
-
- return 0;
-}
-
-static struct ast_channel_tech misdn_tech = {
- .type="mISDN",
- .description="Channel driver for mISDN Support (Bri/Pri)",
- .capabilities= AST_FORMAT_ALAW ,
- .requester=misdn_request,
- .send_digit_begin=misdn_digit_begin,
- .send_digit_end=misdn_digit_end,
- .call=misdn_call,
- .bridge=misdn_bridge,
- .hangup=misdn_hangup,
- .answer=misdn_answer,
- .read=misdn_read,
- .write=misdn_write,
- .indicate=misdn_indication,
- .fixup=misdn_fixup,
- .send_text=misdn_send_text,
- .properties=0
-};
-
-static struct ast_channel_tech misdn_tech_wo_bridge = {
- .type="mISDN",
- .description="Channel driver for mISDN Support (Bri/Pri)",
- .capabilities=AST_FORMAT_ALAW ,
- .requester=misdn_request,
- .send_digit_begin=misdn_digit_begin,
- .send_digit_end=misdn_digit_end,
- .call=misdn_call,
- .hangup=misdn_hangup,
- .answer=misdn_answer,
- .read=misdn_read,
- .write=misdn_write,
- .indicate=misdn_indication,
- .fixup=misdn_fixup,
- .send_text=misdn_send_text,
- .properties=0
-};
-
-
-static int glob_channel=0;
-
-static void update_name(struct ast_channel *tmp, int port, int c)
-{
- int chan_offset=0;
- int tmp_port = misdn_cfg_get_next_port(0);
- for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) {
- if (tmp_port == port) break;
- chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2;
- }
- if (c<0) c=0;
-
- ast_string_field_build(tmp, name, "%s/%d-u%d",
- misdn_type, chan_offset+c, glob_channel++);
-
- chan_misdn_log(3,port," --> updating channel name to [%s]\n",tmp->name);
-
-}
-
-static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, int port, int c)
-{
- struct ast_channel *tmp;
- char *cid_name = 0, *cid_num = 0;
- int chan_offset=0;
- int tmp_port = misdn_cfg_get_next_port(0);
-
- for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) {
- if (tmp_port == port) break;
- chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2;
- }
- if (c<0) c=0;
-
-
- if (callerid)
- ast_callerid_parse(callerid, &cid_name, &cid_num);
-
- tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
-
- if (tmp) {
- int bridging;
- chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid);
-
- tmp->nativeformats = prefformat;
-
- tmp->readformat = format;
- tmp->rawreadformat = format;
- tmp->writeformat = format;
- tmp->rawwriteformat = format;
-
- tmp->tech_pvt = chlist;
-
- misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
-
- if (bridging)
- tmp->tech = &misdn_tech;
- else
- tmp->tech = &misdn_tech_wo_bridge;
-
- tmp->writeformat = format;
- tmp->readformat = format;
- tmp->priority=1;
-
- if (exten)
- ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
- else
- chan_misdn_log(1,0,"misdn_new: no exten given.\n");
-
- if (callerid)
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(cid_num);
-
- {
- if (pipe(chlist->pipe)<0)
- perror("Pipe failed\n");
-
- tmp->fds[0]=chlist->pipe[0];
-
- }
-
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- else
- tmp->rings = 0;
-
-
- } else {
- chan_misdn_log(-1,0,"Unable to allocate channel structure\n");
- }
-
- return tmp;
-}
-
-static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc)
-{
- struct chan_list *help=list;
- for (;help; help=help->next) {
- if (help->bc == bc) return help;
- }
-
- chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
-
- return NULL;
-}
-
-static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid)
-{
- struct chan_list *help=list;
- for (;help; help=help->next) {
- if ( help->bc && (help->bc->pid == pid) ) return help;
- }
-
- chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid);
-
- return NULL;
-}
-
-static struct chan_list *find_holded(struct chan_list *list, struct misdn_bchannel *bc)
-{
- struct chan_list *help=list;
-
- if (bc->pri) return NULL;
-
- chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
- for (;help; help=help->next) {
- chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel);
- if ( (help->state == MISDN_HOLDED) &&
- (help->hold_info.port == bc->port) )
- return help;
- }
- chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
-
- return NULL;
-}
-
-
-static struct chan_list *find_holded_l3(struct chan_list *list, unsigned long l3_id, int w)
-
-{
- struct chan_list *help=list;
-
- for (;help; help=help->next) {
- if ( (help->state == MISDN_HOLDED) &&
- (help->l3id == l3_id)
- )
- return help;
- }
-
- return NULL;
-}
-
-static void cl_queue_chan(struct chan_list **list, struct chan_list *chan)
-{
- chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
-
- ast_mutex_lock(&cl_te_lock);
- if (!*list) {
- *list = chan;
- } else {
- struct chan_list *help=*list;
- for (;help->next; help=help->next);
- help->next=chan;
- }
- chan->next=NULL;
- ast_mutex_unlock(&cl_te_lock);
-}
-
-static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan)
-{
- if (chan->dsp)
- ast_dsp_free(chan->dsp);
- if (chan->trans)
- ast_translator_free_path(chan->trans);
-
-
-
- ast_mutex_lock(&cl_te_lock);
- if (!*list) {
- ast_mutex_unlock(&cl_te_lock);
- return;
- }
-
- if (*list == chan) {
- *list=(*list)->next;
- ast_mutex_unlock(&cl_te_lock);
- return ;
- }
-
- {
- struct chan_list *help=*list;
- for (;help->next; help=help->next) {
- if (help->next == chan) {
- help->next=help->next->next;
- ast_mutex_unlock(&cl_te_lock);
- return;
- }
- }
- }
-
- ast_mutex_unlock(&cl_te_lock);
-}
-
-/** Channel Queue End **/
-
-
-int pbx_start_chan(struct chan_list *ch)
-{
- int ret=ast_pbx_start(ch->ast);
-
- if (ret>=0)
- ch->need_hangup=0;
- else
- ch->need_hangup=1;
-
- return ret;
-}
-
-static void hangup_chan(struct chan_list *ch)
-{
- int port=ch?ch->bc?ch->bc->port:0:0;
- if (!ch) {
- cb_log(1,0,"Cannot hangup chan, no ch\n");
- return;
- }
-
- cb_log(5,port,"hangup_chan called\n");
-
- if (ch->need_hangup)
- {
- cb_log(2,port," --> hangup\n");
- send_cause2ast(ch->ast,ch->bc,ch);
- ch->need_hangup=0;
- ch->need_queue_hangup=0;
- if (ch->ast)
- ast_hangup(ch->ast);
- return;
- }
-
- if (!ch->need_queue_hangup) {
- cb_log(2,port," --> No need to queue hangup\n");
- }
-
- ch->need_queue_hangup=0;
- if (ch->ast) {
- send_cause2ast(ch->ast,ch->bc,ch);
-
- if (ch->ast)
- ast_queue_hangup(ch->ast);
- cb_log(2,port," --> queue_hangup\n");
- } else {
- cb_log(1,port,"Cannot hangup chan, no ast\n");
- }
-}
-
-/** Isdn asks us to release channel, pendant to misdn_hangup **/
-static void release_chan(struct misdn_bchannel *bc) {
- struct ast_channel *ast=NULL;
-
- ast_mutex_lock(&release_lock);
- {
- struct chan_list *ch=find_chan_by_bc(cl_te, bc);
- if (!ch) {
- chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n");
- ast_mutex_unlock(&release_lock);
- return;
- }
-
- if (ch->ast) {
- ast=ch->ast;
- }
-
- chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
-
- /*releaseing jitterbuffer*/
- if (ch->jb ) {
- misdn_jb_destroy(ch->jb);
- ch->jb=NULL;
- } else {
- if (!bc->nojitter)
- chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n");
- }
-
- if (ch->overlap_dial) {
- if (ch->overlap_dial_task != -1) {
- misdn_tasks_remove(ch->overlap_dial_task);
- ch->overlap_dial_task = -1;
- }
- ast_mutex_destroy(&ch->overlap_tv_lock);
- }
-
- if (ch->originator == ORG_AST) {
- misdn_out_calls[bc->port]--;
- } else {
- misdn_in_calls[bc->port]--;
- }
-
- if (ch) {
-
- close(ch->pipe[0]);
- close(ch->pipe[1]);
-
-
- if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
- chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,ast->cid.cid_num,misdn_get_ch_state(ch));
- chan_misdn_log(3, bc->port, " --> * State Down\n");
- MISDN_ASTERISK_TECH_PVT(ast)=NULL;
-
-
- if (ast->_state != AST_STATE_RESERVED) {
- chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
- ast_setstate(ast, AST_STATE_DOWN);
- }
- }
-
- ch->state=MISDN_CLEANING;
- cl_dequeue_chan(&cl_te, ch);
-
- free(ch);
- } else {
- /* chan is already cleaned, so exiting */
- }
- }
-
- ast_mutex_unlock(&release_lock);
-}
-/*** release end **/
-
-static void misdn_transfer_bc(struct chan_list *tmp_ch, struct chan_list *holded_chan)
-{
- chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name);
-
- tmp_ch->state=MISDN_HOLD_DISCONNECT;
-
- ast_moh_stop(ast_bridged_channel(holded_chan->ast));
-
- holded_chan->state=MISDN_CONNECTED;
- //misdn_lib_transfer(holded_chan->bc);
- ast_channel_masquerade(holded_chan->ast, ast_bridged_channel(tmp_ch->ast));
-}
-
-
-static void do_immediate_setup(struct misdn_bchannel *bc,struct chan_list *ch , struct ast_channel *ast)
-{
- char predial[256]="";
- char *p = predial;
-
- struct ast_frame fr;
-
- strncpy(predial, ast->exten, sizeof(predial) -1 );
-
- ch->state=MISDN_DIALING;
-
- if (!ch->noautorespond_on_setup) {
- if (bc->nt) {
- int ret;
- ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- } else {
- int ret;
- if ( misdn_lib_is_ptp(bc->port)) {
- ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- } else {
- ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
- }
- }
- } else {
- ch->state = MISDN_INCOMING_SETUP;
- }
-
- chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, ast->cid.cid_num);
-
- strncpy(ast->exten,"s", 2);
-
- if (pbx_start_chan(ch)<0) {
- ast=NULL;
- hangup_chan(ch);
- hanguptone_indicate(ch);
-
- if (bc->nt)
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
- else
- misdn_lib_send_event(bc, EVENT_DISCONNECT );
- }
-
-
- while (!ast_strlen_zero(p) ) {
- fr.frametype = AST_FRAME_DTMF;
- fr.subclass = *p ;
- fr.src=NULL;
- fr.data = NULL ;
- fr.datalen = 0;
- fr.samples = 0 ;
- fr.mallocd =0 ;
- fr.offset= 0 ;
- fr.delivery= ast_tv(0,0) ;
-
- if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
- ast_queue_frame(ch->ast, &fr);
- }
- p++;
- }
-}
-
-
-
-static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch) {
- if (!ast) {
- chan_misdn_log(1,0,"send_cause2ast: No Ast\n");
- return;
- }
- if (!bc) {
- chan_misdn_log(1,0,"send_cause2ast: No BC\n");
- return;
- }
- if (!ch) {
- chan_misdn_log(1,0,"send_cause2ast: No Ch\n");
- return;
- }
-
- ast->hangupcause=bc->cause;
-
- switch ( bc->cause) {
-
- case 1: /** Congestion Cases **/
- case 2:
- case 3:
- case 4:
- case 22:
- case 27:
- /*
- * Not Queueing the Congestion anymore, since we want to hear
- * the inband message
- *
- chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1);
- ch->state=MISDN_BUSY;
-
- ast_queue_control(ast, AST_CONTROL_CONGESTION);
- */
- break;
-
- case 21:
- case 17: /* user busy */
-
- ch->state=MISDN_BUSY;
-
- if (!ch->need_busy) {
- chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n");
- break;
- }
-
- chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
-
- ast_queue_control(ast, AST_CONTROL_BUSY);
-
- ch->need_busy=0;
-
- break;
- }
-}
-
-
-
-
-void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
-{
- const char *tmp;
- tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
- if (tmp) {
- ch->other_pid=atoi(tmp);
- chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp);
- if (ch->other_pid >0) {
- ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
- if (ch->other_ch) ch->other_ch->other_ch=ch;
- }
- }
-
- tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE");
- if (tmp && (atoi(tmp) == 1)) {
- bc->sending_complete=1;
- }
-
- tmp=pbx_builtin_getvar_helper(chan,"MISDN_USERUSER");
- if (tmp) {
- ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
- strcpy(bc->uu, tmp);
- bc->uulen=strlen(bc->uu);
- }
-
- tmp=pbx_builtin_getvar_helper(chan,"MISDN_KEYPAD");
- if (tmp) {
- strncpy(bc->keypad,tmp,sizeof(bc->keypad));
- bc->keypad[sizeof(bc->keypad)-1]=0;
- }
-
-
-}
-
-void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
-{
- char tmp[32];
- chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid);
- sprintf(tmp,"%d",bc->pid);
- pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
-
- if (bc->sending_complete) {
- sprintf(tmp,"%d",bc->sending_complete);
- pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp);
- }
-
- if (bc->urate) {
- sprintf(tmp,"%d",bc->urate);
- pbx_builtin_setvar_helper(chan,"MISDN_URATE",tmp);
- }
-
- if (bc->uulen && (bc->uulen < sizeof(bc->uu))) {
- bc->uu[bc->uulen]=0;
- pbx_builtin_setvar_helper(chan,"MISDN_USERUSER",bc->uu);
- }
-
- if (bc->keypad[0])
- pbx_builtin_setvar_helper(chan,"MISDN_KEYPAD",bc->keypad);
-}
-
-int add_in_calls(int port)
-{
- int max_in_calls;
-
- misdn_cfg_get( port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
- misdn_in_calls[port]++;
-
- if (max_in_calls >=0 && max_in_calls<misdn_in_calls[port]) {
- ast_log(LOG_NOTICE,"Marking Incoming Call on port[%d]\n",port);
- return misdn_in_calls[port]-max_in_calls;
- }
-
- return 0;
-}
-
-int add_out_calls(int port)
-{
- int max_out_calls;
-
- misdn_cfg_get( port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
-
-
- if (max_out_calls >=0 && max_out_calls<=misdn_out_calls[port]) {
- ast_log(LOG_NOTICE,"Rejecting Outgoing Call on port[%d]\n",port);
- return (misdn_out_calls[port]+1)-max_out_calls;
- }
-
- misdn_out_calls[port]++;
-
- return 0;
-}
-
-static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
- if (pbx_start_chan(ch)<0) {
- hangup_chan(ch);
- chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
- if (bc->nt) {
- hanguptone_indicate(ch);
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
- } else
- misdn_lib_send_event(bc, EVENT_RELEASE);
- }
-}
-
-static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
- ch->state=MISDN_WAITING4DIGS;
- misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- if (bc->nt && !bc->dad[0])
- dialtone_indicate(ch);
-}
-
-
-/************************************************************/
-/* Receive Events from isdn_lib here */
-/************************************************************/
-static enum event_response_e
-cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
-{
- int msn_valid;
- struct chan_list *ch=find_chan_by_bc(cl_te, bc);
-
- if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */
- int debuglevel=1;
- if ( event==EVENT_CLEANUP && !user_data)
- debuglevel=5;
-
- chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch?misdn_get_ch_state(ch):"none");
- if (debuglevel==1) {
- misdn_lib_log_ies(bc);
- chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
- }
- }
-
- if (!ch) {
- switch(event) {
- case EVENT_SETUP:
- case EVENT_DISCONNECT:
- case EVENT_PORT_ALARM:
- case EVENT_RETRIEVE:
- case EVENT_NEW_BC:
- case EVENT_FACILITY:
- break;
- case EVENT_RELEASE_COMPLETE:
- chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
- break;
- case EVENT_CLEANUP:
- case EVENT_TONE_GENERATE:
- case EVENT_BCHAN_DATA:
- return -1;
-
- default:
- chan_misdn_log(1,bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n",bc->l3_id, bc, manager_isdn_get_info( event), bc->port,bc->channel);
- return -1;
- }
- }
-
- if (ch ) {
- switch (event) {
- case EVENT_TONE_GENERATE:
- break;
- case EVENT_DISCONNECT:
- case EVENT_RELEASE:
- case EVENT_RELEASE_COMPLETE:
- case EVENT_CLEANUP:
- case EVENT_TIMEOUT:
- if (!ch->ast)
- chan_misdn_log(3,bc->port,"ast_hangup already called, so we have no ast ptr anymore in event(%s)\n",manager_isdn_get_info(event));
- break;
- default:
- if ( !ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
- if (event!=EVENT_BCHAN_DATA)
- ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
- return -1;
- }
- }
- }
-
-
- switch (event) {
- case EVENT_PORT_ALARM:
- {
- int boa=0;
- misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
- if (boa) {
- cb_log(1,bc->port," --> blocking\n");
- misdn_lib_port_block(bc->port);
- }
- }
- break;
- case EVENT_BCHAN_ACTIVATED:
- break;
-
- case EVENT_NEW_CHANNEL:
- update_name(ch->ast,bc->port,bc->channel);
- break;
-
- case EVENT_NEW_L3ID:
- ch->l3id=bc->l3_id;
- ch->addr=bc->addr;
- break;
-
- case EVENT_NEW_BC:
- if (!ch) {
- ch=find_holded(cl_te,bc);
- }
-
- if (!ch) {
- ast_log(LOG_WARNING,"NEW_BC without chan_list?\n");
- break;
- }
-
- if (bc)
- ch->bc=(struct misdn_bchannel*)user_data;
- break;
-
- case EVENT_DTMF_TONE:
- {
- /* sending INFOS as DTMF-Frames :) */
- struct ast_frame fr;
- memset(&fr, 0 , sizeof(fr));
- fr.frametype = AST_FRAME_DTMF;
- fr.subclass = bc->dtmf ;
- fr.src=NULL;
- fr.data = NULL ;
- fr.datalen = 0;
- fr.samples = 0 ;
- fr.mallocd =0 ;
- fr.offset= 0 ;
- fr.delivery= ast_tv(0,0) ;
-
- if (!ch->ignore_dtmf) {
- chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
- ast_queue_frame(ch->ast, &fr);
- } else {
- chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf);
- }
- }
- break;
- case EVENT_STATUS:
- break;
-
- case EVENT_INFORMATION:
- {
- int l;
-
- if ( ch->state != MISDN_CONNECTED )
- stop_indicate(ch);
-
- if (!ch->ast) break;
-
- if (ch->state == MISDN_WAITING4DIGS ) {
- /* Ok, incomplete Setup, waiting till extension exists */
- if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
- chan_misdn_log(1, bc->port, " --> using keypad as info\n");
- strcpy(bc->info_dad,bc->keypad);
- }
-
- l = sizeof(bc->dad);
- strncat(bc->dad,bc->info_dad, l - strlen(bc->dad) - 1);
-
- l = sizeof(ch->ast->exten);
- strncpy(ch->ast->exten, bc->dad, l);
- ch->ast->exten[l-1] = 0;
-
- /* Check for Pickup Request first */
- if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
- if (ast_pickup_call(ch->ast)) {
- hangup_chan(ch);
- } else {
- struct ast_channel *chan=ch->ast;
- ch->state = MISDN_CALLING_ACKNOWLEDGE;
- ast_setstate(chan, AST_STATE_DOWN);
- hangup_chan(ch);
- ch->ast=NULL;
- break;
- }
- }
-
- if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
- ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port);
- strcpy(ch->ast->exten, "i");
-
- ch->state = MISDN_DIALING;
- start_pbx(ch, bc, ch->ast);
- break;
- }
-
- ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)."
- "maybe you want to add an 'i' extension to catch this case.\n",
- bc->port);
-
- if (bc->nt)
- hanguptone_indicate(ch);
- ch->state=MISDN_EXTCANTMATCH;
- bc->out_cause=1;
-
- misdn_lib_send_event(bc, EVENT_DISCONNECT );
- break;
- }
-
- if (ch->overlap_dial) {
- ast_mutex_lock(&ch->overlap_tv_lock);
- ch->overlap_tv = ast_tvnow();
- ast_mutex_unlock(&ch->overlap_tv_lock);
- if (ch->overlap_dial_task == -1) {
- ch->overlap_dial_task =
- misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
- }
- break;
- }
-
- if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
-
- ch->state = MISDN_DIALING;
- start_pbx(ch, bc, ch->ast);
- }
- } else {
- /* sending INFOS as DTMF-Frames :) */
- int digits;
- struct ast_frame fr;
- memset(&fr, 0, sizeof(fr));
- fr.frametype = AST_FRAME_DTMF;
- fr.subclass = bc->info_dad[0] ;
- fr.src=NULL;
- fr.data = NULL ;
- fr.datalen = 0;
- fr.samples = 0 ;
- fr.mallocd =0 ;
- fr.offset= 0 ;
- fr.delivery= ast_tv(0,0) ;
-
- misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
- if (ch->state != MISDN_CONNECTED ) {
- if (digits) {
- int l = sizeof(bc->dad);
- strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1);
- l = sizeof(ch->ast->exten);
- strncpy(ch->ast->exten, bc->dad, l);
- ch->ast->exten[l-1] = 0;
-
- ast_cdr_update(ch->ast);
- }
-
- ast_queue_frame(ch->ast, &fr);
- }
- }
- }
- break;
- case EVENT_SETUP:
- {
- struct chan_list *ch=find_chan_by_bc(cl_te, bc);
- if (ch) {
- switch (ch->state) {
- case MISDN_NOTHING:
- ch=NULL;
- break;
- default:
- chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
- return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */
- }
- }
- }
-
- msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
- if (!bc->nt && ! msn_valid) {
- chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
- return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */
- }
-
-
- if (bc->cw) {
- int cause;
- chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
- misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
- bc->out_cause=cause?cause:16;
- return RESPONSE_RELEASE_SETUP;
- }
-
- print_bearer(bc);
-
- {
- struct chan_list *ch;
- struct ast_channel *chan;
- int exceed;
- int pres,screen;
- int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
- int ai, im;
- if (!bc->nt && ! msn_valid) {
- chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
- return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */
- }
-
- if (bc->cw) {
- int cause;
- chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
- misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
- bc->out_cause=cause?cause:16;
- return RESPONSE_RELEASE_SETUP;
- }
-
- print_bearer(bc);
-
- ch=init_chan_list(ORG_MISDN);
-
- if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
-
- ch->bc = bc;
- ch->l3id=bc->l3_id;
- ch->addr=bc->addr;
- ch->originator = ORG_MISDN;
-
- chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
-
- if (!chan) {
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
- return 0;
- }
-
- ch->ast = chan;
-
- if ((exceed=add_in_calls(bc->port))) {
- char tmp[16];
- sprintf(tmp,"%d",exceed);
- pbx_builtin_setvar_helper(chan,"MAX_OVERFLOW",tmp);
- }
-
- read_config(ch, ORG_MISDN);
-
- export_ch(chan, bc, ch);
-
- ch->ast->rings=1;
- ast_setstate(ch->ast, AST_STATE_RINGING);
-
- switch (bc->pres) {
- case 1:
- pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n");
- break;
- case 2:
- pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n");
- break;
- default:
- pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres);
- }
-
- switch (bc->screen) {
- case 0:
- screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n");
- break;
- case 1:
- screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n");
- break;
- case 2:
- screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n");
- break;
- case 3:
- screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n");
- break;
- default:
- screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen);
- }
-
- chan->cid.cid_pres=pres+screen;
-
- pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
- chan->transfercapability=bc->capability;
-
- switch (bc->capability) {
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
- pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
- break;
- default:
- pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
- }
-
- /** queue new chan **/
- cl_queue_chan(&cl_te, ch) ;
-
- if (!strstr(ch->allowed_bearers,"all")) {
- int i;
- for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) {
- if (allowed_bearers_array[i].cap == bc->capability) {
- if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) {
- chan_misdn_log(0,bc->port,"Bearer Not allowed\b");
- bc->out_cause=88;
-
- ch->state=MISDN_EXTCANTMATCH;
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
- return RESPONSE_OK;
- }
- }
-
- }
- }
-
- /* Check for Pickup Request first */
- if (!strcmp(chan->exten, ast_pickup_ext())) {
- if (!ch->noautorespond_on_setup) {
- int ret;/** Sending SETUP_ACK**/
- ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- } else {
- ch->state = MISDN_INCOMING_SETUP;
- }
- if (ast_pickup_call(chan)) {
- hangup_chan(ch);
- } else {
- ch->state = MISDN_CALLING_ACKNOWLEDGE;
- ast_setstate(chan, AST_STATE_DOWN);
- hangup_chan(ch);
- ch->ast=NULL;
- break;
- }
- }
-
- /*
- added support for s extension hope it will help those poor cretains
- which haven't overlap dial.
- */
- misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
- if ( ai ) {
- do_immediate_setup(bc, ch , chan);
- break;
- }
-
- /* check if we should jump into s when we have no dad */
- misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
- if ( im && ast_strlen_zero(bc->dad) ) {
- do_immediate_setup(bc, ch , chan);
- break;
- }
-
- chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context);
- if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
- ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port);
- strcpy(ch->ast->exten, "i");
- misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
- ch->state=MISDN_DIALING;
- start_pbx(ch, bc, chan);
- break;
- }
-
- ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)."
- "maybe you want to add an 'i' extension to catch this case.\n",
- bc->port);
- if (bc->nt)
- hanguptone_indicate(ch);
-
- ch->state=MISDN_EXTCANTMATCH;
- bc->out_cause=1;
-
- if (bc->nt)
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
- else
- misdn_lib_send_event(bc, EVENT_RELEASE );
-
- break;
- }
-
- /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely
- * jump into the dialplan, when the dialed extension does not exist, the 's' extension
- * will be used by Asterisk automatically. */
- if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
- if (!ch->noautorespond_on_setup) {
- ch->state=MISDN_DIALING;
- misdn_lib_send_event(bc, EVENT_PROCEEDING );
- } else {
- ch->state = MISDN_INCOMING_SETUP;
- }
- start_pbx(ch, bc, chan);
- break;
- }
-
-
- /*
- * When we are NT and overlapdial is set and if
- * the number is empty, we wait for the ISDN timeout
- * instead of our own timer.
- */
- if (ch->overlap_dial && bc->nt && !bc->dad[0] ) {
- wait_for_digits(ch, bc, chan);
- break;
- }
-
- /*
- * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more
- * Infos with a Interdigit Timeout.
- * */
- if (ch->overlap_dial) {
- ast_mutex_lock(&ch->overlap_tv_lock);
- ch->overlap_tv = ast_tvnow();
- ast_mutex_unlock(&ch->overlap_tv_lock);
-
- wait_for_digits(ch, bc, chan);
- if (ch->overlap_dial_task == -1)
- ch->overlap_dial_task =
- misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
-
- break;
- }
-
- /* If the extension does not exist and we're not TE_PTMP we wait for more digis
- * without interdigit timeout.
- * */
- if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- wait_for_digits(ch, bc, chan);
- break;
- }
-
- /*
- * If the extension exists let's just jump into it.
- * */
- if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- if (bc->need_more_infos)
- misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- else
- misdn_lib_send_event(bc, EVENT_PROCEEDING);
-
- ch->state=MISDN_DIALING;
- start_pbx(ch, bc, chan);
- break;
- }
- }
- break;
-
- case EVENT_SETUP_ACKNOWLEDGE:
- {
- ch->state = MISDN_CALLING_ACKNOWLEDGE;
-
- if (bc->channel)
- update_name(ch->ast,bc->port,bc->channel);
-
- if (!ast_strlen_zero(bc->infos_pending)) {
- /* TX Pending Infos */
-
- {
- int l = sizeof(bc->dad);
- strncat(bc->dad, bc->infos_pending, l - strlen(bc->dad) - 1);
- }
-
- if (!ch->ast) break;
- {
- int l = sizeof(ch->ast->exten);
- strncpy(ch->ast->exten, bc->dad, l);
- ch->ast->exten[l-1] = 0;
- }
- {
- int l = sizeof(bc->info_dad);
- strncpy(bc->info_dad, bc->infos_pending, l);
- bc->info_dad[l-1] = 0;
- }
- strncpy(bc->infos_pending,"", 1);
-
- misdn_lib_send_event(bc, EVENT_INFORMATION);
- }
- }
- break;
- case EVENT_PROCEEDING:
- {
- if (bc->channel)
- update_name(ch->ast,bc->port,bc->channel);
-
- if ( misdn_cap_is_speech(bc->capability) &&
- misdn_inband_avail(bc) ) {
- start_bc_tones(ch);
- }
-
- ch->state = MISDN_PROCEEDING;
-
- if (!ch->ast) break;
-
- ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
- }
- break;
- case EVENT_PROGRESS:
- if (bc->channel)
- update_name(ch->ast,bc->port,bc->channel);
-
- if (!bc->nt ) {
- if ( misdn_cap_is_speech(bc->capability) &&
- misdn_inband_avail(bc)
- ) {
- start_bc_tones(ch);
- }
-
- ch->state=MISDN_PROGRESS;
-
- if (!ch->ast) break;
- ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
- }
- break;
-
-
- case EVENT_ALERTING:
- {
- if (bc->channel)
- update_name(ch->ast,bc->port,bc->channel);
-
- ch->state = MISDN_ALERTING;
-
- if (!ch->ast) break;
-
- ast_queue_control(ch->ast, AST_CONTROL_RINGING);
- ast_setstate(ch->ast, AST_STATE_RINGING);
-
- cb_log(7,bc->port," --> Set State Ringing\n");
-
- if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
- cb_log(1,bc->port,"Starting Tones, we have inband Data\n");
- start_bc_tones(ch);
- } else {
- cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n");
- if (ch->far_alerting) {
- cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself..");
- start_bc_tones(ch);
- /*tone_indicate(ch, TONE_FAR_ALERTING);*/
- }
- }
- }
- break;
- case EVENT_CONNECT:
- {
- struct ast_channel *bridged;
- /*we answer when we've got our very new L3 ID from the NT stack */
- misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
-
- if (!ch->ast) break;
-
- bridged=ast_bridged_channel(ch->ast);
- stop_indicate(ch);
-
- if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) {
- struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
-
- chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad);
- if (bridged_ch) {
- bridged_ch->bc->cpnnumplan=bc->cpnnumplan;
- ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad));
- }
- }
- }
- ch->l3id=bc->l3_id;
- ch->addr=bc->addr;
-
- start_bc_tones(ch);
-
- ch->state = MISDN_CONNECTED;
-
- ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
- break;
- case EVENT_CONNECT_ACKNOWLEDGE:
- {
- ch->l3id=bc->l3_id;
- ch->addr=bc->addr;
-
- start_bc_tones(ch);
-
- ch->state = MISDN_CONNECTED;
- }
- break;
- case EVENT_DISCONNECT:
- /*we might not have an ch->ast ptr here anymore*/
- if (ch) {
- struct chan_list *holded_ch=find_holded(cl_te, bc);
-
- chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state);
- if ( ch->originator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
- /* If there's inband information available (e.g. a
- recorded message saying what was wrong with the
- dialled number, or perhaps even giving an
- alternative number, then play it instead of
- immediately releasing the call */
- chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n");
-
- ch->state=MISDN_DISCONNECTED;
- start_bc_tones(ch);
-
- if (ch->ast) {
- ch->ast->hangupcause=bc->cause;
- if (bc->cause == 17)
- ast_queue_control(ch->ast, AST_CONTROL_BUSY);
- }
- ch->need_busy=0;
- break;
- }
-
- /*Check for holded channel, to implement transfer*/
- if ( holded_ch &&
- holded_ch != ch &&
- ch->ast &&
- ch->state == MISDN_CONNECTED ) {
- cb_log(1,bc->port," --> found holded ch\n");
- misdn_transfer_bc(ch, holded_ch) ;
- }
-
- bc->need_disconnect=0;
-
- stop_bc_tones(ch);
- hangup_chan(ch);
- } else {
- /* ch=find_holded_l3(cl_te, bc->l3_id,1);
- if (ch) {
- hangup_chan(ch);
- }
- */
- }
- bc->out_cause=-1;
- if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE);
- break;
-
- case EVENT_RELEASE:
- {
- bc->need_disconnect=0;
- bc->need_release=0;
-
- hangup_chan(ch);
- release_chan(bc);
- }
- break;
- case EVENT_RELEASE_COMPLETE:
- {
- bc->need_disconnect=0;
- bc->need_release=0;
- bc->need_release_complete=0;
-
- stop_bc_tones(ch);
- hangup_chan(ch);
-
- if(ch)
- ch->state=MISDN_CLEANING;
-
- release_chan(bc);
- }
- break;
- case EVENT_BCHAN_ERROR:
- case EVENT_CLEANUP:
- {
- stop_bc_tones(ch);
-
- switch(ch->state) {
- case MISDN_CALLING:
- bc->cause=27; /* Destination out of order */
- break;
- default:
- break;
- }
-
- hangup_chan(ch);
- release_chan(bc);
- }
- break;
-
- case EVENT_TONE_GENERATE:
- {
- int tone_len=bc->tone_cnt;
- struct ast_channel *ast=ch->ast;
- void *tmp;
- int res;
- int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
-
- chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n");
-
- if (!ast) break;
-
- if (!ast->generator) break;
-
-
-
- tmp = ast->generatordata;
- ast->generatordata = NULL;
- generate = ast->generator->generate;
-
- if (tone_len <0 || tone_len > 512 ) {
- ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len);
- tone_len=128;
- }
-
- res = generate(ast, tmp, tone_len, tone_len);
- ast->generatordata = tmp;
-
- if (res) {
- ast_log(LOG_WARNING, "Auto-deactivating generator\n");
- ast_deactivate_generator(ast);
- } else {
- bc->tone_cnt=0;
- }
- }
- break;
-
- case EVENT_BCHAN_DATA:
- {
- if ( !misdn_cap_is_speech(ch->bc->capability) ) {
- struct ast_frame frame;
- /*In Data Modes we queue frames*/
- frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/
- frame.subclass = AST_FORMAT_ALAW;
- frame.datalen = bc->bframe_len;
- frame.samples = bc->bframe_len ;
- frame.mallocd =0 ;
- frame.offset= 0 ;
- frame.delivery= ast_tv(0,0) ;
- frame.src = NULL;
- frame.data = bc->bframe ;
-
- if (ch->ast)
- ast_queue_frame(ch->ast,&frame);
- } else {
- int t;
- fd_set wrfs;
- struct timeval tv;
- tv.tv_sec=0;
- tv.tv_usec=0;
-
-
- FD_ZERO(&wrfs);
- FD_SET(ch->pipe[1],&wrfs);
-
- t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv);
-
- if (!t) {
- chan_misdn_log(9, bc->port, "Select Timed out\n");
- break;
- }
-
- if (t<0) {
- chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno));
- break;
- }
-
- if (FD_ISSET(ch->pipe[1],&wrfs)) {
- int ret;
- chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len);
- ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
-
- if (ret<=0) {
- chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno));
-
- stop_bc_tones(ch);
- hangup_chan(ch);
- release_chan(bc);
- }
- } else {
- chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
- }
- }
- }
- break;
- case EVENT_TIMEOUT:
- {
- if (ch && bc)
- chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch));
-
- switch (ch->state) {
- case MISDN_DIALING:
- case MISDN_PROGRESS:
- if (bc->nt && !ch->nttimeout) break;
-
- case MISDN_CALLING:
- case MISDN_ALERTING:
- case MISDN_PROCEEDING:
- case MISDN_CALLING_ACKNOWLEDGE:
- if (bc->nt) {
- bc->progress_indicator=8;
- hanguptone_indicate(ch);
- }
-
- bc->out_cause=1;
- misdn_lib_send_event(bc,EVENT_DISCONNECT);
- break;
-
- case MISDN_WAITING4DIGS:
- if (bc->nt) {
- bc->progress_indicator=8;
- bc->out_cause=1;
- hanguptone_indicate(ch);
- misdn_lib_send_event(bc,EVENT_DISCONNECT);
- } else {
- bc->out_cause=16;
- misdn_lib_send_event(bc,EVENT_RELEASE);
- }
-
- break;
-
-
- case MISDN_CLEANING:
- chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n");
- break;
-
- default:
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- }
- }
- break;
-
-
- /***************************/
- /** Suplementary Services **/
- /***************************/
- case EVENT_RETRIEVE:
- {
- struct ast_channel *hold_ast;
- if (!ch) {
- chan_misdn_log(4, bc->port, " --> no CH, searching in holded\n");
- ch=find_holded_l3(cl_te, bc->l3_id,1);
- }
-
- if (!ch) {
- ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
- misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
- break;
- }
-
- /*remember the channel again*/
- ch->bc=bc;
- ch->state = MISDN_CONNECTED;
-
- ch->hold_info.port=0;
- ch->hold_info.channel=0;
-
- hold_ast=ast_bridged_channel(ch->ast);
-
- if (hold_ast) {
- ast_moh_stop(hold_ast);
- }
-
- if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) {
- chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
- misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
- }
- }
- break;
-
- case EVENT_HOLD:
- {
- int hold_allowed;
- struct ast_channel *bridged;
- misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
-
- if (!hold_allowed) {
-
- chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
- misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
- break;
- }
-
- bridged=ast_bridged_channel(ch->ast);
-
- if (bridged) {
- chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type);
- ch->state = MISDN_HOLDED;
- ch->l3id = bc->l3_id;
-
- misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
-
- /* XXX This should queue an AST_CONTROL_HOLD frame on this channel
- * instead of starting moh on the bridged channel directly */
- ast_moh_start(bridged, NULL, NULL);
-
- /*forget the channel now*/
- ch->bc=NULL;
- ch->hold_info.port=bc->port;
- ch->hold_info.channel=bc->channel;
-
- } else {
- misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
- chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
- }
- }
- break;
-
- case EVENT_FACILITY:
- if (!ch) {
- /* This may come from a call we don't know nothing about, so we ignore it. */
- chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n");
- break;
- }
-
- print_facility(&(bc->fac_in), bc);
-
- switch (bc->fac_in.Function) {
- case Fac_CD:
- {
- struct ast_channel *bridged=ast_bridged_channel(ch->ast);
- struct chan_list *ch_br;
- if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
- ch_br=MISDN_ASTERISK_TECH_PVT(bridged);
- /*ch->state=MISDN_FACILITY_DEFLECTED;*/
- if (ch_br->bc) {
- if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) {
- ch_br->state=MISDN_DIALING;
- if (pbx_start_chan(ch_br) < 0) {
- chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
- }
- }
- }
-
- }
- misdn_lib_send_event(bc, EVENT_DISCONNECT);
- }
- break;
- case Fac_AOCDCurrency:
- bc->AOCDtype = Fac_AOCDCurrency;
- memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency));
- export_aoc_vars(ch->originator, ch->ast, bc);
- break;
- case Fac_AOCDChargingUnit:
- bc->AOCDtype = Fac_AOCDChargingUnit;
- memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit));
- export_aoc_vars(ch->originator, ch->ast, bc);
- break;
- default:
- chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_in.Function);
- }
-
- break;
-
- case EVENT_RESTART:
-
- if (!bc->dummy) {
- stop_bc_tones(ch);
- release_chan(bc);
- }
-
- break;
-
- default:
- chan_misdn_log(1,0, "Got Unknown Event\n");
- break;
- }
-
- return RESPONSE_OK;
-}
-
-/** TE STUFF END **/
-
-/******************************************
- *
- * Asterisk Channel Endpoint END
- *
- *
- *******************************************/
-
-
-
-static int unload_module(void)
-{
- /* First, take us out of the channel loop */
- ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
-
- misdn_tasks_destroy();
-
- if (!g_config_initialized) return 0;
-
- ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
-
- /* ast_unregister_application("misdn_crypt"); */
- ast_unregister_application("misdn_set_opt");
- ast_unregister_application("misdn_facility");
- ast_unregister_application("misdn_check_l2l1");
-
- ast_channel_unregister(&misdn_tech);
-
-
- free_robin_list();
- misdn_cfg_destroy();
- misdn_lib_destroy();
-
- if (misdn_debug)
- free(misdn_debug);
- if (misdn_debug_only)
- free(misdn_debug_only);
- free(misdn_ports);
-
- return 0;
-}
-
-static int load_module(void)
-{
- int i, port;
-
- char ports[256]="";
-
- max_ports=misdn_lib_maxports_get();
-
- if (max_ports<=0) {
- ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- if (misdn_cfg_init(max_ports)) {
- ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
- return AST_MODULE_LOAD_DECLINE;
- }
- g_config_initialized=1;
-
- misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
- misdn_ports = (int *)malloc(sizeof(int) * (max_ports+1));
- misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
- for (i = 1; i <= max_ports; i++) {
- misdn_debug[i] = misdn_debug[0];
- misdn_ports[i] = i;
- }
- *misdn_ports = 0;
- misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int));
-
- {
- char tempbuf[BUFFERSIZE+1];
- misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
- if (strlen(tempbuf))
- tracing = 1;
- }
-
- misdn_in_calls = (int *)malloc(sizeof(int) * (max_ports+1));
- misdn_out_calls = (int *)malloc(sizeof(int) * (max_ports+1));
-
- for (i=1; i <= max_ports; i++) {
- misdn_in_calls[i]=0;
- misdn_out_calls[i]=0;
- }
-
- ast_mutex_init(&cl_te_lock);
- ast_mutex_init(&release_lock);
-
- misdn_cfg_update_ptp();
- misdn_cfg_get_ports_string(ports);
-
- if (strlen(ports))
- chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
-
- {
- int ntflags=0, ntkc=0;
- char ntfile[BUFFERSIZE+1];
- struct misdn_lib_iface iface = {
- .cb_event = cb_events,
- .cb_log = chan_misdn_log,
- .cb_jb_empty = chan_misdn_jb_empty,
- };
-
- if (misdn_lib_init(ports, &iface, NULL))
- chan_misdn_log(0, 0, "No te ports initialized\n");
-
- misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
- misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
- misdn_lib_nt_debug_init(ntflags,ntfile);
-
- misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(int));
- misdn_lib_nt_keepcalls(ntkc);
- }
-
- {
- if (ast_channel_register(&misdn_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
- unload_module();
- return -1;
- }
- }
-
- ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
-
- ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
- "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
- "Sets mISDN opts. and optargs\n"
- "\n"
- "The available options are:\n"
- " d - Send display text on called phone, text is the optparam\n"
- " n - don't detect dtmf tones on called channel\n"
- " h - make digital outgoing call\n"
- " c - make crypted outgoing call, param is keyindex\n"
- " e - perform echo cancelation on this channel,\n"
- " takes taps as arguments (32,64,128,256)\n"
- " s - send Non Inband DTMF as inband\n"
- " vr - rxgain control\n"
- " vt - txgain control\n"
- " i - Ignore detected dtmf tones, don't signal them to asterisk, they will be transported inband.\n"
- );
-
-
- ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
- "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
- "Sends the Facility Message FACILITY_TYPE with \n"
- "the given Arguments to the current ISDN Channel\n"
- "Supported Facilities are:\n"
- "\n"
- "type=calldeflect args=Nr where to deflect\n"
- );
-
-
- ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
- "misdn_check_l2l1(<port>||g:<groupname>,timeout)"
- "Checks if the L2 and L1 are up on either the given <port> or\n"
- "on the ports in the group with <groupname>\n"
- "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
- "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
- "\n"
- "This application, ensures the L1/L2 state of the Ports in a group\n"
- "it is intended to make the pmp_l1_check option redundant and to\n"
- "fix a buggy switch config from your provider\n"
- "\n"
- "a sample dialplan would look like:\n\n"
- "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
- "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
- "\n"
- );
-
-
- misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
-
- /* start the l1 watchers */
-
- for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
- int l1timeout;
- misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
- if (l1timeout) {
- chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
- misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]);
- }
- }
-
- chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n");
-
- return 0;
-}
-
-
-
-static int reload(void)
-{
- reload_config();
-
- return 0;
-}
-
-/*** SOME APPS ;)***/
-
-static int misdn_facility_exec(struct ast_channel *chan, void *data)
-{
- struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
- char *tok, *tokb;
-
- chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type);
-
- if (strcasecmp(chan->tech->type,"mISDN")) {
- ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
- return -1;
- }
-
- if (ast_strlen_zero((char *)data)) {
- ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
- return -1;
- }
-
- tok=strtok_r((char*)data,"|", &tokb) ;
-
- if (!tok) {
- ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
- return -1;
- }
-
- if (!strcasecmp(tok,"calldeflect")) {
- tok=strtok_r(NULL,"|", &tokb) ;
-
- if (!tok) {
- ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
- }
-
- if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) {
- ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n");
- return 0;
- }
- ch->bc->fac_out.Function = Fac_CD;
- strncpy((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber));
- misdn_lib_send_event(ch->bc, EVENT_FACILITY);
- } else {
- chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok);
- }
-
- return 0;
-
-}
-
-static int misdn_check_l2l1(struct ast_channel *chan, void *data)
-{
- char group[BUFFERSIZE+1];
- char *port_str;
- int port_up;
- int timeout;
- int dowait=0;
- int port=0;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(grouppar);
- AST_APP_ARG(timeout);
- );
-
- if (ast_strlen_zero((char *)data)) {
- ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, data);
-
- if (args.argc != 2) {
- ast_log(LOG_WARNING, "Wrong argument count\n");
- return 0;
- }
-
- /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/
- timeout=atoi(args.timeout);
- port_str=args.grouppar;
- if (port_str[0]=='g' && port_str[1]==':' ) {
- /* We make a group call lets checkout which ports are in my group */
- port_str += 2;
- strncpy(group, port_str, BUFFERSIZE);
- group[BUFFERSIZE-1] = 0;
- chan_misdn_log(2, 0, "Checking Ports in group: %s\n",group);
-
- for ( port = misdn_cfg_get_next_port(port);
- port > 0;
- port = misdn_cfg_get_next_port(port))
- {
- char cfg_group[BUFFERSIZE+1];
-
- chan_misdn_log(2,0,"trying port %d\n",port);
-
- misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
-
- if (!strcasecmp(cfg_group, group)) {
- port_up = misdn_lib_port_up(port, 1);
-
- if (!port_up) {
- chan_misdn_log(2, 0, " --> port '%d'\n", port);
- misdn_lib_get_port_up(port);
- dowait=1;
- }
- }
- }
-
- } else {
- port = atoi(port_str);
- chan_misdn_log(2, 0, "Checking Port: %d\n",port);
- port_up = misdn_lib_port_up(port, 1);
- if (!port_up) {
- misdn_lib_get_port_up(port);
- dowait=1;
- }
-
- }
-
- if (dowait) {
- chan_misdn_log(2, 0, "Waiting for '%d' seconds\n",timeout);
- sleep(timeout);
- }
-
- return 0;
-}
-
-static int misdn_set_opt_exec(struct ast_channel *chan, void *data)
-{
- struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
- char *tok,*tokb;
- int keyidx=0;
- int rxgain=0;
- int txgain=0;
- int change_jitter=0;
-
- if (strcasecmp(chan->tech->type,"mISDN")) {
- ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
- return -1;
- }
-
- if (ast_strlen_zero((char *)data)) {
- ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
- return -1;
- }
-
- for (tok=strtok_r((char*)data, ":",&tokb);
- tok;
- tok=strtok_r(NULL,":",&tokb) ) {
- char keys[4096];
- char *key, *tmp;
- int i;
- int neglect=0;
-
- if (tok[0] == '!' ) {
- neglect=1;
- tok++;
- }
-
- switch(tok[0]) {
-
- case 'd' :
- ast_copy_string(ch->bc->display,++tok,84);
- chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display);
- break;
-
- case 'n':
- chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
- ch->bc->nodsp=1;
- break;
-
- case 'j':
- chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
- tok++;
- change_jitter=1;
-
- switch ( tok[0] ) {
- case 'b' :
- ch->jb_len=atoi(++tok);
- chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len);
- break;
- case 't' :
- ch->jb_upper_threshold=atoi(++tok);
- chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold);
- break;
-
- case 'n':
- ch->bc->nojitter=1;
- chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
- break;
-
- default:
- ch->jb_len=4000;
- ch->jb_upper_threshold=0;
- chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len);
- chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold);
- }
-
- break;
-
- case 'v':
- tok++;
-
- switch ( tok[0] ) {
- case 'r' :
- rxgain=atoi(++tok);
- if (rxgain<-8) rxgain=-8;
- if (rxgain>8) rxgain=8;
- ch->bc->rxgain=rxgain;
- chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain);
- break;
- case 't':
- txgain=atoi(++tok);
- if (txgain<-8) txgain=-8;
- if (txgain>8) txgain=8;
- ch->bc->txgain=txgain;
- chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain);
- break;
- }
- break;
-
- case 'c':
- keyidx=atoi(++tok);
- key=NULL;
- misdn_cfg_get( 0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
-
- tmp=keys;
-
- for (i=0; i<keyidx; i++) {
- key=strsep(&tmp,",");
- }
-
- if (key) {
- ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
- }
-
- chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",ch->bc->crypt_key);
- break;
-
- case 'e':
- chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
-
- if (neglect) {
- chan_misdn_log(1, ch->bc->port, " --> disabled\n");
-#ifdef MISDN_1_2
- *ch->bc->pipeline=0;
-#else
- ch->bc->ec_enable=0;
-#endif
- } else {
-#ifdef MISDN_1_2
- update_pipeline_config(ch->bc);
-#else
- ch->bc->ec_enable=1;
- ch->bc->orig=ch->originator;
- tok++;
- if (*tok) {
- ch->bc->ec_deftaps=atoi(tok);
- }
-#endif
- }
-
- break;
-
- case 'h':
- chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
-
- if (strlen(tok) > 1 && tok[1]=='1') {
- chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
- if (!ch->bc->hdlc) {
- ch->bc->hdlc=1;
- }
- }
- ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
- break;
-
- case 's':
- chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
- ch->bc->send_dtmf=1;
- break;
-
- case 'f':
- chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
- ch->faxdetect=1;
- misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
- break;
-
- case 'a':
- chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
- ch->ast_dsp=1;
- break;
-
- case 'p':
- chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]);
- /* CRICH: callingpres!!! */
- if (strstr(tok,"allowed") ) {
- ch->bc->pres=0;
- } else if (strstr(tok,"not_screened")) {
- ch->bc->pres=1;
- }
- break;
- case 'i' :
- chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
- ch->ignore_dtmf=1;
- break;
- default:
- break;
- }
- }
-
- if (change_jitter)
- config_jitterbuffer(ch);
-
-
- if (ch->faxdetect || ch->ast_dsp) {
- if (!ch->dsp) ch->dsp = ast_dsp_new();
- if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
- if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
- }
-
- if (ch->ast_dsp) {
- chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
- ch->bc->nodsp=1;
- ch->bc->nojitter=1;
- }
-
- return 0;
-}
-
-
-int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len)
-{
- struct chan_list *ch=find_chan_by_bc(cl_te, bc);
-
- if (ch && ch->jb) {
- return misdn_jb_empty(ch->jb, buf, len);
- }
-
- return -1;
-}
-
-
-
-/*******************************************************/
-/***************** JITTERBUFFER ************************/
-/*******************************************************/
-
-
-/* allocates the jb-structure and initialise the elements*/
-struct misdn_jb *misdn_jb_init(int size, int upper_threshold)
-{
- int i;
- struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb));
- jb->size = size;
- jb->upper_threshold = upper_threshold;
- jb->wp = 0;
- jb->rp = 0;
- jb->state_full = 0;
- jb->state_empty = 0;
- jb->bytes_wrote = 0;
- jb->samples = (char *)malloc(size*sizeof(char));
-
- if (!jb->samples) {
- chan_misdn_log(-1,0,"No free Mem for jb->samples\n");
- return NULL;
- }
-
- jb->ok = (char *)malloc(size*sizeof(char));
-
- if (!jb->ok) {
- chan_misdn_log(-1,0,"No free Mem for jb->ok\n");
- return NULL;
- }
-
- for(i=0; i<size; i++)
- jb->ok[i]=0;
-
- ast_mutex_init(&jb->mutexjb);
-
- return jb;
-}
-
-/* frees the data and destroys the given jitterbuffer struct */
-void misdn_jb_destroy(struct misdn_jb *jb)
-{
- ast_mutex_destroy(&jb->mutexjb);
-
- free(jb->samples);
- free(jb);
-}
-
-/* fills the jitterbuffer with len data returns < 0 if there was an
- error (bufferoverflow). */
-int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
-{
- int i, j, rp, wp;
-
- if (!jb || ! data) return 0;
-
- ast_mutex_lock (&jb->mutexjb);
-
- wp=jb->wp;
- rp=jb->rp;
-
- for(i=0; i<len; i++)
- {
- jb->samples[wp]=data[i];
- jb->ok[wp]=1;
- wp = (wp!=jb->size-1 ? wp+1 : 0);
-
- if(wp==jb->rp)
- jb->state_full=1;
- }
-
- if(wp>=rp)
- jb->state_buffer=wp-rp;
- else
- jb->state_buffer= jb->size-rp+wp;
- chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
-
- if(jb->state_full)
- {
- jb->wp=wp;
-
- rp=wp;
- for(j=0; j<jb->upper_threshold; j++)
- rp = (rp!=0 ? rp-1 : jb->size-1);
- jb->rp=rp;
- jb->state_full=0;
- jb->state_empty=1;
-
- ast_mutex_unlock (&jb->mutexjb);
-
- return -1;
- }
-
- if(!jb->state_empty)
- {
- jb->bytes_wrote+=len;
- if(jb->bytes_wrote>=jb->upper_threshold)
- {
- jb->state_empty=1;
- jb->bytes_wrote=0;
- }
- }
- jb->wp=wp;
-
- ast_mutex_unlock (&jb->mutexjb);
-
- return 0;
-}
-
-/* gets len bytes out of the jitterbuffer if available, else only the
-available data is returned and the return value indicates the number
-of data. */
-int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
-{
- int i, wp, rp, read=0;
-
- ast_mutex_lock (&jb->mutexjb);
-
- rp=jb->rp;
- wp=jb->wp;
-
- if(jb->state_empty)
- {
- for(i=0; i<len; i++)
- {
- if(wp==rp)
- {
- jb->rp=rp;
- jb->state_empty=0;
-
- ast_mutex_unlock (&jb->mutexjb);
-
- return read;
- }
- else
- {
- if(jb->ok[rp]==1)
- {
- data[i]=jb->samples[rp];
- jb->ok[rp]=0;
- rp=(rp!=jb->size-1 ? rp+1 : 0);
- read+=1;
- }
- }
- }
-
- if(wp >= rp)
- jb->state_buffer=wp-rp;
- else
- jb->state_buffer= jb->size-rp+wp;
- chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
-
- jb->rp=rp;
- }
- else
- chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb);
-
- ast_mutex_unlock (&jb->mutexjb);
-
- return read;
-}
-
-
-
-
-/*******************************************************/
-/*************** JITTERBUFFER END *********************/
-/*******************************************************/
-
-
-
-
-void chan_misdn_log(int level, int port, char *tmpl, ...)
-{
- va_list ap;
- char buf[1024];
- char port_buf[8];
-
- if (! ((0 <= port) && (port <= max_ports))) {
- ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
- port=0;
- level=-1;
- }
-
- sprintf(port_buf,"P[%2d] ",port);
-
- va_start(ap, tmpl);
- vsnprintf( buf, 1023, tmpl, ap );
- va_end(ap);
-
- if (level == -1)
- ast_log(LOG_WARNING, buf);
-
- else if (misdn_debug_only[port] ?
- (level==1 && misdn_debug[port]) || (level==misdn_debug[port])
- : level <= misdn_debug[port]) {
-
- ast_console_puts(port_buf);
- ast_console_puts(buf);
- }
-
- if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
- time_t tm = time(NULL);
- char *tmp=ctime(&tm),*p;
-
- FILE *fp= fopen(global_tracefile, "a+");
-
- p=strchr(tmp,'\n');
- if (p) *p=':';
-
- if (!fp) {
- ast_console_puts("Error opening Tracefile: [ ");
- ast_console_puts(global_tracefile);
- ast_console_puts(" ] ");
-
- ast_console_puts(strerror(errno));
- ast_console_puts("\n");
- return ;
- }
-
- fputs(tmp,fp);
- fputs(" ", fp);
- fputs(port_buf,fp);
- fputs(" ", fp);
- fputs(buf, fp);
-
- fclose(fp);
- }
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for mISDN Support (BRI/PRI)",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/chan_nbs.c b/1.4/channels/chan_nbs.c
deleted file mode 100644
index b231127ce..000000000
--- a/1.4/channels/chan_nbs.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Network broadcast sound support channel driver
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>nbs</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <nbs.h>
-
-#include "asterisk/lock.h"
-#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"
-
-static const char tdesc[] = "Network Broadcast Sound Driver";
-
-/* Only linear is allowed */
-static int prefformat = AST_FORMAT_SLINEAR;
-
-static char context[AST_MAX_EXTENSION] = "default";
-static char type[] = "NBS";
-
-/* NBS creates private structures on demand */
-
-struct nbs_pvt {
- NBS *nbs;
- struct ast_channel *owner; /* Channel we belong to, possibly NULL */
- char app[16]; /* Our app */
- char stream[80]; /* Our stream */
- struct ast_frame fr; /* "null" frame */
- struct ast_module_user *u; /*! for holding a reference to this module */
-};
-
-static struct ast_channel *nbs_request(const char *type, int format, void *data, int *cause);
-static int nbs_call(struct ast_channel *ast, char *dest, int timeout);
-static int nbs_hangup(struct ast_channel *ast);
-static struct ast_frame *nbs_xread(struct ast_channel *ast);
-static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame);
-
-static const struct ast_channel_tech nbs_tech = {
- .type = type,
- .description = tdesc,
- .capabilities = AST_FORMAT_SLINEAR,
- .requester = nbs_request,
- .call = nbs_call,
- .hangup = nbs_hangup,
- .read = nbs_xread,
- .write = nbs_xwrite,
-};
-
-static int nbs_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct nbs_pvt *p;
-
- p = ast->tech_pvt;
-
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "nbs_call called on %s, neither down nor reserved\n", ast->name);
- return -1;
- }
- /* When we call, it just works, really, there's no destination... Just
- ring the phone and wait for someone to answer */
- if (option_debug)
- ast_log(LOG_DEBUG, "Calling %s on %s\n", dest, ast->name);
-
- /* If we can't connect, return congestion */
- if (nbs_connect(p->nbs)) {
- ast_log(LOG_WARNING, "NBS Connection failed on %s\n", ast->name);
- ast_queue_control(ast, AST_CONTROL_CONGESTION);
- } else {
- ast_setstate(ast, AST_STATE_RINGING);
- ast_queue_control(ast, AST_CONTROL_ANSWER);
- }
-
- return 0;
-}
-
-static void nbs_destroy(struct nbs_pvt *p)
-{
- if (p->nbs)
- nbs_delstream(p->nbs);
- ast_module_user_remove(p->u);
- free(p);
-}
-
-static struct nbs_pvt *nbs_alloc(void *data)
-{
- struct nbs_pvt *p;
- int flags = 0;
- char stream[256];
- char *opts;
-
- ast_copy_string(stream, data, sizeof(stream));
- if ((opts = strchr(stream, ':'))) {
- *opts = '\0';
- opts++;
- } else
- opts = "";
- p = malloc(sizeof(struct nbs_pvt));
- if (p) {
- memset(p, 0, sizeof(struct nbs_pvt));
- if (!ast_strlen_zero(opts)) {
- if (strchr(opts, 'm'))
- flags |= NBS_FLAG_MUTE;
- if (strchr(opts, 'o'))
- flags |= NBS_FLAG_OVERSPEAK;
- if (strchr(opts, 'e'))
- flags |= NBS_FLAG_EMERGENCY;
- if (strchr(opts, 'O'))
- flags |= NBS_FLAG_OVERRIDE;
- } else
- flags = NBS_FLAG_OVERSPEAK;
-
- ast_copy_string(p->stream, stream, sizeof(p->stream));
- p->nbs = nbs_newstream("asterisk", stream, flags);
- if (!p->nbs) {
- ast_log(LOG_WARNING, "Unable to allocate new NBS stream '%s' with flags %d\n", stream, flags);
- free(p);
- p = NULL;
- } else {
- /* Set for 8000 hz mono, 640 samples */
- nbs_setbitrate(p->nbs, 8000);
- nbs_setchannels(p->nbs, 1);
- nbs_setblocksize(p->nbs, 640);
- nbs_setblocking(p->nbs, 0);
- }
- }
- return p;
-}
-
-static int nbs_hangup(struct ast_channel *ast)
-{
- struct nbs_pvt *p;
- p = ast->tech_pvt;
- if (option_debug)
- ast_log(LOG_DEBUG, "nbs_hangup(%s)\n", ast->name);
- if (!ast->tech_pvt) {
- ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
- return 0;
- }
- nbs_destroy(p);
- ast->tech_pvt = NULL;
- ast_setstate(ast, AST_STATE_DOWN);
- return 0;
-}
-
-static struct ast_frame *nbs_xread(struct ast_channel *ast)
-{
- struct nbs_pvt *p = ast->tech_pvt;
-
-
- /* Some nice norms */
- p->fr.datalen = 0;
- p->fr.samples = 0;
- p->fr.data = NULL;
- p->fr.src = type;
- p->fr.offset = 0;
- p->fr.mallocd=0;
- p->fr.delivery.tv_sec = 0;
- p->fr.delivery.tv_usec = 0;
-
- ast_log(LOG_DEBUG, "Returning null frame on %s\n", ast->name);
-
- return &p->fr;
-}
-
-static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct nbs_pvt *p = ast->tech_pvt;
- /* Write a frame of (presumably voice) data */
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype != AST_FRAME_IMAGE)
- ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
- return 0;
- }
- if (!(frame->subclass &
- (AST_FORMAT_SLINEAR))) {
- ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
- return 0;
- }
- if (ast->_state != AST_STATE_UP) {
- /* Don't try tos end audio on-hook */
- return 0;
- }
- if (nbs_write(p->nbs, frame->data, frame->datalen / 2) < 0)
- return -1;
- return 0;
-}
-
-static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
-{
- struct ast_channel *tmp;
- tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, 0, "NBS/%s", i->stream);
- if (tmp) {
- tmp->tech = &nbs_tech;
- tmp->fds[0] = nbs_fd(i->nbs);
- tmp->nativeformats = prefformat;
- tmp->rawreadformat = prefformat;
- tmp->rawwriteformat = prefformat;
- tmp->writeformat = prefformat;
- tmp->readformat = prefformat;
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->tech_pvt = i;
- ast_copy_string(tmp->context, context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, "s", sizeof(tmp->exten));
- ast_string_field_set(tmp, language, "");
- i->owner = tmp;
- i->u = ast_module_user_add(tmp);
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- }
- }
- } else
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- return tmp;
-}
-
-
-static struct ast_channel *nbs_request(const char *type, int format, void *data, int *cause)
-{
- int oldformat;
- struct nbs_pvt *p;
- struct ast_channel *tmp = NULL;
-
- oldformat = format;
- format &= (AST_FORMAT_SLINEAR);
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
- return NULL;
- }
- p = nbs_alloc(data);
- if (p) {
- tmp = nbs_new(p, AST_STATE_DOWN);
- if (!tmp)
- nbs_destroy(p);
- }
- return tmp;
-}
-
-static int unload_module(void)
-{
- /* First, take us out of the channel loop */
- ast_channel_unregister(&nbs_tech);
- return 0;
-}
-
-static int load_module(void)
-{
- /* Make sure we can register our channel type */
- if (ast_channel_register(&nbs_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
- return -1;
- }
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Network Broadcast Sound Support");
diff --git a/1.4/channels/chan_oss.c b/1.4/channels/chan_oss.c
deleted file mode 100644
index 7e27e7696..000000000
--- a/1.4/channels/chan_oss.c
+++ /dev/null
@@ -1,1887 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * FreeBSD changes and multiple device support by Luigi Rizzo, 2005.05.25
- * note-this code best seen with ts=8 (8-spaces tabs) in the editor
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Channel driver for OSS sound cards
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Luigi Rizzo
- *
- * \par See also
- * \arg \ref Config_oss
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>ossaudio</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#ifdef __linux
-#include <linux/soundcard.h>
-#elif defined(__FreeBSD__)
-#include <sys/soundcard.h>
-#else
-#include <soundcard.h>
-#endif
-
-#include "asterisk/lock.h"
-#include "asterisk/frame.h"
-#include "asterisk/logger.h"
-#include "asterisk/callerid.h"
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/endian.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/musiconhold.h"
-
-/* ringtones we use */
-#include "busy.h"
-#include "ringtone.h"
-#include "ring10.h"
-#include "answer.h"
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = "",
-};
-static struct ast_jb_conf global_jbconf;
-
-/*
- * Basic mode of operation:
- *
- * we have one keyboard (which receives commands from the keyboard)
- * and multiple headset's connected to audio cards.
- * Cards/Headsets are named as the sections of oss.conf.
- * The section called [general] contains the default parameters.
- *
- * At any time, the keyboard is attached to one card, and you
- * can switch among them using the command 'console foo'
- * where 'foo' is the name of the card you want.
- *
- * oss.conf parameters are
-START_CONFIG
-
-[general]
- ; General config options, with default values shown.
- ; You should use one section per device, with [general] being used
- ; for the first device and also as a template for other devices.
- ;
- ; All but 'debug' can go also in the device-specific sections.
- ;
- ; debug = 0x0 ; misc debug flags, default is 0
-
- ; Set the device to use for I/O
- ; device = /dev/dsp
-
- ; Optional mixer command to run upon startup (e.g. to set
- ; volume levels, mutes, etc.
- ; mixer =
-
- ; Software mic volume booster (or attenuator), useful for sound
- ; cards or microphones with poor sensitivity. The volume level
- ; is in dB, ranging from -20.0 to +20.0
- ; boost = n ; mic volume boost in dB
-
- ; Set the callerid for outgoing calls
- ; callerid = John Doe <555-1234>
-
- ; autoanswer = no ; no autoanswer on call
- ; autohangup = yes ; hangup when other party closes
- ; extension = s ; default extension to call
- ; context = default ; default context for outgoing calls
- ; language = "" ; default language
-
- ; Default Music on Hold class to use when this channel is placed on hold in
- ; the case that the music class is not set on the channel with
- ; Set(CHANNEL(musicclass)=whatever) in the dialplan and the peer channel
- ; putting this one on hold did not suggest a class to use.
- ;
- ; mohinterpret=default
-
- ; If you set overridecontext to 'yes', then the whole dial string
- ; will be interpreted as an extension, which is extremely useful
- ; to dial SIP, IAX and other extensions which use the '@' character.
- ; The default is 'no' just for backward compatibility, but the
- ; suggestion is to change it.
- ; overridecontext = no ; if 'no', the last @ will start the context
- ; if 'yes' the whole string is an extension.
-
- ; low level device parameters in case you have problems with the
- ; device driver on your operating system. You should not touch these
- ; unless you know what you are doing.
- ; queuesize = 10 ; frames in device driver
- ; frags = 8 ; argument to SETFRAGMENT
-
- ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
- ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
- ; OSS channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The OSS channel can't accept jitter,
- ; thus an enabled jitterbuffer on the receive OSS side will always
- ; be used if the sending side can create jitter.
-
- ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
- ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usualy sent from exotic devices
- ; and programs. Defaults to 1000.
-
- ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an OSS
- ; channel. Two implementations are currenlty available - "fixed"
- ; (with size always equals to jbmax-size) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
- ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
- ;-----------------------------------------------------------------------------------
-
-[card1]
- ; device = /dev/dsp1 ; alternate device
-
-END_CONFIG
-
-.. and so on for the other cards.
-
- */
-
-/*
- * Helper macros to parse config arguments. They will go in a common
- * header file if their usage is globally accepted. In the meantime,
- * we define them here. Typical usage is as below.
- * Remember to open a block right before M_START (as it declares
- * some variables) and use the M_* macros WITHOUT A SEMICOLON:
- *
- * {
- * M_START(v->name, v->value)
- *
- * M_BOOL("dothis", x->flag1)
- * M_STR("name", x->somestring)
- * M_F("bar", some_c_code)
- * M_END(some_final_statement)
- * ... other code in the block
- * }
- *
- * XXX NOTE these macros should NOT be replicated in other parts of asterisk.
- * Likely we will come up with a better way of doing config file parsing.
- */
-#define M_START(var, val) \
- char *__s = var; char *__val = val;
-#define M_END(x) x;
-#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
-#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
-#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
-#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
-
-/*
- * The following parameters are used in the driver:
- *
- * FRAME_SIZE the size of an audio frame, in samples.
- * 160 is used almost universally, so you should not change it.
- *
- * FRAGS the argument for the SETFRAGMENT ioctl.
- * Overridden by the 'frags' parameter in oss.conf
- *
- * Bits 0-7 are the base-2 log of the device's block size,
- * bits 16-31 are the number of blocks in the driver's queue.
- * There are a lot of differences in the way this parameter
- * is supported by different drivers, so you may need to
- * experiment a bit with the value.
- * A good default for linux is 30 blocks of 64 bytes, which
- * results in 6 frames of 320 bytes (160 samples).
- * FreeBSD works decently with blocks of 256 or 512 bytes,
- * leaving the number unspecified.
- * Note that this only refers to the device buffer size,
- * this module will then try to keep the lenght of audio
- * buffered within small constraints.
- *
- * QUEUE_SIZE The max number of blocks actually allowed in the device
- * driver's buffer, irrespective of the available number.
- * Overridden by the 'queuesize' parameter in oss.conf
- *
- * Should be >=2, and at most as large as the hw queue above
- * (otherwise it will never be full).
- */
-
-#define FRAME_SIZE 160
-#define QUEUE_SIZE 10
-
-#if defined(__FreeBSD__)
-#define FRAGS 0x8
-#else
-#define FRAGS ( ( (6 * 5) << 16 ) | 0x6 )
-#endif
-
-/*
- * XXX text message sizes are probably 256 chars, but i am
- * not sure if there is a suitable definition anywhere.
- */
-#define TEXT_SIZE 256
-
-#if 0
-#define TRYOPEN 1 /* try to open on startup */
-#endif
-#define O_CLOSE 0x444 /* special 'close' mode for device */
-/* Which device to use */
-#if defined( __OpenBSD__ ) || defined( __NetBSD__ )
-#define DEV_DSP "/dev/audio"
-#else
-#define DEV_DSP "/dev/dsp"
-#endif
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-static char *config = "oss.conf"; /* default config file */
-
-static int oss_debug;
-
-/*
- * Each sound is made of 'datalen' samples of sound, repeated as needed to
- * generate 'samplen' samples of data, then followed by 'silencelen' samples
- * of silence. The loop is repeated if 'repeat' is set.
- */
-struct sound {
- int ind;
- char *desc;
- short *data;
- int datalen;
- int samplen;
- int silencelen;
- int repeat;
-};
-
-static struct sound sounds[] = {
- { AST_CONTROL_RINGING, "RINGING", ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
- { AST_CONTROL_BUSY, "BUSY", busy, sizeof(busy)/2, 4000, 4000, 1 },
- { AST_CONTROL_CONGESTION, "CONGESTION", busy, sizeof(busy)/2, 2000, 2000, 1 },
- { AST_CONTROL_RING, "RING10", ring10, sizeof(ring10)/2, 16000, 32000, 1 },
- { AST_CONTROL_ANSWER, "ANSWER", answer, sizeof(answer)/2, 2200, 0, 0 },
- { -1, NULL, 0, 0, 0, 0 }, /* end marker */
-};
-
-
-/*
- * descriptor for one of our channels.
- * There is one used for 'default' values (from the [general] entry in
- * the configuration file), and then one instance for each device
- * (the default is cloned from [general], others are only created
- * if the relevant section exists).
- */
-struct chan_oss_pvt {
- struct chan_oss_pvt *next;
-
- char *name;
- /*
- * cursound indicates which in struct sound we play. -1 means nothing,
- * any other value is a valid sound, in which case sampsent indicates
- * the next sample to send in [0..samplen + silencelen]
- * nosound is set to disable the audio data from the channel
- * (so we can play the tones etc.).
- */
- int sndcmd[2]; /* Sound command pipe */
- int cursound; /* index of sound to send */
- int sampsent; /* # of sound samples sent */
- int nosound; /* set to block audio from the PBX */
-
- int total_blocks; /* total blocks in the output device */
- int sounddev;
- enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
- int autoanswer;
- int autohangup;
- int hookstate;
- char *mixer_cmd; /* initial command to issue to the mixer */
- unsigned int queuesize; /* max fragments in queue */
- unsigned int frags; /* parameter for SETFRAGMENT */
-
- int warned; /* various flags used for warnings */
-#define WARN_used_blocks 1
-#define WARN_speed 2
-#define WARN_frag 4
- int w_errors; /* overfull in the write path */
- struct timeval lastopen;
-
- int overridecontext;
- int mute;
-
- /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
- * be representable in 16 bits to avoid overflows.
- */
-#define BOOST_SCALE (1<<9)
-#define BOOST_MAX 40 /* slightly less than 7 bits */
- int boost; /* input boost, scaled by BOOST_SCALE */
- char device[64]; /* device to open */
-
- pthread_t sthread;
-
- struct ast_channel *owner;
- char ext[AST_MAX_EXTENSION];
- char ctx[AST_MAX_CONTEXT];
- char language[MAX_LANGUAGE];
- char cid_name[256]; /*XXX */
- char cid_num[256]; /*XXX */
- char mohinterpret[MAX_MUSICCLASS];
-
- /* buffers used in oss_write */
- char oss_write_buf[FRAME_SIZE * 2];
- int oss_write_dst;
- /* buffers used in oss_read - AST_FRIENDLY_OFFSET space for headers
- * plus enough room for a full frame
- */
- char oss_read_buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
- int readpos; /* read position above */
- struct ast_frame read_f; /* returned by oss_read */
-};
-
-static struct chan_oss_pvt oss_default = {
- .cursound = -1,
- .sounddev = -1,
- .duplex = M_UNSET, /* XXX check this */
- .autoanswer = 1,
- .autohangup = 1,
- .queuesize = QUEUE_SIZE,
- .frags = FRAGS,
- .ext = "s",
- .ctx = "default",
- .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */
- .lastopen = { 0, 0 },
- .boost = BOOST_SCALE,
-};
-
-static char *oss_active; /* the active device */
-
-static int setformat(struct chan_oss_pvt *o, int mode);
-
-static struct ast_channel *oss_request(const char *type, int format, void *data
-, int *cause);
-static int oss_digit_begin(struct ast_channel *c, char digit);
-static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
-static int oss_text(struct ast_channel *c, const char *text);
-static int oss_hangup(struct ast_channel *c);
-static int oss_answer(struct ast_channel *c);
-static struct ast_frame *oss_read(struct ast_channel *chan);
-static int oss_call(struct ast_channel *c, char *dest, int timeout);
-static int oss_write(struct ast_channel *chan, struct ast_frame *f);
-static int oss_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
-static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static char tdesc[] = "OSS Console Channel Driver";
-
-static const struct ast_channel_tech oss_tech = {
- .type = "Console",
- .description = tdesc,
- .capabilities = AST_FORMAT_SLINEAR,
- .requester = oss_request,
- .send_digit_begin = oss_digit_begin,
- .send_digit_end = oss_digit_end,
- .send_text = oss_text,
- .hangup = oss_hangup,
- .answer = oss_answer,
- .read = oss_read,
- .call = oss_call,
- .write = oss_write,
- .indicate = oss_indicate,
- .fixup = oss_fixup,
-};
-
-/*
- * returns a pointer to the descriptor with the given name
- */
-static struct chan_oss_pvt *find_desc(char *dev)
-{
- struct chan_oss_pvt *o = NULL;
-
- if (!dev)
- ast_log(LOG_WARNING, "null dev\n");
-
- for (o = oss_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
-
- if (!o)
- ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
-
- return o;
-}
-
-/*
- * split a string in extension-context, returns pointers to malloc'ed
- * strings.
- * If we do not have 'overridecontext' then the last @ is considered as
- * a context separator, and the context is overridden.
- * This is usually not very necessary as you can play with the dialplan,
- * and it is nice not to need it because you have '@' in SIP addresses.
- * Return value is the buffer address.
- */
-static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (ext == NULL || ctx == NULL)
- return NULL; /* error */
-
- *ext = *ctx = NULL;
-
- if (src && *src != '\0')
- *ext = ast_strdup(src);
-
- if (*ext == NULL)
- return NULL;
-
- if (!o->overridecontext) {
- /* parse from the right */
- *ctx = strrchr(*ext, '@');
- if (*ctx)
- *(*ctx)++ = '\0';
- }
-
- return *ext;
-}
-
-/*
- * Returns the number of blocks used in the audio output channel
- */
-static int used_blocks(struct chan_oss_pvt *o)
-{
- struct audio_buf_info info;
-
- if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
- if (!(o->warned & WARN_used_blocks)) {
- ast_log(LOG_WARNING, "Error reading output space\n");
- o->warned |= WARN_used_blocks;
- }
- return 1;
- }
-
- if (o->total_blocks == 0) {
- if (0) /* debugging */
- ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
- o->total_blocks = info.fragments;
- }
-
- return o->total_blocks - info.fragments;
-}
-
-/* Write an exactly FRAME_SIZE sized frame */
-static int soundcard_writeframe(struct chan_oss_pvt *o, short *data)
-{
- int res;
-
- if (o->sounddev < 0)
- setformat(o, O_RDWR);
- if (o->sounddev < 0)
- return 0; /* not fatal */
- /*
- * Nothing complex to manage the audio device queue.
- * If the buffer is full just drop the extra, otherwise write.
- * XXX in some cases it might be useful to write anyways after
- * a number of failures, to restart the output chain.
- */
- res = used_blocks(o);
- if (res > o->queuesize) { /* no room to write a block */
- if (o->w_errors++ == 0 && (oss_debug & 0x4))
- ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
- return 0;
- }
- o->w_errors = 0;
- return write(o->sounddev, ((void *) data), FRAME_SIZE * 2);
-}
-
-/*
- * Handler for 'sound writable' events from the sound thread.
- * Builds a frame from the high level description of the sounds,
- * and passes it to the audio device.
- * The actual sound is made of 1 or more sequences of sound samples
- * (s->datalen, repeated to make s->samplen samples) followed by
- * s->silencelen samples of silence. The position in the sequence is stored
- * in o->sampsent, which goes between 0 .. s->samplen+s->silencelen.
- * In case we fail to write a frame, don't update o->sampsent.
- */
-static void send_sound(struct chan_oss_pvt *o)
-{
- short myframe[FRAME_SIZE];
- int ofs, l, start;
- int l_sampsent = o->sampsent;
- struct sound *s;
-
- if (o->cursound < 0) /* no sound to send */
- return;
-
- s = &sounds[o->cursound];
-
- for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
- l = s->samplen - l_sampsent; /* # of available samples */
- if (l > 0) {
- start = l_sampsent % s->datalen; /* source offset */
- if (l > FRAME_SIZE - ofs) /* don't overflow the frame */
- l = FRAME_SIZE - ofs;
- if (l > s->datalen - start) /* don't overflow the source */
- l = s->datalen - start;
- bcopy(s->data + start, myframe + ofs, l * 2);
- if (0)
- ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
- l_sampsent += l;
- } else { /* end of samples, maybe some silence */
- static const short silence[FRAME_SIZE] = { 0, };
-
- l += s->silencelen;
- if (l > 0) {
- if (l > FRAME_SIZE - ofs)
- l = FRAME_SIZE - ofs;
- bcopy(silence, myframe + ofs, l * 2);
- l_sampsent += l;
- } else { /* silence is over, restart sound if loop */
- if (s->repeat == 0) { /* last block */
- o->cursound = -1;
- o->nosound = 0; /* allow audio data */
- if (ofs < FRAME_SIZE) /* pad with silence */
- bcopy(silence, myframe + ofs, (FRAME_SIZE - ofs) * 2);
- }
- l_sampsent = 0;
- }
- }
- }
- l = soundcard_writeframe(o, myframe);
- if (l > 0)
- o->sampsent = l_sampsent; /* update status */
-}
-
-static void *sound_thread(void *arg)
-{
- char ign[4096];
- struct chan_oss_pvt *o = (struct chan_oss_pvt *) arg;
-
- /*
- * Just in case, kick the driver by trying to read from it.
- * Ignore errors - this read is almost guaranteed to fail.
- */
- read(o->sounddev, ign, sizeof(ign));
- for (;;) {
- fd_set rfds, wfds;
- int maxfd, res;
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_SET(o->sndcmd[0], &rfds);
- maxfd = o->sndcmd[0]; /* pipe from the main process */
- if (o->cursound > -1 && o->sounddev < 0)
- setformat(o, O_RDWR); /* need the channel, try to reopen */
- else if (o->cursound == -1 && o->owner == NULL)
- setformat(o, O_CLOSE); /* can close */
- if (o->sounddev > -1) {
- if (!o->owner) { /* no one owns the audio, so we must drain it */
- FD_SET(o->sounddev, &rfds);
- maxfd = MAX(o->sounddev, maxfd);
- }
- if (o->cursound > -1) {
- FD_SET(o->sounddev, &wfds);
- maxfd = MAX(o->sounddev, maxfd);
- }
- }
- /* ast_select emulates linux behaviour in terms of timeout handling */
- res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
- if (res < 1) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
- sleep(1);
- continue;
- }
- if (FD_ISSET(o->sndcmd[0], &rfds)) {
- /* read which sound to play from the pipe */
- int i, what = -1;
-
- read(o->sndcmd[0], &what, sizeof(what));
- for (i = 0; sounds[i].ind != -1; i++) {
- if (sounds[i].ind == what) {
- o->cursound = i;
- o->sampsent = 0;
- o->nosound = 1; /* block audio from pbx */
- break;
- }
- }
- if (sounds[i].ind == -1)
- ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
- }
- if (o->sounddev > -1) {
- if (FD_ISSET(o->sounddev, &rfds)) /* read and ignore errors */
- read(o->sounddev, ign, sizeof(ign));
- if (FD_ISSET(o->sounddev, &wfds))
- send_sound(o);
- }
- }
- return NULL; /* Never reached */
-}
-
-/*
- * reset and close the device if opened,
- * then open and initialize it in the desired mode,
- * trigger reads and writes so we can start using it.
- */
-static int setformat(struct chan_oss_pvt *o, int mode)
-{
- int fmt, desired, res, fd;
-
- if (o->sounddev >= 0) {
- ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
- close(o->sounddev);
- o->duplex = M_UNSET;
- o->sounddev = -1;
- }
- if (mode == O_CLOSE) /* we are done */
- return 0;
- if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000)
- return -1; /* don't open too often */
- o->lastopen = ast_tvnow();
- fd = o->sounddev = open(o->device, mode | O_NONBLOCK);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Unable to re-open DSP device %s: %s\n", o->device, strerror(errno));
- return -1;
- }
- if (o->owner)
- o->owner->fds[0] = fd;
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- fmt = AFMT_S16_LE;
-#else
- fmt = AFMT_S16_BE;
-#endif
- res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
- return -1;
- }
- switch (mode) {
- case O_RDWR:
- res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
- /* Check to see if duplex set (FreeBSD Bug) */
- res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
- if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
- o->duplex = M_FULL;
- };
- break;
- case O_WRONLY:
- o->duplex = M_WRITE;
- break;
- case O_RDONLY:
- o->duplex = M_READ;
- break;
- }
-
- fmt = 0;
- res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
- return -1;
- }
- fmt = desired = DEFAULT_SAMPLE_RATE; /* 8000 Hz desired */
- res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
-
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
- return -1;
- }
- if (fmt != desired) {
- if (!(o->warned & WARN_speed)) {
- ast_log(LOG_WARNING,
- "Requested %d Hz, got %d Hz -- sound may be choppy\n",
- desired, fmt);
- o->warned |= WARN_speed;
- }
- }
- /*
- * on Freebsd, SETFRAGMENT does not work very well on some cards.
- * Default to use 256 bytes, let the user override
- */
- if (o->frags) {
- fmt = o->frags;
- res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
- if (res < 0) {
- if (!(o->warned & WARN_frag)) {
- ast_log(LOG_WARNING,
- "Unable to set fragment size -- sound may be choppy\n");
- o->warned |= WARN_frag;
- }
- }
- }
- /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
- res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
- res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
- /* it may fail if we are in half duplex, never mind */
- return 0;
-}
-
-/*
- * some of the standard methods supported by channels.
- */
-static int oss_digit_begin(struct ast_channel *c, char digit)
-{
- return 0;
-}
-
-static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration)
-{
- /* no better use for received digits than print them */
- ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
- digit, duration);
- return 0;
-}
-
-static int oss_text(struct ast_channel *c, const char *text)
-{
- /* print received messages */
- ast_verbose(" << Console Received text %s >> \n", text);
- return 0;
-}
-
-/* Play ringtone 'x' on device 'o' */
-static void ring(struct chan_oss_pvt *o, int x)
-{
- write(o->sndcmd[1], &x, sizeof(x));
-}
-
-
-/*
- * handler for incoming calls. Either autoanswer, or start ringing
- */
-static int oss_call(struct ast_channel *c, char *dest, int timeout)
-{
- struct chan_oss_pvt *o = c->tech_pvt;
- struct ast_frame f = { 0, };
-
- ast_verbose(" << Call to device '%s' dnid '%s' rdnis '%s' on console from '%s' <%s> >>\n", dest, c->cid.cid_dnid, c->cid.cid_rdnis, c->cid.cid_name, c->cid.cid_num);
- if (o->autoanswer) {
- ast_verbose(" << Auto-answered >> \n");
- f.frametype = AST_FRAME_CONTROL;
- f.subclass = AST_CONTROL_ANSWER;
- ast_queue_frame(c, &f);
- } else {
- ast_verbose("<< Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
- f.frametype = AST_FRAME_CONTROL;
- f.subclass = AST_CONTROL_RINGING;
- ast_queue_frame(c, &f);
- ring(o, AST_CONTROL_RING);
- }
- return 0;
-}
-
-/*
- * remote side answered the phone
- */
-static int oss_answer(struct ast_channel *c)
-{
- struct chan_oss_pvt *o = c->tech_pvt;
-
- ast_verbose(" << Console call has been answered >> \n");
-#if 0
- /* play an answer tone (XXX do we really need it ?) */
- ring(o, AST_CONTROL_ANSWER);
-#endif
- ast_setstate(c, AST_STATE_UP);
- o->cursound = -1;
- o->nosound = 0;
- return 0;
-}
-
-static int oss_hangup(struct ast_channel *c)
-{
- struct chan_oss_pvt *o = c->tech_pvt;
-
- o->cursound = -1;
- o->nosound = 0;
- c->tech_pvt = NULL;
- o->owner = NULL;
- ast_verbose(" << Hangup on console >> \n");
- ast_module_unref(ast_module_info->self);
- if (o->hookstate) {
- if (o->autoanswer || o->autohangup) {
- /* Assume auto-hangup too */
- o->hookstate = 0;
- setformat(o, O_CLOSE);
- } else {
- /* Make congestion noise */
- ring(o, AST_CONTROL_CONGESTION);
- }
- }
- return 0;
-}
-
-/* used for data coming from the network */
-static int oss_write(struct ast_channel *c, struct ast_frame *f)
-{
- int src;
- struct chan_oss_pvt *o = c->tech_pvt;
-
- /* Immediately return if no sound is enabled */
- if (o->nosound)
- return 0;
- /* Stop any currently playing sound */
- o->cursound = -1;
- /*
- * we could receive a block which is not a multiple of our
- * FRAME_SIZE, so buffer it locally and write to the device
- * in FRAME_SIZE chunks.
- * Keep the residue stored for future use.
- */
- src = 0; /* read position into f->data */
- while (src < f->datalen) {
- /* Compute spare room in the buffer */
- int l = sizeof(o->oss_write_buf) - o->oss_write_dst;
-
- if (f->datalen - src >= l) { /* enough to fill a frame */
- memcpy(o->oss_write_buf + o->oss_write_dst, f->data + src, l);
- soundcard_writeframe(o, (short *) o->oss_write_buf);
- src += l;
- o->oss_write_dst = 0;
- } else { /* copy residue */
- l = f->datalen - src;
- memcpy(o->oss_write_buf + o->oss_write_dst, f->data + src, l);
- src += l; /* but really, we are done */
- o->oss_write_dst += l;
- }
- }
- return 0;
-}
-
-static struct ast_frame *oss_read(struct ast_channel *c)
-{
- int res;
- struct chan_oss_pvt *o = c->tech_pvt;
- struct ast_frame *f = &o->read_f;
-
- /* XXX can be simplified returning &ast_null_frame */
- /* prepare a NULL frame in case we don't have enough data to return */
- bzero(f, sizeof(struct ast_frame));
- f->frametype = AST_FRAME_NULL;
- f->src = oss_tech.type;
-
- res = read(o->sounddev, o->oss_read_buf + o->readpos, sizeof(o->oss_read_buf) - o->readpos);
- if (res < 0) /* audio data not ready, return a NULL frame */
- return f;
-
- o->readpos += res;
- if (o->readpos < sizeof(o->oss_read_buf)) /* not enough samples */
- return f;
-
- if (o->mute)
- return f;
-
- o->readpos = AST_FRIENDLY_OFFSET; /* reset read pointer for next frame */
- if (c->_state != AST_STATE_UP) /* drop data if frame is not up */
- return f;
- /* ok we can build and deliver the frame to the caller */
- f->frametype = AST_FRAME_VOICE;
- f->subclass = AST_FORMAT_SLINEAR;
- f->samples = FRAME_SIZE;
- f->datalen = FRAME_SIZE * 2;
- f->data = o->oss_read_buf + AST_FRIENDLY_OFFSET;
- if (o->boost != BOOST_SCALE) { /* scale and clip values */
- int i, x;
- int16_t *p = (int16_t *) f->data;
- for (i = 0; i < f->samples; i++) {
- x = (p[i] * o->boost) / BOOST_SCALE;
- if (x > 32767)
- x = 32767;
- else if (x < -32768)
- x = -32768;
- p[i] = x;
- }
- }
-
- f->offset = AST_FRIENDLY_OFFSET;
- return f;
-}
-
-static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct chan_oss_pvt *o = newchan->tech_pvt;
- o->owner = newchan;
- return 0;
-}
-
-static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
-{
- struct chan_oss_pvt *o = c->tech_pvt;
- int res = -1;
-
- switch (cond) {
- case AST_CONTROL_BUSY:
- case AST_CONTROL_CONGESTION:
- case AST_CONTROL_RINGING:
- res = cond;
- break;
-
- case -1:
- o->cursound = -1;
- o->nosound = 0; /* when cursound is -1 nosound must be 0 */
- return 0;
-
- case AST_CONTROL_VIDUPDATE:
- res = -1;
- break;
- case AST_CONTROL_HOLD:
- ast_verbose(" << Console Has Been Placed on Hold >> \n");
- ast_moh_start(c, data, o->mohinterpret);
- break;
- case AST_CONTROL_UNHOLD:
- ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
- ast_moh_stop(c);
- break;
- case AST_CONTROL_SRCUPDATE:
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
- return -1;
- }
-
- if (res > -1)
- ring(o, res);
-
- return 0;
-}
-
-/*
- * allocate a new channel.
- */
-static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state)
-{
- struct ast_channel *c;
-
- c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Console/%s", o->device + 5);
- if (c == NULL)
- return NULL;
- c->tech = &oss_tech;
- if (o->sounddev < 0)
- setformat(o, O_RDWR);
- c->fds[0] = o->sounddev; /* -1 if device closed, override later */
- c->nativeformats = AST_FORMAT_SLINEAR;
- c->readformat = AST_FORMAT_SLINEAR;
- c->writeformat = AST_FORMAT_SLINEAR;
- c->tech_pvt = o;
-
- if (!ast_strlen_zero(o->language))
- ast_string_field_set(c, language, o->language);
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
- c->cid.cid_ani = ast_strdup(o->cid_num);
- if (!ast_strlen_zero(ext))
- c->cid.cid_dnid = ast_strdup(ext);
-
- o->owner = c;
- ast_module_ref(ast_module_info->self);
- ast_jb_configure(c, &global_jbconf);
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(c)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
- ast_hangup(c);
- o->owner = c = NULL;
- /* XXX what about the channel itself ? */
- /* XXX what about usecnt ? */
- }
- }
-
- return c;
-}
-
-static struct ast_channel *oss_request(const char *type, int format, void *data, int *cause)
-{
- struct ast_channel *c;
- struct chan_oss_pvt *o = find_desc(data);
-
- ast_log(LOG_WARNING, "oss_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
- if (o == NULL) {
- ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
- /* XXX we could default to 'dsp' perhaps ? */
- return NULL;
- }
- if ((format & AST_FORMAT_SLINEAR) == 0) {
- ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
- return NULL;
- }
- if (o->owner) {
- ast_log(LOG_NOTICE, "Already have a call (chan %p) on the OSS channel\n", o->owner);
- *cause = AST_CAUSE_BUSY;
- return NULL;
- }
- c = oss_new(o, NULL, NULL, AST_STATE_DOWN);
- if (c == NULL) {
- ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
- return NULL;
- }
- return c;
-}
-
-static int console_autoanswer_deprecated(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc == 1) {
- ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off");
- return RESULT_SUCCESS;
- }
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- if (o == NULL) {
- ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n", oss_active);
- return RESULT_FAILURE;
- }
- if (!strcasecmp(argv[1], "on"))
- o->autoanswer = -1;
- else if (!strcasecmp(argv[1], "off"))
- o->autoanswer = 0;
- else
- return RESULT_SHOWUSAGE;
- return RESULT_SUCCESS;
-}
-
-static int console_autoanswer(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc == 2) {
- ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off");
- return RESULT_SUCCESS;
- }
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- if (o == NULL) {
- ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n",
- oss_active);
- return RESULT_FAILURE;
- }
- if (!strcasecmp(argv[2], "on"))
- o->autoanswer = -1;
- else if (!strcasecmp(argv[2], "off"))
- o->autoanswer = 0;
- else
- return RESULT_SHOWUSAGE;
- return RESULT_SUCCESS;
-}
-
-static char *autoanswer_complete_deprecated(const char *line, const char *word, int pos, int state)
-{
- static char *choices[] = { "on", "off", NULL };
-
- return (pos != 2) ? NULL : ast_cli_complete(word, choices, state);
-}
-
-static char *autoanswer_complete(const char *line, const char *word, int pos, int state)
-{
- static char *choices[] = { "on", "off", NULL };
-
- return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);
-}
-
-static char autoanswer_usage[] =
- "Usage: console autoanswer [on|off]\n"
- " Enables or disables autoanswer feature. If used without\n"
- " argument, displays the current on/off status of autoanswer.\n"
- " The default value of autoanswer is in 'oss.conf'.\n";
-
-/*
- * answer command from the console
- */
-static int console_answer_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 1)
- return RESULT_SHOWUSAGE;
- if (!o->owner) {
- ast_cli(fd, "No one is calling us\n");
- return RESULT_FAILURE;
- }
- o->hookstate = 1;
- o->cursound = -1;
- o->nosound = 0;
- ast_queue_frame(o->owner, &f);
-#if 0
- /* XXX do we really need it ? considering we shut down immediately... */
- ring(o, AST_CONTROL_ANSWER);
-#endif
- return RESULT_SUCCESS;
-}
-
-static int console_answer(int fd, int argc, char *argv[])
-{
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- if (!o->owner) {
- ast_cli(fd, "No one is calling us\n");
- return RESULT_FAILURE;
- }
- o->hookstate = 1;
- o->cursound = -1;
- o->nosound = 0;
- ast_queue_frame(o->owner, &f);
-#if 0
- /* XXX do we really need it ? considering we shut down immediately... */
- ring(o, AST_CONTROL_ANSWER);
-#endif
- return RESULT_SUCCESS;
-}
-
-static char answer_usage[] =
- "Usage: console answer\n"
- " Answers an incoming call on the console (OSS) channel.\n";
-
-/*
- * concatenate all arguments into a single string. argv is NULL-terminated
- * so we can use it right away
- */
-static int console_sendtext_deprecated(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
- char buf[TEXT_SIZE];
-
- if (argc < 2)
- return RESULT_SHOWUSAGE;
- if (!o->owner) {
- ast_cli(fd, "Not in a call\n");
- return RESULT_FAILURE;
- }
- ast_join(buf, sizeof(buf) - 1, argv + 2);
- if (!ast_strlen_zero(buf)) {
- struct ast_frame f = { 0, };
- int i = strlen(buf);
- buf[i] = '\n';
- f.frametype = AST_FRAME_TEXT;
- f.subclass = 0;
- f.data = buf;
- f.datalen = i + 1;
- ast_queue_frame(o->owner, &f);
- }
- return RESULT_SUCCESS;
-}
-
-static int console_sendtext(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
- char buf[TEXT_SIZE];
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
- if (!o->owner) {
- ast_cli(fd, "Not in a call\n");
- return RESULT_FAILURE;
- }
- ast_join(buf, sizeof(buf) - 1, argv + 3);
- if (!ast_strlen_zero(buf)) {
- struct ast_frame f = { 0, };
- int i = strlen(buf);
- buf[i] = '\n';
- f.frametype = AST_FRAME_TEXT;
- f.subclass = 0;
- f.data = buf;
- f.datalen = i + 1;
- ast_queue_frame(o->owner, &f);
- }
- return RESULT_SUCCESS;
-}
-
-static char sendtext_usage[] =
- "Usage: console send text <message>\n"
- " Sends a text message for display on the remote terminal.\n";
-
-static int console_hangup_deprecated(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 1)
- return RESULT_SHOWUSAGE;
- o->cursound = -1;
- o->nosound = 0;
- if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */
- ast_cli(fd, "No call to hang up\n");
- return RESULT_FAILURE;
- }
- o->hookstate = 0;
- if (o->owner)
- ast_queue_hangup(o->owner);
- setformat(o, O_CLOSE);
- return RESULT_SUCCESS;
-}
-
-static int console_hangup(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- o->cursound = -1;
- o->nosound = 0;
- if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */
- ast_cli(fd, "No call to hang up\n");
- return RESULT_FAILURE;
- }
- o->hookstate = 0;
- if (o->owner)
- ast_queue_hangup(o->owner);
- setformat(o, O_CLOSE);
- return RESULT_SUCCESS;
-}
-
-static char hangup_usage[] =
- "Usage: console hangup\n"
- " Hangs up any call currently placed on the console.\n";
-
-static int console_flash_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH };
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 1)
- return RESULT_SHOWUSAGE;
- o->cursound = -1;
- o->nosound = 0; /* when cursound is -1 nosound must be 0 */
- if (!o->owner) { /* XXX maybe !o->hookstate too ? */
- ast_cli(fd, "No call to flash\n");
- return RESULT_FAILURE;
- }
- o->hookstate = 0;
- if (o->owner) /* XXX must be true, right ? */
- ast_queue_frame(o->owner, &f);
- return RESULT_SUCCESS;
-}
-
-static int console_flash(int fd, int argc, char *argv[])
-{
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH };
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- o->cursound = -1;
- o->nosound = 0; /* when cursound is -1 nosound must be 0 */
- if (!o->owner) { /* XXX maybe !o->hookstate too ? */
- ast_cli(fd, "No call to flash\n");
- return RESULT_FAILURE;
- }
- o->hookstate = 0;
- if (o->owner) /* XXX must be true, right ? */
- ast_queue_frame(o->owner, &f);
- return RESULT_SUCCESS;
-}
-
-static char flash_usage[] =
- "Usage: console flash\n"
- " Flashes the call currently placed on the console.\n";
-
-static int console_dial_deprecated(int fd, int argc, char *argv[])
-{
- char *s = NULL, *mye = NULL, *myc = NULL;
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 1 && argc != 2)
- return RESULT_SHOWUSAGE;
- if (o->owner) { /* already in a call */
- int i;
- struct ast_frame f = { AST_FRAME_DTMF, 0 };
-
- if (argc == 1) { /* argument is mandatory here */
- ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n");
- return RESULT_FAILURE;
- }
- s = argv[1];
- /* send the string one char at a time */
- for (i = 0; i < strlen(s); i++) {
- f.subclass = s[i];
- ast_queue_frame(o->owner, &f);
- }
- return RESULT_SUCCESS;
- }
- /* if we have an argument split it into extension and context */
- if (argc == 2)
- s = ast_ext_ctx(argv[1], &mye, &myc);
- /* supply default values if needed */
- if (mye == NULL)
- mye = o->ext;
- if (myc == NULL)
- myc = o->ctx;
- if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
- o->hookstate = 1;
- oss_new(o, mye, myc, AST_STATE_RINGING);
- } else
- ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
- if (s)
- free(s);
- return RESULT_SUCCESS;
-}
-
-static int console_dial(int fd, int argc, char *argv[])
-{
- char *s = NULL, *mye = NULL, *myc = NULL;
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc != 2 && argc != 3)
- return RESULT_SHOWUSAGE;
- if (o->owner) { /* already in a call */
- int i;
- struct ast_frame f = { AST_FRAME_DTMF, 0 };
-
- if (argc == 2) { /* argument is mandatory here */
- ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n");
- return RESULT_FAILURE;
- }
- s = argv[2];
- /* send the string one char at a time */
- for (i = 0; i < strlen(s); i++) {
- f.subclass = s[i];
- ast_queue_frame(o->owner, &f);
- }
- return RESULT_SUCCESS;
- }
- /* if we have an argument split it into extension and context */
- if (argc == 3)
- s = ast_ext_ctx(argv[2], &mye, &myc);
- /* supply default values if needed */
- if (mye == NULL)
- mye = o->ext;
- if (myc == NULL)
- myc = o->ctx;
- if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
- o->hookstate = 1;
- oss_new(o, mye, myc, AST_STATE_RINGING);
- } else
- ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
- if (s)
- free(s);
- return RESULT_SUCCESS;
-}
-
-static char dial_usage[] =
- "Usage: console dial [extension[@context]]\n"
- " Dials a given extension (and context if specified)\n";
-
-static int __console_mute_unmute(int mute)
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- o->mute = mute;
- return RESULT_SUCCESS;
-}
-
-static int console_mute_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 1)
- return RESULT_SHOWUSAGE;
-
- return __console_mute_unmute(1);
-}
-
-static int console_mute(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
-
- return __console_mute_unmute(1);
-}
-
-static char mute_usage[] =
- "Usage: console mute\nMutes the microphone\n";
-
-static int console_unmute_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 1)
- return RESULT_SHOWUSAGE;
-
- return __console_mute_unmute(0);
-}
-
-static int console_unmute(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
-
- return __console_mute_unmute(0);
-}
-
-static char unmute_usage[] =
- "Usage: console unmute\nUnmutes the microphone\n";
-
-static int console_transfer_deprecated(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
- struct ast_channel *b = NULL;
- char *tmp, *ext, *ctx;
-
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- if (o == NULL)
- return RESULT_FAILURE;
- if (o->owner ==NULL || (b = ast_bridged_channel(o->owner)) == NULL) {
- ast_cli(fd, "There is no call to transfer\n");
- return RESULT_SUCCESS;
- }
-
- tmp = ast_ext_ctx(argv[1], &ext, &ctx);
- if (ctx == NULL) /* supply default context if needed */
- ctx = o->owner->context;
- if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num))
- ast_cli(fd, "No such extension exists\n");
- else {
- ast_cli(fd, "Whee, transferring %s to %s@%s.\n",
- b->name, ext, ctx);
- if (ast_async_goto(b, ctx, ext, 1))
- ast_cli(fd, "Failed to transfer :(\n");
- }
- if (tmp)
- free(tmp);
- return RESULT_SUCCESS;
-}
-
-static int console_transfer(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
- struct ast_channel *b = NULL;
- char *tmp, *ext, *ctx;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- if (o == NULL)
- return RESULT_FAILURE;
- if (o->owner == NULL || (b = ast_bridged_channel(o->owner)) == NULL) {
- ast_cli(fd, "There is no call to transfer\n");
- return RESULT_SUCCESS;
- }
-
- tmp = ast_ext_ctx(argv[2], &ext, &ctx);
- if (ctx == NULL) /* supply default context if needed */
- ctx = o->owner->context;
- if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num))
- ast_cli(fd, "No such extension exists\n");
- else {
- ast_cli(fd, "Whee, transferring %s to %s@%s.\n", b->name, ext, ctx);
- if (ast_async_goto(b, ctx, ext, 1))
- ast_cli(fd, "Failed to transfer :(\n");
- }
- if (tmp)
- free(tmp);
- return RESULT_SUCCESS;
-}
-
-static char transfer_usage[] =
- "Usage: console transfer <extension>[@context]\n"
- " Transfers the currently connected call to the given extension (and\n"
- "context if specified)\n";
-
-static int console_active_deprecated(int fd, int argc, char *argv[])
-{
- if (argc == 1)
- ast_cli(fd, "active console is [%s]\n", oss_active);
- else if (argc != 2)
- return RESULT_SHOWUSAGE;
- else {
- struct chan_oss_pvt *o;
- if (strcmp(argv[1], "show") == 0) {
- for (o = oss_default.next; o; o = o->next)
- ast_cli(fd, "device [%s] exists\n", o->name);
- return RESULT_SUCCESS;
- }
- o = find_desc(argv[1]);
- if (o == NULL)
- ast_cli(fd, "No device [%s] exists\n", argv[1]);
- else
- oss_active = o->name;
- }
- return RESULT_SUCCESS;
-}
-
-static int console_active(int fd, int argc, char *argv[])
-{
- if (argc == 2)
- ast_cli(fd, "active console is [%s]\n", oss_active);
- else if (argc != 3)
- return RESULT_SHOWUSAGE;
- else {
- struct chan_oss_pvt *o;
- if (strcmp(argv[2], "show") == 0) {
- for (o = oss_default.next; o; o = o->next)
- ast_cli(fd, "device [%s] exists\n", o->name);
- return RESULT_SUCCESS;
- }
- o = find_desc(argv[2]);
- if (o == NULL)
- ast_cli(fd, "No device [%s] exists\n", argv[2]);
- else
- oss_active = o->name;
- }
- return RESULT_SUCCESS;
-}
-
-static char active_usage[] =
- "Usage: console active [device]\n"
- " If used without a parameter, displays which device is the current\n"
- "console. If a device is specified, the console sound device is changed to\n"
- "the device specified.\n";
-
-/*
- * store the boost factor
- */
-static void store_boost(struct chan_oss_pvt *o, char *s)
-{
- double boost = 0;
- if (sscanf(s, "%lf", &boost) != 1) {
- ast_log(LOG_WARNING, "invalid boost <%s>\n", s);
- return;
- }
- if (boost < -BOOST_MAX) {
- ast_log(LOG_WARNING, "boost %s too small, using %d\n", s, -BOOST_MAX);
- boost = -BOOST_MAX;
- } else if (boost > BOOST_MAX) {
- ast_log(LOG_WARNING, "boost %s too large, using %d\n", s, BOOST_MAX);
- boost = BOOST_MAX;
- }
- boost = exp(log(10) * boost / 20) * BOOST_SCALE;
- o->boost = boost;
- ast_log(LOG_WARNING, "setting boost %s to %d\n", s, o->boost);
-}
-
-static int do_boost(int fd, int argc, char *argv[])
-{
- struct chan_oss_pvt *o = find_desc(oss_active);
-
- if (argc == 2)
- ast_cli(fd, "boost currently %5.1f\n", 20 * log10(((double) o->boost / (double) BOOST_SCALE)));
- else if (argc == 3)
- store_boost(o, argv[2]);
- return RESULT_SUCCESS;
-}
-
-static struct ast_cli_entry cli_oss_answer_deprecated = {
- { "answer", NULL },
- console_answer_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_hangup_deprecated = {
- { "hangup", NULL },
- console_hangup_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_flash_deprecated = {
- { "flash", NULL },
- console_flash_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_dial_deprecated = {
- { "dial", NULL },
- console_dial_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_mute_deprecated = {
- { "mute", NULL },
- console_mute_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_unmute_deprecated = {
- { "unmute", NULL },
- console_unmute_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_transfer_deprecated = {
- { "transfer", NULL },
- console_transfer_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_send_text_deprecated = {
- { "send", "text", NULL },
- console_sendtext_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_autoanswer_deprecated = {
- { "autoanswer", NULL },
- console_autoanswer_deprecated, NULL,
- NULL, autoanswer_complete_deprecated };
-
-static struct ast_cli_entry cli_oss_boost_deprecated = {
- { "oss", "boost", NULL },
- do_boost, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss_active_deprecated = {
- { "console", NULL },
- console_active_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_oss[] = {
- { { "console", "answer", NULL },
- console_answer, "Answer an incoming console call",
- answer_usage, NULL, &cli_oss_answer_deprecated },
-
- { { "console", "hangup", NULL },
- console_hangup, "Hangup a call on the console",
- hangup_usage, NULL, &cli_oss_hangup_deprecated },
-
- { { "console", "flash", NULL },
- console_flash, "Flash a call on the console",
- flash_usage, NULL, &cli_oss_flash_deprecated },
-
- { { "console", "dial", NULL },
- console_dial, "Dial an extension on the console",
- dial_usage, NULL, &cli_oss_dial_deprecated },
-
- { { "console", "mute", NULL },
- console_mute, "Disable mic input",
- mute_usage, NULL, &cli_oss_mute_deprecated },
-
- { { "console", "unmute", NULL },
- console_unmute, "Enable mic input",
- unmute_usage, NULL, &cli_oss_unmute_deprecated },
-
- { { "console", "transfer", NULL },
- console_transfer, "Transfer a call to a different extension",
- transfer_usage, NULL, &cli_oss_transfer_deprecated },
-
- { { "console", "send", "text", NULL },
- console_sendtext, "Send text to the remote device",
- sendtext_usage, NULL, &cli_oss_send_text_deprecated },
-
- { { "console", "autoanswer", NULL },
- console_autoanswer, "Sets/displays autoanswer",
- autoanswer_usage, autoanswer_complete, &cli_oss_autoanswer_deprecated },
-
- { { "console", "boost", NULL },
- do_boost, "Sets/displays mic boost in dB",
- NULL, NULL, &cli_oss_boost_deprecated },
-
- { { "console", "active", NULL },
- console_active, "Sets/displays active console",
- active_usage, NULL, &cli_oss_active_deprecated },
-};
-
-/*
- * store the mixer argument from the config file, filtering possibly
- * invalid or dangerous values (the string is used as argument for
- * system("mixer %s")
- */
-static void store_mixer(struct chan_oss_pvt *o, char *s)
-{
- int i;
-
- for (i = 0; i < strlen(s); i++) {
- if (!isalnum(s[i]) && index(" \t-/", s[i]) == NULL) {
- ast_log(LOG_WARNING, "Suspect char %c in mixer cmd, ignoring:\n\t%s\n", s[i], s);
- return;
- }
- }
- if (o->mixer_cmd)
- free(o->mixer_cmd);
- o->mixer_cmd = ast_strdup(s);
- ast_log(LOG_WARNING, "setting mixer %s\n", s);
-}
-
-/*
- * store the callerid components
- */
-static void store_callerid(struct chan_oss_pvt *o, char *s)
-{
- ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
-}
-
-/*
- * grab fields from the config file, init the descriptor and open the device.
- */
-static struct chan_oss_pvt *store_config(struct ast_config *cfg, char *ctg)
-{
- struct ast_variable *v;
- struct chan_oss_pvt *o;
-
- if (ctg == NULL) {
- o = &oss_default;
- ctg = "general";
- } else {
- if (!(o = ast_calloc(1, sizeof(*o))))
- return NULL;
- *o = oss_default;
- /* "general" is also the default thing */
- if (strcmp(ctg, "general") == 0) {
- o->name = ast_strdup("dsp");
- oss_active = o->name;
- goto openit;
- }
- o->name = ast_strdup(ctg);
- }
-
- strcpy(o->mohinterpret, "default");
-
- o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
- /* fill other fields from configuration */
- for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
- M_START(v->name, v->value);
-
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
- continue;
-
- M_BOOL("autoanswer", o->autoanswer)
- M_BOOL("autohangup", o->autohangup)
- M_BOOL("overridecontext", o->overridecontext)
- M_STR("device", o->device)
- M_UINT("frags", o->frags)
- M_UINT("debug", oss_debug)
- M_UINT("queuesize", o->queuesize)
- M_STR("context", o->ctx)
- M_STR("language", o->language)
- M_STR("mohinterpret", o->mohinterpret)
- M_STR("extension", o->ext)
- M_F("mixer", store_mixer(o, v->value))
- M_F("callerid", store_callerid(o, v->value))
- M_F("boost", store_boost(o, v->value))
- M_END(;
- );
- }
- if (ast_strlen_zero(o->device))
- ast_copy_string(o->device, DEV_DSP, sizeof(o->device));
- if (o->mixer_cmd) {
- char *cmd;
-
- asprintf(&cmd, "mixer %s", o->mixer_cmd);
- ast_log(LOG_WARNING, "running [%s]\n", cmd);
- system(cmd);
- free(cmd);
- }
- if (o == &oss_default) /* we are done with the default */
- return NULL;
-
- openit:
-#if TRYOPEN
- if (setformat(o, O_RDWR) < 0) { /* open device */
- if (option_verbose > 0) {
- ast_verbose(VERBOSE_PREFIX_2 "Device %s not detected\n", ctg);
- ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding " "'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
- }
- goto error;
- }
- if (o->duplex != M_FULL)
- ast_log(LOG_WARNING, "XXX I don't work right with non " "full-duplex sound cards XXX\n");
-#endif /* TRYOPEN */
- if (pipe(o->sndcmd) != 0) {
- ast_log(LOG_ERROR, "Unable to create pipe\n");
- goto error;
- }
- ast_pthread_create_background(&o->sthread, NULL, sound_thread, o);
- /* link into list of devices */
- if (o != &oss_default) {
- o->next = oss_default.next;
- oss_default.next = o;
- }
- return o;
-
- error:
- if (o != &oss_default)
- free(o);
- return NULL;
-}
-
-static int load_module(void)
-{
- struct ast_config *cfg = NULL;
- char *ctg = NULL;
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- /* load config file */
- if (!(cfg = ast_config_load(config))) {
- ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- do {
- store_config(cfg, ctg);
- } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
-
- ast_config_destroy(cfg);
-
- if (find_desc(oss_active) == NULL) {
- ast_log(LOG_NOTICE, "Device %s not found\n", oss_active);
- /* XXX we could default to 'dsp' perhaps ? */
- /* XXX should cleanup allocated memory etc. */
- return AST_MODULE_LOAD_FAILURE;
- }
-
- if (ast_channel_register(&oss_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n");
- return AST_MODULE_LOAD_FAILURE;
- }
-
- ast_cli_register_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry));
-
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-
-static int unload_module(void)
-{
- struct chan_oss_pvt *o;
-
- ast_channel_unregister(&oss_tech);
- ast_cli_unregister_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry));
-
- for (o = oss_default.next; o; o = o->next) {
- close(o->sounddev);
- if (o->sndcmd[0] > 0) {
- close(o->sndcmd[0]);
- close(o->sndcmd[1]);
- }
- if (o->owner)
- ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
- if (o->owner) /* XXX how ??? */
- return -1;
- /* XXX what about the thread ? */
- /* XXX what about the memory allocated ? */
- }
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "OSS Console Channel Driver");
diff --git a/1.4/channels/chan_phone.c b/1.4/channels/chan_phone.c
deleted file mode 100644
index b551b1cba..000000000
--- a/1.4/channels/chan_phone.c
+++ /dev/null
@@ -1,1433 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Generic Linux Telephony Interface driver
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>ixjuser</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-#ifdef HAVE_LINUX_COMPILER_H
-#include <linux/compiler.h>
-#endif
-#include <linux/telephony.h>
-/* Still use some IXJ specific stuff */
-#include <linux/version.h>
-#include <linux/ixjuser.h>
-
-#include "asterisk/lock.h"
-#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/callerid.h"
-#include "asterisk/causes.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/musiconhold.h"
-
-#include "DialTone.h"
-
-#ifdef QTI_PHONEJACK_TJ_PCI /* check for the newer quicknet driver v.3.1.0 which has this symbol */
-#define QNDRV_VER 310
-#else
-#define QNDRV_VER 100
-#endif
-
-#if QNDRV_VER > 100
-#ifdef __linux__
-#define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);
-#else /* FreeBSD and others */
-#define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, x);
-#endif /* __linux__ */
-#else /* older driver */
-#define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);
-#endif
-
-#define DEFAULT_CALLER_ID "Unknown"
-#define PHONE_MAX_BUF 480
-#define DEFAULT_GAIN 0x100
-
-static const char tdesc[] = "Standard Linux Telephony API Driver";
-static const char config[] = "phone.conf";
-
-/* Default context for dialtone mode */
-static char context[AST_MAX_EXTENSION] = "default";
-
-/* Default language */
-static char language[MAX_LANGUAGE] = "";
-
-static int echocancel = AEC_OFF;
-
-static int silencesupression = 0;
-
-static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
-
-/* Protect the interface list (of phone_pvt's) */
-AST_MUTEX_DEFINE_STATIC(iflock);
-
-/* Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
-
-/* Boolean value whether the monitoring thread shall continue. */
-static unsigned int monitor;
-
-/* This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-
-static int restart_monitor(void);
-
-/* The private structures of the Phone Jack channels are linked for
- selecting outgoing channels */
-
-#define MODE_DIALTONE 1
-#define MODE_IMMEDIATE 2
-#define MODE_FXO 3
-#define MODE_FXS 4
-#define MODE_SIGMA 5
-
-static struct phone_pvt {
- int fd; /* Raw file descriptor for this device */
- struct ast_channel *owner; /* Channel we belong to, possibly NULL */
- int mode; /* Is this in the */
- int lastformat; /* Last output format */
- int lastinput; /* Last input format */
- int ministate; /* Miniature state, for dialtone mode */
- char dev[256]; /* Device name */
- struct phone_pvt *next; /* Next channel in list */
- struct ast_frame fr; /* Frame */
- char offset[AST_FRIENDLY_OFFSET];
- char buf[PHONE_MAX_BUF]; /* Static buffer for reading frames */
- int obuflen;
- int dialtone;
- int txgain, rxgain; /* gain control for playing, recording */
- /* 0x100 - 1.0, 0x200 - 2.0, 0x80 - 0.5 */
- int cpt; /* Call Progress Tone playing? */
- int silencesupression;
- char context[AST_MAX_EXTENSION];
- char obuf[PHONE_MAX_BUF * 2];
- char ext[AST_MAX_EXTENSION];
- char language[MAX_LANGUAGE];
- char cid_num[AST_MAX_EXTENSION];
- char cid_name[AST_MAX_EXTENSION];
-} *iflist = NULL;
-
-static char cid_num[AST_MAX_EXTENSION];
-static char cid_name[AST_MAX_EXTENSION];
-
-static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause);
-static int phone_digit_begin(struct ast_channel *ast, char digit);
-static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int phone_call(struct ast_channel *ast, char *dest, int timeout);
-static int phone_hangup(struct ast_channel *ast);
-static int phone_answer(struct ast_channel *ast);
-static struct ast_frame *phone_read(struct ast_channel *ast);
-static int phone_write(struct ast_channel *ast, struct ast_frame *frame);
-static struct ast_frame *phone_exception(struct ast_channel *ast);
-static int phone_send_text(struct ast_channel *ast, const char *text);
-static int phone_fixup(struct ast_channel *old, struct ast_channel *new);
-static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
-
-static const struct ast_channel_tech phone_tech = {
- .type = "Phone",
- .description = tdesc,
- .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
- .requester = phone_request,
- .send_digit_begin = phone_digit_begin,
- .send_digit_end = phone_digit_end,
- .call = phone_call,
- .hangup = phone_hangup,
- .answer = phone_answer,
- .read = phone_read,
- .write = phone_write,
- .exception = phone_exception,
- .indicate = phone_indicate,
- .fixup = phone_fixup
-};
-
-static struct ast_channel_tech phone_tech_fxs = {
- .type = "Phone",
- .description = tdesc,
- .requester = phone_request,
- .send_digit_begin = phone_digit_begin,
- .send_digit_end = phone_digit_end,
- .call = phone_call,
- .hangup = phone_hangup,
- .answer = phone_answer,
- .read = phone_read,
- .write = phone_write,
- .exception = phone_exception,
- .write_video = phone_write,
- .send_text = phone_send_text,
- .indicate = phone_indicate,
- .fixup = phone_fixup
-};
-
-static struct ast_channel_tech *cur_tech;
-
-static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
-{
- struct phone_pvt *p = chan->tech_pvt;
- int res=-1;
- ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
- switch(condition) {
- case AST_CONTROL_FLASH:
- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
- usleep(320000);
- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
- p->lastformat = -1;
- res = 0;
- break;
- case AST_CONTROL_HOLD:
- ast_moh_start(chan, data, NULL);
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(chan);
- break;
- case AST_CONTROL_SRCUPDATE:
- res = 0;
- break;
- default:
- ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, chan->name);
- }
- return res;
-}
-
-static int phone_fixup(struct ast_channel *old, struct ast_channel *new)
-{
- struct phone_pvt *pvt = old->tech_pvt;
- if (pvt && pvt->owner == old)
- pvt->owner = new;
- return 0;
-}
-
-static int phone_digit_begin(struct ast_channel *chan, char digit)
-{
- /* XXX Modify this callback to let Asterisk support controlling the length of DTMF */
- return 0;
-}
-
-static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct phone_pvt *p;
- int outdigit;
- p = ast->tech_pvt;
- ast_log(LOG_DEBUG, "Dialed %c\n", digit);
- switch(digit) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- outdigit = digit - '0';
- break;
- case '*':
- outdigit = 11;
- break;
- case '#':
- outdigit = 12;
- break;
- case 'f': /*flash*/
- case 'F':
- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
- usleep(320000);
- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
- p->lastformat = -1;
- return 0;
- default:
- ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
- return -1;
- }
- ast_log(LOG_DEBUG, "Dialed %d\n", outdigit);
- ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
- p->lastformat = -1;
- return 0;
-}
-
-static int phone_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct phone_pvt *p;
-
- PHONE_CID cid;
- time_t UtcTime;
- struct tm tm;
- int start;
-
- time(&UtcTime);
- ast_localtime(&UtcTime, &tm, NULL);
-
- memset(&cid, 0, sizeof(PHONE_CID));
- if(&tm != NULL) {
- snprintf(cid.month, sizeof(cid.month), "%02d",(tm.tm_mon + 1));
- snprintf(cid.day, sizeof(cid.day), "%02d", tm.tm_mday);
- snprintf(cid.hour, sizeof(cid.hour), "%02d", tm.tm_hour);
- snprintf(cid.min, sizeof(cid.min), "%02d", tm.tm_min);
- }
- /* the standard format of ast->callerid is: "name" <number>, but not always complete */
- if (ast_strlen_zero(ast->cid.cid_name))
- strcpy(cid.name, DEFAULT_CALLER_ID);
- else
- ast_copy_string(cid.name, ast->cid.cid_name, sizeof(cid.name));
-
- if (ast->cid.cid_num)
- ast_copy_string(cid.number, ast->cid.cid_num, sizeof(cid.number));
-
- p = ast->tech_pvt;
-
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast->name);
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
-
- start = IXJ_PHONE_RING_START(cid);
- if (start == -1)
- return -1;
-
- if (p->mode == MODE_FXS) {
- char *digit = strchr(dest, '/');
- if (digit)
- {
- digit++;
- while (*digit)
- phone_digit_end(ast, *digit++, 0);
- }
- }
-
- ast_setstate(ast, AST_STATE_RINGING);
- ast_queue_control(ast, AST_CONTROL_RINGING);
- return 0;
-}
-
-static int phone_hangup(struct ast_channel *ast)
-{
- struct phone_pvt *p;
- p = ast->tech_pvt;
- if (option_debug)
- ast_log(LOG_DEBUG, "phone_hangup(%s)\n", ast->name);
- if (!ast->tech_pvt) {
- ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
- return 0;
- }
- /* XXX Is there anything we can do to really hang up except stop recording? */
- ast_setstate(ast, AST_STATE_DOWN);
- if (ioctl(p->fd, PHONE_REC_STOP))
- ast_log(LOG_WARNING, "Failed to stop recording\n");
- if (ioctl(p->fd, PHONE_PLAY_STOP))
- ast_log(LOG_WARNING, "Failed to stop playing\n");
- if (ioctl(p->fd, PHONE_RING_STOP))
- ast_log(LOG_WARNING, "Failed to stop ringing\n");
- if (ioctl(p->fd, PHONE_CPT_STOP))
- ast_log(LOG_WARNING, "Failed to stop sounds\n");
-
- /* If it's an FXO, hang them up */
- if (p->mode == MODE_FXO) {
- if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
- ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",ast->name, strerror(errno));
- }
-
- /* If they're off hook, give a busy signal */
- if (ioctl(p->fd, PHONE_HOOKSTATE)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got hunghup, giving busy signal\n");
- ioctl(p->fd, PHONE_BUSY);
- p->cpt = 1;
- }
- p->lastformat = -1;
- p->lastinput = -1;
- p->ministate = 0;
- p->obuflen = 0;
- p->dialtone = 0;
- memset(p->ext, 0, sizeof(p->ext));
- ((struct phone_pvt *)(ast->tech_pvt))->owner = NULL;
- ast_module_unref(ast_module_info->self);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
- ast->tech_pvt = NULL;
- ast_setstate(ast, AST_STATE_DOWN);
- restart_monitor();
- return 0;
-}
-
-static int phone_setup(struct ast_channel *ast)
-{
- struct phone_pvt *p;
- p = ast->tech_pvt;
- ioctl(p->fd, PHONE_CPT_STOP);
- /* Nothing to answering really, just start recording */
- if (ast->rawreadformat == AST_FORMAT_G723_1) {
- /* Prefer g723 */
- ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput != AST_FORMAT_G723_1) {
- p->lastinput = AST_FORMAT_G723_1;
- if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
- ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");
- return -1;
- }
- }
- } else if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
- ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput != AST_FORMAT_SLINEAR) {
- p->lastinput = AST_FORMAT_SLINEAR;
- if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
- ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
- return -1;
- }
- }
- } else if (ast->rawreadformat == AST_FORMAT_ULAW) {
- ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput != AST_FORMAT_ULAW) {
- p->lastinput = AST_FORMAT_ULAW;
- if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
- ast_log(LOG_WARNING, "Failed to set codec to uLaw\n");
- return -1;
- }
- }
- } else if (p->mode == MODE_FXS) {
- ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput != ast->rawreadformat) {
- p->lastinput = ast->rawreadformat;
- if (ioctl(p->fd, PHONE_REC_CODEC, ast->rawreadformat)) {
- ast_log(LOG_WARNING, "Failed to set codec to %d\n",
- ast->rawreadformat);
- return -1;
- }
- }
- } else {
- ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast->rawreadformat));
- return -1;
- }
- if (ioctl(p->fd, PHONE_REC_START)) {
- ast_log(LOG_WARNING, "Failed to start recording\n");
- return -1;
- }
- /* set the DTMF times (the default is too short) */
- ioctl(p->fd, PHONE_SET_TONE_ON_TIME, 300);
- ioctl(p->fd, PHONE_SET_TONE_OFF_TIME, 200);
- return 0;
-}
-
-static int phone_answer(struct ast_channel *ast)
-{
- struct phone_pvt *p;
- p = ast->tech_pvt;
- /* In case it's a LineJack, take it off hook */
- if (p->mode == MODE_FXO) {
- if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK))
- ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast->name, strerror(errno));
- else
- ast_log(LOG_DEBUG, "Took linejack off hook\n");
- }
- phone_setup(ast);
- if (option_debug)
- ast_log(LOG_DEBUG, "phone_answer(%s)\n", ast->name);
- ast->rings = 0;
- ast_setstate(ast, AST_STATE_UP);
- return 0;
-}
-
-#if 0
-static char phone_2digit(char c)
-{
- if (c == 12)
- return '#';
- else if (c == 11)
- return '*';
- else if ((c < 10) && (c >= 0))
- return '0' + c - 1;
- else
- return '?';
-}
-#endif
-
-static struct ast_frame *phone_exception(struct ast_channel *ast)
-{
- int res;
- union telephony_exception phonee;
- struct phone_pvt *p = ast->tech_pvt;
- char digit;
-
- /* Some nice norms */
- p->fr.datalen = 0;
- p->fr.samples = 0;
- p->fr.data = NULL;
- p->fr.src = "Phone";
- p->fr.offset = 0;
- p->fr.mallocd=0;
- p->fr.delivery = ast_tv(0,0);
-
- phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);
- if (phonee.bits.dtmf_ready) {
- if (option_debug)
- ast_log(LOG_DEBUG, "phone_exception(): DTMF\n");
-
- /* We've got a digit -- Just handle this nicely and easily */
- digit = ioctl(p->fd, PHONE_GET_DTMF_ASCII);
- p->fr.subclass = digit;
- p->fr.frametype = AST_FRAME_DTMF;
- return &p->fr;
- }
- if (phonee.bits.hookstate) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Hookstate changed\n");
- res = ioctl(p->fd, PHONE_HOOKSTATE);
- /* See if we've gone on hook, if so, notify by returning NULL */
- if (option_debug)
- ast_log(LOG_DEBUG, "New hookstate: %d\n", res);
- if (!res && (p->mode != MODE_FXO))
- return NULL;
- else {
- if (ast->_state == AST_STATE_RINGING) {
- /* They've picked up the phone */
- p->fr.frametype = AST_FRAME_CONTROL;
- p->fr.subclass = AST_CONTROL_ANSWER;
- phone_setup(ast);
- ast_setstate(ast, AST_STATE_UP);
- return &p->fr;
- } else
- ast_log(LOG_WARNING, "Got off hook in weird state %d\n", ast->_state);
- }
- }
-#if 1
- if (phonee.bits.pstn_ring)
- ast_verbose("Unit is ringing\n");
- if (phonee.bits.caller_id) {
- ast_verbose("We have caller ID\n");
- }
- if (phonee.bits.pstn_wink)
- ast_verbose("Detected Wink\n");
-#endif
- /* Strange -- nothing there.. */
- p->fr.frametype = AST_FRAME_NULL;
- p->fr.subclass = 0;
- return &p->fr;
-}
-
-static struct ast_frame *phone_read(struct ast_channel *ast)
-{
- int res;
- struct phone_pvt *p = ast->tech_pvt;
-
-
- /* Some nice norms */
- p->fr.datalen = 0;
- p->fr.samples = 0;
- p->fr.data = NULL;
- p->fr.src = "Phone";
- p->fr.offset = 0;
- p->fr.mallocd=0;
- p->fr.delivery = ast_tv(0,0);
-
- /* Try to read some data... */
- CHECK_BLOCKING(ast);
- res = read(p->fd, p->buf, PHONE_MAX_BUF);
- ast_clear_flag(ast, AST_FLAG_BLOCKING);
- if (res < 0) {
-#if 0
- if (errno == EAGAIN) {
- ast_log(LOG_WARNING, "Null frame received\n");
- p->fr.frametype = AST_FRAME_NULL;
- p->fr.subclass = 0;
- return &p->fr;
- }
-#endif
- ast_log(LOG_WARNING, "Error reading: %s\n", strerror(errno));
- return NULL;
- }
- p->fr.data = p->buf;
- if (p->mode != MODE_FXS)
- switch(p->buf[0] & 0x3) {
- case '0':
- case '1':
- /* Normal */
- break;
- case '2':
- case '3':
- /* VAD/CNG, only send two words */
- res = 4;
- break;
- }
- p->fr.samples = 240;
- p->fr.datalen = res;
- p->fr.frametype = p->lastinput <= AST_FORMAT_MAX_AUDIO ?
- AST_FRAME_VOICE :
- p->lastinput <= AST_FORMAT_PNG ? AST_FRAME_IMAGE
- : AST_FRAME_VIDEO;
- p->fr.subclass = p->lastinput;
- p->fr.offset = AST_FRIENDLY_OFFSET;
- /* Byteswap from little-endian to native-endian */
- if (p->fr.subclass == AST_FORMAT_SLINEAR)
- ast_frame_byteswap_le(&p->fr);
- return &p->fr;
-}
-
-static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int frlen, int swap)
-{
- int res;
- /* Store as much of the buffer as we can, then write fixed frames */
- int space = sizeof(p->obuf) - p->obuflen;
- /* Make sure we have enough buffer space to store the frame */
- if (space < len)
- len = space;
- if (swap)
- ast_swapcopy_samples(p->obuf+p->obuflen, buf, len/2);
- else
- memcpy(p->obuf + p->obuflen, buf, len);
- p->obuflen += len;
- while(p->obuflen > frlen) {
- res = write(p->fd, p->obuf, frlen);
- if (res != frlen) {
- if (res < 1) {
-/*
- * Card is in non-blocking mode now and it works well now, but there are
- * lot of messages like this. So, this message is temporarily disabled.
- */
- return 0;
- } else {
- ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frlen);
- }
- }
- p->obuflen -= frlen;
- /* Move memory if necessary */
- if (p->obuflen)
- memmove(p->obuf, p->obuf + frlen, p->obuflen);
- }
- return len;
-}
-
-static int phone_send_text(struct ast_channel *ast, const char *text)
-{
- int length = strlen(text);
- return phone_write_buf(ast->tech_pvt, text, length, length, 0) ==
- length ? 0 : -1;
-}
-
-static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct phone_pvt *p = ast->tech_pvt;
- int res;
- int maxfr=0;
- char *pos;
- int sofar;
- int expected;
- int codecset = 0;
- char tmpbuf[4];
- /* Write a frame of (presumably voice) data */
- if (frame->frametype != AST_FRAME_VOICE && p->mode != MODE_FXS) {
- if (frame->frametype != AST_FRAME_IMAGE)
- ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
- return 0;
- }
- if (!(frame->subclass &
- (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) &&
- p->mode != MODE_FXS) {
- ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
- return -1;
- }
-#if 0
- /* If we're not in up mode, go into up mode now */
- if (ast->_state != AST_STATE_UP) {
- ast_setstate(ast, AST_STATE_UP);
- phone_setup(ast);
- }
-#else
- if (ast->_state != AST_STATE_UP) {
- /* Don't try tos end audio on-hook */
- return 0;
- }
-#endif
- if (frame->subclass == AST_FORMAT_G723_1) {
- if (p->lastformat != AST_FORMAT_G723_1) {
- ioctl(p->fd, PHONE_PLAY_STOP);
- ioctl(p->fd, PHONE_REC_STOP);
- if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {
- ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
- return -1;
- }
- if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
- ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
- return -1;
- }
- p->lastformat = AST_FORMAT_G723_1;
- p->lastinput = AST_FORMAT_G723_1;
- /* Reset output buffer */
- p->obuflen = 0;
- codecset = 1;
- }
- if (frame->datalen > 24) {
- ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);
- return -1;
- }
- maxfr = 24;
- } else if (frame->subclass == AST_FORMAT_SLINEAR) {
- if (p->lastformat != AST_FORMAT_SLINEAR) {
- ioctl(p->fd, PHONE_PLAY_STOP);
- ioctl(p->fd, PHONE_REC_STOP);
- if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {
- ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
- return -1;
- }
- if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
- ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
- return -1;
- }
- p->lastformat = AST_FORMAT_SLINEAR;
- p->lastinput = AST_FORMAT_SLINEAR;
- codecset = 1;
- /* Reset output buffer */
- p->obuflen = 0;
- }
- maxfr = 480;
- } else if (frame->subclass == AST_FORMAT_ULAW) {
- if (p->lastformat != AST_FORMAT_ULAW) {
- ioctl(p->fd, PHONE_PLAY_STOP);
- ioctl(p->fd, PHONE_REC_STOP);
- if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
- ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
- return -1;
- }
- if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
- ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
- return -1;
- }
- p->lastformat = AST_FORMAT_ULAW;
- p->lastinput = AST_FORMAT_ULAW;
- codecset = 1;
- /* Reset output buffer */
- p->obuflen = 0;
- }
- maxfr = 240;
- } else {
- if (p->lastformat != frame->subclass) {
- ioctl(p->fd, PHONE_PLAY_STOP);
- ioctl(p->fd, PHONE_REC_STOP);
- if (ioctl(p->fd, PHONE_PLAY_CODEC, frame->subclass)) {
- ast_log(LOG_WARNING, "Unable to set %d mode\n",
- frame->subclass);
- return -1;
- }
- if (ioctl(p->fd, PHONE_REC_CODEC, frame->subclass)) {
- ast_log(LOG_WARNING, "Unable to set %d mode\n",
- frame->subclass);
- return -1;
- }
- p->lastformat = frame->subclass;
- p->lastinput = frame->subclass;
- codecset = 1;
- /* Reset output buffer */
- p->obuflen = 0;
- }
- maxfr = 480;
- }
- if (codecset) {
- ioctl(p->fd, PHONE_REC_DEPTH, 3);
- ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
- if (ioctl(p->fd, PHONE_PLAY_START)) {
- ast_log(LOG_WARNING, "Failed to start playback\n");
- return -1;
- }
- if (ioctl(p->fd, PHONE_REC_START)) {
- ast_log(LOG_WARNING, "Failed to start recording\n");
- return -1;
- }
- }
- /* If we get here, we have a frame of Appropriate data */
- sofar = 0;
- pos = frame->data;
- while(sofar < frame->datalen) {
- /* Write in no more than maxfr sized frames */
- expected = frame->datalen - sofar;
- if (maxfr < expected)
- expected = maxfr;
- /* XXX Internet Phone Jack does not handle the 4-byte VAD frame properly! XXX
- we have to pad it to 24 bytes still. */
- if (frame->datalen == 4) {
- if (p->silencesupression) {
- memset(tmpbuf + 4, 0, sizeof(tmpbuf) - 4);
- memcpy(tmpbuf, frame->data, 4);
- expected = 24;
- res = phone_write_buf(p, tmpbuf, expected, maxfr, 0);
- }
- res = 4;
- expected=4;
- } else {
- int swap = 0;
-#if __BYTE_ORDER == __BIG_ENDIAN
- if (frame->subclass == AST_FORMAT_SLINEAR)
- swap = 1; /* Swap big-endian samples to little-endian as we copy */
-#endif
- res = phone_write_buf(p, pos, expected, maxfr, swap);
- }
- if (res != expected) {
- if ((errno != EAGAIN) && (errno != EINTR)) {
- if (res < 0)
- ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
- /*
- * Card is in non-blocking mode now and it works well now, but there are
- * lot of messages like this. So, this message is temporarily disabled.
- */
-#if 0
- else
- ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
-#endif
- return -1;
- } else /* Pretend it worked */
- res = expected;
- }
- sofar += res;
- pos += res;
- }
- return 0;
-}
-
-static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *context)
-{
- struct ast_channel *tmp;
- struct phone_codec_data codec;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, 0, "Phone/%s", i->dev + 5);
- if (tmp) {
- tmp->tech = cur_tech;
- tmp->fds[0] = i->fd;
- /* XXX Switching formats silently causes kernel panics XXX */
- if (i->mode == MODE_FXS &&
- ioctl(i->fd, PHONE_QUERY_CODEC, &codec) == 0) {
- if (codec.type == LINEAR16)
- tmp->nativeformats =
- tmp->rawreadformat =
- tmp->rawwriteformat =
- AST_FORMAT_SLINEAR;
- else {
- tmp->nativeformats =
- tmp->rawreadformat =
- tmp->rawwriteformat =
- prefformat & ~AST_FORMAT_SLINEAR;
- }
- }
- else {
- tmp->nativeformats = prefformat;
- tmp->rawreadformat = prefformat;
- tmp->rawwriteformat = prefformat;
- }
- /* no need to call ast_setstate: the channel_alloc already did its job */
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->tech_pvt = i;
- ast_copy_string(tmp->context, context, sizeof(tmp->context));
- if (!ast_strlen_zero(i->ext))
- ast_copy_string(tmp->exten, i->ext, sizeof(tmp->exten));
- else
- strcpy(tmp->exten, "s");
- if (!ast_strlen_zero(i->language))
- ast_string_field_set(tmp, language, i->language);
-
- /* Don't use ast_set_callerid() here because it will
- * generate a NewCallerID event before the NewChannel event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
-
- i->owner = tmp;
- ast_module_ref(ast_module_info->self);
- if (state != AST_STATE_DOWN) {
- if (state == AST_STATE_RING) {
- ioctl(tmp->fds[0], PHONE_RINGBACK);
- i->cpt = 1;
- }
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- }
- }
- } else
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- return tmp;
-}
-
-static void phone_mini_packet(struct phone_pvt *i)
-{
- int res;
- char buf[1024];
- /* Ignore stuff we read... */
- res = read(i->fd, buf, sizeof(buf));
- if (res < 1) {
- ast_log(LOG_WARNING, "Read returned %d: %s\n", res, strerror(errno));
- return;
- }
-}
-
-static void phone_check_exception(struct phone_pvt *i)
-{
- int offhook=0;
- char digit[2] = {0 , 0};
- union telephony_exception phonee;
- /* XXX Do something XXX */
-#if 0
- ast_log(LOG_DEBUG, "Exception!\n");
-#endif
- phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);
- if (phonee.bits.dtmf_ready) {
- digit[0] = ioctl(i->fd, PHONE_GET_DTMF_ASCII);
- if (i->mode == MODE_DIALTONE || i->mode == MODE_FXS || i->mode == MODE_SIGMA) {
- ioctl(i->fd, PHONE_PLAY_STOP);
- ioctl(i->fd, PHONE_REC_STOP);
- ioctl(i->fd, PHONE_CPT_STOP);
- i->dialtone = 0;
- if (strlen(i->ext) < AST_MAX_EXTENSION - 1)
- strncat(i->ext, digit, sizeof(i->ext) - strlen(i->ext) - 1);
- if ((i->mode != MODE_FXS ||
- !(phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION)) ||
- !phonee.bits.dtmf_ready) &&
- ast_exists_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
- /* It's a valid extension in its context, get moving! */
- phone_new(i, AST_STATE_RING, i->context);
- /* No need to restart monitor, we are the monitor */
- } else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
- /* There is nothing in the specified extension that can match anymore.
- Try the default */
- if (ast_exists_extension(NULL, "default", i->ext, 1, i->cid_num)) {
- /* Check the default, too... */
- phone_new(i, AST_STATE_RING, "default");
- /* XXX This should probably be justified better XXX */
- } else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {
- /* It's not a valid extension, give a busy signal */
- if (option_debug)
- ast_log(LOG_DEBUG, "%s can't match anything in %s or default\n", i->ext, i->context);
- ioctl(i->fd, PHONE_BUSY);
- i->cpt = 1;
- }
- }
-#if 0
- ast_verbose("Extension is %s\n", i->ext);
-#endif
- }
- }
- if (phonee.bits.hookstate) {
- offhook = ioctl(i->fd, PHONE_HOOKSTATE);
- if (offhook) {
- if (i->mode == MODE_IMMEDIATE) {
- phone_new(i, AST_STATE_RING, i->context);
- } else if (i->mode == MODE_DIALTONE) {
- ast_module_ref(ast_module_info->self);
- /* Reset the extension */
- i->ext[0] = '\0';
- /* Play the dialtone */
- i->dialtone++;
- ioctl(i->fd, PHONE_PLAY_STOP);
- ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
- ioctl(i->fd, PHONE_PLAY_START);
- i->lastformat = -1;
- } else if (i->mode == MODE_SIGMA) {
- ast_module_ref(ast_module_info->self);
- /* Reset the extension */
- i->ext[0] = '\0';
- /* Play the dialtone */
- i->dialtone++;
- ioctl(i->fd, PHONE_DIALTONE);
- }
- } else {
- if (i->dialtone)
- ast_module_unref(ast_module_info->self);
- memset(i->ext, 0, sizeof(i->ext));
- if (i->cpt)
- {
- ioctl(i->fd, PHONE_CPT_STOP);
- i->cpt = 0;
- }
- ioctl(i->fd, PHONE_PLAY_STOP);
- ioctl(i->fd, PHONE_REC_STOP);
- i->dialtone = 0;
- i->lastformat = -1;
- }
- }
- if (phonee.bits.pstn_ring) {
- ast_verbose("Unit is ringing\n");
- phone_new(i, AST_STATE_RING, i->context);
- }
- if (phonee.bits.caller_id)
- ast_verbose("We have caller ID\n");
-
-
-}
-
-static void *do_monitor(void *data)
-{
- fd_set rfds, efds;
- int n, res;
- struct phone_pvt *i;
- int tonepos = 0;
- /* The tone we're playing this round */
- struct timeval tv = {0,0};
- int dotone;
- /* This thread monitors all the frame relay interfaces which are not yet in use
- (and thus do not have a separate thread) indefinitely */
- while (monitor) {
- /* Don't let anybody kill us right away. Nobody should lock the interface list
- and wait for the monitor list, but the other way around is okay. */
- /* Lock the interface list */
- if (ast_mutex_lock(&iflock)) {
- ast_log(LOG_ERROR, "Unable to grab interface lock\n");
- return NULL;
- }
- /* Build the stuff we're going to select on, that is the socket of every
- phone_pvt that does not have an associated owner channel */
- n = -1;
- FD_ZERO(&rfds);
- FD_ZERO(&efds);
- i = iflist;
- dotone = 0;
- while (i) {
- if (FD_ISSET(i->fd, &rfds))
- ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
- if (!i->owner) {
- /* This needs to be watched, as it lacks an owner */
- FD_SET(i->fd, &rfds);
- FD_SET(i->fd, &efds);
- if (i->fd > n)
- n = i->fd;
- if (i->dialtone && i->mode != MODE_SIGMA) {
- /* Remember we're going to have to come back and play
- more dialtones */
- if (ast_tvzero(tv)) {
- /* If we're due for a dialtone, play one */
- if (write(i->fd, DialTone + tonepos, 240) != 240)
- ast_log(LOG_WARNING, "Dial tone write error\n");
- }
- dotone++;
- }
- }
-
- i = i->next;
- }
- /* Okay, now that we know what to do, release the interface lock */
- ast_mutex_unlock(&iflock);
-
- /* Wait indefinitely for something to happen */
- if (dotone && i && i->mode != MODE_SIGMA) {
- /* If we're ready to recycle the time, set it to 30 ms */
- tonepos += 240;
- if (tonepos >= sizeof(DialTone))
- tonepos = 0;
- if (ast_tvzero(tv)) {
- tv = ast_tv(30000, 0);
- }
- res = ast_select(n + 1, &rfds, NULL, &efds, &tv);
- } else {
- res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
- tv = ast_tv(0,0);
- tonepos = 0;
- }
- /* Okay, select has finished. Let's see what happened. */
- if (res < 0) {
- ast_log(LOG_DEBUG, "select return %d: %s\n", res, strerror(errno));
- continue;
- }
- /* If there are no fd's changed, just continue, it's probably time
- to play some more dialtones */
- if (!res)
- continue;
- /* Alright, lock the interface list again, and let's look and see what has
- happened */
- if (ast_mutex_lock(&iflock)) {
- ast_log(LOG_WARNING, "Unable to lock the interface list\n");
- continue;
- }
-
- i = iflist;
- for(; i; i=i->next) {
- if (FD_ISSET(i->fd, &rfds)) {
- if (i->owner) {
- continue;
- }
- phone_mini_packet(i);
- }
- if (FD_ISSET(i->fd, &efds)) {
- if (i->owner) {
- continue;
- }
- phone_check_exception(i);
- }
- }
- ast_mutex_unlock(&iflock);
- }
- return NULL;
-
-}
-
-static int restart_monitor()
-{
- /* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == AST_PTHREADT_STOP)
- return 0;
- if (ast_mutex_lock(&monlock)) {
- ast_log(LOG_WARNING, "Unable to lock monitor\n");
- return -1;
- }
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread != AST_PTHREADT_NULL) {
- if (ast_mutex_lock(&iflock)) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Unable to lock the interface list\n");
- return -1;
- }
- monitor = 0;
- while (pthread_kill(monitor_thread, SIGURG) == 0)
- sched_yield();
- pthread_join(monitor_thread, NULL);
- ast_mutex_unlock(&iflock);
- }
- monitor = 1;
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- return -1;
- }
- ast_mutex_unlock(&monlock);
- return 0;
-}
-
-static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
-{
- /* Make a phone_pvt structure for this interface */
- struct phone_pvt *tmp;
- int flags;
-
- tmp = malloc(sizeof(struct phone_pvt));
- if (tmp) {
- tmp->fd = open(iface, O_RDWR);
- if (tmp->fd < 0) {
- ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
- free(tmp);
- return NULL;
- }
- if (mode == MODE_FXO) {
- if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN))
- ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
- } else {
- if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS))
- if (mode != MODE_FXS)
- ast_log(LOG_DEBUG, "Unable to set port to POTS\n");
- }
- ioctl(tmp->fd, PHONE_PLAY_STOP);
- ioctl(tmp->fd, PHONE_REC_STOP);
- ioctl(tmp->fd, PHONE_RING_STOP);
- ioctl(tmp->fd, PHONE_CPT_STOP);
- if (ioctl(tmp->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
- ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno));
- if (echocancel != AEC_OFF)
- ioctl(tmp->fd, IXJCTL_AEC_START, echocancel);
- if (silencesupression)
- tmp->silencesupression = 1;
-#ifdef PHONE_VAD
- ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);
-#endif
- tmp->mode = mode;
- flags = fcntl(tmp->fd, F_GETFL);
- fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
- tmp->owner = NULL;
- tmp->lastformat = -1;
- tmp->lastinput = -1;
- tmp->ministate = 0;
- memset(tmp->ext, 0, sizeof(tmp->ext));
- ast_copy_string(tmp->language, language, sizeof(tmp->language));
- ast_copy_string(tmp->dev, iface, sizeof(tmp->dev));
- ast_copy_string(tmp->context, context, sizeof(tmp->context));
- tmp->next = NULL;
- tmp->obuflen = 0;
- tmp->dialtone = 0;
- tmp->cpt = 0;
- ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
- ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));
- tmp->txgain = txgain;
- ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);
- tmp->rxgain = rxgain;
- ioctl(tmp->fd, PHONE_REC_VOLUME, tmp->rxgain);
- }
- return tmp;
-}
-
-static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause)
-{
- int oldformat;
- struct phone_pvt *p;
- struct ast_channel *tmp = NULL;
- char *name = data;
-
- /* Search for an unowned channel */
- if (ast_mutex_lock(&iflock)) {
- ast_log(LOG_ERROR, "Unable to lock interface list???\n");
- return NULL;
- }
- p = iflist;
- while(p) {
- if (p->mode == MODE_FXS ||
- format & (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) {
- size_t length = strlen(p->dev + 5);
- if (strncmp(name, p->dev + 5, length) == 0 &&
- !isalnum(name[length])) {
- if (!p->owner) {
- tmp = phone_new(p, AST_STATE_DOWN, p->context);
- break;
- } else
- *cause = AST_CAUSE_BUSY;
- }
- }
- p = p->next;
- }
- ast_mutex_unlock(&iflock);
- restart_monitor();
- if (tmp == NULL) {
- oldformat = format;
- format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
- return NULL;
- }
- }
- return tmp;
-}
-
-/* parse gain value from config file */
-static int parse_gain_value(char *gain_type, char *value)
-{
- float gain;
-
- /* try to scan number */
- if (sscanf(value, "%f", &gain) != 1)
- {
- ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n",
- value, gain_type, config);
- return DEFAULT_GAIN;
- }
-
- /* multiplicate gain by 1.0 gain value */
- gain = gain * (float)DEFAULT_GAIN;
-
- /* percentage? */
- if (value[strlen(value) - 1] == '%')
- return (int)(gain / (float)100);
-
- return (int)gain;
-}
-
-static int __unload_module(void)
-{
- struct phone_pvt *p, *pl;
- /* First, take us out of the channel loop */
- if (cur_tech)
- ast_channel_unregister(cur_tech);
- if (!ast_mutex_lock(&iflock)) {
- /* Hangup all interfaces if they have an owner */
- p = iflist;
- while(p) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- p = p->next;
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- return -1;
- }
- if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread > AST_PTHREADT_NULL) {
- monitor = 0;
- while (pthread_kill(monitor_thread, SIGURG) == 0)
- sched_yield();
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- return -1;
- }
-
- if (!ast_mutex_lock(&iflock)) {
- /* Destroy all the interfaces and free their memory */
- p = iflist;
- while(p) {
- /* Close the socket, assuming it's real */
- if (p->fd > -1)
- close(p->fd);
- pl = p;
- p = p->next;
- /* Free associated memory */
- free(pl);
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
- } else {
- ast_log(LOG_WARNING, "Unable to lock the monitor\n");
- return -1;
- }
-
- return 0;
-}
-
-static int unload_module(void)
-{
- return __unload_module();
-}
-
-static int load_module(void)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- struct phone_pvt *tmp;
- int mode = MODE_IMMEDIATE;
- int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
- cfg = ast_config_load(config);
-
- /* We *must* have a config file otherwise stop immediately */
- if (!cfg) {
- ast_log(LOG_ERROR, "Unable to load config %s\n", config);
- return AST_MODULE_LOAD_DECLINE;
- }
- if (ast_mutex_lock(&iflock)) {
- /* It's a little silly to lock it, but we mind as well just to be sure */
- ast_log(LOG_ERROR, "Unable to lock interface list???\n");
- return AST_MODULE_LOAD_FAILURE;
- }
- v = ast_variable_browse(cfg, "interfaces");
- while(v) {
- /* Create the interface list */
- if (!strcasecmp(v->name, "device")) {
- tmp = mkif(v->value, mode, txgain, rxgain);
- if (tmp) {
- tmp->next = iflist;
- iflist = tmp;
-
- } else {
- ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
- ast_config_destroy(cfg);
- ast_mutex_unlock(&iflock);
- __unload_module();
- return AST_MODULE_LOAD_FAILURE;
- }
- } else if (!strcasecmp(v->name, "silencesupression")) {
- silencesupression = ast_true(v->value);
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(language, v->value, sizeof(language));
- } else if (!strcasecmp(v->name, "callerid")) {
- ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
- } else if (!strcasecmp(v->name, "mode")) {
- if (!strncasecmp(v->value, "di", 2))
- mode = MODE_DIALTONE;
- else if (!strncasecmp(v->value, "sig", 3))
- mode = MODE_SIGMA;
- else if (!strncasecmp(v->value, "im", 2))
- mode = MODE_IMMEDIATE;
- else if (!strncasecmp(v->value, "fxs", 3)) {
- mode = MODE_FXS;
- prefformat = 0x01ff0000; /* All non-voice */
- }
- else if (!strncasecmp(v->value, "fx", 2))
- mode = MODE_FXO;
- else
- ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(context, v->value, sizeof(context));
- } else if (!strcasecmp(v->name, "format")) {
- if (!strcasecmp(v->value, "g723.1")) {
- prefformat = AST_FORMAT_G723_1;
- } else if (!strcasecmp(v->value, "slinear")) {
- if (mode == MODE_FXS)
- prefformat |= AST_FORMAT_SLINEAR;
- else prefformat = AST_FORMAT_SLINEAR;
- } else if (!strcasecmp(v->value, "ulaw")) {
- prefformat = AST_FORMAT_ULAW;
- } else
- ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
- } else if (!strcasecmp(v->name, "echocancel")) {
- if (!strcasecmp(v->value, "off")) {
- echocancel = AEC_OFF;
- } else if (!strcasecmp(v->value, "low")) {
- echocancel = AEC_LOW;
- } else if (!strcasecmp(v->value, "medium")) {
- echocancel = AEC_MED;
- } else if (!strcasecmp(v->value, "high")) {
- echocancel = AEC_HIGH;
- } else
- ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value);
- } else if (!strcasecmp(v->name, "txgain")) {
- txgain = parse_gain_value(v->name, v->value);
- } else if (!strcasecmp(v->name, "rxgain")) {
- rxgain = parse_gain_value(v->name, v->value);
- }
- v = v->next;
- }
- ast_mutex_unlock(&iflock);
-
- if (mode == MODE_FXS) {
- phone_tech_fxs.capabilities = prefformat;
- cur_tech = &phone_tech_fxs;
- } else
- cur_tech = (struct ast_channel_tech *) &phone_tech;
-
- /* Make sure we can register our Adtranphone channel type */
-
- if (ast_channel_register(cur_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
- ast_config_destroy(cfg);
- __unload_module();
- return AST_MODULE_LOAD_FAILURE;
- }
- ast_config_destroy(cfg);
- /* And start the monitor for the first time */
- restart_monitor();
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Linux Telephony API Support");
diff --git a/1.4/channels/chan_sip.c b/1.4/channels/chan_sip.c
deleted file mode 100644
index 3f05f2243..000000000
--- a/1.4/channels/chan_sip.c
+++ /dev/null
@@ -1,18276 +0,0 @@
-/*
- * 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.
- */
-
-/*!
- * \file
- * \brief Implementation of Session Initiation Protocol
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * See Also:
- * \arg \ref AstCREDITS
- *
- * Implementation of RFC 3261 - without S/MIME, TCP and TLS support
- * Configuration file \link Config_sip sip.conf \endlink
- *
- *
- * \todo SIP over TCP
- * \todo SIP over TLS
- * \todo Better support of forking
- * \todo VIA branch tag transaction checking
- * \todo Transaction support
- *
- * \ingroup channel_drivers
- *
- * \par Overview of the handling of SIP sessions
- * The SIP channel handles several types of SIP sessions, or dialogs,
- * not all of them being "telephone calls".
- * - Incoming calls that will be sent to the PBX core
- * - Outgoing calls, generated by the PBX
- * - SIP subscriptions and notifications of states and voicemail messages
- * - SIP registrations, both inbound and outbound
- * - SIP peer management (peerpoke, OPTIONS)
- * - SIP text messages
- *
- * In the SIP channel, there's a list of active SIP dialogs, which includes
- * all of these when they are active. "sip show channels" in the CLI will
- * show most of these, excluding subscriptions which are shown by
- * "sip show subscriptions"
- *
- * \par incoming packets
- * Incoming packets are received in the monitoring thread, then handled by
- * sipsock_read(). This function parses the packet and matches an existing
- * dialog or starts a new SIP dialog.
- *
- * sipsock_read sends the packet to handle_request(), that parses a bit more.
- * if it's a response to an outbound request, it's sent to handle_response().
- * If it is a request, handle_request sends it to one of a list of functions
- * depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc
- * sipsock_read locks the ast_channel if it exists (an active call) and
- * unlocks it after we have processed the SIP message.
- *
- * A new INVITE is sent to handle_request_invite(), that will end up
- * starting a new channel in the PBX, the new channel after that executing
- * in a separate channel thread. This is an incoming "call".
- * When the call is answered, either by a bridged channel or the PBX itself
- * the sip_answer() function is called.
- *
- * The actual media - Video or Audio - is mostly handled by the RTP subsystem
- * in rtp.c
- *
- * \par Outbound calls
- * Outbound calls are set up by the PBX through the sip_request_call()
- * function. After that, they are activated by sip_call().
- *
- * \par Hanging up
- * The PBX issues a hangup on both incoming and outgoing calls through
- * the sip_hangup() function
- *
- * \par Deprecated stuff
- * This is deprecated and will be removed after the 1.4 release
- * - the SIPUSERAGENT dialplan variable
- * - the ALERT_INFO dialplan variable
- */
-
-/*** MODULEINFO
- <depend>res_features</depend>
- ***/
-
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <signal.h>
-#include <sys/signal.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <arpa/inet.h>
-#include <netinet/ip.h>
-#include <regex.h>
-
-#include "asterisk/lock.h"
-#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/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/udptl.h"
-#include "asterisk/acl.h"
-#include "asterisk/manager.h"
-#include "asterisk/callerid.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/dsp.h"
-#include "asterisk/features.h"
-#include "asterisk/srv.h"
-#include "asterisk/astdb.h"
-#include "asterisk/causes.h"
-#include "asterisk/utils.h"
-#include "asterisk/file.h"
-#include "asterisk/astobj.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/monitor.h"
-#include "asterisk/localtime.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/compiler.h"
-#include "asterisk/threadstorage.h"
-#include "asterisk/translate.h"
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define SIPBUFSIZE 512
-
-#define XMIT_ERROR -2
-
-#define VIDEO_CODEC_MASK 0x1fc0000 /*!< Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO */
-#ifndef IPTOS_MINCOST
-#define IPTOS_MINCOST 0x02
-#endif
-
-/* #define VOCAL_DATA_HACK */
-
-#define DEFAULT_DEFAULT_EXPIRY 120
-#define DEFAULT_MIN_EXPIRY 60
-#define DEFAULT_MAX_EXPIRY 3600
-#define DEFAULT_REGISTRATION_TIMEOUT 20
-#define DEFAULT_MAX_FORWARDS "70"
-
-/* guard limit must be larger than guard secs */
-/* guard min must be < 1000, and should be >= 250 */
-#define EXPIRY_GUARD_SECS 15 /*!< How long before expiry do we reregister */
-#define EXPIRY_GUARD_LIMIT 30 /*!< Below here, we use EXPIRY_GUARD_PCT instead of
- EXPIRY_GUARD_SECS */
-#define EXPIRY_GUARD_MIN 500 /*!< This is the minimum guard time applied. If
- GUARD_PCT turns out to be lower than this, it
- will use this time instead.
- This is in milliseconds. */
-#define EXPIRY_GUARD_PCT 0.20 /*!< Percentage of expires timeout to use when
- below EXPIRY_GUARD_LIMIT */
-#define DEFAULT_EXPIRY 900 /*!< Expire slowly */
-
-static int min_expiry = DEFAULT_MIN_EXPIRY; /*!< Minimum accepted registration time */
-static int max_expiry = DEFAULT_MAX_EXPIRY; /*!< Maximum accepted registration time */
-static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
-static int expiry = DEFAULT_EXPIRY;
-
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-#define CALLERID_UNKNOWN "Unknown"
-
-#define DEFAULT_MAXMS 2000 /*!< Qualification: Must be faster than 2 seconds by default */
-#define DEFAULT_FREQ_OK 60 * 1000 /*!< Qualification: How often to check for the host to be up */
-#define DEFAULT_FREQ_NOTOK 10 * 1000 /*!< Qualification: How often to check, if the host is down... */
-
-#define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit Default: 2 * 500 ms in RFC 3261 */
-#define MAX_RETRANS 6 /*!< Try only 6 times for retransmissions, a total of 7 transmissions */
-#define SIP_TRANS_TIMEOUT 32000 /*!< SIP request timeout (rfc 3261) 64*T1
- \todo Use known T1 for timeout (peerpoke)
- */
-#define DEFAULT_TRANS_TIMEOUT -1 /* Use default SIP transaction timeout */
-#define MAX_AUTHTRIES 3 /*!< Try authentication three times, then fail */
-
-#define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
-#define SIP_MAX_LINES 64 /*!< Max amount of lines in SIP attachment (like SDP) */
-#define SIP_MAX_PACKET 4096 /*!< Also from RFC 3261 (2543), should sub headers tho */
-
-#define SDP_MAX_RTPMAP_CODECS 32 /*!< Maximum number of codecs allowed in received SDP */
-
-#define INITIAL_CSEQ 101 /*!< our initial sip sequence number */
-
-/*! \brief Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-static const char config[] = "sip.conf";
-static const char notify_config[] = "sip_notify.conf";
-
-#define RTP 1
-#define NO_RTP 0
-
-/*! \brief Authorization scheme for call transfers
-\note Not a bitfield flag, since there are plans for other modes,
- like "only allow transfers for authenticated devices" */
-enum transfermodes {
- TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */
- TRANSFER_CLOSED, /*!< Allow no SIP transfers */
-};
-
-
-enum sip_result {
- AST_SUCCESS = 0,
- AST_FAILURE = -1,
-};
-
-/*! \brief States for the INVITE transaction, not the dialog
- \note this is for the INVITE that sets up the dialog
-*/
-enum invitestates {
- INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */
- INV_CALLING = 1, /*!< Invite sent, no answer */
- INV_PROCEEDING = 2, /*!< We got/sent 1xx message */
- INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */
- INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */
- INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */
- INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done
- The only way out of this is a BYE from one side */
- INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */
-};
-
-/* Do _NOT_ make any changes to this enum, or the array following it;
- if you think you are doing the right thing, you are probably
- not doing the right thing. If you think there are changes
- needed, get someone else to review them first _before_
- submitting a patch. If these two lists do not match properly
- bad things will happen.
-*/
-
-enum xmittype {
- XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits.
- If it fails, it's critical and will cause a teardown of the session */
- XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */
- XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */
-};
-
-enum parse_register_result {
- PARSE_REGISTER_FAILED,
- PARSE_REGISTER_UPDATE,
- PARSE_REGISTER_QUERY,
-};
-
-enum subscriptiontype {
- NONE = 0,
- XPIDF_XML,
- DIALOG_INFO_XML,
- CPIM_PIDF_XML,
- PIDF_XML,
- MWI_NOTIFICATION
-};
-
-static const struct cfsubscription_types {
- enum subscriptiontype type;
- const char * const event;
- const char * const mediatype;
- const char * const text;
-} subscription_types[] = {
- { NONE, "-", "unknown", "unknown" },
- /* RFC 4235: SIP Dialog event package */
- { DIALOG_INFO_XML, "dialog", "application/dialog-info+xml", "dialog-info+xml" },
- { CPIM_PIDF_XML, "presence", "application/cpim-pidf+xml", "cpim-pidf+xml" }, /* RFC 3863 */
- { PIDF_XML, "presence", "application/pidf+xml", "pidf+xml" }, /* RFC 3863 */
- { XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" }, /* Pre-RFC 3863 with MS additions */
- { MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
-};
-
-/*! \brief SIP Request methods known by Asterisk */
-enum sipmethod {
- SIP_UNKNOWN, /* Unknown response */
- SIP_RESPONSE, /* Not request, response to outbound request */
- SIP_REGISTER,
- SIP_OPTIONS,
- SIP_NOTIFY,
- SIP_INVITE,
- SIP_ACK,
- SIP_PRACK, /* Not supported at all */
- SIP_BYE,
- SIP_REFER,
- SIP_SUBSCRIBE,
- SIP_MESSAGE,
- SIP_UPDATE, /* We can send UPDATE; but not accept it */
- SIP_INFO,
- SIP_CANCEL,
- SIP_PUBLISH, /* Not supported at all */
- SIP_PING, /* Not supported at all, no standard but still implemented out there */
-};
-
-/*! \brief Authentication types - proxy or www authentication
- \note Endpoints, like Asterisk, should always use WWW authentication to
- allow multiple authentications in the same call - to the proxy and
- to the end point.
-*/
-enum sip_auth_type {
- PROXY_AUTH,
- WWW_AUTH,
-};
-
-/*! \brief Authentication result from check_auth* functions */
-enum check_auth_result {
- AUTH_SUCCESSFUL = 0,
- AUTH_CHALLENGE_SENT = 1,
- AUTH_SECRET_FAILED = -1,
- AUTH_USERNAME_MISMATCH = -2,
- AUTH_NOT_FOUND = -3,
- AUTH_FAKE_AUTH = -4,
- AUTH_UNKNOWN_DOMAIN = -5,
- AUTH_PEER_NOT_DYNAMIC = -6,
- AUTH_ACL_FAILED = -7,
-};
-
-/*! \brief States for outbound registrations (with register= lines in sip.conf */
-enum sipregistrystate {
- REG_STATE_UNREGISTERED = 0, /*!< We are not registred */
- REG_STATE_REGSENT, /*!< Registration request sent */
- REG_STATE_AUTHSENT, /*!< We have tried to authenticate */
- REG_STATE_REGISTERED, /*!< Registred and done */
- REG_STATE_REJECTED, /*!< Registration rejected */
- REG_STATE_TIMEOUT, /*!< Registration timed out */
- REG_STATE_NOAUTH, /*!< We have no accepted credentials */
- REG_STATE_FAILED, /*!< Registration failed after several tries */
-};
-
-#define CAN_NOT_CREATE_DIALOG 0
-#define CAN_CREATE_DIALOG 1
-#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2
-
-/*! XXX Note that sip_methods[i].id == i must hold or the code breaks */
-static const struct cfsip_methods {
- enum sipmethod id;
- int need_rtp; /*!< when this is the 'primary' use for a pvt structure, does it need RTP? */
- char * const text;
- int can_create;
-} sip_methods[] = {
- { SIP_UNKNOWN, RTP, "-UNKNOWN-", CAN_CREATE_DIALOG },
- { SIP_RESPONSE, NO_RTP, "SIP/2.0", CAN_NOT_CREATE_DIALOG },
- { SIP_REGISTER, NO_RTP, "REGISTER", CAN_CREATE_DIALOG },
- { SIP_OPTIONS, NO_RTP, "OPTIONS", CAN_CREATE_DIALOG },
- { SIP_NOTIFY, NO_RTP, "NOTIFY", CAN_CREATE_DIALOG },
- { SIP_INVITE, RTP, "INVITE", CAN_CREATE_DIALOG },
- { SIP_ACK, NO_RTP, "ACK", CAN_NOT_CREATE_DIALOG },
- { SIP_PRACK, NO_RTP, "PRACK", CAN_NOT_CREATE_DIALOG },
- { SIP_BYE, NO_RTP, "BYE", CAN_NOT_CREATE_DIALOG },
- { SIP_REFER, NO_RTP, "REFER", CAN_CREATE_DIALOG },
- { SIP_SUBSCRIBE, NO_RTP, "SUBSCRIBE", CAN_CREATE_DIALOG },
- { SIP_MESSAGE, NO_RTP, "MESSAGE", CAN_CREATE_DIALOG },
- { SIP_UPDATE, NO_RTP, "UPDATE", CAN_NOT_CREATE_DIALOG },
- { SIP_INFO, NO_RTP, "INFO", CAN_NOT_CREATE_DIALOG },
- { SIP_CANCEL, NO_RTP, "CANCEL", CAN_NOT_CREATE_DIALOG },
- { SIP_PUBLISH, NO_RTP, "PUBLISH", CAN_CREATE_DIALOG_UNSUPPORTED_METHOD },
- { SIP_PING, NO_RTP, "PING", CAN_CREATE_DIALOG_UNSUPPORTED_METHOD }
-};
-
-/*! Define SIP option tags, used in Require: and Supported: headers
- We need to be aware of these properties in the phones to use
- the replace: header. We should not do that without knowing
- that the other end supports it...
- This is nothing we can configure, we learn by the dialog
- Supported: header on the REGISTER (peer) or the INVITE
- (other devices)
- We are not using many of these today, but will in the future.
- This is documented in RFC 3261
-*/
-#define SUPPORTED 1
-#define NOT_SUPPORTED 0
-
-#define SIP_OPT_REPLACES (1 << 0)
-#define SIP_OPT_100REL (1 << 1)
-#define SIP_OPT_TIMER (1 << 2)
-#define SIP_OPT_EARLY_SESSION (1 << 3)
-#define SIP_OPT_JOIN (1 << 4)
-#define SIP_OPT_PATH (1 << 5)
-#define SIP_OPT_PREF (1 << 6)
-#define SIP_OPT_PRECONDITION (1 << 7)
-#define SIP_OPT_PRIVACY (1 << 8)
-#define SIP_OPT_SDP_ANAT (1 << 9)
-#define SIP_OPT_SEC_AGREE (1 << 10)
-#define SIP_OPT_EVENTLIST (1 << 11)
-#define SIP_OPT_GRUU (1 << 12)
-#define SIP_OPT_TARGET_DIALOG (1 << 13)
-#define SIP_OPT_NOREFERSUB (1 << 14)
-#define SIP_OPT_HISTINFO (1 << 15)
-#define SIP_OPT_RESPRIORITY (1 << 16)
-
-/*! \brief List of well-known SIP options. If we get this in a require,
- we should check the list and answer accordingly. */
-static const struct cfsip_options {
- int id; /*!< Bitmap ID */
- int supported; /*!< Supported by Asterisk ? */
- char * const text; /*!< Text id, as in standard */
-} sip_options[] = { /* XXX used in 3 places */
- /* RFC3891: Replaces: header for transfer */
- { SIP_OPT_REPLACES, SUPPORTED, "replaces" },
- /* One version of Polycom firmware has the wrong label */
- { SIP_OPT_REPLACES, SUPPORTED, "replace" },
- /* RFC3262: PRACK 100% reliability */
- { SIP_OPT_100REL, NOT_SUPPORTED, "100rel" },
- /* RFC4028: SIP Session Timers */
- { SIP_OPT_TIMER, NOT_SUPPORTED, "timer" },
- /* RFC3959: SIP Early session support */
- { SIP_OPT_EARLY_SESSION, NOT_SUPPORTED, "early-session" },
- /* RFC3911: SIP Join header support */
- { SIP_OPT_JOIN, NOT_SUPPORTED, "join" },
- /* RFC3327: Path support */
- { SIP_OPT_PATH, NOT_SUPPORTED, "path" },
- /* RFC3840: Callee preferences */
- { SIP_OPT_PREF, NOT_SUPPORTED, "pref" },
- /* RFC3312: Precondition support */
- { SIP_OPT_PRECONDITION, NOT_SUPPORTED, "precondition" },
- /* RFC3323: Privacy with proxies*/
- { SIP_OPT_PRIVACY, NOT_SUPPORTED, "privacy" },
- /* RFC4092: Usage of the SDP ANAT Semantics in the SIP */
- { SIP_OPT_SDP_ANAT, NOT_SUPPORTED, "sdp-anat" },
- /* RFC3329: Security agreement mechanism */
- { SIP_OPT_SEC_AGREE, NOT_SUPPORTED, "sec_agree" },
- /* SIMPLE events: RFC4662 */
- { SIP_OPT_EVENTLIST, NOT_SUPPORTED, "eventlist" },
- /* GRUU: Globally Routable User Agent URI's */
- { SIP_OPT_GRUU, NOT_SUPPORTED, "gruu" },
- /* RFC4538: Target-dialog */
- { SIP_OPT_TARGET_DIALOG,NOT_SUPPORTED, "tdialog" },
- /* Disable the REFER subscription, RFC 4488 */
- { SIP_OPT_NOREFERSUB, NOT_SUPPORTED, "norefersub" },
- /* ietf-sip-history-info-06.txt */
- { SIP_OPT_HISTINFO, NOT_SUPPORTED, "histinfo" },
- /* ietf-sip-resource-priority-10.txt */
- { SIP_OPT_RESPRIORITY, NOT_SUPPORTED, "resource-priority" },
-};
-
-
-/*! \brief SIP Methods we support */
-#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
-
-/*! \brief SIP Extensions we support */
-#define SUPPORTED_EXTENSIONS "replaces"
-
-/*! \brief Standard SIP port from RFC 3261. DO NOT CHANGE THIS */
-#define STANDARD_SIP_PORT 5060
-/* Note: in many SIP headers, absence of a port number implies port 5060,
- * and this is why we cannot change the above constant.
- * There is a limited number of places in asterisk where we could,
- * in principle, use a different "default" port number, but
- * we do not support this feature at the moment.
- */
-
-/* Default values, set and reset in reload_config before reading configuration */
-/* These are default values in the source. There are other recommended values in the
- sip.conf.sample for new installations. These may differ to keep backwards compatibility,
- yet encouraging new behaviour on new installations
- */
-#define DEFAULT_CONTEXT "default"
-#define DEFAULT_MOHINTERPRET "default"
-#define DEFAULT_MOHSUGGEST ""
-#define DEFAULT_VMEXTEN "asterisk"
-#define DEFAULT_CALLERID "asterisk"
-#define DEFAULT_NOTIFYMIME "application/simple-message-summary"
-#define DEFAULT_MWITIME 10
-#define DEFAULT_ALLOWGUEST TRUE
-#define DEFAULT_SRVLOOKUP TRUE /*!< Recommended setting is ON */
-#define DEFAULT_COMPACTHEADERS FALSE
-#define DEFAULT_TOS_SIP 0 /*!< Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions. */
-#define DEFAULT_TOS_AUDIO 0 /*!< Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions. */
-#define DEFAULT_TOS_VIDEO 0 /*!< Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions. */
-#define DEFAULT_ALLOW_EXT_DOM TRUE
-#define DEFAULT_REALM "asterisk"
-#define DEFAULT_NOTIFYRINGING TRUE
-#define DEFAULT_PEDANTIC FALSE
-#define DEFAULT_AUTOCREATEPEER FALSE
-#define DEFAULT_QUALIFY FALSE
-#define DEFAULT_T1MIN 100 /*!< 100 MS for minimal roundtrip time */
-#define DEFAULT_MAX_CALL_BITRATE (384) /*!< Max bitrate for video */
-#ifndef DEFAULT_USERAGENT
-#define DEFAULT_USERAGENT "Asterisk PBX" /*!< Default Useragent: header unless re-defined in sip.conf */
-#endif
-
-
-/* Default setttings are used as a channel setting and as a default when
- configuring devices */
-static char default_context[AST_MAX_CONTEXT];
-static char default_subscribecontext[AST_MAX_CONTEXT];
-static char default_language[MAX_LANGUAGE];
-static char default_callerid[AST_MAX_EXTENSION];
-static char default_fromdomain[AST_MAX_EXTENSION];
-static char default_notifymime[AST_MAX_EXTENSION];
-static int default_qualify; /*!< Default Qualify= setting */
-static char default_vmexten[AST_MAX_EXTENSION];
-static char default_mohinterpret[MAX_MUSICCLASS]; /*!< Global setting for moh class to use when put on hold */
-static char default_mohsuggest[MAX_MUSICCLASS]; /*!< Global setting for moh class to suggest when putting
- * a bridged channel on hold */
-static int default_maxcallbitrate; /*!< Maximum bitrate for call */
-static struct ast_codec_pref default_prefs; /*!< Default codec prefs */
-
-/* Global settings only apply to the channel */
-static int global_directrtpsetup; /*!< Enable support for Direct RTP setup (no re-invites) */
-static int global_limitonpeers; /*!< Match call limit on peers only */
-static int global_rtautoclear;
-static int global_notifyringing; /*!< Send notifications on ringing */
-static int global_notifyhold; /*!< Send notifications on hold */
-static int global_alwaysauthreject; /*!< Send 401 Unauthorized for all failing requests */
-static int srvlookup; /*!< SRV Lookup on or off. Default is on */
-static int pedanticsipchecking; /*!< Extra checking ? Default off */
-static int autocreatepeer; /*!< Auto creation of peers at registration? Default off. */
-static int global_relaxdtmf; /*!< Relax DTMF */
-static int global_rtptimeout; /*!< Time out call if no RTP */
-static int global_rtpholdtimeout;
-static int global_rtpkeepalive; /*!< Send RTP keepalives */
-static int global_reg_timeout;
-static int global_regattempts_max; /*!< Registration attempts before giving up */
-static int global_allowguest; /*!< allow unauthenticated users/peers to connect? */
-static int global_allowsubscribe; /*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE
- the global setting is in globals_flags[1] */
-static int global_mwitime; /*!< Time between MWI checks for peers */
-static unsigned int global_tos_sip; /*!< IP type of service for SIP packets */
-static unsigned int global_tos_audio; /*!< IP type of service for audio RTP packets */
-static unsigned int global_tos_video; /*!< IP type of service for video RTP packets */
-static int compactheaders; /*!< send compact sip headers */
-static int recordhistory; /*!< Record SIP history. Off by default */
-static int dumphistory; /*!< Dump history to verbose before destroying SIP dialog */
-static char global_realm[MAXHOSTNAMELEN]; /*!< Default realm */
-static char global_regcontext[AST_MAX_CONTEXT]; /*!< Context for auto-extensions */
-static char global_useragent[AST_MAX_EXTENSION]; /*!< Useragent for the SIP channel */
-static int allow_external_domains; /*!< Accept calls to external SIP domains? */
-static int global_callevents; /*!< Whether we send manager events or not */
-static int global_t1min; /*!< T1 roundtrip time minimum */
-static int global_autoframing; /*!< Turn autoframing on or off. */
-static enum transfermodes global_allowtransfer; /*!< SIP Refer restriction scheme */
-
-static int global_matchexterniplocally; /*!< Match externip/externhost setting against localnet setting */
-
-/*! \brief Codecs that we support by default: */
-static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
-
-/* Object counters */
-static int suserobjs = 0; /*!< Static users */
-static int ruserobjs = 0; /*!< Realtime users */
-static int speerobjs = 0; /*!< Statis peers */
-static int rpeerobjs = 0; /*!< Realtime peers */
-static int apeerobjs = 0; /*!< Autocreated peer objects */
-static int regobjs = 0; /*!< Registry objects */
-
-static struct ast_flags global_flags[2] = {{0}}; /*!< global SIP_ flags */
-
-/*! \brief Protect the SIP dialog list (of sip_pvt's) */
-AST_MUTEX_DEFINE_STATIC(iflock);
-
-/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(netlock);
-
-AST_MUTEX_DEFINE_STATIC(monlock);
-
-AST_MUTEX_DEFINE_STATIC(sip_reload_lock);
-
-/*! \brief This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-
-static int sip_reloading = FALSE; /*!< Flag for avoiding multiple reloads at the same time */
-static enum channelreloadreason sip_reloadreason; /*!< Reason for last reload/load of configuration */
-
-static struct sched_context *sched; /*!< The scheduling context */
-static struct io_context *io; /*!< The IO context */
-static int *sipsock_read_id; /*!< ID of IO entry for sipsock FD */
-
-#define DEC_CALL_LIMIT 0
-#define INC_CALL_LIMIT 1
-#define DEC_CALL_RINGING 2
-#define INC_CALL_RINGING 3
-
-/*! \brief sip_request: The data grabbed from the UDP socket */
-struct sip_request {
- char *rlPart1; /*!< SIP Method Name or "SIP/2.0" protocol version */
- char *rlPart2; /*!< The Request URI or Response Status */
- int len; /*!< Length */
- int headers; /*!< # of SIP Headers */
- int method; /*!< Method of this request */
- int lines; /*!< Body Content */
- unsigned int flags; /*!< SIP_PKT Flags for this packet */
- char *header[SIP_MAX_HEADERS];
- char *line[SIP_MAX_LINES];
- char data[SIP_MAX_PACKET];
- unsigned int sdp_start; /*!< the line number where the SDP begins */
- unsigned int sdp_end; /*!< the line number where the SDP ends */
-};
-
-/*
- * A sip packet is stored into the data[] buffer, with the header followed
- * by an empty line and the body of the message.
- * On outgoing packets, data is accumulated in data[] with len reflecting
- * the next available byte, headers and lines count the number of lines
- * in both parts. There are no '\0' in data[0..len-1].
- *
- * On received packet, the input read from the socket is copied into data[],
- * len is set and the string is NUL-terminated. Then a parser fills up
- * the other fields -header[] and line[] to point to the lines of the
- * message, rlPart1 and rlPart2 parse the first lnie as below:
- *
- * Requests have in the first line METHOD URI SIP/2.0
- * rlPart1 = method; rlPart2 = uri;
- * Responses have in the first line SIP/2.0 code description
- * rlPart1 = SIP/2.0; rlPart2 = code + description;
- *
- */
-
-/*! \brief structure used in transfers */
-struct sip_dual {
- struct ast_channel *chan1; /*!< First channel involved */
- struct ast_channel *chan2; /*!< Second channel involved */
- struct sip_request req; /*!< Request that caused the transfer (REFER) */
- int seqno; /*!< Sequence number */
-};
-
-struct sip_pkt;
-
-/*! \brief Parameters to the transmit_invite function */
-struct sip_invite_param {
- const char *distinctive_ring; /*!< Distinctive ring header */
- int addsipheaders; /*!< Add extra SIP headers */
- const char *uri_options; /*!< URI options to add to the URI */
- const char *vxml_url; /*!< VXML url for Cisco phones */
- char *auth; /*!< Authentication */
- char *authheader; /*!< Auth header */
- enum sip_auth_type auth_type; /*!< Authentication type */
- const char *replaces; /*!< Replaces header for call transfers */
- int transfer; /*!< Flag - is this Invite part of a SIP transfer? (invite/replaces) */
-};
-
-/*! \brief Structure to save routing information for a SIP session */
-struct sip_route {
- struct sip_route *next;
- char hop[0];
-};
-
-/*! \brief Modes for SIP domain handling in the PBX */
-enum domain_mode {
- SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */
- SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */
-};
-
-/*! \brief Domain data structure.
- \note In the future, we will connect this to a configuration tree specific
- for this domain
-*/
-struct domain {
- char domain[MAXHOSTNAMELEN]; /*!< SIP domain we are responsible for */
- char context[AST_MAX_EXTENSION]; /*!< Incoming context for this domain */
- enum domain_mode mode; /*!< How did we find this domain? */
- AST_LIST_ENTRY(domain) list; /*!< List mechanics */
-};
-
-static AST_LIST_HEAD_STATIC(domain_list, domain); /*!< The SIP domain list */
-
-
-/*! \brief sip_history: Structure for saving transactions within a SIP dialog */
-struct sip_history {
- AST_LIST_ENTRY(sip_history) list;
- char event[0]; /* actually more, depending on needs */
-};
-
-AST_LIST_HEAD_NOLOCK(sip_history_head, sip_history); /*!< history list, entry in sip_pvt */
-
-/*! \brief sip_auth: Credentials for authentication to other SIP services */
-struct sip_auth {
- char realm[AST_MAX_EXTENSION]; /*!< Realm in which these credentials are valid */
- char username[256]; /*!< Username */
- char secret[256]; /*!< Secret */
- char md5secret[256]; /*!< MD5Secret */
- struct sip_auth *next; /*!< Next auth structure in list */
-};
-
-/*--- Various flags for the flags field in the pvt structure */
-#define SIP_ALREADYGONE (1 << 0) /*!< Whether or not we've already been destroyed by our peer */
-#define SIP_NEEDDESTROY (1 << 1) /*!< if we need to be destroyed by the monitor thread */
-#define SIP_NOVIDEO (1 << 2) /*!< Didn't get video in invite, don't offer */
-#define SIP_RINGING (1 << 3) /*!< Have sent 180 ringing */
-#define SIP_PROGRESS_SENT (1 << 4) /*!< Have sent 183 message progress */
-#define SIP_NEEDREINVITE (1 << 5) /*!< Do we need to send another reinvite? */
-#define SIP_PENDINGBYE (1 << 6) /*!< Need to send bye after we ack? */
-#define SIP_GOTREFER (1 << 7) /*!< Got a refer? */
-#define SIP_PROMISCREDIR (1 << 8) /*!< Promiscuous redirection */
-#define SIP_TRUSTRPID (1 << 9) /*!< Trust RPID headers? */
-#define SIP_USEREQPHONE (1 << 10) /*!< Add user=phone to numeric URI. Default off */
-#define SIP_REALTIME (1 << 11) /*!< Flag for realtime users */
-#define SIP_USECLIENTCODE (1 << 12) /*!< Trust X-ClientCode info message */
-#define SIP_OUTGOING (1 << 13) /*!< Direction of the last transaction in this dialog */
-#define SIP_FREE_BIT (1 << 14) /*!< ---- */
-#define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) /*!< Do not hangup at first ast_hangup */
-#define SIP_DTMF (3 << 16) /*!< DTMF Support: four settings, uses two bits */
-#define SIP_DTMF_RFC2833 (0 << 16) /*!< DTMF Support: RTP DTMF - "rfc2833" */
-#define SIP_DTMF_INBAND (1 << 16) /*!< DTMF Support: Inband audio, only for ULAW/ALAW - "inband" */
-#define SIP_DTMF_INFO (2 << 16) /*!< DTMF Support: SIP Info messages - "info" */
-#define SIP_DTMF_AUTO (3 << 16) /*!< DTMF Support: AUTO switch between rfc2833 and in-band DTMF */
-/* NAT settings */
-#define SIP_NAT (3 << 18) /*!< four settings, uses two bits */
-#define SIP_NAT_NEVER (0 << 18) /*!< No nat support */
-#define SIP_NAT_RFC3581 (1 << 18) /*!< NAT RFC3581 */
-#define SIP_NAT_ROUTE (2 << 18) /*!< NAT Only ROUTE */
-#define SIP_NAT_ALWAYS (3 << 18) /*!< NAT Both ROUTE and RFC3581 */
-/* re-INVITE related settings */
-#define SIP_REINVITE (7 << 20) /*!< three bits used */
-#define SIP_CAN_REINVITE (1 << 20) /*!< allow peers to be reinvited to send media directly p2p */
-#define SIP_CAN_REINVITE_NAT (2 << 20) /*!< allow media reinvite when new peer is behind NAT */
-#define SIP_REINVITE_UPDATE (4 << 20) /*!< use UPDATE (RFC3311) when reinviting this peer */
-/* "insecure" settings */
-#define SIP_INSECURE_PORT (1 << 23) /*!< don't require matching port for incoming requests */
-#define SIP_INSECURE_INVITE (1 << 24) /*!< don't require authentication for incoming INVITEs */
-/* Sending PROGRESS in-band settings */
-#define SIP_PROG_INBAND (3 << 25) /*!< three settings, uses two bits */
-#define SIP_PROG_INBAND_NEVER (0 << 25)
-#define SIP_PROG_INBAND_NO (1 << 25)
-#define SIP_PROG_INBAND_YES (2 << 25)
-#define SIP_NO_HISTORY (1 << 27) /*!< Suppress recording request/response history */
-#define SIP_CALL_LIMIT (1 << 28) /*!< Call limit enforced for this call */
-#define SIP_SENDRPID (1 << 29) /*!< Remote Party-ID Support */
-#define SIP_INC_COUNT (1 << 30) /*!< Did this connection increment the counter of in-use calls? */
-#define SIP_G726_NONSTANDARD (1 << 31) /*!< Use non-standard packing for G726-32 data */
-
-#define SIP_FLAGS_TO_COPY \
- (SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \
- SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \
- SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
-
-/*--- a new page of flags (for flags[1] */
-/* realtime flags */
-#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0)
-#define SIP_PAGE2_RTUPDATE (1 << 1)
-#define SIP_PAGE2_RTAUTOCLEAR (1 << 2)
-#define SIP_PAGE2_RT_FROMCONTACT (1 << 4)
-#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5)
-/* Space for addition of other realtime flags in the future */
-#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) /*!< D: Unsent state pending change exists */
-#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10)
-#define SIP_PAGE2_DEBUG (3 << 11)
-#define SIP_PAGE2_DEBUG_CONFIG (1 << 11)
-#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12)
-#define SIP_PAGE2_DYNAMIC (1 << 13) /*!< Dynamic Peers register with Asterisk */
-#define SIP_PAGE2_SELFDESTRUCT (1 << 14) /*!< Automatic peers need to destruct themselves */
-#define SIP_PAGE2_VIDEOSUPPORT (1 << 15)
-#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) /*!< Allow subscriptions from this peer? */
-#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) /*!< Allow overlap dialing ? */
-#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) /*!< Only issue MWI notification if subscribed to */
-#define SIP_PAGE2_INC_RINGING (1 << 19) /*!< Did this connection increment the counter of in-use calls? */
-#define SIP_PAGE2_T38SUPPORT (7 << 20) /*!< T38 Fax Passthrough Support */
-#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) /*!< 20: T38 Fax Passthrough Support */
-#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) /*!< 21: T38 Fax Passthrough Support (not implemented) */
-#define SIP_PAGE2_T38SUPPORT_TCP (4 << 20) /*!< 22: T38 Fax Passthrough Support (not implemented) */
-#define SIP_PAGE2_CALL_ONHOLD (3 << 23) /*!< Call states */
-#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) /*!< 23: Active hold */
-#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) /*!< 23: One directional hold */
-#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) /*!< 23: Inactive hold */
-#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) /*!< 25: ???? */
-#define SIP_PAGE2_BUGGY_MWI (1 << 26) /*!< 26: Buggy CISCO MWI fix */
-#define SIP_PAGE2_OUTGOING_CALL (1 << 27) /*!< 27: Is this an outgoing call? */
-
-#define SIP_PAGE2_FLAGS_TO_COPY \
- (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \
- SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI)
-
-/* SIP packet flags */
-#define SIP_PKT_DEBUG (1 << 0) /*!< Debug this packet */
-#define SIP_PKT_WITH_TOTAG (1 << 1) /*!< This packet has a to-tag */
-#define SIP_PKT_IGNORE (1 << 2) /*!< This is a re-transmit, ignore it */
-#define SIP_PKT_IGNORE_RESP (1 << 3) /*!< Resp ignore - ??? */
-#define SIP_PKT_IGNORE_REQ (1 << 4) /*!< Req ignore - ??? */
-
-/* T.38 set of flags */
-#define T38FAX_FILL_BIT_REMOVAL (1 << 0) /*!< Default: 0 (unset)*/
-#define T38FAX_TRANSCODING_MMR (1 << 1) /*!< Default: 0 (unset)*/
-#define T38FAX_TRANSCODING_JBIG (1 << 2) /*!< Default: 0 (unset)*/
-/* Rate management */
-#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3)
-#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) /*!< Unset for transferredTCF (UDPTL), set for localTCF (TPKT) */
-/* UDP Error correction */
-#define T38FAX_UDP_EC_NONE (0 << 4) /*!< two bits, if unset NO t38UDPEC field in T38 SDP*/
-#define T38FAX_UDP_EC_FEC (1 << 4) /*!< Set for t38UDPFEC */
-#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) /*!< Set for t38UDPRedundancy */
-/* T38 Spec version */
-#define T38FAX_VERSION (3 << 6) /*!< two bits, 2 values so far, up to 4 values max */
-#define T38FAX_VERSION_0 (0 << 6) /*!< Version 0 */
-#define T38FAX_VERSION_1 (1 << 6) /*!< Version 1 */
-/* Maximum Fax Rate */
-#define T38FAX_RATE_2400 (1 << 8) /*!< 2400 bps t38FaxRate */
-#define T38FAX_RATE_4800 (1 << 9) /*!< 4800 bps t38FaxRate */
-#define T38FAX_RATE_7200 (1 << 10) /*!< 7200 bps t38FaxRate */
-#define T38FAX_RATE_9600 (1 << 11) /*!< 9600 bps t38FaxRate */
-#define T38FAX_RATE_12000 (1 << 12) /*!< 12000 bps t38FaxRate */
-#define T38FAX_RATE_14400 (1 << 13) /*!< 14400 bps t38FaxRate */
-
-/*!< This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate */
-static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600;
-
-#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
-#define sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
-#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)
-
-/*! \brief T38 States for a call */
-enum t38state {
- T38_DISABLED = 0, /*!< Not enabled */
- T38_LOCAL_DIRECT, /*!< Offered from local */
- T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */
- T38_PEER_DIRECT, /*!< Offered from peer */
- T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */
- T38_ENABLED /*!< Negotiated (enabled) */
-};
-
-/*! \brief T.38 channel settings (at some point we need to make this alloc'ed */
-struct t38properties {
- struct ast_flags t38support; /*!< Flag for udptl, rtp or tcp support for this session */
- int capability; /*!< Our T38 capability */
- int peercapability; /*!< Peers T38 capability */
- int jointcapability; /*!< Supported T38 capability at both ends */
- enum t38state state; /*!< T.38 state */
-};
-
-/*! \brief Parameters to know status of transfer */
-enum referstatus {
- REFER_IDLE, /*!< No REFER is in progress */
- REFER_SENT, /*!< Sent REFER to transferee */
- REFER_RECEIVED, /*!< Received REFER from transferer */
- REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */
- REFER_ACCEPTED, /*!< Accepted by transferee */
- REFER_RINGING, /*!< Target Ringing */
- REFER_200OK, /*!< Answered by transfer target */
- REFER_FAILED, /*!< REFER declined - go on */
- REFER_NOAUTH /*!< We had no auth for REFER */
-};
-
-static const struct c_referstatusstring {
- enum referstatus status;
- char *text;
-} referstatusstrings[] = {
- { REFER_IDLE, "<none>" },
- { REFER_SENT, "Request sent" },
- { REFER_RECEIVED, "Request received" },
- { REFER_ACCEPTED, "Accepted" },
- { REFER_RINGING, "Target ringing" },
- { REFER_200OK, "Done" },
- { REFER_FAILED, "Failed" },
- { REFER_NOAUTH, "Failed - auth failure" }
-} ;
-
-/*! \brief Structure to handle SIP transfers. Dynamically allocated when needed */
-/* OEJ: Should be moved to string fields */
-struct sip_refer {
- char refer_to[AST_MAX_EXTENSION]; /*!< Place to store REFER-TO extension */
- char refer_to_domain[AST_MAX_EXTENSION]; /*!< Place to store REFER-TO domain */
- char refer_to_urioption[AST_MAX_EXTENSION]; /*!< Place to store REFER-TO uri options */
- char refer_to_context[AST_MAX_EXTENSION]; /*!< Place to store REFER-TO context */
- char referred_by[AST_MAX_EXTENSION]; /*!< Place to store REFERRED-BY extension */
- char referred_by_name[AST_MAX_EXTENSION]; /*!< Place to store REFERRED-BY extension */
- char refer_contact[AST_MAX_EXTENSION]; /*!< Place to store Contact info from a REFER extension */
- char replaces_callid[SIPBUFSIZE]; /*!< Replace info: callid */
- char replaces_callid_totag[SIPBUFSIZE/2]; /*!< Replace info: to-tag */
- char replaces_callid_fromtag[SIPBUFSIZE/2]; /*!< Replace info: from-tag */
- struct sip_pvt *refer_call; /*!< Call we are referring */
- int attendedtransfer; /*!< Attended or blind transfer? */
- int localtransfer; /*!< Transfer to local domain? */
- enum referstatus status; /*!< REFER status */
-};
-
-/*! \brief sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe */
-static struct sip_pvt {
- ast_mutex_t lock; /*!< Dialog private lock */
- int method; /*!< SIP method that opened this dialog */
- enum invitestates invitestate; /*!< The state of the INVITE transaction only */
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(callid); /*!< Global CallID */
- AST_STRING_FIELD(randdata); /*!< Random data */
- AST_STRING_FIELD(accountcode); /*!< Account code */
- AST_STRING_FIELD(realm); /*!< Authorization realm */
- AST_STRING_FIELD(nonce); /*!< Authorization nonce */
- AST_STRING_FIELD(opaque); /*!< Opaque nonsense */
- AST_STRING_FIELD(qop); /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
- AST_STRING_FIELD(domain); /*!< Authorization domain */
- AST_STRING_FIELD(from); /*!< The From: header */
- AST_STRING_FIELD(useragent); /*!< User agent in SIP request */
- AST_STRING_FIELD(exten); /*!< Extension where to start */
- AST_STRING_FIELD(context); /*!< Context for this call */
- AST_STRING_FIELD(subscribecontext); /*!< Subscribecontext */
- AST_STRING_FIELD(subscribeuri); /*!< Subscribecontext */
- AST_STRING_FIELD(fromdomain); /*!< Domain to show in the from field */
- AST_STRING_FIELD(fromuser); /*!< User to show in the user field */
- AST_STRING_FIELD(fromname); /*!< Name to show in the user field */
- AST_STRING_FIELD(tohost); /*!< Host we should put in the "to" field */
- AST_STRING_FIELD(language); /*!< Default language for this call */
- AST_STRING_FIELD(mohinterpret); /*!< MOH class to use when put on hold */
- AST_STRING_FIELD(mohsuggest); /*!< MOH class to suggest when putting a peer on hold */
- AST_STRING_FIELD(rdnis); /*!< Referring DNIS */
- AST_STRING_FIELD(theirtag); /*!< Their tag */
- AST_STRING_FIELD(username); /*!< [user] name */
- AST_STRING_FIELD(peername); /*!< [peer] name, not set if [user] */
- AST_STRING_FIELD(authname); /*!< Who we use for authentication */
- AST_STRING_FIELD(uri); /*!< Original requested URI */
- AST_STRING_FIELD(okcontacturi); /*!< URI from the 200 OK on INVITE */
- AST_STRING_FIELD(peersecret); /*!< Password */
- AST_STRING_FIELD(peermd5secret);
- AST_STRING_FIELD(cid_num); /*!< Caller*ID number */
- AST_STRING_FIELD(cid_name); /*!< Caller*ID name */
- AST_STRING_FIELD(via); /*!< Via: header */
- AST_STRING_FIELD(fullcontact); /*!< The Contact: that the UA registers with us */
- AST_STRING_FIELD(our_contact); /*!< Our contact header */
- AST_STRING_FIELD(rpid); /*!< Our RPID header */
- AST_STRING_FIELD(rpid_from); /*!< Our RPID From header */
- );
- unsigned int ocseq; /*!< Current outgoing seqno */
- unsigned int icseq; /*!< Current incoming seqno */
- ast_group_t callgroup; /*!< Call group */
- ast_group_t pickupgroup; /*!< Pickup group */
- int lastinvite; /*!< Last Cseq of invite */
- int lastnoninvite; /*!< Last Cseq of non-invite */
- struct ast_flags flags[2]; /*!< SIP_ flags */
- int timer_t1; /*!< SIP timer T1, ms rtt */
- unsigned int sipoptions; /*!< Supported SIP options on the other end */
- struct ast_codec_pref prefs; /*!< codec prefs */
- int capability; /*!< Special capability (codec) */
- int jointcapability; /*!< Supported capability at both ends (codecs) */
- int peercapability; /*!< Supported peer capability */
- int prefcodec; /*!< Preferred codec (outbound only) */
- int noncodeccapability; /*!< DTMF RFC2833 telephony-event */
- int jointnoncodeccapability; /*!< Joint Non codec capability */
- int redircodecs; /*!< Redirect codecs */
- int maxcallbitrate; /*!< Maximum Call Bitrate for Video Calls */
- struct t38properties t38; /*!< T38 settings */
- struct sockaddr_in udptlredirip; /*!< Where our T.38 UDPTL should be going if not to us */
- struct ast_udptl *udptl; /*!< T.38 UDPTL session */
- int callingpres; /*!< Calling presentation */
- int authtries; /*!< Times we've tried to authenticate */
- int expiry; /*!< How long we take to expire */
- long branch; /*!< The branch identifier of this session */
- char tag[11]; /*!< Our tag for this session */
- int sessionid; /*!< SDP Session ID */
- int sessionversion; /*!< SDP Session Version */
- struct sockaddr_in sa; /*!< Our peer */
- struct sockaddr_in redirip; /*!< Where our RTP should be going if not to us */
- struct sockaddr_in vredirip; /*!< Where our Video RTP should be going if not to us */
- time_t lastrtprx; /*!< Last RTP received */
- time_t lastrtptx; /*!< Last RTP sent */
- int rtptimeout; /*!< RTP timeout time */
- struct sockaddr_in recv; /*!< Received as */
- struct in_addr ourip; /*!< Our IP */
- struct ast_channel *owner; /*!< Who owns us (if we have an owner) */
- struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */
- int route_persistant; /*!< Is this the "real" route? */
- struct sip_auth *peerauth; /*!< Realm authentication */
- int noncecount; /*!< Nonce-count */
- char lastmsg[256]; /*!< Last Message sent/received */
- int amaflags; /*!< AMA Flags */
- int pendinginvite; /*!< Any pending INVITE or state NOTIFY (in subscribe pvt's) ? (seqno of this) */
- struct sip_request initreq; /*!< Request that opened the latest transaction
- within this SIP dialog */
-
- int maxtime; /*!< Max time for first response */
- int initid; /*!< Auto-congest ID if appropriate (scheduler) */
- int waitid; /*!< Wait ID for scheduler after 491 or other delays */
- int autokillid; /*!< Auto-kill ID (scheduler) */
- enum transfermodes allowtransfer; /*!< REFER: restriction scheme */
- struct sip_refer *refer; /*!< REFER: SIP transfer data structure */
- enum subscriptiontype subscribed; /*!< SUBSCRIBE: Is this dialog a subscription? */
- int stateid; /*!< SUBSCRIBE: ID for devicestate subscriptions */
- int laststate; /*!< SUBSCRIBE: Last known extension state */
- int dialogver; /*!< SUBSCRIBE: Version for subscription dialog-info */
-
- struct ast_dsp *vad; /*!< Voice Activation Detection dsp */
-
- struct sip_peer *relatedpeer; /*!< If this dialog is related to a peer, which one
- Used in peerpoke, mwi subscriptions */
- struct sip_registry *registry; /*!< If this is a REGISTER dialog, to which registry */
- struct ast_rtp *rtp; /*!< RTP Session */
- struct ast_rtp *vrtp; /*!< Video RTP session */
- struct sip_pkt *packets; /*!< Packets scheduled for re-transmission */
- struct sip_history_head *history; /*!< History of this SIP dialog */
- size_t history_entries; /*!< Number of entires in the history */
- struct ast_variable *chanvars; /*!< Channel variables to set for inbound call */
- struct sip_pvt *next; /*!< Next dialog in chain */
- struct sip_invite_param *options; /*!< Options for INVITE */
- int autoframing;
-} *iflist = NULL;
-
-/*! Max entires in the history list for a sip_pvt */
-#define MAX_HISTORY_ENTRIES 50
-
-#define FLAG_RESPONSE (1 << 0)
-#define FLAG_FATAL (1 << 1)
-
-/*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission */
-struct sip_pkt {
- struct sip_pkt *next; /*!< Next packet in linked list */
- int retrans; /*!< Retransmission number */
- int method; /*!< SIP method for this packet */
- int seqno; /*!< Sequence number */
- unsigned int flags; /*!< non-zero if this is a response packet (e.g. 200 OK) */
- struct sip_pvt *owner; /*!< Owner AST call */
- int retransid; /*!< Retransmission ID */
- int timer_a; /*!< SIP timer A, retransmission timer */
- int timer_t1; /*!< SIP Timer T1, estimated RTT or 500 ms */
- int packetlen; /*!< Length of packet */
- char data[0];
-};
-
-/*! \brief Structure for SIP user data. User's place calls to us */
-struct sip_user {
- /* Users who can access various contexts */
- ASTOBJ_COMPONENTS(struct sip_user);
- char secret[80]; /*!< Password */
- char md5secret[80]; /*!< Password in md5 */
- char context[AST_MAX_CONTEXT]; /*!< Default context for incoming calls */
- char subscribecontext[AST_MAX_CONTEXT]; /* Default context for subscriptions */
- char cid_num[80]; /*!< Caller ID num */
- char cid_name[80]; /*!< Caller ID name */
- char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */
- char language[MAX_LANGUAGE]; /*!< Default language for this user */
- char mohinterpret[MAX_MUSICCLASS];/*!< Music on Hold class */
- char mohsuggest[MAX_MUSICCLASS];/*!< Music on Hold class */
- char useragent[256]; /*!< User agent in SIP request */
- struct ast_codec_pref prefs; /*!< codec prefs */
- ast_group_t callgroup; /*!< Call group */
- ast_group_t pickupgroup; /*!< Pickup Group */
- unsigned int sipoptions; /*!< Supported SIP options */
- struct ast_flags flags[2]; /*!< SIP_ flags */
- int amaflags; /*!< AMA flags for billing */
- int callingpres; /*!< Calling id presentation */
- int capability; /*!< Codec capability */
- int inUse; /*!< Number of calls in use */
- int call_limit; /*!< Limit of concurrent calls */
- enum transfermodes allowtransfer; /*! SIP Refer restriction scheme */
- struct ast_ha *ha; /*!< ACL setting */
- struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
- int maxcallbitrate; /*!< Maximum Bitrate for a video call */
- int autoframing;
-};
-
-/*! \brief Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) */
-/* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
-struct sip_peer {
- ASTOBJ_COMPONENTS(struct sip_peer); /*!< name, refcount, objflags, object pointers */
- /*!< peer->name is the unique name of this object */
- char secret[80]; /*!< Password */
- char md5secret[80]; /*!< Password in MD5 */
- struct sip_auth *auth; /*!< Realm authentication list */
- char context[AST_MAX_CONTEXT]; /*!< Default context for incoming calls */
- char subscribecontext[AST_MAX_CONTEXT]; /*!< Default context for subscriptions */
- char username[80]; /*!< Temporary username until registration */
- char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
- int amaflags; /*!< AMA Flags (for billing) */
- char tohost[MAXHOSTNAMELEN]; /*!< If not dynamic, IP address */
- char regexten[AST_MAX_EXTENSION]; /*!< Extension to register (if regcontext is used) */
- char fromuser[80]; /*!< From: user when calling this peer */
- char fromdomain[MAXHOSTNAMELEN]; /*!< From: domain when calling this peer */
- char fullcontact[256]; /*!< Contact registered with us (not in sip.conf) */
- char cid_num[80]; /*!< Caller ID num */
- char cid_name[80]; /*!< Caller ID name */
- int callingpres; /*!< Calling id presentation */
- int inUse; /*!< Number of calls in use */
- int inRinging; /*!< Number of calls ringing */
- int onHold; /*!< Peer has someone on hold */
- int call_limit; /*!< Limit of concurrent calls */
- enum transfermodes allowtransfer; /*! SIP Refer restriction scheme */
- char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
- char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
- char language[MAX_LANGUAGE]; /*!< Default language for prompts */
- char mohinterpret[MAX_MUSICCLASS];/*!< Music on Hold class */
- char mohsuggest[MAX_MUSICCLASS];/*!< Music on Hold class */
- char useragent[256]; /*!< User agent in SIP request (saved from registration) */
- struct ast_codec_pref prefs; /*!< codec prefs */
- int lastmsgssent;
- time_t lastmsgcheck; /*!< Last time we checked for MWI */
- unsigned int sipoptions; /*!< Supported SIP options */
- struct ast_flags flags[2]; /*!< SIP_ flags */
- int expire; /*!< When to expire this peer registration */
- int capability; /*!< Codec capability */
- int rtptimeout; /*!< RTP timeout */
- int rtpholdtimeout; /*!< RTP Hold Timeout */
- int rtpkeepalive; /*!< Send RTP packets for keepalive */
- ast_group_t callgroup; /*!< Call group */
- ast_group_t pickupgroup; /*!< Pickup group */
- struct sockaddr_in addr; /*!< IP address of peer */
- int maxcallbitrate; /*!< Maximum Bitrate for a video call */
-
- /* Qualification */
- struct sip_pvt *call; /*!< Call pointer */
- int pokeexpire; /*!< When to expire poke (qualify= checking) */
- int lastms; /*!< How long last response took (in ms), or -1 for no response */
- int maxms; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
- struct timeval ps; /*!< Ping send time */
-
- struct sockaddr_in defaddr; /*!< Default IP address, used until registration */
- struct ast_ha *ha; /*!< Access control list */
- struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
- struct sip_pvt *mwipvt; /*!< Subscription for MWI */
- int lastmsg;
- int autoframing;
-};
-
-
-
-/*! \brief Registrations with other SIP proxies */
-struct sip_registry {
- ASTOBJ_COMPONENTS_FULL(struct sip_registry,1,1);
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(callid); /*!< Global Call-ID */
- AST_STRING_FIELD(realm); /*!< Authorization realm */
- AST_STRING_FIELD(nonce); /*!< Authorization nonce */
- AST_STRING_FIELD(opaque); /*!< Opaque nonsense */
- AST_STRING_FIELD(qop); /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
- AST_STRING_FIELD(domain); /*!< Authorization domain */
- AST_STRING_FIELD(username); /*!< Who we are registering as */
- AST_STRING_FIELD(authuser); /*!< Who we *authenticate* as */
- AST_STRING_FIELD(hostname); /*!< Domain or host we register to */
- AST_STRING_FIELD(secret); /*!< Password in clear text */
- AST_STRING_FIELD(md5secret); /*!< Password in md5 */
- AST_STRING_FIELD(contact); /*!< Contact extension */
- AST_STRING_FIELD(random);
- );
- int portno; /*!< Optional port override */
- int expire; /*!< Sched ID of expiration */
- int regattempts; /*!< Number of attempts (since the last success) */
- int timeout; /*!< sched id of sip_reg_timeout */
- int refresh; /*!< How often to refresh */
- struct sip_pvt *call; /*!< create a sip_pvt structure for each outbound "registration dialog" in progress */
- enum sipregistrystate regstate; /*!< Registration state (see above) */
- time_t regtime; /*!< Last succesful registration time */
- int callid_valid; /*!< 0 means we haven't chosen callid for this registry yet. */
- unsigned int ocseq; /*!< Sequence number we got to for REGISTERs for this registry */
- struct sockaddr_in us; /*!< Who the server thinks we are */
- int noncecount; /*!< Nonce-count */
- char lastmsg[256]; /*!< Last Message sent/received */
-};
-
-/* --- Linked lists of various objects --------*/
-
-/*! \brief The user list: Users and friends */
-static struct ast_user_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_user);
-} userl;
-
-/*! \brief The peer list: Peers and Friends */
-static struct ast_peer_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_peer);
-} peerl;
-
-/*! \brief The register list: Other SIP proxys we register with and place calls to */
-static struct ast_register_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
- int recheck;
-} regl;
-
-static void temp_pvt_cleanup(void *);
-
-/*! \brief A per-thread temporary pvt structure */
-AST_THREADSTORAGE_CUSTOM(ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup);
-
-/*! \todo Move the sip_auth list to AST_LIST */
-static struct sip_auth *authl = NULL; /*!< Authentication list for realm authentication */
-
-
-/* --- Sockets and networking --------------*/
-static int sipsock = -1; /*!< Main socket for SIP network communication */
-static struct sockaddr_in bindaddr = { 0, }; /*!< The address we bind to */
-static struct sockaddr_in externip; /*!< External IP address if we are behind NAT */
-static char externhost[MAXHOSTNAMELEN]; /*!< External host name (possibly with dynamic DNS and DHCP */
-static time_t externexpire = 0; /*!< Expiration counter for re-resolving external host name in dynamic DNS */
-static int externrefresh = 10;
-static struct ast_ha *localaddr; /*!< List of local networks, on the same side of NAT as this Asterisk */
-static struct in_addr __ourip;
-static struct sockaddr_in outboundproxyip;
-static int ourport;
-static struct sockaddr_in debugaddr;
-
-static struct ast_config *notify_types; /*!< The list of manual NOTIFY types we know how to send */
-
-/*---------------------------- Forward declarations of functions in chan_sip.c */
-/*! \note This is added to help splitting up chan_sip.c into several files
- in coming releases */
-
-/*--- PBX interface functions */
-static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause);
-static int sip_devicestate(void *data);
-static int sip_sendtext(struct ast_channel *ast, const char *text);
-static int sip_call(struct ast_channel *ast, char *dest, int timeout);
-static int sip_hangup(struct ast_channel *ast);
-static int sip_answer(struct ast_channel *ast);
-static struct ast_frame *sip_read(struct ast_channel *ast);
-static int sip_write(struct ast_channel *ast, struct ast_frame *frame);
-static int sip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
-static int sip_transfer(struct ast_channel *ast, const char *dest);
-static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static int sip_senddigit_begin(struct ast_channel *ast, char digit);
-static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
-
-/*--- Transmitting responses and requests */
-static int sipsock_read(int *id, int fd, short events, void *ignore);
-static int __sip_xmit(struct sip_pvt *p, char *data, int len);
-static int __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod);
-static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
-static int retrans_pkt(const void *data);
-static int transmit_sip_request(struct sip_pvt *p, struct sip_request *req);
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg);
-static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
-static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported);
-static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
-static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, int reliable);
-static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
-static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
-static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
-static int transmit_reinvite_with_sdp(struct sip_pvt *p);
-static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
-static int transmit_info_with_vidupdate(struct sip_pvt *p);
-static int transmit_message_with_text(struct sip_pvt *p, const char *text);
-static int transmit_refer(struct sip_pvt *p, const char *dest);
-static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten);
-static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *message, int terminate);
-static int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader);
-static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno);
-static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno);
-static void copy_request(struct sip_request *dst, const struct sip_request *src);
-static void receive_message(struct sip_pvt *p, struct sip_request *req);
-static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req);
-static int sip_send_mwi_to_peer(struct sip_peer *peer);
-static int does_peer_need_mwi(struct sip_peer *peer);
-
-/*--- Dialog management */
-static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
- int useglobal_nat, const int intended_method);
-static int __sip_autodestruct(const void *data);
-static void sip_scheddestroy(struct sip_pvt *p, int ms);
-static int sip_cancel_destroy(struct sip_pvt *p);
-static void sip_destroy(struct sip_pvt *p);
-static int __sip_destroy(struct sip_pvt *p, int lockowner);
-static void __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod);
-static void __sip_pretend_ack(struct sip_pvt *p);
-static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod);
-static int auto_congest(const void *nothing);
-static int update_call_counter(struct sip_pvt *fup, int event);
-static int hangup_sip2cause(int cause);
-static const char *hangup_cause2sip(int cause);
-static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method);
-static void free_old_route(struct sip_route *route);
-static void list_route(struct sip_route *route);
-static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards);
-static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
- struct sip_request *req, char *uri);
-static struct sip_pvt *get_sip_pvt_byid_locked(const char *callid, const char *totag, const char *fromtag);
-static void check_pendings(struct sip_pvt *p);
-static void *sip_park_thread(void *stuff);
-static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno);
-static int sip_sipredirect(struct sip_pvt *p, const char *dest);
-
-/*--- Codec handling / SDP */
-static void try_suggested_sip_codec(struct sip_pvt *p);
-static const char* get_sdp_iterate(int* start, struct sip_request *req, const char *name);
-static const char *get_sdp(struct sip_request *req, const char *name);
-static int find_sdp(struct sip_request *req);
-static int process_sdp(struct sip_pvt *p, struct sip_request *req);
-static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
- char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
- int debug, int *min_packet_size);
-static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
- char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
- int debug);
-static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p);
-static void stop_media_flows(struct sip_pvt *p);
-
-/*--- Authentication stuff */
-static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len);
-static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len);
-static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
- const char *secret, const char *md5secret, int sipmethod,
- char *uri, enum xmittype reliable, int ignore);
-static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_request *req,
- int sipmethod, char *uri, enum xmittype reliable,
- struct sockaddr_in *sin, struct sip_peer **authpeer);
-static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin);
-
-/*--- Domain handling */
-static int check_sip_domain(const char *domain, char *context, size_t len); /* Check if domain is one of our local domains */
-static int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context);
-static void clear_sip_domains(void);
-
-/*--- SIP realm authentication */
-static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno);
-static int clear_realm_authentication(struct sip_auth *authlist); /* Clear realm authentication list (at reload) */
-static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm);
-
-/*--- Misc functions */
-static int sip_do_reload(enum channelreloadreason reason);
-static int reload_config(enum channelreloadreason reason);
-static int expire_register(const void *data);
-static void *do_monitor(void *data);
-static int restart_monitor(void);
-static int sip_send_mwi_to_peer(struct sip_peer *peer);
-static int sip_addrcmp(char *name, struct sockaddr_in *sin); /* Support for peer matching */
-static int sip_refer_allocate(struct sip_pvt *p);
-static void ast_quiet_chan(struct ast_channel *chan);
-static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
-
-/*--- Device monitoring and Device/extension state handling */
-static int cb_extensionstate(char *context, char* exten, int state, void *data);
-static int sip_devicestate(void *data);
-static int sip_poke_noanswer(const void *data);
-static int sip_poke_peer(struct sip_peer *peer);
-static void sip_poke_all_peers(void);
-static void sip_peer_hold(struct sip_pvt *p, int hold);
-
-/*--- Applications, functions, CLI and manager command helpers */
-static const char *sip_nat_mode(const struct sip_pvt *p);
-static int sip_show_inuse(int fd, int argc, char *argv[]);
-static char *transfermode2str(enum transfermodes mode) attribute_const;
-static char *nat2str(int nat) attribute_const;
-static int peer_status(struct sip_peer *peer, char *status, int statuslen);
-static int sip_show_users(int fd, int argc, char *argv[]);
-static int _sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]);
-static int sip_show_peers(int fd, int argc, char *argv[]);
-static int sip_show_objects(int fd, int argc, char *argv[]);
-static void print_group(int fd, ast_group_t group, int crlf);
-static const char *dtmfmode2str(int mode) attribute_const;
-static const char *insecure2str(int port, int invite) attribute_const;
-static void cleanup_stale_contexts(char *new, char *old);
-static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
-static const char *domain_mode_to_text(const enum domain_mode mode);
-static int sip_show_domains(int fd, int argc, char *argv[]);
-static int _sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]);
-static int sip_show_peer(int fd, int argc, char *argv[]);
-static int sip_show_user(int fd, int argc, char *argv[]);
-static int sip_show_registry(int fd, int argc, char *argv[]);
-static int sip_show_settings(int fd, int argc, char *argv[]);
-static const char *subscription_type2str(enum subscriptiontype subtype) attribute_pure;
-static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
-static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions);
-static int sip_show_channels(int fd, int argc, char *argv[]);
-static int sip_show_subscriptions(int fd, int argc, char *argv[]);
-static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions);
-static char *complete_sipch(const char *line, const char *word, int pos, int state);
-static char *complete_sip_peer(const char *word, int state, int flags2);
-static char *complete_sip_show_peer(const char *line, const char *word, int pos, int state);
-static char *complete_sip_debug_peer(const char *line, const char *word, int pos, int state);
-static char *complete_sip_user(const char *word, int state, int flags2);
-static char *complete_sip_show_user(const char *line, const char *word, int pos, int state);
-static char *complete_sipnotify(const char *line, const char *word, int pos, int state);
-static char *complete_sip_prune_realtime_peer(const char *line, const char *word, int pos, int state);
-static char *complete_sip_prune_realtime_user(const char *line, const char *word, int pos, int state);
-static int sip_show_channel(int fd, int argc, char *argv[]);
-static int sip_show_history(int fd, int argc, char *argv[]);
-static int sip_do_debug_ip(int fd, int argc, char *argv[]);
-static int sip_do_debug_peer(int fd, int argc, char *argv[]);
-static int sip_do_debug(int fd, int argc, char *argv[]);
-static int sip_no_debug(int fd, int argc, char *argv[]);
-static int sip_notify(int fd, int argc, char *argv[]);
-static int sip_do_history(int fd, int argc, char *argv[]);
-static int sip_no_history(int fd, int argc, char *argv[]);
-static int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
-static int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
-static int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
-static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
-static int sip_dtmfmode(struct ast_channel *chan, void *data);
-static int sip_addheader(struct ast_channel *chan, void *data);
-static int sip_do_reload(enum channelreloadreason reason);
-static int sip_reload(int fd, int argc, char *argv[]);
-static int acf_channel_read(struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen);
-
-/*--- Debugging
- Functions for enabling debug per IP or fully, or enabling history logging for
- a SIP dialog
-*/
-static void sip_dump_history(struct sip_pvt *dialog); /* Dump history to LOG_DEBUG at end of dialog, before destroying data */
-static inline int sip_debug_test_addr(const struct sockaddr_in *addr);
-static inline int sip_debug_test_pvt(struct sip_pvt *p);
-static void append_history_full(struct sip_pvt *p, const char *fmt, ...);
-static void sip_dump_history(struct sip_pvt *dialog);
-
-/*--- Device object handling */
-static struct sip_peer *temp_peer(const char *name);
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
-static struct sip_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
-static int update_call_counter(struct sip_pvt *fup, int event);
-static void sip_destroy_peer(struct sip_peer *peer);
-static void sip_destroy_user(struct sip_user *user);
-static int sip_poke_peer(struct sip_peer *peer);
-static int sip_poke_peer_s(const void *data);
-static void set_peer_defaults(struct sip_peer *peer);
-static struct sip_peer *temp_peer(const char *name);
-static void register_peer_exten(struct sip_peer *peer, int onoff);
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime);
-static struct sip_user *find_user(const char *name, int realtime);
-static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
-static int expire_register(const void *data);
-static void reg_source_db(struct sip_peer *peer);
-static void destroy_association(struct sip_peer *peer);
-static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
-
-/* Realtime device support */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
-static struct sip_user *realtime_user(const char *username);
-static void update_peer(struct sip_peer *p, int expiry);
-static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
-static int sip_prune_realtime(int fd, int argc, char *argv[]);
-
-/*--- Internal UA client handling (outbound registrations) */
-static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us);
-static void sip_registry_destroy(struct sip_registry *reg);
-static int sip_register(char *value, int lineno);
-static char *regstate2str(enum sipregistrystate regstate) attribute_const;
-static int sip_reregister(const void *data);
-static int __sip_do_register(struct sip_registry *r);
-static int sip_reg_timeout(const void *data);
-static void sip_send_all_registers(void);
-
-/*--- Parsing SIP requests and responses */
-static void append_date(struct sip_request *req); /* Append date to SIP packet */
-static int determine_firstline_parts(struct sip_request *req);
-static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
-static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize);
-static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno);
-static int find_sip_method(const char *msg);
-static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported);
-static int parse_request(struct sip_request *req);
-static const char *get_header(const struct sip_request *req, const char *name);
-static char *referstatus2str(enum referstatus rstatus) attribute_pure;
-static int method_match(enum sipmethod id, const char *name);
-static void parse_copy(struct sip_request *dst, const struct sip_request *src);
-static char *get_in_brackets(char *tmp);
-static const char *find_alias(const char *name, const char *_default);
-static const char *__get_header(const struct sip_request *req, const char *name, int *start);
-static int lws2sws(char *msgbuf, int len);
-static void extract_uri(struct sip_pvt *p, struct sip_request *req);
-static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoing_req);
-static int get_also_info(struct sip_pvt *p, struct sip_request *oreq);
-static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req);
-static int set_address_from_contact(struct sip_pvt *pvt);
-static void check_via(struct sip_pvt *p, const struct sip_request *req);
-static char *get_calleridname(const char *input, char *output, size_t outputsize);
-static int get_rpid_num(const char *input, char *output, int maxlen);
-static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq);
-static int get_destination(struct sip_pvt *p, struct sip_request *oreq);
-static int get_msg_text(char *buf, int len, struct sip_request *req);
-static void free_old_route(struct sip_route *route);
-static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout);
-
-/*--- Constructing requests and responses */
-static void initialize_initreq(struct sip_pvt *p, struct sip_request *req);
-static int init_req(struct sip_request *req, int sipmethod, const char *recip);
-static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch);
-static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod);
-static int init_resp(struct sip_request *resp, const char *msg);
-static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
-static void build_via(struct sip_pvt *p);
-static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer);
-static int create_addr(struct sip_pvt *dialog, const char *opeer);
-static char *generate_random_string(char *buf, size_t size);
-static void build_callid_pvt(struct sip_pvt *pvt);
-static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
-static void make_our_tag(char *tagbuf, size_t len);
-static int add_header(struct sip_request *req, const char *var, const char *value);
-static int add_header_contentLength(struct sip_request *req, int len);
-static int add_line(struct sip_request *req, const char *line);
-static int add_text(struct sip_request *req, const char *text);
-static int add_digit(struct sip_request *req, char digit, unsigned int duration);
-static int add_vidupdate(struct sip_request *req);
-static void add_route(struct sip_request *req, struct sip_route *route);
-static int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field);
-static int copy_all_header(struct sip_request *req, const struct sip_request *orig, const char *field);
-static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field);
-static void set_destination(struct sip_pvt *p, char *uri);
-static void append_date(struct sip_request *req);
-static void build_contact(struct sip_pvt *p);
-static void build_rpid(struct sip_pvt *p);
-
-/*------Request handling functions */
-static int handle_request(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock);
-static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock);
-static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock);
-static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e);
-static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e);
-static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
-static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin);
-static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e);
-static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno);
-
-/*------Response handling functions */
-static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno);
-static void handle_response_refer(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno);
-static int handle_response_register(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno);
-static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno);
-
-/*----- RTP interface functions */
-static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
-static enum ast_rtp_get_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp);
-static enum ast_rtp_get_result sip_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp **rtp);
-static int sip_get_codec(struct ast_channel *chan);
-static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p, int *faxdetect);
-
-/*------ T38 Support --------- */
-static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_pvt *pvt, int reinvite); /*!< T38 negotiation helper function */
-static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
-static int transmit_reinvite_with_t38_sdp(struct sip_pvt *p);
-static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
-static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
-
-/*! \brief Definition of this channel for PBX channel registration */
-static const struct ast_channel_tech sip_tech = {
- .type = "SIP",
- .description = "Session Initiation Protocol (SIP)",
- .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
- .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
- .requester = sip_request_call,
- .devicestate = sip_devicestate,
- .call = sip_call,
- .hangup = sip_hangup,
- .answer = sip_answer,
- .read = sip_read,
- .write = sip_write,
- .write_video = sip_write,
- .indicate = sip_indicate,
- .transfer = sip_transfer,
- .fixup = sip_fixup,
- .send_digit_begin = sip_senddigit_begin,
- .send_digit_end = sip_senddigit_end,
- .bridge = ast_rtp_bridge,
- .send_text = sip_sendtext,
- .func_channel_read = acf_channel_read,
-};
-
-/*! \brief This version of the sip channel tech has no send_digit_begin
- * callback. This is for use with channels using SIP INFO DTMF so that
- * the core knows that the channel doesn't want DTMF BEGIN frames. */
-static const struct ast_channel_tech sip_tech_info = {
- .type = "SIP",
- .description = "Session Initiation Protocol (SIP)",
- .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
- .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
- .requester = sip_request_call,
- .devicestate = sip_devicestate,
- .call = sip_call,
- .hangup = sip_hangup,
- .answer = sip_answer,
- .read = sip_read,
- .write = sip_write,
- .write_video = sip_write,
- .indicate = sip_indicate,
- .transfer = sip_transfer,
- .fixup = sip_fixup,
- .send_digit_end = sip_senddigit_end,
- .bridge = ast_rtp_bridge,
- .send_text = sip_sendtext,
- .func_channel_read = acf_channel_read,
-};
-
-/**--- some list management macros. **/
-
-#define UNLINK(element, head, prev) do { \
- if (prev) \
- (prev)->next = (element)->next; \
- else \
- (head) = (element)->next; \
- } while (0)
-
-/*! \brief Interface structure with callbacks used to connect to RTP module */
-static struct ast_rtp_protocol sip_rtp = {
- type: "SIP",
- get_rtp_info: sip_get_rtp_peer,
- get_vrtp_info: sip_get_vrtp_peer,
- set_rtp_peer: sip_set_rtp_peer,
- get_codec: sip_get_codec,
-};
-
-/*! \brief Interface structure with callbacks used to connect to UDPTL module*/
-static struct ast_udptl_protocol sip_udptl = {
- type: "SIP",
- get_udptl_info: sip_get_udptl_peer,
- set_udptl_peer: sip_set_udptl_peer,
-};
-
-/*! \brief Convert transfer status to string */
-static char *referstatus2str(enum referstatus rstatus)
-{
- int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
- int x;
-
- for (x = 0; x < i; x++) {
- if (referstatusstrings[x].status == rstatus)
- return (char *) referstatusstrings[x].text;
- }
- return "";
-}
-
-/*! \brief Initialize the initital request packet in the pvt structure.
- This packet is used for creating replies and future requests in
- a dialog */
-static void initialize_initreq(struct sip_pvt *p, struct sip_request *req)
-{
- if (p->initreq.headers && option_debug) {
- ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
- }
- /* Use this as the basis */
- copy_request(&p->initreq, req);
- parse_request(&p->initreq);
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
-}
-
-static void sip_alreadygone(struct sip_pvt *dialog)
-{
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
- ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
-}
-
-
-/*! \brief returns true if 'name' (with optional trailing whitespace)
- * matches the sip method 'id'.
- * Strictly speaking, SIP methods are case SENSITIVE, but we do
- * a case-insensitive comparison to be more tolerant.
- * following Jon Postel's rule: Be gentle in what you accept, strict with what you send
- */
-static int method_match(enum sipmethod id, const char *name)
-{
- int len = strlen(sip_methods[id].text);
- int l_name = name ? strlen(name) : 0;
- /* true if the string is long enough, and ends with whitespace, and matches */
- return (l_name >= len && name[len] < 33 &&
- !strncasecmp(sip_methods[id].text, name, len));
-}
-
-/*! \brief find_sip_method: Find SIP method from header */
-static int find_sip_method(const char *msg)
-{
- int i, res = 0;
-
- if (ast_strlen_zero(msg))
- return 0;
- for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
- if (method_match(i, msg))
- res = sip_methods[i].id;
- }
- return res;
-}
-
-/*! \brief Parse supported header in incoming packet */
-static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported)
-{
- char *next, *sep;
- char *temp;
- unsigned int profile = 0;
- int i, found;
-
- if (ast_strlen_zero(supported) )
- return 0;
- temp = ast_strdupa(supported);
-
- if (option_debug > 2 && sipdebug)
- ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported);
-
- for (next = temp; next; next = sep) {
- found = FALSE;
- if ( (sep = strchr(next, ',')) != NULL)
- *sep++ = '\0';
- next = ast_skip_blanks(next);
- if (option_debug > 2 && sipdebug)
- ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next);
- for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) {
- if (!strcasecmp(next, sip_options[i].text)) {
- profile |= sip_options[i].id;
- found = TRUE;
- if (option_debug > 2 && sipdebug)
- ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next);
- break;
- }
- }
- if (!found && option_debug > 2 && sipdebug) {
- if (!strncasecmp(next, "x-", 2))
- ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next);
- else
- ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next);
- }
- }
-
- if (pvt)
- pvt->sipoptions = profile;
- return profile;
-}
-
-/*! \brief See if we pass debug IP filter */
-static inline int sip_debug_test_addr(const struct sockaddr_in *addr)
-{
- if (!sipdebug)
- return 0;
- if (debugaddr.sin_addr.s_addr) {
- if (((ntohs(debugaddr.sin_port) != 0)
- && (debugaddr.sin_port != addr->sin_port))
- || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
-}
-
-/*! \brief The real destination address for a write */
-static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p)
-{
- return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
-}
-
-/*! \brief Display SIP nat mode */
-static const char *sip_nat_mode(const struct sip_pvt *p)
-{
- return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
-}
-
-/*! \brief Test PVT for debugging output */
-static inline int sip_debug_test_pvt(struct sip_pvt *p)
-{
- if (!sipdebug)
- return 0;
- return sip_debug_test_addr(sip_real_dst(p));
-}
-
-/*! \brief Transmit SIP message */
-static int __sip_xmit(struct sip_pvt *p, char *data, int len)
-{
- int res;
- const struct sockaddr_in *dst = sip_real_dst(p);
- res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
-
- if (res == -1) {
- switch (errno) {
- case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
- case EHOSTUNREACH: /* Host can't be reached */
- case ENETDOWN: /* Inteface down */
- case ENETUNREACH: /* Network failure */
- res = XMIT_ERROR; /* Don't bother with trying to transmit again */
- }
- }
- if (res != len)
- ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
- return res;
-}
-
-
-/*! \brief Build a Via header for a request */
-static void build_via(struct sip_pvt *p)
-{
- /* Work around buggy UNIDEN UIP200 firmware */
- const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
-
- /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
- ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
- ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
-}
-
-/*! \brief NAT fix - decide which IP address to use for ASterisk server?
- *
- * Using the localaddr structure built up with localnet statements in sip.conf
- * apply it to their address to see if we need to substitute our
- * externip or can get away with our internal bindaddr
- */
-static enum sip_result ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us)
-{
- struct sockaddr_in theirs, ours;
-
- /* Get our local information */
- ast_ouraddrfor(them, us);
- theirs.sin_addr = *them;
- ours.sin_addr = *us;
-
- if (localaddr && externip.sin_addr.s_addr &&
- (ast_apply_ha(localaddr, &theirs)) &&
- (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
- if (externexpire && time(NULL) >= externexpire) {
- struct ast_hostent ahp;
- struct hostent *hp;
-
- externexpire = time(NULL) + externrefresh;
- if ((hp = ast_gethostbyname(externhost, &ahp))) {
- memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
- } else
- ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
- }
- *us = externip.sin_addr;
- if (option_debug) {
- ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n",
- ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
- }
- } else if (bindaddr.sin_addr.s_addr)
- *us = bindaddr.sin_addr;
- return AST_SUCCESS;
-}
-
-/*! \brief Append to SIP dialog history
- \return Always returns 0 */
-#define append_history(p, event, fmt , args... ) append_history_full(p, "%-15s " fmt, event, ## args)
-
-static void append_history_full(struct sip_pvt *p, const char *fmt, ...)
- __attribute__ ((format (printf, 2, 3)));
-
-/*! \brief Append to SIP dialog history with arg list */
-static void append_history_va(struct sip_pvt *p, const char *fmt, va_list ap)
-{
- char buf[80], *c = buf; /* max history length */
- struct sip_history *hist;
- int l;
-
- vsnprintf(buf, sizeof(buf), fmt, ap);
- strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
- l = strlen(buf) + 1;
- if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
- return;
- if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
- free(hist);
- return;
- }
- memcpy(hist->event, buf, l);
- if (p->history_entries == MAX_HISTORY_ENTRIES) {
- struct sip_history *oldest;
- oldest = AST_LIST_REMOVE_HEAD(p->history, list);
- p->history_entries--;
- free(oldest);
- }
- AST_LIST_INSERT_TAIL(p->history, hist, list);
- p->history_entries++;
-}
-
-/*! \brief Append to SIP dialog history with arg list */
-static void append_history_full(struct sip_pvt *p, const char *fmt, ...)
-{
- va_list ap;
-
- if (!p)
- return;
-
- if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY)
- && !recordhistory && !dumphistory) {
- return;
- }
-
- va_start(ap, fmt);
- append_history_va(p, fmt, ap);
- va_end(ap);
-
- return;
-}
-
-/*! \brief Retransmit SIP message if no answer (Called from scheduler) */
-static int retrans_pkt(const void *data)
-{
- struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
- int reschedule = DEFAULT_RETRANS;
- int xmitres = 0;
-
- /* Lock channel PVT */
- ast_mutex_lock(&pkt->owner->lock);
-
- if (pkt->retrans < MAX_RETRANS) {
- pkt->retrans++;
- if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
- } else {
- int siptimer_a;
-
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
- if (!pkt->timer_a)
- pkt->timer_a = 2 ;
- else
- pkt->timer_a = 2 * pkt->timer_a;
-
- /* For non-invites, a maximum of 4 secs */
- siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */
- if (pkt->method != SIP_INVITE && siptimer_a > 4000)
- siptimer_a = 4000;
-
- /* Reschedule re-transmit */
- reschedule = siptimer_a;
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
- }
-
- if (sip_debug_test_pvt(pkt->owner)) {
- const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
- ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
- pkt->retrans, sip_nat_mode(pkt->owner),
- ast_inet_ntoa(dst->sin_addr),
- ntohs(dst->sin_port), pkt->data);
- }
-
- append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
- xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
- ast_mutex_unlock(&pkt->owner->lock);
- if (xmitres == XMIT_ERROR)
- ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
- else
- return reschedule;
- }
- /* Too many retries */
- if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
- if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
- ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request");
- } else if ((pkt->method == SIP_OPTIONS) && sipdebug) {
- ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
- }
- if (xmitres == XMIT_ERROR) {
- ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid);
- append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
- } else
- append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
-
- pkt->retransid = -1;
-
- if (ast_test_flag(pkt, FLAG_FATAL)) {
- while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
- ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */
- usleep(1);
- ast_mutex_lock(&pkt->owner->lock);
- }
-
- if (pkt->owner->owner && !pkt->owner->owner->hangupcause)
- pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
-
- if (pkt->owner->owner) {
- sip_alreadygone(pkt->owner);
- ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
- ast_queue_hangup(pkt->owner->owner);
- ast_channel_unlock(pkt->owner->owner);
- } else {
- /* If no channel owner, destroy now */
-
- /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
- if (pkt->method != SIP_OPTIONS) {
- ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
- sip_alreadygone(pkt->owner);
- if (option_debug)
- append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
- }
- }
- }
-
- if (pkt->method == SIP_BYE) {
- /* We're not getting answers on SIP BYE's. Tear down the call anyway. */
- if (pkt->owner->owner)
- ast_channel_unlock(pkt->owner->owner);
- append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
- ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
- }
-
- /* In any case, go ahead and remove the packet */
- for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
- if (cur == pkt)
- break;
- }
- if (cur) {
- if (prev)
- prev->next = cur->next;
- else
- pkt->owner->packets = cur->next;
- ast_mutex_unlock(&pkt->owner->lock);
- free(cur);
- pkt = NULL;
- } else
- ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
- if (pkt)
- ast_mutex_unlock(&pkt->owner->lock);
- return 0;
-}
-
-/*! \brief Transmit packet with retransmits
- \return 0 on success, -1 on failure to allocate packet
-*/
-static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
-{
- struct sip_pkt *pkt;
- int siptimer_a = DEFAULT_RETRANS;
- int xmitres = 0;
-
- if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
- return AST_FAILURE;
- memcpy(pkt->data, data, len);
- pkt->method = sipmethod;
- pkt->packetlen = len;
- pkt->next = p->packets;
- pkt->owner = p;
- pkt->seqno = seqno;
- if (resp)
- ast_set_flag(pkt, FLAG_RESPONSE);
- pkt->data[len] = '\0';
- pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */
- pkt->retransid = -1;
- if (fatal)
- ast_set_flag(pkt, FLAG_FATAL);
- if (pkt->timer_t1)
- siptimer_a = pkt->timer_t1 * 2;
-
- if (option_debug > 3 && sipdebug)
- ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid);
- pkt->retransid = -1;
- pkt->next = p->packets;
- p->packets = pkt;
- if (sipmethod == SIP_INVITE) {
- /* Note this is a pending invite */
- p->pendinginvite = seqno;
- }
-
- xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */
-
- if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */
- append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
- return AST_FAILURE;
- } else {
- /* Schedule retransmission */
- pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
- return AST_SUCCESS;
- }
-}
-
-/*! \brief Kill a SIP dialog (called by scheduler) */
-static int __sip_autodestruct(const void *data)
-{
- struct sip_pvt *p = (struct sip_pvt *)data;
-
- /* If this is a subscription, tell the phone that we got a timeout */
- if (p->subscribed) {
- transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */
- p->subscribed = NONE;
- append_history(p, "Subscribestatus", "timeout");
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
- return 10000; /* Reschedule this destruction so that we know that it's gone */
- }
-
- /* If there are packets still waiting for delivery, delay the destruction */
- if (p->packets) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
- append_history(p, "ReliableXmit", "timeout");
- return 10000;
- }
-
- /* If we're destroying a subscription, dereference peer object too */
- if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
- ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
-
- /* Reset schedule ID */
- p->autokillid = -1;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
- append_history(p, "AutoDestroy", "%s", p->callid);
- if (p->owner) {
- ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
- ast_queue_hangup(p->owner);
- } else if (p->refer) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
- transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- } else
- sip_destroy(p);
- return 0;
-}
-
-/*! \brief Schedule destruction of SIP dialog */
-static void sip_scheddestroy(struct sip_pvt *p, int ms)
-{
- if (ms < 0) {
- if (p->timer_t1 == 0)
- p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */
- ms = p->timer_t1 * 64;
- }
- if (sip_debug_test_pvt(p))
- ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "SchedDestroy", "%d ms", ms);
-
- AST_SCHED_DEL(sched, p->autokillid);
- p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
-}
-
-/*! \brief Cancel destruction of SIP dialog */
-static int sip_cancel_destroy(struct sip_pvt *p)
-{
- int res = 0;
- if (p->autokillid > -1) {
- if (!(res = ast_sched_del(sched, p->autokillid))) {
- append_history(p, "CancelDestroy", "");
- p->autokillid = -1;
- }
- }
- return res;
-}
-
-/*! \brief Acknowledges receipt of a packet and stops retransmission
- * called with p locked*/
-static void __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
-{
- struct sip_pkt *cur, *prev = NULL;
-
- /* Just in case... */
- char *msg;
- int res = FALSE;
-
- msg = sip_methods[sipmethod].text;
-
- for (cur = p->packets; cur; prev = cur, cur = cur->next) {
- if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
- ((ast_test_flag(cur, FLAG_RESPONSE)) ||
- (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
- if (!resp && (seqno == p->pendinginvite)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
- p->pendinginvite = 0;
- }
- /* this is our baby */
- res = TRUE;
- UNLINK(cur, p->packets, prev);
- if (cur->retransid > -1) {
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
- }
- /* This odd section is designed to thwart a
- * race condition in the packet scheduler. There are
- * two conditions under which deleting the packet from the
- * scheduler can fail.
- *
- * 1. The packet has been removed from the scheduler because retransmission
- * is being attempted. The problem is that if the packet is currently attempting
- * retransmission and we are at this point in the code, then that MUST mean
- * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
- * lock temporarily to allow retransmission.
- *
- * 2. The packet has reached its maximum number of retransmissions and has
- * been permanently removed from the packet scheduler. If this is the case, then
- * the packet's retransid will be set to -1. The atomicity of the setting and checking
- * of the retransid to -1 is ensured since in both cases p's lock is held.
- */
- while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- }
- free(cur);
- break;
- }
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found");
-}
-
-/*! \brief Pretend to ack all packets
- * called with p locked */
-static void __sip_pretend_ack(struct sip_pvt *p)
-{
- struct sip_pkt *cur = NULL;
-
- while (p->packets) {
- int method;
- if (cur == p->packets) {
- ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
- return;
- }
- cur = p->packets;
- method = (cur->method) ? cur->method : find_sip_method(cur->data);
- __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
- }
-}
-
-/*! \brief Acks receipt of packet, keep it around (used for provisional responses) */
-static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
-{
- struct sip_pkt *cur;
- int res = -1;
-
- for (cur = p->packets; cur; cur = cur->next) {
- if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
- (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
- /* this is our baby */
- if (cur->retransid > -1) {
- if (option_debug > 3 && sipdebug)
- ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
- }
- AST_SCHED_DEL(sched, cur->retransid);
- res = 0;
- break;
- }
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
- return res;
-}
-
-
-/*! \brief Copy SIP request, parse it */
-static void parse_copy(struct sip_request *dst, const struct sip_request *src)
-{
- memset(dst, 0, sizeof(*dst));
- memcpy(dst->data, src->data, sizeof(dst->data));
- dst->len = src->len;
- parse_request(dst);
-}
-
-/*! \brief add a blank line if no body */
-static void add_blank(struct sip_request *req)
-{
- if (!req->lines) {
- /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
- snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
- req->len += strlen(req->data + req->len);
- }
-}
-
-/*! \brief Transmit response on SIP request*/
-static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
-{
- int res;
-
- add_blank(req);
- if (sip_debug_test_pvt(p)) {
- const struct sockaddr_in *dst = sip_real_dst(p);
-
- ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
- reliable ? "Reliably " : "", sip_nat_mode(p),
- ast_inet_ntoa(dst->sin_addr),
- ntohs(dst->sin_port), req->data);
- }
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
- struct sip_request tmp;
- parse_copy(&tmp, req);
- append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"),
- (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
- }
- res = (reliable) ?
- __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
- __sip_xmit(p, req->data, req->len);
- if (res > 0)
- return 0;
- return res;
-}
-
-/*! \brief Send SIP Request to the other part of the dialogue */
-static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
-{
- int res;
-
- add_blank(req);
- if (sip_debug_test_pvt(p)) {
- if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
- ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
- else
- ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
- }
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
- struct sip_request tmp;
- parse_copy(&tmp, req);
- append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
- }
- res = (reliable) ?
- __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
- __sip_xmit(p, req->data, req->len);
- return res;
-}
-
-/*! \brief Locate closing quote in a string, skipping escaped quotes.
- * optionally with a limit on the search.
- * start must be past the first quote.
- */
-static const char *find_closing_quote(const char *start, const char *lim)
-{
- char last_char = '\0';
- const char *s;
- for (s = start; *s && s != lim; last_char = *s++) {
- if (*s == '"' && last_char != '\\')
- break;
- }
- return s;
-}
-
-/*! \brief Pick out text in brackets from character string
- \return pointer to terminated stripped string
- \param tmp input string that will be modified
- Examples:
-
- "foo" <bar> valid input, returns bar
- foo returns the whole string
- < "foo ... > returns the string between brackets
- < "foo... bogus (missing closing bracket), returns the whole string
- XXX maybe should still skip the opening bracket
- */
-static char *get_in_brackets(char *tmp)
-{
- const char *parse = tmp;
- char *first_bracket;
-
- /*
- * Skip any quoted text until we find the part in brackets.
- * On any error give up and return the full string.
- */
- while ( (first_bracket = strchr(parse, '<')) ) {
- char *first_quote = strchr(parse, '"');
-
- if (!first_quote || first_quote > first_bracket)
- break; /* no need to look at quoted part */
- /* the bracket is within quotes, so ignore it */
- parse = find_closing_quote(first_quote + 1, NULL);
- if (!*parse) { /* not found, return full string ? */
- /* XXX or be robust and return in-bracket part ? */
- ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
- break;
- }
- parse++;
- }
- if (first_bracket) {
- char *second_bracket = strchr(first_bracket + 1, '>');
- if (second_bracket) {
- *second_bracket = '\0';
- tmp = first_bracket + 1;
- } else {
- ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
- }
- }
- return tmp;
-}
-
-/*! \brief Send SIP MESSAGE text within a call
- Called from PBX core sendtext() application */
-static int sip_sendtext(struct ast_channel *ast, const char *text)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int debug = sip_debug_test_pvt(p);
-
- if (debug)
- ast_verbose("Sending text %s on %s\n", text, ast->name);
- if (!p)
- return -1;
- if (ast_strlen_zero(text))
- return 0;
- if (debug)
- ast_verbose("Really sending text %s on %s\n", text, ast->name);
- transmit_message_with_text(p, text);
- return 0;
-}
-
-/*! \brief Update peer object in realtime storage
- If the Asterisk system name is set in asterisk.conf, we will use
- that name and store that in the "regserver" field in the sippeers
- table to facilitate multi-server setups.
-*/
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
-{
- char port[10];
- char ipaddr[INET_ADDRSTRLEN];
- char regseconds[20];
-
- char *sysname = ast_config_AST_SYSTEM_NAME;
- char *syslabel = NULL;
-
- time_t nowtime = time(NULL) + expirey;
- const char *fc = fullcontact ? "fullcontact" : NULL;
-
- snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */
- ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
- snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
-
- if (ast_strlen_zero(sysname)) /* No system name, disable this */
- sysname = NULL;
- else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
- syslabel = "regserver";
-
- if (fc)
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
- "port", port, "regseconds", regseconds,
- "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
- else
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
- "port", port, "regseconds", regseconds,
- "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
-}
-
-/*! \brief Automatically add peer extension to dial plan */
-static void register_peer_exten(struct sip_peer *peer, int onoff)
-{
- char multi[256];
- char *stringp, *ext, *context;
-
- /* XXX note that global_regcontext is both a global 'enable' flag and
- * the name of the global regexten context, if not specified
- * individually.
- */
- if (ast_strlen_zero(global_regcontext))
- return;
-
- ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
- stringp = multi;
- while ((ext = strsep(&stringp, "&"))) {
- if ((context = strchr(ext, '@'))) {
- *context++ = '\0'; /* split ext@context */
- if (!ast_context_find(context)) {
- ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
- continue;
- }
- } else {
- context = global_regcontext;
- }
- if (onoff)
- ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
- ast_strdup(peer->name), ast_free, "SIP");
- else
- ast_context_remove_extension(context, ext, 1, NULL);
- }
-}
-
-/*! \brief Destroy peer object from memory */
-static void sip_destroy_peer(struct sip_peer *peer)
-{
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
-
- /* Delete it, it needs to disappear */
- if (peer->call)
- sip_destroy(peer->call);
-
- if (peer->mwipvt) /* We have an active subscription, delete it */
- sip_destroy(peer->mwipvt);
-
- if (peer->chanvars) {
- ast_variables_destroy(peer->chanvars);
- peer->chanvars = NULL;
- }
-
- register_peer_exten(peer, FALSE);
- ast_free_ha(peer->ha);
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
- apeerobjs--;
- else if (ast_test_flag(&peer->flags[0], SIP_REALTIME))
- rpeerobjs--;
- else
- speerobjs--;
- clear_realm_authentication(peer->auth);
- peer->auth = NULL;
- free(peer);
-}
-
-/*! \brief Update peer data in database (if used) */
-static void update_peer(struct sip_peer *p, int expiry)
-{
- int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
- if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
- (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
- realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
- }
-}
-
-
-/*! \brief realtime_peer: Get peer from realtime storage
- * Checks the "sippeers" realtime family from extconfig.conf
- * \todo Consider adding check of port address when matching here to follow the same
- * algorithm as for static peers. Will we break anything by adding that?
-*/
-static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin)
-{
- struct sip_peer *peer=NULL;
- struct ast_variable *var = NULL;
- struct ast_config *peerlist = NULL;
- struct ast_variable *tmp;
- struct ast_flags flags = {0};
- const char *iabuf = NULL;
- char portstring[6]; /*up to five digits plus null terminator*/
- const char *insecure;
- char *cat = NULL;
- unsigned short portnum;
-
- /* First check on peer name */
- if (newpeername) {
- var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
- if (!var && sin)
- var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
- if (!var) {
- var = ast_load_realtime("sippeers", "name", newpeername, NULL);
- /*!\note
- * If this one loaded something, then we need to ensure that the host
- * field matched. The only reason why we can't have this as a criteria
- * is because we only have the IP address and the host field might be
- * set as a name (and the reverse PTR might not match).
- */
- if (var && sin) {
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "host")) {
- struct hostent *hp;
- struct ast_hostent ahp;
- if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
- /* No match */
- ast_variables_destroy(var);
- var = NULL;
- }
- break;
- }
- }
- }
- }
- }
-
- if (!var && sin) { /* Then check on IP address */
- iabuf = ast_inet_ntoa(sin->sin_addr);
- portnum = ntohs(sin->sin_port);
- sprintf(portstring, "%d", portnum);
- var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */
- if (!var)
- var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */
- if (!var) {
- peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/
- if(peerlist){
- while((cat = ast_category_browse(peerlist, cat)))
- {
- insecure = ast_variable_retrieve(peerlist, cat, "insecure");
- set_insecure_flags(&flags, insecure, -1);
- if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
- var = ast_category_root(peerlist, cat);
- break;
- }
- }
- }
- if(!var) {
- ast_config_destroy(peerlist);
- peerlist = NULL; /*for safety's sake*/
- cat = NULL;
- peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/
- if(peerlist) {
- while((cat = ast_category_browse(peerlist, cat)))
- {
- insecure = ast_variable_retrieve(peerlist, cat, "insecure");
- set_insecure_flags(&flags, insecure, -1);
- if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
- var = ast_category_root(peerlist, cat);
- break;
- }
- }
- }
- }
- }
- }
-
- if (!var) {
- if(peerlist)
- ast_config_destroy(peerlist);
- return NULL;
- }
-
- for (tmp = var; tmp; tmp = tmp->next) {
- /* If this is type=user, then skip this object. */
- if (!strcasecmp(tmp->name, "type") &&
- !strcasecmp(tmp->value, "user")) {
- ast_variables_destroy(var);
- return NULL;
- } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
- newpeername = tmp->value;
- }
- }
-
- if (!newpeername) { /* Did not find peer in realtime */
- ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
- if(peerlist)
- ast_config_destroy(peerlist);
- else
- ast_variables_destroy(var);
- return NULL;
- }
-
- /* Peer found in realtime, now build it in memory */
- peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
- if (!peer) {
- if(peerlist)
- ast_config_destroy(peerlist);
- else
- ast_variables_destroy(var);
- return NULL;
- }
-
- if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- /* Cache peer */
- ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
- if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
- if (!AST_SCHED_DEL(sched, peer->expire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer));
- if (peer->expire == -1) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- }
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
- } else {
- ast_set_flag(&peer->flags[0], SIP_REALTIME);
- }
- if(peerlist)
- ast_config_destroy(peerlist);
- else
- ast_variables_destroy(var);
- return peer;
-}
-
-/*! \brief Support routine for find_peer */
-static int sip_addrcmp(char *name, struct sockaddr_in *sin)
-{
- /* We know name is the first field, so we can cast */
- struct sip_peer *p = (struct sip_peer *) name;
- return !(!inaddrcmp(&p->addr, sin) ||
- (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
- (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
-}
-
-/*! \brief Locate peer by name or ip address
- * This is used on incoming SIP message to find matching peer on ip
- or outgoing message to find matching peer on name */
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
-{
- struct sip_peer *p = NULL;
-
- if (peer)
- p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
- else
- p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
-
- if (!p && realtime)
- p = realtime_peer(peer, sin);
-
- return p;
-}
-
-/*! \brief Remove user object from in-memory storage */
-static void sip_destroy_user(struct sip_user *user)
-{
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
- ast_free_ha(user->ha);
- if (user->chanvars) {
- ast_variables_destroy(user->chanvars);
- user->chanvars = NULL;
- }
- if (ast_test_flag(&user->flags[0], SIP_REALTIME))
- ruserobjs--;
- else
- suserobjs--;
- free(user);
-}
-
-/*! \brief Load user from realtime storage
- * Loads user from "sipusers" category in realtime (extconfig.conf)
- * Users are matched on From: user name (the domain in skipped) */
-static struct sip_user *realtime_user(const char *username)
-{
- struct ast_variable *var;
- struct ast_variable *tmp;
- struct sip_user *user = NULL;
-
- var = ast_load_realtime("sipusers", "name", username, NULL);
-
- if (!var)
- return NULL;
-
- for (tmp = var; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, "type") &&
- !strcasecmp(tmp->value, "peer")) {
- ast_variables_destroy(var);
- return NULL;
- }
- }
-
- user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
-
- if (!user) { /* No user found */
- ast_variables_destroy(var);
- return NULL;
- }
-
- if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
- suserobjs++;
- ASTOBJ_CONTAINER_LINK(&userl,user);
- } else {
- /* Move counter from s to r... */
- suserobjs--;
- ruserobjs++;
- ast_set_flag(&user->flags[0], SIP_REALTIME);
- }
- ast_variables_destroy(var);
- return user;
-}
-
-/*! \brief Locate user by name
- * Locates user by name (From: sip uri user name part) first
- * from in-memory list (static configuration) then from
- * realtime storage (defined in extconfig.conf) */
-static struct sip_user *find_user(const char *name, int realtime)
-{
- struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
- if (!u && realtime)
- u = realtime_user(name);
- return u;
-}
-
-/*! \brief Set nat mode on the various data sockets */
-static void do_setnat(struct sip_pvt *p, int natflags)
-{
- const char *mode = natflags ? "On" : "Off";
-
- if (p->rtp) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
- ast_rtp_setnat(p->rtp, natflags);
- }
- if (p->vrtp) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
- ast_rtp_setnat(p->vrtp, natflags);
- }
- if (p->udptl) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
- ast_udptl_setnat(p->udptl, natflags);
- }
-}
-
-/*! \brief Create address structure from peer reference.
- * return -1 on error, 0 on success.
- */
-static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
-{
- if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
- (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) {
- dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
- dialog->recv = dialog->sa;
- } else
- return -1;
-
- ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
- dialog->capability = peer->capability;
- if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) {
- ast_rtp_destroy(dialog->vrtp);
- dialog->vrtp = NULL;
- }
- dialog->prefs = peer->prefs;
- if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
- dialog->t38.capability = global_t38_capability;
- if (dialog->udptl) {
- if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
- dialog->t38.capability |= T38FAX_UDP_EC_FEC;
- else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
- dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
- else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
- dialog->t38.capability |= T38FAX_UDP_EC_NONE;
- dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability);
- }
- dialog->t38.jointcapability = dialog->t38.capability;
- } else if (dialog->udptl) {
- ast_udptl_destroy(dialog->udptl);
- dialog->udptl = NULL;
- }
- do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
-
- if (dialog->rtp) {
- ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
- ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
- ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
- ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
- ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
- /* Set Frame packetization */
- ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
- dialog->autoframing = peer->autoframing;
- }
- if (dialog->vrtp) {
- ast_rtp_setdtmf(dialog->vrtp, 0);
- ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
- ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
- ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
- ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
- }
-
- ast_string_field_set(dialog, peername, peer->name);
- ast_string_field_set(dialog, authname, peer->username);
- ast_string_field_set(dialog, username, peer->username);
- ast_string_field_set(dialog, peersecret, peer->secret);
- ast_string_field_set(dialog, peermd5secret, peer->md5secret);
- ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
- ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
- ast_string_field_set(dialog, tohost, peer->tohost);
- ast_string_field_set(dialog, fullcontact, peer->fullcontact);
- if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
- char *tmpcall;
- char *c;
- tmpcall = ast_strdupa(dialog->callid);
- c = strchr(tmpcall, '@');
- if (c) {
- *c = '\0';
- ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
- }
- }
- if (ast_strlen_zero(dialog->tohost))
- ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
- if (!ast_strlen_zero(peer->fromdomain))
- ast_string_field_set(dialog, fromdomain, peer->fromdomain);
- if (!ast_strlen_zero(peer->fromuser))
- ast_string_field_set(dialog, fromuser, peer->fromuser);
- if (!ast_strlen_zero(peer->language))
- ast_string_field_set(dialog, language, peer->language);
- dialog->maxtime = peer->maxms;
- dialog->callgroup = peer->callgroup;
- dialog->pickupgroup = peer->pickupgroup;
- dialog->allowtransfer = peer->allowtransfer;
- /* Set timer T1 to RTT for this peer (if known by qualify=) */
- /* Minimum is settable or default to 100 ms */
- if (peer->maxms && peer->lastms)
- dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
- if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
- (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
- dialog->noncodeccapability |= AST_RTP_DTMF;
- else
- dialog->noncodeccapability &= ~AST_RTP_DTMF;
- dialog->jointnoncodeccapability = dialog->noncodeccapability;
- ast_string_field_set(dialog, context, peer->context);
- dialog->rtptimeout = peer->rtptimeout;
- if (peer->call_limit)
- ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
- dialog->maxcallbitrate = peer->maxcallbitrate;
-
- return 0;
-}
-
-/*! \brief create address structure from peer name
- * Or, if peer not found, find it in the global DNS
- * returns TRUE (-1) on failure, FALSE on success */
-static int create_addr(struct sip_pvt *dialog, const char *opeer)
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- struct sip_peer *p;
- char *port;
- int portno;
- char host[MAXHOSTNAMELEN], *hostn;
- char peer[256];
-
- ast_copy_string(peer, opeer, sizeof(peer));
- port = strchr(peer, ':');
- if (port)
- *port++ = '\0';
- dialog->sa.sin_family = AF_INET;
- dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
- p = find_peer(peer, NULL, 1);
-
- if (p) {
- int res = create_addr_from_peer(dialog, p);
- ASTOBJ_UNREF(p, sip_destroy_peer);
- return res;
- }
- hostn = peer;
- portno = port ? atoi(port) : STANDARD_SIP_PORT;
- if (srvlookup) {
- char service[MAXHOSTNAMELEN];
- int tportno;
- int ret;
-
- snprintf(service, sizeof(service), "_sip._udp.%s", peer);
- ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
- if (ret > 0) {
- hostn = host;
- portno = tportno;
- }
- }
- hp = ast_gethostbyname(hostn, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "No such host: %s\n", peer);
- return -1;
- }
- ast_string_field_set(dialog, tohost, peer);
- memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
- dialog->sa.sin_port = htons(portno);
- dialog->recv = dialog->sa;
- return 0;
-}
-
-/*! \brief Scheduled congestion on a call */
-static int auto_congest(const void *nothing)
-{
- struct sip_pvt *p = (struct sip_pvt *)nothing;
-
- ast_mutex_lock(&p->lock);
- p->initid = -1;
- if (p->owner) {
- /* XXX fails on possible deadlock */
- if (!ast_channel_trylock(p->owner)) {
- ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
- append_history(p, "Cong", "Auto-congesting (timer)");
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_channel_unlock(p->owner);
- }
- }
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-
-/*! \brief Initiate SIP call from PBX
- * used from the dial() application */
-static int sip_call(struct ast_channel *ast, char *dest, int timeout)
-{
- int res, xmitres = 0;
- struct sip_pvt *p;
- struct varshead *headp;
- struct ast_var_t *current;
- const char *referer = NULL; /* SIP refererer */
-
- p = ast->tech_pvt;
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
- return -1;
- }
-
- /* Check whether there is vxml_url, distinctive ring variables */
- headp=&ast->varshead;
- AST_LIST_TRAVERSE(headp,current,entries) {
- /* Check whether there is a VXML_URL variable */
- if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
- p->options->vxml_url = ast_var_value(current);
- } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
- p->options->uri_options = ast_var_value(current);
- } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
- /* Check whether there is a ALERT_INFO variable */
- p->options->distinctive_ring = ast_var_value(current);
- } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
- /* Check whether there is a variable with a name starting with SIPADDHEADER */
- p->options->addsipheaders = 1;
- } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
- /* This is a transfered call */
- p->options->transfer = 1;
- } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
- /* This is the referer */
- referer = ast_var_value(current);
- } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
- /* We're replacing a call. */
- p->options->replaces = ast_var_value(current);
- } else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
- p->t38.state = T38_LOCAL_DIRECT;
- if (option_debug)
- ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
- }
-
- }
-
- res = 0;
- ast_set_flag(&p->flags[0], SIP_OUTGOING);
-
- if (p->options->transfer) {
- char buf[SIPBUFSIZE/2];
-
- if (referer) {
- if (sipdebug && option_debug > 2)
- ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer);
- snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
- } else
- snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
- ast_string_field_set(p, cid_name, buf);
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
-
- res = update_call_counter(p, INC_CALL_RINGING);
- if ( res != -1 ) {
- p->callingpres = ast->cid.cid_pres;
- p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
- p->jointnoncodeccapability = p->noncodeccapability;
-
- /* If there are no audio formats left to offer, punt */
- if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
- ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
- res = -1;
- } else {
- p->t38.jointcapability = p->t38.capability;
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
- xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
- if (xmitres == XMIT_ERROR)
- return -1; /* Transmission error */
-
- p->invitestate = INV_CALLING;
-
- /* Initialize auto-congest time */
- AST_SCHED_DEL(sched, p->initid);
- p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p);
- }
- }
- return res;
-}
-
-/*! \brief Destroy registry object
- Objects created with the register= statement in static configuration */
-static void sip_registry_destroy(struct sip_registry *reg)
-{
- /* Really delete */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
-
- if (reg->call) {
- /* Clear registry before destroying to ensure
- we don't get reentered trying to grab the registry lock */
- reg->call->registry = NULL;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
- sip_destroy(reg->call);
- }
- AST_SCHED_DEL(sched, reg->expire);
- AST_SCHED_DEL(sched, reg->timeout);
- ast_string_field_free_memory(reg);
- regobjs--;
- free(reg);
-
-}
-
-/*! \brief Execute destruction of SIP dialog structure, release memory */
-static int __sip_destroy(struct sip_pvt *p, int lockowner)
-{
- struct sip_pvt *cur, *prev = NULL;
- struct sip_pkt *cp;
-
- /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
- if (p->rtp && ast_rtp_get_bridged(p->rtp)) {
- ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
- return -1;
- }
-
- if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) {
- ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
- return -1;
- }
-
- if (sip_debug_test_pvt(p) || option_debug > 2)
- ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
-
- if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
- update_call_counter(p, DEC_CALL_LIMIT);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
- }
-
- /* Unlink us from the owner if we have one */
- if (p->owner) {
- if (lockowner)
- ast_channel_lock(p->owner);
- if (option_debug)
- ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
- p->owner->tech_pvt = NULL;
- /* Make sure that the channel knows its backend is going away */
- p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- if (lockowner)
- ast_channel_unlock(p->owner);
- /* Give the channel a chance to react before deallocation */
- usleep(1);
- }
-
- /* Remove link from peer to subscription of MWI */
- if (p->relatedpeer) {
- p->relatedpeer->mwipvt = NULL;
- ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer);
- }
-
- if (dumphistory)
- sip_dump_history(p);
-
- if (p->options)
- free(p->options);
-
- if (p->stateid > -1)
- ast_extension_state_del(p->stateid, NULL);
- AST_SCHED_DEL(sched, p->initid);
- AST_SCHED_DEL(sched, p->waitid);
- AST_SCHED_DEL(sched, p->autokillid);
-
- if (p->rtp) {
- ast_rtp_destroy(p->rtp);
- }
- if (p->vrtp) {
- ast_rtp_destroy(p->vrtp);
- }
- if (p->udptl)
- ast_udptl_destroy(p->udptl);
- if (p->refer)
- free(p->refer);
- if (p->route) {
- free_old_route(p->route);
- p->route = NULL;
- }
- if (p->registry) {
- if (p->registry->call == p)
- p->registry->call = NULL;
- ASTOBJ_UNREF(p->registry, sip_registry_destroy);
- }
-
- /* Clear history */
- if (p->history) {
- struct sip_history *hist;
- while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
- free(hist);
- p->history_entries--;
- }
- free(p->history);
- p->history = NULL;
- }
-
- for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
- if (cur == p) {
- UNLINK(cur, iflist, prev);
- break;
- }
- }
- if (!cur) {
- ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
- return 0;
- }
-
- /* remove all current packets in this dialog */
- while((cp = p->packets)) {
- p->packets = p->packets->next;
- AST_SCHED_DEL(sched, cp->retransid);
- free(cp);
- }
- if (p->chanvars) {
- ast_variables_destroy(p->chanvars);
- p->chanvars = NULL;
- }
- ast_mutex_destroy(&p->lock);
-
- ast_string_field_free_memory(p);
-
- free(p);
- return 0;
-}
-
-/*! \brief update_call_counter: Handle call_limit for SIP users
- * Setting a call-limit will cause calls above the limit not to be accepted.
- *
- * Remember that for a type=friend, there's one limit for the user and
- * another for the peer, not a combined call limit.
- * This will cause unexpected behaviour in subscriptions, since a "friend"
- * is *two* devices in Asterisk, not one.
- *
- * Thought: For realtime, we should propably update storage with inuse counter...
- *
- * \return 0 if call is ok (no call limit, below treshold)
- * -1 on rejection of call
- *
- */
-static int update_call_counter(struct sip_pvt *fup, int event)
-{
- char name[256];
- int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
- int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
- struct sip_user *u = NULL;
- struct sip_peer *p = NULL;
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
-
- /* Test if we need to check call limits, in order to avoid
- realtime lookups if we do not need it */
- if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
- return 0;
-
- ast_copy_string(name, fup->username, sizeof(name));
-
- /* Check the list of users only for incoming calls */
- if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) {
- inuse = &u->inUse;
- call_limit = &u->call_limit;
- inringing = NULL;
- } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
- inuse = &p->inUse;
- call_limit = &p->call_limit;
- inringing = &p->inRinging;
- ast_copy_string(name, fup->peername, sizeof(name));
- }
- if (!p && !u) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
- return 0;
- }
-
- switch(event) {
- /* incoming and outgoing affects the inUse counter */
- case DEC_CALL_LIMIT:
- if ( *inuse > 0 ) {
- if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
- (*inuse)--;
- ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
- }
- } else {
- *inuse = 0;
- }
- if (inringing) {
- if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
- if (*inringing > 0)
- (*inringing)--;
- else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
- ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
- ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
- }
- }
- if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
- ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
- sip_peer_hold(fup, 0);
- }
- if (option_debug > 1 || sipdebug) {
- ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
- }
- break;
-
- case INC_CALL_RINGING:
- case INC_CALL_LIMIT:
- if (*call_limit > 0 ) {
- if (*inuse >= *call_limit) {
- ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
- if (u)
- ASTOBJ_UNREF(u, sip_destroy_user);
- else
- ASTOBJ_UNREF(p, sip_destroy_peer);
- return -1;
- }
- }
- if (inringing && (event == INC_CALL_RINGING)) {
- if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
- (*inringing)++;
- ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
- }
- }
- /* Continue */
- (*inuse)++;
- ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
- if (option_debug > 1 || sipdebug) {
- ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
- }
- break;
-
- case DEC_CALL_RINGING:
- if (inringing) {
- if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
- if (*inringing > 0)
- (*inringing)--;
- else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
- ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
- ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
- }
- }
- break;
-
- default:
- ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
- }
- if (p) {
- ast_device_state_changed("SIP/%s", p->name);
- ASTOBJ_UNREF(p, sip_destroy_peer);
- } else /* u must be set */
- ASTOBJ_UNREF(u, sip_destroy_user);
- return 0;
-}
-
-/*! \brief Destroy SIP call structure */
-static void sip_destroy(struct sip_pvt *p)
-{
- ast_mutex_lock(&iflock);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
- __sip_destroy(p, 1);
- ast_mutex_unlock(&iflock);
-}
-
-/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
-static int hangup_sip2cause(int cause)
-{
- /* Possible values taken from causes.h */
-
- switch(cause) {
- case 401: /* Unauthorized */
- return AST_CAUSE_CALL_REJECTED;
- case 403: /* Not found */
- return AST_CAUSE_CALL_REJECTED;
- case 404: /* Not found */
- return AST_CAUSE_UNALLOCATED;
- case 405: /* Method not allowed */
- return AST_CAUSE_INTERWORKING;
- case 407: /* Proxy authentication required */
- return AST_CAUSE_CALL_REJECTED;
- case 408: /* No reaction */
- return AST_CAUSE_NO_USER_RESPONSE;
- case 409: /* Conflict */
- return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
- case 410: /* Gone */
- return AST_CAUSE_UNALLOCATED;
- case 411: /* Length required */
- return AST_CAUSE_INTERWORKING;
- case 413: /* Request entity too large */
- return AST_CAUSE_INTERWORKING;
- case 414: /* Request URI too large */
- return AST_CAUSE_INTERWORKING;
- case 415: /* Unsupported media type */
- return AST_CAUSE_INTERWORKING;
- case 420: /* Bad extension */
- return AST_CAUSE_NO_ROUTE_DESTINATION;
- case 480: /* No answer */
- return AST_CAUSE_NO_ANSWER;
- case 481: /* No answer */
- return AST_CAUSE_INTERWORKING;
- case 482: /* Loop detected */
- return AST_CAUSE_INTERWORKING;
- case 483: /* Too many hops */
- return AST_CAUSE_NO_ANSWER;
- case 484: /* Address incomplete */
- return AST_CAUSE_INVALID_NUMBER_FORMAT;
- case 485: /* Ambigous */
- return AST_CAUSE_UNALLOCATED;
- case 486: /* Busy everywhere */
- return AST_CAUSE_BUSY;
- case 487: /* Request terminated */
- return AST_CAUSE_INTERWORKING;
- case 488: /* No codecs approved */
- return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
- case 491: /* Request pending */
- return AST_CAUSE_INTERWORKING;
- case 493: /* Undecipherable */
- return AST_CAUSE_INTERWORKING;
- case 500: /* Server internal failure */
- return AST_CAUSE_FAILURE;
- case 501: /* Call rejected */
- return AST_CAUSE_FACILITY_REJECTED;
- case 502:
- return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
- case 503: /* Service unavailable */
- return AST_CAUSE_CONGESTION;
- case 504: /* Gateway timeout */
- return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
- case 505: /* SIP version not supported */
- return AST_CAUSE_INTERWORKING;
- case 600: /* Busy everywhere */
- return AST_CAUSE_USER_BUSY;
- case 603: /* Decline */
- return AST_CAUSE_CALL_REJECTED;
- case 604: /* Does not exist anywhere */
- return AST_CAUSE_UNALLOCATED;
- case 606: /* Not acceptable */
- return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
- default:
- return AST_CAUSE_NORMAL;
- }
- /* Never reached */
- return 0;
-}
-
-/*! \brief Convert Asterisk hangup causes to SIP codes
-\verbatim
- Possible values from causes.h
- AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY
- AST_CAUSE_FAILURE AST_CAUSE_CONGESTION AST_CAUSE_UNALLOCATED
-
- In addition to these, a lot of PRI codes is defined in causes.h
- ...should we take care of them too ?
-
- Quote RFC 3398
-
- ISUP Cause value SIP response
- ---------------- ------------
- 1 unallocated number 404 Not Found
- 2 no route to network 404 Not found
- 3 no route to destination 404 Not found
- 16 normal call clearing --- (*)
- 17 user busy 486 Busy here
- 18 no user responding 408 Request Timeout
- 19 no answer from the user 480 Temporarily unavailable
- 20 subscriber absent 480 Temporarily unavailable
- 21 call rejected 403 Forbidden (+)
- 22 number changed (w/o diagnostic) 410 Gone
- 22 number changed (w/ diagnostic) 301 Moved Permanently
- 23 redirection to new destination 410 Gone
- 26 non-selected user clearing 404 Not Found (=)
- 27 destination out of order 502 Bad Gateway
- 28 address incomplete 484 Address incomplete
- 29 facility rejected 501 Not implemented
- 31 normal unspecified 480 Temporarily unavailable
-\endverbatim
-*/
-static const char *hangup_cause2sip(int cause)
-{
- switch (cause) {
- case AST_CAUSE_UNALLOCATED: /* 1 */
- case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
- case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
- return "404 Not Found";
- case AST_CAUSE_CONGESTION: /* 34 */
- case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
- return "503 Service Unavailable";
- case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
- return "408 Request Timeout";
- case AST_CAUSE_NO_ANSWER: /* 19 */
- return "480 Temporarily unavailable";
- case AST_CAUSE_CALL_REJECTED: /* 21 */
- return "403 Forbidden";
- case AST_CAUSE_NUMBER_CHANGED: /* 22 */
- return "410 Gone";
- case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
- return "480 Temporarily unavailable";
- case AST_CAUSE_INVALID_NUMBER_FORMAT:
- return "484 Address incomplete";
- case AST_CAUSE_USER_BUSY:
- return "486 Busy here";
- case AST_CAUSE_FAILURE:
- return "500 Server internal failure";
- case AST_CAUSE_FACILITY_REJECTED: /* 29 */
- return "501 Not Implemented";
- case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
- return "503 Service Unavailable";
- /* Used in chan_iax2 */
- case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
- return "502 Bad Gateway";
- case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
- return "488 Not Acceptable Here";
-
- case AST_CAUSE_NOTDEFINED:
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
- return NULL;
- }
-
- /* Never reached */
- return 0;
-}
-
-
-/*! \brief sip_hangup: Hangup SIP call
- * Part of PBX interface, called from ast_hangup */
-static int sip_hangup(struct ast_channel *ast)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int needcancel = FALSE;
- int needdestroy = 0;
- struct ast_channel *oldowner = ast;
-
- if (!p) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n");
- return 0;
- }
-
- if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
- if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
- if (option_debug && sipdebug)
- ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
- update_call_counter(p, DEC_CALL_LIMIT);
- }
- if (option_debug >3)
- ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
- if (p->autokillid > -1 && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
- ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY);
- p->owner->tech_pvt = NULL;
- p->owner = NULL; /* Owner will be gone after we return, so take it away */
- return 0;
- }
- if (option_debug) {
- if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug)
- ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
- else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
- }
- }
- if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE))
- ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n");
-
- ast_mutex_lock(&p->lock);
- if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
- if (option_debug && sipdebug)
- ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
- update_call_counter(p, DEC_CALL_LIMIT);
- }
-
- /* Determine how to disconnect */
- if (p->owner != ast) {
- ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n");
- ast_mutex_unlock(&p->lock);
- return 0;
- }
- /* If the call is not UP, we need to send CANCEL instead of BYE */
- if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) {
- needcancel = TRUE;
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
- }
-
- stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
-
- append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown");
-
- /* Disconnect */
- if (p->vad)
- ast_dsp_free(p->vad);
-
- p->owner = NULL;
- ast->tech_pvt = NULL;
-
- ast_module_unref(ast_module_info->self);
-
- /* Do not destroy this pvt until we have timeout or
- get an answer to the BYE or INVITE/CANCEL
- If we get no answer during retransmit period, drop the call anyway.
- (Sorry, mother-in-law, you can't deny a hangup by sending
- 603 declined to BYE...)
- */
- if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
- needdestroy = 1; /* Set destroy flag at end of this function */
- else if (p->invitestate != INV_CALLING)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-
- /* Start the process if it's not already started */
- if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
- if (needcancel) { /* Outgoing call, not up */
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- /* stop retransmitting an INVITE that has not received a response */
- __sip_pretend_ack(p);
- p->invitestate = INV_CANCELLED;
-
- /* if we can't send right now, mark it pending */
- if (p->invitestate == INV_CALLING) {
- /* We can't send anything in CALLING state */
- ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
- /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
- } else {
- /* Send a new request: CANCEL */
- transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
- /* Actually don't destroy us yet, wait for the 487 on our original
- INVITE, but do set an autodestruct just in case we never get it. */
- needdestroy = 0;
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- if ( p->initid != -1 ) {
- /* channel still up - reverse dec of inUse counter
- only if the channel is not auto-congested */
- update_call_counter(p, INC_CALL_LIMIT);
- }
- } else { /* Incoming call, not up */
- const char *res;
- if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause)))
- transmit_response_reliable(p, res, &p->initreq);
- else
- transmit_response_reliable(p, "603 Declined", &p->initreq);
- p->invitestate = INV_TERMINATED;
- }
- } else { /* Call is in UP state, send BYE */
- if (!p->pendinginvite) {
- char *audioqos = "";
- char *videoqos = "";
- if (p->rtp)
- audioqos = ast_rtp_get_quality(p->rtp, NULL);
- if (p->vrtp)
- videoqos = ast_rtp_get_quality(p->vrtp, NULL);
- /* Send a hangup */
- transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
-
- /* Get RTCP quality before end of call */
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
- if (p->rtp)
- append_history(p, "RTCPaudio", "Quality:%s", audioqos);
- if (p->vrtp)
- append_history(p, "RTCPvideo", "Quality:%s", videoqos);
- }
- if (p->rtp && oldowner)
- pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos);
- if (p->vrtp && oldowner)
- pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos);
- } else {
- /* Note we will need a BYE when this all settles out
- but we can't send one while we have "INVITE" outstanding. */
- ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
- ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
- AST_SCHED_DEL(sched, p->waitid);
- if (sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- }
- }
- }
- if (needdestroy)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-/*! \brief Try setting codec suggested by the SIP_CODEC channel variable */
-static void try_suggested_sip_codec(struct sip_pvt *p)
-{
- int fmt;
- const char *codec;
-
- codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
- if (!codec)
- return;
-
- fmt = ast_getformatbyname(codec);
- if (fmt) {
- ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
- if (p->jointcapability & fmt) {
- p->jointcapability &= fmt;
- p->capability &= fmt;
- } else
- ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
- } else
- ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
- return;
-}
-
-/*! \brief sip_answer: Answer SIP call , send 200 OK on Invite
- * Part of PBX interface */
-static int sip_answer(struct ast_channel *ast)
-{
- int res = 0;
- struct sip_pvt *p = ast->tech_pvt;
-
- ast_mutex_lock(&p->lock);
- if (ast->_state != AST_STATE_UP) {
- try_suggested_sip_codec(p);
-
- ast_setstate(ast, AST_STATE_UP);
- if (option_debug)
- ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
- if (p->t38.state == T38_PEER_DIRECT) {
- p->t38.state = T38_ENABLED;
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
- res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
- } else {
- res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
- }
- }
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-/*! \brief Send frame to media channel (rtp) */
-static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int res = 0;
-
- switch (frame->frametype) {
- case AST_FRAME_VOICE:
- if (!(frame->subclass & ast->nativeformats)) {
- char s1[512], s2[512], s3[512];
- ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
- frame->subclass,
- ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
- ast->nativeformats & AST_FORMAT_AUDIO_MASK,
- ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
- ast->readformat,
- ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
- ast->writeformat);
- return 0;
- }
- if (p) {
- ast_mutex_lock(&p->lock);
- if (p->rtp) {
- /* If channel is not up, activate early media session */
- if ((ast->_state != AST_STATE_UP) &&
- !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
- !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- ast_rtp_new_source(p->rtp);
- transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
- ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
- }
- p->lastrtptx = time(NULL);
- res = ast_rtp_write(p->rtp, frame);
- }
- ast_mutex_unlock(&p->lock);
- }
- break;
- case AST_FRAME_VIDEO:
- if (p) {
- ast_mutex_lock(&p->lock);
- if (p->vrtp) {
- /* Activate video early media */
- if ((ast->_state != AST_STATE_UP) &&
- !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
- !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
- ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
- }
- p->lastrtptx = time(NULL);
- res = ast_rtp_write(p->vrtp, frame);
- }
- ast_mutex_unlock(&p->lock);
- }
- break;
- case AST_FRAME_IMAGE:
- return 0;
- break;
- case AST_FRAME_MODEM:
- if (p) {
- ast_mutex_lock(&p->lock);
- /* UDPTL requires two-way communication, so early media is not needed here.
- we simply forget the frames if we get modem frames before the bridge is up.
- Fax will re-transmit.
- */
- if (p->udptl && ast->_state == AST_STATE_UP)
- res = ast_udptl_write(p->udptl, frame);
- ast_mutex_unlock(&p->lock);
- }
- break;
- default:
- ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
- return 0;
- }
-
- return res;
-}
-
-/*! \brief sip_fixup: Fix up a channel: If a channel is consumed, this is called.
- Basically update any ->owner links */
-static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- int ret = -1;
- struct sip_pvt *p;
-
- if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
- ast_log(LOG_DEBUG, "New channel is zombie\n");
- if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
- ast_log(LOG_DEBUG, "Old channel is zombie\n");
-
- if (!newchan || !newchan->tech_pvt) {
- if (!newchan)
- ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
- else
- ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
- return -1;
- }
- p = newchan->tech_pvt;
-
- if (!p) {
- ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
- return -1;
- }
-
- ast_mutex_lock(&p->lock);
- append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
- append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
- if (p->owner != oldchan)
- ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
- else {
- p->owner = newchan;
- /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
- RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
- able to do this if the masquerade happens before the bridge breaks (e.g., AMI
- redirect of both channels). Note that a channel can not be masqueraded *into*
- a native bridge. So there is no danger that this breaks a native bridge that
- should stay up. */
- sip_set_rtp_peer(newchan, NULL, NULL, 0, 0);
- ret = 0;
- }
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
-
- ast_mutex_unlock(&p->lock);
- return ret;
-}
-
-static int sip_senddigit_begin(struct ast_channel *ast, char digit)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int res = 0;
-
- ast_mutex_lock(&p->lock);
- switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
- case SIP_DTMF_INBAND:
- res = -1; /* Tell Asterisk to generate inband indications */
- break;
- case SIP_DTMF_RFC2833:
- if (p->rtp)
- ast_rtp_senddigit_begin(p->rtp, digit);
- break;
- default:
- break;
- }
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-/*! \brief Send DTMF character on SIP channel
- within one call, we're able to transmit in many methods simultaneously */
-static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int res = 0;
-
- ast_mutex_lock(&p->lock);
- switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
- case SIP_DTMF_INFO:
- transmit_info_with_digit(p, digit, duration);
- break;
- case SIP_DTMF_RFC2833:
- if (p->rtp)
- ast_rtp_senddigit_end(p->rtp, digit);
- break;
- case SIP_DTMF_INBAND:
- res = -1; /* Tell Asterisk to stop inband indications */
- break;
- }
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-/*! \brief Transfer SIP call */
-static int sip_transfer(struct ast_channel *ast, const char *dest)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int res;
-
- if (dest == NULL) /* functions below do not take a NULL */
- dest = "";
- ast_mutex_lock(&p->lock);
- if (ast->_state == AST_STATE_RING)
- res = sip_sipredirect(p, dest);
- else
- res = transmit_refer(p, dest);
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-/*! \brief Play indication to user
- * With SIP a lot of indications is sent as messages, letting the device play
- the indication - busy signal, congestion etc
- \return -1 to force ast_indicate to send indication in audio, 0 if SIP can handle the indication by sending a message
-*/
-static int sip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
-{
- struct sip_pvt *p = ast->tech_pvt;
- int res = 0;
-
- ast_mutex_lock(&p->lock);
- switch(condition) {
- case AST_CONTROL_RINGING:
- if (ast->_state == AST_STATE_RING) {
- p->invitestate = INV_EARLY_MEDIA;
- if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
- (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {
- /* Send 180 ringing if out-of-band seems reasonable */
- transmit_response(p, "180 Ringing", &p->initreq);
- ast_set_flag(&p->flags[0], SIP_RINGING);
- if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
- break;
- } else {
- /* Well, if it's not reasonable, just send in-band */
- }
- }
- res = -1;
- break;
- case AST_CONTROL_BUSY:
- if (ast->_state != AST_STATE_UP) {
- transmit_response(p, "486 Busy Here", &p->initreq);
- p->invitestate = INV_COMPLETED;
- sip_alreadygone(p);
- ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
- break;
- }
- res = -1;
- break;
- case AST_CONTROL_CONGESTION:
- if (ast->_state != AST_STATE_UP) {
- transmit_response(p, "503 Service Unavailable", &p->initreq);
- p->invitestate = INV_COMPLETED;
- sip_alreadygone(p);
- ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
- break;
- }
- res = -1;
- break;
- case AST_CONTROL_PROCEEDING:
- if ((ast->_state != AST_STATE_UP) &&
- !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
- !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- transmit_response(p, "100 Trying", &p->initreq);
- p->invitestate = INV_PROCEEDING;
- break;
- }
- res = -1;
- break;
- case AST_CONTROL_PROGRESS:
- if ((ast->_state != AST_STATE_UP) &&
- !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
- !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- p->invitestate = INV_EARLY_MEDIA;
- transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
- ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
- break;
- }
- res = -1;
- break;
- case AST_CONTROL_HOLD:
- ast_rtp_new_source(p->rtp);
- ast_moh_start(ast, data, p->mohinterpret);
- break;
- case AST_CONTROL_UNHOLD:
- ast_rtp_new_source(p->rtp);
- ast_moh_stop(ast);
- break;
- case AST_CONTROL_VIDUPDATE: /* Request a video frame update */
- if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
- transmit_info_with_vidupdate(p);
- /* ast_rtcp_send_h261fur(p->vrtp); */
- } else
- res = -1;
- break;
- case AST_CONTROL_SRCUPDATE:
- ast_rtp_new_source(p->rtp);
- break;
- case -1:
- res = -1;
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
- res = -1;
- break;
- }
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-
-/*! \brief Initiate a call in the SIP channel
- called from sip_request_call (calls from the pbx ) for outbound channels
- and from handle_request_invite for inbound channels
-
-*/
-static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title)
-{
- struct ast_channel *tmp;
- struct ast_variable *v = NULL;
- int fmt;
- int what;
- int needvideo = 0, video = 0;
- char *decoded_exten;
- {
- const char *my_name; /* pick a good name */
-
- if (title)
- my_name = title;
- else if ( (my_name = strchr(i->fromdomain,':')) )
- my_name++; /* skip ':' */
- else
- my_name = i->fromdomain;
-
- ast_mutex_unlock(&i->lock);
- /* Don't hold a sip pvt lock while we allocate a channel */
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i);
-
- }
- if (!tmp) {
- ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
- ast_mutex_lock(&i->lock);
- return NULL;
- }
- ast_mutex_lock(&i->lock);
-
- if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
- tmp->tech = &sip_tech_info;
- else
- tmp->tech = &sip_tech;
-
- /* Select our native format based on codec preference until we receive
- something from another device to the contrary. */
- if (i->jointcapability) { /* The joint capabilities of us and peer */
- what = i->jointcapability;
- video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
- } else if (i->capability) { /* Our configured capability for this peer */
- what = i->capability;
- video = i->capability & AST_FORMAT_VIDEO_MASK;
- } else {
- what = global_capability; /* Global codec support */
- video = global_capability & AST_FORMAT_VIDEO_MASK;
- }
-
- /* Set the native formats for audio and merge in video */
- tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video;
- if (option_debug > 2) {
- char buf[SIPBUFSIZE];
- ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
- ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
- ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
- ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
- if (i->prefcodec)
- ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
- }
-
- /* XXX Why are we choosing a codec from the native formats?? */
- fmt = ast_best_codec(tmp->nativeformats);
-
- /* If we have a prefcodec setting, we have an inbound channel that set a
- preferred format for this call. Otherwise, we check the jointcapability
- We also check for vrtp. If it's not there, we are not allowed do any video anyway.
- */
- if (i->vrtp) {
- if (i->prefcodec)
- needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */
- else
- needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */
- }
-
- if (option_debug > 2) {
- if (needvideo)
- ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
- else
- ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
- }
-
-
-
- if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
- i->vad = ast_dsp_new();
- ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
- if (global_relaxdtmf)
- ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
- }
- if (i->rtp) {
- tmp->fds[0] = ast_rtp_fd(i->rtp);
- tmp->fds[1] = ast_rtcp_fd(i->rtp);
- }
- if (needvideo && i->vrtp) {
- tmp->fds[2] = ast_rtp_fd(i->vrtp);
- tmp->fds[3] = ast_rtcp_fd(i->vrtp);
- }
- if (i->udptl) {
- tmp->fds[5] = ast_udptl_fd(i->udptl);
- }
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
- tmp->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp->rawreadformat = fmt;
- tmp->tech_pvt = i;
-
- tmp->callgroup = i->callgroup;
- tmp->pickupgroup = i->pickupgroup;
- tmp->cid.cid_pres = i->callingpres;
- if (!ast_strlen_zero(i->accountcode))
- ast_string_field_set(tmp, accountcode, i->accountcode);
- if (i->amaflags)
- tmp->amaflags = i->amaflags;
- if (!ast_strlen_zero(i->language))
- ast_string_field_set(tmp, language, i->language);
- i->owner = tmp;
- ast_module_ref(ast_module_info->self);
- ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
- /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
- * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
- * structure so that there aren't issues when forming URI's
- */
- decoded_exten = ast_strdupa(i->exten);
- ast_uri_decode(decoded_exten);
- ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
-
- /* Don't use ast_set_callerid() here because it will
- * generate an unnecessary NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
- if (!ast_strlen_zero(i->rdnis))
- tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
-
- if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
- tmp->cid.cid_dnid = ast_strdup(i->exten);
-
- tmp->priority = 1;
- if (!ast_strlen_zero(i->uri))
- pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
- if (!ast_strlen_zero(i->domain))
- pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
- if (!ast_strlen_zero(i->useragent))
- pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
- if (!ast_strlen_zero(i->callid))
- pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
- if (i->rtp)
- ast_jb_configure(tmp, &global_jbconf);
-
- /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */
- if (i->udptl && i->t38.state == T38_PEER_DIRECT)
- pbx_builtin_setvar_helper(tmp, "_T38CALL", "1");
-
- /* Set channel variables for this call from configuration */
- for (v = i->chanvars ; v ; v = v->next)
- pbx_builtin_setvar_helper(tmp, v->name, v->value);
-
- if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- ast_hangup(tmp);
- tmp = NULL;
- }
-
- if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
- append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
-
- return tmp;
-}
-
-/*! \brief Reads one line of SIP message body */
-static char *get_body_by_line(const char *line, const char *name, int nameLen)
-{
- if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
- return ast_skip_blanks(line + nameLen + 1);
-
- return "";
-}
-
-/*! \brief Lookup 'name' in the SDP starting
- * at the 'start' line. Returns the matching line, and 'start'
- * is updated with the next line number.
- */
-static const char *get_sdp_iterate(int *start, struct sip_request *req, const char *name)
-{
- int len = strlen(name);
-
- while (*start < req->sdp_end) {
- const char *r = get_body_by_line(req->line[(*start)++], name, len);
- if (r[0] != '\0')
- return r;
- }
-
- return "";
-}
-
-/*! \brief Get a line from an SDP message body */
-static const char *get_sdp(struct sip_request *req, const char *name)
-{
- int dummy = 0;
-
- return get_sdp_iterate(&dummy, req, name);
-}
-
-/*! \brief Get a specific line from the message body */
-static char *get_body(struct sip_request *req, char *name)
-{
- int x;
- int len = strlen(name);
- char *r;
-
- for (x = 0; x < req->lines; x++) {
- r = get_body_by_line(req->line[x], name, len);
- if (r[0] != '\0')
- return r;
- }
-
- return "";
-}
-
-/*! \brief Find compressed SIP alias */
-static const char *find_alias(const char *name, const char *_default)
-{
- /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
- static const struct cfalias {
- char * const fullname;
- char * const shortname;
- } aliases[] = {
- { "Content-Type", "c" },
- { "Content-Encoding", "e" },
- { "From", "f" },
- { "Call-ID", "i" },
- { "Contact", "m" },
- { "Content-Length", "l" },
- { "Subject", "s" },
- { "To", "t" },
- { "Supported", "k" },
- { "Refer-To", "r" },
- { "Referred-By", "b" },
- { "Allow-Events", "u" },
- { "Event", "o" },
- { "Via", "v" },
- { "Accept-Contact", "a" },
- { "Reject-Contact", "j" },
- { "Request-Disposition", "d" },
- { "Session-Expires", "x" },
- { "Identity", "y" },
- { "Identity-Info", "n" },
- };
- int x;
-
- for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++)
- if (!strcasecmp(aliases[x].fullname, name))
- return aliases[x].shortname;
-
- return _default;
-}
-
-static const char *__get_header(const struct sip_request *req, const char *name, int *start)
-{
- int pass;
-
- /*
- * Technically you can place arbitrary whitespace both before and after the ':' in
- * a header, although RFC3261 clearly says you shouldn't before, and place just
- * one afterwards. If you shouldn't do it, what absolute idiot decided it was
- * a good idea to say you can do it, and if you can do it, why in the hell would.
- * you say you shouldn't.
- * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
- * and we always allow spaces after that for compatibility.
- */
- for (pass = 0; name && pass < 2;pass++) {
- int x, len = strlen(name);
- for (x=*start; x<req->headers; x++) {
- if (!strncasecmp(req->header[x], name, len)) {
- char *r = req->header[x] + len; /* skip name */
- if (pedanticsipchecking)
- r = ast_skip_blanks(r);
-
- if (*r == ':') {
- *start = x+1;
- return ast_skip_blanks(r+1);
- }
- }
- }
- if (pass == 0) /* Try aliases */
- name = find_alias(name, NULL);
- }
-
- /* Don't return NULL, so get_header is always a valid pointer */
- return "";
-}
-
-/*! \brief Get header from SIP request */
-static const char *get_header(const struct sip_request *req, const char *name)
-{
- int start = 0;
- return __get_header(req, name, &start);
-}
-
-/*! \brief Read RTP from network */
-static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
-{
- /* Retrieve audio/etc from channel. Assumes p->lock is already held. */
- struct ast_frame *f;
-
- if (!p->rtp) {
- /* We have no RTP allocated for this channel */
- return &ast_null_frame;
- }
-
- switch(ast->fdno) {
- case 0:
- f = ast_rtp_read(p->rtp); /* RTP Audio */
- break;
- case 1:
- f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
- break;
- case 2:
- f = ast_rtp_read(p->vrtp); /* RTP Video */
- break;
- case 3:
- f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */
- break;
- case 5:
- f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
- break;
- default:
- f = &ast_null_frame;
- }
- /* Don't forward RFC2833 if we're not supposed to */
- if (f && (f->frametype == AST_FRAME_DTMF) &&
- (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
- return &ast_null_frame;
-
- /* We already hold the channel lock */
- if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
- return f;
-
- if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
- if (!(f->subclass & p->jointcapability)) {
- if (option_debug) {
- ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
- ast_getformatname(f->subclass), p->owner->name);
- }
- return &ast_null_frame;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
- p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
- ast_set_read_format(p->owner, p->owner->readformat);
- ast_set_write_format(p->owner, p->owner->writeformat);
- }
-
- if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
- f = ast_dsp_process(p->owner, p->vad, f);
- if (f && f->frametype == AST_FRAME_DTMF) {
- if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
- if (option_debug)
- ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
- *faxdetect = 1;
- } else if (option_debug) {
- ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
- }
- }
- }
-
- return f;
-}
-
-/*! \brief Read SIP RTP from channel */
-static struct ast_frame *sip_read(struct ast_channel *ast)
-{
- struct ast_frame *fr;
- struct sip_pvt *p = ast->tech_pvt;
- int faxdetected = FALSE;
-
- ast_mutex_lock(&p->lock);
- fr = sip_rtp_read(ast, p, &faxdetected);
- p->lastrtprx = time(NULL);
-
- /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
- /* If we are bridged then it is the responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preamble */
- if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
- if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
- if (!p->pendinginvite) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
- p->t38.state = T38_LOCAL_REINVITE;
- transmit_reinvite_with_t38_sdp(p);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
- }
- } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
- ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
- }
- }
-
- /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
- if (fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
- fr = &ast_null_frame;
- }
-
- ast_mutex_unlock(&p->lock);
- return fr;
-}
-
-
-/*! \brief Generate 32 byte random string for callid's etc */
-static char *generate_random_string(char *buf, size_t size)
-{
- long val[4];
- int x;
-
- for (x=0; x<4; x++)
- val[x] = ast_random();
- snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
-
- return buf;
-}
-
-/*! \brief Build SIP Call-ID value for a non-REGISTER transaction */
-static void build_callid_pvt(struct sip_pvt *pvt)
-{
- char buf[33];
-
- const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
-
- ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
-
-}
-
-/*! \brief Build SIP Call-ID value for a REGISTER transaction */
-static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
-{
- char buf[33];
-
- const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
-
- ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
-}
-
-/*! \brief Make our SIP dialog tag */
-static void make_our_tag(char *tagbuf, size_t len)
-{
- snprintf(tagbuf, len, "as%08lx", ast_random());
-}
-
-/*! \brief Allocate SIP_PVT structure and set defaults */
-static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
- int useglobal_nat, const int intended_method)
-{
- struct sip_pvt *p;
-
- if (!(p = ast_calloc(1, sizeof(*p))))
- return NULL;
-
- if (ast_string_field_init(p, 512)) {
- free(p);
- return NULL;
- }
-
- ast_mutex_init(&p->lock);
-
- p->method = intended_method;
- p->initid = -1;
- p->waitid = -1;
- p->autokillid = -1;
- p->subscribed = NONE;
- p->stateid = -1;
- p->prefs = default_prefs; /* Set default codecs for this call */
-
- if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
- p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
-
- if (sin) {
- p->sa = *sin;
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
- } else
- p->ourip = __ourip;
-
- /* Copy global flags to this PVT at setup. */
- ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
-
- ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
-
- p->branch = ast_random();
- make_our_tag(p->tag, sizeof(p->tag));
- p->ocseq = INITIAL_CSEQ;
-
- if (sip_methods[intended_method].need_rtp) {
- p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
- /* If the global videosupport flag is on, we always create a RTP interface for video */
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
- p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
- p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
- if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
- ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
- ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
- ast_mutex_destroy(&p->lock);
- if (p->chanvars) {
- ast_variables_destroy(p->chanvars);
- p->chanvars = NULL;
- }
- free(p);
- return NULL;
- }
- ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
- ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
- ast_rtp_settos(p->rtp, global_tos_audio);
- ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
- ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
- ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
- if (p->vrtp) {
- ast_rtp_settos(p->vrtp, global_tos_video);
- ast_rtp_setdtmf(p->vrtp, 0);
- ast_rtp_setdtmfcompensate(p->vrtp, 0);
- ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
- ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
- ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
- }
- if (p->udptl)
- ast_udptl_settos(p->udptl, global_tos_audio);
- p->maxcallbitrate = default_maxcallbitrate;
- }
-
- if (useglobal_nat && sin) {
- /* Setup NAT structure according to global settings if we have an address */
- ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
- p->recv = *sin;
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
- }
-
- if (p->method != SIP_REGISTER)
- ast_string_field_set(p, fromdomain, default_fromdomain);
- build_via(p);
- if (!callid)
- build_callid_pvt(p);
- else
- ast_string_field_set(p, callid, callid);
- /* Assign default music on hold class */
- ast_string_field_set(p, mohinterpret, default_mohinterpret);
- ast_string_field_set(p, mohsuggest, default_mohsuggest);
- p->capability = global_capability;
- p->allowtransfer = global_allowtransfer;
- if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
- (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
- p->noncodeccapability |= AST_RTP_DTMF;
- if (p->udptl) {
- p->t38.capability = global_t38_capability;
- if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
- p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
- else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
- p->t38.capability |= T38FAX_UDP_EC_FEC;
- else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
- p->t38.capability |= T38FAX_UDP_EC_NONE;
- p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
- p->t38.jointcapability = p->t38.capability;
- }
- ast_string_field_set(p, context, default_context);
-
- /* Add to active dialog list */
- ast_mutex_lock(&iflock);
- p->next = iflist;
- iflist = p;
- ast_mutex_unlock(&iflock);
- if (option_debug)
- ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
- return p;
-}
-
-/*! \brief Connect incoming SIP message to current dialog or create new dialog structure
- Called by handle_request, sipsock_read */
-static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
-{
- struct sip_pvt *p = NULL;
- char *tag = ""; /* note, tag is never NULL */
- char totag[128];
- char fromtag[128];
- const char *callid = get_header(req, "Call-ID");
- const char *from = get_header(req, "From");
- const char *to = get_header(req, "To");
- const char *cseq = get_header(req, "Cseq");
-
- /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
- /* get_header always returns non-NULL so we must use ast_strlen_zero() */
- if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
- ast_strlen_zero(from) || ast_strlen_zero(cseq))
- return NULL; /* Invalid packet */
-
- if (pedanticsipchecking) {
- /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
- we need more to identify a branch - so we have to check branch, from
- and to tags to identify a call leg.
- For Asterisk to behave correctly, you need to turn on pedanticsipchecking
- in sip.conf
- */
- if (gettag(req, "To", totag, sizeof(totag)))
- ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
- gettag(req, "From", fromtag, sizeof(fromtag));
-
- tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
-
- if (option_debug > 4 )
- ast_log(LOG_DEBUG, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
- }
-
- ast_mutex_lock(&iflock);
- for (p = iflist; p; p = p->next) {
- /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
- int found = FALSE;
- if (ast_strlen_zero(p->callid))
- continue;
- if (req->method == SIP_REGISTER)
- found = (!strcmp(p->callid, callid));
- else
- found = (!strcmp(p->callid, callid) &&
- (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
-
- if (option_debug > 4)
- ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
-
- /* If we get a new request within an existing to-tag - check the to tag as well */
- if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */
- if (p->tag[0] == '\0' && totag[0]) {
- /* We have no to tag, but they have. Wrong dialog */
- found = FALSE;
- } else if (totag[0]) { /* Both have tags, compare them */
- if (strcmp(totag, p->tag)) {
- found = FALSE; /* This is not our packet */
- }
- }
- if (!found && option_debug > 4)
- ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text);
- }
-
-
- if (found) {
- /* Found the call */
- ast_mutex_lock(&p->lock);
- ast_mutex_unlock(&iflock);
- return p;
- }
- }
- ast_mutex_unlock(&iflock);
-
- /* See if the method is capable of creating a dialog */
- if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
- if (intended_method == SIP_REFER) {
- /* We do support REFER, but not outside of a dialog yet */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
- } else if (intended_method == SIP_NOTIFY) {
- /* We do not support out-of-dialog NOTIFY either,
- like voicemail notification, so cancel that early */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
- } else {
- /* Ok, time to create a new SIP dialog object, a pvt */
- if ((p = sip_alloc(callid, sin, 1, intended_method))) {
- /* Ok, we've created a dialog, let's go and process it */
- ast_mutex_lock(&p->lock);
- } else {
- /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
- getting a dialog from sip_alloc.
-
- Without a dialog we can't retransmit and handle ACKs and all that, but at least
- send an error message.
-
- Sorry, we apologize for the inconvienience
- */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
- }
- }
- return p;
- } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
- /* A method we do not support, let's take it on the volley */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
- } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
- /* This is a request outside of a dialog that we don't know about
- ...never reply to an ACK!
- */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
- }
- /* We do not respond to responses for dialogs that we don't know about, we just drop
- the session quickly */
-
- return p;
-}
-
-/*! \brief Parse register=> line in sip.conf and add to registry */
-static int sip_register(char *value, int lineno)
-{
- struct sip_registry *reg;
- int portnum = 0;
- char username[256] = "";
- char *hostname=NULL, *secret=NULL, *authuser=NULL;
- char *porta=NULL;
- char *contact=NULL;
-
- if (!value)
- return -1;
- ast_copy_string(username, value, sizeof(username));
- /* First split around the last '@' then parse the two components. */
- hostname = strrchr(username, '@'); /* allow @ in the first part */
- if (hostname)
- *hostname++ = '\0';
- if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
- ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
- return -1;
- }
- /* split user[:secret[:authuser]] */
- secret = strchr(username, ':');
- if (secret) {
- *secret++ = '\0';
- authuser = strchr(secret, ':');
- if (authuser)
- *authuser++ = '\0';
- }
- /* split host[:port][/contact] */
- contact = strchr(hostname, '/');
- if (contact)
- *contact++ = '\0';
- if (ast_strlen_zero(contact))
- contact = "s";
- porta = strchr(hostname, ':');
- if (porta) {
- *porta++ = '\0';
- portnum = atoi(porta);
- if (portnum == 0) {
- ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
- return -1;
- }
- }
- if (!(reg = ast_calloc(1, sizeof(*reg)))) {
- ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
- return -1;
- }
-
- if (ast_string_field_init(reg, 256)) {
- ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
- free(reg);
- return -1;
- }
-
- regobjs++;
- ASTOBJ_INIT(reg);
- ast_string_field_set(reg, contact, contact);
- if (!ast_strlen_zero(username))
- ast_string_field_set(reg, username, username);
- if (hostname)
- ast_string_field_set(reg, hostname, hostname);
- if (authuser)
- ast_string_field_set(reg, authuser, authuser);
- if (secret)
- ast_string_field_set(reg, secret, secret);
- reg->expire = -1;
- reg->timeout = -1;
- reg->refresh = default_expiry;
- reg->portno = portnum;
- reg->callid_valid = FALSE;
- reg->ocseq = INITIAL_CSEQ;
- ASTOBJ_CONTAINER_LINK(&regl, reg); /* Add the new registry entry to the list */
- ASTOBJ_UNREF(reg,sip_registry_destroy);
- return 0;
-}
-
-/*! \brief Parse multiline SIP headers into one header
- This is enabled if pedanticsipchecking is enabled */
-static int lws2sws(char *msgbuf, int len)
-{
- int h = 0, t = 0;
- int lws = 0;
-
- for (; h < len;) {
- /* Eliminate all CRs */
- if (msgbuf[h] == '\r') {
- h++;
- continue;
- }
- /* Check for end-of-line */
- if (msgbuf[h] == '\n') {
- /* Check for end-of-message */
- if (h + 1 == len)
- break;
- /* Check for a continuation line */
- if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') {
- /* Merge continuation line */
- h++;
- continue;
- }
- /* Propagate LF and start new line */
- msgbuf[t++] = msgbuf[h++];
- lws = 0;
- continue;
- }
- if (msgbuf[h] == ' ' || msgbuf[h] == '\t') {
- if (lws) {
- h++;
- continue;
- }
- msgbuf[t++] = msgbuf[h++];
- lws = 1;
- continue;
- }
- msgbuf[t++] = msgbuf[h++];
- if (lws)
- lws = 0;
- }
- msgbuf[t] = '\0';
- return t;
-}
-
-/*! \brief Parse a SIP message
- \note this function is used both on incoming and outgoing packets
-*/
-static int parse_request(struct sip_request *req)
-{
- /* Divide fields by NULL's */
- char *c;
- int f = 0;
-
- c = req->data;
-
- /* First header starts immediately */
- req->header[f] = c;
- while(*c) {
- if (*c == '\n') {
- /* We've got a new header */
- *c = 0;
-
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
- if (ast_strlen_zero(req->header[f])) {
- /* Line by itself means we're now in content */
- c++;
- break;
- }
- if (f >= SIP_MAX_HEADERS - 1) {
- ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
- } else
- f++;
- req->header[f] = c + 1;
- } else if (*c == '\r') {
- /* Ignore but eliminate \r's */
- *c = 0;
- }
- c++;
- }
- /* Check for last header */
- if (!ast_strlen_zero(req->header[f])) {
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
- f++;
- }
- req->headers = f;
- /* Now we process any mime content */
- f = 0;
- req->line[f] = c;
- while(*c) {
- if (*c == '\n') {
- /* We've got a new line */
- *c = 0;
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
- if (f >= SIP_MAX_LINES - 1) {
- ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
- } else
- f++;
- req->line[f] = c + 1;
- } else if (*c == '\r') {
- /* Ignore and eliminate \r's */
- *c = 0;
- }
- c++;
- }
- /* Check for last line */
- if (!ast_strlen_zero(req->line[f]))
- f++;
- req->lines = f;
- if (*c)
- ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
- /* Split up the first line parts */
- return determine_firstline_parts(req);
-}
-
-/*!
- \brief Determine whether a SIP message contains an SDP in its body
- \param req the SIP request to process
- \return 1 if SDP found, 0 if not found
-
- Also updates req->sdp_start and req->sdp_end to indicate where the SDP
- lives in the message body.
-*/
-static int find_sdp(struct sip_request *req)
-{
- const char *content_type;
- const char *content_length;
- const char *search;
- char *boundary;
- unsigned int x;
- int boundaryisquoted = FALSE;
- int found_application_sdp = FALSE;
- int found_end_of_headers = FALSE;
-
- content_length = get_header(req, "Content-Length");
-
- if (!ast_strlen_zero(content_length)) {
- if (sscanf(content_length, "%ud", &x) != 1) {
- ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
- return 0;
- }
-
- /* Content-Length of zero means there can't possibly be an
- SDP here, even if the Content-Type says there is */
- if (x == 0)
- return 0;
- }
-
- content_type = get_header(req, "Content-Type");
-
- /* if the body contains only SDP, this is easy */
- if (!strcasecmp(content_type, "application/sdp")) {
- req->sdp_start = 0;
- req->sdp_end = req->lines;
- return req->lines ? 1 : 0;
- }
-
- /* if it's not multipart/mixed, there cannot be an SDP */
- if (strncasecmp(content_type, "multipart/mixed", 15))
- return 0;
-
- /* if there is no boundary marker, it's invalid */
- if ((search = strcasestr(content_type, ";boundary=")))
- search += 10;
- else if ((search = strcasestr(content_type, "; boundary=")))
- search += 11;
- else
- return 0;
-
- if (ast_strlen_zero(search))
- return 0;
-
- /* If the boundary is quoted with ", remove quote */
- if (*search == '\"') {
- search++;
- boundaryisquoted = TRUE;
- }
-
- /* make a duplicate of the string, with two extra characters
- at the beginning */
- boundary = ast_strdupa(search - 2);
- boundary[0] = boundary[1] = '-';
- /* Remove final quote */
- if (boundaryisquoted)
- boundary[strlen(boundary) - 1] = '\0';
-
- /* search for the boundary marker, the empty line delimiting headers from
- sdp part and the end boundry if it exists */
-
- for (x = 0; x < (req->lines ); x++) {
- if(!strncasecmp(req->line[x], boundary, strlen(boundary))){
- if(found_application_sdp && found_end_of_headers){
- req->sdp_end = x-1;
- return 1;
- }
- found_application_sdp = FALSE;
- }
- if(!strcasecmp(req->line[x], "Content-Type: application/sdp"))
- found_application_sdp = TRUE;
-
- if(strlen(req->line[x]) == 0 ){
- if(found_application_sdp && !found_end_of_headers){
- req->sdp_start = x;
- found_end_of_headers = TRUE;
- }
- }
- }
- if(found_application_sdp && found_end_of_headers) {
- req->sdp_end = x;
- return TRUE;
- }
- return FALSE;
-}
-
-/*! \brief Change hold state for a call */
-static void change_hold_state(struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
-{
- if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
- sip_peer_hold(dialog, holdstate);
- if (global_callevents)
- manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n",
- dialog->owner->name,
- dialog->owner->uniqueid);
- append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
- if (!holdstate) { /* Put off remote hold */
- ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
- return;
- }
- /* No address for RTP, we're on hold */
-
- if (sendonly == 1) /* One directional hold (sendonly/recvonly) */
- ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
- else if (sendonly == 2) /* Inactive stream */
- ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
- else
- ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
- return;
-}
-
-/*! \brief Process SIP SDP offer, select formats and activate RTP channels
- If offer is rejected, we will not change any properties of the call
- Return 0 on success, a negative value on errors.
- Must be called after find_sdp().
-*/
-static int process_sdp(struct sip_pvt *p, struct sip_request *req)
-{
- const char *m; /* SDP media offer */
- const char *c;
- const char *a;
- char host[258];
- int len = -1;
- int portno = -1; /*!< RTP Audio port number */
- int vportno = -1; /*!< RTP Video port number */
- int udptlportno = -1;
- int peert38capability = 0;
- char s[256];
- int old = 0;
-
- /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */
- int peercapability = 0, peernoncodeccapability = 0;
- int vpeercapability = 0, vpeernoncodeccapability = 0;
- struct sockaddr_in sin; /*!< media socket address */
- struct sockaddr_in vsin; /*!< Video socket address */
-
- const char *codecs;
- struct hostent *hp; /*!< RTP Audio host IP */
- struct hostent *vhp = NULL; /*!< RTP video host IP */
- struct ast_hostent audiohp;
- struct ast_hostent videohp;
- int codec;
- int destiterator = 0;
- int iterator;
- int sendonly = -1;
- int numberofports;
- struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */
- int newjointcapability; /* Negotiated capability */
- int newpeercapability;
- int newnoncodeccapability;
- int numberofmediastreams = 0;
- int debug = sip_debug_test_pvt(p);
-
- int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS];
- int last_rtpmap_codec=0;
-
- if (!p->rtp) {
- ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
- return -1;
- }
-
- /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
- newaudiortp = alloca(ast_rtp_alloc_size());
- memset(newaudiortp, 0, ast_rtp_alloc_size());
- ast_rtp_new_init(newaudiortp);
- ast_rtp_pt_clear(newaudiortp);
-
- newvideortp = alloca(ast_rtp_alloc_size());
- memset(newvideortp, 0, ast_rtp_alloc_size());
- ast_rtp_new_init(newvideortp);
- ast_rtp_pt_clear(newvideortp);
-
- /* Update our last rtprx when we receive an SDP, too */
- p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
-
-
- /* Try to find first media stream */
- m = get_sdp(req, "m");
- destiterator = req->sdp_start;
- c = get_sdp_iterate(&destiterator, req, "c");
- if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
- ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
- return -1;
- }
-
- /* Check for IPv4 address (not IPv6 yet) */
- if (sscanf(c, "IN IP4 %256s", host) != 1) {
- ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
- return -1;
- }
-
- /* XXX This could block for a long time, and block the main thread! XXX */
- hp = ast_gethostbyname(host, &audiohp);
- if (!hp) {
- ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
- return -1;
- }
- vhp = hp; /* Copy to video address as default too */
-
- iterator = req->sdp_start;
- ast_set_flag(&p->flags[0], SIP_NOVIDEO);
-
-
- /* Find media streams in this SDP offer */
- while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
- int x;
- int audio = FALSE;
-
- numberofports = 1;
- if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
- (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
- audio = TRUE;
- numberofmediastreams++;
- /* Found audio stream in this media definition */
- portno = x;
- /* Scan through the RTP payload types specified in a "m=" line: */
- for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
- if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
- ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
- return -1;
- }
- if (debug)
- ast_verbose("Found RTP audio format %d\n", codec);
- ast_rtp_set_m_type(newaudiortp, codec);
- }
- } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
- (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
- /* If it is not audio - is it video ? */
- ast_clear_flag(&p->flags[0], SIP_NOVIDEO);
- numberofmediastreams++;
- vportno = x;
- /* Scan through the RTP payload types specified in a "m=" line: */
- for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
- if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
- ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
- return -1;
- }
- if (debug)
- ast_verbose("Found RTP video format %d\n", codec);
- ast_rtp_set_m_type(newvideortp, codec);
- }
- } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) ||
- (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) {
- if (debug)
- ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
- udptlportno = x;
- numberofmediastreams++;
-
- if (p->owner && p->lastinvite) {
- p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" );
- } else {
- p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
- } else
- ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
- if (numberofports > 1)
- ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
-
-
- /* Check for Media-description-level-address for audio */
- c = get_sdp_iterate(&destiterator, req, "c");
- if (!ast_strlen_zero(c)) {
- if (sscanf(c, "IN IP4 %256s", host) != 1) {
- ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
- } else {
- /* XXX This could block for a long time, and block the main thread! XXX */
- if (audio) {
- if ( !(hp = ast_gethostbyname(host, &audiohp))) {
- ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c);
- return -2;
- }
- } else if (!(vhp = ast_gethostbyname(host, &videohp))) {
- ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c);
- return -2;
- }
- }
-
- }
- }
- if (portno == -1 && vportno == -1 && udptlportno == -1)
- /* No acceptable offer found in SDP - we have no ports */
- /* Do not change RTP or VRTP if this is a re-invite */
- return -2;
-
- if (numberofmediastreams > 2)
- /* We have too many fax, audio and/or video media streams, fail this offer */
- return -3;
-
- /* RTP addresses and ports for audio and video */
- sin.sin_family = AF_INET;
- vsin.sin_family = AF_INET;
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- if (vhp)
- memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
-
- /* Setup UDPTL port number */
- if (p->udptl) {
- if (udptlportno > 0) {
- sin.sin_port = htons(udptlportno);
- ast_udptl_set_peer(p->udptl, &sin);
- if (debug)
- ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- } else {
- ast_udptl_stop(p->udptl);
- if (debug)
- ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n");
- }
- }
-
-
- if (p->rtp) {
- if (portno > 0) {
- sin.sin_port = htons(portno);
- ast_rtp_set_peer(p->rtp, &sin);
- if (debug)
- ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- } else {
- if (udptlportno > 0) {
- if (debug)
- ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid);
- } else {
- ast_rtp_stop(p->rtp);
- if (debug)
- ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid);
- }
- }
- }
- /* Setup video port number */
- if (vportno != -1)
- vsin.sin_port = htons(vportno);
-
- /* Next, scan through each "a=rtpmap:" line, noting each
- * specified RTP payload type (with corresponding MIME subtype):
- */
- /* XXX This needs to be done per media stream, since it's media stream specific */
- iterator = req->sdp_start;
- while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
- char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
- if (option_debug > 1) {
- int breakout = FALSE;
-
- /* If we're debugging, check for unsupported sdp options */
- if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
- if (debug)
- ast_verbose("Got unsupported a:rtcp in SDP offer \n");
- breakout = TRUE;
- } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) {
- /* Format parameters: Not supported */
- /* Note: This is used for codec parameters, like bitrate for
- G722 and video formats for H263 and H264
- See RFC2327 for an example */
- if (debug)
- ast_verbose("Got unsupported a:fmtp in SDP offer \n");
- breakout = TRUE;
- } else if (!strncasecmp(a, "framerate:", (size_t) 10)) {
- /* Video stuff: Not supported */
- if (debug)
- ast_verbose("Got unsupported a:framerate in SDP offer \n");
- breakout = TRUE;
- } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) {
- /* Video stuff: Not supported */
- if (debug)
- ast_verbose("Got unsupported a:maxprate in SDP offer \n");
- breakout = TRUE;
- } else if (!strncasecmp(a, "crypto:", (size_t) 7)) {
- /* SRTP stuff, not yet supported */
- if (debug)
- ast_verbose("Got unsupported a:crypto in SDP offer \n");
- breakout = TRUE;
- }
- if (breakout) /* We have a match, skip to next header */
- continue;
- }
- if (!strcasecmp(a, "sendonly")) {
- if (sendonly == -1)
- sendonly = 1;
- continue;
- } else if (!strcasecmp(a, "inactive")) {
- if (sendonly == -1)
- sendonly = 2;
- continue;
- } else if (!strcasecmp(a, "sendrecv")) {
- if (sendonly == -1)
- sendonly = 0;
- continue;
- } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
- char *tmp = strrchr(a, ':');
- long int framing = 0;
- if (tmp) {
- tmp++;
- framing = strtol(tmp, NULL, 10);
- if (framing == LONG_MIN || framing == LONG_MAX) {
- framing = 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a);
- }
- }
- if (framing && last_rtpmap_codec) {
- if (p->autoframing) {
- struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
- int codec_n;
- int format = 0;
- for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) {
- format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]);
- if (!format) /* non-codec or not found */
- continue;
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing);
- ast_codec_pref_setsize(pref, format, framing);
- }
- ast_rtp_codec_setpref(p->rtp, pref);
- }
- }
- memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs));
- last_rtpmap_codec = 0;
- continue;
- } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) {
- /* We have a rtpmap to handle */
- int found = FALSE;
- /* We should propably check if this is an audio or video codec
- so we know where to look */
-
- if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
- /* Note: should really look at the 'freq' and '#chans' params too */
- if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
- ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) {
- if (debug)
- ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
- found_rtpmap_codecs[last_rtpmap_codec] = codec;
- last_rtpmap_codec++;
- found = TRUE;
-
- } else if (p->vrtp) {
- if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) {
- if (debug)
- ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
- found_rtpmap_codecs[last_rtpmap_codec] = codec;
- last_rtpmap_codec++;
- found = TRUE;
- }
- }
- } else {
- if (debug)
- ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
- }
-
- if (!found) {
- /* Remove this codec since it's an unknown media type for us */
- /* XXX This is buggy since the media line for audio and video can have the
- same numbers. We need to check as described above, but for testing this works... */
- ast_rtp_unset_m_type(newaudiortp, codec);
- ast_rtp_unset_m_type(newvideortp, codec);
- if (debug)
- ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
- }
- }
- }
-
- if (udptlportno != -1) {
- int found = 0, x;
-
- old = 0;
-
- /* Scan trough the a= lines for T38 attributes and set apropriate fileds */
- iterator = req->sdp_start;
- while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
- if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x);
- } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
- switch (x) {
- case 14400:
- peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
- break;
- case 12000:
- peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
- break;
- case 9600:
- peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
- break;
- case 7200:
- peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
- break;
- case 4800:
- peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400;
- break;
- case 2400:
- peert38capability |= T38FAX_RATE_2400;
- break;
- }
- } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "FaxVersion: %d\n",x);
- if (x == 0)
- peert38capability |= T38FAX_VERSION_0;
- else if (x == 1)
- peert38capability |= T38FAX_VERSION_1;
- } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x);
- ast_udptl_set_far_max_datagram(p->udptl, x);
- ast_udptl_set_local_max_datagram(p->udptl, x);
- } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x);
- if (x == 1)
- peert38capability |= T38FAX_FILL_BIT_REMOVAL;
- } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x);
- if (x == 1)
- peert38capability |= T38FAX_TRANSCODING_MMR;
- }
- if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x);
- if (x == 1)
- peert38capability |= T38FAX_TRANSCODING_JBIG;
- } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "RateManagement: %s\n", s);
- if (!strcasecmp(s, "localTCF"))
- peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF;
- else if (!strcasecmp(s, "transferredTCF"))
- peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
- } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
- found = 1;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "UDP EC: %s\n", s);
- if (!strcasecmp(s, "t38UDPRedundancy")) {
- peert38capability |= T38FAX_UDP_EC_REDUNDANCY;
- ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
- } else if (!strcasecmp(s, "t38UDPFEC")) {
- peert38capability |= T38FAX_UDP_EC_FEC;
- ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
- } else {
- peert38capability |= T38FAX_UDP_EC_NONE;
- ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
- }
- }
- }
- if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */
- p->t38.peercapability = peert38capability;
- p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */
- peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400);
- p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */
- }
- if (debug)
- ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n",
- p->t38.capability,
- p->t38.peercapability,
- p->t38.jointcapability);
- } else {
- p->t38.state = T38_DISABLED;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
-
- /* Now gather all of the codecs that we are asked for: */
- ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
- ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
-
- newjointcapability = p->capability & (peercapability | vpeercapability);
- newpeercapability = (peercapability | vpeercapability);
- newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
-
-
- if (debug) {
- /* shame on whoever coded this.... */
- char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE];
-
- ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
- ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
- ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability),
- ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
- ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability));
-
- ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
- ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0),
- ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0),
- ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0));
- }
- if (!newjointcapability) {
- /* If T.38 was not negotiated either, totally bail out... */
- if (!p->t38.jointcapability || !udptlportno) {
- ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
- /* Do NOT Change current setting */
- return -1;
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n");
- return 0;
- }
- }
-
- /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
- they are acceptable */
- p->jointcapability = newjointcapability; /* Our joint codec profile for this call */
- p->peercapability = newpeercapability; /* The other sides capability in latest offer */
- p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */
-
- ast_rtp_pt_copy(p->rtp, newaudiortp);
- if (p->vrtp)
- ast_rtp_pt_copy(p->vrtp, newvideortp);
-
- if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
- ast_clear_flag(&p->flags[0], SIP_DTMF);
- if (newnoncodeccapability & AST_RTP_DTMF) {
- /* XXX Would it be reasonable to drop the DSP at this point? XXX */
- ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
- /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
- ast_rtp_setdtmf(p->rtp, 1);
- ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
- } else {
- ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
- }
- }
-
- /* Setup audio port number */
- if (p->rtp && sin.sin_port) {
- ast_rtp_set_peer(p->rtp, &sin);
- if (debug)
- ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- }
-
- /* Setup video port number */
- if (p->vrtp && vsin.sin_port) {
- ast_rtp_set_peer(p->vrtp, &vsin);
- if (debug)
- ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
- }
-
- /* Ok, we're going with this offer */
- if (option_debug > 1) {
- char buf[SIPBUFSIZE];
- ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
- }
-
- if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
- return 0;
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n");
-
- if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
- if (debug) {
- char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
- ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
- ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
- ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
- }
- p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability);
- ast_set_read_format(p->owner, p->owner->readformat);
- ast_set_write_format(p->owner, p->owner->writeformat);
- }
-
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
- ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
- /* Activate a re-invite */
- ast_queue_frame(p->owner, &ast_null_frame);
- } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
- ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
- S_OR(p->mohsuggest, NULL),
- !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- if (sendonly)
- ast_rtp_stop(p->rtp);
- /* RTCP needs to go ahead, even if we're on hold!!! */
- /* Activate a re-invite */
- ast_queue_frame(p->owner, &ast_null_frame);
- }
-
- /* Manager Hold and Unhold events must be generated, if necessary */
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1))
- change_hold_state(p, req, FALSE, sendonly);
- else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1))
- change_hold_state(p, req, TRUE, sendonly);
- return 0;
-}
-
-
-/*! \brief Add header to SIP message */
-static int add_header(struct sip_request *req, const char *var, const char *value)
-{
- int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
-
- if (req->headers == SIP_MAX_HEADERS) {
- ast_log(LOG_WARNING, "Out of SIP header space\n");
- return -1;
- }
-
- if (req->lines) {
- ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
- return -1;
- }
-
- if (maxlen <= 0) {
- ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
- return -1;
- }
-
- req->header[req->headers] = req->data + req->len;
-
- if (compactheaders)
- var = find_alias(var, var);
-
- snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
- req->len += strlen(req->header[req->headers]);
- req->headers++;
-
- return 0;
-}
-
-/*! \brief Add 'Content-Length' header to SIP message */
-static int add_header_contentLength(struct sip_request *req, int len)
-{
- char clen[10];
-
- snprintf(clen, sizeof(clen), "%d", len);
- return add_header(req, "Content-Length", clen);
-}
-
-/*! \brief Add content (not header) to SIP message */
-static int add_line(struct sip_request *req, const char *line)
-{
- if (req->lines == SIP_MAX_LINES) {
- ast_log(LOG_WARNING, "Out of SIP line space\n");
- return -1;
- }
- if (!req->lines) {
- /* Add extra empty return */
- snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
- req->len += strlen(req->data + req->len);
- }
- if (req->len >= sizeof(req->data) - 4) {
- ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
- return -1;
- }
- req->line[req->lines] = req->data + req->len;
- snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
- req->len += strlen(req->line[req->lines]);
- req->lines++;
- return 0;
-}
-
-/*! \brief Copy one header field from one request to another */
-static int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field)
-{
- const char *tmp = get_header(orig, field);
-
- if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
- return add_header(req, field, tmp);
- ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
- return -1;
-}
-
-/*! \brief Copy all headers from one request to another */
-static int copy_all_header(struct sip_request *req, const struct sip_request *orig, const char *field)
-{
- int start = 0;
- int copied = 0;
- for (;;) {
- const char *tmp = __get_header(orig, field, &start);
-
- if (ast_strlen_zero(tmp))
- break;
- /* Add what we're responding to */
- add_header(req, field, tmp);
- copied++;
- }
- return copied ? 0 : -1;
-}
-
-/*! \brief Copy SIP VIA Headers from the request to the response
-\note If the client indicates that it wishes to know the port we received from,
- it adds ;rport without an argument to the topmost via header. We need to
- add the port number (from our point of view) to that parameter.
- We always add ;received=<ip address> to the topmost via header.
- Received: RFC 3261, rport RFC 3581 */
-static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
-{
- int copied = 0;
- int start = 0;
-
- for (;;) {
- char new[512];
- const char *oh = __get_header(orig, field, &start);
-
- if (ast_strlen_zero(oh))
- break;
-
- if (!copied) { /* Only check for empty rport in topmost via header */
- char leftmost[512], *others, *rport;
-
- /* Only work on leftmost value */
- ast_copy_string(leftmost, oh, sizeof(leftmost));
- others = strchr(leftmost, ',');
- if (others)
- *others++ = '\0';
-
- /* Find ;rport; (empty request) */
- rport = strstr(leftmost, ";rport");
- if (rport && *(rport+6) == '=')
- rport = NULL; /* We already have a parameter to rport */
-
- /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */
- if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
- /* We need to add received port - rport */
- char *end;
-
- rport = strstr(leftmost, ";rport");
-
- if (rport) {
- end = strchr(rport + 1, ';');
- if (end)
- memmove(rport, end, strlen(end) + 1);
- else
- *rport = '\0';
- }
-
- /* Add rport to first VIA header if requested */
- snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
- leftmost, ast_inet_ntoa(p->recv.sin_addr),
- ntohs(p->recv.sin_port),
- others ? "," : "", others ? others : "");
- } else {
- /* We should *always* add a received to the topmost via */
- snprintf(new, sizeof(new), "%s;received=%s%s%s",
- leftmost, ast_inet_ntoa(p->recv.sin_addr),
- others ? "," : "", others ? others : "");
- }
- oh = new; /* the header to copy */
- } /* else add the following via headers untouched */
- add_header(req, field, oh);
- copied++;
- }
- if (!copied) {
- ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
- return -1;
- }
- return 0;
-}
-
-/*! \brief Add route header into request per learned route */
-static void add_route(struct sip_request *req, struct sip_route *route)
-{
- char r[SIPBUFSIZE*2], *p;
- int n, rem = sizeof(r);
-
- if (!route)
- return;
-
- p = r;
- for (;route ; route = route->next) {
- n = strlen(route->hop);
- if (rem < n+3) /* we need room for ",<route>" */
- break;
- if (p != r) { /* add a separator after fist route */
- *p++ = ',';
- --rem;
- }
- *p++ = '<';
- ast_copy_string(p, route->hop, rem); /* cannot fail */
- p += n;
- *p++ = '>';
- rem -= (n+2);
- }
- *p = '\0';
- add_header(req, "Route", r);
-}
-
-/*! \brief Set destination from SIP URI */
-static void set_destination(struct sip_pvt *p, char *uri)
-{
- char *h, *maddr, hostname[256];
- int port, hn;
- struct hostent *hp;
- struct ast_hostent ahp;
- int debug=sip_debug_test_pvt(p);
-
- /* Parse uri to h (host) and port - uri is already just the part inside the <> */
- /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
-
- if (debug)
- ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
-
- /* Find and parse hostname */
- h = strchr(uri, '@');
- if (h)
- ++h;
- else {
- h = uri;
- if (strncasecmp(h, "sip:", 4) == 0)
- h += 4;
- else if (strncasecmp(h, "sips:", 5) == 0)
- h += 5;
- }
- hn = strcspn(h, ":;>") + 1;
- if (hn > sizeof(hostname))
- hn = sizeof(hostname);
- ast_copy_string(hostname, h, hn);
- /* XXX bug here if string has been trimmed to sizeof(hostname) */
- h += hn - 1;
-
- /* Is "port" present? if not default to STANDARD_SIP_PORT */
- if (*h == ':') {
- /* Parse port */
- ++h;
- port = strtol(h, &h, 10);
- }
- else
- port = STANDARD_SIP_PORT;
-
- /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
- maddr = strstr(h, "maddr=");
- if (maddr) {
- maddr += 6;
- hn = strspn(maddr, "0123456789.") + 1;
- if (hn > sizeof(hostname))
- hn = sizeof(hostname);
- ast_copy_string(hostname, maddr, hn);
- }
-
- hp = ast_gethostbyname(hostname, &ahp);
- if (hp == NULL) {
- ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
- return;
- }
- p->sa.sin_family = AF_INET;
- memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
- p->sa.sin_port = htons(port);
- if (debug)
- ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
-}
-
-/*! \brief Initialize SIP response, based on SIP request */
-static int init_resp(struct sip_request *resp, const char *msg)
-{
- /* Initialize a response */
- memset(resp, 0, sizeof(*resp));
- resp->method = SIP_RESPONSE;
- resp->header[0] = resp->data;
- snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
- resp->len = strlen(resp->header[0]);
- resp->headers++;
- return 0;
-}
-
-/*! \brief Initialize SIP request */
-static int init_req(struct sip_request *req, int sipmethod, const char *recip)
-{
- /* Initialize a request */
- memset(req, 0, sizeof(*req));
- req->method = sipmethod;
- req->header[0] = req->data;
- snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
- req->len = strlen(req->header[0]);
- req->headers++;
- return 0;
-}
-
-
-/*! \brief Prepare SIP response packet */
-static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
-{
- char newto[256];
- const char *ot;
-
- init_resp(resp, msg);
- copy_via_headers(p, resp, req, "Via");
- if (msg[0] == '1' || msg[0] == '2')
- copy_all_header(resp, req, "Record-Route");
- copy_header(resp, req, "From");
- ot = get_header(req, "To");
- if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
- /* Add the proper tag if we don't have it already. If they have specified
- their tag, use it. Otherwise, use our own tag */
- if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
- else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
- else
- ast_copy_string(newto, ot, sizeof(newto));
- ot = newto;
- }
- add_header(resp, "To", ot);
- copy_header(resp, req, "Call-ID");
- copy_header(resp, req, "CSeq");
- if (!ast_strlen_zero(global_useragent))
- add_header(resp, "User-Agent", global_useragent);
- add_header(resp, "Allow", ALLOWED_METHODS);
- add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
- if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
- /* For registration responses, we also need expiry and
- contact info */
- char tmp[256];
-
- snprintf(tmp, sizeof(tmp), "%d", p->expiry);
- add_header(resp, "Expires", tmp);
- if (p->expiry) { /* Only add contact if we have an expiry time */
- char contact[SIPBUFSIZE];
- snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
- add_header(resp, "Contact", contact); /* Not when we unregister */
- }
- } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) {
- add_header(resp, "Contact", p->our_contact);
- }
- return 0;
-}
-
-/*! \brief Initialize a SIP request message (not the initial one in a dialog) */
-static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
-{
- struct sip_request *orig = &p->initreq;
- char stripped[80];
- char tmp[80];
- char newto[256];
- const char *c;
- const char *ot, *of;
- int is_strict = FALSE; /*!< Strict routing flag */
-
- memset(req, 0, sizeof(struct sip_request));
-
- snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
-
- if (!seqno) {
- p->ocseq++;
- seqno = p->ocseq;
- }
-
- if (newbranch) {
- p->branch ^= ast_random();
- build_via(p);
- }
-
- /* Check for strict or loose router */
- if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
- is_strict = TRUE;
- if (sipdebug)
- ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
- }
-
- if (sipmethod == SIP_CANCEL)
- c = p->initreq.rlPart2; /* Use original URI */
- else if (sipmethod == SIP_ACK) {
- /* Use URI from Contact: in 200 OK (if INVITE)
- (we only have the contacturi on INVITEs) */
- if (!ast_strlen_zero(p->okcontacturi))
- c = is_strict ? p->route->hop : p->okcontacturi;
- else
- c = p->initreq.rlPart2;
- } else if (!ast_strlen_zero(p->okcontacturi))
- c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
- else if (!ast_strlen_zero(p->uri))
- c = p->uri;
- else {
- char *n;
- /* We have no URI, use To: or From: header as URI (depending on direction) */
- ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
- sizeof(stripped));
- n = get_in_brackets(stripped);
- c = strsep(&n, ";"); /* trim ; and beyond */
- }
- init_req(req, sipmethod, c);
-
- snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
-
- add_header(req, "Via", p->via);
- if (p->route) {
- set_destination(p, p->route->hop);
- add_route(req, is_strict ? p->route->next : p->route);
- }
-
- ot = get_header(orig, "To");
- of = get_header(orig, "From");
-
- /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
- as our original request, including tag (or presumably lack thereof) */
- if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
- /* Add the proper tag if we don't have it already. If they have specified
- their tag, use it. Otherwise, use our own tag */
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
- else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
- else
- snprintf(newto, sizeof(newto), "%s", ot);
- ot = newto;
- }
-
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- add_header(req, "From", of);
- add_header(req, "To", ot);
- } else {
- add_header(req, "From", ot);
- add_header(req, "To", of);
- }
- /* Do not add Contact for MESSAGE, BYE and Cancel requests */
- if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
- add_header(req, "Contact", p->our_contact);
-
- copy_header(req, orig, "Call-ID");
- add_header(req, "CSeq", tmp);
-
- if (!ast_strlen_zero(global_useragent))
- add_header(req, "User-Agent", global_useragent);
- add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
-
- if (!ast_strlen_zero(p->rpid))
- add_header(req, "Remote-Party-ID", p->rpid);
-
- return 0;
-}
-
-/*! \brief Base transmit response function */
-static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
-{
- struct sip_request resp;
- int seqno = 0;
-
- if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
- ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
- return -1;
- }
- respprep(&resp, p, msg, req);
- add_header_contentLength(&resp, 0);
- /* If we are cancelling an incoming invite for some reason, add information
- about the reason why we are doing this in clear text */
- if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
- char buf[10];
-
- add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
- snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
- add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
- }
- return send_response(p, &resp, reliable, seqno);
-}
-
-static void temp_pvt_cleanup(void *data)
-{
- struct sip_pvt *p = data;
-
- ast_string_field_free_memory(p);
-
- free(data);
-}
-
-/*! \brief Transmit response, no retransmits, using a temporary pvt structure */
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
-{
- struct sip_pvt *p = NULL;
-
- if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
- ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
- return -1;
- }
-
- /* if the structure was just allocated, initialize it */
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
- ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
- if (ast_string_field_init(p, 512))
- return -1;
- }
-
- /* Initialize the bare minimum */
- p->method = intended_method;
-
- if (sin) {
- p->sa = *sin;
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
- } else
- p->ourip = __ourip;
-
- p->branch = ast_random();
- make_our_tag(p->tag, sizeof(p->tag));
- p->ocseq = INITIAL_CSEQ;
-
- if (useglobal_nat && sin) {
- ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
- p->recv = *sin;
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
- }
- check_via(p, req);
-
- ast_string_field_set(p, fromdomain, default_fromdomain);
- build_via(p);
- ast_string_field_set(p, callid, callid);
-
- /* Use this temporary pvt structure to send the message */
- __transmit_response(p, msg, req, XMIT_UNRELIABLE);
-
- /* Free the string fields, but not the pool space */
- ast_string_field_reset_all(p);
-
- return 0;
-}
-
-/*! \brief Transmit response, no retransmits */
-static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req)
-{
- return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
-}
-
-/*! \brief Transmit response, no retransmits */
-static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
-{
- struct sip_request resp;
- respprep(&resp, p, msg, req);
- append_date(&resp);
- add_header(&resp, "Unsupported", unsupported);
- add_header_contentLength(&resp, 0);
- return send_response(p, &resp, XMIT_UNRELIABLE, 0);
-}
-
-/*! \brief Transmit response, Make sure you get an ACK
- This is only used for responses to INVITEs, where we need to make sure we get an ACK
-*/
-static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_request *req)
-{
- return __transmit_response(p, msg, req, XMIT_CRITICAL);
-}
-
-/*! \brief Append date to SIP message */
-static void append_date(struct sip_request *req)
-{
- char tmpdat[256];
- struct tm tm;
- time_t t = time(NULL);
-
- gmtime_r(&t, &tm);
- strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
- add_header(req, "Date", tmpdat);
-}
-
-/*! \brief Append date and content length before transmitting response */
-static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req)
-{
- struct sip_request resp;
- respprep(&resp, p, msg, req);
- append_date(&resp);
- add_header_contentLength(&resp, 0);
- return send_response(p, &resp, XMIT_UNRELIABLE, 0);
-}
-
-/*! \brief Append Accept header, content length before transmitting response */
-static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
-{
- struct sip_request resp;
- respprep(&resp, p, msg, req);
- add_header(&resp, "Accept", "application/sdp");
- add_header_contentLength(&resp, 0);
- return send_response(p, &resp, reliable, 0);
-}
-
-/*! \brief Respond with authorization request */
-static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
-{
- struct sip_request resp;
- char tmp[512];
- int seqno = 0;
-
- if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
- ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
- return -1;
- }
- /* Stale means that they sent us correct authentication, but
- based it on an old challenge (nonce) */
- snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
- respprep(&resp, p, msg, req);
- add_header(&resp, header, tmp);
- add_header_contentLength(&resp, 0);
- append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
- return send_response(p, &resp, reliable, seqno);
-}
-
-/*! \brief Add text body to SIP message */
-static int add_text(struct sip_request *req, const char *text)
-{
- /* XXX Convert \n's to \r\n's XXX */
- add_header(req, "Content-Type", "text/plain");
- add_header_contentLength(req, strlen(text));
- add_line(req, text);
- return 0;
-}
-
-/*! \brief Add DTMF INFO tone to sip message */
-/* Always adds default duration 250 ms, regardless of what came in over the line */
-static int add_digit(struct sip_request *req, char digit, unsigned int duration)
-{
- char tmp[256];
-
- snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
- add_header(req, "Content-Type", "application/dtmf-relay");
- add_header_contentLength(req, strlen(tmp));
- add_line(req, tmp);
- return 0;
-}
-
-/*! \brief add XML encoded media control with update
- \note XML: The only way to turn 0 bits of information into a few hundred. (markster) */
-static int add_vidupdate(struct sip_request *req)
-{
- const char *xml_is_a_huge_waste_of_space =
- "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
- " <media_control>\r\n"
- " <vc_primitive>\r\n"
- " <to_encoder>\r\n"
- " <picture_fast_update>\r\n"
- " </picture_fast_update>\r\n"
- " </to_encoder>\r\n"
- " </vc_primitive>\r\n"
- " </media_control>\r\n";
- add_header(req, "Content-Type", "application/media_control+xml");
- add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
- add_line(req, xml_is_a_huge_waste_of_space);
- return 0;
-}
-
-/*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
- char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
- int debug, int *min_packet_size)
-{
- int rtp_code;
- struct ast_format_list fmt;
-
-
- if (debug)
- ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
- if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
- return;
-
- if (p->rtp) {
- struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
- fmt = ast_codec_pref_getsize(pref, codec);
- } else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
- return;
- ast_build_string(m_buf, m_size, " %d", rtp_code);
- ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
- ast_rtp_lookup_mime_subtype(1, codec,
- ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
- sample_rate);
- if (codec == AST_FORMAT_G729A) {
- /* Indicate that we don't support VAD (G.729 annex B) */
- ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
- } else if (codec == AST_FORMAT_G723_1) {
- /* Indicate that we don't support VAD (G.723.1 annex A) */
- ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
- } else if (codec == AST_FORMAT_ILBC) {
- /* Add information about us using only 20/30 ms packetization */
- ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
- }
-
- if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
- *min_packet_size = fmt.cur_ms;
-
- /* Our first codec packetization processed cannot be less than zero */
- if ((*min_packet_size) == 0 && fmt.cur_ms)
- *min_packet_size = fmt.cur_ms;
-}
-
-/*! \brief Get Max T.38 Transmission rate from T38 capabilities */
-static int t38_get_rate(int t38cap)
-{
- int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
-
- if (maxrate & T38FAX_RATE_14400) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
- return 14400;
- } else if (maxrate & T38FAX_RATE_12000) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
- return 12000;
- } else if (maxrate & T38FAX_RATE_9600) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
- return 9600;
- } else if (maxrate & T38FAX_RATE_7200) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
- return 7200;
- } else if (maxrate & T38FAX_RATE_4800) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
- return 4800;
- } else if (maxrate & T38FAX_RATE_2400) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
- return 2400;
- } else {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
- return 0;
- }
-}
-
-/*! \brief Add T.38 Session Description Protocol message */
-static int add_t38_sdp(struct sip_request *resp, struct sip_pvt *p)
-{
- int len = 0;
- int x = 0;
- struct sockaddr_in udptlsin;
- char v[256] = "";
- char s[256] = "";
- char o[256] = "";
- char c[256] = "";
- char t[256] = "";
- char m_modem[256];
- char a_modem[1024];
- char *m_modem_next = m_modem;
- size_t m_modem_left = sizeof(m_modem);
- char *a_modem_next = a_modem;
- size_t a_modem_left = sizeof(a_modem);
- struct sockaddr_in udptldest = { 0, };
- int debug;
-
- debug = sip_debug_test_pvt(p);
- len = 0;
- if (!p->udptl) {
- ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
- return -1;
- }
-
- if (!p->sessionid) {
- p->sessionid = getpid();
- p->sessionversion = p->sessionid;
- } else
- p->sessionversion++;
-
- /* Our T.38 end is */
- ast_udptl_get_us(p->udptl, &udptlsin);
-
- /* Determine T.38 UDPTL destination */
- if (p->udptlredirip.sin_addr.s_addr) {
- udptldest.sin_port = p->udptlredirip.sin_port;
- udptldest.sin_addr = p->udptlredirip.sin_addr;
- } else {
- udptldest.sin_addr = p->ourip;
- udptldest.sin_port = udptlsin.sin_port;
- }
-
- if (debug)
- ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
-
- /* We break with the "recommendation" and send our IP, in order that our
- peer doesn't have to ast_gethostbyname() us */
-
- if (debug) {
- ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
- p->t38.capability,
- p->t38.peercapability,
- p->t38.jointcapability);
- }
- snprintf(v, sizeof(v), "v=0\r\n");
- snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
- snprintf(s, sizeof(s), "s=session\r\n");
- snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
- snprintf(t, sizeof(t), "t=0 0\r\n");
- ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
-
- if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
- if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
- if ((x = t38_get_rate(p->t38.jointcapability)))
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
- x = ast_udptl_get_local_max_datagram(p->udptl);
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
- if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
- ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
- len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
- add_header(resp, "Content-Type", "application/sdp");
- add_header_contentLength(resp, len);
- add_line(resp, v);
- add_line(resp, o);
- add_line(resp, s);
- add_line(resp, c);
- add_line(resp, t);
- add_line(resp, m_modem);
- add_line(resp, a_modem);
-
- /* Update lastrtprx when we send our SDP */
- p->lastrtprx = p->lastrtptx = time(NULL);
-
- return 0;
-}
-
-
-/*! \brief Add RFC 2833 DTMF offer to SDP */
-static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
- char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
- int debug)
-{
- int rtp_code;
-
- if (debug)
- ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
- if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
- return;
-
- ast_build_string(m_buf, m_size, " %d", rtp_code);
- ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
- ast_rtp_lookup_mime_subtype(0, format, 0),
- sample_rate);
- if (format == AST_RTP_DTMF)
- /* Indicate we support DTMF and FLASH... */
- ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
-}
-
-/*!
- * \note G.722 actually is supposed to specified as 8 kHz, even though it is
- * really 16 kHz. Update this macro for other formats as they are added in
- * the future.
- */
-#define SDP_SAMPLE_RATE(x) 8000
-
-/*! \brief Add Session Description Protocol message */
-static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p)
-{
- int len = 0;
- int alreadysent = 0;
-
- struct sockaddr_in sin;
- struct sockaddr_in vsin;
- struct sockaddr_in dest;
- struct sockaddr_in vdest = { 0, };
-
- /* SDP fields */
- char *version = "v=0\r\n"; /* Protocol version */
- char *subject = "s=session\r\n"; /* Subject of the session */
- char owner[256]; /* Session owner/creator */
- char connection[256]; /* Connection data */
- char *stime = "t=0 0\r\n"; /* Time the session is active */
- char bandwidth[256] = ""; /* Max bitrate */
- char *hold;
- char m_audio[256]; /* Media declaration line for audio */
- char m_video[256]; /* Media declaration line for video */
- char a_audio[1024]; /* Attributes for audio */
- char a_video[1024]; /* Attributes for video */
- char *m_audio_next = m_audio;
- char *m_video_next = m_video;
- size_t m_audio_left = sizeof(m_audio);
- size_t m_video_left = sizeof(m_video);
- char *a_audio_next = a_audio;
- char *a_video_next = a_video;
- size_t a_audio_left = sizeof(a_audio);
- size_t a_video_left = sizeof(a_video);
-
- int x;
- int capability;
- int needvideo = FALSE;
- int debug = sip_debug_test_pvt(p);
- int min_audio_packet_size = 0;
- int min_video_packet_size = 0;
-
- m_video[0] = '\0'; /* Reset the video media string if it's not needed */
-
- if (!p->rtp) {
- ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
- return AST_FAILURE;
- }
-
- /* Set RTP Session ID and version */
- if (!p->sessionid) {
- p->sessionid = getpid();
- p->sessionversion = p->sessionid;
- } else
- p->sessionversion++;
-
- /* Get our addresses */
- ast_rtp_get_us(p->rtp, &sin);
- if (p->vrtp)
- ast_rtp_get_us(p->vrtp, &vsin);
-
- /* Is this a re-invite to move the media out, then use the original offer from caller */
- if (p->redirip.sin_addr.s_addr) {
- dest.sin_port = p->redirip.sin_port;
- dest.sin_addr = p->redirip.sin_addr;
- } else {
- dest.sin_addr = p->ourip;
- dest.sin_port = sin.sin_port;
- }
-
- capability = p->jointcapability;
-
-
- if (option_debug > 1) {
- char codecbuf[SIPBUFSIZE];
- ast_log(LOG_DEBUG, "** Our capability: %s Video flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), ast_test_flag(&p->flags[0], SIP_NOVIDEO) ? "True" : "False");
- ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
- }
-
-#ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
- if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
- ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
- ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
- }
-#endif
-
- /* Check if we need video in this call */
- if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
- if (p->vrtp) {
- needvideo = TRUE;
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "This call needs video offers!\n");
- } else if (option_debug > 1)
- ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
- }
-
-
- /* Ok, we need video. Let's add what we need for video and set codecs.
- Video is handled differently than audio since we can not transcode. */
- if (needvideo) {
- /* Determine video destination */
- if (p->vredirip.sin_addr.s_addr) {
- vdest.sin_addr = p->vredirip.sin_addr;
- vdest.sin_port = p->vredirip.sin_port;
- } else {
- vdest.sin_addr = p->ourip;
- vdest.sin_port = vsin.sin_port;
- }
- ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
-
- /* Build max bitrate string */
- if (p->maxcallbitrate)
- snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
- if (debug)
- ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));
- }
-
- if (debug)
- ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port));
-
- /* Start building generic SDP headers */
-
- /* We break with the "recommendation" and send our IP, in order that our
- peer doesn't have to ast_gethostbyname() us */
-
- snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
- snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
- ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
-
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
- hold = "a=recvonly\r\n";
- else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
- hold = "a=inactive\r\n";
- else
- hold = "a=sendrecv\r\n";
-
- /* Now, start adding audio codecs. These are added in this order:
- - First what was requested by the calling channel
- - Then preferences in order from sip.conf device config for this peer/user
- - Then other codecs in capabilities, including video
- */
-
- /* Prefer the audio codec we were requested to use, first, no matter what
- Note that p->prefcodec can include video codecs, so mask them out
- */
- if (capability & p->prefcodec) {
- int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
-
- add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
- &m_audio_next, &m_audio_left,
- &a_audio_next, &a_audio_left,
- debug, &min_audio_packet_size);
- alreadysent |= codec;
- }
-
- /* Start by sending our preferred audio codecs */
- for (x = 0; x < 32; x++) {
- int codec;
-
- if (!(codec = ast_codec_pref_index(&p->prefs, x)))
- break;
-
- if (!(capability & codec))
- continue;
-
- if (alreadysent & codec)
- continue;
-
- add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
- &m_audio_next, &m_audio_left,
- &a_audio_next, &a_audio_left,
- debug, &min_audio_packet_size);
- alreadysent |= codec;
- }
-
- /* Now send any other common audio and video codecs, and non-codec formats: */
- for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
- if (!(capability & x)) /* Codec not requested */
- continue;
-
- if (alreadysent & x) /* Already added to SDP */
- continue;
-
- if (x <= AST_FORMAT_MAX_AUDIO)
- add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
- &m_audio_next, &m_audio_left,
- &a_audio_next, &a_audio_left,
- debug, &min_audio_packet_size);
- else
- add_codec_to_sdp(p, x, 90000,
- &m_video_next, &m_video_left,
- &a_video_next, &a_video_left,
- debug, &min_video_packet_size);
- }
-
- /* Now add DTMF RFC2833 telephony-event as a codec */
- for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
- if (!(p->jointnoncodeccapability & x))
- continue;
-
- add_noncodec_to_sdp(p, x, 8000,
- &m_audio_next, &m_audio_left,
- &a_audio_next, &a_audio_left,
- debug);
- }
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
-
- if (!p->owner || !ast_internal_timing_enabled(p->owner))
- ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
-
- if (min_audio_packet_size)
- ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
-
- if (min_video_packet_size)
- ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
-
- if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
- ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
-
- ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
- if (needvideo)
- ast_build_string(&m_video_next, &m_video_left, "\r\n");
-
- len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
- if (needvideo) /* only if video response is appropriate */
- len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
-
- add_header(resp, "Content-Type", "application/sdp");
- add_header_contentLength(resp, len);
- add_line(resp, version);
- add_line(resp, owner);
- add_line(resp, subject);
- add_line(resp, connection);
- if (needvideo) /* only if video response is appropriate */
- add_line(resp, bandwidth);
- add_line(resp, stime);
- add_line(resp, m_audio);
- add_line(resp, a_audio);
- add_line(resp, hold);
- if (needvideo) { /* only if video response is appropriate */
- add_line(resp, m_video);
- add_line(resp, a_video);
- add_line(resp, hold); /* Repeat hold for the video stream */
- }
-
- /* Update lastrtprx when we send our SDP */
- p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
-
- if (option_debug > 2) {
- char buf[SIPBUFSIZE];
- ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
- }
-
- return AST_SUCCESS;
-}
-
-/*! \brief Used for 200 OK and 183 early media */
-static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
-{
- struct sip_request resp;
- int seqno;
-
- if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
- ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
- return -1;
- }
- respprep(&resp, p, msg, req);
- if (p->udptl) {
- ast_udptl_offered_from_local(p->udptl, 0);
- add_t38_sdp(&resp, p);
- } else
- ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
- if (retrans && !p->pendinginvite)
- p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */
- return send_response(p, &resp, retrans, seqno);
-}
-
-/*! \brief copy SIP request (mostly used to save request for responses) */
-static void copy_request(struct sip_request *dst, const struct sip_request *src)
-{
- long offset;
- int x;
- offset = ((void *)dst) - ((void *)src);
- /* First copy stuff */
- memcpy(dst, src, sizeof(*dst));
- /* Now fix pointer arithmetic */
- for (x=0; x < src->headers; x++)
- dst->header[x] += offset;
- for (x=0; x < src->lines; x++)
- dst->line[x] += offset;
- dst->rlPart1 += offset;
- dst->rlPart2 += offset;
-}
-
-/*! \brief Used for 200 OK and 183 early media
- \return Will return XMIT_ERROR for network errors.
-*/
-static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
-{
- struct sip_request resp;
- int seqno;
- if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
- ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
- return -1;
- }
- respprep(&resp, p, msg, req);
- if (p->rtp) {
- if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
- ast_rtp_codec_setpref(p->rtp, &p->prefs);
- }
- try_suggested_sip_codec(p);
- add_sdp(&resp, p);
- } else
- ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
- if (reliable && !p->pendinginvite)
- p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */
- return send_response(p, &resp, reliable, seqno);
-}
-
-/*! \brief Parse first line of incoming SIP request */
-static int determine_firstline_parts(struct sip_request *req)
-{
- char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */
-
- if (!*e)
- return -1;
- req->rlPart1 = e; /* method or protocol */
- e = ast_skip_nonblanks(e);
- if (*e)
- *e++ = '\0';
- /* Get URI or status code */
- e = ast_skip_blanks(e);
- if ( !*e )
- return -1;
- ast_trim_blanks(e);
-
- if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
- if (strlen(e) < 3) /* status code is 3 digits */
- return -1;
- req->rlPart2 = e;
- } else { /* We have a request */
- if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
- ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
- e++;
- if (!*e)
- return -1;
- }
- req->rlPart2 = e; /* URI */
- e = ast_skip_nonblanks(e);
- if (*e)
- *e++ = '\0';
- e = ast_skip_blanks(e);
- if (strcasecmp(e, "SIP/2.0") ) {
- ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
- return -1;
- }
- }
- return 1;
-}
-
-/*! \brief Transmit reinvite with SDP
-\note A re-invite is basically a new INVITE with the same CALL-ID and TAG as the
- INVITE that opened the SIP dialogue
- We reinvite so that the audio stream (RTP) go directly between
- the SIP UAs. SIP Signalling stays with * in the path.
-*/
-static int transmit_reinvite_with_sdp(struct sip_pvt *p)
-{
- struct sip_request req;
-
- reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
-
- add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
- if (sipdebug)
- add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "ReInv", "Re-invite sent");
- add_sdp(&req, p);
- /* Use this as the basis */
- initialize_initreq(p, &req);
- p->lastinvite = p->ocseq;
- ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */
- return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
-}
-
-/*! \brief Transmit reinvite with T38 SDP
- We reinvite so that the T38 processing can take place.
- SIP Signalling stays with * in the path.
-*/
-static int transmit_reinvite_with_t38_sdp(struct sip_pvt *p)
-{
- struct sip_request req;
-
- reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
-
- add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
- if (sipdebug)
- add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
- ast_udptl_offered_from_local(p->udptl, 1);
- add_t38_sdp(&req, p);
- /* Use this as the basis */
- initialize_initreq(p, &req);
- ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */
- p->lastinvite = p->ocseq;
- return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
-}
-
-/*! \brief Check Contact: URI of SIP message */
-static void extract_uri(struct sip_pvt *p, struct sip_request *req)
-{
- char stripped[SIPBUFSIZE];
- char *c;
-
- ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
- c = get_in_brackets(stripped);
- c = strsep(&c, ";"); /* trim ; and beyond */
- if (!ast_strlen_zero(c))
- ast_string_field_set(p, uri, c);
-}
-
-/*! \brief Build contact header - the contact header we send out */
-static void build_contact(struct sip_pvt *p)
-{
- /* Construct Contact: header */
- if (ourport != STANDARD_SIP_PORT)
- ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), ourport);
- else
- ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
-}
-
-/*! \brief Build the Remote Party-ID & From using callingpres options */
-static void build_rpid(struct sip_pvt *p)
-{
- int send_pres_tags = TRUE;
- const char *privacy=NULL;
- const char *screen=NULL;
- char buf[256];
- const char *clid = default_callerid;
- const char *clin = NULL;
- const char *fromdomain;
-
- if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))
- return;
-
- if (p->owner && p->owner->cid.cid_num)
- clid = p->owner->cid.cid_num;
- if (p->owner && p->owner->cid.cid_name)
- clin = p->owner->cid.cid_name;
- if (ast_strlen_zero(clin))
- clin = clid;
-
- switch (p->callingpres) {
- case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
- privacy = "off";
- screen = "no";
- break;
- case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
- privacy = "off";
- screen = "yes";
- break;
- case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
- privacy = "off";
- screen = "no";
- break;
- case AST_PRES_ALLOWED_NETWORK_NUMBER:
- privacy = "off";
- screen = "yes";
- break;
- case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
- privacy = "full";
- screen = "no";
- break;
- case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
- privacy = "full";
- screen = "yes";
- break;
- case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
- privacy = "full";
- screen = "no";
- break;
- case AST_PRES_PROHIB_NETWORK_NUMBER:
- privacy = "full";
- screen = "yes";
- break;
- case AST_PRES_NUMBER_NOT_AVAILABLE:
- send_pres_tags = FALSE;
- break;
- default:
- ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
- if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
- privacy = "full";
- else
- privacy = "off";
- screen = "no";
- break;
- }
-
- fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
-
- snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
- if (send_pres_tags)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
- ast_string_field_set(p, rpid, buf);
-
- ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
- S_OR(p->fromuser, clid),
- fromdomain, p->tag);
-}
-
-/*! \brief Initiate new SIP request to peer/user */
-static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod)
-{
- char invite_buf[256] = "";
- char *invite = invite_buf;
- size_t invite_max = sizeof(invite_buf);
- char from[256];
- char to[256];
- char tmp[SIPBUFSIZE/2];
- char tmp2[SIPBUFSIZE/2];
- const char *l = NULL, *n = NULL;
- const char *urioptions = "";
-
- if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
- const char *s = p->username; /* being a string field, cannot be NULL */
-
- /* Test p->username against allowed characters in AST_DIGIT_ANY
- If it matches the allowed characters list, then sipuser = ";user=phone"
- If not, then sipuser = ""
- */
- /* + is allowed in first position in a tel: uri */
- if (*s == '+')
- s++;
- for (; *s; s++) {
- if (!strchr(AST_DIGIT_ANYNUM, *s) )
- break;
- }
- /* If we have only digits, add ;user=phone to the uri */
- if (*s)
- urioptions = ";user=phone";
- }
-
-
- snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
-
- if (p->owner) {
- l = p->owner->cid.cid_num;
- n = p->owner->cid.cid_name;
- }
- /* if we are not sending RPID and user wants his callerid restricted */
- if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
- ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
- l = CALLERID_UNKNOWN;
- n = l;
- }
- if (ast_strlen_zero(l))
- l = default_callerid;
- if (ast_strlen_zero(n))
- n = l;
- /* Allow user to be overridden */
- if (!ast_strlen_zero(p->fromuser))
- l = p->fromuser;
- else /* Save for any further attempts */
- ast_string_field_set(p, fromuser, l);
-
- /* Allow user to be overridden */
- if (!ast_strlen_zero(p->fromname))
- n = p->fromname;
- else /* Save for any further attempts */
- ast_string_field_set(p, fromname, n);
-
- if (pedanticsipchecking) {
- ast_uri_encode(n, tmp, sizeof(tmp), 0);
- n = tmp;
- ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
- l = tmp2;
- }
-
- if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
- snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag);
- else
- snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
-
- /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
- if (!ast_strlen_zero(p->fullcontact)) {
- /* If we have full contact, trust it */
- ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
- } else {
- /* Otherwise, use the username while waiting for registration */
- ast_build_string(&invite, &invite_max, "sip:");
- if (!ast_strlen_zero(p->username)) {
- n = p->username;
- if (pedanticsipchecking) {
- ast_uri_encode(n, tmp, sizeof(tmp), 0);
- n = tmp;
- }
- ast_build_string(&invite, &invite_max, "%s@", n);
- }
- ast_build_string(&invite, &invite_max, "%s", p->tohost);
- if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
- ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
- ast_build_string(&invite, &invite_max, "%s", urioptions);
- }
-
- /* If custom URI options have been provided, append them */
- if (p->options && !ast_strlen_zero(p->options->uri_options))
- ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
-
- ast_string_field_set(p, uri, invite_buf);
-
- if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
- /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
- snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag);
- } else if (p->options && p->options->vxml_url) {
- /* If there is a VXML URL append it to the SIP URL */
- snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
- } else
- snprintf(to, sizeof(to), "<%s>", p->uri);
-
- init_req(req, sipmethod, p->uri);
- snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
-
- add_header(req, "Via", p->via);
- /* SLD: FIXME?: do Route: here too? I think not cos this is the first request.
- * OTOH, then we won't have anything in p->route anyway */
- /* Build Remote Party-ID and From */
- if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
- build_rpid(p);
- add_header(req, "From", p->rpid_from);
- } else
- add_header(req, "From", from);
- add_header(req, "To", to);
- ast_string_field_set(p, exten, l);
- build_contact(p);
- add_header(req, "Contact", p->our_contact);
- add_header(req, "Call-ID", p->callid);
- add_header(req, "CSeq", tmp);
- if (!ast_strlen_zero(global_useragent))
- add_header(req, "User-Agent", global_useragent);
- add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
- if (!ast_strlen_zero(p->rpid))
- add_header(req, "Remote-Party-ID", p->rpid);
-}
-
-/*! \brief Build REFER/INVITE/OPTIONS message and transmit it */
-static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
-{
- struct sip_request req;
-
- req.method = sipmethod;
- if (init) { /* Seems like init always is 2 */
- /* Bump branch even on initial requests */
- p->branch ^= ast_random();
- build_via(p);
- if (init > 1)
- initreqprep(&req, p, sipmethod);
- else
- reqprep(&req, p, sipmethod, 0, 1);
- } else
- reqprep(&req, p, sipmethod, 0, 1);
-
- if (p->options && p->options->auth)
- add_header(&req, p->options->authheader, p->options->auth);
- append_date(&req);
- if (sipmethod == SIP_REFER) { /* Call transfer */
- if (p->refer) {
- char buf[SIPBUFSIZE];
- if (!ast_strlen_zero(p->refer->refer_to))
- add_header(&req, "Refer-To", p->refer->refer_to);
- if (!ast_strlen_zero(p->refer->referred_by)) {
- snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
- add_header(&req, "Referred-By", buf);
- }
- }
- }
- /* This new INVITE is part of an attended transfer. Make sure that the
- other end knows and replace the current call with this new call */
- if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
- add_header(&req, "Replaces", p->options->replaces);
- add_header(&req, "Require", "replaces");
- }
-
- add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
- if (p->options && p->options->addsipheaders && p->owner) {
- struct ast_channel *chan = p->owner; /* The owner channel */
- struct varshead *headp;
-
- ast_channel_lock(chan);
-
- headp = &chan->varshead;
-
- if (!headp)
- ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
- else {
- const struct ast_var_t *current;
- AST_LIST_TRAVERSE(headp, current, entries) {
- /* SIPADDHEADER: Add SIP header to outgoing call */
- if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
- char *content, *end;
- const char *header = ast_var_value(current);
- char *headdup = ast_strdupa(header);
-
- /* Strip of the starting " (if it's there) */
- if (*headdup == '"')
- headdup++;
- if ((content = strchr(headdup, ':'))) {
- *content++ = '\0';
- content = ast_skip_blanks(content); /* Skip white space */
- /* Strip the ending " (if it's there) */
- end = content + strlen(content) -1;
- if (*end == '"')
- *end = '\0';
-
- add_header(&req, headdup, content);
- if (sipdebug)
- ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
- }
- }
- }
- }
-
- ast_channel_unlock(chan);
- }
- if (sdp) {
- if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) {
- ast_udptl_offered_from_local(p->udptl, 1);
- if (option_debug)
- ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- add_t38_sdp(&req, p);
- } else if (p->rtp)
- add_sdp(&req, p);
- } else {
- add_header_contentLength(&req, 0);
- }
-
- if (!p->initreq.headers)
- initialize_initreq(p, &req);
- p->lastinvite = p->ocseq;
- return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Used in the SUBSCRIBE notification subsystem */
-static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout)
-{
- char tmp[4000], from[256], to[256];
- char *t = tmp, *c, *mfrom, *mto;
- size_t maxbytes = sizeof(tmp);
- struct sip_request req;
- char hint[AST_MAX_EXTENSION];
- char *statestring = "terminated";
- const struct cfsubscription_types *subscriptiontype;
- enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
- char *pidfstate = "--";
- char *pidfnote= "Ready";
-
- memset(from, 0, sizeof(from));
- memset(to, 0, sizeof(to));
- memset(tmp, 0, sizeof(tmp));
-
- switch (state) {
- case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
- statestring = (global_notifyringing) ? "early" : "confirmed";
- local_state = NOTIFY_INUSE;
- pidfstate = "busy";
- pidfnote = "Ringing";
- break;
- case AST_EXTENSION_RINGING:
- statestring = "early";
- local_state = NOTIFY_INUSE;
- pidfstate = "busy";
- pidfnote = "Ringing";
- break;
- case AST_EXTENSION_INUSE:
- statestring = "confirmed";
- local_state = NOTIFY_INUSE;
- pidfstate = "busy";
- pidfnote = "On the phone";
- break;
- case AST_EXTENSION_BUSY:
- statestring = "confirmed";
- local_state = NOTIFY_CLOSED;
- pidfstate = "busy";
- pidfnote = "On the phone";
- break;
- case AST_EXTENSION_UNAVAILABLE:
- statestring = "terminated";
- local_state = NOTIFY_CLOSED;
- pidfstate = "away";
- pidfnote = "Unavailable";
- break;
- case AST_EXTENSION_ONHOLD:
- statestring = "confirmed";
- local_state = NOTIFY_CLOSED;
- pidfstate = "busy";
- pidfnote = "On Hold";
- break;
- case AST_EXTENSION_NOT_INUSE:
- default:
- /* Default setting */
- break;
- }
-
- subscriptiontype = find_subscription_type(p->subscribed);
-
- /* Check which device/devices we are watching and if they are registered */
- if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
- char *hint2 = hint, *individual_hint = NULL;
- int hint_count = 0, unavailable_count = 0;
-
- while ((individual_hint = strsep(&hint2, "&"))) {
- hint_count++;
-
- if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
- unavailable_count++;
- }
-
- /* If none of the hinted devices are registered, we will
- * override notification and show no availability.
- */
- if (hint_count > 0 && hint_count == unavailable_count) {
- local_state = NOTIFY_CLOSED;
- pidfstate = "away";
- pidfnote = "Not online";
- }
- }
-
- ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
- c = get_in_brackets(from);
- if (strncasecmp(c, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
- return -1;
- }
- mfrom = strsep(&c, ";"); /* trim ; and beyond */
-
- ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
- c = get_in_brackets(to);
- if (strncasecmp(c, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
- return -1;
- }
- mto = strsep(&c, ";"); /* trim ; and beyond */
-
- reqprep(&req, p, SIP_NOTIFY, 0, 1);
-
-
- add_header(&req, "Event", subscriptiontype->event);
- add_header(&req, "Content-Type", subscriptiontype->mediatype);
- switch(state) {
- case AST_EXTENSION_DEACTIVATED:
- if (timeout)
- add_header(&req, "Subscription-State", "terminated;reason=timeout");
- else {
- add_header(&req, "Subscription-State", "terminated;reason=probation");
- add_header(&req, "Retry-After", "60");
- }
- break;
- case AST_EXTENSION_REMOVED:
- add_header(&req, "Subscription-State", "terminated;reason=noresource");
- break;
- default:
- if (p->expiry)
- add_header(&req, "Subscription-State", "active");
- else /* Expired */
- add_header(&req, "Subscription-State", "terminated;reason=timeout");
- }
- switch (p->subscribed) {
- case XPIDF_XML:
- case CPIM_PIDF_XML:
- ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
- ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
- ast_build_string(&t, &maxbytes, "<presence>\n");
- ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
- ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
- ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
- ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
- ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
- ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
- break;
- case PIDF_XML: /* Eyebeam supports this format */
- ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
- ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
- ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
- if (pidfstate[0] != '-')
- ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
- ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
- ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
- ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
- ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
- if (pidfstate[0] == 'b') /* Busy? Still open ... */
- ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
- else
- ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
- ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
- break;
- case DIALOG_INFO_XML: /* SNOM subscribes in this format */
- ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
- ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
- if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
- ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
- else
- ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
- ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
- if (state == AST_EXTENSION_ONHOLD) {
- ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
- "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
- "</target>\n</local>\n", mto);
- }
- ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
- break;
- case NONE:
- default:
- break;
- }
-
- if (t > tmp + sizeof(tmp))
- ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n");
-
- add_header_contentLength(&req, strlen(tmp));
- add_line(&req, tmp);
- p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
-
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Notify user of messages waiting in voicemail
-\note - Notification only works for registered peers with mailbox= definitions
- in sip.conf
- - We use the SIP Event package message-summary
- MIME type defaults to "application/simple-message-summary";
- */
-static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
-{
- struct sip_request req;
- char tmp[500];
- char *t = tmp;
- size_t maxbytes = sizeof(tmp);
-
- initreqprep(&req, p, SIP_NOTIFY);
- add_header(&req, "Event", "message-summary");
- add_header(&req, "Content-Type", default_notifymime);
-
- ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
- ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
- S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
- /* Cisco has a bug in the SIP stack where it can't accept the
- (0/0) notification. This can temporarily be disabled in
- sip.conf with the "buggymwi" option */
- ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d%s\r\n", newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)"));
-
- if (p->subscribed) {
- if (p->expiry)
- add_header(&req, "Subscription-State", "active");
- else /* Expired */
- add_header(&req, "Subscription-State", "terminated;reason=timeout");
- }
-
- if (t > tmp + sizeof(tmp))
- ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n");
-
- add_header_contentLength(&req, strlen(tmp));
- add_line(&req, tmp);
-
- if (!p->initreq.headers)
- initialize_initreq(p, &req);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Transmit SIP request unreliably (only used in sip_notify subsystem) */
-static int transmit_sip_request(struct sip_pvt *p, struct sip_request *req)
-{
- if (!p->initreq.headers) /* Initialize first request before sending */
- initialize_initreq(p, req);
- return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
-}
-
-/*! \brief Notify a transferring party of the status of transfer */
-static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *message, int terminate)
-{
- struct sip_request req;
- char tmp[SIPBUFSIZE/2];
-
- reqprep(&req, p, SIP_NOTIFY, 0, 1);
- snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
- add_header(&req, "Event", tmp);
- add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
- add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
- add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
-
- snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
- add_header_contentLength(&req, strlen(tmp));
- add_line(&req, tmp);
-
- if (!p->initreq.headers)
- initialize_initreq(p, &req);
-
- p->lastnoninvite = p->ocseq;
-
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Convert registration state status to string */
-static char *regstate2str(enum sipregistrystate regstate)
-{
- switch(regstate) {
- case REG_STATE_FAILED:
- return "Failed";
- case REG_STATE_UNREGISTERED:
- return "Unregistered";
- case REG_STATE_REGSENT:
- return "Request Sent";
- case REG_STATE_AUTHSENT:
- return "Auth. Sent";
- case REG_STATE_REGISTERED:
- return "Registered";
- case REG_STATE_REJECTED:
- return "Rejected";
- case REG_STATE_TIMEOUT:
- return "Timeout";
- case REG_STATE_NOAUTH:
- return "No Authentication";
- default:
- return "Unknown";
- }
-}
-
-/*! \brief Update registration with SIP Proxy */
-static int sip_reregister(const void *data)
-{
- /* if we are here, we know that we need to reregister. */
- struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
-
- /* if we couldn't get a reference to the registry object, punt */
- if (!r)
- return 0;
-
- if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
- append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
- /* Since registry's are only added/removed by the the monitor thread, this
- may be overkill to reference/dereference at all here */
- if (sipdebug)
- ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname);
-
- r->expire = -1;
- __sip_do_register(r);
- ASTOBJ_UNREF(r, sip_registry_destroy);
- return 0;
-}
-
-/*! \brief Register with SIP proxy */
-static int __sip_do_register(struct sip_registry *r)
-{
- int res;
-
- res = transmit_register(r, SIP_REGISTER, NULL, NULL);
- return res;
-}
-
-/*! \brief Registration timeout, register again */
-static int sip_reg_timeout(const void *data)
-{
-
- /* if we are here, our registration timed out, so we'll just do it over */
- struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
- struct sip_pvt *p;
- int res;
-
- /* if we couldn't get a reference to the registry object, punt */
- if (!r)
- return 0;
-
- ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts);
- if (r->call) {
- /* Unlink us, destroy old call. Locking is not relevant here because all this happens
- in the single SIP manager thread. */
- p = r->call;
- ast_mutex_lock(&p->lock);
- if (p->registry)
- ASTOBJ_UNREF(p->registry, sip_registry_destroy);
- r->call = NULL;
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- /* Pretend to ACK anything just in case */
- __sip_pretend_ack(p);
- ast_mutex_unlock(&p->lock);
- }
- /* If we have a limit, stop registration and give up */
- if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
- /* Ok, enough is enough. Don't try any more */
- /* We could add an external notification here...
- steal it from app_voicemail :-) */
- ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
- r->regstate = REG_STATE_FAILED;
- } else {
- r->regstate = REG_STATE_UNREGISTERED;
- r->timeout = -1;
- res=transmit_register(r, SIP_REGISTER, NULL, NULL);
- }
- manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
- ASTOBJ_UNREF(r, sip_registry_destroy);
- return 0;
-}
-
-/*! \brief Transmit register to SIP proxy or UA */
-static int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
-{
- struct sip_request req;
- char from[256];
- char to[256];
- char tmp[80];
- char addr[80];
- struct sip_pvt *p;
-
- /* exit if we are already in process with this registrar ?*/
- if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
- ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
- return 0;
- }
-
- if (r->call) { /* We have a registration */
- if (!auth) {
- ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
- return 0;
- } else {
- p = r->call;
- make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */
- ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
- }
- } else {
- /* Build callid for registration if we haven't registered before */
- if (!r->callid_valid) {
- build_callid_registry(r, __ourip, default_fromdomain);
- r->callid_valid = TRUE;
- }
- /* Allocate SIP packet for registration */
- if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
- ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
- return 0;
- }
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
- /* Find address to hostname */
- if (create_addr(p, r->hostname)) {
- /* we have what we hope is a temporary network error,
- * probably DNS. We need to reschedule a registration try */
- sip_destroy(p);
-
- if (r->timeout > -1)
- ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
- else
- ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout);
-
- AST_SCHED_DEL(sched, r->timeout);
- r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
- r->regattempts++;
- return 0;
- }
- /* Copy back Call-ID in case create_addr changed it */
- ast_string_field_set(r, callid, p->callid);
- if (r->portno) {
- p->sa.sin_port = htons(r->portno);
- p->recv.sin_port = htons(r->portno);
- } else /* Set registry port to the port set from the peer definition/srv or default */
- r->portno = ntohs(p->sa.sin_port);
- ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
- r->call=p; /* Save pointer to SIP packet */
- p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */
- if (!ast_strlen_zero(r->secret)) /* Secret (password) */
- ast_string_field_set(p, peersecret, r->secret);
- if (!ast_strlen_zero(r->md5secret))
- ast_string_field_set(p, peermd5secret, r->md5secret);
- /* User name in this realm
- - if authuser is set, use that, otherwise use username */
- if (!ast_strlen_zero(r->authuser)) {
- ast_string_field_set(p, peername, r->authuser);
- ast_string_field_set(p, authname, r->authuser);
- } else if (!ast_strlen_zero(r->username)) {
- ast_string_field_set(p, peername, r->username);
- ast_string_field_set(p, authname, r->username);
- ast_string_field_set(p, fromuser, r->username);
- }
- if (!ast_strlen_zero(r->username))
- ast_string_field_set(p, username, r->username);
- /* Save extension in packet */
- ast_string_field_set(p, exten, r->contact);
-
- /*
- check which address we should use in our contact header
- based on whether the remote host is on the external or
- internal network so we can register through nat
- */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = bindaddr.sin_addr;
- build_contact(p);
- }
-
- /* set up a timeout */
- if (auth == NULL) {
- if (r->timeout > -1)
- ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
- AST_SCHED_DEL(sched, r->timeout);
- r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
- if (option_debug)
- ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout);
- }
-
- if (strchr(r->username, '@')) {
- snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
- if (!ast_strlen_zero(p->theirtag))
- snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
- else
- snprintf(to, sizeof(to), "<sip:%s>", r->username);
- } else {
- snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
- if (!ast_strlen_zero(p->theirtag))
- snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
- else
- snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
- }
-
- /* Fromdomain is what we are registering to, regardless of actual
- host name from SRV */
- if (!ast_strlen_zero(p->fromdomain)) {
- if (r->portno && r->portno != STANDARD_SIP_PORT)
- snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
- else
- snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
- } else {
- if (r->portno && r->portno != STANDARD_SIP_PORT)
- snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
- else
- snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
- }
- ast_string_field_set(p, uri, addr);
-
- p->branch ^= ast_random();
-
- init_req(&req, sipmethod, addr);
-
- /* Add to CSEQ */
- snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
- p->ocseq = r->ocseq;
-
- build_via(p);
- add_header(&req, "Via", p->via);
- add_header(&req, "From", from);
- add_header(&req, "To", to);
- add_header(&req, "Call-ID", p->callid);
- add_header(&req, "CSeq", tmp);
- if (!ast_strlen_zero(global_useragent))
- add_header(&req, "User-Agent", global_useragent);
- add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
-
-
- if (auth) /* Add auth header */
- add_header(&req, authheader, auth);
- else if (!ast_strlen_zero(r->nonce)) {
- char digest[1024];
-
- /* We have auth data to reuse, build a digest header! */
- if (sipdebug)
- ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
- ast_string_field_set(p, realm, r->realm);
- ast_string_field_set(p, nonce, r->nonce);
- ast_string_field_set(p, domain, r->domain);
- ast_string_field_set(p, opaque, r->opaque);
- ast_string_field_set(p, qop, r->qop);
- r->noncecount++;
- p->noncecount = r->noncecount;
-
- memset(digest,0,sizeof(digest));
- if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
- add_header(&req, "Authorization", digest);
- else
- ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
-
- }
-
- snprintf(tmp, sizeof(tmp), "%d", default_expiry);
- add_header(&req, "Expires", tmp);
- add_header(&req, "Contact", p->our_contact);
- add_header(&req, "Event", "registration");
- add_header_contentLength(&req, 0);
-
- initialize_initreq(p, &req);
- if (sip_debug_test_pvt(p))
- ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
- r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
- r->regattempts++; /* Another attempt */
- if (option_debug > 3)
- ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
- return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
-}
-
-/*! \brief Transmit text with SIP MESSAGE method */
-static int transmit_message_with_text(struct sip_pvt *p, const char *text)
-{
- struct sip_request req;
-
- reqprep(&req, p, SIP_MESSAGE, 0, 1);
- add_text(&req, text);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Allocate SIP refer structure */
-static int sip_refer_allocate(struct sip_pvt *p)
-{
- p->refer = ast_calloc(1, sizeof(struct sip_refer));
- return p->refer ? 1 : 0;
-}
-
-/*! \brief Transmit SIP REFER message (initiated by the transfer() dialplan application
- \note this is currently broken as we have no way of telling the dialplan
- engine whether a transfer succeeds or fails.
- \todo Fix the transfer() dialplan function so that a transfer may fail
-*/
-static int transmit_refer(struct sip_pvt *p, const char *dest)
-{
- struct sip_request req = {
- .headers = 0,
- };
- char from[256];
- const char *of;
- char *c;
- char referto[256];
- char *ttag, *ftag;
- char *theirtag = ast_strdupa(p->theirtag);
-
- if (option_debug || sipdebug)
- ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
-
- /* Are we transfering an inbound or outbound call ? */
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- of = get_header(&p->initreq, "To");
- ttag = theirtag;
- ftag = p->tag;
- } else {
- of = get_header(&p->initreq, "From");
- ftag = theirtag;
- ttag = p->tag;
- }
-
- ast_copy_string(from, of, sizeof(from));
- of = get_in_brackets(from);
- ast_string_field_set(p, from, of);
- if (strncasecmp(of, "sip:", 4))
- ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
- else
- of += 4;
- /* Get just the username part */
- if ((c = strchr(dest, '@')))
- c = NULL;
- else if ((c = strchr(of, '@')))
- *c++ = '\0';
- if (c)
- snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
- else
- snprintf(referto, sizeof(referto), "<sip:%s>", dest);
-
- /* save in case we get 407 challenge */
- sip_refer_allocate(p);
- ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
- ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
- p->refer->status = REFER_SENT; /* Set refer status */
-
- reqprep(&req, p, SIP_REFER, 0, 1);
-
- add_header(&req, "Refer-To", referto);
- add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
- if (!ast_strlen_zero(p->our_contact))
- add_header(&req, "Referred-By", p->our_contact);
-
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
- /* We should propably wait for a NOTIFY here until we ack the transfer */
- /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
-
- /*! \todo In theory, we should hang around and wait for a reply, before
- returning to the dial plan here. Don't know really how that would
- affect the transfer() app or the pbx, but, well, to make this
- useful we should have a STATUS code on transfer().
- */
-}
-
-
-/*! \brief Send SIP INFO dtmf message, see Cisco documentation on cisco.com */
-static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration)
-{
- struct sip_request req;
-
- reqprep(&req, p, SIP_INFO, 0, 1);
- add_digit(&req, digit, duration);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Send SIP INFO with video update request */
-static int transmit_info_with_vidupdate(struct sip_pvt *p)
-{
- struct sip_request req;
-
- reqprep(&req, p, SIP_INFO, 0, 1);
- add_vidupdate(&req);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
-/*! \brief Transmit generic SIP request
- returns XMIT_ERROR if transmit failed with a critical error (don't retry)
-*/
-static int transmit_request(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
-{
- struct sip_request resp;
-
- if (sipmethod == SIP_ACK)
- p->invitestate = INV_CONFIRMED;
-
- reqprep(&resp, p, sipmethod, seqno, newbranch);
- add_header_contentLength(&resp, 0);
- return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
-}
-
-/*! \brief Transmit SIP request, auth added */
-static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
-{
- struct sip_request resp;
-
- reqprep(&resp, p, sipmethod, seqno, newbranch);
- if (!ast_strlen_zero(p->realm)) {
- char digest[1024];
-
- memset(digest, 0, sizeof(digest));
- if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
- if (p->options && p->options->auth_type == PROXY_AUTH)
- add_header(&resp, "Proxy-Authorization", digest);
- else if (p->options && p->options->auth_type == WWW_AUTH)
- add_header(&resp, "Authorization", digest);
- else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
- add_header(&resp, "Proxy-Authorization", digest);
- } else
- ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
- }
- /* If we are hanging up and know a cause for that, send it in clear text to make
- debugging easier. */
- if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
- char buf[10];
-
- add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
- snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
- add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
- }
-
- add_header_contentLength(&resp, 0);
- return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
-}
-
-/*! \brief Remove registration data from realtime database or AST/DB when registration expires */
-static void destroy_association(struct sip_peer *peer)
-{
- if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
- ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
- else
- ast_db_del("SIP/Registry", peer->name);
- }
-}
-
-/*! \brief Expire registration of SIP peer */
-static int expire_register(const void *data)
-{
- struct sip_peer *peer = (struct sip_peer *)data;
-
- if (!peer) /* Hmmm. We have no peer. Weird. */
- return 0;
-
- memset(&peer->addr, 0, sizeof(peer->addr));
-
- destroy_association(peer); /* remove registration data from storage */
-
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
- register_peer_exten(peer, FALSE); /* Remove regexten */
- peer->expire = -1;
- ast_device_state_changed("SIP/%s", peer->name);
-
- /* Do we need to release this peer from memory?
- Only for realtime peers and autocreated peers
- */
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
- ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
- struct sip_peer *peer_ptr = peer_ptr;
- peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
- if (peer_ptr) {
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- }
-
- ASTOBJ_UNREF(peer, sip_destroy_peer);
-
- return 0;
-}
-
-/*! \brief Poke peer (send qualify to check if peer is alive and well) */
-static int sip_poke_peer_s(const void *data)
-{
- struct sip_peer *peer = (struct sip_peer *) data;
-
- peer->pokeexpire = -1;
-
- sip_poke_peer(peer);
-
- ASTOBJ_UNREF(peer, sip_destroy_peer);
-
- return 0;
-}
-
-/*! \brief Get registration details from Asterisk DB */
-static void reg_source_db(struct sip_peer *peer)
-{
- char data[256];
- struct in_addr in;
- int expiry;
- int port;
- char *scan, *addr, *port_str, *expiry_str, *username, *contact;
-
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
- return;
- if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
- return;
-
- scan = data;
- addr = strsep(&scan, ":");
- port_str = strsep(&scan, ":");
- expiry_str = strsep(&scan, ":");
- username = strsep(&scan, ":");
- contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
-
- if (!inet_aton(addr, &in))
- return;
-
- if (port_str)
- port = atoi(port_str);
- else
- return;
-
- if (expiry_str)
- expiry = atoi(expiry_str);
- else
- return;
-
- if (username)
- ast_copy_string(peer->username, username, sizeof(peer->username));
- if (contact)
- ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
- peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
-
- memset(&peer->addr, 0, sizeof(peer->addr));
- peer->addr.sin_family = AF_INET;
- peer->addr.sin_addr = in;
- peer->addr.sin_port = htons(port);
- if (sipsock < 0) {
- /* SIP isn't up yet, so schedule a poke only, pretty soon */
- if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer));
- if (peer->pokeexpire == -1) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- } else
- sip_poke_peer(peer);
- if (!AST_SCHED_DEL(sched, peer->expire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
- if (peer->expire == -1) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- register_peer_exten(peer, TRUE);
-}
-
-/*! \brief Save contact header for 200 OK on INVITE */
-static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
-{
- char contact[SIPBUFSIZE];
- char *c;
-
- /* Look for brackets */
- ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
- c = get_in_brackets(contact);
-
- /* Save full contact to call pvt for later bye or re-invite */
- ast_string_field_set(pvt, fullcontact, c);
-
- /* Save URI for later ACKs, BYE or RE-invites */
- ast_string_field_set(pvt, okcontacturi, c);
-
- /* We should return false for URI:s we can't handle,
- like sips:, tel:, mailto:,ldap: etc */
- return TRUE;
-}
-
-/*! \brief Change the other partys IP address based on given contact */
-static int set_address_from_contact(struct sip_pvt *pvt)
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port;
- char *c, *host, *pt;
- char contact_buf[256];
- char *contact;
-
- if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
- /* NAT: Don't trust the contact field. Just use what they came to us
- with. */
- pvt->sa = pvt->recv;
- return 0;
- }
-
- /* Work on a copy */
- ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf));
- contact = contact_buf;
-
- /* Make sure it's a SIP URL */
- if (strncasecmp(contact, "sip:", 4)) {
- ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
- } else
- contact += 4;
-
- /* Ditch arguments */
- /* XXX this code is replicated also shortly below */
-
- /* Grab host */
- host = strchr(contact, '@');
- if (!host) { /* No username part */
- host = contact;
- c = NULL;
- } else {
- *host++ = '\0';
- }
- pt = strchr(host, ':');
- if (pt) {
- *pt++ = '\0';
- port = atoi(pt);
- } else
- port = STANDARD_SIP_PORT;
-
- contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
- host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */
-
- /* XXX This could block for a long time XXX */
- /* We should only do this if it's a name, not an IP */
- hp = ast_gethostbyname(host, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
- return -1;
- }
- pvt->sa.sin_family = AF_INET;
- memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
- pvt->sa.sin_port = htons(port);
-
- return 0;
-}
-
-
-/*! \brief Parse contact header and save registration (peer registration) */
-static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
-{
- char contact[SIPBUFSIZE];
- char data[SIPBUFSIZE];
- const char *expires = get_header(req, "Expires");
- int expiry = atoi(expires);
- char *curi, *n, *pt;
- int port;
- const char *useragent;
- struct hostent *hp;
- struct ast_hostent ahp;
- struct sockaddr_in oldsin;
-
- ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
-
- if (ast_strlen_zero(expires)) { /* No expires header */
- expires = strcasestr(contact, ";expires=");
- if (expires) {
- /* XXX bug here, we overwrite the string */
- expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
- if (sscanf(expires + 9, "%d", &expiry) != 1)
- expiry = default_expiry;
- } else {
- /* Nothing has been specified */
- expiry = default_expiry;
- }
- }
-
- /* Look for brackets */
- curi = contact;
- if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */
- strsep(&curi, ";"); /* This is Header options, not URI options */
- curi = get_in_brackets(contact);
-
- /* if they did not specify Contact: or Expires:, they are querying
- what we currently have stored as their contact address, so return
- it
- */
- if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
- /* If we have an active registration, tell them when the registration is going to expire */
- if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
- pvt->expiry = ast_sched_when(sched, peer->expire);
- return PARSE_REGISTER_QUERY;
- } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
- /* This means remove all registrations and return OK */
- memset(&peer->addr, 0, sizeof(peer->addr));
- if (!AST_SCHED_DEL(sched, peer->expire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
-
- destroy_association(peer);
-
- register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
- peer->fullcontact[0] = '\0';
- peer->useragent[0] = '\0';
- peer->sipoptions = 0;
- peer->lastms = 0;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
- return PARSE_REGISTER_UPDATE;
- }
-
- /* Store whatever we got as a contact from the client */
- ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
-
- /* For the 200 OK, we should use the received contact */
- ast_string_field_build(pvt, our_contact, "<%s>", curi);
-
- /* Make sure it's a SIP URL */
- if (strncasecmp(curi, "sip:", 4)) {
- ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
- } else
- curi += 4;
- /* Ditch q */
- curi = strsep(&curi, ";");
- /* Grab host */
- n = strchr(curi, '@');
- if (!n) {
- n = curi;
- curi = NULL;
- } else
- *n++ = '\0';
- pt = strchr(n, ':');
- if (pt) {
- *pt++ = '\0';
- port = atoi(pt);
- } else
- port = STANDARD_SIP_PORT;
- oldsin = peer->addr;
- if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
- /* XXX This could block for a long time XXX */
- hp = ast_gethostbyname(n, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
- return PARSE_REGISTER_FAILED;
- }
- peer->addr.sin_family = AF_INET;
- memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
- peer->addr.sin_port = htons(port);
- } else {
- /* Don't trust the contact field. Just use what they came to us
- with */
- peer->addr = pvt->recv;
- }
-
- /* Save SIP options profile */
- peer->sipoptions = pvt->sipoptions;
-
- if (curi && ast_strlen_zero(peer->username))
- ast_copy_string(peer->username, curi, sizeof(peer->username));
-
- if (!AST_SCHED_DEL(sched, peer->expire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- if (expiry > max_expiry)
- expiry = max_expiry;
- if (expiry < min_expiry)
- expiry = min_expiry;
- if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) {
- peer->expire = -1;
- } else {
- peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
- if (peer->expire == -1) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- }
- pvt->expiry = expiry;
- snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry, peer->username, peer->fullcontact);
- if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
- ast_db_put("SIP/Registry", peer->name, data);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
-
- /* Is this a new IP address for us? */
- if (inaddrcmp(&peer->addr, &oldsin)) {
- sip_poke_peer(peer);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry);
- register_peer_exten(peer, 1);
- }
-
- /* Save User agent */
- useragent = get_header(req, "User-Agent");
- if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */
- ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
- }
- return PARSE_REGISTER_UPDATE;
-}
-
-/*! \brief Remove route from route list */
-static void free_old_route(struct sip_route *route)
-{
- struct sip_route *next;
-
- while (route) {
- next = route->next;
- free(route);
- route = next;
- }
-}
-
-/*! \brief List all routes - mostly for debugging */
-static void list_route(struct sip_route *route)
-{
- if (!route)
- ast_verbose("list_route: no route\n");
- else {
- for (;route; route = route->next)
- ast_verbose("list_route: hop: <%s>\n", route->hop);
- }
-}
-
-/*! \brief Build route list from Record-Route header */
-static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards)
-{
- struct sip_route *thishop, *head, *tail;
- int start = 0;
- int len;
- const char *rr, *contact, *c;
-
- /* Once a persistant route is set, don't fool with it */
- if (p->route && p->route_persistant) {
- if (option_debug)
- ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
- return;
- }
-
- if (p->route) {
- free_old_route(p->route);
- p->route = NULL;
- }
-
- /* We only want to create the route set the first time this is called */
- p->route_persistant = 1;
-
- /* Build a tailq, then assign it to p->route when done.
- * If backwards, we add entries from the head so they end up
- * in reverse order. However, we do need to maintain a correct
- * tail pointer because the contact is always at the end.
- */
- head = NULL;
- tail = head;
- /* 1st we pass through all the hops in any Record-Route headers */
- for (;;) {
- /* Each Record-Route header */
- rr = __get_header(req, "Record-Route", &start);
- if (*rr == '\0')
- break;
- for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
- ++rr;
- len = strcspn(rr, ">") + 1;
- /* Make a struct route */
- if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
- /* ast_calloc is not needed because all fields are initialized in this block */
- ast_copy_string(thishop->hop, rr, len);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
- /* Link in */
- if (backwards) {
- /* Link in at head so they end up in reverse order */
- thishop->next = head;
- head = thishop;
- /* If this was the first then it'll be the tail */
- if (!tail)
- tail = thishop;
- } else {
- thishop->next = NULL;
- /* Link in at the end */
- if (tail)
- tail->next = thishop;
- else
- head = thishop;
- tail = thishop;
- }
- }
- }
- }
-
- /* Only append the contact if we are dealing with a strict router */
- if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
- /* 2nd append the Contact: if there is one */
- /* Can be multiple Contact headers, comma separated values - we just take the first */
- contact = get_header(req, "Contact");
- if (!ast_strlen_zero(contact)) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
- /* Look for <: delimited address */
- c = strchr(contact, '<');
- if (c) {
- /* Take to > */
- ++c;
- len = strcspn(c, ">") + 1;
- } else {
- /* No <> - just take the lot */
- c = contact;
- len = strlen(contact) + 1;
- }
- if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
- /* ast_calloc is not needed because all fields are initialized in this block */
- ast_copy_string(thishop->hop, c, len);
- thishop->next = NULL;
- /* Goes at the end */
- if (tail)
- tail->next = thishop;
- else
- head = thishop;
- }
- }
- }
-
- /* Store as new route */
- p->route = head;
-
- /* For debugging dump what we ended up with */
- if (sip_debug_test_pvt(p))
- list_route(p->route);
-}
-
-AST_THREADSTORAGE(check_auth_buf, check_auth_buf_init);
-#define CHECK_AUTH_BUF_INITLEN 256
-
-/*! \brief Check user authorization from peer definition
- Some actions, like REGISTER and INVITEs from peers require
- authentication (if peer have secret set)
- \return 0 on success, non-zero on error
-*/
-static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
- const char *secret, const char *md5secret, int sipmethod,
- char *uri, enum xmittype reliable, int ignore)
-{
- const char *response = "407 Proxy Authentication Required";
- const char *reqheader = "Proxy-Authorization";
- const char *respheader = "Proxy-Authenticate";
- const char *authtoken;
- char a1_hash[256];
- char resp_hash[256]="";
- char *c;
- int wrongnonce = FALSE;
- int good_response;
- const char *usednonce = p->randdata;
- struct ast_dynamic_str *buf;
- int res;
-
- /* table of recognised keywords, and their value in the digest */
- enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
- struct x {
- const char *key;
- const char *s;
- } *i, keys[] = {
- [K_RESP] = { "response=", "" },
- [K_URI] = { "uri=", "" },
- [K_USER] = { "username=", "" },
- [K_NONCE] = { "nonce=", "" },
- [K_LAST] = { NULL, NULL}
- };
-
- /* Always OK if no secret */
- if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
- return AUTH_SUCCESSFUL;
- if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
- /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
- of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in
- different circumstances! What a surprise. */
- response = "401 Unauthorized";
- reqheader = "Authorization";
- respheader = "WWW-Authenticate";
- }
- authtoken = get_header(req, reqheader);
- if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
- /* This is a retransmitted invite/register/etc, don't reconstruct authentication
- information */
- if (!reliable) {
- /* Resend message if this was NOT a reliable delivery. Otherwise the
- retransmission should get it */
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
- /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- return AUTH_CHALLENGE_SENT;
- } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
- /* We have no auth, so issue challenge and request authentication */
- ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
- /* Schedule auto destroy in 32 seconds */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return AUTH_CHALLENGE_SENT;
- }
-
- /* --- We have auth, so check it */
-
- /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
- an example in the spec of just what it is you're doing a hash on. */
-
- if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
- return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
-
- /* Make a copy of the response and parse it */
- res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken);
-
- if (res == AST_DYNSTR_BUILD_FAILED)
- return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
-
- c = buf->str;
-
- while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
- for (i = keys; i->key != NULL; i++) {
- const char *separator = ","; /* default */
-
- if (strncasecmp(c, i->key, strlen(i->key)) != 0)
- continue;
- /* Found. Skip keyword, take text in quotes or up to the separator. */
- c += strlen(i->key);
- if (*c == '"') { /* in quotes. Skip first and look for last */
- c++;
- separator = "\"";
- }
- i->s = c;
- strsep(&c, separator);
- break;
- }
- if (i->key == NULL) /* not found, jump after space or comma */
- strsep(&c, " ,");
- }
-
- /* Verify that digest username matches the username we auth as */
- if (strcmp(username, keys[K_USER].s)) {
- ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
- username, keys[K_USER].s);
- /* Oops, we're trying something here */
- return AUTH_USERNAME_MISMATCH;
- }
-
- /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */
- if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
- wrongnonce = TRUE;
- usednonce = keys[K_NONCE].s;
- }
-
- if (!ast_strlen_zero(md5secret))
- ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
- else {
- char a1[256];
- snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
- ast_md5_hash(a1_hash, a1);
- }
-
- /* compute the expected response to compare with what we received */
- {
- char a2[256];
- char a2_hash[256];
- char resp[256];
-
- snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
- S_OR(keys[K_URI].s, uri));
- ast_md5_hash(a2_hash, a2);
- snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
- ast_md5_hash(resp_hash, resp);
- }
-
- good_response = keys[K_RESP].s &&
- !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
- if (wrongnonce) {
- if (good_response) {
- if (sipdebug)
- ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
- /* We got working auth token, based on stale nonce . */
- ast_string_field_build(p, randdata, "%08lx", ast_random());
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
- } else {
- /* Everything was wrong, so give the device one more try with a new challenge */
- if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
- if (sipdebug)
- ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
- ast_string_field_build(p, randdata, "%08lx", ast_random());
- } else {
- if (sipdebug)
- ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
- }
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
- }
-
- /* Schedule auto destroy in 32 seconds */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return AUTH_CHALLENGE_SENT;
- }
- if (good_response) {
- append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
- return AUTH_SUCCESSFUL;
- }
-
- /* Ok, we have a bad username/secret pair */
- /* Tell the UAS not to re-send this authentication data, because
- it will continue to fail
- */
-
- return AUTH_SECRET_FAILED;
-}
-
-/*! \brief Change onhold state of a peer using a pvt structure */
-static void sip_peer_hold(struct sip_pvt *p, int hold)
-{
- struct sip_peer *peer = find_peer(p->peername, NULL, 1);
-
- if (!peer)
- return;
-
- /* If they put someone on hold, increment the value... otherwise decrement it */
- if (hold)
- peer->onHold++;
- else
- peer->onHold--;
-
- /* Request device state update */
- ast_device_state_changed("SIP/%s", peer->name);
-
- return;
-}
-
-/*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem
-\note If you add an "hint" priority to the extension in the dial plan,
- you will get notifications on device state changes */
-static int cb_extensionstate(char *context, char* exten, int state, void *data)
-{
- struct sip_pvt *p = data;
-
- ast_mutex_lock(&p->lock);
-
- switch(state) {
- case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
- case AST_EXTENSION_REMOVED: /* Extension is gone */
- if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */
- ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
- p->stateid = -1;
- p->subscribed = NONE;
- append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
- break;
- default: /* Tell user */
- p->laststate = state;
- break;
- }
- if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */
- if (!p->pendinginvite) {
- transmit_state_notify(p, state, 1, FALSE);
- } else {
- /* We already have a NOTIFY sent that is not answered. Queue the state up.
- if many state changes happen meanwhile, we will only send a notification of the last one */
- ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
- }
- }
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
- ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
-
-
- ast_mutex_unlock(&p->lock);
-
- return 0;
-}
-
-/*! \brief Send a fake 401 Unauthorized response when the administrator
- wants to hide the names of local users/peers from fishers
- */
-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, int reliable)
-{
- ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
- transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
-}
-
-/*! \brief Verify registration of user
- - Registration is done in several steps, first a REGISTER without auth
- to get a challenge (nonce) then a second one with auth
- - Registration requests are only matched with peers that are marked as "dynamic"
- */
-static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
- struct sip_request *req, char *uri)
-{
- enum check_auth_result res = AUTH_NOT_FOUND;
- struct sip_peer *peer;
- char tmp[256];
- char *name, *c;
- char *t;
- char *domain;
-
- /* Terminate URI */
- t = uri;
- while(*t && (*t > 32) && (*t != ';'))
- t++;
- *t = '\0';
-
- ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
- if (pedanticsipchecking)
- ast_uri_decode(tmp);
-
- c = get_in_brackets(tmp);
- c = strsep(&c, ";"); /* Ditch ;user=phone */
-
- if (!strncasecmp(c, "sip:", 4)) {
- name = c + 4;
- } else {
- name = c;
- ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
- }
-
- /* Strip off the domain name */
- if ((c = strchr(name, '@'))) {
- *c++ = '\0';
- domain = c;
- if ((c = strchr(domain, ':'))) /* Remove :port */
- *c = '\0';
- if (!AST_LIST_EMPTY(&domain_list)) {
- if (!check_sip_domain(domain, NULL, 0)) {
- transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
- return AUTH_UNKNOWN_DOMAIN;
- }
- }
- }
-
- ast_string_field_set(p, exten, name);
- build_contact(p);
- peer = find_peer(name, NULL, 1);
- if (!(peer && ast_apply_ha(peer->ha, sin))) {
- /* Peer fails ACL check */
- if (peer) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- res = AUTH_ACL_FAILED;
- } else
- res = AUTH_NOT_FOUND;
- }
- if (peer) {
- /* Set Frame packetization */
- if (p->rtp) {
- ast_rtp_codec_setpref(p->rtp, &peer->prefs);
- p->autoframing = peer->autoframing;
- }
- if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
- ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
- res = AUTH_PEER_NOT_DYNAMIC;
- } else {
- ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
- transmit_response(p, "100 Trying", req);
- if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
- if (sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
-
- /* We have a succesful registration attemp with proper authentication,
- now, update the peer */
- switch (parse_register_contact(p, peer, req)) {
- case PARSE_REGISTER_FAILED:
- ast_log(LOG_WARNING, "Failed to parse contact info\n");
- transmit_response_with_date(p, "400 Bad Request", req);
- peer->lastmsgssent = -1;
- res = 0;
- break;
- case PARSE_REGISTER_QUERY:
- transmit_response_with_date(p, "200 OK", req);
- peer->lastmsgssent = -1;
- res = 0;
- break;
- case PARSE_REGISTER_UPDATE:
- update_peer(peer, p->expiry);
- /* Say OK and ask subsystem to retransmit msg counter */
- transmit_response_with_date(p, "200 OK", req);
- if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
- peer->lastmsgssent = -1;
- res = 0;
- break;
- }
- }
- }
- }
- if (!peer && autocreatepeer) {
- /* Create peer if we have autocreate mode enabled */
- peer = temp_peer(name);
- if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
- if (sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- switch (parse_register_contact(p, peer, req)) {
- case PARSE_REGISTER_FAILED:
- ast_log(LOG_WARNING, "Failed to parse contact info\n");
- transmit_response_with_date(p, "400 Bad Request", req);
- peer->lastmsgssent = -1;
- res = 0;
- break;
- case PARSE_REGISTER_QUERY:
- transmit_response_with_date(p, "200 OK", req);
- peer->lastmsgssent = -1;
- res = 0;
- break;
- case PARSE_REGISTER_UPDATE:
- /* Say OK and ask subsystem to retransmit msg counter */
- transmit_response_with_date(p, "200 OK", req);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
- peer->lastmsgssent = -1;
- res = 0;
- break;
- }
- }
- }
- if (!res) {
- ast_device_state_changed("SIP/%s", peer->name);
- }
- if (res < 0) {
- switch (res) {
- case AUTH_SECRET_FAILED:
- /* Wrong password in authentication. Go away, don't try again until you fixed it */
- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
- break;
- case AUTH_USERNAME_MISMATCH:
- /* Username and digest username does not match.
- Asterisk uses the From: username for authentication. We need the
- users to use the same authentication user name until we support
- proper authentication by digest auth name */
- transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
- break;
- case AUTH_NOT_FOUND:
- case AUTH_PEER_NOT_DYNAMIC:
- case AUTH_ACL_FAILED:
- if (global_alwaysauthreject) {
- transmit_fake_auth_response(p, &p->initreq, 1);
- } else {
- /* URI not found */
- if (res == AUTH_PEER_NOT_DYNAMIC)
- transmit_response(p, "403 Forbidden", &p->initreq);
- else
- transmit_response(p, "404 Not found", &p->initreq);
- }
- break;
- default:
- break;
- }
- }
- if (peer)
- ASTOBJ_UNREF(peer, sip_destroy_peer);
-
- return res;
-}
-
-/*! \brief Get referring dnis */
-static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq)
-{
- char tmp[256], *c, *a;
- struct sip_request *req;
-
- req = oreq;
- if (!req)
- req = &p->initreq;
- ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
- if (ast_strlen_zero(tmp))
- return 0;
- c = get_in_brackets(tmp);
- if (strncasecmp(c, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c);
- return -1;
- }
- c += 4;
- a = c;
- strsep(&a, "@;"); /* trim anything after @ or ; */
- if (sip_debug_test_pvt(p))
- ast_verbose("RDNIS is %s\n", c);
- ast_string_field_set(p, rdnis, c);
-
- return 0;
-}
-
-/*! \brief Find out who the call is for
- We use the INVITE uri to find out
-*/
-static int get_destination(struct sip_pvt *p, struct sip_request *oreq)
-{
- char tmp[256] = "", *uri, *a;
- char tmpf[256] = "", *from;
- struct sip_request *req;
- char *colon;
-
- req = oreq;
- if (!req)
- req = &p->initreq;
-
- /* Find the request URI */
- if (req->rlPart2)
- ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
-
- if (pedanticsipchecking)
- ast_uri_decode(tmp);
-
- uri = get_in_brackets(tmp);
-
- if (strncasecmp(uri, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri);
- return -1;
- }
- uri += 4;
-
- /* Now find the From: caller ID and name */
- ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
- if (!ast_strlen_zero(tmpf)) {
- if (pedanticsipchecking)
- ast_uri_decode(tmpf);
- from = get_in_brackets(tmpf);
- } else {
- from = NULL;
- }
-
- if (!ast_strlen_zero(from)) {
- if (strncasecmp(from, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
- return -1;
- }
- from += 4;
- if ((a = strchr(from, '@')))
- *a++ = '\0';
- else
- a = from; /* just a domain */
- from = strsep(&from, ";"); /* Remove userinfo options */
- a = strsep(&a, ";"); /* Remove URI options */
- ast_string_field_set(p, fromdomain, a);
- }
-
- /* Skip any options and find the domain */
-
- /* Get the target domain */
- if ((a = strchr(uri, '@'))) {
- *a++ = '\0';
- } else { /* No username part */
- a = uri;
- uri = "s"; /* Set extension to "s" */
- }
- colon = strchr(a, ':'); /* Remove :port */
- if (colon)
- *colon = '\0';
-
- uri = strsep(&uri, ";"); /* Remove userinfo options */
- a = strsep(&a, ";"); /* Remove URI options */
-
- ast_string_field_set(p, domain, a);
-
- if (!AST_LIST_EMPTY(&domain_list)) {
- char domain_context[AST_MAX_EXTENSION];
-
- domain_context[0] = '\0';
- if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
- if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
- return -2;
- }
- }
- /* If we have a context defined, overwrite the original context */
- if (!ast_strlen_zero(domain_context))
- ast_string_field_set(p, context, domain_context);
- }
-
- /* If the request coming in is a subscription and subscribecontext has been specified use it */
- if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
- ast_string_field_set(p, context, p->subscribecontext);
-
- if (sip_debug_test_pvt(p))
- ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
-
- /* If this is a subscription we actually just need to see if a hint exists for the extension */
- if (req->method == SIP_SUBSCRIBE) {
- char hint[AST_MAX_EXTENSION];
- return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
- } else {
- /* Check the dialplan for the username part of the request URI,
- the domain will be stored in the SIPDOMAIN variable
- Since extensions.conf can have unescaped characters, try matching a decoded
- uri in addition to the non-decoded uri
- Return 0 if we have a matching extension */
- char *decoded_uri = ast_strdupa(uri);
- ast_uri_decode(decoded_uri);
- if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) ||
- !strcmp(uri, ast_pickup_ext())) {
- if (!oreq)
- ast_string_field_set(p, exten, uri);
- return 0;
- }
- }
-
- /* Return 1 for pickup extension or overlap dialling support (if we support it) */
- if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) &&
- ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) ||
- !strncmp(uri, ast_pickup_ext(), strlen(uri))) {
- return 1;
- }
-
- return -1;
-}
-
-/*! \brief Lock interface lock and find matching pvt lock
- - Their tag is fromtag, our tag is to-tag
- - This means that in some transactions, totag needs to be their tag :-)
- depending upon the direction
-*/
-static struct sip_pvt *get_sip_pvt_byid_locked(const char *callid, const char *totag, const char *fromtag)
-{
- struct sip_pvt *sip_pvt_ptr;
-
- ast_mutex_lock(&iflock);
-
- if (option_debug > 3 && totag)
- ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
-
- /* Search interfaces and find the match */
- for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
- if (!strcmp(sip_pvt_ptr->callid, callid)) {
- int match = 1;
- char *ourtag = sip_pvt_ptr->tag;
-
- /* Go ahead and lock it (and its owner) before returning */
- ast_mutex_lock(&sip_pvt_ptr->lock);
-
- /* Check if tags match. If not, this is not the call we want
- (With a forking SIP proxy, several call legs share the
- call id, but have different tags)
- */
- if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag))))
- match = 0;
-
- if (!match) {
- ast_mutex_unlock(&sip_pvt_ptr->lock);
- continue;
- }
-
- if (option_debug > 3 && totag)
- ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
- ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING",
- sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
-
- /* deadlock avoidance... */
- while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
- ast_mutex_unlock(&sip_pvt_ptr->lock);
- usleep(1);
- ast_mutex_lock(&sip_pvt_ptr->lock);
- }
- break;
- }
- }
- ast_mutex_unlock(&iflock);
- if (option_debug > 3 && !sip_pvt_ptr)
- ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
- return sip_pvt_ptr;
-}
-
-/*! \brief Call transfer support (the REFER method)
- * Extracts Refer headers into pvt dialog structure */
-static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoing_req)
-{
-
- const char *p_referred_by = NULL;
- char *h_refer_to = NULL;
- char *h_referred_by = NULL;
- char *refer_to;
- const char *p_refer_to;
- char *referred_by_uri = NULL;
- char *ptr;
- struct sip_request *req = NULL;
- const char *transfer_context = NULL;
- struct sip_refer *referdata;
-
-
- req = outgoing_req;
- referdata = transferer->refer;
-
- if (!req)
- req = &transferer->initreq;
-
- p_refer_to = get_header(req, "Refer-To");
- if (ast_strlen_zero(p_refer_to)) {
- ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
- return -2; /* Syntax error */
- }
- h_refer_to = ast_strdupa(p_refer_to);
- refer_to = get_in_brackets(h_refer_to);
- if (pedanticsipchecking)
- ast_uri_decode(refer_to);
-
- if (strncasecmp(refer_to, "sip:", 4)) {
- ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to);
- return -3;
- }
- refer_to += 4; /* Skip sip: */
-
- /* Get referred by header if it exists */
- p_referred_by = get_header(req, "Referred-By");
- if (!ast_strlen_zero(p_referred_by)) {
- char *lessthan;
- h_referred_by = ast_strdupa(p_referred_by);
- if (pedanticsipchecking)
- ast_uri_decode(h_referred_by);
-
- /* Store referrer's caller ID name */
- ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
- if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
- *(lessthan - 1) = '\0'; /* Space */
- }
-
- referred_by_uri = get_in_brackets(h_referred_by);
- if(strncasecmp(referred_by_uri, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
- referred_by_uri = (char *) NULL;
- } else {
- referred_by_uri += 4; /* Skip sip: */
- }
- }
-
- /* Check for arguments in the refer_to header */
- if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
- *ptr++ = '\0';
- if (!strncasecmp(ptr, "REPLACES=", 9)) {
- char *to = NULL, *from = NULL;
-
- /* This is an attended transfer */
- referdata->attendedtransfer = 1;
- ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
- ast_uri_decode(referdata->replaces_callid);
- if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ {
- *ptr++ = '\0';
- }
-
- if (ptr) {
- /* Find the different tags before we destroy the string */
- to = strcasestr(ptr, "to-tag=");
- from = strcasestr(ptr, "from-tag=");
- }
-
- /* Grab the to header */
- if (to) {
- ptr = to + 7;
- if ((to = strchr(ptr, '&')))
- *to = '\0';
- if ((to = strchr(ptr, ';')))
- *to = '\0';
- ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
- }
-
- if (from) {
- ptr = from + 9;
- if ((to = strchr(ptr, '&')))
- *to = '\0';
- if ((to = strchr(ptr, ';')))
- *to = '\0';
- ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
- }
-
- if (option_debug > 1) {
- if (!pedanticsipchecking)
- ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
- else
- ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
- }
- }
- }
-
- if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */
- char *urioption = NULL, *domain;
- *ptr++ = '\0';
-
- if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
- *urioption++ = '\0';
-
- domain = ptr;
- if ((ptr = strchr(domain, ':'))) /* Remove :port */
- *ptr = '\0';
-
- /* Save the domain for the dial plan */
- ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
- if (urioption)
- ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
- }
-
- if ((ptr = strchr(refer_to, ';'))) /* Remove options */
- *ptr = '\0';
- ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
-
- if (referred_by_uri) {
- if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */
- *ptr = '\0';
- ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
- } else {
- referdata->referred_by[0] = '\0';
- }
-
- /* Determine transfer context */
- if (transferer->owner) /* Mimic behaviour in res_features.c */
- transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
-
- /* By default, use the context in the channel sending the REFER */
- if (ast_strlen_zero(transfer_context)) {
- transfer_context = S_OR(transferer->owner->macrocontext,
- S_OR(transferer->context, default_context));
- }
-
- ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
-
- /* Either an existing extension or the parking extension */
- if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
- if (sip_debug_test_pvt(transferer)) {
- ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
- }
- /* We are ready to transfer to the extension */
- return 0;
- }
- if (sip_debug_test_pvt(transferer))
- ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
-
- /* Failure, we can't find this extension */
- return -1;
-}
-
-
-/*! \brief Call transfer support (old way, deprecated by the IETF)--*/
-static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
-{
- char tmp[256] = "", *c, *a;
- struct sip_request *req = oreq ? oreq : &p->initreq;
- struct sip_refer *referdata = NULL;
- const char *transfer_context = NULL;
-
- if (!p->refer && !sip_refer_allocate(p))
- return -1;
-
- referdata = p->refer;
-
- ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
- c = get_in_brackets(tmp);
-
- if (pedanticsipchecking)
- ast_uri_decode(c);
-
- if (strncasecmp(c, "sip:", 4)) {
- ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
- return -1;
- }
- c += 4;
- if ((a = strchr(c, ';'))) /* Remove arguments */
- *a = '\0';
-
- if ((a = strchr(c, '@'))) { /* Separate Domain */
- *a++ = '\0';
- ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
- }
-
- if (sip_debug_test_pvt(p))
- ast_verbose("Looking for %s in %s\n", c, p->context);
-
- if (p->owner) /* Mimic behaviour in res_features.c */
- transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
-
- /* By default, use the context in the channel sending the REFER */
- if (ast_strlen_zero(transfer_context)) {
- transfer_context = S_OR(p->owner->macrocontext,
- S_OR(p->context, default_context));
- }
- if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
- /* This is a blind transfer */
- if (option_debug)
- ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
- ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
- ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
- ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
- referdata->refer_call = NULL;
- /* Set new context */
- ast_string_field_set(p, context, transfer_context);
- return 0;
- } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
- return 1;
- }
-
- return -1;
-}
-/*! \brief check Via: header for hostname, port and rport request/answer */
-static void check_via(struct sip_pvt *p, const struct sip_request *req)
-{
- char via[512];
- char *c, *pt;
- struct hostent *hp;
- struct ast_hostent ahp;
-
- ast_copy_string(via, get_header(req, "Via"), sizeof(via));
-
- /* Work on the leftmost value of the topmost Via header */
- c = strchr(via, ',');
- if (c)
- *c = '\0';
-
- /* Check for rport */
- c = strstr(via, ";rport");
- if (c && (c[6] != '=')) /* rport query, not answer */
- ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
-
- c = strchr(via, ';');
- if (c)
- *c = '\0';
-
- c = strchr(via, ' ');
- if (c) {
- *c = '\0';
- c = ast_skip_blanks(c+1);
- if (strcasecmp(via, "SIP/2.0/UDP")) {
- ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
- return;
- }
- pt = strchr(c, ':');
- if (pt)
- *pt++ = '\0'; /* remember port pointer */
- hp = ast_gethostbyname(c, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
- return;
- }
- memset(&p->sa, 0, sizeof(p->sa));
- p->sa.sin_family = AF_INET;
- memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
- p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
-
- if (sip_debug_test_pvt(p)) {
- const struct sockaddr_in *dst = sip_real_dst(p);
- ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
- }
- }
-}
-
-/*! \brief Get caller id name from SIP headers */
-static char *get_calleridname(const char *input, char *output, size_t outputsize)
-{
- const char *end = strchr(input,'<'); /* first_bracket */
- const char *tmp = strchr(input,'"'); /* first quote */
- int bytes = 0;
- int maxbytes = outputsize - 1;
-
- if (!end || end == input) /* we require a part in brackets */
- return NULL;
-
- end--; /* move just before "<" */
-
- if (tmp && tmp <= end) {
- /* The quote (tmp) precedes the bracket (end+1).
- * Find the matching quote and return the content.
- */
- end = strchr(tmp+1, '"');
- if (!end)
- return NULL;
- bytes = (int) (end - tmp);
- /* protect the output buffer */
- if (bytes > maxbytes)
- bytes = maxbytes;
- ast_copy_string(output, tmp + 1, bytes);
- } else {
- /* No quoted string, or it is inside brackets. */
- /* clear the empty characters in the begining*/
- input = ast_skip_blanks(input);
- /* clear the empty characters in the end */
- while(*end && *end < 33 && end > input)
- end--;
- if (end >= input) {
- bytes = (int) (end - input) + 2;
- /* protect the output buffer */
- if (bytes > maxbytes)
- bytes = maxbytes;
- ast_copy_string(output, input, bytes);
- } else
- return NULL;
- }
- return output;
-}
-
-/*! \brief Get caller id number from Remote-Party-ID header field
- * Returns true if number should be restricted (privacy setting found)
- * output is set to NULL if no number found
- */
-static int get_rpid_num(const char *input, char *output, int maxlen)
-{
- char *start;
- char *end;
-
- start = strchr(input,':');
- if (!start) {
- output[0] = '\0';
- return 0;
- }
- start++;
-
- /* we found "number" */
- ast_copy_string(output,start,maxlen);
- output[maxlen-1] = '\0';
-
- end = strchr(output,'@');
- if (end)
- *end = '\0';
- else
- output[0] = '\0';
- if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
- return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
-
- return 0;
-}
-
-
-/*! \brief Check if matching user or peer is defined
- Match user on From: user name and peer on IP/port
- This is used on first invite (not re-invites) and subscribe requests
- \return 0 on success, non-zero on failure
-*/
-static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_request *req,
- int sipmethod, char *uri, enum xmittype reliable,
- struct sockaddr_in *sin, struct sip_peer **authpeer)
-{
- struct sip_user *user = NULL;
- struct sip_peer *peer;
- char from[256], *c;
- char *of;
- char rpid_num[50];
- const char *rpid;
- enum check_auth_result res = AUTH_SUCCESSFUL;
- char *t;
- char calleridname[50];
- int debug=sip_debug_test_addr(sin);
- struct ast_variable *tmpvar = NULL, *v = NULL;
- char *uri2 = ast_strdupa(uri);
-
- /* Terminate URI */
- t = uri2;
- while (*t && *t > 32 && *t != ';')
- t++;
- *t = '\0';
- ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */
- if (pedanticsipchecking)
- ast_uri_decode(from);
- /* XXX here tries to map the username for invite things */
- memset(calleridname, 0, sizeof(calleridname));
- get_calleridname(from, calleridname, sizeof(calleridname));
- if (calleridname[0])
- ast_string_field_set(p, cid_name, calleridname);
-
- rpid = get_header(req, "Remote-Party-ID");
- memset(rpid_num, 0, sizeof(rpid_num));
- if (!ast_strlen_zero(rpid))
- p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
-
- of = get_in_brackets(from);
- if (ast_strlen_zero(p->exten)) {
- t = uri2;
- if (!strncasecmp(t, "sip:", 4))
- t+= 4;
- ast_string_field_set(p, exten, t);
- t = strchr(p->exten, '@');
- if (t)
- *t = '\0';
- if (ast_strlen_zero(p->our_contact))
- build_contact(p);
- }
- /* save the URI part of the From header */
- ast_string_field_set(p, from, of);
- if (strncasecmp(of, "sip:", 4)) {
- ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
- } else
- of += 4;
- /* Get just the username part */
- if ((c = strchr(of, '@'))) {
- char *tmp;
- *c = '\0';
- if ((c = strchr(of, ':')))
- *c = '\0';
- tmp = ast_strdupa(of);
- /* We need to be able to handle auth-headers looking like
- <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
- */
- tmp = strsep(&tmp, ";");
- if (ast_is_shrinkable_phonenumber(tmp))
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- }
-
- if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
- user = find_user(of, 1);
-
- /* Find user based on user name in the from header */
- if (user && ast_apply_ha(user->ha, sin)) {
- ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
- /* copy channel vars */
- for (v = user->chanvars ; v ; v = v->next) {
- if ((tmpvar = ast_variable_new(v->name, v->value))) {
- tmpvar->next = p->chanvars;
- p->chanvars = tmpvar;
- }
- }
- p->prefs = user->prefs;
- /* Set Frame packetization */
- if (p->rtp) {
- ast_rtp_codec_setpref(p->rtp, &p->prefs);
- p->autoframing = user->autoframing;
- }
- /* replace callerid if rpid found, and not restricted */
- if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
- char *tmp;
- if (*calleridname)
- ast_string_field_set(p, cid_name, calleridname);
- tmp = ast_strdupa(rpid_num);
- if (ast_is_shrinkable_phonenumber(tmp))
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- }
-
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
-
- if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
- if (sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
- /* Copy SIP extensions profile from INVITE */
- if (p->sipoptions)
- user->sipoptions = p->sipoptions;
-
- /* If we have a call limit, set flag */
- if (user->call_limit)
- ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
- if (!ast_strlen_zero(user->context))
- ast_string_field_set(p, context, user->context);
- if (!ast_strlen_zero(user->cid_num)) {
- char *tmp = ast_strdupa(user->cid_num);
- if (ast_is_shrinkable_phonenumber(tmp))
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- }
- if (!ast_strlen_zero(user->cid_name))
- ast_string_field_set(p, cid_name, user->cid_name);
- ast_string_field_set(p, username, user->name);
- ast_string_field_set(p, peername, user->name);
- ast_string_field_set(p, peersecret, user->secret);
- ast_string_field_set(p, peermd5secret, user->md5secret);
- ast_string_field_set(p, subscribecontext, user->subscribecontext);
- ast_string_field_set(p, accountcode, user->accountcode);
- ast_string_field_set(p, language, user->language);
- ast_string_field_set(p, mohsuggest, user->mohsuggest);
- ast_string_field_set(p, mohinterpret, user->mohinterpret);
- p->allowtransfer = user->allowtransfer;
- p->amaflags = user->amaflags;
- p->callgroup = user->callgroup;
- p->pickupgroup = user->pickupgroup;
- if (user->callingpres) /* User callingpres setting will override RPID header */
- p->callingpres = user->callingpres;
-
- /* Set default codec settings for this call */
- p->capability = user->capability; /* User codec choice */
- p->jointcapability = user->capability; /* Our codecs */
- if (p->peercapability) /* AND with peer's codecs */
- p->jointcapability &= p->peercapability;
- if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
- (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
- p->noncodeccapability |= AST_RTP_DTMF;
- else
- p->noncodeccapability &= ~AST_RTP_DTMF;
- p->jointnoncodeccapability = p->noncodeccapability;
- if (p->t38.peercapability)
- p->t38.jointcapability &= p->t38.peercapability;
- p->maxcallbitrate = user->maxcallbitrate;
- /* If we do not support video, remove video from call structure */
- if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
- ast_rtp_destroy(p->vrtp);
- p->vrtp = NULL;
- }
- }
- if (user && debug)
- ast_verbose("Found user '%s'\n", user->name);
- } else {
- if (user) {
- if (!authpeer && debug)
- ast_verbose("Found user '%s', but fails host access\n", user->name);
- ASTOBJ_UNREF(user,sip_destroy_user);
- }
- user = NULL;
- }
-
- if (!user) {
- /* If we didn't find a user match, check for peers */
- if (sipmethod == SIP_SUBSCRIBE)
- /* For subscribes, match on peer name only */
- peer = find_peer(of, NULL, 1);
- else
- /* Look for peer based on the IP address we received data from */
- /* If peer is registered from this IP address or have this as a default
- IP address, this call is from the peer
- */
- peer = find_peer(NULL, &p->recv, 1);
-
- if (peer) {
- /* Set Frame packetization */
- if (p->rtp) {
- ast_rtp_codec_setpref(p->rtp, &peer->prefs);
- p->autoframing = peer->autoframing;
- }
- if (debug)
- ast_verbose("Found peer '%s'\n", peer->name);
-
- /* Take the peer */
- ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
-
- /* Copy SIP extensions profile to peer */
- if (p->sipoptions)
- peer->sipoptions = p->sipoptions;
-
- /* replace callerid if rpid found, and not restricted */
- if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
- char *tmp = ast_strdupa(rpid_num);
- if (*calleridname)
- ast_string_field_set(p, cid_name, calleridname);
- if (ast_is_shrinkable_phonenumber(tmp))
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- }
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
-
- ast_string_field_set(p, peersecret, peer->secret);
- ast_string_field_set(p, peermd5secret, peer->md5secret);
- ast_string_field_set(p, subscribecontext, peer->subscribecontext);
- ast_string_field_set(p, mohinterpret, peer->mohinterpret);
- ast_string_field_set(p, mohsuggest, peer->mohsuggest);
- if (peer->callingpres) /* Peer calling pres setting will override RPID */
- p->callingpres = peer->callingpres;
- if (peer->maxms && peer->lastms)
- p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
- if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
- /* Pretend there is no required authentication */
- ast_string_field_free(p, peersecret);
- ast_string_field_free(p, peermd5secret);
- }
- if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
- ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
- /* If we have a call limit, set flag */
- if (peer->call_limit)
- ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
- ast_string_field_set(p, peername, peer->name);
- ast_string_field_set(p, authname, peer->name);
-
- /* copy channel vars */
- for (v = peer->chanvars ; v ; v = v->next) {
- if ((tmpvar = ast_variable_new(v->name, v->value))) {
- tmpvar->next = p->chanvars;
- p->chanvars = tmpvar;
- }
- }
- if (authpeer) {
- (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
- }
-
- if (!ast_strlen_zero(peer->username)) {
- ast_string_field_set(p, username, peer->username);
- /* Use the default username for authentication on outbound calls */
- /* XXX this takes the name from the caller... can we override ? */
- ast_string_field_set(p, authname, peer->username);
- }
- if (!ast_strlen_zero(peer->cid_num)) {
- char *tmp = ast_strdupa(peer->cid_num);
- if (ast_is_shrinkable_phonenumber(tmp))
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- }
- if (!ast_strlen_zero(peer->cid_name))
- ast_string_field_set(p, cid_name, peer->cid_name);
- ast_string_field_set(p, fullcontact, peer->fullcontact);
- if (!ast_strlen_zero(peer->context))
- ast_string_field_set(p, context, peer->context);
- ast_string_field_set(p, peersecret, peer->secret);
- ast_string_field_set(p, peermd5secret, peer->md5secret);
- ast_string_field_set(p, language, peer->language);
- ast_string_field_set(p, accountcode, peer->accountcode);
- p->amaflags = peer->amaflags;
- p->callgroup = peer->callgroup;
- p->pickupgroup = peer->pickupgroup;
- p->capability = peer->capability;
- p->prefs = peer->prefs;
- p->jointcapability = peer->capability;
- if (p->peercapability)
- p->jointcapability &= p->peercapability;
- p->maxcallbitrate = peer->maxcallbitrate;
- if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
- ast_rtp_destroy(p->vrtp);
- p->vrtp = NULL;
- }
- if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
- (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
- p->noncodeccapability |= AST_RTP_DTMF;
- else
- p->noncodeccapability &= ~AST_RTP_DTMF;
- p->jointnoncodeccapability = p->noncodeccapability;
- if (p->t38.peercapability)
- p->t38.jointcapability &= p->t38.peercapability;
- }
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- } else {
- if (debug)
- ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
-
- /* do we allow guests? */
- if (!global_allowguest) {
- if (global_alwaysauthreject)
- res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
- else
- res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
- } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
- char *tmp = ast_strdupa(rpid_num);
- if (*calleridname)
- ast_string_field_set(p, cid_name, calleridname);
- if (ast_is_shrinkable_phonenumber(tmp))
- ast_shrink_phone_number(tmp);
- ast_string_field_set(p, cid_num, tmp);
- }
- }
-
- }
-
- if (user)
- ASTOBJ_UNREF(user, sip_destroy_user);
- return res;
-}
-
-/*! \brief Find user
- If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced
-*/
-static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin)
-{
- return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
-}
-
-/*! \brief Get text out of a SIP MESSAGE packet */
-static int get_msg_text(char *buf, int len, struct sip_request *req)
-{
- int x;
- int y;
-
- buf[0] = '\0';
- y = len - strlen(buf) - 5;
- if (y < 0)
- y = 0;
- for (x=0;x<req->lines;x++) {
- strncat(buf, req->line[x], y); /* safe */
- y -= strlen(req->line[x]) + 1;
- if (y < 0)
- y = 0;
- if (y != 0)
- strcat(buf, "\n"); /* safe */
- }
- return 0;
-}
-
-
-/*! \brief Receive SIP MESSAGE method messages
-\note We only handle messages within current calls currently
- Reference: RFC 3428 */
-static void receive_message(struct sip_pvt *p, struct sip_request *req)
-{
- char buf[1024];
- struct ast_frame f;
- const char *content_type = get_header(req, "Content-Type");
-
- if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */
- transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
- if (!p->owner)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- }
-
- if (get_msg_text(buf, sizeof(buf), req)) {
- ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
- transmit_response(p, "202 Accepted", req);
- if (!p->owner)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- }
-
- if (p->owner) {
- if (sip_debug_test_pvt(p))
- ast_verbose("Message received: '%s'\n", buf);
- memset(&f, 0, sizeof(f));
- f.frametype = AST_FRAME_TEXT;
- f.subclass = 0;
- f.offset = 0;
- f.data = buf;
- f.datalen = strlen(buf);
- ast_queue_frame(p->owner, &f);
- transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
- } else { /* Message outside of a call, we do not support that */
- ast_log(LOG_WARNING,"Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf);
- transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- return;
-}
-
-/*! \brief CLI Command to show calls within limits set by call_limit */
-static int sip_show_inuse(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-25.25s %-15.15s %-15.15s \n"
-#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
- char ilimits[40];
- char iused[40];
- int showall = FALSE;
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
-
- if (argc == 4 && !strcmp(argv[3],"all"))
- showall = TRUE;
-
- ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->call_limit)
- snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
- else
- ast_copy_string(ilimits, "N/A", sizeof(ilimits));
- snprintf(iused, sizeof(iused), "%d", iterator->inUse);
- if (showall || iterator->call_limit)
- ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
-
- ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
-
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->call_limit)
- snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
- else
- ast_copy_string(ilimits, "N/A", sizeof(ilimits));
- snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
- if (showall || iterator->call_limit)
- ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
-
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-/*! \brief Convert transfer mode to text string */
-static char *transfermode2str(enum transfermodes mode)
-{
- if (mode == TRANSFER_OPENFORALL)
- return "open";
- else if (mode == TRANSFER_CLOSED)
- return "closed";
- return "strict";
-}
-
-/*! \brief Convert NAT setting to text string */
-static char *nat2str(int nat)
-{
- switch(nat) {
- case SIP_NAT_NEVER:
- return "No";
- case SIP_NAT_ROUTE:
- return "Route";
- case SIP_NAT_ALWAYS:
- return "Always";
- case SIP_NAT_RFC3581:
- return "RFC3581";
- default:
- return "Unknown";
- }
-}
-
-/*! \brief Report Peer status in character string
- * \return 0 if peer is unreachable, 1 if peer is online, -1 if unmonitored
- */
-static int peer_status(struct sip_peer *peer, char *status, int statuslen)
-{
- int res = 0;
- if (peer->maxms) {
- if (peer->lastms < 0) {
- ast_copy_string(status, "UNREACHABLE", statuslen);
- } else if (peer->lastms > peer->maxms) {
- snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
- res = 1;
- } else if (peer->lastms) {
- snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
- res = 1;
- } else {
- ast_copy_string(status, "UNKNOWN", statuslen);
- }
- } else {
- ast_copy_string(status, "Unmonitored", statuslen);
- /* Checking if port is 0 */
- res = -1;
- }
- return res;
-}
-
-/*! \brief CLI Command 'SIP Show Users' */
-static int sip_show_users(int fd, int argc, char *argv[])
-{
- regex_t regexbuf;
- int havepattern = FALSE;
-
-#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
-
- switch (argc) {
- case 5:
- if (!strcasecmp(argv[3], "like")) {
- if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = TRUE;
- } else
- return RESULT_SHOWUSAGE;
- case 3:
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
- ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
-
- if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
- continue;
- }
-
- ast_cli(fd, FORMAT, iterator->name,
- iterator->secret,
- iterator->accountcode,
- iterator->context,
- iterator->ha ? "Yes" : "No",
- nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
- ASTOBJ_UNLOCK(iterator);
- } while (0)
- );
-
- if (havepattern)
- regfree(&regexbuf);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-}
-
-static char mandescr_show_peers[] =
-"Description: Lists SIP peers in text format with details on current status.\n"
-"Variables: \n"
-" ActionID: <id> Action ID for this transaction. Will be returned.\n";
-
-/*! \brief Show SIP peers in the manager API */
-/* Inspired from chan_iax2 */
-static int manager_sip_show_peers(struct mansession *s, const struct message *m)
-{
- const char *id = astman_get_header(m,"ActionID");
- const char *a[] = {"sip", "show", "peers"};
- char idtext[256] = "";
- int total = 0;
-
- if (!ast_strlen_zero(id))
- snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
-
- astman_send_ack(s, m, "Peer status list will follow");
- /* List the peers in separate manager events */
- _sip_show_peers(-1, &total, s, m, 3, a);
- /* Send final confirmation */
- astman_append(s,
- "Event: PeerlistComplete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
- return 0;
-}
-
-/*! \brief CLI Show Peers command */
-static int sip_show_peers(int fd, int argc, char *argv[])
-{
- return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
-}
-
-/*! \brief _sip_show_peers: Execute sip show peers command */
-static int _sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
-{
- regex_t regexbuf;
- int havepattern = FALSE;
-
-#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
-#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
-
- char name[256];
- int total_peers = 0;
- int peers_mon_online = 0;
- int peers_mon_offline = 0;
- int peers_unmon_offline = 0;
- int peers_unmon_online = 0;
- const char *id;
- char idtext[256] = "";
- int realtimepeers;
-
- realtimepeers = ast_check_realtime("sippeers");
-
- if (s) { /* Manager - get ActionID */
- id = astman_get_header(m,"ActionID");
- if (!ast_strlen_zero(id))
- snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
- }
-
- switch (argc) {
- case 5:
- if (!strcasecmp(argv[3], "like")) {
- if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = TRUE;
- } else
- return RESULT_SHOWUSAGE;
- case 3:
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
- if (!s) /* Normal list */
- ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
-
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- char status[20] = "";
- char srch[2000];
- char pstatus;
-
- ASTOBJ_RDLOCK(iterator);
-
- if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
- continue;
- }
-
- if (!ast_strlen_zero(iterator->username) && !s)
- snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
- else
- ast_copy_string(name, iterator->name, sizeof(name));
-
- pstatus = peer_status(iterator, status, sizeof(status));
- if (pstatus == 1)
- peers_mon_online++;
- else if (pstatus == 0)
- peers_mon_offline++;
- else {
- if (iterator->addr.sin_port == 0)
- peers_unmon_offline++;
- else
- peers_unmon_online++;
- }
-
- snprintf(srch, sizeof(srch), FORMAT, name,
- iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
- ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */
- ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
- iterator->ha ? " A " : " ", /* permit/deny */
- ntohs(iterator->addr.sin_port), status,
- realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
-
- if (!s) {/* Normal CLI list */
- ast_cli(fd, FORMAT, name,
- iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
- ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */
- ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
- iterator->ha ? " A " : " ", /* permit/deny */
-
- ntohs(iterator->addr.sin_port), status,
- realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
- } else { /* Manager format */
- /* The names here need to be the same as other channels */
- astman_append(s,
- "Event: PeerEntry\r\n%s"
- "Channeltype: SIP\r\n"
- "ObjectName: %s\r\n"
- "ChanObjectType: peer\r\n" /* "peer" or "user" */
- "IPaddress: %s\r\n"
- "IPport: %d\r\n"
- "Dynamic: %s\r\n"
- "Natsupport: %s\r\n"
- "VideoSupport: %s\r\n"
- "ACL: %s\r\n"
- "Status: %s\r\n"
- "RealtimeDevice: %s\r\n\r\n",
- idtext,
- iterator->name,
- iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
- ntohs(iterator->addr.sin_port),
- ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */
- ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
- ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
- iterator->ha ? "yes" : "no", /* permit/deny */
- status,
- realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
- }
-
- ASTOBJ_UNLOCK(iterator);
-
- total_peers++;
- } while(0) );
-
- if (!s)
- ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
- total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
-
- if (havepattern)
- regfree(&regexbuf);
-
- if (total)
- *total = total_peers;
-
-
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-/*! \brief List all allocated SIP Objects (realtime or static) */
-static int sip_show_objects(int fd, int argc, char *argv[])
-{
- char tmp[256];
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
- ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
- ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
- ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
- ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
- ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
- return RESULT_SUCCESS;
-}
-/*! \brief Print call group and pickup group */
-static void print_group(int fd, ast_group_t group, int crlf)
-{
- char buf[256];
- ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
-}
-
-/*! \brief Convert DTMF mode to printable string */
-static const char *dtmfmode2str(int mode)
-{
- switch (mode) {
- case SIP_DTMF_RFC2833:
- return "rfc2833";
- case SIP_DTMF_INFO:
- return "info";
- case SIP_DTMF_INBAND:
- return "inband";
- case SIP_DTMF_AUTO:
- return "auto";
- }
- return "<error>";
-}
-
-/*! \brief Convert Insecure setting to printable string */
-static const char *insecure2str(int port, int invite)
-{
- if (port && invite)
- return "port,invite";
- else if (port)
- return "port";
- else if (invite)
- return "invite";
- else
- return "no";
-}
-
-/*! \brief Destroy disused contexts between reloads
- Only used in reload_config so the code for regcontext doesn't get ugly
-*/
-static void cleanup_stale_contexts(char *new, char *old)
-{
- char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
-
- while ((oldcontext = strsep(&old, "&"))) {
- stalecontext = '\0';
- ast_copy_string(newlist, new, sizeof(newlist));
- stringp = newlist;
- while ((newcontext = strsep(&stringp, "&"))) {
- if (strcmp(newcontext, oldcontext) == 0) {
- /* This is not the context you're looking for */
- stalecontext = '\0';
- break;
- } else if (strcmp(newcontext, oldcontext)) {
- stalecontext = oldcontext;
- }
-
- }
- if (stalecontext)
- ast_context_destroy(ast_context_find(stalecontext), "SIP");
- }
-}
-
-/*! \brief Remove temporary realtime objects from memory (CLI) */
-static int sip_prune_realtime(int fd, int argc, char *argv[])
-{
- struct sip_peer *peer;
- struct sip_user *user;
- int pruneuser = FALSE;
- int prunepeer = FALSE;
- int multi = FALSE;
- char *name = NULL;
- regex_t regexbuf;
-
- switch (argc) {
- case 4:
- if (!strcasecmp(argv[3], "user"))
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[3], "peer"))
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[3], "like"))
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[3], "all")) {
- multi = TRUE;
- pruneuser = prunepeer = TRUE;
- } else {
- pruneuser = prunepeer = TRUE;
- name = argv[3];
- }
- break;
- case 5:
- if (!strcasecmp(argv[4], "like"))
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[3], "all"))
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[3], "like")) {
- multi = TRUE;
- name = argv[4];
- pruneuser = prunepeer = TRUE;
- } else if (!strcasecmp(argv[3], "user")) {
- pruneuser = TRUE;
- if (!strcasecmp(argv[4], "all"))
- multi = TRUE;
- else
- name = argv[4];
- } else if (!strcasecmp(argv[3], "peer")) {
- prunepeer = TRUE;
- if (!strcasecmp(argv[4], "all"))
- multi = TRUE;
- else
- name = argv[4];
- } else
- return RESULT_SHOWUSAGE;
- break;
- case 6:
- if (strcasecmp(argv[4], "like"))
- return RESULT_SHOWUSAGE;
- if (!strcasecmp(argv[3], "user")) {
- pruneuser = TRUE;
- name = argv[5];
- } else if (!strcasecmp(argv[3], "peer")) {
- prunepeer = TRUE;
- name = argv[5];
- } else
- return RESULT_SHOWUSAGE;
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
- if (multi && name) {
- if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- }
-
- if (multi) {
- if (prunepeer) {
- int pruned = 0;
-
- ASTOBJ_CONTAINER_WRLOCK(&peerl);
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
- continue;
- };
- if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- ASTOBJ_MARK(iterator);
- pruned++;
- }
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
- ast_cli(fd, "%d peers pruned.\n", pruned);
- } else
- ast_cli(fd, "No peers found to prune.\n");
- ASTOBJ_CONTAINER_UNLOCK(&peerl);
- }
- if (pruneuser) {
- int pruned = 0;
-
- ASTOBJ_CONTAINER_WRLOCK(&userl);
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
- continue;
- };
- if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- ASTOBJ_MARK(iterator);
- pruned++;
- }
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
- ast_cli(fd, "%d users pruned.\n", pruned);
- } else
- ast_cli(fd, "No users found to prune.\n");
- ASTOBJ_CONTAINER_UNLOCK(&userl);
- }
- } else {
- if (prunepeer) {
- if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
- if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
- } else
- ast_cli(fd, "Peer '%s' pruned.\n", name);
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- } else
- ast_cli(fd, "Peer '%s' not found.\n", name);
- }
- if (pruneuser) {
- if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
- if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
- ASTOBJ_CONTAINER_LINK(&userl, user);
- } else
- ast_cli(fd, "User '%s' pruned.\n", name);
- ASTOBJ_UNREF(user, sip_destroy_user);
- } else
- ast_cli(fd, "User '%s' not found.\n", name);
- }
- }
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief Print codec list from preference to CLI/manager */
-static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
-{
- int x, codec;
-
- for(x = 0; x < 32 ; x++) {
- codec = ast_codec_pref_index(pref, x);
- if (!codec)
- break;
- ast_cli(fd, "%s", ast_getformatname(codec));
- ast_cli(fd, ":%d", pref->framing[x]);
- if (x < 31 && ast_codec_pref_index(pref, x + 1))
- ast_cli(fd, ",");
- }
- if (!x)
- ast_cli(fd, "none");
-}
-
-/*! \brief Print domain mode to cli */
-static const char *domain_mode_to_text(const enum domain_mode mode)
-{
- switch (mode) {
- case SIP_DOMAIN_AUTO:
- return "[Automatic]";
- case SIP_DOMAIN_CONFIG:
- return "[Configured]";
- }
-
- return "";
-}
-
-/*! \brief CLI command to list local domains */
-static int sip_show_domains(int fd, int argc, char *argv[])
-{
- struct domain *d;
-#define FORMAT "%-40.40s %-20.20s %-16.16s\n"
-
- if (AST_LIST_EMPTY(&domain_list)) {
- ast_cli(fd, "SIP Domain support not enabled.\n\n");
- return RESULT_SUCCESS;
- } else {
- ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
- AST_LIST_LOCK(&domain_list);
- AST_LIST_TRAVERSE(&domain_list, d, list)
- ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
- domain_mode_to_text(d->mode));
- AST_LIST_UNLOCK(&domain_list);
- ast_cli(fd, "\n");
- return RESULT_SUCCESS;
- }
-}
-#undef FORMAT
-
-static char mandescr_show_peer[] =
-"Description: Show one SIP peer with details on current status.\n"
-"Variables: \n"
-" Peer: <name> The peer name you want to check.\n"
-" ActionID: <id> Optional action ID for this AMI transaction.\n";
-
-/*! \brief Show SIP peers in the manager API */
-static int manager_sip_show_peer(struct mansession *s, const struct message *m)
-{
- const char *a[4];
- const char *peer;
- int ret;
-
- peer = astman_get_header(m,"Peer");
- if (ast_strlen_zero(peer)) {
- astman_send_error(s, m, "Peer: <name> missing.\n");
- return 0;
- }
- a[0] = "sip";
- a[1] = "show";
- a[2] = "peer";
- a[3] = peer;
-
- ret = _sip_show_peer(1, -1, s, m, 4, a);
- astman_append(s, "\r\n\r\n" );
- return ret;
-}
-
-
-
-/*! \brief Show one peer in detail */
-static int sip_show_peer(int fd, int argc, char *argv[])
-{
- return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
-}
-
-/*! \brief Show one peer in detail (main function) */
-static int _sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
-{
- char status[30] = "";
- char cbuf[256];
- struct sip_peer *peer;
- char codec_buf[512];
- struct ast_codec_pref *pref;
- struct ast_variable *v;
- struct sip_auth *auth;
- int x = 0, codec = 0, load_realtime;
- int realtimepeers;
-
- realtimepeers = ast_check_realtime("sippeers");
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
- peer = find_peer(argv[3], NULL, load_realtime);
- if (s) { /* Manager */
- if (peer) {
- const char *id = astman_get_header(m,"ActionID");
-
- astman_append(s, "Response: Success\r\n");
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n",id);
- } else {
- snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]);
- astman_send_error(s, m, cbuf);
- return 0;
- }
- }
- if (peer && type==0 ) { /* Normal listing */
- ast_cli(fd,"\n\n");
- ast_cli(fd, " * Name : %s\n", peer->name);
- if (realtimepeers) { /* Realtime is enabled */
- ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
- }
- ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
- ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
- for (auth = peer->auth; auth; auth = auth->next) {
- ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
- ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
- }
- ast_cli(fd, " Context : %s\n", peer->context);
- ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
- ast_cli(fd, " Language : %s\n", peer->language);
- if (!ast_strlen_zero(peer->accountcode))
- ast_cli(fd, " Accountcode : %s\n", peer->accountcode);
- ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags));
- ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
- ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres));
- if (!ast_strlen_zero(peer->fromuser))
- ast_cli(fd, " FromUser : %s\n", peer->fromuser);
- if (!ast_strlen_zero(peer->fromdomain))
- ast_cli(fd, " FromDomain : %s\n", peer->fromdomain);
- ast_cli(fd, " Callgroup : ");
- print_group(fd, peer->callgroup, 0);
- ast_cli(fd, " Pickupgroup : ");
- print_group(fd, peer->pickupgroup, 0);
- ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
- ast_cli(fd, " VM Extension : %s\n", peer->vmexten);
- ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
- ast_cli(fd, " Call limit : %d\n", peer->call_limit);
- ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
- ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
- ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate);
- ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire));
- ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)));
- ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
- ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
- ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
-#ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
- ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
- ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
-#endif
- ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
- ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
- ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
- ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
- ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
- ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
- ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
- ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
-
- /* - is enumerated */
- ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
- ast_cli(fd, " LastMsg : %d\n", peer->lastmsg);
- ast_cli(fd, " ToHost : %s\n", peer->tohost);
- ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
- ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
- if (!ast_strlen_zero(global_regcontext))
- ast_cli(fd, " Reg. exten : %s\n", peer->regexten);
- ast_cli(fd, " Def. Username: %s\n", peer->username);
- ast_cli(fd, " SIP Options : ");
- if (peer->sipoptions) {
- int lastoption = -1;
- for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
- if (sip_options[x].id != lastoption) {
- if (peer->sipoptions & sip_options[x].id)
- ast_cli(fd, "%s ", sip_options[x].text);
- lastoption = x;
- }
- }
- } else
- ast_cli(fd, "(none)");
-
- ast_cli(fd, "\n");
- ast_cli(fd, " Codecs : ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
- ast_cli(fd, "%s\n", codec_buf);
- ast_cli(fd, " Codec Order : (");
- print_codec_to_cli(fd, &peer->prefs);
- ast_cli(fd, ")\n");
-
- ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No");
- ast_cli(fd, " Status : ");
- peer_status(peer, status, sizeof(status));
- ast_cli(fd, "%s\n",status);
- ast_cli(fd, " Useragent : %s\n", peer->useragent);
- ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact);
- if (peer->chanvars) {
- ast_cli(fd, " Variables :\n");
- for (v = peer->chanvars ; v ; v = v->next)
- ast_cli(fd, " %s = %s\n", v->name, v->value);
- }
- ast_cli(fd,"\n");
- ASTOBJ_UNREF(peer,sip_destroy_peer);
- } else if (peer && type == 1) { /* manager listing */
- char buf[256];
- astman_append(s, "Channeltype: SIP\r\n");
- astman_append(s, "ObjectName: %s\r\n", peer->name);
- astman_append(s, "ChanObjectType: peer\r\n");
- astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
- astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
- astman_append(s, "Context: %s\r\n", peer->context);
- astman_append(s, "Language: %s\r\n", peer->language);
- if (!ast_strlen_zero(peer->accountcode))
- astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
- astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
- astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
- if (!ast_strlen_zero(peer->fromuser))
- astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
- if (!ast_strlen_zero(peer->fromdomain))
- astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
- astman_append(s, "Callgroup: ");
- astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
- astman_append(s, "Pickupgroup: ");
- astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
- astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
- astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
- astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
- astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
- astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
- astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
- astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
- astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
- astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)));
- astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
- astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
- astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
- astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
- astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
- astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
-
- /* - is enumerated */
- astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
- astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
- astman_append(s, "ToHost: %s\r\n", peer->tohost);
- astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port));
- astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
- astman_append(s, "Default-Username: %s\r\n", peer->username);
- if (!ast_strlen_zero(global_regcontext))
- astman_append(s, "RegExtension: %s\r\n", peer->regexten);
- astman_append(s, "Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
- astman_append(s, "%s\r\n", codec_buf);
- astman_append(s, "CodecOrder: ");
- pref = &peer->prefs;
- for(x = 0; x < 32 ; x++) {
- codec = ast_codec_pref_index(pref,x);
- if (!codec)
- break;
- astman_append(s, "%s", ast_getformatname(codec));
- if (x < 31 && ast_codec_pref_index(pref,x+1))
- astman_append(s, ",");
- }
-
- astman_append(s, "\r\n");
- astman_append(s, "Status: ");
- peer_status(peer, status, sizeof(status));
- astman_append(s, "%s\r\n", status);
- astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
- astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
- if (peer->chanvars) {
- for (v = peer->chanvars ; v ; v = v->next) {
- astman_append(s, "ChanVariable:\n");
- astman_append(s, " %s,%s\r\n", v->name, v->value);
- }
- }
-
- ASTOBJ_UNREF(peer,sip_destroy_peer);
-
- } else {
- ast_cli(fd,"Peer %s not found.\n", argv[3]);
- ast_cli(fd,"\n");
- }
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief Show one user in detail */
-static int sip_show_user(int fd, int argc, char *argv[])
-{
- char cbuf[256];
- struct sip_user *user;
- struct ast_variable *v;
- int load_realtime;
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- /* Load from realtime storage? */
- load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-
- user = find_user(argv[3], load_realtime);
- if (user) {
- ast_cli(fd,"\n\n");
- ast_cli(fd, " * Name : %s\n", user->name);
- ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
- ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
- ast_cli(fd, " Context : %s\n", user->context);
- ast_cli(fd, " Language : %s\n", user->language);
- if (!ast_strlen_zero(user->accountcode))
- ast_cli(fd, " Accountcode : %s\n", user->accountcode);
- ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags));
- ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer));
- ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate);
- ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres));
- ast_cli(fd, " Call limit : %d\n", user->call_limit);
- ast_cli(fd, " Callgroup : ");
- print_group(fd, user->callgroup, 0);
- ast_cli(fd, " Pickupgroup : ");
- print_group(fd, user->pickupgroup, 0);
- ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
- ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No"));
- ast_cli(fd, " Codec Order : (");
- print_codec_to_cli(fd, &user->prefs);
- ast_cli(fd, ")\n");
-
- ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No");
- if (user->chanvars) {
- ast_cli(fd, " Variables :\n");
- for (v = user->chanvars ; v ; v = v->next)
- ast_cli(fd, " %s = %s\n", v->name, v->value);
- }
- ast_cli(fd,"\n");
- ASTOBJ_UNREF(user,sip_destroy_user);
- } else {
- ast_cli(fd,"User %s not found.\n", argv[3]);
- ast_cli(fd,"\n");
- }
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief Show SIP Registry (registrations with other SIP proxies */
-static int sip_show_registry(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"
-#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n"
- char host[80];
- char tmpdat[256];
- struct tm tm;
-
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
- ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
- if (iterator->regtime) {
- ast_localtime(&iterator->regtime, &tm, NULL);
- strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
- } else {
- tmpdat[0] = 0;
- }
- ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
- ASTOBJ_UNLOCK(iterator);
- } while(0));
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-/*! \brief List global settings for the SIP channel */
-static int sip_show_settings(int fd, int argc, char *argv[])
-{
- int realtimepeers;
- int realtimeusers;
- char codec_buf[SIPBUFSIZE];
-
- realtimepeers = ast_check_realtime("sippeers");
- realtimeusers = ast_check_realtime("sipusers");
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, "\n\nGlobal Settings:\n");
- ast_cli(fd, "----------------\n");
- ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port));
- ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr));
- ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
- ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No");
- ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No");
- ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
- ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
- ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
- ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
- ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
- ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
- ast_cli(fd, " Our auth realm %s\n", global_realm);
- ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No");
- ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No");
- ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No");
- ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No");
- ast_cli(fd, " User Agent: %s\n", global_useragent);
- ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime);
- ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)"));
- ast_cli(fd, " Caller ID: %s\n", default_callerid);
- ast_cli(fd, " From: Domain: %s\n", default_fromdomain);
- ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off");
- ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off");
- ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip));
- ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio));
- ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video));
- ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
-#ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
- ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
- ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
-#endif
- ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
- if (!realtimepeers && !realtimeusers)
- ast_cli(fd, " SIP realtime: Disabled\n" );
- else
- ast_cli(fd, " SIP realtime: Enabled\n" );
-
- ast_cli(fd, "\nGlobal Signalling Settings:\n");
- ast_cli(fd, "---------------------------\n");
- ast_cli(fd, " Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
- ast_cli(fd, "%s\n", codec_buf);
- ast_cli(fd, " Codec Order: ");
- print_codec_to_cli(fd, &default_prefs);
- ast_cli(fd, "\n");
- ast_cli(fd, " T1 minimum: %d\n", global_t1min);
- ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No");
- ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No");
- ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
- ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
- ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
- ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime);
- ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No");
- ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No");
- ast_cli(fd, " Reg. min duration %d secs\n", min_expiry);
- ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry);
- ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry);
- ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout);
- ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max);
- ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No");
- ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No");
- ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer));
- ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate);
- ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No");
- ast_cli(fd, "\nDefault Settings:\n");
- ast_cli(fd, "-----------------\n");
- ast_cli(fd, " Context: %s\n", default_context);
- ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
- ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
- ast_cli(fd, " Qualify: %d\n", default_qualify);
- ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
- ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" );
- ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)"));
- ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret);
- ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest);
- ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten);
-
-
- if (realtimepeers || realtimeusers) {
- ast_cli(fd, "\nRealtime SIP Settings:\n");
- ast_cli(fd, "----------------------\n");
- ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No");
- ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No");
- ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
- ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
- ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
- ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
- ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear);
- }
- ast_cli(fd, "\n----\n");
- return RESULT_SUCCESS;
-}
-
-/*! \brief Show subscription type in string format */
-static const char *subscription_type2str(enum subscriptiontype subtype)
-{
- int i;
-
- for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
- if (subscription_types[i].type == subtype) {
- return subscription_types[i].text;
- }
- }
- return subscription_types[0].text;
-}
-
-/*! \brief Find subscription type in array */
-static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype)
-{
- int i;
-
- for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
- if (subscription_types[i].type == subtype) {
- return &subscription_types[i];
- }
- }
- return &subscription_types[0];
-}
-
-/*! \brief Show active SIP channels */
-static int sip_show_channels(int fd, int argc, char *argv[])
-{
- return __sip_show_channels(fd, argc, argv, 0);
-}
-
-/*! \brief Show active SIP subscriptions */
-static int sip_show_subscriptions(int fd, int argc, char *argv[])
-{
- return __sip_show_channels(fd, argc, argv, 1);
-}
-
-/*! \brief SIP show channels CLI (main function) */
-static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions)
-{
-#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n"
-#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"
-#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"
- struct sip_pvt *cur;
- int numchans = 0;
- char *referstatus = NULL;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_mutex_lock(&iflock);
- cur = iflist;
- if (!subscriptions)
- ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
- else
- ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
- for (; cur; cur = cur->next) {
- referstatus = "";
- if (cur->refer) { /* SIP transfer in progress */
- referstatus = referstatus2str(cur->refer->status);
- }
- if (cur->subscribed == NONE && !subscriptions) {
- char formatbuf[SIPBUFSIZE/2];
- ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr),
- S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
- cur->callid,
- cur->ocseq, cur->icseq,
- ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
- ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
- ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
- cur->lastmsg ,
- referstatus
- );
- numchans++;
- }
- if (cur->subscribed != NONE && subscriptions) {
- ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr),
- S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
- cur->callid,
- /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
- cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
- cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
- subscription_type2str(cur->subscribed),
- cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
-);
- numchans++;
- }
- }
- ast_mutex_unlock(&iflock);
- if (!subscriptions)
- ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
- else
- ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-#undef FORMAT3
-}
-
-/*! \brief Support routine for 'sip show channel' CLI */
-static char *complete_sipch(const char *line, const char *word, int pos, int state)
-{
- int which=0;
- struct sip_pvt *cur;
- char *c = NULL;
- int wordlen = strlen(word);
-
- if (pos != 3) {
- return NULL;
- }
-
- ast_mutex_lock(&iflock);
- for (cur = iflist; cur; cur = cur->next) {
- if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
- c = ast_strdup(cur->callid);
- break;
- }
- }
- ast_mutex_unlock(&iflock);
- return c;
-}
-
-/*! \brief Do completion on peer name */
-static char *complete_sip_peer(const char *word, int state, int flags2)
-{
- char *result = NULL;
- int wordlen = strlen(word);
- int which = 0;
-
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
- /* locking of the object is not required because only the name and flags are being compared */
- if (!strncasecmp(word, iterator->name, wordlen) &&
- (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
- ++which > state)
- result = ast_strdup(iterator->name);
- } while(0) );
- return result;
-}
-
-/*! \brief Support routine for 'sip show peer' CLI */
-static char *complete_sip_show_peer(const char *line, const char *word, int pos, int state)
-{
- if (pos == 3)
- return complete_sip_peer(word, state, 0);
-
- return NULL;
-}
-
-/*! \brief Support routine for 'sip debug peer' CLI */
-static char *complete_sip_debug_peer(const char *line, const char *word, int pos, int state)
-{
- if (pos == 3)
- return complete_sip_peer(word, state, 0);
-
- return NULL;
-}
-
-/*! \brief Do completion on user name */
-static char *complete_sip_user(const char *word, int state, int flags2)
-{
- char *result = NULL;
- int wordlen = strlen(word);
- int which = 0;
-
- ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
- /* locking of the object is not required because only the name and flags are being compared */
- if (!strncasecmp(word, iterator->name, wordlen)) {
- if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
- continue;
- if (++which > state) {
- result = ast_strdup(iterator->name);
- }
- }
- } while(0) );
- return result;
-}
-
-/*! \brief Support routine for 'sip show user' CLI */
-static char *complete_sip_show_user(const char *line, const char *word, int pos, int state)
-{
- if (pos == 3)
- return complete_sip_user(word, state, 0);
-
- return NULL;
-}
-
-/*! \brief Support routine for 'sip notify' CLI */
-static char *complete_sipnotify(const char *line, const char *word, int pos, int state)
-{
- char *c = NULL;
-
- if (pos == 2) {
- int which = 0;
- char *cat = NULL;
- int wordlen = strlen(word);
-
- /* do completion for notify type */
-
- if (!notify_types)
- return NULL;
-
- while ( (cat = ast_category_browse(notify_types, cat)) ) {
- if (!strncasecmp(word, cat, wordlen) && ++which > state) {
- c = ast_strdup(cat);
- break;
- }
- }
- return c;
- }
-
- if (pos > 2)
- return complete_sip_peer(word, state, 0);
-
- return NULL;
-}
-
-/*! \brief Support routine for 'sip prune realtime peer' CLI */
-static char *complete_sip_prune_realtime_peer(const char *line, const char *word, int pos, int state)
-{
- if (pos == 4)
- return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
- return NULL;
-}
-
-/*! \brief Support routine for 'sip prune realtime user' CLI */
-static char *complete_sip_prune_realtime_user(const char *line, const char *word, int pos, int state)
-{
- if (pos == 4)
- return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
-
- return NULL;
-}
-
-/*! \brief Show details of one active dialog */
-static int sip_show_channel(int fd, int argc, char *argv[])
-{
- struct sip_pvt *cur;
- size_t len;
- int found = 0;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- len = strlen(argv[3]);
- ast_mutex_lock(&iflock);
- for (cur = iflist; cur; cur = cur->next) {
- if (!strncasecmp(cur->callid, argv[3], len)) {
- char formatbuf[SIPBUFSIZE/2];
- ast_cli(fd,"\n");
- if (cur->subscribed != NONE)
- ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
- else
- ast_cli(fd, " * SIP Call\n");
- ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
- ast_cli(fd, " Call-ID: %s\n", cur->callid);
- ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>");
- ast_cli(fd, " Our Codec Capability: %d\n", cur->capability);
- ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability);
- ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability);
- ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability);
- ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
- ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate);
- ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
- ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
- ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
- ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
- ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
- ast_cli(fd, " Our Tag: %s\n", cur->tag);
- ast_cli(fd, " Their Tag: %s\n", cur->theirtag);
- ast_cli(fd, " SIP User agent: %s\n", cur->useragent);
- if (!ast_strlen_zero(cur->username))
- ast_cli(fd, " Username: %s\n", cur->username);
- if (!ast_strlen_zero(cur->peername))
- ast_cli(fd, " Peername: %s\n", cur->peername);
- if (!ast_strlen_zero(cur->uri))
- ast_cli(fd, " Original uri: %s\n", cur->uri);
- if (!ast_strlen_zero(cur->cid_num))
- ast_cli(fd, " Caller-ID: %s\n", cur->cid_num);
- ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
- ast_cli(fd, " Last Message: %s\n", cur->lastmsg);
- ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
- ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A");
- ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
- ast_cli(fd, " SIP Options: ");
- if (cur->sipoptions) {
- int x;
- for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
- if (cur->sipoptions & sip_options[x].id)
- ast_cli(fd, "%s ", sip_options[x].text);
- }
- } else
- ast_cli(fd, "(none)\n");
- ast_cli(fd, "\n\n");
- found++;
- }
- }
- ast_mutex_unlock(&iflock);
- if (!found)
- ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
- return RESULT_SUCCESS;
-}
-
-/*! \brief Show history details of one dialog */
-static int sip_show_history(int fd, int argc, char *argv[])
-{
- struct sip_pvt *cur;
- size_t len;
- int found = 0;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (!recordhistory)
- ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n");
- len = strlen(argv[3]);
- ast_mutex_lock(&iflock);
- for (cur = iflist; cur; cur = cur->next) {
- if (!strncasecmp(cur->callid, argv[3], len)) {
- struct sip_history *hist;
- int x = 0;
-
- ast_cli(fd,"\n");
- if (cur->subscribed != NONE)
- ast_cli(fd, " * Subscription\n");
- else
- ast_cli(fd, " * SIP Call\n");
- if (cur->history)
- AST_LIST_TRAVERSE(cur->history, hist, list)
- ast_cli(fd, "%d. %s\n", ++x, hist->event);
- if (x == 0)
- ast_cli(fd, "Call '%s' has no history\n", cur->callid);
- found++;
- }
- }
- ast_mutex_unlock(&iflock);
- if (!found)
- ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
- return RESULT_SUCCESS;
-}
-
-/*! \brief Dump SIP history to debug log file at end of lifespan for SIP dialog */
-static void sip_dump_history(struct sip_pvt *dialog)
-{
- int x = 0;
- struct sip_history *hist;
- static int errmsg = 0;
-
- if (!dialog)
- return;
-
- if (!option_debug && !sipdebug) {
- if (!errmsg) {
- ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
- errmsg = 1;
- }
- return;
- }
-
- ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
- if (dialog->subscribed)
- ast_log(LOG_DEBUG, " * Subscription\n");
- else
- ast_log(LOG_DEBUG, " * SIP Call\n");
- if (dialog->history)
- AST_LIST_TRAVERSE(dialog->history, hist, list)
- ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event);
- if (!x)
- ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
- ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
-}
-
-
-/*! \brief Receive SIP INFO Message
-\note Doesn't read the duration of the DTMF signal */
-static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
-{
- char buf[1024];
- unsigned int event;
- const char *c = get_header(req, "Content-Type");
-
- /* Need to check the media/type */
- if (!strcasecmp(c, "application/dtmf-relay") ||
- !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
- unsigned int duration = 0;
-
- /* Try getting the "signal=" part */
- if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
- ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
- transmit_response(p, "200 OK", req); /* Should return error */
- return;
- } else {
- ast_copy_string(buf, c, sizeof(buf));
- }
-
- if (!ast_strlen_zero((c = get_body(req, "Duration"))))
- duration = atoi(c);
- if (!duration)
- duration = 100; /* 100 ms */
-
- if (!p->owner) { /* not a PBX call */
- transmit_response(p, "481 Call leg/transaction does not exist", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- }
-
- if (ast_strlen_zero(buf)) {
- transmit_response(p, "200 OK", req);
- return;
- }
-
- if (buf[0] == '*')
- event = 10;
- else if (buf[0] == '#')
- event = 11;
- else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
- event = 12 + buf[0] - 'A';
- else
- event = atoi(buf);
- if (event == 16) {
- /* send a FLASH event */
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
- ast_queue_frame(p->owner, &f);
- if (sipdebug)
- ast_verbose("* DTMF-relay event received: FLASH\n");
- } else {
- /* send a DTMF event */
- struct ast_frame f = { AST_FRAME_DTMF, };
- if (event < 10) {
- f.subclass = '0' + event;
- } else if (event < 11) {
- f.subclass = '*';
- } else if (event < 12) {
- f.subclass = '#';
- } else if (event < 16) {
- f.subclass = 'A' + (event - 12);
- }
- f.len = duration;
- ast_queue_frame(p->owner, &f);
- if (sipdebug)
- ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
- }
- transmit_response(p, "200 OK", req);
- return;
- } else if (!strcasecmp(c, "application/media_control+xml")) {
- /* Eh, we'll just assume it's a fast picture update for now */
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
- transmit_response(p, "200 OK", req);
- return;
- } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
- /* Client code (from SNOM phone) */
- if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
- if (p->owner && p->owner->cdr)
- ast_cdr_setuserfield(p->owner, c);
- if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
- ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
- transmit_response(p, "200 OK", req);
- } else {
- transmit_response(p, "403 Unauthorized", req);
- }
- return;
- } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
- /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
- transmit_response(p, "200 OK", req);
- return;
- }
-
- /* Other type of INFO message, not really understood by Asterisk */
- /* if (get_msg_text(buf, sizeof(buf), req)) { */
-
- ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
- transmit_response(p, "415 Unsupported media type", req);
- return;
-}
-
-/*! \brief Enable SIP Debugging in CLI */
-static int sip_do_debug_ip(int fd, int argc, char *argv[])
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port = 0;
- char *p, *arg;
-
- /* sip set debug ip <ip> */
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- p = arg = argv[4];
- strsep(&p, ":");
- if (p)
- port = atoi(p);
- hp = ast_gethostbyname(arg, &ahp);
- if (hp == NULL)
- return RESULT_SHOWUSAGE;
-
- debugaddr.sin_family = AF_INET;
- memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
- debugaddr.sin_port = htons(port);
- if (port == 0)
- ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
- else
- ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
-
- ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief sip_do_debug_peer: Turn on SIP debugging with peer mask */
-static int sip_do_debug_peer(int fd, int argc, char *argv[])
-{
- struct sip_peer *peer;
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- peer = find_peer(argv[4], NULL, 1);
- if (peer) {
- if (peer->addr.sin_addr.s_addr) {
- debugaddr.sin_family = AF_INET;
- debugaddr.sin_addr = peer->addr.sin_addr;
- debugaddr.sin_port = peer->addr.sin_port;
- ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
- ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
- } else
- ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
- ASTOBJ_UNREF(peer,sip_destroy_peer);
- } else
- ast_cli(fd, "No such peer '%s'\n", argv[4]);
- return RESULT_SUCCESS;
-}
-
-/*! \brief Turn on SIP debugging (CLI command) */
-static int sip_do_debug(int fd, int argc, char *argv[])
-{
- int oldsipdebug = sipdebug_console;
- if (argc != 3) {
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- else if (strcmp(argv[3], "ip") == 0)
- return sip_do_debug_ip(fd, argc, argv);
- else if (strcmp(argv[3], "peer") == 0)
- return sip_do_debug_peer(fd, argc, argv);
- else
- return RESULT_SHOWUSAGE;
- }
- ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
- memset(&debugaddr, 0, sizeof(debugaddr));
- ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
- return RESULT_SUCCESS;
-}
-
-static int sip_do_debug_deprecated(int fd, int argc, char *argv[])
-{
- int oldsipdebug = sipdebug_console;
- char *newargv[6] = { "sip", "set", "debug", NULL };
- if (argc != 2) {
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- else if (strcmp(argv[2], "ip") == 0) {
- newargv[3] = argv[2];
- newargv[4] = argv[3];
- return sip_do_debug_ip(fd, argc + 1, newargv);
- } else if (strcmp(argv[2], "peer") == 0) {
- newargv[3] = argv[2];
- newargv[4] = argv[3];
- return sip_do_debug_peer(fd, argc + 1, newargv);
- } else
- return RESULT_SHOWUSAGE;
- }
- ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
- memset(&debugaddr, 0, sizeof(debugaddr));
- ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
- return RESULT_SUCCESS;
-}
-
-/*! \brief Cli command to send SIP notify to peer */
-static int sip_notify(int fd, int argc, char *argv[])
-{
- struct ast_variable *varlist;
- int i;
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- if (!notify_types) {
- ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
- return RESULT_FAILURE;
- }
-
- varlist = ast_variable_browse(notify_types, argv[2]);
-
- if (!varlist) {
- ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
- return RESULT_FAILURE;
- }
-
- for (i = 3; i < argc; i++) {
- struct sip_pvt *p;
- struct sip_request req;
- struct ast_variable *var;
-
- if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
- ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
- return RESULT_FAILURE;
- }
-
- if (create_addr(p, argv[i])) {
- /* Maybe they're not registered, etc. */
- sip_destroy(p);
- ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
- continue;
- }
-
- initreqprep(&req, p, SIP_NOTIFY);
-
- for (var = varlist; var; var = var->next)
- add_header(&req, var->name, ast_unescape_semicolon(var->value));
-
- /* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
- build_via(p);
- build_callid_pvt(p);
- ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
- transmit_sip_request(p, &req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief Disable SIP Debugging in CLI */
-static int sip_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
- ast_cli(fd, "SIP Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int sip_no_debug_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
- ast_cli(fd, "SIP Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-/*! \brief Enable SIP History logging (CLI) */
-static int sip_do_history(int fd, int argc, char *argv[])
-{
- if (argc != 2) {
- return RESULT_SHOWUSAGE;
- }
- recordhistory = TRUE;
- ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
- return RESULT_SUCCESS;
-}
-
-/*! \brief Disable SIP History logging (CLI) */
-static int sip_no_history(int fd, int argc, char *argv[])
-{
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- recordhistory = FALSE;
- ast_cli(fd, "SIP History Recording Disabled\n");
- return RESULT_SUCCESS;
-}
-
-/*! \brief Authenticate for outbound registration */
-static int do_register_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader)
-{
- char digest[1024];
- p->authtries++;
- memset(digest,0,sizeof(digest));
- if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
- /* There's nothing to use for authentication */
- /* No digest challenge in request */
- if (sip_debug_test_pvt(p) && p->registry)
- ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
- /* No old challenge */
- return -1;
- }
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "RegistryAuth", "Try: %d", p->authtries);
- if (sip_debug_test_pvt(p) && p->registry)
- ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
- return transmit_register(p->registry, SIP_REGISTER, digest, respheader);
-}
-
-/*! \brief Add authentication on outbound SIP packet */
-static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init)
-{
- char digest[1024];
-
- if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
- return -2;
-
- p->authtries++;
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
- memset(digest, 0, sizeof(digest));
- if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
- /* No way to authenticate */
- return -1;
- }
- /* Now we have a reply digest */
- p->options->auth = digest;
- p->options->authheader = respheader;
- return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init);
-}
-
-/*! \brief reply to authentication for outbound registrations
-\return Returns -1 if we have no auth
-\note This is used for register= servers in sip.conf, SIP proxies we register
- with for receiving calls from. */
-static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
-{
- char tmp[512];
- char *c;
- char oldnonce[256];
-
- /* table of recognised keywords, and places where they should be copied */
- const struct x {
- const char *key;
- int field_index;
- } *i, keys[] = {
- { "realm=", ast_string_field_index(p, realm) },
- { "nonce=", ast_string_field_index(p, nonce) },
- { "opaque=", ast_string_field_index(p, opaque) },
- { "qop=", ast_string_field_index(p, qop) },
- { "domain=", ast_string_field_index(p, domain) },
- { NULL, 0 },
- };
-
- ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
- if (ast_strlen_zero(tmp))
- return -1;
- if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
- ast_log(LOG_WARNING, "missing Digest.\n");
- return -1;
- }
- c = tmp + strlen("Digest ");
- ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
- while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
- for (i = keys; i->key != NULL; i++) {
- char *src, *separator;
- if (strncasecmp(c, i->key, strlen(i->key)) != 0)
- continue;
- /* Found. Skip keyword, take text in quotes or up to the separator. */
- c += strlen(i->key);
- if (*c == '"') {
- src = ++c;
- separator = "\"";
- } else {
- src = c;
- separator = ",";
- }
- strsep(&c, separator); /* clear separator and move ptr */
- ast_string_field_index_set(p, i->field_index, src);
- break;
- }
- if (i->key == NULL) /* not found, try ',' */
- strsep(&c, ",");
- }
- /* Reset nonce count */
- if (strcmp(p->nonce, oldnonce))
- p->noncecount = 0;
-
- /* Save auth data for following registrations */
- if (p->registry) {
- struct sip_registry *r = p->registry;
-
- if (strcmp(r->nonce, p->nonce)) {
- ast_string_field_set(r, realm, p->realm);
- ast_string_field_set(r, nonce, p->nonce);
- ast_string_field_set(r, domain, p->domain);
- ast_string_field_set(r, opaque, p->opaque);
- ast_string_field_set(r, qop, p->qop);
- r->noncecount = 0;
- }
- }
- return build_reply_digest(p, sipmethod, digest, digest_len);
-}
-
-/*! \brief Build reply digest
-\return Returns -1 if we have no auth
-\note Build digest challenge for authentication of peers (for registration)
- and users (for calls). Also used for authentication of CANCEL and BYE
-*/
-static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int digest_len)
-{
- char a1[256];
- char a2[256];
- char a1_hash[256];
- char a2_hash[256];
- char resp[256];
- char resp_hash[256];
- char uri[256];
- char opaque[256] = "";
- char cnonce[80];
- const char *username;
- const char *secret;
- const char *md5secret;
- struct sip_auth *auth = NULL; /* Realm authentication */
-
- if (!ast_strlen_zero(p->domain))
- ast_copy_string(uri, p->domain, sizeof(uri));
- else if (!ast_strlen_zero(p->uri))
- ast_copy_string(uri, p->uri, sizeof(uri));
- else
- snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
-
- snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
-
- /* Check if we have separate auth credentials */
- if ((auth = find_realm_authentication(authl, p->realm))) {
- ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n",
- auth->username, p->peername, p->username);
- username = auth->username;
- secret = auth->secret;
- md5secret = auth->md5secret;
- if (sipdebug)
- ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
- } else {
- /* No authentication, use peer or register= config */
- username = p->authname;
- secret = p->peersecret;
- md5secret = p->peermd5secret;
- }
- if (ast_strlen_zero(username)) /* We have no authentication */
- return -1;
-
- /* Calculate SIP digest response */
- snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
- snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
- if (!ast_strlen_zero(md5secret))
- ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
- else
- ast_md5_hash(a1_hash,a1);
- ast_md5_hash(a2_hash,a2);
-
- p->noncecount++;
- if (!ast_strlen_zero(p->qop))
- snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
- else
- snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
- ast_md5_hash(resp_hash, resp);
-
- /* only include the opaque string if it's set */
- if (!ast_strlen_zero(p->opaque)) {
- snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
- }
-
- /* XXX We hard code our qop to "auth" for now. XXX */
- if (!ast_strlen_zero(p->qop))
- snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
- else
- snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque);
-
- append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
-
- return 0;
-}
-
-static char show_domains_usage[] =
-"Usage: sip show domains\n"
-" Lists all configured SIP local domains.\n"
-" Asterisk only responds to SIP messages to local domains.\n";
-
-static char notify_usage[] =
-"Usage: sip notify <type> <peer> [<peer>...]\n"
-" Send a NOTIFY message to a SIP peer or peers\n"
-" Message types are defined in sip_notify.conf\n";
-
-static char show_users_usage[] =
-"Usage: sip show users [like <pattern>]\n"
-" Lists all known SIP users.\n"
-" Optional regular expression pattern is used to filter the user list.\n";
-
-static char show_user_usage[] =
-"Usage: sip show user <name> [load]\n"
-" Shows all details on one SIP user and the current status.\n"
-" Option \"load\" forces lookup of peer in realtime storage.\n";
-
-static char show_inuse_usage[] =
-"Usage: sip show inuse [all]\n"
-" List all SIP users and peers usage counters and limits.\n"
-" Add option \"all\" to show all devices, not only those with a limit.\n";
-
-static char show_channels_usage[] =
-"Usage: sip show channels\n"
-" Lists all currently active SIP channels.\n";
-
-static char show_channel_usage[] =
-"Usage: sip show channel <channel>\n"
-" Provides detailed status on a given SIP channel.\n";
-
-static char show_history_usage[] =
-"Usage: sip show history <channel>\n"
-" Provides detailed dialog history on a given SIP channel.\n";
-
-static char show_peers_usage[] =
-"Usage: sip show peers [like <pattern>]\n"
-" Lists all known SIP peers.\n"
-" Optional regular expression pattern is used to filter the peer list.\n";
-
-static char show_peer_usage[] =
-"Usage: sip show peer <name> [load]\n"
-" Shows all details on one SIP peer and the current status.\n"
-" Option \"load\" forces lookup of peer in realtime storage.\n";
-
-static char prune_realtime_usage[] =
-"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n"
-" Prunes object(s) from the cache.\n"
-" Optional regular expression pattern is used to filter the objects.\n";
-
-static char show_reg_usage[] =
-"Usage: sip show registry\n"
-" Lists all registration requests and status.\n";
-
-static char debug_usage[] =
-"Usage: sip set debug\n"
-" Enables dumping of SIP packets for debugging purposes\n\n"
-" sip set debug ip <host[:PORT]>\n"
-" Enables dumping of SIP packets to and from host.\n\n"
-" sip set debug peer <peername>\n"
-" Enables dumping of SIP packets to and from host.\n"
-" Require peer to be registered.\n";
-
-static char no_debug_usage[] =
-"Usage: sip set debug off\n"
-" Disables dumping of SIP packets for debugging purposes\n";
-
-static char no_history_usage[] =
-"Usage: sip history off\n"
-" Disables recording of SIP dialog history for debugging purposes\n";
-
-static char history_usage[] =
-"Usage: sip history\n"
-" Enables recording of SIP dialog history for debugging purposes.\n"
-"Use 'sip show history' to view the history of a call number.\n";
-
-static char sip_reload_usage[] =
-"Usage: sip reload\n"
-" Reloads SIP configuration from sip.conf\n";
-
-static char show_subscriptions_usage[] =
-"Usage: sip show subscriptions\n"
-" Lists active SIP subscriptions for extension states\n";
-
-static char show_objects_usage[] =
-"Usage: sip show objects\n"
-" Lists status of known SIP objects\n";
-
-static char show_settings_usage[] =
-"Usage: sip show settings\n"
-" Provides detailed list of the configuration of the SIP channel.\n";
-
-/*! \brief Read SIP header (dialplan function) */
-static int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
-{
- struct sip_pvt *p;
- const char *content = NULL;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(header);
- AST_APP_ARG(number);
- );
- int i, number, start = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "This function requires a header name.\n");
- return -1;
- }
-
- ast_channel_lock(chan);
- if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
- ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
- ast_channel_unlock(chan);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, data);
- if (!args.number) {
- number = 1;
- } else {
- sscanf(args.number, "%d", &number);
- if (number < 1)
- number = 1;
- }
-
- p = chan->tech_pvt;
-
- /* If there is no private structure, this channel is no longer alive */
- if (!p) {
- ast_channel_unlock(chan);
- return -1;
- }
-
- for (i = 0; i < number; i++)
- content = __get_header(&p->initreq, args.header, &start);
-
- if (ast_strlen_zero(content)) {
- ast_channel_unlock(chan);
- return -1;
- }
-
- ast_copy_string(buf, content, len);
- ast_channel_unlock(chan);
-
- return 0;
-}
-
-static struct ast_custom_function sip_header_function = {
- .name = "SIP_HEADER",
- .synopsis = "Gets the specified SIP header",
- .syntax = "SIP_HEADER(<name>[,<number>])",
- .desc = "Since there are several headers (such as Via) which can occur multiple\n"
- "times, SIP_HEADER takes an optional second argument to specify which header with\n"
- "that name to retrieve. Headers start at offset 1.\n",
- .read = func_header_read,
-};
-
-/*! \brief Dial plan function to check if domain is local */
-static int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
- return -1;
- }
- if (check_sip_domain(data, NULL, 0))
- ast_copy_string(buf, data, len);
- else
- buf[0] = '\0';
- return 0;
-}
-
-static struct ast_custom_function checksipdomain_function = {
- .name = "CHECKSIPDOMAIN",
- .synopsis = "Checks if domain is a local domain",
- .syntax = "CHECKSIPDOMAIN(<domain|IP>)",
- .read = func_check_sipdomain,
- .desc = "This function checks if the domain in the argument is configured\n"
- "as a local SIP domain that this Asterisk server is configured to handle.\n"
- "Returns the domain name if it is locally handled, otherwise an empty string.\n"
- "Check the domain= configuration in sip.conf\n",
-};
-
-/*! \brief ${SIPPEER()} Dialplan function - reads peer data */
-static int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct sip_peer *peer;
- char *colname;
-
- if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */
- *colname++ = '\0';
- else if ((colname = strchr(data, '|')))
- *colname++ = '\0';
- else
- colname = "ip";
-
- if (!(peer = find_peer(data, NULL, 1)))
- return -1;
-
- if (!strcasecmp(colname, "ip")) {
- ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
- } else if (!strcasecmp(colname, "status")) {
- peer_status(peer, buf, len);
- } else if (!strcasecmp(colname, "language")) {
- ast_copy_string(buf, peer->language, len);
- } else if (!strcasecmp(colname, "regexten")) {
- ast_copy_string(buf, peer->regexten, len);
- } else if (!strcasecmp(colname, "limit")) {
- snprintf(buf, len, "%d", peer->call_limit);
- } else if (!strcasecmp(colname, "curcalls")) {
- snprintf(buf, len, "%d", peer->inUse);
- } else if (!strcasecmp(colname, "accountcode")) {
- ast_copy_string(buf, peer->accountcode, len);
- } else if (!strcasecmp(colname, "useragent")) {
- ast_copy_string(buf, peer->useragent, len);
- } else if (!strcasecmp(colname, "mailbox")) {
- ast_copy_string(buf, peer->mailbox, len);
- } else if (!strcasecmp(colname, "context")) {
- ast_copy_string(buf, peer->context, len);
- } else if (!strcasecmp(colname, "expire")) {
- snprintf(buf, len, "%d", peer->expire);
- } else if (!strcasecmp(colname, "dynamic")) {
- ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
- } else if (!strcasecmp(colname, "callerid_name")) {
- ast_copy_string(buf, peer->cid_name, len);
- } else if (!strcasecmp(colname, "callerid_num")) {
- ast_copy_string(buf, peer->cid_num, len);
- } else if (!strcasecmp(colname, "codecs")) {
- ast_getformatname_multiple(buf, len -1, peer->capability);
- } else if (!strncasecmp(colname, "codec[", 6)) {
- char *codecnum;
- int index = 0, codec = 0;
-
- codecnum = colname + 6; /* move past the '[' */
- codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
- index = atoi(codecnum);
- if((codec = ast_codec_pref_index(&peer->prefs, index))) {
- ast_copy_string(buf, ast_getformatname(codec), len);
- }
- }
-
- ASTOBJ_UNREF(peer, sip_destroy_peer);
-
- return 0;
-}
-
-/*! \brief Structure to declare a dialplan function: SIPPEER */
-struct ast_custom_function sippeer_function = {
- .name = "SIPPEER",
- .synopsis = "Gets SIP peer information",
- .syntax = "SIPPEER(<peername>[|item])",
- .read = function_sippeer,
- .desc = "Valid items are:\n"
- "- ip (default) The IP address.\n"
- "- mailbox The configured mailbox.\n"
- "- context The configured context.\n"
- "- expire The epoch time of the next expire.\n"
- "- dynamic Is it dynamic? (yes/no).\n"
- "- callerid_name The configured Caller ID name.\n"
- "- callerid_num The configured Caller ID number.\n"
- "- codecs The configured codecs.\n"
- "- status Status (if qualify=yes).\n"
- "- regexten Registration extension\n"
- "- limit Call limit (call-limit)\n"
- "- curcalls Current amount of calls \n"
- " Only available if call-limit is set\n"
- "- language Default language for peer\n"
- "- accountcode Account code for this peer\n"
- "- useragent Current user agent id for peer\n"
- "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
- "\n"
-};
-
-/*! \brief ${SIPCHANINFO()} Dialplan function - reads sip channel data */
-static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct sip_pvt *p;
-
- *buf = 0;
-
- if (!data) {
- ast_log(LOG_WARNING, "This function requires a parameter name.\n");
- return -1;
- }
-
- ast_channel_lock(chan);
- if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
- ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
- ast_channel_unlock(chan);
- return -1;
- }
-
- p = chan->tech_pvt;
-
- /* If there is no private structure, this channel is no longer alive */
- if (!p) {
- ast_channel_unlock(chan);
- return -1;
- }
-
- if (!strcasecmp(data, "peerip")) {
- ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
- } else if (!strcasecmp(data, "recvip")) {
- ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
- } else if (!strcasecmp(data, "from")) {
- ast_copy_string(buf, p->from, len);
- } else if (!strcasecmp(data, "uri")) {
- ast_copy_string(buf, p->uri, len);
- } else if (!strcasecmp(data, "useragent")) {
- ast_copy_string(buf, p->useragent, len);
- } else if (!strcasecmp(data, "peername")) {
- ast_copy_string(buf, p->peername, len);
- } else if (!strcasecmp(data, "t38passthrough")) {
- if (p->t38.state == T38_DISABLED)
- ast_copy_string(buf, "0", sizeof("0"));
- else /* T38 is offered or enabled in this call */
- ast_copy_string(buf, "1", sizeof("1"));
- } else {
- ast_channel_unlock(chan);
- return -1;
- }
- ast_channel_unlock(chan);
-
- return 0;
-}
-
-/*! \brief Structure to declare a dialplan function: SIPCHANINFO */
-static struct ast_custom_function sipchaninfo_function = {
- .name = "SIPCHANINFO",
- .synopsis = "Gets the specified SIP parameter from the current channel",
- .syntax = "SIPCHANINFO(item)",
- .read = function_sipchaninfo_read,
- .desc = "Valid items are:\n"
- "- peerip The IP address of the peer.\n"
- "- recvip The source IP address of the peer.\n"
- "- from The URI from the From: header.\n"
- "- uri The URI from the Contact: header.\n"
- "- useragent The useragent.\n"
- "- peername The name of the peer.\n"
- "- t38passthrough 1 if T38 is offered or enabled in this channel, otherwise 0\n"
-};
-
-/*! \brief Parse 302 Moved temporalily response */
-static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
-{
- char tmp[SIPBUFSIZE];
- char *s, *e, *uri, *t;
- char *domain;
-
- ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
- if ((t = strchr(tmp, ',')))
- *t = '\0';
- s = get_in_brackets(tmp);
- uri = ast_strdupa(s);
- if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
- if (!strncasecmp(s, "sip:", 4))
- s += 4;
- e = strchr(s, ';');
- if (e)
- *e = '\0';
- if (option_debug)
- ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
- if (p->owner)
- ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
- } else {
- e = strchr(tmp, '@');
- if (e) {
- *e++ = '\0';
- domain = e;
- } else {
- /* No username part */
- domain = tmp;
- }
- e = strchr(s, ';'); /* Strip of parameters in the username part */
- if (e)
- *e = '\0';
- e = strchr(domain, ';'); /* Strip of parameters in the domain part */
- if (e)
- *e = '\0';
-
- if (!strncasecmp(s, "sip:", 4))
- s += 4;
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
- if (p->owner) {
- pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
- pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
- ast_string_field_set(p->owner, call_forward, s);
- }
- }
-}
-
-/*! \brief Check pending actions on SIP call */
-static void check_pendings(struct sip_pvt *p)
-{
- if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- /* if we can't BYE, then this is really a pending CANCEL */
- if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
- transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
- /* Actually don't destroy us yet, wait for the 487 on our original
- INVITE, but do set an autodestruct just in case we never get it. */
- else {
- /* We have a pending outbound invite, don't send someting
- new in-transaction */
- if (p->pendinginvite)
- return;
-
- /* Perhaps there is an SD change INVITE outstanding */
- transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
- }
- ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
- /* if we can't REINVITE, hold it for later */
- if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
- /* Didn't get to reinvite yet, so do it now */
- transmit_reinvite_with_sdp(p);
- ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
- }
- }
-}
-
-/*! \brief Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite
- to avoid race conditions between asterisk servers.
- Called from the scheduler.
-*/
-static int sip_reinvite_retry(const void *data)
-{
- struct sip_pvt *p = (struct sip_pvt *) data;
-
- ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
- p->waitid = -1;
- return 0;
-}
-
-
-/*! \brief Handle SIP response to INVITE dialogue */
-static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
-{
- int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
- int res = 0;
- int xmitres = 0;
- int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
- struct ast_channel *bridgepeer = NULL;
-
- if (option_debug > 3) {
- if (reinvite)
- ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
- else
- ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
- }
-
- if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
- if (option_debug)
- ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
- return;
- }
-
- /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
- /* Don't auto congest anymore since we've gotten something useful back */
- AST_SCHED_DEL(sched, p->initid);
-
- /* RFC3261 says we must treat every 1xx response (but not 100)
- that we don't recognize as if it was 183.
- */
- if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183)
- resp = 183;
-
- /* Any response between 100 and 199 is PROCEEDING */
- if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
- p->invitestate = INV_PROCEEDING;
-
- /* Final response, not 200 ? */
- if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
- p->invitestate = INV_COMPLETED;
-
-
- switch (resp) {
- case 100: /* Trying */
- case 101: /* Dialog establishment */
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- check_pendings(p);
- break;
-
- case 180: /* 180 Ringing */
- case 182: /* 182 Queued */
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
- ast_queue_control(p->owner, AST_CONTROL_RINGING);
- if (p->owner->_state != AST_STATE_UP) {
- ast_setstate(p->owner, AST_STATE_RINGING);
- }
- }
- if (find_sdp(req)) {
- if (p->invitestate != INV_CANCELLED)
- p->invitestate = INV_EARLY_MEDIA;
- res = process_sdp(p, req);
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
- /* Queue a progress frame only if we have SDP in 180 or 182 */
- ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
- }
- }
- check_pendings(p);
- break;
-
- case 183: /* Session progress */
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- /* Ignore 183 Session progress without SDP */
- if (find_sdp(req)) {
- if (p->invitestate != INV_CANCELLED)
- p->invitestate = INV_EARLY_MEDIA;
- res = process_sdp(p, req);
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
- /* Queue a progress frame */
- ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
- }
- }
- check_pendings(p);
- break;
-
- case 200: /* 200 OK on invite - someone's answering our call */
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- p->authtries = 0;
- if (find_sdp(req)) {
- if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
- if (!reinvite)
- /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
- /* For re-invites, we try to recover */
- ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
- }
-
- /* Parse contact header for continued conversation */
- /* When we get 200 OK, we know which device (and IP) to contact for this call */
- /* This is important when we have a SIP proxy between us and the phone */
- if (outgoing) {
- update_call_counter(p, DEC_CALL_RINGING);
- parse_ok_contact(p, req);
- if(set_address_from_contact(p)) {
- /* Bad contact - we don't know how to reach this device */
- /* We need to ACK, but then send a bye */
- /* OEJ: Possible issue that may need a check:
- If we have a proxy route between us and the device,
- should we care about resolving the contact
- or should we just send it?
- */
- if (!ast_test_flag(req, SIP_PKT_IGNORE))
- ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
- }
-
- /* Save Record-Route for any later requests we make on this dialogue */
- if (!reinvite)
- build_route(p, req, 1);
- }
-
- if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
- struct sip_pvt *bridgepvt = NULL;
-
- if (!bridgepeer->tech) {
- ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n");
- break;
- }
- if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
- bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
- if (bridgepvt->udptl) {
- if (p->t38.state == T38_PEER_REINVITE) {
- sip_handle_t38_reinvite(bridgepeer, p, 0);
- ast_rtp_set_rtptimers_onhold(p->rtp);
- if (p->vrtp)
- ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
- } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
- ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
- /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
- /* XXXX Should we really destroy this session here, without any response at all??? */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- } else {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
- ast_mutex_lock(&bridgepvt->lock);
- bridgepvt->t38.state = T38_DISABLED;
- ast_mutex_unlock(&bridgepvt->lock);
- if (option_debug)
- ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
- p->t38.state = T38_DISABLED;
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
- } else {
- /* Other side is not a SIP channel */
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
- p->t38.state = T38_DISABLED;
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
- }
- if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
- /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
- p->t38.state = T38_ENABLED;
- if (option_debug)
- ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
-
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
- if (!reinvite) {
- ast_queue_control(p->owner, AST_CONTROL_ANSWER);
- } else { /* RE-invite */
- ast_queue_frame(p->owner, &ast_null_frame);
- }
- } else {
- /* It's possible we're getting an 200 OK after we've tried to disconnect
- by sending CANCEL */
- /* First send ACK, then send bye */
- if (!ast_test_flag(req, SIP_PKT_IGNORE))
- ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
- }
- /* If I understand this right, the branch is different for a non-200 ACK only */
- p->invitestate = INV_TERMINATED;
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
- check_pendings(p);
- break;
- case 407: /* Proxy authentication */
- case 401: /* Www auth */
- /* First we ACK */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->options)
- p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
-
- /* Then we AUTH */
- ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
- if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
- char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
- char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
- if (p->authtries < MAX_AUTHTRIES)
- p->invitestate = INV_CALLING;
- if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
- ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- sip_alreadygone(p);
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- }
- }
- break;
-
- case 403: /* Forbidden */
- /* First we ACK */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- sip_alreadygone(p);
- break;
-
- case 404: /* Not found */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- sip_alreadygone(p);
- break;
-
- case 408: /* Request timeout */
- case 481: /* Call leg does not exist */
- /* Could be REFER caused INVITE with replaces */
- ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- break;
- case 487: /* Cancelled transaction */
- /* We have sent CANCEL on an outbound INVITE
- This transaction is already scheduled to be killed by sip_hangup().
- */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
- ast_queue_hangup(p->owner);
- append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
- } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
- update_call_counter(p, DEC_CALL_LIMIT);
- append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- sip_alreadygone(p);
- }
- break;
- case 488: /* Not acceptable here */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (reinvite && p->udptl) {
- /* If this is a T.38 call, we should go back to
- audio. If this is an audio call - something went
- terribly wrong since we don't renegotiate codecs,
- only IP/port .
- */
- p->t38.state = T38_DISABLED;
- /* Try to reset RTP timers */
- ast_rtp_set_rtptimers_onhold(p->rtp);
- ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n");
-
- /*! \bug Is there any way we can go back to the audio call on both
- sides here?
- */
- /* While figuring that out, hangup the call */
- if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) {
- /* We tried to send T.38 out in an initial INVITE and the remote side rejected it,
- right now we can't fall back to audio so totally abort.
- */
- p->t38.state = T38_DISABLED;
- /* Try to reset RTP timers */
- ast_rtp_set_rtptimers_onhold(p->rtp);
- ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n");
-
- /* The dialog is now terminated */
- if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- sip_alreadygone(p);
- } else {
- /* We can't set up this call, so give up */
- if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- /* If there's no dialog to end, then mark p as already gone */
- if (!reinvite)
- sip_alreadygone(p);
- }
- break;
- case 491: /* Pending */
- /* we really should have to wait a while, then retransmit
- * We should support the retry-after at some point
- * At this point, we treat this as a congestion if the call is not in UP state
- */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
- if (p->owner->_state != AST_STATE_UP) {
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else {
- /* This is a re-invite that failed.
- * Reset the flag after a while
- */
- int wait = 3 + ast_random() % 5;
- p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait);
- }
- }
- break;
-
- case 501: /* Not implemented */
- xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- break;
- }
- if (xmitres == XMIT_ERROR)
- ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
-}
-
-/* \brief Handle SIP response in REFER transaction
- We've sent a REFER, now handle responses to it
- */
-static void handle_response_refer(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
-{
- char *auth = "Proxy-Authenticate";
- char *auth2 = "Proxy-Authorization";
-
- /* If no refer structure exists, then do nothing */
- if (!p->refer)
- return;
-
- switch (resp) {
- case 202: /* Transfer accepted */
- /* We need to do something here */
- /* The transferee is now sending INVITE to target */
- p->refer->status = REFER_ACCEPTED;
- /* Now wait for next message */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
- /* We should hang along, waiting for NOTIFY's here */
- break;
-
- case 401: /* Not www-authorized on SIP method */
- case 407: /* Proxy auth */
- if (ast_strlen_zero(p->authname)) {
- ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
- ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- if (resp == 401) {
- auth = "WWW-Authenticate";
- auth2 = "Authorization";
- }
- if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
- ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
- p->refer->status = REFER_NOAUTH;
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 481: /* Call leg does not exist */
-
- /* A transfer with Replaces did not work */
- /* OEJ: We should Set flag, cancel the REFER, go back
- to original call - but right now we can't */
- ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
-
- case 500: /* Server error */
- case 501: /* Method not implemented */
- /* Return to the current call onhold */
- /* Status flag needed to be reset */
- ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- p->refer->status = REFER_FAILED;
- break;
- case 603: /* Transfer declined */
- ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
- p->refer->status = REFER_FAILED;
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
- }
-}
-
-/*! \brief Handle responses on REGISTER to services */
-static int handle_response_register(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
-{
- int expires, expires_ms;
- struct sip_registry *r;
- r=p->registry;
-
- switch (resp) {
- case 401: /* Unauthorized */
- if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
- ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 403: /* Forbidden */
- ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
- if (global_regattempts_max)
- p->registry->regattempts = global_regattempts_max+1;
- AST_SCHED_DEL(sched, r->timeout);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
- case 404: /* Not found */
- ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
- if (global_regattempts_max)
- p->registry->regattempts = global_regattempts_max+1;
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- r->call = NULL;
- AST_SCHED_DEL(sched, r->timeout);
- break;
- case 407: /* Proxy auth */
- if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
- ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 408: /* Request timeout */
- if (global_regattempts_max)
- p->registry->regattempts = global_regattempts_max+1;
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- r->call = NULL;
- AST_SCHED_DEL(sched, r->timeout);
- break;
- case 479: /* SER: Not able to process the URI - address is wrong in register*/
- ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
- if (global_regattempts_max)
- p->registry->regattempts = global_regattempts_max+1;
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- r->call = NULL;
- AST_SCHED_DEL(sched, r->timeout);
- break;
- case 200: /* 200 OK */
- if (!r) {
- ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
-
- r->regstate = REG_STATE_REGISTERED;
- r->regtime = time(NULL); /* Reset time of last succesful registration */
- manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
- r->regattempts = 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "Registration successful\n");
- if (r->timeout > -1) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
- }
- AST_SCHED_DEL(sched, r->timeout);
- r->call = NULL;
- p->registry = NULL;
- /* Let this one hang around until we have all the responses */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
-
- /* set us up for re-registering */
- /* figure out how long we got registered for */
- AST_SCHED_DEL(sched, r->expire);
- /* according to section 6.13 of RFC, contact headers override
- expires headers, so check those first */
- expires = 0;
-
- /* XXX todo: try to save the extra call */
- if (!ast_strlen_zero(get_header(req, "Contact"))) {
- const char *contact = NULL;
- const char *tmptmp = NULL;
- int start = 0;
- for(;;) {
- contact = __get_header(req, "Contact", &start);
- /* this loop ensures we get a contact header about our register request */
- if(!ast_strlen_zero(contact)) {
- if( (tmptmp=strstr(contact, p->our_contact))) {
- contact=tmptmp;
- break;
- }
- } else
- break;
- }
- tmptmp = strcasestr(contact, "expires=");
- if (tmptmp) {
- if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
- expires = 0;
- }
-
- }
- if (!expires)
- expires=atoi(get_header(req, "expires"));
- if (!expires)
- expires=default_expiry;
-
- expires_ms = expires * 1000;
- if (expires <= EXPIRY_GUARD_LIMIT)
- expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
- else
- expires_ms -= EXPIRY_GUARD_SECS * 1000;
- if (sipdebug)
- ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000);
-
- r->refresh= (int) expires_ms / 1000;
-
- /* Schedule re-registration before we expire */
- AST_SCHED_DEL(sched, r->expire);
- r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r);
- ASTOBJ_UNREF(r, sip_registry_destroy);
- }
- return 1;
-}
-
-/*! \brief Handle qualification responses (OPTIONS) */
-static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
-{
- struct sip_peer *peer = p->relatedpeer;
- int statechanged, is_reachable, was_reachable;
- int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
-
- /*
- * Compute the response time to a ping (goes in peer->lastms.)
- * -1 means did not respond, 0 means unknown,
- * 1..maxms is a valid response, >maxms means late response.
- */
- if (pingtime < 1) /* zero = unknown, so round up to 1 */
- pingtime = 1;
-
- /* Now determine new state and whether it has changed.
- * Use some helper variables to simplify the writing
- * of the expressions.
- */
- was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
- is_reachable = pingtime <= peer->maxms;
- statechanged = peer->lastms == 0 /* yes, unknown before */
- || was_reachable != is_reachable;
-
- peer->lastms = pingtime;
- peer->call = NULL;
- if (statechanged) {
- const char *s = is_reachable ? "Reachable" : "Lagged";
-
- ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
- peer->name, s, pingtime, peer->maxms);
- ast_device_state_changed("SIP/%s", peer->name);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
- "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
- peer->name, s, pingtime);
- }
-
- if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
-
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
-
- /* Try again eventually */
- peer->pokeexpire = ast_sched_add(sched,
- is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
- sip_poke_peer_s, ASTOBJ_REF(peer));
-
- if (peer->pokeexpire == -1) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- }
-}
-
-/*! \brief Immediately stop RTP, VRTP and UDPTL as applicable */
-static void stop_media_flows(struct sip_pvt *p)
-{
- /* Immediately stop RTP, VRTP and UDPTL as applicable */
- if (p->rtp)
- ast_rtp_stop(p->rtp);
- if (p->vrtp)
- ast_rtp_stop(p->vrtp);
- if (p->udptl)
- ast_udptl_stop(p->udptl);
-}
-
-/*! \brief Handle SIP response in dialogue */
-/* XXX only called by handle_request */
-static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
-{
- struct ast_channel *owner;
- int sipmethod;
- int res = 1;
- const char *c = get_header(req, "Cseq");
- const char *msg = strchr(c, ' ');
-
- if (!msg)
- msg = "";
- else
- msg++;
- sipmethod = find_sip_method(msg);
-
- owner = p->owner;
- if (owner)
- owner->hangupcause = hangup_sip2cause(resp);
-
- /* Acknowledge whatever it is destined for */
- if ((resp >= 100) && (resp <= 199))
- __sip_semi_ack(p, seqno, 0, sipmethod);
- else
- __sip_ack(p, seqno, 0, sipmethod);
-
- /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
- if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
- p->pendinginvite = 0;
-
- /* Get their tag if we haven't already */
- if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
- char tag[128];
-
- gettag(req, "To", tag, sizeof(tag));
- ast_string_field_set(p, theirtag, tag);
- }
- if (p->relatedpeer && p->method == SIP_OPTIONS) {
- /* We don't really care what the response is, just that it replied back.
- Well, as long as it's not a 100 response... since we might
- need to hang around for something more "definitive" */
- if (resp != 100)
- handle_response_peerpoke(p, resp, req);
- } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- switch(resp) {
- case 100: /* 100 Trying */
- case 101: /* 101 Dialog establishment */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- break;
- case 183: /* 183 Session Progress */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- break;
- case 180: /* 180 Ringing */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- break;
- case 182: /* 182 Queued */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- break;
- case 200: /* 200 OK */
- p->authtries = 0; /* Reset authentication counter */
- if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
- /* We successfully transmitted a message
- or a video update request in INFO */
- /* Nothing happens here - the message is inside a dialog */
- } else if (sipmethod == SIP_INVITE) {
- handle_response_invite(p, resp, rest, req, seqno);
- } else if (sipmethod == SIP_NOTIFY) {
- /* They got the notify, this is the end */
- if (p->owner) {
- if (!p->refer) {
- ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
- ast_queue_hangup(p->owner);
- } else if (option_debug > 3)
- ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n");
- } else {
- if (p->subscribed == NONE)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
- /* Ready to send the next state we have on queue */
- ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
- cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
- }
- }
- } else if (sipmethod == SIP_REGISTER)
- res = handle_response_register(p, resp, rest, req, ignore, seqno);
- else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
- case 202: /* Transfer accepted */
- if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- break;
- case 401: /* Not www-authorized on SIP method */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- else if (p->registry && sipmethod == SIP_REGISTER)
- res = handle_response_register(p, resp, rest, req, ignore, seqno);
- else if (sipmethod == SIP_BYE) {
- if (ast_strlen_zero(p->authname)) {
- ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
- msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) {
- ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- /* We fail to auth bye on our own call, but still needs to tear down the call.
- Life, they call it. */
- }
- } else {
- ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 403: /* Forbidden - we failed authentication */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (p->registry && sipmethod == SIP_REGISTER)
- res = handle_response_register(p, resp, rest, req, ignore, seqno);
- else {
- ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 404: /* Not found */
- if (p->registry && sipmethod == SIP_REGISTER)
- res = handle_response_register(p, resp, rest, req, ignore, seqno);
- else if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- break;
- case 407: /* Proxy auth required */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- else if (p->registry && sipmethod == SIP_REGISTER)
- res = handle_response_register(p, resp, rest, req, ignore, seqno);
- else if (sipmethod == SIP_BYE) {
- if (ast_strlen_zero(p->authname)) {
- ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
- msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
- ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- } else /* We can't handle this, giving up in a bad way */
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
-
- break;
- case 408: /* Request timeout - terminate dialog */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_REGISTER)
- res = handle_response_register(p, resp, rest, req, ignore, seqno);
- else if (sipmethod == SIP_BYE) {
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (option_debug)
- ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
- } else {
- if (owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 481: /* Call leg does not exist */
- if (sipmethod == SIP_INVITE) {
- handle_response_invite(p, resp, rest, req, seqno);
- } else if (sipmethod == SIP_REFER) {
- handle_response_refer(p, resp, rest, req, seqno);
- } else if (sipmethod == SIP_BYE) {
- /* The other side has no transaction to bye,
- just assume it's all right then */
- ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
- } else if (sipmethod == SIP_CANCEL) {
- /* The other side has no transaction to cancel,
- just assume it's all right then */
- ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
- } else {
- ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
- /* Guessing that this is not an important request */
- }
- break;
- case 487:
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- break;
- case 488: /* Not acceptable here - codec error */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- break;
- case 491: /* Pending */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- break;
- case 501: /* Not Implemented */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- else
- ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
- break;
- case 603: /* Declined transfer */
- if (sipmethod == SIP_REFER) {
- handle_response_refer(p, resp, rest, req, seqno);
- break;
- }
- /* Fallthrough */
- default:
- if ((resp >= 300) && (resp < 700)) {
- /* Fatal response */
- if ((option_verbose > 2) && (resp != 487))
- ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
-
- if (sipmethod == SIP_INVITE)
- stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
-
- /* XXX Locking issues?? XXX */
- switch(resp) {
- case 300: /* Multiple Choices */
- case 301: /* Moved permenantly */
- case 302: /* Moved temporarily */
- case 305: /* Use Proxy */
- parse_moved_contact(p, req);
- /* Fall through */
- case 486: /* Busy here */
- case 600: /* Busy everywhere */
- case 603: /* Decline */
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_BUSY);
- break;
- case 482: /*
- \note SIP is incapable of performing a hairpin call, which
- is yet another failure of not having a layer 2 (again, YAY
- IETF for thinking ahead). So we treat this as a call
- forward and hope we end up at the right place... */
- if (option_debug)
- ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
- if (p->owner)
- ast_string_field_build(p->owner, call_forward,
- "Local/%s@%s", p->username, p->context);
- /* Fall through */
- case 480: /* Temporarily Unavailable */
- case 404: /* Not Found */
- case 410: /* Gone */
- case 400: /* Bad Request */
- case 500: /* Server error */
- if (sipmethod == SIP_REFER) {
- handle_response_refer(p, resp, rest, req, seqno);
- break;
- }
- /* Fall through */
- case 502: /* Bad gateway */
- case 503: /* Service Unavailable */
- case 504: /* Server Timeout */
- if (owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- break;
- default:
- /* Send hangup */
- if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
- ast_queue_hangup(p->owner);
- break;
- }
- /* ACK on invite */
- if (sipmethod == SIP_INVITE)
- transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
- sip_alreadygone(p);
- if (!p->owner)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else if ((resp >= 100) && (resp < 200)) {
- if (sipmethod == SIP_INVITE) {
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- if (find_sdp(req))
- process_sdp(p, req);
- if (p->owner) {
- /* Queue a progress frame */
- ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
- }
- }
- } else
- ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr));
- }
- } else {
- /* Responses to OUTGOING SIP requests on INCOMING calls
- get handled here. As well as out-of-call message responses */
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
-
- if (sipmethod == SIP_INVITE && resp == 200) {
- /* Tags in early session is replaced by the tag in 200 OK, which is
- the final reply to our INVITE */
- char tag[128];
-
- gettag(req, "To", tag, sizeof(tag));
- ast_string_field_set(p, theirtag, tag);
- }
-
- switch(resp) {
- case 200:
- if (sipmethod == SIP_INVITE) {
- handle_response_invite(p, resp, rest, req, seqno);
- } else if (sipmethod == SIP_CANCEL) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
-
- /* Wait for 487, then destroy */
- } else if (sipmethod == SIP_NOTIFY) {
- /* They got the notify, this is the end */
- if (p->owner) {
- if (p->refer) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n");
- } else
- ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
- /* ast_queue_hangup(p->owner); Disabled */
- } else {
- if (!p->subscribed && !p->refer)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
- /* Ready to send the next state we have on queue */
- ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
- cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
- }
- }
- } else if (sipmethod == SIP_BYE)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
- /* We successfully transmitted a message or
- a video update request in INFO */
- ;
- else if (sipmethod == SIP_BYE)
- /* Ok, we're ready to go */
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
- case 202: /* Transfer accepted */
- if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- break;
- case 401: /* www-auth */
- case 407:
- if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_BYE) {
- char *auth, *auth2;
-
- auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate");
- auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization");
- if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
- ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- }
- break;
- case 481: /* Call leg does not exist */
- if (sipmethod == SIP_INVITE) {
- /* Re-invite failed */
- handle_response_invite(p, resp, rest, req, seqno);
- } else if (sipmethod == SIP_BYE) {
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else if (sipdebug) {
- ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
- }
- break;
- case 501: /* Not Implemented */
- if (sipmethod == SIP_INVITE)
- handle_response_invite(p, resp, rest, req, seqno);
- else if (sipmethod == SIP_REFER)
- handle_response_refer(p, resp, rest, req, seqno);
- break;
- case 603: /* Declined transfer */
- if (sipmethod == SIP_REFER) {
- handle_response_refer(p, resp, rest, req, seqno);
- break;
- }
- /* Fallthrough */
- default: /* Errors without handlers */
- if ((resp >= 100) && (resp < 200)) {
- if (sipmethod == SIP_INVITE) { /* re-invite */
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- }
- }
- if ((resp >= 300) && (resp < 700)) {
- if ((option_verbose > 2) && (resp != 487))
- ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
- switch(resp) {
- case 488: /* Not acceptable here - codec error */
- case 603: /* Decline */
- case 500: /* Server error */
- case 502: /* Bad gateway */
- case 503: /* Service Unavailable */
- case 504: /* Server timeout */
-
- /* re-invite failed */
- if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- break;
- }
- }
- break;
- }
- }
-}
-
-
-/*! \brief Park SIP call support function
- Starts in a new thread, then parks the call
- XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the
- audio can't be heard before hangup
-*/
-static void *sip_park_thread(void *stuff)
-{
- struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
- struct sip_dual *d;
- struct sip_request req;
- int ext;
- int res;
-
- d = stuff;
- transferee = d->chan1;
- transferer = d->chan2;
- copy_request(&req, &d->req);
- free(d);
-
- if (!transferee || !transferer) {
- ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
- return NULL;
- }
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
-
- ast_channel_lock(transferee);
- if (ast_do_masquerade(transferee)) {
- ast_log(LOG_WARNING, "Masquerade failed.\n");
- transmit_response(transferer->tech_pvt, "503 Internal error", &req);
- ast_channel_unlock(transferee);
- return NULL;
- }
- ast_channel_unlock(transferee);
-
- res = ast_park_call(transferee, transferer, 0, &ext);
-
-
-#ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
- if (!res) {
- transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
- } else {
- /* Then tell the transferer what happened */
- sprintf(buf, "Call parked on extension '%d'", ext);
- transmit_message_with_text(transferer->tech_pvt, buf);
- }
-#endif
-
- /* Any way back to the current call??? */
- /* Transmit response to the REFER request */
- transmit_response(transferer->tech_pvt, "202 Accepted", &req);
- if (!res) {
- /* Transfer succeeded */
- append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
- transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
- transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- ast_hangup(transferer); /* This will cause a BYE */
- if (option_debug)
- ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
- } else {
- transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
- append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
- if (option_debug)
- ast_log(LOG_DEBUG, "SIP Call parked failed \n");
- /* Do not hangup call */
- }
- return NULL;
-}
-
-/*! \brief Park a call using the subsystem in res_features.c
- This is executed in a separate thread
-*/
-static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
-{
- struct sip_dual *d;
- struct ast_channel *transferee, *transferer;
- /* Chan2m: The transferer, chan1m: The transferee */
- pthread_t th;
-
- transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
- transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
- if ((!transferer) || (!transferee)) {
- if (transferee) {
- transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- ast_hangup(transferee);
- }
- if (transferer) {
- transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- ast_hangup(transferer);
- }
- return -1;
- }
-
- /* Make formats okay */
- transferee->readformat = chan1->readformat;
- transferee->writeformat = chan1->writeformat;
-
- /* Prepare for taking over the channel */
- ast_channel_masquerade(transferee, chan1);
-
- /* Setup the extensions and such */
- ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
- ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
- transferee->priority = chan1->priority;
-
- /* We make a clone of the peer channel too, so we can play
- back the announcement */
-
- /* Make formats okay */
- transferer->readformat = chan2->readformat;
- transferer->writeformat = chan2->writeformat;
-
- /* Prepare for taking over the channel. Go ahead and grab this channel
- * lock here to avoid a deadlock with callbacks into the channel driver
- * that hold the channel lock and want the pvt lock. */
- while (ast_channel_trylock(chan2)) {
- struct sip_pvt *pvt = chan2->tech_pvt;
- ast_mutex_unlock(&pvt->lock);
- usleep(1);
- ast_mutex_lock(&pvt->lock);
- }
- ast_channel_masquerade(transferer, chan2);
- ast_channel_unlock(chan2);
-
- /* Setup the extensions and such */
- ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
- ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
- transferer->priority = chan2->priority;
-
- ast_channel_lock(transferer);
- if (ast_do_masquerade(transferer)) {
- ast_log(LOG_WARNING, "Masquerade failed :(\n");
- ast_channel_unlock(transferer);
- transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- ast_hangup(transferer);
- return -1;
- }
- ast_channel_unlock(transferer);
- if (!transferer || !transferee) {
- if (!transferer) {
- if (option_debug)
- ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
- }
- if (!transferee) {
- if (option_debug)
- ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
- }
- return -1;
- }
- if ((d = ast_calloc(1, sizeof(*d)))) {
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- /* Save original request for followup */
- copy_request(&d->req, req);
- d->chan1 = transferee; /* Transferee */
- d->chan2 = transferer; /* Transferer */
- d->seqno = seqno;
- if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
- /* Could not start thread */
- free(d); /* We don't need it anymore. If thread is created, d will be free'd
- by sip_park_thread() */
- pthread_attr_destroy(&attr);
- return 0;
- }
- pthread_attr_destroy(&attr);
- }
- return -1;
-}
-
-/*! \brief Turn off generator data
- XXX Does this function belong in the SIP channel?
-*/
-static void ast_quiet_chan(struct ast_channel *chan)
-{
- if (chan && chan->_state == AST_STATE_UP) {
- if (ast_test_flag(chan, AST_FLAG_MOH))
- ast_moh_stop(chan);
- else if (chan->generatordata)
- ast_deactivate_generator(chan);
- }
-}
-
-/*! \brief Attempt transfer of SIP call
- This fix for attended transfers on a local PBX */
-static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target)
-{
- int res = 0;
- struct ast_channel *peera = NULL,
- *peerb = NULL,
- *peerc = NULL,
- *peerd = NULL;
-
-
- /* We will try to connect the transferee with the target and hangup
- all channels to the transferer */
- if (option_debug > 3) {
- ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
- if (transferer->chan1)
- ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
- else
- ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
- if (target->chan1)
- ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
- else
- ast_log(LOG_DEBUG, "-- No target first channel ---\n");
- if (transferer->chan2)
- ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
- else
- ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
- if (target->chan2)
- ast_log(LOG_DEBUG, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)");
- else
- ast_log(LOG_DEBUG, "-- No target second channel ---\n");
- ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
- }
- if (transferer->chan2) { /* We have a bridge on the transferer's channel */
- peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
- peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */
- peerc = transferer->chan2; /* Asterisk to Transferee */
- peerd = target->chan2; /* Asterisk to Target */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
- } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */
- peera = target->chan1; /* Transferer to PBX -> target channel */
- peerb = transferer->chan1; /* Transferer to IVR*/
- peerc = target->chan2; /* Asterisk to Target */
- peerd = transferer->chan2; /* Nothing */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
- }
-
- if (peera && peerb && peerc && (peerb != peerc)) {
- ast_quiet_chan(peera); /* Stop generators */
- ast_quiet_chan(peerb);
- ast_quiet_chan(peerc);
- if (peerd)
- ast_quiet_chan(peerd);
-
- /* Fix CDRs so they're attached to the remaining channel */
- if (peera->cdr && peerb->cdr)
- peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
- else if (peera->cdr)
- peerb->cdr = peera->cdr;
- peera->cdr = NULL;
-
- if (peerb->cdr && peerc->cdr)
- peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
- else if (peerc->cdr)
- peerb->cdr = peerc->cdr;
- peerc->cdr = NULL;
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
- if (ast_channel_masquerade(peerb, peerc)) {
- ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
- res = -1;
- } else
- ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
- return res;
- } else {
- ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
- if (transferer->chan1)
- ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
- if (target->chan1)
- ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
- return -2;
- }
- return 0;
-}
-
-/*! \brief Get tag from packet
- *
- * \return Returns the pointer to the provided tag buffer,
- * or NULL if the tag was not found.
- */
-static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
-{
- const char *thetag;
-
- if (!tagbuf)
- return NULL;
- tagbuf[0] = '\0'; /* reset the buffer */
- thetag = get_header(req, header);
- thetag = strcasestr(thetag, ";tag=");
- if (thetag) {
- thetag += 5;
- ast_copy_string(tagbuf, thetag, tagbufsize);
- return strsep(&tagbuf, ";");
- }
- return NULL;
-}
-
-/*! \brief Handle incoming notifications */
-static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
-{
- /* This is mostly a skeleton for future improvements */
- /* Mostly created to return proper answers on notifications on outbound REFER's */
- int res = 0;
- const char *event = get_header(req, "Event");
- char *eventid = NULL;
- char *sep;
-
- if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */
- *sep++ = '\0';
- eventid = sep;
- }
-
- if (option_debug > 1 && sipdebug)
- ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
-
- if (strcmp(event, "refer")) {
- /* We don't understand this event. */
- /* Here's room to implement incoming voicemail notifications :-) */
- transmit_response(p, "489 Bad event", req);
- res = -1;
- } else {
- /* Save nesting depth for now, since there might be other events we will
- support in the future */
-
- /* Handle REFER notifications */
-
- char buf[1024];
- char *cmd, *code;
- int respcode;
- int success = TRUE;
-
- /* EventID for each transfer... EventID is basically the REFER cseq
-
- We are getting notifications on a call that we transfered
- We should hangup when we are getting a 200 OK in a sipfrag
- Check if we have an owner of this event */
-
- /* Check the content type */
- if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
- /* We need a sipfrag */
- transmit_response(p, "400 Bad request", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return -1;
- }
-
- /* Get the text of the attachment */
- if (get_msg_text(buf, sizeof(buf), req)) {
- ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
- transmit_response(p, "400 Bad request", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return -1;
- }
-
- /*
- From the RFC...
- A minimal, but complete, implementation can respond with a single
- NOTIFY containing either the body:
- SIP/2.0 100 Trying
-
- if the subscription is pending, the body:
- SIP/2.0 200 OK
- if the reference was successful, the body:
- SIP/2.0 503 Service Unavailable
- if the reference failed, or the body:
- SIP/2.0 603 Declined
-
- if the REFER request was accepted before approval to follow the
- reference could be obtained and that approval was subsequently denied
- (see Section 2.4.7).
-
- If there are several REFERs in the same dialog, we need to
- match the ID of the event header...
- */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
- cmd = ast_skip_blanks(buf);
- code = cmd;
- /* We are at SIP/2.0 */
- while(*code && (*code > 32)) { /* Search white space */
- code++;
- }
- *code++ = '\0';
- code = ast_skip_blanks(code);
- sep = code;
- sep++;
- while(*sep && (*sep > 32)) { /* Search white space */
- sep++;
- }
- *sep++ = '\0'; /* Response string */
- respcode = atoi(code);
- switch (respcode) {
- case 100: /* Trying: */
- case 101: /* dialog establishment */
- /* Don't do anything yet */
- break;
- case 183: /* Ringing: */
- /* Don't do anything yet */
- break;
- case 200: /* OK: The new call is up, hangup this call */
- /* Hangup the call that we are replacing */
- break;
- case 301: /* Moved permenantly */
- case 302: /* Moved temporarily */
- /* Do we get the header in the packet in this case? */
- success = FALSE;
- break;
- case 503: /* Service Unavailable: The new call failed */
- /* Cancel transfer, continue the call */
- success = FALSE;
- break;
- case 603: /* Declined: Not accepted */
- /* Cancel transfer, continue the current call */
- success = FALSE;
- break;
- }
- if (!success) {
- ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
- }
-
- /* Confirm that we received this packet */
- transmit_response(p, "200 OK", req);
- };
-
- if (!p->lastinvite)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-
- return res;
-}
-
-/*! \brief Handle incoming OPTIONS request */
-static int handle_request_options(struct sip_pvt *p, struct sip_request *req)
-{
- int res;
-
- res = get_destination(p, req);
- build_contact(p);
-
- /* XXX Should we authenticate OPTIONS? XXX */
-
- if (ast_strlen_zero(p->context))
- ast_string_field_set(p, context, default_context);
-
- if (ast_shutting_down())
- transmit_response_with_allow(p, "503 Unavailable", req, 0);
- else if (res < 0)
- transmit_response_with_allow(p, "404 Not Found", req, 0);
- else
- transmit_response_with_allow(p, "200 OK", req, 0);
-
- /* Destroy if this OPTIONS was the opening request, but not if
- it's in the middle of a normal call flow. */
- if (!p->lastinvite)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-
- return res;
-}
-
-/*! \brief Handle the transfer part of INVITE with a replaces: header,
- meaning a target pickup or an attended transfer */
-static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin)
-{
- struct ast_frame *f;
- int earlyreplace = 0;
- int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */
- struct ast_channel *c = p->owner; /* Our incoming call */
- struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
- struct ast_channel *targetcall; /* The bridge to the take-over target */
-
- /* Check if we're in ring state */
- if (replacecall->_state == AST_STATE_RING)
- earlyreplace = 1;
-
- /* Check if we have a bridge */
- if (!(targetcall = ast_bridged_channel(replacecall))) {
- /* We have no bridge */
- if (!earlyreplace) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
- oneleggedreplace = 1;
- }
- }
- if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
- ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
-
- if (option_debug > 3) {
- if (targetcall)
- ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name);
- else
- ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name);
- }
-
- if (ignore) {
- ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
- /* We should answer something here. If we are here, the
- call we are replacing exists, so an accepted
- can't harm */
- transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
- /* Do something more clever here */
- ast_channel_unlock(c);
- ast_mutex_unlock(&p->refer->refer_call->lock);
- return 1;
- }
- if (!c) {
- /* What to do if no channel ??? */
- ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n");
- transmit_response_reliable(p, "503 Service Unavailable", req);
- append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- ast_mutex_unlock(&p->refer->refer_call->lock);
- return 1;
- }
- append_history(p, "Xfer", "INVITE/Replace received");
- /* We have three channels to play with
- channel c: New incoming call
- targetcall: Call from PBX to target
- p->refer->refer_call: SIP pvt dialog from transferer to pbx.
- replacecall: The owner of the previous
- We need to masq C into refer_call to connect to
- targetcall;
- If we are talking to internal audio stream, target call is null.
- */
-
- /* Fake call progress */
- transmit_response(p, "100 Trying", req);
- ast_setstate(c, AST_STATE_RING);
-
- /* Masquerade the new call into the referred call to connect to target call
- Targetcall is not touched by the masq */
-
- /* Answer the incoming call and set channel to UP state */
- transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
-
- ast_setstate(c, AST_STATE_UP);
-
- /* Stop music on hold and other generators */
- ast_quiet_chan(replacecall);
- ast_quiet_chan(targetcall);
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
- /* Unlock clone, but not original (replacecall) */
- if (!oneleggedreplace)
- ast_channel_unlock(c);
-
- /* Unlock PVT */
- ast_mutex_unlock(&p->refer->refer_call->lock);
-
- /* Make sure that the masq does not free our PVT for the old call */
- if (! earlyreplace && ! oneleggedreplace )
- ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */
-
- /* Prepare the masquerade - if this does not happen, we will be gone */
- if(ast_channel_masquerade(replacecall, c))
- ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
- else if (option_debug > 3)
- ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
-
- /* The masquerade will happen as soon as someone reads a frame from the channel */
-
- /* C should now be in place of replacecall */
- /* ast_read needs to lock channel */
- ast_channel_unlock(c);
-
- if (earlyreplace || oneleggedreplace ) {
- /* Force the masq to happen */
- if ((f = ast_read(replacecall))) { /* Force the masq to happen */
- ast_frfree(f);
- f = NULL;
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n");
- } else {
- ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n");
- }
- c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- if (!oneleggedreplace)
- ast_channel_unlock(replacecall);
- } else { /* Bridged call, UP channel */
- if ((f = ast_read(replacecall))) { /* Force the masq to happen */
- /* Masq ok */
- ast_frfree(f);
- f = NULL;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n");
- } else {
- ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n");
- }
- ast_channel_unlock(replacecall);
- }
- ast_mutex_unlock(&p->refer->refer_call->lock);
-
- ast_setstate(c, AST_STATE_DOWN);
- if (option_debug > 3) {
- struct ast_channel *test;
- ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
- ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state));
- if (replacecall)
- ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
- if (p->owner) {
- ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
- test = ast_bridged_channel(p->owner);
- if (test)
- ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
- else
- ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
- } else
- ast_log(LOG_DEBUG, " -- No channel yet \n");
- ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
- }
-
- ast_channel_unlock(p->owner); /* Unlock new owner */
- if (!oneleggedreplace)
- ast_mutex_unlock(&p->lock); /* Unlock SIP structure */
-
- /* The call should be down with no ast_channel, so hang it up */
- c->tech_pvt = NULL;
- ast_hangup(c);
- return 0;
-}
-
-
-/*! \brief Handle incoming INVITE request
-\note If the INVITE has a Replaces header, it is part of an
- * attended transfer. If so, we do not go through the dial
- * plan but tries to find the active call and masquerade
- * into it
- */
-static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock)
-{
- int res = 1;
- int gotdest;
- const char *p_replaces;
- char *replace_id = NULL;
- const char *required;
- unsigned int required_profile = 0;
- struct ast_channel *c = NULL; /* New channel */
- int reinvite = 0;
-
- /* Find out what they support */
- if (!p->sipoptions) {
- const char *supported = get_header(req, "Supported");
- if (!ast_strlen_zero(supported))
- parse_sip_options(p, supported);
- }
-
- /* Find out what they require */
- required = get_header(req, "Require");
- if (!ast_strlen_zero(required)) {
- required_profile = parse_sip_options(NULL, required);
- if (required_profile && required_profile != SIP_OPT_REPLACES) {
- /* At this point we only support REPLACES */
- transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
- ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
- p->invitestate = INV_COMPLETED;
- if (!p->lastinvite)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return -1;
- }
- }
-
- /* Check if this is a loop */
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) {
- /* This is a call to ourself. Send ourselves an error code and stop
- processing immediately, as SIP really has no good mechanism for
- being able to call yourself */
- /* If pedantic is on, we need to check the tags. If they're different, this is
- in fact a forked call through a SIP proxy somewhere. */
- transmit_response(p, "482 Loop Detected", req);
- p->invitestate = INV_COMPLETED;
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return 0;
- }
-
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
- /* We already have a pending invite. Sorry. You are on hold. */
- transmit_response(p, "491 Request Pending", req);
- if (option_debug)
- ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
- /* Don't destroy dialog here */
- return 0;
- }
-
- p_replaces = get_header(req, "Replaces");
- if (!ast_strlen_zero(p_replaces)) {
- /* We have a replaces header */
- char *ptr;
- char *fromtag = NULL;
- char *totag = NULL;
- char *start, *to;
- int error = 0;
-
- if (p->owner) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
- transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */
- /* Do not destroy existing call */
- return -1;
- }
-
- if (sipdebug && option_debug > 2)
- ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
- /* Create a buffer we can manipulate */
- replace_id = ast_strdupa(p_replaces);
- ast_uri_decode(replace_id);
-
- if (!p->refer && !sip_refer_allocate(p)) {
- transmit_response(p, "500 Server Internal Error", req);
- append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- p->invitestate = INV_COMPLETED;
- return -1;
- }
-
- /* Todo: (When we find phones that support this)
- if the replaces header contains ";early-only"
- we can only replace the call in early
- stage, not after it's up.
-
- If it's not in early mode, 486 Busy.
- */
-
- /* Skip leading whitespace */
- replace_id = ast_skip_blanks(replace_id);
-
- start = replace_id;
- while ( (ptr = strsep(&start, ";")) ) {
- ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
- if ( (to = strcasestr(ptr, "to-tag=") ) )
- totag = to + 7; /* skip the keyword */
- else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
- fromtag = to + 9; /* skip the keyword */
- fromtag = strsep(&fromtag, "&"); /* trim what ? */
- }
- }
-
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG,"Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", replace_id, fromtag ? fromtag : "<no from tag>", totag ? totag : "<no to tag>");
-
-
- /* Try to find call that we are replacing
- If we have a Replaces header, we need to cancel that call if we succeed with this call
- */
- if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
- ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
- transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req);
- error = 1;
- }
-
- /* At this point, bot the pvt and the owner of the call to be replaced is locked */
-
- /* The matched call is the call from the transferer to Asterisk .
- We want to bridge the bridged part of the call to the
- incoming invite, thus taking over the refered call */
-
- if (p->refer->refer_call == p) {
- ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
- p->refer->refer_call = NULL;
- transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */
- error = 1;
- }
-
- if (!error && !p->refer->refer_call->owner) {
- /* Oops, someting wrong anyway, no owner, no call */
- ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
- /* Check for better return code */
- transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req);
- error = 1;
- }
-
- if (!error && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) {
- ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
- transmit_response(p, "603 Declined (Replaces)", req);
- error = 1;
- }
-
- if (error) { /* Give up this dialog */
- append_history(p, "Xfer", "INVITE/Replace Failed.");
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- ast_mutex_unlock(&p->lock);
- if (p->refer->refer_call) {
- ast_mutex_unlock(&p->refer->refer_call->lock);
- ast_channel_unlock(p->refer->refer_call->owner);
- }
- p->invitestate = INV_COMPLETED;
- return -1;
- }
- }
-
-
- /* Check if this is an INVITE that sets up a new dialog or
- a re-invite in an existing dialog */
-
- if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
- int newcall = (p->initreq.headers ? TRUE : FALSE);
-
- if (sip_cancel_destroy(p))
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- /* This also counts as a pending invite */
- p->pendinginvite = seqno;
- check_via(p, req);
-
- copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */
- if (!p->owner) { /* Not a re-invite */
- if (debug)
- ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
- if (newcall)
- append_history(p, "Invite", "New call: %s", p->callid);
- parse_ok_contact(p, req);
- } else { /* Re-invite on existing call */
- ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */
- /* Handle SDP here if we already have an owner */
- if (find_sdp(req)) {
- if (process_sdp(p, req)) {
- transmit_response(p, "488 Not acceptable here", req);
- if (!p->lastinvite)
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return -1;
- }
- } else {
- p->jointcapability = p->capability;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n");
- /* Some devices signal they want to be put off hold by sending a re-invite
- *without* an SDP, which is supposed to mean "Go back to your state"
- and since they put os on remote hold, we go back to off hold */
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
- change_hold_state(p, req, FALSE, 0);
- }
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
- append_history(p, "ReInv", "Re-invite received");
- }
- } else if (debug)
- ast_verbose("Ignoring this INVITE request\n");
-
-
- if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
- /* This is a new invite */
- /* Handle authentication if this is our first invite */
- res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
- if (res == AUTH_CHALLENGE_SENT) {
- p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */
- return 0;
- }
- if (res < 0) { /* Something failed in authentication */
- if (res == AUTH_FAKE_AUTH) {
- ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
- transmit_fake_auth_response(p, req, 1);
- } else {
- ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
- transmit_response_reliable(p, "403 Forbidden", req);
- }
- p->invitestate = INV_COMPLETED;
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- ast_string_field_free(p, theirtag);
- return 0;
- }
-
- /* We have a succesful authentication, process the SDP portion if there is one */
- if (find_sdp(req)) {
- if (process_sdp(p, req)) {
- /* Unacceptable codecs */
- transmit_response_reliable(p, "488 Not acceptable here", req);
- p->invitestate = INV_COMPLETED;
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- if (option_debug)
- ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
- return -1;
- }
- } else { /* No SDP in invite, call control session */
- p->jointcapability = p->capability;
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
- }
-
- /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
- /* This seems redundant ... see !p-owner above */
- if (p->owner)
- ast_queue_frame(p->owner, &ast_null_frame);
-
-
- /* Initialize the context if it hasn't been already */
- if (ast_strlen_zero(p->context))
- ast_string_field_set(p, context, default_context);
-
-
- /* Check number of concurrent calls -vs- incoming limit HERE */
- if (option_debug)
- ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
- if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
- if (res < 0) {
- ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
- transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- p->invitestate = INV_COMPLETED;
- }
- return 0;
- }
- gotdest = get_destination(p, NULL); /* Get destination right away */
- get_rdnis(p, NULL); /* Get redirect information */
- extract_uri(p, req); /* Get the Contact URI */
- build_contact(p); /* Build our contact header */
-
- if (p->rtp) {
- ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
- ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
- }
-
- if (!replace_id && gotdest) { /* No matching extension found */
- if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
- transmit_response_reliable(p, "484 Address Incomplete", req);
- else {
- transmit_response_reliable(p, "404 Not Found", req);
- ast_log(LOG_NOTICE, "Call from '%s' to extension"
- " '%s' rejected because extension not found.\n",
- S_OR(p->username, p->peername), p->exten);
- }
- p->invitestate = INV_COMPLETED;
- update_call_counter(p, DEC_CALL_LIMIT);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return 0;
- } else {
- /* If no extension was specified, use the s one */
- /* Basically for calling to IP/Host name only */
- if (ast_strlen_zero(p->exten))
- ast_string_field_set(p, exten, "s");
- /* Initialize our tag */
-
- make_our_tag(p->tag, sizeof(p->tag));
- /* First invitation - create the channel */
- c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL));
- *recount = 1;
-
- /* Save Record-Route for any later requests we make on this dialogue */
- build_route(p, req, 0);
-
- if (c) {
- /* Pre-lock the call */
- ast_channel_lock(c);
- }
- }
- } else {
- if (option_debug > 1 && sipdebug) {
- if (!ast_test_flag(req, SIP_PKT_IGNORE))
- ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
- else
- ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
- }
- reinvite = 1;
- c = p->owner;
- }
-
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
- p->lastinvite = seqno;
-
- if (replace_id) { /* Attended transfer or call pickup - we're the target */
- /* Go and take over the target call */
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
- return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
- }
-
-
- if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */
- switch(c->_state) {
- case AST_STATE_DOWN:
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
- transmit_response(p, "100 Trying", req);
- p->invitestate = INV_PROCEEDING;
- ast_setstate(c, AST_STATE_RING);
- if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
- enum ast_pbx_result res;
-
- res = ast_pbx_start(c);
-
- switch(res) {
- case AST_PBX_FAILED:
- ast_log(LOG_WARNING, "Failed to start PBX :(\n");
- p->invitestate = INV_COMPLETED;
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, "503 Unavailable", req);
- else
- transmit_response_reliable(p, "503 Unavailable", req);
- break;
- case AST_PBX_CALL_LIMIT:
- ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
- p->invitestate = INV_COMPLETED;
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, "480 Temporarily Unavailable", req);
- else
- transmit_response_reliable(p, "480 Temporarily Unavailable", req);
- break;
- case AST_PBX_SUCCESS:
- /* nothing to do */
- break;
- }
-
- if (res) {
-
- /* Unlock locks so ast_hangup can do its magic */
- ast_mutex_unlock(&c->lock);
- ast_mutex_unlock(&p->lock);
- ast_hangup(c);
- ast_mutex_lock(&p->lock);
- c = NULL;
- }
- } else { /* Pickup call in call group */
- ast_channel_unlock(c);
- *nounlock = 1;
- if (ast_pickup_call(c)) {
- ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */
- else
- transmit_response_reliable(p, "503 Unavailable", req);
- sip_alreadygone(p);
- /* Unlock locks so ast_hangup can do its magic */
- ast_mutex_unlock(&p->lock);
- c->hangupcause = AST_CAUSE_CALL_REJECTED;
- } else {
- ast_mutex_unlock(&p->lock);
- ast_setstate(c, AST_STATE_DOWN);
- c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- }
- p->invitestate = INV_COMPLETED;
- ast_hangup(c);
- ast_mutex_lock(&p->lock);
- c = NULL;
- }
- break;
- case AST_STATE_RING:
- transmit_response(p, "100 Trying", req);
- p->invitestate = INV_PROCEEDING;
- break;
- case AST_STATE_RINGING:
- transmit_response(p, "180 Ringing", req);
- p->invitestate = INV_PROCEEDING;
- break;
- case AST_STATE_UP:
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
-
- transmit_response(p, "100 Trying", req);
-
- if (p->t38.state == T38_PEER_REINVITE) {
- struct ast_channel *bridgepeer = NULL;
- struct sip_pvt *bridgepvt = NULL;
-
- if ((bridgepeer = ast_bridged_channel(p->owner))) {
- /* We have a bridge, and this is re-invite to switchover to T38 so we send re-invite with T38 SDP, to other side of bridge*/
- /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
- if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
- bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
- if (bridgepvt->t38.state == T38_DISABLED) {
- if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
- /* Send re-invite to the bridged channel */
- sip_handle_t38_reinvite(bridgepeer, p, 1);
- } else { /* Something is wrong with peers udptl struct */
- ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
- ast_mutex_lock(&bridgepvt->lock);
- bridgepvt->t38.state = T38_DISABLED;
- ast_mutex_unlock(&bridgepvt->lock);
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, "488 Not acceptable here", req);
- else
- transmit_response_reliable(p, "488 Not acceptable here", req);
-
- }
- } else {
- /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
- transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
- p->t38.state = T38_ENABLED;
- if (option_debug)
- ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
- } else {
- /* Other side is not a SIP channel */
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, "488 Not acceptable here", req);
- else
- transmit_response_reliable(p, "488 Not acceptable here", req);
- p->t38.state = T38_DISABLED;
- if (option_debug > 1)
- ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
-
- if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- } else {
- /* we are not bridged in a call */
- transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
- p->t38.state = T38_ENABLED;
- if (option_debug)
- ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
- }
- } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
- int sendok = TRUE;
-
- /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
- /* so handle it here (re-invite other party to RTP) */
- struct ast_channel *bridgepeer = NULL;
- struct sip_pvt *bridgepvt = NULL;
- if ((bridgepeer = ast_bridged_channel(p->owner))) {
- if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) {
- bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
- /* Does the bridged peer have T38 ? */
- if (bridgepvt->t38.state == T38_ENABLED) {
- ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
- /* Insted of this we should somehow re-invite the other side of the bridge to RTP */
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
- else
- transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req);
- sendok = FALSE;
- }
- /* No bridged peer with T38 enabled*/
- }
- }
- /* Respond to normal re-invite */
- if (sendok)
- /* If this is not a re-invite or something to ignore - it's critical */
- transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL)));
- }
- p->invitestate = INV_TERMINATED;
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
- transmit_response(p, "100 Trying", req);
- break;
- }
- } else {
- if (p && (p->autokillid == -1)) {
- const char *msg;
-
- if (!p->jointcapability)
- msg = "488 Not Acceptable Here (codec error)";
- else {
- ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
- msg = "503 Unavailable";
- }
- if (ast_test_flag(req, SIP_PKT_IGNORE))
- transmit_response(p, msg, req);
- else
- transmit_response_reliable(p, msg, req);
- p->invitestate = INV_COMPLETED;
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- }
- return res;
-}
-
-/*! \brief Find all call legs and bridge transferee with target
- * called from handle_request_refer */
-static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno)
-{
- struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */
- /* Chan 2: Call from Asterisk to target */
- int res = 0;
- struct sip_pvt *targetcall_pvt;
-
- /* Check if the call ID of the replaces header does exist locally */
- if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
- transferer->refer->replaces_callid_fromtag))) {
- if (transferer->refer->localtransfer) {
- /* We did not find the refered call. Sorry, can't accept then */
- transmit_response(transferer, "202 Accepted", req);
- /* Let's fake a response from someone else in order
- to follow the standard */
- transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
- append_history(transferer, "Xfer", "Refer failed");
- ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
- transferer->refer->status = REFER_FAILED;
- return -1;
- }
- /* Fall through for remote transfers that we did not find locally */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
- return 0;
- }
-
- /* Ok, we can accept this transfer */
- transmit_response(transferer, "202 Accepted", req);
- append_history(transferer, "Xfer", "Refer accepted");
- if (!targetcall_pvt->owner) { /* No active channel */
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
- /* Cancel transfer */
- transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
- append_history(transferer, "Xfer", "Refer failed");
- ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
- transferer->refer->status = REFER_FAILED;
- ast_mutex_unlock(&targetcall_pvt->lock);
- ast_channel_unlock(current->chan1);
- return -1;
- }
-
- /* We have a channel, find the bridge */
- target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */
- target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */
-
- if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
- /* Wrong state of new channel */
- if (option_debug > 3) {
- if (target.chan2)
- ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
- else if (target.chan1->_state != AST_STATE_RING)
- ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
- else
- ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
- }
- }
-
- /* Transfer */
- if (option_debug > 3 && sipdebug) {
- if (current->chan2) /* We have two bridges */
- ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
- else /* One bridge, propably transfer of IVR/voicemail etc */
- ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
- }
-
- ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */
-
- /* Perform the transfer */
- res = attempt_transfer(current, &target);
- ast_mutex_unlock(&targetcall_pvt->lock);
- if (res) {
- /* Failed transfer */
- transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
- append_history(transferer, "Xfer", "Refer failed");
- transferer->refer->status = REFER_FAILED;
- if (targetcall_pvt->owner)
- ast_channel_unlock(targetcall_pvt->owner);
- /* Right now, we have to hangup, sorry. Bridge is destroyed */
- if (res != -2)
- ast_hangup(transferer->owner);
- else
- ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
- } else {
- /* Transfer succeeded! */
-
- /* Tell transferer that we're done. */
- transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
- append_history(transferer, "Xfer", "Refer succeeded");
- transferer->refer->status = REFER_200OK;
- if (targetcall_pvt->owner) {
- if (option_debug)
- ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
- ast_channel_unlock(targetcall_pvt->owner);
- }
- }
- return 1;
-}
-
-
-/*! \brief Handle incoming REFER request */
-/*! \page SIP_REFER SIP transfer Support (REFER)
-
- REFER is used for call transfer in SIP. We get a REFER
- to place a new call with an INVITE somwhere and then
- keep the transferor up-to-date of the transfer. If the
- transfer fails, get back on line with the orginal call.
-
- - REFER can be sent outside or inside of a dialog.
- Asterisk only accepts REFER inside of a dialog.
-
- - If we get a replaces header, it is an attended transfer
-
- \par Blind transfers
- The transferor provides the transferee
- with the transfer targets contact. The signalling between
- transferer or transferee should not be cancelled, so the
- call is recoverable if the transfer target can not be reached
- by the transferee.
-
- In this case, Asterisk receives a TRANSFER from
- the transferor, thus is the transferee. We should
- try to set up a call to the contact provided
- and if that fails, re-connect the current session.
- If the new call is set up, we issue a hangup.
- In this scenario, we are following section 5.2
- in the SIP CC Transfer draft. (Transfer without
- a GRUU)
-
- \par Transfer with consultation hold
- In this case, the transferor
- talks to the transfer target before the transfer takes place.
- This is implemented with SIP hold and transfer.
- Note: The invite From: string could indicate a transfer.
- (Section 6. Transfer with consultation hold)
- The transferor places the transferee on hold, starts a call
- with the transfer target to alert them to the impending
- transfer, terminates the connection with the target, then
- proceeds with the transfer (as in Blind transfer above)
-
- \par Attended transfer
- The transferor places the transferee
- on hold, calls the transfer target to alert them,
- places the target on hold, then proceeds with the transfer
- using a Replaces header field in the Refer-to header. This
- will force the transfee to send an Invite to the target,
- with a replaces header that instructs the target to
- hangup the call between the transferor and the target.
- In this case, the Refer/to: uses the AOR address. (The same
- URI that the transferee used to establish the session with
- the transfer target (To: ). The Require: replaces header should
- be in the INVITE to avoid the wrong UA in a forked SIP proxy
- scenario to answer and have no call to replace with.
-
- The referred-by header is *NOT* required, but if we get it,
- can be copied into the INVITE to the transfer target to
- inform the target about the transferor
-
- "Any REFER request has to be appropriately authenticated.".
-
- We can't destroy dialogs, since we want the call to continue.
-
- */
-static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
-{
- struct sip_dual current; /* Chan1: Call between asterisk and transferer */
- /* Chan2: Call between asterisk and transferee */
-
- int res = 0;
-
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
-
- if (!p->owner) {
- /* This is a REFER outside of an existing SIP dialog */
- /* We can't handle that, so decline it */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
- transmit_response(p, "603 Declined (No dialog)", req);
- if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
- append_history(p, "Xfer", "Refer failed. Outside of dialog.");
- sip_alreadygone(p);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- return 0;
- }
-
-
- /* Check if transfer is allowed from this device */
- if (p->allowtransfer == TRANSFER_CLOSED ) {
- /* Transfer not allowed, decline */
- transmit_response(p, "603 Declined (policy)", req);
- append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
- /* Do not destroy SIP session */
- return 0;
- }
-
- if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
- /* Already have a pending REFER */
- transmit_response(p, "491 Request pending", req);
- append_history(p, "Xfer", "Refer failed. Request pending.");
- return 0;
- }
-
- /* Allocate memory for call transfer data */
- if (!p->refer && !sip_refer_allocate(p)) {
- transmit_response(p, "500 Internal Server Error", req);
- append_history(p, "Xfer", "Refer failed. Memory allocation error.");
- return -3;
- }
-
- res = get_refer_info(p, req); /* Extract headers */
-
- p->refer->status = REFER_SENT;
-
- if (res != 0) {
- switch (res) {
- case -2: /* Syntax error */
- transmit_response(p, "400 Bad Request (Refer-to missing)", req);
- append_history(p, "Xfer", "Refer failed. Refer-to missing.");
- if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
- ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
- break;
- case -3:
- transmit_response(p, "603 Declined (Non sip: uri)", req);
- append_history(p, "Xfer", "Refer failed. Non SIP uri");
- if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
- ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
- break;
- default:
- /* Refer-to extension not found, fake a failed transfer */
- transmit_response(p, "202 Accepted", req);
- append_history(p, "Xfer", "Refer failed. Bad extension.");
- transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
- ast_clear_flag(&p->flags[0], SIP_GOTREFER);
- if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
- ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
- break;
- }
- return 0;
- }
- if (ast_strlen_zero(p->context))
- ast_string_field_set(p, context, default_context);
-
- /* If we do not support SIP domains, all transfers are local */
- if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
- p->refer->localtransfer = 1;
- if (sipdebug && option_debug > 2)
- ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
- } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
- /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
- p->refer->localtransfer = 1;
- } else if (sipdebug && option_debug > 2)
- ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
-
- /* Is this a repeat of a current request? Ignore it */
- /* Don't know what else to do right now. */
- if (ignore)
- return res;
-
- /* If this is a blind transfer, we have the following
- channels to work with:
- - chan1, chan2: The current call between transferer and transferee (2 channels)
- - target_channel: A new call from the transferee to the target (1 channel)
- We need to stay tuned to what happens in order to be able
- to bring back the call to the transferer */
-
- /* If this is a attended transfer, we should have all call legs within reach:
- - chan1, chan2: The call between the transferer and transferee (2 channels)
- - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
- We want to bridge chan2 with targetcall_pvt!
-
- The replaces call id in the refer message points
- to the call leg between Asterisk and the transferer.
- So we need to connect the target and the transferee channel
- and hangup the two other channels silently
-
- If the target is non-local, the call ID could be on a remote
- machine and we need to send an INVITE with replaces to the
- target. We basically handle this as a blind transfer
- and let the sip_call function catch that we need replaces
- header in the INVITE.
- */
-
-
- /* Get the transferer's channel */
- current.chan1 = p->owner;
-
- /* Find the other part of the bridge (2) - transferee */
- current.chan2 = ast_bridged_channel(current.chan1);
-
- if (sipdebug && option_debug > 2)
- ast_log(LOG_DEBUG, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>");
-
- if (!current.chan2 && !p->refer->attendedtransfer) {
- /* No bridged channel, propably IVR or echo or similar... */
- /* Guess we should masquerade or something here */
- /* Until we figure it out, refuse transfer of such calls */
- if (sipdebug && option_debug > 2)
- ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
- p->refer->status = REFER_FAILED;
- append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
- transmit_response(p, "603 Declined", req);
- return -1;
- }
-
- if (current.chan2) {
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
-
- ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
- }
-
- ast_set_flag(&p->flags[0], SIP_GOTREFER);
-
- /* Attended transfer: Find all call legs and bridge transferee with target*/
- if (p->refer->attendedtransfer) {
- if ((res = local_attended_transfer(p, &current, req, seqno)))
- return res; /* We're done with the transfer */
- /* Fall through for remote transfers that we did not find locally */
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
- /* Fallthrough if we can't find the call leg internally */
- }
-
-
- /* Parking a call */
- if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
- /* Must release c's lock now, because it will not longer be accessible after the transfer! */
- *nounlock = 1;
- ast_channel_unlock(current.chan1);
- copy_request(&current.req, req);
- ast_clear_flag(&p->flags[0], SIP_GOTREFER);
- p->refer->status = REFER_200OK;
- append_history(p, "Xfer", "REFER to call parking.");
- if (sipdebug && option_debug > 3)
- ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
- sip_park(current.chan2, current.chan1, req, seqno);
- return res;
- }
-
- /* Blind transfers and remote attended xfers */
- transmit_response(p, "202 Accepted", req);
-
- if (current.chan1 && current.chan2) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
- pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
- }
- if (current.chan2) {
- pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
- pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
- pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
- /* One for the new channel */
- pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
- /* Attended transfer to remote host, prepare headers for the INVITE */
- if (p->refer->referred_by)
- pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
- }
- /* Generate a Replaces string to be used in the INVITE during attended transfer */
- if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
- char tempheader[SIPBUFSIZE];
- snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid,
- p->refer->replaces_callid_totag ? ";to-tag=" : "",
- p->refer->replaces_callid_totag,
- p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
- p->refer->replaces_callid_fromtag);
- if (current.chan2)
- pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
- }
- /* Must release lock now, because it will not longer
- be accessible after the transfer! */
- *nounlock = 1;
- ast_channel_unlock(current.chan1);
-
- /* Connect the call */
-
- /* FAKE ringing if not attended transfer */
- if (!p->refer->attendedtransfer)
- transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE);
-
- /* For blind transfer, this will lead to a new call */
- /* For attended transfer to remote host, this will lead to
- a new SIP call with a replaces header, if the dial plan allows it
- */
- if (!current.chan2) {
- /* We have no bridge, so we're talking with Asterisk somehow */
- /* We need to masquerade this call */
- /* What to do to fix this situation:
- * Set up the new call in a new channel
- * Let the new channel masq into this channel
- Please add that code here :-)
- */
- p->refer->status = REFER_FAILED;
- transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
- ast_clear_flag(&p->flags[0], SIP_GOTREFER);
- append_history(p, "Xfer", "Refer failed (only bridged calls).");
- return -1;
- }
- ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */
-
- /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
- servers - generate an INVITE with Replaces. Either way, let the dial plan decided */
- res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
-
- if (!res) {
- /* Success - we have a new channel */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
- transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
- if (p->refer->localtransfer)
- p->refer->status = REFER_200OK;
- if (p->owner)
- p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- append_history(p, "Xfer", "Refer succeeded.");
- ast_clear_flag(&p->flags[0], SIP_GOTREFER);
- /* Do not hangup call, the other side do that when we say 200 OK */
- /* We could possibly implement a timer here, auto congestion */
- res = 0;
- } else {
- ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
- append_history(p, "Xfer", "Refer failed.");
- /* Failure of some kind */
- p->refer->status = REFER_FAILED;
- transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
- ast_clear_flag(&p->flags[0], SIP_GOTREFER);
- res = -1;
- }
- return res;
-}
-
-/*! \brief Handle incoming CANCEL request */
-static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req)
-{
-
- check_via(p, req);
- sip_alreadygone(p);
-
- /* At this point, we could have cancelled the invite at the same time
- as the other side sends a CANCEL. Our final reply with error code
- might not have been received by the other side before the CANCEL
- was sent, so let's just give up retransmissions and waiting for
- ACK on our error code. The call is hanging up any way. */
- if (p->invitestate == INV_TERMINATED)
- __sip_pretend_ack(p);
- else
- p->invitestate = INV_CANCELLED;
-
- if (p->owner && p->owner->_state == AST_STATE_UP) {
- /* This call is up, cancel is ignored, we need a bye */
- transmit_response(p, "200 OK", req);
- if (option_debug)
- ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
- return 0;
- }
-
- if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
- update_call_counter(p, DEC_CALL_LIMIT);
-
- stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
- if (p->owner)
- ast_queue_hangup(p->owner);
- else
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- if (p->initreq.len > 0) {
- transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
- transmit_response(p, "200 OK", req);
- return 1;
- } else {
- transmit_response(p, "481 Call Leg Does Not Exist", req);
- return 0;
- }
-}
-
-static int acf_channel_read(struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen)
-{
- struct ast_rtp_quality qos;
- struct sip_pvt *p = chan->tech_pvt;
- char *all = "", *parse = ast_strdupa(preparse);
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(param);
- AST_APP_ARG(type);
- AST_APP_ARG(field);
- );
- AST_STANDARD_APP_ARGS(args, parse);
-
- /* Sanity check */
- if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
- ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
- return 0;
- }
-
- if (strcasecmp(args.param, "rtpqos"))
- return 0;
-
- /* Default arguments of audio,all */
- if (ast_strlen_zero(args.type))
- args.type = "audio";
- if (ast_strlen_zero(args.field))
- args.field = "all";
-
- memset(buf, 0, buflen);
- memset(&qos, 0, sizeof(qos));
-
- if (strcasecmp(args.type, "AUDIO") == 0) {
- all = ast_rtp_get_quality(p->rtp, &qos);
- } else if (strcasecmp(args.type, "VIDEO") == 0) {
- all = ast_rtp_get_quality(p->vrtp, &qos);
- }
-
- if (strcasecmp(args.field, "local_ssrc") == 0)
- snprintf(buf, buflen, "%u", qos.local_ssrc);
- else if (strcasecmp(args.field, "local_lostpackets") == 0)
- snprintf(buf, buflen, "%u", qos.local_lostpackets);
- else if (strcasecmp(args.field, "local_jitter") == 0)
- snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
- else if (strcasecmp(args.field, "local_count") == 0)
- snprintf(buf, buflen, "%u", qos.local_count);
- else if (strcasecmp(args.field, "remote_ssrc") == 0)
- snprintf(buf, buflen, "%u", qos.remote_ssrc);
- else if (strcasecmp(args.field, "remote_lostpackets") == 0)
- snprintf(buf, buflen, "%u", qos.remote_lostpackets);
- else if (strcasecmp(args.field, "remote_jitter") == 0)
- snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
- else if (strcasecmp(args.field, "remote_count") == 0)
- snprintf(buf, buflen, "%u", qos.remote_count);
- else if (strcasecmp(args.field, "rtt") == 0)
- snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
- else if (strcasecmp(args.field, "all") == 0)
- ast_copy_string(buf, all, buflen);
- else {
- ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
- return -1;
- }
- return 0;
-}
-
-/*! \brief Handle incoming BYE request */
-static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
-{
- struct ast_channel *c=NULL;
- int res;
- struct ast_channel *bridged_to;
-
- /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
- if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner)
- transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
-
- p->invitestate = INV_TERMINATED;
-
- copy_request(&p->initreq, req);
- check_via(p, req);
- sip_alreadygone(p);
-
- /* Get RTCP quality before end of call */
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
- char *audioqos, *videoqos;
- if (p->rtp) {
- audioqos = ast_rtp_get_quality(p->rtp, NULL);
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "RTCPaudio", "Quality:%s", audioqos);
- if (p->owner)
- pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
- }
- if (p->vrtp) {
- videoqos = ast_rtp_get_quality(p->vrtp, NULL);
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "RTCPvideo", "Quality:%s", videoqos);
- if (p->owner)
- pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
- }
- }
-
- stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
-
- if (!ast_strlen_zero(get_header(req, "Also"))) {
- ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n",
- ast_inet_ntoa(p->recv.sin_addr));
- if (ast_strlen_zero(p->context))
- ast_string_field_set(p, context, default_context);
- res = get_also_info(p, req);
- if (!res) {
- c = p->owner;
- if (c) {
- bridged_to = ast_bridged_channel(c);
- if (bridged_to) {
- /* Don't actually hangup here... */
- ast_queue_control(c, AST_CONTROL_UNHOLD);
- ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
- } else
- ast_queue_hangup(p->owner);
- }
- } else {
- ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
- if (p->owner)
- ast_queue_hangup(p->owner);
- }
- } else if (p->owner) {
- ast_queue_hangup(p->owner);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
- } else {
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
- }
- transmit_response(p, "200 OK", req);
-
- return 1;
-}
-
-/*! \brief Handle incoming MESSAGE request */
-static int handle_request_message(struct sip_pvt *p, struct sip_request *req)
-{
- if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Receiving message!\n");
- receive_message(p, req);
- } else
- transmit_response(p, "202 Accepted", req);
- return 1;
-}
-
-/*! \brief Handle incoming SUBSCRIBE request */
-static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
-{
- int gotdest;
- int res = 0;
- int firststate = AST_EXTENSION_REMOVED;
- struct sip_peer *authpeer = NULL;
- const char *eventheader = get_header(req, "Event"); /* Get Event package name */
- const char *accept = get_header(req, "Accept");
- int resubscribe = (p->subscribed != NONE);
- char *temp, *event;
-
- if (p->initreq.headers) {
- /* We already have a dialog */
- if (p->initreq.method != SIP_SUBSCRIBE) {
- /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
- /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
- transmit_response(p, "403 Forbidden (within dialog)", req);
- /* Do not destroy session, since we will break the call if we do */
- if (option_debug)
- ast_log(LOG_DEBUG, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
- return 0;
- } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
- if (option_debug) {
- if (resubscribe)
- ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
- else
- ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
- }
- }
- }
-
- /* Check if we have a global disallow setting on subscriptions.
- if so, we don't have to check peer/user settings after auth, which saves a lot of processing
- */
- if (!global_allowsubscribe) {
- transmit_response(p, "403 Forbidden (policy)", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
-
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */
- const char *to = get_header(req, "To");
- char totag[128];
-
- /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
- if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
- transmit_response(p, "481 Subscription does not exist", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
-
- /* Use this as the basis */
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Creating new subscription\n");
-
- copy_request(&p->initreq, req);
- check_via(p, req);
- } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
- ast_verbose("Ignoring this SUBSCRIBE request\n");
-
- /* Find parameters to Event: header value and remove them for now */
- if (ast_strlen_zero(eventheader)) {
- transmit_response(p, "489 Bad Event", req);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
-
- if ( (strchr(eventheader, ';'))) {
- event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */
- temp = strchr(event, ';');
- *temp = '\0'; /* Remove any options for now */
- /* We might need to use them later :-) */
- } else
- event = (char *) eventheader; /* XXX is this legal ? */
-
- /* Handle authentication */
- res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
- /* if an authentication response was sent, we are done here */
- if (res == AUTH_CHALLENGE_SENT) {
- if (authpeer)
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
- if (res < 0) {
- if (res == AUTH_FAKE_AUTH) {
- ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
- transmit_fake_auth_response(p, req, 1);
- } else {
- ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
- transmit_response_reliable(p, "403 Forbidden", req);
- }
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (authpeer)
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
-
- /* Check if this user/peer is allowed to subscribe at all */
- if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
- transmit_response(p, "403 Forbidden (policy)", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (authpeer)
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
-
- /* Get destination right away */
- gotdest = get_destination(p, NULL);
-
- /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
- parse_ok_contact(p, req);
-
- build_contact(p);
- if (strcmp(event, "message-summary") && gotdest) {
- transmit_response(p, "404 Not Found", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (authpeer)
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
-
- /* Initialize tag for new subscriptions */
- if (ast_strlen_zero(p->tag))
- make_our_tag(p->tag, sizeof(p->tag));
-
- if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
- if (authpeer) /* No need for authpeer here */
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
-
- /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
- /* Polycom phones only handle xpidf+xml, even if they say they can
- handle pidf+xml as well
- */
- if (strstr(p->useragent, "Polycom")) {
- p->subscribed = XPIDF_XML;
- } else if (strstr(accept, "application/pidf+xml")) {
- p->subscribed = PIDF_XML; /* RFC 3863 format */
- } else if (strstr(accept, "application/dialog-info+xml")) {
- p->subscribed = DIALOG_INFO_XML;
- /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
- } else if (strstr(accept, "application/cpim-pidf+xml")) {
- p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
- } else if (strstr(accept, "application/xpidf+xml")) {
- p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
- } else if (ast_strlen_zero(accept)) {
- if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
- transmit_response(p, "489 Bad Event", req);
-
- ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
- p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
- /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
- so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
- } else {
- /* Can't find a format for events that we know about */
- char mybuf[200];
- snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
- transmit_response(p, mybuf, req);
-
- ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
- accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
- } else if (!strcmp(event, "message-summary")) {
- if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
- /* Format requested that we do not support */
- transmit_response(p, "406 Not Acceptable", req);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (authpeer) /* No need for authpeer here */
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
- /* Looks like they actually want a mailbox status
- This version of Asterisk supports mailbox subscriptions
- The subscribed URI needs to exist in the dial plan
- In most devices, this is configurable to the voicemailmain extension you use
- */
- if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
- transmit_response(p, "404 Not found (no mailbox)", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
- if (authpeer) /* No need for authpeer here */
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
-
- p->subscribed = MWI_NOTIFICATION;
- if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */
- /* We only allow one subscription per peer */
- sip_destroy(authpeer->mwipvt);
- authpeer->mwipvt = p; /* Link from peer to pvt */
- p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */
- } else { /* At this point, Asterisk does not understand the specified event */
- transmit_response(p, "489 Bad Event", req);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- if (authpeer) /* No need for authpeer here */
- ASTOBJ_UNREF(authpeer, sip_destroy_peer);
- return 0;
- }
-
- if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
- if (p->stateid > -1)
- ast_extension_state_del(p->stateid, cb_extensionstate);
- p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
- }
-
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
- p->lastinvite = seqno;
- if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
- p->expiry = atoi(get_header(req, "Expires"));
-
- /* check if the requested expiry-time is within the approved limits from sip.conf */
- if (p->expiry > max_expiry)
- p->expiry = max_expiry;
- if (p->expiry < min_expiry && p->expiry > 0)
- p->expiry = min_expiry;
-
- if (sipdebug || option_debug > 1) {
- if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
- ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
- else
- ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
- }
- if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */
- ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
- if (p->expiry > 0)
- sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */
-
- if (p->subscribed == MWI_NOTIFICATION) {
- transmit_response(p, "200 OK", req);
- if (p->relatedpeer) { /* Send first notification */
- ASTOBJ_WRLOCK(p->relatedpeer);
- sip_send_mwi_to_peer(p->relatedpeer);
- ASTOBJ_UNLOCK(p->relatedpeer);
- }
- } else {
- struct sip_pvt *p_old;
-
- if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
-
- ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_inet_ntoa(p->sa.sin_addr));
- transmit_response(p, "404 Not found", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
-
- transmit_response(p, "200 OK", req);
- transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
- append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
- /* hide the 'complete' exten/context in the refer_to field for later display */
- ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
-
- /* remove any old subscription from this peer for the same exten/context,
- as the peer has obviously forgotten about it and it's wasteful to wait
- for it to expire and send NOTIFY messages to the peer only to have them
- ignored (or generate errors)
- */
- ast_mutex_lock(&iflock);
- for (p_old = iflist; p_old; p_old = p_old->next) {
- if (p_old == p)
- continue;
- if (p_old->initreq.method != SIP_SUBSCRIBE)
- continue;
- if (p_old->subscribed == NONE)
- continue;
- ast_mutex_lock(&p_old->lock);
- if (!strcmp(p_old->username, p->username)) {
- if (!strcmp(p_old->exten, p->exten) &&
- !strcmp(p_old->context, p->context)) {
- ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
- ast_mutex_unlock(&p_old->lock);
- break;
- }
- }
- ast_mutex_unlock(&p_old->lock);
- }
- ast_mutex_unlock(&iflock);
- }
- if (!p->expiry)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- return 1;
-}
-
-/*! \brief Handle incoming REGISTER request */
-static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e)
-{
- enum check_auth_result res;
-
- /* Use this as the basis */
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Using latest REGISTER request as basis request\n");
- copy_request(&p->initreq, req);
- check_via(p, req);
- if ((res = register_verify(p, sin, req, e)) < 0) {
- const char *reason;
-
- switch (res) {
- case AUTH_SECRET_FAILED:
- reason = "Wrong password";
- break;
- case AUTH_USERNAME_MISMATCH:
- reason = "Username/auth name mismatch";
- break;
- case AUTH_NOT_FOUND:
- reason = "No matching peer found";
- break;
- case AUTH_UNKNOWN_DOMAIN:
- reason = "Not a local domain";
- break;
- case AUTH_PEER_NOT_DYNAMIC:
- reason = "Peer is not supposed to register";
- break;
- case AUTH_ACL_FAILED:
- reason = "Device does not match ACL";
- break;
- default:
- reason = "Unknown failure";
- break;
- }
- ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
- get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
- reason);
- append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
- } else
- append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
-
- if (res < 1) {
- /* Destroy the session, but keep us around for just a bit in case they don't
- get our 200 OK */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- return res;
-}
-
-/*! \brief Handle incoming SIP requests (methods)
-\note This is where all incoming requests go first */
-/* called with p and p->owner locked */
-static int handle_request(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
-{
- /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
- relatively static */
- const char *cmd;
- const char *cseq;
- const char *useragent;
- int seqno;
- int len;
- int ignore = FALSE;
- int respid;
- int res = 0;
- int debug = sip_debug_test_pvt(p);
- char *e;
- int error = 0;
-
- /* Get Method and Cseq */
- cseq = get_header(req, "Cseq");
- cmd = req->header[0];
-
- /* Must have Cseq */
- if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
- ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
- error = 1;
- }
- if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
- ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
- error = 1;
- }
- if (error) {
- if (!p->initreq.headers) /* New call */
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
- return -1;
- }
- /* Get the command XXX */
-
- cmd = req->rlPart1;
- e = req->rlPart2;
-
- /* Save useragent of the client */
- useragent = get_header(req, "User-Agent");
- if (!ast_strlen_zero(useragent))
- ast_string_field_set(p, useragent, useragent);
-
- /* Find out SIP method for incoming request */
- if (req->method == SIP_RESPONSE) { /* Response to our request */
- /* Response to our request -- Do some sanity checks */
- if (!p->initreq.headers) {
- if (option_debug)
- ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
- return -1;
- } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) {
- /* ignore means "don't do anything with it" but still have to
- respond appropriately */
- ignore = TRUE;
- ast_set_flag(req, SIP_PKT_IGNORE);
- ast_set_flag(req, SIP_PKT_IGNORE_RESP);
- append_history(p, "Ignore", "Ignoring this retransmit\n");
- } else if (e) {
- e = ast_skip_blanks(e);
- if (sscanf(e, "%d %n", &respid, &len) != 1) {
- ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
- } else {
- if (respid <= 0) {
- ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
- return 0;
- }
- /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
- if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
- extract_uri(p, req);
- handle_response(p, respid, e + len, req, ignore, seqno);
- }
- }
- return 0;
- }
-
- /* New SIP request coming in
- (could be new request in existing SIP dialog as well...)
- */
-
- p->method = req->method; /* Find out which SIP method they are using */
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd);
-
- if (p->icseq && (p->icseq > seqno) ) {
- if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n");
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
- if (req->method != SIP_ACK)
- transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */
- return -1;
- }
- } else if (p->icseq &&
- p->icseq == seqno &&
- req->method != SIP_ACK &&
- (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
- /* ignore means "don't do anything with it" but still have to
- respond appropriately. We do this if we receive a repeat of
- the last sequence number */
- ignore = 2;
- ast_set_flag(req, SIP_PKT_IGNORE);
- ast_set_flag(req, SIP_PKT_IGNORE_REQ);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
- }
-
- if (seqno >= p->icseq)
- /* Next should follow monotonically (but not necessarily
- incrementally -- thanks again to the genius authors of SIP --
- increasing */
- p->icseq = seqno;
-
- /* Find their tag if we haven't got it */
- if (ast_strlen_zero(p->theirtag)) {
- char tag[128];
-
- gettag(req, "From", tag, sizeof(tag));
- ast_string_field_set(p, theirtag, tag);
- }
- snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
-
- if (pedanticsipchecking) {
- /* If this is a request packet without a from tag, it's not
- correct according to RFC 3261 */
- /* Check if this a new request in a new dialog with a totag already attached to it,
- RFC 3261 - section 12.2 - and we don't want to mess with recovery */
- if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
- /* If this is a first request and it got a to-tag, it is not for us */
- if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
- transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
- /* Will cease to exist after ACK */
- } else if (req->method != SIP_ACK) {
- transmit_response(p, "481 Call/Transaction Does Not Exist", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- return res;
- }
- }
-
- if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
- transmit_response(p, "400 Bad request", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return -1;
- }
-
- /* Handle various incoming SIP methods in requests */
- switch (p->method) {
- case SIP_OPTIONS:
- res = handle_request_options(p, req);
- break;
- case SIP_INVITE:
- res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
- break;
- case SIP_REFER:
- res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
- break;
- case SIP_CANCEL:
- res = handle_request_cancel(p, req);
- break;
- case SIP_BYE:
- res = handle_request_bye(p, req);
- break;
- case SIP_MESSAGE:
- res = handle_request_message(p, req);
- break;
- case SIP_SUBSCRIBE:
- res = handle_request_subscribe(p, req, sin, seqno, e);
- break;
- case SIP_REGISTER:
- res = handle_request_register(p, req, sin, e);
- break;
- case SIP_INFO:
- if (ast_test_flag(req, SIP_PKT_DEBUG))
- ast_verbose("Receiving INFO!\n");
- if (!ignore)
- handle_request_info(p, req);
- else /* if ignoring, transmit response */
- transmit_response(p, "200 OK", req);
- break;
- case SIP_NOTIFY:
- res = handle_request_notify(p, req, sin, seqno, e);
- break;
- case SIP_ACK:
- /* Make sure we don't ignore this */
- if (seqno == p->pendinginvite) {
- p->invitestate = INV_TERMINATED;
- p->pendinginvite = 0;
- __sip_ack(p, seqno, FLAG_RESPONSE, 0);
- if (find_sdp(req)) {
- if (process_sdp(p, req))
- return -1;
- }
- check_pendings(p);
- }
- /* Got an ACK that we did not match. Ignore silently */
- if (!p->lastinvite && ast_strlen_zero(p->randdata))
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
- default:
- transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
- ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
- cmd, ast_inet_ntoa(p->sa.sin_addr));
- /* If this is some new method, and we don't have a call, destroy it now */
- if (!p->initreq.headers)
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- break;
- }
- return res;
-}
-
-/*! \brief Read data from SIP socket
-\note sipsock_read locks the owner channel while we are processing the SIP message
-\return 1 on error, 0 on success
-\note Successful messages is connected to SIP call and forwarded to handle_request()
-*/
-static int sipsock_read(int *id, int fd, short events, void *ignore)
-{
- struct sip_request req;
- struct sockaddr_in sin = { 0, };
- struct sip_pvt *p;
- int res;
- socklen_t len = sizeof(sin);
- int nounlock;
- int recount = 0;
- int lockretry;
-
- memset(&req, 0, sizeof(req));
- res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
- if (res < 0) {
-#if !defined(__FreeBSD__)
- if (errno == EAGAIN)
- ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
- else
-#endif
- if (errno != ECONNREFUSED)
- ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
- return 1;
- }
- if (option_debug && res == sizeof(req.data) - 1)
- ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
-
- req.data[res] = '\0';
- req.len = res;
- if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
- ast_set_flag(&req, SIP_PKT_DEBUG);
- if (pedanticsipchecking)
- req.len = lws2sws(req.data, req.len); /* Fix multiline headers */
- if (ast_test_flag(&req, SIP_PKT_DEBUG))
- ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
-
- if(parse_request(&req) == -1) /* Bad packet, can't parse */
- return 1;
-
- req.method = find_sip_method(req.rlPart1);
-
- if (ast_test_flag(&req, SIP_PKT_DEBUG))
- ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
-
- if (req.headers < 2) /* Must have at least two headers */
- return 1;
-
- /* Process request, with netlock held, and with usual deadlock avoidance */
- for (lockretry = 100; lockretry > 0; lockretry--) {
- ast_mutex_lock(&netlock);
-
- /* Find the active SIP dialog or create a new one */
- p = find_call(&req, &sin, req.method); /* returns p locked */
- if (p == NULL) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
- ast_mutex_unlock(&netlock);
- return 1;
- }
- /* Go ahead and lock the owner if it has one -- we may need it */
- /* becaues this is deadlock-prone, we need to try and unlock if failed */
- if (!p->owner || !ast_channel_trylock(p->owner))
- break; /* locking succeeded */
- if (option_debug)
- ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
- ast_mutex_unlock(&p->lock);
- ast_mutex_unlock(&netlock);
- /* Sleep for a very short amount of time */
- usleep(1);
- }
- p->recv = sin;
-
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
- append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
-
- if (!lockretry) {
- if (p->owner)
- ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - "));
- ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
- if (req.method != SIP_ACK)
- transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
- /* XXX We could add retry-after to make sure they come back */
- append_history(p, "LockFail", "Owner lock failed, transaction failed.");
- return 1;
- }
- nounlock = 0;
- if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
- /* Request failed */
- if (option_debug)
- ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
- }
-
- if (p->owner && !nounlock)
- ast_channel_unlock(p->owner);
- ast_mutex_unlock(&p->lock);
- ast_mutex_unlock(&netlock);
- if (recount)
- ast_update_use_count();
-
- return 1;
-}
-
-/*! \brief Send message waiting indication to alert peer that they've got voicemail */
-static int sip_send_mwi_to_peer(struct sip_peer *peer)
-{
- /* Called with peerl lock, but releases it */
- struct sip_pvt *p;
- int newmsgs, oldmsgs;
-
- /* Do we have an IP address? If not, skip this peer */
- if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr)
- return 0;
-
- /* Check for messages */
- ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
-
- peer->lastmsgcheck = time(NULL);
-
- /* Return now if it's the same thing we told them last time */
- if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
- return 0;
- }
-
-
- peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
-
- if (peer->mwipvt) {
- /* Base message on subscription */
- p = peer->mwipvt;
- } else {
- /* Build temporary dialog for this message */
- if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
- return -1;
- if (create_addr_from_peer(p, peer)) {
- /* Maybe they're not registered, etc. */
- sip_destroy(p);
- return 0;
- }
- /* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
- build_via(p);
- build_callid_pvt(p);
- /* Destroy this session after 32 secs */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- /* Send MWI */
- ast_set_flag(&p->flags[0], SIP_OUTGOING);
- transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
- return 0;
-}
-
-/*! \brief Check whether peer needs a new MWI notification check */
-static int does_peer_need_mwi(struct sip_peer *peer)
-{
- time_t t = time(NULL);
-
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
- !peer->mwipvt) { /* We don't have a subscription */
- peer->lastmsgcheck = t; /* Reset timer */
- return FALSE;
- }
-
- if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
- return TRUE;
-
- return FALSE;
-}
-
-
-/*! \brief The SIP monitoring thread
-\note This thread monitors all the SIP sessions and peers that needs notification of mwi
- (and thus do not have a separate thread) indefinitely
-*/
-static void *do_monitor(void *data)
-{
- int res;
- struct sip_pvt *sip;
- struct sip_peer *peer = NULL;
- time_t t;
- int fastrestart = FALSE;
- int lastpeernum = -1;
- int curpeernum;
- int reloading;
-
- /* Add an I/O event to our SIP UDP socket */
- if (sipsock > -1)
- sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
-
- /* From here on out, we die whenever asked */
- for(;;) {
- /* Check for a reload request */
- ast_mutex_lock(&sip_reload_lock);
- reloading = sip_reloading;
- sip_reloading = FALSE;
- ast_mutex_unlock(&sip_reload_lock);
- if (reloading) {
- if (option_verbose > 0)
- ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
- sip_do_reload(sip_reloadreason);
-
- /* Change the I/O fd of our UDP socket */
- if (sipsock > -1) {
- if (sipsock_read_id)
- sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
- else
- sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
- } else if (sipsock_read_id) {
- ast_io_remove(io, sipsock_read_id);
- sipsock_read_id = NULL;
- }
- }
-restartsearch:
- /* Check for interfaces needing to be killed */
- ast_mutex_lock(&iflock);
- t = time(NULL);
- /* don't scan the interface list if it hasn't been a reasonable period
- of time since the last time we did it (when MWI is being sent, we can
- get back to this point every millisecond or less)
- */
- for (sip = iflist; !fastrestart && sip; sip = sip->next) {
- /*! \note If we can't get a lock on an interface, skip it and come
- * back later. Note that there is the possibility of a deadlock with
- * sip_hangup otherwise, because sip_hangup is called with the channel
- * locked first, and the iface lock is attempted second.
- */
- if (ast_mutex_trylock(&sip->lock))
- continue;
-
- /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
- if (sip->rtp && sip->owner &&
- (sip->owner->_state == AST_STATE_UP) &&
- !sip->redirip.sin_addr.s_addr &&
- sip->t38.state != T38_ENABLED) {
- if (sip->lastrtptx &&
- ast_rtp_get_rtpkeepalive(sip->rtp) &&
- (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
- /* Need to send an empty RTP packet */
- sip->lastrtptx = time(NULL);
- ast_rtp_sendcng(sip->rtp, 0);
- }
- if (sip->lastrtprx &&
- (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
- (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
- /* Might be a timeout now -- see if we're on hold */
- struct sockaddr_in sin;
- ast_rtp_get_peer(sip->rtp, &sin);
- if (sin.sin_addr.s_addr ||
- (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
- (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
- /* Needs a hangup */
- if (ast_rtp_get_rtptimeout(sip->rtp)) {
- while (sip->owner && ast_channel_trylock(sip->owner)) {
- ast_mutex_unlock(&sip->lock);
- usleep(1);
- ast_mutex_lock(&sip->lock);
- }
- if (sip->owner) {
- ast_log(LOG_NOTICE,
- "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
- sip->owner->name,
- (long) (t - sip->lastrtprx));
- /* Issue a softhangup */
- ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
- ast_channel_unlock(sip->owner);
- /* forget the timeouts for this call, since a hangup
- has already been requested and we don't want to
- repeatedly request hangups
- */
- ast_rtp_set_rtptimeout(sip->rtp, 0);
- ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
- if (sip->vrtp) {
- ast_rtp_set_rtptimeout(sip->vrtp, 0);
- ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
- }
- }
- }
- }
- }
- }
- /* If we have sessions that needs to be destroyed, do it now */
- if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
- !sip->owner) {
- ast_mutex_unlock(&sip->lock);
- __sip_destroy(sip, 1);
- ast_mutex_unlock(&iflock);
- usleep(1);
- goto restartsearch;
- }
- ast_mutex_unlock(&sip->lock);
- }
- ast_mutex_unlock(&iflock);
-
- pthread_testcancel();
- /* Wait for sched or io */
- res = ast_sched_wait(sched);
- if ((res < 0) || (res > 1000))
- res = 1000;
- /* If we might need to send more mailboxes, don't wait long at all.*/
- if (fastrestart)
- res = 1;
- res = ast_io_wait(io, res);
- if (option_debug && res > 20)
- ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
- ast_mutex_lock(&monlock);
- if (res >= 0) {
- res = ast_sched_runq(sched);
- if (option_debug && res >= 20)
- ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
- }
-
- /* Send MWI notifications to peers - static and cached realtime peers */
- t = time(NULL);
- fastrestart = FALSE;
- curpeernum = 0;
- peer = NULL;
- /* Find next peer that needs mwi */
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
- if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
- fastrestart = TRUE;
- lastpeernum = curpeernum;
- peer = ASTOBJ_REF(iterator);
- };
- curpeernum++;
- } while (0)
- );
- /* Send MWI to the peer */
- if (peer) {
- ASTOBJ_WRLOCK(peer);
- sip_send_mwi_to_peer(peer);
- ASTOBJ_UNLOCK(peer);
- ASTOBJ_UNREF(peer,sip_destroy_peer);
- } else {
- /* Reset where we come from */
- lastpeernum = -1;
- }
- ast_mutex_unlock(&monlock);
- }
- /* Never reached */
- return NULL;
-
-}
-
-/*! \brief Start the channel monitor thread */
-static int restart_monitor(void)
-{
- /* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == AST_PTHREADT_STOP)
- return 0;
- ast_mutex_lock(&monlock);
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread != AST_PTHREADT_NULL) {
- /* Wake up the thread */
- pthread_kill(monitor_thread, SIGURG);
- } else {
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- return -1;
- }
- }
- ast_mutex_unlock(&monlock);
- return 0;
-}
-
-/*! \brief React to lack of answer to Qualify poke */
-static int sip_poke_noanswer(const void *data)
-{
- struct sip_peer *peer = (struct sip_peer *)data;
-
- peer->pokeexpire = -1;
- if (peer->lastms > -1) {
- ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
- }
- if (peer->call)
- sip_destroy(peer->call);
- peer->call = NULL;
- peer->lastms = -1;
- ast_device_state_changed("SIP/%s", peer->name);
-
- /* This function gets called one place outside of the scheduler ... */
- if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
-
- /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback
- * inherit the reference that the current callback already has. */
- peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
- if (peer->pokeexpire == -1) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- }
-
- return 0;
-}
-
-/*! \brief Check availability of peer, also keep NAT open
-\note This is done with the interval in qualify= configuration option
- Default is 2 seconds */
-static int sip_poke_peer(struct sip_peer *peer)
-{
- struct sip_pvt *p;
- int xmitres = 0;
-
- if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
- /* IF we have no IP, or this isn't to be monitored, return
- imeediately after clearing things out */
- if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- peer->lastms = 0;
- peer->call = NULL;
- return 0;
- }
- if (peer->call) {
- if (sipdebug)
- ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
- sip_destroy(peer->call);
- }
- if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
- return -1;
-
- p->sa = peer->addr;
- p->recv = peer->addr;
- ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
-
- /* Send OPTIONs to peer's fullcontact */
- if (!ast_strlen_zero(peer->fullcontact))
- ast_string_field_set(p, fullcontact, peer->fullcontact);
-
- if (!ast_strlen_zero(peer->tohost))
- ast_string_field_set(p, tohost, peer->tohost);
- else
- ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
-
- /* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
- build_via(p);
- build_callid_pvt(p);
-
- if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
-
- p->relatedpeer = ASTOBJ_REF(peer);
- ast_set_flag(&p->flags[0], SIP_OUTGOING);
-#ifdef VOCAL_DATA_HACK
- ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
- xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
-#else
- xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
-#endif
- gettimeofday(&peer->ps, NULL);
- if (xmitres == XMIT_ERROR) {
- sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */
- } else {
- if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer));
- if (peer->pokeexpire == -1) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- }
-
- return 0;
-}
-
-/*! \brief Part of PBX channel interface
-\note
-\par Return values:---
-
- If we have qualify on and the device is not reachable, regardless of registration
- state we return AST_DEVICE_UNAVAILABLE
-
- For peers with call limit:
- - not registered AST_DEVICE_UNAVAILABLE
- - registered, no call AST_DEVICE_NOT_INUSE
- - registered, active calls AST_DEVICE_INUSE
- - registered, call limit reached AST_DEVICE_BUSY
- - registered, onhold AST_DEVICE_ONHOLD
- - registered, ringing AST_DEVICE_RINGING
-
- For peers without call limit:
- - not registered AST_DEVICE_UNAVAILABLE
- - registered AST_DEVICE_NOT_INUSE
- - fixed IP (!dynamic) AST_DEVICE_NOT_INUSE
-
- Peers that does not have a known call and can't be reached by OPTIONS
- - unreachable AST_DEVICE_UNAVAILABLE
-
- If we return AST_DEVICE_UNKNOWN, the device state engine will try to find
- out a state by walking the channel list.
-
- The queue system (\ref app_queue.c) treats a member as "active"
- if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
-
- When placing a call to the queue member, queue system sets a member to busy if
- != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
-
-*/
-static int sip_devicestate(void *data)
-{
- char *host;
- char *tmp;
-
- struct hostent *hp;
- struct ast_hostent ahp;
- struct sip_peer *p;
-
- int res = AST_DEVICE_INVALID;
-
- /* make sure data is not null. Maybe unnecessary, but better be safe */
- host = ast_strdupa(data ? data : "");
- if ((tmp = strchr(host, '@')))
- host = tmp + 1;
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
-
- if ((p = find_peer(host, NULL, 1))) {
- if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
- /* we have an address for the peer */
-
- /* Check status in this order
- - Hold
- - Ringing
- - Busy (enforced only by call limit)
- - Inuse (we have a call)
- - Unreachable (qualify)
- If we don't find any of these state, report AST_DEVICE_NOT_INUSE
- for registered devices */
-
- if (p->onHold)
- /* First check for hold or ring states */
- res = AST_DEVICE_ONHOLD;
- else if (p->inRinging) {
- if (p->inRinging == p->inUse)
- res = AST_DEVICE_RINGING;
- else
- res = AST_DEVICE_RINGINUSE;
- } else if (p->call_limit && (p->inUse == p->call_limit))
- /* check call limit */
- res = AST_DEVICE_BUSY;
- else if (p->call_limit && p->inUse)
- /* Not busy, but we do have a call */
- res = AST_DEVICE_INUSE;
- else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0)))
- /* We don't have a call. Are we reachable at all? Requires qualify= */
- res = AST_DEVICE_UNAVAILABLE;
- else /* Default reply if we're registered and have no other data */
- res = AST_DEVICE_NOT_INUSE;
- } else {
- /* there is no address, it's unavailable */
- res = AST_DEVICE_UNAVAILABLE;
- }
- ASTOBJ_UNREF(p,sip_destroy_peer);
- } else {
- char *port = strchr(host, ':');
- if (port)
- *port = '\0';
- hp = ast_gethostbyname(host, &ahp);
- if (hp)
- res = AST_DEVICE_UNKNOWN;
- }
-
- return res;
-}
-
-/*! \brief PBX interface function -build SIP pvt structure
- SIP calls initiated by the PBX arrive here */
-static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause)
-{
- int oldformat;
- struct sip_pvt *p;
- struct ast_channel *tmpc = NULL;
- char *ext, *host;
- char tmp[256];
- char *dest = data;
-
- oldformat = format;
- if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(global_capability));
- *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */
- return NULL;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
-
- if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
- ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
- *cause = AST_CAUSE_SWITCH_CONGESTION;
- return NULL;
- }
-
- ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
-
- if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
- sip_destroy(p);
- ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
- *cause = AST_CAUSE_SWITCH_CONGESTION;
- return NULL;
- }
-
- ast_copy_string(tmp, dest, sizeof(tmp));
- host = strchr(tmp, '@');
- if (host) {
- *host++ = '\0';
- ext = tmp;
- } else {
- ext = strchr(tmp, '/');
- if (ext)
- *ext++ = '\0';
- host = tmp;
- }
-
- if (create_addr(p, host)) {
- *cause = AST_CAUSE_UNREGISTERED;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
- sip_destroy(p);
- return NULL;
- }
- if (ast_strlen_zero(p->peername) && ext)
- ast_string_field_set(p, peername, ext);
- /* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
- build_via(p);
- build_callid_pvt(p);
-
- /* We have an extension to call, don't use the full contact here */
- /* This to enable dialing registered peers with extension dialling,
- like SIP/peername/extension
- SIP/peername will still use the full contact */
- if (ext) {
- ast_string_field_set(p, username, ext);
- ast_string_field_free(p, fullcontact);
- }
-#if 0
- printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
-#endif
- p->prefcodec = oldformat; /* Format for this call */
- ast_mutex_lock(&p->lock);
- tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */
- ast_mutex_unlock(&p->lock);
- if (!tmpc)
- sip_destroy(p);
- ast_update_use_count();
- restart_monitor();
- return tmpc;
-}
-
-/*!
- * \brief Parse the "insecure" setting from sip.conf or from realtime.
- * \param flags a pointer to an ast_flags structure
- * \param value the value of the SIP insecure setting
- * \param lineno linenumber in sip.conf or -1 for realtime
- */
-static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno)
-{
- static int dep_insecure_very = 0;
- static int dep_insecure_yes = 0;
-
- if (ast_strlen_zero(value))
- return;
-
- if (!strcasecmp(value, "very")) {
- ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
- if(!dep_insecure_very) {
- if(lineno != -1)
- ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
- else
- ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
- dep_insecure_very = 1;
- }
- }
- else if (ast_true(value)) {
- ast_set_flag(flags, SIP_INSECURE_PORT);
- if(!dep_insecure_yes) {
- if(lineno != -1)
- ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
- else
- ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
- dep_insecure_yes = 1;
- }
- }
- else if (!ast_false(value)) {
- char buf[64];
- char *word, *next;
- ast_copy_string(buf, value, sizeof(buf));
- next = buf;
- while ((word = strsep(&next, ","))) {
- if (!strcasecmp(word, "port"))
- ast_set_flag(flags, SIP_INSECURE_PORT);
- else if (!strcasecmp(word, "invite"))
- ast_set_flag(flags, SIP_INSECURE_INVITE);
- else
- ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
- }
- }
-}
-
-/*!
- \brief Handle flag-type options common to configuration of devices - users and peers
- \param flags array of two struct ast_flags
- \param mask array of two struct ast_flags
- \param v linked list of config variables to process
- \returns non-zero if any config options were handled, zero otherwise
-*/
-static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
-{
- int res = 1;
-
- if (!strcasecmp(v->name, "trustrpid")) {
- ast_set_flag(&mask[0], SIP_TRUSTRPID);
- ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
- } else if (!strcasecmp(v->name, "sendrpid")) {
- ast_set_flag(&mask[0], SIP_SENDRPID);
- ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
- } else if (!strcasecmp(v->name, "g726nonstandard")) {
- ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
- ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
- } else if (!strcasecmp(v->name, "useclientcode")) {
- ast_set_flag(&mask[0], SIP_USECLIENTCODE);
- ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
- } else if (!strcasecmp(v->name, "dtmfmode")) {
- ast_set_flag(&mask[0], SIP_DTMF);
- ast_clear_flag(&flags[0], SIP_DTMF);
- if (!strcasecmp(v->value, "inband"))
- ast_set_flag(&flags[0], SIP_DTMF_INBAND);
- else if (!strcasecmp(v->value, "rfc2833"))
- ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
- else if (!strcasecmp(v->value, "info"))
- ast_set_flag(&flags[0], SIP_DTMF_INFO);
- else if (!strcasecmp(v->value, "auto"))
- ast_set_flag(&flags[0], SIP_DTMF_AUTO);
- else {
- ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
- ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
- }
- } else if (!strcasecmp(v->name, "nat")) {
- ast_set_flag(&mask[0], SIP_NAT);
- ast_clear_flag(&flags[0], SIP_NAT);
- if (!strcasecmp(v->value, "never"))
- ast_set_flag(&flags[0], SIP_NAT_NEVER);
- else if (!strcasecmp(v->value, "route"))
- ast_set_flag(&flags[0], SIP_NAT_ROUTE);
- else if (ast_true(v->value))
- ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
- else
- ast_set_flag(&flags[0], SIP_NAT_RFC3581);
- } else if (!strcasecmp(v->name, "canreinvite")) {
- ast_set_flag(&mask[0], SIP_REINVITE);
- ast_clear_flag(&flags[0], SIP_REINVITE);
- if(ast_true(v->value)) {
- ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
- } else if (!ast_false(v->value)) {
- char buf[64];
- char *word, *next = buf;
-
- ast_copy_string(buf, v->value, sizeof(buf));
- while ((word = strsep(&next, ","))) {
- if(!strcasecmp(word, "update")) {
- ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
- } else if(!strcasecmp(word, "nonat")) {
- ast_set_flag(&flags[0], SIP_CAN_REINVITE);
- ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
- } else {
- ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
- }
- }
- }
- } else if (!strcasecmp(v->name, "insecure")) {
- ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
- ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
- set_insecure_flags(flags, v->value, v->lineno);
- } else if (!strcasecmp(v->name, "progressinband")) {
- ast_set_flag(&mask[0], SIP_PROG_INBAND);
- ast_clear_flag(&flags[0], SIP_PROG_INBAND);
- if (ast_true(v->value))
- ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
- else if (strcasecmp(v->value, "never"))
- ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
- } else if (!strcasecmp(v->name, "promiscredir")) {
- ast_set_flag(&mask[0], SIP_PROMISCREDIR);
- ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
- } else if (!strcasecmp(v->name, "videosupport")) {
- ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
- } else if (!strcasecmp(v->name, "allowoverlap")) {
- ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
- } else if (!strcasecmp(v->name, "allowsubscribe")) {
- ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
- } else if (!strcasecmp(v->name, "t38pt_udptl")) {
- ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
-#ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
- } else if (!strcasecmp(v->name, "t38pt_rtp")) {
- ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
- } else if (!strcasecmp(v->name, "t38pt_tcp")) {
- ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
-#endif
- } else if (!strcasecmp(v->name, "rfc2833compensate")) {
- ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
- } else if (!strcasecmp(v->name, "buggymwi")) {
- ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
- ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
- } else
- res = 0;
-
- return res;
-}
-
-/*! \brief Add SIP domain to list of domains we are responsible for */
-static int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context)
-{
- struct domain *d;
-
- if (ast_strlen_zero(domain)) {
- ast_log(LOG_WARNING, "Zero length domain.\n");
- return 1;
- }
-
- if (!(d = ast_calloc(1, sizeof(*d))))
- return 0;
-
- ast_copy_string(d->domain, domain, sizeof(d->domain));
-
- if (!ast_strlen_zero(context))
- ast_copy_string(d->context, context, sizeof(d->context));
-
- d->mode = mode;
-
- AST_LIST_LOCK(&domain_list);
- AST_LIST_INSERT_TAIL(&domain_list, d, list);
- AST_LIST_UNLOCK(&domain_list);
-
- if (sipdebug)
- ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
-
- return 1;
-}
-
-/*! \brief check_sip_domain: Check if domain part of uri is local to our server */
-static int check_sip_domain(const char *domain, char *context, size_t len)
-{
- struct domain *d;
- int result = 0;
-
- AST_LIST_LOCK(&domain_list);
- AST_LIST_TRAVERSE(&domain_list, d, list) {
- if (strcasecmp(d->domain, domain))
- continue;
-
- if (len && !ast_strlen_zero(d->context))
- ast_copy_string(context, d->context, len);
-
- result = 1;
- break;
- }
- AST_LIST_UNLOCK(&domain_list);
-
- return result;
-}
-
-/*! \brief Clear our domain list (at reload) */
-static void clear_sip_domains(void)
-{
- struct domain *d;
-
- AST_LIST_LOCK(&domain_list);
- while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
- free(d);
- AST_LIST_UNLOCK(&domain_list);
-}
-
-
-/*! \brief Add realm authentication in list */
-static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno)
-{
- char authcopy[256];
- char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
- char *stringp;
- struct sip_auth *a, *b, *auth;
-
- if (ast_strlen_zero(configuration))
- return authlist;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration);
-
- ast_copy_string(authcopy, configuration, sizeof(authcopy));
- stringp = authcopy;
-
- username = stringp;
- realm = strrchr(stringp, '@');
- if (realm)
- *realm++ = '\0';
- if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
- ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
- return authlist;
- }
- stringp = username;
- username = strsep(&stringp, ":");
- if (username) {
- secret = strsep(&stringp, ":");
- if (!secret) {
- stringp = username;
- md5secret = strsep(&stringp,"#");
- }
- }
- if (!(auth = ast_calloc(1, sizeof(*auth))))
- return authlist;
-
- ast_copy_string(auth->realm, realm, sizeof(auth->realm));
- ast_copy_string(auth->username, username, sizeof(auth->username));
- if (secret)
- ast_copy_string(auth->secret, secret, sizeof(auth->secret));
- if (md5secret)
- ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
-
- /* find the end of the list */
- for (b = NULL, a = authlist; a ; b = a, a = a->next)
- ;
- if (b)
- b->next = auth; /* Add structure add end of list */
- else
- authlist = auth;
-
- if (option_verbose > 2)
- ast_verbose("Added authentication for realm %s\n", realm);
-
- return authlist;
-
-}
-
-/*! \brief Clear realm authentication list (at reload) */
-static int clear_realm_authentication(struct sip_auth *authlist)
-{
- struct sip_auth *a = authlist;
- struct sip_auth *b;
-
- while (a) {
- b = a;
- a = a->next;
- free(b);
- }
-
- return 1;
-}
-
-/*! \brief Find authentication for a specific realm */
-static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm)
-{
- struct sip_auth *a;
-
- for (a = authlist; a; a = a->next) {
- if (!strcasecmp(a->realm, realm))
- break;
- }
-
- return a;
-}
-
-/*! \brief Initiate a SIP user structure from configuration (configuration or realtime) */
-static struct sip_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
-{
- struct sip_user *user;
- int format;
- struct ast_ha *oldha = NULL;
- char *varname = NULL, *varval = NULL;
- struct ast_variable *tmpvar = NULL;
- struct ast_flags userflags[2] = {{(0)}};
- struct ast_flags mask[2] = {{(0)}};
-
-
- if (!(user = ast_calloc(1, sizeof(*user))))
- return NULL;
-
- suserobjs++;
- ASTOBJ_INIT(user);
- ast_copy_string(user->name, name, sizeof(user->name));
- oldha = user->ha;
- user->ha = NULL;
- ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
- user->capability = global_capability;
- user->allowtransfer = global_allowtransfer;
- user->maxcallbitrate = default_maxcallbitrate;
- user->autoframing = global_autoframing;
- user->prefs = default_prefs;
- /* set default context */
- strcpy(user->context, default_context);
- strcpy(user->language, default_language);
- strcpy(user->mohinterpret, default_mohinterpret);
- strcpy(user->mohsuggest, default_mohsuggest);
- /* First we walk through the v parameters list and then the alt parameters list */
- for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
- if (handle_common_options(&userflags[0], &mask[0], v))
- continue;
-
- if (!strcasecmp(v->name, "context")) {
- ast_copy_string(user->context, v->value, sizeof(user->context));
- } else if (!strcasecmp(v->name, "subscribecontext")) {
- ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
- } else if (!strcasecmp(v->name, "setvar")) {
- varname = ast_strdupa(v->value);
- if ((varval = strchr(varname,'='))) {
- *varval++ = '\0';
- if ((tmpvar = ast_variable_new(varname, varval))) {
- tmpvar->next = user->chanvars;
- user->chanvars = tmpvar;
- }
- }
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- user->ha = ast_append_ha(v->name, v->value, user->ha);
- } else if (!strcasecmp(v->name, "allowtransfer")) {
- user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
- } else if (!strcasecmp(v->name, "secret")) {
- ast_copy_string(user->secret, v->value, sizeof(user->secret));
- } else if (!strcasecmp(v->name, "md5secret")) {
- ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
- } else if (!strcasecmp(v->name, "callerid")) {
- ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
- } else if (!strcasecmp(v->name, "fullname")) {
- ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
- } else if (!strcasecmp(v->name, "cid_number")) {
- ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
- } else if (!strcasecmp(v->name, "callgroup")) {
- user->callgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "pickupgroup")) {
- user->pickupgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(user->language, v->value, sizeof(user->language));
- } else if (!strcasecmp(v->name, "mohinterpret")
- || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
- } else if (!strcasecmp(v->name, "call-limit")) {
- user->call_limit = atoi(v->value);
- if (user->call_limit < 0)
- user->call_limit = 0;
- } else if (!strcasecmp(v->name, "amaflags")) {
- format = ast_cdr_amaflags2int(v->value);
- if (format < 0) {
- ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
- } else {
- user->amaflags = format;
- }
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
- } else if (!strcasecmp(v->name, "autoframing")) {
- user->autoframing = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callingpres")) {
- user->callingpres = ast_parse_caller_presentation(v->value);
- if (user->callingpres == -1)
- user->callingpres = atoi(v->value);
- } else if (!strcasecmp(v->name, "maxcallbitrate")) {
- user->maxcallbitrate = atoi(v->value);
- if (user->maxcallbitrate < 0)
- user->maxcallbitrate = default_maxcallbitrate;
- }
- /* We can't just report unknown options here because this may be a
- * type=friend entry. All user options are valid for a peer, but not
- * the other way around. */
- }
- ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
- ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
- if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
- global_allowsubscribe = TRUE; /* No global ban any more */
- ast_free_ha(oldha);
- return user;
-}
-
-/*! \brief Set peer defaults before configuring specific configurations */
-static void set_peer_defaults(struct sip_peer *peer)
-{
- if (peer->expire == 0) {
- /* Don't reset expire or port time during reload
- if we have an active registration
- */
- peer->expire = -1;
- peer->pokeexpire = -1;
- peer->addr.sin_port = htons(STANDARD_SIP_PORT);
- }
- ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
- ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
- strcpy(peer->context, default_context);
- strcpy(peer->subscribecontext, default_subscribecontext);
- strcpy(peer->language, default_language);
- strcpy(peer->mohinterpret, default_mohinterpret);
- strcpy(peer->mohsuggest, default_mohsuggest);
- peer->addr.sin_family = AF_INET;
- peer->defaddr.sin_family = AF_INET;
- peer->capability = global_capability;
- peer->maxcallbitrate = default_maxcallbitrate;
- peer->rtptimeout = global_rtptimeout;
- peer->rtpholdtimeout = global_rtpholdtimeout;
- peer->rtpkeepalive = global_rtpkeepalive;
- peer->allowtransfer = global_allowtransfer;
- peer->autoframing = global_autoframing;
- strcpy(peer->vmexten, default_vmexten);
- peer->secret[0] = '\0';
- peer->md5secret[0] = '\0';
- peer->cid_num[0] = '\0';
- peer->cid_name[0] = '\0';
- peer->fromdomain[0] = '\0';
- peer->fromuser[0] = '\0';
- peer->regexten[0] = '\0';
- peer->mailbox[0] = '\0';
- peer->callgroup = 0;
- peer->pickupgroup = 0;
- peer->maxms = default_qualify;
- peer->prefs = default_prefs;
-}
-
-/*! \brief Create temporary peer (used in autocreatepeer mode) */
-static struct sip_peer *temp_peer(const char *name)
-{
- struct sip_peer *peer;
-
- if (!(peer = ast_calloc(1, sizeof(*peer))))
- return NULL;
-
- apeerobjs++;
- ASTOBJ_INIT(peer);
- set_peer_defaults(peer);
-
- ast_copy_string(peer->name, name, sizeof(peer->name));
-
- ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
- ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
- peer->prefs = default_prefs;
- reg_source_db(peer);
-
- return peer;
-}
-
-/*! \brief Build peer from configuration (file or realtime static/dynamic) */
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
-{
- struct sip_peer *peer = NULL;
- struct ast_ha *oldha = NULL;
- int obproxyfound=0;
- int found=0;
- int firstpass=1;
- int format=0; /* Ama flags */
- time_t regseconds = 0;
- char *varname = NULL, *varval = NULL;
- struct ast_variable *tmpvar = NULL;
- struct ast_flags peerflags[2] = {{(0)}};
- struct ast_flags mask[2] = {{(0)}};
-
-
- if (!realtime)
- /* Note we do NOT use find_peer here, to avoid realtime recursion */
- /* We also use a case-sensitive comparison (unlike find_peer) so
- that case changes made to the peer name will be properly handled
- during reload
- */
- peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
-
- if (peer) {
- /* Already in the list, remove it and it will be added back (or FREE'd) */
- found = 1;
- if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
- firstpass = 0;
- } else {
- if (!(peer = ast_calloc(1, sizeof(*peer))))
- return NULL;
-
- if (realtime)
- rpeerobjs++;
- else
- speerobjs++;
- ASTOBJ_INIT(peer);
- }
- /* Note that our peer HAS had its reference count incrased */
- if (firstpass) {
- peer->lastmsgssent = -1;
- oldha = peer->ha;
- peer->ha = NULL;
- set_peer_defaults(peer); /* Set peer defaults */
- }
- if (!found && name)
- ast_copy_string(peer->name, name, sizeof(peer->name));
-
- /* If we have channel variables, remove them (reload) */
- if (peer->chanvars) {
- ast_variables_destroy(peer->chanvars);
- peer->chanvars = NULL;
- /* XXX should unregister ? */
- }
-
- /* If we have realm authentication information, remove them (reload) */
- clear_realm_authentication(peer->auth);
- peer->auth = NULL;
-
- for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
- if (handle_common_options(&peerflags[0], &mask[0], v))
- continue;
- if (realtime && !strcasecmp(v->name, "regseconds")) {
- ast_get_time_t(v->value, &regseconds, 0, NULL);
- } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
- inet_aton(v->value, &(peer->addr.sin_addr));
- } else if (realtime && !strcasecmp(v->name, "name"))
- ast_copy_string(peer->name, v->value, sizeof(peer->name));
- else if (realtime && !strcasecmp(v->name, "fullcontact")) {
- ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact));
- ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
- } else if (!strcasecmp(v->name, "secret"))
- ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
- else if (!strcasecmp(v->name, "md5secret"))
- ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
- else if (!strcasecmp(v->name, "auth"))
- peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
- else if (!strcasecmp(v->name, "callerid")) {
- ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
- } else if (!strcasecmp(v->name, "fullname")) {
- ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
- } else if (!strcasecmp(v->name, "cid_number")) {
- ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(peer->context, v->value, sizeof(peer->context));
- } else if (!strcasecmp(v->name, "subscribecontext")) {
- ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
- } else if (!strcasecmp(v->name, "fromdomain")) {
- ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
- } else if (!strcasecmp(v->name, "usereqphone")) {
- ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
- } else if (!strcasecmp(v->name, "fromuser")) {
- ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
- } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
- if (!strcasecmp(v->value, "dynamic")) {
- if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
- ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
- } else {
- /* They'll register with us */
- if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
- /* Initialize stuff if this is a new peer, or if it used to be
- * non-dynamic before the reload. */
- memset(&peer->addr.sin_addr, 0, 4);
- if (peer->addr.sin_port) {
- /* If we've already got a port, make it the default rather than absolute */
- peer->defaddr.sin_port = peer->addr.sin_port;
- peer->addr.sin_port = 0;
- }
- }
- ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
- }
- } else {
- /* Non-dynamic. Make sure we become that way if we're not */
- if (!AST_SCHED_DEL(sched, peer->expire)) {
- struct sip_peer *peer_ptr = peer;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
- if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
- if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- return NULL;
- }
- }
- if (!strcasecmp(v->name, "outboundproxy"))
- obproxyfound=1;
- else {
- ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
- if (!peer->addr.sin_port)
- peer->addr.sin_port = htons(STANDARD_SIP_PORT);
- }
- }
- } else if (!strcasecmp(v->name, "defaultip")) {
- if (ast_get_ip(&peer->defaddr, v->value)) {
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- return NULL;
- }
- } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
- peer->ha = ast_append_ha(v->name, v->value, peer->ha);
- } else if (!strcasecmp(v->name, "port")) {
- if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
- peer->defaddr.sin_port = htons(atoi(v->value));
- else
- peer->addr.sin_port = htons(atoi(v->value));
- } else if (!strcasecmp(v->name, "callingpres")) {
- peer->callingpres = ast_parse_caller_presentation(v->value);
- if (peer->callingpres == -1)
- peer->callingpres = atoi(v->value);
- } else if (!strcasecmp(v->name, "username")) {
- ast_copy_string(peer->username, v->value, sizeof(peer->username));
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(peer->language, v->value, sizeof(peer->language));
- } else if (!strcasecmp(v->name, "regexten")) {
- ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
- } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
- peer->call_limit = atoi(v->value);
- if (peer->call_limit < 0)
- peer->call_limit = 0;
- } else if (!strcasecmp(v->name, "amaflags")) {
- format = ast_cdr_amaflags2int(v->value);
- if (format < 0) {
- ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
- } else {
- peer->amaflags = format;
- }
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
- } else if (!strcasecmp(v->name, "mohinterpret")
- || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
- } else if (!strcasecmp(v->name, "mailbox")) {
- ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
- } else if (!strcasecmp(v->name, "subscribemwi")) {
- ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
- } else if (!strcasecmp(v->name, "vmexten")) {
- ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
- } else if (!strcasecmp(v->name, "callgroup")) {
- peer->callgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "allowtransfer")) {
- peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
- } else if (!strcasecmp(v->name, "pickupgroup")) {
- peer->pickupgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
- } else if (!strcasecmp(v->name, "autoframing")) {
- peer->autoframing = ast_true(v->value);
- } else if (!strcasecmp(v->name, "rtptimeout")) {
- if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
- peer->rtptimeout = global_rtptimeout;
- }
- } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
- if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
- peer->rtpholdtimeout = global_rtpholdtimeout;
- }
- } else if (!strcasecmp(v->name, "rtpkeepalive")) {
- if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno);
- peer->rtpkeepalive = global_rtpkeepalive;
- }
- } else if (!strcasecmp(v->name, "setvar")) {
- /* Set peer channel variable */
- varname = ast_strdupa(v->value);
- if ((varval = strchr(varname, '='))) {
- *varval++ = '\0';
- if ((tmpvar = ast_variable_new(varname, varval))) {
- tmpvar->next = peer->chanvars;
- peer->chanvars = tmpvar;
- }
- }
- } else if (!strcasecmp(v->name, "qualify")) {
- if (!strcasecmp(v->value, "no")) {
- peer->maxms = 0;
- } else if (!strcasecmp(v->value, "yes")) {
- peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
- } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
- ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
- peer->maxms = 0;
- }
- } else if (!strcasecmp(v->name, "maxcallbitrate")) {
- peer->maxcallbitrate = atoi(v->value);
- if (peer->maxcallbitrate < 0)
- peer->maxcallbitrate = default_maxcallbitrate;
- }
- }
- if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
- time_t nowtime = time(NULL);
-
- if ((nowtime - regseconds) > 0) {
- destroy_association(peer);
- memset(&peer->addr, 0, sizeof(peer->addr));
- if (option_debug)
- ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
- }
- }
- ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
- ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
- global_allowsubscribe = TRUE; /* No global ban any more */
- if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
- reg_source_db(peer);
- ASTOBJ_UNMARK(peer);
- ast_free_ha(oldha);
- return peer;
-}
-
-/*! \brief Re-read SIP.conf config file
-\note This function reloads all config data, except for
- active peers (with registrations). They will only
- change configuration data at restart, not at reload.
- SIP debug and recordhistory state will not change
- */
-static int reload_config(enum channelreloadreason reason)
-{
- struct ast_config *cfg, *ucfg;
- struct ast_variable *v;
- struct sip_peer *peer;
- struct sip_user *user;
- struct ast_hostent ahp;
- char *cat, *stringp, *context, *oldregcontext;
- char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
- struct hostent *hp;
- int format;
- struct ast_flags dummy[2];
- int auto_sip_domains = FALSE;
- struct sockaddr_in old_bindaddr = bindaddr;
- int registry_count = 0, peer_count = 0, user_count = 0;
- unsigned int temp_tos = 0;
- struct ast_flags debugflag = {0};
-
- cfg = ast_config_load(config);
-
- /* We *must* have a config file otherwise stop immediately */
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
- return -1;
- }
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
-
- clear_realm_authentication(authl);
- clear_sip_domains();
- authl = NULL;
-
- /* First, destroy all outstanding registry calls */
- /* This is needed, since otherwise active registry entries will not be destroyed */
- ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->call) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
- /* This will also remove references to the registry */
- sip_destroy(iterator->call);
- }
- ASTOBJ_UNLOCK(iterator);
-
- } while(0));
-
- /* Then, actually destroy users and registry */
- ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
- ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
- ASTOBJ_CONTAINER_MARKALL(&peerl);
-
- /* Initialize copy of current global_regcontext for later use in removing stale contexts */
- ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
- oldregcontext = oldcontexts;
-
- /* Clear all flags before setting default values */
- /* Preserve debugging settings for console */
- ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
- ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
- ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
- ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
-
- /* Reset IP addresses */
- memset(&bindaddr, 0, sizeof(bindaddr));
- ast_free_ha(localaddr);
- memset(&localaddr, 0, sizeof(localaddr));
- memset(&externip, 0, sizeof(externip));
- memset(&default_prefs, 0 , sizeof(default_prefs));
- outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
- outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */
- ourport = STANDARD_SIP_PORT;
- srvlookup = DEFAULT_SRVLOOKUP;
- global_tos_sip = DEFAULT_TOS_SIP;
- global_tos_audio = DEFAULT_TOS_AUDIO;
- global_tos_video = DEFAULT_TOS_VIDEO;
- externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */
- externexpire = 0; /* Expiration for DNS re-issuing */
- externrefresh = 10;
- memset(&outboundproxyip, 0, sizeof(outboundproxyip));
-
- /* Reset channel settings to default before re-configuring */
- allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */
- global_regcontext[0] = '\0';
- expiry = DEFAULT_EXPIRY;
- global_notifyringing = DEFAULT_NOTIFYRINGING;
- global_limitonpeers = FALSE;
- global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */
- global_notifyhold = FALSE;
- global_alwaysauthreject = 0;
- global_allowsubscribe = FALSE;
- ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
- ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
- if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
- ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
- else
- ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
- ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
- compactheaders = DEFAULT_COMPACTHEADERS;
- global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
- global_regattempts_max = 0;
- pedanticsipchecking = DEFAULT_PEDANTIC;
- global_mwitime = DEFAULT_MWITIME;
- autocreatepeer = DEFAULT_AUTOCREATEPEER;
- global_autoframing = 0;
- global_allowguest = DEFAULT_ALLOWGUEST;
- global_rtptimeout = 0;
- global_rtpholdtimeout = 0;
- global_rtpkeepalive = 0;
- global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */
- global_rtautoclear = 120;
- ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */
- ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */
- ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
-
- /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
- ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
- default_subscribecontext[0] = '\0';
- default_language[0] = '\0';
- default_fromdomain[0] = '\0';
- default_qualify = DEFAULT_QUALIFY;
- default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
- ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
- ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
- ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
- ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
- ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */
- ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */
-
- /* Debugging settings, always default to off */
- dumphistory = FALSE;
- recordhistory = FALSE;
- ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
-
- /* Misc settings for the channel */
- global_relaxdtmf = FALSE;
- global_callevents = FALSE;
- global_t1min = DEFAULT_T1MIN;
-
- global_matchexterniplocally = FALSE;
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
-
- /* Read the [general] config section of sip.conf (or from realtime config) */
- for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
- if (handle_common_options(&global_flags[0], &dummy[0], v))
- continue;
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
- continue;
-
- /* Create the interface list */
- if (!strcasecmp(v->name, "context")) {
- ast_copy_string(default_context, v->value, sizeof(default_context));
- } else if (!strcasecmp(v->name, "subscribecontext")) {
- ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
- } else if (!strcasecmp(v->name, "allowguest")) {
- global_allowguest = ast_true(v->value) ? 1 : 0;
- } else if (!strcasecmp(v->name, "realm")) {
- ast_copy_string(global_realm, v->value, sizeof(global_realm));
- } else if (!strcasecmp(v->name, "useragent")) {
- ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
- } else if (!strcasecmp(v->name, "allowtransfer")) {
- global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
- } else if (!strcasecmp(v->name, "rtcachefriends")) {
- ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);
- } else if (!strcasecmp(v->name, "rtsavesysname")) {
- ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);
- } else if (!strcasecmp(v->name, "rtupdate")) {
- ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);
- } else if (!strcasecmp(v->name, "ignoreregexpire")) {
- ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);
- } else if (!strcasecmp(v->name, "t1min")) {
- global_t1min = atoi(v->value);
- } else if (!strcasecmp(v->name, "rtautoclear")) {
- int i = atoi(v->value);
- if (i > 0)
- global_rtautoclear = i;
- else
- i = 0;
- ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
- } else if (!strcasecmp(v->name, "usereqphone")) {
- ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);
- } else if (!strcasecmp(v->name, "relaxdtmf")) {
- global_relaxdtmf = ast_true(v->value);
- } else if (!strcasecmp(v->name, "checkmwi")) {
- if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno);
- global_mwitime = DEFAULT_MWITIME;
- }
- } else if (!strcasecmp(v->name, "vmexten")) {
- ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
- } else if (!strcasecmp(v->name, "rtptimeout")) {
- if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
- global_rtptimeout = 0;
- }
- } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
- if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno);
- global_rtpholdtimeout = 0;
- }
- } else if (!strcasecmp(v->name, "rtpkeepalive")) {
- if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
- ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno);
- global_rtpkeepalive = 0;
- }
- } else if (!strcasecmp(v->name, "compactheaders")) {
- compactheaders = ast_true(v->value);
- } else if (!strcasecmp(v->name, "notifymimetype")) {
- ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
- } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
- global_limitonpeers = ast_true(v->value);
- } else if (!strcasecmp(v->name, "directrtpsetup")) {
- global_directrtpsetup = ast_true(v->value);
- } else if (!strcasecmp(v->name, "notifyringing")) {
- global_notifyringing = ast_true(v->value);
- } else if (!strcasecmp(v->name, "notifyhold")) {
- global_notifyhold = ast_true(v->value);
- } else if (!strcasecmp(v->name, "alwaysauthreject")) {
- global_alwaysauthreject = ast_true(v->value);
- } else if (!strcasecmp(v->name, "mohinterpret")
- || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(default_language, v->value, sizeof(default_language));
- } else if (!strcasecmp(v->name, "regcontext")) {
- ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
- stringp = newcontexts;
- /* Let's remove any contexts that are no longer defined in regcontext */
- cleanup_stale_contexts(stringp, oldregcontext);
- /* Create contexts if they don't exist already */
- while ((context = strsep(&stringp, "&"))) {
- if (!ast_context_find(context))
- ast_context_create(NULL, context,"SIP");
- }
- ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
- } else if (!strcasecmp(v->name, "callerid")) {
- ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
- } else if (!strcasecmp(v->name, "fromdomain")) {
- ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
- } else if (!strcasecmp(v->name, "outboundproxy")) {
- if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
- ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
- } else if (!strcasecmp(v->name, "outboundproxyport")) {
- /* Port needs to be after IP */
- sscanf(v->value, "%d", &format);
- outboundproxyip.sin_port = htons(format);
- } else if (!strcasecmp(v->name, "autocreatepeer")) {
- autocreatepeer = ast_true(v->value);
- } else if (!strcasecmp(v->name, "srvlookup")) {
- srvlookup = ast_true(v->value);
- } else if (!strcasecmp(v->name, "pedantic")) {
- pedanticsipchecking = ast_true(v->value);
- } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
- max_expiry = atoi(v->value);
- if (max_expiry < 1)
- max_expiry = DEFAULT_MAX_EXPIRY;
- } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
- min_expiry = atoi(v->value);
- if (min_expiry < 1)
- min_expiry = DEFAULT_MIN_EXPIRY;
- } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
- default_expiry = atoi(v->value);
- if (default_expiry < 1)
- default_expiry = DEFAULT_DEFAULT_EXPIRY;
- } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */
- if (ast_true(v->value))
- ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
- } else if (!strcasecmp(v->name, "dumphistory")) {
- dumphistory = ast_true(v->value);
- } else if (!strcasecmp(v->name, "recordhistory")) {
- recordhistory = ast_true(v->value);
- } else if (!strcasecmp(v->name, "registertimeout")) {
- global_reg_timeout = atoi(v->value);
- if (global_reg_timeout < 1)
- global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
- } else if (!strcasecmp(v->name, "registerattempts")) {
- global_regattempts_max = atoi(v->value);
- } else if (!strcasecmp(v->name, "bindaddr")) {
- if (!(hp = ast_gethostbyname(v->value, &ahp))) {
- ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
- } else {
- memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
- }
- } else if (!strcasecmp(v->name, "localnet")) {
- struct ast_ha *na;
- if (!(na = ast_append_ha("d", v->value, localaddr)))
- ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
- else
- localaddr = na;
- } else if (!strcasecmp(v->name, "localmask")) {
- ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
- } else if (!strcasecmp(v->name, "externip")) {
- if (!(hp = ast_gethostbyname(v->value, &ahp)))
- ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
- else
- memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
- externexpire = 0;
- } else if (!strcasecmp(v->name, "externhost")) {
- ast_copy_string(externhost, v->value, sizeof(externhost));
- if (!(hp = ast_gethostbyname(externhost, &ahp)))
- ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
- else
- memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
- externexpire = time(NULL);
- } else if (!strcasecmp(v->name, "externrefresh")) {
- if (sscanf(v->value, "%d", &externrefresh) != 1) {
- ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
- externrefresh = 10;
- }
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
- } else if (!strcasecmp(v->name, "autoframing")) {
- global_autoframing = ast_true(v->value);
- } else if (!strcasecmp(v->name, "allowexternaldomains")) {
- allow_external_domains = ast_true(v->value);
- } else if (!strcasecmp(v->name, "autodomain")) {
- auto_sip_domains = ast_true(v->value);
- } else if (!strcasecmp(v->name, "domain")) {
- char *domain = ast_strdupa(v->value);
- char *context = strchr(domain, ',');
-
- if (context)
- *context++ = '\0';
-
- if (option_debug && ast_strlen_zero(context))
- ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
- if (ast_strlen_zero(domain))
- ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
- else
- add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
- } else if (!strcasecmp(v->name, "register")) {
- if (sip_register(v->value, v->lineno) == 0)
- registry_count++;
- } else if (!strcasecmp(v->name, "tos")) {
- if (!ast_str2tos(v->value, &temp_tos)) {
- global_tos_sip = temp_tos;
- global_tos_audio = temp_tos;
- global_tos_video = temp_tos;
- ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno);
- } else
- ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
- } else if (!strcasecmp(v->name, "tos_sip")) {
- if (ast_str2tos(v->value, &global_tos_sip))
- ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
- } else if (!strcasecmp(v->name, "tos_audio")) {
- if (ast_str2tos(v->value, &global_tos_audio))
- ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
- } else if (!strcasecmp(v->name, "tos_video")) {
- if (ast_str2tos(v->value, &global_tos_video))
- ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
- } else if (!strcasecmp(v->name, "bindport")) {
- if (sscanf(v->value, "%d", &ourport) == 1) {
- bindaddr.sin_port = htons(ourport);
- } else {
- ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
- }
- } else if (!strcasecmp(v->name, "qualify")) {
- if (!strcasecmp(v->value, "no")) {
- default_qualify = 0;
- } else if (!strcasecmp(v->value, "yes")) {
- default_qualify = DEFAULT_MAXMS;
- } else if (sscanf(v->value, "%d", &default_qualify) != 1) {
- ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
- default_qualify = 0;
- }
- } else if (!strcasecmp(v->name, "callevents")) {
- global_callevents = ast_true(v->value);
- } else if (!strcasecmp(v->name, "maxcallbitrate")) {
- default_maxcallbitrate = atoi(v->value);
- if (default_maxcallbitrate < 0)
- default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
- } else if (!strcasecmp(v->name, "matchexterniplocally")) {
- global_matchexterniplocally = ast_true(v->value);
- }
- }
-
- if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
- ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
- allow_external_domains = 1;
- }
-
- /* Build list of authentication to various SIP realms, i.e. service providers */
- for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
- /* Format for authentication is auth = username:password@realm */
- if (!strcasecmp(v->name, "auth"))
- authl = add_realm_authentication(authl, v->value, v->lineno);
- }
-
- ucfg = ast_config_load("users.conf");
- if (ucfg) {
- struct ast_variable *gen;
- int genhassip, genregistersip;
- const char *hassip, *registersip;
-
- genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
- genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
- gen = ast_variable_browse(ucfg, "general");
- cat = ast_category_browse(ucfg, NULL);
- while (cat) {
- if (strcasecmp(cat, "general")) {
- hassip = ast_variable_retrieve(ucfg, cat, "hassip");
- registersip = ast_variable_retrieve(ucfg, cat, "registersip");
- if (ast_true(hassip) || (!hassip && genhassip)) {
- user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
- if (user) {
- ASTOBJ_CONTAINER_LINK(&userl,user);
- ASTOBJ_UNREF(user, sip_destroy_user);
- user_count++;
- }
- peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
- if (peer) {
- ast_device_state_changed("SIP/%s", peer->name);
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- peer_count++;
- }
- }
- if (ast_true(registersip) || (!registersip && genregistersip)) {
- char tmp[256];
- const char *host = ast_variable_retrieve(ucfg, cat, "host");
- const char *username = ast_variable_retrieve(ucfg, cat, "username");
- const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
- const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
- if (!host)
- host = ast_variable_retrieve(ucfg, "general", "host");
- if (!username)
- username = ast_variable_retrieve(ucfg, "general", "username");
- if (!secret)
- secret = ast_variable_retrieve(ucfg, "general", "secret");
- if (!contact)
- contact = "s";
- if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
- if (!ast_strlen_zero(secret))
- snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
- else
- snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
- if (sip_register(tmp, 0) == 0)
- registry_count++;
- }
- }
- }
- cat = ast_category_browse(ucfg, cat);
- }
- ast_config_destroy(ucfg);
- }
-
-
- /* Load peers, users and friends */
- cat = NULL;
- while ( (cat = ast_category_browse(cfg, cat)) ) {
- const char *utype;
- if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
- continue;
- utype = ast_variable_retrieve(cfg, cat, "type");
- if (!utype) {
- ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
- continue;
- } else {
- int is_user = 0, is_peer = 0;
- if (!strcasecmp(utype, "user"))
- is_user = 1;
- else if (!strcasecmp(utype, "friend"))
- is_user = is_peer = 1;
- else if (!strcasecmp(utype, "peer"))
- is_peer = 1;
- else {
- ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
- continue;
- }
- if (is_user) {
- user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (user) {
- ASTOBJ_CONTAINER_LINK(&userl,user);
- ASTOBJ_UNREF(user, sip_destroy_user);
- user_count++;
- }
- }
- if (is_peer) {
- peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
- ASTOBJ_UNREF(peer, sip_destroy_peer);
- peer_count++;
- }
- }
- }
- }
- if (ast_find_ourip(&__ourip, bindaddr)) {
- ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
- ast_config_destroy(cfg);
- return 0;
- }
- if (!ntohs(bindaddr.sin_port))
- bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
- bindaddr.sin_family = AF_INET;
- ast_mutex_lock(&netlock);
- if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
- close(sipsock);
- sipsock = -1;
- }
- if (sipsock < 0) {
- sipsock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sipsock < 0) {
- ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
- ast_config_destroy(cfg);
- return -1;
- } else {
- /* Allow SIP clients on the same host to access us: */
- const int reuseFlag = 1;
-
- setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&reuseFlag,
- sizeof reuseFlag);
-
- ast_enable_packet_fragmentation(sipsock);
-
- if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
- ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
- strerror(errno));
- close(sipsock);
- sipsock = -1;
- } else {
- if (option_verbose > 1) {
- ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
- ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
- }
- if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip)))
- ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
- }
- }
- }
- ast_mutex_unlock(&netlock);
-
- /* Add default domains - host name, IP address and IP:port */
- /* Only do this if user added any sip domain with "localdomains" */
- /* In order to *not* break backwards compatibility */
- /* Some phones address us at IP only, some with additional port number */
- if (auto_sip_domains) {
- char temp[MAXHOSTNAMELEN];
-
- /* First our default IP address */
- if (bindaddr.sin_addr.s_addr)
- add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
- else
- ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
-
- /* Our extern IP address, if configured */
- if (externip.sin_addr.s_addr)
- add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
-
- /* Extern host name (NAT traversal support) */
- if (!ast_strlen_zero(externhost))
- add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
-
- /* Our host name */
- if (!gethostname(temp, sizeof(temp)))
- add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
- }
-
- /* Release configuration from memory */
- ast_config_destroy(cfg);
-
- /* Load the list of manual NOTIFY types to support */
- if (notify_types)
- ast_config_destroy(notify_types);
- notify_types = ast_config_load(notify_config);
-
- /* Done, tell the manager */
- manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count);
-
- return 0;
-}
-
-static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan)
-{
- struct sip_pvt *p;
- struct ast_udptl *udptl = NULL;
-
- p = chan->tech_pvt;
- if (!p)
- return NULL;
-
- ast_mutex_lock(&p->lock);
- if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
- udptl = p->udptl;
- ast_mutex_unlock(&p->lock);
- return udptl;
-}
-
-static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
-{
- struct sip_pvt *p;
-
- p = chan->tech_pvt;
- if (!p)
- return -1;
- ast_mutex_lock(&p->lock);
- if (udptl)
- ast_udptl_get_peer(udptl, &p->udptlredirip);
- else
- memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
- if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
- if (!p->pendinginvite) {
- if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
- }
- transmit_reinvite_with_t38_sdp(p);
- } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
- }
- ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
- }
- }
- /* Reset lastrtprx timer */
- p->lastrtprx = p->lastrtptx = time(NULL);
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-/*! \brief Handle T38 reinvite
- \todo Make sure we don't destroy the call if we can't handle the re-invite.
- Nothing should be changed until we have processed the SDP and know that we
- can handle it.
-*/
-static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
-{
- struct sip_pvt *p;
- int flag = 0;
-
- p = chan->tech_pvt;
- if (!p || !pvt->udptl)
- return -1;
-
- /* Setup everything on the other side like offered/responded from first side */
- ast_mutex_lock(&p->lock);
-
- /*! \todo check if this is not set earlier when setting up the PVT. If not
- maybe it should move there. */
- p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
-
- ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
- ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
- ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
-
- if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */
- /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
- not really T38 re-invites which are different. In this
- case it's used properly, to see if we can reinvite over
- NAT
- */
- if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
- ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
- flag =1;
- } else {
- memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
- }
- if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
- if (!p->pendinginvite) {
- if (option_debug > 2) {
- if (flag)
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
- else
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
- }
- transmit_reinvite_with_t38_sdp(p);
- } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- if (option_debug > 2) {
- if (flag)
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
- else
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
- }
- ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
- }
- }
- /* Reset lastrtprx timer */
- p->lastrtprx = p->lastrtptx = time(NULL);
- ast_mutex_unlock(&p->lock);
- return 0;
- } else { /* If we are handling sending 200 OK to the other side of the bridge */
- if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
- ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
- flag = 1;
- } else {
- memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
- }
- if (option_debug > 2) {
- if (flag)
- ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
- else
- ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
- }
- pvt->t38.state = T38_ENABLED;
- p->t38.state = T38_ENABLED;
- if (option_debug > 1) {
- ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
- ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
- }
- transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
- p->lastrtprx = p->lastrtptx = time(NULL);
- ast_mutex_unlock(&p->lock);
- return 0;
- }
-}
-
-
-/*! \brief Returns null if we can't reinvite audio (part of RTP interface) */
-static enum ast_rtp_get_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
-{
- struct sip_pvt *p = NULL;
- enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
-
- if (!(p = chan->tech_pvt))
- return AST_RTP_GET_FAILED;
-
- ast_mutex_lock(&p->lock);
- if (!(p->rtp)) {
- ast_mutex_unlock(&p->lock);
- return AST_RTP_GET_FAILED;
- }
-
- *rtp = p->rtp;
-
- if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
- res = AST_RTP_TRY_PARTIAL;
- else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
- res = AST_RTP_TRY_NATIVE;
- else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
- res = AST_RTP_GET_FAILED;
-
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-/*! \brief Returns null if we can't reinvite video (part of RTP interface) */
-static enum ast_rtp_get_result sip_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
-{
- struct sip_pvt *p = NULL;
- enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
-
- if (!(p = chan->tech_pvt))
- return AST_RTP_GET_FAILED;
-
- ast_mutex_lock(&p->lock);
- if (!(p->vrtp)) {
- ast_mutex_unlock(&p->lock);
- return AST_RTP_GET_FAILED;
- }
-
- *rtp = p->vrtp;
-
- if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
- res = AST_RTP_TRY_NATIVE;
-
- ast_mutex_unlock(&p->lock);
-
- return res;
-}
-
-/*! \brief Set the RTP peer for this call */
-static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
-{
- struct sip_pvt *p;
- int changed = 0;
-
- p = chan->tech_pvt;
- if (!p)
- return -1;
-
- /* Disable early RTP bridge */
- if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */
- return 0;
-
- ast_mutex_lock(&p->lock);
- if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
- /* If we're destroyed, don't bother */
- ast_mutex_unlock(&p->lock);
- return 0;
- }
-
- /* if this peer cannot handle reinvites of the media stream to devices
- that are known to be behind a NAT, then stop the process now
- */
- if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
- ast_mutex_unlock(&p->lock);
- return 0;
- }
-
- if (rtp) {
- changed |= ast_rtp_get_peer(rtp, &p->redirip);
- } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
- memset(&p->redirip, 0, sizeof(p->redirip));
- changed = 1;
- }
- if (vrtp) {
- changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
- } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
- memset(&p->vredirip, 0, sizeof(p->vredirip));
- changed = 1;
- }
- if (codecs) {
- if ((p->redircodecs != codecs)) {
- p->redircodecs = codecs;
- changed = 1;
- }
- if ((p->capability & codecs) != p->capability) {
- p->jointcapability &= codecs;
- p->capability &= codecs;
- changed = 1;
- }
- }
- if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
- if (chan->_state != AST_STATE_UP) { /* We are in early state */
- if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
- append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
- if (option_debug)
- ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
- } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */
- if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
- }
- transmit_reinvite_with_sdp(p);
- } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
- }
- /* We have a pending Invite. Send re-invite when we're done with the invite */
- ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
- }
- }
- /* Reset lastrtprx timer */
- p->lastrtprx = p->lastrtptx = time(NULL);
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static char *synopsis_dtmfmode = "Change the dtmfmode for a SIP call";
-static char *descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n";
-static char *app_dtmfmode = "SIPDtmfMode";
-
-static char *app_sipaddheader = "SIPAddHeader";
-static char *synopsis_sipaddheader = "Add a SIP header to the outbound call";
-
-static char *descrip_sipaddheader = ""
-" SIPAddHeader(Header: Content)\n"
-"Adds a header to a SIP call placed with DIAL.\n"
-"Remember to user the X-header if you are adding non-standard SIP\n"
-"headers, like \"X-Asterisk-Accountcode:\". Use this with care.\n"
-"Adding the wrong headers may jeopardize the SIP dialog.\n"
-"Always returns 0\n";
-
-
-/*! \brief Set the DTMFmode for an outbound SIP call (application) */
-static int sip_dtmfmode(struct ast_channel *chan, void *data)
-{
- struct sip_pvt *p;
- char *mode;
- if (data)
- mode = (char *)data;
- else {
- ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
- return 0;
- }
- ast_channel_lock(chan);
- if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
- ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
- ast_channel_unlock(chan);
- return 0;
- }
- p = chan->tech_pvt;
- if (!p) {
- ast_channel_unlock(chan);
- return 0;
- }
- ast_mutex_lock(&p->lock);
- if (!strcasecmp(mode,"info")) {
- ast_clear_flag(&p->flags[0], SIP_DTMF);
- ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
- p->jointnoncodeccapability &= ~AST_RTP_DTMF;
- } else if (!strcasecmp(mode,"rfc2833")) {
- ast_clear_flag(&p->flags[0], SIP_DTMF);
- ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
- p->jointnoncodeccapability |= AST_RTP_DTMF;
- } else if (!strcasecmp(mode,"inband")) {
- ast_clear_flag(&p->flags[0], SIP_DTMF);
- ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
- p->jointnoncodeccapability &= ~AST_RTP_DTMF;
- } else
- ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
- if (p->rtp)
- ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
- if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
- if (!p->vad) {
- p->vad = ast_dsp_new();
- ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
- }
- } else {
- if (p->vad) {
- ast_dsp_free(p->vad);
- p->vad = NULL;
- }
- }
- ast_mutex_unlock(&p->lock);
- ast_channel_unlock(chan);
- return 0;
-}
-
-/*! \brief Add a SIP header to an outbound INVITE */
-static int sip_addheader(struct ast_channel *chan, void *data)
-{
- int no = 0;
- int ok = FALSE;
- char varbuf[30];
- char *inbuf = (char *) data;
-
- if (ast_strlen_zero(inbuf)) {
- ast_log(LOG_WARNING, "This application requires the argument: Header\n");
- return 0;
- }
- ast_channel_lock(chan);
-
- /* Check for headers */
- while (!ok && no <= 50) {
- no++;
- snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
-
- /* Compare without the leading underscore */
- if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) )
- ok = TRUE;
- }
- if (ok) {
- pbx_builtin_setvar_helper (chan, varbuf, inbuf);
- if (sipdebug)
- ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
- } else {
- ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
- }
- ast_channel_unlock(chan);
- return 0;
-}
-
-/*! \brief Transfer call before connect with a 302 redirect
-\note Called by the transfer() dialplan application through the sip_transfer()
- pbx interface function if the call is in ringing state
-\todo Fix this function so that we wait for reply to the REFER and
- react to errors, denials or other issues the other end might have.
- */
-static int sip_sipredirect(struct sip_pvt *p, const char *dest)
-{
- char *cdest;
- char *extension, *host, *port;
- char tmp[80];
-
- cdest = ast_strdupa(dest);
-
- extension = strsep(&cdest, "@");
- host = strsep(&cdest, ":");
- port = strsep(&cdest, ":");
- if (ast_strlen_zero(extension)) {
- ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
- return 0;
- }
-
- /* we'll issue the redirect message here */
- if (!host) {
- char *localtmp;
- ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
- if (ast_strlen_zero(tmp)) {
- ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
- return 0;
- }
- if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
- char lhost[80], lport[80];
- memset(lhost, 0, sizeof(lhost));
- memset(lport, 0, sizeof(lport));
- localtmp++;
- /* This is okey because lhost and lport are as big as tmp */
- sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
- if (ast_strlen_zero(lhost)) {
- ast_log(LOG_ERROR, "Can't find the host address\n");
- return 0;
- }
- host = ast_strdupa(lhost);
- if (!ast_strlen_zero(lport)) {
- port = ast_strdupa(lport);
- }
- }
- }
-
- ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
- transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
-
- sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */
- sip_alreadygone(p);
- return 0;
-}
-
-/*! \brief Return SIP UA's codec (part of the RTP interface) */
-static int sip_get_codec(struct ast_channel *chan)
-{
- struct sip_pvt *p = chan->tech_pvt;
- return p->peercapability ? p->peercapability : p->capability;
-}
-
-/*! \brief Send a poke to all known peers
- Space them out 100 ms apart
- XXX We might have a cool algorithm for this or use random - any suggestions?
-*/
-static void sip_poke_all_peers(void)
-{
- int ms = 0;
-
- if (!speerobjs) /* No peers, just give up */
- return;
-
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_WRLOCK(iterator);
- if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
- struct sip_peer *peer_ptr = iterator;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- ms += 100;
- iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator));
- if (iterator->pokeexpire == -1) {
- struct sip_peer *peer_ptr = iterator;
- ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
- }
- ASTOBJ_UNLOCK(iterator);
- } while (0)
- );
-}
-
-/*! \brief Send all known registrations */
-static void sip_send_all_registers(void)
-{
- int ms;
- int regspacing;
- if (!regobjs)
- return;
- regspacing = default_expiry * 1000/regobjs;
- if (regspacing > 100)
- regspacing = 100;
- ms = regspacing;
- ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
- ASTOBJ_WRLOCK(iterator);
- AST_SCHED_DEL(sched, iterator->expire);
- ms += regspacing;
- iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
- ASTOBJ_UNLOCK(iterator);
- } while (0)
- );
-}
-
-/*! \brief Reload module */
-static int sip_do_reload(enum channelreloadreason reason)
-{
- reload_config(reason);
-
- /* Prune peers who still are supposed to be deleted */
- ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
-
- /* Send qualify (OPTIONS) to all peers */
- sip_poke_all_peers();
-
- /* Register with all services */
- sip_send_all_registers();
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
-
- return 0;
-}
-
-/*! \brief Force reload of module from cli */
-static int sip_reload(int fd, int argc, char *argv[])
-{
- ast_mutex_lock(&sip_reload_lock);
- if (sip_reloading)
- ast_verbose("Previous SIP reload not yet done\n");
- else {
- sip_reloading = TRUE;
- if (fd)
- sip_reloadreason = CHANNEL_CLI_RELOAD;
- else
- sip_reloadreason = CHANNEL_MODULE_RELOAD;
- }
- ast_mutex_unlock(&sip_reload_lock);
- restart_monitor();
-
- return 0;
-}
-
-/*! \brief Part of Asterisk module interface */
-static int reload(void)
-{
- return sip_reload(0, 0, NULL);
-}
-
-static struct ast_cli_entry cli_sip_debug_deprecated =
- { { "sip", "debug", NULL },
- sip_do_debug_deprecated, "Enable SIP debugging",
- debug_usage };
-
-static struct ast_cli_entry cli_sip_no_debug_deprecated =
- { { "sip", "no", "debug", NULL },
- sip_no_debug_deprecated, "Disable SIP debugging",
- debug_usage };
-
-static struct ast_cli_entry cli_sip[] = {
- { { "sip", "show", "channels", NULL },
- sip_show_channels, "List active SIP channels",
- show_channels_usage },
-
- { { "sip", "show", "domains", NULL },
- sip_show_domains, "List our local SIP domains.",
- show_domains_usage },
-
- { { "sip", "show", "inuse", NULL },
- sip_show_inuse, "List all inuse/limits",
- show_inuse_usage },
-
- { { "sip", "show", "objects", NULL },
- sip_show_objects, "List all SIP object allocations",
- show_objects_usage },
-
- { { "sip", "show", "peers", NULL },
- sip_show_peers, "List defined SIP peers",
- show_peers_usage },
-
- { { "sip", "show", "registry", NULL },
- sip_show_registry, "List SIP registration status",
- show_reg_usage },
-
- { { "sip", "show", "settings", NULL },
- sip_show_settings, "Show SIP global settings",
- show_settings_usage },
-
- { { "sip", "show", "subscriptions", NULL },
- sip_show_subscriptions, "List active SIP subscriptions",
- show_subscriptions_usage },
-
- { { "sip", "show", "users", NULL },
- sip_show_users, "List defined SIP users",
- show_users_usage },
-
- { { "sip", "notify", NULL },
- sip_notify, "Send a notify packet to a SIP peer",
- notify_usage, complete_sipnotify },
-
- { { "sip", "show", "channel", NULL },
- sip_show_channel, "Show detailed SIP channel info",
- show_channel_usage, complete_sipch },
-
- { { "sip", "show", "history", NULL },
- sip_show_history, "Show SIP dialog history",
- show_history_usage, complete_sipch },
-
- { { "sip", "show", "peer", NULL },
- sip_show_peer, "Show details on specific SIP peer",
- show_peer_usage, complete_sip_show_peer },
-
- { { "sip", "show", "user", NULL },
- sip_show_user, "Show details on specific SIP user",
- show_user_usage, complete_sip_show_user },
-
- { { "sip", "prune", "realtime", NULL },
- sip_prune_realtime, "Prune cached Realtime object(s)",
- prune_realtime_usage },
-
- { { "sip", "prune", "realtime", "peer", NULL },
- sip_prune_realtime, "Prune cached Realtime peer(s)",
- prune_realtime_usage, complete_sip_prune_realtime_peer },
-
- { { "sip", "prune", "realtime", "user", NULL },
- sip_prune_realtime, "Prune cached Realtime user(s)",
- prune_realtime_usage, complete_sip_prune_realtime_user },
-
- { { "sip", "set", "debug", NULL },
- sip_do_debug, "Enable SIP debugging",
- debug_usage, NULL, &cli_sip_debug_deprecated },
-
- { { "sip", "set", "debug", "ip", NULL },
- sip_do_debug, "Enable SIP debugging on IP",
- debug_usage },
-
- { { "sip", "set", "debug", "peer", NULL },
- sip_do_debug, "Enable SIP debugging on Peername",
- debug_usage, complete_sip_debug_peer },
-
- { { "sip", "set", "debug", "off", NULL },
- sip_no_debug, "Disable SIP debugging",
- no_debug_usage, NULL, &cli_sip_no_debug_deprecated },
-
- { { "sip", "history", NULL },
- sip_do_history, "Enable SIP history",
- history_usage },
-
- { { "sip", "history", "off", NULL },
- sip_no_history, "Disable SIP history",
- no_history_usage },
-
- { { "sip", "reload", NULL },
- sip_reload, "Reload SIP configuration",
- sip_reload_usage },
-};
-
-/*! \brief PBX load module - initialization */
-static int load_module(void)
-{
- ASTOBJ_CONTAINER_INIT(&userl); /* User object list */
- ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */
- ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
-
- if (!(sched = sched_context_create())) {
- ast_log(LOG_ERROR, "Unable to create scheduler context\n");
- return AST_MODULE_LOAD_FAILURE;
- }
-
- if (!(io = io_context_create())) {
- ast_log(LOG_ERROR, "Unable to create I/O context\n");
- sched_context_destroy(sched);
- return AST_MODULE_LOAD_FAILURE;
- }
-
- sip_reloadreason = CHANNEL_MODULE_LOAD;
-
- if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
- return AST_MODULE_LOAD_DECLINE;
-
- /* Make sure we can register our sip channel type */
- if (ast_channel_register(&sip_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
- io_context_destroy(io);
- sched_context_destroy(sched);
- return AST_MODULE_LOAD_FAILURE;
- }
-
- /* Register all CLI functions for SIP */
- ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
-
- /* Tell the RTP subdriver that we're here */
- ast_rtp_proto_register(&sip_rtp);
-
- /* Tell the UDPTL subdriver that we're here */
- ast_udptl_proto_register(&sip_udptl);
-
- /* Register dialplan applications */
- ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
- ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
-
- /* Register dialplan functions */
- ast_custom_function_register(&sip_header_function);
- ast_custom_function_register(&sippeer_function);
- ast_custom_function_register(&sipchaninfo_function);
- ast_custom_function_register(&checksipdomain_function);
-
- /* Register manager commands */
- ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
- "List SIP peers (text format)", mandescr_show_peers);
- ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
- "Show SIP peer (text format)", mandescr_show_peer);
-
- sip_poke_all_peers();
- sip_send_all_registers();
-
- /* And start the monitor for the first time */
- restart_monitor();
-
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-/*! \brief PBX unload module API */
-static int unload_module(void)
-{
- struct sip_pvt *p, *pl;
-
- /* First, take us out of the channel type list */
- ast_channel_unregister(&sip_tech);
-
- /* Unregister dial plan functions */
- ast_custom_function_unregister(&sipchaninfo_function);
- ast_custom_function_unregister(&sippeer_function);
- ast_custom_function_unregister(&sip_header_function);
- ast_custom_function_unregister(&checksipdomain_function);
-
- /* Unregister dial plan applications */
- ast_unregister_application(app_dtmfmode);
- ast_unregister_application(app_sipaddheader);
-
- /* Unregister CLI commands */
- ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
-
- /* Disconnect from the RTP subsystem */
- ast_rtp_proto_unregister(&sip_rtp);
-
- /* Disconnect from UDPTL */
- ast_udptl_proto_unregister(&sip_udptl);
-
- /* Unregister AMI actions */
- ast_manager_unregister("SIPpeers");
- ast_manager_unregister("SIPshowpeer");
-
- ast_mutex_lock(&iflock);
- /* Hangup all interfaces if they have an owner */
- for (p = iflist; p ; p = p->next) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- }
- ast_mutex_unlock(&iflock);
-
- ast_mutex_lock(&monlock);
- if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
- pthread_cancel(monitor_thread);
- pthread_kill(monitor_thread, SIGURG);
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
-
-restartdestroy:
- ast_mutex_lock(&iflock);
- /* Destroy all the interfaces and free their memory */
- p = iflist;
- while (p) {
- pl = p;
- p = p->next;
- if (__sip_destroy(pl, TRUE) < 0) {
- /* Something is still bridged, let it react to getting a hangup */
- iflist = p;
- ast_mutex_unlock(&iflock);
- usleep(1);
- goto restartdestroy;
- }
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
-
- /* Free memory for local network address mask */
- ast_free_ha(localaddr);
-
- ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
- ASTOBJ_CONTAINER_DESTROY(&userl);
- ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
- ASTOBJ_CONTAINER_DESTROY(&peerl);
- ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
- ASTOBJ_CONTAINER_DESTROY(&regl);
-
- clear_realm_authentication(authl);
- clear_sip_domains();
- close(sipsock);
- sched_context_destroy(sched);
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Session Initiation Protocol (SIP)",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/channels/chan_skinny.c b/1.4/channels/chan_skinny.c
deleted file mode 100644
index d1ef0d6dd..000000000
--- a/1.4/channels/chan_skinny.c
+++ /dev/null
@@ -1,5008 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * chan_skinny was developed by Jeremy McNamara & Florian Overkamp
- * chan_skinny was heavily modified/fixed by North Antara
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Implementation of the Skinny protocol
- *
- * \author Jeremy McNamara & Florian Overkamp & North Antara
- * \ingroup channel_drivers
- */
-
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <sys/signal.h>
-#include <signal.h>
-#include <ctype.h>
-
-#include "asterisk/lock.h"
-#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/lock.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/rtp.h"
-#include "asterisk/acl.h"
-#include "asterisk/callerid.h"
-#include "asterisk/cli.h"
-#include "asterisk/say.h"
-#include "asterisk/cdr.h"
-#include "asterisk/astdb.h"
-#include "asterisk/features.h"
-#include "asterisk/app.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/utils.h"
-#include "asterisk/dsp.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/astobj.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/threadstorage.h"
-
-/*************************************
- * Skinny/Asterisk Protocol Settings *
- *************************************/
-static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
-static const char config[] = "skinny.conf";
-
-static int default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW;
-static struct ast_codec_pref default_prefs;
-
-enum skinny_codecs {
- SKINNY_CODEC_ALAW = 2,
- SKINNY_CODEC_ULAW = 4,
- SKINNY_CODEC_G723_1 = 9,
- SKINNY_CODEC_G729A = 12,
- SKINNY_CODEC_G726_32 = 82, /* XXX Which packing order does this translate to? */
- SKINNY_CODEC_H261 = 100,
- SKINNY_CODEC_H263 = 101
-};
-
-#define DEFAULT_SKINNY_PORT 2000
-#define DEFAULT_SKINNY_BACKLOG 2
-#define SKINNY_MAX_PACKET 1000
-
-static int keep_alive = 120;
-static char date_format[6] = "D-M-Y";
-static char version_id[16] = "P002F202";
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define letohl(x) (x)
-#define letohs(x) (x)
-#define htolel(x) (x)
-#define htoles(x) (x)
-#else
-#if defined(SOLARIS) || defined(__Darwin__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
-#define __bswap_16(x) \
- ((((x) & 0xff00) >> 8) | \
- (((x) & 0x00ff) << 8))
-#define __bswap_32(x) \
- ((((x) & 0xff000000) >> 24) | \
- (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | \
- (((x) & 0x000000ff) << 24))
-#else
-#include <bits/byteswap.h>
-#endif
-#define letohl(x) __bswap_32(x)
-#define letohs(x) __bswap_16(x)
-#define htolel(x) __bswap_32(x)
-#define htoles(x) __bswap_16(x)
-#endif
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-AST_THREADSTORAGE(device2str_threadbuf, device2str_threadbuf_init);
-#define DEVICE2STR_BUFSIZE 15
-
-AST_THREADSTORAGE(control2str_threadbuf, control2str_threadbuf_init);
-#define CONTROL2STR_BUFSIZE 100
-
-/*********************
- * Protocol Messages *
- *********************/
-/* message types */
-#define KEEP_ALIVE_MESSAGE 0x0000
-/* no additional struct */
-
-#define REGISTER_MESSAGE 0x0001
-struct register_message {
- char name[16];
- uint32_t userId;
- uint32_t instance;
- uint32_t ip;
- uint32_t type;
- uint32_t maxStreams;
-};
-
-#define IP_PORT_MESSAGE 0x0002
-
-#define KEYPAD_BUTTON_MESSAGE 0x0003
-struct keypad_button_message {
- uint32_t button;
- uint32_t lineInstance;
- uint32_t callReference;
-};
-
-
-#define ENBLOC_CALL_MESSAGE 0x0004
-struct enbloc_call_message {
- char calledParty[24];
-};
-
-#define STIMULUS_MESSAGE 0x0005
-struct stimulus_message {
- uint32_t stimulus;
- uint32_t stimulusInstance;
- uint32_t callreference;
-};
-
-#define OFFHOOK_MESSAGE 0x0006
-struct offhook_message {
- uint32_t unknown1;
- uint32_t unknown2;
-};
-
-#define ONHOOK_MESSAGE 0x0007
-struct onhook_message {
- uint32_t unknown1;
- uint32_t unknown2;
-};
-
-#define CAPABILITIES_RES_MESSAGE 0x0010
-struct station_capabilities {
- uint32_t codec;
- uint32_t frames;
- union {
- char res[8];
- uint32_t rate;
- } payloads;
-};
-
-#define SKINNY_MAX_CAPABILITIES 18
-
-struct capabilities_res_message {
- uint32_t count;
- struct station_capabilities caps[SKINNY_MAX_CAPABILITIES];
-};
-
-#define SPEED_DIAL_STAT_REQ_MESSAGE 0x000A
-struct speed_dial_stat_req_message {
- uint32_t speedDialNumber;
-};
-
-#define LINE_STATE_REQ_MESSAGE 0x000B
-struct line_state_req_message {
- uint32_t lineNumber;
-};
-
-#define TIME_DATE_REQ_MESSAGE 0x000D
-#define BUTTON_TEMPLATE_REQ_MESSAGE 0x000E
-#define VERSION_REQ_MESSAGE 0x000F
-#define SERVER_REQUEST_MESSAGE 0x0012
-
-#define ALARM_MESSAGE 0x0020
-struct alarm_message {
- uint32_t alarmSeverity;
- char displayMessage[80];
- uint32_t alarmParam1;
- uint32_t alarmParam2;
-};
-
-#define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022
-struct open_receive_channel_ack_message {
- uint32_t status;
- uint32_t ipAddr;
- uint32_t port;
- uint32_t passThruId;
-};
-
-#define SOFT_KEY_SET_REQ_MESSAGE 0x0025
-
-#define SOFT_KEY_EVENT_MESSAGE 0x0026
-struct soft_key_event_message {
- uint32_t softKeyEvent;
- uint32_t instance;
- uint32_t callreference;
-};
-
-#define UNREGISTER_MESSAGE 0x0027
-#define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028
-#define HEADSET_STATUS_MESSAGE 0x002B
-#define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D
-
-#define REGISTER_ACK_MESSAGE 0x0081
-struct register_ack_message {
- uint32_t keepAlive;
- char dateTemplate[6];
- char res[2];
- uint32_t secondaryKeepAlive;
- char res2[4];
-};
-
-#define START_TONE_MESSAGE 0x0082
-struct start_tone_message {
- uint32_t tone;
- uint32_t space;
- uint32_t instance;
- uint32_t reference;
-};
-
-#define STOP_TONE_MESSAGE 0x0083
-struct stop_tone_message {
- uint32_t instance;
- uint32_t reference;
-};
-
-#define SET_RINGER_MESSAGE 0x0085
-struct set_ringer_message {
- uint32_t ringerMode;
- uint32_t unknown1; /* See notes in transmit_ringer_mode */
- uint32_t unknown2;
- uint32_t space[2];
-};
-
-#define SET_LAMP_MESSAGE 0x0086
-struct set_lamp_message {
- uint32_t stimulus;
- uint32_t stimulusInstance;
- uint32_t deviceStimulus;
-};
-
-#define SET_SPEAKER_MESSAGE 0x0088
-struct set_speaker_message {
- uint32_t mode;
-};
-
-/* XXX When do we need to use this? */
-#define SET_MICROPHONE_MESSAGE 0x0089
-struct set_microphone_message {
- uint32_t mode;
-};
-
-#define START_MEDIA_TRANSMISSION_MESSAGE 0x008A
-struct media_qualifier {
- uint32_t precedence;
- uint32_t vad;
- uint16_t packets;
- uint32_t bitRate;
-};
-
-struct start_media_transmission_message {
- uint32_t conferenceId;
- uint32_t passThruPartyId;
- uint32_t remoteIp;
- uint32_t remotePort;
- uint32_t packetSize;
- uint32_t payloadType;
- struct media_qualifier qualifier;
- uint32_t space[16];
-};
-
-#define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B
-struct stop_media_transmission_message {
- uint32_t conferenceId;
- uint32_t passThruPartyId;
- uint32_t space[3];
-};
-
-#define CALL_INFO_MESSAGE 0x008F
-struct call_info_message {
- char callingPartyName[40];
- char callingParty[24];
- char calledPartyName[40];
- char calledParty[24];
- uint32_t instance;
- uint32_t reference;
- uint32_t type;
- char originalCalledPartyName[40];
- char originalCalledParty[24];
- char lastRedirectingPartyName[40];
- char lastRedirectingParty[24];
- uint32_t originalCalledPartyRedirectReason;
- uint32_t lastRedirectingReason;
- char callingPartyVoiceMailbox[24];
- char calledPartyVoiceMailbox[24];
- char originalCalledPartyVoiceMailbox[24];
- char lastRedirectingVoiceMailbox[24];
- uint32_t space[3];
-};
-
-#define SPEED_DIAL_STAT_RES_MESSAGE 0x0091
-struct speed_dial_stat_res_message {
- uint32_t speedDialNumber;
- char speedDialDirNumber[24];
- char speedDialDisplayName[40];
-};
-
-#define LINE_STAT_RES_MESSAGE 0x0092
-struct line_stat_res_message {
- uint32_t lineNumber;
- char lineDirNumber[24];
- char lineDisplayName[24];
- uint32_t space[15];
-};
-
-#define DEFINETIMEDATE_MESSAGE 0x0094
-struct definetimedate_message {
- uint32_t year; /* since 1900 */
- uint32_t month;
- uint32_t dayofweek; /* monday = 1 */
- uint32_t day;
- uint32_t hour;
- uint32_t minute;
- uint32_t seconds;
- uint32_t milliseconds;
- uint32_t timestamp;
-};
-
-#define BUTTON_TEMPLATE_RES_MESSAGE 0x0097
-struct button_definition {
- uint8_t instanceNumber;
- uint8_t buttonDefinition;
-};
-
-struct button_definition_template {
- uint8_t buttonDefinition;
- /* for now, anything between 0xB0 and 0xCF is custom */
- /*int custom;*/
-};
-
-#define STIMULUS_REDIAL 0x01
-#define STIMULUS_SPEEDDIAL 0x02
-#define STIMULUS_HOLD 0x03
-#define STIMULUS_TRANSFER 0x04
-#define STIMULUS_FORWARDALL 0x05
-#define STIMULUS_FORWARDBUSY 0x06
-#define STIMULUS_FORWARDNOANSWER 0x07
-#define STIMULUS_DISPLAY 0x08
-#define STIMULUS_LINE 0x09
-#define STIMULUS_VOICEMAIL 0x0F
-#define STIMULUS_AUTOANSWER 0x11
-#define STIMULUS_CONFERENCE 0x7D
-#define STIMULUS_CALLPARK 0x7E
-#define STIMULUS_CALLPICKUP 0x7F
-#define STIMULUS_NONE 0xFF
-
-/* Button types */
-#define BT_REDIAL STIMULUS_REDIAL
-#define BT_SPEEDDIAL STIMULUS_SPEEDDIAL
-#define BT_HOLD STIMULUS_HOLD
-#define BT_TRANSFER STIMULUS_TRANSFER
-#define BT_FORWARDALL STIMULUS_FORWARDALL
-#define BT_FORWARDBUSY STIMULUS_FORWARDBUSY
-#define BT_FORWARDNOANSWER STIMULUS_FORWARDNOANSWER
-#define BT_DISPLAY STIMULUS_DISPLAY
-#define BT_LINE STIMULUS_LINE
-#define BT_VOICEMAIL STIMULUS_VOICEMAIL
-#define BT_AUTOANSWER STIMULUS_AUTOANSWER
-#define BT_CONFERENCE STIMULUS_CONFERENCE
-#define BT_CALLPARK STIMULUS_CALLPARK
-#define BT_CALLPICKUP STIMULUS_CALLPICKUP
-#define BT_NONE 0x00
-
-/* Custom button types - add our own between 0xB0 and 0xCF.
- This may need to be revised in the future,
- if stimuluses are ever added in this range. */
-#define BT_CUST_LINESPEEDDIAL 0xB0 /* line or speeddial */
-#define BT_CUST_HINT 0xB1 /* pipe dream */
-
-struct button_template_res_message {
- uint32_t buttonOffset;
- uint32_t buttonCount;
- uint32_t totalButtonCount;
- struct button_definition definition[42];
-};
-
-#define VERSION_RES_MESSAGE 0x0098
-struct version_res_message {
- char version[16];
-};
-
-#define DISPLAYTEXT_MESSAGE 0x0099
-struct displaytext_message {
- char text[40];
-};
-
-#define CLEAR_NOTIFY_MESSAGE 0x0115
-#define CLEAR_DISPLAY_MESSAGE 0x009A
-
-#define CAPABILITIES_REQ_MESSAGE 0x009B
-
-#define REGISTER_REJ_MESSAGE 0x009D
-struct register_rej_message {
- char errMsg[33];
-};
-
-#define SERVER_RES_MESSAGE 0x009E
-struct server_identifier {
- char serverName[48];
-};
-
-struct server_res_message {
- struct server_identifier server[5];
- uint32_t serverListenPort[5];
- uint32_t serverIpAddr[5];
-};
-
-#define RESET_MESSAGE 0x009F
-struct reset_message {
- uint32_t resetType;
-};
-
-#define KEEP_ALIVE_ACK_MESSAGE 0x0100
-
-#define OPEN_RECEIVE_CHANNEL_MESSAGE 0x0105
-struct open_receive_channel_message {
- uint32_t conferenceId;
- uint32_t partyId;
- uint32_t packets;
- uint32_t capability;
- uint32_t echo;
- uint32_t bitrate;
- uint32_t space[16];
-};
-
-#define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106
-struct close_receive_channel_message {
- uint32_t conferenceId;
- uint32_t partyId;
- uint32_t space[2];
-};
-
-#define SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108
-
-struct soft_key_template_definition {
- char softKeyLabel[16];
- uint32_t softKeyEvent;
-};
-
-#define KEYDEF_ONHOOK 0
-#define KEYDEF_CONNECTED 1
-#define KEYDEF_ONHOLD 2
-#define KEYDEF_RINGIN 3
-#define KEYDEF_OFFHOOK 4
-#define KEYDEF_CONNWITHTRANS 5
-#define KEYDEF_DADFD 6 /* Digits After Dialing First Digit */
-#define KEYDEF_CONNWITHCONF 7
-#define KEYDEF_RINGOUT 8
-#define KEYDEF_OFFHOOKWITHFEAT 9
-#define KEYDEF_UNKNOWN 10
-
-#define SOFTKEY_NONE 0x00
-#define SOFTKEY_REDIAL 0x01
-#define SOFTKEY_NEWCALL 0x02
-#define SOFTKEY_HOLD 0x03
-#define SOFTKEY_TRNSFER 0x04
-#define SOFTKEY_CFWDALL 0x05
-#define SOFTKEY_CFWDBUSY 0x06
-#define SOFTKEY_CFWDNOANSWER 0x07
-#define SOFTKEY_BKSPC 0x08
-#define SOFTKEY_ENDCALL 0x09
-#define SOFTKEY_RESUME 0x0A
-#define SOFTKEY_ANSWER 0x0B
-#define SOFTKEY_INFO 0x0C
-#define SOFTKEY_CONFRN 0x0D
-#define SOFTKEY_PARK 0x0E
-#define SOFTKEY_JOIN 0x0F
-#define SOFTKEY_MEETME 0x10
-#define SOFTKEY_PICKUP 0x11
-#define SOFTKEY_GPICKUP 0x12
-
-struct soft_key_template_definition soft_key_template_default[] = {
- { "Redial", 0x01 },
- { "NewCall", 0x02 },
- { "Hold", 0x03 },
- { "Trnsfer", 0x04 },
- { "CFwdAll", 0x05 },
- { "CFwdBusy", 0x06 },
- { "CFwdNoAnswer", 0x07 },
- { "<<", 0x08 },
- { "EndCall", 0x09 },
- { "Resume", 0x0A },
- { "Answer", 0x0B },
- { "Info", 0x0C },
- { "Confrn", 0x0D },
- { "Park", 0x0E },
- { "Join", 0x0F },
- { "MeetMe", 0x10 },
- { "PickUp", 0x11 },
- { "GPickUp", 0x12 },
-};
-
-struct soft_key_definitions {
- const uint8_t mode;
- const uint8_t *defaults;
- const int count;
-};
-
-static const uint8_t soft_key_default_onhook[] = {
- SOFTKEY_REDIAL,
- SOFTKEY_NEWCALL,
- SOFTKEY_CFWDALL,
- SOFTKEY_CFWDBUSY,
- /*SOFTKEY_GPICKUP,
- SOFTKEY_CONFRN,*/
-};
-
-static const uint8_t soft_key_default_connected[] = {
- SOFTKEY_HOLD,
- SOFTKEY_ENDCALL,
- SOFTKEY_TRNSFER,
- SOFTKEY_PARK,
- SOFTKEY_CFWDALL,
- SOFTKEY_CFWDBUSY,
-};
-
-static const uint8_t soft_key_default_onhold[] = {
- SOFTKEY_RESUME,
- SOFTKEY_NEWCALL,
- SOFTKEY_ENDCALL,
- SOFTKEY_TRNSFER,
-};
-
-static const uint8_t soft_key_default_ringin[] = {
- SOFTKEY_ANSWER,
- SOFTKEY_ENDCALL,
- SOFTKEY_TRNSFER,
-};
-
-static const uint8_t soft_key_default_offhook[] = {
- SOFTKEY_REDIAL,
- SOFTKEY_ENDCALL,
- SOFTKEY_CFWDALL,
- SOFTKEY_CFWDBUSY,
- /*SOFTKEY_GPICKUP,*/
-};
-
-static const uint8_t soft_key_default_connwithtrans[] = {
- SOFTKEY_HOLD,
- SOFTKEY_ENDCALL,
- SOFTKEY_TRNSFER,
- SOFTKEY_PARK,
- SOFTKEY_CFWDALL,
- SOFTKEY_CFWDBUSY,
-};
-
-static const uint8_t soft_key_default_dadfd[] = {
- SOFTKEY_BKSPC,
- SOFTKEY_ENDCALL,
-};
-
-static const uint8_t soft_key_default_connwithconf[] = {
- SOFTKEY_NONE,
-};
-
-static const uint8_t soft_key_default_ringout[] = {
- SOFTKEY_NONE,
- SOFTKEY_ENDCALL,
-};
-
-static const uint8_t soft_key_default_offhookwithfeat[] = {
- SOFTKEY_REDIAL,
- SOFTKEY_ENDCALL,
-};
-
-static const uint8_t soft_key_default_unknown[] = {
- SOFTKEY_NONE,
-};
-
-static const struct soft_key_definitions soft_key_default_definitions[] = {
- {KEYDEF_ONHOOK, soft_key_default_onhook, sizeof(soft_key_default_onhook) / sizeof(uint8_t)},
- {KEYDEF_CONNECTED, soft_key_default_connected, sizeof(soft_key_default_connected) / sizeof(uint8_t)},
- {KEYDEF_ONHOLD, soft_key_default_onhold, sizeof(soft_key_default_onhold) / sizeof(uint8_t)},
- {KEYDEF_RINGIN, soft_key_default_ringin, sizeof(soft_key_default_ringin) / sizeof(uint8_t)},
- {KEYDEF_OFFHOOK, soft_key_default_offhook, sizeof(soft_key_default_offhook) / sizeof(uint8_t)},
- {KEYDEF_CONNWITHTRANS, soft_key_default_connwithtrans, sizeof(soft_key_default_connwithtrans) / sizeof(uint8_t)},
- {KEYDEF_DADFD, soft_key_default_dadfd, sizeof(soft_key_default_dadfd) / sizeof(uint8_t)},
- {KEYDEF_CONNWITHCONF, soft_key_default_connwithconf, sizeof(soft_key_default_connwithconf) / sizeof(uint8_t)},
- {KEYDEF_RINGOUT, soft_key_default_ringout, sizeof(soft_key_default_ringout) / sizeof(uint8_t)},
- {KEYDEF_OFFHOOKWITHFEAT, soft_key_default_offhookwithfeat, sizeof(soft_key_default_offhookwithfeat) / sizeof(uint8_t)},
- {KEYDEF_UNKNOWN, soft_key_default_unknown, sizeof(soft_key_default_unknown) / sizeof(uint8_t)}
-};
-
-struct soft_key_template_res_message {
- uint32_t softKeyOffset;
- uint32_t softKeyCount;
- uint32_t totalSoftKeyCount;
- struct soft_key_template_definition softKeyTemplateDefinition[32];
-};
-
-#define SOFT_KEY_SET_RES_MESSAGE 0x0109
-
-struct soft_key_set_definition {
- uint8_t softKeyTemplateIndex[16];
- uint16_t softKeyInfoIndex[16];
-};
-
-struct soft_key_set_res_message {
- uint32_t softKeySetOffset;
- uint32_t softKeySetCount;
- uint32_t totalSoftKeySetCount;
- struct soft_key_set_definition softKeySetDefinition[16];
- uint32_t res;
-};
-
-#define SELECT_SOFT_KEYS_MESSAGE 0x0110
-struct select_soft_keys_message {
- uint32_t instance;
- uint32_t reference;
- uint32_t softKeySetIndex;
- uint32_t validKeyMask;
-};
-
-#define CALL_STATE_MESSAGE 0x0111
-struct call_state_message {
- uint32_t callState;
- uint32_t lineInstance;
- uint32_t callReference;
- uint32_t space[3];
-};
-
-#define DISPLAY_PROMPT_STATUS_MESSAGE 0x0112
-struct display_prompt_status_message {
- uint32_t messageTimeout;
- char promptMessage[32];
- uint32_t lineInstance;
- uint32_t callReference;
-};
-
-#define CLEAR_PROMPT_MESSAGE 0x0113
-struct clear_prompt_message {
- uint32_t lineInstance;
- uint32_t callReference;
-};
-
-#define DISPLAY_NOTIFY_MESSAGE 0x0114
-struct display_notify_message {
- uint32_t displayTimeout;
- char displayMessage[100];
-};
-
-#define ACTIVATE_CALL_PLANE_MESSAGE 0x0116
-struct activate_call_plane_message {
- uint32_t lineInstance;
-};
-
-#define DIALED_NUMBER_MESSAGE 0x011D
-struct dialed_number_message {
- char dialedNumber[24];
- uint32_t lineInstance;
- uint32_t callReference;
-};
-
-union skinny_data {
- struct alarm_message alarm;
- struct speed_dial_stat_req_message speeddialreq;
- struct register_message reg;
- struct register_ack_message regack;
- struct register_rej_message regrej;
- struct capabilities_res_message caps;
- struct version_res_message version;
- struct button_template_res_message buttontemplate;
- struct displaytext_message displaytext;
- struct display_prompt_status_message displaypromptstatus;
- struct clear_prompt_message clearpromptstatus;
- struct definetimedate_message definetimedate;
- struct start_tone_message starttone;
- struct stop_tone_message stoptone;
- struct speed_dial_stat_res_message speeddial;
- struct line_state_req_message line;
- struct line_stat_res_message linestat;
- struct soft_key_set_res_message softkeysets;
- struct soft_key_template_res_message softkeytemplate;
- struct server_res_message serverres;
- struct reset_message reset;
- struct set_lamp_message setlamp;
- struct set_ringer_message setringer;
- struct call_state_message callstate;
- struct keypad_button_message keypad;
- struct select_soft_keys_message selectsoftkey;
- struct activate_call_plane_message activatecallplane;
- struct stimulus_message stimulus;
- struct offhook_message offhook;
- struct onhook_message onhook;
- struct set_speaker_message setspeaker;
- struct set_microphone_message setmicrophone;
- struct call_info_message callinfo;
- struct start_media_transmission_message startmedia;
- struct stop_media_transmission_message stopmedia;
- struct open_receive_channel_message openreceivechannel;
- struct open_receive_channel_ack_message openreceivechannelack;
- struct close_receive_channel_message closereceivechannel;
- struct display_notify_message displaynotify;
- struct dialed_number_message dialednumber;
- struct soft_key_event_message softkeyeventmessage;
- struct enbloc_call_message enbloccallmessage;
-};
-
-/* packet composition */
-struct skinny_req {
- int len;
- int res;
- int e;
- union skinny_data data;
-};
-
-/* XXX This is the combined size of the variables above. (len, res, e)
- If more are added, this MUST change.
- (sizeof(skinny_req) - sizeof(skinny_data)) DOES NOT WORK on all systems (amd64?). */
-int skinny_header_size = 12;
-
-/*****************************
- * Asterisk specific globals *
- *****************************/
-
-static int skinnydebug = 0;
-
-/* a hostname, portnumber, socket and such is usefull for VoIP protocols */
-static struct sockaddr_in bindaddr;
-static char ourhost[256];
-static int ourport;
-static struct in_addr __ourip;
-struct ast_hostent ahp;
-struct hostent *hp;
-static int skinnysock = -1;
-static pthread_t accept_t;
-static char context[AST_MAX_CONTEXT] = "default";
-static char language[MAX_LANGUAGE] = "";
-static char mohinterpret[MAX_MUSICCLASS] = "default";
-static char mohsuggest[MAX_MUSICCLASS] = "";
-static char cid_num[AST_MAX_EXTENSION] = "";
-static char cid_name[AST_MAX_EXTENSION] = "";
-static char linelabel[AST_MAX_EXTENSION] ="";
-static int nat = 0;
-static ast_group_t cur_callergroup = 0;
-static ast_group_t cur_pickupgroup = 0;
-static int immediate = 0;
-static int callwaiting = 0;
-static int callreturn = 0;
-static int threewaycalling = 0;
-static int mwiblink = 0;
-/* This is for flashhook transfers */
-static int transfer = 0;
-static int cancallforward = 0;
-/* static int busycount = 3;*/
-static char accountcode[AST_MAX_ACCOUNT_CODE] = "";
-static char mailbox[AST_MAX_EXTENSION];
-static int amaflags = 0;
-static int callnums = 1;
-
-#define SKINNY_DEVICE_UNKNOWN -1
-#define SKINNY_DEVICE_NONE 0
-#define SKINNY_DEVICE_30SPPLUS 1
-#define SKINNY_DEVICE_12SPPLUS 2
-#define SKINNY_DEVICE_12SP 3
-#define SKINNY_DEVICE_12 4
-#define SKINNY_DEVICE_30VIP 5
-#define SKINNY_DEVICE_7910 6
-#define SKINNY_DEVICE_7960 7
-#define SKINNY_DEVICE_7940 8
-#define SKINNY_DEVICE_7935 9
-#define SKINNY_DEVICE_ATA186 12 /* Cisco ATA-186 */
-#define SKINNY_DEVICE_7941 115
-#define SKINNY_DEVICE_7971 119
-#define SKINNY_DEVICE_7914 124 /* Expansion module */
-#define SKINNY_DEVICE_7985 302
-#define SKINNY_DEVICE_7911 307
-#define SKINNY_DEVICE_7961GE 308
-#define SKINNY_DEVICE_7941GE 309
-#define SKINNY_DEVICE_7931 348
-#define SKINNY_DEVICE_7921 365
-#define SKINNY_DEVICE_7906 369
-#define SKINNY_DEVICE_7962 404 /* Not found */
-#define SKINNY_DEVICE_7937 431
-#define SKINNY_DEVICE_7942 434
-#define SKINNY_DEVICE_7945 435
-#define SKINNY_DEVICE_7965 436
-#define SKINNY_DEVICE_7975 437
-#define SKINNY_DEVICE_7905 20000
-#define SKINNY_DEVICE_7920 30002
-#define SKINNY_DEVICE_7970 30006
-#define SKINNY_DEVICE_7912 30007
-#define SKINNY_DEVICE_7902 30008
-#define SKINNY_DEVICE_CIPC 30016 /* Cisco IP Communicator */
-#define SKINNY_DEVICE_7961 30018
-#define SKINNY_DEVICE_7936 30019
-#define SKINNY_DEVICE_SCCPGATEWAY_AN 30027 /* ??? */
-#define SKINNY_DEVICE_SCCPGATEWAY_BRI 30028 /* ??? */
-
-#define SKINNY_SPEAKERON 1
-#define SKINNY_SPEAKEROFF 2
-
-#define SKINNY_MICON 1
-#define SKINNY_MICOFF 2
-
-#define SKINNY_OFFHOOK 1
-#define SKINNY_ONHOOK 2
-#define SKINNY_RINGOUT 3
-#define SKINNY_RINGIN 4
-#define SKINNY_CONNECTED 5
-#define SKINNY_BUSY 6
-#define SKINNY_CONGESTION 7
-#define SKINNY_HOLD 8
-#define SKINNY_CALLWAIT 9
-#define SKINNY_TRANSFER 10
-#define SKINNY_PARK 11
-#define SKINNY_PROGRESS 12
-#define SKINNY_INVALID 14
-
-#define SKINNY_SILENCE 0x00
-#define SKINNY_DIALTONE 0x21
-#define SKINNY_BUSYTONE 0x23
-#define SKINNY_ALERT 0x24
-#define SKINNY_REORDER 0x25
-#define SKINNY_CALLWAITTONE 0x2D
-#define SKINNY_NOTONE 0x7F
-
-#define SKINNY_LAMP_OFF 1
-#define SKINNY_LAMP_ON 2
-#define SKINNY_LAMP_WINK 3
-#define SKINNY_LAMP_FLASH 4
-#define SKINNY_LAMP_BLINK 5
-
-#define SKINNY_RING_OFF 1
-#define SKINNY_RING_INSIDE 2
-#define SKINNY_RING_OUTSIDE 3
-#define SKINNY_RING_FEATURE 4
-
-#define TYPE_TRUNK 1
-#define TYPE_LINE 2
-
-/* Skinny rtp stream modes. Do we really need this? */
-#define SKINNY_CX_SENDONLY 0
-#define SKINNY_CX_RECVONLY 1
-#define SKINNY_CX_SENDRECV 2
-#define SKINNY_CX_CONF 3
-#define SKINNY_CX_CONFERENCE 3
-#define SKINNY_CX_MUTE 4
-#define SKINNY_CX_INACTIVE 4
-
-#if 0
-static char *skinny_cxmodes[] = {
- "sendonly",
- "recvonly",
- "sendrecv",
- "confrnce",
- "inactive"
-};
-#endif
-
-/* driver scheduler */
-static struct sched_context *sched = NULL;
-static struct io_context *io;
-
-/* Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
-/* Protect the network socket */
-AST_MUTEX_DEFINE_STATIC(netlock);
-/* Protect the session list */
-AST_MUTEX_DEFINE_STATIC(sessionlock);
-/* Protect the device list */
-AST_MUTEX_DEFINE_STATIC(devicelock);
-#if 0
-/* Protect the paging device list */
-AST_MUTEX_DEFINE_STATIC(pagingdevicelock);
-#endif
-
-/* This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-
-/* Wait up to 16 seconds for first digit */
-static int firstdigittimeout = 16000;
-
-/* How long to wait for following digits */
-static int gendigittimeout = 8000;
-
-/* How long to wait for an extra digit, if there is an ambiguous match */
-static int matchdigittimeout = 3000;
-
-struct skinny_subchannel {
- ast_mutex_t lock;
- struct ast_channel *owner;
- struct ast_rtp *rtp;
- struct ast_rtp *vrtp;
- unsigned int callid;
- /* time_t lastouttime; */ /* Unused */
- int progress;
- int ringing;
- int onhold;
- /* int lastout; */ /* Unused */
- int cxmode;
- int nat;
- int outgoing;
- int alreadygone;
-
- struct skinny_subchannel *next;
- struct skinny_line *parent;
-};
-
-struct skinny_line {
- ast_mutex_t lock;
- char name[80];
- char label[24]; /* Label that shows next to the line buttons */
- char accountcode[AST_MAX_ACCOUNT_CODE];
- char exten[AST_MAX_EXTENSION]; /* Extension where to start */
- char context[AST_MAX_CONTEXT];
- char language[MAX_LANGUAGE];
- char cid_num[AST_MAX_EXTENSION]; /* Caller*ID */
- char cid_name[AST_MAX_EXTENSION]; /* Caller*ID */
- char lastcallerid[AST_MAX_EXTENSION]; /* Last Caller*ID */
- char call_forward[AST_MAX_EXTENSION];
- char mailbox[AST_MAX_EXTENSION];
- char mohinterpret[MAX_MUSICCLASS];
- char mohsuggest[MAX_MUSICCLASS];
- char lastnumberdialed[AST_MAX_EXTENSION]; /* Last number that was dialed - used for redial */
- int curtone; /* Current tone being played */
- ast_group_t callgroup;
- ast_group_t pickupgroup;
- int callwaiting;
- int transfer;
- int threewaycalling;
- int mwiblink;
- int cancallforward;
- int callreturn;
- int dnd; /* How does this affect callwait? Do we just deny a skinny_request if we're dnd? */
- int hascallerid;
- int hidecallerid;
- int amaflags;
- int type;
- int instance;
- int group;
- int needdestroy;
- int capability;
- int nonCodecCapability;
- int onhooktime;
- int msgstate; /* voicemail message state */
- int immediate;
- int hookstate;
- int nat;
-
- struct ast_codec_pref prefs;
- struct skinny_subchannel *sub;
- struct skinny_line *next;
- struct skinny_device *parent;
-};
-
-struct skinny_speeddial {
- ast_mutex_t lock;
- char label[42];
- char exten[AST_MAX_EXTENSION];
- int instance;
-
- struct skinny_speeddial *next;
- struct skinny_device *parent;
-};
-
-struct skinny_addon {
- ast_mutex_t lock;
- char type[10];
-
- struct skinny_addon *next;
- struct skinny_device *parent;
-};
-
-static struct skinny_device {
- /* A device containing one or more lines */
- char name[80];
- char id[16];
- char version_id[16];
- int type;
- int registered;
- int lastlineinstance;
- int lastcallreference;
- int capability;
- int earlyrtp;
- char exten[AST_MAX_EXTENSION];
- struct sockaddr_in addr;
- struct in_addr ourip;
- struct skinny_line *lines;
- struct skinny_speeddial *speeddials;
- struct skinny_addon *addons;
- struct ast_codec_pref prefs;
- struct ast_ha *ha;
- struct skinnysession *session;
- struct skinny_device *next;
-} *devices = NULL;
-
-struct skinny_paging_device {
- char name[80];
- char id[16];
- struct skinny_device ** devices;
- struct skinny_paging_device *next;
-};
-
-static struct skinnysession {
- pthread_t t;
- ast_mutex_t lock;
- struct sockaddr_in sin;
- int fd;
- char inbuf[SKINNY_MAX_PACKET];
- char outbuf[SKINNY_MAX_PACKET];
- struct skinny_device *device;
- struct skinnysession *next;
-} *sessions = NULL;
-
-static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause);
-static int skinny_call(struct ast_channel *ast, char *dest, int timeout);
-static int skinny_hangup(struct ast_channel *ast);
-static int skinny_answer(struct ast_channel *ast);
-static struct ast_frame *skinny_read(struct ast_channel *ast);
-static int skinny_write(struct ast_channel *ast, struct ast_frame *frame);
-static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);
-static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static int skinny_senddigit_begin(struct ast_channel *ast, char digit);
-static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int handle_time_date_req_message(struct skinny_req *req, struct skinnysession *s);
-
-static const struct ast_channel_tech skinny_tech = {
- .type = "Skinny",
- .description = tdesc,
- .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
- .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
- .requester = skinny_request,
- .call = skinny_call,
- .hangup = skinny_hangup,
- .answer = skinny_answer,
- .read = skinny_read,
- .write = skinny_write,
- .indicate = skinny_indicate,
- .fixup = skinny_fixup,
- .send_digit_begin = skinny_senddigit_begin,
- .send_digit_end = skinny_senddigit_end,
-/* .bridge = ast_rtp_bridge, */
-};
-
-static void *get_button_template(struct skinnysession *s, struct button_definition_template *btn)
-{
- struct skinny_device *d = s->device;
- struct skinny_addon *a = d->addons;
- int i;
-
- switch (d->type) {
- case SKINNY_DEVICE_30SPPLUS:
- case SKINNY_DEVICE_30VIP:
- /* 13 rows, 2 columns */
- for (i = 0; i < 4; i++)
- (btn++)->buttonDefinition = BT_LINE;
- (btn++)->buttonDefinition = BT_REDIAL;
- (btn++)->buttonDefinition = BT_VOICEMAIL;
- (btn++)->buttonDefinition = BT_CALLPARK;
- (btn++)->buttonDefinition = BT_FORWARDALL;
- (btn++)->buttonDefinition = BT_CONFERENCE;
- for (i = 0; i < 4; i++)
- (btn++)->buttonDefinition = BT_NONE;
- for (i = 0; i < 13; i++)
- (btn++)->buttonDefinition = BT_SPEEDDIAL;
-
- break;
- case SKINNY_DEVICE_12SPPLUS:
- case SKINNY_DEVICE_12SP:
- case SKINNY_DEVICE_12:
- /* 6 rows, 2 columns */
- for (i = 0; i < 2; i++)
- (btn++)->buttonDefinition = BT_LINE;
- (btn++)->buttonDefinition = BT_REDIAL;
- for (i = 0; i < 3; i++)
- (btn++)->buttonDefinition = BT_SPEEDDIAL;
- (btn++)->buttonDefinition = BT_HOLD;
- (btn++)->buttonDefinition = BT_TRANSFER;
- (btn++)->buttonDefinition = BT_FORWARDALL;
- (btn++)->buttonDefinition = BT_CALLPARK;
- (btn++)->buttonDefinition = BT_VOICEMAIL;
- (btn++)->buttonDefinition = BT_CONFERENCE;
- break;
- case SKINNY_DEVICE_7910:
- (btn++)->buttonDefinition = BT_LINE;
- (btn++)->buttonDefinition = BT_HOLD;
- (btn++)->buttonDefinition = BT_TRANSFER;
- (btn++)->buttonDefinition = BT_DISPLAY;
- (btn++)->buttonDefinition = BT_VOICEMAIL;
- (btn++)->buttonDefinition = BT_CONFERENCE;
- (btn++)->buttonDefinition = BT_FORWARDALL;
- for (i = 0; i < 2; i++)
- (btn++)->buttonDefinition = BT_SPEEDDIAL;
- (btn++)->buttonDefinition = BT_REDIAL;
- break;
- case SKINNY_DEVICE_7960:
- case SKINNY_DEVICE_7961:
- case SKINNY_DEVICE_7961GE:
- case SKINNY_DEVICE_7962:
- case SKINNY_DEVICE_7965:
- for (i = 0; i < 6; i++)
- (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
- break;
- case SKINNY_DEVICE_7940:
- case SKINNY_DEVICE_7941:
- case SKINNY_DEVICE_7941GE:
- case SKINNY_DEVICE_7942:
- case SKINNY_DEVICE_7945:
- for (i = 0; i < 2; i++)
- (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
- break;
- case SKINNY_DEVICE_7935:
- case SKINNY_DEVICE_7936:
- for (i = 0; i < 2; i++)
- (btn++)->buttonDefinition = BT_LINE;
- break;
- case SKINNY_DEVICE_ATA186:
- (btn++)->buttonDefinition = BT_LINE;
- break;
- case SKINNY_DEVICE_7970:
- case SKINNY_DEVICE_7971:
- case SKINNY_DEVICE_7975:
- case SKINNY_DEVICE_CIPC:
- for (i = 0; i < 8; i++)
- (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
- break;
- case SKINNY_DEVICE_7985:
- /* XXX I have no idea what the buttons look like on these. */
- ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type);
- break;
- case SKINNY_DEVICE_7912:
- case SKINNY_DEVICE_7911:
- case SKINNY_DEVICE_7905:
- (btn++)->buttonDefinition = BT_LINE;
- (btn++)->buttonDefinition = BT_HOLD;
- break;
- case SKINNY_DEVICE_7920:
- /* XXX I don't know if this is right. */
- for (i = 0; i < 4; i++)
- (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
- break;
- case SKINNY_DEVICE_7921:
- for (i = 0; i < 6; i++)
- (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
- break;
- case SKINNY_DEVICE_7902:
- ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type);
- break;
- case SKINNY_DEVICE_7906:
- ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type);
- break;
- case SKINNY_DEVICE_7931:
- ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type);
- break;
- case SKINNY_DEVICE_7937:
- ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type);
- break;
- case SKINNY_DEVICE_7914:
- ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found. Expansion module registered by itself?\n", d->type);
- break;
- case SKINNY_DEVICE_SCCPGATEWAY_AN:
- case SKINNY_DEVICE_SCCPGATEWAY_BRI:
- ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type);
- break;
- default:
- ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type);
- break;
- }
-
- for (a = d->addons; a; a = a->next) {
- if (!strcasecmp(a->type, "7914")) {
- for (i = 0; i < 14; i++)
- (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
- } else {
- ast_log(LOG_WARNING, "Unknown addon type '%s' found. Skipping.\n", a->type);
- }
- }
-
- return btn;
-}
-
-static struct skinny_req *req_alloc(size_t size, int response_message)
-{
- struct skinny_req *req;
-
- if (!(req = ast_calloc(1, skinny_header_size + size + 4)))
- return NULL;
-
- req->len = htolel(size+4);
- req->e = htolel(response_message);
-
- return req;
-}
-
-static struct skinny_line *find_line_by_instance(struct skinny_device *d, int instance)
-{
- struct skinny_line *l;
-
- if (!instance)
- instance = 1;
-
- for (l = d->lines; l; l = l->next) {
- if (l->instance == instance)
- break;
- }
-
- if (!l) {
- ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name);
- }
- return l;
-}
-
-static struct skinny_line *find_line_by_name(const char *dest)
-{
- struct skinny_line *l;
- struct skinny_device *d;
- char line[256];
- char *at;
- char *device;
-
- ast_copy_string(line, dest, sizeof(line));
- at = strchr(line, '@');
- if (!at) {
- ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);
- return NULL;
- }
- *at++ = '\0';
- device = at;
- ast_mutex_lock(&devicelock);
- for (d = devices; d; d = d->next) {
- if (!strcasecmp(d->name, device)) {
- if (skinnydebug)
- ast_verbose("Found device: %s\n", d->name);
- /* Found the device */
- for (l = d->lines; l; l = l->next) {
- /* Search for the right line */
- if (!strcasecmp(l->name, line)) {
- ast_mutex_unlock(&devicelock);
- return l;
- }
- }
- }
- }
- /* Device not found */
- ast_mutex_unlock(&devicelock);
- return NULL;
-}
-
-/* It's quicker/easier to find the subchannel when we know the instance number too */
-static struct skinny_subchannel *find_subchannel_by_instance_reference(struct skinny_device *d, int instance, int reference)
-{
- struct skinny_line *l = find_line_by_instance(d, instance);
- struct skinny_subchannel *sub;
-
- if (!l) {
- return NULL;
- }
-
- if (!reference)
- sub = l->sub;
- else {
- for (sub = l->sub; sub; sub = sub->next) {
- if (sub->callid == reference)
- break;
- }
- }
-
- if (!sub) {
- ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name);
- }
- return sub;
-}
-
-/* Find the subchannel when we only have the callid - this shouldn't happen often */
-static struct skinny_subchannel *find_subchannel_by_reference(struct skinny_device *d, int reference)
-{
- struct skinny_line *l;
- struct skinny_subchannel *sub = NULL;
-
- for (l = d->lines; l; l = l->next) {
- for (sub = l->sub; sub; sub = sub->next) {
- if (sub->callid == reference)
- break;
- }
- if (sub)
- break;
- }
-
- if (!l) {
- ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name);
- } else {
- if (!sub) {
- ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name);
- }
- }
- return sub;
-}
-
-static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device *d, int instance)
-{
- struct skinny_speeddial *sd;
-
- for (sd = d->speeddials; sd; sd = sd->next) {
- if (sd->instance == instance)
- break;
- }
-
- if (!sd) {
- ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name);
- }
- return sd;
-}
-
-static int codec_skinny2ast(enum skinny_codecs skinnycodec)
-{
- switch (skinnycodec) {
- case SKINNY_CODEC_ALAW:
- return AST_FORMAT_ALAW;
- case SKINNY_CODEC_ULAW:
- return AST_FORMAT_ULAW;
- case SKINNY_CODEC_G723_1:
- return AST_FORMAT_G723_1;
- case SKINNY_CODEC_G729A:
- return AST_FORMAT_G729A;
- case SKINNY_CODEC_G726_32:
- return AST_FORMAT_G726_AAL2; /* XXX Is this right? */
- case SKINNY_CODEC_H261:
- return AST_FORMAT_H261;
- case SKINNY_CODEC_H263:
- return AST_FORMAT_H263;
- default:
- return 0;
- }
-}
-
-static int codec_ast2skinny(int astcodec)
-{
- switch (astcodec) {
- case AST_FORMAT_ALAW:
- return SKINNY_CODEC_ALAW;
- case AST_FORMAT_ULAW:
- return SKINNY_CODEC_ULAW;
- case AST_FORMAT_G723_1:
- return SKINNY_CODEC_G723_1;
- case AST_FORMAT_G729A:
- return SKINNY_CODEC_G729A;
- case AST_FORMAT_G726_AAL2: /* XXX Is this right? */
- return SKINNY_CODEC_G726_32;
- case AST_FORMAT_H261:
- return SKINNY_CODEC_H261;
- case AST_FORMAT_H263:
- return SKINNY_CODEC_H263;
- default:
- return 0;
- }
-}
-
-
-static int skinny_register(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d;
- struct sockaddr_in sin;
- socklen_t slen;
-
- ast_mutex_lock(&devicelock);
- for (d = devices; d; d = d->next) {
- if (!strcasecmp(req->data.reg.name, d->id)
- && ast_apply_ha(d->ha, &(s->sin))) {
- s->device = d;
- d->type = letohl(req->data.reg.type);
- if (ast_strlen_zero(d->version_id)) {
- ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
- }
- d->registered = 1;
- d->session = s;
-
- slen = sizeof(sin);
- if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {
- ast_log(LOG_WARNING, "Cannot get socket name\n");
- sin.sin_addr = __ourip;
- }
- d->ourip = sin.sin_addr;
- break;
- }
- }
- ast_mutex_unlock(&devicelock);
- if (!d) {
- return 0;
- }
- return 1;
-}
-
-static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d;
-
- d = s->device;
-
- if (d) {
- d->session = NULL;
- d->registered = 0;
- }
-
- return -1; /* main loop will destroy the session */
-}
-
-static int transmit_response(struct skinnysession *s, struct skinny_req *req)
-{
- int res = 0;
-
- if (!s) {
- ast_log(LOG_WARNING, "Asked to transmit to a non-existant session!\n");
- return -1;
- }
-
- ast_mutex_lock(&s->lock);
-
- if (skinnydebug)
- ast_log(LOG_VERBOSE, "writing packet type %04X (%d bytes) to socket %d\n", letohl(req->e), letohl(req->len)+8, s->fd);
-
- if (letohl(req->len > SKINNY_MAX_PACKET) || letohl(req->len < 0)) {
- ast_log(LOG_WARNING, "transmit_response: the length of the request is out of bounds\n");
- return -1;
- }
-
- memset(s->outbuf,0,sizeof(s->outbuf));
- memcpy(s->outbuf, req, skinny_header_size);
- memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));
-
- res = write(s->fd, s->outbuf, letohl(req->len)+8);
-
- if (res != letohl(req->len)+8) {
- ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
- if (res == -1) {
- if (skinnydebug)
- ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");
- skinny_unregister(NULL, s);
- }
-
- }
-
- ast_mutex_unlock(&s->lock);
- return 1;
-}
-
-static void transmit_speaker_mode(struct skinnysession *s, int mode)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE)))
- return;
-
- req->data.setspeaker.mode = htolel(mode);
- transmit_response(s, req);
-}
-/*
-static void transmit_microphone_mode(struct skinnysession *s, int mode)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct set_microphone_message), SET_MICROPHONE_MESSAGE)))
- return;
-
- req->data.setmicrophone.mode = htolel(mode);
- transmit_response(s, req);
-}
-*/
-
-static void transmit_callinfo(struct skinnysession *s, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE)))
- return;
-
- if (skinnydebug)
- ast_verbose("Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, s->device->name, instance);
-
- if (fromname) {
- ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName));
- }
- if (fromnum) {
- ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty));
- }
- if (toname) {
- ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName));
- }
- if (tonum) {
- ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty));
- }
- req->data.callinfo.instance = htolel(instance);
- req->data.callinfo.reference = htolel(callid);
- req->data.callinfo.type = htolel(calltype);
- transmit_response(s, req);
-}
-
-static void transmit_connect(struct skinnysession *s, struct skinny_subchannel *sub)
-{
- struct skinny_req *req;
- struct skinny_line *l = sub->parent;
- struct ast_format_list fmt;
-
- if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
- return;
-
- fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
-
- req->data.openreceivechannel.conferenceId = htolel(sub->callid);
- req->data.openreceivechannel.partyId = htolel(sub->callid);
- req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
- req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
- req->data.openreceivechannel.echo = htolel(0);
- req->data.openreceivechannel.bitrate = htolel(0);
- transmit_response(s, req);
-}
-
-static void transmit_tone(struct skinnysession *s, int tone, int instance, int reference)
-{
- struct skinny_req *req;
-
- if (tone == SKINNY_NOTONE) {
- /* This is bad, mmm'kay? */
- return;
- }
-
- if (tone > 0) {
- if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))
- return;
- req->data.starttone.tone = htolel(tone);
- req->data.starttone.instance = htolel(instance);
- req->data.starttone.reference = htolel(reference);
- } else {
- if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))
- return;
- req->data.stoptone.instance = htolel(instance);
- req->data.stoptone.reference = htolel(reference);
- }
-
- if (tone > 0) {
- req->data.starttone.tone = htolel(tone);
- }
- transmit_response(s, req);
-}
-
-static void transmit_selectsoftkeys(struct skinnysession *s, int instance, int callid, int softkey)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct select_soft_keys_message), SELECT_SOFT_KEYS_MESSAGE)))
- return;
-
- req->data.selectsoftkey.instance = htolel(instance);
- req->data.selectsoftkey.reference = htolel(callid);
- req->data.selectsoftkey.softKeySetIndex = htolel(softkey);
- req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF);
- transmit_response(s, req);
-}
-
-static void transmit_lamp_indication(struct skinnysession *s, int stimulus, int instance, int indication)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct set_lamp_message), SET_LAMP_MESSAGE)))
- return;
-
- req->data.setlamp.stimulus = htolel(stimulus);
- req->data.setlamp.stimulusInstance = htolel(instance);
- req->data.setlamp.deviceStimulus = htolel(indication);
- transmit_response(s, req);
-}
-
-static void transmit_ringer_mode(struct skinnysession *s, int mode)
-{
- struct skinny_req *req;
-
- if (skinnydebug)
- ast_verbose("Setting ringer mode to '%d'.\n", mode);
-
- if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE)))
- return;
-
- req->data.setringer.ringerMode = htolel(mode);
- /* XXX okay, I don't quite know what this is, but here's what happens (on a 7960).
- Note: The phone will always show as ringing on the display.
-
- 1: phone will audibly ring over and over
- 2: phone will audibly ring only once
- any other value, will NOT cause the phone to audibly ring
- */
- req->data.setringer.unknown1 = htolel(1);
- /* XXX the value here doesn't seem to change anything. Must be higher than 0.
- Perhaps a packet capture can shed some light on this. */
- req->data.setringer.unknown2 = htolel(1);
- transmit_response(s, req);
-}
-
-static void transmit_displaymessage(struct skinnysession *s, const char *text, int instance, int reference)
-{
- struct skinny_req *req;
-
- if (text == 0) {
- if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
- return;
-
- req->data.clearpromptstatus.lineInstance = instance;
- req->data.clearpromptstatus.callReference = reference;
-
- if (skinnydebug)
- ast_verbose("Clearing Display\n");
- } else {
- if (!(req = req_alloc(sizeof(struct displaytext_message), DISPLAYTEXT_MESSAGE)))
- return;
-
- ast_copy_string(req->data.displaytext.text, text, sizeof(req->data.displaytext.text));
- if (skinnydebug)
- ast_verbose("Displaying message '%s'\n", req->data.displaytext.text);
- }
-
- transmit_response(s, req);
-}
-
-static void transmit_displaynotify(struct skinnysession *s, const char *text, int t)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct display_notify_message), DISPLAY_NOTIFY_MESSAGE)))
- return;
-
- ast_copy_string(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage));
- req->data.displaynotify.displayTimeout = htolel(t);
-
- if (skinnydebug)
- ast_verbose("Displaying notify '%s'\n", text);
-
- transmit_response(s, req);
-}
-
-static void transmit_displaypromptstatus(struct skinnysession *s, const char *text, int t, int instance, int callid)
-{
- struct skinny_req *req;
-
- if (text == 0) {
- if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE)))
- return;
-
- req->data.clearpromptstatus.lineInstance = htolel(instance);
- req->data.clearpromptstatus.callReference = htolel(callid);
-
- if (skinnydebug)
- ast_verbose("Clearing Prompt\n");
- } else {
- if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE)))
- return;
-
- ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage));
- req->data.displaypromptstatus.messageTimeout = htolel(t);
- req->data.displaypromptstatus.lineInstance = htolel(instance);
- req->data.displaypromptstatus.callReference = htolel(callid);
-
- if (skinnydebug)
- ast_verbose("Displaying Prompt Status '%s'\n", text);
- }
-
- transmit_response(s, req);
-}
-
-static void transmit_dialednumber(struct skinnysession *s, const char *text, int instance, int callid)
-{
- struct skinny_req *req;
-
- if (!(req = req_alloc(sizeof(struct dialed_number_message), DIALED_NUMBER_MESSAGE)))
- return;
-
- ast_copy_string(req->data.dialednumber.dialedNumber, text, sizeof(req->data.dialednumber.dialedNumber));
- req->data.dialednumber.lineInstance = htolel(instance);
- req->data.dialednumber.callReference = htolel(callid);
-
- transmit_response(s, req);
-}
-
-static void transmit_callstate(struct skinnysession *s, int instance, int state, unsigned callid)
-{
- struct skinny_req *req;
-
- if (state == SKINNY_ONHOOK) {
- if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
- return;
-
- req->data.closereceivechannel.conferenceId = htolel(callid);
- req->data.closereceivechannel.partyId = htolel(callid);
- transmit_response(s, req);
-
- if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
- return;
-
- req->data.stopmedia.conferenceId = htolel(callid);
- req->data.stopmedia.passThruPartyId = htolel(callid);
- transmit_response(s, req);
-
- transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
-
- transmit_displaypromptstatus(s, NULL, 0, instance, callid);
- }
-
- if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
- return;
-
- req->data.callstate.callState = htolel(state);
- req->data.callstate.lineInstance = htolel(instance);
- req->data.callstate.callReference = htolel(callid);
- transmit_response(s, req);
-
- if (state == SKINNY_ONHOOK) {
- transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
- }
-
- if (state == SKINNY_OFFHOOK || state == SKINNY_ONHOOK) {
- if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
- return;
-
- req->data.activatecallplane.lineInstance = htolel(instance);
- transmit_response(s, req);
- }
-}
-
-/*
-static int has_voicemail(struct skinny_line *l)
-{
- return ast_app_has_voicemail(l->mailbox, NULL);
-}
-*/
-
-static void do_housekeeping(struct skinnysession *s)
-{
-/*
- int new;
- int old;
- struct skinny_device *d = s->device;
- struct skinny_line *l;
-*/
-
- /* Update time on device */
- handle_time_date_req_message(NULL, s);
-
-/*
- for (l = d->lines; l; l = l->next) {
- if (has_voicemail(l)) {
- if (skinnydebug)
- ast_verbose("Checking for voicemail Skinny %s@%s\n", l->name, d->name);
- ast_app_inboxcount(l->mailbox, &new, &old);
- if (skinnydebug)
- ast_verbose("Skinny %s@%s has voicemail!\n", l->name, d->name);
- transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
- } else {
- transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF);
- }
- }
-*/
-}
-
-/* I do not believe skinny can deal with video.
- Anyone know differently? */
-/* Yes, it can. Currently 7985 and Cisco VT Advantage do video. */
-static enum ast_rtp_get_result skinny_get_vrtp_peer(struct ast_channel *c, struct ast_rtp **rtp)
-{
- struct skinny_subchannel *sub = NULL;
-
- if (!(sub = c->tech_pvt) || !(sub->vrtp))
- return AST_RTP_GET_FAILED;
-
- *rtp = sub->vrtp;
-
- return AST_RTP_TRY_NATIVE;
-}
-
-static enum ast_rtp_get_result skinny_get_rtp_peer(struct ast_channel *c, struct ast_rtp **rtp)
-{
- struct skinny_subchannel *sub = NULL;
-
- if (!(sub = c->tech_pvt) || !(sub->rtp))
- return AST_RTP_GET_FAILED;
-
- *rtp = sub->rtp;
-
- return AST_RTP_TRY_NATIVE;
-}
-
-static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
-{
- struct skinny_subchannel *sub;
- sub = c->tech_pvt;
- if (sub) {
- /* transmit_modify_with_sdp(sub, rtp); @@FIXME@@ if needed */
- return 0;
- }
- return -1;
-}
-
-static struct ast_rtp_protocol skinny_rtp = {
- .type = "Skinny",
- .get_rtp_info = skinny_get_rtp_peer,
- .get_vrtp_info = skinny_get_vrtp_peer,
- .set_rtp_peer = skinny_set_rtp_peer,
-};
-
-static int skinny_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- skinnydebug = 1;
- ast_cli(fd, "Skinny Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int skinny_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 4) {
- return RESULT_SHOWUSAGE;
- }
- skinnydebug = 0;
- ast_cli(fd, "Skinny Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static char *complete_skinny_reset(const char *line, const char *word, int pos, int state)
-{
- struct skinny_device *d;
-
- char *result = NULL;
- int wordlen = strlen(word);
- int which = 0;
-
- if (pos == 2) {
- for (d = devices; d && !result; d = d->next) {
- if (!strncasecmp(word, d->id, wordlen) && ++which > state)
- result = ast_strdup(d->id);
- }
- }
-
- return result;
-}
-
-static int skinny_reset_device(int fd, int argc, char *argv[])
-{
- struct skinny_device *d;
- struct skinny_req *req;
-
- if (argc < 3 || argc > 4) {
- return RESULT_SHOWUSAGE;
- }
- ast_mutex_lock(&devicelock);
-
- for (d = devices; d; d = d->next) {
- int fullrestart = 0;
- if (!strcasecmp(argv[2], d->id) || !strcasecmp(argv[2], "all")) {
- if (!(d->session))
- continue;
-
- if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE)))
- continue;
-
- if (argc == 4 && !strcasecmp(argv[3], "restart"))
- fullrestart = 1;
-
- if (fullrestart)
- req->data.reset.resetType = 2;
- else
- req->data.reset.resetType = 1;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id);
- transmit_response(d->session, req);
- }
- }
- ast_mutex_unlock(&devicelock);
- return RESULT_SUCCESS;
-}
-
-static char *device2str(int type)
-{
- char *tmp;
-
- switch (type) {
- case SKINNY_DEVICE_NONE:
- return "No Device";
- case SKINNY_DEVICE_30SPPLUS:
- return "30SP Plus";
- case SKINNY_DEVICE_12SPPLUS:
- return "12SP Plus";
- case SKINNY_DEVICE_12SP:
- return "12SP";
- case SKINNY_DEVICE_12:
- return "12";
- case SKINNY_DEVICE_30VIP:
- return "30VIP";
- case SKINNY_DEVICE_7910:
- return "7910";
- case SKINNY_DEVICE_7960:
- return "7960";
- case SKINNY_DEVICE_7940:
- return "7940";
- case SKINNY_DEVICE_7935:
- return "7935";
- case SKINNY_DEVICE_ATA186:
- return "ATA186";
- case SKINNY_DEVICE_7941:
- return "7941";
- case SKINNY_DEVICE_7971:
- return "7971";
- case SKINNY_DEVICE_7914:
- return "7914";
- case SKINNY_DEVICE_7985:
- return "7985";
- case SKINNY_DEVICE_7911:
- return "7911";
- case SKINNY_DEVICE_7961GE:
- return "7961GE";
- case SKINNY_DEVICE_7941GE:
- return "7941GE";
- case SKINNY_DEVICE_7931:
- return "7931";
- case SKINNY_DEVICE_7921:
- return "7921";
- case SKINNY_DEVICE_7906:
- return "7906";
- case SKINNY_DEVICE_7962:
- return "7962";
- case SKINNY_DEVICE_7937:
- return "7937";
- case SKINNY_DEVICE_7942:
- return "7942";
- case SKINNY_DEVICE_7945:
- return "7945";
- case SKINNY_DEVICE_7965:
- return "7965";
- case SKINNY_DEVICE_7975:
- return "7975";
- case SKINNY_DEVICE_7905:
- return "7905";
- case SKINNY_DEVICE_7920:
- return "7920";
- case SKINNY_DEVICE_7970:
- return "7970";
- case SKINNY_DEVICE_7912:
- return "7912";
- case SKINNY_DEVICE_7902:
- return "7902";
- case SKINNY_DEVICE_CIPC:
- return "IP Communicator";
- case SKINNY_DEVICE_7961:
- return "7961";
- case SKINNY_DEVICE_7936:
- return "7936";
- case SKINNY_DEVICE_SCCPGATEWAY_AN:
- return "SCCPGATEWAY_AN";
- case SKINNY_DEVICE_SCCPGATEWAY_BRI:
- return "SCCPGATEWAY_BRI";
- case SKINNY_DEVICE_UNKNOWN:
- return "Unknown";
- default:
- if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE)))
- return "Unknown";
- snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type);
- return tmp;
- }
-}
-
-static int skinny_show_devices(int fd, int argc, char *argv[])
-{
- struct skinny_device *d;
- struct skinny_line *l;
- int numlines = 0;
-
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- ast_mutex_lock(&devicelock);
-
- ast_cli(fd, "Name DeviceId IP Type R NL\n");
- ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n");
- for (d = devices; d; d = d->next) {
- numlines = 0;
- for (l = d->lines; l; l = l->next) {
- numlines++;
- }
-
- ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n",
- d->name,
- d->id,
- d->session?ast_inet_ntoa(d->session->sin.sin_addr):"",
- device2str(d->type),
- d->registered?'Y':'N',
- numlines);
- }
- ast_mutex_unlock(&devicelock);
- return RESULT_SUCCESS;
-}
-
-static int skinny_show_lines(int fd, int argc, char *argv[])
-{
- struct skinny_device *d;
- struct skinny_line *l;
-
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- ast_mutex_lock(&devicelock);
-
- ast_cli(fd, "Device Name Instance Name Label \n");
- ast_cli(fd, "-------------------- -------- -------------------- --------------------\n");
- for (d = devices; d; d = d->next) {
- for (l = d->lines; l; l = l->next) {
- ast_cli(fd, "%-20s %8d %-20s %-20s\n",
- d->name,
- l->instance,
- l->name,
- l->label);
- }
- }
-
- ast_mutex_unlock(&devicelock);
- return RESULT_SUCCESS;
-}
-
-static char show_devices_usage[] =
-"Usage: skinny show devices\n"
-" Lists all devices known to the Skinny subsystem.\n";
-
-static char show_lines_usage[] =
-"Usage: skinny show lines\n"
-" Lists all lines known to the Skinny subsystem.\n";
-
-static char debug_usage[] =
-"Usage: skinny set debug\n"
-" Enables dumping of Skinny packets for debugging purposes\n";
-
-static char no_debug_usage[] =
-"Usage: skinny set debug off\n"
-" Disables dumping of Skinny packets for debugging purposes\n";
-
-static char reset_usage[] =
-"Usage: skinny reset <DeviceId|all> [restart]\n"
-" Causes a Skinny device to reset itself, optionally with a full restart\n";
-
-static struct ast_cli_entry cli_skinny[] = {
- { { "skinny", "show", "devices", NULL },
- skinny_show_devices, "List defined Skinny devices",
- show_devices_usage },
-
- { { "skinny", "show", "lines", NULL },
- skinny_show_lines, "List defined Skinny lines per device",
- show_lines_usage },
-
- { { "skinny", "set", "debug", NULL },
- skinny_do_debug, "Enable Skinny debugging",
- debug_usage },
-
- { { "skinny", "set", "debug", "off", NULL },
- skinny_no_debug, "Disable Skinny debugging",
- no_debug_usage },
-
- { { "skinny", "reset", NULL },
- skinny_reset_device, "Reset Skinny device(s)",
- reset_usage, complete_skinny_reset },
-};
-
-#if 0
-static struct skinny_paging_device *build_paging_device(const char *cat, struct ast_variable *v)
-{
- return NULL;
-}
-#endif
-
-static struct skinny_device *build_device(const char *cat, struct ast_variable *v)
-{
- struct skinny_device *d;
- struct skinny_line *l;
- struct skinny_speeddial *sd;
- struct skinny_addon *a;
- int lineInstance = 1;
- int speeddialInstance = 1;
- int y = 0;
-
- if (!(d = ast_calloc(1, sizeof(struct skinny_device)))) {
- return NULL;
- } else {
- ast_copy_string(d->name, cat, sizeof(d->name));
- d->lastlineinstance = 1;
- d->capability = default_capability;
- d->prefs = default_prefs;
- d->earlyrtp = 1;
- while(v) {
- if (!strcasecmp(v->name, "host")) {
- if (ast_get_ip(&d->addr, v->value)) {
- free(d);
- return NULL;
- }
- } else if (!strcasecmp(v->name, "port")) {
- d->addr.sin_port = htons(atoi(v->value));
- } else if (!strcasecmp(v->name, "device")) {
- ast_copy_string(d->id, v->value, sizeof(d->id));
- } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
- d->ha = ast_append_ha(v->name, v->value, d->ha);
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(context, v->value, sizeof(context));
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&d->prefs, &d->capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&d->prefs, &d->capability, v->value, 0);
- } else if (!strcasecmp(v->name, "version")) {
- ast_copy_string(d->version_id, v->value, sizeof(d->version_id));
- } else if (!strcasecmp(v->name, "earlyrtp")) {
- d->earlyrtp = ast_true(v->value);
- } else if (!strcasecmp(v->name, "nat")) {
- nat = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callerid")) {
- if (!strcasecmp(v->value, "asreceived")) {
- cid_num[0] = '\0';
- cid_name[0] = '\0';
- } else {
- ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
- }
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(language, v->value, sizeof(language));
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(accountcode, v->value, sizeof(accountcode));
- } else if (!strcasecmp(v->name, "amaflags")) {
- y = ast_cdr_amaflags2int(v->value);
- if (y < 0) {
- ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
- } else {
- amaflags = y;
- }
- } else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
- } else if (!strcasecmp(v->name, "callgroup")) {
- cur_callergroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "pickupgroup")) {
- cur_pickupgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "immediate")) {
- immediate = ast_true(v->value);
- } else if (!strcasecmp(v->name, "cancallforward")) {
- cancallforward = ast_true(v->value);
- } else if (!strcasecmp(v->name, "mailbox")) {
- ast_copy_string(mailbox, v->value, sizeof(mailbox));
- } else if (!strcasecmp(v->name, "callreturn")) {
- callreturn = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callwaiting")) {
- callwaiting = ast_true(v->value);
- } else if (!strcasecmp(v->name, "transfer")) {
- transfer = ast_true(v->value);
- } else if (!strcasecmp(v->name, "threewaycalling")) {
- threewaycalling = ast_true(v->value);
- } else if (!strcasecmp(v->name, "mwiblink")) {
- mwiblink = ast_true(v->value);
- } else if (!strcasecmp(v->name, "linelabel")) {
- ast_copy_string(linelabel, v->value, sizeof(linelabel));
- } else if (!strcasecmp(v->name, "speeddial")) {
- if (!(sd = ast_calloc(1, sizeof(struct skinny_speeddial)))) {
- return NULL;
- } else {
- char *stringp, *exten, *label;
- stringp = v->value;
- exten = strsep(&stringp, ",");
- label = strsep(&stringp, ",");
- ast_mutex_init(&sd->lock);
- ast_copy_string(sd->exten, exten, sizeof(sd->exten));
- if (label)
- ast_copy_string(sd->label, label, sizeof(sd->label));
- else
- ast_copy_string(sd->label, exten, sizeof(sd->label));
- sd->instance = speeddialInstance++;
-
- sd->parent = d;
-
- sd->next = d->speeddials;
- d->speeddials = sd;
- }
- } else if (!strcasecmp(v->name, "addon")) {
- if (!(a = ast_calloc(1, sizeof(struct skinny_addon)))) {
- return NULL;
- } else {
- ast_mutex_init(&a->lock);
- ast_copy_string(a->type, v->value, sizeof(a->type));
-
- a->next = d->addons;
- d->addons = a;
- }
- } else if (!strcasecmp(v->name, "trunk") || !strcasecmp(v->name, "line")) {
- if (!(l = ast_calloc(1, sizeof(struct skinny_line)))) {
- return NULL;
- } else {
- ast_mutex_init(&l->lock);
- ast_copy_string(l->name, v->value, sizeof(l->name));
-
- /* XXX Should we check for uniqueness?? XXX */
- ast_copy_string(l->context, context, sizeof(l->context));
- ast_copy_string(l->cid_num, cid_num, sizeof(l->cid_num));
- ast_copy_string(l->cid_name, cid_name, sizeof(l->cid_name));
- ast_copy_string(l->label, linelabel, sizeof(l->label));
- ast_copy_string(l->language, language, sizeof(l->language));
- ast_copy_string(l->mohinterpret, mohinterpret, sizeof(l->mohinterpret));
- ast_copy_string(l->mohsuggest, mohsuggest, sizeof(l->mohsuggest));
- ast_copy_string(l->mailbox, mailbox, sizeof(l->mailbox));
- if (!ast_strlen_zero(mailbox)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, d->name, l->name);
- }
- l->msgstate = -1;
- l->capability = d->capability;
- l->prefs = d->prefs;
- l->parent = d;
- if (!strcasecmp(v->name, "trunk")) {
- l->type = TYPE_TRUNK;
- } else {
- l->type = TYPE_LINE;
- }
- l->immediate = immediate;
- l->callgroup = cur_callergroup;
- l->pickupgroup = cur_pickupgroup;
- l->callreturn = callreturn;
- l->cancallforward = cancallforward;
- l->callwaiting = callwaiting;
- l->transfer = transfer;
- l->threewaycalling = threewaycalling;
- l->mwiblink = mwiblink;
- l->onhooktime = time(NULL);
- l->instance = lineInstance++;
- /* ASSUME we're onhook at this point */
- l->hookstate = SKINNY_ONHOOK;
- l->nat = nat;
-
- l->next = d->lines;
- d->lines = l;
- }
- } else {
- ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
- }
- v = v->next;
- }
-
- if (!d->lines) {
- ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n");
- return NULL;
- }
- if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) {
- d->addr.sin_port = htons(DEFAULT_SKINNY_PORT);
- }
-#if 0
- /* I don't think we need this anymore at all, since d->ourip is set in skinny_register now */
- if (d->addr.sin_addr.s_addr) {
- /* XXX See note above, in 'host' option. */
- if (ast_ouraddrfor(&d->addr.sin_addr, &d->ourip)) {
- d->ourip = __ourip;
- }
- } else {
- d->ourip = __ourip;
- }
-#endif
- }
- return d;
-}
-
-static void start_rtp(struct skinny_subchannel *sub)
-{
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- int hasvideo = 0;
-
- ast_mutex_lock(&sub->lock);
- /* Allocate the RTP */
- sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
- if (hasvideo)
- sub->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
-
- if (sub->rtp && sub->owner) {
- sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
- sub->owner->fds[1] = ast_rtcp_fd(sub->rtp);
- }
- if (hasvideo && sub->vrtp && sub->owner) {
- sub->owner->fds[2] = ast_rtp_fd(sub->vrtp);
- sub->owner->fds[3] = ast_rtcp_fd(sub->vrtp);
- }
- if (sub->rtp) {
- ast_rtp_setnat(sub->rtp, l->nat);
- }
- if (sub->vrtp) {
- ast_rtp_setnat(sub->vrtp, l->nat);
- }
- /* Set Frame packetization */
- if (sub->rtp)
- ast_rtp_codec_setpref(sub->rtp, &l->prefs);
-
- /* Create the RTP connection */
- transmit_connect(d->session, sub);
- ast_mutex_unlock(&sub->lock);
-}
-
-static void *skinny_newcall(void *data)
-{
- struct ast_channel *c = data;
- struct skinny_subchannel *sub = c->tech_pvt;
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
- int res = 0;
-
- ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed));
- ast_set_callerid(c,
- l->hidecallerid ? "" : l->cid_num,
- l->hidecallerid ? "" : l->cid_name,
- c->cid.cid_ani ? NULL : l->cid_num);
- ast_setstate(c, AST_STATE_RING);
- if (!sub->rtp) {
- start_rtp(sub);
- }
- res = ast_pbx_run(c);
- if (res) {
- ast_log(LOG_WARNING, "PBX exited non-zero\n");
- transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
- }
- return NULL;
-}
-
-static void *skinny_ss(void *data)
-{
- struct ast_channel *c = data;
- struct skinny_subchannel *sub = c->tech_pvt;
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
- int len = 0;
- int timeout = firstdigittimeout;
- int res = 0;
- int getforward=0;
- int loop_pause = 100;
-
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s@%s'\n", l->name, d->name);
- len = strlen(d->exten);
-
- while (len < AST_MAX_EXTENSION-1) {
-
- res = 1; /* Assume we will get a digit */
- while (strlen(d->exten) == len) {
- ast_safe_sleep(c, loop_pause);
- timeout -= loop_pause;
- if (timeout <= 0){
- res = 0;
- break;
- }
- }
-
- len = strlen(d->exten);
-
- if (!ast_ignore_pattern(c->context, d->exten)) {
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- }
-
- if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) {
- if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) {
- if (getforward) {
- /* Record this as the forwarding extension */
- ast_copy_string(l->call_forward, d->exten, sizeof(l->call_forward));
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n",
- l->call_forward, c->name);
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- if (res) {
- break;
- }
- ast_safe_sleep(c, 500);
- ast_indicate(c, -1);
- ast_safe_sleep(c, 1000);
- memset(d->exten, 0, sizeof(d->exten));
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- len = 0;
- getforward = 0;
- } else {
- ast_copy_string(c->exten, d->exten, sizeof(c->exten));
- ast_copy_string(l->lastnumberdialed, d->exten, sizeof(l->lastnumberdialed));
- memset (d->exten, 0, sizeof(d->exten));
- skinny_newcall(c);
- return NULL;
- }
- } else {
- /* It's a match, but they just typed a digit, and there is an ambiguous match,
- so just set the timeout to matchdigittimeout and wait some more */
- timeout = matchdigittimeout;
- }
- } else if (res == 0) {
- ast_log(LOG_DEBUG, "Not enough digits (and no ambiguous match)...\n");
- memset(d->exten, 0, sizeof(d->exten));
- transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
- if (sub->owner && sub->owner->_state != AST_STATE_UP) {
- ast_indicate(c, -1);
- ast_hangup(c);
- }
- return NULL;
- } else if (!ast_canmatch_extension(c, c->context, d->exten, 1, c->cid.cid_num) &&
- ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
- ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, c->cid.cid_num ? c->cid.cid_num : "<Unknown Caller>", c->context);
- memset(d->exten, 0, sizeof(d->exten));
- transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
- /* hang out for 3 seconds to let congestion play */
- ast_safe_sleep(c, 3000);
- break;
- }
- if (!timeout) {
- timeout = gendigittimeout;
- }
- if (len && !ast_ignore_pattern(c->context, d->exten)) {
- ast_indicate(c, -1);
- }
- }
- if (c)
- ast_hangup(c);
-
- memset(d->exten, 0, sizeof(d->exten));
- return NULL;
-}
-
-
-
-static int skinny_call(struct ast_channel *ast, char *dest, int timeout)
-{
- int res = 0;
- int tone = 0;
- struct skinny_subchannel *sub = ast->tech_pvt;
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
-
- if (!d->registered) {
- ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
- return -1;
- }
-
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name);
- return -1;
- }
-
- if (skinnydebug)
- ast_verbose(VERBOSE_PREFIX_3 "skinny_call(%s)\n", ast->name);
-
- if (l->dnd) {
- ast_queue_control(ast, AST_CONTROL_BUSY);
- return -1;
- }
-
- switch (l->hookstate) {
- case SKINNY_OFFHOOK:
- tone = SKINNY_CALLWAITTONE;
- break;
- case SKINNY_ONHOOK:
- tone = SKINNY_ALERT;
- break;
- default:
- ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate);
- break;
- }
-
- transmit_callstate(s, l->instance, SKINNY_RINGIN, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGIN);
- transmit_displaypromptstatus(s, "Ring-In", 0, l->instance, sub->callid);
- transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, l->cid_name, l->cid_num, l->instance, sub->callid, 1);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
- transmit_ringer_mode(s, SKINNY_RING_INSIDE);
-
- ast_setstate(ast, AST_STATE_RINGING);
- ast_queue_control(ast, AST_CONTROL_RINGING);
- sub->outgoing = 1;
- return res;
-}
-
-static int skinny_hangup(struct ast_channel *ast)
-{
- struct skinny_subchannel *sub = ast->tech_pvt;
- struct skinny_line *l;
- struct skinny_device *d;
- struct skinnysession *s;
-
- if (!sub) {
- ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
- return 0;
- }
- l = sub->parent;
- d = l->parent;
- s = d->session;
- if (skinnydebug)
- ast_verbose("skinny_hangup(%s) on %s@%s\n", ast->name, l->name, d->name);
-
- if (d->registered) {
- if ((l->type = TYPE_LINE) && (l->hookstate == SKINNY_OFFHOOK)) {
- l->hookstate = SKINNY_ONHOOK;
- transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
- transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
- } else if ((l->type = TYPE_LINE) && (l->hookstate == SKINNY_ONHOOK)) {
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid);
- transmit_ringer_mode(s, SKINNY_RING_OFF);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
- do_housekeeping(s);
- }
- }
- ast_mutex_lock(&sub->lock);
- sub->owner = NULL;
- ast->tech_pvt = NULL;
- sub->alreadygone = 0;
- sub->outgoing = 0;
- if (sub->rtp) {
- ast_rtp_destroy(sub->rtp);
- sub->rtp = NULL;
- }
- ast_mutex_unlock(&sub->lock);
- return 0;
-}
-
-static int skinny_answer(struct ast_channel *ast)
-{
- int res = 0;
- struct skinny_subchannel *sub = ast->tech_pvt;
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
- char exten[AST_MAX_EXTENSION] = "";
-
- ast_copy_string(exten, S_OR(ast->macroexten, ast->exten), sizeof(exten));
-
- sub->cxmode = SKINNY_CX_SENDRECV;
- if (!sub->rtp) {
- start_rtp(sub);
- }
- if (skinnydebug)
- ast_verbose("skinny_answer(%s) on %s@%s-%d\n", ast->name, l->name, d->name, sub->callid);
- if (ast->_state != AST_STATE_UP) {
- ast_setstate(ast, AST_STATE_UP);
- }
-
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- /* order matters here...
- for some reason, transmit_callinfo must be before transmit_callstate,
- or you won't get keypad messages in some situations. */
- transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2);
- transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
- transmit_dialednumber(s, exten, l->instance, sub->callid);
- transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
- return res;
-}
-
-/* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
-static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub)
-{
- struct ast_channel *ast = sub->owner;
- struct ast_frame *f;
-
- if (!sub->rtp) {
- /* We have no RTP allocated for this channel */
- return &ast_null_frame;
- }
-
- switch(ast->fdno) {
- case 0:
- f = ast_rtp_read(sub->rtp); /* RTP Audio */
- break;
- case 1:
- f = ast_rtcp_read(sub->rtp); /* RTCP Control Channel */
- break;
- case 2:
- f = ast_rtp_read(sub->vrtp); /* RTP Video */
- break;
- case 3:
- f = ast_rtcp_read(sub->vrtp); /* RTCP Control Channel for video */
- break;
-#if 0
- case 5:
- /* Not yet supported */
- f = ast_udptl_read(sub->udptl); /* UDPTL for T.38 */
- break;
-#endif
- default:
- f = &ast_null_frame;
- }
-
- if (ast) {
- /* We already hold the channel lock */
- if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass != ast->nativeformats) {
- ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
- ast->nativeformats = f->subclass;
- ast_set_read_format(ast, ast->readformat);
- ast_set_write_format(ast, ast->writeformat);
- }
- }
- }
- return f;
-}
-
-static struct ast_frame *skinny_read(struct ast_channel *ast)
-{
- struct ast_frame *fr;
- struct skinny_subchannel *sub = ast->tech_pvt;
- ast_mutex_lock(&sub->lock);
- fr = skinny_rtp_read(sub);
- ast_mutex_unlock(&sub->lock);
- return fr;
-}
-
-static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct skinny_subchannel *sub = ast->tech_pvt;
- int res = 0;
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype == AST_FRAME_IMAGE) {
- return 0;
- } else {
- ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype);
- return 0;
- }
- } else {
- if (!(frame->subclass & ast->nativeformats)) {
- ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
- frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
- return -1;
- }
- }
- if (sub) {
- ast_mutex_lock(&sub->lock);
- if (sub->rtp) {
- res = ast_rtp_write(sub->rtp, frame);
- }
- ast_mutex_unlock(&sub->lock);
- }
- return res;
-}
-
-static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct skinny_subchannel *sub = newchan->tech_pvt;
- ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name);
- if (sub->owner != oldchan) {
- ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
- return -1;
- }
- sub->owner = newchan;
- return 0;
-}
-
-static int skinny_senddigit_begin(struct ast_channel *ast, char digit)
-{
- return -1; /* Start inband indications */
-}
-
-static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
-#if 0
- struct skinny_subchannel *sub = ast->tech_pvt;
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- int tmp;
- /* not right */
- sprintf(tmp, "%d", digit);
- transmit_tone(d->session, digit, l->instance, sub->callid);
-#endif
- return -1; /* Stop inband indications */
-}
-
-static char *control2str(int ind) {
- char *tmp;
-
- switch (ind) {
- case AST_CONTROL_HANGUP:
- return "Other end has hungup";
- case AST_CONTROL_RING:
- return "Local ring";
- case AST_CONTROL_RINGING:
- return "Remote end is ringing";
- case AST_CONTROL_ANSWER:
- return "Remote end has answered";
- case AST_CONTROL_BUSY:
- return "Remote end is busy";
- case AST_CONTROL_TAKEOFFHOOK:
- return "Make it go off hook";
- case AST_CONTROL_OFFHOOK:
- return "Line is off hook";
- case AST_CONTROL_CONGESTION:
- return "Congestion (circuits busy)";
- case AST_CONTROL_FLASH:
- return "Flash hook";
- case AST_CONTROL_WINK:
- return "Wink";
- case AST_CONTROL_OPTION:
- return "Set a low-level option";
- case AST_CONTROL_RADIO_KEY:
- return "Key Radio";
- case AST_CONTROL_RADIO_UNKEY:
- return "Un-Key Radio";
- case AST_CONTROL_PROGRESS:
- return "Remote end is making Progress";
- case AST_CONTROL_PROCEEDING:
- return "Remote end is proceeding";
- case AST_CONTROL_HOLD:
- return "Hold";
- case AST_CONTROL_UNHOLD:
- return "Unhold";
- case -1:
- return "Stop tone";
- default:
- if (!(tmp = ast_threadstorage_get(&control2str_threadbuf, CONTROL2STR_BUFSIZE)))
- return "Unknown";
- snprintf(tmp, CONTROL2STR_BUFSIZE, "UNKNOWN-%d", ind);
- return tmp;
- }
-}
-
-
-static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
-{
- struct skinny_subchannel *sub = ast->tech_pvt;
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
- char exten[AST_MAX_EXTENSION] = "";
-
- if (!s) {
- ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast->name);
- return -1;
- }
-
- ast_copy_string(exten, S_OR(ast->macroexten, ast->exten), sizeof(exten));
-
- if (skinnydebug)
- ast_verbose(VERBOSE_PREFIX_3 "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name);
- switch(ind) {
- case AST_CONTROL_RINGING:
- if (ast->_state != AST_STATE_UP) {
- if (!sub->progress) {
- if (!d->earlyrtp) {
- transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
- }
- transmit_callstate(s, l->instance, SKINNY_RINGOUT, sub->callid);
- transmit_dialednumber(s, exten, l->instance, sub->callid);
- transmit_displaypromptstatus(s, "Ring Out", 0, l->instance, sub->callid);
- transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
- sub->ringing = 1;
- if (!d->earlyrtp) {
- break;
- }
- }
- }
- return -1; /* Tell asterisk to provide inband signalling */
- case AST_CONTROL_BUSY:
- if (ast->_state != AST_STATE_UP) {
- if (!d->earlyrtp) {
- transmit_tone(s, SKINNY_BUSYTONE, l->instance, sub->callid);
- }
- transmit_callstate(s, l->instance, SKINNY_BUSY, sub->callid);
- sub->alreadygone = 1;
- ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
- if (!d->earlyrtp) {
- break;
- }
- }
- return -1; /* Tell asterisk to provide inband signalling */
- case AST_CONTROL_CONGESTION:
- if (ast->_state != AST_STATE_UP) {
- if (!d->earlyrtp) {
- transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
- }
- transmit_callstate(s, l->instance, SKINNY_CONGESTION, sub->callid);
- sub->alreadygone = 1;
- ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
- if (!d->earlyrtp) {
- break;
- }
- }
- return -1; /* Tell asterisk to provide inband signalling */
- case AST_CONTROL_PROGRESS:
- if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) {
- if (!d->earlyrtp) {
- transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
- }
- transmit_callstate(s, l->instance, SKINNY_PROGRESS, sub->callid);
- transmit_displaypromptstatus(s, "Call Progress", 0, l->instance, sub->callid);
- transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
- sub->progress = 1;
- if (!d->earlyrtp) {
- break;
- }
- }
- return -1; /* Tell asterisk to provide inband signalling */
- case -1: /* STOP_TONE */
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- break;
- case AST_CONTROL_HOLD:
- ast_moh_start(ast, data, l->mohinterpret);
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(ast);
- break;
- case AST_CONTROL_PROCEEDING:
- break;
- case AST_CONTROL_SRCUPDATE:
- ast_rtp_new_source(sub->rtp);
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
- return -1; /* Tell asterisk to provide inband signalling */
- }
- return 0;
-}
-
-static struct ast_channel *skinny_new(struct skinny_line *l, int state)
-{
- struct ast_channel *tmp;
- struct skinny_subchannel *sub;
- struct skinny_device *d = l->parent;
- int fmt;
-
- tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
- if (!tmp) {
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- return NULL;
- } else {
- sub = ast_calloc(1, sizeof(struct skinny_subchannel));
- if (!sub) {
- ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n");
- return NULL;
- } else {
- ast_mutex_init(&sub->lock);
-
- sub->owner = tmp;
- sub->callid = callnums++;
- d->lastlineinstance = l->instance;
- d->lastcallreference = sub->callid;
- sub->cxmode = SKINNY_CX_INACTIVE;
- sub->nat = l->nat;
- sub->parent = l;
- sub->onhold = 0;
-
- sub->next = l->sub;
- l->sub = sub;
- }
- tmp->tech = &skinny_tech;
- tmp->tech_pvt = sub;
- tmp->nativeformats = l->capability;
- if (!tmp->nativeformats)
- tmp->nativeformats = default_capability;
- fmt = ast_best_codec(tmp->nativeformats);
- if (skinnydebug)
- ast_verbose("skinny_new: tmp->nativeformats=%d fmt=%d\n", tmp->nativeformats, fmt);
- if (sub->rtp) {
- tmp->fds[0] = ast_rtp_fd(sub->rtp);
- }
- if (state == AST_STATE_RING) {
- tmp->rings = 1;
- }
- tmp->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp->rawreadformat = fmt;
- if (!ast_strlen_zero(l->language))
- ast_string_field_set(tmp, language, l->language);
- if (!ast_strlen_zero(l->accountcode))
- ast_string_field_set(tmp, accountcode, l->accountcode);
- if (l->amaflags)
- tmp->amaflags = l->amaflags;
-
- ast_module_ref(ast_module_info->self);
- tmp->callgroup = l->callgroup;
- tmp->pickupgroup = l->pickupgroup;
- ast_string_field_set(tmp, call_forward, l->call_forward);
- ast_copy_string(tmp->context, l->context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, l->exten, sizeof(tmp->exten));
-
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(l->cid_num);
-
- tmp->priority = 1;
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
-
- if (sub->rtp)
- ast_jb_configure(tmp, &global_jbconf);
-
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- tmp = NULL;
- }
- }
- }
- return tmp;
-}
-
-static int skinny_hold(struct skinny_subchannel *sub)
-{
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
- struct skinny_req *req;
-
- /* Don't try to hold a channel that doesn't exist */
- if (!sub || !sub->owner)
- return 0;
-
- /* Channel needs to be put on hold */
- if (skinnydebug)
- ast_verbose("Putting on Hold(%d)\n", l->instance);
-
- ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
- S_OR(l->mohsuggest, NULL),
- !ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0);
-
- if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
- return 0;
-
- req->data.activatecallplane.lineInstance = htolel(l->instance);
- transmit_response(s, req);
-
- if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
- return 0;
-
- req->data.closereceivechannel.conferenceId = htolel(sub->callid);
- req->data.closereceivechannel.partyId = htolel(sub->callid);
- transmit_response(s, req);
-
- if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
- return 0;
-
- req->data.stopmedia.conferenceId = htolel(sub->callid);
- req->data.stopmedia.passThruPartyId = htolel(sub->callid);
- transmit_response(s, req);
-
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
- sub->onhold = 1;
- return 1;
-}
-
-static int skinny_unhold(struct skinny_subchannel *sub)
-{
- struct skinny_line *l = sub->parent;
- struct skinny_device *d = l->parent;
- struct skinnysession *s = d->session;
- struct skinny_req *req;
-
- /* Don't try to unhold a channel that doesn't exist */
- if (!sub || !sub->owner)
- return 0;
-
- /* Channel is on hold, so we will unhold */
- if (skinnydebug)
- ast_verbose("Taking off Hold(%d)\n", l->instance);
-
- ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
-
- if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
- return 0;
-
- req->data.activatecallplane.lineInstance = htolel(l->instance);
- transmit_response(s, req);
-
- transmit_connect(s, sub);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
- sub->onhold = 0;
- return 1;
-}
-
-static int handle_keep_alive_message(struct skinny_req *req, struct skinnysession *s)
-{
- if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE)))
- return -1;
-
- transmit_response(s, req);
- do_housekeeping(s);
- return 1;
-}
-
-static int handle_register_message(struct skinny_req *req, struct skinnysession *s)
-{
- char name[16];
- int res;
-
- memcpy(&name, req->data.reg.name, sizeof(name));
-
- res = skinny_register(req, s);
- if (!res) {
- ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", name);
- if (!(req = req_alloc(sizeof(struct register_rej_message), REGISTER_REJ_MESSAGE)))
- return -1;
-
- snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name);
- transmit_response(s, req);
- return 0;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Device '%s' successfully registered\n", name);
-
- if (!(req = req_alloc(sizeof(struct register_ack_message), REGISTER_ACK_MESSAGE)))
- return -1;
-
- req->data.regack.res[0] = '0';
- req->data.regack.res[1] = '\0';
- req->data.regack.keepAlive = htolel(keep_alive);
- memcpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate));
- req->data.regack.res2[0] = '0';
- req->data.regack.res2[1] = '\0';
- req->data.regack.secondaryKeepAlive = htolel(keep_alive);
- transmit_response(s, req);
- if (skinnydebug)
- ast_verbose("Requesting capabilities\n");
-
- if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE)))
- return -1;
-
- transmit_response(s, req);
-
- return res;
-}
-
-static int handle_ip_port_message(struct skinny_req *req, struct skinnysession *s)
-{
- /* no response necessary */
- return 1;
-}
-
-static int handle_keypad_button_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_subchannel *sub = NULL;
- struct skinny_line *l;
- struct skinny_device *d = s->device;
- struct ast_frame f = { 0, };
- char dgt;
- int digit;
- int lineInstance;
- int callReference;
-
- digit = letohl(req->data.keypad.button);
- lineInstance = letohl(req->data.keypad.lineInstance);
- callReference = letohl(req->data.keypad.callReference);
-
- if (digit == 14) {
- dgt = '*';
- } else if (digit == 15) {
- dgt = '#';
- } else if (digit >= 0 && digit <= 9) {
- dgt = '0' + digit;
- } else {
- /* digit=10-13 (A,B,C,D ?), or
- * digit is bad value
- *
- * probably should not end up here, but set
- * value for backward compatibility, and log
- * a warning.
- */
- dgt = '0' + digit;
- ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
- }
-
- f.subclass = dgt;
-
- f.src = "skinny";
-
- if (lineInstance && callReference)
- sub = find_subchannel_by_instance_reference(d, lineInstance, callReference);
- else
- sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
-
- if (!sub)
- return 0;
-
- l = sub->parent;
- if (sub->owner) {
- if (sub->owner->_state == 0) {
- f.frametype = AST_FRAME_DTMF_BEGIN;
- ast_queue_frame(sub->owner, &f);
- }
- /* XXX MUST queue this frame to all lines in threeway call if threeway call is active */
- f.frametype = AST_FRAME_DTMF_END;
- ast_queue_frame(sub->owner, &f);
- /* XXX This seriously needs to be fixed */
- if (sub->next && sub->next->owner) {
- if (sub->owner->_state == 0) {
- f.frametype = AST_FRAME_DTMF_BEGIN;
- ast_queue_frame(sub->next->owner, &f);
- }
- f.frametype = AST_FRAME_DTMF_END;
- ast_queue_frame(sub->next->owner, &f);
- }
- } else {
- if (skinnydebug)
- ast_verbose("No owner: %s\n", l->name);
- }
- return 1;
-}
-
-static int handle_stimulus_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- struct skinny_subchannel *sub;
- /*struct skinny_speeddial *sd;*/
- struct ast_channel *c;
- pthread_t t;
- int event;
- int instance;
- int callreference;
- /*int res = 0;*/
-
- event = letohl(req->data.stimulus.stimulus);
- instance = letohl(req->data.stimulus.stimulusInstance);
- callreference = letohl(req->data.stimulus.callreference);
- if (skinnydebug)
- ast_verbose("callreference in handle_stimulus_message is '%d'\n", callreference);
-
- /* Note that this call should be using the passed in instance and callreference */
- sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
-
- if (!sub) {
- l = find_line_by_instance(d, d->lastlineinstance);
- if (!l) {
- return 0;
- }
- } else {
- l = sub->parent;
- }
-
- switch(event) {
- case STIMULUS_REDIAL:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Redial(%d/%d)\n", instance, callreference);
-
-#if 0
- if (ast_strlen_zero(l->lastnumberdialed)) {
- ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n");
- l->hookstate = SKINNY_ONHOOK;
- transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
- transmit_callstate(s, l->instance, SKINNY_ONHOOK, instance);
- break;
- }
-
- c = skinny_new(l, AST_STATE_DOWN);
- if(!c) {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- } else {
- sub = c->tech_pvt;
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
-
- if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- }
- ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
- if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
- ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- }
-#endif
- break;
- case STIMULUS_SPEEDDIAL:
- if (skinnydebug)
- ast_verbose("Received Stimulus: SpeedDial(%d/%d)\n", instance, callreference);
-
-#if 0
- if (!(sd = find_speeddial_by_instance(d, instance))) {
- return 0;
- }
-
- if (ast_strlen_zero(l->lastnumberdialed)) {
- ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n");
- l->hookstate = SKINNY_ONHOOK;
- transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
- transmit_callstate(s, l->instance, SKINNY_ONHOOK, instance);
- break;
- }
-
- c = skinny_new(l, AST_STATE_DOWN);
- if(c) {
- sub = c->tech_pvt;
- l = sub->parent;
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
-
- if (!ast_ignore_pattern(c->context, sd->exten)) {
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- }
- if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) {
- if (!ast_matchmore_extension(c, c->context, sd->exten, 1, l->cid_num)) {
- ast_copy_string(c->exten, sd->exten, sizeof(c->exten));
- ast_copy_string(l->lastnumberdialed, sd->exten, sizeof(l->lastnumberdialed));
- skinny_newcall(c);
- break;
- }
- }
- } else {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- }
-#endif
- break;
- case STIMULUS_HOLD:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Hold(%d/%d)\n", instance, callreference);
-
- if (!sub)
- break;
-
- if (sub->onhold) {
- skinny_unhold(sub);
- } else {
- skinny_hold(sub);
- }
- break;
- case STIMULUS_TRANSFER:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Transfer(%d/%d)\n", instance, callreference);
- /* XXX figure out how to transfer */
- break;
- case STIMULUS_CONFERENCE:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Conference(%d/%d)\n", instance, callreference);
- /* XXX determine the best way to pull off a conference. Meetme? */
- break;
- case STIMULUS_VOICEMAIL:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Voicemail(%d/%d)\n", instance, callreference);
- /* XXX Find and dial voicemail extension */
- break;
- case STIMULUS_CALLPARK:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Park Call(%d/%d)\n", instance, callreference);
- /* XXX Park the call */
- break;
- case STIMULUS_FORWARDALL:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Forward All(%d/%d)\n", instance, callreference);
- /* Why is DND under FORWARDALL? */
- /* Because it's the same thing. */
-
- /* Do not disturb */
- if (l->dnd != 0){
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Disabling DND on %s@%s\n", l->name, d->name);
- l->dnd = 0;
- transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
- transmit_displaynotify(s, "DnD disabled", 10);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Enabling DND on %s@%s\n", l->name, d->name);
- l->dnd = 1;
- transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF);
- transmit_displaynotify(s, "DnD enabled", 10);
- }
- break;
- case STIMULUS_FORWARDBUSY:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference);
- break;
- case STIMULUS_FORWARDNOANSWER:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Forward No Answer (%d/%d)\n", instance, callreference);
- break;
- case STIMULUS_DISPLAY:
- /* Not sure what this is */
- if (skinnydebug)
- ast_verbose("Received Stimulus: Display(%d/%d)\n", instance, callreference);
- break;
- case STIMULUS_LINE:
- if (skinnydebug)
- ast_verbose("Received Stimulus: Line(%d/%d)\n", instance, callreference);
-
- l = find_line_by_instance(s->device, instance);
-
- if (!l) {
- return 0;
- }
-
- /* turn the speaker on */
- transmit_speaker_mode(s, SKINNY_SPEAKERON);
- transmit_ringer_mode(s, SKINNY_RING_OFF);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
-
- l->hookstate = SKINNY_OFFHOOK;
-
- if (sub && sub->outgoing) {
- /* We're answering a ringing call */
- ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
- transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
- start_rtp(sub);
- ast_setstate(sub->owner, AST_STATE_UP);
- } else {
- if (sub && sub->owner) {
- ast_log(LOG_DEBUG, "Current subchannel [%s] already has owner\n", sub->owner->name);
- } else {
- c = skinny_new(l, AST_STATE_DOWN);
- if(c) {
- sub = c->tech_pvt;
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
-
- /* start the switch thread */
- if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
- ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- } else {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- }
- }
- }
- break;
- default:
- if (skinnydebug)
- ast_verbose("RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference);
- break;
- }
- return 1;
-}
-
-static int handle_offhook_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- struct skinny_subchannel *sub;
- struct ast_channel *c;
- pthread_t t;
- int unknown1;
- int unknown2;
-
- unknown1 = letohl(req->data.offhook.unknown1);
- unknown2 = letohl(req->data.offhook.unknown2);
-
- sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
-
- if (!sub) {
- l = find_line_by_instance(d, d->lastlineinstance);
- if (!l) {
- return 0;
- }
- } else {
- l = sub->parent;
- }
-
- transmit_ringer_mode(s, SKINNY_RING_OFF);
- l->hookstate = SKINNY_OFFHOOK;
-
- if (sub && sub->onhold) {
- return 1;
- }
-
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
-
- if (sub && sub->outgoing) {
- /* We're answering a ringing call */
- ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
- start_rtp(sub);
- ast_setstate(sub->owner, AST_STATE_UP);
- } else {
- if (sub && sub->owner) {
- ast_log(LOG_DEBUG, "Current sub [%s] already has owner\n", sub->owner->name);
- } else {
- c = skinny_new(l, AST_STATE_DOWN);
- if(c) {
- sub = c->tech_pvt;
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
-
- /* start the switch thread */
- if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
- ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- } else {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- }
- }
- }
- return 1;
-}
-
-static int handle_onhook_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- struct skinny_subchannel *sub;
- int unknown1;
- int unknown2;
-
- unknown1 = letohl(req->data.onhook.unknown1);
- unknown2 = letohl(req->data.onhook.unknown2);
-
- sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
-
- if (!sub) {
- return 0;
- }
- l = sub->parent;
-
- if (l->hookstate == SKINNY_ONHOOK) {
- /* Something else already put us back on hook */
- return 0;
- }
- l->hookstate = SKINNY_ONHOOK;
-
- if (sub->onhold) {
- return 0;
- }
-
- sub->cxmode = SKINNY_CX_RECVONLY;
- transmit_callstate(s, l->instance, l->hookstate, sub->callid);
- if (skinnydebug)
- ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
- if (l->transfer && (sub->owner && sub->next && sub->next->owner) && ((!sub->outgoing) || (sub->next && !sub->next->outgoing))) {
- /* We're allowed to transfer, we have two active calls and
- we made at least one of the calls. Let's try and transfer */
-
-#if 0
- if ((res = attempt_transfer(p)) < 0) {
- if (sub->next && sub->next->owner) {
- sub->next->alreadygone = 1;
- ast_queue_hangup(sub->next->owner,1);
- }
- } else if (res) {
- ast_log(LOG_WARNING, "Transfer attempt failed\n");
- return 0;
- }
-#endif
- } else {
- /* Hangup the current call */
- /* If there is another active call, skinny_hangup will ring the phone with the other call */
- if (sub->owner) {
- sub->alreadygone = 1;
- ast_queue_hangup(sub->owner);
- } else {
- ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n",
- l->name, d->name, sub->callid);
- }
- }
- if ((l->hookstate == SKINNY_ONHOOK) && (sub->next && !sub->next->rtp)) {
- do_housekeeping(s);
- }
- return 1;
-}
-
-static int handle_capabilities_res_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- uint32_t count = 0;
- int codecs = 0;
- int i;
-
- count = letohl(req->data.caps.count);
- if (count > SKINNY_MAX_CAPABILITIES) {
- count = SKINNY_MAX_CAPABILITIES;
- ast_log(LOG_WARNING, "Received more capabilities than we can handle (%d). Ignoring the rest.\n", SKINNY_MAX_CAPABILITIES);
- }
-
- for (i = 0; i < count; i++) {
- int acodec = 0;
- int scodec = 0;
- scodec = letohl(req->data.caps.caps[i].codec);
- acodec = codec_skinny2ast(scodec);
- if (skinnydebug)
- ast_verbose("Adding codec capability '%d (%d)'\n", acodec, scodec);
- codecs |= acodec;
- }
-
- d->capability &= codecs;
- ast_verbose("Device capability set to '%d'\n", d->capability);
- for (l = d->lines; l; l = l->next) {
- ast_mutex_lock(&l->lock);
- l->capability = d->capability;
- ast_mutex_unlock(&l->lock);
- }
-
- return 1;
-}
-
-static int handle_speed_dial_stat_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_speeddial *sd;
- int instance;
-
- instance = letohl(req->data.speeddialreq.speedDialNumber);
-
- sd = find_speeddial_by_instance(d, instance);
-
- if (!sd) {
- return 0;
- }
-
- if (!(req = req_alloc(sizeof(struct speed_dial_stat_res_message), SPEED_DIAL_STAT_RES_MESSAGE)))
- return -1;
-
- req->data.speeddialreq.speedDialNumber = htolel(instance);
- snprintf(req->data.speeddial.speedDialDirNumber, sizeof(req->data.speeddial.speedDialDirNumber), sd->exten);
- snprintf(req->data.speeddial.speedDialDisplayName, sizeof(req->data.speeddial.speedDialDisplayName), sd->label);
-
- transmit_response(s, req);
- return 1;
-}
-
-static int handle_line_state_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- int instance;
-
- instance = letohl(req->data.line.lineNumber);
-
- ast_mutex_lock(&devicelock);
-
- l = find_line_by_instance(d, instance);
-
- if (!l) {
- return 0;
- }
-
- ast_mutex_unlock(&devicelock);
-
- if (!(req = req_alloc(sizeof(struct line_stat_res_message), LINE_STAT_RES_MESSAGE)))
- return -1;
-
- req->data.linestat.lineNumber = letohl(instance);
- memcpy(req->data.linestat.lineDirNumber, l->name,
- sizeof(req->data.linestat.lineDirNumber));
- memcpy(req->data.linestat.lineDisplayName, l->label,
- sizeof(req->data.linestat.lineDisplayName));
- transmit_response(s,req);
- return 1;
-}
-
-static int handle_time_date_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- time_t timer;
- struct tm *cmtime;
-
- if (!(req = req_alloc(sizeof(struct definetimedate_message), DEFINETIMEDATE_MESSAGE)))
- return -1;
-
- timer = time(NULL);
- cmtime = localtime(&timer);
- req->data.definetimedate.year = htolel(cmtime->tm_year+1900);
- req->data.definetimedate.month = htolel(cmtime->tm_mon+1);
- req->data.definetimedate.dayofweek = htolel(cmtime->tm_wday);
- req->data.definetimedate.day = htolel(cmtime->tm_mday);
- req->data.definetimedate.hour = htolel(cmtime->tm_hour);
- req->data.definetimedate.minute = htolel(cmtime->tm_min);
- req->data.definetimedate.seconds = htolel(cmtime->tm_sec);
- req->data.definetimedate.milliseconds = htolel(0);
- req->data.definetimedate.timestamp = htolel(timer);
- transmit_response(s, req);
- return 1;
-}
-
-static int handle_button_template_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- int i;
-
- struct skinny_speeddial *sd;
- struct button_definition_template btn[42];
- int lineInstance = 1;
- int speeddialInstance = 1;
- int buttonCount = 0;
-
- if (!(req = req_alloc(sizeof(struct button_template_res_message), BUTTON_TEMPLATE_RES_MESSAGE)))
- return -1;
-
- memset(&btn, 0, sizeof(btn));
-
- get_button_template(s, btn);
-
- for (i=0; i<42; i++) {
- int btnSet = 0;
- switch (btn[i].buttonDefinition) {
- case BT_CUST_LINESPEEDDIAL:
- /* assume failure */
- req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
- req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
-
- for (l = d->lines; l; l = l->next) {
- if (l->instance == lineInstance) {
- ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
- req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
- req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance);
- lineInstance++;
- buttonCount++;
- btnSet = 1;
- break;
- }
- }
-
- if (!btnSet) {
- for (sd = d->speeddials; sd; sd = sd->next) {
- if (sd->instance == speeddialInstance) {
- ast_verbose("Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
- req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
- req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance);
- speeddialInstance++;
- buttonCount++;
- btnSet = 1;
- break;
- }
- }
- }
- break;
- case BT_LINE:
- req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE);
- req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
-
- for (l = d->lines; l; l = l->next) {
- if (l->instance == lineInstance) {
- ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
- req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
- req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance);
- lineInstance++;
- buttonCount++;
- btnSet = 1;
- break;
- }
- }
- break;
- case BT_SPEEDDIAL:
- req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
- req->data.buttontemplate.definition[i].instanceNumber = 0;
-
- for (sd = d->speeddials; sd; sd = sd->next) {
- if (sd->instance == speeddialInstance) {
- ast_verbose("Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
- req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
- req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance);
- speeddialInstance++;
- buttonCount++;
- btnSet = 1;
- break;
- }
- }
- break;
- case BT_CUST_HINT:
- break;
- case BT_NONE:
- break;
- default:
- ast_verbose("Adding button: %d, %d\n", btn[i].buttonDefinition, 0);
- req->data.buttontemplate.definition[i].buttonDefinition = htolel(btn[i].buttonDefinition);
- req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
- buttonCount++;
- btnSet = 1;
- break;
- }
- }
-
- req->data.buttontemplate.buttonOffset = htolel(0);
- req->data.buttontemplate.buttonCount = htolel(buttonCount);
- req->data.buttontemplate.totalButtonCount = htolel(buttonCount);
-
- if (skinnydebug)
- ast_verbose("Sending %d template to %s\n",
- d->type,
- d->name);
- transmit_response(s, req);
- return 1;
-}
-
-static int handle_version_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- if (!(req = req_alloc(sizeof(struct version_res_message), VERSION_RES_MESSAGE)))
- return -1;
-
- snprintf(req->data.version.version, sizeof(req->data.version.version), d->version_id);
- transmit_response(s, req);
- return 1;
-}
-
-static int handle_server_request_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- if (!(req = req_alloc(sizeof(struct server_res_message), SERVER_RES_MESSAGE)))
- return -1;
-
- memcpy(req->data.serverres.server[0].serverName, ourhost,
- sizeof(req->data.serverres.server[0].serverName));
- req->data.serverres.serverListenPort[0] = htolel(ourport);
- req->data.serverres.serverIpAddr[0] = htolel(d->ourip.s_addr);
- transmit_response(s, req);
- return 1;
-}
-
-static int handle_alarm_message(struct skinny_req *req, struct skinnysession *s)
-{
- /* no response necessary */
- if (skinnydebug)
- ast_verbose("Received Alarm Message: %s\n", req->data.alarm.displayMessage);
-
- return 1;
-}
-
-static int handle_open_receive_channel_ack_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- struct skinny_subchannel *sub;
- struct ast_format_list fmt;
- struct sockaddr_in sin;
- struct sockaddr_in us;
- uint32_t addr;
- int port;
- int status;
- int passthruid;
-
- status = letohl(req->data.openreceivechannelack.status);
- if (status) {
- ast_log(LOG_ERROR, "Open Receive Channel Failure\n");
- return 0;
- }
- addr = letohl(req->data.openreceivechannelack.ipAddr);
- port = letohl(req->data.openreceivechannelack.port);
- passthruid = letohl(req->data.openreceivechannelack.passThruId);
-
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = addr;
- sin.sin_port = htons(port);
-
- sub = find_subchannel_by_reference(d, passthruid);
-
- if (!sub)
- return 0;
-
- l = sub->parent;
-
- if (sub->rtp) {
- ast_rtp_set_peer(sub->rtp, &sin);
- ast_rtp_get_us(sub->rtp, &us);
- } else {
- ast_log(LOG_ERROR, "No RTP structure, this is very bad\n");
- return 0;
- }
-
- if (skinnydebug) {
- ast_verbose("ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- ast_verbose("ourip = %s:%d\n", ast_inet_ntoa(d->ourip), ntohs(us.sin_port));
- }
-
- if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
- return -1;
-
- fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
-
- if (skinnydebug)
- ast_verbose("Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms);
-
- req->data.startmedia.conferenceId = htolel(sub->callid);
- req->data.startmedia.passThruPartyId = htolel(sub->callid);
- req->data.startmedia.remoteIp = htolel(d->ourip.s_addr);
- req->data.startmedia.remotePort = htolel(ntohs(us.sin_port));
- req->data.startmedia.packetSize = htolel(fmt.cur_ms);
- req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits));
- req->data.startmedia.qualifier.precedence = htolel(127);
- req->data.startmedia.qualifier.vad = htolel(0);
- req->data.startmedia.qualifier.packets = htolel(0);
- req->data.startmedia.qualifier.bitRate = htolel(0);
- transmit_response(s, req);
-
- return 1;
-}
-
-static int handle_enbloc_call_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- struct skinny_subchannel *sub = NULL;
- struct ast_channel *c;
- pthread_t t;
-
- if (skinnydebug)
- ast_verbose("Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty);
-
- sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
-
- if (!sub) {
- l = find_line_by_instance(d, d->lastlineinstance);
- if (!l) {
- return 0;
- }
- } else {
- l = sub->parent;
- }
-
- c = skinny_new(l, AST_STATE_DOWN);
-
- if(!c) {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- } else {
- l->hookstate = SKINNY_OFFHOOK;
-
- sub = c->tech_pvt;
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-
- if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) {
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- }
- ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten));
- if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
- ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- }
-
- return 1;
-}
-
-
-static int handle_soft_key_set_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- int i;
- int x;
- int y;
- const struct soft_key_definitions *softkeymode = soft_key_default_definitions;
-
- if (!(req = req_alloc(sizeof(struct soft_key_set_res_message), SOFT_KEY_SET_RES_MESSAGE)))
- return -1;
-
- req->data.softkeysets.softKeySetOffset = htolel(0);
- req->data.softkeysets.softKeySetCount = htolel(11);
- req->data.softkeysets.totalSoftKeySetCount = htolel(11);
- for (x = 0; x < sizeof(soft_key_default_definitions) / sizeof(struct soft_key_definitions); x++) {
- const uint8_t *defaults = softkeymode->defaults;
- /* XXX I wanted to get the size of the array dynamically, but that wasn't wanting to work.
- This will have to do for now. */
- for (y = 0; y < softkeymode->count; y++) {
- for (i = 0; i < (sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); i++) {
- if (defaults[y] == i+1) {
- req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyTemplateIndex[y] = htolel(i+1);
- req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyInfoIndex[y] = htolel(i+301);
- }
- }
- }
- softkeymode++;
- }
- transmit_response(s,req);
- transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
- return 1;
-}
-
-static int handle_soft_key_event_message(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d = s->device;
- struct skinny_line *l;
- struct skinny_subchannel *sub = NULL;
- struct ast_channel *c;
- pthread_t t;
- int event;
- int instance;
- int callreference;
-
- event = letohl(req->data.softkeyeventmessage.softKeyEvent);
- instance = letohl(req->data.softkeyeventmessage.instance);
- callreference = letohl(req->data.softkeyeventmessage.callreference);
-
- if (instance) {
- l = find_line_by_instance(d, instance);
- if (callreference) {
- sub = find_subchannel_by_instance_reference(d, instance, callreference);
- } else {
- sub = find_subchannel_by_instance_reference(d, instance, d->lastcallreference);
- }
- } else {
- l = find_line_by_instance(d, d->lastlineinstance);
- }
-
- if (!l) {
- if (skinnydebug)
- ast_verbose("Received Softkey Event: %d(%d/%d)\n", event, instance, callreference);
- return 0;
- }
-
- switch(event) {
- case SOFTKEY_NONE:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: None(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_REDIAL:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Redial(%d/%d)\n", instance, callreference);
-
-#if 0
- if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
- } else {
- c = sub->owner;
- }
-
- if(!c) {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- } else {
- sub = c->tech_pvt;
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
-
- if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- }
- ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
- if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
- ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- }
-#endif
- break;
- case SOFTKEY_NEWCALL: /* Actually the DIAL softkey */
- if (skinnydebug)
- ast_verbose("Received Softkey Event: New Call(%d/%d)\n", instance, callreference);
-
- if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
- } else {
- c = sub->owner;
- }
-
- if (!c) {
- ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
- } else {
- sub = c->tech_pvt;
- if (l->hookstate == SKINNY_ONHOOK) {
- l->hookstate = SKINNY_OFFHOOK;
- transmit_speaker_mode(s, SKINNY_SPEAKERON);
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- }
-
- if (skinnydebug)
- ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
- transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
- transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
-
- /* start the switch thread */
- if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
- ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
- ast_hangup(c);
- }
- }
- break;
- case SOFTKEY_HOLD:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Hold(%d/%d)\n", instance, callreference);
-
- if (sub) {
- if (sub->onhold) {
- skinny_unhold(sub);
- } else {
- skinny_hold(sub);
- }
- }
-
- break;
- case SOFTKEY_TRNSFER:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Transfer(%d/%d)\n", instance, callreference);
- /* XXX figure out how to transfer */
- break;
- case SOFTKEY_CFWDALL:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Forward All(%d/%d)\n", instance, callreference);
-
- /* Do not disturb */
- if (l->dnd != 0){
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Disabling DND on %s@%s\n", l->name, d->name);
- l->dnd = 0;
- transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
- transmit_displaynotify(s, "DnD disabled", 10);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Enabling DND on %s@%s\n", l->name, d->name);
- l->dnd = 1;
- transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF);
- transmit_displaynotify(s, "DnD enabled", 10);
- }
- break;
- case SOFTKEY_CFWDBUSY:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_CFWDNOANSWER:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Forward No Answer (%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_BKSPC:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Backspace(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_ENDCALL:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: End Call(%d/%d)\n", instance, callreference);
-
- if (l->hookstate == SKINNY_ONHOOK) {
- /* Something else already put us back on hook */
- break;
- }
- if (sub) {
- sub->cxmode = SKINNY_CX_RECVONLY;
- l->hookstate = SKINNY_ONHOOK;
- transmit_callstate(s, l->instance, l->hookstate, sub->callid);
- if (skinnydebug)
- ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
- if (l->transfer && (sub->owner && sub->next && sub->next->owner) && ((!sub->outgoing) || (sub->next && !sub->next->outgoing))) {
- /* We're allowed to transfer, we have two active calls and
- we made at least one of the calls. Let's try and transfer */
-
-#if 0
- if ((res = attempt_transfer(p)) < 0) {
- if (sub->next && sub->next->owner) {
- sub->next->alreadygone = 1;
- ast_queue_hangup(sub->next->owner, 1);
- }
- } else if (res) {
- ast_log(LOG_WARNING, "Transfer attempt failed\n");
- break;
- }
-#endif
- } else {
- /* Hangup the current call */
- /* If there is another active call, skinny_hangup will ring the phone with the other call */
- if (sub->owner) {
- sub->alreadygone = 1;
- ast_queue_hangup(sub->owner);
- } else {
- ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n",
- l->name, d->name, sub->callid);
- }
- }
- if ((l->hookstate == SKINNY_ONHOOK) && (sub->next && !sub->next->rtp)) {
- do_housekeeping(s);
- }
- }
- break;
- case SOFTKEY_RESUME:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Resume(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_ANSWER:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Answer(%d/%d)\n", instance, callreference);
-
- transmit_ringer_mode(s,SKINNY_RING_OFF);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
-
- l->hookstate = SKINNY_OFFHOOK;
-
- if (sub && sub->outgoing) {
- /* We're answering a ringing call */
- ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
- transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
- transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
- transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
- transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
- start_rtp(sub);
- ast_setstate(sub->owner, AST_STATE_UP);
- }
- break;
- case SOFTKEY_INFO:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Info(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_CONFRN:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Conference(%d/%d)\n", instance, callreference);
- /* XXX determine the best way to pull off a conference. Meetme? */
- break;
- case SOFTKEY_PARK:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Park Call(%d/%d)\n", instance, callreference);
- /* XXX Park the call */
- break;
- case SOFTKEY_JOIN:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Join(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_MEETME:
- /* XXX How is this different from CONFRN? */
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Meetme(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_PICKUP:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Pickup(%d/%d)\n", instance, callreference);
- break;
- case SOFTKEY_GPICKUP:
- if (skinnydebug)
- ast_verbose("Received Softkey Event: Group Pickup(%d/%d)\n", instance, callreference);
- break;
- default:
- if (skinnydebug)
- ast_verbose("Received unknown Softkey Event: %d(%d/%d)\n", event, instance, callreference);
- break;
- }
- return 1;
-}
-
-static int handle_unregister_message(struct skinny_req *req, struct skinnysession *s)
-{
- return skinny_unregister(req, s);
-}
-
-static int handle_soft_key_template_req_message(struct skinny_req *req, struct skinnysession *s)
-{
- if (!(req = req_alloc(sizeof(struct soft_key_template_res_message), SOFT_KEY_TEMPLATE_RES_MESSAGE)))
- return -1;
-
- req->data.softkeytemplate.softKeyOffset = htolel(0);
- req->data.softkeytemplate.softKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition));
- req->data.softkeytemplate.totalSoftKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition));
- memcpy(req->data.softkeytemplate.softKeyTemplateDefinition,
- soft_key_template_default,
- sizeof(soft_key_template_default));
- transmit_response(s,req);
- return 1;
-}
-
-static int handle_headset_status_message(struct skinny_req *req, struct skinnysession *s)
-{
- /* XXX umm...okay? Why do I care? */
- return 1;
-}
-
-static int handle_register_available_lines_message(struct skinny_req *req, struct skinnysession *s)
-{
- /* XXX I have no clue what this is for, but my phone was sending it, so... */
- return 1;
-}
-
-static int handle_message(struct skinny_req *req, struct skinnysession *s)
-{
- int res = 0;
- struct skinny_device *d = s->device;
- struct skinny_subchannel *sub;
- int lineInstance;
- int callReference;
-
- if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) {
- ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e);
- free(req);
- return 0;
- }
-
- switch(letohl(req->e)) {
- case KEEP_ALIVE_MESSAGE:
- res = handle_keep_alive_message(req, s);
- break;
- case REGISTER_MESSAGE:
- if (skinnydebug)
- ast_verbose("Device %s is attempting to register\n", req->data.reg.name);
-
- res = handle_register_message(req, s);
- break;
- case IP_PORT_MESSAGE:
- res = handle_ip_port_message(req, s);
- break;
- case KEYPAD_BUTTON_MESSAGE:
- if (skinnydebug)
- ast_verbose("Collected digit: [%d]\n", letohl(req->data.keypad.button));
-
- lineInstance = letohl(req->data.keypad.lineInstance);
- callReference = letohl(req->data.keypad.callReference);
-
- sub = find_subchannel_by_instance_reference(d, lineInstance, callReference);
-
- if (sub && (sub->owner && sub->owner->_state < AST_STATE_UP)) {
- char dgt;
- int digit = letohl(req->data.keypad.button);
- size_t len;
-
- if (digit == 14) {
- dgt = '*';
- } else if (digit == 15) {
- dgt = '#';
- } else if (digit >= 0 && digit <= 9) {
- dgt = '0' + digit;
- } else {
- /* digit=10-13 (A,B,C,D ?), or
- * digit is bad value
- *
- * probably should not end up here, but set
- * value for backward compatibility, and log
- * a warning.
- */
- dgt = '0' + digit;
- ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
- }
-
- len = strlen(d->exten);
- if (len < sizeof(d->exten) - 1) {
- d->exten[len] = dgt;
- d->exten[len+1] = '\0';
- } else {
- ast_log(LOG_WARNING, "Dropping digit with value %d because digit queue is full\n", dgt);
- }
- } else
- res = handle_keypad_button_message(req, s);
- break;
- case ENBLOC_CALL_MESSAGE:
- res = handle_enbloc_call_message(req, s);
- break;
- case STIMULUS_MESSAGE:
- res = handle_stimulus_message(req, s);
- break;
- case OFFHOOK_MESSAGE:
- res = handle_offhook_message(req, s);
- break;
- case ONHOOK_MESSAGE:
- res = handle_onhook_message(req, s);
- break;
- case CAPABILITIES_RES_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received CapabilitiesRes\n");
-
- res = handle_capabilities_res_message(req, s);
- break;
- case SPEED_DIAL_STAT_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received SpeedDialStatRequest\n");
-
- res = handle_speed_dial_stat_req_message(req, s);
- break;
- case LINE_STATE_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received LineStatRequest\n");
- res = handle_line_state_req_message(req, s);
- break;
- case TIME_DATE_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received Time/Date Request\n");
-
- res = handle_time_date_req_message(req, s);
- break;
- case BUTTON_TEMPLATE_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Buttontemplate requested\n");
-
- res = handle_button_template_req_message(req, s);
- break;
- case VERSION_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Version Request\n");
-
- res = handle_version_req_message(req, s);
- break;
- case SERVER_REQUEST_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received Server Request\n");
-
- res = handle_server_request_message(req, s);
- break;
- case ALARM_MESSAGE:
- res = handle_alarm_message(req, s);
- break;
- case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received Open Receive Channel Ack\n");
-
- res = handle_open_receive_channel_ack_message(req, s);
- break;
- case SOFT_KEY_SET_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received SoftKeySetReq\n");
-
- res = handle_soft_key_set_req_message(req, s);
- break;
- case SOFT_KEY_EVENT_MESSAGE:
- res = handle_soft_key_event_message(req, s);
- break;
- case UNREGISTER_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received Unregister Request\n");
-
- res = handle_unregister_message(req, s);
- break;
- case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
- if (skinnydebug)
- ast_verbose("Received SoftKey Template Request\n");
-
- res = handle_soft_key_template_req_message(req, s);
- break;
- case HEADSET_STATUS_MESSAGE:
- res = handle_headset_status_message(req, s);
- break;
- case REGISTER_AVAILABLE_LINES_MESSAGE:
- res = handle_register_available_lines_message(req, s);
- break;
- default:
- if (skinnydebug)
- ast_verbose("RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e));
- break;
- }
- if (res >= 0 && req)
- free(req);
- return res;
-}
-
-static void destroy_session(struct skinnysession *s)
-{
- struct skinnysession *cur, *prev = NULL;
- ast_mutex_lock(&sessionlock);
- cur = sessions;
- while(cur) {
- if (cur == s) {
- break;
- }
- prev = cur;
- cur = cur->next;
- }
- if (cur) {
- if (prev) {
- prev->next = cur->next;
- } else {
- sessions = cur->next;
- }
- if (s->fd > -1) {
- close(s->fd);
- }
- ast_mutex_destroy(&s->lock);
- free(s);
- } else {
- ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s);
- }
- ast_mutex_unlock(&sessionlock);
-}
-
-static int get_input(struct skinnysession *s)
-{
- int res;
- int dlen = 0;
- struct pollfd fds[1];
-
- fds[0].fd = s->fd;
- fds[0].events = POLLIN;
- fds[0].revents = 0;
- res = poll(fds, 1, (keep_alive * 1100)); /* If nothing has happen, client is dead */
- /* we add 10% to the keep_alive to deal */
- /* with network delays, etc */
- if (res < 0) {
- if (errno != EINTR) {
- ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
- return res;
- }
- } else if (res == 0) {
- if (skinnydebug)
- ast_verbose("Skinny Client was lost, unregistering\n");
- skinny_unregister(NULL, s);
- return -1;
- }
-
- if (fds[0].revents) {
- ast_mutex_lock(&s->lock);
- memset(s->inbuf,0,sizeof(s->inbuf));
- res = read(s->fd, s->inbuf, 4);
- if (res < 0) {
- ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
-
- if (skinnydebug)
- ast_verbose("Skinny Client was lost, unregistering\n");
-
- skinny_unregister(NULL,s);
- ast_mutex_unlock(&s->lock);
- return res;
- } else if (res != 4) {
- ast_log(LOG_WARNING, "Skinny Client sent less data than expected. Expected 4 but got %d.\n", res);
- ast_mutex_unlock(&s->lock);
-
- if (res == 0) {
- if (skinnydebug)
- ast_verbose("Skinny Client was lost, unregistering\n");
- skinny_unregister(NULL, s);
- }
-
- return -1;
- }
-
- dlen = letohl(*(int *)s->inbuf);
- if (dlen < 4) {
- ast_log(LOG_WARNING, "Skinny Client sent invalid data.\n");
- ast_mutex_unlock(&s->lock);
- return -1;
- }
- if (dlen+8 > sizeof(s->inbuf)) {
- dlen = sizeof(s->inbuf) - 8;
- }
- *(int *)s->inbuf = htolel(dlen);
-
- res = read(s->fd, s->inbuf+4, dlen+4);
- ast_mutex_unlock(&s->lock);
- if (res < 0) {
- ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
- return res;
- } else if (res != (dlen+4)) {
- ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n");
- return -1;
- }
- return res;
- }
- return 0;
-}
-
-static struct skinny_req *skinny_req_parse(struct skinnysession *s)
-{
- struct skinny_req *req;
-
- if (!(req = ast_calloc(1, SKINNY_MAX_PACKET)))
- return NULL;
-
- ast_mutex_lock(&s->lock);
- memcpy(req, s->inbuf, skinny_header_size);
- memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*(int*)(s->inbuf))-4);
-
- ast_mutex_unlock(&s->lock);
-
- if (letohl(req->e) < 0) {
- ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd);
- free(req);
- return NULL;
- }
-
- return req;
-}
-
-static void *skinny_session(void *data)
-{
- int res;
- struct skinny_req *req;
- struct skinnysession *s = data;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
-
- for (;;) {
- res = get_input(s);
- if (res < 0) {
- break;
- }
-
- if (res > 0)
- {
- if (!(req = skinny_req_parse(s))) {
- destroy_session(s);
- return NULL;
- }
-
- res = handle_message(req, s);
- if (res < 0) {
- destroy_session(s);
- return NULL;
- }
- }
- }
- ast_log(LOG_NOTICE, "Skinny Session returned: %s\n", strerror(errno));
-
- if (s)
- destroy_session(s);
-
- return 0;
-}
-
-static void *accept_thread(void *ignore)
-{
- int as;
- struct sockaddr_in sin;
- socklen_t sinlen;
- struct skinnysession *s;
- struct protoent *p;
- int arg = 1;
- pthread_attr_t attr;
- pthread_t tcp_thread;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- for (;;) {
- sinlen = sizeof(sin);
- as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen);
- if (as < 0) {
- ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
- continue;
- }
- p = getprotobyname("tcp");
- if(p) {
- if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
- ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
- }
- }
- if (!(s = ast_calloc(1, sizeof(struct skinnysession))))
- continue;
-
- memcpy(&s->sin, &sin, sizeof(sin));
- ast_mutex_init(&s->lock);
- s->fd = as;
- ast_mutex_lock(&sessionlock);
- s->next = sessions;
- sessions = s;
- ast_mutex_unlock(&sessionlock);
-
- if (ast_pthread_create(&tcp_thread, &attr, skinny_session, s)) {
- destroy_session(s);
- }
- }
- if (skinnydebug)
- ast_verbose("killing accept thread\n");
- close(as);
- pthread_attr_destroy(&attr);
- return 0;
-}
-
-static void *do_monitor(void *data)
-{
- int res;
-
- /* This thread monitors all the interfaces which are not yet in use
- (and thus do not have a separate thread) indefinitely */
- /* From here on out, we die whenever asked */
- for(;;) {
- pthread_testcancel();
- /* Wait for sched or io */
- res = ast_sched_wait(sched);
- if ((res < 0) || (res > 1000)) {
- res = 1000;
- }
- res = ast_io_wait(io, res);
- ast_mutex_lock(&monlock);
- if (res >= 0) {
- ast_sched_runq(sched);
- }
- ast_mutex_unlock(&monlock);
- }
- /* Never reached */
- return NULL;
-
-}
-
-static int restart_monitor(void)
-{
- /* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == AST_PTHREADT_STOP)
- return 0;
-
- ast_mutex_lock(&monlock);
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread != AST_PTHREADT_NULL) {
- /* Wake up the thread */
- pthread_kill(monitor_thread, SIGURG);
- } else {
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- return -1;
- }
- }
- ast_mutex_unlock(&monlock);
- return 0;
-}
-
-static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause)
-{
- int oldformat;
-
- struct skinny_line *l;
- struct ast_channel *tmpc = NULL;
- char tmp[256];
- char *dest = data;
-
- oldformat = format;
-
- if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
- return NULL;
- }
-
- ast_copy_string(tmp, dest, sizeof(tmp));
- if (ast_strlen_zero(tmp)) {
- ast_log(LOG_NOTICE, "Skinny channels require a device\n");
- return NULL;
- }
- l = find_line_by_name(tmp);
- if (!l) {
- ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
- return NULL;
- }
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "skinny_request(%s)\n", tmp);
- }
- tmpc = skinny_new(l, AST_STATE_DOWN);
- if (!tmpc) {
- ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
- }
- restart_monitor();
- return tmpc;
-}
-
-static int reload_config(void)
-{
- int on = 1;
- struct ast_config *cfg;
- struct ast_variable *v;
- char *cat;
- struct skinny_device *d;
- int oldport = ntohs(bindaddr.sin_port);
-
- if (gethostname(ourhost, sizeof(ourhost))) {
- ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled\n");
- return 0;
- }
- cfg = ast_config_load(config);
-
- /* We *must* have a config file otherwise stop immediately */
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled\n", config);
- return -1;
- }
- memset(&bindaddr, 0, sizeof(bindaddr));
- memset(&default_prefs, 0, sizeof(default_prefs));
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- /* load the general section */
- v = ast_variable_browse(cfg, "general");
- while (v) {
- /* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
- v = v->next;
- continue;
- }
-
- /* Create the interface list */
- if (!strcasecmp(v->name, "bindaddr")) {
- if (!(hp = ast_gethostbyname(v->value, &ahp))) {
- ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
- } else {
- memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
- }
- } else if (!strcasecmp(v->name, "keepalive")) {
- keep_alive = atoi(v->value);
- } else if (!strcasecmp(v->name, "dateformat")) {
- memcpy(date_format, v->value, sizeof(date_format));
- } else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1);
- } else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0);
- } else if (!strcasecmp(v->name, "bindport") || !strcasecmp(v->name, "port")) {
- if (sscanf(v->value, "%d", &ourport) == 1) {
- bindaddr.sin_port = htons(ourport);
- } else {
- ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config);
- }
- if (!strcasecmp(v->name, "port")) { /*! \todo Remove 'port' option after 1.4 */
- ast_log(LOG_WARNING, "Option 'port' at line %d of %s has been deprecated. Please use 'bindport' instead.\n", v->lineno, config);
- }
- }
- v = v->next;
- }
-
- if (ntohl(bindaddr.sin_addr.s_addr)) {
- __ourip = bindaddr.sin_addr;
- } else {
- hp = ast_gethostbyname(ourhost, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n");
- ast_config_destroy(cfg);
- return 0;
- }
- memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
- }
- if (!ntohs(bindaddr.sin_port)) {
- bindaddr.sin_port = ntohs(DEFAULT_SKINNY_PORT);
- }
- bindaddr.sin_family = AF_INET;
-
- /* load the device sections */
- cat = ast_category_browse(cfg, NULL);
- while(cat) {
- if (!strcasecmp(cat, "general")) {
- /* Nothing to do */
-#if 0
- } else if (!strncasecmp(cat, "paging-", 7)) {
- p = build_paging_device(cat, ast_variable_browse(cfg, cat));
- if (p) {
- }
-#endif
- } else {
- d = build_device(cat, ast_variable_browse(cfg, cat));
- if (d) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Added device '%s'\n", d->name);
- ast_mutex_lock(&devicelock);
- d->next = devices;
- devices = d;
- ast_mutex_unlock(&devicelock);
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
- ast_mutex_lock(&netlock);
- if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) {
- close(skinnysock);
- skinnysock = -1;
- }
- if (skinnysock < 0) {
- skinnysock = socket(AF_INET, SOCK_STREAM, 0);
- if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
- ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s\n", errno, strerror(errno));
- ast_config_destroy(cfg);
- return 0;
- }
- if (skinnysock < 0) {
- ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno));
- } else {
- if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
- ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
- strerror(errno));
- close(skinnysock);
- skinnysock = -1;
- ast_config_destroy(cfg);
- return 0;
- }
- if (listen(skinnysock,DEFAULT_SKINNY_BACKLOG)) {
- ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
- strerror(errno));
- close(skinnysock);
- skinnysock = -1;
- ast_config_destroy(cfg);
- return 0;
- }
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Skinny listening on %s:%d\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
- ast_pthread_create_background(&accept_t,NULL, accept_thread, NULL);
- }
- }
- ast_mutex_unlock(&netlock);
- ast_config_destroy(cfg);
- return 1;
-}
-
-static void delete_devices(void)
-{
- struct skinny_device *d, *dlast;
- struct skinny_line *l, *llast;
- struct skinny_speeddial *sd, *sdlast;
- struct skinny_addon *a, *alast;
-
- ast_mutex_lock(&devicelock);
-
- /* Delete all devices */
- for (d=devices;d;) {
- /* Delete all lines for this device */
- for (l=d->lines;l;) {
- llast = l;
- l = l->next;
- ast_mutex_destroy(&llast->lock);
- free(llast);
- }
- /* Delete all speeddials for this device */
- for (sd=d->speeddials;sd;) {
- sdlast = sd;
- sd = sd->next;
- ast_mutex_destroy(&sdlast->lock);
- free(sdlast);
- }
- /* Delete all addons for this device */
- for (a=d->addons;a;) {
- alast = a;
- a = a->next;
- ast_mutex_destroy(&alast->lock);
- free(alast);
- }
- dlast = d;
- d = d->next;
- free(dlast);
- }
- devices=NULL;
- ast_mutex_unlock(&devicelock);
-}
-
-#if 0
-/*
- * XXX This never worked properly anyways.
- * Let's get rid of it, until we can fix it.
- */
-static int reload(void)
-{
- delete_devices();
- reload_config();
- restart_monitor();
- return 0;
-}
-#endif
-
-static int load_module(void)
-{
- int res = 0;
-
- for (; res < (sizeof(soft_key_template_default) / sizeof(soft_key_template_default[0])); res++) {
- soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
- }
- /* load and parse config */
- res = reload_config();
- if (res == -1) {
- return AST_MODULE_LOAD_DECLINE;
- }
-
- /* Make sure we can register our skinny channel type */
- if (ast_channel_register(&skinny_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n");
- return -1;
- }
-
- ast_rtp_proto_register(&skinny_rtp);
- ast_cli_register_multiple(cli_skinny, sizeof(cli_skinny) / sizeof(struct ast_cli_entry));
- sched = sched_context_create();
- if (!sched) {
- ast_log(LOG_WARNING, "Unable to create schedule context\n");
- }
- io = io_context_create();
- if (!io) {
- ast_log(LOG_WARNING, "Unable to create I/O context\n");
- }
- /* And start the monitor for the first time */
- restart_monitor();
-
- return res;
-}
-
-static int unload_module(void)
-{
- struct skinnysession *s, *slast;
- struct skinny_device *d;
- struct skinny_line *l;
- struct skinny_subchannel *sub;
-
- ast_mutex_lock(&sessionlock);
- /* Destroy all the interfaces and free their memory */
- s = sessions;
- while(s) {
- slast = s;
- s = s->next;
- for (d = slast->device; d; d = d->next) {
- for (l = d->lines; l; l = l->next) {
- ast_mutex_lock(&l->lock);
- for (sub = l->sub; sub; sub = sub->next) {
- ast_mutex_lock(&sub->lock);
- if (sub->owner) {
- sub->alreadygone = 1;
- ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD);
- }
- ast_mutex_unlock(&sub->lock);
- }
- ast_mutex_unlock(&l->lock);
- }
- }
- if (slast->fd > -1)
- close(slast->fd);
- ast_mutex_destroy(&slast->lock);
- free(slast);
- }
- sessions = NULL;
- ast_mutex_unlock(&sessionlock);
-
- delete_devices();
-
- ast_mutex_lock(&monlock);
- if ((monitor_thread != AST_PTHREADT_NULL) && (monitor_thread != AST_PTHREADT_STOP)) {
- pthread_cancel(monitor_thread);
- pthread_kill(monitor_thread, SIGURG);
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
-
- ast_mutex_lock(&netlock);
- if (accept_t && (accept_t != AST_PTHREADT_STOP)) {
- pthread_cancel(accept_t);
- pthread_kill(accept_t, SIGURG);
- pthread_join(accept_t, NULL);
- }
- accept_t = AST_PTHREADT_STOP;
- ast_mutex_unlock(&netlock);
-
- ast_rtp_proto_unregister(&skinny_rtp);
- ast_channel_unregister(&skinny_tech);
- ast_cli_unregister_multiple(cli_skinny, sizeof(cli_skinny) / sizeof(struct ast_cli_entry));
-
- close(skinnysock);
- if (sched)
- sched_context_destroy(sched);
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Skinny Client Control Protocol (Skinny)",
- .load = load_module,
- .unload = unload_module,
- );
diff --git a/1.4/channels/chan_vpb.cc b/1.4/channels/chan_vpb.cc
deleted file mode 100644
index 359a4ddf0..000000000
--- a/1.4/channels/chan_vpb.cc
+++ /dev/null
@@ -1,2905 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2003, Paul Bagyenda
- * Paul Bagyenda <bagyenda@dsmagic.com>
- * Copyright (C) 2004 - 2005, Ben Kramer
- * Ben Kramer <ben@voicetronix.com.au>
- *
- * Daniel Bichara <daniel@bichara.com.br> - Brazilian CallerID detection (c)2004
- *
- * Welber Silveira - welberms@magiclink.com.br - (c)2004
- * Copying CLID string to propper structure after detection
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief VoiceTronix Interface driver
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
- <depend>vpbapi</depend>
- ***/
-
-#include <vpbapi.h>
-
-extern "C" {
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#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/callerid.h"
-#include "asterisk/dsp.h"
-#include "asterisk/features.h"
-#include "asterisk/musiconhold.h"
-}
-
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <ctype.h>
-
-#include <assert.h>
-
-#ifdef pthread_create
-#undef pthread_create
-#endif
-
-#define DEFAULT_GAIN 0
-#define DEFAULT_ECHO_CANCEL 1
-
-#define VPB_SAMPLES 160
-#define VPB_MAX_BUF VPB_SAMPLES*4 + AST_FRIENDLY_OFFSET
-
-#define VPB_NULL_EVENT 200
-
-#define VPB_WAIT_TIMEOUT 4000
-
-#define MAX_VPB_GAIN 12.0
-#define MIN_VPB_GAIN -12.0
-
-#define DTMF_CALLERID
-#define DTMF_CID_START 'D'
-#define DTMF_CID_STOP 'C'
-
-/**/
-#if defined(__cplusplus) || defined(c_plusplus)
- extern "C" {
-#endif
-/**/
-
-static const char desc[] = "VoiceTronix V6PCI/V12PCI/V4PCI API Support";
-static const char tdesc[] = "Standard VoiceTronix API Driver";
-static const char config[] = "vpb.conf";
-
-/* Backwards compatibility from trunk */
-#define ast_verb(level, ...) do { \
- if (option_verbose >= level) { \
- if (level >= 4) \
- ast_verbose(VERBOSE_PREFIX_4 __VA_ARGS__); \
- else if (level == 3) \
- ast_verbose(VERBOSE_PREFIX_3 __VA_ARGS__); \
- else if (level == 2) \
- ast_verbose(VERBOSE_PREFIX_2 __VA_ARGS__); \
- else if (level == 1) \
- ast_verbose(VERBOSE_PREFIX_1 __VA_ARGS__); \
- else \
- ast_verbose(__VA_ARGS__); \
- } \
-} while (0)
-
-#define ast_debug(level, ...) do { \
- if (option_debug >= (level)) \
- ast_log(LOG_DEBUG, __VA_ARGS__); \
-} while (0)
-
-/* Default context for dialtone mode */
-static char context[AST_MAX_EXTENSION] = "default";
-
-/* Default language */
-static char language[MAX_LANGUAGE] = "";
-
-static int gruntdetect_timeout = 3600000; /* Grunt detect timeout is 1hr. */
-
-static const int prefformat = AST_FORMAT_SLINEAR;
-
-/* Protect the interface list (of vpb_pvt's) */
-AST_MUTEX_DEFINE_STATIC(iflock);
-
-/* Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
-
-/* This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread;
-
-static int mthreadactive = -1; /* Flag for monitoring monitorthread.*/
-
-
-static int restart_monitor(void);
-
-/* The private structures of the VPB channels are
- linked for selecting outgoing channels */
-
-#define MODE_DIALTONE 1
-#define MODE_IMMEDIATE 2
-#define MODE_FXO 3
-
-/* Pick a country or add your own! */
-/* These are the tones that are played to the user */
-#define TONES_AU
-/* #define TONES_USA */
-
-#ifdef TONES_AU
-static VPB_TONE Dialtone = {440, 440, 440, -10, -10, -10, 5000, 0 };
-static VPB_TONE Busytone = {470, 0, 0, -10, -100, -100, 5000, 0 };
-static VPB_TONE Ringbacktone = {400, 50, 440, -10, -10, -10, 1400, 800 };
-#endif
-#ifdef TONES_USA
-static VPB_TONE Dialtone = {350, 440, 0, -16, -16, -100, 10000, 0};
-static VPB_TONE Busytone = {480, 620, 0, -10, -10, -100, 500, 500};
-static VPB_TONE Ringbacktone = {440, 480, 0, -20, -20, -100, 2000, 4000};
-#endif
-
-/* grunt tone defn's */
-#if 0
-static VPB_DETECT toned_grunt = { 3, VPB_GRUNT, 1, 2000, 3000, 0, 0, -40, 0, 0, 0, 40, { { VPB_DELAY, 1000, 0, 0 }, { VPB_RISING, 0, 40, 0 }, { 0, 100, 0, 0 } } };
-#endif
-static VPB_DETECT toned_ungrunt = { 2, VPB_GRUNT, 1, 2000, 1, 0, 0, -40, 0, 0, 30, 40, { { 0, 0, 0, 0 } } };
-
-/* Use loop polarity detection for CID */
-static int UsePolarityCID=0;
-
-/* Use loop drop detection */
-static int UseLoopDrop=1;
-
-/* To use or not to use Native bridging */
-static int UseNativeBridge=1;
-
-/* Use Asterisk Indication or VPB */
-static int use_ast_ind=0;
-
-/* Use Asterisk DTMF detection or VPB */
-static int use_ast_dtmfdet=0;
-
-static int relaxdtmf=0;
-
-/* Use Asterisk DTMF play back or VPB */
-static int use_ast_dtmf=0;
-
-/* Break for DTMF on native bridge ? */
-static int break_for_dtmf=1;
-
-/* Set EC suppression threshold */
-static short ec_supp_threshold=-1;
-
-/* Inter Digit Delay for collecting DTMF's */
-static int dtmf_idd = 3000;
-
-#define TIMER_PERIOD_RINGBACK 2000
-#define TIMER_PERIOD_BUSY 700
-#define TIMER_PERIOD_RING 4000
-static int timer_period_ring = TIMER_PERIOD_RING;
-
-#define VPB_EVENTS_ALL (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \
- |VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
- |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH)
-#define VPB_EVENTS_NODROP (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \
- |VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
- |VPB_MRING_OFF|VPB_MSTATION_FLASH)
-#define VPB_EVENTS_NODTMF (VPB_MRING|VPB_MDIGIT|VPB_MTONEDETECT|VPB_MTIMEREXP \
- |VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
- |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH)
-#define VPB_EVENTS_STAT (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \
- |VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
- |VPB_MRING_OFF|VPB_MSTATION_FLASH)
-
-
-/* Dialing parameters for Australia */
-/* #define DIAL_WITH_CALL_PROGRESS */
-VPB_TONE_MAP DialToneMap[] = { { VPB_BUSY, VPB_CALL_DISCONNECT, 0 },
- { VPB_DIAL, VPB_CALL_DIALTONE, 0 },
- { VPB_RINGBACK, VPB_CALL_RINGBACK, 0 },
- { VPB_BUSY, VPB_CALL_BUSY, 0 },
- { VPB_GRUNT, VPB_CALL_GRUNT, 0 },
- { 0, 0, 1 } };
-#define VPB_DIALTONE_WAIT 2000 /* Wait up to 2s for a dialtone */
-#define VPB_RINGWAIT 4000 /* Wait up to 4s for ring tone after dialing */
-#define VPB_CONNECTED_WAIT 4000 /* If no ring tone detected for 4s then consider call connected */
-#define TIMER_PERIOD_NOANSWER 120000 /* Let it ring for 120s before deciding theres noone there */
-
-#define MAX_BRIDGES_V4PCI 2
-#define MAX_BRIDGES_V12PCI 128
-
-/* port states */
-#define VPB_STATE_ONHOOK 0
-#define VPB_STATE_OFFHOOK 1
-#define VPB_STATE_DIALLING 2
-#define VPB_STATE_JOINED 3
-#define VPB_STATE_GETDTMF 4
-#define VPB_STATE_PLAYDIAL 5
-#define VPB_STATE_PLAYBUSY 6
-#define VPB_STATE_PLAYRING 7
-
-#define VPB_GOT_RXHWG 1
-#define VPB_GOT_TXHWG 2
-#define VPB_GOT_RXSWG 4
-#define VPB_GOT_TXSWG 8
-
-typedef struct {
- int inuse;
- struct ast_channel *c0, *c1, **rc;
- struct ast_frame **fo;
- int flags;
- ast_mutex_t lock;
- ast_cond_t cond;
- int endbridge;
-} vpb_bridge_t;
-
-static vpb_bridge_t * bridges;
-static int max_bridges = MAX_BRIDGES_V4PCI;
-
-AST_MUTEX_DEFINE_STATIC(bridge_lock);
-
-typedef enum {
- vpb_model_unknown = 0,
- vpb_model_v4pci,
- vpb_model_v12pci
-} vpb_model_t;
-
-static struct vpb_pvt {
-
- ast_mutex_t owner_lock; /* Protect blocks that expect ownership to remain the same */
- struct ast_channel *owner; /* Channel who owns us, possibly NULL */
-
- int golock; /* Got owner lock ? */
-
- int mode; /* fxo/imediate/dialtone*/
- int handle; /* Handle for vpb interface */
-
- int state; /* used to keep port state (internal to driver) */
-
- int group; /* Which group this port belongs to */
- ast_group_t callgroup; /* Call group */
- ast_group_t pickupgroup; /* Pickup group */
-
-
- char dev[256]; /* Device name, eg vpb/1-1 */
- vpb_model_t vpb_model; /* card model */
-
- struct ast_frame f, fr; /* Asterisk frame interface */
- char buf[VPB_MAX_BUF]; /* Static buffer for reading frames */
-
- int dialtone; /* NOT USED */
- float txgain, rxgain; /* Hardware gain control */
- float txswgain, rxswgain; /* Software gain control */
-
- int wantdtmf; /* Waiting for DTMF. */
- char context[AST_MAX_EXTENSION]; /* The context for this channel */
-
- char ext[AST_MAX_EXTENSION]; /* DTMF buffer for the ext[ens] */
- char language[MAX_LANGUAGE]; /* language being used */
- char callerid[AST_MAX_EXTENSION]; /* CallerId used for directly connected phone */
- int callerid_type; /* Caller ID type: 0=>none 1=>vpb 2=>AstV23 3=>AstBell */
- char cid_num[AST_MAX_EXTENSION];
- char cid_name[AST_MAX_EXTENSION];
-
- int dtmf_caller_pos; /* DTMF CallerID detection (Brazil)*/
-
- int lastoutput; /* Holds the last Audio format output'ed */
- int lastinput; /* Holds the last Audio format input'ed */
- int last_ignore_dtmf;
-
- void *busy_timer; /* Void pointer for busy vpb_timer */
- int busy_timer_id; /* unique timer ID for busy timer */
-
- void *ringback_timer; /* Void pointer for ringback vpb_timer */
- int ringback_timer_id; /* unique timer ID for ringback timer */
-
- void *ring_timer; /* Void pointer for ring vpb_timer */
- int ring_timer_id; /* unique timer ID for ring timer */
-
- void *dtmfidd_timer; /* Void pointer for DTMF IDD vpb_timer */
- int dtmfidd_timer_id; /* unique timer ID for DTMF IDD timer */
-
- struct ast_dsp *vad; /* AST Voice Activation Detection dsp */
-
- struct timeval lastgrunt; /* time stamp of last grunt event */
-
- ast_mutex_t lock; /* This one just protects bridge ptr below */
- vpb_bridge_t *bridge;
-
- int stopreads; /* Stop reading...*/
- int read_state; /* Read state */
- int chuck_count; /* a count of packets weve chucked away!*/
- pthread_t readthread; /* For monitoring read channel. One per owned channel. */
-
- ast_mutex_t record_lock; /* This one prevents reentering a record_buf block */
- ast_mutex_t play_lock; /* This one prevents reentering a play_buf block */
- int play_buf_time; /* How long the last play_buf took */
- struct timeval lastplay; /* Last play time */
-
- ast_mutex_t play_dtmf_lock;
- char play_dtmf[16];
-
- int faxhandled; /* has a fax tone been handled ? */
-
- struct vpb_pvt *next; /* Next channel in list */
-
-} *iflist = NULL;
-
-static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context);
-static void *do_chanreads(void *pvt);
-static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause);
-static int vpb_digit_begin(struct ast_channel *ast, char digit);
-static int vpb_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int vpb_call(struct ast_channel *ast, char *dest, int timeout);
-static int vpb_hangup(struct ast_channel *ast);
-static int vpb_answer(struct ast_channel *ast);
-static struct ast_frame *vpb_read(struct ast_channel *ast);
-static int vpb_write(struct ast_channel *ast, struct ast_frame *frame);
-static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-static int vpb_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
-static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-
-static struct ast_channel_tech vpb_tech = {
- type: "vpb",
- description: tdesc,
- capabilities: AST_FORMAT_SLINEAR,
- properties: 0,
- requester: vpb_request,
- devicestate: NULL,
- send_digit_begin: vpb_digit_begin,
- send_digit_end: vpb_digit_end,
- call: vpb_call,
- hangup: vpb_hangup,
- answer: vpb_answer,
- read: vpb_read,
- write: vpb_write,
- send_text: NULL,
- send_image: NULL,
- send_html: NULL,
- exception: NULL,
- bridge: ast_vpb_bridge,
- indicate: vpb_indicate,
- fixup: vpb_fixup,
- setoption: NULL,
- queryoption: NULL,
- transfer: NULL,
- write_video: NULL,
- bridged_channel: NULL
-};
-
-static struct ast_channel_tech vpb_tech_indicate = {
- type: "vpb",
- description: tdesc,
- capabilities: AST_FORMAT_SLINEAR,
- properties: 0,
- requester: vpb_request,
- devicestate: NULL,
- send_digit_begin: vpb_digit_begin,
- send_digit_end: vpb_digit_end,
- call: vpb_call,
- hangup: vpb_hangup,
- answer: vpb_answer,
- read: vpb_read,
- write: vpb_write,
- send_text: NULL,
- send_image: NULL,
- send_html: NULL,
- exception: NULL,
- bridge: ast_vpb_bridge,
- indicate: NULL,
- fixup: vpb_fixup,
- setoption: NULL,
- queryoption: NULL,
- transfer: NULL,
- write_video: NULL,
- bridged_channel: NULL
-};
-
-/* Can't get ast_vpb_bridge() working on v4pci without either a horrible
-* high pitched feedback noise or bad hiss noise depending on gain settings
-* Get asterisk to do the bridging
-*/
-#define BAD_V4PCI_BRIDGE
-
-/* This one enables a half duplex bridge which may be required to prevent high pitched
- * feedback when getting asterisk to do the bridging and when using certain gain settings.
- */
-/* #define HALF_DUPLEX_BRIDGE */
-
-/* This is the Native bridge code, which Asterisk will try before using its own bridging code */
-static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
-{
- struct vpb_pvt *p0 = (struct vpb_pvt *)c0->tech_pvt;
- struct vpb_pvt *p1 = (struct vpb_pvt *)c1->tech_pvt;
- int i;
- int res;
- struct ast_channel *cs[3];
- struct ast_channel *who;
- struct ast_frame *f;
-
- cs[0] = c0;
- cs[1] = c1;
-
- #ifdef BAD_V4PCI_BRIDGE
- if (p0->vpb_model==vpb_model_v4pci)
- return AST_BRIDGE_FAILED_NOWARN;
- #endif
- if ( UseNativeBridge != 1){
- return AST_BRIDGE_FAILED_NOWARN;
- }
-
-/*
- ast_mutex_lock(&p0->lock);
- ast_mutex_lock(&p1->lock);
-*/
-
- /* Bridge channels, check if we can. I believe we always can, so find a slot.*/
-
- ast_mutex_lock(&bridge_lock);
- for (i = 0; i < max_bridges; i++)
- if (!bridges[i].inuse)
- break;
- if (i < max_bridges) {
- bridges[i].inuse = 1;
- bridges[i].endbridge = 0;
- bridges[i].flags = flags;
- bridges[i].rc = rc;
- bridges[i].fo = fo;
- bridges[i].c0 = c0;
- bridges[i].c1 = c1;
- }
- ast_mutex_unlock(&bridge_lock);
-
- if (i == max_bridges) {
- ast_log(LOG_WARNING, "%s: vpb_bridge: Failed to bridge %s and %s!\n", p0->dev, c0->name, c1->name);
- ast_mutex_unlock(&p0->lock);
- ast_mutex_unlock(&p1->lock);
- return AST_BRIDGE_FAILED_NOWARN;
- } else {
- /* Set bridge pointers. You don't want to take these locks while holding bridge lock.*/
- ast_mutex_lock(&p0->lock);
- p0->bridge = &bridges[i];
- ast_mutex_unlock(&p0->lock);
-
- ast_mutex_lock(&p1->lock);
- p1->bridge = &bridges[i];
- ast_mutex_unlock(&p1->lock);
-
- ast_verb(2, "%s: vpb_bridge: Bridging call entered with [%s, %s]\n", p0->dev, c0->name, c1->name);
- }
-
- ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name);
-
- #ifdef HALF_DUPLEX_BRIDGE
-
- ast_debug(2, "%s: vpb_bridge: Starting half-duplex bridge [%s, %s]\n", p0->dev, c0->name, c1->name);
-
- int dir = 0;
-
- memset(p0->buf, 0, sizeof(p0->buf));
- memset(p1->buf, 0, sizeof(p1->buf));
-
- vpb_record_buf_start(p0->handle, VPB_ALAW);
- vpb_record_buf_start(p1->handle, VPB_ALAW);
-
- vpb_play_buf_start(p0->handle, VPB_ALAW);
- vpb_play_buf_start(p1->handle, VPB_ALAW);
-
- while (!bridges[i].endbridge) {
- struct vpb_pvt *from, *to;
- if (++dir % 2) {
- from = p0;
- to = p1;
- } else {
- from = p1;
- to = p0;
- }
- vpb_record_buf_sync(from->handle, from->buf, VPB_SAMPLES);
- vpb_play_buf_sync(to->handle, from->buf, VPB_SAMPLES);
- }
-
- vpb_record_buf_finish(p0->handle);
- vpb_record_buf_finish(p1->handle);
-
- vpb_play_buf_finish(p0->handle);
- vpb_play_buf_finish(p1->handle);
-
- ast_debug(2, "%s: vpb_bridge: Finished half-duplex bridge [%s, %s]\n", p0->dev, c0->name, c1->name);
-
- res = VPB_OK;
-
- #else
-
- res = vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_ON);
- if (res == VPB_OK) {
- /* pthread_cond_wait(&bridges[i].cond, &bridges[i].lock);*/ /* Wait for condition signal. */
- while (!bridges[i].endbridge) {
- /* Are we really ment to be doing nothing ?!?! */
- who = ast_waitfor_n(cs, 2, &timeoutms);
- if (!who) {
- if (!timeoutms) {
- res = AST_BRIDGE_RETRY;
- break;
- }
- ast_debug(1, "%s: vpb_bridge: Empty frame read...\n", p0->dev);
- /* check for hangup / whentohangup */
- if (ast_check_hangup(c0) || ast_check_hangup(c1))
- break;
- continue;
- }
- f = ast_read(who);
- if (!f || ((f->frametype == AST_FRAME_DTMF) &&
- (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
- ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
- *fo = f;
- *rc = who;
- ast_debug(1, "%s: vpb_bridge: Got a [%s]\n", p0->dev, f ? "digit" : "hangup");
-#if 0
- if ((c0->tech_pvt == pvt0) && (!ast_check_hangup(c0))) {
- if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
- }
- if ((c1->tech_pvt == pvt1) && (!ast_check_hangup(c1))) {
- if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
- }
- /* That's all we needed */
- return 0;
-#endif
- /* Check if we need to break */
- if (break_for_dtmf) {
- break;
- } else if ((f->frametype == AST_FRAME_DTMF) && ((f->subclass == '#') || (f->subclass == '*'))) {
- break;
- }
- } else {
- if ((f->frametype == AST_FRAME_DTMF) ||
- (f->frametype == AST_FRAME_VOICE) ||
- (f->frametype == AST_FRAME_VIDEO))
- {
- /* Forward voice or DTMF frames if they happen upon us */
- /* Actually I dont think we want to forward on any frames!
- if (who == c0) {
- ast_write(c1, f);
- } else if (who == c1) {
- ast_write(c0, f);
- }
- */
- }
- ast_frfree(f);
- }
- /* Swap priority not that it's a big deal at this point */
- cs[2] = cs[0];
- cs[0] = cs[1];
- cs[1] = cs[2];
- };
- vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_OFF);
- }
-
- #endif
-
- ast_mutex_lock(&bridge_lock);
- bridges[i].inuse = 0;
- ast_mutex_unlock(&bridge_lock);
-
- p0->bridge = NULL;
- p1->bridge = NULL;
-
-
- ast_verb(2, "Bridging call done with [%s, %s] => %d\n", c0->name, c1->name, res);
-
-/*
- ast_mutex_unlock(&p0->lock);
- ast_mutex_unlock(&p1->lock);
-*/
- return (res == VPB_OK) ? AST_BRIDGE_COMPLETE : AST_BRIDGE_FAILED;
-}
-
-/* Caller ID can be located in different positions between the rings depending on your Telco
- * Australian (Telstra) callerid starts 700ms after 1st ring and finishes 1.5s after first ring
- * Use ANALYSE_CID to record rings and determine location of callerid
- */
-/* #define ANALYSE_CID */
-#define RING_SKIP 300
-#define CID_MSECS 2000
-
-static void get_callerid(struct vpb_pvt *p)
-{
- short buf[CID_MSECS*8]; /* 8kHz sampling rate */
- struct timeval cid_record_time;
- int rc;
- struct ast_channel *owner = p->owner;
-/*
- char callerid[AST_MAX_EXTENSION] = "";
-*/
-#ifdef ANALYSE_CID
- void * ws;
- char * file="cidsams.wav";
-#endif
-
-
- if (ast_mutex_trylock(&p->record_lock) == 0) {
-
- cid_record_time = ast_tvnow();
- ast_verb(4, "CID record - start\n");
-
- /* Skip any trailing ringtone */
- if (UsePolarityCID != 1){
- vpb_sleep(RING_SKIP);
- }
-
- ast_verb(4, "CID record - skipped %dms trailing ring\n",
- ast_tvdiff_ms(ast_tvnow(), cid_record_time));
- cid_record_time = ast_tvnow();
-
- /* Record bit between the rings which contains the callerid */
- vpb_record_buf_start(p->handle, VPB_LINEAR);
- rc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf));
- vpb_record_buf_finish(p->handle);
-#ifdef ANALYSE_CID
- vpb_wave_open_write(&ws, file, VPB_LINEAR);
- vpb_wave_write(ws, (char *)buf, sizeof(buf));
- vpb_wave_close_write(ws);
-#endif
-
- ast_verb(4, "CID record - recorded %dms between rings\n",
- ast_tvdiff_ms(ast_tvnow(), cid_record_time));
-
- ast_mutex_unlock(&p->record_lock);
-
- if (rc != VPB_OK) {
- ast_log(LOG_ERROR, "Failed to record caller id sample on %s\n", p->dev);
- return;
- }
-
- VPB_CID *cli_struct = new VPB_CID;
- cli_struct->ra_cldn[0] = 0;
- cli_struct->ra_cn[0] = 0;
- /* This decodes FSK 1200baud type callerid */
- if ((rc = vpb_cid_decode2(cli_struct, buf, CID_MSECS * 8)) == VPB_OK ) {
- /*
- if (owner->cid.cid_num)
- ast_free(owner->cid.cid_num);
- owner->cid.cid_num=NULL;
- if (owner->cid.cid_name)
- ast_free(owner->cid.cid_name);
- owner->cid.cid_name=NULL;
- */
-
- if (cli_struct->ra_cldn[0] == '\0') {
- /*
- owner->cid.cid_num = ast_strdup(cli_struct->cldn);
- owner->cid.cid_name = ast_strdup(cli_struct->cn);
- */
- if (owner) {
- ast_set_callerid(owner, cli_struct->cldn, cli_struct->cn, cli_struct->cldn);
- } else {
- strcpy(p->cid_num, cli_struct->cldn);
- strcpy(p->cid_name, cli_struct->cn);
- }
- ast_verb(4, "CID record - got [%s] [%s]\n", owner->cid.cid_num, owner->cid.cid_name);
- snprintf(p->callerid, sizeof(p->callerid), "%s %s", cli_struct->cldn, cli_struct->cn);
- } else {
- ast_log(LOG_ERROR, "CID record - No caller id avalable on %s \n", p->dev);
- }
-
- } else {
- ast_log(LOG_ERROR, "CID record - Failed to decode caller id on %s - %d\n", p->dev, rc);
- ast_copy_string(p->callerid, "unknown", sizeof(p->callerid));
- }
- delete cli_struct;
-
- } else
- ast_log(LOG_ERROR, "CID record - Failed to set record mode for caller id on %s\n", p->dev);
-}
-
-static void get_callerid_ast(struct vpb_pvt *p)
-{
- struct callerid_state *cs;
- char buf[1024];
- char *name = NULL, *number = NULL;
- int flags;
- int rc = 0, vrc;
- int sam_count = 0;
- struct ast_channel *owner = p->owner;
- int which_cid;
-/*
- float old_gain;
-*/
-#ifdef ANALYSE_CID
- void * ws;
- char * file = "cidsams.wav";
-#endif
-
- if (p->callerid_type == 1) {
- ast_verb(4, "Collected caller ID already\n");
- return;
- }
- else if (p->callerid_type == 2 ) {
- which_cid = CID_SIG_V23;
- ast_verb(4, "Collecting Caller ID v23...\n");
- }
- else if (p->callerid_type == 3) {
- which_cid = CID_SIG_BELL;
- ast_verb(4, "Collecting Caller ID bell...\n");
- } else {
- ast_verb(4, "Caller ID disabled\n");
- return;
- }
-/* vpb_sleep(RING_SKIP); */
-/* vpb_record_get_gain(p->handle, &old_gain); */
- cs = callerid_new(which_cid);
- if (cs) {
-#ifdef ANALYSE_CID
- vpb_wave_open_write(&ws, file, VPB_MULAW);
- vpb_record_set_gain(p->handle, 3.0);
- vpb_record_set_hw_gain(p->handle, 12.0);
-#endif
- vpb_record_buf_start(p->handle, VPB_MULAW);
- while ((rc == 0) && (sam_count < 8000 * 3)) {
- vrc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf));
- if (vrc != VPB_OK)
- ast_log(LOG_ERROR, "%s: Caller ID couldn't read audio buffer!\n", p->dev);
- rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), AST_FORMAT_ULAW);
-#ifdef ANALYSE_CID
- vpb_wave_write(ws, (char *)buf, sizeof(buf));
-#endif
- sam_count += sizeof(buf);
- ast_verb(4, "Collecting Caller ID samples [%d][%d]...\n", sam_count, rc);
- }
- vpb_record_buf_finish(p->handle);
-#ifdef ANALYSE_CID
- vpb_wave_close_write(ws);
-#endif
- if (rc == 1) {
- callerid_get(cs, &name, &number, &flags);
- ast_debug(1, "%s: Caller ID name [%s] number [%s] flags [%d]\n", p->dev, name, number, flags);
- } else {
- ast_log(LOG_ERROR, "%s: Failed to decode Caller ID \n", p->dev);
- }
-/* vpb_record_set_gain(p->handle, old_gain); */
-/* vpb_record_set_hw_gain(p->handle,6.0); */
- } else {
- ast_log(LOG_ERROR, "%s: Failed to create Caller ID struct\n", p->dev);
- }
- if (owner->cid.cid_num) {
- ast_free(owner->cid.cid_num);
- owner->cid.cid_num = NULL;
- }
- if (owner->cid.cid_name) {
- ast_free(owner->cid.cid_name);
- owner->cid.cid_name = NULL;
- }
- if (number)
- ast_shrink_phone_number(number);
- ast_set_callerid(owner,
- number, name,
- owner->cid.cid_ani ? NULL : number);
- if (!ast_strlen_zero(name)){
- snprintf(p->callerid, sizeof(p->callerid), "%s %s", number, name);
- } else {
- ast_copy_string(p->callerid, number, sizeof(p->callerid));
- }
- if (cs)
- callerid_free(cs);
-}
-
-/* Terminate any tones we are presently playing */
-static void stoptone(int handle)
-{
- int ret;
- VPB_EVENT je;
- while (vpb_playtone_state(handle) != VPB_OK) {
- vpb_tone_terminate(handle);
- ret = vpb_get_event_ch_async(handle, &je);
- if ((ret == VPB_OK) && (je.type != VPB_DIALEND)) {
- ast_verb(4, "Stop tone collected a wrong event!![%d]\n", je.type);
-/* vpb_put_event(&je); */
- }
- vpb_sleep(10);
- }
-}
-
-/* Safe vpb_playtone_async */
-static int playtone( int handle, VPB_TONE *tone)
-{
- int ret = VPB_OK;
- stoptone(handle);
- ast_verb(4, "[%02d]: Playing tone\n", handle);
- ret = vpb_playtone_async(handle, tone);
- return ret;
-}
-
-static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
-{
- struct ast_frame f = {AST_FRAME_CONTROL}; /* default is control, Clear rest. */
- int endbridge = 0;
- int res = 0;
-
- ast_verb(4, "%s: handle_owned: got event: [%d=>%d]\n", p->dev, e->type, e->data);
-
- f.src = "vpb";
- switch (e->type) {
- case VPB_RING:
- if (p->mode == MODE_FXO) {
- f.subclass = AST_CONTROL_RING;
- vpb_timer_stop(p->ring_timer);
- vpb_timer_start(p->ring_timer);
- } else
- f.frametype = AST_FRAME_NULL; /* ignore ring on station port. */
- break;
-
- case VPB_RING_OFF:
- f.frametype = AST_FRAME_NULL;
- break;
-
- case VPB_TIMEREXP:
- if (e->data == p->busy_timer_id) {
- playtone(p->handle, &Busytone);
- p->state = VPB_STATE_PLAYBUSY;
- vpb_timer_stop(p->busy_timer);
- vpb_timer_start(p->busy_timer);
- f.frametype = AST_FRAME_NULL;
- } else if (e->data == p->ringback_timer_id) {
- playtone(p->handle, &Ringbacktone);
- vpb_timer_stop(p->ringback_timer);
- vpb_timer_start(p->ringback_timer);
- f.frametype = AST_FRAME_NULL;
- } else if (e->data == p->ring_timer_id) {
- /* We didnt get another ring in time! */
- if (p->owner->_state != AST_STATE_UP) {
- /* Assume caller has hung up */
- vpb_timer_stop(p->ring_timer);
- f.subclass = AST_CONTROL_HANGUP;
- } else {
- vpb_timer_stop(p->ring_timer);
- f.frametype = AST_FRAME_NULL;
- }
-
- } else {
- f.frametype = AST_FRAME_NULL; /* Ignore. */
- }
- break;
-
- case VPB_DTMF_DOWN:
- case VPB_DTMF:
- if (use_ast_dtmfdet) {
- f.frametype = AST_FRAME_NULL;
- } else if (p->owner->_state == AST_STATE_UP) {
- f.frametype = AST_FRAME_DTMF;
- f.subclass = e->data;
- } else
- f.frametype = AST_FRAME_NULL;
- break;
-
- case VPB_TONEDETECT:
- if (e->data == VPB_BUSY || e->data == VPB_BUSY_308 || e->data == VPB_BUSY_AUST ) {
- ast_debug(4, "%s: handle_owned: got event: BUSY\n", p->dev);
- if (p->owner->_state == AST_STATE_UP) {
- f.subclass = AST_CONTROL_HANGUP;
- } else {
- f.subclass = AST_CONTROL_BUSY;
- }
- } else if (e->data == VPB_FAX) {
- if (!p->faxhandled) {
- if (strcmp(p->owner->exten, "fax")) {
- const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
-
- if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) {
- ast_verb(3, "Redirecting %s to fax extension\n", p->owner->name);
- /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
- pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
- if (ast_async_goto(p->owner, target_context, "fax", 1)) {
- ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context);
- }
- } else {
- ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
- }
- } else {
- ast_debug(1, "Already in a fax extension, not redirecting\n");
- }
- } else {
- ast_debug(1, "Fax already handled\n");
- }
- } else if (e->data == VPB_GRUNT) {
- if (ast_tvdiff_ms(ast_tvnow(), p->lastgrunt) > gruntdetect_timeout) {
- /* Nothing heard on line for a very long time
- * Timeout connection */
- ast_verb(3, "grunt timeout\n");
- ast_log(LOG_NOTICE, "%s: Line hangup due of lack of conversation\n", p->dev);
- f.subclass = AST_CONTROL_HANGUP;
- } else {
- p->lastgrunt = ast_tvnow();
- f.frametype = AST_FRAME_NULL;
- }
- } else {
- f.frametype = AST_FRAME_NULL;
- }
- break;
-
- case VPB_CALLEND:
- #ifdef DIAL_WITH_CALL_PROGRESS
- if (e->data == VPB_CALL_CONNECTED) {
- f.subclass = AST_CONTROL_ANSWER;
- } else if (e->data == VPB_CALL_NO_DIAL_TONE || e->data == VPB_CALL_NO_RING_BACK) {
- f.subclass = AST_CONTROL_CONGESTION;
- } else if (e->data == VPB_CALL_NO_ANSWER || e->data == VPB_CALL_BUSY) {
- f.subclass = AST_CONTROL_BUSY;
- } else if (e->data == VPB_CALL_DISCONNECTED) {
- f.subclass = AST_CONTROL_HANGUP;
- }
- #else
- ast_log(LOG_NOTICE, "%s: Got call progress callback but blind dialing \n", p->dev);
- f.frametype = AST_FRAME_NULL;
- #endif
- break;
-
- case VPB_STATION_OFFHOOK:
- f.subclass = AST_CONTROL_ANSWER;
- break;
-
- case VPB_DROP:
- if ((p->mode == MODE_FXO) && (UseLoopDrop)) { /* ignore loop drop on stations */
- if (p->owner->_state == AST_STATE_UP) {
- f.subclass = AST_CONTROL_HANGUP;
- } else {
- f.frametype = AST_FRAME_NULL;
- }
- }
- break;
- case VPB_LOOP_ONHOOK:
- if (p->owner->_state == AST_STATE_UP) {
- f.subclass = AST_CONTROL_HANGUP;
- } else {
- f.frametype = AST_FRAME_NULL;
- }
- break;
- case VPB_STATION_ONHOOK:
- f.subclass = AST_CONTROL_HANGUP;
- break;
-
- case VPB_STATION_FLASH:
- f.subclass = AST_CONTROL_FLASH;
- break;
-
- /* Called when dialing has finished and ringing starts
- * No indication that call has really been answered when using blind dialing
- */
- case VPB_DIALEND:
- if (p->state < 5) {
- f.subclass = AST_CONTROL_ANSWER;
- ast_verb(2, "%s: Dialend\n", p->dev);
- } else {
- f.frametype = AST_FRAME_NULL;
- }
- break;
-
-/* case VPB_PLAY_UNDERFLOW:
- f.frametype = AST_FRAME_NULL;
- vpb_reset_play_fifo_alarm(p->handle);
- break;
-
- case VPB_RECORD_OVERFLOW:
- f.frametype = AST_FRAME_NULL;
- vpb_reset_record_fifo_alarm(p->handle);
- break;
-*/
- default:
- f.frametype = AST_FRAME_NULL;
- break;
- }
-
-/*
- ast_verb(4, "%s: LOCKING in handle_owned [%d]\n", p->dev,res);
- res = ast_mutex_lock(&p->lock);
- ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- if (p->bridge) { /* Check what happened, see if we need to report it. */
- switch (f.frametype) {
- case AST_FRAME_DTMF:
- if ( !(p->bridge->c0 == p->owner &&
- (p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_0) ) &&
- !(p->bridge->c1 == p->owner &&
- (p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_1) )) {
- /* Kill bridge, this is interesting. */
- endbridge = 1;
- }
- break;
-
- case AST_FRAME_CONTROL:
- if (!(p->bridge->flags & AST_BRIDGE_IGNORE_SIGS)) {
- #if 0
- if (f.subclass == AST_CONTROL_BUSY ||
- f.subclass == AST_CONTROL_CONGESTION ||
- f.subclass == AST_CONTROL_HANGUP ||
- f.subclass == AST_CONTROL_FLASH)
- #endif
- endbridge = 1;
- }
- break;
-
- default:
- break;
- }
-
- if (endbridge) {
- if (p->bridge->fo) {
- *p->bridge->fo = ast_frisolate(&f);
- }
-
- if (p->bridge->rc) {
- *p->bridge->rc = p->owner;
- }
-
- ast_mutex_lock(&p->bridge->lock);
- p->bridge->endbridge = 1;
- ast_cond_signal(&p->bridge->cond);
- ast_mutex_unlock(&p->bridge->lock);
- }
- }
-
- if (endbridge) {
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in handle_owned [%d]\n", p->dev,res);
-*/
- return 0;
- }
-
- ast_verb(4, "%s: handle_owned: Prepared frame type[%d]subclass[%d], bridge=%p owner=[%s]\n",
- p->dev, f.frametype, f.subclass, (void *)p->bridge, p->owner->name);
-
- /* Trylock used here to avoid deadlock that can occur if we
- * happen to be in here handling an event when hangup is called
- * Problem is that hangup holds p->owner->lock
- */
- if ((f.frametype >= 0) && (f.frametype != AST_FRAME_NULL) && (p->owner)) {
- if (ast_channel_trylock(p->owner) == 0) {
- ast_queue_frame(p->owner, &f);
- ast_channel_unlock(p->owner);
- ast_verb(4, "%s: handled_owned: Queued Frame to [%s]\n", p->dev, p->owner->name);
- } else {
- ast_verbose("%s: handled_owned: Missed event %d/%d \n",
- p->dev, f.frametype, f.subclass);
- }
- }
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in handle_owned [%d]\n", p->dev,res);
-*/
-
- return 0;
-}
-
-static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
-{
- char s[2] = {0};
- struct ast_channel *owner = p->owner;
- char cid_num[256];
- char cid_name[256];
-/*
- struct ast_channel *c;
-*/
-
- char str[VPB_MAX_STR];
-
- vpb_translate_event(e, str);
- ast_verb(4, "%s: handle_notowned: mode=%d, event[%d][%s]=[%d]\n", p->dev, p->mode, e->type,str, e->data);
-
- switch (e->type) {
- case VPB_LOOP_ONHOOK:
- case VPB_LOOP_POLARITY:
- if (UsePolarityCID == 1) {
- ast_verb(4, "Polarity reversal\n");
- if (p->callerid_type == 1) {
- ast_verb(4, "Using VPB Caller ID\n");
- get_callerid(p); /* UK CID before 1st ring*/
- }
-/* get_callerid_ast(p); */ /* Caller ID using the ast functions */
- }
- break;
- case VPB_RING:
- if (p->mode == MODE_FXO) /* FXO port ring, start * */ {
- vpb_new(p, AST_STATE_RING, p->context);
- if (UsePolarityCID != 1) {
- if (p->callerid_type == 1) {
- ast_verb(4, "Using VPB Caller ID\n");
- get_callerid(p); /* Australian CID only between 1st and 2nd ring */
- }
- get_callerid_ast(p); /* Caller ID using the ast functions */
- } else {
- ast_log(LOG_ERROR, "Setting caller ID: %s %s\n", p->cid_num, p->cid_name);
- ast_set_callerid(p->owner, p->cid_num, p->cid_name, p->cid_num);
- p->cid_num[0] = 0;
- p->cid_name[0] = 0;
- }
-
- vpb_timer_stop(p->ring_timer);
- vpb_timer_start(p->ring_timer);
- }
- break;
-
- case VPB_RING_OFF:
- break;
-
- case VPB_STATION_OFFHOOK:
- if (p->mode == MODE_IMMEDIATE) {
- vpb_new(p,AST_STATE_RING, p->context);
- } else {
- ast_verb(4, "%s: handle_notowned: playing dialtone\n", p->dev);
- playtone(p->handle, &Dialtone);
- p->state = VPB_STATE_PLAYDIAL;
- p->wantdtmf = 1;
- p->ext[0] = 0; /* Just to be sure & paranoid.*/
- }
- break;
-
- case VPB_DIALEND:
- if (p->mode == MODE_DIALTONE) {
- if (p->state == VPB_STATE_PLAYDIAL) {
- playtone(p->handle, &Dialtone);
- p->wantdtmf = 1;
- p->ext[0] = 0; /* Just to be sure & paranoid. */
- }
-#if 0
- /* These are not needed as they have timers to restart them */
- else if (p->state == VPB_STATE_PLAYBUSY) {
- playtone(p->handle, &Busytone);
- p->wantdtmf = 1;
- p->ext[0] = 0;
- } else if (p->state == VPB_STATE_PLAYRING) {
- playtone(p->handle, &Ringbacktone);
- p->wantdtmf = 1;
- p->ext[0] = 0;
- }
-#endif
- } else {
- ast_verb(4, "%s: handle_notowned: Got a DIALEND when not really expected\n",p->dev);
- }
- break;
-
- case VPB_STATION_ONHOOK: /* clear ext */
- stoptone(p->handle);
- p->wantdtmf = 1 ;
- p->ext[0] = 0;
- p->state = VPB_STATE_ONHOOK;
- break;
- case VPB_TIMEREXP:
- if (e->data == p->dtmfidd_timer_id) {
- if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)){
- ast_verb(4, "%s: handle_notowned: DTMF IDD timer out, matching on [%s] in [%s]\n", p->dev, p->ext, p->context);
-
- vpb_new(p, AST_STATE_RING, p->context);
- }
- } else if (e->data == p->ring_timer_id) {
- /* We didnt get another ring in time! */
- if (p->owner) {
- if (p->owner->_state != AST_STATE_UP) {
- /* Assume caller has hung up */
- vpb_timer_stop(p->ring_timer);
- }
- } else {
- /* No owner any more, Assume caller has hung up */
- vpb_timer_stop(p->ring_timer);
- }
- }
- break;
-
- case VPB_DTMF:
- if (p->state == VPB_STATE_ONHOOK){
- /* DTMF's being passed while on-hook maybe Caller ID */
- if (p->mode == MODE_FXO) {
- if (e->data == DTMF_CID_START) { /* CallerID Start signal */
- p->dtmf_caller_pos = 0; /* Leaves the first digit out */
- memset(p->callerid, 0, sizeof(p->callerid));
- } else if (e->data == DTMF_CID_STOP) { /* CallerID End signal */
- p->callerid[p->dtmf_caller_pos] = '\0';
- ast_verb(3, " %s: DTMF CallerID %s\n", p->dev, p->callerid);
- if (owner) {
- /*
- if (owner->cid.cid_num)
- ast_free(owner->cid.cid_num);
- owner->cid.cid_num=NULL;
- if (owner->cid.cid_name)
- ast_free(owner->cid.cid_name);
- owner->cid.cid_name=NULL;
- owner->cid.cid_num = strdup(p->callerid);
- */
- cid_name[0] = '\0';
- cid_num[0] = '\0';
- ast_callerid_split(p->callerid, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
- ast_set_callerid(owner, cid_num, cid_name, cid_num);
-
- } else {
- ast_verb(3, " %s: DTMF CallerID: no owner to assign CID \n", p->dev);
- }
- } else if (p->dtmf_caller_pos < AST_MAX_EXTENSION) {
- if (p->dtmf_caller_pos >= 0) {
- p->callerid[p->dtmf_caller_pos] = e->data;
- }
- p->dtmf_caller_pos++;
- }
- }
- break;
- }
- if (p->wantdtmf == 1) {
- stoptone(p->handle);
- p->wantdtmf = 0;
- }
- p->state = VPB_STATE_GETDTMF;
- s[0] = e->data;
- strncat(p->ext, s, sizeof(p->ext) - strlen(p->ext) - 1);
- #if 0
- if (!strcmp(p->ext, ast_pickup_ext())) {
- /* Call pickup has been dialled! */
- if (ast_pickup_call(c)) {
- /* Call pickup wasnt possible */
- }
- } else
- #endif
- if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)) {
- if (ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) {
- ast_verb(4, "%s: handle_notowned: Multiple matches on [%s] in [%s]\n", p->dev, p->ext, p->context);
- /* Start DTMF IDD timer */
- vpb_timer_stop(p->dtmfidd_timer);
- vpb_timer_start(p->dtmfidd_timer);
- } else {
- ast_verb(4, "%s: handle_notowned: Matched on [%s] in [%s]\n", p->dev, p->ext , p->context);
- vpb_new(p, AST_STATE_UP, p->context);
- }
- } else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) {
- if (ast_exists_extension(NULL, "default", p->ext, 1, p->callerid)) {
- vpb_new(p, AST_STATE_UP, "default");
- } else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) {
- ast_verb(4, "%s: handle_notowned: can't match anything in %s or default\n", p->dev, p->context);
- playtone(p->handle, &Busytone);
- vpb_timer_stop(p->busy_timer);
- vpb_timer_start(p->busy_timer);
- p->state = VPB_STATE_PLAYBUSY;
- }
- }
- break;
-
- default:
- /* Ignore.*/
- break;
- }
-
- ast_verb(4, "%s: handle_notowned: mode=%d, [%d=>%d]\n", p->dev, p->mode, e->type, e->data);
-
- return 0;
-}
-
-static void *do_monitor(void *unused)
-{
-
- /* Monitor thread, doesn't die until explicitly killed. */
-
- ast_verb(2, "Starting vpb monitor thread[%ld]\n", pthread_self());
-
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
- for (;;) {
- VPB_EVENT e;
- VPB_EVENT je;
- char str[VPB_MAX_STR];
- struct vpb_pvt *p;
-
- /*
- ast_verb(4, "Monitor waiting for event\n");
- */
-
- int res = vpb_get_event_sync(&e, VPB_WAIT_TIMEOUT);
- if ((res == VPB_NO_EVENTS) || (res == VPB_TIME_OUT)) {
- /*
- if (res == VPB_NO_EVENTS) {
- ast_verb(4, "No events....\n");
- } else {
- ast_verb(4, "No events, timed out....\n");
- }
- */
- continue;
- }
-
- if (res != VPB_OK) {
- ast_log(LOG_ERROR,"Monitor get event error %d\n", res );
- ast_verbose("Monitor get event error %d\n", res );
- continue;
- }
-
- str[0] = 0;
-
- p = NULL;
-
- ast_mutex_lock(&monlock);
- if (e.type == VPB_NULL_EVENT) {
- ast_verb(4, "Monitor got null event\n");
- } else {
- vpb_translate_event(&e, str);
- if (*str && *(str + 1)) {
- str[strlen(str) - 1] = '\0';
- }
-
- ast_mutex_lock(&iflock);
- for (p = iflist; p && p->handle != e.handle; p = p->next);
- ast_mutex_unlock(&iflock);
-
- if (p) {
- ast_verb(4, "%s: Event [%d=>%s]\n",
- p ? p->dev : "null", e.type, str);
- }
- }
-
- ast_mutex_unlock(&monlock);
-
- if (!p) {
- if (e.type != VPB_NULL_EVENT) {
- ast_log(LOG_WARNING, "Got event [%s][%d], no matching iface!\n", str, e.type);
- ast_verb(4, "vpb/ERR: No interface for Event [%d=>%s] \n", e.type, str);
- }
- continue;
- }
-
- /* flush the event from the channel event Q */
- vpb_get_event_ch_async(e.handle, &je);
- vpb_translate_event(&je, str);
- ast_verb(5, "%s: Flushing event [%d]=>%s\n", p->dev, je.type, str);
-
- /* Check for ownership and locks */
- if ((p->owner) && (!p->golock)) {
- /* Need to get owner lock */
- /* Safely grab both p->lock and p->owner->lock so that there
- cannot be a race with something from the other side */
- /*
- ast_mutex_lock(&p->lock);
- while (ast_mutex_trylock(&p->owner->lock)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- if (!p->owner)
- break;
- }
- if (p->owner)
- p->golock = 1;
- */
- }
- /* Two scenarios: Are you owned or not. */
- if (p->owner) {
- monitor_handle_owned(p, &e);
- } else {
- monitor_handle_notowned(p, &e);
- }
- /* if ((!p->owner)&&(p->golock)) {
- ast_mutex_unlock(&p->owner->lock);
- ast_mutex_unlock(&p->lock);
- }
- */
-
- }
-
- return NULL;
-}
-
-static int restart_monitor(void)
-{
- int error = 0;
-
- /* If we're supposed to be stopped -- stay stopped */
- if (mthreadactive == -2)
- return 0;
-
- ast_verb(4, "Restarting monitor\n");
-
- ast_mutex_lock(&monlock);
- if (monitor_thread == pthread_self()) {
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- error = -1;
- ast_verb(4, "Monitor trying to kill monitor\n");
- } else {
- if (mthreadactive != -1) {
- /* Why do other drivers kill the thread? No need says I, simply awake thread with event. */
- VPB_EVENT e;
- e.handle = 0;
- e.type = VPB_EVT_NONE;
- e.data = 0;
-
- ast_verb(4, "Trying to reawake monitor\n");
-
- vpb_put_event(&e);
- } else {
- /* Start a new monitor */
- int pid = ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL);
- ast_verb(4, "Created new monitor thread %d\n", pid);
- if (pid < 0) {
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- error = -1;
- } else {
- mthreadactive = 0; /* Started the thread!*/
- }
- }
- }
- ast_mutex_unlock(&monlock);
-
- ast_verb(4, "Monitor restarted\n");
-
- return error;
-}
-
-/* Per board config that must be called after vpb_open() */
-static void mkbrd(vpb_model_t model, int echo_cancel)
-{
- if (!bridges) {
- if (model == vpb_model_v4pci) {
- max_bridges = MAX_BRIDGES_V4PCI;
- }
- bridges = (vpb_bridge_t *)ast_calloc(1, max_bridges * sizeof(vpb_bridge_t));
- if (!bridges) {
- ast_log(LOG_ERROR, "Failed to initialize bridges\n");
- } else {
- int i;
- for (i = 0; i < max_bridges; i++) {
- ast_mutex_init(&bridges[i].lock);
- ast_cond_init(&bridges[i].cond, NULL);
- }
- }
- }
- if (!echo_cancel) {
- if (model == vpb_model_v4pci) {
- vpb_echo_canc_disable();
- ast_log(LOG_NOTICE, "Voicetronix echo cancellation OFF\n");
- } else {
- /* need to do it port by port for OpenSwitch */
- }
- } else {
- if (model == vpb_model_v4pci) {
- vpb_echo_canc_enable();
- ast_log(LOG_NOTICE, "Voicetronix echo cancellation ON\n");
- if (ec_supp_threshold > -1) {
- vpb_echo_canc_set_sup_thresh(0, &ec_supp_threshold);
- ast_log(LOG_NOTICE, "Voicetronix EC Sup Thres set\n");
- }
- } else {
- /* need to do it port by port for OpenSwitch */
- }
- }
-}
-
-static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float txgain, float rxgain,
- float txswgain, float rxswgain, int bal1, int bal2, int bal3,
- char * callerid, int echo_cancel, int group, ast_group_t callgroup, ast_group_t pickupgroup )
-{
- struct vpb_pvt *tmp;
- char buf[64];
-
- tmp = (vpb_pvt *)ast_calloc(1, sizeof(*tmp));
-
- if (!tmp)
- return NULL;
-
- tmp->handle = vpb_open(board, channel);
-
- if (tmp->handle < 0) {
- ast_log(LOG_WARNING, "Unable to create channel vpb/%d-%d: %s\n",
- board, channel, strerror(errno));
- ast_free(tmp);
- return NULL;
- }
-
- snprintf(tmp->dev, sizeof(tmp->dev), "vpb/%d-%d", board, channel);
-
- tmp->mode = mode;
-
- tmp->group = group;
- tmp->callgroup = callgroup;
- tmp->pickupgroup = pickupgroup;
-
- /* Initilize dtmf caller ID position variable */
- tmp->dtmf_caller_pos = 0;
-
- ast_copy_string(tmp->language, language, sizeof(tmp->language));
- ast_copy_string(tmp->context, context, sizeof(tmp->context));
-
- tmp->callerid_type = 0;
- if (callerid) {
- if (strcasecmp(callerid, "on") == 0) {
- tmp->callerid_type = 1;
- ast_copy_string(tmp->callerid, "unknown", sizeof(tmp->callerid));
- } else if (strcasecmp(callerid, "v23") == 0) {
- tmp->callerid_type = 2;
- ast_copy_string(tmp->callerid, "unknown", sizeof(tmp->callerid));
- } else if (strcasecmp(callerid, "bell") == 0) {
- tmp->callerid_type = 3;
- ast_copy_string(tmp->callerid, "unknown", sizeof(tmp->callerid));
- } else {
- ast_copy_string(tmp->callerid, callerid, sizeof(tmp->callerid));
- }
- } else {
- ast_copy_string(tmp->callerid, "unknown", sizeof(tmp->callerid));
- }
-
- /* check if codec balances have been set in the config file */
- if (bal3 >= 0) {
- if ((bal1>=0) && !(bal1 & 32)) bal1 |= 32;
- vpb_set_codec_reg(tmp->handle, 0x42, bal3);
- }
- if (bal1 >= 0) {
- vpb_set_codec_reg(tmp->handle, 0x32, bal1);
- }
- if (bal2 >= 0) {
- vpb_set_codec_reg(tmp->handle, 0x3a, bal2);
- }
-
- if (gains & VPB_GOT_TXHWG) {
- if (txgain > MAX_VPB_GAIN) {
- tmp->txgain = MAX_VPB_GAIN;
- } else if (txgain < MIN_VPB_GAIN) {
- tmp->txgain = MIN_VPB_GAIN;
- } else {
- tmp->txgain = txgain;
- }
-
- ast_log(LOG_NOTICE, "VPB setting Tx Hw gain to [%f]\n", tmp->txgain);
- vpb_play_set_hw_gain(tmp->handle, tmp->txgain);
- }
-
- if (gains & VPB_GOT_RXHWG) {
- if (rxgain > MAX_VPB_GAIN) {
- tmp->rxgain = MAX_VPB_GAIN;
- } else if (rxgain < MIN_VPB_GAIN) {
- tmp->rxgain = MIN_VPB_GAIN;
- } else {
- tmp->rxgain = rxgain;
- }
- ast_log(LOG_NOTICE, "VPB setting Rx Hw gain to [%f]\n", tmp->rxgain);
- vpb_record_set_hw_gain(tmp->handle, tmp->rxgain);
- }
-
- if (gains & VPB_GOT_TXSWG) {
- tmp->txswgain = txswgain;
- ast_log(LOG_NOTICE, "VPB setting Tx Sw gain to [%f]\n", tmp->txswgain);
- vpb_play_set_gain(tmp->handle, tmp->txswgain);
- }
-
- if (gains & VPB_GOT_RXSWG) {
- tmp->rxswgain = rxswgain;
- ast_log(LOG_NOTICE, "VPB setting Rx Sw gain to [%f]\n", tmp->rxswgain);
- vpb_record_set_gain(tmp->handle, tmp->rxswgain);
- }
-
- tmp->vpb_model = vpb_model_unknown;
- if (vpb_get_model(tmp->handle, buf) == VPB_OK) {
- if (strcmp(buf, "V12PCI") == 0) {
- tmp->vpb_model = vpb_model_v12pci;
- } else if (strcmp(buf, "VPB4") == 0) {
- tmp->vpb_model = vpb_model_v4pci;
- }
- }
-
- ast_mutex_init(&tmp->owner_lock);
- ast_mutex_init(&tmp->lock);
- ast_mutex_init(&tmp->record_lock);
- ast_mutex_init(&tmp->play_lock);
- ast_mutex_init(&tmp->play_dtmf_lock);
-
- /* set default read state */
- tmp->read_state = 0;
-
- tmp->golock = 0;
-
- tmp->busy_timer_id = vpb_timer_get_unique_timer_id();
- vpb_timer_open(&tmp->busy_timer, tmp->handle, tmp->busy_timer_id, TIMER_PERIOD_BUSY);
-
- tmp->ringback_timer_id = vpb_timer_get_unique_timer_id();
- vpb_timer_open(&tmp->ringback_timer, tmp->handle, tmp->ringback_timer_id, TIMER_PERIOD_RINGBACK);
-
- tmp->ring_timer_id = vpb_timer_get_unique_timer_id();
- vpb_timer_open(&tmp->ring_timer, tmp->handle, tmp->ring_timer_id, timer_period_ring);
-
- tmp->dtmfidd_timer_id = vpb_timer_get_unique_timer_id();
- vpb_timer_open(&tmp->dtmfidd_timer, tmp->handle, tmp->dtmfidd_timer_id, dtmf_idd);
-
- if (mode == MODE_FXO){
- if (use_ast_dtmfdet)
- vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF);
- else
- vpb_set_event_mask(tmp->handle, VPB_EVENTS_ALL);
- } else {
-/*
- if (use_ast_dtmfdet)
- vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF);
- else
-*/
- vpb_set_event_mask(tmp->handle, VPB_EVENTS_STAT);
- }
-
- if ((tmp->vpb_model == vpb_model_v12pci) && (echo_cancel)) {
- vpb_hostecho_on(tmp->handle);
- }
- if (use_ast_dtmfdet) {
- tmp->vad = ast_dsp_new();
- ast_dsp_set_features(tmp->vad, DSP_FEATURE_DTMF_DETECT);
- ast_dsp_digitmode(tmp->vad, DSP_DIGITMODE_DTMF);
- if (relaxdtmf)
- ast_dsp_digitmode(tmp->vad, DSP_DIGITMODE_DTMF|DSP_DIGITMODE_RELAXDTMF);
- } else {
- tmp->vad = NULL;
- }
-
- /* define grunt tone */
- vpb_settonedet(tmp->handle,&toned_ungrunt);
-
- ast_log(LOG_NOTICE,"Voicetronix %s channel %s initialized (rxsg=%f/txsg=%f/rxhg=%f/txhg=%f)(0x%x/0x%x/0x%x)\n",
- (tmp->vpb_model == vpb_model_v4pci) ? "V4PCI" :
- (tmp->vpb_model == vpb_model_v12pci) ? "V12PCI" : "[Unknown model]",
- tmp->dev, tmp->rxswgain, tmp->txswgain, tmp->rxgain, tmp->txgain, bal1, bal2, bal3);
-
- return tmp;
-}
-
-static int vpb_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- int res = 0;
- int tmp = 0;
-
- if (use_ast_ind == 1) {
- ast_verb(4, "%s: vpb_indicate called when using Ast Indications !?!\n", p->dev);
- return 0;
- }
-
- ast_verb(4, "%s: vpb_indicate [%d] state[%d]\n", p->dev, condition,ast->_state);
-/*
- if (ast->_state != AST_STATE_UP) {
- ast_verb(4, "%s: vpb_indicate Not in AST_STATE_UP\n", p->dev, condition,ast->_state);
- return res;
- }
-*/
-
-/*
- ast_verb(4, "%s: LOCKING in indicate \n", p->dev);
- ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count, p->lock.__m_owner);
-*/
- ast_mutex_lock(&p->lock);
- switch (condition) {
- case AST_CONTROL_BUSY:
- case AST_CONTROL_CONGESTION:
- if (ast->_state == AST_STATE_UP) {
- playtone(p->handle, &Busytone);
- p->state = VPB_STATE_PLAYBUSY;
- vpb_timer_stop(p->busy_timer);
- vpb_timer_start(p->busy_timer);
- }
- break;
- case AST_CONTROL_RINGING:
- if (ast->_state == AST_STATE_UP) {
- playtone(p->handle, &Ringbacktone);
- p->state = VPB_STATE_PLAYRING;
- ast_verb(4, "%s: vpb indicate: setting ringback timer [%d]\n", p->dev,p->ringback_timer_id);
-
- vpb_timer_stop(p->ringback_timer);
- vpb_timer_start(p->ringback_timer);
- }
- break;
- case AST_CONTROL_ANSWER:
- case -1: /* -1 means stop playing? */
- vpb_timer_stop(p->ringback_timer);
- vpb_timer_stop(p->busy_timer);
- stoptone(p->handle);
- break;
- case AST_CONTROL_HANGUP:
- if (ast->_state == AST_STATE_UP) {
- playtone(p->handle, &Busytone);
- p->state = VPB_STATE_PLAYBUSY;
- vpb_timer_stop(p->busy_timer);
- vpb_timer_start(p->busy_timer);
- }
- break;
- case AST_CONTROL_HOLD:
- ast_moh_start(ast, (const char *) data, NULL);
- break;
- case AST_CONTROL_UNHOLD:
- ast_moh_stop(ast);
- break;
- default:
- res = 0;
- break;
- }
- tmp = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in indicate [%d]\n", p->dev,tmp);
-*/
- return res;
-}
-
-static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)newchan->tech_pvt;
- int res = 0;
-
-/*
- ast_verb(4, "%s: LOCKING in fixup \n", p->dev);
- ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- ast_mutex_lock(&p->lock);
- ast_debug(1, "New owner for channel %s is %s\n", p->dev, newchan->name);
-
- if (p->owner == oldchan) {
- p->owner = newchan;
- }
-
- if (newchan->_state == AST_STATE_RINGING){
- if (use_ast_ind == 1) {
- ast_verb(4, "%s: vpb_fixup Calling ast_indicate\n", p->dev);
- ast_indicate(newchan, AST_CONTROL_RINGING);
- } else {
- ast_verb(4, "%s: vpb_fixup Calling vpb_indicate\n", p->dev);
- vpb_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
- }
- }
-
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in fixup [%d]\n", p->dev,res);
-*/
- return 0;
-}
-
-static int vpb_digit_begin(struct ast_channel *ast, char digit)
-{
- /* XXX Modify this callback to let Asterisk control the length of DTMF */
- return 0;
-}
-static int vpb_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- char s[2];
- int res = 0;
-
- if (use_ast_dtmf) {
- ast_verb(4, "%s: vpb_digit: asked to play digit[%c] but we are using asterisk dtmf play back?!\n", p->dev, digit);
- return 0;
- }
-
-/*
- ast_verb(4, "%s: LOCKING in digit \n", p->dev);
- ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- ast_mutex_lock(&p->lock);
-
-
- s[0] = digit;
- s[1] = '\0';
-
- ast_verb(4, "%s: vpb_digit: asked to play digit[%s]\n", p->dev, s);
-
- ast_mutex_lock(&p->play_dtmf_lock);
- strncat(p->play_dtmf, s, sizeof(*p->play_dtmf) - strlen(p->play_dtmf) - 1);
- ast_mutex_unlock(&p->play_dtmf_lock);
-
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in digit [%d]\n", p->dev,res);
-*/
- return 0;
-}
-
-/* Places a call out of a VPB channel */
-static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- int res = 0, i;
- char *s = strrchr(dest, '/');
- char dialstring[254] = "";
- int tmp = 0;
-
-/*
- ast_verb(4, "%s: LOCKING in call \n", p->dev);
- ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- ast_mutex_lock(&p->lock);
- ast_verb(4, "%s: starting call to [%s]\n", p->dev, dest);
-
- if (s)
- s = s + 1;
- else
- s = dest;
- ast_copy_string(dialstring, s, sizeof(dialstring));
- for (i = 0; dialstring[i] != '\0'; i++) {
- if ((dialstring[i] == 'w') || (dialstring[i] == 'W'))
- dialstring[i] = ',';
- else if ((dialstring[i] == 'f') || (dialstring[i] == 'F'))
- dialstring[i] = '&';
- }
-
- if (ast->_state != AST_STATE_DOWN && ast->_state != AST_STATE_RESERVED) {
- ast_log(LOG_WARNING, "vpb_call on %s neither down nor reserved!\n", ast->name);
- tmp = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in call [%d]\n", p->dev,tmp);
-*/
- return -1;
- }
- if (p->mode != MODE_FXO) /* Station port, ring it. */
- vpb_ring_station_async(p->handle, 2);
- else {
- VPB_CALL call;
- int j;
-
- /* Dial must timeout or it can leave channels unuseable */
- if (timeout == 0) {
- timeout = TIMER_PERIOD_NOANSWER;
- } else {
- timeout = timeout * 1000; /* convert from secs to ms. */
- }
-
- /* These timeouts are only used with call progress dialing */
- call.dialtones = 1; /* Number of dialtones to get outside line */
- call.dialtone_timeout = VPB_DIALTONE_WAIT; /* Wait this long for dialtone (ms) */
- call.ringback_timeout = VPB_RINGWAIT; /* Wait this long for ringing after dialing (ms) */
- call.inter_ringback_timeout = VPB_CONNECTED_WAIT; /* If ringing stops for this long consider it connected (ms) */
- call.answer_timeout = timeout; /* Time to wait for answer after ringing starts (ms) */
- memcpy(&call.tone_map, DialToneMap, sizeof(DialToneMap));
- vpb_set_call(p->handle, &call);
-
- ast_verb(2, "%s: Calling %s on %s \n",p->dev, dialstring, ast->name);
-
- ast_verb(2, "%s: Dial parms for %s %d/%dms/%dms/%dms/%dms\n", p->dev,
- ast->name, call.dialtones, call.dialtone_timeout,
- call.ringback_timeout, call.inter_ringback_timeout,
- call.answer_timeout);
- for (j = 0; !call.tone_map[j].terminate; j++) {
- ast_verb(2, "%s: Dial parms for %s tone %d->%d\n", p->dev,
- ast->name, call.tone_map[j].tone_id, call.tone_map[j].call_id);
- }
-
- ast_verb(4, "%s: Disabling Loop Drop detection\n", p->dev);
- vpb_disable_event(p->handle, VPB_MDROP);
- vpb_sethook_sync(p->handle, VPB_OFFHOOK);
- p->state = VPB_STATE_OFFHOOK;
-
- #ifndef DIAL_WITH_CALL_PROGRESS
- vpb_sleep(300);
- ast_verb(4, "%s: Enabling Loop Drop detection\n", p->dev);
- vpb_enable_event(p->handle, VPB_MDROP);
- res = vpb_dial_async(p->handle, dialstring);
- #else
- ast_verb(4, "%s: Enabling Loop Drop detection\n", p->dev);
- vpb_enable_event(p->handle, VPB_MDROP);
- res = vpb_call_async(p->handle, dialstring);
- #endif
-
- if (res != VPB_OK) {
- ast_debug(1, "Call on %s to %s failed: %d\n", ast->name, s, res);
- res = -1;
- } else
- res = 0;
- }
-
- ast_verb(3, "%s: VPB Calling %s [t=%d] on %s returned %d\n", p->dev , s, timeout, ast->name, res);
- if (res == 0) {
- ast_setstate(ast, AST_STATE_RINGING);
- ast_queue_control(ast, AST_CONTROL_RINGING);
- }
-
- if (!p->readthread) {
- ast_pthread_create(&p->readthread, NULL, do_chanreads, (void *)p);
- }
-
- tmp = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in call [%d]\n", p->dev,tmp);
-*/
- return res;
-}
-
-static int vpb_hangup(struct ast_channel *ast)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- VPB_EVENT je;
- char str[VPB_MAX_STR];
- int res = 0;
-
-/*
- ast_verb(4, "%s: LOCKING in hangup \n", p->dev);
- ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
- ast_verb(4, "%s: LOCKING pthread_self(%d)\n", p->dev,pthread_self());
- ast_mutex_lock(&p->lock);
-*/
- ast_verb(2, "%s: Hangup requested\n", ast->name);
-
- if (!ast->tech || !ast->tech_pvt) {
- ast_log(LOG_WARNING, "%s: channel not connected?\n", ast->name);
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in hangup [%d]\n", p->dev,res);
-*/
- /* Free up ast dsp if we have one */
- if (use_ast_dtmfdet && p->vad) {
- ast_dsp_free(p->vad);
- p->vad = NULL;
- }
- return 0;
- }
-
-
-
- /* Stop record */
- p->stopreads = 1;
- if (p->readthread) {
- pthread_join(p->readthread, NULL);
- ast_verb(4, "%s: stopped record thread \n", ast->name);
- }
-
- /* Stop play */
- if (p->lastoutput != -1) {
- ast_verb(2, "%s: Ending play mode \n", ast->name);
- vpb_play_terminate(p->handle);
- ast_mutex_lock(&p->play_lock);
- vpb_play_buf_finish(p->handle);
- ast_mutex_unlock(&p->play_lock);
- }
-
- ast_verb(4, "%s: Setting state down\n", ast->name);
- ast_setstate(ast, AST_STATE_DOWN);
-
-
-/*
- ast_verb(4, "%s: LOCKING in hangup \n", p->dev);
- ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
- ast_verb(4, "%s: LOCKING pthread_self(%d)\n", p->dev,pthread_self());
-*/
- ast_mutex_lock(&p->lock);
-
- if (p->mode != MODE_FXO) {
- /* station port. */
- vpb_ring_station_async(p->handle, 0);
- if (p->state != VPB_STATE_ONHOOK) {
- /* This is causing a "dial end" "play tone" loop
- playtone(p->handle, &Busytone);
- p->state = VPB_STATE_PLAYBUSY;
- ast_verb(5, "%s: Station offhook[%d], playing busy tone\n",
- ast->name,p->state);
- */
- } else {
- stoptone(p->handle);
- }
- #ifdef VPB_PRI
- vpb_setloop_async(p->handle, VPB_OFFHOOK);
- vpb_sleep(100);
- vpb_setloop_async(p->handle, VPB_ONHOOK);
- #endif
- } else {
- stoptone(p->handle); /* Terminates any dialing */
- vpb_sethook_sync(p->handle, VPB_ONHOOK);
- p->state=VPB_STATE_ONHOOK;
- }
- while (VPB_OK == vpb_get_event_ch_async(p->handle, &je)) {
- vpb_translate_event(&je, str);
- ast_verb(4, "%s: Flushing event [%d]=>%s\n", ast->name, je.type, str);
- }
-
- p->readthread = 0;
- p->lastoutput = -1;
- p->lastinput = -1;
- p->last_ignore_dtmf = 1;
- p->ext[0] = 0;
- p->dialtone = 0;
-
- p->owner = NULL;
- ast->tech_pvt = NULL;
-
- /* Free up ast dsp if we have one */
- if (use_ast_dtmfdet && p->vad) {
- ast_dsp_free(p->vad);
- p->vad = NULL;
- }
-
- ast_verb(2, "%s: Hangup complete\n", ast->name);
-
- restart_monitor();
-/*
- ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in hangup [%d]\n", p->dev,res);
- ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- return 0;
-}
-
-static int vpb_answer(struct ast_channel *ast)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- int res = 0;
-/*
- VPB_EVENT je;
- int ret;
- ast_verb(4, "%s: LOCKING in answer \n", p->dev);
- ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
-*/
- ast_mutex_lock(&p->lock);
-
- ast_verb(4, "%s: Answering channel\n", p->dev);
-
- if (p->mode == MODE_FXO) {
- ast_verb(4, "%s: Disabling Loop Drop detection\n", p->dev);
- vpb_disable_event(p->handle, VPB_MDROP);
- }
-
- if (ast->_state != AST_STATE_UP) {
- if (p->mode == MODE_FXO) {
- vpb_sethook_sync(p->handle, VPB_OFFHOOK);
- p->state = VPB_STATE_OFFHOOK;
-/* vpb_sleep(500);
- ret = vpb_get_event_ch_async(p->handle, &je);
- if ((ret == VPB_OK) && ((je.type != VPB_DROP)&&(je.type != VPB_RING))){
- ast_verb(4, "%s: Answer collected a wrong event!!\n", p->dev);
- vpb_put_event(&je);
- }
-*/
- }
- ast_setstate(ast, AST_STATE_UP);
-
- ast_verb(2, "%s: Answered call on %s [%s]\n", p->dev,
- ast->name, (p->mode == MODE_FXO) ? "FXO" : "FXS");
-
- ast->rings = 0;
- if (!p->readthread) {
- /* res = ast_mutex_unlock(&p->lock); */
- /* ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); */
- ast_pthread_create(&p->readthread, NULL, do_chanreads, (void *)p);
- } else {
- ast_verb(4, "%s: Record thread already running!!\n", p->dev);
- }
- } else {
- ast_verb(4, "%s: Answered state is up\n", p->dev);
- /* res = ast_mutex_unlock(&p->lock); */
- /* ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); */
- }
- vpb_sleep(500);
- if (p->mode == MODE_FXO) {
- ast_verb(4, "%s: Re-enabling Loop Drop detection\n", p->dev);
- vpb_enable_event(p->handle, VPB_MDROP);
- }
- res = ast_mutex_unlock(&p->lock);
-/*
- ast_verb(4, "%s: unLOCKING in answer [%d]\n", p->dev,res);
-*/
- return 0;
-}
-
-static struct ast_frame *vpb_read(struct ast_channel *ast)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- static struct ast_frame f = { AST_FRAME_NULL };
-
- f.src = "vpb";
- ast_log(LOG_NOTICE, "%s: vpb_read: should never be called!\n", p->dev);
- ast_verbose("%s: vpb_read: should never be called!\n", p->dev);
-
- return &f;
-}
-
-static inline AudioCompress ast2vpbformat(int ast_format)
-{
- switch (ast_format) {
- case AST_FORMAT_ALAW:
- return VPB_ALAW;
- case AST_FORMAT_SLINEAR:
- return VPB_LINEAR;
- case AST_FORMAT_ULAW:
- return VPB_MULAW;
- case AST_FORMAT_ADPCM:
- return VPB_OKIADPCM;
- default:
- return VPB_RAW;
- }
-}
-
-static inline const char * ast2vpbformatname(int ast_format)
-{
- switch(ast_format) {
- case AST_FORMAT_ALAW:
- return "AST_FORMAT_ALAW:VPB_ALAW";
- case AST_FORMAT_SLINEAR:
- return "AST_FORMAT_SLINEAR:VPB_LINEAR";
- case AST_FORMAT_ULAW:
- return "AST_FORMAT_ULAW:VPB_MULAW";
- case AST_FORMAT_ADPCM:
- return "AST_FORMAT_ADPCM:VPB_OKIADPCM";
- default:
- return "UNKN:UNKN";
- }
-}
-
-static inline int astformatbits(int ast_format)
-{
- switch (ast_format) {
- case AST_FORMAT_SLINEAR:
- return 16;
- case AST_FORMAT_ADPCM:
- return 4;
- case AST_FORMAT_ALAW:
- case AST_FORMAT_ULAW:
- default:
- return 8;
- }
-}
-
-int a_gain_vector(float g, short *v, int n)
-{
- int i;
- float tmp;
- for (i = 0; i < n; i++) {
- tmp = g * v[i];
- if (tmp > 32767.0)
- tmp = 32767.0;
- if (tmp < -32768.0)
- tmp = -32768.0;
- v[i] = (short)tmp;
- }
- return i;
-}
-
-/* Writes a frame of voice data to a VPB channel */
-static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
- int res = 0;
- AudioCompress fmt = VPB_RAW;
- struct timeval play_buf_time_start;
- int tdiff;
-
-/* ast_mutex_lock(&p->lock); */
- ast_verb(6, "%s: vpb_write: Writing to channel\n", p->dev);
-
- if (frame->frametype != AST_FRAME_VOICE) {
- ast_verb(4, "%s: vpb_write: Don't know how to handle from type %d\n", ast->name, frame->frametype);
-/* ast_mutex_unlock(&p->lock); */
- return 0;
- } else if (ast->_state != AST_STATE_UP) {
- ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%d] on not up chan(state[%d])\n",ast->name, frame->frametype, frame->subclass,ast->_state);
- p->lastoutput = -1;
-/* ast_mutex_unlock(&p->lock); */
- return 0;
- }
-/* ast_debug(1, "%s: vpb_write: Checked frame type..\n", p->dev); */
-
-
- fmt = ast2vpbformat(frame->subclass);
- if (fmt < 0) {
- ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %d format!\n", ast->name, frame->subclass);
- return -1;
- }
-
- tdiff = ast_tvdiff_ms(ast_tvnow(), p->lastplay);
- ast_debug(1, "%s: vpb_write: time since last play(%d) \n", p->dev, tdiff);
- if (tdiff < (VPB_SAMPLES / 8 - 1)) {
- ast_debug(1, "%s: vpb_write: Asked to play too often (%d) (%d)\n", p->dev, tdiff, frame->datalen);
-/* return 0; */
- }
- p->lastplay = ast_tvnow();
-/*
- ast_debug(1, "%s: vpb_write: Checked frame format..\n", p->dev);
-*/
-
- ast_mutex_lock(&p->play_lock);
-
-/*
- ast_debug(1, "%s: vpb_write: Got play lock..\n", p->dev);
-*/
-
- /* Check if we have set up the play_buf */
- if (p->lastoutput == -1) {
- vpb_play_buf_start(p->handle, fmt);
- ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(frame->subclass));
- p->lastoutput = fmt;
- ast_mutex_unlock(&p->play_lock);
- return 0;
- } else if (p->lastoutput != fmt) {
- vpb_play_buf_finish(p->handle);
- vpb_play_buf_start(p->handle, fmt);
- ast_verb(2, "%s: vpb_write: Changed play format (%d=>%d)\n", p->dev, p->lastoutput, fmt);
- ast_mutex_unlock(&p->play_lock);
- return 0;
- }
- p->lastoutput = fmt;
-
-
-
- /* Apply extra gain ! */
- if( p->txswgain > MAX_VPB_GAIN )
- a_gain_vector(p->txswgain - MAX_VPB_GAIN , (short*)frame->data, frame->datalen / sizeof(short));
-
-/* ast_debug(1, "%s: vpb_write: Applied gain..\n", p->dev); */
-/* ast_debug(1, "%s: vpb_write: play_buf_time %d\n", p->dev, p->play_buf_time); */
-
- if ((p->read_state == 1) && (p->play_buf_time < 5)){
- play_buf_time_start = ast_tvnow();
-/* res = vpb_play_buf_sync(p->handle, (char *)frame->data, tdiff * 8 * 2); */
- res = vpb_play_buf_sync(p->handle, (char *)frame->data, frame->datalen);
- if(res == VPB_OK) {
- short * data = (short*)frame->data;
- ast_verb(6, "%s: vpb_write: Wrote chan (codec=%d) %d %d\n", p->dev, fmt, data[0], data[1]);
- }
- p->play_buf_time = ast_tvdiff_ms(ast_tvnow(), play_buf_time_start);
- } else {
- p->chuck_count++;
- ast_debug(1, "%s: vpb_write: Tossed data away, tooooo much data!![%d]\n", p->dev, p->chuck_count);
- p->play_buf_time = 0;
- }
-
- ast_mutex_unlock(&p->play_lock);
-/* ast_mutex_unlock(&p->lock); */
- ast_verb(6, "%s: vpb_write: Done Writing to channel\n", p->dev);
- return 0;
-}
-
-/* Read monitor thread function. */
-static void *do_chanreads(void *pvt)
-{
- struct vpb_pvt *p = (struct vpb_pvt *)pvt;
- struct ast_frame *fr = &p->fr;
- char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET;
- int bridgerec = 0;
- int afmt, readlen, res, trycnt=0;
- AudioCompress fmt;
- int ignore_dtmf;
- const char * getdtmf_var = NULL;
-
- fr->frametype = AST_FRAME_VOICE;
- fr->src = "vpb";
- fr->mallocd = 0;
- fr->delivery.tv_sec = 0;
- fr->delivery.tv_usec = 0;
- fr->samples = VPB_SAMPLES;
- fr->offset = AST_FRIENDLY_OFFSET;
- memset(p->buf, 0, sizeof p->buf);
-
- ast_verb(3, "%s: chanreads: starting thread\n", p->dev);
- ast_mutex_lock(&p->record_lock);
-
- p->stopreads = 0;
- p->read_state = 1;
- while (!p->stopreads && p->owner) {
-
- ast_verb(5, "%s: chanreads: Starting cycle ...\n", p->dev);
- ast_verb(5, "%s: chanreads: Checking bridge \n", p->dev);
- if (p->bridge) {
- if (p->bridge->c0 == p->owner && (p->bridge->flags & AST_BRIDGE_REC_CHANNEL_0))
- bridgerec = 1;
- else if (p->bridge->c1 == p->owner && (p->bridge->flags & AST_BRIDGE_REC_CHANNEL_1))
- bridgerec = 1;
- else
- bridgerec = 0;
- } else {
- ast_verb(5, "%s: chanreads: No native bridge.\n", p->dev);
- if (p->owner->_bridge) {
- ast_verb(5, "%s: chanreads: Got Asterisk bridge with [%s].\n", p->dev, p->owner->_bridge->name);
- bridgerec = 1;
- } else {
- bridgerec = 0;
- }
- }
-
-/* if ((p->owner->_state != AST_STATE_UP) || !bridgerec) */
- if ((p->owner->_state != AST_STATE_UP)) {
- if (p->owner->_state != AST_STATE_UP) {
- ast_verb(5, "%s: chanreads: Im not up[%d]\n", p->dev, p->owner->_state);
- } else {
- ast_verb(5, "%s: chanreads: No bridgerec[%d]\n", p->dev, bridgerec);
- }
- vpb_sleep(10);
- continue;
- }
-
- /* Voicetronix DTMF detection can be triggered off ordinary speech
- * This leads to annoying beeps during the conversation
- * Avoid this problem by just setting VPB_GETDTMF when you want to listen for DTMF
- */
- /* ignore_dtmf = 1; */
- ignore_dtmf = 0; /* set this to 1 to turn this feature on */
- getdtmf_var = pbx_builtin_getvar_helper(p->owner, "VPB_GETDTMF");
- if (getdtmf_var && strcasecmp(getdtmf_var, "yes") == 0)
- ignore_dtmf = 0;
-
- if ((ignore_dtmf != p->last_ignore_dtmf) && (!use_ast_dtmfdet)){
- ast_verb(2, "%s:Now %s DTMF \n",
- p->dev, ignore_dtmf ? "ignoring" : "listening for");
- vpb_set_event_mask(p->handle, ignore_dtmf ? VPB_EVENTS_NODTMF : VPB_EVENTS_ALL );
- }
- p->last_ignore_dtmf = ignore_dtmf;
-
- /* Play DTMF digits here to avoid problem you get if playing a digit during
- * a record operation
- */
- ast_verb(6, "%s: chanreads: Checking dtmf's \n", p->dev);
- ast_mutex_lock(&p->play_dtmf_lock);
- if (p->play_dtmf[0]) {
- /* Try to ignore DTMF event we get after playing digit */
- /* This DTMF is played by asterisk and leads to an annoying trailing beep on CISCO phones */
- if (!ignore_dtmf) {
- vpb_set_event_mask(p->handle, VPB_EVENTS_NODTMF );
- }
- if (p->bridge == NULL) {
- vpb_dial_sync(p->handle, p->play_dtmf);
- ast_verb(2, "%s: chanreads: Played DTMF %s\n", p->dev, p->play_dtmf);
- } else {
- ast_verb(2, "%s: chanreads: Not playing DTMF frame on native bridge\n", p->dev);
- }
- p->play_dtmf[0] = '\0';
- ast_mutex_unlock(&p->play_dtmf_lock);
- vpb_sleep(700); /* Long enough to miss echo and DTMF event */
- if( !ignore_dtmf)
- vpb_set_event_mask(p->handle, VPB_EVENTS_ALL);
- continue;
- }
- ast_mutex_unlock(&p->play_dtmf_lock);
-
-/* afmt = (p->owner) ? p->owner->rawreadformat : AST_FORMAT_SLINEAR; */
- if (p->owner) {
- afmt = p->owner->rawreadformat;
-/* ast_debug(1,"%s: Record using owner format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
- } else {
- afmt = AST_FORMAT_SLINEAR;
-/* ast_debug(1,"%s: Record using default format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
- }
- fmt = ast2vpbformat(afmt);
- if (fmt < 0) {
- ast_log(LOG_WARNING, "%s: Record failure (unsupported format %d)\n", p->dev, afmt);
- return NULL;
- }
- readlen = VPB_SAMPLES * astformatbits(afmt) / 8;
-
- if (p->lastinput == -1) {
- vpb_record_buf_start(p->handle, fmt);
-/* vpb_reset_record_fifo_alarm(p->handle); */
- p->lastinput = fmt;
- ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(afmt));
- continue;
- } else if (p->lastinput != fmt) {
- vpb_record_buf_finish(p->handle);
- vpb_record_buf_start(p->handle, fmt);
- p->lastinput = fmt;
- ast_verb(2, "%s: Changed record format (%d=>%d)\n", p->dev, p->lastinput, fmt);
- continue;
- }
-
- /* Read only if up and not bridged, or a bridge for which we can read. */
- ast_verb(6, "%s: chanreads: getting buffer!\n", p->dev);
- if( (res = vpb_record_buf_sync(p->handle, readbuf, readlen) ) == VPB_OK ) {
- ast_verb(6, "%s: chanreads: got buffer!\n", p->dev);
- /* Apply extra gain ! */
- if( p->rxswgain > MAX_VPB_GAIN )
- a_gain_vector(p->rxswgain - MAX_VPB_GAIN, (short *)readbuf, readlen / sizeof(short));
- ast_verb(6, "%s: chanreads: applied gain\n", p->dev);
-
- fr->subclass = afmt;
- fr->data = readbuf;
- fr->datalen = readlen;
- fr->frametype = AST_FRAME_VOICE;
-
- if ((use_ast_dtmfdet)&&(p->vad)) {
- fr = ast_dsp_process(p->owner,p->vad,fr);
- if (fr && (fr->frametype == AST_FRAME_DTMF)) {
- ast_debug(1, "%s: chanreads: Detected DTMF '%c'\n", p->dev, fr->subclass);
- } else if (fr->subclass == 'f') {
- }
- }
- /* Using trylock here to prevent deadlock when channel is hungup
- * (ast_hangup() immediately gets lock)
- */
- if (p->owner && !p->stopreads) {
- ast_verb(6, "%s: chanreads: queueing buffer on read frame q (state[%d])\n", p->dev, p->owner->_state);
- do {
- res = ast_channel_trylock(p->owner);
- trycnt++;
- } while ((res !=0 ) && (trycnt < 300));
- if (res == 0) {
- ast_queue_frame(p->owner, fr);
- ast_channel_unlock(p->owner);
- } else {
- ast_verb(5, "%s: chanreads: Couldnt get lock after %d tries!\n", p->dev, trycnt);
- }
- trycnt = 0;
-
-/*
- res = ast_mutex_trylock(&p->owner->lock);
- if (res == 0) {
- ast_queue_frame(p->owner, fr);
- ast_mutex_unlock(&p->owner->lock);
- } else {
- if (res == EINVAL)
- ast_verb(5, "%s: chanreads: try owner->lock gave me EINVAL[%d]\n", p->dev, res);
- else if (res == EBUSY)
- ast_verb(5, "%s: chanreads: try owner->lock gave me EBUSY[%d]\n", p->dev, res);
- while (res != 0) {
- res = ast_mutex_trylock(&p->owner->lock);
- }
- if (res == 0) {
- ast_queue_frame(p->owner, fr);
- ast_mutex_unlock(&p->owner->lock);
- } else {
- if (res == EINVAL) {
- ast_verb(5, "%s: chanreads: try owner->lock gave me EINVAL[%d]\n", p->dev, res);
- } else if (res == EBUSY) {
- ast_verb(5, "%s: chanreads: try owner->lock gave me EBUSY[%d]\n", p->dev, res);
- }
- ast_verb(5, "%s: chanreads: Couldnt get lock on owner[%s][%d][%d] channel to send frame!\n", p->dev, p->owner->name, (int)p->owner->lock.__m_owner, (int)p->owner->lock.__m_count);
- }
- }
-*/
- short *data = (short *)readbuf;
- ast_verb(7, "%s: Read channel (codec=%d) %d %d\n", p->dev, fmt, data[0], data[1]);
- } else {
- ast_verb(5, "%s: p->stopreads[%d] p->owner[%p]\n", p->dev, p->stopreads, (void *)p->owner);
- }
- }
- ast_verb(5, "%s: chanreads: Finished cycle...\n", p->dev);
- }
- p->read_state = 0;
-
- /* When stopreads seen, go away! */
- vpb_record_buf_finish(p->handle);
- p->read_state = 0;
- ast_mutex_unlock(&p->record_lock);
-
- ast_verb(2, "%s: Ending record mode (%d/%s)\n",
- p->dev, p->stopreads, p->owner ? "yes" : "no");
- return NULL;
-}
-
-static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context)
-{
- struct ast_channel *tmp;
- char cid_num[256];
- char cid_name[256];
-
- if (me->owner) {
- ast_log(LOG_WARNING, "Called vpb_new on owned channel (%s) ?!\n", me->dev);
- return NULL;
- }
- ast_verb(4, "%s: New call for context [%s]\n", me->dev, context);
-
- tmp = ast_channel_alloc(1, state, 0, 0, "", me->ext, me->context, 0, me->dev);
- if (tmp) {
- if (use_ast_ind == 1){
- tmp->tech = &vpb_tech_indicate;
- } else {
- tmp->tech = &vpb_tech;
- }
-
- tmp->callgroup = me->callgroup;
- tmp->pickupgroup = me->pickupgroup;
-
- /* Linear is the preferred format. Although Voicetronix supports other formats
- * they are all converted to/from linear in the vpb code. Best for us to use
- * linear since we can then adjust volume in this modules.
- */
- tmp->nativeformats = prefformat;
- tmp->rawreadformat = AST_FORMAT_SLINEAR;
- tmp->rawwriteformat = AST_FORMAT_SLINEAR;
- if (state == AST_STATE_RING) {
- tmp->rings = 1;
- cid_name[0] = '\0';
- cid_num[0] = '\0';
- ast_callerid_split(me->callerid, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
- ast_set_callerid(tmp, cid_num, cid_name, cid_num);
- }
- tmp->tech_pvt = me;
-
- ast_copy_string(tmp->context, context, sizeof(tmp->context));
- if (!ast_strlen_zero(me->ext))
- ast_copy_string(tmp->exten, me->ext, sizeof(tmp->exten));
- else
- strcpy(tmp->exten, "s");
- if (!ast_strlen_zero(me->language))
- ast_string_field_set(tmp, language, me->language);
-
- me->owner = tmp;
-
- me->bridge = NULL;
- me->lastoutput = -1;
- me->lastinput = -1;
- me->last_ignore_dtmf = 1;
- me->readthread = 0;
- me->play_dtmf[0] = '\0';
- me->faxhandled = 0;
-
- me->lastgrunt = ast_tvnow(); /* Assume at least one grunt tone seen now. */
- me->lastplay = ast_tvnow(); /* Assume at least one grunt tone seen now. */
-
- if (state != AST_STATE_DOWN) {
- if ((me->mode != MODE_FXO) && (state != AST_STATE_UP)) {
- vpb_answer(tmp);
- }
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- }
- }
- } else {
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
- }
- return tmp;
-}
-
-static struct ast_channel *vpb_request(const char *type, int format, void *vdata, int *cause)
-{
- int oldformat;
- struct vpb_pvt *p;
- struct ast_channel *tmp = NULL;
- char *sepstr, *data = (char *)vdata, *name;
- const char *s;
- int group = -1;
-
- oldformat = format;
- format &= prefformat;
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
- return NULL;
- }
-
- name = ast_strdup(S_OR(data, ""));
-
- sepstr = name;
- s = strsep(&sepstr, "/"); /* Handle / issues */
- if (!s)
- s = "";
- /* Check if we are looking for a group */
- if (toupper(name[0]) == 'G' || toupper(name[0]) == 'R') {
- group = atoi(name + 1);
- }
- /* Search for an unowned channel */
- ast_mutex_lock(&iflock);
- for (p = iflist; p; p = p->next) {
- if (group == -1) {
- if (strncmp(s, p->dev + 4, sizeof p->dev) == 0) {
- if (!p->owner) {
- tmp = vpb_new(p, AST_STATE_DOWN, p->context);
- break;
- }
- }
- } else {
- if ((p->group == group) && (!p->owner)) {
- tmp = vpb_new(p, AST_STATE_DOWN, p->context);
- break;
- }
- }
- }
- ast_mutex_unlock(&iflock);
-
-
- ast_verb(2, " %s requested, got: [%s]\n", name, tmp ? tmp->name : "None");
-
- ast_free(name);
-
- restart_monitor();
- return tmp;
-}
-
-static float parse_gain_value(const char *gain_type, const char *value)
-{
- float gain;
-
- /* try to scan number */
- if (sscanf(value, "%f", &gain) != 1) {
- ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n", value, gain_type, config);
- return DEFAULT_GAIN;
- }
-
-
- /* percentage? */
- /*if (value[strlen(value) - 1] == '%') */
- /* return gain / (float)100; */
-
- return gain;
-}
-
-
-static int unload_module(void)
-{
- struct vpb_pvt *p;
- /* First, take us out of the channel loop */
- if (use_ast_ind == 1){
- ast_channel_unregister(&vpb_tech_indicate);
- } else {
- ast_channel_unregister(&vpb_tech);
- }
-
- ast_mutex_lock(&iflock);
- /* Hangup all interfaces if they have an owner */
- for (p = iflist; p; p = p->next) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
-
- ast_mutex_lock(&monlock);
- if (mthreadactive > -1) {
- pthread_cancel(monitor_thread);
- pthread_join(monitor_thread, NULL);
- }
- mthreadactive = -2;
- ast_mutex_unlock(&monlock);
-
- ast_mutex_lock(&iflock);
- /* Destroy all the interfaces and free their memory */
-
- while (iflist) {
- p = iflist;
- ast_mutex_destroy(&p->lock);
- pthread_cancel(p->readthread);
- ast_mutex_destroy(&p->owner_lock);
- ast_mutex_destroy(&p->record_lock);
- ast_mutex_destroy(&p->play_lock);
- ast_mutex_destroy(&p->play_dtmf_lock);
- p->readthread = 0;
-
- vpb_close(p->handle);
-
- iflist = iflist->next;
-
- ast_free(p);
- }
- iflist = NULL;
- ast_mutex_unlock(&iflock);
-
- if (bridges) {
- ast_mutex_lock(&bridge_lock);
- memset(bridges, 0, sizeof bridges);
- ast_mutex_unlock(&bridge_lock);
- ast_mutex_destroy(&bridge_lock);
- for (int i = 0; i < max_bridges; i++) {
- ast_mutex_destroy(&bridges[i].lock);
- ast_cond_destroy(&bridges[i].cond);
- }
- ast_free(bridges);
- }
-
- return 0;
-}
-
-static enum ast_module_load_result load_module()
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- struct vpb_pvt *tmp;
- int board = 0, group = 0;
- ast_group_t callgroup = 0;
- ast_group_t pickupgroup = 0;
- int mode = MODE_IMMEDIATE;
- float txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN;
- float txswgain = 0, rxswgain = 0;
- int got_gain=0;
- int first_channel = 1;
- int echo_cancel = DEFAULT_ECHO_CANCEL;
- enum ast_module_load_result error = AST_MODULE_LOAD_SUCCESS; /* Error flag */
- int bal1 = -1; /* Special value - means do not set */
- int bal2 = -1;
- int bal3 = -1;
- char * callerid = NULL;
-
- int num_cards = 0;
- try {
- num_cards = vpb_get_num_cards();
- } catch (VpbException e) {
- ast_log(LOG_ERROR, "No Voicetronix cards detected\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- int ports_per_card[num_cards];
- for (int i = 0; i < num_cards; ++i)
- ports_per_card[i] = vpb_get_ports_per_card(i);
-
- cfg = ast_config_load(config);
-
- /* We *must* have a config file otherwise stop immediately */
- if (!cfg) {
- ast_log(LOG_ERROR, "Unable to load config %s\n", config);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- ast_mutex_lock(&iflock);
- v = ast_variable_browse(cfg, "general");
- while (v){
- if (strcasecmp(v->name, "cards") == 0) {
- ast_log(LOG_NOTICE, "VPB Driver configured to use [%d] cards\n", atoi(v->value));
- } else if (strcasecmp(v->name, "indication") == 0) {
- use_ast_ind = 1;
- ast_log(LOG_NOTICE, "VPB driver using Asterisk Indication functions!\n");
- } else if (strcasecmp(v->name, "break-for-dtmf") == 0) {
- if (ast_true(v->value)) {
- break_for_dtmf = 1;
- } else {
- break_for_dtmf = 0;
- ast_log(LOG_NOTICE, "VPB driver not stopping for DTMF's in native bridge\n");
- }
- } else if (strcasecmp(v->name, "ast-dtmf") == 0) {
- use_ast_dtmf = 1;
- ast_log(LOG_NOTICE, "VPB driver using Asterisk DTMF play functions!\n");
- } else if (strcasecmp(v->name, "ast-dtmf-det") == 0) {
- use_ast_dtmfdet = 1;
- ast_log(LOG_NOTICE, "VPB driver using Asterisk DTMF detection functions!\n");
- } else if (strcasecmp(v->name, "relaxdtmf") == 0) {
- relaxdtmf = 1;
- ast_log(LOG_NOTICE, "VPB driver using Relaxed DTMF with Asterisk DTMF detections functions!\n");
- } else if (strcasecmp(v->name, "timer_period_ring") == 0) {
- timer_period_ring = atoi(v->value);
- } else if (strcasecmp(v->name, "ecsuppthres") == 0) {
- ec_supp_threshold = (short)atoi(v->value);
- } else if (strcasecmp(v->name, "dtmfidd") == 0) {
- dtmf_idd = atoi(v->value);
- ast_log(LOG_NOTICE, "VPB Driver setting DTMF IDD to [%d]ms\n", dtmf_idd);
- }
- v = v->next;
- }
-
- v = ast_variable_browse(cfg, "interfaces");
- while (v) {
- /* Create the interface list */
- if (strcasecmp(v->name, "board") == 0) {
- board = atoi(v->value);
- } else if (strcasecmp(v->name, "group") == 0) {
- group = atoi(v->value);
- } else if (strcasecmp(v->name, "callgroup") == 0) {
- callgroup = ast_get_group(v->value);
- } else if (strcasecmp(v->name, "pickupgroup") == 0) {
- pickupgroup = ast_get_group(v->value);
- } else if (strcasecmp(v->name, "usepolaritycid") == 0) {
- UsePolarityCID = atoi(v->value);
- } else if (strcasecmp(v->name, "useloopdrop") == 0) {
- UseLoopDrop = atoi(v->value);
- } else if (strcasecmp(v->name, "usenativebridge") == 0) {
- UseNativeBridge = atoi(v->value);
- } else if (strcasecmp(v->name, "channel") == 0) {
- int channel = atoi(v->value);
- if (board >= num_cards || board < 0 || channel < 0 || channel >= ports_per_card[board]) {
- ast_log(LOG_ERROR, "Invalid board/channel (%d/%d) for channel '%s'\n", board, channel, v->value);
- error = AST_MODULE_LOAD_FAILURE;
- goto done;
- }
- tmp = mkif(board, channel, mode, got_gain, txgain, rxgain, txswgain, rxswgain, bal1, bal2, bal3, callerid, echo_cancel,group,callgroup,pickupgroup);
- if (tmp) {
- if (first_channel) {
- mkbrd(tmp->vpb_model, echo_cancel);
- first_channel = 0;
- }
- tmp->next = iflist;
- iflist = tmp;
- } else {
- ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
- error = AST_MODULE_LOAD_FAILURE;
- goto done;
- }
- } else if (strcasecmp(v->name, "language") == 0) {
- ast_copy_string(language, v->value, sizeof(language));
- } else if (strcasecmp(v->name, "callerid") == 0) {
- callerid = ast_strdup(v->value);
- } else if (strcasecmp(v->name, "mode") == 0) {
- if (strncasecmp(v->value, "di", 2) == 0) {
- mode = MODE_DIALTONE;
- } else if (strncasecmp(v->value, "im", 2) == 0) {
- mode = MODE_IMMEDIATE;
- } else if (strncasecmp(v->value, "fx", 2) == 0) {
- mode = MODE_FXO;
- } else {
- ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
- }
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(context, v->value, sizeof(context));
- } else if (!strcasecmp(v->name, "echocancel")) {
- if (!strcasecmp(v->value, "off")) {
- echo_cancel = 0;
- }
- } else if (strcasecmp(v->name, "txgain") == 0) {
- txswgain = parse_gain_value(v->name, v->value);
- got_gain |= VPB_GOT_TXSWG;
- } else if (strcasecmp(v->name, "rxgain") == 0) {
- rxswgain = parse_gain_value(v->name, v->value);
- got_gain |= VPB_GOT_RXSWG;
- } else if (strcasecmp(v->name, "txhwgain") == 0) {
- txgain = parse_gain_value(v->name, v->value);
- got_gain |= VPB_GOT_TXHWG;
- } else if (strcasecmp(v->name, "rxhwgain") == 0) {
- rxgain = parse_gain_value(v->name, v->value);
- got_gain |= VPB_GOT_RXHWG;
- } else if (strcasecmp(v->name, "bal1") == 0) {
- bal1 = strtol(v->value, NULL, 16);
- if (bal1 < 0 || bal1 > 255) {
- ast_log(LOG_WARNING, "Bad bal1 value: %d\n", bal1);
- bal1 = -1;
- }
- } else if (strcasecmp(v->name, "bal2") == 0) {
- bal2 = strtol(v->value, NULL, 16);
- if (bal2 < 0 || bal2 > 255) {
- ast_log(LOG_WARNING, "Bad bal2 value: %d\n", bal2);
- bal2 = -1;
- }
- } else if (strcasecmp(v->name, "bal3") == 0) {
- bal3 = strtol(v->value, NULL, 16);
- if (bal3 < 0 || bal3 > 255) {
- ast_log(LOG_WARNING, "Bad bal3 value: %d\n", bal3);
- bal3 = -1;
- }
- } else if (strcasecmp(v->name, "grunttimeout") == 0) {
- gruntdetect_timeout = 1000 * atoi(v->value);
- }
- v = v->next;
- }
-
- if (gruntdetect_timeout < 1000)
- gruntdetect_timeout = 1000;
-
- done: (void)0;
- ast_mutex_unlock(&iflock);
-
- ast_config_destroy(cfg);
-
- if (use_ast_ind == 1) {
- if (error == AST_MODULE_LOAD_SUCCESS && ast_channel_register(&vpb_tech_indicate) != 0) {
- ast_log(LOG_ERROR, "Unable to register channel class 'vpb'\n");
- error = AST_MODULE_LOAD_FAILURE;
- } else {
- ast_log(LOG_NOTICE, "VPB driver Registered (w/AstIndication)\n");
- }
- } else {
- if (error == AST_MODULE_LOAD_SUCCESS && ast_channel_register(&vpb_tech) != 0) {
- ast_log(LOG_ERROR, "Unable to register channel class 'vpb'\n");
- error = AST_MODULE_LOAD_FAILURE;
- } else {
- ast_log(LOG_NOTICE, "VPB driver Registered )\n");
- }
- }
-
-
- if (error != AST_MODULE_LOAD_SUCCESS)
- unload_module();
- else
- restart_monitor(); /* And start the monitor for the first time */
-
- return error;
-}
-
-/**/
-#if defined(__cplusplus) || defined(c_plusplus)
- }
-#endif
-/**/
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Voicetronix API driver");
diff --git a/1.4/channels/chan_zap.c b/1.4/channels/chan_zap.c
deleted file mode 100644
index fc016bac9..000000000
--- a/1.4/channels/chan_zap.c
+++ /dev/null
@@ -1,11583 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Zaptel Pseudo TDM interface
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * Connects to the zaptel telephony library as well as
- * libpri. Libpri is optional and needed only if you are
- * going to use ISDN connections.
- *
- * You need to install libraries before you attempt to compile
- * and install the zaptel channel.
- *
- * \par See also
- * \arg \ref Config_zap
- *
- * \ingroup channel_drivers
- *
- * \todo Deprecate the "musiconhold" configuration option post 1.4
- */
-
-/*** MODULEINFO
- <depend>res_smdi</depend>
- <depend>zaptel_vldtmf</depend>
- <depend>zaptel</depend>
- <depend>tonezone</depend>
- <depend>res_features</depend>
- <use>pri</use>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#ifdef __NetBSD__
-#include <pthread.h>
-#include <signal.h>
-#else
-#include <sys/signal.h>
-#endif
-#include <errno.h>
-#include <stdlib.h>
-#if !defined(SOLARIS) && !defined(__FreeBSD__)
-#include <stdint.h>
-#endif
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <math.h>
-#include <ctype.h>
-#include <zaptel/zaptel.h>
-#include <zaptel/tonezone.h>
-
-#ifdef HAVE_PRI
-#include <libpri.h>
-#endif
-
-#include "asterisk/lock.h"
-#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/file.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/alaw.h"
-#include "asterisk/callerid.h"
-#include "asterisk/adsi.h"
-#include "asterisk/cli.h"
-#include "asterisk/cdr.h"
-#include "asterisk/features.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/say.h"
-#include "asterisk/tdd.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/astdb.h"
-#include "asterisk/manager.h"
-#include "asterisk/causes.h"
-#include "asterisk/term.h"
-#include "asterisk/utils.h"
-#include "asterisk/transcap.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/smdi.h"
-#include "asterisk/astobj.h"
-#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
-
-/*! Global jitterbuffer configuration - by default, jb is disabled */
-static struct ast_jb_conf default_jbconf =
-{
- .flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
-};
-static struct ast_jb_conf global_jbconf;
-
-#if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
-#error "Your zaptel is too old. Please update"
-#endif
-
-#ifndef ZT_TONEDETECT
-/* Work around older code with no tone detect */
-#define ZT_EVENT_DTMFDOWN 0
-#define ZT_EVENT_DTMFUP 0
-#endif
-
-/* define this to send PRI user-user information elements */
-#undef SUPPORT_USERUSER
-
-/*!
- * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
- * the user hangs up to reset the state machine so ring works properly.
- * This is used to be able to support kewlstart by putting the zhone in
- * groundstart mode since their forward disconnect supervision is entirely
- * broken even though their documentation says it isn't and their support
- * is entirely unwilling to provide any assistance with their channel banks
- * even though their web site says they support their products for life.
- */
-/* #define ZHONE_HACK */
-
-/*! \note
- * Define if you want to check the hook state for an FXO (FXS signalled) interface
- * before dialing on it. Certain FXO interfaces always think they're out of
- * service with this method however.
- */
-/* #define ZAP_CHECK_HOOKSTATE */
-
-/*! \brief Typically, how many rings before we should send Caller*ID */
-#define DEFAULT_CIDRINGS 1
-
-#define CHANNEL_PSEUDO -12
-
-#define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
-
-/*! \brief Signaling types that need to use MF detection should be placed in this macro */
-#define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB))
-
-static const char tdesc[] = "Zapata Telephony Driver"
-#ifdef HAVE_PRI
- " w/PRI"
-#endif
-;
-
-static const char config[] = "zapata.conf";
-
-#define SIG_EM ZT_SIG_EM
-#define SIG_EMWINK (0x0100000 | ZT_SIG_EM)
-#define SIG_FEATD (0x0200000 | ZT_SIG_EM)
-#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
-#define SIG_FEATB (0x0800000 | ZT_SIG_EM)
-#define SIG_E911 (0x1000000 | ZT_SIG_EM)
-#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
-#define SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM)
-#define SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
-#define SIG_FXSLS ZT_SIG_FXSLS
-#define SIG_FXSGS ZT_SIG_FXSGS
-#define SIG_FXSKS ZT_SIG_FXSKS
-#define SIG_FXOLS ZT_SIG_FXOLS
-#define SIG_FXOGS ZT_SIG_FXOGS
-#define SIG_FXOKS ZT_SIG_FXOKS
-#define SIG_PRI ZT_SIG_CLEAR
-#define SIG_SF ZT_SIG_SF
-#define SIG_SFWINK (0x0100000 | ZT_SIG_SF)
-#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
-#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
-#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF)
-#define SIG_EM_E1 ZT_SIG_EM_E1
-#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS)
-#define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS)
-
-#define NUM_SPANS 32
-#define NUM_DCHANS 4 /*!< No more than 4 d-channels */
-#define MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
-
-#define CHAN_PSEUDO -2
-
-#define DCHAN_PROVISIONED (1 << 0)
-#define DCHAN_NOTINALARM (1 << 1)
-#define DCHAN_UP (1 << 2)
-
-#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
-
-static char defaultcic[64] = "";
-static char defaultozz[64] = "";
-
-static char progzone[10] = "";
-
-static int distinctiveringaftercid = 0;
-
-static int numbufs = 4;
-
-#ifdef HAVE_PRI
-static struct ast_channel inuse;
-#ifdef PRI_GETSET_TIMERS
-static int pritimers[PRI_MAX_TIMERS];
-#endif
-static int pridebugfd = -1;
-static char pridebugfilename[1024] = "";
-#endif
-
-/*! \brief Wait up to 16 seconds for first digit (FXO logic) */
-static int firstdigittimeout = 16000;
-
-/*! \brief How long to wait for following digits (FXO logic) */
-static int gendigittimeout = 8000;
-
-/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
-static int matchdigittimeout = 3000;
-
-/*! \brief Protect the interface list (of zt_pvt's) */
-AST_MUTEX_DEFINE_STATIC(iflock);
-
-
-static int ifcount = 0;
-
-#ifdef HAVE_PRI
-AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
-#endif
-
-/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
-
-/*! \brief This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-
-static int restart_monitor(void);
-
-static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-
-static int zt_sendtext(struct ast_channel *c, const char *text);
-
-/*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
-static inline int zt_get_event(int fd)
-{
- int j;
- if (ioctl(fd, ZT_GETEVENT, &j) == -1)
- return -1;
- return j;
-}
-
-/*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
-static inline int zt_wait_event(int fd)
-{
- int i, j = 0;
- i = ZT_IOMUX_SIGEVENT;
- if (ioctl(fd, ZT_IOMUX, &i) == -1)
- return -1;
- if (ioctl(fd, ZT_GETEVENT, &j) == -1)
- return -1;
- return j;
-}
-
-/*! Chunk size to read -- we use 20ms chunks to make things happy. */
-#define READ_SIZE 160
-
-#define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
-#define MASK_INUSE (1 << 1) /*!< Channel currently in use */
-
-#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) /*!< 300 ms */
-#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) /*!< 300 ms */
-#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) /*!< 500 ms */
-#define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */
-#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE)
-
-struct zt_pvt;
-
-static int ringt_base = DEFAULT_RINGT;
-
-#ifdef HAVE_PRI
-
-#define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
-#define PRI_CHANNEL(p) ((p) & 0xff)
-#define PRI_SPAN(p) (((p) >> 8) & 0xff)
-#define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
-
-struct zt_pri {
- pthread_t master; /*!< Thread of master */
- ast_mutex_t lock; /*!< Mutex */
- char idleext[AST_MAX_EXTENSION]; /*!< Where to idle extra calls */
- char idlecontext[AST_MAX_CONTEXT]; /*!< What context to use for idle */
- char idledial[AST_MAX_EXTENSION]; /*!< What to dial before dumping */
- int minunused; /*!< Min # of channels to keep empty */
- int minidle; /*!< Min # of "idling" calls to keep active */
- int nodetype; /*!< Node type */
- int switchtype; /*!< Type of switch to emulate */
- int nsf; /*!< Network-Specific Facilities */
- int dialplan; /*!< Dialing plan */
- int localdialplan; /*!< Local dialing plan */
- char internationalprefix[10]; /*!< country access code ('00' for european dialplans) */
- char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */
- char localprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */
- char privateprefix[20]; /*!< for private dialplans */
- char unknownprefix[20]; /*!< for unknown dialplans */
- int dchannels[NUM_DCHANS]; /*!< What channel are the dchannels on */
- int trunkgroup; /*!< What our trunkgroup is */
- int mastertrunkgroup; /*!< What trunk group is our master */
- int prilogicalspan; /*!< Logical span number within trunk group */
- int numchans; /*!< Num of channels we represent */
- int overlapdial; /*!< In overlap dialing mode */
- int facilityenable; /*!< Enable facility IEs */
- struct pri *dchans[NUM_DCHANS]; /*!< Actual d-channels */
- int dchanavail[NUM_DCHANS]; /*!< Whether each channel is available */
- struct pri *pri; /*!< Currently active D-channel */
- int debug;
- int fds[NUM_DCHANS]; /*!< FD's for d-channels */
- int offset;
- int span;
- int resetting;
- int resetpos;
- time_t lastreset; /*!< time when unused channels were last reset */
- long resetinterval; /*!< Interval (in seconds) for resetting unused channels */
- struct zt_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
- struct zt_pvt *crvs; /*!< Member CRV structs */
- struct zt_pvt *crvend; /*!< Pointer to end of CRV structs */
-};
-
-
-static struct zt_pri pris[NUM_SPANS];
-
-#if 0
-#define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
-#else
-#define DEFAULT_PRI_DEBUG 0
-#endif
-
-static inline void pri_rel(struct zt_pri *pri)
-{
- ast_mutex_unlock(&pri->lock);
-}
-
-#else
-/*! Shut up the compiler */
-struct zt_pri;
-#endif
-
-#define SUB_REAL 0 /*!< Active call */
-#define SUB_CALLWAIT 1 /*!< Call-Waiting call on hold */
-#define SUB_THREEWAY 2 /*!< Three-way call */
-
-/* Polarity states */
-#define POLARITY_IDLE 0
-#define POLARITY_REV 1
-
-
-static struct zt_distRings drings;
-
-struct distRingData {
- int ring[3];
-};
-struct ringContextData {
- char contextData[AST_MAX_CONTEXT];
-};
-struct zt_distRings {
- struct distRingData ringnum[3];
- struct ringContextData ringContext[3];
-};
-
-static char *subnames[] = {
- "Real",
- "Callwait",
- "Threeway"
-};
-
-struct zt_subchannel {
- int zfd;
- struct ast_channel *owner;
- int chan;
- short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
- struct ast_frame f; /*!< One frame for each channel. How did this ever work before? */
- unsigned int needringing:1;
- unsigned int needbusy:1;
- unsigned int needcongestion:1;
- unsigned int needcallerid:1;
- unsigned int needanswer:1;
- unsigned int needflash:1;
- unsigned int needhold:1;
- unsigned int needunhold:1;
- unsigned int linear:1;
- unsigned int inthreeway:1;
- ZT_CONFINFO curconf;
-};
-
-#define CONF_USER_REAL (1 << 0)
-#define CONF_USER_THIRDCALL (1 << 1)
-
-#define MAX_SLAVES 4
-
-static struct zt_pvt {
- ast_mutex_t lock;
- struct ast_channel *owner; /*!< Our current active owner (if applicable) */
- /*!< Up to three channels can be associated with this call */
-
- struct zt_subchannel sub_unused; /*!< Just a safety precaution */
- struct zt_subchannel subs[3]; /*!< Sub-channels */
- struct zt_confinfo saveconf; /*!< Saved conference info */
-
- struct zt_pvt *slaves[MAX_SLAVES]; /*!< Slave to us (follows our conferencing) */
- struct zt_pvt *master; /*!< Master to us (we follow their conferencing) */
- int inconference; /*!< If our real should be in the conference */
-
- int sig; /*!< Signalling style */
- int radio; /*!< radio type */
- int outsigmod; /*!< Outbound Signalling style (modifier) */
- int oprmode; /*!< "Operator Services" mode */
- struct zt_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */
- float rxgain;
- float txgain;
- int tonezone; /*!< tone zone for this chan, or -1 for default */
- struct zt_pvt *next; /*!< Next channel in list */
- struct zt_pvt *prev; /*!< Prev channel in list */
-
- /* flags */
- unsigned int adsi:1;
- unsigned int answeronpolarityswitch:1;
- unsigned int busydetect:1;
- unsigned int callreturn:1;
- unsigned int callwaiting:1;
- unsigned int callwaitingcallerid:1;
- unsigned int cancallforward:1;
- unsigned int canpark:1;
- unsigned int confirmanswer:1; /*!< Wait for '#' to confirm answer */
- unsigned int destroy:1;
- unsigned int didtdd:1; /*!< flag to say its done it once */
- unsigned int dialednone:1;
- unsigned int dialing:1;
- unsigned int digital:1;
- unsigned int dnd:1;
- unsigned int echobreak:1;
- unsigned int echocanbridged:1;
- unsigned int echocanon:1;
- unsigned int faxhandled:1; /*!< Has a fax tone already been handled? */
- unsigned int firstradio:1;
- unsigned int hanguponpolarityswitch:1;
- unsigned int hardwaredtmf:1;
- unsigned int hidecallerid:1;
- unsigned int hidecalleridname:1; /*!< Hide just the name not the number for legacy PBX use */
- unsigned int ignoredtmf:1;
- unsigned int immediate:1; /*!< Answer before getting digits? */
- unsigned int inalarm:1;
- unsigned int unknown_alarm:1;
- unsigned int mate:1; /*!< flag to say its in MATE mode */
- unsigned int outgoing:1;
- unsigned int overlapdial:1;
- unsigned int permcallwaiting:1;
- unsigned int permhidecallerid:1; /*!< Whether to hide our outgoing caller ID or not */
- unsigned int priindication_oob:1;
- unsigned int priexclusive:1;
- unsigned int pulse:1;
- unsigned int pulsedial:1; /*!< whether a pulse dial phone is detected */
- unsigned int restrictcid:1; /*!< Whether restrict the callerid -> only send ANI */
- unsigned int threewaycalling:1;
- unsigned int transfer:1;
- unsigned int use_callerid:1; /*!< Whether or not to use caller id on this channel */
- unsigned int use_callingpres:1; /*!< Whether to use the callingpres the calling switch sends */
- unsigned int usedistinctiveringdetection:1;
- unsigned int zaptrcallerid:1; /*!< should we use the callerid from incoming call on zap transfer or not */
- unsigned int transfertobusy:1; /*!< allow flash-transfers to busy channels */
-#if defined(HAVE_PRI)
- unsigned int alerting:1;
- unsigned int alreadyhungup:1;
- unsigned int isidlecall:1;
- unsigned int proceeding:1;
- unsigned int progress:1;
- unsigned int resetting:1;
- unsigned int setup_ack:1;
-#endif
- unsigned int use_smdi:1; /* Whether to use SMDI on this channel */
- struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
-
- struct zt_distRings drings;
-
- char context[AST_MAX_CONTEXT];
- char defcontext[AST_MAX_CONTEXT];
- char exten[AST_MAX_EXTENSION];
- char language[MAX_LANGUAGE];
- char mohinterpret[MAX_MUSICCLASS];
- char mohsuggest[MAX_MUSICCLASS];
-#ifdef PRI_ANI
- char cid_ani[AST_MAX_EXTENSION];
-#endif
- char cid_num[AST_MAX_EXTENSION];
- int cid_ton; /*!< Type Of Number (TON) */
- char cid_name[AST_MAX_EXTENSION];
- char lastcid_num[AST_MAX_EXTENSION];
- char lastcid_name[AST_MAX_EXTENSION];
- char *origcid_num; /*!< malloced original callerid */
- char *origcid_name; /*!< malloced original callerid */
- char callwait_num[AST_MAX_EXTENSION];
- char callwait_name[AST_MAX_EXTENSION];
- char rdnis[AST_MAX_EXTENSION];
- char dnid[AST_MAX_EXTENSION];
- ast_group_t group;
- int law;
- int confno; /*!< Our conference */
- int confusers; /*!< Who is using our conference */
- int propconfno; /*!< Propagated conference number */
- ast_group_t callgroup;
- ast_group_t pickupgroup;
- int channel; /*!< Channel Number or CRV */
- int span; /*!< Span number */
- time_t guardtime; /*!< Must wait this much time before using for new call */
- int cid_signalling; /*!< CID signalling type bell202 or v23 */
- int cid_start; /*!< CID start indicator, polarity or ring */
- int callingpres; /*!< The value of callling presentation that we're going to use when placing a PRI call */
- int callwaitingrepeat; /*!< How many samples to wait before repeating call waiting */
- int cidcwexpire; /*!< When to expire our muting for CID/CW */
- unsigned char *cidspill;
- int cidpos;
- int cidlen;
- int ringt;
- int ringt_base;
- int stripmsd;
- int callwaitcas;
- int callwaitrings;
- int echocancel;
- int echotraining;
- char echorest[20];
- int busycount;
- int busy_tonelength;
- int busy_quietlength;
- int callprogress;
- struct timeval flashtime; /*!< Last flash-hook time */
- struct ast_dsp *dsp;
- int cref; /*!< Call reference number */
- ZT_DIAL_OPERATION dop;
- int whichwink; /*!< SIG_FEATDMF_TA Which wink are we on? */
- char finaldial[64];
- char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
- int amaflags; /*!< AMA Flags */
- struct tdd_state *tdd; /*!< TDD flag */
- char call_forward[AST_MAX_EXTENSION];
- char mailbox[AST_MAX_EXTENSION];
- char dialdest[256];
- int onhooktime;
- int msgstate;
- int distinctivering; /*!< Which distinctivering to use */
- int cidrings; /*!< Which ring to deliver CID on */
- int dtmfrelax; /*!< whether to run in relaxed DTMF mode */
- int fake_event;
- int polarityonanswerdelay;
- struct timeval polaritydelaytv;
- int sendcalleridafter;
-#ifdef HAVE_PRI
- struct zt_pri *pri;
- struct zt_pvt *bearer;
- struct zt_pvt *realcall;
- q931_call *call;
- int prioffset;
- int logicalspan;
-#endif
- int polarity;
- int dsp_features;
- char begindigit;
-} *iflist = NULL, *ifend = NULL;
-
-/*! \brief Channel configuration from zapata.conf .
- * This struct is used for parsing the [channels] section of zapata.conf.
- * Generally there is a field here for every possible configuration item.
- *
- * The state of fields is saved along the parsing and whenever a 'channel'
- * statement is reached, the current zt_chan_conf is used to configure the
- * channel (struct zt_pvt)
- *
- * @seealso zt_chan_init for the default values.
- */
-struct zt_chan_conf {
- struct zt_pvt chan;
-#ifdef HAVE_PRI
- struct zt_pri pri;
-#endif
- ZT_PARAMS timing;
-
- char smdi_port[SMDI_MAX_FILENAME_LEN];
-};
-
-/** returns a new zt_chan_conf with default values (by-value) */
-static struct zt_chan_conf zt_chan_conf_default(void) {
- /* recall that if a field is not included here it is initialized
- * to 0 or equivalent
- */
- struct zt_chan_conf conf = {
-#ifdef HAVE_PRI
- .pri = {
- .nsf = PRI_NSF_NONE,
- .switchtype = PRI_SWITCH_NI2,
- .dialplan = PRI_NATIONAL_ISDN + 1,
- .localdialplan = PRI_NATIONAL_ISDN + 1,
- .nodetype = PRI_CPE,
-
- .minunused = 2,
- .idleext = "",
- .idledial = "",
- .internationalprefix = "",
- .nationalprefix = "",
- .localprefix = "",
- .privateprefix = "",
- .unknownprefix = "",
-
- .resetinterval = 3600
- },
-#endif
- .chan = {
- .context = "default",
- .cid_num = "",
- .cid_name = "",
- .mohinterpret = "default",
- .mohsuggest = "",
- .transfertobusy = 1,
-
- .cid_signalling = CID_SIG_BELL,
- .cid_start = CID_START_RING,
- .zaptrcallerid = 0,
- .use_callerid = 1,
- .sig = -1,
- .outsigmod = -1,
-
- .tonezone = -1,
-
- .echocancel = 1,
-
- .busycount = 3,
-
- .accountcode = "",
-
- .mailbox = "",
-
-
- .polarityonanswerdelay = 600,
-
- .sendcalleridafter = DEFAULT_CIDRINGS
- },
- .timing = {
- .prewinktime = -1,
- .preflashtime = -1,
- .winktime = -1,
- .flashtime = -1,
- .starttime = -1,
- .rxwinktime = -1,
- .rxflashtime = -1,
- .debouncetime = -1
- },
- .smdi_port = "/dev/ttyS0",
- };
-
- return conf;
-}
-
-
-static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
-static int zt_digit_begin(struct ast_channel *ast, char digit);
-static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int zt_sendtext(struct ast_channel *c, const char *text);
-static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
-static int zt_hangup(struct ast_channel *ast);
-static int zt_answer(struct ast_channel *ast);
-static struct ast_frame *zt_read(struct ast_channel *ast);
-static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
-static struct ast_frame *zt_exception(struct ast_channel *ast);
-static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
-static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
-static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
-static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
-
-static const struct ast_channel_tech zap_tech = {
- .type = "Zap",
- .description = tdesc,
- .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
- .requester = zt_request,
- .send_digit_begin = zt_digit_begin,
- .send_digit_end = zt_digit_end,
- .send_text = zt_sendtext,
- .call = zt_call,
- .hangup = zt_hangup,
- .answer = zt_answer,
- .read = zt_read,
- .write = zt_write,
- .bridge = zt_bridge,
- .exception = zt_exception,
- .indicate = zt_indicate,
- .fixup = zt_fixup,
- .setoption = zt_setoption,
- .func_channel_read = zt_func_read,
-};
-
-#ifdef HAVE_PRI
-#define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
-#else
-#define GET_CHANNEL(p) ((p)->channel)
-#endif
-
-struct zt_pvt *round_robin[32];
-
-#ifdef HAVE_PRI
-static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
-{
- int res;
- /* Grab the lock first */
- do {
- res = ast_mutex_trylock(&pri->lock);
- if (res) {
- ast_mutex_unlock(&pvt->lock);
- /* Release the lock and try again */
- usleep(1);
- ast_mutex_lock(&pvt->lock);
- }
- } while (res);
- /* Then break the poll */
- pthread_kill(pri->master, SIGURG);
- return 0;
-}
-#endif
-
-#define NUM_CADENCE_MAX 25
-static int num_cadence = 4;
-static int user_has_defined_cadences = 0;
-
-static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
- { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
- { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
- { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
- { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
-};
-
-/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
- * is 1, the second pause is 2 and so on.
- */
-
-static int cidrings[NUM_CADENCE_MAX] = {
- 2, /*!< Right after first long ring */
- 4, /*!< Right after long part */
- 3, /*!< After third chirp */
- 2, /*!< Second spell */
-};
-
-#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
- (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
-
-#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
-#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
-
-static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
-{
- int res;
- if (p->subs[0].owner == ast)
- res = 0;
- else if (p->subs[1].owner == ast)
- res = 1;
- else if (p->subs[2].owner == ast)
- res = 2;
- else {
- res = -1;
- if (!nullok)
- ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
- }
- return res;
-}
-
-#ifdef HAVE_PRI
-static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
-#else
-static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
-#endif
-{
-#ifdef HAVE_PRI
- if (pri)
- ast_mutex_unlock(&pri->lock);
-#endif
- for (;;) {
- if (p->subs[a].owner) {
- if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- } else {
- ast_queue_frame(p->subs[a].owner, &ast_null_frame);
- ast_mutex_unlock(&p->subs[a].owner->lock);
- break;
- }
- } else
- break;
- }
-#ifdef HAVE_PRI
- if (pri)
- ast_mutex_lock(&pri->lock);
-#endif
-}
-
-#ifdef HAVE_PRI
-static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
-#else
-static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
-#endif
-{
- /* We must unlock the PRI to avoid the possibility of a deadlock */
-#ifdef HAVE_PRI
- if (pri)
- ast_mutex_unlock(&pri->lock);
-#endif
- for (;;) {
- if (p->owner) {
- if (ast_mutex_trylock(&p->owner->lock)) {
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- } else {
- ast_queue_frame(p->owner, f);
- ast_mutex_unlock(&p->owner->lock);
- break;
- }
- } else
- break;
- }
-#ifdef HAVE_PRI
- if (pri)
- ast_mutex_lock(&pri->lock);
-#endif
-}
-
-static int restore_gains(struct zt_pvt *p);
-
-static void swap_subs(struct zt_pvt *p, int a, int b)
-{
- int tchan;
- int tinthreeway;
- struct ast_channel *towner;
-
- ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
-
- tchan = p->subs[a].chan;
- towner = p->subs[a].owner;
- tinthreeway = p->subs[a].inthreeway;
-
- p->subs[a].chan = p->subs[b].chan;
- p->subs[a].owner = p->subs[b].owner;
- p->subs[a].inthreeway = p->subs[b].inthreeway;
-
- p->subs[b].chan = tchan;
- p->subs[b].owner = towner;
- p->subs[b].inthreeway = tinthreeway;
-
- if (p->subs[a].owner)
- p->subs[a].owner->fds[0] = p->subs[a].zfd;
- if (p->subs[b].owner)
- p->subs[b].owner->fds[0] = p->subs[b].zfd;
- wakeup_sub(p, a, NULL);
- wakeup_sub(p, b, NULL);
-}
-
-static int zt_open(char *fn)
-{
- int fd;
- int isnum;
- int chan = 0;
- int bs;
- int x;
- isnum = 1;
- for (x = 0; x < strlen(fn); x++) {
- if (!isdigit(fn[x])) {
- isnum = 0;
- break;
- }
- }
- if (isnum) {
- chan = atoi(fn);
- if (chan < 1) {
- ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
- return -1;
- }
- fn = "/dev/zap/channel";
- }
- fd = open(fn, O_RDWR | O_NONBLOCK);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
- return -1;
- }
- if (chan) {
- if (ioctl(fd, ZT_SPECIFY, &chan)) {
- x = errno;
- close(fd);
- errno = x;
- ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
- return -1;
- }
- }
- bs = READ_SIZE;
- if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
- ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno));
- x = errno;
- close(fd);
- errno = x;
- return -1;
- }
- return fd;
-}
-
-static void zt_close(int fd)
-{
- if (fd > 0)
- close(fd);
-}
-
-static int zt_setlinear(int zfd, int linear)
-{
- int res;
- res = ioctl(zfd, ZT_SETLINEAR, &linear);
- if (res)
- return res;
- return 0;
-}
-
-
-static int alloc_sub(struct zt_pvt *p, int x)
-{
- ZT_BUFFERINFO bi;
- int res;
- if (p->subs[x].zfd < 0) {
- p->subs[x].zfd = zt_open("/dev/zap/pseudo");
- if (p->subs[x].zfd > -1) {
- res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
- if (!res) {
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = numbufs;
- res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
- }
- } else
- ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
- if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
- ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
- zt_close(p->subs[x].zfd);
- p->subs[x].zfd = -1;
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
- return 0;
- } else
- ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
- return -1;
- }
- ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
- return -1;
-}
-
-static int unalloc_sub(struct zt_pvt *p, int x)
-{
- if (!x) {
- ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
- return -1;
- }
- ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
- if (p->subs[x].zfd > -1) {
- zt_close(p->subs[x].zfd);
- }
- p->subs[x].zfd = -1;
- p->subs[x].linear = 0;
- p->subs[x].chan = 0;
- p->subs[x].owner = NULL;
- p->subs[x].inthreeway = 0;
- p->polarity = POLARITY_IDLE;
- memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
- return 0;
-}
-
-static int digit_to_dtmfindex(char digit)
-{
- if (isdigit(digit))
- return ZT_TONE_DTMF_BASE + (digit - '0');
- else if (digit >= 'A' && digit <= 'D')
- return ZT_TONE_DTMF_A + (digit - 'A');
- else if (digit >= 'a' && digit <= 'd')
- return ZT_TONE_DTMF_A + (digit - 'a');
- else if (digit == '*')
- return ZT_TONE_DTMF_s;
- else if (digit == '#')
- return ZT_TONE_DTMF_p;
- else
- return -1;
-}
-
-static int zt_digit_begin(struct ast_channel *chan, char digit)
-{
- struct zt_pvt *pvt;
- int index;
- int dtmf = -1;
-
- pvt = chan->tech_pvt;
-
- ast_mutex_lock(&pvt->lock);
-
- index = zt_get_index(chan, pvt, 0);
-
- if ((index != SUB_REAL) || !pvt->owner)
- goto out;
-
-#ifdef HAVE_PRI
- if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
- if (pvt->setup_ack) {
- if (!pri_grab(pvt, pvt->pri)) {
- pri_information(pvt->pri->pri, pvt->call, digit);
- pri_rel(pvt->pri);
- } else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
- } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
- int res;
- ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
- res = strlen(pvt->dialdest);
- pvt->dialdest[res++] = digit;
- pvt->dialdest[res] = '\0';
- }
- goto out;
- }
-#endif
- if ((dtmf = digit_to_dtmfindex(digit)) == -1)
- goto out;
-
- if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
- int res;
- ZT_DIAL_OPERATION zo = {
- .op = ZT_DIAL_OP_APPEND,
- .dialstr[0] = 'T',
- .dialstr[1] = digit,
- .dialstr[2] = 0,
- };
- if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
- ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
- else
- pvt->dialing = 1;
- } else {
- ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
- pvt->dialing = 1;
- pvt->begindigit = digit;
- }
-
-out:
- ast_mutex_unlock(&pvt->lock);
-
- return 0;
-}
-
-static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
-{
- struct zt_pvt *pvt;
- int res = 0;
- int index;
- int x;
-
- pvt = chan->tech_pvt;
-
- ast_mutex_lock(&pvt->lock);
-
- index = zt_get_index(chan, pvt, 0);
-
- if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
- goto out;
-
-#ifdef HAVE_PRI
- /* This means that the digit was already sent via PRI signalling */
- if (pvt->sig == SIG_PRI && !pvt->begindigit)
- goto out;
-#endif
-
- if (pvt->begindigit) {
- x = -1;
- ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
- res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
- pvt->dialing = 0;
- pvt->begindigit = 0;
- }
-
-out:
- ast_mutex_unlock(&pvt->lock);
-
- return res;
-}
-
-static char *events[] = {
- "No event",
- "On hook",
- "Ring/Answered",
- "Wink/Flash",
- "Alarm",
- "No more alarm",
- "HDLC Abort",
- "HDLC Overrun",
- "HDLC Bad FCS",
- "Dial Complete",
- "Ringer On",
- "Ringer Off",
- "Hook Transition Complete",
- "Bits Changed",
- "Pulse Start",
- "Timer Expired",
- "Timer Ping",
- "Polarity Reversal",
- "Ring Begin",
-};
-
-static struct {
- int alarm;
- char *name;
-} alarms[] = {
- { ZT_ALARM_RED, "Red Alarm" },
- { ZT_ALARM_YELLOW, "Yellow Alarm" },
- { ZT_ALARM_BLUE, "Blue Alarm" },
- { ZT_ALARM_RECOVER, "Recovering" },
- { ZT_ALARM_LOOPBACK, "Loopback" },
- { ZT_ALARM_NOTOPEN, "Not Open" },
- { ZT_ALARM_NONE, "None" },
-};
-
-static char *alarm2str(int alarm)
-{
- int x;
- for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
- if (alarms[x].alarm & alarm)
- return alarms[x].name;
- }
- return alarm ? "Unknown Alarm" : "No Alarm";
-}
-
-static char *event2str(int event)
-{
- static char buf[256];
- if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
- return events[event];
- sprintf(buf, "Event %d", event); /* safe */
- return buf;
-}
-
-#ifdef HAVE_PRI
-static char *dialplan2str(int dialplan)
-{
- if (dialplan == -1) {
- return("Dynamically set dialplan in ISDN");
- }
- return (pri_plan2str(dialplan));
-}
-#endif
-
-static char *zap_sig2str(int sig)
-{
- static char buf[256];
- switch (sig) {
- case SIG_EM:
- return "E & M Immediate";
- case SIG_EMWINK:
- return "E & M Wink";
- case SIG_EM_E1:
- return "E & M E1";
- case SIG_FEATD:
- return "Feature Group D (DTMF)";
- case SIG_FEATDMF:
- return "Feature Group D (MF)";
- case SIG_FEATDMF_TA:
- return "Feature Groud D (MF) Tandem Access";
- case SIG_FEATB:
- return "Feature Group B (MF)";
- case SIG_E911:
- return "E911 (MF)";
- case SIG_FGC_CAMA:
- return "FGC/CAMA (Dialpulse)";
- case SIG_FGC_CAMAMF:
- return "FGC/CAMA (MF)";
- case SIG_FXSLS:
- return "FXS Loopstart";
- case SIG_FXSGS:
- return "FXS Groundstart";
- case SIG_FXSKS:
- return "FXS Kewlstart";
- case SIG_FXOLS:
- return "FXO Loopstart";
- case SIG_FXOGS:
- return "FXO Groundstart";
- case SIG_FXOKS:
- return "FXO Kewlstart";
- case SIG_PRI:
- return "ISDN PRI";
- case SIG_SF:
- return "SF (Tone) Immediate";
- case SIG_SFWINK:
- return "SF (Tone) Wink";
- case SIG_SF_FEATD:
- return "SF (Tone) with Feature Group D (DTMF)";
- case SIG_SF_FEATDMF:
- return "SF (Tone) with Feature Group D (MF)";
- case SIG_SF_FEATB:
- return "SF (Tone) with Feature Group B (MF)";
- case SIG_GR303FXOKS:
- return "GR-303 with FXOKS";
- case SIG_GR303FXSKS:
- return "GR-303 with FXSKS";
- case 0:
- return "Pseudo";
- default:
- snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
- return buf;
- }
-}
-
-#define sig2str zap_sig2str
-
-static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
-{
- /* If the conference already exists, and we're already in it
- don't bother doing anything */
- ZT_CONFINFO zi;
-
- memset(&zi, 0, sizeof(zi));
- zi.chan = 0;
-
- if (slavechannel > 0) {
- /* If we have only one slave, do a digital mon */
- zi.confmode = ZT_CONF_DIGITALMON;
- zi.confno = slavechannel;
- } else {
- if (!index) {
- /* Real-side and pseudo-side both participate in conference */
- zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
- ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
- } else
- zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
- zi.confno = p->confno;
- }
- if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
- return 0;
- if (c->zfd < 0)
- return 0;
- if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
- ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
- return -1;
- }
- if (slavechannel < 1) {
- p->confno = zi.confno;
- }
- memcpy(&c->curconf, &zi, sizeof(c->curconf));
- ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
- return 0;
-}
-
-static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
-{
- /* If they're listening to our channel, they're ours */
- if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
- return 1;
- /* If they're a talker on our (allocated) conference, they're ours */
- if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
- return 1;
- return 0;
-}
-
-static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
-{
- ZT_CONFINFO zi;
- if (/* Can't delete if there's no zfd */
- (c->zfd < 0) ||
- /* Don't delete from the conference if it's not our conference */
- !isourconf(p, c)
- /* Don't delete if we don't think it's conferenced at all (implied) */
- ) return 0;
- memset(&zi, 0, sizeof(zi));
- zi.chan = 0;
- zi.confno = 0;
- zi.confmode = 0;
- if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
- ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
- return -1;
- }
- ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
- memcpy(&c->curconf, &zi, sizeof(c->curconf));
- return 0;
-}
-
-static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
-{
- int x;
- int useslavenative;
- struct zt_pvt *slave = NULL;
- /* Start out optimistic */
- useslavenative = 1;
- /* Update conference state in a stateless fashion */
- for (x = 0; x < 3; x++) {
- /* Any three-way calling makes slave native mode *definitely* out
- of the question */
- if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
- useslavenative = 0;
- }
- /* If we don't have any 3-way calls, check to see if we have
- precisely one slave */
- if (useslavenative) {
- for (x = 0; x < MAX_SLAVES; x++) {
- if (p->slaves[x]) {
- if (slave) {
- /* Whoops already have a slave! No
- slave native and stop right away */
- slave = NULL;
- useslavenative = 0;
- break;
- } else {
- /* We have one slave so far */
- slave = p->slaves[x];
- }
- }
- }
- }
- /* If no slave, slave native definitely out */
- if (!slave)
- useslavenative = 0;
- else if (slave->law != p->law) {
- useslavenative = 0;
- slave = NULL;
- }
- if (out)
- *out = slave;
- return useslavenative;
-}
-
-static int reset_conf(struct zt_pvt *p)
-{
- ZT_CONFINFO zi;
- memset(&zi, 0, sizeof(zi));
- p->confno = -1;
- memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
- if (p->subs[SUB_REAL].zfd > -1) {
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
- ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
- }
- return 0;
-}
-
-static int update_conf(struct zt_pvt *p)
-{
- int needconf = 0;
- int x;
- int useslavenative;
- struct zt_pvt *slave = NULL;
-
- useslavenative = isslavenative(p, &slave);
- /* Start with the obvious, general stuff */
- for (x = 0; x < 3; x++) {
- /* Look for three way calls */
- if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
- conf_add(p, &p->subs[x], x, 0);
- needconf++;
- } else {
- conf_del(p, &p->subs[x], x);
- }
- }
- /* If we have a slave, add him to our conference now. or DAX
- if this is slave native */
- for (x = 0; x < MAX_SLAVES; x++) {
- if (p->slaves[x]) {
- if (useslavenative)
- conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
- else {
- conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
- needconf++;
- }
- }
- }
- /* If we're supposed to be in there, do so now */
- if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
- if (useslavenative)
- conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
- else {
- conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
- needconf++;
- }
- }
- /* If we have a master, add ourselves to his conference */
- if (p->master) {
- if (isslavenative(p->master, NULL)) {
- conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
- } else {
- conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
- }
- }
- if (!needconf) {
- /* Nobody is left (or should be left) in our conference.
- Kill it. */
- p->confno = -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
- return 0;
-}
-
-static void zt_enable_ec(struct zt_pvt *p)
-{
- int x;
- int res;
- if (!p)
- return;
- if (p->echocanon) {
- ast_log(LOG_DEBUG, "Echo cancellation already on\n");
- return;
- }
- if (p->digital) {
- ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
- return;
- }
- if (p->echocancel) {
- if (p->sig == SIG_PRI) {
- x = 1;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
- if (res)
- ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
- }
- x = p->echocancel;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
- if (res)
- ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
- else {
- p->echocanon = 1;
- if (option_debug)
- ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
- }
- } else if (option_debug)
- ast_log(LOG_DEBUG, "No echo cancellation requested\n");
-}
-
-static void zt_train_ec(struct zt_pvt *p)
-{
- int x;
- int res;
- if (p && p->echocancel && p->echotraining) {
- x = p->echotraining;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
- if (res)
- ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
- else {
- ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
- }
- } else
- ast_log(LOG_DEBUG, "No echo training requested\n");
-}
-
-static void zt_disable_ec(struct zt_pvt *p)
-{
- int x;
- int res;
- if (p->echocancel) {
- x = 0;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
- if (res)
- ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
- else if (option_debug)
- ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
- }
- p->echocanon = 0;
-}
-
-static void fill_txgain(struct zt_gains *g, float gain, int law)
-{
- int j;
- int k;
- float linear_gain = pow(10.0, gain / 20.0);
-
- switch (law) {
- case ZT_LAW_ALAW:
- for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
- if (gain) {
- k = (int) (((float) AST_ALAW(j)) * linear_gain);
- if (k > 32767) k = 32767;
- if (k < -32767) k = -32767;
- g->txgain[j] = AST_LIN2A(k);
- } else {
- g->txgain[j] = j;
- }
- }
- break;
- case ZT_LAW_MULAW:
- for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
- if (gain) {
- k = (int) (((float) AST_MULAW(j)) * linear_gain);
- if (k > 32767) k = 32767;
- if (k < -32767) k = -32767;
- g->txgain[j] = AST_LIN2MU(k);
- } else {
- g->txgain[j] = j;
- }
- }
- break;
- }
-}
-
-static void fill_rxgain(struct zt_gains *g, float gain, int law)
-{
- int j;
- int k;
- float linear_gain = pow(10.0, gain / 20.0);
-
- switch (law) {
- case ZT_LAW_ALAW:
- for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
- if (gain) {
- k = (int) (((float) AST_ALAW(j)) * linear_gain);
- if (k > 32767) k = 32767;
- if (k < -32767) k = -32767;
- g->rxgain[j] = AST_LIN2A(k);
- } else {
- g->rxgain[j] = j;
- }
- }
- break;
- case ZT_LAW_MULAW:
- for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
- if (gain) {
- k = (int) (((float) AST_MULAW(j)) * linear_gain);
- if (k > 32767) k = 32767;
- if (k < -32767) k = -32767;
- g->rxgain[j] = AST_LIN2MU(k);
- } else {
- g->rxgain[j] = j;
- }
- }
- break;
- }
-}
-
-static int set_actual_txgain(int fd, int chan, float gain, int law)
-{
- struct zt_gains g;
- int res;
-
- memset(&g, 0, sizeof(g));
- g.chan = chan;
- res = ioctl(fd, ZT_GETGAINS, &g);
- if (res) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
- return res;
- }
-
- fill_txgain(&g, gain, law);
-
- return ioctl(fd, ZT_SETGAINS, &g);
-}
-
-static int set_actual_rxgain(int fd, int chan, float gain, int law)
-{
- struct zt_gains g;
- int res;
-
- memset(&g, 0, sizeof(g));
- g.chan = chan;
- res = ioctl(fd, ZT_GETGAINS, &g);
- if (res) {
- ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
- return res;
- }
-
- fill_rxgain(&g, gain, law);
-
- return ioctl(fd, ZT_SETGAINS, &g);
-}
-
-static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
-{
- return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
-}
-
-static int bump_gains(struct zt_pvt *p)
-{
- int res;
-
- /* Bump receive gain by 5.0db */
- res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
- if (res) {
- ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int restore_gains(struct zt_pvt *p)
-{
- int res;
-
- res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
- if (res) {
- ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static inline int zt_set_hook(int fd, int hs)
-{
- int x, res;
-
- x = hs;
- res = ioctl(fd, ZT_HOOK, &x);
-
- if (res < 0) {
- if (errno == EINPROGRESS)
- return 0;
- ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
- }
-
- return res;
-}
-
-static inline int zt_confmute(struct zt_pvt *p, int muted)
-{
- int x, y, res;
- x = muted;
- if (p->sig == SIG_PRI) {
- y = 1;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
- if (res)
- ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
- }
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
- if (res < 0)
- ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
- return res;
-}
-
-static int save_conference(struct zt_pvt *p)
-{
- struct zt_confinfo c;
- int res;
- if (p->saveconf.confmode) {
- ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
- return -1;
- }
- p->saveconf.chan = 0;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
- if (res) {
- ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
- p->saveconf.confmode = 0;
- return -1;
- }
- c.chan = 0;
- c.confno = 0;
- c.confmode = ZT_CONF_NORMAL;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
- if (res) {
- ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Disabled conferencing\n");
- return 0;
-}
-
-static int restore_conference(struct zt_pvt *p)
-{
- int res;
- if (p->saveconf.confmode) {
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
- p->saveconf.confmode = 0;
- if (res) {
- ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
- return -1;
- }
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Restored conferencing\n");
- return 0;
-}
-
-static int send_callerid(struct zt_pvt *p);
-
-static int send_cwcidspill(struct zt_pvt *p)
-{
- p->callwaitcas = 0;
- p->cidcwexpire = 0;
- if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
- return -1;
- p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
- /* Make sure we account for the end */
- p->cidlen += READ_SIZE * 4;
- p->cidpos = 0;
- send_callerid(p);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
- return 0;
-}
-
-static int has_voicemail(struct zt_pvt *p)
-{
-
- return ast_app_has_voicemail(p->mailbox, NULL);
-}
-
-static int send_callerid(struct zt_pvt *p)
-{
- /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
- int res;
- /* Take out of linear mode if necessary */
- if (p->subs[SUB_REAL].linear) {
- p->subs[SUB_REAL].linear = 0;
- zt_setlinear(p->subs[SUB_REAL].zfd, 0);
- }
- while (p->cidpos < p->cidlen) {
- res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
- if (res < 0) {
- if (errno == EAGAIN)
- return 0;
- else {
- ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
- return -1;
- }
- }
- if (!res)
- return 0;
- p->cidpos += res;
- }
- free(p->cidspill);
- p->cidspill = NULL;
- if (p->callwaitcas) {
- /* Wait for CID/CW to expire */
- p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
- } else
- restore_conference(p);
- return 0;
-}
-
-static int zt_callwait(struct ast_channel *ast)
-{
- struct zt_pvt *p = ast->tech_pvt;
- p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
- if (p->cidspill) {
- ast_log(LOG_WARNING, "Spill already exists?!?\n");
- free(p->cidspill);
- }
- if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
- return -1;
- save_conference(p);
- /* Silence */
- memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
- if (!p->callwaitrings && p->callwaitingcallerid) {
- ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
- p->callwaitcas = 1;
- p->cidlen = 2400 + 680 + READ_SIZE * 4;
- } else {
- ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
- p->callwaitcas = 0;
- p->cidlen = 2400 + READ_SIZE * 4;
- }
- p->cidpos = 0;
- send_callerid(p);
-
- return 0;
-}
-
-static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
-{
- struct zt_pvt *p = ast->tech_pvt;
- int x, res, index,mysig;
- char *c, *n, *l;
-#ifdef HAVE_PRI
- char *s = NULL;
-#endif
- char dest[256]; /* must be same length as p->dialdest */
- ast_mutex_lock(&p->lock);
- ast_copy_string(dest, rdest, sizeof(dest));
- ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
- if ((ast->_state == AST_STATE_BUSY)) {
- p->subs[SUB_REAL].needbusy = 1;
- ast_mutex_unlock(&p->lock);
- return 0;
- }
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- p->dialednone = 0;
- if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
- {
- /* Special pseudo -- automatically up */
- ast_setstate(ast, AST_STATE_UP);
- ast_mutex_unlock(&p->lock);
- return 0;
- }
- x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
- if (res)
- ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
- p->outgoing = 1;
-
- set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
-
- mysig = p->sig;
- if (p->outsigmod > -1)
- mysig = p->outsigmod;
-
- switch (mysig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- if (p->owner == ast) {
- /* Normal ring, on hook */
-
- /* Don't send audio while on hook, until the call is answered */
- p->dialing = 1;
- if (p->use_callerid) {
- /* Generate the Caller-ID spill if desired */
- if (p->cidspill) {
- ast_log(LOG_WARNING, "cidspill already exists??\n");
- free(p->cidspill);
- }
- p->callwaitcas = 0;
- if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
- p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
- p->cidpos = 0;
- send_callerid(p);
- }
- }
- /* Choose proper cadence */
- if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
- ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
- p->cidrings = cidrings[p->distinctivering - 1];
- } else {
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
- ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
- p->cidrings = p->sendcalleridafter;
- }
-
- /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
- c = strchr(dest, '/');
- if (c)
- c++;
- if (c && (strlen(c) < p->stripmsd)) {
- ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
- c = NULL;
- }
- if (c) {
- p->dop.op = ZT_DIAL_OP_REPLACE;
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
- ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
- } else {
- p->dop.dialstr[0] = '\0';
- }
- x = ZT_RING;
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
- ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- p->dialing = 1;
- } else {
- /* Call waiting call */
- p->callwaitrings = 0;
- if (ast->cid.cid_num)
- ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
- else
- p->callwait_num[0] = '\0';
- if (ast->cid.cid_name)
- ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
- else
- p->callwait_name[0] = '\0';
- /* Call waiting tone instead */
- if (zt_callwait(ast)) {
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- /* Make ring-back */
- if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
- ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
-
- }
- n = ast->cid.cid_name;
- l = ast->cid.cid_num;
- if (l)
- ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
- else
- p->lastcid_num[0] = '\0';
- if (n)
- ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
- else
- p->lastcid_name[0] = '\0';
- ast_setstate(ast, AST_STATE_RINGING);
- index = zt_get_index(ast, p, 0);
- if (index > -1) {
- p->subs[index].needringing = 1;
- }
- break;
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
- case SIG_EMWINK:
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_FEATD:
- case SIG_FEATDMF:
- case SIG_E911:
- case SIG_FGC_CAMA:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_SFWINK:
- case SIG_SF:
- case SIG_SF_FEATD:
- case SIG_SF_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_SF_FEATB:
- c = strchr(dest, '/');
- if (c)
- c++;
- else
- c = "";
- if (strlen(c) < p->stripmsd) {
- ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
-#ifdef HAVE_PRI
- /* Start the trunk, if not GR-303 */
- if (!p->pri) {
-#endif
- x = ZT_START;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
- if (res < 0) {
- if (errno != EINPROGRESS) {
- ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- }
-#ifdef HAVE_PRI
- }
-#endif
- ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
- p->dop.op = ZT_DIAL_OP_REPLACE;
-
- c += p->stripmsd;
-
- switch (mysig) {
- case SIG_FEATD:
- l = ast->cid.cid_num;
- if (l)
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
- else
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
- break;
- case SIG_FEATDMF:
- l = ast->cid.cid_num;
- if (l)
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
- else
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
- break;
- case SIG_FEATDMF_TA:
- {
- const char *cic, *ozz;
-
- /* If you have to go through a Tandem Access point you need to use this */
- ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
- if (!ozz)
- ozz = defaultozz;
- cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
- if (!cic)
- cic = defaultcic;
- if (!ozz || !cic) {
- ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
- snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
- p->whichwink = 0;
- }
- break;
- case SIG_E911:
- ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
- break;
- case SIG_FGC_CAMA:
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
- break;
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
- break;
- default:
- if (p->pulse)
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
- else
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
- break;
- }
-
- if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
- memset(p->echorest, 'w', sizeof(p->echorest) - 1);
- strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
- p->echorest[sizeof(p->echorest) - 1] = '\0';
- p->echobreak = 1;
- p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
- } else
- p->echobreak = 0;
- if (!res) {
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
- x = ZT_ONHOOK;
- ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
- ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- } else
- ast_log(LOG_DEBUG, "Deferring dialing...\n");
- p->dialing = 1;
- if (ast_strlen_zero(c))
- p->dialednone = 1;
- ast_setstate(ast, AST_STATE_DIALING);
- break;
- case 0:
- /* Special pseudo -- automatically up*/
- ast_setstate(ast, AST_STATE_UP);
- break;
- case SIG_PRI:
- /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
- p->dialdest[0] = '\0';
- break;
- default:
- ast_log(LOG_DEBUG, "not yet implemented\n");
- ast_mutex_unlock(&p->lock);
- return -1;
- }
-#ifdef HAVE_PRI
- if (p->pri) {
- struct pri_sr *sr;
-#ifdef SUPPORT_USERUSER
- const char *useruser;
-#endif
- int pridialplan;
- int dp_strip;
- int prilocaldialplan;
- int ldp_strip;
- int exclusive;
- const char *rr_str;
- int redirect_reason;
-
- c = strchr(dest, '/');
- if (c)
- c++;
- else
- c = dest;
-
- l = NULL;
- n = NULL;
-
- if (!p->hidecallerid) {
- l = ast->cid.cid_num;
- if (!p->hidecalleridname) {
- n = ast->cid.cid_name;
- }
- }
-
-
- if (strlen(c) < p->stripmsd) {
- ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- if (mysig != SIG_FXSKS) {
- p->dop.op = ZT_DIAL_OP_REPLACE;
- s = strchr(c + p->stripmsd, 'w');
- if (s) {
- if (strlen(s) > 1)
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
- else
- p->dop.dialstr[0] = '\0';
- *s = '\0';
- } else {
- p->dop.dialstr[0] = '\0';
- }
- }
- if (pri_grab(p, p->pri)) {
- ast_log(LOG_WARNING, "Failed to grab PRI!\n");
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- if (!(p->call = pri_new_call(p->pri->pri))) {
- ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
- pri_rel(p->pri);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- if (!(sr = pri_sr_new())) {
- ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
- pri_rel(p->pri);
- ast_mutex_unlock(&p->lock);
- }
- if (p->bearer || (mysig == SIG_FXSKS)) {
- if (p->bearer) {
- ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
- p->bearer->call = p->call;
- } else
- ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
- pri_set_crv(p->pri->pri, p->call, p->channel, 0);
- }
- p->digital = IS_DIGITAL(ast->transfercapability);
- /* Add support for exclusive override */
- if (p->priexclusive)
- exclusive = 1;
- else {
- /* otherwise, traditional behavior */
- if (p->pri->nodetype == PRI_NETWORK)
- exclusive = 0;
- else
- exclusive = 1;
- }
-
- pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
- pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
- (p->digital ? -1 :
- ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
- if (p->pri->facilityenable)
- pri_facility_enable(p->pri->pri);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
- dp_strip = 0;
- pridialplan = p->pri->dialplan - 1;
- if (pridialplan == -2) { /* compute dynamically */
- if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
- dp_strip = strlen(p->pri->internationalprefix);
- pridialplan = PRI_INTERNATIONAL_ISDN;
- } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
- dp_strip = strlen(p->pri->nationalprefix);
- pridialplan = PRI_NATIONAL_ISDN;
- } else {
- pridialplan = PRI_LOCAL_ISDN;
- }
- }
- pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
-
- ldp_strip = 0;
- prilocaldialplan = p->pri->localdialplan - 1;
- if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
- if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
- ldp_strip = strlen(p->pri->internationalprefix);
- prilocaldialplan = PRI_INTERNATIONAL_ISDN;
- } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
- ldp_strip = strlen(p->pri->nationalprefix);
- prilocaldialplan = PRI_NATIONAL_ISDN;
- } else {
- prilocaldialplan = PRI_LOCAL_ISDN;
- }
- }
- pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
- p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
- if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
- if (!strcasecmp(rr_str, "UNKNOWN"))
- redirect_reason = 0;
- else if (!strcasecmp(rr_str, "BUSY"))
- redirect_reason = 1;
- else if (!strcasecmp(rr_str, "NO_REPLY"))
- redirect_reason = 2;
- else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
- redirect_reason = 15;
- else
- redirect_reason = PRI_REDIR_UNCONDITIONAL;
- } else
- redirect_reason = PRI_REDIR_UNCONDITIONAL;
- pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
-
-#ifdef SUPPORT_USERUSER
- /* User-user info */
- useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
-
- if (useruser)
- pri_sr_set_useruser(sr, useruser);
-#endif
-
- if (pri_setup(p->pri->pri, p->call, sr)) {
- ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
- c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
- pri_rel(p->pri);
- ast_mutex_unlock(&p->lock);
- pri_sr_free(sr);
- return -1;
- }
- pri_sr_free(sr);
- ast_setstate(ast, AST_STATE_DIALING);
- pri_rel(p->pri);
- }
-#endif
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static void destroy_zt_pvt(struct zt_pvt **pvt)
-{
- struct zt_pvt *p = *pvt;
- /* Remove channel from the list */
- if (p->prev)
- p->prev->next = p->next;
- if (p->next)
- p->next->prev = p->prev;
- if (p->use_smdi)
- ast_smdi_interface_unref(p->smdi_iface);
- ast_mutex_destroy(&p->lock);
- free(p);
- *pvt = NULL;
-}
-
-static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
-{
- int owned = 0;
- int i = 0;
-
- if (!now) {
- if (cur->owner) {
- owned = 1;
- }
-
- for (i = 0; i < 3; i++) {
- if (cur->subs[i].owner) {
- owned = 1;
- }
- }
- if (!owned) {
- if (prev) {
- prev->next = cur->next;
- if (prev->next)
- prev->next->prev = prev;
- else
- ifend = prev;
- } else {
- iflist = cur->next;
- if (iflist)
- iflist->prev = NULL;
- else
- ifend = NULL;
- }
- if (cur->subs[SUB_REAL].zfd > -1) {
- zt_close(cur->subs[SUB_REAL].zfd);
- }
- destroy_zt_pvt(&cur);
- }
- } else {
- if (prev) {
- prev->next = cur->next;
- if (prev->next)
- prev->next->prev = prev;
- else
- ifend = prev;
- } else {
- iflist = cur->next;
- if (iflist)
- iflist->prev = NULL;
- else
- ifend = NULL;
- }
- if (cur->subs[SUB_REAL].zfd > -1) {
- zt_close(cur->subs[SUB_REAL].zfd);
- }
- destroy_zt_pvt(&cur);
- }
- return 0;
-}
-
-#ifdef HAVE_PRI
-static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
-
-static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
-
-static char *zap_send_keypad_facility_descrip =
-" ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
-" IE over the current channel.\n";
-
-static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
-{
- /* Data will be our digit string */
- struct zt_pvt *p;
- char *digits = (char *) data;
-
- if (ast_strlen_zero(digits)) {
- ast_log(LOG_DEBUG, "No digit string sent to application!\n");
- return -1;
- }
-
- p = (struct zt_pvt *)chan->tech_pvt;
-
- if (!p) {
- ast_log(LOG_DEBUG, "Unable to find technology private\n");
- return -1;
- }
-
- ast_mutex_lock(&p->lock);
-
- if (!p->pri || !p->call) {
- ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
- ast_mutex_unlock(&p->lock);
- return -1;
- }
-
- if (!pri_grab(p, p->pri)) {
- pri_keypad_facility(p->pri->pri, p->call, digits);
- pri_rel(p->pri);
- } else {
- ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
- ast_mutex_unlock(&p->lock);
- return -1;
- }
-
- ast_mutex_unlock(&p->lock);
-
- return 0;
-}
-
-static int pri_is_up(struct zt_pri *pri)
-{
- int x;
- for (x = 0; x < NUM_DCHANS; x++) {
- if (pri->dchanavail[x] == DCHAN_AVAILABLE)
- return 1;
- }
- return 0;
-}
-
-static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
-{
- bearer->owner = &inuse;
- bearer->realcall = crv;
- crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
- if (crv->subs[SUB_REAL].owner)
- crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
- crv->bearer = bearer;
- crv->call = bearer->call;
- crv->pri = pri;
- return 0;
-}
-
-static char *pri_order(int level)
-{
- switch (level) {
- case 0:
- return "Primary";
- case 1:
- return "Secondary";
- case 2:
- return "Tertiary";
- case 3:
- return "Quaternary";
- default:
- return "<Unknown>";
- }
-}
-
-/* Returns fd of the active dchan */
-static int pri_active_dchan_fd(struct zt_pri *pri)
-{
- int x = -1;
-
- for (x = 0; x < NUM_DCHANS; x++) {
- if ((pri->dchans[x] == pri->pri))
- break;
- }
-
- return pri->fds[x];
-}
-
-static int pri_find_dchan(struct zt_pri *pri)
-{
- int oldslot = -1;
- struct pri *old;
- int newslot = -1;
- int x;
- old = pri->pri;
- for (x = 0; x < NUM_DCHANS; x++) {
- if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
- newslot = x;
- if (pri->dchans[x] == old) {
- oldslot = x;
- }
- }
- if (newslot < 0) {
- newslot = 0;
- ast_log(LOG_WARNING, "No D-channels available! Using Primary channel %d as D-channel anyway!\n",
- pri->dchannels[newslot]);
- }
- if (old && (oldslot != newslot))
- ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
- pri->dchannels[oldslot], pri->dchannels[newslot]);
- pri->pri = pri->dchans[newslot];
- return 0;
-}
-#endif
-
-static int zt_hangup(struct ast_channel *ast)
-{
- int res;
- int index,x, law;
- /*static int restore_gains(struct zt_pvt *p);*/
- struct zt_pvt *p = ast->tech_pvt;
- struct zt_pvt *tmp = NULL;
- struct zt_pvt *prev = NULL;
- ZT_PARAMS par;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
- if (!ast->tech_pvt) {
- ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
- return 0;
- }
-
- ast_mutex_lock(&p->lock);
-
- index = zt_get_index(ast, p, 1);
-
- if (p->sig == SIG_PRI) {
- x = 1;
- ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
- }
-
- x = 0;
- zt_confmute(p, 0);
- restore_gains(p);
- if (p->origcid_num) {
- ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
- free(p->origcid_num);
- p->origcid_num = NULL;
- }
- if (p->origcid_name) {
- ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
- free(p->origcid_name);
- p->origcid_name = NULL;
- }
- if (p->dsp)
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
- if (p->exten)
- p->exten[0] = '\0';
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
- p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
- p->ignoredtmf = 0;
-
- if (index > -1) {
- /* Real channel, do some fixup */
- p->subs[index].owner = NULL;
- p->subs[index].needanswer = 0;
- p->subs[index].needflash = 0;
- p->subs[index].needringing = 0;
- p->subs[index].needbusy = 0;
- p->subs[index].needcongestion = 0;
- p->subs[index].linear = 0;
- p->subs[index].needcallerid = 0;
- p->polarity = POLARITY_IDLE;
- zt_setlinear(p->subs[index].zfd, 0);
- if (index == SUB_REAL) {
- if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
- ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
- if (p->subs[SUB_CALLWAIT].inthreeway) {
- /* We had flipped over to answer a callwait and now it's gone */
- ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
- /* Move to the call-wait, but un-own us until they flip back. */
- swap_subs(p, SUB_CALLWAIT, SUB_REAL);
- unalloc_sub(p, SUB_CALLWAIT);
- p->owner = NULL;
- } else {
- /* The three way hung up, but we still have a call wait */
- ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- unalloc_sub(p, SUB_THREEWAY);
- if (p->subs[SUB_REAL].inthreeway) {
- /* This was part of a three way call. Immediately make way for
- another call */
- ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
- p->owner = p->subs[SUB_REAL].owner;
- } else {
- /* This call hasn't been completed yet... Set owner to NULL */
- ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
- p->owner = NULL;
- }
- p->subs[SUB_REAL].inthreeway = 0;
- }
- } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
- /* Move to the call-wait and switch back to them. */
- swap_subs(p, SUB_CALLWAIT, SUB_REAL);
- unalloc_sub(p, SUB_CALLWAIT);
- p->owner = p->subs[SUB_REAL].owner;
- if (p->owner->_state != AST_STATE_UP)
- p->subs[SUB_REAL].needanswer = 1;
- if (ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
- } else if (p->subs[SUB_THREEWAY].zfd > -1) {
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- unalloc_sub(p, SUB_THREEWAY);
- if (p->subs[SUB_REAL].inthreeway) {
- /* This was part of a three way call. Immediately make way for
- another call */
- ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
- p->owner = p->subs[SUB_REAL].owner;
- } else {
- /* This call hasn't been completed yet... Set owner to NULL */
- ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
- p->owner = NULL;
- }
- p->subs[SUB_REAL].inthreeway = 0;
- }
- } else if (index == SUB_CALLWAIT) {
- /* Ditch the holding callwait call, and immediately make it availabe */
- if (p->subs[SUB_CALLWAIT].inthreeway) {
- /* This is actually part of a three way, placed on hold. Place the third part
- on music on hold now */
- if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
- S_OR(p->mohsuggest, NULL),
- !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- }
- p->subs[SUB_THREEWAY].inthreeway = 0;
- /* Make it the call wait now */
- swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
- unalloc_sub(p, SUB_THREEWAY);
- } else
- unalloc_sub(p, SUB_CALLWAIT);
- } else if (index == SUB_THREEWAY) {
- if (p->subs[SUB_CALLWAIT].inthreeway) {
- /* The other party of the three way call is currently in a call-wait state.
- Start music on hold for them, and take the main guy out of the third call */
- if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
- ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
- S_OR(p->mohsuggest, NULL),
- !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- }
- p->subs[SUB_CALLWAIT].inthreeway = 0;
- }
- p->subs[SUB_REAL].inthreeway = 0;
- /* If this was part of a three way call index, let us make
- another three way call */
- unalloc_sub(p, SUB_THREEWAY);
- } else {
- /* This wasn't any sort of call, but how are we an index? */
- ast_log(LOG_WARNING, "Index found but not any type of call?\n");
- }
- }
-
- if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
- p->owner = NULL;
- p->ringt = 0;
- p->distinctivering = 0;
- p->confirmanswer = 0;
- p->cidrings = 1;
- p->outgoing = 0;
- p->digital = 0;
- p->faxhandled = 0;
- p->pulsedial = 0;
- p->onhooktime = time(NULL);
-#ifdef HAVE_PRI
- p->proceeding = 0;
- p->progress = 0;
- p->alerting = 0;
- p->setup_ack = 0;
-#endif
- if (p->dsp) {
- ast_dsp_free(p->dsp);
- p->dsp = NULL;
- }
-
- law = ZT_LAW_DEFAULT;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
- /* Perform low level hangup if no owner left */
-#ifdef HAVE_PRI
- if (p->pri) {
-#ifdef SUPPORT_USERUSER
- const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
-#endif
-
- /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
- if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
- if (!pri_grab(p, p->pri)) {
- if (p->alreadyhungup) {
- ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n");
-
-#ifdef SUPPORT_USERUSER
- pri_call_set_useruser(p->call, useruser);
-#endif
-
- pri_hangup(p->pri->pri, p->call, -1);
- p->call = NULL;
- if (p->bearer)
- p->bearer->call = NULL;
- } else {
- const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
- int icause = ast->hangupcause ? ast->hangupcause : -1;
- ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n");
-
-#ifdef SUPPORT_USERUSER
- pri_call_set_useruser(p->call, useruser);
-#endif
-
- p->alreadyhungup = 1;
- if (p->bearer)
- p->bearer->alreadyhungup = 1;
- if (cause) {
- if (atoi(cause))
- icause = atoi(cause);
- }
- pri_hangup(p->pri->pri, p->call, icause);
- }
- if (res < 0)
- ast_log(LOG_WARNING, "pri_disconnect failed\n");
- pri_rel(p->pri);
- } else {
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- res = -1;
- }
- } else {
- if (p->bearer)
- ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
- p->call = NULL;
- res = 0;
- }
- }
-#endif
- if (p->sig && (p->sig != SIG_PRI))
- res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
- }
- switch (p->sig) {
- case SIG_FXOGS:
- case SIG_FXOLS:
- case SIG_FXOKS:
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
- if (!res) {
-#if 0
- ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
-#endif
- /* If they're off hook, try playing congestion */
- if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
- tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
- else
- tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
- }
- break;
- case SIG_FXSGS:
- case SIG_FXSLS:
- case SIG_FXSKS:
- /* Make sure we're not made available for at least two seconds assuming
- we were actually used for an inbound or outbound call. */
- if (ast->_state != AST_STATE_RESERVED) {
- time(&p->guardtime);
- p->guardtime += 2;
- }
- break;
- default:
- tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
- }
- if (p->cidspill)
- free(p->cidspill);
- if (p->sig)
- zt_disable_ec(p);
- x = 0;
- ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
- ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
- p->didtdd = 0;
- p->cidspill = NULL;
- p->callwaitcas = 0;
- p->callwaiting = p->permcallwaiting;
- p->hidecallerid = p->permhidecallerid;
- p->dialing = 0;
- p->rdnis[0] = '\0';
- update_conf(p);
- reset_conf(p);
- /* Restore data mode */
- if (p->sig == SIG_PRI) {
- x = 0;
- ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
- }
-#ifdef HAVE_PRI
- if (p->bearer) {
- ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
- /* Free up the bearer channel as well, and
- don't use its file descriptor anymore */
- update_conf(p->bearer);
- reset_conf(p->bearer);
- p->bearer->owner = NULL;
- p->bearer->realcall = NULL;
- p->bearer = NULL;
- p->subs[SUB_REAL].zfd = -1;
- p->pri = NULL;
- }
-#endif
- restart_monitor();
- }
-
- p->callwaitingrepeat = 0;
- p->cidcwexpire = 0;
- p->oprmode = 0;
- ast->tech_pvt = NULL;
- ast_mutex_unlock(&p->lock);
- ast_module_unref(ast_module_info->self);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
-
- ast_mutex_lock(&iflock);
- tmp = iflist;
- prev = NULL;
- if (p->destroy) {
- while (tmp) {
- if (tmp == p) {
- destroy_channel(prev, tmp, 0);
- break;
- } else {
- prev = tmp;
- tmp = tmp->next;
- }
- }
- }
- ast_mutex_unlock(&iflock);
- return 0;
-}
-
-static int zt_answer(struct ast_channel *ast)
-{
- struct zt_pvt *p = ast->tech_pvt;
- int res = 0;
- int index;
- int oldstate = ast->_state;
- ast_setstate(ast, AST_STATE_UP);
- ast_mutex_lock(&p->lock);
- index = zt_get_index(ast, p, 0);
- if (index < 0)
- index = SUB_REAL;
- /* nothing to do if a radio channel */
- if ((p->radio || (p->oprmode < 0))) {
- ast_mutex_unlock(&p->lock);
- return 0;
- }
- switch (p->sig) {
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
- p->ringt = 0;
- /* Fall through */
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_EMWINK:
- case SIG_FEATD:
- case SIG_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_E911:
- case SIG_FGC_CAMA:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_SF:
- case SIG_SFWINK:
- case SIG_SF_FEATD:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- /* Pick up the line */
- ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
- if (p->hanguponpolarityswitch) {
- gettimeofday(&p->polaritydelaytv, NULL);
- }
- res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- tone_zone_play_tone(p->subs[index].zfd, -1);
- p->dialing = 0;
- if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
- if (oldstate == AST_STATE_RINGING) {
- ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
- tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- p->owner = p->subs[SUB_REAL].owner;
- }
- }
- if (p->sig & __ZT_SIG_FXS) {
- zt_enable_ec(p);
- zt_train_ec(p);
- }
- break;
-#ifdef HAVE_PRI
- case SIG_PRI:
- /* Send a pri acknowledge */
- if (!pri_grab(p, p->pri)) {
- p->proceeding = 1;
- res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
- pri_rel(p->pri);
- } else {
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- res = -1;
- }
- break;
-#endif
- case 0:
- ast_mutex_unlock(&p->lock);
- return 0;
- default:
- ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
- res = -1;
- }
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
-{
- char *cp;
- signed char *scp;
- int x;
- int index;
- struct zt_pvt *p = chan->tech_pvt, *pp;
- struct oprmode *oprmode;
-
-
- /* all supported options require data */
- if (!data || (datalen < 1)) {
- errno = EINVAL;
- return -1;
- }
-
- switch (option) {
- case AST_OPTION_TXGAIN:
- scp = (signed char *) data;
- index = zt_get_index(chan, p, 0);
- if (index < 0) {
- ast_log(LOG_WARNING, "No index in TXGAIN?\n");
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
- return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
- case AST_OPTION_RXGAIN:
- scp = (signed char *) data;
- index = zt_get_index(chan, p, 0);
- if (index < 0) {
- ast_log(LOG_WARNING, "No index in RXGAIN?\n");
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
- return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
- case AST_OPTION_TONE_VERIFY:
- if (!p->dsp)
- break;
- cp = (char *) data;
- switch (*cp) {
- case 1:
- ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */
- break;
- case 2:
- ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */
- break;
- default:
- ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */
- break;
- }
- break;
- case AST_OPTION_TDD:
- /* turn on or off TDD */
- cp = (char *) data;
- p->mate = 0;
- if (!*cp) { /* turn it off */
- if (option_debug)
- ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
- if (p->tdd)
- tdd_free(p->tdd);
- p->tdd = 0;
- break;
- }
- ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
- (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
- zt_disable_ec(p);
- /* otherwise, turn it on */
- if (!p->didtdd) { /* if havent done it yet */
- unsigned char mybuf[41000], *buf;
- int size, res, fd, len;
- struct pollfd fds[1];
-
- buf = mybuf;
- memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
- ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */
- len = 40000;
- index = zt_get_index(chan, p, 0);
- if (index < 0) {
- ast_log(LOG_WARNING, "No index in TDD?\n");
- return -1;
- }
- fd = p->subs[index].zfd;
- while (len) {
- if (ast_check_hangup(chan))
- return -1;
- size = len;
- if (size > READ_SIZE)
- size = READ_SIZE;
- fds[0].fd = fd;
- fds[0].events = POLLPRI | POLLOUT;
- fds[0].revents = 0;
- res = poll(fds, 1, -1);
- if (!res) {
- ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
- continue;
- }
- /* if got exception */
- if (fds[0].revents & POLLPRI)
- return -1;
- if (!(fds[0].revents & POLLOUT)) {
- ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
- continue;
- }
- res = write(fd, buf, size);
- if (res != size) {
- if (res == -1) return -1;
- ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
- break;
- }
- len -= size;
- buf += size;
- }
- p->didtdd = 1; /* set to have done it now */
- }
- if (*cp == 2) { /* Mate mode */
- if (p->tdd)
- tdd_free(p->tdd);
- p->tdd = 0;
- p->mate = 1;
- break;
- }
- if (!p->tdd) { /* if we dont have one yet */
- p->tdd = tdd_new(); /* allocate one */
- }
- break;
- case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */
- if (!p->dsp)
- break;
- cp = (char *) data;
- ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
- *cp ? "ON" : "OFF", (int) *cp, chan->name);
- p->dtmfrelax = 0;
- if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
- ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
- break;
- case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */
- cp = (char *) data;
- if (!*cp) {
- ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
- x = 0;
- zt_disable_ec(p);
- } else {
- ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
- x = 1;
- }
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
- ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
- break;
- case AST_OPTION_OPRMODE: /* Operator services mode */
- oprmode = (struct oprmode *) data;
- pp = oprmode->peer->tech_pvt;
- p->oprmode = pp->oprmode = 0;
- /* setup peers */
- p->oprpeer = pp;
- pp->oprpeer = p;
- /* setup modes, if any */
- if (oprmode->mode)
- {
- pp->oprmode = oprmode->mode;
- p->oprmode = -oprmode->mode;
- }
- ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
- oprmode->mode, chan->name,oprmode->peer->name);;
- break;
- case AST_OPTION_ECHOCAN:
- cp = (char *) data;
- if (*cp) {
- ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
- zt_enable_ec(p);
- } else {
- ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
- zt_disable_ec(p);
- }
- break;
- }
- errno = 0;
-
- return 0;
-}
-
-static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
-{
- struct zt_pvt *p = chan->tech_pvt;
-
- if (!strcasecmp(data, "rxgain")) {
- ast_mutex_lock(&p->lock);
- snprintf(buf, len, "%f", p->rxgain);
- ast_mutex_unlock(&p->lock);
- } else if (!strcasecmp(data, "txgain")) {
- ast_mutex_lock(&p->lock);
- snprintf(buf, len, "%f", p->txgain);
- ast_mutex_unlock(&p->lock);
- } else {
- ast_copy_string(buf, "", len);
- }
- return 0;
-}
-
-
-static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
-{
- /* Unlink a specific slave or all slaves/masters from a given master */
- int x;
- int hasslaves;
- if (!master)
- return;
- if (needlock) {
- ast_mutex_lock(&master->lock);
- if (slave) {
- while (ast_mutex_trylock(&slave->lock)) {
- ast_mutex_unlock(&master->lock);
- usleep(1);
- ast_mutex_lock(&master->lock);
- }
- }
- }
- hasslaves = 0;
- for (x = 0; x < MAX_SLAVES; x++) {
- if (master->slaves[x]) {
- if (!slave || (master->slaves[x] == slave)) {
- /* Take slave out of the conference */
- ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
- conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
- conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
- master->slaves[x]->master = NULL;
- master->slaves[x] = NULL;
- } else
- hasslaves = 1;
- }
- if (!hasslaves)
- master->inconference = 0;
- }
- if (!slave) {
- if (master->master) {
- /* Take master out of the conference */
- conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
- conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
- hasslaves = 0;
- for (x = 0; x < MAX_SLAVES; x++) {
- if (master->master->slaves[x] == master)
- master->master->slaves[x] = NULL;
- else if (master->master->slaves[x])
- hasslaves = 1;
- }
- if (!hasslaves)
- master->master->inconference = 0;
- }
- master->master = NULL;
- }
- update_conf(master);
- if (needlock) {
- if (slave)
- ast_mutex_unlock(&slave->lock);
- ast_mutex_unlock(&master->lock);
- }
-}
-
-static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
- int x;
- if (!slave || !master) {
- ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
- return;
- }
- for (x = 0; x < MAX_SLAVES; x++) {
- if (!master->slaves[x]) {
- master->slaves[x] = slave;
- break;
- }
- }
- if (x >= MAX_SLAVES) {
- ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
- master->slaves[MAX_SLAVES - 1] = slave;
- }
- if (slave->master)
- ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
- slave->master = master;
-
- ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
-}
-
-static void disable_dtmf_detect(struct zt_pvt *p)
-{
-#ifdef ZT_TONEDETECT
- int val;
-#endif
-
- p->ignoredtmf = 1;
-
-#ifdef ZT_TONEDETECT
- val = 0;
- ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
-#endif
- if (!p->hardwaredtmf && p->dsp) {
- p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
- ast_dsp_set_features(p->dsp, p->dsp_features);
- }
-}
-
-static void enable_dtmf_detect(struct zt_pvt *p)
-{
-#ifdef ZT_TONEDETECT
- int val;
-#endif
-
- if (p->channel == CHAN_PSEUDO)
- return;
-
- p->ignoredtmf = 0;
-
-#ifdef ZT_TONEDETECT
- val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
- ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
-#endif
- if (!p->hardwaredtmf && p->dsp) {
- p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
- ast_dsp_set_features(p->dsp, p->dsp_features);
- }
-}
-
-static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
-{
- struct ast_channel *who;
- struct zt_pvt *p0, *p1, *op0, *op1;
- struct zt_pvt *master = NULL, *slave = NULL;
- struct ast_frame *f;
- int inconf = 0;
- int nothingok = 1;
- int ofd0, ofd1;
- int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
- int os0 = -1, os1 = -1;
- int priority = 0;
- struct ast_channel *oc0, *oc1;
- enum ast_bridge_result res;
-
-#ifdef PRI_2BCT
- int triedtopribridge = 0;
- q931_call *q931c0 = NULL, *q931c1 = NULL;
-#endif
-
- /* For now, don't attempt to native bridge if either channel needs DTMF detection.
- There is code below to handle it properly until DTMF is actually seen,
- but due to currently unresolved issues it's ignored...
- */
-
- if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
- return AST_BRIDGE_FAILED_NOWARN;
-
- ast_mutex_lock(&c0->lock);
- while (ast_mutex_trylock(&c1->lock)) {
- ast_mutex_unlock(&c0->lock);
- usleep(1);
- ast_mutex_lock(&c0->lock);
- }
-
- p0 = c0->tech_pvt;
- p1 = c1->tech_pvt;
- /* cant do pseudo-channels here */
- if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
- ast_mutex_unlock(&c0->lock);
- ast_mutex_unlock(&c1->lock);
- return AST_BRIDGE_FAILED_NOWARN;
- }
-
- oi0 = zt_get_index(c0, p0, 0);
- oi1 = zt_get_index(c1, p1, 0);
- if ((oi0 < 0) || (oi1 < 0)) {
- ast_mutex_unlock(&c0->lock);
- ast_mutex_unlock(&c1->lock);
- return AST_BRIDGE_FAILED;
- }
-
- op0 = p0 = c0->tech_pvt;
- op1 = p1 = c1->tech_pvt;
- ofd0 = c0->fds[0];
- ofd1 = c1->fds[0];
- oc0 = p0->owner;
- oc1 = p1->owner;
-
- if (ast_mutex_trylock(&p0->lock)) {
- /* Don't block, due to potential for deadlock */
- ast_mutex_unlock(&c0->lock);
- ast_mutex_unlock(&c1->lock);
- ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
- return AST_BRIDGE_RETRY;
- }
- if (ast_mutex_trylock(&p1->lock)) {
- /* Don't block, due to potential for deadlock */
- ast_mutex_unlock(&p0->lock);
- ast_mutex_unlock(&c0->lock);
- ast_mutex_unlock(&c1->lock);
- ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
- return AST_BRIDGE_RETRY;
- }
-
- if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
- if (p0->owner && p1->owner) {
- /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
- if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
- master = p0;
- slave = p1;
- inconf = 1;
- } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
- master = p1;
- slave = p0;
- inconf = 1;
- } else {
- ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n");
- ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
- p0->channel,
- oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
- p0->subs[SUB_REAL].inthreeway, p0->channel,
- oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
- p1->subs[SUB_REAL].inthreeway);
- }
- nothingok = 0;
- }
- } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
- if (p1->subs[SUB_THREEWAY].inthreeway) {
- master = p1;
- slave = p0;
- nothingok = 0;
- }
- } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
- if (p0->subs[SUB_THREEWAY].inthreeway) {
- master = p0;
- slave = p1;
- nothingok = 0;
- }
- } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
- /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise,
- don't put us in anything */
- if (p1->subs[SUB_CALLWAIT].inthreeway) {
- master = p1;
- slave = p0;
- nothingok = 0;
- }
- } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
- /* Same as previous */
- if (p0->subs[SUB_CALLWAIT].inthreeway) {
- master = p0;
- slave = p1;
- nothingok = 0;
- }
- }
- ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
- master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
- if (master && slave) {
- /* Stop any tones, or play ringtone as appropriate. If they're bridged
- in an active threeway call with a channel that is ringing, we should
- indicate ringing. */
- if ((oi1 == SUB_THREEWAY) &&
- p1->subs[SUB_THREEWAY].inthreeway &&
- p1->subs[SUB_REAL].owner &&
- p1->subs[SUB_REAL].inthreeway &&
- (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
- ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
- tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
- os1 = p1->subs[SUB_REAL].owner->_state;
- } else {
- ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
- tone_zone_play_tone(p0->subs[oi0].zfd, -1);
- }
- if ((oi0 == SUB_THREEWAY) &&
- p0->subs[SUB_THREEWAY].inthreeway &&
- p0->subs[SUB_REAL].owner &&
- p0->subs[SUB_REAL].inthreeway &&
- (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
- ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
- tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
- os0 = p0->subs[SUB_REAL].owner->_state;
- } else {
- ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
- tone_zone_play_tone(p1->subs[oi0].zfd, -1);
- }
- if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
- if (!p0->echocanbridged || !p1->echocanbridged) {
- /* Disable echo cancellation if appropriate */
- zt_disable_ec(p0);
- zt_disable_ec(p1);
- }
- }
- zt_link(slave, master);
- master->inconference = inconf;
- } else if (!nothingok)
- ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
-
- update_conf(p0);
- update_conf(p1);
- t0 = p0->subs[SUB_REAL].inthreeway;
- t1 = p1->subs[SUB_REAL].inthreeway;
-
- ast_mutex_unlock(&p0->lock);
- ast_mutex_unlock(&p1->lock);
-
- ast_mutex_unlock(&c0->lock);
- ast_mutex_unlock(&c1->lock);
-
- /* Native bridge failed */
- if ((!master || !slave) && !nothingok) {
- zt_enable_ec(p0);
- zt_enable_ec(p1);
- return AST_BRIDGE_FAILED;
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
-
- if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
- disable_dtmf_detect(op0);
-
- if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
- disable_dtmf_detect(op1);
-
- for (;;) {
- struct ast_channel *c0_priority[2] = {c0, c1};
- struct ast_channel *c1_priority[2] = {c1, c0};
-
- /* Here's our main loop... Start by locking things, looking for private parts,
- and then balking if anything is wrong */
- ast_mutex_lock(&c0->lock);
- while (ast_mutex_trylock(&c1->lock)) {
- ast_mutex_unlock(&c0->lock);
- usleep(1);
- ast_mutex_lock(&c0->lock);
- }
-
- p0 = c0->tech_pvt;
- p1 = c1->tech_pvt;
-
- if (op0 == p0)
- i0 = zt_get_index(c0, p0, 1);
- if (op1 == p1)
- i1 = zt_get_index(c1, p1, 1);
- ast_mutex_unlock(&c0->lock);
- ast_mutex_unlock(&c1->lock);
-
- if (!timeoutms ||
- (op0 != p0) ||
- (op1 != p1) ||
- (ofd0 != c0->fds[0]) ||
- (ofd1 != c1->fds[0]) ||
- (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) ||
- (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) ||
- (oc0 != p0->owner) ||
- (oc1 != p1->owner) ||
- (t0 != p0->subs[SUB_REAL].inthreeway) ||
- (t1 != p1->subs[SUB_REAL].inthreeway) ||
- (oi0 != i0) ||
- (oi1 != i1)) {
- ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
- op0->channel, oi0, op1->channel, oi1);
- res = AST_BRIDGE_RETRY;
- goto return_from_bridge;
- }
-
-#ifdef PRI_2BCT
- q931c0 = p0->call;
- q931c1 = p1->call;
- if (p0->transfer && p1->transfer
- && q931c0 && q931c1
- && !triedtopribridge) {
- pri_channel_bridge(q931c0, q931c1);
- triedtopribridge = 1;
- }
-#endif
-
- who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
- if (!who) {
- ast_log(LOG_DEBUG, "Ooh, empty read...\n");
- continue;
- }
- f = ast_read(who);
- if (!f || (f->frametype == AST_FRAME_CONTROL)) {
- *fo = f;
- *rc = who;
- res = AST_BRIDGE_COMPLETE;
- goto return_from_bridge;
- }
- if (f->frametype == AST_FRAME_DTMF) {
- if ((who == c0) && p0->pulsedial) {
- ast_write(c1, f);
- } else if ((who == c1) && p1->pulsedial) {
- ast_write(c0, f);
- } else {
- *fo = f;
- *rc = who;
- res = AST_BRIDGE_COMPLETE;
- goto return_from_bridge;
- }
- }
- ast_frfree(f);
-
- /* Swap who gets priority */
- priority = !priority;
- }
-
-return_from_bridge:
- if (op0 == p0)
- zt_enable_ec(p0);
-
- if (op1 == p1)
- zt_enable_ec(p1);
-
- if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
- enable_dtmf_detect(op0);
-
- if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
- enable_dtmf_detect(op1);
-
- zt_unlink(slave, master, 1);
-
- return res;
-}
-
-static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
- struct zt_pvt *p = newchan->tech_pvt;
- int x;
- ast_mutex_lock(&p->lock);
- ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
- if (p->owner == oldchan) {
- p->owner = newchan;
- }
- for (x = 0; x < 3; x++)
- if (p->subs[x].owner == oldchan) {
- if (!x)
- zt_unlink(NULL, p, 0);
- p->subs[x].owner = newchan;
- }
- if (newchan->_state == AST_STATE_RINGING)
- zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
- update_conf(p);
- ast_mutex_unlock(&p->lock);
- return 0;
-}
-
-static int zt_ring_phone(struct zt_pvt *p)
-{
- int x;
- int res;
- /* Make sure our transmit state is on hook */
- x = 0;
- x = ZT_ONHOOK;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
- do {
- x = ZT_RING;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
- if (res) {
- switch (errno) {
- case EBUSY:
- case EINTR:
- /* Wait just in case */
- usleep(10000);
- continue;
- case EINPROGRESS:
- res = 0;
- break;
- default:
- ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
- res = 0;
- }
- }
- } while (res);
- return res;
-}
-
-static void *ss_thread(void *data);
-
-static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
-
-static int attempt_transfer(struct zt_pvt *p)
-{
- /* In order to transfer, we need at least one of the channels to
- actually be in a call bridge. We can't conference two applications
- together (but then, why would we want to?) */
- if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
- /* The three-way person we're about to transfer to could still be in MOH, so
- stop if now if appropriate */
- if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
- ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
- if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
- ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
- }
- if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
- tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
- }
- if (p->subs[SUB_REAL].owner->cdr) {
- /* Move CDR from second channel to current one */
- p->subs[SUB_THREEWAY].owner->cdr =
- ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
- p->subs[SUB_REAL].owner->cdr = NULL;
- }
- if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
- /* Move CDR from second channel's bridge to current one */
- p->subs[SUB_THREEWAY].owner->cdr =
- ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
- ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
- }
- if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
- return -1;
- }
- /* Orphan the channel after releasing the lock */
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- unalloc_sub(p, SUB_THREEWAY);
- } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
- if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
- ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
- }
- if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
- tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
- }
- if (p->subs[SUB_THREEWAY].owner->cdr) {
- /* Move CDR from second channel to current one */
- p->subs[SUB_REAL].owner->cdr =
- ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
- p->subs[SUB_THREEWAY].owner->cdr = NULL;
- }
- if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
- /* Move CDR from second channel's bridge to current one */
- p->subs[SUB_REAL].owner->cdr =
- ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
- ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
- }
- if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
- return -1;
- }
- /* Three-way is now the REAL */
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
- unalloc_sub(p, SUB_THREEWAY);
- /* Tell the caller not to hangup */
- return 1;
- } else {
- ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
- p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
- p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
- return -1;
- }
- return 0;
-}
-
-static int check_for_conference(struct zt_pvt *p)
-{
- ZT_CONFINFO ci;
- /* Fine if we already have a master, etc */
- if (p->master || (p->confno > -1))
- return 0;
- memset(&ci, 0, sizeof(ci));
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
- ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
- return 0;
- }
- /* If we have no master and don't have a confno, then
- if we're in a conference, it's probably a MeetMe room or
- some such, so don't let us 3-way out! */
- if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
- return 1;
- }
- return 0;
-}
-
-static int get_alarms(struct zt_pvt *p)
-{
- int res;
- ZT_SPANINFO zi;
- memset(&zi, 0, sizeof(zi));
- zi.spanno = p->span;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
- return 0;
- }
- return zi.alarms;
-}
-
-static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
-{
- struct zt_pvt *p = ast->tech_pvt;
- struct ast_frame *f = *dest;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
-
- if (p->confirmanswer) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
- /* Upon receiving a DTMF digit, consider this an answer confirmation instead
- of a DTMF digit */
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_ANSWER;
- *dest = &p->subs[index].f;
- /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
- p->confirmanswer = 0;
- } else if (p->callwaitcas) {
- if ((f->subclass == 'A') || (f->subclass == 'D')) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
- if (p->cidspill)
- free(p->cidspill);
- send_cwcidspill(p);
- }
- if ((f->subclass != 'm') && (f->subclass != 'u'))
- p->callwaitcas = 0;
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- *dest = &p->subs[index].f;
- } else if (f->subclass == 'f') {
- /* Fax tone -- Handle and return NULL */
- if ((p->callprogress & 0x6) && !p->faxhandled) {
- p->faxhandled++;
- if (strcmp(ast->exten, "fax")) {
- const char *target_context = S_OR(ast->macrocontext, ast->context);
-
- if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
- /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
- pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
- if (ast_async_goto(ast, target_context, "fax", 1))
- ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
- } else
- ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Fax already handled\n");
- zt_confmute(p, 0);
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- *dest = &p->subs[index].f;
- } else if (f->subclass == 'm') {
- /* Confmute request */
- zt_confmute(p, 1);
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- *dest = &p->subs[index].f;
- } else if (f->subclass == 'u') {
- /* Unmute */
- zt_confmute(p, 0);
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- *dest = &p->subs[index].f;
- } else
- zt_confmute(p, 0);
-}
-
-static struct ast_frame *zt_handle_event(struct ast_channel *ast)
-{
- int res, x;
- int index, mysig;
- char *c;
- struct zt_pvt *p = ast->tech_pvt;
- pthread_t threadid;
- pthread_attr_t attr;
- struct ast_channel *chan;
- struct ast_frame *f;
-
- index = zt_get_index(ast, p, 0);
- mysig = p->sig;
- if (p->outsigmod > -1)
- mysig = p->outsigmod;
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- p->subs[index].f.datalen = 0;
- p->subs[index].f.samples = 0;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = 0;
- p->subs[index].f.src = "zt_handle_event";
- p->subs[index].f.data = NULL;
- f = &p->subs[index].f;
-
- if (index < 0)
- return &p->subs[index].f;
- if (p->fake_event) {
- res = p->fake_event;
- p->fake_event = 0;
- } else
- res = zt_get_event(p->subs[index].zfd);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
-
- if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
- p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
-
- ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
-#ifdef HAVE_PRI
- if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
- /* absorb event */
- } else {
-#endif
- p->subs[index].f.frametype = AST_FRAME_DTMF_END;
- p->subs[index].f.subclass = res & 0xff;
-#ifdef HAVE_PRI
- }
-#endif
- zt_handle_dtmfup(ast, index, &f);
- return f;
- }
-
- if (res & ZT_EVENT_DTMFDOWN) {
- if (option_debug)
- ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
- /* Mute conference */
- zt_confmute(p, 1);
- p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
- p->subs[index].f.subclass = res & 0xff;
- return &p->subs[index].f;
- }
-
- switch (res) {
-#ifdef ZT_EVENT_EC_DISABLED
- case ZT_EVENT_EC_DISABLED:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
- p->echocanon = 0;
- break;
-#endif
- case ZT_EVENT_BITSCHANGED:
- ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
- case ZT_EVENT_PULSE_START:
- /* Stop tone if there's a pulse start and the PBX isn't started */
- if (!ast->pbx)
- tone_zone_play_tone(p->subs[index].zfd, -1);
- break;
- case ZT_EVENT_DIALCOMPLETE:
- if (p->inalarm) break;
- if ((p->radio || (p->oprmode < 0))) break;
- if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
- ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
- return NULL;
- }
- if (!x) { /* if not still dialing in driver */
- zt_enable_ec(p);
- if (p->echobreak) {
- zt_train_ec(p);
- ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
- p->dop.op = ZT_DIAL_OP_REPLACE;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
- p->echobreak = 0;
- } else {
- p->dialing = 0;
- if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
- /* if thru with dialing after offhook */
- if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
- ast_setstate(ast, AST_STATE_UP);
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_ANSWER;
- break;
- } else { /* if to state wait for offhook to dial rest */
- /* we now wait for off hook */
- ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
- }
- }
- if (ast->_state == AST_STATE_DIALING) {
- if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
- ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
- } else if (p->confirmanswer || (!p->dialednone && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) || (mysig == SIG_SF) || (mysig == SIG_SFWINK) || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) || (mysig == SIG_SF_FEATB)))) {
- ast_setstate(ast, AST_STATE_RINGING);
- } else if (!p->answeronpolarityswitch) {
- ast_setstate(ast, AST_STATE_UP);
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_ANSWER;
- /* If aops=0 and hops=1, this is necessary */
- p->polarity = POLARITY_REV;
- } else {
- /* Start clean, so we can catch the change to REV polarity when party answers */
- p->polarity = POLARITY_IDLE;
- }
- }
- }
- }
- break;
- case ZT_EVENT_ALARM:
-#ifdef HAVE_PRI
- if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
- /* T309 is not enabled : hangup calls when alarm occurs */
- if (p->call) {
- if (p->pri && p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_hangup(p->pri->pri, p->call, -1);
- pri_destroycall(p->pri->pri, p->call);
- p->call = NULL;
- pri_rel(p->pri);
- } else
- ast_log(LOG_WARNING, "Failed to grab PRI!\n");
- } else
- ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
- }
- if (p->owner)
- p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- }
- if (p->bearer)
- p->bearer->inalarm = 1;
- else
-#endif
- p->inalarm = 1;
- res = get_alarms(p);
- do {
- const char *alarm_str = alarm2str(res);
-
- /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
- * doesn't know what to do with it. Don't confuse users with log messages. */
- if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
- p->unknown_alarm = 1;
- break;
- } else {
- p->unknown_alarm = 0;
- }
-
- ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
- manager_event(EVENT_FLAG_SYSTEM, "Alarm",
- "Alarm: %s\r\n"
- "Channel: %d\r\n",
- alarm_str, p->channel);
- } while (0);
-#ifdef HAVE_LIBPRI
- if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
- /* fall through intentionally */
- } else {
- break;
- }
-#endif
- case ZT_EVENT_ONHOOK:
- if (p->radio) {
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
- break;
- }
- if (p->oprmode < 0)
- {
- if (p->oprmode != -1) break;
- if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
- {
- /* Make sure it starts ringing */
- zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
- zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
- save_conference(p->oprpeer);
- tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
- }
- break;
- }
- switch (p->sig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- p->onhooktime = time(NULL);
- p->msgstate = -1;
- /* Check for some special conditions regarding call waiting */
- if (index == SUB_REAL) {
- /* The normal line was hung up */
- if (p->subs[SUB_CALLWAIT].owner) {
- /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
- swap_subs(p, SUB_CALLWAIT, SUB_REAL);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
- unalloc_sub(p, SUB_CALLWAIT);
-#if 0
- p->subs[index].needanswer = 0;
- p->subs[index].needringing = 0;
-#endif
- p->callwaitingrepeat = 0;
- p->cidcwexpire = 0;
- p->owner = NULL;
- /* Don't start streaming audio yet if the incoming call isn't up yet */
- if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
- p->dialing = 1;
- zt_ring_phone(p);
- } else if (p->subs[SUB_THREEWAY].owner) {
- unsigned int mssinceflash;
- /* Here we have to retain the lock on both the main channel, the 3-way channel, and
- the private structure -- not especially easy or clean */
- while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
- /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
- ast_mutex_unlock(&p->lock);
- ast_mutex_unlock(&ast->lock);
- usleep(1);
- /* We can grab ast and p in that order, without worry. We should make sure
- nothing seriously bad has happened though like some sort of bizarre double
- masquerade! */
- ast_mutex_lock(&ast->lock);
- ast_mutex_lock(&p->lock);
- if (p->owner != ast) {
- ast_log(LOG_WARNING, "This isn't good...\n");
- return NULL;
- }
- }
- if (!p->subs[SUB_THREEWAY].owner) {
- ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
- return NULL;
- }
- mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
- ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
- if (mssinceflash < MIN_MS_SINCE_FLASH) {
- /* It hasn't been long enough since the last flashook. This is probably a bounce on
- hanging up. Hangup both channels now */
- if (p->subs[SUB_THREEWAY].owner)
- ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
- p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
- if (p->transfer) {
- /* In any case this isn't a threeway call anymore */
- p->subs[SUB_REAL].inthreeway = 0;
- p->subs[SUB_THREEWAY].inthreeway = 0;
- /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
- if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- /* Swap subs and dis-own channel */
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- p->owner = NULL;
- /* Ring the phone */
- zt_ring_phone(p);
- } else {
- if ((res = attempt_transfer(p)) < 0) {
- p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
- if (p->subs[SUB_THREEWAY].owner)
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- } else if (res) {
- /* Don't actually hang up at this point */
- if (p->subs[SUB_THREEWAY].owner)
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- break;
- }
- }
- } else {
- p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
- if (p->subs[SUB_THREEWAY].owner)
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- }
- } else {
- ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
- /* Swap subs and dis-own channel */
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- p->owner = NULL;
- /* Ring the phone */
- zt_ring_phone(p);
- }
- }
- } else {
- ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
- }
- /* Fall through */
- default:
- zt_disable_ec(p);
- return NULL;
- }
- break;
- case ZT_EVENT_RINGOFFHOOK:
- if (p->inalarm) break;
- if (p->oprmode < 0)
- {
- if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
- {
- /* Make sure it stops ringing */
- zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
- tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
- restore_conference(p->oprpeer);
- }
- break;
- }
- if (p->radio)
- {
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
- break;
- }
- /* for E911, its supposed to wait for offhook then dial
- the second half of the dial string */
- if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
- c = strchr(p->dialdest, '/');
- if (c)
- c++;
- else
- c = p->dialdest;
- if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
- else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
- if (strlen(p->dop.dialstr) > 4) {
- memset(p->echorest, 'w', sizeof(p->echorest) - 1);
- strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
- p->echorest[sizeof(p->echorest) - 1] = '\0';
- p->echobreak = 1;
- p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
- } else
- p->echobreak = 0;
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
- x = ZT_ONHOOK;
- ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
- ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
- return NULL;
- }
- p->dialing = 1;
- return &p->subs[index].f;
- }
- switch (p->sig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- switch (ast->_state) {
- case AST_STATE_RINGING:
- zt_enable_ec(p);
- zt_train_ec(p);
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_ANSWER;
- /* Make sure it stops ringing */
- zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
- ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
- if (p->cidspill) {
- /* Cancel any running CallerID spill */
- free(p->cidspill);
- p->cidspill = NULL;
- }
- p->dialing = 0;
- p->callwaitcas = 0;
- if (p->confirmanswer) {
- /* Ignore answer if "confirm answer" is enabled */
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- } else if (!ast_strlen_zero(p->dop.dialstr)) {
- /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
- p->dop.dialstr[0] = '\0';
- return NULL;
- } else {
- ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- p->dialing = 1;
- }
- p->dop.dialstr[0] = '\0';
- ast_setstate(ast, AST_STATE_DIALING);
- } else
- ast_setstate(ast, AST_STATE_UP);
- return &p->subs[index].f;
- case AST_STATE_DOWN:
- ast_setstate(ast, AST_STATE_RING);
- ast->rings = 1;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
- ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
- return &p->subs[index].f;
- case AST_STATE_UP:
- /* Make sure it stops ringing */
- zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
- /* Okay -- probably call waiting*/
- if (ast_bridged_channel(p->owner))
- ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
- p->subs[index].needunhold = 1;
- break;
- case AST_STATE_RESERVED:
- /* Start up dialtone */
- if (has_voicemail(p))
- res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
- else
- res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
- break;
- default:
- ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
- }
- break;
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
- if (ast->_state == AST_STATE_RING) {
- p->ringt = p->ringt_base;
- }
-
- /* Fall through */
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_EMWINK:
- case SIG_FEATD:
- case SIG_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_E911:
- case SIG_FGC_CAMA:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_SF:
- case SIG_SFWINK:
- case SIG_SF_FEATD:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- if (ast->_state == AST_STATE_PRERING)
- ast_setstate(ast, AST_STATE_RING);
- if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ring detected\n");
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_RING;
- } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Line answered\n");
- if (p->confirmanswer) {
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- } else {
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_ANSWER;
- ast_setstate(ast, AST_STATE_UP);
- }
- } else if (ast->_state != AST_STATE_RING)
- ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
- }
- break;
-#ifdef ZT_EVENT_RINGBEGIN
- case ZT_EVENT_RINGBEGIN:
- switch (p->sig) {
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
- if (ast->_state == AST_STATE_RING) {
- p->ringt = p->ringt_base;
- }
- break;
- }
- break;
-#endif
- case ZT_EVENT_RINGEROFF:
- if (p->inalarm) break;
- if ((p->radio || (p->oprmode < 0))) break;
- ast->rings++;
- if ((ast->rings > p->cidrings) && (p->cidspill)) {
- ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n");
- free(p->cidspill);
- p->cidspill = NULL;
- p->callwaitcas = 0;
- }
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_RINGING;
- break;
- case ZT_EVENT_RINGERON:
- break;
- case ZT_EVENT_NOALARM:
- p->inalarm = 0;
-#ifdef HAVE_PRI
- /* Extremely unlikely but just in case */
- if (p->bearer)
- p->bearer->inalarm = 0;
-#endif
- if (!p->unknown_alarm) {
- ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
- manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
- "Channel: %d\r\n", p->channel);
- } else {
- p->unknown_alarm = 0;
- }
- break;
- case ZT_EVENT_WINKFLASH:
- if (p->inalarm) break;
- if (p->radio) break;
- if (p->oprmode < 0) break;
- if (p->oprmode > 1)
- {
- struct zt_params par;
-
- if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
- {
- if (!par.rxisoffhook)
- {
- /* Make sure it stops ringing */
- zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
- zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
- save_conference(p);
- tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
- }
- }
- break;
- }
- /* Remember last time we got a flash-hook */
- gettimeofday(&p->flashtime, NULL);
- switch (mysig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
- index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
- p->callwaitcas = 0;
-
- if (index != SUB_REAL) {
- ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
- goto winkflashdone;
- }
-
- if (p->subs[SUB_CALLWAIT].owner) {
- /* Swap to call-wait */
- swap_subs(p, SUB_REAL, SUB_CALLWAIT);
- tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
- p->owner = p->subs[SUB_REAL].owner;
- ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
- if (p->owner->_state == AST_STATE_RINGING) {
- ast_setstate(p->owner, AST_STATE_UP);
- p->subs[SUB_REAL].needanswer = 1;
- }
- p->callwaitingrepeat = 0;
- p->cidcwexpire = 0;
- /* Start music on hold if appropriate */
- if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
- ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
- S_OR(p->mohsuggest, NULL),
- !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- }
- p->subs[SUB_CALLWAIT].needhold = 1;
- if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
- ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
- S_OR(p->mohsuggest, NULL),
- !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- }
- p->subs[SUB_REAL].needunhold = 1;
- } else if (!p->subs[SUB_THREEWAY].owner) {
- char cid_num[256];
- char cid_name[256];
-
- if (!p->threewaycalling) {
- /* Just send a flash if no 3-way calling */
- p->subs[SUB_REAL].needflash = 1;
- goto winkflashdone;
- } else if (!check_for_conference(p)) {
- if (p->zaptrcallerid && p->owner) {
- if (p->owner->cid.cid_num)
- ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
- if (p->owner->cid.cid_name)
- ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
- }
- /* XXX This section needs much more error checking!!! XXX */
- /* Start a 3-way call if feasible */
- if (!((ast->pbx) ||
- (ast->_state == AST_STATE_UP) ||
- (ast->_state == AST_STATE_RING))) {
- ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
- goto winkflashdone;
- }
- if (alloc_sub(p, SUB_THREEWAY)) {
- ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
- goto winkflashdone;
- }
- /* Make new channel */
- chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
- if (p->zaptrcallerid) {
- if (!p->origcid_num)
- p->origcid_num = ast_strdup(p->cid_num);
- if (!p->origcid_name)
- p->origcid_name = ast_strdup(p->cid_name);
- ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
- ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
- }
- /* Swap things around between the three-way and real call */
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- /* Disable echo canceller for better dialing */
- zt_disable_ec(p);
- res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
- if (res)
- ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
- p->owner = chan;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (!chan) {
- ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
- } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
- ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
- res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
- zt_enable_ec(p);
- ast_hangup(chan);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
- /* Start music on hold if appropriate */
- if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
- S_OR(p->mohsuggest, NULL),
- !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
- }
- p->subs[SUB_THREEWAY].needhold = 1;
- }
- pthread_attr_destroy(&attr);
- }
- } else {
- /* Already have a 3 way call */
- if (p->subs[SUB_THREEWAY].inthreeway) {
- /* Call is already up, drop the last person */
- if (option_debug)
- ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
- /* If the primary call isn't answered yet, use it */
- if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
- /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- p->owner = p->subs[SUB_REAL].owner;
- }
- /* Drop the last call and stop the conference */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
- p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
- p->subs[SUB_REAL].inthreeway = 0;
- p->subs[SUB_THREEWAY].inthreeway = 0;
- } else {
- /* Lets see what we're up to */
- if (((ast->pbx) || (ast->_state == AST_STATE_UP)) &&
- (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
- int otherindex = SUB_THREEWAY;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
- /* Put them in the threeway, and flip */
- p->subs[SUB_THREEWAY].inthreeway = 1;
- p->subs[SUB_REAL].inthreeway = 1;
- if (ast->_state == AST_STATE_UP) {
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- otherindex = SUB_REAL;
- }
- if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
- ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
- p->subs[otherindex].needunhold = 1;
- p->owner = p->subs[SUB_REAL].owner;
- if (ast->_state == AST_STATE_RINGING) {
- ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
- res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
- res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
- }
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
- p->owner = p->subs[SUB_REAL].owner;
- if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
- p->subs[SUB_REAL].needunhold = 1;
- zt_enable_ec(p);
- }
-
- }
- }
- winkflashdone:
- update_conf(p);
- break;
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_EMWINK:
- case SIG_FEATD:
- case SIG_SF:
- case SIG_SFWINK:
- case SIG_SF_FEATD:
- case SIG_FXSLS:
- case SIG_FXSGS:
- if (p->dialing)
- ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
- else
- ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
- break;
- case SIG_FEATDMF_TA:
- switch (p->whichwink) {
- case 0:
- ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
- break;
- case 1:
- ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
- break;
- case 2:
- ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
- return NULL;
- }
- p->whichwink++;
- /* Fall through */
- case SIG_FEATDMF:
- case SIG_E911:
- case SIG_FGC_CAMAMF:
- case SIG_FGC_CAMA:
- case SIG_FEATB:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- /* FGD MF *Must* wait for wink */
- if (!ast_strlen_zero(p->dop.dialstr)) {
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
- p->dop.dialstr[0] = '\0';
- return NULL;
- } else
- ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
- }
- p->dop.dialstr[0] = '\0';
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
- }
- break;
- case ZT_EVENT_HOOKCOMPLETE:
- if (p->inalarm) break;
- if ((p->radio || (p->oprmode < 0))) break;
- switch (mysig) {
- case SIG_FXSLS: /* only interesting for FXS */
- case SIG_FXSGS:
- case SIG_FXSKS:
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_EMWINK:
- case SIG_FEATD:
- case SIG_SF:
- case SIG_SFWINK:
- case SIG_SF_FEATD:
- if (!ast_strlen_zero(p->dop.dialstr)) {
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
- p->dop.dialstr[0] = '\0';
- return NULL;
- } else
- ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
- }
- p->dop.dialstr[0] = '\0';
- p->dop.op = ZT_DIAL_OP_REPLACE;
- break;
- case SIG_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_E911:
- case SIG_FGC_CAMA:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
- break;
- default:
- break;
- }
- break;
- case ZT_EVENT_POLARITY:
- /*
- * If we get a Polarity Switch event, check to see
- * if we should change the polarity state and
- * mark the channel as UP or if this is an indication
- * of remote end disconnect.
- */
- if (p->polarity == POLARITY_IDLE) {
- p->polarity = POLARITY_REV;
- if (p->answeronpolarityswitch &&
- ((ast->_state == AST_STATE_DIALING) ||
- (ast->_state == AST_STATE_RINGING))) {
- ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
- ast_setstate(p->owner, AST_STATE_UP);
- if (p->hanguponpolarityswitch) {
- gettimeofday(&p->polaritydelaytv, NULL);
- }
- } else
- ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
- }
- /* Removed else statement from here as it was preventing hangups from ever happening*/
- /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
- if (p->hanguponpolarityswitch &&
- (p->polarityonanswerdelay > 0) &&
- (p->polarity == POLARITY_REV) &&
- ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
- /* Added log_debug information below to provide a better indication of what is going on */
- ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
-
- if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
- ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
- ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
- p->polarity = POLARITY_IDLE;
- } else {
- ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
- }
- } else {
- p->polarity = POLARITY_IDLE;
- ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
- }
- /* Added more log_debug information below to provide a better indication of what is going on */
- ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
- break;
- default:
- ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
- }
- return &p->subs[index].f;
-}
-
-static struct ast_frame *__zt_exception(struct ast_channel *ast)
-{
- struct zt_pvt *p = ast->tech_pvt;
- int res;
- int usedindex=-1;
- int index;
- struct ast_frame *f;
-
-
- index = zt_get_index(ast, p, 1);
-
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.datalen = 0;
- p->subs[index].f.samples = 0;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = 0;
- p->subs[index].f.subclass = 0;
- p->subs[index].f.delivery = ast_tv(0,0);
- p->subs[index].f.src = "zt_exception";
- p->subs[index].f.data = NULL;
-
-
- if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
- /* If nobody owns us, absorb the event appropriately, otherwise
- we loop indefinitely. This occurs when, during call waiting, the
- other end hangs up our channel so that it no longer exists, but we
- have neither FLASH'd nor ONHOOK'd to signify our desire to
- change to the other channel. */
- if (p->fake_event) {
- res = p->fake_event;
- p->fake_event = 0;
- } else
- res = zt_get_event(p->subs[SUB_REAL].zfd);
- /* Switch to real if there is one and this isn't something really silly... */
- if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
- (res != ZT_EVENT_HOOKCOMPLETE)) {
- ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
- p->owner = p->subs[SUB_REAL].owner;
- if (p->owner && ast_bridged_channel(p->owner))
- ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
- p->subs[SUB_REAL].needunhold = 1;
- }
- switch (res) {
- case ZT_EVENT_ONHOOK:
- zt_disable_ec(p);
- if (p->owner) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
- zt_ring_phone(p);
- p->callwaitingrepeat = 0;
- p->cidcwexpire = 0;
- } else
- ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
- update_conf(p);
- break;
- case ZT_EVENT_RINGOFFHOOK:
- zt_enable_ec(p);
- zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
- p->subs[SUB_REAL].needanswer = 1;
- p->dialing = 0;
- }
- break;
- case ZT_EVENT_HOOKCOMPLETE:
- case ZT_EVENT_RINGERON:
- case ZT_EVENT_RINGEROFF:
- /* Do nothing */
- break;
- case ZT_EVENT_WINKFLASH:
- gettimeofday(&p->flashtime, NULL);
- if (p->owner) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
- if (p->owner->_state != AST_STATE_UP) {
- /* Answer if necessary */
- usedindex = zt_get_index(p->owner, p, 0);
- if (usedindex > -1) {
- p->subs[usedindex].needanswer = 1;
- }
- ast_setstate(p->owner, AST_STATE_UP);
- }
- p->callwaitingrepeat = 0;
- p->cidcwexpire = 0;
- if (ast_bridged_channel(p->owner))
- ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
- p->subs[SUB_REAL].needunhold = 1;
- } else
- ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
- update_conf(p);
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
- }
- f = &p->subs[index].f;
- return f;
- }
- if (!(p->radio || (p->oprmode < 0)) && option_debug)
- ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
- /* If it's not us, return NULL immediately */
- if (ast != p->owner) {
- ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
- f = &p->subs[index].f;
- return f;
- }
- f = zt_handle_event(ast);
- return f;
-}
-
-static struct ast_frame *zt_exception(struct ast_channel *ast)
-{
- struct zt_pvt *p = ast->tech_pvt;
- struct ast_frame *f;
- ast_mutex_lock(&p->lock);
- f = __zt_exception(ast);
- ast_mutex_unlock(&p->lock);
- return f;
-}
-
-static struct ast_frame *zt_read(struct ast_channel *ast)
-{
- struct zt_pvt *p = ast->tech_pvt;
- int res;
- int index;
- void *readbuf;
- struct ast_frame *f;
-
-
- ast_mutex_lock(&p->lock);
-
- index = zt_get_index(ast, p, 0);
-
- /* Hang up if we don't really exist */
- if (index < 0) {
- ast_log(LOG_WARNING, "We dont exist?\n");
- ast_mutex_unlock(&p->lock);
- return NULL;
- }
-
- if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
-
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.datalen = 0;
- p->subs[index].f.samples = 0;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = 0;
- p->subs[index].f.subclass = 0;
- p->subs[index].f.delivery = ast_tv(0,0);
- p->subs[index].f.src = "zt_read";
- p->subs[index].f.data = NULL;
-
- /* make sure it sends initial key state as first frame */
- if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
- {
- ZT_PARAMS ps;
-
- ps.channo = p->channel;
- if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
- ast_mutex_unlock(&p->lock);
- return NULL;
- }
- p->firstradio = 1;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- if (ps.rxisoffhook)
- {
- p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
- }
- else
- {
- p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
- }
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
- if (p->ringt == 1) {
- ast_mutex_unlock(&p->lock);
- return NULL;
- }
- else if (p->ringt > 0)
- p->ringt--;
-
- if (p->subs[index].needringing) {
- /* Send ringing frame if requested */
- p->subs[index].needringing = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_RINGING;
- ast_setstate(ast, AST_STATE_RINGING);
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
-
- if (p->subs[index].needbusy) {
- /* Send busy frame if requested */
- p->subs[index].needbusy = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_BUSY;
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
-
- if (p->subs[index].needcongestion) {
- /* Send congestion frame if requested */
- p->subs[index].needcongestion = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
-
- if (p->subs[index].needcallerid) {
- ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
- S_OR(p->lastcid_name, NULL),
- S_OR(p->lastcid_num, NULL)
- );
- p->subs[index].needcallerid = 0;
- }
-
- if (p->subs[index].needanswer) {
- /* Send answer frame if requested */
- p->subs[index].needanswer = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_ANSWER;
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
-
- if (p->subs[index].needflash) {
- /* Send answer frame if requested */
- p->subs[index].needflash = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_FLASH;
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
-
- if (p->subs[index].needhold) {
- /* Send answer frame if requested */
- p->subs[index].needhold = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_HOLD;
- ast_mutex_unlock(&p->lock);
- ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
- return &p->subs[index].f;
- }
-
- if (p->subs[index].needunhold) {
- /* Send answer frame if requested */
- p->subs[index].needunhold = 0;
- p->subs[index].f.frametype = AST_FRAME_CONTROL;
- p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
- ast_mutex_unlock(&p->lock);
- ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
- return &p->subs[index].f;
- }
-
- if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
- if (!p->subs[index].linear) {
- p->subs[index].linear = 1;
- res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
- if (res)
- ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
- }
- } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
- (ast->rawreadformat == AST_FORMAT_ALAW)) {
- if (p->subs[index].linear) {
- p->subs[index].linear = 0;
- res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
- if (res)
- ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
- }
- } else {
- ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
- ast_mutex_unlock(&p->lock);
- return NULL;
- }
- readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
- CHECK_BLOCKING(ast);
- res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
- ast_clear_flag(ast, AST_FLAG_BLOCKING);
- /* Check for hangup */
- if (res < 0) {
- f = NULL;
- if (res == -1) {
- if (errno == EAGAIN) {
- /* Return "NULL" frame if there is nobody there */
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- } else if (errno == ELAST) {
- f = __zt_exception(ast);
- } else
- ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
- }
- ast_mutex_unlock(&p->lock);
- return f;
- }
- if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
- ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
- f = __zt_exception(ast);
- ast_mutex_unlock(&p->lock);
- return f;
- }
- if (p->tdd) { /* if in TDD mode, see if we receive that */
- int c;
-
- c = tdd_feed(p->tdd,readbuf,READ_SIZE);
- if (c < 0) {
- ast_log(LOG_DEBUG,"tdd_feed failed\n");
- ast_mutex_unlock(&p->lock);
- return NULL;
- }
- if (c) { /* if a char to return */
- p->subs[index].f.subclass = 0;
- p->subs[index].f.frametype = AST_FRAME_TEXT;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
- p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
- p->subs[index].f.datalen = 1;
- *((char *) p->subs[index].f.data) = c;
- ast_mutex_unlock(&p->lock);
- return &p->subs[index].f;
- }
- }
- if (p->callwaitingrepeat)
- p->callwaitingrepeat--;
- if (p->cidcwexpire)
- p->cidcwexpire--;
- /* Repeat callwaiting */
- if (p->callwaitingrepeat == 1) {
- p->callwaitrings++;
- zt_callwait(ast);
- }
- /* Expire CID/CW */
- if (p->cidcwexpire == 1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
- restore_conference(p);
- }
- if (p->subs[index].linear) {
- p->subs[index].f.datalen = READ_SIZE * 2;
- } else
- p->subs[index].f.datalen = READ_SIZE;
-
- /* Handle CallerID Transmission */
- if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
- send_callerid(p);
- }
-
- p->subs[index].f.frametype = AST_FRAME_VOICE;
- p->subs[index].f.subclass = ast->rawreadformat;
- p->subs[index].f.samples = READ_SIZE;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
- p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
-#if 0
- ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
-#endif
- if (p->dialing || /* Transmitting something */
- (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
- ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
- ) {
- /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
- don't send anything */
- p->subs[index].f.frametype = AST_FRAME_NULL;
- p->subs[index].f.subclass = 0;
- p->subs[index].f.samples = 0;
- p->subs[index].f.mallocd = 0;
- p->subs[index].f.offset = 0;
- p->subs[index].f.data = NULL;
- p->subs[index].f.datalen= 0;
- }
- if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) {
- /* Perform busy detection. etc on the zap line */
- f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
- if (f) {
- if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
- if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
- /* Treat this as a "hangup" instead of a "busy" on the assumption that
- a busy */
- f = NULL;
- }
- } else if (f->frametype == AST_FRAME_DTMF) {
-#ifdef HAVE_PRI
- if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
- /* Don't accept in-band DTMF when in overlap dial mode */
- f->frametype = AST_FRAME_NULL;
- f->subclass = 0;
- }
-#endif
- /* DSP clears us of being pulse */
- p->pulsedial = 0;
- }
- }
- } else
- f = &p->subs[index].f;
-
- if (f && (f->frametype == AST_FRAME_DTMF))
- zt_handle_dtmfup(ast, index, &f);
-
- /* If we have a fake_event, trigger exception to handle it */
- if (p->fake_event)
- ast_set_flag(ast, AST_FLAG_EXCEPTION);
-
- ast_mutex_unlock(&p->lock);
- return f;
-}
-
-static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
-{
- int sent=0;
- int size;
- int res;
- int fd;
- fd = p->subs[index].zfd;
- while (len) {
- size = len;
- if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
- size = (linear ? READ_SIZE * 2 : READ_SIZE);
- res = write(fd, buf, size);
- if (res != size) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
- return sent;
- }
- len -= size;
- buf += size;
- }
- return sent;
-}
-
-static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
-{
- struct zt_pvt *p = ast->tech_pvt;
- int res;
- int index;
- index = zt_get_index(ast, p, 0);
- if (index < 0) {
- ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
- return -1;
- }
-
-#if 0
-#ifdef HAVE_PRI
- ast_mutex_lock(&p->lock);
- if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
- if (p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
- pri_rel(p->pri);
- } else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- p->proceeding=1;
- }
- ast_mutex_unlock(&p->lock);
-#endif
-#endif
- /* Write a frame of (presumably voice) data */
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype != AST_FRAME_IMAGE)
- ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
- return 0;
- }
- if ((frame->subclass != AST_FORMAT_SLINEAR) &&
- (frame->subclass != AST_FORMAT_ULAW) &&
- (frame->subclass != AST_FORMAT_ALAW)) {
- ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
- return -1;
- }
- if (p->dialing) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
- return 0;
- }
- if (!p->owner) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
- return 0;
- }
- if (p->cidspill) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
- return 0;
- }
- /* Return if it's not valid data */
- if (!frame->data || !frame->datalen)
- return 0;
-
- if (frame->subclass == AST_FORMAT_SLINEAR) {
- if (!p->subs[index].linear) {
- p->subs[index].linear = 1;
- res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
- if (res)
- ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
- }
- res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
- } else {
- /* x-law already */
- if (p->subs[index].linear) {
- p->subs[index].linear = 0;
- res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
- if (res)
- ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
- }
- res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
- }
- if (res < 0) {
- ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
-{
- struct zt_pvt *p = chan->tech_pvt;
- int res=-1;
- int index;
- int func = ZT_FLASH;
- ast_mutex_lock(&p->lock);
- index = zt_get_index(chan, p, 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
- if (index == SUB_REAL) {
- switch (condition) {
- case AST_CONTROL_BUSY:
-#ifdef HAVE_PRI
- if (p->priindication_oob && p->sig == SIG_PRI) {
- chan->hangupcause = AST_CAUSE_USER_BUSY;
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- res = 0;
- } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
- if (p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
- pri_rel(p->pri);
- }
- else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- p->progress = 1;
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
- } else
-#endif
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
- break;
- case AST_CONTROL_RINGING:
-#ifdef HAVE_PRI
- if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
- if (p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
- pri_rel(p->pri);
- }
- else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- p->alerting = 1;
- }
-#endif
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
- if (chan->_state != AST_STATE_UP) {
- if ((chan->_state != AST_STATE_RING) ||
- ((p->sig != SIG_FXSKS) &&
- (p->sig != SIG_FXSLS) &&
- (p->sig != SIG_FXSGS)))
- ast_setstate(chan, AST_STATE_RINGING);
- }
- break;
- case AST_CONTROL_PROCEEDING:
- ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
-#ifdef HAVE_PRI
- if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
- if (p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
- pri_rel(p->pri);
- }
- else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- p->proceeding = 1;
- }
-#endif
- /* don't continue in ast_indicate */
- res = 0;
- break;
- case AST_CONTROL_PROGRESS:
- ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
-#ifdef HAVE_PRI
- p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */
- if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
- if (p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
- pri_rel(p->pri);
- }
- else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- p->progress = 1;
- }
-#endif
- /* don't continue in ast_indicate */
- res = 0;
- break;
- case AST_CONTROL_CONGESTION:
- chan->hangupcause = AST_CAUSE_CONGESTION;
-#ifdef HAVE_PRI
- if (p->priindication_oob && p->sig == SIG_PRI) {
- chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- res = 0;
- } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
- if (p->pri) {
- if (!pri_grab(p, p->pri)) {
- pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
- pri_rel(p->pri);
- } else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- p->progress = 1;
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- } else
-#endif
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- break;
- case AST_CONTROL_HOLD:
-#ifdef HAVE_PRI
- if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
- if (!pri_grab(p, p->pri)) {
- res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
- pri_rel(p->pri);
- } else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- } else
-#endif
- ast_moh_start(chan, data, p->mohinterpret);
- break;
- case AST_CONTROL_UNHOLD:
-#ifdef HAVE_PRI
- if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
- if (!pri_grab(p, p->pri)) {
- res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
- pri_rel(p->pri);
- } else
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- } else
-#endif
- ast_moh_stop(chan);
- break;
- case AST_CONTROL_RADIO_KEY:
- if (p->radio)
- res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
- res = 0;
- break;
- case AST_CONTROL_RADIO_UNKEY:
- if (p->radio)
- res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
- res = 0;
- break;
- case AST_CONTROL_FLASH:
- /* flash hookswitch */
- if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
- /* Clear out the dial buffer */
- p->dop.dialstr[0] = '\0';
- if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
- ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
- chan->name, strerror(errno));
- } else
- res = 0;
- } else
- res = 0;
- break;
- case AST_CONTROL_SRCUPDATE:
- res = 0;
- break;
- case -1:
- res = tone_zone_play_tone(p->subs[index].zfd, -1);
- break;
- }
- } else
- res = 0;
- ast_mutex_unlock(&p->lock);
- return res;
-}
-
-static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
-{
- struct ast_channel *tmp;
- int deflaw;
- int res;
- int x,y;
- int features;
- char *b2 = NULL;
- ZT_PARAMS ps;
- if (i->subs[index].owner) {
- ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
- return NULL;
- }
- y = 1;
- do {
- if (b2)
- free(b2);
-#ifdef HAVE_PRI
- if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
- b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
- else
-#endif
- if (i->channel == CHAN_PSEUDO)
- b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
- else
- b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
- for (x = 0; x < 3; x++) {
- if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
- break;
- }
- y++;
- } while (x < 3);
- tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
- if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
- free(b2);
- if (!tmp)
- return NULL;
- tmp->tech = &zap_tech;
- ps.channo = i->channel;
- res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
- if (res) {
- ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
- ps.curlaw = ZT_LAW_MULAW;
- }
- if (ps.curlaw == ZT_LAW_ALAW)
- deflaw = AST_FORMAT_ALAW;
- else
- deflaw = AST_FORMAT_ULAW;
- if (law) {
- if (law == ZT_LAW_ALAW)
- deflaw = AST_FORMAT_ALAW;
- else
- deflaw = AST_FORMAT_ULAW;
- }
- tmp->fds[0] = i->subs[index].zfd;
- tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
- /* Start out assuming ulaw since it's smaller :) */
- tmp->rawreadformat = deflaw;
- tmp->readformat = deflaw;
- tmp->rawwriteformat = deflaw;
- tmp->writeformat = deflaw;
- i->subs[index].linear = 0;
- zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
- features = 0;
- if (index == SUB_REAL) {
- if (i->busydetect && CANBUSYDETECT(i))
- features |= DSP_FEATURE_BUSY_DETECT;
- if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
- features |= DSP_FEATURE_CALL_PROGRESS;
- if ((!i->outgoing && (i->callprogress & 4)) ||
- (i->outgoing && (i->callprogress & 2))) {
- features |= DSP_FEATURE_FAX_DETECT;
- }
-#ifdef ZT_TONEDETECT
- x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
- if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
-#endif
- i->hardwaredtmf = 0;
- features |= DSP_FEATURE_DTMF_DETECT;
-#ifdef ZT_TONEDETECT
- } else if (NEED_MFDETECT(i)) {
- i->hardwaredtmf = 1;
- features |= DSP_FEATURE_DTMF_DETECT;
- }
-#endif
- }
- if (features) {
- if (i->dsp) {
- ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
- } else {
- if (i->channel != CHAN_PSEUDO)
- i->dsp = ast_dsp_new();
- else
- i->dsp = NULL;
- if (i->dsp) {
- i->dsp_features = features & ~DSP_PROGRESS_TALK;
-#ifdef HAVE_PRI
- /* We cannot do progress detection until receives PROGRESS message */
- if (i->outgoing && (i->sig == SIG_PRI)) {
- /* Remember requested DSP features, don't treat
- talking as ANSWER */
- features = 0;
- }
-#endif
- ast_dsp_set_features(i->dsp, features);
- ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
- if (!ast_strlen_zero(progzone))
- ast_dsp_set_call_progress_zone(i->dsp, progzone);
- if (i->busydetect && CANBUSYDETECT(i)) {
- ast_dsp_set_busy_count(i->dsp, i->busycount);
- ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
- }
- }
- }
- }
-
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->tech_pvt = i;
- if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
- /* Only FXO signalled stuff can be picked up */
- tmp->callgroup = i->callgroup;
- tmp->pickupgroup = i->pickupgroup;
- }
- if (!ast_strlen_zero(i->language))
- ast_string_field_set(tmp, language, i->language);
- if (!i->owner)
- i->owner = tmp;
- if (!ast_strlen_zero(i->accountcode))
- ast_string_field_set(tmp, accountcode, i->accountcode);
- if (i->amaflags)
- tmp->amaflags = i->amaflags;
- i->subs[index].owner = tmp;
- ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
- ast_string_field_set(tmp, call_forward, i->call_forward);
- /* If we've been told "no ADSI" then enforce it */
- if (!i->adsi)
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
- if (!ast_strlen_zero(i->exten))
- ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
- if (!ast_strlen_zero(i->rdnis))
- tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
- if (!ast_strlen_zero(i->dnid))
- tmp->cid.cid_dnid = ast_strdup(i->dnid);
-
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
-#ifdef PRI_ANI
- if (!ast_strlen_zero(i->cid_ani))
- tmp->cid.cid_ani = ast_strdup(i->cid_ani);
- else
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
-#else
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
-#endif
- tmp->cid.cid_pres = i->callingpres;
- tmp->cid.cid_ton = i->cid_ton;
-#ifdef HAVE_PRI
- tmp->transfercapability = transfercapability;
- pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
- if (transfercapability & PRI_TRANS_CAP_DIGITAL)
- i->digital = 1;
- /* Assume calls are not idle calls unless we're told differently */
- i->isidlecall = 0;
- i->alreadyhungup = 0;
-#endif
- /* clear the fake event in case we posted one before we had ast_channel */
- i->fake_event = 0;
- /* Assure there is no confmute on this channel */
- zt_confmute(i, 0);
- /* Configure the new channel jb */
- ast_jb_configure(tmp, &global_jbconf);
- if (startpbx) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- ast_hangup(tmp);
- i->owner = NULL;
- return NULL;
- }
- }
-
- ast_module_ref(ast_module_info->self);
-
- return tmp;
-}
-
-
-static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
-{
- char c;
-
- *str = 0; /* start with empty output buffer */
- for (;;)
- {
- /* Wait for the first digit (up to specified ms). */
- c = ast_waitfordigit(chan, ms);
- /* if timeout, hangup or error, return as such */
- if (c < 1)
- return c;
- *str++ = c;
- *str = 0;
- if (strchr(term, c))
- return 1;
- }
-}
-
-static int zt_wink(struct zt_pvt *p, int index)
-{
- int j;
- zt_set_hook(p->subs[index].zfd, ZT_WINK);
- for (;;)
- {
- /* set bits of interest */
- j = ZT_IOMUX_SIGEVENT;
- /* wait for some happening */
- if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
- /* exit loop if we have it */
- if (j & ZT_IOMUX_SIGEVENT) break;
- }
- /* get the event info */
- if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
- return 0;
-}
-
-static void *ss_thread(void *data)
-{
- struct ast_channel *chan = data;
- struct zt_pvt *p = chan->tech_pvt;
- char exten[AST_MAX_EXTENSION] = "";
- char exten2[AST_MAX_EXTENSION] = "";
- unsigned char buf[256];
- char dtmfcid[300];
- char dtmfbuf[300];
- struct callerid_state *cs = NULL;
- char *name = NULL, *number = NULL;
- int distMatches;
- int curRingData[3];
- int receivedRingT;
- int counter1;
- int counter;
- int samples = 0;
- struct ast_smdi_md_message *smdi_msg = NULL;
- int flags;
- int i;
- int timeout;
- int getforward = 0;
- char *s1, *s2;
- int len = 0;
- int res;
- int index;
-
- /* in the bizarre case where the channel has become a zombie before we
- even get started here, abort safely
- */
- if (!p) {
- ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
- ast_hangup(chan);
- return NULL;
- }
-
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
- index = zt_get_index(chan, p, 1);
- if (index < 0) {
- ast_log(LOG_WARNING, "Huh?\n");
- ast_hangup(chan);
- return NULL;
- }
- if (p->dsp)
- ast_dsp_digitreset(p->dsp);
- switch (p->sig) {
-#ifdef HAVE_PRI
- case SIG_PRI:
- /* Now loop looking for an extension */
- ast_copy_string(exten, p->exten, sizeof(exten));
- len = strlen(exten);
- res = 0;
- while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
- if (len && !ast_ignore_pattern(chan->context, exten))
- tone_zone_play_tone(p->subs[index].zfd, -1);
- else
- tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
- if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
- timeout = matchdigittimeout;
- else
- timeout = gendigittimeout;
- res = ast_waitfordigit(chan, timeout);
- if (res < 0) {
- ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
- ast_hangup(chan);
- return NULL;
- } else if (res) {
- exten[len++] = res;
- exten[len] = '\0';
- } else
- break;
- }
- /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
- if (ast_strlen_zero(exten)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
- exten[0] = 's';
- exten[1] = '\0';
- }
- tone_zone_play_tone(p->subs[index].zfd, -1);
- if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
- /* Start the real PBX */
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- if (p->dsp) ast_dsp_digitreset(p->dsp);
- zt_enable_ec(p);
- ast_setstate(chan, AST_STATE_RING);
- res = ast_pbx_run(chan);
- if (res) {
- ast_log(LOG_WARNING, "PBX exited non-zero!\n");
- }
- } else {
- ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
- chan->hangupcause = AST_CAUSE_UNALLOCATED;
- ast_hangup(chan);
- p->exten[0] = '\0';
- /* Since we send release complete here, we won't get one */
- p->call = NULL;
- }
- return NULL;
- break;
-#endif
- case SIG_FEATD:
- case SIG_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_E911:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_EMWINK:
- case SIG_SF_FEATD:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- case SIG_SFWINK:
- if (zt_wink(p, index))
- return NULL;
- /* Fall through */
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_SF:
- case SIG_FGC_CAMA:
- res = tone_zone_play_tone(p->subs[index].zfd, -1);
- if (p->dsp)
- ast_dsp_digitreset(p->dsp);
- /* set digit mode appropriately */
- if (p->dsp) {
- if (NEED_MFDETECT(p))
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
- else
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
- }
- memset(dtmfbuf, 0, sizeof(dtmfbuf));
- /* Wait for the first digit only if immediate=no */
- if (!p->immediate)
- /* Wait for the first digit (up to 5 seconds). */
- res = ast_waitfordigit(chan, 5000);
- else
- res = 0;
- if (res > 0) {
- /* save first char */
- dtmfbuf[0] = res;
- switch (p->sig) {
- case SIG_FEATD:
- case SIG_SF_FEATD:
- res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
- if (res > 0)
- res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
- if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
- break;
- case SIG_FEATDMF_TA:
- res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
- if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
- if (zt_wink(p, index)) return NULL;
- dtmfbuf[0] = 0;
- /* Wait for the first digit (up to 5 seconds). */
- res = ast_waitfordigit(chan, 5000);
- if (res <= 0) break;
- dtmfbuf[0] = res;
- /* fall through intentionally */
- case SIG_FEATDMF:
- case SIG_E911:
- case SIG_FGC_CAMAMF:
- case SIG_SF_FEATDMF:
- res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
- /* if international caca, do it again to get real ANO */
- if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
- {
- if (zt_wink(p, index)) return NULL;
- dtmfbuf[0] = 0;
- /* Wait for the first digit (up to 5 seconds). */
- res = ast_waitfordigit(chan, 5000);
- if (res <= 0) break;
- dtmfbuf[0] = res;
- res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
- }
- if (res > 0) {
- /* if E911, take off hook */
- if (p->sig == SIG_E911)
- zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
- }
- if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
- break;
- case SIG_FEATB:
- case SIG_SF_FEATB:
- res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
- if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
- break;
- case SIG_EMWINK:
- /* if we received a '*', we are actually receiving Feature Group D
- dial syntax, so use that mode; otherwise, fall through to normal
- mode
- */
- if (res == '*') {
- res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
- if (res > 0)
- res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
- if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
- break;
- }
- default:
- /* If we got the first digit, get the rest */
- len = 1;
- dtmfbuf[len] = '\0';
- while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
- if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
- timeout = matchdigittimeout;
- } else {
- timeout = gendigittimeout;
- }
- res = ast_waitfordigit(chan, timeout);
- if (res < 0) {
- ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
- ast_hangup(chan);
- return NULL;
- } else if (res) {
- dtmfbuf[len++] = res;
- dtmfbuf[len] = '\0';
- } else {
- break;
- }
- }
- break;
- }
- }
- if (res == -1) {
- ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
- ast_hangup(chan);
- return NULL;
- } else if (res < 0) {
- ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
- ast_hangup(chan);
- return NULL;
- }
-
- if (p->sig == SIG_FGC_CAMA) {
- char anibuf[100];
-
- if (ast_safe_sleep(chan,1000) == -1) {
- ast_hangup(chan);
- return NULL;
- }
- zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
- res = my_getsigstr(chan, anibuf, "#", 10000);
- if ((res > 0) && (strlen(anibuf) > 2)) {
- if (anibuf[strlen(anibuf) - 1] == '#')
- anibuf[strlen(anibuf) - 1] = 0;
- ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
- }
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
- }
-
- ast_copy_string(exten, dtmfbuf, sizeof(exten));
- if (ast_strlen_zero(exten))
- ast_copy_string(exten, "s", sizeof(exten));
- if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
- /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
- if (exten[0] == '*') {
- char *stringp=NULL;
- ast_copy_string(exten2, exten, sizeof(exten2));
- /* Parse out extension and callerid */
- stringp=exten2 +1;
- s1 = strsep(&stringp, "*");
- s2 = strsep(&stringp, "*");
- if (s2) {
- if (!ast_strlen_zero(p->cid_num))
- ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
- else
- ast_set_callerid(chan, s1, NULL, s1);
- ast_copy_string(exten, s2, sizeof(exten));
- } else
- ast_copy_string(exten, s1, sizeof(exten));
- } else if (p->sig == SIG_FEATD)
- ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
- }
- if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
- if (exten[0] == '*') {
- char *stringp=NULL;
- ast_copy_string(exten2, exten, sizeof(exten2));
- /* Parse out extension and callerid */
- stringp=exten2 +1;
- s1 = strsep(&stringp, "#");
- s2 = strsep(&stringp, "#");
- if (s2) {
- if (!ast_strlen_zero(p->cid_num))
- ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
- else
- if (*(s1 + 2))
- ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
- ast_copy_string(exten, s2 + 1, sizeof(exten));
- } else
- ast_copy_string(exten, s1 + 2, sizeof(exten));
- } else
- ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
- }
- if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
- if (exten[0] == '*') {
- char *stringp=NULL;
- ast_copy_string(exten2, exten, sizeof(exten2));
- /* Parse out extension and callerid */
- stringp=exten2 +1;
- s1 = strsep(&stringp, "#");
- s2 = strsep(&stringp, "#");
- if (s2 && (*(s2 + 1) == '0')) {
- if (*(s2 + 2))
- ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
- }
- if (s1) ast_copy_string(exten, s1, sizeof(exten));
- else ast_copy_string(exten, "911", sizeof(exten));
- } else
- ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel);
- }
- if (p->sig == SIG_FEATB) {
- if (exten[0] == '*') {
- char *stringp=NULL;
- ast_copy_string(exten2, exten, sizeof(exten2));
- /* Parse out extension and callerid */
- stringp=exten2 +1;
- s1 = strsep(&stringp, "#");
- ast_copy_string(exten, exten2 + 1, sizeof(exten));
- } else
- ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel);
- }
- if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
- zt_wink(p, index);
- /* some switches require a minimum guard time between
- the last FGD wink and something that answers
- immediately. This ensures it */
- if (ast_safe_sleep(chan,100)) return NULL;
- }
- zt_enable_ec(p);
- if (NEED_MFDETECT(p)) {
- if (p->dsp) {
- if (!p->hardwaredtmf)
- ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
- else {
- ast_dsp_free(p->dsp);
- p->dsp = NULL;
- }
- }
- }
-
- if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- if (p->dsp) ast_dsp_digitreset(p->dsp);
- res = ast_pbx_run(chan);
- if (res) {
- ast_log(LOG_WARNING, "PBX exited non-zero\n");
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- }
- return NULL;
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
- sleep(2);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
- else
- sleep(1);
- res = ast_streamfile(chan, "ss-noservice", chan->language);
- if (res >= 0)
- ast_waitstream(chan, "");
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- ast_hangup(chan);
- return NULL;
- }
- break;
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- /* Read the first digit */
- timeout = firstdigittimeout;
- /* If starting a threeway call, never timeout on the first digit so someone
- can use flash-hook as a "hold" feature */
- if (p->subs[SUB_THREEWAY].owner)
- timeout = 999999;
- while (len < AST_MAX_EXTENSION-1) {
- /* Read digit unless it's supposed to be immediate, in which case the
- only answer is 's' */
- if (p->immediate)
- res = 's';
- else
- res = ast_waitfordigit(chan, timeout);
- timeout = 0;
- if (res < 0) {
- ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
- res = tone_zone_play_tone(p->subs[index].zfd, -1);
- ast_hangup(chan);
- return NULL;
- } else if (res) {
- exten[len++]=res;
- exten[len] = '\0';
- }
- if (!ast_ignore_pattern(chan->context, exten))
- tone_zone_play_tone(p->subs[index].zfd, -1);
- else
- tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
- if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
- if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
- if (getforward) {
- /* Record this as the forwarding extension */
- ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- if (res)
- break;
- usleep(500000);
- res = tone_zone_play_tone(p->subs[index].zfd, -1);
- sleep(1);
- memset(exten, 0, sizeof(exten));
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
- len = 0;
- getforward = 0;
- } else {
- res = tone_zone_play_tone(p->subs[index].zfd, -1);
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- if (!ast_strlen_zero(p->cid_num)) {
- if (!p->hidecallerid)
- ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
- else
- ast_set_callerid(chan, NULL, NULL, p->cid_num);
- }
- if (!ast_strlen_zero(p->cid_name)) {
- if (!p->hidecallerid)
- ast_set_callerid(chan, NULL, p->cid_name, NULL);
- }
- ast_setstate(chan, AST_STATE_RING);
- zt_enable_ec(p);
- res = ast_pbx_run(chan);
- if (res) {
- ast_log(LOG_WARNING, "PBX exited non-zero\n");
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- }
- return NULL;
- }
- } else {
- /* It's a match, but they just typed a digit, and there is an ambiguous match,
- so just set the timeout to matchdigittimeout and wait some more */
- timeout = matchdigittimeout;
- }
- } else if (res == 0) {
- ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- zt_wait_event(p->subs[index].zfd);
- ast_hangup(chan);
- return NULL;
- } else if (p->callwaiting && !strcmp(exten, "*70")) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
- /* Disable call waiting if enabled */
- p->callwaiting = 0;
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- if (res) {
- ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
- chan->name, strerror(errno));
- }
- len = 0;
- ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
- memset(exten, 0, sizeof(exten));
- timeout = firstdigittimeout;
-
- } else if (!strcmp(exten,ast_pickup_ext())) {
- /* Scan all channels and see if there are any
- * ringing channels that have call groups
- * that equal this channels pickup group
- */
- if (index == SUB_REAL) {
- /* Switch us from Third call to Call Wait */
- if (p->subs[SUB_THREEWAY].owner) {
- /* If you make a threeway call and the *8# a call, it should actually
- look like a callwait */
- alloc_sub(p, SUB_CALLWAIT);
- swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
- unalloc_sub(p, SUB_THREEWAY);
- }
- zt_enable_ec(p);
- if (ast_pickup_call(chan)) {
- ast_log(LOG_DEBUG, "No call pickup possible...\n");
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- zt_wait_event(p->subs[index].zfd);
- }
- ast_hangup(chan);
- return NULL;
- } else {
- ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n");
- ast_hangup(chan);
- return NULL;
- }
-
- } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
- /* Disable Caller*ID if enabled */
- p->hidecallerid = 1;
- if (chan->cid.cid_num)
- free(chan->cid.cid_num);
- chan->cid.cid_num = NULL;
- if (chan->cid.cid_name)
- free(chan->cid.cid_name);
- chan->cid.cid_name = NULL;
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- if (res) {
- ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
- chan->name, strerror(errno));
- }
- len = 0;
- memset(exten, 0, sizeof(exten));
- timeout = firstdigittimeout;
- } else if (p->callreturn && !strcmp(exten, "*69")) {
- res = 0;
- if (!ast_strlen_zero(p->lastcid_num)) {
- res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
- }
- if (!res)
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- break;
- } else if (!strcmp(exten, "*78")) {
- /* Do not disturb */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
- manager_event(EVENT_FLAG_SYSTEM, "DNDState",
- "Channel: Zap/%d\r\n"
- "Status: enabled\r\n", p->channel);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- p->dnd = 1;
- getforward = 0;
- memset(exten, 0, sizeof(exten));
- len = 0;
- } else if (!strcmp(exten, "*79")) {
- /* Do not disturb */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
- manager_event(EVENT_FLAG_SYSTEM, "DNDState",
- "Channel: Zap/%d\r\n"
- "Status: disabled\r\n", p->channel);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- p->dnd = 0;
- getforward = 0;
- memset(exten, 0, sizeof(exten));
- len = 0;
- } else if (p->cancallforward && !strcmp(exten, "*72")) {
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- getforward = 1;
- memset(exten, 0, sizeof(exten));
- len = 0;
- } else if (p->cancallforward && !strcmp(exten, "*73")) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- memset(p->call_forward, 0, sizeof(p->call_forward));
- getforward = 0;
- memset(exten, 0, sizeof(exten));
- len = 0;
- } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) &&
- p->subs[SUB_THREEWAY].owner &&
- ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- /* This is a three way call, the main call being a real channel,
- and we're parking the first call. */
- ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
- break;
- } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
- res = ast_db_put("blacklist", p->lastcid_num, "1");
- if (!res) {
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- memset(exten, 0, sizeof(exten));
- len = 0;
- }
- } else if (p->hidecallerid && !strcmp(exten, "*82")) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
- /* Enable Caller*ID if enabled */
- p->hidecallerid = 0;
- if (chan->cid.cid_num)
- free(chan->cid.cid_num);
- chan->cid.cid_num = NULL;
- if (chan->cid.cid_name)
- free(chan->cid.cid_name);
- chan->cid.cid_name = NULL;
- ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
- if (res) {
- ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
- chan->name, strerror(errno));
- }
- len = 0;
- memset(exten, 0, sizeof(exten));
- timeout = firstdigittimeout;
- } else if (!strcmp(exten, "*0")) {
- struct ast_channel *nbridge =
- p->subs[SUB_THREEWAY].owner;
- struct zt_pvt *pbridge = NULL;
- /* set up the private struct of the bridged one, if any */
- if (nbridge && ast_bridged_channel(nbridge))
- pbridge = ast_bridged_channel(nbridge)->tech_pvt;
- if (nbridge && pbridge &&
- (nbridge->tech == &zap_tech) &&
- (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
- ISTRUNK(pbridge)) {
- int func = ZT_FLASH;
- /* Clear out the dial buffer */
- p->dop.dialstr[0] = '\0';
- /* flash hookswitch */
- if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
- ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
- nbridge->name, strerror(errno));
- }
- swap_subs(p, SUB_REAL, SUB_THREEWAY);
- unalloc_sub(p, SUB_THREEWAY);
- p->owner = p->subs[SUB_REAL].owner;
- if (ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
- ast_hangup(chan);
- return NULL;
- } else {
- tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- zt_wait_event(p->subs[index].zfd);
- tone_zone_play_tone(p->subs[index].zfd, -1);
- swap_subs(p, SUB_REAL, SUB_THREEWAY);
- unalloc_sub(p, SUB_THREEWAY);
- p->owner = p->subs[SUB_REAL].owner;
- ast_hangup(chan);
- return NULL;
- }
- } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
- ((exten[0] != '*') || (strlen(exten) > 2))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
- break;
- }
- if (!timeout)
- timeout = gendigittimeout;
- if (len && !ast_ignore_pattern(chan->context, exten))
- tone_zone_play_tone(p->subs[index].zfd, -1);
- }
- break;
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
-#ifdef HAVE_PRI
- if (p->pri) {
- /* This is a GR-303 trunk actually. Wait for the first ring... */
- struct ast_frame *f;
- int res;
- time_t start;
-
- time(&start);
- ast_setstate(chan, AST_STATE_RING);
- while (time(NULL) < start + 3) {
- res = ast_waitfor(chan, 1000);
- if (res) {
- f = ast_read(chan);
- if (!f) {
- ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
- ast_hangup(chan);
- return NULL;
- } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
- res = 1;
- } else
- res = 0;
- ast_frfree(f);
- if (res) {
- ast_log(LOG_DEBUG, "Got ring!\n");
- res = 0;
- break;
- }
- }
- }
- }
-#endif
- /* check for SMDI messages */
- if (p->use_smdi && p->smdi_iface) {
- smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
-
- if (smdi_msg != NULL) {
- ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
-
- if (smdi_msg->type == 'B')
- pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
- else if (smdi_msg->type == 'N')
- pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
-
- ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
- } else {
- ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
- }
- }
-
- if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
- number = smdi_msg->calling_st;
-
- /* If we want caller id, we're in a prering state due to a polarity reversal
- * and we're set to use a polarity reversal to trigger the start of caller id,
- * grab the caller id and wait for ringing to start... */
- } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
- /* If set to use DTMF CID signalling, listen for DTMF */
- if (p->cid_signalling == CID_SIG_DTMF) {
- int i = 0;
- cs = NULL;
- ast_log(LOG_DEBUG, "Receiving DTMF cid on "
- "channel %s\n", chan->name);
- zt_setlinear(p->subs[index].zfd, 0);
- res = 2000;
- for (;;) {
- struct ast_frame *f;
- res = ast_waitfor(chan, res);
- if (res <= 0) {
- ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
- "Exiting simple switch\n");
- ast_hangup(chan);
- return NULL;
- }
- f = ast_read(chan);
- if (!f)
- break;
- if (f->frametype == AST_FRAME_DTMF) {
- dtmfbuf[i++] = f->subclass;
- ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
- res = 2000;
- }
- ast_frfree(f);
- if (chan->_state == AST_STATE_RING ||
- chan->_state == AST_STATE_RINGING)
- break; /* Got ring */
- }
- dtmfbuf[i] = '\0';
- zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
- /* Got cid and ring. */
- ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
- callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
- ast_log(LOG_DEBUG, "CID is '%s', flags %d\n",
- dtmfcid, flags);
- /* If first byte is NULL, we have no cid */
- if (!ast_strlen_zero(dtmfcid))
- number = dtmfcid;
- else
- number = NULL;
- /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
- } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
- cs = callerid_new(p->cid_signalling);
- if (cs) {
- samples = 0;
-#if 1
- bump_gains(p);
-#endif
- /* Take out of linear mode for Caller*ID processing */
- zt_setlinear(p->subs[index].zfd, 0);
-
- /* First we wait and listen for the Caller*ID */
- for (;;) {
- i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
- if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) {
- ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- if (i & ZT_IOMUX_SIGEVENT) {
- res = zt_get_event(p->subs[index].zfd);
- ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
-
- if (p->cid_signalling == CID_SIG_V23_JP) {
-#ifdef ZT_EVENT_RINGBEGIN
- if (res == ZT_EVENT_RINGBEGIN) {
- res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- usleep(1);
- }
-#endif
- } else {
- res = 0;
- break;
- }
- } else if (i & ZT_IOMUX_READ) {
- res = read(p->subs[index].zfd, buf, sizeof(buf));
- if (res < 0) {
- if (errno != ELAST) {
- ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- break;
- }
- samples += res;
-
- if (p->cid_signalling == CID_SIG_V23_JP) {
- res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
- } else {
- res = callerid_feed(cs, buf, res, AST_LAW(p));
- }
-
- if (res < 0) {
- ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
- break;
- } else if (res)
- break;
- else if (samples > (8000 * 10))
- break;
- }
- }
- if (res == 1) {
- callerid_get(cs, &name, &number, &flags);
- ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
- }
-
- if (p->cid_signalling == CID_SIG_V23_JP) {
- res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
- usleep(1);
- res = 4000;
- } else {
-
- /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
- res = 2000;
- }
-
- for (;;) {
- struct ast_frame *f;
- res = ast_waitfor(chan, res);
- if (res <= 0) {
- ast_log(LOG_WARNING, "CID timed out waiting for ring. "
- "Exiting simple switch\n");
- ast_hangup(chan);
- return NULL;
- }
- f = ast_read(chan);
- ast_frfree(f);
- if (chan->_state == AST_STATE_RING ||
- chan->_state == AST_STATE_RINGING)
- break; /* Got ring */
- }
-
- /* We must have a ring by now, so, if configured, lets try to listen for
- * distinctive ringing */
- if (p->usedistinctiveringdetection == 1) {
- len = 0;
- distMatches = 0;
- /* Clear the current ring data array so we dont have old data in it. */
- for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
- curRingData[receivedRingT] = 0;
- receivedRingT = 0;
- counter = 0;
- counter1 = 0;
- /* Check to see if context is what it should be, if not set to be. */
- if (strcmp(p->context,p->defcontext) != 0) {
- ast_copy_string(p->context, p->defcontext, sizeof(p->context));
- ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
- }
-
- for (;;) {
- i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
- if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) {
- ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- if (i & ZT_IOMUX_SIGEVENT) {
- res = zt_get_event(p->subs[index].zfd);
- ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
- res = 0;
- /* Let us detect distinctive ring */
-
- curRingData[receivedRingT] = p->ringt;
-
- if (p->ringt < p->ringt_base/2)
- break;
- /* Increment the ringT counter so we can match it against
- values in zapata.conf for distinctive ring */
- if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
- break;
- } else if (i & ZT_IOMUX_READ) {
- res = read(p->subs[index].zfd, buf, sizeof(buf));
- if (res < 0) {
- if (errno != ELAST) {
- ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- break;
- }
- if (p->ringt)
- p->ringt--;
- if (p->ringt == 1) {
- res = -1;
- break;
- }
- }
- }
- if (option_verbose > 2)
- /* this only shows up if you have n of the dring patterns filled in */
- ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
-
- for (counter = 0; counter < 3; counter++) {
- /* Check to see if the rings we received match any of the ones in zapata.conf for this
- channel */
- distMatches = 0;
- for (counter1 = 0; counter1 < 3; counter1++) {
- if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
- (p->drings.ringnum[counter].ring[counter1]-10)) {
- distMatches++;
- }
- }
- if (distMatches == 3) {
- /* The ring matches, set the context to whatever is for distinctive ring.. */
- ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
- ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
- break;
- }
- }
- }
- /* Restore linear mode (if appropriate) for Caller*ID processing */
- zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
-#if 1
- restore_gains(p);
-#endif
- } else
- ast_log(LOG_WARNING, "Unable to get caller ID space\n");
- } else {
- ast_log(LOG_WARNING, "Channel %s in prering "
- "state, but I have nothing to do. "
- "Terminating simple switch, should be "
- "restarted by the actual ring.\n",
- chan->name);
- ast_hangup(chan);
- return NULL;
- }
- } else if (p->use_callerid && p->cid_start == CID_START_RING) {
- /* FSK Bell202 callerID */
- cs = callerid_new(p->cid_signalling);
- if (cs) {
-#if 1
- bump_gains(p);
-#endif
- samples = 0;
- len = 0;
- distMatches = 0;
- /* Clear the current ring data array so we dont have old data in it. */
- for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
- curRingData[receivedRingT] = 0;
- receivedRingT = 0;
- counter = 0;
- counter1 = 0;
- /* Check to see if context is what it should be, if not set to be. */
- if (strcmp(p->context,p->defcontext) != 0) {
- ast_copy_string(p->context, p->defcontext, sizeof(p->context));
- ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
- }
-
- /* Take out of linear mode for Caller*ID processing */
- zt_setlinear(p->subs[index].zfd, 0);
- for (;;) {
- i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
- if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) {
- ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- if (i & ZT_IOMUX_SIGEVENT) {
- res = zt_get_event(p->subs[index].zfd);
- ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
- /* If we get a PR event, they hung up while processing calerid */
- if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
- ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
- p->polarity = POLARITY_IDLE;
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- res = 0;
- /* Let us detect callerid when the telco uses distinctive ring */
-
- curRingData[receivedRingT] = p->ringt;
-
- if (p->ringt < p->ringt_base/2)
- break;
- /* Increment the ringT counter so we can match it against
- values in zapata.conf for distinctive ring */
- if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
- break;
- } else if (i & ZT_IOMUX_READ) {
- res = read(p->subs[index].zfd, buf, sizeof(buf));
- if (res < 0) {
- if (errno != ELAST) {
- ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- break;
- }
- if (p->ringt)
- p->ringt--;
- if (p->ringt == 1) {
- res = -1;
- break;
- }
- samples += res;
- res = callerid_feed(cs, buf, res, AST_LAW(p));
- if (res < 0) {
- ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
- break;
- } else if (res)
- break;
- else if (samples > (8000 * 10))
- break;
- }
- }
- if (res == 1) {
- callerid_get(cs, &name, &number, &flags);
- if (option_debug)
- ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
- }
- if (distinctiveringaftercid == 1) {
- /* Clear the current ring data array so we dont have old data in it. */
- for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
- curRingData[receivedRingT] = 0;
- }
- receivedRingT = 0;
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
- for (;;) {
- i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
- if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) {
- ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- if (i & ZT_IOMUX_SIGEVENT) {
- res = zt_get_event(p->subs[index].zfd);
- ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
- res = 0;
- /* Let us detect callerid when the telco uses distinctive ring */
-
- curRingData[receivedRingT] = p->ringt;
-
- if (p->ringt < p->ringt_base/2)
- break;
- /* Increment the ringT counter so we can match it against
- values in zapata.conf for distinctive ring */
- if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
- break;
- } else if (i & ZT_IOMUX_READ) {
- res = read(p->subs[index].zfd, buf, sizeof(buf));
- if (res < 0) {
- if (errno != ELAST) {
- ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- return NULL;
- }
- break;
- }
- if (p->ringt)
- p->ringt--;
- if (p->ringt == 1) {
- res = -1;
- break;
- }
- }
- }
- }
- if (p->usedistinctiveringdetection == 1) {
- if (option_verbose > 2)
- /* this only shows up if you have n of the dring patterns filled in */
- ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
-
- for (counter = 0; counter < 3; counter++) {
- /* Check to see if the rings we received match any of the ones in zapata.conf for this
- channel */
- if (option_verbose > 2)
- /* this only shows up if you have n of the dring patterns filled in */
- ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
- p->drings.ringnum[counter].ring[0],
- p->drings.ringnum[counter].ring[1],
- p->drings.ringnum[counter].ring[2]);
- distMatches = 0;
- for (counter1 = 0; counter1 < 3; counter1++) {
- if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
- (p->drings.ringnum[counter].ring[counter1]-10)) {
- distMatches++;
- }
- }
- if (distMatches == 3) {
- /* The ring matches, set the context to whatever is for distinctive ring.. */
- ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
- ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
- break;
- }
- }
- }
- /* Restore linear mode (if appropriate) for Caller*ID processing */
- zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
-#if 1
- restore_gains(p);
-#endif
- if (res < 0) {
- ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
- }
- } else
- ast_log(LOG_WARNING, "Unable to get caller ID space\n");
- }
- else
- cs = NULL;
-
- if (number)
- ast_shrink_phone_number(number);
- ast_set_callerid(chan, number, name, number);
-
- if (smdi_msg)
- ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
-
- if (cs)
- callerid_free(cs);
-
- ast_setstate(chan, AST_STATE_RING);
- chan->rings = 1;
- p->ringt = p->ringt_base;
- res = ast_pbx_run(chan);
- if (res) {
- ast_hangup(chan);
- ast_log(LOG_WARNING, "PBX exited non-zero\n");
- }
- return NULL;
- default:
- ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
- }
- res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
- ast_hangup(chan);
- return NULL;
-}
-
-/* destroy a zaptel channel, identified by its number */
-static int zap_destroy_channel_bynum(int channel)
-{
- struct zt_pvt *tmp = NULL;
- struct zt_pvt *prev = NULL;
-
- tmp = iflist;
- while (tmp) {
- if (tmp->channel == channel) {
- destroy_channel(prev, tmp, 1);
- return RESULT_SUCCESS;
- }
- prev = tmp;
- tmp = tmp->next;
- }
- return RESULT_FAILURE;
-}
-
-static int handle_init_event(struct zt_pvt *i, int event)
-{
- int res;
- pthread_t threadid;
- pthread_attr_t attr;
- struct ast_channel *chan;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- /* Handle an event on a given channel for the monitor thread. */
- switch (event) {
- case ZT_EVENT_NONE:
- case ZT_EVENT_BITSCHANGED:
- break;
- case ZT_EVENT_WINKFLASH:
- case ZT_EVENT_RINGOFFHOOK:
- if (i->inalarm) break;
- if (i->radio) break;
- /* Got a ring/answer. What kind of channel are we? */
- switch (i->sig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- if (res && (errno == EBUSY))
- break;
- if (i->cidspill) {
- /* Cancel VMWI spill */
- free(i->cidspill);
- i->cidspill = NULL;
- }
- if (i->immediate) {
- zt_enable_ec(i);
- /* The channel is immediately up. Start right away */
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
- chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
- if (!chan) {
- ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
- }
- } else {
- /* Check for callerid, digits, etc */
- chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
- if (chan) {
- if (has_voicemail(i))
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
- else
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
- if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
- ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
- ast_hangup(chan);
- }
- } else
- ast_log(LOG_WARNING, "Unable to create channel\n");
- }
- break;
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
- i->ringt = i->ringt_base;
- /* Fall through */
- case SIG_EMWINK:
- case SIG_FEATD:
- case SIG_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_E911:
- case SIG_FGC_CAMA:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_SFWINK:
- case SIG_SF_FEATD:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- case SIG_SF:
- /* Check for callerid, digits, etc */
- chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
- if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
- ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
- ast_hangup(chan);
- } else if (!chan) {
- ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
- }
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
- return -1;
- }
- break;
- case ZT_EVENT_NOALARM:
- i->inalarm = 0;
- if (!i->unknown_alarm) {
- ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
- manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
- "Channel: %d\r\n", i->channel);
- } else {
- i->unknown_alarm = 0;
- }
- break;
- case ZT_EVENT_ALARM:
- i->inalarm = 1;
- res = get_alarms(i);
- do {
- const char *alarm_str = alarm2str(res);
-
- /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
- * doesn't know what to do with it. Don't confuse users with log messages. */
- if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
- i->unknown_alarm = 1;
- break;
- } else {
- i->unknown_alarm = 0;
- }
-
- ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str);
- manager_event(EVENT_FLAG_SYSTEM, "Alarm",
- "Alarm: %s\r\n"
- "Channel: %d\r\n",
- alarm_str, i->channel);
- } while (0);
- /* fall thru intentionally */
- case ZT_EVENT_ONHOOK:
- if (i->radio)
- break;
- /* Back on hook. Hang up. */
- switch (i->sig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FEATD:
- case SIG_FEATDMF:
- case SIG_FEATDMF_TA:
- case SIG_E911:
- case SIG_FGC_CAMA:
- case SIG_FGC_CAMAMF:
- case SIG_FEATB:
- case SIG_EM:
- case SIG_EM_E1:
- case SIG_EMWINK:
- case SIG_SF_FEATD:
- case SIG_SF_FEATDMF:
- case SIG_SF_FEATB:
- case SIG_SF:
- case SIG_SFWINK:
- case SIG_FXSLS:
- case SIG_FXSGS:
- case SIG_FXSKS:
- case SIG_GR303FXSKS:
- zt_disable_ec(i);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
- zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
- break;
- case SIG_GR303FXOKS:
- case SIG_FXOKS:
- zt_disable_ec(i);
- /* Diddle the battery for the zhone */
-#ifdef ZHONE_HACK
- zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
- usleep(1);
-#endif
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
- zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
- break;
- case SIG_PRI:
- zt_disable_ec(i);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
- return -1;
- }
- break;
- case ZT_EVENT_POLARITY:
- switch (i->sig) {
- case SIG_FXSLS:
- case SIG_FXSKS:
- case SIG_FXSGS:
- /* We have already got a PR before the channel was
- created, but it wasn't handled. We need polarity
- to be REV for remote hangup detection to work.
- At least in Spain */
- if (i->hanguponpolarityswitch)
- i->polarity = POLARITY_REV;
-
- if (i->cid_start == CID_START_POLARITY) {
- i->polarity = POLARITY_REV;
- ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
- "CID detection on channel %d\n",
- i->channel);
- chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
- if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
- ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
- }
- }
- break;
- default:
- ast_log(LOG_WARNING, "handle_init_event detected "
- "polarity reversal on non-FXO (SIG_FXS) "
- "interface %d\n", i->channel);
- }
- break;
- case ZT_EVENT_REMOVED: /* destroy channel */
- ast_log(LOG_NOTICE,
- "Got ZT_EVENT_REMOVED. Destroying channel %d\n",
- i->channel);
- zap_destroy_channel_bynum(i->channel);
- break;
- }
- pthread_attr_destroy(&attr);
- return 0;
-}
-
-static void *do_monitor(void *data)
-{
- int count, res, res2, spoint, pollres=0;
- struct zt_pvt *i;
- struct zt_pvt *last = NULL;
- time_t thispass = 0, lastpass = 0;
- int found;
- char buf[1024];
- struct pollfd *pfds=NULL;
- int lastalloc = -1;
- /* This thread monitors all the frame relay interfaces which are not yet in use
- (and thus do not have a separate thread) indefinitely */
- /* From here on out, we die whenever asked */
-#if 0
- if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
- ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
- return NULL;
- }
- ast_log(LOG_DEBUG, "Monitor starting...\n");
-#endif
- for (;;) {
- /* Lock the interface list */
- ast_mutex_lock(&iflock);
- if (!pfds || (lastalloc != ifcount)) {
- if (pfds) {
- free(pfds);
- pfds = NULL;
- }
- if (ifcount) {
- if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
- ast_mutex_unlock(&iflock);
- return NULL;
- }
- }
- lastalloc = ifcount;
- }
- /* Build the stuff we're going to poll on, that is the socket of every
- zt_pvt that does not have an associated owner channel */
- count = 0;
- i = iflist;
- while (i) {
- if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
- if (!i->owner && !i->subs[SUB_REAL].owner) {
- /* This needs to be watched, as it lacks an owner */
- pfds[count].fd = i->subs[SUB_REAL].zfd;
- pfds[count].events = POLLPRI;
- pfds[count].revents = 0;
- /* Message waiting or r2 channels also get watched for reading */
- if (i->cidspill)
- pfds[count].events |= POLLIN;
- count++;
- }
- }
- i = i->next;
- }
- /* Okay, now that we know what to do, release the interface lock */
- ast_mutex_unlock(&iflock);
-
- pthread_testcancel();
- /* Wait at least a second for something to happen */
- res = poll(pfds, count, 1000);
- pthread_testcancel();
- /* Okay, poll has finished. Let's see what happened. */
- if (res < 0) {
- if ((errno != EAGAIN) && (errno != EINTR))
- ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
- continue;
- }
- /* Alright, lock the interface list again, and let's look and see what has
- happened */
- ast_mutex_lock(&iflock);
- found = 0;
- spoint = 0;
- lastpass = thispass;
- thispass = time(NULL);
- i = iflist;
- while (i) {
- if (thispass != lastpass) {
- if (!found && ((i == last) || ((i == iflist) && !last))) {
- last = i;
- if (last) {
- if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
- (last->sig & __ZT_SIG_FXO)) {
- res = ast_app_has_voicemail(last->mailbox, NULL);
- if (last->msgstate != res) {
- int x;
- ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
- x = ZT_FLUSH_BOTH;
- res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
- if (res2)
- ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
- if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
- /* Turn on on hook transfer for 4 seconds */
- x = 4000;
- ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
- last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
- last->cidpos = 0;
- last->msgstate = res;
- last->onhooktime = thispass;
- }
- found ++;
- }
- }
- last = last->next;
- }
- }
- }
- if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
- if (i->radio && !i->owner)
- {
- res = zt_get_event(i->subs[SUB_REAL].zfd);
- if (res)
- {
- if (option_debug)
- ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
- /* Don't hold iflock while handling init events */
- ast_mutex_unlock(&iflock);
- handle_init_event(i, res);
- ast_mutex_lock(&iflock);
- }
- i = i->next;
- continue;
- }
- pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
- if (pollres & POLLIN) {
- if (i->owner || i->subs[SUB_REAL].owner) {
-#ifdef HAVE_PRI
- if (!i->pri)
-#endif
- ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
- i = i->next;
- continue;
- }
- if (!i->cidspill) {
- ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
- i = i->next;
- continue;
- }
- res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
- if (res > 0) {
- /* We read some number of bytes. Write an equal amount of data */
- if (res > i->cidlen - i->cidpos)
- res = i->cidlen - i->cidpos;
- res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
- if (res2 > 0) {
- i->cidpos += res2;
- if (i->cidpos >= i->cidlen) {
- free(i->cidspill);
- i->cidspill = 0;
- i->cidpos = 0;
- i->cidlen = 0;
- }
- } else {
- ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
- i->msgstate = -1;
- }
- } else {
- ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
- }
- }
- if (pollres & POLLPRI) {
- if (i->owner || i->subs[SUB_REAL].owner) {
-#ifdef HAVE_PRI
- if (!i->pri)
-#endif
- ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
- i = i->next;
- continue;
- }
- res = zt_get_event(i->subs[SUB_REAL].zfd);
- if (option_debug)
- ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
- /* Don't hold iflock while handling init events */
- ast_mutex_unlock(&iflock);
- handle_init_event(i, res);
- ast_mutex_lock(&iflock);
- }
- }
- i=i->next;
- }
- ast_mutex_unlock(&iflock);
- }
- /* Never reached */
- return NULL;
-
-}
-
-static int restart_monitor(void)
-{
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- /* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == AST_PTHREADT_STOP)
- return 0;
- ast_mutex_lock(&monlock);
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread != AST_PTHREADT_NULL) {
- /* Wake up the thread */
- pthread_kill(monitor_thread, SIGURG);
- } else {
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- pthread_attr_destroy(&attr);
- return -1;
- }
- }
- ast_mutex_unlock(&monlock);
- pthread_attr_destroy(&attr);
- return 0;
-}
-
-#ifdef HAVE_PRI
-static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
-{
- int x;
- int trunkgroup;
- /* Get appropriate trunk group if there is one */
- trunkgroup = pris[*span].mastertrunkgroup;
- if (trunkgroup) {
- /* Select a specific trunk group */
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].trunkgroup == trunkgroup) {
- *span = x;
- return 0;
- }
- }
- ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
- *span = -1;
- } else {
- if (pris[*span].trunkgroup) {
- ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
- *span = -1;
- } else if (pris[*span].mastertrunkgroup) {
- ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
- *span = -1;
- } else {
- if (si->totalchans == 31) { /* if it's an E1 */
- pris[*span].dchannels[0] = 16 + offset;
- } else {
- pris[*span].dchannels[0] = 24 + offset;
- }
- pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
- pris[*span].offset = offset;
- pris[*span].span = *span + 1;
- }
- }
- return 0;
-}
-
-static int pri_create_trunkgroup(int trunkgroup, int *channels)
-{
- struct zt_spaninfo si;
- ZT_PARAMS p;
- int fd;
- int span;
- int ospan=0;
- int x,y;
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].trunkgroup == trunkgroup) {
- ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
- return -1;
- }
- }
- for (y = 0; y < NUM_DCHANS; y++) {
- if (!channels[y])
- break;
- memset(&si, 0, sizeof(si));
- memset(&p, 0, sizeof(p));
- fd = open("/dev/zap/channel", O_RDWR);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
- return -1;
- }
- x = channels[y];
- if (ioctl(fd, ZT_SPECIFY, &x)) {
- ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
- zt_close(fd);
- return -1;
- }
- if (ioctl(fd, ZT_GET_PARAMS, &p)) {
- ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
- return -1;
- }
- if (ioctl(fd, ZT_SPANSTAT, &si)) {
- ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
- zt_close(fd);
- return -1;
- }
- span = p.spanno - 1;
- if (pris[span].trunkgroup) {
- ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
- zt_close(fd);
- return -1;
- }
- if (pris[span].pvts[0]) {
- ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
- zt_close(fd);
- return -1;
- }
- if (!y) {
- pris[span].trunkgroup = trunkgroup;
- pris[span].offset = channels[y] - p.chanpos;
- ospan = span;
- }
- pris[ospan].dchannels[y] = channels[y];
- pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
- pris[span].span = span + 1;
- zt_close(fd);
- }
- return 0;
-}
-
-static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
-{
- if (pris[span].mastertrunkgroup) {
- ast_log(LOG_WARNING, "Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup);
- return -1;
- }
- pris[span].mastertrunkgroup = trunkgroup;
- pris[span].prilogicalspan = logicalspan;
- return 0;
-}
-
-#endif
-
-static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
-{
- /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
- struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL;
- char fn[80];
-#if 1
- struct zt_bufferinfo bi;
-#endif
- struct zt_spaninfo si;
- int res;
- int span=0;
- int here = 0;
- int x;
- struct zt_pvt **wlist;
- struct zt_pvt **wend;
- ZT_PARAMS p;
-
- wlist = &iflist;
- wend = &ifend;
-
-#ifdef HAVE_PRI
- if (pri) {
- wlist = &pri->crvs;
- wend = &pri->crvend;
- }
-#endif
-
- tmp2 = *wlist;
- prev = NULL;
-
- while (tmp2) {
- if (!tmp2->destroy) {
- if (tmp2->channel == channel) {
- tmp = tmp2;
- here = 1;
- break;
- }
- if (tmp2->channel > channel) {
- break;
- }
- }
- prev = tmp2;
- tmp2 = tmp2->next;
- }
-
- if (!here && !reloading) {
- if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- ast_mutex_init(&tmp->lock);
- ifcount++;
- for (x = 0; x < 3; x++)
- tmp->subs[x].zfd = -1;
- tmp->channel = channel;
- }
-
- if (tmp) {
- if (!here) {
- if ((channel != CHAN_PSEUDO) && !pri) {
- snprintf(fn, sizeof(fn), "%d", channel);
- /* Open non-blocking */
- if (!here)
- tmp->subs[SUB_REAL].zfd = zt_open(fn);
- /* Allocate a zapata structure */
- if (tmp->subs[SUB_REAL].zfd < 0) {
- ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- memset(&p, 0, sizeof(p));
- res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
- if (res < 0) {
- ast_log(LOG_ERROR, "Unable to get parameters\n");
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
- ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(conf.chan.sig), sig2str(p.sigtype));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- tmp->law = p.curlaw;
- tmp->span = p.spanno;
- span = p.spanno - 1;
- } else {
- if (channel == CHAN_PSEUDO)
- conf.chan.sig = 0;
- else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
- ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
- return NULL;
- }
- }
-#ifdef HAVE_PRI
- if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
- int offset;
- int myswitchtype;
- int matchesdchan;
- int x,y;
- offset = 0;
- if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
- ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (span >= NUM_SPANS) {
- ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
- destroy_zt_pvt(&tmp);
- return NULL;
- } else {
- si.spanno = 0;
- if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
- ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- /* Store the logical span first based upon the real span */
- tmp->logicalspan = pris[span].prilogicalspan;
- pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
- if (span < 0) {
- ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (conf.chan.sig == SIG_PRI)
- myswitchtype = conf.pri.switchtype;
- else
- myswitchtype = PRI_SWITCH_GR303_TMC;
- /* Make sure this isn't a d-channel */
- matchesdchan=0;
- for (x = 0; x < NUM_SPANS; x++) {
- for (y = 0; y < NUM_DCHANS; y++) {
- if (pris[x].dchannels[y] == tmp->channel) {
- matchesdchan = 1;
- break;
- }
- }
- }
- offset = p.chanpos;
- if (!matchesdchan) {
- if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
- ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
- ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
- ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
- ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
- ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
- ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
- ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (pris[span].numchans >= MAX_CHANNELS) {
- ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
- pris[span].trunkgroup);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- pris[span].nodetype = conf.pri.nodetype;
- pris[span].switchtype = myswitchtype;
- pris[span].nsf = conf.pri.nsf;
- pris[span].dialplan = conf.pri.dialplan;
- pris[span].localdialplan = conf.pri.localdialplan;
- pris[span].pvts[pris[span].numchans++] = tmp;
- pris[span].minunused = conf.pri.minunused;
- pris[span].minidle = conf.pri.minidle;
- pris[span].overlapdial = conf.pri.overlapdial;
- pris[span].facilityenable = conf.pri.facilityenable;
- ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
- ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
- ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
- ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
- ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
- ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
- ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
- pris[span].resetinterval = conf.pri.resetinterval;
-
- tmp->pri = &pris[span];
- tmp->prioffset = offset;
- tmp->call = NULL;
- } else {
- ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- }
- } else {
- tmp->prioffset = 0;
- }
-#endif
- } else {
- conf.chan.sig = tmp->sig;
- conf.chan.radio = tmp->radio;
- memset(&p, 0, sizeof(p));
- if (tmp->subs[SUB_REAL].zfd > -1)
- res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
- }
- /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
- if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
- (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) || (conf.chan.sig == SIG_EMWINK) ||
- (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
- (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
- (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
- (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
- (conf.chan.sig == SIG_SF_FEATB)) {
- p.starttime = 250;
- }
- if (conf.chan.radio) {
- /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
- p.channo = channel;
- p.rxwinktime = 1;
- p.rxflashtime = 1;
- p.starttime = 1;
- p.debouncetime = 5;
- }
- if (!conf.chan.radio) {
- p.channo = channel;
- /* Override timing settings based on config file */
- if (conf.timing.prewinktime >= 0)
- p.prewinktime = conf.timing.prewinktime;
- if (conf.timing.preflashtime >= 0)
- p.preflashtime = conf.timing.preflashtime;
- if (conf.timing.winktime >= 0)
- p.winktime = conf.timing.winktime;
- if (conf.timing.flashtime >= 0)
- p.flashtime = conf.timing.flashtime;
- if (conf.timing.starttime >= 0)
- p.starttime = conf.timing.starttime;
- if (conf.timing.rxwinktime >= 0)
- p.rxwinktime = conf.timing.rxwinktime;
- if (conf.timing.rxflashtime >= 0)
- p.rxflashtime = conf.timing.rxflashtime;
- if (conf.timing.debouncetime >= 0)
- p.debouncetime = conf.timing.debouncetime;
- }
-
- /* dont set parms on a pseudo-channel (or CRV) */
- if (tmp->subs[SUB_REAL].zfd >= 0)
- {
- res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
- if (res < 0) {
- ast_log(LOG_ERROR, "Unable to set parameters\n");
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- }
-#if 1
- if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
- memset(&bi, 0, sizeof(bi));
- res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
- if (!res) {
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = numbufs;
- res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
- }
- } else
- ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
- }
-#endif
- tmp->immediate = conf.chan.immediate;
- tmp->transfertobusy = conf.chan.transfertobusy;
- tmp->sig = conf.chan.sig;
- tmp->outsigmod = conf.chan.outsigmod;
- tmp->radio = conf.chan.radio;
- tmp->ringt_base = ringt_base;
- tmp->firstradio = 0;
- if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
- tmp->permcallwaiting = conf.chan.callwaiting;
- else
- tmp->permcallwaiting = 0;
- /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
- tmp->destroy = 0;
- tmp->drings = drings;
- tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection;
- tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
- tmp->threewaycalling = conf.chan.threewaycalling;
- tmp->adsi = conf.chan.adsi;
- tmp->use_smdi = conf.chan.use_smdi;
- tmp->permhidecallerid = conf.chan.hidecallerid;
- tmp->callreturn = conf.chan.callreturn;
- tmp->echocancel = conf.chan.echocancel;
- tmp->echotraining = conf.chan.echotraining;
- tmp->pulse = conf.chan.pulse;
- if (tmp->echocancel)
- tmp->echocanbridged = conf.chan.echocanbridged;
- else {
- if (conf.chan.echocanbridged)
- ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
- tmp->echocanbridged = 0;
- }
- tmp->busydetect = conf.chan.busydetect;
- tmp->busycount = conf.chan.busycount;
- tmp->busy_tonelength = conf.chan.busy_tonelength;
- tmp->busy_quietlength = conf.chan.busy_quietlength;
- tmp->callprogress = conf.chan.callprogress;
- tmp->cancallforward = conf.chan.cancallforward;
- tmp->dtmfrelax = conf.chan.dtmfrelax;
- tmp->callwaiting = tmp->permcallwaiting;
- tmp->hidecallerid = tmp->permhidecallerid;
- tmp->channel = channel;
- tmp->stripmsd = conf.chan.stripmsd;
- tmp->use_callerid = conf.chan.use_callerid;
- tmp->cid_signalling = conf.chan.cid_signalling;
- tmp->cid_start = conf.chan.cid_start;
- tmp->zaptrcallerid = conf.chan.zaptrcallerid;
- tmp->restrictcid = conf.chan.restrictcid;
- tmp->use_callingpres = conf.chan.use_callingpres;
- tmp->priindication_oob = conf.chan.priindication_oob;
- tmp->priexclusive = conf.chan.priexclusive;
- if (tmp->usedistinctiveringdetection) {
- if (!tmp->use_callerid) {
- ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
- tmp->use_callerid = 1;
- }
- }
-
- if (tmp->cid_signalling == CID_SIG_SMDI) {
- if (!tmp->use_smdi) {
- ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
- tmp->use_smdi = 1;
- }
- }
- if (tmp->use_smdi) {
- tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
- if (!(tmp->smdi_iface)) {
- ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
- tmp->use_smdi = 0;
- }
- }
-
- ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
- tmp->amaflags = conf.chan.amaflags;
- if (!here) {
- tmp->confno = -1;
- tmp->propconfno = -1;
- }
- tmp->canpark = conf.chan.canpark;
- tmp->transfer = conf.chan.transfer;
- ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
- ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
- ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
- ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
- ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
- ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
- tmp->cid_ton = 0;
- ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
- ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
- tmp->msgstate = -1;
- tmp->group = conf.chan.group;
- tmp->callgroup = conf.chan.callgroup;
- tmp->pickupgroup= conf.chan.pickupgroup;
- tmp->rxgain = conf.chan.rxgain;
- tmp->txgain = conf.chan.txgain;
- tmp->tonezone = conf.chan.tonezone;
- tmp->onhooktime = time(NULL);
- if (tmp->subs[SUB_REAL].zfd > -1) {
- set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
- if (tmp->dsp)
- ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
- update_conf(tmp);
- if (!here) {
- if (conf.chan.sig != SIG_PRI)
- /* Hang it up to be sure it's good */
- zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
- }
- ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
-#ifdef HAVE_PRI
- /* the dchannel is down so put the channel in alarm */
- if (tmp->pri && !pri_is_up(tmp->pri))
- tmp->inalarm = 1;
- else
- tmp->inalarm = 0;
-#endif
- memset(&si, 0, sizeof(si));
- if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
- ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
- destroy_zt_pvt(&tmp);
- return NULL;
- }
- if (si.alarms) tmp->inalarm = 1;
- }
-
- tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay;
- tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch;
- tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch;
- tmp->sendcalleridafter = conf.chan.sendcalleridafter;
-
- }
- if (tmp && !here) {
- /* nothing on the iflist */
- if (!*wlist) {
- *wlist = tmp;
- tmp->prev = NULL;
- tmp->next = NULL;
- *wend = tmp;
- } else {
- /* at least one member on the iflist */
- struct zt_pvt *working = *wlist;
-
- /* check if we maybe have to put it on the begining */
- if (working->channel > tmp->channel) {
- tmp->next = *wlist;
- tmp->prev = NULL;
- (*wlist)->prev = tmp;
- *wlist = tmp;
- } else {
- /* go through all the members and put the member in the right place */
- while (working) {
- /* in the middle */
- if (working->next) {
- if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
- tmp->next = working->next;
- tmp->prev = working;
- working->next->prev = tmp;
- working->next = tmp;
- break;
- }
- } else {
- /* the last */
- if (working->channel < tmp->channel) {
- working->next = tmp;
- tmp->next = NULL;
- tmp->prev = working;
- *wend = tmp;
- break;
- }
- }
- working = working->next;
- }
- }
- }
- }
- return tmp;
-}
-
-static inline int available(struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
-{
- int res;
- ZT_PARAMS par;
-
- /* First, check group matching */
- if (groupmatch) {
- if ((p->group & groupmatch) != groupmatch)
- return 0;
- *groupmatched = 1;
- }
- /* Check to see if we have a channel match */
- if (channelmatch != -1) {
- if (p->channel != channelmatch)
- return 0;
- *channelmatched = 1;
- }
- /* We're at least busy at this point */
- if (busy) {
- if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
- *busy = 1;
- }
- /* If do not disturb, definitely not */
- if (p->dnd)
- return 0;
- /* If guard time, definitely not */
- if (p->guardtime && (time(NULL) < p->guardtime))
- return 0;
-
- /* If no owner definitely available */
- if (!p->owner) {
-#ifdef HAVE_PRI
- /* Trust PRI */
- if (p->pri) {
- if (p->resetting || p->call)
- return 0;
- else
- return 1;
- }
-#endif
- if (!(p->radio || (p->oprmode < 0)))
- {
- if (!p->sig || (p->sig == SIG_FXSLS))
- return 1;
- /* Check hook state */
- if (p->subs[SUB_REAL].zfd > -1)
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
- else {
- /* Assume not off hook on CVRS */
- res = 0;
- par.rxisoffhook = 0;
- }
- if (res) {
- ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
- } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
- /* When "onhook" that means no battery on the line, and thus
- it is out of service..., if it's on a TDM card... If it's a channel
- bank, there is no telling... */
- if (par.rxbits > -1)
- return 1;
- if (par.rxisoffhook)
- return 1;
- else
-#ifdef ZAP_CHECK_HOOKSTATE
- return 0;
-#else
- return 1;
-#endif
- } else if (par.rxisoffhook) {
- ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
- /* Not available when the other end is off hook */
- return 0;
- }
- }
- return 1;
- }
-
- /* If it's not an FXO, forget about call wait */
- if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS))
- return 0;
-
- if (!p->callwaiting) {
- /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
- return 0;
- }
-
- if (p->subs[SUB_CALLWAIT].zfd > -1) {
- /* If there is already a call waiting call, then we can't take a second one */
- return 0;
- }
-
- if ((p->owner->_state != AST_STATE_UP) &&
- ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
- /* If the current call is not up, then don't allow the call */
- return 0;
- }
- if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
- /* Can't take a call wait when the three way calling hasn't been merged yet. */
- return 0;
- }
- /* We're cool */
- return 1;
-}
-
-static struct zt_pvt *chandup(struct zt_pvt *src)
-{
- struct zt_pvt *p;
- ZT_BUFFERINFO bi;
- int res;
-
- if ((p = ast_malloc(sizeof(*p)))) {
- memcpy(p, src, sizeof(struct zt_pvt));
- ast_mutex_init(&p->lock);
- p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
- /* Allocate a zapata structure */
- if (p->subs[SUB_REAL].zfd < 0) {
- ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
- destroy_zt_pvt(&p);
- return NULL;
- }
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
- if (!res) {
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = numbufs;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
- }
- } else
- ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
- }
- p->destroy = 1;
- p->next = iflist;
- p->prev = NULL;
- iflist = p;
- if (iflist->next)
- iflist->next->prev = p;
- return p;
-}
-
-
-#ifdef HAVE_PRI
-static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
-{
- int x;
- if (backwards)
- x = pri->numchans;
- else
- x = 0;
- for (;;) {
- if (backwards && (x < 0))
- break;
- if (!backwards && (x >= pri->numchans))
- break;
- if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
- ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n",
- pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
- return x;
- }
- if (backwards)
- x--;
- else
- x++;
- }
- return -1;
-}
-#endif
-
-static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
-{
- ast_group_t groupmatch = 0;
- int channelmatch = -1;
- int roundrobin = 0;
- int callwait = 0;
- int busy = 0;
- struct zt_pvt *p;
- struct ast_channel *tmp = NULL;
- char *dest=NULL;
- int x;
- char *s;
- char opt=0;
- int res=0, y=0;
- int backwards = 0;
-#ifdef HAVE_PRI
- int crv;
- int bearer = -1;
- int trunkgroup;
- struct zt_pri *pri=NULL;
-#endif
- struct zt_pvt *exit, *start, *end;
- ast_mutex_t *lock;
- int channelmatched = 0;
- int groupmatched = 0;
-
- /* Assume we're locking the iflock */
- lock = &iflock;
- start = iflist;
- end = ifend;
- if (data) {
- dest = ast_strdupa((char *)data);
- } else {
- ast_log(LOG_WARNING, "Channel requested with no data\n");
- return NULL;
- }
- if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
- /* Retrieve the group number */
- char *stringp=NULL;
- stringp=dest + 1;
- s = strsep(&stringp, "/");
- if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
- ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
- return NULL;
- }
- groupmatch = ((ast_group_t) 1 << x);
- if (toupper(dest[0]) == 'G') {
- if (dest[0] == 'G') {
- backwards = 1;
- p = ifend;
- } else
- p = iflist;
- } else {
- if (dest[0] == 'R') {
- backwards = 1;
- p = round_robin[x]?round_robin[x]->prev:ifend;
- if (!p)
- p = ifend;
- } else {
- p = round_robin[x]?round_robin[x]->next:iflist;
- if (!p)
- p = iflist;
- }
- roundrobin = 1;
- }
- } else {
- char *stringp=NULL;
- stringp=dest;
- s = strsep(&stringp, "/");
- p = iflist;
- if (!strcasecmp(s, "pseudo")) {
- /* Special case for pseudo */
- x = CHAN_PSEUDO;
- channelmatch = x;
- }
-#ifdef HAVE_PRI
- else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
- if ((trunkgroup < 1) || (crv < 1)) {
- ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
- return NULL;
- }
- res--;
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].trunkgroup == trunkgroup) {
- pri = pris + x;
- lock = &pri->lock;
- start = pri->crvs;
- end = pri->crvend;
- break;
- }
- }
- if (!pri) {
- ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
- return NULL;
- }
- channelmatch = crv;
- p = pris[x].crvs;
- }
-#endif
- else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
- ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
- return NULL;
- } else {
- channelmatch = x;
- }
- }
- /* Search for an unowned channel */
- ast_mutex_lock(lock);
- exit = p;
- while (p && !tmp) {
- if (roundrobin)
- round_robin[x] = p;
-#if 0
- ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
-#endif
-
- if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
- if (p->inalarm)
- goto next;
-
- callwait = (p->owner != NULL);
-#ifdef HAVE_PRI
- if (pri && (p->subs[SUB_REAL].zfd < 0)) {
- if (p->sig != SIG_FXSKS) {
- /* Gotta find an actual channel to use for this
- CRV if this isn't a callwait */
- bearer = pri_find_empty_chan(pri, 0);
- if (bearer < 0) {
- ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
- p = NULL;
- break;
- }
- pri_assign_bearer(p, pri, pri->pvts[bearer]);
- } else {
- if (alloc_sub(p, 0)) {
- ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
- p = NULL;
- break;
- } else
- ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
- p->pri = pri;
- }
- }
-#endif
- if (p->channel == CHAN_PSEUDO) {
- p = chandup(p);
- if (!p) {
- break;
- }
- }
- if (p->owner) {
- if (alloc_sub(p, SUB_CALLWAIT)) {
- p = NULL;
- break;
- }
- }
- p->outgoing = 1;
- tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
-#ifdef HAVE_PRI
- if (p->bearer) {
- /* Log owner to bearer channel, too */
- p->bearer->owner = tmp;
- }
-#endif
- /* Make special notes */
- if (res > 1) {
- if (opt == 'c') {
- /* Confirm answer */
- p->confirmanswer = 1;
- } else if (opt == 'r') {
- /* Distinctive ring */
- if (res < 3)
- ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
- else
- p->distinctivering = y;
- } else if (opt == 'd') {
- /* If this is an ISDN call, make it digital */
- p->digital = 1;
- if (tmp)
- tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
- } else {
- ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
- }
- }
- /* Note if the call is a call waiting call */
- if (tmp && callwait)
- tmp->cdrflags |= AST_CDR_CALLWAIT;
- break;
- }
-next:
- if (backwards) {
- p = p->prev;
- if (!p)
- p = end;
- } else {
- p = p->next;
- if (!p)
- p = start;
- }
- /* stop when you roll to the one that we started from */
- if (p == exit)
- break;
- }
- ast_mutex_unlock(lock);
- restart_monitor();
- if (callwait)
- *cause = AST_CAUSE_BUSY;
- else if (!tmp) {
- if (channelmatched) {
- if (busy)
- *cause = AST_CAUSE_BUSY;
- } else if (groupmatched) {
- *cause = AST_CAUSE_CONGESTION;
- }
- }
-
- return tmp;
-}
-
-
-#ifdef HAVE_PRI
-static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
-{
- struct zt_pvt *p;
- p = pri->crvs;
- while (p) {
- if (p->channel == crv)
- return p;
- p = p->next;
- }
- return NULL;
-}
-
-
-static int pri_find_principle(struct zt_pri *pri, int channel)
-{
- int x;
- int span = PRI_SPAN(channel);
- int spanfd;
- ZT_PARAMS param;
- int principle = -1;
- int explicit = PRI_EXPLICIT(channel);
- channel = PRI_CHANNEL(channel);
-
- if (!explicit) {
- spanfd = pri_active_dchan_fd(pri);
- if (ioctl(spanfd, ZT_GET_PARAMS, &param))
- return -1;
- span = pris[param.spanno - 1].prilogicalspan;
- }
-
- for (x = 0; x < pri->numchans; x++) {
- if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
- principle = x;
- break;
- }
- }
-
- return principle;
-}
-
-static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
-{
- int x;
- struct zt_pvt *crv;
- if (!c) {
- if (principle < 0)
- return -1;
- return principle;
- }
- if ((principle > -1) &&
- (principle < pri->numchans) &&
- (pri->pvts[principle]) &&
- (pri->pvts[principle]->call == c))
- return principle;
- /* First, check for other bearers */
- for (x = 0; x < pri->numchans; x++) {
- if (!pri->pvts[x])
- continue;
- if (pri->pvts[x]->call == c) {
- /* Found our call */
- if (principle != x) {
- struct zt_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
- old->channel, new->channel);
- if (new->owner) {
- ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
- old->channel, new->channel, new->channel);
- return -1;
- }
- /* Fix it all up now */
- new->owner = old->owner;
- old->owner = NULL;
- if (new->owner) {
- ast_string_field_build(new->owner, name,
- "Zap/%d:%d-%d", pri->trunkgroup,
- new->channel, 1);
- new->owner->tech_pvt = new;
- new->owner->fds[0] = new->subs[SUB_REAL].zfd;
- new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
- old->subs[SUB_REAL].owner = NULL;
- } else
- ast_log(LOG_WARNING, "Whoa, there's no owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel);
- new->call = old->call;
- old->call = NULL;
-
- /* Copy any DSP that may be present */
- new->dsp = old->dsp;
- new->dsp_features = old->dsp_features;
- old->dsp = NULL;
- old->dsp_features = 0;
- }
- return principle;
- }
- }
- /* Now check for a CRV with no bearer */
- crv = pri->crvs;
- while (crv) {
- if (crv->call == c) {
- /* This is our match... Perform some basic checks */
- if (crv->bearer)
- ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
- else if (pri->pvts[principle]->owner)
- ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
- else {
- /* Looks good. Drop the pseudo channel now, clear up the assignment, and
- wakeup the potential sleeper */
- zt_close(crv->subs[SUB_REAL].zfd);
- pri->pvts[principle]->call = crv->call;
- pri_assign_bearer(crv, pri, pri->pvts[principle]);
- ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
- pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
- pri->trunkgroup, crv->channel);
- wakeup_sub(crv, SUB_REAL, pri);
- }
- return principle;
- }
- crv = crv->next;
- }
- ast_log(LOG_WARNING, "Call specified, but not found?\n");
- return -1;
-}
-
-static void *do_idle_thread(void *vchan)
-{
- struct ast_channel *chan = vchan;
- struct zt_pvt *pvt = chan->tech_pvt;
- struct ast_frame *f;
- char ex[80];
- /* Wait up to 30 seconds for an answer */
- int newms, ms = 30000;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
- snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
- if (ast_call(chan, ex, 0)) {
- ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
- ast_hangup(chan);
- return NULL;
- }
- while ((newms = ast_waitfor(chan, ms)) > 0) {
- f = ast_read(chan);
- if (!f) {
- /* Got hangup */
- break;
- }
- if (f->frametype == AST_FRAME_CONTROL) {
- switch (f->subclass) {
- case AST_CONTROL_ANSWER:
- /* Launch the PBX */
- ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
- ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
- chan->priority = 1;
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
- ast_pbx_run(chan);
- /* It's already hungup, return immediately */
- return NULL;
- case AST_CONTROL_BUSY:
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
- break;
- };
- }
- ast_frfree(f);
- ms = newms;
- }
- /* Hangup the channel since nothing happend */
- ast_hangup(chan);
- return NULL;
-}
-
-#ifndef PRI_RESTART
-#error "Upgrade your libpri"
-#endif
-static void zt_pri_message(struct pri *pri, char *s)
-{
- int x, y;
- int dchan = -1, span = -1;
- int dchancount = 0;
-
- if (pri) {
- for (x = 0; x < NUM_SPANS; x++) {
- for (y = 0; y < NUM_DCHANS; y++) {
- if (pris[x].dchans[y])
- dchancount++;
-
- if (pris[x].dchans[y] == pri)
- dchan = y;
- }
- if (dchan >= 0) {
- span = x;
- break;
- }
- dchancount = 0;
- }
- if ((dchan >= 0) && (span >= 0)) {
- if (dchancount > 1)
- ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
- else
- ast_verbose("%s", s);
- } else
- ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
- } else
- ast_verbose("%s", s);
-
- ast_mutex_lock(&pridebugfdlock);
-
- if (pridebugfd >= 0)
- write(pridebugfd, s, strlen(s));
-
- ast_mutex_unlock(&pridebugfdlock);
-}
-
-static void zt_pri_error(struct pri *pri, char *s)
-{
- int x, y;
- int dchan = -1, span = -1;
- int dchancount = 0;
-
- if (pri) {
- for (x = 0; x < NUM_SPANS; x++) {
- for (y = 0; y < NUM_DCHANS; y++) {
- if (pris[x].dchans[y])
- dchancount++;
-
- if (pris[x].dchans[y] == pri)
- dchan = y;
- }
- if (dchan >= 0) {
- span = x;
- break;
- }
- dchancount = 0;
- }
- if ((dchan >= 0) && (span >= 0)) {
- if (dchancount > 1)
- ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
- else
- ast_log(LOG_ERROR, "%s", s);
- } else
- ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
- } else
- ast_log(LOG_ERROR, "%s", s);
-
- ast_mutex_lock(&pridebugfdlock);
-
- if (pridebugfd >= 0)
- write(pridebugfd, s, strlen(s));
-
- ast_mutex_unlock(&pridebugfdlock);
-}
-
-static int pri_check_restart(struct zt_pri *pri)
-{
- do {
- pri->resetpos++;
- } while ((pri->resetpos < pri->numchans) &&
- (!pri->pvts[pri->resetpos] ||
- pri->pvts[pri->resetpos]->call ||
- pri->pvts[pri->resetpos]->resetting));
- if (pri->resetpos < pri->numchans) {
- /* Mark the channel as resetting and restart it */
- pri->pvts[pri->resetpos]->resetting = 1;
- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
- } else {
- pri->resetting = 0;
- time(&pri->lastreset);
- }
- return 0;
-}
-
-static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
-{
- int x;
- int redo;
- ast_mutex_unlock(&pri->lock);
- ast_mutex_lock(&p->lock);
- do {
- redo = 0;
- for (x = 0; x < 3; x++) {
- while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
- redo++;
- ast_mutex_unlock(&p->lock);
- usleep(1);
- ast_mutex_lock(&p->lock);
- }
- if (p->subs[x].owner) {
- ast_queue_hangup(p->subs[x].owner);
- ast_mutex_unlock(&p->subs[x].owner->lock);
- }
- }
- } while (redo);
- ast_mutex_unlock(&p->lock);
- ast_mutex_lock(&pri->lock);
- return 0;
-}
-
-static char * redirectingreason2str(int redirectingreason)
-{
- switch (redirectingreason) {
- case 0:
- return "UNKNOWN";
- case 1:
- return "BUSY";
- case 2:
- return "NO_REPLY";
- case 0xF:
- return "UNCONDITIONAL";
- default:
- return "NOREDIRECT";
- }
-}
-
-static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
-{
- switch (plan) {
- case PRI_INTERNATIONAL_ISDN: /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
- snprintf(buf, size, "%s%s", pri->internationalprefix, number);
- break;
- case PRI_NATIONAL_ISDN: /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
- snprintf(buf, size, "%s%s", pri->nationalprefix, number);
- break;
- case PRI_LOCAL_ISDN: /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
- snprintf(buf, size, "%s%s", pri->localprefix, number);
- break;
- case PRI_PRIVATE: /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
- snprintf(buf, size, "%s%s", pri->privateprefix, number);
- break;
- case PRI_UNKNOWN: /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
- snprintf(buf, size, "%s%s", pri->unknownprefix, number);
- break;
- default: /* other Q.931 dialplan => don't twiddle with callingnum */
- snprintf(buf, size, "%s", number);
- break;
- }
-}
-
-static int zt_setlaw(int zfd, int law)
-{
- int res;
- res = ioctl(zfd, ZT_SETLAW, &law);
- if (res)
- return res;
- return 0;
-}
-
-static void *pri_dchannel(void *vpri)
-{
- struct zt_pri *pri = vpri;
- pri_event *e;
- struct pollfd fds[NUM_DCHANS];
- int res;
- int chanpos = 0;
- int x;
- int haveidles;
- int activeidles;
- int nextidle = -1;
- struct ast_channel *c;
- struct timeval tv, lowest, *next;
- struct timeval lastidle = { 0, 0 };
- int doidling=0;
- char *cc;
- char idlen[80];
- struct ast_channel *idle;
- pthread_t p;
- time_t t;
- int i, which=-1;
- int numdchans;
- int cause=0;
- struct zt_pvt *crv;
- pthread_t threadid;
- pthread_attr_t attr;
- char ani2str[6];
- char plancallingnum[256];
- char plancallingani[256];
- char calledtonstr[10];
-
- gettimeofday(&lastidle, NULL);
- if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
- /* Need to do idle dialing, check to be sure though */
- cc = strchr(pri->idleext, '@');
- if (cc) {
- *cc = '\0';
- cc++;
- ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
-#if 0
- /* Extensions may not be loaded yet */
- if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
- ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
- else
-#endif
- doidling = 1;
- } else
- ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
- }
- for (;;) {
- for (i = 0; i < NUM_DCHANS; i++) {
- if (!pri->dchannels[i])
- break;
- fds[i].fd = pri->fds[i];
- fds[i].events = POLLIN | POLLPRI;
- fds[i].revents = 0;
- }
- numdchans = i;
- time(&t);
- ast_mutex_lock(&pri->lock);
- if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
- if (pri->resetting && pri_is_up(pri)) {
- if (pri->resetpos < 0)
- pri_check_restart(pri);
- } else {
- if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) {
- pri->resetting = 1;
- pri->resetpos = -1;
- }
- }
- }
- /* Look for any idle channels if appropriate */
- if (doidling && pri_is_up(pri)) {
- nextidle = -1;
- haveidles = 0;
- activeidles = 0;
- for (x = pri->numchans; x >= 0; x--) {
- if (pri->pvts[x] && !pri->pvts[x]->owner &&
- !pri->pvts[x]->call) {
- if (haveidles < pri->minunused) {
- haveidles++;
- } else if (!pri->pvts[x]->resetting) {
- nextidle = x;
- break;
- }
- } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
- activeidles++;
- }
- if (nextidle > -1) {
- if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
- /* Don't create a new idle call more than once per second */
- snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
- idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
- if (idle) {
- pri->pvts[nextidle]->isidlecall = 1;
- if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
- ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
- zt_hangup(idle);
- }
- } else
- ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
- gettimeofday(&lastidle, NULL);
- }
- } else if ((haveidles < pri->minunused) &&
- (activeidles > pri->minidle)) {
- /* Mark something for hangup if there is something
- that can be hungup */
- for (x = pri->numchans; x >= 0; x--) {
- /* find a candidate channel */
- if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
- pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- haveidles++;
- /* Stop if we have enough idle channels or
- can't spare any more active idle ones */
- if ((haveidles >= pri->minunused) ||
- (activeidles <= pri->minidle))
- break;
- }
- }
- }
- }
- /* Start with reasonable max */
- lowest = ast_tv(60, 0);
- for (i = 0; i < NUM_DCHANS; i++) {
- /* Find lowest available d-channel */
- if (!pri->dchannels[i])
- break;
- if ((next = pri_schedule_next(pri->dchans[i]))) {
- /* We need relative time here */
- tv = ast_tvsub(*next, ast_tvnow());
- if (tv.tv_sec < 0) {
- tv = ast_tv(0,0);
- }
- if (doidling || pri->resetting) {
- if (tv.tv_sec > 1) {
- tv = ast_tv(1, 0);
- }
- } else {
- if (tv.tv_sec > 60) {
- tv = ast_tv(60, 0);
- }
- }
- } else if (doidling || pri->resetting) {
- /* Make sure we stop at least once per second if we're
- monitoring idle channels */
- tv = ast_tv(1,0);
- } else {
- /* Don't poll for more than 60 seconds */
- tv = ast_tv(60, 0);
- }
- if (!i || ast_tvcmp(tv, lowest) < 0) {
- lowest = tv;
- }
- }
- ast_mutex_unlock(&pri->lock);
-
- e = NULL;
- res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
-
- ast_mutex_lock(&pri->lock);
- if (!res) {
- for (which = 0; which < NUM_DCHANS; which++) {
- if (!pri->dchans[which])
- break;
- /* Just a timeout, run the scheduler */
- e = pri_schedule_run(pri->dchans[which]);
- if (e)
- break;
- }
- } else if (res > -1) {
- for (which = 0; which < NUM_DCHANS; which++) {
- if (!pri->dchans[which])
- break;
- if (fds[which].revents & POLLPRI) {
- /* Check for an event */
- x = 0;
- res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
- if (x)
- ast_log(LOG_NOTICE, "PRI got event: %s (%d) on %s D-channel of span %d\n", event2str(x), x, pri_order(which), pri->span);
- /* Keep track of alarm state */
- if (x == ZT_EVENT_ALARM) {
- pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
- pri_find_dchan(pri);
- } else if (x == ZT_EVENT_NOALARM) {
- pri->dchanavail[which] |= DCHAN_NOTINALARM;
- pri_restart(pri->dchans[which]);
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
- } else if (fds[which].revents & POLLIN) {
- e = pri_check_event(pri->dchans[which]);
- }
- if (e)
- break;
- }
- } else if (errno != EINTR)
- ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
-
- if (e) {
- if (pri->debug)
- pri_dump_event(pri->dchans[which], e);
-
- if (e->e != PRI_EVENT_DCHAN_DOWN) {
- if (!(pri->dchanavail[which] & DCHAN_UP)) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
- }
- pri->dchanavail[which] |= DCHAN_UP;
- } else {
- if (pri->dchanavail[which] & DCHAN_UP) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
- }
- pri->dchanavail[which] &= ~DCHAN_UP;
- }
-
- if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
- /* Must be an NFAS group that has the secondary dchan active */
- pri->pri = pri->dchans[which];
-
- switch (e->e) {
- case PRI_EVENT_DCHAN_UP:
- if (!pri->pri) pri_find_dchan(pri);
-
- /* Note presense of D-channel */
- time(&pri->lastreset);
-
- /* Restart in 5 seconds */
- if (pri->resetinterval > -1) {
- pri->lastreset -= pri->resetinterval;
- pri->lastreset += 5;
- }
- pri->resetting = 0;
- /* Take the channels from inalarm condition */
- for (i = 0; i < pri->numchans; i++)
- if (pri->pvts[i]) {
- pri->pvts[i]->inalarm = 0;
- }
- break;
- case PRI_EVENT_DCHAN_DOWN:
- pri_find_dchan(pri);
- if (!pri_is_up(pri)) {
- pri->resetting = 0;
- /* Hangup active channels and put them in alarm mode */
- for (i = 0; i < pri->numchans; i++) {
- struct zt_pvt *p = pri->pvts[i];
- if (p) {
- if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
- /* T309 is not enabled : hangup calls when alarm occurs */
- if (p->call) {
- if (p->pri && p->pri->pri) {
- pri_hangup(p->pri->pri, p->call, -1);
- pri_destroycall(p->pri->pri, p->call);
- p->call = NULL;
- } else
- ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
- }
- if (p->realcall) {
- pri_hangup_all(p->realcall, pri);
- } else if (p->owner)
- p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- }
- p->inalarm = 1;
- }
- }
- }
- break;
- case PRI_EVENT_RESTART:
- if (e->restart.channel > -1) {
- chanpos = pri_find_principle(pri, e->restart.channel);
- if (chanpos < 0)
- ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n",
- PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
- else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n",
- PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (pri->pvts[chanpos]->call) {
- pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
- pri->pvts[chanpos]->call = NULL;
- }
- /* Force soft hangup if appropriate */
- if (pri->pvts[chanpos]->realcall)
- pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
- else if (pri->pvts[chanpos]->owner)
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
- for (x = 0; x < pri->numchans; x++)
- if (pri->pvts[x]) {
- ast_mutex_lock(&pri->pvts[x]->lock);
- if (pri->pvts[x]->call) {
- pri_destroycall(pri->pri, pri->pvts[x]->call);
- pri->pvts[x]->call = NULL;
- }
- if (pri->pvts[chanpos]->realcall)
- pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
- else if (pri->pvts[x]->owner)
- pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_mutex_unlock(&pri->pvts[x]->lock);
- }
- }
- break;
- case PRI_EVENT_KEYPAD_DIGIT:
- chanpos = pri_find_principle(pri, e->digit.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
- if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
- /* how to do that */
- int digitlen = strlen(e->digit.digits);
- char digit;
- int i;
- for (i = 0; i < digitlen; i++) {
- digit = e->digit.digits[i];
- {
- struct ast_frame f = { AST_FRAME_DTMF, digit, };
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- }
- }
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
-
- case PRI_EVENT_INFO_RECEIVED:
- chanpos = pri_find_principle(pri, e->ring.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
- if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
- /* how to do that */
- int digitlen = strlen(e->ring.callednum);
- char digit;
- int i;
- for (i = 0; i < digitlen; i++) {
- digit = e->ring.callednum[i];
- {
- struct ast_frame f = { AST_FRAME_DTMF, digit, };
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- }
- }
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_RING:
- crv = NULL;
- if (e->ring.channel == -1)
- chanpos = pri_find_empty_chan(pri, 1);
- else
- chanpos = pri_find_principle(pri, e->ring.channel);
- /* if no channel specified find one empty */
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (pri->pvts[chanpos]->owner) {
- if (pri->pvts[chanpos]->call == e->ring.call) {
- ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n",
- PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
- break;
- } else {
- /* This is where we handle initial glare */
- ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d. Attempting to renegotiating channel.\n",
- PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- chanpos = -1;
- }
- }
- if (chanpos > -1)
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- if ((chanpos < 0) && (e->ring.flexible))
- chanpos = pri_find_empty_chan(pri, 1);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
- /* Should be safe to lock CRV AFAIK while bearer is still locked */
- crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
- if (crv)
- ast_mutex_lock(&crv->lock);
- if (!crv || crv->owner) {
- pri->pvts[chanpos]->call = NULL;
- if (crv) {
- if (crv->owner)
- crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
- } else
- ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
- if (crv)
- ast_mutex_unlock(&crv->lock);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- break;
- }
- }
- pri->pvts[chanpos]->call = e->ring.call;
- apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
- if (pri->pvts[chanpos]->use_callerid) {
- ast_shrink_phone_number(plancallingnum);
- ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
-#ifdef PRI_ANI
- if (!ast_strlen_zero(e->ring.callingani)) {
- apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
- ast_shrink_phone_number(plancallingani);
- ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
- } else {
- pri->pvts[chanpos]->cid_ani[0] = '\0';
- }
-#endif
- ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
- pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
- } else {
- pri->pvts[chanpos]->cid_num[0] = '\0';
- pri->pvts[chanpos]->cid_ani[0] = '\0';
- pri->pvts[chanpos]->cid_name[0] = '\0';
- pri->pvts[chanpos]->cid_ton = 0;
- }
- apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
- e->ring.redirectingnum, e->ring.callingplanrdnis);
- /* If immediate=yes go to s|1 */
- if (pri->pvts[chanpos]->immediate) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
- pri->pvts[chanpos]->exten[0] = 's';
- pri->pvts[chanpos]->exten[1] = '\0';
- }
- /* Get called number */
- else if (!ast_strlen_zero(e->ring.callednum)) {
- ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
- ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
- } else if (pri->overlapdial)
- pri->pvts[chanpos]->exten[0] = '\0';
- else {
- /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */
- pri->pvts[chanpos]->exten[0] = 's';
- pri->pvts[chanpos]->exten[1] = '\0';
- }
- /* Set DNID on all incoming calls -- even immediate */
- if (!ast_strlen_zero(e->ring.callednum))
- ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
- /* No number yet, but received "sending complete"? */
- if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
- pri->pvts[chanpos]->exten[0] = 's';
- pri->pvts[chanpos]->exten[1] = '\0';
- }
- /* Make sure extension exists (or in overlap dial mode, can exist) */
- if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
- ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
- /* Setup law */
- int law;
- if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
- /* Set to audio mode at this point */
- law = 1;
- if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
- ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
- }
- if (e->ring.layer1 == PRI_LAYER_1_ALAW)
- law = ZT_LAW_ALAW;
- else
- law = ZT_LAW_MULAW;
- res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
- res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
- if (res < 0)
- ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
- if (e->ring.complete || !pri->overlapdial) {
- /* Just announce proceeding */
- pri->pvts[chanpos]->proceeding = 1;
- pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
- } else {
- if (pri->switchtype != PRI_SWITCH_GR303_TMC)
- pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
- else
- pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
- }
- /* Get the use_callingpres state */
- pri->pvts[chanpos]->callingpres = e->ring.callingpres;
-
- /* Start PBX */
- if (!e->ring.complete && pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
- /* Release the PRI lock while we create the channel */
- ast_mutex_unlock(&pri->lock);
- if (crv) {
- /* Set bearer and such */
- pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
- c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
- pri->pvts[chanpos]->owner = &inuse;
- ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
- } else {
- c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
- }
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-
- if (!ast_strlen_zero(e->ring.callingsubaddr)) {
- pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
- }
- if (e->ring.ani2 >= 0) {
- snprintf(ani2str, 5, "%.2d", e->ring.ani2);
- pbx_builtin_setvar_helper(c, "ANI2", ani2str);
- }
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->ring.useruserinfo)) {
- pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
- }
-#endif
-
- snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
- pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
- if (e->ring.redirectingreason >= 0)
- pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_mutex_lock(&pri->lock);
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
- plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
- } else {
- ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
- if (c)
- ast_hangup(c);
- else {
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
- pri->pvts[chanpos]->call = NULL;
- }
- }
- pthread_attr_destroy(&attr);
- } else {
- ast_mutex_unlock(&pri->lock);
- /* Release PRI lock while we create the channel */
- c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
- if (c) {
- char calledtonstr[10];
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-
- if (e->ring.ani2 >= 0) {
- snprintf(ani2str, 5, "%d", e->ring.ani2);
- pbx_builtin_setvar_helper(c, "ANI2", ani2str);
- }
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->ring.useruserinfo)) {
- pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
- }
-#endif
-
- if (e->ring.redirectingreason >= 0)
- pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
-
- snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
- pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_mutex_lock(&pri->lock);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
- plancallingnum, pri->pvts[chanpos]->exten,
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
- zt_enable_ec(pri->pvts[chanpos]);
- } else {
-
- ast_mutex_lock(&pri->lock);
-
- ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
- pri->pvts[chanpos]->call = NULL;
- }
- }
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n",
- pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan,
- pri->pvts[chanpos]->prioffset, pri->span);
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
- pri->pvts[chanpos]->call = NULL;
- pri->pvts[chanpos]->exten[0] = '\0';
- }
- if (crv)
- ast_mutex_unlock(&crv->lock);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- } else {
- if (e->ring.flexible)
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
- else
- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
- }
- break;
- case PRI_EVENT_RINGING:
- chanpos = pri_find_principle(pri, e->ringing.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n",
- PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
- zt_enable_ec(pri->pvts[chanpos]);
- pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
- pri->pvts[chanpos]->alerting = 1;
- } else
- ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
-#ifdef PRI_PROGRESS_MASK
- if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
-#else
- if (e->ringing.progress == 8) {
-#endif
- /* Now we can do call progress detection */
- if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
- /* RINGING detection isn't required because we got ALERTING signal */
- ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
- pri->pvts[chanpos]->dsp_features = 0;
- }
- }
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->ringing.useruserinfo)) {
- struct ast_channel *owner = pri->pvts[chanpos]->owner;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- }
-#endif
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_PROGRESS:
- /* Get chan value if e->e is not PRI_EVNT_RINGING */
- chanpos = pri_find_principle(pri, e->proceeding.channel);
- if (chanpos > -1) {
-#ifdef PRI_PROGRESS_MASK
- if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
-#else
- if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
-#endif
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
-
- if (e->proceeding.cause > -1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
-
- /* Work around broken, out of spec USER_BUSY cause in a progress message */
- if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
- if (pri->pvts[chanpos]->owner) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
-
- pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
- f.subclass = AST_CONTROL_BUSY;
- }
- }
- }
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
-#ifdef PRI_PROGRESS_MASK
- if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
-#else
- if (e->proceeding.progress == 8) {
-#endif
- /* Now we can do call progress detection */
- if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
- ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
- pri->pvts[chanpos]->dsp_features = 0;
- }
- }
- pri->pvts[chanpos]->progress = 1;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_PROCEEDING:
- chanpos = pri_find_principle(pri, e->proceeding.channel);
- if (chanpos > -1) {
- if (!pri->pvts[chanpos]->proceeding) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
-#ifdef PRI_PROGRESS_MASK
- if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
-#else
- if (e->proceeding.progress == 8) {
-#endif
- /* Now we can do call progress detection */
- if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
- ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
- pri->pvts[chanpos]->dsp_features = 0;
- }
- /* Bring voice path up */
- f.subclass = AST_CONTROL_PROGRESS;
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- }
- pri->pvts[chanpos]->proceeding = 1;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_FACNAME:
- chanpos = pri_find_principle(pri, e->facname.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n",
- PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
- } else {
- /* Re-use *69 field for PRI */
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
- ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
- pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
- zt_enable_ec(pri->pvts[chanpos]);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_ANSWER:
- chanpos = pri_find_principle(pri, e->answer.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- /* Now we can do call progress detection */
-
- /* We changed this so it turns on the DSP no matter what... progress or no progress.
- * By this time, we need DTMF detection and other features that were previously disabled
- * -- Matt F */
- if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
- ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
- pri->pvts[chanpos]->dsp_features = 0;
- }
- if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
- ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
- x = ZT_START;
- res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
- if (res < 0) {
- if (errno != EINPROGRESS) {
- ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
- }
- }
- } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
- pri->pvts[chanpos]->dialing = 1;
- /* Send any "w" waited stuff */
- res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
- pri->pvts[chanpos]->dop.dialstr[0] = '\0';
- } else
- ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
- pri->pvts[chanpos]->dop.dialstr[0] = '\0';
- } else if (pri->pvts[chanpos]->confirmanswer) {
- ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
- } else {
- pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
- /* Enable echo cancellation if it's not on already */
- zt_enable_ec(pri->pvts[chanpos]);
- }
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->answer.useruserinfo)) {
- struct ast_channel *owner = pri->pvts[chanpos]->owner;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- }
-#endif
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_HANGUP:
- chanpos = pri_find_principle(pri, e->hangup.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (!pri->pvts[chanpos]->alreadyhungup) {
- /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
- pri->pvts[chanpos]->alreadyhungup = 1;
- if (pri->pvts[chanpos]->realcall)
- pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
- else if (pri->pvts[chanpos]->owner) {
- /* Queue a BUSY instead of a hangup if our cause is appropriate */
- pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
- if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- else {
- switch (e->hangup.cause) {
- case PRI_CAUSE_USER_BUSY:
- pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
- break;
- case PRI_CAUSE_CALL_REJECTED:
- case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
- case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
- case PRI_CAUSE_SWITCH_CONGESTION:
- case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
- case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
- pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
- break;
- default:
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- }
- }
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
- } else {
- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
- pri->pvts[chanpos]->call = NULL;
- }
- if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
- pri->pvts[chanpos]->resetting = 1;
- }
- if (e->hangup.aoc_units > -1)
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
-
-#ifdef SUPPORT_USERUSER
- if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
- struct ast_channel *owner = pri->pvts[chanpos]->owner;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- }
-#endif
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- } else {
- ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- }
- }
- break;
-#ifndef PRI_EVENT_HANGUP_REQ
-#error please update libpri
-#endif
- case PRI_EVENT_HANGUP_REQ:
- chanpos = pri_find_principle(pri, e->hangup.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (pri->pvts[chanpos]->realcall)
- pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
- else if (pri->pvts[chanpos]->owner) {
- pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
- if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- else {
- switch (e->hangup.cause) {
- case PRI_CAUSE_USER_BUSY:
- pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
- break;
- case PRI_CAUSE_CALL_REJECTED:
- case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
- case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
- case PRI_CAUSE_SWITCH_CONGESTION:
- case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
- case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
- pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
- break;
- default:
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- }
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
- if (e->hangup.aoc_units > -1)
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
- } else {
- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
- pri->pvts[chanpos]->call = NULL;
- }
- if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
- pri->pvts[chanpos]->resetting = 1;
- }
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->hangup.useruserinfo)) {
- struct ast_channel *owner = pri->pvts[chanpos]->owner;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- }
-#endif
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- } else {
- ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- }
- }
- break;
- case PRI_EVENT_HANGUP_ACK:
- chanpos = pri_find_principle(pri, e->hangup.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- pri->pvts[chanpos]->call = NULL;
- pri->pvts[chanpos]->resetting = 0;
- if (pri->pvts[chanpos]->owner) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
- }
-
-#ifdef SUPPORT_USERUSER
- if (!ast_strlen_zero(e->hangup.useruserinfo)) {
- struct ast_channel *owner = pri->pvts[chanpos]->owner;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- }
-#endif
-
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
- break;
- case PRI_EVENT_CONFIG_ERR:
- ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
- break;
- case PRI_EVENT_RESTART_ACK:
- chanpos = pri_find_principle(pri, e->restartack.channel);
- if (chanpos < 0) {
- /* Sometime switches (e.g. I421 / British Telecom) don't give us the
- channel number, so we have to figure it out... This must be why
- everybody resets exactly a channel at a time. */
- for (x = 0; x < pri->numchans; x++) {
- if (pri->pvts[x] && pri->pvts[x]->resetting) {
- chanpos = x;
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan,
- pri->pvts[chanpos]->prioffset, pri->span);
- if (pri->pvts[chanpos]->realcall)
- pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
- else if (pri->pvts[chanpos]->owner) {
- ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan,
- pri->pvts[chanpos]->prioffset, pri->span);
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- }
- pri->pvts[chanpos]->resetting = 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
- pri->pvts[chanpos]->prioffset, pri->span);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- if (pri->resetting)
- pri_check_restart(pri);
- break;
- }
- }
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n",
- PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
- }
- } else {
- if (pri->pvts[chanpos]) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (pri->pvts[chanpos]->realcall)
- pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
- else if (pri->pvts[chanpos]->owner) {
- ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
- PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
- pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- }
- pri->pvts[chanpos]->resetting = 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
- pri->pvts[chanpos]->prioffset, pri->span);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- if (pri->resetting)
- pri_check_restart(pri);
- }
- }
- break;
- case PRI_EVENT_SETUP_ACK:
- chanpos = pri_find_principle(pri, e->setup_ack.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
- } else {
- chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- pri->pvts[chanpos]->setup_ack = 1;
- /* Send any queued digits */
- for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
- ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
- pri_information(pri->pri, pri->pvts[chanpos]->call,
- pri->pvts[chanpos]->dialdest[x]);
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- } else
- ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
- }
- break;
- case PRI_EVENT_NOTIFY:
- chanpos = pri_find_principle(pri, e->notify.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
- } else {
- struct ast_frame f = { AST_FRAME_CONTROL, };
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- switch (e->notify.info) {
- case PRI_NOTIFY_REMOTE_HOLD:
- f.subclass = AST_CONTROL_HOLD;
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- break;
- case PRI_NOTIFY_REMOTE_RETRIEVAL:
- f.subclass = AST_CONTROL_UNHOLD;
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- break;
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- break;
- default:
- ast_log(LOG_DEBUG, "Event: %d\n", e->e);
- }
- }
- ast_mutex_unlock(&pri->lock);
- }
- /* Never reached */
- return NULL;
-}
-
-static int start_pri(struct zt_pri *pri)
-{
- int res, x;
- ZT_PARAMS p;
- ZT_BUFFERINFO bi;
- struct zt_spaninfo si;
- int i;
-
- for (i = 0; i < NUM_DCHANS; i++) {
- if (!pri->dchannels[i])
- break;
- pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
- x = pri->dchannels[i];
- if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
- ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
- return -1;
- }
- res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
- if (res) {
- zt_close(pri->fds[i]);
- pri->fds[i] = -1;
- ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
- return -1;
- }
- if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
- zt_close(pri->fds[i]);
- pri->fds[i] = -1;
- ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode. See /etc/zaptel.conf\n", x);
- return -1;
- }
- memset(&si, 0, sizeof(si));
- res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
- if (res) {
- zt_close(pri->fds[i]);
- pri->fds[i] = -1;
- ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
- }
- if (!si.alarms)
- pri->dchanavail[i] |= DCHAN_NOTINALARM;
- else
- pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = 32;
- bi.bufsize = 1024;
- if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
- ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
- zt_close(pri->fds[i]);
- pri->fds[i] = -1;
- return -1;
- }
- pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
- /* Force overlap dial if we're doing GR-303! */
- if (pri->switchtype == PRI_SWITCH_GR303_TMC)
- pri->overlapdial = 1;
- pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
- /* Enslave to master if appropriate */
- if (i)
- pri_enslave(pri->dchans[0], pri->dchans[i]);
- if (!pri->dchans[i]) {
- zt_close(pri->fds[i]);
- pri->fds[i] = -1;
- ast_log(LOG_ERROR, "Unable to create PRI structure\n");
- return -1;
- }
- pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
- pri_set_nsf(pri->dchans[i], pri->nsf);
-#ifdef PRI_GETSET_TIMERS
- for (x = 0; x < PRI_MAX_TIMERS; x++) {
- if (pritimers[x] != 0)
- pri_set_timer(pri->dchans[i], x, pritimers[x]);
- }
-#endif
- }
- /* Assume primary is the one we use */
- pri->pri = pri->dchans[0];
- pri->resetpos = -1;
- if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
- for (i = 0; i < NUM_DCHANS; i++) {
- if (!pri->dchannels[i])
- break;
- zt_close(pri->fds[i]);
- pri->fds[i] = -1;
- }
- ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
-{
- int which, span;
- char *ret = NULL;
-
- if (pos != rpos)
- return ret;
-
- for (which = span = 0; span < NUM_SPANS; span++) {
- if (pris[span].pri && ++which > state) {
- asprintf(&ret, "%d", span + 1); /* user indexes start from 1 */
- break;
- }
- }
- return ret;
-}
-
-static char *complete_span_4(const char *line, const char *word, int pos, int state)
-{
- return complete_span_helper(line,word,pos,state,3);
-}
-
-static char *complete_span_5(const char *line, const char *word, int pos, int state)
-{
- return complete_span_helper(line,word,pos,state,4);
-}
-
-static int handle_pri_set_debug_file(int fd, int argc, char **argv)
-{
- int myfd;
-
- if (!strncasecmp(argv[1], "set", 3)) {
- if (argc < 5)
- return RESULT_SHOWUSAGE;
-
- if (ast_strlen_zero(argv[4]))
- return RESULT_SHOWUSAGE;
-
- myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
- if (myfd < 0) {
- ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
- return RESULT_SUCCESS;
- }
-
- ast_mutex_lock(&pridebugfdlock);
-
- if (pridebugfd >= 0)
- close(pridebugfd);
-
- pridebugfd = myfd;
- ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
-
- ast_mutex_unlock(&pridebugfdlock);
-
- ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
- } else {
- /* Assume it is unset */
- ast_mutex_lock(&pridebugfdlock);
- close(pridebugfd);
- pridebugfd = -1;
- ast_cli(fd, "PRI debug output to file disabled\n");
- ast_mutex_unlock(&pridebugfdlock);
- }
-
- return RESULT_SUCCESS;
-}
-
-#ifdef HAVE_PRI_VERSION
-static int handle_pri_version(int fd, int agc, char *argv[]) {
- ast_cli(fd, "libpri version: %s\n", pri_get_version());
- return RESULT_SUCCESS;
-}
-#endif
-
-static int handle_pri_debug(int fd, int argc, char *argv[])
-{
- int span;
- int x;
- if (argc < 4) {
- return RESULT_SHOWUSAGE;
- }
- span = atoi(argv[3]);
- if ((span < 1) || (span > NUM_SPANS)) {
- ast_cli(fd, "Invalid span %s. Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
- return RESULT_SUCCESS;
- }
- if (!pris[span-1].pri) {
- ast_cli(fd, "No PRI running on span %d\n", span);
- return RESULT_SUCCESS;
- }
- for (x = 0; x < NUM_DCHANS; x++) {
- if (pris[span-1].dchans[x])
- pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
- PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
- PRI_DEBUG_Q921_STATE);
- }
- ast_cli(fd, "Enabled debugging on span %d\n", span);
- return RESULT_SUCCESS;
-}
-
-
-
-static int handle_pri_no_debug(int fd, int argc, char *argv[])
-{
- int span;
- int x;
- if (argc < 5)
- return RESULT_SHOWUSAGE;
- span = atoi(argv[4]);
- if ((span < 1) || (span > NUM_SPANS)) {
- ast_cli(fd, "Invalid span %s. Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
- return RESULT_SUCCESS;
- }
- if (!pris[span-1].pri) {
- ast_cli(fd, "No PRI running on span %d\n", span);
- return RESULT_SUCCESS;
- }
- for (x = 0; x < NUM_DCHANS; x++) {
- if (pris[span-1].dchans[x])
- pri_set_debug(pris[span-1].dchans[x], 0);
- }
- ast_cli(fd, "Disabled debugging on span %d\n", span);
- return RESULT_SUCCESS;
-}
-
-static int handle_pri_really_debug(int fd, int argc, char *argv[])
-{
- int span;
- int x;
- if (argc < 5)
- return RESULT_SHOWUSAGE;
- span = atoi(argv[4]);
- if ((span < 1) || (span > NUM_SPANS)) {
- ast_cli(fd, "Invalid span %s. Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
- return RESULT_SUCCESS;
- }
- if (!pris[span-1].pri) {
- ast_cli(fd, "No PRI running on span %d\n", span);
- return RESULT_SUCCESS;
- }
- for (x = 0; x < NUM_DCHANS; x++) {
- if (pris[span-1].dchans[x])
- pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
- PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
- PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
- }
- ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
- return RESULT_SUCCESS;
-}
-
-static void build_status(char *s, size_t len, int status, int active)
-{
- if (!s || len < 1) {
- return;
- }
- s[0] = '\0';
- if (status & DCHAN_PROVISIONED)
- strncat(s, "Provisioned, ", len - strlen(s) - 1);
- if (!(status & DCHAN_NOTINALARM))
- strncat(s, "In Alarm, ", len - strlen(s) - 1);
- if (status & DCHAN_UP)
- strncat(s, "Up", len - strlen(s) - 1);
- else
- strncat(s, "Down", len - strlen(s) - 1);
- if (active)
- strncat(s, ", Active", len - strlen(s) - 1);
- else
- strncat(s, ", Standby", len - strlen(s) - 1);
- s[len - 1] = '\0';
-}
-
-static int handle_pri_show_spans(int fd, int argc, char *argv[])
-{
- int span;
- int x;
- char status[256];
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- for (span = 0; span < NUM_SPANS; span++) {
- if (pris[span].pri) {
- for (x = 0; x < NUM_DCHANS; x++) {
- if (pris[span].dchannels[x]) {
- build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
- ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
- }
- }
- }
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_pri_show_span(int fd, int argc, char *argv[])
-{
- int span;
- int x;
- char status[256];
- if (argc < 4)
- return RESULT_SHOWUSAGE;
- span = atoi(argv[3]);
- if ((span < 1) || (span > NUM_SPANS)) {
- ast_cli(fd, "Invalid span '%s'. Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
- return RESULT_SUCCESS;
- }
- if (!pris[span-1].pri) {
- ast_cli(fd, "No PRI running on span %d\n", span);
- return RESULT_SUCCESS;
- }
- for (x = 0; x < NUM_DCHANS; x++) {
- if (pris[span-1].dchannels[x]) {
-#ifdef PRI_DUMP_INFO_STR
- char *info_str = NULL;
-#endif
- ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
- build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
- ast_cli(fd, "Status: %s\n", status);
-#ifdef PRI_DUMP_INFO_STR
- info_str = pri_dump_info_str(pris[span-1].pri);
- if (info_str) {
- ast_cli(fd, "%s", info_str);
- free(info_str);
- }
-#else
- pri_dump_info(pris[span-1].pri);
-#endif
- ast_cli(fd, "\n");
- }
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_pri_show_debug(int fd, int argc, char *argv[])
-{
- int x;
- int span;
- int count=0;
- int debug=0;
-
- for (span = 0; span < NUM_SPANS; span++) {
- if (pris[span].pri) {
- for (x = 0; x < NUM_DCHANS; x++) {
- debug = 0;
- if (pris[span].dchans[x]) {
- debug = pri_get_debug(pris[span].dchans[x]);
- ast_cli(fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" );
- count++;
- }
- }
- }
-
- }
- ast_mutex_lock(&pridebugfdlock);
- if (pridebugfd >= 0)
- ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
- ast_mutex_unlock(&pridebugfdlock);
-
- if (!count)
- ast_cli(fd, "No debug set or no PRI running\n");
- return RESULT_SUCCESS;
-}
-
-static const char pri_debug_help[] =
- "Usage: pri debug span <span>\n"
- " Enables debugging on a given PRI span\n";
-
-static const char pri_no_debug_help[] =
- "Usage: pri no debug span <span>\n"
- " Disables debugging on a given PRI span\n";
-
-static const char pri_really_debug_help[] =
- "Usage: pri intensive debug span <span>\n"
- " Enables debugging down to the Q.921 level\n";
-
-static const char pri_show_span_help[] =
- "Usage: pri show span <span>\n"
- " Displays PRI Information on a given PRI span\n";
-
-static const char pri_show_spans_help[] =
- "Usage: pri show spans\n"
- " Displays PRI Information\n";
-
-static struct ast_cli_entry zap_pri_cli[] = {
- { { "pri", "debug", "span", NULL },
- handle_pri_debug, "Enables PRI debugging on a span",
- pri_debug_help, complete_span_4 },
-
- { { "pri", "no", "debug", "span", NULL },
- handle_pri_no_debug, "Disables PRI debugging on a span",
- pri_no_debug_help, complete_span_5 },
-
- { { "pri", "intense", "debug", "span", NULL },
- handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
- pri_really_debug_help, complete_span_5 },
-
- { { "pri", "show", "spans", NULL },
- handle_pri_show_spans, "Displays PRI Information",
- pri_show_spans_help },
-
- { { "pri", "show", "span", NULL },
- handle_pri_show_span, "Displays PRI Information",
- pri_show_span_help, complete_span_4 },
-
- { { "pri", "show", "debug", NULL },
- handle_pri_show_debug, "Displays current PRI debug settings" },
-
- { { "pri", "set", "debug", "file", NULL },
- handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
-
- { { "pri", "unset", "debug", "file", NULL },
- handle_pri_set_debug_file, "Ends PRI debug output to file" },
-
-#ifdef HAVE_PRI_VERSION
- { { "pri", "show", "version", NULL },
- handle_pri_version, "Displays version of libpri" },
-#endif
-};
-
-#endif /* HAVE_PRI */
-
-static int zap_destroy_channel(int fd, int argc, char **argv)
-{
- int channel;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- channel = atoi(argv[3]);
-
- return zap_destroy_channel_bynum(channel);
-}
-
-static int setup_zap(int reload);
-static int zap_restart(void)
-{
- if (option_verbose > 0)
- ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
- while (iflist) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
- /* Also updates iflist: */
- destroy_channel(NULL, iflist, 1);
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
- if (setup_zap(0) != 0) {
- ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
- return 1;
- }
- return 0;
-}
-
-static int zap_restart_cmd(int fd, int argc, char **argv)
-{
- if (argc != 2) {
- return RESULT_SHOWUSAGE;
- }
-
- if (zap_restart() != 0)
- return RESULT_FAILURE;
- return RESULT_SUCCESS;
-}
-
-static int action_zaprestart(struct mansession *s, const struct message *m)
-{
- if (zap_restart() != 0) {
- astman_send_error(s, m, "Failed rereading zaptel configuration");
- return 1;
- }
- astman_send_ack(s, m, "ZapRestart: Success");
- return 0;
-}
-
-static int zap_show_channels(int fd, int argc, char **argv)
-{
-#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
-#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
- struct zt_pvt *tmp = NULL;
- char tmps[20] = "";
- ast_mutex_t *lock;
- struct zt_pvt *start;
-#ifdef HAVE_PRI
- int trunkgroup;
- struct zt_pri *pri = NULL;
- int x;
-#endif
-
- lock = &iflock;
- start = iflist;
-
-#ifdef HAVE_PRI
- if (argc == 4) {
- if ((trunkgroup = atoi(argv[3])) < 1)
- return RESULT_SHOWUSAGE;
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].trunkgroup == trunkgroup) {
- pri = pris + x;
- break;
- }
- }
- if (pri) {
- start = pri->crvs;
- lock = &pri->lock;
- } else {
- ast_cli(fd, "No such trunk group %d\n", trunkgroup);
- return RESULT_FAILURE;
- }
- } else
-#endif
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- ast_mutex_lock(lock);
-#ifdef HAVE_PRI
- ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
-#else
- ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
-#endif
-
- tmp = start;
- while (tmp) {
- if (tmp->channel > 0) {
- snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
- } else
- ast_copy_string(tmps, "pseudo", sizeof(tmps));
- ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
- tmp = tmp->next;
- }
- ast_mutex_unlock(lock);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int zap_show_channel(int fd, int argc, char **argv)
-{
- int channel;
- struct zt_pvt *tmp = NULL;
- ZT_CONFINFO ci;
- ZT_PARAMS ps;
- int x;
- ast_mutex_t *lock;
- struct zt_pvt *start;
-#ifdef HAVE_PRI
- char *c;
- int trunkgroup;
- struct zt_pri *pri=NULL;
-#endif
-
- lock = &iflock;
- start = iflist;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-#ifdef HAVE_PRI
- if ((c = strchr(argv[3], ':'))) {
- if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
- return RESULT_SHOWUSAGE;
- if ((trunkgroup < 1) || (channel < 1))
- return RESULT_SHOWUSAGE;
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].trunkgroup == trunkgroup) {
- pri = pris + x;
- break;
- }
- }
- if (pri) {
- start = pri->crvs;
- lock = &pri->lock;
- } else {
- ast_cli(fd, "No such trunk group %d\n", trunkgroup);
- return RESULT_FAILURE;
- }
- } else
-#endif
- channel = atoi(argv[3]);
-
- ast_mutex_lock(lock);
- tmp = start;
- while (tmp) {
- if (tmp->channel == channel) {
-#ifdef HAVE_PRI
- if (pri)
- ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
- else
-#endif
- ast_cli(fd, "Channel: %d\n", tmp->channel);
- ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
- ast_cli(fd, "Span: %d\n", tmp->span);
- ast_cli(fd, "Extension: %s\n", tmp->exten);
- ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
- ast_cli(fd, "Context: %s\n", tmp->context);
- ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
- ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
- ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
- ast_cli(fd, "Destroy: %d\n", tmp->destroy);
- ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
- ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
- ast_cli(fd, "Radio: %d\n", tmp->radio);
- ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
- ast_cli(fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? tmp->subs[SUB_REAL].owner->name : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
- ast_cli(fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? tmp->subs[SUB_CALLWAIT].owner->name : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
- ast_cli(fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? tmp->subs[SUB_THREEWAY].owner->name : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
- ast_cli(fd, "Confno: %d\n", tmp->confno);
- ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
- ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
- ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
- ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
- ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
- ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
- ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
- ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
- ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
- if (tmp->master)
- ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
- for (x = 0; x < MAX_SLAVES; x++) {
- if (tmp->slaves[x])
- ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
- }
-#ifdef HAVE_PRI
- if (tmp->pri) {
- ast_cli(fd, "PRI Flags: ");
- if (tmp->resetting)
- ast_cli(fd, "Resetting ");
- if (tmp->call)
- ast_cli(fd, "Call ");
- if (tmp->bearer)
- ast_cli(fd, "Bearer ");
- ast_cli(fd, "\n");
- if (tmp->logicalspan)
- ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
- else
- ast_cli(fd, "PRI Logical Span: Implicit\n");
- }
-
-#endif
- memset(&ci, 0, sizeof(ci));
- ps.channo = tmp->channel;
- if (tmp->subs[SUB_REAL].zfd > -1) {
- if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
- ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
- }
-#ifdef ZT_GETCONFMUTE
- if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
- ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
- }
-#endif
- if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
- ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
- } else {
- ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
- }
- }
- ast_mutex_unlock(lock);
- return RESULT_SUCCESS;
- }
- tmp = tmp->next;
- }
-
- ast_cli(fd, "Unable to find given channel %d\n", channel);
- ast_mutex_unlock(lock);
- return RESULT_FAILURE;
-}
-
-static char zap_show_cadences_help[] =
-"Usage: zap show cadences\n"
-" Shows all cadences currently defined\n";
-
-static int handle_zap_show_cadences(int fd, int argc, char *argv[])
-{
- int i, j;
- for (i = 0; i < num_cadence; i++) {
- char output[1024];
- char tmp[16], tmp2[64];
- snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
- term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
-
- for (j = 0; j < 16; j++) {
- if (cadences[i].ringcadence[j] == 0)
- break;
- snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
- if (cidrings[i] * 2 - 1 == j)
- term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
- else
- term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
- if (j != 0)
- strncat(output, ",", sizeof(output) - strlen(output) - 1);
- strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
- }
- ast_cli(fd,"%s\n",output);
- }
- return 0;
-}
-
-/* Based on irqmiss.c */
-static int zap_show_status(int fd, int argc, char *argv[]) {
- #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
- #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
-
- int span;
- int res;
- char alarms[50];
-
- int ctl;
- ZT_SPANINFO s;
-
- ctl = open("/dev/zap/ctl", O_RDWR);
- if (ctl < 0) {
- ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
- ast_cli(fd, "No Zaptel interface found.\n");
- return RESULT_FAILURE;
- }
- ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
-
- for (span = 1; span < ZT_MAX_SPANS; ++span) {
- s.spanno = span;
- res = ioctl(ctl, ZT_SPANSTAT, &s);
- if (res) {
- continue;
- }
- alarms[0] = '\0';
- if (s.alarms > 0) {
- if (s.alarms & ZT_ALARM_BLUE)
- strcat(alarms, "BLU/");
- if (s.alarms & ZT_ALARM_YELLOW)
- strcat(alarms, "YEL/");
- if (s.alarms & ZT_ALARM_RED)
- strcat(alarms, "RED/");
- if (s.alarms & ZT_ALARM_LOOPBACK)
- strcat(alarms, "LB/");
- if (s.alarms & ZT_ALARM_RECOVER)
- strcat(alarms, "REC/");
- if (s.alarms & ZT_ALARM_NOTOPEN)
- strcat(alarms, "NOP/");
- if (!strlen(alarms))
- strcat(alarms, "UUU/");
- if (strlen(alarms)) {
- /* Strip trailing / */
- alarms[strlen(alarms) - 1] = '\0';
- }
- } else {
- if (s.numchans)
- strcpy(alarms, "OK");
- else
- strcpy(alarms, "UNCONFIGURED");
- }
-
- ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
- }
- close(ctl);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static char show_channels_usage[] =
- "Usage: zap show channels\n"
- " Shows a list of available channels\n";
-
-static char show_channel_usage[] =
- "Usage: zap show channel <chan num>\n"
- " Detailed information about a given channel\n";
-
-static char zap_show_status_usage[] =
- "Usage: zap show status\n"
- " Shows a list of Zaptel cards with status\n";
-
-static char destroy_channel_usage[] =
- "Usage: zap destroy channel <chan num>\n"
- " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
-
-static char zap_restart_usage[] =
- "Usage: zap restart\n"
- " Restarts the zaptel channels: destroys them all and then\n"
- " re-reads them from zapata.conf.\n"
- " Note that this will STOP any running CALL on zaptel channels.\n"
- "";
-
-static struct ast_cli_entry zap_cli[] = {
- { { "zap", "show", "cadences", NULL },
- handle_zap_show_cadences, "List cadences",
- zap_show_cadences_help },
-
- { { "zap", "show", "channels", NULL},
- zap_show_channels, "Show active zapata channels",
- show_channels_usage },
-
- { { "zap", "show", "channel", NULL},
- zap_show_channel, "Show information on a channel",
- show_channel_usage },
-
- { { "zap", "destroy", "channel", NULL},
- zap_destroy_channel, "Destroy a channel",
- destroy_channel_usage },
-
- { { "zap", "restart", NULL},
- zap_restart_cmd, "Fully restart zaptel channels",
- zap_restart_usage },
-
- { { "zap", "show", "status", NULL},
- zap_show_status, "Show all Zaptel cards status",
- zap_show_status_usage },
-};
-
-#define TRANSFER 0
-#define HANGUP 1
-
-static int zap_fake_event(struct zt_pvt *p, int mode)
-{
- if (p) {
- switch (mode) {
- case TRANSFER:
- p->fake_event = ZT_EVENT_WINKFLASH;
- break;
- case HANGUP:
- p->fake_event = ZT_EVENT_ONHOOK;
- break;
- default:
- ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);
- }
- }
- return 0;
-}
-static struct zt_pvt *find_channel(int channel)
-{
- struct zt_pvt *p = iflist;
- while (p) {
- if (p->channel == channel) {
- break;
- }
- p = p->next;
- }
- return p;
-}
-
-static int action_zapdndon(struct mansession *s, const struct message *m)
-{
- struct zt_pvt *p = NULL;
- const char *channel = astman_get_header(m, "ZapChannel");
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- p = find_channel(atoi(channel));
- if (!p) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- p->dnd = 1;
- astman_send_ack(s, m, "DND Enabled");
- return 0;
-}
-
-static int action_zapdndoff(struct mansession *s, const struct message *m)
-{
- struct zt_pvt *p = NULL;
- const char *channel = astman_get_header(m, "ZapChannel");
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- p = find_channel(atoi(channel));
- if (!p) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- p->dnd = 0;
- astman_send_ack(s, m, "DND Disabled");
- return 0;
-}
-
-static int action_transfer(struct mansession *s, const struct message *m)
-{
- struct zt_pvt *p = NULL;
- const char *channel = astman_get_header(m, "ZapChannel");
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- p = find_channel(atoi(channel));
- if (!p) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- zap_fake_event(p,TRANSFER);
- astman_send_ack(s, m, "ZapTransfer");
- return 0;
-}
-
-static int action_transferhangup(struct mansession *s, const struct message *m)
-{
- struct zt_pvt *p = NULL;
- const char *channel = astman_get_header(m, "ZapChannel");
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- p = find_channel(atoi(channel));
- if (!p) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- zap_fake_event(p,HANGUP);
- astman_send_ack(s, m, "ZapHangup");
- return 0;
-}
-
-static int action_zapdialoffhook(struct mansession *s, const struct message *m)
-{
- struct zt_pvt *p = NULL;
- const char *channel = astman_get_header(m, "ZapChannel");
- const char *number = astman_get_header(m, "Number");
- int i;
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- if (ast_strlen_zero(number)) {
- astman_send_error(s, m, "No number specified");
- return 0;
- }
- p = find_channel(atoi(channel));
- if (!p) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- if (!p->owner) {
- astman_send_error(s, m, "Channel does not have it's owner");
- return 0;
- }
- for (i = 0; i < strlen(number); i++) {
- struct ast_frame f = { AST_FRAME_DTMF, number[i] };
- zap_queue_frame(p, &f, NULL);
- }
- astman_send_ack(s, m, "ZapDialOffhook");
- return 0;
-}
-
-static int action_zapshowchannels(struct mansession *s, const struct message *m)
-{
- struct zt_pvt *tmp = NULL;
- const char *id = astman_get_header(m, "ActionID");
- char idText[256] = "";
-
- astman_send_ack(s, m, "Zapata channel status will follow");
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
-
- ast_mutex_lock(&iflock);
-
- tmp = iflist;
- while (tmp) {
- if (tmp->channel > 0) {
- int alarm = get_alarms(tmp);
- astman_append(s,
- "Event: ZapShowChannels\r\n"
- "Channel: %d\r\n"
- "Signalling: %s\r\n"
- "Context: %s\r\n"
- "DND: %s\r\n"
- "Alarm: %s\r\n"
- "%s"
- "\r\n",
- tmp->channel, sig2str(tmp->sig), tmp->context,
- tmp->dnd ? "Enabled" : "Disabled",
- alarm2str(alarm), idText);
- }
-
- tmp = tmp->next;
- }
-
- ast_mutex_unlock(&iflock);
-
- astman_append(s,
- "Event: ZapShowChannelsComplete\r\n"
- "%s"
- "\r\n",
- idText);
- return 0;
-}
-
-static int __unload_module(void)
-{
- int x;
- struct zt_pvt *p, *pl;
-
-#ifdef HAVE_PRI
- int i;
- for (i = 0; i < NUM_SPANS; i++) {
- if (pris[i].master != AST_PTHREADT_NULL)
- pthread_cancel(pris[i].master);
- }
- ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
- ast_unregister_application(zap_send_keypad_facility_app);
-#endif
- ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
- ast_manager_unregister( "ZapDialOffhook" );
- ast_manager_unregister( "ZapHangup" );
- ast_manager_unregister( "ZapTransfer" );
- ast_manager_unregister( "ZapDNDoff" );
- ast_manager_unregister( "ZapDNDon" );
- ast_manager_unregister("ZapShowChannels");
- ast_manager_unregister("ZapRestart");
- ast_channel_unregister(&zap_tech);
- ast_mutex_lock(&iflock);
- /* Hangup all interfaces if they have an owner */
- p = iflist;
- while (p) {
- if (p->owner)
- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
- p = p->next;
- }
- ast_mutex_unlock(&iflock);
- ast_mutex_lock(&monlock);
- if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
- pthread_cancel(monitor_thread);
- pthread_kill(monitor_thread, SIGURG);
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
-
- ast_mutex_lock(&iflock);
- /* Destroy all the interfaces and free their memory */
- p = iflist;
- while (p) {
- /* Free any callerid */
- if (p->cidspill)
- free(p->cidspill);
- /* Close the zapata thingy */
- if (p->subs[SUB_REAL].zfd > -1)
- zt_close(p->subs[SUB_REAL].zfd);
- pl = p;
- p = p->next;
- x = pl->channel;
- /* Free associated memory */
- if (pl)
- destroy_zt_pvt(&pl);
- ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
- }
- iflist = NULL;
- ifcount = 0;
- ast_mutex_unlock(&iflock);
-#ifdef HAVE_PRI
- for (i = 0; i < NUM_SPANS; i++) {
- if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
- pthread_join(pris[i].master, NULL);
- zt_close(pris[i].fds[i]);
- }
-#endif
- return 0;
-}
-
-static int unload_module(void)
-{
-#ifdef HAVE_PRI
- int y;
- for (y = 0; y < NUM_SPANS; y++)
- ast_mutex_destroy(&pris[y].lock);
-#endif
- return __unload_module();
-}
-
-static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
-{
- char *c, *chan;
- int x, start, finish;
- struct zt_pvt *tmp;
-#ifdef HAVE_PRI
- struct zt_pri *pri;
- int trunkgroup, y;
-#endif
-
- if ((reload == 0) && (conf.chan.sig < 0)) {
- ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
- return -1;
- }
-
- c = ast_strdupa(value);
-
-#ifdef HAVE_PRI
- pri = NULL;
- if (iscrv) {
- if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
- ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
- return -1;
- }
- if (trunkgroup < 1) {
- ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
- return -1;
- }
- c += y;
- for (y = 0; y < NUM_SPANS; y++) {
- if (pris[y].trunkgroup == trunkgroup) {
- pri = pris + y;
- break;
- }
- }
- if (!pri) {
- ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
- return -1;
- }
- }
-#endif
-
- while ((chan = strsep(&c, ","))) {
- if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
- /* Range */
- } else if (sscanf(chan, "%d", &start)) {
- /* Just one */
- finish = start;
- } else if (!strcasecmp(chan, "pseudo")) {
- finish = start = CHAN_PSEUDO;
- if (found_pseudo)
- *found_pseudo = 1;
- } else {
- ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
- return -1;
- }
- if (finish < start) {
- ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
- x = finish;
- finish = start;
- start = x;
- }
-
- for (x = start; x <= finish; x++) {
-#ifdef HAVE_PRI
- tmp = mkintf(x, conf, pri, reload);
-#else
- tmp = mkintf(x, conf, NULL, reload);
-#endif
-
- if (tmp) {
- if (option_verbose > 2) {
-#ifdef HAVE_PRI
- if (pri)
- ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
- else
-#endif
- ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
- }
- } else {
- ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
- (reload == 1) ? "reconfigure" : "register", value);
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-/** The length of the parameters list of 'zapchan'.
- * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
-#define MAX_CHANLIST_LEN 80
-static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
-{
- struct zt_pvt *tmp;
- char *ringc; /* temporary string for parsing the dring number. */
- int y;
- int found_pseudo = 0;
- char zapchan[MAX_CHANLIST_LEN] = {};
-
- for (; v; v = v->next) {
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
- continue;
-
- /* Create the interface list */
- if (!strcasecmp(v->name, "channel")
-#ifdef HAVE_PRI
- || !strcasecmp(v->name, "crv")
-#endif
- ) {
- int iscrv;
- if (skipchannels)
- continue;
- iscrv = !strcasecmp(v->name, "crv");
- if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
- return -1;
- } else if (!strcasecmp(v->name, "zapchan")) {
- ast_copy_string(zapchan, v->value, sizeof(zapchan));
- } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
- if (ast_true(v->value))
- confp->chan.usedistinctiveringdetection = 1;
- } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
- if (ast_true(v->value))
- distinctiveringaftercid = 1;
- } else if (!strcasecmp(v->name, "dring1context")) {
- ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
- } else if (!strcasecmp(v->name, "dring2context")) {
- ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
- } else if (!strcasecmp(v->name, "dring3context")) {
- ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
- } else if (!strcasecmp(v->name, "dring1")) {
- ringc = v->value;
- sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
- } else if (!strcasecmp(v->name, "dring2")) {
- ringc = v->value;
- sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
- } else if (!strcasecmp(v->name, "dring3")) {
- ringc = v->value;
- sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
- } else if (!strcasecmp(v->name, "usecallerid")) {
- confp->chan.use_callerid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "cidsignalling")) {
- if (!strcasecmp(v->value, "bell"))
- confp->chan.cid_signalling = CID_SIG_BELL;
- else if (!strcasecmp(v->value, "v23"))
- confp->chan.cid_signalling = CID_SIG_V23;
- else if (!strcasecmp(v->value, "dtmf"))
- confp->chan.cid_signalling = CID_SIG_DTMF;
- else if (!strcasecmp(v->value, "smdi"))
- confp->chan.cid_signalling = CID_SIG_SMDI;
- else if (!strcasecmp(v->value, "v23_jp"))
- confp->chan.cid_signalling = CID_SIG_V23_JP;
- else if (ast_true(v->value))
- confp->chan.cid_signalling = CID_SIG_BELL;
- } else if (!strcasecmp(v->name, "cidstart")) {
- if (!strcasecmp(v->value, "ring"))
- confp->chan.cid_start = CID_START_RING;
- else if (!strcasecmp(v->value, "polarity"))
- confp->chan.cid_start = CID_START_POLARITY;
- else if (ast_true(v->value))
- confp->chan.cid_start = CID_START_RING;
- } else if (!strcasecmp(v->name, "threewaycalling")) {
- confp->chan.threewaycalling = ast_true(v->value);
- } else if (!strcasecmp(v->name, "cancallforward")) {
- confp->chan.cancallforward = ast_true(v->value);
- } else if (!strcasecmp(v->name, "relaxdtmf")) {
- if (ast_true(v->value))
- confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
- else
- confp->chan.dtmfrelax = 0;
- } else if (!strcasecmp(v->name, "mailbox")) {
- ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
- } else if (!strcasecmp(v->name, "adsi")) {
- confp->chan.adsi = ast_true(v->value);
- } else if (!strcasecmp(v->name, "usesmdi")) {
- confp->chan.use_smdi = ast_true(v->value);
- } else if (!strcasecmp(v->name, "smdiport")) {
- ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
- } else if (!strcasecmp(v->name, "transfer")) {
- confp->chan.transfer = ast_true(v->value);
- } else if (!strcasecmp(v->name, "canpark")) {
- confp->chan.canpark = ast_true(v->value);
- } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
- confp->chan.echocanbridged = ast_true(v->value);
- } else if (!strcasecmp(v->name, "busydetect")) {
- confp->chan.busydetect = ast_true(v->value);
- } else if (!strcasecmp(v->name, "busycount")) {
- confp->chan.busycount = atoi(v->value);
- } else if (!strcasecmp(v->name, "busypattern")) {
- if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
- ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
- }
- } else if (!strcasecmp(v->name, "callprogress")) {
- if (ast_true(v->value))
- confp->chan.callprogress |= 1;
- else
- confp->chan.callprogress &= ~1;
- } else if (!strcasecmp(v->name, "faxdetect")) {
- if (!strcasecmp(v->value, "incoming")) {
- confp->chan.callprogress |= 4;
- confp->chan.callprogress &= ~2;
- } else if (!strcasecmp(v->value, "outgoing")) {
- confp->chan.callprogress &= ~4;
- confp->chan.callprogress |= 2;
- } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
- confp->chan.callprogress |= 6;
- else
- confp->chan.callprogress &= ~6;
- } else if (!strcasecmp(v->name, "echocancel")) {
- if (!ast_strlen_zero(v->value)) {
- y = atoi(v->value);
- } else
- y = 0;
- if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
- confp->chan.echocancel = y;
- else {
- confp->chan.echocancel = ast_true(v->value);
- if (confp->chan.echocancel)
- confp->chan.echocancel=128;
- }
- } else if (!strcasecmp(v->name, "echotraining")) {
- if (sscanf(v->value, "%d", &y) == 1) {
- if ((y < 10) || (y > 4000)) {
- ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);
- } else {
- confp->chan.echotraining = y;
- }
- } else if (ast_true(v->value)) {
- confp->chan.echotraining = 400;
- } else
- confp->chan.echotraining = 0;
- } else if (!strcasecmp(v->name, "hidecallerid")) {
- confp->chan.hidecallerid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "hidecalleridname")) {
- confp->chan.hidecalleridname = ast_true(v->value);
- } else if (!strcasecmp(v->name, "pulsedial")) {
- confp->chan.pulse = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callreturn")) {
- confp->chan.callreturn = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callwaiting")) {
- confp->chan.callwaiting = ast_true(v->value);
- } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
- confp->chan.callwaitingcallerid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "context")) {
- ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
- } else if (!strcasecmp(v->name, "language")) {
- ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
- } else if (!strcasecmp(v->name, "progzone")) {
- ast_copy_string(progzone, v->value, sizeof(progzone));
- } else if (!strcasecmp(v->name, "mohinterpret")
- ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
- ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
- } else if (!strcasecmp(v->name, "mohsuggest")) {
- ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
- } else if (!strcasecmp(v->name, "stripmsd")) {
- confp->chan.stripmsd = atoi(v->value);
- } else if (!strcasecmp(v->name, "jitterbuffers")) {
- numbufs = atoi(v->value);
- } else if (!strcasecmp(v->name, "group")) {
- confp->chan.group = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "callgroup")) {
- confp->chan.callgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "pickupgroup")) {
- confp->chan.pickupgroup = ast_get_group(v->value);
- } else if (!strcasecmp(v->name, "immediate")) {
- confp->chan.immediate = ast_true(v->value);
- } else if (!strcasecmp(v->name, "transfertobusy")) {
- confp->chan.transfertobusy = ast_true(v->value);
- } else if (!strcasecmp(v->name, "rxgain")) {
- if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
- ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
- }
- } else if (!strcasecmp(v->name, "txgain")) {
- if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
- ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
- }
- } else if (!strcasecmp(v->name, "tonezone")) {
- if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
- ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
- }
- } else if (!strcasecmp(v->name, "callerid")) {
- if (!strcasecmp(v->value, "asreceived")) {
- confp->chan.cid_num[0] = '\0';
- confp->chan.cid_name[0] = '\0';
- } else {
- ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
- }
- } else if (!strcasecmp(v->name, "fullname")) {
- ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
- } else if (!strcasecmp(v->name, "cid_number")) {
- ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
- } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
- confp->chan.zaptrcallerid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "restrictcid")) {
- confp->chan.restrictcid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "usecallingpres")) {
- confp->chan.use_callingpres = ast_true(v->value);
- } else if (!strcasecmp(v->name, "accountcode")) {
- ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
- } else if (!strcasecmp(v->name, "amaflags")) {
- y = ast_cdr_amaflags2int(v->value);
- if (y < 0)
- ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
- else
- confp->chan.amaflags = y;
- } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
- confp->chan.polarityonanswerdelay = atoi(v->value);
- } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
- confp->chan.answeronpolarityswitch = ast_true(v->value);
- } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
- confp->chan.hanguponpolarityswitch = ast_true(v->value);
- } else if (!strcasecmp(v->name, "sendcalleridafter")) {
- confp->chan.sendcalleridafter = atoi(v->value);
- } else if (!reload){
- if (!strcasecmp(v->name, "signalling")) {
- confp->chan.outsigmod = -1;
- if (!strcasecmp(v->value, "em")) {
- confp->chan.sig = SIG_EM;
- } else if (!strcasecmp(v->value, "em_e1")) {
- confp->chan.sig = SIG_EM_E1;
- } else if (!strcasecmp(v->value, "em_w")) {
- confp->chan.sig = SIG_EMWINK;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxs_ls")) {
- confp->chan.sig = SIG_FXSLS;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxs_gs")) {
- confp->chan.sig = SIG_FXSGS;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxs_ks")) {
- confp->chan.sig = SIG_FXSKS;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxo_ls")) {
- confp->chan.sig = SIG_FXOLS;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxo_gs")) {
- confp->chan.sig = SIG_FXOGS;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxo_ks")) {
- confp->chan.sig = SIG_FXOKS;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fxs_rx")) {
- confp->chan.sig = SIG_FXSKS;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "fxo_rx")) {
- confp->chan.sig = SIG_FXOLS;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "fxs_tx")) {
- confp->chan.sig = SIG_FXSLS;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "fxo_tx")) {
- confp->chan.sig = SIG_FXOGS;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "em_rx")) {
- confp->chan.sig = SIG_EM;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "em_tx")) {
- confp->chan.sig = SIG_EM;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "em_rxtx")) {
- confp->chan.sig = SIG_EM;
- confp->chan.radio = 2;
- } else if (!strcasecmp(v->value, "em_txrx")) {
- confp->chan.sig = SIG_EM;
- confp->chan.radio = 2;
- } else if (!strcasecmp(v->value, "sf")) {
- confp->chan.sig = SIG_SF;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "sf_w")) {
- confp->chan.sig = SIG_SFWINK;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "sf_featd")) {
- confp->chan.sig = SIG_FEATD;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "sf_featdmf")) {
- confp->chan.sig = SIG_FEATDMF;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "sf_featb")) {
- confp->chan.sig = SIG_SF_FEATB;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "sf")) {
- confp->chan.sig = SIG_SF;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "sf_rx")) {
- confp->chan.sig = SIG_SF;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "sf_tx")) {
- confp->chan.sig = SIG_SF;
- confp->chan.radio = 1;
- } else if (!strcasecmp(v->value, "sf_rxtx")) {
- confp->chan.sig = SIG_SF;
- confp->chan.radio = 2;
- } else if (!strcasecmp(v->value, "sf_txrx")) {
- confp->chan.sig = SIG_SF;
- confp->chan.radio = 2;
- } else if (!strcasecmp(v->value, "featd")) {
- confp->chan.sig = SIG_FEATD;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "featdmf")) {
- confp->chan.sig = SIG_FEATDMF;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "featdmf_ta")) {
- confp->chan.sig = SIG_FEATDMF_TA;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "e911")) {
- confp->chan.sig = SIG_E911;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fgccama")) {
- confp->chan.sig = SIG_FGC_CAMA;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "fgccamamf")) {
- confp->chan.sig = SIG_FGC_CAMAMF;
- confp->chan.radio = 0;
- } else if (!strcasecmp(v->value, "featb")) {
- confp->chan.sig = SIG_FEATB;
- confp->chan.radio = 0;
-#ifdef HAVE_PRI
- } else if (!strcasecmp(v->value, "pri_net")) {
- confp->chan.radio = 0;
- confp->chan.sig = SIG_PRI;
- confp->pri.nodetype = PRI_NETWORK;
- } else if (!strcasecmp(v->value, "pri_cpe")) {
- confp->chan.sig = SIG_PRI;
- confp->chan.radio = 0;
- confp->pri.nodetype = PRI_CPE;
- } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
- confp->chan.sig = SIG_GR303FXOKS;
- confp->chan.radio = 0;
- confp->pri.nodetype = PRI_NETWORK;
- } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
- confp->chan.sig = SIG_GR303FXSKS;
- confp->chan.radio = 0;
- confp->pri.nodetype = PRI_CPE;
-#endif
- } else {
- ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
- }
- } else if (!strcasecmp(v->name, "outsignalling")) {
- if (!strcasecmp(v->value, "em")) {
- confp->chan.outsigmod = SIG_EM;
- } else if (!strcasecmp(v->value, "em_e1")) {
- confp->chan.outsigmod = SIG_EM_E1;
- } else if (!strcasecmp(v->value, "em_w")) {
- confp->chan.outsigmod = SIG_EMWINK;
- } else if (!strcasecmp(v->value, "sf")) {
- confp->chan.outsigmod = SIG_SF;
- } else if (!strcasecmp(v->value, "sf_w")) {
- confp->chan.outsigmod = SIG_SFWINK;
- } else if (!strcasecmp(v->value, "sf_featd")) {
- confp->chan.outsigmod = SIG_FEATD;
- } else if (!strcasecmp(v->value, "sf_featdmf")) {
- confp->chan.outsigmod = SIG_FEATDMF;
- } else if (!strcasecmp(v->value, "sf_featb")) {
- confp->chan.outsigmod = SIG_SF_FEATB;
- } else if (!strcasecmp(v->value, "sf")) {
- confp->chan.outsigmod = SIG_SF;
- } else if (!strcasecmp(v->value, "featd")) {
- confp->chan.outsigmod = SIG_FEATD;
- } else if (!strcasecmp(v->value, "featdmf")) {
- confp->chan.outsigmod = SIG_FEATDMF;
- } else if (!strcasecmp(v->value, "featdmf_ta")) {
- confp->chan.outsigmod = SIG_FEATDMF_TA;
- } else if (!strcasecmp(v->value, "e911")) {
- confp->chan.outsigmod = SIG_E911;
- } else if (!strcasecmp(v->value, "fgccama")) {
- confp->chan.outsigmod = SIG_FGC_CAMA;
- } else if (!strcasecmp(v->value, "fgccamamf")) {
- confp->chan.outsigmod = SIG_FGC_CAMAMF;
- } else if (!strcasecmp(v->value, "featb")) {
- confp->chan.outsigmod = SIG_FEATB;
- } else {
- ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
- }
-#ifdef HAVE_PRI
- } else if (!strcasecmp(v->name, "pridialplan")) {
- if (!strcasecmp(v->value, "national")) {
- confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "unknown")) {
- confp->pri.dialplan = PRI_UNKNOWN + 1;
- } else if (!strcasecmp(v->value, "private")) {
- confp->pri.dialplan = PRI_PRIVATE + 1;
- } else if (!strcasecmp(v->value, "international")) {
- confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "local")) {
- confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "dynamic")) {
- confp->pri.dialplan = -1;
- } else {
- ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "prilocaldialplan")) {
- if (!strcasecmp(v->value, "national")) {
- confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "unknown")) {
- confp->pri.localdialplan = PRI_UNKNOWN + 1;
- } else if (!strcasecmp(v->value, "private")) {
- confp->pri.localdialplan = PRI_PRIVATE + 1;
- } else if (!strcasecmp(v->value, "international")) {
- confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "local")) {
- confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "dynamic")) {
- confp->pri.localdialplan = -1;
- } else {
- ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "switchtype")) {
- if (!strcasecmp(v->value, "national"))
- confp->pri.switchtype = PRI_SWITCH_NI2;
- else if (!strcasecmp(v->value, "ni1"))
- confp->pri.switchtype = PRI_SWITCH_NI1;
- else if (!strcasecmp(v->value, "dms100"))
- confp->pri.switchtype = PRI_SWITCH_DMS100;
- else if (!strcasecmp(v->value, "4ess"))
- confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
- else if (!strcasecmp(v->value, "5ess"))
- confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
- else if (!strcasecmp(v->value, "euroisdn"))
- confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
- else if (!strcasecmp(v->value, "qsig"))
- confp->pri.switchtype = PRI_SWITCH_QSIG;
- else {
- ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
- return -1;
- }
- } else if (!strcasecmp(v->name, "nsf")) {
- if (!strcasecmp(v->value, "sdn"))
- confp->pri.nsf = PRI_NSF_SDN;
- else if (!strcasecmp(v->value, "megacom"))
- confp->pri.nsf = PRI_NSF_MEGACOM;
- else if (!strcasecmp(v->value, "tollfreemegacom"))
- confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
- else if (!strcasecmp(v->value, "accunet"))
- confp->pri.nsf = PRI_NSF_ACCUNET;
- else if (!strcasecmp(v->value, "none"))
- confp->pri.nsf = PRI_NSF_NONE;
- else {
- ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
- confp->pri.nsf = PRI_NSF_NONE;
- }
- } else if (!strcasecmp(v->name, "priindication")) {
- if (!strcasecmp(v->value, "outofband"))
- confp->chan.priindication_oob = 1;
- else if (!strcasecmp(v->value, "inband"))
- confp->chan.priindication_oob = 0;
- else
- ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
- v->value, v->lineno);
- } else if (!strcasecmp(v->name, "priexclusive")) {
- confp->chan.priexclusive = ast_true(v->value);
- } else if (!strcasecmp(v->name, "internationalprefix")) {
- ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
- } else if (!strcasecmp(v->name, "nationalprefix")) {
- ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
- } else if (!strcasecmp(v->name, "localprefix")) {
- ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
- } else if (!strcasecmp(v->name, "privateprefix")) {
- ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
- } else if (!strcasecmp(v->name, "unknownprefix")) {
- ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
- } else if (!strcasecmp(v->name, "resetinterval")) {
- if (!strcasecmp(v->value, "never"))
- confp->pri.resetinterval = -1;
- else if (atoi(v->value) >= 60)
- confp->pri.resetinterval = atoi(v->value);
- else
- ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
- v->value, v->lineno);
- } else if (!strcasecmp(v->name, "minunused")) {
- confp->pri.minunused = atoi(v->value);
- } else if (!strcasecmp(v->name, "minidle")) {
- confp->pri.minidle = atoi(v->value);
- } else if (!strcasecmp(v->name, "idleext")) {
- ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
- } else if (!strcasecmp(v->name, "idledial")) {
- ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
- } else if (!strcasecmp(v->name, "overlapdial")) {
- confp->pri.overlapdial = ast_true(v->value);
- } else if (!strcasecmp(v->name, "pritimer")) {
-#ifdef PRI_GETSET_TIMERS
- char *timerc, *c;
- int timer, timeridx;
- c = v->value;
- timerc = strsep(&c, ",");
- if (timerc) {
- timer = atoi(c);
- if (!timer)
- ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
- else {
- if ((timeridx = pri_timer2idx(timerc)) >= 0)
- pritimers[timeridx] = timer;
- else
- ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
- }
- } else
- ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
-
- } else if (!strcasecmp(v->name, "facilityenable")) {
- confp->pri.facilityenable = ast_true(v->value);
-#endif /* PRI_GETSET_TIMERS */
-#endif /* HAVE_PRI */
- } else if (!strcasecmp(v->name, "cadence")) {
- /* setup to scan our argument */
- int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- int i;
- struct zt_ring_cadence new_cadence;
- int cid_location = -1;
- int firstcadencepos = 0;
- char original_args[80];
- int cadence_is_ok = 1;
-
- ast_copy_string(original_args, v->value, sizeof(original_args));
- /* 16 cadences allowed (8 pairs) */
- element_count = sscanf(v->value, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
-
- /* Cadence must be even (on/off) */
- if (element_count % 2 == 1) {
- ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
- cadence_is_ok = 0;
- }
-
- /* Ring cadences cannot be negative */
- for (i = 0; i < element_count; i++) {
- if (c[i] == 0) {
- ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
- cadence_is_ok = 0;
- break;
- } else if (c[i] < 0) {
- if (i % 2 == 1) {
- /* Silence duration, negative possibly okay */
- if (cid_location == -1) {
- cid_location = i;
- c[i] *= -1;
- } else {
- ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
- cadence_is_ok = 0;
- break;
- }
- } else {
- if (firstcadencepos == 0) {
- firstcadencepos = i; /* only recorded to avoid duplicate specification */
- /* duration will be passed negative to the zaptel driver */
- } else {
- ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
- cadence_is_ok = 0;
- break;
- }
- }
- }
- }
-
- /* Substitute our scanned cadence */
- for (i = 0; i < 16; i++) {
- new_cadence.ringcadence[i] = c[i];
- }
-
- if (cadence_is_ok) {
- /* ---we scanned it without getting annoyed; now some sanity checks--- */
- if (element_count < 2) {
- ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
- } else {
- if (cid_location == -1) {
- /* user didn't say; default to first pause */
- cid_location = 1;
- } else {
- /* convert element_index to cidrings value */
- cid_location = (cid_location + 1) / 2;
- }
- /* ---we like their cadence; try to install it--- */
- if (!user_has_defined_cadences++)
- /* this is the first user-defined cadence; clear the default user cadences */
- num_cadence = 0;
- if ((num_cadence+1) >= NUM_CADENCE_MAX)
- ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
- else {
- cadences[num_cadence] = new_cadence;
- cidrings[num_cadence++] = cid_location;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
- }
- }
- }
- } else if (!strcasecmp(v->name, "ringtimeout")) {
- ringt_base = (atoi(v->value) * 8) / READ_SIZE;
- } else if (!strcasecmp(v->name, "prewink")) {
- confp->timing.prewinktime = atoi(v->value);
- } else if (!strcasecmp(v->name, "preflash")) {
- confp->timing.preflashtime = atoi(v->value);
- } else if (!strcasecmp(v->name, "wink")) {
- confp->timing.winktime = atoi(v->value);
- } else if (!strcasecmp(v->name, "flash")) {
- confp->timing.flashtime = atoi(v->value);
- } else if (!strcasecmp(v->name, "start")) {
- confp->timing.starttime = atoi(v->value);
- } else if (!strcasecmp(v->name, "rxwink")) {
- confp->timing.rxwinktime = atoi(v->value);
- } else if (!strcasecmp(v->name, "rxflash")) {
- confp->timing.rxflashtime = atoi(v->value);
- } else if (!strcasecmp(v->name, "debounce")) {
- confp->timing.debouncetime = atoi(v->value);
- } else if (!strcasecmp(v->name, "toneduration")) {
- int toneduration;
- int ctlfd;
- int res;
- struct zt_dialparams dps;
-
- ctlfd = open("/dev/zap/ctl", O_RDWR);
- if (ctlfd == -1) {
- ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
- return -1;
- }
-
- toneduration = atoi(v->value);
- if (toneduration > -1) {
- memset(&dps, 0, sizeof(dps));
-
- dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
- res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
- if (res < 0) {
- ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
- return -1;
- }
- }
- close(ctlfd);
- } else if (!strcasecmp(v->name, "defaultcic")) {
- ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
- } else if (!strcasecmp(v->name, "defaultozz")) {
- ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
- }
- } else if (!skipchannels)
- ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
- }
- if (zapchan[0]) {
- /* The user has set 'zapchan' */
- /*< \todo pass proper line number instead of 0 */
- if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) {
- return -1;
- }
- }
- /*< \todo why check for the pseudo in the per-channel section.
- * Any actual use for manual setup of the pseudo channel? */
- if (!found_pseudo && reload == 0) {
- /* Make sure pseudo isn't a member of any groups if
- we're automatically making it. */
-
- confp->chan.group = 0;
- confp->chan.callgroup = 0;
- confp->chan.pickupgroup = 0;
-
- tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload);
-
- if (tmp) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
- } else {
- ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
- }
- }
- return 0;
-}
-
-static int setup_zap(int reload)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- struct zt_chan_conf conf = zt_chan_conf_default();
- int res;
-
-#ifdef HAVE_PRI
- char *c;
- int spanno;
- int i, x;
- int logicalspan;
- int trunkgroup;
- int dchannels[NUM_DCHANS];
-#endif
-
- cfg = ast_config_load(config);
-
- /* Error if we have no config file */
- if (!cfg) {
- ast_log(LOG_ERROR, "Unable to load config %s\n", config);
- return 0;
- }
-
- /* It's a little silly to lock it, but we mind as well just to be sure */
- ast_mutex_lock(&iflock);
-#ifdef HAVE_PRI
- if (!reload) {
- /* Process trunkgroups first */
- v = ast_variable_browse(cfg, "trunkgroups");
- while (v) {
- if (!strcasecmp(v->name, "trunkgroup")) {
- trunkgroup = atoi(v->value);
- if (trunkgroup > 0) {
- if ((c = strchr(v->value, ','))) {
- i = 0;
- memset(dchannels, 0, sizeof(dchannels));
- while (c && (i < NUM_DCHANS)) {
- dchannels[i] = atoi(c + 1);
- if (dchannels[i] < 0) {
- ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of zapata.conf\n", trunkgroup, v->lineno);
- } else
- i++;
- c = strchr(c + 1, ',');
- }
- if (i) {
- if (pri_create_trunkgroup(trunkgroup, dchannels)) {
- ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of zapata.conf\n", trunkgroup, dchannels[0], v->lineno);
- } else if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
- } else
- ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
- } else
- ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
- } else
- ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
- } else if (!strcasecmp(v->name, "spanmap")) {
- spanno = atoi(v->value);
- if (spanno > 0) {
- if ((c = strchr(v->value, ','))) {
- trunkgroup = atoi(c + 1);
- if (trunkgroup > 0) {
- if ((c = strchr(c + 1, ',')))
- logicalspan = atoi(c + 1);
- else
- logicalspan = 0;
- if (logicalspan >= 0) {
- if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
- ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
- } else if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
- } else
- ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
- } else
- ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
- } else
- ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
- } else
- ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
- } else {
- ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
- }
- v = v->next;
- }
- }
-#endif
-
- /* Copy the default jb config over global_jbconf */
- memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
- v = ast_variable_browse(cfg, "channels");
- res = process_zap(&conf, v, reload, 0);
- ast_mutex_unlock(&iflock);
- ast_config_destroy(cfg);
- if (res)
- return res;
- cfg = ast_config_load("users.conf");
- if (cfg) {
- char *cat;
- const char *chans;
- process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
- for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
- if (!strcasecmp(cat, "general"))
- continue;
- chans = ast_variable_retrieve(cfg, cat, "zapchan");
- if (!ast_strlen_zero(chans)) {
- struct zt_chan_conf sect_conf;
- memcpy(&sect_conf, &conf, sizeof(sect_conf));
-
- process_zap(&sect_conf, ast_variable_browse(cfg, cat), reload, 0);
- }
- }
- ast_config_destroy(cfg);
- }
-#ifdef HAVE_PRI
- if (!reload) {
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].pvts[0]) {
- if (start_pri(pris + x)) {
- ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
- return -1;
- } else if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
- }
- }
- }
-#endif
- /* And start the monitor for the first time */
- restart_monitor();
- return 0;
-}
-
-static int load_module(void)
-{
- int res;
-
-#ifdef HAVE_PRI
- int y,i;
- memset(pris, 0, sizeof(pris));
- for (y = 0; y < NUM_SPANS; y++) {
- ast_mutex_init(&pris[y].lock);
- pris[y].offset = -1;
- pris[y].master = AST_PTHREADT_NULL;
- for (i = 0; i < NUM_DCHANS; i++)
- pris[y].fds[i] = -1;
- }
- pri_set_error(zt_pri_error);
- pri_set_message(zt_pri_message);
- ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
- zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
-#endif
- res = setup_zap(0);
- /* Make sure we can register our Zap channel type */
- if (res)
- return AST_MODULE_LOAD_DECLINE;
- if (ast_channel_register(&zap_tech)) {
- ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
- __unload_module();
- return -1;
- }
-#ifdef HAVE_PRI
- ast_string_field_init(&inuse, 16);
- ast_string_field_set(&inuse, name, "GR-303InUse");
- ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
-#endif
- ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
-
- memset(round_robin, 0, sizeof(round_robin));
- ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
- ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
- ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
- ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
- ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
- ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
- ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
-
- return res;
-}
-
-static int zt_sendtext(struct ast_channel *c, const char *text)
-{
-#define END_SILENCE_LEN 400
-#define HEADER_MS 50
-#define TRAILER_MS 5
-#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
-#define ASCII_BYTES_PER_CHAR 80
-
- unsigned char *buf,*mybuf;
- struct zt_pvt *p = c->tech_pvt;
- struct pollfd fds[1];
- int size,res,fd,len,x;
- int bytes=0;
- /* Initial carrier (imaginary) */
- float cr = 1.0;
- float ci = 0.0;
- float scont = 0.0;
- int index;
-
- index = zt_get_index(c, p, 0);
- if (index < 0) {
- ast_log(LOG_WARNING, "Huh? I don't exist?\n");
- return -1;
- }
- if (!text[0]) return(0); /* if nothing to send, dont */
- if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */
- if (p->mate)
- buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
- else
- buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
- if (!buf)
- return -1;
- mybuf = buf;
- if (p->mate) {
- int codec = AST_LAW(p);
- for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
- PUT_CLID_MARKMS;
- }
- /* Put actual message */
- for (x = 0; text[x]; x++) {
- PUT_CLID(text[x]);
- }
- for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */
- PUT_CLID_MARKMS;
- }
- len = bytes;
- buf = mybuf;
- } else {
- len = tdd_generate(p->tdd, buf, text);
- if (len < 1) {
- ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
- free(mybuf);
- return -1;
- }
- }
- memset(buf + len, 0x7f, END_SILENCE_LEN);
- len += END_SILENCE_LEN;
- fd = p->subs[index].zfd;
- while (len) {
- if (ast_check_hangup(c)) {
- free(mybuf);
- return -1;
- }
- size = len;
- if (size > READ_SIZE)
- size = READ_SIZE;
- fds[0].fd = fd;
- fds[0].events = POLLOUT | POLLPRI;
- fds[0].revents = 0;
- res = poll(fds, 1, -1);
- if (!res) {
- ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
- continue;
- }
- /* if got exception */
- if (fds[0].revents & POLLPRI) {
- ast_free(mybuf);
- return -1;
- }
- if (!(fds[0].revents & POLLOUT)) {
- ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
- continue;
- }
- res = write(fd, buf, size);
- if (res != size) {
- if (res == -1) {
- free(mybuf);
- return -1;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
- break;
- }
- len -= size;
- buf += size;
- }
- free(mybuf);
- return(0);
-}
-
-
-static int reload(void)
-{
- int res = 0;
-
- res = setup_zap(1);
- if (res) {
- ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
- return -1;
- }
- return 0;
-}
-
-/* This is a workaround so that menuselect displays a proper description
- * AST_MODULE_INFO(, , "Zapata Telephony"
- */
-
-#ifdef ZAPATA_PRI
-#define tdesc "Zapata Telephony w/PRI"
-#else
-#define tdesc "Zapata Telephony"
-#endif
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
-
diff --git a/1.4/channels/gentone-ulaw.c b/1.4/channels/gentone-ulaw.c
deleted file mode 100644
index b290d76c7..000000000
--- a/1.4/channels/gentone-ulaw.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Generate a header file for a particular
- single or double frequency */
-
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#define CLIP 32635
-#define BIAS 0x84
-static float loudness=16384.0;
-
-static int calc_samples(int freq)
-{
- int x, samples;
- /* Calculate the number of samples at 8000hz sampling
- we need to have this wave form */
- samples = 8000;
- /* Take out common 2's up to six times */
- for (x=0;x<6;x++)
- if (!(freq % 2)) {
- freq /= 2;
- samples /= 2;
- }
- /* Take out common 5's (up to three times */
- for (x=0;x<3;x++)
- if (!(freq % 5)) {
- freq /= 5;
- samples /=5;
- }
- /* No more common factors. */
- return samples;
-}
-
-/*
-** This routine converts from linear to ulaw
-**
-** Craig Reese: IDA/Supercomputing Research Center
-** Joe Campbell: Department of Defense
-** 29 September 1989
-**
-** References:
-** 1) CCITT Recommendation G.711 (very difficult to follow)
-** 2) "A New Digital Technique for Implementation of Any
-** Continuous PCM Companding Law," Villeret, Michel,
-** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
-** 1973, pg. 11.12-11.17
-** 3) MIL-STD-188-113,"Interoperability and Performance Standards
-** for Analog-to_Digital Conversion Techniques,"
-** 17 February 1987
-**
-** Input: Signed 16 bit linear sample
-** Output: 8 bit ulaw sample
-*/
-
-#define ZEROTRAP /* turn on the trap as per the MIL-STD */
-#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
-#define CLIP 32635
-
-static unsigned char linear2ulaw(short sample) {
-static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
- int sign, exponent, mantissa;
- unsigned char ulawbyte;
-
- /* Get the sample into sign-magnitude. */
- sign = (sample >> 8) & 0x80; /* set aside the sign */
- if (sign != 0) sample = -sample; /* get magnitude */
- if (sample > CLIP) sample = CLIP; /* clip the magnitude */
-
- /* Convert from 16 bit linear to ulaw. */
- sample = sample + BIAS;
- exponent = exp_lut[(sample >> 7) & 0xFF];
- mantissa = (sample >> (exponent + 3)) & 0x0F;
- ulawbyte = ~(sign | (exponent << 4) | mantissa);
-#ifdef ZEROTRAP
- if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */
-#endif
-
- return(ulawbyte);
-}
-
-int main(int argc, char *argv[])
-{
- FILE *f;
- int freq1, freq2;
- float wlen1, wlen2;
- float val;
- int x, samples1, samples2, samples=0;
- char fn[256];
- if (argc < 3) {
- fprintf(stderr, "Usage: gensound <name> <freq1> [freq2]\n");
- exit(1);
- }
- freq1 = atoi(argv[2]);
- if (argc > 3)
- freq2 = atoi(argv[3]);
- else
- freq2 = 0;
- wlen1 = 8000.0/(float)freq1;
- samples1 = calc_samples(freq1);
- printf("Wavelength 1 (in samples): %10.5f\n", wlen1);
- printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples1, samples1 / wlen1);
- if (freq2) {
- wlen2 = 8000.0/(float)freq2;
- samples2 = calc_samples(freq2);
- printf("Wavelength 1 (in samples): %10.5f\n", wlen2);
- printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples2, samples2 / wlen2);
- }
- samples = samples1;
- if (freq2) {
- while(samples % samples2)
- samples += samples1;
- }
- printf("Need %d samples\n", samples);
- snprintf(fn, sizeof(fn), "%s.h", argv[1]);
- if ((f = fopen(fn, "w"))) {
- if (freq2)
- fprintf(f, "/* %s: Generated from frequencies %d and %d \n"
- " by gentone. %d samples */\n", fn, freq1, freq2, samples);
- else
- fprintf(f, "/* %s: Generated from frequency %d\n"
- " by gentone. %d samples */\n", fn, freq1, samples);
- fprintf(f, "static unsigned char %s[%d] = {\n\t", argv[1], samples);
- for (x=0;x<samples;x++) {
- val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);
- if (freq2)
- val += loudness * sin((freq2 * 2.0 * M_PI * x)/8000.0);
- fprintf(f, "%3d, ", (int) linear2ulaw(val));
- if (!((x+1) % 8))
- fprintf(f, "\n\t");
- }
- if (x % 15)
- fprintf(f, "\n");
- fprintf(f, "};\n");
- fclose(f);
- printf("Wrote %s\n", fn);
- } else {
- fprintf(stderr, "Unable to open %s for writing\n", fn);
- return 1;
- }
- return 0;
-}
diff --git a/1.4/channels/gentone.c b/1.4/channels/gentone.c
deleted file mode 100644
index 29bd88e91..000000000
--- a/1.4/channels/gentone.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Generate a header file for a particular
- single or double frequency */
-
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#define CLIP 32635
-#define BIAS 0x84
-static float loudness=16384.0;
-
-static int calc_samples(int freq)
-{
- int x, samples;
- /* Calculate the number of samples at 8000hz sampling
- we need to have this wave form */
- samples = 8000;
- /* Take out common 2's up to six times */
- for (x=0;x<6;x++)
- if (!(freq % 2)) {
- freq /= 2;
- samples /= 2;
- }
- /* Take out common 5's (up to three times */
- for (x=0;x<3;x++)
- if (!(freq % 5)) {
- freq /= 5;
- samples /=5;
- }
- /* No more common factors. */
- return samples;
-}
-
-int main(int argc, char *argv[])
-{
- FILE *f;
- int freq1, freq2;
- float wlen1, wlen2;
- float val;
- int x, samples1, samples2=0, samples=0;
- char fn[256];
- if (argc < 3) {
- fprintf(stderr, "Usage: gensound <name> <freq1> [freq2]\n");
- exit(1);
- }
- freq1 = atoi(argv[2]);
- if (argc > 3)
- freq2 = atoi(argv[3]);
- else
- freq2 = 0;
- wlen1 = 8000.0/(float)freq1;
- samples1 = calc_samples(freq1);
- printf("Wavelength 1 (in samples): %10.5f\n", wlen1);
- printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples1, samples1 / wlen1);
- if (freq2) {
- wlen2 = 8000.0/(float)freq2;
- samples2 = calc_samples(freq2);
- printf("Wavelength 1 (in samples): %10.5f\n", wlen2);
- printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples2, samples2 / wlen2);
- }
- samples = samples1;
- if (freq2) {
- while(samples % samples2)
- samples += samples1;
- }
- printf("Need %d samples\n", samples);
- snprintf(fn, sizeof(fn), "%s.h", argv[1]);
- if ((f = fopen(fn, "w"))) {
- if (freq2)
- fprintf(f, "/* %s: Generated from frequencies %d and %d \n"
- " by gentone. %d samples */\n", fn, freq1, freq2, samples);
- else
- fprintf(f, "/* %s: Generated from frequency %d\n"
- " by gentone. %d samples */\n", fn, freq1, samples);
- fprintf(f, "static short %s[%d] = {\n\t", argv[1], samples);
- for (x=0;x<samples;x++) {
- val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);
- if (freq2)
- val += loudness * sin((freq2 * 2.0 * M_PI * x)/8000.0);
- fprintf(f, "%5d, ", (int)val);
- if (!((x+1) % 8))
- fprintf(f, "\n\t");
- }
- if (x % 15)
- fprintf(f, "\n");
- fprintf(f, "};\n");
- fclose(f);
- printf("Wrote %s\n", fn);
- } else {
- fprintf(stderr, "Unable to open %s for writing\n", fn);
- return 1;
- }
- return 0;
-}
diff --git a/1.4/channels/h323/ChangeLog b/1.4/channels/h323/ChangeLog
deleted file mode 100644
index ddbf08193..000000000
--- a/1.4/channels/h323/ChangeLog
+++ /dev/null
@@ -1,43 +0,0 @@
-Build
- -- Hold lock when creating new H.323 channel to sync the audio channels
- -- Decrement usage counter when appropriate
- -- Actually unregister everything in unload_module
- -- Add IP based authentication using 'host'in type=user's
-0.1.0
- -- Intergration into the mainline Asterisk codebase
- -- Remove reduandant debug info
- -- Add Caller*id support
- -- Inband DTMF
- -- Retool port usage (to avoid possible seg fault condition)
-0.0.6
- -- Configurable support for user-input (DTMF)
- -- Reworked Gatekeeper support
- -- Native bridging (but is still broken, help!)
- -- Locally implement a non-broken G.723.1 Capability
- -- Utilize the cleaner RTP method implemented by Mark
- -- AllowGkRouted, thanks to Panny from http://hotlinks.co.uk
- -- Clened up inbound call flow
- -- Prefix, E.164 and Gateway support
- -- Multi-homed support
- -- Killed more seg's
-0.0.5
- -- Added H.323 Alias support
- -- Clened up inbound call flow
- -- Fixed RTP port logic
- -- Stomped on possible seg fault conditions thanks to Iain Stevenson
-0.0.4
- -- Fixed one-way audio on inbound calls. Found
- race condition in monitor thread.
-
-0.0.3
- -- Changed name to chan_h323
- -- Also renamed file names to futher avoid confusion
-
-0.0.2
- -- First public offering
- -- removed most hardcoded values
- -- lots of changes to alias/exension operation
-
-0.0.1
- -- initial build, lots of hardcoded crap
- -- Proof of concept for External RTP
diff --git a/1.4/channels/h323/INSTALL.openh323 b/1.4/channels/h323/INSTALL.openh323
deleted file mode 100644
index f46c37905..000000000
--- a/1.4/channels/h323/INSTALL.openh323
+++ /dev/null
@@ -1,18 +0,0 @@
-To build Open H.323 see:
-
-http://www.openh323.org/build.html#unix
-
-You only need to do 'make opt'. Anything else you will be simply waisting time and HD space.
-Also, you will notice they never tell you to 'make install' so don't do it.
-
-
-On FreeBSD, the Makefiles are configured to
-locate the compiled openh323 port, if it has
-been built. Here is one way to build
-openh323 and ptlib on such that the Makefiles
-find it:
- # cd /usr/ports/net/openh323
- # make
-It is not necessary to install the port. The
-asterisk makefiles do not use any files
-installed by the port.
diff --git a/1.4/channels/h323/Makefile.in b/1.4/channels/h323/Makefile.in
deleted file mode 100644
index 083250f55..000000000
--- a/1.4/channels/h323/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Makefile
-#
-# Make file for OpenH323 support layer
-#
-
-.PHONY: Makefile.ast clean
-
-default:: @OPENH323_BUILD@
-
-# Verify those options with main Makefile
-STDCCFLAGS = -DNDEBUG
-STDCCFLAGS += -I../../include -include ../../include/asterisk/autoconfig.h
-STDCCFLAGS += -fPIC
-#OPTCCFLAGS +=
-CFLAGS = -pipe
-TARGET = libchanh323.a
-TARGET += Makefile.ast
-SOURCES = ast_h323.cxx compat_h323.cxx cisco-h225.cxx caps_h323.cxx
-OBJDIR = .
-OBJS =
-
-ifndef OPENH323DIR
-OPENH323DIR=@OPENH323DIR@
-endif
-
-include $(OPENH323DIR)/openh323u.mak
-
-notrace::
- $(MAKE) NOTRACE=1 opt
-
-$(SOURCES):: Makefile ../../Makefile
- touch $@
-
-libchanh323.a: $(OBJS)
- ar crv $@ $(OBJS)
-
-cisco-h225.cxx:: cisco-h225.asn
- asnparser -m CISCO_H225 -c $<
-
-Makefile.ast:
- @echo H323CFLAGS = $(STDCCFLAGS) $(OPTCCFLAGS) $(CFLAGS) >$@.tmp
- @echo H323LDFLAGS = $(CFLAGS) $(LDFLAGS) >>$@.tmp
- @echo H323LDLIBS = $(LDLIBS) $(ENDLDLIBS) $(ENDLDFLAGS) >>$@.tmp
- @if [ -r $@ ] && cmp -s $@ $@.tmp; then rm -f $@.tmp; else mv -f $@.tmp $@; fi
-
-clean::
- rm -f $(TARGET) $(OBJS) Makefile.ast *.dep
diff --git a/1.4/channels/h323/README b/1.4/channels/h323/README
deleted file mode 100644
index 875bf3668..000000000
--- a/1.4/channels/h323/README
+++ /dev/null
@@ -1,144 +0,0 @@
- Open H.323 Channel Driver for Asterisk
- By Jeremy McNamara
- For The NuFone Network
-
- First public release on November 10th, 2002
-
- Dependancies (based on OpenH323/PWLib ones):
- openssl-0.9.6b+
- openssl-devel-0.9.6b+
- expat-1.95+
- expat-dev-1.95+
-
-Tested with Open H.323 version v1.18.0, PWLib v1.10.0 and GCC v3.2.2. Usage of any
-other (especially prior OpenH323 v1.17.3 and PWLib v1.9.2) versions is not
-supported.
-
-NOTICE: Whatever you do, DO NOT USE distrubution specific installs
-of Open H.323 and PWLib. In fact, you should check to make sure
-your distro did not install them for you without your knowledge.
-
-
-To compile this code
---------------------
-Once PWLib and Open H.323 have been compiled per their specific build
-instructions, issue a make in the asterisk/channels/h323 directory with
-argument used to build PWLib and OpenH323 (for example, make opt), then go
-back to the Asterisk source top level directory and issue a make install.
-
-
-The most common compile error
-----------------------------
-If you receive ANYTHING that says 'undefined symbol' you are experiencing
-typical version skew. For example:
-
-libh323_linux_x86_r.so.1: undefined symbol: GetNumberValueAt__C14PAbstractArrayi
-
-You need to search and destroy every version of libh323 and libpt then
-completely recompile everything
-
-Example commands to make sure everything gets cleaned and then
-rebult in proper order:
-
-cd /path/to/pwlib
-./configure
-make clean opt
-cd /path/to/openh323
-./configure
-make clean opt
-cd /path/to/asterisk/channels/h323
-make opt
-cd /path/to/asterisk
-make install
-
-
-Most common run-time error
--------------------------
-libpt_linux_x86_r.so.1: cannot open shared object file: No such
-file or directory
-
-You have not set the LD_LIBRARY_PATH environment variable.
-
-Example environment for sh/bash:
-
-PWLIBDIR=$HOME/pwlib
-export PWLIBDIR
-OPENH323DIR=$HOME/openh323
-export OPENH323DIR
-LD_LIBRARY_PATH=$PWLIBDIR/lib:$OPENH323DIR/lib
-export LD_LIBRARY_PATH
-
-We recomend puting the above directives into your /etc/profile so
-you do not have to remember to export those values every time you
-want to recompile. Make sure to logout and log back in, so your
-envrionment can pick up the new variables.
-
-
-Upgrading Asterisk
------------------
-After you cvs update (or make update) Asterisk you have to go into
-asterisk/channels/h323 and issue a make clean all, before compiling the
-rest of asterisk. Doing this process every time you upgrade Asterisk
-will ensure a sane build.
-
-
-Dialing an H.323 channel
-------------------------
-Without a gatekeeper:
-exten => _1NXXNXXXXXX,1,Dial,H323/${EXTEN}@peer
-or
-exten => _1NXXNXXXXXX,1,Dial,H323/${EXTEN}@ip.or.hostname
-
-'peer' is defined in h323.conf as:
-
-[peer]
-type=peer
-host=1.2.3.4
-disallow=all
-allow=ulaw
-
-Using a gatekeeper:
-exten => _1NXXNXXXXXX,1,Dial,H323/${EXTEN}
-
-When using a gatekeeper you cannot utilize the type=peer features,
-since the H.323 spec states that when a Gatekeeper is part of an H.323 network,
-the Gatekeeper shall be used for all communication.
-
-
-Developer Contact
-----------------
-If you have trouble contact 'JerJer' in #Asterisk on
-irc.freenode.net and/or send reasonable debug information to support@nufone.net.
-
-If are lucky enough to segfault this code please run a
-backtrace and send the gory details. Segmentation faults are not
-tolerated, no matter what Distro you run (even debian)!
-
-a simple bt example:
-
-# /usr/sbin/asterisk -vvvgc
-...
-[chan_h323.so]
-Segmentation Fault (core dumped)
-
-# ls core.*
-core.1976
-
-# gdb /usr/sbin/asterisk core.1976
-...lots of useless garbage here...
-(gdb) bt
-
-Send whatever shows up right after the 'bt'
-
-Also, a full debug screen output is almost needed. Make sure you are
-in the full console mode (-c) and turn on 'h.323 debug' or worst case
-senerio 'h.323 trace 4'. A nice way to capture debug info is with
-script (man script).
-
-If you are motivated to update/fix this code please submit a
-disclaimer along with the patch to the Asterisk bug
-tracker: http://bugs.digium.com/
-
-
-Jeremy McNamara
-The NuFone Network
diff --git a/1.4/channels/h323/TODO b/1.4/channels/h323/TODO
deleted file mode 100644
index 1e114ca3b..000000000
--- a/1.4/channels/h323/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-The NuFone Network's Open H.323 Channel Driver for Asterisk
-
- TODO:
-
- - H.323 Native Bridging
-
- - Gatekeeping support (started)
-
- - Acutally implement the options for broken H.323 stacks
diff --git a/1.4/channels/h323/ast_h323.cxx b/1.4/channels/h323/ast_h323.cxx
deleted file mode 100644
index 83c1a8464..000000000
--- a/1.4/channels/h323/ast_h323.cxx
+++ /dev/null
@@ -1,2475 +0,0 @@
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-/*
- * ast_h323.cpp
- *
- * OpenH323 Channel Driver for ASTERISK PBX.
- * By Jeremy McNamara
- * For The NuFone Network
- *
- * chan_h323 has been derived from code created by
- * Michael Manousos and Mark Spencer
- *
- * This file is part of the chan_h323 driver for Asterisk
- *
- * chan_h323 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * chan_h323 is distributed WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Version Info: $Id$
- */
-#include <arpa/inet.h>
-
-#include <list>
-#include <string>
-#include <algorithm>
-
-#include <ptlib.h>
-#include <h323.h>
-#include <h323pdu.h>
-#include <h323neg.h>
-#include <mediafmt.h>
-#include <lid.h>
-#ifdef H323_H450
-#include "h4501.h"
-#include "h4504.h"
-#include "h45011.h"
-#include "h450pdu.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/astobj.h"
-#ifdef __cplusplus
-}
-#endif
-
-#include "chan_h323.h"
-#include "ast_h323.h"
-#include "cisco-h225.h"
-#include "caps_h323.h"
-
-/* PWlib Required Components */
-#define MAJOR_VERSION 1
-#define MINOR_VERSION 0
-#define BUILD_TYPE ReleaseCode
-#define BUILD_NUMBER 0
-
-/** Counter for the number of connections */
-static int channelsOpen;
-
-/**
- * We assume that only one endPoint should exist.
- * The application cannot run the h323_end_point_create() more than once
- * FIXME: Singleton this, for safety
- */
-static MyH323EndPoint *endPoint = NULL;
-
-/** PWLib entry point */
-static MyProcess *localProcess = NULL;
-
-static int _timerChangePipe[2];
-
-static unsigned traceOptions = PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine;
-
-class PAsteriskLog : public PObject, public iostream {
- PCLASSINFO(PAsteriskLog, PObject);
-
- public:
- PAsteriskLog() : iostream(cout.rdbuf()) { init(&buffer); }
- ~PAsteriskLog() { flush(); }
-
- private:
- PAsteriskLog(const PAsteriskLog &) : iostream(cout.rdbuf()) { }
- PAsteriskLog & operator=(const PAsteriskLog &) { return *this; }
-
- class Buffer : public streambuf {
- public:
- virtual int overflow(int=EOF);
- virtual int underflow();
- virtual int sync();
- PString string;
- } buffer;
- friend class Buffer;
-};
-
-static PAsteriskLog *logstream = NULL;
-
-int PAsteriskLog::Buffer::overflow(int c)
-{
- if (pptr() >= epptr()) {
- int ppos = pptr() - pbase();
- char *newptr = string.GetPointer(string.GetSize() + 2000);
- setp(newptr, newptr + string.GetSize() - 1);
- pbump(ppos);
- }
- if (c != EOF) {
- *pptr() = (char)c;
- pbump(1);
- }
- return 0;
-}
-
-int PAsteriskLog::Buffer::underflow()
-{
- return EOF;
-}
-
-int PAsteriskLog::Buffer::sync()
-{
- char *str = strdup(string);
- char *s, *s1;
- char c;
-
- /* Pass each line with different ast_verbose() call */
- for (s = str; s && *s; s = s1) {
- s1 = strchr(s, '\n');
- if (!s1)
- s1 = s + strlen(s);
- else
- s1++;
- c = *s1;
- *s1 = '\0';
- ast_verbose("%s", s);
- *s1 = c;
- }
- free(str);
-
- string = PString();
- char *base = string.GetPointer(2000);
- setp(base, base + string.GetSize() - 1);
- return 0;
-}
-
-static ostream &my_endl(ostream &os)
-{
- if (logstream) {
- PTrace::SetOptions(traceOptions);
- return PTrace::End(os);
- }
- return endl(os);
-}
-
-#define cout \
- (logstream ? (PTrace::ClearOptions((unsigned)-1), PTrace::Begin(0, __FILE__, __LINE__)) : std::cout)
-#define endl my_endl
-
-/* Special class designed to call cleanup code on module destruction */
-class MyH323_Shutdown {
- public:
- MyH323_Shutdown() { };
- ~MyH323_Shutdown()
- {
- h323_end_process();
- };
-};
-
-MyProcess::MyProcess(): PProcess("The NuFone Networks",
- "H.323 Channel Driver for Asterisk",
- MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
-{
- /* Call shutdown when module being unload or asterisk has been stopped */
- static MyH323_Shutdown x;
-
- /* Fix missed one in PWLib */
- PX_firstTimeStart = FALSE;
- Resume();
-}
-
-MyProcess::~MyProcess()
-{
- _timerChangePipe[0] = timerChangePipe[0];
- _timerChangePipe[1] = timerChangePipe[1];
-}
-
-void MyProcess::Main()
-{
- PTrace::Initialise(PTrace::GetLevel(), NULL, traceOptions);
- PTrace::SetStream(logstream);
-
- cout << " == Creating H.323 Endpoint" << endl;
- if (endPoint) {
- cout << " == ENDPOINT ALREADY CREATED" << endl;
- return;
- }
- endPoint = new MyH323EndPoint();
- /* Due to a bug in the H.323 recomendation/stack we should request a sane
- amount of bandwidth from the GK - this function is ignored if not using a GK
- We are requesting 128 (64k in each direction), which is the worst case codec. */
- endPoint->SetInitialBandwidth(1280);
-}
-
-void PAssertFunc(const char *msg)
-{
- ast_log(LOG_ERROR, "%s\n", msg);
- /* XXX: Probably we need to crash here */
-}
-
-
-/** MyH323EndPoint
- */
-MyH323EndPoint::MyH323EndPoint()
- : H323EndPoint()
-{
- /* Capabilities will be negotiated on per-connection basis */
- capabilities.RemoveAll();
-
- /* Reset call setup timeout to some more reasonable value than 1 minute */
- signallingChannelCallTimeout = PTimeInterval(0, 0, 10); /* 10 minutes */
-}
-
-/** The fullAddress parameter is used directly in the MakeCall method so
- * the General form for the fullAddress argument is :
- * [alias@][transport$]host[:port]
- * default values: alias = the same value as host.
- * transport = ip.
- * port = 1720.
- */
-int MyH323EndPoint::MyMakeCall(const PString & dest, PString & token, void *_callReference, void *_opts)
-{
- PString fullAddress;
- MyH323Connection * connection;
- H323Transport *transport = NULL;
- unsigned int *callReference = (unsigned int *)_callReference;
- call_options_t *opts = (call_options_t *)_opts;
-
- /* Determine whether we are using a gatekeeper or not. */
- if (GetGatekeeper()) {
- fullAddress = dest;
- if (h323debug) {
- cout << " -- Making call to " << fullAddress << " using gatekeeper." << endl;
- }
- } else {
- fullAddress = dest;
- if (h323debug) {
- cout << " -- Making call to " << fullAddress << " without gatekeeper." << endl;
- }
- /* Use bindaddr for outgoing calls too if we don't use gatekeeper */
- if (listeners.GetSize() > 0) {
- H323TransportAddress taddr = listeners[0].GetTransportAddress();
- PIPSocket::Address addr;
- WORD port;
- if (taddr.GetIpAndPort(addr, port)) {
- /* Create own transport for specific addresses only */
- if (addr) {
- if (h323debug)
- cout << "Using " << addr << " for outbound call" << endl;
- transport = new MyH323TransportTCP(*this, addr);
- if (!transport)
- cout << "Unable to create transport for outgoing call" << endl;
- }
- } else
- cout << "Unable to get address and port" << endl;
- }
- }
- if (!(connection = (MyH323Connection *)H323EndPoint::MakeCallLocked(fullAddress, token, opts, transport))) {
- if (h323debug) {
- cout << "Error making call to \"" << fullAddress << '"' << endl;
- }
- return 1;
- }
- *callReference = connection->GetCallReference();
-
- if (h323debug) {
- cout << "\t-- " << GetLocalUserName() << " is calling host " << fullAddress << endl;
- cout << "\t-- Call token is " << (const char *)token << endl;
- cout << "\t-- Call reference is " << *callReference << endl;
-#ifdef PTRACING
- cout << "\t-- DTMF Payload is " << connection->dtmfCodec << endl;
-#endif
- }
- connection->Unlock();
- return 0;
-}
-
-void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const
-{
- H323EndPoint::SetEndpointTypeInfo(info);
-
- if (terminalType == e_GatewayOnly){
- info.RemoveOptionalField(H225_EndpointType::e_terminal);
- info.IncludeOptionalField(H225_EndpointType::e_gateway);
- }
-
- info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);
- info.m_gateway.m_protocol.SetSize(1);
- H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0];
- protocol.SetTag(H225_SupportedProtocols::e_voice);
- PINDEX as=SupportedPrefixes.GetSize();
- ((H225_VoiceCaps &)protocol).m_supportedPrefixes.SetSize(as);
- for (PINDEX p=0; p<as; p++) {
- H323SetAliasAddress(SupportedPrefixes[p], ((H225_VoiceCaps &)protocol).m_supportedPrefixes[p].m_prefix, H225_AliasAddress::e_dialedDigits);
- }
-}
-
-void MyH323EndPoint::SetGateway(void)
-{
- terminalType = e_GatewayOnly;
-}
-
-BOOL MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason)
-{
- if (h323debug) {
-#ifdef PTRACING
- cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause " << reason << endl;
-#else
- cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause [" << (int)reason << "]" << endl;
-#endif
- }
- return H323EndPoint::ClearCall(token, reason);
-}
-
-BOOL MyH323EndPoint::ClearCall(const PString & token)
-{
- if (h323debug) {
- cout << "\t-- ClearCall: Request to clear call with token " << token << endl;
- }
- return H323EndPoint::ClearCall(token, H323Connection::EndedByLocalUser);
-}
-
-void MyH323EndPoint::SendUserTone(const PString &token, char tone)
-{
- H323Connection *connection = NULL;
-
- connection = FindConnectionWithLock(token);
- if (connection != NULL) {
- connection->SendUserInputTone(tone, 500);
- connection->Unlock();
- }
-}
-
-void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H323Channel & channel)
-{
- channelsOpen--;
- if (h323debug) {
- cout << "\t\tchannelsOpen = " << channelsOpen << endl;
- }
- H323EndPoint::OnClosedLogicalChannel(connection, channel);
-}
-
-BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,
- const PString & forwardParty,
- const H323SignalPDU & pdu)
-{
- if (h323debug) {
- cout << "\t-- Call Forwarded to " << forwardParty << endl;
- }
- return FALSE;
-}
-
-BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,
- const PString & forwardParty,
- const H323SignalPDU & pdu)
-{
- if (h323debug) {
- cout << "\t-- Forwarding call to " << forwardParty << endl;
- }
- return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
-}
-
-void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
-{
- if (h323debug) {
- cout << "\t=-= In OnConnectionEstablished for call " << connection.GetCallReference() << endl;
- cout << "\t\t-- Connection Established with \"" << connection.GetRemotePartyName() << "\"" << endl;
- }
- on_connection_established(connection.GetCallReference(), (const char *)connection.GetCallToken());
-}
-
-/** OnConnectionCleared callback function is called upon the dropping of an established
- * H323 connection.
- */
-void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken)
-{
- PString remoteName = connection.GetRemotePartyName();
-
- switch (connection.GetCallEndReason()) {
- case H323Connection::EndedByCallForwarded:
- if (h323debug) {
- cout << "-- " << remoteName << " has forwarded the call" << endl;
- }
- break;
- case H323Connection::EndedByRemoteUser:
- if (h323debug) {
- cout << "-- " << remoteName << " has cleared the call" << endl;
- }
- break;
- case H323Connection::EndedByCallerAbort:
- if (h323debug) {
- cout << "-- " << remoteName << " has stopped calling" << endl;
- }
- break;
- case H323Connection::EndedByRefusal:
- if (h323debug) {
- cout << "-- " << remoteName << " did not accept your call" << endl;
- }
- break;
- case H323Connection::EndedByRemoteBusy:
- if (h323debug) {
- cout << "-- " << remoteName << " was busy" << endl;
- }
- break;
- case H323Connection::EndedByRemoteCongestion:
- if (h323debug) {
- cout << "-- Congested link to " << remoteName << endl;
- }
- break;
- case H323Connection::EndedByNoAnswer:
- if (h323debug) {
- cout << "-- " << remoteName << " did not answer your call" << endl;
- }
- break;
- case H323Connection::EndedByTransportFail:
- if (h323debug) {
- cout << "-- Call with " << remoteName << " ended abnormally" << endl;
- }
- break;
- case H323Connection::EndedByCapabilityExchange:
- if (h323debug) {
- cout << "-- Could not find common codec with " << remoteName << endl;
- }
- break;
- case H323Connection::EndedByNoAccept:
- if (h323debug) {
- cout << "-- Did not accept incoming call from " << remoteName << endl;
- }
- break;
- case H323Connection::EndedByAnswerDenied:
- if (h323debug) {
- cout << "-- Refused incoming call from " << remoteName << endl;
- }
- break;
- case H323Connection::EndedByNoUser:
- if (h323debug) {
- cout << "-- Remote endpoint could not find user: " << remoteName << endl;
- }
- break;
- case H323Connection::EndedByNoBandwidth:
- if (h323debug) {
- cout << "-- Call to " << remoteName << " aborted, insufficient bandwidth." << endl;
- }
- break;
- case H323Connection::EndedByUnreachable:
- if (h323debug) {
- cout << "-- " << remoteName << " could not be reached." << endl;
- }
- break;
- case H323Connection::EndedByHostOffline:
- if (h323debug) {
- cout << "-- " << remoteName << " is not online." << endl;
- }
- break;
- case H323Connection::EndedByNoEndPoint:
- if (h323debug) {
- cout << "-- No phone running for " << remoteName << endl;
- }
- break;
- case H323Connection::EndedByConnectFail:
- if (h323debug) {
- cout << "-- Transport error calling " << remoteName << endl;
- }
- break;
- default:
- if (h323debug) {
-#ifdef PTRACING
- cout << " -- Call with " << remoteName << " completed (" << connection.GetCallEndReason() << ")" << endl;
-#else
- cout << " -- Call with " << remoteName << " completed ([" << (int)connection.GetCallEndReason() << "])" << endl;
-#endif
- }
- }
-
- if (connection.IsEstablished()) {
- if (h323debug) {
- cout << "\t-- Call duration " << setprecision(0) << setw(5) << (PTime() - connection.GetConnectionStartTime()) << endl;
- }
- }
- /* Invoke the PBX application registered callback */
- on_connection_cleared(connection.GetCallReference(), clearedCallToken);
- return;
-}
-
-H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *userData, H323Transport *transport, H323SignalPDU *setupPDU)
-{
- unsigned options = 0;
- call_options_t *opts = (call_options_t *)userData;
- MyH323Connection *conn;
-
- if (opts && opts->fastStart) {
- options |= H323Connection::FastStartOptionEnable;
- } else {
- options |= H323Connection::FastStartOptionDisable;
- }
- if (opts && opts->h245Tunneling) {
- options |= H323Connection::H245TunnelingOptionEnable;
- } else {
- options |= H323Connection::H245TunnelingOptionDisable;
- }
-/* Disable until I can figure out the proper way to deal with this */
-#if 0
- if (opts->silenceSuppression) {
- options |= H323Connection::SilenceSuppresionOptionEnable;
- } else {
- options |= H323Connection::SilenceSUppressionOptionDisable;
- }
-#endif
- conn = new MyH323Connection(*this, callReference, options);
- if (conn) {
- if (opts)
- conn->SetCallOptions(opts, (setupPDU ? TRUE : FALSE));
- }
- return conn;
-}
-
-/* MyH323Connection Implementation */
-MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
- unsigned options)
- : H323Connection(ep, callReference, options)
-{
- cause = -1;
- sessionId = 0;
- bridging = FALSE;
- progressSetup = progressAlert = 0;
- dtmfMode = 0;
- dtmfCodec = (RTP_DataFrame::PayloadTypes)0;
- redirect_reason = -1;
- transfer_capability = -1;
-#ifdef TUNNELLING
- tunnelOptions = remoteTunnelOptions = 0;
-#endif
- if (h323debug) {
- cout << " == New H.323 Connection created." << endl;
- }
- return;
-}
-
-MyH323Connection::~MyH323Connection()
-{
- if (h323debug) {
- cout << " == H.323 Connection deleted." << endl;
- }
- return;
-}
-
-BOOL MyH323Connection::OnReceivedProgress(const H323SignalPDU &pdu)
-{
- BOOL isInband;
- unsigned pi;
-
- if (!H323Connection::OnReceivedProgress(pdu)) {
- return FALSE;
- }
-
- if (!pdu.GetQ931().GetProgressIndicator(pi))
- pi = 0;
- if (h323debug) {
- cout << "\t- Progress Indicator: " << pi << endl;
- }
-
- switch(pi) {
- case Q931::ProgressNotEndToEndISDN:
- case Q931::ProgressInbandInformationAvailable:
- isInband = TRUE;
- break;
- default:
- isInband = FALSE;
- }
- on_progress(GetCallReference(), (const char *)GetCallToken(), isInband);
-
- return connectionState != ShuttingDownConnection;
-}
-
-BOOL MyH323Connection::MySendProgress()
-{
- /* The code taken from H323Connection::AnsweringCall() but ALWAYS send
- PROGRESS message, including slow start operations */
- H323SignalPDU progressPDU;
- H225_Progress_UUIE &prog = progressPDU.BuildProgress(*this);
-
- if (!mediaWaitForConnect) {
- if (SendFastStartAcknowledge(prog.m_fastStart))
- prog.IncludeOptionalField(H225_Progress_UUIE::e_fastStart);
- else {
- if (connectionState == ShuttingDownConnection)
- return FALSE;
-
- /* Do early H.245 start */
- earlyStart = TRUE;
- if (!h245Tunneling) {
- if (!H323Connection::StartControlChannel())
- return FALSE;
- prog.IncludeOptionalField(H225_Progress_UUIE::e_h245Address);
- controlChannel->SetUpTransportPDU(prog.m_h245Address, TRUE);
- }
- }
- }
- progressPDU.GetQ931().SetProgressIndicator(Q931::ProgressInbandInformationAvailable);
-
-#ifdef TUNNELLING
- EmbedTunneledInfo(progressPDU);
-#endif
- HandleTunnelPDU(&progressPDU);
- WriteSignalPDU(progressPDU);
-
- return TRUE;
-}
-
-H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString & caller,
- const H323SignalPDU & setupPDU,
- H323SignalPDU & connectPDU)
-{
- unsigned pi;
-
- if (h323debug) {
- cout << "\t=-= In OnAnswerCall for call " << GetCallReference() << endl;
- }
-
- if (connectionState == ShuttingDownConnection)
- return H323Connection::AnswerCallDenied;
-
- if (!setupPDU.GetQ931().GetProgressIndicator(pi)) {
- pi = 0;
- }
- if (h323debug) {
- cout << "\t\t- Progress Indicator: " << pi << endl;
- }
- if (progressAlert) {
- pi = progressAlert;
- } else if (pi == Q931::ProgressOriginNotISDN) {
- pi = Q931::ProgressInbandInformationAvailable;
- }
- if (pi && alertingPDU) {
- alertingPDU->GetQ931().SetProgressIndicator(pi);
- }
- if (h323debug) {
- cout << "\t\t- Inserting PI of " << pi << " into ALERTING message" << endl;
- }
-
-#ifdef TUNNELLING
- if (alertingPDU)
- EmbedTunneledInfo(*alertingPDU);
- EmbedTunneledInfo(connectPDU);
-#endif
-
- if (!on_answer_call(GetCallReference(), (const char *)GetCallToken())) {
- return H323Connection::AnswerCallDenied;
- }
- /* The call will be answered later with "AnsweringCall()" function.
- */
- return ((pi || (fastStartState != FastStartDisabled)) ? AnswerCallDeferredWithMedia : AnswerCallDeferred);
-}
-
-BOOL MyH323Connection::OnAlerting(const H323SignalPDU & alertingPDU, const PString & username)
-{
- if (h323debug) {
- cout << "\t=-= In OnAlerting for call " << GetCallReference()
- << ": sessionId=" << sessionId << endl;
- cout << "\t-- Ringing phone for \"" << username << "\"" << endl;
- }
-
- if (on_progress) {
- BOOL isInband;
- unsigned alertingPI;
-
- if (!alertingPDU.GetQ931().GetProgressIndicator(alertingPI)) {
- alertingPI = 0;
- }
- if (h323debug) {
- cout << "\t\t- Progress Indicator: " << alertingPI << endl;
- }
-
- switch(alertingPI) {
- case Q931::ProgressNotEndToEndISDN:
- case Q931::ProgressInbandInformationAvailable:
- isInband = TRUE;
- break;
- default:
- isInband = FALSE;
- }
- on_progress(GetCallReference(), (const char *)GetCallToken(), isInband);
- }
- on_chan_ringing(GetCallReference(), (const char *)GetCallToken() );
- return connectionState != ShuttingDownConnection;
-}
-
-void MyH323Connection::SetCallOptions(void *o, BOOL isIncoming)
-{
- call_options_t *opts = (call_options_t *)o;
-
- progressSetup = opts->progress_setup;
- progressAlert = opts->progress_alert;
- dtmfCodec = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec;
- dtmfMode = opts->dtmfmode;
-
- if (isIncoming) {
- fastStartState = (opts->fastStart ? FastStartInitiate : FastStartDisabled);
- h245Tunneling = (opts->h245Tunneling ? TRUE : FALSE);
- } else {
- sourceE164 = PString(opts->cid_num);
- SetLocalPartyName(PString(opts->cid_name));
- SetDisplayName(PString(opts->cid_name));
- if (opts->redirect_reason >= 0) {
- rdnis = PString(opts->cid_rdnis);
- redirect_reason = opts->redirect_reason;
- }
- cid_presentation = opts->presentation;
- cid_ton = opts->type_of_number;
- if (opts->transfer_capability >= 0) {
- transfer_capability = opts->transfer_capability;
- }
- }
- tunnelOptions = opts->tunnelOptions;
-}
-
-void MyH323Connection::SetCallDetails(void *callDetails, const H323SignalPDU &setupPDU, BOOL isIncoming)
-{
- PString sourceE164;
- PString destE164;
- PString sourceAliases;
- PString destAliases;
- char *s, *s1;
- call_details_t *cd = (call_details_t *)callDetails;
-
- memset(cd, 0, sizeof(*cd));
- cd->call_reference = GetCallReference();
- cd->call_token = strdup((const char *)GetCallToken());
-
- sourceE164 = "";
- setupPDU.GetSourceE164(sourceE164);
- cd->call_source_e164 = strdup((const char *)sourceE164);
-
- destE164 = "";
- setupPDU.GetDestinationE164(destE164);
- cd->call_dest_e164 = strdup((const char *)destE164);
-
- /* XXX Is it possible to have this information for outgoing calls too? XXX */
- if (isIncoming) {
- PString sourceName;
- PIPSocket::Address Ip;
- WORD sourcePort;
- PString redirect_number;
- unsigned redirect_reason;
- unsigned plan, type, screening, presentation;
- Q931::InformationTransferCapability capability;
- unsigned transferRate, codingStandard, userInfoLayer1;
-
- /* Fetch presentation and type information about calling party's number */
- if (setupPDU.GetQ931().GetCallingPartyNumber(sourceName, &plan, &type, &presentation, &screening, 0, 0)) {
- /* Construct fields back */
- cd->type_of_number = (type << 4) | plan;
- cd->presentation = (presentation << 5) | screening;
- } else if (cd->call_source_e164[0]) {
- cd->type_of_number = 0; /* UNKNOWN */
- cd->presentation = 0x03; /* ALLOWED NETWORK NUMBER - Default */
- if (setupPDU.GetQ931().HasIE(Q931::UserUserIE)) {
- const H225_Setup_UUIE &setup_uuie = setupPDU.m_h323_uu_pdu.m_h323_message_body;
- if (setup_uuie.HasOptionalField(H225_Setup_UUIE::e_presentationIndicator))
- cd->presentation = (cd->presentation & 0x9f) | (((unsigned int)setup_uuie.m_presentationIndicator.GetTag()) << 5);
- if (setup_uuie.HasOptionalField(H225_Setup_UUIE::e_screeningIndicator))
- cd->presentation = (cd->presentation & 0xe0) | (((unsigned int)setup_uuie.m_screeningIndicator.GetValue()) & 0x1f);
- }
- } else {
- cd->type_of_number = 0; /* UNKNOWN */
- cd->presentation = 0x43; /* NUMBER NOT AVAILABLE */
- }
-
- sourceName = setupPDU.GetQ931().GetDisplayName();
- cd->call_source_name = strdup((const char *)sourceName);
-
- GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
- cd->sourceIp = strdup((const char *)Ip.AsString());
-
- if (setupPDU.GetQ931().GetRedirectingNumber(redirect_number, NULL, NULL, NULL, NULL, &redirect_reason, 0, 0, 0)) {
- cd->redirect_number = strdup((const char *)redirect_number);
- cd->redirect_reason = redirect_reason;
- }
- else
- cd->redirect_reason = -1;
-
- /* Fetch Q.931's transfer capability */
- if (((Q931 &)setupPDU.GetQ931()).GetBearerCapabilities(capability, transferRate, &codingStandard, &userInfoLayer1))
- cd->transfer_capability = ((unsigned int)capability & 0x1f) | (codingStandard << 5);
- else
- cd->transfer_capability = 0x00; /* ITU coding of Speech */
-
- /* Don't show local username as called party name */
- SetDisplayName(cd->call_dest_e164);
- }
-
- /* Convert complex strings */
- // FIXME: deal more than one source alias
- sourceAliases = setupPDU.GetSourceAliases();
- s1 = strdup((const char *)sourceAliases);
- if ((s = strchr(s1, ' ')) != NULL)
- *s = '\0';
- if ((s = strchr(s1, '\t')) != NULL)
- *s = '\0';
- cd->call_source_aliases = s1;
-
- destAliases = setupPDU.GetDestinationAlias();
- s1 = strdup((const char *)destAliases);
- if ((s = strchr(s1, ' ')) != NULL)
- *s = '\0';
- if ((s = strchr(s1, '\t')) != NULL)
- *s = '\0';
- cd->call_dest_alias = s1;
-}
-
-#ifdef TUNNELLING
-static BOOL FetchInformationElements(Q931 &q931, const PBYTEArray &data)
-{
- PINDEX offset = 0;
-
- while (offset < data.GetSize()) {
- // Get field discriminator
- int discriminator = data[offset++];
-
-#if 0
- /* Do not overwrite existing IEs */
- if (q931.HasIE((Q931::InformationElementCodes)discriminator)) {
- if ((discriminatir & 0x80) == 0)
- offset += data[offset++];
- if (offset > data.GetSize())
- return FALSE;
- continue;
- }
-#endif
-
- PBYTEArray * item = new PBYTEArray;
-
- // For discriminator with high bit set there is no data
- if ((discriminator & 0x80) == 0) {
- int len = data[offset++];
-
-#if 0 // That is not H.225 but regular Q.931 (ISDN) IEs
- if (discriminator == UserUserIE) {
- // Special case of User-user field. See 7.2.2.31/H.225.0v4.
- len <<= 8;
- len |= data[offset++];
-
- // we also have a protocol discriminator, which we ignore
- offset++;
-
- // before decrementing the length, make sure it is not zero
- if (len == 0)
- return FALSE;
-
- // adjust for protocol discriminator
- len--;
- }
-#endif
-
- if (offset + len > data.GetSize()) {
- delete item;
- return FALSE;
- }
-
- memcpy(item->GetPointer(len), (const BYTE *)data+offset, len);
- offset += len;
- }
-
- q931.SetIE((Q931::InformationElementCodes)discriminator, *item);
- delete item;
- }
- return TRUE;
-}
-
-static BOOL FetchCiscoTunneledInfo(Q931 &q931, const H323SignalPDU &pdu)
-{
- BOOL res = FALSE;
- const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
-
- if(uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) {
- for(int i = 0; i < uuPDU.m_nonStandardControl.GetSize(); ++i) {
- const H225_NonStandardParameter &np = uuPDU.m_nonStandardControl[i];
- const H225_NonStandardIdentifier &id = np.m_nonStandardIdentifier;
- if (id.GetTag() == H225_NonStandardIdentifier::e_h221NonStandard) {
- const H225_H221NonStandard &ni = id;
- /* Check for Cisco */
- if ((ni.m_t35CountryCode == 181) && (ni.m_t35Extension == 0) && (ni.m_manufacturerCode == 18)) {
- const PBYTEArray &data = np.m_data;
- if (h323debug)
- cout << setprecision(0) << "Received non-standard Cisco extension data " << np.m_data << endl;
- CISCO_H225_H323_UU_NonStdInfo c;
- PPER_Stream strm(data);
- if (c.Decode(strm)) {
- BOOL haveIEs = FALSE;
- if (h323debug)
- cout << setprecision(0) << "H323_UU_NonStdInfo = " << c << endl;
- if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam)) {
- FetchInformationElements(q931, c.m_protoParam.m_qsigNonStdInfo.m_rawMesg);
- haveIEs = TRUE;
- }
- if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam)) {
- FetchInformationElements(q931, c.m_commonParam.m_redirectIEinfo.m_redirectIE);
- haveIEs = TRUE;
- }
- if (haveIEs && h323debug)
- cout << setprecision(0) << "Information elements collected:" << q931 << endl;
- res = TRUE;
- } else {
- cout << "ERROR while decoding non-standard Cisco extension" << endl;
- return FALSE;
- }
- }
- }
- }
- }
- return res;
-}
-
-static BOOL EmbedCiscoTunneledInfo(H323SignalPDU &pdu)
-{
- const static struct {
- Q931::InformationElementCodes ie;
- BOOL dontDelete;
- } codes[] = {
- { Q931::RedirectingNumberIE, },
- { Q931::FacilityIE, },
-// { Q931::CallingPartyNumberIE, TRUE },
- };
-
- BOOL res = FALSE;
- BOOL notRedirOnly = FALSE;
- Q931 tmpQ931;
- Q931 &q931 = pdu.GetQ931();
-
- for(unsigned i = 0; i < (sizeof(codes) / sizeof(codes[0])); ++i) {
- if (q931.HasIE(codes[i].ie)) {
- tmpQ931.SetIE(codes[i].ie, q931.GetIE(codes[i].ie));
- if (!codes[i].dontDelete)
- q931.RemoveIE(codes[i].ie);
- if (codes[i].ie != Q931::RedirectingNumberIE)
- notRedirOnly = TRUE;
- res = TRUE;
- }
- }
- /* Have something to embed */
- if (res) {
- PBYTEArray msg;
- if (!tmpQ931.Encode(msg))
- return FALSE;
- PBYTEArray ies(msg.GetPointer() + 5, msg.GetSize() - 5);
-
- H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
- if(!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) {
- uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_nonStandardControl);
- uuPDU.m_nonStandardControl.SetSize(0);
- }
- H225_NonStandardParameter *np = new H225_NonStandardParameter;
- uuPDU.m_nonStandardControl.Append(np);
- H225_NonStandardIdentifier &nsi = (*np).m_nonStandardIdentifier;
- nsi.SetTag(H225_NonStandardIdentifier::e_h221NonStandard);
- H225_H221NonStandard &ns = nsi;
- ns.m_t35CountryCode = 181;
- ns.m_t35Extension = 0;
- ns.m_manufacturerCode = 18;
-
- CISCO_H225_H323_UU_NonStdInfo c;
- c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_version);
- c.m_version = 0;
-
- if (notRedirOnly) {
- c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam);
- CISCO_H225_QsigNonStdInfo &qsigInfo = c.m_protoParam.m_qsigNonStdInfo;
- qsigInfo.m_iei = ies[0];
- qsigInfo.m_rawMesg = ies;
- } else {
- c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam);
- c.m_commonParam.m_redirectIEinfo.m_redirectIE = ies;
- }
- PPER_Stream stream;
- c.Encode(stream);
- stream.CompleteEncoding();
- (*np).m_data = stream;
- }
- return res;
-}
-
-static const char OID_QSIG[] = "1.3.12.9";
-
-static BOOL FetchQSIGTunneledInfo(Q931 &q931, const H323SignalPDU &pdu)
-{
- BOOL res = FALSE;
- const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
- if (uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage)) {
- const H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage;
- const H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id;
- if ((proto.GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) &&
- (((const PASN_ObjectId &)proto).AsString() == OID_QSIG)) {
- const H225_ArrayOf_PASN_OctetString &sigs = sig.m_messageContent;
- for(int i = 0; i < sigs.GetSize(); ++i) {
- const PASN_OctetString &msg = sigs[i];
- if (h323debug)
- cout << setprecision(0) << "Q.931 message data is " << msg << endl;
- if(!q931.Decode((const PBYTEArray &)msg)) {
- cout << "Error while decoding Q.931 message" << endl;
- return FALSE;
- }
- res = TRUE;
- if (h323debug)
- cout << setprecision(0) << "Received QSIG message " << q931 << endl;
- }
- }
- }
- return res;
-}
-
-static H225_EndpointType *GetEndpointType(H323SignalPDU &pdu)
-{
- if (!pdu.GetQ931().HasIE(Q931::UserUserIE))
- return NULL;
-
- H225_H323_UU_PDU_h323_message_body &body = pdu.m_h323_uu_pdu.m_h323_message_body;
- switch (body.GetTag()) {
- case H225_H323_UU_PDU_h323_message_body::e_setup:
- return &((H225_Setup_UUIE &)body).m_sourceInfo;
- case H225_H323_UU_PDU_h323_message_body::e_callProceeding:
- return &((H225_CallProceeding_UUIE &)body).m_destinationInfo;
- case H225_H323_UU_PDU_h323_message_body::e_connect:
- return &((H225_Connect_UUIE &)body).m_destinationInfo;
- case H225_H323_UU_PDU_h323_message_body::e_alerting:
- return &((H225_Alerting_UUIE &)body).m_destinationInfo;
- case H225_H323_UU_PDU_h323_message_body::e_facility:
- return &((H225_Facility_UUIE &)body).m_destinationInfo;
- case H225_H323_UU_PDU_h323_message_body::e_progress:
- return &((H225_Progress_UUIE &)body).m_destinationInfo;
- }
- return NULL;
-}
-
-static BOOL QSIGTunnelRequested(H323SignalPDU &pdu)
-{
- H225_EndpointType *epType = GetEndpointType(pdu);
- if (epType) {
- if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) {
- return FALSE;
- }
- H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols;
- for (int i = 0; i < protos.GetSize(); ++i)
- {
- if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) &&
- (((const PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) {
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-static BOOL EmbedQSIGTunneledInfo(H323SignalPDU &pdu)
-{
- const static Q931::InformationElementCodes codes[] =
- { Q931::RedirectingNumberIE, Q931::FacilityIE };
-
- Q931 &q931 = pdu.GetQ931();
- PBYTEArray message;
-
- q931.Encode(message);
-
- /* Remove non-standard IEs */
- for(unsigned i = 0; i < (sizeof(codes) / sizeof(codes[0])); ++i) {
- if (q931.HasIE(codes[i])) {
- q931.RemoveIE(codes[i]);
- }
- }
-
- H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
- H225_EndpointType *epType = GetEndpointType(pdu);
- if (epType) {
- if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) {
- (*epType).IncludeOptionalField(H225_EndpointType::e_supportedTunnelledProtocols);
- (*epType).m_supportedTunnelledProtocols.SetSize(0);
- }
- H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols;
- BOOL addQSIG = TRUE;
- for (int i = 0; i < protos.GetSize(); ++i)
- {
- if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) &&
- (((PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) {
- addQSIG = FALSE;
- break;
- }
- }
- if (addQSIG) {
- H225_TunnelledProtocol *proto = new H225_TunnelledProtocol;
- (*proto).m_id.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID);
- (PASN_ObjectId &)(proto->m_id) = OID_QSIG;
- protos.Append(proto);
- }
- }
- if (!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage))
- uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage);
- H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage;
- H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id;
- if ((proto.GetTag() != H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) ||
- (((const PASN_ObjectId &)proto).AsString() != OID_QSIG)) {
- proto.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID);
- (PASN_ObjectId &)proto = OID_QSIG;
- sig.m_messageContent.SetSize(0);
- }
- PASN_OctetString *msg = new PASN_OctetString;
- sig.m_messageContent.Append(msg);
- *msg = message;
- return TRUE;
-}
-
-BOOL MyH323Connection::EmbedTunneledInfo(H323SignalPDU &pdu)
-{
- if ((tunnelOptions & H323_TUNNEL_QSIG) || (remoteTunnelOptions & H323_TUNNEL_QSIG))
- EmbedQSIGTunneledInfo(pdu);
- if ((tunnelOptions & H323_TUNNEL_CISCO) || (remoteTunnelOptions & H323_TUNNEL_CISCO))
- EmbedCiscoTunneledInfo(pdu);
-
- return TRUE;
-}
-
-/* Handle tunneled messages */
-BOOL MyH323Connection::HandleSignalPDU(H323SignalPDU &pdu)
-{
- if (pdu.GetQ931().HasIE(Q931::UserUserIE)) {
- Q931 tunneledInfo;
- const Q931 *q931Info;
-
- q931Info = NULL;
- if (FetchCiscoTunneledInfo(tunneledInfo, pdu)) {
- q931Info = &tunneledInfo;
- remoteTunnelOptions |= H323_TUNNEL_CISCO;
- }
- if (FetchQSIGTunneledInfo(tunneledInfo, pdu)) {
- q931Info = &tunneledInfo;
- remoteTunnelOptions |= H323_TUNNEL_QSIG;
- }
- if (!(remoteTunnelOptions & H323_TUNNEL_QSIG) && QSIGTunnelRequested(pdu)) {
- remoteTunnelOptions |= H323_TUNNEL_QSIG;
- }
- if (q931Info) {
- if (q931Info->HasIE(Q931::RedirectingNumberIE)) {
- pdu.GetQ931().SetIE(Q931::RedirectingNumberIE, q931Info->GetIE(Q931::RedirectingNumberIE));
- if (h323debug) {
- PString number;
- unsigned reason;
- if(q931Info->GetRedirectingNumber(number, NULL, NULL, NULL, NULL, &reason, 0, 0, 0))
- cout << "Got redirection from " << number << ", reason " << reason << endl;
- }
- }
- }
- }
-
- return H323Connection::HandleSignalPDU(pdu);
-}
-#endif
-
-BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
-{
- call_details_t cd;
-
- if (h323debug) {
- cout << "\t--Received SETUP message" << endl;
- }
-
- if (connectionState == ShuttingDownConnection)
- return FALSE;
-
- SetCallDetails(&cd, setupPDU, TRUE);
-
- /* Notify Asterisk of the request */
- call_options_t *res = on_incoming_call(&cd);
-
- if (!res) {
- if (h323debug) {
- cout << "\t-- Call Failed" << endl;
- }
- return FALSE;
- }
-
- SetCallOptions(res, TRUE);
-
- /* Disable fastStart if requested by remote side */
- if (h245Tunneling && !setupPDU.m_h323_uu_pdu.m_h245Tunneling) {
- masterSlaveDeterminationProcedure->Stop();
- capabilityExchangeProcedure->Stop();
- PTRACE(3, "H225\tFast Start DISABLED!");
- h245Tunneling = FALSE;
- }
-
- return H323Connection::OnReceivedSignalSetup(setupPDU);
-}
-
-BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
-{
- call_details_t cd;
-
- if (h323debug) {
- cout << "\t-- Sending SETUP message" << endl;
- }
-
- if (connectionState == ShuttingDownConnection)
- return FALSE;
-
- if (progressSetup)
- setupPDU.GetQ931().SetProgressIndicator(progressSetup);
-
- if (redirect_reason >= 0) {
- setupPDU.GetQ931().SetRedirectingNumber(rdnis, 0, 0, 0, 0, redirect_reason);
- /* OpenH323 incorrectly fills number IE when redirecting reason is specified - fix it */
- PBYTEArray IE(setupPDU.GetQ931().GetIE(Q931::RedirectingNumberIE));
- IE[0] = IE[0] & 0x7f;
- IE[1] = IE[1] & 0x7f;
- setupPDU.GetQ931().SetIE(Q931::RedirectingNumberIE, IE);
- }
-
- if (transfer_capability)
- setupPDU.GetQ931().SetBearerCapabilities((Q931::InformationTransferCapability)(transfer_capability & 0x1f), 1, ((transfer_capability >> 5) & 3));
-
- SetCallDetails(&cd, setupPDU, FALSE);
-
- int res = on_outgoing_call(&cd);
- if (!res) {
- if (h323debug) {
- cout << "\t-- Call Failed" << endl;
- }
- return FALSE;
- }
-
- /* OpenH323 will build calling party information with default
- type and presentation information, so build it to be recorded
- by embedding routines */
- setupPDU.GetQ931().SetCallingPartyNumber(sourceE164, (cid_ton >> 4) & 0x07,
- cid_ton & 0x0f, (cid_presentation >> 5) & 0x03, cid_presentation & 0x1f);
- setupPDU.GetQ931().SetDisplayName(GetDisplayName());
-
-#ifdef TUNNELLING
- EmbedTunneledInfo(setupPDU);
-#endif
-
- return H323Connection::OnSendSignalSetup(setupPDU);
-}
-
-static BOOL BuildFastStartList(const H323Channel & channel,
- H225_ArrayOf_PASN_OctetString & array,
- H323Channel::Directions reverseDirection)
-{
- H245_OpenLogicalChannel open;
- const H323Capability & capability = channel.GetCapability();
-
- if (channel.GetDirection() != reverseDirection) {
- if (!capability.OnSendingPDU(open.m_forwardLogicalChannelParameters.m_dataType))
- return FALSE;
- }
- else {
- if (!capability.OnSendingPDU(open.m_reverseLogicalChannelParameters.m_dataType))
- return FALSE;
-
- open.m_forwardLogicalChannelParameters.m_multiplexParameters.SetTag(
- H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters::e_none);
- open.m_forwardLogicalChannelParameters.m_dataType.SetTag(H245_DataType::e_nullData);
- open.IncludeOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters);
- }
-
- if (!channel.OnSendingPDU(open))
- return FALSE;
-
- PTRACE(4, "H225\tBuild fastStart:\n " << setprecision(2) << open);
- PINDEX last = array.GetSize();
- array.SetSize(last+1);
- array[last].EncodeSubType(open);
-
- PTRACE(3, "H225\tBuilt fastStart for " << capability);
- return TRUE;
-}
-
-H323Connection::CallEndReason MyH323Connection::SendSignalSetup(const PString & alias,
- const H323TransportAddress & address)
-{
- // Start the call, first state is asking gatekeeper
- connectionState = AwaitingGatekeeperAdmission;
-
- // Indicate the direction of call.
- if (alias.IsEmpty())
- remotePartyName = remotePartyAddress = address;
- else {
- remotePartyName = alias;
- remotePartyAddress = alias + '@' + address;
- }
-
- // Start building the setup PDU to get various ID's
- H323SignalPDU setupPDU;
- H225_Setup_UUIE & setup = setupPDU.BuildSetup(*this, address);
-
-#ifdef H323_H450
- h450dispatcher->AttachToSetup(setupPDU);
-#endif
-
- // Save the identifiers generated by BuildSetup
- setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber);
-
- H323TransportAddress gatekeeperRoute = address;
-
- // Check for gatekeeper and do admission check if have one
- H323Gatekeeper * gatekeeper = endpoint.GetGatekeeper();
- H225_ArrayOf_AliasAddress newAliasAddresses;
- if (gatekeeper != NULL) {
- H323Gatekeeper::AdmissionResponse response;
- response.transportAddress = &gatekeeperRoute;
- response.aliasAddresses = &newAliasAddresses;
- if (!gkAccessTokenOID)
- response.accessTokenData = &gkAccessTokenData;
- while (!gatekeeper->AdmissionRequest(*this, response, alias.IsEmpty())) {
- PTRACE(1, "H225\tGatekeeper refused admission: "
- << (response.rejectReason == UINT_MAX
- ? PString("Transport error")
- : H225_AdmissionRejectReason(response.rejectReason).GetTagName()));
-#ifdef H323_H450
- h4502handler->onReceivedAdmissionReject(H4501_GeneralErrorList::e_notAvailable);
-#endif
-
- switch (response.rejectReason) {
- case H225_AdmissionRejectReason::e_calledPartyNotRegistered:
- return EndedByNoUser;
- case H225_AdmissionRejectReason::e_requestDenied:
- return EndedByNoBandwidth;
- case H225_AdmissionRejectReason::e_invalidPermission:
- case H225_AdmissionRejectReason::e_securityDenial:
- return EndedBySecurityDenial;
- case H225_AdmissionRejectReason::e_resourceUnavailable:
- return EndedByRemoteBusy;
- case H225_AdmissionRejectReason::e_incompleteAddress:
- if (OnInsufficientDigits())
- break;
- // Then default case
- default:
- return EndedByGatekeeper;
- }
-
- PString lastRemotePartyName = remotePartyName;
- while (lastRemotePartyName == remotePartyName) {
- Unlock(); // Release the mutex as can deadlock trying to clear call during connect.
- digitsWaitFlag.Wait();
- if (!Lock()) // Lock while checking for shutting down.
- return EndedByCallerAbort;
- }
- }
- mustSendDRQ = TRUE;
- if (response.gatekeeperRouted) {
- setup.IncludeOptionalField(H225_Setup_UUIE::e_endpointIdentifier);
- setup.m_endpointIdentifier = gatekeeper->GetEndpointIdentifier();
- gatekeeperRouted = TRUE;
- }
- }
-
-#ifdef H323_TRANSNEXUS_OSP
- // check for OSP server (if not using GK)
- if (gatekeeper == NULL) {
- OpalOSP::Provider * ospProvider = endpoint.GetOSPProvider();
- if (ospProvider != NULL) {
- OpalOSP::Transaction * transaction = new OpalOSP::Transaction();
- if (transaction->Open(*ospProvider) != 0) {
- PTRACE(1, "H225\tCannot create OSP transaction");
- return EndedByOSPRefusal;
- }
-
- OpalOSP::Transaction::DestinationInfo destInfo;
- if (!AuthoriseOSPTransaction(*transaction, destInfo)) {
- delete transaction;
- return EndedByOSPRefusal;
- }
-
- // save the transaction for use by the call
- ospTransaction = transaction;
-
- // retreive the call information
- gatekeeperRoute = destInfo.destinationAddress;
- newAliasAddresses.Append(new H225_AliasAddress(destInfo.calledNumber));
-
- // insert the token
- setup.IncludeOptionalField(H225_Setup_UUIE::e_tokens);
- destInfo.InsertToken(setup.m_tokens);
- }
- }
-#endif
-
- // Update the field e_destinationAddress in the SETUP PDU to reflect the new
- // alias received in the ACF (m_destinationInfo).
- if (newAliasAddresses.GetSize() > 0) {
- setup.IncludeOptionalField(H225_Setup_UUIE::e_destinationAddress);
- setup.m_destinationAddress = newAliasAddresses;
-
- // Update the Q.931 Information Element (if is an E.164 address)
- PString e164 = H323GetAliasAddressE164(newAliasAddresses);
- if (!e164)
- remotePartyNumber = e164;
- }
-
- if (addAccessTokenToSetup && !gkAccessTokenOID && !gkAccessTokenData.IsEmpty()) {
- PString oid1, oid2;
- PINDEX comma = gkAccessTokenOID.Find(',');
- if (comma == P_MAX_INDEX)
- oid1 = oid2 = gkAccessTokenOID;
- else {
- oid1 = gkAccessTokenOID.Left(comma);
- oid2 = gkAccessTokenOID.Mid(comma+1);
- }
- setup.IncludeOptionalField(H225_Setup_UUIE::e_tokens);
- PINDEX last = setup.m_tokens.GetSize();
- setup.m_tokens.SetSize(last+1);
- setup.m_tokens[last].m_tokenOID = oid1;
- setup.m_tokens[last].IncludeOptionalField(H235_ClearToken::e_nonStandard);
- setup.m_tokens[last].m_nonStandard.m_nonStandardIdentifier = oid2;
- setup.m_tokens[last].m_nonStandard.m_data = gkAccessTokenData;
- }
-
- if (!signallingChannel->SetRemoteAddress(gatekeeperRoute)) {
- PTRACE(1, "H225\tInvalid "
- << (gatekeeperRoute != address ? "gatekeeper" : "user")
- << " supplied address: \"" << gatekeeperRoute << '"');
- connectionState = AwaitingTransportConnect;
- return EndedByConnectFail;
- }
-
- // Do the transport connect
- connectionState = AwaitingTransportConnect;
-
- // Release the mutex as can deadlock trying to clear call during connect.
- Unlock();
-
- signallingChannel->SetWriteTimeout(100);
-
- BOOL connectFailed = !signallingChannel->Connect();
-
- // Lock while checking for shutting down.
- if (!Lock())
- return EndedByCallerAbort;
-
- // See if transport connect failed, abort if so.
- if (connectFailed) {
- connectionState = NoConnectionActive;
- switch (signallingChannel->GetErrorNumber()) {
- case ENETUNREACH :
- return EndedByUnreachable;
- case ECONNREFUSED :
- return EndedByNoEndPoint;
- case ETIMEDOUT :
- return EndedByHostOffline;
- }
- return EndedByConnectFail;
- }
-
- PTRACE(3, "H225\tSending Setup PDU");
- connectionState = AwaitingSignalConnect;
-
- // Put in all the signalling addresses for link
- setup.IncludeOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress);
- signallingChannel->SetUpTransportPDU(setup.m_sourceCallSignalAddress, TRUE);
- if (!setup.HasOptionalField(H225_Setup_UUIE::e_destCallSignalAddress)) {
- setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress);
- signallingChannel->SetUpTransportPDU(setup.m_destCallSignalAddress, FALSE);
- }
-
- // If a standard call do Fast Start (if required)
- if (setup.m_conferenceGoal.GetTag() == H225_Setup_UUIE_conferenceGoal::e_create) {
-
- // Get the local capabilities before fast start is handled
- OnSetLocalCapabilities();
-
- // Ask the application what channels to open
- PTRACE(3, "H225\tCheck for Fast start by local endpoint");
- fastStartChannels.RemoveAll();
- OnSelectLogicalChannels();
-
- // If application called OpenLogicalChannel, put in the fastStart field
- if (!fastStartChannels.IsEmpty()) {
- PTRACE(3, "H225\tFast start begun by local endpoint");
- for (PINDEX i = 0; i < fastStartChannels.GetSize(); i++)
- BuildFastStartList(fastStartChannels[i], setup.m_fastStart, H323Channel::IsReceiver);
- if (setup.m_fastStart.GetSize() > 0)
- setup.IncludeOptionalField(H225_Setup_UUIE::e_fastStart);
- }
-
- // Search the capability set and see if we have video capability
- for (PINDEX i = 0; i < localCapabilities.GetSize(); i++) {
- switch (localCapabilities[i].GetMainType()) {
- case H323Capability::e_Audio:
- case H323Capability::e_UserInput:
- break;
-
- default: // Is video or other data (eg T.120)
- setupPDU.GetQ931().SetBearerCapabilities(Q931::TransferUnrestrictedDigital, 6);
- i = localCapabilities.GetSize(); // Break out of the for loop
- break;
- }
- }
- }
-
- if (!OnSendSignalSetup(setupPDU))
- return EndedByNoAccept;
-
- // Do this again (was done when PDU was constructed) in case
- // OnSendSignalSetup() changed something.
-// setupPDU.SetQ931Fields(*this, TRUE);
- setupPDU.GetQ931().GetCalledPartyNumber(remotePartyNumber);
-
- fastStartState = FastStartDisabled;
- BOOL set_lastPDUWasH245inSETUP = FALSE;
-
- if (h245Tunneling && doH245inSETUP) {
- h245TunnelTxPDU = &setupPDU;
-
- // Try and start the master/slave and capability exchange through the tunnel
- // Note: this used to be disallowed but is now allowed as of H323v4
- BOOL ok = StartControlNegotiations();
-
- h245TunnelTxPDU = NULL;
-
- if (!ok)
- return EndedByTransportFail;
-
- if (setup.m_fastStart.GetSize() > 0) {
- // Now if fast start as well need to put this in setup specific field
- // and not the generic H.245 tunneling field
- setup.IncludeOptionalField(H225_Setup_UUIE::e_parallelH245Control);
- setup.m_parallelH245Control = setupPDU.m_h323_uu_pdu.m_h245Control;
- setupPDU.m_h323_uu_pdu.RemoveOptionalField(H225_H323_UU_PDU::e_h245Control);
- set_lastPDUWasH245inSETUP = TRUE;
- }
- }
-
- // Send the initial PDU
- setupTime = PTime();
- if (!WriteSignalPDU(setupPDU))
- return EndedByTransportFail;
-
- // WriteSignalPDU always resets lastPDUWasH245inSETUP.
- // So set it here if required
- if (set_lastPDUWasH245inSETUP)
- lastPDUWasH245inSETUP = TRUE;
-
- // Set timeout for remote party to answer the call
- signallingChannel->SetReadTimeout(endpoint.GetSignallingChannelCallTimeout());
-
- return NumCallEndReasons;
-}
-
-
-BOOL MyH323Connection::OnSendReleaseComplete(H323SignalPDU & releaseCompletePDU)
-{
- if (h323debug) {
- cout << "\t-- Sending RELEASE COMPLETE" << endl;
- }
- if (cause > 0)
- releaseCompletePDU.GetQ931().SetCause((Q931::CauseValues)cause);
-
-#ifdef TUNNELLING
- EmbedTunneledInfo(releaseCompletePDU);
-#endif
-
- return H323Connection::OnSendReleaseComplete(releaseCompletePDU);
-}
-
-BOOL MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu)
-{
- if (h323debug) {
- cout << "\t-- Received Facility message... " << endl;
- }
- return H323Connection::OnReceivedFacility(pdu);
-}
-
-void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu)
-{
- if (h323debug) {
- cout << "\t-- Received RELEASE COMPLETE message..." << endl;
- }
- if (on_hangup)
- on_hangup(GetCallReference(), (const char *)GetCallToken(), pdu.GetQ931().GetCause());
- return H323Connection::OnReceivedReleaseComplete(pdu);
-}
-
-BOOL MyH323Connection::OnClosingLogicalChannel(H323Channel & channel)
-{
- if (h323debug) {
- cout << "\t-- Closing logical channel..." << endl;
- }
- return H323Connection::OnClosingLogicalChannel(channel);
-}
-
-void MyH323Connection::SendUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
-{
- SendUserInputModes mode = GetRealSendUserInputMode();
-// That is recursive call... Why?
-// on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken());
- if ((tone != ' ') || (mode == SendUserInputAsTone) || (mode == SendUserInputAsInlineRFC2833)) {
- if (h323debug) {
- cout << "\t-- Sending user input tone (" << tone << ") to remote" << endl;
- }
- H323Connection::SendUserInputTone(tone, duration);
- }
-}
-
-void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
-{
- if (dtmfMode == H323_DTMF_RFC2833) {
- if (h323debug) {
- cout << "\t-- Received user input tone (" << tone << ") from remote" << endl;
- }
- on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken(), duration);
- }
-}
-
-void MyH323Connection::OnUserInputString(const PString &value)
-{
- if (h323debug) {
- cout << "\t-- Received user input string (" << value << ") from remote." << endl;
- }
- on_receive_digit(GetCallReference(), value[0], (const char *)GetCallToken(), 0);
-}
-
-void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu)
-{
- PINDEX i;
-
- H323Connection::OnSendCapabilitySet(pdu);
-
- H245_ArrayOf_CapabilityTableEntry & tables = pdu.m_capabilityTable;
- for(i = 0; i < tables.GetSize(); i++)
- {
- H245_CapabilityTableEntry & entry = tables[i];
- if (entry.HasOptionalField(H245_CapabilityTableEntry::e_capability)) {
- H245_Capability & cap = entry.m_capability;
- if (cap.GetTag() == H245_Capability::e_receiveRTPAudioTelephonyEventCapability) {
- H245_AudioTelephonyEventCapability & atec = cap;
- atec.m_dynamicRTPPayloadType = dtmfCodec;
-// on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec);
-#ifdef PTRACING
- if (h323debug) {
- cout << "\t-- Transmitting RFC2833 on payload " <<
- atec.m_dynamicRTPPayloadType << endl;
- }
-#endif
- }
- }
- }
-}
-
-void MyH323Connection::OnSetLocalCapabilities()
-{
- if (on_setcapabilities)
- on_setcapabilities(GetCallReference(), (const char *)callToken);
-}
-
-BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,
- const H245_MultiplexCapability * muxCap,
- H245_TerminalCapabilitySetReject & reject)
-{
- struct __codec__ {
- unsigned int asterisk_codec;
- unsigned int h245_cap;
- const char *oid;
- };
- static const struct __codec__ codecs[] = {
- { AST_FORMAT_G723_1, H245_AudioCapability::e_g7231 },
- { AST_FORMAT_GSM, H245_AudioCapability::e_gsmFullRate },
- { AST_FORMAT_ULAW, H245_AudioCapability::e_g711Ulaw64k },
- { AST_FORMAT_ALAW, H245_AudioCapability::e_g711Alaw64k },
- { AST_FORMAT_G729A, H245_AudioCapability::e_g729AnnexA },
- { AST_FORMAT_G729A, H245_AudioCapability::e_g729 },
-#ifdef AST_FORMAT_MODEM
- { AST_FORMAT_MODEM, H245_DataApplicationCapability_application::e_t38fax },
-#endif
- { 0 }
- };
-
-#if 0
- static const struct __codec__ vcodecs[] = {
-#ifdef HAVE_H261
- { AST_FORMAT_H261, H245_VideoCapability::e_h261VideoCapability },
-#endif
-#ifdef HAVE_H263
- { AST_FORMAT_H263, H245_VideoCapability::e_h263VideoCapability },
-#endif
-#ifdef HAVE_H264
- { AST_FORMAT_H264, H245_VideoCapability::e_genericVideoCapability, "0.0.8.241.0.0.1" },
-#endif
- { 0 }
- };
-#endif
- struct ast_codec_pref prefs;
-
- if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) {
- return FALSE;
- }
-
- const H323Capability * cap = remoteCaps.FindCapability(H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833]);
- if (cap != NULL) {
- RTP_DataFrame::PayloadTypes pt = ((H323_UserInputCapability*)cap)->GetPayloadType();
- on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt);
- if ((dtmfMode == H323_DTMF_RFC2833) && (sendUserInputMode == SendUserInputAsTone))
- sendUserInputMode = SendUserInputAsInlineRFC2833;
-#ifdef PTRACING
- if (h323debug) {
- cout << "\t-- Inbound RFC2833 on payload " << pt << endl;
- }
-#endif
- }
- memset(&prefs, 0, sizeof(prefs));
- int peer_capabilities = 0;
- for (int i = 0; i < remoteCapabilities.GetSize(); ++i) {
- unsigned int subType = remoteCapabilities[i].GetSubType();
- if (h323debug) {
- cout << "Peer capability is " << remoteCapabilities[i] << endl;
- }
- switch(remoteCapabilities[i].GetMainType()) {
- case H323Capability::e_Audio:
- for (int x = 0; codecs[x].asterisk_codec > 0; ++x) {
- if (subType == codecs[x].h245_cap) {
- int ast_codec = codecs[x].asterisk_codec;
- int ms = 0;
- if (!(peer_capabilities & ast_codec)) {
- struct ast_format_list format;
- ast_codec_pref_append(&prefs, ast_codec);
- format = ast_codec_pref_getsize(&prefs, ast_codec);
- if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) {
- ms = remoteCapabilities[i].GetTxFramesInPacket();
- if (ms > 60)
- ms = format.cur_ms;
- } else
- ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms;
- ast_codec_pref_setsize(&prefs, ast_codec, ms);
- }
- if (h323debug) {
- cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl;
- }
- peer_capabilities |= ast_codec;
- }
- }
- break;
-#if 0
- case H323Capability::e_Video:
- for (int x = 0; vcodecs[x].asterisk_codec > 0; ++x) {
- if (subType == vcodecs[x].h245_cap) {
- H245_CapabilityIdentifier *cap = NULL;
- H245_GenericCapability y;
- if (vcodecs[x].oid) {
- cap = new H245_CapabilityIdentifier(H245_CapabilityIdentifier::e_standard);
- PASN_ObjectId &object_id = *cap;
- object_id = vcodecs[x].oid;
- y.m_capabilityIdentifier = *cap;
- }
- if ((subType != H245_VideoCapability::e_genericVideoCapability) ||
- (vcodecs[x].oid && ((const H323GenericVideoCapability &)remoteCapabilities[i]).IsGenericMatch((const H245_GenericCapability)y))) {
- if (h323debug) {
- cout << "Found peer video capability " << remoteCapabilities[i] << ", Asterisk code is " << vcodecs[x].asterisk_codec << endl;
- }
- peer_capabilities |= vcodecs[x].asterisk_codec;
- }
- if (cap)
- delete(cap);
- }
- }
- break;
-#endif
- default:
- break;
- }
- }
- if (h323debug) {
- char caps_str[1024], caps2_str[1024];
- ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str));
- cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities)
- << ", ordered list is " << caps2_str << endl;
- }
-#if 0
- redir_capabilities &= peer_capabilities;
-#endif
- if (on_setpeercapabilities)
- on_setpeercapabilities(GetCallReference(), (const char *)callToken, peer_capabilities, &prefs);
-
- return TRUE;
-}
-
-H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability,
- H323Channel::Directions dir,
- unsigned sessionID,
- const H245_H2250LogicalChannelParameters * /*param*/,
- RTP_QOS * /*param*/ )
-{
- /* Do not open tx channel when transmitter has been paused by empty TCS */
- if ((dir == H323Channel::IsTransmitter) && transmitterSidePaused)
- return NULL;
-
- return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID);
-}
-
-/** This callback function is invoked once upon creation of each
- * channel for an H323 session
- */
-BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
-{
- /* Increase the count of channels we have open */
- channelsOpen++;
-
- if (h323debug) {
- cout << "\t-- Started logical channel: "
- << ((channel.GetDirection() == H323Channel::IsTransmitter) ? "sending " : ((channel.GetDirection() == H323Channel::IsReceiver) ? "receiving " : " "))
- << (const char *)(channel.GetCapability()).GetFormatName() << endl;
- cout << "\t\t-- channelsOpen = " << channelsOpen << endl;
- }
- return connectionState != ShuttingDownConnection;
-}
-
-void MyH323Connection::SetCapabilities(int cap, int dtmf_mode, void *_prefs, int pref_codec)
-{
- PINDEX lastcap = -1; /* last common capability index */
- int alreadysent = 0;
- int codec;
- int x, y;
- char caps_str[1024];
- struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs;
- struct ast_format_list format;
- int frames_per_packet;
- int max_frames_per_packet;
-
- localCapabilities.RemoveAll();
-
- if (h323debug) {
- cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), cap) << endl;
- ast_codec_pref_string(prefs, caps_str, sizeof(caps_str));
- cout << "Capabilities in preference order is " << caps_str << endl;
- }
- /* Add audio codecs in preference order first, then
- audio codecs without preference as allowed by mask */
- for (y = 0, x = -1; x < 32 + 32; ++x) {
- if (x < 0)
- codec = pref_codec;
- else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) {
- if (!y)
- y = 1;
- else if (y == AST_FORMAT_MAX_AUDIO)
- break;
- else
- y <<= 1;
- codec = y;
- }
- if (!(cap & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
- continue;
- alreadysent |= codec;
- format = ast_codec_pref_getsize(prefs, codec);
- frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms);
- max_frames_per_packet = (format.inc_ms ? format.max_ms / format.inc_ms : 0);
- switch(codec) {
-#if 0
- case AST_FORMAT_SPEEX:
- /* Not real sure if Asterisk acutally supports all
- of the various different bit rates so add them
- all and figure it out later*/
-
- lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow2AudioCapability());
- lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow3AudioCapability());
- lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow4AudioCapability());
- lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow5AudioCapability());
- lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow6AudioCapability());
- break;
-#endif
- case AST_FORMAT_G729A:
- AST_G729ACapability *g729aCap;
- AST_G729Capability *g729Cap;
- lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet));
- lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet));
- if (max_frames_per_packet) {
- g729aCap->SetTxFramesInPacket(max_frames_per_packet);
- g729Cap->SetTxFramesInPacket(max_frames_per_packet);
- }
- break;
- case AST_FORMAT_G723_1:
- AST_G7231Capability *g7231Cap;
- lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE));
- if (max_frames_per_packet)
- g7231Cap->SetTxFramesInPacket(max_frames_per_packet);
- lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE));
- if (max_frames_per_packet)
- g7231Cap->SetTxFramesInPacket(max_frames_per_packet);
- break;
- case AST_FORMAT_GSM:
- AST_GSM0610Capability *gsmCap;
- lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet));
- if (max_frames_per_packet)
- gsmCap->SetTxFramesInPacket(max_frames_per_packet);
- break;
- case AST_FORMAT_ULAW:
- AST_G711Capability *g711uCap;
- lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw));
- if (format.max_ms)
- g711uCap->SetTxFramesInPacket(format.max_ms);
- break;
- case AST_FORMAT_ALAW:
- AST_G711Capability *g711aCap;
- lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw));
- if (format.max_ms)
- g711aCap->SetTxFramesInPacket(format.max_ms);
- break;
- default:
- alreadysent &= ~codec;
- break;
- }
- }
-
- lastcap++;
- lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245));
-
- lastcap++;
- dtmfMode = dtmf_mode;
- if (dtmf_mode == H323_DTMF_INBAND) {
- localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::BasicString));
- sendUserInputMode = SendUserInputAsString;
- } else {
- lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833));
- /* Cisco sends DTMF only through h245-alphanumeric or h245-signal, no support for RFC2833 */
- lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245));
- sendUserInputMode = SendUserInputAsTone; /* RFC2833 transmission handled at Asterisk level */
- }
-
- if (h323debug) {
- cout << "Allowed Codecs:\n\t" << setprecision(2) << localCapabilities << endl;
- }
-}
-
-BOOL MyH323Connection::StartControlChannel(const H225_TransportAddress & h245Address)
-{
- // Check that it is an IP address, all we support at the moment
- if (h245Address.GetTag() != H225_TransportAddress::e_ipAddress
-#if P_HAS_IPV6
- && h245Address.GetTag() != H225_TransportAddress::e_ip6Address
-#endif
- ) {
- PTRACE(1, "H225\tConnect of H245 failed: Unsupported transport");
- return FALSE;
- }
-
- // Already have the H245 channel up.
- if (controlChannel != NULL)
- return TRUE;
-
- PIPSocket::Address addr;
- WORD port;
- GetSignallingChannel()->GetLocalAddress().GetIpAndPort(addr, port);
- if (addr) {
- if (h323debug)
- cout << "Using " << addr << " for outbound H.245 transport" << endl;
- controlChannel = new MyH323TransportTCP(endpoint, addr);
- } else
- controlChannel = new H323TransportTCP(endpoint);
- if (!controlChannel->SetRemoteAddress(h245Address)) {
- PTRACE(1, "H225\tCould not extract H245 address");
- delete controlChannel;
- controlChannel = NULL;
- return FALSE;
- }
- if (!controlChannel->Connect()) {
- PTRACE(1, "H225\tConnect of H245 failed: " << controlChannel->GetErrorText());
- delete controlChannel;
- controlChannel = NULL;
- return FALSE;
- }
-
- controlChannel->StartControlChannel(*this);
- return TRUE;
-}
-
-/* MyH323_ExternalRTPChannel */
-MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
- const H323Capability & capability,
- Directions direction,
- unsigned id)
- : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id)
-{
- struct rtp_info *info;
-
- /* Determine the Local (A side) IP Address and port */
- info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken());
- if (!info) {
- cout << "\tERROR: on_external_rtp_create failure" << endl;
- return;
- } else {
- localIpAddr = info->addr;
- localPort = info->port;
- /* tell the H.323 stack */
- SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1));
- /* clean up allocated memory */
- free(info);
- }
-
- /* Get the payload code */
- OpalMediaFormat format(capability.GetFormatName(), FALSE);
- payloadCode = format.GetPayloadType();
-}
-
-MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel()
-{
- if (h323debug) {
- cout << "\tExternalRTPChannel Destroyed" << endl;
- }
-}
-
-BOOL MyH323_ExternalRTPChannel::Start(void)
-{
- /* Call ancestor first */
- if (!H323_ExternalRTPChannel::Start()) {
- return FALSE;
- }
-
- if (h323debug) {
- cout << "\t\tExternal RTP Session Starting" << endl;
- cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl;
- }
-
- /* Collect the remote information */
- H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddr, remotePort);
-
- if (h323debug) {
- cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl;
- cout << "\t\t-- remotePort: " << remotePort << endl;
- cout << "\t\t-- ExternalIpAddress: " << localIpAddr << endl;
- cout << "\t\t-- ExternalPort: " << localPort << endl;
- }
- /* Notify Asterisk of remote RTP information */
- on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort,
- (const char *)connection.GetCallToken(), (int)payloadCode);
- return TRUE;
-}
-
-BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param)
-{
- if (h323debug) {
- cout << " MyH323_ExternalRTPChannel::OnReceivedAckPDU" << endl;
- }
-
- if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) {
- GetRemoteAddress(remoteIpAddr, remotePort);
- if (h323debug) {
- cout << " -- remoteIpAddress: " << remoteIpAddr << endl;
- cout << " -- remotePort: " << remotePort << endl;
- }
- on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(),
- remotePort, (const char *)connection.GetCallToken(), (int)payloadCode);
- return TRUE;
- }
- return FALSE;
-}
-
-
-/** IMPLEMENTATION OF C FUNCTIONS */
-
-/**
- * The extern "C" directive takes care for
- * the ANSI-C representation of linkable symbols
- */
-
-extern "C" {
-
-int h323_end_point_exist(void)
-{
- if (!endPoint) {
- return 0;
- }
- return 1;
-}
-
-void h323_end_point_create(void)
-{
- channelsOpen = 0;
- logstream = new PAsteriskLog();
- localProcess = new MyProcess();
- localProcess->Main();
-}
-
-void h323_gk_urq(void)
-{
- if (!h323_end_point_exist()) {
- cout << " ERROR: [h323_gk_urq] No Endpoint, this is bad" << endl;
- return;
- }
- endPoint->RemoveGatekeeper();
-}
-
-void h323_debug(int flag, unsigned level)
-{
- if (flag) {
- PTrace:: SetLevel(level);
- } else {
- PTrace:: SetLevel(0);
- }
-}
-
-/** Installs the callback functions on behalf of the PBX application */
-void h323_callback_register(setup_incoming_cb ifunc,
- setup_outbound_cb sfunc,
- on_rtp_cb rtpfunc,
- start_rtp_cb lfunc,
- clear_con_cb clfunc,
- chan_ringing_cb rfunc,
- con_established_cb efunc,
- receive_digit_cb dfunc,
- answer_call_cb acfunc,
- progress_cb pgfunc,
- rfc2833_cb dtmffunc,
- hangup_cb hangupfunc,
- setcapabilities_cb capabilityfunc,
- setpeercapabilities_cb peercapabilityfunc)
-{
- on_incoming_call = ifunc;
- on_outgoing_call = sfunc;
- on_external_rtp_create = rtpfunc;
- on_start_rtp_channel = lfunc;
- on_connection_cleared = clfunc;
- on_chan_ringing = rfunc;
- on_connection_established = efunc;
- on_receive_digit = dfunc;
- on_answer_call = acfunc;
- on_progress = pgfunc;
- on_set_rfc2833_payload = dtmffunc;
- on_hangup = hangupfunc;
- on_setcapabilities = capabilityfunc;
- on_setpeercapabilities = peercapabilityfunc;
-}
-
-/**
- * Add capability to the capability table of the end point.
- */
-int h323_set_capabilities(const char *token, int cap, int dtmf_mode, struct ast_codec_pref *prefs, int pref_codec)
-{
- MyH323Connection *conn;
-
- if (!h323_end_point_exist()) {
- cout << " ERROR: [h323_set_capablities] No Endpoint, this is bad" << endl;
- return 1;
- }
- if (!token || !*token) {
- cout << " ERROR: [h323_set_capabilities] Invalid call token specified." << endl;
- return 1;
- }
-
- PString myToken(token);
- conn = (MyH323Connection *)endPoint->FindConnectionWithLock(myToken);
- if (!conn) {
- cout << " ERROR: [h323_set_capabilities] Unable to find connection " << token << endl;
- return 1;
- }
- conn->SetCapabilities((/*conn->bridging ? conn->redir_capabilities :*/ cap), dtmf_mode, prefs, pref_codec);
- conn->Unlock();
-
- return 0;
-}
-
-/** Start the H.323 listener */
-int h323_start_listener(int listenPort, struct sockaddr_in bindaddr)
-{
-
- if (!h323_end_point_exist()) {
- cout << "ERROR: [h323_start_listener] No Endpoint, this is bad!" << endl;
- return 1;
- }
-
- PIPSocket::Address interfaceAddress(bindaddr.sin_addr);
- if (!listenPort) {
- listenPort = 1720;
- }
- /** H.323 listener */
- H323ListenerTCP *tcpListener;
- tcpListener = new H323ListenerTCP(*endPoint, interfaceAddress, (WORD)listenPort);
- if (!endPoint->StartListener(tcpListener)) {
- cout << "ERROR: Could not open H.323 listener port on " << ((H323ListenerTCP *) tcpListener)->GetListenerPort() << endl;
- delete tcpListener;
- return 1;
- }
- cout << " == H.323 listener started" << endl;
- return 0;
-};
-
-int h323_set_alias(struct oh323_alias *alias)
-{
- char *p;
- char *num;
- PString h323id(alias->name);
- PString e164(alias->e164);
- char *prefix;
-
- if (!h323_end_point_exist()) {
- cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl;
- return 1;
- }
-
- cout << "== Adding alias \"" << h323id << "\" to endpoint" << endl;
- endPoint->AddAliasName(h323id);
- endPoint->RemoveAliasName(localProcess->GetUserName());
-
- if (!e164.IsEmpty()) {
- cout << "== Adding E.164 \"" << e164 << "\" to endpoint" << endl;
- endPoint->AddAliasName(e164);
- }
- if (strlen(alias->prefix)) {
- p = prefix = strdup(alias->prefix);
- while((num = strsep(&p, ",")) != (char *)NULL) {
- cout << "== Adding Prefix \"" << num << "\" to endpoint" << endl;
- endPoint->SupportedPrefixes += PString(num);
- endPoint->SetGateway();
- }
- if (prefix)
- free(prefix);
- }
- return 0;
-}
-
-void h323_set_id(char *id)
-{
- PString h323id(id);
-
- if (h323debug) {
- cout << " == Using '" << h323id << "' as our H.323ID for this call" << endl;
- }
- /* EVIL HACK */
- endPoint->SetLocalUserName(h323id);
-}
-
-void h323_show_tokens(void)
-{
- cout << "Current call tokens: " << setprecision(2) << endPoint->GetAllConnections() << endl;
-}
-
-/** Establish Gatekeeper communiations, if so configured,
- * register aliases for the H.323 endpoint to respond to.
- */
-int h323_set_gk(int gatekeeper_discover, char *gatekeeper, char *secret)
-{
- PString gkName = PString(gatekeeper);
- PString pass = PString(secret);
- H323TransportUDP *rasChannel;
-
- if (!h323_end_point_exist()) {
- cout << "ERROR: [h323_set_gk] No Endpoint, this is bad!" << endl;
- return 1;
- }
-
- if (!gatekeeper) {
- cout << "Error: Gatekeeper cannot be NULL" << endl;
- return 1;
- }
- if (strlen(secret)) {
- endPoint->SetGatekeeperPassword(pass);
- }
- if (gatekeeper_discover) {
- /* discover the gk using multicast */
- if (endPoint->DiscoverGatekeeper(new MyH323TransportUDP(*endPoint))) {
- cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
- } else {
- cout << "Warning: Could not find a gatekeeper." << endl;
- return 1;
- }
- } else {
- rasChannel = new MyH323TransportUDP(*endPoint);
-
- if (!rasChannel) {
- cout << "Error: No RAS Channel, this is bad" << endl;
- return 1;
- }
- if (endPoint->SetGatekeeper(gkName, rasChannel)) {
- cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
- } else {
- cout << "Error registering with gatekeeper \"" << gkName << "\". " << endl;
- /* XXX Maybe we should fire a new thread to attempt to re-register later and not kill asterisk here? */
- return 1;
- }
- }
- return 0;
-}
-
-/** Send a DTMF tone over the H323Connection with the
- * specified token.
- */
-void h323_send_tone(const char *call_token, char tone)
-{
- if (!h323_end_point_exist()) {
- cout << "ERROR: [h323_send_tone] No Endpoint, this is bad!" << endl;
- return;
- }
- PString token = PString(call_token);
- endPoint->SendUserTone(token, tone);
-}
-
-/** Make a call to the remote endpoint.
- */
-int h323_make_call(char *dest, call_details_t *cd, call_options_t *call_options)
-{
- int res;
- PString token;
- PString host(dest);
-
- if (!h323_end_point_exist()) {
- return 1;
- }
-
- res = endPoint->MyMakeCall(host, token, &cd->call_reference, call_options);
- memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength());
- return res;
-};
-
-int h323_clear_call(const char *call_token, int cause)
-{
- H225_ReleaseCompleteReason dummy;
- H323Connection::CallEndReason r = H323Connection::EndedByLocalUser;
- MyH323Connection *connection;
- const PString currentToken(call_token);
-
- if (!h323_end_point_exist()) {
- return 1;
- }
-
- if (cause) {
- r = H323TranslateToCallEndReason((Q931::CauseValues)(cause), dummy);
- }
-
- connection = (MyH323Connection *)endPoint->FindConnectionWithLock(currentToken);
- if (connection) {
- connection->SetCause(cause);
- connection->SetCallEndReason(r);
- connection->Unlock();
- }
- endPoint->ClearCall(currentToken, r);
- return 0;
-};
-
-/* Send Alerting PDU to H.323 caller */
-int h323_send_alerting(const char *token)
-{
- const PString currentToken(token);
- H323Connection * connection;
-
- if (h323debug) {
- cout << "\tSending alerting" << endl;
- }
- connection = endPoint->FindConnectionWithLock(currentToken);
- if (!connection) {
- cout << "No connection found for " << token << endl;
- return -1;
- }
- connection->AnsweringCall(H323Connection::AnswerCallPending);
- connection->Unlock();
- return 0;
-}
-
-/* Send Progress PDU to H.323 caller */
-int h323_send_progress(const char *token)
-{
- const PString currentToken(token);
- H323Connection * connection;
-
- connection = endPoint->FindConnectionWithLock(currentToken);
- if (!connection) {
- cout << "No connection found for " << token << endl;
- return -1;
- }
-#if 1
- ((MyH323Connection *)connection)->MySendProgress();
-#else
- connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia);
-#endif
- connection->Unlock();
- return 0;
-}
-
-/** This function tells the h.323 stack to either
- answer or deny an incoming call */
-int h323_answering_call(const char *token, int busy)
-{
- const PString currentToken(token);
- H323Connection * connection;
-
- connection = endPoint->FindConnectionWithLock(currentToken);
-
- if (!connection) {
- cout << "No connection found for " << token << endl;
- return -1;
- }
- if (!busy) {
- if (h323debug) {
- cout << "\tAnswering call " << token << endl;
- }
- connection->AnsweringCall(H323Connection::AnswerCallNow);
- } else {
- if (h323debug) {
- cout << "\tdenying call " << token << endl;
- }
- connection->AnsweringCall(H323Connection::AnswerCallDenied);
- }
- connection->Unlock();
- return 0;
-}
-
-int h323_soft_hangup(const char *data)
-{
- PString token(data);
- BOOL result;
- cout << "Soft hangup" << endl;
- result = endPoint->ClearCall(token);
- return result;
-}
-
-/* alas, this doesn't work :( */
-void h323_native_bridge(const char *token, const char *them, char *capability)
-{
- H323Channel *channel;
- MyH323Connection *connection = (MyH323Connection *)endPoint->FindConnectionWithLock(token);
-
- if (!connection) {
- cout << "ERROR: No connection found, this is bad" << endl;
- return;
- }
-
- cout << "Native Bridge: them [" << them << "]" << endl;
-
- channel = connection->FindChannel(connection->sessionId, TRUE);
- connection->bridging = TRUE;
- connection->CloseLogicalChannelNumber(channel->GetNumber());
-
- connection->Unlock();
- return;
-
-}
-
-#undef cout
-#undef endl
-void h323_end_process(void)
-{
- if (endPoint) {
- endPoint->ClearAllCalls();
- endPoint->RemoveListener(NULL);
- delete endPoint;
- endPoint = NULL;
- }
- if (localProcess) {
- delete localProcess;
- localProcess = NULL;
- close(_timerChangePipe[0]);
- close(_timerChangePipe[1]);
- }
- if (logstream) {
- PTrace::SetLevel(0);
- PTrace::SetStream(&cout);
- delete logstream;
- logstream = NULL;
- }
-}
-
-} /* extern "C" */
-
diff --git a/1.4/channels/h323/ast_h323.h b/1.4/channels/h323/ast_h323.h
deleted file mode 100644
index c4f24c529..000000000
--- a/1.4/channels/h323/ast_h323.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * ast_h323.h
- *
- * OpenH323 Channel Driver for ASTERISK PBX.
- * By Jeremy McNamara
- * For The NuFone Network
- *
- * This code has been derived from code created by
- * Michael Manousos and Mark Spencer
- *
- * This file is part of the chan_h323 driver for Asterisk
- *
- * chan_h323 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * chan_h323 is distributed WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Version Info: $Id$
- */
-
-#ifndef AST_H323_H
-#define AST_H323_H
-
-#define VERSION(a,b,c) ((a)*10000+(b)*100+(c))
-
-class MyH323EndPoint : public H323EndPoint
-{
- PCLASSINFO(MyH323EndPoint, H323EndPoint);
-
-public:
- MyH323EndPoint();
- int MyMakeCall(const PString &, PString &, void *_callReference, void *_opts);
- BOOL ClearCall(const PString &, H323Connection::CallEndReason reason);
- BOOL ClearCall(const PString &);
-
- void OnClosedLogicalChannel(H323Connection &, const H323Channel &);
- void OnConnectionEstablished(H323Connection &, const PString &);
- void OnConnectionCleared(H323Connection &, const PString &);
- virtual H323Connection * CreateConnection(unsigned, void *, H323Transport *, H323SignalPDU *);
- void SendUserTone(const PString &, char);
- BOOL OnConnectionForwarded(H323Connection &, const PString &, const H323SignalPDU &);
- BOOL ForwardConnection(H323Connection &, const PString &, const H323SignalPDU &);
- void SetEndpointTypeInfo( H225_EndpointType & info ) const;
- void SetGateway(void);
- PStringArray SupportedPrefixes;
-};
-
-class MyH323Connection : public H323Connection
-{
- PCLASSINFO(MyH323Connection, H323Connection);
-
-public:
- MyH323Connection(MyH323EndPoint &, unsigned, unsigned);
- ~MyH323Connection();
- H323Channel * CreateRealTimeLogicalChannel(const H323Capability &,
- H323Channel::Directions,
- unsigned,
- const H245_H2250LogicalChannelParameters *,
- RTP_QOS *);
- H323Connection::AnswerCallResponse OnAnswerCall(const PString &,
- const H323SignalPDU &,
- H323SignalPDU &);
- void OnReceivedReleaseComplete(const H323SignalPDU &);
- BOOL OnAlerting(const H323SignalPDU &, const PString &);
- BOOL OnSendReleaseComplete(H323SignalPDU &);
- BOOL OnReceivedSignalSetup(const H323SignalPDU &);
- BOOL OnReceivedFacility(const H323SignalPDU &);
- BOOL OnSendSignalSetup(H323SignalPDU &);
- BOOL OnStartLogicalChannel(H323Channel &);
- BOOL OnClosingLogicalChannel(H323Channel &);
- virtual void SendUserInputTone(char tone, unsigned duration = 0, unsigned logicalChannel = 0, unsigned rtpTimestamp = 0);
- virtual void OnUserInputTone(char, unsigned, unsigned, unsigned);
- virtual void OnUserInputString(const PString &value);
- BOOL OnReceivedProgress(const H323SignalPDU &);
- BOOL MySendProgress();
- void OnSendCapabilitySet(H245_TerminalCapabilitySet &);
- void OnSetLocalCapabilities();
- void SetCapabilities(int, int, void *, int);
- BOOL OnReceivedCapabilitySet(const H323Capabilities &, const H245_MultiplexCapability *,
- H245_TerminalCapabilitySetReject &);
- void SetCause(int _cause) { cause = _cause; };
- virtual BOOL StartControlChannel(const H225_TransportAddress & h245Address);
- void SetCallOptions(void *opts, BOOL isIncoming);
- void SetCallDetails(void *callDetails, const H323SignalPDU &setupPDU, BOOL isIncoming);
- virtual H323Connection::CallEndReason SendSignalSetup(const PString&, const H323TransportAddress&);
-#ifdef TUNNELLING
- virtual BOOL HandleSignalPDU(H323SignalPDU &pdu);
- BOOL EmbedTunneledInfo(H323SignalPDU &pdu);
-#endif
-
- PString sourceAliases;
- PString destAliases;
- PString sourceE164;
- PString destE164;
- int cid_presentation;
- int cid_ton;
- PString rdnis;
- int redirect_reason;
- int transfer_capability;
-
- WORD sessionId;
- BOOL bridging;
-#ifdef TUNNELLING
- int remoteTunnelOptions;
- int tunnelOptions;
-#endif
-
- unsigned progressSetup;
- unsigned progressAlert;
- int cause;
-
- RTP_DataFrame::PayloadTypes dtmfCodec;
- int dtmfMode;
-};
-
-class MyH323_ExternalRTPChannel : public H323_ExternalRTPChannel
-{
- PCLASSINFO(MyH323_ExternalRTPChannel, H323_ExternalRTPChannel);
-
-public:
- MyH323_ExternalRTPChannel(
- MyH323Connection & connection,
- const H323Capability & capability,
- Directions direction,
- unsigned sessionID);
-
- ~MyH323_ExternalRTPChannel();
-
- /* Overrides */
- BOOL Start(void);
- BOOL OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param);
-
-protected:
- BYTE payloadCode;
-
- PIPSocket::Address localIpAddr;
- PIPSocket::Address remoteIpAddr;
- WORD localPort;
- WORD remotePort;
-};
-
-/**
- * The MyProcess is a necessary descendant PProcess class so that the H323EndPoint
- * objected to be created from within that class. (Solves the who owns main() problem).
- */
-class MyProcess : public PProcess
-{
- PCLASSINFO(MyProcess, PProcess);
-
-public:
- MyProcess();
- ~MyProcess();
- void Main();
-};
-
-#include "compat_h323.h"
-
-#endif /* !defined AST_H323_H */
diff --git a/1.4/channels/h323/caps_h323.cxx b/1.4/channels/h323/caps_h323.cxx
deleted file mode 100644
index a420825a3..000000000
--- a/1.4/channels/h323/caps_h323.cxx
+++ /dev/null
@@ -1,239 +0,0 @@
-#include <ptlib.h>
-#include <h323.h>
-#include <h245.h>
-#include "ast_h323.h"
-#include "caps_h323.h"
-
-#define DEFINE_G711_CAPABILITY(cls, code, capName) \
-class cls : public AST_G711Capability { \
- public: \
- cls() : AST_G711Capability(240, code) { } \
-}; \
-H323_REGISTER_CAPABILITY(cls, capName) \
-
-DEFINE_G711_CAPABILITY(AST_G711ALaw64Capability, H323_G711Capability::ALaw, OPAL_G711_ALAW_64K);
-DEFINE_G711_CAPABILITY(AST_G711uLaw64Capability, H323_G711Capability::muLaw, OPAL_G711_ULAW_64K);
-H323_REGISTER_CAPABILITY(AST_G7231Capability, OPAL_G7231);
-H323_REGISTER_CAPABILITY(AST_G729Capability, OPAL_G729);
-H323_REGISTER_CAPABILITY(AST_G729ACapability, OPAL_G729A);
-H323_REGISTER_CAPABILITY(AST_GSM0610Capability, OPAL_GSM0610);
-
-/*
- * Capability: G.711
- */
-AST_G711Capability::AST_G711Capability(int rx_frames, H323_G711Capability::Mode m, H323_G711Capability::Speed s)
- : H323AudioCapability(rx_frames, 30) // 240ms max, 30ms desired
-{
- mode = m;
- speed = s;
-}
-
-
-PObject * AST_G711Capability::Clone() const
-{
- return new AST_G711Capability(*this);
-}
-
-
-unsigned AST_G711Capability::GetSubType() const
-{
- static const unsigned G711SubType[2][2] = {
- { H245_AudioCapability::e_g711Alaw64k, H245_AudioCapability::e_g711Alaw56k },
- { H245_AudioCapability::e_g711Ulaw64k, H245_AudioCapability::e_g711Ulaw56k }
- };
- return G711SubType[mode][speed];
-}
-
-
-PString AST_G711Capability::GetFormatName() const
-{
- static const char * const G711Name[2][2] = {
- { OPAL_G711_ALAW_64K, OPAL_G711_ALAW_56K },
- { OPAL_G711_ULAW_64K, OPAL_G711_ULAW_56K },
- };
- return G711Name[mode][speed];
-}
-
-
-H323Codec * AST_G711Capability::CreateCodec(H323Codec::Direction direction) const
-{
- return NULL;
-}
-
-
-/*
- * Capability: G.723.1
- */
-AST_G7231Capability::AST_G7231Capability(int rx_frames, BOOL annexA_)
- : H323AudioCapability(rx_frames, 4)
-{
- annexA = annexA_;
-}
-
-PObject::Comparison AST_G7231Capability::Compare(const PObject & obj) const
-{
- Comparison result = H323AudioCapability::Compare(obj);
- if (result != EqualTo) {
- return result;
- }
- PINDEX otherAnnexA = ((const AST_G7231Capability &)obj).annexA;
- if (annexA < otherAnnexA) {
- return LessThan;
- }
- if (annexA > otherAnnexA) {
- return GreaterThan;
- }
- return EqualTo;
-}
-
-PObject * AST_G7231Capability::Clone() const
-{
- return new AST_G7231Capability(*this);
-}
-
-PString AST_G7231Capability::GetFormatName() const
-{
- return (annexA ? OPAL_G7231 "A" : OPAL_G7231);
-}
-
-unsigned AST_G7231Capability::GetSubType() const
-{
- return H245_AudioCapability::e_g7231;
-}
-
-BOOL AST_G7231Capability::OnSendingPDU(H245_AudioCapability & cap,
- unsigned packetSize) const
-{
- cap.SetTag(H245_AudioCapability::e_g7231);
- H245_AudioCapability_g7231 & g7231 = cap;
- g7231.m_maxAl_sduAudioFrames = packetSize;
- g7231.m_silenceSuppression = annexA;
- return TRUE;
-}
-
-BOOL AST_G7231Capability::OnReceivedPDU(const H245_AudioCapability & cap,
- unsigned & packetSize)
-{
- if (cap.GetTag() != H245_AudioCapability::e_g7231) {
- return FALSE;
- }
- const H245_AudioCapability_g7231 & g7231 = cap;
- packetSize = g7231.m_maxAl_sduAudioFrames;
- annexA = g7231.m_silenceSuppression;
- return TRUE;
-}
-
-H323Codec * AST_G7231Capability::CreateCodec(H323Codec::Direction direction) const
-{
- return NULL;
-}
-
-/*
- * Capability: G.729
- */
-AST_G729Capability::AST_G729Capability(int rx_frames)
- : H323AudioCapability(rx_frames, 2)
-{
-}
-
-PObject * AST_G729Capability::Clone() const
-{
- return new AST_G729Capability(*this);
-}
-
-unsigned AST_G729Capability::GetSubType() const
-{
- return H245_AudioCapability::e_g729;
-}
-
-PString AST_G729Capability::GetFormatName() const
-{
- return OPAL_G729;
-}
-
-H323Codec * AST_G729Capability::CreateCodec(H323Codec::Direction direction) const
-{
- return NULL;
-}
-
-/*
- * Capability: G.729A
- */
-AST_G729ACapability::AST_G729ACapability(int rx_frames)
- : H323AudioCapability(rx_frames, 6)
-{
-}
-
-PObject * AST_G729ACapability::Clone() const
-{
- return new AST_G729ACapability(*this);
-}
-
-unsigned AST_G729ACapability::GetSubType() const
-{
- return H245_AudioCapability::e_g729AnnexA;
-}
-
-PString AST_G729ACapability::GetFormatName() const
-{
- return OPAL_G729A;
-}
-
-H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) const
-{
- return NULL;
-}
-
-/*
- * Capability: GSM full rate
- */
-AST_GSM0610Capability::AST_GSM0610Capability(int rx_frames, int comfortNoise_, int scrambled_)
- : H323AudioCapability(rx_frames, 2)
-{
- comfortNoise = comfortNoise_;
- scrambled = scrambled_;
-}
-
-PObject * AST_GSM0610Capability::Clone() const
-{
- return new AST_GSM0610Capability(*this);
-}
-
-unsigned AST_GSM0610Capability::GetSubType() const
-{
- return H245_AudioCapability::e_gsmFullRate;
-}
-
-BOOL AST_GSM0610Capability::OnSendingPDU(H245_AudioCapability & cap,
- unsigned packetSize) const
-{
- cap.SetTag(H245_AudioCapability::e_gsmFullRate);
- H245_GSMAudioCapability & gsm = cap;
- gsm.m_audioUnitSize = packetSize * 33;
- gsm.m_comfortNoise = comfortNoise;
- gsm.m_scrambled = scrambled;
- return TRUE;
-}
-
-BOOL AST_GSM0610Capability::OnReceivedPDU(const H245_AudioCapability & cap,
- unsigned & packetSize)
-{
- if (cap.GetTag() != H245_AudioCapability::e_gsmFullRate)
- return FALSE;
- const H245_GSMAudioCapability & gsm = cap;
- packetSize = (gsm.m_audioUnitSize + 32) / 33;
- comfortNoise = gsm.m_comfortNoise;
- scrambled = gsm.m_scrambled;
-
- return TRUE;
-}
-
-PString AST_GSM0610Capability::GetFormatName() const
-{
- return OPAL_GSM0610;
-}
-
-H323Codec * AST_GSM0610Capability::CreateCodec(H323Codec::Direction direction) const
-{
- return NULL;
-}
diff --git a/1.4/channels/h323/caps_h323.h b/1.4/channels/h323/caps_h323.h
deleted file mode 100644
index be63e0230..000000000
--- a/1.4/channels/h323/caps_h323.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef __AST_H323CAPS_H
-#define __AST_H323CAPS_H
-
-/**This class describes the G.711 codec capability.
- */
-class AST_G711Capability : public H323AudioCapability
-{
- PCLASSINFO(AST_G711Capability, H323AudioCapability);
-
-public:
- AST_G711Capability(int rx_frames = 125, H323_G711Capability::Mode _mode = H323_G711Capability::muLaw, H323_G711Capability::Speed _speed = H323_G711Capability::At64k);
- virtual PObject *Clone() const;
- virtual H323Codec * CreateCodec(H323Codec::Direction direction) const;
- virtual unsigned GetSubType() const;
- virtual PString GetFormatName() const;
-
-protected:
- H323_G711Capability::Mode mode;
- H323_G711Capability::Speed speed;
-};
-
-/**This class describes the G.723.1 codec capability.
- */
-class AST_G7231Capability : public H323AudioCapability
-{
- PCLASSINFO(AST_G7231Capability, H323AudioCapability);
-
-public:
- AST_G7231Capability(int rx_frames = 7, BOOL annexA = TRUE);
- Comparison Compare(const PObject & obj) const;
- virtual PObject * Clone() const;
- virtual H323Codec * CreateCodec(H323Codec::Direction direction) const;
- virtual unsigned GetSubType() const;
- virtual PString GetFormatName() const;
- virtual BOOL OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const;
- virtual BOOL OnReceivedPDU(const H245_AudioCapability & pdu, unsigned & packetSize);
-
-protected:
- BOOL annexA;
-};
-
-/**This class describes the (fake) G729 codec capability.
- */
-class AST_G729Capability : public H323AudioCapability
-{
- PCLASSINFO(AST_G729Capability, H323AudioCapability);
-
-public:
- AST_G729Capability(int rx_frames = 24);
- /* Create a copy of the object. */
- virtual PObject * Clone() const;
-
- /* Create the codec instance, allocating resources as required. */
- virtual H323Codec * CreateCodec(H323Codec::Direction direction) const;
-
- /* Get the sub-type of the capability. This is a code dependent on the
- main type of the capability.
-
- This returns one of the four possible combinations of mode and speed
- using the enum values of the protocol ASN H245_AudioCapability class. */
- virtual unsigned GetSubType() const;
-
- /* Get the name of the media data format this class represents. */
- virtual PString GetFormatName() const;
-};
-
-/* This class describes the VoiceAge G729A codec capability. */
-class AST_G729ACapability : public H323AudioCapability
-{
- PCLASSINFO(AST_G729ACapability, H323AudioCapability);
-
-public:
- /* Create a new G.729A capability. */
- AST_G729ACapability(int rx_frames = 24);
-
- /* Create a copy of the object. */
- virtual PObject * Clone() const;
- /* Create the codec instance, allocating resources as required. */
- virtual H323Codec * CreateCodec(H323Codec::Direction direction) const;
-
- /* Get the sub-type of the capability. This is a code dependent on the
- main type of the capability.
-
- This returns one of the four possible combinations of mode and speed
- using the enum values of the protocol ASN H245_AudioCapability class. */
- virtual unsigned GetSubType() const;
-
- /* Get the name of the media data format this class represents. */
- virtual PString GetFormatName() const;
-};
-
-/* This class describes the GSM-06.10 codec capability. */
-class AST_GSM0610Capability : public H323AudioCapability
-{
- PCLASSINFO(AST_GSM0610Capability, H323AudioCapability);
-
-public:
- /* Create a new GSM capability. */
- AST_GSM0610Capability(int rx_frames = 24, int comfortNoise = 0, int scrambled = 0);
-
- /* Create a copy of the object. */
- virtual PObject * Clone() const;
-
- /* Create the codec instance, allocating resources as required. */
- virtual H323Codec * CreateCodec(H323Codec::Direction direction) const;
-
- /* Get the sub-type of the capability. This is a code dependent on the
- main type of the capability.
-
- This returns one of the four possible combinations of mode and speed
- using the enum values of the protocol ASN H245_AudioCapability class. */
- virtual unsigned GetSubType() const;
-
- /* Get the name of the media data format this class represents. */
- virtual PString GetFormatName() const;
-
- BOOL OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const;
- BOOL OnReceivedPDU(const H245_AudioCapability & pdu, unsigned & packetSize);
-
-protected:
- int comfortNoise;
- int scrambled;
-};
-#endif /* __AST_H323CAPS_H */
diff --git a/1.4/channels/h323/chan_h323.h b/1.4/channels/h323/chan_h323.h
deleted file mode 100644
index 0fd94561f..000000000
--- a/1.4/channels/h323/chan_h323.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * chan_h323.h
- *
- * OpenH323 Channel Driver for ASTERISK PBX.
- * By Jeremy McNamara
- * For The NuFone Network
- *
- * This code has been derived from code created by
- * Michael Manousos and Mark Spencer
- *
- * This file is part of the chan_h323 driver for Asterisk
- *
- * chan_h323 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * chan_h323 is distributed WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Version Info: $Id$
- */
-
-#include <arpa/inet.h>
-
-/*
- * Enable support for sending/reception of tunnelled Q.SIG messages and
- * some sort of IEs (especially RedirectingNumber) which Cisco CallManager
- * isn't like to pass in standard Q.931 message.
- *
- */
-#define TUNNELLING
-
-#define H323_TUNNEL_CISCO (1 << 0)
-#define H323_TUNNEL_QSIG (1 << 1)
-
-/** call_option struct holds various bits
- * of information for each call */
-typedef struct call_options {
- char cid_num[80];
- char cid_name[80];
- char cid_rdnis[80];
- int redirect_reason;
- int presentation;
- int type_of_number;
- int transfer_capability;
- int fastStart;
- int h245Tunneling;
- int silenceSuppression;
- int progress_setup;
- int progress_alert;
- int progress_audio;
- int dtmfcodec;
- int dtmfmode;
- int capability;
- int bridge;
- int nat;
- int tunnelOptions;
- struct ast_codec_pref prefs;
-} call_options_t;
-
-/* structure to hold the valid asterisk users */
-struct oh323_user {
- ASTOBJ_COMPONENTS(struct oh323_user);
-// char name[80];
- char context[80];
- char secret[80];
- char accountcode[AST_MAX_ACCOUNT_CODE];
- int amaflags;
- int host;
- struct sockaddr_in addr;
- struct ast_ha *ha;
- call_options_t options;
-};
-
-/* structure to hold the valid asterisk peers
- All peers are registered to a GK if there is one */
-struct oh323_peer {
- ASTOBJ_COMPONENTS(struct oh323_peer);
- char mailbox[80];
- int delme;
- struct sockaddr_in addr;
- struct ast_ha *ha;
- call_options_t options;
-};
-
-/* structure to hold the H.323 aliases which get registered to
- the H.323 endpoint and gatekeeper */
-struct oh323_alias {
- ASTOBJ_COMPONENTS(struct oh323_alias);
- char e164[20]; /* tells a GK to route this E.164 to this alias */
- char prefix[500]; /* tells a GK this alias supports these prefixes */
- char secret[20]; /* the H.235 password to send to the GK for authentication */
- char context[80];
-};
-
-/** call_details struct call detail records
- to asterisk for processing and used for matching up
- asterisk channels to acutal h.323 connections */
-typedef struct call_details {
- unsigned int call_reference;
- char *call_token;
- char *call_source_aliases;
- char *call_dest_alias;
- char *call_source_name;
- char *call_source_e164;
- char *call_dest_e164;
- char *redirect_number;
- int redirect_reason;
- int presentation;
- int type_of_number;
- int transfer_capability;
- char *sourceIp;
-} call_details_t;
-
-typedef struct rtp_info {
- char addr[32];
- unsigned int port;
-} rtp_info_t;
-
-/* This is a callback prototype function, called pass
- DTMF down the RTP. */
-typedef int (*receive_digit_cb)(unsigned, char, const char *, int);
-extern receive_digit_cb on_receive_digit;
-
-/* This is a callback prototype function, called to collect
- the external RTP port from Asterisk. */
-typedef rtp_info_t *(*on_rtp_cb)(unsigned, const char *);
-extern on_rtp_cb on_external_rtp_create;
-
-/* This is a callback prototype function, called to send
- the remote IP and RTP port from H.323 to Asterisk */
-typedef void (*start_rtp_cb)(unsigned int, const char *, int, const char *, int);
-extern start_rtp_cb on_start_rtp_channel;
-
-/* This is a callback that happens when call progress is
- * made, and handles inband progress */
-typedef int (*progress_cb)(unsigned, const char *, int);
-extern progress_cb on_progress;
-
-/* This is a callback prototype function, called upon
- an incoming call happens. */
-typedef call_options_t *(*setup_incoming_cb)(call_details_t *);
-extern setup_incoming_cb on_incoming_call;
-
-/* This is a callback prototype function, called upon
- an outbound call. */
-typedef int (*setup_outbound_cb)(call_details_t *);
-extern setup_outbound_cb on_outgoing_call;
-
-/* This is a callback prototype function, called when
- OnAlerting is invoked */
-typedef void (*chan_ringing_cb)(unsigned, const char *);
-extern chan_ringing_cb on_chan_ringing;
-
-/* This is a callback protoype function, called when
- OnConnectionEstablished is inovked */
-typedef void (*con_established_cb)(unsigned, const char *);
-extern con_established_cb on_connection_established;
-
-/* This is a callback prototype function, called when
- OnConnectionCleared callback is invoked */
-typedef void (*clear_con_cb)(unsigned, const char *);
-extern clear_con_cb on_connection_cleared;
-
-/* This is a callback prototype function, called when
- an H.323 call is answered */
-typedef int (*answer_call_cb)(unsigned, const char *);
-extern answer_call_cb on_answer_call;
-
-/* This is a callback prototype function, called when
- we know which RTP payload type RFC2833 will be
- transmitted */
-typedef void (*rfc2833_cb)(unsigned, const char *, int);
-extern rfc2833_cb on_set_rfc2833_payload;
-
-typedef void (*hangup_cb)(unsigned, const char *, int);
-extern hangup_cb on_hangup;
-
-typedef void (*setcapabilities_cb)(unsigned, const char *);
-extern setcapabilities_cb on_setcapabilities;
-
-typedef void (*setpeercapabilities_cb)(unsigned, const char *, int, struct ast_codec_pref *);
-extern setpeercapabilities_cb on_setpeercapabilities;
-
-/* debug flag */
-extern int h323debug;
-
-#define H323_DTMF_RFC2833 (1 << 0)
-#define H323_DTMF_INBAND (1 << 1)
-
-#ifndef BOOL
-#define BOOL int
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- void h323_gk_urq(void);
- void h323_end_point_create(void);
- void h323_end_process(void);
- int h323_end_point_exist(void);
-
- void h323_debug(int, unsigned);
-
- /* callback function handler*/
- void h323_callback_register(setup_incoming_cb,
- setup_outbound_cb,
- on_rtp_cb,
- start_rtp_cb,
- clear_con_cb,
- chan_ringing_cb,
- con_established_cb,
- receive_digit_cb,
- answer_call_cb,
- progress_cb,
- rfc2833_cb,
- hangup_cb,
- setcapabilities_cb,
- setpeercapabilities_cb);
- int h323_set_capabilities(const char *, int, int, struct ast_codec_pref *, int);
- int h323_set_alias(struct oh323_alias *);
- int h323_set_gk(int, char *, char *);
- void h323_set_id(char *);
- void h323_show_tokens(void);
-
- /* H323 listener related funcions */
- int h323_start_listener(int, struct sockaddr_in);
-
- void h323_native_bridge(const char *, const char *, char *);
-
- /* Send a DTMF tone to remote endpoint */
- void h323_send_tone(const char *call_token, char tone);
-
- /* H323 create and destroy sessions */
- int h323_make_call(char *dest, call_details_t *cd, call_options_t *);
- int h323_clear_call(const char *, int cause);
-
- /* H.323 alerting and progress */
- int h323_send_alerting(const char *token);
- int h323_send_progress(const char *token);
- int h323_answering_call(const char *token, int);
- int h323_soft_hangup(const char *data);
- int h323_show_codec(int fd, int argc, char *argv[]);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/1.4/channels/h323/cisco-h225.asn b/1.4/channels/h323/cisco-h225.asn
deleted file mode 100644
index 1372e67d5..000000000
--- a/1.4/channels/h323/cisco-h225.asn
+++ /dev/null
@@ -1,74 +0,0 @@
-CISCO-H225-MESSAGES DEFINITIONS AUTOMATIC TAGS ::=
-BEGIN
-
-H323_UU_NonStdInfo ::= SEQUENCE
-{
- version INTEGER OPTIONAL,
- protoParam ProtoParam OPTIONAL,
- commonParam CommonParam OPTIONAL,
- ...,
- dummy1 OCTET STRING OPTIONAL,
- progIndParam ProgIndParam OPTIONAL,
- callMgrParam CallMgrParam OPTIONAL,
- callSignallingParam CallSignallingParam OPTIONAL,
- dummy2 OCTET STRING OPTIONAL,
- callPreserveParam CallPreserveParam OPTIONAL
-}
-
-CommonParam ::= SEQUENCE
-{
- redirectIEinfo RedirectIEinfo,
- ...
-}
-
-RedirectIEinfo ::= SEQUENCE
-{
- redirectIE OCTET STRING,
- ...
-}
-
-ProgIndParam ::= SEQUENCE
-{
- progIndIEinfo ProgIndIEinfo,
- ...
-}
-
-ProgIndIEinfo ::= SEQUENCE
-{
- progIndIE OCTET STRING,
- ...
-}
-
-ProtoParam ::= SEQUENCE
-{
- qsigNonStdInfo QsigNonStdInfo,
- ...
-}
-
-QsigNonStdInfo ::= SEQUENCE
-{
- iei INTEGER,
- rawMesg OCTET STRING,
- ...
-}
-
-CallMgrParam ::= SEQUENCE
-{
- interclusterVersion INTEGER,
- enterpriseID OCTET STRING,
- ...
-}
-
-CallPreserveParam ::= SEQUENCE
-{
- callPreserveIE BOOLEAN,
- ...
-}
-
-CallSignallingParam ::= SEQUENCE
-{
- connectedNumber OCTET STRING (1..127) OPTIONAL,
- ...
-}
-
-END
diff --git a/1.4/channels/h323/cisco-h225.cxx b/1.4/channels/h323/cisco-h225.cxx
deleted file mode 100644
index 37adc4e87..000000000
--- a/1.4/channels/h323/cisco-h225.cxx
+++ /dev/null
@@ -1,853 +0,0 @@
-//
-// cisco-h225.cxx
-//
-// Code automatically generated by asnparse.
-//
-
-#ifdef P_USE_PRAGMA
-#pragma implementation "cisco-h225.h"
-#endif
-
-#include <ptlib.h>
-#include "cisco-h225.h"
-
-#define new PNEW
-
-
-#if ! H323_DISABLE_CISCO_H225
-
-//
-// RedirectIEinfo
-//
-
-CISCO_H225_RedirectIEinfo::CISCO_H225_RedirectIEinfo(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_RedirectIEinfo::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+13) << "redirectIE = " << setprecision(indent) << m_redirectIE << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_RedirectIEinfo::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_RedirectIEinfo), PInvalidCast);
-#endif
- const CISCO_H225_RedirectIEinfo & other = (const CISCO_H225_RedirectIEinfo &)obj;
-
- Comparison result;
-
- if ((result = m_redirectIE.Compare(other.m_redirectIE)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_RedirectIEinfo::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_redirectIE.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_RedirectIEinfo::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_redirectIE.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_RedirectIEinfo::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_redirectIE.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_RedirectIEinfo::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_RedirectIEinfo::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_RedirectIEinfo(*this);
-}
-
-
-//
-// ProgIndIEinfo
-//
-
-CISCO_H225_ProgIndIEinfo::CISCO_H225_ProgIndIEinfo(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_ProgIndIEinfo::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+12) << "progIndIE = " << setprecision(indent) << m_progIndIE << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_ProgIndIEinfo::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_ProgIndIEinfo), PInvalidCast);
-#endif
- const CISCO_H225_ProgIndIEinfo & other = (const CISCO_H225_ProgIndIEinfo &)obj;
-
- Comparison result;
-
- if ((result = m_progIndIE.Compare(other.m_progIndIE)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_ProgIndIEinfo::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_progIndIE.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_ProgIndIEinfo::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_progIndIE.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_ProgIndIEinfo::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_progIndIE.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_ProgIndIEinfo::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_ProgIndIEinfo::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_ProgIndIEinfo(*this);
-}
-
-
-//
-// QsigNonStdInfo
-//
-
-CISCO_H225_QsigNonStdInfo::CISCO_H225_QsigNonStdInfo(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_QsigNonStdInfo::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+6) << "iei = " << setprecision(indent) << m_iei << '\n';
- strm << setw(indent+10) << "rawMesg = " << setprecision(indent) << m_rawMesg << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_QsigNonStdInfo::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_QsigNonStdInfo), PInvalidCast);
-#endif
- const CISCO_H225_QsigNonStdInfo & other = (const CISCO_H225_QsigNonStdInfo &)obj;
-
- Comparison result;
-
- if ((result = m_iei.Compare(other.m_iei)) != EqualTo)
- return result;
- if ((result = m_rawMesg.Compare(other.m_rawMesg)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_QsigNonStdInfo::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_iei.GetObjectLength();
- length += m_rawMesg.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_QsigNonStdInfo::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_iei.Decode(strm))
- return FALSE;
- if (!m_rawMesg.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_QsigNonStdInfo::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_iei.Encode(strm);
- m_rawMesg.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_QsigNonStdInfo::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_QsigNonStdInfo::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_QsigNonStdInfo(*this);
-}
-
-
-//
-// CallMgrParam
-//
-
-CISCO_H225_CallMgrParam::CISCO_H225_CallMgrParam(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_CallMgrParam::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+22) << "interclusterVersion = " << setprecision(indent) << m_interclusterVersion << '\n';
- strm << setw(indent+15) << "enterpriseID = " << setprecision(indent) << m_enterpriseID << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_CallMgrParam::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_CallMgrParam), PInvalidCast);
-#endif
- const CISCO_H225_CallMgrParam & other = (const CISCO_H225_CallMgrParam &)obj;
-
- Comparison result;
-
- if ((result = m_interclusterVersion.Compare(other.m_interclusterVersion)) != EqualTo)
- return result;
- if ((result = m_enterpriseID.Compare(other.m_enterpriseID)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_CallMgrParam::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_interclusterVersion.GetObjectLength();
- length += m_enterpriseID.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_CallMgrParam::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_interclusterVersion.Decode(strm))
- return FALSE;
- if (!m_enterpriseID.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_CallMgrParam::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_interclusterVersion.Encode(strm);
- m_enterpriseID.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_CallMgrParam::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_CallMgrParam::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_CallMgrParam(*this);
-}
-
-
-//
-// CallPreserveParam
-//
-
-CISCO_H225_CallPreserveParam::CISCO_H225_CallPreserveParam(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_CallPreserveParam::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+17) << "callPreserveIE = " << setprecision(indent) << m_callPreserveIE << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_CallPreserveParam::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_CallPreserveParam), PInvalidCast);
-#endif
- const CISCO_H225_CallPreserveParam & other = (const CISCO_H225_CallPreserveParam &)obj;
-
- Comparison result;
-
- if ((result = m_callPreserveIE.Compare(other.m_callPreserveIE)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_CallPreserveParam::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_callPreserveIE.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_CallPreserveParam::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_callPreserveIE.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_CallPreserveParam::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_callPreserveIE.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_CallPreserveParam::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_CallPreserveParam::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_CallPreserveParam(*this);
-}
-
-
-//
-// CallSignallingParam
-//
-
-CISCO_H225_CallSignallingParam::CISCO_H225_CallSignallingParam(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 1, TRUE, 0)
-{
- m_connectedNumber.SetConstraints(PASN_Object::FixedConstraint, 1, 127);
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_CallSignallingParam::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- if (HasOptionalField(e_connectedNumber))
- strm << setw(indent+18) << "connectedNumber = " << setprecision(indent) << m_connectedNumber << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_CallSignallingParam::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_CallSignallingParam), PInvalidCast);
-#endif
- const CISCO_H225_CallSignallingParam & other = (const CISCO_H225_CallSignallingParam &)obj;
-
- Comparison result;
-
- if ((result = m_connectedNumber.Compare(other.m_connectedNumber)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_CallSignallingParam::GetDataLength() const
-{
- PINDEX length = 0;
- if (HasOptionalField(e_connectedNumber))
- length += m_connectedNumber.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_CallSignallingParam::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (HasOptionalField(e_connectedNumber) && !m_connectedNumber.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_CallSignallingParam::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- if (HasOptionalField(e_connectedNumber))
- m_connectedNumber.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_CallSignallingParam::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_CallSignallingParam::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_CallSignallingParam(*this);
-}
-
-
-//
-// CommonParam
-//
-
-CISCO_H225_CommonParam::CISCO_H225_CommonParam(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_CommonParam::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+17) << "redirectIEinfo = " << setprecision(indent) << m_redirectIEinfo << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_CommonParam::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_CommonParam), PInvalidCast);
-#endif
- const CISCO_H225_CommonParam & other = (const CISCO_H225_CommonParam &)obj;
-
- Comparison result;
-
- if ((result = m_redirectIEinfo.Compare(other.m_redirectIEinfo)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_CommonParam::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_redirectIEinfo.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_CommonParam::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_redirectIEinfo.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_CommonParam::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_redirectIEinfo.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_CommonParam::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_CommonParam::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_CommonParam(*this);
-}
-
-
-//
-// ProgIndParam
-//
-
-CISCO_H225_ProgIndParam::CISCO_H225_ProgIndParam(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_ProgIndParam::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+16) << "progIndIEinfo = " << setprecision(indent) << m_progIndIEinfo << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_ProgIndParam::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_ProgIndParam), PInvalidCast);
-#endif
- const CISCO_H225_ProgIndParam & other = (const CISCO_H225_ProgIndParam &)obj;
-
- Comparison result;
-
- if ((result = m_progIndIEinfo.Compare(other.m_progIndIEinfo)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_ProgIndParam::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_progIndIEinfo.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_ProgIndParam::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_progIndIEinfo.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_ProgIndParam::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_progIndIEinfo.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_ProgIndParam::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_ProgIndParam::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_ProgIndParam(*this);
-}
-
-
-//
-// ProtoParam
-//
-
-CISCO_H225_ProtoParam::CISCO_H225_ProtoParam(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 0, TRUE, 0)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_ProtoParam::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- strm << setw(indent+17) << "qsigNonStdInfo = " << setprecision(indent) << m_qsigNonStdInfo << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_ProtoParam::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_ProtoParam), PInvalidCast);
-#endif
- const CISCO_H225_ProtoParam & other = (const CISCO_H225_ProtoParam &)obj;
-
- Comparison result;
-
- if ((result = m_qsigNonStdInfo.Compare(other.m_qsigNonStdInfo)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_ProtoParam::GetDataLength() const
-{
- PINDEX length = 0;
- length += m_qsigNonStdInfo.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_ProtoParam::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (!m_qsigNonStdInfo.Decode(strm))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_ProtoParam::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- m_qsigNonStdInfo.Encode(strm);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_ProtoParam::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_ProtoParam::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_ProtoParam(*this);
-}
-
-
-//
-// H323_UU_NonStdInfo
-//
-
-CISCO_H225_H323_UU_NonStdInfo::CISCO_H225_H323_UU_NonStdInfo(unsigned tag, PASN_Object::TagClass tagClass)
- : PASN_Sequence(tag, tagClass, 3, TRUE, 6)
-{
-}
-
-
-#ifndef PASN_NOPRINTON
-void CISCO_H225_H323_UU_NonStdInfo::PrintOn(ostream & strm) const
-{
- int indent = strm.precision() + 2;
- strm << "{\n";
- if (HasOptionalField(e_version))
- strm << setw(indent+10) << "version = " << setprecision(indent) << m_version << '\n';
- if (HasOptionalField(e_protoParam))
- strm << setw(indent+13) << "protoParam = " << setprecision(indent) << m_protoParam << '\n';
- if (HasOptionalField(e_commonParam))
- strm << setw(indent+14) << "commonParam = " << setprecision(indent) << m_commonParam << '\n';
- if (HasOptionalField(e_dummy1))
- strm << setw(indent+9) << "dummy1 = " << setprecision(indent) << m_dummy1 << '\n';
- if (HasOptionalField(e_progIndParam))
- strm << setw(indent+15) << "progIndParam = " << setprecision(indent) << m_progIndParam << '\n';
- if (HasOptionalField(e_callMgrParam))
- strm << setw(indent+15) << "callMgrParam = " << setprecision(indent) << m_callMgrParam << '\n';
- if (HasOptionalField(e_callSignallingParam))
- strm << setw(indent+22) << "callSignallingParam = " << setprecision(indent) << m_callSignallingParam << '\n';
- if (HasOptionalField(e_dummy2))
- strm << setw(indent+9) << "dummy2 = " << setprecision(indent) << m_dummy2 << '\n';
- if (HasOptionalField(e_callPreserveParam))
- strm << setw(indent+20) << "callPreserveParam = " << setprecision(indent) << m_callPreserveParam << '\n';
- strm << setw(indent-1) << setprecision(indent-2) << "}";
-}
-#endif
-
-
-PObject::Comparison CISCO_H225_H323_UU_NonStdInfo::Compare(const PObject & obj) const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(PIsDescendant(&obj, CISCO_H225_H323_UU_NonStdInfo), PInvalidCast);
-#endif
- const CISCO_H225_H323_UU_NonStdInfo & other = (const CISCO_H225_H323_UU_NonStdInfo &)obj;
-
- Comparison result;
-
- if ((result = m_version.Compare(other.m_version)) != EqualTo)
- return result;
- if ((result = m_protoParam.Compare(other.m_protoParam)) != EqualTo)
- return result;
- if ((result = m_commonParam.Compare(other.m_commonParam)) != EqualTo)
- return result;
-
- return PASN_Sequence::Compare(other);
-}
-
-
-PINDEX CISCO_H225_H323_UU_NonStdInfo::GetDataLength() const
-{
- PINDEX length = 0;
- if (HasOptionalField(e_version))
- length += m_version.GetObjectLength();
- if (HasOptionalField(e_protoParam))
- length += m_protoParam.GetObjectLength();
- if (HasOptionalField(e_commonParam))
- length += m_commonParam.GetObjectLength();
- return length;
-}
-
-
-BOOL CISCO_H225_H323_UU_NonStdInfo::Decode(PASN_Stream & strm)
-{
- if (!PreambleDecode(strm))
- return FALSE;
-
- if (HasOptionalField(e_version) && !m_version.Decode(strm))
- return FALSE;
- if (HasOptionalField(e_protoParam) && !m_protoParam.Decode(strm))
- return FALSE;
- if (HasOptionalField(e_commonParam) && !m_commonParam.Decode(strm))
- return FALSE;
- if (!KnownExtensionDecode(strm, e_dummy1, m_dummy1))
- return FALSE;
- if (!KnownExtensionDecode(strm, e_progIndParam, m_progIndParam))
- return FALSE;
- if (!KnownExtensionDecode(strm, e_callMgrParam, m_callMgrParam))
- return FALSE;
- if (!KnownExtensionDecode(strm, e_callSignallingParam, m_callSignallingParam))
- return FALSE;
- if (!KnownExtensionDecode(strm, e_dummy2, m_dummy2))
- return FALSE;
- if (!KnownExtensionDecode(strm, e_callPreserveParam, m_callPreserveParam))
- return FALSE;
-
- return UnknownExtensionsDecode(strm);
-}
-
-
-void CISCO_H225_H323_UU_NonStdInfo::Encode(PASN_Stream & strm) const
-{
- PreambleEncode(strm);
-
- if (HasOptionalField(e_version))
- m_version.Encode(strm);
- if (HasOptionalField(e_protoParam))
- m_protoParam.Encode(strm);
- if (HasOptionalField(e_commonParam))
- m_commonParam.Encode(strm);
- KnownExtensionEncode(strm, e_dummy1, m_dummy1);
- KnownExtensionEncode(strm, e_progIndParam, m_progIndParam);
- KnownExtensionEncode(strm, e_callMgrParam, m_callMgrParam);
- KnownExtensionEncode(strm, e_callSignallingParam, m_callSignallingParam);
- KnownExtensionEncode(strm, e_dummy2, m_dummy2);
- KnownExtensionEncode(strm, e_callPreserveParam, m_callPreserveParam);
-
- UnknownExtensionsEncode(strm);
-}
-
-
-PObject * CISCO_H225_H323_UU_NonStdInfo::Clone() const
-{
-#ifndef PASN_LEANANDMEAN
- PAssert(IsClass(CISCO_H225_H323_UU_NonStdInfo::Class()), PInvalidCast);
-#endif
- return new CISCO_H225_H323_UU_NonStdInfo(*this);
-}
-
-
-#endif // if ! H323_DISABLE_CISCO_H225
-
-
-// End of cisco-h225.cxx
diff --git a/1.4/channels/h323/cisco-h225.h b/1.4/channels/h323/cisco-h225.h
deleted file mode 100644
index 7595b4b65..000000000
--- a/1.4/channels/h323/cisco-h225.h
+++ /dev/null
@@ -1,299 +0,0 @@
-//
-// cisco-h225.h
-//
-// Code automatically generated by asnparse.
-//
-
-#if ! H323_DISABLE_CISCO_H225
-
-#ifndef __CISCO_H225_H
-#define __CISCO_H225_H
-
-#ifdef P_USE_PRAGMA
-#pragma interface
-#endif
-
-#include <ptclib/asner.h>
-
-//
-// RedirectIEinfo
-//
-
-class CISCO_H225_RedirectIEinfo : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_RedirectIEinfo, PASN_Sequence);
-#endif
- public:
- CISCO_H225_RedirectIEinfo(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- PASN_OctetString m_redirectIE;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// ProgIndIEinfo
-//
-
-class CISCO_H225_ProgIndIEinfo : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_ProgIndIEinfo, PASN_Sequence);
-#endif
- public:
- CISCO_H225_ProgIndIEinfo(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- PASN_OctetString m_progIndIE;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// QsigNonStdInfo
-//
-
-class CISCO_H225_QsigNonStdInfo : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_QsigNonStdInfo, PASN_Sequence);
-#endif
- public:
- CISCO_H225_QsigNonStdInfo(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- PASN_Integer m_iei;
- PASN_OctetString m_rawMesg;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// CallMgrParam
-//
-
-class CISCO_H225_CallMgrParam : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_CallMgrParam, PASN_Sequence);
-#endif
- public:
- CISCO_H225_CallMgrParam(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- PASN_Integer m_interclusterVersion;
- PASN_OctetString m_enterpriseID;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// CallPreserveParam
-//
-
-class CISCO_H225_CallPreserveParam : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_CallPreserveParam, PASN_Sequence);
-#endif
- public:
- CISCO_H225_CallPreserveParam(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- PASN_Boolean m_callPreserveIE;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// CallSignallingParam
-//
-
-class CISCO_H225_CallSignallingParam : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_CallSignallingParam, PASN_Sequence);
-#endif
- public:
- CISCO_H225_CallSignallingParam(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- enum OptionalFields {
- e_connectedNumber
- };
-
- PASN_OctetString m_connectedNumber;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// CommonParam
-//
-
-class CISCO_H225_CommonParam : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_CommonParam, PASN_Sequence);
-#endif
- public:
- CISCO_H225_CommonParam(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- CISCO_H225_RedirectIEinfo m_redirectIEinfo;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// ProgIndParam
-//
-
-class CISCO_H225_ProgIndParam : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_ProgIndParam, PASN_Sequence);
-#endif
- public:
- CISCO_H225_ProgIndParam(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- CISCO_H225_ProgIndIEinfo m_progIndIEinfo;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// ProtoParam
-//
-
-class CISCO_H225_ProtoParam : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_ProtoParam, PASN_Sequence);
-#endif
- public:
- CISCO_H225_ProtoParam(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- CISCO_H225_QsigNonStdInfo m_qsigNonStdInfo;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-//
-// H323_UU_NonStdInfo
-//
-
-class CISCO_H225_H323_UU_NonStdInfo : public PASN_Sequence
-{
-#ifndef PASN_LEANANDMEAN
- PCLASSINFO(CISCO_H225_H323_UU_NonStdInfo, PASN_Sequence);
-#endif
- public:
- CISCO_H225_H323_UU_NonStdInfo(unsigned tag = UniversalSequence, TagClass tagClass = UniversalTagClass);
-
- enum OptionalFields {
- e_version,
- e_protoParam,
- e_commonParam,
- e_dummy1,
- e_progIndParam,
- e_callMgrParam,
- e_callSignallingParam,
- e_dummy2,
- e_callPreserveParam
- };
-
- PASN_Integer m_version;
- CISCO_H225_ProtoParam m_protoParam;
- CISCO_H225_CommonParam m_commonParam;
- PASN_OctetString m_dummy1;
- CISCO_H225_ProgIndParam m_progIndParam;
- CISCO_H225_CallMgrParam m_callMgrParam;
- CISCO_H225_CallSignallingParam m_callSignallingParam;
- PASN_OctetString m_dummy2;
- CISCO_H225_CallPreserveParam m_callPreserveParam;
-
- PINDEX GetDataLength() const;
- BOOL Decode(PASN_Stream & strm);
- void Encode(PASN_Stream & strm) const;
-#ifndef PASN_NOPRINTON
- void PrintOn(ostream & strm) const;
-#endif
- Comparison Compare(const PObject & obj) const;
- PObject * Clone() const;
-};
-
-
-#endif // __CISCO_H225_H
-
-#endif // if ! H323_DISABLE_CISCO_H225
-
-
-// End of cisco-h225.h
diff --git a/1.4/channels/h323/compat_h323.cxx b/1.4/channels/h323/compat_h323.cxx
deleted file mode 100644
index eec7361b2..000000000
--- a/1.4/channels/h323/compat_h323.cxx
+++ /dev/null
@@ -1,138 +0,0 @@
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-/*
- * ast_h323.cpp
- *
- * OpenH323 Channel Driver for ASTERISK PBX.
- * By Jeremy McNamara
- * For The NuFone Network
- *
- * chan_h323 has been derived from code created by
- * Michael Manousos and Mark Spencer
- *
- * This file is part of the chan_h323 driver for Asterisk
- *
- * chan_h323 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * chan_h323 is distributed WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Version Info: $Id$
- */
-#include <ptlib.h>
-#include <h323.h>
-#include <transports.h>
-
-#include "ast_h323.h"
-
-#if VERSION(OPENH323_MAJOR,OPENH323_MINOR,OPENH323_BUILD) < VERSION(1,17,3)
-MyH323TransportTCP::MyH323TransportTCP(
- H323EndPoint & endpoint,
- PIPSocket::Address binding,
- BOOL listen)
- : H323TransportTCP(endpoint, binding, listen)
-{
-}
-
-BOOL MyH323TransportTCP::Connect()
-{
- if (IsListening())
- return TRUE;
-
- PTCPSocket * socket = new PTCPSocket(remotePort);
- Open(socket);
-
- channelPointerMutex.StartRead();
-
- socket->SetReadTimeout(10000/*endpoint.GetSignallingChannelConnectTimeout()*/);
-
- localPort = endpoint.GetNextTCPPort();
- WORD firstPort = localPort;
- for (;;) {
- PTRACE(4, "H323TCP\tConnecting to "
- << remoteAddress << ':' << remotePort
- << " (local port=" << localPort << ')');
- if (socket->Connect(localAddress, localPort, remoteAddress))
- break;
-
- int errnum = socket->GetErrorNumber();
- if (localPort == 0 || (errnum != EADDRINUSE && errnum != EADDRNOTAVAIL)) {
- PTRACE(1, "H323TCP\tCould not connect to "
- << remoteAddress << ':' << remotePort
- << " (local port=" << localPort << ") - "
- << socket->GetErrorText() << '(' << errnum << ')');
- channelPointerMutex.EndRead();
- return SetErrorValues(socket->GetErrorCode(), errnum);
- }
-
- localPort = endpoint.GetNextTCPPort();
- if (localPort == firstPort) {
- PTRACE(1, "H323TCP\tCould not bind to any port in range " <<
- endpoint.GetTCPPortBase() << " to " << endpoint.GetTCPPortMax());
- channelPointerMutex.EndRead();
- return SetErrorValues(socket->GetErrorCode(), errnum);
- }
- }
-
- socket->SetReadTimeout(PMaxTimeInterval);
-
- channelPointerMutex.EndRead();
-
- return OnOpen();
-}
-#endif
-
-BOOL MyH323TransportUDP::DiscoverGatekeeper(H323Gatekeeper &gk, H323RasPDU &pdu, const H323TransportAddress &address)
-{
- PThread *thd = PThread::Current();
-
- /* If we run in OpenH323's thread use it instead of creating new one */
- if (thd)
- return H323TransportUDP::DiscoverGatekeeper(gk, pdu, address);
-
- /* Make copy of arguments to pass them into thread */
- discoverGatekeeper = &gk;
- discoverPDU = &pdu;
- discoverAddress = &address;
-
- /* Assume discovery thread isn't finished */
- discoverReady = FALSE;
-
- /* Create discovery thread */
- thd = PThread::Create(PCREATE_NOTIFIER(DiscoverMain), 0,
- PThread::NoAutoDeleteThread,
- PThread::NormalPriority,
- "GkDiscovery:%x");
-
- /* Wait until discovery thread signal us its finished */
- for(;;) {
- discoverMutex.Wait();
- if (discoverReady) /* Thread has been finished */
- break;
- discoverMutex.Signal();
- }
- discoverMutex.Signal();
-
- /* Cleanup/delete thread */
- thd->WaitForTermination();
- delete thd;
-
- return discoverResult;
-}
-
-void MyH323TransportUDP::DiscoverMain(PThread &thread, INT arg)
-{
- PWaitAndSignal m(discoverMutex);
-
- discoverResult = H323TransportUDP::DiscoverGatekeeper(*discoverGatekeeper, *discoverPDU, *discoverAddress);
- discoverReady = TRUE;
-}
diff --git a/1.4/channels/h323/compat_h323.h b/1.4/channels/h323/compat_h323.h
deleted file mode 100644
index 63da8ac8c..000000000
--- a/1.4/channels/h323/compat_h323.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef COMPAT_H323_H
-#define COMPAT_H323_H
-
-#if VERSION(OPENH323_MAJOR,OPENH323_MINOR,OPENH323_BUILD) < VERSION(1,17,3)
-/**
- * Workaround for broken (less than 1.17.3) OpenH323 stack to be able to
- * make TCP connections from specific address
- */
-class MyH323TransportTCP : public H323TransportTCP
-{
- PCLASSINFO(MyH323TransportTCP, H323TransportTCP);
-
-public:
- MyH323TransportTCP(
- H323EndPoint & endpoint, ///< H323 End Point object
- PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), ///< Local interface to use
- BOOL listen = FALSE ///< Flag for need to wait for remote to connect
- );
- /**Connect to the remote party.
- */
- virtual BOOL Connect();
-};
-#else
-#define MyH323TransportTCP H323TransportTCP
-#endif /* <VERSION(1,17,3) */
-
-class MyH323TransportUDP: public H323TransportUDP
-{
- PCLASSINFO(MyH323TransportUDP, H323TransportUDP);
-
-public:
- MyH323TransportUDP(H323EndPoint &endpoint,
- PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
- WORD localPort = 0,
- WORD remotePort = 0): H323TransportUDP(endpoint, binding, localPort, remotePort)
- {
- }
- virtual BOOL DiscoverGatekeeper(H323Gatekeeper &,
- H323RasPDU &,
- const H323TransportAddress &);
-protected:
- PDECLARE_NOTIFIER(PThread, MyH323TransportUDP, DiscoverMain);
- H323Gatekeeper *discoverGatekeeper;
- H323RasPDU *discoverPDU;
- const H323TransportAddress *discoverAddress;
- BOOL discoverResult;
- BOOL discoverReady;
- PMutex discoverMutex;
-};
-
-template <class _Abstract_T, typename _Key_T = PString>
-class MyPFactory: public PFactory<_Abstract_T, _Key_T>
-{
-public:
- template <class _Concrete_T> class Worker: public PFactory<_Abstract_T, _Key_T>::WorkerBase
- {
- public:
- Worker(const _Key_T &_key, bool singleton = false)
- :PFactory<_Abstract_T, _Key_T>::WorkerBase(singleton), key(_key)
- {
- PFactory<_Abstract_T, _Key_T>::Register(key, this);
- }
- ~Worker()
- {
- PFactory<_Abstract_T, _Key_T>::Unregister(key);
- }
- protected:
- virtual _Abstract_T *Create(const _Key_T &) const { return new _Concrete_T; }
-
- private:
- PString key;
- };
-};
-
-#ifdef H323_REGISTER_CAPABILITY
-#undef H323_REGISTER_CAPABILITY
-#endif
-#define H323_REGISTER_CAPABILITY(cls, capName) static MyPFactory<H323Capability>::Worker<cls> cls##Factory(capName, true)
-
-#endif /* !defined AST_H323_H */
diff --git a/1.4/channels/h323/noexport.map b/1.4/channels/h323/noexport.map
deleted file mode 100644
index b51f84263..000000000
--- a/1.4/channels/h323/noexport.map
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- global:
- _Z11PAssertFuncPKc;
- local: *;
-}; \ No newline at end of file
diff --git a/1.4/channels/iax2-parser.c b/1.4/channels/iax2-parser.c
deleted file mode 100644
index f9c3714db..000000000
--- a/1.4/channels/iax2-parser.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Implementation of Inter-Asterisk eXchange Protocol, v 2
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/utils.h"
-#include "asterisk/unaligned.h"
-#include "asterisk/lock.h"
-#include "asterisk/threadstorage.h"
-
-#include "iax2.h"
-#include "iax2-parser.h"
-#include "iax2-provision.h"
-
-static int frames = 0;
-static int iframes = 0;
-static int oframes = 0;
-
-#if !defined(LOW_MEMORY)
-static void frame_cache_cleanup(void *data);
-
-/*! \brief A per-thread cache of iax_frame structures */
-AST_THREADSTORAGE_CUSTOM(frame_cache, frame_cache_init, frame_cache_cleanup);
-
-/*! \brief This is just so iax_frames, a list head struct for holding a list of
- * iax_frame structures, is defined. */
-AST_LIST_HEAD_NOLOCK(iax_frames, iax_frame);
-#endif
-
-static void internaloutput(const char *str)
-{
- fputs(str, stdout);
-}
-
-static void internalerror(const char *str)
-{
- fprintf(stderr, "WARNING: %s", str);
-}
-
-static void (*outputf)(const char *str) = internaloutput;
-static void (*errorf)(const char *str) = internalerror;
-
-static void dump_addr(char *output, int maxlen, void *value, int len)
-{
- struct sockaddr_in sin;
- if (len == (int)sizeof(sin)) {
- memcpy(&sin, value, len);
- snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- } else {
- snprintf(output, maxlen, "Invalid Address");
- }
-}
-
-static void dump_string(char *output, int maxlen, void *value, int len)
-{
- maxlen--;
- if (maxlen > len)
- maxlen = len;
- strncpy(output, value, maxlen);
- output[maxlen] = '\0';
-}
-
-static void dump_prefs(char *output, int maxlen, void *value, int len)
-{
- struct ast_codec_pref pref;
- int total_len = 0;
-
- maxlen--;
- total_len = maxlen;
-
- if (maxlen > len)
- maxlen = len;
-
- strncpy(output, value, maxlen);
- output[maxlen] = '\0';
-
- ast_codec_pref_convert(&pref, output, total_len, 0);
- memset(output,0,total_len);
- ast_codec_pref_string(&pref, output, total_len);
-}
-
-static void dump_int(char *output, int maxlen, void *value, int len)
-{
- if (len == (int)sizeof(unsigned int))
- snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
- else
- ast_copy_string(output, "Invalid INT", maxlen);
-}
-
-static void dump_short(char *output, int maxlen, void *value, int len)
-{
- if (len == (int)sizeof(unsigned short))
- snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
- else
- ast_copy_string(output, "Invalid SHORT", maxlen);
-}
-
-static void dump_byte(char *output, int maxlen, void *value, int len)
-{
- if (len == (int)sizeof(unsigned char))
- snprintf(output, maxlen, "%d", *((unsigned char *)value));
- else
- ast_copy_string(output, "Invalid BYTE", maxlen);
-}
-
-static void dump_datetime(char *output, int maxlen, void *value, int len)
-{
- struct tm tm;
- unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value));
- if (len == (int)sizeof(unsigned int)) {
- tm.tm_sec = (val & 0x1f) << 1;
- tm.tm_min = (val >> 5) & 0x3f;
- tm.tm_hour = (val >> 11) & 0x1f;
- tm.tm_mday = (val >> 16) & 0x1f;
- tm.tm_mon = ((val >> 21) & 0x0f) - 1;
- tm.tm_year = ((val >> 25) & 0x7f) + 100;
- strftime(output, maxlen, "%Y-%m-%d %T", &tm);
- } else
- ast_copy_string(output, "Invalid DATETIME format!", maxlen);
-}
-
-static void dump_ipaddr(char *output, int maxlen, void *value, int len)
-{
- struct sockaddr_in sin;
- if (len == (int)sizeof(unsigned int)) {
- memcpy(&sin.sin_addr, value, len);
- snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr));
- } else
- ast_copy_string(output, "Invalid IPADDR", maxlen);
-}
-
-
-static void dump_prov_flags(char *output, int maxlen, void *value, int len)
-{
- char buf[256] = "";
- if (len == (int)sizeof(unsigned int))
- snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)),
- iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value))));
- else
- ast_copy_string(output, "Invalid INT", maxlen);
-}
-
-static void dump_samprate(char *output, int maxlen, void *value, int len)
-{
- char tmp[256]="";
- int sr;
- if (len == (int)sizeof(unsigned short)) {
- sr = ntohs(*((unsigned short *)value));
- if (sr & IAX_RATE_8KHZ)
- strcat(tmp, ",8khz");
- if (sr & IAX_RATE_11KHZ)
- strcat(tmp, ",11.025khz");
- if (sr & IAX_RATE_16KHZ)
- strcat(tmp, ",16khz");
- if (sr & IAX_RATE_22KHZ)
- strcat(tmp, ",22.05khz");
- if (sr & IAX_RATE_44KHZ)
- strcat(tmp, ",44.1khz");
- if (sr & IAX_RATE_48KHZ)
- strcat(tmp, ",48khz");
- if (strlen(tmp))
- ast_copy_string(output, &tmp[1], maxlen);
- else
- ast_copy_string(output, "None Specified!\n", maxlen);
- } else
- ast_copy_string(output, "Invalid SHORT", maxlen);
-
-}
-
-static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len);
-static void dump_prov(char *output, int maxlen, void *value, int len)
-{
- dump_prov_ies(output, maxlen, value, len);
-}
-
-static struct iax2_ie {
- int ie;
- char *name;
- void (*dump)(char *output, int maxlen, void *value, int len);
-} ies[] = {
- { IAX_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string },
- { IAX_IE_CALLING_NUMBER, "CALLING NUMBER", dump_string },
- { IAX_IE_CALLING_ANI, "ANI", dump_string },
- { IAX_IE_CALLING_NAME, "CALLING NAME", dump_string },
- { IAX_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string },
- { IAX_IE_USERNAME, "USERNAME", dump_string },
- { IAX_IE_PASSWORD, "PASSWORD", dump_string },
- { IAX_IE_CAPABILITY, "CAPABILITY", dump_int },
- { IAX_IE_FORMAT, "FORMAT", dump_int },
- { IAX_IE_LANGUAGE, "LANGUAGE", dump_string },
- { IAX_IE_VERSION, "VERSION", dump_short },
- { IAX_IE_ADSICPE, "ADSICPE", dump_short },
- { IAX_IE_DNID, "DNID", dump_string },
- { IAX_IE_AUTHMETHODS, "AUTHMETHODS", dump_short },
- { IAX_IE_CHALLENGE, "CHALLENGE", dump_string },
- { IAX_IE_MD5_RESULT, "MD5 RESULT", dump_string },
- { IAX_IE_RSA_RESULT, "RSA RESULT", dump_string },
- { IAX_IE_APPARENT_ADDR, "APPARENT ADDRESS", dump_addr },
- { IAX_IE_REFRESH, "REFRESH", dump_short },
- { IAX_IE_DPSTATUS, "DIALPLAN STATUS", dump_short },
- { IAX_IE_CALLNO, "CALL NUMBER", dump_short },
- { IAX_IE_CAUSE, "CAUSE", dump_string },
- { IAX_IE_IAX_UNKNOWN, "UNKNOWN IAX CMD", dump_byte },
- { IAX_IE_MSGCOUNT, "MESSAGE COUNT", dump_short },
- { IAX_IE_AUTOANSWER, "AUTO ANSWER REQ" },
- { IAX_IE_TRANSFERID, "TRANSFER ID", dump_int },
- { IAX_IE_RDNIS, "REFERRING DNIS", dump_string },
- { IAX_IE_PROVISIONING, "PROVISIONING", dump_prov },
- { IAX_IE_AESPROVISIONING, "AES PROVISIONG" },
- { IAX_IE_DATETIME, "DATE TIME", dump_datetime },
- { IAX_IE_DEVICETYPE, "DEVICE TYPE", dump_string },
- { IAX_IE_SERVICEIDENT, "SERVICE IDENT", dump_string },
- { IAX_IE_FIRMWAREVER, "FIRMWARE VER", dump_short },
- { IAX_IE_FWBLOCKDESC, "FW BLOCK DESC", dump_int },
- { IAX_IE_FWBLOCKDATA, "FW BLOCK DATA" },
- { IAX_IE_PROVVER, "PROVISIONG VER", dump_int },
- { IAX_IE_CALLINGPRES, "CALLING PRESNTN", dump_byte },
- { IAX_IE_CALLINGTON, "CALLING TYPEOFNUM", dump_byte },
- { IAX_IE_CALLINGTNS, "CALLING TRANSITNET", dump_short },
- { IAX_IE_SAMPLINGRATE, "SAMPLINGRATE", dump_samprate },
- { IAX_IE_CAUSECODE, "CAUSE CODE", dump_byte },
- { IAX_IE_ENCRYPTION, "ENCRYPTION", dump_short },
- { IAX_IE_ENCKEY, "ENCRYPTION KEY" },
- { IAX_IE_CODEC_PREFS, "CODEC_PREFS", dump_prefs },
- { IAX_IE_RR_JITTER, "RR_JITTER", dump_int },
- { IAX_IE_RR_LOSS, "RR_LOSS", dump_int },
- { IAX_IE_RR_PKTS, "RR_PKTS", dump_int },
- { IAX_IE_RR_DELAY, "RR_DELAY", dump_short },
- { IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int },
- { IAX_IE_RR_OOO, "RR_OUTOFORDER", dump_int },
-};
-
-static struct iax2_ie prov_ies[] = {
- { PROV_IE_USEDHCP, "USEDHCP" },
- { PROV_IE_IPADDR, "IPADDR", dump_ipaddr },
- { PROV_IE_SUBNET, "SUBNET", dump_ipaddr },
- { PROV_IE_GATEWAY, "GATEWAY", dump_ipaddr },
- { PROV_IE_PORTNO, "BINDPORT", dump_short },
- { PROV_IE_USER, "USERNAME", dump_string },
- { PROV_IE_PASS, "PASSWORD", dump_string },
- { PROV_IE_LANG, "LANGUAGE", dump_string },
- { PROV_IE_TOS, "TYPEOFSERVICE", dump_byte },
- { PROV_IE_FLAGS, "FLAGS", dump_prov_flags },
- { PROV_IE_FORMAT, "FORMAT", dump_int },
- { PROV_IE_AESKEY, "AESKEY" },
- { PROV_IE_SERVERIP, "SERVERIP", dump_ipaddr },
- { PROV_IE_SERVERPORT, "SERVERPORT", dump_short },
- { PROV_IE_NEWAESKEY, "NEWAESKEY" },
- { PROV_IE_PROVVER, "PROV VERSION", dump_int },
- { PROV_IE_ALTSERVER, "ALTSERVERIP", dump_ipaddr },
-};
-
-const char *iax_ie2str(int ie)
-{
- int x;
- for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
- if (ies[x].ie == ie)
- return ies[x].name;
- }
- return "Unknown IE";
-}
-
-
-static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len)
-{
- int ielen;
- int ie;
- int x;
- int found;
- char interp[80];
- char tmp[256];
- if (len < 2)
- return;
- strcpy(output, "\n");
- maxlen -= strlen(output); output += strlen(output);
- while(len > 2) {
- ie = iedata[0];
- ielen = iedata[1];
- if (ielen + 2> len) {
- snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len);
- ast_copy_string(output, tmp, maxlen);
- maxlen -= strlen(output);
- output += strlen(output);
- return;
- }
- found = 0;
- for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) {
- if (prov_ies[x].ie == ie) {
- if (prov_ies[x].dump) {
- prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
- snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp);
- ast_copy_string(output, tmp, maxlen);
- maxlen -= strlen(output); output += strlen(output);
- } else {
- if (ielen)
- snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
- else
- strcpy(interp, "Present");
- snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp);
- ast_copy_string(output, tmp, maxlen);
- maxlen -= strlen(output); output += strlen(output);
- }
- found++;
- }
- }
- if (!found) {
- snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie);
- ast_copy_string(output, tmp, maxlen);
- maxlen -= strlen(output); output += strlen(output);
- }
- iedata += (2 + ielen);
- len -= (2 + ielen);
- }
-}
-
-static void dump_ies(unsigned char *iedata, int len)
-{
- int ielen;
- int ie;
- int x;
- int found;
- char interp[1024];
- char tmp[1024];
- if (len < 2)
- return;
- while(len > 2) {
- ie = iedata[0];
- ielen = iedata[1];
- if (ielen + 2> len) {
- snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
- outputf(tmp);
- return;
- }
- found = 0;
- for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
- if (ies[x].ie == ie) {
- if (ies[x].dump) {
- ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
- snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp);
- outputf(tmp);
- } else {
- if (ielen)
- snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
- else
- strcpy(interp, "Present");
- snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp);
- outputf(tmp);
- }
- found++;
- }
- }
- if (!found) {
- snprintf(tmp, (int)sizeof(tmp), " Unknown IE %03d : Present\n", ie);
- outputf(tmp);
- }
- iedata += (2 + ielen);
- len -= (2 + ielen);
- }
- outputf("\n");
-}
-
-void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
-{
- const char *frames[] = {
- "(0?)",
- "DTMF_E ",
- "VOICE ",
- "VIDEO ",
- "CONTROL",
- "NULL ",
- "IAX ",
- "TEXT ",
- "IMAGE ",
- "HTML ",
- "CNG ",
- "MODEM ",
- "DTMF_B ",
- };
- const char *iaxs[] = {
- "(0?)",
- "NEW ",
- "PING ",
- "PONG ",
- "ACK ",
- "HANGUP ",
- "REJECT ",
- "ACCEPT ",
- "AUTHREQ",
- "AUTHREP",
- "INVAL ",
- "LAGRQ ",
- "LAGRP ",
- "REGREQ ",
- "REGAUTH",
- "REGACK ",
- "REGREJ ",
- "REGREL ",
- "VNAK ",
- "DPREQ ",
- "DPREP ",
- "DIAL ",
- "TXREQ ",
- "TXCNT ",
- "TXACC ",
- "TXREADY",
- "TXREL ",
- "TXREJ ",
- "QUELCH ",
- "UNQULCH",
- "POKE ",
- "PAGE ",
- "MWI ",
- "UNSPRTD",
- "TRANSFR",
- "PROVISN",
- "FWDWNLD",
- "FWDATA ",
- "TXMEDIA"
- };
- const char *cmds[] = {
- "(0?)",
- "HANGUP ",
- "RING ",
- "RINGING",
- "ANSWER ",
- "BUSY ",
- "TKOFFHK",
- "OFFHOOK",
- "CONGSTN",
- "FLASH ",
- "WINK ",
- "OPTION ",
- "RDKEY ",
- "RDUNKEY",
- "PROGRES",
- "PROCDNG",
- "HOLD ",
- "UNHOLD ",
- "VIDUPDT", };
- struct ast_iax2_full_hdr *fh;
- char retries[20];
- char class2[20];
- char subclass2[20];
- const char *class;
- const char *subclass;
- char *dir;
- char tmp[512];
-
- switch(rx) {
- case 0:
- dir = "Tx";
- break;
- case 2:
- dir = "TE";
- break;
- case 3:
- dir = "RD";
- break;
- default:
- dir = "Rx";
- break;
- }
- if (f) {
- fh = f->data;
- snprintf(retries, sizeof(retries), "%03d", f->retries);
- } else {
- fh = fhi;
- if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
- strcpy(retries, "Yes");
- else
- strcpy(retries, " No");
- }
- if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
- /* Don't mess with mini-frames */
- return;
- }
- if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) {
- snprintf(class2, sizeof(class2), "(%d?)", fh->type);
- class = class2;
- } else {
- class = frames[(int)fh->type];
- }
- if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) {
- sprintf(subclass2, "%c", fh->csub);
- subclass = subclass2;
- } else if (fh->type == AST_FRAME_IAX) {
- if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
- snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
- subclass = subclass2;
- } else {
- subclass = iaxs[(int)fh->csub];
- }
- } else if (fh->type == AST_FRAME_CONTROL) {
- if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) {
- snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
- subclass = subclass2;
- } else {
- subclass = cmds[(int)fh->csub];
- }
- } else {
- snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
- subclass = subclass2;
- }
- snprintf(tmp, sizeof(tmp),
- "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
- dir,
- retries, fh->oseqno, fh->iseqno, class, subclass);
- outputf(tmp);
- snprintf(tmp, sizeof(tmp),
- " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n",
- (unsigned long)ntohl(fh->ts),
- ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
- outputf(tmp);
- if (fh->type == AST_FRAME_IAX)
- dump_ies(fh->iedata, datalen);
-}
-
-int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
-{
- char tmp[256];
- if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
- snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", iax_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
- errorf(tmp);
- return -1;
- }
- ied->buf[ied->pos++] = ie;
- ied->buf[ied->pos++] = datalen;
- memcpy(ied->buf + ied->pos, data, datalen);
- ied->pos += datalen;
- return 0;
-}
-
-int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, const struct sockaddr_in *sin)
-{
- return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
-}
-
-int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value)
-{
- unsigned int newval;
- newval = htonl(value);
- return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
-}
-
-int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value)
-{
- unsigned short newval;
- newval = htons(value);
- return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
-}
-
-int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str)
-{
- return iax_ie_append_raw(ied, ie, str, strlen(str));
-}
-
-int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
-{
- return iax_ie_append_raw(ied, ie, &dat, 1);
-}
-
-int iax_ie_append(struct iax_ie_data *ied, unsigned char ie)
-{
- return iax_ie_append_raw(ied, ie, NULL, 0);
-}
-
-void iax_set_output(void (*func)(const char *))
-{
- outputf = func;
-}
-
-void iax_set_error(void (*func)(const char *))
-{
- errorf = func;
-}
-
-int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
-{
- /* Parse data into information elements */
- int len;
- int ie;
- char tmp[256];
- memset(ies, 0, (int)sizeof(struct iax_ies));
- ies->msgcount = -1;
- ies->firmwarever = -1;
- ies->calling_ton = -1;
- ies->calling_tns = -1;
- ies->calling_pres = -1;
- ies->samprate = IAX_RATE_8KHZ;
- while(datalen >= 2) {
- ie = data[0];
- len = data[1];
- if (len > datalen - 2) {
- errorf("Information element length exceeds message size\n");
- return -1;
- }
- switch(ie) {
- case IAX_IE_CALLED_NUMBER:
- ies->called_number = (char *)data + 2;
- break;
- case IAX_IE_CALLING_NUMBER:
- ies->calling_number = (char *)data + 2;
- break;
- case IAX_IE_CALLING_ANI:
- ies->calling_ani = (char *)data + 2;
- break;
- case IAX_IE_CALLING_NAME:
- ies->calling_name = (char *)data + 2;
- break;
- case IAX_IE_CALLED_CONTEXT:
- ies->called_context = (char *)data + 2;
- break;
- case IAX_IE_USERNAME:
- ies->username = (char *)data + 2;
- break;
- case IAX_IE_PASSWORD:
- ies->password = (char *)data + 2;
- break;
- case IAX_IE_CODEC_PREFS:
- ies->codec_prefs = (char *)data + 2;
- break;
- case IAX_IE_CAPABILITY:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else
- ies->capability = ntohl(get_unaligned_uint32(data + 2));
- break;
- case IAX_IE_FORMAT:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else
- ies->format = ntohl(get_unaligned_uint32(data + 2));
- break;
- case IAX_IE_LANGUAGE:
- ies->language = (char *)data + 2;
- break;
- case IAX_IE_VERSION:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->version = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_ADSICPE:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_SAMPLINGRATE:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->samprate = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_DNID:
- ies->dnid = (char *)data + 2;
- break;
- case IAX_IE_RDNIS:
- ies->rdnis = (char *)data + 2;
- break;
- case IAX_IE_AUTHMETHODS:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_ENCRYPTION:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_CHALLENGE:
- ies->challenge = (char *)data + 2;
- break;
- case IAX_IE_MD5_RESULT:
- ies->md5_result = (char *)data + 2;
- break;
- case IAX_IE_RSA_RESULT:
- ies->rsa_result = (char *)data + 2;
- break;
- case IAX_IE_APPARENT_ADDR:
- ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
- break;
- case IAX_IE_REFRESH:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->refresh = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_DPSTATUS:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_CALLNO:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->callno = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_CAUSE:
- ies->cause = (char *)data + 2;
- break;
- case IAX_IE_CAUSECODE:
- if (len != 1) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
- errorf(tmp);
- } else {
- ies->causecode = data[2];
- }
- break;
- case IAX_IE_IAX_UNKNOWN:
- if (len == 1)
- ies->iax_unknown = data[2];
- else {
- snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
- errorf(tmp);
- }
- break;
- case IAX_IE_MSGCOUNT:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->msgcount = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_AUTOANSWER:
- ies->autoanswer = 1;
- break;
- case IAX_IE_MUSICONHOLD:
- ies->musiconhold = 1;
- break;
- case IAX_IE_TRANSFERID:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else
- ies->transferid = ntohl(get_unaligned_uint32(data + 2));
- break;
- case IAX_IE_DATETIME:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else
- ies->datetime = ntohl(get_unaligned_uint32(data + 2));
- break;
- case IAX_IE_FIRMWAREVER:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_DEVICETYPE:
- ies->devicetype = (char *)data + 2;
- break;
- case IAX_IE_SERVICEIDENT:
- ies->serviceident = (char *)data + 2;
- break;
- case IAX_IE_FWBLOCKDESC:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else
- ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
- break;
- case IAX_IE_FWBLOCKDATA:
- ies->fwdata = data + 2;
- ies->fwdatalen = len;
- break;
- case IAX_IE_ENCKEY:
- ies->enckey = data + 2;
- ies->enckeylen = len;
- break;
- case IAX_IE_PROVVER:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else {
- ies->provverpres = 1;
- ies->provver = ntohl(get_unaligned_uint32(data + 2));
- }
- break;
- case IAX_IE_CALLINGPRES:
- if (len == 1)
- ies->calling_pres = data[2];
- else {
- snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
- errorf(tmp);
- }
- break;
- case IAX_IE_CALLINGTON:
- if (len == 1)
- ies->calling_ton = data[2];
- else {
- snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
- errorf(tmp);
- }
- break;
- case IAX_IE_CALLINGTNS:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));
- break;
- case IAX_IE_RR_JITTER:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else {
- ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
- }
- break;
- case IAX_IE_RR_LOSS:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else {
- ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
- }
- break;
- case IAX_IE_RR_PKTS:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else {
- ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
- }
- break;
- case IAX_IE_RR_DELAY:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else {
- ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
- }
- break;
- case IAX_IE_RR_DROPPED:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else {
- ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
- }
- break;
- case IAX_IE_RR_OOO:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else {
- ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
- }
- break;
- default:
- snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
- outputf(tmp);
- }
- /* Overwrite information element with 0, to null terminate previous portion */
- data[0] = 0;
- datalen -= (len + 2);
- data += (len + 2);
- }
- /* Null-terminate last field */
- *data = '\0';
- if (datalen) {
- errorf("Invalid information element contents, strange boundary\n");
- return -1;
- }
- return 0;
-}
-
-void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
-{
- fr->af.frametype = f->frametype;
- fr->af.subclass = f->subclass;
- fr->af.mallocd = 0; /* Our frame is static relative to the container */
- fr->af.datalen = f->datalen;
- fr->af.samples = f->samples;
- fr->af.offset = AST_FRIENDLY_OFFSET;
- fr->af.src = f->src;
- fr->af.delivery.tv_sec = 0;
- fr->af.delivery.tv_usec = 0;
- fr->af.data = fr->afdata;
- fr->af.len = f->len;
- if (fr->af.datalen) {
- size_t copy_len = fr->af.datalen;
- if (copy_len > fr->afdatalen) {
- ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
- (int) fr->afdatalen, (int) fr->af.datalen);
- copy_len = fr->afdatalen;
- }
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- /* We need to byte-swap slinear samples from network byte order */
- if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
- /* 2 bytes / sample for SLINEAR */
- ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
- } else
-#endif
- memcpy(fr->af.data, f->data, copy_len);
- }
-}
-
-struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheable)
-{
- struct iax_frame *fr = NULL;
-
-#if !defined(LOW_MEMORY)
- struct iax_frames *iax_frames;
-
- /* Attempt to get a frame from this thread's cache */
- if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
- AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
- if (fr->afdatalen >= datalen) {
- size_t afdatalen = fr->afdatalen;
- AST_LIST_REMOVE_CURRENT(iax_frames, list);
- memset(fr, 0, sizeof(*fr));
- fr->afdatalen = afdatalen;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- }
- if (!fr) {
- if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
- return NULL;
- fr->afdatalen = datalen;
- }
-#else
- if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
- return NULL;
- fr->afdatalen = datalen;
-#endif
-
-
- fr->direction = direction;
- fr->retrans = -1;
- fr->cacheable = cacheable;
-
- if (fr->direction == DIRECTION_INGRESS)
- ast_atomic_fetchadd_int(&iframes, 1);
- else
- ast_atomic_fetchadd_int(&oframes, 1);
-
- ast_atomic_fetchadd_int(&frames, 1);
-
- return fr;
-}
-
-void iax_frame_free(struct iax_frame *fr)
-{
-#if !defined(LOW_MEMORY)
- struct iax_frames *iax_frames;
-#endif
-
- /* Note: does not remove from scheduler! */
- if (fr->direction == DIRECTION_INGRESS)
- ast_atomic_fetchadd_int(&iframes, -1);
- else if (fr->direction == DIRECTION_OUTGRESS)
- ast_atomic_fetchadd_int(&oframes, -1);
- else {
- errorf("Attempt to double free frame detected\n");
- return;
- }
- ast_atomic_fetchadd_int(&frames, -1);
-
-#if !defined(LOW_MEMORY)
- if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
- free(fr);
- return;
- }
-
- fr->direction = 0;
- AST_LIST_INSERT_HEAD(iax_frames, fr, list);
-#else
- free(fr);
-#endif
-}
-
-#if !defined(LOW_MEMORY)
-static void frame_cache_cleanup(void *data)
-{
- struct iax_frames *frames = data;
- struct iax_frame *cur;
-
- while ((cur = AST_LIST_REMOVE_HEAD(frames, list)))
- free(cur);
-
- free(frames);
-}
-#endif
-
-int iax_get_frames(void) { return frames; }
-int iax_get_iframes(void) { return iframes; }
-int iax_get_oframes(void) { return oframes; }
diff --git a/1.4/channels/iax2-parser.h b/1.4/channels/iax2-parser.h
deleted file mode 100644
index 0f3e18c00..000000000
--- a/1.4/channels/iax2-parser.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Implementation of Inter-Asterisk eXchange
- *
- * Copyright (C) 2003, Digium
- *
- * Mark Spencer <markster@digium.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*!\file
- * \brief Implementation of the IAX2 protocol
- */
-
-#ifndef _IAX2_PARSER_H
-#define _IAX2_PARSER_H
-
-#include "asterisk/linkedlists.h"
-
-struct iax_ies {
- char *called_number;
- char *calling_number;
- char *calling_ani;
- char *calling_name;
- int calling_ton;
- int calling_tns;
- int calling_pres;
- char *called_context;
- char *username;
- char *password;
- unsigned int capability;
- unsigned int format;
- char *codec_prefs;
- char *language;
- int version;
- unsigned short adsicpe;
- char *dnid;
- char *rdnis;
- unsigned int authmethods;
- unsigned int encmethods;
- char *challenge;
- char *md5_result;
- char *rsa_result;
- struct sockaddr_in *apparent_addr;
- unsigned short refresh;
- unsigned short dpstatus;
- unsigned short callno;
- char *cause;
- unsigned char causecode;
- unsigned char iax_unknown;
- int msgcount;
- int autoanswer;
- int musiconhold;
- unsigned int transferid;
- unsigned int datetime;
- char *devicetype;
- char *serviceident;
- int firmwarever;
- unsigned int fwdesc;
- unsigned char *fwdata;
- unsigned char fwdatalen;
- unsigned char *enckey;
- unsigned char enckeylen;
- unsigned int provver;
- unsigned short samprate;
- int provverpres;
- unsigned int rr_jitter;
- unsigned int rr_loss;
- unsigned int rr_pkts;
- unsigned short rr_delay;
- unsigned int rr_dropped;
- unsigned int rr_ooo;
-};
-
-#define DIRECTION_INGRESS 1
-#define DIRECTION_OUTGRESS 2
-
-struct iax_frame {
-#ifdef LIBIAX
- struct iax_session *session;
- struct iax_event *event;
-#else
- int sockfd;
-#endif
-
- /* /Our/ call number */
- unsigned short callno;
- /* /Their/ call number */
- unsigned short dcallno;
- /* Start of raw frame (outgoing only) */
- void *data;
- /* Length of frame (outgoing only) */
- int datalen;
- /* How many retries so far? */
- int retries;
- /* Outgoing relative timestamp (ms) */
- unsigned int ts;
- /* How long to wait before retrying */
- int retrytime;
- /* Are we received out of order? */
- unsigned int outoforder:1;
- /* Have we been sent at all yet? */
- unsigned int sentyet:1;
- /* Non-zero if should be sent to transfer peer */
- unsigned int transfer:1;
- /* Non-zero if this is the final message */
- unsigned int final:1;
- /* Ingress or outgres */
- unsigned int direction:2;
- /* Can this frame be cached? */
- unsigned int cacheable:1;
- /* Outgoing Packet sequence number */
- int oseqno;
- /* Next expected incoming packet sequence number */
- int iseqno;
- /* Retransmission ID */
- int retrans;
- /* Easy linking */
- AST_LIST_ENTRY(iax_frame) list;
- /* Actual, isolated frame header */
- struct ast_frame af;
- /*! Amount of space _allocated_ for data */
- size_t afdatalen;
- unsigned char unused[AST_FRIENDLY_OFFSET];
- unsigned char afdata[0]; /* Data for frame */
-};
-
-struct iax_ie_data {
- unsigned char buf[1024];
- int pos;
-};
-
-/* Choose a different function for output */
-void iax_set_output(void (*output)(const char *data));
-/* Choose a different function for errors */
-void iax_set_error(void (*output)(const char *data));
-void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
-
-const char *iax_ie2str(int ie);
-
-int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen);
-int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, const struct sockaddr_in *sin);
-int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value);
-int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value);
-int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str);
-int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat);
-int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
-int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
-
-int iax_get_frames(void);
-int iax_get_iframes(void);
-int iax_get_oframes(void);
-
-void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f);
-struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheable);
-void iax_frame_free(struct iax_frame *fr);
-#endif
diff --git a/1.4/channels/iax2-provision.c b/1.4/channels/iax2-provision.c
deleted file mode 100644
index b6137a88b..000000000
--- a/1.4/channels/iax2-provision.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief IAX Provisioning Protocol
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/socket.h>
-
-#include "asterisk/config.h"
-#include "asterisk/logger.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-#include "asterisk/frame.h"
-#include "asterisk/options.h"
-#include "asterisk/md5.h"
-#include "asterisk/astdb.h"
-#include "asterisk/utils.h"
-#include "asterisk/acl.h"
-#include "iax2.h"
-#include "iax2-provision.h"
-#include "iax2-parser.h"
-
-#ifndef IPTOS_MINCOST
-#define IPTOS_MINCOST 0x02
-#endif
-
-static int provinit = 0;
-
-struct iax_template {
- int dead;
- char name[80];
- char src[80];
- struct iax_template *next;
- char user[20];
- char pass[20];
- char lang[10];
- unsigned short port;
- unsigned int server;
- unsigned short serverport;
- unsigned int altserver;
- unsigned int flags;
- unsigned int format;
- unsigned int tos;
-} *templates;
-
-static struct iax_flag {
- char *name;
- int value;
-} iax_flags[] = {
- { "register", PROV_FLAG_REGISTER },
- { "secure", PROV_FLAG_SECURE },
- { "heartbeat", PROV_FLAG_HEARTBEAT },
- { "debug", PROV_FLAG_DEBUG },
- { "disablecid", PROV_FLAG_DIS_CALLERID },
- { "disablecw", PROV_FLAG_DIS_CALLWAIT },
- { "disablecidcw", PROV_FLAG_DIS_CIDCW },
- { "disable3way", PROV_FLAG_DIS_THREEWAY },
-};
-
-char *iax_provflags2str(char *buf, int buflen, unsigned int flags)
-{
- int x;
-
- if (!buf || buflen < 1)
- return NULL;
-
- buf[0] = '\0';
-
- for (x = 0; x < sizeof(iax_flags) / sizeof(iax_flags[0]); x++) {
- if (flags & iax_flags[x].value){
- strncat(buf, iax_flags[x].name, buflen - strlen(buf) - 1);
- strncat(buf, ",", buflen - strlen(buf) - 1);
- }
- }
-
- if (!ast_strlen_zero(buf))
- buf[strlen(buf) - 1] = '\0';
- else
- strncpy(buf, "none", buflen - 1);
-
- return buf;
-}
-
-static unsigned int iax_str2flags(const char *buf)
-{
- int x;
- int len;
- int found;
- unsigned int flags = 0;
- char *e;
- while(buf && *buf) {
- e = strchr(buf, ',');
- if (e)
- len = e - buf;
- else
- len = 0;
- found = 0;
- for (x=0;x<sizeof(iax_flags) / sizeof(iax_flags[0]); x++) {
- if ((len && !strncasecmp(iax_flags[x].name, buf, len)) ||
- (!len && !strcasecmp(iax_flags[x].name, buf))) {
- flags |= iax_flags[x].value;
- break;
- }
- }
- if (e) {
- buf = e + 1;
- while(*buf && (*buf < 33))
- buf++;
- } else
- break;
- }
- return flags;
-}
-AST_MUTEX_DEFINE_STATIC(provlock);
-
-static struct iax_template *iax_template_find(const char *s, int allowdead)
-{
- struct iax_template *cur;
- cur = templates;
- while(cur) {
- if (!strcasecmp(s, cur->name)) {
- if (!allowdead && cur->dead)
- cur = NULL;
- break;
- }
- cur = cur->next;
- }
- return cur;
-}
-
-char *iax_prov_complete_template(const char *line, const char *word, int pos, int state)
-{
- struct iax_template *c;
- int which=0;
- char *ret = NULL;
- int wordlen = strlen(word);
-
- ast_mutex_lock(&provlock);
- for (c = templates; c; c = c->next) {
- if (!strncasecmp(word, c->name, wordlen) && ++which > state) {
- ret = strdup(c->name);
- break;
- }
- }
- ast_mutex_unlock(&provlock);
-
- return ret;
-}
-
-static unsigned int prov_ver_calc(struct iax_ie_data *provdata)
-{
- struct MD5Context md5;
- unsigned int tmp[4];
- MD5Init(&md5);
- MD5Update(&md5, provdata->buf, provdata->pos);
- MD5Final((unsigned char *)tmp, &md5);
- return tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
-}
-
-int iax_provision_build(struct iax_ie_data *provdata, unsigned int *signature, const char *template, int force)
-{
- struct iax_template *cur;
- unsigned int sig;
- char tmp[40];
- memset(provdata, 0, sizeof(*provdata));
- ast_mutex_lock(&provlock);
- cur = iax_template_find(template, 1);
- /* If no match, try searching for '*' */
- if (!cur)
- cur = iax_template_find("*", 1);
- if (cur) {
- /* found it -- add information elements as appropriate */
- if (force || strlen(cur->user))
- iax_ie_append_str(provdata, PROV_IE_USER, cur->user);
- if (force || strlen(cur->pass))
- iax_ie_append_str(provdata, PROV_IE_PASS, cur->pass);
- if (force || strlen(cur->lang))
- iax_ie_append_str(provdata, PROV_IE_LANG, cur->lang);
- if (force || cur->port)
- iax_ie_append_short(provdata, PROV_IE_PORTNO, cur->port);
- if (force || cur->server)
- iax_ie_append_int(provdata, PROV_IE_SERVERIP, cur->server);
- if (force || cur->serverport)
- iax_ie_append_short(provdata, PROV_IE_SERVERPORT, cur->serverport);
- if (force || cur->altserver)
- iax_ie_append_int(provdata, PROV_IE_ALTSERVER, cur->altserver);
- if (force || cur->flags)
- iax_ie_append_int(provdata, PROV_IE_FLAGS, cur->flags);
- if (force || cur->format)
- iax_ie_append_int(provdata, PROV_IE_FORMAT, cur->format);
- if (force || cur->tos)
- iax_ie_append_byte(provdata, PROV_IE_TOS, cur->tos);
-
- /* Calculate checksum of message so far */
- sig = prov_ver_calc(provdata);
- if (signature)
- *signature = sig;
- /* Store signature */
- iax_ie_append_int(provdata, PROV_IE_PROVVER, sig);
- /* Cache signature for later verification so we need not recalculate all this */
- snprintf(tmp, sizeof(tmp), "v0x%08x", sig);
- ast_db_put("iax/provisioning/cache", template, tmp);
- } else
- ast_db_put("iax/provisioning/cache", template, "u");
- ast_mutex_unlock(&provlock);
- return cur ? 0 : -1;
-}
-
-int iax_provision_version(unsigned int *version, const char *template, int force)
-{
- char tmp[80] = "";
- struct iax_ie_data ied;
- int ret=0;
- memset(&ied, 0, sizeof(ied));
-
- ast_mutex_lock(&provlock);
- ast_db_get("iax/provisioning/cache", template, tmp, sizeof(tmp));
- if (sscanf(tmp, "v%x", version) != 1) {
- if (strcmp(tmp, "u")) {
- ret = iax_provision_build(&ied, version, template, force);
- if (ret)
- ast_log(LOG_DEBUG, "Unable to create provisioning packet for '%s'\n", template);
- } else
- ret = -1;
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Retrieved cached version '%s' = '%08x'\n", tmp, *version);
- ast_mutex_unlock(&provlock);
- return ret;
-}
-
-static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg, const char *s, const char *def)
-{
- struct ast_variable *v;
- int foundportno = 0;
- int foundserverportno = 0;
- int x;
- struct in_addr ia;
- struct hostent *hp;
- struct ast_hostent h;
- struct iax_template *src, tmp;
- const char *t;
- if (def) {
- t = ast_variable_retrieve(cfg, s ,"template");
- src = NULL;
- if (t && strlen(t)) {
- src = iax_template_find(t, 0);
- if (!src)
- ast_log(LOG_WARNING, "Unable to find base template '%s' for creating '%s'. Trying '%s'\n", t, s, def);
- else
- def = t;
- }
- if (!src) {
- src = iax_template_find(def, 0);
- if (!src)
- ast_log(LOG_WARNING, "Unable to locate default base template '%s' for creating '%s', omitting.\n", def, s);
- }
- if (!src)
- return -1;
- ast_mutex_lock(&provlock);
- /* Backup old data */
- memcpy(&tmp, cur, sizeof(tmp));
- /* Restore from src */
- memcpy(cur, src, sizeof(tmp));
- /* Restore important headers */
- memcpy(cur->name, tmp.name, sizeof(cur->name));
- cur->dead = tmp.dead;
- cur->next = tmp.next;
- ast_mutex_unlock(&provlock);
- }
- if (def)
- strncpy(cur->src, def, sizeof(cur->src) - 1);
- else
- cur->src[0] = '\0';
- v = ast_variable_browse(cfg, s);
- while(v) {
- if (!strcasecmp(v->name, "port") || !strcasecmp(v->name, "serverport")) {
- if ((sscanf(v->value, "%d", &x) == 1) && (x > 0) && (x < 65535)) {
- if (!strcasecmp(v->name, "port")) {
- cur->port = x;
- foundportno = 1;
- } else {
- cur->serverport = x;
- foundserverportno = 1;
- }
- } else
- ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
- } else if (!strcasecmp(v->name, "server") || !strcasecmp(v->name, "altserver")) {
- hp = ast_gethostbyname(v->value, &h);
- if (hp) {
- memcpy(&ia, hp->h_addr, sizeof(ia));
- if (!strcasecmp(v->name, "server"))
- cur->server = ntohl(ia.s_addr);
- else
- cur->altserver = ntohl(ia.s_addr);
- } else
- ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
- } else if (!strcasecmp(v->name, "codec")) {
- if ((x = ast_getformatbyname(v->value)) > 0) {
- cur->format = x;
- } else
- ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno);
- } else if (!strcasecmp(v->name, "tos")) {
- if (ast_str2tos(v->value, &cur->tos))
- ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.\n", v->lineno);
- } else if (!strcasecmp(v->name, "user")) {
- strncpy(cur->user, v->value, sizeof(cur->user) - 1);
- if (strcmp(cur->user, v->value))
- ast_log(LOG_WARNING, "Truncating username from '%s' to '%s' for '%s' at line %d\n", v->value, cur->user, s, v->lineno);
- } else if (!strcasecmp(v->name, "pass")) {
- strncpy(cur->pass, v->value, sizeof(cur->pass) - 1);
- if (strcmp(cur->pass, v->value))
- ast_log(LOG_WARNING, "Truncating password from '%s' to '%s' for '%s' at line %d\n", v->value, cur->pass, s, v->lineno);
- } else if (!strcasecmp(v->name, "language")) {
- strncpy(cur->lang, v->value, sizeof(cur->lang) - 1);
- if (strcmp(cur->lang, v->value))
- ast_log(LOG_WARNING, "Truncating language from '%s' to '%s' for '%s' at line %d\n", v->value, cur->lang, s, v->lineno);
- } else if (!strcasecmp(v->name, "flags")) {
- cur->flags = iax_str2flags(v->value);
- } else if (!strncasecmp(v->name, "flags", 5) && strchr(v->name, '+')) {
- cur->flags |= iax_str2flags(v->value);
- } else if (!strncasecmp(v->name, "flags", 5) && strchr(v->name, '-')) {
- cur->flags &= ~iax_str2flags(v->value);
- } else if (strcasecmp(v->name, "template")) {
- ast_log(LOG_WARNING, "Unknown keyword '%s' in definition of '%s' at line %d\n", v->name, s, v->lineno);
- }
- v = v->next;
- }
- if (!foundportno)
- cur->port = IAX_DEFAULT_PORTNO;
- if (!foundserverportno)
- cur->serverport = IAX_DEFAULT_PORTNO;
- return 0;
-}
-
-static int iax_process_template(struct ast_config *cfg, char *s, char *def)
-{
- /* Find an already existing one if there */
- struct iax_template *cur;
- int mallocd = 0;
- cur = templates;
- while(cur) {
- if (!strcasecmp(cur->name, s))
- break;
- cur = cur->next;
- }
- if (!cur) {
- mallocd = 1;
- cur = malloc(sizeof(struct iax_template));
- if (!cur) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- return -1;
- }
- /* Initialize entry */
- memset(cur, 0, sizeof(*cur));
- strncpy(cur->name, s, sizeof(cur->name) - 1);
- cur->dead = 1;
- }
- if (!iax_template_parse(cur, cfg, s, def))
- cur->dead = 0;
-
- /* Link if we're mallocd */
- if (mallocd) {
- ast_mutex_lock(&provlock);
- cur->next = templates;
- templates = cur;
- ast_mutex_unlock(&provlock);
- }
- return 0;
-}
-
-static char show_provisioning_usage[] =
-"Usage: iax list provisioning [template]\n"
-" Lists all known IAX provisioning templates or a\n"
-" specific one if specified.\n";
-
-static const char *ifthere(const char *s)
-{
- if (strlen(s))
- return s;
- else
- return "<unspecified>";
-}
-
-static const char *iax_server(unsigned int addr)
-{
- struct in_addr ia;
-
- if (!addr)
- return "<unspecified>";
-
- ia.s_addr = htonl(addr);
-
- return ast_inet_ntoa(ia);
-}
-
-
-static int iax_show_provisioning(int fd, int argc, char *argv[])
-{
- struct iax_template *cur;
- char server[INET_ADDRSTRLEN];
- char alternate[INET_ADDRSTRLEN];
- char flags[80]; /* Has to be big enough for 'flags' too */
- int found = 0;
- if ((argc != 3) && (argc != 4))
- return RESULT_SHOWUSAGE;
- ast_mutex_lock(&provlock);
- for (cur = templates;cur;cur = cur->next) {
- if ((argc == 3) || (!strcasecmp(argv[3], cur->name))) {
- if (found)
- ast_cli(fd, "\n");
- ast_copy_string(server, iax_server(cur->server), sizeof(server));
- ast_copy_string(alternate, iax_server(cur->altserver), sizeof(alternate));
- ast_cli(fd, "== %s ==\n", cur->name);
- ast_cli(fd, "Base Templ: %s\n", strlen(cur->src) ? cur->src : "<none>");
- ast_cli(fd, "Username: %s\n", ifthere(cur->user));
- ast_cli(fd, "Secret: %s\n", ifthere(cur->pass));
- ast_cli(fd, "Language: %s\n", ifthere(cur->lang));
- ast_cli(fd, "Bind Port: %d\n", cur->port);
- ast_cli(fd, "Server: %s\n", server);
- ast_cli(fd, "Server Port: %d\n", cur->serverport);
- ast_cli(fd, "Alternate: %s\n", alternate);
- ast_cli(fd, "Flags: %s\n", iax_provflags2str(flags, sizeof(flags), cur->flags));
- ast_cli(fd, "Format: %s\n", ast_getformatname(cur->format));
- ast_cli(fd, "TOS: 0x%x\n", cur->tos);
- found++;
- }
- }
- ast_mutex_unlock(&provlock);
- if (!found) {
- if (argc == 3)
- ast_cli(fd, "No provisioning templates found\n");
- else
- ast_cli(fd, "No provisioning template matching '%s' found\n", argv[3]);
- }
- return RESULT_SUCCESS;
-}
-
-static struct ast_cli_entry cli_iax2_provision[] = {
- { { "iax2", "show", "provisioning", NULL },
- iax_show_provisioning, "Display iax provisioning",
- show_provisioning_usage, iax_prov_complete_template, },
-};
-
-static int iax_provision_init(void)
-{
- ast_cli_register_multiple(cli_iax2_provision, sizeof(cli_iax2_provision) / sizeof(struct ast_cli_entry));
- provinit = 1;
- return 0;
-}
-
-int iax_provision_unload(void)
-{
- provinit = 0;
- ast_cli_unregister_multiple(cli_iax2_provision, sizeof(cli_iax2_provision) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-int iax_provision_reload(void)
-{
- struct ast_config *cfg;
- struct iax_template *cur, *prev, *next;
- char *cat;
- int found = 0;
- if (!provinit)
- iax_provision_init();
- /* Mark all as dead. No need for locking */
- cur = templates;
- while(cur) {
- cur->dead = 1;
- cur = cur->next;
- }
- cfg = ast_config_load("iaxprov.conf");
- if (cfg) {
- /* Load as appropriate */
- cat = ast_category_browse(cfg, NULL);
- while(cat) {
- if (strcasecmp(cat, "general")) {
- iax_process_template(cfg, cat, found ? "default" : NULL);
- found++;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Loaded provisioning template '%s'\n", cat);
- }
- cat = ast_category_browse(cfg, cat);
- }
- ast_config_destroy(cfg);
- } else
- ast_log(LOG_NOTICE, "No IAX provisioning configuration found, IAX provisioning disabled.\n");
- ast_mutex_lock(&provlock);
- /* Drop dead entries while locked */
- prev = NULL;
- cur = templates;
- while(cur) {
- next = cur->next;
- if (cur->dead) {
- if (prev)
- prev->next = next;
- else
- templates = next;
- free(cur);
- } else
- prev = cur;
- cur = next;
- }
- ast_mutex_unlock(&provlock);
- /* Purge cached signature DB entries */
- ast_db_deltree("iax/provisioning/cache", NULL);
- return 0;
-
-}
diff --git a/1.4/channels/iax2-provision.h b/1.4/channels/iax2-provision.h
deleted file mode 100644
index d95150253..000000000
--- a/1.4/channels/iax2-provision.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * IAX Provisioning Protocol
- *
- * Sub-information elements
- *
- * Copyright (C) 2003, Digium
- *
- * Mark Spencer <markster@digium.com>
- *
- */
-
-/*! \file
- * \brief IAX2 Provisioning protocol
- */
-
-#include "iax2-parser.h"
-
-#define PROV_IE_USEDHCP 1 /* Presense only */
-#define PROV_IE_IPADDR 2 /* 32-bit */
-#define PROV_IE_SUBNET 3 /* 32-bit */
-#define PROV_IE_GATEWAY 4 /* 32-bit */
-#define PROV_IE_PORTNO 5 /* 16-bit */
-#define PROV_IE_USER 6 /* < 20 bytes */
-#define PROV_IE_PASS 7 /* < 20 bytes */
-#define PROV_IE_SERVERUSER 8 /* < 20 bytes */
-#define PROV_IE_SERVERPASS 9 /* < 20 bytes */
-#define PROV_IE_LANG 10 /* < 10 bytes */
-#define PROV_IE_TOS 11 /* 8-bits */
-#define PROV_IE_FLAGS 12 /* 32-bits */
-#define PROV_IE_FORMAT 13 /* 32-bits */
-#define PROV_IE_AESKEY 14 /* 128-bits */
-#define PROV_IE_SERVERIP 15 /* 32-bits */
-#define PROV_IE_SERVERPORT 16 /* 16-bits */
-#define PROV_IE_NEWAESKEY 17 /* 128-bits */
-#define PROV_IE_PROVVER 18 /* 32-bits */
-#define PROV_IE_ALTSERVER 19 /* 32-bits */
-
-#define PROV_FLAG_REGISTER (1 << 0)
-#define PROV_FLAG_SECURE (1 << 1)
-#define PROV_FLAG_HEARTBEAT (1 << 2)
-#define PROV_FLAG_DEBUG (1 << 3)
-
-#define PROV_FLAG_DIS_CALLERID (1 << 4) /* Caller-ID Disabled */
-#define PROV_FLAG_DIS_CALLWAIT (1 << 5) /* Caller-ID / Call Waiting Disable */
-#define PROV_FLAG_DIS_CIDCW (1 << 6) /* CID/CW Disabled */
-#define PROV_FLAG_DIS_THREEWAY (1 << 7) /* Three-way calling, transfer disabled */
-
-char *iax_provflags2str(char *buf, int buflen, unsigned int flags);
-int iax_provision_reload(void);
-int iax_provision_unload(void);
-int iax_provision_build(struct iax_ie_data *provdata, unsigned int *signature, const char *template, int force);
-int iax_provision_version(unsigned int *signature, const char *template, int force);
-char *iax_prov_complete_template(const char *line, const char *word, int pos, int state);
diff --git a/1.4/channels/iax2.h b/1.4/channels/iax2.h
deleted file mode 100644
index 960dec8bb..000000000
--- a/1.4/channels/iax2.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Implementation of Inter-Asterisk eXchange
- *
- * Copyright (C) 2003, Digium
- *
- * Mark Spencer <markster@linux-support.net>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-#ifndef _IAX2_H
-#define _IAX2_H
-
-/* Max version of IAX protocol we support */
-#define IAX_PROTO_VERSION 2
-
-/* NOTE: IT IS CRITICAL THAT IAX_MAX_CALLS BE A POWER OF 2. */
-#if defined(LOW_MEMORY)
-#define IAX_MAX_CALLS 2048
-#else
-#define IAX_MAX_CALLS 32768
-#endif
-
-#define IAX_FLAG_FULL 0x8000
-
-#define IAX_FLAG_RETRANS 0x8000
-
-#define IAX_FLAG_SC_LOG 0x80
-
-#define IAX_MAX_SHIFT 0x1F
-
-#define IAX_WINDOW 64
-
-/* Subclass for AST_FRAME_IAX */
-#define IAX_COMMAND_NEW 1
-#define IAX_COMMAND_PING 2
-#define IAX_COMMAND_PONG 3
-#define IAX_COMMAND_ACK 4
-#define IAX_COMMAND_HANGUP 5
-#define IAX_COMMAND_REJECT 6
-#define IAX_COMMAND_ACCEPT 7
-#define IAX_COMMAND_AUTHREQ 8
-#define IAX_COMMAND_AUTHREP 9
-#define IAX_COMMAND_INVAL 10
-#define IAX_COMMAND_LAGRQ 11
-#define IAX_COMMAND_LAGRP 12
-#define IAX_COMMAND_REGREQ 13 /* Registration request */
-#define IAX_COMMAND_REGAUTH 14 /* Registration authentication required */
-#define IAX_COMMAND_REGACK 15 /* Registration accepted */
-#define IAX_COMMAND_REGREJ 16 /* Registration rejected */
-#define IAX_COMMAND_REGREL 17 /* Force release of registration */
-#define IAX_COMMAND_VNAK 18 /* If we receive voice before valid first voice frame, send this */
-#define IAX_COMMAND_DPREQ 19 /* Request status of a dialplan entry */
-#define IAX_COMMAND_DPREP 20 /* Request status of a dialplan entry */
-#define IAX_COMMAND_DIAL 21 /* Request a dial on channel brought up TBD */
-#define IAX_COMMAND_TXREQ 22 /* Transfer Request */
-#define IAX_COMMAND_TXCNT 23 /* Transfer Connect */
-#define IAX_COMMAND_TXACC 24 /* Transfer Accepted */
-#define IAX_COMMAND_TXREADY 25 /* Transfer ready */
-#define IAX_COMMAND_TXREL 26 /* Transfer release */
-#define IAX_COMMAND_TXREJ 27 /* Transfer reject */
-#define IAX_COMMAND_QUELCH 28 /* Stop audio/video transmission */
-#define IAX_COMMAND_UNQUELCH 29 /* Resume audio/video transmission */
-#define IAX_COMMAND_POKE 30 /* Like ping, but does not require an open connection */
-#define IAX_COMMAND_PAGE 31 /* Paging description */
-#define IAX_COMMAND_MWI 32 /* Stand-alone message waiting indicator */
-#define IAX_COMMAND_UNSUPPORT 33 /* Unsupported message received */
-#define IAX_COMMAND_TRANSFER 34 /* Request remote transfer */
-#define IAX_COMMAND_PROVISION 35 /* Provision device */
-#define IAX_COMMAND_FWDOWNL 36 /* Download firmware */
-#define IAX_COMMAND_FWDATA 37 /* Firmware Data */
-#define IAX_COMMAND_TXMEDIA 38 /* Transfer media only */
-
-#define IAX_DEFAULT_REG_EXPIRE 60 /* By default require re-registration once per minute */
-
-#define IAX_LINGER_TIMEOUT 10 /* How long to wait before closing bridged call */
-
-#define IAX_DEFAULT_PORTNO 4569
-
-/* IAX Information elements */
-#define IAX_IE_CALLED_NUMBER 1 /* Number/extension being called - string */
-#define IAX_IE_CALLING_NUMBER 2 /* Calling number - string */
-#define IAX_IE_CALLING_ANI 3 /* Calling number ANI for billing - string */
-#define IAX_IE_CALLING_NAME 4 /* Name of caller - string */
-#define IAX_IE_CALLED_CONTEXT 5 /* Context for number - string */
-#define IAX_IE_USERNAME 6 /* Username (peer or user) for authentication - string */
-#define IAX_IE_PASSWORD 7 /* Password for authentication - string */
-#define IAX_IE_CAPABILITY 8 /* Actual codec capability - unsigned int */
-#define IAX_IE_FORMAT 9 /* Desired codec format - unsigned int */
-#define IAX_IE_LANGUAGE 10 /* Desired language - string */
-#define IAX_IE_VERSION 11 /* Protocol version - short */
-#define IAX_IE_ADSICPE 12 /* CPE ADSI capability - short */
-#define IAX_IE_DNID 13 /* Originally dialed DNID - string */
-#define IAX_IE_AUTHMETHODS 14 /* Authentication method(s) - short */
-#define IAX_IE_CHALLENGE 15 /* Challenge data for MD5/RSA - string */
-#define IAX_IE_MD5_RESULT 16 /* MD5 challenge result - string */
-#define IAX_IE_RSA_RESULT 17 /* RSA challenge result - string */
-#define IAX_IE_APPARENT_ADDR 18 /* Apparent address of peer - struct sockaddr_in */
-#define IAX_IE_REFRESH 19 /* When to refresh registration - short */
-#define IAX_IE_DPSTATUS 20 /* Dialplan status - short */
-#define IAX_IE_CALLNO 21 /* Call number of peer - short */
-#define IAX_IE_CAUSE 22 /* Cause - string */
-#define IAX_IE_IAX_UNKNOWN 23 /* Unknown IAX command - byte */
-#define IAX_IE_MSGCOUNT 24 /* How many messages waiting - short */
-#define IAX_IE_AUTOANSWER 25 /* Request auto-answering -- none */
-#define IAX_IE_MUSICONHOLD 26 /* Request musiconhold with QUELCH -- none or string */
-#define IAX_IE_TRANSFERID 27 /* Transfer Request Identifier -- int */
-#define IAX_IE_RDNIS 28 /* Referring DNIS -- string */
-#define IAX_IE_PROVISIONING 29 /* Provisioning info */
-#define IAX_IE_AESPROVISIONING 30 /* AES Provisioning info */
-#define IAX_IE_DATETIME 31 /* Date/Time */
-#define IAX_IE_DEVICETYPE 32 /* Device Type -- string */
-#define IAX_IE_SERVICEIDENT 33 /* Service Identifier -- string */
-#define IAX_IE_FIRMWAREVER 34 /* Firmware revision -- u16 */
-#define IAX_IE_FWBLOCKDESC 35 /* Firmware block description -- u32 */
-#define IAX_IE_FWBLOCKDATA 36 /* Firmware block of data -- raw */
-#define IAX_IE_PROVVER 37 /* Provisioning Version (u32) */
-#define IAX_IE_CALLINGPRES 38 /* Calling presentation (u8) */
-#define IAX_IE_CALLINGTON 39 /* Calling type of number (u8) */
-#define IAX_IE_CALLINGTNS 40 /* Calling transit network select (u16) */
-#define IAX_IE_SAMPLINGRATE 41 /* Supported sampling rates (u16) */
-#define IAX_IE_CAUSECODE 42 /* Hangup cause (u8) */
-#define IAX_IE_ENCRYPTION 43 /* Encryption format (u16) */
-#define IAX_IE_ENCKEY 44 /* Encryption key (raw) */
-#define IAX_IE_CODEC_PREFS 45 /* Codec Negotiation */
-
-#define IAX_IE_RR_JITTER 46 /* Received jitter (as in RFC1889) u32 */
-#define IAX_IE_RR_LOSS 47 /* Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889 */
-#define IAX_IE_RR_PKTS 48 /* Received frames (total frames received) u32 */
-#define IAX_IE_RR_DELAY 49 /* Max playout delay for received frames (in ms) u16 */
-#define IAX_IE_RR_DROPPED 50 /* Dropped frames (presumably by jitterbuf) u32 */
-#define IAX_IE_RR_OOO 51 /* Frames received Out of Order u32 */
-
-
-#define IAX_AUTH_PLAINTEXT (1 << 0)
-#define IAX_AUTH_MD5 (1 << 1)
-#define IAX_AUTH_RSA (1 << 2)
-
-#define IAX_ENCRYPT_AES128 (1 << 0)
-
-#define IAX_META_TRUNK 1 /* Trunk meta-message */
-#define IAX_META_VIDEO 2 /* Video frame */
-
-#define IAX_META_TRUNK_SUPERMINI 0 /* This trunk frame contains classic supermini frames */
-#define IAX_META_TRUNK_MINI 1 /* This trunk frame contains trunked mini frames */
-
-#define IAX_RATE_8KHZ (1 << 0) /* 8khz sampling (default if absent) */
-#define IAX_RATE_11KHZ (1 << 1) /* 11.025khz sampling */
-#define IAX_RATE_16KHZ (1 << 2) /* 16khz sampling */
-#define IAX_RATE_22KHZ (1 << 3) /* 22.05khz sampling */
-#define IAX_RATE_44KHZ (1 << 4) /* 44.1khz sampling */
-#define IAX_RATE_48KHZ (1 << 5) /* 48khz sampling */
-
-#define IAX_DPSTATUS_EXISTS (1 << 0)
-#define IAX_DPSTATUS_CANEXIST (1 << 1)
-#define IAX_DPSTATUS_NONEXISTENT (1 << 2)
-#define IAX_DPSTATUS_IGNOREPAT (1 << 14)
-#define IAX_DPSTATUS_MATCHMORE (1 << 15)
-
-/* Full frames are always delivered reliably */
-struct ast_iax2_full_hdr {
- unsigned short scallno; /* Source call number -- high bit must be 1 */
- unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */
- unsigned int ts; /* 32-bit timestamp in milliseconds (from 1st transmission) */
- unsigned char oseqno; /* Packet number (outgoing) */
- unsigned char iseqno; /* Packet number (next incoming expected) */
- unsigned char type; /* Frame type */
- unsigned char csub; /* Compressed subclass */
- unsigned char iedata[0];
-} __attribute__ ((__packed__));
-
-/* Full frames are always delivered reliably */
-struct ast_iax2_full_enc_hdr {
- unsigned short scallno; /* Source call number -- high bit must be 1 */
- unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */
- unsigned char encdata[0];
-} __attribute__ ((__packed__));
-
-/* Mini header is used only for voice frames -- delivered unreliably */
-struct ast_iax2_mini_hdr {
- unsigned short callno; /* Source call number -- high bit must be 0, rest must be non-zero */
- unsigned short ts; /* 16-bit Timestamp (high 16 bits from last ast_iax2_full_hdr) */
- /* Frametype implicitly VOICE_FRAME */
- /* subclass implicit from last ast_iax2_full_hdr */
- unsigned char data[0];
-} __attribute__ ((__packed__));
-
-/* Mini header is used only for voice frames -- delivered unreliably */
-struct ast_iax2_mini_enc_hdr {
- unsigned short callno; /* Source call number -- high bit must be 0, rest must be non-zero */
- unsigned char encdata[0];
-} __attribute__ ((__packed__));
-
-struct ast_iax2_meta_hdr {
- unsigned short zeros; /* Zeros field -- must be zero */
- unsigned char metacmd; /* Meta command */
- unsigned char cmddata; /* Command Data */
- unsigned char data[0];
-} __attribute__ ((__packed__));
-
-struct ast_iax2_video_hdr {
- unsigned short zeros; /* Zeros field -- must be zero */
- unsigned short callno; /* Video call number */
- unsigned short ts; /* Timestamp and mark if present */
- unsigned char data[0];
-} __attribute__ ((__packed__));
-
-struct ast_iax2_meta_trunk_hdr {
- unsigned int ts; /* 32-bit timestamp for all messages */
- unsigned char data[0];
-} __attribute__ ((__packed__));
-
-struct ast_iax2_meta_trunk_entry {
- unsigned short callno; /* Call number */
- unsigned short len; /* Length of data for this callno */
-} __attribute__ ((__packed__));
-
-/* When trunktimestamps are used, we use this format instead */
-struct ast_iax2_meta_trunk_mini {
- unsigned short len;
- struct ast_iax2_mini_hdr mini; /* this is an actual miniframe */
-} __attribute__ ((__packed__));
-
-#define IAX_FIRMWARE_MAGIC 0x69617879
-
-struct ast_iax2_firmware_header {
- unsigned int magic; /* Magic number */
- unsigned short version; /* Software version */
- unsigned char devname[16]; /* Device */
- unsigned int datalen; /* Data length of file beyond header */
- unsigned char chksum[16]; /* Checksum of all data */
- unsigned char data[0];
-} __attribute__ ((__packed__));
-#endif
diff --git a/1.4/channels/misdn/Makefile b/1.4/channels/misdn/Makefile
deleted file mode 100644
index 85478225b..000000000
--- a/1.4/channels/misdn/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Makefile for chan_misdn support
-#
-ifneq ($(wildcard /usr/include/linux/mISDNdsp.h),)
-CFLAGS+=-DMISDN_1_2
-endif
-
-all:
-
-%.o: %.c
- $(CC) $(CFLAGS) -c -o $@ $<
-
-portinfo: portinfo.o
- $(CC) -o $@ $^ -lisdnnet -lmISDN -lpthread
-
-clean:
- rm -rf *.a *.o *.so portinfo
diff --git a/1.4/channels/misdn/chan_misdn_config.h b/1.4/channels/misdn/chan_misdn_config.h
deleted file mode 100644
index f675704c0..000000000
--- a/1.4/channels/misdn/chan_misdn_config.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-
-
-#ifndef CHAN_MISDN_CONFIG_H
-#define CHAN_MISDN_CONFIG_H
-
-#define BUFFERSIZE 512
-
-enum misdn_cfg_elements {
-
- /* port config items */
- MISDN_CFG_FIRST = 0,
- MISDN_CFG_GROUPNAME, /* char[] */
- MISDN_CFG_ALLOWED_BEARERS, /* char[] */
- MISDN_CFG_FAR_ALERTING, /* int (bool) */
- MISDN_CFG_RXGAIN, /* int */
- MISDN_CFG_TXGAIN, /* int */
- MISDN_CFG_TE_CHOOSE_CHANNEL, /* int (bool) */
- MISDN_CFG_PMP_L1_CHECK, /* int (bool) */
- MISDN_CFG_REJECT_CAUSE, /* int */
- MISDN_CFG_ALARM_BLOCK, /* int (bool) */
- MISDN_CFG_HDLC, /* int (bool) */
- MISDN_CFG_CONTEXT, /* char[] */
- MISDN_CFG_LANGUAGE, /* char[] */
- MISDN_CFG_MUSICCLASS, /* char[] */
- MISDN_CFG_CALLERID, /* char[] */
- MISDN_CFG_METHOD, /* char[] */
- MISDN_CFG_DIALPLAN, /* int */
- MISDN_CFG_LOCALDIALPLAN, /* int */
- MISDN_CFG_CPNDIALPLAN, /* int */
- MISDN_CFG_NATPREFIX, /* char[] */
- MISDN_CFG_INTERNATPREFIX, /* char[] */
- MISDN_CFG_PRES, /* int */
- MISDN_CFG_SCREEN, /* int */
- MISDN_CFG_ALWAYS_IMMEDIATE, /* int (bool) */
- MISDN_CFG_NODIALTONE, /* int (bool) */
- MISDN_CFG_IMMEDIATE, /* int (bool) */
- MISDN_CFG_SENDDTMF, /* int (bool) */
- MISDN_CFG_ASTDTMF, /* int (bool) */
- MISDN_CFG_HOLD_ALLOWED, /* int (bool) */
- MISDN_CFG_EARLY_BCONNECT, /* int (bool) */
- MISDN_CFG_INCOMING_EARLY_AUDIO, /* int (bool) */
- MISDN_CFG_ECHOCANCEL, /* int */
-#ifdef MISDN_1_2
- MISDN_CFG_PIPELINE, /* char[] */
-#endif
-
-#ifdef WITH_BEROEC
- MISDN_CFG_BNECHOCANCEL,
- MISDN_CFG_BNEC_ANTIHOWL,
- MISDN_CFG_BNEC_NLP,
- MISDN_CFG_BNEC_ZEROCOEFF,
- MISDN_CFG_BNEC_TD,
- MISDN_CFG_BNEC_ADAPT,
-#endif
- MISDN_CFG_NEED_MORE_INFOS, /* bool */
- MISDN_CFG_NOAUTORESPOND_ON_SETUP, /* bool */
- MISDN_CFG_NTTIMEOUT, /* bool */
- MISDN_CFG_BRIDGING, /* bool */
- MISDN_CFG_JITTERBUFFER, /* int */
- MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, /* int */
- MISDN_CFG_CALLGROUP, /* ast_group_t */
- MISDN_CFG_PICKUPGROUP, /* ast_group_t */
- MISDN_CFG_MAX_IN, /* int */
- MISDN_CFG_MAX_OUT, /* int */
- MISDN_CFG_L1_TIMEOUT, /* int */
- MISDN_CFG_OVERLAP_DIAL, /* int (bool)*/
- MISDN_CFG_MSNS, /* char[] */
- MISDN_CFG_FAXDETECT, /* char[] */
- MISDN_CFG_FAXDETECT_CONTEXT, /* char[] */
- MISDN_CFG_FAXDETECT_TIMEOUT, /* int */
- MISDN_CFG_PTP, /* int (bool) */
- MISDN_CFG_LAST,
-
- /* general config items */
- MISDN_GEN_FIRST,
-#ifndef MISDN_1_2
- MISDN_GEN_MISDN_INIT, /* char[] */
-#endif
- MISDN_GEN_DEBUG, /* int */
- MISDN_GEN_TRACEFILE, /* char[] */
- MISDN_GEN_BRIDGING, /* int (bool) */
- MISDN_GEN_STOP_TONE, /* int (bool) */
- MISDN_GEN_APPEND_DIGITS2EXTEN, /* int (bool) */
- MISDN_GEN_DYNAMIC_CRYPT, /* int (bool) */
- MISDN_GEN_CRYPT_PREFIX, /* char[] */
- MISDN_GEN_CRYPT_KEYS, /* char[] */
- MISDN_GEN_NTKEEPCALLS, /* int (bool) */
- MISDN_GEN_NTDEBUGFLAGS, /* int */
- MISDN_GEN_NTDEBUGFILE, /* char[] */
- MISDN_GEN_LAST
-};
-
-enum misdn_cfg_method {
- METHOD_STANDARD = 0,
- METHOD_ROUND_ROBIN,
- METHOD_STANDARD_DEC
-};
-
-/* you must call misdn_cfg_init before any other function of this header file */
-int misdn_cfg_init(int max_ports);
-void misdn_cfg_reload(void);
-void misdn_cfg_destroy(void);
-
-void misdn_cfg_update_ptp( void );
-
-/* if you requst a general config element, the port value is ignored. if the requested
- * value is not available, or the buffer is too small, the buffer will be nulled (in
- * case of a char* only its first byte will be nulled). */
-void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void* buf, int bufsize);
-
-/* returns the enum element for the given name, returns MISDN_CFG_FIRST if none was found */
-enum misdn_cfg_elements misdn_cfg_get_elem (char *name);
-
-/* fills the buffer with the name of the given config element */
-void misdn_cfg_get_name (enum misdn_cfg_elements elem, void *buf, int bufsize);
-
-/* fills the buffer with the description of the given config element */
-void misdn_cfg_get_desc (enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default);
-
-/* fills the buffer with a ',' separated list of all active ports */
-void misdn_cfg_get_ports_string(char *ports);
-
-/* fills the buffer with a nice printable string representation of the config element */
-void misdn_cfg_get_config_string(int port, enum misdn_cfg_elements elem, char* buf, int bufsize);
-
-/* returns the next available port number. returns -1 if the last one was reached. */
-int misdn_cfg_get_next_port(int port);
-int misdn_cfg_get_next_port_spin(int port);
-
-int misdn_cfg_is_msn_valid(int port, char* msn);
-int misdn_cfg_is_port_valid(int port);
-int misdn_cfg_is_group_method(char *group, enum misdn_cfg_method meth);
-
-#if 0
-char *misdn_cfg_get_next_group(char *group);
-int misdn_cfg_get_next_port_in_group(int port, char *group);
-#endif
-
-#endif
diff --git a/1.4/channels/misdn/ie.c b/1.4/channels/misdn/ie.c
deleted file mode 100644
index 2e7fae998..000000000
--- a/1.4/channels/misdn/ie.c
+++ /dev/null
@@ -1,1422 +0,0 @@
-
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2005, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * heaviliy patched from jollys ie.cpp, jolly gave me ALL
- * rights for this code, i can even have my own copyright on it.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*
- the pointer of enc_ie_* always points to the IE itself
- if qi is not NULL (TE-mode), offset is set
-*/
-
-
-#include <string.h>
-
-#include <mISDNuser/mISDNlib.h>
-#include <mISDNuser/isdn_net.h>
-#include <mISDNuser/l3dss1.h>
-#include <mISDNuser/net_l3.h>
-
-
-
-#define MISDN_IE_DEBG 0
-
-/* support stuff */
-static void strnncpy(char *dest, char *src, int len, int dst_len)
-{
- if (len > dst_len-1)
- len = dst_len-1;
- strncpy((char *)dest, (char *)src, len);
- dest[len] = '\0';
-}
-
-
-/* IE_COMPLETE */
-static void enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-
- if (complete<0 || complete>1)
- {
- printf("%s: ERROR: complete(%d) is out of range.\n", __FUNCTION__, complete);
- return;
- }
-
- if (complete)
- if (MISDN_IE_DEBG) printf(" complete=%d\n", complete);
-
- if (complete)
- {
- p = msg_put(msg, 1);
- if (nt)
- {
- *ntmode = p;
- } else
- qi->QI_ELEMENT(sending_complete) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-
- p[0] = IE_COMPLETE;
- }
-}
-
-static void dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete, int nt, struct misdn_bchannel *bc)
-{
- *complete = 0;
- if (!nt)
- {
- if (qi->QI_ELEMENT(sending_complete))
- *complete = 1;
- } else
- if (p)
- *complete = 1;
-
- if (*complete)
- if (MISDN_IE_DEBG) printf(" complete=%d\n", *complete);
-}
-
-
-/* IE_BEARER */
-static void enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (coding<0 || coding>3)
- {
- printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
- return;
- }
- if (capability<0 || capability>31)
- {
- printf("%s: ERROR: capability(%d) is out of range.\n", __FUNCTION__, capability);
- return;
- }
- if (mode<0 || mode>3)
- {
- printf("%s: ERROR: mode(%d) is out of range.\n", __FUNCTION__, mode);
- return;
- }
- if (rate<0 || rate>31)
- {
- printf("%s: ERROR: rate(%d) is out of range.\n", __FUNCTION__, rate);
- return;
- }
- if (multi>127)
- {
- printf("%s: ERROR: multi(%d) is out of range.\n", __FUNCTION__, multi);
- return;
- }
- if (user>31)
- {
- printf("%s: ERROR: user L1(%d) is out of range.\n", __FUNCTION__, rate);
- return;
- }
- if (rate!=24 && multi>=0)
- {
- printf("%s: WARNING: multi(%d) is only possible if rate(%d) would be 24.\n", __FUNCTION__, multi, rate);
- multi = -1;
- }
-
- if (MISDN_IE_DEBG) printf(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", coding, capability, mode, rate, multi, user);
-
- l = 2 + (multi>=0) + (user>=0);
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(bearer_capability) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_BEARER;
- p[1] = l;
- p[2] = 0x80 + (coding<<5) + capability;
- p[3] = 0x80 + (mode<<5) + rate;
- if (multi >= 0)
- p[4] = 0x80 + multi;
- if (user >= 0)
- p[4+(multi>=0)] = 0xa0 + user;
-}
-
-static void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user,
- int *async, int *urate, int *stopbits, int *dbits, int *parity, int nt, struct misdn_bchannel *bc)
-{
- int octet;
- *coding = -1;
- *capability = -1;
- *mode = -1;
- *rate = -1;
- *multi = -1;
- *user = -1;
- *async = -1;
- *urate = -1;
- *stopbits = -1;
- *dbits = -1;
- *parity = -1;
-
- if (!nt)
- {
- p = NULL;
-#ifdef LLC_SUPPORT
- if (qi->QI_ELEMENT(llc)) {
-
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
- }
-#endif
- if (qi->QI_ELEMENT(bearer_capability))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
- }
- if (!p)
- return;
-
- if (p[0] < 2)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *coding = (p[1]&0x60) >> 5;
- *capability = p[1] & 0x1f;
- octet = 2;
- if (!(p[1] & 0x80))
- octet++;
-
- if (p[0] < octet)
- goto done;
-
- *mode = (p[octet]&0x60) >> 5;
- *rate = p[octet] & 0x1f;
-
- octet++;
-
- if (p[0] < octet)
- goto done;
-
- if (*rate == 0x18) {
- /* Rate multiplier only present if 64Kb/s base rate */
- *multi = p[octet++] & 0x7f;
- }
-
- if (p[0] < octet)
- goto done;
-
- /* Start L1 info */
- if ((p[octet] & 0x60) == 0x20) {
- *user = p[octet] & 0x1f;
-
- if (p[0] <= octet)
- goto done;
-
- if (p[octet++] & 0x80)
- goto l2;
-
- *async = !!(p[octet] & 0x40);
- /* 0x20 is inband negotiation */
- *urate = p[octet] & 0x1f;
-
- if (p[0] <= octet)
- goto done;
-
- if (p[octet++] & 0x80)
- goto l2;
-
- /* Ignore next byte for now: Intermediate rate, NIC, flow control */
-
- if (p[0] <= octet)
- goto done;
-
- if (p[octet++] & 0x80)
- goto l2;
-
- /* And the next one. Header, multiframe, mode, assignor/ee, negotiation */
-
- if (p[0] <= octet)
- goto done;
-
- if (!p[octet++] & 0x80)
- goto l2;
-
- /* Wheee. V.110 speed information */
-
- *stopbits = (p[octet] & 0x60) >> 5;
- *dbits = (p[octet] & 0x18) >> 3;
- *parity = p[octet] & 7;
-
- octet++;
- }
- l2: /* Nobody seems to want the rest so we don't bother (yet) */
- done:
- if (MISDN_IE_DEBG) printf(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d async=%d urate=%d stopbits=%d dbits=%d parity=%d\n", *coding, *capability, *mode, *rate, *multi, *user, *async, *urate, *stopbits, *dbits, *parity);
-}
-
-
-/* IE_CALL_ID */
-#if 0
-static void enc_ie_call_id(unsigned char **ntmode, msg_t *msg, char *callid, int callid_len, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- char debug[25];
- int i;
-
- if (!callid || callid_len<=0)
- {
- return;
- }
- if (callid_len>8)
- {
- printf("%s: ERROR: callid_len(%d) is out of range.\n", __FUNCTION__, callid_len);
- return;
- }
-
- i = 0;
- while(i < callid_len)
- {
- if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", callid[i]);
- i++;
- }
-
- if (MISDN_IE_DEBG) printf(" callid%s\n", debug);
-
- l = callid_len;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(call_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CALL_ID;
- p[1] = l;
- memcpy(p+2, callid, callid_len);
-}
-#endif
-
-#if 0
-static void dec_ie_call_id(unsigned char *p, Q931_info_t *qi, char *callid, int *callid_len, int nt, struct misdn_bchannel *bc)
-{
- char debug[25];
- int i;
-
- *callid_len = -1;
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(call_id))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(call_id) + 1;
- }
- if (!p)
- return;
- if (p[0] > 8)
- {
- printf("%s: ERROR: IE too long (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *callid_len = p[0];
- memcpy(callid, p+1, *callid_len);
-
- i = 0;
- while(i < *callid_len)
- {
- if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", callid[i]);
- i++;
- }
-
- if (MISDN_IE_DEBG) printf(" callid%s\n", debug);
-}
-#endif
-
-/* IE_CALLED_PN */
-static void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, char *number, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (type<0 || type>7)
- {
- printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
- return;
- }
- if (plan<0 || plan>15)
- {
- printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
- return;
- }
- if (!number[0])
- {
- printf("%s: ERROR: number is not given.\n", __FUNCTION__);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d number='%s'\n", type, plan, number);
-
- l = 1+strlen((char *)number);
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(called_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CALLED_PN;
- p[1] = l;
- p[2] = 0x80 + (type<<4) + plan;
- strncpy((char *)p+3, (char *)number, strlen((char *)number));
-}
-
-static void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, char *number, int number_len, int nt, struct misdn_bchannel *bc)
-{
- *type = -1;
- *plan = -1;
- *number = '\0';
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(called_nr))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(called_nr) + 1;
- }
- if (!p)
- return;
- if (p[0] < 2)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *type = (p[1]&0x70) >> 4;
- *plan = p[1] & 0xf;
- strnncpy(number, (char *)p+2, p[0]-1, number_len);
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d number='%s'\n", *type, *plan, number);
-}
-
-
-/* IE_CALLING_PN */
-static void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (type<0 || type>7)
- {
- printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
- return;
- }
- if (plan<0 || plan>15)
- {
- printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
- return;
- }
- if (present>3)
- {
- printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
- return;
- }
- if (present >= 0) if (screen<0 || screen>3)
- {
- printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
-
- l = 1;
- if (number) if (number[0])
- l += strlen((char *)number);
- if (present >= 0)
- l += 1;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(calling_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CALLING_PN;
- p[1] = l;
- if (present >= 0)
- {
- p[2] = 0x00 + (type<<4) + plan;
- p[3] = 0x80 + (present<<5) + screen;
- if (number) if (number[0])
- strncpy((char *)p+4, (char *)number, strlen((char *)number));
- } else
- {
- p[2] = 0x80 + (type<<4) + plan;
- if (number) if (number[0])
- strncpy((char *)p+3, (char *)number, strlen((char *)number));
- }
-}
-
-static void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, int number_len, int nt, struct misdn_bchannel *bc)
-{
- *type = -1;
- *plan = -1;
- *present = -1;
- *screen = -1;
- *number = '\0';
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(calling_nr))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(calling_nr) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *type = (p[1]&0x70) >> 4;
- *plan = p[1] & 0xf;
- if (!(p[1] & 0x80))
- {
- if (p[0] < 2)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
- *present = (p[2]&0x60) >> 5;
- *screen = p[2] & 0x3;
- strnncpy(number, (char *)p+3, p[0]-2, number_len);
- } else
- {
- strnncpy(number, (char *)p+2, p[0]-1, number_len);
- /* SPECIAL workarround for IBT software bug */
- /* if (number[0]==0x80) */
- /* strcpy((char *)number, (char *)number+1); */
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
-}
-
-
-/* IE_CONNECTED_PN */
-static void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (type<0 || type>7)
- {
- printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
- return;
- }
- if (plan<0 || plan>15)
- {
- printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
- return;
- }
- if (present>3)
- {
- printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
- return;
- }
- if (present >= 0) if (screen<0 || screen>3)
- {
- printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
-
- l = 1;
- if (number) if (number[0])
- l += strlen((char *)number);
- if (present >= 0)
- l += 1;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(connected_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CONNECT_PN;
- p[1] = l;
- if (present >= 0)
- {
- p[2] = 0x00 + (type<<4) + plan;
- p[3] = 0x80 + (present<<5) + screen;
- if (number) if (number[0])
- strncpy((char *)p+4, (char *)number, strlen((char *)number));
- } else
- {
- p[2] = 0x80 + (type<<4) + plan;
- if (number) if (number[0])
- strncpy((char *)p+3, (char *)number, strlen((char *)number));
- }
-}
-
-static void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, int number_len, int nt, struct misdn_bchannel *bc)
-{
- *type = -1;
- *plan = -1;
- *present = -1;
- *screen = -1;
- *number = '\0';
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(connected_nr))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(connected_nr) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *type = (p[1]&0x70) >> 4;
- *plan = p[1] & 0xf;
- if (!(p[1] & 0x80))
- {
- if (p[0] < 2)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
- *present = (p[2]&0x60) >> 5;
- *screen = p[2] & 0x3;
- strnncpy(number, (char *)p+3, p[0]-2, number_len);
- } else
- {
- strnncpy(number, (char *)p+2, p[0]-1, number_len);
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
-}
-
-
-/* IE_CAUSE */
-static void enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (location<0 || location>7)
- {
- printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
- return;
- }
- if (cause<0 || cause>127)
- {
- printf("%s: ERROR: cause(%d) is out of range.\n", __FUNCTION__, cause);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" location=%d cause=%d\n", location, cause);
-
- l = 2;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CAUSE;
- p[1] = l;
- p[2] = 0x80 + location;
- p[3] = 0x80 + cause;
-}
-
-#if 0
-static void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p = msg_put(msg, 4);
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- if (ntmode)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CAUSE;
- p[1] = 2;
- p[2] = 0x80 + location;
- p[3] = 0x80 + cause;
-}
-#endif
-
-static void dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause, int nt, struct misdn_bchannel *bc)
-{
- *location = -1;
- *cause = -1;
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(cause))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(cause) + 1;
- }
- if (!p)
- return;
- if (p[0] < 2)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *location = p[1] & 0x0f;
- *cause = p[2] & 0x7f;
-
- if (MISDN_IE_DEBG) printf(" location=%d cause=%d\n", *location, *cause);
-}
-
-
-/* IE_CHANNEL_ID */
-static void enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
- struct misdn_stack *stack=get_stack_by_bc(bc);
- int pri = stack->pri;
-
- if (exclusive<0 || exclusive>1)
- {
- printf("%s: ERROR: exclusive(%d) is out of range.\n", __FUNCTION__, exclusive);
- return;
- }
- if ((channel<0 || channel>0xff)
- || (!pri && (channel>2 && channel<0xff))
- || (pri && (channel>31 && channel<0xff))
- || (pri && channel==16))
- {
- printf("%s: ERROR: channel(%d) is out of range.\n", __FUNCTION__, channel);
- return;
- }
-
- /* if (MISDN_IE_DEBG) printf(" exclusive=%d channel=%d\n", exclusive, channel); */
-
-
- if (!pri)
- {
- /* BRI */
- l = 1;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CHANNEL_ID;
- p[1] = l;
- if (channel == 0xff)
- channel = 3;
- p[2] = 0x80 + (exclusive<<3) + channel;
- /* printf(" exclusive=%d channel=%d\n", exclusive, channel); */
- } else
- {
- /* PRI */
- if (channel == 0) /* no channel */
- return; /* IE not present */
-/* if (MISDN_IE_DEBG) printf("channel = %d\n", channel); */
- if (channel == 0xff) /* any channel */
- {
- l = 1;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CHANNEL_ID;
- p[1] = l;
- p[2] = 0x80 + 0x20 + 0x03;
-/* if (MISDN_IE_DEBG) printf("%02x\n", p[2]); */
- return; /* end */
- }
- l = 3;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_CHANNEL_ID;
- p[1] = l;
- p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
- p[3] = 0x80 + 3; /* CCITT, Number, B-type */
- p[4] = 0x80 + channel;
-/* if (MISDN_IE_DEBG) printf("%02x %02x %02x\n", p[2], p[3], p[4]); */
- }
-}
-
-static void dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel, int nt, struct misdn_bchannel *bc)
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
- int pri =stack->pri;
-
- *exclusive = -1;
- *channel = -1;
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(channel_id))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(channel_id) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- if (p[1] & 0x40)
- {
- printf("%s: ERROR: refering to channels of other interfaces is not supported.\n", __FUNCTION__);
- return;
- }
- if (p[1] & 0x04)
- {
- printf("%s: ERROR: using d-channel is not supported.\n", __FUNCTION__);
- return;
- }
-
- *exclusive = (p[1]&0x08) >> 3;
- if (!pri)
- {
- /* BRI */
- if (p[1] & 0x20)
- {
- printf("%s: ERROR: extended channel ID with non PRI interface.\n", __FUNCTION__);
- return;
- }
- *channel = p[1] & 0x03;
- if (*channel == 3)
- *channel = 0xff;
- } else
- {
- /* PRI */
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short for PRI (%d).\n", __FUNCTION__, p[0]);
- return;
- }
- if (!(p[1] & 0x20))
- {
- printf("%s: ERROR: basic channel ID with PRI interface.\n", __FUNCTION__);
- return;
- }
- if ((p[1]&0x03) == 0x00)
- {
- /* no channel */
- *channel = 0;
- return;
- }
- if ((p[1]&0x03) == 0x03)
- {
- /* any channel */
- *channel = 0xff;
- return;
- }
- if (p[0] < 3)
- {
- printf("%s: ERROR: IE too short for PRI with channel(%d).\n", __FUNCTION__, p[0]);
- return;
- }
- if (p[2] & 0x10)
- {
- printf("%s: ERROR: channel map not supported.\n", __FUNCTION__);
- return;
- }
- *channel = p[3] & 0x7f;
- if ( (*channel<1) | (*channel==16) | (*channel>31))
- {
- printf("%s: ERROR: PRI interface channel out of range (%d).\n", __FUNCTION__, *channel);
- return;
- }
-/* if (MISDN_IE_DEBG) printf("%02x %02x %02x\n", p[1], p[2], p[3]); */
- }
-
- if (MISDN_IE_DEBG) printf(" exclusive=%d channel=%d\n", *exclusive, *channel);
-}
-
-
-/* IE_DATE */
-static void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- struct tm *tm;
-
- tm = localtime(&ti);
- if (!tm)
- {
- printf("%s: ERROR: gettimeofday() returned NULL.\n", __FUNCTION__);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" year=%d month=%d day=%d hour=%d minute=%d\n", tm->tm_year%100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
-
- l = 5;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(date) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_DATE;
- p[1] = l;
- p[2] = tm->tm_year % 100;
- p[3] = tm->tm_mon + 1;
- p[4] = tm->tm_mday;
- p[5] = tm->tm_hour;
- p[6] = tm->tm_min;
-}
-
-
-/* IE_DISPLAY */
-static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (!display[0])
- {
- printf("%s: ERROR: display text not given.\n", __FUNCTION__);
- return;
- }
-
- if (strlen((char *)display) > 80)
- {
- printf("%s: WARNING: display text too long (max 80 chars), cutting.\n", __FUNCTION__);
- display[80] = '\0';
- }
-
- /* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, strlen((char *)display)); */
-
- l = strlen((char *)display);
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(display) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_DISPLAY;
- p[1] = l;
- strncpy((char *)p+2, (char *)display, strlen((char *)display));
-}
-
-#if 0
-static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, int display_len, int nt, struct misdn_bchannel *bc)
-{
- *display = '\0';
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(display))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(display) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- strnncpy(display, (char *)p+1, p[0], display_len);
-
- if (MISDN_IE_DEBG) printf(" display='%s'\n", display);
-}
-#endif
-
-/* IE_KEYPAD */
-#if 1
-static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (!keypad[0])
- {
- printf("%s: ERROR: keypad info not given.\n", __FUNCTION__);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" keypad='%s'\n", keypad);
-
- l = strlen(keypad);
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(keypad) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_KEYPAD;
- p[1] = l;
- strncpy((char *)p+2, keypad, strlen(keypad));
-}
-#endif
-
-static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, int keypad_len, int nt, struct misdn_bchannel *bc)
-{
- *keypad = '\0';
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(keypad))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(keypad) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- strnncpy(keypad, (char *)p+1, p[0], keypad_len);
-
- if (MISDN_IE_DEBG) printf(" keypad='%s'\n", keypad);
-}
-
-
-/* IE_NOTIFY */
-#if 0
-static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (notify<0 || notify>0x7f)
- {
- printf("%s: ERROR: notify(%d) is out of range.\n", __FUNCTION__, notify);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" notify=%d\n", notify);
-
- l = 1;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(notify) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_NOTIFY;
- p[1] = l;
- p[2] = 0x80 + notify;
-}
-#endif
-
-#if 0
-static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
-{
- *notify = -1;
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(notify))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(notify) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *notify = p[1] & 0x7f;
-
- if (MISDN_IE_DEBG) printf(" notify=%d\n", *notify);
-}
-#endif
-
-
-/* IE_PROGRESS */
-static void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (coding<0 || coding>0x03)
- {
- printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
- return;
- }
- if (location<0 || location>0x0f)
- {
- printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
- return;
- }
- if (progress<0 || progress>0x7f)
- {
- printf("%s: ERROR: progress(%d) is out of range.\n", __FUNCTION__, progress);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", coding, location, progress);
-
- l = 2;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(progress) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_PROGRESS;
- p[1] = l;
- p[2] = 0x80 + (coding<<5) + location;
- p[3] = 0x80 + progress;
-}
-
-static void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress, int nt, struct misdn_bchannel *bc)
-{
- *coding = -1;
- *location = -1;
- //*progress = -1;
- *progress = 0;
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(progress))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(progress) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *coding = (p[1]&0x60) >> 5;
- *location = p[1] & 0x0f;
- *progress = p[2] & 0x7f;
-
- if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", *coding, *location, *progress);
-}
-
-
-/* IE_REDIR_NR (redirecting = during MT_SETUP) */
-static void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, char *number, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- if (type<0 || type>7)
- {
- printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
- return;
- }
- if (plan<0 || plan>15)
- {
- printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
- return;
- }
- if (present > 3)
- {
- printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
- return;
- }
- if (present >= 0) if (screen<0 || screen>3)
- {
- printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
- return;
- }
- if (reason > 0x0f)
- {
- printf("%s: ERROR: reason(%d) is out of range.\n", __FUNCTION__, reason);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
-
- l = 1;
- if (number)
- l += strlen((char *)number);
- if (present >= 0)
- {
- l += 1;
- if (reason >= 0)
- l += 1;
- }
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(redirect_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_REDIR_NR;
- p[1] = l;
- if (present >= 0)
- {
- if (reason >= 0)
- {
- p[2] = 0x00 + (type<<4) + plan;
- p[3] = 0x00 + (present<<5) + screen;
- p[4] = 0x80 + reason;
- if (number)
- strncpy((char *)p+5, (char *)number, strlen((char *)number));
- } else
- {
- p[2] = 0x00 + (type<<4) + plan;
- p[3] = 0x80 + (present<<5) + screen;
- if (number)
- strncpy((char *)p+4, (char *)number, strlen((char *)number));
- }
- } else
- {
- p[2] = 0x80 + (type<<4) + plan;
- if (number) if (number[0])
- strncpy((char *)p+3, (char *)number, strlen((char *)number));
- }
-}
-
-static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, int number_len, int nt, struct misdn_bchannel *bc)
-{
- *type = -1;
- *plan = -1;
- *present = -1;
- *screen = -1;
- *reason = -1;
- *number = '\0';
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(redirect_nr))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_nr) + 1;
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *type = (p[1]&0x70) >> 4;
- *plan = p[1] & 0xf;
- if (!(p[1] & 0x80))
- {
- *present = (p[2]&0x60) >> 5;
- *screen = p[2] & 0x3;
- if (!(p[2] & 0x80))
- {
- *reason = p[3] & 0x0f;
- strnncpy(number, (char *)p+4, p[0]-3, number_len);
- } else
- {
- strnncpy(number, (char *)p+3, p[0]-2, number_len);
- }
- } else
- {
- strnncpy(number, (char *)p+2, p[0]-1, number_len);
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
-}
-
-
-/* IE_REDIR_DN (redirection = during MT_NOTIFY) */
-#if 0
-static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, char *number, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
-/* Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN); */
- int l;
-
- if (type<0 || type>7)
- {
- printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
- return;
- }
- if (plan<0 || plan>15)
- {
- printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
- return;
- }
- if (present > 3)
- {
- printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
- return;
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
-
- l = 1;
- if (number)
- l += strlen((char *)number);
- if (present >= 0)
- l += 1;
- p = msg_put(msg, l+2);
- if (nt)
- *ntmode = p+1;
- else
-/* #warning REINSERT redir_dn, when included in te-mode */
- /*qi->QI_ELEMENT(redir_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t)*/;
- p[0] = IE_REDIR_DN;
- p[1] = l;
- if (present >= 0)
- {
- p[2] = 0x00 + (type<<4) + plan;
- p[3] = 0x80 + (present<<5);
- if (number)
- strncpy((char *)p+4, (char *)number, strlen((char *)number));
- } else
- {
- p[2] = 0x80 + (type<<4) + plan;
- if (number)
- strncpy((char *)p+3, (char *)number, strlen((char *)number));
- }
-}
-#endif
-
-#if 0
-static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, int number_len, int nt, struct misdn_bchannel *bc)
-{
- *type = -1;
- *plan = -1;
- *present = -1;
- *number = '\0';
-
- if (!nt)
- {
- p = NULL;
-/* #warning REINSERT redir_dn, when included in te-mode */
-/* if (qi->QI_ELEMENT(redir_dn)) */
-/* p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redir_dn) + 1; */
- }
- if (!p)
- return;
- if (p[0] < 1)
- {
- printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
- return;
- }
-
- *type = (p[1]&0x70) >> 4;
- *plan = p[1] & 0xf;
- if (!(p[1] & 0x80))
- {
- *present = (p[2]&0x60) >> 5;
- strnncpy(number, (char *)p+3, p[0]-2, number_len);
- } else
- {
- strnncpy(number, (char *)p+2, p[0]-1, number_len);
- }
-
- if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
-}
-#endif
-
-
-/* IE_USERUSER */
-#if 1
-static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, char *user, int user_len, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- int l;
-
- char debug[768];
- int i;
-
- if (protocol<0 || protocol>127)
- {
- printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
- return;
- }
- if (!user || user_len<=0)
- {
- return;
- }
-
- i = 0;
- while(i < user_len)
- {
- if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", user[i]);
- i++;
- }
-
- if (MISDN_IE_DEBG) printf(" protocol=%d user-user%s\n", protocol, debug);
-
- l = user_len+1;
- p = msg_put(msg, l+3);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(useruser) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_USER_USER;
- p[1] = l;
- p[2] = protocol;
- memcpy(p+3, user, user_len);
-}
-#endif
-
-#if 1
-static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, char *user, int *user_len, int nt, struct misdn_bchannel *bc)
-{
- char debug[768];
- int i;
-
- *user_len = 0;
- *protocol = -1;
-
- if (!nt)
- {
- p = NULL;
- if (qi->QI_ELEMENT(useruser))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(useruser) + 1;
- }
- if (!p)
- return;
-
- *user_len = p[0]-1;
- if (p[0] < 1)
- return;
- *protocol = p[1];
- memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
-
- i = 0;
- while(i < *user_len)
- {
- if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", user[i]);
- i++;
- }
- debug[i*3] = '\0';
-
- if (MISDN_IE_DEBG) printf(" protocol=%d user-user%s\n", *protocol, debug);
-}
-#endif
-
-/* IE_DISPLAY */
-static void enc_ie_restart_ind(unsigned char **ntmode, msg_t *msg, unsigned char rind, int nt, struct misdn_bchannel *bc)
-{
- unsigned char *p;
- Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- /* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, strlen((char *)display)); */
-
- p = msg_put(msg, 3);
- if (nt)
- *ntmode = p+1;
- else
- qi->QI_ELEMENT(restart_ind) = p - (unsigned char *)qi - sizeof(Q931_info_t);
- p[0] = IE_RESTART_IND;
- p[1] = 1;
- p[2] = rind;
-
-}
-
diff --git a/1.4/channels/misdn/isdn_lib.c b/1.4/channels/misdn/isdn_lib.c
deleted file mode 100644
index 64b92f66a..000000000
--- a/1.4/channels/misdn/isdn_lib.c
+++ /dev/null
@@ -1,4574 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-
-#include <syslog.h>
-#include <mISDNuser/isdn_debug.h>
-
-#include "isdn_lib_intern.h"
-#include "isdn_lib.h"
-
-void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
-void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
-
-int queue_cleanup_bc(struct misdn_bchannel *bc) ;
-
-int misdn_lib_get_l2_up(struct misdn_stack *stack);
-
-struct misdn_stack* get_misdn_stack( void );
-
-static int set_chan_in_stack(struct misdn_stack *stack, int channel);
-
-int release_cr(struct misdn_stack *stack, mISDNuser_head_t *hh);
-
-int misdn_lib_port_is_pri(int port)
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) {
- return stack->pri;
- }
- }
-
- return -1;
-}
-
-static void make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
-{
- memset (dummybc,0,sizeof(struct misdn_bchannel));
- dummybc->port=port;
- dummybc->l3_id=l3id;
- dummybc->nt=nt;
- dummybc->dummy=1;
- dummybc->channel=channel;
-}
-
-int misdn_lib_port_block(int port)
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) {
- stack->blocked=1;
- return 0;
- }
- }
- return -1;
-
-}
-
-int misdn_lib_port_unblock(int port)
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) {
- stack->blocked=0;
- return 0;
- }
- }
- return -1;
-
-}
-
-int misdn_lib_is_port_blocked(int port)
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) {
- return stack->blocked;
- }
- }
- return -1;
-}
-
-int misdn_lib_is_ptp(int port)
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) return stack->ptp;
- }
- return -1;
-}
-
-int misdn_lib_get_maxchans(int port)
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) {
- if (stack->pri)
- return 30;
- else
- return 2;
- }
- }
- return -1;
-}
-
-
-struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc)
-{
- struct misdn_stack *stack=get_misdn_stack();
-
- if (!bc) return NULL;
-
- for ( ; stack; stack=stack->next) {
- int i;
- for (i=0; i <=stack->b_num; i++) {
- if ( bc->port == stack->port) return stack;
- }
- }
-
- return NULL;
-}
-
-
-void get_show_stack_details(int port, char *buf)
-{
- struct misdn_stack *stack=get_misdn_stack();
-
- for ( ; stack; stack=stack->next) {
- if (stack->port == port) break;
- }
-
- if (stack) {
- sprintf(buf, "* Port %d Type %s Prot. %s L2Link %s L1Link:%s Blocked:%d", stack->port, stack->nt?"NT":"TE", stack->ptp?"PTP":"PMP", stack->l2link?"UP":"DOWN", stack->l1link?"UP":"DOWN",stack->blocked);
-
- } else {
- buf[0]=0;
- }
-
-}
-
-
-static int nt_err_cnt =0 ;
-
-enum global_states {
- MISDN_INITIALIZING,
- MISDN_INITIALIZED
-} ;
-
-static enum global_states global_state=MISDN_INITIALIZING;
-
-
-#include <mISDNuser/net_l2.h>
-#include <mISDNuser/tone.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "isdn_lib.h"
-
-
-struct misdn_lib {
- int midev;
- int midev_nt;
-
- pthread_t event_thread;
- pthread_t event_handler_thread;
-
- void *user_data;
-
- msg_queue_t upqueue;
- msg_queue_t activatequeue;
-
- sem_t new_msg;
-
- struct misdn_stack *stack_list;
-} ;
-
-#ifndef ECHOCAN_ON
-#define ECHOCAN_ON 123
-#define ECHOCAN_OFF 124
-#endif
-
-#define MISDN_DEBUG 0
-
-void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
-
-struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
-
-struct misdn_bchannel *find_bc_by_confid(unsigned long confid);
-
-struct misdn_bchannel *stack_holder_find_bychan(struct misdn_stack *stack, int chan);
-
-int setup_bc(struct misdn_bchannel *bc);
-
-int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
-
-int misdn_lib_port_restart(int port);
-int misdn_lib_pid_restart(int pid);
-
-extern struct isdn_msg msgs_g[];
-
-#define ISDN_PID_L3_B_USER 0x430000ff
-#define ISDN_PID_L4_B_USER 0x440000ff
-
-/* #define MISDN_IBUF_SIZE 1024 */
-#define MISDN_IBUF_SIZE 512
-
-/* Fine Tuning of Inband Signalling time */
-#define TONE_ALERT_CNT 41 /* 1 Sec */
-#define TONE_ALERT_SILENCE_CNT 200 /* 4 Sec */
-
-#define TONE_BUSY_CNT 20 /* ? */
-#define TONE_BUSY_SILENCE_CNT 48 /* ? */
-
-static int entity;
-
-static struct misdn_lib *glob_mgr;
-
-char tone_425_flip[TONE_425_SIZE];
-char tone_silence_flip[TONE_SILENCE_SIZE];
-
-static void misdn_lib_isdn_event_catcher(void *arg);
-static int handle_event_nt(void *dat, void *arg);
-
-
-void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder);
-void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder);
-struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id);
-
-/* from isdn_lib.h */
-int init_bc(struct misdn_stack * stack, struct misdn_bchannel *bc, int midev, int port, int bidx, char *msn, int firsttime);
-struct misdn_stack* stack_init(int midev, int port, int ptp);
-void stack_destroy(struct misdn_stack* stack);
- /* user iface */
-int te_lib_init( void ) ; /* returns midev */
-void te_lib_destroy(int midev) ;
-struct misdn_bchannel *manager_find_bc_by_pid(int pid);
-struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc);
-void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len);
-void manager_clean_bc(struct misdn_bchannel *bc );
-void manager_bchannel_setup (struct misdn_bchannel *bc);
-void manager_bchannel_cleanup (struct misdn_bchannel *bc);
-
-void ec_chunk( struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size);
- /* end */
-int bchdev_echocancel_activate(struct misdn_bchannel* dev);
-void bchdev_echocancel_deactivate(struct misdn_bchannel* dev);
-/* end */
-
-
-static char *bearer2str(int cap) {
- static char *bearers[]={
- "Speech",
- "Audio 3.1k",
- "Unres Digital",
- "Res Digital",
- "Unknown Bearer"
- };
-
- switch (cap) {
- case INFO_CAPABILITY_SPEECH:
- return bearers[0];
- break;
- case INFO_CAPABILITY_AUDIO_3_1K:
- return bearers[1];
- break;
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
- return bearers[2];
- break;
- case INFO_CAPABILITY_DIGITAL_RESTRICTED:
- return bearers[3];
- break;
- default:
- return bearers[4];
- break;
- }
-}
-
-
-static char flip_table[256];
-
-static void init_flip_bits(void)
-{
- int i,k;
-
- for (i = 0 ; i < 256 ; i++) {
- unsigned char sample = 0 ;
- for (k = 0; k<8; k++) {
- if ( i & 1 << k ) sample |= 0x80 >> k;
- }
- flip_table[i] = sample;
- }
-}
-
-static char * flip_buf_bits ( char * buf , int len)
-{
- int i;
- char * start = buf;
-
- for (i = 0 ; i < len; i++) {
- buf[i] = flip_table[(unsigned char)buf[i]];
- }
-
- return start;
-}
-
-
-
-
-static msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
-{
- int i = 0;
- msg_t *dmsg;
-
- while(i < 10)
- {
- dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
- if (dmsg)
- return(dmsg);
-
- if (!i)
- printf("cannot allocate memory, trying again...\n");
- i++;
- usleep(300000);
- }
- printf("cannot allocate memory, system overloaded.\n");
- exit(-1);
-}
-
-
-
-msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
-{
- int i = 0;
- msg_t *dmsg;
- Q931_info_t *qi;
- iframe_t *frm;
-
- if (!ntmode)
- size = sizeof(Q931_info_t)+2;
-
- while(i < 10) {
- if (ntmode) {
- dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
- if (dmsg) {
- return(dmsg);
- }
- } else {
- dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
- if (dmsg)
- {
- memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
- frm = (iframe_t *)dmsg->data;
- frm->prim = prim;
- frm->dinfo = dinfo;
- qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
- qi->type = mt;
- return(dmsg);
- }
- }
-
- if (!i) printf("cannot allocate memory, trying again...\n");
- i++;
- usleep(300000);
- }
- printf("cannot allocate memory, system overloaded.\n");
- exit(-1);
-}
-
-
-static int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
-{
- struct misdn_stack *stack;
- iframe_t *frm;
- frm = (iframe_t *)dmsg->data;
- stack=get_stack_by_bc(bc);
-
- if (!stack) {
- cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
- return -1;
- }
-
- frm->addr = (stack->upper_id | FLG_MSG_DOWN);
- frm->dinfo = bc->l3_id;
- frm->len = (dmsg->len) - mISDN_HEADER_LEN;
-
- cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
-
- mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
- free_msg(dmsg);
-
- return 0;
-}
-
-
-static int mypid=1;
-
-
-int misdn_cap_is_speech(int cap)
-/** Poor mans version **/
-{
- if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
- (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
- return 0;
-}
-
-int misdn_inband_avail(struct misdn_bchannel *bc)
-{
-
- /*if ! early_bconnect we have never inband available*/
- if ( ! bc->early_bconnect ) return 0;
-
- switch (bc->progress_indicator) {
- case INFO_PI_INBAND_AVAILABLE:
- case INFO_PI_CALL_NOT_E2E_ISDN:
- case INFO_PI_CALLED_NOT_ISDN:
- return 1;
- default:
- return 0;
- }
- return 0;
-}
-
-
-static void dump_chan_list(struct misdn_stack *stack)
-{
- int i;
-
- for (i=0; i <= stack->b_num; i++) {
- cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",i,stack->channels[i], stack->bc[i].in_use, i+1);
- }
-}
-
-
-void misdn_dump_chanlist()
-{
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- dump_chan_list(stack);
- }
-
-}
-
-int set_chan_in_stack(struct misdn_stack *stack, int channel)
-{
-
- cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
- dump_chan_list(stack);
- if (channel >=1 && channel <= MAX_BCHANS) {
- if (!stack->channels[channel-1])
- stack->channels[channel-1] = 1;
- else {
- cb_log(4,stack->port,"channel already in use:%d\n", channel );
- return -1;
- }
- } else {
- cb_log(0,stack->port,"couldn't set channel %d in\n", channel );
- return -1;
- }
-
- return 0;
-}
-
-
-
-static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec)
-{
- int i;
- int bnums;
- int chan=0;
-
- if (bc->channel_found)
- return 0;
-
- bc->channel_found=1;
-
- cb_log(5,stack->port,"find_free_chan: req_chan:%d\n",channel);
-
-
- if (channel < 0 || channel > MAX_BCHANS) {
- cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
- return 0;
- }
-
- channel--;
-
- bnums=stack->pri?stack->b_num:stack->b_num-1;
-
- if (dec) {
- for (i = bnums; i >=0; i--) {
- if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */
- if (!stack->channels[i]) {
- cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
- chan=i+1;
- break;
- }
- }
- }
- } else {
- for (i = 0; i <= bnums; i++) {
- if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */
- if (!stack->channels[i]) {
- cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
- chan=i+1;
- break;
- }
- }
- }
- }
-
- if (!chan) {
- cb_log (1, stack->port, " !! NO FREE CHAN IN STACK\n");
- dump_chan_list(stack);
- bc->out_cause=34;
- return -1;
- }
-
- if (set_chan_in_stack(stack, chan)<0) {
- cb_log (0, stack->port, "Channel Already in use:%d\n", chan);
- bc->out_cause=44;
- return -1;
- }
-
- bc->channel=chan;
- return 0;
-}
-
-static int empty_chan_in_stack(struct misdn_stack *stack, int channel)
-{
- if (channel<=0 || channel>MAX_BCHANS) {
- cb_log(0,stack?stack->port:0, "empty_chan_in_stack: cannot empty channel %d\n",channel);
- return -1;
- }
-
- cb_log (4, stack?stack->port:0, "empty_chan_in_stack: %d\n",channel);
- stack->channels[channel-1] = 0;
- dump_chan_list(stack);
- return 0;
-}
-
-char *bc_state2str(enum bchannel_state state) {
- int i;
-
- struct bchan_state_s {
- char *n;
- enum bchannel_state s;
- } states[] = {
- {"BCHAN_CLEANED", BCHAN_CLEANED },
- {"BCHAN_EMPTY", BCHAN_EMPTY},
- {"BCHAN_SETUP", BCHAN_SETUP},
- {"BCHAN_SETUPED", BCHAN_SETUPED},
- {"BCHAN_ACTIVE", BCHAN_ACTIVE},
- {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
- {"BCHAN_BRIDGE", BCHAN_BRIDGE},
- {"BCHAN_BRIDGED", BCHAN_BRIDGED},
- {"BCHAN_RELEASE", BCHAN_RELEASE},
- {"BCHAN_RELEASED", BCHAN_RELEASED},
- {"BCHAN_CLEAN", BCHAN_CLEAN},
- {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
- {"BCHAN_ERROR", BCHAN_ERROR}
- };
-
- for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
- if ( states[i].s == state)
- return states[i].n;
-
- return "UNKNOWN";
-}
-
-void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
-{
- cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
- bc->l3_id,
- bc_state2str(bc->bc_state),
- bc_state2str(state) );
-
- switch (state) {
- case BCHAN_ACTIVATED:
- if (bc->next_bc_state == BCHAN_BRIDGED) {
- misdn_join_conf(bc, bc->conf_id);
- bc->next_bc_state = BCHAN_EMPTY;
- return;
- }
- default:
- bc->bc_state=state;
- break;
- }
-}
-
-static void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
-{
- cb_log(5,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
- bc_state2str(bc->next_bc_state),
- bc_state2str(state) );
-
- bc->next_bc_state=state;
-}
-
-
-static void empty_bc(struct misdn_bchannel *bc)
-{
- bc->dummy=0;
-
- bc->bframe_len=0;
-
- bc->cw= 0;
-
- bc->dec=0;
- bc->channel = 0;
-
- bc->sending_complete = 0;
-
- bc->restart_channel=0;
-
- bc->conf_id = 0;
-
- bc->need_more_infos = 0;
-
- bc->send_dtmf=0;
- bc->nodsp=0;
- bc->nojitter=0;
-
- bc->time_usec=0;
-
- bc->rxgain=0;
- bc->txgain=0;
-
- bc->crypt=0;
- bc->curptx=0; bc->curprx=0;
-
- bc->crypt_key[0] = 0;
-
- bc->generate_tone=0;
- bc->tone_cnt=0;
-
- bc->dnumplan=NUMPLAN_UNKNOWN;
- bc->onumplan=NUMPLAN_UNKNOWN;
- bc->rnumplan=NUMPLAN_UNKNOWN;
- bc->cpnnumplan=NUMPLAN_UNKNOWN;
-
-
- bc->active = 0;
-
- bc->early_bconnect = 1;
-
-#ifdef MISDN_1_2
- *bc->pipeline = 0;
-#else
- bc->ec_enable = 0;
- bc->ec_deftaps = 128;
-#endif
-
- bc->orig=0;
-
- bc->cause=16;
- bc->out_cause=16;
- bc->pres=0 ; /* screened */
-
- bc->evq=EVENT_NOTHING;
-
- bc->progress_coding=0;
- bc->progress_location=0;
- bc->progress_indicator=0;
-
-/** Set Default Bearer Caps **/
- bc->capability=INFO_CAPABILITY_SPEECH;
- bc->law=INFO_CODEC_ALAW;
- bc->mode=0;
- bc->rate=0x10;
- bc->user1=0;
- bc->urate=0;
-
- bc->hdlc=0;
-
-
- bc->info_dad[0] = 0;
- bc->display[0] = 0;
- bc->infos_pending[0] = 0;
- bc->cad[0] = 0;
- bc->oad[0] = 0;
- bc->dad[0] = 0;
- bc->rad[0] = 0;
- bc->orig_dad[0] = 0;
- bc->uu[0]=0;
- bc->uulen=0;
-
- bc->fac_in.Function = Fac_None;
- bc->fac_out.Function = Fac_None;
-
- bc->te_choose_channel = 0;
- bc->channel_found= 0;
-}
-
-
-static int clean_up_bc(struct misdn_bchannel *bc)
-{
- int ret=0;
- unsigned char buff[32];
- struct misdn_stack * stack;
-
- cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
-
- if (!bc ) return -1;
- stack=get_stack_by_bc(bc);
-
- if (!stack) return -1;
-
- switch (bc->bc_state ) {
- case BCHAN_CLEANED:
- cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
- return -1;
-
- default:
- break;
- }
-
- cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
-
- manager_ec_disable(bc);
-
- manager_bchannel_deactivate(bc);
-
- mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
- bc->b_stid = 0;
- bc_state_change(bc, BCHAN_CLEANED);
-
- return ret;
-}
-
-
-
-static void clear_l3(struct misdn_stack *stack)
-{
- int i;
-
- for (i=0; i<=stack->b_num; i++) {
- if (global_state == MISDN_INITIALIZED) {
- cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
- empty_chan_in_stack(stack,i+1);
- empty_bc(&stack->bc[i]);
- clean_up_bc(&stack->bc[i]);
- stack->bc[i].in_use = 0;
- }
-
- }
-}
-
-static int newteid=0;
-
-#define MAXPROCS 0x100
-
-static int misdn_lib_get_l1_down(struct misdn_stack *stack)
-{
- /* Pull Up L1 */
- iframe_t act;
- act.prim = PH_DEACTIVATE | REQUEST;
- act.addr = stack->lower_id|FLG_MSG_DOWN;
- act.dinfo = 0;
- act.len = 0;
-
- cb_log(1, stack->port, "SENDING PH_DEACTIVATE | REQ\n");
- return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
-
-
-static int misdn_lib_get_l2_down(struct misdn_stack *stack)
-{
-
- if (stack->ptp && (stack->nt) ) {
- msg_t *dmsg;
- /* L2 */
- dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
-
- if (stack->nst.manager_l3(&stack->nst, dmsg))
- free_msg(dmsg);
-
- } else {
- iframe_t act;
-
- act.prim = DL_RELEASE| REQUEST;
- act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
-
- act.dinfo = 0;
- act.len = 0;
- return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
- }
-
- return 0;
-}
-
-
-static int misdn_lib_get_l1_up(struct misdn_stack *stack)
-{
- /* Pull Up L1 */
- iframe_t act;
- act.prim = PH_ACTIVATE | REQUEST;
- act.addr = (stack->upper_id | FLG_MSG_DOWN) ;
-
-
- act.dinfo = 0;
- act.len = 0;
-
- return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-
-}
-
-int misdn_lib_get_l2_up(struct misdn_stack *stack)
-{
-
- if (stack->ptp && (stack->nt) ) {
- msg_t *dmsg;
- /* L2 */
- dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
-
- if (stack->nst.manager_l3(&stack->nst, dmsg))
- free_msg(dmsg);
-
- } else {
- iframe_t act;
-
- act.prim = DL_ESTABLISH | REQUEST;
- act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
-
- act.dinfo = 0;
- act.len = 0;
- return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
- }
-
- return 0;
-}
-
-#if 0
-static int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
-{
- iframe_t act;
-
- act.prim = DL_ESTABLISH | REQUEST;
- act.addr = (stack->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
-
- act.dinfo = 0;
- act.len = 0;
- return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
- return 0;
-}
-#endif
-
-static int misdn_lib_get_short_status(struct misdn_stack *stack)
-{
- iframe_t act;
-
-
- act.prim = MGR_SHORTSTATUS | REQUEST;
-
- act.addr = (stack->upper_id | MSG_BROADCAST) ;
-
- act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
-
- act.len = 0;
- return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
-
-
-
-static int create_process (int midev, struct misdn_bchannel *bc) {
- iframe_t ncr;
- int l3_id;
- int i;
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- if (stack->nt) {
- if (find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0, 0)<0) return -1;
- cb_log(4,stack->port, " --> found channel: %d\n",bc->channel);
-
- for (i=0; i <= MAXPROCS; i++)
- if (stack->procids[i]==0) break;
-
- if (i== MAXPROCS) {
- cb_log(0, stack->port, "Couldnt Create New ProcId.\n");
- return -1;
- }
- stack->procids[i]=1;
-
- l3_id = 0xff00 | i;
-
- ncr.prim = CC_NEW_CR | REQUEST;
-
- ncr.addr = (stack->upper_id | FLG_MSG_DOWN) ;
-
- ncr.dinfo = l3_id;
- ncr.len = 0;
-
- bc->l3_id = l3_id;
- cb_log(3, stack->port, " --> new_l3id %x\n",l3_id);
-
- } else {
- if (stack->ptp || bc->te_choose_channel) {
- /* we know exactly which channels are in use */
- if (find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0, bc->dec)<0) return -1;
- cb_log(2,stack->port, " --> found channel: %d\n",bc->channel);
- } else {
- /* other phones could have made a call also on this port (ptmp) */
- bc->channel=0xff;
- }
-
-
- /* if we are in te-mode, we need to create a process first */
- if (newteid++ > 0xffff)
- newteid = 0x0001;
-
- l3_id = (entity<<16) | newteid;
- /* preparing message */
- ncr.prim = CC_NEW_CR | REQUEST;
-
- ncr.addr = (stack->upper_id | FLG_MSG_DOWN) ;
-
- ncr.dinfo =l3_id;
- ncr.len = 0;
- /* send message */
-
- bc->l3_id = l3_id;
- cb_log(3, stack->port, "--> new_l3id %x\n",l3_id);
-
- mISDN_write(midev, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC);
- }
-
- return l3_id;
-}
-
-
-void misdn_lib_setup_bc(struct misdn_bchannel *bc)
-{
- clean_up_bc(bc);
- setup_bc(bc);
-}
-
-
-int setup_bc(struct misdn_bchannel *bc)
-{
- unsigned char buff[1025];
- int midev, i;
- int channel;
- int b_stid;
-
- mISDN_pid_t pid;
- int ret;
-
-
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- if (!stack) {
- cb_log(0, bc->port, "setup_bc: NO STACK FOUND!!\n");
- return -1;
- }
-
- midev=stack->midev;
- channel=bc->channel-1-(bc->channel>16);
- b_stid=stack->b_stids[channel>=0?channel:0];
-
-
- switch (bc->bc_state) {
- case BCHAN_CLEANED:
- break;
- default:
- cb_log(4, stack->port, "$$$ bc already upsetted stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
- return -1;
- }
-
- cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
-
- /*check if the b_stid is alread initialized*/
- for (i=0; i <= stack->b_num; i++) {
- if (stack->bc[i].b_stid == b_stid) {
- cb_log(0, bc->port, "setup_bc: b_stid:%x already in use !!!\n", b_stid);
- return -1;
- }
- }
-
- if (b_stid <= 0) {
- cb_log(0, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
-
- bc_state_change(bc,BCHAN_ERROR);
- return 1;
- }
-
-
- bc->b_stid = b_stid;
-
- {
- layer_info_t li;
- memset(&li, 0, sizeof(li));
-
- li.object_id = -1;
- li.extentions = 0;
-
- li.st = bc->b_stid; /* given idx */
-
-
-#define MISDN_DSP
-#ifndef MISDN_DSP
- bc->nodsp=1;
-#endif
- if ( bc->hdlc || bc->nodsp) {
- cb_log(4, stack->port,"setup_bc: without dsp\n");
- {
- int l = sizeof(li.name);
- strncpy(li.name, "B L3", l);
- li.name[l-1] = 0;
- }
- li.pid.layermask = ISDN_LAYER((3));
- li.pid.protocol[3] = ISDN_PID_L3_B_USER;
-
- bc->layer=3;
- } else {
- cb_log(4, stack->port,"setup_bc: with dsp\n");
- {
- int l = sizeof(li.name);
- strncpy(li.name, "B L4", l);
- li.name[l-1] = 0;
- }
- li.pid.layermask = ISDN_LAYER((4));
- li.pid.protocol[4] = ISDN_PID_L4_B_USER
-;
- bc->layer=4;
-
- }
-
- ret = mISDN_new_layer(midev, &li);
- if (ret ) {
- cb_log(0, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
-
- bc_state_change(bc,BCHAN_ERROR);
- return(-EINVAL);
- }
-
- bc->layer_id = li.id;
- }
-
- memset(&pid, 0, sizeof(pid));
-
-
-
- cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
-
- if (bc->nodsp) {
- cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
- pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
- pid.protocol[2] = ISDN_PID_L2_B_TRANS;
- pid.protocol[3] = ISDN_PID_L3_B_USER;
- pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
-
- } else if ( bc->hdlc ) {
- cb_log(2, stack->port," --> HDLC Mode\n");
- pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
- pid.protocol[2] = ISDN_PID_L2_B_TRANS ;
- pid.protocol[3] = ISDN_PID_L3_B_USER;
- pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
- } else {
- cb_log(2, stack->port," --> TRANSPARENT Mode\n");
- pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
- pid.protocol[2] = ISDN_PID_L2_B_TRANS;
- pid.protocol[3] = ISDN_PID_L3_B_DSP;
- pid.protocol[4] = ISDN_PID_L4_B_USER;
- pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
-
- }
-
- ret = mISDN_set_stack(midev, bc->b_stid, &pid);
-
- if (ret){
- cb_log(0, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
-
- mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
- bc_state_change(bc,BCHAN_ERROR);
- cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
- return(-EINVAL);
- }
-
- ret = mISDN_get_setstack_ind(midev, bc->layer_id);
-
- if (ret) {
- cb_log(0, stack->port,"$$$ Set StackIND Err: %d %s\n",ret,strerror(errno));
- mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
- bc_state_change(bc,BCHAN_ERROR);
- cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
- return(-EINVAL);
- }
-
- ret = mISDN_get_layerid(midev, bc->b_stid, bc->layer) ;
-
- bc->addr = ret>0? ret : 0;
-
- if (!bc->addr) {
- cb_log(0, stack->port,"$$$ Get Layerid Err: %d %s\n",ret,strerror(errno));
- mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
- bc_state_change(bc,BCHAN_ERROR);
- cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
- return (-EINVAL);
- }
-
- manager_bchannel_activate(bc);
-
- bc_state_change(bc,BCHAN_ACTIVATED);
-
- return 0;
-}
-
-
-
-/** IFACE **/
-int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, int port, int bidx, char *msn, int firsttime)
-{
- unsigned char buff[1025] = "";
- iframe_t *frm = (iframe_t *)buff;
- int ret;
-
- if (!bc) return -1;
-
- cb_log(8, port, "Init.BC %d.\n",bidx);
-
- memset(bc, 0,sizeof(struct misdn_bchannel));
-
- bc->send_lock=malloc(sizeof(struct send_lock));
-
- pthread_mutex_init(&bc->send_lock->lock, NULL);
-
- if (msn) {
- int l = sizeof(bc->msn);
- strncpy(bc->msn,msn, l);
- bc->msn[l-1] = 0;
- }
-
-
- empty_bc(bc);
- bc_state_change(bc, BCHAN_CLEANED);
-
- bc->port=stack->port;
- bc->nt=stack->nt?1:0;
- bc->pri=stack->pri;
-
- {
- ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE);
-
- if (!ibuf) return -1;
-
- clear_ibuffer( ibuf);
-
- ibuf->rsem=malloc(sizeof(sem_t));
-
- bc->astbuf=ibuf;
-
- if (sem_init(ibuf->rsem,1,0)<0)
- sem_init(ibuf->rsem,0,0);
-
- }
-
- {
- stack_info_t *stinf;
- ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff));
- if (ret < 0) {
- cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
- return -1;
- }
-
- stinf = (stack_info_t *)&frm->data.p;
-
- cb_log(8, port, " --> Child %x\n",stinf->child[bidx]);
- }
-
- return 0;
-}
-
-
-
-struct misdn_stack* stack_init( int midev, int port, int ptp )
-{
- int ret;
- unsigned char buff[1025];
- iframe_t *frm = (iframe_t *)buff;
- stack_info_t *stinf;
- int i;
- layer_info_t li;
-
- struct misdn_stack *stack = malloc(sizeof(struct misdn_stack));
- if (!stack ) return NULL;
-
-
- cb_log(8, port, "Init. Stack.\n");
-
- memset(stack,0,sizeof(struct misdn_stack));
-
- for (i=0; i<MAX_BCHANS + 1; i++ ) stack->channels[i]=0;
-
- stack->port=port;
- stack->midev=midev;
- stack->ptp=ptp;
-
- stack->holding=NULL;
- stack->pri=0;
-
- msg_queue_init(&stack->downqueue);
- msg_queue_init(&stack->upqueue);
-
- /* query port's requirements */
- ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
- if (ret < 0) {
- cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
- return(NULL);
- }
-
- stinf = (stack_info_t *)&frm->data.p;
-
- stack->d_stid = stinf->id;
- stack->b_num = stinf->childcnt;
-
- for (i=0; i<=stinf->childcnt; i++)
- stack->b_stids[i] = stinf->child[i];
-
- switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
- case ISDN_PID_L0_TE_S0:
- stack->nt=0;
- break;
- case ISDN_PID_L0_NT_S0:
- cb_log(8, port, "NT Stack\n");
-
- stack->nt=1;
- break;
- case ISDN_PID_L0_TE_E1:
- cb_log(8, port, "TE S2M Stack\n");
- stack->nt=0;
- stack->pri=1;
- break;
- case ISDN_PID_L0_NT_E1:
- cb_log(8, port, "TE S2M Stack\n");
- stack->nt=1;
- stack->pri=1;
-
- break;
- default:
- cb_log(0, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
-
- }
-
- if (!stack->nt) {
- if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) {
- stack->ptp = 1;
- } else {
- stack->ptp = 0;
- }
- }
-
- {
- int ret;
- int nt=stack->nt;
-
- cb_log(8, port, "Init. Stack.\n");
-
- memset(&li, 0, sizeof(li));
- {
- int l = sizeof(li.name);
- strncpy(li.name,nt?"net l2":"user l4", l);
- li.name[l-1] = 0;
- }
- li.object_id = -1;
- li.extentions = 0;
- li.pid.protocol[nt?2:4] = nt?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
- li.pid.layermask = ISDN_LAYER((nt?2:4));
- li.st = stack->d_stid;
-
-
- ret = mISDN_new_layer(midev, &li);
- if (ret) {
- cb_log(0, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
- return(NULL);
- }
-
-
- stack->upper_id = li.id;
- ret = mISDN_register_layer(midev, stack->d_stid, stack->upper_id);
- if (ret)
- {
- cb_log(0,port,"Cannot register layer %d of this port.\n", nt?2:4);
- return(NULL);
- }
-
- stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3);
- if (stack->lower_id < 0) {
- cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
- return(NULL);
- }
-
- stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
- if (stack->upper_id < 0) {
- cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, 2);
- return(NULL);
- }
-
- cb_log(8, port, "NT Stacks upper_id %x\n",stack->upper_id);
-
-
- /* create nst (nt-mode only) */
- if (nt) {
-
- memset(&stack->nst, 0, sizeof(net_stack_t));
- memset(&stack->mgr, 0, sizeof(manager_t));
-
- stack->mgr.nst = &stack->nst;
- stack->nst.manager = &stack->mgr;
-
- stack->nst.l3_manager = handle_event_nt;
- stack->nst.device = midev;
- stack->nst.cardnr = port;
- stack->nst.d_stid = stack->d_stid;
-
- stack->nst.feature = FEATURE_NET_HOLD;
- if (stack->ptp)
- stack->nst.feature |= FEATURE_NET_PTP;
- if (stack->pri)
- stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
-
- stack->nst.l1_id = stack->lower_id;
- stack->nst.l2_id = stack->upper_id;
-
- msg_queue_init(&stack->nst.down_queue);
-
- Isdnl2Init(&stack->nst);
- Isdnl3Init(&stack->nst);
-
- }
-
- if (!stack->nt) {
- /*assume L1 is up, we'll get DEACTIVATES soon, for non
- * up L1s*/
- stack->l1link=0;
- }
- stack->l1link=0;
- stack->l2link=0;
-#if 0
- if (!stack->nt) {
- misdn_lib_get_short_status(stack);
- } else {
- misdn_lib_get_l1_up(stack);
- if (!stack->ptp) misdn_lib_get_l1_up(stack);
- misdn_lib_get_l2_up(stack);
- }
-#endif
-
- misdn_lib_get_short_status(stack);
- misdn_lib_get_l1_up(stack);
- misdn_lib_get_l2_up(stack);
-
- }
-
- cb_log(8,0,"stack_init: port:%d lowerId:%x upperId:%x\n",stack->port,stack->lower_id, stack->upper_id);
-
- return stack;
-}
-
-
-void stack_destroy(struct misdn_stack* stack)
-{
- char buf[1024];
- if (!stack) return;
-
- if (stack->nt) {
- cleanup_Isdnl2(&stack->nst);
- cleanup_Isdnl3(&stack->nst);
- }
-
- if (stack->lower_id)
- mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
- if (stack->upper_id)
- mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-}
-
-
-static struct misdn_stack * find_stack_by_addr(int addr)
-{
- struct misdn_stack *stack;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
- if ( (stack->upper_id&STACK_ID_MASK) == (addr&STACK_ID_MASK)) return stack;
-
- }
-
- return NULL;
-}
-
-
-static struct misdn_stack * find_stack_by_port(int port)
-{
- struct misdn_stack *stack;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next)
- if (stack->port == port) return stack;
-
- return NULL;
-}
-
-static struct misdn_stack * find_stack_by_mgr(manager_t* mgr_nt)
-{
- struct misdn_stack *stack;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next)
- if ( &stack->mgr == mgr_nt) return stack;
-
- return NULL;
-}
-
-static struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
-{
- int i;
- for (i=0; i<=stack->b_num; i++) {
- if ( (stack->bc[i].l3_id & mask) == (l3id & mask)) return &stack->bc[i] ;
- }
- return stack_holder_find(stack,l3id);
-}
-
-
-struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id)
-{
- int i;
- for (i=0; i<=stack->b_num; i++) {
- if (stack->bc[i].l3_id == l3id) return &stack->bc[i] ;
- }
- return stack_holder_find(stack,l3id);
-}
-
-static struct misdn_bchannel *find_bc_holded(struct misdn_stack *stack)
-{
- int i;
- for (i=0; i<=stack->b_num; i++) {
- if (stack->bc[i].holded ) return &stack->bc[i] ;
- }
- return NULL;
-}
-
-
-static struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
-{
- struct misdn_stack* stack;
- int i;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
- for (i=0; i<=stack->b_num; i++) {
- if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) || stack->bc[i].layer_id== addr ) {
- return &stack->bc[i];
- }
- }
- }
-
- return NULL;
-}
-
-struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
-{
- struct misdn_stack* stack;
- int i;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
- for (i=0; i<=stack->b_num; i++) {
- if ( stack->bc[i].conf_id==confid ) {
- return &stack->bc[i];
- }
- }
- }
- return NULL;
-}
-
-
-static struct misdn_bchannel *find_bc_by_channel(int port, int channel)
-{
- struct misdn_stack* stack=find_stack_by_port(port);
- int i;
-
- if (!stack) return NULL;
-
- for (i=0; i<=stack->b_num; i++) {
- if ( stack->bc[i].channel== channel ) {
- return &stack->bc[i];
- }
- }
-
- return NULL;
-}
-
-
-
-
-
-static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- if (!stack->nt) {
-
- switch (event) {
-
- case EVENT_CONNECT_ACKNOWLEDGE:
- setup_bc(bc);
-
- if ( *bc->crypt_key ) {
- cb_log(4, stack->port, "ENABLING BLOWFISH channel:%d oad%d:%s dad%d:%s\n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
- manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
- }
-
- if (misdn_cap_is_speech(bc->capability)) {
- if ( !bc->nodsp) manager_ph_control(bc, DTMF_TONE_START, 0);
- manager_ec_enable(bc);
-
- if ( bc->txgain != 0 ) {
- cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
- manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
- }
- if ( bc->rxgain != 0 ) {
- cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
- manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
- }
- }
-
- break;
- case EVENT_CONNECT:
-
- if ( *bc->crypt_key ) {
- cb_log(4, stack->port, "ENABLING BLOWFISH channel:%d oad%d:%s dad%d:%s\n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
- manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
- }
- case EVENT_ALERTING:
- case EVENT_PROGRESS:
- case EVENT_PROCEEDING:
- case EVENT_SETUP_ACKNOWLEDGE:
- case EVENT_SETUP:
- {
- if (bc->channel == 0xff || bc->channel<=0)
- bc->channel=0;
-
- if (find_free_chan_in_stack(stack, bc, bc->channel, 0)<0){
- if (!stack->pri && !stack->ptp) {
- bc->cw=1;
- break;
- }
-
- cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- return -1;
- }
- }
-
- setup_bc(bc);
- break;
-
- case EVENT_RELEASE_COMPLETE:
- case EVENT_RELEASE:
- break;
- default:
- break;
- }
- } else { /** NT MODE **/
-
- }
- return 0;
-}
-
-static int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
-{
- struct misdn_bchannel* bc;
- if (!stack) return -1;
-
- switch (frm->prim) {
- case CC_NEW_CR|INDICATION:
- cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
-
- bc=misdn_lib_get_free_bc(stack->port, 0, 1, 0);
- if (!bc) {
- cb_log(0, stack->port, " --> !! lib: No free channel!\n");
- return -1;
- }
-
- cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
- bc->l3_id=frm->dinfo;
- return 1;
- case CC_NEW_CR|CONFIRM:
- return 1;
- case CC_NEW_CR|REQUEST:
- return 1;
- case CC_RELEASE_CR|REQUEST:
- return 1;
- case CC_RELEASE_CR|CONFIRM:
- break;
- case CC_RELEASE_CR|INDICATION:
- cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n",frm->dinfo);
- {
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, frm->dinfo);
- struct misdn_bchannel dummybc;
-
- if (!bc) {
- cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
- make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
-
- bc=&dummybc;
- }
-
- if (bc) {
- int channel = bc->channel;
- cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo);
-
- /*bc->pid = 0;*/
- bc->need_disconnect=0;
- bc->need_release=0;
- bc->need_release_complete=0;
-
- cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
-
- empty_bc(bc);
- clean_up_bc(bc);
-
- if (channel>0)
- empty_chan_in_stack(stack,channel);
- bc->in_use=0;
-
- dump_chan_list(stack);
-
- if (bc->stack_holder) {
- cb_log(4,stack->port, "REMOVEING Holder\n");
- stack_holder_remove( stack, bc);
- free(bc);
- }
- }
- else {
- if (stack->nt)
- cb_log(4, stack->port, "BC with dinfo: %x not found.. (prim was %x and addr %x)\n",frm->dinfo, frm->prim, frm->addr);
- }
-
- return 1;
- }
- break;
- }
-
- return 0;
-}
-
-
-/*Emptys bc if it's reserved (no SETUP out yet)*/
-void misdn_lib_release(struct misdn_bchannel *bc)
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- if (!stack) {
- cb_log(1,0,"misdn_release: No Stack found\n");
- return;
- }
-
- if (bc->channel>0)
- empty_chan_in_stack(stack,bc->channel);
-
- empty_bc(bc);
- clean_up_bc(bc);
- bc->in_use=0;
-}
-
-
-
-
-int misdn_lib_get_port_up (int port)
-{ /* Pull Up L1 */
- struct misdn_stack *stack;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
-
- if (stack->port == port) {
-
- if (!stack->l1link)
- misdn_lib_get_l1_up(stack);
- if (!stack->l2link)
- misdn_lib_get_l2_up(stack);
-
- return 0;
- }
- }
- return 0;
-}
-
-
-int misdn_lib_get_port_down (int port)
-{ /* Pull Down L1 */
- struct misdn_stack *stack;
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
- if (stack->port == port) {
- if (stack->l2link)
- misdn_lib_get_l2_down(stack);
- misdn_lib_get_l1_down(stack);
- return 0;
- }
- }
- return 0;
-}
-
-int misdn_lib_port_up(int port, int check)
-{
- struct misdn_stack *stack;
-
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
-
- if (stack->port == port) {
-
- if (stack->blocked) {
- cb_log(0,port, "Port Blocked:%d L2:%d L1:%d\n", stack->blocked, stack->l2link, stack->l1link);
- return -1;
- }
-
- if (stack->ptp ) {
-
- if (stack->l1link && stack->l2link) {
- return 1;
- } else {
- cb_log(1,port, "Port Down L2:%d L1:%d\n",
- stack->l2link, stack->l1link);
- return 0;
- }
- } else {
- if ( !check || stack->l1link )
- return 1;
- else {
- cb_log(1,port, "Port down PMP\n");
- return 0;
- }
- }
- }
- }
-
- return -1;
-}
-
-
-int release_cr(struct misdn_stack *stack, mISDNuser_head_t *hh)
-{
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
- struct misdn_bchannel dummybc;
- iframe_t frm; /* fake te frm to remove callref from global callreflist */
- frm.dinfo = hh->dinfo;
-
- frm.addr=stack->upper_id | FLG_MSG_DOWN;
-
- frm.prim = CC_RELEASE_CR|INDICATION;
- cb_log(4, stack->port, " --> CC_RELEASE_CR: Faking Realease_cr for %x l3id:%x\n",frm.addr, frm.dinfo);
- /** removing procid **/
- if (!bc) {
- cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
- make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
- bc=&dummybc;
- }
-
- if (bc) {
- if ( (bc->l3_id & 0xff00) == 0xff00) {
- cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id&0xff);
- stack->procids[bc->l3_id&0xff] = 0 ;
- }
- }
- else cb_log(0, stack->port, "Couldnt find BC so I couldnt remove the Process!!!! this is a bad port.\n");
-
- if (handle_cr(stack, &frm)<0) {
- }
-
- return 0 ;
-}
-
-int
-handle_event_nt(void *dat, void *arg)
-{
- manager_t *mgr = (manager_t *)dat;
- msg_t *msg = (msg_t *)arg;
- mISDNuser_head_t *hh;
- int reject=0;
-
- struct misdn_stack *stack=find_stack_by_mgr(mgr);
- int port;
-
- if (!msg || !mgr)
- return(-EINVAL);
-
- hh=(mISDNuser_head_t*)msg->data;
- port=stack->port;
-
- cb_log(5, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
- {
- switch(hh->prim){
- case CC_RETRIEVE|INDICATION:
- {
- struct misdn_bchannel *bc;
- struct misdn_bchannel *hold_bc;
- iframe_t frm; /* fake te frm to add callref to global callreflist */
- frm.dinfo = hh->dinfo;
-
- frm.addr=stack->upper_id | FLG_MSG_DOWN;
-
- frm.prim = CC_NEW_CR|INDICATION;
-
- if (handle_cr( stack, &frm)< 0) {
- msg_t *dmsg;
- cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
- dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
- stack->nst.manager_l3(&stack->nst, dmsg);
- free_msg(msg);
- return 0;
- }
-
- bc=find_bc_by_l3id(stack, hh->dinfo);
- hold_bc=stack_holder_find(stack,bc->l3_id);
- cb_log(4, stack->port, "bc_l3id:%x holded_bc_l3id:%x\n",bc->l3_id, hold_bc->l3_id);
-
- if (hold_bc) {
- cb_log(4, stack->port, "REMOVEING Holder\n");
-
- /*swap the backup to our new channel back*/
- stack_holder_remove(stack, hold_bc);
- memcpy(bc,hold_bc,sizeof(struct misdn_bchannel));
- free(hold_bc);
-
- bc->holded=0;
- bc->b_stid=0;
- }
-
- }
-
- break;
-
- case CC_SETUP|CONFIRM:
- {
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
- int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
- cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n",l3id );
-
- if (!bc) { cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n"); return 0; }
- cb_log (2,bc->port,"I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
- bc->l3_id=l3id;
- cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
- }
- free_msg(msg);
- return 0;
-
- case CC_SETUP|INDICATION:
- {
- struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1, 0);
- if (!bc)
- ERR_NO_CHANNEL:
- {
- msg_t *dmsg;
- cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
- dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
- stack->nst.manager_l3(&stack->nst, dmsg);
- free_msg(msg);
- return 0;
- }
-
- cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
- bc->l3_id=hh->dinfo;
- }
- break;
-
- case CC_CONNECT_ACKNOWLEDGE|INDICATION:
- break;
-
- case CC_ALERTING|INDICATION:
- case CC_PROCEEDING|INDICATION:
- case CC_SETUP_ACKNOWLEDGE|INDICATION:
- if(!stack->ptp) break;
- case CC_CONNECT|INDICATION:
- break;
- case CC_DISCONNECT|INDICATION:
- {
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
- if (!bc) {
- bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
- if (bc) {
- int myprocid=bc->l3_id&0x0000ffff;
- hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
- cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
- reject=1;
- }
- }
- }
- break;
-
- case CC_FACILITY|INDICATION:
- {
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
- if (!bc) {
- bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
- if (bc) {
- int myprocid=bc->l3_id&0x0000ffff;
- hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
- cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
- }
- }
- }
- break;
-
- case CC_RELEASE_COMPLETE|INDICATION:
- break;
-
- case CC_SUSPEND|INDICATION:
- {
- msg_t *dmsg;
- cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
- dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
- stack->nst.manager_l3(&stack->nst, dmsg);
- free_msg(msg);
- return 0;
- }
- break;
- case CC_RESUME|INDICATION:
- break;
-
- case CC_RELEASE|CONFIRM:
- {
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
-
- if (bc) {
- cb_log(1, stack->port, "CC_RELEASE|CONFIRM (l3id:%x), sending RELEASE_COMPLETE\n", hh->dinfo);
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
- }
- }
- break;
-
- case CC_RELEASE|INDICATION:
- break;
-
- case CC_RELEASE_CR|INDICATION:
- release_cr(stack, hh);
- free_msg(msg);
- return 0 ;
- break;
-
- case CC_NEW_CR|INDICATION:
- /* Got New CR for bchan, for now I handle this one in */
- /* connect_ack, Need to be changed */
- {
- struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
- int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
- if (!bc) { cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n"); return -1;};
- if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
- cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
- stack->procids[bc->l3_id&0xff] = 0 ;
- }
- cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID is %x\n",l3id );
-
- bc->l3_id =l3id;
- cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
-
- free_msg(msg);
- return 0;
- }
-
- case DL_ESTABLISH | INDICATION:
- case DL_ESTABLISH | CONFIRM:
- {
- cb_log(3, stack->port, "%% GOT L2 Activate Info.\n");
-
- if (stack->ptp && stack->l2link) {
- cb_log(0, stack->port, "%% GOT L2 Activate Info. but we're activated already.. this l2 is faulty, blocking port\n");
- cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
- }
-
- if (stack->ptp && !stack->restart_sent) {
- /* make sure we restart the interface of the
- * other side */
- stack->restart_sent=1;
- misdn_lib_send_restart(stack->port, -1);
-
- }
-
- /* when we get the L2 UP, the L1 is UP definitely too*/
- stack->l1link = 1;
- stack->l2link = 1;
- stack->l2upcnt=0;
-
- free_msg(msg);
- return 0;
- }
- break;
-
-
- case DL_RELEASE | INDICATION:
- case DL_RELEASE | CONFIRM:
- {
- if (stack->ptp) {
- cb_log(3 , stack->port, "%% GOT L2 DeActivate Info.\n");
-
- if (stack->l2upcnt>3) {
- cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attemps!!!\n");
- } else {
-#if 0
- if (stack->nt) misdn_lib_reinit_nt_stack(stack->port);
-#endif
- if (stack->l1link) {
- misdn_lib_get_l2_up(stack);
- stack->l2upcnt++;
- }
- }
-
- } else
- cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
-
- stack->l2link = 0;
- free_msg(msg);
- return 0;
- }
- break;
- }
- }
-
- {
- /* Parse Events and fire_up to App. */
- struct misdn_bchannel *bc;
- struct misdn_bchannel dummybc;
-
- enum event_e event = isdn_msg_get_event(msgs_g, msg, 1);
-
- bc=find_bc_by_l3id(stack, hh->dinfo);
-
- if (!bc) {
- cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x).\n", hh->dinfo);
- make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
- bc=&dummybc;
- }
- if (bc ) {
- isdn_msg_parse_event(msgs_g,msg,bc, 1);
-
- switch (event) {
- int channel;
- int tmpcause;
- case EVENT_SETUP:
- if (bc->channel<=0 || bc->channel==0xff)
- bc->channel=0;
-
- if (find_free_chan_in_stack(stack,bc, bc->channel,0)<0)
- goto ERR_NO_CHANNEL;
- break;
- case EVENT_RELEASE:
- case EVENT_RELEASE_COMPLETE:
- {
- channel=bc->channel;
- tmpcause=bc->cause;
- empty_bc(bc);
- bc->cause=tmpcause;
- clean_up_bc(bc);
-
- if (channel>0)
- empty_chan_in_stack(stack,channel);
- bc->in_use=0;
- }
- break;
-
- default:
- break;
- }
-
- if(!isdn_get_info(msgs_g,event,1)) {
- cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n",hh->prim, hh->dinfo);
- } else {
- if (reject) {
- switch(bc->cause){
- case 17:
- cb_log(1, stack->port, "Siemens Busy reject..\n");
-
- break;
- default:
- break;
- }
- }
- cb_event(event, bc, glob_mgr->user_data);
- }
- } else {
- cb_log(4, stack->port, "No BC found with l3id: prim %x dinfo %x\n",hh->prim, hh->dinfo);
- }
-
- free_msg(msg);
- }
-
-
- return 0;
-}
-
-
-static int handle_timers(msg_t* msg)
-{
- iframe_t *frm= (iframe_t*)msg->data;
- struct misdn_stack *stack;
-
- /* Timer Stuff */
- switch (frm->prim) {
- case MGR_INITTIMER | CONFIRM:
- case MGR_ADDTIMER | CONFIRM:
- case MGR_DELTIMER | CONFIRM:
- case MGR_REMOVETIMER | CONFIRM:
- free_msg(msg);
- return(1);
- }
-
-
-
- if (frm->prim==(MGR_TIMER | INDICATION) ) {
- for (stack = glob_mgr->stack_list;
- stack;
- stack = stack->next) {
- itimer_t *it;
-
- if (!stack->nt) continue;
-
- it = stack->nst.tlist;
- /* find timer */
- for(it=stack->nst.tlist;
- it;
- it=it->next) {
- if (it->id == (int)frm->addr)
- break;
- }
- if (it) {
- int ret;
- ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
- MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
- test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
- ret = it->function(it->data);
- free_msg(msg);
- return 1;
- }
- }
-
- cb_log(0, 0, "Timer Msg without Timer ??\n");
- free_msg(msg);
- return 1;
- }
-
- return 0;
-}
-
-
-
-void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
-{
- bc->generate_tone=1;
-}
-
-void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
-{
- bc->generate_tone=0;
-}
-
-
-static int do_tone(struct misdn_bchannel *bc, int len)
-{
- bc->tone_cnt=len;
-
- if (bc->generate_tone) {
- cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
-
- if ( !bc->nojitter ) {
- misdn_tx_jitter(bc,len);
- }
-
- return 1;
- }
-
- return 0;
-}
-
-
-#ifdef MISDN_SAVE_DATA
-static void misdn_save_data(int id, char *p1, int l1, char *p2, int l2)
-{
- char n1[32],n2[32];
-
- sprintf(n1,"/tmp/misdn-rx-%d.raw",id);
- sprintf(n2,"/tmp/misdn-tx-%d.raw",id);
-
- FILE *rx=fopen(n1,"a+");
- FILE *tx=fopen(n2,"a+");
-
- if (!rx || !tx) {
- cb_log(0,0,"Couldn't open files: %s\n",strerror(errno));
- return ;
- }
-
- fwrite(p1,1,l1,rx);
- fwrite(p2,1,l2,tx);
-
- fclose(rx);
- fclose(tx);
-
-}
-#endif
-
-void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
-{
- char buf[4096 + mISDN_HEADER_LEN];
- char *data=&buf[mISDN_HEADER_LEN];
- iframe_t *txfrm= (iframe_t*)buf;
- int jlen, r;
-
- jlen=cb_jb_empty(bc,data,len);
-
- if (jlen) {
-#ifdef MISDN_SAVE_DATA
- misdn_save_data((bc->port*100+bc->channel), data, jlen, bc->bframe, bc->bframe_len);
-#endif
- flip_buf_bits( data, jlen);
-
- if (jlen < len) {
- cb_log(7,bc->port,"Jitterbuffer Underrun.\n");
- }
-
- txfrm->prim = DL_DATA|REQUEST;
-
- txfrm->dinfo = 0;
-
- txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
-
- txfrm->len =jlen;
- cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
-
- r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
- } else {
-#define MISDN_GEN_SILENCE
-#ifdef MISDN_GEN_SILENCE
- int cnt=len/TONE_SILENCE_SIZE;
- int rest=len%TONE_SILENCE_SIZE;
- int i;
-
- for (i=0; i<cnt; i++) {
- memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
- data +=TONE_SILENCE_SIZE;
- }
-
- if (rest) {
- memcpy(data, tone_silence_flip, rest);
- }
-
- txfrm->prim = DL_DATA|REQUEST;
-
- txfrm->dinfo = 0;
-
- txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
-
- txfrm->len =len;
- cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
-
- r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
-#endif
-
- }
-}
-
-static int handle_bchan(msg_t *msg)
-{
- iframe_t *frm= (iframe_t*)msg->data;
- struct misdn_stack *stack;
- struct misdn_bchannel *bc=find_bc_by_addr(frm->addr);
-
- if (!bc) {
- cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
- return 0 ;
- }
-
- stack=get_stack_by_bc(bc);
-
- if (!stack) {
- cb_log(0, bc->port,"handle_bchan: STACK not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
- return 0;
- }
-
- switch (frm->prim) {
-
- case MGR_SETSTACK| CONFIRM:
- cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid);
- break;
-
- case MGR_SETSTACK| INDICATION:
- cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
- break;
-#if 0
- AGAIN:
- bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
- if (!bc->addr) {
-
- if (errno == EAGAIN) {
- usleep(1000);
- goto AGAIN;
- }
-
- cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
-
- /* we kill the channel later, when we received some
- data. */
- bc->addr= frm->addr;
- } else if ( bc->addr < 0) {
- cb_log(0, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
- bc->addr=0;
- }
-
- cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
-
- free_msg(msg);
-
-
- switch(bc->bc_state) {
- case BCHAN_SETUP:
- bc_state_change(bc,BCHAN_SETUPED);
- break;
-
- case BCHAN_CLEAN_REQUEST:
- default:
- cb_log(0, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid);
- clean_up_bc(bc);
- }
- return 1;
-#endif
-
- case MGR_DELLAYER| INDICATION:
- cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
- break;
-
- case MGR_DELLAYER| CONFIRM:
- cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid);
-
- bc->pid=0;
- bc->addr=0;
-
- free_msg(msg);
- return 1;
-
- case PH_ACTIVATE | INDICATION:
- case DL_ESTABLISH | INDICATION:
- cb_log(3, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid);
-
- free_msg(msg);
- return 1;
-
- case PH_ACTIVATE | CONFIRM:
- case DL_ESTABLISH | CONFIRM:
-
- cb_log(3, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid);
- free_msg(msg);
-
- return 1;
-
- case DL_ESTABLISH | REQUEST:
- {
- char buf[128];
- mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
- }
- free_msg(msg);
- return 1;
-
- case DL_RELEASE|REQUEST:
- {
- char buf[128];
- mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
- }
- free_msg(msg);
- return 1;
-
- case PH_DEACTIVATE | INDICATION:
- case DL_RELEASE | INDICATION:
- cb_log (3, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid);
-
- free_msg(msg);
- return 1;
-
- case PH_DEACTIVATE | CONFIRM:
- case DL_RELEASE | CONFIRM:
- cb_log(3, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid);
-
- free_msg(msg);
- return 1;
-
- case PH_CONTROL|INDICATION:
- {
- unsigned int *cont = (unsigned int *) &frm->data.p;
-
- cb_log(4, stack->port, "PH_CONTROL: channel:%d oad%d:%s dad%d:%s \n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
-
- if ((*cont & ~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
- int dtmf = *cont & DTMF_TONE_MASK;
- cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
- bc->dtmf=dtmf;
- cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
-
- free_msg(msg);
- return 1;
- }
- if (*cont == BF_REJECT) {
- cb_log(4, stack->port, " --> BF REJECT\n");
- free_msg(msg);
- return 1;
- }
- if (*cont == BF_ACCEPT) {
- cb_log(4, stack->port, " --> BF ACCEPT\n");
- free_msg(msg);
- return 1;
- }
- }
- break;
-
- case PH_DATA|REQUEST:
- case DL_DATA|REQUEST:
- cb_log(0, stack->port, "DL_DATA REQUEST \n");
- do_tone(bc, 64);
-
- free_msg(msg);
- return 1;
-
-
- case PH_DATA|INDICATION:
- case DL_DATA|INDICATION:
- {
- bc->bframe = (void*)&frm->data.i;
- bc->bframe_len = frm->len;
-
- /** Anyway flip the bufbits **/
- if ( misdn_cap_is_speech(bc->capability) )
- flip_buf_bits(bc->bframe, bc->bframe_len);
-
-
- if (!bc->bframe_len) {
- cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
- free_msg(msg);
- return 1;
- }
-
- if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
- cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
- free_msg(msg);
- return 1;
- }
-
-#if MISDN_DEBUG
- cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
-
-#endif
-
- if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
- int t;
-
-#ifdef MISDN_B_DEBUG
- cb_log(0,bc->port,"do_tone START\n");
-#endif
- t=do_tone(bc,frm->len);
-
-#ifdef MISDN_B_DEBUG
- cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
-#endif
- if ( !t ) {
- int i;
-
- if ( misdn_cap_is_speech(bc->capability)) {
- if ( !bc->nojitter ) {
-#ifdef MISDN_B_DEBUG
- cb_log(0,bc->port,"tx_jitter START\n");
-#endif
- misdn_tx_jitter(bc,frm->len);
-#ifdef MISDN_B_DEBUG
- cb_log(0,bc->port,"tx_jitter STOP\n");
-#endif
- }
- }
-
-#ifdef MISDN_B_DEBUG
- cb_log(0,bc->port,"EVENT_B_DATA START\n");
-#endif
-
- i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
-#ifdef MISDN_B_DEBUG
- cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
-#endif
-
- if (i<0) {
- cb_log(10,stack->port,"cb_event returned <0\n");
- /*clean_up_bc(bc);*/
- }
- }
- }
- free_msg(msg);
- return 1;
- }
-
-
- case PH_CONTROL | CONFIRM:
- cb_log(4, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
- free_msg(msg);
- return 1;
-
- case PH_DATA | CONFIRM:
- case DL_DATA|CONFIRM:
-#if MISDN_DEBUG
-
- cb_log(0, stack->port, "Data confirmed\n");
-
-#endif
- free_msg(msg);
- return 1;
- case DL_DATA|RESPONSE:
-#if MISDN_DEBUG
- cb_log(0, stack->port, "Data response\n");
-
-#endif
- break;
- }
-
- return 0;
-}
-
-
-
-static int handle_frm_nt(msg_t *msg)
-{
- iframe_t *frm= (iframe_t*)msg->data;
- struct misdn_stack *stack;
- int err=0;
-
- stack=find_stack_by_addr( frm->addr );
-
-
-
- if (!stack || !stack->nt) {
- return 0;
- }
-
-
- if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
-
- if (nt_err_cnt > 0 ) {
- if (nt_err_cnt < 100) {
- nt_err_cnt++;
- cb_log(0, stack->port, "NT Stack sends us error: %d \n", err);
- } else if (nt_err_cnt < 105){
- cb_log(0, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
- nt_err_cnt = - 1;
- }
- }
- free_msg(msg);
- return 1;
-
- }
-
- return 1;
-}
-
-
-static int handle_frm(msg_t *msg)
-{
- iframe_t *frm = (iframe_t*) msg->data;
-
- struct misdn_stack *stack=find_stack_by_addr(frm->addr);
-
- if (!stack || stack->nt) {
- return 0;
- }
-
- cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim);
-
- {
- struct misdn_bchannel dummybc;
- struct misdn_bchannel *bc;
- int ret=handle_cr(stack, frm);
-
- if (ret<0) {
- cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
-
-
- }
-
- if(ret) {
- free_msg(msg);
- return 1;
- }
-
- bc=find_bc_by_l3id(stack, frm->dinfo);
-
- if (!bc && (frm->prim==(CC_RESTART|CONFIRM)) ) {
- make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
- bc=&dummybc;
- }
-
-handle_frm_bc:
- if (bc ) {
- int ret;
- enum event_e event = isdn_msg_get_event(msgs_g, msg, 0);
- enum event_response_e response=RESPONSE_OK;
-
- isdn_msg_parse_event(msgs_g,msg,bc, 0);
-
- /** Preprocess some Events **/
- ret=handle_event(bc, event, frm);
- if (ret<0) {
- cb_log(0,stack->port,"couldn't handle event\n");
- free_msg(msg);
- return 1;
- }
- /* shoot up event to App: */
- cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
-
- if(!isdn_get_info(msgs_g,event,0))
- cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
- else
- response=cb_event(event, bc, glob_mgr->user_data);
-#if 1
- if (event == EVENT_SETUP) {
- switch (response) {
- case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
-
- cb_log(0, stack->port, "TOTALY IGNORING SETUP \n");
-
- break;
- case RESPONSE_IGNORE_SETUP:
- /* I think we should send CC_RELEASE_CR, but am not sure*/
- bc->out_cause=16;
-
- case RESPONSE_RELEASE_SETUP:
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- if (bc->channel>0)
- empty_chan_in_stack(stack, bc->channel);
- empty_bc(bc);
- bc_state_change(bc,BCHAN_CLEANED);
- bc->in_use=0;
-
- cb_log(0, stack->port, "GOT IGNORE SETUP\n");
- break;
- case RESPONSE_OK:
- cb_log(4, stack->port, "GOT SETUP OK\n");
-
-
- break;
- default:
- break;
- }
- }
-
- if (event == EVENT_RELEASE_COMPLETE) {
- /* release bchannel only after we've anounced the RELEASE_COMPLETE */
- int channel=bc->channel;
- int tmpcause=bc->cause;
- int tmp_out_cause=bc->out_cause;
- empty_bc(bc);
- bc->cause=tmpcause;
- bc->out_cause=tmp_out_cause;
- clean_up_bc(bc);
-
- if (tmpcause == 44) {
- cb_log(0,stack->port,"**** Received CAUSE:44, so not cleaning up channel %d\n", channel);
- cb_log(0,stack->port,"**** This channel is now no longer available,\nplease try to restart it with 'misdn send restart <port> <channel>'\n");
- set_chan_in_stack(stack, channel);
- bc->channel=channel;
- misdn_lib_send_restart(stack->port, channel);
- } else {
- if (channel>0)
- empty_chan_in_stack(stack, channel);
- }
- bc->in_use=0;
- }
-
- if (event == EVENT_RESTART) {
- cb_log(0, stack->port, "**** Received RESTART_ACK channel:%d\n", bc->restart_channel);
- empty_chan_in_stack(stack, bc->restart_channel);
- }
-
- cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim);
-
-
- free_msg(msg);
- return 1;
-#endif
-
- } else {
- struct misdn_bchannel dummybc;
- cb_log(0, stack->port, " --> Didn't find BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
- memset (&dummybc,0,sizeof(dummybc));
- dummybc.port=stack->port;
- dummybc.l3_id=frm->dinfo;
- bc=&dummybc;
- goto handle_frm_bc;
- }
- }
-
- cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x \n",frm->prim);
- return 0;
-}
-
-
-static int handle_l1(msg_t *msg)
-{
- iframe_t *frm = (iframe_t*) msg->data;
- struct misdn_stack *stack = find_stack_by_addr(frm->addr);
- int i ;
-
- if (!stack) return 0 ;
-
- switch (frm->prim) {
- case PH_ACTIVATE | CONFIRM:
- case PH_ACTIVATE | INDICATION:
- cb_log (3, stack->port, "L1: PH L1Link Up!\n");
- stack->l1link=1;
-
- if (stack->nt) {
-
- if (stack->nst.l1_l2(&stack->nst, msg))
- free_msg(msg);
-
- if (stack->ptp)
- misdn_lib_get_l2_up(stack);
- } else {
- free_msg(msg);
- }
-
- for (i=0;i<=stack->b_num; i++) {
- if (stack->bc[i].evq != EVENT_NOTHING) {
- cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
- misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
- stack->bc[i].evq=EVENT_NOTHING;
- }
-
- }
- return 1;
-
- case PH_ACTIVATE | REQUEST:
- free_msg(msg);
- cb_log(3,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
- return 1;
-
- case PH_DEACTIVATE | REQUEST:
- free_msg(msg);
- cb_log(3,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
- return 1;
-
- case PH_DEACTIVATE | CONFIRM:
- case PH_DEACTIVATE | INDICATION:
- cb_log (3, stack->port, "L1: PH L1Link Down! \n");
-
-#if 0
- for (i=0; i<=stack->b_num; i++) {
- if (global_state == MISDN_INITIALIZED) {
- cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
- }
- }
-#endif
-
- if (stack->nt) {
- if (stack->nst.l1_l2(&stack->nst, msg))
- free_msg(msg);
- } else {
- free_msg(msg);
- }
-
- stack->l1link=0;
- stack->l2link=0;
- return 1;
- }
-
- return 0;
-}
-
-static int handle_l2(msg_t *msg)
-{
- iframe_t *frm = (iframe_t*) msg->data;
-
- struct misdn_stack *stack = find_stack_by_addr(frm->addr);
-
- if (!stack) {
- return 0 ;
- }
-
- switch(frm->prim) {
-
- case DL_ESTABLISH | REQUEST:
- cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
- return 1;
- case DL_RELEASE | REQUEST:
- cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
- return 1;
-
- case DL_ESTABLISH | INDICATION:
- case DL_ESTABLISH | CONFIRM:
- {
- cb_log (3, stack->port, "L2: L2Link Up! \n");
- if (stack->ptp && stack->l2link) {
- cb_log (-1, stack->port, "L2: L2Link Up! but it's already UP.. must be faulty, blocking port\n");
- cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
- }
- stack->l2link=1;
- free_msg(msg);
- return 1;
- }
- break;
-
- case DL_RELEASE | INDICATION:
- case DL_RELEASE | CONFIRM:
- {
- cb_log (3, stack->port, "L2: L2Link Down! \n");
- stack->l2link=0;
-
- free_msg(msg);
- return 1;
- }
- break;
- }
- return 0;
-}
-
-static int handle_mgmt(msg_t *msg)
-{
- struct misdn_stack *stack;
- iframe_t *frm = (iframe_t*) msg->data;
-
- if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
- cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
- free_msg(msg);
- return 1;
- }
-
- stack=find_stack_by_addr(frm->addr);
-
- if (!stack) {
- if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
- cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
- frm->addr) ;
- free_msg(msg);
- return 1;
- }
-
- return 0;
- }
-
- switch(frm->prim) {
- case MGR_SHORTSTATUS | INDICATION:
- case MGR_SHORTSTATUS | CONFIRM:
- cb_log(5, 0, "MGMT: Short status dinfo %x\n",frm->dinfo);
-
- switch (frm->dinfo) {
- case SSTATUS_L1_ACTIVATED:
- cb_log(3, 0, "MGMT: SSTATUS: L1_ACTIVATED \n");
- stack->l1link=1;
-
- break;
- case SSTATUS_L1_DEACTIVATED:
- cb_log(3, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
- stack->l1link=0;
-#if 0
- clear_l3(stack);
-#endif
- break;
-
- case SSTATUS_L2_ESTABLISHED:
- cb_log(3, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
-
- /*when the L2 goes UP, L1 needs to be UP too*/
- stack->l1link=1;
- stack->l2link=1;
- break;
-
- case SSTATUS_L2_RELEASED:
- cb_log(3, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
- stack->l2link=0;
- break;
- }
-
- free_msg(msg);
- return 1;
-
- case MGR_SETSTACK | INDICATION:
- cb_log(4, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
- free_msg(msg);
- return 1;
- case MGR_DELLAYER | CONFIRM:
- cb_log(4, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
- free_msg(msg);
- return 1;
-
- }
-
- /*
- if ( (frm->prim & 0x0f0000) == 0x0f0000) {
- cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
- free_msg(msg);
- return 1;
- } */
-
- return 0;
-}
-
-
-static msg_t *fetch_msg(int midev)
-{
- msg_t *msg=alloc_msg(MAX_MSG_SIZE);
- int r;
-
- if (!msg) {
- cb_log(0, 0, "fetch_msg: alloc msg failed !!");
- return NULL;
- }
-
- AGAIN:
- r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC);
- msg->len=r;
-
- if (r==0) {
- free_msg(msg); /* danger, cauz usualy freeing in main_loop */
- cb_log(6,0,"Got empty Msg..\n");
- return NULL;
- }
-
- if (r<0) {
- if (errno == EAGAIN) {
- /*we wait for mISDN here*/
- cb_log(4,0,"mISDN_read wants us to wait\n");
- usleep(5000);
- goto AGAIN;
- }
-
- cb_log(0,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno);
- }
-
-#if 0
- if (!(frm->prim == (DL_DATA|INDICATION) )|| (frm->prim == (PH_DATA|INDICATION)))
- cb_log(0,0,"prim: %x dinfo:%x addr:%x msglen:%d frm->len:%d\n",frm->prim, frm->dinfo, frm->addr, msg->len,frm->len );
-#endif
- return msg;
-}
-
-void misdn_lib_isdn_l1watcher(int port)
-{
- struct misdn_stack *stack;
-
- for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
- ;
-
- if (stack) {
- cb_log(4, port, "Checking L1 State\n");
- if (!stack->l1link) {
- cb_log(4, port, "L1 State Down, trying to get it up again\n");
- misdn_lib_get_short_status(stack);
- misdn_lib_get_l1_up(stack);
- misdn_lib_get_l2_up(stack);
- }
- }
-}
-
-static void misdn_lib_isdn_event_catcher(void *arg)
-{
- struct misdn_lib *mgr = arg;
- int zero_frm=0 , fff_frm=0 ;
- int midev= mgr->midev;
- int port=0;
-
- while (1) {
- msg_t *msg = fetch_msg(midev);
- iframe_t *frm;
-
-
- if (!msg) continue;
-
- frm = (iframe_t*) msg->data;
-
- /** When we make a call from NT2Ast we get this frames **/
- if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
- zero_frm++;
- free_msg(msg);
- continue;
- } else {
- if (zero_frm) {
- cb_log(0, port, "*** Alert: %d zero_frms caught\n", zero_frm);
- zero_frm = 0 ;
- }
- }
-
- /** I get this sometimes after setup_bc **/
- if (frm->len == 0 && frm->dinfo == 0 && frm->prim == 0xffffffff ) {
- fff_frm++;
- free_msg(msg);
- continue;
- } else {
- if (fff_frm) {
- cb_log(0, port, "*** Alert: %d fff_frms caught\n", fff_frm);
- fff_frm = 0 ;
- }
- }
-
- manager_isdn_handler(frm, msg);
- }
-
-}
-
-
-/** App Interface **/
-
-int te_lib_init() {
- char buff[1025];
- iframe_t *frm=(iframe_t*)buff;
- int midev=mISDN_open();
- int ret;
-
- memset(buff,0,1025);
-
- if (midev<=0) return midev;
-
-/* create entity for layer 3 TE-mode */
- mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
- ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
-
- if (ret < mISDN_HEADER_LEN) {
- noentity:
- fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n",strerror(errno));
- exit(-1);
- }
-
- entity = frm->dinfo & 0xffff ;
-
- if (!entity)
- goto noentity;
-
- return midev;
-
-}
-
-void te_lib_destroy(int midev)
-{
- char buf[1024];
- mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
-
- cb_log(4, 0, "Entetity deleted\n");
- mISDN_close(midev);
- cb_log(4, 0, "midev closed\n");
-}
-
-
-
-void misdn_lib_transfer(struct misdn_bchannel* holded_bc)
-{
- holded_bc->holded=0;
-}
-
-struct misdn_bchannel *manager_find_bc_by_pid(int pid)
-{
- struct misdn_stack *stack;
- int i;
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next) {
- for (i=0; i<=stack->b_num; i++)
- if (stack->bc[i].pid == pid) return &stack->bc[i];
- }
-
- return NULL;
-}
-
-struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc)
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
- return find_bc_holded(stack);
-}
-
-
-
-static void prepare_bc(struct misdn_bchannel*bc, int channel)
-{
- bc->channel = channel;
- bc->channel_preselected = channel?1:0;
- bc->in_use = 1;
- bc->need_disconnect=1;
- bc->need_release=1;
- bc->need_release_complete=1;
- bc->cause=16;
-
- if (++mypid>5000) mypid=1;
- bc->pid=mypid;
-
-#if 0
- bc->addr=0;
- bc->b_stid=0;
- bc->layer_id=0;
-#endif
-}
-
-struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout, int dec)
-{
- struct misdn_stack *stack;
- int i;
-
- if (channel < 0 || channel > MAX_BCHANS) {
- cb_log(0,port,"Requested channel out of bounds (%d)\n",channel);
- return NULL;
- }
-
- for (stack=glob_mgr->stack_list; stack; stack=stack->next) {
-
- if (stack->port == port) {
- int maxnum;
- if (stack->blocked) {
- cb_log(0,port,"Port is blocked\n");
- return NULL;
- }
-
- if (channel > 0) {
- if (channel <= stack->b_num) {
- for (i = 0; i < stack->b_num; i++) {
- if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
- cb_log(0,port,"Requested channel:%d on port:%d is already in use\n",channel, port);
- return NULL;
- }
- }
- } else {
- cb_log(0,port,"Requested channel:%d is out of bounds on port:%d\n",channel, port);
- return NULL;
- }
- }
-
- maxnum=inout&&!stack->pri&&!stack->ptp?stack->b_num+1:stack->b_num;
-
- if (dec) {
- for (i = maxnum-1; i>=0; i--) {
- if (!stack->bc[i].in_use) {
- /* 3. channel on bri means CW*/
- if (!stack->pri && i==stack->b_num)
- stack->bc[i].cw=1;
-
- prepare_bc(&stack->bc[i], channel);
- stack->bc[i].dec=1;
- return &stack->bc[i];
- }
- }
- } else {
- for (i = 0; i <maxnum; i++) {
- if (!stack->bc[i].in_use) {
- /* 3. channel on bri means CW*/
- if (!stack->pri && i==stack->b_num)
- stack->bc[i].cw=1;
-
- prepare_bc(&stack->bc[i], channel);
- return &stack->bc[i];
- }
- }
- }
-
- cb_log(1,port,"There is no free channel on port (%d)\n",port);
- return NULL;
- }
- }
-
- cb_log(0,port,"Port is not configured (%d)\n",port);
- return NULL;
-}
-
-
-static char *fac2str (enum FacFunction func)
-{
- struct arr_el {
- enum FacFunction p;
- char *s ;
- } arr[] = {
- { Fac_None, "Fac_None" },
- { Fac_CD, "Fac_CD"},
- };
-
- int i;
-
- for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
- if ( arr[i].p==func) return arr[i].s;
-
- return "unknown";
-}
-
-void misdn_lib_log_ies(struct misdn_bchannel *bc)
-{
- struct misdn_stack *stack;
- if (!bc) return;
-
- stack=get_stack_by_bc(bc);
-
- if (!stack) return;
-
- cb_log(2, stack->port, " --> channel:%d mode:%s cause:%d ocause:%d rad:%s cad:%s\n", bc->channel, stack->nt?"NT":"TE", bc->cause, bc->out_cause, bc->rad, bc->cad);
-
- cb_log(2, stack->port,
- " --> info_dad:%s onumplan:%c dnumplan:%c rnumplan:%c cpnnumplan:%c\n",
- bc->info_dad,
- bc->onumplan>=0?'0'+bc->onumplan:' ',
- bc->dnumplan>=0?'0'+bc->dnumplan:' ',
- bc->rnumplan>=0?'0'+bc->rnumplan:' ',
- bc->cpnnumplan>=0?'0'+bc->cpnnumplan:' '
- );
-
- cb_log(3, stack->port, " --> caps:%s pi:%x keypad:%s sending_complete:%d\n", bearer2str(bc->capability),bc->progress_indicator, bc->keypad, bc->sending_complete);
- cb_log(4, stack->port, " --> screen:%d --> pres:%d\n",
- bc->screen, bc->pres);
-
- cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
-
- cb_log(4, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_in.Function),fac2str(bc->fac_out.Function));
-
- cb_log(5, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
-
- cb_log(5, stack->port, " --> bc:%x h:%d sh:%d\n", bc, bc->holded, bc->stack_holder);
-}
-
-void misdn_send_lock(struct misdn_bchannel *bc);
-void misdn_send_unlock(struct misdn_bchannel *bc);
-
-#define RETURN(a,b) {retval=a; goto b;}
-
-void misdn_send_lock(struct misdn_bchannel *bc)
-{
- //cb_log(0,bc->port,"Locking bc->pid:%d\n", bc->pid);
- if (bc->send_lock)
- pthread_mutex_lock(&bc->send_lock->lock);
-}
-
-void misdn_send_unlock(struct misdn_bchannel *bc)
-{
- //cb_log(0,bc->port,"UnLocking bc->pid:%d\n", bc->pid);
- if (bc->send_lock)
- pthread_mutex_unlock(&bc->send_lock->lock);
-}
-
-int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
-{
- msg_t *msg;
- struct misdn_stack *stack;
- int retval=0;
-
- if (!bc) RETURN(-1,OUT_POST_UNLOCK);
-
- stack=get_stack_by_bc(bc);
-
- if (!stack) {
- cb_log(0,bc->port,"SENDEVENT: no Stack for event:%s oad:%s dad:%s \n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad);
- RETURN(-1,OUT);
- }
-
- misdn_send_lock(bc);
-
-
- cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->uperid:%x\n",stack->nt, stack->upper_id);
-
- if ( stack->nt && !stack->l1link) {
- /** Queue Event **/
- bc->evq=event;
- cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0));
- misdn_lib_get_l1_up(stack);
- RETURN(0,OUT);
- }
-
- cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s pid:%d\n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad, bc->pid);
- cb_log(4, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
- misdn_lib_log_ies(bc);
-
- switch (event) {
- case EVENT_SETUP:
- if (create_process(glob_mgr->midev, bc)<0) {
- cb_log(0, stack->port, " No free channel at the moment @ send_event\n");
-
- RETURN(-ENOCHAN,OUT);
- }
- break;
-
- case EVENT_PROGRESS:
- case EVENT_ALERTING:
- case EVENT_PROCEEDING:
- case EVENT_SETUP_ACKNOWLEDGE:
- case EVENT_CONNECT:
- if (!stack->nt) break;
-
- case EVENT_RETRIEVE_ACKNOWLEDGE:
-
- if (stack->nt) {
- if (bc->channel <=0 ) { /* else we have the channel already */
- if (find_free_chan_in_stack(stack, bc, 0, 0)<0) {
- cb_log(0, stack->port, " No free channel at the moment\n");
- /*FIXME: add disconnect*/
- RETURN(-ENOCHAN,OUT);
- }
- }
- /* Its that i generate channels */
- }
-
- retval=setup_bc(bc);
- if (retval == -EINVAL) {
- cb_log(0,bc->port,"send_event: setup_bc failed\n");
- }
-
- if (misdn_cap_is_speech(bc->capability)) {
- if ((event==EVENT_CONNECT)||(event==EVENT_RETRIEVE_ACKNOWLEDGE)) {
- if ( *bc->crypt_key ) {
- cb_log(4, stack->port, " --> ENABLING BLOWFISH channel:%d oad%d:%s dad%d:%s \n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
-
- manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
- }
-
- if (!bc->nodsp) manager_ph_control(bc, DTMF_TONE_START, 0);
- manager_ec_enable(bc);
-
- if (bc->txgain != 0) {
- cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
- manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
- }
-
- if ( bc->rxgain != 0 ) {
- cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
- manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
- }
- }
- }
- break;
-
- case EVENT_HOLD_ACKNOWLEDGE:
- {
- struct misdn_bchannel *holded_bc=malloc(sizeof(struct misdn_bchannel));
- if (!holded_bc) {
- cb_log(0,bc->port, "Could not allocate holded_bc!!!\n");
- RETURN(-1,OUT);
- }
-
- /*backup the bc*/
- memcpy(holded_bc,bc,sizeof(struct misdn_bchannel));
- holded_bc->holded=1;
- bc_state_change(holded_bc,BCHAN_CLEANED);
-
- stack_holder_add(stack,holded_bc);
-
- /*kill the bridge and clean the bchannel*/
- if (stack->nt) {
- int channel;
- if (bc->bc_state == BCHAN_BRIDGED) {
- struct misdn_bchannel *bc2;
- misdn_split_conf(bc,bc->conf_id);
- bc2=find_bc_by_confid(bc->conf_id);
- if (!bc2) {
- cb_log(0,bc->port,"We have no second bc in bridge???\n");
- } else {
- misdn_split_conf(bc2,bc->conf_id);
- }
- }
-
- channel=bc->channel;
-
- empty_bc(bc);
- clean_up_bc(bc);
-
- if (channel>0)
- empty_chan_in_stack(stack,channel);
-
- bc->in_use=0;
- }
-
- }
- break;
-
- /* finishing the channel eh ? */
- case EVENT_DISCONNECT:
- if (!bc->need_disconnect) {
- cb_log(0,bc->port," --> we have already send Disconnect\n");
- RETURN(-1,OUT);
- }
-
- bc->need_disconnect=0;
- break;
- case EVENT_RELEASE:
- if (!bc->need_release) {
- cb_log(0,bc->port," --> we have already send Release\n");
- RETURN(-1,OUT);
- }
- bc->need_disconnect=0;
- bc->need_release=0;
- break;
- case EVENT_RELEASE_COMPLETE:
- if (!bc->need_release_complete) {
- cb_log(0,bc->port," --> we have already send Release_complete\n");
- RETURN(-1,OUT);
- }
- bc->need_disconnect=0;
- bc->need_release=0;
- bc->need_release_complete=0;
-
- if (!stack->nt) {
- /*create clenaup in TE*/
- int channel=bc->channel;
-
- int tmpcause=bc->cause;
- int tmp_out_cause=bc->out_cause;
- empty_bc(bc);
- bc->cause=tmpcause;
- bc->out_cause=tmp_out_cause;
- clean_up_bc(bc);
-
- if (channel>0)
- empty_chan_in_stack(stack,channel);
-
- bc->in_use=0;
- }
- break;
-
- case EVENT_CONNECT_ACKNOWLEDGE:
-
- if ( bc->nt || misdn_cap_is_speech(bc->capability)) {
- int retval=setup_bc(bc);
- if (retval == -EINVAL){
- cb_log(0,bc->port,"send_event: setup_bc failed\n");
-
- }
- }
-
- if (misdn_cap_is_speech(bc->capability)) {
- if ( !bc->nodsp) manager_ph_control(bc, DTMF_TONE_START, 0);
- manager_ec_enable(bc);
-
- if ( bc->txgain != 0 ) {
- cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
- manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
- }
- if ( bc->rxgain != 0 ) {
- cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
- manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
- }
- }
- break;
-
- default:
- break;
- }
-
- /* Later we should think about sending bchannel data directly to misdn. */
- msg = isdn_msg_build_event(msgs_g, bc, event, stack->nt);
- msg_queue_tail(&stack->downqueue, msg);
- sem_post(&glob_mgr->new_msg);
-
-OUT:
- misdn_send_unlock(bc);
-
-OUT_POST_UNLOCK:
- return retval;
-}
-
-
-static int handle_err(msg_t *msg)
-{
- iframe_t *frm = (iframe_t*) msg->data;
-
-
- if (!frm->addr) {
- static int cnt=0;
- if (!cnt)
- cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x\n",frm->prim,frm->dinfo);
- cnt++;
- if (cnt>100) {
- cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x (already more than 100 of them)\n",frm->prim,frm->dinfo);
- cnt=0;
- }
-
- free_msg(msg);
- return 1;
-
- }
-
- switch (frm->prim) {
- case MGR_SETSTACK|INDICATION:
- return handle_bchan(msg);
- break;
-
- case MGR_SETSTACK|CONFIRM:
- case MGR_CLEARSTACK|CONFIRM:
- free_msg(msg) ;
- return 1;
- break;
-
- case DL_DATA|CONFIRM:
- cb_log(4,0,"DL_DATA|CONFIRM\n");
- free_msg(msg);
- return 1;
-
- case PH_CONTROL|CONFIRM:
- cb_log(4,0,"PH_CONTROL|CONFIRM\n");
- free_msg(msg);
- return 1;
-
- case DL_DATA|INDICATION:
- {
- struct misdn_bchannel *bc;
- int port=(frm->addr&MASTER_ID_MASK) >> 8;
- int channel=(frm->addr&CHILD_ID_MASK) >> 16;
-
- /*we flush the read buffer here*/
-
- cb_log(9,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
-
- free_msg(msg) ;
- return 1;
-
-
- bc=find_bc_by_channel( port , channel);
-
- if (!bc) {
- struct misdn_stack *stack=find_stack_by_port( port );
-
- if (!stack) {
- cb_log(0,0," --> stack not found\n");
- free_msg(msg);
- return 1;
- }
-
- cb_log(0,0," --> bc not found by channel\n");
- if (stack->l2link)
- misdn_lib_get_l2_down(stack);
-
- if (stack->l1link)
- misdn_lib_get_l1_down(stack);
-
- free_msg(msg);
- return 1;
- }
-
- cb_log(3,port," --> BC in state:%s\n", bc_state2str(bc->bc_state));
- }
- }
-
- return 0;
-}
-
-#if 0
-static int queue_l2l3(msg_t *msg)
-{
- iframe_t *frm= (iframe_t*)msg->data;
- struct misdn_stack *stack;
- stack=find_stack_by_addr( frm->addr );
-
-
- if (!stack) {
- return 0;
- }
-
- msg_queue_tail(&stack->upqueue, msg);
- sem_post(&glob_mgr->new_msg);
- return 1;
-}
-#endif
-
-int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
-{
-
- if (frm->dinfo==0xffffffff && frm->prim==(PH_DATA|CONFIRM)) {
- cb_log(0,0,"SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
- }
-
- if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
- if (handle_bchan(msg)) {
- return 0 ;
- }
- }
-
-#ifdef RECV_FRM_SYSLOG_DEBUG
- syslog(LOG_NOTICE,"mISDN recv: P(%02d): ADDR:%x PRIM:%x DINFO:%x\n",stack->port, frm->addr, frm->prim, frm->dinfo);
-#endif
-
- if (handle_timers(msg))
- return 0 ;
-
-
- if (handle_mgmt(msg))
- return 0 ;
-
- if (handle_l2(msg))
- return 0 ;
-
- /* Its important to handle l1 AFTER l2 */
- if (handle_l1(msg))
- return 0 ;
-
- if (handle_frm_nt(msg)) {
- return 0;
- }
-
- if (handle_frm(msg)) {
- return 0;
- }
-
- if (handle_err(msg)) {
- return 0 ;
- }
-
- cb_log(0, 0, "Unhandled Message: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);
- free_msg(msg);
-
-
- return 0;
-}
-
-
-
-
-int misdn_lib_get_port_info(int port)
-{
- msg_t *msg=alloc_msg(MAX_MSG_SIZE);
- iframe_t *frm;
- struct misdn_stack *stack=find_stack_by_port(port);
- if (!msg) {
- cb_log(0, port, "misgn_lib_get_port: alloc_msg failed!\n");
- return -1;
- }
- frm=(iframe_t*)msg->data;
- if (!stack ) {
- cb_log(0, port, "There is no Stack for this port.\n");
- return -1;
- }
- /* activate bchannel */
- frm->prim = CC_STATUS_ENQUIRY | REQUEST;
-
- frm->addr = stack->upper_id| FLG_MSG_DOWN;
-
- frm->dinfo = 0;
- frm->len = 0;
-
- msg_queue_tail(&glob_mgr->activatequeue, msg);
- sem_post(&glob_mgr->new_msg);
-
-
- return 0;
-}
-
-
-int queue_cleanup_bc(struct misdn_bchannel *bc)
-{
- msg_t *msg=alloc_msg(MAX_MSG_SIZE);
- iframe_t *frm;
- if (!msg) {
- cb_log(0, bc->port, "misgn_lib_get_port: alloc_msg failed!\n");
- return -1;
- }
- frm=(iframe_t*)msg->data;
-
- /* activate bchannel */
- frm->prim = MGR_CLEARSTACK| REQUEST;
-
- frm->addr = bc->l3_id;
-
- frm->dinfo = bc->port;
- frm->len = 0;
-
- msg_queue_tail(&glob_mgr->activatequeue, msg);
- sem_post(&glob_mgr->new_msg);
-
- return 0;
-
-}
-
-int misdn_lib_pid_restart(int pid)
-{
- struct misdn_bchannel *bc=manager_find_bc_by_pid(pid);
-
- if (bc) {
- manager_clean_bc(bc);
- }
- return 0;
-}
-
-/*Sends Restart message for every bchnanel*/
-int misdn_lib_send_restart(int port, int channel)
-{
- struct misdn_bchannel dummybc;
- struct misdn_stack *stack=find_stack_by_port(port);
- cb_log(0, port, "Sending Restarts on this port.\n");
-
- make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
-
- /*default is all channels*/
- if (channel <0) {
- dummybc.channel=-1;
- cb_log(0, port, "Restarting and all Interfaces\n");
- misdn_lib_send_event(&dummybc, EVENT_RESTART);
-
- return 0;
- }
-
- /*if a channel is specified we restart only this one*/
- if (channel >0) {
- int cnt;
- dummybc.channel=channel;
- cb_log(0, port, "Restarting and cleaning channel %d\n",channel);
- misdn_lib_send_event(&dummybc, EVENT_RESTART);
- /* clean up chan in stack, to be sure we don't think it's
- * in use anymore */
- for (cnt=0; cnt<=stack->b_num; cnt++) {
- if (stack->bc[cnt].channel == channel) {
- empty_bc(&stack->bc[cnt]);
- clean_up_bc(&stack->bc[cnt]);
- stack->bc[cnt].in_use=0;
- }
- }
- }
-
- return 0;
-}
-
-/*reinitializes the L2/L3*/
-int misdn_lib_port_restart(int port)
-{
- struct misdn_stack *stack=find_stack_by_port(port);
-
- cb_log(0, port, "Restarting this port.\n");
- if (stack) {
- cb_log(0, port, "Stack:%p\n",stack);
-
- clear_l3(stack);
- {
- msg_t *msg=alloc_msg(MAX_MSG_SIZE);
- iframe_t *frm;
-
- if (!msg) {
- cb_log(0, port, "port_restart: alloc_msg failed\n");
- return -1;
- }
-
- frm=(iframe_t*)msg->data;
- /* we must activate if we are deactivated */
- /* activate bchannel */
- frm->prim = DL_RELEASE | REQUEST;
- frm->addr = stack->upper_id | FLG_MSG_DOWN;
-
- frm->dinfo = 0;
- frm->len = 0;
- msg_queue_tail(&glob_mgr->activatequeue, msg);
- sem_post(&glob_mgr->new_msg);
- }
-
- if (stack->nt)
- misdn_lib_reinit_nt_stack(stack->port);
-
- }
-
- return 0;
-}
-
-
-
-sem_t handler_started;
-
-static void manager_event_handler(void *arg)
-{
- sem_post(&handler_started);
- while (1) {
- struct misdn_stack *stack;
- msg_t *msg;
-
- /** wait for events **/
- sem_wait(&glob_mgr->new_msg);
-
- for (msg=msg_dequeue(&glob_mgr->activatequeue);
- msg;
- msg=msg_dequeue(&glob_mgr->activatequeue)
- )
- {
-
- iframe_t *frm = (iframe_t*) msg->data ;
-
- switch ( frm->prim) {
-
- case MGR_CLEARSTACK | REQUEST:
- /*a queued bchannel cleanup*/
- {
- struct misdn_bchannel *bc;
- struct misdn_stack *stack=find_stack_by_port(frm->dinfo);
- if (!stack) {
- cb_log(0,0,"no stack found with port [%d]!! so we cannot cleanup the bc\n",frm->dinfo);
- free_msg(msg);
- break;
- }
-
- bc=find_bc_by_l3id(stack,frm->addr);
- if (bc) {
- cb_log(1,bc->port,"CLEARSTACK queued, cleaning up\n");
- clean_up_bc(bc);
- } else {
- cb_log(0,stack->port,"bc could not be cleaned correctly !! addr [%x]\n",frm->addr);
- }
- }
- free_msg(msg);
- break;
- case MGR_SETSTACK | REQUEST :
- break;
- default:
- mISDN_write(glob_mgr->midev, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
- free_msg(msg);
- }
- }
-
- for (stack=glob_mgr->stack_list;
- stack;
- stack=stack->next ) {
-
- while ( (msg=msg_dequeue(&stack->upqueue)) ) {
- /** Handle L2/3 Signalling after bchans **/
- if (!handle_frm_nt(msg)) {
- /* Maybe it's TE */
- if (!handle_frm(msg)) {
- /* wow none! */
- cb_log(0,stack->port,"Wow we've got a strange issue while dequeueing a Frame\n");
- }
- }
- }
-
- /* Here we should check if we really want to
- send all the messages we've queued, lets
- assume we've queued a Disconnect, but
- received it already from the other side!*/
-
- while ( (msg=msg_dequeue(&stack->downqueue)) ) {
- if (stack->nt ) {
- if (stack->nst.manager_l3(&stack->nst, msg))
- cb_log(0, stack->port, "Error@ Sending Message in NT-Stack.\n");
-
- } else {
- iframe_t *frm = (iframe_t *)msg->data;
- struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo);
- if (bc) send_msg(glob_mgr->midev, bc, msg);
- else {
- if (frm->dinfo == MISDN_ID_GLOBAL) {
- struct misdn_bchannel dummybc;
- make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
- send_msg(glob_mgr->midev, &dummybc, msg);
- }
- }
- }
- }
- }
- }
-}
-
-
-int misdn_lib_maxports_get() { /** BE AWARE WE HAVE NO CB_LOG HERE! **/
-
- int i = mISDN_open();
- int max=0;
-
- if (i<0)
- return -1;
-
- max = mISDN_get_stack_count(i);
-
- mISDN_close(i);
-
- return max;
-}
-
-
-void misdn_lib_nt_keepcalls( int kc)
-{
-#ifdef FEATURE_NET_KEEPCALLS
- if (kc) {
- struct misdn_stack *stack=get_misdn_stack();
- for ( ; stack; stack=stack->next) {
- stack->nst.feature |= FEATURE_NET_KEEPCALLS;
- }
- }
-#endif
-}
-
-void misdn_lib_nt_debug_init( int flags, char *file )
-{
- int static init=0;
- char *f;
-
- if (!flags)
- f=NULL;
- else
- f=file;
-
- if (!init) {
- debug_init( flags , f, f, f);
- init=1;
- } else {
- debug_close();
- debug_init( flags , f, f, f);
- }
-}
-
-
-int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
-{
- struct misdn_lib *mgr=calloc(1, sizeof(struct misdn_lib));
- char *tok, *tokb;
- char plist[1024];
- int midev;
- int port_count=0;
-
- cb_log = iface->cb_log;
- cb_event = iface->cb_event;
- cb_jb_empty = iface->cb_jb_empty;
-
- glob_mgr = mgr;
-
- msg_init();
-
- misdn_lib_nt_debug_init(0,NULL);
-
- if (!portlist || (*portlist == 0) ) return 1;
-
- init_flip_bits();
-
- {
- strncpy(plist,portlist, 1024);
- plist[1023] = 0;
- }
-
- memcpy(tone_425_flip,tone_425,TONE_425_SIZE);
- flip_buf_bits(tone_425_flip,TONE_425_SIZE);
-
- memcpy(tone_silence_flip,tone_SILENCE,TONE_SILENCE_SIZE);
- flip_buf_bits(tone_silence_flip,TONE_SILENCE_SIZE);
-
- midev=te_lib_init();
- mgr->midev=midev;
-
- port_count=mISDN_get_stack_count(midev);
-
- msg_queue_init(&mgr->activatequeue);
-
- if (sem_init(&mgr->new_msg, 1, 0)<0)
- sem_init(&mgr->new_msg, 0, 0);
-
- for (tok=strtok_r(plist," ,",&tokb );
- tok;
- tok=strtok_r(NULL," ,",&tokb)) {
- int port = atoi(tok);
- struct misdn_stack *stack;
- static int first=1;
- int ptp=0;
-
- if (strstr(tok, "ptp"))
- ptp=1;
-
- if (port > port_count) {
- cb_log(0, port, "Couldn't Initialize this port since we have only %d ports\n", port_count);
- exit(1);
- }
- stack=stack_init(midev, port, ptp);
-
- if (!stack) {
- perror("init_stack");
- exit(1);
- }
-
- {
- int i;
- for(i=0;i<=stack->b_num; i++) {
- int r;
- if ((r=init_bc(stack, &stack->bc[i], stack->midev,port,i, "", 1))<0) {
- cb_log(0, port, "Got Err @ init_bc :%d\n",r);
- exit(1);
- }
- }
- }
-
- if (stack && first) {
- mgr->stack_list=stack;
- first=0;
- continue;
- }
-
- if (stack) {
- struct misdn_stack * help;
- for ( help=mgr->stack_list; help; help=help->next )
- if (help->next == NULL) break;
- help->next=stack;
- }
-
- }
-
- if (sem_init(&handler_started, 1, 0)<0)
- sem_init(&handler_started, 0, 0);
-
- cb_log(8, 0, "Starting Event Handler\n");
- pthread_create( &mgr->event_handler_thread, NULL,(void*)manager_event_handler, mgr);
-
- sem_wait(&handler_started) ;
- cb_log(8, 0, "Starting Event Catcher\n");
- pthread_create( &mgr->event_thread, NULL, (void*)misdn_lib_isdn_event_catcher, mgr);
-
- cb_log(8, 0, "Event Catcher started\n");
-
- global_state= MISDN_INITIALIZED;
-
- return (mgr == NULL);
-}
-
-void misdn_lib_destroy()
-{
- struct misdn_stack *help;
- int i;
-
- for ( help=glob_mgr->stack_list; help; help=help->next ) {
- for(i=0;i<=help->b_num; i++) {
- char buf[1024];
- mISDN_write_frame(help->midev, buf, help->bc[i].addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
- help->bc[i].addr = 0;
- }
- cb_log (1, help->port, "Destroying this port.\n");
- stack_destroy(help);
- }
-
- if (global_state == MISDN_INITIALIZED) {
- cb_log(4, 0, "Killing Handler Thread\n");
- if ( pthread_cancel(glob_mgr->event_handler_thread) == 0 ) {
- cb_log(4, 0, "Joining Handler Thread\n");
- pthread_join(glob_mgr->event_handler_thread, NULL);
- }
-
- cb_log(4, 0, "Killing Main Thread\n");
- if ( pthread_cancel(glob_mgr->event_thread) == 0 ) {
- cb_log(4, 0, "Joining Main Thread\n");
- pthread_join(glob_mgr->event_thread, NULL);
- }
- }
-
- cb_log(1, 0, "Closing mISDN device\n");
- te_lib_destroy(glob_mgr->midev);
-}
-
-char *manager_isdn_get_info(enum event_e event)
-{
- return isdn_get_info(msgs_g , event, 0);
-}
-
-void manager_bchannel_activate(struct misdn_bchannel *bc)
-{
- char buf[128];
-
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- if (!stack) {
- cb_log(0, bc->port, "bchannel_activate: Stack not found !");
- return ;
- }
-
- /* we must activate if we are deactivated */
- clear_ibuffer(bc->astbuf);
-
- cb_log(5, stack->port, "$$$ Bchan Activated addr %x\n", bc->addr);
-
- mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN, DL_ESTABLISH | REQUEST, 0,0, NULL, TIMEOUT_1SEC);
-
- return ;
-}
-
-
-void manager_bchannel_deactivate(struct misdn_bchannel * bc)
-{
- char buf[128];
- iframe_t dact;
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- switch (bc->bc_state) {
- case BCHAN_ACTIVATED:
- break;
- case BCHAN_BRIDGED:
- misdn_split_conf(bc,bc->conf_id);
- break;
- default:
- cb_log( 4, bc->port,"bchan_deactivate: called but not activated\n");
- return ;
-
- }
-
- cb_log(5, stack->port, "$$$ Bchan deActivated addr %x\n", bc->addr);
-
- bc->generate_tone=0;
-
- dact.prim = DL_RELEASE | REQUEST;
- dact.addr = bc->addr | FLG_MSG_DOWN;
- dact.dinfo = 0;
- dact.len = 0;
- mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN, DL_RELEASE|REQUEST,0,0,NULL, TIMEOUT_1SEC);
-
- clear_ibuffer(bc->astbuf);
-
- bc_state_change(bc,BCHAN_RELEASE);
-
- return;
-}
-
-
-int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
-{
- char buf[4096 + mISDN_HEADER_LEN];
- iframe_t *frm;
- int r;
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- switch (bc->bc_state) {
- case BCHAN_ACTIVATED:
- case BCHAN_BRIDGED:
- break;
- default:
- cb_log(3, bc->port, "BC not yet activated (state:%s)\n",bc_state2str(bc->bc_state));
- return -1;
- }
-
- frm= (iframe_t*)buf;
-
- frm->prim = DL_DATA|REQUEST;
- frm->dinfo = 0;
- frm->addr = bc->addr | FLG_MSG_DOWN ;
-
- frm->len = len;
- memcpy(&buf[mISDN_HEADER_LEN], data,len);
-
- if ( misdn_cap_is_speech(bc->capability) )
- flip_buf_bits( &buf[mISDN_HEADER_LEN], len);
- else
- cb_log(6, stack->port, "Writing %d data bytes\n",len);
-
- cb_log(9, stack->port, "Writing %d bytes 2 mISDN\n",len);
- r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_INFINIT);
- return 0;
-}
-
-
-
-/*
- * send control information to the channel (dsp-module)
- */
-void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2)
-{
- unsigned char buffer[mISDN_HEADER_LEN+2*sizeof(int)];
- iframe_t *ctrl = (iframe_t *)buffer; /* preload data */
- unsigned int *d = (unsigned int*)&ctrl->data.p;
- /*struct misdn_stack *stack=get_stack_by_bc(bc);*/
-
- cb_log(4,bc->port,"ph_control: c1:%x c2:%x\n",c1,c2);
-
- ctrl->prim = PH_CONTROL | REQUEST;
- ctrl->addr = bc->addr | FLG_MSG_DOWN;
- ctrl->dinfo = 0;
- ctrl->len = sizeof(unsigned int)*2;
- *d++ = c1;
- *d++ = c2;
- mISDN_write(glob_mgr->midev, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
-}
-
-/*
- * allow live control of channel parameters
- */
-void isdn_lib_update_rxgain (struct misdn_bchannel *bc)
-{
- manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
-}
-
-void isdn_lib_update_txgain (struct misdn_bchannel *bc)
-{
- manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
-}
-
-void isdn_lib_update_ec (struct misdn_bchannel *bc)
-{
-#ifdef MISDN_1_2
- if (*bc->pipeline)
-#else
- if (bc->ec_enable)
-#endif
- manager_ec_enable(bc);
- else
- manager_ec_disable(bc);
-}
-
-void isdn_lib_stop_dtmf (struct misdn_bchannel *bc)
-{
- manager_ph_control(bc, DTMF_TONE_STOP, 0);
-}
-
-/*
- * send control information to the channel (dsp-module)
- */
-void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len)
-{
- unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
- iframe_t *ctrl = (iframe_t *)buffer;
- unsigned int *d = (unsigned int *)&ctrl->data.p;
- /*struct misdn_stack *stack=get_stack_by_bc(bc);*/
-
- ctrl->prim = PH_CONTROL | REQUEST;
- ctrl->addr = bc->addr | FLG_MSG_DOWN;
- ctrl->dinfo = 0;
- ctrl->len = sizeof(unsigned int) + c2_len;
- *d++ = c1;
- memcpy(d, c2, c2_len);
- mISDN_write(glob_mgr->midev, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
-}
-
-
-
-
-void manager_clean_bc(struct misdn_bchannel *bc )
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- if (bc->channel>0)
- empty_chan_in_stack(stack, bc->channel);
- empty_bc(bc);
- bc->in_use=0;
-
- cb_event(EVENT_CLEANUP, bc, NULL);
-}
-
-
-void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder)
-{
- struct misdn_bchannel *help;
- cb_log(4,stack->port, "*HOLDER: add %x\n",holder->l3_id);
-
- holder->stack_holder=1;
-
- if (!stack ) return ;
-
- holder->next=NULL;
-
- if (!stack->holding) {
- stack->holding = holder;
- return;
- }
-
- for (help=stack->holding;
- help;
- help=help->next) {
- if (!help->next) {
- help->next=holder;
- break;
- }
- }
-
-}
-
-void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder)
-{
- struct misdn_bchannel *h1;
-
- if (!holder->stack_holder) return;
-
- holder->stack_holder=0;
-
- cb_log(4,stack->port, "*HOLDER: remove %x\n",holder->l3_id);
- if (!stack || ! stack->holding) return;
-
- if (holder == stack->holding) {
- stack->holding = stack->holding->next;
- return;
- }
-
- for (h1=stack->holding;
- h1;
- h1=h1->next) {
- if (h1->next == holder) {
- h1->next=h1->next->next;
- return ;
- }
- }
-}
-
-struct misdn_bchannel *stack_holder_find_bychan(struct misdn_stack *stack, int chan)
-{
- struct misdn_bchannel *help;
-
- cb_log(4,stack?stack->port:0, "*HOLDER: find_bychan %c\n", chan);
-
- if (!stack) return NULL;
-
- for (help=stack->holding;
- help;
- help=help->next) {
- if (help->channel == chan) {
- cb_log(4,stack->port, "*HOLDER: found_bychan bc\n");
- return help;
- }
- }
-
- cb_log(4,stack->port, "*HOLDER: find_bychan nothing\n");
- return NULL;
-
-}
-
-struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id)
-{
- struct misdn_bchannel *help;
-
- cb_log(4,stack?stack->port:0, "*HOLDER: find %x\n",l3id);
-
- if (!stack) return NULL;
-
- for (help=stack->holding;
- help;
- help=help->next) {
- if (help->l3_id == l3id) {
- cb_log(4,stack->port, "*HOLDER: found bc\n");
- return help;
- }
- }
-
- cb_log(4,stack->port, "*HOLDER: find nothing\n");
- return NULL;
-}
-
-
-
-void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone)
-{
- char buf[mISDN_HEADER_LEN+128];
- iframe_t *frm;
-
- switch(tone) {
- case TONE_DIAL:
- manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_DIALTONE);
- break;
-
- case TONE_ALERTING:
- manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_RINGING);
- break;
-
- case TONE_HANGUP:
- manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_HANGUP);
- break;
-
- case TONE_NONE:
- default:
- manager_ph_control(bc, TONE_PATT_OFF, TONE_GERMAN_HANGUP);
- }
-
- frm=(iframe_t*)buf;
- memset(buf,0,mISDN_HEADER_LEN+128);
-
- frm->prim=DL_DATA|REQUEST;
- frm->addr=bc->addr|FLG_MSG_DOWN;
- frm->dinfo=0;
- frm->len=128;
-
- mISDN_write(glob_mgr->midev, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
-}
-
-
-void manager_ec_enable(struct misdn_bchannel *bc)
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- cb_log(4, stack?stack->port:0,"ec_enable\n");
-
- if (!misdn_cap_is_speech(bc->capability)) {
- cb_log(1, stack?stack->port:0, " --> no speech? cannot enable EC\n");
- } else {
-
-#ifdef MISDN_1_2
- if (*bc->pipeline) {
- cb_log(3, stack?stack->port:0,"Sending Control PIPELINE_CFG %s\n",bc->pipeline);
- manager_ph_control_block(bc, PIPELINE_CFG, bc->pipeline, strlen(bc->pipeline) + 1);
- }
-#else
- int ec_arr[2];
-
- if (bc->ec_enable) {
- cb_log(3, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d\n",bc->ec_deftaps);
-
- switch (bc->ec_deftaps) {
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- case 256:
- case 512:
- case 1024:
- cb_log(4, stack->port, "Taps is %d\n",bc->ec_deftaps);
- break;
- default:
- cb_log(0, stack->port, "Taps should be power of 2\n");
- bc->ec_deftaps=128;
- }
-
- ec_arr[0]=bc->ec_deftaps;
- ec_arr[1]=0;
-
- manager_ph_control_block(bc, ECHOCAN_ON, ec_arr, sizeof(ec_arr));
- }
-#endif
- }
-}
-
-
-
-void manager_ec_disable(struct misdn_bchannel *bc)
-{
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
- cb_log(4, stack?stack->port:0," --> ec_disable\n");
-
- if (!misdn_cap_is_speech(bc->capability)) {
- cb_log(1, stack?stack->port:0, " --> no speech? cannot disable EC\n");
- return;
- }
-
-#ifdef MISDN_1_2
- manager_ph_control_block(bc, PIPELINE_CFG, "", 0);
-#else
- if ( ! bc->ec_enable) {
- cb_log(3, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
- manager_ph_control(bc, ECHOCAN_OFF, 0);
- }
-#endif
-}
-
-struct misdn_stack* get_misdn_stack() {
- return glob_mgr->stack_list;
-}
-
-
-
-void misdn_join_conf(struct misdn_bchannel *bc, int conf_id)
-{
- char data[16];
- int len=15;
-
- bc_state_change(bc,BCHAN_BRIDGED);
- manager_ph_control(bc, CMX_RECEIVE_OFF, 0);
- manager_ph_control(bc, CMX_CONF_JOIN, conf_id);
-
- cb_log(3,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
-
- memset(data,0,15);
-
- misdn_lib_tx2misdn_frm(bc, data, len);
-
-}
-
-
-void misdn_split_conf(struct misdn_bchannel *bc, int conf_id)
-{
- bc_state_change(bc,BCHAN_ACTIVATED);
- manager_ph_control(bc, CMX_RECEIVE_ON, 0);
- manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
-
- cb_log(4,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
-}
-
-void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
-{
- int conf_id=bc1->pid +1;
- struct misdn_bchannel *bc_list[]={
- bc1,bc2,NULL
- };
- struct misdn_bchannel **bc;
-
- cb_log(4, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
-
- for (bc=bc_list; *bc; bc++) {
- (*bc)->conf_id=conf_id;
- cb_log(4, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
-
- switch((*bc)->bc_state) {
- case BCHAN_ACTIVATED:
- misdn_join_conf(*bc,conf_id);
- break;
- default:
- bc_next_state_change(*bc,BCHAN_BRIDGED);
- break;
- }
- }
-}
-
-void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
-{
-
- struct misdn_bchannel *bc_list[]={
- bc1,bc2,NULL
- };
- struct misdn_bchannel **bc;
-
- for (bc=bc_list; *bc; bc++) {
- if ( (*bc)->bc_state == BCHAN_BRIDGED){
- misdn_split_conf( *bc, (*bc)->conf_id);
- } else {
- cb_log( 2, (*bc)->port, "BC not bridged (state:%s) so not splitting it\n",bc_state2str((*bc)->bc_state));
- }
- }
-
-}
-
-
-
-void misdn_lib_echo(struct misdn_bchannel *bc, int onoff)
-{
- cb_log(3,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
- manager_ph_control(bc, onoff?CMX_ECHO_ON:CMX_ECHO_OFF, 0);
-}
-
-
-
-void misdn_lib_reinit_nt_stack(int port)
-{
- struct misdn_stack *stack=find_stack_by_port(port);
-
- if (stack) {
- stack->l2link=0;
- stack->blocked=0;
-
- cleanup_Isdnl3(&stack->nst);
- cleanup_Isdnl2(&stack->nst);
-
-
- memset(&stack->nst, 0, sizeof(net_stack_t));
- memset(&stack->mgr, 0, sizeof(manager_t));
-
- stack->mgr.nst = &stack->nst;
- stack->nst.manager = &stack->mgr;
-
- stack->nst.l3_manager = handle_event_nt;
- stack->nst.device = glob_mgr->midev;
- stack->nst.cardnr = port;
- stack->nst.d_stid = stack->d_stid;
-
- stack->nst.feature = FEATURE_NET_HOLD;
- if (stack->ptp)
- stack->nst.feature |= FEATURE_NET_PTP;
- if (stack->pri)
- stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
-
- stack->nst.l1_id = stack->lower_id;
- stack->nst.l2_id = stack->upper_id;
-
- msg_queue_init(&stack->nst.down_queue);
-
- Isdnl2Init(&stack->nst);
- Isdnl3Init(&stack->nst);
-
- if (!stack->ptp)
- misdn_lib_get_l1_up(stack);
- misdn_lib_get_l2_up(stack);
- }
-}
-
-
diff --git a/1.4/channels/misdn/isdn_lib.h b/1.4/channels/misdn/isdn_lib.h
deleted file mode 100644
index 22f5d9ff6..000000000
--- a/1.4/channels/misdn/isdn_lib.h
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-#ifndef TE_LIB
-#define TE_LIB
-
-#include <mISDNuser/suppserv.h>
-
-/** For initialization usage **/
-/* typedef int ie_nothing_t ;*/
-/** end of init usage **/
-
-
-/*
- * uncomment the following to make chan_misdn create
- * record files in /tmp/misdn-{rx|tx}-PortChannel format
- * */
-
-/*#define MISDN_SAVE_DATA*/
-
-#ifdef WITH_BEROEC
-typedef int beroec_t;
-
-
-enum beroec_type {
- BEROEC_FULLBAND=0,
- BEROEC_SUBBAND,
- BEROEC_FASTSUBBAND
-};
-
-void beroec_init(void);
-void beroec_exit(void);
-beroec_t *beroec_new(int tail, enum beroec_type type, int anti_howl,
- int tonedisable, int zerocoeff, int adapt, int nlp);
-
-void beroec_destroy(beroec_t *ec);
-int beroec_cancel_alaw_chunk(beroec_t *ec,
- char *send,
- char *receive ,
- int len);
-
-int beroec_version(void);
-#endif
-
-
-
-enum tone_e {
- TONE_NONE=0,
- TONE_DIAL,
- TONE_ALERTING,
- TONE_FAR_ALERTING,
- TONE_BUSY,
- TONE_HANGUP,
- TONE_CUSTOM,
- TONE_FILE
-};
-
-
-
-#define MAX_BCHANS 31
-
-enum bchannel_state {
- BCHAN_CLEANED=0,
- BCHAN_EMPTY,
- BCHAN_SETUP,
- BCHAN_SETUPED,
- BCHAN_ACTIVE,
- BCHAN_ACTIVATED,
- BCHAN_BRIDGE,
- BCHAN_BRIDGED,
- BCHAN_RELEASE,
- BCHAN_RELEASED,
- BCHAN_CLEAN,
- BCHAN_CLEAN_REQUEST,
- BCHAN_ERROR
-};
-
-
-enum misdn_err_e {
- ENOCHAN=1
-};
-
-
-enum mISDN_NUMBER_PLAN {
- NUMPLAN_UNINITIALIZED=-1,
- NUMPLAN_INTERNATIONAL=0x1,
- NUMPLAN_NATIONAL=0x2,
- NUMPLAN_SUBSCRIBER=0x4,
- NUMPLAN_UNKNOWN=0x0
-};
-
-
-enum event_response_e {
- RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE,
- RESPONSE_IGNORE_SETUP,
- RESPONSE_RELEASE_SETUP,
- RESPONSE_ERR,
- RESPONSE_OK
-};
-
-
-enum event_e {
- EVENT_NOTHING,
- EVENT_TONE_GENERATE,
- EVENT_BCHAN_DATA,
- EVENT_BCHAN_ACTIVATED,
- EVENT_BCHAN_ERROR,
- EVENT_CLEANUP,
- EVENT_PROCEEDING,
- EVENT_PROGRESS,
- EVENT_SETUP,
- EVENT_ALERTING,
- EVENT_CONNECT,
- EVENT_SETUP_ACKNOWLEDGE,
- EVENT_CONNECT_ACKNOWLEDGE ,
- EVENT_USER_INFORMATION,
- EVENT_SUSPEND_REJECT,
- EVENT_RESUME_REJECT,
- EVENT_HOLD,
- EVENT_SUSPEND,
- EVENT_RESUME,
- EVENT_HOLD_ACKNOWLEDGE,
- EVENT_SUSPEND_ACKNOWLEDGE,
- EVENT_RESUME_ACKNOWLEDGE,
- EVENT_HOLD_REJECT,
- EVENT_RETRIEVE,
- EVENT_RETRIEVE_ACKNOWLEDGE,
- EVENT_RETRIEVE_REJECT,
- EVENT_DISCONNECT,
- EVENT_RESTART,
- EVENT_RELEASE,
- EVENT_RELEASE_COMPLETE,
- EVENT_FACILITY,
- EVENT_NOTIFY,
- EVENT_STATUS_ENQUIRY,
- EVENT_INFORMATION,
- EVENT_STATUS,
- EVENT_TIMEOUT,
- EVENT_DTMF_TONE,
- EVENT_NEW_L3ID,
- EVENT_NEW_BC,
- EVENT_PORT_ALARM,
- EVENT_NEW_CHANNEL,
- EVENT_UNKNOWN
-};
-
-
-enum ie_name_e {
- IE_DUMMY,
- IE_LAST
-};
-
-enum { /* bearer capability */
- INFO_CAPABILITY_SPEECH=0,
- INFO_CAPABILITY_AUDIO_3_1K=0x10 ,
- INFO_CAPABILITY_AUDIO_7K=0x11 ,
- INFO_CAPABILITY_VIDEO =0x18,
- INFO_CAPABILITY_DIGITAL_UNRESTRICTED =0x8,
- INFO_CAPABILITY_DIGITAL_RESTRICTED =0x09,
- INFO_CAPABILITY_DIGITAL_UNRESTRICTED_TONES
-};
-
-enum { /* progress indicators */
- INFO_PI_CALL_NOT_E2E_ISDN =0x01,
- INFO_PI_CALLED_NOT_ISDN =0x02,
- INFO_PI_CALLER_NOT_ISDN =0x03,
- INFO_PI_CALLER_RETURNED_TO_ISDN =0x04,
- INFO_PI_INBAND_AVAILABLE =0x08,
- INFO_PI_DELAY_AT_INTERF =0x0a,
- INFO_PI_INTERWORKING_WITH_PUBLIC =0x10,
- INFO_PI_INTERWORKING_NO_RELEASE =0x11,
- INFO_PI_INTERWORKING_NO_RELEASE_PRE_ANSWER =0x12,
- INFO_PI_INTERWORKING_NO_RELEASE_POST_ANSWER =0x13
-};
-
-enum { /*CODECS*/
- INFO_CODEC_ULAW=2,
- INFO_CODEC_ALAW=3
-};
-
-
-enum layer_e {
- L3,
- L2,
- L1,
- UNKNOWN
-};
-
-
-
-struct misdn_bchannel {
- struct send_lock *send_lock;
-
- int dummy;
-
- int nt;
- int pri;
-
- int port;
- /** init stuff **/
- int b_stid;
- /* int b_addr; */
- int layer_id;
-
- int layer;
-
- /*state stuff*/
- int need_disconnect;
- int need_release;
- int need_release_complete;
-
- int dec;
- /** var stuff**/
- int l3_id;
- int pid;
- int ces;
-
- int restart_channel;
- int channel;
- int channel_preselected;
-
- int in_use;
- int cw;
- int addr;
-
- char * bframe;
- int bframe_len;
- int time_usec;
-
-
- void *astbuf;
-
- void *misdnbuf;
-
- int te_choose_channel;
- int early_bconnect;
-
- /* dtmf digit */
- int dtmf;
- int send_dtmf;
-
- /* get setup ack */
- int need_more_infos;
-
- /* may there be more infos ?*/
- int sending_complete;
-
-
- /* wether we should use jollys dsp or not */
- int nodsp;
-
- /* wether we should use our jitter buf system or not */
- int nojitter;
-
- enum mISDN_NUMBER_PLAN dnumplan;
- enum mISDN_NUMBER_PLAN rnumplan;
- enum mISDN_NUMBER_PLAN onumplan;
- enum mISDN_NUMBER_PLAN cpnnumplan;
-
- int progress_coding;
- int progress_location;
- int progress_indicator;
-
- struct FacParm fac_in;
- struct FacParm fac_out;
-
- /* storing the current AOCD info here */
- enum FacFunction AOCDtype;
- union {
- struct FacAOCDCurrency currency;
- struct FacAOCDChargingUnit chargingUnit;
- } AOCD;
-
- enum event_e evq;
-
- /*** CRYPTING STUFF ***/
-
- int crypt;
- int curprx;
- int curptx;
- char crypt_key[255];
-
- int crypt_state;
-
- /*char ast_dtmf_buf[255];
- char misdn_dtmf_buf[255]; */
-
- /*** CRYPTING STUFF END***/
-
- int active;
- int upset;
-
- int generate_tone;
- int tone_cnt;
-
- enum bchannel_state bc_state;
- enum bchannel_state next_bc_state;
-
- int conf_id;
-
- int holded;
- int stack_holder;
-
- int pres;
- int screen;
-
- int capability;
- int law;
- /** V110 Stuff **/
- int rate;
- int mode;
-
- int user1;
- int urate;
- int hdlc;
- /* V110 */
-
- char display[84];
- char msn[32];
- char oad[32];
- char rad[32];
- char dad[32];
- char cad[32];
- char orig_dad[32];
- char keypad[32];
-
- char info_dad[64];
- char infos_pending[64];
-
-/* unsigned char info_keypad[32]; */
-/* unsigned char clisub[24]; */
-/* unsigned char cldsub[24]; */
-
- char uu[256];
- int uulen;
-
- int cause;
- int out_cause;
-
- /* struct misdn_bchannel hold_bc; */
-
- /** list stuf **/
-
-#ifdef MISDN_1_2
- char pipeline[128];
-#else
- int ec_enable;
- int ec_deftaps;
-#endif
-
- int channel_found;
-
- int orig;
-
- int txgain;
- int rxgain;
-
- struct misdn_bchannel *next;
-};
-
-
-enum event_response_e (*cb_event) (enum event_e event, struct misdn_bchannel *bc, void *user_data);
-void (*cb_log) (int level, int port, char *tmpl, ...);
-int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
-
-struct misdn_lib_iface {
- enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data);
- void (*cb_log)(int level, int port, char *tmpl, ...);
- int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
-};
-
-/***** USER IFACE **********/
-
-void misdn_lib_nt_keepcalls(int kc);
-
-void misdn_lib_nt_debug_init( int flags, char *file );
-
-int misdn_lib_init(char *portlist, struct misdn_lib_iface* iface, void *user_data);
-int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event );
-void misdn_lib_destroy(void);
-
-void misdn_lib_isdn_l1watcher(int port);
-
-void misdn_lib_log_ies(struct misdn_bchannel *bc);
-
-char *manager_isdn_get_info(enum event_e event);
-
-void misdn_lib_transfer(struct misdn_bchannel* holded_bc);
-
-struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout, int dec);
-
-void manager_bchannel_activate(struct misdn_bchannel *bc);
-void manager_bchannel_deactivate(struct misdn_bchannel * bc);
-
-int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len);
-
-void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2);
-
-void isdn_lib_update_rxgain (struct misdn_bchannel *bc);
-void isdn_lib_update_txgain (struct misdn_bchannel *bc);
-void isdn_lib_update_ec (struct misdn_bchannel *bc);
-void isdn_lib_stop_dtmf (struct misdn_bchannel *bc);
-
-int misdn_lib_port_restart(int port);
-int misdn_lib_pid_restart(int pid);
-int misdn_lib_send_restart(int port, int channel);
-
-int misdn_lib_get_port_info(int port);
-
-int misdn_lib_is_port_blocked(int port);
-int misdn_lib_port_block(int port);
-int misdn_lib_port_unblock(int port);
-
-int misdn_lib_port_is_pri(int port);
-
-int misdn_lib_port_up(int port, int notcheck);
-
-int misdn_lib_get_port_down(int port);
-
-int misdn_lib_get_port_up (int port) ;
-
-int misdn_lib_maxports_get(void) ;
-
-void misdn_lib_release(struct misdn_bchannel *bc);
-
-int misdn_cap_is_speech(int cap);
-int misdn_inband_avail(struct misdn_bchannel *bc);
-
-void manager_ec_enable(struct misdn_bchannel *bc);
-void manager_ec_disable(struct misdn_bchannel *bc);
-
-void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone);
-
-void get_show_stack_details(int port, char *buf);
-
-
-void misdn_lib_tone_generator_start(struct misdn_bchannel *bc);
-void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc);
-
-
-void misdn_lib_setup_bc(struct misdn_bchannel *bc);
-
-void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2);
-void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2);
-
-void misdn_lib_echo(struct misdn_bchannel *bc, int onoff);
-
-int misdn_lib_is_ptp(int port);
-int misdn_lib_get_maxchans(int port);
-
-void misdn_lib_reinit_nt_stack(int port);
-
-#define PRI_TRANS_CAP_SPEECH 0x0
-#define PRI_TRANS_CAP_DIGITAL 0x08
-#define PRI_TRANS_CAP_RESTRICTED_DIGITAL 0x09
-#define PRI_TRANS_CAP_3_1K_AUDIO 0x10
-#define PRI_TRANS_CAP_7K_AUDIO 0x11
-
-
-
-char *bc_state2str(enum bchannel_state state);
-void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state);
-
-void misdn_dump_chanlist(void);
-
-#endif
diff --git a/1.4/channels/misdn/isdn_lib_intern.h b/1.4/channels/misdn/isdn_lib_intern.h
deleted file mode 100644
index 050c86fee..000000000
--- a/1.4/channels/misdn/isdn_lib_intern.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef ISDN_LIB_INTERN
-#define ISDN_LIB_INTERN
-
-
-#include <mISDNuser/mISDNlib.h>
-#include <mISDNuser/isdn_net.h>
-#include <mISDNuser/l3dss1.h>
-#include <mISDNuser/net_l3.h>
-
-#include <pthread.h>
-
-#include "isdn_lib.h"
-
-#if !defined MISDNUSER_VERSION_CODE || (MISDNUSER_VERSION_CODE < MISDNUSER_VERSION(1, 0, 3))
-#error "You need a newer version of mISDNuser ..."
-#endif
-
-
-#define QI_ELEMENT(a) a.off
-
-
-#ifndef mISDNUSER_HEAD_SIZE
-
-#define mISDNUSER_HEAD_SIZE (sizeof(mISDNuser_head_t))
-/*#define mISDNUSER_HEAD_SIZE (sizeof(mISDN_head_t))*/
-#endif
-
-
-ibuffer_t *astbuf;
-ibuffer_t *misdnbuf;
-
-struct send_lock {
- pthread_mutex_t lock;
-};
-
-
-struct isdn_msg {
- unsigned long misdn_msg;
-
- enum layer_e layer;
- enum event_e event;
-
- void (*msg_parser)(struct isdn_msg *msgs, msg_t *msg, struct misdn_bchannel *bc, int nt);
- msg_t *(*msg_builder)(struct isdn_msg *msgs, struct misdn_bchannel *bc, int nt);
- char *info;
-
-} ;
-
-/* for isdn_msg_parser.c */
-msg_t *create_l3msg(int prim, int mt, int dinfo , int size, int nt);
-
-
-
-struct misdn_stack {
- /** is first element because &nst equals &mISDNlist **/
- net_stack_t nst;
- manager_t mgr;
-
- int d_stid;
-
- int b_num;
-
- int b_stids[MAX_BCHANS + 1];
-
- int ptp;
-
- int l2upcnt;
-
- int l2_id;
- int lower_id;
- int upper_id;
-
-
- int blocked;
-
- int l2link;
-
- time_t l2establish;
-
- int l1link;
-
- int restart_sent;
-
- int midev;
-
- int nt;
-
- int pri;
-
-
- int procids[0x100+1];
-
- msg_queue_t downqueue;
- msg_queue_t upqueue;
- int busy;
-
- int port;
- struct misdn_bchannel bc[MAX_BCHANS + 1];
-
- struct misdn_bchannel* bc_list;
-
- int channels[MAX_BCHANS + 1];
-
-
- struct misdn_bchannel *holding; /* Queue which holds holded channels :) */
-
- struct misdn_stack *next;
-};
-
-
-struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc);
-
-int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *frm, int nt);
-enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *frm, int nt);
-int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *frm, struct misdn_bchannel *bc, int nt);
-char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt);
-msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt);
-int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt);
-char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt);
-
-
-#endif
diff --git a/1.4/channels/misdn/isdn_msg_parser.c b/1.4/channels/misdn/isdn_msg_parser.c
deleted file mode 100644
index a587f8eae..000000000
--- a/1.4/channels/misdn/isdn_msg_parser.c
+++ /dev/null
@@ -1,1348 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-
-#include "isdn_lib_intern.h"
-
-
-#include "isdn_lib.h"
-
-#include "ie.c"
-
-
-static void set_channel(struct misdn_bchannel *bc, int channel)
-{
-
- cb_log(3,bc->port,"set_channel: bc->channel:%d channel:%d\n", bc->channel, channel);
-
-
- if (channel==0xff) {
- /* any channel */
- channel=-1;
- }
-
- /* ALERT: is that everytime true ? */
- if (channel > 0 && bc->nt ) {
-
- if (bc->channel && ( bc->channel != 0xff) ) {
- cb_log(0,bc->port,"We already have a channel (%d)\n", bc->channel);
- } else {
- bc->channel = channel;
- cb_event(EVENT_NEW_CHANNEL,bc,NULL);
- }
- }
-
- if (channel > 0 && !bc->nt ) {
- bc->channel = channel;
- cb_event(EVENT_NEW_CHANNEL,bc,NULL);
- }
-}
-
-static void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- CALL_PROCEEDING_t *proceeding=(CALL_PROCEEDING_t*)((unsigned long)msg->data+ HEADER_LEN);
- //struct misdn_stack *stack=get_stack_by_bc(bc);
-
- {
- int exclusive, channel;
- dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)proceeding, &exclusive, &channel, nt,bc);
-
- set_channel(bc,channel);
-
- }
-
- dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)proceeding, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-
-#if DEBUG
- printf("Parsing PROCEEDING Msg\n");
-#endif
-}
-static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- CALL_PROCEEDING_t *proceeding;
- msg_t *msg =(msg_t*)create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, bc?bc->l3_id:-1, sizeof(CALL_PROCEEDING_t) ,nt);
-
- proceeding=(CALL_PROCEEDING_t*)((msg->data+HEADER_LEN));
-
- enc_ie_channel_id(&proceeding->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-
- if (nt)
- enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
-
-
-#if DEBUG
- printf("Building PROCEEDING Msg\n");
-#endif
- return msg;
-}
-
-static void parse_alerting (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- ALERTING_t *alerting=(ALERTING_t*)((unsigned long)(msg->data+HEADER_LEN));
- //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
-
- dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-#if DEBUG
- printf("Parsing ALERTING Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- ALERTING_t *alerting;
- msg_t *msg =(msg_t*)create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING, bc?bc->l3_id:-1, sizeof(ALERTING_t) ,nt);
-
- alerting=(ALERTING_t*)((msg->data+HEADER_LEN));
-
- enc_ie_channel_id(&alerting->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-
- if (nt)
- enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
-#if DEBUG
- printf("Building ALERTING Msg\n");
-#endif
- return msg;
-}
-
-
-static void parse_progress (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- PROGRESS_t *progress=(PROGRESS_t*)((unsigned long)(msg->data+HEADER_LEN));
- //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
-
- dec_ie_progress(progress->PROGRESS, (Q931_info_t *)progress, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-#if DEBUG
- printf("Parsing PROGRESS Msg\n");
-#endif
-}
-
-static msg_t *build_progress (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- PROGRESS_t *progress;
- msg_t *msg =(msg_t*)create_l3msg(CC_PROGRESS | REQUEST, MT_PROGRESS, bc?bc->l3_id:-1, sizeof(PROGRESS_t) ,nt);
-
- progress=(PROGRESS_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building PROGRESS Msg\n");
-#endif
- return msg;
-}
-
-static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SETUP_t *setup= (SETUP_t*)((unsigned long)msg->data+HEADER_LEN);
- Q931_info_t *qi=(Q931_info_t*)((unsigned long)msg->data+HEADER_LEN);
-
-#if DEBUG
- printf("Parsing SETUP Msg\n");
-#endif
- {
- int type,plan,present, screen;
- char id[32];
- dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, id, sizeof(id)-1, nt,bc);
-
- bc->onumplan=type;
- strcpy(bc->oad, id);
- switch (present) {
- case 0:
- bc->pres=0; /* screened */
- break;
- case 1:
- bc->pres=1; /* not screened */
- break;
- default:
- bc->pres=0;
- }
- switch (screen) {
- case 0:
- break;
- default:
- ;
- }
- }
- {
- int type, plan;
- char number[32];
- dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *)setup, &type, &plan, number, sizeof(number)-1, nt,bc);
- strcpy(bc->dad, number);
- bc->dnumplan=type;
- }
- {
- char keypad[32];
- dec_ie_keypad(setup->KEYPAD, (Q931_info_t *)setup, keypad, sizeof(keypad)-1, nt,bc);
- strcpy(bc->keypad, keypad);
- }
-
- {
- dec_ie_complete(setup->COMPLETE, (Q931_info_t *)setup, &bc->sending_complete, nt,bc);
-
- }
-
- {
- int type, plan, present, screen, reason;
- char id[32];
- dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *)setup, &type, &plan, &present, &screen, &reason, id, sizeof(id)-1, nt,bc);
-
- strcpy(bc->rad, id);
- bc->rnumplan=type;
- }
- {
- int coding, capability, mode, rate, multi, user, async, urate, stopbits, dbits, parity;
- dec_ie_bearer(setup->BEARER, (Q931_info_t *)setup, &coding, &capability, &mode, &rate, &multi, &user, &async, &urate, &stopbits, &dbits, &parity, nt,bc);
- switch (capability) {
- case -1: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
- break;
- case 0: bc->capability=INFO_CAPABILITY_SPEECH;
- break;
- case 18: bc->capability=INFO_CAPABILITY_VIDEO;
- break;
- case 8: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
- bc->user1 = user;
- bc->urate = urate;
-
- bc->rate = rate;
- bc->mode = mode;
- break;
- case 9: bc->capability=INFO_CAPABILITY_DIGITAL_RESTRICTED;
- break;
- default:
- break;
- }
-
- switch(user) {
- case 2:
- bc->law=INFO_CODEC_ULAW;
- break;
- case 3:
- bc->law=INFO_CODEC_ALAW;
- break;
- default:
- bc->law=INFO_CODEC_ALAW;
-
- }
-
- bc->capability=capability;
- }
- {
- int exclusive, channel;
- dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)setup, &exclusive, &channel, nt,bc);
-
- set_channel(bc,channel);
- }
-
- {
- int protocol ;
- dec_ie_useruser(setup->USER_USER, (Q931_info_t *)setup, &protocol, bc->uu, &bc->uulen, nt,bc);
- if (bc->uulen) cb_log(1,bc->port,"USERUESRINFO:%s\n",bc->uu);
- else
- cb_log(1,bc->port,"NO USERUESRINFO\n");
- }
-
- dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-}
-
-#define ANY_CHANNEL 0xff /* IE attribut for 'any channel' */
-static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SETUP_t *setup;
- msg_t *msg =(msg_t*)create_l3msg(CC_SETUP | REQUEST, MT_SETUP, bc?bc->l3_id:-1, sizeof(SETUP_t) ,nt);
-
- setup=(SETUP_t*)((msg->data+HEADER_LEN));
-
- if (bc->channel == 0 || bc->channel == ANY_CHANNEL || bc->channel==-1)
- enc_ie_channel_id(&setup->CHANNEL_ID, msg, 0, bc->channel, nt,bc);
- else
- enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
-
-
- {
- int type=bc->onumplan,plan=1,present=bc->pres,screen=bc->screen;
- enc_ie_calling_pn(&setup->CALLING_PN, msg, type, plan, present,
- screen, bc->oad, nt, bc);
- }
-
- {
- if (bc->dad[0])
- enc_ie_called_pn(&setup->CALLED_PN, msg, bc->dnumplan, 1, bc->dad, nt,bc);
- }
-
- {
- if (bc->rad[0])
- enc_ie_redir_nr(&setup->REDIR_NR, msg, 1, 1, bc->pres, bc->screen, 0, bc->rad, nt,bc);
- }
-
- {
- if (bc->keypad[0])
- enc_ie_keypad(&setup->KEYPAD, msg, bc->keypad, nt,bc);
- }
-
-
- if (*bc->display) {
- enc_ie_display(&setup->DISPLAY, msg, bc->display, nt,bc);
- }
-
- {
- int coding=0, capability, mode=0 /* 2 for packet ! */
- ,user, rate=0x10;
-
- switch (bc->law) {
- case INFO_CODEC_ULAW: user=2;
- break;
- case INFO_CODEC_ALAW: user=3;
- break;
- default:
- user=3;
- }
-
- switch (bc->capability) {
- case INFO_CAPABILITY_SPEECH: capability = 0;
- break;
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
- user=-1;
- mode=bc->mode;
- rate=bc->rate;
- break;
- case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
- user=-1;
- break;
- default:
- capability=bc->capability;
- }
-
-
-
- enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
- }
-
- if (bc->sending_complete) {
- enc_ie_complete(&setup->COMPLETE,msg, bc->sending_complete, nt, bc);
- }
-
- if (bc->uulen) {
- int protocol=4;
- enc_ie_useruser(&setup->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
- }
-
-#if DEBUG
- printf("Building SETUP Msg\n");
-#endif
- return msg;
-}
-
-static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- CONNECT_t *connect=(CONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
-
- int plan,pres,screen;
-
- bc->ces = connect->ces;
- bc->ces = connect->ces;
-
- dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
- dec_ie_connected_pn(connect->CONNECT_PN,(Q931_info_t *)connect, &bc->cpnnumplan, &plan, &pres, &screen, bc->cad, 31, nt, bc);
-
- /*
- cb_log(1,bc->port,"CONNETED PN: %s cpn_dialplan:%d\n", connected_pn, type);
- */
-
-#if DEBUG
- printf("Parsing CONNECT Msg\n");
-#endif
-}
-
-static msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- CONNECT_t *connect;
- msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT, bc?bc->l3_id:-1, sizeof(CONNECT_t) ,nt);
-
- cb_log(6,bc->port,"BUILD_CONNECT: bc:%p bc->l3id:%d, nt:%d\n",bc,bc->l3_id,nt);
-
- connect=(CONNECT_t*)((msg->data+HEADER_LEN));
-
- if (nt) {
- time_t now;
- time(&now);
- enc_ie_date(&connect->DATE, msg, now, nt,bc);
- }
-
- {
- int type=bc->cpnnumplan, plan=1, present=2, screen=0;
- enc_ie_connected_pn(&connect->CONNECT_PN, msg, type,plan, present, screen, bc->cad, nt , bc);
- }
-
-#if DEBUG
- printf("Building CONNECT Msg\n");
-#endif
- return msg;
-}
-
-static void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SETUP_ACKNOWLEDGE_t *setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((unsigned long)(msg->data+HEADER_LEN));
-
- {
- int exclusive, channel;
- dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)setup_acknowledge, &exclusive, &channel, nt,bc);
-
-
- set_channel(bc, channel);
- }
-
- dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-#if DEBUG
- printf("Parsing SETUP_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SETUP_ACKNOWLEDGE_t *setup_acknowledge;
- msg_t *msg =(msg_t*)create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(SETUP_ACKNOWLEDGE_t) ,nt);
-
- setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
- enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-
- if (nt)
- enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
-
-#if DEBUG
- printf("Building SETUP_ACKNOWLEDGE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_connect_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing CONNECT_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_connect_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
- msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT, bc?bc->l3_id:-1, sizeof(CONNECT_ACKNOWLEDGE_t) ,nt);
-
- connect_acknowledge=(CONNECT_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
- enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
-
-#if DEBUG
- printf("Building CONNECT_ACKNOWLEDGE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_user_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing USER_INFORMATION Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_user_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- USER_INFORMATION_t *user_information;
- msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION, bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt);
-
- user_information=(USER_INFORMATION_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building USER_INFORMATION Msg\n");
-#endif
- return msg;
-}
-
-static void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing SUSPEND_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SUSPEND_REJECT_t *suspend_reject;
- msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt);
-
- suspend_reject=(SUSPEND_REJECT_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building SUSPEND_REJECT Msg\n");
-#endif
- return msg;
-}
-
-static void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing RESUME_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RESUME_REJECT_t *resume_reject;
- msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT, bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt);
-
- resume_reject=(RESUME_REJECT_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building RESUME_REJECT Msg\n");
-#endif
- return msg;
-}
-
-static void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing HOLD Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- HOLD_t *hold;
- msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD, bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt);
-
- hold=(HOLD_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building HOLD Msg\n");
-#endif
- return msg;
-}
-
-static void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing SUSPEND Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SUSPEND_t *suspend;
- msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND, bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt);
-
- suspend=(SUSPEND_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building SUSPEND Msg\n");
-#endif
- return msg;
-}
-
-static void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing RESUME Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RESUME_t *resume;
- msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME, bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt);
-
- resume=(RESUME_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building RESUME Msg\n");
-#endif
- return msg;
-}
-
-static void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing HOLD_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- HOLD_ACKNOWLEDGE_t *hold_acknowledge;
- msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt);
-
- hold_acknowledge=(HOLD_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building HOLD_ACKNOWLEDGE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
- msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt);
-
- suspend_acknowledge=(SUSPEND_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building SUSPEND_ACKNOWLEDGE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing RESUME_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RESUME_ACKNOWLEDGE_t *resume_acknowledge;
- msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt);
-
- resume_acknowledge=(RESUME_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building RESUME_ACKNOWLEDGE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing HOLD_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- HOLD_REJECT_t *hold_reject;
- msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT, bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt);
-
- hold_reject=(HOLD_REJECT_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building HOLD_REJECT Msg\n");
-#endif
- return msg;
-}
-
-static void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing RETRIEVE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RETRIEVE_t *retrieve;
- msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE, bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt);
-
- retrieve=(RETRIEVE_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building RETRIEVE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
- msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt);
-
- retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
- enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
-#if DEBUG
- printf("Building RETRIEVE_ACKNOWLEDGE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing RETRIEVE_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RETRIEVE_REJECT_t *retrieve_reject;
- msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT, bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt);
-
- retrieve_reject=(RETRIEVE_REJECT_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building RETRIEVE_REJECT Msg\n");
-#endif
- return msg;
-}
-
-static void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- DISCONNECT_t *disconnect=(DISCONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
- int location;
- int cause;
- dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
- if (cause>0) bc->cause=cause;
-
- dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-#if DEBUG
- printf("Parsing DISCONNECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- DISCONNECT_t *disconnect;
- msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt);
-
- disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
-
- enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
- if (nt) enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt?1:5, 8 ,nt,bc);
-
- if (bc->uulen) {
- int protocol=4;
- enc_ie_useruser(&disconnect->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
- }
-
-#if DEBUG
- printf("Building DISCONNECT Msg\n");
-#endif
- return msg;
-}
-
-static void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RESTART_t *restart=(RESTART_t*)((unsigned long)(msg->data+HEADER_LEN));
-
- struct misdn_stack *stack=get_stack_by_bc(bc);
-
-#if DEBUG
- printf("Parsing RESTART Msg\n");
-#endif
-
- {
- int exclusive;
- dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &bc->restart_channel, nt,bc);
- cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n", bc->restart_channel);
- }
-
-}
-
-static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RESTART_t *restart;
- msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART, bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt);
-
- restart=(RESTART_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building RESTART Msg\n");
-#endif
-
- if (bc->channel > 0) {
- enc_ie_channel_id(&restart->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
- enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x80, nt, bc);
- } else {
- enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x87, nt, bc);
- }
-
- cb_log(0,bc->port, "Restarting channel %d\n", bc->channel);
-
- return msg;
-}
-
-static void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RELEASE_t *release=(RELEASE_t*)((unsigned long)(msg->data+HEADER_LEN));
- int location;
- int cause;
-
- dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
- if (cause>0) bc->cause=cause;
-#if DEBUG
- printf("Parsing RELEASE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RELEASE_t *release;
- msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt);
-
- release=(RELEASE_t*)((msg->data+HEADER_LEN));
-
- if (bc->out_cause>= 0)
- enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
-
- if (bc->uulen) {
- int protocol=4;
- enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
- }
-
-#if DEBUG
- printf("Building RELEASE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RELEASE_COMPLETE_t *release_complete=(RELEASE_COMPLETE_t*)((unsigned long)(msg->data+HEADER_LEN));
- int location;
- int cause;
- iframe_t *frm = (iframe_t*) msg->data;
-
- struct misdn_stack *stack=get_stack_by_bc(bc);
- mISDNuser_head_t *hh;
- hh=(mISDNuser_head_t*)msg->data;
-
- /*hh=(mISDN_head_t*)msg->data;
- mISDN_head_t *hh;*/
-
- if (nt) {
- if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
- cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
- return;
- }
- } else {
- if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
- cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
- return;
- }
- }
- dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
- if (cause>0) bc->cause=cause;
-
-#if DEBUG
- printf("Parsing RELEASE_COMPLETE Msg\n");
-#endif
-}
-
-static msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- RELEASE_COMPLETE_t *release_complete;
- msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt);
-
- release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN));
-
- enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
-
- if (bc->uulen) {
- int protocol=4;
- enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
- }
-
-#if DEBUG
- printf("Building RELEASE_COMPLETE Msg\n");
-#endif
- return msg;
-}
-
-static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
- FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
- Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
- unsigned char *p = NULL;
- int err;
-
-#if DEBUG
- printf("Parsing FACILITY Msg\n");
-#endif
-
- if (!bc->nt) {
- if (qi->QI_ELEMENT(facility))
- p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
- } else {
- p = facility->FACILITY;
- }
- if (!p)
- return;
-
- err = decodeFac(p, &(bc->fac_in));
- if (err) {
- cb_log(1, bc->port, "Decoding FACILITY failed! (%d)\n", err);
- }
-}
-
-static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int len,
- HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
- unsigned char *ie_fac,
- fac_tmp[256];
- msg_t *msg =(msg_t*)create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc?bc->l3_id:-1, sizeof(FACILITY_t) ,nt);
- FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
- Q931_info_t *qi;
-
-#if DEBUG
- printf("Building FACILITY Msg\n");
-#endif
-
- len = encodeFac(fac_tmp, &(bc->fac_out));
- if (len <= 0)
- return NULL;
-
- ie_fac = msg_put(msg, len);
- if (bc->nt) {
- facility->FACILITY = ie_fac + 1;
- } else {
- qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
- qi->QI_ELEMENT(facility) = ie_fac - (unsigned char *)qi - sizeof(Q931_info_t);
- }
-
- memcpy(ie_fac, fac_tmp, len);
-
- if (*bc->display) {
- printf("Sending %s as Display\n", bc->display);
- enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
- }
-
- return msg;
-}
-
-static void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing NOTIFY Msg\n");
-#endif
-}
-
-static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- NOTIFY_t *notify;
- msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt);
-
- notify=(NOTIFY_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building NOTIFY Msg\n");
-#endif
- return msg;
-}
-
-static void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing STATUS_ENQUIRY Msg\n");
-#endif
-}
-
-static msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- STATUS_ENQUIRY_t *status_enquiry;
- msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY, bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt);
-
- status_enquiry=(STATUS_ENQUIRY_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building STATUS_ENQUIRY Msg\n");
-#endif
- return msg;
-}
-
-static void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- INFORMATION_t *information=(INFORMATION_t*)((unsigned long)(msg->data+HEADER_LEN));
- {
- int type, plan;
- char number[32];
- char keypad[32];
- dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)information, &type, &plan, number, sizeof(number)-1, nt, bc);
- dec_ie_keypad(information->KEYPAD, (Q931_info_t *)information, keypad, sizeof(keypad)-1, nt, bc);
- strcpy(bc->info_dad, number);
- strcpy(bc->keypad,keypad);
- }
-#if DEBUG
- printf("Parsing INFORMATION Msg\n");
-#endif
-}
-
-static msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- INFORMATION_t *information;
- msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt);
-
- information=(INFORMATION_t*)((msg->data+HEADER_LEN));
-
- {
- enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
- }
-
- {
- if (*bc->display) {
- printf("Sending %s as Display\n", bc->display);
- enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
- }
- }
-
-#if DEBUG
- printf("Building INFORMATION Msg\n");
-#endif
- return msg;
-}
-
-static void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- STATUS_t *status=(STATUS_t*)((unsigned long)(msg->data+HEADER_LEN));
- int location;
- int cause;
-
- dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &cause, nt,bc);
- if (cause>0) bc->cause=cause;
- ;
-
-#if DEBUG
- printf("Parsing STATUS Msg\n");
-#endif
-}
-
-static msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- STATUS_t *status;
- msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS, bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
-
- status=(STATUS_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building STATUS Msg\n");
-#endif
- return msg;
-}
-
-static void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#if DEBUG
- printf("Parsing STATUS Msg\n");
-#endif
-}
-
-static msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
- int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
- STATUS_t *status;
- msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS, bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
-
- status=(STATUS_t*)((msg->data+HEADER_LEN));
-
-#if DEBUG
- printf("Building STATUS Msg\n");
-#endif
- return msg;
-}
-
-
-/************************************/
-
-
-
-
-/** Msg Array **/
-
-struct isdn_msg msgs_g[] = {
- {CC_PROCEEDING,L3,EVENT_PROCEEDING,
- parse_proceeding,build_proceeding,
- "PROCEEDING"},
- {CC_ALERTING,L3,EVENT_ALERTING,
- parse_alerting,build_alerting,
- "ALERTING"},
- {CC_PROGRESS,L3,EVENT_PROGRESS,
- parse_progress,build_progress,
- "PROGRESS"},
- {CC_SETUP,L3,EVENT_SETUP,
- parse_setup,build_setup,
- "SETUP"},
- {CC_CONNECT,L3,EVENT_CONNECT,
- parse_connect,build_connect,
- "CONNECT"},
- {CC_SETUP_ACKNOWLEDGE,L3,EVENT_SETUP_ACKNOWLEDGE,
- parse_setup_acknowledge,build_setup_acknowledge,
- "SETUP_ACKNOWLEDGE"},
- {CC_CONNECT_ACKNOWLEDGE ,L3,EVENT_CONNECT_ACKNOWLEDGE ,
- parse_connect_acknowledge ,build_connect_acknowledge,
- "CONNECT_ACKNOWLEDGE "},
- {CC_USER_INFORMATION,L3,EVENT_USER_INFORMATION,
- parse_user_information,build_user_information,
- "USER_INFORMATION"},
- {CC_SUSPEND_REJECT,L3,EVENT_SUSPEND_REJECT,
- parse_suspend_reject,build_suspend_reject,
- "SUSPEND_REJECT"},
- {CC_RESUME_REJECT,L3,EVENT_RESUME_REJECT,
- parse_resume_reject,build_resume_reject,
- "RESUME_REJECT"},
- {CC_HOLD,L3,EVENT_HOLD,
- parse_hold,build_hold,
- "HOLD"},
- {CC_SUSPEND,L3,EVENT_SUSPEND,
- parse_suspend,build_suspend,
- "SUSPEND"},
- {CC_RESUME,L3,EVENT_RESUME,
- parse_resume,build_resume,
- "RESUME"},
- {CC_HOLD_ACKNOWLEDGE,L3,EVENT_HOLD_ACKNOWLEDGE,
- parse_hold_acknowledge,build_hold_acknowledge,
- "HOLD_ACKNOWLEDGE"},
- {CC_SUSPEND_ACKNOWLEDGE,L3,EVENT_SUSPEND_ACKNOWLEDGE,
- parse_suspend_acknowledge,build_suspend_acknowledge,
- "SUSPEND_ACKNOWLEDGE"},
- {CC_RESUME_ACKNOWLEDGE,L3,EVENT_RESUME_ACKNOWLEDGE,
- parse_resume_acknowledge,build_resume_acknowledge,
- "RESUME_ACKNOWLEDGE"},
- {CC_HOLD_REJECT,L3,EVENT_HOLD_REJECT,
- parse_hold_reject,build_hold_reject,
- "HOLD_REJECT"},
- {CC_RETRIEVE,L3,EVENT_RETRIEVE,
- parse_retrieve,build_retrieve,
- "RETRIEVE"},
- {CC_RETRIEVE_ACKNOWLEDGE,L3,EVENT_RETRIEVE_ACKNOWLEDGE,
- parse_retrieve_acknowledge,build_retrieve_acknowledge,
- "RETRIEVE_ACKNOWLEDGE"},
- {CC_RETRIEVE_REJECT,L3,EVENT_RETRIEVE_REJECT,
- parse_retrieve_reject,build_retrieve_reject,
- "RETRIEVE_REJECT"},
- {CC_DISCONNECT,L3,EVENT_DISCONNECT,
- parse_disconnect,build_disconnect,
- "DISCONNECT"},
- {CC_RESTART,L3,EVENT_RESTART,
- parse_restart,build_restart,
- "RESTART"},
- {CC_RELEASE,L3,EVENT_RELEASE,
- parse_release,build_release,
- "RELEASE"},
- {CC_RELEASE_COMPLETE,L3,EVENT_RELEASE_COMPLETE,
- parse_release_complete,build_release_complete,
- "RELEASE_COMPLETE"},
- {CC_FACILITY,L3,EVENT_FACILITY,
- parse_facility,build_facility,
- "FACILITY"},
- {CC_NOTIFY,L3,EVENT_NOTIFY,
- parse_notify,build_notify,
- "NOTIFY"},
- {CC_STATUS_ENQUIRY,L3,EVENT_STATUS_ENQUIRY,
- parse_status_enquiry,build_status_enquiry,
- "STATUS_ENQUIRY"},
- {CC_INFORMATION,L3,EVENT_INFORMATION,
- parse_information,build_information,
- "INFORMATION"},
- {CC_STATUS,L3,EVENT_STATUS,
- parse_status,build_status,
- "STATUS"},
- {CC_TIMEOUT,L3,EVENT_TIMEOUT,
- parse_timeout,build_timeout,
- "TIMEOUT"},
- {0,0,0,NULL,NULL,NULL}
-};
-
-#define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
-
-/** INTERFACE FCTS ***/
-int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
-{
- int i;
-
- if (nt){
- mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
-
- for (i=0; i< msgs_max -1; i++) {
- if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
- }
-
- } else {
- iframe_t *frm = (iframe_t*)msg->data;
-
- for (i=0; i< msgs_max -1; i++)
- if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
- }
-
- return -1;
-}
-
-int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
-{
- int i;
- for (i=0; i< msgs_max; i++)
- if ( event == msgs[i].event) return i;
-
- cb_log(10,0, "get_index: event not found!\n");
-
- return -1;
-}
-
-enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
-{
- int i=isdn_msg_get_index(msgs, msg, nt);
- if(i>=0) return msgs[i].event;
- return EVENT_UNKNOWN;
-}
-
-char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt)
-{
- int i=isdn_msg_get_index(msgs, msg, nt);
- if(i>=0) return msgs[i].info;
- return NULL;
-}
-
-
-char EVENT_CLEAN_INFO[] = "CLEAN_UP";
-char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
-char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
-char EVENT_NEW_BC_INFO[] = "NEW_BC";
-char EVENT_PORT_ALARM_INFO[] = "ALARM";
-char EVENT_NEW_CHANNEL_INFO[] = "NEW_CHANNEL";
-char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
-char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
-char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
-char EVENT_BCHAN_ERROR_INFO[] = "BCHAN_ERROR";
-
-char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
-{
- int i=isdn_msg_get_index_by_event(msgs, event, nt);
-
- if(i>=0) return msgs[i].info;
-
- if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
- if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
- if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
- if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
- if (event == EVENT_NEW_CHANNEL) return EVENT_NEW_CHANNEL_INFO;
- if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
- if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
- if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
- if (event == EVENT_PORT_ALARM) return EVENT_PORT_ALARM_INFO;
- if (event == EVENT_BCHAN_ERROR) return EVENT_BCHAN_ERROR_INFO;
-
- return NULL;
-}
-
-int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
- int i=isdn_msg_get_index(msgs, msg, nt);
- if(i<0) return -1;
-
- msgs[i].msg_parser(msgs, msg, bc, nt);
- return 0;
-}
-
-msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
-{
- int i=isdn_msg_get_index_by_event(msgs, event, nt);
- if(i<0) return NULL;
-
- return msgs[i].msg_builder(msgs, bc, nt);
-}
diff --git a/1.4/channels/misdn/portinfo.c b/1.4/channels/misdn/portinfo.c
deleted file mode 100644
index bcb9f0313..000000000
--- a/1.4/channels/misdn/portinfo.c
+++ /dev/null
@@ -1,198 +0,0 @@
-
-
-#include "isdn_lib.h"
-#include "isdn_lib_intern.h"
-
-
-/*
- * global function to show all available isdn ports
- */
-void isdn_port_info(void)
-{
- int err;
- int i, ii, p;
- int useable, nt, pri;
- unsigned char buff[1025];
- iframe_t *frm = (iframe_t *)buff;
- stack_info_t *stinf;
- int device;
-
- /* open mISDN */
- if ((device = mISDN_open()) < 0)
- {
- fprintf(stderr, "mISDN_open() failed: ret=%d errno=%d (%s) Check for mISDN modules and device.\n", device, errno, strerror(errno));
- exit(-1);
- }
-
- /* get number of stacks */
- i = 1;
- ii = mISDN_get_stack_count(device);
- printf("\n");
- if (ii <= 0)
- {
- printf("Found no card. Please be sure to load card drivers.\n");
- }
-
- /* loop the number of cards and get their info */
- while(i <= ii)
- {
- err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
- if (err <= 0)
- {
- fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
- break;
- }
- stinf = (stack_info_t *)&frm->data.p;
-
- nt = pri = 0;
- useable = 1;
-
- /* output the port info */
- printf("Port %2d: ", i);
- switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
- {
- case ISDN_PID_L0_TE_S0:
- printf("TE-mode BRI S/T interface line (for phone lines)");
-#if 0
- if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
- printf(" HFC multiport card");
-#endif
- break;
- case ISDN_PID_L0_NT_S0:
- nt = 1;
- printf("NT-mode BRI S/T interface port (for phones)");
-#if 0
- if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
- printf(" HFC multiport card");
-#endif
- break;
- case ISDN_PID_L0_TE_U:
- printf("TE-mode BRI U interface line");
- break;
- case ISDN_PID_L0_NT_U:
- nt = 1;
- printf("NT-mode BRI U interface port");
- break;
- case ISDN_PID_L0_TE_UP2:
- printf("TE-mode BRI Up2 interface line");
- break;
- case ISDN_PID_L0_NT_UP2:
- nt = 1;
- printf("NT-mode BRI Up2 interface port");
- break;
- case ISDN_PID_L0_TE_E1:
- pri = 1;
- printf("TE-mode PRI E1 interface line (for phone lines)");
-#if 0
- if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
- printf(" HFC-E1 card");
-#endif
- break;
- case ISDN_PID_L0_NT_E1:
- nt = 1;
- pri = 1;
- printf("NT-mode PRI E1 interface port (for phones)");
-#if 0
- if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
- printf(" HFC-E1 card");
-#endif
- break;
- default:
- useable = 0;
- printf("unknown type 0x%08x",stinf->pid.protocol[0]);
- }
- printf("\n");
-
- if (nt)
- {
- if (stinf->pid.protocol[1] == 0)
- {
- useable = 0;
- printf(" -> Missing layer 1 NT-mode protocol.\n");
- }
- p = 2;
- while(p <= MAX_LAYER_NR) {
- if (stinf->pid.protocol[p])
- {
- useable = 0;
- printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
- }
- p++;
- }
- if (useable)
- {
- if (pri)
- printf(" -> Interface is Point-To-Point (PRI).\n");
- else
- printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
- }
- } else
- {
- if (stinf->pid.protocol[1] == 0)
- {
- useable = 0;
- printf(" -> Missing layer 1 protocol.\n");
- }
- if (stinf->pid.protocol[2] == 0)
- {
- useable = 0;
- printf(" -> Missing layer 2 protocol.\n");
- }
- if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
- {
- printf(" -> Interface is Poin-To-Point.\n");
- }
- if (stinf->pid.protocol[3] == 0)
- {
- useable = 0;
- printf(" -> Missing layer 3 protocol.\n");
- } else
- {
- printf(" -> Protocol: ");
- switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
- {
- case ISDN_PID_L3_DSS1USER:
- printf("DSS1 (Euro ISDN)");
- break;
-
- default:
- useable = 0;
- printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
- }
- printf("\n");
- }
- p = 4;
- while(p <= MAX_LAYER_NR) {
- if (stinf->pid.protocol[p])
- {
- useable = 0;
- printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
- }
- p++;
- }
- printf(" -> childcnt: %d\n",stinf->childcnt);
- }
-
- if (!useable)
- printf(" * Port NOT useable for PBX\n");
-
- printf("--------\n");
-
- i++;
- }
- printf("\n");
-
- /* close mISDN */
- if ((err = mISDN_close(device)))
- {
- fprintf(stderr, "mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
- exit(-1);
- }
-}
-
-
-int main()
-{
- isdn_port_info();
- return 0;
-}
diff --git a/1.4/channels/misdn_config.c b/1.4/channels/misdn_config.c
deleted file mode 100644
index cb1662251..000000000
--- a/1.4/channels/misdn_config.c
+++ /dev/null
@@ -1,1150 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Christian Richter
- *
- * Christian Richter <crich@beronet.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.
- *
- */
-
-/*!
- * \file
- *
- * \brief chan_misdn configuration management
- * \author Christian Richter <crich@beronet.com>
- *
- * \ingroup channel_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "chan_misdn_config.h"
-
-#include "asterisk/config.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/lock.h"
-#include "asterisk/pbx.h"
-#include "asterisk/strings.h"
-#include "asterisk/utils.h"
-
-#define AST_LOAD_CFG ast_config_load
-#define AST_DESTROY_CFG ast_config_destroy
-
-#define NO_DEFAULT "<>"
-#define NONE 0
-
-#define GEN_CFG 1
-#define PORT_CFG 2
-#define NUM_GEN_ELEMENTS (sizeof(gen_spec) / sizeof(struct misdn_cfg_spec))
-#define NUM_PORT_ELEMENTS (sizeof(port_spec) / sizeof(struct misdn_cfg_spec))
-
-enum misdn_cfg_type {
- MISDN_CTYPE_STR,
- MISDN_CTYPE_INT,
- MISDN_CTYPE_BOOL,
- MISDN_CTYPE_BOOLINT,
- MISDN_CTYPE_MSNLIST,
- MISDN_CTYPE_ASTGROUP
-};
-
-struct msn_list {
- char *msn;
- struct msn_list *next;
-};
-
-union misdn_cfg_pt {
- char *str;
- int *num;
- struct msn_list *ml;
- ast_group_t *grp;
- void *any;
-};
-
-struct misdn_cfg_spec {
- char name[BUFFERSIZE];
- enum misdn_cfg_elements elem;
- enum misdn_cfg_type type;
- char def[BUFFERSIZE];
- int boolint_def;
- char desc[BUFFERSIZE];
-};
-
-
-static const char ports_description[] =
- "Define your ports, e.g. 1,2 (depends on mISDN-driver loading order).";
-
-static const struct misdn_cfg_spec port_spec[] = {
- { "name", MISDN_CFG_GROUPNAME, MISDN_CTYPE_STR, "default", NONE,
- "Name of the portgroup." },
- { "allowed_bearers", MISDN_CFG_ALLOWED_BEARERS, MISDN_CTYPE_STR, "all", NONE,
- "Here you can define which bearers should be allowed." },
- { "rxgain", MISDN_CFG_RXGAIN, MISDN_CTYPE_INT, "0", NONE,
- "Set this between -8 and 8 to change the RX Gain." },
- { "txgain", MISDN_CFG_TXGAIN, MISDN_CTYPE_INT, "0", NONE,
- "Set this between -8 and 8 to change the TX Gain." },
- { "te_choose_channel", MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CTYPE_BOOL, "no", NONE,
- "Some telcos espacially in NL seem to need this set to yes,\n"
- "\talso in switzerland this seems to be important." },
- { "far_alerting", MISDN_CFG_FAR_ALERTING, MISDN_CTYPE_BOOL, "no", NONE,
- "If we should generate ringing for chan_sip and others." },
- { "pmp_l1_check", MISDN_CFG_PMP_L1_CHECK, MISDN_CTYPE_BOOL, "no", NONE,
- "This option defines, if chan_misdn should check the L1 on a PMP\n"
- "\tbefore makeing a group call on it. The L1 may go down for PMP Ports\n"
- "\tso we might need this.\n"
- "\tBut be aware! a broken or plugged off cable might be used for a group call\n"
- "\tas well, since chan_misdn has no chance to distinguish if the L1 is down\n"
- "\tbecause of a lost Link or because the Provider shut it down..." },
- { "block_on_alarm", MISDN_CFG_ALARM_BLOCK, MISDN_CTYPE_BOOL, "no", NONE ,
- "Block this port if we have an alarm on it."
- "default: yes\n" },
- { "hdlc", MISDN_CFG_HDLC, MISDN_CTYPE_BOOL, "no", NONE,
- "Set this to yes, if you want to bridge a mISDN data channel to\n"
- "\tanother channel type or to an application." },
- { "context", MISDN_CFG_CONTEXT, MISDN_CTYPE_STR, "default", NONE,
- "Context to use for incoming calls." },
- { "language", MISDN_CFG_LANGUAGE, MISDN_CTYPE_STR, "en", NONE,
- "Language." },
- { "musicclass", MISDN_CFG_MUSICCLASS, MISDN_CTYPE_STR, "default", NONE,
- "Sets the musiconhold class." },
- { "callerid", MISDN_CFG_CALLERID, MISDN_CTYPE_STR, "", NONE,
- "Sets the caller ID." },
- { "method", MISDN_CFG_METHOD, MISDN_CTYPE_STR, "standard", NONE,
- "Sets the method to use for channel selection:\n"
- "\t standard - always choose the first free channel with the lowest number\n"
- "\t round_robin - use the round robin algorithm to select a channel. use this\n"
- "\t if you want to balance your load." },
- { "dialplan", MISDN_CFG_DIALPLAN, MISDN_CTYPE_INT, "0", NONE,
- "Dialplan means Type Of Number in ISDN Terms (for outgoing calls)\n"
- "\n"
- "\tThere are different types of the dialplan:\n"
- "\n"
- "\tdialplan -> outgoing Number\n"
- "\tlocaldialplan -> callerid\n"
- "\tcpndialplan -> connected party number\n"
- "\n"
- "\tdialplan options:\n"
- "\n"
- "\t0 - unknown\n"
- "\t1 - International\n"
- "\t2 - National\n"
- "\t4 - Subscriber\n"
- "\n"
- "\tThis setting is used for outgoing calls." },
- { "localdialplan", MISDN_CFG_LOCALDIALPLAN, MISDN_CTYPE_INT, "0", NONE,
- "Dialplan means Type Of Number in ISDN Terms (for outgoing calls)\n"
- "\n"
- "\tThere are different types of the dialplan:\n"
- "\n"
- "\tdialplan -> outgoing Number\n"
- "\tlocaldialplan -> callerid\n"
- "\tcpndialplan -> connected party number\n"
- "\n"
- "\tdialplan options:\n"
- "\n"
- "\t0 - unknown\n"
- "\t1 - International\n"
- "\t2 - National\n"
- "\t4 - Subscriber\n"
- "\n"
- "\tThis setting is used for outgoing calls" },
- { "cpndialplan", MISDN_CFG_CPNDIALPLAN, MISDN_CTYPE_INT, "0", NONE,
- "Dialplan means Type Of Number in ISDN Terms (for outgoing calls)\n"
- "\n"
- "\tThere are different types of the dialplan:\n"
- "\n"
- "\tdialplan -> outgoing Number\n"
- "\tlocaldialplan -> callerid\n"
- "\tcpndialplan -> connected party number\n"
- "\n"
- "\tdialplan options:\n"
- "\n"
- "\t0 - unknown\n"
- "\t1 - International\n"
- "\t2 - National\n"
- "\t4 - Subscriber\n"
- "\n"
- "\tThis setting is used for outgoing calls." },
- { "nationalprefix", MISDN_CFG_NATPREFIX, MISDN_CTYPE_STR, "0", NONE,
- "Prefix for national, this is put before the\n"
- "\toad if an according dialplan is set by the other end." },
- { "internationalprefix", MISDN_CFG_INTERNATPREFIX, MISDN_CTYPE_STR, "00", NONE,
- "Prefix for international, this is put before the\n"
- "\toad if an according dialplan is set by the other end." },
- { "presentation", MISDN_CFG_PRES, MISDN_CTYPE_INT, "-1", NONE,
- "These (presentation and screen) are the exact isdn screening and presentation\n"
- "\tindicators.\n"
- "\tIf -1 is given for both values, the presentation indicators are used from\n"
- "\tAsterisks SetCallerPres application.\n"
- "\n"
- "\tscreen=0, presentation=0 -> callerid presented not screened\n"
- "\tscreen=1, presentation=1 -> callerid presented but screened (the remote end doesn't see it!)" },
- { "screen", MISDN_CFG_SCREEN, MISDN_CTYPE_INT, "-1", NONE,
- "These (presentation and screen) are the exact isdn screening and presentation\n"
- "\tindicators.\n"
- "\tIf -1 is given for both values, the presentation indicators are used from\n"
- "\tAsterisks SetCallerPres application.\n"
- "\n"
- "\tscreen=0, presentation=0 -> callerid presented not screened\n"
- "\tscreen=1, presentation=1 -> callerid presented but screened (the remote end doesn't see it!)" },
- { "always_immediate", MISDN_CFG_ALWAYS_IMMEDIATE, MISDN_CTYPE_BOOL, "no", NONE,
- "Enable this to get into the s dialplan-extension.\n"
- "\tThere you can use DigitTimeout if you can't or don't want to use\n"
- "\tisdn overlap dial.\n"
- "\tNOTE: This will jump into the s extension for every exten!" },
- { "nodialtone", MISDN_CFG_NODIALTONE, MISDN_CTYPE_BOOL, "no", NONE,
- "Enable this to prevent chan_misdn to generate the dialtone\n"
- "\tThis makes only sense together with the always_immediate=yes option\n"
- "\tto generate your own dialtone with Playtones or so."},
- { "immediate", MISDN_CFG_IMMEDIATE, MISDN_CTYPE_BOOL, "no", NONE,
- "Enable this if you want callers which called exactly the base\n"
- "\tnumber (so no extension is set) to jump into the s extension.\n"
- "\tIf the user dials something more, it jumps to the correct extension\n"
- "\tinstead." },
- { "senddtmf", MISDN_CFG_SENDDTMF, MISDN_CTYPE_BOOL, "no", NONE,
- "Enable this if we should produce DTMF Tones ourselves." },
- { "astdtmf", MISDN_CFG_ASTDTMF, MISDN_CTYPE_BOOL, "no", NONE,
- "Enable this if you want to use the Asterisk dtmf detector\n"
- "instead of the mISDN_dsp/hfcmulti one."
- },
- { "hold_allowed", MISDN_CFG_HOLD_ALLOWED, MISDN_CTYPE_BOOL, "no", NONE,
- "Enable this to have support for hold and retrieve." },
- { "early_bconnect", MISDN_CFG_EARLY_BCONNECT, MISDN_CTYPE_BOOL, "yes", NONE,
- "Disable this if you don't mind correct handling of Progress Indicators." },
- { "incoming_early_audio", MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CTYPE_BOOL, "no", NONE,
- "Turn this on if you like to send Tone Indications to a Incoming\n"
- "\tisdn channel on a TE Port. Rarely used, only if the Telco allows\n"
- "\tyou to send indications by yourself, normally the Telco sends the\n"
- "\tindications to the remote party." },
- { "echocancel", MISDN_CFG_ECHOCANCEL, MISDN_CTYPE_BOOLINT, "0", 128,
- "This enables echocancellation, with the given number of taps.\n"
- "\tBe aware, move this setting only to outgoing portgroups!\n"
- "\tA value of zero turns echocancellation off.\n"
- "\n"
- "\tPossible values are: 0,32,64,128,256,yes(=128),no(=0)" },
-#ifdef MISDN_1_2
- { "pipeline", MISDN_CFG_PIPELINE, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
- "Set the configuration string for the mISDN dsp pipeline.\n"
- "\n"
- "\tExample for enabling the mg2 echo cancellation module with deftaps\n"
- "\tset to 128:\n"
- "\t\tmg2ec(deftaps=128)" },
-#endif
-#ifdef WITH_BEROEC
- { "bnechocancel", MISDN_CFG_BNECHOCANCEL, MISDN_CTYPE_BOOLINT, "yes", 64,
- "echotail in ms (1-200)\n"},
- { "bnec_antihowl", MISDN_CFG_BNEC_ANTIHOWL, MISDN_CTYPE_INT, "0", NONE,
- "Use antihowl\n"},
- { "bnec_nlp", MISDN_CFG_BNEC_NLP, MISDN_CTYPE_BOOL, "yes", NONE,
- "Nonlinear Processing (much faster adaption)"},
- { "bnec_zerocoeff", MISDN_CFG_BNEC_ZEROCOEFF, MISDN_CTYPE_BOOL, "no", NONE,
- "ZeroCoeffeciens\n"},
- { "bnec_tonedisabler", MISDN_CFG_BNEC_TD, MISDN_CTYPE_BOOL, "no", NONE,
- "Disable Tone\n"},
- { "bnec_adaption", MISDN_CFG_BNEC_ADAPT, MISDN_CTYPE_INT, "1", NONE,
- "Adaption mode (0=no,1=full,2=fast)\n"},
-#endif
- { "need_more_infos", MISDN_CFG_NEED_MORE_INFOS, MISDN_CTYPE_BOOL, "0", NONE,
- "Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING),\n"
- "\tthis requests additional Infos, so we can waitfordigits without much\n"
- "\tissues. This works only for PTP Ports" },
- { "noautorespond_on_setup", MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CTYPE_BOOL, "0", NONE,
- "Do not send SETUP_ACKNOWLEDGE or PROCEEDING automatically to the calling Party.\n"
- "Instead we directly jump into the dialplan. This might be useful for fast call\n"
- "rejection, or for some broken switches, that need hangup causes like busy in the.\n"
- "RELEASE_COMPLETE Message, instead of the DISCONNECT Message.\n"},
- { "jitterbuffer", MISDN_CFG_JITTERBUFFER, MISDN_CTYPE_INT, "4000", NONE,
- "The jitterbuffer." },
- { "jitterbuffer_upper_threshold", MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CTYPE_INT, "0", NONE,
- "Change this threshold to enable dejitter functionality." },
- { "callgroup", MISDN_CFG_CALLGROUP, MISDN_CTYPE_ASTGROUP, NO_DEFAULT, NONE,
- "Callgroup." },
- { "pickupgroup", MISDN_CFG_PICKUPGROUP, MISDN_CTYPE_ASTGROUP, NO_DEFAULT, NONE,
- "Pickupgroup." },
- { "max_incoming", MISDN_CFG_MAX_IN, MISDN_CTYPE_INT, "-1", NONE,
- "Defines the maximum amount of incoming calls per port for this group.\n"
- "\tCalls which exceed the maximum will be marked with the channel varible\n"
- "\tMAX_OVERFLOW. It will contain the amount of overflowed calls" },
- { "max_outgoing", MISDN_CFG_MAX_OUT, MISDN_CTYPE_INT, "-1", NONE,
- "Defines the maximum amount of outgoing calls per port for this group\n"
- "\texceeding calls will be rejected" },
-
- { "reject_cause", MISDN_CFG_REJECT_CAUSE, MISDN_CTYPE_INT, "21", NONE,
- "Defines the cause with which a 3. call is rejected on PTMP BRI."},
- { "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE,
- "Setup fax detection:\n"
- "\t no - no fax detection\n"
- "\t incoming - fax detection for incoming calls\n"
- "\t outgoing - fax detection for outgoing calls\n"
- "\t both - fax detection for incoming and outgoing calls\n"
- "\tAdd +nojump to your value (i.e. faxdetect=both+nojump) if you don't want to jump into the\n"
- "\tfax-extension but still want to detect the fax and prepare the channel for fax transfer." },
- { "faxdetect_timeout", MISDN_CFG_FAXDETECT_TIMEOUT, MISDN_CTYPE_INT, "5", NONE,
- "Number of seconds the fax detection should do its job. After the given period of time,\n"
- "\twe assume that it's not a fax call and save some CPU time by turning off fax detection.\n"
- "\tSet this to 0 if you don't want a timeout (never stop detecting)." },
- { "faxdetect_context", MISDN_CFG_FAXDETECT_CONTEXT, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
- "Context to jump into if we detect a fax. Don't set this if you want to stay in the current context." },
- { "l1watcher_timeout", MISDN_CFG_L1_TIMEOUT, MISDN_CTYPE_BOOLINT, "0", 4,
- "Watches the layer 1. If the layer 1 is down, it tries to\n"
- "\tget it up. The timeout is given in seconds. with 0 as value it\n"
- "\tdoes not watch the l1 at all\n"
- "\n"
- "\tThis option is only read at loading time of chan_misdn, which\n"
- "\tmeans you need to unload and load chan_misdn to change the value,\n"
- "\tan Asterisk restart should do the trick." },
- { "overlapdial", MISDN_CFG_OVERLAP_DIAL, MISDN_CTYPE_BOOLINT, "0", 4,
- "Enables overlap dial for the given amount of seconds.\n"
- "\tPossible values are positive integers or:\n"
- "\t yes (= 4 seconds)\n"
- "\t no (= 0 seconds = disabled)" },
- { "nttimeout", MISDN_CFG_NTTIMEOUT, MISDN_CTYPE_BOOL, "no", NONE ,
- "Set this to yes if you want calls disconnected in overlap mode"
- "when a timeout happens.\n"},
- { "bridging", MISDN_CFG_BRIDGING, MISDN_CTYPE_BOOL, "yes", NONE,
- "Set this to yes/no, default is yes.\n"
- "This can be used to have bridging enabled in general and to\n"
- "disable it for specific ports. It makes sense to disable\n"
- "bridging on NT Port where you plan to use the HOLD/RETRIEVE\n"
- "features with ISDN phones.\n"
- },
- { "msns", MISDN_CFG_MSNS, MISDN_CTYPE_MSNLIST, "*", NONE,
- "MSN's for TE ports, listen on those numbers on the above ports, and\n"
- "\tindicate the incoming calls to Asterisk.\n"
- "\tHere you can give a comma seperated list, or simply an '*' for any msn." },
-};
-
-static const struct misdn_cfg_spec gen_spec[] = {
- { "debug", MISDN_GEN_DEBUG, MISDN_CTYPE_INT, "0", NONE,
- "Sets the debugging flag:\n"
- "\t0 - No Debug\n"
- "\t1 - mISDN Messages and * - Messages, and * - State changes\n"
- "\t2 - Messages + Message specific Informations (e.g. bearer capability)\n"
- "\t3 - very Verbose, the above + lots of Driver specific infos\n"
- "\t4 - even more Verbose than 3" },
-#ifndef MISDN_1_2
- { "misdn_init", MISDN_GEN_MISDN_INIT, MISDN_CTYPE_STR, "/etc/misdn-init.conf", NONE,
- "Set the path to the misdn-init.conf (for nt_ptp mode checking)." },
-#endif
- { "tracefile", MISDN_GEN_TRACEFILE, MISDN_CTYPE_STR, "/var/log/asterisk/misdn.log", NONE,
- "Set the path to the massively growing trace file, if you want that." },
- { "bridging", MISDN_GEN_BRIDGING, MISDN_CTYPE_BOOL, "yes", NONE,
- "Set this to yes if you want mISDN_dsp to bridge the calls in HW." },
- { "stop_tone_after_first_digit", MISDN_GEN_STOP_TONE, MISDN_CTYPE_BOOL, "yes", NONE,
- "Stops dialtone after getting first digit on NT Port." },
- { "append_digits2exten", MISDN_GEN_APPEND_DIGITS2EXTEN, MISDN_CTYPE_BOOL, "yes", NONE,
- "Wether to append overlapdialed Digits to Extension or not." },
- { "dynamic_crypt", MISDN_GEN_DYNAMIC_CRYPT, MISDN_CTYPE_BOOL, "no", NONE,
- "Wether to look out for dynamic crypting attempts." },
- { "crypt_prefix", MISDN_GEN_CRYPT_PREFIX, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
- "What is used for crypting Protocol." },
- { "crypt_keys", MISDN_GEN_CRYPT_KEYS, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
- "Keys for cryption, you reference them in the dialplan\n"
- "\tLater also in dynamic encr." },
- { "ntkeepcalls", MISDN_GEN_NTKEEPCALLS, MISDN_CTYPE_BOOL, "no", NONE,
- "avoid dropping calls if the L2 goes down. some nortel pbx\n"
- "do put down the L2/L1 for some milliseconds even if there\n"
- "are running calls. with this option you can avoid dropping them\n" },
- { "ntdebugflags", MISDN_GEN_NTDEBUGFLAGS, MISDN_CTYPE_INT, "0", NONE,
- "No description yet."},
- { "ntdebugfile", MISDN_GEN_NTDEBUGFILE, MISDN_CTYPE_STR, "/var/log/misdn-nt.log", NONE,
- "No description yet." }
-};
-
-
-/* array of port configs, default is at position 0. */
-static union misdn_cfg_pt **port_cfg;
-/* max number of available ports, is set on init */
-static int max_ports;
-/* general config */
-static union misdn_cfg_pt *general_cfg;
-/* storing the ptp flag separated to save memory */
-static int *ptp;
-/* maps enum config elements to array positions */
-static int *map;
-
-static ast_mutex_t config_mutex;
-
-#define CLI_ERROR(name, value, section) ({ \
- ast_log(LOG_WARNING, "misdn.conf: \"%s=%s\" (section: %s) invalid or out of range. " \
- "Please edit your misdn.conf and then do a \"misdn reload\".\n", name, value, section); \
-})
-
-static int _enum_array_map (void)
-{
- int i, j, ok;
-
- for (i = MISDN_CFG_FIRST + 1; i < MISDN_CFG_LAST; ++i) {
- if (i == MISDN_CFG_PTP)
- continue;
- ok = 0;
- for (j = 0; j < NUM_PORT_ELEMENTS; ++j) {
- if (port_spec[j].elem == i) {
- map[i] = j;
- ok = 1;
- break;
- }
- }
- if (!ok) {
- ast_log(LOG_WARNING, "Enum element %d in misdn_cfg_elements (port section) has no corresponding element in the config struct!\n", i);
- return -1;
- }
- }
- for (i = MISDN_GEN_FIRST + 1; i < MISDN_GEN_LAST; ++i) {
- ok = 0;
- for (j = 0; j < NUM_GEN_ELEMENTS; ++j) {
- if (gen_spec[j].elem == i) {
- map[i] = j;
- ok = 1;
- break;
- }
- }
- if (!ok) {
- ast_log(LOG_WARNING, "Enum element %d in misdn_cfg_elements (general section) has no corresponding element in the config struct!\n", i);
- return -1;
- }
- }
- return 0;
-}
-
-static int get_cfg_position (char *name, int type)
-{
- int i;
-
- switch (type) {
- case PORT_CFG:
- for (i = 0; i < NUM_PORT_ELEMENTS; ++i) {
- if (!strcasecmp(name, port_spec[i].name))
- return i;
- }
- break;
- case GEN_CFG:
- for (i = 0; i < NUM_GEN_ELEMENTS; ++i) {
- if (!strcasecmp(name, gen_spec[i].name))
- return i;
- }
- }
-
- return -1;
-}
-
-static inline void misdn_cfg_lock (void)
-{
- ast_mutex_lock(&config_mutex);
-}
-
-static inline void misdn_cfg_unlock (void)
-{
- ast_mutex_unlock(&config_mutex);
-}
-
-static void _free_msn_list (struct msn_list* iter)
-{
- if (iter->next)
- _free_msn_list(iter->next);
- if (iter->msn)
- free(iter->msn);
- free(iter);
-}
-
-static void _free_port_cfg (void)
-{
- int i, j;
- int gn = map[MISDN_CFG_GROUPNAME];
- union misdn_cfg_pt* free_list[max_ports + 2];
-
- memset(free_list, 0, sizeof(free_list));
- free_list[0] = port_cfg[0];
- for (i = 1; i <= max_ports; ++i) {
- if (port_cfg[i][gn].str) {
- /* we always have a groupname in the non-default case, so this is fine */
- for (j = 1; j <= max_ports; ++j) {
- if (free_list[j] && free_list[j][gn].str == port_cfg[i][gn].str)
- break;
- else if (!free_list[j]) {
- free_list[j] = port_cfg[i];
- break;
- }
- }
- }
- }
- for (j = 0; free_list[j]; ++j) {
- for (i = 0; i < NUM_PORT_ELEMENTS; ++i) {
- if (free_list[j][i].any) {
- if (port_spec[i].type == MISDN_CTYPE_MSNLIST)
- _free_msn_list(free_list[j][i].ml);
- else
- free(free_list[j][i].any);
- }
- }
- }
-}
-
-static void _free_general_cfg (void)
-{
- int i;
-
- for (i = 0; i < NUM_GEN_ELEMENTS; i++)
- if (general_cfg[i].any)
- free(general_cfg[i].any);
-}
-
-void misdn_cfg_get (int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
-{
- int place;
-
- if ((elem < MISDN_CFG_LAST) && !misdn_cfg_is_port_valid(port)) {
- memset(buf, 0, bufsize);
- ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get! Port number %d is not valid.\n", port);
- return;
- }
-
- misdn_cfg_lock();
- if (elem == MISDN_CFG_PTP) {
- if (!memcpy(buf, &ptp[port], (bufsize > ptp[port]) ? sizeof(ptp[port]) : bufsize))
- memset(buf, 0, bufsize);
- } else {
- if ((place = map[elem]) < 0) {
- memset (buf, 0, bufsize);
- ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get! Invalid element (%d) requested.\n", elem);
- } else {
- if (elem < MISDN_CFG_LAST) {
- switch (port_spec[place].type) {
- case MISDN_CTYPE_STR:
- if (port_cfg[port][place].str) {
- if (!memccpy(buf, port_cfg[port][place].str, 0, bufsize))
- memset(buf, 0, 1);
- } else if (port_cfg[0][place].str) {
- if (!memccpy(buf, port_cfg[0][place].str, 0, bufsize))
- memset(buf, 0, 1);
- } else
- memset(buf, 0, bufsize);
- break;
- default:
- if (port_cfg[port][place].any)
- memcpy(buf, port_cfg[port][place].any, bufsize);
- else if (port_cfg[0][place].any)
- memcpy(buf, port_cfg[0][place].any, bufsize);
- else
- memset(buf, 0, bufsize);
- }
- } else {
- switch (gen_spec[place].type) {
- case MISDN_CTYPE_STR:
- if (!general_cfg[place].str || !memccpy(buf, general_cfg[place].str, 0, bufsize))
- memset(buf, 0, 1);
- break;
- default:
- if (general_cfg[place].any)
- memcpy(buf, general_cfg[place].any, bufsize);
- else
- memset(buf, 0, bufsize);
- }
- }
- }
- }
- misdn_cfg_unlock();
-}
-
-enum misdn_cfg_elements misdn_cfg_get_elem (char *name)
-{
- int pos;
-
- /* here comes a hack to replace the (not existing) "name" elemet with the "ports" element */
- if (!strcmp(name, "ports"))
- return MISDN_CFG_GROUPNAME;
- if (!strcmp(name, "name"))
- return MISDN_CFG_FIRST;
-
- pos = get_cfg_position (name, PORT_CFG);
- if (pos >= 0)
- return port_spec[pos].elem;
-
- pos = get_cfg_position (name, GEN_CFG);
- if (pos >= 0)
- return gen_spec[pos].elem;
-
- return MISDN_CFG_FIRST;
-}
-
-void misdn_cfg_get_name (enum misdn_cfg_elements elem, void *buf, int bufsize)
-{
- struct misdn_cfg_spec *spec = NULL;
- int place = map[elem];
-
- /* the ptp hack */
- if (elem == MISDN_CFG_PTP) {
- memset(buf, 0, 1);
- return;
- }
-
- /* here comes a hack to replace the (not existing) "name" elemet with the "ports" element */
- if (elem == MISDN_CFG_GROUPNAME) {
- if (!snprintf(buf, bufsize, "ports"))
- memset(buf, 0, 1);
- return;
- }
-
- if ((elem > MISDN_CFG_FIRST) && (elem < MISDN_CFG_LAST))
- spec = (struct misdn_cfg_spec *)port_spec;
- else if ((elem > MISDN_GEN_FIRST) && (elem < MISDN_GEN_LAST))
- spec = (struct misdn_cfg_spec *)gen_spec;
-
- if (!spec || !memccpy(buf, spec[place].name, 0, bufsize))
- memset(buf, 0, 1);
-}
-
-void misdn_cfg_get_desc (enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default)
-{
- int place = map[elem];
- struct misdn_cfg_spec *spec = NULL;
-
- /* here comes a hack to replace the (not existing) "name" elemet with the "ports" element */
- if (elem == MISDN_CFG_GROUPNAME) {
- if (!memccpy(buf, ports_description, 0, bufsize))
- memset(buf, 0, 1);
- if (buf_default && bufsize_default)
- memset(buf_default, 0, 1);
- return;
- }
-
- if ((elem > MISDN_CFG_FIRST) && (elem < MISDN_CFG_LAST))
- spec = (struct misdn_cfg_spec *)port_spec;
- else if ((elem > MISDN_GEN_FIRST) && (elem < MISDN_GEN_LAST))
- spec = (struct misdn_cfg_spec *)gen_spec;
-
- if (!spec || !spec[place].desc)
- memset(buf, 0, 1);
- else {
- if (!memccpy(buf, spec[place].desc, 0, bufsize))
- memset(buf, 0, 1);
- if (buf_default && bufsize) {
- if (!strcmp(spec[place].def, NO_DEFAULT))
- memset(buf_default, 0, 1);
- else if (!memccpy(buf_default, spec[place].def, 0, bufsize_default))
- memset(buf_default, 0, 1);
- }
- }
-}
-
-int misdn_cfg_is_msn_valid (int port, char* msn)
-{
- int re = 0;
- struct msn_list *iter;
-
- if (!misdn_cfg_is_port_valid(port)) {
- ast_log(LOG_WARNING, "Invalid call to misdn_cfg_is_msn_valid! Port number %d is not valid.\n", port);
- return 0;
- }
-
- misdn_cfg_lock();
- if (port_cfg[port][map[MISDN_CFG_MSNS]].ml)
- iter = port_cfg[port][map[MISDN_CFG_MSNS]].ml;
- else
- iter = port_cfg[0][map[MISDN_CFG_MSNS]].ml;
- for (; iter; iter = iter->next)
- if (*(iter->msn) == '*' || ast_extension_match(iter->msn, msn)) {
- re = 1;
- break;
- }
- misdn_cfg_unlock();
-
- return re;
-}
-
-int misdn_cfg_is_port_valid (int port)
-{
- int gn = map[MISDN_CFG_GROUPNAME];
-
- return (port >= 1 && port <= max_ports && port_cfg[port][gn].str);
-}
-
-int misdn_cfg_is_group_method (char *group, enum misdn_cfg_method meth)
-{
- int i, re = 0;
- char *method ;
-
- misdn_cfg_lock();
-
- method = port_cfg[0][map[MISDN_CFG_METHOD]].str;
-
- for (i = 1; i <= max_ports; i++) {
- if (port_cfg[i] && port_cfg[i][map[MISDN_CFG_GROUPNAME]].str) {
- if (!strcasecmp(port_cfg[i][map[MISDN_CFG_GROUPNAME]].str, group))
- method = (port_cfg[i][map[MISDN_CFG_METHOD]].str ?
- port_cfg[i][map[MISDN_CFG_METHOD]].str : port_cfg[0][map[MISDN_CFG_METHOD]].str);
- }
- }
-
- if (method) {
- switch (meth) {
- case METHOD_STANDARD: re = !strcasecmp(method, "standard");
- break;
- case METHOD_ROUND_ROBIN: re = !strcasecmp(method, "round_robin");
- break;
- case METHOD_STANDARD_DEC: re = !strcasecmp(method, "standard_dec");
- break;
- }
- }
- misdn_cfg_unlock();
-
- return re;
-}
-
-void misdn_cfg_get_ports_string (char *ports)
-{
- char tmp[16];
- int l, i;
- int gn = map[MISDN_CFG_GROUPNAME];
-
- *ports = 0;
-
- misdn_cfg_lock();
- for (i = 1; i <= max_ports; i++) {
- if (port_cfg[i][gn].str) {
- if (ptp[i])
- sprintf(tmp, "%dptp,", i);
- else
- sprintf(tmp, "%d,", i);
- strcat(ports, tmp);
- }
- }
- misdn_cfg_unlock();
-
- if ((l = strlen(ports)))
- ports[l-1] = 0;
-}
-
-void misdn_cfg_get_config_string (int port, enum misdn_cfg_elements elem, char* buf, int bufsize)
-{
- int place;
- char tempbuf[BUFFERSIZE] = "";
- struct msn_list *iter;
-
- if ((elem < MISDN_CFG_LAST) && !misdn_cfg_is_port_valid(port)) {
- *buf = 0;
- ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get_config_string! Port number %d is not valid.\n", port);
- return;
- }
-
- place = map[elem];
-
- misdn_cfg_lock();
- if (elem == MISDN_CFG_PTP) {
- snprintf(buf, bufsize, " -> ptp: %s", ptp[port] ? "yes" : "no");
- }
- else if (elem > MISDN_CFG_FIRST && elem < MISDN_CFG_LAST) {
- switch (port_spec[place].type) {
- case MISDN_CTYPE_INT:
- case MISDN_CTYPE_BOOLINT:
- if (port_cfg[port][place].num)
- snprintf(buf, bufsize, " -> %s: %d", port_spec[place].name, *port_cfg[port][place].num);
- else if (port_cfg[0][place].num)
- snprintf(buf, bufsize, " -> %s: %d", port_spec[place].name, *port_cfg[0][place].num);
- else
- snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
- break;
- case MISDN_CTYPE_BOOL:
- if (port_cfg[port][place].num)
- snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, *port_cfg[port][place].num ? "yes" : "no");
- else if (port_cfg[0][place].num)
- snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, *port_cfg[0][place].num ? "yes" : "no");
- else
- snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
- break;
- case MISDN_CTYPE_ASTGROUP:
- if (port_cfg[port][place].grp)
- snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name,
- ast_print_group(tempbuf, sizeof(tempbuf), *port_cfg[port][place].grp));
- else if (port_cfg[0][place].grp)
- snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name,
- ast_print_group(tempbuf, sizeof(tempbuf), *port_cfg[0][place].grp));
- else
- snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
- break;
- case MISDN_CTYPE_MSNLIST:
- if (port_cfg[port][place].ml)
- iter = port_cfg[port][place].ml;
- else
- iter = port_cfg[0][place].ml;
- if (iter) {
- for (; iter; iter = iter->next)
- sprintf(tempbuf, "%s%s, ", tempbuf, iter->msn);
- tempbuf[strlen(tempbuf)-2] = 0;
- }
- snprintf(buf, bufsize, " -> msns: %s", *tempbuf ? tempbuf : "none");
- break;
- case MISDN_CTYPE_STR:
- if ( port_cfg[port][place].str) {
- snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, port_cfg[port][place].str);
- } else if (port_cfg[0][place].str) {
- snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, port_cfg[0][place].str);
- } else {
- snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
- }
- break;
- }
- } else if (elem > MISDN_GEN_FIRST && elem < MISDN_GEN_LAST) {
- switch (gen_spec[place].type) {
- case MISDN_CTYPE_INT:
- case MISDN_CTYPE_BOOLINT:
- if (general_cfg[place].num)
- snprintf(buf, bufsize, " -> %s: %d", gen_spec[place].name, *general_cfg[place].num);
- else
- snprintf(buf, bufsize, " -> %s:", gen_spec[place].name);
- break;
- case MISDN_CTYPE_BOOL:
- if (general_cfg[place].num)
- snprintf(buf, bufsize, " -> %s: %s", gen_spec[place].name, *general_cfg[place].num ? "yes" : "no");
- else
- snprintf(buf, bufsize, " -> %s:", gen_spec[place].name);
- break;
- case MISDN_CTYPE_STR:
- if ( general_cfg[place].str) {
- snprintf(buf, bufsize, " -> %s: %s", gen_spec[place].name, general_cfg[place].str);
- } else {
- snprintf(buf, bufsize, " -> %s:", gen_spec[place].name);
- }
- break;
- default:
- snprintf(buf, bufsize, " -> type of %s not handled yet", gen_spec[place].name);
- break;
- }
- } else {
- *buf = 0;
- ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get_config_string! Invalid config element (%d) requested.\n", elem);
- }
- misdn_cfg_unlock();
-}
-
-int misdn_cfg_get_next_port (int port)
-{
- int p = -1;
- int gn = map[MISDN_CFG_GROUPNAME];
-
- misdn_cfg_lock();
- for (port++; port <= max_ports; port++) {
- if (port_cfg[port][gn].str) {
- p = port;
- break;
- }
- }
- misdn_cfg_unlock();
-
- return p;
-}
-
-int misdn_cfg_get_next_port_spin (int port)
-{
- int p = misdn_cfg_get_next_port(port);
- return (p > 0) ? p : misdn_cfg_get_next_port(0);
-}
-
-static int _parse (union misdn_cfg_pt *dest, char *value, enum misdn_cfg_type type, int boolint_def)
-{
- int re = 0;
- int len, tmp;
- char *valtmp;
-
- switch (type) {
- case MISDN_CTYPE_STR:
- if ((len = strlen(value))) {
- dest->str = (char *)malloc((len + 1) * sizeof(char));
- strncpy(dest->str, value, len);
- dest->str[len] = 0;
- } else {
- dest->str = (char *)malloc( sizeof(char));
- dest->str[0] = 0;
- }
- break;
- case MISDN_CTYPE_INT:
- {
- char *pat;
- if (strchr(value,'x'))
- pat="%x";
- else
- pat="%d";
- if (sscanf(value, pat, &tmp)) {
- dest->num = (int *)malloc(sizeof(int));
- memcpy(dest->num, &tmp, sizeof(int));
- } else
- re = -1;
- }
- break;
- case MISDN_CTYPE_BOOL:
- dest->num = (int *)malloc(sizeof(int));
- *(dest->num) = (ast_true(value) ? 1 : 0);
- break;
- case MISDN_CTYPE_BOOLINT:
- dest->num = (int *)malloc(sizeof(int));
- if (sscanf(value, "%d", &tmp)) {
- memcpy(dest->num, &tmp, sizeof(int));
- } else {
- *(dest->num) = (ast_true(value) ? boolint_def : 0);
- }
- break;
- case MISDN_CTYPE_MSNLIST:
- for (valtmp = strsep(&value, ","); valtmp; valtmp = strsep(&value, ",")) {
- if ((len = strlen(valtmp))) {
- struct msn_list *ml = (struct msn_list *)malloc(sizeof(struct msn_list));
- ml->msn = (char *)calloc(len+1, sizeof(char));
- strncpy(ml->msn, valtmp, len);
- ml->next = dest->ml;
- dest->ml = ml;
- }
- }
- break;
- case MISDN_CTYPE_ASTGROUP:
- dest->grp = (ast_group_t *)malloc(sizeof(ast_group_t));
- *(dest->grp) = ast_get_group(value);
- break;
- }
-
- return re;
-}
-
-static void _build_general_config (struct ast_variable *v)
-{
- int pos;
-
- for (; v; v = v->next) {
- if (((pos = get_cfg_position(v->name, GEN_CFG)) < 0) ||
- (_parse(&general_cfg[pos], v->value, gen_spec[pos].type, gen_spec[pos].boolint_def) < 0))
- CLI_ERROR(v->name, v->value, "general");
- }
-}
-
-static void _build_port_config (struct ast_variable *v, char *cat)
-{
- int pos, i;
- union misdn_cfg_pt cfg_tmp[NUM_PORT_ELEMENTS];
- int cfg_for_ports[max_ports + 1];
-
- if (!v || !cat)
- return;
-
- memset(cfg_tmp, 0, sizeof(cfg_tmp));
- memset(cfg_for_ports, 0, sizeof(cfg_for_ports));
-
- if (!strcasecmp(cat, "default")) {
- cfg_for_ports[0] = 1;
- }
-
- if (((pos = get_cfg_position("name", PORT_CFG)) < 0) ||
- (_parse(&cfg_tmp[pos], cat, port_spec[pos].type, port_spec[pos].boolint_def) < 0)) {
- CLI_ERROR(v->name, v->value, cat);
- return;
- }
-
- for (; v; v = v->next) {
- if (!strcasecmp(v->name, "ports")) {
- char *token;
- char ptpbuf[BUFFERSIZE] = "";
- int start, end;
- for (token = strsep(&v->value, ","); token; token = strsep(&v->value, ","), *ptpbuf = 0) {
- if (!*token)
- continue;
- if (sscanf(token, "%d-%d%s", &start, &end, ptpbuf) >= 2) {
- for (; start <= end; start++) {
- if (start <= max_ports && start > 0) {
- cfg_for_ports[start] = 1;
- ptp[start] = (strstr(ptpbuf, "ptp")) ? 1 : 0;
- } else
- CLI_ERROR(v->name, v->value, cat);
- }
- } else {
- if (sscanf(token, "%d%s", &start, ptpbuf)) {
- if (start <= max_ports && start > 0) {
- cfg_for_ports[start] = 1;
- ptp[start] = (strstr(ptpbuf, "ptp")) ? 1 : 0;
- } else
- CLI_ERROR(v->name, v->value, cat);
- } else
- CLI_ERROR(v->name, v->value, cat);
- }
- }
- } else {
- if (((pos = get_cfg_position(v->name, PORT_CFG)) < 0) ||
- (_parse(&cfg_tmp[pos], v->value, port_spec[pos].type, port_spec[pos].boolint_def) < 0))
- CLI_ERROR(v->name, v->value, cat);
- }
- }
-
- for (i = 0; i < (max_ports + 1); ++i) {
- if (cfg_for_ports[i]) {
- memcpy(port_cfg[i], cfg_tmp, sizeof(cfg_tmp));
- }
- }
-}
-
-void misdn_cfg_update_ptp (void)
-{
-#ifndef MISDN_1_2
- char misdn_init[BUFFERSIZE];
- char line[BUFFERSIZE];
- FILE *fp;
- char *tok, *p, *end;
- int port;
-
- misdn_cfg_get(0, MISDN_GEN_MISDN_INIT, &misdn_init, sizeof(misdn_init));
-
- if (!ast_strlen_zero(misdn_init)) {
- fp = fopen(misdn_init, "r");
- if (fp) {
- while(fgets(line, sizeof(line), fp)) {
- if (!strncmp(line, "nt_ptp", 6)) {
- for (tok = strtok_r(line,",=", &p);
- tok;
- tok = strtok_r(NULL,",=", &p)) {
- port = strtol(tok, &end, 10);
- if (end != tok && misdn_cfg_is_port_valid(port)) {
- misdn_cfg_lock();
- ptp[port] = 1;
- misdn_cfg_unlock();
- }
- }
- }
- }
- fclose(fp);
- } else {
- ast_log(LOG_WARNING,"Couldn't open %s: %s\n", misdn_init, strerror(errno));
- }
- }
-#else
- int i;
- int proto;
- char filename[128];
- FILE *fp;
-
- for (i = 1; i <= max_ports; ++i) {
- snprintf(filename, sizeof(filename), "/sys/class/mISDN-stacks/st-%08x/protocol", i << 8);
- fp = fopen(filename, "r");
- if (!fp) {
- ast_log(LOG_WARNING, "Could not open %s: %s\n", filename, strerror(errno));
- continue;
- }
- if (fscanf(fp, "0x%08x", &proto) != 1)
- ast_log(LOG_WARNING, "Could not parse contents of %s!\n", filename);
- else
- ptp[i] = proto & 1<<5 ? 1 : 0;
- fclose(fp);
- }
-#endif
-}
-
-static void _fill_defaults (void)
-{
- int i;
-
- for (i = 0; i < NUM_PORT_ELEMENTS; ++i) {
- if (!port_cfg[0][i].any && strcasecmp(port_spec[i].def, NO_DEFAULT))
- _parse(&(port_cfg[0][i]), (char *)port_spec[i].def, port_spec[i].type, port_spec[i].boolint_def);
- }
- for (i = 0; i < NUM_GEN_ELEMENTS; ++i) {
- if (!general_cfg[i].any && strcasecmp(gen_spec[i].def, NO_DEFAULT))
- _parse(&(general_cfg[i]), (char *)gen_spec[i].def, gen_spec[i].type, gen_spec[i].boolint_def);
- }
-}
-
-void misdn_cfg_reload (void)
-{
- misdn_cfg_init (0);
-}
-
-void misdn_cfg_destroy (void)
-{
- misdn_cfg_lock();
-
- _free_port_cfg();
- _free_general_cfg();
-
- free(port_cfg);
- free(general_cfg);
- free(ptp);
- free(map);
-
- misdn_cfg_unlock();
- ast_mutex_destroy(&config_mutex);
-}
-
-int misdn_cfg_init (int this_max_ports)
-{
- char config[] = "misdn.conf";
- char *cat, *p;
- int i;
- struct ast_config *cfg;
- struct ast_variable *v;
-
- if (!(cfg = AST_LOAD_CFG(config))) {
- ast_log(LOG_WARNING, "missing file: misdn.conf\n");
- return -1;
- }
-
- ast_mutex_init(&config_mutex);
-
- misdn_cfg_lock();
-
- if (this_max_ports) {
- /* this is the first run */
- max_ports = this_max_ports;
- map = (int *)calloc(MISDN_GEN_LAST + 1, sizeof(int));
- if (_enum_array_map())
- return -1;
- p = (char *)calloc(1, (max_ports + 1) * sizeof(union misdn_cfg_pt *)
- + (max_ports + 1) * NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt));
- port_cfg = (union misdn_cfg_pt **)p;
- p += (max_ports + 1) * sizeof(union misdn_cfg_pt *);
- for (i = 0; i <= max_ports; ++i) {
- port_cfg[i] = (union misdn_cfg_pt *)p;
- p += NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt);
- }
- general_cfg = (union misdn_cfg_pt *)calloc(1, sizeof(union misdn_cfg_pt *) * NUM_GEN_ELEMENTS);
- ptp = (int *)calloc(max_ports + 1, sizeof(int));
- }
- else {
- /* misdn reload */
- _free_port_cfg();
- _free_general_cfg();
- memset(port_cfg[0], 0, NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt) * (max_ports + 1));
- memset(general_cfg, 0, sizeof(union misdn_cfg_pt *) * NUM_GEN_ELEMENTS);
- memset(ptp, 0, sizeof(int) * (max_ports + 1));
- }
-
- cat = ast_category_browse(cfg, NULL);
-
- while(cat) {
- v = ast_variable_browse(cfg, cat);
- if (!strcasecmp(cat, "general")) {
- _build_general_config(v);
- } else {
- _build_port_config(v, cat);
- }
- cat = ast_category_browse(cfg, cat);
- }
-
- _fill_defaults();
-
- misdn_cfg_unlock();
- AST_DESTROY_CFG(cfg);
-
- return 0;
-}
-
-
diff --git a/1.4/channels/ring10.h b/1.4/channels/ring10.h
deleted file mode 100644
index f45f8dbb9..000000000
--- a/1.4/channels/ring10.h
+++ /dev/null
@@ -1,1752 +0,0 @@
-/*! \file
- * \brief Signed 16-bit audio data
- *
- * Source: /home/markster/ring10.raw
- *
- * Copyright (C) 1999-2005, Digium, Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short ring10[] = {
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 0x82a0, 0x8dc7, 0x607e, 0xc0c6, 0x2bd3,
-0x8df5, 0x828d, 0x0716, 0xaca6, 0xcefe, 0x41df, 0xd185, 0x8aa3, 0x8b1a, 0x789b,
-0x82a2, 0x804f, 0x7ea8, 0x8113, 0x7f7d, 0x7fff, 0x801e, 0x801d, 0x7f32, 0x82ec,
-0x83e1, 0x7fb0, 0x7f71, 0x80de, 0x7f3d, 0x7fe3, 0x81b4, 0x7c37, 0x8553, 0x7b29,
-0x7ede, 0xde6e, 0x0e64, 0xf9f4, 0x015e, 0x00f6, 0xfe56, 0x0019, 0xf8bb, 0xfd90,
-0x08cc, 0x05ab, 0xfd0b, 0xf9c6, 0xf875, 0xf789, 0xfc74, 0x032e, 0xf97a, 0xf4bb,
-0x0212, 0x006e, 0x03df, 0x17c5, 0x0f50, 0xfb23, 0xfdbd, 0xf7cf, 0xdf5b, 0xe2d3,
-0xf111, 0xef27, 0x11c5, 0x33a4, 0x168d, 0x0145, 0x0494, 0xe85c, 0xdac3, 0xf0c7,
-0xeea8, 0x0023, 0x3036, 0x252a, 0xffb7, 0x01d1, 0xf637, 0xd506, 0xe8eb, 0xf5ff,
-0xe5ca, 0x1ec5, 0x3fa4, 0x0e3c, 0x1570, 0x2b37, 0xea23, 0xca43, 0xf392, 0xdf0e,
-0xde40, 0x2e7c, 0x276f, 0x035c, 0x2ccc, 0x1acf, 0xcf4a, 0xeb5b, 0x0fb1, 0xe01a,
-0x0c69, 0x3a97, 0xfb54, 0x0751, 0x20f1, 0xdce9, 0xd2a2, 0x19b3, 0x096f, 0xf1b6,
-0x38de, 0x1f70, 0xf32b, 0x2569, 0x0650, 0xc3d7, 0xf1ad, 0x1aa5, 0xe87e, 0x0c7f,
-0x406d, 0xffaa, 0x0ba8, 0x2e02, 0xe545, 0xcebb, 0x10fc, 0x0102, 0xded8, 0x2b7c,
-0x2053, 0xec6f, 0x266e, 0x1770, 0xcb63, 0xf18e, 0x2015, 0xe6ef, 0xfe64, 0x3700,
-0xf628, 0xfb00, 0x2e43, 0xee48, 0xcd4a, 0x1867, 0x0ec3, 0xdd77, 0x2291, 0x1c80,
-0xe325, 0x19b7, 0x1719, 0xcb88, 0xeded, 0x258c, 0xe7e8, 0xf0c6, 0x2d21, 0xf3d5,
-0xf494, 0x290d, 0xef7b, 0xca28, 0x12c8, 0x0d8d, 0xd5f3, 0x171d, 0x1994, 0xe0c0,
-0x1348, 0x1929, 0xcf9b, 0xe6fb, 0x20ae, 0xe921, 0xed2b, 0x2c54, 0xf96e, 0xf19f,
-0x21b6, 0xf12e, 0xc8b4, 0x0907, 0x0964, 0xd049, 0x0eb8, 0x1fa6, 0xe6b5, 0x0cec,
-0x16b6, 0xcd0c, 0xda57, 0x17c9, 0xe440, 0xe2a2, 0x2b4d, 0xffa2, 0xec7e, 0x1ee9,
-0xf674, 0xbfcb, 0xf769, 0x0402, 0xcfe8, 0x104b, 0x2734, 0xe7e9, 0x07d9, 0x19f4,
-0xd032, 0xd00b, 0x0e46, 0xe17d, 0xe2d8, 0x3456, 0x0781, 0xed01, 0x238d, 0xfa72,
-0xbb51, 0xf543, 0x050b, 0xccd5, 0x1491, 0x3358, 0xedad, 0x10c4, 0x283b, 0xd051,
-0xc9e9, 0x11f8, 0xe2cb, 0xe534, 0x43aa, 0x1090, 0xf11b, 0x3267, 0x02c3, 0xb72d,
-0xf9ac, 0x0fbd, 0xce45, 0x1d7b, 0x4389, 0xef2e, 0x1593, 0x348e, 0xd0cb, 0xca8c,
-0x1f61, 0xe981, 0xdef7, 0x4774, 0x15ae, 0xefab, 0x3b28, 0x0a9e, 0xb2f6, 0xf9e9,
-0x1976, 0xcc08, 0x15ab, 0x4534, 0xee6c, 0x159b, 0x3753, 0xcf09, 0xc69a, 0x2270,
-0xf15c, 0xdee6, 0x48ce, 0x1af4, 0xf169, 0x3da0, 0x0d68, 0xb573, 0xff9e, 0x20ba,
-0xcbfe, 0x142d, 0x4879, 0xed49, 0x1434, 0x3d96, 0xd714, 0xca99, 0x298b, 0xf708,
-0xd92c, 0x4632, 0x1acc, 0xea6e, 0x3d2c, 0x1412, 0xb534, 0xfbfa, 0x24f9, 0xcd72,
-0x0df9, 0x48f8, 0xeb87, 0x0bca, 0x3dd5, 0xd6cc, 0xc015, 0x2605, 0xfa87, 0xd1a9,
-0x40d0, 0x1c59, 0xe0de, 0x34f9, 0x14c6, 0xaf61, 0xf2a5, 0x23e6, 0xc929, 0x01be,
-0x4423, 0xe53b, 0x0182, 0x3c3a, 0xd758, 0xbb9d, 0x1fa9, 0xf454, 0xc611, 0x36e8,
-0x18f7, 0xdac9, 0x2e8a, 0x126d, 0xac14, 0xead6, 0x2215, 0xc990, 0xf9f5, 0x43cb,
-0xea01, 0xfcbf, 0x38fd, 0xd9f3, 0xb7cd, 0x1bc4, 0xfd41, 0xca56, 0x31e3, 0x1d4b,
-0xdca2, 0x2a9f, 0x1c24, 0xb8aa, 0xeb59, 0x25d5, 0xd2d0, 0xfa10, 0x44fa, 0xefe0,
-0xfced, 0x3ef4, 0xe9a1, 0xbdf0, 0x19ac, 0x0198, 0xca6f, 0x2f04, 0x25b6, 0xe187,
-0x29ba, 0x250a, 0xbe42, 0xe40e, 0x24ef, 0xd75d, 0xf476, 0x44f8, 0xf719, 0xf7a1,
-0x3c94, 0xf20e, 0xbcdf, 0x16a3, 0x07e8, 0xc8d4, 0x2a3e, 0x2b3f, 0xdf4e, 0x235d,
-0x2c92, 0xc2c7, 0xdf39, 0x2873, 0xd790, 0xea2a, 0x47fd, 0xfd0e, 0xf0e3, 0x3bd8,
-0xf4e9, 0xb265, 0x0c2c, 0x0751, 0xc302, 0x29bb, 0x37bd, 0xe138, 0x1e0c, 0x2d09,
-0xbddb, 0xd246, 0x24c4, 0xd87a, 0xe5df, 0x4ff6, 0x08d6, 0xf0d8, 0x3d61, 0xf8bf,
-0xaede, 0x0a36, 0x0df3, 0xc0f5, 0x23ec, 0x3e92, 0xe3d7, 0x1cad, 0x348e, 0xc0d6,
-0xcd4e, 0x265c, 0xd9b6, 0xdf83, 0x510e, 0x0c41, 0xeece, 0x4153, 0xfeeb, 0xa9f6,
-0x04b3, 0x12a4, 0xbf2f, 0x20d1, 0x42f4, 0xe1b1, 0x1b1e, 0x3980, 0xc2b4, 0xcb50,
-0x2b74, 0xded0, 0xd835, 0x4e7a, 0x0b46, 0xe555, 0x4015, 0x0517, 0xaa54, 0x0504,
-0x1932, 0xbc34, 0x1a77, 0x48b1, 0xe0bb, 0x149b, 0x3ba7, 0xc34a, 0xc481, 0x2bc2,
-0xe401, 0xd20e, 0x4f53, 0x1389, 0xe3b7, 0x418b, 0x0a15, 0xa70d, 0x0024, 0x1f9f,
-0xbf65, 0x142d, 0x4a81, 0xe0ca, 0x1152, 0x4325, 0xcb03, 0xc18a, 0x2b95, 0xeb45,
-0xcf92, 0x4c54, 0x18ad, 0xe08b, 0x3f12, 0x1264, 0xa9fc, 0xfd97, 0x246f, 0xbf86,
-0x0ce2, 0x4e7c, 0xe4f3, 0x0c20, 0x44e0, 0xd069, 0xbdcb, 0x2b8e, 0xf32d, 0xcad4,
-0x464f, 0x1e76, 0xdf62, 0x3b07, 0x17ea, 0xaafb, 0xf5a0, 0x2835, 0xc7c2, 0x0842,
-0x4d2b, 0xe634, 0x03ef, 0x42bc, 0xd7f2, 0xbb73, 0x2662, 0xf892, 0xc8b3, 0x3e30,
-0x1f20, 0xdcca, 0x354a, 0x1c6b, 0xaf75, 0xf0f7, 0x2963, 0xc908, 0xfdbf, 0x4c3c,
-0xebe5, 0x00e3, 0x44c4, 0xdf15, 0xb9e9, 0x243b, 0x00e9, 0xcb76, 0x3b53, 0x248e,
-0xdc27, 0x2fcb, 0x22e5, 0xb66c, 0xec96, 0x2b19, 0xd0ef, 0xf97b, 0x48ae, 0xecc0,
-0xf8b4, 0x411d, 0xe769, 0xb9f7, 0x1c41, 0x0022, 0xc369, 0x2ced, 0x23ac, 0xd8eb,
-0x2522, 0x232a, 0xb611, 0xe19f, 0x2738, 0xd013, 0xece5, 0x434c, 0xf00e, 0xefcc,
-0x3b79, 0xeb32, 0xb19c, 0x135e, 0x04ef, 0xc1b9, 0x27a8, 0x2992, 0xd7b3, 0x1ba5,
-0x2481, 0xb8c5, 0xd97d, 0x246f, 0xd113, 0xe45d, 0x4486, 0xf7f7, 0xeb36, 0x395a,
-0xf122, 0xaea5, 0x0c28, 0x05eb, 0xbde4, 0x2585, 0x36a2, 0xde67, 0x1b86, 0x2dac,
-0xbd03, 0xd2b8, 0x2624, 0xd8b8, 0xe802, 0x521b, 0x0855, 0xefbc, 0x4048, 0xfad2,
-0xafe2, 0x0fb1, 0x12b2, 0xc62c, 0x2c2a, 0x43f5, 0xe562, 0x1fcb, 0x3791, 0xc2ac,
-0xd4d1, 0x2dfd, 0xde0a, 0xe53f, 0x5578, 0x0f49, 0xf2b6, 0x4609, 0x0105, 0xabf5,
-0x09a8, 0x157e, 0xc286, 0x23e7, 0x425f, 0xe36a, 0x1d93, 0x3580, 0xbf80, 0xcaf2,
-0x2a04, 0xf16e, 0xd92b, 0x0eaa, 0xf1a7, 0x1ddb, 0x5b52, 0x0665, 0xd2e3, 0x15f8,
-0xf606, 0x9d42, 0xdba7, 0xf312, 0xd349, 0x21ed, 0x576a, 0x34e8, 0x2450, 0x2679,
-0xdc01, 0xb506, 0xcb0f, 0xa454, 0xccf3, 0x2c13, 0x1673, 0xf8ca, 0x4ff1, 0x63ac,
-0xec26, 0xd77c, 0xf1f9, 0xc268, 0xb11a, 0xdfe4, 0x02e7, 0x10f5, 0x3512, 0x19dd,
-0x0edc, 0x3568, 0xf6f7, 0xbe10, 0xda93, 0xf4fe, 0xda03, 0xe293, 0x15dd, 0x15f3,
-0x1ba5, 0x1521, 0x12e8, 0x23ab, 0x0fc3, 0xdb3e, 0xb671, 0xe960, 0xe13c, 0xc695,
-0x1a81, 0x3d23, 0x1c56, 0x190d, 0x4234, 0x1970, 0xd784, 0xd86b, 0xb5e8, 0xc9f3,
-0xeb89, 0xe344, 0x17ae, 0x5713, 0x37fc, 0xffe2, 0x36b3, 0x1dfe, 0xb963, 0xbf9c,
-0xc9a1, 0xcc7b, 0xe409, 0x08a6, 0x2077, 0x3b4d, 0x3cba, 0x0553, 0x220e, 0x226e,
-0xd219, 0xb7ec, 0xcb8b, 0xdf2a, 0xd0c7, 0xf5be, 0x2ff0, 0x42a6, 0x3c24, 0x25ae,
-0x2d6d, 0x0d94, 0xde80, 0xb78b, 0xb12b, 0xdf7a, 0xde33, 0x0046, 0x47b1, 0x5170,
-0x29c0, 0x2945, 0x3ab5, 0xf08f, 0xc806, 0xc229, 0xbbf4, 0xe40d, 0xf365, 0x0bfe,
-0x448d, 0x5cd8, 0x1e52, 0x10ba, 0x3908, 0xefa4, 0xc243, 0xcf89, 0xd02d, 0xde92,
-0xf8e0, 0x191e, 0x2f7b, 0x48e6, 0x1e38, 0x1074, 0x3785, 0xf8be, 0xbd1c, 0xc06b,
-0xdc36, 0xdb97, 0xe3c0, 0x2042, 0x37c5, 0x36ff, 0x1b73, 0x2064, 0x2c9a, 0xefa2,
-0xbf0c, 0xb7f0, 0xe221, 0xe243, 0xd998, 0x2263, 0x4bae, 0x3596, 0x18aa, 0x3763,
-0x27d0, 0xdcc6, 0xcacc, 0xc06f, 0xd83d, 0xecfe, 0xeefa, 0x1ffa, 0x5052, 0x393f,
-0x0af5, 0x3c9e, 0x316b, 0xd2df, 0xc575, 0xd3c8, 0xddd2, 0xdf98, 0xfbd7, 0x2929,
-0x4879, 0x4052, 0x160c, 0x3708, 0x2b31, 0xdac6, 0xc0c3, 0xcfc0, 0xe71d, 0xddec,
-0x0145, 0x3847, 0x457c, 0x356b, 0x214a, 0x3a5f, 0x1474, 0xd892, 0xc579, 0xc6a7,
-0xe77a, 0xe4dc, 0x00ab, 0x3b89, 0x4eba, 0x290a, 0x16ea, 0x3dc6, 0x0956, 0xcc12,
-0xc3bd, 0xc9e9, 0xe4be, 0xe60b, 0x0561, 0x3707, 0x4c82, 0x2444, 0x1406, 0x3a8e,
-0xff5b, 0xc494, 0xbf9f, 0xcb26, 0xdfef, 0xe755, 0x1060, 0x334f, 0x40e5, 0x1f87,
-0x16b9, 0x33e8, 0xfa6e, 0xc670, 0xb774, 0xcc17, 0xe18f, 0xdd0f, 0x102c, 0x3f0d,
-0x4098, 0x1b95, 0x24b2, 0x315a, 0xe9d8, 0xc459, 0xb314, 0xc524, 0xe2a6, 0xe1cf,
-0x100a, 0x44af, 0x455c, 0x1551, 0x264f, 0x2ab1, 0xd681, 0xb90c, 0xb4d6, 0xc68d,
-0xddac, 0xef74, 0x1f57, 0x4357, 0x4192, 0x0e60, 0x1bcb, 0x20fd, 0xd477, 0xb435,
-0xb3e3, 0xcdc3, 0xd9c4, 0xef97, 0x2384, 0x3b60, 0x34c9, 0x119d, 0x1f15, 0x0fb3,
-0xd15d, 0xb30d, 0xa9e3, 0xd431, 0xdc02, 0xe98a, 0x2987, 0x4204, 0x290c, 0x1181,
-0x2d0c, 0x0800, 0xcb55, 0xb8f5, 0xaaa6, 0xd49f, 0xe57c, 0xf063, 0x281c, 0x4c65,
-0x2d19, 0x0cd2, 0x2ddb, 0xfefe, 0xc171, 0xbd4c, 0xb7c2, 0xd4c5, 0xe6f3, 0x0040,
-0x2b86, 0x4b6d, 0x2ed1, 0x0ce3, 0x2d97, 0x01f9, 0xc2ad, 0xb8fc, 0xc53e, 0xe1cf,
-0xea35, 0x0eb0, 0x38b8, 0x4a3b, 0x2a1e, 0x1457, 0x2a1e, 0xfbca, 0xcdf1, 0xbc93,
-0xcc0b, 0xec27, 0xeb05, 0x144b, 0x4443, 0x496d, 0x2233, 0x2180, 0x30b2, 0xf03c,
-0xcced, 0xbf0d, 0xcc55, 0xeec3, 0xf367, 0x186f, 0x45cd, 0x4e7d, 0x215a, 0x2485,
-0x3122, 0xe7a8, 0xc40a, 0xbf85, 0xd4dd, 0xebe8, 0xf32b, 0x2121, 0x49bb, 0x4c61,
-0x1af5, 0x1f88, 0x2c32, 0xe8c5, 0xc512, 0xc0b7, 0xdbf9, 0xe9ea, 0xf2f4, 0x2584,
-0x43e2, 0x3e1b, 0x19cf, 0x28d2, 0x2442, 0xe27b, 0xc589, 0xbe8a, 0xdddc, 0xe567,
-0xed4e, 0x27f2, 0x48cd, 0x3505, 0x0e88, 0x2cd5, 0x207d, 0xda54, 0xc1cf, 0xb8c1,
-0xd925, 0xe569, 0xefd0, 0x2723, 0x4dd1, 0x38b2, 0x0de5, 0x2d90, 0x155b, 0xca06,
-0xbab6, 0xbf37, 0xdd46, 0xe3fd, 0xfb50, 0x2e5d, 0x487b, 0x343e, 0x0abe, 0x25e9,
-0x0f65, 0xcb83, 0xb474, 0xbc50, 0xe2ab, 0xe1df, 0xfd3e, 0x3672, 0x458b, 0x294e,
-0x10fd, 0x2afa, 0x027f, 0xcae8, 0xb95b, 0xbc6f, 0xe536, 0xe3af, 0xfd1c, 0x3b18,
-0x4cb1, 0x23ff, 0x13eb, 0x3353, 0xfb34, 0xc4aa, 0xb71a, 0xb9f2, 0xe1d7, 0xe97f,
-0x058d, 0x3a0f, 0x4fcd, 0x2408, 0x11a3, 0x2fb9, 0xf271, 0xbb7f, 0xb447, 0xc317,
-0xde44, 0xe56a, 0x110a, 0x3ccc, 0x494a, 0x1f80, 0x11af, 0x26a1, 0xeb09, 0xbcd0,
-0xaf90, 0xc8d4, 0xe63f, 0xe47d, 0x1435, 0x3f4f, 0x3fbe, 0x17c7, 0x1a4f, 0x2393,
-0xe191, 0xbfa1, 0xb0e4, 0xc7c9, 0xe2d9, 0xe363, 0x1625, 0x4320, 0x3da9, 0x11c4,
-0x1e02, 0x1d1b, 0xd6be, 0xbe96, 0xb123, 0xc8a4, 0xe6ce, 0xef2e, 0x1c03, 0x4584,
-0x3fd1, 0x1006, 0x20d8, 0x197b, 0xcf64, 0xb99e, 0xb693, 0xd396, 0xe8eb, 0xfb01,
-0x2aca, 0x4b38, 0x3f87, 0x0de0, 0x1f2f, 0x1503, 0xd574, 0xba46, 0xb72d, 0xf07a,
-0xfa16, 0xf608, 0x29c0, 0x3a7e, 0x42a7, 0x43ac, 0x2717, 0xec6f, 0xd732, 0xc1ac,
-0xa146, 0xef37, 0x122b, 0x05c1, 0x5c67, 0x8e8c, 0x3d5e, 0x0043, 0x00d0, 0xb9ef,
-0xa38d, 0xc8dd, 0xc921, 0x15c9, 0x5fe3, 0x531a, 0x477d, 0x5852, 0x1b9f, 0xb930,
-0xd1b6, 0xde60, 0xbcce, 0xe7f7, 0x16b1, 0x2aeb, 0x4605, 0x3592, 0xfe8c, 0x0c1d,
-0x1b24, 0xd084, 0xd667, 0x2736, 0x06f7, 0xdfa7, 0x1976, 0x0df9, 0xc5e8, 0x032b,
-0x324e, 0xea0e, 0x1ab4, 0x46e4, 0xf72e, 0x0369, 0x0ef3, 0xbe35, 0xbd17, 0x10fd,
-0xfb35, 0xeb3f, 0x4e43, 0x2da4, 0xfe31, 0x2f50, 0xf64c, 0xafd6, 0xe267, 0xfd01,
-0xca77, 0x1087, 0x48c1, 0xfcf4, 0x1bb0, 0x31af, 0xd234, 0xc0cb, 0x054e, 0xec6b,
-0xce29, 0x29db, 0x1bb4, 0xf0fd, 0x3608, 0x12eb, 0xbb40, 0xeaa8, 0x190f, 0xce00,
-0xed59, 0x39ef, 0xf1f0, 0xfb2a, 0x3535, 0xe3b3, 0xbf33, 0x1a9b, 0x013b, 0xc2ab,
-0x2976, 0x21e0, 0xd3d8, 0x1ca6, 0x14ae, 0xb242, 0xe538, 0x2958, 0xd98c, 0xf279,
-0x4106, 0xf13e, 0xf68b, 0x3379, 0xe023, 0xb4a8, 0x104b, 0x0685, 0xcca4, 0x2e61,
-0x2d96, 0xe2b8, 0x26ac, 0x2510, 0xc114, 0xd9e5, 0x1f91, 0xdbc9, 0xe515, 0x40bd,
-0x0693, 0xff44, 0x3c5e, 0xf664, 0xb8dc, 0x0b37, 0x1314, 0xc29c, 0x161f, 0x3582,
-0xe32e, 0x17c0, 0x2de6, 0xc7c1, 0xcfeb, 0x23a6, 0xe644, 0xe65f, 0x4256, 0xf765,
-0xe698, 0x4148, 0xfbe1, 0xa6b4, 0x03fa, 0x1c92, 0xcb85, 0x1a54, 0x37af, 0xe830,
-0x1b0b, 0x255d, 0xc13f, 0xd3d9, 0x205e, 0xde69, 0xe2ab, 0x48d5, 0x0931, 0xee2f,
-0x3d79, 0x0658, 0xb36c, 0xf59e, 0x11f4, 0xd042, 0x110b, 0x2e1b, 0xe763, 0x2269,
-0x3bda, 0xcefb, 0xd37b, 0x2d7f, 0xe9d7, 0xd48e, 0x3fd2, 0x0e86, 0xea62, 0x3cd5,
-0x11e0, 0xc1dc, 0x08e0, 0x1f68, 0xd3f1, 0x1fc8, 0x3da6, 0xe12f, 0x1d62, 0x4060,
-0xccb6, 0xd211, 0x316f, 0xf370, 0xe20e, 0x4657, 0x1280, 0xf30a, 0x3df0, 0x07fc,
-0xb956, 0x023e, 0x1978, 0xcbba, 0x137d, 0x3ff7, 0xecbc, 0x1698, 0x3f29, 0xdf9f,
-0xcc1c, 0x1bdc, 0xef17, 0xd3da, 0x346b, 0x1296, 0xeb25, 0x3885, 0x190f, 0xbf13,
-0xfb71, 0x1df2, 0xc509, 0xffa2, 0x3a66, 0xe5fd, 0x04f6, 0x36be, 0xda99, 0xc67e,
-0x1fc2, 0xef95, 0xcfa8, 0x39df, 0x0f1a, 0xd986, 0x2d7b, 0x0e88, 0xb2a2, 0xf40f,
-0x1bd3, 0xc95c, 0x0511, 0x408d, 0xec48, 0x03d2, 0x3281, 0xd7a0, 0xb9a0, 0x13ab,
-0xf02d, 0xc92c, 0x3af6, 0x26c0, 0xe5f8, 0x2de7, 0x18b9, 0xafd8, 0xddbf, 0x15bc,
-0xc4d3, 0xf6dc, 0x4b73, 0xf89f, 0x018a, 0x3c4e, 0xdf11, 0xb20d, 0x12d7, 0xf511,
-0xbf7e, 0x33aa, 0x286f, 0xe309, 0x3107, 0x1f74, 0xb1c3, 0xe10f, 0x1fd3, 0xc7d4,
-0xef6e, 0x4b78, 0xf32f, 0xf8e5, 0x43cb, 0xe7da, 0xaf46, 0x115a, 0xfeb2, 0xbf7a,
-0x2e9a, 0x2ed7, 0xde2f, 0x2807, 0x259c, 0xb09f, 0xd3d4, 0x2606, 0xd544, 0xeb3d,
-0x5107, 0xfecf, 0xf63f, 0x4304, 0xedfe, 0xae0d, 0x0d7f, 0x0957, 0xc47d, 0x2f62,
-0x3b51, 0xdfea, 0x2a01, 0x3390, 0xb825, 0xd3e9, 0x29f1, 0xd82e, 0xe2e3, 0x509a,
-0x061c, 0xf530, 0x48b1, 0xf740, 0xabeb, 0x0d93, 0x0ed4, 0xbed0, 0x274e, 0x3e3b,
-0xddc2, 0x2168, 0x35a1, 0xbbb0, 0xcedb, 0x2b94, 0xdd5b, 0xdd2d, 0x4e6a, 0x068d,
-0xe741, 0x3eef, 0xfe34, 0xad12, 0x0bb7, 0x1a73, 0xbea5, 0x1c31, 0x4269, 0xdc1a,
-0x1611, 0x37d6, 0xc048, 0xcaa3, 0x2f7e, 0xe59c, 0xd94c, 0x4ed8, 0x0af6, 0xe225,
-0x3c84, 0xfd49, 0xa4b2, 0x048d, 0x1ed5, 0xc496, 0x1caa, 0x4641, 0xddd4, 0x1578,
-0x37dc, 0xc13b, 0xcab7, 0x30dc, 0xfec0, 0xd462, 0x1387, 0x07dd, 0x14c1, 0x4b92,
-0x0d74, 0xda49, 0x12de, 0x02fe, 0xb8fe, 0xeaae, 0x0363, 0xdab0, 0x23b0, 0x68fb,
-0x3681, 0x1351, 0x29fc, 0xf22e, 0xb781, 0xd225, 0xc11d, 0xd7d8, 0x354d, 0x26b8,
-0x09af, 0x60fa, 0x5f8c, 0xe302, 0xde80, 0xff6a, 0xbb95, 0xafec, 0x029f, 0x161d,
-0x0fee, 0x3924, 0x2b6c, 0x1ed5, 0x24fe, 0xec7b, 0xc1fe, 0xe22b, 0xfbcd, 0xdc4d,
-0xf3f7, 0x210f, 0x1d01, 0x1305, 0x1342, 0x1f6c, 0x0852, 0xfea5, 0xdd42, 0xc083,
-0xf243, 0xde95, 0xd818, 0x23f7, 0x3eab, 0x0891, 0x1381, 0x52fd, 0xff10, 0xc983,
-0xe091, 0xc3b8, 0xcafc, 0xe7d7, 0xfc8d, 0x2043, 0x559d, 0x2c2e, 0x0418, 0x4485,
-0x0b4c, 0xb4e5, 0xc68e, 0xddbf, 0xd0b6, 0xdc81, 0x1e4b, 0x2d10, 0x365b, 0x2c50,
-0x170a, 0x303e, 0x0a60, 0xcc89, 0xb88a, 0xdbc7, 0xe3e7, 0xcdd2, 0x0b38, 0x3c7e,
-0x392b, 0x254c, 0x3272, 0x2fc9, 0xf0ee, 0xd4d8, 0xb5b4, 0xc03b, 0xdef0, 0xd8e9,
-0x0edc, 0x533e, 0x46e4, 0x0fc4, 0x358a, 0x34b8, 0xd1c3, 0xbf29, 0xbb64, 0xbeea,
-0xdb1c, 0xf31b, 0x17f1, 0x44fa, 0x4bfb, 0x0a36, 0x1fe2, 0x2ce9, 0xcf0d, 0xb605,
-0xc6c6, 0xcc96, 0xcf30, 0xf9cd, 0x25fb, 0x36d1, 0x4086, 0x1499, 0x21d8, 0x287f,
-0xde77, 0xb0fd, 0xba6d, 0xe0f5, 0xd3e4, 0xee77, 0x3561, 0x4077, 0x2baa, 0x1d38,
-0x3753, 0x1587, 0xd2e2, 0xb252, 0xb44b, 0xe5a7, 0xdbb5, 0xe778, 0x3790, 0x55cb,
-0x234e, 0x10ab, 0x42e9, 0x083e, 0xc15a, 0xc2a9, 0xbe30, 0xd7d1, 0xe76a, 0xfa22,
-0x2b37, 0x53cb, 0x29a6, 0x0950, 0x4086, 0x0f68, 0xbba0, 0xb824, 0xcc9c, 0xd743,
-0xd665, 0x06ae, 0x3597, 0x44f1, 0x2854, 0x19d4, 0x3395, 0xfe8f, 0xc1b9, 0xad2d,
-0xc39d, 0xde05, 0xd850, 0x0bf2, 0x4266, 0x457f, 0x1d4b, 0x2284, 0x337f, 0xe442,
-0xbc43, 0xb8ba, 0xc33a, 0xe0e4, 0xe8f8, 0x10b5, 0x4262, 0x4afc, 0x1744, 0x1d2b,
-0x3125, 0xe2b5, 0xbcb6, 0xbdea, 0xccfd, 0xdfe5, 0xefed, 0x1bae, 0x3f5e, 0x451d,
-0x167c, 0x1ea7, 0x2848, 0xdf70, 0xbb35, 0xbbfc, 0xd959, 0xe266, 0xec2b, 0x20e3,
-0x435c, 0x3878, 0x0fee, 0x25e8, 0x1ba1, 0xdaf0, 0xc061, 0xb76f, 0xdd9c, 0xe727,
-0xece4, 0x247e, 0x48ee, 0x303d, 0x099a, 0x320b, 0x19b9, 0xd0b8, 0xc508, 0xbe20,
-0xd52c, 0xe430, 0xf5f1, 0x21d1, 0x4aae, 0x3670, 0x0bc4, 0x349a, 0x16c6, 0xc9e1,
-0xbb8f, 0xc44e, 0xdbed, 0xde26, 0x03b2, 0x34c9, 0x4689, 0x30a8, 0x17ea, 0x33bd,
-0x0b87, 0xcd79, 0xb9b9, 0xc3c1, 0xe227, 0xdffc, 0x07ae, 0x3deb, 0x4732, 0x25e8,
-0x1ef9, 0x370f, 0xfb29, 0xcc78, 0xbf32, 0xc5c0, 0xe807, 0xe571, 0x074b, 0x4121,
-0x4902, 0x1968, 0x206c, 0x3da5, 0xf467, 0xc9c7, 0xc240, 0xc6d8, 0xe2b1, 0xeca9,
-0x0f7d, 0x3a80, 0x4ac1, 0x1bda, 0x1cdc, 0x3836, 0xee35, 0xc32e, 0xc0a2, 0xce3e,
-0xdfd7, 0xe9c8, 0x162c, 0x3eb5, 0x48b0, 0x1a61, 0x1e8f, 0x2cf5, 0xe5c6, 0xbb80,
-0xb378, 0xd228, 0xe3dd, 0xeba5, 0x2266, 0x46f5, 0x3e1f, 0x13fa, 0x26ea, 0x21ec,
-0xd925, 0xbdc7, 0xb66d, 0xd76b, 0xe81e, 0xf025, 0x269d, 0x4d69, 0x3d40, 0x1027,
-0x2c58, 0x1cc9, 0xd265, 0xbfd4, 0xbabe, 0xd919, 0xe822, 0xf931, 0x2bc9, 0x4c69,
-0x3d20, 0x158d, 0x31ca, 0x1821, 0xce8a, 0xb8af, 0xba0f, 0xdfb6, 0xe677, 0xfd3b,
-0x385e, 0x53d9, 0x3764, 0x14a8, 0x30af, 0x0a51, 0xcb95, 0xbad7, 0xbc48, 0xe366,
-0xea7e, 0x06cf, 0x3f08, 0x53c7, 0x2fe0, 0x189d, 0x383f, 0x00fd, 0xc5f3, 0xbf0d,
-0xc38f, 0xe4a3, 0xecee, 0x0ef5, 0x432c, 0x54a7, 0x2a15, 0x190d, 0x3675, 0xf7bc,
-0xc3e0, 0xbc22, 0xc381, 0xe210, 0xec59, 0x15ed, 0x4300, 0x4fd8, 0x269c, 0x1bda,
-0x324a, 0xed57, 0xbb9c, 0xb705, 0xceb8, 0xeb30, 0xed72, 0x1baa, 0x48ad, 0x4bd3,
-0x1fde, 0x1ea9, 0x2826, 0xe505, 0xc2b3, 0xb577, 0xceec, 0xeeb9, 0xef73, 0x1fd5,
-0x4c99, 0x41f7, 0x12c7, 0x24ad, 0x22eb, 0xd504, 0xbfe3, 0xba2a, 0xd063, 0xea6f,
-0xf037, 0x1c9c, 0x4acf, 0x430c, 0x0b68, 0x200d, 0x1c9e, 0xcce4, 0xb9ad, 0xbc29,
-0xd211, 0xe475, 0xfc21, 0x2910, 0x443b, 0x3a83, 0x0ef1, 0x2295, 0x15ac, 0xd00d,
-0xb774, 0xbaff, 0xded3, 0xe41e, 0xf945, 0x331e, 0x49b7, 0x3276, 0x128d, 0x28c7,
-0x08f2, 0xce8e, 0xbb2e, 0xb907, 0xe4c0, 0xe9f8, 0xf98a, 0x3323, 0x4a75, 0x2718,
-0x0ddc, 0x3369, 0x0795, 0xc936, 0xc192, 0xc3cc, 0xe2b9, 0xe583, 0xfce9, 0x312f,
-0x4951, 0x266f, 0x0ffe, 0x3698, 0x0679, 0xca63, 0xc301, 0xc844, 0xde4c, 0xe26e,
-0x076e, 0x3283, 0x4507, 0x259a, 0x11af, 0x30ff, 0xfd1c, 0xc1b2, 0xb384, 0xc924,
-0xe414, 0xde8f, 0x0781, 0x295f, 0x51b4, 0x5b09, 0x17c9, 0xf17b, 0xd9cd, 0xb11a,
-0x8396, 0xbd98, 0x073f, 0x0598, 0x5258, 0x7bf8, 0x3dd3, 0x096d, 0xe7f8, 0xa966,
-0x9271, 0xc3c7, 0xb173, 0xf5d9, 0x6db2, 0x3b89, 0x2231, 0x4aaf, 0x1c3b, 0xc115,
-0xcb06, 0xd460, 0xbb98, 0x03f6, 0xf9d7, 0xecaf, 0x4aa5, 0x27cf, 0xcf8c, 0x0764,
-0x3489, 0xd9cb, 0xf31b, 0x39b5, 0xebc3, 0xeb7f, 0x1192, 0xceee, 0xbd72, 0x16f9,
-0x1b5a, 0xf888, 0x4a44, 0x34a8, 0xedd8, 0x18bb, 0xf8d6, 0xa74c, 0xd19c, 0x139c,
-0xeaf7, 0x0d0b, 0x5317, 0x0e81, 0x0c44, 0x35bd, 0xe010, 0xb51d, 0x075b, 0xfc77,
-0xc9ae, 0x2b95, 0x35a1, 0xf0e8, 0x2c61, 0x2481, 0xc370, 0xe826, 0x20b5, 0xd95a,
-0xf832, 0x43e0, 0xf261, 0xf7ef, 0x414e, 0xf14b, 0xbf9e, 0x1c6c, 0x1380, 0xd3d1,
-0x2650, 0x1f52, 0xd592, 0x1ddb, 0x2414, 0xc347, 0xebd1, 0x3e70, 0xf240, 0xeb89,
-0x3d66, 0xf738, 0xe57b, 0x2fe8, 0xf22d, 0xbd68, 0x1e7b, 0x2466, 0xd858, 0x2613,
-0x3122, 0xdc86, 0x16b9, 0x277b, 0xc324, 0xdb13, 0x2c78, 0xe8ab, 0xed0b, 0x49bb,
-0x0342, 0xf02a, 0x3b6c, 0xf7d9, 0xb9c6, 0x0fd8, 0x1192, 0xc763, 0x12e5, 0x2738,
-0xe26c, 0x1a89, 0x2a72, 0xcd72, 0xdca7, 0x27a9, 0xe962, 0xd98a, 0x271e, 0xf948,
-0xe783, 0x29f0, 0x000e, 0xc137, 0x064c, 0x17e6, 0xcd48, 0x0efb, 0x329b, 0xdc50,
-0xf9d6, 0x28fd, 0xd866, 0xc34b, 0x13df, 0xefa3, 0xdcbf, 0x3578, 0x09a7, 0xe33f,
-0x2c3f, 0x02a6, 0xaa76, 0xf3eb, 0x1870, 0xc21d, 0x029e, 0x3d07, 0xedbb, 0x0a92,
-0x33dc, 0xd94f, 0xc985, 0x15a5, 0xdf1c, 0xd3f5, 0x3f5e, 0x0fca, 0xe50f, 0x3b04,
-0x1a3d, 0xb99b, 0xf6d1, 0x1c75, 0xcc21, 0x0987, 0x3e95, 0xed51, 0x0dcf, 0x3b32,
-0xd980, 0xc6f7, 0x280e, 0xf587, 0xd3c2, 0x4871, 0x233c, 0xe02f, 0x3039, 0x183d,
-0xaecf, 0xf137, 0x2776, 0xcc66, 0x0bf0, 0x5162, 0xeddf, 0x088c, 0x4536, 0xd457,
-0xb205, 0x2315, 0xf51a, 0xc60d, 0x4281, 0x2682, 0xe5d9, 0x3aad, 0x1cab, 0xb02d,
-0xf294, 0x20af, 0xbecb, 0x0084, 0x4c16, 0xeaf2, 0x054e, 0x449f, 0xdf02, 0xbd48,
-0x25bf, 0xfda9, 0xcb15, 0x3a93, 0x1e9b, 0xddd4, 0x3408, 0x1f70, 0xb333, 0xf3df,
-0x32ab, 0xd133, 0x014e, 0x52b2, 0xf138, 0xfe00, 0x4260, 0xe1f2, 0xbbac, 0x28bf,
-0x0404, 0xcc81, 0x4649, 0x2e56, 0xdee8, 0x3677, 0x23ef, 0xabc0, 0xea62, 0x3159,
-0xcf59, 0xfdcf, 0x575a, 0xf403, 0xfe40, 0x4759, 0xe094, 0xb225, 0x1ffa, 0xfefc,
-0xc26f, 0x3a61, 0x2be1, 0xdb44, 0x2efe, 0x2504, 0xadcb, 0xe074, 0x2713, 0xc6d3,
-0xecc2, 0x48d6, 0xea4d, 0xf2ec, 0x43a0, 0xe1fc, 0xaa5f, 0x1825, 0xffd7, 0xba38,
-0x2bdb, 0x24a3, 0xce10, 0x1cd8, 0x1cfc, 0xab2e, 0xdc4d, 0x276d, 0xca22, 0xeb01,
-0x4a08, 0xeb0e, 0xe94c, 0x3cd7, 0xe45f, 0xa6c6, 0x0f8c, 0x066f, 0xc2d2, 0x2a01,
-0x2aea, 0xd9bf, 0x251a, 0x2933, 0xb64d, 0xd9b5, 0x26a1, 0xd2ba, 0xe822, 0x4af1,
-0xfec7, 0xf323, 0x3fdf, 0xf78e, 0xb4c1, 0x0f7f, 0x0e1c, 0xc7ce, 0x25fb, 0x3129,
-0xdeb5, 0x2268, 0x3385, 0xc266, 0xd9b6, 0x2efc, 0xddb0, 0xe00f, 0x45ac, 0x0168,
-0xea8d, 0x3cd9, 0xfeda, 0xb603, 0x13c5, 0x166b, 0xc192, 0x1f5a, 0x3804, 0xda94,
-0x15a3, 0x35b3, 0xc729, 0xd3ae, 0x2e68, 0xe359, 0xde70, 0x4764, 0x0725, 0xe6b1,
-0x3882, 0xfed4, 0xad23, 0x0819, 0x16c2, 0xc15b, 0x1c91, 0x4358, 0xe49c, 0x1162,
-0x35d1, 0xc8f8, 0xc74f, 0x2676, 0xe0e9, 0xd0d7, 0x4b09, 0x1cea, 0xedea, 0x3f3b,
-0x11f4, 0xb09a, 0xfc73, 0x177b, 0xba40, 0x109f, 0x4fcb, 0xf285, 0x1d0f, 0x3dc2,
-0xc588, 0xc98d, 0x329a, 0xfd8a, 0xcc33, 0x1573, 0x1810, 0x1532, 0x434e, 0x102d,
-0xd555, 0x08d4, 0x0011, 0xb77c, 0xec37, 0x098c, 0xd4fc, 0x2033, 0x7926, 0x32be,
-0xfe95, 0x28ab, 0xef9c, 0xa428, 0xcffc, 0xcbdf, 0xd07c, 0x3681, 0x2f87, 0x0680,
-0x626e, 0x5e9c, 0xd624, 0xd9e4, 0x080a, 0xadfe, 0xa2f5, 0x12af, 0x142c, 0xffde,
-0x3703, 0x3570, 0x269e, 0x24fb, 0xe8a1, 0xb7ec, 0xe753, 0xf82a, 0xce4d, 0x001a,
-0x2e98, 0x1f84, 0x0eb8, 0x1beb, 0x2603, 0xfcff, 0xfd98, 0xd8c0, 0xc719, 0xfc52,
-0xddd2, 0xe3ec, 0x2ee0, 0x4393, 0x042b, 0x1929, 0x569a, 0xef83, 0xc35d, 0xd9e5,
-0xc6ce, 0xd1e0, 0xed86, 0x0b2a, 0x23b2, 0x504c, 0x20ad, 0x029d, 0x3b72, 0xf5a5,
-0xad6b, 0xbe54, 0xddfc, 0xd162, 0xddcd, 0x2952, 0x324b, 0x3156, 0x1d3f, 0x12f5,
-0x235b, 0xf27f, 0xc001, 0xb250, 0xdfdd, 0xe3f3, 0xd455, 0x14e4, 0x3c06, 0x3326,
-0x1a60, 0x30e7, 0x24a0, 0xe2c3, 0xcd08, 0xb21c, 0xc75c, 0xdc66, 0xe088, 0x1e09,
-0x54ef, 0x4197, 0x0dca, 0x356f, 0x22ce, 0xcaf2, 0xc0ce, 0xbc3d, 0xcfda, 0xe59b,
-0xfe5c, 0x27b1, 0x4caa, 0x45a1, 0x0add, 0x274f, 0x1c6c, 0xcde6, 0xc343, 0xd011,
-0xdf48, 0xe021, 0x0b0c, 0x335a, 0x3c8e, 0x345d, 0x0d86, 0x278e, 0x1b8f, 0xdc12,
-0xbc28, 0xc6ff, 0xead3, 0xdba0, 0xfdee, 0x39b8, 0x3f03, 0x2143, 0x1858, 0x376b,
-0x021b, 0xcaa8, 0xbb59, 0xc6f6, 0xef67, 0xe041, 0xf9ba, 0x3cd7, 0x4cfd, 0x168d,
-0x1037, 0x3fec, 0xf71d, 0xbed3, 0xc8d6, 0xcbc6, 0xdd8f, 0xea8c, 0x09b1, 0x2e92,
-0x4701, 0x1829, 0x091c, 0x3ad7, 0xfd4b, 0xb999, 0xbe68, 0xdc50, 0xdc39, 0xd663,
-0x1009, 0x330e, 0x37f3, 0x1ad3, 0x1cca, 0x3476, 0xf66a, 0xc5e8, 0xbb6f, 0xd5e8,
-0xe008, 0xd5ea, 0x10b5, 0x3f63, 0x3725, 0x1102, 0x2911, 0x3855, 0xe9cb, 0xc610,
-0xc44b, 0xd547, 0xdd89, 0xe4aa, 0x195d, 0x4084, 0x3d9b, 0x10ab, 0x2a1f, 0x3667,
-0xe38c, 0xc1a0, 0xc4c5, 0xdd94, 0xe21b, 0xe99c, 0x1f49, 0x4312, 0x3b69, 0x0f14,
-0x2b3d, 0x2eaa, 0xdeab, 0xc00a, 0xc634, 0xe225, 0xe0e3, 0xf311, 0x2b9a, 0x44fd,
-0x3881, 0x11ee, 0x2f2a, 0x2428, 0xdc87, 0xc347, 0xc2d0, 0xe6e0, 0xe5b0, 0xf196,
-0x2d4e, 0x4a97, 0x3366, 0x1388, 0x3ae0, 0x1bf8, 0xd058, 0xc212, 0xc09b, 0xdbf3,
-0xe25c, 0xfa1f, 0x3093, 0x4e94, 0x31f0, 0x12fe, 0x3bde, 0x11ad, 0xc841, 0xb8bd,
-0xbe0b, 0xdd25, 0xdd7e, 0x0138, 0x3ac9, 0x4ccb, 0x2ba2, 0x1359, 0x3033, 0xfbc6,
-0xc14d, 0xb543, 0xbd7e, 0xdcf8, 0xde2b, 0x0754, 0x388b, 0x409a, 0x1e0d, 0x134a,
-0x2ba8, 0xeee4, 0xbe5b, 0xafaf, 0xbb90, 0xe059, 0xde74, 0x0736, 0x3d1c, 0x4310,
-0x16f1, 0x1686, 0x2f2a, 0xe9de, 0xbe17, 0xb446, 0xc0ca, 0xdd27, 0xe1a0, 0x0ccd,
-0x3c13, 0x4661, 0x1949, 0x196a, 0x2a50, 0xdf8d, 0xb6a7, 0xb25a, 0xc8aa, 0xdf0e,
-0xe6dc, 0x19c8, 0x411d, 0x423f, 0x15db, 0x1a0d, 0x2316, 0xdf69, 0xba97, 0xb2a9,
-0xd092, 0xe29a, 0xebf2, 0x2556, 0x4a3b, 0x3fb1, 0x16cb, 0x2603, 0x1c1b, 0xd67d,
-0xbcf3, 0xb765, 0xdad1, 0xea4b, 0xf176, 0x27e4, 0x4d31, 0x3b4c, 0x0fab, 0x2ad5,
-0x1a4d, 0xd10b, 0xbc49, 0xba78, 0xda1f, 0xe903, 0xffda, 0x308c, 0x4a2f, 0x38ce,
-0x11cc, 0x299c, 0x105c, 0xcdc3, 0xba31, 0xc03e, 0xe616, 0xe849, 0xfec7, 0x37e1,
-0x4e98, 0x3198, 0x12d8, 0x2aeb, 0x03e5, 0xcb29, 0xbccb, 0xc232, 0xe734, 0xeb9c,
-0x07ed, 0x3d12, 0x4b48, 0x2515, 0x14e8, 0x330c, 0xfd19, 0xc86d, 0xc241, 0xca17,
-0xe64b, 0xe918, 0x09ed, 0x3ba3, 0x4eee, 0x25e2, 0x167a, 0x38a6, 0xffcf, 0xcb0e,
-0xc615, 0xd055, 0xe3d3, 0xeafc, 0x1602, 0x3e86, 0x49c2, 0x257e, 0x2166, 0x3bcd,
-0xfc55, 0xc4ad, 0xbb87, 0xd6e3, 0xe7a1, 0xe64f, 0x1ddd, 0x4682, 0x4516, 0x1dee,
-0x1dc5, 0x2b0d, 0xed86, 0xc590, 0xb97d, 0xd84f, 0xec06, 0xe368, 0x1c7f, 0x4cee,
-0x3f07, 0x13c3, 0x289d, 0x28fb, 0xdcf0, 0xc5b7, 0xbdb7, 0xd4a7, 0xec46, 0xecd0,
-0x1bda, 0x48cc, 0x4019, 0x0cd7, 0x23a7, 0x2698, 0xd5be, 0xbc3e, 0xb90e, 0xcc6c,
-0xddf3, 0xf12b, 0x24f1, 0x4448, 0x3b5c, 0x118e, 0x2441, 0x1c2b, 0xd270, 0xb368,
-0xb6c7, 0xdd46, 0xdf51, 0xefbb, 0x3138, 0x49d2, 0x3667, 0x1864, 0x2b86, 0x1073,
-0xd35e, 0xbbf4, 0xb47a, 0xdfb4, 0xe8bb, 0xf6b2, 0x353a, 0x4fd4, 0x2e9f, 0x12a8,
-0x323d, 0x07c8, 0xcb04, 0xc1fa, 0xbd57, 0xdf17, 0xe6e8, 0xfa82, 0x3052, 0x4c63,
-0x2d83, 0x12bf, 0x3366, 0x0318, 0xc6dd, 0xbd85, 0xbc4f, 0xd9e1, 0xe604, 0x0814,
-0x34df, 0x4a09, 0x2d9d, 0x148f, 0x2e79, 0xfba1, 0xc12c, 0xb277, 0xbf95, 0xdeb7,
-0xe211, 0x10bc, 0x423c, 0x4956, 0x24f7, 0x1571, 0x2434, 0xebbb, 0xc333, 0xb587,
-0xc733, 0xedc0, 0xebba, 0x0854, 0x3f2e, 0x6f7e, 0x4a81, 0x0e5e, 0x03fe, 0xcb43,
-0xa313, 0xa8c3, 0xd5fe, 0x0fe0, 0x3ce3, 0x6922, 0x5cb3, 0x4541, 0x10b8, 0xc5c1,
-0xb7c8, 0xca44, 0xca38, 0xd7f7, 0x38e7, 0x4e53, 0x1cb5, 0x3dfb, 0x3d19, 0x06ab,
-0xeda0, 0xe9ef, 0xd83d, 0xf9bf, 0x0ebe, 0xca2a, 0x0a79, 0x510e, 0xf01d, 0xe7eb,
-0x3be6, 0x1a2e, 0xf989, 0x353e, 0x099c, 0xe538, 0x16d7, 0xd697, 0xa93c, 0x0407,
-0x1bee, 0xf75f, 0x46c6, 0x50e3, 0xf430, 0x1813, 0x169b, 0xaf5d, 0xc57c, 0x0fb5,
-0xe638, 0xf7e9, 0x459c, 0x122e, 0x0654, 0x352e, 0xfc93, 0xc262, 0xf99c, 0x072c,
-0xc8f1, 0x0bf2, 0x32cd, 0xf85b, 0x1790, 0x25c1, 0xde96, 0xd882, 0x18ea, 0xe834,
-0xd77c, 0x3995, 0x1231, 0xeab1, 0x28e3, 0x0cfc, 0xc5ef, 0xf7bd, 0x18f1, 0xd03e,
-0x057e, 0x320a, 0xe5e4, 0x07c7, 0x2d5d, 0xd88a, 0xc884, 0x2072, 0xfd6c, 0xd3d0,
-0x2a59, 0x1066, 0xe564, 0x22a2, 0x047a, 0xb2ee, 0xeaad, 0x1c28, 0xcc6c, 0xf7e5,
-0x3c36, 0xee88, 0xfbfb, 0x3085, 0xddf6, 0xb28a, 0x0aaf, 0xf456, 0xbc45, 0x223a,
-0x21ed, 0xe31c, 0x2214, 0x1882, 0xb51a, 0xdbdc, 0x18ba, 0xc1ce, 0xe1c3, 0x397c,
-0xed39, 0xf426, 0x3690, 0xe68c, 0xb498, 0x0e83, 0x00c5, 0xc494, 0x1ef7, 0x1b31,
-0xdc33, 0x1f84, 0x1b7f, 0xb9c1, 0xdc07, 0x2246, 0xd5fb, 0xeaf7, 0x4a41, 0x042a,
-0xed8c, 0x29a9, 0xf4c4, 0xbbf5, 0xffbd, 0x02b3, 0xd089, 0x2a98, 0x349a, 0xe5f4,
-0x231d, 0x3682, 0xc042, 0xc757, 0x28ee, 0xe56b, 0xda47, 0x3eac, 0x0d7c, 0xfc17,
-0x4512, 0x05d1, 0xbb63, 0x0fc8, 0x0da5, 0xb98f, 0x1ecc, 0x3aea, 0xdbbd, 0x1bd6,
-0x4041, 0xd007, 0xd35e, 0x2aaf, 0xea38, 0xe711, 0x3e4a, 0xfa47, 0xef65, 0x3f02,
-0xf730, 0xae98, 0x0fae, 0x1e19, 0xc953, 0x1ea3, 0x3db2, 0xe20d, 0x1043, 0x2d87,
-0xc8ab, 0xca8a, 0x2270, 0xe769, 0xe021, 0x4751, 0x0a42, 0xed5b, 0x468e, 0x0a0e,
-0xa823, 0xfc1e, 0x19ce, 0xc19e, 0x0fd8, 0x3c33, 0xe854, 0x1d91, 0x3f3f, 0xd03c,
-0xd290, 0x2d60, 0xe292, 0xd443, 0x4229, 0x0590, 0xe446, 0x3c78, 0x0d2e, 0xbba0,
-0x0b10, 0x1fdc, 0xccc6, 0x142f, 0x3174, 0xdc18, 0x1061, 0x371b, 0xd368, 0xd200,
-0x2d59, 0xf1a5, 0xdc23, 0x3edd, 0x0fb6, 0xe812, 0x2f6f, 0x0a77, 0xb941, 0xfe00,
-0x1d36, 0xcc9c, 0x11f2, 0x404a, 0xe70a, 0x0abc, 0x3965, 0xd3be, 0xbed2, 0x1fe7,
-0xee09, 0xd03e, 0x3f07, 0x1799, 0xe33b, 0x342f, 0x1443, 0xb44b, 0xf906, 0x1979,
-0xbeaf, 0x0a9f, 0x45b3, 0xe73c, 0x0a6f, 0x3e78, 0xd655, 0xc03d, 0x2087, 0xeb0b,
-0xcf7a, 0x4395, 0x1915, 0xe1a6, 0x34d0, 0x134e, 0xac96, 0xeeeb, 0x1aa0, 0xc459,
-0x0965, 0x4852, 0xe8bd, 0x0151, 0x3569, 0xd16f, 0xb855, 0x1c6f, 0xed54, 0xcabb,
-0x428e, 0x1dfb, 0xdf3c, 0x323b, 0x15f0, 0xab84, 0xe597, 0x18a2, 0xc34f, 0x0120,
-0x48dd, 0xedf1, 0x07d1, 0x3f6b, 0xd521, 0xb0ac, 0x1903, 0xf0c7, 0xc122, 0x3959,
-0x22ad, 0xe010, 0x2ec7, 0x1837, 0xaaf6, 0xe170, 0x1e2b, 0xc7b9, 0xfdb5, 0x4c53,
-0xebef, 0xfb34, 0x3ee4, 0xdef9, 0xb297, 0x1b34, 0xfd76, 0xc42a, 0x391e, 0x2b29,
-0xde3f, 0x2dc8, 0x2491, 0xb2a5, 0xe544, 0x2b06, 0xcad8, 0xf507, 0x54ba, 0xf673,
-0xfa92, 0x48ca, 0xe9a8, 0xafd3, 0x1ef7, 0x084a, 0xc383, 0x3a6e, 0x3354, 0xdbff,
-0x2c3f, 0x2b2a, 0xb115, 0xe1c4, 0x348d, 0xd2d5, 0xf3b1, 0x5801, 0xf84b, 0xf5dc,
-0x4897, 0xeba9, 0xac5a, 0x1d11, 0x0bb4, 0xbcd7, 0x32ed, 0x3809, 0xdc0a, 0x2aa8,
-0x3035, 0xb63c, 0xddf9, 0x3359, 0xe1e6, 0xdc8c, 0x1666, 0xf007, 0x2428, 0x5dbe,
-0x00c2, 0xd781, 0x22f0, 0xf405, 0xa1af, 0xed74, 0xf64b, 0xd808, 0x304e, 0x5c2f,
-0x2e87, 0x2aaf, 0x32b5, 0xdc5e, 0xbf90, 0xd852, 0xad5b, 0xdde3, 0x38e2, 0x1923,
-0x04d1, 0x62c4, 0x5bb8, 0xe529, 0xeaaf, 0xfd61, 0xc422, 0xc0df, 0xfa6b, 0x0d7b,
-0x16ff, 0x3f3e, 0x1d78, 0x1a46, 0x3b1d, 0xf55f, 0xc829, 0xeeb5, 0x0157, 0xdd55,
-0xf41a, 0x20b5, 0x1533, 0x2329, 0x1f7c, 0x1523, 0x1e43, 0x1419, 0xdc00, 0xbfc2,
-0xfbcf, 0xe187, 0xd1ef, 0x2a18, 0x3c8b, 0x1862, 0x2179, 0x4380, 0x06a1, 0xdc67,
-0xe0e4, 0xb854, 0xda4e, 0xf2b5, 0xe744, 0x1f54, 0x57ea, 0x2932, 0xfa55, 0x3961,
-0x0fd9, 0xbac6, 0xcdda, 0xd258, 0xcf89, 0xe3ab, 0x0707, 0x1a3e, 0x3967, 0x30cc,
-0x0264, 0x2d4f, 0x1e6c, 0xcc01, 0xb70b, 0xd1c4, 0xdac0, 0xca7b, 0xfba8, 0x26c2,
-0x371b, 0x359b, 0x23c6, 0x2fb4, 0x0da1, 0xd9bd, 0xae9d, 0xb89c, 0xdb61, 0xcb90,
-0x0132, 0x482d, 0x42cd, 0x1e49, 0x2e1f, 0x3691, 0xe7fa, 0xc93c, 0xba66, 0xbb0a,
-0xe251, 0xe472, 0x0383, 0x3f08, 0x4cc8, 0x1215, 0x1c80, 0x3b71, 0xe4f3, 0xc431,
-0xcbb0, 0xc403, 0xd2f9, 0xf12b, 0x1313, 0x2f50, 0x4774, 0x1313, 0x18c4, 0x4058,
-0xed5d, 0xb643, 0xc25a, 0xd92a, 0xcdc3, 0xe267, 0x25f0, 0x37bf, 0x38e3, 0x1db0,
-0x2909, 0x2dab, 0xe635, 0xb3fb, 0xb52f, 0xe71a, 0xdad1, 0xdbe5, 0x2dd4, 0x4a45,
-0x2f11, 0x15fc, 0x375b, 0x1edc, 0xd95e, 0xc7dd, 0xb91d, 0xdb9a, 0xe8d2, 0xea7d,
-0x243c, 0x50aa, 0x347a, 0x0b10, 0x3f2c, 0x24ae, 0xc984, 0xc48d, 0xccec, 0xd726,
-0xda77, 0xf845, 0x2782, 0x491b, 0x3bb7, 0x1233, 0x3698, 0x200c, 0xcd29, 0xb25f,
-0xc2ef, 0xdd85, 0xd457, 0xfe96, 0x3830, 0x43f0, 0x2e94, 0x1a60, 0x3369, 0x07e9,
-0xcb4f, 0xb645, 0xba73, 0xdbb8, 0xdb8f, 0xffae, 0x3a33, 0x48d7, 0x2211, 0x15da,
-0x362f, 0xfbd5, 0xc39a, 0xb7fb, 0xc2cf, 0xe1cd, 0xe2d2, 0x0604, 0x36c9, 0x495d,
-0x209d, 0x15d2, 0x37e6, 0xf91a, 0xc431, 0xbe00, 0xccf7, 0xe3be, 0xe90a, 0x14f8,
-0x3bed, 0x4775, 0x22c5, 0x1a55, 0x2eb8, 0xf7ab, 0xcbee, 0xbb0a, 0xd4b7, 0xea3e,
-0xe43a, 0x18fd, 0x455e, 0x429e, 0x1d75, 0x27b4, 0x2e04, 0xeadd, 0xca0c, 0xb834,
-0xcf7e, 0xebe8, 0xec12, 0x1d2b, 0x4ce6, 0x4388, 0x1410, 0x2882, 0x2863, 0xdbfa,
-0xc201, 0xbc64, 0xd1a8, 0xe40d, 0xf23c, 0x21f6, 0x44ac, 0x3ed5, 0x105b, 0x1f33,
-0x1ab9, 0xd393, 0xb879, 0xb8a2, 0xd559, 0xdf87, 0xf31b, 0x2555, 0x3b7c, 0x3066,
-0x0f9b, 0x206c, 0x1043, 0xd352, 0xb6fe, 0xb4ae, 0xdacb, 0xdd79, 0xed28, 0x2944,
-0x40cc, 0x26e3, 0x1073, 0x2c6d, 0x0a8e, 0xd1fe, 0xbe7c, 0xb79c, 0xdbb0, 0xe28f,
-0xf1b8, 0x2782, 0x45d6, 0x288a, 0x146e, 0x3752, 0x08d7, 0xccea, 0xc003, 0xbd89,
-0xda98, 0xe4f4, 0x0193, 0x3341, 0x4c65, 0x29eb, 0x1665, 0x385c, 0x0502, 0xcaf3,
-0xbfdd, 0xc859, 0xe1b4, 0xe85f, 0x0f40, 0x394b, 0x49b1, 0x2907, 0x1adb, 0x324c,
-0xf922, 0xc6e9, 0xb961, 0xcbdd, 0xe7b2, 0xe6bd, 0x11f6, 0x3fef, 0x46fb, 0x1df6,
-0x1d0f, 0x2f40, 0xeef5, 0xc4a6, 0xb575, 0xcb9f, 0xe637, 0xea22, 0x1afc, 0x450f,
-0x486c, 0x1ca2, 0x2081, 0x27c1, 0xe170, 0xbe81, 0xb610, 0xd4bd, 0xe951, 0xed82,
-0x22d8, 0x4920, 0x44fd, 0x1967, 0x24be, 0x230d, 0xdd5b, 0xbd48, 0xb2b2, 0xd74f,
-0xebd6, 0xf51e, 0x2d0e, 0x4f15, 0x406d, 0x18ea, 0x2d32, 0x1b37, 0xd68b, 0xc044,
-0xb935, 0xdd2b, 0xe8ca, 0xf474, 0x309b, 0x54b6, 0x3c42, 0x14ba, 0x347b, 0x1910,
-0xd0a8, 0xbcba, 0xb8c9, 0xdc46, 0xe9fe, 0xfff4, 0x3532, 0x5389, 0x3988, 0x14af,
-0x3504, 0x102d, 0xc848, 0xb929, 0xbe6f, 0xdd0e, 0xe430, 0x059c, 0x3ba7, 0x4f58,
-0x2e33, 0x10f0, 0x2a2f, 0xfdb9, 0xc2f6, 0xafbb, 0xbb99, 0xe4f6, 0xe5f2, 0x07f0,
-0x3ce6, 0x4606, 0x2206, 0x1803, 0x2b80, 0xee52, 0xc24f, 0xb46d, 0xbb4a, 0xe32e,
-0xe633, 0x0953, 0x4238, 0x4b00, 0x1a28, 0x1723, 0x280d, 0xe191, 0xbf29, 0xb512,
-0xbb95, 0xe083, 0xee77, 0x11e1, 0x3d02, 0x4905, 0x18fb, 0x175c, 0x25d3, 0xdaba,
-0xb4bd, 0xb51c, 0xcc2b, 0xe1c5, 0xed1f, 0x1d15, 0x42ae, 0x42e0, 0x12aa, 0x15c7,
-0x1ce6, 0xdd86, 0xbb2e, 0xb339, 0xd4c6, 0xe6a3, 0xee5c, 0x246d, 0x4599, 0x378a,
-0x117f, 0x247f, 0x1587, 0xd40f, 0xc211, 0xba12, 0xda04, 0xe9d2, 0xf097, 0x2593,
-0x4a0d, 0x33f2, 0x0e58, 0x2f92, 0x1796, 0xd23e, 0xc5d1, 0xbd1d, 0xd6a8, 0xea03,
-0xfd4b, 0x2b76, 0x4d07, 0x372b, 0x12c1, 0x3610, 0x1455, 0xc9fa, 0xc082, 0xc65f,
-0xdbf3, 0xe5fa, 0x0864, 0x3695, 0x4d6d, 0x3441, 0x13be, 0x2f2f, 0x090c, 0xce34,
-0xb830, 0xc505, 0xfada, 0xec81, 0xfb68, 0x2eba, 0x319e, 0x3ce2, 0x44fb, 0x1d01,
-0xdd9d, 0xd66a, 0xb232, 0xa016, 0xf64b, 0xfff6, 0x09d5, 0x7376, 0x8570, 0x20f6,
-0xfe82, 0xf200, 0x9a52, 0xa325, 0xc4f5, 0xcbde, 0x2c79, 0x67bb, 0x4c8f, 0x46a8,
-0x523c, 0xf79d, 0xabd0, 0xda12, 0xcc15, 0xb71c, 0xf62d, 0x1e60, 0x327a, 0x4b18,
-0x2770, 0xf598, 0x157f, 0x094e, 0xbe89, 0xebf7, 0x2a77, 0xf098, 0xe9ee, 0x28e2,
-0xf32a, 0xc056, 0x237c, 0x271d, 0xe4a4, 0x3978, 0x35ba, 0xe536, 0x10f5, 0xfdaa,
-0xa68b, 0xd3ea, 0x212f, 0xea07, 0x08a6, 0x5e96, 0x0ae2, 0x07c6, 0x37b6, 0xd70c,
-0xb092, 0xfe7d, 0xf21a, 0xcad9, 0x34d2, 0x36e9, 0xf083, 0x37da, 0x22a5, 0xbc01,
-0xdc00, 0x1395, 0xd553, 0xe5e3, 0x3bac, 0xfd08, 0xfe92, 0x3f5c, 0xee23, 0xbc45,
-0x0d39, 0x0a9c, 0xc61a, 0x146f, 0x2951, 0xdb39, 0x171e, 0x293d, 0xc2e7, 0xdd20,
-0x32b9, 0xe330, 0xd7b9, 0x3cc5, 0xf7d9, 0xdcad, 0x311b, 0xf1df, 0xb0b8, 0x105b,
-0x1a8c, 0xca51, 0x1be5, 0x2f80, 0xd616, 0x11ca, 0x2652, 0xbc4e, 0xcb96, 0x21a7,
-0xe4b4, 0xe253, 0x4487, 0x0196, 0xe674, 0x3516, 0xfb04, 0xb3bc, 0xfeb8, 0x1079,
-0xc24e, 0x088e, 0x3298, 0xe80b, 0x14c1, 0x2ed3, 0xd1a8, 0xcf82, 0x2207, 0xee50,
-0xcf02, 0x2dec, 0x08af, 0xe42a, 0x344d, 0x0fb2, 0xb971, 0xfa3f, 0x1df7, 0xd32e,
-0x11cc, 0x3722, 0xda30, 0x07ac, 0x3d3f, 0xd7ab, 0xc34d, 0x271b, 0xfe76, 0xdbb3,
-0x3d61, 0x18ed, 0xed9b, 0x3389, 0x0c14, 0xba7c, 0xf987, 0x187e, 0xcd50, 0x1066,
-0x476b, 0xf480, 0x1314, 0x42bb, 0xe5fe, 0xc3be, 0x1389, 0xf39f, 0xd575, 0x3648,
-0x1e47, 0xf2fa, 0x3e74, 0x234a, 0xbf4c, 0xf288, 0x221b, 0xc710, 0xfa3c, 0x5035,
-0xfb9e, 0x0502, 0x44eb, 0xeee6, 0xc43e, 0x1d61, 0xfb1c, 0xc9de, 0x3c74, 0x2aae,
-0xe190, 0x3674, 0x2619, 0xaff2, 0xe8b6, 0x2937, 0xc78c, 0xf5df, 0x540b, 0xfb05,
-0x020b, 0x434b, 0xe0e6, 0xacc1, 0x10fc, 0xf91d, 0xbcee, 0x3592, 0x3566, 0xe36e,
-0x337d, 0x30bf, 0xb32f, 0xd426, 0x2162, 0xc820, 0xe042, 0x4c56, 0xfe46, 0xf61f,
-0x4a89, 0xf803, 0xad4d, 0x11a6, 0x0a6c, 0xb6d1, 0x253a, 0x3311, 0xd5a0, 0x2667,
-0x3498, 0xb800, 0xd872, 0x2f83, 0xd41e, 0xe4e1, 0x5463, 0xf738, 0xea30, 0x492c,
-0xf007, 0xaab2, 0x16ec, 0x11da, 0xc262, 0x2e37, 0x3e3b, 0xdd03, 0x22dd, 0x30e8,
-0xb674, 0xd170, 0x2e2c, 0xdcd6, 0xe399, 0x56b9, 0x04f1, 0xea52, 0x4a44, 0xfd31,
-0xa60d, 0x09bf, 0x162d, 0xbcc9, 0x1f55, 0x4352, 0xde68, 0x1cd9, 0x3c0d, 0xbf98,
-0xc8d8, 0x2a1f, 0xdc64, 0xd503, 0x4d6c, 0x0785, 0xe7a8, 0x476e, 0xff01, 0xa5cd,
-0x064f, 0x17bf, 0xbe55, 0x1800, 0x3b7b, 0xd4d9, 0x10f0, 0x3690, 0xbf8d, 0xc71e,
-0x297a, 0xe393, 0xd729, 0x47fe, 0x0285, 0xda51, 0x391b, 0xfeb3, 0xa48e, 0xfbc3,
-0x19a9, 0xc3a0, 0x108e, 0x3eae, 0xdebc, 0x0f12, 0x36a2, 0xc4c0, 0xbf91, 0x1e2f,
-0xe5de, 0xd395, 0x4354, 0x10d5, 0xe319, 0x39c0, 0x0a87, 0xace4, 0xf7d2, 0x18b7,
-0xc582, 0x0b6f, 0x3da5, 0xe290, 0x0dde, 0x3c3e, 0xcfe6, 0xc55b, 0x253d, 0xeca1,
-0xcf94, 0x3b7a, 0x0f41, 0xdf74, 0x366b, 0x1370, 0xb644, 0xfb14, 0x1f1e, 0xc7c9,
-0x07b4, 0x41e9, 0xe70d, 0x071d, 0x3d77, 0xdb66, 0xc478, 0x265f, 0xf916, 0xd180,
-0x3ee6, 0x1beb, 0xdeb9, 0x31d9, 0x191a, 0xb479, 0xf52c, 0x2801, 0xccf7, 0x03d4,
-0x4bd7, 0xedac, 0x016a, 0x3a65, 0xd6fc, 0xbe27, 0x2266, 0x07f4, 0xd0c6, 0x0dcf,
-0x1281, 0x0eb0, 0x45e8, 0x1d9a, 0xd8e3, 0x05c1, 0x084a, 0xb5be, 0xdaec, 0x09a2,
-0xe1b9, 0x11ee, 0x6086, 0x43d5, 0x17db, 0x2892, 0xfb50, 0xb60e, 0xc9f7, 0xc054,
-0xc68d, 0x23e0, 0x2ffe, 0x062b, 0x4e99, 0x701f, 0xf80e, 0xd329, 0xff2c, 0xcb90,
-0xa2d6, 0xed8c, 0x1910, 0x0699, 0x2f80, 0x3089, 0x1d1c, 0x374f, 0x03b2, 0xc14c,
-0xd8b6, 0xfb3d, 0xd617, 0xe1a7, 0x22a2, 0x2021, 0x1a55, 0x1dcb, 0x2025, 0x150c,
-0x0753, 0xe11c, 0xb5ad, 0xeb4f, 0xe450, 0xcc01, 0x1b1d, 0x3faa, 0x18aa, 0x0e6d,
-0x4970, 0x17e5, 0xcba3, 0xd80b, 0xbb23, 0xc5d9, 0xe755, 0xf01c, 0x158e, 0x5028,
-0x3e7d, 0xfcdb, 0x3482, 0x21eb, 0xbae5, 0xbfbe, 0xd2fb, 0xcfc4, 0xd821, 0x0aca,
-0x27bb, 0x3924, 0x3d1e, 0x0e86, 0x271a, 0x205b, 0xd16c, 0xaf53, 0xc9df, 0xe377,
-0xce6f, 0xfa21, 0x34f1, 0x4083, 0x3410, 0x259d, 0x319d, 0x06b6, 0xd9dc, 0xb750,
-0xb2df, 0xde42, 0xd8e4, 0xfe96, 0x4970, 0x54f6, 0x25ba, 0x2520, 0x3c2e, 0xedea,
-0xc061, 0xba0d, 0xba48, 0xde9c, 0xeb84, 0x0af2, 0x401e, 0x56b2, 0x1aa5, 0x0f66,
-0x36cf, 0xe844, 0xb80e, 0xc1dd, 0xc246, 0xcece, 0xe9fe, 0x177a, 0x32d2, 0x4547,
-0x1818, 0x0c52, 0x30b6, 0xec12, 0xaf1a, 0xb2f2, 0xcfa8, 0xd2b1, 0xdf9e, 0x2116,
-0x3ab2, 0x35ab, 0x1b48, 0x247c, 0x25e1, 0xdedd, 0xb1e5, 0xaf2b, 0xdb4a, 0xe17b,
-0xdfc7, 0x27da, 0x4f71, 0x34be, 0x0ed1, 0x2d58, 0x1ef5, 0xd091, 0xc1bb, 0xbe47,
-0xd524, 0xeaee, 0xf469, 0x2112, 0x4cf4, 0x3d3e, 0x0aff, 0x304c, 0x281a, 0xcdc7,
-0xbbed, 0xd088, 0xe04a, 0xdeea, 0xfee9, 0x2f94, 0x47fc, 0x3dff, 0x1a27, 0x31e9,
-0x1deb, 0xd894, 0xbec6, 0xc6e8, 0xe5fc, 0xe340, 0x014d, 0x3cd1, 0x4e2f, 0x32bd,
-0x1d0c, 0x372e, 0x0af1, 0xce88, 0xc502, 0xc97d, 0xe495, 0xeb9c, 0x0798, 0x374a,
-0x4e4d, 0x2a7e, 0x16b3, 0x3ddd, 0x08ed, 0xc949, 0xc5ee, 0xce08, 0xdf28, 0xe8b7,
-0x0fe9, 0x3689, 0x490a, 0x2817, 0x1714, 0x38c1, 0x0109, 0xc527, 0xc1af, 0xd087,
-0xdced, 0xe41e, 0x12dc, 0x3476, 0x3cd2, 0x201b, 0x1cbb, 0x2e40, 0xf269, 0xc5fe,
-0xb844, 0xcaac, 0xdf7f, 0xe02f, 0x0f09, 0x373a, 0x383b, 0x13eb, 0x21ef, 0x2cbc,
-0xe41a, 0xc568, 0xb82e, 0xc319, 0xdca2, 0xe63b, 0x0f93, 0x3ca2, 0x4202, 0x11af,
-0x2392, 0x2ac6, 0xd906, 0xb7d3, 0xb715, 0xce35, 0xdb89, 0xef49, 0x2213, 0x3ff6,
-0x3f4b, 0x14d9, 0x2398, 0x1f27, 0xd7ab, 0xb866, 0xb50a, 0xd74b, 0xe11e, 0xf58b,
-0x2ece, 0x467f, 0x3963, 0x1933, 0x2caa, 0x1426, 0xd5d8, 0xbe81, 0xb620, 0xdf76,
-0xe789, 0xf65e, 0x349f, 0x505c, 0x3366, 0x16ea, 0x3646, 0x0f5a, 0xd18a, 0xc1b2,
-0xb7f7, 0xdd2a, 0xeb2f, 0xfd79, 0x30f5, 0x516e, 0x31d6, 0x12af, 0x388a, 0x0be7,
-0xca82, 0xbdf0, 0xbc89, 0xda3c, 0xe687, 0x06e8, 0x3695, 0x5204, 0x3323, 0x158c,
-0x3447, 0x05f1, 0xca02, 0xb88d, 0xc1cf, 0xe381, 0xea5c, 0x110d, 0x40c6, 0x4e27,
-0x2a69, 0x1e8c, 0x30b5, 0xf349, 0xc5eb, 0xb6f0, 0xc440, 0xe7cd, 0xebf2, 0x1281,
-0x4308, 0x4ce7, 0x1f25, 0x1bf5, 0x2d5c, 0xe897, 0xc291, 0xb85f, 0xc6be, 0xe556,
-0xf257, 0x1cc0, 0x442d, 0x4d14, 0x200a, 0x1f36, 0x26a6, 0xdf96, 0xbef2, 0xb898,
-0xd0e1, 0xe9a1, 0xf513, 0x2536, 0x486a, 0x4666, 0x1bd4, 0x216e, 0x1a61, 0xd966,
-0xbfd6, 0xb46f, 0xd414, 0xeb0f, 0xf5c1, 0x2917, 0x4b03, 0x3b01, 0x120a, 0x279d,
-0x127b, 0xce60, 0xc0b2, 0xbaa1, 0xd93a, 0xea16, 0xf79d, 0x29e1, 0x4e28, 0x3952,
-0x0c9b, 0x2918, 0x0da3, 0xc8e3, 0xbf5d, 0xbd5b, 0xd7be, 0xe6b5, 0xff78, 0x2bfe,
-0x474e, 0x30ea, 0x0afb, 0x2996, 0x09da, 0xc618, 0xb66b, 0xc002, 0xde8f, 0xe009,
-0x0068, 0x34b1, 0x479e, 0x290d, 0x1057, 0x2cf4, 0x0037, 0xc901, 0xba19, 0xc161,
-0xe4c1, 0xe626, 0x06b7, 0x3bce, 0x46e6, 0x1fc6, 0x1c43, 0x37dd, 0xf4a3, 0xc6e9,
-0xc0da, 0xc57a, 0xe45d, 0xe96e, 0x0b68, 0x3e09, 0x4c53, 0x1c9e, 0x1978, 0x350c,
-0xec82, 0xc2fd, 0xc069, 0xc683, 0xdf64, 0xee42, 0x1619, 0x39da, 0x4685, 0x1dc8,
-0x1c78, 0x2de4, 0xe52f, 0xbb56, 0xb88c, 0xd10f, 0xe424, 0xed39, 0x226e, 0x45c9,
-0x4373, 0x1798, 0x1d16, 0x2213, 0xe050, 0xbf9c, 0xb315, 0xd32f, 0xe7c5, 0xec31,
-0x23d2, 0x48dd, 0x38f4, 0x0de0, 0x25fc, 0x1996, 0xcef8, 0xbc82, 0xb55a, 0xd59c,
-0xe89f, 0xefe0, 0x23a4, 0x4993, 0x37a4, 0x0c32, 0x2be5, 0x17d1, 0xcddd, 0xc07a,
-0xb8e9, 0xd329, 0xe54b, 0xfb4e, 0x2cfc, 0x4d3a, 0x3bad, 0x0fee, 0x2b2b, 0x1047,
-0xc712, 0xb4f7, 0xbbf0, 0xdc5f, 0xe2f3, 0xfef6, 0x224e, 0x4c36, 0x6c76, 0x2b5c,
-0xfa57, 0xe594, 0xbdb1, 0x8b0a, 0xa7ca, 0x0160, 0x0786, 0x400c, 0x8424, 0x5796,
-0x1be9, 0xf540, 0xbdf9, 0x9768, 0xc4df, 0xbd3d, 0xdd3d, 0x63d3, 0x4e65, 0x1fea,
-0x4e57, 0x38bb, 0xd91b, 0xcd56, 0xe3ad, 0xbffd, 0xfbd6, 0x0607, 0xdb8e, 0x3ccb,
-0x4192, 0xd6b0, 0xf73b, 0x42bf, 0xeff1, 0xe330, 0x3dbd, 0xfa84, 0xdccf, 0x13df,
-0xde74, 0xb718, 0x0b45, 0x28d2, 0xfb25, 0x3fa0, 0x4276, 0xedb2, 0x1335, 0x0954,
-0xadc9, 0xc6fc, 0x1522, 0xf53c, 0xfe45, 0x4b87, 0x18e7, 0x04a7, 0x3412, 0xee3f,
-0xb321, 0xfd48, 0x04c9, 0xc508, 0x15a8, 0x372c, 0xeb2f, 0x165c, 0x2ca0, 0xce55,
-0xd34d, 0x1c95, 0xe2fd, 0xdd7e, 0x3294, 0xf905, 0xe452, 0x34a4, 0x04d0, 0xbdd7,
-0x0a01, 0x1d14, 0xce45, 0x0c02, 0x2888, 0xd716, 0x03dc, 0x2b4a, 0xd5cd, 0xd68c,
-0x2ef2, 0xfc10, 0xda6f, 0x316f, 0x0773, 0xda8e, 0x2215, 0x0507, 0xb6f3, 0xfe70,
-0x2a5d, 0xd6c8, 0x0b84, 0x4188, 0xe8c4, 0xfdd0, 0x2ec5, 0xd794, 0xc3a2, 0x2279,
-0xf779, 0xd09d, 0x423d, 0x27fc, 0xe6f8, 0x2f40, 0x1b5a, 0xbc8b, 0xf157, 0x1fb4,
-0xcaa0, 0xfa3a, 0x4232, 0xf922, 0x0ecb, 0x3f09, 0xe3ee, 0xc318, 0x1cef, 0xfdc1,
-0xca4c, 0x2a22, 0x20f1, 0xe87d, 0x279c, 0x1afc, 0xbe72, 0xe720, 0x2220, 0xd1d4,
-0xf6a7, 0x4e3e, 0xf5f4, 0xecca, 0x3b54, 0xf567, 0xb06f, 0x0a45, 0x0b98, 0xc973,
-0x28f0, 0x2f21, 0xdfeb, 0x24a0, 0x2810, 0xaef4, 0xd207, 0x2ab3, 0xcd51, 0xdc82,
-0x4ca3, 0xfdde, 0xef82, 0x40ab, 0xf143, 0xac33, 0x082b, 0xfdac, 0xb9b7, 0x28f3,
-0x2b71, 0xd054, 0x2723, 0x3651, 0xb6cf, 0xd176, 0x2ba8, 0xd75d, 0xdb92, 0x450f,
-0xfd8f, 0xec9c, 0x3e23, 0xf598, 0xaf02, 0x111a, 0x135a, 0xbd2d, 0x2334, 0x3d0a,
-0xd3d8, 0x1768, 0x3bb0, 0xbab9, 0xc676, 0x311a, 0xe06f, 0xd889, 0x5018, 0x070b,
-0xe756, 0x4942, 0xfd09, 0x9d71, 0x0bcc, 0x1bed, 0xb4ce, 0x1c66, 0x47ec, 0xdc5f,
-0x1b74, 0x4238, 0xc481, 0xcf1b, 0x32f5, 0xe1ce, 0xda85, 0x4e4d, 0x0437, 0xe474,
-0x4777, 0x07ed, 0xaff9, 0x127d, 0x24cd, 0xc370, 0x199d, 0x3e29, 0xd8bf, 0x14fd,
-0x3d8b, 0xc8ea, 0xd1b6, 0x3766, 0xecd3, 0xda6f, 0x4fa7, 0x0ce7, 0xdddd, 0x4019,
-0x0c05, 0xaedb, 0x0dbc, 0x2b4c, 0xcdd3, 0x1ddc, 0x470d, 0xe283, 0x1764, 0x40d4,
-0xcabb, 0xcd66, 0x3585, 0xf1c2, 0xdda9, 0x4ffb, 0x11e4, 0xe28a, 0x415d, 0x12d2,
-0xb486, 0x055e, 0x1fd4, 0xc66e, 0x12ca, 0x417e, 0xe4e2, 0x1229, 0x3e2a, 0xd10c,
-0xc800, 0x29e0, 0xed4e, 0xd10c, 0x3fcc, 0x11a3, 0xe1f9, 0x3ad7, 0x16ca, 0xb727,
-0x0155, 0x2400, 0xc8c6, 0x0c22, 0x40bf, 0xe1dc, 0x06e9, 0x3e89, 0xd924, 0xc59a,
-0x27a2, 0xf22c, 0xcfad, 0x3f51, 0x14cd, 0xda51, 0x2f15, 0x1235, 0xae68, 0xedef,
-0x1983, 0xc602, 0x06d9, 0x46e6, 0xe9de, 0x01cd, 0x3928, 0xd470, 0xb512, 0x15ff,
-0xec31, 0xc9cd, 0x3f78, 0x243a, 0xe15e, 0x29ed, 0x1245, 0xaba1, 0xe5e9, 0x199e,
-0xc296, 0xfe39, 0x4ac5, 0xeb5f, 0xfa56, 0x3c11, 0xd94f, 0xae50, 0x1511, 0xf001,
-0xbde3, 0x36c2, 0x230d, 0xd7fe, 0x2c17, 0x1e3a, 0xaa06, 0xe31f, 0x226e, 0xc144,
-0xf626, 0x4f4e, 0xeb1e, 0xf4dd, 0x3e8c, 0xdc0a, 0xaf47, 0x1e56, 0xfed8, 0xc48e,
-0x3d56, 0x2b0f, 0xd682, 0x2918, 0x1dec, 0xa955, 0xe5bb, 0x2b6b, 0xc9b8, 0xfa77,
-0x56f8, 0xf481, 0xfb61, 0x4479, 0xdf2e, 0xabca, 0x1c70, 0xffe7, 0xbc88, 0x3a59,
-0x3826, 0xe054, 0x2f4b, 0x2c11, 0xb1dd, 0xe03e, 0x2b29, 0xc998, 0xf18d, 0x59ee,
-0xf7ac, 0xf73d, 0x4d8e, 0xed67, 0xb1d8, 0x21a9, 0x1848, 0xccda, 0x07a8, 0xffcd,
-0xfa23, 0x5aea, 0x3797, 0xd62f, 0x0ab0, 0x245e, 0xb225, 0xc27c, 0x09d2, 0xd863,
-0xfe56, 0x5bb6, 0x4ddb, 0x2aa0, 0x3bda, 0x0b4a, 0xc172, 0xdcc2, 0xc178, 0xb04a,
-0x211f, 0x3a69, 0xf99a, 0x3316, 0x7dfa, 0x1afe, 0xd954, 0x046d, 0xdf49, 0xb051,
-0xdb3e, 0x09de, 0x0f9f, 0x347e, 0x2f84, 0x0af2, 0x3895, 0x1ade, 0xc5b6, 0xd468,
-0xfe63, 0xe6d0, 0xddae, 0x14b5, 0x175e, 0x16c3, 0x1fae, 0x122e, 0x1fcb, 0x16f5,
-0xef7f, 0xbe99, 0xdd8a, 0xf61b, 0xc6ce, 0x019a, 0x43c3, 0x2909, 0x1168, 0x39ad,
-0x2f76, 0xde14, 0xddd2, 0xc963, 0xbd2a, 0xea45, 0xea62, 0x0266, 0x4616, 0x4e1c,
-0x015e, 0x18de, 0x36f6, 0xcf20, 0xb656, 0xd210, 0xd017, 0xd8b3, 0xfb2f, 0x1950,
-0x2b27, 0x3c69, 0x095e, 0x0ec5, 0x2d9c, 0xe85e, 0xb75b, 0xc4ac, 0xe1a3, 0xcfe0,
-0xdf2a, 0x1a10, 0x3183, 0x376b, 0x1d4c, 0x237d, 0x185c, 0xe4f3, 0xbf7b, 0xab18,
-0xcfc2, 0xd346, 0xe11c, 0x2903, 0x45ea, 0x24aa, 0x102b, 0x353d, 0x080f, 0xc677,
-0xbdeb, 0xb32e, 0xd477, 0xe331, 0xef66, 0x2325, 0x4c5c, 0x27b3, 0xfaf5, 0x3106,
-0x1252, 0xc709, 0xca81, 0xcbe5, 0xd04d, 0xdd4e, 0xfd3c, 0x1a5f, 0x3c21, 0x2935,
-0x0252, 0x3750, 0x1e8e, 0xc8e4, 0xb83e, 0xd48f, 0xdc6e, 0xce04, 0x0585, 0x31bc,
-0x360a, 0x2009, 0x14c2, 0x394e, 0x10a3, 0xc93d, 0xafa5, 0xd6b1, 0xef04, 0xcd94,
-0x0467, 0x48be, 0x4051, 0x1437, 0x1fb5, 0x3cd3, 0xf79e, 0xcc8f, 0xc153, 0xcd1f,
-0xeeb7, 0xe37c, 0x03cf, 0x4174, 0x4958, 0x1000, 0x1d3b, 0x4853, 0xf289, 0xbea9,
-0xc9e2, 0xd4e7, 0xde7b, 0xe633, 0x1461, 0x3e75, 0x4911, 0x1b5a, 0x2106, 0x4059,
-0xf467, 0xbf92, 0xc1f8, 0xd995, 0xdcf6, 0xe0ba, 0x1eb5, 0x4600, 0x4167, 0x1d25,
-0x2ef9, 0x3639, 0xe56b, 0xc105, 0xc027, 0xd70a, 0xe1eb, 0xea01, 0x247e, 0x4c66,
-0x3f10, 0x14c8, 0x3245, 0x3094, 0xdd32, 0xc132, 0xc147, 0xd9a1, 0xe18c, 0xeeb8,
-0x2824, 0x4a69, 0x395c, 0x1015, 0x3040, 0x238d, 0xd48a, 0xc21b, 0xc53b, 0xdc6d,
-0xe1ce, 0xf6ef, 0x2ad6, 0x46b7, 0x34da, 0x1114, 0x34eb, 0x1e8c, 0xd361, 0xbe8c,
-0xc1c6, 0xe012, 0xdf71, 0xf81f, 0x3359, 0x4a06, 0x2d71, 0x1454, 0x38da, 0x0f58,
-0xccf4, 0xbea1, 0xbbb5, 0xdb25, 0xe2c4, 0xfd77, 0x3627, 0x5121, 0x2c35, 0x15a0,
-0x3989, 0x0018, 0xc03f, 0xbaf5, 0xc3cd, 0xe02b, 0xe6c9, 0x0e3d, 0x3eb5, 0x4d58,
-0x26cb, 0x1318, 0x2fe0, 0xf891, 0xc27d, 0xb828, 0xc71e, 0xe21d, 0xe699, 0x15c5,
-0x4058, 0x45ef, 0x2262, 0x1985, 0x28bc, 0xeca7, 0xc32c, 0xb7e4, 0xcfc1, 0xea07,
-0xe4ac, 0x173a, 0x461c, 0x3eba, 0x15fa, 0x2087, 0x2703, 0xe29a, 0xc4b3, 0xb600,
-0xc8f7, 0xe687, 0xe9ba, 0x15c4, 0x426b, 0x3e74, 0x0edd, 0x1f75, 0x23b8, 0xd925,
-0xc0ab, 0xba1f, 0xcb2d, 0xe095, 0xeca2, 0x1990, 0x40e5, 0x3c5d, 0x1023, 0x24d2,
-0x1ebd, 0xd280, 0xbab7, 0xba30, 0xd226, 0xe0d0, 0xf39a, 0x22d6, 0x4063, 0x34fc,
-0x0f3b, 0x2825, 0x190f, 0xd310, 0xbcd9, 0xbd2e, 0xd80b, 0xdd5a, 0xf3ce, 0x2b22,
-0x4783, 0x32fb, 0x13a4, 0x3361, 0x1484, 0xcf84, 0xc067, 0xc184, 0xdb6a, 0xe3e8,
-0x0230, 0x3122, 0x4768, 0x320a, 0x16c1, 0x3427, 0x0aed, 0xc9bb, 0xba81, 0xc328,
-0xe12c, 0xe1e3, 0x07e1, 0x3ec1, 0x4f67, 0x2ddc, 0x15f0, 0x2f32, 0xfe24, 0xc964,
-0xbbfd, 0xc754, 0xe848, 0xe9ef, 0x1196, 0x41b3, 0x4b5f, 0x2760, 0x1f91, 0x35ce,
-0xf3d5, 0xc722, 0xbfad, 0xcade, 0xe85a, 0xeaa5, 0x1660, 0x4809, 0x4c60, 0x1f11,
-0x212f, 0x36b0, 0xefd1, 0xc764, 0xbc28, 0xc837, 0xe455, 0xec50, 0x1c88, 0x4b3c,
-0x4de3, 0x2041, 0x28c6, 0x32d7, 0xe1ea, 0xbea7, 0xbd29, 0xd1a9, 0xe60c, 0xf02d,
-0x2433, 0x4c51, 0x4811, 0x1816, 0x23ce, 0x292b, 0xdf35, 0xbcec, 0xb6b3, 0xd50d,
-0xe49a, 0xee6a, 0x2b0c, 0x4b27, 0x39f9, 0x15f5, 0x29d8, 0x1859, 0xd36e, 0xc04c,
-0xb5ab, 0xd4b0, 0xe461, 0xec0c, 0x2803, 0x4fb2, 0x371f, 0x0f49, 0x2de8, 0x1063,
-0xc7dd, 0xbbcc, 0xb195, 0xcdad, 0xe2b5, 0xf6ed, 0x29d0, 0x4ac5, 0x31e4, 0x0aa9,
-0x2acb, 0x0735, 0xbe72, 0xb39c, 0xb620, 0xd1d9, 0xdc5c, 0xfcdd, 0x307a, 0x46be,
-0x2c7c, 0x0a2b, 0x22ab, 0xfca8, 0xc0ac, 0xafc4, 0xb815, 0xde74, 0xe13f, 0x0269,
-0x370e, 0x4107, 0x21c4, 0x13c8, 0x26a3, 0xf061, 0xc3ac, 0xb5ad, 0xbbea, 0xe2b6,
-0xe314, 0x03cd, 0x3a8a, 0x453e, 0x1c0b, 0x167a, 0x2afd, 0xe8ae, 0xc330, 0xbb1d,
-0xbd71, 0xdff6, 0xea8c, 0x0cd6, 0x3cc1, 0x4b59, 0x1e08, 0x1762, 0x288a, 0xe327,
-0xbcf5, 0xbc04, 0xcc41, 0xe3b8, 0xf214, 0x1f63, 0x40b7, 0x4556, 0x1932, 0x14e9,
-0x22d4, 0xe5af, 0xc176, 0xbaf1, 0xd516, 0xeaa3, 0xed1a, 0x10a5, 0x4490, 0x6d0e,
-0x387d, 0x06ad, 0xf979, 0xc011, 0x9e3c, 0xad92, 0xe582, 0x1234, 0x4531, 0x6a71,
-0x4d3b, 0x3443, 0xfe14, 0xbf35, 0xb76f, 0xcbe7, 0xc8b4, 0xe9aa, 0x501f, 0x43d8,
-0x1d18, 0x4560, 0x2e0d, 0xf4de, 0xea75, 0xe7b7, 0xd73f, 0x0fdc, 0x11cd, 0xd145,
-0x29c3, 0x44d4, 0xdad6, 0xf4f0, 0x3e51, 0x092e, 0x07b6, 0x43ce, 0xfd5a, 0xf591,
-0x1f19, 0xc2ea, 0xb2d7, 0x198e, 0x140f, 0xfa53, 0x5e12, 0x4564, 0xf1ae, 0x2e33,
-0x0b49, 0xa4bb, 0xdaed, 0x1485, 0xdc90, 0x0cbf, 0x4f0d, 0x0854, 0x15b5, 0x3b75,
-0xe6b5, 0xbe4e, 0x0981, 0xfc23, 0xc6c6, 0x22a2, 0x2984, 0xf1db, 0x27f9, 0x1ab0,
-0xc60e, 0xe49e, 0x21a8, 0xd681, 0xe953, 0x41f4, 0xf337, 0xeb9d, 0x3560, 0xf514,
-0xbd12, 0x135a, 0x1144, 0xc99f, 0x21e0, 0x2271, 0xd155, 0x1a35, 0x25a3, 0xbec7,
-0xdc7d, 0x31ed, 0xe802, 0xe46d, 0x3ef6, 0xfc72, 0xeb7d, 0x2fc5, 0xecf1, 0xb132,
-0x0d6d, 0x171d, 0xcaf3, 0x20be, 0x36cd, 0xdeff, 0x1430, 0x2c97, 0xc49c, 0xcab8,
-0x247c, 0xe2b5, 0xd3f1, 0x3d93, 0x0c22, 0xee37, 0x3907, 0x01ea, 0xb32c, 0x07e5,
-0x153f, 0xb7d0, 0x0a61, 0x333d, 0xdb8a, 0x1138, 0x3892, 0xcfca, 0xccd1, 0x2831,
-0xeb12, 0xd73f, 0x357e, 0xfe1d, 0xe21b, 0x300a, 0xfded, 0xaf91, 0xffaf, 0x1ba1,
-0xc5b1, 0x0c52, 0x3c73, 0xe33f, 0xfac8, 0x2338, 0xd7bc, 0xc7f4, 0x0f99, 0xe739,
-0xd9e0, 0x3980, 0x0e6d, 0xe382, 0x335e, 0x15f9, 0xae82, 0xe698, 0x1c86, 0xca1d,
-0xf6f1, 0x34d2, 0xf14d, 0x0fec, 0x3c9a, 0xdef1, 0xc8df, 0x20f3, 0xea68, 0xc50a,
-0x33ef, 0x1185, 0xd7d4, 0x2ebc, 0x2178, 0xc1c1, 0xf72b, 0x2354, 0xd2eb, 0x0168,
-0x30db, 0xe0a6, 0x05a6, 0x3bad, 0xdc09, 0xc45f, 0x276d, 0xfd11, 0xcf0a, 0x363e,
-0x204b, 0xe4d0, 0x2851, 0x199c, 0xbc3c, 0xe9df, 0x1c38, 0xcf05, 0x03b3, 0x4c0e,
-0xf6ee, 0x068d, 0x44a0, 0xe3e0, 0xb163, 0x17fa, 0xfdee, 0xc709, 0x37cd, 0x2e63,
-0xea1c, 0x3531, 0x2ca0, 0xbf9e, 0xeeec, 0x2b06, 0xc5f7, 0xf1c8, 0x5385, 0xfc84,
-0x0002, 0x49cb, 0xf52b, 0xbfbf, 0x204d, 0x04c6, 0xc649, 0x35e9, 0x30b9, 0xe658,
-0x31b2, 0x2cb7, 0xb96b, 0xe5a8, 0x2f24, 0xd410, 0xf6ab, 0x5771, 0x04b9, 0xfc36,
-0x3ec2, 0xecd7, 0xb28a, 0x1904, 0x0954, 0xc24d, 0x3764, 0x3ade, 0xddf2, 0x29ce,
-0x3445, 0xb4d5, 0xd352, 0x2d79, 0xd037, 0xe09a, 0x535a, 0x01a5, 0xf095, 0x48ef,
-0xf767, 0xa8aa, 0x11b3, 0x097b, 0xb15c, 0x2a36, 0x3db4, 0xd6cd, 0x24b8, 0x3712,
-0xb430, 0xcdb4, 0x2b60, 0xd3aa, 0xe09b, 0x53eb, 0xfc4a, 0xea6b, 0x4b2a, 0xf90e,
-0xa8c8, 0x1124, 0x129b, 0xbaac, 0x269d, 0x4030, 0xda96, 0x20e1, 0x3a2e, 0xbd1c,
-0xd0d8, 0x3158, 0xdd88, 0xdee5, 0x57dc, 0x0a22, 0xeb70, 0x4be8, 0x027e, 0xa602,
-0x0680, 0x1714, 0xbfed, 0x242e, 0x47b1, 0xe011, 0x1d8e, 0x3eca, 0xc029, 0xc616,
-0x2e06, 0xe28f, 0xd4aa, 0x4f9e, 0x0f06, 0xe649, 0x438d, 0x0564, 0xa6f1, 0x02f6,
-0x1bd3, 0xc020, 0x18b7, 0x4204, 0xd71b, 0x0fc8, 0x3e52, 0xc2b8, 0xbf78, 0x2bd7,
-0xe6d3, 0xce7b, 0x47d7, 0x0a5d, 0xd7d4, 0x39c7, 0x074e, 0xa273, 0xfc77, 0x1fef,
-0xbcf9, 0x0cec, 0x426a, 0xd4f2, 0x044f, 0x3d93, 0xc6ea, 0xbcdf, 0x2bd1, 0xed0b,
-0xce10, 0x43d0, 0x0ca2, 0xd5d2, 0x35c4, 0x0c15, 0xa646, 0xfa2d, 0x2097, 0xc0dd,
-0x0c2b, 0x439b, 0xdc9c, 0x059f, 0x3b30, 0xca4a, 0xbbcb, 0x2337, 0xe7a3, 0xc717,
-0x3dae, 0x1491, 0xdc09, 0x3229, 0x0f3e, 0xac38, 0xf62a, 0x25d7, 0xcda9, 0xe86a,
-0x0ccd, 0xe87d, 0x2a51, 0x46ee, 0xea42, 0xe40d, 0x22b1, 0xd631, 0xa84b, 0xf868,
-0xe4f9, 0xdc35, 0x395d, 0x50be, 0x1fd6, 0x25ac, 0x1e57, 0xc641, 0xc358, 0xd0f2,
-0xac56, 0xf1aa, 0x385d, 0x08e0, 0x0c0c, 0x6c90, 0x3d9a, 0xd534, 0xf575, 0xf32f,
-0xb660, 0xc715, 0x00c3, 0x060a, 0x1cc0, 0x3bee, 0x0fef, 0x2648, 0x390e, 0xe520,
-0xcaa4, 0xfc07, 0xfa8c, 0xcfc3, 0xff3b, 0x2146, 0x0eaa, 0x22f7, 0x21eb, 0x22a5,
-0x2b3f, 0x140f, 0xd035, 0xce0d, 0x018b, 0xcdfd, 0xe402, 0x4024, 0x35a0, 0x11b4,
-0x30f7, 0x48c6, 0xfc36, 0xe429, 0xd9e4, 0xb819, 0xe9ae, 0xecf6, 0xeaac, 0x339b,
-0x5af6, 0x18c2, 0x0a7d, 0x49f9, 0xfaf8, 0xba8d, 0xd5ae, 0xd0dc, 0xd43b, 0xee6d,
-0x117b, 0x23d1, 0x46ee, 0x29ad, 0x0339, 0x3a96, 0x1314, 0xc110, 0xbad0, 0xd9cf,
-0xd706, 0xcd74, 0x0d91, 0x315e, 0x3f9c, 0x359b, 0x2190, 0x2aef, 0x0433, 0xcdb2,
-0xa574, 0xc711, 0xe12e, 0xcf40, 0x197f, 0x5324, 0x3d77, 0x20a5, 0x375c, 0x2d03,
-0xe262, 0xca54, 0xb0b0, 0xc640, 0xed6e, 0xe3a9, 0x14a7, 0x559a, 0x4789, 0x0af5,
-0x2c0d, 0x3078, 0xd574, 0xc8f1, 0xc60c, 0xc4a3, 0xddbb, 0xf434, 0x12bf, 0x3a4f,
-0x46b5, 0x0de9, 0x28f8, 0x3a3e, 0xd862, 0xb36e, 0xc4b9, 0xd290, 0xcc9e, 0xf150,
-0x28e5, 0x36b7, 0x3727, 0x1942, 0x296a, 0x1f3b, 0xd304, 0xaa50, 0xb7e0, 0xe064,
-0xcd60, 0xe774, 0x36d2, 0x4354, 0x256f, 0x16b9, 0x32a9, 0x04e9, 0xc94b, 0xbd89,
-0xb4e8, 0xde63, 0xe6b3, 0xefc2, 0x2c99, 0x4d30, 0x244c, 0x0dd9, 0x4013, 0x0a25,
-0xbf81, 0xc647, 0xc8d3, 0xd098, 0xddd7, 0x0729, 0x2f46, 0x49fe, 0x3186, 0x11dd,
-0x33c9, 0x0a1a, 0xc455, 0xb4fe, 0xcbf9, 0xe01f, 0xd9c3, 0x0d63, 0x3ca9, 0x40e4,
-0x2597, 0x1f85, 0x2fee, 0xf6c7, 0xc763, 0xb733, 0xcbd2, 0xe734, 0xe337, 0x11ef,
-0x4379, 0x4377, 0x1865, 0x216c, 0x32c8, 0xee0c, 0xca47, 0xc04a, 0xd076, 0xe70b,
-0xebed, 0x16a9, 0x3f81, 0x44ae, 0x16f6, 0x2266, 0x31f0, 0xe6d6, 0xc30d, 0xc333,
-0xd87e, 0xe495, 0xf14b, 0x1f91, 0x3ab4, 0x3a37, 0x1822, 0x291b, 0x2bcf, 0xea2c,
-0xc762, 0xbf57, 0xdd08, 0xe181, 0xec7b, 0x28f2, 0x456d, 0x366d, 0x1d72, 0x3891,
-0x2266, 0xe229, 0xcd55, 0xbe26, 0xdad8, 0xe6b2, 0xf1ad, 0x2a59, 0x4ce7, 0x346f,
-0x18da, 0x3eb3, 0x1a5c, 0xd0e6, 0xc45c, 0xbfe1, 0xd4d3, 0xe11f, 0x014a, 0x2f81,
-0x4863, 0x3408, 0x1268, 0x31f4, 0x0ec8, 0xca3c, 0xb9fc, 0xc1dc, 0xdd52, 0xe093,
-0x05ff, 0x33c3, 0x43d7, 0x2da7, 0x1671, 0x2bf0, 0x0034, 0xc97d, 0xb0c3, 0xbe5e,
-0xe43b, 0xdb68, 0x0387, 0x3ae6, 0x3ee7, 0x1b43, 0x174b, 0x2d76, 0xf26e, 0xc68d,
-0xb289, 0xbb76, 0xe0fe, 0xde57, 0x0305, 0x3b0e, 0x44f7, 0x17e8, 0x1ae0, 0x2e9e,
-0xe6b9, 0xc23e, 0xb5b3, 0xbe35, 0xde8a, 0xe55c, 0x0e04, 0x3e2d, 0x4749, 0x1891,
-0x1cce, 0x2c46, 0xe31a, 0xbc10, 0xb2be, 0xc7d4, 0xe1b0, 0xec58, 0x1b5f, 0x42a4,
-0x4577, 0x18af, 0x206d, 0x2610, 0xe0cf, 0xbee7, 0xb63b, 0xd3ec, 0xe4ab, 0xed6c,
-0x253f, 0x4a99, 0x42a8, 0x18da, 0x2a90, 0x2130, 0xd967, 0xc013, 0xb623, 0xd3d0,
-0xe7d4, 0xf7c7, 0x2d1b, 0x4df4, 0x3dfe, 0x18d3, 0x2e94, 0x12e1, 0xceb7, 0xbc8b,
-0xb721, 0xd9e6, 0xe7b6, 0xfe42, 0x37c7, 0x5256, 0x3916, 0x14fa, 0x2b19, 0x0829,
-0xcbbc, 0xbc11, 0xba4e, 0xe0c8, 0xec3c, 0x04ba, 0x39d7, 0x4f48, 0x314f, 0x1b2a,
-0x320f, 0xfbd4, 0xc7ad, 0xbe46, 0xbcb0, 0xdfec, 0xea9d, 0x0a76, 0x3eae, 0x51ce,
-0x28b8, 0x15c7, 0x32b1, 0xf736, 0xc436, 0xbbe2, 0xc2bd, 0xe357, 0xecf4, 0x10c4,
-0x40f6, 0x524e, 0x25cd, 0x19ce, 0x301e, 0xec1e, 0xbc6a, 0xbace, 0xd1d8, 0xe825,
-0xec23, 0x1b1b, 0x4400, 0x482a, 0x1bce, 0x1896, 0x260d, 0xe7f6, 0xc325, 0xb5e4,
-0xd101, 0xeabf, 0xea0d, 0x1d52, 0x47b3, 0x3cf0, 0x1282, 0x235d, 0x2050, 0xd9ae,
-0xc4d9, 0xb970, 0xd086, 0xe87d, 0xea86, 0x1b23, 0x48b1, 0x3c02, 0x0e92, 0x2cb2,
-0x2472, 0xd2cb, 0xbff8, 0xbc43, 0xce22, 0xe2d3, 0xf745, 0x2364, 0x47bb, 0x3e11,
-0x1209, 0x2f53, 0x1fb0, 0xcfac, 0xba0d, 0xbeea, 0xd8e3, 0xde1c, 0xf854, 0x2f24,
-0x49ea, 0x387f, 0x14be, 0x2de7, 0x1304, 0xd01b, 0xb948, 0xbc56, 0xe0d1, 0xe484,
-0xff93, 0x3655, 0x488a, 0x2bf5, 0x16ba, 0x3637, 0x07aa, 0xcf32, 0xc24d, 0xc063,
-0xe449, 0xe713, 0x01e8, 0x3b25, 0x4f83, 0x26c5, 0x1640, 0x3ab8, 0xff8c, 0xc83c,
-0xbf7c, 0xc052, 0xdf32, 0xe807, 0x09ef, 0x390f, 0x4d01, 0x25f5, 0x19b1, 0x3685,
-0xf201, 0xbb2e, 0xb561, 0xc59a, 0xdeac, 0xe81d, 0x110d, 0x2f0d, 0x5faf, 0x5bc4,
-0x12fe, 0xf615, 0xda50, 0xa9ae, 0x886f, 0xcd18, 0x0718, 0x09f1, 0x5bb7, 0x7af7,
-0x3e15, 0x0a73, 0xe799, 0xa715, 0x9c71, 0xc971, 0xb0a1, 0x07a7, 0x6f82, 0x3163,
-0x2a82, 0x5398, 0x14c9, 0xbfc2, 0xd8b3, 0xd540, 0xc5ce, 0x0fda, 0xf099, 0xf1a7,
-0x518e, 0x1c60, 0xcd84, 0x19da, 0x35b8, 0xd346, 0x03a1, 0x377b, 0xdf14, 0xefc5,
-0x0c59, 0xc206, 0xc448, 0x2196, 0x11ee, 0xfe70, 0x4f48, 0x1fa8, 0xeb2d, 0x1d5b,
-0xeaf2, 0x9f51, 0xdaef, 0x10e0, 0xe2b8, 0x140e, 0x4a7c, 0x0548, 0x11c6, 0x2b5c,
-0xd063, 0xb9e9, 0x0c49, 0xee9f, 0xcd6b, 0x32da, 0x2204, 0xe702, 0x2c36, 0x195d,
-0xbc4d, 0xef56, 0x1ea6, 0xd1a8, 0xfb24, 0x33f8, 0xe2fa, 0xffb5, 0x3ccd, 0xe4cb,
-0xca25, 0x2563, 0x0355, 0xd2da, 0x2bb0, 0x137a, 0xd6ec, 0x2218, 0x1b95, 0xc3b7,
-0xf854, 0x3722, 0xe6e8, 0xf671, 0x3596, 0xec18, 0xf030, 0x2d9c, 0xe6e7, 0xc2e9,
-0x26d5, 0x1a49, 0xd733, 0x2bbd, 0x26a1, 0xdab2, 0x1ba0, 0x23f0, 0xc355, 0xe703,
-0x2bce, 0xdc49, 0xf190, 0x496d, 0xfc6e, 0xf386, 0x3dfc, 0xf7e9, 0xbcff, 0x1444,
-0x0996, 0xc579, 0x1fc6, 0x2a9c, 0xe722, 0x261f, 0x2af6, 0xc74c, 0xe3b8, 0x2a8b,
-0xe105, 0xe8c4, 0x3bef, 0xfd9f, 0xefc2, 0x313f, 0xf888, 0xbeed, 0x0f0d, 0x10ba,
-0xcf13, 0x2814, 0x3a0d, 0xdf51, 0x0dca, 0x2f8f, 0xccfa, 0xc831, 0x1d1f, 0xe940,
-0xe8cf, 0x4a93, 0x0d52, 0xef83, 0x3c76, 0xfaba, 0xa5dd, 0x0126, 0x112f, 0xbdc7,
-0x1a61, 0x422a, 0xe9fb, 0x1b1a, 0x3694, 0xc9c9, 0xce2b, 0x1ef2, 0xd732, 0xdc7b,
-0x46da, 0xff7f, 0xe9fc, 0x46e1, 0x05ac, 0xaeb6, 0x0663, 0x159d, 0xc012, 0x1316,
-0x34ba, 0xdd94, 0x12fd, 0x31f6, 0xc596, 0xcbff, 0x2ae2, 0xe4d5, 0xd6c1, 0x4927,
-0x0b3d, 0xdd77, 0x3926, 0x07d1, 0xa2d2, 0xfb2e, 0x211d, 0xc317, 0x1769, 0x4b14,
-0xe280, 0x1326, 0x411c, 0xc1e2, 0xbac5, 0x2cf6, 0xe603, 0xcb4b, 0x4ed8, 0x191b,
-0xe401, 0x458d, 0x1545, 0xac87, 0x005f, 0x1e4a, 0xba9b, 0x0cc0, 0x467e, 0xe1cf,
-0x11da, 0x478e, 0xd350, 0xc70d, 0x31c1, 0xf201, 0xce1e, 0x434c, 0x12d6, 0xdd0b,
-0x3986, 0x1337, 0xaf6d, 0x006c, 0x2ca7, 0xc8ff, 0x0c23, 0x4bde, 0xe11d, 0x0318,
-0x41ef, 0xd0e5, 0xbd29, 0x3042, 0xf8a0, 0xd014, 0x4ad2, 0x1b53, 0xda3d, 0x3aa3,
-0x14be, 0xa4bb, 0xf7a1, 0x2b27, 0xc43a, 0x0948, 0x507e, 0xe296, 0x0297, 0x45db,
-0xd510, 0xb990, 0x273a, 0xf430, 0xc750, 0x3f4c, 0x1a85, 0xdb6a, 0x3993, 0x1ab4,
-0xadf3, 0xf5f6, 0x280d, 0xc5fc, 0xfe8a, 0x4668, 0xe58d, 0x011c, 0x457a, 0xdfc7,
-0xbebe, 0x255e, 0xfae1, 0xcb02, 0x3a3a, 0x1b49, 0xd635, 0x2c90, 0x1a6d, 0xb0f1,
-0xf0b7, 0x2851, 0xcb11, 0xfd3b, 0x4815, 0xe902, 0xf73a, 0x3af3, 0xde3a, 0xb633,
-0x1a27, 0xfae7, 0xc8e7, 0x3373, 0x1efa, 0xdab3, 0x2af8, 0x1f54, 0xb3a4, 0xe5bd,
-0x2010, 0xc657, 0xef33, 0x4332, 0xf32a, 0xf8bc, 0x3a43, 0xe716, 0xb380, 0x1025,
-0xf94b, 0xbff8, 0x2cbe, 0x2722, 0xd958, 0x2238, 0x24de, 0xb4e0, 0xd8e0, 0x219f,
-0xcbf4, 0xec3e, 0x4cc4, 0xf5db, 0xee65, 0x3cb1, 0xe88f, 0xad6b, 0x15fb, 0x0312,
-0xbe65, 0x3207, 0x3441, 0xd731, 0x1ee6, 0x2923, 0xb321, 0xd7af, 0x26e1, 0xce3a,
-0xeb73, 0x52d6, 0xfb3a, 0xed11, 0x3fa2, 0xeb93, 0xa537, 0x0fde, 0x078b, 0xbcc7,
-0x2dd2, 0x39bf, 0xde73, 0x2216, 0x2ba5, 0xb204, 0xd113, 0x2873, 0xd059, 0xe433,
-0x5331, 0x00f5, 0xede6, 0x41c9, 0xf3f8, 0xaa8c, 0x0f24, 0x06be, 0xb5e6, 0x29e9,
-0x39f4, 0xda5d, 0x25b6, 0x2b84, 0xb07f, 0xd942, 0x36fe, 0xe8ec, 0xcdd1, 0x1733,
-0x0849, 0x1aa1, 0x4558, 0xfb48, 0xd3ef, 0x11bd, 0xef48, 0xb142, 0xf697, 0xfdea,
-0xd64a, 0x32a6, 0x6fed, 0x25f8, 0x0b17, 0x2a5c, 0xdff3, 0xaef4, 0xd4ec, 0xbcba,
-0xe25d, 0x44cb, 0x234b, 0x1321, 0x73ba, 0x4da9, 0xced4, 0xe817, 0x007f, 0xa908,
-0xb5df, 0x1df6, 0x1875, 0x0e2c, 0x3ec1, 0x2fcd, 0x272d, 0x2290, 0xe25c, 0xc07e,
-0xf134, 0xfb4d, 0xd6f2, 0x0ad3, 0x3447, 0x223c, 0x13f1, 0x2272, 0x269f, 0x025a,
-0x0161, 0xd722, 0xd224, 0x0308, 0xde38, 0xef78, 0x3c18, 0x42ed, 0x0555, 0x290a,
-0x5400, 0xe6be, 0xca2d, 0xdae9, 0xc68f, 0xd7d0, 0xf47c, 0x10ed, 0x3184, 0x5941,
-0x1cf6, 0x0891, 0x3a35, 0xeb6f, 0xae39, 0xc817, 0xe6f7, 0xd6ef, 0xebb0, 0x3372,
-0x35f1, 0x34dd, 0x1e90, 0x16f7, 0x21a1, 0xf074, 0xc287, 0xb8c4, 0xe82d, 0xe6eb,
-0xdb90, 0x1e19, 0x40af, 0x3208, 0x1a9a, 0x320f, 0x1b9a, 0xdeff, 0xcf46, 0xb4a3,
-0xcbd7, 0xdf68, 0xe59a, 0x22fe, 0x55b5, 0x3892, 0x0be2, 0x396b, 0x1a98, 0xc635,
-0xc146, 0xc092, 0xd361, 0xe7eb, 0x0383, 0x2879, 0x4c6a, 0x3c0d, 0x05ca, 0x2976,
-0x14a9, 0xc798, 0xc116, 0xd2d8, 0xdd50, 0xdcd3, 0x0b09, 0x2bce, 0x3653, 0x2ab8,
-0x0a52, 0x2aa9, 0x14b7, 0xd401, 0xb890, 0xcc60, 0xea88, 0xd5e4, 0xfe7d, 0x383b,
-0x3ade, 0x1b88, 0x1ad7, 0x3ed1, 0x075f, 0xcd9c, 0xbbc4, 0xcbe8, 0xeb85, 0xd822,
-0xfbc3, 0x3e44, 0x459b, 0x10ea, 0x17ee, 0x43df, 0xf7f9, 0xc0a0, 0xc419, 0xcf1f,
-0xdea4, 0xe05f, 0x0678, 0x330f, 0x42d4, 0x111c, 0x0fba, 0x3f57, 0xf9a8, 0xb669,
-0xbe1b, 0xe146, 0xdd9a, 0xd4be, 0x11a3, 0x389d, 0x37d6, 0x13b2, 0x1c70, 0x3370,
-0xf10c, 0xc063, 0xb6e6, 0xd48a, 0xdc66, 0xd809, 0x1789, 0x3f92, 0x3566, 0x0e0f,
-0x231e, 0x2ea3, 0xde28, 0xbb31, 0xba09, 0xcf05, 0xd866, 0xdfc8, 0x18f1, 0x3ecd,
-0x369b, 0x0a8f, 0x2386, 0x2af2, 0xda2a, 0xb79e, 0xb7d0, 0xd687, 0xde35, 0xe721,
-0x22ba, 0x4574, 0x3572, 0x0dd3, 0x2e06, 0x263b, 0xd7ab, 0xbfc7, 0xc2f6, 0xdf1b,
-0xe1c3, 0xf1d5, 0x2cb4, 0x4e1c, 0x37cd, 0x115d, 0x35cd, 0x1fe6, 0xd779, 0xc301,
-0xc58e, 0xe72d, 0xe5ce, 0xf960, 0x335a, 0x4fb4, 0x357b, 0x1898, 0x426e, 0x1cc2,
-0xd473, 0xc727, 0xc831, 0xe1fb, 0xe68f, 0x072e, 0x3da1, 0x58d4, 0x39ac, 0x1d25,
-0x4338, 0x1401, 0xcf2b, 0xbee6, 0xca41, 0xe875, 0xe64f, 0x1316, 0x4982, 0x5236,
-0x2f67, 0x2085, 0x38b8, 0xfd01, 0xc7c8, 0xba93, 0xc979, 0xebc7, 0xea26, 0x168d,
-0x477d, 0x4817, 0x212b, 0x1fdd, 0x335a, 0xef3e, 0xc484, 0xb895, 0xc9b8, 0xec42,
-0xe805, 0x136b, 0x4a61, 0x4971, 0x17b6, 0x1f6a, 0x2f97, 0xe4b1, 0xc086, 0xb999,
-0xcac9, 0xe5fd, 0xee0c, 0x1807, 0x412f, 0x460f, 0x166d, 0x1f4c, 0x29b3, 0xdc64,
-0xb965, 0xb861, 0xd211, 0xe147, 0xeb99, 0x2193, 0x450f, 0x3ce4, 0x113e, 0x1f63,
-0x1c84, 0xd769, 0xb874, 0xb487, 0xd682, 0xe1c9, 0xed74, 0x24b0, 0x43a4, 0x33ba,
-0x0e1c, 0x2413, 0x10f7, 0xcdd3, 0xb977, 0xb8d7, 0xdbc4, 0xe37c, 0xf175, 0x272e,
-0x457d, 0x2d0a, 0x07d0, 0x297e, 0x0f41, 0xca51, 0xb9f7, 0xbc9a, 0xdaa7, 0xddfe,
-0xf766, 0x2c64, 0x4532, 0x2d7b, 0x0dd9, 0x2cf4, 0x0c17, 0xc90f, 0xb4bc, 0xc07f,
-0xe270, 0xdce1, 0xfc63, 0x371a, 0x4749, 0x2579, 0x1187, 0x2dc1, 0xff1f, 0xc7eb,
-0xb7f0, 0xc150, 0xe209, 0xe0bb, 0x0562, 0x39a6, 0x419b, 0x18df, 0x11d0, 0x32b0,
-0xf640, 0xc162, 0xbaa8, 0xc92a, 0xe355, 0xdf42, 0x07ce, 0x3de6, 0x485f, 0x1a8d,
-0x15e0, 0x345d, 0xf2a7, 0xc2b4, 0xbc48, 0xcb43, 0xe331, 0xe771, 0x171d, 0x41c7,
-0x46e8, 0x1e6a, 0x1d99, 0x3169, 0xea47, 0xbb34, 0xb612, 0xcfe5, 0xe372, 0xe4f4,
-0x1dce, 0x4978, 0x4538, 0x1abb, 0x1ff9, 0x2726, 0xe2ee, 0xbf5a, 0xb642, 0xd6a7,
-0xeb65, 0xe981, 0x26c2, 0x5246, 0x3d0f, 0x142e, 0x2f6c, 0x28fc, 0xda88, 0xc3aa,
-0xbdbe, 0xd749, 0xeb54, 0xf1e0, 0x25cd, 0x526c, 0x41ba, 0x10bf, 0x2fe6, 0x2449,
-0xd374, 0xbfc4, 0xbbe2, 0xd283, 0xe25c, 0xf99f, 0x2cef, 0x4ac7, 0x3ddf, 0x17d9,
-0x3082, 0x1925, 0xce89, 0xb6a1, 0xbc50, 0xe283, 0xe474, 0xfd8d, 0x3bcc, 0x4e96,
-0x33c3, 0x167a, 0x2e47, 0x0a43, 0xcef1, 0xbc29, 0xba3d, 0xe1a3, 0xe5f7, 0xfe7c,
-0x39db, 0x4bea, 0x270e, 0x128b, 0x30de, 0xfb59, 0xc505, 0xbdab, 0xbd60, 0xe0c5,
-0xe64a, 0x0171, 0x35c3, 0x47fc, 0x21b5, 0x11b5, 0x30fa, 0xf4fc, 0xc06e, 0xbaa3,
-0xbc7a, 0xd83f, 0xe4e1, 0x0b66, 0x373d, 0x497a, 0x2421, 0x109c, 0x26f1, 0xecb6,
-0xbadf, 0xb11f, 0xc45d, 0xdf59, 0xe4b2, 0x1641, 0x3f59, 0x42bc, 0x1c1c, 0x129c,
-0x1bee, 0xe133, 0xbe64, 0xb1ad, 0xcc9f, 0xec32, 0xe986, 0x19ae, 0x44e5, 0x3a19,
-0x0e88, 0x1ade, 0x1f2c, 0xdec4, 0xc3cc, 0xb2ef, 0xdaab, 0xfd08, 0xe6a7, 0x1123,
-0x3704, 0x3898, 0x3ad4, 0x346f, 0xfe92, 0xd1d3, 0xcc04, 0x9cbd, 0xc135, 0x02eb,
-0xf63b, 0x365b, 0x8b58, 0x58ad, 0x0415, 0x0488, 0xcf1c, 0x8e64, 0xb611, 0xc2c4,
-0xeda1, 0x4ea8, 0x63da, 0x49bb, 0x50ec, 0x3618, 0xc859, 0xb818, 0xe010, 0xbc83,
-0xd14a, 0x1ad8, 0x32a9, 0x4030, 0x4434, 0x0f51, 0xf80f, 0x1895, 0xeaf8, 0xc48d,
-0x175a, 0x2702, 0xe895, 0x0fd2, 0x2756, 0xcf30, 0xdfad, 0x3a11, 0xfb80, 0xfa5f,
-0x565f, 0x121d, 0xf290, 0x2352, 0xddf3, 0xa5f4, 0xfe06, 0x187b, 0xde96, 0x3a13,
-0x5105, 0xf698, 0x255a, 0x212e, 0xb7a3, 0xc5a7, 0x10d7, 0xdeff, 0xe90b, 0x551a,
-0x1708, 0xfd81, 0x42e8, 0xf9ae, 0xb328, 0xf8c8, 0x0cd4, 0xc910, 0x1398, 0x3cf8,
-0xe89b, 0x1c9d, 0x36c1, 0xcb0b, 0xcca6, 0x2759, 0xf1e2, 0xd264, 0x3d80, 0x146d,
-0xe372, 0x36c2, 0x0ab3, 0xb2ef, 0x0a0e, 0x2e96, 0xc7be, 0x0dcf, 0x4ba5, 0xdcd8,
-0xff1f, 0x391f, 0xcf51, 0xc4c3, 0x314b, 0xfef3, 0xd680, 0x41c6, 0x156e, 0xdd3b,
-0x2eeb, 0x0886, 0xa9c9, 0xf3a6, 0x247e, 0xc927, 0x069f, 0x4a37, 0xe895, 0x0061,
-0x378e, 0xd6a1, 0xb348, 0x1688, 0xf810, 0xc498, 0x323f, 0x1fc5, 0xe066, 0x29b3,
-0x139d, 0xadbb, 0xe71a, 0x2c44, 0xcae3, 0xe8e1, 0x3f89, 0xe822, 0xf034, 0x367a,
-0xdf30, 0xb32c, 0x1aba, 0x0281, 0xcc1b, 0x36c4, 0x14ca, 0xc6d5, 0x2590, 0x1c08,
-0xa351, 0xd7ce, 0x2a74, 0xd59f, 0xf3fa, 0x477e, 0xf4e0, 0xf8ff, 0x3121, 0xdc01,
-0xb775, 0x150c, 0xfcd8, 0xcc0d, 0x38c8, 0x2ece, 0xe423, 0x2849, 0x29b5, 0xc302,
-0xda74, 0x1f47, 0xdd2f, 0xf247, 0x3ab2, 0xf2d7, 0x006a, 0x4787, 0xf2b8, 0xbc9f,
-0x1f1c, 0x0ac7, 0xbde9, 0x23df, 0x2b4d, 0xd869, 0x1cf2, 0x2e59, 0xc8ac, 0xe6ca,
-0x2cef, 0xd907, 0xf197, 0x4b23, 0xf20c, 0xef15, 0x4469, 0xf156, 0xb2a9, 0x1bfd,
-0x127b, 0xca28, 0x306d, 0x3438, 0xdf08, 0x20cf, 0x27a1, 0xb9c7, 0xd8d7, 0x2741,
-0xd309, 0xe588, 0x5056, 0x03d5, 0xef96, 0x4207, 0xfd8d, 0xae5f, 0x03b5, 0x0589,
-0xbd38, 0x23af, 0x3a76, 0xe095, 0x2023, 0x3839, 0xc165, 0xd4ca, 0x2de1, 0xd781,
-0xe09b, 0x50bd, 0x0340, 0xea0c, 0x4022, 0xf840, 0xad2c, 0x1331, 0x12e3, 0xc260,
-0x2f2a, 0x3b6c, 0xd12c, 0x18a4, 0x3197, 0xb77c, 0xd13d, 0x2bd2, 0xd972, 0xe616,
-0x52eb, 0x041e, 0xeb26, 0x3bdc, 0xf119, 0xa2b2, 0x06d5, 0x1049, 0xbd97, 0x289f,
-0x44ee, 0xdf14, 0x1d7f, 0x34ac, 0xb7bb, 0xc690, 0x278a, 0xda25, 0xdff9, 0x579a,
-0x080c, 0xe6ec, 0x4374, 0xfcbd, 0xa5be, 0x078c, 0x146b, 0xbb5b, 0x2164, 0x4262,
-0xdc47, 0x1e50, 0x39f8, 0xbce7, 0xcbb4, 0x2afe, 0xdc45, 0xdb5e, 0x5409, 0x0b3a,
-0xe53c, 0x4358, 0x02ae, 0xa896, 0x0857, 0x1af8, 0xc23a, 0x2352, 0x496b, 0xdfb5,
-0x197e, 0x3ce3, 0xbe54, 0xc506, 0x3012, 0xe677, 0xd704, 0x5217, 0x11ee, 0xe2e7,
-0x3fe4, 0x06fa, 0xa5a3, 0xfdcd, 0x181f, 0xbb44, 0x1747, 0x4a1f, 0xdca9, 0x10d6,
-0x4291, 0xc4a6, 0xbd25, 0x2a87, 0xe605, 0xcbf6, 0x4b38, 0x15fb, 0xe0ad, 0x3f35,
-0x0d36, 0xa652, 0x0068, 0x234a, 0xbde1, 0x11e2, 0x4aeb, 0xdbe0, 0x0a9d, 0x4344,
-0xcb41, 0xbfb5, 0x3005, 0xef5d, 0xcc1b, 0x497b, 0x1516, 0xd825, 0x3b8a, 0x1677,
-0xabc7, 0xfeb9, 0x2dcb, 0xc484, 0x08d9, 0x4f69, 0xe275, 0x041d, 0x4846, 0xd81a,
-0xc055, 0x3307, 0xfcca, 0xce29, 0x4a68, 0x20cb, 0xd8f3, 0x379a, 0x1b24, 0xaf02,
-0xfaf5, 0x36a2, 0xdc0c, 0xf2c4, 0x1be5, 0xefab, 0x3121, 0x54a4, 0xf198, 0xe7b1,
-0x2ba4, 0xe144, 0xad6e, 0x0105, 0xf0a8, 0xe331, 0x4379, 0x5911, 0x2529, 0x2cc9,
-0x279d, 0xcce3, 0xc4aa, 0xd6d0, 0xaebe, 0xee7a, 0x3b83, 0x0e08, 0x0c23, 0x6c6b,
-0x4249, 0xd2d0, 0xee99, 0xf0dc, 0xb1d9, 0xc315, 0x0097, 0x05b2, 0x198e, 0x3a21,
-0x0a87, 0x19af, 0x3001, 0xda73, 0xbf3b, 0xf320, 0xf1e8, 0xce48, 0xfde9, 0x1c97,
-0x092a, 0x1c03, 0x1996, 0x174f, 0x1e06, 0x0784, 0xc7d4, 0xc266, 0xf6c0, 0xcc3e,
-0xdd41, 0x35c9, 0x3070, 0x0e9b, 0x2df6, 0x46cc, 0xf777, 0xdb3b, 0xd86d, 0xb2ad,
-0xdad5, 0xea97, 0xeb13, 0x2dfd, 0x5bf5, 0x1d45, 0x0c80, 0x4c6b, 0xf9d2, 0xb332,
-0xd3b1, 0xcca7, 0xc90a, 0xeeb9, 0x1637, 0x2142, 0x4501, 0x2b65, 0x034c, 0x35ee,
-0x0df0, 0xbcaf, 0xb962, 0xda48, 0xd509, 0xd169, 0x125a, 0x2f7e, 0x3ce9, 0x31e9,
-0x1f9f, 0x25c3, 0xf9ce, 0xc7fa, 0xa4bc, 0xc4e4, 0xde14, 0xd114, 0x1820, 0x4ec1,
-0x3955, 0x1716, 0x2ffb, 0x23e1, 0xd401, 0xc118, 0xaea8, 0xc267, 0xe761, 0xe650,
-0x166b, 0x5317, 0x4508, 0x02ef, 0x256f, 0x2a58, 0xc9bf, 0xbfb1, 0xc690, 0xc4c0,
-0xdb5a, 0xfc3e, 0x1d56, 0x406f, 0x4672, 0x07f9, 0x258b, 0x3563, 0xd0af, 0xad4b,
-0xc62c, 0xd7ec, 0xd118, 0xfacb, 0x32c8, 0x3cf8, 0x3893, 0x1827, 0x2a88, 0x2056,
-0xd2e0, 0xa9a8, 0xbc95, 0xe82d, 0xd209, 0xed42, 0x4049, 0x4bca, 0x27a4, 0x17b5,
-0x33c7, 0x048c, 0xc896, 0xbbc4, 0xb5e8, 0xde55, 0xe670, 0xf26e, 0x319d, 0x5284,
-0x20bb, 0x0a37, 0x3f54, 0x0425, 0xb7b6, 0xbeac, 0xc4a7, 0xd10a, 0xdf90, 0x067a,
-0x32d8, 0x4def, 0x29e9, 0x0de0, 0x33b8, 0x00f9, 0xbb53, 0xb44c, 0xca99, 0xdcb3,
-0xdf0d, 0x140a, 0x4211, 0x47c0, 0x2741, 0x1ffe, 0x3026, 0xf2ee, 0xc44d, 0xb8c2,
-0xcbde, 0xe86b, 0xed77, 0x1b4d, 0x47ee, 0x4766, 0x1ae9, 0x2386, 0x33e9, 0xea57,
-0xc4ae, 0xc182, 0xd3ec, 0xeae1, 0xf2fa, 0x1c99, 0x46ce, 0x4849, 0x16e5, 0x2357,
-0x2d0d, 0xe171, 0xc2b4, 0xc619, 0xdb43, 0xe861, 0xf96a, 0x2580, 0x41a1, 0x3fcc,
-0x14f6, 0x245e, 0x2692, 0xe3d9, 0xc4b2, 0xc084, 0xdcfb, 0xe481, 0xf277, 0x26e8,
-0x4453, 0x3677, 0x1401, 0x2eb5, 0x1c61, 0xda3a, 0xc536, 0xbbc2, 0xd95f, 0xe409,
-0xf088, 0x24e3, 0x4a50, 0x36ef, 0x1343, 0x3794, 0x1bd7, 0xd0b1, 0xbf04, 0xc0c0,
-0xd999, 0xe102, 0xfe57, 0x307b, 0x4c60, 0x3446, 0x110b, 0x34af, 0x1719, 0xd246,
-0xbe92, 0xc661, 0xdf01, 0xde95, 0x04b9, 0x34ae, 0x44b2, 0x2c3e, 0x140f, 0x311d,
-0x09e5, 0xcd57, 0xb673, 0xc4ea, 0xe8e6, 0xdfae, 0x02f2, 0x3c51, 0x460d, 0x2037,
-0x160e, 0x33a4, 0xffd5, 0xd044, 0xbb77, 0xbff6, 0xe547, 0xe2d3, 0x02a5, 0x3927,
-0x483e, 0x1e84, 0x18a8, 0x35a4, 0xf428, 0xc4b4, 0xb810, 0xbe31, 0xdf3f, 0xe3b9,
-0x070a, 0x3a6e, 0x4a01, 0x1d3d, 0x19b7, 0x312f, 0xe9ed, 0xb9d2, 0xb185, 0xc27d,
-0xdf74, 0xeaac, 0x163c, 0x40b2, 0x480f, 0x196b, 0x1a68, 0x2946, 0xe387, 0xbd44,
-0xb687, 0xcdd3, 0xe1c0, 0xe73f, 0x19c6, 0x454e, 0x4471, 0x1517, 0x1f37, 0x2415,
-0xde12, 0xbc28, 0xb193, 0xce92, 0xe199, 0xeb2a, 0x208d, 0x45c9, 0x3dfd, 0x140f,
-0x2554, 0x1b8d, 0xd3e4, 0xb631, 0xaeee, 0xd2a0, 0xe032, 0xeefc, 0x2bad, 0x4d46,
-0x3a27, 0x0f3b, 0x24c9, 0x111e, 0xcdbf, 0xb6b5, 0xb194, 0xd7c9, 0xe60a, 0xf93b,
-0x2f30, 0x4968, 0x3246, 0x1306, 0x2d46, 0x06e7, 0xc785, 0xba49, 0xb9ab, 0xde3a,
-0xe629, 0xff26, 0x3a02, 0x5456, 0x30f0, 0x10ea, 0x3149, 0x0578, 0xc92c, 0xbe07,
-0xc00c, 0xe26f, 0xec57, 0x0aaf, 0x3ec0, 0x560f, 0x2fbd, 0x16da, 0x3543, 0xfe12,
-0xc441, 0xbe1e, 0xce80, 0xec2a, 0xeeda, 0x1761, 0x467e, 0x531c, 0x2945, 0x16f3,
-0x30b3, 0xfa85, 0xc82a, 0xb95b, 0xd0b9, 0xf0bf, 0xecf0, 0x1a23, 0x4acc, 0x48e2,
-0x1c65, 0x1e4d, 0x2902, 0xe8e0, 0xc9c2, 0xbc2f, 0xd2c0, 0xf22e, 0xed1c, 0x1844,
-0x4b01, 0x4776, 0x146e, 0x2125, 0x2832, 0xde1c, 0xc52b, 0xbd52, 0xcf76, 0xec76,
-0xf496, 0x1c9f, 0x4726, 0x432c, 0x116f, 0x25e7, 0x2766, 0xd731, 0xbc99, 0xc162,
-0xd7c6, 0xe12d, 0xf3c2, 0x27ac, 0x489f, 0x3fb7, 0x11f9, 0x23e3, 0x1dd1, 0xd9f9,
-0xbc81, 0xbc41, 0xe051, 0xe6f9, 0xf6af, 0x2df2, 0x4613, 0x2fe6, 0x12b9, 0x303c,
-0x120f, 0xd130, 0xc1da, 0xbc62, 0xdb80, 0xe279, 0xf4be, 0x2c52, 0x4660, 0x275e,
-0x0d1c, 0x3149, 0x075f, 0xc931, 0xbf24, 0xbaf3, 0xd888, 0xe2cc, 0xfb8b, 0x2cb6,
-0x4a52, 0x29ea, 0x0caa, 0x3097, 0xff78, 0xbdf9, 0xb45b, 0xc1cb, 0xdd4e, 0xe310,
-0x068a, 0x24f2, 0x54ac, 0x60d2, 0x1650, 0xf4c6, 0xe059, 0xb014, 0x83b1, 0xbc91,
-0x02f9, 0x0157, 0x4fca, 0x7cb3, 0x41bb, 0x0df7, 0xea9f, 0xace6, 0x957f, 0xc6c1,
-0xb25c, 0xf25c, 0x6d4a, 0x3c23, 0x2274, 0x5314, 0x2754, 0xc59a, 0xd13d, 0xdf25,
-0xc110, 0x097d, 0xfee9, 0xe7e9, 0x4a58, 0x3073, 0xd0cf, 0x0834, 0x3f47, 0xde37,
-0xefad, 0x3de0, 0xef24, 0xe80f, 0x1519, 0xd4ff, 0xbae7, 0x160b, 0x1ed5, 0xf6f3,
-0x4a32, 0x391f, 0xed02, 0x1a95, 0x0194, 0xa798, 0xcdb4, 0x1870, 0xed7d, 0x0805,
-0x5609, 0x1649, 0x0c10, 0x37fb, 0xe698, 0xb602, 0x0ab1, 0x02bc, 0xc982, 0x29a0,
-0x3592, 0xeb4c, 0x26a0, 0x2b39, 0xc51e, 0xe028, 0x25df, 0xdd3d, 0xeb89, 0x3c7d,
-0xf25b, 0xf2a8, 0x40cd, 0xf67a, 0xbd91, 0x18e1, 0x1367, 0xcbf7, 0x1e2b, 0x2469,
-0xd608, 0x16f8, 0x2a0b, 0xc927, 0xe2cc, 0x37b1, 0xf346, 0xe694, 0x382d, 0xf93e,
-0xe10a, 0x2a89, 0xf6d1, 0xba9a, 0x1681, 0x2591, 0xd24e, 0x187c, 0x2fad, 0xd8f6,
-0x0b46, 0x2ae5, 0xc8c2, 0xd38a, 0x2a7a, 0xe7b1, 0xdcb3, 0x3e95, 0x03d8, 0xe5e1,
-0x3718, 0x0451, 0xb6fc, 0x05d7, 0x1636, 0xc589, 0x0c0d, 0x2d31, 0xe2a5, 0x145e,
-0x2ff3, 0xd16c, 0xd748, 0x2961, 0xeee4, 0xd89a, 0x2f77, 0x0413, 0xe432, 0x2a18,
-0x07e4, 0xbf90, 0xffac, 0x1a5c, 0xce43, 0x0eae, 0x3e2a, 0xe525, 0xfcdf, 0x3412,
-0xe19f, 0xc0d0, 0x160c, 0xf679, 0xdaf7, 0x3d0f, 0x184f, 0xe643, 0x3314, 0x0d97,
-0xa9d1, 0xf210, 0x1e09, 0xc374, 0x0591, 0x4995, 0xef24, 0x05bf, 0x3aa6, 0xdaf6,
-0xc1a1, 0x198b, 0xe5e1, 0xce1f, 0x40dc, 0x134c, 0xddc5, 0x3b68, 0x1d73, 0xb2c0,
-0xf385, 0x2228, 0xc6a9, 0xff0d, 0x4056, 0xea16, 0x071a, 0x3ca3, 0xd74b, 0xbcb1,
-0x210f, 0xf2c1, 0xcb2c, 0x414d, 0x1f07, 0xd958, 0x2f24, 0x195a, 0xa747, 0xe84d,
-0x2605, 0xc501, 0xff0e, 0x4e0a, 0xea48, 0x02a4, 0x46c5, 0xd723, 0xafda, 0x23af,
-0xf6a4, 0xbc7c, 0x3c45, 0x26f8, 0xdc74, 0x367d, 0x2543, 0xb0bd, 0xed3e, 0x27e5,
-0xc333, 0xf8e2, 0x4d51, 0xeb5f, 0xfefc, 0x4865, 0xe34b, 0xb937, 0x2748, 0x0266,
-0xc562, 0x3a6b, 0x25b1, 0xd774, 0x2daa, 0x2313, 0xb311, 0xef4a, 0x32e8, 0xcf60,
-0xf8b2, 0x51fb, 0xee07, 0xf368, 0x44ab, 0xe548, 0xb2da, 0x24f2, 0x07b3, 0xc446,
-0x3bc4, 0x2db3, 0xd779, 0x2ee4, 0x281e, 0xace1, 0xe4c5, 0x335a, 0xceab, 0xf17b,
-0x55c7, 0xf4d4, 0xf24d, 0x4603, 0xeb3d, 0xaf65, 0x1bbf, 0x08f3, 0xbf31, 0x300f,
-0x30d1, 0xd9cf, 0x29ba, 0x2ead, 0xb5b6, 0xdd53, 0x2dff, 0xcf0d, 0xe2d2, 0x4b14,
-0xf7cf, 0xf104, 0x48fe, 0xf5f9, 0xb102, 0x175c, 0x0bd9, 0xbcb2, 0x27b4, 0x336a,
-0xd7be, 0x2088, 0x3408, 0xbf37, 0xdc20, 0x3264, 0xdb9f, 0xe60e, 0x5013, 0xffb1,
-0xe856, 0x4281, 0xff01, 0xb10f, 0x1094, 0x176a, 0xc863, 0x243b, 0x390b, 0xdf6d,
-0x1d95, 0x3900, 0xc65f, 0xd25c, 0x2c3a, 0xe187, 0xdbeb, 0x465f, 0x0986, 0xeb79,
-0x4044, 0x0711, 0xb0da, 0x0496, 0x1513, 0xc287, 0x187b, 0x3c78, 0xe032, 0x1521,
-0x3c5f, 0xccc3, 0xcce1, 0x2b96, 0xe4ca, 0xd2ba, 0x430a, 0x0aa2, 0xdffc, 0x3ad9,
-0x0be5, 0xaea0, 0x03b6, 0x1ba6, 0xbbed, 0x0db5, 0x4113, 0xdc05, 0x05bb, 0x3a65,
-0xcc55, 0xc14b, 0x25ec, 0xe783, 0xd1d2, 0x4965, 0x1616, 0xdbb4, 0x3263, 0x0a8b,
-0xa569, 0xf7cf, 0x1f57, 0xc4d2, 0x1559, 0x517f, 0xea47, 0x0848, 0x3a1f, 0xc9f1,
-0xbb1e, 0x266f, 0xea60, 0xcd1c, 0x4d59, 0x23a6, 0xe328, 0x3b46, 0x19d2, 0xabe2,
-0xf47d, 0x1e1a, 0xbcd3, 0x09ed, 0x4fb3, 0xe964, 0x0dbc, 0x485b, 0xd3bb, 0xbbbe,
-0x2722, 0xffc5, 0xce39, 0x0d09, 0xfe2c, 0x112d, 0x596c, 0x16f5, 0xd170, 0x12a7,
-0x07ab, 0xa521, 0xd945, 0x0290, 0xcf7b, 0x0c60, 0x5af6, 0x3c64, 0x1c78, 0x2c17,
-0xf082, 0xb62e, 0xcf0c, 0xac7d, 0xba75, 0x27ac, 0x23af, 0xf129, 0x473d, 0x6f3b,
-0xefd4, 0xd0fc, 0xfcb5, 0xc5fa, 0xa532, 0xe2aa, 0x08ff, 0x0704, 0x304a, 0x21e6,
-0x0f85, 0x38c1, 0x010f, 0xbcdf, 0xd894, 0xf8ab, 0xd8c7, 0xe36a, 0x1b7a, 0x178e,
-0x1a72, 0x1741, 0x157f, 0x1dd4, 0x0dfe, 0xe47e, 0xbdd3, 0xf139, 0xe9ae, 0xc861,
-0x198e, 0x432e, 0x1c93, 0x1246, 0x4ca3, 0x23d4, 0xd5a3, 0xdda1, 0xc097, 0xcd1a,
-0xeddd, 0xed1a, 0x1738, 0x5658, 0x41b1, 0xfba0, 0x3319, 0x2a1d, 0xc048, 0xc0cf,
-0xd583, 0xd4c9, 0xdb7a, 0x070a, 0x2588, 0x3798, 0x3aa9, 0x0add, 0x25af, 0x2337,
-0xd4c2, 0xb504, 0xca8a, 0xe4dd, 0xd039, 0xf1df, 0x2bb9, 0x3c1d, 0x3426, 0x22ac,
-0x331f, 0x0f10, 0xdc7d, 0xbbe1, 0xb47c, 0xdb63, 0xd984, 0xfcbd, 0x450f, 0x5431,
-0x271a, 0x210b, 0x3c62, 0xf43d, 0xc565, 0xc201, 0xc114, 0xe4f6, 0xee9b, 0x085b,
-0x3cf5, 0x5653, 0x1e82, 0x0d52, 0x38a8, 0xf608, 0xc456, 0xce8b, 0xcfd1, 0xda08,
-0xf0f6, 0x16f4, 0x3014, 0x4610, 0x1a46, 0x0c35, 0x36d1, 0xfb60, 0xbc9c, 0xbcea,
-0xdb0c, 0xda74, 0xdb6c, 0x17ce, 0x3715, 0x33b3, 0x13c8, 0x1e7d, 0x290c, 0xe55b,
-0xb756, 0xb135, 0xdad6, 0xde70, 0xd336, 0x1782, 0x43a0, 0x29e5, 0x03f8, 0x2c8f,
-0x2768, 0xd396, 0xc0e1, 0xbc23, 0xccce, 0xdf32, 0xe829, 0x16bf, 0x4610, 0x3567,
-0x012e, 0x312c, 0x3059, 0xcf4c, 0xbc48, 0xcf7d, 0xdb0c, 0xd4f7, 0xefe3, 0x2327,
-0x3f5e, 0x34bf, 0x11d9, 0x3885, 0x2a09, 0xd700, 0xbd59, 0xc753, 0xde26, 0xd765,
-0xf612, 0x31cc, 0x45d3, 0x2d56, 0x17c3, 0x3e94, 0x16b7, 0xce82, 0xc389, 0xc8ab,
-0xdd9d, 0xdd82, 0xfe36, 0x3550, 0x4d5b, 0x2a45, 0x1384, 0x3ff2, 0x0ef3, 0xc81d,
-0xbe61, 0xcce9, 0xe4aa, 0xe0ab, 0x0699, 0x385e, 0x486b, 0x2294, 0x15f0, 0x3d85,
-0x01db, 0xc686, 0xc116, 0xcff5, 0xe34d, 0xe14b, 0x10c9, 0x3f07, 0x466b, 0x1f0d,
-0x1d05, 0x3ab5, 0xf8ef, 0xc8ce, 0xc05e, 0xd357, 0xe7d4, 0xe29f, 0x13df, 0x471a,
-0x4a47, 0x1c4c, 0x297f, 0x3e3f, 0xed74, 0xc6f8, 0xbfdc, 0xccde, 0xe3d5, 0xeaa0,
-0x19ee, 0x4b1b, 0x4d49, 0x1865, 0x2976, 0x37a0, 0xe1a2, 0xb9e8, 0xba35, 0xd299,
-0xde2b, 0xecfc, 0x27c6, 0x4ae2, 0x4564, 0x19a4, 0x28b5, 0x2426, 0xd885, 0xbc0a,
-0xb90e, 0xd777, 0xe284, 0xf34a, 0x2d9a, 0x4813, 0x38b9, 0x14ee, 0x2c67, 0x1894,
-0xd324, 0xbc7e, 0xb3bc, 0xda55, 0xe3e2, 0xef0a, 0x2fd7, 0x4da0, 0x2e6a, 0x0ee2,
-0x326e, 0x0fc1, 0xcb23, 0xbee7, 0xb82c, 0xdaac, 0xe70d, 0xf676, 0x2c96, 0x4efe,
-0x3180, 0x0f59, 0x3430, 0x0900, 0xc464, 0xbdf3, 0xbfd4, 0xdc18, 0xe54f, 0x02ac,
-0x346a, 0x4ca2, 0x2bdb, 0x0ba0, 0x2ca5, 0x00e4, 0xc0c2, 0xb4ae, 0xbea2, 0xdd3b,
-0xe1b5, 0x05e5, 0x36cd, 0x455d, 0x228c, 0x0f39, 0x2721, 0xf06a, 0xbe3c, 0xb625,
-0xc315, 0xe0db, 0xe130, 0x0824, 0x3af9, 0x4450, 0x1a04, 0x1254, 0x2a20, 0xeab7,
-0xbec0, 0xb857, 0xc3f1, 0xdf5a, 0xe831, 0x122e, 0x3daa, 0x44fa, 0x18f6, 0x1739,
-0x28bb, 0xe41d, 0xbbf3, 0xb89c, 0xcff6, 0xe5c1, 0xea00, 0x1c60, 0x45d5, 0x43ef,
-0x1c06, 0x2434, 0x292a, 0xe39e, 0xc2cb, 0xbd71, 0xd5c4, 0xe95c, 0xf5d3, 0x2a36,
-0x4b75, 0x403d, 0x1c75, 0x32bf, 0x27ef, 0xdda2, 0xcb76, 0xc7c5, 0xdb1a, 0xe84b,
-0xf612, 0x2b74, 0x5112, 0x4137, 0x18a7, 0x3889, 0x2791, 0xd8ed, 0xc90a, 0xc6c8,
-0xd83c, 0xe5cf, 0x01d1, 0x32e1, 0x4e08, 0x3e77, 0x1bcc, 0x39cc, 0x1bcb, 0xcf7c,
-0xbfad, 0xc693, 0xe1af, 0xe44a, 0x0379, 0x3b80, 0x5122, 0x34da, 0x12cd, 0x2ff7,
-0x0b3f, 0xcb7c, 0xb95e, 0xc0f4, 0xe555, 0xe1ce, 0x01a1, 0x3cc9, 0x475e, 0x2196,
-0x156a, 0x33d5, 0xf97d, 0xc4c1, 0xb9ed, 0xbd90, 0xe1db, 0xe24b, 0x021d, 0x3cfa,
-0x4dca, 0x1ea3, 0x12f7, 0x33e9, 0xf159, 0xbf15, 0xb984, 0xbdf4, 0xd9dc, 0xe483,
-0x0d28, 0x3bb5, 0x4aee, 0x1fcf, 0x1792, 0x2e75, 0xe773, 0xb55d, 0xaeed, 0xc525,
-0xdc07, 0xe07a, 0x162d, 0x403a, 0x41df, 0x18e6, 0x1816, 0x22ca, 0xe0d7, 0xba3f,
-0xab7d, 0xc6d9, 0xe296, 0xe464, 0x1a6b, 0x45ec, 0x3cb4, 0x1203, 0x21d7, 0x1e19,
-0xd553, 0xc042, 0xb44a, 0xca17, 0xe29f, 0xe893, 0x1a35, 0x457e, 0x3ca4, 0x0eee,
-0x274f, 0x1dc0, 0xd010, 0xbe2a, 0xb43a, 0xca4c, 0xe2e4, 0xf448, 0x246d, 0x4965,
-0x3fdb, 0x10f7, 0x25b8, 0x162e, 0xcca7, 0xb882, 0xb947, 0xd7a5, 0xe438, 0xfea1,
-0x33b7, 0x4cfe, 0x3b14, 0x1175, 0x24b7, 0x0bf7, 0xcecd, 0xbc06, 0xbdfc, 0xe81e,
-0xee24, 0x01b0, 0x3af8, 0x476e, 0x28b0, 0x20d9, 0x3412, 0xf8f1, 0xc8c9, 0xbcf1,
-0xbe75, 0xed66, 0xf061, 0x0477, 0x2e04, 0x4a13, 0x58d9, 0x3473, 0x0a86, 0xde23,
-0xc927, 0xa391, 0xa85a, 0xfd01, 0x01c0, 0x26a1, 0x8016, 0x6b60, 0x1f2e, 0x05f0,
-0xdab1, 0x948b, 0xb8c2, 0xc47d, 0xcb07, 0x3e6c, 0x61b3, 0x38d1, 0x421e, 0x423b,
-0xe147, 0xbac6, 0xe0e9, 0xbe22, 0xd9dd, 0x0b3a, 0x03de, 0x31f4, 0x40dc, 0xf8e0,
-0xf398, 0x2cdd, 0xec3a, 0xc582, 0x25ea, 0x1c58, 0xd8cd, 0x0700, 0x13d5, 0xbffb,
-0xdfbf, 0x2eeb, 0xf5a6, 0x0a90, 0x5506, 0x0dfc, 0xf5d4, 0x194f, 0xd0b1, 0xa469,
-0xf944, 0x0659, 0xe225, 0x3e8d, 0x4455, 0xf804, 0x285d, 0x16e8, 0xac54, 0xcbe6,
-0x0dc1, 0xcfa2, 0xef3a, 0x51ba, 0x0cea, 0x02d9, 0x4169, 0xec8e, 0xb42c, 0x04b3,
-0xfdcb, 0xc5c1, 0x233b, 0x2fa0, 0xe530, 0x27ec, 0x2937, 0xc096, 0xdeaa, 0x2435,
-0xe010, 0xe6f7, 0x3e0a, 0xfd91, 0xeb2e, 0x333b, 0xf30c, 0xb2be, 0x1250, 0x1fd9,
-0xc7fa, 0x1877, 0x3b5d, 0xdbdb, 0x0644, 0x23bb, 0xbdc0, 0xcc54, 0x2f0c, 0xf1f3,
-0xe57b, 0x48e5, 0x082c, 0xe598, 0x360e, 0xf80f, 0xa876, 0x0659, 0x1b42, 0xc57b,
-0x1fb9, 0x48cb, 0xe657, 0x1591, 0x3682, 0xcb26, 0xccd4, 0x2692, 0xe8fa, 0xda38,
-0x445f, 0x1220, 0xf0e0, 0x3d8f, 0x09d0, 0xb6bc, 0x00e1, 0x260a, 0xd188, 0x0576,
-0x3935, 0xef31, 0x1179, 0x33e9, 0xd401, 0xcde0, 0x2d56, 0xfa21, 0xdbb0, 0x4a3c,
-0x1c17, 0xdc92, 0x334e, 0x1ceb, 0xb17d, 0xebbf, 0x27e0, 0xd919, 0x0f7e, 0x4a4b,
-0xf20c, 0x107b, 0x3a20, 0xcab0, 0xba0a, 0x24cb, 0xf1fa, 0xcaf2, 0x3f6a, 0x2005,
-0xe495, 0x30ba, 0x16ef, 0xb7a7, 0xec01, 0x1401, 0xc9b7, 0x05b6, 0x393b, 0xe12d,
-0x07bf, 0x44cb, 0xdee8, 0xbd85, 0x23f1, 0xfc20, 0xc5f2, 0x2bd6, 0x194b, 0xdfc0,
-0x26e3, 0x160b, 0xba3e, 0xf25d, 0x2457, 0xcdc4, 0x004b, 0x4634, 0xe4dc, 0xf4a7,
-0x3d04, 0xdcc3, 0xb397, 0x1fb0, 0x0021, 0xcbc7, 0x37a0, 0x223d, 0xdd2e, 0x2e4a,
-0x1e22, 0xae9d, 0xea89, 0x28db, 0xc94f, 0xf4c9, 0x4a0c, 0xf565, 0xfefa, 0x4525,
-0xee89, 0xbfb1, 0x1b8b, 0xfa5c, 0xc436, 0x2f51, 0x24ca, 0xdfcd, 0x2cf4, 0x2a31,
-0xbd55, 0xe94e, 0x2b96, 0xd147, 0xee2f, 0x4235, 0xf2bf, 0xf601, 0x3b75, 0xe821,
-0xb876, 0x1f6c, 0x056a, 0xc597, 0x378b, 0x2e60, 0xd377, 0x1e9d, 0x283c, 0xb892,
-0xdee1, 0x2781, 0xd1f0, 0xf4ba, 0x554c, 0x0123, 0xf9be, 0x420b, 0xea52, 0xaa76,
-0x121d, 0x04f0, 0xbdca, 0x333f, 0x4315, 0xe753, 0x27d8, 0x325a, 0xb873, 0xd272,
-0x2388, 0xcf65, 0xe913, 0x57fe, 0x07f4, 0xf542, 0x4773, 0xf6c7, 0xab18, 0x11a2,
-0x0c42, 0xb926, 0x2816, 0x3c96, 0xde7c, 0x28fb, 0x3ab1, 0xb843, 0xd1f6, 0x2e08,
-0xd30e, 0xdd67, 0x552d, 0x04b1, 0xe6f1, 0x4408, 0xfac7, 0xa436, 0x0956, 0x1138,
-0xb9e0, 0x267a, 0x42e3, 0xd676, 0x199d, 0x3443, 0xb086, 0xc200, 0x28e5, 0xda7a,
-0xd827, 0x53d9, 0x0bab, 0xe3c1, 0x40a6, 0xfc98, 0xa29e, 0x018f, 0x1105, 0xb6e7,
-0x1b43, 0x498c, 0xdd00, 0x1541, 0x4138, 0xc0de, 0xbf2e, 0x283d, 0xe09c, 0xce50,
-0x4aa8, 0x1053, 0xdfdb, 0x3f0a, 0x0676, 0xa0c4, 0xfe21, 0x1b86, 0xb753, 0x10a7,
-0x4958, 0xd934, 0x0821, 0x3f0a, 0xc34f, 0xba57, 0x2b9e, 0xe817, 0xc7b8, 0x46a9,
-0x0faa, 0xd39d, 0x38e6, 0x0b67, 0x9f2e, 0xfa87, 0x2298, 0xbafd, 0x0a31, 0x466b,
-0xd41d, 0xfd51, 0x3a2b, 0xc101, 0xb40d, 0x2b20, 0xef1f, 0xc9c0, 0x46b9, 0x10a8,
-0xce9c, 0x3371, 0x097d, 0x9c55, 0xf5c4, 0x3090, 0xd2df, 0xecd4, 0x147e, 0xe806,
-0x2e2d, 0x4ebd, 0xe525, 0xe179, 0x26a7, 0xd61d, 0xaa44, 0x0053, 0xe8dc, 0xe136,
-0x46b6, 0x57fc, 0x24b5, 0x2da9, 0x235d, 0xcd31, 0xca81, 0xd1c7, 0xaf26, 0xfdb0,
-0x3bad, 0x09ac, 0x1da0, 0x74cf, 0x3a9c, 0xd9e6, 0xf662, 0xf1b3, 0xb74e, 0xc78b,
-0x079d, 0x1303, 0x25f7, 0x3f88, 0x14f4, 0x2459, 0x2c9b, 0xdd69, 0xc8da, 0xfb0c,
-0xfc56, 0xd94a, 0x0b6d, 0x29c0, 0x150a, 0x22e5, 0x1d92, 0x18ef, 0x1cfc, 0x0c23,
-0xcdc3, 0xcd7b, 0x0116, 0xd225, 0xea05, 0x3ecf, 0x321c, 0x114b, 0x3429, 0x4818,
-0xf80f, 0xe0f6, 0xd86d, 0xb88f, 0xe34c, 0xec85, 0xf335, 0x37f0, 0x5dfb, 0x1c42,
-0x11db, 0x4f23, 0xfc26, 0xba44, 0xd5aa, 0xd324, 0xd1fd, 0xf17c, 0x1856, 0x276a,
-0x4692, 0x286a, 0x0ba3, 0x3d7b, 0x1150, 0xc1ac, 0xbdf0, 0xe136, 0xd542, 0xcf26,
-0x1384, 0x2faf, 0x3870, 0x2e2c, 0x2318, 0x28d4, 0xfdee, 0xcb16, 0xa730, 0xc88d,
-0xdb00, 0xceb6, 0x1995, 0x4d9d, 0x384a, 0x1a5c, 0x3253, 0x2473, 0xd8f1, 0xc53c,
-0xafa7, 0xc440, 0xe9ed, 0xe807, 0x176e, 0x51f8, 0x4372, 0x074b, 0x2912, 0x2b6d,
-0xcf1e, 0xc37a, 0xc518, 0xc3a3, 0xdc9c, 0xfa3e, 0x1a98, 0x40fa, 0x4783, 0x0983,
-0x2539, 0x3545, 0xd15a, 0xad3e, 0xc7ca, 0xd8f8, 0xd06d, 0xf96a, 0x3340, 0x3d0f,
-0x375f, 0x19a1, 0x2cbe, 0x2480, 0xd619, 0xaa0f, 0xbfde, 0xe9c8, 0xd157, 0xf05e,
-0x42af, 0x4a8c, 0x2ada, 0x1e55, 0x372a, 0x09e1, 0xcd35, 0xbbbe, 0xb8fb, 0xe193,
-0xe480, 0xf329, 0x3476, 0x51aa, 0x233d, 0x1102, 0x44ce, 0x08c4, 0xbbca, 0xc158,
-0xc692, 0xd1e1, 0xdde2, 0x0656, 0x33cd, 0x4f74, 0x2ddc, 0x0f4d, 0x394e, 0x09e6,
-0xbe5c, 0xb5ad, 0xcc4d, 0xdc27, 0xdab2, 0x1043, 0x3ea4, 0x479b, 0x2b41, 0x1d61,
-0x308b, 0xf8bb, 0xc464, 0xb735, 0xcd64, 0xe75e, 0xe437, 0x161f, 0x4870, 0x48ad,
-0x1c9b, 0x1ea2, 0x33d1, 0xf0d7, 0xc828, 0xc0cf, 0xd2aa, 0xe99c, 0xeb83, 0x1a23,
-0x47fe, 0x4a7b, 0x1905, 0x1e38, 0x324a, 0xe958, 0xc1e9, 0xc325, 0xd7e4, 0xe635,
-0xf2dc, 0x2267, 0x3faa, 0x415f, 0x1a59, 0x202f, 0x2852, 0xe889, 0xc4bd, 0xbe6c,
-0xdab6, 0xe56a, 0xef10, 0x26eb, 0x4556, 0x3a6e, 0x180a, 0x2a09, 0x1fb9, 0xde8b,
-0xc5cf, 0xb9e8, 0xd7a7, 0xe7b9, 0xedd9, 0x2300, 0x49df, 0x37d1, 0x12a8, 0x2f9a,
-0x18aa, 0xce1b, 0xbdb0, 0xbc6b, 0xd29e, 0xdeee, 0xf71a, 0x2781, 0x45f4, 0x339d,
-0x0ccf, 0x2b8f, 0x12d6, 0xc8e8, 0xb6b6, 0xbda1, 0xd3af, 0xd912, 0xfe42, 0x2d6d,
-0x3ef8, 0x304b, 0x1689, 0x29cf, 0x067c, 0xcba1, 0xb57d, 0xbede, 0xdf90, 0xdc36,
-0xfffb, 0x3465, 0x3c40, 0x2128, 0x1a44, 0x31e1, 0xfd23, 0xcc9c, 0xbac3, 0xbc48,
-0xdd17, 0xde23, 0xfd31, 0x3137, 0x4362, 0x1eee, 0x18fc, 0x32b8, 0xf20e, 0xc5cc,
-0xbb44, 0xbdcc, 0xd9bd, 0xe2e3, 0x076b, 0x353c, 0x4892, 0x1e7b, 0x18f6, 0x30cf,
-0xea76, 0xbae7, 0xb387, 0xc4fa, 0xdcc0, 0xe7b8, 0x15fe, 0x3d5b, 0x45ed, 0x199f,
-0x192d, 0x2670, 0xe39c, 0xbd23, 0xb49a, 0xce79, 0xe000, 0xe7b3, 0x1c0b, 0x42fb,
-0x4231, 0x1500, 0x214f, 0x24b7, 0xddd0, 0xbdaf, 0xb443, 0xd1d6, 0xe488, 0xf035,
-0x248c, 0x481a, 0x412e, 0x17e3, 0x2a09, 0x1e55, 0xd730, 0xbb6d, 0xb458, 0xd6fe,
-0xe4f4, 0xf65d, 0x30dd, 0x50e1, 0x3ee0, 0x15ff, 0x2a77, 0x133f, 0xd208, 0xbb41,
-0xb5d0, 0xdc9b, 0xea0f, 0xfe2e, 0x33e8, 0x4ec6, 0x3729, 0x17b0, 0x327e, 0x0ae7,
-0xcbb1, 0xbd40, 0xbbb0, 0xe021, 0xe92f, 0x0274, 0x3a54, 0x53fa, 0x3201, 0x1417,
-0x340a, 0x073d, 0xcaf8, 0xbd21, 0xbddc, 0xdfe9, 0xebda, 0x0cee, 0x3df0, 0x5410,
-0x3025, 0x16c7, 0x32e0, 0xfb90, 0xc1f6, 0xbac8, 0xcb01, 0xe852, 0xeb00, 0x14bb,
-0x4362, 0x4e09, 0x267e, 0x175e, 0x2ea6, 0xf673, 0xc679, 0xb7ca, 0xce42, 0xef38,
-0xea88, 0x19da, 0x4c19, 0x4976, 0x1f9b, 0x2155, 0x2984, 0xe747, 0xc939, 0xbc60,
-0xced0, 0xf05b, 0xef4a, 0x1a1b, 0x4d06, 0x49db, 0x1707, 0x21a4, 0x261f, 0xdb58,
-0xc42f, 0xbd07, 0xcd03, 0xeb57, 0xf6f1, 0x1fe4, 0x4885, 0x45cb, 0x1391, 0x2121,
-0x232c, 0xd7ec, 0xbd29, 0xbf59, 0xd799, 0xe575, 0xf6b7, 0x28c6, 0x4774, 0x3e39,
-0x1137, 0x1ef7, 0x1744, 0xd610, 0xbc35, 0xb9e4, 0xdd70, 0xe860, 0xf41e, 0x2929,
-0x4423, 0x2e1c, 0x110a, 0x2d77, 0x0e41, 0xced2, 0xc1cd, 0xbb1d, 0xd9b8, 0xe41e,
-0xf4ed, 0x2b8f, 0x4959, 0x2b92, 0x0f36, 0x32ac, 0x0962, 0xc983, 0xc063, 0xbadd,
-0xd65d, 0xe557, 0xfe42, 0x2c4a, 0x49b0, 0x2cc4, 0x11af, 0x335e, 0x0099, 0xbfb6,
-0xb950, 0xc282, 0xda13, 0xe2c3, 0x0c6b, 0x2301, 0x3d0d, 0x5b32, 0x2bf1, 0xf816,
-0xd811, 0xc694, 0x94e5, 0xa76b, 0x02b3, 0xf90f, 0x23f0, 0x863b, 0x6a8b, 0x1164,
-0xf826, 0xd412, 0x8d7c, 0xade7, 0xbb44, 0xce06, 0x446e, 0x60cd, 0x37d3, 0x464b,
-0x4603, 0xdb1a, 0xadc9, 0xd748, 0xbb79, 0xd2d1, 0x0130, 0x0928, 0x3b0a, 0x4390,
-0x0002, 0xef18, 0x25c7, 0xf662, 0xbcac, 0x1201, 0x1f14, 0xda32, 0xff28, 0x1fbe,
-0xd1ed, 0xd6db, 0x389e, 0x0dbf, 0xf3fb, 0x488e, 0x1c7e, 0xe70e, 0x1374, 0xed9e,
-0xa6a3, 0xedff, 0x24fa, 0xe3d7, 0x2454, 0x55ff, 0xfbf6, 0x19ad, 0x27e2, 0xbe48,
-0xc206, 0x1296, 0xe45b, 0xdd35, 0x4db6, 0x1c33, 0xef46, 0x4348, 0x0b24, 0xb5eb,
-0xf732, 0x126a, 0xcd2b, 0x063c, 0x37c5, 0xec01, 0x18d9, 0x3cc8, 0xd616, 0xd2bc,
-0x273a, 0xf84b, 0xd381, 0x30e7, 0x1385, 0xdff9, 0x30f4, 0x18b0, 0xc10e, 0x0696,
-0x364d, 0xd762, 0xfbf8, 0x3d8c, 0xe397, 0xf63d, 0x3932, 0xe0e0, 0xc7fb, 0x31c6,
-0x0e47, 0xd472, 0x33f1, 0x19cb, 0xd9b6, 0x297e, 0x174d, 0xb770, 0xf385, 0x2b80,
-0xd844, 0x020b, 0x44ae, 0xecdc, 0xffc6, 0x3c84, 0xe59b, 0xc239, 0x1b9c, 0x03d8,
-0xcdfc, 0x284d, 0x2050, 0xe856, 0x29ba, 0x1da6, 0xc79c, 0xf13e, 0x2a8b, 0xdb89,
-0xe7cf, 0x315a, 0xf321, 0xf5f9, 0x332c, 0xf230, 0xc508, 0x1566, 0x093d, 0xce9a,
-0x23e7, 0x1dac, 0xd1bc, 0x1aa1, 0x2c3b, 0xbf9a, 0xd5cb, 0x286f, 0xe374, 0xeccb,
-0x3bb8, 0xfa4b, 0xf5e8, 0x2f2d, 0xe9fe, 0xbb23, 0x0ce2, 0xff3a, 0xc469, 0x2484,
-0x2c01, 0xe186, 0x1b3d, 0x26db, 0xc966, 0xd43c, 0x0cf6, 0xd3cc, 0xeaf1, 0x349d,
-0xf49e, 0xfa1b, 0x3da3, 0xf2ae, 0xb5a2, 0x09f1, 0x0303, 0xbee6, 0x1c15, 0x2f77,
-0xe137, 0x187e, 0x2a96, 0xc3d0, 0xd414, 0x1e88, 0xd685, 0xe774, 0x4a59, 0xfa19,
-0xe6e2, 0x3f71, 0xf365, 0xa657, 0x0aac, 0x0b27, 0xbbf9, 0x22a4, 0x3896, 0xdde2,
-0x1ea6, 0x2ddb, 0xb6a3, 0xcf13, 0x234d, 0xd209, 0xdfcd, 0x4de4, 0x0530, 0xf235,
-0x458e, 0xfe1c, 0xaf9c, 0x04ff, 0x0ba8, 0xc04a, 0x1dfe, 0x3a8f, 0xe44e, 0x1ebd,
-0x3786, 0xc838, 0xd340, 0x2d49, 0xe462, 0xdc75, 0x4606, 0x05e5, 0xe8d6, 0x3e07,
-0x0367, 0xb349, 0x0d09, 0x1be3, 0xc56a, 0x2148, 0x4004, 0xd8d7, 0x1595, 0x3a7d,
-0xc56d, 0xd126, 0x3261, 0xe7bb, 0xe124, 0x5308, 0x0eb8, 0xeb26, 0x437a, 0x042c,
-0xaf26, 0x0eb2, 0x218d, 0xc6ad, 0x22c2, 0x4ab9, 0xe2d2, 0x1874, 0x40cd, 0xca8d,
-0xc838, 0x2e68, 0xedb9, 0xd7fa, 0x4c7a, 0x1526, 0xe7cb, 0x4150, 0x0c9e, 0xae99,
-0x0430, 0x20bb, 0xc1b5, 0x1187, 0x47d4, 0xe4da, 0x1440, 0x42ec, 0xcdff, 0xc6df,
-0x2c13, 0xec08, 0xd2d5, 0x46ed, 0x0ef1, 0xdd36, 0x3d9e, 0x0f6f, 0xadf9, 0x0331,
-0x2434, 0xc516, 0x0f43, 0x4485, 0xde32, 0x0700, 0x3d61, 0xce91, 0xbeff, 0x2926,
-0xf4fa, 0xd134, 0x41a9, 0x1664, 0xdc49, 0x34e2, 0x1333, 0xace3, 0xf361, 0x1f70,
-0xc693, 0x0699, 0x47e9, 0xe934, 0x0537, 0x4024, 0xd7ae, 0xba09, 0x1da8, 0xf1cd,
-0xcbb4, 0x3981, 0x188e, 0xddeb, 0x326b, 0x1892, 0xb095, 0xf130, 0x20bc, 0xc29d,
-0xf9a7, 0x3f9b, 0xe3d4, 0xfb7a, 0x3e64, 0xdf3d, 0xbe59, 0x2395, 0xf6d6, 0xc4b9,
-0x3386, 0x1936, 0xd767, 0x2b7a, 0x1dd1, 0xb547, 0xeefe, 0x2814, 0xcaa5, 0xf817,
-0x487c, 0xeb89, 0xf26b, 0x397c, 0xdf7f, 0xb39b, 0x1c04, 0xfe68, 0xc54d, 0x349f,
-0x2a68, 0xdbdd, 0x22d6, 0x1ddd, 0xb0a0, 0xe0fa, 0x21cc, 0xc993, 0xf898, 0x52ec,
-0xf689, 0xf70a, 0x426a, 0xe741, 0xaf61, 0x151d, 0xf921, 0xc0cc, 0x3886, 0x3002,
-0xdf54, 0x2dc5, 0x25fe, 0xb022, 0xe019, 0x2b01, 0xdc46, 0xdf34, 0x113b, 0xf3ef,
-0x2b9e, 0x5380, 0xf6a9, 0xdedb, 0x2143, 0xe2d9, 0xa1ed, 0xf09b, 0xf0dc, 0xdb67,
-0x3407, 0x5e55, 0x32ca, 0x27e1, 0x25c5, 0xd709, 0xc36a, 0xcfc9, 0xa7f8, 0xea51,
-0x3bd7, 0x0e16, 0x0801, 0x6978, 0x4f5b, 0xdcee, 0xefc1, 0xfe47, 0xbe36, 0xbc03,
-0xf6fb, 0x0a54, 0x1b49, 0x3bd0, 0x15ec, 0x2382, 0x3cb2, 0xeb19, 0xc5aa, 0xedb7,
-0xf957, 0xd7a6, 0xf768, 0x22e7, 0x17a3, 0x2061, 0x1ba7, 0x1fd9, 0x23d8, 0x0c01,
-0xd667, 0xc4b5, 0xfb1e, 0xd994, 0xd7e9, 0x3398, 0x3e92, 0x166b, 0x27af, 0x4ec2,
-0x0515, 0xd7d3, 0xde1a, 0xb994, 0xdcbe, 0xf079, 0xeced, 0x2d31, 0x5f61, 0x253a,
-0x040a, 0x4aa6, 0x0dcf, 0xb7f1, 0xcf3e, 0xd1b1, 0xcf61, 0xe63f, 0x105c, 0x26cc,
-0x431a, 0x31ef, 0x089d, 0x3279, 0x1505, 0xc9c8, 0xbc77, 0xd253, 0xdbe3, 0xd185,
-0x028c, 0x2ef7, 0x3d5b, 0x2ff3, 0x2436, 0x2ecc, 0xffae, 0xd27d, 0xae72, 0xb7bb,
-0xda8b, 0xd2ea, 0x0b5f, 0x4d03, 0x43e6, 0x19f3, 0x2a63, 0x2e3d, 0xdc83, 0xc2d3,
-0xb8a6, 0xbf1e, 0xe681, 0xe9fe, 0x0c02, 0x47ed, 0x4b9b, 0x0b96, 0x1c09, 0x3193,
-0xdad3, 0xc2e7, 0xcba3, 0xc7a2, 0xd979, 0xf765, 0x1768, 0x34eb, 0x4272, 0x0e6d,
-0x1cba, 0x35bf, 0xe2f7, 0xb4ec, 0xc2dc, 0xdbc9, 0xd4b0, 0xeaf5, 0x2a04, 0x3d45,
-0x3135, 0x163c, 0x29bf, 0x1de9, 0xd862, 0xb512, 0xbc25, 0xe60f, 0xdb2d, 0xe4e1,
-0x2e4c, 0x46ed, 0x2280, 0x0c95, 0x3390, 0x0dba, 0xc912, 0xc227, 0xbe99, 0xd9c1,
-0xe290, 0xed33, 0x2239, 0x44f4, 0x1ed4, 0x0166, 0x3720, 0x122c, 0xc1e5, 0xbe0b,
-0xcc00, 0xd5f1, 0xd17f, 0xf3b3, 0x23a2, 0x3db4, 0x2624, 0x0cc4, 0x33e1, 0x1023,
-0xc9ae, 0xb631, 0xc8cd, 0xdd8a, 0xceea, 0xfaf7, 0x3621, 0x3ded, 0x1ca5, 0x1b0d,
-0x3ba6, 0x0216, 0xce92, 0xc394, 0xc90e, 0xdd1a, 0xd9c7, 0x0438, 0x3a3b, 0x43f5,
-0x193b, 0x1b93, 0x427f, 0xfe8c, 0xc66d, 0xc591, 0xd58c, 0xe393, 0xe1bc, 0x0fe2,
-0x3df6, 0x448e, 0x1c8a, 0x21c0, 0x3e71, 0xf9bd, 0xc96f, 0xc456, 0xd5d9, 0xe4b5,
-0xe922, 0x1ce5, 0x418b, 0x417b, 0x1d09, 0x2518, 0x341d, 0xf03a, 0xcbea, 0xc1e1,
-0xd6e8, 0xe7f3, 0xe55f, 0x1d2e, 0x4954, 0x3f9e, 0x1b23, 0x31e7, 0x3163, 0xe580,
-0xcb7b, 0xbe90, 0xd27b, 0xe98e, 0xede5, 0x22f3, 0x51cc, 0x440f, 0x174a, 0x3744,
-0x308b, 0xdab4, 0xc2e8, 0xc03f, 0xd50d, 0xe3f9, 0xf766, 0x2e0e, 0x4fbc, 0x4269,
-0x17f2, 0x2ec2, 0x1f55, 0xd524, 0xbca2, 0xbb93, 0xda21, 0xe34e, 0xfad1, 0x31b6,
-0x47da, 0x36e7, 0x19ff, 0x2ef6, 0x0ef3, 0xd0a0, 0xb94c, 0xb54a, 0xdd97, 0xe171,
-0xf86b, 0x35bc, 0x47ba, 0x2983, 0x1694, 0x3324, 0x023b, 0xc961, 0xbc03, 0xb2d4,
-0xd7d9, 0xe2e7, 0xf9f7, 0x3391, 0x4b1a, 0x23f3, 0x1255, 0x2f9f, 0xf2dd, 0xbf1b,
-0xb8c8, 0xb595, 0xd67b, 0xe49e, 0x04eb, 0x3553, 0x491e, 0x20bc, 0x101c, 0x2d09,
-0xefb9, 0xbc9b, 0xb456, 0xbc74, 0xdcb8, 0xe7e3, 0x1085, 0x3e2d, 0x4862, 0x20a4,
-0x178e, 0x24e7, 0xe5be, 0xbfc5, 0xb5ac, 0xc6ce, 0xe4c1, 0xe9df, 0x156b, 0x41e6,
-0x4347, 0x169b, 0x1dcf, 0x2537, 0xdbdb, 0xbd60, 0xb4ac, 0xc74f, 0xe58f, 0xf1d1,
-0x1bdb, 0x438d, 0x41e3, 0x1215, 0x1c5f, 0x197b, 0xd34e, 0xbb05, 0xb7f2, 0xd3b2,
-0xe362, 0xf0f9, 0x2581, 0x46a8, 0x3c22, 0x115f, 0x2009, 0x122f, 0xd304, 0xbd34,
-0xb54b, 0xd890, 0xe911, 0xf7d8, 0x2be6, 0x4644, 0x3124, 0x11c4, 0x2d7b, 0x0ee0,
-0xcfc2, 0xc445, 0xbf59, 0xdf01, 0xe6a3, 0xf6fe, 0x2fa7, 0x4f24, 0x32c6, 0x10fe,
-0x360f, 0x14d0, 0xd1fe, 0xc5f6, 0xc3cd, 0xdf16, 0xe84d, 0x00f9, 0x3302, 0x4f34,
-0x330f, 0x190f, 0x3c38, 0x0f70, 0xcd2f, 0xc1c9, 0xccf8, 0xe5e1, 0xe528, 0x0d0a,
-0x3fdc, 0x4c89, 0x2965, 0x1572, 0x3558, 0x0773, 0xcf30, 0xbe56, 0xcfa1, 0xeeb4,
-0xe390, 0x0d40, 0x446b, 0x47d6, 0x22c9, 0x1f4d, 0x33f7, 0xf611, 0xcd9c, 0xbd57,
-0xc66d, 0xec7d, 0xe7bf, 0x0df9, 0x474d, 0x4b43, 0x1b2f, 0x1f2d, 0x35f1, 0xea3c,
-0xc455, 0xbc6b, 0xc16f, 0xe41e, 0xef9d, 0x16e5, 0x457b, 0x4d9b, 0x1df1, 0x2052,
-0x310e, 0xe35e, 0xbd3b, 0xbe4a, 0xd17b, 0xe63a, 0xf0dd, 0x2445, 0x4bde, 0x4c1f,
-0x20d2, 0x25a1, 0x2da1, 0xe9a8, 0xc288, 0xb909, 0xd9c6, 0xee3e, 0xf6a6, 0x2ef9,
-0x50a3, 0x43ee, 0x1dd3, 0x2eed, 0x2309, 0xe027, 0xcabc, 0xbd16, 0xdbde, 0xee25,
-0xf339, 0x2c27, 0x5390, 0x40a0, 0x1b96, 0x375c, 0x1d2b, 0xd734, 0xc78b, 0xb807,
-0xd541, 0xecee, 0xfe54, 0x2fa0, 0x5361, 0x3f28, 0x1522, 0x3393, 0x1266, 0xc88d,
-0xbc85, 0xb8d2, 0xd4a8, 0xe5ab, 0x0438, 0x3396, 0x4c0c, 0x33cd, 0x0a79, 0x2169,
-0xfe45, 0xc2f1, 0xb2f9, 0xb954, 0xe0e9, 0xe165, 0x029e, 0x2aa5, 0x318e, 0x465f,
-0x33d0, 0x0444, 0xd0f3, 0xc734, 0xa46c, 0x9309, 0xec1b, 0xfbdf, 0x010e, 0x6440,
-0x7e13, 0x1ed8, 0xeedd, 0xe7dd, 0x9c36, 0x94bd, 0xaeea, 0xb4e6, 0x08d9, 0x4ccc,
-0x44d3, 0x3995, 0x43b3, 0xfbc8, 0xa9f8, 0xbc47, 0xb7e9, 0xb05c, 0xd4b9, 0x0205,
-0x2fad, 0x38f1, 0x145d, 0xf759, 0x0aec, 0xf6cf, 0xb93a, 0xdb0a, 0x14b9, 0xe52f,
-0xdb64, 0x2275, 0xfc04, 0xc169, 0x1482, 0x2708, 0xda58, 0x13ad, 0x34f3, 0xe68c,
-0xf5c6, 0x0b27, 0xbfca, 0xc11f, 0x1a39, 0xf895, 0xf15a, 0x535e, 0x1fbe, 0xfd1c,
-0x2fab, 0xeb46, 0xb207, 0xf114, 0xfe7d, 0xd0f4, 0x2a5f, 0x4be3, 0xf98f, 0x2db3,
-0x365b, 0xcbe5, 0xd12f, 0x160e, 0xe93e, 0xe29c, 0x4478, 0x1d6f, 0x0413, 0x49f1,
-0x0cdb, 0xc582, 0x08ff, 0x1ce3, 0xd295, 0x10d4, 0x44fb, 0xeff9, 0x15bb, 0x4310,
-0xddfd, 0xd8c9, 0x34f7, 0xfaaf, 0xd716, 0x4457, 0x1cff, 0xe28a, 0x3514, 0x1237,
-0xb5a9, 0x01cc, 0x3075, 0xd90a, 0x1130, 0x4b8f, 0xf1cd, 0x0fee, 0x37f4, 0xcf77,
-0xc32c, 0x262d, 0xfb1f, 0xde11, 0x4cfa, 0x220f, 0xe7b6, 0x379f, 0x1630, 0xb473,
-0xeb2b, 0x1f40, 0xcdde, 0xfb49, 0x44ba, 0xf7a8, 0x0b44, 0x3ad4, 0xdf56, 0xbc11,
-0x192e, 0xfdae, 0xc1e6, 0x2be2, 0x260a, 0xe13b, 0x285b, 0x1e09, 0xb912, 0xe471,
-0x2223, 0xd36d, 0xfe2f, 0x46c5, 0xe36b, 0xf7a8, 0x4755, 0xdf55, 0xa7b3, 0x1a23,
-0x0b84, 0xc893, 0x2faf, 0x2991, 0xe2bb, 0x2481, 0x13cb, 0xb383, 0xe0a3, 0x1702,
-0xc7e4, 0xf45d, 0x4b67, 0xf6a6, 0xf97a, 0x3e6f, 0xecd9, 0xadf3, 0xfeb4, 0xfd06,
-0xc788, 0x1f7a, 0x200a, 0xe5ba, 0x31ba, 0x2511, 0xb3da, 0xe100, 0x2776, 0xc990,
-0xe1ba, 0x44f0, 0xef0a, 0xe6e3, 0x3c2c, 0xf024, 0xb397, 0x1376, 0x054e, 0xc2a5,
-0x2c7f, 0x2067, 0xc5d1, 0x227f, 0x2507, 0xa6ee, 0xd8b4, 0x2da2, 0xd0d2, 0xe5d2,
-0x4ae3, 0xf3c8, 0xec01, 0x3d1d, 0xe4c8, 0xa76d, 0x0cd7, 0x02fe, 0xc051, 0x2a3f,
-0x2ff4, 0xd96d, 0x206e, 0x2cdb, 0xbcc2, 0xcfce, 0x1d9e, 0xd936, 0xe286, 0x3c62,
-0xf899, 0xf161, 0x4188, 0xfacc, 0xb89c, 0x13b2, 0x0f18, 0xbfc2, 0x1908, 0x2b9b,
-0xdd40, 0x1c58, 0x31c8, 0xcc18, 0xe1de, 0x3029, 0xe1a2, 0xeab8, 0x4814, 0xf8bb,
-0xec3b, 0x41cd, 0xfd3d, 0xbb42, 0x1ab1, 0x1bc5, 0xd03f, 0x2b94, 0x39e6, 0xe56b,
-0x20f6, 0x302f, 0xc7e3, 0xe07e, 0x304b, 0xe35d, 0xef37, 0x556b, 0x0a77, 0xf3f3,
-0x471e, 0x0715, 0xb6bf, 0x0a15, 0x15a7, 0xc8f0, 0x27ce, 0x49e1, 0xef3f, 0x24d8,
-0x3fc8, 0xcf85, 0xd3a9, 0x2981, 0xe391, 0xe1e2, 0x5568, 0x1a44, 0xf6f8, 0x47a5,
-0x0bb1, 0xb4f6, 0x0758, 0x180f, 0xc264, 0x1c7f, 0x4997, 0xe7b6, 0x1790, 0x3eec,
-0xcc71, 0xc989, 0x25c5, 0xe0ff, 0xd5eb, 0x4cb5, 0x1585, 0xe9fb, 0x3f4e, 0x079f,
-0xa4e8, 0xf8b6, 0x18b7, 0xbe0e, 0x140f, 0x4dcd, 0xe6f8, 0x106e, 0x3e48, 0xc659,
-0xb8d1, 0x1fc6, 0xe2f7, 0xcafc, 0x4b21, 0x1aac, 0xddf9, 0x38ef, 0x0d86, 0xa172,
-0xefb8, 0x1ae3, 0xb8b9, 0x022b, 0x4952, 0xe3b7, 0x0763, 0x3fb6, 0xcaa1, 0xb546,
-0x2034, 0xe7b3, 0xc26e, 0x4341, 0x1b44, 0xd872, 0x37f9, 0x158c, 0xa302, 0xed16,
-0x212e, 0xbda6, 0x0112, 0x4eb5, 0xe481, 0x0180, 0x448c, 0xd2be, 0xb34a, 0x2659,
-0xf969, 0xc3e7, 0x4253, 0x2498, 0xd3ac, 0x2f84, 0x1c93, 0xa86a, 0xeae4, 0x2be9,
-0xc824, 0xfb1e, 0x5254, 0xeb1f, 0xf85a, 0x40c6, 0xd602, 0xacc6, 0x20d2, 0xfcc1,
-0xbfa1, 0x3d9b, 0x2b83, 0xd669, 0x2fcc, 0x202d, 0xa65f, 0xe170, 0x2e20, 0xdd4c,
-0xe4e8, 0x1128, 0xe9c6, 0x2b2e, 0x54f5, 0xec68, 0xd881, 0x25b3, 0xe44f, 0x9e7f,
-0xf130, 0xeb8e, 0xd492, 0x3413, 0x5451, 0x26e6, 0x289d, 0x2623, 0xcf51, 0xbd9d,
-0xcfb5, 0xa20d, 0xdfe7, 0x36b7, 0x0cc4, 0x056d, 0x65fe, 0x4dbe, 0xdc03, 0xeb0b,
-0xf3c5, 0xb95e, 0xbfab, 0xf463, 0x0575, 0x1cd4, 0x3d59, 0x1332, 0x1c9e, 0x36b2,
-0xe6ff, 0xc1d2, 0xebab, 0xf875, 0xd9ed, 0xf751, 0x1ec8, 0x177a, 0x1fdf, 0x14b0,
-0x158a, 0x1d8b, 0x09a1, 0xd3cc, 0xc301, 0xfa03, 0xda41, 0xd913, 0x31d2, 0x3bcd,
-0x1398, 0x2276, 0x47f0, 0x04ad, 0xdb13, 0xde05, 0xbc40, 0xe0b4, 0xf233, 0xedf8,
-0x2b4d, 0x5c62, 0x258d, 0x04db, 0x4756, 0x0b9d, 0xbaa9, 0xd2dc, 0xd3e6, 0xd2e5,
-0xeb10, 0x1044, 0x260b, 0x4492, 0x307c, 0x0989, 0x37e3, 0x1952, 0xc9b1, 0xbe5d,
-0xd980, 0xdd51, 0xcfb1, 0x0665, 0x3440, 0x3f66, 0x32e5, 0x2caa, 0x3828, 0x04a2,
-0xd6f3, 0xb98c, 0xc152, 0xdc75, 0xd7fc, 0x131d, 0x50a8, 0x4584, 0x218f, 0x39e9,
-0x3a8c, 0xe3c0, 0xca56, 0xc147, 0xc3c0, 0xe3a0, 0xec33, 0x13df, 0x4aaa, 0x4c83,
-0x117c, 0x2896, 0x399a, 0xdc86, 0xc6f6, 0xcd47, 0xc6ce, 0xd9cc, 0xf86e, 0x19ad,
-0x3a91, 0x491f, 0x123e, 0x24d9, 0x3cde, 0xe11b, 0xb37c, 0xc2df, 0xd7a4, 0xd130,
-0xef29, 0x2c49, 0x3d20, 0x37d9, 0x16ea, 0x291c, 0x26ac, 0xda1f, 0xaaed, 0xb607,
-0xe686, 0xd568, 0xe17d, 0x337f, 0x4b43, 0x2881, 0x1389, 0x38c7, 0x12c8, 0xcd26,
-0xbcc3, 0xb56e, 0xdd1b, 0xe483, 0xea42, 0x2a90, 0x51ed, 0x261e, 0x0805, 0x4126,
-0x1494, 0xbddc, 0xbaf3, 0xc450, 0xd324, 0xd5cd, 0xf712, 0x2ef6, 0x4d20, 0x2af3,
-0x0e0c, 0x3762, 0x0ac6, 0xbe79, 0xae49, 0xc076, 0xd8d1, 0xd3ec, 0x0029, 0x3a43,
-0x4756, 0x22ca, 0x1958, 0x35d2, 0xf721, 0xbeb2, 0xb3fe, 0xbef0, 0xda1f, 0xdc92,
-0x07d3, 0x4050, 0x4bd0, 0x19d3, 0x154a, 0x3522, 0xefeb, 0xbbc4, 0xb715, 0xc994,
-0xdf48, 0xe0b3, 0x1046, 0x40b6, 0x462c, 0x16f6, 0x1aab, 0x3230, 0xe981, 0xbd2a,
-0xbab3, 0xd2a2, 0xe5c9, 0xe97f, 0x1c0b, 0x466f, 0x4272, 0x167d, 0x2642, 0x3042,
-0xe930, 0xc684, 0xbe13, 0xdccc, 0xed63, 0xea9d, 0x2413, 0x5441, 0x43f9, 0x180c,
-0x36e2, 0x2e3f, 0xdd7b, 0xc957, 0xc358, 0xdaa2, 0xeec1, 0xf6ba, 0x27c0, 0x5560,
-0x448c, 0x1635, 0x38ef, 0x285a, 0xd524, 0xc336, 0xc6ef, 0xdd82, 0xe86a, 0x024a,
-0x3514, 0x5243, 0x4024, 0x1679, 0x30ad, 0x19cb, 0xd2e3, 0xbea4, 0xc57f, 0xe4e0,
-0xe5d6, 0xfff4, 0x3873, 0x4af7, 0x2f8e, 0x188b, 0x3243, 0x0881, 0xcd5e, 0xbb93,
-0xbf31, 0xe52f, 0xe3f9, 0xfc94, 0x39c7, 0x4714, 0x1d41, 0x169d, 0x38c9, 0xfecd,
-0xcb1a, 0xc0fc, 0xbdbe, 0xdc75, 0xe1b5, 0xfaa7, 0x3213, 0x48a1, 0x1b68, 0x15dc,
-0x3a99, 0xf55f, 0xc01b, 0xbf71, 0xc2a6, 0xd4e4, 0xdf4d, 0x066a, 0x3170, 0x40f1,
-0x1a26, 0x18e0, 0x342c, 0xedf9, 0xba41, 0xb3b4, 0xc38e, 0xd795, 0xe02b, 0x10cf,
-0x387d, 0x3bf9, 0x151b, 0x1afe, 0x254b, 0xde99, 0xbc43, 0xb3bd, 0xc921, 0xde4a,
-0xe189, 0x1332, 0x3ec6, 0x3af6, 0x0d82, 0x1fcf, 0x23ba, 0xd6bf, 0xb847, 0xb180,
-0xcc73, 0xe0cc, 0xeb2b, 0x1cb5, 0x417e, 0x395b, 0x0e37, 0x260e, 0x1c37, 0xceea,
-0xb693, 0xb466, 0xd44d, 0xde55, 0xeccf, 0x28e9, 0x4c64, 0x3a26, 0x1085, 0x2a16,
-0x12d5, 0xcc04, 0xb7f6, 0xb4e4, 0xda25, 0xe424, 0xf801, 0x3387, 0x4c82, 0x2ff0,
-0x133d, 0x33da, 0x0a6a, 0xc653, 0xba9f, 0xb9a4, 0xdb0d, 0xe2d3, 0xfd70, 0x3932,
-0x535b, 0x2ec6, 0x131d, 0x36f2, 0x041c, 0xc4de, 0xbc13, 0xbb88, 0xdb49, 0xe632,
-0x0792, 0x3bf9, 0x5215, 0x2df5, 0x197b, 0x38ba, 0xfc1c, 0xc000, 0xb9c1, 0xc559,
-0xe3b9, 0xea55, 0x13bb, 0x45e0, 0x506f, 0x2598, 0x1a8a, 0x31d4, 0xf25d, 0xc2c1,
-0xb752, 0xc926, 0xeaa3, 0xebad, 0x18ac, 0x4b3a, 0x4b14, 0x1dc9, 0x246e, 0x2f24,
-0xe2ff, 0xc4be, 0xbca8, 0xccb7, 0xee7a, 0xf1d7, 0x1fad, 0x5446, 0x4e8c, 0x1a55,
-0x2bfd, 0x2de3, 0xdbcc, 0xc7c4, 0xc19e, 0xcdf0, 0xeebf, 0x0347, 0x2b46, 0x50aa,
-0x4efc, 0x1ae7, 0x2bc2, 0x29fc, 0xd661, 0xbcdd, 0xc496, 0xddc3, 0xe917, 0xff6c,
-0x336f, 0x4f83, 0x433f, 0x1820, 0x2877, 0x176c, 0xd63d, 0xbf37, 0xbd41, 0xe3e4,
-0xec70, 0xfccc, 0x35e8, 0x4cad, 0x2f68, 0x12a7, 0x2fac, 0x08d7, 0xcd76, 0xc4f5,
-0xbf59, 0xdfbb, 0xe9f3, 0xfd34, 0x3194, 0x4aa3, 0x2767, 0x0f36, 0x33c2, 0x0048,
-0xc54f, 0xc2fd, 0xbd10, 0xd605, 0xe41c, 0xff51, 0x2a83, 0x4801, 0x28e6, 0x0aff,
-0x2f62, 0xfdb7, 0xbd39, 0xb775, 0xc18e, 0xd7dc, 0xe021, 0x0a7d, 0x33af, 0x423a,
-0x2081, 0x0d26, 0x28f2, 0xf6aa, 0xc604, 0xb20f, 0xca22, 0xf929, 0xe0c9, 0xfe41,
-0x2c91, 0x285c, 0x3479, 0x40e1, 0x11dd, 0xd23c, 0xd207, 0xa861, 0xa807, 0xfe96,
-0xf904, 0x0d6b, 0x7934, 0x78f8, 0x0f08, 0xfce1, 0xe859, 0x8e1b, 0xa714, 0xc4a3,
-0xd05d, 0x3229, 0x6379, 0x4af3, 0x48ea, 0x4a2d, 0xe67d, 0xa875, 0xd782, 0xc120,
-0xb7cb, 0xfb9f, 0x1f2e, 0x34e8, 0x4bf0, 0x20cd, 0xf0b2, 0x1643, 0x0563, 0xbcd0,
-0xf27f, 0x2741, 0xe7cd, 0xef58, 0x2d5f, 0xebc6, 0xc657, 0x2de0, 0x1cb6, 0xe47e,
-0x4360, 0x2d6e, 0xe23e, 0x16ee, 0xf98d, 0xa445, 0xddbb, 0x207f, 0xe2c0, 0x123e,
-0x5bce, 0x016d, 0x1099, 0x3582, 0xc93d, 0xb242, 0x0573, 0xeaa3, 0xcd42, 0x3ec8,
-0x2edf, 0xedf6, 0x39f9, 0x19b8, 0xb85b, 0xe3bc, 0x1369, 0xd1a8, 0xf1db, 0x3e71,
-0xf679, 0x05fa, 0x4211, 0xe5a8, 0xbfbb, 0x17fb, 0x0686, 0xc767, 0x1e4b, 0x24e5,
-0xdea8, 0x2460, 0x26bf, 0xbfbf, 0xebef, 0x3662, 0xdb5b, 0xe735, 0x478f, 0xf36f,
-0xe6aa, 0x3a12, 0xedab, 0xb885, 0x2168, 0x1a11, 0xd137, 0x2b7c, 0x29a9, 0xd6be,
-0x2004, 0x24d0, 0xb744, 0xddad, 0x2f52, 0xe201, 0xeeef, 0x4b3b, 0xfc02, 0xef7b,
-0x3d92, 0xf6b9, 0xb6be, 0x0b17, 0x0d77, 0xc534, 0x191c, 0x30b3, 0xe945, 0x23b0,
-0x2f3b, 0xc9bb, 0xd7dc, 0x269c, 0xe46c, 0xd902, 0x3766, 0x0212, 0xeb25, 0x39af,
-0x03e0, 0xb8e7, 0x077c, 0x169d, 0xcc6f, 0x1b10, 0x2e0e, 0xd19a, 0x0fd8, 0x38f6,
-0xca91, 0xc8f9, 0x29d6, 0xf078, 0xdd5c, 0x3b96, 0x09ef, 0xf001, 0x3507, 0xfbb1,
-0xb660, 0x03d5, 0x0e0a, 0xc387, 0x17f0, 0x3e5b, 0xe93c, 0x15a4, 0x38a5, 0xd46a,
-0xc5fe, 0x1360, 0xe4bc, 0xda9b, 0x39bc, 0x0c8d, 0xef2a, 0x3f9f, 0x0fdb, 0xb193,
-0xf8d2, 0x1694, 0xb855, 0xffea, 0x4558, 0xed39, 0x083b, 0x3cd1, 0xda45, 0xc36d,
-0x1e6e, 0xe476, 0xc765, 0x430f, 0x19a5, 0xde45, 0x3c55, 0x16d3, 0xa619, 0xf171,
-0x1f0a, 0xbe1b, 0x04f9, 0x4d9d, 0xeec4, 0x0d1f, 0x3e78, 0xccbe, 0xb49f, 0x1d9b,
-0xeb29, 0xc2b6, 0x448d, 0x28e1, 0xe2a4, 0x3aab, 0x21b9, 0xad2c, 0xe5d9, 0x1d14,
-0xbe21, 0xf5ec, 0x4db1, 0xef99, 0x030b, 0x4e45, 0xe3cc, 0xb105, 0x20c5, 0xfc50,
-0xb9ac, 0x35e2, 0x2898, 0xd9cf, 0x3397, 0x236d, 0xace6, 0xea90, 0x2c38, 0xc65d,
-0xf7eb, 0x5313, 0xe39f, 0xf211, 0x477a, 0xdbe9, 0xad7a, 0x1ffa, 0x0017, 0xc201,
-0x3906, 0x27ff, 0xd56a, 0x2d70, 0x20b7, 0xa843, 0xe22b, 0x2d3a, 0xc8d1, 0xeff9,
-0x5809, 0xf171, 0xf1ca, 0x4aa1, 0xe752, 0xa7f6, 0x1531, 0x03a8, 0xbd38, 0x3515,
-0x35e4, 0xd873, 0x2cec, 0x2fa3, 0xaedb, 0xd92e, 0x2cc6, 0xccea, 0xe531, 0x5116,
-0xf947, 0xf6dd, 0x4ce8, 0xef45, 0xaeac, 0x190f, 0x0bfc, 0xbc68, 0x2afb, 0x3612,
-0xd723, 0x2687, 0x3899, 0xbdfb, 0xda26, 0x3069, 0xdbaf, 0xe6bf, 0x5016, 0x0057,
-0xf1d5, 0x480e, 0xf64b, 0xad29, 0x13a0, 0x16f4, 0xc33e, 0x2614, 0x4041, 0xe193,
-0x201a, 0x3648, 0xc1be, 0xd35e, 0x2aee, 0xe031, 0xe3b6, 0x52de, 0x0b18, 0xedc3,
-0x4b67, 0x084a, 0xaf95, 0x0ccc, 0x1af7, 0xc089, 0x19da, 0x4369, 0xe6d2, 0x1d97,
-0x422d, 0xcfe2, 0xd1f7, 0x2e93, 0xe6d4, 0xd904, 0x4acc, 0x0d46, 0xe47d, 0x425b,
-0x0eb4, 0xb1bb, 0x06af, 0x2009, 0xc469, 0x12a4, 0x3fee, 0xdd98, 0x0e0f, 0x3d40,
-0xcdb1, 0xc9b2, 0x2f38, 0xedc8, 0xcf7d, 0x42ef, 0x1026, 0xd9af, 0x3710, 0x1033,
-0xad12, 0xfd62, 0x2285, 0xc358, 0x0c72, 0x48be, 0xe51c, 0x0a9a, 0x2ff8, 0xbdc8,
-0xc28d, 0x2cc9, 0xfec9, 0xc7ca, 0x13e5, 0x17e1, 0x02ca, 0x35c6, 0x0fac, 0xcd93,
-0xf8c0, 0xfbac, 0xbba6, 0xe67f, 0x0735, 0xd6a6, 0x1bde, 0x7350, 0x2eb9, 0xfad9,
-0x2334, 0xeee4, 0xa104, 0xc9e5, 0xcf89, 0xd376, 0x2f8b, 0x2f58, 0x13f9, 0x6199,
-0x5172, 0xd760, 0xdae6, 0x0109, 0xaaab, 0x9f01, 0x11f6, 0x1c74, 0xff8b, 0x303b,
-0x3d89, 0x2a49, 0x1900, 0xe5d6, 0xbb94, 0xe00a, 0xeeb6, 0xce23, 0x0253, 0x3291,
-0x20e8, 0x0d77, 0x2650, 0x2ac1, 0xf46d, 0xf971, 0xdbe5, 0xc599, 0xf13a, 0xdd86,
-0xebfb, 0x30a4, 0x422d, 0x0726, 0x20e1, 0x53cf, 0xe990, 0xbf8d, 0xd717, 0xc738,
-0xcc12, 0xed69, 0x1207, 0x2679, 0x4b59, 0x2072, 0x0f6e, 0x3b3c, 0xef93, 0xaf82,
-0xc07e, 0xdcf5, 0xccea, 0xe17b, 0x31b5, 0x3ad1, 0x3673, 0x24ae, 0x1fad, 0x2260,
-0xf0dd, 0xc29e, 0xb494, 0xe43c, 0xe377, 0xdb2b, 0x2318, 0x45fc, 0x34e0, 0x20c4,
-0x3ea5, 0x232d, 0xdb31, 0xcc1d, 0xb320, 0xc65a, 0xdf18, 0xea47, 0x25f0, 0x5cd4,
-0x4386, 0x10e7, 0x3d78, 0x214b, 0xc538, 0xbca9, 0xbe8b, 0xcd16, 0xe049, 0x05f5,
-0x2fe8, 0x5197, 0x45f2, 0x0fc2, 0x2f2f, 0x1971, 0xc5a7, 0xb7fc, 0xca80, 0xd975,
-0xd7df, 0x0c99, 0x3a4e, 0x3fc6, 0x30e6, 0x13a0, 0x2b87, 0x0f79, 0xcd82, 0xaf27,
-0xc107, 0xe381, 0xd5f3, 0x035c, 0x44e6, 0x44fc, 0x1db9, 0x1e95, 0x3a4e, 0xf713,
-0xc17f, 0xb545, 0xc44b, 0xea43, 0xe0b2, 0x034f, 0x458e, 0x4e96, 0x1557, 0x1819,
-0x3caa, 0xeb53, 0xb81f, 0xc29d, 0xcb34, 0xd827, 0xea2e, 0x153f, 0x3683, 0x4599,
-0x17a8, 0x1025, 0x3238, 0xefae, 0xb3df, 0xb7d0, 0xd811, 0xd6f7, 0xd85a, 0x1792,
-0x3a94, 0x35ea, 0x1657, 0x21c8, 0x243d, 0xdfb1, 0xbb30, 0xb0e9, 0xceed, 0xddbf,
-0xdff2, 0x1be1, 0x44e0, 0x3265, 0x0879, 0x260d, 0x1f6a, 0xcd4c, 0xba1b, 0xbafd,
-0xcb3d, 0xd899, 0xeb07, 0x19d6, 0x3c13, 0x3544, 0x08ed, 0x2407, 0x1daa, 0xcd68,
-0xb792, 0xbf01, 0xd1c2, 0xd611, 0xf34b, 0x259b, 0x3b2f, 0x2f39, 0x1053, 0x2d78,
-0x1a05, 0xd265, 0xba97, 0xc02a, 0xdab7, 0xd903, 0xf86d, 0x2ff9, 0x403d, 0x28d3,
-0x14a1, 0x34af, 0x0a0e, 0xcda4, 0xc3ac, 0xc13a, 0xdd8d, 0xe2ea, 0xfd27, 0x2eb2,
-0x45ac, 0x26be, 0x14ec, 0x3dd9, 0x06bc, 0xc81d, 0xc6e2, 0xc719, 0xd8c3, 0xe5c7,
-0x0b66, 0x32c9, 0x4b92, 0x2cb4, 0x19ce, 0x3c10, 0x0272, 0xc5eb, 0xbb96, 0xccd7,
-0xe07a, 0xdfbb, 0x160a, 0x4341, 0x4749, 0x2676, 0x21c7, 0x2fd3, 0xf0d0, 0xc6ee,
-0xb624, 0xcad8, 0xe85f, 0xe7c5, 0x1d81, 0x4b84, 0x45af, 0x1eba, 0x2c0d, 0x30c1,
-0xe4ba, 0xca8d, 0xbdbe, 0xcc89, 0xed50, 0xf3dd, 0x2203, 0x5159, 0x4cd1, 0x1b22,
-0x2e08, 0x3255, 0xe28f, 0xc7e6, 0xc2e3, 0xd510, 0xe8de, 0xfa14, 0x2846, 0x4a33,
-0x4c04, 0x1fed, 0x2f64, 0x2cdb, 0xe195, 0xc51d, 0xc13f, 0xdb62, 0xe696, 0xfa3e,
-0x31bd, 0x4d3c, 0x4355, 0x2150, 0x33b3, 0x204a, 0xe0d7, 0xc877, 0xbdd9, 0xdeff,
-0xeb46, 0x0024, 0x3a0c, 0x5485, 0x3c57, 0x1fe4, 0x3a57, 0x110e, 0xd1f0, 0xc4f8,
-0xbfae, 0xe303, 0xf0e8, 0x0757, 0x3795, 0x525c, 0x364d, 0x163e, 0x3411, 0x078d,
-0xc95e, 0xbed3, 0xc146, 0xdd79, 0xe8cb, 0x0fb0, 0x3b8b, 0x4b40, 0x2f52, 0x1708,
-0x2c9b, 0xf6f7, 0xc33e, 0xb8f8, 0xc0a0, 0xe27b, 0xe6d8, 0x0c22, 0x3d9b, 0x4878,
-0x24a6, 0x186c, 0x2467, 0xe600, 0xc014, 0xb323, 0xbc0b, 0xe0eb, 0xe8da, 0x0f11,
-0x3cef, 0x40c5, 0x12df, 0x1430, 0x227a, 0xdb2e, 0xb8c4, 0xb5de, 0xc528, 0xdd7a,
-0xe824, 0x13d4, 0x3e15, 0x4384, 0x124e, 0x1469, 0x1e10, 0xd6df, 0xb7fb, 0xb8e3,
-0xcdaf, 0xdd42, 0xecbb, 0x1e7d, 0x3c6f, 0x378a, 0x1149, 0x1e8a, 0x1b08, 0xd447,
-0xb3c7, 0xb0b3, 0xd341, 0xe16d, 0xebda, 0x22db, 0x4450, 0x345d, 0x0fcd, 0x27aa,
-0x137c, 0xcfd2, 0xc241, 0xbb1b, 0xd538, 0xe771, 0xf62c, 0x297f, 0x4c37, 0x3271,
-0x103e, 0x360c, 0x143c, 0xc8cb, 0xc2e2, 0xc46f, 0xd919, 0xe83f, 0x0316, 0x2e44,
-0x49f7, 0x320d, 0x1102, 0x34eb, 0x0f20, 0xc998, 0xc1e5, 0xc68b, 0xd8b7, 0xe3aa,
-0x0e51, 0x3839, 0x473d, 0x306d, 0x1936, 0x313b, 0x023a, 0xca3b, 0xb9cb, 0xc4e8,
-0xe9a8, 0xe8e8, 0x0e4f, 0x4390, 0x4a72, 0x23d2, 0x1d52, 0x31ca, 0xf0b0, 0xc813,
-0xbd25, 0xc202, 0xe6ea, 0xee18, 0x12c8, 0x4476, 0x4b2e, 0x198b, 0x19a1, 0x2fcc,
-0xe518, 0xbf8d, 0xbe9e, 0xcb6d, 0xe622, 0xee0e, 0x167e, 0x3fbf, 0x46fb, 0x1a7d,
-0x1f4e, 0x2d08, 0xe17f, 0xbedd, 0xbaa3, 0xcc16, 0xe196, 0xeedc, 0x21cc, 0x44ed,
-0x4348, 0x1a18, 0x2363, 0x242e, 0xdc65, 0xbd61, 0xb300, 0xcfa0, 0xe712, 0xe5c7,
-0x169f, 0x5f17, 0x7299, 0x2bb1, 0x0b65, 0xe2fd, 0x9b1c, 0xa3b5, 0xaeb5, 0xe147,
-0x3787, 0x593a, 0x5290, 0x4a3c, 0x2e69, 0xcbb4, 0xa91f, 0xc5a3, 0xbd85, 0xd07b,
-0x1055, 0x3d01, 0x2411, 0x222c, 0x2b1a, 0x0b05, 0xffdc, 0xe3f2, 0xcf8c, 0xf390,
-0x15ad, 0xd9f5, 0xc944, 0x2d37, 0x09de, 0xc93f, 0x0d00, 0x229d, 0x0eb5, 0x31fb,
-0x193d, 0xdefd, 0x0b6e, 0xe2b8, 0x80c1, 0xd2cb, 0x1719, 0xe9c2, 0x3008, 0x6a8a,
-0xfee8, 0x01bc, 0x299a, 0xb39d, 0xa48f, 0x0798, 0xe5e9, 0xddfa, 0x41e1, 0x17dc,
-0xf43b, 0x3829, 0x05c3, 0xbd89, 0xf1bc, 0x0dab, 0xcd37, 0xfad8, 0x2e14, 0xf080,
-0x107b, 0x24ea, 0xd852, 0xd4a0, 0x17fd, 0xfd24, 0xd818, 0x2b57, 0x168d, 0xdb81,
-0x1759, 0x0cdb, 0xc867, 0xf2e6, 0x257d, 0xe349, 0xfff1, 0x39a1, 0xe33d, 0xee45,
-0x2b9d, 0xe388, 0xc702, 0x21a8, 0x103e, 0xda0f, 0x2f4b, 0x1b70, 0xd6c1, 0x1b55,
-0x104d, 0xb577, 0xe811, 0x28c6, 0xe0aa, 0xfee3, 0x4403, 0xf56f, 0xf711, 0x2c32,
-0xe60a, 0xbd96, 0x0d61, 0x048f, 0xce3d, 0x272f, 0x325d, 0xf1c7, 0x2094, 0x1ff0,
-0xc860, 0xe30a, 0x2515, 0xdac5, 0xe92d, 0x441f, 0x0548, 0xfb76, 0x3d79, 0xfd5c,
-0xbecb, 0x1149, 0x13f9, 0xd214, 0x2a6f, 0x3388, 0xe6f8, 0x2190, 0x2948, 0xc4a5,
-0xdd42, 0x2f43, 0xe6af, 0xf03f, 0x54db, 0x13d9, 0xfca6, 0x3215, 0xf506, 0xc57a,
-0x12c0, 0x0f9f, 0xd3cc, 0x322e, 0x4301, 0xf273, 0x23ab, 0x356e, 0xd3b2, 0xd051,
-0x21b7, 0xf281, 0xecda, 0x4489, 0x12f0, 0x0242, 0x4407, 0x06d1, 0xbafe, 0x0b6c,
-0x1d26, 0xc6ee, 0x19bc, 0x44e9, 0xe86d, 0x13b7, 0x39ca, 0xd446, 0xd119, 0x2941,
-0xee93, 0xe7c5, 0x4bc2, 0x0643, 0xe908, 0x4535, 0x0444, 0xaaed, 0x0a10, 0x21a1,
-0xc807, 0x1964, 0x41d6, 0xe77b, 0x16b3, 0x34e4, 0xc869, 0xc8dc, 0x2196, 0xe4ba,
-0xdb97, 0x4973, 0x106a, 0xe7d9, 0x3cc5, 0x0a39, 0xa769, 0xf083, 0x1925, 0xc4c2,
-0x075d, 0x3c4a, 0xe3ca, 0x0d28, 0x38d3, 0xc8d1, 0xbd34, 0x29a4, 0xea91, 0xbfc6,
-0x3ad0, 0x0fbe, 0xd348, 0x3125, 0x0f03, 0xa6a3, 0xf4e3, 0x222b, 0xbe73, 0x00e2,
-0x3cfa, 0xd671, 0xff6d, 0x3893, 0xc753, 0xb6c9, 0x236e, 0xec95, 0xc571, 0x3925,
-0x1324, 0xdbd6, 0x2c09, 0x07a8, 0xaa2d, 0xf242, 0x1fa6, 0xc716, 0x042c, 0x441c,
-0xe490, 0xffd3, 0x3dc4, 0xdc2a, 0xb9f6, 0x1f30, 0xfbb0, 0xca2e, 0x371c, 0x2003,
-0xddf1, 0x31fa, 0x2307, 0xb4d8, 0xf004, 0x2cbc, 0xc878, 0xf7c6, 0x4caf, 0xed6b,
-0xfe78, 0x48e2, 0xe5f3, 0xb861, 0x209c, 0xffdd, 0xc990, 0x3a8f, 0x2235, 0xd8df,
-0x3307, 0x26fb, 0xb85c, 0xf04e, 0x2cb8, 0xd049, 0xfa7c, 0x49ae, 0xedac, 0xfa25,
-0x3f7d, 0xe587, 0xbae6, 0x1de2, 0x03f4, 0xc964, 0x35b0, 0x2bf3, 0xdcc1, 0x287a,
-0x2509, 0xb53e, 0xdd34, 0x21f5, 0xd014, 0xf4e6, 0x5327, 0xfbed, 0xf63d, 0x422a,
-0xebde, 0xadff, 0x109b, 0x03c0, 0xc66e, 0x34a1, 0x371f, 0xe1e5, 0x266b, 0x298a,
-0xb6ec, 0xdb6e, 0x2815, 0xd421, 0xf019, 0x5352, 0xff26, 0xf3f2, 0x43a2, 0xf389,
-0xb155, 0x11bc, 0x093e, 0xc3cf, 0x2cd7, 0x37d3, 0xe04d, 0x22e3, 0x2ecd, 0xb8a8,
-0xd4f6, 0x2b5c, 0xd879, 0xe9c1, 0x5345, 0x0074, 0xeb1b, 0x3d0d, 0xf0a8, 0xa78e,
-0x0f83, 0x1369, 0xc523, 0x2e80, 0x3d4c, 0xdb13, 0x1e41, 0x2ecc, 0xb34d, 0xd013,
-0x2f65, 0xd81e, 0xe458, 0x57d2, 0x0406, 0xebe0, 0x457a, 0xf7e1, 0xa66e, 0x0b6f,
-0x0e7a, 0xb8d1, 0x251b, 0x3fe1, 0xdd7d, 0x20b9, 0x3687, 0xbb17, 0xd0b9, 0x2e06,
-0xd6de, 0xd8c9, 0x50ce, 0x0665, 0xe605, 0x3fce, 0xfc63, 0xac6f, 0x0f4a, 0x249e,
-0xcfcc, 0xfc68, 0x0488, 0xeb03, 0x4794, 0x43ec, 0xda83, 0xf3bd, 0x2644, 0xc019,
-0xac19, 0xfdb7, 0xdae0, 0xebc8, 0x4a7e, 0x4842, 0x204b, 0x2f4a, 0x0bd7, 0xb466,
-0xc7b6, 0xc25a, 0x9ff5, 0xfeaa, 0x3147, 0xf5d6, 0x1606, 0x7098, 0x2536, 0xcb1f,
-0xef7c, 0xd8bb, 0xa610, 0xc6a6, 0xf94d, 0x01cf, 0x2326, 0x2e92, 0xfa36, 0x1b23,
-0x1fee, 0xc9e0, 0xbf64, 0xf0f7, 0xebf9, 0xcd60, 0xfed7, 0x1727, 0x0a34, 0x1723,
-0x0a36, 0x0e7b, 0x18aa, 0xfc64, 0xb854, 0xc985, 0xfdd8, 0xc68b, 0xea58, 0x3e80,
-0x2a34, 0x0ba2, 0x2d28, 0x367f, 0xec1b, 0xe1de, 0xce20, 0xb654, 0xf084, 0xed7d,
-0xf556, 0x44c2, 0x5de8, 0x118c, 0x103a, 0x43c2, 0xea97, 0xbbb3, 0xd781, 0xd5a7,
-0xe105, 0xfd04, 0x1bc6, 0x2dbd, 0x4a4e, 0x2262, 0x090c, 0x37f3, 0x0697, 0xc337,
-0xc445, 0xe70d, 0xe217, 0xdb53, 0x1953, 0x38c9, 0x40c1, 0x2ede, 0x22c3, 0x260c,
-0xfc8c, 0xcfd4, 0xb0e1, 0xd39e, 0xe34c, 0xdae1, 0x253f, 0x508f, 0x342f, 0x1aa5,
-0x3628, 0x1e6e, 0xd753, 0xc9cd, 0xb7c4, 0xd23c, 0xef41, 0xeb30, 0x1cc2, 0x523c,
-0x3c38, 0x02b5, 0x29f9, 0x28a2, 0xd759, 0xd1f8, 0xd1bf, 0xd245, 0xe508, 0xfe91,
-0x19fc, 0x3b30, 0x3d9b, 0x0a4c, 0x2fd0, 0x37f4, 0xdc8c, 0xbe49, 0xd7b4, 0xe591,
-0xd3af, 0xfd0f, 0x3070, 0x36f1, 0x325e, 0x18a4, 0x3386, 0x27ca, 0xdc73, 0xb513,
-0xcdc8, 0xf809, 0xd5d9, 0xf013, 0x4334, 0x4964, 0x2395, 0x1b7b, 0x3c5a, 0x0fe4,
-0xd7a3, 0xc6c6, 0xc6b6, 0xf0cf, 0xeb7d, 0xf80b, 0x3914, 0x525a, 0x2445, 0x1417,
-0x4928, 0x0ff5, 0xc35d, 0xc78a, 0xd244, 0xdff9, 0xe35e, 0x07df, 0x35ae, 0x4ba7,
-0x2974, 0x1106, 0x3cf3, 0x0fec, 0xc4b4, 0xb9c7, 0xd562, 0xe489, 0xd970, 0x0e52,
-0x3f61, 0x43d6, 0x27aa, 0x2131, 0x364b, 0xfd16, 0xc955, 0xb961, 0xcde0, 0xe8ce,
-0xe024, 0x0e4f, 0x4544, 0x4582, 0x18cd, 0x22be, 0x3a77, 0xf22e, 0xc4f3, 0xbabf,
-0xcce0, 0xe32e, 0xe352, 0x12f7, 0x43a1, 0x4666, 0x1401, 0x1c0c, 0x30e6, 0xe619,
-0xbb56, 0xbb95, 0xd491, 0xe00b, 0xe61a, 0x17a4, 0x3b47, 0x3b00, 0x10e7, 0x1c7e,
-0x2707, 0xe361, 0xb750, 0xb2d2, 0xd7be, 0xdb41, 0xe145, 0x2096, 0x40ed, 0x319a,
-0x118b, 0x2924, 0x1a2e, 0xd6af, 0xba5f, 0xad6c, 0xd2c9, 0xe064, 0xe67c, 0x25df,
-0x4ea4, 0x3357, 0x0fc7, 0x312c, 0x1020, 0xc418, 0xb5ff, 0xb68a, 0xd4f7, 0xe2ef,
-0xfb14, 0x2e11, 0x4c3e, 0x3280, 0x08fc, 0x2966, 0x0e36, 0xc69d, 0xb3ba, 0xbf26,
-0xde72, 0xe461, 0x0918, 0x3887, 0x4967, 0x313c, 0x1236, 0x2763, 0x0526, 0xcb44,
-0xb35a, 0xc8b5, 0xed8f, 0xdf83, 0x05bf, 0x41b2, 0x4548, 0x20ab, 0x1a30, 0x2bd9,
-0xf884, 0xce0f, 0xb377, 0xc10c, 0xede8, 0xe5b7, 0x0520, 0x42f2, 0x4b64, 0x19c0,
-0x1a50, 0x2fd7, 0xee52, 0xc8d4, 0xbcea, 0xc661, 0xe5d5, 0xe9b8, 0x0e4b, 0x42da,
-0x4c23, 0x187a, 0x1ba9, 0x2fdd, 0xe89e, 0xbcad, 0xb84a, 0xd201, 0xe619, 0xeba8,
-0x1a61, 0x40ef, 0x41b7, 0x151a, 0x1cbf, 0x2b05, 0xea44, 0xc1f8, 0xbc6c, 0xdb3c,
-0xe422, 0xe69f, 0x208e, 0x4881, 0x3cc7, 0x1503, 0x2aa9, 0x27ed, 0xe431, 0xc5cc,
-0xbdfa, 0xdd9a, 0xe8e9, 0xf074, 0x2496, 0x4a59, 0x3e74, 0x1374, 0x2e8f, 0x252c,
-0xd82c, 0xba66, 0xbeda, 0xe1cc, 0xe3a5, 0xf456, 0x3043, 0x4df4, 0x382a, 0x0d8b,
-0x25d9, 0x1516, 0xd249, 0xb805, 0xbbdd, 0xe317, 0xe31f, 0xf717, 0x307f, 0x4438,
-0x2ce7, 0x1089, 0x29b8, 0x060d, 0xc757, 0xb6c7, 0xb848, 0xdd4c, 0xde36, 0xf60e,
-0x341a, 0x45f6, 0x1fc8, 0x0b03, 0x2ed5, 0xff75, 0xc14a, 0xb3bb, 0xb4dc, 0xd6d2,
-0xdc36, 0xfbb0, 0x356c, 0x49c3, 0x2300, 0x0fe9, 0x2f18, 0xf499, 0xb802, 0xb1b2,
-0xc06f, 0xdc85, 0xde22, 0x0805, 0x3cc1, 0x488e, 0x1f2e, 0x11d7, 0x2c64, 0xf3b1,
-0xbd78, 0xadbb, 0xc5eb, 0xe451, 0xde57, 0x0e82, 0x4140, 0x4137, 0x1916, 0x1b84,
-0x28d4, 0xe639, 0xc1a0, 0xb2e7, 0xc697, 0xe4be, 0xdf87, 0x10dc, 0x49b4, 0x457d,
-0x1479, 0x2405, 0x2b0f, 0xdcbe, 0xbefc, 0xb3a9, 0xc6dd, 0xe60b, 0xed45, 0x1b13,
-0x497b, 0x4531, 0x1324, 0x24b0, 0x243c, 0xd210, 0xb83d, 0xb984, 0xd0bc, 0xe2a6,
-0xf3b7, 0x2766, 0x4a82, 0x4204, 0x133f, 0x22b4, 0x1b4e, 0xd4a3, 0xba37, 0xbaaf,
-0xdf26, 0xea12, 0xf84b, 0x3177, 0x4e17, 0x39af, 0x193b, 0x308a, 0x13c1, 0xd6b0,
-0xc5d3, 0xbffc, 0xe599, 0xeec6, 0xff4d, 0x38ac, 0x5167, 0x346a, 0x1b9d, 0x376a,
-0x0ce4, 0xd4a8, 0xc78f, 0xc195, 0xe4f4, 0xf0f5, 0x07bb, 0x3cdc, 0x5981, 0x3510,
-0x1b26, 0x3a31, 0x03fb, 0xca72, 0xc53e, 0xcd25, 0xecab, 0xf768, 0x193e, 0x437d,
-0x53af, 0x2c6f, 0x15b8, 0x31bf, 0xff10, 0xcc99, 0xc147, 0xd348, 0xee05, 0xee95,
-0x1782, 0x2f2b, 0x4b20, 0x5a80, 0x2b14, 0xfd25, 0xdd6a, 0xccb5, 0x9c77, 0xbb91,
-0x0abb, 0xfa6d, 0x308d, 0x8b3b, 0x6386, 0x0f1b, 0x0366, 0xd9a6, 0x969a, 0xbb36,
-0xbe42, 0xd650, 0x4a43, 0x5e11, 0x39f6, 0x4e5f, 0x3f3f, 0xd1f7, 0xbac7, 0xda01,
-0xb75e, 0xdb85, 0x0689, 0x0f50, 0x402d, 0x3a48, 0xf492, 0xf3ba, 0x232e, 0xe3c2,
-0xc221, 0x1c7e, 0x103b, 0xda32, 0x0d99, 0x12a9, 0xc374, 0xe4a9, 0x2fee, 0xef59,
-0xf571, 0x4551, 0x09ce, 0xee4d, 0x190c, 0xdd87, 0xa5eb, 0xf5c9, 0x0d02, 0xd8dd,
-0x32e0, 0x4556, 0xf27b, 0x272d, 0x1a0f, 0xac2d, 0xc929, 0x0d48, 0xd065, 0xe73f,
-0x4fb6, 0x0a4b, 0xfcc1, 0x4512, 0xed54, 0xb2b9, 0x0350, 0xfc0b, 0xbed7, 0x1926,
-0x2f0c, 0xe1a6, 0x2871, 0x338a, 0xc365, 0xd8fc, 0x2261, 0xe12a, 0xda5e, 0x3836,
-0x02a6, 0xeb2d, 0x3c29, 0xfc95, 0xb47f, 0x126c, 0x2240, 0xc4df, 0x1301, 0x42d9,
-0xddbd, 0x05c8, 0x2ff4, 0xc609, 0xc9ef, 0x2ebd, 0xf193, 0xda07, 0x46da, 0x0cd3,
-0xe052, 0x39eb, 0x0085, 0xa3df, 0xfdbd, 0x1d67, 0xc36d, 0x1321, 0x461a, 0xe3db,
-0x121d, 0x3bc5, 0xce7e, 0xc611, 0x1e92, 0xe869, 0xd146, 0x3d6e, 0x12f6, 0xe781,
-0x3a2e, 0x100e, 0xb4c0, 0xf87f, 0x2451, 0xce12, 0xfd54, 0x3b61, 0xe9af, 0x0485,
-0x363a, 0xd7a5, 0xc531, 0x26b6, 0xfb26, 0xd3af, 0x4024, 0x13d3, 0xcf38, 0x31ca,
-0x1fe6, 0xacba, 0xe830, 0x28d0, 0xd67b, 0x03f4, 0x4390, 0xeff5, 0x0d9b, 0x3cdc,
-0xd2ef, 0xbce5, 0x1df5, 0xf194, 0xcc0a, 0x3c7b, 0x22be, 0xe9d0, 0x37e4, 0x1f21,
-0xbf6a, 0xed14, 0x13f9, 0xccad, 0xfeed, 0x36f2, 0xe931, 0x0bd9, 0x4870, 0xe9a7,
-0xc649, 0x2406, 0x009e, 0xc7de, 0x28c6, 0x1d14, 0xe19d, 0x2d2e, 0x24eb, 0xc1ae,
-0xf293, 0x2948, 0xd034, 0xfc36, 0x4c80, 0xed33, 0xf76a, 0x4574, 0xe546, 0xb51f,
-0x205e, 0x01e4, 0xc8f6, 0x3c9b, 0x2dfd, 0xe000, 0x3231, 0x23e4, 0xac3f, 0xe1e2,
-0x2470, 0xc806, 0xf279, 0x51f9, 0xfc93, 0xfd3d, 0x471f, 0xf14b, 0xb564, 0x0d8d,
-0xf7a1, 0xbaf7, 0x2ae2, 0x3330, 0xe3cf, 0x2876, 0x2f9d, 0xbe99, 0xd8ed, 0x2066,
-0xcc5b, 0xe037, 0x444b, 0xfc55, 0xf1ae, 0x3dee, 0xedb1, 0xa9f3, 0x0f58, 0x052a,
-0xb88b, 0x286b, 0x32e9, 0xd191, 0x1a2d, 0x2b19, 0xb1ba, 0xd055, 0x2574, 0xcd9d,
-0xe17a, 0x4f5d, 0xf991, 0xe9c8, 0x4424, 0xee22, 0xa03f, 0x0b3e, 0x0833, 0xb2f6,
-0x25d7, 0x3fb5, 0xd971, 0x1eca, 0x3552, 0xb55f, 0xc5ed, 0x2341, 0xd2b5, 0xd7c1,
-0x523e, 0x069d, 0xe63d, 0x453d, 0xfaec, 0xa137, 0x0414, 0x12c4, 0xb981, 0x1bb8,
-0x4054, 0xdb21, 0x1feb, 0x3f6a, 0xbc6b, 0xcb19, 0x2eaa, 0xdddc, 0xd782, 0x53f0,
-0x0db9, 0xe5f5, 0x4ae5, 0x09f1, 0xaaaa, 0x08ea, 0x1b96, 0xc280, 0x22c4, 0x4ce0,
-0xe24f, 0x1cfe, 0x4491, 0xc23a, 0xc424, 0x2faf, 0xe9a8, 0xd606, 0x50b8, 0x16c3,
-0xe5a3, 0x41e4, 0x0b1a, 0xa940, 0xfef6, 0x1bdf, 0xbfb1, 0x1607, 0x4e4e, 0xe252,
-0x116e, 0x44af, 0xc71f, 0xbeed, 0x2c56, 0xed57, 0xd13f, 0x46da, 0x1220, 0xdf44,
-0x3fcf, 0x0e72, 0xa687, 0xfe99, 0x22c2, 0xc0f4, 0x10f5, 0x4ab0, 0xdcc9, 0x0862,
-0x42d3, 0xcce8, 0xbf2b, 0x2c4a, 0xf130, 0xcf23, 0x47a0, 0x1557, 0xd894, 0x3b17,
-0x15eb, 0xac91, 0xfc3e, 0x2839, 0xc889, 0x0a6b, 0x4a0a, 0xe524, 0x0571, 0x40a3,
-0xd642, 0xc2d3, 0x2b1c, 0xfa19, 0xd4f9, 0x465b, 0x1ef6, 0xe106, 0x371e, 0x15ec,
-0xb185, 0xfc2f, 0x2898, 0xcc97, 0x0b55, 0x4c1f, 0xebc4, 0x08bc, 0x3f08, 0xd705,
-0xc599, 0x2bb5, 0x081d, 0xcd96, 0x0d3b, 0x0ffa, 0x0823, 0x3f09, 0x1a45, 0xdad9,
-0x0662, 0x07b7, 0xbb6a, 0xde9a, 0x0740, 0xda46, 0x0e1e, 0x6549, 0x38b1, 0x04bd,
-0x2510, 0xf943, 0xad98, 0xc9a0, 0xca5c, 0xcaba, 0x22c9, 0x2b10, 0x01f0, 0x511a,
-0x637c, 0xe409, 0xcfea, 0xff1b, 0xbae4, 0x9b34, 0xfafc, 0x154f, 0xfdb5, 0x2da1,
-0x2e82, 0x1b20, 0x2472, 0xf46c, 0xbc6b, 0xd8c3, 0xf895, 0xcd65, 0xe4ee, 0x20c1,
-0x1821, 0x08d6, 0x178c, 0x2a03, 0x07e8, 0xfe05, 0xe136, 0xbccf, 0xeb99, 0xdae7,
-0xd3aa, 0x1d70, 0x3e94, 0x094b, 0x0900, 0x5434, 0x0901, 0xc4b1, 0xdc6e, 0xc832,
-0xca7f, 0xe370, 0xfc55, 0x19fb, 0x5037, 0x3174, 0xfe1c, 0x3bdc, 0x1079, 0xb5a5,
-0xbd97, 0xde91, 0xd7dc, 0xd8e9, 0x1ed3, 0x2fd7, 0x3373, 0x2e1c, 0x130d, 0x2861,
-0x0ada, 0xcec0, 0xaf81, 0xd3f1, 0xe991, 0xcbf7, 0x0636, 0x408c, 0x3d14, 0x22da,
-0x2e7f, 0x334f, 0xf091, 0xd23f, 0xb6f6, 0xbe39, 0xe0ea, 0xdac6, 0x0ab7, 0x52de,
-0x5241, 0x1a28, 0x36a7, 0x3ee4, 0xdc10, 0xbfb1, 0xc06c, 0xc69f, 0xdf82, 0xf62e,
-0x1f54, 0x4e25, 0x578d, 0x17a6, 0x26c4, 0x37fc, 0xe05d, 0xc099, 0xcd8c, 0xd886,
-0xd8c3, 0xfcba, 0x2d83, 0x3fa6, 0x48bb, 0x1e77, 0x2a31, 0x31eb, 0xe98e, 0xbcf5,
-0xc196, 0xe4e4, 0xdb34, 0xf4b5, 0x398d, 0x47e8, 0x3526, 0x2168, 0x3d9a, 0x20eb,
-0xddcb, 0xbe09, 0xb85c, 0xe775, 0xe3f6, 0xedd1, 0x3731, 0x576a, 0x2d99, 0x1229,
-0x4011, 0x0fb4, 0xc58a, 0xc2e0, 0xc163, 0xd8b3, 0xe485, 0xfbc4, 0x28a2, 0x4aba,
-0x2b57, 0x06a4, 0x385f, 0x150e, 0xc2cd, 0xb65c, 0xcd33, 0xde60, 0xd4fe, 0x0096,
-0x3507, 0x45bc, 0x2781, 0x142c, 0x33ba, 0x049c, 0xc775, 0xb39c, 0xc6ec, 0xe39b,
-0xd75b, 0x0203, 0x3c34, 0x4589, 0x1c2f, 0x171d, 0x336b, 0xeff6, 0xbf31, 0xb8c6,
-0xc21c, 0xde19, 0xe412, 0x0b3a, 0x399a, 0x4631, 0x1799, 0x116c, 0x3085, 0xeefe,
-0xbcec, 0xb922, 0xcdc6, 0xe051, 0xe2d7, 0x10d0, 0x38e1, 0x3dfb, 0x1356, 0x1516,
-0x2876, 0xe6f8, 0xbb6a, 0xb636, 0xd128, 0xdda0, 0xdf16, 0x11df, 0x387e, 0x338c,
-0x0c5c, 0x211c, 0x2422, 0xdca8, 0xbf10, 0xb435, 0xcd32, 0xde18, 0xe25f, 0x144e,
-0x3fe0, 0x3472, 0x0753, 0x2b41, 0x27e8, 0xd555, 0xc117, 0xbddb, 0xcb8c, 0xdaa8,
-0xee16, 0x185e, 0x406a, 0x394d, 0x0e4c, 0x3224, 0x2283, 0xcee6, 0xb78f, 0xbe46,
-0xd600, 0xd73a, 0xf882, 0x2db5, 0x4253, 0x3500, 0x1558, 0x2eee, 0x13ba, 0xd1b3,
-0xb80a, 0xbd32, 0xe28d, 0xdf23, 0xfd44, 0x3980, 0x4ace, 0x2d3f, 0x18f4, 0x34ae,
-0x039f, 0xcc97, 0xbb5e, 0xbe2a, 0xe6fa, 0xe555, 0x023b, 0x3de8, 0x4db4, 0x2192,
-0x1578, 0x3a68, 0xfe29, 0xc84a, 0xbd0b, 0xc1ef, 0xe3a9, 0xe936, 0x0a3b, 0x3ab4,
-0x505a, 0x260d, 0x1903, 0x39c0, 0xf9ac, 0xc53b, 0xbc41, 0xcc45, 0xe5fc, 0xe843,
-0x15b8, 0x436d, 0x4dae, 0x24c5, 0x212b, 0x33f2, 0xf1b2, 0xc3a3, 0xb509, 0xcd57,
-0xe8db, 0xeb7c, 0x1d1e, 0x4aef, 0x4a01, 0x1af5, 0x24c7, 0x2df1, 0xe4a5, 0xc1ae,
-0xb8ad, 0xd2c8, 0xe887, 0xee7b, 0x21d0, 0x4d5f, 0x4806, 0x171f, 0x2854, 0x27e5,
-0xdd26, 0xc075, 0xb9c1, 0xd6dc, 0xe94e, 0xf760, 0x2a99, 0x4d0c, 0x4405, 0x1751,
-0x2a63, 0x1e7d, 0xd670, 0xba60, 0xb674, 0xde00, 0xe8fc, 0xf57e, 0x3121, 0x51b2,
-0x3a66, 0x11d4, 0x29d9, 0x107f, 0xd01f, 0xbbd1, 0xb864, 0xe08f, 0xea2a, 0xfafd,
-0x34de, 0x5038, 0x3061, 0x1294, 0x3316, 0x07d3, 0xc6ab, 0xbd82, 0xc0f2, 0xe421,
-0xebe4, 0x0398, 0x39c6, 0x54a2, 0x2e8b, 0x0e55, 0x3308, 0x0648, 0xc5ad, 0xbd8e,
-0xc53c, 0xdfb2, 0xe8b4, 0x0f4a, 0x3d14, 0x4caa, 0x2bf1, 0x15bf, 0x2e89, 0xf945,
-0xc136, 0xb890, 0xcaeb, 0xe950, 0xe7bf, 0x115d, 0x451b, 0x4aa1, 0x20cd, 0x1684,
-0x2a91, 0xf0a3, 0xc5b7, 0xb815, 0xc9bf, 0xee16, 0xea12, 0x117d, 0x470b, 0x42c7,
-0x113f, 0x1b7c, 0x2b91, 0xe191, 0xc212, 0xbd24, 0xc84b, 0xe419, 0xe8c1, 0x104f,
-0x440c, 0x4662, 0x1122, 0x20a6, 0x2d8e, 0xda8b, 0xbcf3, 0xc089, 0xcbf5, 0xde1c,
-0xf3c0, 0x2135, 0x414e, 0x3fd9, 0x15e1, 0x26f5, 0x292e, 0xdc7e, 0xb937, 0xb924,
-0xd769, 0xe06d, 0xee92, 0x2aa0, 0x48ae, 0x379d, 0x15e3, 0x2afa, 0x167d, 0xd370,
-0xbfeb, 0xb8aa, 0xd8da, 0xe695, 0xf331, 0x2abe, 0x4918, 0x2e1c, 0x0f19, 0x32cf,
-0x0f46, 0xc822, 0xbf6b, 0xbca2, 0xdadc, 0xe628, 0xf835, 0x2cf1, 0x4b03, 0x2c10,
-0x0df9, 0x358e, 0x0a2c, 0xc678, 0xc06b, 0xc05f, 0xd849, 0xe170, 0x02e1, 0x3324,
-0x4bd0, 0x2fc8, 0x13c8, 0x3314, 0x0029, 0xbf2e, 0xb455, 0xc1d3, 0xe027, 0xe480,
-0x0a7f, 0x2c7a, 0x5506, 0x634d, 0x2129, 0xfadf, 0xe1b5, 0xb620, 0x8bd2, 0xbfae,
-0x0a2a, 0x0d5d, 0x5240, 0x8109, 0x4e83, 0x15cf, 0xf367, 0xba2c, 0x9d5f, 0xcd2e,
-0xbdc8, 0xf85d, 0x6f35, 0x4484, 0x29e8, 0x54f0, 0x2a04, 0xcc06, 0xd6d5, 0xe253,
-0xc387, 0x09da, 0xff4a, 0xebc6, 0x4eb3, 0x2edb, 0xcfcc, 0x0b9a, 0x3d1b, 0xdc1f,
-0xf4a1, 0x3fae, 0xeb9b, 0xe915, 0x13be, 0xcb86, 0xb940, 0x1643, 0x18ee, 0xf7d9,
-0x4acf, 0x30df, 0xe6dc, 0x16fe, 0xf4d5, 0x9c55, 0xcc79, 0x10aa, 0xe384, 0x0496,
-0x4c2c, 0x0504, 0xff4c, 0x2d7e, 0xd93d, 0xacb4, 0x00e4, 0xf5af, 0xc18e, 0x2289,
-0x2a64, 0xe0a9, 0x2089, 0x21b8, 0xbaf3, 0xdd89, 0x1ea4, 0xd2e4, 0xe648, 0x37ea,
-0xec35, 0xe993, 0x35d6, 0xed2e, 0xbadd, 0x15b4, 0x0a9d, 0xc841, 0x1a7c, 0x191c,
-0xcaef, 0x0f4e, 0x1fff, 0xbfae, 0xe155, 0x3460, 0xeb55, 0xe0b6, 0x3048, 0xf2f2,
-0xddca, 0x235a, 0xee7f, 0xb7cc, 0x15dd, 0x2097, 0xce52, 0x180f, 0x2dcf, 0xd499,
-0x0857, 0x29b8, 0xc4c2, 0xd000, 0x28ff, 0xe652, 0xde94, 0x43c5, 0x05e6, 0xe425,
-0x356a, 0xfee7, 0xb2c1, 0x0914, 0x1584, 0xbe7b, 0x0e5a, 0x368a, 0xe276, 0x1274,
-0x3391, 0xd008, 0xd357, 0x26c2, 0xec06, 0xdd61, 0x39e2, 0x0868, 0xe6f9, 0x3207,
-0x091c, 0xbc0e, 0x0582, 0x1f6d, 0xd133, 0x1cab, 0x4d57, 0xeb81, 0x02e3, 0x3712,
-0xde41, 0xc71f, 0x212b, 0xfb67, 0xe7a1, 0x504a, 0x23ac, 0xedd8, 0x3eb6, 0x157e,
-0xad36, 0xfc30, 0x2995, 0xcb86, 0x10c5, 0x529b, 0xf7a7, 0x15fe, 0x4546, 0xdc21,
-0xcaba, 0x26eb, 0xe984, 0xd493, 0x4c8e, 0x16e6, 0xe56c, 0x463b, 0x1cf9, 0xb4a9,
-0xfd71, 0x24ab, 0xc8a4, 0x09c8, 0x41c1, 0xe4ff, 0x0a9c, 0x3d28, 0xd226, 0xc16f,
-0x2d0a, 0xf732, 0xcb2f, 0x42b2, 0x1d8f, 0xd5f3, 0x2c26, 0x1649, 0xa7c7, 0xed21,
-0x286f, 0xc688, 0x04e2, 0x51dd, 0xe73b, 0x0013, 0x46f0, 0xd1e8, 0xab29, 0x260f,
-0xf7aa, 0xbdee, 0x402d, 0x25c0, 0xda8b, 0x3989, 0x21df, 0xa95c, 0xf0ed, 0x290b,
-0xbd3d, 0xfb44, 0x4eba, 0xe63a, 0xfecd, 0x4a1d, 0xe177, 0xbc6f, 0x2af3, 0xfdf2,
-0xc4cf, 0x3b3d, 0x1ebb, 0xd4a0, 0x319d, 0x221e, 0xaf94, 0xf1b0, 0x3313, 0xcaf9,
-0xf7f2, 0x4fd1, 0xeb5b, 0xf54e, 0x3faa, 0xd925, 0xb016, 0x2624, 0x012e, 0xc2f3,
-0x3e16, 0x255d, 0xce61, 0x2b67, 0x1e8d, 0xa020, 0xe075, 0x2e2f, 0xc930, 0xf3f3,
-0x4f96, 0xe6da, 0xef8a, 0x43fb, 0xdd85, 0xab7b, 0x2022, 0xfe5f, 0xba39, 0x346d,
-0x27b4, 0xd20a, 0x2bfd, 0x2882, 0xae6f, 0xe3d3, 0x2b38, 0xc9c6, 0xef8e, 0x49d8,
-0xeade, 0xf2c2, 0x46de, 0xe8ca, 0xb2fe, 0x208e, 0x0855, 0xc5c4, 0x338e, 0x29eb,
-0xd645, 0x257e, 0x260c, 0xb7e2, 0xebef, 0x3365, 0xd6d8, 0xf811, 0x518d, 0xf457,
-0xf134, 0x4558, 0xf41a, 0xb66e, 0x1a28, 0x0bd1, 0xcaa3, 0x31f9, 0x3045, 0xe17a,
-0x2ad4, 0x2f2d, 0xbd2b, 0xe13e, 0x2cfe, 0xd3bd, 0xea52, 0x4fb4, 0x020e, 0xf40a,
-0x4278, 0xf8f7, 0xb45e, 0x127c, 0x0af1, 0xc2d1, 0x2b03, 0x36f1, 0xdd10, 0x20d2,
-0x35ec, 0xc074, 0xd7bd, 0x2eef, 0xd9db, 0xe543, 0x52c9, 0x05cf, 0xec53, 0x41bb,
-0xfa65, 0xaf2a, 0x15c6, 0x1274, 0xbe0e, 0x2c97, 0x448e, 0xdd59, 0x1c74, 0x3817,
-0xbb2b, 0xcf5b, 0x2f9a, 0xdc0c, 0xe4f0, 0x586d, 0x096c, 0xe913, 0x42c2, 0xf921,
-0xa4d2, 0x0f94, 0x157d, 0xbee7, 0x2a97, 0x46c2, 0xe0bf, 0x1d38, 0x3786, 0xb9af,
-0xcb2a, 0x2dd9, 0xd952, 0xdcbe, 0x5596, 0x0bab, 0xea4b, 0x4531, 0xffe2, 0xa78b,
-0x0c61, 0x136f, 0xb532, 0x2148, 0x44ae, 0xd96e, 0x195c, 0x392c, 0xb898, 0xc8e9,
-0x3388, 0xef92, 0xcd85, 0x0ef6, 0xf796, 0x13e1, 0x506a, 0x028d, 0xcd42, 0x14f5,
-0xf58e, 0x9d81, 0xe29f, 0xfb3c, 0xcd66, 0x1bbf, 0x6302, 0x30d7, 0x14e4, 0x29bc,
-0xdf14, 0xae5e, 0xce80, 0xabdc, 0xca7e, 0x3503, 0x1ee4, 0xf688, 0x5aac, 0x62a7,
-0xd87d, 0xd4d5, 0xfc76, 0xb6dd, 0xa5b5, 0xf6e7, 0x0b99, 0x0665, 0x381b, 0x1f19,
-0x1206, 0x2ed5, 0xebdd, 0xb56d, 0xde2e, 0xf87e, 0xce4d, 0xed47, 0x2439, 0x121c,
-0x1266, 0x1483, 0x16c8, 0x10fd, 0x0650, 0xd754, 0xbaff, 0xf7e2, 0xda39, 0xcd45,
-0x2986, 0x40dc, 0x0e53, 0x182a, 0x50a1, 0x01de, 0xcb6e, 0xdc62, 0xb781, 0xcfc4,
-0xee54, 0xf542, 0x2240, 0x5981, 0x2c5e, 0xf8e5, 0x3e3b, 0x0d29, 0xaf98, 0xc3b7,
-0xd787, 0xd3b1, 0xe2e2, 0x19c0, 0x28df, 0x3943, 0x2fe3, 0x081e, 0x2922, 0x0f78,
-0xc962, 0xb6cc, 0xd979, 0xe6a6, 0xd121, 0x07cf, 0x3500, 0x3ad0, 0x2c2a, 0x2624,
-0x2c95, 0xfb6f, 0xd7be, 0xb61f, 0xc05e, 0xe300, 0xd931, 0x0c0c, 0x4eae, 0x4878,
-0x15a7, 0x2a43, 0x31b1, 0xdd24, 0xc4ea, 0xbda7, 0xc680, 0xe6be, 0xf0c6, 0x13f8,
-0x45f0, 0x4cdc, 0x09ee, 0x185b, 0x3039, 0xdd40, 0xc562, 0xd19d, 0xd51e, 0xdcc7,
-0xfbf1, 0x1f9a, 0x3311, 0x4108, 0x10a0, 0x1d6d, 0x368a, 0xebc0, 0xbacd, 0xc61c,
-0xe6be, 0xd8c6, 0xecc7, 0x2b4f, 0x3ad6, 0x3234, 0x16aa, 0x312b, 0x2c20, 0xe5cf,
-0xbf0c, 0xc2d3, 0xef02, 0xde96, 0xe42b, 0x3264, 0x4f6e, 0x2b87, 0x1502, 0x434e,
-0x2169, 0xd824, 0xcd4a, 0xcbe5, 0xe67d, 0xe8bc, 0xf5fe, 0x2bd2, 0x4fbf, 0x2b2a,
-0x05aa, 0x4482, 0x2857, 0xcb20, 0xc28b, 0xdaa2, 0xe5a8, 0xd616, 0xfaa0, 0x2fc3,
-0x4640, 0x2ce5, 0x0f5a, 0x3ab7, 0x1944, 0xcda3, 0xbbcb, 0xcda1, 0xe22a, 0xd491,
-0x0143, 0x3873, 0x3fbe, 0x22bb, 0x1736, 0x3ae6, 0x0407, 0xc3a8, 0xb9c4, 0xc437,
-0xdc67, 0xd7ba, 0x00f1, 0x3801, 0x41a0, 0x1951, 0x11c6, 0x35de, 0xf7fb, 0xbeac,
-0xb811, 0xc658, 0xdc21, 0xd8e4, 0x060e, 0x39e5, 0x4146, 0x14d2, 0x16dd, 0x36f4,
-0xed6d, 0xba86, 0xb9b4, 0xcb20, 0xdd7e, 0xdfe1, 0x0f15, 0x3b82, 0x3e9b, 0x1158,
-0x1b8a, 0x323f, 0xe8e2, 0xbdfb, 0xb835, 0xd09f, 0xddf2, 0xdd36, 0x148a, 0x40d3,
-0x3e5f, 0x13a7, 0x2794, 0x2f4a, 0xde17, 0xbd25, 0xb6e3, 0xcb99, 0xdc56, 0xe6b9,
-0x1ce9, 0x4836, 0x40a4, 0x1189, 0x2c70, 0x2966, 0xd436, 0xb74c, 0xb722, 0xd074,
-0xdc0f, 0xf37b, 0x2f67, 0x4c6c, 0x3aa1, 0x13df, 0x2e82, 0x1863, 0xcd4e, 0xbc3f,
-0xbce0, 0xd9c4, 0xe1be, 0xfb8d, 0x359d, 0x4c01, 0x3625, 0x17b8, 0x32ce, 0x1032,
-0xcc89, 0xbc30, 0xbdba, 0xe2ec, 0xe81c, 0x005e, 0x3db9, 0x512c, 0x2c97, 0x17fc,
-0x380c, 0x06f5, 0xcdb1, 0xc0d4, 0xbe6b, 0xe241, 0xead9, 0x05a4, 0x3a27, 0x518a,
-0x2c10, 0x187d, 0x3809, 0xfd0c, 0xc4ac, 0xbff0, 0xc939, 0xe3de, 0xe907, 0x0ded,
-0x3e36, 0x4e75, 0x2456, 0x1759, 0x31b3, 0xf547, 0xc449, 0xba76, 0xcb7c, 0xe629,
-0xeb17, 0x17cc, 0x43ae, 0x4970, 0x1dfb, 0x1c5c, 0x2c1b, 0xe97c, 0xc40d, 0xbedd,
-0xd492, 0xe90c, 0xea14, 0x18aa, 0x44ec, 0x43bf, 0x15aa, 0x2421, 0x2f68, 0xe453,
-0xc2c4, 0xbef4, 0xd4c2, 0xe5c8, 0xf22d, 0x2430, 0x475e, 0x4461, 0x187f, 0x2916,
-0x2d8a, 0xe382, 0xc1ee, 0xc2fa, 0xe144, 0xe6ea, 0xf400, 0x30a7, 0x50eb, 0x4265,
-0x1b39, 0x2f67, 0x2260, 0xde78, 0xc61b, 0xc3e2, 0xe4c5, 0xea6e, 0xf9b7, 0x32e4,
-0x4b24, 0x330a, 0x1529, 0x377b, 0x1ad4, 0xd298, 0xc471, 0xc39e, 0xdfcf, 0xe493,
-0xf83e, 0x339f, 0x5169, 0x3178, 0x0fe4, 0x3634, 0x10e7, 0xcad8, 0xc188, 0xc0cb,
-0xd97a, 0xe36b, 0x01cf, 0x3255, 0x49ca, 0x2dc9, 0x1019, 0x33a3, 0x059a, 0xbd42,
-0xb33f, 0xbe30, 0xd9b3, 0xdc31, 0x0338, 0x37ee, 0x44ae, 0x224f, 0x0cf2, 0x27ab,
-0xf5dc, 0xbd67, 0xaf02, 0xbe02, 0xde1c, 0xd738, 0x02b2, 0x3eba, 0x4074, 0x174f,
-0x1829, 0x2c82, 0xe72a, 0xbf61, 0xb6b3, 0xbe85, 0xe2b1, 0xe25f, 0x05c1, 0x4181,
-0x4a2b, 0x1512, 0x1a96, 0x326a, 0xe3c7, 0xbc8c, 0xb7af, 0xbd6f, 0xd849, 0xe90a,
-0x150e, 0x3ed0, 0x469e, 0x176f, 0x1b23, 0x2908, 0xdb26, 0xb2f3, 0xb1f8, 0xca6a,
-0xdb06, 0xe6a5, 0x1fb9, 0x4383, 0x3e5d, 0x1596, 0x1e94, 0x1cb0, 0xd8cf, 0xba95,
-0xaec4, 0xcef4, 0xe43f, 0xeaf7, 0x2443, 0x4766, 0x336a, 0x0e32, 0x27a3, 0x1356,
-0xcd5d, 0xc150, 0xb6ba, 0xd1d8, 0xe528, 0xee84, 0x2426, 0x4adf, 0x3667, 0x10cd,
-0x310e, 0x1388, 0xcbbb, 0xc47e, 0xbd1f, 0xd491, 0xe98e, 0x0244, 0x3289, 0x53b3,
-0x3eb9, 0x1566, 0x3290, 0x11e3, 0xcc07, 0xc004, 0xc4fd, 0xe223, 0xed0a, 0x10ae,
-0x3ff0, 0x5037, 0x36e6, 0x164f, 0x29a1, 0x0284, 0xcdb8, 0xbdcd, 0xc637, 0xed96,
-0xeeb1, 0x0cd0, 0x4050, 0x49bb, 0x239a, 0x1780, 0x2eab, 0xf6b6, 0xce3d, 0xbc38,
-0xc8a0, 0x00e6, 0xefad, 0x0021, 0x33f9, 0x3ae3, 0x3cd3, 0x3fb1, 0x1838, 0xd924,
-0xd541, 0xaecf, 0xa5de, 0xf7be, 0xfc4c, 0x140b, 0x790a, 0x7937, 0x1616, 0xfecc,
-0xe9f4, 0x93de, 0xa330, 0xc0f0, 0xcf7e, 0x2cbc, 0x6286, 0x4ccf, 0x462d, 0x450f,
-0xe74f, 0xa99c, 0xd6b1, 0xc669, 0xba55, 0xfefe, 0x25a9, 0x3149, 0x43ec, 0x1f26,
-0xede2, 0x0adf, 0xff6f, 0xbdad, 0xf121, 0x2c23, 0xf18d, 0xf0cc, 0x2718, 0xe6c1,
-0xbbba, 0x1d92, 0x14c7, 0xde85, 0x3e57, 0x31f4, 0xe295, 0x0f8d, 0xf992, 0xa267,
-0xd117, 0x1bec, 0xe179, 0x07c9, 0x5af9, 0x03a7, 0x02e9, 0x3014, 0xd04d, 0xa794,
-0xfb7e, 0xf282, 0xc715, 0x36b9, 0x3764, 0xea25, 0x307a, 0x1cb0, 0xb2ec, 0xd406,
-0x117c, 0xd2a9, 0xea54, 0x43e9, 0xfc21, 0xfaa3, 0x3fc1, 0xeafd, 0xb060, 0x0b4c,
-0x0ff9, 0xc461, 0x1954, 0x3040, 0xd984, 0x1601, 0x2825, 0xbc3f, 0xdbce, 0x3875,
-0xe248, 0xdd2e, 0x4e02, 0xfd2c, 0xd91c, 0x3749, 0xf658, 0xaa69, 0x13e1, 0x2498,
-0xcc14, 0x21ba, 0x3a26, 0xdb15, 0x1623, 0x2c3d, 0xba40, 0xcd2e, 0x2cf5, 0xe4ae,
-0xe186, 0x52e0, 0x0d31, 0xe5cf, 0x3778, 0xffc1, 0xac3d, 0xfddf, 0x1bac, 0xc8ec,
-0x14d4, 0x4029, 0xe79d, 0x15d6, 0x3792, 0xcc34, 0xca86, 0x3225, 0xf50a, 0xcf32,
-0x3e28, 0x12b9, 0xe181, 0x364b, 0x1002, 0xb4c9, 0x031c, 0x26d6, 0xd0a9, 0x1e6a,
-0x443a, 0xd350, 0x08d3, 0x41ed, 0xc7a2, 0xb99c, 0x2fe3, 0xff21, 0xdc75, 0x4839,
-0x19bb, 0xe84c, 0x32f7, 0x01b7, 0xaddf, 0xfef1, 0x1e1c, 0xcae8, 0x16e4, 0x4bda,
-0xecbb, 0x0caf, 0x3f24, 0xe0dc, 0xc4bc, 0x18da, 0xf67e, 0xdd77, 0x3908, 0x10f4,
-0xed5b, 0x4369, 0x1b8d, 0xb980, 0x0190, 0x297a, 0xc6e3, 0x009e, 0x4462, 0xea33,
-0x0155, 0x3cba, 0xe27f, 0xcbef, 0x2bda, 0xf9a0, 0xd4bc, 0x439f, 0x150b, 0xd559,
-0x344d, 0x1a5b, 0xaf57, 0xf935, 0x2de0, 0xcf9a, 0x0979, 0x49a9, 0xea95, 0x051a,
-0x3cdb, 0xd6df, 0xbc25, 0x2174, 0xf28b, 0xc89b, 0x4222, 0x2645, 0xdfc1, 0x315e,
-0x201e, 0xb2fc, 0xe3d4, 0x181b, 0xc442, 0xfd80, 0x4a43, 0xed31, 0xff1f, 0x4381,
-0xdf06, 0xb4dc, 0x1fd7, 0xf6dc, 0xbffe, 0x3a30, 0x24f3, 0xd6d6, 0x297b, 0x1c5d,
-0xaf37, 0xedb8, 0x286b, 0xc61d, 0xfe95, 0x515b, 0xe559, 0xf3c9, 0x4090, 0xd830,
-0xae85, 0x1db8, 0xf7ec, 0xc607, 0x3f9f, 0x264d, 0xd94a, 0x2a8a, 0x1485, 0xa002,
-0xdeaf, 0x235b, 0xc381, 0xfa49, 0x5796, 0xefa6, 0xf6b9, 0x4056, 0xd904, 0xa813,
-0x17bf, 0xf931, 0xbf26, 0x3e31, 0x2c1d, 0xd50a, 0x2d55, 0x22b9, 0xa846, 0xdf9f,
-0x28c5, 0xc598, 0xef6b, 0x51e5, 0xf17d, 0xfa6e, 0x46ce, 0xddcb, 0xac63, 0x1bcf,
-0xff42, 0xc08e, 0x3b8a, 0x30ab, 0xd540, 0x2b2a, 0x2b14, 0xb01e, 0xe003, 0x2eb4,
-0xd207, 0xf705, 0x5a04, 0xf5f1, 0xf4f2, 0x49c1, 0xe735, 0xac7d, 0x1ff2, 0x0bc1,
-0xc150, 0x3a15, 0x3cd0, 0xdc44, 0x29ee, 0x3079, 0xb504, 0xdcbb, 0x2cd7, 0xcfca,
-0xeed8, 0x5c84, 0xfe19, 0xf346, 0x4ec0, 0xf24e, 0xa9a2, 0x1b01, 0x120e, 0xbf61,
-0x31bd, 0x3ed0, 0xdca8, 0x27d7, 0x3553, 0xb79f, 0xddc0, 0x376a, 0xd743, 0xea45,
-0x592a, 0xf9f4, 0xe94c, 0x4a1d, 0xf552, 0xa9a1, 0x19d2, 0x14c6, 0xbc9b, 0x2b11,
-0x3913, 0xd2dc, 0x1f02, 0x340a, 0xb6b6, 0xd426, 0x33f8, 0xd9a8, 0xdc7f, 0x5123,
-0xfd3a, 0xde46, 0x40ce, 0xfa10, 0xa997, 0x14a8, 0x1bb4, 0xc08d, 0x2376, 0x3d24,
-0xd503, 0x166b, 0x35f1, 0xbc86, 0xd0fa, 0x36e8, 0xf1a1, 0xd628, 0x16ed, 0xf145,
-0x0d1a, 0x55e9, 0x09b3, 0xd0ea, 0x189e, 0xfae5, 0xa1d9, 0xe581, 0xfd1f, 0xd241,
-0x1ffa, 0x5b9f, 0x2d05, 0x1f94, 0x316b, 0xe330, 0xba22, 0xd9ab, 0xb354, 0xcfaa,
-0x3059, 0x1e34, 0xfcfc, 0x565e, 0x623a, 0xe738, 0xe027, 0xfe57, 0xc099, 0xb327,
-0xf470, 0x0c3c, 0x0e38, 0x38fd, 0x1a11, 0x0892, 0x3339, 0xf5c3, 0xbab1, 0xe297,
-0xf843, 0xce95, 0xe620, 0x1c2a, 0x09ee, 0x1283, 0x1b02, 0x1187, 0x188b, 0x0e86,
-0xd87e, 0xb652, 0xeca9, 0xdb2d, 0xc7dd, 0x1fe5, 0x379e, 0x0fd2, 0x1c45, 0x4c2e,
-0x1316, 0xd85d, 0xdfc8, 0xb6df, 0xc87f, 0xeb35, 0xe54a, 0x1628, 0x57e4, 0x3419,
-0xff6c, 0x4156, 0x1c74, 0xb5b4, 0xca06, 0xd49b, 0xc6db, 0xdff3, 0x0f42, 0x1c9b,
-0x38c2, 0x3cc3, 0x059b, 0x2a27, 0x2699, 0xce85, 0xb4f9, 0xd393, 0xdea9, 0xcdb3,
-0x03e7, 0x3281, 0x3d54, 0x3c61, 0x2583, 0x2ce2, 0x0c86, 0xdb4d, 0xb3bf, 0xbb9c,
-0xe353, 0xd3fa, 0x034f, 0x4cdb, 0x4ab4, 0x21fa, 0x2b59, 0x391f, 0xeb27, 0xc6cb,
-0xb8e4, 0xba9a, 0xe811, 0xec0e, 0x0c31, 0x4bdb, 0x5772, 0x163d, 0x1a19, 0x3f4d,
-0xe9e8, 0xc3a2, 0xce2a, 0xc788, 0xd9f4, 0xf83e, 0x1bc6, 0x3ce8, 0x5548, 0x1db0,
-0x1a55, 0x4521, 0xf1e2, 0xb3ab, 0xc2fd, 0xdbe1, 0xd800, 0xed52, 0x2c30, 0x402d,
-0x430b, 0x23ff, 0x260b, 0x2f76, 0xea68, 0xb3d7, 0xb28e, 0xe14a, 0xdd06, 0xe066,
-0x33b3, 0x51ec, 0x33b4, 0x1667, 0x3052, 0x1b77, 0xd41e, 0xc1bd, 0xb6c4, 0xd7a4,
-0xeae0, 0xe9c9, 0x2119, 0x50ee, 0x3348, 0x0504, 0x35a7, 0x2224, 0xc555, 0xbad4,
-0xc362, 0xd0c4, 0xdade, 0xf6c3, 0x247a, 0x463c, 0x3726, 0x098e, 0x2ae9, 0x1a2f,
-0xc9d7, 0xb0fe, 0xc012, 0xdaac, 0xd5e1, 0xf9b0, 0x351f, 0x47da, 0x2cc6, 0x10fb,
-0x2d9f, 0x068e, 0xc5e3, 0xb7fe, 0xc297, 0xe2b0, 0xe422, 0x01db, 0x36ef, 0x48cb,
-0x23b7, 0x10de, 0x3507, 0x0307, 0xc7bf, 0xbff3, 0xc77c, 0xe128, 0xe56e, 0x0857,
-0x3924, 0x4aaf, 0x2249, 0x103e, 0x31eb, 0xfa7b, 0xc42a, 0xbff2, 0xca69, 0xdf50,
-0xe715, 0x1070, 0x37d6, 0x4303, 0x1eac, 0x16ba, 0x3184, 0xf739, 0xc4f5, 0xba46,
-0xcd7e, 0xe4d0, 0xe592, 0x10ee, 0x3d09, 0x4044, 0x17ce, 0x2016, 0x2f3f, 0xe9e5,
-0xc633, 0xbad5, 0xc6f9, 0xdeac, 0xe624, 0x121c, 0x413b, 0x4301, 0x1783, 0x29fd,
-0x2ba5, 0xdaa4, 0xbe2e, 0xbb8e, 0xcbc8, 0xdde4, 0xf1e9, 0x21db, 0x439b, 0x4190,
-0x172e, 0x27a0, 0x21f8, 0xd636, 0xbad8, 0xb8bf, 0xd096, 0xdf64, 0xf8a8, 0x2b93,
-0x443b, 0x3b96, 0x185e, 0x26da, 0x10a6, 0xd167, 0xbdb5, 0xb977, 0xdb3a, 0xe708,
-0xfa86, 0x2f52, 0x4806, 0x3265, 0x17a3, 0x31bc, 0x0e05, 0xd510, 0xc461, 0xbd66,
-0xe192, 0xed77, 0x0119, 0x32ba, 0x50ed, 0x31ea, 0x16d3, 0x36ec, 0x0732, 0xcfc7,
-0xc460, 0xc184, 0xdf83, 0xea58, 0x0626, 0x3550, 0x5246, 0x2def, 0x16cd, 0x3427,
-0xfd3a, 0xc953, 0xbd3c, 0xc544, 0xe4ec, 0xf153, 0x166b, 0x3e10, 0x4e6d, 0x26d4,
-0x1968, 0x2f16, 0xf428, 0xcae0, 0xbedd, 0xccf8, 0xe956, 0xefa2, 0x1950, 0x4297,
-0x4a75, 0x1de5, 0x1955, 0x29ba, 0xeb91, 0xc61c, 0xbb12, 0xce33, 0xe7ce, 0xefe6,
-0x18c6, 0x3e32, 0x43c5, 0x1922, 0x1cc3, 0x20fd, 0xde2b, 0xbf55, 0xb70b, 0xd16f,
-0xe788, 0xef8e, 0x20c4, 0x4654, 0x3d93, 0x11d7, 0x1d2e, 0x15c5, 0xd810, 0xc122,
-0xb7df, 0xd5bd, 0xe934, 0xf5a0, 0x24cd, 0x4321, 0x356b, 0x10be, 0x2522, 0x0e25,
-0xcdbf, 0xc120, 0xbd1c, 0xd9ef, 0xe950, 0xf8ec, 0x2940, 0x4a04, 0x31e9, 0x09bb,
-0x2935, 0x0de2, 0xcd32, 0xc3e0, 0xc0ad, 0xd96f, 0xebee, 0x0617, 0x2f65, 0x4a9d,
-0x32b8, 0x104d, 0x2b20, 0x042c, 0xc6fe, 0xc0fc, 0xccb1, 0xe4c6, 0xe7e5, 0x0a2f,
-0x3646, 0x44a9, 0x27ed, 0x0f84, 0x2482, 0xf9ba, 0xc9c9, 0xbc46, 0xc6f1, 0xe7c9,
-0xe7b4, 0x0935, 0x38ab, 0x3dfb, 0x17f4, 0x1202, 0x2366, 0xe8cf, 0xc894, 0xc02b,
-0xc4e7, 0xe682, 0xe9b4, 0x07dc, 0x39bc, 0x4323, 0x1255, 0x11a3, 0x2383, 0xde38,
-0xc201, 0xc28c, 0xc797, 0xe30e, 0xf319, 0x11aa, 0x3329, 0x3e07, 0x11d9, 0x1242,
-0x2173, 0xdd6c, 0xbc12, 0xbfc4, 0xd3cc, 0xe301, 0xf14f, 0x1ed7, 0x3c0b, 0x3bbe,
-0x150a, 0x16d9, 0x1504, 0xded6, 0xc844, 0xc0c3, 0xdedd, 0xf0d7, 0xf666, 0x25d8,
-0x4424, 0x33d0, 0x130e, 0x2876, 0x1370, 0xd7a6, 0xcf17, 0xc604, 0xdfb9, 0xf3d2,
-0xfde9, 0x29bc, 0x4a3a, 0x328f, 0x0b59, 0x293f, 0x0f84, 0xd398, 0xd04b, 0xc938,
-0xdc96, 0xf077, 0x05ff, 0x2a1d, 0x46e9, 0x33e3, 0x0e06, 0x27af, 0x084b, 0xcbee,
-0xc5ed, 0xce50, 0xe4ec, 0xee95, 0x0fc4, 0x3481, 0x4291, 0x2ab8, 0x0ee7, 0x217a,
-0xfbca, 0xd072, 0xc584, 0xcdc2, 0xeeae, 0xf284, 0x0beb, 0x2a91, 0x499c, 0x4ab9,
-0x1751, 0xfb4e, 0xdff4, 0xc548, 0xaa11, 0xcb25, 0x079b, 0x0c5f, 0x3e98, 0x6247,
-0x3e07, 0x0f43, 0xf0e4, 0xca5f, 0xb34f, 0xd401, 0xc893, 0xf3d1, 0x4c26, 0x308b,
-0x22b3, 0x41c0, 0x2279, 0xdc8b, 0xdff8, 0xe310, 0xcceb, 0x027f, 0xf615, 0xee06,
-0x3db0, 0x2392, 0xe01d, 0x1366, 0x3415, 0xe34c, 0xf6fc, 0x29c3, 0xe8c4, 0xee7a,
-0x0fa2, 0xddee, 0xd84b, 0x1d1b, 0x1722, 0xff58, 0x3ac2, 0x1f74, 0xf03f, 0x1870,
-0xfcd6, 0xbff1, 0xe68f, 0x1180, 0xed1f, 0x0a12, 0x3895, 0x07ec, 0x0a31, 0x24b3,
-0xe648, 0xc9fc, 0x0734, 0xf757, 0xd412, 0x1f4f, 0x1e8b, 0xee37, 0x1f0e, 0x1be3,
-0xd43a, 0xefa3, 0x194b, 0xddce, 0xf237, 0x287d, 0xeedf, 0xf88e, 0x2f7f, 0xf704,
-0xd874, 0x1c88, 0x0972, 0xd8d5, 0x1702, 0x0f28, 0xe05e, 0x15f4, 0x1a7c, 0xd9ff,
-0xf6eb, 0x29b0, 0xf002, 0xf068, 0x23d5, 0xf4b8, 0xf046, 0x1d23, 0xf157, 0xd110,
-0x1519, 0x14cc, 0xdede, 0x142d, 0x1a12, 0xe515, 0x0b1c, 0x1636, 0xd4d5, 0xe629,
-0x1cf8, 0xe7c6, 0xea58, 0x2b1f, 0xfc3e, 0xeeea, 0x236a, 0xfb53, 0xcfca, 0x089d,
-0x0488, 0xd160, 0x0a55, 0x141d, 0xe5cd, 0x107d, 0x186d, 0xd8c8, 0xeaf7, 0x1870,
-0xe826, 0xe955, 0x18d7, 0xf4b0, 0xf2f4, 0x198f, 0xf637, 0xd898, 0x0a60, 0x099d,
-0xe121, 0x112c, 0x19f0, 0xe9f0, 0x0257, 0x16f3, 0xea68, 0xe825, 0x11db, 0xf73d,
-0xf784, 0x22c2, 0x01a7, 0xfa94, 0x2329, 0xff98, 0xd3ac, 0x066b, 0x0f20, 0xe092,
-0x0cc3, 0x1ddc, 0xf6f5, 0x1320, 0x1de5, 0xe877, 0xf111, 0x167b, 0xeabe, 0xf59b,
-0x2682, 0xf99e, 0xf763, 0x2689, 0x0359, 0xdfbd, 0x0e98, 0x0da2, 0xe78d, 0x0e20,
-0x0ddb, 0xeff0, 0x11e2, 0x1312, 0xe459, 0xf4b0, 0x1704, 0xee92, 0xf4ab, 0x1ec2,
-0xfc20, 0xf450, 0x169f, 0xfcad, 0xdbac, 0x0468, 0x089e, 0xe794, 0x0e53, 0x118e,
-0xefe9, 0x0e4a, 0x169a, 0xe1da, 0xebc0, 0x15eb, 0xefcb, 0xf2ee, 0x1beb, 0xfce8,
-0xfa9c, 0x1c17, 0xffdb, 0xe6b1, 0x0fc5, 0x065c, 0xe6be, 0x10a6, 0x0c31, 0xefee,
-0x1306, 0x13f9, 0xe94c, 0xfe45, 0x19f0, 0xf32a, 0xfe85, 0x1905, 0xf62a, 0xfd6b,
-0x1747, 0xf729, 0xeaea, 0x11d1, 0x0593, 0xf301, 0x1786, 0x0b5f, 0xf124, 0x0940,
-0x0668, 0xe6ec, 0xfe96, 0x1506, 0xf474, 0x04f3, 0x1923, 0xf708, 0xfe00, 0x1197,
-0xf0a5, 0xe784, 0x0dcb, 0xff73, 0xf084, 0x1476, 0x091e, 0xf640, 0x0af0, 0x0286,
-0xe773, 0xfd6b, 0x0efa, 0xf175, 0xf89a, 0x07af, 0xf9a6, 0x0516, 0x128d, 0x00ff,
-0xfb4e, 0x0ed0, 0xfc70, 0xe60e, 0xf53d, 0xf46c, 0xf494, 0x0bff, 0x1551, 0x06e1,
-0x0c9f, 0x0f55, 0xefab, 0xed70, 0xf731, 0xf0fe, 0xfd13, 0x0d56, 0x068f, 0x0174,
-0x0fee, 0xffe4, 0xea15, 0xfb9a, 0xffd4, 0xf166, 0xfe33, 0x0e6f, 0xfeb8, 0x0068,
-0x0cad, 0xf543, 0xef47, 0x0118, 0xf5be, 0xeb4f, 0x04dc, 0x09b3, 0xf586, 0x0081,
-0x05bb, 0xf123, 0xf60d, 0x03d9, 0xf8d9, 0xfe28, 0x0dac, 0xfb79, 0xf27c, 0xfe7f,
-0xf2c5, 0xeeb0, 0x04d2, 0x030d, 0xfb07, 0x0e9e, 0x0d11, 0xf686, 0xfc94, 0xffbf,
-0xed59, 0xf589, 0x05ab, 0xfa48, 0xffa7, 0x10c1, 0x014b, 0xfa25, 0x09af, 0xfdfc,
-0xf0ef, 0x03b9, 0x0400, 0xf635, 0x063f, 0x0b0b, 0xf9ca, 0x03dd, 0x0d8d, 0xfce6,
-0x00df, 0x0f4b, 0x024e, 0xff59, 0x0dc5, 0x0159, 0xf654, 0x067a, 0x0580, 0xfe5c,
-0x0e74, 0x0f97, 0x0220, 0x099e, 0x09f1, 0xf6cc, 0xfa19, 0x04a0, 0xfb69, 0x0199,
-0x10a2, 0x0726, 0x02f2, 0x0c0d, 0x00c5, 0xf7e4, 0x056d, 0x020c, 0xf921, 0x0880,
-0x0a05, 0xfc9b, 0x05b1, 0x0ba8, 0xfd73, 0x0126, 0x0afa, 0xfedb, 0xfe8e, 0x0754,
-0xff08, 0x010e, 0x0a12, 0xff2a, 0xfc7a, 0x0965, 0x0306, 0xfbf9, 0x0735, 0x05c2,
-0xfdbe, 0x020b, 0x01d4, 0xfd23, 0x035d, 0x0690, 0x0006, 0x0536, 0x0b42, 0x02fd,
-0x0048, 0x04d9, 0xffac, 0xfb96, 0x0522, 0x06ea, 0x01a3, 0x0640, 0x0721, 0x02e7,
-0x04ad, 0x0494, 0xfe70, 0x009e, 0x0380, 0xfafb, 0xfecf, 0x0890, 0x0224, 0xffd6,
-0x0613, 0x005f, 0xfada, 0x0129, 0xfdf3, 0xf949, 0x014d, 0x006d, 0xfa91, 0x0029,
-0x002c, 0xf7d8, 0xff02, 0x0615, 0xfbc4, 0xfc2b, 0x035b, 0xfb89, 0xf601, 0xfa4f,
-0xfabf, 0xfbd9, 0x00a3, 0xfe0a, 0xfbd4, 0x0009, 0xfe8b, 0xf866, 0xf96c, 0xfcbd,
-0xf750, 0xf6d5, 0xfee5, 0xfea6, 0xfc47, 0x00a5, 0x013f, 0xfaa4, 0xf910, 0xf98a,
-0xf6f0, 0xfa55, 0xfc01, 0xfac1, 0xff53, 0x001d, 0xfac1, 0xfb9d, 0xfef2, 0xf9c9,
-0xf9ce, 0xff10, 0xfabf, 0xfab8, 0xfe59, 0xfa05, 0xfa90, 0x00a1, 0xff54, 0xfdbe,
-0x0243, 0xff6b, 0xfac6, 0xfde2, 0xfc78, 0xf927, 0xfc12, 0xfe2f, 0xfc8a, 0xfe15,
-0x00a9, 0xff55, 0x0011, 0x0049, 0xfbfb, 0xfa18, 0xfd23, 0xfbc7, 0xf7ac, 0xfd25,
-0x019e, 0x0030, 0x02a9, 0x0344, 0x0053, 0x0036, 0x003f, 0xfc42, 0xfd77, 0x047f,
-0x022f, 0xffd5, 0x0747, 0x065b, 0xffcd, 0x058c, 0x0801, 0x00b8, 0x029f, 0x057c,
-0x0228, 0x02a9, 0x03ae, 0x0336, 0x052e, 0x06d3, 0x0355, 0x0367, 0x097b, 0x0767,
-0x040b, 0x0708, 0x062b, 0x00f3, 0x010e, 0x0624, 0x0661, 0x0641, 0x0870, 0x08cf,
-0x095c, 0x0672, 0x0114, 0x0064, 0x0450, 0x0372, 0x00f0, 0x074e, 0x0927, 0x0375,
-0x04d0, 0x06fa, 0x0278, 0x00e0, 0x023e, 0x0105, 0x0392, 0x0478, 0x01dc, 0x0633,
-0x06ad, 0x0137, 0x035b, 0x071e, 0x039a, 0x00b9, 0x0238, 0x0257, 0x03b3, 0x032c,
-0x00b5, 0x062b, 0x0920, 0x0425, 0x05d7, 0x09b0, 0x0457, 0x011e, 0x02cb, 0x0112,
-0x01e7, 0x03e0, 0x04a0, 0x09f0, 0x0993, 0x025d, 0x03ab, 0x06f0, 0x01ce, 0xffa9,
-0x0343, 0x03bf, 0x02bc, 0x0192, 0x0175, 0x03f8, 0x025f, 0xfe13, 0xffaf, 0x037b,
-0x017f, 0xff0d, 0x010c, 0x01cc, 0xff47, 0xfda7, 0xff79, 0xffc8, 0xfd08, 0xfdcd,
-0x01e5, 0x03c0, 0x00fa, 0xfdf8, 0xfdb9, 0xff87, 0xff9b, 0xfbe2, 0xfeae, 0x0380,
-0x0014, 0xfe6f, 0x0115, 0x0048, 0xfe1d, 0xff3b, 0xff7b, 0xff0a, 0x0012, 0xfed0,
-0xfed6, 0xffe0, 0xfcbf, 0xfbdb, 0x005d, 0xffb1, 0xf9ae, 0xfb2b, 0x0004, 0xff44,
-0xfc6c, 0xfb62, 0xfdf8, 0xff0d, 0xfbbb, 0xfae7, 0xfd8a, 0xfd70, 0xfaee, 0xfbe3,
-0xfdf3, 0xfc89, 0xfa9a, 0xfb6e, 0xfd82, 0xfcb8, 0xfaa3, 0xfc2a, 0xfeb9, 0xfc5c,
-0xf8a1, 0xfb85, 0x000c, 0xfee7, 0xfbc5, 0xfc1f, 0xfee8, 0xfdac, 0xfae0, 0xfc8b,
-0xfef5, 0xfebd, 0xfdf5, 0xfec1, 0x0023, 0xff0f, 0xfc4a, 0xfdd7, 0x00f5, 0xfea6,
-0xfd0c, 0x002f, 0x0087, 0xfc77, 0xfc93, 0x0024, 0x013b, 0x00dc, 0xfdb0, 0xfcbd,
-0x0060, 0xfed8, 0xfc65, 0xfff5, 0x0160, 0xfef8, 0x0045, 0x0243, 0x0065, 0xfff6,
-0x0124, 0x00f9, 0x00f5, 0x00ae, 0xff8e, 0x00df, 0x02e1, 0xffa3, 0xfea2, 0x0390,
-0x035d, 0xff35, 0xff1f, 0x009b, 0x0048, 0xffed, 0x0005, 0xfff7, 0x0019, 0xff23,
-0xfe36, 0xff91, 0x0112, 0x0088, 0xfff6, 0x00fa, 0x00a3, 0xfe18, 0xfe82, 0x01b6,
-0x00ae, 0xfead, 0x018f, 0x02ef, 0x0126, 0x002b, 0xffb6, 0x01e3, 0x0382, 0x00b0,
-0x00bd, 0x0402, 0x024e, 0x0002, 0x02e3, 0x0327, 0x00b6, 0x01cf, 0x02ca, 0x0250,
-0x0280, 0x01bd, 0x021d, 0x04f6, 0x0340, 0xfee9, 0x0095, 0x0305, 0x00bc, 0x012c,
-0x04fc, 0x0469, 0x0257, 0x027e, 0x0242, 0x01ad, 0x014b, 0x00c3, 0x0147, 0x037a,
-0x036a, 0x00b5, 0x0068, 0x0121, 0xff9a, 0xfec8, 0x0143, 0x0151, 0xfd18, 0xfced,
-0xffbd, 0x0066, 0x007d, 0xff3b, 0xfdd4, 0xfe9a, 0xff0d, 0xfdc1, 0xfe33, 0xffd7,
-0xfd45, 0xfbe9, 0xffc6, 0xff2d, 0xfb3e, 0xfd69, 0x0057, 0xff59, 0xffc4, 0x00ad,
-0x0017, 0xffc4, 0xfde4, 0xfc22, 0xfe08, 0x004b, 0xffd4, 0x0028, 0x0265, 0x00fa,
-0xfdc5, 0xfe0b, 0xff0e, 0xfe78, 0xfdca, 0xfe74, 0xff9b, 0x005c, 0x0106, 0x00eb,
-0x015c, 0x01a8, 0xff52, 0xfee2, 0x00ee, 0xffbe, 0xfec8, 0x010d, 0x01ab, 0x00d9,
-0x0106, 0x010d, 0x00e8, 0x0118, 0x00e8, 0x012b, 0x02b4, 0x0211, 0xff7a, 0xff8e,
-0x0115, 0x0100, 0x00de, 0x02dd, 0x0379, 0x00f9, 0xffd1, 0x0018, 0xfff6, 0xfffa,
-0x000c, 0xfff1, 0x0004, 0x0012, 0xffc4, 0x009c, 0x010c, 0xfffb, 0xffe4, 0x001a,
-0xfff2, 0xfffc, 0x0012, 0xffe2, 0x0015, 0x015a, 0x0257, 0x01c9, 0x004d, 0xfff9,
-0xffdd, 0x0059, 0x019b, 0x004f, 0x0095, 0x030f, 0x0191, 0xff96, 0x015d, 0x0296,
-0x01ee, 0x0205, 0x01f5, 0x0220, 0x0303, 0x0276, 0x01b6, 0x02a2, 0x02f4, 0x01f9,
-0x0209, 0x01e3, 0x0073, 0x00ad, 0x0219, 0x0205, 0x00f2, 0x000a, 0xffc0, 0x00c9,
-0x0105, 0xffac, 0x007c, 0x0198, 0x0051, 0xffcf, 0x001b, 0xfff4, 0x0001, 0x0002,
-0xfffe, 0xfffb, 0x0005, 0xfffd, 0xfff3, 0x0025, 0xff14, 0xfe3b, 0xffa5, 0xfffc,
-0xfee0, 0xff17, 0xffe8, 0x0010, 0xffec, 0x0017, 0xffe5, 0xff21, 0xfef3, 0xfef8,
-0xff4b, 0x002c, 0xffc0, 0xfee9, 0xffc3, 0x001f, 0xff65, 0xffbc, 0x001d, 0xfff2,
-000000, 0x0003, 0xfffc, 0xfffc, 0x000a, 0xffec, 0x0015, 0x0095, 0x002c, 0xffc9,
-0x006a, 0x0078, 0xfff2, 0xfffb, 0x0006, 0xfffa, 0x0002, 0xfffd, 0x0004, 0xfff4,
-0x0010, 0xfff2, 0xfff7, 0x003a, 0xfeb1, 0xfe3a, 0xfff4, 0x0020, 0xffde, 0x0015,
-0xfff6, 000000, 0x0002, 0xfffc, 0x0001, 0xfffe, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000 };
diff --git a/1.4/codecs/Makefile b/1.4/codecs/Makefile
deleted file mode 100644
index a32d157a8..000000000
--- a/1.4/codecs/Makefile
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for codec modules
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# Mark Spencer <markster@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=CODECS
-MENUSELECT_DESCRIPTION=Codec Translators
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard codec_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard codec_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_CODECS),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_CODECS),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring codecs,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-LIBILBC:=ilbc/libilbc.a
-LIBLPC10:=lpc10/liblpc10.a
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
-
-ifneq ($(GSM_INTERNAL),no)
-GSM_INCLUDE:=-Igsm/inc
-$(if $(filter codec_gsm,$(EMBEDDED_MODS)),modules.link,codec_gsm.so): gsm/lib/libgsm.a
-endif
-
-clean::
- $(MAKE) -C gsm clean
- $(MAKE) -C lpc10 clean
- $(MAKE) -C ilbc clean
-
-gsm/lib/libgsm.a:
- @mkdir -p gsm/lib
- @$(MAKE) -C gsm lib/libgsm.a
-
-$(LIBLPC10):
- @$(MAKE) -C lpc10 all
-
-$(if $(filter codec_lpc10,$(EMBEDDED_MODS)),modules.link,codec_lpc10.so): $(LIBLPC10)
-
-$(LIBILBC):
- @$(MAKE) -C ilbc all ASTCFLAGS="$(filter-out -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) $(AST_NO_STRICT_OVERFLOW)"
-
-$(if $(filter codec_ilbc,$(EMBEDDED_MODS)),modules.link,codec_ilbc.so): $(LIBILBC)
diff --git a/1.4/codecs/adpcm_slin_ex.h b/1.4/codecs/adpcm_slin_ex.h
deleted file mode 100644
index c3f86c72d..000000000
--- a/1.4/codecs/adpcm_slin_ex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*! \file
- * adpcm_slin_ex.h --
- *
- * \brief 4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
- *
- * Source: g723.example
- *
- * Copyright (C) 2001-2005, Digium, Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char adpcm_slin_ex[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/1.4/codecs/codec_a_mu.c b/1.4/codecs/codec_a_mu.c
deleted file mode 100644
index b9c1c4938..000000000
--- a/1.4/codecs/codec_a_mu.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief codec_a_mu.c - translate between alaw and ulaw directly
- *
- * \ingroup codecs
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/channel.h"
-#include "asterisk/alaw.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/utils.h"
-
-#define BUFFER_SAMPLES 8000 /* size for the translation buffers */
-
-static unsigned char mu2a[256];
-static unsigned char a2mu[256];
-
-/* Sample frame data (Mu data is okay) */
-
-#include "ulaw_slin_ex.h"
-
-/*! \brief convert frame data and store into the buffer */
-static int alawtoulaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int x = f->samples;
- unsigned char *src = f->data;
- unsigned char *dst = (unsigned char *)pvt->outbuf + pvt->samples;
-
- pvt->samples += x;
- pvt->datalen += x;
-
- while (x--)
- *dst++ = a2mu[*src++];
-
- return 0;
-}
-
-/*! \brief convert frame data and store into the buffer */
-static int ulawtoalaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int x = f->samples;
- unsigned char *src = f->data;
- unsigned char *dst = (unsigned char *)pvt->outbuf + pvt->samples;
-
- pvt->samples += x;
- pvt->datalen += x;
-
- while (x--)
- *dst++ = mu2a[*src++];
-
- return 0;
-}
-
-/*
- * alawToLin_Sample. Just random data, somehow...
- */
-static struct ast_frame *alawtoulaw_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_ALAW;
- f.datalen = sizeof(ulaw_slin_ex);
- f.samples = sizeof(ulaw_slin_ex);
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = ulaw_slin_ex; /* XXX what ? */
- return &f;
-}
-
-static struct ast_frame *ulawtoalaw_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_ULAW;
- f.datalen = sizeof(ulaw_slin_ex);
- f.samples = sizeof(ulaw_slin_ex);
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = ulaw_slin_ex;
- return &f;
-}
-
-static struct ast_translator alawtoulaw = {
- .name = "alawtoulaw",
- .srcfmt = AST_FORMAT_ALAW,
- .dstfmt = AST_FORMAT_ULAW,
- .framein = alawtoulaw_framein,
- .sample = alawtoulaw_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES,
-};
-
-static struct ast_translator ulawtoalaw = {
- .name = "ulawtoalaw",
- .srcfmt = AST_FORMAT_ULAW,
- .dstfmt = AST_FORMAT_ALAW,
- .framein = ulawtoalaw_framein,
- .sample = ulawtoalaw_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES,
-};
-
-/*! \brief standard module glue */
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&ulawtoalaw);
- res |= ast_unregister_translator(&alawtoulaw);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
- int x;
-
- for (x=0;x<256;x++) {
- mu2a[x] = AST_LIN2A(AST_MULAW(x));
- a2mu[x] = AST_LIN2MU(AST_ALAW(x));
- }
- res = ast_register_translator(&alawtoulaw);
- if (!res)
- res = ast_register_translator(&ulawtoalaw);
- else
- ast_unregister_translator(&alawtoulaw);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "A-law and Mulaw direct Coder/Decoder");
diff --git a/1.4/codecs/codec_adpcm.c b/1.4/codecs/codec_adpcm.c
deleted file mode 100644
index 7469f056c..000000000
--- a/1.4/codecs/codec_adpcm.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Based on frompcm.c and topcm.c from the Emiliano MIPL browser/
- * interpreter. See http://www.bsdtelephony.com.mx
- *
- * Copyright (c) 2001 - 2005 Digium, Inc.
- * All rights reserved.
- *
- * Karl Sackett <krs@linux-support.net>, 2001-03-21
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief codec_adpcm.c - translate between signed linear and Dialogic ADPCM
- *
- * \ingroup codecs
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/translate.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-/* define NOT_BLI to use a faster but not bit-level identical version */
-/* #define NOT_BLI */
-
-#define BUFFER_SAMPLES 8096 /* size for the translation buffers */
-
-/* Sample frame data */
-
-#include "slin_adpcm_ex.h"
-#include "adpcm_slin_ex.h"
-
-/*
- * Step size index shift table
- */
-
-static int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
-
-/*
- * Step size table, where stpsz[i]=floor[16*(11/10)^i]
- */
-
-static int stpsz[49] = {
- 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
- 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
- 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
- 1060, 1166, 1282, 1411, 1552
-};
-
-/*
- * Decoder/Encoder state
- * States for both encoder and decoder are synchronized
- */
-struct adpcm_state {
- int ssindex;
- int signal;
- int zero_count;
- int next_flag;
-};
-
-/*
- * Decode(encoded)
- * Decodes the encoded nibble from the adpcm file.
- *
- * Results:
- * Returns the encoded difference.
- *
- * Side effects:
- * Sets the index to the step size table for the next encode.
- */
-
-static inline short decode(int encoded, struct adpcm_state *state)
-{
- int diff;
- int step;
- int sign;
-
- step = stpsz[state->ssindex];
-
- sign = encoded & 0x08;
- encoded &= 0x07;
-#ifdef NOT_BLI
- diff = (((encoded << 1) + 1) * step) >> 3;
-#else /* BLI code */
- diff = step >> 3;
- if (encoded & 4)
- diff += step;
- if (encoded & 2)
- diff += step >> 1;
- if (encoded & 1)
- diff += step >> 2;
- if ((encoded >> 1) & step & 0x1)
- diff++;
-#endif
- if (sign)
- diff = -diff;
-
- if (state->next_flag & 0x1)
- state->signal -= 8;
- else if (state->next_flag & 0x2)
- state->signal += 8;
-
- state->signal += diff;
-
- if (state->signal > 2047)
- state->signal = 2047;
- else if (state->signal < -2047)
- state->signal = -2047;
-
- state->next_flag = 0;
-
-#ifdef AUTO_RETURN
- if (encoded)
- state->zero_count = 0;
- else if (++(state->zero_count) == 24) {
- state->zero_count = 0;
- if (state->signal > 0)
- state->next_flag = 0x1;
- else if (state->signal < 0)
- state->next_flag = 0x2;
- }
-#endif
-
- state->ssindex += indsft[encoded];
- if (state->ssindex < 0)
- state->ssindex = 0;
- else if (state->ssindex > 48)
- state->ssindex = 48;
-
- return state->signal << 4;
-}
-
-/*
- * Adpcm
- * Takes a signed linear signal and encodes it as ADPCM
- * For more information see http://support.dialogic.com/appnotes/adpcm.pdf
- *
- * Results:
- * Foo.
- *
- * Side effects:
- * signal gets updated with each pass.
- */
-
-static inline int adpcm(short csig, struct adpcm_state *state)
-{
- int diff;
- int step;
- int encoded;
-
- /*
- * Clip csig if too large or too small
- */
- csig >>= 4;
-
- step = stpsz[state->ssindex];
- diff = csig - state->signal;
-
-#ifdef NOT_BLI
- if (diff < 0) {
- encoded = (-diff << 2) / step;
- if (encoded > 7)
- encoded = 7;
- encoded |= 0x08;
- } else {
- encoded = (diff << 2) / step;
- if (encoded > 7)
- encoded = 7;
- }
-#else /* BLI code */
- if (diff < 0) {
- encoded = 8;
- diff = -diff;
- } else
- encoded = 0;
- if (diff >= step) {
- encoded |= 4;
- diff -= step;
- }
- step >>= 1;
- if (diff >= step) {
- encoded |= 2;
- diff -= step;
- }
- step >>= 1;
- if (diff >= step)
- encoded |= 1;
-#endif /* NOT_BLI */
-
- /* feedback to state */
- decode(encoded, state);
-
- return encoded;
-}
-
-/*----------------- Asterisk-codec glue ------------*/
-
-/*! \brief Workspace for translating signed linear signals to ADPCM. */
-struct adpcm_encoder_pvt {
- struct adpcm_state state;
- int16_t inbuf[BUFFER_SAMPLES]; /* Unencoded signed linear values */
-};
-
-/*! \brief Workspace for translating ADPCM signals to signed linear. */
-struct adpcm_decoder_pvt {
- struct adpcm_state state;
-};
-
-/*! \brief decode 4-bit adpcm frame data and store in output buffer */
-static int adpcmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct adpcm_decoder_pvt *tmp = pvt->pvt;
- int x = f->datalen;
- unsigned char *src = f->data;
- int16_t *dst = (int16_t *)pvt->outbuf + pvt->samples;
-
- while (x--) {
- *dst++ = decode((*src >> 4) & 0xf, &tmp->state);
- *dst++ = decode(*src++ & 0x0f, &tmp->state);
- }
- pvt->samples += f->samples;
- pvt->datalen += 2*f->samples;
- return 0;
-}
-
-/*! \brief fill input buffer with 16-bit signed linear PCM values. */
-static int lintoadpcm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct adpcm_encoder_pvt *tmp = pvt->pvt;
-
- memcpy(&tmp->inbuf[pvt->samples], f->data, f->datalen);
- pvt->samples += f->samples;
- return 0;
-}
-
-/*! \brief convert inbuf and store into frame */
-static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
-{
- struct adpcm_encoder_pvt *tmp = pvt->pvt;
- struct ast_frame *f;
- int i;
- int samples = pvt->samples; /* save original number */
-
- if (samples < 2)
- return NULL;
-
- pvt->samples &= ~1; /* atomic size is 2 samples */
-
- for (i = 0; i < pvt->samples; i += 2) {
- pvt->outbuf[i/2] =
- (adpcm(tmp->inbuf[i ], &tmp->state) << 4) |
- (adpcm(tmp->inbuf[i+1], &tmp->state) );
- };
-
- f = ast_trans_frameout(pvt, pvt->samples/2, 0);
-
- /*
- * If there is a left over sample, move it to the beginning
- * of the input buffer.
- */
-
- if (samples & 1) { /* move the leftover sample at beginning */
- tmp->inbuf[0] = tmp->inbuf[samples - 1];
- pvt->samples = 1;
- }
- return f;
-}
-
-
-/*! \brief AdpcmToLin_Sample */
-static struct ast_frame *adpcmtolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_ADPCM;
- f.datalen = sizeof(adpcm_slin_ex);
- f.samples = sizeof(adpcm_slin_ex) * 2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = adpcm_slin_ex;
- return &f;
-}
-
-/*! \brief LinToAdpcm_Sample */
-static struct ast_frame *lintoadpcm_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_adpcm_ex);
- /* Assume 8000 Hz */
- f.samples = sizeof(slin_adpcm_ex) / 2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_adpcm_ex;
- return &f;
-}
-
-static struct ast_translator adpcmtolin = {
- .name = "adpcmtolin",
- .srcfmt = AST_FORMAT_ADPCM,
- .dstfmt = AST_FORMAT_SLINEAR,
- .framein = adpcmtolin_framein,
- .sample = adpcmtolin_sample,
- .desc_size = sizeof(struct adpcm_decoder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .plc_samples = 160,
-};
-
-static struct ast_translator lintoadpcm = {
- .name = "lintoadpcm",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_ADPCM,
- .framein = lintoadpcm_framein,
- .frameout = lintoadpcm_frameout,
- .sample = lintoadpcm_sample,
- .desc_size = sizeof (struct adpcm_encoder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES/ 2, /* 2 samples per byte */
-};
-
-static void parse_config(void)
-{
- struct ast_config *cfg = ast_config_load("codecs.conf");
- struct ast_variable *var;
- if (cfg == NULL)
- return;
- for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- adpcmtolin.useplc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_adpcm: %susing generic PLC\n", adpcmtolin.useplc ? "" : "not ");
- }
- }
- ast_config_destroy(cfg);
-}
-
-/*! \brief standard module glue */
-static int reload(void)
-{
- parse_config();
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintoadpcm);
- res |= ast_unregister_translator(&adpcmtolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- parse_config();
- res = ast_register_translator(&adpcmtolin);
- if (!res)
- res = ast_register_translator(&lintoadpcm);
- else
- ast_unregister_translator(&adpcmtolin);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Adaptive Differential PCM Coder/Decoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_alaw.c b/1.4/codecs/codec_alaw.c
deleted file mode 100644
index de1061687..000000000
--- a/1.4/codecs/codec_alaw.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief codec_alaw.c - translate between signed linear and alaw
- *
- * \ingroup codecs
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/translate.h"
-#include "asterisk/channel.h"
-#include "asterisk/alaw.h"
-#include "asterisk/utils.h"
-
-#define BUFFER_SAMPLES 8096 /* size for the translation buffers */
-
-/* Sample frame data (Mu data is okay) */
-
-#include "slin_ulaw_ex.h"
-#include "ulaw_slin_ex.h"
-
-/*! \brief decode frame into lin and fill output buffer. */
-static int alawtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int i = f->samples;
- unsigned char *src = f->data;
- int16_t *dst = (int16_t *)pvt->outbuf + pvt->samples;
-
- pvt->samples += i;
- pvt->datalen += i * 2; /* 2 bytes/sample */
-
- while (i--)
- *dst++ = AST_ALAW(*src++);
-
- return 0;
-}
-
-/*! \brief convert and store input samples in output buffer */
-static int lintoalaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int i = f->samples;
- char *dst = pvt->outbuf + pvt->samples;
- int16_t *src = f->data;
-
- pvt->samples += i;
- pvt->datalen += i; /* 1 byte/sample */
-
- while (i--)
- *dst++ = AST_LIN2A(*src++);
-
- return 0;
-}
-
-/*! \brief alawToLin_Sample */
-static struct ast_frame *alawtolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_ALAW;
- f.datalen = sizeof(ulaw_slin_ex);
- f.samples = sizeof(ulaw_slin_ex);
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = ulaw_slin_ex;
- return &f;
-}
-
-/*! \brief LinToalaw_Sample */
-static struct ast_frame *lintoalaw_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_ulaw_ex);
- f.samples = sizeof(slin_ulaw_ex) / 2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_ulaw_ex;
- return &f;
-}
-
-static struct ast_translator alawtolin = {
- .name = "alawtolin",
- .srcfmt = AST_FORMAT_ALAW,
- .dstfmt = AST_FORMAT_SLINEAR,
- .framein = alawtolin_framein,
- .sample = alawtolin_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .plc_samples = 160,
-};
-
-static struct ast_translator lintoalaw = {
- "lintoalaw",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_ALAW,
- .framein = lintoalaw_framein,
- .sample = lintoalaw_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES,
-};
-
-static void parse_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg = ast_config_load("codecs.conf");
- if (!cfg)
- return;
- for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- alawtolin.useplc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_alaw: %susing generic PLC\n", alawtolin.useplc ? "" : "not ");
- }
- }
- ast_config_destroy(cfg);
-}
-
-/*! \brief standard module stuff */
-
-static int reload(void)
-{
- parse_config();
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintoalaw);
- res |= ast_unregister_translator(&alawtolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- parse_config();
- res = ast_register_translator(&alawtolin);
- if (!res)
- res = ast_register_translator(&lintoalaw);
- else
- ast_unregister_translator(&alawtolin);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "A-law Coder/Decoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_g726.c b/1.4/codecs/codec_g726.c
deleted file mode 100644
index bfc49ad9c..000000000
--- a/1.4/codecs/codec_g726.c
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@digium.com>
- *
- * Based on frompcm.c and topcm.c from the Emiliano MIPL browser/
- * interpreter. See http://www.bsdtelephony.com.mx
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief codec_g726.c - translate between signed linear and ITU G.726-32kbps (both RFC3551 and AAL2 codeword packing)
- *
- * \ingroup codecs
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/translate.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-#define WANT_ASM
-#include "log2comp.h"
-
-/* define NOT_BLI to use a faster but not bit-level identical version */
-/* #define NOT_BLI */
-
-#if defined(NOT_BLI)
-# if defined(_MSC_VER)
-typedef __int64 sint64;
-# elif defined(__GNUC__)
-typedef long long sint64;
-# else
-# error 64-bit integer type is not defined for your compiler/platform
-# endif
-#endif
-
-#define BUFFER_SAMPLES 8096 /* size for the translation buffers */
-#define BUF_SHIFT 5
-
-/* Sample frame data */
-
-#include "slin_g726_ex.h"
-#include "g726_slin_ex.h"
-
-/*
- * The following is the definition of the state structure
- * used by the G.726 encoder and decoder to preserve their internal
- * state between successive calls. The meanings of the majority
- * of the state structure fields are explained in detail in the
- * CCITT Recommendation G.721. The field names are essentially identical
- * to variable names in the bit level description of the coding algorithm
- * included in this Recommendation.
- */
-struct g726_state {
- long yl; /* Locked or steady state step size multiplier. */
- int yu; /* Unlocked or non-steady state step size multiplier. */
- int dms; /* Short term energy estimate. */
- int dml; /* Long term energy estimate. */
- int ap; /* Linear weighting coefficient of 'yl' and 'yu'. */
- int a[2]; /* Coefficients of pole portion of prediction filter.
- * stored as fixed-point 1==2^14 */
- int b[6]; /* Coefficients of zero portion of prediction filter.
- * stored as fixed-point 1==2^14 */
- int pk[2]; /* Signs of previous two samples of a partially
- * reconstructed signal. */
- int dq[6]; /* Previous 6 samples of the quantized difference signal
- * stored as fixed point 1==2^12,
- * or in internal floating point format */
- int sr[2]; /* Previous 2 samples of the quantized difference signal
- * stored as fixed point 1==2^12,
- * or in internal floating point format */
- int td; /* delayed tone detect, new in 1988 version */
-};
-
-static int qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
-/*
- * Maps G.721 code word to reconstructed scale factor normalized log
- * magnitude values.
- */
-static int _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
- 425, 373, 323, 273, 213, 135, 4, -2048};
-
-/* Maps G.721 code word to log of scale factor multiplier. */
-static int _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
- 1122, 355, 198, 112, 64, 41, 18, -12};
-/*
- * Maps G.721 code words to a set of values whose long and short
- * term averages are computed and then compared to give an indication
- * how stationary (steady state) the signal is.
- */
-static int _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
- 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
-
-
-/*
- * g72x_init_state()
- *
- * This routine initializes and/or resets the g726_state structure
- * pointed to by 'state_ptr'.
- * All the initial state values are specified in the CCITT G.721 document.
- */
-static void g726_init_state(struct g726_state *state_ptr)
-{
- int cnta;
-
- state_ptr->yl = 34816;
- state_ptr->yu = 544;
- state_ptr->dms = 0;
- state_ptr->dml = 0;
- state_ptr->ap = 0;
- for (cnta = 0; cnta < 2; cnta++) {
- state_ptr->a[cnta] = 0;
- state_ptr->pk[cnta] = 0;
-#ifdef NOT_BLI
- state_ptr->sr[cnta] = 1;
-#else
- state_ptr->sr[cnta] = 32;
-#endif
- }
- for (cnta = 0; cnta < 6; cnta++) {
- state_ptr->b[cnta] = 0;
-#ifdef NOT_BLI
- state_ptr->dq[cnta] = 1;
-#else
- state_ptr->dq[cnta] = 32;
-#endif
- }
- state_ptr->td = 0;
-}
-
-/*
- * quan()
- *
- * quantizes the input val against the table of integers.
- * It returns i if table[i - 1] <= val < table[i].
- *
- * Using linear search for simple coding.
- */
-static int quan(int val, int *table, int size)
-{
- int i;
-
- for (i = 0; i < size && val >= *table; ++i, ++table)
- ;
- return (i);
-}
-
-#ifdef NOT_BLI /* faster non-identical version */
-
-/*
- * predictor_zero()
- *
- * computes the estimated signal from 6-zero predictor.
- *
- */
-static int predictor_zero(struct g726_state *state_ptr)
-{ /* divide by 2 is necessary here to handle negative numbers correctly */
- int i;
- sint64 sezi;
- for (sezi = 0, i = 0; i < 6; i++) /* ACCUM */
- sezi += (sint64)state_ptr->b[i] * state_ptr->dq[i];
- return (int)(sezi >> 13) / 2 /* 2^14 */;
-}
-
-/*
- * predictor_pole()
- *
- * computes the estimated signal from 2-pole predictor.
- *
- */
-static int predictor_pole(struct g726_state *state_ptr)
-{ /* divide by 2 is necessary here to handle negative numbers correctly */
- return (int)(((sint64)state_ptr->a[1] * state_ptr->sr[1] +
- (sint64)state_ptr->a[0] * state_ptr->sr[0]) >> 13) / 2 /* 2^14 */;
-}
-
-#else /* NOT_BLI - identical version */
-/*
- * fmult()
- *
- * returns the integer product of the fixed-point number "an" (1==2^12) and
- * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
- */
-static int fmult(int an, int srn)
-{
- int anmag, anexp, anmant;
- int wanexp, wanmant;
- int retval;
-
- anmag = (an > 0) ? an : ((-an) & 0x1FFF);
- anexp = ilog2(anmag) - 5;
- anmant = (anmag == 0) ? 32 :
- (anexp >= 0) ? anmag >> anexp : anmag << -anexp;
- wanexp = anexp + ((srn >> 6) & 0xF) - 13;
-
- wanmant = (anmant * (srn & 077) + 0x30) >> 4;
- retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
- (wanmant >> -wanexp);
-
- return (((an ^ srn) < 0) ? -retval : retval);
-}
-
-static int predictor_zero(struct g726_state *state_ptr)
-{
- int i;
- int sezi;
- for (sezi = 0, i = 0; i < 6; i++) /* ACCUM */
- sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
- return sezi;
-}
-
-static int predictor_pole(struct g726_state *state_ptr)
-{
- return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
- fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
-}
-
-#endif /* NOT_BLI */
-
-/*
- * step_size()
- *
- * computes the quantization step size of the adaptive quantizer.
- *
- */
-static int step_size(struct g726_state *state_ptr)
-{
- int y;
- int dif;
- int al;
-
- if (state_ptr->ap >= 256)
- return (state_ptr->yu);
- else {
- y = state_ptr->yl >> 6;
- dif = state_ptr->yu - y;
- al = state_ptr->ap >> 2;
- if (dif > 0)
- y += (dif * al) >> 6;
- else if (dif < 0)
- y += (dif * al + 0x3F) >> 6;
- return (y);
- }
-}
-
-/*
- * quantize()
- *
- * Given a raw sample, 'd', of the difference signal and a
- * quantization step size scale factor, 'y', this routine returns the
- * ADPCM codeword to which that sample gets quantized. The step
- * size scale factor division operation is done in the log base 2 domain
- * as a subtraction.
- */
-static int quantize(
- int d, /* Raw difference signal sample */
- int y, /* Step size multiplier */
- int *table, /* quantization table */
- int size) /* table size of integers */
-{
- int dqm; /* Magnitude of 'd' */
- int exp; /* Integer part of base 2 log of 'd' */
- int mant; /* Fractional part of base 2 log */
- int dl; /* Log of magnitude of 'd' */
- int dln; /* Step size scale factor normalized log */
- int i;
-
- /*
- * LOG
- *
- * Compute base 2 log of 'd', and store in 'dl'.
- */
- dqm = abs(d);
- exp = ilog2(dqm);
- if (exp < 0)
- exp = 0;
- mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */
- dl = (exp << 7) | mant;
-
- /*
- * SUBTB
- *
- * "Divide" by step size multiplier.
- */
- dln = dl - (y >> 2);
-
- /*
- * QUAN
- *
- * Obtain codword i for 'd'.
- */
- i = quan(dln, table, size);
- if (d < 0) /* take 1's complement of i */
- return ((size << 1) + 1 - i);
- else if (i == 0) /* take 1's complement of 0 */
- return ((size << 1) + 1); /* new in 1988 */
- else
- return (i);
-}
-
-/*
- * reconstruct()
- *
- * Returns reconstructed difference signal 'dq' obtained from
- * codeword 'i' and quantization step size scale factor 'y'.
- * Multiplication is performed in log base 2 domain as addition.
- */
-static int reconstruct(
- int sign, /* 0 for non-negative value */
- int dqln, /* G.72x codeword */
- int y) /* Step size multiplier */
-{
- int dql; /* Log of 'dq' magnitude */
- int dex; /* Integer part of log */
- int dqt;
- int dq; /* Reconstructed difference signal sample */
-
- dql = dqln + (y >> 2); /* ADDA */
-
- if (dql < 0) {
-#ifdef NOT_BLI
- return (sign) ? -1 : 1;
-#else
- return (sign) ? -0x8000 : 0;
-#endif
- } else { /* ANTILOG */
- dex = (dql >> 7) & 15;
- dqt = 128 + (dql & 127);
-#ifdef NOT_BLI
- dq = ((dqt << 19) >> (14 - dex));
- return (sign) ? -dq : dq;
-#else
- dq = (dqt << 7) >> (14 - dex);
- return (sign) ? (dq - 0x8000) : dq;
-#endif
- }
-}
-
-/*
- * update()
- *
- * updates the state variables for each output code
- */
-static void update(
- int code_size, /* distinguish 723_40 with others */
- int y, /* quantizer step size */
- int wi, /* scale factor multiplier */
- int fi, /* for long/short term energies */
- int dq, /* quantized prediction difference */
- int sr, /* reconstructed signal */
- int dqsez, /* difference from 2-pole predictor */
- struct g726_state *state_ptr) /* coder state pointer */
-{
- int cnt;
- int mag; /* Adaptive predictor, FLOAT A */
-#ifndef NOT_BLI
- int exp;
-#endif
- int a2p=0; /* LIMC */
- int a1ul; /* UPA1 */
- int pks1; /* UPA2 */
- int fa1;
- int tr; /* tone/transition detector */
- int ylint, thr2, dqthr;
- int ylfrac, thr1;
- int pk0;
-
- pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */
-
-#ifdef NOT_BLI
- mag = abs(dq / 0x1000); /* prediction difference magnitude */
-#else
- mag = dq & 0x7FFF; /* prediction difference magnitude */
-#endif
- /* TRANS */
- ylint = state_ptr->yl >> 15; /* exponent part of yl */
- ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */
- thr1 = (32 + ylfrac) << ylint; /* threshold */
- thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */
- dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */
- if (state_ptr->td == 0) /* signal supposed voice */
- tr = 0;
- else if (mag <= dqthr) /* supposed data, but small mag */
- tr = 0; /* treated as voice */
- else /* signal is data (modem) */
- tr = 1;
-
- /*
- * Quantizer scale factor adaptation.
- */
-
- /* FUNCTW & FILTD & DELAY */
- /* update non-steady state step size multiplier */
- state_ptr->yu = y + ((wi - y) >> 5);
-
- /* LIMB */
- if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */
- state_ptr->yu = 544;
- else if (state_ptr->yu > 5120)
- state_ptr->yu = 5120;
-
- /* FILTE & DELAY */
- /* update steady state step size multiplier */
- state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
-
- /*
- * Adaptive predictor coefficients.
- */
- if (tr == 1) { /* reset a's and b's for modem signal */
- state_ptr->a[0] = 0;
- state_ptr->a[1] = 0;
- state_ptr->b[0] = 0;
- state_ptr->b[1] = 0;
- state_ptr->b[2] = 0;
- state_ptr->b[3] = 0;
- state_ptr->b[4] = 0;
- state_ptr->b[5] = 0;
- } else { /* update a's and b's */
- pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */
-
- /* update predictor pole a[1] */
- a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
- if (dqsez != 0) {
- fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
- if (fa1 < -8191) /* a2p = function of fa1 */
- a2p -= 0x100;
- else if (fa1 > 8191)
- a2p += 0xFF;
- else
- a2p += fa1 >> 5;
-
- if (pk0 ^ state_ptr->pk[1])
- /* LIMC */
- if (a2p <= -12160)
- a2p = -12288;
- else if (a2p >= 12416)
- a2p = 12288;
- else
- a2p -= 0x80;
- else if (a2p <= -12416)
- a2p = -12288;
- else if (a2p >= 12160)
- a2p = 12288;
- else
- a2p += 0x80;
- }
-
- /* TRIGB & DELAY */
- state_ptr->a[1] = a2p;
-
- /* UPA1 */
- /* update predictor pole a[0] */
- state_ptr->a[0] -= state_ptr->a[0] >> 8;
- if (dqsez != 0) {
- if (pks1 == 0)
- state_ptr->a[0] += 192;
- else
- state_ptr->a[0] -= 192;
- }
- /* LIMD */
- a1ul = 15360 - a2p;
- if (state_ptr->a[0] < -a1ul)
- state_ptr->a[0] = -a1ul;
- else if (state_ptr->a[0] > a1ul)
- state_ptr->a[0] = a1ul;
-
- /* UPB : update predictor zeros b[6] */
- for (cnt = 0; cnt < 6; cnt++) {
- if (code_size == 5) /* for 40Kbps G.723 */
- state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
- else /* for G.721 and 24Kbps G.723 */
- state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
- if (mag)
- { /* XOR */
- if ((dq ^ state_ptr->dq[cnt]) >= 0)
- state_ptr->b[cnt] += 128;
- else
- state_ptr->b[cnt] -= 128;
- }
- }
- }
-
- for (cnt = 5; cnt > 0; cnt--)
- state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
-#ifdef NOT_BLI
- state_ptr->dq[0] = dq;
-#else
- /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
- if (mag == 0) {
- state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0x20 - 0x400;
- } else {
- exp = ilog2(mag) + 1;
- state_ptr->dq[0] = (dq >= 0) ?
- (exp << 6) + ((mag << 6) >> exp) :
- (exp << 6) + ((mag << 6) >> exp) - 0x400;
- }
-#endif
-
- state_ptr->sr[1] = state_ptr->sr[0];
-#ifdef NOT_BLI
- state_ptr->sr[0] = sr;
-#else
- /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
- if (sr == 0) {
- state_ptr->sr[0] = 0x20;
- } else if (sr > 0) {
- exp = ilog2(sr) + 1;
- state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp);
- } else if (sr > -0x8000) {
- mag = -sr;
- exp = ilog2(mag) + 1;
- state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400;
- } else
- state_ptr->sr[0] = 0x20 - 0x400;
-#endif
-
- /* DELAY A */
- state_ptr->pk[1] = state_ptr->pk[0];
- state_ptr->pk[0] = pk0;
-
- /* TONE */
- if (tr == 1) /* this sample has been treated as data */
- state_ptr->td = 0; /* next one will be treated as voice */
- else if (a2p < -11776) /* small sample-to-sample correlation */
- state_ptr->td = 1; /* signal may be data */
- else /* signal is voice */
- state_ptr->td = 0;
-
- /*
- * Adaptation speed control.
- */
- state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */
- state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */
-
- if (tr == 1)
- state_ptr->ap = 256;
- else if (y < 1536) /* SUBTC */
- state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
- else if (state_ptr->td == 1)
- state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
- else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
- (state_ptr->dml >> 3))
- state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
- else
- state_ptr->ap += (-state_ptr->ap) >> 4;
-}
-
-/*
- * g726_decode()
- *
- * Description:
- *
- * Decodes a 4-bit code of G.726-32 encoded data of i and
- * returns the resulting linear PCM, A-law or u-law value.
- * return -1 for unknown out_coding value.
- */
-static int g726_decode(int i, struct g726_state *state_ptr)
-{
- int sezi, sez, se; /* ACCUM */
- int y; /* MIX */
- int sr; /* ADDB */
- int dq;
- int dqsez;
-
- i &= 0x0f; /* mask to get proper bits */
-#ifdef NOT_BLI
- sezi = predictor_zero(state_ptr);
- sez = sezi;
- se = sezi + predictor_pole(state_ptr); /* estimated signal */
-#else
- sezi = predictor_zero(state_ptr);
- sez = sezi >> 1;
- se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
-#endif
-
- y = step_size(state_ptr); /* dynamic quantizer step size */
-
- dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized diff. */
-
-#ifdef NOT_BLI
- sr = se + dq; /* reconst. signal */
- dqsez = dq + sez; /* pole prediction diff. */
-#else
- sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
- dqsez = sr - se + sez; /* pole prediction diff. */
-#endif
-
- update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
-
-#ifdef NOT_BLI
- return (sr >> 10); /* sr was 26-bit dynamic range */
-#else
- return (sr << 2); /* sr was 14-bit dynamic range */
-#endif
-}
-
-/*
- * g726_encode()
- *
- * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
- * the resulting code. -1 is returned for unknown input coding value.
- */
-static int g726_encode(int sl, struct g726_state *state_ptr)
-{
- int sezi, se, sez; /* ACCUM */
- int d; /* SUBTA */
- int sr; /* ADDB */
- int y; /* MIX */
- int dqsez; /* ADDC */
- int dq, i;
-
-#ifdef NOT_BLI
- sl <<= 10; /* 26-bit dynamic range */
-
- sezi = predictor_zero(state_ptr);
- sez = sezi;
- se = sezi + predictor_pole(state_ptr); /* estimated signal */
-#else
- sl >>= 2; /* 14-bit dynamic range */
-
- sezi = predictor_zero(state_ptr);
- sez = sezi >> 1;
- se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
-#endif
-
- d = sl - se; /* estimation difference */
-
- /* quantize the prediction difference */
- y = step_size(state_ptr); /* quantizer step size */
-#ifdef NOT_BLI
- d /= 0x1000;
-#endif
- i = quantize(d, y, qtab_721, 7); /* i = G726 code */
-
- dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
-
-#ifdef NOT_BLI
- sr = se + dq; /* reconst. signal */
- dqsez = dq + sez; /* pole prediction diff. */
-#else
- sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
- dqsez = sr - se + sez; /* pole prediction diff. */
-#endif
-
- update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
-
- return (i);
-}
-
-/*
- * Private workspace for translating signed linear signals to G726.
- * Don't bother to define two distinct structs.
- */
-
-struct g726_coder_pvt {
- /* buffer any odd byte in input - 0x80 + (value & 0xf) if present */
- unsigned char next_flag;
- struct g726_state g726;
-};
-
-/*! \brief init a new instance of g726_coder_pvt. */
-static int lintog726_new(struct ast_trans_pvt *pvt)
-{
- struct g726_coder_pvt *tmp = pvt->pvt;
-
- g726_init_state(&tmp->g726);
-
- return 0;
-}
-
-/*! \brief decode packed 4-bit G726 values (AAL2 packing) and store in buffer. */
-static int g726aal2tolin_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct g726_coder_pvt *tmp = pvt->pvt;
- unsigned char *src = f->data;
- int16_t *dst = (int16_t *) pvt->outbuf + pvt->samples;
- unsigned int i;
-
- for (i = 0; i < f->datalen; i++) {
- *dst++ = g726_decode((src[i] >> 4) & 0xf, &tmp->g726);
- *dst++ = g726_decode(src[i] & 0x0f, &tmp->g726);
- }
-
- pvt->samples += f->samples;
- pvt->datalen += 2 * f->samples; /* 2 bytes/sample */
-
- return 0;
-}
-
-/*! \brief compress and store data (4-bit G726 samples, AAL2 packing) in outbuf */
-static int lintog726aal2_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct g726_coder_pvt *tmp = pvt->pvt;
- int16_t *src = f->data;
- unsigned int i;
-
- for (i = 0; i < f->samples; i++) {
- unsigned char d = g726_encode(src[i], &tmp->g726); /* this sample */
-
- if (tmp->next_flag & 0x80) { /* merge with leftover sample */
- pvt->outbuf[pvt->datalen++] = ((tmp->next_flag & 0xf)<< 4) | d;
- pvt->samples += 2; /* 2 samples per byte */
- tmp->next_flag = 0;
- } else {
- tmp->next_flag = 0x80 | d;
- }
- }
-
- return 0;
-}
-
-/*! \brief decode packed 4-bit G726 values (RFC3551 packing) and store in buffer. */
-static int g726tolin_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct g726_coder_pvt *tmp = pvt->pvt;
- unsigned char *src = f->data;
- int16_t *dst = (int16_t *) pvt->outbuf + pvt->samples;
- unsigned int i;
-
- for (i = 0; i < f->datalen; i++) {
- *dst++ = g726_decode(src[i] & 0x0f, &tmp->g726);
- *dst++ = g726_decode((src[i] >> 4) & 0xf, &tmp->g726);
- }
-
- pvt->samples += f->samples;
- pvt->datalen += 2 * f->samples; /* 2 bytes/sample */
-
- return 0;
-}
-
-/*! \brief compress and store data (4-bit G726 samples, RFC3551 packing) in outbuf */
-static int lintog726_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct g726_coder_pvt *tmp = pvt->pvt;
- int16_t *src = f->data;
- unsigned int i;
-
- for (i = 0; i < f->samples; i++) {
- unsigned char d = g726_encode(src[i], &tmp->g726); /* this sample */
-
- if (tmp->next_flag & 0x80) { /* merge with leftover sample */
- pvt->outbuf[pvt->datalen++] = (d << 4) | (tmp->next_flag & 0xf);
- pvt->samples += 2; /* 2 samples per byte */
- tmp->next_flag = 0;
- } else {
- tmp->next_flag = 0x80 | d;
- }
- }
-
- return 0;
-}
-
-/*! \brief convert G726-32 RFC3551 packed data into AAL2 packed data (or vice-versa) */
-static int g726tog726aal2_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- unsigned char *src = f->data;
- unsigned char *dst = (unsigned char *) pvt->outbuf + pvt->samples;
- unsigned int i;
-
- for (i = 0; i < f->datalen; i++)
- *dst++ = ((src[i] & 0xf) << 4) | (src[i] >> 4);
-
- pvt->samples += f->samples;
- pvt->datalen += f->samples; /* 1 byte/sample */
-
- return 0;
-}
-
-static struct ast_frame *g726tolin_sample(void)
-{
- static struct ast_frame f = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_G726,
- .datalen = sizeof(g726_slin_ex),
- .samples = sizeof(g726_slin_ex) * 2, /* 2 samples per byte */
- .src = __PRETTY_FUNCTION__,
- .data = g726_slin_ex,
- };
-
- return &f;
-}
-
-static struct ast_frame *lintog726_sample (void)
-{
- static struct ast_frame f = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_SLINEAR,
- .datalen = sizeof(slin_g726_ex),
- .samples = sizeof(slin_g726_ex) / 2, /* 1 sample per 2 bytes */
- .src = __PRETTY_FUNCTION__,
- .data = slin_g726_ex,
- };
-
- return &f;
-}
-
-static struct ast_translator g726tolin = {
- .name = "g726tolin",
- .srcfmt = AST_FORMAT_G726,
- .dstfmt = AST_FORMAT_SLINEAR,
- .newpvt = lintog726_new, /* same for both directions */
- .framein = g726tolin_framein,
- .sample = g726tolin_sample,
- .desc_size = sizeof(struct g726_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .plc_samples = 160,
-};
-
-static struct ast_translator lintog726 = {
- .name = "lintog726",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_G726,
- .newpvt = lintog726_new, /* same for both directions */
- .framein = lintog726_framein,
- .sample = lintog726_sample,
- .desc_size = sizeof(struct g726_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES/2,
-};
-
-static struct ast_translator g726aal2tolin = {
- .name = "g726aal2tolin",
- .srcfmt = AST_FORMAT_G726_AAL2,
- .dstfmt = AST_FORMAT_SLINEAR,
- .newpvt = lintog726_new, /* same for both directions */
- .framein = g726aal2tolin_framein,
- .sample = g726tolin_sample,
- .desc_size = sizeof(struct g726_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .plc_samples = 160,
-};
-
-static struct ast_translator lintog726aal2 = {
- .name = "lintog726aal2",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_G726_AAL2,
- .newpvt = lintog726_new, /* same for both directions */
- .framein = lintog726aal2_framein,
- .sample = lintog726_sample,
- .desc_size = sizeof(struct g726_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES / 2,
-};
-
-static struct ast_translator g726tog726aal2 = {
- .name = "g726tog726aal2",
- .srcfmt = AST_FORMAT_G726,
- .dstfmt = AST_FORMAT_G726_AAL2,
- .framein = g726tog726aal2_framein, /* same for both directions */
- .sample = lintog726_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES,
-};
-
-static struct ast_translator g726aal2tog726 = {
- .name = "g726aal2tog726",
- .srcfmt = AST_FORMAT_G726_AAL2,
- .dstfmt = AST_FORMAT_G726,
- .framein = g726tog726aal2_framein, /* same for both directions */
- .sample = lintog726_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES,
-};
-
-static void parse_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg = ast_config_load("codecs.conf");
-
- if (!cfg)
- return;
- for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- g726tolin.useplc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_g726: %susing generic PLC\n",
- g726tolin.useplc ? "" : "not ");
- }
- }
- ast_config_destroy(cfg);
-}
-
-static int reload(void)
-{
- parse_config();
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_unregister_translator(&g726tolin);
- res |= ast_unregister_translator(&lintog726);
-
- res |= ast_unregister_translator(&g726aal2tolin);
- res |= ast_unregister_translator(&lintog726aal2);
-
- res |= ast_unregister_translator(&g726aal2tog726);
- res |= ast_unregister_translator(&g726tog726aal2);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
-
- parse_config();
-
- res |= ast_register_translator(&g726tolin);
- res |= ast_register_translator(&lintog726);
-
- res |= ast_register_translator(&g726aal2tolin);
- res |= ast_register_translator(&lintog726aal2);
-
- res |= ast_register_translator(&g726aal2tog726);
- res |= ast_register_translator(&g726tog726aal2);
-
- if (res)
- unload_module();
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.726-32kbps G726 Transcoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_gsm.c b/1.4/codecs/codec_gsm.c
deleted file mode 100644
index 8a3749319..000000000
--- a/1.4/codecs/codec_gsm.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * The GSM code is from TOAST. Copyright information for that package is available
- * in the GSM directory.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Translate between signed linear and Global System for Mobile Communications (GSM)
- *
- * \ingroup codecs
- */
-
-/*** MODULEINFO
- <depend>gsm</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/translate.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-#ifdef HAVE_GSM_HEADER
-#include "gsm.h"
-#elif defined(HAVE_GSM_GSM_HEADER)
-#include <gsm/gsm.h>
-#endif
-
-#include "../formats/msgsm.h"
-
-/* Sample frame data */
-#include "slin_gsm_ex.h"
-#include "gsm_slin_ex.h"
-
-#define BUFFER_SAMPLES 8000
-#define GSM_SAMPLES 160
-#define GSM_FRAME_LEN 33
-#define MSGSM_FRAME_LEN 65
-
-struct gsm_translator_pvt { /* both gsm2lin and lin2gsm */
- gsm gsm;
- int16_t buf[BUFFER_SAMPLES]; /* lin2gsm, temporary storage */
-};
-
-static int gsm_new(struct ast_trans_pvt *pvt)
-{
- struct gsm_translator_pvt *tmp = pvt->pvt;
-
- return (tmp->gsm = gsm_create()) ? 0 : -1;
-}
-
-static struct ast_frame *lintogsm_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_gsm_ex);
- /* Assume 8000 Hz */
- f.samples = sizeof(slin_gsm_ex)/2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_gsm_ex;
- return &f;
-}
-
-static struct ast_frame *gsmtolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_GSM;
- f.datalen = sizeof(gsm_slin_ex);
- /* All frames are 20 ms long */
- f.samples = GSM_SAMPLES;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = gsm_slin_ex;
- return &f;
-}
-
-/*! \brief decode and store in outbuf. */
-static int gsmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct gsm_translator_pvt *tmp = pvt->pvt;
- int x;
- int16_t *dst = (int16_t *)pvt->outbuf;
- /* guess format from frame len. 65 for MSGSM, 33 for regular GSM */
- int flen = (f->datalen % MSGSM_FRAME_LEN == 0) ?
- MSGSM_FRAME_LEN : GSM_FRAME_LEN;
-
- for (x=0; x < f->datalen; x += flen) {
- unsigned char data[2 * GSM_FRAME_LEN];
- unsigned char *src;
- int len;
- if (flen == MSGSM_FRAME_LEN) {
- len = 2*GSM_SAMPLES;
- src = data;
- /* Translate MSGSM format to Real GSM format before feeding in */
- /* XXX what's the point here! we should just work
- * on the full format.
- */
- conv65(f->data + x, data);
- } else {
- len = GSM_SAMPLES;
- src = f->data + x;
- }
- /* XXX maybe we don't need to check */
- if (pvt->samples + len > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- if (gsm_decode(tmp->gsm, src, dst + pvt->samples)) {
- ast_log(LOG_WARNING, "Invalid GSM data (1)\n");
- return -1;
- }
- pvt->samples += GSM_SAMPLES;
- pvt->datalen += 2 * GSM_SAMPLES;
- if (flen == MSGSM_FRAME_LEN) {
- if (gsm_decode(tmp->gsm, data + GSM_FRAME_LEN, dst + pvt->samples)) {
- ast_log(LOG_WARNING, "Invalid GSM data (2)\n");
- return -1;
- }
- pvt->samples += GSM_SAMPLES;
- pvt->datalen += 2 * GSM_SAMPLES;
- }
- }
- return 0;
-}
-
-/*! \brief store samples into working buffer for later decode */
-static int lintogsm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct gsm_translator_pvt *tmp = pvt->pvt;
-
- /* XXX We should look at how old the rest of our stream is, and if it
- is too old, then we should overwrite it entirely, otherwise we can
- get artifacts of earlier talk that do not belong */
- if (pvt->samples + f->samples > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
- pvt->samples += f->samples;
- return 0;
-}
-
-/*! \brief encode and produce a frame */
-static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt)
-{
- struct gsm_translator_pvt *tmp = pvt->pvt;
- int datalen = 0;
- int samples = 0;
-
- /* We can't work on anything less than a frame in size */
- if (pvt->samples < GSM_SAMPLES)
- return NULL;
- while (pvt->samples >= GSM_SAMPLES) {
- /* Encode a frame of data */
- gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf + datalen);
- datalen += GSM_FRAME_LEN;
- samples += GSM_SAMPLES;
- pvt->samples -= GSM_SAMPLES;
- }
-
- /* Move the data at the end of the buffer to the front */
- if (pvt->samples)
- memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
-
- return ast_trans_frameout(pvt, datalen, samples);
-}
-
-static void gsm_destroy_stuff(struct ast_trans_pvt *pvt)
-{
- struct gsm_translator_pvt *tmp = pvt->pvt;
- if (tmp->gsm)
- gsm_destroy(tmp->gsm);
-}
-
-static struct ast_translator gsmtolin = {
- .name = "gsmtolin",
- .srcfmt = AST_FORMAT_GSM,
- .dstfmt = AST_FORMAT_SLINEAR,
- .newpvt = gsm_new,
- .framein = gsmtolin_framein,
- .destroy = gsm_destroy_stuff,
- .sample = gsmtolin_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .desc_size = sizeof (struct gsm_translator_pvt ),
- .plc_samples = GSM_SAMPLES,
-};
-
-static struct ast_translator lintogsm = {
- .name = "lintogsm",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_GSM,
- .newpvt = gsm_new,
- .framein = lintogsm_framein,
- .frameout = lintogsm_frameout,
- .destroy = gsm_destroy_stuff,
- .sample = lintogsm_sample,
- .desc_size = sizeof (struct gsm_translator_pvt ),
- .buf_size = (BUFFER_SAMPLES * GSM_FRAME_LEN + GSM_SAMPLES - 1)/GSM_SAMPLES,
-};
-
-
-static void parse_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg = ast_config_load("codecs.conf");
- if (!cfg)
- return;
- for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- gsmtolin.useplc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_gsm: %susing generic PLC\n", gsmtolin.useplc ? "" : "not ");
- }
- }
- ast_config_destroy(cfg);
-}
-
-/*! \brief standard module glue */
-static int reload(void)
-{
- parse_config();
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintogsm);
- if (!res)
- res = ast_unregister_translator(&gsmtolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- parse_config();
- res = ast_register_translator(&gsmtolin);
- if (!res)
- res=ast_register_translator(&lintogsm);
- else
- ast_unregister_translator(&gsmtolin);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "GSM Coder/Decoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_ilbc.c b/1.4/codecs/codec_ilbc.c
deleted file mode 100644
index b5fc9bf32..000000000
--- a/1.4/codecs/codec_ilbc.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * The iLBC code is from The IETF code base and is copyright The Internet Society (2004)
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Translate between signed linear and Internet Low Bitrate Codec
- *
- * \ingroup codecs
- */
-
-/*** MODULEINFO
- <defaultenabled>no</defaultenabled>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/translate.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-#include "ilbc/iLBC_encode.h"
-#include "ilbc/iLBC_decode.h"
-
-/* Sample frame data */
-#include "slin_ilbc_ex.h"
-#include "ilbc_slin_ex.h"
-
-#define USE_ILBC_ENHANCER 0
-#define ILBC_MS 30
-/* #define ILBC_MS 20 */
-
-#define ILBC_FRAME_LEN 50 /* apparently... */
-#define ILBC_SAMPLES 240 /* 30ms at 8000 hz */
-#define BUFFER_SAMPLES 8000
-
-struct ilbc_coder_pvt {
- iLBC_Enc_Inst_t enc;
- iLBC_Dec_Inst_t dec;
- /* Enough to store a full second */
- int16_t buf[BUFFER_SAMPLES];
-};
-
-static int lintoilbc_new(struct ast_trans_pvt *pvt)
-{
- struct ilbc_coder_pvt *tmp = pvt->pvt;
-
- initEncode(&tmp->enc, ILBC_MS);
-
- return 0;
-}
-
-static int ilbctolin_new(struct ast_trans_pvt *pvt)
-{
- struct ilbc_coder_pvt *tmp = pvt->pvt;
-
- initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER);
-
- return 0;
-}
-
-static struct ast_frame *lintoilbc_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_ilbc_ex);
- f.samples = sizeof(slin_ilbc_ex)/2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_ilbc_ex;
- return &f;
-}
-
-static struct ast_frame *ilbctolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_ILBC;
- f.datalen = sizeof(ilbc_slin_ex);
- /* All frames are 30 ms long */
- f.samples = ILBC_SAMPLES;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = ilbc_slin_ex;
- return &f;
-}
-
-/*! \brief decode a frame and store in outbuf */
-static int ilbctolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct ilbc_coder_pvt *tmp = pvt->pvt;
- int plc_mode = 1; /* 1 = normal data, 0 = plc */
- /* Assuming there's space left, decode into the current buffer at
- the tail location. Read in as many frames as there are */
- int x,i;
- int16_t *dst = (int16_t *)pvt->outbuf;
- float tmpf[ILBC_SAMPLES];
-
- if (f->datalen == 0) { /* native PLC, set fake f->datalen and clear plc_mode */
- f->datalen = ILBC_FRAME_LEN;
- f->samples = ILBC_SAMPLES;
- plc_mode = 0; /* do native plc */
- pvt->samples += ILBC_SAMPLES;
- }
-
- if (f->datalen % ILBC_FRAME_LEN) {
- ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, f->datalen);
- return -1;
- }
-
- for (x=0; x < f->datalen ; x += ILBC_FRAME_LEN) {
- if (pvt->samples + ILBC_SAMPLES > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- iLBC_decode(tmpf, plc_mode ? f->data + x : NULL, &tmp->dec, plc_mode);
- for ( i=0; i < ILBC_SAMPLES; i++)
- dst[pvt->samples + i] = tmpf[i];
- pvt->samples += ILBC_SAMPLES;
- pvt->datalen += 2*ILBC_SAMPLES;
- }
- return 0;
-}
-
-/*! \brief store a frame into a temporary buffer, for later decoding */
-static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct ilbc_coder_pvt *tmp = pvt->pvt;
-
- /* Just add the frames to our stream */
- /* XXX We should look at how old the rest of our stream is, and if it
- is too old, then we should overwrite it entirely, otherwise we can
- get artifacts of earlier talk that do not belong */
- memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
- pvt->samples += f->samples;
- return 0;
-}
-
-/*! \brief encode the temporary buffer and generate a frame */
-static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
-{
- struct ilbc_coder_pvt *tmp = pvt->pvt;
- int datalen = 0;
- int samples = 0;
-
- /* We can't work on anything less than a frame in size */
- if (pvt->samples < ILBC_SAMPLES)
- return NULL;
- while (pvt->samples >= ILBC_SAMPLES) {
- float tmpf[ILBC_SAMPLES];
- int i;
-
- /* Encode a frame of data */
- for (i = 0 ; i < ILBC_SAMPLES ; i++)
- tmpf[i] = tmp->buf[samples + i];
- iLBC_encode((unsigned char *) pvt->outbuf + datalen, tmpf, &tmp->enc);
-
- datalen += ILBC_FRAME_LEN;
- samples += ILBC_SAMPLES;
- pvt->samples -= ILBC_SAMPLES;
- }
-
- /* Move the data at the end of the buffer to the front */
- if (pvt->samples)
- memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
-
- return ast_trans_frameout(pvt, datalen, samples);
-}
-
-static struct ast_translator ilbctolin = {
- .name = "ilbctolin",
- .srcfmt = AST_FORMAT_ILBC,
- .dstfmt = AST_FORMAT_SLINEAR,
- .newpvt = ilbctolin_new,
- .framein = ilbctolin_framein,
- .sample = ilbctolin_sample,
- .desc_size = sizeof(struct ilbc_coder_pvt),
- .buf_size = BUFFER_SAMPLES * 2,
- .native_plc = 1,
-};
-
-static struct ast_translator lintoilbc = {
- .name = "lintoilbc",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_ILBC,
- .newpvt = lintoilbc_new,
- .framein = lintoilbc_framein,
- .frameout = lintoilbc_frameout,
- .sample = lintoilbc_sample,
- .desc_size = sizeof(struct ilbc_coder_pvt),
- .buf_size = (BUFFER_SAMPLES * ILBC_FRAME_LEN + ILBC_SAMPLES - 1) / ILBC_SAMPLES,
-};
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintoilbc);
- res |= ast_unregister_translator(&ilbctolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_translator(&ilbctolin);
- if (!res)
- res=ast_register_translator(&lintoilbc);
- else
- ast_unregister_translator(&ilbctolin);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "iLBC Coder/Decoder");
diff --git a/1.4/codecs/codec_lpc10.c b/1.4/codecs/codec_lpc10.c
deleted file mode 100644
index 3f46e0af8..000000000
--- a/1.4/codecs/codec_lpc10.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * The lpc10 code is from a library used by nautilus, modified to be a bit
- * nicer to the compiler.
- * See http://www.arl.wustl.edu/~jaf/
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Translate between signed linear and LPC10 (Linear Predictor Code)
- *
- * \ingroup codecs
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/translate.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-#include "lpc10/lpc10.h"
-
-/* Sample frame data */
-#include "slin_lpc10_ex.h"
-#include "lpc10_slin_ex.h"
-
-/* We use a very strange format here... I have no idea why... The frames are 180
- samples long, which isn't even an even number of milliseconds... Not only that
- but we hvae to waste two bits of each frame to keep them ending on a byte boundary
- because the frames are 54 bits long */
-
-#define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
-
-#define BUFFER_SAMPLES 8000
-
-struct lpc10_coder_pvt {
- union {
- struct lpc10_encoder_state *enc;
- struct lpc10_decoder_state *dec;
- } lpc10;
- /* Enough to store a full second */
- short buf[BUFFER_SAMPLES];
- int longer;
-};
-
-static int lpc10_enc_new(struct ast_trans_pvt *pvt)
-{
- struct lpc10_coder_pvt *tmp = pvt->pvt;
-
- return (tmp->lpc10.enc = create_lpc10_encoder_state()) ? 0 : -1;
-}
-
-static int lpc10_dec_new(struct ast_trans_pvt *pvt)
-{
- struct lpc10_coder_pvt *tmp = pvt->pvt;
-
- return (tmp->lpc10.dec = create_lpc10_decoder_state()) ? 0 : -1;
-}
-
-static struct ast_frame *lintolpc10_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_lpc10_ex);
- /* Assume 8000 Hz */
- f.samples = LPC10_SAMPLES_PER_FRAME;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_lpc10_ex;
- return &f;
-}
-
-static struct ast_frame *lpc10tolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_LPC10;
- f.datalen = sizeof(lpc10_slin_ex);
- /* All frames are 22 ms long (maybe a little more -- why did he choose
- LPC10_SAMPLES_PER_FRAME sample frames anyway?? */
- f.samples = LPC10_SAMPLES_PER_FRAME;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = lpc10_slin_ex;
- return &f;
-}
-
-static void extract_bits(INT32 *bits, unsigned char *c)
-{
- int x;
- for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
- if (*c & (0x80 >> (x & 7)))
- bits[x] = 1;
- else
- bits[x] = 0;
- if ((x & 7) == 7)
- c++;
- }
-}
-
-/* XXX note lpc10_encode() produces one bit per word in bits[] */
-static void build_bits(unsigned char *c, INT32 *bits)
-{
- unsigned char mask=0x80;
- int x;
- *c = 0;
- for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
- if (bits[x])
- *c |= mask;
- mask = mask >> 1;
- if ((x % 8)==7) {
- c++;
- *c = 0;
- mask = 0x80;
- }
- }
-}
-
-static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct lpc10_coder_pvt *tmp = pvt->pvt;
- int16_t *dst = (int16_t *)pvt->outbuf;
- int len = 0;
-
- while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
- int x;
- float tmpbuf[LPC10_SAMPLES_PER_FRAME];
- INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX see note */
- if (pvt->samples + LPC10_SAMPLES_PER_FRAME > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- extract_bits(bits, f->data + len);
- if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
- ast_log(LOG_WARNING, "Invalid lpc10 data\n");
- return -1;
- }
- for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
- /* Convert to a short between -1.0 and 1.0 */
- dst[pvt->samples + x] = (int16_t)(32768.0 * tmpbuf[x]);
- }
-
- pvt->samples += LPC10_SAMPLES_PER_FRAME;
- pvt->datalen += 2*LPC10_SAMPLES_PER_FRAME;
- len += LPC10_BYTES_IN_COMPRESSED_FRAME;
- }
- if (len != f->datalen)
- printf("Decoded %d, expected %d\n", len, f->datalen);
- return 0;
-}
-
-static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct lpc10_coder_pvt *tmp = pvt->pvt;
-
- /* Just add the frames to our stream */
- if (pvt->samples + f->samples > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
- pvt->samples += f->samples;
- return 0;
-}
-
-static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
-{
- struct lpc10_coder_pvt *tmp = pvt->pvt;
- int x;
- int datalen = 0; /* output frame */
- int samples = 0; /* output samples */
- float tmpbuf[LPC10_SAMPLES_PER_FRAME];
- INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX what ??? */
- /* We can't work on anything less than a frame in size */
- if (pvt->samples < LPC10_SAMPLES_PER_FRAME)
- return NULL;
- while (pvt->samples >= LPC10_SAMPLES_PER_FRAME) {
- /* Encode a frame of data */
- for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++)
- tmpbuf[x] = (float)tmp->buf[x + samples] / 32768.0;
- lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
- build_bits((unsigned char *) pvt->outbuf + datalen, bits);
- datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
- samples += LPC10_SAMPLES_PER_FRAME;
- pvt->samples -= LPC10_SAMPLES_PER_FRAME;
- /* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
- important for IAX use */
- tmp->longer = 1 - tmp->longer;
- }
- /* Move the data at the end of the buffer to the front */
- if (pvt->samples)
- memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
- return ast_trans_frameout(pvt, datalen, samples);
-}
-
-
-static void lpc10_destroy(struct ast_trans_pvt *arg)
-{
- struct lpc10_coder_pvt *pvt = arg->pvt;
- /* Enc and DEC are both just allocated, so they can be freed */
- free(pvt->lpc10.enc);
-}
-
-static struct ast_translator lpc10tolin = {
- .name = "lpc10tolin",
- .srcfmt = AST_FORMAT_LPC10,
- .dstfmt = AST_FORMAT_SLINEAR,
- .newpvt = lpc10_dec_new,
- .framein = lpc10tolin_framein,
- .destroy = lpc10_destroy,
- .sample = lpc10tolin_sample,
- .desc_size = sizeof(struct lpc10_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .plc_samples = LPC10_SAMPLES_PER_FRAME,
- .buf_size = BUFFER_SAMPLES * 2,
-};
-
-static struct ast_translator lintolpc10 = {
- .name = "lintolpc10",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_LPC10,
- .newpvt = lpc10_enc_new,
- .framein = lintolpc10_framein,
- .frameout = lintolpc10_frameout,
- .destroy = lpc10_destroy,
- .sample = lintolpc10_sample,
- .desc_size = sizeof(struct lpc10_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = LPC10_BYTES_IN_COMPRESSED_FRAME * (1 + BUFFER_SAMPLES / LPC10_SAMPLES_PER_FRAME),
-};
-
-static void parse_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg = ast_config_load("codecs.conf");
- if (!cfg)
- return;
- for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- lpc10tolin.useplc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_lpc10: %susing generic PLC\n",
- lpc10tolin.useplc ? "" : "not ");
- }
- }
- ast_config_destroy(cfg);
-}
-
-static int reload(void)
-{
- parse_config();
-
- return 0;
-}
-
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintolpc10);
- res |= ast_unregister_translator(&lpc10tolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- parse_config();
- res=ast_register_translator(&lpc10tolin);
- if (!res)
- res=ast_register_translator(&lintolpc10);
- else
- ast_unregister_translator(&lpc10tolin);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "LPC10 2.4kbps Coder/Decoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_speex.c b/1.4/codecs/codec_speex.c
deleted file mode 100644
index 6eff087d3..000000000
--- a/1.4/codecs/codec_speex.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Translate between signed linear and Speex (Open Codec)
- *
- * http://www.speex.org
- * \note This work was motivated by Jeremy McNamara
- * hacked to be configurable by anthm and bkw 9/28/2004
- * \ingroup codecs
- */
-
-/*** MODULEINFO
- <depend>speex</depend>
- <depend>speex_preprocess</depend>
- <use>speexdsp</use>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <stdio.h>
-#include <speex/speex.h>
-
-/* We require a post 1.1.8 version of Speex to enable preprocessing
- and better type handling */
-#ifdef _SPEEX_TYPES_H
-#include <speex/speex_preprocess.h>
-#endif
-
-#include "asterisk/lock.h"
-#include "asterisk/translate.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-/* Sample frame data */
-#include "slin_speex_ex.h"
-#include "speex_slin_ex.h"
-
-/* codec variables */
-static int quality = 3;
-static int complexity = 2;
-static int enhancement = 0;
-static int vad = 0;
-static int vbr = 0;
-static float vbr_quality = 4;
-static int abr = 0;
-static int dtx = 0; /* set to 1 to enable silence detection */
-
-static int preproc = 0;
-static int pp_vad = 0;
-static int pp_agc = 0;
-static float pp_agc_level = 8000; /* XXX what is this 8000 ? */
-static int pp_denoise = 0;
-static int pp_dereverb = 0;
-static float pp_dereverb_decay = 0.4;
-static float pp_dereverb_level = 0.3;
-
-#define TYPE_SILENCE 0x2
-#define TYPE_HIGH 0x0
-#define TYPE_LOW 0x1
-#define TYPE_MASK 0x3
-
-#define BUFFER_SAMPLES 8000
-#define SPEEX_SAMPLES 160
-
-struct speex_coder_pvt {
- void *speex;
- SpeexBits bits;
- int framesize;
- int silent_state;
-#ifdef _SPEEX_TYPES_H
- SpeexPreprocessState *pp;
- spx_int16_t buf[BUFFER_SAMPLES];
-#else
- int16_t buf[BUFFER_SAMPLES]; /* input, waiting to be compressed */
-#endif
-};
-
-
-static int lintospeex_new(struct ast_trans_pvt *pvt)
-{
- struct speex_coder_pvt *tmp = pvt->pvt;
-
- if (!(tmp->speex = speex_encoder_init(&speex_nb_mode)))
- return -1;
-
- speex_bits_init(&tmp->bits);
- speex_bits_reset(&tmp->bits);
- speex_encoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
- speex_encoder_ctl(tmp->speex, SPEEX_SET_COMPLEXITY, &complexity);
-#ifdef _SPEEX_TYPES_H
- if (preproc) {
- tmp->pp = speex_preprocess_state_init(tmp->framesize, 8000); /* XXX what is this 8000 ? */
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_VAD, &pp_vad);
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC, &pp_agc);
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &pp_agc_level);
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DENOISE, &pp_denoise);
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB, &pp_dereverb);
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &pp_dereverb_decay);
- speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &pp_dereverb_level);
- }
-#endif
- if (!abr && !vbr) {
- speex_encoder_ctl(tmp->speex, SPEEX_SET_QUALITY, &quality);
- if (vad)
- speex_encoder_ctl(tmp->speex, SPEEX_SET_VAD, &vad);
- }
- if (vbr) {
- speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR, &vbr);
- speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR_QUALITY, &vbr_quality);
- }
- if (abr)
- speex_encoder_ctl(tmp->speex, SPEEX_SET_ABR, &abr);
- if (dtx)
- speex_encoder_ctl(tmp->speex, SPEEX_SET_DTX, &dtx);
- tmp->silent_state = 0;
-
- return 0;
-}
-
-static int speextolin_new(struct ast_trans_pvt *pvt)
-{
- struct speex_coder_pvt *tmp = pvt->pvt;
-
- if (!(tmp->speex = speex_decoder_init(&speex_nb_mode)))
- return -1;
-
- speex_bits_init(&tmp->bits);
- speex_decoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
- if (enhancement)
- speex_decoder_ctl(tmp->speex, SPEEX_SET_ENH, &enhancement);
-
- return 0;
-}
-
-static struct ast_frame *lintospeex_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_speex_ex);
- /* Assume 8000 Hz */
- f.samples = sizeof(slin_speex_ex)/2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_speex_ex;
- return &f;
-}
-
-static struct ast_frame *speextolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SPEEX;
- f.datalen = sizeof(speex_slin_ex);
- /* All frames are 20 ms long */
- f.samples = SPEEX_SAMPLES;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = speex_slin_ex;
- return &f;
-}
-
-/*! \brief convert and store into outbuf */
-static int speextolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct speex_coder_pvt *tmp = pvt->pvt;
-
- /* Assuming there's space left, decode into the current buffer at
- the tail location. Read in as many frames as there are */
- int x;
- int res;
- int16_t *dst = (int16_t *)pvt->outbuf;
- /* XXX fout is a temporary buffer, may have different types */
-#ifdef _SPEEX_TYPES_H
- spx_int16_t fout[1024];
-#else
- float fout[1024];
-#endif
-
- if (f->datalen == 0) { /* Native PLC interpolation */
- if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
-#ifdef _SPEEX_TYPES_H
- speex_decode_int(tmp->speex, NULL, dst + pvt->samples);
-#else
- speex_decode(tmp->speex, NULL, fout);
- for (x=0;x<tmp->framesize;x++) {
- dst[pvt->samples + x] = (int16_t)fout[x];
- }
-#endif
- pvt->samples += tmp->framesize;
- pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
- return 0;
- }
-
- /* Read in bits */
- speex_bits_read_from(&tmp->bits, f->data, f->datalen);
- for (;;) {
-#ifdef _SPEEX_TYPES_H
- res = speex_decode_int(tmp->speex, &tmp->bits, fout);
-#else
- res = speex_decode(tmp->speex, &tmp->bits, fout);
-#endif
- if (res < 0)
- break;
- if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- for (x = 0 ; x < tmp->framesize; x++)
- dst[pvt->samples + x] = (int16_t)fout[x];
- pvt->samples += tmp->framesize;
- pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
- }
- return 0;
-}
-
-/*! \brief store input frame in work buffer */
-static int lintospeex_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct speex_coder_pvt *tmp = pvt->pvt;
-
- /* XXX We should look at how old the rest of our stream is, and if it
- is too old, then we should overwrite it entirely, otherwise we can
- get artifacts of earlier talk that do not belong */
- memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
- pvt->samples += f->samples;
- return 0;
-}
-
-/*! \brief convert work buffer and produce output frame */
-static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
-{
- struct speex_coder_pvt *tmp = pvt->pvt;
- int is_speech=1;
- int datalen = 0; /* output bytes */
- int samples = 0; /* output samples */
-
- /* We can't work on anything less than a frame in size */
- if (pvt->samples < tmp->framesize)
- return NULL;
- speex_bits_reset(&tmp->bits);
- while (pvt->samples >= tmp->framesize) {
-#ifdef _SPEEX_TYPES_H
- /* Preprocess audio */
- if (preproc)
- is_speech = speex_preprocess(tmp->pp, tmp->buf + samples, NULL);
- /* Encode a frame of data */
- if (is_speech) {
- /* If DTX enabled speex_encode returns 0 during silence */
- is_speech = speex_encode_int(tmp->speex, tmp->buf + samples, &tmp->bits) || !dtx;
- } else {
- /* 5 zeros interpreted by Speex as silence (submode 0) */
- speex_bits_pack(&tmp->bits, 0, 5);
- }
-#else
- {
- float fbuf[1024];
- int x;
- /* Convert to floating point */
- for (x = 0; x < tmp->framesize; x++)
- fbuf[x] = tmp->buf[samples + x];
- /* Encode a frame of data */
- is_speech = speex_encode(tmp->speex, fbuf, &tmp->bits) || !dtx;
- }
-#endif
- samples += tmp->framesize;
- pvt->samples -= tmp->framesize;
- }
-
- /* Move the data at the end of the buffer to the front */
- if (pvt->samples)
- memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
-
- /* Use AST_FRAME_CNG to signify the start of any silence period */
- if (is_speech) {
- tmp->silent_state = 0;
- } else {
- if (tmp->silent_state) {
- return NULL;
- } else {
- tmp->silent_state = 1;
- speex_bits_reset(&tmp->bits);
- memset(&pvt->f, 0, sizeof(pvt->f));
- pvt->f.frametype = AST_FRAME_CNG;
- pvt->f.samples = samples;
- /* XXX what now ? format etc... */
- }
- }
-
- /* Terminate bit stream */
- speex_bits_pack(&tmp->bits, 15, 5);
- datalen = speex_bits_write(&tmp->bits, pvt->outbuf, pvt->t->buf_size);
- return ast_trans_frameout(pvt, datalen, samples);
-}
-
-static void speextolin_destroy(struct ast_trans_pvt *arg)
-{
- struct speex_coder_pvt *pvt = arg->pvt;
-
- speex_decoder_destroy(pvt->speex);
- speex_bits_destroy(&pvt->bits);
-}
-
-static void lintospeex_destroy(struct ast_trans_pvt *arg)
-{
- struct speex_coder_pvt *pvt = arg->pvt;
-#ifdef _SPEEX_TYPES_H
- if (preproc)
- speex_preprocess_state_destroy(pvt->pp);
-#endif
- speex_encoder_destroy(pvt->speex);
- speex_bits_destroy(&pvt->bits);
-}
-
-static struct ast_translator speextolin = {
- .name = "speextolin",
- .srcfmt = AST_FORMAT_SPEEX,
- .dstfmt = AST_FORMAT_SLINEAR,
- .newpvt = speextolin_new,
- .framein = speextolin_framein,
- .destroy = speextolin_destroy,
- .sample = speextolin_sample,
- .desc_size = sizeof(struct speex_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .native_plc = 1,
-};
-
-static struct ast_translator lintospeex = {
- .name = "lintospeex",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_SPEEX,
- .newpvt = lintospeex_new,
- .framein = lintospeex_framein,
- .frameout = lintospeex_frameout,
- .destroy = lintospeex_destroy,
- .sample = lintospeex_sample,
- .desc_size = sizeof(struct speex_coder_pvt),
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2, /* XXX maybe a lot less ? */
-};
-
-static void parse_config(void)
-{
- struct ast_config *cfg = ast_config_load("codecs.conf");
- struct ast_variable *var;
- int res;
- float res_f;
-
- if (cfg == NULL)
- return;
-
- for (var = ast_variable_browse(cfg, "speex"); var; var = var->next) {
- if (!strcasecmp(var->name, "quality")) {
- res = abs(atoi(var->value));
- if (res > -1 && res < 11) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting Quality to %d\n",res);
- quality = res;
- } else
- ast_log(LOG_ERROR,"Error Quality must be 0-10\n");
- } else if (!strcasecmp(var->name, "complexity")) {
- res = abs(atoi(var->value));
- if (res > -1 && res < 11) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting Complexity to %d\n",res);
- complexity = res;
- } else
- ast_log(LOG_ERROR,"Error! Complexity must be 0-10\n");
- } else if (!strcasecmp(var->name, "vbr_quality")) {
- if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0 && res_f <= 10) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting VBR Quality to %f\n",res_f);
- vbr_quality = res_f;
- } else
- ast_log(LOG_ERROR,"Error! VBR Quality must be 0-10\n");
- } else if (!strcasecmp(var->name, "abr_quality")) {
- ast_log(LOG_ERROR,"Error! ABR Quality setting obsolete, set ABR to desired bitrate\n");
- } else if (!strcasecmp(var->name, "enhancement")) {
- enhancement = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Perceptual Enhancement Mode. [%s]\n",enhancement ? "on" : "off");
- } else if (!strcasecmp(var->name, "vbr")) {
- vbr = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: VBR Mode. [%s]\n",vbr ? "on" : "off");
- } else if (!strcasecmp(var->name, "abr")) {
- res = abs(atoi(var->value));
- if (res >= 0) {
- if (option_verbose > 2) {
- if (res > 0)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting ABR target bitrate to %d\n",res);
- else
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Disabling ABR\n");
- }
- abr = res;
- } else
- ast_log(LOG_ERROR,"Error! ABR target bitrate must be >= 0\n");
- } else if (!strcasecmp(var->name, "vad")) {
- vad = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: VAD Mode. [%s]\n",vad ? "on" : "off");
- } else if (!strcasecmp(var->name, "dtx")) {
- dtx = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: DTX Mode. [%s]\n",dtx ? "on" : "off");
- } else if (!strcasecmp(var->name, "preprocess")) {
- preproc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Preprocessing. [%s]\n",preproc ? "on" : "off");
- } else if (!strcasecmp(var->name, "pp_vad")) {
- pp_vad = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Preprocessor VAD. [%s]\n",pp_vad ? "on" : "off");
- } else if (!strcasecmp(var->name, "pp_agc")) {
- pp_agc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Preprocessor AGC. [%s]\n",pp_agc ? "on" : "off");
- } else if (!strcasecmp(var->name, "pp_agc_level")) {
- if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting preprocessor AGC Level to %f\n",res_f);
- pp_agc_level = res_f;
- } else
- ast_log(LOG_ERROR,"Error! Preprocessor AGC Level must be >= 0\n");
- } else if (!strcasecmp(var->name, "pp_denoise")) {
- pp_denoise = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Preprocessor Denoise. [%s]\n",pp_denoise ? "on" : "off");
- } else if (!strcasecmp(var->name, "pp_dereverb")) {
- pp_dereverb = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Preprocessor Dereverb. [%s]\n",pp_dereverb ? "on" : "off");
- } else if (!strcasecmp(var->name, "pp_dereverb_decay")) {
- if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting preprocessor Dereverb Decay to %f\n",res_f);
- pp_dereverb_decay = res_f;
- } else
- ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Decay must be >= 0\n");
- } else if (!strcasecmp(var->name, "pp_dereverb_level")) {
- if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting preprocessor Dereverb Level to %f\n",res_f);
- pp_dereverb_level = res_f;
- } else
- ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Level must be >= 0\n");
- }
- }
- ast_config_destroy(cfg);
-}
-
-static int reload(void)
-{
- parse_config();
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintospeex);
- res |= ast_unregister_translator(&speextolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- parse_config();
- res=ast_register_translator(&speextolin);
- if (!res)
- res=ast_register_translator(&lintospeex);
- else
- ast_unregister_translator(&speextolin);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Speex Coder/Decoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_ulaw.c b/1.4/codecs/codec_ulaw.c
deleted file mode 100644
index 334f8d9ad..000000000
--- a/1.4/codecs/codec_ulaw.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief codec_ulaw.c - translate between signed linear and ulaw
- *
- * \ingroup codecs
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/translate.h"
-#include "asterisk/channel.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/utils.h"
-
-#define BUFFER_SAMPLES 8096 /* size for the translation buffers */
-
-/* Sample frame data */
-
-#include "slin_ulaw_ex.h"
-#include "ulaw_slin_ex.h"
-
-/*! \brief convert and store samples in outbuf */
-static int ulawtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int i = f->samples;
- unsigned char *src = f->data;
- int16_t *dst = (int16_t *)pvt->outbuf + pvt->samples;
-
- pvt->samples += i;
- pvt->datalen += i * 2; /* 2 bytes/sample */
-
- /* convert and copy in outbuf */
- while (i--)
- *dst++ = AST_MULAW(*src++);
-
- return 0;
-}
-
-/*! \brief convert and store samples in outbuf */
-static int lintoulaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int i = f->samples;
- char *dst = pvt->outbuf + pvt->samples;
- int16_t *src = f->data;
-
- pvt->samples += i;
- pvt->datalen += i; /* 1 byte/sample */
-
- while (i--)
- *dst++ = AST_LIN2MU(*src++);
-
- return 0;
-}
-
-/*! * \brief ulawToLin_Sample */
-static struct ast_frame *ulawtolin_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_ULAW;
- f.datalen = sizeof(ulaw_slin_ex);
- f.samples = sizeof(ulaw_slin_ex);
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = ulaw_slin_ex;
- return &f;
-}
-
-/*!
- * \brief LinToulaw_Sample
- */
-
-static struct ast_frame *lintoulaw_sample(void)
-{
- static struct ast_frame f;
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.datalen = sizeof(slin_ulaw_ex);
- /* Assume 8000 Hz */
- f.samples = sizeof(slin_ulaw_ex) / 2;
- f.mallocd = 0;
- f.offset = 0;
- f.src = __PRETTY_FUNCTION__;
- f.data = slin_ulaw_ex;
- return &f;
-}
-
-/*!
- * \brief The complete translator for ulawToLin.
- */
-
-static struct ast_translator ulawtolin = {
- .name = "ulawtolin",
- .srcfmt = AST_FORMAT_ULAW,
- .dstfmt = AST_FORMAT_SLINEAR,
- .framein = ulawtolin_framein,
- .sample = ulawtolin_sample,
- .buffer_samples = BUFFER_SAMPLES,
- .buf_size = BUFFER_SAMPLES * 2,
- .plc_samples = 160,
-};
-
-/*!
- * \brief The complete translator for LinToulaw.
- */
-
-static struct ast_translator lintoulaw = {
- .name = "lintoulaw",
- .srcfmt = AST_FORMAT_SLINEAR,
- .dstfmt = AST_FORMAT_ULAW,
- .framein = lintoulaw_framein,
- .sample = lintoulaw_sample,
- .buf_size = BUFFER_SAMPLES,
- .buffer_samples = BUFFER_SAMPLES,
-};
-
-static void parse_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg = ast_config_load("codecs.conf");
- if (!cfg)
- return;
- for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- ulawtolin.useplc = ast_true(var->value) ? 1 : 0;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_ulaw: %susing generic PLC\n", ulawtolin.useplc ? "" : "not ");
- }
- }
- ast_config_destroy(cfg);
-}
-
-static int reload(void)
-{
- parse_config();
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_unregister_translator(&lintoulaw);
- res |= ast_unregister_translator(&ulawtolin);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- parse_config();
- res = ast_register_translator(&ulawtolin);
- if (!res)
- res = ast_register_translator(&lintoulaw);
- else
- ast_unregister_translator(&ulawtolin);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "mu-Law Coder/Decoder",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/codec_zap.c b/1.4/codecs/codec_zap.c
deleted file mode 100644
index f4ea5886f..000000000
--- a/1.4/codecs/codec_zap.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Zaptel native transcoding support
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- *
- * \brief Translate between various formats natively through Zaptel transcoding
- *
- * \ingroup codecs
- */
-
-/*** MODULEINFO
- <depend>zaptel_transcode</depend>
- <depend>zaptel</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <zaptel/zaptel.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/translate.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/cli.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-#include "asterisk/linkedlists.h"
-
-#define BUFFER_SAMPLES 8000
-
-static unsigned int global_useplc = 0;
-
-static struct channel_usage {
- int total;
- int encoders;
- int decoders;
-} channels;
-
-static char show_transcoder_usage[] =
-"Usage: show transcoder\n"
-" Displays channel utilization of Zaptel transcoder(s).\n";
-
-static char transcoder_show_usage[] =
-"Usage: transcoder show\n"
-" Displays channel utilization of Zaptel transcoder(s).\n";
-
-static int transcoder_show(int fd, int argc, char **argv);
-
-static struct ast_cli_entry cli_deprecated[] = {
- { { "show", "transcoder", NULL },
- transcoder_show,
- "Display Zaptel transcoder utilization.",
- show_transcoder_usage}
-};
-
-static struct ast_cli_entry cli[] = {
- { { "transcoder", "show", NULL },
- transcoder_show,
- "Display Zaptel transcoder utilization.",
- transcoder_show_usage, NULL,
- &cli_deprecated[0]}
-};
-
-struct format_map {
- unsigned int map[32][32];
-};
-
-static struct format_map global_format_map = { { { 0 } } };
-
-struct translator {
- struct ast_translator t;
- AST_LIST_ENTRY(translator) entry;
-};
-
-static AST_LIST_HEAD_STATIC(translators, translator);
-
-struct pvt {
- int fd;
- int fake;
- unsigned int g729b_warning:1;
-#ifdef DEBUG_TRANSCODE
- int totalms;
- int lasttotalms;
-#endif
- struct zt_transcode_header *hdr;
-};
-
-static int transcoder_show(int fd, int argc, char **argv)
-{
- struct channel_usage copy;
-
- copy = channels;
-
- if (copy.total == 0)
- ast_cli(fd, "No Zaptel transcoders found.\n");
- else
- ast_cli(fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
-
- return RESULT_SUCCESS;
-}
-
-static int zap_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- struct pvt *ztp = pvt->pvt;
- struct zt_transcode_header *hdr = ztp->hdr;
-
- if (!f->subclass) {
- /* Fake a return frame for calculation purposes */
- ztp->fake = 2;
- pvt->samples = f->samples;
- return 0;
- }
-
- if (!hdr->srclen)
- /* Copy at front of buffer */
- hdr->srcoffset = 0;
-
- /* if we get handed a G.729 frame that is not a multiple of
- 10 bytes (10 milliseconds), then it has a CNG frame and
- we need to avoid sending that to the transcoder
- */
- if ((f->subclass == AST_FORMAT_G729A) && ((f->datalen % 10) != 0)) {
- if (!ztp->g729b_warning) {
- ast_log(LOG_WARNING, "G.729B CNG frame received but is not supported; dropping.\n");
- ztp->g729b_warning = 1;
- }
- f->datalen -= f->datalen % 10;
- f->samples = f->datalen * 8;
- }
-
- if (hdr->srclen + f->datalen > sizeof(hdr->srcdata)) {
- ast_log(LOG_WARNING, "Out of space for codec translation!\n");
- return -1;
- }
-
- if (hdr->srclen + f->datalen + hdr->srcoffset > sizeof(hdr->srcdata)) {
- /* Very unlikely */
- memmove(hdr->srcdata, hdr->srcdata + hdr->srcoffset, hdr->srclen);
- hdr->srcoffset = 0;
- }
-
- memcpy(hdr->srcdata + hdr->srcoffset + hdr->srclen, f->data, f->datalen);
- hdr->srclen += f->datalen;
- pvt->samples += f->samples;
-
- return -1;
-}
-
-static struct ast_frame *zap_frameout(struct ast_trans_pvt *pvt)
-{
- struct pvt *ztp = pvt->pvt;
- struct zt_transcode_header *hdr = ztp->hdr;
- unsigned int x;
-
- if (ztp->fake == 2) {
- ztp->fake = 1;
- pvt->f.frametype = AST_FRAME_VOICE;
- pvt->f.subclass = 0;
- pvt->f.samples = 160;
- pvt->f.data = NULL;
- pvt->f.offset = 0;
- pvt->f.datalen = 0;
- pvt->f.mallocd = 0;
- ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR);
- pvt->samples = 0;
- } else if (ztp->fake == 1) {
- return NULL;
- } else {
- if (hdr->dstlen) {
-#ifdef DEBUG_TRANSCODE
- ztp->totalms += hdr->dstsamples;
- if ((ztp->totalms - ztp->lasttotalms) > 8000) {
- printf("Whee %p, %d (%d to %d)\n", ztp, hdr->dstlen, ztp->lasttotalms, ztp->totalms);
- ztp->lasttotalms = ztp->totalms;
- }
-#endif
- pvt->f.frametype = AST_FRAME_VOICE;
- pvt->f.subclass = hdr->dstfmt;
- pvt->f.samples = hdr->dstsamples;
- pvt->f.data = hdr->dstdata + hdr->dstoffset;
- pvt->f.offset = hdr->dstoffset;
- pvt->f.datalen = hdr->dstlen;
- pvt->f.mallocd = 0;
- ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR);
- pvt->samples -= pvt->f.samples;
- hdr->dstlen = 0;
-
- } else {
- if (hdr->srclen) {
- hdr->dstoffset = AST_FRIENDLY_OFFSET;
- x = ZT_TCOP_TRANSCODE;
- if (ioctl(ztp->fd, ZT_TRANSCODE_OP, &x))
- ast_log(LOG_WARNING, "Failed to transcode: %s\n", strerror(errno));
- }
- return NULL;
- }
- }
-
- return &pvt->f;
-}
-
-static void zap_destroy(struct ast_trans_pvt *pvt)
-{
- struct pvt *ztp = pvt->pvt;
- unsigned int x;
-
- x = ZT_TCOP_RELEASE;
- if (ioctl(ztp->fd, ZT_TRANSCODE_OP, &x))
- ast_log(LOG_WARNING, "Failed to release transcoder channel: %s\n", strerror(errno));
-
- switch (ztp->hdr->dstfmt) {
- case AST_FORMAT_G729A:
- case AST_FORMAT_G723_1:
- ast_atomic_fetchadd_int(&channels.encoders, -1);
- break;
- default:
- ast_atomic_fetchadd_int(&channels.decoders, -1);
- break;
- }
-
- munmap(ztp->hdr, sizeof(*ztp->hdr));
- close(ztp->fd);
-}
-
-static int zap_translate(struct ast_trans_pvt *pvt, int dest, int source)
-{
- /* Request translation through zap if possible */
- int fd;
- unsigned int x = ZT_TCOP_ALLOCATE;
- struct pvt *ztp = pvt->pvt;
- struct zt_transcode_header *hdr;
- int flags;
-
- if ((fd = open("/dev/zap/transcode", O_RDWR)) < 0)
- return -1;
- flags = fcntl(fd, F_GETFL);
- if (flags > - 1) {
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
- ast_log(LOG_WARNING, "Could not set non-block mode!\n");
- }
-
-
- if ((hdr = mmap(NULL, sizeof(*hdr), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
- ast_log(LOG_ERROR, "Memory Map failed for transcoding (%s)\n", strerror(errno));
- close(fd);
-
- return -1;
- }
-
- if (hdr->magic != ZT_TRANSCODE_MAGIC) {
- ast_log(LOG_ERROR, "Transcoder header (%08x) wasn't magic. Abandoning\n", hdr->magic);
- munmap(hdr, sizeof(*hdr));
- close(fd);
-
- return -1;
- }
-
- hdr->srcfmt = (1 << source);
- hdr->dstfmt = (1 << dest);
- if (ioctl(fd, ZT_TRANSCODE_OP, &x)) {
- ast_log(LOG_ERROR, "Unable to attach transcoder: %s\n", strerror(errno));
- munmap(hdr, sizeof(*hdr));
- close(fd);
-
- return -1;
- }
-
- ztp = pvt->pvt;
- ztp->fd = fd;
- ztp->hdr = hdr;
-
- switch (hdr->dstfmt) {
- case AST_FORMAT_G729A:
- case AST_FORMAT_G723_1:
- ast_atomic_fetchadd_int(&channels.encoders, +1);
- break;
- default:
- ast_atomic_fetchadd_int(&channels.decoders, +1);
- break;
- }
-
- return 0;
-}
-
-static int zap_new(struct ast_trans_pvt *pvt)
-{
- return zap_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
-}
-
-static struct ast_frame *fakesrc_sample(void)
-{
- /* Don't bother really trying to test hardware ones. */
- static struct ast_frame f = {
- .frametype = AST_FRAME_VOICE,
- .samples = 160,
- .src = __PRETTY_FUNCTION__
- };
-
- return &f;
-}
-
-static int register_translator(int dst, int src)
-{
- struct translator *zt;
- int res;
-
- if (!(zt = ast_calloc(1, sizeof(*zt))))
- return -1;
-
- snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s",
- ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
- zt->t.srcfmt = (1 << src);
- zt->t.dstfmt = (1 << dst);
- zt->t.newpvt = zap_new;
- zt->t.framein = zap_framein;
- zt->t.frameout = zap_frameout;
- zt->t.destroy = zap_destroy;
- zt->t.sample = fakesrc_sample;
- zt->t.useplc = global_useplc;
- zt->t.buf_size = BUFFER_SAMPLES * 2;
- zt->t.desc_size = sizeof(struct pvt);
- if ((res = ast_register_translator(&zt->t))) {
- free(zt);
- return -1;
- }
-
- AST_LIST_LOCK(&translators);
- AST_LIST_INSERT_HEAD(&translators, zt, entry);
- AST_LIST_UNLOCK(&translators);
-
- global_format_map.map[dst][src] = 1;
-
- return res;
-}
-
-static void drop_translator(int dst, int src)
-{
- struct translator *cur;
-
- AST_LIST_LOCK(&translators);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) {
- if (cur->t.srcfmt != src)
- continue;
-
- if (cur->t.dstfmt != dst)
- continue;
-
- AST_LIST_REMOVE_CURRENT(&translators, entry);
- ast_unregister_translator(&cur->t);
- free(cur);
- global_format_map.map[dst][src] = 0;
- break;
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&translators);
-}
-
-static void unregister_translators(void)
-{
- struct translator *cur;
-
- AST_LIST_LOCK(&translators);
- while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
- ast_unregister_translator(&cur->t);
- free(cur);
- }
- AST_LIST_UNLOCK(&translators);
-}
-
-static void parse_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg = ast_config_load("codecs.conf");
-
- if (!cfg)
- return;
-
- for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
- if (!strcasecmp(var->name, "genericplc")) {
- global_useplc = ast_true(var->value);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "codec_zap: %susing generic PLC\n",
- global_useplc ? "" : "not ");
- }
- }
-
- ast_config_destroy(cfg);
-}
-
-static void build_translators(struct format_map *map, unsigned int dstfmts, unsigned int srcfmts)
-{
- unsigned int src, dst;
-
- for (src = 0; src < 32; src++) {
- for (dst = 0; dst < 32; dst++) {
- if (!(srcfmts & (1 << src)))
- continue;
-
- if (!(dstfmts & (1 << dst)))
- continue;
-
- if (global_format_map.map[dst][src])
- continue;
-
- if (!register_translator(dst, src))
- map->map[dst][src] = 1;
- }
- }
-}
-
-static int find_transcoders(void)
-{
- struct zt_transcode_info info = { 0, };
- struct format_map map = { { { 0 } } };
- int fd, res;
- unsigned int x, y;
-
- if ((fd = open("/dev/zap/transcode", O_RDWR)) < 0) {
- ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n");
- return 0;
- }
-
- info.op = ZT_TCOP_GETINFO;
- for (info.tcnum = 0; !(res = ioctl(fd, ZT_TRANSCODE_OP, &info)); info.tcnum++) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name);
- build_translators(&map, info.dstfmts, info.srcfmts);
- ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2);
- }
-
- close(fd);
-
- if (!info.tcnum && (option_verbose > 1))
- ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n");
-
- for (x = 0; x < 32; x++) {
- for (y = 0; y < 32; y++) {
- if (!map.map[x][y] && global_format_map.map[x][y])
- drop_translator(x, y);
- }
- }
-
- return 0;
-}
-
-static int reload(void)
-{
- struct translator *cur;
-
- parse_config();
-
- AST_LIST_LOCK(&translators);
- AST_LIST_TRAVERSE(&translators, cur, entry)
- cur->t.useplc = global_useplc;
- AST_LIST_UNLOCK(&translators);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cli_unregister_multiple(cli, sizeof(cli) / sizeof(cli[0]));
- unregister_translators();
-
- return 0;
-}
-
-static int load_module(void)
-{
- parse_config();
- find_transcoders();
- ast_cli_register_multiple(cli, sizeof(cli) / sizeof(cli[0]));
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Generic Zaptel Transcoder Codec Translator",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/codecs/g726_slin_ex.h b/1.4/codecs/g726_slin_ex.h
deleted file mode 100644
index 80cbf00f4..000000000
--- a/1.4/codecs/g726_slin_ex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*! \file
- * adpcm_slin_ex.h --
- *
- * \brief 4-bit G.726 data, 20 milliseconds worth at 8 kHz.
- *
- * Source: g726.example
- *
- * Copyright (C) 2001-2005, Digium, Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char g726_slin_ex[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/1.4/codecs/gsm/COPYRIGHT b/1.4/codecs/gsm/COPYRIGHT
deleted file mode 100644
index eba0e523b..000000000
--- a/1.4/codecs/gsm/COPYRIGHT
+++ /dev/null
@@ -1,16 +0,0 @@
-Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
-Technische Universitaet Berlin
-
-Any use of this software is permitted provided that this notice is not
-removed and that neither the authors nor the Technische Universitaet Berlin
-are deemed to have made any representations as to the suitability of this
-software for any purpose nor are held responsible for any defects of
-this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
-
-As a matter of courtesy, the authors request to be informed about uses
-this software has found, about bugs in this software, and about any
-improvements that may be of general interest.
-
-Berlin, 28.11.1994
-Jutta Degener
-Carsten Bormann
diff --git a/1.4/codecs/gsm/Makefile b/1.4/codecs/gsm/Makefile
deleted file mode 100644
index b83f9a069..000000000
--- a/1.4/codecs/gsm/Makefile
+++ /dev/null
@@ -1,543 +0,0 @@
-# Copyright 1992-1996 by Jutta Degener and Carsten Bormann, Technische
-# Universitaet Berlin. See the accompanying file "COPYRIGHT" for
-# details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
-
-# Machine- or installation dependent flags you should configure to port
-
-SASR = -DSASR
-######### Define SASR if >> is a signed arithmetic shift (-1 >> 1 == -1)
-
-#MULHACK = -DUSE_FLOAT_MUL
-######### Define this if your host multiplies floats faster than integers,
-######### e.g. on a SPARCstation.
-
-#FAST = -DFAST
-######### Define together with USE_FLOAT_MUL to enable the GSM library's
-######### approximation option for incorrect, but good-enough results.
-
-# LTP_CUT = -DLTP_CUT
-LTP_CUT =
-######### Define to enable the GSM library's long-term correlation
-######### approximation option---faster, but worse; works for
-######### both integer and floating point multiplications.
-######### This flag is still in the experimental stage.
-
-WAV49 = -DWAV49
-#WAV49 =
-######### Define to enable the GSM library's option to pack GSM frames
-######### in the style used by the WAV #49 format. If you want to write
-######### a tool that produces .WAV files which contain GSM-encoded data,
-######### define this, and read about the GSM_OPT_WAV49 option in the
-######### manual page on gsm_option(3).
-
-#K6OPT = -DK6OPT
-#K6OPT =
-######### Define to enable MMXTM optimizations for x86 architecture CPU's
-######### which support MMX instructions. This should be newer pentiums,
-######### ppro's, etc, as well as the AMD K6 and K7. The compile will
-######### probably require gcc.
-
-ifeq (, $(findstring $(OSARCH) , Darwin SunOS ))
-ifeq (, $(findstring $(PROC) , x86_64 amd64 ultrasparc sparc64 arm armv5b armeb hppa2.0 ppc powerpc ppc64 ia64 s390 bfin mipsel mips))
-ifeq (, $(findstring $(shell uname -m) , ppc ppc64 alpha armv4l s390 ))
-OPTIMIZE+=-march=$(PROC)
-endif
-endif
-endif
-
-#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
-#This works for even old (2.96) versions of gcc and provides a small boost either way.
-#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesn't support it.
-#So we go lowest common available by gcc and go a step down, still a step up from
-#the default as we now have a better instruction set to work with. - Belgarath
-ifeq ($(PROC),ultrasparc)
-OPTIMIZE+=-mcpu=v8 -mtune=$(PROC) -O3
-endif
-
-PG =
-#PG = -g -pg
-######### Profiling flags. If you don't know what that means, leave it blank.
-
-# Choose a compiler. The code works both with ANSI and K&R-C.
-# Use -DNeedFunctionPrototypes to compile with, -UNeedFunctionPrototypes to
-# compile without, function prototypes in the header files.
-#
-# You can use the -DSTUPID_COMPILER to circumvent some compilers'
-# static limits regarding the number of subexpressions in a statement.
-
-# CC = cc
-# CCFLAGS = -c -DSTUPID_COMPILER
-
-# CC = /usr/lang/acc
-# CCFLAGS = -c -O
-
-CCFLAGS += -c -DNeedFunctionPrototypes=1 -funroll-loops $(OPTIMIZE)
-
-# LD = gcc
-# LDFLAGS =
-
-
-# If your compiler needs additional flags/libraries, regardless of
-# the source compiled, configure them here.
-
-# CCINC = -I/usr/gnu/lib/gcc-2.1/gcc-lib/sparc-sun-sunos4.1.2/2.1/include
-######### Includes needed by $(CC)
-
-# LDINC = -L/usr/gnu/lib/gcc-2.1/gcc-lib/sparc-sun-sunos4.1.2/2.1
-######### Library paths needed by $(LD)
-
-# LDLIB = -lgcc
-######### Additional libraries needed by $(LD)
-
-
-# Where do you want to install libraries, binaries, a header file
-# and the manual pages?
-#
-# Leave INSTALL_ROOT empty (or just don't execute "make install") to
-# not install gsm and toast outside of this directory.
-
-INSTALL_ROOT =
-
-# Where do you want to install the gsm library, header file, and manpages?
-#
-# Leave GSM_INSTALL_ROOT empty to not install the GSM library outside of
-# this directory.
-
-GSM_INSTALL_ROOT = $(INSTALL_ROOT)
-GSM_INSTALL_LIB = $(GSM_INSTALL_ROOT)/lib
-GSM_INSTALL_INC = $(GSM_INSTALL_ROOT)/inc
-GSM_INSTALL_MAN = $(GSM_INSTALL_ROOT)/man/man3
-
-
-# Where do you want to install the toast binaries and their manpage?
-#
-# Leave TOAST_INSTALL_ROOT empty to not install the toast binaries outside
-# of this directory.
-
-TOAST_INSTALL_ROOT = $(INSTALL_ROOT)
-TOAST_INSTALL_BIN = $(TOAST_INSTALL_ROOT)/bin
-TOAST_INSTALL_MAN = $(TOAST_INSTALL_ROOT)/man/man1
-
-# Other tools
-
-SHELL = /bin/sh
-LN = ln
-BASENAME = basename
-AR = ar
-ARFLAGS = cr
-RMFLAGS = -f
-FIND = find
-COMPRESS = compress
-COMPRESSFLAGS =
-# RANLIB = true
-RANLIB = ranlib
-
-#
-# You shouldn't have to configure below this line if you're porting.
-#
-
-
-# Local Directories
-
-ROOT = .
-ADDTST = $(ROOT)/add-test
-TST = $(ROOT)/tst
-MAN = $(ROOT)/man
-BIN = $(ROOT)/bin
-SRC = $(ROOT)/src
-LIB = $(ROOT)/lib
-TLS = $(ROOT)/tls
-INC = $(ROOT)/inc
-
-# Flags
-
-DEBUG = -DNDEBUG
-######### Remove -DNDEBUG to enable assertions.
-
-ASTCFLAGS += $(PG) $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) \
- $(LTP_CUT) $(WAV49) $(K6OPT) $(CCINC) -I$(INC)
-######### It's $(CC) $(CFLAGS)
-
-LFLAGS = $(PG) $(LDFLAGS) $(LDINC)
-######### It's $(LD) $(LFLAGS)
-
-
-# Targets
-
-LIBGSM = $(LIB)/libgsm.a
-LIBGSMSO= $(LIB)/libgsm.so
-
-TOAST = $(BIN)/toast
-UNTOAST = $(BIN)/untoast
-TCAT = $(BIN)/tcat
-
-# Headers
-
-GSM_HEADERS = $(INC)/gsm.h
-
-HEADERS = $(INC)/proto.h \
- $(INC)/unproto.h \
- $(INC)/config.h \
- $(INC)/private.h \
- $(INC)/gsm.h \
- $(INC)/toast.h \
- $(TLS)/taste.h
-
-# Sources
-
-GSM_SOURCES = $(SRC)/add.c \
- $(SRC)/code.c \
- $(SRC)/debug.c \
- $(SRC)/decode.c \
- $(SRC)/long_term.c \
- $(SRC)/lpc.c \
- $(SRC)/preprocess.c \
- $(SRC)/rpe.c \
- $(SRC)/gsm_destroy.c \
- $(SRC)/gsm_decode.c \
- $(SRC)/gsm_encode.c \
- $(SRC)/gsm_explode.c \
- $(SRC)/gsm_implode.c \
- $(SRC)/gsm_create.c \
- $(SRC)/gsm_print.c \
- $(SRC)/gsm_option.c \
- $(SRC)/short_term.c \
- $(SRC)/table.c
-
-# add k6-specific code only if not on a non-k6 hardware or proc.
-# XXX Keep a space after each findstring argument
-# XXX should merge with GSM_OBJECTS
-ifeq ($(OSARCH),linux-gnu)
-ifeq (,$(findstring $(shell uname -m) , x86_64 amd64 ppc ppc64 alpha armv4l sparc64 parisc s390 ))
-ifeq (,$(findstring $(PROC) , arm armv5b armeb powerpc ia64 s390 bfin mipsel mips ))
-GSM_SOURCES+= $(SRC)/k6opt.s
-endif
-endif
-endif
-
-TOAST_SOURCES = $(SRC)/toast.c \
- $(SRC)/toast_lin.c \
- $(SRC)/toast_ulaw.c \
- $(SRC)/toast_alaw.c \
- $(SRC)/toast_audio.c
-
-SOURCES = $(GSM_SOURCES) \
- $(TOAST_SOURCES) \
- $(ADDTST)/add_test.c \
- $(TLS)/sour.c \
- $(TLS)/ginger.c \
- $(TLS)/sour1.dta \
- $(TLS)/sour2.dta \
- $(TLS)/bitter.c \
- $(TLS)/bitter.dta \
- $(TLS)/taste.c \
- $(TLS)/sweet.c \
- $(TST)/cod2lin.c \
- $(TST)/cod2txt.c \
- $(TST)/gsm2cod.c \
- $(TST)/lin2cod.c \
- $(TST)/lin2txt.c
-
-# Object files
-
-GSM_OBJECTS = $(SRC)/add.o \
- $(SRC)/code.o \
- $(SRC)/debug.o \
- $(SRC)/decode.o \
- $(SRC)/long_term.o \
- $(SRC)/lpc.o \
- $(SRC)/preprocess.o \
- $(SRC)/rpe.o \
- $(SRC)/gsm_destroy.o \
- $(SRC)/gsm_decode.o \
- $(SRC)/gsm_encode.o \
- $(SRC)/gsm_explode.o \
- $(SRC)/gsm_implode.o \
- $(SRC)/gsm_create.o \
- $(SRC)/gsm_print.o \
- $(SRC)/gsm_option.o \
- $(SRC)/short_term.o \
- $(SRC)/table.o
-
-ifeq ($(OSARCH),linux-gnu)
-ifeq (,$(findstring $(shell uname -m) , x86_64 amd64 ppc ppc64 alpha armv4l sparc64 parisc ))
-ifeq (,$(findstring $(PROC) , arm armv5b armeb powerpc ia64 bfin mipsel mips ))
-GSM_OBJECTS+= $(SRC)/k6opt.o
-endif
-endif
-endif
-
-TOAST_OBJECTS = $(SRC)/toast.o \
- $(SRC)/toast_lin.o \
- $(SRC)/toast_ulaw.o \
- $(SRC)/toast_alaw.o \
- $(SRC)/toast_audio.o
-
-OBJECTS = $(GSM_OBJECTS) $(TOAST_OBJECTS)
-
-# Manuals
-
-GSM_MANUALS = $(MAN)/gsm.3 \
- $(MAN)/gsm_explode.3 \
- $(MAN)/gsm_option.3 \
- $(MAN)/gsm_print.3
-
-TOAST_MANUALS = $(MAN)/toast.1
-
-MANUALS = $(GSM_MANUALS) $(TOAST_MANUALS) $(MAN)/bitter.1
-
-# Other stuff in the distribution
-
-STUFF = ChangeLog \
- INSTALL \
- MACHINES \
- MANIFEST \
- Makefile \
- README \
- $(ADDTST)/add_test.dta \
- $(TLS)/bitter.dta \
- $(TST)/run
-
-
-# Install targets
-
-GSM_INSTALL_TARGETS = \
- $(GSM_INSTALL_LIB)/libgsm.a \
- $(GSM_INSTALL_INC)/gsm.h \
- $(GSM_INSTALL_MAN)/gsm.3 \
- $(GSM_INSTALL_MAN)/gsm_explode.3 \
- $(GSM_INSTALL_MAN)/gsm_option.3 \
- $(GSM_INSTALL_MAN)/gsm_print.3
-
-TOAST_INSTALL_TARGETS = \
- $(TOAST_INSTALL_BIN)/toast \
- $(TOAST_INSTALL_BIN)/tcat \
- $(TOAST_INSTALL_BIN)/untoast \
- $(TOAST_INSTALL_MAN)/toast.1
-
-
-# Default rules
-
-include $(ASTTOPDIR)/Makefile.rules
-
-# Target rules
-
-all: $(LIBGSM) $(LIBGSMSO) $(TOAST) $(TCAT) $(UNTOAST)
- @-echo $(ROOT): Done.
-
-tst: $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result
- @-echo tst: Done.
-
-addtst: $(ADDTST)/add $(ADDTST)/add_test.dta
- $(ADDTST)/add < $(ADDTST)/add_test.dta > /dev/null
- @-echo addtst: Done.
-
-misc: $(TLS)/sweet $(TLS)/bitter $(TLS)/sour $(TLS)/ginger \
- $(TST)/lin2txt $(TST)/cod2txt $(TST)/gsm2cod
- @-echo misc: Done.
-
-install: toastinstall gsminstall
- @-echo install: Done.
-
-
-# The basic API: libgsm
-
-$(LIBGSMSO): $(LIB) $(GSM_OBJECTS)
- $(LD) -o $@.1.0.10 -shared -Xlinker -soname -Xlinker libgsm.so.1 $(GSM_OBJECTS) -lc
- ln -fs libgsm.so.1.0.10 lib/libgsm.so.1
- ln -fs libgsm.so.1.0.10 lib/libgsm.so
-
-$(LIBGSM): $(GSM_OBJECTS)
- $(ECHO_PREFIX) echo " [AR] $^ -> $@"
- $(CMD_PREFIX) $(AR) cr $@ $^
- $(CMD_PREFIX) $(RANLIB) $@
-
-
-# Toast, Untoast and Tcat -- the compress-like frontends to gsm.
-
-$(TOAST): $(BIN) $(TOAST_OBJECTS) $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSMSO) $(LDLIB)
-
-$(UNTOAST): $(BIN) $(TOAST)
- -rm $(RMFLAGS) $(UNTOAST)
- $(LN) toast $(UNTOAST)
-
-$(TCAT): $(BIN) $(TOAST)
- -rm $(RMFLAGS) $(TCAT)
- $(LN) toast $(TCAT)
-
-
-# The local bin and lib directories
-
-$(BIN):
- if [ ! -d $(BIN) ] ; then mkdir $(BIN) ; fi
-
-$(LIB):
- if [ ! -d $(LIB) ] ; then mkdir $(LIB) ; fi
-
-
-# Installation
-
-gsminstall:
- -if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then \
- $(MAKE) $(GSM_INSTALL_TARGETS) ; \
- fi
-
-toastinstall:
- -if [ x"$(TOAST_INSTALL_ROOT)" != x ]; then \
- $(MAKE) $(TOAST_INSTALL_TARGETS); \
- fi
-
-gsmuninstall:
- -if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then \
- rm $(RMFLAGS) $(GSM_INSTALL_TARGETS) ; \
- fi
-
-toastuninstall:
- -if [ x"$(TOAST_INSTALL_ROOT)" != x ] ; then \
- rm $(RMFLAGS) $(TOAST_INSTALL_TARGETS); \
- fi
-
-$(TOAST_INSTALL_BIN)/toast: $(TOAST)
- -rm $@
- cp $(TOAST) $@
- chmod 755 $@
-
-$(TOAST_INSTALL_BIN)/untoast: $(TOAST_INSTALL_BIN)/toast
- -rm $@
- ln $? $@
-
-$(TOAST_INSTALL_BIN)/tcat: $(TOAST_INSTALL_BIN)/toast
- -rm $@
- ln $? $@
-
-$(TOAST_INSTALL_MAN)/toast.1: $(MAN)/toast.1
- -rm $@
- cp $? $@
- chmod 444 $@
-
-$(GSM_INSTALL_MAN)/gsm.3: $(MAN)/gsm.3
- -rm $@
- cp $? $@
- chmod 444 $@
-
-$(GSM_INSTALL_MAN)/gsm_option.3: $(MAN)/gsm_option.3
- -rm $@
- cp $? $@
- chmod 444 $@
-
-$(GSM_INSTALL_MAN)/gsm_explode.3: $(MAN)/gsm_explode.3
- -rm $@
- cp $? $@
- chmod 444 $@
-
-$(GSM_INSTALL_MAN)/gsm_print.3: $(MAN)/gsm_print.3
- -rm $@
- cp $? $@
- chmod 444 $@
-
-$(GSM_INSTALL_INC)/gsm.h: $(INC)/gsm.h
- -rm $@
- cp $? $@
- chmod 444 $@
-
-$(GSM_INSTALL_LIB)/libgsm.a: $(LIBGSM)
- -rm $@
- cp $? $@
- chmod 444 $@
-
-
-# Distribution
-
-dist: gsm-1.0.tar.Z
- @echo dist: Done.
-
-gsm-1.0.tar.Z: $(STUFF) $(SOURCES) $(HEADERS) $(MANUALS)
- ( cd $(ROOT)/..; \
- tar cvf - `cat $(ROOT)/gsm-1.0/MANIFEST \
- | sed '/^#/d'` \
- ) | $(COMPRESS) $(COMPRESSFLAGS) > $(ROOT)/gsm-1.0.tar.Z
-
-# Clean
-
-uninstall: toastuninstall gsmuninstall
- @-echo uninstall: Done.
-
-semi-clean:
- -rm $(RMFLAGS) */*.o \
- $(TST)/lin2cod $(TST)/lin2txt \
- $(TST)/cod2lin $(TST)/cod2txt \
- $(TST)/gsm2cod \
- $(TST)/*.*.*
- -$(FIND) . \( -name core -o -name foo \) \
- -print | xargs rm $(RMFLAGS)
-
-clean: semi-clean
- -rm $(RMFLAGS) $(LIBGSM) $(ADDTST)/add \
- $(TOAST) $(TCAT) $(UNTOAST) \
- $(ROOT)/gsm-1.0.tar.Z
- rm -rf lib
- rm -f .*.d
-
-# Two tools that helped me generate gsm_encode.c and gsm_decode.c,
-# but aren't generally needed to port this.
-
-$(TLS)/sweet: $(TLS)/sweet.o $(TLS)/taste.o
- $(LD) $(LFLAGS) -o $(TLS)/sweet \
- $(TLS)/sweet.o $(TLS)/taste.o $(LDLIB)
-
-$(TLS)/bitter: $(TLS)/bitter.o $(TLS)/taste.o
- $(LD) $(LFLAGS) -o $(TLS)/bitter \
- $(TLS)/bitter.o $(TLS)/taste.o $(LDLIB)
-
-# A version of the same family that Jeff Chilton used to implement
-# the WAV #49 GSM format.
-
-$(TLS)/ginger: $(TLS)/ginger.o $(TLS)/taste.o
- $(LD) $(LFLAGS) -o $(TLS)/ginger \
- $(TLS)/ginger.o $(TLS)/taste.o $(LDLIB)
-
-$(TLS)/sour: $(TLS)/sour.o $(TLS)/taste.o
- $(LD) $(LFLAGS) -o $(TLS)/sour \
- $(TLS)/sour.o $(TLS)/taste.o $(LDLIB)
-
-# Run $(ADDTST)/add < $(ADDTST)/add_test.dta to make sure the
-# basic arithmetic functions work as intended.
-
-$(ADDTST)/add: $(ADDTST)/add_test.o
- $(LD) $(LFLAGS) -o $(ADDTST)/add $(ADDTST)/add_test.o $(LDLIB)
-
-
-# Various conversion programs between linear, text, .gsm and the code
-# format used by the tests we ran (.cod). We paid for the test data,
-# so I guess we can't just provide them with this package. Still,
-# if you happen to have them lying around, here's the code.
-#
-# You can use gsm2cod | cod2txt independently to look at what's
-# coded inside the compressed frames, although this shouldn't be
-# hard to roll on your own using the gsm_print() function from
-# the API.
-
-
-$(TST)/test-result: $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/run
- ( cd $(TST); ./run )
-
-$(TST)/lin2txt: $(TST)/lin2txt.o $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TST)/lin2txt \
- $(TST)/lin2txt.o $(LIBGSM) $(LDLIB)
-
-$(TST)/lin2cod: $(TST)/lin2cod.o $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TST)/lin2cod \
- $(TST)/lin2cod.o $(LIBGSM) $(LDLIB)
-
-$(TST)/gsm2cod: $(TST)/gsm2cod.o $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TST)/gsm2cod \
- $(TST)/gsm2cod.o $(LIBGSM) $(LDLIB)
-
-$(TST)/cod2txt: $(TST)/cod2txt.o $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TST)/cod2txt \
- $(TST)/cod2txt.o $(LIBGSM) $(LDLIB)
-
-$(TST)/cod2lin: $(TST)/cod2lin.o $(LIBGSM)
- $(LD) $(LFLAGS) -o $(TST)/cod2lin \
- $(TST)/cod2lin.o $(LIBGSM) $(LDLIB)
diff --git a/1.4/codecs/gsm/README b/1.4/codecs/gsm/README
deleted file mode 100644
index cb6af85cf..000000000
--- a/1.4/codecs/gsm/README
+++ /dev/null
@@ -1,37 +0,0 @@
-
-GSM 06.10 13 kbit/s RPE/LTP speech compression available
---------------------------------------------------------
-
-The Communications and Operating Systems Research Group (KBS) at the
-Technische Universitaet Berlin is currently working on a set of
-UNIX-based tools for computer-mediated telecooperation that will be
-made freely available.
-
-As part of this effort we are publishing an implementation of the
-European GSM 06.10 provisional standard for full-rate speech
-transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
-excitation/long term prediction) coding at 13 kbit/s.
-
-GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling
-rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility
-with typical UNIX applications, our implementation turns frames of 160
-16-bit linear samples into 33-byte frames (1650 Bytes/s).
-The quality of the algorithm is good enough for reliable speaker
-recognition; even music often survives transcoding in recognizable
-form (given the bandwidth limitations of 8 kHz sampling rate).
-
-The interfaces offered are a front end modelled after compress(1), and
-a library API. Compression and decompression run faster than realtime
-on most SPARCstations. The implementation has been verified against the
-ETSI standard test patterns.
-
-Jutta Degener (jutta@cs.tu-berlin.de)
-Carsten Bormann (cabo@cs.tu-berlin.de)
-
-Communications and Operating Systems Research Group, TU Berlin
-Fax: +49.30.31425156, Phone: +49.30.31424315
-
---
-Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
-Universitaet Berlin. See the accompanying file "COPYRIGHT" for
-details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
diff --git a/1.4/codecs/gsm/inc/config.h b/1.4/codecs/gsm/inc/config.h
deleted file mode 100644
index e0b0632be..000000000
--- a/1.4/codecs/gsm/inc/config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/*$Header$*/
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#if 0
-efine SIGHANDLER_T int /* signal handlers are void */
-efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */
-#endif
-
-#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
-#if 0
-efine HAS_LIMITS_H 1 /* /usr/include/limits.h */
-#endif
-#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
-#if 0
-efine HAS_ERRNO_DECL 1 /* errno.h declares errno */
-#endif
-
-#define HAS_FSTAT 1 /* fstat syscall */
-#define HAS_FCHMOD 1 /* fchmod syscall */
-#define HAS_CHMOD 1 /* chmod syscall */
-#define HAS_FCHOWN 1 /* fchown syscall */
-#define HAS_CHOWN 1 /* chown syscall */
-#if 0
-efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */
-#endif
-
-#define HAS_STRING_H 1 /* /usr/include/string.h */
-#if 0
-efine HAS_STRINGS_H 1 /* /usr/include/strings.h */
-#endif
-
-#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
-#define HAS_UTIME 1 /* POSIX utime(path, times) */
-#if 0
-efine HAS_UTIMES 1 /* use utimes() syscall instead */
-#endif
-#define HAS_UTIME_H 1 /* UTIME header file */
-#if 0
-efine HAS_UTIMBUF 1 /* struct utimbuf */
-efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */
-#endif
-
-#endif /* CONFIG_H */
diff --git a/1.4/codecs/gsm/inc/gsm.h b/1.4/codecs/gsm/inc/gsm.h
deleted file mode 100644
index 81065e512..000000000
--- a/1.4/codecs/gsm/inc/gsm.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/*$Header$*/
-
-#ifndef GSM_H
-#define GSM_H
-
-#ifdef __cplusplus
-# define NeedFunctionPrototypes 1
-#endif
-
-#if __STDC__
-# define NeedFunctionPrototypes 1
-#endif
-
-#ifdef _NO_PROTO
-# undef NeedFunctionPrototypes
-#endif
-
-#ifdef NeedFunctionPrototypes
-# include <stdio.h> /* for FILE * */
-#endif
-
-#undef GSM_P
-#if NeedFunctionPrototypes
-# define GSM_P( protos ) protos
-#else
-# define GSM_P( protos ) ( /* protos */ )
-#endif
-
-/*
- * Interface
- */
-
-typedef struct gsm_state * gsm;
-typedef short gsm_signal; /* signed 16 bit */
-typedef unsigned char gsm_byte;
-typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */
-
-#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */
-
-#define GSM_PATCHLEVEL 10
-#define GSM_MINOR 0
-#define GSM_MAJOR 1
-
-#define GSM_OPT_VERBOSE 1
-#define GSM_OPT_FAST 2
-#define GSM_OPT_LTP_CUT 3
-#define GSM_OPT_WAV49 4
-#define GSM_OPT_FRAME_INDEX 5
-#define GSM_OPT_FRAME_CHAIN 6
-
-extern gsm gsm_create GSM_P((void));
-extern void gsm_destroy GSM_P((gsm));
-
-extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *));
-extern int gsm_option GSM_P((gsm, int, int *));
-
-extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *));
-extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *));
-
-extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *));
-extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *));
-
-#undef GSM_P
-
-#endif /* GSM_H */
diff --git a/1.4/codecs/gsm/inc/private.h b/1.4/codecs/gsm/inc/private.h
deleted file mode 100644
index 80ecbc59f..000000000
--- a/1.4/codecs/gsm/inc/private.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/*$Header$*/
-
-#ifndef PRIVATE_H
-#define PRIVATE_H
-
-typedef short word; /* 16 bit signed int */
-typedef long longword; /* 32 bit signed int */
-
-typedef unsigned short uword; /* unsigned word */
-typedef unsigned long ulongword; /* unsigned longword */
-
-struct gsm_state {
-
- word dp0[ 280 ];
-
- word z1; /* preprocessing.c, Offset_com. */
- longword L_z2; /* Offset_com. */
- int mp; /* Preemphasis */
-
- word u[8]; /* short_term_aly_filter.c */
- word LARpp[2][8]; /* */
- word j; /* */
-
- word ltp_cut; /* long_term.c, LTP crosscorr. */
- word nrp; /* 40 */ /* long_term.c, synthesis */
- word v[9]; /* short_term.c, synthesis */
- word msr; /* decoder.c, Postprocessing */
-
- char verbose; /* only used if !NDEBUG */
- char fast; /* only used if FAST */
-
- char wav_fmt; /* only used if WAV49 defined */
- unsigned char frame_index; /* odd/even chaining */
- unsigned char frame_chain; /* half-byte to carry forward */
-};
-
-
-#define MIN_WORD (-32767 - 1)
-#define MAX_WORD 32767
-
-#define MIN_LONGWORD (-2147483647 - 1)
-#define MAX_LONGWORD 2147483647
-
-#ifdef SASR /* flag: >> is a signed arithmetic shift right */
-#undef SASR
-#define SASR(x, by) ((x) >> (by))
-#else
-#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
-#endif /* SASR */
-
-#include "proto.h"
-
-/*
- * Prototypes from add.c
- */
-extern word gsm_mult P((word a, word b));
-extern longword gsm_L_mult P((word a, word b));
-extern word gsm_mult_r P((word a, word b));
-
-extern word gsm_div P((word num, word denum));
-
-extern word gsm_add P(( word a, word b ));
-extern longword gsm_L_add P(( longword a, longword b ));
-
-extern word gsm_sub P((word a, word b));
-extern longword gsm_L_sub P((longword a, longword b));
-
-extern word gsm_abs P((word a));
-
-extern word gsm_norm P(( longword a ));
-
-extern longword gsm_L_asl P((longword a, int n));
-extern word gsm_asl P((word a, int n));
-
-extern longword gsm_L_asr P((longword a, int n));
-extern word gsm_asr P((word a, int n));
-
-/*
- * Inlined functions from add.h
- */
-
-/*
- * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \
- * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))
- */
-#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \
- (SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))
-
-# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \
- (SASR( ((longword)(a) * (longword)(b)), 15 ))
-
-# define GSM_L_MULT(a, b) /* word a, word b */ \
- (((longword)(a) * (longword)(b)) << 1)
-
-#if defined(__GNUC__) && defined(__i386__)
-
-static __inline__ int GSM_L_ADD(int a, int b)
-{
- __asm__ __volatile__(
-
- "addl %2,%0; jno 0f; movl $0x7fffffff,%0; adcl $0,%0; 0:"
- : "=&r" (a)
- : "0" (a), "ir" (b)
- : "cc"
- );
- return(a);
-}
-
-static __inline__ short GSM_ADD(short a, short b)
-{
- __asm__ __volatile__(
- "addw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
- : "=&r" (a)
- : "0" (a), "ir" (b)
- : "cc"
- );
- return(a);
-}
-
-static __inline__ short GSM_SUB(short a, short b)
-{
- __asm__ __volatile__(
- "subw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
- : "=&r" (a)
- : "0" (a), "ir" (b)
- : "cc"
- );
- return(a);
-}
-
-#else
-
-#ifdef WIN32
-#define inline __inline
-#define __inline__ __inline
-#endif
-
-# define GSM_L_ADD(a, b) \
- ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \
- : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
- >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \
- : ((b) <= 0 ? (a) + (b) \
- : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
- ? MAX_LONGWORD : utmp))
-
-static inline word GSM_ADD(longword a, longword b)
-{
- register longword ltmp;
- ltmp = a + b;
- return (word)((ulongword) (ltmp - MIN_WORD) > MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp);
-};
-
-static inline word GSM_SUB(longword a, longword b)
-{
- register longword ltmp;
- ltmp = a - b;
- return (word)(ltmp >= MAX_WORD ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp);
-};
-
-#endif
-
-# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
-
-/* Use these if necessary:
-
-# define GSM_MULT_R(a, b) gsm_mult_r(a, b)
-# define GSM_MULT(a, b) gsm_mult(a, b)
-# define GSM_L_MULT(a, b) gsm_L_mult(a, b)
-
-# define GSM_L_ADD(a, b) gsm_L_add(a, b)
-# define GSM_ADD(a, b) gsm_add(a, b)
-# define GSM_SUB(a, b) gsm_sub(a, b)
-
-# define GSM_ABS(a) gsm_abs(a)
-
-*/
-
-/*
- * More prototypes from implementations..
- */
-extern void Gsm_Coder P((
- struct gsm_state * S,
- word * s, /* [0..159] samples IN */
- word * LARc, /* [0..7] LAR coefficients OUT */
- word * Nc, /* [0..3] LTP lag OUT */
- word * bc, /* [0..3] coded LTP gain OUT */
- word * Mc, /* [0..3] RPE grid selection OUT */
- word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
- word * xMc /* [13*4] normalized RPE samples OUT */));
-
-extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */
- struct gsm_state * S,
- word * d, /* [0..39] residual signal IN */
- word * dp, /* [-120..-1] d' IN */
- word * e, /* [0..40] OUT */
- word * dpp, /* [0..40] OUT */
- word * Nc, /* correlation lag OUT */
- word * bc /* gain factor OUT */));
-
-extern void Gsm_LPC_Analysis P((
- struct gsm_state * S,
- word * s, /* 0..159 signals IN/OUT */
- word * LARc)); /* 0..7 LARc's OUT */
-
-extern void Gsm_Preprocess P((
- struct gsm_state * S,
- word * s, word * so));
-
-extern void Gsm_Encoding P((
- struct gsm_state * S,
- word * e,
- word * ep,
- word * xmaxc,
- word * Mc,
- word * xMc));
-
-extern void Gsm_Short_Term_Analysis_Filter P((
- struct gsm_state * S,
- word * LARc, /* coded log area ratio [0..7] IN */
- word * d /* st res. signal [0..159] IN/OUT */));
-
-extern void Gsm_Decoder P((
- struct gsm_state * S,
- word * LARcr, /* [0..7] IN */
- word * Ncr, /* [0..3] IN */
- word * bcr, /* [0..3] IN */
- word * Mcr, /* [0..3] IN */
- word * xmaxcr, /* [0..3] IN */
- word * xMcr, /* [0..13*4] IN */
- word * s)); /* [0..159] OUT */
-
-extern void Gsm_Decoding P((
- struct gsm_state * S,
- word xmaxcr,
- word Mcr,
- word * xMcr, /* [0..12] IN */
- word * erp)); /* [0..39] OUT */
-
-extern void Gsm_Long_Term_Synthesis_Filtering P((
- struct gsm_state* S,
- word Ncr,
- word bcr,
- word * erp, /* [0..39] IN */
- word * drp)); /* [-120..-1] IN, [0..40] OUT */
-
-void Gsm_RPE_Decoding P((
- struct gsm_state *S,
- word xmaxcr,
- word Mcr,
- word * xMcr, /* [0..12], 3 bits IN */
- word * erp)); /* [0..39] OUT */
-
-void Gsm_RPE_Encoding P((
- struct gsm_state * S,
- word * e, /* -5..-1][0..39][40..44 IN/OUT */
- word * xmaxc, /* OUT */
- word * Mc, /* OUT */
- word * xMc)); /* [0..12] OUT */
-
-extern void Gsm_Short_Term_Synthesis_Filter P((
- struct gsm_state * S,
- word * LARcr, /* log area ratios [0..7] IN */
- word * drp, /* received d [0...39] IN */
- word * s)); /* signal s [0..159] OUT */
-
-extern void Gsm_Update_of_reconstructed_short_time_residual_signal P((
- word * dpp, /* [0...39] IN */
- word * ep, /* [0...39] IN */
- word * dp)); /* [-120...-1] IN/OUT */
-
-/*
- * Tables from table.c
- */
-#ifndef GSM_TABLE_C
-
-extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];
-extern word gsm_INVA[8];
-extern word gsm_DLB[4], gsm_QLB[4];
-extern word gsm_H[11];
-extern word gsm_NRFAC[8];
-extern word gsm_FAC[8];
-
-#endif /* GSM_TABLE_C */
-
-/*
- * Debugging
- */
-#ifdef NDEBUG
-
-# define gsm_debug_words(a, b, c, d) /* nil */
-# define gsm_debug_longwords(a, b, c, d) /* nil */
-# define gsm_debug_word(a, b) /* nil */
-# define gsm_debug_longword(a, b) /* nil */
-
-#else /* !NDEBUG => DEBUG */
-
- extern void gsm_debug_words P((char * name, int, int, word *));
- extern void gsm_debug_longwords P((char * name, int, int, longword *));
- extern void gsm_debug_longword P((char * name, longword));
- extern void gsm_debug_word P((char * name, word));
-
-#endif /* !NDEBUG */
-
-#include "unproto.h"
-
-#endif /* PRIVATE_H */
diff --git a/1.4/codecs/gsm/inc/proto.h b/1.4/codecs/gsm/inc/proto.h
deleted file mode 100644
index 87cf05e8a..000000000
--- a/1.4/codecs/gsm/inc/proto.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/*$Header$*/
-
-#ifndef PROTO_H
-#define PROTO_H
-
-#if __cplusplus
-# define NeedFunctionPrototypes 1
-#endif
-
-#if __STDC__
-# define NeedFunctionPrototypes 1
-#endif
-
-#ifdef _NO_PROTO
-# undef NeedFunctionPrototypes
-#endif
-
-#undef P /* gnu stdio.h actually defines this... */
-#undef P0
-#undef P1
-#undef P2
-#undef P3
-#undef P4
-#undef P5
-#undef P6
-#undef P7
-#undef P8
-
-#if NeedFunctionPrototypes
-
-# define P( protos ) protos
-
-# define P0() (void)
-# define P1(x, a) (a)
-# define P2(x, a, b) (a, b)
-# define P3(x, a, b, c) (a, b, c)
-# define P4(x, a, b, c, d) (a, b, c, d)
-# define P5(x, a, b, c, d, e) (a, b, c, d, e)
-# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f)
-# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g)
-# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h)
-
-#else /* !NeedFunctionPrototypes */
-
-# define P( protos ) ( /* protos */ )
-
-# define P0() ()
-# define P1(x, a) x a;
-# define P2(x, a, b) x a; b;
-# define P3(x, a, b, c) x a; b; c;
-# define P4(x, a, b, c, d) x a; b; c; d;
-# define P5(x, a, b, c, d, e) x a; b; c; d; e;
-# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f;
-# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g;
-# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h;
-
-#endif /* !NeedFunctionPrototypes */
-
-#endif /* PROTO_H */
diff --git a/1.4/codecs/gsm/inc/unproto.h b/1.4/codecs/gsm/inc/unproto.h
deleted file mode 100644
index ccd565109..000000000
--- a/1.4/codecs/gsm/inc/unproto.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/*$Header$*/
-
-#ifdef PROTO_H /* sic */
-#undef PROTO_H
-
-#undef P
-#undef P0
-#undef P1
-#undef P2
-#undef P3
-#undef P4
-#undef P5
-#undef P6
-#undef P7
-#undef P8
-
-#endif /* PROTO_H */
diff --git a/1.4/codecs/gsm/libgsm.vcproj b/1.4/codecs/gsm/libgsm.vcproj
deleted file mode 100644
index f94b209d5..000000000
--- a/1.4/codecs/gsm/libgsm.vcproj
+++ /dev/null
@@ -1,253 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="libgsm"
- ProjectGUID="{8FD2E297-4096-47E5-9258-C48FF1841523}"
- RootNamespace="libgsm"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="inc"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="inc"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath=".\src\add.c"
- >
- </File>
- <File
- RelativePath=".\src\code.c"
- >
- </File>
- <File
- RelativePath=".\src\debug.c"
- >
- </File>
- <File
- RelativePath=".\src\decode.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_create.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_decode.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_destroy.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_encode.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_explode.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_implode.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_option.c"
- >
- </File>
- <File
- RelativePath=".\src\gsm_print.c"
- >
- </File>
- <File
- RelativePath=".\src\long_term.c"
- >
- </File>
- <File
- RelativePath=".\src\lpc.c"
- >
- </File>
- <File
- RelativePath=".\src\preprocess.c"
- >
- </File>
- <File
- RelativePath=".\src\rpe.c"
- >
- </File>
- <File
- RelativePath=".\src\short_term.c"
- >
- </File>
- <File
- RelativePath=".\src\table.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\inc\config.h"
- >
- </File>
- <File
- RelativePath=".\inc\gsm.h"
- >
- </File>
- <File
- RelativePath=".\inc\private.h"
- >
- </File>
- <File
- RelativePath=".\inc\proto.h"
- >
- </File>
- <File
- RelativePath=".\inc\unproto.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/1.4/codecs/gsm/src/add.c b/1.4/codecs/gsm/src/add.c
deleted file mode 100644
index f23d27f16..000000000
--- a/1.4/codecs/gsm/src/add.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-/*
- * See private.h for the more commonly used macro versions.
- */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "private.h"
-#include "gsm.h"
-#include "proto.h"
-
-#define saturate(x) \
- ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
-
-word gsm_add P2((a,b), word a, word b)
-{
- longword sum = (longword)a + (longword)b;
- return (word)saturate(sum);
-}
-
-word gsm_sub P2((a,b), word a, word b)
-{
- longword diff = (longword)a - (longword)b;
- return (word)saturate(diff);
-}
-
-word gsm_mult P2((a,b), word a, word b)
-{
- if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
- else return (word)SASR( (longword)a * (longword)b, 15 );
-}
-
-word gsm_mult_r P2((a,b), word a, word b)
-{
- if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
- else {
- longword prod = (longword)a * (longword)b + 16384;
- prod >>= 15;
- return (word)(prod & 0xFFFF);
- }
-}
-
-word gsm_abs P1((a), word a)
-{
- return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
-}
-
-longword gsm_L_mult P2((a,b),word a, word b)
-{
- assert( a != MIN_WORD || b != MIN_WORD );
- return ((longword)a * (longword)b) << 1;
-}
-
-longword gsm_L_add P2((a,b), longword a, longword b)
-{
- if (a < 0) {
- if (b >= 0) return a + b;
- else {
- ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
- return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
- }
- }
- else if (b <= 0) return a + b;
- else {
- ulongword A = (ulongword)a + (ulongword)b;
- return A > MAX_LONGWORD ? MAX_LONGWORD : A;
- }
-}
-
-longword gsm_L_sub P2((a,b), longword a, longword b)
-{
- if (a >= 0) {
- if (b >= 0) return a - b;
- else {
- /* a>=0, b<0 */
-
- ulongword A = (ulongword)a + -(b + 1);
- return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
- }
- }
- else if (b <= 0) return a - b;
- else {
- /* a<0, b>0 */
-
- ulongword A = (ulongword)-(a + 1) + b;
- return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
- }
-}
-
-static unsigned char const bitoff[ 256 ] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-word gsm_norm P1((a), longword a )
-/*
- * the number of left shifts needed to normalize the 32 bit
- * variable L_var1 for positive values on the interval
- *
- * with minimum of
- * minimum of 1073741824 (01000000000000000000000000000000) and
- * maximum of 2147483647 (01111111111111111111111111111111)
- *
- *
- * and for negative values on the interval with
- * minimum of -2147483648 (-10000000000000000000000000000000) and
- * maximum of -1073741824 ( -1000000000000000000000000000000).
- *
- * in order to normalize the result, the following
- * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
- *
- * (That's 'ffs', only from the left, not the right..)
- */
-{
- assert(a != 0);
-
- if (a < 0) {
- if (a <= -1073741824) return 0;
- a = ~a;
- }
-
- return a & 0xffff0000
- ? ( a & 0xff000000
- ? -1 + bitoff[ 0xFF & (a >> 24) ]
- : 7 + bitoff[ 0xFF & (a >> 16) ] )
- : ( a & 0xff00
- ? 15 + bitoff[ 0xFF & (a >> 8) ]
- : 23 + bitoff[ 0xFF & a ] );
-}
-
-longword gsm_L_asl P2((a,n), longword a, int n)
-{
- if (n >= 32) return 0;
- if (n <= -32) return -(a < 0);
- if (n < 0) return gsm_L_asr(a, -n);
- return a << n;
-}
-
-word gsm_asl P2((a,n), word a, int n)
-{
- if (n >= 16) return 0;
- if (n <= -16) return -(a < 0);
- if (n < 0) return gsm_asr(a, -n);
- return a << n;
-}
-
-longword gsm_L_asr P2((a,n), longword a, int n)
-{
- if (n >= 32) return -(a < 0);
- if (n <= -32) return 0;
- if (n < 0) return a << -n;
-
-# ifdef SASR
- return a >> n;
-# else
- if (a >= 0) return a >> n;
- else return -(longword)( -(ulongword)a >> n );
-# endif
-}
-
-word gsm_asr P2((a,n), word a, int n)
-{
- if (n >= 16) return -(a < 0);
- if (n <= -16) return 0;
- if (n < 0) return a << -n;
-
-# ifdef SASR
- return a >> n;
-# else
- if (a >= 0) return a >> n;
- else return -(word)( -(uword)a >> n );
-# endif
-}
-
-/*
- * (From p. 46, end of section 4.2.5)
- *
- * NOTE: The following lines gives [sic] one correct implementation
- * of the div(num, denum) arithmetic operation. Compute div
- * which is the integer division of num by denum: with denum
- * >= num > 0
- */
-
-word gsm_div P2((num,denum), word num, word denum)
-{
- longword L_num = num;
- longword L_denum = denum;
- word div = 0;
- int k = 15;
-
- /* The parameter num sometimes becomes zero.
- * Although this is explicitly guarded against in 4.2.5,
- * we assume that the result should then be zero as well.
- */
-
- /* assert(num != 0); */
-
- assert(num >= 0 && denum >= num);
- if (num == 0)
- return 0;
-
- while (k--) {
- div <<= 1;
- L_num <<= 1;
-
- if (L_num >= L_denum) {
- L_num -= L_denum;
- div++;
- }
- }
-
- return div;
-}
diff --git a/1.4/codecs/gsm/src/code.c b/1.4/codecs/gsm/src/code.c
deleted file mode 100644
index 4d195dfbd..000000000
--- a/1.4/codecs/gsm/src/code.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "config.h"
-
-#ifdef HAS_STRING_H
-#include <string.h>
-#else
-# include "proto.h"
- extern char * memcpy P((char *, char *, int));
-#endif
-
-#include "private.h"
-#include "gsm.h"
-#include "proto.h"
-
-/*
- * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER
- */
-
-void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),
-
- struct gsm_state * S,
-
- word * s, /* [0..159] samples IN */
-
-/*
- * The RPE-LTD coder works on a frame by frame basis. The length of
- * the frame is equal to 160 samples. Some computations are done
- * once per frame to produce at the output of the coder the
- * LARc[1..8] parameters which are the coded LAR coefficients and
- * also to realize the inverse filtering operation for the entire
- * frame (160 samples of signal d[0..159]). These parts produce at
- * the output of the coder:
- */
-
- word * LARc, /* [0..7] LAR coefficients OUT */
-
-/*
- * Procedure 4.2.11 to 4.2.18 are to be executed four times per
- * frame. That means once for each sub-segment RPE-LTP analysis of
- * 40 samples. These parts produce at the output of the coder:
- */
-
- word * Nc, /* [0..3] LTP lag OUT */
- word * bc, /* [0..3] coded LTP gain OUT */
- word * Mc, /* [0..3] RPE grid selection OUT */
- word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
- word * xMc /* [13*4] normalized RPE samples OUT */
-)
-{
- int k;
- word * dp = S->dp0 + 120; /* [ -120...-1 ] */
- word * dpp = dp; /* [ 0...39 ] */
-
- static word e[50];
-
- word so[160];
-
- Gsm_Preprocess (S, s, so);
- Gsm_LPC_Analysis (S, so, LARc);
- Gsm_Short_Term_Analysis_Filter (S, LARc, so);
-
- for (k = 0; k <= 3; k++, xMc += 13) {
-
- Gsm_Long_Term_Predictor ( S,
- so+k*40, /* d [0..39] IN */
- dp, /* dp [-120..-1] IN */
- e + 5, /* e [0..39] OUT */
- dpp, /* dpp [0..39] OUT */
- Nc++,
- bc++);
-
- Gsm_RPE_Encoding ( S,
- e + 5, /* e ][0..39][ IN/OUT */
- xmaxc++, Mc++, xMc );
- /*
- * Gsm_Update_of_reconstructed_short_time_residual_signal
- * ( dpp, e + 5, dp );
- */
-
- { register int i;
- for (i = 0; i <= 39; i++)
- dp[ i ] = GSM_ADD( e[5 + i], dpp[i] );
- }
- dp += 40;
- dpp += 40;
-
- }
- (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
- 120 * sizeof(*S->dp0) );
-}
diff --git a/1.4/codecs/gsm/src/debug.c b/1.4/codecs/gsm/src/debug.c
deleted file mode 100644
index 22dfa8082..000000000
--- a/1.4/codecs/gsm/src/debug.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "private.h"
-
-#ifndef NDEBUG
-
-/* If NDEBUG _is_ defined and no debugging should be performed,
- * calls to functions in this module are #defined to nothing
- * in private.h.
- */
-
-#include <stdio.h>
-#include "proto.h"
-
-void gsm_debug_words P4( (name, from, to, ptr),
- char * name,
- int from,
- int to,
- word * ptr)
-{
- int nprinted = 0;
-
- fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
- while (from <= to) {
- fprintf(stderr, "%d ", ptr[ from ] );
- from++;
- if (nprinted++ >= 7) {
- nprinted = 0;
- if (from < to) putc('\n', stderr);
- }
- }
- putc('\n', stderr);
-}
-
-void gsm_debug_longwords P4( (name, from, to, ptr),
- char * name,
- int from,
- int to,
- longword * ptr)
-{
- int nprinted = 0;
-
- fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
- while (from <= to) {
-
- fprintf(stderr, "%d ", ptr[ from ] );
- from++;
- if (nprinted++ >= 7) {
- nprinted = 0;
- if (from < to) putc('\n', stderr);
- }
- }
- putc('\n', stderr);
-}
-
-void gsm_debug_longword P2( (name, value),
- char * name,
- longword value )
-{
- fprintf(stderr, "%s: %d\n", name, (long)value );
-}
-
-void gsm_debug_word P2( (name, value),
- char * name,
- word value )
-{
- fprintf(stderr, "%s: %d\n", name, (long)value);
-}
-
-#endif
diff --git a/1.4/codecs/gsm/src/decode.c b/1.4/codecs/gsm/src/decode.c
deleted file mode 100644
index 093ac64df..000000000
--- a/1.4/codecs/gsm/src/decode.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-
-#include "private.h"
-#include "gsm.h"
-#include "proto.h"
-
-/*
- * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
- */
-
-static void Postprocessing P2((S,s),
- struct gsm_state * S,
- register word * s)
-{
- register int k;
- register word msr = S->msr;
- register word tmp;
-
- for (k = 160; k--; s++) {
- tmp = (word)GSM_MULT_R( msr, 28180 );
- msr = GSM_ADD(*s, tmp); /* Deemphasis */
- *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */
- }
- S->msr = msr;
-}
-
-void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),
- struct gsm_state * S,
-
- word * LARcr, /* [0..7] IN */
-
- word * Ncr, /* [0..3] IN */
- word * bcr, /* [0..3] IN */
- word * Mcr, /* [0..3] IN */
- word * xmaxcr, /* [0..3] IN */
- word * xMcr, /* [0..13*4] IN */
-
- word * s) /* [0..159] OUT */
-{
- int j, k;
- word erp[40], wt[160];
- word * drp = S->dp0 + 120;
-
- for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
-
- Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );
- Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
-
- for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ];
- }
-
- Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
- Postprocessing(S, s);
-}
diff --git a/1.4/codecs/gsm/src/gsm_create.c b/1.4/codecs/gsm/src/gsm_create.c
deleted file mode 100644
index a59aa2f2a..000000000
--- a/1.4/codecs/gsm/src/gsm_create.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-static char const ident[] = "$Header$";
-
-#include "config.h"
-
-#ifdef HAS_STRING_H
-#include <string.h>
-#else
-# include "proto.h"
- extern char * memset P((char *, int, int));
-#endif
-
-#ifdef HAS_STDLIB_H
-# include <stdlib.h>
-#else
-# ifdef HAS_MALLOC_H
-# include <malloc.h>
-# else
- extern char * malloc();
-# endif
-#endif
-
-#include <stdio.h>
-
-#include "gsm.h"
-#include "private.h"
-#include "proto.h"
-
-gsm gsm_create P0()
-{
- gsm r;
-
- r = (gsm)malloc(sizeof(struct gsm_state));
- if (!r) return r;
-
- memset((char *)r, 0, sizeof(*r));
- r->nrp = 40;
-
- return r;
-}
diff --git a/1.4/codecs/gsm/src/gsm_decode.c b/1.4/codecs/gsm/src/gsm_decode.c
deleted file mode 100644
index 7318ba2d4..000000000
--- a/1.4/codecs/gsm/src/gsm_decode.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
-{
- word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
-
-#ifdef WAV49
- if (s->wav_fmt) {
-
- uword sr = 0;
-
- s->frame_index = !s->frame_index;
- if (s->frame_index) {
-
- sr = *c++;
- LARc[0] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 2;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 4;
- LARc[2] = sr & 0x1f; sr >>= 5;
- LARc[3] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 2;
- LARc[4] = sr & 0xf; sr >>= 4;
- LARc[5] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2; /* 5 */
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[0] = sr & 0x7f; sr >>= 7;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
- xmc[0] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[1] = sr & 0x7; sr >>= 3;
- xmc[2] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- xmc[5] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 10 */
- xmc[6] = sr & 0x7; sr >>= 3;
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[9] = sr & 0x7; sr >>= 3;
- xmc[10] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[1] = sr & 0x7f; sr >>= 7;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
- xmc[13] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 15 */
- xmc[14] = sr & 0x7; sr >>= 3;
- xmc[15] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- xmc[18] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[19] = sr & 0x7; sr >>= 3;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[22] = sr & 0x7; sr >>= 3;
- xmc[23] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4; /* 20 */
- Nc[2] = sr & 0x7f; sr >>= 7;
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
- xmc[26] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[27] = sr & 0x7; sr >>= 3;
- xmc[28] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- xmc[31] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[32] = sr & 0x7; sr >>= 3;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 25 */
- xmc[35] = sr & 0x7; sr >>= 3;
- xmc[36] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[3] = sr & 0x7f; sr >>= 7;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
- xmc[39] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[40] = sr & 0x7; sr >>= 3;
- xmc[41] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 30 */
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- xmc[44] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[45] = sr & 0x7; sr >>= 3;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[48] = sr & 0x7; sr >>= 3;
- xmc[49] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
-
- s->frame_chain = sr & 0xf;
- }
- else {
- sr = s->frame_chain;
- sr |= (uword)*c++ << 4; /* 1 */
- LARc[0] = sr & 0x3f; sr >>= 6;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr = *c++;
- LARc[2] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 3;
- LARc[3] = sr & 0x1f; sr >>= 5;
- LARc[4] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2;
- LARc[5] = sr & 0xf; sr >>= 4;
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 5 */
- Nc[0] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
- xmc[0] = sr & 0x7; sr >>= 3;
- xmc[1] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[2] = sr & 0x7; sr >>= 3;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[5] = sr & 0x7; sr >>= 3;
- xmc[6] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 10 */
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- xmc[9] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[10] = sr & 0x7; sr >>= 3;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[1] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
- xmc[13] = sr & 0x7; sr >>= 3;
- xmc[14] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 15 */
- xmc[15] = sr & 0x7; sr >>= 3;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[18] = sr & 0x7; sr >>= 3;
- xmc[19] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- xmc[22] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[23] = sr & 0x7; sr >>= 3;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[2] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1; /* 20 */
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
- xmc[26] = sr & 0x7; sr >>= 3;
- xmc[27] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[28] = sr & 0x7; sr >>= 3;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[31] = sr & 0x7; sr >>= 3;
- xmc[32] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- xmc[35] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 25 */
- xmc[36] = sr & 0x7; sr >>= 3;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[3] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
- xmc[39] = sr & 0x7; sr >>= 3;
- xmc[40] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[41] = sr & 0x7; sr >>= 3;
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 30 */
- xmc[44] = sr & 0x7; sr >>= 3;
- xmc[45] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- xmc[48] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[49] = sr & 0x7; sr >>= 3;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
- }
- }
- else
-#endif
- {
- /* GSM_MAGIC = (*c >> 4) & 0xF; */
-
- if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
-
- LARc[0] = (*c++ & 0xF) << 2; /* 1 */
- LARc[0] |= (*c >> 6) & 0x3;
- LARc[1] = *c++ & 0x3F;
- LARc[2] = (*c >> 3) & 0x1F;
- LARc[3] = (*c++ & 0x7) << 2;
- LARc[3] |= (*c >> 6) & 0x3;
- LARc[4] = (*c >> 2) & 0xF;
- LARc[5] = (*c++ & 0x3) << 2;
- LARc[5] |= (*c >> 6) & 0x3;
- LARc[6] = (*c >> 3) & 0x7;
- LARc[7] = *c++ & 0x7;
- Nc[0] = (*c >> 1) & 0x7F;
- bc[0] = (*c++ & 0x1) << 1;
- bc[0] |= (*c >> 7) & 0x1;
- Mc[0] = (*c >> 5) & 0x3;
- xmaxc[0] = (*c++ & 0x1F) << 1;
- xmaxc[0] |= (*c >> 7) & 0x1;
- xmc[0] = (*c >> 4) & 0x7;
- xmc[1] = (*c >> 1) & 0x7;
- xmc[2] = (*c++ & 0x1) << 2;
- xmc[2] |= (*c >> 6) & 0x3;
- xmc[3] = (*c >> 3) & 0x7;
- xmc[4] = *c++ & 0x7;
- xmc[5] = (*c >> 5) & 0x7;
- xmc[6] = (*c >> 2) & 0x7;
- xmc[7] = (*c++ & 0x3) << 1; /* 10 */
- xmc[7] |= (*c >> 7) & 0x1;
- xmc[8] = (*c >> 4) & 0x7;
- xmc[9] = (*c >> 1) & 0x7;
- xmc[10] = (*c++ & 0x1) << 2;
- xmc[10] |= (*c >> 6) & 0x3;
- xmc[11] = (*c >> 3) & 0x7;
- xmc[12] = *c++ & 0x7;
- Nc[1] = (*c >> 1) & 0x7F;
- bc[1] = (*c++ & 0x1) << 1;
- bc[1] |= (*c >> 7) & 0x1;
- Mc[1] = (*c >> 5) & 0x3;
- xmaxc[1] = (*c++ & 0x1F) << 1;
- xmaxc[1] |= (*c >> 7) & 0x1;
- xmc[13] = (*c >> 4) & 0x7;
- xmc[14] = (*c >> 1) & 0x7;
- xmc[15] = (*c++ & 0x1) << 2;
- xmc[15] |= (*c >> 6) & 0x3;
- xmc[16] = (*c >> 3) & 0x7;
- xmc[17] = *c++ & 0x7;
- xmc[18] = (*c >> 5) & 0x7;
- xmc[19] = (*c >> 2) & 0x7;
- xmc[20] = (*c++ & 0x3) << 1;
- xmc[20] |= (*c >> 7) & 0x1;
- xmc[21] = (*c >> 4) & 0x7;
- xmc[22] = (*c >> 1) & 0x7;
- xmc[23] = (*c++ & 0x1) << 2;
- xmc[23] |= (*c >> 6) & 0x3;
- xmc[24] = (*c >> 3) & 0x7;
- xmc[25] = *c++ & 0x7;
- Nc[2] = (*c >> 1) & 0x7F;
- bc[2] = (*c++ & 0x1) << 1; /* 20 */
- bc[2] |= (*c >> 7) & 0x1;
- Mc[2] = (*c >> 5) & 0x3;
- xmaxc[2] = (*c++ & 0x1F) << 1;
- xmaxc[2] |= (*c >> 7) & 0x1;
- xmc[26] = (*c >> 4) & 0x7;
- xmc[27] = (*c >> 1) & 0x7;
- xmc[28] = (*c++ & 0x1) << 2;
- xmc[28] |= (*c >> 6) & 0x3;
- xmc[29] = (*c >> 3) & 0x7;
- xmc[30] = *c++ & 0x7;
- xmc[31] = (*c >> 5) & 0x7;
- xmc[32] = (*c >> 2) & 0x7;
- xmc[33] = (*c++ & 0x3) << 1;
- xmc[33] |= (*c >> 7) & 0x1;
- xmc[34] = (*c >> 4) & 0x7;
- xmc[35] = (*c >> 1) & 0x7;
- xmc[36] = (*c++ & 0x1) << 2;
- xmc[36] |= (*c >> 6) & 0x3;
- xmc[37] = (*c >> 3) & 0x7;
- xmc[38] = *c++ & 0x7;
- Nc[3] = (*c >> 1) & 0x7F;
- bc[3] = (*c++ & 0x1) << 1;
- bc[3] |= (*c >> 7) & 0x1;
- Mc[3] = (*c >> 5) & 0x3;
- xmaxc[3] = (*c++ & 0x1F) << 1;
- xmaxc[3] |= (*c >> 7) & 0x1;
- xmc[39] = (*c >> 4) & 0x7;
- xmc[40] = (*c >> 1) & 0x7;
- xmc[41] = (*c++ & 0x1) << 2;
- xmc[41] |= (*c >> 6) & 0x3;
- xmc[42] = (*c >> 3) & 0x7;
- xmc[43] = *c++ & 0x7; /* 30 */
- xmc[44] = (*c >> 5) & 0x7;
- xmc[45] = (*c >> 2) & 0x7;
- xmc[46] = (*c++ & 0x3) << 1;
- xmc[46] |= (*c >> 7) & 0x1;
- xmc[47] = (*c >> 4) & 0x7;
- xmc[48] = (*c >> 1) & 0x7;
- xmc[49] = (*c++ & 0x1) << 2;
- xmc[49] |= (*c >> 6) & 0x3;
- xmc[50] = (*c >> 3) & 0x7;
- xmc[51] = *c & 0x7; /* 33 */
- }
-
- Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
-
- return 0;
-}
diff --git a/1.4/codecs/gsm/src/gsm_destroy.c b/1.4/codecs/gsm/src/gsm_destroy.c
deleted file mode 100644
index 4807c0acd..000000000
--- a/1.4/codecs/gsm/src/gsm_destroy.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "gsm.h"
-#include "config.h"
-#include "proto.h"
-
-#ifdef HAS_STDLIB_H
-# include <stdlib.h>
-#else
-# ifdef HAS_MALLOC_H
-# include <malloc.h>
-# else
- extern void free();
-# endif
-#endif
-
-void gsm_destroy P1((S), gsm S)
-{
- if (S) free((char *)S);
-}
diff --git a/1.4/codecs/gsm/src/gsm_encode.c b/1.4/codecs/gsm/src/gsm_encode.c
deleted file mode 100644
index 62338300e..000000000
--- a/1.4/codecs/gsm/src/gsm_encode.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "private.h"
-#include "gsm.h"
-#include "proto.h"
-
-void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
-{
- word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
-
- Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
-
-
- /* variable size
-
- GSM_MAGIC 4
-
- LARc[0] 6
- LARc[1] 6
- LARc[2] 5
- LARc[3] 5
- LARc[4] 4
- LARc[5] 4
- LARc[6] 3
- LARc[7] 3
-
- Nc[0] 7
- bc[0] 2
- Mc[0] 2
- xmaxc[0] 6
- xmc[0] 3
- xmc[1] 3
- xmc[2] 3
- xmc[3] 3
- xmc[4] 3
- xmc[5] 3
- xmc[6] 3
- xmc[7] 3
- xmc[8] 3
- xmc[9] 3
- xmc[10] 3
- xmc[11] 3
- xmc[12] 3
-
- Nc[1] 7
- bc[1] 2
- Mc[1] 2
- xmaxc[1] 6
- xmc[13] 3
- xmc[14] 3
- xmc[15] 3
- xmc[16] 3
- xmc[17] 3
- xmc[18] 3
- xmc[19] 3
- xmc[20] 3
- xmc[21] 3
- xmc[22] 3
- xmc[23] 3
- xmc[24] 3
- xmc[25] 3
-
- Nc[2] 7
- bc[2] 2
- Mc[2] 2
- xmaxc[2] 6
- xmc[26] 3
- xmc[27] 3
- xmc[28] 3
- xmc[29] 3
- xmc[30] 3
- xmc[31] 3
- xmc[32] 3
- xmc[33] 3
- xmc[34] 3
- xmc[35] 3
- xmc[36] 3
- xmc[37] 3
- xmc[38] 3
-
- Nc[3] 7
- bc[3] 2
- Mc[3] 2
- xmaxc[3] 6
- xmc[39] 3
- xmc[40] 3
- xmc[41] 3
- xmc[42] 3
- xmc[43] 3
- xmc[44] 3
- xmc[45] 3
- xmc[46] 3
- xmc[47] 3
- xmc[48] 3
- xmc[49] 3
- xmc[50] 3
- xmc[51] 3
- */
-
-#ifdef WAV49
-
- if (s->wav_fmt) {
- s->frame_index = !s->frame_index;
- if (s->frame_index) {
-
- uword sr;
-
- sr = 0;
- sr = sr >> 6 | LARc[0] << 10;
- sr = sr >> 6 | LARc[1] << 10;
- *c++ = sr >> 4;
- sr = sr >> 5 | LARc[2] << 11;
- *c++ = sr >> 7;
- sr = sr >> 5 | LARc[3] << 11;
- sr = sr >> 4 | LARc[4] << 12;
- *c++ = sr >> 6;
- sr = sr >> 4 | LARc[5] << 12;
- sr = sr >> 3 | LARc[6] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | LARc[7] << 13;
- sr = sr >> 7 | Nc[0] << 9;
- *c++ = sr >> 5;
- sr = sr >> 2 | bc[0] << 14;
- sr = sr >> 2 | Mc[0] << 14;
- sr = sr >> 6 | xmaxc[0] << 10;
- *c++ = sr >> 3;
- sr = sr >> 3 | xmc[0] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[1] << 13;
- sr = sr >> 3 | xmc[2] << 13;
- sr = sr >> 3 | xmc[3] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[4] << 13;
- sr = sr >> 3 | xmc[5] << 13;
- sr = sr >> 3 | xmc[6] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[7] << 13;
- sr = sr >> 3 | xmc[8] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[9] << 13;
- sr = sr >> 3 | xmc[10] << 13;
- sr = sr >> 3 | xmc[11] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[12] << 13;
- sr = sr >> 7 | Nc[1] << 9;
- *c++ = sr >> 5;
- sr = sr >> 2 | bc[1] << 14;
- sr = sr >> 2 | Mc[1] << 14;
- sr = sr >> 6 | xmaxc[1] << 10;
- *c++ = sr >> 3;
- sr = sr >> 3 | xmc[13] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[14] << 13;
- sr = sr >> 3 | xmc[15] << 13;
- sr = sr >> 3 | xmc[16] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[17] << 13;
- sr = sr >> 3 | xmc[18] << 13;
- sr = sr >> 3 | xmc[19] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[20] << 13;
- sr = sr >> 3 | xmc[21] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[22] << 13;
- sr = sr >> 3 | xmc[23] << 13;
- sr = sr >> 3 | xmc[24] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[25] << 13;
- sr = sr >> 7 | Nc[2] << 9;
- *c++ = sr >> 5;
- sr = sr >> 2 | bc[2] << 14;
- sr = sr >> 2 | Mc[2] << 14;
- sr = sr >> 6 | xmaxc[2] << 10;
- *c++ = sr >> 3;
- sr = sr >> 3 | xmc[26] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[27] << 13;
- sr = sr >> 3 | xmc[28] << 13;
- sr = sr >> 3 | xmc[29] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[30] << 13;
- sr = sr >> 3 | xmc[31] << 13;
- sr = sr >> 3 | xmc[32] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[33] << 13;
- sr = sr >> 3 | xmc[34] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[35] << 13;
- sr = sr >> 3 | xmc[36] << 13;
- sr = sr >> 3 | xmc[37] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[38] << 13;
- sr = sr >> 7 | Nc[3] << 9;
- *c++ = sr >> 5;
- sr = sr >> 2 | bc[3] << 14;
- sr = sr >> 2 | Mc[3] << 14;
- sr = sr >> 6 | xmaxc[3] << 10;
- *c++ = sr >> 3;
- sr = sr >> 3 | xmc[39] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[40] << 13;
- sr = sr >> 3 | xmc[41] << 13;
- sr = sr >> 3 | xmc[42] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[43] << 13;
- sr = sr >> 3 | xmc[44] << 13;
- sr = sr >> 3 | xmc[45] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[46] << 13;
- sr = sr >> 3 | xmc[47] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[48] << 13;
- sr = sr >> 3 | xmc[49] << 13;
- sr = sr >> 3 | xmc[50] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[51] << 13;
- sr = sr >> 4;
- *c = sr >> 8;
- s->frame_chain = *c;
- }
- else {
- uword sr;
-
- sr = 0;
- sr = sr >> 4 | s->frame_chain << 12;
- sr = sr >> 6 | LARc[0] << 10;
- *c++ = sr >> 6;
- sr = sr >> 6 | LARc[1] << 10;
- *c++ = sr >> 8;
- sr = sr >> 5 | LARc[2] << 11;
- sr = sr >> 5 | LARc[3] << 11;
- *c++ = sr >> 6;
- sr = sr >> 4 | LARc[4] << 12;
- sr = sr >> 4 | LARc[5] << 12;
- *c++ = sr >> 6;
- sr = sr >> 3 | LARc[6] << 13;
- sr = sr >> 3 | LARc[7] << 13;
- *c++ = sr >> 8;
- sr = sr >> 7 | Nc[0] << 9;
- sr = sr >> 2 | bc[0] << 14;
- *c++ = sr >> 7;
- sr = sr >> 2 | Mc[0] << 14;
- sr = sr >> 6 | xmaxc[0] << 10;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[0] << 13;
- sr = sr >> 3 | xmc[1] << 13;
- sr = sr >> 3 | xmc[2] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[3] << 13;
- sr = sr >> 3 | xmc[4] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[5] << 13;
- sr = sr >> 3 | xmc[6] << 13;
- sr = sr >> 3 | xmc[7] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[8] << 13;
- sr = sr >> 3 | xmc[9] << 13;
- sr = sr >> 3 | xmc[10] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[11] << 13;
- sr = sr >> 3 | xmc[12] << 13;
- *c++ = sr >> 8;
- sr = sr >> 7 | Nc[1] << 9;
- sr = sr >> 2 | bc[1] << 14;
- *c++ = sr >> 7;
- sr = sr >> 2 | Mc[1] << 14;
- sr = sr >> 6 | xmaxc[1] << 10;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[13] << 13;
- sr = sr >> 3 | xmc[14] << 13;
- sr = sr >> 3 | xmc[15] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[16] << 13;
- sr = sr >> 3 | xmc[17] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[18] << 13;
- sr = sr >> 3 | xmc[19] << 13;
- sr = sr >> 3 | xmc[20] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[21] << 13;
- sr = sr >> 3 | xmc[22] << 13;
- sr = sr >> 3 | xmc[23] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[24] << 13;
- sr = sr >> 3 | xmc[25] << 13;
- *c++ = sr >> 8;
- sr = sr >> 7 | Nc[2] << 9;
- sr = sr >> 2 | bc[2] << 14;
- *c++ = sr >> 7;
- sr = sr >> 2 | Mc[2] << 14;
- sr = sr >> 6 | xmaxc[2] << 10;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[26] << 13;
- sr = sr >> 3 | xmc[27] << 13;
- sr = sr >> 3 | xmc[28] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[29] << 13;
- sr = sr >> 3 | xmc[30] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[31] << 13;
- sr = sr >> 3 | xmc[32] << 13;
- sr = sr >> 3 | xmc[33] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[34] << 13;
- sr = sr >> 3 | xmc[35] << 13;
- sr = sr >> 3 | xmc[36] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[37] << 13;
- sr = sr >> 3 | xmc[38] << 13;
- *c++ = sr >> 8;
- sr = sr >> 7 | Nc[3] << 9;
- sr = sr >> 2 | bc[3] << 14;
- *c++ = sr >> 7;
- sr = sr >> 2 | Mc[3] << 14;
- sr = sr >> 6 | xmaxc[3] << 10;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[39] << 13;
- sr = sr >> 3 | xmc[40] << 13;
- sr = sr >> 3 | xmc[41] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[42] << 13;
- sr = sr >> 3 | xmc[43] << 13;
- *c++ = sr >> 8;
- sr = sr >> 3 | xmc[44] << 13;
- sr = sr >> 3 | xmc[45] << 13;
- sr = sr >> 3 | xmc[46] << 13;
- *c++ = sr >> 7;
- sr = sr >> 3 | xmc[47] << 13;
- sr = sr >> 3 | xmc[48] << 13;
- sr = sr >> 3 | xmc[49] << 13;
- *c++ = sr >> 6;
- sr = sr >> 3 | xmc[50] << 13;
- sr = sr >> 3 | xmc[51] << 13;
- *c++ = sr >> 8;
- }
- }
-
- else
-
-#endif /* WAV49 */
- {
-
- *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
- | ((LARc[0] >> 2) & 0xF);
- *c++ = ((LARc[0] & 0x3) << 6)
- | (LARc[1] & 0x3F);
- *c++ = ((LARc[2] & 0x1F) << 3)
- | ((LARc[3] >> 2) & 0x7);
- *c++ = ((LARc[3] & 0x3) << 6)
- | ((LARc[4] & 0xF) << 2)
- | ((LARc[5] >> 2) & 0x3);
- *c++ = ((LARc[5] & 0x3) << 6)
- | ((LARc[6] & 0x7) << 3)
- | (LARc[7] & 0x7);
- *c++ = ((Nc[0] & 0x7F) << 1)
- | ((bc[0] >> 1) & 0x1);
- *c++ = ((bc[0] & 0x1) << 7)
- | ((Mc[0] & 0x3) << 5)
- | ((xmaxc[0] >> 1) & 0x1F);
- *c++ = ((xmaxc[0] & 0x1) << 7)
- | ((xmc[0] & 0x7) << 4)
- | ((xmc[1] & 0x7) << 1)
- | ((xmc[2] >> 2) & 0x1);
- *c++ = ((xmc[2] & 0x3) << 6)
- | ((xmc[3] & 0x7) << 3)
- | (xmc[4] & 0x7);
- *c++ = ((xmc[5] & 0x7) << 5) /* 10 */
- | ((xmc[6] & 0x7) << 2)
- | ((xmc[7] >> 1) & 0x3);
- *c++ = ((xmc[7] & 0x1) << 7)
- | ((xmc[8] & 0x7) << 4)
- | ((xmc[9] & 0x7) << 1)
- | ((xmc[10] >> 2) & 0x1);
- *c++ = ((xmc[10] & 0x3) << 6)
- | ((xmc[11] & 0x7) << 3)
- | (xmc[12] & 0x7);
- *c++ = ((Nc[1] & 0x7F) << 1)
- | ((bc[1] >> 1) & 0x1);
- *c++ = ((bc[1] & 0x1) << 7)
- | ((Mc[1] & 0x3) << 5)
- | ((xmaxc[1] >> 1) & 0x1F);
- *c++ = ((xmaxc[1] & 0x1) << 7)
- | ((xmc[13] & 0x7) << 4)
- | ((xmc[14] & 0x7) << 1)
- | ((xmc[15] >> 2) & 0x1);
- *c++ = ((xmc[15] & 0x3) << 6)
- | ((xmc[16] & 0x7) << 3)
- | (xmc[17] & 0x7);
- *c++ = ((xmc[18] & 0x7) << 5)
- | ((xmc[19] & 0x7) << 2)
- | ((xmc[20] >> 1) & 0x3);
- *c++ = ((xmc[20] & 0x1) << 7)
- | ((xmc[21] & 0x7) << 4)
- | ((xmc[22] & 0x7) << 1)
- | ((xmc[23] >> 2) & 0x1);
- *c++ = ((xmc[23] & 0x3) << 6)
- | ((xmc[24] & 0x7) << 3)
- | (xmc[25] & 0x7);
- *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
- | ((bc[2] >> 1) & 0x1);
- *c++ = ((bc[2] & 0x1) << 7)
- | ((Mc[2] & 0x3) << 5)
- | ((xmaxc[2] >> 1) & 0x1F);
- *c++ = ((xmaxc[2] & 0x1) << 7)
- | ((xmc[26] & 0x7) << 4)
- | ((xmc[27] & 0x7) << 1)
- | ((xmc[28] >> 2) & 0x1);
- *c++ = ((xmc[28] & 0x3) << 6)
- | ((xmc[29] & 0x7) << 3)
- | (xmc[30] & 0x7);
- *c++ = ((xmc[31] & 0x7) << 5)
- | ((xmc[32] & 0x7) << 2)
- | ((xmc[33] >> 1) & 0x3);
- *c++ = ((xmc[33] & 0x1) << 7)
- | ((xmc[34] & 0x7) << 4)
- | ((xmc[35] & 0x7) << 1)
- | ((xmc[36] >> 2) & 0x1);
- *c++ = ((xmc[36] & 0x3) << 6)
- | ((xmc[37] & 0x7) << 3)
- | (xmc[38] & 0x7);
- *c++ = ((Nc[3] & 0x7F) << 1)
- | ((bc[3] >> 1) & 0x1);
- *c++ = ((bc[3] & 0x1) << 7)
- | ((Mc[3] & 0x3) << 5)
- | ((xmaxc[3] >> 1) & 0x1F);
- *c++ = ((xmaxc[3] & 0x1) << 7)
- | ((xmc[39] & 0x7) << 4)
- | ((xmc[40] & 0x7) << 1)
- | ((xmc[41] >> 2) & 0x1);
- *c++ = ((xmc[41] & 0x3) << 6) /* 30 */
- | ((xmc[42] & 0x7) << 3)
- | (xmc[43] & 0x7);
- *c++ = ((xmc[44] & 0x7) << 5)
- | ((xmc[45] & 0x7) << 2)
- | ((xmc[46] >> 1) & 0x3);
- *c++ = ((xmc[46] & 0x1) << 7)
- | ((xmc[47] & 0x7) << 4)
- | ((xmc[48] & 0x7) << 1)
- | ((xmc[49] >> 2) & 0x1);
- *c++ = ((xmc[49] & 0x3) << 6)
- | ((xmc[50] & 0x7) << 3)
- | (xmc[51] & 0x7);
-
- }
-}
diff --git a/1.4/codecs/gsm/src/gsm_explode.c b/1.4/codecs/gsm/src/gsm_explode.c
deleted file mode 100644
index a906fc2ed..000000000
--- a/1.4/codecs/gsm/src/gsm_explode.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "private.h"
-#include "gsm.h"
-#include "proto.h"
-
-int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
-{
-# define LARc target
-# define Nc *((gsm_signal (*) [17])(target + 8))
-# define bc *((gsm_signal (*) [17])(target + 9))
-# define Mc *((gsm_signal (*) [17])(target + 10))
-# define xmaxc *((gsm_signal (*) [17])(target + 11))
-
-
-#ifdef WAV49
- if (s->wav_fmt) {
-
- uword sr = 0;
-
- if (s->frame_index == 1) {
-
- sr = *c++;
- LARc[0] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 2;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 4;
- LARc[2] = sr & 0x1f; sr >>= 5;
- LARc[3] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 2;
- LARc[4] = sr & 0xf; sr >>= 4;
- LARc[5] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2; /* 5 */
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[0] = sr & 0x7f; sr >>= 7;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (target + 12)
- xmc[0] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[1] = sr & 0x7; sr >>= 3;
- xmc[2] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- xmc[5] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 10 */
- xmc[6] = sr & 0x7; sr >>= 3;
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[9] = sr & 0x7; sr >>= 3;
- xmc[10] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[1] = sr & 0x7f; sr >>= 7;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (target + 29 - 13)
-
- xmc[13] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 15 */
- xmc[14] = sr & 0x7; sr >>= 3;
- xmc[15] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- xmc[18] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[19] = sr & 0x7; sr >>= 3;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[22] = sr & 0x7; sr >>= 3;
- xmc[23] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4; /* 20 */
- Nc[2] = sr & 0x7f; sr >>= 7;
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
-
-#undef xmc
-#define xmc (target + 46 - 26)
-
- xmc[26] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[27] = sr & 0x7; sr >>= 3;
- xmc[28] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- xmc[31] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[32] = sr & 0x7; sr >>= 3;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 25 */
- xmc[35] = sr & 0x7; sr >>= 3;
- xmc[36] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[3] = sr & 0x7f; sr >>= 7;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (target + 63 - 39)
-
- xmc[39] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[40] = sr & 0x7; sr >>= 3;
- xmc[41] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 30 */
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- xmc[44] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[45] = sr & 0x7; sr >>= 3;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[48] = sr & 0x7; sr >>= 3;
- xmc[49] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
-
- s->frame_chain = sr & 0xf;
- }
- else {
- sr = s->frame_chain;
- sr |= (uword)*c++ << 4; /* 1 */
- LARc[0] = sr & 0x3f; sr >>= 6;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr = *c++;
- LARc[2] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 3;
- LARc[3] = sr & 0x1f; sr >>= 5;
- LARc[4] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2;
- LARc[5] = sr & 0xf; sr >>= 4;
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 5 */
- Nc[0] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (target + 12)
- xmc[0] = sr & 0x7; sr >>= 3;
- xmc[1] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[2] = sr & 0x7; sr >>= 3;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[5] = sr & 0x7; sr >>= 3;
- xmc[6] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 10 */
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- xmc[9] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[10] = sr & 0x7; sr >>= 3;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[1] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (target + 29 - 13)
-
- xmc[13] = sr & 0x7; sr >>= 3;
- xmc[14] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 15 */
- xmc[15] = sr & 0x7; sr >>= 3;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[18] = sr & 0x7; sr >>= 3;
- xmc[19] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- xmc[22] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[23] = sr & 0x7; sr >>= 3;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[2] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1; /* 20 */
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (target + 46 - 26)
- xmc[26] = sr & 0x7; sr >>= 3;
- xmc[27] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[28] = sr & 0x7; sr >>= 3;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[31] = sr & 0x7; sr >>= 3;
- xmc[32] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- xmc[35] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 25 */
- xmc[36] = sr & 0x7; sr >>= 3;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[3] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
-
-#undef xmc
-#define xmc (target + 63 - 39)
-
- xmc[39] = sr & 0x7; sr >>= 3;
- xmc[40] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[41] = sr & 0x7; sr >>= 3;
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 30 */
- xmc[44] = sr & 0x7; sr >>= 3;
- xmc[45] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- xmc[48] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[49] = sr & 0x7; sr >>= 3;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
- }
- }
- else
-#endif
- {
- /* GSM_MAGIC = (*c >> 4) & 0xF; */
-
- if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
-
- LARc[0] = (*c++ & 0xF) << 2; /* 1 */
- LARc[0] |= (*c >> 6) & 0x3;
- LARc[1] = *c++ & 0x3F;
- LARc[2] = (*c >> 3) & 0x1F;
- LARc[3] = (*c++ & 0x7) << 2;
- LARc[3] |= (*c >> 6) & 0x3;
- LARc[4] = (*c >> 2) & 0xF;
- LARc[5] = (*c++ & 0x3) << 2;
- LARc[5] |= (*c >> 6) & 0x3;
- LARc[6] = (*c >> 3) & 0x7;
- LARc[7] = *c++ & 0x7;
-
- Nc[0] = (*c >> 1) & 0x7F;
-
- bc[0] = (*c++ & 0x1) << 1;
- bc[0] |= (*c >> 7) & 0x1;
-
- Mc[0] = (*c >> 5) & 0x3;
-
- xmaxc[0] = (*c++ & 0x1F) << 1;
- xmaxc[0] |= (*c >> 7) & 0x1;
-
-#undef xmc
-#define xmc (target + 12)
-
- xmc[0] = (*c >> 4) & 0x7;
- xmc[1] = (*c >> 1) & 0x7;
- xmc[2] = (*c++ & 0x1) << 2;
- xmc[2] |= (*c >> 6) & 0x3;
- xmc[3] = (*c >> 3) & 0x7;
- xmc[4] = *c++ & 0x7;
- xmc[5] = (*c >> 5) & 0x7;
- xmc[6] = (*c >> 2) & 0x7;
- xmc[7] = (*c++ & 0x3) << 1; /* 10 */
- xmc[7] |= (*c >> 7) & 0x1;
- xmc[8] = (*c >> 4) & 0x7;
- xmc[9] = (*c >> 1) & 0x7;
- xmc[10] = (*c++ & 0x1) << 2;
- xmc[10] |= (*c >> 6) & 0x3;
- xmc[11] = (*c >> 3) & 0x7;
- xmc[12] = *c++ & 0x7;
-
- Nc[1] = (*c >> 1) & 0x7F;
-
- bc[1] = (*c++ & 0x1) << 1;
- bc[1] |= (*c >> 7) & 0x1;
-
- Mc[1] = (*c >> 5) & 0x3;
-
- xmaxc[1] = (*c++ & 0x1F) << 1;
- xmaxc[1] |= (*c >> 7) & 0x1;
-
-#undef xmc
-#define xmc (target + 29 - 13)
-
- xmc[13] = (*c >> 4) & 0x7;
- xmc[14] = (*c >> 1) & 0x7;
- xmc[15] = (*c++ & 0x1) << 2;
- xmc[15] |= (*c >> 6) & 0x3;
- xmc[16] = (*c >> 3) & 0x7;
- xmc[17] = *c++ & 0x7;
- xmc[18] = (*c >> 5) & 0x7;
- xmc[19] = (*c >> 2) & 0x7;
- xmc[20] = (*c++ & 0x3) << 1;
- xmc[20] |= (*c >> 7) & 0x1;
- xmc[21] = (*c >> 4) & 0x7;
- xmc[22] = (*c >> 1) & 0x7;
- xmc[23] = (*c++ & 0x1) << 2;
- xmc[23] |= (*c >> 6) & 0x3;
- xmc[24] = (*c >> 3) & 0x7;
- xmc[25] = *c++ & 0x7;
-
- Nc[2] = (*c >> 1) & 0x7F;
-
- bc[2] = (*c++ & 0x1) << 1; /* 20 */
- bc[2] |= (*c >> 7) & 0x1;
-
- Mc[2] = (*c >> 5) & 0x3;
-
- xmaxc[2] = (*c++ & 0x1F) << 1;
- xmaxc[2] |= (*c >> 7) & 0x1;
-
-#undef xmc
-#define xmc (target + 46 - 26)
-
- xmc[26] = (*c >> 4) & 0x7;
- xmc[27] = (*c >> 1) & 0x7;
- xmc[28] = (*c++ & 0x1) << 2;
- xmc[28] |= (*c >> 6) & 0x3;
- xmc[29] = (*c >> 3) & 0x7;
- xmc[30] = *c++ & 0x7;
- xmc[31] = (*c >> 5) & 0x7;
- xmc[32] = (*c >> 2) & 0x7;
- xmc[33] = (*c++ & 0x3) << 1;
- xmc[33] |= (*c >> 7) & 0x1;
- xmc[34] = (*c >> 4) & 0x7;
- xmc[35] = (*c >> 1) & 0x7;
- xmc[36] = (*c++ & 0x1) << 2;
- xmc[36] |= (*c >> 6) & 0x3;
- xmc[37] = (*c >> 3) & 0x7;
- xmc[38] = *c++ & 0x7;
-
- Nc[3] = (*c >> 1) & 0x7F;
-
- bc[3] = (*c++ & 0x1) << 1;
- bc[3] |= (*c >> 7) & 0x1;
-
- Mc[3] = (*c >> 5) & 0x3;
-
- xmaxc[3] = (*c++ & 0x1F) << 1;
- xmaxc[3] |= (*c >> 7) & 0x1;
-
-#undef xmc
-#define xmc (target + 63 - 39)
-
- xmc[39] = (*c >> 4) & 0x7;
- xmc[40] = (*c >> 1) & 0x7;
- xmc[41] = (*c++ & 0x1) << 2;
- xmc[41] |= (*c >> 6) & 0x3;
- xmc[42] = (*c >> 3) & 0x7;
- xmc[43] = *c++ & 0x7; /* 30 */
- xmc[44] = (*c >> 5) & 0x7;
- xmc[45] = (*c >> 2) & 0x7;
- xmc[46] = (*c++ & 0x3) << 1;
- xmc[46] |= (*c >> 7) & 0x1;
- xmc[47] = (*c >> 4) & 0x7;
- xmc[48] = (*c >> 1) & 0x7;
- xmc[49] = (*c++ & 0x1) << 2;
- xmc[49] |= (*c >> 6) & 0x3;
- xmc[50] = (*c >> 3) & 0x7;
- xmc[51] = *c & 0x7; /* 33 */
- }
-
- return 0;
-}
diff --git a/1.4/codecs/gsm/src/gsm_implode.c b/1.4/codecs/gsm/src/gsm_implode.c
deleted file mode 100644
index 453b8cf39..000000000
--- a/1.4/codecs/gsm/src/gsm_implode.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
-{
- /* variable size index
-
- GSM_MAGIC 4 -
-
- LARc[0] 6 0
- LARc[1] 6 1
- LARc[2] 5 2
- LARc[3] 5 3
- LARc[4] 4 4
- LARc[5] 4 5
- LARc[6] 3 6
- LARc[7] 3 7
-
- Nc[0] 7 8
- bc[0] 2 9
- Mc[0] 2 10
- xmaxc[0] 6 11
- xmc[0] 3 12
- xmc[1] 3 13
- xmc[2] 3 14
- xmc[3] 3 15
- xmc[4] 3 16
- xmc[5] 3 17
- xmc[6] 3 18
- xmc[7] 3 19
- xmc[8] 3 20
- xmc[9] 3 21
- xmc[10] 3 22
- xmc[11] 3 23
- xmc[12] 3 24
-
- Nc[1] 7 25
- bc[1] 2 26
- Mc[1] 2 27
- xmaxc[1] 6 28
- xmc[13] 3 29
- xmc[14] 3 30
- xmc[15] 3 31
- xmc[16] 3 32
- xmc[17] 3 33
- xmc[18] 3 34
- xmc[19] 3 35
- xmc[20] 3 36
- xmc[21] 3 37
- xmc[22] 3 38
- xmc[23] 3 39
- xmc[24] 3 40
- xmc[25] 3 41
-
- Nc[2] 7 42
- bc[2] 2 43
- Mc[2] 2 44
- xmaxc[2] 6 45
- xmc[26] 3 46
- xmc[27] 3 47
- xmc[28] 3 48
- xmc[29] 3 49
- xmc[30] 3 50
- xmc[31] 3 51
- xmc[32] 3 52
- xmc[33] 3 53
- xmc[34] 3 54
- xmc[35] 3 55
- xmc[36] 3 56
- xmc[37] 3 57
- xmc[38] 3 58
-
- Nc[3] 7 59
- bc[3] 2 60
- Mc[3] 2 61
- xmaxc[3] 6 62
- xmc[39] 3 63
- xmc[40] 3 64
- xmc[41] 3 65
- xmc[42] 3 66
- xmc[43] 3 67
- xmc[44] 3 68
- xmc[45] 3 69
- xmc[46] 3 70
- xmc[47] 3 71
- xmc[48] 3 72
- xmc[49] 3 73
- xmc[50] 3 74
- xmc[51] 3 75
- */
-
- /* There are 76 parameters per frame. The first eight are
- * unique. The remaining 68 are four identical subframes of
- * 17 parameters each. gsm_implode converts from a representation
- * of these parameters as values in one array of signed words
- * to the "packed" version of a GSM frame.
- */
-
-# define LARc source
-# define Nc *((gsm_signal (*) [17])(source + 8))
-# define bc *((gsm_signal (*) [17])(source + 9))
-# define Mc *((gsm_signal (*) [17])(source + 10))
-# define xmaxc *((gsm_signal (*) [17])(source + 11))
-
-#ifdef WAV49
- if (s->wav_fmt) {
-
- uword sr = 0;
- if (s->frame_index == 0) {
-
- sr = *c++;
- LARc[0] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 2;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 4;
- LARc[2] = sr & 0x1f; sr >>= 5;
- LARc[3] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 2;
- LARc[4] = sr & 0xf; sr >>= 4;
- LARc[5] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2; /* 5 */
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[0] = sr & 0x7f; sr >>= 7;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 12)
- xmc[0] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[1] = sr & 0x7; sr >>= 3;
- xmc[2] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- xmc[5] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 10 */
- xmc[6] = sr & 0x7; sr >>= 3;
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[9] = sr & 0x7; sr >>= 3;
- xmc[10] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[1] = sr & 0x7f; sr >>= 7;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 29 - 13)
- xmc[13] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 15 */
- xmc[14] = sr & 0x7; sr >>= 3;
- xmc[15] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- xmc[18] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[19] = sr & 0x7; sr >>= 3;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[22] = sr & 0x7; sr >>= 3;
- xmc[23] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4; /* 20 */
- Nc[2] = sr & 0x7f; sr >>= 7;
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 46 - 26)
- xmc[26] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[27] = sr & 0x7; sr >>= 3;
- xmc[28] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- xmc[31] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[32] = sr & 0x7; sr >>= 3;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 25 */
- xmc[35] = sr & 0x7; sr >>= 3;
- xmc[36] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[3] = sr & 0x7f; sr >>= 7;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 63 - 39)
-
- xmc[39] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[40] = sr & 0x7; sr >>= 3;
- xmc[41] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 30 */
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- xmc[44] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[45] = sr & 0x7; sr >>= 3;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[48] = sr & 0x7; sr >>= 3;
- xmc[49] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
-
- s->frame_chain = sr & 0xf;
- }
- else {
- sr = s->frame_chain;
- sr |= (uword)*c++ << 4; /* 1 */
- LARc[0] = sr & 0x3f; sr >>= 6;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr = *c++;
- LARc[2] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 3;
- LARc[3] = sr & 0x1f; sr >>= 5;
- LARc[4] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2;
- LARc[5] = sr & 0xf; sr >>= 4;
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 5 */
- Nc[0] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 12)
- xmc[0] = sr & 0x7; sr >>= 3;
- xmc[1] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[2] = sr & 0x7; sr >>= 3;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[5] = sr & 0x7; sr >>= 3;
- xmc[6] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 10 */
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- xmc[9] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[10] = sr & 0x7; sr >>= 3;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[1] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 29 - 13)
- xmc[13] = sr & 0x7; sr >>= 3;
- xmc[14] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 15 */
- xmc[15] = sr & 0x7; sr >>= 3;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[18] = sr & 0x7; sr >>= 3;
- xmc[19] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- xmc[22] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[23] = sr & 0x7; sr >>= 3;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[2] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1; /* 20 */
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 46 - 26)
- xmc[26] = sr & 0x7; sr >>= 3;
- xmc[27] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[28] = sr & 0x7; sr >>= 3;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[31] = sr & 0x7; sr >>= 3;
- xmc[32] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- xmc[35] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 25 */
- xmc[36] = sr & 0x7; sr >>= 3;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[3] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
-#undef xmc
-#define xmc (source + 63 - 39)
-
- xmc[39] = sr & 0x7; sr >>= 3;
- xmc[40] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[41] = sr & 0x7; sr >>= 3;
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 30 */
- xmc[44] = sr & 0x7; sr >>= 3;
- xmc[45] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- xmc[48] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[49] = sr & 0x7; sr >>= 3;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
- }
- }
- else
-#endif
- {
-
- *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
- | ((LARc[0] >> 2) & 0xF);
- *c++ = ((LARc[0] & 0x3) << 6)
- | (LARc[1] & 0x3F);
- *c++ = ((LARc[2] & 0x1F) << 3)
- | ((LARc[3] >> 2) & 0x7);
- *c++ = ((LARc[3] & 0x3) << 6)
- | ((LARc[4] & 0xF) << 2)
- | ((LARc[5] >> 2) & 0x3);
- *c++ = ((LARc[5] & 0x3) << 6)
- | ((LARc[6] & 0x7) << 3)
- | (LARc[7] & 0x7);
-
-
- *c++ = ((Nc[0] & 0x7F) << 1)
-
-
- | ((bc[0] >> 1) & 0x1);
- *c++ = ((bc[0] & 0x1) << 7)
-
-
- | ((Mc[0] & 0x3) << 5)
-
- | ((xmaxc[0] >> 1) & 0x1F);
- *c++ = ((xmaxc[0] & 0x1) << 7)
-
-#undef xmc
-#define xmc (source + 12)
-
- | ((xmc[0] & 0x7) << 4)
- | ((xmc[1] & 0x7) << 1)
- | ((xmc[2] >> 2) & 0x1);
- *c++ = ((xmc[2] & 0x3) << 6)
- | ((xmc[3] & 0x7) << 3)
- | (xmc[4] & 0x7);
- *c++ = ((xmc[5] & 0x7) << 5) /* 10 */
- | ((xmc[6] & 0x7) << 2)
- | ((xmc[7] >> 1) & 0x3);
- *c++ = ((xmc[7] & 0x1) << 7)
- | ((xmc[8] & 0x7) << 4)
- | ((xmc[9] & 0x7) << 1)
- | ((xmc[10] >> 2) & 0x1);
- *c++ = ((xmc[10] & 0x3) << 6)
- | ((xmc[11] & 0x7) << 3)
- | (xmc[12] & 0x7);
-
-
- *c++ = ((Nc[1] & 0x7F) << 1)
-
-
- | ((bc[1] >> 1) & 0x1);
- *c++ = ((bc[1] & 0x1) << 7)
-
-
- | ((Mc[1] & 0x3) << 5)
-
-
- | ((xmaxc[1] >> 1) & 0x1F);
- *c++ = ((xmaxc[1] & 0x1) << 7)
-
-#undef xmc
-#define xmc (source + 29 - 13)
-
- | ((xmc[13] & 0x7) << 4)
- | ((xmc[14] & 0x7) << 1)
- | ((xmc[15] >> 2) & 0x1);
- *c++ = ((xmc[15] & 0x3) << 6)
- | ((xmc[16] & 0x7) << 3)
- | (xmc[17] & 0x7);
- *c++ = ((xmc[18] & 0x7) << 5)
- | ((xmc[19] & 0x7) << 2)
- | ((xmc[20] >> 1) & 0x3);
- *c++ = ((xmc[20] & 0x1) << 7)
- | ((xmc[21] & 0x7) << 4)
- | ((xmc[22] & 0x7) << 1)
- | ((xmc[23] >> 2) & 0x1);
- *c++ = ((xmc[23] & 0x3) << 6)
- | ((xmc[24] & 0x7) << 3)
- | (xmc[25] & 0x7);
-
-
- *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
-
-
- | ((bc[2] >> 1) & 0x1);
- *c++ = ((bc[2] & 0x1) << 7)
-
-
- | ((Mc[2] & 0x3) << 5)
-
-
- | ((xmaxc[2] >> 1) & 0x1F);
- *c++ = ((xmaxc[2] & 0x1) << 7)
-
-#undef xmc
-#define xmc (source + 46 - 26)
-
- | ((xmc[26] & 0x7) << 4)
- | ((xmc[27] & 0x7) << 1)
- | ((xmc[28] >> 2) & 0x1);
- *c++ = ((xmc[28] & 0x3) << 6)
- | ((xmc[29] & 0x7) << 3)
- | (xmc[30] & 0x7);
- *c++ = ((xmc[31] & 0x7) << 5)
- | ((xmc[32] & 0x7) << 2)
- | ((xmc[33] >> 1) & 0x3);
- *c++ = ((xmc[33] & 0x1) << 7)
- | ((xmc[34] & 0x7) << 4)
- | ((xmc[35] & 0x7) << 1)
- | ((xmc[36] >> 2) & 0x1);
- *c++ = ((xmc[36] & 0x3) << 6)
- | ((xmc[37] & 0x7) << 3)
- | (xmc[38] & 0x7);
-
-
- *c++ = ((Nc[3] & 0x7F) << 1)
-
-
- | ((bc[3] >> 1) & 0x1);
- *c++ = ((bc[3] & 0x1) << 7)
-
-
- | ((Mc[3] & 0x3) << 5)
-
-
- | ((xmaxc[3] >> 1) & 0x1F);
- *c++ = ((xmaxc[3] & 0x1) << 7)
-
-#undef xmc
-#define xmc (source + 63 - 39)
-
- | ((xmc[39] & 0x7) << 4)
- | ((xmc[40] & 0x7) << 1)
- | ((xmc[41] >> 2) & 0x1);
- *c++ = ((xmc[41] & 0x3) << 6) /* 30 */
- | ((xmc[42] & 0x7) << 3)
- | (xmc[43] & 0x7);
- *c++ = ((xmc[44] & 0x7) << 5)
- | ((xmc[45] & 0x7) << 2)
- | ((xmc[46] >> 1) & 0x3);
- *c++ = ((xmc[46] & 0x1) << 7)
- | ((xmc[47] & 0x7) << 4)
- | ((xmc[48] & 0x7) << 1)
- | ((xmc[49] >> 2) & 0x1);
- *c++ = ((xmc[49] & 0x3) << 6)
- | ((xmc[50] & 0x7) << 3)
- | (xmc[51] & 0x7);
- }
-}
diff --git a/1.4/codecs/gsm/src/gsm_option.c b/1.4/codecs/gsm/src/gsm_option.c
deleted file mode 100644
index 280780132..000000000
--- a/1.4/codecs/gsm/src/gsm_option.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-int gsm_option P3((r, opt, val), gsm r, int opt, int * val)
-{
- int result = -1;
-
- switch (opt) {
- case GSM_OPT_LTP_CUT:
-#ifdef LTP_CUT
- result = r->ltp_cut;
- if (val) r->ltp_cut = *val;
-#endif
- break;
-
- case GSM_OPT_VERBOSE:
-#ifndef NDEBUG
- result = r->verbose;
- if (val) r->verbose = *val;
-#endif
- break;
-
- case GSM_OPT_FAST:
-
-#if defined(FAST) && defined(USE_FLOAT_MUL)
- result = r->fast;
- if (val) r->fast = !!*val;
-#endif
- break;
-
- case GSM_OPT_FRAME_CHAIN:
-
-#ifdef WAV49
- result = r->frame_chain;
- if (val) r->frame_chain = *val;
-#endif
- break;
-
- case GSM_OPT_FRAME_INDEX:
-
-#ifdef WAV49
- result = r->frame_index;
- if (val) r->frame_index = *val;
-#endif
- break;
-
- case GSM_OPT_WAV49:
-
-#ifdef WAV49
- result = r->wav_fmt;
- if (val) r->wav_fmt = !!*val;
-#endif
- break;
-
- default:
- break;
- }
- return result;
-}
diff --git a/1.4/codecs/gsm/src/gsm_print.c b/1.4/codecs/gsm/src/gsm_print.c
deleted file mode 100644
index af745bc48..000000000
--- a/1.4/codecs/gsm/src/gsm_print.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)
-{
- word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
-
- /* GSM_MAGIC = (*c >> 4) & 0xF; */
-
- if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
-
- LARc[0] = (*c++ & 0xF) << 2; /* 1 */
- LARc[0] |= (*c >> 6) & 0x3;
- LARc[1] = *c++ & 0x3F;
- LARc[2] = (*c >> 3) & 0x1F;
- LARc[3] = (*c++ & 0x7) << 2;
- LARc[3] |= (*c >> 6) & 0x3;
- LARc[4] = (*c >> 2) & 0xF;
- LARc[5] = (*c++ & 0x3) << 2;
- LARc[5] |= (*c >> 6) & 0x3;
- LARc[6] = (*c >> 3) & 0x7;
- LARc[7] = *c++ & 0x7;
-
-
- Nc[0] = (*c >> 1) & 0x7F;
- bc[0] = (*c++ & 0x1) << 1;
- bc[0] |= (*c >> 7) & 0x1;
- Mc[0] = (*c >> 5) & 0x3;
- xmaxc[0] = (*c++ & 0x1F) << 1;
- xmaxc[0] |= (*c >> 7) & 0x1;
- xmc[0] = (*c >> 4) & 0x7;
- xmc[1] = (*c >> 1) & 0x7;
- xmc[2] = (*c++ & 0x1) << 2;
- xmc[2] |= (*c >> 6) & 0x3;
- xmc[3] = (*c >> 3) & 0x7;
- xmc[4] = *c++ & 0x7;
- xmc[5] = (*c >> 5) & 0x7;
- xmc[6] = (*c >> 2) & 0x7;
- xmc[7] = (*c++ & 0x3) << 1; /* 10 */
- xmc[7] |= (*c >> 7) & 0x1;
- xmc[8] = (*c >> 4) & 0x7;
- xmc[9] = (*c >> 1) & 0x7;
- xmc[10] = (*c++ & 0x1) << 2;
- xmc[10] |= (*c >> 6) & 0x3;
- xmc[11] = (*c >> 3) & 0x7;
- xmc[12] = *c++ & 0x7;
-
- Nc[1] = (*c >> 1) & 0x7F;
- bc[1] = (*c++ & 0x1) << 1;
- bc[1] |= (*c >> 7) & 0x1;
- Mc[1] = (*c >> 5) & 0x3;
- xmaxc[1] = (*c++ & 0x1F) << 1;
- xmaxc[1] |= (*c >> 7) & 0x1;
- xmc[13] = (*c >> 4) & 0x7;
- xmc[14] = (*c >> 1) & 0x7;
- xmc[15] = (*c++ & 0x1) << 2;
- xmc[15] |= (*c >> 6) & 0x3;
- xmc[16] = (*c >> 3) & 0x7;
- xmc[17] = *c++ & 0x7;
- xmc[18] = (*c >> 5) & 0x7;
- xmc[19] = (*c >> 2) & 0x7;
- xmc[20] = (*c++ & 0x3) << 1;
- xmc[20] |= (*c >> 7) & 0x1;
- xmc[21] = (*c >> 4) & 0x7;
- xmc[22] = (*c >> 1) & 0x7;
- xmc[23] = (*c++ & 0x1) << 2;
- xmc[23] |= (*c >> 6) & 0x3;
- xmc[24] = (*c >> 3) & 0x7;
- xmc[25] = *c++ & 0x7;
-
-
- Nc[2] = (*c >> 1) & 0x7F;
- bc[2] = (*c++ & 0x1) << 1; /* 20 */
- bc[2] |= (*c >> 7) & 0x1;
- Mc[2] = (*c >> 5) & 0x3;
- xmaxc[2] = (*c++ & 0x1F) << 1;
- xmaxc[2] |= (*c >> 7) & 0x1;
- xmc[26] = (*c >> 4) & 0x7;
- xmc[27] = (*c >> 1) & 0x7;
- xmc[28] = (*c++ & 0x1) << 2;
- xmc[28] |= (*c >> 6) & 0x3;
- xmc[29] = (*c >> 3) & 0x7;
- xmc[30] = *c++ & 0x7;
- xmc[31] = (*c >> 5) & 0x7;
- xmc[32] = (*c >> 2) & 0x7;
- xmc[33] = (*c++ & 0x3) << 1;
- xmc[33] |= (*c >> 7) & 0x1;
- xmc[34] = (*c >> 4) & 0x7;
- xmc[35] = (*c >> 1) & 0x7;
- xmc[36] = (*c++ & 0x1) << 2;
- xmc[36] |= (*c >> 6) & 0x3;
- xmc[37] = (*c >> 3) & 0x7;
- xmc[38] = *c++ & 0x7;
-
- Nc[3] = (*c >> 1) & 0x7F;
- bc[3] = (*c++ & 0x1) << 1;
- bc[3] |= (*c >> 7) & 0x1;
- Mc[3] = (*c >> 5) & 0x3;
- xmaxc[3] = (*c++ & 0x1F) << 1;
- xmaxc[3] |= (*c >> 7) & 0x1;
-
- xmc[39] = (*c >> 4) & 0x7;
- xmc[40] = (*c >> 1) & 0x7;
- xmc[41] = (*c++ & 0x1) << 2;
- xmc[41] |= (*c >> 6) & 0x3;
- xmc[42] = (*c >> 3) & 0x7;
- xmc[43] = *c++ & 0x7; /* 30 */
- xmc[44] = (*c >> 5) & 0x7;
- xmc[45] = (*c >> 2) & 0x7;
- xmc[46] = (*c++ & 0x3) << 1;
- xmc[46] |= (*c >> 7) & 0x1;
- xmc[47] = (*c >> 4) & 0x7;
- xmc[48] = (*c >> 1) & 0x7;
- xmc[49] = (*c++ & 0x1) << 2;
- xmc[49] |= (*c >> 6) & 0x3;
- xmc[50] = (*c >> 3) & 0x7;
- xmc[51] = *c & 0x7; /* 33 */
-
- fprintf(f,
- "LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n",
- LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);
-
- fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n",
- Nc[0], bc[0], Mc[0], xmaxc[0]);
- fprintf(f,
-"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
- xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],
- xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );
-
- fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n",
- Nc[1], bc[1], Mc[1], xmaxc[1]);
- fprintf(f,
-"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
- xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],
- xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],
- xmc[13+12] );
-
- fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n",
- Nc[2], bc[2], Mc[2], xmaxc[2]);
- fprintf(f,
-"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
- xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],
- xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],
- xmc[26+12] );
-
- fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n",
- Nc[3], bc[3], Mc[3], xmaxc[3]);
- fprintf(f,
-"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
- xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],
- xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],
- xmc[39+12] );
-
- return 0;
-}
diff --git a/1.4/codecs/gsm/src/k6opt.h b/1.4/codecs/gsm/src/k6opt.h
deleted file mode 100644
index 16ea2ac8d..000000000
--- a/1.4/codecs/gsm/src/k6opt.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* k6opt.h vector functions optimized for MMX extensions to x86
- *
- * Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
- *
- * Any use of this software is permitted provided that this notice is not
- * removed and that neither the authors nor the Technische Universitaet Berlin
- * are deemed to have made any representations as to the suitability of this
- * software for any purpose nor are held responsible for any defects of
- * this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE;
- * not even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE.
- *
- * Chicago, 03.12.1999
- * Stanley J. Brooks
- */
-
-extern void Weighting_filter P2((e, x),
- const word * e, /* signal [-5..0.39.44] IN */
- word * x /* signal [0..39] OUT */
-)
-;
-
-extern longword k6maxcc P3((wt,dp,Nc_out),
- const word *wt,
- const word *dp,
- word * Nc_out /* OUT */
-)
-;
-/*
- * k6maxmin(p,n,out[])
- * input p[n] is array of shorts (require n>0)
- * returns (long) maximum absolute value..
- * if out!=NULL, also returns out[0] the maximum and out[1] the minimum
- */
-extern longword k6maxmin P3((p,n,out),
- const word *p,
- int n,
- word *out /* out[0] is max, out[1] is min */
-)
-;
-
-extern longword k6iprod P3((p,q,n),
- const word *p,
- const word *q,
- int n
-)
-;
-
-/*
- * k6vsraw(p,n,bits)
- * input p[n] is array of shorts (require n>0)
- * shift/round each to the right by bits>=0 bits.
- */
-extern void k6vsraw P3((p,n,bits),
- const word *p,
- int n,
- int bits
-)
-;
-
-/*
- * k6vsllw(p,n,bits)
- * input p[n] is array of shorts (require n>0)
- * shift each to the left by bits>=0 bits.
- */
-extern void k6vsllw P3((p,n,bits),
- const word *p,
- int n,
- int bits
-)
-;
-
-#if 1 /* there isn't any significant speed gain from mmx here: */
-extern void Short_term_analysis_filteringx P4((u0,rp0,k_n,s),
- register word * u0,
- register word * rp0, /* [0..7] IN */
- register int k_n, /* k_end - k_start */
- register word * s /* [0..n-1] IN/OUT */
-)
-;
-/*
-#define Short_term_analysis_filtering Short_term_analysis_filteringx
-*/
-#endif
diff --git a/1.4/codecs/gsm/src/k6opt.s b/1.4/codecs/gsm/src/k6opt.s
deleted file mode 100644
index d84d54cbf..000000000
--- a/1.4/codecs/gsm/src/k6opt.s
+++ /dev/null
@@ -1,739 +0,0 @@
- .file "k6opt.s"
- .version "01.01"
-/* gcc2_compiled.: */
-.section .rodata
- .align 4
- .type coefs,@object
- .size coefs,24
-coefs:
- .value -134
- .value -374
- .value 0
- .value 2054
- .value 5741
- .value 8192
- .value 5741
- .value 2054
- .value 0
- .value -374
- .value -134
- .value 0
-.text
- .align 4
-/* void Weighting_filter (const short *e, short *x) */
-.globl Weighting_filter
- .type Weighting_filter,@function
-Weighting_filter:
- pushl %ebp
- movl %esp,%ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- movl 12(%ebp),%edi
- movl 8(%ebp),%ebx
- addl $-10,%ebx
- emms
- movl $0x1000,%eax; movd %eax,%mm5 /* for rounding */
- movq coefs,%mm1
- movq coefs+8,%mm2
- movq coefs+16,%mm3
- xorl %esi,%esi
- .p2align 2
-.L21:
- movq (%ebx,%esi,2),%mm0
- pmaddwd %mm1,%mm0
-
- movq 8(%ebx,%esi,2),%mm4
- pmaddwd %mm2,%mm4
- paddd %mm4,%mm0
-
- movq 16(%ebx,%esi,2),%mm4
- pmaddwd %mm3,%mm4
- paddd %mm4,%mm0
-
- movq %mm0,%mm4
- punpckhdq %mm0,%mm4 /* mm4 has high int32 of mm0 dup'd */
- paddd %mm4,%mm0;
-
- paddd %mm5,%mm0 /* add for roundoff */
- psrad $13,%mm0
- packssdw %mm0,%mm0
- movd %mm0,%eax /* ax has result */
- movw %ax,(%edi,%esi,2)
- incl %esi
- cmpl $39,%esi
- jle .L21
- emms
- popl %ebx
- popl %esi
- popl %edi
- leave
- ret
-.Lfe1:
- .size Weighting_filter,.Lfe1-Weighting_filter
-
-.macro ccstep n
-.if \n
- movq \n(%edi),%mm1
- movq \n(%esi),%mm2
-.else
- movq (%edi),%mm1
- movq (%esi),%mm2
-.endif
- pmaddwd %mm2,%mm1
- paddd %mm1,%mm0
-.endm
-
- .align 4
-/* long k6maxcc(const short *wt, const short *dp, short *Nc_out) */
-.globl k6maxcc
- .type k6maxcc,@function
-k6maxcc:
- pushl %ebp
- movl %esp,%ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- emms
- movl 8(%ebp),%edi
- movl 12(%ebp),%esi
- movl $0,%edx /* will be maximum inner-product */
- movl $40,%ebx
- movl %ebx,%ecx /* will be index of max inner-product */
- subl $80,%esi
- .p2align 2
-.L41:
- movq (%edi),%mm0
- movq (%esi),%mm2
- pmaddwd %mm2,%mm0
- ccstep 8
- ccstep 16
- ccstep 24
- ccstep 32
- ccstep 40
- ccstep 48
- ccstep 56
- ccstep 64
- ccstep 72
-
- movq %mm0,%mm1
- punpckhdq %mm0,%mm1 /* mm1 has high int32 of mm0 dup'd */
- paddd %mm1,%mm0;
- movd %mm0,%eax /* eax has result */
-
- cmpl %edx,%eax
- jle .L40
- movl %eax,%edx
- movl %ebx,%ecx
- .p2align 2
-.L40:
- subl $2,%esi
- incl %ebx
- cmpl $120,%ebx
- jle .L41
- movl 16(%ebp),%eax
- movw %cx,(%eax)
- movl %edx,%eax
- emms
- popl %ebx
- popl %esi
- popl %edi
- leave
- ret
-.Lfe2:
- .size k6maxcc,.Lfe2-k6maxcc
-
-
- .align 4
-/* long k6iprod (const short *p, const short *q, int n) */
-.globl k6iprod
- .type k6iprod,@function
-k6iprod:
- pushl %ebp
- movl %esp,%ebp
- pushl %edi
- pushl %esi
- emms
- pxor %mm0,%mm0
- movl 8(%ebp),%esi
- movl 12(%ebp),%edi
- movl 16(%ebp),%eax
- leal -32(%esi,%eax,2),%edx /* edx = top - 32 */
-
- cmpl %edx,%esi; ja .L202
-
- .p2align 2
-.L201:
- ccstep 0
- ccstep 8
- ccstep 16
- ccstep 24
-
- addl $32,%esi
- addl $32,%edi
- cmpl %edx,%esi; jbe .L201
-
- .p2align 2
-.L202:
- addl $24,%edx /* now edx = top-8 */
- cmpl %edx,%esi; ja .L205
-
- .p2align 2
-.L203:
- ccstep 0
-
- addl $8,%esi
- addl $8,%edi
- cmpl %edx,%esi; jbe .L203
-
- .p2align 2
-.L205:
- addl $4,%edx /* now edx = top-4 */
- cmpl %edx,%esi; ja .L207
-
- movd (%edi),%mm1
- movd (%esi),%mm2
- pmaddwd %mm2,%mm1
- paddd %mm1,%mm0
-
- addl $4,%esi
- addl $4,%edi
-
- .p2align 2
-.L207:
- addl $2,%edx /* now edx = top-2 */
- cmpl %edx,%esi; ja .L209
-
- movswl (%edi),%eax
- movd %eax,%mm1
- movswl (%esi),%eax
- movd %eax,%mm2
- pmaddwd %mm2,%mm1
- paddd %mm1,%mm0
-
- .p2align 2
-.L209:
- movq %mm0,%mm1
- punpckhdq %mm0,%mm1 /* mm1 has high int32 of mm0 dup'd */
- paddd %mm1,%mm0;
- movd %mm0,%eax /* eax has result */
-
- emms
- popl %esi
- popl %edi
- leave
- ret
-.Lfe3:
- .size k6iprod,.Lfe3-k6iprod
-
-
- .align 4
-/* void k6vsraw P3((short *p, int n, int bits) */
-.globl k6vsraw
- .type k6vsraw,@function
-k6vsraw:
- pushl %ebp
- movl %esp,%ebp
- pushl %esi
- movl 8(%ebp),%esi
- movl 16(%ebp),%ecx
- andl %ecx,%ecx; jle .L399
- movl 12(%ebp),%eax
- leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
- emms
- movd %ecx,%mm3
- movq ones,%mm2
- psllw %mm3,%mm2; psrlw $1,%mm2
- cmpl %edx,%esi; ja .L306
-
- .p2align 2
-.L302: /* 8 words per iteration */
- movq (%esi),%mm0
- movq 8(%esi),%mm1
- paddsw %mm2,%mm0
- psraw %mm3,%mm0;
- paddsw %mm2,%mm1
- psraw %mm3,%mm1;
- movq %mm0,(%esi)
- movq %mm1,8(%esi)
- addl $16,%esi
- cmpl %edx,%esi
- jbe .L302
-
- .p2align 2
-.L306:
- addl $12,%edx /* now edx = top-4 */
- cmpl %edx,%esi; ja .L310
-
- .p2align 2
-.L308: /* do up to 6 words, two at a time */
- movd (%esi),%mm0
- paddsw %mm2,%mm0
- psraw %mm3,%mm0;
- movd %mm0,(%esi)
- addl $4,%esi
- cmpl %edx,%esi
- jbe .L308
-
- .p2align 2
-.L310:
- addl $2,%edx /* now edx = top-2 */
- cmpl %edx,%esi; ja .L315
-
- movzwl (%esi),%eax
- movd %eax,%mm0
- paddsw %mm2,%mm0
- psraw %mm3,%mm0;
- movd %mm0,%eax
- movw %ax,(%esi)
-
- .p2align 2
-.L315:
- emms
-.L399:
- popl %esi
- leave
- ret
-.Lfe4:
- .size k6vsraw,.Lfe4-k6vsraw
-
- .align 4
-/* void k6vsllw P3((short *p, int n, int bits) */
-.globl k6vsllw
- .type k6vsllw,@function
-k6vsllw:
- pushl %ebp
- movl %esp,%ebp
- pushl %esi
- movl 8(%ebp),%esi
- movl 16(%ebp),%ecx
- andl %ecx,%ecx; jle .L499
- movl 12(%ebp),%eax
- leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
- emms
- movd %ecx,%mm3
- cmpl %edx,%esi; ja .L406
-
- .p2align 2
-.L402: /* 8 words per iteration */
- movq (%esi),%mm0
- movq 8(%esi),%mm1
- psllw %mm3,%mm0;
- psllw %mm3,%mm1;
- movq %mm0,(%esi)
- movq %mm1,8(%esi)
- addl $16,%esi
- cmpl %edx,%esi
- jbe .L402
-
- .p2align 2
-.L406:
- addl $12,%edx /* now edx = top-4 */
- cmpl %edx,%esi; ja .L410
-
- .p2align 2
-.L408: /* do up to 6 words, two at a time */
- movd (%esi),%mm0
- psllw %mm3,%mm0;
- movd %mm0,(%esi)
- addl $4,%esi
- cmpl %edx,%esi
- jbe .L408
-
- .p2align 2
-.L410:
- addl $2,%edx /* now edx = top-2 */
- cmpl %edx,%esi; ja .L415
-
- movzwl (%esi),%eax
- movd %eax,%mm0
- psllw %mm3,%mm0;
- movd %mm0,%eax
- movw %ax,(%esi)
-
- .p2align 2
-.L415:
- emms
-.L499:
- popl %esi
- leave
- ret
-.Lfe5:
- .size k6vsllw,.Lfe5-k6vsllw
-
-
-.section .rodata
- .align 4
- .type extremes,@object
- .size extremes,8
-extremes:
- .long 0x80008000
- .long 0x7fff7fff
- .type ones,@object
- .size ones,8
-ones:
- .long 0x00010001
- .long 0x00010001
-
-.text
- .align 4
-/* long k6maxmin (const short *p, int n, short *out) */
-.globl k6maxmin
- .type k6maxmin,@function
-k6maxmin:
- pushl %ebp
- movl %esp,%ebp
- pushl %esi
- emms
- movl 8(%ebp),%esi
- movl 12(%ebp),%eax
- leal -8(%esi,%eax,2),%edx
-
- cmpl %edx,%esi
- jbe .L52
- movd extremes,%mm0
- movd extremes+4,%mm1
- jmp .L58
-
- .p2align 2
-.L52:
- movq (%esi),%mm0 /* mm0 will be max's */
- movq %mm0,%mm1 /* mm1 will be min's */
- addl $8,%esi
- cmpl %edx,%esi
- ja .L56
-
- .p2align 2
-.L54:
- movq (%esi),%mm2
-
- movq %mm2,%mm3
- pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
- movq %mm3,%mm4
- pand %mm2,%mm3 /* mm3 is mm2 masked to new max's */
- pandn %mm0,%mm4 /* mm4 is mm0 masked to its max's */
- por %mm3,%mm4
- movq %mm4,%mm0 /* now mm0 is updated max's */
-
- movq %mm1,%mm3
- pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
- pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
- pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
- por %mm3,%mm2
- movq %mm2,%mm1 /* now mm1 is updated min's */
-
- addl $8,%esi
- cmpl %edx,%esi
- jbe .L54
-
- .p2align 2
-.L56: /* merge down the 4-word max/mins to lower 2 words */
-
- movq %mm0,%mm2
- psrlq $32,%mm2
- movq %mm2,%mm3
- pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
- pand %mm3,%mm2 /* mm2 is mm2 masked to new max's */
- pandn %mm0,%mm3 /* mm3 is mm0 masked to its max's */
- por %mm3,%mm2
- movq %mm2,%mm0 /* now mm0 is updated max's */
-
- movq %mm1,%mm2
- psrlq $32,%mm2
- movq %mm1,%mm3
- pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
- pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
- pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
- por %mm3,%mm2
- movq %mm2,%mm1 /* now mm1 is updated min's */
-
- .p2align 2
-.L58:
- addl $4,%edx /* now dx = top-4 */
- cmpl %edx,%esi
- ja .L62
- /* here, there are >= 2 words of input remaining */
- movd (%esi),%mm2
-
- movq %mm2,%mm3
- pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
- movq %mm3,%mm4
- pand %mm2,%mm3 /* mm3 is mm2 masked to new max's */
- pandn %mm0,%mm4 /* mm4 is mm0 masked to its max's */
- por %mm3,%mm4
- movq %mm4,%mm0 /* now mm0 is updated max's */
-
- movq %mm1,%mm3
- pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
- pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
- pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
- por %mm3,%mm2
- movq %mm2,%mm1 /* now mm1 is updated min's */
-
- addl $4,%esi
-
- .p2align 2
-.L62:
- /* merge down the 2-word max/mins to 1 word */
-
- movq %mm0,%mm2
- psrlq $16,%mm2
- movq %mm2,%mm3
- pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
- pand %mm3,%mm2 /* mm2 is mm2 masked to new max's */
- pandn %mm0,%mm3 /* mm3 is mm0 masked to its max's */
- por %mm3,%mm2
- movd %mm2,%ecx /* cx is max so far */
-
- movq %mm1,%mm2
- psrlq $16,%mm2
- movq %mm1,%mm3
- pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
- pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
- pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
- por %mm3,%mm2
- movd %mm2,%eax /* ax is min so far */
-
- addl $2,%edx /* now dx = top-2 */
- cmpl %edx,%esi
- ja .L65
-
- /* here, there is one word of input left */
- cmpw (%esi),%cx
- jge .L64
- movw (%esi),%cx
- .p2align 2
-.L64:
- cmpw (%esi),%ax
- jle .L65
- movw (%esi),%ax
-
- .p2align 2
-.L65: /* (finally!) cx is the max, ax the min */
- movswl %cx,%ecx
- movswl %ax,%eax
-
- movl 16(%ebp),%edx /* ptr to output max,min vals */
- andl %edx,%edx; jz .L77
- movw %cx,(%edx) /* max */
- movw %ax,2(%edx) /* min */
- .p2align 2
-.L77:
- /* now calculate max absolute val */
- negl %eax
- cmpl %ecx,%eax
- jge .L81
- movl %ecx,%eax
- .p2align 2
-.L81:
- emms
- popl %esi
- leave
- ret
-.Lfe6:
- .size k6maxmin,.Lfe6-k6maxmin
-
-/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
- .equiv pm_u0,8
- .equiv pm_rp0,12
- .equiv pm_kn,16
- .equiv pm_s,20
- .equiv lv_u_top,-4
- .equiv lv_s_top,-8
- .equiv lv_rp,-40 /* local version of rp0 with each word twice */
- .align 4
-.globl Short_term_analysis_filteringx
- .type Short_term_analysis_filteringx,@function
-Short_term_analysis_filteringx:
- pushl %ebp
- movl %esp,%ebp
- subl $40,%esp
- pushl %edi
- pushl %esi
-
- movl pm_rp0(%ebp),%esi;
- leal lv_rp(%ebp),%edi;
- cld
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- emms
- movl $0x4000,%eax;
- movd %eax,%mm4;
- punpckldq %mm4,%mm4 /* (0x00004000,0x00004000) for rounding dword product pairs */
-
- movl pm_u0(%ebp),%eax
- addl $16,%eax
- movl %eax,lv_u_top(%ebp) /* UTOP */
- movl pm_s(%ebp),%edx /* edx is local s ptr throughout below */
- movl pm_kn(%ebp),%eax
- leal (%edx,%eax,2),%eax
- movl %eax,lv_s_top(%ebp)
- cmpl %eax,%edx
- jae .L179
- .p2align 2
-.L181:
- leal lv_rp(%ebp),%esi /* RP */
- movl pm_u0(%ebp),%edi /* U */
- movw (%edx),%ax /* (0,DI) */
- roll $16,%eax
- movw (%edx),%ax /* (DI,DI) */
- .p2align 2
-.L185: /* RP is %esi */
- movl %eax,%ecx
- movw (%edi),%ax /* (DI,U) */
- movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
- movw %cx,(%edi)
-
- movd %eax,%mm2 /* mm2 is (0,0,DI,U) */
- rorl $16,%eax
- movd %eax,%mm1 /* mm1 is (0,0,U,DI) */
-
- movq %mm1,%mm0
- pmullw %mm3,%mm0
- pmulhw %mm3,%mm1
- punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
- paddd %mm4,%mm0 /* mm4 is 0x00004000,0x00004000 */
- psrad $15,%mm0 /* (RP*U,RP*DI) adjusted */
- packssdw %mm0,%mm0 /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
- paddsw %mm2,%mm0 /* mm0 is (?,?, DI', U') */
- movd %mm0,%eax /* (DI,U') */
-
- addl $2,%edi
- addl $4,%esi
- cmpl lv_u_top(%ebp),%edi
- jb .L185
-
- rorl $16,%eax
- movw %ax,(%edx) /* last DI goes to *s */
- addl $2,%edx /* next s */
- cmpl lv_s_top(%ebp),%edx
- jb .L181
- .p2align 2
-.L179:
- emms
- popl %esi
- popl %edi
- leave
- ret
-.Lfe7:
- .size Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
-
-.end
-
-/* 'as' macro's seem to be case-insensitive */
-.macro STEP n
-.if \n
- movd \n(%esi),%mm3 /* mm3 is (0,0,RP,RP) */
-.else
- movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
-.endif
- movq %mm5,%mm1;
- movd %mm4,%ecx; movw %cx,%ax /* (DI,U) */
- psllq $48,%mm1; psrlq $16,%mm4; por %mm1,%mm4
- psllq $48,%mm0; psrlq $16,%mm5; por %mm0,%mm5
-
- movd %eax,%mm2 /* mm2 is (0,0,DI,U) */
- rorl $16,%eax
- movd %eax,%mm1 /* mm1 is (0,0,U,DI) */
-
- movq %mm1,%mm0
- pmullw %mm3,%mm0
- pmulhw %mm3,%mm1
- punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
- paddd %mm6,%mm0 /* mm6 is 0x00004000,0x00004000 */
- psrad $15,%mm0 /* (RP*U,RP*DI) adjusted */
- packssdw %mm0,%mm0 /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
- paddsw %mm2,%mm0 /* mm0 is (?,?, DI', U') */
- movd %mm0,%eax /* (DI,U') */
-.endm
-
-/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
- .equiv pm_u0,8
- .equiv pm_rp0,12
- .equiv pm_kn,16
- .equiv pm_s,20
- .equiv lv_rp_top,-4
- .equiv lv_s_top,-8
- .equiv lv_rp,-40 /* local version of rp0 with each word twice */
- .align 4
-.globl Short_term_analysis_filteringx
- .type Short_term_analysis_filteringx,@function
-Short_term_analysis_filteringx:
- pushl %ebp
- movl %esp,%ebp
- subl $56,%esp
- pushl %edi
- pushl %esi
- pushl %ebx
-
- movl pm_rp0(%ebp),%esi;
- leal lv_rp(%ebp),%edi;
- cld
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- lodsw; stosw; stosw
- movl %edi,lv_rp_top(%ebp)
- emms
-
- movl $0x4000,%eax;
- movd %eax,%mm6;
- punpckldq %mm6,%mm6 /* (0x00004000,0x00004000) for rounding dword product pairs */
-
- movl pm_u0(%ebp),%ebx
- movq (%ebx),%mm4; movq 8(%ebx),%mm5 /* the 8 u's */
- movl pm_s(%ebp),%edx /* edx is local s ptr throughout below */
- movl pm_kn(%ebp),%eax
- leal (%edx,%eax,2),%eax
- movl %eax,lv_s_top(%ebp)
- cmpl %eax,%edx
- jae .L179
- .p2align 2
-.L181:
- leal lv_rp(%ebp),%esi /* RP */
- movw (%edx),%ax /* (0,DI) */
- roll $16,%eax
- movw (%edx),%ax /* (DI,DI) */
- movd %eax,%mm0
- .p2align 2
-.L185: /* RP is %esi */
- step 0
- step 4
- step 8
- step 12
-/*
- step 16
- step 20
- step 24
- step 28
-*/
- addl $16,%esi
- cmpl lv_rp_top(%ebp),%esi
- jb .L185
-
- rorl $16,%eax
- movw %ax,(%edx) /* last DI goes to *s */
- addl $2,%edx /* next s */
- cmpl lv_s_top(%ebp),%edx
- jb .L181
-.L179:
- movq %mm4,(%ebx); movq %mm5,8(%ebx) /* the 8 u's */
- emms
- popl %ebx
- popl %esi
- popl %edi
- leave
- ret
-.Lfe7:
- .size Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
- .ident "GCC: (GNU) 2.95.2 19991109 (Debian GNU/Linux)"
diff --git a/1.4/codecs/gsm/src/long_term.c b/1.4/codecs/gsm/src/long_term.c
deleted file mode 100644
index 83b6fdf85..000000000
--- a/1.4/codecs/gsm/src/long_term.c
+++ /dev/null
@@ -1,955 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-#ifdef K6OPT
-#include "k6opt.h"
-#endif
-/*
- * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
- */
-
-
-/*
- * This module computes the LTP gain (bc) and the LTP lag (Nc)
- * for the long term analysis filter. This is done by calculating a
- * maximum of the cross-correlation function between the current
- * sub-segment short term residual signal d[0..39] (output of
- * the short term analysis filter; for simplification the index
- * of this array begins at 0 and ends at 39 for each sub-segment of the
- * RPE-LTP analysis) and the previous reconstructed short term
- * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be
- * performed to avoid overflow.
- */
-
- /* The next procedure exists in six versions. First two integer
- * version (if USE_FLOAT_MUL is not defined); then four floating
- * point versions, twice with proper scaling (USE_FLOAT_MUL defined),
- * once without (USE_FLOAT_MUL and FAST defined, and fast run-time
- * option used). Every pair has first a Cut version (see the -C
- * option to toast or the LTP_CUT option to gsm_option()), then the
- * uncut one. (For a detailed explanation of why this is altogether
- * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
- * Harmful''.)
- */
-
-#ifndef USE_FLOAT_MUL
-
-#ifdef LTP_CUT
-
-static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
-
- struct gsm_state * st,
-
- register word * d, /* [0..39] IN */
- register word * dp, /* [-120..-1] IN */
- word * bc_out, /* OUT */
- word * Nc_out /* OUT */
-)
-{
- register int k, lambda;
- word Nc, bc;
- word wt[40];
-
- longword L_result;
- longword L_max, L_power;
- word R, S, dmax, scal, best_k;
- word ltp_cut;
-
- register word temp, wt_k;
-
- /* Search of the optimum scaling of d[0..39].
- */
- dmax = 0;
- for (k = 0; k <= 39; k++) {
- temp = d[k];
- temp = GSM_ABS( temp );
- if (temp > dmax) {
- dmax = temp;
- best_k = k;
- }
- }
- temp = 0;
- if (dmax == 0) scal = 0;
- else {
- assert(dmax > 0);
- temp = gsm_norm( (longword)dmax << 16 );
- }
- if (temp > 6) scal = 0;
- else scal = 6 - temp;
- assert(scal >= 0);
-
- /* Search for the maximum cross-correlation and coding of the LTP lag
- */
- L_max = 0;
- Nc = 40; /* index for the maximum cross-correlation */
- wt_k = SASR(d[best_k], scal);
-
- for (lambda = 40; lambda <= 120; lambda++) {
- L_result = (longword)wt_k * dp[best_k - lambda];
- if (L_result > L_max) {
- Nc = lambda;
- L_max = L_result;
- }
- }
- *Nc_out = Nc;
- L_max <<= 1;
-
- /* Rescaling of L_max
- */
- assert(scal <= 100 && scal >= -100);
- L_max = L_max >> (6 - scal); /* sub(6, scal) */
-
- assert( Nc <= 120 && Nc >= 40);
-
- /* Compute the power of the reconstructed short term residual
- * signal dp[..]
- */
- L_power = 0;
- for (k = 0; k <= 39; k++) {
-
- register longword L_temp;
-
- L_temp = SASR( dp[k - Nc], 3 );
- L_power += L_temp * L_temp;
- }
- L_power <<= 1; /* from L_MULT */
-
- /* Normalization of L_max and L_power
- */
-
- if (L_max <= 0) {
- *bc_out = 0;
- return;
- }
- if (L_max >= L_power) {
- *bc_out = 3;
- return;
- }
-
- temp = gsm_norm( L_power );
-
- R = SASR( L_max << temp, 16 );
- S = SASR( L_power << temp, 16 );
-
- /* Coding of the LTP gain
- */
-
- /* Table 4.3a must be used to obtain the level DLB[i] for the
- * quantization of the LTP gain b to get the coded version bc.
- */
- for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
- *bc_out = bc;
-}
-
-#endif /* LTP_CUT */
-
-static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
- register word * d, /* [0..39] IN */
- register word * dp, /* [-120..-1] IN */
- word * bc_out, /* OUT */
- word * Nc_out /* OUT */
-)
-{
- register int k;
-#ifndef K6OPT
- register int lambda;
-#endif
- word Nc, bc;
- word wt[40];
-
- longword L_max, L_power;
- word R, S, dmax, scal;
- register word temp;
-
- /* Search of the optimum scaling of d[0..39].
- */
- dmax = 0;
-
- for (k = 0; k <= 39; k++) {
- temp = d[k];
- temp = GSM_ABS( temp );
- if (temp > dmax) dmax = temp;
- }
-
- temp = 0;
- if (dmax == 0) scal = 0;
- else {
- assert(dmax > 0);
- temp = gsm_norm( (longword)dmax << 16 );
- }
-
- if (temp > 6) scal = 0;
- else scal = 6 - temp;
-
- assert(scal >= 0);
-
- /* Initialization of a working array wt
- */
-
- for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );
-
- /* Search for the maximum cross-correlation and coding of the LTP lag
- */
-# ifdef K6OPT
- L_max = k6maxcc(wt,dp,&Nc);
-# else
- L_max = 0;
- Nc = 40; /* index for the maximum cross-correlation */
-
- for (lambda = 40; lambda <= 120; lambda++) {
-
-# undef STEP
-# define STEP(k) (longword)wt[k] * dp[k - lambda]
-
- register longword L_result;
-
- L_result = STEP(0) ; L_result += STEP(1) ;
- L_result += STEP(2) ; L_result += STEP(3) ;
- L_result += STEP(4) ; L_result += STEP(5) ;
- L_result += STEP(6) ; L_result += STEP(7) ;
- L_result += STEP(8) ; L_result += STEP(9) ;
- L_result += STEP(10) ; L_result += STEP(11) ;
- L_result += STEP(12) ; L_result += STEP(13) ;
- L_result += STEP(14) ; L_result += STEP(15) ;
- L_result += STEP(16) ; L_result += STEP(17) ;
- L_result += STEP(18) ; L_result += STEP(19) ;
- L_result += STEP(20) ; L_result += STEP(21) ;
- L_result += STEP(22) ; L_result += STEP(23) ;
- L_result += STEP(24) ; L_result += STEP(25) ;
- L_result += STEP(26) ; L_result += STEP(27) ;
- L_result += STEP(28) ; L_result += STEP(29) ;
- L_result += STEP(30) ; L_result += STEP(31) ;
- L_result += STEP(32) ; L_result += STEP(33) ;
- L_result += STEP(34) ; L_result += STEP(35) ;
- L_result += STEP(36) ; L_result += STEP(37) ;
- L_result += STEP(38) ; L_result += STEP(39) ;
-
- if (L_result > L_max) {
-
- Nc = lambda;
- L_max = L_result;
- }
- }
-# endif
- *Nc_out = Nc;
-
- L_max <<= 1;
-
- /* Rescaling of L_max
- */
- assert(scal <= 100 && scal >= -100);
- L_max = L_max >> (6 - scal); /* sub(6, scal) */
-
- assert( Nc <= 120 && Nc >= 40);
-
- /* Compute the power of the reconstructed short term residual
- * signal dp[..]
- */
- L_power = 0;
- for (k = 0; k <= 39; k++) {
-
- register longword L_temp;
-
- L_temp = SASR( dp[k - Nc], 3 );
- L_power += L_temp * L_temp;
- }
- L_power <<= 1; /* from L_MULT */
-
- /* Normalization of L_max and L_power
- */
-
- if (L_max <= 0) {
- *bc_out = 0;
- return;
- }
- if (L_max >= L_power) {
- *bc_out = 3;
- return;
- }
-
- temp = gsm_norm( L_power );
-
- R = (word)SASR( L_max << temp, 16 );
- S = (word)SASR( L_power << temp, 16 );
-
- /* Coding of the LTP gain
- */
-
- /* Table 4.3a must be used to obtain the level DLB[i] for the
- * quantization of the LTP gain b to get the coded version bc.
- */
- for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
- *bc_out = bc;
-}
-
-#else /* USE_FLOAT_MUL */
-
-#ifdef LTP_CUT
-
-static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
- struct gsm_state * st, /* IN */
- register word * d, /* [0..39] IN */
- register word * dp, /* [-120..-1] IN */
- word * bc_out, /* OUT */
- word * Nc_out /* OUT */
-)
-{
- register int k, lambda;
- word Nc, bc;
- word ltp_cut;
-
- float wt_float[40];
- float dp_float_base[120], * dp_float = dp_float_base + 120;
-
- longword L_max, L_power;
- word R, S, dmax, scal;
- register word temp;
-
- /* Search of the optimum scaling of d[0..39].
- */
- dmax = 0;
-
- for (k = 0; k <= 39; k++) {
- temp = d[k];
- temp = GSM_ABS( temp );
- if (temp > dmax) dmax = temp;
- }
-
- temp = 0;
- if (dmax == 0) scal = 0;
- else {
- assert(dmax > 0);
- temp = gsm_norm( (longword)dmax << 16 );
- }
-
- if (temp > 6) scal = 0;
- else scal = 6 - temp;
-
- assert(scal >= 0);
- ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100;
-
-
- /* Initialization of a working array wt
- */
-
- for (k = 0; k < 40; k++) {
- register word w = SASR( d[k], scal );
- if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
- wt_float[k] = 0.0;
- }
- else {
- wt_float[k] = w;
- }
- }
- for (k = -120; k < 0; k++) dp_float[k] = dp[k];
-
- /* Search for the maximum cross-correlation and coding of the LTP lag
- */
- L_max = 0;
- Nc = 40; /* index for the maximum cross-correlation */
-
- for (lambda = 40; lambda <= 120; lambda += 9) {
-
- /* Calculate L_result for l = lambda .. lambda + 9.
- */
- register float *lp = dp_float - lambda;
-
- register float W;
- register float a = lp[-8], b = lp[-7], c = lp[-6],
- d = lp[-5], e = lp[-4], f = lp[-3],
- g = lp[-2], h = lp[-1];
- register float E;
- register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
- S5 = 0, S6 = 0, S7 = 0, S8 = 0;
-
-# undef STEP
-# define STEP(K, a, b, c, d, e, f, g, h) \
- if ((W = wt_float[K]) != 0.0) { \
- E = W * a; S8 += E; \
- E = W * b; S7 += E; \
- E = W * c; S6 += E; \
- E = W * d; S5 += E; \
- E = W * e; S4 += E; \
- E = W * f; S3 += E; \
- E = W * g; S2 += E; \
- E = W * h; S1 += E; \
- a = lp[K]; \
- E = W * a; S0 += E; } else (a = lp[K])
-
-# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
-# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
-# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
-# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
-# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
-# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
-# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
-# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
-
- STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
- STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
-
- STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
- STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
-
- STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
- STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
-
- STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
- STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
-
- STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
- STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
-
- if (S0 > L_max) { L_max = S0; Nc = lambda; }
- if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
- if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
- if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
- if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
- if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
- if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
- if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
- if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
-
- }
- *Nc_out = Nc;
-
- L_max <<= 1;
-
- /* Rescaling of L_max
- */
- assert(scal <= 100 && scal >= -100);
- L_max = L_max >> (6 - scal); /* sub(6, scal) */
-
- assert( Nc <= 120 && Nc >= 40);
-
- /* Compute the power of the reconstructed short term residual
- * signal dp[..]
- */
- L_power = 0;
- for (k = 0; k <= 39; k++) {
-
- register longword L_temp;
-
- L_temp = SASR( dp[k - Nc], 3 );
- L_power += L_temp * L_temp;
- }
- L_power <<= 1; /* from L_MULT */
-
- /* Normalization of L_max and L_power
- */
-
- if (L_max <= 0) {
- *bc_out = 0;
- return;
- }
- if (L_max >= L_power) {
- *bc_out = 3;
- return;
- }
-
- temp = gsm_norm( L_power );
-
- R = SASR( L_max << temp, 16 );
- S = SASR( L_power << temp, 16 );
-
- /* Coding of the LTP gain
- */
-
- /* Table 4.3a must be used to obtain the level DLB[i] for the
- * quantization of the LTP gain b to get the coded version bc.
- */
- for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
- *bc_out = bc;
-}
-
-#endif /* LTP_CUT */
-
-static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
- register word * d, /* [0..39] IN */
- register word * dp, /* [-120..-1] IN */
- word * bc_out, /* OUT */
- word * Nc_out /* OUT */
-)
-{
- register int k, lambda;
- word Nc, bc;
-
- float wt_float[40];
- float dp_float_base[120], * dp_float = dp_float_base + 120;
-
- longword L_max, L_power;
- word R, S, dmax, scal;
- register word temp;
-
- /* Search of the optimum scaling of d[0..39].
- */
- dmax = 0;
-
- for (k = 0; k <= 39; k++) {
- temp = d[k];
- temp = GSM_ABS( temp );
- if (temp > dmax) dmax = temp;
- }
-
- temp = 0;
- if (dmax == 0) scal = 0;
- else {
- assert(dmax > 0);
- temp = gsm_norm( (longword)dmax << 16 );
- }
-
- if (temp > 6) scal = 0;
- else scal = 6 - temp;
-
- assert(scal >= 0);
-
- /* Initialization of a working array wt
- */
-
- for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal );
- for (k = -120; k < 0; k++) dp_float[k] = dp[k];
-
- /* Search for the maximum cross-correlation and coding of the LTP lag
- */
- L_max = 0;
- Nc = 40; /* index for the maximum cross-correlation */
-
- for (lambda = 40; lambda <= 120; lambda += 9) {
-
- /* Calculate L_result for l = lambda .. lambda + 9.
- */
- register float *lp = dp_float - lambda;
-
- register float W;
- register float a = lp[-8], b = lp[-7], c = lp[-6],
- d = lp[-5], e = lp[-4], f = lp[-3],
- g = lp[-2], h = lp[-1];
- register float E;
- register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
- S5 = 0, S6 = 0, S7 = 0, S8 = 0;
-
-# undef STEP
-# define STEP(K, a, b, c, d, e, f, g, h) \
- W = wt_float[K]; \
- E = W * a; S8 += E; \
- E = W * b; S7 += E; \
- E = W * c; S6 += E; \
- E = W * d; S5 += E; \
- E = W * e; S4 += E; \
- E = W * f; S3 += E; \
- E = W * g; S2 += E; \
- E = W * h; S1 += E; \
- a = lp[K]; \
- E = W * a; S0 += E
-
-# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
-# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
-# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
-# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
-# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
-# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
-# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
-# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
-
- STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
- STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
-
- STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
- STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
-
- STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
- STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
-
- STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
- STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
-
- STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
- STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
-
- if (S0 > L_max) { L_max = S0; Nc = lambda; }
- if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
- if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
- if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
- if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
- if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
- if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
- if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
- if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
- }
- *Nc_out = Nc;
-
- L_max <<= 1;
-
- /* Rescaling of L_max
- */
- assert(scal <= 100 && scal >= -100);
- L_max = L_max >> (6 - scal); /* sub(6, scal) */
-
- assert( Nc <= 120 && Nc >= 40);
-
- /* Compute the power of the reconstructed short term residual
- * signal dp[..]
- */
- L_power = 0;
- for (k = 0; k <= 39; k++) {
-
- register longword L_temp;
-
- L_temp = SASR( dp[k - Nc], 3 );
- L_power += L_temp * L_temp;
- }
- L_power <<= 1; /* from L_MULT */
-
- /* Normalization of L_max and L_power
- */
-
- if (L_max <= 0) {
- *bc_out = 0;
- return;
- }
- if (L_max >= L_power) {
- *bc_out = 3;
- return;
- }
-
- temp = gsm_norm( L_power );
-
- R = SASR( L_max << temp, 16 );
- S = SASR( L_power << temp, 16 );
-
- /* Coding of the LTP gain
- */
-
- /* Table 4.3a must be used to obtain the level DLB[i] for the
- * quantization of the LTP gain b to get the coded version bc.
- */
- for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
- *bc_out = bc;
-}
-
-#ifdef FAST
-#ifdef LTP_CUT
-
-static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,
- d,dp,bc_out,Nc_out),
- struct gsm_state * st, /* IN */
- register word * d, /* [0..39] IN */
- register word * dp, /* [-120..-1] IN */
- word * bc_out, /* OUT */
- word * Nc_out /* OUT */
-)
-{
- register int k, lambda;
- register float wt_float;
- word Nc, bc;
- word wt_max, best_k, ltp_cut;
-
- float dp_float_base[120], * dp_float = dp_float_base + 120;
-
- register float L_result, L_max, L_power;
-
- wt_max = 0;
-
- for (k = 0; k < 40; ++k) {
- if ( d[k] > wt_max) wt_max = d[best_k = k];
- else if (-d[k] > wt_max) wt_max = -d[best_k = k];
- }
-
- assert(wt_max >= 0);
- wt_float = (float)wt_max;
-
- for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
-
- /* Search for the maximum cross-correlation and coding of the LTP lag
- */
- L_max = 0;
- Nc = 40; /* index for the maximum cross-correlation */
-
- for (lambda = 40; lambda <= 120; lambda++) {
- L_result = wt_float * dp_float[best_k - lambda];
- if (L_result > L_max) {
- Nc = lambda;
- L_max = L_result;
- }
- }
-
- *Nc_out = Nc;
- if (L_max <= 0.) {
- *bc_out = 0;
- return;
- }
-
- /* Compute the power of the reconstructed short term residual
- * signal dp[..]
- */
- dp_float -= Nc;
- L_power = 0;
- for (k = 0; k < 40; ++k) {
- register float f = dp_float[k];
- L_power += f * f;
- }
-
- if (L_max >= L_power) {
- *bc_out = 3;
- return;
- }
-
- /* Coding of the LTP gain
- * Table 4.3a must be used to obtain the level DLB[i] for the
- * quantization of the LTP gain b to get the coded version bc.
- */
- lambda = L_max / L_power * 32768.;
- for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
- *bc_out = bc;
-}
-
-#endif /* LTP_CUT */
-
-static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
- register word * d, /* [0..39] IN */
- register word * dp, /* [-120..-1] IN */
- word * bc_out, /* OUT */
- word * Nc_out /* OUT */
-)
-{
- register int k, lambda;
- word Nc, bc;
-
- float wt_float[40];
- float dp_float_base[120], * dp_float = dp_float_base + 120;
-
- register float L_max, L_power;
-
- for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];
- for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
-
- /* Search for the maximum cross-correlation and coding of the LTP lag
- */
- L_max = 0;
- Nc = 40; /* index for the maximum cross-correlation */
-
- for (lambda = 40; lambda <= 120; lambda += 9) {
-
- /* Calculate L_result for l = lambda .. lambda + 9.
- */
- register float *lp = dp_float - lambda;
-
- register float W;
- register float a = lp[-8], b = lp[-7], c = lp[-6],
- d = lp[-5], e = lp[-4], f = lp[-3],
- g = lp[-2], h = lp[-1];
- register float E;
- register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
- S5 = 0, S6 = 0, S7 = 0, S8 = 0;
-
-# undef STEP
-# define STEP(K, a, b, c, d, e, f, g, h) \
- W = wt_float[K]; \
- E = W * a; S8 += E; \
- E = W * b; S7 += E; \
- E = W * c; S6 += E; \
- E = W * d; S5 += E; \
- E = W * e; S4 += E; \
- E = W * f; S3 += E; \
- E = W * g; S2 += E; \
- E = W * h; S1 += E; \
- a = lp[K]; \
- E = W * a; S0 += E
-
-# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
-# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
-# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
-# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
-# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
-# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
-# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
-# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
-
- STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
- STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
-
- STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
- STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
-
- STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
- STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
-
- STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
- STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
-
- STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
- STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
-
- if (S0 > L_max) { L_max = S0; Nc = lambda; }
- if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
- if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
- if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
- if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
- if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
- if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
- if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
- if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
- }
- *Nc_out = Nc;
-
- if (L_max <= 0.) {
- *bc_out = 0;
- return;
- }
-
- /* Compute the power of the reconstructed short term residual
- * signal dp[..]
- */
- dp_float -= Nc;
- L_power = 0;
- for (k = 0; k < 40; ++k) {
- register float f = dp_float[k];
- L_power += f * f;
- }
-
- if (L_max >= L_power) {
- *bc_out = 3;
- return;
- }
-
- /* Coding of the LTP gain
- * Table 4.3a must be used to obtain the level DLB[i] for the
- * quantization of the LTP gain b to get the coded version bc.
- */
- lambda = L_max / L_power * 32768.;
- for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
- *bc_out = bc;
-}
-
-#endif /* FAST */
-#endif /* USE_FLOAT_MUL */
-
-
-/* 4.2.12 */
-
-static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e),
- word bc, /* IN */
- word Nc, /* IN */
- register word * dp, /* previous d [-120..-1] IN */
- register word * d, /* d [0..39] IN */
- register word * dpp, /* estimate [0..39] OUT */
- register word * e /* long term res. signal [0..39] OUT */
-)
-/*
- * In this part, we have to decode the bc parameter to compute
- * the samples of the estimate dpp[0..39]. The decoding of bc needs the
- * use of table 4.3b. The long term residual signal e[0..39]
- * is then calculated to be fed to the RPE encoding section.
- */
-{
- register int k;
-
-# undef STEP
-# define STEP(BP) \
- for (k = 0; k <= 39; k++) { \
- dpp[k] = (word)GSM_MULT_R( BP, dp[k - Nc]); \
- e[k] = GSM_SUB( d[k], dpp[k] ); \
- }
-
- switch (bc) {
- case 0: STEP( 3277 ); break;
- case 1: STEP( 11469 ); break;
- case 2: STEP( 21299 ); break;
- case 3: STEP( 32767 ); break;
- }
-}
-
-void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */
-
- struct gsm_state * S,
-
- word * d, /* [0..39] residual signal IN */
- word * dp, /* [-120..-1] d' IN */
-
- word * e, /* [0..39] OUT */
- word * dpp, /* [0..39] OUT */
- word * Nc, /* correlation lag OUT */
- word * bc /* gain factor OUT */
-)
-{
- assert( d ); assert( dp ); assert( e );
- assert( dpp); assert( Nc ); assert( bc );
-
-#if defined(FAST) && defined(USE_FLOAT_MUL)
- if (S->fast)
-#if defined (LTP_CUT)
- if (S->ltp_cut)
- Cut_Fast_Calculation_of_the_LTP_parameters(S,
- d, dp, bc, Nc);
- else
-#endif /* LTP_CUT */
- Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
- else
-#endif /* FAST & USE_FLOAT_MUL */
-#ifdef LTP_CUT
- if (S->ltp_cut)
- Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
- else
-#endif
- Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
-
- Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
-}
-
-/* 4.3.2 */
-void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp),
- struct gsm_state * S,
-
- word Ncr,
- word bcr,
- register word * erp, /* [0..39] IN */
- register word * drp /* [-120..-1] IN, [-120..40] OUT */
-)
-/*
- * This procedure uses the bcr and Ncr parameter to realize the
- * long term synthesis filtering. The decoding of bcr needs
- * table 4.3b.
- */
-{
- register int k;
- word brp, drpp, Nr;
-
- /* Check the limits of Nr.
- */
- Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
- S->nrp = Nr;
- assert(Nr >= 40 && Nr <= 120);
-
- /* Decoding of the LTP gain bcr
- */
- brp = gsm_QLB[ bcr ];
-
- /* Computation of the reconstructed short term residual
- * signal drp[0..39]
- */
- assert(brp != MIN_WORD);
-
- for (k = 0; k <= 39; k++) {
- drpp = (word)GSM_MULT_R( brp, drp[ k - Nr ] );
- drp[k] = GSM_ADD( erp[k], drpp );
- }
-
- /*
- * Update of the reconstructed short term residual signal
- * drp[ -1..-120 ]
- */
-
- for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
-}
diff --git a/1.4/codecs/gsm/src/lpc.c b/1.4/codecs/gsm/src/lpc.c
deleted file mode 100644
index 744149e02..000000000
--- a/1.4/codecs/gsm/src/lpc.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-#ifdef K6OPT
-#include "k6opt.h"
-#endif
-
-#undef P
-
-/*
- * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
- */
-
-/* 4.2.4 */
-
-
-static void Autocorrelation P2((s, L_ACF),
- word * s, /* [0..159] IN/OUT */
- longword * L_ACF) /* [0..8] OUT */
-/*
- * The goal is to compute the array L_ACF[k]. The signal s[i] must
- * be scaled in order to avoid an overflow situation.
- */
-{
-#ifndef K6OPT
- register int k, i;
- word temp;
-#endif
-
- word smax, scalauto;
-
-#ifdef USE_FLOAT_MUL
- float float_s[160];
-#endif
-
- /* Dynamic scaling of the array s[0..159]
- */
-
- /* Search for the maximum.
- */
-#ifndef K6OPT
- smax = 0;
- for (k = 0; k <= 159; k++) {
- temp = GSM_ABS( s[k] );
- if (temp > smax) smax = temp;
- }
-#else
- {
- longword lmax;
- lmax = k6maxmin(s,160,NULL);
- smax = (lmax > MAX_WORD) ? MAX_WORD : lmax;
- }
-#endif
- /* Computation of the scaling factor.
- */
- if (smax == 0) scalauto = 0;
- else {
- assert(smax > 0);
- scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
- }
-
- /* Scaling of the array s[0...159]
- */
-
- if (scalauto > 0) {
-# ifndef K6OPT
-
-# ifdef USE_FLOAT_MUL
-# define SCALE(n) \
- case n: for (k = 0; k <= 159; k++) \
- float_s[k] = (float) \
- (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
- break;
-# else
-# define SCALE(n) \
- case n: for (k = 0; k <= 159; k++) \
- s[k] = (word)GSM_MULT_R( s[k], 16384 >> (n-1) );\
- break;
-# endif /* USE_FLOAT_MUL */
-
- switch (scalauto) {
- SCALE(1)
- SCALE(2)
- SCALE(3)
- SCALE(4)
- }
-# undef SCALE
-
-# else /* K6OPT */
- k6vsraw(s,160,scalauto);
-# endif
- }
-# ifdef USE_FLOAT_MUL
- else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
-# endif
-
- /* Compute the L_ACF[..].
- */
-#ifndef K6OPT
- {
-# ifdef USE_FLOAT_MUL
- register float * sp = float_s;
- register float sl = *sp;
-
-# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]);
-# else
- word * sp = s;
- word sl = *sp;
-
-# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]);
-# endif
-
-# define NEXTI sl = *++sp
-
-
- for (k = 9; k--; L_ACF[k] = 0) ;
-
- STEP (0);
- NEXTI;
- STEP(0); STEP(1);
- NEXTI;
- STEP(0); STEP(1); STEP(2);
- NEXTI;
- STEP(0); STEP(1); STEP(2); STEP(3);
- NEXTI;
- STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
- NEXTI;
- STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
- NEXTI;
- STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
- NEXTI;
- STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
-
- for (i = 8; i <= 159; i++) {
-
- NEXTI;
-
- STEP(0);
- STEP(1); STEP(2); STEP(3); STEP(4);
- STEP(5); STEP(6); STEP(7); STEP(8);
- }
-
- for (k = 9; k--; L_ACF[k] <<= 1) ;
-
- }
-
-#else
- {
- int k;
- for (k=0; k<9; k++) {
- L_ACF[k] = 2*k6iprod(s,s+k,160-k);
- }
- }
-#endif
- /* Rescaling of the array s[0..159]
- */
- if (scalauto > 0) {
- assert(scalauto <= 4);
-#ifndef K6OPT
- for (k = 160; k--; *s++ <<= scalauto) ;
-# else /* K6OPT */
- k6vsllw(s,160,scalauto);
-# endif
- }
-}
-
-#if defined(USE_FLOAT_MUL) && defined(FAST)
-
-static void Fast_Autocorrelation P2((s, L_ACF),
- word * s, /* [0..159] IN/OUT */
- longword * L_ACF) /* [0..8] OUT */
-{
- register int k, i;
- float f_L_ACF[9];
- float scale;
-
- float s_f[160];
- register float *sf = s_f;
-
- for (i = 0; i < 160; ++i) sf[i] = s[i];
- for (k = 0; k <= 8; k++) {
- register float L_temp2 = 0;
- register float *sfl = sf - k;
- for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
- f_L_ACF[k] = L_temp2;
- }
- scale = MAX_LONGWORD / f_L_ACF[0];
-
- for (k = 0; k <= 8; k++) {
- L_ACF[k] = f_L_ACF[k] * scale;
- }
-}
-#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
-
-/* 4.2.5 */
-
-static void Reflection_coefficients P2( (L_ACF, r),
- longword * L_ACF, /* 0...8 IN */
- register word * r /* 0...7 OUT */
-)
-{
- register int i, m, n;
- register word temp;
- word ACF[9]; /* 0..8 */
- word P[ 9]; /* 0..8 */
- word K[ 9]; /* 2..8 */
-
- /* Schur recursion with 16 bits arithmetic.
- */
-
- if (L_ACF[0] == 0) {
- for (i = 8; i--; *r++ = 0) ;
- return;
- }
-
- assert( L_ACF[0] != 0 );
- temp = gsm_norm( L_ACF[0] );
-
- assert(temp >= 0 && temp < 32);
-
- /* ? overflow ? */
- for (i = 0; i <= 8; i++) ACF[i] = (word)SASR( L_ACF[i] << temp, 16 );
-
- /* Initialize array P[..] and K[..] for the recursion.
- */
-
- for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
- for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
-
- /* Compute reflection coefficients
- */
- for (n = 1; n <= 8; n++, r++) {
-
- temp = P[1];
- temp = GSM_ABS(temp);
- if (P[0] < temp) {
- for (i = n; i <= 8; i++) *r++ = 0;
- return;
- }
-
- *r = gsm_div( temp, P[0] );
-
- assert(*r >= 0);
- if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */
- assert (*r != MIN_WORD);
- if (n == 8) return;
-
- /* Schur recursion
- */
- temp = (word)GSM_MULT_R( P[1], *r );
- P[0] = GSM_ADD( P[0], temp );
-
- for (m = 1; m <= 8 - n; m++) {
- temp = (word)GSM_MULT_R( K[ m ], *r );
- P[m] = GSM_ADD( P[ m+1 ], temp );
-
- temp = (word)GSM_MULT_R( P[ m+1 ], *r );
- K[m] = GSM_ADD( K[ m ], temp );
- }
- }
-}
-
-/* 4.2.6 */
-
-static void Transformation_to_Log_Area_Ratios P1((r),
- register word * r /* 0..7 IN/OUT */
-)
-/*
- * The following scaling for r[..] and LAR[..] has been used:
- *
- * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1.
- * LAR[..] = integer( real_LAR[..] * 16384 );
- * with -1.625 <= real_LAR <= 1.625
- */
-{
- register word temp;
- register int i;
-
-
- /* Computation of the LAR[0..7] from the r[0..7]
- */
- for (i = 1; i <= 8; i++, r++) {
-
- temp = *r;
- temp = GSM_ABS(temp);
- assert(temp >= 0);
-
- if (temp < 22118) {
- temp >>= 1;
- } else if (temp < 31130) {
- assert( temp >= 11059 );
- temp -= 11059;
- } else {
- assert( temp >= 26112 );
- temp -= 26112;
- temp <<= 2;
- }
-
- *r = *r < 0 ? -temp : temp;
- assert( *r != MIN_WORD );
- }
-}
-
-/* 4.2.7 */
-
-static void Quantization_and_coding P1((LAR),
- register word * LAR /* [0..7] IN/OUT */
-)
-{
- register word temp;
-
-
- /* This procedure needs four tables; the following equations
- * give the optimum scaling for the constants:
- *
- * A[0..7] = integer( real_A[0..7] * 1024 )
- * B[0..7] = integer( real_B[0..7] * 512 )
- * MAC[0..7] = maximum of the LARc[0..7]
- * MIC[0..7] = minimum of the LARc[0..7]
- */
-
-# undef STEP
-# define STEP( A, B, MAC, MIC ) \
- temp = (word)GSM_MULT( A, *LAR ); \
- temp = GSM_ADD( temp, B ); \
- temp = GSM_ADD( temp, 256 ); \
- temp = (word)SASR( temp, 9 ); \
- *LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
- LAR++;
-
- STEP( 20480, 0, 31, -32 );
- STEP( 20480, 0, 31, -32 );
- STEP( 20480, 2048, 15, -16 );
- STEP( 20480, -2560, 15, -16 );
-
- STEP( 13964, 94, 7, -8 );
- STEP( 15360, -1792, 7, -8 );
- STEP( 8534, -341, 3, -4 );
- STEP( 9036, -1144, 3, -4 );
-
-# undef STEP
-}
-
-void Gsm_LPC_Analysis P3((S, s,LARc),
- struct gsm_state *S,
- word * s, /* 0..159 signals IN/OUT */
- word * LARc) /* 0..7 LARc's OUT */
-{
- longword L_ACF[9];
-
-#if defined(USE_FLOAT_MUL) && defined(FAST)
- if (S->fast) Fast_Autocorrelation (s, L_ACF );
- else
-#endif
- Autocorrelation (s, L_ACF );
- Reflection_coefficients (L_ACF, LARc );
- Transformation_to_Log_Area_Ratios (LARc);
- Quantization_and_coding (LARc);
-}
diff --git a/1.4/codecs/gsm/src/preprocess.c b/1.4/codecs/gsm/src/preprocess.c
deleted file mode 100644
index eacdac851..000000000
--- a/1.4/codecs/gsm/src/preprocess.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION
- *
- * After A-law to linear conversion (or directly from the
- * Ato D converter) the following scaling is assumed for
- * input to the RPE-LTP algorithm:
- *
- * in: 0.1.....................12
- * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
- *
- * Where S is the sign bit, v a valid bit, and * a "don't care" bit.
- * The original signal is called sop[..]
- *
- * out: 0.1................... 12
- * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
- */
-
-
-void Gsm_Preprocess P3((S, s, so),
- struct gsm_state * S,
- word * s,
- word * so ) /* [0..159] IN/OUT */
-{
- word z1 = S->z1;
- longword L_z2 = S->L_z2;
- word mp = S->mp;
- word s1;
- word SO;
- ulongword utmp; /* for L_ADD */
- register int k = 160;
-
- (void) utmp;
-
- while (k--) {
-
- /* 4.2.1 Downscaling of the input signal
- */
- /* SO = SASR( *s, 3 ) << 2;*/
- SO = SASR( *s, 1 ) & ~3;
- s++;
-
- assert (SO >= -0x4000); /* downscaled by */
- assert (SO <= 0x3FFC); /* previous routine. */
-
-
- /* 4.2.2 Offset compensation
- *
- * This part implements a high-pass filter and requires extended
- * arithmetic precision for the recursive part of this filter.
- * The input of this procedure is the array so[0...159] and the
- * output the array sof[ 0...159 ].
- */
- /* Compute the non-recursive part
- */
-
- s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */
- z1 = SO;
-
- assert(s1 != MIN_WORD);
-
- /* SJB Remark: float might be faster than the mess that follows */
-
- /* Compute the recursive part
- */
-
- /* Execution of a 31 bv 16 bits multiplication
- */
- {
- word msp;
-#ifndef __GNUC__
- word lsp;
-#endif
- longword L_s2;
- longword L_temp;
-
- L_s2 = s1;
- L_s2 <<= 15;
-#ifndef __GNUC__
- msp = (word)SASR( L_z2, 15 );
- lsp = (word)(L_z2 & 0x7fff); /* gsm_L_sub(L_z2,(msp<<15)); */
-
- L_s2 += GSM_MULT_R( lsp, 32735 );
- L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
- L_z2 = GSM_L_ADD( L_temp, L_s2 );
- /* above does L_z2 = L_z2 * 0x7fd5/0x8000 + L_s2 */
-#else
- L_z2 = ((long long)L_z2*32735 + 0x4000)>>15;
- /* alternate (ansi) version of above line does slightly different rounding:
- * L_temp = L_z2 >> 9;
- * L_temp += L_temp >> 5;
- * L_temp = (++L_temp) >> 1;
- * L_z2 = L_z2 - L_temp;
- */
- L_z2 = GSM_L_ADD(L_z2,L_s2);
-#endif
- /* Compute sof[k] with rounding
- */
- L_temp = GSM_L_ADD( L_z2, 16384 );
-
- /* 4.2.3 Preemphasis
- */
-
- msp = (word)GSM_MULT_R( mp, -28180 );
- mp = (word)SASR( L_temp, 15 );
- *so++ = GSM_ADD( mp, msp );
- }
- }
-
- S->z1 = z1;
- S->L_z2 = L_z2;
- S->mp = mp;
-}
diff --git a/1.4/codecs/gsm/src/rpe.c b/1.4/codecs/gsm/src/rpe.c
deleted file mode 100644
index 1c354795d..000000000
--- a/1.4/codecs/gsm/src/rpe.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-
-/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION
- */
-
-/* 4.2.13 */
-#ifdef K6OPT
-#include "k6opt.h"
-#else
-static void Weighting_filter P2((e, x),
- register word * e, /* signal [-5..0.39.44] IN */
- word * x /* signal [0..39] OUT */
-)
-/*
- * The coefficients of the weighting filter are stored in a table
- * (see table 4.4). The following scaling is used:
- *
- * H[0..10] = integer( real_H[ 0..10] * 8192 );
- */
-{
- /* word wt[ 50 ]; */
-
- register longword L_result;
- register int k /* , i */ ;
-
- /* Initialization of a temporary working array wt[0...49]
- */
-
- /* for (k = 0; k <= 4; k++) wt[k] = 0;
- * for (k = 5; k <= 44; k++) wt[k] = *e++;
- * for (k = 45; k <= 49; k++) wt[k] = 0;
- *
- * (e[-5..-1] and e[40..44] are allocated by the caller,
- * are initially zero and are not written anywhere.)
- */
- e -= 5;
-
- /* Compute the signal x[0..39]
- */
- for (k = 0; k <= 39; k++) {
-
- L_result = 8192 >> 1;
-
- /* for (i = 0; i <= 10; i++) {
- * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] );
- * L_result = GSM_L_ADD( L_result, L_temp );
- * }
- */
-
-#undef STEP
-#define STEP( i, H ) (e[ k + i ] * (longword)H)
-
- /* Every one of these multiplications is done twice --
- * but I don't see an elegant way to optimize this.
- * Do you?
- */
-
-#ifdef STUPID_COMPILER
- L_result += STEP( 0, -134 ) ;
- L_result += STEP( 1, -374 ) ;
- /* + STEP( 2, 0 ) */
- L_result += STEP( 3, 2054 ) ;
- L_result += STEP( 4, 5741 ) ;
- L_result += STEP( 5, 8192 ) ;
- L_result += STEP( 6, 5741 ) ;
- L_result += STEP( 7, 2054 ) ;
- /* + STEP( 8, 0 ) */
- L_result += STEP( 9, -374 ) ;
- L_result += STEP( 10, -134 ) ;
-#else
- L_result +=
- STEP( 0, -134 )
- + STEP( 1, -374 )
- /* + STEP( 2, 0 ) */
- + STEP( 3, 2054 )
- + STEP( 4, 5741 )
- + STEP( 5, 8192 )
- + STEP( 6, 5741 )
- + STEP( 7, 2054 )
- /* + STEP( 8, 0 ) */
- + STEP( 9, -374 )
- + STEP(10, -134 )
- ;
-#endif
-
- /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
- * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
- *
- * x[k] = SASR( L_result, 16 );
- */
-
- /* 2 adds vs. >>16 => 14, minus one shift to compensate for
- * those we lost when replacing L_MULT by '*'.
- */
-
- L_result = SASR( L_result, 13 );
- x[k] = (word)( L_result < MIN_WORD ? MIN_WORD
- : (L_result > MAX_WORD ? MAX_WORD : L_result ));
- }
-}
-#endif /* K6OPT */
-
-/* 4.2.14 */
-
-static void RPE_grid_selection P3((x,xM,Mc_out),
- word * x, /* [0..39] IN */
- word * xM, /* [0..12] OUT */
- word * Mc_out /* OUT */
-)
-/*
- * The signal x[0..39] is used to select the RPE grid which is
- * represented by Mc.
- */
-{
- /* register word temp1; */
- register int /* m, */ i;
- register longword L_result, L_temp;
- longword EM; /* xxx should be L_EM? */
- word Mc;
-
- longword L_common_0_3;
-
- EM = 0;
- Mc = 0;
-
- /* for (m = 0; m <= 3; m++) {
- * L_result = 0;
- *
- *
- * for (i = 0; i <= 12; i++) {
- *
- * temp1 = SASR( x[m + 3*i], 2 );
- *
- * assert(temp1 != MIN_WORD);
- *
- * L_temp = GSM_L_MULT( temp1, temp1 );
- * L_result = GSM_L_ADD( L_temp, L_result );
- * }
- *
- * if (L_result > EM) {
- * Mc = m;
- * EM = L_result;
- * }
- * }
- */
-
-#undef STEP
-#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \
- L_result += L_temp * L_temp;
-
- /* common part of 0 and 3 */
-
- L_result = 0;
- STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
- STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
- STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
- L_common_0_3 = L_result;
-
- /* i = 0 */
-
- STEP( 0, 0 );
- L_result <<= 1; /* implicit in L_MULT */
- EM = L_result;
-
- /* i = 1 */
-
- L_result = 0;
- STEP( 1, 0 );
- STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
- STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
- STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
- L_result <<= 1;
- if (L_result > EM) {
- Mc = 1;
- EM = L_result;
- }
-
- /* i = 2 */
-
- L_result = 0;
- STEP( 2, 0 );
- STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
- STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
- STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
- L_result <<= 1;
- if (L_result > EM) {
- Mc = 2;
- EM = L_result;
- }
-
- /* i = 3 */
-
- L_result = L_common_0_3;
- STEP( 3, 12 );
- L_result <<= 1;
- if (L_result > EM) {
- Mc = 3;
- EM = L_result;
- }
-
- /**/
-
- /* Down-sampling by a factor 3 to get the selected xM[0..12]
- * RPE sequence.
- */
- for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
- *Mc_out = Mc;
-}
-
-/* 4.12.15 */
-
-static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),
- word xmaxc, /* IN */
- word * exp_out, /* OUT */
- word * mant_out ) /* OUT */
-{
- word exp, mant;
-
- /* Compute exponent and mantissa of the decoded version of xmaxc
- */
-
- exp = 0;
- if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
- mant = xmaxc - (exp << 3);
-
- if (mant == 0) {
- exp = -4;
- mant = 7;
- }
- else {
- while (mant <= 7) {
- mant = mant << 1 | 1;
- exp--;
- }
- mant -= 8;
- }
-
- assert( exp >= -4 && exp <= 6 );
- assert( mant >= 0 && mant <= 7 );
-
- *exp_out = exp;
- *mant_out = mant;
-}
-
-static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
- word * xM, /* [0..12] IN */
-
- word * xMc, /* [0..12] OUT */
- word * mant_out, /* OUT */
- word * exp_out, /* OUT */
- word * xmaxc_out /* OUT */
-)
-{
- int i, itest;
-
- word xmax, xmaxc, temp, temp1, temp2;
- word exp, mant;
-
-
- /* Find the maximum absolute value xmax of xM[0..12].
- */
-
- xmax = 0;
- for (i = 0; i <= 12; i++) {
- temp = xM[i];
- temp = GSM_ABS(temp);
- if (temp > xmax) xmax = temp;
- }
-
- /* Qantizing and coding of xmax to get xmaxc.
- */
-
- exp = 0;
- temp = SASR( xmax, 9 );
- itest = 0;
-
- for (i = 0; i <= 5; i++) {
-
- itest |= (temp <= 0);
- temp = SASR( temp, 1 );
-
- assert(exp <= 5);
- if (itest == 0) exp++; /* exp = add (exp, 1) */
- }
-
- assert(exp <= 6 && exp >= 0);
- temp = exp + 5;
-
- assert(temp <= 11 && temp >= 0);
- xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
-
- /* Quantizing and coding of the xM[0..12] RPE sequence
- * to get the xMc[0..12]
- */
-
- APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
-
- /* This computation uses the fact that the decoded version of xmaxc
- * can be calculated by using the exponent and the mantissa part of
- * xmaxc (logarithmic table).
- * So, this method avoids any division and uses only a scaling
- * of the RPE samples by a function of the exponent. A direct
- * multiplication by the inverse of the mantissa (NRFAC[0..7]
- * found in table 4.5) gives the 3 bit coded version xMc[0..12]
- * of the RPE samples.
- */
-
-
- /* Direct computation of xMc[0..12] using table 4.5
- */
-
- assert( exp <= 4096 && exp >= -4096);
- assert( mant >= 0 && mant <= 7 );
-
- temp1 = 6 - exp; /* normalization by the exponent */
- temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */
-
- for (i = 0; i <= 12; i++) {
-
- assert(temp1 >= 0 && temp1 < 16);
-
- temp = xM[i] << temp1;
- temp = (word)GSM_MULT( temp, temp2 );
- temp = SASR(temp, 12);
- xMc[i] = temp + 4; /* see note below */
- }
-
- /* NOTE: This equation is used to make all the xMc[i] positive.
- */
-
- *mant_out = mant;
- *exp_out = exp;
- *xmaxc_out = xmaxc;
-}
-
-/* 4.2.16 */
-
-static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
- register word * xMc, /* [0..12] IN */
- word mant,
- word exp,
- register word * xMp) /* [0..12] OUT */
-/*
- * This part is for decoding the RPE sequence of coded xMc[0..12]
- * samples to obtain the xMp[0..12] array. Table 4.6 is used to get
- * the mantissa of xmaxc (FAC[0..7]).
- */
-{
- int i;
- word temp, temp1, temp2, temp3;
-
- assert( mant >= 0 && mant <= 7 );
-
- temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */
- temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */
- temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
-
- for (i = 13; i--;) {
-
- assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */
-
- /* temp = gsm_sub( *xMc++ << 1, 7 ); */
- temp = (*xMc++ << 1) - 7; /* restore sign */
- assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */
-
- temp <<= 12; /* 16 bit signed */
- temp = (word)GSM_MULT_R( temp1, temp );
- temp = GSM_ADD( temp, temp3 );
- *xMp++ = gsm_asr( temp, temp2 );
- }
-}
-
-/* 4.2.17 */
-
-static void RPE_grid_positioning P3((Mc,xMp,ep),
- word Mc, /* grid position IN */
- register word * xMp, /* [0..12] IN */
- register word * ep /* [0..39] OUT */
-)
-/*
- * This procedure computes the reconstructed long term residual signal
- * ep[0..39] for the LTP analysis filter. The inputs are the Mc
- * which is the grid position selection and the xMp[0..12] decoded
- * RPE samples which are upsampled by a factor of 3 by inserting zero
- * values.
- */
-{
- int i = 13;
-
- assert(0 <= Mc && Mc <= 3);
-
- switch (Mc) {
- case 3: *ep++ = 0;
- case 2: do {
- *ep++ = 0;
- case 1: *ep++ = 0;
- case 0: *ep++ = *xMp++;
- } while (--i);
- }
- while (++Mc < 4) *ep++ = 0;
-
- /*
-
- int i, k;
- for (k = 0; k <= 39; k++) ep[k] = 0;
- for (i = 0; i <= 12; i++) {
- ep[ Mc + (3*i) ] = xMp[i];
- }
- */
-}
-
-/* 4.2.18 */
-
-/* This procedure adds the reconstructed long term residual signal
- * ep[0..39] to the estimated signal dpp[0..39] from the long term
- * analysis filter to compute the reconstructed short term residual
- * signal dp[-40..-1]; also the reconstructed short term residual
- * array dp[-120..-41] is updated.
- */
-
-#if 0 /* Has been inlined in code.c */
-void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),
- word * dpp, /* [0...39] IN */
- word * ep, /* [0...39] IN */
- word * dp) /* [-120...-1] IN/OUT */
-{
- int k;
-
- for (k = 0; k <= 79; k++)
- dp[ -120 + k ] = dp[ -80 + k ];
-
- for (k = 0; k <= 39; k++)
- dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
-}
-#endif /* Has been inlined in code.c */
-
-void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),
-
- struct gsm_state * S,
-
- word * e, /* -5..-1][0..39][40..44 IN/OUT */
- word * xmaxc, /* OUT */
- word * Mc, /* OUT */
- word * xMc) /* [0..12] OUT */
-{
- word x[40];
- word xM[13], xMp[13];
- word mant, exp;
-
- Weighting_filter(e, x);
- RPE_grid_selection(x, xM, Mc);
-
- APCM_quantization( xM, xMc, &mant, &exp, xmaxc);
- APCM_inverse_quantization( xMc, mant, exp, xMp);
-
- RPE_grid_positioning( *Mc, xMp, e );
-
-}
-
-void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
- struct gsm_state * S,
-
- word xmaxcr,
- word Mcr,
- word * xMcr, /* [0..12], 3 bits IN */
- word * erp /* [0..39] OUT */
-)
-{
- word exp, mant;
- word xMp[ 13 ];
-
- APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
- APCM_inverse_quantization( xMcr, mant, exp, xMp );
- RPE_grid_positioning( Mcr, xMp, erp );
-
-}
diff --git a/1.4/codecs/gsm/src/short_term.c b/1.4/codecs/gsm/src/short_term.c
deleted file mode 100644
index 43c592c04..000000000
--- a/1.4/codecs/gsm/src/short_term.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "private.h"
-
-#include "gsm.h"
-#include "proto.h"
-#ifdef K6OPT
-#include "k6opt.h"
-
-#define Short_term_analysis_filtering Short_term_analysis_filteringx
-
-#endif
-/*
- * SHORT TERM ANALYSIS FILTERING SECTION
- */
-
-/* 4.2.8 */
-
-static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),
- word * LARc, /* coded log area ratio [0..7] IN */
- word * LARpp) /* out: decoded .. */
-{
- register word temp1 /* , temp2 */;
-
- /* This procedure requires for efficient implementation
- * two tables.
- *
- * INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
- * MIC[1..8] = minimum value of the LARc[1..8]
- */
-
- /* Compute the LARpp[1..8]
- */
-
- /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
- *
- * temp1 = GSM_ADD( *LARc, *MIC ) << 10;
- * temp2 = *B << 1;
- * temp1 = GSM_SUB( temp1, temp2 );
- *
- * assert(*INVA != MIN_WORD);
- *
- * temp1 = GSM_MULT_R( *INVA, temp1 );
- * *LARpp = GSM_ADD( temp1, temp1 );
- * }
- */
-
-#undef STEP
-#define STEP( B, MIC, INVA ) \
- temp1 = GSM_ADD( *LARc++, MIC ) << 10; \
- temp1 = GSM_SUB( temp1, B << 1 ); \
- temp1 = (word)GSM_MULT_R( INVA, temp1 ); \
- *LARpp++ = GSM_ADD( temp1, temp1 );
-
- STEP( 0, -32, 13107 );
- STEP( 0, -32, 13107 );
- STEP( 2048, -16, 13107 );
- STEP( -2560, -16, 13107 );
-
- STEP( 94, -8, 19223 );
- STEP( -1792, -8, 17476 );
- STEP( -341, -4, 31454 );
- STEP( -1144, -4, 29708 );
-
- /* NOTE: the addition of *MIC is used to restore
- * the sign of *LARc.
- */
-}
-
-/* 4.2.9 */
-/* Computation of the quantized reflection coefficients
- */
-
-/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8]
- */
-
-/*
- * Within each frame of 160 analyzed speech samples the short term
- * analysis and synthesis filters operate with four different sets of
- * coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
- * and the actual set of decoded LARs (LARpp(j))
- *
- * (Initial value: LARpp(j-1)[1..8] = 0.)
- */
-
-static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp),
- register word * LARpp_j_1,
- register word * LARpp_j,
- register word * LARp)
-{
- register int i;
-
- for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
- *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
- *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1));
- }
-}
-
-static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),
- register word * LARpp_j_1,
- register word * LARpp_j,
- register word * LARp)
-{
- register int i;
- for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
- *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));
- }
-}
-
-static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),
- register word * LARpp_j_1,
- register word * LARpp_j,
- register word * LARp)
-{
- register int i;
-
- for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
- *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
- *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));
- }
-}
-
-
-static void Coefficients_40_159 P2((LARpp_j, LARp),
- register word * LARpp_j,
- register word * LARp)
-{
- register int i;
-
- for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
- *LARp = *LARpp_j;
-}
-
-/* 4.2.9.2 */
-
-static void LARp_to_rp P1((LARp),
- register word * LARp) /* [0..7] IN/OUT */
-/*
- * The input of this procedure is the interpolated LARp[0..7] array.
- * The reflection coefficients, rp[i], are used in the analysis
- * filter and in the synthesis filter.
- */
-{
- register int i;
- register word temp;
-
- for (i = 1; i <= 8; i++, LARp++) {
-
- /* temp = GSM_ABS( *LARp );
- *
- * if (temp < 11059) temp <<= 1;
- * else if (temp < 20070) temp += 11059;
- * else temp = GSM_ADD( temp >> 2, 26112 );
- *
- * *LARp = *LARp < 0 ? -temp : temp;
- */
-
- if (*LARp < 0) {
- temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
- *LARp = - ((temp < 11059) ? temp << 1
- : ((temp < 20070) ? temp + 11059
- : GSM_ADD( temp >> 2, 26112 )));
- } else {
- temp = *LARp;
- *LARp = (temp < 11059) ? temp << 1
- : ((temp < 20070) ? temp + 11059
- : GSM_ADD( temp >> 2, 26112 ));
- }
- }
-}
-
-
-/* 4.2.10 */
-#ifndef Short_term_analysis_filtering
-
-/* SJB Remark:
- * I tried 2 MMX versions of this function, neither is significantly
- * faster than the C version which follows. MMX might be useful if
- * one were processing 2 input streams in parallel.
- */
-static void Short_term_analysis_filtering P4((u0,rp0,k_n,s),
- register word * u0,
- register word * rp0, /* [0..7] IN */
- register int k_n, /* k_end - k_start */
- register word * s /* [0..n-1] IN/OUT */
-)
-/*
- * This procedure computes the short term residual signal d[..] to be fed
- * to the RPE-LTP loop from the s[..] signal and from the local rp[..]
- * array (quantized reflection coefficients). As the call of this
- * procedure can be done in many ways (see the interpolation of the LAR
- * coefficient), it is assumed that the computation begins with index
- * k_start (for arrays d[..] and s[..]) and stops with index k_end
- * (k_start and k_end are defined in 4.2.9.1). This procedure also
- * needs to keep the array u0[0..7] in memory for each call.
- */
-{
- register word * u_top = u0 + 8;
- register word * s_top = s + k_n;
-
- while (s < s_top) {
- register word *u, *rp ;
- register longword di, u_out;
- di = u_out = *s;
- for (rp=rp0, u=u0; u<u_top;) {
- register longword ui, rpi;
- ui = *u;
- *u++ = (word)u_out;
- rpi = *rp++;
- u_out = ui + (((rpi*di)+0x4000)>>15);
- di = di + (((rpi*ui)+0x4000)>>15);
- /* make the common case fastest: */
- if ((u_out == (word)u_out) && (di == (word)di)) continue;
- /* otherwise do slower fixup (saturation) */
- if (u_out>MAX_WORD) u_out=MAX_WORD;
- else if (u_out<MIN_WORD) u_out=MIN_WORD;
- if (di>MAX_WORD) di=MAX_WORD;
- else if (di<MIN_WORD) di=MIN_WORD;
- }
- *s++ = (word)di;
- }
-}
-#endif
-
-#if defined(USE_FLOAT_MUL) && defined(FAST)
-
-static void Fast_Short_term_analysis_filtering P4((u,rp,k_n,s),
- register word * u;
- register word * rp, /* [0..7] IN */
- register int k_n, /* k_end - k_start */
- register word * s /* [0..n-1] IN/OUT */
-)
-{
- register int i;
-
- float uf[8],
- rpf[8];
-
- register float scalef = 3.0517578125e-5;
- register float sav, di, temp;
-
- for (i = 0; i < 8; ++i) {
- uf[i] = u[i];
- rpf[i] = rp[i] * scalef;
- }
- for (; k_n--; s++) {
- sav = di = *s;
- for (i = 0; i < 8; ++i) {
- register float rpfi = rpf[i];
- register float ufi = uf[i];
-
- uf[i] = sav;
- temp = rpfi * di + ufi;
- di += rpfi * ufi;
- sav = temp;
- }
- *s = di;
- }
- for (i = 0; i < 8; ++i) u[i] = uf[i];
-}
-#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
-
-/*
- * SJB Remark: modified Short_term_synthesis_filtering() below
- * for significant (abt 35%) speedup of decompression.
- * (gcc-2.95, k6 cpu)
- * Please don't change this without benchmarking decompression
- * to see that you haven't harmed speed.
- * This function burns most of CPU time for untoasting.
- * Unfortunately, didn't see any good way to benefit from mmx.
- */
-static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
- struct gsm_state * S,
- register word * rrp, /* [0..7] IN */
- register int k, /* k_end - k_start */
- register word * wt, /* [0..k-1] IN */
- register word * sr /* [0..k-1] OUT */
-)
-{
- register word * v = S->v;
- register int i;
- register longword sri;
-
- while (k--) {
- sri = *wt++;
- for (i = 8; i--;) {
- register longword tmp1, tmp2;
-
- /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
- */
- tmp1 = rrp[i];
- tmp2 = v[i];
-
- tmp2 = (( tmp1 * tmp2 + 16384) >> 15) ;
- /* saturation done below */
- sri -= tmp2;
- if (sri != (word)sri) {
- sri = (sri<0)? MIN_WORD:MAX_WORD;
- }
- /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
- */
-
- tmp1 = (( tmp1 * sri + 16384) >> 15) ;
- /* saturation done below */
- tmp1 += v[i];
- if (tmp1 != (word)tmp1) {
- tmp1 = (tmp1<0)? MIN_WORD:MAX_WORD;
- }
- v[i+1] = (word)tmp1;
- }
- *sr++ = v[0] = (word)sri;
- }
-}
-
-
-#if defined(FAST) && defined(USE_FLOAT_MUL)
-
-static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
- struct gsm_state * S,
- register word * rrp, /* [0..7] IN */
- register int k, /* k_end - k_start */
- register word * wt, /* [0..k-1] IN */
- register word * sr /* [0..k-1] OUT */
-)
-{
- register word * v = S->v;
- register int i;
-
- float va[9], rrpa[8];
- register float scalef = 3.0517578125e-5, temp;
-
- for (i = 0; i < 8; ++i) {
- va[i] = v[i];
- rrpa[i] = (float)rrp[i] * scalef;
- }
- while (k--) {
- register float sri = *wt++;
- for (i = 8; i--;) {
- sri -= rrpa[i] * va[i];
- if (sri < -32768.) sri = -32768.;
- else if (sri > 32767.) sri = 32767.;
-
- temp = va[i] + rrpa[i] * sri;
- if (temp < -32768.) temp = -32768.;
- else if (temp > 32767.) temp = 32767.;
- va[i+1] = temp;
- }
- *sr++ = va[0] = sri;
- }
- for (i = 0; i < 9; ++i) v[i] = va[i];
-}
-
-#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
-
-void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),
-
- struct gsm_state * S,
-
- word * LARc, /* coded log area ratio [0..7] IN */
- word * s /* signal [0..159] IN/OUT */
-)
-{
- word * LARpp_j = S->LARpp[ S->j ];
- word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ];
-
- word LARp[8];
-
-#undef FILTER
-#if defined(FAST) && defined(USE_FLOAT_MUL)
-# define FILTER (* (S->fast \
- ? Fast_Short_term_analysis_filtering \
- : Short_term_analysis_filtering ))
-
-#else
-# define FILTER Short_term_analysis_filtering
-#endif
-
- Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
-
- Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
- LARp_to_rp( LARp );
- FILTER( S->u, LARp, 13, s);
-
- Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
- LARp_to_rp( LARp );
- FILTER( S->u, LARp, 14, s + 13);
-
- Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
- LARp_to_rp( LARp );
- FILTER( S->u, LARp, 13, s + 27);
-
- Coefficients_40_159( LARpp_j, LARp);
- LARp_to_rp( LARp );
- FILTER( S->u, LARp, 120, s + 40);
-
-}
-
-void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),
- struct gsm_state * S,
-
- word * LARcr, /* received log area ratios [0..7] IN */
- word * wt, /* received d [0..159] IN */
-
- word * s /* signal s [0..159] OUT */
-)
-{
- word * LARpp_j = S->LARpp[ S->j ];
- word * LARpp_j_1 = S->LARpp[ S->j ^=1 ];
-
- word LARp[8];
-
-#undef FILTER
-#if defined(FAST) && defined(USE_FLOAT_MUL)
-
-# define FILTER (* (S->fast \
- ? Fast_Short_term_synthesis_filtering \
- : Short_term_synthesis_filtering ))
-#else
-# define FILTER Short_term_synthesis_filtering
-#endif
-
- Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
-
- Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
- LARp_to_rp( LARp );
- FILTER( S, LARp, 13, wt, s );
-
- Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
- LARp_to_rp( LARp );
- FILTER( S, LARp, 14, wt + 13, s + 13 );
-
- Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
- LARp_to_rp( LARp );
- FILTER( S, LARp, 13, wt + 27, s + 27 );
-
- Coefficients_40_159( LARpp_j, LARp );
- LARp_to_rp( LARp );
- FILTER(S, LARp, 120, wt + 40, s + 40);
-}
diff --git a/1.4/codecs/gsm/src/table.c b/1.4/codecs/gsm/src/table.c
deleted file mode 100644
index 16a04118c..000000000
--- a/1.4/codecs/gsm/src/table.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
- */
-
-/* $Header$ */
-
-/* Most of these tables are inlined at their point of use.
- */
-
-/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
- * CODER AND DECODER
- *
- * (Most of them inlined, so watch out.)
- */
-
-#define GSM_TABLE_C
-#include "private.h"
-#include "gsm.h"
-
-/* Table 4.1 Quantization of the Log.-Area Ratios
- */
-/* i 1 2 3 4 5 6 7 8 */
-word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036};
-word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144};
-word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 };
-word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 };
-
-
-/* Table 4.2 Tabulation of 1/A[1..8]
- */
-word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 };
-
-
-/* Table 4.3a Decision level of the LTP gain quantizer
- */
-/* bc 0 1 2 3 */
-word gsm_DLB[4] = { 6554, 16384, 26214, 32767 };
-
-
-/* Table 4.3b Quantization levels of the LTP gain quantizer
- */
-/* bc 0 1 2 3 */
-word gsm_QLB[4] = { 3277, 11469, 21299, 32767 };
-
-
-/* Table 4.4 Coefficients of the weighting filter
- */
-/* i 0 1 2 3 4 5 6 7 8 9 10 */
-word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
-
-
-/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax
- */
-/* i 0 1 2 3 4 5 6 7 */
-word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
-
-
-/* Table 4.6 Normalized direct mantissa used to compute xM/xmax
- */
-/* i 0 1 2 3 4 5 6 7 */
-word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
diff --git a/1.4/codecs/gsm_slin_ex.h b/1.4/codecs/gsm_slin_ex.h
deleted file mode 100644
index 2f001abec..000000000
--- a/1.4/codecs/gsm_slin_ex.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*! \file
- * \brief 8-bit raw data
- *
- * Source: gsm.example
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char gsm_slin_ex[] = {
-0xda, 0xa6, 0xac, 0x2d, 0xa3, 0x50, 000, 0x49, 0x24, 0x92,
-0x49, 0x24, 0x50, 0x40, 0x49, 0x24, 0x92, 0x37, 0x24, 0x52,
-000, 0x49, 0x24, 0x92, 0x47, 0x24, 0x50, 0x80, 0x46, 0xe3,
-0x6d, 0xb8, 0xdc };
diff --git a/1.4/codecs/ilbc/Makefile b/1.4/codecs/ilbc/Makefile
deleted file mode 100644
index 51e2ae249..000000000
--- a/1.4/codecs/ilbc/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-LIB=libilbc.a
-CFLAGS+=-fPIC
-
-OBJS=anaFilter.o iCBSearch.o packing.o \
- constants.o gainquant.o iLBC_decode.o StateConstructW.o \
- createCB.o getCBvec.o iLBC_encode.o StateSearchW.o doCPLC.o \
- helpfun.o syntFilter.o enhancer.o hpInput.o LPCdecode.o \
- filter.o hpOutput.o LPCencode.o FrameClassify.o iCBConstruct.o lsf.o
-
-include $(ASTTOPDIR)/Makefile.rules
-
-all: $(LIB)
-
-$(LIB): $(OBJS)
- $(ECHO_PREFIX) echo " [AR] $^ -> $@"
- $(CMD_PREFIX) $(AR) cr $@ $^
- $(CMD_PREFIX) $(RANLIB) $@
-
-clean:
- rm -f $(LIB) *.o .*.d *.s *.i
diff --git a/1.4/codecs/ilbc_slin_ex.h b/1.4/codecs/ilbc_slin_ex.h
deleted file mode 100644
index b9f4bd4e8..000000000
--- a/1.4/codecs/ilbc_slin_ex.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*! \file
- * \brief Raw 8-bit data
- *
- * Source: ilbc.out
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char ilbc_slin_ex[] = {
-0xff, 0xa0, 0xff, 0xfa, 0xf, 0x60, 0x12, 0x11, 0xa2, 0x47,
-0x22, 0x8c, 00, 00, 0x1, 0x2, 0x80, 0x43, 0xa0, 0x40,
-0x33, 0xff, 0xcf, 0xc0, 0xf3, 0xf3, 0x3f, 0x8f, 0x3f, 0xff,
-0xff, 0xff, 0xff, 0xfc, 0xf9, 0xe5, 0x55, 0x78, 0xb, 0xca,
-0xe1, 0x27, 0x94, 0x7b, 0xa8, 0x91, 0x2c, 0x36, 0x8, 0x56 };
diff --git a/1.4/codecs/log2comp.h b/1.4/codecs/log2comp.h
deleted file mode 100644
index aa397c858..000000000
--- a/1.4/codecs/log2comp.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*! \file
- * \brief log2comp.h - various base 2 log computation versions
- *
- * Asterisk -- A telephony toolkit for Linux.
- *
- * \author Alex Volkov <codepro@usa.net>
- *
- * Copyright (c) 2004 - 2005, Digium Inc.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- *
- * Define WANT_ASM before including this file to use assembly
- * whenever possible
- */
-
-#if defined(_MSC_VER)
-# define inline __inline
-#elif defined(__GNUC__)
-# define inline __inline__
-#else
-# define inline
-#endif
-
-#if defined(WANT_ASM) && defined(_MSC_VER) && defined(_M_IX86)
-/* MS C Inline Asm */
-# pragma warning( disable : 4035 )
-static inline int ilog2(int val) { __asm
-{
- xor eax, eax
- dec eax
- bsr eax, val
-}}
-# pragma warning( default : 4035 )
-#elif defined(WANT_ASM) && defined(__GNUC__) && (defined(__i386__) || defined(i386))
-/* GNU Inline Asm */
-static inline int ilog2(int val)
-{
- int a;
- __asm__
- ("\
- xorl %0, %0 ;\
- decl %0 ;\
- bsrl %1, %0 ;\
- "
- : "=&r" (a)
- : "mr" (val)
- : "cc"
- );
- return a;
-}
-#elif defined(WANT_ASM) && defined(__GNUC__) && defined(__powerpc__)
-static inline int ilog2(int val)
-{
- int a;
- __asm__ ("cntlzw %0,%1"
- : "=r" (a)
- : "r" (val)
- );
- return 31-a;
-}
-#else
-/* no ASM for this compiler and/or platform */
-/* rather slow base 2 log computation
- * Using looped shift.
- */
-static inline int ilog2(int val)
-{
- int i;
- for (i = -1; val; ++i, val >>= 1)
- ;
- return (i);
-}
-#endif
diff --git a/1.4/codecs/lpc10/Makefile b/1.4/codecs/lpc10/Makefile
deleted file mode 100644
index bf6a6e08a..000000000
--- a/1.4/codecs/lpc10/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# Makefile for LPC-10 speech coder library (unix)
-#
-
-# default C compiler
-CC?= gcc
-
-#
-# These definitions for CFLAGS and LIB_TARGET_DIR are used when one
-# runs make in the lpc10 directory, without environment variables that
-# override them. When make is run in this directory from a makefile
-# for an application that uses the LPC10 coder, there are environment
-# variables set for CFLAGS and LIB_TARGET_DIR that override these
-# definitions.
-#
-
-LIB_TARGET_DIR = .
-
-#
-# -I$(LIB_TARGET_DIR) option needed so that #include "machine.h"
-# directives can find the machine.h file.
-#
-
-CFLAGS+= -fPIC -Wno-comment
-
-# The code here generates lots of warnings, so compiling with -Werror
-# fails miserably. Remove it for the time being.
-ASTCFLAGS:= $(ASTCFLAGS:-Werror=)
-
-#fix for PPC processors and ALPHA, And UltraSparc too
-ifneq ($(OSARCH),Darwin)
- ifneq ($(findstring BSD,${OSARCH}),BSD)
- ifneq ($(PROC),ppc)
- ifneq ($(PROC),x86_64)
- ifneq ($(PROC),alpha)
-#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
-#This works for even old (2.96) versions of gcc and provides a small boost either way.
-#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesn.t support it.
-#So we go lowest common available by gcc and go a step down, still a step up from
-#the default as we now have a better instruction set to work with. - Belgarath
- ifeq ($(PROC),ultrasparc)
- CFLAGS+= -mtune=$(PROC) -mcpu=v8 -O3 -fomit-frame-pointer
- else
- ifneq ($(OSARCH),SunOS)
- ifneq ($(OSARCH),arm)
-# CFLAGS+= -march=$(PROC)
- endif
- endif
- endif
- endif
- endif
- endif
- endif
-endif
-
-LIB = $(LIB_TARGET_DIR)/liblpc10.a
-
-.PHONY: all clean
-
-include $(ASTTOPDIR)/Makefile.rules
-
-all: $(LIB)
-
-OBJ=f2clib.o analys.o bsynz.o chanwr.o dcbias.o decode.o \
- deemp.o difmag.o dyptrk.o encode.o energy.o ham84.o \
- hp100.o invert.o irc2pc.o ivfilt.o lpcdec.o lpcenc.o \
- lpcini.o lpfilt.o median.o mload.o onset.o pitsyn.o \
- placea.o placev.o preemp.o prepro.o random.o rcchk.o \
- synths.o tbdm.o voicin.o vparms.o
-
-$(LIB): $(OBJ)
- $(ECHO_PREFIX) echo " [AR] $^ -> $@"
- $(CMD_PREFIX) $(AR) cr $@ $^
- $(CMD_PREFIX) $(RANLIB) $@
-
-clean:
- rm -f *.o $(LIB) .*.d *.s *.i
diff --git a/1.4/codecs/lpc10/README b/1.4/codecs/lpc10/README
deleted file mode 100644
index 30abe4c97..000000000
--- a/1.4/codecs/lpc10/README
+++ /dev/null
@@ -1,89 +0,0 @@
-Tue Aug 20 16:19:51 CDT 1996
-Andy Fingerhut (jaf@arl.wustl.edu)
-
-In release 1.4, there are quite a few hand modifications to the C code
-that was automatically created from the Fortran code with f2c. They
-are all summarized in change log comments at the beginning of the
-changed files. All of the original files from f2c were checked in to
-RCS before modification, so it is possible to see exactly what changes
-were made, for the extremely curious. That precaution was also for my
-benefit, in case I ever recompile the Fortran sources, and want to
-make similar changes to that new C source code.
-
-Below is the README file for this directory included with the 1.3
-release of the LPC-10 package. A few parts of it are a little out of
-date, but it is correct for the most part.
-
-
-Sun Jul 7 15:30:31 CDT 1996
-Andy Fingerhut (jaf@arl.wustl.edu)
-
-To create the LPC-10 library, copy the appropriate makefile to the
-proper name for easy use, e.g., for Unix, copy makefile.unx to the
-file "Makefile". The file makefile.dos has been used with some
-version of the 'nmake' utility that comes with the Microsoft C
-compiler (the same one used for Nautilus v1.5a, which I believe
-specifies Microsoft C version 7.0 or later).
-
-Then edit the file lpc10.h in the directory above. It should already
-be set up to work properly on any Unix compiler for which "int" is 32
-bits and "short" is 16 bits, and under the Microsoft C compiler
-configured so that "long" is 32 bits and "int" is 16 bits. There must
-be a typedef for the two types INT32 and INT16 in that file. You
-should choose types that compile to those sizes using your compiler,
-because there are places in the LPC-10 code that expect INT16's to
-have exactly 16 bits (at least, I *think* they must be no larger), and
-INT32's to have exactly 32 bits.
-
-
-A few notes on how these files were created
--------------------------------------------
-
-(This section is mostly for my benefit, so I can remember what I did.
-You don't need to read it if you just want to use this package. It
-might be useful to read it if you change the Fortran sources and want
-to recreate a usable library of C sources. -- Andy)
-
-These C sources were created automatically from the Fortran sources
-using f2c, for the most part. Listed below are the extra
-modifications that were made after this automatic conversion. Many of
-them were made so that it was not necessary to install f2c in order to
-use this LPC-10 coder.
-
-1.
-
-Put all of those files that were necessary for only the coder, rather
-than an application that uses the coder, into this subdirectory called
-lpc10.
-
-2.
-
-Copied f2c.h from the f2c distribution into this subdirectory. Some
-modifications were made to the "typedef" statements in this file, to
-explicitly indicate the sizes (in bits) that different integer types
-should be. The types INT32 and INT16 must be defined in a file called
-lpc10.h in the directory above. Created the file f2clib.c, containing
-only the functions pow_ii(), r_sign(), and i_nint() from the f2c
-library.
-
-3.
-
-The f2c output originally had a file called contrl_com.c, that defined
-a small structure containing a few variables that were used in many
-different functions of the LPC10 code. Every file containing
-functions that used it defined it as "extern", while contrl_com.c
-actually allocated storage for the structure. Bill Dorsey, one of the
-lead developers of Nautilus, said that the Microsoft C compiler had
-problems either compiling this file, or linking it with all of the
-other compiled files, so he just eliminated that file and removed the
-"extern" keyword from the one of the files that declared it that way.
-The file chosen (arbitrarily) was analys.c.
-
-4.
-
-Copied the makefiles for Unix and Microsoft C from the Nautilus v1.5a
-distribution into the lpc10 directory. Modified them to take out
-references to Nautilus. These makefiles don't create an executable,
-but a library of compiled functions called liblpc10.a (Unix) or
-LPC10.LIB (DOS). This library can be used when linking an executable
-that calls the functions lpcini_(), lpcenc_(), and lpcdec_().
diff --git a/1.4/codecs/lpc10/analys.c b/1.4/codecs/lpc10/analys.c
deleted file mode 100644
index 50e95703d..000000000
--- a/1.4/codecs/lpc10/analys.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.2 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:16:01 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:29:08 jaf
- * Initial revision
- *
-
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int analys_(real *speech, integer *voice, integer *pitch, real *rms, real *rc, struct lpc10_encoder_state *st);
-/* comlen contrl_ 12 */
-/*:ref: preemp_ 14 5 6 6 4 6 6 */
-/*:ref: onset_ 14 7 6 4 4 4 4 4 4 */
-/*:ref: placev_ 14 11 4 4 4 4 4 4 4 4 4 4 4 */
-/*:ref: lpfilt_ 14 4 6 6 4 4 */
-/*:ref: ivfilt_ 14 5 6 6 4 4 6 */
-/*:ref: tbdm_ 14 8 6 4 4 4 6 4 4 4 */
-/*:ref: voicin_ 14 12 4 6 6 4 4 6 6 4 6 4 4 4 */
-/*:ref: dyptrk_ 14 6 6 4 4 4 4 4 */
-/*:ref: placea_ 14 9 4 4 4 4 4 4 4 4 4 */
-/*:ref: dcbias_ 14 3 4 6 6 */
-/*:ref: energy_ 14 3 4 6 6 */
-/*:ref: mload_ 14 6 4 4 4 6 6 6 */
-/*:ref: invert_ 14 4 4 6 6 6 */
-/*:ref: rcchk_ 14 3 4 6 6 */
-/*:ref: initonset_ 14 0 */
-/*:ref: initvoicin_ 14 0 */
-/*:ref: initdyptrk_ 14 0 */
-/* Rerunning f2c -P may change prototypes or declarations. */
-#endif
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* Table of constant values */
-
-static integer c__10 = 10;
-static integer c__181 = 181;
-static integer c__720 = 720;
-static integer c__3 = 3;
-static integer c__90 = 90;
-static integer c__156 = 156;
-static integer c__307 = 307;
-static integer c__462 = 462;
-static integer c__312 = 312;
-static integer c__60 = 60;
-static integer c__1 = 1;
-
-/* ****************************************************************** */
-
-/* ANALYS Version 55 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:16:01 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:29:08 jaf
- * Initial revision
- * */
-/* Revision 1.9 1996/05/23 19:41:07 jaf */
-/* Commented out some unnecessary lines that were reading uninitialized */
-/* values. */
-
-/* Revision 1.8 1996/03/27 23:57:55 jaf */
-/* Added some comments about which indices of the local buffers INBUF, */
-/* LPBUF, etc., get read or modified by some of the subroutine calls. I */
-/* just did this while trying to figure out the discrepancy between the */
-/* embedded code compiled with all local variables implicitly saved, and */
-/* without. */
-
-/* I added some debugging write statements in hopes of finding a problem. */
-/* None of them ever printed anything while running with the long input */
-/* speech file dam9.spd provided in the distribution. */
-
-/* Revision 1.7 1996/03/27 18:06:20 jaf */
-/* Commented out access to MAXOSP, which is just a debugging variable */
-/* that was defined in the COMMON block CONTRL in contrl.fh. */
-
-/* Revision 1.6 1996/03/26 19:31:33 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.5 1996/03/21 15:19:35 jaf */
-/* Added comments for ENTRY PITDEC. */
-
-/* Revision 1.4 1996/03/19 20:54:27 jaf */
-/* Added a line to INITANALYS. See comments there. */
-
-/* Revision 1.3 1996/03/19 20:52:49 jaf */
-/* Rearranged the order of the local variables quite a bit, to separate */
-/* them into groups of "constants", "locals that don't need to be saved */
-/* from one call to the next", and "local that do need to be saved from */
-/* one call to the next". */
-
-/* Several locals in the last set should have been given initial values, */
-/* but weren't. I gave them all initial values of 0. */
-
-/* Added a separate ENTRY INITANALYS that initializes all local state */
-/* that should be, and also calls the corresponding entries of the */
-/* subroutines called by ANALYS that also have local state. */
-
-/* There used to be DATA statements in ANALYS. I got rid of most of */
-/* them, and added a local logical variable FIRST that calls the entry */
-/* INITANALYS on the first call to ANALYS. This is just so that one need */
-/* not remember to call INITANALYS first in order for the state to be */
-/* initialized. */
-
-/* Revision 1.2 1996/03/11 23:29:32 jaf */
-/* Added several comments with my own personal questions about the */
-/* Fortran 77 meaning of the parameters passed to the subroutine PREEMP. */
-
-/* Revision 1.1 1996/02/07 14:42:29 jaf */
-/* Initial revision */
-
-
-/* ****************************************************************** */
-
-/* SUBROUTINE ANALYS */
-
-/* Input: */
-/* SPEECH */
-/* Indices 1 through LFRAME read. */
-/* Output: */
-/* VOICE */
-/* Indices 1 through 2 written. */
-/* PITCH */
-/* Written in subroutine DYPTRK, and then perhaps read and written */
-/* some more. */
-/* RMS */
-/* Written. */
-/* RC */
-/* Indices 1 through ORDER written (ORDER defined in contrl.fh). */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITANALYS. */
-
-
-/* ENTRY PITDEC */
-
-/* Input: */
-/* PITCH - Encoded pitch index */
-/* Output: */
-/* PTAU - Decoded pitch period */
-
-/* This entry has no local state. It accesses a "constant" array */
-/* declared in ANALYS. */
-
-/* Subroutine */ int analys_(real *speech, integer *voice, integer
- *pitch, real *rms, real *rc, struct lpc10_encoder_state *st)
-{
- /* Initialized data */
-
- static integer tau[60] = { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
- 35,36,37,38,39,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,
- 74,76,78,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,
- 140,144,148,152,156 };
- static integer buflim[4] = { 181,720,25,720 };
- static real precoef = .9375f;
-
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- real amdf[60];
- integer half;
- real abuf[156];
- real *bias;
- extern /* Subroutine */ int tbdm_(real *, integer *, integer *, integer *,
- real *, integer *, integer *, integer *);
- integer *awin;
- integer midx, ewin[6] /* was [2][3] */;
- real ivrc[2], temp;
- real *zpre;
- integer *vwin;
- integer i__, j, lanal;
- extern /* Subroutine */ int rcchk_(integer *, real *, real *), mload_(
- integer *, integer *, integer *, real *, real *, real *);
- real *inbuf, *pebuf;
- real *lpbuf, *ivbuf;
- real *rcbuf;
- integer *osbuf;
- extern /* Subroutine */ int onset_(real *, integer *, integer *, integer *
- , integer *, integer *, integer *, struct lpc10_encoder_state *);
- integer *osptr;
- extern int dcbias_(integer *, real *, real *);
- integer ipitch;
- integer *obound;
- extern /* Subroutine */ int preemp_(real *, real *, integer *, real *,
- real *), voicin_(integer *, real *, real *, integer *, integer *,
- real *, real *, integer *, real *, integer *, integer *, integer *,
- struct lpc10_encoder_state *);
- integer *voibuf;
- integer mintau;
- real *rmsbuf;
- extern /* Subroutine */ int lpfilt_(real *, real *, integer *, integer *),
- ivfilt_(real *, real *, integer *, integer *, real *), energy_(
- integer *, real *, real *), invert_(integer *, real *, real *,
- real *);
- integer minptr, maxptr;
- extern /* Subroutine */ int dyptrk_(real *, integer *, integer *, integer
- *, integer *, integer *, struct lpc10_encoder_state *);
- real phi[100] /* was [10][10] */, psi[10];
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:16:01 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:29:08 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Arguments to ANALYS */
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:16:01 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:29:08 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Arguments to entry PITDEC (below) */
-/* Parameters/constants */
-/* Constants */
-/* NF = Number of frames */
-/* AF = Frame in which analysis is done */
-/* OSLEN = Length of the onset buffer */
-/* LTAU = Number of pitch lags */
-/* SBUFL, SBUFH = Start and end index of speech buffers */
-/* LBUFL, LBUFH = Start and end index of LPF speech buffer */
-/* MINWIN, MAXWIN = Min and Max length of voicing (and analysis) windows
-*/
-/* PWLEN, PWINH, PWINL = Length, upper and lower limits of pitch window
- */
-/* DVWINL, DVWINH = Default lower and upper limits of voicing window */
-/* The tables TAU and BUFLIM, and the variable PRECOEF, are not */
-/* Fortran PARAMETER's, but they are initialized with DATA */
-/* statements, and never modified. Thus, they need not have SAVE */
-/* statements for them to keep their values from one invocation to
-*/
-/* the next. */
-/* Local variables that need not be saved */
-/* Local state */
-/* Data Buffers */
-/* INBUF Raw speech (with DC bias removed each frame) */
-/* PEBUF Preemphasized speech */
-/* LPBUF Low pass speech buffer */
-/* IVBUF Inverse filtered speech */
-/* OSBUF Indexes of onsets in speech buffers */
-/* VWIN Voicing window indices */
-/* AWIN Analysis window indices */
-/* EWIN Energy window indices */
-/* VOIBUF Voicing decisions on windows in VWIN */
-/* RMSBUF RMS energy */
-/* RCBUF Reflection Coefficients */
-
-/* Pitch is handled separately from the above parameters. */
-/* The following variables deal with pitch: */
-/* MIDX Encoded initial pitch estimate for analysis frame */
-/* IPITCH Initial pitch computed for frame AF (decoded from MIDX) */
-/* PITCH The encoded pitch value (index into TAU) for the present */
-/* frame (delayed and smoothed by Dyptrack) */
- /* Parameter adjustments */
- if (speech) {
- --speech;
- }
- if (voice) {
- --voice;
- }
- if (rc) {
- --rc;
- }
-
- /* Function Body */
-
-/* Calculations are done on future frame due to requirements */
-/* of the pitch tracker. Delay RMS and RC's 2 frames to give */
-/* current frame parameters on return. */
-/* Update all buffers */
-
- inbuf = &(st->inbuf[0]);
- pebuf = &(st->pebuf[0]);
- lpbuf = &(st->lpbuf[0]);
- ivbuf = &(st->ivbuf[0]);
- bias = &(st->bias);
- osbuf = &(st->osbuf[0]);
- osptr = &(st->osptr);
- obound = &(st->obound[0]);
- vwin = &(st->vwin[0]);
- awin = &(st->awin[0]);
- voibuf = &(st->voibuf[0]);
- rmsbuf = &(st->rmsbuf[0]);
- rcbuf = &(st->rcbuf[0]);
- zpre = &(st->zpre);
-
- i__1 = 720 - contrl_1.lframe;
- for (i__ = 181; i__ <= i__1; ++i__) {
- inbuf[i__ - 181] = inbuf[contrl_1.lframe + i__ - 181];
- pebuf[i__ - 181] = pebuf[contrl_1.lframe + i__ - 181];
- }
- i__1 = 540 - contrl_1.lframe;
- for (i__ = 229; i__ <= i__1; ++i__) {
- ivbuf[i__ - 229] = ivbuf[contrl_1.lframe + i__ - 229];
- }
- i__1 = 720 - contrl_1.lframe;
- for (i__ = 25; i__ <= i__1; ++i__) {
- lpbuf[i__ - 25] = lpbuf[contrl_1.lframe + i__ - 25];
- }
- j = 1;
- i__1 = (*osptr) - 1;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (osbuf[i__ - 1] > contrl_1.lframe) {
- osbuf[j - 1] = osbuf[i__ - 1] - contrl_1.lframe;
- ++j;
- }
- }
- *osptr = j;
- voibuf[0] = voibuf[2];
- voibuf[1] = voibuf[3];
- for (i__ = 1; i__ <= 2; ++i__) {
- vwin[(i__ << 1) - 2] = vwin[((i__ + 1) << 1) - 2] - contrl_1.lframe;
- vwin[(i__ << 1) - 1] = vwin[((i__ + 1) << 1) - 1] - contrl_1.lframe;
- awin[(i__ << 1) - 2] = awin[((i__ + 1) << 1) - 2] - contrl_1.lframe;
- awin[(i__ << 1) - 1] = awin[((i__ + 1) << 1) - 1] - contrl_1.lframe;
-/* EWIN(*,J) is unused for J .NE. AF, so the following shift is
-*/
-/* unnecessary. It also causes error messages when the C versio
-n */
-/* of the code created from this by f2c is run with Purify. It
-*/
-/* correctly complains that uninitialized memory is being read.
-*/
-/* EWIN(1,I) = EWIN(1,I+1) - LFRAME */
-/* EWIN(2,I) = EWIN(2,I+1) - LFRAME */
- obound[i__ - 1] = obound[i__];
- voibuf[i__ * 2] = voibuf[(i__ + 1) * 2];
- voibuf[(i__ << 1) + 1] = voibuf[((i__ + 1) << 1) + 1];
- rmsbuf[i__ - 1] = rmsbuf[i__];
- i__1 = contrl_1.order;
- for (j = 1; j <= i__1; ++j) {
- rcbuf[j + i__ * 10 - 11] = rcbuf[j + (i__ + 1) * 10 - 11];
- }
- }
-/* Copy input speech, scale to sign+12 bit integers */
-/* Remove long term DC bias. */
-/* If the average value in the frame was over 1/4096 (after current
-*/
-/* BIAS correction), then subtract that much more from samples in */
-/* next frame. If the average value in the frame was under */
-/* -1/4096, add 1/4096 more to samples in next frame. In all other
-*/
-/* cases, keep BIAS the same. */
- temp = 0.f;
- i__1 = contrl_1.lframe;
- for (i__ = 1; i__ <= i__1; ++i__) {
- inbuf[720 - contrl_1.lframe + i__ - 181] = speech[i__] * 4096.f -
- (*bias);
- temp += inbuf[720 - contrl_1.lframe + i__ - 181];
- }
- if (temp > (real) contrl_1.lframe) {
- *bias += 1;
- }
- if (temp < (real) (-contrl_1.lframe)) {
- *bias += -1;
- }
-/* Place Voicing Window */
- i__ = 721 - contrl_1.lframe;
- preemp_(&inbuf[i__ - 181], &pebuf[i__ - 181], &contrl_1.lframe, &precoef,
- zpre);
- onset_(pebuf, osbuf, osptr, &c__10, &c__181, &c__720, &contrl_1.lframe, st);
-
-/* MAXOSP is just a debugging variable. */
-
-/* MAXOSP = MAX( MAXOSP, OSPTR ) */
-
- placev_(osbuf, osptr, &c__10, &obound[2], vwin, &c__3, &contrl_1.lframe,
- &c__90, &c__156, &c__307, &c__462);
-/* The Pitch Extraction algorithm estimates the pitch for a frame
-*/
-/* of speech by locating the minimum of the average magnitude difference
- */
-/* function (AMDF). The AMDF operates on low-pass, inverse filtered */
-/* speech. (The low-pass filter is an 800 Hz, 19 tap, equiripple, FIR
-*/
-/* filter and the inverse filter is a 2nd-order LPC filter.) The pitch
-*/
-/* estimate is later refined by dynamic programming (DYPTRK). However,
-*/
-/* since some of DYPTRK's parameters are a function of the voicing */
-/* decisions, a voicing decision must precede the final pitch estimation.
-*/
-/* See subroutines LPFILT, IVFILT, and TBDM. */
-/* LPFILT reads indices LBUFH-LFRAME-29 = 511 through LBUFH = 720 */
-/* of INBUF, and writes indices LBUFH+1-LFRAME = 541 through LBUFH
-*/
-/* = 720 of LPBUF. */
- lpfilt_(&inbuf[228], &lpbuf[384], &c__312, &contrl_1.lframe);
-/* IVFILT reads indices (PWINH-LFRAME-7) = 353 through PWINH = 540
-*/
-/* of LPBUF, and writes indices (PWINH-LFRAME+1) = 361 through */
-/* PWINH = 540 of IVBUF. */
- ivfilt_(&lpbuf[204], ivbuf, &c__312, &contrl_1.lframe, ivrc);
-/* TBDM reads indices PWINL = 229 through */
-/* (PWINL-1)+MAXWIN+(TAU(LTAU)-TAU(1))/2 = 452 of IVBUF, and writes
-*/
-/* indices 1 through LTAU = 60 of AMDF. */
- tbdm_(ivbuf, &c__156, tau, &c__60, amdf, &minptr, &maxptr, &mintau);
-/* Voicing decisions are made for each half frame of input speech.
-*/
-/* An initial voicing classification is made for each half of the */
-/* analysis frame, and the voicing decisions for the present frame */
-/* are finalized. See subroutine VOICIN. */
-/* The voicing detector (VOICIN) classifies the input signal as */
-/* unvoiced (including silence) or voiced using the AMDF windowed */
-/* maximum-to-minimum ratio, the zero crossing rate, energy measures, */
-/* reflection coefficients, and prediction gains. */
-/* The pitch and voicing rules apply smoothing and isolated */
-/* corrections to the pitch and voicing estimates and, in the process,
-*/
-/* introduce two frames of delay into the corrected pitch estimates and
-*/
-/* voicing decisions. */
- for (half = 1; half <= 2; ++half) {
- voicin_(&vwin[4], inbuf, lpbuf, buflim, &half, &amdf[minptr - 1], &
- amdf[maxptr - 1], &mintau, ivrc, obound, voibuf, &c__3, st);
- }
-/* Find the minimum cost pitch decision over several frames */
-/* given the current voicing decision and the AMDF array */
- dyptrk_(amdf, &c__60, &minptr, &voibuf[7], pitch, &midx, st);
- ipitch = tau[midx - 1];
-/* Place spectrum analysis and energy windows */
- placea_(&ipitch, voibuf, &obound[2], &c__3, vwin, awin, ewin, &
- contrl_1.lframe, &c__156);
-/* Remove short term DC bias over the analysis window, Put result in ABUF
-*/
- lanal = awin[5] + 1 - awin[4];
- dcbias_(&lanal, &pebuf[awin[4] - 181], abuf);
-/* ABUF(1:LANAL) is now defined. It is equal to */
-/* PEBUF(AWIN(1,AF):AWIN(2,AF)) corrected for short term DC bias. */
-/* Compute RMS over integer number of pitch periods within the */
-/* analysis window. */
-/* Note that in a hardware implementation this computation may be */
-/* simplified by using diagonal elements of PHI computed by MLOAD. */
- i__1 = ewin[5] - ewin[4] + 1;
- energy_(&i__1, &abuf[ewin[4] - awin[4]], &rmsbuf[2]);
-/* Matrix load and invert, check RC's for stability */
- mload_(&contrl_1.order, &c__1, &lanal, abuf, phi, psi);
- invert_(&contrl_1.order, phi, psi, &rcbuf[20]);
- rcchk_(&contrl_1.order, &rcbuf[10], &rcbuf[20]);
-/* Set return parameters */
- voice[1] = voibuf[2];
- voice[2] = voibuf[3];
- *rms = rmsbuf[0];
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- rc[i__] = rcbuf[i__ - 1];
- }
- return 0;
-} /* analys_ */
diff --git a/1.4/codecs/lpc10/bsynz.c b/1.4/codecs/lpc10/bsynz.c
deleted file mode 100644
index daf9105d6..000000000
--- a/1.4/codecs/lpc10/bsynz.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:18:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:58 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int bsynz_(real *coef, integer *ip, integer *iv, real *sout, real *rms, real *ratio, real *g2pass, struct lpc10_decoder_state *st);
-/* comlen contrl_ 12 */
-/*:ref: random_ 4 0 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* ***************************************************************** */
-
-/* BSYNZ Version 54 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:18:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:58 jaf
- * Initial revision
- * */
-/* Revision 1.4 1996/03/27 18:11:22 jaf */
-/* Changed the range of NOISE printed out in the debugging statements, */
-/* even though they are commented out. I didn't discover this until I */
-/* tried comparing two different versions of the LPC-10 coder, each with */
-/* full tracing enabled. */
-
-/* Revision 1.3 1996/03/26 19:33:23 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.2 1996/03/20 17:12:54 jaf */
-/* Added comments about which indices of array arguments are read or */
-/* written. */
-
-/* Rearranged local variable declarations to indicate which need to be */
-/* saved from one invocation to the next. Added entry INITBSYNZ to */
-/* reinitialize the local state variables, if desired. */
-
-/* Revision 1.1 1996/02/07 14:43:15 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Synthesize One Pitch Epoch */
-
-/* Input: */
-/* COEF - Predictor coefficients */
-/* Indices 1 through ORDER read. */
-/* IP - Pitch period (number of samples to synthesize) */
-/* IV - Voicing for the current epoch */
-/* RMS - Energy for the current epoch */
-/* RATIO - Energy slope for plosives */
-/* G2PASS- Sharpening factor for 2 pass synthesis */
-/* Output: */
-/* SOUT - Synthesized speech */
-/* Indices 1 through IP written. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITBSYNZ. */
-
-/* Subroutine */ int bsynz_(real *coef, integer *ip, integer *iv,
- real *sout, real *rms, real *ratio, real *g2pass,
- struct lpc10_decoder_state *st)
-{
- /* Initialized data */
-
- integer *ipo;
- real *rmso;
- static integer kexc[25] = { 8,-16,26,-48,86,-162,294,-502,718,-728,184,
- 672,-610,-672,184,728,718,502,294,162,86,48,26,16,8 };
- real *exc;
- real *exc2;
- real *lpi1;
- real *lpi2;
- real *lpi3;
- real *hpi1;
- real *hpi2;
- real *hpi3;
-
- /* System generated locals */
- integer i__1, i__2;
- real r__1, r__2;
-
- /* Builtin functions */
- double sqrt(doublereal);
-
- /* Local variables */
- real gain, xssq;
- integer i__, j, k;
- real noise[166], pulse;
- integer px;
- real sscale;
- extern integer random_(struct lpc10_decoder_state *);
- real xy, sum, ssq;
- real lpi0, hpi0;
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:18:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:58 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:18:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:58 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Function return value definitions */
-/* Parameters/constants */
-/* KEXC is not a Fortran PARAMETER, but it is an array initialized
-*/
-/* with a DATA statement that is never modified. */
-/* Local variables that need not be saved */
-/* NOISE is declared with range (1:MAXPIT+MAXORD), but only indices
-*/
-/* ORDER+1 through ORDER+IP are ever used, and I think that IP */
-/* .LE. MAXPIT. Why not declare it to be in the range (1:MAXPIT) */
-/* and use that range? */
-/* Local state */
-/* I believe that only indices 1 through ORDER of EXC need to be */
-/* saved from one invocation to the next, but we may as well save */
-/* the whole array. */
-/* None of these local variables were given initial values in the */
-/* original code. I'm guessing that 0 is a reasonable initial */
-/* value for all of them. */
- /* Parameter adjustments */
- if (coef) {
- --coef;
- }
- if (sout) {
- --sout;
- }
-
- /* Function Body */
- ipo = &(st->ipo);
- exc = &(st->exc[0]);
- exc2 = &(st->exc2[0]);
- lpi1 = &(st->lpi1);
- lpi2 = &(st->lpi2);
- lpi3 = &(st->lpi3);
- hpi1 = &(st->hpi1);
- hpi2 = &(st->hpi2);
- hpi3 = &(st->hpi3);
- rmso = &(st->rmso_bsynz);
-
-/* MAXPIT+MAXORD=166 */
-/* Calculate history scale factor XY and scale filter state */
-/* Computing MIN */
- r__1 = *rmso / (*rms + 1e-6f);
- xy = min(r__1,8.f);
- *rmso = *rms;
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- exc2[i__ - 1] = exc2[*ipo + i__ - 1] * xy;
- }
- *ipo = *ip;
- if (*iv == 0) {
-/* Generate white noise for unvoiced */
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- exc[contrl_1.order + i__ - 1] = (real) (random_(st) / 64);
- }
-/* Impulse doublet excitation for plosives */
-/* (RANDOM()+32768) is in the range 0 to 2**16-1. Therefore the
- */
-/* following expression should be evaluated using integers with
-at */
-/* least 32 bits (16 isn't enough), and PX should be in the rang
-e */
-/* ORDER+1+0 through ORDER+1+(IP-2) .EQ. ORDER+IP-1. */
- px = (random_(st) + 32768) * (*ip - 1) / 65536 + contrl_1.order + 1;
- r__1 = *ratio / 4 * 1.f;
- pulse = r__1 * 342;
- if (pulse > 2e3f) {
- pulse = 2e3f;
- }
- exc[px - 1] += pulse;
- exc[px] -= pulse;
-/* Load voiced excitation */
- } else {
- sscale = (real)sqrt((real) (*ip)) / 6.928f;
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- exc[contrl_1.order + i__ - 1] = 0.f;
- if (i__ <= 25) {
- exc[contrl_1.order + i__ - 1] = sscale * kexc[i__ - 1];
- }
- lpi0 = exc[contrl_1.order + i__ - 1];
- r__2 = exc[contrl_1.order + i__ - 1] * .125f + *lpi1 * .75f;
- r__1 = r__2 + *lpi2 * .125f;
- exc[contrl_1.order + i__ - 1] = r__1 + *lpi3 * 0.f;
- *lpi3 = *lpi2;
- *lpi2 = *lpi1;
- *lpi1 = lpi0;
- }
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- noise[contrl_1.order + i__ - 1] = random_(st) * 1.f / 64;
- hpi0 = noise[contrl_1.order + i__ - 1];
- r__2 = noise[contrl_1.order + i__ - 1] * -.125f + *hpi1 * .25f;
- r__1 = r__2 + *hpi2 * -.125f;
- noise[contrl_1.order + i__ - 1] = r__1 + *hpi3 * 0.f;
- *hpi3 = *hpi2;
- *hpi2 = *hpi1;
- *hpi1 = hpi0;
- }
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- exc[contrl_1.order + i__ - 1] += noise[contrl_1.order + i__ - 1];
- }
- }
-/* Synthesis filters: */
-/* Modify the excitation with all-zero filter 1 + G*SUM */
- xssq = 0.f;
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- k = contrl_1.order + i__;
- sum = 0.f;
- i__2 = contrl_1.order;
- for (j = 1; j <= i__2; ++j) {
- sum += coef[j] * exc[k - j - 1];
- }
- sum *= *g2pass;
- exc2[k - 1] = sum + exc[k - 1];
- }
-/* Synthesize using the all pole filter 1 / (1 - SUM) */
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- k = contrl_1.order + i__;
- sum = 0.f;
- i__2 = contrl_1.order;
- for (j = 1; j <= i__2; ++j) {
- sum += coef[j] * exc2[k - j - 1];
- }
- exc2[k - 1] = sum + exc2[k - 1];
- xssq += exc2[k - 1] * exc2[k - 1];
- }
-/* Save filter history for next epoch */
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- exc[i__ - 1] = exc[*ip + i__ - 1];
- exc2[i__ - 1] = exc2[*ip + i__ - 1];
- }
-/* Apply gain to match RMS */
- r__1 = *rms * *rms;
- ssq = r__1 * *ip;
- gain = (real)sqrt(ssq / xssq);
- i__1 = *ip;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sout[i__] = gain * exc2[contrl_1.order + i__ - 1];
- }
- return 0;
-} /* bsynz_ */
diff --git a/1.4/codecs/lpc10/chanwr.c b/1.4/codecs/lpc10/chanwr.c
deleted file mode 100644
index cefcdd145..000000000
--- a/1.4/codecs/lpc10/chanwr.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:20:24 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Revision 1.1 1996/08/19 22:40:31 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-/* *********************************************************************** */
-
-/* CHANL Version 49 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:20:24 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Revision 1.1 1996/08/19 22:40:31 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/21 15:14:57 jaf */
-/* Added comments about which indices of argument arrays are read or */
-/* written, and about the one bit of local state in CHANWR. CHANRD */
-/* has no local state. */
-
-/* Revision 1.2 1996/03/13 18:55:10 jaf */
-/* Comments added explaining which of the local variables of this */
-/* subroutine need to be saved from one invocation to the next, and which */
-/* do not. */
-
-/* Revision 1.1 1996/02/07 14:43:31 jaf */
-/* Initial revision */
-
-
-/* *********************************************************************** */
-
-/* CHANWR: */
-/* Place quantized parameters into bitstream */
-
-/* Input: */
-/* ORDER - Number of reflection coefficients (not really variable) */
-/* IPITV - Quantized pitch/voicing parameter */
-/* IRMS - Quantized energy parameter */
-/* IRC - Quantized reflection coefficients */
-/* Indices 1 through ORDER read. */
-/* Output: */
-/* IBITS - Serial bitstream */
-/* Indices 1 through 54 written. */
-/* Bit 54, the SYNC bit, alternates from one call to the next. */
-
-/* Subroutine CHANWR maintains one bit of local state from one call to */
-/* the next, in the variable ISYNC. I believe that this one bit is only */
-/* intended to allow a receiver to resynchronize its interpretation of */
-/* the bit stream, by looking for which of the 54 bits alternates every */
-/* frame time. This is just a simple framing mechanism that is not */
-/* useful when other, higher overhead framing mechanisms are used to */
-/* transmit the coded frames. */
-
-/* I'm not going to make an entry to reinitialize this bit, since it */
-/* doesn't help a receiver much to know whether the first sync bit is a 0 */
-/* or a 1. It needs to examine several frames in sequence to have */
-/* reasonably good assurance that its framing is correct. */
-
-
-/* CHANRD: */
-/* Reconstruct parameters from bitstream */
-
-/* Input: */
-/* ORDER - Number of reflection coefficients (not really variable) */
-/* IBITS - Serial bitstream */
-/* Indices 1 through 53 read (SYNC bit is ignored). */
-/* Output: */
-/* IPITV - Quantized pitch/voicing parameter */
-/* IRMS - Quantized energy parameter */
-/* IRC - Quantized reflection coefficients */
-/* Indices 1 through ORDER written */
-
-/* Entry CHANRD has no local state. */
-
-
-
-/* IBITS is 54 bits of LPC data ordered as follows: */
-/* R1-0, R2-0, R3-0, P-0, A-0, */
-/* R1-1, R2-1, R3-1, P-1, A-1, */
-/* R1-2, R4-0, R3-2, A-2, P-2, R4-1, */
-/* R1-3, R2-2, R3-3, R4-2, A-3, */
-/* R1-4, R2-3, R3-4, R4-3, A-4, */
-/* P-3, R2-4, R7-0, R8-0, P-4, R4-4, */
-/* R5-0, R6-0, R7-1,R10-0, R8-1, */
-/* R5-1, R6-1, R7-2, R9-0, P-5, */
-/* R5-2, R6-2,R10-1, R8-2, P-6, R9-1, */
-/* R5-3, R6-3, R7-3, R9-2, R8-3, SYNC */
-/* Subroutine */ int chanwr_0_(int n__, integer *order, integer *ipitv,
- integer *irms, integer *irc, integer *ibits,
- struct lpc10_encoder_state *st)
-{
- /* Initialized data */
-
- integer *isync;
- static integer bit[10] = { 2,4,8,8,8,8,16,16,16,16 };
- static integer iblist[53] = { 13,12,11,1,2,13,12,11,1,2,13,10,11,2,1,10,
- 13,12,11,10,2,13,12,11,10,2,1,12,7,6,1,10,9,8,7,4,6,9,8,7,5,1,9,8,
- 4,6,1,5,9,8,7,5,6 };
-
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- integer itab[13], i__;
-
-/* Arguments */
-/* Parameters/constants */
-/* These arrays are not Fortran PARAMETER's, but they are defined */
-/* by DATA statements below, and their contents are never altered.
-*/
-/* Local variables that need not be saved */
-/* Local state */
-/* ISYNC is only used by CHANWR, not by ENTRY CHANRD. */
-
- /* Parameter adjustments */
- --irc;
- --ibits;
-
- /* Function Body */
- switch(n__) {
- case 1: goto L_chanrd;
- }
-
- isync = &(st->isync);
-
-/* ***********************************************************************
- */
-/* Place quantized parameters into bitstream */
-/* ***********************************************************************
- */
-/* Place parameters into ITAB */
- itab[0] = *ipitv;
- itab[1] = *irms;
- itab[2] = 0;
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- itab[i__ + 2] = irc[*order + 1 - i__] & 32767;
- }
-/* Put 54 bits into IBITS array */
- for (i__ = 1; i__ <= 53; ++i__) {
- ibits[i__] = itab[iblist[i__ - 1] - 1] & 1;
- itab[iblist[i__ - 1] - 1] /= 2;
- }
- ibits[54] = *isync & 1;
- *isync = 1 - *isync;
- return 0;
-/* ***********************************************************************
- */
-/* Reconstruct parameters from bitstream */
-/* ***********************************************************************
- */
-
-L_chanrd:
-/* Reconstruct ITAB */
- for (i__ = 1; i__ <= 13; ++i__) {
- itab[i__ - 1] = 0;
- }
- for (i__ = 1; i__ <= 53; ++i__) {
- itab[iblist[54 - i__ - 1] - 1] = (itab[iblist[54 - i__ - 1] - 1] << 1)
- + ibits[54 - i__];
- }
-/* Sign extend RC's */
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if ((itab[i__ + 2] & bit[i__ - 1]) != 0) {
- itab[i__ + 2] -= bit[i__ - 1] << 1;
- }
- }
-/* Restore variables */
- *ipitv = itab[0];
- *irms = itab[1];
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- irc[i__] = itab[*order + 4 - i__ - 1];
- }
- return 0;
-} /* chanwr_ */
-
-/* Subroutine */ int chanwr_(integer *order, integer *ipitv, integer *irms,
- integer *irc, integer *ibits, struct lpc10_encoder_state *st)
-{
- return chanwr_0_(0, order, ipitv, irms, irc, ibits, st);
- }
-
-/* Subroutine */ int chanrd_(integer *order, integer *ipitv, integer *irms,
- integer *irc, integer *ibits)
-{
- return chanwr_0_(1, order, ipitv, irms, irc, ibits, 0);
- }
diff --git a/1.4/codecs/lpc10/dcbias.c b/1.4/codecs/lpc10/dcbias.c
deleted file mode 100644
index d5a7d644f..000000000
--- a/1.4/codecs/lpc10/dcbias.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:40:23 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int dcbias_(integer *len, real *speech, real *sigout);
-#endif
-
-/* ********************************************************************* */
-
-/* DCBIAS Version 50 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:40:23 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/18 21:19:22 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 16:44:53 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:44:21 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Calculate and remove DC bias from buffer. */
-
-/* Input: */
-/* LEN - Length of speech buffers */
-/* SPEECH - Input speech buffer */
-/* Indices 1 through LEN read. */
-/* Output: */
-/* SIGOUT - Output speech buffer */
-/* Indices 1 through LEN written */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int dcbias_(integer *len, real *speech, real *sigout)
-{
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- real bias;
- integer i__;
-
-/* Arguments */
-/* Local variables that need not be saved */
- /* Parameter adjustments */
- --sigout;
- --speech;
-
- /* Function Body */
- bias = 0.f;
- i__1 = *len;
- for (i__ = 1; i__ <= i__1; ++i__) {
- bias += speech[i__];
- }
- bias /= *len;
- i__1 = *len;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sigout[i__] = speech[i__] - bias;
- }
- return 0;
-} /* dcbias_ */
-
diff --git a/1.4/codecs/lpc10/decode.c b/1.4/codecs/lpc10/decode.c
deleted file mode 100644
index 08b8b9192..000000000
--- a/1.4/codecs/lpc10/decode.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.2 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:22:39 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:38 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int decode_(integer *ipitv, integer *irms, integer *irc, integer *voice, integer *pitch, real *rms, real *rc, struct lpc10_decoder_state *st);
-/* comlen contrl_ 12 */
-/*:ref: ham84_ 14 3 4 4 4 */
-/*:ref: median_ 4 3 4 4 4 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* Table of constant values */
-
-static integer c__2 = 2;
-
-/* ***************************************************************** */
-
-/* DECODE Version 54 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:22:39 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:38 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/05/23 20:06:03 jaf */
-/* Assigned PITCH a "default" value on the first call, since otherwise it */
-/* would be left uninitialized. */
-
-/* Revision 1.4 1996/03/26 19:35:18 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.3 1996/03/21 21:10:50 jaf */
-/* Added entry INITDECODE to reinitialize the local state of subroutine */
-/* DECODE. */
-
-/* Revision 1.2 1996/03/21 21:04:50 jaf */
-/* Determined which local variables should be saved from one invocation */
-/* to the next, and guessed initial values for some that should have been */
-/* saved, but weren't given initial values. Many of the arrays are */
-/* "constants", and many local variables are only used if the "global" */
-/* variable CORRP is .TRUE. */
-
-/* Added comments explaining which indices of array arguments are read or */
-/* written. */
-
-/* Revision 1.1 1996/02/12 03:21:10 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* This subroutine provides error correction and decoding */
-/* for all LPC parameters */
-
-/* Input: */
-/* IPITV - Index value of pitch */
-/* IRMS - Coded Energy */
-/* CORRP - Error correction: */
-/* If FALSE, parameters are decoded directly with no delay. If TRUE, */
-/* most important parameter bits are protected by Hamming code and */
-/* median smoothed. This requires an additional frame of delay. */
-/* Input/Output: */
-/* IRC - Coded Reflection Coefficients */
-/* Indices 1 through ORDER always read, then written. */
-/* Output: */
-/* VOICE - Half frame voicing decisions */
-/* Indices 1 through 2 written. */
-/* PITCH - Decoded pitch */
-/* RMS - Energy */
-/* RC - Reflection coefficients */
-/* Indices 1 through ORDER written. */
-
-/* NOTE: Zero RC's should be done more directly, but this would affect */
-/* coded parameter printout. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITDECODE. */
-
-/* Subroutine */ int decode_(integer *ipitv, integer *irms,
- integer *irc, integer *voice, integer *pitch, real *rms, real *rc,
- struct lpc10_decoder_state *st)
-{
- /* Initialized data */
-
- logical *first;
- static integer ethrs = 2048;
- static integer ethrs1 = 128;
- static integer ethrs2 = 1024;
- static integer ethrs3 = 2048;
- static integer ivtab[32] = { 24960,24960,24960,24960,25480,25480,25483,
- 25480,16640,1560,1560,1560,16640,1816,1563,1560,24960,24960,24859,
- 24856,26001,25881,25915,25913,1560,1560,7800,3640,1561,1561,3643,
- 3641 };
- static real corth[32] /* was [4][8] */ = { 32767.f,10.f,5.f,0.f,
- 32767.f,8.f,4.f,0.f,32.f,6.4f,3.2f,0.f,32.f,6.4f,3.2f,0.f,32.f,
- 11.2f,6.4f,0.f,32.f,11.2f,6.4f,0.f,16.f,5.6f,3.2f,0.f,16.f,5.6f,
- 3.2f,0.f };
- static integer detau[128] = { 0,0,0,3,0,3,3,31,0,3,3,21,3,3,29,30,0,3,3,
- 20,3,25,27,26,3,23,58,22,3,24,28,3,0,3,3,3,3,39,33,32,3,37,35,36,
- 3,38,34,3,3,42,46,44,50,40,48,3,54,3,56,3,52,3,3,1,0,3,3,108,3,78,
- 100,104,3,84,92,88,156,80,96,3,3,74,70,72,66,76,68,3,62,3,60,3,64,
- 3,3,1,3,116,132,112,148,152,3,3,140,3,136,3,144,3,3,1,124,120,128,
- 3,3,3,3,1,3,3,3,1,3,1,1,1 };
- static integer rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420,
- 384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102,
- 92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15,
- 14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 };
- static integer detab7[32] = { 4,11,18,25,32,39,46,53,60,66,72,77,82,87,92,
- 96,101,104,108,111,114,115,117,119,121,122,123,124,125,126,127,
- 127 };
- static real descl[8] = { .6953f,.625f,.5781f,.5469f,.5312f,.5391f,.4688f,
- .3828f };
- integer *ivp2h;
- static integer deadd[8] = { 1152,-2816,-1536,-3584,-1280,-2432,768,-1920 }
- ;
- static integer qb[8] = { 511,511,1023,1023,1023,1023,2047,4095 };
- static integer nbit[10] = { 8,8,5,5,4,4,4,4,3,2 };
- static integer zrc[10] = { 0,0,0,0,0,3,0,2,0,0 };
- static integer bit[5] = { 2,4,8,16,32 };
- integer *iovoic;
- integer *iavgp;
- integer *iptold;
- integer *erate;
- integer *drc;
- integer *dpit;
- integer *drms;
-
- /* System generated locals */
- integer i__1, i__2;
-
- /* Builtin functions */
- integer pow_ii(integer *, integer *);
-
- /* Local variables */
- extern /* Subroutine */ int ham84_(integer *, integer *, integer *);
- integer ipit, iout, i__, icorf, index, ivoic, ixcor, i1, i2, i4;
- extern integer median_(integer *, integer *, integer *);
- integer ishift, errcnt, lsb;
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:22:39 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:38 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Arguments */
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:22:39 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:38 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Function return value definitions */
-
-/* Parameters/constants */
-
-/* The variables below that are not Fortran PARAMETER's are */
-/* initialized with DATA statements, and then never modified. */
-/* The following are used regardless of CORRP's value. */
-
-/* DETAU, NBIT, QB, DEADD, DETAB7, RMST, DESCL */
-
-/* The following are used only if CORRP is .TRUE. */
-
-/* ETHRS, ETHRS1, ETHRS2, ETHRS3, IVTAB, BIT, CORTH, ZRC */
-
-/* Local variables that need not be saved */
-
-/* The following are used regardless of CORRP's value */
-/* The following are used only if CORRP is .TRUE. */
-
-/* Local state */
-
-/* The following are used regardless of CORRP's value */
-/* The following are used only if CORRP is .TRUE. */
-/* I am guessing the initial values for IVP2H, IOVOIC, DRC, DPIT, */
-/* and DRMS. They should be checked to see if they are reasonable.
-*/
-/* I'm also guessing for ERATE, but I think 0 is the right initial
-*/
-/* value. */
- /* Parameter adjustments */
- if (irc) {
- --irc;
- }
- if (voice) {
- --voice;
- }
- if (rc) {
- --rc;
- }
-
- /* Function Body */
-
- iptold = &(st->iptold);
- first = &(st->first);
- ivp2h = &(st->ivp2h);
- iovoic = &(st->iovoic);
- iavgp = &(st->iavgp);
- erate = &(st->erate);
- drc = &(st->drc[0]);
- dpit = &(st->dpit[0]);
- drms = &(st->drms[0]);
-
-/* DATA statements for "constants" defined above. */
-/* IF (LISTL.GE.3) WRITE(FDEBUG,800) IPITV,IRMS,(IRC(J),J=1,ORDER) */
-/* 800 FORMAT(1X,' <<ERRCOR IN>>',T32,6X,I6,I5,T50,10I8) */
-/* If no error correction, do pitch and voicing then jump to decode */
- i4 = detau[*ipitv];
- if (! contrl_1.corrp) {
- voice[1] = 1;
- voice[2] = 1;
- if (*ipitv <= 1) {
- voice[1] = 0;
- }
- if (*ipitv == 0 || *ipitv == 2) {
- voice[2] = 0;
- }
- *pitch = i4;
- if (*pitch <= 4) {
- *pitch = *iptold;
- }
- if (voice[1] == 1 && voice[2] == 1) {
- *iptold = *pitch;
- }
- if (voice[1] != voice[2]) {
- *pitch = *iptold;
- }
- goto L900;
- }
-/* Do error correction pitch and voicing */
- if (i4 > 4) {
- dpit[0] = i4;
- ivoic = 2;
- *iavgp = (*iavgp * 15 + i4 + 8) / 16;
- } else {
- ivoic = i4;
- dpit[0] = *iavgp;
- }
- drms[0] = *irms;
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- drc[i__ * 3 - 3] = irc[i__];
- }
-/* Determine index to IVTAB from V/UV decision */
-/* If error rate is high then use alternate table */
- index = (*ivp2h << 4) + (*iovoic << 2) + ivoic + 1;
- i1 = ivtab[index - 1];
- ipit = i1 & 3;
- icorf = i1 / 8;
- if (*erate < ethrs) {
- icorf /= 64;
- }
-/* Determine error rate: 4=high 1=low */
- ixcor = 4;
- if (*erate < ethrs3) {
- ixcor = 3;
- }
- if (*erate < ethrs2) {
- ixcor = 2;
- }
- if (*erate < ethrs1) {
- ixcor = 1;
- }
-/* Voice/unvoice decision determined from bits 0 and 1 of IVTAB */
- voice[1] = icorf / 2 & 1;
- voice[2] = icorf & 1;
-/* Skip decoding on first frame because present data not yet available */
- if (*first) {
- *first = FALSE_;
-/* Assign PITCH a "default" value on the first call, since */
-/* otherwise it would be left uninitialized. The two lines
-*/
-/* below were copied from above, since it seemed like a */
-/* reasonable thing to do for the first call. */
- *pitch = i4;
- if (*pitch <= 4) {
- *pitch = *iptold;
- }
- goto L500;
- }
-/* If bit 4 of ICORF is set then correct RMS and RC(1) - RC(4). */
-/* Determine error rate and correct errors using a Hamming 8,4 code */
-/* during transition or unvoiced frame. If IOUT is negative, */
-/* more than 1 error occurred, use previous frame's parameters. */
- if ((icorf & bit[3]) != 0) {
- errcnt = 0;
- lsb = drms[1] & 1;
- index = (drc[22] << 4) + drms[1] / 2;
- ham84_(&index, &iout, &errcnt);
- drms[1] = drms[2];
- if (iout >= 0) {
- drms[1] = (iout << 1) + lsb;
- }
- for (i__ = 1; i__ <= 4; ++i__) {
- if (i__ == 1) {
- i1 = ((drc[25] & 7) << 1) + (drc[28] & 1);
- } else {
- i1 = drc[(9 - i__) * 3 - 2] & 15;
- }
- i2 = drc[(5 - i__) * 3 - 2] & 31;
- lsb = i2 & 1;
- index = (i1 << 4) + i2 / 2;
- ham84_(&index, &iout, &errcnt);
- if (iout >= 0) {
- iout = (iout << 1) + lsb;
- if ((iout & 16) == 16) {
- iout += -32;
- }
- } else {
- iout = drc[(5 - i__) * 3 - 1];
- }
- drc[(5 - i__) * 3 - 2] = iout;
- }
-/* Determine error rate */
- *erate = (integer)(*erate * .96875f + errcnt * 102);
- }
-/* Get unsmoothed RMS, RC's, and PITCH */
- *irms = drms[1];
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- irc[i__] = drc[i__ * 3 - 2];
- }
- if (ipit == 1) {
- dpit[1] = dpit[2];
- }
- if (ipit == 3) {
- dpit[1] = dpit[0];
- }
- *pitch = dpit[1];
-/* If bit 2 of ICORF is set then smooth RMS and RC's, */
- if ((icorf & bit[1]) != 0) {
- if ((i__1 = drms[1] - drms[0], (real) abs(i__1)) >= corth[ixcor + 3]
- && (i__2 = drms[1] - drms[2], (real) abs(i__2)) >= corth[
- ixcor + 3]) {
- *irms = median_(&drms[2], &drms[1], drms);
- }
- for (i__ = 1; i__ <= 6; ++i__) {
- if ((i__1 = drc[i__ * 3 - 2] - drc[i__ * 3 - 3], (real) abs(i__1))
- >= corth[ixcor + ((i__ + 2) << 2) - 5] && (i__2 = drc[i__ *
- 3 - 2] - drc[i__ * 3 - 1], (real) abs(i__2)) >= corth[
- ixcor + ((i__ + 2) << 2) - 5]) {
- irc[i__] = median_(&drc[i__ * 3 - 1], &drc[i__ * 3 - 2], &drc[
- i__ * 3 - 3]);
- }
- }
- }
-/* If bit 3 of ICORF is set then smooth pitch */
- if ((icorf & bit[2]) != 0) {
- if ((i__1 = dpit[1] - dpit[0], (real) abs(i__1)) >= corth[ixcor - 1]
- && (i__2 = dpit[1] - dpit[2], (real) abs(i__2)) >= corth[
- ixcor - 1]) {
- *pitch = median_(&dpit[2], &dpit[1], dpit);
- }
- }
-/* If bit 5 of ICORF is set then RC(5) - RC(10) are loaded with */
-/* values so that after quantization bias is removed in decode */
-/* the values will be zero. */
-L500:
- if ((icorf & bit[4]) != 0) {
- i__1 = contrl_1.order;
- for (i__ = 5; i__ <= i__1; ++i__) {
- irc[i__] = zrc[i__ - 1];
- }
- }
-/* House keeping - one frame delay */
- *iovoic = ivoic;
- *ivp2h = voice[2];
- dpit[2] = dpit[1];
- dpit[1] = dpit[0];
- drms[2] = drms[1];
- drms[1] = drms[0];
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- drc[i__ * 3 - 1] = drc[i__ * 3 - 2];
- drc[i__ * 3 - 2] = drc[i__ * 3 - 3];
- }
-L900:
-/* IF (LISTL.GE.3)WRITE(FDEBUG,801)VOICE,PITCH,IRMS,(IRC(J),J=1,ORDER) */
-/* 801 FORMAT(1X,'<<ERRCOR OUT>>',T32,2I3,I6,I5,T50,10I8) */
-/* Decode RMS */
- *irms = rmst[(31 - *irms) * 2];
-/* Decode RC(1) and RC(2) from log-area-ratios */
-/* Protect from illegal coded value (-16) caused by bit errors */
- for (i__ = 1; i__ <= 2; ++i__) {
- i2 = irc[i__];
- i1 = 0;
- if (i2 < 0) {
- i1 = 1;
- i2 = -i2;
- if (i2 > 15) {
- i2 = 0;
- }
- }
- i2 = detab7[i2 * 2];
- if (i1 == 1) {
- i2 = -i2;
- }
- ishift = 15 - nbit[i__ - 1];
- irc[i__] = i2 * pow_ii(&c__2, &ishift);
- }
-/* Decode RC(3)-RC(10) to sign plus 14 bits */
- i__1 = contrl_1.order;
- for (i__ = 3; i__ <= i__1; ++i__) {
- i2 = irc[i__];
- ishift = 15 - nbit[i__ - 1];
- i2 *= pow_ii(&c__2, &ishift);
- i2 += qb[i__ - 3];
- irc[i__] = (integer)(i2 * descl[i__ - 3] + deadd[i__ - 3]);
- }
-/* IF (LISTL.GE.3) WRITE(FDEBUG,811) IRMS, (IRC(I),I=1,ORDER) */
-/* 811 FORMAT(1X,'<<DECODE OUT>>',T45,I4,1X,10I8) */
-/* Scale RMS and RC's to reals */
- *rms = (real) (*irms);
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- rc[i__] = irc[i__] / 16384.f;
- }
- return 0;
-} /* decode_ */
diff --git a/1.4/codecs/lpc10/deemp.c b/1.4/codecs/lpc10/deemp.c
deleted file mode 100644
index c3b5909ff..000000000
--- a/1.4/codecs/lpc10/deemp.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:23:46 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:34 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int deemp_(real *x, integer *n, struct lpc10_decoder_state *st);
-#endif
-
-/* ***************************************************************** */
-
-/* DEEMP Version 48 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:23:46 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:34 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/20 15:54:37 jaf */
-/* Added comments about which indices of array arguments are read or */
-/* written. */
-
-/* Added entry INITDEEMP to reinitialize the local state variables, if */
-/* desired. */
-
-/* Revision 1.2 1996/03/14 22:11:13 jaf */
-/* Comments added explaining which of the local variables of this */
-/* subroutine need to be saved from one invocation to the next, and which */
-/* do not. */
-
-/* Revision 1.1 1996/02/07 14:44:53 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* De-Emphasize output speech with 1 / ( 1 - .75z**-1 ) */
-/* cascaded with 200 Hz high pass filter */
-/* ( 1 - 1.9998z**-1 + z**-2 ) / ( 1 - 1.75z**-1 + .78z**-2 ) */
-
-/* WARNING! The coefficients above may be out of date with the code */
-/* below. Either that, or some kind of transformation was performed */
-/* on the coefficients above to create the code below. */
-
-/* Input: */
-/* N - Number of samples */
-/* Input/Output: */
-/* X - Speech */
-/* Indices 1 through N are read before being written. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITDEEMP. */
-
-/* Subroutine */ int deemp_(real *x, integer *n, struct lpc10_decoder_state *st)
-{
- /* Initialized data */
-
- real *dei1;
- real *dei2;
- real *deo1;
- real *deo2;
- real *deo3;
-
- /* System generated locals */
- integer i__1;
- real r__1;
-
- /* Local variables */
- integer k;
- real dei0;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Local state */
-/* All of the locals saved below were not given explicit initial */
-/* values in the original code. I think 0 is a safe choice. */
- /* Parameter adjustments */
- if (x) {
- --x;
- }
-
- /* Function Body */
-
- dei1 = &(st->dei1);
- dei2 = &(st->dei2);
- deo1 = &(st->deo1);
- deo2 = &(st->deo2);
- deo3 = &(st->deo3);
-
- i__1 = *n;
- for (k = 1; k <= i__1; ++k) {
- dei0 = x[k];
- r__1 = x[k] - *dei1 * 1.9998f + *dei2;
- x[k] = r__1 + *deo1 * 2.5f - *deo2 * 2.0925f + *deo3 * .585f;
- *dei2 = *dei1;
- *dei1 = dei0;
- *deo3 = *deo2;
- *deo2 = *deo1;
- *deo1 = x[k];
- }
- return 0;
-} /* deemp_ */
diff --git a/1.4/codecs/lpc10/difmag.c b/1.4/codecs/lpc10/difmag.c
deleted file mode 100644
index ab59e8c9a..000000000
--- a/1.4/codecs/lpc10/difmag.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:14 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:32:31 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int difmag_(real *speech, integer *lpita, integer *tau, integer *ltau, integer *maxlag, real *amdf, integer *minptr, integer *maxptr);
-#endif
-
-/* ********************************************************************** */
-
-/* DIFMAG Version 49 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:14 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:31 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/15 23:09:39 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 14:41:31 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:45:04 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Compute Average Magnitude Difference Function */
-
-/* Inputs: */
-/* SPEECH - Low pass filtered speech */
-/* Indices MIN_N1 through MAX_N1+LPITA-1 are read, where */
-/* MIN_N1 = (MAXLAG - MAX_TAU)/2+1 MAX_TAU = max of TAU(I) for I=1,LTAU
-*/
-/* MAX_N1 = (MAXLAG - MIN_TAU)/2+1 MIN_TAU = min of TAU(I) for I=1,LTAU
-*/
-/* LPITA - Length of speech buffer */
-/* TAU - Table of lags */
-/* Indices 1 through LTAU read. */
-/* LTAU - Number of lag values to compute */
-/* MAXLAG - Maximum possible lag value */
-/* Outputs: */
-/* (All of these outputs are also read, but only after being written.) */
-/* AMDF - Average Magnitude Difference for each lag in TAU */
-/* Indices 1 through LTAU written */
-/* MINPTR - Index of minimum AMDF value */
-/* MAXPTR - Index of maximum AMDF value */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int difmag_(real *speech, integer *lpita, integer *tau,
- integer *ltau, integer *maxlag, real *amdf, integer *minptr, integer *
- maxptr)
-{
- /* System generated locals */
- integer i__1, i__2;
- real r__1;
-
- /* Local variables */
- integer i__, j, n1, n2;
- real sum;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Local state */
-/* None */
- /* Parameter adjustments */
- --amdf;
- --tau;
- --speech;
-
- /* Function Body */
- *minptr = 1;
- *maxptr = 1;
- i__1 = *ltau;
- for (i__ = 1; i__ <= i__1; ++i__) {
- n1 = (*maxlag - tau[i__]) / 2 + 1;
- n2 = n1 + *lpita - 1;
- sum = 0.f;
- i__2 = n2;
- for (j = n1; j <= i__2; j += 4) {
- sum += (r__1 = speech[j] - speech[j + tau[i__]], abs(r__1));
- }
- amdf[i__] = sum;
- if (amdf[i__] < amdf[*minptr]) {
- *minptr = i__;
- }
- if (amdf[i__] > amdf[*maxptr]) {
- *maxptr = i__;
- }
- }
- return 0;
-} /* difmag_ */
-
diff --git a/1.4/codecs/lpc10/dyptrk.c b/1.4/codecs/lpc10/dyptrk.c
deleted file mode 100644
index 216b55994..000000000
--- a/1.4/codecs/lpc10/dyptrk.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:25:29 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:26 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int dyptrk_(real *amdf, integer *ltau, integer *minptr, integer *voice, integer *pitch, integer *midx, struct lpc10_encoder_state *st);
-/* comlen contrl_ 12 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* ********************************************************************* */
-
-/* DYPTRK Version 52 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:25:29 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:26 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/03/26 19:35:35 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.4 1996/03/19 18:03:22 jaf */
-/* Replaced the initialization "DATA P/60*DEPTH*0/" with "DATA P/120*0/", */
-/* because apparently Fortran (or at least f2c) can't handle expressions */
-/* like that. */
-
-/* Revision 1.3 1996/03/19 17:38:32 jaf */
-/* Added comments about the local variables that should be saved from one */
-/* invocation to the next. None of them were given initial values in the */
-/* original code, but from my testing, it appears that initializing them */
-/* all to 0 works. */
-
-/* Added entry INITDYPTRK to reinitialize these local variables. */
-
-/* Revision 1.2 1996/03/13 16:32:17 jaf */
-/* Comments added explaining which of the local variables of this */
-/* subroutine need to be saved from one invocation to the next, and which */
-/* do not. */
-
-/* WARNING! Some of them that should are never given initial values in */
-/* this code. Hopefully, Fortran 77 defines initial values for them, but */
-/* even so, giving them explicit initial values is preferable. */
-
-/* Revision 1.1 1996/02/07 14:45:14 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Dynamic Pitch Tracker */
-
-/* Input: */
-/* AMDF - Average Magnitude Difference Function array */
-/* Indices 1 through LTAU read, and MINPTR */
-/* LTAU - Number of lags in AMDF */
-/* MINPTR - Location of minimum AMDF value */
-/* VOICE - Voicing decision */
-/* Output: */
-/* PITCH - Smoothed pitch value, 2 frames delayed */
-/* MIDX - Initial estimate of current frame pitch */
-/* Compile time constant: */
-/* DEPTH - Number of frames to trace back */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITDYPTRK. */
-
-/* Subroutine */ int dyptrk_(real *amdf, integer *ltau, integer *
- minptr, integer *voice, integer *pitch, integer *midx,
- struct lpc10_encoder_state *st)
-{
- /* Initialized data */
-
- real *s;
- integer *p;
- integer *ipoint;
- real *alphax;
-
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- integer pbar;
- real sbar;
- integer path[2], iptr, i__, j;
- real alpha, minsc, maxsc;
-
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:25:29 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:26 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Parameters/constants */
-/* Local variables that need not be saved */
-/* Note that PATH is only used for debugging purposes, and can be */
-/* removed. */
-/* Local state */
-/* It would be a bit more "general" to define S(LTAU), if Fortran */
-/* allows the argument of a function to be used as the dimension of
-*/
-/* a local array variable. */
-/* IPOINT is always in the range 0 to DEPTH-1. */
-/* WARNING! */
-
-/* In the original version of this subroutine, IPOINT, ALPHAX, */
-/* every element of S, and potentially any element of P with the */
-/* second index value .NE. IPTR were read without being given */
-/* initial values (all indices of P with second index equal to */
-/* IPTR are all written before being read in this subroutine). */
-
-/* From examining the code carefully, it appears that all of these
-*/
-/* should be saved from one invocation to the next. */
-
-/* I've run lpcsim with the "-l 6" option to see all of the */
-/* debugging information that is printed out by this subroutine */
-/* below, and it appears that S, P, IPOINT, and ALPHAX are all */
-/* initialized to 0 (these initial values would likely be different
-*/
-/* on different platforms, compilers, etc.). Given that the output
-*/
-/* of the coder sounds reasonable, I'm going to initialize these */
-/* variables to 0 explicitly. */
-
- s = &(st->s[0]);
- p = &(st->p[0]);
- ipoint = &(st->ipoint);
- alphax = &(st->alphax);
-
-
- /* Parameter adjustments */
- if (amdf) {
- --amdf;
- }
-
- /* Function Body */
-
-/* Calculate the confidence factor ALPHA, used as a threshold slope in
-*/
-/* SEESAW. If unvoiced, set high slope so that every point in P array
-*/
-/* is marked as a potential pitch frequency. A scaled up version (ALPHAX
-)*/
-/* is used to maintain arithmetic precision. */
- if (*voice == 1) {
- *alphax = *alphax * .75f + amdf[*minptr] / 2.f;
- } else {
- *alphax *= .984375f;
- }
- alpha = *alphax / 16;
- if (*voice == 0 && *alphax < 128.f) {
- alpha = 8.f;
- }
-/* SEESAW: Construct a pitch pointer array and intermediate winner functio
-n*/
-/* Left to right pass: */
- iptr = *ipoint + 1;
- p[iptr * 60 - 60] = 1;
- i__ = 1;
- pbar = 1;
- sbar = s[0];
- i__1 = *ltau;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sbar += alpha;
- if (sbar < s[i__ - 1]) {
- s[i__ - 1] = sbar;
- p[i__ + iptr * 60 - 61] = pbar;
- } else {
- sbar = s[i__ - 1];
- p[i__ + iptr * 60 - 61] = i__;
- pbar = i__;
- }
- }
-/* Right to left pass: */
- i__ = pbar - 1;
- sbar = s[i__];
- while(i__ >= 1) {
- sbar += alpha;
- if (sbar < s[i__ - 1]) {
- s[i__ - 1] = sbar;
- p[i__ + iptr * 60 - 61] = pbar;
- } else {
- pbar = p[i__ + iptr * 60 - 61];
- i__ = pbar;
- sbar = s[i__ - 1];
- }
- --i__;
- }
-/* Update S using AMDF */
-/* Find maximum, minimum, and location of minimum */
- s[0] += amdf[1] / 2;
- minsc = s[0];
- maxsc = minsc;
- *midx = 1;
- i__1 = *ltau;
- for (i__ = 2; i__ <= i__1; ++i__) {
- s[i__ - 1] += amdf[i__] / 2;
- if (s[i__ - 1] > maxsc) {
- maxsc = s[i__ - 1];
- }
- if (s[i__ - 1] < minsc) {
- *midx = i__;
- minsc = s[i__ - 1];
- }
- }
-/* Subtract MINSC from S to prevent overflow */
- i__1 = *ltau;
- for (i__ = 1; i__ <= i__1; ++i__) {
- s[i__ - 1] -= minsc;
- }
- maxsc -= minsc;
-/* Use higher octave pitch if significant null there */
- j = 0;
- for (i__ = 20; i__ <= 40; i__ += 10) {
- if (*midx > i__) {
- if (s[*midx - i__ - 1] < maxsc / 4) {
- j = i__;
- }
- }
- }
- *midx -= j;
-/* TRACE: look back two frames to find minimum cost pitch estimate */
- j = *ipoint;
- *pitch = *midx;
- for (i__ = 1; i__ <= 2; ++i__) {
- j = j % 2 + 1;
- *pitch = p[*pitch + j * 60 - 61];
- path[i__ - 1] = *pitch;
- }
-
-/* The following statement subtracts one from IPOINT, mod DEPTH. I
-*/
-/* think the author chose to add DEPTH-1, instead of subtracting 1,
-*/
-/* because then it will work even if MOD doesn't work as desired on
-*/
-/* negative arguments. */
-
- *ipoint = (*ipoint + 1) % 2;
- return 0;
-} /* dyptrk_ */
diff --git a/1.4/codecs/lpc10/encode.c b/1.4/codecs/lpc10/encode.c
deleted file mode 100644
index b81799f6b..000000000
--- a/1.4/codecs/lpc10/encode.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:32:21 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int encode_(integer *voice, integer *pitch, real *rms, real *rc, integer *ipitch, integer *irms, integer *irc);
-/* comlen contrl_ 12 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* Table of constant values */
-
-static integer c__2 = 2;
-
-/* ***************************************************************** */
-
-/* ENCODE Version 54 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:21 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/03/26 19:35:50 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.4 1996/03/21 00:26:29 jaf */
-/* Added the comment that this subroutine has no local state. */
-
-/* In the last check-in, I forgot to mention that I had added comments */
-/* explaining which indices of array arguments are read or written. */
-
-/* Revision 1.3 1996/03/21 00:22:39 jaf */
-/* Added comments explaining that all local arrays are effectively */
-/* constants. */
-
-/* Revision 1.2 1996/03/13 18:48:33 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:45:29 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Quantize LPC parameters for transmission */
-
-/* INPUTS: */
-/* VOICE - Half frame voicing decisions */
-/* Indices 1 through 2 read. */
-/* PITCH - Pitch */
-/* RMS - Energy */
-/* RC - Reflection coefficients */
-/* Indices 1 through ORDER read. */
-/* CORRP - Error Correction: TRUE = yes, FALSE = none */
-/* (this is defined in file control.fh) */
-/* OUTPUTS: */
-/* IPITCH - Coded pitch and voicing */
-/* IRMS - Quantized energy */
-/* IRC - Quantized reflection coefficients */
-/* Indices 1 through MAX(ORDER,2) written. */
-/* If CORRP is .TRUE., then indices 1 through 10 written */
-/* for unvoiced frames. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int encode_(integer *voice, integer *pitch, real *rms, real *
- rc, integer *ipitch, integer *irms, integer *irc)
-{
- /* Initialized data */
-
- static integer enctab[16] = { 0,7,11,12,13,10,6,1,14,9,5,2,3,4,8,15 };
- static integer entau[60] = { 19,11,27,25,29,21,23,22,30,14,15,7,39,38,46,
- 42,43,41,45,37,53,49,51,50,54,52,60,56,58,26,90,88,92,84,86,82,83,
- 81,85,69,77,73,75,74,78,70,71,67,99,97,113,112,114,98,106,104,108,
- 100,101,76 };
- static integer enadd[8] = { 1920,-768,2432,1280,3584,1536,2816,-1152 };
- static real enscl[8] = { .0204f,.0167f,.0145f,.0147f,.0143f,.0135f,.0125f,
- .0112f };
- static integer enbits[8] = { 6,5,4,4,4,4,3,3 };
- static integer entab6[64] = { 0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,
- 3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,9,9,
- 9,10,10,11,11,12,13,14,15 };
- static integer rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420,
- 384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102,
- 92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15,
- 14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 };
-
- /* System generated locals */
- integer i__1, i__2;
-
- /* Builtin functions */
- integer pow_ii(integer *, integer *);
-
- /* Local variables */
- integer idel, nbit, i__, j, i2, i3, mrk;
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:21 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:21 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Parameters/constants */
-/* These arrays are not Fortran PARAMETER's, but they are defined */
-/* by DATA statements below, and their contents are never altered.
-*/
-/* Local variables that need not be saved */
- /* Parameter adjustments */
- --irc;
- --rc;
- --voice;
-
- /* Function Body */
-/* Scale RMS and RC's to integers */
- *irms = (integer)*rms;
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- irc[i__] = (integer)(rc[i__] * 32768.f);
- }
-/* IF(LISTL.GE.3)WRITE(FDEBUG,800)VOICE,PITCH,IRMS,(IRC(I),I=1,ORDER) */
-/* 800 FORMAT(1X,/,' <<ENCODE IN>>',T32,2I3,I6,I5,T50,10I8) */
-/* Encode pitch and voicing */
- if (voice[1] != 0 && voice[2] != 0) {
- *ipitch = entau[*pitch - 1];
- } else {
- if (contrl_1.corrp) {
- *ipitch = 0;
- if (voice[1] != voice[2]) {
- *ipitch = 127;
- }
- } else {
- *ipitch = (voice[1] << 1) + voice[2];
- }
- }
-/* Encode RMS by binary table search */
- j = 32;
- idel = 16;
- *irms = min(*irms,1023);
- while(idel > 0) {
- if (*irms > rmst[j - 1]) {
- j -= idel;
- }
- if (*irms < rmst[j - 1]) {
- j += idel;
- }
- idel /= 2;
- }
- if (*irms > rmst[j - 1]) {
- --j;
- }
- *irms = 31 - j / 2;
-/* Encode RC(1) and (2) as log-area-ratios */
- for (i__ = 1; i__ <= 2; ++i__) {
- i2 = irc[i__];
- mrk = 0;
- if (i2 < 0) {
- i2 = -i2;
- mrk = 1;
- }
- i2 /= 512;
- i2 = min(i2,63);
- i2 = entab6[i2];
- if (mrk != 0) {
- i2 = -i2;
- }
- irc[i__] = i2;
- }
-/* Encode RC(3) - (10) linearly, remove bias then scale */
- i__1 = contrl_1.order;
- for (i__ = 3; i__ <= i__1; ++i__) {
- i2 = irc[i__] / 2;
- i2 = (integer)((i2 + enadd[contrl_1.order + 1 - i__ - 1]) * enscl[
- contrl_1.order + 1 - i__ - 1]);
-/* Computing MIN */
- i__2 = max(i2,-127);
- i2 = min(i__2,127);
- nbit = enbits[contrl_1.order + 1 - i__ - 1];
- i3 = 0;
- if (i2 < 0) {
- i3 = -1;
- }
- i2 /= pow_ii(&c__2, &nbit);
- if (i3 == -1) {
- --i2;
- }
- irc[i__] = i2;
- }
-/* Protect the most significant bits of the most */
-/* important parameters during non-voiced frames. */
-/* RC(1) - RC(4) are protected using 20 parity bits */
-/* replacing RC(5) - RC(10). */
- if (contrl_1.corrp) {
- if (*ipitch == 0 || *ipitch == 127) {
- irc[5] = enctab[(irc[1] & 30) / 2];
- irc[6] = enctab[(irc[2] & 30) / 2];
- irc[7] = enctab[(irc[3] & 30) / 2];
- irc[8] = enctab[(*irms & 30) / 2];
- irc[9] = enctab[(irc[4] & 30) / 2] / 2;
- irc[10] = enctab[(irc[4] & 30) / 2] & 1;
- }
- }
-/* IF(LISTL.GE.3)WRITE(FDEBUG,801)VOICE,IPITCH,IRMS,(IRC(J),J=1,ORDER) */
-/* 801 FORMAT(1X,'<<ENCODE OUT>>',T32,2I3,I6,I5,T50,10I8) */
- return 0;
-} /* encode_ */
-
diff --git a/1.4/codecs/lpc10/energy.c b/1.4/codecs/lpc10/energy.c
deleted file mode 100644
index eada04bef..000000000
--- a/1.4/codecs/lpc10/energy.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:32:17 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int energy_(integer *len, real *speech, real *rms);
-#endif
-
-/* ********************************************************************* */
-
-/* ENERGY Version 50 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:17 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/18 21:17:41 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 16:46:02 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:45:40 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Compute RMS energy. */
-
-/* Input: */
-/* LEN - Length of speech buffer */
-/* SPEECH - Speech buffer */
-/* Indices 1 through LEN read. */
-/* Output: */
-/* RMS - Root Mean Square energy */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int energy_(integer *len, real *speech, real *rms)
-{
- /* System generated locals */
- integer i__1;
-
- /* Builtin functions */
- double sqrt(doublereal);
-
- /* Local variables */
- integer i__;
-
-/* Arguments */
-/* Local variables that need not be saved */
- /* Parameter adjustments */
- --speech;
-
- /* Function Body */
- *rms = 0.f;
- i__1 = *len;
- for (i__ = 1; i__ <= i__1; ++i__) {
- *rms += speech[i__] * speech[i__];
- }
- *rms = (real)sqrt(*rms / *len);
- return 0;
-} /* energy_ */
-
diff --git a/1.4/codecs/lpc10/f2c.h b/1.4/codecs/lpc10/f2c.h
deleted file mode 100644
index e50d642e0..000000000
--- a/1.4/codecs/lpc10/f2c.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:26:28 jaf
- * Any typedef defining a type that was used in lpc10_encoder_state or
- * lpc10_decoder_state struct's was commented out here and added to
- * lpc10.h.
- *
- * Revision 1.1 1996/08/19 22:32:13 jaf
- * Initial revision
- *
-
-*/
-
-/*
- * f2c.h
- *
- * SCCS ID: @(#)f2c.h 1.2 96/05/19
- */
-
-/* f2c.h -- Standard Fortran to C header file */
-
-/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
-
- - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */
-
-#ifndef F2C_INCLUDE
-#define F2C_INCLUDE
-
-#include "lpc10.h"
-
-/*typedef long int integer;*/
-/*typedef INT32 integer;*/
-/*typedef short int shortint;*/
-/*typedef INT16 shortint;*/
-/*typedef float real;*/
-/* doublereal only used for function arguments to sqrt, exp, etc. */
-typedef double doublereal;
-/* 32 bits seems wasteful, but there really aren't that many logical
- * variables around, and making them 32 bits could avoid word
- * alignment problems, perhaps. */
-/*typedef long int logical;*/
-/*typedef INT32 logical;*/
-/* The following types are not used in the translated C code for the
- * LPC-10 coder, but they might be needed by the definitions down
- * below, so they don't cause compilation errors. */
-typedef char *address;
-typedef struct { real r, i; } complex;
-typedef struct { doublereal r, i; } doublecomplex;
-typedef short int shortlogical;
-typedef char logical1;
-typedef char integer1;
-/* typedef long long longint; */ /* system-dependent */
-
-#define TRUE_ (1)
-#define FALSE_ (0)
-
-/* Extern is for use with -E */
-#ifndef Extern
-#define Extern extern
-#endif
-
-/* I/O stuff */
-
-#ifdef f2c_i2
-/* for -i2 */
-typedef short flag;
-typedef short ftnlen;
-typedef short ftnint;
-#else
-typedef long int flag;
-typedef long int ftnlen;
-typedef long int ftnint;
-#endif
-
-/*external read, write*/
-typedef struct
-{ flag cierr;
- ftnint ciunit;
- flag ciend;
- char *cifmt;
- ftnint cirec;
-} cilist;
-
-/*internal read, write*/
-typedef struct
-{ flag icierr;
- char *iciunit;
- flag iciend;
- char *icifmt;
- ftnint icirlen;
- ftnint icirnum;
-} icilist;
-
-/*open*/
-typedef struct
-{ flag oerr;
- ftnint ounit;
- char *ofnm;
- ftnlen ofnmlen;
- char *osta;
- char *oacc;
- char *ofm;
- ftnint orl;
- char *oblnk;
-} olist;
-
-/*close*/
-typedef struct
-{ flag cerr;
- ftnint cunit;
- char *csta;
-} cllist;
-
-/*rewind, backspace, endfile*/
-typedef struct
-{ flag aerr;
- ftnint aunit;
-} alist;
-
-/* inquire */
-typedef struct
-{ flag inerr;
- ftnint inunit;
- char *infile;
- ftnlen infilen;
- ftnint *inex; /*parameters in standard's order*/
- ftnint *inopen;
- ftnint *innum;
- ftnint *innamed;
- char *inname;
- ftnlen innamlen;
- char *inacc;
- ftnlen inacclen;
- char *inseq;
- ftnlen inseqlen;
- char *indir;
- ftnlen indirlen;
- char *infmt;
- ftnlen infmtlen;
- char *inform;
- ftnint informlen;
- char *inunf;
- ftnlen inunflen;
- ftnint *inrecl;
- ftnint *innrec;
- char *inblank;
- ftnlen inblanklen;
-} inlist;
-
-#define VOID void
-
-union Multitype { /* for multiple entry points */
- integer1 g;
- shortint h;
- integer i;
- /* longint j; */
- real r;
- doublereal d;
- complex c;
- doublecomplex z;
- };
-
-typedef union Multitype Multitype;
-
-/*typedef long int Long;*/ /* No longer used; formerly in Namelist */
-
-struct Vardesc { /* for Namelist */
- char *name;
- char *addr;
- ftnlen *dims;
- int type;
- };
-typedef struct Vardesc Vardesc;
-
-struct Namelist {
- char *name;
- Vardesc **vars;
- int nvars;
- };
-typedef struct Namelist Namelist;
-
-#define abs(x) ((x) >= 0 ? (x) : -(x))
-#define dabs(x) (doublereal)abs(x)
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-#define max(a,b) ((a) >= (b) ? (a) : (b))
-#define dmin(a,b) (doublereal)min(a,b)
-#define dmax(a,b) (doublereal)max(a,b)
-
-/* procedure parameter types for -A and -C++ */
-
-#define F2C_proc_par_types 1
-#ifdef __cplusplus
-typedef int /* Unknown procedure type */ (*U_fp)(...);
-typedef shortint (*J_fp)(...);
-typedef integer (*I_fp)(...);
-typedef real (*R_fp)(...);
-typedef doublereal (*D_fp)(...), (*E_fp)(...);
-typedef /* Complex */ VOID (*C_fp)(...);
-typedef /* Double Complex */ VOID (*Z_fp)(...);
-typedef logical (*L_fp)(...);
-typedef shortlogical (*K_fp)(...);
-typedef /* Character */ VOID (*H_fp)(...);
-typedef /* Subroutine */ int (*S_fp)(...);
-#else
-typedef int /* Unknown procedure type */ (*U_fp)(VOID);
-typedef shortint (*J_fp)(VOID);
-typedef integer (*I_fp)(VOID);
-typedef real (*R_fp)(VOID);
-typedef doublereal (*D_fp)(VOID), (*E_fp)(VOID);
-typedef /* Complex */ VOID (*C_fp)(VOID);
-typedef /* Double Complex */ VOID (*Z_fp)(VOID);
-typedef logical (*L_fp)(VOID);
-typedef shortlogical (*K_fp)(VOID);
-typedef /* Character */ VOID (*H_fp)(VOID);
-typedef /* Subroutine */ int (*S_fp)(VOID);
-#endif
-/* E_fp is for real functions when -R is not specified */
-typedef VOID C_f; /* complex function */
-typedef VOID H_f; /* character function */
-typedef VOID Z_f; /* double complex function */
-typedef doublereal E_f; /* real function with -R not specified */
-
-/* undef any lower-case symbols that your C compiler predefines, e.g.: */
-
-#ifndef Skip_f2c_Undefs
-#undef cray
-#undef gcos
-#undef mc68010
-#undef mc68020
-#undef mips
-#undef pdp11
-#undef sgi
-#undef sparc
-#undef sun
-#undef sun2
-#undef sun3
-#undef sun4
-#undef u370
-#undef u3b
-#undef u3b2
-#undef u3b5
-#undef unix
-#undef vax
-#endif
-
-#ifdef KR_headers
-extern integer pow_ii(ap, bp);
-extern double r_sign(a,b);
-extern integer i_nint(x);
-#else
-extern integer pow_ii(integer *ap, integer *bp);
-extern double r_sign(real *a, real *b);
-extern integer i_nint(real *x);
-
-#endif
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int bsynz_(real *coef, integer *ip, integer *iv,
- real *sout, real *rms, real *ratio, real *g2pass,
- struct lpc10_decoder_state *st);
-extern int chanwr_(integer *order, integer *ipitv, integer *irms,
- integer *irc, integer *ibits, struct lpc10_encoder_state *st);
-extern int chanrd_(integer *order, integer *ipitv, integer *irms,
- integer *irc, integer *ibits);
-extern int chanwr_0_(int n__, integer *order, integer *ipitv,
- integer *irms, integer *irc, integer *ibits,
- struct lpc10_encoder_state *st);
-extern int dcbias_(integer *len, real *speech, real *sigout);
-extern int decode_(integer *ipitv, integer *irms, integer *irc,
- integer *voice, integer *pitch, real *rms,
- real *rc, struct lpc10_decoder_state *st);
-extern int deemp_(real *x, integer *n, struct lpc10_decoder_state *st);
-extern int difmag_(real *speech, integer *lpita, integer *tau, integer *ltau,
- integer *maxlag, real *amdf, integer *minptr, integer *maxptr);
-extern int dyptrk_(real *amdf, integer *ltau, integer *
- minptr, integer *voice, integer *pitch, integer *midx,
- struct lpc10_encoder_state *st);
-extern int encode_(integer *voice, integer *pitch, real *rms, real *rc,
- integer *ipitch, integer *irms, integer *irc);
-extern int energy_(integer *len, real *speech, real *rms);
-extern int ham84_(integer *input, integer *output, integer *errcnt);
-extern int hp100_(real *speech, integer *start, integer *end,
- struct lpc10_encoder_state *st);
-extern int inithp100_(void);
-extern int invert_(integer *order, real *phi, real *psi, real *rc);
-extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pass);
-extern int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer *nsamp, real *ivrc);
-extern int lpcdec_(integer *bits, real *speech);
-extern int initlpcdec_(void);
-extern int lpcenc_(real *speech, integer *bits);
-extern int initlpcenc_(void);
-extern int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer *nsamp);
-extern integer median_(integer *d1, integer *d2, integer *d3);
-extern int mload_(integer *order, integer *awins, integer *awinf, real *speech, real *phi, real *psi);
-extern int onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st);
-extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv, integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio, struct lpc10_decoder_state *st);
-extern int placea_(integer *ipitch, integer *voibuf, integer *obound, integer *af, integer *vwin, integer *awin, integer *ewin, integer *lframe, integer *maxwin);
-extern int placev_(integer *osbuf, integer *osptr, integer *oslen, integer *obound, integer *vwin, integer *af, integer *lframe, integer *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh);
-extern int preemp_(real *inbuf, real *pebuf, integer *nsamp, real *coef, real *z__);
-extern int prepro_(real *speech, integer *length,
- struct lpc10_encoder_state *st);
-extern int decode_(integer *ipitv, integer *irms, integer *irc, integer *voice, integer *pitch, real *rms, real *rc, struct lpc10_decoder_state *st);
-extern integer random_(struct lpc10_decoder_state *st);
-extern int rcchk_(integer *order, real *rc1f, real *rc2f);
-extern int synths_(integer *voice, integer *pitch, real *rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st);
-extern int tbdm_(real *speech, integer *lpita, integer *tau, integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer *mintau);
-extern int voicin_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, integer *mintau, real *ivrc, integer *obound, integer *voibuf, integer *af, struct lpc10_encoder_state *st);
-extern int vparms_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *dither, integer *mintau, integer *zc, integer *lbe, integer *fbe, real *qs, real *rc1, real *ar_b__, real *ar_f__);
-
-#endif
-
-
-#endif /* ! defined F2C_INCLUDE */
diff --git a/1.4/codecs/lpc10/f2clib.c b/1.4/codecs/lpc10/f2clib.c
deleted file mode 100644
index 037172828..000000000
--- a/1.4/codecs/lpc10/f2clib.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-
-$Log$
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:32:10 jaf
- * Initial revision
- *
-
-*/
-
-/*
- * f2clib.c
- *
- * SCCS ID: @(#)f2clib.c 1.2 96/05/19
- */
-
-#include "f2c.h"
-
-#ifdef KR_headers
-integer pow_ii(ap, bp) integer *ap, *bp;
-#else
-integer pow_ii(integer *ap, integer *bp)
-#endif
-{
- integer pow, x, n;
- unsigned long u;
-
- x = *ap;
- n = *bp;
-
- if (n <= 0) {
- if (n == 0 || x == 1)
- return 1;
- if (x != -1)
- return x == 0 ? 0 : 1/x;
- n = -n;
- }
- u = n;
- for(pow = 1; ; )
- {
- if(u & 01)
- pow *= x;
- if(u >>= 1)
- x *= x;
- else
- break;
- }
- return(pow);
- }
-
-
-
-#ifdef KR_headers
-double r_sign(a,b) real *a, *b;
-#else
-double r_sign(real *a, real *b)
-#endif
-{
-double x;
-x = (*a >= 0 ? *a : - *a);
-return( *b >= 0 ? x : -x);
-}
-
-
-
-#ifdef KR_headers
-double floor();
-integer i_nint(x) real *x;
-#else
-#undef abs
-#include "math.h"
-integer i_nint(real *x)
-#endif
-{
-return( (integer)((*x)>=0 ?
- floor(*x + .5) : -floor(.5 - *x)) );
-}
diff --git a/1.4/codecs/lpc10/ham84.c b/1.4/codecs/lpc10/ham84.c
deleted file mode 100644
index fddd8f3c0..000000000
--- a/1.4/codecs/lpc10/ham84.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:32:07 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int ham84_(integer *input, integer *output, integer *errcnt);
-#endif
-
-/* ***************************************************************** */
-
-/* HAM84 Version 45G */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:07 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/21 15:26:00 jaf */
-/* Put comment header in standard form. */
-
-/* Revision 1.2 1996/03/13 22:00:13 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:47:04 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Hamming 8,4 Decoder - can correct 1 out of seven bits */
-/* and can detect up to two errors. */
-
-/* Input: */
-/* INPUT - Seven bit data word, 4 bits parameter and */
-/* 4 bits parity information */
-/* Input/Output: */
-/* ERRCNT - Sums errors detected by Hamming code */
-/* Output: */
-/* OUTPUT - 4 corrected parameter bits */
-
-/* This subroutine is entered with an eight bit word in INPUT. The 8th */
-/* bit is parity and is stripped off. The remaining 7 bits address the */
-/* hamming 8,4 table and the output OUTPUT from the table gives the 4 */
-/* bits of corrected data. If bit 4 is set, no error was detected. */
-/* ERRCNT is the number of errors counted. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int ham84_(integer *input, integer *output, integer *errcnt)
-{
- /* Initialized data */
-
- static integer dactab[128] = { 16,0,0,3,0,5,14,7,0,9,14,11,14,13,30,14,0,
- 9,2,7,4,7,7,23,9,25,10,9,12,9,14,7,0,5,2,11,5,21,6,5,8,11,11,27,
- 12,5,14,11,2,1,18,2,12,5,2,7,12,9,2,11,28,12,12,15,0,3,3,19,4,13,
- 6,3,8,13,10,3,13,29,14,13,4,1,10,3,20,4,4,7,10,9,26,10,4,13,10,15,
- 8,1,6,3,6,5,22,6,24,8,8,11,8,13,6,15,1,17,2,1,4,1,6,15,8,1,10,15,
- 12,15,15,31 };
-
- integer i__, j, parity;
-
-/* Arguments */
-/* Parameters/constants */
-/* Local variables that need not be saved */
-/* Determine parity of input word */
- parity = *input & 255;
- parity ^= parity / 16;
- parity ^= parity / 4;
- parity ^= parity / 2;
- parity &= 1;
- i__ = dactab[*input & 127];
- *output = i__ & 15;
- j = i__ & 16;
- if (j != 0) {
-/* No errors detected in seven bits */
- if (parity != 0) {
- ++(*errcnt);
- }
- } else {
-/* One or two errors detected */
- ++(*errcnt);
- if (parity == 0) {
-/* Two errors detected */
- ++(*errcnt);
- *output = -1;
- }
- }
- return 0;
-} /* ham84_ */
-
diff --git a/1.4/codecs/lpc10/hp100.c b/1.4/codecs/lpc10/hp100.c
deleted file mode 100644
index 9df9e5939..000000000
--- a/1.4/codecs/lpc10/hp100.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:28:05 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:04 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int hp100_(real *speech, integer *start, integer *end,
- struct lpc10_encoder_state *st);
-extern int inithp100_(void);
-#endif
-
-/* ********************************************************************* */
-
-/* HP100 Version 55 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:28:05 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:32:04 jaf
- * Initial revision
- * */
-/* Revision 1.6 1996/03/15 16:45:25 jaf */
-/* Rearranged a few comments. */
-
-/* Revision 1.5 1996/03/14 23:20:54 jaf */
-/* Added comments about when INITHP100 should be used. */
-
-/* Revision 1.4 1996/03/14 23:08:08 jaf */
-/* Added an entry named INITHP100 that initializes the local state of */
-/* subroutine HP100. */
-
-/* Revision 1.3 1996/03/14 22:09:20 jaf */
-/* Comments added explaining which of the local variables of this */
-/* subroutine need to be saved from one invocation to the next, and which */
-/* do not. */
-
-/* Revision 1.2 1996/02/12 15:05:54 jaf */
-/* Added lots of comments explaining why I changed one line, which was a */
-/* declaration with initializations. */
-
-/* Revision 1.1 1996/02/07 14:47:12 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* 100 Hz High Pass Filter */
-
-/* Jan 92 - corrected typo (1.937148 to 1.935715), */
-/* rounded coefficients to 7 places, */
-/* corrected and merged gain (.97466**4), */
-/* merged numerator into first two sections. */
-
-/* Input: */
-/* start, end - Range of samples to filter */
-/* Input/Output: */
-/* speech(end) - Speech data. */
-/* Indices start through end are read and modified. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITHP100. */
-/* Subroutine */ int hp100_(real *speech, integer *start, integer *end,
- struct lpc10_encoder_state *st)
-{
- /* Temporary local copies of variables in lpc10_encoder_state.
- I've only created these because it might cause the loop below
- to execute a bit faster to access local variables, rather than
- variables in the lpc10_encoder_state structure. It is just a
- guess that it will be faster. */
-
- real z11;
- real z21;
- real z12;
- real z22;
-
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- integer i__;
- real si, err;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Local state */
- /* Parameter adjustments */
- if (speech) {
- --speech;
- }
-
- /* Function Body */
-
- z11 = st->z11;
- z21 = st->z21;
- z12 = st->z12;
- z22 = st->z22;
-
- i__1 = *end;
- for (i__ = *start; i__ <= i__1; ++i__) {
- si = speech[i__];
- err = si + z11 * 1.859076f - z21 * .8648249f;
- si = err - z11 * 2.f + z21;
- z21 = z11;
- z11 = err;
- err = si + z12 * 1.935715f - z22 * .9417004f;
- si = err - z12 * 2.f + z22;
- z22 = z12;
- z12 = err;
- speech[i__] = si * .902428f;
- }
-
- st->z11 = z11;
- st->z21 = z21;
- st->z12 = z12;
- st->z22 = z22;
-
- return 0;
-} /* hp100_ */
diff --git a/1.4/codecs/lpc10/invert.c b/1.4/codecs/lpc10/invert.c
deleted file mode 100644
index 912117f9c..000000000
--- a/1.4/codecs/lpc10/invert.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:32:00 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int invert_(integer *order, real *phi, real *psi, real *rc);
-#endif
-
-/* **************************************************************** */
-
-/* INVERT Version 45G */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:00 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/18 20:52:47 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 16:51:32 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Eliminated a comment from the original, describing a local array X */
-/* that appeared nowhere in the code. */
-
-/* Revision 1.1 1996/02/07 14:47:20 jaf */
-/* Initial revision */
-
-
-/* **************************************************************** */
-
-/* Invert a covariance matrix using Choleski decomposition method. */
-
-/* Input: */
-/* ORDER - Analysis order */
-/* PHI(ORDER,ORDER) - Covariance matrix */
-/* Indices (I,J) read, where ORDER .GE. I .GE. J .GE. 1.*/
-/* All other indices untouched. */
-/* PSI(ORDER) - Column vector to be predicted */
-/* Indices 1 through ORDER read. */
-/* Output: */
-/* RC(ORDER) - Pseudo reflection coefficients */
-/* Indices 1 through ORDER written, and then possibly read.
-*/
-/* Internal: */
-/* V(ORDER,ORDER) - Temporary matrix */
-/* Same indices written as read from PHI. */
-/* Many indices may be read and written again after */
-/* initially being copied from PHI, but all indices */
-/* are written before being read. */
-
-/* NOTE: Temporary matrix V is not needed and may be replaced */
-/* by PHI if the original PHI values do not need to be preserved. */
-
-/* Subroutine */ int invert_(integer *order, real *phi, real *psi, real *rc)
-{
- /* System generated locals */
- integer phi_dim1, phi_offset, i__1, i__2, i__3;
- real r__1, r__2;
-
- /* Local variables */
- real save;
- integer i__, j, k;
- real v[100] /* was [10][10] */;
-
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:32:00 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Parameters/constants */
-/* Local variables that need not be saved */
-/* Decompose PHI into V * D * V' where V is a triangular matrix whose */
-/* main diagonal elements are all 1, V' is the transpose of V, and */
-/* D is a vector. Here D(n) is stored in location V(n,n). */
- /* Parameter adjustments */
- --rc;
- --psi;
- phi_dim1 = *order;
- phi_offset = phi_dim1 + 1;
- phi -= phi_offset;
-
- /* Function Body */
- i__1 = *order;
- for (j = 1; j <= i__1; ++j) {
- i__2 = *order;
- for (i__ = j; i__ <= i__2; ++i__) {
- v[i__ + j * 10 - 11] = phi[i__ + j * phi_dim1];
- }
- i__2 = j - 1;
- for (k = 1; k <= i__2; ++k) {
- save = v[j + k * 10 - 11] * v[k + k * 10 - 11];
- i__3 = *order;
- for (i__ = j; i__ <= i__3; ++i__) {
- v[i__ + j * 10 - 11] -= v[i__ + k * 10 - 11] * save;
- }
- }
-/* Compute intermediate results, which are similar to RC's */
- if ((r__1 = v[j + j * 10 - 11], abs(r__1)) < 1e-10f) {
- goto L100;
- }
- rc[j] = psi[j];
- i__2 = j - 1;
- for (k = 1; k <= i__2; ++k) {
- rc[j] -= rc[k] * v[j + k * 10 - 11];
- }
- v[j + j * 10 - 11] = 1.f / v[j + j * 10 - 11];
- rc[j] *= v[j + j * 10 - 11];
-/* Computing MAX */
-/* Computing MIN */
- r__2 = rc[j];
- r__1 = min(r__2,.999f);
- rc[j] = max(r__1,-.999f);
- }
- return 0;
-/* Zero out higher order RC's if algorithm terminated early */
-L100:
- i__1 = *order;
- for (i__ = j; i__ <= i__1; ++i__) {
- rc[i__] = 0.f;
- }
-/* Back substitute for PC's (if needed) */
-/* 110 DO J = ORDER,1,-1 */
-/* PC(J) = RC(J) */
-/* DO I = 1,J-1 */
-/* PC(J) = PC(J) - PC(I)*V(J,I) */
-/* END DO */
-/* END DO */
- return 0;
-} /* invert_ */
-
diff --git a/1.4/codecs/lpc10/irc2pc.c b/1.4/codecs/lpc10/irc2pc.c
deleted file mode 100644
index b96ff0d66..000000000
--- a/1.4/codecs/lpc10/irc2pc.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:56 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pass);
-#endif
-
-/* ***************************************************************** */
-
-/* IRC2PC Version 48 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:56 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/20 15:47:19 jaf */
-/* Added comments about which indices of array arguments are read or */
-/* written. */
-
-/* Revision 1.2 1996/03/14 16:59:04 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:47:27 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Convert Reflection Coefficients to Predictor Coeficients */
-
-/* Inputs: */
-/* RC - Reflection coefficients */
-/* Indices 1 through ORDER read. */
-/* ORDER - Number of RC's */
-/* GPRIME - Excitation modification gain */
-/* Outputs: */
-/* PC - Predictor coefficients */
-/* Indices 1 through ORDER written. */
-/* Indices 1 through ORDER-1 are read after being written. */
-/* G2PASS - Excitation modification sharpening factor */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int irc2pc_(real *rc, real *pc, integer *order, real *gprime,
- real *g2pass)
-{
- /* System generated locals */
- integer i__1, i__2;
-
- /* Builtin functions */
- double sqrt(doublereal);
-
- /* Local variables */
- real temp[10];
- integer i__, j;
-
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:56 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Local variables that need not be saved */
- /* Parameter adjustments */
- --pc;
- --rc;
-
- /* Function Body */
- *g2pass = 1.f;
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- *g2pass *= 1.f - rc[i__] * rc[i__];
- }
- *g2pass = *gprime * (real)sqrt(*g2pass);
- pc[1] = rc[1];
- i__1 = *order;
- for (i__ = 2; i__ <= i__1; ++i__) {
- i__2 = i__ - 1;
- for (j = 1; j <= i__2; ++j) {
- temp[j - 1] = pc[j] - rc[i__] * pc[i__ - j];
- }
- i__2 = i__ - 1;
- for (j = 1; j <= i__2; ++j) {
- pc[j] = temp[j - 1];
- }
- pc[i__] = rc[i__];
- }
- return 0;
-} /* irc2pc_ */
-
diff --git a/1.4/codecs/lpc10/ivfilt.c b/1.4/codecs/lpc10/ivfilt.c
deleted file mode 100644
index 784de2571..000000000
--- a/1.4/codecs/lpc10/ivfilt.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.2 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:53 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer *nsamp, real *ivrc);
-#endif
-
-/* ********************************************************************* */
-
-/* IVFILT Version 48 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:53 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/15 21:36:29 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 00:01:00 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:47:34 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* 2nd order inverse filter, speech is decimated 4:1 */
-
-/* Input: */
-/* LEN - Length of speech buffers */
-/* NSAMP - Number of samples to filter */
-/* LPBUF - Low pass filtered speech buffer */
-/* Indices LEN-NSAMP-7 through LEN read. */
-/* Output: */
-/* IVBUF - Inverse filtered speech buffer */
-/* Indices LEN-NSAMP+1 through LEN written. */
-/* IVRC - Inverse filter reflection coefficients (for voicing) */
-/* Indices 1 and 2 both written (also read, but only after writing).
-*/
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer *
- nsamp, real *ivrc)
-{
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- integer i__, j, k;
- real r__[3], pc1, pc2;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Local state */
-/* None */
-/* Calculate Autocorrelations */
- /* Parameter adjustments */
- --ivbuf;
- --lpbuf;
- --ivrc;
-
- /* Function Body */
- for (i__ = 1; i__ <= 3; ++i__) {
- r__[i__ - 1] = 0.f;
- k = (i__ - 1) << 2;
- i__1 = *len;
- for (j = (i__ << 2) + *len - *nsamp; j <= i__1; j += 2) {
- r__[i__ - 1] += lpbuf[j] * lpbuf[j - k];
- }
- }
-/* Calculate predictor coefficients */
- pc1 = 0.f;
- pc2 = 0.f;
- ivrc[1] = 0.f;
- ivrc[2] = 0.f;
- if (r__[0] > 1e-10f) {
- ivrc[1] = r__[1] / r__[0];
- ivrc[2] = (r__[2] - ivrc[1] * r__[1]) / (r__[0] - ivrc[1] * r__[1]);
- pc1 = ivrc[1] - ivrc[1] * ivrc[2];
- pc2 = ivrc[2];
- }
-/* Inverse filter LPBUF into IVBUF */
- i__1 = *len;
- for (i__ = *len + 1 - *nsamp; i__ <= i__1; ++i__) {
- ivbuf[i__] = lpbuf[i__] - pc1 * lpbuf[i__ - 4] - pc2 * lpbuf[i__ - 8];
- }
- return 0;
-} /* ivfilt_ */
-
diff --git a/1.4/codecs/lpc10/liblpc10.vcproj b/1.4/codecs/lpc10/liblpc10.vcproj
deleted file mode 100644
index a2449a109..000000000
--- a/1.4/codecs/lpc10/liblpc10.vcproj
+++ /dev/null
@@ -1,305 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="liblpc10"
- ProjectGUID="{FF1D238A-9D59-4850-838E-78182E05736B}"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;P_R_O_T_O_T_Y_P_E_S"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;P_R_O_T_O_T_Y_P_E_S"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\f2c.h"
- >
- </File>
- <File
- RelativePath=".\lpc10.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath=".\analys.c"
- >
- </File>
- <File
- RelativePath=".\bsynz.c"
- >
- </File>
- <File
- RelativePath=".\chanwr.c"
- >
- </File>
- <File
- RelativePath=".\dcbias.c"
- >
- </File>
- <File
- RelativePath=".\decode.c"
- >
- </File>
- <File
- RelativePath=".\deemp.c"
- >
- </File>
- <File
- RelativePath=".\difmag.c"
- >
- </File>
- <File
- RelativePath=".\dyptrk.c"
- >
- </File>
- <File
- RelativePath=".\encode.c"
- >
- </File>
- <File
- RelativePath=".\energy.c"
- >
- </File>
- <File
- RelativePath=".\f2clib.c"
- >
- </File>
- <File
- RelativePath=".\ham84.c"
- >
- </File>
- <File
- RelativePath=".\hp100.c"
- >
- </File>
- <File
- RelativePath=".\invert.c"
- >
- </File>
- <File
- RelativePath=".\irc2pc.c"
- >
- </File>
- <File
- RelativePath=".\ivfilt.c"
- >
- </File>
- <File
- RelativePath=".\lpcdec.c"
- >
- </File>
- <File
- RelativePath=".\lpcenc.c"
- >
- </File>
- <File
- RelativePath=".\lpcini.c"
- >
- </File>
- <File
- RelativePath=".\lpfilt.c"
- >
- </File>
- <File
- RelativePath=".\median.c"
- >
- </File>
- <File
- RelativePath=".\mload.c"
- >
- </File>
- <File
- RelativePath=".\onset.c"
- >
- </File>
- <File
- RelativePath=".\pitsyn.c"
- >
- </File>
- <File
- RelativePath=".\placea.c"
- >
- </File>
- <File
- RelativePath=".\placev.c"
- >
- </File>
- <File
- RelativePath=".\preemp.c"
- >
- </File>
- <File
- RelativePath=".\prepro.c"
- >
- </File>
- <File
- RelativePath=".\random.c"
- >
- </File>
- <File
- RelativePath=".\rcchk.c"
- >
- </File>
- <File
- RelativePath=".\synths.c"
- >
- </File>
- <File
- RelativePath=".\tbdm.c"
- >
- </File>
- <File
- RelativePath=".\voicin.c"
- >
- </File>
- <File
- RelativePath=".\vparms.c"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/1.4/codecs/lpc10/lpc10.h b/1.4/codecs/lpc10/lpc10.h
deleted file mode 100644
index a57f84f3f..000000000
--- a/1.4/codecs/lpc10/lpc10.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-
-$Log$
-Revision 1.18 2004/08/31 13:32:11 markster
-Merge NetBSD and Courtesty tone with modifications (bug #2329)
-
-Revision 1.17 2003/10/26 18:50:49 markster
-Make it build and run on MacOS X
-
-Revision 1.3 2003/10/26 18:50:49 markster
-Make it build and run on MacOS X
-
-Revision 1.2 2003/04/23 19:13:35 markster
-More OpenBSD patches
-
-Revision 1.1.1.2 2003/03/16 22:37:30 matteo
-dom mar 16 23:37:23 CET 2003
-
-Revision 1.2 2003/03/16 16:09:48 markster
-Mere James's cleanups for fewer build warnings
-
-Revision 1.1 2000/01/05 00:20:06 markster
-Add broken lpc10 code... It's not too far from working I don't think...
-
- * Revision 1.1 1996/08/19 22:47:31 jaf
- * Initial revision
- *
-
-*/
-
-#ifndef __LPC10_H__
-#define __LPC10_H__
-
-#define P_R_O_T_O_T_Y_P_E_S
-
-#define LPC10_SAMPLES_PER_FRAME 180
-#define LPC10_BITS_IN_COMPRESSED_FRAME 54
-
-
-/*
-
- The "#if defined"'s in this file are by no means intended to be
- complete. They are what Nautilus uses, which has been successfully
- compiled under DOS with the Microsoft C compiler, and under a few
- versions of Unix with the GNU C compiler.
-
- */
-
-#if defined(unix) || defined(__unix__) || defined(__NetBSD__)
-typedef short INT16;
-typedef int INT32;
-#endif
-
-
-#if defined(__MSDOS__) || defined(MSDOS)
-typedef int INT16;
-typedef long INT32;
-#endif
-
-#if defined(__APPLE__)
-typedef short INT16;
-typedef int INT32;
-#endif
-
-#if defined(WIN32) && defined(_MSC_VER)
-typedef __int16 INT16;
-typedef __int32 INT32;
-#pragma warning(disable: 4005)
-#endif
-
-
-/* The initial values for every member of this structure is 0, except
- where noted in comments. */
-
-/* These two lines are copied from f2c.h. There should be a more
- elegant way of doing this than having the same declarations in two
- files. */
-
-typedef float real;
-typedef INT32 integer;
-typedef INT32 logical;
-typedef INT16 shortint;
-
-struct lpc10_encoder_state {
- /* State used only by function hp100 */
- real z11;
- real z21;
- real z12;
- real z22;
-
- /* State used by function analys */
- real inbuf[540], pebuf[540];
- real lpbuf[696], ivbuf[312];
- real bias;
- integer osbuf[10]; /* no initial value necessary */
- integer osptr; /* initial value 1 */
- integer obound[3];
- integer vwin[6] /* was [2][3] */; /* initial value vwin[4] = 307; vwin[5] = 462; */
- integer awin[6] /* was [2][3] */; /* initial value awin[4] = 307; awin[5] = 462; */
- integer voibuf[8] /* was [2][4] */;
- real rmsbuf[3];
- real rcbuf[30] /* was [10][3] */;
- real zpre;
-
-
- /* State used by function onset */
- real n;
- real d__; /* initial value 1.f */
- real fpc; /* no initial value necessary */
- real l2buf[16];
- real l2sum1;
- integer l2ptr1; /* initial value 1 */
- integer l2ptr2; /* initial value 9 */
- integer lasti; /* no initial value necessary */
- logical hyst; /* initial value FALSE_ */
-
- /* State used by function voicin */
- real dither; /* initial value 20.f */
- real snr;
- real maxmin;
- real voice[6] /* was [2][3] */; /* initial value is probably unnecessary */
- integer lbve, lbue, fbve, fbue;
- integer ofbue, sfbue;
- integer olbue, slbue;
- /* Initial values:
- lbve = 3000;
- fbve = 3000;
- fbue = 187;
- ofbue = 187;
- sfbue = 187;
- lbue = 93;
- olbue = 93;
- slbue = 93;
- snr = (real) (fbve / fbue << 6);
- */
-
- /* State used by function dyptrk */
- real s[60];
- integer p[120] /* was [60][2] */;
- integer ipoint;
- real alphax;
-
- /* State used by function chanwr */
- integer isync;
-
-};
-
-
-struct lpc10_decoder_state {
-
- /* State used by function decode */
- integer iptold; /* initial value 60 */
- logical first; /* initial value TRUE_ */
- integer ivp2h;
- integer iovoic;
- integer iavgp; /* initial value 60 */
- integer erate;
- integer drc[30] /* was [3][10] */;
- integer dpit[3];
- integer drms[3];
-
- /* State used by function synths */
- real buf[360];
- integer buflen; /* initial value 180 */
-
- /* State used by function pitsyn */
- integer ivoico; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- integer ipito; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- real rmso; /* initial value 1.f */
- real rco[10]; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- integer jsamp; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- logical first_pitsyn; /* initial value TRUE_ */
-
- /* State used by function bsynz */
- integer ipo;
- real exc[166];
- real exc2[166];
- real lpi1;
- real lpi2;
- real lpi3;
- real hpi1;
- real hpi2;
- real hpi3;
- real rmso_bsynz;
-
- /* State used by function random */
- integer j; /* initial value 2 */
- integer k; /* initial value 5 */
- shortint y[5]; /* initial value { -21161,-8478,30892,-10216,16950 } */
-
- /* State used by function deemp */
- real dei1;
- real dei2;
- real deo1;
- real deo2;
- real deo3;
-
-};
-
-
-
-/*
-
- Calling sequence:
-
- Call create_lpc10_encoder_state(), which returns a pointer to an
- already initialized lpc10_encoder_state structure.
-
- lpc10_encode reads indices 0 through (LPC10_SAMPLES_PER_FRAME-1) of
- array speech[], and writes indices 0 through
- (LPC10_BITS_IN_COMPRESSED_FRAME-1) of array bits[], and both reads
- and writes the lpc10_encoder_state structure contents. The
- lpc10_encoder_state structure should *not* be initialized for every
- frame of encoded speech. Once at the beginning of execution, done
- automatically for you by create_lpc10_encoder_state(), is enough.
-
- init_lpc10_encoder_state() reinitializes the lpc10_encoder_state
- structure. This might be useful if you are finished processing one
- sound sample, and want to reuse the same lpc10_encoder_state
- structure to process another sound sample. There might be other
- uses as well.
-
- Note that the comments in the lpc10/lpcenc.c file imply that indices
- 1 through 180 of array speech[] are read. These comments were
- written for the Fortran version of the code, before it was
- automatically converted to C by the conversion program f2c. f2c
- seems to use the convention that the pointers to arrays passed as
- function arguments point to the first index used in the Fortran
- code, whatever index that might be (usually 1), and then it modifies
- the pointer inside of the function, like so:
-
- if (speech) {
- --speech;
- }
-
- So that the code can access the first value at index 1 and the last
- at index 180. This makes the translated C code "closer" to the
- original Fortran code.
-
- The calling sequence for the decoder is similar to the encoder. The
- only significant difference is that the array bits[] is read
- (indices 0 through (LPC10_BITS_IN_COMPRESSED_FRAME-1)), and the
- array speech[] is written (indices 0 through
- (LPC10_SAMPLES_PER_FRAME-1)).
-
- */
-
-struct lpc10_encoder_state * create_lpc10_encoder_state (void);
-void init_lpc10_encoder_state (struct lpc10_encoder_state *st);
-int lpc10_encode (real *speech, INT32 *bits, struct lpc10_encoder_state *st);
-
-struct lpc10_decoder_state * create_lpc10_decoder_state (void);
-void init_lpc10_decoder_state (struct lpc10_decoder_state *st);
-int lpc10_decode (INT32 *bits, real *speech, struct lpc10_decoder_state *st);
-
-#endif /* __LPC10_H__ */
diff --git a/1.4/codecs/lpc10/lpcdec.c b/1.4/codecs/lpc10/lpcdec.c
deleted file mode 100644
index dd859ffce..000000000
--- a/1.4/codecs/lpc10/lpcdec.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:30:11 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:48 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int lpcdec_(integer *bits, real *speech);
-extern int initlpcdec_(void);
-/* comlen contrl_ 12 */
-/*:ref: chanrd_ 14 5 4 4 4 4 4 */
-/*:ref: decode_ 14 7 4 4 4 4 4 6 6 */
-/*:ref: synths_ 14 6 4 4 6 6 6 4 */
-/*:ref: initdecode_ 14 0 */
-/*:ref: initsynths_ 14 0 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* Table of constant values */
-
-static integer c__10 = 10;
-
-/* ***************************************************************** */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:30:11 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:48 jaf
- * Initial revision
- * */
-/* Revision 1.1 1996/03/28 00:03:00 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Decode 54 bits to one frame of 180 speech samples. */
-
-/* Input: */
-/* BITS - 54 encoded bits, stored 1 per array element. */
-/* Indices 1 through 53 read (SYNC bit ignored). */
-/* Output: */
-/* SPEECH - Speech encoded as real values in the range [-1,+1]. */
-/* Indices 1 through 180 written. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITLPCDEC. */
-
-/* Subroutine */ int lpc10_decode(integer *bits, real *speech,
- struct lpc10_decoder_state *st)
-{
- integer irms, voice[2], pitch, ipitv;
- extern /* Subroutine */ int decode_(integer *, integer *, integer *,
- integer *, integer *, real *, real *, struct lpc10_decoder_state *);
- real rc[10];
- extern /* Subroutine */ int chanrd_(integer *, integer *, integer *,
- integer *, integer *), synths_(integer *,
- integer *, real *, real *, real *, integer *,
- struct lpc10_decoder_state *);
- integer irc[10], len;
- real rms;
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:30:11 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:48 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:30:11 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:48 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Local variables that need not be saved */
-/* Uncoded speech parameters */
-/* Coded speech parameters */
-/* Others */
-/* Local state */
-/* None */
- /* Parameter adjustments */
- if (bits) {
- --bits;
- }
- if (speech) {
- --speech;
- }
-
- /* Function Body */
-
- chanrd_(&c__10, &ipitv, &irms, irc, &bits[1]);
- decode_(&ipitv, &irms, irc, voice, &pitch, &rms, rc, st);
- synths_(voice, &pitch, &rms, rc, &speech[1], &len, st);
- return 0;
-} /* lpcdec_ */
diff --git a/1.4/codecs/lpc10/lpcenc.c b/1.4/codecs/lpc10/lpcenc.c
deleted file mode 100644
index 989a2defd..000000000
--- a/1.4/codecs/lpc10/lpcenc.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:31:21 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:44 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int lpcenc_(real *speech, integer *bits);
-extern int initlpcenc_(void);
-/*:ref: prepro_ 14 2 6 4 */
-/*:ref: analys_ 14 5 6 4 4 6 6 */
-/*:ref: encode_ 14 7 4 4 6 6 4 4 4 */
-/*:ref: chanwr_ 14 5 4 4 4 4 4 */
-/*:ref: initprepro_ 14 0 */
-/*:ref: initanalys_ 14 0 */
-#endif
-
-/* Table of constant values */
-
-static integer c__180 = 180;
-static integer c__10 = 10;
-
-/* ***************************************************************** */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:31:21 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:44 jaf
- * Initial revision
- * */
-/* Revision 1.2 1996/03/28 00:01:22 jaf */
-/* Commented out some trace statements. */
-
-/* Revision 1.1 1996/03/28 00:00:27 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Encode one frame of 180 speech samples to 54 bits. */
-
-/* Input: */
-/* SPEECH - Speech encoded as real values in the range [-1,+1]. */
-/* Indices 1 through 180 read, and modified (by PREPRO). */
-/* Output: */
-/* BITS - 54 encoded bits, stored 1 per array element. */
-/* Indices 1 through 54 written. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITLPCENC. */
-
-/* Subroutine */ int lpc10_encode(real *speech, integer *bits,
- struct lpc10_encoder_state *st)
-{
- integer irms, voice[2], pitch, ipitv;
- real rc[10];
- extern /* Subroutine */ int encode_(integer *, integer *, real *, real *,
- integer *, integer *, integer *), chanwr_(integer *, integer *,
- integer *, integer *, integer *, struct lpc10_encoder_state *),
- analys_(real *, integer *,
- integer *, real *, real *, struct lpc10_encoder_state *),
- prepro_(real *, integer *, struct lpc10_encoder_state *);
- integer irc[10];
- real rms;
-
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:31:21 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Changed name of function from lpcenc_ to lpc10_encode, simply to make
- * all lpc10 functions have more consistent naming with each other.
- *
- * Revision 1.1 1996/08/19 22:31:44 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Local variables that need not be saved */
-/* Uncoded speech parameters */
-/* Coded speech parameters */
-/* Local state */
-/* None */
- /* Parameter adjustments */
- if (speech) {
- --speech;
- }
- if (bits) {
- --bits;
- }
-
- /* Function Body */
- prepro_(&speech[1], &c__180, st);
- analys_(&speech[1], voice, &pitch, &rms, rc, st);
- encode_(voice, &pitch, &rms, rc, &ipitv, &irms, irc);
- chanwr_(&c__10, &ipitv, &irms, irc, &bits[1], st);
- return 0;
-} /* lpcenc_ */
diff --git a/1.4/codecs/lpc10/lpcini.c b/1.4/codecs/lpc10/lpcini.c
deleted file mode 100644
index ebe229a5c..000000000
--- a/1.4/codecs/lpc10/lpcini.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
-
-$Log$
-Revision 1.18 2003/10/21 18:08:11 markster
-Fix include order
-
-Revision 1.5 2003/10/21 18:08:11 markster
-Fix include order
-
-Revision 1.4 2003/10/21 02:57:29 markster
-FreeBSD patch, take 2
-
-Revision 1.3 2003/10/16 21:11:30 martinp
-Revert the previous patch since it's braking compilation
-
-Revision 1.1 2003/02/12 13:59:15 matteo
-Initial revision
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:35:41 jaf
- * Added functions for allocating and initializing lpc10_encoder_state
- * and lpc10_decoder_state structures.
- *
- * Revision 1.1 1996/08/19 22:31:40 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include <stdlib.h>
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int lpcini_(void);
-/* comlen contrl_ 12 */
-/*:ref: initlpcenc_ 14 0 */
-/*:ref: initlpcdec_ 14 0 */
-#endif
-
-/* Common Block Declarations */
-
-struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* ***************************************************************** */
-
-/* $Log$
- * Revision 1.18 2003/10/21 18:08:11 markster
- * Fix include order
- *
- * Revision 1.5 2003/10/21 18:08:11 markster
- * Fix include order
- *
- * Revision 1.4 2003/10/21 02:57:29 markster
- * FreeBSD patch, take 2
- *
- * Revision 1.3 2003/10/16 21:11:30 martinp
- * Revert the previous patch since it's braking compilation
- *
- * Revision 1.1 2003/02/12 13:59:15 matteo
- * Initial revision
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:35:41 jaf
- * Added functions for allocating and initializing lpc10_encoder_state
- * and lpc10_decoder_state structures.
- *
- * Revision 1.1 1996/08/19 22:31:40 jaf
- * Initial revision
- * */
-/* Revision 1.1 1996/03/28 00:04:05 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Initialize COMMON block variables used by LPC-10 encoder and decoder, */
-/* and call initialization routines for both of them. */
-
-/* Subroutine */ int lpcini_(void)
-{
-
-/* $Log$
- * Revision 1.18 2003/10/21 18:08:11 markster
- * Fix include order
- *
- * Revision 1.5 2003/10/21 18:08:11 markster
- * Fix include order
- *
- * Revision 1.4 2003/10/21 02:57:29 markster
- * FreeBSD patch, take 2
- *
- * Revision 1.3 2003/10/16 21:11:30 martinp
- * Revert the previous patch since it's braking compilation
- *
- * Revision 1.1 2003/02/12 13:59:15 matteo
- * Initial revision
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:35:41 jaf
- * Added functions for allocating and initializing lpc10_encoder_state
- * and lpc10_decoder_state structures.
- *
- * Revision 1.1 1996/08/19 22:31:40 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* $Log$
- * Revision 1.18 2003/10/21 18:08:11 markster
- * Fix include order
- *
- * Revision 1.5 2003/10/21 18:08:11 markster
- * Fix include order
- *
- * Revision 1.4 2003/10/21 02:57:29 markster
- * FreeBSD patch, take 2
- *
- * Revision 1.3 2003/10/16 21:11:30 martinp
- * Revert the previous patch since it's braking compilation
- *
- * Revision 1.1 2003/02/12 13:59:15 matteo
- * Initial revision
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:35:41 jaf
- * Added functions for allocating and initializing lpc10_encoder_state
- * and lpc10_decoder_state structures.
- *
- * Revision 1.1 1996/08/19 22:31:40 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
- contrl_1.order = 10;
- contrl_1.lframe = 180;
- contrl_1.corrp = TRUE_;
- return 0;
-} /* lpcini_ */
-
-
-
-/* Allocate memory for, and initialize, the state that needs to be
- kept from encoding one frame to the next for a single
- LPC-10-compressed audio stream. Return 0 if malloc fails,
- otherwise return pointer to new structure. */
-
-struct lpc10_encoder_state *
-create_lpc10_encoder_state()
-{
- struct lpc10_encoder_state *st;
-
- st = (struct lpc10_encoder_state *)
- malloc((unsigned) sizeof (struct lpc10_encoder_state));
- if (st != 0) {
- init_lpc10_encoder_state(st);
- }
- return (st);
-}
-
-
-
-void init_lpc10_encoder_state(struct lpc10_encoder_state *st)
-{
- int i;
-
- lpcini_();
-
- /* State used only by function hp100 */
- st->z11 = 0.0f;
- st->z21 = 0.0f;
- st->z12 = 0.0f;
- st->z22 = 0.0f;
-
- /* State used by function analys */
- for (i = 0; i < 540; i++) {
- st->inbuf[i] = 0.0f;
- st->pebuf[i] = 0.0f;
- }
- for (i = 0; i < 696; i++) {
- st->lpbuf[i] = 0.0f;
- }
- for (i = 0; i < 312; i++) {
- st->ivbuf[i] = 0.0f;
- }
- st->bias = 0.0f;
- /* integer osbuf[10]; */ /* no initial value necessary */
- st->osptr = 1;
- for (i = 0; i < 3; i++) {
- st->obound[i] = 0;
- }
- st->vwin[4] = 307;
- st->vwin[5] = 462;
- st->awin[4] = 307;
- st->awin[5] = 462;
- for (i = 0; i < 8; i++) {
- st->voibuf[i] = 0;
- }
- for (i = 0; i < 3; i++) {
- st->rmsbuf[i] = 0.0f;
- }
- for (i = 0; i < 30; i++) {
- st->rcbuf[i] = 0.0f;
- }
- st->zpre = 0.0f;
-
-
- /* State used by function onset */
- st->n = 0.0f;
- st->d__ = 1.0f;
- /* real fpc; */ /* no initial value necessary */
- for (i = 0; i < 16; i++) {
- st->l2buf[i] = 0.0f;
- }
- st->l2sum1 = 0.0f;
- st->l2ptr1 = 1;
- st->l2ptr2 = 9;
- /* integer lasti; */ /* no initial value necessary */
- st->hyst = FALSE_;
-
- /* State used by function voicin */
- st->dither = 20.0f;
- st->maxmin = 0.0f;
- for (i = 0; i < 6; i++) {
- st->voice[i] = 0.0f;
- }
- st->lbve = 3000;
- st->fbve = 3000;
- st->fbue = 187;
- st->ofbue = 187;
- st->sfbue = 187;
- st->lbue = 93;
- st->olbue = 93;
- st->slbue = 93;
- st->snr = (real) (st->fbve / st->fbue << 6);
-
- /* State used by function dyptrk */
- for (i = 0; i < 60; i++) {
- st->s[i] = 0.0f;
- }
- for (i = 0; i < 120; i++) {
- st->p[i] = 0;
- }
- st->ipoint = 0;
- st->alphax = 0.0f;
-
- /* State used by function chanwr */
- st->isync = 0;
-
-}
-
-
-
-/* Allocate memory for, and initialize, the state that needs to be
- kept from decoding one frame to the next for a single
- LPC-10-compressed audio stream. Return 0 if malloc fails,
- otherwise return pointer to new structure. */
-
-struct lpc10_decoder_state *
-create_lpc10_decoder_state()
-{
- struct lpc10_decoder_state *st;
-
- st = (struct lpc10_decoder_state *)
- malloc((unsigned) sizeof (struct lpc10_decoder_state));
- if (st != 0) {
- init_lpc10_decoder_state(st);
- }
- return (st);
-}
-
-
-
-void init_lpc10_decoder_state(struct lpc10_decoder_state *st)
-{
- int i;
-
- lpcini_();
-
- /* State used by function decode */
- st->iptold = 60;
- st->first = TRUE_;
- st->ivp2h = 0;
- st->iovoic = 0;
- st->iavgp = 60;
- st->erate = 0;
- for (i = 0; i < 30; i++) {
- st->drc[i] = 0;
- }
- for (i = 0; i < 3; i++) {
- st->dpit[i] = 0;
- st->drms[i] = 0;
- }
-
- /* State used by function synths */
- for (i = 0; i < 360; i++) {
- st->buf[i] = 0.0f;
- }
- st->buflen = 180;
-
- /* State used by function pitsyn */
- /* ivoico; */ /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- /* ipito; */ /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- st->rmso = 1.0f;
- /* rco[10]; */ /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- /* integer jsamp; */ /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
- st->first_pitsyn = TRUE_;
-
- /* State used by function bsynz */
- st->ipo = 0;
- for (i = 0; i < 166; i++) {
- st->exc[i] = 0.0f;
- st->exc2[i] = 0.0f;
- }
- st->lpi1 = 0.0f;
- st->lpi2 = 0.0f;
- st->lpi3 = 0.0f;
- st->hpi1 = 0.0f;
- st->hpi2 = 0.0f;
- st->hpi3 = 0.0f;
- st->rmso_bsynz = 0.0f;
-
- /* State used by function random */
- st->j = 2;
- st->k = 5;
- st->y[0] = (shortint) -21161;
- st->y[1] = (shortint) -8478;
- st->y[2] = (shortint) 30892;
- st->y[3] = (shortint) -10216;
- st->y[4] = (shortint) 16950;
-
- /* State used by function deemp */
- st->dei1 = 0.0f;
- st->dei2 = 0.0f;
- st->deo1 = 0.0f;
- st->deo2 = 0.0f;
- st->deo3 = 0.0f;
-}
diff --git a/1.4/codecs/lpc10/lpfilt.c b/1.4/codecs/lpc10/lpfilt.c
deleted file mode 100644
index 375528921..000000000
--- a/1.4/codecs/lpc10/lpfilt.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:35 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer *nsamp);
-#endif
-
-/* *********************************************************************** */
-
-/* LPFILT Version 55 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:35 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/15 16:53:49 jaf */
-/* Just put comment header in standard form. */
-
-/* Revision 1.2 1996/03/12 23:58:06 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:47:44 jaf */
-/* Initial revision */
-
-
-/* *********************************************************************** */
-
-/* 31 Point Equiripple FIR Low-Pass Filter */
-/* Linear phase, delay = 15 samples */
-
-/* Passband: ripple = 0.25 dB, cutoff = 800 Hz */
-/* Stopband: atten. = 40. dB, cutoff = 1240 Hz */
-
-/* Inputs: */
-/* LEN - Length of speech buffers */
-/* NSAMP - Number of samples to filter */
-/* INBUF - Input speech buffer */
-/* Indices len-nsamp-29 through len are read. */
-/* Output: */
-/* LPBUF - Low passed speech buffer (must be different array than INBUF) */
-/* Indices len+1-nsamp through len are written. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer *
- nsamp)
-{
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- integer j;
- real t;
-
-/* Arguments */
-/* Parameters/constants */
-/* Local variables that need not be saved */
-/* Local state */
-/* None */
- /* Parameter adjustments */
- --lpbuf;
- --inbuf;
-
- /* Function Body */
- i__1 = *len;
- for (j = *len + 1 - *nsamp; j <= i__1; ++j) {
- t = (inbuf[j] + inbuf[j - 30]) * -.0097201988f;
- t += (inbuf[j - 1] + inbuf[j - 29]) * -.0105179986f;
- t += (inbuf[j - 2] + inbuf[j - 28]) * -.0083479648f;
- t += (inbuf[j - 3] + inbuf[j - 27]) * 5.860774e-4f;
- t += (inbuf[j - 4] + inbuf[j - 26]) * .0130892089f;
- t += (inbuf[j - 5] + inbuf[j - 25]) * .0217052232f;
- t += (inbuf[j - 6] + inbuf[j - 24]) * .0184161253f;
- t += (inbuf[j - 7] + inbuf[j - 23]) * 3.39723e-4f;
- t += (inbuf[j - 8] + inbuf[j - 22]) * -.0260797087f;
- t += (inbuf[j - 9] + inbuf[j - 21]) * -.0455563702f;
- t += (inbuf[j - 10] + inbuf[j - 20]) * -.040306855f;
- t += (inbuf[j - 11] + inbuf[j - 19]) * 5.029835e-4f;
- t += (inbuf[j - 12] + inbuf[j - 18]) * .0729262903f;
- t += (inbuf[j - 13] + inbuf[j - 17]) * .1572008878f;
- t += (inbuf[j - 14] + inbuf[j - 16]) * .2247288674f;
- t += inbuf[j - 15] * .250535965f;
- lpbuf[j] = t;
- }
- return 0;
-} /* lpfilt_ */
-
diff --git a/1.4/codecs/lpc10/median.c b/1.4/codecs/lpc10/median.c
deleted file mode 100644
index 383c46e89..000000000
--- a/1.4/codecs/lpc10/median.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:31 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern integer median_(integer *d1, integer *d2, integer *d3);
-#endif
-
-/* ********************************************************************* */
-
-/* MEDIAN Version 45G */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:31 jaf
- * Initial revision
- * */
-/* Revision 1.2 1996/03/14 22:30:22 jaf */
-/* Just rearranged the comments and local variable declarations a bit. */
-
-/* Revision 1.1 1996/02/07 14:47:53 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Find median of three values */
-
-/* Input: */
-/* D1,D2,D3 - Three input values */
-/* Output: */
-/* MEDIAN - Median value */
-
-integer median_(integer *d1, integer *d2, integer *d3)
-{
- /* System generated locals */
- integer ret_val;
-
-/* Arguments */
- ret_val = *d2;
- if (*d2 > *d1 && *d2 > *d3) {
- ret_val = *d1;
- if (*d3 > *d1) {
- ret_val = *d3;
- }
- } else if (*d2 < *d1 && *d2 < *d3) {
- ret_val = *d1;
- if (*d3 < *d1) {
- ret_val = *d3;
- }
- }
- return ret_val;
-} /* median_ */
-
diff --git a/1.4/codecs/lpc10/mload.c b/1.4/codecs/lpc10/mload.c
deleted file mode 100644
index 1cdb0647c..000000000
--- a/1.4/codecs/lpc10/mload.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:25 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int mload_(integer *order, integer *awins, integer *awinf, real *speech, real *phi, real *psi);
-#endif
-
-/* ***************************************************************** */
-
-/* MLOAD Version 48 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:25 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/03/27 23:59:51 jaf */
-/* Added some more accurate comments about which indices of the argument */
-/* array SPEECH are read. I thought that this might be the cause of a */
-/* problem I've been having, but it isn't. */
-
-/* Revision 1.4 1996/03/26 19:16:53 jaf */
-/* Commented out the code at the end that copied the lower triangular */
-/* half of PHI into the upper triangular half (making the resulting */
-/* matrix symmetric). The upper triangular half was never used by later */
-/* code in subroutine ANALYS. */
-
-/* Revision 1.3 1996/03/18 21:16:00 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 16:47:41 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:48:01 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Load a covariance matrix. */
-
-/* Input: */
-/* ORDER - Analysis order */
-/* AWINS - Analysis window start */
-/* AWINF - Analysis window finish */
-/* SPEECH(AWINF) - Speech buffer */
-/* Indices MIN(AWINS, AWINF-(ORDER-1)) through */
-/* MAX(AWINF, AWINS+(ORDER-1)) read. */
-/* As long as (AWINF-AWINS) .GE. (ORDER-1), */
-/* this is just indices AWINS through AWINF. */
-/* Output: */
-/* PHI(ORDER,ORDER) - Covariance matrix */
-/* Lower triangular half and diagonal written, and read.*/
-/* Upper triangular half untouched. */
-/* PSI(ORDER) - Prediction vector */
-/* Indices 1 through ORDER written, */
-/* and most are read after that. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int mload_(integer *order, integer *awins, integer *awinf,
- real *speech, real *phi, real *psi)
-{
- /* System generated locals */
- integer phi_dim1, phi_offset, i__1, i__2;
-
- /* Local variables */
- integer c__, i__, r__, start;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Load first column of triangular covariance matrix PHI */
- /* Parameter adjustments */
- --psi;
- phi_dim1 = *order;
- phi_offset = phi_dim1 + 1;
- phi -= phi_offset;
- --speech;
-
- /* Function Body */
- start = *awins + *order;
- i__1 = *order;
- for (r__ = 1; r__ <= i__1; ++r__) {
- phi[r__ + phi_dim1] = 0.f;
- i__2 = *awinf;
- for (i__ = start; i__ <= i__2; ++i__) {
- phi[r__ + phi_dim1] += speech[i__ - 1] * speech[i__ - r__];
- }
- }
-/* Load last element of vector PSI */
- psi[*order] = 0.f;
- i__1 = *awinf;
- for (i__ = start; i__ <= i__1; ++i__) {
- psi[*order] += speech[i__] * speech[i__ - *order];
- }
-/* End correct to get additional columns of PHI */
- i__1 = *order;
- for (r__ = 2; r__ <= i__1; ++r__) {
- i__2 = r__;
- for (c__ = 2; c__ <= i__2; ++c__) {
- phi[r__ + c__ * phi_dim1] = phi[r__ - 1 + (c__ - 1) * phi_dim1] -
- speech[*awinf + 1 - r__] * speech[*awinf + 1 - c__] +
- speech[start - r__] * speech[start - c__];
- }
- }
-/* End correct to get additional elements of PSI */
- i__1 = *order - 1;
- for (c__ = 1; c__ <= i__1; ++c__) {
- psi[c__] = phi[c__ + 1 + phi_dim1] - speech[start - 1] * speech[start
- - 1 - c__] + speech[*awinf] * speech[*awinf - c__];
- }
-/* Copy lower triangular section into upper (why bother?) */
-/* I'm commenting this out, since the upper triangular half of PHI
-*/
-/* is never used by later code, unless a sufficiently high level of
-*/
-/* tracing is turned on. */
-/* DO R = 1,ORDER */
-/* DO C = 1,R-1 */
-/* PHI(C,R) = PHI(R,C) */
-/* END DO */
-/* END DO */
- return 0;
-} /* mload_ */
-
diff --git a/1.4/codecs/lpc10/onset.c b/1.4/codecs/lpc10/onset.c
deleted file mode 100644
index ddca3b477..000000000
--- a/1.4/codecs/lpc10/onset.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:37:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:31:18 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st);
-#endif
-
-/* Table of constant values */
-
-static real c_b2 = 1.f;
-
-/* ****************************************************************** */
-
-/* ONSET Version 49 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:37:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:31:18 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/03/15 16:41:01 jaf */
-/* Just rearranged INITONSET assignment orders to be consistent with */
-/* order of DATA statements in ONSET. */
-
-/* Revision 1.4 1996/03/15 15:48:27 jaf */
-/* Changed some comments, and only reordered the DATA statements (their */
-/* meaning wasn't changed). */
-
-/* Revision 1.3 1996/03/14 23:53:06 jaf */
-/* Added an entry INITONSET that reinitializes the local state variables */
-/* of subroutine ONSET. */
-
-/* Rearranged quite a few comments, adding more explaining which */
-/* arguments were inputs, and how the modified ones can be changed. */
-
-/* Revision 1.2 1996/03/12 23:53:00 jaf */
-/* Lots of comments added about the local state of this subroutine that */
-/* must be saved from one invocation to the next. */
-
-/* One constant 180 replaced with LFRAME, which should be "more general", */
-/* even though it would probably require many more changes than this to */
-/* get this coder to work for other frame sizes. */
-
-/* Revision 1.1 1996/02/07 14:48:09 jaf */
-/* Initial revision */
-
-
-/* ****************************************************************** */
-
-/* Floating point version */
-
-
-/* Detection of onsets in (or slightly preceding) the futuremost frame */
-/* of speech. */
-
-
-/* Input: */
-/* PEBUF(SBUFL:SBUFH) - Preemphasized speech */
-/* Indices SBUFH-LFRAME through SBUFH are read. */
-/* OSLEN - Maximum number of onsets that can be stored in OSBUF. */
-/* SBUFL, SBUFH - Range of PEBUF */
-/* LFRAME - length of a frame, in samples */
-/* Input/Output: */
-/* OSBUF(OSLEN) - Buffer which holds sorted indexes of onsets */
-/* Indices A through B are modified, where A */
-/* is the original value of OSPTR, and B is the final */
-/* value of OSPTR-1. B is at most OSLEN. */
-/* OSPTR - Free pointer into OSBUF */
-/* Initial value should be .LE. OSLEN+1. */
-/* If so, final value grows by one for each new onset */
-/* found, and final value will be .LE. OSLEN+1. */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this subroutine, or */
-/* reinitialize its state for any other reason, call the ENTRY INITONSET. */
-
-/* Subroutine */ int onset_(real *pebuf, integer *osbuf, integer *
- osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *
- lframe, struct lpc10_encoder_state *st)
-{
- /* Initialized data */
-
- real *n;
- real *d__;
- real *l2buf;
- real *l2sum1;
- integer *l2ptr1;
- integer *l2ptr2;
- logical *hyst;
-
- /* System generated locals */
- integer pebuf_offset, i__1;
- real r__1;
-
- /* Builtin functions */
- double r_sign(real *, real *);
-
- /* Local variables */
- integer i__;
- integer *lasti;
- real l2sum2;
- real *fpc;
-
-/* Arguments */
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:37:55 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:31:18 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Parameters/constants */
-/* Parameters for onset detection algorithm: */
-/* L2 Threshold for filtered slope of FPC (function of L2WID!) */
-/* L2LAG Lag due to both filters which compute filtered slope of FPC */
-/* L2WID Width of the filter which computes the slope of FPC */
-/* OSHYST The number of samples of slope(FPC) which must be below */
-/* the threshold before a new onset may be declared. */
-/* Local variables that need not be saved */
-/* Local state */
-/* Variables */
-/* N, D Numerator and denominator of prediction filters */
-/* FPC Current prediction coefs */
-/* L2BUF, L2SUM1, L2SUM2 State of slope filter */
-/* The only "significant" change I've made is to change L2SUM2 out
-*/
-/* of the list of local variables that need to be saved, since it */
-/* didn't need to be. */
-/* L2SUM1 need not be, but avoiding saving it would require a small
-*/
-/* change to the body of the code. See comments below for an */
-/* example of how the code could be changed to avoid saving L2SUM1.
-*/
-/* FPC and LASTI are saved from one invocation to the next, but */
-/* they are not given initial values. This is acceptable, because
-*/
-/* FPC will be assigned a value the first time that this function */
-/* is called after D is initialized to 1, since the formula to */
-/* change D will not change it to 0 in one step, and the IF (D */
-/* .NE. 0) statement will execute its THEN part, initializing FPC.
-*/
-
-/* LASTI's value will not be used until HYST is .TRUE., and */
-/* whenever HYST is changed from its initial value of .FALSE., */
-/* LASTI is assigned a value. */
-/* In a C version of this coder, it would be nice if all of these */
-/* saved things, in this and all other subroutines, could be stored
-*/
-/* in a single struct lpc10_coder_state_t, initialized with a call
-*/
-/* to a function like lpc10_init(&lpc10_coder_state). In this way,
-*/
-/* a program that used these functions could conveniently alternate
-*/
-/* coding more than one distinct audio stream. */
-
- n = &(st->n);
- d__ = &(st->d__);
- fpc = &(st->fpc);
- l2buf = &(st->l2buf[0]);
- l2sum1 = &(st->l2sum1);
- l2ptr1 = &(st->l2ptr1);
- l2ptr2 = &(st->l2ptr2);
- lasti = &(st->lasti);
- hyst = &(st->hyst);
-
- /* Parameter adjustments */
- if (osbuf) {
- --osbuf;
- }
- if (pebuf) {
- pebuf_offset = *sbufl;
- pebuf -= pebuf_offset;
- }
-
- /* Function Body */
-
-/* The following line subtracted a hard-coded "180" from LASTI, */
-/* instead of using a variable like LFRAME or a constant like */
-/* MAXFRM. I changed it to LFRAME, for "generality". */
- if (*hyst) {
- *lasti -= *lframe;
- }
- i__1 = *sbufh;
- for (i__ = *sbufh - *lframe + 1; i__ <= i__1; ++i__) {
-/* Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1.
-*/
- *n = (pebuf[i__] * pebuf[i__ - 1] + (*n) * 63.f) / 64.f;
-/* Computing 2nd power */
- r__1 = pebuf[i__ - 1];
- *d__ = (r__1 * r__1 + (*d__) * 63.f) / 64.f;
- if ((*d__) != 0.f) {
- if (abs(*n) > (*d__)) {
- *fpc = (real)r_sign(&c_b2, n);
- } else {
- *fpc = (*n) / (*d__);
- }
- }
-/* Filter FPC */
-/* In order to allow L2SUM1 not to be saved from one invocation
-of */
-/* this subroutine to the next, one could change the sequence of
- */
-/* assignments below, up to the IF statement, to the following.
- In */
-/* addition, the initial value of L2PTR2 should be changed to */
-/* L2WID/2 instead of L2WID/2+1. */
-
-/* L2SUM1 = L2BUF(L2PTR2) */
-/* L2PTR2 = MOD(L2PTR2,L2WID)+1 */
-/* L2SUM1 = L2SUM1 - L2BUF(L2PTR2) + FPC */
-/* L2BUF(L2PTR2) = L2SUM1 */
-
-/* * The following lines didn't change from the original: */
-/* L2SUM2 = L2BUF(L2PTR1) */
-/* L2BUF(L2PTR1) = FPC */
-/* L2PTR1 = MOD(L2PTR1,L2WID)+1 */
-
- l2sum2 = l2buf[*l2ptr1 - 1];
- *l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc;
- l2buf[*l2ptr2 - 1] = *l2sum1;
- l2buf[*l2ptr1 - 1] = *fpc;
- *l2ptr1 = *l2ptr1 % 16 + 1;
- *l2ptr2 = *l2ptr2 % 16 + 1;
- if ((r__1 = *l2sum1 - l2sum2, abs(r__1)) > 1.7f) {
- if (! (*hyst)) {
-/* Ignore if buffer full */
- if (*osptr <= *oslen) {
- osbuf[*osptr] = i__ - 9;
- ++(*osptr);
- }
- *hyst = TRUE_;
- }
- *lasti = i__;
-/* After one onset detection, at least OSHYST sample times m
-ust go */
-/* by before another is allowed to occur. */
- } else if ((*hyst) && i__ - *lasti >= 10) {
- *hyst = FALSE_;
- }
- }
- return 0;
-} /* onset_ */
diff --git a/1.4/codecs/lpc10/pitsyn.c b/1.4/codecs/lpc10/pitsyn.c
deleted file mode 100644
index ea8177e22..000000000
--- a/1.4/codecs/lpc10/pitsyn.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/11/23 22:14:32 markster
-Various warning cleanups
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:40:12 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:31:12 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv, integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio, struct lpc10_decoder_state *st);
-#endif
-
-/* ***************************************************************** */
-
-/* PITSYN Version 53 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/11/23 22:14:32 markster
- * Various warning cleanups
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:40:12 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:31:12 jaf
- * Initial revision
- * */
-/* Revision 1.2 1996/03/25 18:49:07 jaf */
-/* Added commments about which indices of array arguments are read or */
-/* written. */
-
-/* Rearranged local variable declarations to indicate which need to be */
-/* saved from one invocation to the next. Added entry INITPITSYN to */
-/* reinitialize local state variables, if desired. */
-
-/* Added lots of comments about proving that the maximum number of pitch */
-/* periods (NOUT) that can be returned is 16. The call to STOP that */
-/* could happen if NOUT got too large was removed as a result. */
-
-/* Also proved that the total number of samples returned from N calls, */
-/* each with identical values of LFRAME, will always be in the range */
-/* N*LFRAME-MAXPIT+1 to N*LFRAME. */
-
-/* Revision 1.1 1996/02/07 14:48:18 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* Synthesize a single pitch epoch */
-
-/* Input: */
-/* ORDER - Synthesis order (number of RC's) */
-/* VOICE - Half frame voicing decisions */
-/* Indices 1 through 2 read. */
-/* LFRAME - Length of speech buffer */
-/* Input/Output: */
-/* PITCH - Pitch */
-/* This value should be in the range MINPIT (20) to MAXPIT */
-/* (156), inclusive. */
-/* PITCH can be modified under some conditions. */
-/* RMS - Energy (can be modified) */
-/* RMS is changed to 1 if the value passed in is less than 1. */
-/* RC - Reflection coefficients */
-/* Indices 1 through ORDER can be temporarily overwritten with */
-/* RCO, and then replaced with original values, under some */
-/* conditions. */
-/* Output: */
-/* IVUV - Pitch epoch voicing decisions */
-/* Indices (I) of IVUV, IPITI, and RMSI are written, */
-/* and indices (J,I) of RCI are written, */
-/* where I ranges from 1 to NOUT, and J ranges from 1 to ORDER. */
-/* IPITI - Pitch epoch length */
-/* RMSI - Pitch epoch energy */
-/* RCI - Pitch epoch RC's */
-/* NOUT - Number of pitch periods in this frame */
-/* This is at least 0, at least 1 if MAXPIT .LT. LFRAME (this */
-/* is currently true on every call), and can never be more than */
-/* (LFRAME+MAXPIT-1)/PITCH, which is currently 16 with */
-/* LFRAME=180, MAXPIT=156, and PITCH .GE. 20, as SYNTHS */
-/* guarantees when it calls this subroutine. */
-/* RATIO - Previous to present energy ratio */
-/* Always assigned a value. */
-
-/* Subroutine */ int pitsyn_(integer *order, integer *voice,
- integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv,
- integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio,
- struct lpc10_decoder_state *st)
-{
- /* Initialized data */
-
- real *rmso;
- logical *first;
-
- /* System generated locals */
- integer rci_dim1 = 0, rci_offset, i__1, i__2;
- real r__1;
-
- /* Builtin functions */
- double log(doublereal), exp(doublereal);
-
- /* Local variables */
- real alrn, alro, yarc[10], prop;
- integer i__, j, vflag, jused, lsamp;
- integer *jsamp;
- real slope;
- integer *ipito;
- real uvpit;
- integer ip, nl, ivoice;
- integer *ivoico;
- integer istart;
- real *rco;
- real xxy;
-
-/* Arguments */
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/11/23 22:14:32 markster
- * Various warning cleanups
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:40:12 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:31:12 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Local variables that need not be saved */
-/* LSAMP is initialized in the IF (FIRST) THEN clause, but it is */
-/* not used the first time through, and it is given a value before
-*/
-/* use whenever FIRST is .FALSE., so it appears unnecessary to */
-/* assign it a value when FIRST is .TRUE. */
-/* Local state */
-/* FIRST - .TRUE. only on first call to PITSYN. */
-/* IVOICO - Previous VOICE(2) value. */
-/* IPITO - Previous PITCH value. */
-/* RMSO - Previous RMS value. */
-/* RCO - Previous RC values. */
-
-/* JSAMP - If this routine is called N times with identical values of */
-/* LFRAME, then the total length of all pitch periods returned */
-/* is always N*LFRAME-JSAMP, and JSAMP is always in the range 0
-*/
-/* to MAXPIT-1 (see below for why this is so). Thus JSAMP is */
-/* the number of samples "left over" from the previous call to */
-/* PITSYN, that haven't been "used" in a pitch period returned */
-/* from this subroutine. Every time this subroutine is called,
-*/
-/* it returns pitch periods with a total length of at most */
-/* LFRAME+JSAMP. */
-
-/* IVOICO, IPITO, RCO, and JSAMP need not be assigned an initial value */
-/* with a DATA statement, because they are always initialized on the */
-/* first call to PITSYN. */
-
-/* FIRST and RMSO should be initialized with DATA statements, because */
-/* even on the first call, they are used before being initialized. */
- /* Parameter adjustments */
- if (rc) {
- --rc;
- }
- if (rci) {
- rci_dim1 = *order;
- rci_offset = rci_dim1 + 1;
- rci -= rci_offset;
- }
- if (voice) {
- --voice;
- }
- if (ivuv) {
- --ivuv;
- }
- if (ipiti) {
- --ipiti;
- }
- if (rmsi) {
- --rmsi;
- }
-
- /* Function Body */
- ivoico = &(st->ivoico);
- ipito = &(st->ipito);
- rmso = &(st->rmso);
- rco = &(st->rco[0]);
- jsamp = &(st->jsamp);
- first = &(st->first_pitsyn);
-
- if (*rms < 1.f) {
- *rms = 1.f;
- }
- if (*rmso < 1.f) {
- *rmso = 1.f;
- }
- uvpit = 0.f;
- *ratio = *rms / (*rmso + 8.f);
- if (*first) {
- lsamp = 0;
- ivoice = voice[2];
- if (ivoice == 0) {
- *pitch = *lframe / 4;
- }
- *nout = *lframe / *pitch;
- *jsamp = *lframe - *nout * *pitch;
-
-/* SYNTHS only calls this subroutine with PITCH in the range
-20 */
-/* to 156. LFRAME = MAXFRM = 180, so NOUT is somewhere in th
-e */
-/* range 1 to 9. */
-
-/* JSAMP is "LFRAME mod PITCH", so it is in the range 0 to */
-/* (PITCH-1), or 0 to MAXPIT-1=155, after the first call. */
-
- i__1 = *nout;
- for (i__ = 1; i__ <= i__1; ++i__) {
- i__2 = *order;
- for (j = 1; j <= i__2; ++j) {
- rci[j + i__ * rci_dim1] = rc[j];
- }
- ivuv[i__] = ivoice;
- ipiti[i__] = *pitch;
- rmsi[i__] = *rms;
- }
- *first = FALSE_;
- } else {
- vflag = 0;
- lsamp = *lframe + *jsamp;
- slope = (*pitch - *ipito) / (real) lsamp;
- *nout = 0;
- jused = 0;
- istart = 1;
- if (voice[1] == *ivoico && voice[2] == voice[1]) {
- if (voice[2] == 0) {
-/* SSUV - - 0 , 0 , 0 */
- *pitch = *lframe / 4;
- *ipito = *pitch;
- if (*ratio > 8.f) {
- *rmso = *rms;
- }
- }
-/* SSVC - - 1 , 1 , 1 */
- slope = (*pitch - *ipito) / (real) lsamp;
- ivoice = voice[2];
- } else {
- if (*ivoico != 1) {
- if (*ivoico == voice[1]) {
-/* UV2VC2 - - 0 , 0 , 1 */
- nl = lsamp - *lframe / 4;
- } else {
-/* UV2VC1 - - 0 , 1 , 1 */
- nl = lsamp - *lframe * 3 / 4;
- }
- ipiti[1] = nl / 2;
- ipiti[2] = nl - ipiti[1];
- ivuv[1] = 0;
- ivuv[2] = 0;
- rmsi[1] = *rmso;
- rmsi[2] = *rmso;
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- rci[i__ + rci_dim1] = rco[i__ - 1];
- rci[i__ + (rci_dim1 << 1)] = rco[i__ - 1];
- rco[i__ - 1] = rc[i__];
- }
- slope = 0.f;
- *nout = 2;
- *ipito = *pitch;
- jused = nl;
- istart = nl + 1;
- ivoice = 1;
- } else {
- if (*ivoico != voice[1]) {
-/* VC2UV1 - - 1 , 0 , 0 */
- lsamp = *lframe / 4 + *jsamp;
- } else {
-/* VC2UV2 - - 1 , 1 , 0 */
- lsamp = *lframe * 3 / 4 + *jsamp;
- }
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- yarc[i__ - 1] = rc[i__];
- rc[i__] = rco[i__ - 1];
- }
- ivoice = 1;
- slope = 0.f;
- vflag = 1;
- }
- }
-/* Here is the value of most variables that are used below, depending
-on */
-/* the values of IVOICO, VOICE(1), and VOICE(2). VOICE(1) and VOICE(2
-) */
-/* are input arguments, and IVOICO is the value of VOICE(2) on the */
-/* previous call (see notes for the IF (NOUT .NE. 0) statement near th
-e */
-/* end). Each of these three values is either 0 or 1. These three */
-/* values below are given as 3-bit long strings, in the order IVOICO,
-*/
-/* VOICE(1), and VOICE(2). It appears that the code above assumes tha
-t */
-/* the bit sequences 010 and 101 never occur, but I wonder whether a
-*/
-/* large enough number of bit errors in the channel could cause such a
- */
-/* thing to happen, and if so, could that cause NOUT to ever go over 1
-1? */
-
-/* Note that all of the 180 values in the table are really LFRAME, but
- */
-/* 180 has fewer characters, and it makes the table a little more */
-/* concrete. If LFRAME is ever changed, keep this in mind. Similarly
-, */
-/* 135's are 3*LFRAME/4, and 45's are LFRAME/4. If LFRAME is not a */
-/* multiple of 4, then the 135 for NL-JSAMP is actually LFRAME-LFRAME/
-4, */
-/* and the 45 for NL-JSAMP is actually LFRAME-3*LFRAME/4. */
-
-/* Note that LSAMP-JSAMP is given as the variable. This was just for
-*/
-/* brevity, to avoid adding "+JSAMP" to all of the column entries. */
-/* Similarly for NL-JSAMP. */
-
-/* Variable | 000 001 011,010 111 110 100,101 */
-/* ------------+-------------------------------------------------- */
-/* ISTART | 1 NL+1 NL+1 1 1 1 */
-/* LSAMP-JSAMP | 180 180 180 180 135 45 */
-/* IPITO | 45 PITCH PITCH oldPITCH oldPITCH oldPITCH */
-/* SLOPE | 0 0 0 seebelow 0 0 */
-/* JUSED | 0 NL NL 0 0 0 */
-/* PITCH | 45 PITCH PITCH PITCH PITCH PITCH */
-/* NL-JSAMP | -- 135 45 -- -- -- */
-/* VFLAG | 0 0 0 0 1 1 */
-/* NOUT | 0 2 2 0 0 0 */
-/* IVOICE | 0 1 1 1 1 1 */
-
-/* while_loop | once once once once twice twice */
-
-/* ISTART | -- -- -- -- JUSED+1 JUSED+1 */
-/* LSAMP-JSAMP | -- -- -- -- 180 180 */
-/* IPITO | -- -- -- -- oldPITCH oldPITCH */
-/* SLOPE | -- -- -- -- 0 0 */
-/* JUSED | -- -- -- -- ?? ?? */
-/* PITCH | -- -- -- -- PITCH PITCH */
-/* NL-JSAMP | -- -- -- -- -- -- */
-/* VFLAG | -- -- -- -- 0 0 */
-/* NOUT | -- -- -- -- ?? ?? */
-/* IVOICE | -- -- -- -- 0 0 */
-
-
-/* UVPIT is always 0.0 on the first pass through the DO WHILE (.TRUE.)
- */
-/* loop below. */
-
-/* The only possible non-0 value of SLOPE (in column 111) is */
-/* (PITCH-IPITO)/FLOAT(LSAMP) */
-
-/* Column 101 is identical to 100. Any good properties we can prove
-*/
-/* for 100 will also hold for 101. Similarly for 010 and 011. */
-
-/* SYNTHS calls this subroutine with PITCH restricted to the range 20
-to */
-/* 156. IPITO is similarly restricted to this range, after the first
-*/
-/* call. IP below is also restricted to this range, given the */
-/* definitions of IPITO, SLOPE, UVPIT, and that I is in the range ISTA
-RT */
-/* to LSAMP. */
-
- while(TRUE_) {
-
-/* JUSED is the total length of all pitch periods curr
-ently */
-/* in the output arrays, in samples. */
-
-/* An invariant of the DO I = ISTART,LSAMP loop below,
- under */
-/* the condition that IP is always in the range 1 thro
-ugh */
-/* MAXPIT, is: */
-
-/* (I - MAXPIT) .LE. JUSED .LE. (I-1) */
-
-/* Note that the final value of I is LSAMP+1, so that
-after */
-/* the DO loop is complete, we know: */
-
-/* (LSAMP - MAXPIT + 1) .LE. JUSED .LE. LSAMP */
-
- i__1 = lsamp;
- for (i__ = istart; i__ <= i__1; ++i__) {
- r__1 = *ipito + slope * i__;
- ip = (integer)(r__1 + .5f);
- if (uvpit != 0.f) {
- ip = (integer)uvpit;
- }
- if (ip <= i__ - jused) {
- ++(*nout);
-
-/* The following check is no longer nece
-ssary, now that */
-/* we can prove that NOUT will never go
-over 16. */
-
-/* IF (NOUT .GT. 16) STOP 'PITSYN: too many epochs'
-*/
-
- ipiti[*nout] = ip;
- *pitch = ip;
- ivuv[*nout] = ivoice;
- jused += ip;
- prop = (jused - ip / 2) / (real) lsamp;
- i__2 = *order;
- for (j = 1; j <= i__2; ++j) {
- alro = (real)log((rco[j - 1] + 1) / (1 - rco[j - 1]));
- alrn = (real)log((rc[j] + 1) / (1 - rc[j]));
- xxy = alro + prop * (alrn - alro);
- xxy = (real)exp(xxy);
- rci[j + *nout * rci_dim1] = (xxy - 1) / (xxy + 1);
- }
- rmsi[*nout] = (real)(log(*rmso) + prop * (log(*rms) - log(*rmso)));
- rmsi[*nout] = (real)exp(rmsi[*nout]);
- }
- }
- if (vflag != 1) {
- goto L100;
- }
-
-/* I want to prove what range UVPIT must lie in after
-the */
-/* assignments to it below. To do this, I must determ
-ine */
-/* what range (LSAMP-ISTART) must lie in, after the */
-/* assignments to ISTART and LSAMP below. */
-
-/* Let oldLSAMP be the value of LSAMP at this point in
- the */
-/* execution. This is 135+JSAMP in state 110, or 45+J
-SAMP in */
-/* states 100 or 101. */
-
-/* Given the loop invariant on JUSED above, we know th
-at: */
-
-/* (oldLSAMP - MAXPIT + 1) .LE. JUSED .LE. oldLSAMP */
-
-/* ISTART is one more than this. */
-
-/* Let newLSAMP be the value assigned to LSAMP below.
- This */
-/* is 180+JSAMP. Thus (newLSAMP-oldLSAMP) is either 4
-5 or */
-/* 135, depending on the state. */
-
-/* Thus, the range of newLSAMP-ISTART is: */
-
-/* (newLSAMP-(oldLSAMP+1)) .LE. newLSAMP-ISTART */
-/* .LE. (newLSAMP-(oldLSAMP - MAXPIT + 2)) */
-
-/* or: */
-
-/* 46 .LE. newLSAMP-ISTART .LE. 133+MAXPIT .EQ. 289 */
-
-/* Therefore, UVPIT is in the range 23 to 144 after th
-e first */
-/* assignment to UVPIT below, and after the conditiona
-l */
-/* assignment, it is in the range 23 to 90. */
-
-/* The important thing is that it is in the range 20 t
-o 156, */
-/* so that in the loop above, IP is always in this ran
-ge. */
-
- vflag = 0;
- istart = jused + 1;
- lsamp = *lframe + *jsamp;
- slope = 0.f;
- ivoice = 0;
- uvpit = (real) ((lsamp - istart) / 2);
- if (uvpit > 90.f) {
- uvpit /= 2;
- }
- *rmso = *rms;
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- rc[i__] = yarc[i__ - 1];
- rco[i__ - 1] = yarc[i__ - 1];
- }
- }
-L100:
- *jsamp = lsamp - jused;
- }
-/* Given that the maximum pitch period MAXPIT .LT. LFRAME (this is
-*/
-/* currently true on every call, since SYNTHS always sets */
-/* LFRAME=180), NOUT will always be .GE. 1 at this point. */
- if (*nout != 0) {
- *ivoico = voice[2];
- *ipito = *pitch;
- *rmso = *rms;
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- rco[i__ - 1] = rc[i__];
- }
- }
- return 0;
-} /* pitsyn_ */
diff --git a/1.4/codecs/lpc10/placea.c b/1.4/codecs/lpc10/placea.c
deleted file mode 100644
index dacb50e7a..000000000
--- a/1.4/codecs/lpc10/placea.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.2 2003/09/19 01:20:22 markster
-Code cleanups (bug #66)
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.3 2001/04/12 21:27:53 markh
-app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:07 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int placea_(integer *ipitch, integer *voibuf, integer *obound, integer *af, integer *vwin, integer *awin, integer *ewin, integer *lframe, integer *maxwin);
-#endif
-
-/* *********************************************************************** */
-
-/* PLACEA Version 48 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.2 2003/09/19 01:20:22 markster
- * Code cleanups (bug #66)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.3 2001/04/12 21:27:53 markh
- * app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:07 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/03/19 20:41:55 jaf */
-/* Added some conditions satisfied by the output values in EWIN. */
-
-/* Revision 1.4 1996/03/19 20:24:17 jaf */
-/* Added some conditions satisfied by the output values in AWIN. */
-
-/* Revision 1.3 1996/03/18 21:40:04 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 16:43:09 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:48:31 jaf */
-/* Initial revision */
-
-
-/* *********************************************************************** */
-/* Input: */
-/* IPITCH */
-/* VOIBUF */
-/* Indices (2,AF-2), (1,AF-1), (2,AF-1), (1,AF), and (2,AF) read.*/
-/* All other indices untouched. */
-/* OBOUND */
-/* AF */
-/* VWIN */
-/* Indices (1,AF) and (2,AF) read. */
-/* All other indices untouched. */
-/* LFRAME */
-/* MAXWIN */
-/* Input/Output: */
-/* AWIN */
-/* Index (1,AF-1) read. */
-/* Indices (1,AF) and (2,AF) written, and then read. */
-/* All other indices untouched. */
-/* In all cases (except possibly one), the final values will */
-/* satisfy the condition: AWIN(2,AF)-AWIN(1,AF)+1 = MAXWIN. */
-/* In that other case, */
-/* AWIN(1,AF)=VWIN(1,AF) and AWIN(2,AF)=VWIN(2,AF). */
-/* Output: */
-/* EWIN */
-/* Indices (1,AF) and (2,AF) written. */
-/* All other indices untouched. */
-/* In all cases, the final values will satisfy the condition: */
-/* AWIN(1,AF) .LE. EWIN(1,AF) .LE. EWIN(2,AF) .LE. AWIN(2,AF) */
-/* In other words, the energy window is a sub-window of */
-/* the analysis window. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int placea_(integer *ipitch, integer *voibuf, integer *
- obound, integer *af, integer *vwin, integer *awin, integer *ewin,
- integer *lframe, integer *maxwin)
-{
- /* System generated locals */
- real r__1;
-
- /* Builtin functions */
- integer i_nint(real *);
-
- /* Local variables */
- logical allv, winv;
- integer i__, j, k, l, hrange;
- logical ephase;
- integer lrange;
-
-/* Arguments */
-/* Local variables that need not be saved */
- /* Parameter adjustments */
- ewin -= 3;
- awin -= 3;
- vwin -= 3;
- --voibuf;
-
- /* Function Body */
- lrange = (*af - 2) * *lframe + 1;
- hrange = *af * *lframe;
-/* Place the Analysis window based on the voicing window */
-/* placement, onsets, tentative voicing decision, and pitch. */
-
-/* Case 1: Sustained Voiced Speech */
-/* If the five most recent voicing decisions are */
-/* voiced, then the window is placed phase-synchronously with the */
-/* previous window, as close to the present voicing window if possible.
-*/
-/* If onsets bound the voicing window, then preference is given to */
-/* a phase-synchronous placement which does not overlap these onsets. */
-
-/* Case 2: Voiced Transition */
-/* If at least one voicing decision in AF is voicied, and there are no
-*/
-/* onsets, then the window is placed as in case 1. */
-
-/* Case 3: Unvoiced Speech or Onsets */
-/* If both voicing decisions in AF are unvoiced, or there are onsets, */
-/* then the window is placed coincident with the voicing window. */
-
-/* Note: During phase-synchronous placement of windows, the length */
-/* is not altered from MAXWIN, since this would defeat the purpose */
-/* of phase-synchronous placement. */
-/* Check for case 1 and case 2 */
- allv = voibuf[((*af - 2) << 1) + 2] == 1;
- allv = allv && voibuf[((*af - 1) << 1) + 1] == 1;
- allv = allv && voibuf[((*af - 1) << 1) + 2] == 1;
- allv = allv && voibuf[(*af << 1) + 1] == 1;
- allv = allv && voibuf[(*af << 1) + 2] == 1;
- winv = voibuf[(*af << 1) + 1] == 1 || voibuf[(*af << 1) + 2] == 1;
- if (allv || (winv && *obound == 0)) {
-/* APHASE: Phase synchronous window placement. */
-/* Get minimum lower index of the window. */
- i__ = (lrange + *ipitch - 1 - awin[((*af - 1) << 1) + 1]) / *ipitch;
- i__ *= *ipitch;
- i__ += awin[((*af - 1) << 1) + 1];
-/* L = the actual length of this frame's analysis window. */
- l = *maxwin;
-/* Calculate the location where a perfectly centered window would star
-t. */
- k = (vwin[(*af << 1) + 1] + vwin[(*af << 1) + 2] + 1 - l) / 2;
-/* Choose the actual location to be the pitch multiple closest to this
-. */
- r__1 = (real) (k - i__) / *ipitch;
- awin[(*af << 1) + 1] = i__ + i_nint(&r__1) * *ipitch;
- awin[(*af << 1) + 2] = awin[(*af << 1) + 1] + l - 1;
-/* If there is an onset bounding the right of the voicing window and t
-he */
-/* analysis window overlaps that, then move the analysis window backwa
-rd */
-/* to avoid this onset. */
- if (*obound >= 2 && awin[(*af << 1) + 2] > vwin[(*af << 1) + 2]) {
- awin[(*af << 1) + 1] -= *ipitch;
- awin[(*af << 1) + 2] -= *ipitch;
- }
-/* Similarly for the left of the voicing window. */
- if ((*obound == 1 || *obound == 3) && awin[(*af << 1) + 1] < vwin[(*
- af << 1) + 1]) {
- awin[(*af << 1) + 1] += *ipitch;
- awin[(*af << 1) + 2] += *ipitch;
- }
-/* If this placement puts the analysis window above HRANGE, then */
-/* move it backward an integer number of pitch periods. */
- while(awin[(*af << 1) + 2] > hrange) {
- awin[(*af << 1) + 1] -= *ipitch;
- awin[(*af << 1) + 2] -= *ipitch;
- }
-/* Similarly if the placement puts the analysis window below LRANGE.
-*/
- while(awin[(*af << 1) + 1] < lrange) {
- awin[(*af << 1) + 1] += *ipitch;
- awin[(*af << 1) + 2] += *ipitch;
- }
-/* Make Energy window be phase-synchronous. */
- ephase = TRUE_;
-/* Case 3 */
- } else {
- awin[(*af << 1) + 1] = vwin[(*af << 1) + 1];
- awin[(*af << 1) + 2] = vwin[(*af << 1) + 2];
- ephase = FALSE_;
- }
-/* RMS is computed over an integer number of pitch periods in the analysis
- */
-/*window. When it is not placed phase-synchronously, it is placed as clos
-e*/
-/* as possible to onsets. */
- j = (awin[(*af << 1) + 2] - awin[(*af << 1) + 1] + 1) / *ipitch * *ipitch;
- if (j == 0 || ! winv) {
- ewin[(*af << 1) + 1] = vwin[(*af << 1) + 1];
- ewin[(*af << 1) + 2] = vwin[(*af << 1) + 2];
- } else if (! ephase && *obound == 2) {
- ewin[(*af << 1) + 1] = awin[(*af << 1) + 2] - j + 1;
- ewin[(*af << 1) + 2] = awin[(*af << 1) + 2];
- } else {
- ewin[(*af << 1) + 1] = awin[(*af << 1) + 1];
- ewin[(*af << 1) + 2] = awin[(*af << 1) + 1] + j - 1;
- }
- return 0;
-} /* placea_ */
-
diff --git a/1.4/codecs/lpc10/placev.c b/1.4/codecs/lpc10/placev.c
deleted file mode 100644
index 56e72c4b8..000000000
--- a/1.4/codecs/lpc10/placev.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.3 2001/04/12 21:27:53 markh
-app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:31:02 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int placev_(integer *osbuf, integer *osptr, integer *oslen, integer *obound, integer *vwin, integer *af, integer *lframe, integer *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh);
-#endif
-
-/* ****************************************************************** */
-
-/* PLACEV Version 48 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.3 2001/04/12 21:27:53 markh
- * app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:31:02 jaf
- * Initial revision
- * */
-/* Revision 1.6 1996/03/19 20:42:19 jaf */
-/* Added some conditions satisfied by the output values in VWIN. */
-
-/* Revision 1.5 1996/03/19 18:37:56 jaf */
-/* Strengthened the specification of which indices of VWIN are read and */
-/* written. */
-
-/* Revision 1.4 1996/03/15 16:38:33 jaf */
-/* One tiny comment added. */
-
-/* Revision 1.3 1996/03/15 16:36:13 jaf */
-/* Added comments giving In/Out status of arguments. */
-
-/* Revision 1.2 1996/03/12 23:56:01 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:48:39 jaf */
-/* Initial revision */
-
-
-/* ****************************************************************** */
-
-/* Input: */
-/* OSBUF Buffer which holds sorted indexes of onsets */
-/* I believe that only indices 1 through OSPTR-1 can be read. */
-/* OSLEN */
-/* OSPTR Free pointer into OSBUF */
-/* AF */
-/* LFRAME */
-/* MINWIN */
-/* MAXWIN */
-/* DVWINL */
-/* DVWINH (This argument is never used. Should it be?) */
-/* Input/Output: */
-/* VWIN Buffer of Voicing Window Positions (Modified) */
-/* Index (2,AF-1) is read. */
-/* Indices (1,AF) and (2,AF) are written, */
-/* and then possibly read. */
-/* All other indices are unused. */
-/* In all cases, the final values will satsify the condition:*/
-/* VWIN(2,AF)-VWIN(1,AF)+1 .LE. MAXWIN */
-/* I'm not certain yet, but they may also satisfy: */
-/* MINWIN .LE. VWIN(2,AF)-VWIN(1,AF)+1 */
-/* Output: */
-/* OBOUND This variable is set by this procedure and used */
-/* in placing analysis windows (PLACEA). Bit 1 */
-/* indicates whether an onset bounds the left side */
-/* of the voicing window, and bit 2 indicates whether */
-/* an onset bounds the right side of the voicing window. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int placev_(integer *osbuf, integer *osptr, integer *oslen,
- integer *obound, integer *vwin, integer *af, integer *lframe, integer
- *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh)
-{
- /* System generated locals */
- integer i__1, i__2;
-
- /* Local variables */
- logical crit;
- integer i__, q, osptr1, hrange, lrange;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Variables */
-/* LRANGE, HRANGE Range in which window is placed */
-/* OSPTR1 OSPTR excluding samples in 3F */
-/* Local state */
-/* None */
-/* Voicing Window Placement */
-
-/* __________________ __________________ ______________ */
-/* | | | */
-/* | 1F | 2F | 3F ... */
-/* |__________________|__________________|______________ */
-
-/* Previous | */
-/* Window | */
-/* ...________| */
-
-/* | | */
-/* ------>| This window's placement range |<------ */
-/* | | */
-
-/* There are three cases. Note that these are different from those */
-/* given in the LPC-10e phase 1 report. */
-
-/* 1. If there are no onsets in this range, then the voicing window */
-/* is centered in the pitch window. If such a placement is not within
-*/
-/* the window's placement range, then the window is placed in the left-
-*/
-/* most portion of the placement range. Its length is always MAXWIN. */
-
-/* 2. If the first onset is in 2F and there is sufficient room to place
- */
-/* the window immediately before this onset, then the window is placed
-*/
-/* there, and its length is set to the maximum possible under these */
-/* constraints. */
-
-/* "Critical Region Exception": If there is another onset in 2F */
-/* such that a window can be placed between the two onsets, the */
-/* window is placed there (ie, as in case 3). */
-
-/* 3. Otherwise, the window is placed immediately after the onset. The
- */
-/* window's length */
-/* is the longest length that can fit in the range under these constraint
-s,*/
-/* except that the window may be shortened even further to avoid overlapp
-ing*/
-/* other onsets in the placement range. In any case, the window's length
-*/
-/* is at least MINWIN. */
-
-/* Note that the values of MINWIN and LFRAME must be chosen such */
-/* that case 2 = false implies case 3 = true. This means that */
-/* MINWIN <= LFRAME/2. If this were not the case, then a fourth case */
-/* would have to be added for when the window cannot fit either before
-*/
-/* or after the onset. */
-
-/* Note also that onsets which weren't in 2F last time may be in 1F this
- */
-/* time, due to the filter delays in computing onsets. The result is tha
-t*/
-/* occasionally a voicing window will overlap that onset. The only way
-*/
-/* to circumvent this problem is to add more delay in processing input
-*/
-/* speech. In the trade-off between delay and window-placement, window
-*/
-/* placement lost. */
-/* Compute the placement range */
- /* Parameter adjustments */
- --osbuf;
- vwin -= 3;
-
- /* Function Body */
-/* Computing MAX */
- i__1 = vwin[((*af - 1) << 1) + 2] + 1, i__2 = (*af - 2) * *lframe + 1;
- lrange = max(i__1,i__2);
- hrange = *af * *lframe;
-/* Compute OSPTR1, so the following code only looks at relevant onsets. */
- for (osptr1 = *osptr - 1; osptr1 >= 1; --osptr1) {
- if (osbuf[osptr1] <= hrange) {
- goto L90;
- }
- }
-L90:
- ++osptr1;
-/* Check for case 1 first (fast case): */
- if (osptr1 <= 1 || osbuf[osptr1 - 1] < lrange) {
-/* Computing MAX */
- i__1 = vwin[((*af - 1) << 1) + 2] + 1;
- vwin[(*af << 1) + 1] = max(i__1,*dvwinl);
- vwin[(*af << 1) + 2] = vwin[(*af << 1) + 1] + *maxwin - 1;
- *obound = 0;
- } else {
-/* Search backward in OSBUF for first onset in range. */
-/* This code relies on the above check being performed first. */
- for (q = osptr1 - 1; q >= 1; --q) {
- if (osbuf[q] < lrange) {
- goto L100;
- }
- }
-L100:
- ++q;
-/* Check for case 2 (placement before onset): */
-/* Check for critical region exception: */
- i__1 = osptr1 - 1;
- for (i__ = q + 1; i__ <= i__1; ++i__) {
- if (osbuf[i__] - osbuf[q] >= *minwin) {
- crit = TRUE_;
- goto L105;
- }
- }
- crit = FALSE_;
-L105:
-/* Computing MAX */
- i__1 = (*af - 1) * *lframe, i__2 = lrange + *minwin - 1;
- if (! crit && osbuf[q] > max(i__1,i__2)) {
- vwin[(*af << 1) + 2] = osbuf[q] - 1;
-/* Computing MAX */
- i__1 = lrange, i__2 = vwin[(*af << 1) + 2] - *maxwin + 1;
- vwin[(*af << 1) + 1] = max(i__1,i__2);
- *obound = 2;
-/* Case 3 (placement after onset) */
- } else {
- vwin[(*af << 1) + 1] = osbuf[q];
-L110:
- ++q;
- if (q >= osptr1) {
- goto L120;
- }
- if (osbuf[q] > vwin[(*af << 1) + 1] + *maxwin) {
- goto L120;
- }
- if (osbuf[q] < vwin[(*af << 1) + 1] + *minwin) {
- goto L110;
- }
- vwin[(*af << 1) + 2] = osbuf[q] - 1;
- *obound = 3;
- return 0;
-L120:
-/* Computing MIN */
- i__1 = vwin[(*af << 1) + 1] + *maxwin - 1;
- vwin[(*af << 1) + 2] = min(i__1,hrange);
- *obound = 1;
- }
- }
- return 0;
-} /* placev_ */
-
diff --git a/1.4/codecs/lpc10/preemp.c b/1.4/codecs/lpc10/preemp.c
deleted file mode 100644
index 645428c3c..000000000
--- a/1.4/codecs/lpc10/preemp.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:30:58 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int preemp_(real *inbuf, real *pebuf, integer *nsamp, real *coef, real *z__);
-#endif
-
-/* ******************************************************************* */
-
-/* PREEMP Version 55 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:30:58 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/14 23:16:29 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/11 23:23:34 jaf */
-/* Added a bunch of comments to an otherwise simple subroutine. */
-
-/* Revision 1.1 1996/02/07 14:48:48 jaf */
-/* Initial revision */
-
-
-/* ******************************************************************* */
-
-/* Preemphasize speech with a single-zero filter. */
-/* (When coef = .9375, preemphasis is as in LPC43.) */
-
-/* Inputs: */
-/* NSAMP - Number of samples to filter */
-/* INBUF - Input speech buffer */
-/* Indices 1 through NSAMP are read. */
-/* COEF - Preemphasis coefficient */
-/* Input/Output: */
-/* Z - Filter state */
-/* Output: */
-/* PEBUF - Preemphasized speech buffer (can be equal to INBUF) */
-/* Indices 1 through NSAMP are modified. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int preemp_(real *inbuf, real *pebuf, integer *nsamp, real *
- coef, real *z__)
-{
- /* System generated locals */
- integer i__1;
-
- /* Local variables */
- real temp;
- integer i__;
-
-/* Arguments */
-/* Local variables */
-
-/* None of these need to have their values saved from one */
-/* invocation to the next. */
-
-/* Logically, this subroutine computes the output sequence */
-/* pebuf(1:nsamp) defined by: */
-
-/* pebuf(i) = inbuf(i) - coef * inbuf(i-1) */
-
-/* where inbuf(0) is defined by the value of z given as input to */
-/* this subroutine. */
-
-/* What is this filter's frequency response and phase response? */
-
-/* Why is this filter applied to the speech? */
-
-/* Could it be more efficient to apply multiple filters */
-/* simultaneously, by combining them into one equivalent filter? */
-
-/* Are there ever cases when "factoring" one high-order filter into
-*/
-/* multiple smaller-order filter actually reduces the number of */
-/* arithmetic operations needed to perform them? */
-/* When I first read this subroutine, I didn't understand why the */
-/* variable temp was used. It seemed that the statements in the do
-*/
-/* loop could be replaced with the following: */
-
-/* pebuf(i) = inbuf(i) - coef * z */
-/* z = inbuf(i) */
-
-/* The reason for temp is so that even if pebuf and inbuf are the */
-/* same arrays in memory (i.e., they are aliased), then this */
-/* subroutine will still work correctly. I didn't realize this */
-/* until seeing the comment after PEBUF above that says "(can be */
-/* equal to INBUF)". */
- /* Parameter adjustments */
- --pebuf;
- --inbuf;
-
- /* Function Body */
- i__1 = *nsamp;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = inbuf[i__] - *coef * *z__;
- *z__ = inbuf[i__];
- pebuf[i__] = temp;
-/* L10: */
- }
- return 0;
-} /* preemp_ */
-
diff --git a/1.4/codecs/lpc10/prepro.c b/1.4/codecs/lpc10/prepro.c
deleted file mode 100644
index d24ce0da3..000000000
--- a/1.4/codecs/lpc10/prepro.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:40:51 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:54 jaf
- * Initial revision
- *
- */
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int prepro_(real *speech, integer *length,
- struct lpc10_encoder_state *st);
-/*:ref: hp100_ 14 3 6 4 4 */
-/*:ref: inithp100_ 14 0 */
-#endif
-
-/* Table of constant values */
-
-static integer c__1 = 1;
-
-/* ********************************************************************* */
-
-/* PREPRO Version 48 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:40:51 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:54 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/14 23:22:56 jaf */
-/* Added comments about when INITPREPRO should be used. */
-
-/* Revision 1.2 1996/03/14 23:09:27 jaf */
-/* Added an entry named INITPREPRO that initializes the local state of */
-/* this subroutine, and those it calls (if any). */
-
-/* Revision 1.1 1996/02/07 14:48:54 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Pre-process input speech: */
-
-/* Inputs: */
-/* LENGTH - Number of SPEECH samples */
-/* Input/Output: */
-/* SPEECH(LENGTH) - Speech data. */
-/* Indices 1 through LENGTH are read and modified. */
-
-/* This subroutine has no local state maintained from one call to the */
-/* next, but HP100 does. If you want to switch to using a new audio */
-/* stream for this filter, or reinitialize its state for any other */
-/* reason, call the ENTRY INITPREPRO. */
-
-/* Subroutine */ int prepro_(real *speech, integer *length,
- struct lpc10_encoder_state *st)
-{
- extern /* Subroutine */ int hp100_(real *, integer *, integer *, struct lpc10_encoder_state *);
-
-/* Arguments */
-/* High Pass Filter at 100 Hz */
- /* Parameter adjustments */
- if (speech) {
- --speech;
- }
-
- /* Function Body */
- hp100_(&speech[1], &c__1, length, st);
- return 0;
-} /* prepro_ */
diff --git a/1.4/codecs/lpc10/random.c b/1.4/codecs/lpc10/random.c
deleted file mode 100644
index 0f8e9b209..000000000
--- a/1.4/codecs/lpc10/random.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:41:32 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:49 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern integer random_(struct lpc10_decoder_state *st);
-#endif
-
-/* ********************************************************************** */
-
-/* RANDOM Version 49 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:41:32 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:49 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/20 16:13:54 jaf */
-/* Rearranged comments a little bit, and added comments explaining that */
-/* even though there is local state here, there is no need to create an */
-/* ENTRY for reinitializing it. */
-
-/* Revision 1.2 1996/03/14 22:25:29 jaf */
-/* Just rearranged the comments and local variable declarations a bit. */
-
-/* Revision 1.1 1996/02/07 14:49:01 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Pseudo random number generator based on Knuth, Vol 2, p. 27. */
-
-/* Function Return: */
-/* RANDOM - Integer variable, uniformly distributed over -32768 to 32767 */
-
-/* This subroutine maintains local state from one call to the next. */
-/* In the context of the LPC10 coder, there is no reason to reinitialize */
-/* this local state when switching between audio streams, because its */
-/* results are only used to generate noise for unvoiced frames. */
-
-integer random_(struct lpc10_decoder_state *st)
-{
- /* Initialized data */
-
- integer *j;
- integer *k;
- shortint *y;
-
- /* System generated locals */
- integer ret_val;
-
-/* Parameters/constants */
-/* Local state */
-/* The following is a 16 bit 2's complement addition, */
-/* with overflow checking disabled */
-
- j = &(st->j);
- k = &(st->k);
- y = &(st->y[0]);
-
- y[*k - 1] += y[*j - 1];
- ret_val = y[*k - 1];
- --(*k);
- if (*k <= 0) {
- *k = 5;
- }
- --(*j);
- if (*j <= 0) {
- *j = 5;
- }
- return ret_val;
-} /* random_ */
-
diff --git a/1.4/codecs/lpc10/rcchk.c b/1.4/codecs/lpc10/rcchk.c
deleted file mode 100644
index 6cb76ef7d..000000000
--- a/1.4/codecs/lpc10/rcchk.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:30:41 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int rcchk_(integer *order, real *rc1f, real *rc2f);
-#endif
-
-/* ********************************************************************* */
-
-/* RCCHK Version 45G */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:30:41 jaf
- * Initial revision
- * */
-/* Revision 1.4 1996/03/27 18:13:47 jaf */
-/* Commented out a call to subroutine ERROR. */
-
-/* Revision 1.3 1996/03/18 15:48:53 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 16:55:22 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:49:08 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Check RC's, repeat previous frame's RC's if unstable */
-
-/* Input: */
-/* ORDER - Number of RC's */
-/* RC1F - Previous frame's RC's */
-/* Indices 1 through ORDER may be read. */
-/* Input/Output: */
-/* RC2F - Present frame's RC's */
-/* Indices 1 through ORDER may be read, and written. */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int rcchk_(integer *order, real *rc1f, real *rc2f)
-{
- /* System generated locals */
- integer i__1;
- real r__1;
-
- /* Local variables */
- integer i__;
-
-/* Arguments */
-/* Local variables that need not be saved */
- /* Parameter adjustments */
- --rc2f;
- --rc1f;
-
- /* Function Body */
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if ((r__1 = rc2f[i__], abs(r__1)) > .99f) {
- goto L10;
- }
- }
- return 0;
-/* Note: In version embedded in other software, all calls to ERROR
-*/
-/* should probably be removed. */
-L10:
-
-/* This call to ERROR is only needed for debugging purposes. */
-
-/* CALL ERROR('RCCHK',2,I) */
- i__1 = *order;
- for (i__ = 1; i__ <= i__1; ++i__) {
- rc2f[i__] = rc1f[i__];
- }
- return 0;
-} /* rcchk_ */
-
diff --git a/1.4/codecs/lpc10/synths.c b/1.4/codecs/lpc10/synths.c
deleted file mode 100644
index 4c5a70fac..000000000
--- a/1.4/codecs/lpc10/synths.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/09/27 02:45:37 markster
-Fix various compiler warnings (bug #322)
-
-Revision 1.2 2003/09/27 02:45:37 markster
-Fix various compiler warnings (bug #322)
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:39 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:42:59 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:33 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int synths_(integer *voice, integer *pitch, real *rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st);
-/* comlen contrl_ 12 */
-/*:ref: pitsyn_ 14 12 4 4 4 6 6 4 4 4 6 6 4 6 */
-/*:ref: irc2pc_ 14 5 6 6 4 6 6 */
-/*:ref: bsynz_ 14 7 6 4 4 6 6 6 6 */
-/*:ref: deemp_ 14 2 6 4 */
-/*:ref: initpitsyn_ 14 0 */
-/*:ref: initbsynz_ 14 0 */
-/*:ref: initdeemp_ 14 0 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/* Table of constant values */
-
-static real c_b2 = .7f;
-
-/* ***************************************************************** */
-
-/* SYNTHS Version 54 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/27 02:45:37 markster
- * Fix various compiler warnings (bug #322)
- *
- * Revision 1.2 2003/09/27 02:45:37 markster
- * Fix various compiler warnings (bug #322)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:42:59 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:33 jaf
- * Initial revision
- * */
-/* Revision 1.5 1996/03/26 19:31:58 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.4 1996/03/25 19:41:01 jaf */
-/* Changed so that MAXFRM samples are always returned in the output array */
-/* SPEECH. */
-
-/* This required delaying the returned samples by MAXFRM sample times, */
-/* and remembering any "left over" samples returned by PITSYN from one */
-/* call of SYNTHS to the next. */
-
-/* Changed size of SPEECH from 2*MAXFRM to MAXFRM. Removed local */
-/* variable SOUT. Added local state variables BUF and BUFLEN. */
-
-/* Revision 1.3 1996/03/25 19:20:10 jaf */
-/* Added comments about the range of possible return values for argument */
-/* K, and increased the size of the arrays filled in by PITSYN from 11 to */
-/* 16, as has been already done inside of PITSYN. */
-
-/* Revision 1.2 1996/03/22 00:18:18 jaf */
-/* Added comments explaining meanings of input and output parameters, and */
-/* indicating which array indices can be read or written. */
-
-/* Added entry INITSYNTHS, which does nothing except call the */
-/* corresponding initialization entries for subroutines PITSYN, BSYNZ, */
-/* and DEEMP. */
-
-/* Revision 1.1 1996/02/07 14:49:44 jaf */
-/* Initial revision */
-
-
-/* ***************************************************************** */
-
-/* The note below is from the distributed version of the LPC10 coder. */
-/* The version of the code below has been modified so that SYNTHS always */
-/* has a constant frame length output of MAXFRM. */
-
-/* Also, BSYNZ and DEEMP need not be modified to work on variable */
-/* positions within an array. It is only necessary to pass the first */
-/* index desired as the array argument. What actually gets passed is the */
-/* address of that array position, which the subroutine treats as the */
-/* first index of the array. */
-
-/* This technique is used in subroutine ANALYS when calling PREEMP, so it */
-/* appears that multiple people wrote different parts of this LPC10 code, */
-/* and that they didn't necessarily have equivalent knowledge of Fortran */
-/* (not surprising). */
-
-/* NOTE: There is excessive buffering here, BSYNZ and DEEMP should be */
-/* changed to operate on variable positions within SOUT. Also, */
-/* the output length parameter is bogus, and PITSYN should be */
-/* rewritten to allow a constant frame length output. */
-
-/* Input: */
-/* VOICE - Half frame voicing decisions */
-/* Indices 1 through 2 read. */
-/* Input/Output: */
-/* PITCH - Pitch */
-/* PITCH is restricted to range 20 to 156, inclusive, */
-/* before calling subroutine PITSYN, and then PITSYN */
-/* can modify it further under some conditions. */
-/* RMS - Energy */
-/* Only use is for debugging, and passed to PITSYN. */
-/* See comments there for how it can be modified. */
-/* RC - Reflection coefficients */
-/* Indices 1 through ORDER restricted to range -.99 to .99, */
-/* before calling subroutine PITSYN, and then PITSYN */
-/* can modify it further under some conditions. */
-/* Output: */
-/* SPEECH - Synthesized speech samples. */
-/* Indices 1 through the final value of K are written. */
-/* K - Number of samples placed into array SPEECH. */
-/* This is always MAXFRM. */
-
-/* Subroutine */ int synths_(integer *voice, integer *pitch, real *
- rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st)
-{
- /* Initialized data */
-
- real *buf;
- integer *buflen;
-
- /* System generated locals */
- integer i__1;
- real r__1, r__2;
-
- /* Local variables */
- real rmsi[16];
- integer nout, ivuv[16], i__, j;
- extern /* Subroutine */ int deemp_(real *, integer *, struct lpc10_decoder_state *);
- real ratio;
- integer ipiti[16];
- real g2pass;
- real pc[10];
- extern /* Subroutine */ int pitsyn_(integer *, integer *, integer *, real
- *, real *, integer *, integer *, integer *, real *, real *,
- integer *, real *, struct lpc10_decoder_state *);
- real rci[160] /* was [10][16] */;
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/27 02:45:37 markster
- * Fix various compiler warnings (bug #322)
- *
- * Revision 1.2 2003/09/27 02:45:37 markster
- * Fix various compiler warnings (bug #322)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:42:59 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:33 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:03:47 jaf */
-/* Removed definitions for any constants that were no longer used. */
-
-/* Revision 1.2 1996/03/26 19:34:33 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:43:51 jaf */
-/* Initial revision */
-
-/* LPC Configuration parameters: */
-/* Frame size, Prediction order, Pitch period */
-/* Arguments */
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/09/27 02:45:37 markster
- * Fix various compiler warnings (bug #322)
- *
- * Revision 1.2 2003/09/27 02:45:37 markster
- * Fix various compiler warnings (bug #322)
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:39 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:42:59 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_decoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_decoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:33 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Parameters/constants */
-/* Local variables that need not be saved */
-/* Local state */
-/* BUF is a buffer of speech samples that would have been returned
-*/
-/* by the older version of SYNTHS, but the newer version doesn't, */
-/* so that the newer version can always return MAXFRM samples on */
-/* every call. This has the effect of delaying the return of */
-/* samples for one additional frame time. */
-
-/* Indices 1 through BUFLEN contain samples that are left over from
-*/
-/* the last call to SYNTHS. Given the way that PITSYN works, */
-/* BUFLEN should always be in the range MAXFRM-MAXPIT+1 through */
-/* MAXFRM, inclusive, after a call to SYNTHS is complete. */
-
-/* On the first call to SYNTHS (or the first call after */
-/* reinitializing with the entry INITSYNTHS), BUFLEN is MAXFRM, and
-*/
-/* a frame of silence is always returned. */
- /* Parameter adjustments */
- if (voice) {
- --voice;
- }
- if (rc) {
- --rc;
- }
- if (speech) {
- --speech;
- }
-
- /* Function Body */
- buf = &(st->buf[0]);
- buflen = &(st->buflen);
-
-/* Computing MAX */
- i__1 = min(*pitch,156);
- *pitch = max(i__1,20);
- i__1 = contrl_1.order;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* Computing MAX */
-/* Computing MIN */
- r__2 = rc[i__];
- r__1 = min(r__2,.99f);
- rc[i__] = max(r__1,-.99f);
- }
- pitsyn_(&contrl_1.order, &voice[1], pitch, rms, &rc[1], &contrl_1.lframe,
- ivuv, ipiti, rmsi, rci, &nout, &ratio, st);
- if (nout > 0) {
- i__1 = nout;
- for (j = 1; j <= i__1; ++j) {
-
-/* Add synthesized speech for pitch period J to the en
-d of */
-/* BUF. */
-
- irc2pc_(&rci[j * 10 - 10], pc, &contrl_1.order, &c_b2, &g2pass);
- bsynz_(pc, &ipiti[j - 1], &ivuv[j - 1], &buf[*buflen], &rmsi[j - 1]
- , &ratio, &g2pass, st);
- deemp_(&buf[*buflen], &ipiti[j - 1], st);
- *buflen += ipiti[j - 1];
- }
-
-/* Copy first MAXFRM samples from BUF to output array SPEECH
-*/
-/* (scaling them), and then remove them from the beginning of
- */
-/* BUF. */
-
- for (i__ = 1; i__ <= 180; ++i__) {
- speech[i__] = buf[i__ - 1] / 4096.f;
- }
- *k = 180;
- *buflen += -180;
- i__1 = *buflen;
- for (i__ = 1; i__ <= i__1; ++i__) {
- buf[i__ - 1] = buf[i__ + 179];
- }
- }
- return 0;
-} /* synths_ */
diff --git a/1.4/codecs/lpc10/tbdm.c b/1.4/codecs/lpc10/tbdm.c
deleted file mode 100644
index 2f6f3d692..000000000
--- a/1.4/codecs/lpc10/tbdm.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:40 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:30:26 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int tbdm_(real *speech, integer *lpita, integer *tau, integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer *mintau);
-/*:ref: difmag_ 14 8 6 4 4 4 4 6 4 4 */
-#endif
-
-/* ********************************************************************** */
-
-/* TBDM Version 49 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:40 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:30:26 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/18 22:14:00 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 14:48:37 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:49:54 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/*TURBO DIFMAG: Compute High Resolution Average Magnitude Difference Function
-*/
-
-/* Note: There are several constants in here that appear to depend on a */
-/* particular TAU table. That's not a problem for the LPC10 coder, but */
-/* watch out if you change the contents of TAU in the subroutine ANALYS. */
-
-/* Input: */
-/* SPEECH - Low pass filtered speech */
-/* Indices 1 through MAX+LPITA-1 are read, where: */
-/* MAX = (TAU(LTAU)-TAU(1))/2+1 */
-/* (If TAU(1) .LT. 39, then larger indices could be read */
-/* by the last call to DIFMAG below.) */
-/* LPITA - Length of speech buffer */
-/* TAU - Table of lags, sorted in increasing order. */
-/* Indices 1 through LTAU read. */
-/* LTAU - Number of lag values to compute */
-/* Output: */
-/* AMDF - Average Magnitude Difference for each lag in TAU */
-/* Indices 1 through LTAU written, and several might then be read.*/
-/* MINPTR - Index of minimum AMDF value */
-/* MAXPTR - Index of maximum AMDF value within +/- 1/2 octave of min */
-/* MINTAU - Lag corresponding to minimum AMDF value */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int tbdm_(real *speech, integer *lpita, integer *tau,
- integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer *
- mintau)
-{
- /* System generated locals */
- integer i__1, i__2, i__3, i__4;
-
- /* Local variables */
- real amdf2[6];
- integer minp2, ltau2, maxp2, i__;
- extern /* Subroutine */ int difmag_(real *, integer *, integer *, integer
- *, integer *, real *, integer *, integer *);
- integer minamd, ptr, tau2[6];
-
-/* Arguments */
-/* REAL SPEECH(LPITA+TAU(LTAU)), AMDF(LTAU) */
-/* Stupid TOAST doesn't understand expressions */
-/* Local variables that need not be saved */
-/* Local state */
-/* None */
-/* Compute full AMDF using log spaced lags, find coarse minimum */
- /* Parameter adjustments */
- --speech;
- --amdf;
- --tau;
-
- /* Function Body */
- difmag_(&speech[1], lpita, &tau[1], ltau, &tau[*ltau], &amdf[1], minptr,
- maxptr);
- *mintau = tau[*minptr];
- minamd = (integer)amdf[*minptr];
-/* Build table containing all lags within +/- 3 of the AMDF minimum */
-/* excluding all that have already been computed */
- ltau2 = 0;
- ptr = *minptr - 2;
-/* Computing MAX */
- i__1 = *mintau - 3;
-/* Computing MIN */
- i__3 = *mintau + 3, i__4 = tau[*ltau] - 1;
- i__2 = min(i__3,i__4);
- for (i__ = max(i__1,41); i__ <= i__2; ++i__) {
- while(tau[ptr] < i__) {
- ++ptr;
- }
- if (tau[ptr] != i__) {
- ++ltau2;
- tau2[ltau2 - 1] = i__;
- }
- }
-/* Compute AMDF of the new lags, if there are any, and choose one */
-/* if it is better than the coarse minimum */
- if (ltau2 > 0) {
- difmag_(&speech[1], lpita, tau2, &ltau2, &tau[*ltau], amdf2, &minp2, &
- maxp2);
- if (amdf2[minp2 - 1] < (real) minamd) {
- *mintau = tau2[minp2 - 1];
- minamd = (integer)amdf2[minp2 - 1];
- }
- }
-/* Check one octave up, if there are any lags not yet computed */
- if (*mintau >= 80) {
- i__ = *mintau / 2;
- if ((i__ & 1) == 0) {
- ltau2 = 2;
- tau2[0] = i__ - 1;
- tau2[1] = i__ + 1;
- } else {
- ltau2 = 1;
- tau2[0] = i__;
- }
- difmag_(&speech[1], lpita, tau2, &ltau2, &tau[*ltau], amdf2, &minp2, &
- maxp2);
- if (amdf2[minp2 - 1] < (real) minamd) {
- *mintau = tau2[minp2 - 1];
- minamd = (integer)amdf2[minp2 - 1];
- *minptr += -20;
- }
- }
-/* Force minimum of the AMDF array to the high resolution minimum */
- amdf[*minptr] = (real) minamd;
-/* Find maximum of AMDF within 1/2 octave of minimum */
-/* Computing MAX */
- i__2 = *minptr - 5;
- *maxptr = max(i__2,1);
-/* Computing MIN */
- i__1 = *minptr + 5;
- i__2 = min(i__1,*ltau);
- for (i__ = *maxptr + 1; i__ <= i__2; ++i__) {
- if (amdf[i__] > amdf[*maxptr]) {
- *maxptr = i__;
- }
- }
- return 0;
-} /* tbdm_ */
-
diff --git a/1.4/codecs/lpc10/voicin.c b/1.4/codecs/lpc10/voicin.c
deleted file mode 100644
index 3605d2f2e..000000000
--- a/1.4/codecs/lpc10/voicin.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
-
-$Log$
-Revision 1.16 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.15 2003/11/23 22:14:32 markster
-Various warning cleanups
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:40 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.2 1996/08/20 20:45:00 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:14 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int voicin_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, integer *mintau, real *ivrc, integer *obound, integer *voibuf, integer *af, struct lpc10_encoder_state *st);
-/* comlen contrl_ 12 */
-/*:ref: vparms_ 14 14 4 6 6 4 4 6 4 4 4 4 6 6 6 6 */
-#endif
-
-/* Common Block Declarations */
-
-extern struct {
- integer order, lframe;
- logical corrp;
-} contrl_;
-
-#define contrl_1 contrl_
-
-/****************************************************************************/
-
-/* VOICIN Version 52 */
-
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/11/23 22:14:32 markster
- * Various warning cleanups
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:40 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:45:00 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:14 jaf
- * Initial revision
- * */
-/* Revision 1.10 1996/03/29 17:59:14 jaf */
-/* Avoided using VALUE(9), although it shouldn't affect the function of */
-/* the code at all, because it was always multiplied by VDC(9,SNRL), */
-/* which is 0 for all values of SNRL. Still, if VALUE(9) had an initial */
-/* value of IEEE NaN, it might cause trouble (I don't know how IEEE */
-/* defines Nan * 0. It should either be NaN or 0.) */
-
-/* Revision 1.9 1996/03/29 17:54:46 jaf */
-/* Added a few comments about the accesses made to argument array VOIBUF */
-/* and the local saved array VOICE. */
-
-/* Revision 1.8 1996/03/27 18:19:54 jaf */
-/* Added an assignment to VSTATE that does not affect the function of the */
-/* program at all. The only reason I put it in was so that the tracing */
-/* statements at the end, when enabled, will print a consistent value for */
-/* VSTATE when HALF .EQ. 1, rather than a garbage value that could change */
-/* from one call to the next. */
-
-/* Revision 1.7 1996/03/26 20:00:06 jaf */
-/* Removed the inclusion of the file "vcomm.fh", and put its contents */
-/* into this file. It was included nowhere else but here. */
-
-/* Revision 1.6 1996/03/26 19:38:09 jaf */
-/* Commented out trace statements. */
-
-/* Revision 1.5 1996/03/19 20:43:45 jaf */
-/* Added comments about which indices of OBOUND and VOIBUF can be */
-/* accessed, and whether they are read or written. VOIBUF is fairly */
-/* messy. */
-
-/* Revision 1.4 1996/03/19 15:00:58 jaf */
-/* Moved the DATA statements for the *VDC* variables later, as it is */
-/* apparently illegal to have DATA statements before local variable */
-/* declarations. */
-
-/* Revision 1.3 1996/03/19 00:10:49 jaf */
-/* Heavily commented the local variables that are saved from one */
-/* invocation to the next, and how the local variable FIRST is used to */
-/* avoid the need to assign most of them initial values with DATA */
-/* statements. */
-
-/* A few should be initialized, but aren't. I've guessed initial values */
-/* for two of these, SFBUE and SLBUE, and I've convinced myself that for */
-/* VOICE, the effects of uninitialized values will die out after 2 or 3 */
-/* frame times. It would still be good to choose initial values for */
-/* these, but I don't know what reasonable values would be (0 comes to */
-/* mind). */
-
-/* Revision 1.2 1996/03/13 16:09:28 jaf */
-/* Comments added explaining which of the local variables of this */
-/* subroutine need to be saved from one invocation to the next, and which */
-/* do not. */
-
-/* WARNING! Some of them that should are never given initial values in */
-/* this code. Hopefully, Fortran 77 defines initial values for them, but */
-/* even so, giving them explicit initial values is preferable. */
-
-/* WARNING! VALUE(9) is used, but never assigned a value. It should */
-/* probably be eliminated from the code. */
-
-/* Revision 1.1 1996/02/07 14:50:28 jaf */
-/* Initial revision */
-
-
-/****************************************************************************/
-
-/* Voicing Detection (VOICIN) makes voicing decisions for each half */
-/* frame of input speech. Tentative voicing decisions are made two frames*/
-/* in the future (2F) for each half frame. These decisions are carried */
-/* through one frame in the future (1F) to the present (P) frame where */
-/* they are examined and smoothed, resulting in the final voicing */
-/* decisions for each half frame. */
-/* The voicing parameter (signal measurement) column vector (VALUE) */
-/* is based on a rectangular window of speech samples determined by the */
-/* window placement algorithm. The voicing parameter vector contains the*/
-/* AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy*/
-/* measures, reflection coefficients, and prediction gains. The voicing */
-/* window is placed to avoid contamination of the voicing parameter vector*/
-/* with speech onsets. */
-/* The input signal is then classified as unvoiced (including */
-/* silence) or voiced. This decision is made by a linear discriminant */
-/* function consisting of a dot product of the voicing decision */
-/* coefficient (VDC) row vector with the measurement column vector */
-/* (VALUE). The VDC vector is 2-dimensional, each row vector is optimized*/
-/* for a particular signal-to-noise ratio (SNR). So, before the dot */
-/* product is performed, the SNR is estimated to select the appropriate */
-/* VDC vector. */
-/* The smoothing algorithm is a modified median smoother. The */
-/* voicing discriminant function is used by the smoother to determine how*/
-/* strongly voiced or unvoiced a signal is. The smoothing is further */
-/* modified if a speech onset and a voicing decision transition occur */
-/* within one half frame. In this case, the voicing decision transition */
-/* is extended to the speech onset. For transmission purposes, there are*/
-/* constraints on the duration and transition of voicing decisions. The */
-/* smoother takes these constraints into account. */
-/* Finally, the energy estimates are updated along with the dither */
-/* threshold used to calculate the zero crossing rate (ZC). */
-
-/* Inputs: */
-/* VWIN - Voicing window limits */
-/* The indices read of arrays VWIN, INBUF, LPBUF, and BUFLIM */
-/* are the same as those read by subroutine VPARMS. */
-/* INBUF - Input speech buffer */
-/* LPBUF - Low-pass filtered speech buffer */
-/* BUFLIM - INBUF and LPBUF limits */
-/* HALF - Present analysis half frame number */
-/* MINAMD - Minimum value of the AMDF */
-/* MAXAMD - Maximum value of the AMDF */
-/* MINTAU - Pointer to the lag of the minimum AMDF value */
-/* IVRC(2) - Inverse filter's RC's */
-/* Only index 2 of array IVRC read under normal operation. */
-/* (Index 1 is also read when debugging is turned on.) */
-/* OBOUND - Onset boundary descriptions */
-/* Indices 1 through 3 read if (HALF .NE. 1), otherwise untouched.
-*/
-/* AF - The analysis frame number */
-/* Output: */
-/* VOIBUF(2,0:AF) - Buffer of voicing decisions */
-/* Index (HALF,3) written. */
-/* If (HALF .EQ. 1), skip down to "Read (HALF,3)" below. */
-/* Indices (1,2), (2,1), (1,2), and (2,2) read. */
-/* One of the following is then done: */
-/* read (1,3) and possibly write (1,2) */
-/* read (1,3) and write (1,2) or (2,2) */
-/* write (2,1) */
-/* write (2,1) or (1,2) */
-/* read (1,0) and (1,3) and then write (2,2) or (1,1) */
-/* no reads or writes on VOIBUF */
-/* Finally, read (HALF,3) */
-/* Internal: */
-/* QS - Ratio of preemphasized to full-band energies */
-/* RC1 - First reflection coefficient */
-/* AR_B - Product of the causal forward and reverse pitch prediction gain
-s*/
-/* AR_F - Product of the noncausal forward and rev. pitch prediction gain
-s*/
-/* ZC - Zero crossing rate */
-/* DITHER - Zero crossing threshold level */
-/* MAXMIN - AMDF's 1 octave windowed maximum-to-minimum ratio */
-/* MINPTR - Location of minimum AMDF value */
-/* NVDC - Number of elements in each VDC vector */
-/* NVDCL - Number of VDC vectors */
-/* VDCL - SNR values corresponding to the set of VDC's */
-/* VDC - 2-D voicing decision coefficient vector */
-/* VALUE(9) - Voicing Parameters */
-/* VOICE(2,3)- History of LDA results */
-/* On every call when (HALF .EQ. 1), VOICE(*,I+1) is */
-/* shifted back to VOICE(*,I), for I=1,2. */
-/* VOICE(HALF,3) is written on every call. */
-/* Depending on several conditions, one or more of */
-/* (1,1), (1,2), (2,1), and (2,2) might then be read. */
-/* LBE - Ratio of low-band instantaneous to average energies */
-/* FBE - Ratio of full-band instantaneous to average energies */
-/* LBVE - Low band voiced energy */
-/* LBUE - Low band unvoiced energy */
-/* FBVE - Full band voiced energy */
-/* FBUE - Full band unvoiced energy */
-/* OFBUE - Previous full-band unvoiced energy */
-/* OLBUE - Previous low-band unvoiced energy */
-/* REF - Reference energy for initialization and DITHER threshold */
-/* SNR - Estimate of signal-to-noise ratio */
-/* SNR2 - Estimate of low-band signal-to-noise ratio */
-/* SNRL - SNR level number */
-/* OT - Onset transition present */
-/* VSTATE - Decimal interpretation of binary voicing classifications */
-/* FIRST - First call flag */
-
-/* This subroutine maintains local state from one call to the next. If */
-/* you want to switch to using a new audio stream for this filter, or */
-/* reinitialize its state for any other reason, call the ENTRY */
-/* INITVOICIN. */
-
-/* Subroutine */ int voicin_(integer *vwin, real *inbuf, real *
- lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd,
- integer *mintau, real *ivrc, integer *obound, integer *voibuf,
- integer *af, struct lpc10_encoder_state *st)
-{
- /* Initialized data */
-
- real *dither;
- static real vdc[100] /* was [10][10] */ = { 0.f,1714.f,-110.f,
- 334.f,-4096.f,-654.f,3752.f,3769.f,0.f,1181.f,0.f,874.f,-97.f,
- 300.f,-4096.f,-1021.f,2451.f,2527.f,0.f,-500.f,0.f,510.f,-70.f,
- 250.f,-4096.f,-1270.f,2194.f,2491.f,0.f,-1500.f,0.f,500.f,-10.f,
- 200.f,-4096.f,-1300.f,2e3f,2e3f,0.f,-2e3f,0.f,500.f,0.f,0.f,
- -4096.f,-1300.f,2e3f,2e3f,0.f,-2500.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
- 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
- 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
- 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f };
- static integer nvdcl = 5;
- static real vdcl[10] = { 600.f,450.f,300.f,200.f,0.f,0.f,0.f,0.f,0.f,0.f }
- ;
-
- /* System generated locals */
- integer inbuf_offset = 0, lpbuf_offset = 0, i__1, i__2;
- real r__1, r__2;
-
- /* Builtin functions */
- integer i_nint(real *);
- double sqrt(doublereal);
-
- /* Local variables */
- real ar_b__, ar_f__;
- integer *lbve, *lbue, *fbve, *fbue;
- integer snrl, i__;
- integer *ofbue, *sfbue;
- real *voice;
- integer *olbue, *slbue;
- real value[9];
- integer zc;
- logical ot;
- real qs;
- real *maxmin;
- integer vstate;
- real rc1;
- extern /* Subroutine */ int vparms_(integer *, real *, real *, integer *,
- integer *, real *, integer *, integer *, integer *, integer *,
- real *, real *, real *, real *);
- integer fbe, lbe;
- real *snr;
- real snr2;
-
-/* Global Variables: */
-/* Arguments */
-/* $Log$
- * Revision 1.16 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.15 2003/11/23 22:14:32 markster
- * Various warning cleanups
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:40 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.2 1996/08/20 20:45:00 jaf
- * Removed all static local variables that were SAVE'd in the Fortran
- * code, and put them in struct lpc10_encoder_state that is passed as an
- * argument.
- *
- * Removed init function, since all initialization is now done in
- * init_lpc10_encoder_state().
- *
- * Revision 1.1 1996/08/19 22:30:14 jaf
- * Initial revision
- * */
-/* Revision 1.3 1996/03/29 22:05:55 jaf */
-/* Commented out the common block variables that are not needed by the */
-/* embedded version. */
-
-/* Revision 1.2 1996/03/26 19:34:50 jaf */
-/* Added comments indicating which constants are not needed in an */
-/* application that uses the LPC-10 coder. */
-
-/* Revision 1.1 1996/02/07 14:44:09 jaf */
-/* Initial revision */
-
-/* LPC Processing control variables: */
-
-/* *** Read-only: initialized in setup */
-
-/* Files for Speech, Parameter, and Bitstream Input & Output, */
-/* and message and debug outputs. */
-
-/* Here are the only files which use these variables: */
-
-/* lpcsim.f setup.f trans.f error.f vqsetup.f */
-
-/* Many files which use fdebug are not listed, since it is only used in */
-/* those other files conditionally, to print trace statements. */
-/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* LPC order, Frame size, Quantization rate, Bits per frame, */
-/* Error correction */
-/* Subroutine SETUP is the only place where order is assigned a value, */
-/* and that value is 10. It could increase efficiency 1% or so to */
-/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
-*/
-/* a variable in a COMMON block, since it is used in many places in the */
-/* core of the coding and decoding routines. Actually, I take that back.
-*/
-/* At least when compiling with f2c, the upper bound of DO loops is */
-/* stored in a local variable before the DO loop begins, and then that is
-*/
-/* compared against on each iteration. */
-/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
-/* Similarly for quant, which is given a value of 2400 in SETUP. quant */
-/* is used in only a few places, and never in the core coding and */
-/* decoding routines, so it could be eliminated entirely. */
-/* nbits is similar to quant, and is given a value of 54 in SETUP. */
-/* corrp is given a value of .TRUE. in SETUP, and is only used in the */
-/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */
-/* coder significantly whether it is .TRUE. or .FALSE., or whether it is
-*/
-/* a constant or a variable, since it is only examined once per frame. */
-/* Leaving it as a variable that is set to .TRUE. seems like a good */
-/* idea, since it does enable some error-correction capability for */
-/* unvoiced frames, with no change in the coding rate, and no noticeable
-*/
-/* quality difference in the decoded speech. */
-/* integer quant, nbits */
-/* *** Read/write: variables for debugging, not needed for LPC algorithm
-*/
-
-/* Current frame, Unstable frames, Output clip count, Max onset buffer,
-*/
-/* Debug listing detail level, Line count on listing page */
-
-/* nframe is not needed for an embedded LPC10 at all. */
-/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
-/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */
-/* an application, I would recommend removing the call to ERROR in RCCHK,
-*/
-/* and remove ERROR and nunsfm completely. */
-/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
-*/
-/* sread.f. When LPC10 is embedded into an application, one might want */
-/* to cause it to be incremented in a routine that takes the output of */
-/* SYNTHS and sends it to an audio device. It could be optionally */
-/* displayed, for those that might want to know what it is. */
-/* maxosp is never initialized to 0 in SETUP, although it probably should
-*/
-/* be, and it is updated in subroutine ANALYS. I doubt that its value */
-/* would be of much interest to an application in which LPC10 is */
-/* embedded. */
-/* listl and lincnt are not needed for an embedded LPC10 at all. */
-/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
-/* common /contrl/ quant, nbits */
-/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
-/* Parameters/constants */
-/* Voicing coefficient and Linear Discriminant Analysis variables:
-*/
-/* Max number of VDC's and VDC levels */
-/* The following are not Fortran PARAMETER's, but they are */
-/* initialized with DATA statements, and never modified. */
-/* Actual number of VDC's and levels */
-/* Local variables that need not be saved */
-/* Note: */
-
-/* VALUE(1) through VALUE(8) are assigned values, but VALUE(9) */
-/* never is. Yet VALUE(9) is read in the loop that begins "DO I =
-*/
-/* 1, 9" below. I believe that this doesn't cause any problems in
-*/
-/* this subroutine, because all VDC(9,*) array elements are 0, and
-*/
-/* this is what is multiplied by VALUE(9) in all cases. Still, it
-*/
-/* would save a multiplication to change the loop to "DO I = 1, 8".
-*/
-/* Local state */
-/* WARNING! */
-
-/* VOICE, SFBUE, and SLBUE should be saved from one invocation to */
-/* the next, but they are never given an initial value. */
-
-/* Does Fortran 77 specify some default initial value, like 0, or */
-/* is it undefined? If it is undefined, then this code should be */
-/* corrected to specify an initial value. */
-
-/* For VOICE, note that it is "shifted" in the statement that */
-/* begins "IF (HALF .EQ. 1) THEN" below. Also, uninitialized */
-/* values in the VOICE array can only affect entries in the VOIBUF
-*/
-/* array that are for the same frame, or for an older frame. Thus
-*/
-/* the effects of uninitialized values in VOICE cannot linger on */
-/* for more than 2 or 3 frame times. */
-
-/* For SFBUE and SLBUE, the effects of uninitialized values can */
-/* linger on for many frame times, because their previous values */
-/* are exponentially decayed. Thus it is more important to choose
-*/
-/* initial values for these variables. I would guess that a */
-/* reasonable initial value for SFBUE is REF/16, the same as used */
-/* for FBUE and OFBUE. Similarly, SLBUE can be initialized to */
-/* REF/32, the same as for LBUE and OLBUE. */
-
-/* These guessed initial values should be validated by re-running */
-/* the modified program on some audio samples. */
-
-/* Declare and initialize filters: */
-
- dither = (&st->dither);
- snr = (&st->snr);
- maxmin = (&st->maxmin);
- voice = (&st->voice[0]);
- lbve = (&st->lbve);
- lbue = (&st->lbue);
- fbve = (&st->fbve);
- fbue = (&st->fbue);
- ofbue = (&st->ofbue);
- olbue = (&st->olbue);
- sfbue = (&st->sfbue);
- slbue = (&st->slbue);
-
- /* Parameter adjustments */
- if (vwin) {
- --vwin;
- }
- if (buflim) {
- --buflim;
- }
- if (inbuf) {
- inbuf_offset = buflim[1];
- inbuf -= inbuf_offset;
- }
- if (lpbuf) {
- lpbuf_offset = buflim[3];
- lpbuf -= lpbuf_offset;
- }
- if (ivrc) {
- --ivrc;
- }
- if (obound) {
- --obound;
- }
- if (voibuf) {
- --voibuf;
- }
-
- /* Function Body */
-
-/* The following variables are saved from one invocation to the */
-/* next, but are not initialized with DATA statements. This is */
-/* acceptable, because FIRST is initialized ot .TRUE., and the */
-/* first time that this subroutine is then called, they are all */
-/* given initial values. */
-
-/* SNR */
-/* LBVE, LBUE, FBVE, FBUE, OFBUE, OLBUE */
-
-/* MAXMIN is initialized on the first call, assuming that HALF */
-/* .EQ. 1 on first call. This is how ANALYS calls this subroutine.
-*/
-
-/* Voicing Decision Parameter vector (* denotes zero coefficient): */
-
-/* * MAXMIN */
-/* LBE/LBVE */
-/* ZC */
-/* RC1 */
-/* QS */
-/* IVRC2 */
-/* aR_B */
-/* aR_F */
-/* * LOG(LBE/LBVE) */
-/* Define 2-D voicing decision coefficient vector according to the voicin
-g*/
-/* parameter order above. Each row (VDC vector) is optimized for a speci
-fic*/
-/* SNR. The last element of the vector is the constant. */
-/* E ZC RC1 Qs IVRC2 aRb aRf c */
-
-/* The VOICE array contains the result of the linear discriminant functio
-n*/
-/* (analog values). The VOIBUF array contains the hard-limited binary
-*/
-/* voicing decisions. The VOICE and VOIBUF arrays, according to FORTRAN
- */
-/* memory allocation, are addressed as: */
-
-/* (half-frame number, future-frame number) */
-
-/* | Past | Present | Future1 | Future2 | */
-/* | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 | ---> time */
-
-/* Update linear discriminant function history each frame: */
- if (*half == 1) {
- voice[0] = voice[2];
- voice[1] = voice[3];
- voice[2] = voice[4];
- voice[3] = voice[5];
- *maxmin = *maxamd / max(*minamd,1.f);
- }
-/* Calculate voicing parameters twice per frame: */
- vparms_(&vwin[1], &inbuf[inbuf_offset], &lpbuf[lpbuf_offset], &buflim[1],
- half, dither, mintau, &zc, &lbe, &fbe, &qs, &rc1, &ar_b__, &
- ar_f__);
-/* Estimate signal-to-noise ratio to select the appropriate VDC vector.
-*/
-/* The SNR is estimated as the running average of the ratio of the */
-/* running average full-band voiced energy to the running average */
-/* full-band unvoiced energy. SNR filter has gain of 63. */
- r__1 = (*snr + *fbve / (real) max(*fbue,1)) * 63 / 64.f;
- *snr = (real) i_nint(&r__1);
- snr2 = *snr * *fbue / max(*lbue,1);
-/* Quantize SNR to SNRL according to VDCL thresholds. */
- snrl = 1;
- i__1 = nvdcl - 1;
- for (snrl = 1; snrl <= i__1; ++snrl) {
- if (snr2 > vdcl[snrl - 1]) {
- goto L69;
- }
- }
-/* (Note: SNRL = NVDCL here) */
-L69:
-/* Linear discriminant voicing parameters: */
- value[0] = *maxmin;
- value[1] = (real) lbe / max(*lbve,1);
- value[2] = (real) zc;
- value[3] = rc1;
- value[4] = qs;
- value[5] = ivrc[2];
- value[6] = ar_b__;
- value[7] = ar_f__;
-/* Evaluation of linear discriminant function: */
- voice[*half + 3] = vdc[snrl * 10 - 1];
- for (i__ = 1; i__ <= 8; ++i__) {
- voice[*half + 3] += vdc[i__ + snrl * 10 - 11] * value[i__ - 1];
- }
-/* Classify as voiced if discriminant > 0, otherwise unvoiced */
-/* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */
- if (voice[*half + 3] > 0.f) {
- voibuf[*half + 6] = 1;
- } else {
- voibuf[*half + 6] = 0;
- }
-/* Skip voicing decision smoothing in first half-frame: */
-/* Give a value to VSTATE, so that trace statements below will print
-*/
-/* a consistent value from one call to the next when HALF .EQ. 1. */
-/* The value of VSTATE is not used for any other purpose when this is
-*/
-/* true. */
- vstate = -1;
- if (*half == 1) {
- goto L99;
- }
-/* Voicing decision smoothing rules (override of linear combination): */
-
-/* Unvoiced half-frames: At least two in a row. */
-/* -------------------- */
-
-/* Voiced half-frames: At least two in a row in one frame. */
-/* ------------------- Otherwise at least three in a row. */
-/* (Due to the way transition frames are encoded) */
-
-/* In many cases, the discriminant function determines how to smooth. */
-/* In the following chart, the decisions marked with a * may be overridden
-.*/
-
-/* Voicing override of transitions at onsets: */
-/* If a V/UV or UV/V voicing decision transition occurs within one-half
-*/
-/* frame of an onset bounding a voicing window, then the transition is */
-/* moved to occur at the onset. */
-
-/* P 1F */
-/* ----- ----- */
-/* 0 0 0 0 */
-/* 0 0 0* 1 (If there is an onset there) */
-/* 0 0 1* 0* (Based on 2F and discriminant distance) */
-/* 0 0 1 1 */
-/* 0 1* 0 0 (Always) */
-/* 0 1* 0* 1 (Based on discriminant distance) */
-/* 0* 1 1 0* (Based on past, 2F, and discriminant distance) */
-/* 0 1* 1 1 (If there is an onset there) */
-/* 1 0* 0 0 (If there is an onset there) */
-/* 1 0 0 1 */
-/* 1 0* 1* 0 (Based on discriminant distance) */
-/* 1 0* 1 1 (Always) */
-/* 1 1 0 0 */
-/* 1 1 0* 1* (Based on 2F and discriminant distance) */
-/* 1 1 1* 0 (If there is an onset there) */
-/* 1 1 1 1 */
-
-/* Determine if there is an onset transition between P and 1F. */
-/* OT (Onset Transition) is true if there is an onset between */
-/* P and 1F but not after 1F. */
- ot = ((obound[1] & 2) != 0 || obound[2] == 1) && (obound[3] & 1) == 0;
-/* Multi-way dispatch on voicing decision history: */
- vstate = (voibuf[3] << 3) + (voibuf[4] << 2) + (voibuf[5] << 1) + voibuf[
- 6];
- switch (vstate + 1) {
- case 1: goto L99;
- case 2: goto L1;
- case 3: goto L2;
- case 4: goto L99;
- case 5: goto L4;
- case 6: goto L5;
- case 7: goto L6;
- case 8: goto L7;
- case 9: goto L8;
- case 10: goto L99;
- case 11: goto L10;
- case 12: goto L11;
- case 13: goto L99;
- case 14: goto L13;
- case 15: goto L14;
- case 16: goto L99;
- }
-L1:
- if (ot && voibuf[7] == 1) {
- voibuf[5] = 1;
- }
- goto L99;
-L2:
- if (voibuf[7] == 0 || voice[2] < -voice[3]) {
- voibuf[5] = 0;
- } else {
- voibuf[6] = 1;
- }
- goto L99;
-L4:
- voibuf[4] = 0;
- goto L99;
-L5:
- if (voice[1] < -voice[2]) {
- voibuf[4] = 0;
- } else {
- voibuf[5] = 1;
- }
- goto L99;
-/* VOIBUF(2,0) must be 0 */
-L6:
- if (voibuf[1] == 1 || voibuf[7] == 1 || voice[3] > voice[0]) {
- voibuf[6] = 1;
- } else {
- voibuf[3] = 1;
- }
- goto L99;
-L7:
- if (ot) {
- voibuf[4] = 0;
- }
- goto L99;
-L8:
- if (ot) {
- voibuf[4] = 1;
- }
- goto L99;
-L10:
- if (voice[2] < -voice[1]) {
- voibuf[5] = 0;
- } else {
- voibuf[4] = 1;
- }
- goto L99;
-L11:
- voibuf[4] = 1;
- goto L99;
-L13:
- if (voibuf[7] == 0 && voice[3] < -voice[2]) {
- voibuf[6] = 0;
- } else {
- voibuf[5] = 1;
- }
- goto L99;
-L14:
- if (ot && voibuf[7] == 0) {
- voibuf[5] = 0;
- }
-/* GOTO 99 */
-L99:
-/* Now update parameters: */
-/* ---------------------- */
-
-/* During unvoiced half-frames, update the low band and full band unvoice
-d*/
-/* energy estimates (LBUE and FBUE) and also the zero crossing */
-/* threshold (DITHER). (The input to the unvoiced energy filters is */
-/* restricted to be less than 10dB above the previous inputs of the */
-/* filters.) */
-/* During voiced half-frames, update the low-pass (LBVE) and all-pass */
-/* (FBVE) voiced energy estimates. */
- if (voibuf[*half + 6] == 0) {
-/* Computing MIN */
- i__1 = fbe, i__2 = *ofbue * 3;
- r__1 = (*sfbue * 63 + (min(i__1,i__2) << 3)) / 64.f;
- *sfbue = i_nint(&r__1);
- *fbue = *sfbue / 8;
- *ofbue = fbe;
-/* Computing MIN */
- i__1 = lbe, i__2 = *olbue * 3;
- r__1 = (*slbue * 63 + (min(i__1,i__2) << 3)) / 64.f;
- *slbue = i_nint(&r__1);
- *lbue = *slbue / 8;
- *olbue = lbe;
- } else {
- r__1 = (*lbve * 63 + lbe) / 64.f;
- *lbve = i_nint(&r__1);
- r__1 = (*fbve * 63 + fbe) / 64.f;
- *fbve = i_nint(&r__1);
- }
-/* Set dither threshold to yield proper zero crossing rates in the */
-/* presence of low frequency noise and low level signal input. */
-/* NOTE: The divisor is a function of REF, the expected energies. */
-/* Computing MIN */
-/* Computing MAX */
- r__2 = (real)(sqrt((real) (*lbue * *lbve)) * 64 / 3000);
- r__1 = max(r__2,1.f);
- *dither = min(r__1,20.f);
-/* Voicing decisions are returned in VOIBUF. */
- return 0;
-} /* voicin_ */
diff --git a/1.4/codecs/lpc10/vparms.c b/1.4/codecs/lpc10/vparms.c
deleted file mode 100644
index c75b1b17d..000000000
--- a/1.4/codecs/lpc10/vparms.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-
-$Log$
-Revision 1.15 2004/06/26 03:50:14 markster
-Merge source cleanups (bug #1911)
-
-Revision 1.14 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.1.1.1 2003/02/12 13:59:15 matteo
-mer feb 12 14:56:57 CET 2003
-
-Revision 1.2 2000/01/05 08:20:40 markster
-Some OSS fixes and a few lpc changes to make it actually work
-
- * Revision 1.1 1996/08/19 22:30:04 jaf
- * Initial revision
- *
-
-*/
-
-/* -- translated by f2c (version 19951025).
- You must link the resulting object file with the libraries:
- -lf2c -lm (in that order)
-*/
-
-#include "f2c.h"
-
-#ifdef P_R_O_T_O_T_Y_P_E_S
-extern int vparms_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *dither, integer *mintau, integer *zc, integer *lbe, integer *fbe, real *qs, real *rc1, real *ar_b__, real *ar_f__);
-#endif
-
-/* Table of constant values */
-
-static real c_b2 = 1.f;
-
-/* ********************************************************************* */
-
-/* VPARMS Version 50 */
-
-/* $Log$
- * Revision 1.15 2004/06/26 03:50:14 markster
- * Merge source cleanups (bug #1911)
- *
- * Revision 1.14 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
- * mer feb 12 14:56:57 CET 2003
- *
- * Revision 1.2 2000/01/05 08:20:40 markster
- * Some OSS fixes and a few lpc changes to make it actually work
- *
- * Revision 1.1 1996/08/19 22:30:04 jaf
- * Initial revision
- * */
-/* Revision 1.6 1996/03/29 18:01:16 jaf */
-/* Added some more comments about the range of INBUF and LPBUF that can */
-/* be read. Note that it is possible for index VWIN(2)+1 to be read from */
-/* INBUF, which might be outside of its defined range, although that will */
-/* require more careful checking. */
-
-/* Revision 1.5 1996/03/19 00:02:02 jaf */
-/* I just noticed that the argument DITHER is modified inside of this */
-/* subroutine. Comments were added explaining the possible final values. */
-
-/* Revision 1.4 1996/03/18 22:22:59 jaf */
-/* Finishing the job I said I did with the last check-in comments. */
-
-/* Revision 1.3 1996/03/18 22:22:17 jaf */
-/* Just added a few comments about which array indices of the arguments */
-/* are used, and mentioning that this subroutine has no local state. */
-
-/* Revision 1.2 1996/03/13 15:02:58 jaf */
-/* Comments added explaining that none of the local variables of this */
-/* subroutine need to be saved from one invocation to the next. */
-
-/* Revision 1.1 1996/02/07 14:50:42 jaf */
-/* Initial revision */
-
-
-/* ********************************************************************* */
-
-/* Calculate voicing parameters: */
-
-/* Input: */
-/* VWIN - Voicing window limits */
-/* Indices 1 through 2 read. */
-/* INBUF - Input speech buffer */
-/* Indices START-1 through STOP read, */
-/* where START and STOP are defined in the code (only written once).
-*/
-/* Note that STOP can be as large as VWIN(2)+1 ! */
-/* LPBUF - Low pass filtered speech */
-/* Indices START-MINTAU through STOP+MINTAU read, */
-/* where START and STOP are defined in the code (only written once).
-*/
-/* BUFLIM - Array bounds for INBUF and LPBUF */
-/* Indices 1 through 4 read. */
-/* HALF - Half frame (1 or 2) */
-/* MINTAU - Lag corresponding to minimum AMDF value (pitch estimate) */
-/* Input/Output: */
-/* DITHER - Zero crossing threshold */
-/* The resulting value might be the negation of the input */
-/* value. It might always be the same as the input value, */
-/* if the DO loop below always executes an even number of times. */
-/* Output: (all of them are written on every call) */
-/* ZC - Zero crossing rate */
-/* LBE - Low band energy (sum of magnitudes - SM) */
-/* FBE - Full band energy (SM) */
-/* QS - Ratio of 6 dB/oct preemphasized energy to full band energy */
-/* RC1 - First reflection coefficient */
-/* AR_B - Product of the causal forward and reverse pitch */
-/* prediction gains */
-/* AR_F - Product of the noncausal forward and reverse pitch */
-/* prediction gains */
-/* Internal: */
-/* OLDSGN - Previous sign of dithered signal */
-/* VLEN - Length of voicing window */
-/* START - Lower address of current half of voicing window */
-/* STOP - Upper address of current half of voicing window */
-/* E_0 - Energy of LPF speech (sum of squares - SS) */
-/* E_B - Energy of LPF speech backward one pitch period (SS) */
-/* E_F - Energy of LPF speech forward one pitch period (SS) */
-/* R_B - Autocovariance of LPF speech backward one pitch period */
-/* R_F - Autocovariance of LPF speech forward one pitch period */
-/* LP_RMS - Energy of LPF speech (sum of magnitudes - SM) */
-/* AP_RMS - Energy of all-pass speech (SM) */
-/* E_PRE - Energy of 6dB preemphasized speech (SM) */
-/* E0AP - Energy of all-pass speech (SS) */
-
-/* This subroutine has no local state. */
-
-/* Subroutine */ int vparms_(integer *vwin, real *inbuf, real *lpbuf, integer
- *buflim, integer *half, real *dither, integer *mintau, integer *zc,
- integer *lbe, integer *fbe, real *qs, real *rc1, real *ar_b__, real *
- ar_f__)
-{
- /* System generated locals */
- integer inbuf_offset, lpbuf_offset, i__1;
- real r__1, r__2;
-
- /* Builtin functions */
- double r_sign(real *, real *);
- integer i_nint(real *);
-
- /* Local variables */
- integer vlen, stop, i__;
- real e_pre__;
- integer start;
- real ap_rms__, e_0__, oldsgn, lp_rms__, e_b__, e_f__, r_b__, r_f__, e0ap;
-
-/* Arguments */
-/* Local variables that need not be saved */
-/* Calculate zero crossings (ZC) and several energy and correlation */
-/* measures on low band and full band speech. Each measure is taken */
-/* over either the first or the second half of the voicing window, */
-/* depending on the variable HALF. */
- /* Parameter adjustments */
- --vwin;
- --buflim;
- lpbuf_offset = buflim[3];
- lpbuf -= lpbuf_offset;
- inbuf_offset = buflim[1];
- inbuf -= inbuf_offset;
-
- /* Function Body */
- lp_rms__ = 0.f;
- ap_rms__ = 0.f;
- e_pre__ = 0.f;
- e0ap = 0.f;
- *rc1 = 0.f;
- e_0__ = 0.f;
- e_b__ = 0.f;
- e_f__ = 0.f;
- r_f__ = 0.f;
- r_b__ = 0.f;
- *zc = 0;
- vlen = vwin[2] - vwin[1] + 1;
- start = vwin[1] + (*half - 1) * vlen / 2 + 1;
- stop = start + vlen / 2 - 1;
-
-/* I'll use the symbol HVL in the table below to represent the value */
-/* VLEN/2. Note that if VLEN is odd, then HVL should be rounded down, */
-/* i.e., HVL = (VLEN-1)/2. */
-
-/* HALF START STOP */
-
-/* 1 VWIN(1)+1 VWIN(1)+HVL */
-/* 2 VWIN(1)+HVL+1 VWIN(1)+2*HVL */
-
-/* Note that if VLEN is even and HALF is 2, then STOP will be */
-/* VWIN(1)+VLEN = VWIN(2)+1. That could be bad, if that index of INBUF */
-/* is undefined. */
-
- r__1 = inbuf[start - 1] - *dither;
- oldsgn = (real)r_sign(&c_b2, &r__1);
- i__1 = stop;
- for (i__ = start; i__ <= i__1; ++i__) {
- lp_rms__ += (r__1 = lpbuf[i__], abs(r__1));
- ap_rms__ += (r__1 = inbuf[i__], abs(r__1));
- e_pre__ += (r__1 = inbuf[i__] - inbuf[i__ - 1], abs(r__1));
-/* Computing 2nd power */
- r__1 = inbuf[i__];
- e0ap += r__1 * r__1;
- *rc1 += inbuf[i__] * inbuf[i__ - 1];
-/* Computing 2nd power */
- r__1 = lpbuf[i__];
- e_0__ += r__1 * r__1;
-/* Computing 2nd power */
- r__1 = lpbuf[i__ - *mintau];
- e_b__ += r__1 * r__1;
-/* Computing 2nd power */
- r__1 = lpbuf[i__ + *mintau];
- e_f__ += r__1 * r__1;
- r_f__ += lpbuf[i__] * lpbuf[i__ + *mintau];
- r_b__ += lpbuf[i__] * lpbuf[i__ - *mintau];
- r__1 = inbuf[i__] + *dither;
- if (r_sign(&c_b2, &r__1) != oldsgn) {
- ++(*zc);
- oldsgn = -oldsgn;
- }
- *dither = -(*dither);
- }
-/* Normalized short-term autocovariance coefficient at unit sample delay
- */
- *rc1 /= max(e0ap,1.f);
-/* Ratio of the energy of the first difference signal (6 dB/oct preemphas
-is)*/
-/* to the energy of the full band signal */
-/* Computing MAX */
- r__1 = ap_rms__ * 2.f;
- *qs = e_pre__ / max(r__1,1.f);
-/* aR_b is the product of the forward and reverse prediction gains, */
-/* looking backward in time (the causal case). */
- *ar_b__ = r_b__ / max(e_b__,1.f) * (r_b__ / max(e_0__,1.f));
-/* aR_f is the same as aR_b, but looking forward in time (non causal case
-).*/
- *ar_f__ = r_f__ / max(e_f__,1.f) * (r_f__ / max(e_0__,1.f));
-/* Normalize ZC, LBE, and FBE to old fixed window length of 180. */
-/* (The fraction 90/VLEN has a range of .58 to 1) */
- r__2 = (real) (*zc << 1);
- r__1 = r__2 * (90.f / vlen);
- *zc = i_nint(&r__1);
-/* Computing MIN */
- r__1 = lp_rms__ / 4 * (90.f / vlen);
- i__1 = i_nint(&r__1);
- *lbe = min(i__1,32767);
-/* Computing MIN */
- r__1 = ap_rms__ / 4 * (90.f / vlen);
- i__1 = i_nint(&r__1);
- *fbe = min(i__1,32767);
- return 0;
-} /* vparms_ */
-
diff --git a/1.4/codecs/lpc10_slin_ex.h b/1.4/codecs/lpc10_slin_ex.h
deleted file mode 100644
index cf9f05999..000000000
--- a/1.4/codecs/lpc10_slin_ex.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*! \file
- * \brief 8-bit raw data
- *
- * Source: example.lpc10
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char lpc10_slin_ex[] = {
-0x1, 0x8, 0x31, 0x8, 0x31, 0x80, 0x30 };
diff --git a/1.4/codecs/slin_adpcm_ex.h b/1.4/codecs/slin_adpcm_ex.h
deleted file mode 100644
index 801549a3c..000000000
--- a/1.4/codecs/slin_adpcm_ex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*! \file
- * \brief slin_adpcm_ex.h --
- *
- * Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
- *
- * Source: g723.example
- *
- * Copyright (C) 2001-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_adpcm_ex[] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
diff --git a/1.4/codecs/slin_g726_ex.h b/1.4/codecs/slin_g726_ex.h
deleted file mode 100644
index 8dad39cbd..000000000
--- a/1.4/codecs/slin_g726_ex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*! \file
- * \brief slin_adpcm_ex.h --
- *
- * Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
- *
- * Source: g726.example
- *
- * Copyright (C) 2001-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_g726_ex[] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
diff --git a/1.4/codecs/slin_gsm_ex.h b/1.4/codecs/slin_gsm_ex.h
deleted file mode 100644
index 7ac281800..000000000
--- a/1.4/codecs/slin_gsm_ex.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*! \file
- * \brief Signed 16-bit audio data
- *
- * Source: gsm.example
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_gsm_ex[] = {
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 0xfff8, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 0x0008, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-0x0008, 000000, 000000, 000000, 0xfff8, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 0x0008, 000000, 000000, 000000 };
diff --git a/1.4/codecs/slin_ilbc_ex.h b/1.4/codecs/slin_ilbc_ex.h
deleted file mode 100644
index b89655c6b..000000000
--- a/1.4/codecs/slin_ilbc_ex.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*! \file
- * \brief Signed 16-bit audio data
- *
- * Source: gsm.example
- *
- * Copyright (C) 1999-2005, Digium Inc
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_ilbc_ex[] = {
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 0xfff8, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 0x0008, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-0x0008, 000000, 000000, 000000, 0xfff8, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 0x0008, 000000, 000000, 000000 };
diff --git a/1.4/codecs/slin_lpc10_ex.h b/1.4/codecs/slin_lpc10_ex.h
deleted file mode 100644
index 169e9a9e1..000000000
--- a/1.4/codecs/slin_lpc10_ex.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*! \file
- * \brief Signed 16-bit audio data
- *
- * Source: example.slin
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_lpc10_ex[] = {
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
-000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000 };
diff --git a/1.4/codecs/slin_speex_ex.h b/1.4/codecs/slin_speex_ex.h
deleted file mode 100644
index 0c6258c37..000000000
--- a/1.4/codecs/slin_speex_ex.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*! \file
- * \brief Signed 16-bit audio data, 500ms of speech at 8kHz to ensure no DTX triggered
- *
- * Source: speex.example
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_speex_ex[] = {
-0x4a00, 0xa700, 0x6d00, 0x4900, 0x5800, 0x3e00, 0x1b00, 0x1400, 0xf9ff, 0xe4ff, 0x0a00, 0xf0ff, 0xbbff, 0x0200, 0x0800, 0xd6ff,
-0xf1ff, 0x1200, 0x0500, 0x1000, 0x0f00, 0x0700, 0x4100, 0x2800, 0xf4ff, 0x2900, 0x3100, 0xf4ff, 0xefff, 0xdaff, 0xdaff, 0xc2ff,
-0xa5ff, 0xccff, 0xd4ff, 0xc7ff, 0xe6ff, 0x0600, 0x0c00, 0x1900, 0x1200, 0x0d00, 0x2900, 0x1e00, 0xf4ff, 0x0000, 0x1200, 0xf5ff,
-0xe5ff, 0x0000, 0x0000, 0xf1ff, 0x0300, 0x0b00, 0xfdff, 0x0500, 0x0f00, 0x0600, 0x0d00, 0x0f00, 0x0000, 0xfdff, 0xfcff, 0xe5ff,
-0xdcff, 0xe0ff, 0xafff, 0xb2ff, 0xe4ff, 0xceff, 0xe2ff, 0x0000, 0x1600, 0x2600, 0x2400, 0x3f00, 0x4a00, 0x3d00, 0x2b00, 0x2f00,
-0x4300, 0x1000, 0x0300, 0x0700, 0xe9ff, 0xf3ff, 0xebff, 0xd9ff, 0xe5ff, 0xf9ff, 0xeeff, 0xe9ff, 0x0500, 0x0a00, 0x0300, 0x0800,
-0x1800, 0x1c00, 0x1000, 0x1300, 0x0d00, 0x0400, 0x0200, 0xf9ff, 0xe4ff, 0xe6ff, 0xe0ff, 0xd9ff, 0xecff, 0xf2ff, 0xe8ff, 0xfdff,
-0x1100, 0x0d00, 0x0b00, 0x1100, 0x1100, 0x1200, 0x0c00, 0x0400, 0x0900, 0x0d00, 0x0100, 0xfdff, 0x0000, 0xfdff, 0x0000, 0xffff,
-0xf5ff, 0xfcff, 0x0600, 0xfeff, 0x0000, 0x0300, 0x1300, 0x1700, 0x0300, 0x0700, 0xf0ff, 0xe1ff, 0xd7ff, 0xd1ff, 0xc6ff, 0xc2ff,
-0xf2ff, 0xf0ff, 0xecff, 0x0700, 0x3200, 0x2d00, 0x0400, 0x2200, 0x2900, 0x1900, 0x2400, 0x0500, 0x1900, 0x1f00, 0xfeff, 0x0d00,
-0x0600, 0xebff, 0xf5ff, 0x0600, 0xebff, 0xe3ff, 0x0c00, 0x0d00, 0xefff, 0x1100, 0x3a00, 0x0700, 0x1700, 0x2f00, 0xf7ff, 0x0700,
-0x2600, 0xd9ff, 0xb8ff, 0xeaff, 0xbeff, 0x9eff, 0xc7ff, 0xccff, 0xc4ff, 0xeeff, 0x0000, 0xfdff, 0x1200, 0x1d00, 0x3100, 0x3600,
-0x2d00, 0x3c00, 0x4700, 0x3000, 0x2000, 0x2300, 0x1800, 0x0900, 0xffff, 0xeaff, 0xe7ff, 0xe8ff, 0xd3ff, 0xc5ff, 0xe1ff, 0xedff,
-0xe4ff, 0xfaff, 0xe3ff, 0xacff, 0xcdff, 0xd4ff, 0xabff, 0xa6ff, 0xdaff, 0x0500, 0xf1ff, 0xfaff, 0x3800, 0x7000, 0x4100, 0x1c00,
-0x4b00, 0x5300, 0x3a00, 0x2a00, 0x1400, 0x2000, 0x1c00, 0x1500, 0x0500, 0xf6ff, 0x0000, 0x1300, 0xfaff, 0xe9ff, 0x0000, 0x0a00,
-0xfcff, 0xfaff, 0x1000, 0x1200, 0x0900, 0x0c00, 0x0400, 0x0000, 0x0800, 0xffff, 0xe7ff, 0xe2ff, 0xe6ff, 0xd5ff, 0xdaff, 0xe0ff,
-0xdcff, 0xeeff, 0x0200, 0xfbff, 0x0000, 0x1000, 0x1100, 0x1500, 0x1900, 0x1400, 0x1900, 0x1c00, 0x1500, 0x1000, 0x0d00, 0x0b00,
-0x0700, 0x0200, 0xf6ff, 0xf5ff, 0xf9ff, 0xecff, 0xe8ff, 0xeeff, 0xf4ff, 0xf4ff, 0xeeff, 0xecff, 0xebff, 0xd7ff, 0xd8ff, 0xeaff,
-0xe0ff, 0xddff, 0x0100, 0x0500, 0xf8ff, 0x1800, 0x2d00, 0x1d00, 0x1a00, 0x2100, 0x1f00, 0x1f00, 0x1a00, 0x0f00, 0x0300, 0x0d00,
-0x0e00, 0xfeff, 0x0000, 0xfeff, 0x0000, 0x0000, 0xf1ff, 0xfaff, 0x0a00, 0x0100, 0xf5ff, 0x0300, 0x0e00, 0x0300, 0x0200, 0x0000,
-0x0800, 0x0700, 0xf8ff, 0xf5ff, 0xf1ff, 0xefff, 0xe9ff, 0xe0ff, 0xe0ff, 0xedff, 0xf0ff, 0xedff, 0xfcff, 0xffff, 0xfdff, 0x0a00,
-0x0f00, 0x0e00, 0x0f00, 0x1700, 0x1400, 0x0700, 0x0500, 0x0800, 0x0000, 0x0200, 0x0400, 0xfaff, 0xffff, 0x0200, 0xfaff, 0xfbff,
-0x0300, 0x0400, 0x0400, 0x0100, 0xe7ff, 0xd4ff, 0xdbff, 0xe2ff, 0xe0ff, 0xd0ff, 0xe7ff, 0x0700, 0xf2ff, 0x0000, 0x2d00, 0x2000,
-0x1800, 0x2c00, 0x1f00, 0x2600, 0x2200, 0x0e00, 0x0e00, 0x0000, 0x0400, 0x0800, 0x0300, 0xfbff, 0x0500, 0x1d00, 0x0000, 0xfbff,
-0x2e00, 0x2500, 0x0600, 0x1c00, 0x2600, 0x1600, 0x0e00, 0x0200, 0xf9ff, 0x0000, 0xe1ff, 0xc0ff, 0xd5ff, 0xc9ff, 0xb6ff, 0xbcff,
-0xccff, 0xc9ff, 0xcbff, 0xe5ff, 0xeaff, 0xf0ff, 0xfeff, 0x0000, 0x0b00, 0x1f00, 0x2000, 0x1b00, 0x2000, 0x2400, 0x1800, 0x1200,
-0x1700, 0x0c00, 0x0b00, 0x0d00, 0xfdff, 0xf5ff, 0x0000, 0xf9ff, 0xefff, 0xfaff, 0xf7ff, 0xf0ff, 0xe7ff, 0xcbff, 0xd1ff, 0xedff,
-0xf5ff, 0xfcff, 0xfeff, 0x1e00, 0x3200, 0x2200, 0x3800, 0x4f00, 0x3800, 0x2c00, 0x4000, 0x3e00, 0x2e00, 0x2900, 0x1200, 0x0500,
-0x0700, 0x0000, 0xf2ff, 0xf2ff, 0xf8ff, 0xf5ff, 0xf7ff, 0xeaff, 0xefff, 0x0100, 0xfcff, 0xf9ff, 0x0000, 0x0700, 0xf9ff, 0xf2ff,
-0xf9ff, 0xf0ff, 0xf1ff, 0xe7ff, 0xddff, 0xe1ff, 0xddff, 0xd9ff, 0xdaff, 0xe1ff, 0xe2ff, 0xe5ff, 0xe5ff, 0xf0ff, 0xfaff, 0xf4ff,
-0xfdff, 0x1100, 0x0e00, 0x0e00, 0x1800, 0x1600, 0x1200, 0x1400, 0x1500, 0x1200, 0x0b00, 0x0600, 0x0c00, 0x0500, 0x0100, 0x0b00,
-0x0200, 0xfaff, 0xffff, 0xf9ff, 0xe8ff, 0xd0ff, 0xc9ff, 0xd5ff, 0xe0ff, 0xe6ff, 0xedff, 0xf5ff, 0x1100, 0x1300, 0x1f00, 0x3600,
-0x2900, 0x2200, 0x2c00, 0x3700, 0x2d00, 0x2000, 0x1a00, 0x0800, 0xfaff, 0xfcff, 0xf6ff, 0xf2ff, 0xebff, 0xf7ff, 0x0200, 0xf1ff,
-0xf5ff, 0x0d00, 0x0900, 0xf9ff, 0x1000, 0x2000, 0x0a00, 0xf9ff, 0xffff, 0xf9ff, 0xf2ff, 0xeeff, 0xdbff, 0xd8ff, 0xdbff, 0xdaff,
-0xdaff, 0xdfff, 0xe6ff, 0xecff, 0xedff, 0xf0ff, 0x0500, 0x0900, 0x0400, 0x0f00, 0x2600, 0x2700, 0x2200, 0x2b00, 0x1700, 0x1100,
-0x2a00, 0x2200, 0x0c00, 0x0200, 0x0100, 0x0200, 0xfeff, 0xfaff, 0xf7ff, 0xf3ff, 0xf1ff, 0xf5ff, 0xf6ff, 0xe8ff, 0xd3ff, 0xcdff,
-0xdbff, 0xebff, 0xedff, 0xf0ff, 0xfbff, 0x1400, 0x1700, 0x2000, 0x3400, 0x2700, 0x1a00, 0x2100, 0x2e00, 0x2900, 0x1e00, 0x0c00,
-0xfbff, 0xfbff, 0xf9ff, 0xf3ff, 0xf4ff, 0xe8ff, 0xecff, 0x0300, 0xf8ff, 0xf4ff, 0x0100, 0x0600, 0xf7ff, 0x0900, 0x1e00, 0x0f00,
-0x0900, 0x0700, 0x0000, 0x0000, 0x0000, 0xf5ff, 0xebff, 0xefff, 0xf3ff, 0xeeff, 0xf0ff, 0xf1ff, 0xefff, 0xf0ff, 0xf6ff, 0xfcff,
-0xf9ff, 0xf8ff, 0xfbff, 0x0300, 0x0900, 0x0800, 0x0900, 0x0100, 0x0200, 0x0c00, 0x0e00, 0x0300, 0xfdff, 0xfcff, 0xfbff, 0xfbff,
-0xf9ff, 0xf3ff, 0xf3ff, 0xecff, 0xf6ff, 0xfbff, 0xf4ff, 0xecff, 0xd6ff, 0xdcff, 0xf1ff, 0xf1ff, 0xeeff, 0xf6ff, 0x0600, 0x0a00,
-0x1000, 0x1e00, 0x1b00, 0x1100, 0x1800, 0x2800, 0x2500, 0x2600, 0x1c00, 0x0e00, 0x0900, 0x0e00, 0x0800, 0x0200, 0xfaff, 0xf5ff,
-0x0300, 0xf8ff, 0xfcff, 0x0500, 0x0500, 0x0000, 0xfaff, 0x0b00, 0x1c00, 0x0d00, 0xfdff, 0x0200, 0x0100, 0xfbff, 0xf5ff, 0xe8ff,
-0xe8ff, 0xecff, 0xdaff, 0xd1ff, 0xddff, 0xdeff, 0xd8ff, 0xdeff, 0xedff, 0xf3ff, 0xf8ff, 0x0100, 0x1100, 0x2300, 0x2800, 0x3100,
-0x3200, 0x3500, 0x3a00, 0x3e00, 0x3400, 0x2700, 0x2100, 0x1400, 0x0900, 0xf7ff, 0xfaff, 0xf3ff, 0xe2ff, 0xeaff, 0xe3ff, 0xdfff,
-0xd7ff, 0xc9ff, 0xdaff, 0xe4ff, 0xe0ff, 0xe4ff, 0xefff, 0xf4ff, 0xf6ff, 0x0000, 0x0100, 0x0000, 0x0600, 0x0c00, 0x0c00, 0x1000,
-0x1900, 0x1600, 0x1500, 0x1600, 0x1100, 0x1400, 0x1200, 0x1300, 0x0900, 0x0d00, 0x1400, 0x0e00, 0x1900, 0x1400, 0x0900, 0x0600,
-0x1600, 0x1900, 0x0800, 0x0300, 0x0000, 0xf5ff, 0xedff, 0xeaff, 0xdbff, 0xdcff, 0xcbff, 0xb7ff, 0xbfff, 0xc3ff, 0xc2ff, 0xbfff,
-0xcbff, 0xdaff, 0xe7ff, 0xf9ff, 0x0600, 0x1b00, 0x2c00, 0x2900, 0x3d00, 0x4b00, 0x4700, 0x4b00, 0x4a00, 0x4300, 0x3700, 0x3300,
-0x1f00, 0x1400, 0x1000, 0x0f00, 0x0c00, 0x0000, 0xf6ff, 0xe7ff, 0xe7ff, 0xdeff, 0xd3ff, 0xe1ff, 0xdeff, 0xd9ff, 0xe0ff, 0xe8ff,
-0xf1ff, 0xeaff, 0xe8ff, 0xf5ff, 0xf7ff, 0xf6ff, 0xf7ff, 0xf4ff, 0xf8ff, 0xfcff, 0x0100, 0xfcff, 0xf7ff, 0x0100, 0x0600, 0x0100,
-0x0700, 0x0200, 0x0c00, 0x1000, 0x0e00, 0x1c00, 0x1a00, 0x1a00, 0x1800, 0x2200, 0x1f00, 0x1600, 0x1700, 0x0b00, 0xfbff, 0xfcff,
-0xeaff, 0xd6ff, 0xdfff, 0xcbff, 0xc0ff, 0xc0ff, 0xbcff, 0xc1ff, 0xc5ff, 0xd1ff, 0xdaff, 0xecff, 0xffff, 0xfeff, 0x1000, 0x2700,
-0x2400, 0x2400, 0x3800, 0x3600, 0x3100, 0x3300, 0x2800, 0x2000, 0x1e00, 0x1d00, 0x0800, 0x0400, 0x1600, 0x0900, 0x0000, 0x0d00,
-0x0100, 0xefff, 0xf1ff, 0xedff, 0xe0ff, 0xe6ff, 0xf5ff, 0xe1ff, 0xdaff, 0xf3ff, 0xf6ff, 0xeeff, 0xf1ff, 0xf9ff, 0xfbff, 0x0000,
-0x0700, 0x0900, 0x0d00, 0x1c00, 0x1d00, 0x1b00, 0x1a00, 0x2500, 0x2500, 0x1a00, 0x1600, 0x0e00, 0x0c00, 0x0b00, 0x0500, 0x0100,
-0x0200, 0x0000, 0xfbff, 0xfcff, 0xfdff, 0xfcff, 0xfcff, 0xf9ff, 0xf6ff, 0xf3ff, 0xeaff, 0xe6ff, 0xecff, 0xe8ff, 0xdfff, 0xe6ff,
-0xddff, 0xdaff, 0xecff, 0xefff, 0xf2ff, 0xfdff, 0x0100, 0xffff, 0x0800, 0x1700, 0x1000, 0x1300, 0x2100, 0x1b00, 0x1800, 0x1a00,
-0x1200, 0x1000, 0x2000, 0x1100, 0x0000, 0x0700, 0x0500, 0xfdff, 0xfcff, 0x0300, 0xf2ff, 0xeaff, 0xe1ff, 0xcdff, 0xd2ff, 0xe0ff,
-0xe0ff, 0xd5ff, 0xdfff, 0xf3ff, 0xf7ff, 0xfcff, 0x1100, 0x1800, 0x1900, 0x2100, 0x2600, 0x2800, 0x2900, 0x2d00, 0x2400, 0x1b00,
-0x1a00, 0x1000, 0x0800, 0x0500, 0xfcff, 0xf1ff, 0xf4ff, 0xf6ff, 0xf2ff, 0xf6ff, 0xffff, 0xffff, 0x0000, 0x0a00, 0x0a00, 0xfbff,
-0x0200, 0x0700, 0xf9ff, 0xf2ff, 0xeaff, 0xedff, 0xdfff, 0xd9ff, 0xe3ff, 0xd8ff, 0xdbff, 0xddff, 0xe2ff, 0xefff, 0xf6ff, 0xffff,
-0x0000, 0x0d00, 0x1500, 0x1600, 0x2200, 0x2800, 0x2700, 0x2900, 0x3700, 0x2d00, 0x2500, 0x2c00, 0x2900, 0x1100, 0x0600, 0xfdff,
-0xedff, 0xeaff, 0xddff, 0xcfff, 0xc9ff, 0xc0ff, 0xa8ff, 0xa8ff, 0xbeff, 0xceff, 0xd6ff, 0xe1ff, 0xf4ff, 0x1000, 0x1100, 0x1e00,
-0x3e00, 0x3c00, 0x3c00, 0x3d00, 0x3e00, 0x3300, 0x3000, 0x2b00, 0x1300, 0x0b00, 0x0600, 0xfaff, 0xf6ff, 0xf4ff, 0xe9ff, 0xedff,
-0x0000, 0xf8ff, 0xfbff, 0x0400, 0x0300, 0x0a00, 0x1400, 0x1300, 0x0100, 0x0b00, 0x0400, 0xf9ff, 0xf8ff, 0xeeff, 0xe9ff, 0xdeff,
-0xe1ff, 0xdaff, 0xd7ff, 0xe5ff, 0xd2ff, 0xd3ff, 0xe3ff, 0xe7ff, 0xedff, 0xf5ff, 0x0000, 0x0600, 0x1300, 0x1f00, 0x1c00, 0x2600,
-0x2b00, 0x3100, 0x2d00, 0x3100, 0x2e00, 0x2600, 0x1900, 0x1100, 0x0400, 0xf3ff, 0xf3ff, 0xdcff, 0xdbff, 0xddff, 0xd2ff, 0xccff,
-0xbbff, 0xc3ff, 0xe4ff, 0xf4ff, 0xf6ff, 0xfbff, 0x1600, 0x2100, 0x1600, 0x2000, 0x2500, 0x1b00, 0x2700, 0x2100, 0x1400, 0x0d00,
-0x1300, 0x0800, 0xfbff, 0xf8ff, 0xecff, 0xeeff, 0x0000, 0xefff, 0xeeff, 0xfcff, 0x0000, 0xfeff, 0x0600, 0x0700, 0x0200, 0x1400,
-0x1600, 0x0700, 0x0d00, 0x1400, 0x0e00, 0x0900, 0x0b00, 0x0500, 0xfaff, 0x0600, 0x0000, 0xf2ff, 0xfaff, 0xf6ff, 0xe9ff, 0xecff,
-0xecff, 0xe2ff, 0xe7ff, 0xf3ff, 0xf6ff, 0xf4ff, 0x0000, 0x0000, 0xffff, 0x1400, 0x0f00, 0x0f00, 0x1500, 0x1400, 0x1100, 0x1200,
-0x0c00, 0x0400, 0x0500, 0xffff, 0x0200, 0xfbff, 0xf5ff, 0xfeff, 0xf5ff, 0xe5ff, 0xe3ff, 0xe4ff, 0xe6ff, 0x0a00, 0xffff, 0xf3ff,
-0x0900, 0x0d00, 0xfbff, 0x0700, 0x0c00, 0xffff, 0x1200, 0x1e00, 0xfdff, 0x0700, 0x1c00, 0x1200, 0x0f00, 0x1200, 0x1500, 0xfbff,
-0x1200, 0x2300, 0xf9ff, 0x0300, 0x0d00, 0xf2ff, 0xf2ff, 0xf5ff, 0xd8ff, 0xd0ff, 0xddff, 0xd8ff, 0xc4ff, 0xdbff, 0xe0ff, 0xd6ff,
-0xecff, 0xd8ff, 0xf7ff, 0x1100, 0xffff, 0x1500, 0x2a00, 0x1c00, 0x1800, 0x2200, 0x1500, 0x0800, 0x1d00, 0x1600, 0x0800, 0x1300,
-0x0500, 0xecff, 0x1100, 0x0a00, 0x1700, 0x0900, 0xffff, 0x2700, 0x1b00, 0x0b00, 0x1400, 0x1200, 0xecff, 0x1000, 0x1800, 0xdfff,
-0xfbff, 0xf1ff, 0x9bff, 0x90ff, 0x97ff, 0x81ff, 0xf2ff, 0xf9ff, 0x8cff, 0xcbff, 0x3300, 0x0200, 0x1300, 0x4f00, 0x1600, 0x2700,
-0x7400, 0x4000, 0x2a00, 0x4e00, 0x4b00, 0x1800, 0x2b00, 0x3900, 0x1c00, 0x2500, 0x1000, 0xf1ff, 0xf9ff, 0xf5ff, 0xdbff, 0xdbff,
-0x0000, 0x0b00, 0xd7ff, 0xcbff, 0xecff, 0xdfff, 0xebff, 0xe5ff, 0xafff, 0xdfff, 0xe5ff, 0xbeff, 0xc9ff, 0x0000, 0xe0ff, 0xcdff,
-0x1d00, 0x1b00, 0xefff, 0x1c00, 0x2100, 0x1100, 0x3200, 0x3400, 0x1d00, 0x2d00, 0x2600, 0x3b00, 0x3600, 0x4200, 0x0a00, 0x0000,
-0x5f00, 0x4000, 0x0000, 0x1000, 0x2800, 0xeaff, 0xd9ff, 0xcdff, 0xf8ff, 0x8400, 0xc1ff, 0xbefe, 0x56ff, 0x7fff, 0xe5fe, 0xf5ff,
-0x3600, 0x4aff, 0x24ff, 0x6800, 0xdf00, 0x1600, 0x6d00, 0x7b00, 0xf200, 0xd500, 0x0700, 0x2300, 0x3500, 0x0600, 0xeaff, 0xd1ff,
-0x95ff, 0xd5ff, 0x0300, 0xbcff, 0xe0ff, 0x0000, 0x2500, 0x3100, 0xdf00, 0x6700, 0x0300, 0x6900, 0x2a00, 0x3f00, 0x0400, 0x7dff,
-0x58ff, 0xb2ff, 0x7bff, 0x71ff, 0xa1ff, 0x7dff, 0xd0ff, 0x1700, 0x0000, 0x0700, 0x5900, 0x4b00, 0x4b00, 0x4700, 0xf8ff, 0x4300,
-0x5e00, 0x0d00, 0xdaff, 0x1300, 0x0e00, 0x0f00, 0x2d00, 0xeaff, 0x1400, 0x6200, 0x3a00, 0xe3ff, 0x0c00, 0x1600, 0xfbff, 0xe8ff,
-0xfbff, 0x6700, 0xe3ff, 0x8eff, 0xf2fe, 0x25fe, 0x9bfe, 0x54ff, 0x94ff, 0x94ff, 0x7dff, 0x3000, 0x9401, 0xce01, 0x5601, 0x0e01,
-0xd300, 0x4f01, 0xdf00, 0x6fff, 0x25ff, 0x79ff, 0x5eff, 0x51ff, 0xd4ff, 0xbaff, 0x1b00, 0xbe00, 0x4a00, 0xf3ff, 0x2800, 0x4500,
-0x5e00, 0x1800, 0x84ff, 0x8aff, 0xc7ff, 0xc2ff, 0x8aff, 0xd7fe, 0x16ff, 0x0000, 0x1300, 0xf7ff, 0xbcff, 0xc3ff, 0x5500, 0x7c00,
-0x5a00, 0x5400, 0x2d00, 0x2d00, 0x2b00, 0xf9ff, 0xfcff, 0x0500, 0xddff, 0x1d00, 0x6600, 0x7a00, 0x9200, 0x3700, 0x0e00, 0x5600,
-0x2500, 0xcfff, 0xfdff, 0xe3ff, 0xc5ff, 0xcdff, 0x00ff, 0x67ff, 0xb100, 0x3200, 0x3200, 0xc800, 0xcdff, 0xaaff, 0x4dff, 0x42fd,
-0xc4fd, 0x3500, 0x2a00, 0x99ff, 0x1d00, 0xe500, 0x4e02, 0xf802, 0x6f01, 0xd4ff, 0x4f00, 0x7300, 0x88ff, 0x20ff, 0x81fe, 0x9afe,
-0xb2ff, 0x6800, 0x9100, 0x9700, 0x3001, 0x5500, 0xf4ff, 0xa400, 0xb2ff, 0xdeff, 0x1500, 0x05ff, 0x4fff, 0xe6ff, 0xaaff, 0xc9ff,
-0x0000, 0xafff, 0xeeff, 0x8200, 0x1800, 0xc7ff, 0xf1ff, 0xd5ff, 0x3000, 0x1d00, 0x50ff, 0x89ff, 0x82ff, 0x7cff, 0x2000, 0x1d00,
-0x0d00, 0x9500, 0x8c00, 0x2d00, 0x5b00, 0x2200, 0xf8ff, 0x6700, 0x7800, 0x3e00, 0xa800, 0x9100, 0xbfff, 0xccff, 0xdaff, 0x9bff,
-0x8400, 0x98ff, 0xa4fe, 0xddff, 0x1200, 0x2e00, 0xf100, 0x3500, 0x73ff, 0x99ff, 0xd1fd, 0x97fd, 0x0500, 0x7800, 0x3400, 0xc700,
-0xfc00, 0x8201, 0x6002, 0x8201, 0xb5ff, 0xaeff, 0xa5ff, 0x15ff, 0x90ff, 0x53ff, 0xccfe, 0x8eff, 0x9d00, 0xef00, 0x0601, 0xf300,
-0xa4ff, 0x5cff, 0x0b00, 0xfcff, 0x0d00, 0xd9ff, 0x3cff, 0x60ff, 0x5400, 0x3400, 0x2b00, 0x4800, 0xbbff, 0x0300, 0x5a00, 0xf5ff,
-0xc7ff, 0xe5ff, 0x91ff, 0xfeff, 0x0000, 0x51ff, 0xa8ff, 0x57ff, 0x74ff, 0x3a00, 0x6500, 0x5400, 0x0e00, 0x2900, 0x3800, 0x3d00,
-0x3300, 0x1100, 0x4400, 0x7200, 0x5c00, 0x6f00, 0x4c00, 0xc8ff, 0xa6ff, 0xc4ff, 0x9bff, 0x6a00, 0x1000, 0xccfe, 0xc6ff, 0x7e00,
-0x8aff, 0x6b00, 0xae00, 0x7bff, 0x71ff, 0xa0fd, 0x05fd, 0xc5ff, 0x5001, 0x1801, 0x9a01, 0x3f01, 0x1701, 0xc102, 0xd901, 0x83ff,
-0x35ff, 0xa7fe, 0x52fe, 0x98ff, 0x9eff, 0xcbfe, 0x90ff, 0xe100, 0x4801, 0xa001, 0x5101, 0x59ff, 0x04ff, 0xc3ff, 0x1800, 0x4400,
-0xe7ff, 0x22ff, 0x1dff, 0x4000, 0x2c00, 0x4b00, 0x7800, 0xa3ff, 0xd9ff, 0x7b00, 0x1a00, 0xb7ff, 0xb4ff, 0x70ff, 0xb6ff, 0x2200,
-0xc9ff, 0x35ff, 0xaeff, 0x2b00, 0x4700, 0x5100, 0xe6ff, 0x1100, 0x5900, 0x0500, 0xf0ff, 0x2300, 0x5b00, 0xbd00, 0xec00, 0xc500,
-0x8200, 0x93ff, 0x39ff, 0xafff, 0xbfff, 0x5200, 0x9cff, 0x49fe, 0x7fff, 0xa600, 0xfcff, 0xaa00, 0x7000, 0xf8fe, 0x64fe, 0xf7fc,
-0x73fd, 0x2100, 0xa001, 0xe501, 0x4a02, 0x3701, 0xe500, 0x7402, 0x6601, 0xb5ff, 0x5eff, 0x69fe, 0x40fe, 0xc8ff, 0xe6ff, 0x1cff,
-0xd1ff, 0xc900, 0x6601, 0xdf01, 0xf300, 0x67ff, 0xdcfe, 0x50ff, 0x2500, 0x7400, 0x0900, 0x42ff, 0x32ff, 0xe2ff, 0x2e00, 0x8700,
-0x2800, 0x84ff, 0xd4ff, 0x5a00, 0x1000, 0xc1ff, 0xafff, 0x62ff, 0xa7ff, 0x2700, 0x1100, 0xc5ff, 0xe2ff, 0xeeff, 0xb8ff, 0x3200,
-0x8b00, 0x0d00, 0x2600, 0x7b00, 0xf4ff, 0x6dff, 0x3d00, 0x9600, 0x8800, 0x2201, 0xa500, 0xf1ff, 0xe7ff, 0x9fff, 0x70ff, 0xe9ff,
-0x3a00, 0x5fff, 0xe8fe, 0x52ff, 0x0f00, 0x8e00, 0xb300, 0x3800, 0x1aff, 0x77fe, 0x13fd, 0x9afc, 0x6dff, 0xe301, 0x5602, 0x9902,
-0x3b01, 0xa6ff, 0x1501, 0x1a02, 0xa300, 0xebff, 0x1aff, 0xe6fd, 0x09ff, 0x6700, 0x5800, 0xefff, 0x4500, 0xd100, 0x6601, 0x5301,
-0x5600, 0x0eff, 0x9dfe, 0x91ff, 0x2400, 0x8500, 0xd7ff, 0xeffe, 0x39ff, 0xddff, 0x8c00, 0xa500, 0x0c00, 0x86ff, 0xd0ff, 0x2f00,
-0x1200, 0xf1ff, 0xbfff, 0x88ff, 0xd1ff, 0x4900, 0x2100, 0xbcff, 0xb1ff, 0x9aff, 0xf1ff, 0x8300, 0x6400, 0x3b00, 0x3e00, 0x2400,
-0xa3ff, 0x0000, 0x8200, 0x4b00, 0xa800, 0xe600, 0x0300, 0x2cff, 0x82ff, 0x0b00, 0x4300, 0x5600, 0xa9ff, 0xcdfe, 0x15ff, 0x6700,
-0xed00, 0x8a00, 0xe3ff, 0x74fe, 0xe3fc, 0xd1fc, 0x98fe, 0x2601, 0x7b02, 0x8d02, 0x8001, 0x3f00, 0xd300, 0x9501, 0xfe00, 0xeeff,
-0x50ff, 0x67fe, 0x81fe, 0xe8ff, 0x4900, 0x1200, 0x6800, 0xc000, 0xc200, 0x0c01, 0xb100, 0x7bff, 0x2fff, 0x91ff, 0xd6ff, 0xfeff,
-0xfeff, 0x63ff, 0x35ff, 0x0700, 0x7100, 0x6600, 0x4400, 0xceff, 0x9cff, 0x1100, 0x4500, 0xdfff, 0xabff, 0x96ff, 0x96ff, 0x1000,
-0x5b00, 0x0f00, 0xc2ff, 0xe3ff, 0xfdff, 0x3a00, 0x9000, 0x4c00, 0x1400, 0xe6ff, 0xe2ff, 0xc0ff, 0xf3ff, 0x4300, 0x1a00, 0x5100,
-0x7300, 0x3100, 0xc2ff, 0xebff, 0x5a00, 0x1e00, 0xafff, 0x3aff, 0x3cff, 0x80ff, 0x5a00, 0xf500, 0xffff, 0x57ff, 0x39ff, 0xe8fd,
-0x65fd, 0x65ff, 0x7d01, 0xfb01, 0x5b02, 0x7501, 0x9aff, 0x6000, 0x7701, 0x6b00, 0x94ff, 0x31ff, 0xe2fd, 0x85fe, 0x9300, 0xab00,
-0x4900, 0x9300, 0x5900, 0x3b00, 0x0701, 0x9000, 0x47ff, 0x4eff, 0x6cff, 0xedff, 0x5c00, 0x0000, 0x33ff, 0x81ff, 0x6200, 0x7400,
-0x9b00, 0x3400, 0x67ff, 0x94ff, 0x3100, 0x2800, 0xfeff, 0xfdff, 0xa3ff, 0x9fff, 0x2100, 0x2400, 0xebff, 0xf5ff, 0xe4ff, 0xe0ff,
-0x3f00, 0x5100, 0x1600, 0x1a00, 0xe7ff, 0xe0ff, 0xd4ff, 0x0000, 0x1200, 0x0500, 0x5b00, 0xc200, 0x5000, 0xcbff, 0x3b00, 0xe5ff,
-0x9fff, 0xf0ff, 0xd4ff, 0x76ff, 0x40ff, 0x2200, 0x8c00, 0x0f00, 0x5700, 0x5fff, 0xdffc, 0xfbfc, 0xe8ff, 0xc501, 0xa202, 0xbc02,
-0x6300, 0x49ff, 0x0b01, 0x7001, 0x6f00, 0xe2ff, 0x72fe, 0x84fd, 0x7dff, 0xcc00, 0x7300, 0x7c00, 0x5e00, 0xf1ff, 0xa200, 0x2101,
-0xd4ff, 0x46ff, 0x5eff, 0x82ff, 0x4800, 0x7d00, 0xd2ff, 0x71ff, 0xe3ff, 0x1b00, 0x7b00, 0x5c00, 0xc4ff, 0x84ff, 0x76ff, 0xe5ff,
-0x2b00, 0x3500, 0x1500, 0xe2ff, 0x99ff, 0x73ff, 0x9bff, 0xc7ff, 0xc8ff, 0x0000, 0x2d00, 0x4100, 0x3400, 0x2600, 0xf1ff, 0xd6ff,
-0x0900, 0x1300, 0xe0ff, 0x5c00, 0xbc00, 0x4700, 0x2500, 0xd5ff, 0x5eff, 0xb5ff, 0x4800, 0x3200, 0x0a00, 0x5bff, 0x91ff, 0x9b00,
-0x7000, 0x6400, 0x0800, 0xa7fd, 0x41fc, 0x8dfe, 0x3c01, 0x0102, 0x4b03, 0x0002, 0x58ff, 0x8b00, 0xc401, 0xad00, 0x5c00, 0x7aff,
-0x8efd, 0x85fe, 0x5600, 0x4000, 0x5700, 0xd200, 0xa700, 0xd400, 0xbb01, 0x7500, 0x1bff, 0x11ff, 0x47ff, 0x0700, 0x7500, 0x3c00,
-0x67ff, 0x05ff, 0x91ff, 0x4300, 0x6700, 0x3300, 0x1200, 0x94ff, 0x8dff, 0x1e00, 0xd6ff, 0x98ff, 0xafff, 0x9bff, 0x55ff, 0x97ff,
-0xaeff, 0x86ff, 0xc1ff, 0x2f00, 0x5200, 0x7100, 0x7600, 0xfdff, 0x9fff, 0xc3ff, 0xe5ff, 0xd9ff, 0x1500, 0x7e00, 0x3c00, 0x8200,
-0x5900, 0x60ff, 0x8cff, 0x1e00, 0x3400, 0x4300, 0x3800, 0x1dff, 0xbffe, 0xd2ff, 0xcf00, 0xff00, 0x5c00, 0x36ff, 0xd4fd, 0x85fc,
-0x18fe, 0xa301, 0x2e02, 0xfc01, 0x9d02, 0xf400, 0x4400, 0xbf01, 0xea00, 0x40ff, 0x83ff, 0x05ff, 0x5afe, 0xc5ff, 0x5100, 0xa4ff,
-0x8f00, 0x8501, 0x2501, 0x2e01, 0xd300, 0x21ff, 0xe0fe, 0xd1ff, 0x0400, 0x5a00, 0xd2ff, 0x62ff, 0xcfff, 0xc0ff, 0xfbff, 0x2b00,
-0xf9ff, 0xd6ff, 0xf7ff, 0xfbff, 0xb7ff, 0xc6ff, 0x2eff, 0x52ff, 0x3900, 0x1500, 0xc2ff, 0xf0ff, 0xc6ff, 0xccff, 0x7f00, 0x9500,
-0x0200, 0x0b00, 0x0000, 0x98ff, 0xa3ff, 0xb9ff, 0xacff, 0x4600, 0x8a00, 0x9300, 0x1300, 0x94ff, 0xd4ff, 0x2a00, 0x1301, 0xce00,
-0x78ff, 0xa7fe, 0xa1fe, 0x76ff, 0xe200, 0xfe00, 0xecff, 0xadff, 0x6fff, 0xe4fd, 0x2afd, 0x51ff, 0x3f01, 0x8c01, 0x9202, 0xac01,
-0xf4ff, 0x0d01, 0x7601, 0x0800, 0xd5ff, 0xafff, 0x9cfe, 0x2dff, 0x2200, 0x85ff, 0xbdff, 0xd500, 0xc000, 0xd300, 0x2701, 0x0700,
-0x12ff, 0xb6ff, 0xf5ff, 0xebff, 0x7900, 0xc7ff, 0x4dff, 0x5c00, 0x9800, 0xf9ff, 0xa4ff, 0xa4ff, 0x6bff, 0xafff, 0x2a00, 0xceff,
-0xc2ff, 0xc6ff, 0xb9ff, 0x3600, 0x5a00, 0xdbff, 0xa1ff, 0xe1ff, 0x1500, 0x3e00, 0x5d00, 0x0400, 0xccff, 0x2000, 0x1900, 0xa7ff,
-0x77ff, 0x9dff, 0xfdff, 0x4a00, 0xcd00, 0x0300, 0x8bff, 0x0000, 0xf0ff, 0xa100, 0xbf00, 0xdaff, 0x04ff, 0x2aff, 0x76ff, 0xe1ff,
-0x8b00, 0x8100, 0x3700, 0x4700, 0x2fff, 0x1ffd, 0xd7fd, 0x6a00, 0x6c01, 0x9301, 0x9c01, 0x5900, 0x3c00, 0x9f01, 0x6201, 0xbfff,
-0x28ff, 0x69ff, 0x63ff, 0xf5ff, 0x0a00, 0x2cff, 0x91ff, 0x9e00, 0x1c01, 0x0d01, 0x7900, 0xa9ff, 0x3aff, 0x2b00, 0x3500, 0xc4ff,
-0xc5ff, 0x77ff, 0xb8ff, 0x9600, 0xaa00, 0xd4ff, 0x97ff, 0xdfff, 0xc3ff, 0x1a00, 0xf9ff, 0x65ff, 0x81ff, 0xa7ff, 0xd0ff, 0x2a00,
-0x0600, 0x0800, 0x2d00, 0xebff, 0x2000, 0x6d00, 0x6a00, 0x5900, 0x5700, 0x0c00, 0x85ff, 0x9bff, 0xe4ff, 0x0400, 0x4000, 0xd7ff,
-0x0f00, 0x1f00, 0xf2ff, 0xb800, 0x6c00, 0xacff, 0x59ff, 0x2eff, 0x5fff, 0x1f00, 0x5200, 0x1f00, 0x2700, 0x3e00, 0xcdfe, 0x09fd,
-0x87fd, 0x2300, 0x0802, 0x8401, 0x2f01, 0x7c00, 0x9c00, 0x0302, 0xb301, 0x8fff, 0xc2fe, 0x25ff, 0x0000, 0x6e00, 0xabff, 0xedfe,
-0x54ff, 0xa800, 0xa301, 0x4801, 0x1900, 0x8eff, 0xf2ff, 0x7000, 0x6c00, 0xc6ff, 0x02ff, 0x34ff, 0x0000, 0x6c00, 0x4f00, 0x55ff,
-0x65ff, 0x3c00, 0x4d00, 0x1d00, 0x81ff, 0x49ff, 0xaaff, 0x2300, 0x1600, 0xaaff, 0x92ff, 0xb7ff, 0x7100, 0x4900, 0xf8ff, 0x4900,
-0x5700, 0x9f00, 0xa100, 0x5b00, 0xb6ff, 0x8bff, 0x0700, 0x3300, 0x3e00, 0xa2ff, 0x99ff, 0x2e00, 0x1200, 0x9500, 0x9200, 0xceff,
-0x99ff, 0xa9ff, 0x77ff, 0x5fff, 0xc7ff, 0x1c00, 0x1b00, 0x5400, 0x9fff, 0xd8fd, 0xe8fc, 0xaefe, 0x7301, 0x8a01, 0xd700, 0x6b00,
-0x6600, 0xfa01, 0x9d02, 0x5e00, 0xddfe, 0x75ff, 0x1f00, 0x8500, 0x6dff, 0x3ffe, 0xc4fe, 0x7200, 0x5401, 0xe600, 0x2900, 0xd8ff,
-0x6900, 0xe800, 0x9400, 0xd8ff, 0x45ff, 0x6aff, 0xedff, 0xf4ff, 0xf3ff, 0x8cff, 0x7aff, 0x1e00, 0x3a00, 0xfcff, 0xc7ff, 0xbbff,
-0xd1ff, 0x1300, 0x1c00, 0xc1ff, 0xbfff, 0xd6ff, 0x1300, 0x5100, 0xf7ff, 0x77ff, 0xe4ff, 0x9000, 0xa400, 0x9a00, 0x5300, 0xacff,
-0xa5ff, 0x3a00, 0x3800, 0x0000, 0xe2ff, 0xe3ff, 0x4300, 0xc400, 0x5e00, 0x90ff, 0xb4ff, 0x3a00, 0xf6ff, 0x8eff, 0x86ff, 0xcbfe,
-0x49ff, 0xe400, 0x7f00, 0x5cff, 0x80fe, 0x61fd, 0x78fe, 0xf601, 0x4001, 0xabff, 0xc500, 0xe000, 0xf201, 0x0c03, 0x7e00, 0x6ffe,
-0xceff, 0x7100, 0xd0ff, 0x6dff, 0x5cfe, 0x4afe, 0x5800, 0x6d01, 0x0e00, 0xc7ff, 0x2e00, 0x2a00, 0xc800, 0xe500, 0x89ff, 0x3cff,
-0x5900, 0x1a00, 0xcfff, 0x0b00, 0x71ff, 0x87ff, 0x7000, 0x3100, 0x95ff, 0xe1ff, 0x0000, 0xe9ff, 0x4700, 0x0300, 0x7aff, 0xf1ff,
-0x3700, 0xc9ff, 0xfcff, 0x0000, 0xd0ff, 0x6800, 0x9500, 0xdfff, 0xfaff, 0xe7ff, 0xe9ff, 0x9600, 0x1700, 0xbbff, 0x0b00, 0x5300,
-0x9000, 0x9c00, 0x1900, 0x97ff, 0xd7ff, 0x6100, 0x2400, 0xbdfe, 0xe0fe, 0xb0ff, 0xb0ff, 0x6400, 0x5500, 0x0dff, 0xdafe, 0x38fe,
-0xe1fd, 0x6200, 0x3801, 0xeaff, 0xe200, 0xf901, 0xd901, 0x4802, 0x8001, 0x25ff, 0xd7ff, 0xfa00, 0x7bff, 0xc8fe, 0xe4fe, 0x76fe,
-0xb4ff, 0xa800, 0xd5ff, 0xa7ff, 0x4d00, 0x6d00, 0x6e00, 0xb600, 0xe3ff, 0xc3ff, 0x6600, 0x1b00, 0xa3ff, 0xc0ff, 0xbaff, 0x90ff,
-0x0a00, 0x1c00, 0x99ff, 0x0900, 0x5000, 0xd6ff, 0x0e00, 0x7400, 0x1f00, 0xf5ff, 0x0d00, 0xc3ff, 0xe6ff, 0x4400, 0xebff, 0x9dff,
-0xdfff, 0x5a00, 0x1c00, 0x80ff, 0xd4ff, 0x1f00, 0x1200, 0x4e00, 0x6f00, 0xd900, 0x7d00, 0x9aff, 0xdbff, 0x4000, 0x2300, 0xd1ff,
-0xa3ff, 0x89ff, 0x74ff, 0xbdff, 0xb5ff, 0xe8ff, 0x4900, 0x0b00, 0xc6ff, 0x5aff, 0x6dfe, 0xc6fe, 0x3400, 0x6700, 0x2300, 0x9500,
-0xa300, 0x2901, 0x0a02, 0xf200, 0x7fff, 0x3800, 0x7e00, 0xedff, 0xb8ff, 0x0fff, 0xeafe, 0xdeff, 0x4500, 0xdcff, 0xcaff, 0x0d00,
-0x3d00, 0x7b00, 0x7c00, 0xffff, 0xf5ff, 0x2600, 0x1500, 0xe2ff, 0xd8ff, 0xc6ff, 0xb8ff, 0xf7ff, 0xf6ff, 0xd4ff, 0xf7ff, 0x1300,
-0xf7ff, 0x0800, 0xf3ff, 0xbbff, 0xb5ff, 0xfcff, 0xcaff, 0xc4ff, 0xfcff, 0xd2ff, 0xfeff, 0x2500, 0x2000, 0x0400, 0x0000, 0x0200,
-0x1000, 0x1e00, 0x1900, 0x2a00, 0x1600, 0x2e00, 0x5500, 0x1b00, 0x1f00, 0x1200, 0x2600, 0x6600, 0x3700, 0xfbff, 0x2200, 0x1300,
-0xffff, 0xfbff, 0xcaff, 0x97ff, 0x9eff, 0x95ff, 0x9aff, 0xceff, 0xa2ff, 0x6fff, 0xabff, 0x0000, 0x2400, 0x0c00, 0xf2ff, 0x0f00,
-0x6100, 0x7500, 0x4200, 0xfeff, 0x1c00, 0x5a00, 0x4a00, 0x2300, 0x0b00, 0x0f00, 0x0900, 0x1900, 0xfcff, 0xe0ff, 0xfdff, 0x1200,
-0x1100, 0x1200, 0x1700, 0x1800, 0x1500, 0x1500, 0x0500, 0xf7ff, 0xf9ff, 0x0800, 0xffff, 0x0300, 0x0000, 0xccff, 0xdaff, 0x0200,
-0xe5ff, 0xa7ff, 0x9cff, 0xb4ff, 0xd0ff, 0xcaff, 0xdbff, 0xc9ff, 0xd3ff, 0x0a00, 0x0500, 0x0600, 0x1500, 0x1400, 0x2d00, 0x5900,
-0x3000, 0x0900, 0x1300, 0x0800, 0x2000, 0x3600, 0x0500, 0x0000, 0xf6ff, 0x0700, 0x1900, 0xf5ff, 0x1000, 0x1300, 0xcdff, 0xbdff,
-0xd7ff, 0xe0ff, 0xd6ff, 0xe6ff, 0xbfff, 0xdfff, 0x3500, 0x1700, 0x0000, 0x2900, 0x4c00, 0x4600, 0x4500, 0x4a00, 0x2100, 0x3c00,
-0x4000, 0x0a00, 0xeeff, 0xedff, 0xe6ff, 0xe1ff, 0xe0ff, 0xeeff, 0x0100, 0x0a00, 0x1300, 0x0900, 0x0500, 0x0c00, 0x0600, 0xf2ff,
-0xecff, 0xe1ff, 0xe3ff, 0xe2ff, 0xe6ff, 0xe6ff, 0xf8ff, 0x0500, 0x0200, 0x0800, 0xe2ff, 0xdfff, 0x0000, 0x0300, 0xffff, 0x0000,
-0x1200, 0x1300, 0x0600, 0x0c00, 0xfcff, 0x1200, 0x1000, 0xfcff, 0x0800, 0x0900, 0xfbff, 0xf6ff, 0xfeff, 0xfbff, 0xfeff, 0xf1ff,
-0xfbff, 0x0400, 0x0600, 0x1700, 0x2500, 0x0e00, 0xdbff, 0xb8ff, 0xc9ff, 0xcfff, 0xb2ff, 0xbeff, 0xcdff, 0xc7ff, 0xe2ff, 0x0500,
-0x2400, 0x1600, 0x2300, 0x3900, 0x4c00, 0x5400, 0x4200, 0x3a00, 0x3100, 0x3e00, 0x2e00, 0x0800, 0xf6ff, 0xf2ff, 0xf7ff, 0xfaff,
-0xf7ff, 0xf3ff, 0x0600, 0x0f00, 0x0300, 0xffff, 0xf9ff, 0xe6ff, 0x0a00, 0x1f00, 0x0a00, 0x0300, 0xf8ff, 0xecff, 0xf2ff, 0xfdff,
-0xccff, 0xbbff, 0xe5ff, 0xe6ff, 0xb3ff, 0xc7ff, 0x0000, 0xfaff, 0xf2ff, 0x0d00, 0x1000, 0x0e00, 0x2300, 0x1c00, 0x0f00, 0x1c00,
-0x1700, 0x0b00, 0x1000, 0x0c00, 0x0400, 0x0100, 0x0200, 0x0300, 0x0000, 0xfdff, 0x0300, 0x0500, 0x0700, 0x0a00, 0x0600, 0x0400,
-0x0100, 0xf5ff, 0xecff, 0xf2ff, 0xf5ff, 0xecff, 0x0200, 0xfdff, 0xe0ff, 0x0800, 0x1b00, 0x0300, 0x0000, 0x0700, 0x0500, 0x0400,
-0x0100, 0xf0ff, 0xefff, 0x0100, 0xfcff, 0xfaff, 0x0700, 0x0600, 0x0e00, 0x1500, 0x0800, 0x0500, 0x0d00, 0x1100, 0x0800, 0x0a00,
-0x0600, 0xf8ff, 0xfdff, 0x0400, 0x2200, 0x2800, 0x1500, 0x0f00, 0x1800, 0x0e00, 0xfcff, 0xf9ff, 0xefff, 0xe5ff, 0xc5ff, 0xb4ff,
-0xc3ff, 0xcfff, 0xcbff, 0xcdff, 0xe4ff, 0xf7ff, 0x0300, 0x1300, 0xffff, 0xf8ff, 0x0e00, 0x0900, 0xfeff, 0xfeff, 0xfeff, 0xfbff,
-0x0300, 0x0a00, 0x0a00, 0x0f00, 0x1100, 0x0d00, 0x0800, 0x0e00, 0x1600, 0x0d00, 0x0900, 0x0900, 0x0100, 0x0200, 0x0000, 0xebff,
-0xfbff, 0x0200, 0xdeff, 0xf8ff, 0x0c00, 0xf8ff, 0xefff, 0x0100, 0x0000, 0x0200, 0x0500, 0x0f00, 0x1900, 0x2400, 0x2d00, 0x1b00,
-0x1500, 0x1b00, 0x1e00, 0x1200, 0x0100, 0x0000, 0xfeff, 0x0200, 0x0400, 0xfeff, 0xfaff, 0x0200, 0x0b00, 0x1d00, 0x2e00, 0x0100,
-0xf7ff, 0x0d00, 0x0300, 0xf7ff, 0xfbff, 0xf5ff, 0xeaff, 0xe8ff, 0xc9ff, 0xccff, 0xe2ff, 0xe2ff, 0xdeff, 0xe5ff, 0xf0ff, 0xfaff,
-0x0900, 0x0700, 0xe8ff, 0xedff, 0x0300, 0xfdff, 0xf3ff, 0xf8ff, 0x0e00, 0x0b00, 0x1800, 0x1200, 0x0100, 0x0f00, 0x1300, 0x1100,
-0x0e00, 0x1700, 0x1500, 0x0800, 0x0500, 0xf1ff, 0xe5ff, 0xe3ff, 0xd9ff, 0xceff, 0xc6ff, 0xbeff, 0xe5ff, 0xf2ff, 0xebff, 0xf1ff,
-0x0200, 0xffff, 0x0900, 0x1000, 0x1000, 0x1300, 0x2a00, 0x3700, 0x2c00, 0x3000, 0x3000, 0x2300, 0x2100, 0x2500, 0x1d00, 0x1700,
-0x1b00, 0x1800, 0x1800, 0x1900, 0x0f00, 0x0a00, 0x1300, 0x1e00, 0x1600, 0x0f00, 0xffff, 0x0200, 0xf2ff, 0xe3ff, 0xdfff, 0xdbff,
-0xd5ff, 0xc2ff, 0xb8ff, 0xb3ff, 0xbaff, 0xc4ff, 0xc9ff, 0xd1ff, 0xe4ff, 0xfcff, 0xfbff, 0xfeff, 0x0c00, 0x0c00, 0x1300, 0x2200,
-0x2300, 0x2100, 0x2b00, 0x3700, 0x2c00, 0x2d00, 0x2d00, 0x2300, 0x2800, 0x2300, 0x1300, 0x1800, 0x1000, 0xedff, 0xe1ff, 0xd6ff,
-0xbcff, 0xb8ff, 0xb3ff, 0x98ff, 0x9bff, 0xb7ff, 0xcfff, 0xd6ff, 0xe5ff, 0xecff, 0xf5ff, 0x0000, 0x0600, 0x1600, 0x1100, 0x1a00,
-0x3100, 0x3700, 0x3800, 0x3700, 0x3b00, 0x3900, 0x3700, 0x3200, 0x3400, 0x3600, 0x2e00, 0x2800, 0x2700, 0x1e00, 0x1800, 0x1800,
-0x1000, 0x1400, 0x0900, 0xfcff, 0xf7ff, 0xf1ff, 0xe4ff, 0xd7ff, 0xd7ff, 0xd2ff, 0xc1ff, 0xc1ff, 0xc8ff, 0xc3ff, 0xc5ff, 0xd6ff,
-0xddff, 0xdfff, 0xf0ff, 0x0000, 0x0300, 0x0300, 0x0900, 0x0a00, 0x1700, 0x2200, 0x1700, 0x2000, 0x3100, 0x3200, 0x3300, 0x2e00,
-0x2800, 0x1d00, 0x2600, 0x2200, 0x1800, 0x1300, 0x0200, 0xf0ff, 0xd3ff, 0xc8ff, 0xc0ff, 0xbbff, 0xbbff, 0xb4ff, 0xaaff, 0xbaff,
-0xd7ff, 0xe9ff, 0xf2ff, 0xfcff, 0x0500, 0x1000, 0x1900, 0x1a00, 0x2100, 0x1b00, 0x1d00, 0x2a00, 0x1d00, 0x1000, 0x0b00, 0x0c00,
-0x0b00, 0x0600, 0x0100, 0x0400, 0x0900, 0x0900, 0x0600, 0x0500, 0x0800, 0x0f00, 0x1100, 0xfcff, 0x0900, 0x0c00, 0x0400, 0x0500,
-0x0000, 0xf8ff, 0xf3ff, 0xf7ff, 0xefff, 0xe7ff, 0xeeff, 0xf1ff, 0xf2ff, 0xf5ff, 0xfbff, 0xfdff, 0xffff, 0x0000, 0x0100, 0x0000,
-0xfeff, 0xffff, 0x0000, 0x0000, 0x0100, 0xffff, 0x0000, 0x0400, 0x0500, 0x0200, 0xffff, 0x0000, 0xfeff, 0xfcff, 0xfbff, 0xf7ff,
-0xf3ff, 0xf1ff, 0xf6ff, 0xf1ff, 0xf4ff, 0xf7ff, 0xfaff, 0xfeff, 0x0700, 0x0e00, 0x1300, 0x1e00, 0x2000, 0x2200, 0x2000, 0x2200,
-0x1d00, 0x1c00, 0x1d00, 0x1b00, 0x1600, 0x1b00, 0x1900, 0x1200, 0x0d00, 0x0a00, 0x0500, 0x0000, 0xebff, 0xddff, 0xe1ff, 0xe0ff,
-0xddff, 0xdcff, 0xdeff, 0xdeff, 0xe6ff, 0xebff, 0xeeff, 0xf4ff, 0xffff, 0x0100, 0x0a00, 0x0b00, 0x0100, 0x0600, 0x1600, 0x0e00,
-0x0a00, 0x1100, 0x1500, 0x1000, 0x1000, 0x0d00, 0x0b00, 0x0900, 0x0500, 0xfbff, 0xffff, 0x0200, 0x0000, 0x0100, 0x0100, 0x0200,
-0xfbff, 0x0000, 0xfaff, 0xf4ff, 0xedff, 0xedff, 0xe9ff, 0xe4ff, 0xe2ff, 0xdeff, 0xdbff, 0xe0ff, 0xe0ff, 0xe3ff, 0xe9ff, 0xf3ff,
-0xf7ff, 0x0700, 0x0b00, 0x0000, 0x0f00, 0x1b00, 0x1700, 0x1600, 0x2100, 0x2600, 0x2700, 0x2e00, 0x2600, 0x2300, 0x2000, 0x1800,
-0x0e00, 0x0b00, 0x0200, 0x0300, 0xf3ff, 0xe2ff, 0xe0ff, 0xe0ff, 0xe1ff, 0xdeff, 0xe3ff, 0xe4ff, 0xf2ff, 0xf1ff, 0xfcff, 0xf9ff,
-0xf8ff, 0x0000, 0x0300, 0x0900, 0x0a00, 0x0e00, 0x0300, 0x0600, 0x0400, 0x0400, 0x0100, 0x0200, 0x0000, 0x0000, 0xffff, 0xfcff,
-0x0100, 0x0100, 0x0300, 0x0400, 0x0800, 0x0500, 0x0500, 0x0000, 0xfaff, 0xffff, 0x0100, 0xfcff, 0xfeff, 0x0000, 0xfcff, 0xf6ff,
-0xf5ff, 0xf3ff, 0xf3ff, 0xf0ff, 0xf7ff, 0xfcff, 0x0100, 0x0e00, 0x1800, 0x1900, 0x1d00, 0x2800, 0x2400, 0x2000, 0x2400, 0x2000,
-0x1400, 0x0d00, 0x0000, 0xf9ff, 0xeeff, 0xe7ff, 0xe6ff, 0xe3ff, 0xe0ff, 0xdbff, 0xe6ff, 0xeeff, 0xf4ff, 0xfdff, 0xfeff, 0xffff,
-0x0000, 0x0400, 0x0000, 0x0500, 0x0500, 0x0900, 0x0500, 0x0600, 0x0c00, 0x0d00, 0x1200, 0x0c00, 0x0d00, 0x0a00, 0x0d00, 0x0b00,
-0x0500, 0x0100, 0x0100, 0xfeff, 0xfdff, 0xfaff, 0xfaff, 0xfaff, 0xfbff, 0xf9ff, 0xf8ff, 0xf8ff, 0xf7ff, 0xf8ff, 0xf6ff, 0xf3ff,
-0xf8ff, 0xf6ff, 0xf4ff, 0xf2ff, 0xf1ff, 0xefff, 0xf5ff, 0xf3ff, 0xf6ff, 0xfcff, 0xfdff, 0xfcff, 0xffff, 0x0100, 0x0000, 0x0000,
-0x0400, 0x1000, 0x1000, 0x1300, 0x1700, 0x1e00, 0x1400, 0x1200, 0x1400, 0x0e00, 0x1400, 0x1100, 0x0600, 0xfbff, 0xf3ff, 0xe9ff,
-0xebff, 0xe8ff, 0xe2ff, 0xe7ff, 0xebff, 0xf1ff, 0xf5ff, 0xfeff, 0x0100, 0xffff, 0xfaff, 0xfdff, 0xfeff, 0xfeff, 0xfeff, 0xffff,
-0x0900, 0x0c00, 0x1100, 0x1400, 0x1100, 0x1200, 0x0d00, 0x0b00, 0x0f00, 0x0f00, 0x0a00, 0x0600, 0xfeff, 0x0000, 0xfeff, 0xf9ff,
-0xfcff, 0xfaff, 0xf8ff, 0xfbff, 0xfeff, 0xf9ff, 0xfcff, 0xf7ff, 0xfbff, 0xf5ff, 0xfcff, 0x0900, 0x0000, 0x0a00, 0x0600, 0xfeff,
-0xfbff, 0x1700, 0x1000, 0x0800, 0x1100, 0x0800, 0xf2ff, 0x0400, 0x0300, 0x0000, 0x1d00, 0x1b00, 0x0b00, 0xf1ff, 0xd8ff, 0xddff,
-0xeeff, 0xdfff, 0xd0ff, 0xf0ff, 0xf3ff, 0xf4ff, 0x0300, 0x1000, 0xf9ff, 0xf3ff, 0x1000, 0x1e00, 0x0e00, 0xfdff, 0xfaff, 0xfdff,
-0x1100, 0xfeff, 0x1d00, 0x3100, 0x0300, 0xf8ff, 0x0c00, 0x1700, 0x1300, 0x0200, 0xfdff, 0x0900, 0x0800, 0xf8ff, 0xf9ff, 0xfaff,
-0xf3ff, 0x0400, 0xfcff, 0xf5ff, 0x0100, 0xfaff, 0xe3ff, 0xe4ff, 0xf8ff, 0x0000, 0x0300, 0xf1ff, 0xe1ff, 0x0000, 0xf7ff, 0xf4ff,
-0xefff, 0xdfff, 0x0900, 0x1600, 0xe0ff, 0xf5ff, 0x1500, 0x0900, 0xfdff, 0x0300, 0x1200, 0x1900, 0xffff, 0x0e00, 0x3e00, 0x3400,
-0xe3ff, 0xfbff, 0x2c00, 0xfdff, 0xe5ff, 0x0300, 0x0800, 0x0200, 0xe5ff, 0xe0ff, 0x0900, 0x1500, 0xdeff, 0xe1ff, 0xf8ff, 0xe0ff,
-0xddff, 0x1500, 0x1f00, 0xecff, 0x0c00, 0x6aff, 0x0700, 0x2600, 0xecfe, 0xac01, 0x8500, 0xa9fe, 0xa200, 0x6700, 0xb8ff, 0x8f00,
-0xf9ff, 0xa1ff, 0xd100, 0xc1fe, 0x8900, 0x4a01, 0x6dfe, 0xf9ff, 0x1301, 0xb1ff, 0xbaff, 0xac00, 0x1401, 0x7bfe, 0x16ff, 0x8e01,
-0x92ff, 0x03ff, 0x7202, 0xedff, 0x58fe, 0x6b00, 0x0300, 0xc6ff, 0x5600, 0xadff, 0xd5ff, 0xe800, 0x85ff, 0x16ff, 0xd000, 0x2600,
-0xacff, 0x3f00, 0x47fe, 0x6000, 0x3b02, 0xc1fe, 0x56fe, 0x3001, 0xc2ff, 0xfffe, 0xf4ff, 0x2400, 0x5000, 0x1f00, 0x38ff, 0x0200,
-0x6800, 0xc800, 0x45ff, 0xb1ff, 0xeb00, 0x0100, 0xaaff, 0x0f00, 0x7f00, 0x2400, 0x8d00, 0xa5ff, 0x0600, 0xa501, 0xa5ff, 0x67ff,
-0xb700, 0x0e00, 0xa6ff, 0xe1ff, 0x0c00, 0xf4ff, 0xf1ff, 0x29ff, 0x0cff, 0xb1ff, 0x2fff, 0xfffe, 0xe0ff, 0x1900, 0xe1ff, 0x1600,
-0x5b00, 0x6200, 0x7d00, 0x1f00, 0x1300, 0x6100, 0x4500, 0xf3ff, 0xb400, 0x7800, 0x5d00, 0x1600, 0x4500, 0x4700, 0x1200, 0x0a00,
-0xd5ff, 0x5a00, 0x3400, 0xf4ff, 0x3600, 0xbeff, 0xe1ff, 0x0300, 0xb6ff, 0xa5ff, 0xc2ff, 0x98ff, 0xc5ff, 0x2100, 0xdbff, 0x2d00,
-0x1400, 0xd4ff, 0x2e00, 0x0a00, 0xfaff, 0x0a00, 0x0300, 0xd9ff, 0xc3ff, 0x6600, 0x1d00, 0x80ff, 0x0700, 0x2300, 0x0eff, 0xacff,
-0x0500, 0xacff, 0x1400, 0x4600, 0x5000, 0x6400, 0xad00, 0x4900, 0x2c00, 0x7900, 0x3000, 0xc7ff, 0xbbff, 0x8cff, 0xa3ff, 0x5800,
-0xcfff, 0xddfe, 0x8fff, 0xc3ff, 0x78fe, 0x51ff, 0xceff, 0x62ff, 0x2b00, 0xbd00, 0x7300, 0xe000, 0x7901, 0x8900, 0x6e00, 0xf000,
-0x5100, 0xd5ff, 0xcfff, 0xacff, 0xe1ff, 0xc400, 0x71ff, 0xbffd, 0xacff, 0xfdff, 0x5dfe, 0x43ff, 0xa000, 0x9b00, 0xab00, 0x1f01,
-0x0b01, 0x7e01, 0x1f01, 0xddff, 0xfcff, 0x3200, 0x3fff, 0x16ff, 0x1500, 0xc7ff, 0xddfe, 0x64ff, 0xe6fe, 0x4efe, 0x26ff, 0x4dff,
-0x30ff, 0x2800, 0x2401, 0xe300, 0x6301, 0xdf01, 0xa801, 0xb001, 0x5701, 0xc500, 0x8100, 0x3600, 0xa7ff, 0xd6ff, 0x6100, 0x0eff,
-0x82fe, 0x9eff, 0xa8ff, 0x03ff, 0x97ff, 0x7300, 0x8200, 0x6600, 0x6000, 0x6700, 0x7c00, 0xdeff, 0x2fff, 0x57ff, 0x83ff, 0x26ff,
-0xf3fe, 0x37ff, 0x49ff, 0xe6fe, 0x04ff, 0x66ff, 0x8dff, 0xa6ff, 0x0100, 0x8300, 0xbc00, 0xf200, 0x2501, 0x6301, 0x6601, 0x2b01,
-0xed00, 0xbe00, 0x6400, 0x2400, 0x2f00, 0x0d00, 0xe0ff, 0xe5ff, 0xbeff, 0xc4ff, 0x0e00, 0x0600, 0xebff, 0xfbff, 0xd1ff, 0xa5ff,
-0x7eff, 0x48ff, 0x2dff, 0x35ff, 0x19ff, 0x62ff, 0x30ff, 0x40ff, 0xbfff, 0x6fff, 0x7eff, 0x0600, 0xe4ff, 0xbaff, 0x4000, 0xae00,
-0x8f00, 0x8500, 0xab00, 0xd500, 0xa900, 0x5800, 0x4d00, 0x4a00, 0x1f00, 0xe3ff, 0xd5ff, 0x0500, 0x0e00, 0x5eff, 0xbfff, 0x9500 };
diff --git a/1.4/codecs/slin_ulaw_ex.h b/1.4/codecs/slin_ulaw_ex.h
deleted file mode 100644
index 9af79eba2..000000000
--- a/1.4/codecs/slin_ulaw_ex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*! \file
- * \brief slin_ulaw_ex.h --
- *
- * Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
- *
- * Source: g723.example
- *
- * Copyright (C) 2001-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static signed short slin_ulaw_ex[] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
diff --git a/1.4/codecs/speex_slin_ex.h b/1.4/codecs/speex_slin_ex.h
deleted file mode 100644
index 404743799..000000000
--- a/1.4/codecs/speex_slin_ex.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*! \file
- * \brief Random Data data
- *
- * Source: speex.raw
- *
- * Copyright (C) 1999-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char speex_slin_ex[] = {
-0x2e, 0x8e, 0x0f, 0x9a, 0x20, 0000, 0x01, 0x7f, 0xff, 0xff,
-0xff, 0xff, 0xff, 0x91, 0000, 0xbf, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xdc, 0x80, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0x98, 0x7f, 0xff, 0xff, 0xff, 0xe8, 0xff, 0xf7, 0x80 };
diff --git a/1.4/codecs/ulaw_slin_ex.h b/1.4/codecs/ulaw_slin_ex.h
deleted file mode 100644
index 9f0417a6b..000000000
--- a/1.4/codecs/ulaw_slin_ex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*! \file
- * \brief ulaw_slin_ex.h --
- *
- * 4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
- *
- * Source: g723.example
- *
- * Copyright (C) 2001-2005, Digium Inc.
- *
- * Distributed under the terms of the GNU General Public License
- *
- */
-
-static unsigned char ulaw_slin_ex[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/1.4/config.guess b/1.4/config.guess
deleted file mode 100755
index 22906b339..000000000
--- a/1.4/config.guess
+++ /dev/null
@@ -1,1495 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
-
-timestamp='2006-03-13'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerppc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- i*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- x86:Interix*:[345]*)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- EM64T:Interix*:[345]*)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-gnu
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
-and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/1.4/config.sub b/1.4/config.sub
deleted file mode 100755
index 5705e543b..000000000
--- a/1.4/config.sub
+++ /dev/null
@@ -1,1609 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
-
-timestamp='2006-03-07'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64vr | mips64vrel \
- | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | mt \
- | msp430 \
- | nios | nios2 \
- | ns16k | ns32k \
- | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
- | we32k \
- | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m32c)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nios-* | nios2-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tron-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
- | ymp-* \
- | z8k-*)
- ;;
- m32c-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16c)
- basic_machine=cr16c-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -kaos*)
- os=-kaos
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/1.4/configs/adsi.conf.sample b/1.4/configs/adsi.conf.sample
deleted file mode 100644
index 0f36f80da..000000000
--- a/1.4/configs/adsi.conf.sample
+++ /dev/null
@@ -1,8 +0,0 @@
-;
-; Sample ADSI Configuration file
-;
-[intro]
-alignment = center
-greeting => Welcome to the
-greeting => Asterisk
-greeting => Open Source PBX
diff --git a/1.4/configs/adtranvofr.conf.sample b/1.4/configs/adtranvofr.conf.sample
deleted file mode 100644
index dc7bcfc7c..000000000
--- a/1.4/configs/adtranvofr.conf.sample
+++ /dev/null
@@ -1,39 +0,0 @@
-;
-; Voice over Frame Relay (Adtran style)
-;
-; Configuration file
-
-[interfaces]
-;
-; Default language
-;
-;language=en
-;
-; Lines for which we are the user termination. They accept incoming
-; and outgoing calls. We use the default context on the first 8 lines
-; used by internal phones.
-;
-context=default
-;user => voice00
-;user => voice01
-;user => voice02
-;user => voice03
-;user => voice04
-;user => voice05
-;user => voice06
-;user => voice07
-; Calls on 16 and 17 come from the outside world, so they get
-; a little bit special treatment
-context=remote
-;user => voice16
-;user => voice17
-;
-; Next we have lines which we only accept calls on, and typically
-; do not send outgoing calls on (i.e. these are where we are the
-; network termination)
-;
-;network => voice08
-;network => voice09
-;network => voice10
-;network => voice11
-;network => voice12
diff --git a/1.4/configs/agents.conf.sample b/1.4/configs/agents.conf.sample
deleted file mode 100644
index eb0383f3c..000000000
--- a/1.4/configs/agents.conf.sample
+++ /dev/null
@@ -1,105 +0,0 @@
-;
-; Agent configuration
-;
-
-[general]
-;
-; Define whether callbacklogins should be stored in astdb for
-; persistence. Persistent logins will be reloaded after
-; Asterisk restarts.
-;
-persistentagents=yes
-
-; Enable or disable a single extension from logging in as multiple agents.
-; The default value is "yes".
-;multiplelogin=yes
-
-[agents]
-;
-; Define maxlogintries to allow agent to try max logins before
-; failed.
-; default to 3
-;
-;maxlogintries=5
-;
-;
-; Define autologoff times if appropriate. This is how long
-; the phone has to ring with no answer before the agent is
-; automatically logged off (in seconds)
-;
-;autologoff=15
-;
-; Define autologoffunavail to have agents automatically logged
-; out when the extension that they are at returns a CHANUNAVAIL
-; status when a call is attempted to be sent there.
-; Default is "no".
-;
-;autologoffunavail=yes
-;
-; Define ackcall to require an acknowledgement by '#' when
-; an agent logs in using agentcallbacklogin. Default is "no".
-;
-;ackcall=no
-;
-; Define endcall to allow an agent to hangup a call by '*'.
-; Default is "yes". Set this to "no" to ignore '*'.
-;
-;endcall=yes
-;
-; Define wrapuptime. This is the minimum amount of time when
-; after disconnecting before the caller can receive a new call
-; note this is in milliseconds.
-;
-;wrapuptime=5000
-;
-; Define the default musiconhold for agents
-; musiconhold => music_class
-;
-;musiconhold => default
-;
-; Define the default good bye sound file for agents
-; default to vm-goodbye
-;
-;agentgoodbye => goodbye_file
-;
-; Define updatecdr. This is whether or not to change the source
-; channel in the CDR record for this call to agent/agent_id so
-; that we know which agent generates the call
-;
-;updatecdr=no
-;
-; Group memberships for agents (may change in mid-file)
-;
-;group=3
-;group=1,2
-;group=
-;
-; --------------------------------------------------
-; This section is devoted to recording agent's calls
-; The keywords are global to the chan_agent channel driver
-;
-; Enable recording calls addressed to agents. It's turned off by default.
-;recordagentcalls=yes
-;
-; The format to be used to record the calls: wav, gsm, wav49.
-; By default its "wav".
-;recordformat=gsm
-;
-; The text to be added to the name of the recording. Allows forming a url link.
-;urlprefix=http://localhost/calls/
-;
-; The optional directory to save the conversations in. The default is
-; /var/spool/asterisk/monitor
-;savecallsin=/var/calls
-;
-; An optional custom beep sound file to play to always-connected agents.
-;custom_beep=beep
-;
-; --------------------------------------------------
-;
-; This section contains the agent definitions, in the form:
-;
-; agent => agentid,agentpassword,name
-;
-;agent => 1001,4321,Mark Spencer
-;agent => 1002,4321,Will Meadows
diff --git a/1.4/configs/alarmreceiver.conf.sample b/1.4/configs/alarmreceiver.conf.sample
deleted file mode 100644
index bf767dea3..000000000
--- a/1.4/configs/alarmreceiver.conf.sample
+++ /dev/null
@@ -1,80 +0,0 @@
-;
-; alarmreceiver.conf
-;
-; Sample configuration file for the Asterisk alarm receiver application.
-;
-
-
-[general]
-
-;
-; Specify a timestamp format for the metadata section of the event files
-; Default is %a %b %d, %Y @ %H:%M:%S %Z
-
-timestampformat = %a %b %d, %Y @ %H:%M:%S %Z
-
-;
-; Specify a command to execute when the caller hangs up
-;
-; Default is none
-;
-
-;eventcmd = yourprogram -yourargs ...
-
-;
-; Specify a spool directory for the event files. This setting is required
-; if you want the app to be useful. Event files written to the spool
-; directory will be of the template event-XXXXXX, where XXXXXX is a random
-; and unique alphanumeric string.
-;
-; Default is none, and the events will be dropped on the floor.
-;
-
-eventspooldir = /tmp
-
-;
-; The alarmreceiver app can either log the events one-at-a-time to individual
-; files in the spool directory, or it can store them until the caller
-; disconnects and write them all to one file.
-;
-; The default setting for logindividualevents is no.
-;
-
-logindividualevents = no
-
-;
-; The timeout for receiving the first DTMF digit is adjustable from 1000 msec.
-; to 10000 msec. The default is 2000 msec. Note: if you wish to test the
-; receiver by entering digits manually, set this to a reasonable time out
-; like 10000 milliseconds.
-
-fdtimeout = 2000
-
-;
-; The timeout for receiving subsequent DTMF digits is adjustable from
-; 110 msec. to 4000 msec. The default is 200 msec. Note: if you wish to test
-; the receiver by entering digits manually, set this to a reasonable time out
-; like 4000 milliseconds.
-;
-
-sdtimeout = 200
-
-;
-; The loudness of the ACK and Kissoff tones is adjustable from 100 to 8192.
-; The default is 8192. This shouldn't need to be messed with, but is included
-; just in case there are problems with signal levels.
-;
-
-loudness = 8192
-
-;
-; The db-family setting allows the user to capture statistics on the number of
-; calls, and the errors the alarm receiver sees. The default is for no
-; db-family name to be defined and the database logging to be turned off.
-;
-
-;db-family = yourfamily:
-
-;
-; End of alarmreceiver.conf
-;
diff --git a/1.4/configs/alsa.conf.sample b/1.4/configs/alsa.conf.sample
deleted file mode 100644
index f55030618..000000000
--- a/1.4/configs/alsa.conf.sample
+++ /dev/null
@@ -1,62 +0,0 @@
-;
-; Open Sound System Console Driver Configuration File
-;
-[general]
-;
-; Automatically answer incoming calls on the console? Choose yes if
-; for example you want to use this as an intercom.
-;
-autoanswer=yes
-;
-; Default context (is overridden with @context syntax)
-;
-context=local
-;
-; Default extension to call
-;
-extension=s
-;
-; Default language
-;
-;language=en
-;
-; Default Music on Hold class to use when this channel is placed on hold in
-; the case that the music class is not set on the channel with
-; Set(CHANNEL(musicclass)=whatever) in the dialplan and the peer channel
-; putting this one on hold did not suggest a class to use.
-;
-;mohinterpret=default
-;
-; Silence suppression can be enabled when sound is over a certain threshold.
-; The value for the threshold should probably be between 500 and 2000 or so,
-; but your mileage may vary. Use the echo test to evaluate the best setting.
-;silencesuppression = yes
-;silencethreshold = 1000
-;
-; To set which ALSA device to use, change this parameter
-;input_device=hw:0,0
-;output_device=hw:0,0
-
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
-; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
- ; ALSA channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The ALSA channel can't accept jitter,
- ; thus an enabled jitterbuffer on the receive ALSA side will always
- ; be used if the sending side can create jitter.
-
-; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
-; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usually sent from exotic devices
- ; and programs. Defaults to 1000.
-
-; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
- ; channel. Two implementations are currently available - "fixed"
- ; (with size always equals to jbmax-size) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
-; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
-
diff --git a/1.4/configs/amd.conf.sample b/1.4/configs/amd.conf.sample
deleted file mode 100644
index ce4808a0c..000000000
--- a/1.4/configs/amd.conf.sample
+++ /dev/null
@@ -1,18 +0,0 @@
-;
-; Answering Machine Detection Configuration
-;
-
-[general]
-initial_silence = 2500 ; Maximum silence duration before the greeting.
- ; If exceeded then MACHINE.
-greeting = 1500 ; Maximum length of a greeting. If exceeded then MACHINE.
-after_greeting_silence = 800 ; Silence after detecting a greeting.
- ; If exceeded then HUMAN
-total_analysis_time = 5000 ; Maximum time allowed for the algorithm to decide
- ; on a HUMAN or MACHINE
-min_word_length = 100 ; Minimum duration of Voice to considered as a word
-between_words_silence = 50 ; Minimum duration of silence after a word to consider
- ; the audio what follows as a new word
-maximum_number_of_words = 3 ; Maximum number of words in the greeting.
- ; If exceeded then MACHINE
-silence_threshold = 256
diff --git a/1.4/configs/asterisk.adsi b/1.4/configs/asterisk.adsi
deleted file mode 100644
index a275502ac..000000000
--- a/1.4/configs/asterisk.adsi
+++ /dev/null
@@ -1,159 +0,0 @@
-;
-; Asterisk default ADSI script
-;
-;
-; Begin with the preamble requirements
-;
-DESCRIPTION "Asterisk PBX" ; Name of vendor
-VERSION 0x00 ; Version of stuff
-;SECURITY "_AST" ; Security code
-SECURITY 0X9BDBF7AC ; Security code
-FDN 0x0000000F ; Descriptor number
-
-;
-; Flags
-;
-FLAG "nocallwaiting"
-
-;
-; Predefined strings
-;
-DISPLAY "titles" IS "** Asterisk PBX **"
-DISPLAY "talkingto" IS "Call active." JUSTIFY LEFT
-DISPLAY "callname" IS "$Call1p" JUSTIFY LEFT
-DISPLAY "callnum" IS "$Call1s" JUSTIFY LEFT
-DISPLAY "incoming" IS "Incoming call!" JUSTIFY LEFT
-DISPLAY "ringing" IS "Calling... " JUSTIFY LEFT
-DISPLAY "callended" IS "Call ended." JUSTIFY LEFT
-DISPLAY "missedcall" IS "Missed call." JUSTIFY LEFT
-DISPLAY "busy" IS "Busy." JUSTIFY LEFT
-DISPLAY "reorder" IS "Reorder." JUSTIFY LEFT
-DISPLAY "cwdisabled" IS "Callwait disabled"
-DISPLAY "empty" IS "asdf"
-
-;
-; Begin soft key definitions
-;
-KEY "callfwd" IS "CallFwd" OR "Call Forward"
- OFFHOOK
- VOICEMODE
- WAITDIALTONE
- SENDDTMF "*60"
- GOTO "offHook"
-ENDKEY
-
-KEY "vmail_OH" IS "VMail" OR "Voicemail"
- OFFHOOK
- VOICEMODE
- WAITDIALTONE
- SENDDTMF "8500"
-ENDKEY
-
-KEY "vmail" IS "VMail" OR "Voicemail"
- SENDDTMF "8500"
-ENDKEY
-
-KEY "backspace" IS "BackSpc" OR "Backspace"
- BACKSPACE
-ENDKEY
-
-KEY "cwdisable" IS "CWDsble" OR "Disable Call Wait"
- SENDDTMF "*70"
- SETFLAG "nocallwaiting"
- SHOWDISPLAY "cwdisabled" AT 4
- TIMERCLEAR
- TIMERSTART 1
-ENDKEY
-
-KEY "cidblock" IS "CIDBlk" OR "Block Callerid"
- SENDDTMF "*67"
- SETFLAG "nocallwaiting"
-ENDKEY
-
-;
-; Begin main subroutine
-;
-
-SUB "main" IS
- IFEVENT NEARANSWER THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1 NOUPDATE
- SHOWDISPLAY "talkingto" AT 2 NOUPDATE
- SHOWDISPLAY "callname" AT 3
- SHOWDISPLAY "callnum" AT 4
- GOTO "stableCall"
- ENDIF
- IFEVENT OFFHOOK THEN
- CLEAR
- CLEARFLAG "nocallwaiting"
- CLEARDISPLAY
- SHOWDISPLAY "titles" AT 1
- SHOWKEYS "vmail"
- SHOWKEYS "cidblock"
- SHOWKEYS "cwdisable" UNLESS "nocallwaiting"
- GOTO "offHook"
- ENDIF
- IFEVENT IDLE THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1
- SHOWKEYS "vmail_OH"
- ENDIF
- IFEVENT CALLERID THEN
- CLEAR
-; SHOWDISPLAY "titles" AT 1 NOUPDATE
-; SHOWDISPLAY "incoming" AT 2 NOUPDATE
- SHOWDISPLAY "callname" AT 3 NOUPDATE
- SHOWDISPLAY "callnum" AT 4
- ENDIF
- IFEVENT RING THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1 NOUPDATE
- SHOWDISPLAY "incoming" AT 2
- ENDIF
- IFEVENT ENDOFRING THEN
- SHOWDISPLAY "missedcall" AT 2
- CLEAR
- SHOWDISPLAY "titles" AT 1
- SHOWKEYS "vmail_OH"
- ENDIF
- IFEVENT TIMER THEN
- CLEAR
- SHOWDISPLAY "empty" AT 4
- ENDIF
-ENDSUB
-
-SUB "offHook" IS
- IFEVENT FARRING THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1 NOUPDATE
- SHOWDISPLAY "ringing" AT 2 NOUPDATE
- SHOWDISPLAY "callname" at 3 NOUPDATE
- SHOWDISPLAY "callnum" at 4
- ENDIF
- IFEVENT FARANSWER THEN
- CLEAR
- SHOWDISPLAY "talkingto" AT 2
- GOTO "stableCall"
- ENDIF
- IFEVENT BUSY THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1 NOUPDATE
- SHOWDISPLAY "busy" AT 2 NOUPDATE
- SHOWDISPLAY "callname" at 3 NOUPDATE
- SHOWDISPLAY "callnum" at 4
- ENDIF
- IFEVENT REORDER THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1 NOUPDATE
- SHOWDISPLAY "reorder" AT 2 NOUPDATE
- SHOWDISPLAY "callname" at 3 NOUPDATE
- SHOWDISPLAY "callnum" at 4
- ENDIF
-ENDSUB
-
-SUB "stableCall" IS
- IFEVENT REORDER THEN
- SHOWDISPLAY "callended" AT 2
- ENDIF
-ENDSUB
-
diff --git a/1.4/configs/cdr.conf.sample b/1.4/configs/cdr.conf.sample
deleted file mode 100644
index 693b28092..000000000
--- a/1.4/configs/cdr.conf.sample
+++ /dev/null
@@ -1,148 +0,0 @@
-;
-; Asterisk Call Detail Record engine configuration
-;
-; CDR is Call Detail Record, which provides logging services via a variety of
-; pluggable backend modules. Detailed call information can be recorded to
-; databases, files, etc. Useful for billing, fraud prevention, compliance with
-; Sarbanes-Oxley aka The Enron Act, QOS evaluations, and more.
-;
-
-[general]
-
-; Define whether or not to use CDR logging. Setting this to "no" will override
-; any loading of backend CDR modules. Default is "yes".
-;enable=yes
-
-; Define whether or not to log unanswered calls. Setting this to "yes" will
-; report every attempt to ring a phone in dialing attempts, when it was not
-; answered. For example, if you try to dial 3 extensions, and this option is "yes",
-; you will get 3 CDR's, one for each phone that was rung. Default is "no". Some
-; find this information horribly useless. Others find it very valuable. Note, in "yes"
-; mode, you will see one CDR, with one of the call targets on one side, and the originating
-; channel on the other, and then one CDR for each channel attempted. This may seem
-; redundant, but cannot be helped.
-;unanswered = no
-
-; Define the CDR batch mode, where instead of posting the CDR at the end of
-; every call, the data will be stored in a buffer to help alleviate load on the
-; asterisk server. Default is "no".
-;
-; WARNING WARNING WARNING
-; Use of batch mode may result in data loss after unsafe asterisk termination
-; ie. software crash, power failure, kill -9, etc.
-; WARNING WARNING WARNING
-;
-;batch=no
-
-; Define the maximum number of CDRs to accumulate in the buffer before posting
-; them to the backend engines. 'batch' must be set to 'yes'. Default is 100.
-;size=100
-
-; Define the maximum time to accumulate CDRs in the buffer before posting them
-; to the backend engines. If this time limit is reached, then it will post the
-; records, regardless of the value defined for 'size'. 'batch' must be set to
-; 'yes'. Note that time is in seconds. Default is 300 (5 minutes).
-;time=300
-
-; The CDR engine uses the internal asterisk scheduler to determine when to post
-; records. Posting can either occur inside the scheduler thread, or a new
-; thread can be spawned for the submission of every batch. For small batches,
-; it might be acceptable to just use the scheduler thread, so set this to "yes".
-; For large batches, say anything over size=10, a new thread is recommended, so
-; set this to "no". Default is "no".
-;scheduleronly=no
-
-; When shutting down asterisk, you can block until the CDRs are submitted. If
-; you don't, then data will likely be lost. You can always check the size of
-; the CDR batch buffer with the CLI "cdr status" command. To enable blocking on
-; submission of CDR data during asterisk shutdown, set this to "yes". Default
-; is "yes".
-;safeshutdown=yes
-
-; Normally, CDR's are not closed out until after all extensions are finished
-; executing. By enabling this option, the CDR will be ended before executing
-; the "h" extension so that CDR values such as "end" and "billsec" may be
-; retrieved inside of of this extension.
-;endbeforehexten=no
-
-;
-;
-; CHOOSING A CDR "BACKEND" (what kind of output to generate)
-;
-; To choose a backend, you have to make sure either the right category is
-; defined in this file, or that the appropriate config file exists, and has the
-; proper definitions in it. If there are any problems, usually, the entry will
-; silently ignored, and you get no output.
-;
-; Also, please note that you can generate CDR records in as many formats as you
-; wish. If you configure 5 different CDR formats, then each event will be logged
-; in 5 different places! In the example config files, all formats are commented
-; out except for the cdr-csv format.
-;
-; Here are all the possible back ends:
-;
-; csv, custom, manager, odbc, pgsql, radius, sqlite, tds
-; (also, mysql is available via the asterisk-addons, due to licensing
-; requirements)
-; (please note, also, that other backends can be created, by creating
-; a new backend module in the source cdr/ directory!)
-;
-; Some of the modules required to provide these backends will not build or install
-; unless some dependency requirements are met. Examples of this are pgsql, odbc,
-; etc. If you are not getting output as you would expect, the first thing to do
-; is to run the command "make menuselect", and check what modules are available,
-; by looking in the "2. Call Detail Recording" option in the main menu. If your
-; backend is marked with XXX, you know that the "configure" command could not find
-; the required libraries for that option.
-;
-; To get CDRs to be logged to the plain-jane /var/log/asterisk/cdr-csv/Master.csv
-; file, define the [csv] category in this file. No database necessary. The example
-; config files are set up to provide this kind of output by default.
-;
-; To get custom csv CDR records, make sure the cdr_custom.conf file
-; is present, and contains the proper [mappings] section. The advantage to
-; using this backend, is that you can define which fields to output, and in
-; what order. By default, the example configs are set up to mimic the cdr-csv
-; output. If you don't make any changes to the mappings, you are basically generating
-; the same thing as cdr-csv, but expending more CPU cycles to do so!
-;
-; To get manager events generated, make sure the cdr_manager.conf file exists,
-; and the [general] section is defined, with the single variable 'enabled = yes'.
-;
-; For odbc, make sure all the proper libs are installed, that "make menuselect"
-; shows that the modules are available, and the cdr_odbc.conf file exists, and
-; has a [global] section with the proper variables defined.
-;
-; For pgsql, make sure all the proper libs are installed, that "make menuselect"
-; shows that the modules are available, and the cdr_pgsql.conf file exists, and
-; has a [global] section with the proper variables defined.
-;
-; For logging to radius databases, make sure all the proper libs are installed, that
-; "make menuselect" shows that the modules are available, and the [radius]
-; category is defined in this file, and in that section, make sure the 'radiuscfg'
-; variable is properly pointing to an existing radiusclient.conf file.
-;
-; For logging to sqlite databases, make sure the 'cdr.db' file exists in the log directory,
-; which is usually /var/log/asterisk. Of course, the proper libraries should be available
-; during the 'configure' operation.
-;
-; For tds logging, make sure the proper libraries are available during the 'configure'
-; phase, and that cdr_tds.conf exists and is properly set up with a [global] category.
-;
-; Also, remember, that if you wish to log CDR info to a database, you will have to define
-; a specific table in that databse to make things work! See the doc directory for more details
-; on how to create this table in each database.
-;
-
-[csv]
-usegmtime=yes ; log date/time in GMT. Default is "no"
-loguniqueid=yes ; log uniqueid. Default is "no"
-loguserfield=yes ; log user field. Default is "no"
-
-;[radius]
-;usegmtime=yes ; log date/time in GMT
-;loguniqueid=yes ; log uniqueid
-;loguserfield=yes ; log user field
-; Set this to the location of the radiusclient-ng configuration file
-; The default is /etc/radiusclient-ng/radiusclient.conf
-;radiuscfg => /usr/local/etc/radiusclient-ng/radiusclient.conf
diff --git a/1.4/configs/cdr_custom.conf.sample b/1.4/configs/cdr_custom.conf.sample
deleted file mode 100644
index 8bc2cb34e..000000000
--- a/1.4/configs/cdr_custom.conf.sample
+++ /dev/null
@@ -1,10 +0,0 @@
-;
-; Mappings for custom config file
-;
-; to get your csv output in a format tailored to your liking, uncomment the following
-; and look for the output in the cdr-custom/Master.csv file (usually in /var/log/asterisk).
-;
-;
-;[mappings]
-;Master.csv => "${CDR(clid)}","${CDR(src)}","${CDR(dst)}","${CDR(dcontext)}","${CDR(channel)}","${CDR(dstchannel)}","${CDR(lastapp)}","${CDR(lastdata)}","${CDR(start)}","${CDR(answer)}","${CDR(end)}","${CDR(duration)}","${CDR(billsec)}","${CDR(disposition)}","${CDR(amaflags)}","${CDR(accountcode)}","${CDR(uniqueid)}","${CDR(userfield)}"
-
diff --git a/1.4/configs/cdr_manager.conf.sample b/1.4/configs/cdr_manager.conf.sample
deleted file mode 100644
index 1d7984ba4..000000000
--- a/1.4/configs/cdr_manager.conf.sample
+++ /dev/null
@@ -1,6 +0,0 @@
-;
-; Asterisk Call Management CDR
-;
-[general]
-enabled = no
-
diff --git a/1.4/configs/cdr_odbc.conf.sample b/1.4/configs/cdr_odbc.conf.sample
deleted file mode 100644
index 6245e37eb..000000000
--- a/1.4/configs/cdr_odbc.conf.sample
+++ /dev/null
@@ -1,12 +0,0 @@
-;
-; cdr_odbc.conf
-;
-
-;[global]
-;dsn=MySQL-test
-;username=username
-;password=password
-;loguniqueid=yes
-;dispositionstring=yes
-;table=cdr ;"cdr" is default table name
-;usegmtime=no ; set to "yes" to log in GMT
diff --git a/1.4/configs/cdr_pgsql.conf.sample b/1.4/configs/cdr_pgsql.conf.sample
deleted file mode 100644
index 0784c7b08..000000000
--- a/1.4/configs/cdr_pgsql.conf.sample
+++ /dev/null
@@ -1,9 +0,0 @@
-; Sample Asterisk config file for CDR logging to PostgresSQL
-
-[global]
-;hostname=localhost
-;port=5432
-;dbname=asterisk
-;password=password
-;user=postgres
-;table=cdr ;SQL table where CDRs will be inserted
diff --git a/1.4/configs/cdr_tds.conf.sample b/1.4/configs/cdr_tds.conf.sample
deleted file mode 100644
index d8c7d075c..000000000
--- a/1.4/configs/cdr_tds.conf.sample
+++ /dev/null
@@ -1,11 +0,0 @@
-; Sample Asterisk config file for CDR logging to FreeTDS
-
-;[global]
-;hostname=fs.malico.loc
-;port=1433
-;dbname=MalicoHN
-;user=mangUsr
-;password=
-;charset=BIG5
-;table=cdr
-
diff --git a/1.4/configs/codecs.conf.sample b/1.4/configs/codecs.conf.sample
deleted file mode 100644
index c8caeab60..000000000
--- a/1.4/configs/codecs.conf.sample
+++ /dev/null
@@ -1,65 +0,0 @@
-[speex]
-; CBR encoding quality [0..10]
-; used only when vbr = false
-quality => 3
-
-; codec complexity [0..10]
-; tradeoff between cpu/quality
-complexity => 2
-
-; perceptual enhancement [true / false]
-; improves clarity of decoded speech
-enhancement => true
-
-; voice activity detection [true / false]
-; reduces bitrate when no voice detected, used only for CBR
-; (implicit in VBR/ABR)
-vad => true
-
-; variable bit rate [true / false]
-; uses bit rate proportionate to voice complexity
-vbr => true
-
-; available bit rate [bps, 0 = off]
-; encoding quality modulated to match this target bit rate
-; not recommended with dtx or pp_vad - may cause bandwidth spikes
-abr => 0
-
-; VBR encoding quality [0-10]
-; floating-point values allowed
-vbr_quality => 4
-
-; discontinuous transmission [true / false]
-; stops transmitting completely when silence is detected
-; pp_vad is far more effective but more CPU intensive
-dtx => false
-
-; preprocessor configuration
-; these options only affect Speex v1.1.8 or newer
-
-; enable preprocessor [true / false]
-; allows dsp functionality below but incurs CPU overhead
-preprocess => false
-
-; preproc voice activity detection [true / false]
-; more advanced equivalent of DTX, based on voice frequencies
-pp_vad => false
-
-; preproc automatic gain control [true / false]
-pp_agc => false
-pp_agc_level => 8000
-
-; preproc denoiser [true / false]
-pp_denoise => false
-
-; preproc dereverb [true / false]
-pp_dereverb => false
-pp_dereverb_decay => 0.4
-pp_dereverb_level => 0.3
-
-
-[plc]
-; for all codecs which do not support native PLC
-; this determines whether to perform generic PLC
-; there is a minor performance penalty for this
-genericplc => true
diff --git a/1.4/configs/dnsmgr.conf.sample b/1.4/configs/dnsmgr.conf.sample
deleted file mode 100644
index e34dbcf0a..000000000
--- a/1.4/configs/dnsmgr.conf.sample
+++ /dev/null
@@ -1,5 +0,0 @@
-[general]
-;enable=yes ; enable creation of managed DNS lookups
- ; default is 'no'
-;refreshinterval=1200 ; refresh managed DNS lookups every <n> seconds
- ; default is 300 (5 minutes) \ No newline at end of file
diff --git a/1.4/configs/dundi.conf.sample b/1.4/configs/dundi.conf.sample
deleted file mode 100644
index a1e999726..000000000
--- a/1.4/configs/dundi.conf.sample
+++ /dev/null
@@ -1,239 +0,0 @@
-;
-; DUNDi configuration file
-;
-; For more information about DUNDi, see http://www.dundi.com
-;
-;
-[general]
-;
-; The "general" section contains general parameters relating
-; to the operation of the dundi client and server.
-;
-; The first part should be your complete contact information
-; should someone else in your peer group need to contact you.
-;
-;department=Your Department
-;organization=Your Company, Inc.
-;locality=Your City
-;stateprov=ST
-;country=US
-;email=your@email.com
-;phone=+12565551212
-;
-;
-; Specify bind address and port number. Default is
-; 4520
-;
-;bindaddr=0.0.0.0
-;port=4520
-;
-; Our entity identifier (Should generally be the MAC address of the
-; machine it's running on. Defaults to the first eth address, but you
-; can override it here, as long as you set it to the MAC of *something*
-; you own!)
-;
-;entityid=00:07:E9:3B:76:60
-;
-; Peers shall cache our query responses for the specified time,
-; given in seconds. Default is 3600.
-;
-;cachetime=3600
-;
-; This defines the max depth in which to search the DUNDi system.
-; Note that the maximum time that we will wait for a response is
-; (2000 + 200 * ttl) ms.
-;
-ttl=32
-;
-; If we don't get ACK to our DPDISCOVER within 2000ms, and autokill is set
-; to yes, then we cancel the whole thing (that's enough time for one
-; retransmission only). This is used to keep things from stalling for a long
-; time for a host that is not available, but would be ill advised for bad
-; connections. In addition to 'yes' or 'no' you can also specify a number
-; of milliseconds. See 'qualify' for individual peers to turn on for just
-; a specific peer.
-;
-autokill=yes
-;
-; pbx_dundi creates a rotating key called "secret", under the family
-; 'secretpath'. The default family is dundi (resulting in
-; the key being held at dundi/secret).
-;
-;secretpath=dundi
-;
-; The 'storehistory' option (also changeable at runtime with
-; 'dundi store history' and 'dundi no store history') will
-; cause the DUNDi engine to keep track of the last several
-; queries and the amount of time each query took to execute
-; for the purpose of tracking slow nodes. This option is
-; off by default due to performance impacts.
-;
-;storehistory=yes
-
-[mappings]
-;
-; The "mappings" section maps DUNDi contexts
-; to contexts on the local asterisk system. Remember
-; that numbers that are made available under the e164
-; DUNDi context are regulated by the DUNDi General Peering
-; Agreement (GPA) if you are a member of the DUNDi E.164
-; Peering System.
-;
-; dundi_context => local_context,weight,tech,dest[,options]]
-;
-; 'dundi_context' is the name of the context being requested
-; within the DUNDi request
-;
-; 'local_context' is the name of the context on the local system
-; in which numbers can be looked up for which responses shall be given.
-;
-; 'weight' is the weight to use for the responses provided from this
-; mapping. The number must be >= 0 and < 60000. Since it is totally
-; valid to receive multiple responses to a query, responses received
-; with a lower weight are tried first. Note that the weight has a
-; special meaning in the e164 context - see the GPA for more details.
-;
-; 'tech' is the technology to use (IAX, SIP, H323)
-;
-; 'dest' is the destination to supply for reaching that number. The
-; following variables can be used in the destination string and will
-; be automatically substituted:
-; ${NUMBER}: The number being requested
-; ${IPADDR}: The IP address to connect to
-; ${SECRET}: The current rotating secret key to be used
-;
-; Further options may include:
-;
-; nounsolicited: No unsolicited calls of any type permitted via this
-; route
-; nocomunsolicit: No commercial unsolicited calls permitted via
-; this route
-; residential: This number is known to be a residence
-; commercial: This number is known to be a business
-; mobile: This number is known to be a mobile phone
-; nocomunsolicit: No commercial unsolicited calls permitted via
-; this route
-; nopartial: Do not search for partial matches
-;
-; There *must* exist an entry in mappings for DUNDi to respond
-; to any request, although it may be empty.
-;
-;e164 => dundi-e164-canonical,0,IAX2,dundi:${SECRET}@${IPADDR}/${NUMBER},nounsolicited,nocomunsolicit,nopartial
-;e164 => dundi-e164-customers,100,IAX2,dundi:${SECRET}@${IPADDR}/${NUMBER},nounsolicited,nocomunsolicit,nopartial
-;e164 => dundi-e164-via-pstn,400,IAX2,dundi:${SECRET}@${IPADDR}/${NUMBER},nounsolicited,nocomunsolicit,nopartial
-
-;digexten => default,0,IAX2,guest@lappy/${NUMBER}
-;asdf =>
-
-
-;
-;
-; The remaining sections represent the peers
-; that we fundamentally trust. The section name
-; represents the name and optionally at a specific
-; DUNDi context if you want the trust to be established
-; for only a specific DUNDi context.
-;
-; inkey - What key they will be authenticating to us with
-;
-; outkey - What key we use to authenticate to them
-;
-; host - What their host is
-;
-; order - What search order to use. May be 'primary', 'secondary',
-; 'tertiary' or 'quartiary'. In large systems, it is beneficial
-; to only query one up-stream host in order to maximize caching
-; value. Adding one with primary and one with secondary gives you
-; redundancy without sacrificing performance.
-;
-; include - Includes this peer when searching a particular context
-; for lookup (set "all" to perform all lookups with that
-; host. This is also the context in which peers are permitted
-; to precache.
-;
-; noinclude - Disincludes this peer when searching a particular context
-; for lookup (set "all" to perform no lookups with that
-; host.
-;
-; permit - Permits this peer to search a given DUNDi context on
-; the local system. Set "all" to permit this host to
-; lookup all contexts. This is also a context for which
-; we will create/forward PRECACHE commands.
-;
-; deny - Denies this peer to search a given DUNDi context on
-; the local system. Set "all" to deny this host to
-; lookup all contexts.
-;
-; model - inbound, outbound, or symmetric for whether we receive
-; requests only, transmit requests only, or do both.
-;
-; precache - Utilize/Permit precaching with this peer (to pre
-; cache means to provide an answer when no request
-; was made and is used so that machines with few
-; routes can push those routes up a to a higher level).
-; outgoing means we send precache routes to this peer,
-; incoming means we permit this peer to send us
-; precache routes. symmetric means we do both.
-;
-; Note: You cannot mix symmetric/outbound model with symmetric/inbound
-; precache, nor can you mix symmetric/inbound model with symmetric/outbound
-; precache.
-;
-;
-; The '*' peer is special and matches an unspecified entity
-;
-
-;
-; Sample Primary e164 DUNDi peer
-;
-;[00:50:8B:F3:75:BB]
-;model = symmetric
-;host = 64.215.96.114
-;inkey = digium
-;outkey = misery
-;include = e164
-;permit = e164
-;qualify = yes
-
-;
-; Sample Secondary e164 DUNDi peer
-;
-;[00:A0:C9:96:92:84]
-;model = symmetric
-;host = misery.digium.com
-;inkey = misery
-;outkey = ourkey
-;include = e164
-;permit = e164
-;qualify = yes
-;order = secondary
-
-;
-; Sample "push mode" downstream host
-;
-;[00:0C:76:96:75:28]
-;model = inbound
-;host = dynamic
-;precache = inbound
-;inkey = littleguy
-;outkey = ourkey
-;include = e164 ; In this case used only for precaching
-;permit = e164
-;qualify = yes
-
-;
-; Sample "push mode" upstream host
-;
-;[00:07:E9:3B:76:60]
-;model = outbound
-;precache = outbound
-;host = 216.207.245.34
-;register = yes
-;inkey = dhcp34
-;permit = all ; In this case used only for precaching
-;include = all
-;qualify = yes
-;outkey=foo
-
-;[*]
-;
diff --git a/1.4/configs/enum.conf.sample b/1.4/configs/enum.conf.sample
deleted file mode 100644
index 39c723175..000000000
--- a/1.4/configs/enum.conf.sample
+++ /dev/null
@@ -1,22 +0,0 @@
-;
-; ENUM Configuration for resolving phone numbers over DNS
-;
-; Sample config for Asterisk
-; This file is reloaded at "module reload enum" in the CLI
-;
-[general]
-;
-; The search list for domains may be customized. Domains are searched
-; in the order they are listed here.
-;
-search => e164.arpa
-;
-; If you'd like to use the E.164.org public ENUM registry in addition
-; to the official e164.arpa one, uncomment the following line
-;
-;search => e164.org
-;
-; As there are more H323 drivers available you have to select to which
-; drive a H323 URI will map. Default is "H323".
-;
-h323driver => H323
diff --git a/1.4/configs/extconfig.conf.sample b/1.4/configs/extconfig.conf.sample
deleted file mode 100644
index d2c5fbbb2..000000000
--- a/1.4/configs/extconfig.conf.sample
+++ /dev/null
@@ -1,58 +0,0 @@
-;
-; Static and realtime external configuration
-; engine configuration
-;
-; Please read doc/extconfig.txt for basic table
-; formatting information.
-;
-[settings]
-;
-; Static configuration files:
-;
-; file.conf => driver,database[,table]
-;
-; maps a particular configuration file to the given
-; database driver, database and table (or uses the
-; name of the file as the table if not specified)
-;
-;uncomment to load queues.conf via the odbc engine.
-;
-;queues.conf => odbc,asterisk,ast_config
-;
-; The following files CANNOT be loaded from Realtime storage:
-; asterisk.conf
-; extconfig.conf (this file)
-; logger.conf
-;
-; Additionally, the following files cannot be loaded from
-; Realtime storage unless the storage driver is loaded
-; early using 'preload' statements in modules.conf:
-; manager.conf
-; cdr.conf
-; rtp.conf
-;
-;
-; Realtime configuration engine
-;
-; maps a particular family of realtime
-; configuration to a given database driver,
-; database and table (or uses the name of
-; the family if the table is not specified
-;
-;example => odbc,asterisk,alttable
-;
-; "odbc" is shown in the examples below, but is not the only valid realtime
-; engine. There is:
-; odbc ... res_config_odbc
-; pgsql ... res_config_pgsql
-; mysql ... res_config_mysql (available from asterisk-addons)
-;
-;iaxusers => odbc,asterisk
-;iaxpeers => odbc,asterisk
-;sipusers => odbc,asterisk
-;sippeers => odbc,asterisk
-;voicemail => odbc,asterisk
-;extensions => odbc,asterisk
-;queues => odbc,asterisk
-;queue_members => odbc,asterisk
-
diff --git a/1.4/configs/extensions.ael.sample b/1.4/configs/extensions.ael.sample
deleted file mode 100644
index 89436dc21..000000000
--- a/1.4/configs/extensions.ael.sample
+++ /dev/null
@@ -1,448 +0,0 @@
-//
-// Example AEL config file
-//
-//
-// Static extension configuration file, used by
-// the pbx_ael module. This is where you configure all your
-// inbound and outbound calls in Asterisk.
-//
-// This configuration file is reloaded
-// - With the "ael reload" command in the CLI
-// - With the "reload" command (that reloads everything) in the CLI
-
-// The "Globals" category contains global variables that can be referenced
-// in the dialplan by using the GLOBAL dialplan function:
-// ${GLOBAL(VARIABLE)}
-// ${${GLOBAL(VARIABLE)}} or ${text${GLOBAL(VARIABLE)}} or any hybrid
-// Unix/Linux environmental variables are reached with the ENV dialplan
-// function: ${ENV(VARIABLE)}
-//
-
-globals {
- CONSOLE="Console/dsp"; // Console interface for demo
- //CONSOLE=Zap/1
- //CONSOLE=Phone/phone0
- IAXINFO=guest; // IAXtel username/password
- //IAXINFO="myuser:mypass";
- TRUNK="Zap/g2"; // Trunk interface
- //
- // Note the 'g2' in the TRUNK variable above. It specifies which group (defined
- // in zapata.conf) to dial, i.e. group 2, and how to choose a channel to use in
- // the specified group. The four possible options are:
- //
- // g: select the lowest-numbered non-busy Zap channel
- // (aka. ascending sequential hunt group).
- // G: select the highest-numbered non-busy Zap channel
- // (aka. descending sequential hunt group).
- // r: use a round-robin search, starting at the next highest channel than last
- // time (aka. ascending rotary hunt group).
- // R: use a round-robin search, starting at the next lowest channel than last
- // time (aka. descending rotary hunt group).
- //
- TRUNKMSD=1; // MSD digits to strip (usually 1 or 0)
- //TRUNK=IAX2/user:pass@provider
-};
-
-//
-// Any category other than "General" and "Globals" represent
-// extension contexts, which are collections of extensions.
-//
-// Extension names may be numbers, letters, or combinations
-// thereof. If an extension name is prefixed by a '_'
-// character, it is interpreted as a pattern rather than a
-// literal. In patterns, some characters have special meanings:
-//
-// X - any digit from 0-9
-// Z - any digit from 1-9
-// N - any digit from 2-9
-// [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
-// . - wildcard, matches anything remaining (e.g. _9011. matches
-// anything starting with 9011 excluding 9011 itself)
-// ! - wildcard, causes the matching process to complete as soon as
-// it can unambiguously determine that no other matches are possible
-//
-// For example the extension _NXXXXXX would match normal 7 digit dialings,
-// while _1NXXNXXXXXX would represent an area code plus phone number
-// preceded by a one.
-//
-// Each step of an extension is ordered by priority, which must
-// always start with 1 to be considered a valid extension. The priority
-// "next" or "n" means the previous priority plus one, regardless of whether
-// the previous priority was associated with the current extension or not.
-// The priority "same" or "s" means the same as the previously specified
-// priority, again regardless of whether the previous entry was for the
-// same extension. Priorities may be immediately followed by a plus sign
-// and another integer to add that amount (most useful with 's' or 'n').
-// Priorities may then also have an alias, or label, in
-// parenthesis after their name which can be used in goto situations
-//
-// Contexts contain several lines, one for each step of each
-// extension, which can take one of two forms as listed below,
-// with the first form being preferred. One may include another
-// context in the current one as well, optionally with a
-// date and time. Included contexts are included in the order
-// they are listed.
-//
-//context name {
-// exten-name => {
-// application(arg1,arg2,...);
-//
-// Timing list for includes is
-//
-// <time range>|<days of week>|<days of month>|<months>
-//
-// includes {
-// daytime|9:00-17:00|mon-fri|*|*;
-// };
-//
-// ignorepat can be used to instruct drivers to not cancel dialtone upon
-// receipt of a particular pattern. The most commonly used example is
-// of course '9' like this:
-//
-// ignorepat => 9;
-//
-// so that dialtone remains even after dialing a 9.
-//};
-
-
-//
-// Sample entries for extensions.conf
-//
-//
-context ael-dundi-e164-canonical {
- //
- // List canonical entries here
- //
- // 12564286000 => &ael-std-exten(6000,IAX2/foo);
- // _125642860XX => Dial(IAX2/otherbox/${EXTEN:7});
-};
-
-context ael-dundi-e164-customers {
- //
- // If you are an ITSP or Reseller, list your customers here.
- //
- //_12564286000 => Dial(SIP/customer1);
- //_12564286001 => Dial(IAX2/customer2);
-};
-
-context ael-dundi-e164-via-pstn {
- //
- // If you are freely delivering calls to the PSTN, list them here
- //
- //_1256428XXXX => Dial(Zap/g2/${EXTEN:7}); // Expose all of 256-428
- //_1256325XXXX => Dial(Zap/g2/${EXTEN:7}); // Ditto for 256-325
-};
-
-context ael-dundi-e164-local {
- //
- // Context to put your dundi IAX2 or SIP user in for
- // full access
- //
- includes {
- ael-dundi-e164-canonical;
- ael-dundi-e164-customers;
- ael-dundi-e164-via-pstn;
- };
-};
-
-context ael-dundi-e164-switch {
- //
- // Just a wrapper for the switch
- //
-
- switches {
- DUNDi/e164;
- };
-};
-
-context ael-dundi-e164-lookup {
- //
- // Locally to lookup, try looking for a local E.164 solution
- // then try DUNDi if we don't have one.
- //
- includes {
- ael-dundi-e164-local;
- ael-dundi-e164-switch;
- };
- //
-};
-
-//
-// DUNDi can also be implemented as a Macro instead of using
-// the Local channel driver.
-//
-macro ael-dundi-e164(exten) {
-//
-// ARG1 is the extension to Dial
-//
- goto ${exten}|1;
- return;
-};
-
-//
-// Here are the entries you need to participate in the IAXTEL
-// call routing system. Most IAXTEL numbers begin with 1-700, but
-// there are exceptions. For more information, and to sign
-// up, please go to www.gnophone.com or www.iaxtel.com
-//
-context ael-iaxtel700 {
- _91700XXXXXXX => Dial(IAX2/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel);
-};
-
-//
-// The SWITCH statement permits a server to share the dialplan with
-// another server. Use with care: Reciprocal switch statements are not
-// allowed (e.g. both A -> B and B -> A), and the switched server needs
-// to be on-line or else dialing can be severly delayed.
-//
-context ael-iaxprovider {
- switches {
- // IAX2/user:[key]@myserver/mycontext;
- };
-};
-
-context ael-trunkint {
- //
- // International long distance through trunk
- //
- includes {
- ael-dundi-e164-lookup;
- };
- _9011. => {
- &ael-dundi-e164(${EXTEN:4});
- Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
- };
-};
-
-context ael-trunkld {
- //
- // Long distance context accessed through trunk
- //
- includes {
- ael-dundi-e164-lookup;
- };
- _91NXXNXXXXXX => {
- &ael-dundi-e164(${EXTEN:1});
- Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
- };
-};
-
-context ael-trunklocal {
- //
- // Local seven-digit dialing accessed through trunk interface
- //
- _9NXXXXXX => {
- Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
- };
-};
-
-context ael-trunktollfree {
- //
- // Long distance context accessed through trunk interface
- //
-
- _91800NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
- _91888NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
- _91877NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
- _91866NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
-};
-
-context ael-international {
- //
- // Master context for international long distance
- //
- ignorepat => 9;
- includes {
- ael-longdistance;
- ael-trunkint;
- };
-};
-
-context ael-longdistance {
- //
- // Master context for long distance
- //
- ignorepat => 9;
- includes {
- ael-local;
- ael-trunkld;
- };
-};
-
-context ael-local {
- //
- // Master context for local, toll-free, and iaxtel calls only
- //
- ignorepat => 9;
- includes {
- ael-default;
- ael-trunklocal;
- ael-iaxtel700;
- ael-trunktollfree;
- ael-iaxprovider;
- };
-};
-
-//
-// You can use an alternative switch type as well, to resolve
-// extensions that are not known here, for example with remote
-// IAX switching you transparently get access to the remote
-// Asterisk PBX
-//
-// switch => IAX2/user:password@bigserver/local
-//
-// An "lswitch" is like a switch but is literal, in that
-// variable substitution is not performed at load time
-// but is passed to the switch directly (presumably to
-// be substituted in the switch routine itself)
-//
-// lswitch => Loopback/12${EXTEN}@othercontext
-//
-// An "eswitch" is like a switch but the evaluation of
-// variable substitution is performed at runtime before
-// being passed to the switch routine.
-//
-// eswitch => IAX2/context@${CURSERVER}
-
-
-macro ael-std-exten-ael( ext , dev ) {
- Dial(${dev}/${ext},20);
- switch(${DIALSTATUS}) {
- case BUSY:
- Voicemail(${ext},b);
- break;
- default:
- Voicemail(${ext},u);
- };
- catch a {
- VoiceMailMain(${ext});
- return;
- };
- return;
-};
-
-context ael-demo {
- s => {
- Wait(1);
- Answer();
- Set(TIMEOUT(digit)=5);
- Set(TIMEOUT(response)=10);
-restart:
- Background(demo-congrats);
-instructions:
- for (x=0; ${x} < 3; x=${x} + 1) {
- Background(demo-instruct);
- WaitExten();
- };
- };
- 2 => {
- Background(demo-moreinfo);
- goto s|instructions;
- };
- 3 => {
- Set(LANGUAGE()=fr);
- goto s|restart;
- };
- 1000 => {
- goto ael-default|s|1;
- };
- 500 => {
- Playback(demo-abouttotry);
- Dial(IAX2/guest@misery.digium.com/s@default);
- Playback(demo-nogo);
- goto s|instructions;
- };
- 600 => {
- Playback(demo-echotest);
- Echo();
- Playback(demo-echodone);
- goto s|instructions;
- };
- _1234 => &ael-std-exten-ael(${EXTEN}, "IAX2");
- 8500 => {
- VoicemailMain();
- goto s|instructions;
- };
- # => {
- Playback(demo-thanks);
- Hangup();
- };
- t => goto #|1;
- i => Playback(invalid);
-};
-
-
-//
-// If you wish to use AEL for your default context, remove it
-// from extensions.conf (or change its name or comment it out)
-// and then uncomment the one here.
-//
-
-context ael-default {
-
-// By default we include the demo. In a production system, you
-// probably don't want to have the demo there.
-
- includes {
- ael-demo;
- };
-//
-// Extensions like the two below can be used for FWD, Nikotel, sipgate etc.
-// Note that you must have a [sipprovider] section in sip.conf whereas
-// the otherprovider.net example does not require such a peer definition
-//
-//_41X. => Dial(SIP/${EXTEN:2}@sipprovider,,r);
-//_42X. => Dial(SIP/user:passwd@${EXTEN:2}@otherprovider.net,30,rT);
-
-// Real extensions would go here. Generally you want real extensions to be
-// 4 or 5 digits long (although there is no such requirement) and start with a
-// single digit that is fairly large (like 6 or 7) so that you have plenty of
-// room to overlap extensions and menu options without conflict. You can alias
-// them with names, too, and use global variables
-
-// 6245 => {
-// hint(SIP/Grandstream1&SIP/Xlite1,Joe Schmoe); // Channel hints for presence
-// Dial(SIP/Grandstream1,20,rt); // permit transfer
-// Dial(${HINT}/5245},20,rtT); // Use hint as listed
-// switch(${DIALSTATUS}) {
-// case BUSY:
-// Voicemail(6245,b);
-// return;
-// default:
-// Voicemail(6245,u);
-// return;
-// };
-// };
-
-// 6361 => Dial(IAX2/JaneDoe,,rm); // ring without time limit
-// 6389 => Dial(MGCP/aaln/1@192.168.0.14);
-// 6394 => Dial(Local/6275/n); // this will dial ${MARK}
-
-// 6275 => &ael-stdexten(6275,${MARK}); // assuming ${MARK} is something like Zap/2
-// mark => goto 6275|1; // alias mark to 6275
-// 6536 => &ael-stdexten(6236,${WIL}); // Ditto for wil
-// wil => goto 6236|1;
-//
-// Some other handy things are an extension for checking voicemail via
-// voicemailmain
-//
-// 8500 => {
-// VoicemailMain();
-// Hangup();
-// };
-//
-// Or a conference room (you'll need to edit meetme.conf to enable this room)
-//
-// 8600 => Meetme(1234);
-//
-// Or playing an announcement to the called party, as soon it answers
-//
-// 8700 => Dial(${MARK},30,A(/path/to/my/announcemsg))
-//
-// For more information on applications, just type "show applications" at your
-// friendly Asterisk CLI prompt.
-//
-// 'show application <command>' will show details of how you
-// use that particular application in this file, the dial plan.
-//
-}
diff --git a/1.4/configs/extensions.conf.sample b/1.4/configs/extensions.conf.sample
deleted file mode 100644
index d1e7a8310..000000000
--- a/1.4/configs/extensions.conf.sample
+++ /dev/null
@@ -1,614 +0,0 @@
-; extensions.conf - the Asterisk dial plan
-;
-; Static extension configuration file, used by
-; the pbx_config module. This is where you configure all your
-; inbound and outbound calls in Asterisk.
-;
-; This configuration file is reloaded
-; - With the "dialplan reload" command in the CLI
-; - With the "reload" command (that reloads everything) in the CLI
-
-;
-; The "General" category is for certain variables.
-;
-[general]
-;
-; If static is set to no, or omitted, then the pbx_config will rewrite
-; this file when extensions are modified. Remember that all comments
-; made in the file will be lost when that happens.
-;
-; XXX Not yet implemented XXX
-;
-static=yes
-;
-; if static=yes and writeprotect=no, you can save dialplan by
-; CLI command "dialplan save" too
-;
-writeprotect=no
-;
-; If autofallthrough is set, then if an extension runs out of
-; things to do, it will terminate the call with BUSY, CONGESTION
-; or HANGUP depending on Asterisk's best guess. This is the default.
-;
-; If autofallthrough is not set, then if an extension runs out of
-; things to do, Asterisk will wait for a new extension to be dialed
-; (this is the original behavior of Asterisk 1.0 and earlier).
-;
-;autofallthrough=no
-;
-; If clearglobalvars is set, global variables will be cleared
-; and reparsed on an extensions reload, or Asterisk reload.
-;
-; If clearglobalvars is not set, then global variables will persist
-; through reloads, and even if deleted from the extensions.conf or
-; one of its included files, will remain set to the previous value.
-;
-; NOTE: A complication sets in, if you put your global variables into
-; the AEL file, instead of the extensions.conf file. With clearglobalvars
-; set, a "reload" will often leave the globals vars cleared, because it
-; is not unusual to have extensions.conf (which will have no globals)
-; load after the extensions.ael file (where the global vars are stored).
-; So, with "reload" in this particular situation, first the AEL file will
-; clear and then set all the global vars, then, later, when the extensions.conf
-; file is loaded, the global vars are all cleared, and then not set, because
-; they are not stored in the extensions.conf file.
-;
-clearglobalvars=no
-;
-; If priorityjumping is set to 'yes', then applications that support
-; 'jumping' to a different priority based on the result of their operations
-; will do so (this is backwards compatible behavior with pre-1.2 releases
-; of Asterisk). Individual applications can also be requested to do this
-; by passing a 'j' option in their arguments.
-;
-;priorityjumping=yes
-;
-; User context is where entries from users.conf are registered. The
-; default value is 'default'
-;
-;userscontext=default
-;
-; You can include other config files, use the #include command
-; (without the ';'). Note that this is different from the "include" command
-; that includes contexts within other contexts. The #include command works
-; in all asterisk configuration files.
-;#include "filename.conf"
-
-; The "Globals" category contains global variables that can be referenced
-; in the dialplan with the GLOBAL dialplan function:
-; ${GLOBAL(VARIABLE)}
-; ${${GLOBAL(VARIABLE)}} or ${text${GLOBAL(VARIABLE)}} or any hybrid
-; Unix/Linux environmental variables can be reached with the ENV dialplan
-; function: ${ENV(VARIABLE)}
-;
-[globals]
-CONSOLE=Console/dsp ; Console interface for demo
-;CONSOLE=Zap/1
-;CONSOLE=Phone/phone0
-IAXINFO=guest ; IAXtel username/password
-;IAXINFO=myuser:mypass
-TRUNK=Zap/G2 ; Trunk interface
-;
-; Note the 'G2' in the TRUNK variable above. It specifies which group (defined
-; in zapata.conf) to dial, i.e. group 2, and how to choose a channel to use in
-; the specified group. The four possible options are:
-;
-; g: select the lowest-numbered non-busy Zap channel
-; (aka. ascending sequential hunt group).
-; G: select the highest-numbered non-busy Zap channel
-; (aka. descending sequential hunt group).
-; r: use a round-robin search, starting at the next highest channel than last
-; time (aka. ascending rotary hunt group).
-; R: use a round-robin search, starting at the next lowest channel than last
-; time (aka. descending rotary hunt group).
-;
-TRUNKMSD=1 ; MSD digits to strip (usually 1 or 0)
-;TRUNK=IAX2/user:pass@provider
-
-;
-; Any category other than "General" and "Globals" represent
-; extension contexts, which are collections of extensions.
-;
-; Extension names may be numbers, letters, or combinations
-; thereof. If an extension name is prefixed by a '_'
-; character, it is interpreted as a pattern rather than a
-; literal. In patterns, some characters have special meanings:
-;
-; X - any digit from 0-9
-; Z - any digit from 1-9
-; N - any digit from 2-9
-; [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
-; . - wildcard, matches anything remaining (e.g. _9011. matches
-; anything starting with 9011 excluding 9011 itself)
-; ! - wildcard, causes the matching process to complete as soon as
-; it can unambiguously determine that no other matches are possible
-;
-; For example the extension _NXXXXXX would match normal 7 digit dialings,
-; while _1NXXNXXXXXX would represent an area code plus phone number
-; preceded by a one.
-;
-; Each step of an extension is ordered by priority, which must
-; always start with 1 to be considered a valid extension. The priority
-; "next" or "n" means the previous priority plus one, regardless of whether
-; the previous priority was associated with the current extension or not.
-; The priority "same" or "s" means the same as the previously specified
-; priority, again regardless of whether the previous entry was for the
-; same extension. Priorities may be immediately followed by a plus sign
-; and another integer to add that amount (most useful with 's' or 'n').
-; Priorities may then also have an alias, or label, in
-; parenthesis after their name which can be used in goto situations
-;
-; Contexts contain several lines, one for each step of each
-; extension, which can take one of two forms as listed below,
-; with the first form being preferred.
-;
-;[context]
-;exten => someexten,{priority|label{+|-}offset}[(alias)],application(arg1,arg2,...)
-;exten => someexten,{priority|label{+|-}offset}[(alias)],application,arg1|arg2...
-;
-; Included Contexts
-;
-; One may include another context in the current one as well, optionally with a
-; date and time. Included contexts are included in the order
-; they are listed.
-; The reason a context would include other contexts is for their
-; extensions.
-; The algorithm to find an extension is recursive, and works in this
-; fashion:
-; first, given a stack on which to store context references,
-; push the context to find the extension onto the stack...
-; a) Try to find a matching extension in the context at the top of
-; the stack, and, if found, begin executing the priorities
-; there in sequence.
-; b) If not found, Search the switches, if any declared, in
-; sequence.
-; c) If still not found, for each include, push that context onto
-; the top of the context stack, and recurse to a).
-; d) If still not found, pop the entry from the top of the stack;
-; if the stack is empty, the search has failed. If it's not,
-; continue with the next context in c).
-; This is a depth-first traversal, and stops with the first context
-; that provides a matching extension. As usual, if more than one
-; pattern in a context will match, the 'best' match will win.
-; Please note that that extensions found in an included context are
-; treated as if they were in the context from which the search began.
-; The PBX's notion of the "current context" is not changed.
-; Please note that in a context, it does not matter where an include
-; directive occurs. Whether at the top, or near the bottom, the effect
-; will be the same. The only thing that matters is that if there is
-; more than one include directive, they will be searched for extensions
-; in order, first to last.
-; Also please note that pattern matches (like _9XX) are not treated
-; any differently than exact matches (like 987). Also note that the
-; order of extensions in a context have no affect on the outcome.
-;
-; Timing list for includes is
-;
-; <time range>|<days of week>|<days of month>|<months>
-;
-; Note that ranges may be specified to wrap around the ends. Also, minutes are
-; fine-grained only down to the closest even minute.
-;
-;include => daytime|9:00-17:00|mon-fri|*|*
-;include => weekend|*|sat-sun|*|*
-;include => weeknights|17:02-8:58|mon-fri|*|*
-;
-; ignorepat can be used to instruct drivers to not cancel dialtone upon
-; receipt of a particular pattern. The most commonly used example is
-; of course '9' like this:
-;
-;ignorepat => 9
-;
-; so that dialtone remains even after dialing a 9.
-;
-
-;
-; Sample entries for extensions.conf
-;
-;
-[dundi-e164-canonical]
-;
-; List canonical entries here
-;
-;exten => 12564286000,1,Macro(stdexten,6000,IAX2/foo)
-;exten => _125642860XX,1,Dial(IAX2/otherbox/${EXTEN:7})
-
-[dundi-e164-customers]
-;
-; If you are an ITSP or Reseller, list your customers here.
-;
-;exten => _12564286000,1,Dial(SIP/customer1)
-;exten => _12564286001,1,Dial(IAX2/customer2)
-
-[dundi-e164-via-pstn]
-;
-; If you are freely delivering calls to the PSTN, list them here
-;
-;exten => _1256428XXXX,1,Dial(Zap/G2/${EXTEN:7}) ; Expose all of 256-428
-;exten => _1256325XXXX,1,Dial(Zap/G2/${EXTEN:7}) ; Ditto for 256-325
-
-[dundi-e164-local]
-;
-; Context to put your dundi IAX2 or SIP user in for
-; full access
-;
-include => dundi-e164-canonical
-include => dundi-e164-customers
-include => dundi-e164-via-pstn
-
-[dundi-e164-switch]
-;
-; Just a wrapper for the switch
-;
-switch => DUNDi/e164
-
-[dundi-e164-lookup]
-;
-; Locally to lookup, try looking for a local E.164 solution
-; then try DUNDi if we don't have one.
-;
-include => dundi-e164-local
-include => dundi-e164-switch
-;
-; DUNDi can also be implemented as a Macro instead of using
-; the Local channel driver.
-;
-[macro-dundi-e164]
-;
-; ARG1 is the extension to Dial
-;
-; Extension "s" is not a wildcard extension that matches "anything".
-; In macros, it is the start extension. In most other cases,
-; you have to goto "s" to execute that extension.
-;
-; For wildcard matches, see above - all pattern matches start with
-; an underscore.
-exten => s,1,Goto(${ARG1},1)
-include => dundi-e164-lookup
-
-;
-; Here are the entries you need to participate in the IAXTEL
-; call routing system. Most IAXTEL numbers begin with 1-700, but
-; there are exceptions. For more information, and to sign
-; up, please go to www.gnophone.com or www.iaxtel.com
-;
-[iaxtel700]
-exten => _91700XXXXXXX,1,Dial(IAX2/${GLOBAL(IAXINFO)}@iaxtel.com/${EXTEN:1}@iaxtel)
-
-;
-; The SWITCH statement permits a server to share the dialplan with
-; another server. Use with care: Reciprocal switch statements are not
-; allowed (e.g. both A -> B and B -> A), and the switched server needs
-; to be on-line or else dialing can be severly delayed.
-;
-[iaxprovider]
-;switch => IAX2/user:[key]@myserver/mycontext
-
-[trunkint]
-;
-; International long distance through trunk
-;
-exten => _9011.,1,Macro(dundi-e164,${EXTEN:4})
-exten => _9011.,n,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-
-[trunkld]
-;
-; Long distance context accessed through trunk
-;
-exten => _91NXXNXXXXXX,1,Macro(dundi-e164,${EXTEN:1})
-exten => _91NXXNXXXXXX,n,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-
-[trunklocal]
-;
-; Local seven-digit dialing accessed through trunk interface
-;
-exten => _9NXXXXXX,1,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-
-[trunktollfree]
-;
-; Long distance context accessed through trunk interface
-;
-exten => _91800NXXXXXX,1,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-exten => _91888NXXXXXX,1,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-exten => _91877NXXXXXX,1,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-exten => _91866NXXXXXX,1,Dial(${GLOBAL(TRUNK)}/${EXTEN:${GLOBAL(TRUNKMSD)}})
-
-[international]
-;
-; Master context for international long distance
-;
-ignorepat => 9
-include => longdistance
-include => trunkint
-
-[longdistance]
-;
-; Master context for long distance
-;
-ignorepat => 9
-include => local
-include => trunkld
-
-[local]
-;
-; Master context for local, toll-free, and iaxtel calls only
-;
-ignorepat => 9
-include => default
-include => trunklocal
-include => iaxtel700
-include => trunktollfree
-include => iaxprovider
-
-;Include parkedcalls (or the context you define in features conf)
-;to enable call parking.
-include => parkedcalls
-;
-; You can use an alternative switch type as well, to resolve
-; extensions that are not known here, for example with remote
-; IAX switching you transparently get access to the remote
-; Asterisk PBX
-;
-; switch => IAX2/user:password@bigserver/local
-;
-; An "lswitch" is like a switch but is literal, in that
-; variable substitution is not performed at load time
-; but is passed to the switch directly (presumably to
-; be substituted in the switch routine itself)
-;
-; lswitch => Loopback/12${EXTEN}@othercontext
-;
-; An "eswitch" is like a switch but the evaluation of
-; variable substitution is performed at runtime before
-; being passed to the switch routine.
-;
-; eswitch => IAX2/context@${CURSERVER}
-
-[macro-trunkdial]
-;
-; Standard trunk dial macro (hangs up on a dialstatus that should
-; terminate call)
-; ${ARG1} - What to dial
-;
-exten => s,1,Dial(${ARG1})
-exten => s,n,Goto(s-${DIALSTATUS},1)
-exten => s-NOANSWER,1,Hangup
-exten => s-BUSY,1,Hangup
-exten => _s-.,1,NoOp
-
-[macro-stdexten];
-;
-; Standard extension macro:
-; ${ARG1} - Extension (we could have used ${MACRO_EXTEN} here as well
-; ${ARG2} - Device(s) to ring
-;
-exten => s,1,Dial(${ARG2},20) ; Ring the interface, 20 seconds maximum
-exten => s,2,Goto(s-${DIALSTATUS},1) ; Jump based on status (NOANSWER,BUSY,CHANUNAVAIL,CONGESTION,ANSWER)
-
-exten => s-NOANSWER,1,Voicemail(${ARG1},u) ; If unavailable, send to voicemail w/ unavail announce
-exten => s-NOANSWER,2,Goto(default,s,1) ; If they press #, return to start
-
-exten => s-BUSY,1,Voicemail(${ARG1},b) ; If busy, send to voicemail w/ busy announce
-exten => s-BUSY,2,Goto(default,s,1) ; If they press #, return to start
-
-exten => _s-.,1,Goto(s-NOANSWER,1) ; Treat anything else as no answer
-
-exten => a,1,VoicemailMain(${ARG1}) ; If they press *, send the user into VoicemailMain
-
-[macro-stdPrivacyexten];
-;
-; Standard extension macro:
-; ${ARG1} - Extension (we could have used ${MACRO_EXTEN} here as well
-; ${ARG2} - Device(s) to ring
-; ${ARG3} - Optional DONTCALL context name to jump to (assumes the s,1 extension-priority)
-; ${ARG4} - Optional TORTURE context name to jump to (assumes the s,1 extension-priority)`
-;
-exten => s,1,Dial(${ARG2},20|p) ; Ring the interface, 20 seconds maximum, call screening
- ; option (or use P for databased call screening)
-exten => s,2,Goto(s-${DIALSTATUS},1) ; Jump based on status (NOANSWER,BUSY,CHANUNAVAIL,CONGESTION,ANSWER)
-
-exten => s-NOANSWER,1,Voicemail(${ARG1},u) ; If unavailable, send to voicemail w/ unavail announce
-exten => s-NOANSWER,2,Goto(default,s,1) ; If they press #, return to start
-
-exten => s-BUSY,1,Voicemail(${ARG1},b) ; If busy, send to voicemail w/ busy announce
-exten => s-BUSY,2,Goto(default,s,1) ; If they press #, return to start
-
-exten => s-DONTCALL,1,Goto(${ARG3},s,1) ; Callee chose to send this call to a polite "Don't call again" script.
-
-exten => s-TORTURE,1,Goto(${ARG4},s,1) ; Callee chose to send this call to a telemarketer torture script.
-
-exten => _s-.,1,Goto(s-NOANSWER,1) ; Treat anything else as no answer
-
-exten => a,1,VoicemailMain(${ARG1}) ; If they press *, send the user into VoicemailMain
-
-[macro-page];
-;
-; Paging macro:
-;
-; Check to see if SIP device is in use and DO NOT PAGE if they are
-;
-; ${ARG1} - Device to page
-
-exten => s,1,ChanIsAvail(${ARG1}|js) ; j is for Jump and s is for ANY call
-exten => s,n,GoToIf([${AVAILSTATUS} = "1"]?autoanswer:fail)
-exten => s,n(autoanswer),Set(_ALERT_INFO="RA") ; This is for the PolyComs
-exten => s,n,SIPAddHeader(Call-Info: Answer-After=0) ; This is for the Grandstream, Snoms, and Others
-exten => s,n,NoOp() ; Add others here and Post on the Wiki!!!!
-exten => s,n,Dial(${ARG1}||)
-exten => s,n(fail),Hangup
-
-
-[demo]
-;
-; We start with what to do when a call first comes in.
-;
-exten => s,1,Wait(1) ; Wait a second, just for fun
-exten => s,n,Answer ; Answer the line
-exten => s,n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
-exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
-exten => s,n(restart),BackGround(demo-congrats) ; Play a congratulatory message
-exten => s,n(instruct),BackGround(demo-instruct) ; Play some instructions
-exten => s,n,WaitExten ; Wait for an extension to be dialed.
-
-exten => 2,1,BackGround(demo-moreinfo) ; Give some more information.
-exten => 2,n,Goto(s,instruct)
-
-exten => 3,1,Set(LANGUAGE()=fr) ; Set language to french
-exten => 3,n,Goto(s,restart) ; Start with the congratulations
-
-exten => 1000,1,Goto(default,s,1)
-;
-; We also create an example user, 1234, who is on the console and has
-; voicemail, etc.
-;
-exten => 1234,1,Playback(transfer,skip) ; "Please hold while..."
- ; (but skip if channel is not up)
-exten => 1234,n,Macro(stdexten,1234,${GLOBAL(CONSOLE)})
-
-exten => 1235,1,Voicemail(1234,u) ; Right to voicemail
-
-exten => 1236,1,Dial(Console/dsp) ; Ring forever
-exten => 1236,n,Voicemail(1234,b) ; Unless busy
-
-;
-; # for when they're done with the demo
-;
-exten => #,1,Playback(demo-thanks) ; "Thanks for trying the demo"
-exten => #,n,Hangup ; Hang them up.
-
-;
-; A timeout and "invalid extension rule"
-;
-exten => t,1,Goto(#,1) ; If they take too long, give up
-exten => i,1,Playback(invalid) ; "That's not valid, try again"
-
-;
-; Create an extension, 500, for dialing the
-; Asterisk demo.
-;
-exten => 500,1,Playback(demo-abouttotry); Let them know what's going on
-exten => 500,n,Dial(IAX2/guest@pbx.digium.com/s@default) ; Call the Asterisk demo
-exten => 500,n,Playback(demo-nogo) ; Couldn't connect to the demo site
-exten => 500,n,Goto(s,6) ; Return to the start over message.
-
-;
-; Create an extension, 600, for evaluating echo latency.
-;
-exten => 600,1,Playback(demo-echotest) ; Let them know what's going on
-exten => 600,n,Echo ; Do the echo test
-exten => 600,n,Playback(demo-echodone) ; Let them know it's over
-exten => 600,n,Goto(s,6) ; Start over
-
-;
-; You can use the Macro Page to intercom a individual user
-exten => 76245,1,Macro(page,SIP/Grandstream1)
-; or if your peernames are the same as extensions
-exten => _7XXX,1,Macro(page,SIP/${EXTEN})
-;
-;
-; System Wide Page at extension 7999
-;
-exten => 7999,1,Set(TIMEOUT(absolute)=60)
-exten => 7999,2,Page(Local/Grandstream1@page&Local/Xlite1@page&Local/1234@page/n|d)
-
-; Give voicemail at extension 8500
-;
-exten => 8500,1,VoicemailMain
-exten => 8500,n,Goto(s,6)
-;
-; Here's what a phone entry would look like (IXJ for example)
-;
-;exten => 1265,1,Dial(Phone/phone0,15)
-;exten => 1265,n,Goto(s,5)
-
-;
-; The page context calls up the page macro that sets variables needed for auto-answer
-; It is in is own context to make calling it from the Page() application as simple as
-; Local/{peername}@page
-;
-[page]
-exten => _X.,1,Macro(page,SIP/${EXTEN})
-
-;[mainmenu]
-;
-; Example "main menu" context with submenu
-;
-;exten => s,1,Answer
-;exten => s,n,Background(thanks) ; "Thanks for calling press 1 for sales, 2 for support, ..."
-;exten => s,n,WaitExten
-;exten => 1,1,Goto(submenu,s,1)
-;exten => 2,1,Hangup
-;include => default
-;
-;[submenu]
-;exten => s,1,Ringing ; Make them comfortable with 2 seconds of ringback
-;exten => s,n,Wait,2
-;exten => s,n,Background(submenuopts) ; "Thanks for calling the sales department. Press 1 for steve, 2 for..."
-;exten => s,n,WaitExten
-;exten => 1,1,Goto(default,steve,1)
-;exten => 2,1,Goto(default,mark,2)
-
-[default]
-;
-; By default we include the demo. In a production system, you
-; probably don't want to have the demo there.
-;
-include => demo
-
-;
-; An extension like the one below can be used for FWD, Nikotel, sipgate etc.
-; Note that you must have a [sipprovider] section in sip.conf
-;
-;exten => _41X.,1,Dial(SIP/${EXTEN:2}@sipprovider,,r)
-
-; Real extensions would go here. Generally you want real extensions to be
-; 4 or 5 digits long (although there is no such requirement) and start with a
-; single digit that is fairly large (like 6 or 7) so that you have plenty of
-; room to overlap extensions and menu options without conflict. You can alias
-; them with names, too, and use global variables
-
-;exten => 6245,hint,SIP/Grandstream1&SIP/Xlite1,Joe Schmoe ; Channel hints for presence
-;exten => 6245,1,Dial(SIP/Grandstream1,20,rt) ; permit transfer
-;exten => 6245,n(dial),Dial(${HINT},20,rtT) ; Use hint as listed
-;exten => 6245,n,Voicemail(6245,u) ; Voicemail (unavailable)
-;exten => 6245,s+1,Hangup ; s+1, same as n
-;exten => 6245,dial+101,Voicemail(6245,b) ; Voicemail (busy)
-;exten => 6361,1,Dial(IAX2/JaneDoe,,rm) ; ring without time limit
-;exten => 6389,1,Dial(MGCP/aaln/1@192.168.0.14)
-;exten => 6390,1,Dial(JINGLE/caller/callee) ; Dial via jingle using labels
-;exten => 6391,1,Dial(JINGLE/asterisk@digium.com/mogorman@astjab.org) ;Dial via jingle using asterisk as the transport and calling mogorman.
-;exten => 6394,1,Dial(Local/6275/n) ; this will dial ${MARK}
-
-;exten => 6275,1,Macro(stdexten,6275,${MARK}) ; assuming ${MARK} is something like Zap/2
-;exten => mark,1,Goto(6275|1) ; alias mark to 6275
-;exten => 6536,1,Macro(stdexten,6236,${WIL}) ; Ditto for wil
-;exten => wil,1,Goto(6236|1)
-
-;If you want to subscribe to the status of a parking space, this is
-;how you do it. Subscribe to extension 6600 in sip, and you will see
-;the status of the first parking lot with this extensions' help
-;exten => 6600,hint,park:701@parkedcalls
-;exten => 6600,1,noop
-;
-; Some other handy things are an extension for checking voicemail via
-; voicemailmain
-;
-;exten => 8500,1,VoicemailMain
-;exten => 8500,n,Hangup
-;
-; Or a conference room (you'll need to edit meetme.conf to enable this room)
-;
-;exten => 8600,1,Meetme(1234)
-;
-; Or playing an announcement to the called party, as soon it answers
-;
-;exten = 8700,1,Dial(${MARK},30,A(/path/to/my/announcemsg))
-;
-; For more information on applications, just type "core show applications" at your
-; friendly Asterisk CLI prompt.
-;
-; "core show application <command>" will show details of how you
-; use that particular application in this file, the dial plan.
-; "core show functions" will list all dialplan functions
-; "core show function <COMMAND>" will show you more information about
-; one function. Remember that function names are UPPER CASE.
diff --git a/1.4/configs/features.conf.sample b/1.4/configs/features.conf.sample
deleted file mode 100644
index 969074c8e..000000000
--- a/1.4/configs/features.conf.sample
+++ /dev/null
@@ -1,98 +0,0 @@
-;
-; Sample Call Features (parking, transfer, etc) configuration
-;
-
-[general]
-parkext => 700 ; What extension to dial to park
-parkpos => 701-720 ; What extensions to park calls on. These needs to be
- ; numeric, as Asterisk starts from the start position
- ; and increments with one for the next parked call.
-context => parkedcalls ; Which context parked calls are in
-;parkingtime => 45 ; Number of seconds a call can be parked for
- ; (default is 45 seconds)
-;courtesytone = beep ; Sound file to play to the parked caller
- ; when someone dials a parked call
- ; or the Touch Monitor is activated/deactivated.
-;parkedplay = caller ; Who to play the courtesy tone to when picking up a parked call
- ; one of: parked, caller, both (default is caller)
-;adsipark = yes ; if you want ADSI parking announcements
-;findslot => next ; Continue to the 'next' free parking space.
- ; Defaults to 'first' available
-;parkedmusicclass=default ; This is the MOH class to use for the parked channel
- ; as long as the class is not set on the channel directly
- ; using Set(CHANNEL(musicclass)=whatever) in the dialplan
-
-;transferdigittimeout => 3 ; Number of seconds to wait between digits when transferring a call
- ; (default is 3 seconds)
-;xfersound = beep ; to indicate an attended transfer is complete
-;xferfailsound = beeperr ; to indicate a failed transfer
-;pickupexten = *8 ; Configure the pickup extension. (default is *8)
-;featuredigittimeout = 500 ; Max time (ms) between digits for
- ; feature activation (default is 500 ms)
-;atxfernoanswertimeout = 15 ; Timeout for answer on attended transfer default is 15 seconds.
-
-; Note that the DTMF features listed below only work when two channels have answered and are bridged together.
-; They can not be used while the remote party is ringing or in progress. If you require this feature you can use
-; chan_local in combination with Answer to accomplish it.
-
-[featuremap]
-;blindxfer => #1 ; Blind transfer (default is #)
-;disconnect => *0 ; Disconnect (default is *)
-;automon => *1 ; One Touch Record a.k.a. Touch Monitor
-;atxfer => *2 ; Attended transfer
-;parkcall => #72 ; Park call (one step parking)
-
-[applicationmap]
-; Note that the DYNAMIC_FEATURES channel variable must be set to use the features
-; defined here. The value of DYNAMIC_FEATURES should be the names of the features
-; to allow the channel to use separated by '#'. For example:
-;
-; Set(__DYNAMIC_FEATURES=myfeature1#myfeature2#myfeature3)
-;
-; (Note: The two leading underscores allow these feature settings to be set on
-; on the outbound channels, as well. Otherwise, only the original channel
-; will have access to these features.)
-;
-; The syntax for declaring a dynamic feature is the following:
-;
-;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppArguments>[,MOH_Class]]
-;
-; FeatureName -> This is the name of the feature used in when setting the
-; DYNAMIC_FEATURES variable to enable usage of this feature.
-; DTMF_sequence -> This is the key sequence used to activate this feature.
-; ActivateOn -> This is the channel of the call that the application will be executed
-; on. Valid values are "self" and "peer". "self" means run the
-; application on the same channel that activated the feature. "peer"
-; means run the application on the opposite channel from the one that
-; has activated the feature.
-; ActivatedBy -> This is which channel is allowed to activate this feature. Valid
-; values are "caller", "callee", and "both". "both" is the default.
-; The "caller" is the channel that executed the Dial application, while
-; the "callee" is the channel called by the Dial application.
-; Application -> This is the application to execute.
-; AppArguments -> These are the arguments to be passed into the application.
-; MOH_Class -> This is the music on hold class to play while the idle
-; channel waits for the feature to complete. If left blank,
-; no music will be played.
-;
-;
-; IMPORTANT NOTE: The applicationmap is not intended to be used for all Asterisk
-; applications. When applications are used in extensions.conf, they are executed
-; by the PBX core. In this case, these applications are executed outside of the
-; PBX core, so it does *not* make sense to use any application which has any
-; concept of dialplan flow. Examples of this would be things like Macro, Goto,
-; Background, WaitExten, and many more.
-;
-; Enabling these features means that the PBX needs to stay in the media flow and
-; media will not be re-directed if DTMF is sent in the media stream.
-;
-; Example Usage:
-;
-;testfeature => #9,peer,Playback,tt-monkeys ;Allow both the caller and callee to play
-; ;tt-monkeys to the opposite channel
-;
-;pauseMonitor => #1,self/callee,Pausemonitor ;Allow the callee to pause monitoring
-; ;on their channel
-;unpauseMonitor => #3,self/callee,UnPauseMonitor ;Allow the callee to unpause monitoring
-; ;on their channel
-;
diff --git a/1.4/configs/festival.conf.sample b/1.4/configs/festival.conf.sample
deleted file mode 100644
index 774f1a16c..000000000
--- a/1.4/configs/festival.conf.sample
+++ /dev/null
@@ -1,35 +0,0 @@
-;
-; Festival Configuration
-;
-[general]
-;
-; Host which runs the festival server (default : localhost);
-;
-;host=localhost
-;
-; Port on host where the festival server runs (default : 1314)
-;
-;port=1314
-;
-; Use cache (yes, no - defaults to no)
-;
-;usecache=yes
-;
-; If usecache=yes, a directory to store waveform cache files.
-; The cache is never cleared (yet), so you must take care of cleaning it
-; yourself (just delete any or all files from the cache).
-; THIS DIRECTORY *MUST* EXIST and must be writable from the asterisk process.
-; Defaults to /tmp/
-;
-;cachedir=/var/lib/asterisk/festivalcache/
-;
-; Festival command to send to the server.
-; Defaults to: (tts_textasterisk "%s" 'file)(quit)\n
-; %s is replaced by the desired text to say. The command MUST end with a
-; (quit) directive, or the cache handling mechanism will hang. Do not
-; forget the \n at the end.
-;
-;festivalcommand=(tts_textasterisk "%s" 'file)(quit)\n
-;
-;
-
diff --git a/1.4/configs/followme.conf.sample b/1.4/configs/followme.conf.sample
deleted file mode 100644
index 697e5a69c..000000000
--- a/1.4/configs/followme.conf.sample
+++ /dev/null
@@ -1,86 +0,0 @@
-; Find-Me / Follow-Me Configuration File
-[general]
-;
-featuredigittimeout=>5000
-; The number of ms to wait for a digit input for the callee on whether to take the call or
-; not before we consider them "done" entering digits.
-;
-takecall=>1
-; The global default keypress for the callee to take taking the current call. This can be
-; a single digit or multiple digits. Default is "1".
-;
-declinecall=>2
-; The global default keypress for the callee to decline taking the current call. This can
-; be a single digit or multiple digits. Default is "2".
-;
-call-from-prompt=>followme/call-from
-; The global default for the 'Incoming call from' message.
-;
-norecording-prompt=>followme/no-recording
-; The global default for the 'You have an incoming call' message when the caller elects
-; not to leave their name or the option isn't set for them to do so.
-;
-options-prompt=>followme/options
-; The global default for the 'Press 1 to accept this call or press 2 to decline it' message.
-;
-pls-hold-prompt=>followme/pls-hold-while-try
-; The global default for 'Please hold while we try and connect your call' message.
-;
-status-prompt=>followme/status
-; The global default for 'The party you're calling isn't at their desk' message.
-;
-sorry-prompt=>followme/sorry
-; The global default for 'I'm sorry, but we were unable to locate your party' message.
-;
-;
-[default]
-musicclass=>default
-; The moh class that should be used for the caller while they are waiting to be connected.
-context=>default
-; The context to dial the numbers from
-number=>01233456,25
-; The a follow-me number to call. The format is:
-; number=> <number to call[&2nd #[&3rd #]]> [, <timeout value in seconds> [, <order in follow-me>] ]
-; You can specify as many of these numbers as you like. They will be dialed in the
-; order that you specify them in the config file OR as specified with the order field
-; on the number prompt. As you can see from the example, forked dialing of multiple
-; numbers in the same step is supported with this application if you'd like to dial
-; multiple numbers in the same followme step.
-; It's also important to note that the timeout value is not the same
-; as the timeout value you would use in app_dial. This timeout value is the amount of
-; time allowed between the time the dialing step starts and the callee makes a choice
-; on whether to take the call or not. That being the case, you may want to account for
-; this time, and make this timeout longer than a timeout you might specify in app_dial.
-takecall=>1
-; The keypress for the callee to take taking the current call. This can be
-; a single digit or multiple digits. Default is the global default.
-;
-declinecall=>2
-; The keypress for the callee to decline taking the current call. This can
-; be a single digit or multiple digits. Default is the global default.
-;
-call-from-prompt=>followme/call-from
-; The 'Incoming call from' message prompt. Default is the global default.
-;
-followme-norecording-prompt=>followme/no-recording
-; The 'You have an incoming call' message prompt when the caller elects
-; not to leave their name or the option isn't set for them to do so. Default
-; is the global default.
-;
-followme-options-prompt=>followme/options
-; The 'Press 1 to accept this call or press 2 to decline it' message prompt.
-; Default is the global default.
-;
-followme-pls-hold-prompt=>followme/pls-hold-while-try
-; The 'Please hold while we try and connect your call' message prompt.
-; Default is the global default.
-;
-followme-status-prompt=>followme/status
-; The 'The party you're calling isn't at their desk' message prompt.
-; Default is the global default.
-;
-followme-sorry-prompt=>followme/sorry
-; The 'I'm sorry, but we were unable to locate your party' message prompt. Default
-; is the global default.
-
-
diff --git a/1.4/configs/func_odbc.conf.sample b/1.4/configs/func_odbc.conf.sample
deleted file mode 100644
index c9f9d5d7f..000000000
--- a/1.4/configs/func_odbc.conf.sample
+++ /dev/null
@@ -1,41 +0,0 @@
-;
-; func_odbc.conf
-;
-; Each context is a separately defined function. By convention, all
-; functions are entirely uppercase, so the defined contexts should also
-; be all-uppercase, but there is nothing that enforces this. All functions
-; are case-sensitive, however.
-;
-; For substitution, you have ${ARG1}, ${ARG2} ... ${ARGn}
-; for the arguments to each SQL statement.
-;
-; In addition, for write statements, you have ${VAL1}, ${VAL2} ... ${VALn}
-; parsed, just like arguments, for the values. In addition, if you want the
-; whole value, never mind the parsing, you can get that with ${VALUE}.
-;
-;
-; If you have data which may potentially contain single ticks, you may wish
-; to use the dialplan function SQL_ESC() to escape the data prior to its
-; inclusion in the SQL statement.
-
-
-; ODBC_SQL - Allow an SQL statement to be built entirely in the dialplan
-[SQL]
-dsn=mysql1
-read=${ARG1}
-
-; ODBC_ANTIGF - A blacklist.
-[ANTIGF]
-dsn=mysql1
-read=SELECT COUNT(*) FROM exgirlfriends WHERE callerid='${SQL_ESC(${ARG1})}'
-
-; ODBC_PRESENCE - Retrieve and update presence
-[PRESENCE]
-dsn=mysql1
-read=SELECT location FROM presence WHERE id='${SQL_ESC(${ARG1})}'
-write=UPDATE presence SET location='${SQL_ESC(${VAL1})}' WHERE id='${SQL_ESC(${ARG1})}'
-;prefix=OFFICE ; Changes this function from ODBC_PRESENCE to OFFICE_PRESENCE
-;escapecommas=no ; Normally, commas within a field are escaped such that each
- ; field may be separated into individual variables with ARRAY.
- ; This option turns that behavior off [default=yes].
-
diff --git a/1.4/configs/gtalk.conf.sample b/1.4/configs/gtalk.conf.sample
deleted file mode 100644
index da629b626..000000000
--- a/1.4/configs/gtalk.conf.sample
+++ /dev/null
@@ -1,19 +0,0 @@
-;[general]
-;context=default ;;Context to dump call into
-;allowguest=yes ;;Allow calls from people not in
- ;;list of peers
-;
-;[guest] ;;special account for options on guest account
-;disallow=all
-;allow=ulaw
-;context=guest
-;
-;[ogorman]
-;username=ogorman@gmail.com ;;username of the peer your
- ;;calling or accepting calls from
-;disallow=all
-;allow=ulaw
-;context=default
-;connection=asterisk ;;client or component in jabber.conf
- ;;for the call to leave on.
-;
diff --git a/1.4/configs/h323.conf.sample b/1.4/configs/h323.conf.sample
deleted file mode 100644
index 4b558ec0b..000000000
--- a/1.4/configs/h323.conf.sample
+++ /dev/null
@@ -1,193 +0,0 @@
-; The NuFone Network's
-; Open H.323 driver configuration
-;
-[general]
-port = 1720
-;bindaddr = 1.2.3.4 ; this SHALL contain a single, valid IP address for this machine
-;tos=lowdelay
-;
-; You may specify a global default AMA flag for iaxtel calls. It must be
-; one of 'default', 'omit', 'billing', or 'documentation'. These flags
-; are used in the generation of call detail records.
-;
-;amaflags = default
-;
-; You may specify a default account for Call Detail Records in addition
-; to specifying on a per-user basis
-;
-;accountcode=lss0101
-;
-; You can fine tune codecs here using "allow" and "disallow" clauses
-; with specific codecs. Use "all" to represent all formats.
-;
-;disallow=all
-;allow=all ; turns on all installed codecs
-;disallow=g723.1 ; Hm... Proprietary, don't use it...
-;allow=gsm ; Always allow GSM, it's cool :)
-;allow=ulaw ; see doc/rtp-packetization for framing options
-;
-; User-Input Mode (DTMF)
-;
-; valid entries are: rfc2833, inband
-; default is rfc2833
-;dtmfmode=rfc2833
-;
-; Default RTP Payload to send RFC2833 DTMF on. This is used to
-; interoperate with broken gateways which cannot successfully
-; negotiate a RFC2833 payload type in the TerminalCapabilitySet.
-;
-; You may also specify on either a per-peer or per-user basis below.
-;dtmfcodec=101
-;
-; Set the gatekeeper
-; DISCOVER - Find the Gk address using multicast
-; DISABLE - Disable the use of a GK
-; <IP address> or <Host name> - The acutal IP address or hostname of your GK
-;gatekeeper = DISABLE
-;
-;
-; Tell Asterisk whether or not to accept Gatekeeper
-; routed calls or not. Normally this should always
-; be set to yes, unless you want to have finer control
-; over which users are allowed access to Asterisk.
-; Default: YES
-;
-;AllowGKRouted = yes
-;
-; When the channel works without gatekeeper, there is possible to
-; reject calls from anonymous (not listed in users) callers.
-; Default is to allow anonymous calls.
-;
-;AcceptAnonymous = yes
-;
-; Optionally you can determine a user by Source IP versus its H.323 alias.
-; Default behavour is to determine user by H.323 alias.
-;
-;UserByAlias=no
-;
-; Default context gets used in siutations where you are using
-; the GK routed model or no type=user was found. This gives you
-; the ability to either play an invalid message or to simply not
-; use user authentication at all.
-;
-;context=default
-;
-; Use this option to help Cisco (or other) gateways to setup backward voice
-; path to pass inband tones to calling user (see, for example,
-; http://www.cisco.com/warp/public/788/voip/ringback.html)
-;
-; Add PROGRESS information element to SETUP message sent on outbound calls
-; to notify about required backward voice path. Valid values are:
-; 0 - don't add PROGRESS information element (default);
-; 1 - call is not end-end ISDN, further call progress information can
-; possibly be available in-band;
-; 3 - origination address is non-ISDN (Cisco accepts this value only);
-; 8 - in-band information or an appropriate pattern is now available;
-;progress_setup = 3
-;
-; Add PROGRESS information element (IE) to ALERT message sent on incoming
-; calls to notify about required backwared voice path. Valid values are:
-; 0 - don't add PROGRESS IE (default);
-; 8 - in-band information or an appropriate pattern is now available;
-;progress_alert = 8
-;
-; Generate PROGRESS message when H.323 audio path has established to create
-; backward audio path at other end of a call.
-;progress_audio = yes
-;
-; Specify how to inject non-standard information into H.323 messages. When
-; the channel receives messages with tunneled information, it automatically
-; enables the same option for all further outgoing messages independedly on
-; options has been set by the configuration. This behavior is required, for
-; example, for Cisco CallManager when Q.SIG tunneling is enabled for a
-; gateway where Asterisk lives.
-; The option can be used multiple times, one option per line.
-;tunneling=none ; Totally disable tunneling (default)
-;tunneling=cisco ; Enable Cisco-specific tunneling
-;tunneling=qsig ; Enable tunneling via Q.SIG messages
-;
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
-; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
- ; H323 channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The H323 channel can accept jitter,
- ; thus an enabled jitterbuffer on the receive H323 side will only
- ; be used if the sending side can create jitter and jbforce is
- ; also set to yes.
-
-; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a H323
- ; channel. Defaults to "no".
-
-; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
-; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usualy sent from exotic devices
- ; and programs. Defaults to 1000.
-
-; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a H323
- ; channel. Two implementations are currenlty available - "fixed"
- ; (with size always equals to jbmax-size) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
-; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
-;
-; H.323 Alias definitions
-;
-; Type 'h323' will register aliases to the endpoint
-; and Gatekeeper, if there is one.
-;
-; Example: if someone calls time@your.asterisk.box.com
-; Asterisk will send the call to the extension 'time'
-; in the context default
-;
-; [default]
-; exten => time,1,Answer
-; exten => time,2,Playback,current-time
-;
-; Keyword's 'prefix' and 'e164' are only make sense when
-; used with a gatekeeper. You can specify either a prefix
-; or E.164 this endpoint is responsible for terminating.
-;
-; Example: The H.323 alias 'det-gw' will tell the gatekeeper
-; to route any call with the prefix 1248 to this alias. Keyword
-; e164 is used when you want to specifiy a full telephone
-; number. So a call to the number 18102341212 would be
-; routed to the H.323 alias 'time'.
-;
-;[time]
-;type=h323
-;e164=18102341212
-;context=default
-;
-;[det-gw]
-;type=h323
-;prefix=1248,1313
-;context=detroit
-;
-;
-; Inbound H.323 calls from BillyBob would land in the incoming
-; context with a maximum of 4 concurrent incoming calls
-;
-;
-; Note: If keyword 'incominglimit' are omitted Asterisk will not
-; enforce any maximum number of concurrent calls.
-;
-;[BillyBob]
-;type=user
-;host=192.168.1.1
-;context=incoming
-;incominglimit=4
-;h245Tunneling=no
-;
-;
-; Outbound H.323 call to Larry using SlowStart
-;
-;[Larry]
-;type=peer
-;host=192.168.2.1
-;fastStart=no
-
-
-
diff --git a/1.4/configs/http.conf.sample b/1.4/configs/http.conf.sample
deleted file mode 100644
index f8a86f85a..000000000
--- a/1.4/configs/http.conf.sample
+++ /dev/null
@@ -1,40 +0,0 @@
-;
-; Asterisk Builtin mini-HTTP server
-;
-;
-[general]
-;
-; Whether HTTP interface is enabled or not. Default is no.
-;
-;enabled=yes
-;
-; Whether Asterisk should serve static content from http-static
-; Default is no.
-;
-;enablestatic=yes
-;
-; Address to bind to. Default is 0.0.0.0
-;
-bindaddr=127.0.0.1
-;
-; Port to bind to (default is 8088)
-;
-bindport=8088
-;
-; Prefix allows you to specify a prefix for all requests
-; to the server. The default is "asterisk" so that all
-; requests must begin with /asterisk
-;
-;prefix=asterisk
-
-; The post_mappings section maps URLs to real paths on the filesystem. If a
-; POST is done from within an authenticated manager session to one of the
-; configured POST mappings, then any files in the POST will be placed in the
-; configured directory.
-;
-;[post_mappings]
-;
-; In this example, if the prefix option is set to "asterisk", then using the
-; POST URL: /asterisk/uploads will put files in /var/lib/asterisk/uploads/.
-;uploads = /var/lib/asterisk/uploads/
-;
diff --git a/1.4/configs/iax.conf.sample b/1.4/configs/iax.conf.sample
deleted file mode 100644
index cd4b8751a..000000000
--- a/1.4/configs/iax.conf.sample
+++ /dev/null
@@ -1,406 +0,0 @@
-
-; Inter-Asterisk eXchange driver definition
-;
-; This configuration is re-read at reload
-; or with the CLI command
-; reload chan_iax2.so
-;
-; General settings, like port number to bind to, and
-; an option address (the default is to bind to all
-; local addresses).
-;
-[general]
-;bindport=4569 ; bindport and bindaddr may be specified
-; ; NOTE: bindport must be specified BEFORE
- ; bindaddr or may be specified on a specific
- ; bindaddr if followed by colon and port
- ; (e.g. bindaddr=192.168.0.1:4569)
-;bindaddr=192.168.0.1 ; more than once to bind to multiple
-; ; addresses, but the first will be the
-; ; default
-;
-; Set iaxcompat to yes if you plan to use layered switches or
-; some other scenario which may cause some delay when doing a
-; lookup in the dialplan. It incurs a small performance hit to
-; enable it. This option causes Asterisk to spawn a separate thread
-; when it receives an IAX DPREQ (Dialplan Request) instead of
-; blocking while it waits for a response.
-;
-;iaxcompat=yes
-;
-; Disable UDP checksums (if nochecksums is set, then no checkums will
-; be calculated/checked on systems supporting this feature)
-;
-;nochecksums=no
-;
-;
-; For increased security against brute force password attacks
-; enable "delayreject" which will delay the sending of authentication
-; reject for REGREQ or AUTHREP if there is a password.
-;
-;delayreject=yes
-;
-; You may specify a global default AMA flag for iaxtel calls. It must be
-; one of 'default', 'omit', 'billing', or 'documentation'. These flags
-; are used in the generation of call detail records.
-;
-;amaflags=default
-;
-; ADSI (Analog Display Services Interface) can be enabled if you have
-; (or may have) ADSI compatible CPE equipment
-;
-;adsi=no
-;
-; You may specify a default account for Call Detail Records in addition
-; to specifying on a per-user basis
-;
-;accountcode=lss0101
-;
-; You may specify a global default language for users.
-; Can be specified also on a per-user basis
-; If omitted, will fallback to english
-;
-;language=en
-;
-; This option specifies a preference for which music on hold class this channel
-; should listen to when put on hold if the music class has not been set on the
-; channel with Set(CHANNEL(musicclass)=whatever) in the dialplan, and the peer
-; channel putting this one on hold did not suggest a music class.
-;
-; If this option is set to "passthrough", then the hold message will always be
-; passed through as signalling instead of generating hold music locally.
-;
-; This option may be specified globally, or on a per-user or per-peer basis.
-;
-;mohinterpret=default
-;
-; This option specifies which music on hold class to suggest to the peer channel
-; when this channel places the peer on hold. It may be specified globally or on
-; a per-user or per-peer basis.
-;
-;mohsuggest=default
-;
-; Specify bandwidth of low, medium, or high to control which codecs are used
-; in general.
-;
-bandwidth=low
-;
-; You can also fine tune codecs here using "allow" and "disallow" clauses
-; with specific codecs. Use "all" to represent all formats.
-;
-;allow=all ; same as bandwidth=high
-;disallow=g723.1 ; Hm... Proprietary, don't use it...
-disallow=lpc10 ; Icky sound quality... Mr. Roboto.
-;allow=gsm ; Always allow GSM, it's cool :)
-;
-
-; You can adjust several parameters relating to the jitter buffer.
-; The jitter buffer's function is to compensate for varying
-; network delay.
-;
-; All the jitter buffer settings are in milliseconds.
-; The jitter buffer works for INCOMING audio - the outbound audio
-; will be dejittered by the jitter buffer at the other end.
-;
-; jitterbuffer=yes|no: global default as to whether you want
-; the jitter buffer at all.
-;
-; forcejitterbuffer=yes|no: in the ideal world, when we bridge VoIP channels
-; we don't want to do jitterbuffering on the switch, since the endpoints
-; can each handle this. However, some endpoints may have poor jitterbuffers
-; themselves, so this option will force * to always jitterbuffer, even in this
-; case.
-;
-; maxjitterbuffer: a maximum size for the jitter buffer.
-; Setting a reasonable maximum here will prevent the call delay
-; from rising to silly values in extreme situations; you'll hear
-; SOMETHING, even though it will be jittery.
-;
-; resyncthreshold: when the jitterbuffer notices a significant change in delay
-; that continues over a few frames, it will resync, assuming that the change in
-; delay was caused by a timestamping mix-up. The threshold for noticing a
-; change in delay is measured as twice the measured jitter plus this resync
-; threshold.
-; Resyncing can be disabled by setting this parameter to -1.
-;
-; maxjitterinterps: the maximum number of interpolation frames the jitterbuffer
-; should return in a row. Since some clients do not send CNG/DTX frames to
-; indicate silence, the jitterbuffer will assume silence has begun after
-; returning this many interpolations. This prevents interpolating throughout
-; a long silence.
-;
-
-jitterbuffer=no
-forcejitterbuffer=no
-;maxjitterbuffer=1000
-;maxjitterinterps=10
-;resyncthreshold=1000
-
-;trunkfreq=20 ; How frequently to send trunk msgs (in ms)
-
-; Should we send timestamps for the individual sub-frames within trunk frames?
-; There is a small bandwidth use for these (less than 1kbps/call), but they
-; ensure that frame timestamps get sent end-to-end properly. If both ends of
-; all your trunks go directly to TDM, _and_ your trunkfreq equals the frame
-; length for your codecs, you can probably suppress these. The receiver must
-; also support this feature, although they do not also need to have it enabled.
-;
-; trunktimestamps=yes
-;
-; Minimum and maximum amounts of time that IAX peers can request as
-; a registration expiration interval (in seconds).
-; minregexpire = 60
-; maxregexpire = 60
-;
-; IAX helper threads
-; Establishes the number of iax helper threads to handle I/O.
-; iaxthreadcount = 10
-; Establishes the number of extra dynamic threads that may be spawned to handle I/O
-; iaxmaxthreadcount = 100
-;
-; We can register with another IAX server to let him know where we are
-; in case we have a dynamic IP address for example
-;
-; Register with tormenta using username marko and password secretpass
-;
-;register => marko:secretpass@tormenta.linux-support.net
-;
-; Register joe at remote host with no password
-;
-;register => joe@remotehost:5656
-;
-; Register marko at tormenta.linux-support.net using RSA key "torkey"
-;
-;register => marko:[torkey]@tormenta.linux-support.net
-;
-; Sample Registration for iaxtel
-;
-; Visit http://www.iaxtel.com to register with iaxtel. Replace "user"
-; and "pass" with your username and password for iaxtel. Incoming
-; calls arrive at the "s" extension of "default" context.
-;
-;register => user:pass@iaxtel.com
-;
-; Sample Registration for IAX + FWD
-;
-; To register using IAX with FWD, it must be enabled by visiting the URL
-; http://www.fwdnet.net/index.php?section_id=112
-;
-; Note that you need an extension in you default context which matches
-; your free world dialup number. Please replace "FWDNumber" with your
-; FWD number and "passwd" with your password.
-;
-;register => FWDNumber:passwd@iax.fwdnet.net
-;
-;
-; You can disable authentication debugging to reduce the amount of
-; debugging traffic.
-;
-;authdebug=no
-;
-; See doc/ip-tos.txt for a description of the tos parameters.
-;tos=ef
-;
-; If regcontext is specified, Asterisk will dynamically create and destroy
-; a NoOp priority 1 extension for a given peer who registers or unregisters
-; with us. The actual extension is the 'regexten' parameter of the registering
-; peer or its name if 'regexten' is not provided. More than one regexten
-; may be supplied if they are separated by '&'. Patterns may be used in
-; regexten.
-;
-;regcontext=iaxregistrations
-;
-; If we don't get ACK to our NEW within 2000ms, and autokill is set to yes,
-; then we cancel the whole thing (that's enough time for one retransmission
-; only). This is used to keep things from stalling for a long time for a host
-; that is not available, but would be ill advised for bad connections. In
-; addition to 'yes' or 'no' you can also specify a number of milliseconds.
-; See 'qualify' for individual peers to turn on for just a specific peer.
-;
-autokill=yes
-;
-; codecpriority controls the codec negotiation of an inbound IAX call.
-; This option is inherited to all user entities. It can also be defined
-; in each user entity separately which will override the setting in general.
-;
-; The valid values are:
-;
-; caller - Consider the callers preferred order ahead of the host's.
-; host - Consider the host's preferred order ahead of the caller's.
-; disabled - Disable the consideration of codec preference altogether.
-; (this is the original behaviour before preferences were added)
-; reqonly - Same as disabled, only do not consider capabilities if
-; the requested format is not available the call will only
-; be accepted if the requested format is available.
-;
-; The default value is 'host'
-;
-;codecpriority=host
-
-;rtcachefriends=yes ; Cache realtime friends by adding them to the internal list
- ; just like friends added from the config file only on a
- ; as-needed basis? (yes|no)
-
-;rtupdate=yes ; Send registry updates to database using realtime? (yes|no)
- ; If set to yes, when a IAX2 peer registers successfully,
- ; the ip address, the origination port, the registration period,
- ; and the username of the peer will be set to database via realtime.
- ; If not present, defaults to 'yes'.
-
-;rtautoclear=yes ; Auto-Expire friends created on the fly on the same schedule
- ; as if it had just registered? (yes|no|<seconds>)
- ; If set to yes, when the registration expires, the friend will
- ; vanish from the configuration until requested again.
- ; If set to an integer, friends expire within this number of
- ; seconds instead of the registration interval.
-
-;rtignoreregexpire=yes ; When reading a peer from Realtime, if the peer's registration
- ; has expired based on its registration interval, used the stored
- ; address information regardless. (yes|no)
-
-; Guest sections for unauthenticated connection attempts. Just specify an
-; empty secret, or provide no secret section.
-;
-[guest]
-type=user
-context=default
-callerid="Guest IAX User"
-
-;
-; Trust Caller*ID Coming from iaxtel.com
-;
-[iaxtel]
-type=user
-context=default
-auth=rsa
-inkeys=iaxtel
-
-;
-; Trust Caller*ID Coming from iax.fwdnet.net
-;
-[iaxfwd]
-type=user
-context=default
-auth=rsa
-inkeys=freeworlddialup
-
-;
-; Trust callerid delivered over DUNDi/e164
-;
-;
-;[dundi]
-;type=user
-;dbsecret=dundi/secret
-;context=dundi-e164-local
-
-;
-; Further user sections may be added, specifying a context and a secret used
-; for connections with that given authentication name. Limited IP based
-; access control is allowed by use of "allow" and "deny" keywords. Multiple
-; rules are permitted. Multiple permitted contexts may be specified, in
-; which case the first will be the default. You can also override caller*ID
-; so that when you receive a call you set the Caller*ID to be what you want
-; instead of trusting what the remote user provides
-;
-; There are three authentication methods that are supported: md5, plaintext,
-; and rsa. The least secure is "plaintext", which sends passwords cleartext
-; across the net. "md5" uses a challenge/response md5 sum arrangement, but
-; still requires both ends have plain text access to the secret. "rsa" allows
-; unidirectional secret knowledge through public/private keys. If "rsa"
-; authentication is used, "inkeys" is a list of acceptable public keys on the
-; local system that can be used to authenticate the remote peer, separated by
-; the ":" character. "outkey" is a single, private key to use to authenticate
-; to the other side. Public keys are named /var/lib/asterisk/keys/<name>.pub
-; while private keys are named /var/lib/asterisk/keys/<name>.key. Private
-; keys should always be 3DES encrypted.
-;
-;
-; NOTE: All hostnames and IP addresses in this file are for example purposes
-; only; you should not expect any of them to actually be available for
-; your use.
-;
-;
-;[markster]
-;type=user
-;context=default
-;context=local
-;auth=md5,plaintext,rsa
-;secret=markpasswd
-;setvar=foo=bar
-;dbsecret=mysecrets/place ; Secrets can be stored in astdb, too
-;transfer=no ; Disable IAX native transfer
-;transfer=mediaonly ; When doing IAX native transfers, transfer
- ; only media stream
-;jitterbuffer=yes ; Override global setting an enable jitter buffer
-; ; for this user
-;maxauthreq=10 ; Set maximum number of outstanding AUTHREQs waiting for replies. Any further authentication attempts will be blocked
-; ; if this limit is reached until they expire or a reply is received.
-;callerid="Mark Spencer" <(256) 428-6275>
-;deny=0.0.0.0/0.0.0.0
-;accountcode=markster0101
-;permit=209.16.236.73/255.255.255.0
-;language=en ; Use english as default language
-;
-; Peers may also be specified, with a secret and
-; a remote hostname.
-;
-[demo]
-type=peer
-username=asterisk
-secret=supersecret
-host=216.207.245.47
-;sendani=no
-;host=asterisk.linux-support.net
-;port=5036
-;mask=255.255.255.255
-;qualify=yes ; Make sure this peer is alive
-;qualifysmoothing = yes ; use an average of the last two PONG
- ; results to reduce falsely detected LAGGED hosts
- ; Default: Off
-;qualifyfreqok = 60000 ; how frequently to ping the peer when
- ; everything seems to be ok, in milliseconds
-;qualifyfreqnotok = 10000 ; how frequently to ping the peer when it's
- ; either LAGGED or UNAVAILABLE, in milliseconds
-;jitterbuffer=no ; Turn off jitter buffer for this peer
-
-;
-; Peers can remotely register as well, so that they can be mobile. Default
-; IP's can also optionally be given but are not required. Caller*ID can be
-; suggested to the other side as well if it is for example a phone instead of
-; another PBX.
-;
-
-;[dynamichost]
-;host=dynamic
-;secret=mysecret
-;mailbox=1234 ; Notify about mailbox 1234
-;inkeys=key1:key2
-;peercontext=local ; Default context to request for calls to peer
-;defaultip=216.207.245.34
-;callerid="Some Host" <(256) 428-6011>
-;
-
-;
-;[biggateway]
-;type=peer
-;host=192.168.0.1
-;context=*
-;secret=myscret
-;trunk=yes ; Use IAX2 trunking with this host
-;timezone=America/New_York ; Set a timezone for the date/time IE
-;
-
-;
-; Friends are a short cut for creating a user and
-; a peer with the same values.
-;
-;[marko]
-;type=friend
-;host=dynamic
-;regexten=1234
-;secret=moofoo ; Multiple secrets may be specified. For a "user", all
-;secret=foomoo ; specified entries will be accepted as valid. For a "peer",
-;secret=shazbot ; only the last specified secret will be used.
-;context=default
-;permit=0.0.0.0/0.0.0.0
-
diff --git a/1.4/configs/iaxprov.conf.sample b/1.4/configs/iaxprov.conf.sample
deleted file mode 100644
index 0ed1ff8e4..000000000
--- a/1.4/configs/iaxprov.conf.sample
+++ /dev/null
@@ -1,81 +0,0 @@
-;
-; IAX2 Provisioning Information
-;
-; Contains provisioning information for templates and for specific service
-; entries.
-;
-; Templates provide a group of settings from which provisioning takes place.
-; A template may be based upon any template that has been specified before
-; it. If the template that an entry is based on is not specified then it is
-; presumed to be 'default' (unless it is the first of course).
-;
-; Templates which begin with 'si-' are used for provisioning units with
-; specific service identifiers. For example the entry "si-000364000126"
-; would be used when the device with the corresponding service identifier of
-; "000364000126" attempts to register or make a call.
-;
-[default]
-;
-; The port number the device should use to bind to. The default is 4569.
-;
-;port=4569
-;
-; server is our PRIMARY server for registration and placing calls
-;
-;server=192.168.69.3
-;
-; altserver is the BACKUP server for registration and placing calls in the
-; event the primary server is unavailable.
-;
-;altserver=192.168.69.4
-;
-; port is the port number to use for IAX2 outbound. The connections to the
-; server and altserver -- default is of course 4569.
-;serverport=4569
-;
-; language is the preferred language for the device
-;
-;language=en
-;
-; codec is the requested codec. The iaxy supports ulaw and adpcm
-;
-codec=ulaw
-;
-; flags is a comma separated list of flags which the device should
-; use and may contain any of the following keywords:
-;
-; "register" - Register with server
-; "secure" - Do not accept calls / provisioning not originated by the server
-; "heartbeat" - Generate status packets on port 9999 sent to 255.255.255.255
-; "debug" - Output extra debugging to port 9999
-;
-; Note that use can use += and -= to adjust parameters
-;
-flags=register,heartbeat
-;
-; See doc/ip-tos.txt for a description of this parameter.
-;tos=ef
-;
-; Example iaxy provisioning
-;
-;[si-000364000126]
-;user=iaxy
-;pass=bitsy
-;flags += debug
-
-;[si-000364000127]
-;user=iaxy2
-;pass=bitsy2
-;template=si-000364000126
-;flags += debug
-
-;
-;[*]
-;
-; If specified, the '*' provisioning is used for all devices which do not
-; have another provisioning entry within the file. If unspecified, no
-; provisioning will take place for devices which have no entry. DO NOT
-; USE A '*' PROVISIONING ENTRY UNLESS YOU KNOW WHAT YOU'RE DOING.
-;
-;template=default
-
diff --git a/1.4/configs/indications.conf.sample b/1.4/configs/indications.conf.sample
deleted file mode 100644
index 03a3fadb5..000000000
--- a/1.4/configs/indications.conf.sample
+++ /dev/null
@@ -1,733 +0,0 @@
-; indications.conf
-; Configuration file for location specific tone indications
-; used by the pbx_indications module.
-;
-; NOTE:
-; When adding countries to this file, please keep them in alphabetical
-; order according to the 2-character country codes!
-;
-; The [general] category is for certain global variables.
-; All other categories are interpreted as location specific indications
-;
-;
-[general]
-country=us ; default location
-
-
-; [example]
-; description = string
-; The full name of your country, in English.
-; alias = iso[,iso]*
-; List of other countries 2-letter iso codes, which have the same
-; tone indications.
-; ringcadence = num[,num]*
-; List of durations the physical bell rings.
-; dial = tonelist
-; Set of tones to be played when one picks up the hook.
-; busy = tonelist
-; Set of tones played when the receiving end is busy.
-; congestion = tonelist
-; Set of tones played when there is some congestion (on the network?)
-; callwaiting = tonelist
-; Set of tones played when there is a call waiting in the background.
-; dialrecall = tonelist
-; Not well defined; many phone systems play a recall dial tone after hook
-; flash.
-; record = tonelist
-; Set of tones played when call recording is in progress.
-; info = tonelist
-; Set of tones played with special information messages (e.g., "number is
-; out of service")
-; 'name' = tonelist
-; Every other variable will be available as a shortcut for the "PlayList" command
-; but will not be used automatically by Asterisk.
-;
-;
-; The tonelist itself is defined by a comma-separated sequence of elements.
-; Each element consist of a frequency (f) with an optional duration (in ms)
-; attached to it (f/duration). The frequency component may be a mixture of two
-; frequencies (f1+f2) or a frequency modulated by another frequency (f1*f2).
-; The implicit modulation depth is fixed at 90%, though.
-; If the list element starts with a !, that element is NOT repeated,
-; therefore, only if all elements start with !, the tonelist is time-limited,
-; all others will repeat indefinitely.
-;
-; concisely:
-; element = [!]freq[+|*freq2][/duration]
-; tonelist = element[,element]*
-;
-; Please note that SPACES ARE NOT ALLOWED in tone lists!
-;
-
-[at]
-description = Austria
-ringcadence = 1000,5000
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-dial = 420
-busy = 420/400,0/400
-ring = 420/1000,0/5000
-congestion = 420/200,0/200
-callwaiting = 420/40,0/1960
-dialrecall = 420
-; RECORDTONE - not specified
-record = 1400/80,0/14920
-info = 950/330,1450/330,1850/330,0/1000
-stutter = 380+420
-
-[au]
-description = Australia
-; Reference http://www.acif.org.au/__data/page/3303/S002_2001.pdf
-; Normal Ring
-ringcadence = 400,200,400,2000
-; Distinctive Ring 1 - Forwarded Calls
-; 400,400,200,200,400,1400
-; Distinctive Ring 2 - Selective Ring 2 + Operator + Recall
-; 400,400,200,2000
-; Distinctive Ring 3 - Multiple Subscriber Number 1
-; 200,200,400,2200
-; Distinctive Ring 4 - Selective Ring 1 + Centrex
-; 400,2600
-; Distinctive Ring 5 - Selective Ring 3
-; 400,400,200,400,200,1400
-; Distinctive Ring 6 - Multiple Subscriber Number 2
-; 200,400,200,200,400,1600
-; Distinctive Ring 7 - Multiple Subscriber Number 3 + Data Privacy
-; 200,400,200,400,200,1600
-; Tones
-dial = 413+438
-busy = 425/375,0/375
-ring = 413+438/400,0/200,413+438/400,0/2000
-; XXX Congestion: Should reduce by 10 db every other cadence XXX
-congestion = 425/375,0/375,420/375,0/375
-callwaiting = 425/200,0/200,425/200,0/4400
-dialrecall = 413+438
-; Record tone used for Call Intrusion/Recording or Conference
-record = !425/1000,!0/15000,425/360,0/15000
-info = 425/2500,0/500
-; Other Australian Tones
-; The STD "pips" indicate the call is not an untimed local call
-std = !525/100,!0/100,!525/100,!0/100,!525/100,!0/100,!525/100,!0/100,!525/100
-; Facility confirmation tone (eg. Call Forward Activated)
-facility = 425
-; Message Waiting "stutter" dialtone
-stutter = 413+438/100,0/40
-; Ringtone for calls to Telstra mobiles
-ringmobile = 400+450/400,0/200,400+450/400,0/2000
-
-[bg]
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-description = Bulgaria
-ringdance = 1000,4000
-;
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/250,0/250
-callwaiting = 425/150,0/150,425/150,0/4000
-dialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-record = 1400/425,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-stutter = 425/1500,0/100
-
-[br]
-description = Brazil
-ringcadence = 1000,4000
-dial = 425
-busy = 425/250,0/250
-ring = 425/1000,0/4000
-congestion = 425/250,0/250,425/750,0/250
-callwaiting = 425/50,0/1000
-; Dialrecall not used in Brazil standard (using UK standard)
-dialrecall = 350+440
-; Record tone is not used in Brazil, use busy tone
-record = 425/250,0/250
-; Info not used in Brazil standard (using UK standard)
-info = 950/330,1400/330,1800/330
-stutter = 350+440
-
-[be]
-description = Belgium
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,3000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/3000
-congestion = 425/167,0/167
-callwaiting = 1400/175,0/175,1400/175,0/3500
-; DIALRECALL - not specified
-dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440"
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-info = 900/330,1400/330,1800/330,0/1000
-stutter = 425/1000,0/250
-
-[ch]
-description = Switzerland
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = 425/200,0/200,425/200,0/4000
-; DIALRECALL - not specified
-dialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-; RECORDTONE - not specified
-record = 1400/80,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-stutter = 425+340/1100,0/1100
-
-[cl]
-description = Chile
-; According to specs from Telefonica CTC Chile
-ringcadence = 1000,3000
-dial = 400
-busy = 400/500,0/500
-ring = 400/1000,0/3000
-congestion = 400/200,0/200
-callwaiting = 400/250,0/8750
-dialrecall = !400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400
-record = 1400/500,0/15000
-info = 950/333,1400/333,1800/333,0/1000
-stutter = !400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400
-
-[cn]
-description = China
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 450
-busy = 450/350,0/350
-ring = 450/1000,0/4000
-congestion = 450/700,0/700
-callwaiting = 450/400,0/4000
-dialrecall = 450
-record = 950/400,0/10000
-info = 450/100,0/100,450/100,0/100,450/100,0/100,450/400,0/400
-; STUTTER - not specified
-stutter = 450+425
-
-[cz]
-description = Czech Republic
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 425/330,0/330,425/660,0/660
-busy = 425/330,0/330
-ring = 425/1000,0/4000
-congestion = 425/165,0/165
-callwaiting = 425/330,0/9000
-; DIALRECALL - not specified
-dialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660
-; RECORDTONE - not specified
-record = 1400/500,0/14000
-info = 950/330,0/30,1400/330,0/30,1800/330,0/1000
-; STUTTER - not specified
-stutter = 425/450,0/50
-
-[de]
-description = Germany
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 425
-busy = 425/480,0/480
-ring = 425/1000,0/4000
-congestion = 425/240,0/240
-callwaiting = !425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,0
-; DIALRECALL - not specified
-dialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-; RECORDTONE - not specified
-record = 1400/80,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-stutter = 425+400
-
-[dk]
-description = Denmark
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = !425/200,!0/600,!425/200,!0/3000,!425/200,!0/200,!425/200,0
-; DIALRECALL - not specified
-dialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-; RECORDTONE - not specified
-record = 1400/80,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-; STUTTER - not specified
-stutter = 425/450,0/50
-
-[ee]
-description = Estonia
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 425
-busy = 425/300,0/300
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-; CALLWAIT not in accordance to ITU
-callwaiting = 950/650,0/325,950/325,0/30,1400/1300,0/2600
-; DIALRECALL - not specified
-dialrecall = 425/650,0/25
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-; INFO not in accordance to ITU
-info = 950/650,0/325,950/325,0/30,1400/1300,0/2600
-; STUTTER not specified
-stutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-
-[es]
-description = Spain
-ringcadence = 1500,3000
-dial = 425
-busy = 425/200,0/200
-ring = 425/1500,0/3000
-congestion = 425/200,0/200,425/200,0/200,425/200,0/600
-callwaiting = 425/175,0/175,425/175,0/3500
-dialrecall = !425/200,!0/200,!425/200,!0/200,!425/200,!0/200,425
-record = 1400/500,0/15000
-info = 950/330,0/1000
-dialout = 500
-
-
-[fi]
-description = Finland
-ringcadence = 1000,4000
-dial = 425
-busy = 425/300,0/300
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = 425/150,0/150,425/150,0/8000
-dialrecall = 425/650,0/25
-record = 1400/500,0/15000
-info = 950/650,0/325,950/325,0/30,1400/1300,0/2600
-stutter = 425/650,0/25
-
-[fr]
-description = France
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1500,3500
-; Dialtone can also be 440+330
-dial = 440
-busy = 440/500,0/500
-ring = 440/1500,0/3500
-; CONGESTION - not specified
-congestion = 440/250,0/250
-callwait = 440/300,0/10000
-; DIALRECALL - not specified
-dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330
-stutter = !440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,440
-
-[gr]
-description = Greece
-ringcadence = 1000,4000
-dial = 425/200,0/300,425/700,0/800
-busy = 425/300,0/300
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = 425/150,0/150,425/150,0/8000
-dialrecall = 425/650,0/25
-record = 1400/400,0/15000
-info = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0
-stutter = 425/650,0/25
-
-[hu]
-description = Hungary
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1250,3750
-dial = 425
-busy = 425/300,0/300
-ring = 425/1250,0/3750
-congestion = 425/300,0/300
-callwaiting = 425/40,0/1960
-dialrecall = 425+450
-; RECORDTONE - not specified
-record = 1400/400,0/15000
-info = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0
-stutter = 350+375+400
-
-[il]
-description = Israel
-ringcadence = 1000,3000
-dial = 414
-busy = 414/500,0/500
-ring = 414/1000,0/3000
-congestion = 414/250,0/250
-callwaiting = 414/100,0/100,414/100,0/100,414/600,0/3000
-dialrecall = !414/100,!0/100,!414/100,!0/100,!414/100,!0/100,414
-record = 1400/500,0/15000
-info = 1000/330,1400/330,1800/330,0/1000
-stutter = !414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,414
-
-
-[in]
-description = India
-ringcadence = 400,200,400,2000
-dial = 400*25
-busy = 400/750,0/750
-ring = 400*25/400,0/200,400*25/400,0/2000
-congestion = 400/250,0/250
-callwaiting = 400/200,0/100,400/200,0/7500
-dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330,0/1000
-stutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-
-[it]
-description = Italy
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-dial = 425/200,0/200,425/600,0/1000
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = 425/400,0/100,425/250,0/100,425/150,0/14000
-dialrecall = 470/400,425/400
-record = 1400/400,0/15000
-info = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0
-stutter = 470/400,425/400
-
-[lt]
-description = Lithuania
-ringcadence = 1000,4000
-dial = 425
-busy = 425/350,0/350
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = 425/150,0/150,425/150,0/4000
-; DIALRECALL - not specified
-dialrecall = 425/500,0/50
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0
-; STUTTER - not specified
-stutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-
-[jp]
-description = Japan
-ringcadence = 1000,2000
-dial = 400
-busy = 400/500,0/500
-ring = 400+15/1000,0/2000
-congestion = 400/500,0/500
-callwaiting = 400+16/500,0/8000
-dialrecall = !400/200,!0/200,!400/200,!0/200,!400/200,!0/200,400
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330,0
-stutter = !400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400
-
-[mx]
-description = Mexico
-ringcadence = 2000,4000
-dial = 425
-busy = 425/250,0/250
-ring = 425/1000,0/4000
-congestion = 425/250,0/250
-callwaiting = 425/200,0/600,425/200,0/10000
-dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-record = 1400/500,0/15000
-info = 950/330,0/30,1400/330,0/30,1800/330,0/1000
-stutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-
-[my]
-description = Malaysia
-ringcadence = 2000,4000
-dial = 425
-busy = 425/500,0/500
-ring = 425/400,0/200
-congestion = 425/500,0/500
-
-[nl]
-description = Netherlands
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-ringcadence = 1000,4000
-; Most of these 425's can also be 450's
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/250,0/250
-callwaiting = 425/500,0/9500
-; DIALRECALL - not specified
-dialrecall = 425/500,0/50
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-stutter = 425/500,0/50
-
-[no]
-description = Norway
-ringcadence = 1000,4000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/200,0/200
-callwaiting = 425/200,0/600,425/200,0/10000
-dialrecall = 470/400,425/400
-record = 1400/400,0/15000
-info = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0
-stutter = 470/400,425/400
-
-[nz]
-description = New Zealand
-;NOTE - the ITU has different tonesets for NZ, but according to some residents there,
-; this is, indeed, the correct way to do it.
-ringcadence = 400,200,400,2000
-dial = 400
-busy = 400/250,0/250
-ring = 400+450/400,0/200,400+450/400,0/2000
-congestion = 400/375,0/375
-callwaiting = !400/200,!0/3000,!400/200,!0/3000,!400/200,!0/3000,!400/200
-dialrecall = !400/100!0/100,!400/100,!0/100,!400/100,!0/100,400
-record = 1400/425,0/15000
-info = 400/750,0/100,400/750,0/100,400/750,0/100,400/750,0/400
-stutter = !400/100!0/100,!400/100,!0/100,!400/100,!0/100,!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400
-unobtainable = 400/75,0/100,400/75,0/100,400/75,0/100,400/75,0/400
-
-[ph]
-
-; reference http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-
-description = Philippines
-ringcadence = 1000,4000
-dial = 425
-busy = 480+620/500,0/500
-ring = 425+480/1000,0/4000
-congestion = 480+620/250,0/250
-callwaiting = 440/300,0/10000
-; DIALRECALL - not specified
-dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-; INFO - not specified
-info = !950/330,!1400/330,!1800/330,0
-; STUTTER - not specified
-stutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-
-
-[pl]
-description = Poland
-ringcadence = 1000,4000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/500,0/500
-callwaiting = 425/150,0/150,425/150,0/4000
-; DIALRECALL - not specified
-dialrecall = 425/500,0/50
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-; 950/1400/1800 3x0.33 on 1.0 off repeated 3 times
-info = !950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000
-; STUTTER - not specified
-stutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-
-[pt]
-description = Portugal
-ringcadence = 1000,5000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/5000
-congestion = 425/200,0/200
-callwaiting = 440/300,0/10000
-dialrecall = 425/1000,0/200
-record = 1400/500,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-stutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-
-[ru]
-; References:
-; http://www.minsvyaz.ru/site.shtml?id=1806
-; http://www.aboutphone.info/lib/gost/45-223-2001.html
-description = Russian Federation / ex Soviet Union
-ringcadence = 1000,4000
-dial = 425
-busy = 425/350,0/350
-ring = 425/1000,0/4000
-congestion = 425/175,0/175
-callwaiting = 425/200,0/5000
-record = 1400/400,0/15000
-info = 950/330,1400/330,1800/330,0/1000
-dialrecall = 425/400,0/40
-stutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-
-[se]
-description = Sweden
-ringcadence = 1000,5000
-dial = 425
-busy = 425/250,0/250
-ring = 425/1000,0/5000
-congestion = 425/250,0/750
-callwaiting = 425/200,0/500,425/200,0/9100
-dialrecall = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-record = 1400/500,0/15000
-info = !950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024,!950/332,!0/24,!1400/332,!0/24,!1800/332,0
-stutter = !425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425
-; stutter = 425/320,0/20 ; Real swedish standard, not used for now
-
-[sg]
-description = Singapore
-; Singapore
-; Reference: http://www.ida.gov.sg/idaweb/doc/download/I397/ida_ts_pstn1_i4r2.pdf
-; Frequency specs are: 425 Hz +/- 20Hz; 24 Hz +/- 2Hz; modulation depth 100%; SIT +/- 50Hz
-ringcadence = 400,200,400,2000
-dial = 425
-ring = 425*24/400,0/200,425*24/400,0/2000 ; modulation should be 100%, not 90%
-busy = 425/750,0/750
-congestion = 425/250,0/250
-callwaiting = 425*24/300,0/200,425*24/300,0/3200
-stutter = !425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,425
-info = 950/330,1400/330,1800/330,0/1000 ; not currently in use acc. to reference
-dialrecall = 425*24/500,0/500,425/500,0/2500 ; unspecified in IDA reference, use repeating Holding Tone A,B
-record = 1400/500,0/15000 ; unspecified in IDA reference, use 0.5s tone every 15s
-; additionally defined in reference
-nutone = 425/2500,0/500
-intrusion = 425/250,0/2000
-warning = 425/624,0/4376 ; end of period tone, warning
-acceptance = 425/125,0/125
-holdinga = !425*24/500,!0/500 ; followed by holdingb
-holdingb = !425/500,!0/2500
-
-[th]
-description = Thailand
-ringcadence = 1000,4000
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-dial = 400*50
-busy = 400/500,0/500
-ring = 420/1000,0/5000
-congestion = 400/300,0/300
-callwaiting = 1000/400,10000/400,1000/400
-; DIALRECALL - not specified - use special dial tone instead.
-dialrecall = 400*50/400,0/100,400*50/400,0/100
-; RECORDTONE - not specified
-record = 1400/500,0/15000
-; INFO - specified as an announcement - use special information tones instead
-info = 950/330,1400/330,1800/330
-; STUTTER - not specified
-stutter = !400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,400
-
-[uk]
-description = United Kingdom
-ringcadence = 400,200,400,2000
-; These are the official tones taken from BT SIN350. The actual tones
-; used by BT include some volume differences so sound slightly different
-; from Asterisk-generated ones.
-dial = 350+440
-; Special dial is the intermittent dial tone heard when, for example,
-; you have a divert active on the line
-specialdial = 350+440/750,440/750
-; Busy is also called "Engaged"
-busy = 400/375,0/375
-; "Congestion" is the Beep-bip engaged tone
-congestion = 400/400,0/350,400/225,0/525
-; "Special Congestion" is not used by BT very often if at all
-specialcongestion = 400/200,1004/300
-unobtainable = 400
-ring = 400+450/400,0/200,400+450/400,0/2000
-callwaiting = 400/100,0/4000
-; BT seem to use "Special Call Waiting" rather than just "Call Waiting" tones
-specialcallwaiting = 400/250,0/250,400/250,0/250,400/250,0/5000
-; "Pips" used by BT on payphones. (Sounds wrong, but this is what BT claim it
-; is and I've not used a payphone for years)
-creditexpired = 400/125,0/125
-; These two are used to confirm/reject service requests on exchanges that
-; don't do voice announcements.
-confirm = 1400
-switching = 400/200,0/400,400/2000,0/400
-; This is the three rising tones Doo-dah-dee "Special Information Tone",
-; usually followed by the BT woman saying an appropriate message.
-info = 950/330,0/15,1400/330,0/15,1800/330,0/1000
-; Not listed in SIN350
-record = 1400/500,0/60000
-stutter = 350+440/750,440/750
-
-[us]
-description = United States / North America
-ringcadence = 2000,4000
-dial = 350+440
-busy = 480+620/500,0/500
-ring = 440+480/2000,0/4000
-congestion = 480+620/250,0/250
-callwaiting = 440/300,0/10000
-dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330,0
-stutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-
-[us-old]
-description = United States Circa 1950/ North America
-ringcadence = 2000,4000
-dial = 600*120
-busy = 500*100/500,0/500
-ring = 420*40/2000,0/4000
-congestion = 500*100/250,0/250
-callwaiting = 440/300,0/10000
-dialrecall = !600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330,0
-stutter = !600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120
-
-[tw]
-description = Taiwan
-; http://nemesis.lonestar.org/reference/telecom/signaling/dialtone.html
-; http://nemesis.lonestar.org/reference/telecom/signaling/busy.html
-; http://www.iproducts.com.tw/ee/kylink/06ky-1000a.htm
-; http://www.pbx-manufacturer.com/ky120dx.htm
-; http://www.nettwerked.net/tones.txt
-; http://www.cisco.com/univercd/cc/td/doc/product/tel_pswt/vco_prod/taiw_sup/taiw2.htm
-;
-; busy tone 480+620Hz 0.5 sec. on ,0.5 sec. off
-; reorder tone 480+620Hz 0.25 sec. on,0.25 sec. off
-; ringing tone 440+480Hz 1 sec. on ,2 sec. off
-;
-ringcadence = 1000,4000
-dial = 350+440
-busy = 480+620/500,0/500
-ring = 440+480/1000,0/2000
-congestion = 480+620/250,0/250
-callwaiting = 350+440/250,0/250,350+440/250,0/3250
-dialrecall = 300/1500,0/500
-record = 1400/500,0/15000
-info = !950/330,!1400/330,!1800/330,0
-stutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
-
-[ve]
-; Tone definition source for ve found on
-; Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf
-description = Venezuela / South America
-ringcadence = 1000,4000
-dial = 425
-busy = 425/500,0/500
-ring = 425/1000,0/4000
-congestion = 425/250,0/250
-callwaiting = 400+450/300,0/6000
-dialrecall = 425
-record = 1400/500,0/15000
-info = !950/330,!1440/330,!1800/330,0/1000
-
-
-[za]
-description = South Africa
-; http://www.cisco.com/univercd/cc/td/doc/product/tel_pswt/vco_prod/safr_sup/saf02.htm
-; (definitions for other countries can also be found there)
-; Note, though, that South Africa uses two switch types in their network --
-; Alcatel switches -- mainly in the Western Cape, and Siemens elsewhere.
-; The former use 383+417 in dial, ringback etc. The latter use 400*33
-; I've provided both, uncomment the ones you prefer
-ringcadence = 400,200,400,2000
-; dial/ring/callwaiting for the Siemens switches:
-dial = 400*33
-ring = 400*33/400,0/200,400*33/400,0/2000
-callwaiting = 400*33/250,0/250,400*33/250,0/250,400*33/250,0/250,400*33/250,0/250
-; dial/ring/callwaiting for the Alcatel switches:
-; dial = 383+417
-; ring = 383+417/400,0/200,383+417/400,0/2000
-; callwaiting = 383+417/250,0/250,383+417/250,0/250,383+417/250,0/250,383+417/250,0/250
-congestion = 400/250,0/250
-busy = 400/500,0/500
-dialrecall = 350+440
-; XXX Not sure about the RECORDTONE
-record = 1400/500,0/10000
-info = 950/330,1400/330,1800/330,0/330
-stutter = !400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,400*33
diff --git a/1.4/configs/jabber.conf.sample b/1.4/configs/jabber.conf.sample
deleted file mode 100644
index 5ee26e510..000000000
--- a/1.4/configs/jabber.conf.sample
+++ /dev/null
@@ -1,18 +0,0 @@
-[general]
-;debug=yes ;;Turn on debugging by default.
-;autoprune=yes ;;Auto remove users from buddy list.
-;autoregister=yes ;;Auto register users from buddy list.
-
-;[asterisk] ;;label
-;type=client ;;Client or Component connection
-;serverhost=astjab.org ;;Route to server for example,
- ;; talk.google.com
-;username=asterisk@astjab.org/asterisk ;;Username with optional roster.
-;secret=blah ;;Password
-;port=5222 ;;Port to use defaults to 5222
-;usetls=yes ;;Use tls or not
-;usesasl=yes ;;Use sasl or not
-;buddy=mogorman@astjab.org ;;Manual addition of buddy to list.
-;statusmessage="I am available" ;;Have custom status message for
- ;;Asterisk.
-;timeout=100 ;;Timeout on the message stack.
diff --git a/1.4/configs/logger.conf.sample b/1.4/configs/logger.conf.sample
deleted file mode 100644
index f2ff0ea7e..000000000
--- a/1.4/configs/logger.conf.sample
+++ /dev/null
@@ -1,69 +0,0 @@
-;
-; Logging Configuration
-;
-; In this file, you configure logging to files or to
-; the syslog system.
-;
-; "logger reload" at the CLI will reload configuration
-; of the logging system.
-
-[general]
-; Customize the display of debug message time stamps
-; this example is the ISO 8601 date format (yyyy-mm-dd HH:MM:SS)
-; see strftime(3) Linux manual for format specifiers
-;dateformat=%F %T
-;
-; This appends the hostname to the name of the log files.
-;appendhostname = yes
-;
-; This determines whether or not we log queue events to a file
-; (defaults to yes).
-;queue_log = no
-;
-; This determines whether or not we log generic events to a file
-; (defaults to yes).
-;event_log = no
-;
-;
-; For each file, specify what to log.
-;
-; For console logging, you set options at start of
-; Asterisk with -v for verbose and -d for debug
-; See 'asterisk -h' for more information.
-;
-; Directory for log files is configures in asterisk.conf
-; option astlogdir
-;
-[logfiles]
-;
-; Format is "filename" and then "levels" of debugging to be included:
-; debug
-; notice
-; warning
-; error
-; verbose
-; dtmf
-;
-; Special filename "console" represents the system console
-;
-; We highly recommend that you DO NOT turn on debug mode if you are simply
-; running a production system. Debug mode turns on a LOT of extra messages,
-; most of which you are unlikely to understand without an understanding of
-; the underlying code. Do NOT report debug messages as code issues, unless
-; you have a specific issue that you are attempting to debug. They are
-; messages for just that -- debugging -- and do not rise to the level of
-; something that merit your attention as an Asterisk administrator. Debug
-; messages are also very verbose and can and do fill up logfiles quickly;
-; this is another reason not to have debug mode on a production system unless
-; you are in the process of debugging a specific issue.
-;
-;debug => debug
-console => notice,warning,error
-;console => notice,warning,error,debug
-messages => notice,warning,error
-;full => notice,warning,error,debug,verbose
-
-;syslog keyword : This special keyword logs to syslog facility
-;
-;syslog.local0 => notice,warning,error
-;
diff --git a/1.4/configs/manager.conf.sample b/1.4/configs/manager.conf.sample
deleted file mode 100644
index 1f51b0d8c..000000000
--- a/1.4/configs/manager.conf.sample
+++ /dev/null
@@ -1,56 +0,0 @@
-;
-; AMI - The Asterisk Manager Interface
-;
-; Third party application call management support and PBX event supervision
-;
-; This configuration file is read every time someone logs in
-;
-; Use the "manager list commands" at the CLI to list available manager commands
-; and their authorization levels.
-;
-; "manager show command <command>" will show a help text.
-;
-; ---------------------------- SECURITY NOTE -------------------------------
-; Note that you should not enable the AMI on a public IP address. If needed,
-; block this TCP port with iptables (or another FW software) and reach it
-; with IPsec, SSH, or SSL vpn tunnel. You can also make the manager
-; interface available over http if Asterisk's http server is enabled in
-; http.conf and if both "enabled" and "webenabled" are set to yes in
-; this file. Both default to no. httptimeout provides the maximum
-; timeout in seconds before a web based session is discarded. The
-; default is 60 seconds.
-;
-[general]
-displaysystemname = yes
-enabled = no
-;webenabled = yes
-port = 5038
-
-;httptimeout = 60
-; a) httptimeout sets the Max-Age of the http cookie
-; b) httptimeout is the amount of time the webserver waits
-; on a action=waitevent request (actually its httptimeout-10)
-; c) httptimeout is also the amount of time the webserver keeps
-; a http session alive after completing a successful action
-
-bindaddr = 0.0.0.0
-;displayconnects = yes
-;
-; Add a Unix epoch timestamp to events (not action responses)
-;
-;timestampevents = yes
-
-;[mark]
-;secret = mysecret
-;deny=0.0.0.0/0.0.0.0
-;permit=209.16.236.73/255.255.255.0
-;
-; If the device connected via this user accepts input slowly,
-; the timeout for writes to it can be increased to keep it
-; from being disconnected (value is in milliseconds)
-;
-; writetimeout = 100
-;
-; Authorization for various classes
-;read = system,call,log,verbose,command,agent,user,config
-;write = system,call,log,verbose,command,agent,user,config
diff --git a/1.4/configs/meetme.conf.sample b/1.4/configs/meetme.conf.sample
deleted file mode 100644
index 62e52dca4..000000000
--- a/1.4/configs/meetme.conf.sample
+++ /dev/null
@@ -1,26 +0,0 @@
-;
-; Configuration file for MeetMe simple conference rooms for Asterisk of course.
-;
-; This configuration file is read every time you call app meetme()
-
-[general]
-;audiobuffers=32 ; The number of 20ms audio buffers to be used
- ; when feeding audio frames from non-Zap channels
- ; into the conference; larger numbers will allow
- ; for the conference to 'de-jitter' audio that arrives
- ; at different timing than the conference's timing
- ; source, but can also allow for latency in hearing
- ; the audio from the speaker. Minimum value is 2,
- ; maximum value is 32.
-;
-[rooms]
-;
-; Usage is conf => confno[,pin][,adminpin]
-;
-; Note that once a participant has called the conference, a change to the pin
-; number done in this file will not take effect until there are no more users
-; in the conference and it goes away. When it is created again, it will have
-; the new pin number.
-;
-;conf => 1234
-;conf => 2345,9938
diff --git a/1.4/configs/mgcp.conf.sample b/1.4/configs/mgcp.conf.sample
deleted file mode 100644
index 288065355..000000000
--- a/1.4/configs/mgcp.conf.sample
+++ /dev/null
@@ -1,104 +0,0 @@
-;
-; MGCP Configuration for Asterisk
-;
-[general]
-;port = 2427
-;bindaddr = 0.0.0.0
-
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
-; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
- ; MGCP channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The MGCP channel can accept jitter,
- ; thus an enabled jitterbuffer on the receive MGCP side will only
- ; be used if the sending side can create jitter and jbforce is
- ; also set to yes.
-
-; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a MGCP
- ; channel. Defaults to "no".
-
-; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
-; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usually sent from exotic devices
- ; and programs. Defaults to 1000.
-
-; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a MGCP
- ; channel. Two implementations are currently available - "fixed"
- ; (with size always equals to jbmax-size) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
-; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
-
-;[dlinkgw]
-;host = 192.168.0.64
-;context = default
-;canreinvite = no
-;line => aaln/2
-;line => aaln/1
-
-;; The MGCP channel supports the following service codes:
-;; # - Transfer
-;; *67 - Calling Number Delivery Blocking
-;; *70 - Cancel Call Waiting
-;; *72 - Call Forwarding Activation
-;; *73 - Call Forwarding Deactivation
-;; *78 - Do Not Disturb Activation
-;; *79 - Do Not Disturb Deactivation
-;; *8 - Call pick-up
-;
-; known to work with Swissvoice IP10s
-;[192.168.1.20]
-;context=local
-;host=192.168.1.20
-;callerid = "John Doe" <123>
-;callgroup=0 ; in the range from 0 to 63
-;pickupgroup=0 ; in the range from 0 to 63
-;nat=no
-;threewaycalling=yes
-;transfer=yes ; transfer requires threewaycalling=yes. Use FLASH to transfer
-;callwaiting=yes ; this might be a cause of trouble for ip10s
-;cancallforward=yes
-;line => aaln/1
-;
-
-;[dph100]
-;
-; Supporting the DPH100M requires defining DLINK_BUGGY_FIRMWARE in
-; chan_mgcp.c in addition to enabling the slowsequence mode due to
-; bugs in the D-Link firmware
-;
-;context=local
-;host=dynamic
-;dtmfmode=none ; DTMF Mode can be 'none', 'rfc2833', or 'inband' or
- ; 'hybrid' which starts in none and moves to inband. Default is none.
-;slowsequence=yes ; The DPH100M does not follow MGCP standards for sequencing
-;line => aaln/1
-
-; known to work with wave7optics FTTH LMGs
-;[192.168.1.20]
-;accountcode = 1000 ; record this in cdr as account identification for billing
-;amaflags = billing ; record this in cdr as flagged for 'billing',
- ; 'documentation', or 'omit'
-;context = local
-;host = 192.168.1.20
-;wcardep = aaln/* ; enables wildcard endpoint and sets it to 'aaln/*'
- ; another common format is '*'
-;callerid = "Duane Cox" <123> ; now lets setup line 1 using per endpoint configuration...
-;callwaiting = no
-;callreturn = yes
-;cancallforward = yes
-;canreinvite = no
-;transfer = no
-;dtmfmode = inband
-;line => aaln/1 ; now lets save this config to line1 aka aaln/1
-;callerid = "Duane Cox" <456> ; now lets setup line 2
-;callwaiting = no
-;callreturn = yes
-;cancallforward = yes
-;canreinvite = no
-;transfer = no
-;dtmfmode = inband
-;line => aaln/2 ; now lets save this config to line2 aka aaln/2
diff --git a/1.4/configs/misdn.conf.sample b/1.4/configs/misdn.conf.sample
deleted file mode 100644
index 1b1049d3f..000000000
--- a/1.4/configs/misdn.conf.sample
+++ /dev/null
@@ -1,429 +0,0 @@
-;
-; chan_misdn sample config
-;
-
-; general section:
-;
-; for debugging and general setup, things that are not bound to port groups
-;
-
-[general]
-;
-; Sets the Path to the misdn-init.conf (for nt_ptp mode checking)
-;
-misdn_init=/etc/misdn-init.conf
-
-; set debugging flag:
-; 0 - No Debug
-; 1 - mISDN Messages and * - Messages, and * - State changes
-; 2 - Messages + Message specific Informations (e.g. bearer capability)
-; 3 - very Verbose, the above + lots of Driver specific infos
-; 4 - even more Verbose than 3
-;
-; default value: 0
-;
-debug=0
-
-
-
-; set debugging file and flags for mISDNuser (NT-Stack)
-;
-; flags can be or'ed with the following values:
-;
-; DBGM_NET 0x00000001
-; DBGM_MSG 0x00000002
-; DBGM_FSM 0x00000004
-; DBGM_TEI 0x00000010
-; DBGM_L2 0x00000020
-; DBGM_L3 0x00000040
-; DBGM_L3DATA 0x00000080
-; DBGM_BC 0x00000100
-; DBGM_TONE 0x00000200
-; DBGM_BCDATA 0x00000400
-; DBGM_MAN 0x00001000
-; DBGM_APPL 0x00002000
-; DBGM_ISDN 0x00004000
-; DBGM_SOCK 0x00010000
-; DBGM_CONN 0x00020000
-; DBGM_CDATA 0x00040000
-; DBGM_DDATA 0x00080000
-; DBGM_SOUND 0x00100000
-; DBGM_SDATA 0x00200000
-; DBGM_TOPLEVEL 0x40000000
-; DBGM_ALL 0xffffffff
-;
-
-ntdebugflags=0
-ntdebugfile=/var/log/misdn-nt.log
-
-
-; some pbx systems do cut the L1 for some milliseconds, to avoid
-; dropping running calls, we can set this flag to yes and tell
-; mISDNuser not to drop the calls on L2_RELEASE
-ntkeepcalls=no
-
-; the big trace
-;
-; default value: [not set]
-;
-;tracefile=/var/log/asterisk/misdn.log
-
-
-; set to yes if you want mISDN_dsp to bridge the calls in HW
-;
-; default value: yes
-;
-bridging=no
-
-
-;
-; watches the L1s of every port. If one l1 is down it tries to
-; get it up. The timeout is given in seconds. with 0 as value it
-; does not watch the l1 at all
-;
-; default value: 0
-;
-; this option is only read at loading time of chan_misdn,
-; which means you need to unload and load chan_misdn to change the
-; value, an asterisk restart should do the trick
-;
-l1watcher_timeout=0
-
-; stops dialtone after getting first digit on nt Port
-;
-; default value: yes
-;
-stop_tone_after_first_digit=yes
-
-; whether to append overlapdialed Digits to Extension or not
-;
-; default value: yes
-;
-append_digits2exten=yes
-
-;;; CRYPTION STUFF
-
-; Whether to look for dynamic crypting attempt
-;
-; default value: no
-;
-dynamic_crypt=no
-
-; crypt_prefix, what is used for crypting Protocol
-;
-; default value: [not set]
-;
-crypt_prefix=**
-
-; Keys for cryption, you reference them in the dialplan
-; later also in dynamic encr.
-;
-; default value: [not set]
-;
-crypt_keys=test,muh
-
-; users sections:
-;
-; name your sections as you which but not "general" !
-; the sections are Groups, you can dial out in extensions.conf
-; with Dial(mISDN/g:extern/101) where extern is a section name,
-; chan_misdn tries every port in this section to find a
-; new free channel
-;
-
-; The default section is not a group section, it just contains config elements
-; which are inherited by group sections.
-;
-
-[default]
-
-; define your default context here
-;
-; default value: default
-;
-context=misdn
-
-; language
-;
-; default value: en
-;
-language=en
-
-;
-; sets the musiconhold class
-;
-musicclass=default
-
-;
-; Either if we should produce DTMF Tones ourselves
-;
-senddtmf=yes
-
-;
-; If we should generate Ringing for chan_sip and others
-;
-far_alerting=no
-
-
-;
-; here you can define which bearers should be allowed
-;
-allowed_bearers=all
-
-; Prefixes for national and international, those are put before the
-; oad if an according dialplan is set by the other end.
-;
-; default values: nationalprefix : 0
-; internationalprefix : 00
-;
-nationalprefix=0
-internationalprefix=00
-
-; set rx/tx gains between -8 and 8 to change the RX/TX Gain
-;
-; default values: rxgain: 0
-; txgain: 0
-;
-rxgain=0
-txgain=0
-
-; some telcos especially in NL seem to need this set to yes, also in
-; switzerland this seems to be important
-;
-; default value: no
-;
-te_choose_channel=no
-
-
-
-;
-; This option defines, if chan_misdn should check the L1 on a PMP
-; before making a group call on it. The L1 may go down for PMP Ports
-; so we might need this.
-; But be aware! a broken or plugged off cable might be used for a group call
-; as well, since chan_misdn has no chance to distinguish if the L1 is down
-; because of a lost Link or because the Provider shut it down...
-;
-; default: no
-;
-pmp_l1_check=no
-
-
-;
-; in PMP this option defines which cause should be sent out to
-; the 3. caller. chan_misdn does not support callwaiting on TE
-; PMP side. This allows to modify the RELEASE_COMPLETE cause
-; at least.
-;
-reject_cause=16
-
-
-;
-; Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING),
-; this requests additional Infos, so we can waitfordigits
-; without much issues. This works only for PTP Ports
-;
-; default value: no
-;
-need_more_infos=no
-
-
-;
-; set this to yes if you want to disconnect calls when a timeout occurs
-; for example during the overlapdial phase
-;
-nttimeout=no
-
-; set the method to use for channel selection:
-; standard - always choose the first free channel with the lowest number
-; round_robin - use the round robin algorithm to select a channel. use this
-; if you want to balance your load.
-;
-; default value: standard
-;
-method=standard
-
-
-; specify if chan_misdn should collect digits before going into the
-; dialplan, you can choose yes=4 Seconds, no, or specify the amount
-; of seconds you need;
-;
-overlapdial=yes
-
-;
-; dialplan means Type Of Number in ISDN Terms (for outgoing calls)
-;
-; there are different types of the dialplan:
-;
-; dialplan -> outgoing Number
-; localdialplan -> callerid
-; cpndialplan -> connected party number
-;
-; dialplan options:
-;
-; 0 - unknown
-; 1 - International
-; 2 - National
-; 4 - Subscriber
-;
-; This setting is used for outgoing calls
-;
-; default value: 0
-;
-dialplan=0
-localdialplan=0
-cpndialplan=0
-
-
-
-;
-; turn this to no if you don't mind correct handling of Progress Indicators
-;
-early_bconnect=yes
-
-
-;
-; turn this on if you like to send Tone Indications to a Incoming
-; isdn channel on a TE Port. Rarely used, only if the Telco allows
-; you to send indications by yourself, normally the Telco sends the
-; indications to the remote party.
-;
-; default: no
-;
-incoming_early_audio=no
-
-; uncomment the following to get into s extension at extension conf
-; there you can use DigitTimeout if you can't or don't want to use
-; isdn overlap dial.
-; note: This will jump into the s exten for every exten!
-;
-; default value: no
-;
-;always_immediate=no
-
-;
-; set this to yes if you want to generate your own dialtone
-; with always_immediate=yes, else chan_misdn generates the dialtone
-;
-; default value: no
-;
-nodialtone=no
-
-
-; uncomment the following if you want callers which called exactly the
-; base number (so no extension is set) jump to the s extension.
-; if the user dials something more it jumps to the correct extension
-; instead
-;
-; default value: no
-;
-;immediate=no
-
-; uncomment the following to have hold and retrieve support
-;
-; default value: no
-;
-;hold_allowed=yes
-
-; Pickup and Callgroup
-;
-; default values: not set = 0
-; range: 0-63
-;
-;callgroup=1
-;pickupgroup=1
-
-
-;
-; these are the exact isdn screening and presentation indicators
-; if -1 is given for both values the presentation indicators are used
-; from asterisks SetCallerPres application.
-; s=0, p=0 -> callerid presented not screened
-; s=1, p=1 -> callerid presented but screened (the remote end does not see it!)
-;
-; default values s=-1, p=-1
-presentation=-1
-screen=-1
-
-; this enables echocancellation, with the given number of taps
-; be aware, move this setting only to outgoing portgroups!
-; A value of zero turns echocancellation off.
-;
-; possible values are: 0,32,64,128,256,yes(=128),no(=0)
-;
-; default value: no
-;
-;echocancel=no
-
-; Set this to no to disable echotraining. You can enter a number > 10
-; the value is a multiple of 0.125 ms.
-;
-; default value: no
-; yes = 2000
-; no = 0
-;
-echotraining=no
-
-;
-; chan_misdns jitterbuffer, default 4000
-;
-jitterbuffer=4000
-
-;
-; change this threshold to enable dejitter functionality
-;
-jitterbuffer_upper_threshold=0
-
-
-;
-; change this to yes, if you want to bridge a mISDN data channel to
-; another channel type or to an application.
-;
-hdlc=no
-
-
-;
-; defines the maximum amount of incoming calls per port for
-; this group. Calls which exceed the maximum will be marked with
-; the channel variable MAX_OVERFLOW. It will contain the amount of
-; overflowed calls
-;
-max_incoming=-1
-
-;
-; defines the maximum amount of outgoing calls per port for this group
-; exceeding calls will be rejected
-;
-max_outgoing=-1
-
-[intern]
-; define your ports, e.g. 1,2 (depends on mISDN-driver loading order)
-ports=1,2
-; context where to go to when incoming Call on one of the above ports
-context=Intern
-
-[internPP]
-;
-; adding the postfix 'ptp' to a port number is obsolete now, chan_misdn
-; parses /etc/misdn-init.conf and sets the ptp mode to the corresponding
-; configs. For backwards compatibility you can still set ptp here.
-;
-ports=3
-
-[first_extern]
-; again port defs
-ports=4
-; again a context for incoming calls
-context=Extern1
-; msns for te ports, listen on those numbers on the above ports, and
-; indicate the incoming calls to asterisk
-; here you can give a comma separated list or simply an '*' for
-; any msn.
-msns=*
-
-; here an example with given msns
-[second_extern]
-ports=5
-context=Extern2
-callerid=15
-msns=102,144,101,104
diff --git a/1.4/configs/modules.conf.sample b/1.4/configs/modules.conf.sample
deleted file mode 100644
index 9302e87ac..000000000
--- a/1.4/configs/modules.conf.sample
+++ /dev/null
@@ -1,35 +0,0 @@
-;
-; Asterisk configuration file
-;
-; Module Loader configuration file
-;
-
-[modules]
-autoload=yes
-;
-; Any modules that need to be loaded before the Asterisk core has been
-; initialized (just after the logger has been initialized) can be loaded
-; using 'preload'. This will frequently be needed if you wish to map all
-; module configuration files into Realtime storage, since the Realtime
-; driver will need to be loaded before the modules using those configuration
-; files are initialized.
-;
-; An example of loading ODBC support would be:
-;preload => res_odbc.so
-;preload => res_config_odbc.so
-;
-; Uncomment the following if you wish to use the Speech Recognition API
-;preload => res_speech.so
-;
-; If you want, load the GTK console right away.
-;
-noload => pbx_gtkconsole.so
-;load => pbx_gtkconsole.so
-;
-load => res_musiconhold.so
-;
-; Load either OSS or ALSA, not both
-; By default, load OSS only (automatically) and do not load ALSA
-;
-noload => chan_alsa.so
-;noload => chan_oss.so
diff --git a/1.4/configs/musiconhold.conf.sample b/1.4/configs/musiconhold.conf.sample
deleted file mode 100644
index e485552c1..000000000
--- a/1.4/configs/musiconhold.conf.sample
+++ /dev/null
@@ -1,66 +0,0 @@
-;
-; Music on Hold -- Sample Configuration
-;
-
-; valid mode options:
-; files -- read files from a directory in any Asterisk supported
-; media format
-; quietmp3 -- default
-; mp3 -- loud
-; mp3nb -- unbuffered
-; quietmp3nb -- quiet unbuffered
-; custom -- run a custom application (See examples below)
-
-; =========
-; File-based (native) music on hold
-; =========
-;
-; This plays files directly from the specified directory, no external
-; processes are required. Files are played in normal sorting order
-; (same as a sorted directory listing), and no volume or other
-; sound adjustments are available. If the file is available in
-; the same format as the channel's codec, then it will be played
-; without transcoding (same as Playback would do in the dialplan).
-; Files can be present in as many formats as you wish, and the
-; 'best' format will be chosen at playback time.
-;
-; NOTE:
-; If you are not using "autoload" in modules.conf, then you
-; must ensure that the format modules for any formats you wish
-; to use are loaded _before_ res_musiconhold. If you do not do
-; this, res_musiconhold will skip the files it is not able to
-; understand when it loads.
-;
-
-[default]
-mode=files
-directory=/var/lib/asterisk/moh
-;
-;[native-random]
-;mode=files
-;directory=/var/lib/asterisk/moh
-;random=yes ; Play the files in a random order
-
-
-; =========
-; Other (non-native) playback methods
-; =========
-
-;[manual]
-;mode=custom
-; Note that with mode=custom, a directory is not required, such as when reading
-; from a stream.
-;directory=/var/lib/asterisk/mohmp3
-;application=/usr/bin/mpg123 -q -r 8000 -f 8192 -b 2048 --mono -s
-
-;[ulawstream]
-;mode=custom
-;application=/usr/bin/streamplayer 192.168.100.52 888
-;format=ulaw
-
-; mpg123 on Solaris does not always exit properly; madplay may be a better
-; choice
-;[solaris]
-;mode=custom
-;directory=/var/lib/asterisk/mohmp3
-;application=/site/sw/bin/madplay -Q -o raw:- --mono -R 8000 -a -12
diff --git a/1.4/configs/muted.conf.sample b/1.4/configs/muted.conf.sample
deleted file mode 100644
index 2970223f5..000000000
--- a/1.4/configs/muted.conf.sample
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Sample muted configuration file
-#
-# Copyright (C) 2004 Digium, Inc.
-#
-# What is this? Well, haven't you ever wished you could automatically
-# turn down the volume on your stereo, CDPlayer, etc, when a call comes in,
-# and then return it to normal when the call ends? Well, this is a possible
-# mechanism to make this happen!
-# You have to fire up the new utils/muted, which runs as a daemon in the
-# background. This daemon connects to asterisk via a manager interface, and
-# also reads this config file. When the channels mentioned
-# are activated, it tweaks the sound levels on the sound card(s).
-# So, depending on the sound card, you may be able to run all your sound
-# generating devices thru your sound card, and use this mechanism to quiet
-# them down while you are on the phone. If anyone figures out how to make
-# this work with kids, please inform!!
-#
-# First you have the host, username, and password
-# we use to connect to the asterisk system
-#
-host localhost
-user user
-pass pass
-#
-# List each channel we're supposed to watch
-#
-channel Zap/1
-channel Zap/2
-channel SIP/mark
-#
-# Mute level is the percentage of the current volume we should
-# lower the music to.
-#
-mutelevel 20
-#
-# Smooth fade makes the fadein/fadeout nicer sounding
-#
-smoothfade
diff --git a/1.4/configs/osp.conf.sample b/1.4/configs/osp.conf.sample
deleted file mode 100644
index edd8af1e3..000000000
--- a/1.4/configs/osp.conf.sample
+++ /dev/null
@@ -1,72 +0,0 @@
-;
-; Open Settlement Protocol Sample Configuration File
-;
-;
-; This file contains configuration of providers that
-; are used by the OSP subsystem of Asterisk. The section
-; "general" is reserved for global options. Each other
-; section declares an OSP Provider. The provider "default"
-; is used when no provider is otherwise specified.
-;
-[general]
-;
-; Should hardware acceleration be enabled? May not be changed
-; on a reload.
-;
-;accelerate=yes
-;
-; Defines the token format that Asterisk can validate.
-; 0 - signed tokens only
-; 1 - unsigned tokens only
-; 2 - both signed and unsigned
-; The defaults to 0, i.e. the Asterisk can validate signed tokens only.
-;
-;tokenformat=0
-
-;[default]
-;
-; All paths are presumed to be under /var/lib/asterisk/keys unless
-; the path begins with '/'
-;
-; Specify the private keyfile. If unspecified, defaults to the name
-; of the section followed by "-privatekey.pem" (e.g. default-privatekey.pem)
-;
-;privatekey=pkey.pem
-;
-; Specify the local certificate file. If unspecified, defaults to
-; the name of the section followed by "-localcert.pem"
-;
-;localcert=localcert.pem
-;
-; Specify one or more Certificate Authority keys. If none are listed,
-; a single one is added with the name "-cacert.pem"
-;
-;cacert=cacert_0.pem
-;
-; Specific parameters can be tuned as well:
-;
-; maxconnections: Max number of simultaneous connections to the provider (default=20)
-; retrydelay: Extra delay between retries (default=0)
-; retrylimit: Max number of retries before giving up (default=2)
-; timeout: Timeout for response in milliseconds (default=500)
-;
-;maxconnections=20
-;retrydelay=0
-;retrylimit=2
-;timeout=500
-;
-; List all service points for this provider
-;
-;servicepoint=http://osptestserver.transnexus.com:1080/osp
-;
-; Set the "source" for requesting authorization
-;
-;source=foo
-;
-; Set the authentication policy.
-; 0 - NO
-; 1 - YES
-; 2 - EXCLUSIVE
-; Default is 1, validate token but allow no token.
-;
-;authpolicy=1
diff --git a/1.4/configs/oss.conf.sample b/1.4/configs/oss.conf.sample
deleted file mode 100644
index fb2d0281a..000000000
--- a/1.4/configs/oss.conf.sample
+++ /dev/null
@@ -1,75 +0,0 @@
-;
-; Automatically generated from ../channels/chan_oss.c
-;
-
-[general]
- ; General config options, with default values shown.
- ; You should use one section per device, with [general] being used
- ; for the first device and also as a template for other devices.
- ;
- ; All but 'debug' can go also in the device-specific sections.
- ;
- ; debug = 0x0 ; misc debug flags, default is 0
-
- ; Set the device to use for I/O
- ; device = /dev/dsp
-
- ; Optional mixer command to run upon startup (e.g. to set
- ; volume levels, mutes, etc.
- ; mixer =
-
- ; Software mic volume booster (or attenuator), useful for sound
- ; cards or microphones with poor sensitivity. The volume level
- ; is in dB, ranging from -20.0 to +20.0
- ; boost = n ; mic volume boost in dB
-
- ; Set the callerid for outgoing calls
- ; callerid = John Doe <555-1234>
-
- ; autoanswer = no ; no autoanswer on call
- ; autohangup = yes ; hangup when other party closes
- ; extension = s ; default extension to call
- ; context = default ; default context for outgoing calls
- ; language = "" ; default language
-
- ; If you set overridecontext to 'yes', then the whole dial string
- ; will be interpreted as an extension, which is extremely useful
- ; to dial SIP, IAX and other extensions which use the '@' character.
- ; The default is 'no' just for backward compatibility, but the
- ; suggestion is to change it.
- ; overridecontext = no ; if 'no', the last @ will start the context
- ; if 'yes' the whole string is an extension.
-
- ; low level device parameters in case you have problems with the
- ; device driver on your operating system. You should not touch these
- ; unless you know what you are doing.
- ; queuesize = 10 ; frames in device driver
- ; frags = 8 ; argument to SETFRAGMENT
-
- ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
- ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
- ; OSS channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The OSS channel can't accept jitter,
- ; thus an enabled jitterbuffer on the receive OSS side will always
- ; be used if the sending side can create jitter.
-
- ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
- ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usually sent from exotic devices
- ; and programs. Defaults to 1000.
-
- ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an OSS
- ; channel. Two implementations are currently available - "fixed"
- ; (with size always equals to jbmax-size) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
- ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
- ;-----------------------------------------------------------------------------------
-
-
-[card1]
- ; device = /dev/dsp1 ; alternate device
-
diff --git a/1.4/configs/phone.conf.sample b/1.4/configs/phone.conf.sample
deleted file mode 100644
index 649edc7bb..000000000
--- a/1.4/configs/phone.conf.sample
+++ /dev/null
@@ -1,49 +0,0 @@
-;
-; Linux Telephony Interface
-;
-; Configuration file
-;
-[interfaces]
-;
-; Select a mode, either the phone jack provides dialtone, reads digits,
-; then starts PBX with the given extension (dialtone mode), or
-; immediately provides the PBX without reading any digits or providing
-; any dialtone (this is the immediate mode, the default). Also, you
-; can set the mode to "fxo" if you have a linejack to make it operate
-; properly. If you are using a Sigma Designs board you may set this to
-; "sig".
-;
-mode=immediate
-;mode=dialtone
-;mode=fxo
-;mode=sig
-;
-; You can decide which format to use by default, "g723.1" or "slinear".
-; XXX Be careful, sometimes the card causes kernel panics when running
-; in signed linear mode for some reason... XXX
-;
-format=slinear
-;format=g723.1
-;
-; And set the echo cancellation to "off", "low", "medium", and "high".
-; This is not supported on all phones.
-;
-echocancel=medium
-;
-; You can optionally use VAD/CNG silence suppression
-;
-;silencesupression=yes
-;
-; List all devices we can use. Contexts may also be specified
-;
-;context=local
-;
-; You can set txgain and rxgain for each device in the same way as context.
-; If you want to change default gain value (1.0 =~ 100%) for device, simple
-; add txgain or rxgain line before device line. But remember, if you change
-; volume all cards listed below will be affected by these values. You can
-; use float values (1.0, 0.5, 2.0) or percentage values (100%, 150%, 50%).
-;
-;txgain=100%
-;rxgain=1.0
-;device => /dev/phone0
diff --git a/1.4/configs/privacy.conf.sample b/1.4/configs/privacy.conf.sample
deleted file mode 100644
index 0236bccb7..000000000
--- a/1.4/configs/privacy.conf.sample
+++ /dev/null
@@ -1,3 +0,0 @@
-[general]
-
-maxretries = 2 ;How many chances the caller has to enter their number
diff --git a/1.4/configs/queues.conf.sample b/1.4/configs/queues.conf.sample
deleted file mode 100644
index de93da60e..000000000
--- a/1.4/configs/queues.conf.sample
+++ /dev/null
@@ -1,308 +0,0 @@
-[general]
-;
-; Global settings for call queues
-;
-; Persistent Members
-; Store each dynamic member in each queue in the astdb so that
-; when asterisk is restarted, each member will be automatically
-; read into their recorded queues. Default is 'yes'.
-;
-persistentmembers = yes
-;
-; AutoFill Behavior
-; The old/current behavior of the queue has a serial type behavior
-; in that the queue will make all waiting callers wait in the queue
-; even if there is more than one available member ready to take
-; calls until the head caller is connected with the member they
-; were trying to get to. The next waiting caller in line then
-; becomes the head caller, and they are then connected with the
-; next available member and all available members and waiting callers
-; waits while this happens. The new behavior, enabled by setting
-; autofill=yes makes sure that when the waiting callers are connecting
-; with available members in a parallel fashion until there are
-; no more available members or no more waiting callers. This is
-; probably more along the lines of how a queue should work and
-; in most cases, you will want to enable this behavior. If you
-; do not specify or comment out this option, it will default to no
-; to keep backward compatibility with the old behavior.
-;
-autofill = yes
-;
-; Monitor Type
-; By setting monitor-type = MixMonitor, when specifying monitor-format
-; to enable recording of queue member conversations, app_queue will
-; now use the new MixMonitor application instead of Monitor so
-; the concept of "joining/mixing" the in/out files now goes away
-; when this is enabled. You can set the default type for all queues
-; here, and then also change monitor-type for individual queues within
-; queue by using the same configuration parameter within a queue
-; configuration block. If you do not specify or comment out this option,
-; it will default to the old 'Monitor' behavior to keep backward
-; compatibility.
-;
-monitor-type = MixMonitor
-;
-; Note that a timeout to fail out of a queue may be passed as part of
-; an application call from extensions.conf:
-; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
-; example: Queue(dave|t|||45)
-
-;[markq]
-;
-; A sample call queue
-;
-; Musicclass sets which music applies for this particular call queue.
-; The only class which can override this one is if the MOH class is set
-; directly on the channel using Set(CHANNEL(musicclass)=whatever) in the
-; dialplan.
-;
-;musicclass = default
-;
-; An announcement may be specified which is played for the member as
-; soon as they answer a call, typically to indicate to them which queue
-; this call should be answered as, so that agents or members who are
-; listening to more than one queue can differentiated how they should
-; engage the customer
-;
-;announce = queue-markq
-;
-; A strategy may be specified. Valid strategies include:
-;
-; ringall - ring all available channels until one answers (default)
-; roundrobin - take turns ringing each available interface
-; leastrecent - ring interface which was least recently called by this queue
-; fewestcalls - ring the one with fewest completed calls from this queue
-; random - ring random interface
-; rrmemory - round robin with memory, remember where we left off last ring pass
-;
-;strategy = ringall
-;
-; Second settings for service level (default 0)
-; Used for service level statistics (calls answered within service level time
-; frame)
-;servicelevel = 60
-;
-; A context may be specified, in which if the user types a SINGLE
-; digit extension while they are in the queue, they will be taken out
-; of the queue and sent to that extension in this context.
-;
-;context = qoutcon
-;
-; How long do we let the phone ring before we consider this a timeout...
-;
-;timeout = 15
-;
-; How long do we wait before trying all the members again?
-;
-;retry = 5
-;
-; Weight of queue - when compared to other queues, higher weights get
-; first shot at available channels when the same channel is included in
-; more than one queue.
-;
-;weight=0
-;
-; After a successful call, how long to wait before sending a potentially
-; free member another call (default is 0, or no delay)
-;
-;wrapuptime=15
-;
-; Autofill will follow queue strategy but push multiple calls through
-; at same time until there are no more waiting callers or no more
-; available members. The per-queue setting of autofill allows you
-; to override the default setting on an individual queue level.
-;
-;autofill=yes
-;
-; Autopause will pause a queue member if they fail to answer a call
-;
-;autopause=yes
-;
-; Maximum number of people waiting in the queue (0 for unlimited)
-;
-;maxlen = 0
-;
-; If set to yes, just prior to the caller being bridged with a queue member
-; the MEMBERINTERFACE variable will be set with the interface name (eg. Agent/1234)
-; of the queue member that was chosen and is now connected to be bridged with
-; the caller
-;
-;setinterfacevar=no
-;
-; How often to announce queue position and/or estimated
-; holdtime to caller (0=off)
-;
-;announce-frequency = 90
-;
-;
-; How often to make any periodic announcement (see periodic-announce)
-;
-;periodic-announce-frequency=60
-;
-; Should we include estimated hold time in position announcements?
-; Either yes, no, or only once.
-; Hold time will be announced as the estimated time,
-; or "less than 2 minutes" when appropriate.
-;
-;announce-holdtime = yes|no|once
-
-;
-; What's the rounding time for the seconds?
-; If this is non-zero, then we announce the seconds as well as the minutes
-; rounded to this value.
-;
-; announce-round-seconds = 10
-;
-; Use these sound files in making position/holdtime announcements. The
-; defaults are as listed below -- change only if you need to.
-;
- ; ("You are now first in line.")
-;queue-youarenext = queue-youarenext
- ; ("There are")
-;queue-thereare = queue-thereare
- ; ("calls waiting.")
-;queue-callswaiting = queue-callswaiting
- ; ("The current est. holdtime is")
-;queue-holdtime = queue-holdtime
- ; ("minutes.")
-;queue-minutes = queue-minutes
- ; ("seconds.")
-;queue-seconds = queue-seconds
- ; ("Thank you for your patience.")
-;queue-thankyou = queue-thankyou
- ; ("less than")
-;queue-lessthan = queue-less-than
- ; ("Hold time")
-;queue-reporthold = queue-reporthold
- ; ("All reps busy / wait for next")
-;periodic-announce = queue-periodic-announce
-;
-; Calls may be recorded using Asterisk's monitor/MixMonitor resource
-; This can be enabled from within the Queue application, starting recording
-; when the call is actually picked up; thus, only successful calls are
-; recorded, and you are not recording while people are listening to MOH.
-; To enable monitoring, simply specify "monitor-format"; it will be disabled
-; otherwise.
-;
-; You can specify the monitor filename with by calling
-; Set(MONITOR_FILENAME=foo)
-; Otherwise it will use MONITOR_FILENAME=${UNIQUEID}
-;
-; Pick any one valid extension for monitor format recording. If you leave
-; monitor-format commented out, it will not record calls.
-;
-; monitor-format = gsm|wav|wav49
-;
-; Monitor Type
-; By setting monitor-type = MixMonitor, when specifying monitor-format
-; to enable recording of queue member conversations, app_queue will
-; now use the new MixMonitor application instead of Monitor so
-; the concept of "joining/mixing" the in/out files now goes away
-; when this is enabled. If you do not specify or comment out this option,
-; it will default to the old 'Monitor' behavior to keep backward
-; compatibility.
-;
-; monitor-type = MixMonitor
-;
-; ----------------------- TYPE MIXMONITOR OPTIONS -----------------------------
-;
-;
-; You can specify the options supplied to MixMonitor by calling
-; Set(MONITOR_OPTIONS=av(<x>)V(<x>)W(<x>))
-; The 'b' option for MixMonitor (only save audio to the file while bridged) is
-; implied.
-;
-; You can specify a post recording command to be executed after the end of
-; recording by calling
-; Set(MONITOR_EXEC=mv /var/spool/asterisk/monitor/^{MONITOR_FILENAME} /tmp/^{MONITOR_FILENAME})
-;
-; The command specified within the contents of MONITOR_EXEC will be executed when
-; the recording is over. Any strings matching ^{X} will be unescaped to ${X} and
-; all variables will be evaluated just prior to recording being started.
-;
-; The contents of MONITOR_FILENAME will also be unescaped from ^{X} to ${X} and
-; all variables will be evaluated just prior to recording being started.
-;
-;
-; This setting controls whether callers can join a queue with no members. There
-; are three choices:
-;
-; yes - callers can join a queue with no members or only unavailable members
-; no - callers cannot join a queue with no members
-; strict - callers cannot join a queue with no members or only unavailable
-; members
-;
-; joinempty = yes
-;
-;
-; If you wish to remove callers from the queue when new callers cannot join,
-; set this setting to one of the same choices for 'joinempty'
-;
-; leavewhenempty = yes
-;
-;
-; If this is set to yes, the following manager events will be generated:
-; AgentCalled, AgentDump, AgentConnect, AgentComplete; setting this to
-; vars also sends all channel variables with the event.
-; (may generate some extra manager events, but probably ones you want)
-;
-; eventwhencalled = yes|no|vars
-;
-; If this is set to yes, the following manager events will be generated:
-; QueueMemberStatus
-; (may generate a WHOLE LOT of extra manager events)
-;
-; eventmemberstatus = no
-;
-; If you wish to report the caller's hold time to the member before they are
-; connected to the caller, set this to yes.
-;
-; reportholdtime = no
-;
-; If you want the queue to avoid sending calls to members whose devices are
-; known to be 'in use' (via the channel driver supporting that device state)
-; uncomment this option. (Note: only the SIP channel driver currently is able
-; to report 'in use'.)
-;
-; ringinuse = no
-;
-; If you wish to have a delay before the member is connected to the caller (or
-; before the member hears any announcement messages), set this to the number of
-; seconds to delay.
-;
-; memberdelay = 0
-;
-; If timeoutrestart is set to yes, then the timeout for an agent to answer is
-; reset if a BUSY or CONGESTION is received. This can be useful if agents
-; are able to cancel a call with reject or similar.
-;
-; timeoutrestart = no
-;
-; Each member of this call queue is listed on a separate line in
-; the form technology/dialstring. "member" means a normal member of a
-; queue. An optional penalty may be specified after a comma, such that
-; entries with higher penalties are considered last. An optional member
-; name may also be specified after a second comma, which is used in log
-; messages as a "friendly name". Multiple interfaces may share a single
-; member name.
-;
-; It is important to ensure that channel drivers used for members are loaded
-; before app_queue.so itself or they may be marked invalid until reload. This
-; can be accomplished by explicitly listing them in modules.conf before app_queue.so
-;
-;member => Zap/1
-;member => Zap/2,10
-;member => Zap/3,10,Bob Johnson
-;member => Agent/1001
-;member => Agent/1002
-
-;
-; Note that using agent groups is probably not what you want. Strategies do
-; not propagate down to the Agent system so if you want round robin, least
-; recent, etc, you should list all the agents in this file individually and not
-; use agent groups.
-;
-;member => Agent/@1 ; Any agent in group 1
-;member => Agent/:1,1 ; Any agent in group 1, wait for first
- ; available, but consider with penalty
-
diff --git a/1.4/configs/res_odbc.conf.sample b/1.4/configs/res_odbc.conf.sample
deleted file mode 100644
index 4b5fe428f..000000000
--- a/1.4/configs/res_odbc.conf.sample
+++ /dev/null
@@ -1,49 +0,0 @@
-;;; odbc setup file
-
-; ENV is a global set of environmental variables that will get set.
-; Note that all environmental variables can be seen by all connections,
-; so you can't have different values for different connections.
-[ENV]
-INFORMIXSERVER => my_special_database
-INFORMIXDIR => /opt/informix
-
-; All other sections are arbitrary names for database connections.
-
-[asterisk]
-enabled => no
-dsn => asterisk
-;username => myuser
-;password => mypass
-pre-connect => yes
-
-
-[mysql2]
-enabled => no
-dsn => MySQL-asterisk
-username => myuser
-password => mypass
-pre-connect => yes
-;
-; On some databases, the connection times out and a reconnection will be
-; necessary. This setting configures the amount of time a connection
-; may sit idle (in seconds) before a reconnection will be attempted.
-;idlecheck => 3600
-
-; Certain servers, such as MS SQL Server and Sybase use the TDS protocol, which
-; limits the number of active queries per connection to 1. By setting up pools
-; of connections, Asterisk can be made to work with these servers.
-[sqlserver]
-enabled => no
-dsn => mickeysoft
-pooling => yes
-limit => 5
-username => oscar
-password => thegrouch
-pre-connect => yes
-; Many databases have a default of '\' to escape special characters. MS SQL
-; Server does not.
-backslash_is_escape => no
-
-
-
-
diff --git a/1.4/configs/res_pgsql.conf.sample b/1.4/configs/res_pgsql.conf.sample
deleted file mode 100644
index 1ec2293e2..000000000
--- a/1.4/configs/res_pgsql.conf.sample
+++ /dev/null
@@ -1,14 +0,0 @@
-;
-; Sample configuration for res_config_pgsql
-;
-; The value of dbhost may be either a hostname or an IP address.
-; If dbhost is commented out or the string "localhost", a connection
-; to the local host is assumed and dbsock is used instead of TCP/IP
-; to connect to the server.
-;
-[general]
-dbhost=127.0.0.1
-dbport=5432
-dbname=asterisk
-dbuser=asterisk
-dbpass=password
diff --git a/1.4/configs/res_snmp.conf.sample b/1.4/configs/res_snmp.conf.sample
deleted file mode 100644
index 5ca09d576..000000000
--- a/1.4/configs/res_snmp.conf.sample
+++ /dev/null
@@ -1,10 +0,0 @@
-;
-; Configuration file for res_snmp
-;
-
-[general]
-; We run as a subagent per default -- to run as a full agent
-; we must run as root (to be able to bind to port 161)
-;subagent = yes
-; SNMP must be explicitly enabled to be active
-;enabled = yes
diff --git a/1.4/configs/rpt.conf.sample b/1.4/configs/rpt.conf.sample
deleted file mode 100644
index 6aee784dc..000000000
--- a/1.4/configs/rpt.conf.sample
+++ /dev/null
@@ -1,193 +0,0 @@
-; Radio Repeater / Remote Base configuration file (for use with app_rpt)
-; As of app_rpt version 0.39, 12/20/2005
-;
-
-;[000] ; Node ID of first repeater
-
-;rxchannel = Zap/1 ; Rx audio/signalling channel
-; Note: if you use a unified interface (tx/rx on one channel), only
-; specify the rxchannel and the txchannel will be assumed from the rxchannel
-;txchannel = Zap/2 ; Tx audio/signalling channel
-;duplex = 2 ; (Optional) set duplex operating mode
-;; 0 = half duplex (telemetry and courtesy tones do not transmit)
-;; 1 = semi-half duplex (telemetry and courtesy tones transmit, but not
-;; repeated audio
-;; 2 = normal full-duplex mode (Default)
-;; 3 = full-duplex mode, without repeated audio from main input source
-;functions = functions-repeater ; DTMF function list
-;; specify this for a different function list then local when on link
-;;link_functions = functions-different ; DTMF function list for link
-;;phone_functions = functions-phone ; (optional) different functions for 'P' mode
-;;dphone_functions = functions-dphone ; (optional) different functions for 'D' mode
-;;nodes = nodes-different ; (optional) different node list
-;tonezone = us ; use US tones (default)
-;context = default ; dialing context for phone
-;callerid = "WB6NIL Repeater" <(213) 555-0123> ; Callerid for phone calls
-;idrecording = wb6nil ; id recording
-;accountcode=RADIO ; account code (optional)
-;funcchar = * ; function lead-in character (defaults to '*')
-;endchar = # ; command mode end character (defaults to '#')
-;;nobusyout=yes ; (optional) Do not busy-out reverse-patch when
- ; normal patch in use
-;hangtime=1000 ; squelch tail hang time (in ms) (optional)
-;totime=100000 ; transmit time-out time (in ms) (optional)
-;idtime=30000 ; id interval time (in ms) (optional)
-;politeid=30000 ; time in milliseconds before ID timer
- ; expires to try and ID in the tail.
- ; (optional, default is 30000).
-;idtalkover=|iwb6nil/rpt ; Talkover ID (optional) default is none
-;unlinkedct=ct2 ; unlinked courtesy tone (optional) default is none
-
-;; The tailmessagetime,tailsquashedtime, and tailmessages need to be set
-;; to support tail messages. They can be omitted otherwise.
-;tailmessagetime=300000 ; Play a tail message every 5 mins
-;tailsquashedtime=30000 ; If squashed by another user,
-;; try again after 30 seconds
-;tailmessages=msg1,msg2,msg3 ;list of messages to be played for tail message
-
-; The default values for hangtime, time-out time, and id interval time are
-; 5 seconds (5000 ms), 3 minutes (180000 ms), and 5 minutes (300000 ms)
-; respectively
-
-;[001] ; Node ID of first repeater
-
-;rxchannel = Zap/3 ; Rx audio/signalling channel
-; Note: if you use a unified interface (tx/rx on one channel), only
-; specify the rxchannel and the txchannel will be assumed from the rxchannel
-;txchannel = Zap/4 ; Tx audio/signalling channel
-;functions = functions-repeater ; DTMF function list
-;; specify this for a different function list then local when on link
-;;link_functions = functions-different ; DTMF function list for link
-;;phone_functions = functions-phone ; (optional) different functions for 'P' mode
-;;dphone_functions = functions-dphone ; (optional) different functions for 'D' mode
-;;nodes = nodes-different ; (optional) different node list
-;tonezone = us ; use US tones (default)
-;context = default ; dialing context for phone
-;callerid = "WB6NIL Repeater" <(213) 555-0123> ; Callerid for phone calls
-;idrecording = wb6nil ; id recording
-;accountcode=RADIO ; account code (optional)
-;funcchar = * ; function lead-in character (defaults to '*')
-;endchar = # ; command mode end character (defaults to '#')
-;;nobusyout=yes ; (optional) Do not busy-out reverse-patch when
- ; normal patch in use
-;hangtime=1000 ; squelch tail hang time (in ms) (optional)
-;totime=100000 ; transmit time-out time (in ms) (optional)
-;idtime=30000 ; id interval time (in ms) (optional)
-;politeid=30000 ; time in milliseconds before ID timer
- ; expires to try and ID in the tail.
- ; (optional, default is 30000).
-;idtalkover=|iwb6nil/rpt ; Talkover ID (optional) default is none
-;unlinkedct=ct2 ; unlinked courtesy tone (optional) default is none
-
-;[002] ; Node ID of remote base
-
-;rxchannel = Zap/5 ; Rx audio/signalling channel
-; Note: if you use a unified interface (tx/rx on one channel), only
-; specify the rxchannel and the txchannel will be assumed from the rxchannel
-;txchannel = Zap/6 ; Tx audio/signalling channel
-;functions = functions-remote
-;remote = ft897 ; Set remote=y for dumb remote or
- ; remote=ft897 for Yaesu FT-897 or
- ; remote=rbi for Doug Hall RBI1
-;iobase = 0x378 ; Specify IO port for parallel port (optional)
-
-;[functions-repeater]
-;1=ilink,1 ; Specific link disconnect
-;2=ilink,2 ; Specific Link connect - monitor only
-;3=ilink,3 ; Specific Link connect - transceive
-;4=ilink,4 ; Enter command mode on a specific link
-;7=ilink,5 ; Link status
-;;XX=ilink,6 ; Disconnect all links (not used here)
-
-;80=status,1 ; System info
-;81=status,2 ; Time
-;82=status,3 ; app_rpt.c Version
-
-;6=autopatchup ; Autopatch up
-;0=autopatchdn ; Autopatch down
-
-;90=cop,1 ; System warm boot
-;91=cop,2 ; System enable
-;92=cop,3 ; System disable
-
-;[functions-remote]
-
-;0=remote,1 ; Retrieve Memory
-;1=remote,2 ; Set freq.
-;2=remote,3 ; Set Rx PL tone.
-;40=remote,100 ; Rx PL off
-;41=remote,101 ; Rx PL on
-;42=remote,102 ; Tx PL off
-;43=remote,103 ; Tx PL on
-;44=remote,104 ; Low Pwr
-;45=remote,105 ; Med Pwr
-;46=remote,106 ; Hi Pwr
-;5=remote,5 ; Status
-
-;[telemetry]
-
-; Telemetry entries are shared across all repeaters
-; Can be a tone sequence, morse string, or a file
-;
-; |t - Tone escape sequence
-;
-; Tone sequences consist of 1 or more 4-tuple entries (freq1, freq2, duration, amplitude)
-; Single frequencies are created by setting freq1 or freq2 to zero.
-;
-; |m - Morse escape sequence
-;
-; Sends Morse code at the telemetry amplitude and telemetry frequency as defined in the
-; [morse] section.
-;
-; Follow with an alphanumeric string
-;
-; |i - Morse ID escape sequence
-;
-; Sends Morse code at the ID amplitude and ID frequency as defined in the
-; [morse] section.
-;
-; Follow with an alphanumeric string
-
-
-;ct1=|t(350,0,100,2048)(500,0,100,2048)(660,0,100,2048)
-;ct2=|t(660,880,150,2048)
-;ct3=|t(440,0,150,2048)
-;ct4=|t(550,0,150,2048)
-;ct5=|t(660,0,150,2048)
-;ct6=|t(880,0,150,2048)
-;ct7=|t(660,440,150,2048)
-;ct8=|t(700,1100,150,2048)
-;remotetx=|t(2000,0,75,2048)(0,0,75,0)(1600,0,75,2048);
-;remotemon=|t(1600,0,75,2048)
-;cmdmode=|t(900,903,200,2048)
-;functcomplete=|t(1000,0,100,2048)(0,0,100,0)(1000,0,100,2048)
-
-
-;[morse]
-
-;speed=20 ; Approximate speed in WPM
-;frequency=800 ; Morse Telemetry Frequency
-;amplitude=4096 ; Morse Telemetry Amplitude
-;idfrequency=330 ; Morse ID Frequency
-;idamplitude=2048 ; Morse ID Amplitude
-
-;[nodes]
-
-;000 = context_A@foo.bar.com/1234,foo.bar.com
-;001 = context_B@baz.waldo.com/4321,baz.waldo.com
-;002 = context_C@pepper.salt.com/5678,pepper.salt.com,y ; this is a remote
-
-;of course, you can also specify these with domain names, but why rely
-;on DNS working unnecessarily?
-
-;[memory]
-
-;; this example gives you 146.460, simplex, 100.0 HZ PL, hi-power, transmit PL
-;00 = 146.460,100.0,sht
-;; this example gives you 146.940, minus offset, 100.0 HZ PL, low-power, no PL
-;01 = 146.940,100.0,-l
-
-; The format for these entries is: Receive-Freq,Receive-PL,Attrbutes
-; Attributes: l=low power, m=medium power, h=high power, -=minus offset,
-; s=simplex, +=plus offset, t=tx PL enable, r=rx PL enable
-
diff --git a/1.4/configs/rtp.conf.sample b/1.4/configs/rtp.conf.sample
deleted file mode 100644
index a96a0a09b..000000000
--- a/1.4/configs/rtp.conf.sample
+++ /dev/null
@@ -1,22 +0,0 @@
-;
-; RTP Configuration
-;
-[general]
-;
-; RTP start and RTP end configure start and end addresses
-;
-; Defaults are rtpstart=5000 and rtpend=31000
-;
-rtpstart=10000
-rtpend=20000
-;
-; Whether to enable or disable UDP checksums on RTP traffic
-;
-;rtpchecksums=no
-;
-; The amount of time a DTMF digit with no 'end' marker should be
-; allowed to continue (in 'samples', 1/8000 of a second)
-;
-;dtmftimeout=3000
-; rtcpinterval = 5000 ; Milliseconds between rtcp reports
- ;(min 500, max 60000, default 5000)
diff --git a/1.4/configs/say.conf.sample b/1.4/configs/say.conf.sample
deleted file mode 100644
index c5ad62071..000000000
--- a/1.4/configs/say.conf.sample
+++ /dev/null
@@ -1,171 +0,0 @@
-; say.conf
-;
-; language configuration
-;
-; The new language routines produce strings of the form
-; prefix:[format:]data
-; that are matched against the rules in this file to produce
-; an output.
-;
-; The data is generally the string to be spelled (either a number,
-; an ascii string or a date/time in the format specified below).
-; It is available, in the right hand side of a rule, as variable ${SAY}.
-;
-; The format is optional and normally used only for date/time.
-; The prefix is used to select the pronunciation - standard
-; prefixes are
-; num used for numbers
-; enum used for enumerations
-; date for dates
-; time for times
-; datetime for dates and times
-; char for character strings
-; phonetic for phonetic strings
-; digit for digit strings
-;
-; but others can be used at will.
-;
-; Processing occurs as follows:
-; If the format is empty, or there is no format, the entire
-; string is matched against one of the pattern on the left hand side.
-; On the first match, the various comma-separated components on the right
-; hand side are pronounced, as follows:
-; + a component starting with a prefix: (i.e. with a ':' in it)
-; is re-processed according to these rules;
-; + a component without a ':' in it is considered a filename and
-; the corresponding file is played.
-;
-; If the format is non-empty, the format is split into its components
-; (individual characters, or filenames in single quotes), and then
-; filenames are played, whereas single characters are used to
-; generate a new string format:pat:data to be processed.
-;
-; DATES/AND TIMES assume that the date info is available in
-; the form YYYYMMDDHHmm.ss-dow-doy
-; with 4 digits for the year, 2 for month, day, hour, minutes, seconds,
-; one digit for the day-of-week, and 3 digits for the day-of-year.
-;
-; Example:
-; datetime::200604172030.00-4-102
-; (typical format for a date) is first matched against the line
-; datetime::. => date:AdBY 'digits/at' IMp:${SAY}
-; which is normally present with the default format for dates.
-; In turn, the format string "AdBY 'digits/at' IMp" results in
-; the sequence
-; date:A:200604172030.00-4-102
-; date:d:200604172030.00-4-102
-; date:B:200604172030.00-4-102
-; date:Y:200604172030.00-4-102
-; digits/at
-; date:I:200604172030.00-4-102
-; date:M:200604172030.00-4-102
-; date:p:200604172030.00-4-102
-;
-;
-; Remember, normally X Z N are special, and the search is
-; case insensitive, so you must use [X] [N] [Z] .. if you
-; want exact match.
-
-; We start with the basic rules that might be more-or-less
-; language-independent
-
-[digit-base](!) ; base rule for digit strings
- ; XXX incomplete yet
- _digit:[0-9] => digits/${SAY}
- _digit:[-] => letters/dash
- _digit:[*] => letters/star
- _digit:[@] => letters/at
- _digit:[0-9]. => digit:${SAY:0:1}, digit:${SAY:1}
-
-[date-base](!) ; base rules for dates and times
- ; the 'SAY' variable contains YYYYMMDDHHmm.ss-dow-doy
- ; these rule map the strftime attributes.
- _date:Y:. => num:${SAY:0:4} ; year, 19xx
- _date:[Bb]:. => digits/mon-$[${SAY:4:2}-1] ; month name, 0..11
- _date:[Aa]:. => digits/day-${SAY:16:1} ; day of week
- _date:[de]:. => num:${SAY:6:2} ; day of month
- _date:[hH]:. => num:${SAY:8:2} ; hour
- _date:[I]:. => num:$[${SAY:8:2} % 12] ; hour 0-12
- _date:[M]:. => num:${SAY:10:2} ; minute
- ; XXX too bad the '?' function does not remove the quotes
- ; _date:[pP]:. => digits/$[ ${SAY:10:2} > 12 ? "p-m" :: "a-m"] ; am pm
- _date:[pP]:. => digits/p-m ; am pm
- _date:[S]:. => num:${SAY:13:2} ; seconds
-
-[en-base](!)
- _[n]um:0. => num:${SAY:1}
- _[n]um:X => digits/${SAY}
- _[n]um:1X => digits/${SAY}
- _[n]um:[2-9]0 => digits/${SAY}
- _[n]um:[2-9][1-9] => digits/${SAY:0:1}0, num:${SAY:1}
- _[n]um:XXX => num:${SAY:0:1}, digits/hundred, num:${SAY:1}
-
- _[n]um:XXXX => num:${SAY:0:1}, digits/thousand, num:${SAY:1}
- _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
- _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3}
-
- _[n]um:XXXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
- _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/million, num:${SAY:2}
- _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/million, num:${SAY:3}
-
- _[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1}
- _[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2}
- _[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3}
-
- ; enumeration
- _e[n]um:X => digits/h-${SAY}
- _e[n]um:1X => digits/h-${SAY}
- _e[n]um:[2-9]0 => digits/h-${SAY}
- _e[n]um:[2-9][1-9] => num:${SAY:0:1}0, digits/h-${SAY:1}
- _e[n]um:[1-9]XX => num:${SAY:0:1}, digits/hundred, enum:${SAY:1}
-
-[it](digit-base,date-base)
- _[n]um:0. => num:${SAY:1}
- _[n]um:X => digits/${SAY}
- _[n]um:1X => digits/${SAY}
- _[n]um:[2-9]0 => digits/${SAY}
- _[n]um:[2-9][1-9] => digits/${SAY:0:1}0, num:${SAY:1}
- _[n]um:1XX => digits/hundred, num:${SAY:1}
- _[n]um:[2-9]XX => num:${SAY:0:1}, digits/hundred, num:${SAY:1}
-
- _[n]um:1XXX => digits/thousand, num:${SAY:1}
- _[n]um:[2-9]XXX => num:${SAY:0:1}, digits/thousands, num:${SAY:1}
- _[n]um:XXXXX => num:${SAY:0:2}, digits/thousands, num:${SAY:2}
- _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousands, num:${SAY:3}
-
- _[n]um:1XXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
- _[n]um:[2-9]XXXXXX => num:${SAY:0:1}, digits/millions, num:${SAY:1}
- _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2}
- _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3}
-
- _datetime::. => date:AdBY 'digits/at' IMp:${SAY}
- _date::. => date:AdBY:${SAY}
- _time::. => date:IMp:${SAY}
-
-[en](en-base,date-base,digit-base)
- _datetime::. => date:AdBY 'digits/at' IMp:${SAY}
- _date::. => date:AdBY:${SAY}
- _time::. => date:IMp:${SAY}
-
-[de](date-base,digit-base)
- _[n]um:0. => num:${SAY:1}
- _[n]um:X => digits/${SAY}
- _[n]um:1X => digits/${SAY}
- _[n]um:[2-9]0 => digits/${SAY}
- _[n]um:[2-9][1-9] => digits/${SAY:1}-and, digits/${SAY:0:1}0
- _[n]um:1XX => digits/ein, digits/hundred, num:${SAY:1}
- _[n]um:[2-9]XX => digits/${SAY:0:1}, digits/hundred, num:${SAY:1}
- _[n]um:1XXX => digits/ein, digits/thousand, num:${SAY:1}
- _[n]um:[2-9]XXX => digits/${SAY:0:1}, digits/thousand, num:${SAY:1}
- _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
- _[n]um:X00XXX => digits/${SAY:0:1}, digits/hundred, digits/thousand, num:${SAY:3}
- _[n]um:XXXXXX => digits/${SAY:0:1}, digits/hundred, num:${SAY:1}
- _[n]um:1XXXXXX => digits/eine, digits/million, num:${SAY:1}
- _[n]um:[2-9]XXXXXX => digits/${SAY:0:1}, digits/millions, num:${SAY:1}
- _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2}
- _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3}
-
- _datetime::. => date:AdBY 'digits/at' IMp:${SAY}
- _date::. => date:AdBY:${SAY}
- _time::. => date:IMp:${SAY}
-
diff --git a/1.4/configs/sip.conf.sample b/1.4/configs/sip.conf.sample
deleted file mode 100644
index 42c32607e..000000000
--- a/1.4/configs/sip.conf.sample
+++ /dev/null
@@ -1,664 +0,0 @@
-;
-; SIP Configuration example for Asterisk
-;
-; Syntax for specifying a SIP device in extensions.conf is
-; SIP/devicename where devicename is defined in a section below.
-;
-; You may also use
-; SIP/username@domain to call any SIP user on the Internet
-; (Don't forget to enable DNS SRV records if you want to use this)
-;
-; If you define a SIP proxy as a peer below, you may call
-; SIP/proxyhostname/user or SIP/user@proxyhostname
-; where the proxyhostname is defined in a section below
-;
-; Useful CLI commands to check peers/users:
-; sip show peers Show all SIP peers (including friends)
-; sip show users Show all SIP users (including friends)
-; sip show registry Show status of hosts we register with
-;
-; sip debug Show all SIP messages
-;
-; reload chan_sip.so Reload configuration file
-; Active SIP peers will not be reconfigured
-;
-
-[general]
-context=default ; Default context for incoming calls
-;allowguest=no ; Allow or reject guest calls (default is yes)
-allowoverlap=no ; Disable overlap dialing support. (Default is yes)
-;allowtransfer=no ; Disable all transfers (unless enabled in peers or users)
- ; Default is enabled
-;realm=mydomain.tld ; Realm for digest authentication
- ; defaults to "asterisk". If you set a system name in
- ; asterisk.conf, it defaults to that system name
- ; Realms MUST be globally unique according to RFC 3261
- ; Set this to your host name or domain name
-bindport=5060 ; UDP Port to bind to (SIP standard port is 5060)
- ; bindport is the local UDP port that Asterisk will listen on
-bindaddr=0.0.0.0 ; IP address to bind to (0.0.0.0 binds to all)
-srvlookup=yes ; Enable DNS SRV lookups on outbound calls
- ; Note: Asterisk only uses the first host
- ; in SRV records
- ; Disabling DNS SRV lookups disables the
- ; ability to place SIP calls based on domain
- ; names to some other SIP users on the Internet
-
-;domain=mydomain.tld ; Set default domain for this host
- ; If configured, Asterisk will only allow
- ; INVITE and REFER to non-local domains
- ; Use "sip show domains" to list local domains
-;pedantic=yes ; Enable checking of tags in headers,
- ; international character conversions in URIs
- ; and multiline formatted headers for strict
- ; SIP compatibility (defaults to "no")
-
-; See doc/ip-tos.txt for a description of these parameters.
-;tos_sip=cs3 ; Sets TOS for SIP packets.
-;tos_audio=ef ; Sets TOS for RTP audio packets.
-;tos_video=af41 ; Sets TOS for RTP video packets.
-
-;maxexpiry=3600 ; Maximum allowed time of incoming registrations
- ; and subscriptions (seconds)
-;minexpiry=60 ; Minimum length of registrations/subscriptions (default 60)
-;defaultexpiry=120 ; Default length of incoming/outgoing registration
-;t1min=100 ; Minimum roundtrip time for messages to monitored hosts
- ; Defaults to 100 ms
-;notifymimetype=text/plain ; Allow overriding of mime type in MWI NOTIFY
-;checkmwi=10 ; Default time between mailbox checks for peers
-;buggymwi=no ; Cisco SIP firmware doesn't support the MWI RFC
- ; fully. Enable this option to not get error messages
- ; when sending MWI to phones with this bug.
-;vmexten=voicemail ; dialplan extension to reach mailbox sets the
- ; Message-Account in the MWI notify message
- ; defaults to "asterisk"
-;disallow=all ; First disallow all codecs
-;allow=ulaw ; Allow codecs in order of preference
-;allow=ilbc ; see doc/rtp-packetization for framing options
-;
-; This option specifies a preference for which music on hold class this channel
-; should listen to when put on hold if the music class has not been set on the
-; channel with Set(CHANNEL(musicclass)=whatever) in the dialplan, and the peer
-; channel putting this one on hold did not suggest a music class.
-;
-; This option may be specified globally, or on a per-user or per-peer basis.
-;
-;mohinterpret=default
-;
-; This option specifies which music on hold class to suggest to the peer channel
-; when this channel places the peer on hold. It may be specified globally or on
-; a per-user or per-peer basis.
-;
-;mohsuggest=default
-;
-;language=en ; Default language setting for all users/peers
- ; This may also be set for individual users/peers
-;relaxdtmf=yes ; Relax dtmf handling
-;trustrpid = no ; If Remote-Party-ID should be trusted
-;sendrpid = yes ; If Remote-Party-ID should be sent
-;progressinband=never ; If we should generate in-band ringing always
- ; use 'never' to never use in-band signalling, even in cases
- ; where some buggy devices might not render it
- ; Valid values: yes, no, never Default: never
-;useragent=Asterisk PBX ; Allows you to change the user agent string
-;promiscredir = no ; If yes, allows 302 or REDIR to non-local SIP address
- ; Note that promiscredir when redirects are made to the
- ; local system will cause loops since Asterisk is incapable
- ; of performing a "hairpin" call.
-;usereqphone = no ; If yes, ";user=phone" is added to uri that contains
- ; a valid phone number
-;dtmfmode = rfc2833 ; Set default dtmfmode for sending DTMF. Default: rfc2833
- ; Other options:
- ; info : SIP INFO messages
- ; inband : Inband audio (requires 64 kbit codec -alaw, ulaw)
- ; auto : Use rfc2833 if offered, inband otherwise
-
-;compactheaders = yes ; send compact sip headers.
-;
-;videosupport=yes ; Turn on support for SIP video. You need to turn this on
- ; in the this section to get any video support at all.
- ; You can turn it off on a per peer basis if the general
- ; video support is enabled, but you can't enable it for
- ; one peer only without enabling in the general section.
-;maxcallbitrate=384 ; Maximum bitrate for video calls (default 384 kb/s)
- ; Videosupport and maxcallbitrate is settable
- ; for peers and users as well
-;callevents=no ; generate manager events when sip ua
- ; performs events (e.g. hold)
-;alwaysauthreject = yes ; When an incoming INVITE or REGISTER is to be rejected,
- ; for any reason, always reject with '401 Unauthorized'
- ; instead of letting the requester know whether there was
- ; a matching user or peer for their request
-
-;g726nonstandard = yes ; If the peer negotiates G726-32 audio, use AAL2 packing
- ; order instead of RFC3551 packing order (this is required
- ; for Sipura and Grandstream ATAs, among others). This is
- ; contrary to the RFC3551 specification, the peer _should_
- ; be negotiating AAL2-G726-32 instead :-(
-
-;matchexterniplocally = yes ; Only substitute the externip or externhost setting if it matches
- ; your localnet setting. Unless you have some sort of strange network
- ; setup you will not need to enable this.
-
-;
-; If regcontext is specified, Asterisk will dynamically create and destroy a
-; NoOp priority 1 extension for a given peer who registers or unregisters with
-; us and have a "regexten=" configuration item.
-; Multiple contexts may be specified by separating them with '&'. The
-; actual extension is the 'regexten' parameter of the registering peer or its
-; name if 'regexten' is not provided. If more than one context is provided,
-; the context must be specified within regexten by appending the desired
-; context after '@'. More than one regexten may be supplied if they are
-; separated by '&'. Patterns may be used in regexten.
-;
-;regcontext=sipregistrations
-;
-;--------------------------- RTP timers ----------------------------------------------------
-; These timers are currently used for both audio and video streams. The RTP timeouts
-; are only applied to the audio channel.
-; The settings are settable in the global section as well as per device
-;
-;rtptimeout=60 ; Terminate call if 60 seconds of no RTP or RTCP activity
- ; on the audio channel
- ; when we're not on hold. This is to be able to hangup
- ; a call in the case of a phone disappearing from the net,
- ; like a powerloss or grandma tripping over a cable.
-;rtpholdtimeout=300 ; Terminate call if 300 seconds of no RTP or RTCP activity
- ; on the audio channel
- ; when we're on hold (must be > rtptimeout)
-;rtpkeepalive=<secs> ; Send keepalives in the RTP stream to keep NAT open
- ; (default is off - zero)
-;--------------------------- SIP DEBUGGING ---------------------------------------------------
-;sipdebug = yes ; Turn on SIP debugging by default, from
- ; the moment the channel loads this configuration
-;recordhistory=yes ; Record SIP history by default
- ; (see sip history / sip no history)
-;dumphistory=yes ; Dump SIP history at end of SIP dialogue
- ; SIP history is output to the DEBUG logging channel
-
-
-;--------------------------- STATUS NOTIFICATIONS (SUBSCRIPTIONS) ----------------------------
-; You can subscribe to the status of extensions with a "hint" priority
-; (See extensions.conf.sample for examples)
-; chan_sip support two major formats for notifications: dialog-info and SIMPLE
-;
-; You will get more detailed reports (busy etc) if you have a call limit set
-; for a device. When the call limit is filled, we will indicate busy. Note that
-; you need at least 2 in order to be able to do attended transfers.
-;
-; For queues, you will need this level of detail in status reporting, regardless
-; if you use SIP subscriptions. Queues and manager use the same internal interface
-; for reading status information.
-;
-; Note: Subscriptions does not work if you have a realtime dialplan and use the
-; realtime switch.
-;
-;allowsubscribe=no ; Disable support for subscriptions. (Default is yes)
-;subscribecontext = default ; Set a specific context for SUBSCRIBE requests
- ; Useful to limit subscriptions to local extensions
- ; Settable per peer/user also
-;notifyringing = yes ; Notify subscriptions on RINGING state (default: no)
-;notifyhold = yes ; Notify subscriptions on HOLD state (default: no)
- ; Turning on notifyringing and notifyhold will add a lot
- ; more database transactions if you are using realtime.
-;limitonpeers = yes ; Apply call limits on peers only. This will improve
- ; status notification when you are using type=friend
- ; Inbound calls, that really apply to the user part
- ; of a friend will now be added to and compared with
- ; the peer limit instead of applying two call limits,
- ; one for the peer and one for the user.
- ; "sip show inuse" will only show active calls on
- ; the peer side of a "type=friend" object if this
- ; setting is turned on.
-
-;----------------------------------------- T.38 FAX PASSTHROUGH SUPPORT -----------------------
-;
-; This setting is available in the [general] section as well as in device configurations.
-; Setting this to yes, enables T.38 fax (UDPTL) passthrough on SIP to SIP calls, provided
-; both parties have T38 support enabled in their Asterisk configuration
-; This has to be enabled in the general section for all devices to work. You can then
-; disable it on a per device basis.
-;
-; T.38 faxing only works in SIP to SIP calls, with no local or agent channel being used.
-;
-; t38pt_udptl = yes ; Default false
-;
-;----------------------------------------- OUTBOUND SIP REGISTRATIONS ------------------------
-; Asterisk can register as a SIP user agent to a SIP proxy (provider)
-; Format for the register statement is:
-; register => user[:secret[:authuser]]@host[:port][/extension]
-;
-; If no extension is given, the 's' extension is used. The extension needs to
-; be defined in extensions.conf to be able to accept calls from this SIP proxy
-; (provider).
-;
-; host is either a host name defined in DNS or the name of a section defined
-; below.
-;
-; Examples:
-;
-;register => 1234:password@mysipprovider.com
-;
-; This will pass incoming calls to the 's' extension
-;
-;
-;register => 2345:password@sip_proxy/1234
-;
-; Register 2345 at sip provider 'sip_proxy'. Calls from this provider
-; connect to local extension 1234 in extensions.conf, default context,
-; unless you configure a [sip_proxy] section below, and configure a
-; context.
-; Tip 1: Avoid assigning hostname to a sip.conf section like [provider.com]
-; Tip 2: Use separate type=peer and type=user sections for SIP providers
-; (instead of type=friend) if you have calls in both directions
-
-;registertimeout=20 ; retry registration calls every 20 seconds (default)
-;registerattempts=10 ; Number of registration attempts before we give up
- ; 0 = continue forever, hammering the other server
- ; until it accepts the registration
- ; Default is 0 tries, continue forever
-
-;----------------------------------------- NAT SUPPORT ------------------------
-; The externip, externhost and localnet settings are used if you use Asterisk
-; behind a NAT device to communicate with services on the outside.
-
-;externip = 200.201.202.203 ; Address that we're going to put in outbound SIP
- ; messages if we're behind a NAT
-
- ; The externip and localnet is used
- ; when registering and communicating with other proxies
- ; that we're registered with
-;externhost=foo.dyndns.net ; Alternatively you can specify an
- ; external host, and Asterisk will
- ; perform DNS queries periodically. Not
- ; recommended for production
- ; environments! Use externip instead
-;externrefresh=10 ; How often to refresh externhost if
- ; used
- ; You may add multiple local networks. A reasonable
- ; set of defaults are:
-;localnet=192.168.0.0/255.255.0.0; All RFC 1918 addresses are local networks
-;localnet=10.0.0.0/255.0.0.0 ; Also RFC1918
-;localnet=172.16.0.0/12 ; Another RFC1918 with CIDR notation
-;localnet=169.254.0.0/255.255.0.0 ;Zero conf local network
-
-; The nat= setting is used when Asterisk is on a public IP, communicating with
-; devices hidden behind a NAT device (broadband router). If you have one-way
-; audio problems, you usually have problems with your NAT configuration or your
-; firewall's support of SIP+RTP ports. You configure Asterisk choice of RTP
-; ports for incoming audio in rtp.conf
-;
-;nat=no ; Global NAT settings (Affects all peers and users)
- ; yes = Always ignore info and assume NAT
- ; no = Use NAT mode only according to RFC3581 (;rport)
- ; never = Never attempt NAT mode or RFC3581 support
- ; route = Assume NAT, don't send rport
- ; (work around more UNIDEN bugs)
-
-;----------------------------------- MEDIA HANDLING --------------------------------
-; By default, Asterisk tries to re-invite the audio to an optimal path. If there's
-; no reason for Asterisk to stay in the media path, the media will be redirected.
-; This does not really work with in the case where Asterisk is outside and have
-; clients on the inside of a NAT. In that case, you want to set canreinvite=nonat
-;
-;canreinvite=yes ; Asterisk by default tries to redirect the
- ; RTP media stream (audio) to go directly from
- ; the caller to the callee. Some devices do not
- ; support this (especially if one of them is behind a NAT).
- ; The default setting is YES. If you have all clients
- ; behind a NAT, or for some other reason wants Asterisk to
- ; stay in the audio path, you may want to turn this off.
-
- ; In Asterisk 1.4 this setting also affect direct RTP
- ; at call setup (a new feature in 1.4 - setting up the
- ; call directly between the endpoints instead of sending
- ; a re-INVITE).
-
-;directrtpsetup=yes ; Enable the new experimental direct RTP setup. This sets up
- ; the call directly with media peer-2-peer without re-invites.
- ; Will not work for video and cases where the callee sends
- ; RTP payloads and fmtp headers in the 200 OK that does not match the
- ; callers INVITE. This will also fail if canreinvite is enabled when
- ; the device is actually behind NAT.
-
-;canreinvite=nonat ; An additional option is to allow media path redirection
- ; (reinvite) but only when the peer where the media is being
- ; sent is known to not be behind a NAT (as the RTP core can
- ; determine it based on the apparent IP address the media
- ; arrives from).
-
-;canreinvite=update ; Yet a third option... use UPDATE for media path redirection,
- ; instead of INVITE. This can be combined with 'nonat', as
- ; 'canreinvite=update,nonat'. It implies 'yes'.
-
-;----------------------------------------- REALTIME SUPPORT ------------------------
-; For additional information on ARA, the Asterisk Realtime Architecture,
-; please read realtime.txt and extconfig.txt in the /doc directory of the
-; source code.
-;
-;rtcachefriends=yes ; Cache realtime friends by adding them to the internal list
- ; just like friends added from the config file only on a
- ; as-needed basis? (yes|no)
-
-;rtsavesysname=yes ; Save systemname in realtime database at registration
- ; Default= no
-
-;rtupdate=yes ; Send registry updates to database using realtime? (yes|no)
- ; If set to yes, when a SIP UA registers successfully, the ip address,
- ; the origination port, the registration period, and the username of
- ; the UA will be set to database via realtime.
- ; If not present, defaults to 'yes'.
-;rtautoclear=yes ; Auto-Expire friends created on the fly on the same schedule
- ; as if it had just registered? (yes|no|<seconds>)
- ; If set to yes, when the registration expires, the friend will
- ; vanish from the configuration until requested again. If set
- ; to an integer, friends expire within this number of seconds
- ; instead of the registration interval.
-
-;ignoreregexpire=yes ; Enabling this setting has two functions:
- ;
- ; For non-realtime peers, when their registration expires, the
- ; information will _not_ be removed from memory or the Asterisk database
- ; if you attempt to place a call to the peer, the existing information
- ; will be used in spite of it having expired
- ;
- ; For realtime peers, when the peer is retrieved from realtime storage,
- ; the registration information will be used regardless of whether
- ; it has expired or not; if it expires while the realtime peer
- ; is still in memory (due to caching or other reasons), the
- ; information will not be removed from realtime storage
-
-;----------------------------------------- SIP DOMAIN SUPPORT ------------------------
-; Incoming INVITE and REFER messages can be matched against a list of 'allowed'
-; domains, each of which can direct the call to a specific context if desired.
-; By default, all domains are accepted and sent to the default context or the
-; context associated with the user/peer placing the call.
-; Domains can be specified using:
-; domain=<domain>[,<context>]
-; Examples:
-; domain=myasterisk.dom
-; domain=customer.com,customer-context
-;
-; In addition, all the 'default' domains associated with a server should be
-; added if incoming request filtering is desired.
-; autodomain=yes
-;
-; To disallow requests for domains not serviced by this server:
-; allowexternaldomains=no
-
-;domain=mydomain.tld,mydomain-incoming
- ; Add domain and configure incoming context
- ; for external calls to this domain
-;domain=1.2.3.4 ; Add IP address as local domain
- ; You can have several "domain" settings
-;allowexternaldomains=no ; Disable INVITE and REFER to non-local domains
- ; Default is yes
-;autodomain=yes ; Turn this on to have Asterisk add local host
- ; name and local IP to domain list.
-
-; fromdomain=mydomain.tld ; When making outbound SIP INVITEs to
- ; non-peers, use your primary domain "identity"
- ; for From: headers instead of just your IP
- ; address. This is to be polite and
- ; it may be a mandatory requirement for some
- ; destinations which do not have a prior
- ; account relationship with your server.
-
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
-; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
- ; SIP channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The SIP channel can accept jitter,
- ; thus a jitterbuffer on the receive SIP side will be used only
- ; if it is forced and enabled.
-
-; jbforce = no ; Forces the use of a jitterbuffer on the receive side of a SIP
- ; channel. Defaults to "no".
-
-; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
-; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usually sent from exotic devices
- ; and programs. Defaults to 1000.
-
-; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a SIP
- ; channel. Two implementations are currently available - "fixed"
- ; (with size always equals to jbmaxsize) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
-; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
-
-[authentication]
-; Global credentials for outbound calls, i.e. when a proxy challenges your
-; Asterisk server for authentication. These credentials override
-; any credentials in peer/register definition if realm is matched.
-;
-; This way, Asterisk can authenticate for outbound calls to other
-; realms. We match realm on the proxy challenge and pick an set of
-; credentials from this list
-; Syntax:
-; auth = <user>:<secret>@<realm>
-; auth = <user>#<md5secret>@<realm>
-; Example:
-;auth=mark:topsecret@digium.com
-;
-; You may also add auth= statements to [peer] definitions
-; Peer auth= override all other authentication settings if we match on realm
-
-;------------------------------------------------------------------------------
-; Users and peers have different settings available. Friends have all settings,
-; since a friend is both a peer and a user
-;
-; User config options: Peer configuration:
-; -------------------- -------------------
-; context context
-; callingpres callingpres
-; permit permit
-; deny deny
-; secret secret
-; md5secret md5secret
-; dtmfmode dtmfmode
-; canreinvite canreinvite
-; nat nat
-; callgroup callgroup
-; pickupgroup pickupgroup
-; language language
-; allow allow
-; disallow disallow
-; insecure insecure
-; trustrpid trustrpid
-; progressinband progressinband
-; promiscredir promiscredir
-; useclientcode useclientcode
-; accountcode accountcode
-; setvar setvar
-; callerid callerid
-; amaflags amaflags
-; call-limit call-limit
-; allowoverlap allowoverlap
-; allowsubscribe allowsubscribe
-; allowtransfer allowtransfer
-; subscribecontext subscribecontext
-; videosupport videosupport
-; maxcallbitrate maxcallbitrate
-; rfc2833compensate mailbox
-; username
-; template
-; fromdomain
-; regexten
-; fromuser
-; host
-; port
-; qualify
-; defaultip
-; rtptimeout
-; rtpholdtimeout
-; sendrpid
-; outboundproxy
-; rfc2833compensate
-
-;[sip_proxy]
-; For incoming calls only. Example: FWD (Free World Dialup)
-; We match on IP address of the proxy for incoming calls
-; since we can not match on username (caller id)
-;type=peer
-;context=from-fwd
-;host=fwd.pulver.com
-
-;[sip_proxy-out]
-;type=peer ; we only want to call out, not be called
-;secret=guessit
-;username=yourusername ; Authentication user for outbound proxies
-;fromuser=yourusername ; Many SIP providers require this!
-;fromdomain=provider.sip.domain
-;host=box.provider.com
-;usereqphone=yes ; This provider requires ";user=phone" on URI
-;call-limit=5 ; permit only 5 simultaneous outgoing calls to this peer
-;outboundproxy=proxy.provider.domain ; send outbound signaling to this proxy, not directly to the peer
- ; Call-limits will not be enforced on real-time peers,
- ; since they are not stored in-memory
-;port=80 ; The port number we want to connect to on the remote side
- ; Also used as "defaultport" in combination with "defaultip" settings
-
-;------------------------------------------------------------------------------
-; Definitions of locally connected SIP devices
-;
-; type = user a device that authenticates to us by "from" field to place calls
-; type = peer a device we place calls to or that calls us and we match by host
-; type = friend two configurations (peer+user) in one
-;
-; For device names, we recommend using only a-z, numerics (0-9) and underscore
-;
-; For local phones, type=friend works most of the time
-;
-; If you have one-way audio, you probably have NAT problems.
-; If Asterisk is on a public IP, and the phone is inside of a NAT device
-; you will need to configure nat option for those phones.
-; Also, turn on qualify=yes to keep the nat session open
-
-;[grandstream1]
-;type=friend
-;context=from-sip ; Where to start in the dialplan when this phone calls
-;callerid=John Doe <1234> ; Full caller ID, to override the phones config
- ; on incoming calls to Asterisk
-;host=192.168.0.23 ; we have a static but private IP address
- ; No registration allowed
-;nat=no ; there is not NAT between phone and Asterisk
-;canreinvite=yes ; allow RTP voice traffic to bypass Asterisk
-;dtmfmode=info ; either RFC2833 or INFO for the BudgeTone
-;call-limit=1 ; permit only 1 outgoing call and 1 incoming call at a time
- ; from the phone to asterisk
- ; 1 for the explicit peer, 1 for the explicit user,
- ; remember that a friend equals 1 peer and 1 user in
- ; memory
- ; This will affect your subscriptions as well.
- ; There is no combined call counter for a "friend"
- ; so there's currently no way in sip.conf to limit
- ; to one inbound or outbound call per phone. Use
- ; the group counters in the dial plan for that.
- ;
-;mailbox=1234@default ; mailbox 1234 in voicemail context "default"
-;disallow=all ; need to disallow=all before we can use allow=
-;allow=ulaw ; Note: In user sections the order of codecs
- ; listed with allow= does NOT matter!
-;allow=alaw
-;allow=g723.1 ; Asterisk only supports g723.1 pass-thru!
-;allow=g729 ; Pass-thru only unless g729 license obtained
-;callingpres=allowed_passed_screen ; Set caller ID presentation
- ; See doc/callingpres.txt for more information
-
-
-;[xlite1]
-; Turn off silence suppression in X-Lite ("Transmit Silence"=YES)!
-; Note that Xlite sends NAT keep-alive packets, so qualify=yes is not needed
-;type=friend
-;regexten=1234 ; When they register, create extension 1234
-;callerid="Jane Smith" <5678>
-;host=dynamic ; This device needs to register
-;nat=yes ; X-Lite is behind a NAT router
-;canreinvite=no ; Typically set to NO if behind NAT
-;disallow=all
-;allow=gsm ; GSM consumes far less bandwidth than ulaw
-;allow=ulaw
-;allow=alaw
-;mailbox=1234@default,1233@default ; Subscribe to status of multiple mailboxes
-
-
-;[snom]
-;type=friend ; Friends place calls and receive calls
-;context=from-sip ; Context for incoming calls from this user
-;secret=blah
-;subscribecontext=localextensions ; Only allow SUBSCRIBE for local extensions
-;language=de ; Use German prompts for this user
-;host=dynamic ; This peer register with us
-;dtmfmode=inband ; Choices are inband, rfc2833, or info
-;defaultip=192.168.0.59 ; IP used until peer registers
-;mailbox=1234@context,2345 ; Mailbox(-es) for message waiting indicator
-;subscribemwi=yes ; Only send notifications if this phone
- ; subscribes for mailbox notification
-;vmexten=voicemail ; dialplan extension to reach mailbox
- ; sets the Message-Account in the MWI notify message
- ; defaults to global vmexten which defaults to "asterisk"
-;disallow=all
-;allow=ulaw ; dtmfmode=inband only works with ulaw or alaw!
-
-
-;[polycom]
-;type=friend ; Friends place calls and receive calls
-;context=from-sip ; Context for incoming calls from this user
-;secret=blahpoly
-;host=dynamic ; This peer register with us
-;dtmfmode=rfc2833 ; Choices are inband, rfc2833, or info
-;username=polly ; Username to use in INVITE until peer registers
- ; Normally you do NOT need to set this parameter
-;disallow=all
-;allow=ulaw ; dtmfmode=inband only works with ulaw or alaw!
-;progressinband=no ; Polycom phones don't work properly with "never"
-
-
-;[pingtel]
-;type=friend
-;secret=blah
-;host=dynamic
-;insecure=port ; Allow matching of peer by IP address without
- ; matching port number
-;insecure=invite ; Do not require authentication of incoming INVITEs
-;insecure=port,invite ; (both)
-;qualify=1000 ; Consider it down if it's 1 second to reply
- ; Helps with NAT session
- ; qualify=yes uses default value
-;
-; Call group and Pickup group should be in the range from 0 to 63
-;
-;callgroup=1,3-4 ; We are in caller groups 1,3,4
-;pickupgroup=1,3-5 ; We can do call pick-p for call group 1,3,4,5
-;defaultip=192.168.0.60 ; IP address to use if peer has not registered
-;deny=0.0.0.0/0.0.0.0 ; ACL: Control access to this account based on IP address
-;permit=192.168.0.60/255.255.255.0
-
-;[cisco1]
-;type=friend
-;secret=blah
-;qualify=200 ; Qualify peer is no more than 200ms away
-;nat=yes ; This phone may be natted
- ; Send SIP and RTP to the IP address that packet is
- ; received from instead of trusting SIP headers
-;host=dynamic ; This device registers with us
-;canreinvite=no ; Asterisk by default tries to redirect the
- ; RTP media stream (audio) to go directly from
- ; the caller to the callee. Some devices do not
- ; support this (especially if one of them is
- ; behind a NAT).
-;defaultip=192.168.0.4 ; IP address to use until registration
-;username=goran ; Username to use when calling this device before registration
- ; Normally you do NOT need to set this parameter
-;setvar=CUSTID=5678 ; Channel variable to be set for all calls from this device
-
-;[pre14-asterisk]
-;type=friend
-;secret=digium
-;host=dynamic
-;rfc2833compensate=yes ; Compensate for pre-1.4 DTMF transmission from another Asterisk machine.
- ; You must have this turned on or DTMF reception will work improperly.
diff --git a/1.4/configs/sip_notify.conf.sample b/1.4/configs/sip_notify.conf.sample
deleted file mode 100644
index ca7dbe3d0..000000000
--- a/1.4/configs/sip_notify.conf.sample
+++ /dev/null
@@ -1,22 +0,0 @@
-[polycom-check-cfg]
-Event=>check-sync
-Content-Length=>0
-
-; Untested
-[sipura-check-cfg]
-Event=>resync
-Content-Length=>0
-
-; Untested
-[grandstream-check-cfg]
-Event=>sys-control
-
-; Untested
-[cisco-check-cfg]
-Event=>check-sync
-Content-Length=>0
-
-; Tested
-[snom-check-cfg]
-Event=>check-sync\;reboot=false
-Content-Length=>0
diff --git a/1.4/configs/skinny.conf.sample b/1.4/configs/skinny.conf.sample
deleted file mode 100644
index 87c37e4d2..000000000
--- a/1.4/configs/skinny.conf.sample
+++ /dev/null
@@ -1,96 +0,0 @@
-;
-; Skinny Configuration for Asterisk
-;
-[general]
-bindaddr=0.0.0.0 ; Address to bind to
-bindport=2000 ; Port to bind to, default tcp/2000
-dateformat=M-D-Y ; M,D,Y in any order (6 chars max)
- ; "A" may also be used, but it must be at the end.
- ; Use M for month, D for day, Y for year, A for 12-hour time.
-keepalive=120
-
-;allow=all ; see doc/rtp-packetization for framing options
-;disallow=
-
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
-;jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
- ; skinny channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The skinny channel can accept
- ; jitter, thus a jitterbuffer on the receive skinny side will be
- ; used only if it is forced and enabled.
-
-;jbforce = no ; Forces the use of a jitterbuffer on the receive side of a skinny
- ; channel. Defaults to "no".
-
-;jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
-;jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usually sent from exotic devices
- ; and programs. Defaults to 1000.
-
-;jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a
- ; skinny channel. Two implementations are currently available
- ; - "fixed" (with size always equals to jbmaxsize)
- ; - "adaptive" (with variable size, actually the new jb of IAX2).
- ; Defaults to fixed.
-
-;jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
-
-;----------------------------------- DEVICE OPTIONS --------------------------------
-;earlyrtp=1 ; whether audio signalling should be provided by asterisk
- ; (earlyrtp=1) or device generated (earlyrtp=0).
- ; defaults to earlyrtp=1
-;-----------------------------------------------------------------------------------
-
-; Typical config for 12SP+
-;[florian]
-;device=SEP00D0BA847E6B
-;version=P002G204 ; Thanks critch
-;context=did
-;line => 120 ; Dial(Skinny/120@florian)
-
-
-; Typical config for a 7910
-;[duba] ; Device name
-;device=SEP0007EB463101 ; Official identifier
-;version=P002F202 ; Firmware version identifier
-;host=192.168.1.144
-;permit=192.168.0/24 ; Optional, used for authentication
-;nat=yes
-;callerid="George W. Bush" <202-456-1414>
-;mailbox=500
-;callwaiting=yes
-;transfer=yes
-;threewaycalling=yes
-;context=default
-;line => 500 ; Dial(Skinny/500@duba)
-;mohinterpret=default ; This option specifies a default music on hold class to
- ; use when put on hold if the channel's moh class was not
- ; explicitly set with Set(CHANNEL(musicclass)=whatever) and
- ; the peer channel did not suggest a class to use.
-;mohsuggest=default ; This option specifies which music on hold class to suggest to the peer channel
- ; when this channel places the peer on hold. It may be specified globally or on
- ; a per-user or per-peer basis.
-
-; Typical config for a 7940 with dual 7914s
-;[support]
-;device=SEP0007EB463121
-;nat=yes
-;callerid="Customer Support" <810-234-1212>
-;mailbox=100
-;context=inbound
-;linelabel="Support Line" ; Displays next to the line
- ; button on 7940's and 7960s
-;line => 100
-;callerid="John Chambers" <408-526-4000>
-;context=did
-;linelabel="John"
-;mailbox=110
-;line => 110
-;speeddial => 111,Jack Smith
-;speeddial => 112,Bob Peterson
-;addon => 7914
-;addon => 7914
diff --git a/1.4/configs/sla.conf.sample b/1.4/configs/sla.conf.sample
deleted file mode 100644
index 2e5c88b00..000000000
--- a/1.4/configs/sla.conf.sample
+++ /dev/null
@@ -1,140 +0,0 @@
-;
-; Configuration for Shared Line Appearances (SLA).
-;
-; See doc/sla.pdf for more information.
-;
-
-; ---- General Options ----------------
-[general]
-
-;attemptcallerid=no ; Attempt CallerID handling. The default value for this
- ; is "no" because CallerID handling with an SLA setup is
- ; known to not work properly in some situations. However,
- ; feel free to enable it if you would like. If you do, and
- ; you find problems, please do not report them.
-; -------------------------------------
-
-
-; ---- Trunk Declarations -------------
-;
-;[line1] ; Provide a name for this trunk.
-
-;type=trunk ; This line is what marks this entry as a trunk.
-
-;device=Zap/3 ; Map this trunk declaration to a specific device.
- ; NOTE: You can not just put any type of channel here.
- ; Zap channels can be directly used. IP trunks
- ; require some indirect configuration which is
- ; described in doc/sla.pdf.
-
-;autocontext=line1 ; This supports automatic generation of the dialplan entries
- ; if the autocontext option is used. Each trunk should have
- ; a unique context name. Then, in zapata.conf, this device
- ; should be configured to have incoming calls go to this context.
-
-;ringtimeout=30 ; Set how long to allow this trunk to ring on an inbound call before hanging
- ; it up as an unanswered call. The value is in seconds.
-
-;barge=no ; If this option is set to "no", then no station will be
- ; allowed to join a call that is in progress. The default
- ; value is "yes".
-
-;hold=private ; This option configure hold permissions for this trunk.
- ; "open" - This means that any station can put this trunk
- ; on hold, and any station can retrieve it from
- ; hold. This is the default.
- ; "private" - This means that once a station puts the
- ; trunk on hold, no other station will be
- ; allowed to retrieve the call from hold.
-
-;[line2]
-;type=trunk
-;device=Zap/4
-;autocontext=line2
-
-;[line3]
-;type=trunk
-;device=Zap/3
-;autocontext=line3
-
-;[line4]
-;type=trunk
-;device=Local/disa@line4_outbound ; A Local channel in combination with the Disa
- ; application can be used to support IP trunks.
- ; See doc/sla.pdf on more information on how
- ; IP trunks work.
-;autocontext=line4
-; --------------------------------------
-
-
-; ---- Station Declarations ------------
-
-;[station1] ; Define a name for this station.
-
-;type=station ; This line indicates that this entry is a station.
-
-;device=SIP/station1 ; Each station must be mapped to a device.
-
-;autocontext=sla_stations ; This supports automatic generation of the dialplan entries if
- ; the autocontext option is used. All stations can use the same
- ; context without conflict. The device for this station should
- ; have its context configured to the same one listed here.
-
-;ringtimeout=10 ; Set a timeout for how long to allow the station to ring for an
- ; incoming call, in seconds.
-
-;ringdelay=10 ; Set a time for how long to wait before beginning to ring this station
- ; once there is an incoming call, in seconds.
-
-;hold=private ; This option configure hold permissions for this station. Note
- ; that if private hold is set in the trunk entry, that will override
- ; anything here. However, if a trunk has open hold access, but this
- ; station is set to private hold, then the private hold will be in
- ; effect.
- ; "open" - This means that once this station puts a call
- ; on hold, any other station is allowed to retrieve
- ; it. This is the default.
- ; "private" - This means that once this station puts a
- ; call on hold, no other station will be
- ; allowed to retrieve the call from hold.
-
-
-;trunk=line1 ; Individually list all of the trunks that will appear on this station. This
- ; order is significant. It should be the same order as they appear on the
- ; phone. The order here defines the order of preference that the trunks will
- ; be used.
-;trunk=line2
-;trunk=line3,ringdelay=5 ; A ring delay for the station can also be specified for a specific trunk.
- ; If a ring delay is specified both for the whole station and for a specific
- ; trunk on a station, the setting for the specific trunk will take priority.
- ; This value is in seconds.
-
-;trunk=line4,ringtimeout=5 ; A ring timeout for the station can also be specified for a specific trunk.
- ; If a ring timeout is specified both for the whole station and for a specific
- ; trunk on a station, the setting for the specific trunk will take priority.
- ; This value is in seconds.
-
-
-;[station](!) ; When there are a lot of stations that are configured the same way,
- ; it is convenient to use a configuration template like this so that
- ; the common settings stay in one place.
-;type=station
-;autocontext=sla_stations
-;trunk=line1
-;trunk=line2
-;trunk=line3
-;trunk=line4
-
-;[station2](station) ; Define a station that uses the configuration from the template "station".
-;device=SIP/station2
-;
-;[station3](station)
-;device=SIP/station3
-;
-;[station4](station)
-;device=SIP/station4
-;
-;[station5](station)
-;device=SIP/station5
-; --------------------------------------
-
diff --git a/1.4/configs/smdi.conf.sample b/1.4/configs/smdi.conf.sample
deleted file mode 100644
index 669530e81..000000000
--- a/1.4/configs/smdi.conf.sample
+++ /dev/null
@@ -1,75 +0,0 @@
-; Asterisk SMDI configuration
-
-[interfaces]
-; Specify serial ports to listen for SMDI messages on below. These will be
-; referenced later in zapata.conf. If you do not specify any interfaces then
-; SMDI will be disabled. Interfaces can have several different attributes
-; associated with them.
-
-; Set the number of stop bits to use per character here. The default is no,
-; in which case one stop bit will be used.
-
-;twostopbits = no
-
-; Character size or bit length is the size of each character sent across the
-; link. Character size can be 7 or 8. The default is 7.
-
-;charsize = 7
-
-; If you need parity checking enabled you can turn it on here. Acceptable
-; values are even, odd, and none. The default is even.
-
-;paritybit = even
-
-; The baudrate to use for this port. Acceptable values are 1200, 2400, 4800,
-; and 9600. The default is 9600.
-
-;baudrate = 1200
-
-; Often the numbering scheme for a set of mailboxes or extensions will not be 7
-; or 10 digits (as SMDI requires). Use the msdstrip option to strip unused
-; digits from the start of numbers.
-
-;msdstrip = 0
-
-; Occasionally Asterisk and the SMDI switch may become out of sync. If this
-; happens, Asterisk will appear one or several calls behind as it processes
-; voicemail requests. To prevent this from happening, adjust the msgexpirytime.
-; This will make Asterisk discard old SMDI messages that have not yet been
-; processed. The default expiry time is 30000 milliseconds.
-
-;msgexpirytime = 30000
-
-;smdiport => /dev/ttyS0
-
-
-[mailboxes]
-; This section configures parameters related to MWI handling for the SMDI link.
-
-; This option configures the polling interval used to check to see if the
-; mailboxes have any new messages. This option is specified in seconds.
-; The default value is 10 seconds.
-;
-;pollinginterval=10
-
-; Every other entry in this section of the configuration file is interpreted as
-; a mapping between the mailbox ID on the SMDI link, and the local Asterisk
-; mailbox name. In many cases, they are the same thing, but they still must be
-; listed here so that this module knows which mailboxes it needs to pay
-; attention to.
-;
-; Syntax:
-; <SMDI mailbox ID>=<Asterisk Mailbox Name>[@Asterisk Voicemail Context]
-;
-; If no Asterisk voicemail context is specified, "default" will be assumed.
-;
-; Before specifying mailboxes, you must specify an SMDI interface. All mailbox
-; definitions that follow will correspond to that SMDI interface. If you specify
-; another interface, then all definitions following that will correspond to the
-; new interface.
-;
-;smdiport=/dev/ttyS0
-;2565551234=1234@vmcontext1
-;2565555678=5678@vmcontext2
-;smdiport=/dev/ttyS1
-;2565559999=9999
diff --git a/1.4/configs/telcordia-1.adsi b/1.4/configs/telcordia-1.adsi
deleted file mode 100644
index 1486aa95e..000000000
--- a/1.4/configs/telcordia-1.adsi
+++ /dev/null
@@ -1,83 +0,0 @@
-;
-; Asterisk default ADSI script
-;
-;
-; Begin with the preamble requirements
-;
-DESCRIPTION "Telcordia Demo" ; Name of vendor
-VERSION 0x02 ; Version of stuff
-;SECURITY "_AST" ; Security code
-SECURITY 0x0000 ; Security code
-FDN 0x0000000f ; Descriptor number
-
-;
-; Predefined strings
-;
-DISPLAY "talkingto" IS "Talking To" "$Call1p" WRAP
-DISPLAY "titles" IS "20th Century IQ Svc"
-DISPLAY "newcall" IS "New Call From" "$Call1p" WRAP
-DISPLAY "ringing" IS "Ringing"
-
-;
-; Begin state definitions
-;
-STATE "callup" ; Call is currently up
-STATE "inactive" ; No active call
-
-;
-; Begin soft key definitions
-;
-KEY "CB_OH" IS "Block" OR "Call Block"
- OFFHOOK
- VOICEMODE
- WAITDIALTONE
- SENDDTMF "*60"
- SUBSCRIPT "offHook"
-ENDKEY
-
-KEY "CB" IS "Block" OR "Call Block"
- SENDDTMF "*60"
-ENDKEY
-
-;
-; Begin main subroutine
-;
-
-SUB "main" IS
- IFEVENT NEARANSWER THEN
- CLEAR
- SHOWDISPLAY "talkingto" AT 1
- GOTO "stableCall"
- ENDIF
- IFEVENT OFFHOOK THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1
- SHOWKEYS "CB"
- GOTO "offHook"
- ENDIF
- IFEVENT IDLE THEN
- CLEAR
- SHOWDISPLAY "titles" AT 1
- SHOWKEYS "CB_OH"
- ENDIF
- IFEVENT CALLERID THEN
- CLEAR
- SHOWDISPLAY "newcall" AT 1
- ENDIF
-ENDSUB
-
-SUB "offHook" IS
- IFEVENT FARRING THEN
- CLEAR
- SHOWDISPLAY "ringing" AT 1
- ENDIF
- IFEVENT FARANSWER THEN
- CLEAR
- SHOWDISPLAY "talkingto" AT 1
- GOTO "stableCall"
- ENDIF
-ENDSUB
-
-SUB "stableCall" IS
-
-ENDSUB
diff --git a/1.4/configs/udptl.conf.sample b/1.4/configs/udptl.conf.sample
deleted file mode 100644
index 05a38d54e..000000000
--- a/1.4/configs/udptl.conf.sample
+++ /dev/null
@@ -1,30 +0,0 @@
-;
-; UDPTL Configuration (UDPTL is one of the transports for T.38)
-;
-[general]
-;
-; UDPTL start and UDPTL end configure start and end addresses
-;
-udptlstart=4000
-udptlend=4999
-;
-; Whether to enable or disable UDP checksums on UDPTL traffic
-;
-;udptlchecksums=no
-;
-; The error correction type to be sent
-;
-T38FaxUdpEC = t38UDPFEC
-;T38FaxUdpEC = t38UDPRedundancy
-;
-; The maximum length of a UDPTL packet
-;
-T38FaxMaxDatagram = 400
-;
-; The number of error correction entries in a UDPTL packet
-;
-udptlfecentries = 3
-;
-; The span over which parity is calculated for FEC in a UDPTL packet
-;
-udptlfecspan = 3
diff --git a/1.4/configs/users.conf.sample b/1.4/configs/users.conf.sample
deleted file mode 100644
index 2a816d7e4..000000000
--- a/1.4/configs/users.conf.sample
+++ /dev/null
@@ -1,79 +0,0 @@
-;
-; User configuration
-;
-; Creating entries in users.conf is a "shorthand" for creating individual
-; entries in each configuration file. Using users.conf is not intended to
-; provide you with as much flexibility as using the separate configuration
-; files (e.g. sip.conf, iax.conf, etc) but is intended to accelerate the
-; simple task of adding users. Note that creating individual items (e.g.
-; custom SIP peers, IAX friends, etc.) will allow you to override specific
-; parameters within this file. Parameter names here are the same as they
-; appear in the other configuration files. There is no way to change the
-; value of a parameter here for just one subsystem.
-;
-
-[general]
-;
-; Full name of a user
-;
-fullname = New User
-;
-; Starting point of allocation of extensions
-;
-userbase = 6000
-;
-; Create voicemail mailbox and use use macro-stdexten
-;
-hasvoicemail = yes
-;
-; Set voicemail mailbox 6000 password to 1234
-;
-vmsecret = 1234
-;
-; Create SIP Peer
-;
-hassip = yes
-;
-; Create IAX friend
-;
-hasiax = yes
-;
-; Create H.323 friend
-;
-;hash323 = yes
-;
-; Create manager entry
-;
-hasmanager = no
-;
-; Set permissions for manager entry (see manager.conf.sample for documentation)
-; (defaults to *all* permissions)
-;managerread = system,call,log,verbose,command,agent,user,config
-;managerwrite = system,call,log,verbose,command,agent,user,config
-;
-; Remaining options are not specific to users.conf entries but are general.
-;
-callwaiting = yes
-threewaycalling = yes
-callwaitingcallerid = yes
-transfer = yes
-canpark = yes
-cancallforward = yes
-callreturn = yes
-callgroup = 1
-pickupgroup = 1
-
-
-;[6000]
-;fullname = Joe User
-;email = joe@foo.bar
-;secret = 1234
-;zapchan = 1
-;hasvoicemail = yes
-;vmsecret = 1234
-;hassip = yes
-;hasiax = no
-;hash323 = no
-;hasmanager = no
-;callwaiting = no
-;context = international
diff --git a/1.4/configs/voicemail.conf.sample b/1.4/configs/voicemail.conf.sample
deleted file mode 100644
index ec8798782..000000000
--- a/1.4/configs/voicemail.conf.sample
+++ /dev/null
@@ -1,248 +0,0 @@
-;
-; Voicemail Configuration
-;
-
-;
-; NOTE: Asterisk has to edit this file to change a user's password. This does
-; not currently work with the "#include <file>" directive for Asterisk
-; configuration files, nor when using realtime static configuration.
-; Do not use them with this configuration file.
-;
-
-[general]
-; Formats for writing Voicemail. Note that when using IMAP storage for
-; voicemail, only the first format specified will be used.
-;format=g723sf|wav49|wav
-format=wav49|gsm|wav
-;
-; WARNING:
-; If you change the list of formats that you record voicemail in
-; when you have mailboxes that contain messages, you _MUST_ absolutely
-; manually go through those mailboxes and convert/delete/add the
-; the message files so that they appear to have been stored using
-; your new format list. If you don't do this, very unpleasant
-; things may happen to your users while they are retrieving and
-; manipulating their voicemail.
-;
-; In other words: don't change the format list on a production system
-; unless you are _VERY_ sure that you know what you are doing and are
-; prepared for the consequences.
-;
-; Who the e-mail notification should appear to come from
-serveremail=asterisk
-;serveremail=asterisk@linux-support.net
-; Should the email contain the voicemail as an attachment
-attach=yes
-; Maximum number of messages per folder. If not specified, a default value
-; (100) is used. Maximum value for this option is 9999.
-;maxmsg=100
-; Maximum length of a voicemail message in seconds
-;maxmessage=180
-; Minimum length of a voicemail message in seconds for the message to be kept
-; The default is no minimum.
-;minmessage=3
-; Maximum length of greetings in seconds
-;maxgreet=60
-; How many milliseconds to skip forward/back when rew/ff in message playback
-skipms=3000
-; How many seconds of silence before we end the recording
-maxsilence=10
-; Silence threshold (what we consider silence: the lower, the more sensitive)
-silencethreshold=128
-; Max number of failed login attempts
-maxlogins=3
-;
-; User context is where entries from users.conf are registered. The
-; default value is 'default'
-;
-;userscontext=default
-;
-; If you need to have an external program, i.e. /usr/bin/myapp
-; called when a voicemail is left, delivered, or your voicemailbox
-; is checked, uncomment this. It can also be set to 'smdi' to use
-; smdi for external notification. If it is 'smdi', smdiport should
-; be set to a valid port as specified in smdi.conf.
-
-;externnotify=/usr/bin/myapp
-;smdiport=/dev/ttyS0
-
-; If you need to have an external program, i.e. /usr/bin/myapp
-; called when a voicemail password is changed, uncomment this:
-;externpass=/usr/bin/myapp
-; For the directory, you can override the intro file if you want
-;directoryintro=dir-intro
-; The character set for voicemail messages can be specified here
-;charset=ISO-8859-1
-; The ADSI feature descriptor number to download to
-;adsifdn=0000000F
-; The ADSI security lock code
-;adsisec=9BDBF7AC
-; The ADSI voicemail application version number.
-;adsiver=1
-; Skip the "[PBX]:" string from the message title
-;pbxskip=yes
-; Change the From: string
-;fromstring=The Asterisk PBX
-; Permit finding entries for forward/compose from the directory
-;usedirectory=yes
-; Voicemail can be stored in a database using the ODBC driver.
-; The value of odbcstorage is the database connection configured
-; in res_odbc.conf.
-;odbcstorage=asterisk
-; The default table for ODBC voicemail storage is voicemessages.
-;odbctable=voicemessages
-;
-; Change the from, body and/or subject, variables:
-; VM_NAME, VM_DUR, VM_MSGNUM, VM_MAILBOX, VM_CALLERID, VM_CIDNUM,
-; VM_CIDNAME, VM_DATE
-;
-; Note: The emailbody config row can only be up to 512 characters due to a
-; limitation in the Asterisk configuration subsystem.
-;emailsubject=[PBX]: New message ${VM_MSGNUM} in mailbox ${VM_MAILBOX}
-; The following definition is very close to the default, but the default shows
-; just the CIDNAME, if it is not null, otherwise just the CIDNUM, or "an unknown
-; caller", if they are both null.
-;emailbody=Dear ${VM_NAME}:\n\n\tjust wanted to let you know you were just left a ${VM_DUR} long message (number ${VM_MSGNUM})\nin mailbox ${VM_MAILBOX} from ${VM_CALLERID}, on ${VM_DATE}, so you might\nwant to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n
-;
-; You can also change the Pager From: string, the pager body and/or subject.
-; The above defined variables also can be used here
-;pagerfromstring=The Asterisk PBX
-;pagersubject=New VM
-;pagerbody=New ${VM_DUR} long msg in box ${VM_MAILBOX}\nfrom ${VM_CALLERID}, on ${VM_DATE}
-;
-; Set the date format on outgoing mails. Valid arguments can be found on the
-; strftime(3) man page
-;
-; Default
-emaildateformat=%A, %B %d, %Y at %r
-; 24h date format
-;emaildateformat=%A, %d %B %Y at %H:%M:%S
-;
-; You can override the default program to send e-mail if you wish, too
-;
-;mailcmd=/usr/sbin/sendmail -t
-;
-; Users may be located in different timezones, or may have different
-; message announcements for their introductory message when they enter
-; the voicemail system. Set the message and the timezone each user
-; hears here. Set the user into one of these zones with the tz= attribute
-; in the options field of the mailbox. Of course, language substitution
-; still applies here so you may have several directory trees that have
-; alternate language choices.
-;
-; Look in /usr/share/zoneinfo/ for names of timezones.
-; Look at the manual page for strftime for a quick tutorial on how the
-; variable substitution is done on the values below.
-;
-; Supported values:
-; 'filename' filename of a soundfile (single ticks around the filename
-; required)
-; ${VAR} variable substitution
-; A or a Day of week (Saturday, Sunday, ...)
-; B or b or h Month name (January, February, ...)
-; d or e numeric day of month (first, second, ..., thirty-first)
-; Y Year
-; I or l Hour, 12 hour clock
-; H Hour, 24 hour clock (single digit hours preceded by "oh")
-; k Hour, 24 hour clock (single digit hours NOT preceded by "oh")
-; M Minute, with 00 pronounced as "o'clock"
-; N Minute, with 00 pronounced as "hundred" (US military time)
-; P or p AM or PM
-; Q "today", "yesterday" or ABdY
-; (*note: not standard strftime value)
-; q "" (for today), "yesterday", weekday, or ABdY
-; (*note: not standard strftime value)
-; R 24 hour time, including minute
-;
-;
-;
-; Each mailbox is listed in the form <mailbox>=<password>,<name>,<email>,<pager_email>,<options>
-; if the e-mail is specified, a message will be sent when a message is
-; received, to the given mailbox. If pager is specified, a message will be
-; sent there as well. If the password is prefixed by '-', then it is
-; considered to be unchangeable.
-;
-; Advanced options example is extension 4069
-; NOTE: All options can be expressed globally in the general section, and
-; overridden in the per-mailbox settings, unless listed otherwise.
-;
-; tz=central ; Timezone from zonemessages below. Irrelevant if envelope=no.
-; attach=yes ; Attach the voicemail to the notification email *NOT* the pager email
-; attachfmt=wav49 ; Which format to attach to the email. Normally this is the
- ; first format specified in the format parameter above, but this
- ; option lets you customize the format sent to particular mailboxes.
- ; Useful if Windows users want wav49, but Linux users want gsm.
- ; [per-mailbox only]
-; saycid=yes ; Say the caller id information before the message. If not described,
- ; or set to no, it will be in the envelope
-; cidinternalcontexts=intern ; Internal Context for Name Playback instead of
- ; extension digits when saying caller id.
-; sayduration=no ; Turn on/off the duration information before the message. [ON by default]
-; saydurationm=2 ; Specify the minimum duration to say. Default is 2 minutes
-; dialout=fromvm ; Context to dial out from [option 4 from mailbox's advanced menu].
- ; If not specified, option 4 will not be listed and dialing out
- ; from within VoiceMailMain() will not be permitted.
-sendvoicemail=yes ; Allow the user to compose and send a voicemail while inside
- ; VoiceMailMain() [option 5 from mailbox's advanced menu].
- ; If set to 'no', option 5 will not be listed.
-; searchcontexts=yes ; Current default behavior is to search only the default context
- ; if one is not specified. The older behavior was to search all contexts.
- ; This option restores the old behavior [DEFAULT=no]
-; callback=fromvm ; Context to call back from
- ; if not listed, calling the sender back will not be permitted
-; review=yes ; Allow sender to review/rerecord their message before saving it [OFF by default
-; operator=yes ; Allow sender to hit 0 before/after/during leaving a voicemail to
- ; reach an operator [OFF by default]
-; envelope=no ; Turn on/off envelope playback before message playback. [ON by default]
- ; This does NOT affect option 3,3 from the advanced options menu
-; delete=yes ; After notification, the voicemail is deleted from the server. [per-mailbox only]
- ; This is intended for use with users who wish to receive their
- ; voicemail ONLY by email. Note: "deletevoicemail" is provided as an
- ; equivalent option for Realtime configuration.
-; volgain=0.0 ; Emails bearing the voicemail may arrive in a volume too
- ; quiet to be heard. This parameter allows you to specify how
- ; much gain to add to the message when sending a voicemail.
- ; NOTE: sox must be installed for this option to work.
-; nextaftercmd=yes ; Skips to the next message after hitting 7 or 9 to delete/save current message.
- ; [global option only at this time]
-; forcename=yes ; Forces a new user to record their name. A new user is
- ; determined by the password being the same as
- ; the mailbox number. The default is "no".
-; forcegreetings=no ; This is the same as forcename, except for recording
- ; greetings. The default is "no".
-; hidefromdir=yes ; Hide this mailbox from the directory produced by app_directory
- ; The default is "no".
-;tempgreetwarn=yes ; Remind the user that their temporary greeting is set
-
-[zonemessages]
-eastern=America/New_York|'vm-received' Q 'digits/at' IMp
-central=America/Chicago|'vm-received' Q 'digits/at' IMp
-central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'
-military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
-european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM
-
-
-
-[default]
-; Define maximum number of messages per folder for a particular context.
-;maxmsg=50
-
-1234 => 4242,Example Mailbox,root@localhost
-;4200 => 9855,Mark Spencer,markster@linux-support.net,mypager@digium.com,attach=no|serveremail=myaddy@digium.com|tz=central|maxmsg=10
-;4300 => 3456,Ben Rigas,ben@american-computer.net
-;4310 => -5432,Sales,sales@marko.net
-;4069 => 6522,Matt Brooks,matt@marko.net,,|tz=central|attach=yes|saycid=yes|dialout=fromvm|callback=fromvm|review=yes|operator=yes|envelope=yes|sayduration=yes|saydurationm=1
-;4073 => 1099,Bianca Paige,bianca@biancapaige.com,,delete=1
-;4110 => 3443,Rob Flynn,rflynn@blueridge.net
-;4235 => 1234,Jim Holmes,jim@astricon.ips,,Tz=european
-
-
-;
-; Mailboxes may be organized into multiple contexts for
-; voicemail virtualhosting
-;
-
-[other]
-;The intro can be customized on a per-context basis
-;directoryintro=dir-company2
-1234 => 5678,Company2 User,root@localhost
diff --git a/1.4/configs/vpb.conf.sample b/1.4/configs/vpb.conf.sample
deleted file mode 100644
index 4a9b0b36a..000000000
--- a/1.4/configs/vpb.conf.sample
+++ /dev/null
@@ -1,108 +0,0 @@
-;
-; V6PCI/V12PCI config file for VoiceTronix Hardware
-;
-; Options for [general] section
-;
-; type = v12pci|v6pci|v4pci
-; cards = number of cards
-; To use Asterisk indication tones
-; indication = 1
-; none,-24db,-18db only for use with OpenLine4
-; ecsuppthres = 0|2048|4096
-; Inter Digit Delay timeout for when collecting DTMF tones for dialling
-; from a Station port, in ms
-; dtmfidd = 3000
-; To use Asterisk DTMF detection
-; ast-dtmf-det=1
-; Used with ast-dtmf-det
-; relaxdtmf=1
-; When a native bridge occurs between 2 vpb channels, it will only break
-; the connection for '#' and '*'
-; break-for-dtmf=no
-; Set the maximum period between received rings, default 4000ms
-; timer_period_ring=4000
-;
-; Options for [interface] section
-; board = board_number (1, 2, 3, ...)
-; channel = channel_number (1,2,3...)
-; mode = fxo|immediate|dialtone -- for type of line and line handling
-; context = starting context
-; echocancel = on|off (on by default of v4pci, off by default for others)
-; callerid = on|off|v23|bell (on => to collect caller ID if available between 1st/2nd rings using vpb functions)
-; (v23|bell => collect caller ID using asterisk functions)
-; Or for use with FXS channels a '"name" <location>' format can be used to set the channels CID
-;
-; UseLoopDrop = 0|1 (enables the use of Loop Drop detection, on by default in
-; some cases spurious loop-drops can cause unexpected
-; hangup detection)
-;
-; Gain settings
-; txgain => Transmit Software Gain (-12 => 12)
-; rxgain => Receive Software Gain (-12 => 12)
-; txhwgain => Transmit hardware gain (-12 => 12)
-; rxhwgain => Receive Hardware gain (-12 => 12)
-;
-; These are advanced settings and only mentioned for completeness.
-; bal1 => Hybrid balance codec register 1
-; bal2 => Hybrid balance codec register 2
-; bal3 => Hybrid balance codec register 3
-;
-; Dial translations - if you want a pause or hook-flash in your dial string
-; you can use "w" for pause (wait) or "f" for "hook-flash", eg:
-; exten => _9XXX,1,Dial(vpb/g1/ww${EXTEN:${TRUNKMSD}})
-;
-;
-
-[general]
-type = v12pci
-;type = v6pci
-;type = v4pci
-cards = 1
-
-[interfaces]
-
-board = 0
-echocancel = on
-
-
-; For OpenLine4 cards
-;context = demo
-;mode = fxo
-;channel = 0
-;channel = 1
-;channel = 2
-;channel = 3
-
-; For OpenSwith12 with jumpers at factory default
-context = demo
-mode = fxo
-channel = 8
-channel = 9
-channel = 10
-channel = 11
-
-context = local
-mode = dialtone
-channel = 0
-channel = 1
-channel = 2
-channel = 3
-channel = 4
-channel = 5
-channel = 6
-channel = 7
-;
-; For OpenSwitch6
-; Note that V6PCI channel numbers start at 7!
-;context = demo
-;mode = fxo
-;channel = 6
-;channel = 7
-
-;mode = dialtone
-;channel = 8
-;channel = 9
-;channel = 10
-;channel = 11
-
-
diff --git a/1.4/configs/zapata.conf.sample b/1.4/configs/zapata.conf.sample
deleted file mode 100644
index bcc98fcf8..000000000
--- a/1.4/configs/zapata.conf.sample
+++ /dev/null
@@ -1,671 +0,0 @@
-;
-; Zapata telephony interface
-;
-; Configuration file
-;
-; You need to restart Asterisk to re-configure the Zap channel
-; CLI> reload chan_zap.so
-; will reload the configuration file,
-; but not all configuration options are
-; re-configured during a reload.
-
-
-
-[trunkgroups]
-;
-; Trunk groups are used for NFAS or GR-303 connections.
-;
-; Group: Defines a trunk group.
-; trunkgroup => <trunkgroup>,<dchannel>[,<backup1>...]
-;
-; trunkgroup is the numerical trunk group to create
-; dchannel is the zap channel which will have the
-; d-channel for the trunk.
-; backup1 is an optional list of backup d-channels.
-;
-;trunkgroup => 1,24,48
-;trunkgroup => 1,24
-;
-; Spanmap: Associates a span with a trunk group
-; spanmap => <zapspan>,<trunkgroup>[,<logicalspan>]
-;
-; zapspan is the zap span number to associate
-; trunkgroup is the trunkgroup (specified above) for the mapping
-; logicalspan is the logical span number within the trunk group to use.
-; if unspecified, no logical span number is used.
-;
-;spanmap => 1,1,1
-;spanmap => 2,1,2
-;spanmap => 3,1,3
-;spanmap => 4,1,4
-
-[channels]
-;
-; Default language
-;
-;language=en
-;
-; Default context
-;
-context=default
-;
-; Switchtype: Only used for PRI.
-;
-; national: National ISDN 2 (default)
-; dms100: Nortel DMS100
-; 4ess: AT&T 4ESS
-; 5ess: Lucent 5ESS
-; euroisdn: EuroISDN
-; ni1: Old National ISDN 1
-; qsig: Q.SIG
-;
-switchtype=national
-;
-; Some switches (AT&T especially) require network specific facility IE
-; supported values are currently 'none', 'sdn', 'megacom', 'tollfreemegacom', 'accunet'
-;
-;nsf=none
-;
-; PRI Dialplan: Only RARELY used for PRI.
-;
-; unknown: Unknown
-; private: Private ISDN
-; local: Local ISDN
-; national: National ISDN
-; international: International ISDN
-; dynamic: Dynamically selects the appropriate dialplan
-;
-;pridialplan=national
-;
-; PRI Local Dialplan: Only RARELY used for PRI (sets the calling number's numbering plan)
-;
-; unknown: Unknown
-; private: Private ISDN
-; local: Local ISDN
-; national: National ISDN
-; international: International ISDN
-; dynamic: Dynamically selects the appropriate dialplan
-;
-;prilocaldialplan=national
-;
-; PRI callerid prefixes based on the given TON/NPI (dialplan)
-; This is especially needed for euroisdn E1-PRIs
-;
-; sample 1 for Germany
-;internationalprefix = 00
-;nationalprefix = 0
-;localprefix = 0711
-;privateprefix = 07115678
-;unknownprefix =
-;
-; sample 2 for Germany
-;internationalprefix = +
-;nationalprefix = +49
-;localprefix = +49711
-;privateprefix = +497115678
-;unknownprefix =
-;
-; PRI resetinterval: sets the time in seconds between restart of unused
-; channels, defaults to 3600; minimum 60 seconds. Some PBXs don't like
-; channel restarts. so set the interval to a very long interval e.g. 100000000
-; or 'never' to disable *entirely*.
-;
-;resetinterval = 3600
-;
-; Overlap dialing mode (sending overlap digits)
-;
-;overlapdial=yes
-;
-; PRI Out of band indications.
-; Enable this to report Busy and Congestion on a PRI using out-of-band
-; notification. Inband indication, as used by Asterisk doesn't seem to work
-; with all telcos.
-;
-; outofband: Signal Busy/Congestion out of band with RELEASE/DISCONNECT
-; inband: Signal Busy/Congestion using in-band tones
-;
-; priindication = outofband
-;
-; If you need to override the existing channels selection routine and force all
-; PRI channels to be marked as exclusively selected, set this to yes.
-; priexclusive = yes
-;
-; ISDN Timers
-; All of the ISDN timers and counters that are used are configurable. Specify
-; the timer name, and its value (in ms for timers).
-; K: Layer 2 max number of outstanding unacknowledged I frames (default 7)
-; N200: Layer 2 max number of retransmissions of a frame (default 3)
-; T200: Layer 2 max time before retransmission of a frame (default 1000 ms)
-; T203: Layer 2 max time without frames being exchanged (default 10000 ms)
-; T305: Wait for DISCONNECT acknowledge (default 30000 ms)
-; T308: Wait for RELEASE acknowledge (default 4000 ms)
-; T309: Maintain active calls on Layer 2 disconnection (default -1, Asterisk clears calls)
-; EuroISDN: 6000 to 12000 ms, according to (N200 + 1) x T200 + 2s
-; May vary in other ISDN standards (Q.931 1993 : 90000 ms)
-; T313: Wait for CONNECT acknowledge, CPE side only (default 3000 ms)
-;
-; pritimer => t200,1000
-; pritimer => t313,4000
-;
-; To enable transmission of facility-based ISDN supplementary services (such
-; as caller name from CPE over facility), enable this option.
-; facilityenable = yes
-;
-;
-; Signalling method (default is fxs). Valid values:
-; em: E & M
-; em_w: E & M Wink
-; featd: Feature Group D (The fake, Adtran style, DTMF)
-; featdmf: Feature Group D (The real thing, MF (domestic, US))
-; featdmf_ta: Feature Group D (The real thing, MF (domestic, US)) through
-; a Tandem Access point
-; featb: Feature Group B (MF (domestic, US))
-; fgccama Feature Group C-CAMA (DP DNIS, MF ANI)
-; fgccamamf Feature Group C-CAMA MF (MF DNIS, MF ANI)
-; fxs_ls: FXS (Loop Start)
-; fxs_gs: FXS (Ground Start)
-; fxs_ks: FXS (Kewl Start)
-; fxo_ls: FXO (Loop Start)
-; fxo_gs: FXO (Ground Start)
-; fxo_ks: FXO (Kewl Start)
-; pri_cpe: PRI signalling, CPE side
-; pri_net: PRI signalling, Network side
-; gr303fxoks_net: GR-303 Signalling, FXO Loopstart, Network side
-; gr303fxsks_cpe: GR-303 Signalling, FXS Loopstart, CPE side
-; sf: SF (Inband Tone) Signalling
-; sf_w: SF Wink
-; sf_featd: SF Feature Group D (The fake, Adtran style, DTMF)
-; sf_featdmf: SF Feature Group D (The real thing, MF (domestic, US))
-; sf_featb: SF Feature Group B (MF (domestic, US))
-; e911: E911 (MF) style signalling
-;
-; The following are used for Radio interfaces:
-; fxs_rx: Receive audio/COR on an FXS kewlstart interface (FXO at the
-; channel bank)
-; fxs_tx: Transmit audio/PTT on an FXS loopstart interface (FXO at the
-; channel bank)
-; fxo_rx: Receive audio/COR on an FXO loopstart interface (FXS at the
-; channel bank)
-; fxo_tx: Transmit audio/PTT on an FXO groundstart interface (FXS at
-; the channel bank)
-; em_rx: Receive audio/COR on an E&M interface (1-way)
-; em_tx: Transmit audio/PTT on an E&M interface (1-way)
-; em_txrx: Receive audio/COR AND Transmit audio/PTT on an E&M interface
-; (2-way)
-; em_rxtx: Same as em_txrx (for our dyslexic friends)
-; sf_rx: Receive audio/COR on an SF interface (1-way)
-; sf_tx: Transmit audio/PTT on an SF interface (1-way)
-; sf_txrx: Receive audio/COR AND Transmit audio/PTT on an SF interface
-; (2-way)
-; sf_rxtx: Same as sf_txrx (for our dyslexic friends)
-;
-signalling=fxo_ls
-;
-; If you have an outbound signalling format that is different from format
-; specified above (but compatible), you can specify outbound signalling format,
-; (see below). The 'signalling' format specified will be the inbound signalling
-; format. If you only specify 'signalling', then it will be the format for
-; both inbound and outbound.
-;
-; signalling=featdmf
-; outsignalling=featb
-;
-; For Feature Group D Tandem access, to set the default CIC and OZZ use these
-; parameters:
-;defaultozz=0000
-;defaultcic=303
-;
-; A variety of timing parameters can be specified as well
-; Including:
-; prewink: Pre-wink time (default 50ms)
-; preflash: Pre-flash time (default 50ms)
-; wink: Wink time (default 150ms)
-; flash: Flash time (default 750ms)
-; start: Start time (default 1500ms)
-; rxwink: Receiver wink time (default 300ms)
-; rxflash: Receiver flashtime (default 1250ms)
-; debounce: Debounce timing (default 600ms)
-;
-rxwink=300 ; Atlas seems to use long (250ms) winks
-;
-; How long generated tones (DTMF and MF) will be played on the channel
-; (in milliseconds)
-;toneduration=100
-;
-; Whether or not to do distinctive ring detection on FXO lines
-;
-;usedistinctiveringdetection=yes
-;distinctiveringaftercid=yes ; enable dring detection after callerid for those countries like Australia
- ; where the ring cadence is changed *after* the callerid spill.
-;
-; Whether or not to use caller ID
-;
-usecallerid=yes
-;
-; Type of caller ID signalling in use
-; bell = bell202 as used in US
-; v23 = v23 as used in the UK
-; v23_jp = v23 as used in Japan
-; dtmf = DTMF as used in Denmark, Sweden and Netherlands
-; smdi = Use SMDI for callerid. Requires SMDI to be enabled (usesmdi).
-;
-;cidsignalling=bell
-;
-; What signals the start of caller ID
-; ring = a ring signals the start
-; polarity = polarity reversal signals the start
-;
-;cidstart=ring
-;
-; Whether or not to hide outgoing caller ID (Override with *67 or *82)
-;
-hidecallerid=no
-;
-; Whether or not to enable call waiting on internal extensions
-; With this set to 'yes', busy extensions will hear the call-waiting
-; tone, and can use hook-flash to switch between callers. The Dial()
-; app will not return the "BUSY" result for extensions.
-;
-callwaiting=yes
-;
-; Whether or not restrict outgoing caller ID (will be sent as ANI only, not
-; available for the user)
-; Mostly use with FXS ports
-;
-;restrictcid=no
-;
-; Whether or not use the caller ID presentation for the outgoing call that the
-; calling switch is sending.
-; See doc/callingpres.txt
-;
-usecallingpres=yes
-;
-; Some countries (UK) have ring tones with different ring tones (ring-ring),
-; which means the callerid needs to be set later on, and not just after
-; the first ring, as per the default.
-;
-;sendcalleridafter=1
-;
-;
-; Support Caller*ID on Call Waiting
-;
-callwaitingcallerid=yes
-;
-; Support three-way calling
-;
-threewaycalling=yes
-;
-; For FXS ports (either direct analog or over T1/E1):
-; Support flash-hook call transfer (requires three way calling)
-; Also enables call parking (overrides the 'canpark' parameter)
-;
-; For digital ports using ISDN PRI protocols:
-; Support switch-side transfer (called 2BCT, RLT or other names)
-; This setting must be enabled on both ports involved, and the
-; 'facilityenable' setting must also be enabled to allow sending
-; the transfer to the ISDN switch, since it sent in a FACILITY
-; message.
-;
-transfer=yes
-;
-; Allow call parking
-; ('canpark=no' is overridden by 'transfer=yes')
-;
-canpark=yes
-;
-; Support call forward variable
-;
-cancallforward=yes
-;
-; Whether or not to support Call Return (*69)
-;
-callreturn=yes
-;
-; Stutter dialtone support: If a mailbox is specified without a voicemail
-; context, then when voicemail is received in a mailbox in the default
-; voicemail context in voicemail.conf, taking the phone off hook will cause a
-; stutter dialtone instead of a normal one.
-;
-; If a mailbox is specified *with* a voicemail context, the same will result
-; if voicemail received in mailbox in the specified voicemail context.
-;
-; for default voicemail context, the example below is fine:
-;
-;mailbox=1234
-;
-; for any other voicemail context, the following will produce the stutter tone:
-;
-;mailbox=1234@context
-;
-; Enable echo cancellation
-; Use either "yes", "no", or a power of two from 32 to 256 if you wish to
-; actually set the number of taps of cancellation.
-;
-; Note that when setting the number of taps, the number 256 does not translate
-; to 256 ms of echo cancellation. echocancel=256 means 256 / 8 = 32 ms.
-;
-; Note that if any of your Zaptel cards have hardware echo cancellers,
-; then this setting only turns them on and off; numeric settings will
-; be treated as "yes". There are no special settings required for
-; hardware echo cancellers; when present and enabled in their kernel
-; modules, they take precedence over the software echo canceller compiled
-; into Zaptel automatically.
-;
-echocancel=yes
-;
-; Generally, it is not necessary (and in fact undesirable) to echo cancel when
-; the circuit path is entirely TDM. You may, however, change this behavior
-; by enabling the echo cancel during pure TDM bridging below.
-;
-echocancelwhenbridged=yes
-;
-; In some cases, the echo canceller doesn't train quickly enough and there
-; is echo at the beginning of the call. Enabling echo training will cause
-; asterisk to briefly mute the channel, send an impulse, and use the impulse
-; response to pre-train the echo canceller so it can start out with a much
-; closer idea of the actual echo. Value may be "yes", "no", or a number of
-; milliseconds to delay before training (default = 400)
-;
-; WARNING: In some cases this option can make echo worse! If you are
-; trying to debug an echo problem, it is worth checking to see if your echo
-; is better with the option set to yes or no. Use whatever setting gives
-; the best results.
-;
-; Note that these parameters do not apply to hardware echo cancellers.
-;
-;echotraining=yes
-;echotraining=800
-;
-; If you are having trouble with DTMF detection, you can relax the DTMF
-; detection parameters. Relaxing them may make the DTMF detector more likely
-; to have "talkoff" where DTMF is detected when it shouldn't be.
-;
-;relaxdtmf=yes
-;
-; You may also set the default receive and transmit gains (in dB)
-;
-rxgain=0.0
-txgain=0.0
-;
-; Logical groups can be assigned to allow outgoing rollover. Groups range
-; from 0 to 63, and multiple groups can be specified.
-;
-group=1
-;
-; Ring groups (a.k.a. call groups) and pickup groups. If a phone is ringing
-; and it is a member of a group which is one of your pickup groups, then
-; you can answer it by picking up and dialling *8#. For simple offices, just
-; make these both the same. Groups range from 0 to 63.
-;
-callgroup=1
-pickupgroup=1
-
-;
-; Specify whether the channel should be answered immediately or if the simple
-; switch should provide dialtone, read digits, etc.
-; Note: If immediate=yes the dialplan execution will always start at extension
-; 's' priority 1 regardless of the dialed number!
-;
-immediate=no
-;
-; Specify whether flash-hook transfers to 'busy' channels should complete or
-; return to the caller performing the transfer (default is yes).
-;
-;transfertobusy=no
-;
-; CallerID can be set to "asreceived" or a specific number if you want to
-; override it. Note that "asreceived" only applies to trunk interfaces.
-;
-;callerid=2564286000
-;
-; AMA flags affects the recording of Call Detail Records. If specified
-; it may be 'default', 'omit', 'billing', or 'documentation'.
-;
-;amaflags=default
-;
-; Channels may be associated with an account code to ease
-; billing
-;
-;accountcode=lss0101
-;
-; ADSI (Analog Display Services Interface) can be enabled on a per-channel
-; basis if you have (or may have) ADSI compatible CPE equipment
-;
-;adsi=yes
-;
-; SMDI (Simplified Message Desk Interface) can be enabled on a per-channel
-; basis if you would like that channel to behave like an SMDI message desk.
-; The SMDI port specified should have already been defined in smdi.conf. The
-; default port is /dev/ttyS0.
-;
-;usesmdi=yes
-;smdiport=/dev/ttyS0
-;
-; On trunk interfaces (FXS) and E&M interfaces (E&M, Wink, Feature Group D
-; etc, it can be useful to perform busy detection either in an effort to
-; detect hangup or for detecting busies. This enables listening for
-; the beep-beep busy pattern.
-;
-;busydetect=yes
-;
-; If busydetect is enabled, it is also possible to specify how many busy tones
-; to wait for before hanging up. The default is 4, but better results can be
-; achieved if set to 6 or even 8. Mind that the higher the number, the more
-; time that will be needed to hangup a channel, but lowers the probability
-; that you will get random hangups.
-;
-;busycount=4
-;
-; If busydetect is enabled, it is also possible to specify the cadence of your
-; busy signal. In many countries, it is 500msec on, 500msec off. Without
-; busypattern specified, we'll accept any regular sound-silence pattern that
-; repeats <busycount> times as a busy signal. If you specify busypattern,
-; then we'll further check the length of the sound (tone) and silence, which
-; will further reduce the chance of a false positive.
-;
-;busypattern=500,500
-;
-; NOTE: In the Asterisk Makefile you'll find further options to tweak the busy
-; detector. If your country has a busy tone with the same length tone and
-; silence (as many countries do), consider defining the
-; -DBUSYDETECT_COMPARE_TONE_AND_SILENCE option.
-;
-; Use a polarity reversal to mark when a outgoing call is answered by the
-; remote party.
-;
-;answeronpolarityswitch=yes
-;
-; In some countries, a polarity reversal is used to signal the disconnect of a
-; phone line. If the hanguponpolarityswitch option is selected, the call will
-; be considered "hung up" on a polarity reversal.
-;
-;hanguponpolarityswitch=yes
-;
-; On trunk interfaces (FXS) it can be useful to attempt to follow the progress
-; of a call through RINGING, BUSY, and ANSWERING. If turned on, call
-; progress attempts to determine answer, busy, and ringing on phone lines.
-; This feature is HIGHLY EXPERIMENTAL and can easily detect false answers,
-; so don't count on it being very accurate.
-;
-; Few zones are supported at the time of this writing, but may be selected
-; with "progzone"
-;
-; This feature can also easily detect false hangups. The symptoms of this is
-; being disconnected in the middle of a call for no reason.
-;
-;callprogress=yes
-;progzone=us
-;
-; FXO (FXS signalled) devices must have a timeout to determine if there was a
-; hangup before the line was answered. This value can be tweaked to shorten
-; how long it takes before Zap considers a non-ringing line to have hungup.
-;
-;ringtimeout=8000
-;
-; For FXO (FXS signalled) devices, whether to use pulse dial instead of DTMF
-;
-;pulsedial=yes
-;
-; For fax detection, uncomment one of the following lines. The default is *OFF*
-;
-;faxdetect=both
-;faxdetect=incoming
-;faxdetect=outgoing
-;faxdetect=no
-;
-; This option specifies a preference for which music on hold class this channel
-; should listen to when put on hold if the music class has not been set on the
-; channel with Set(CHANNEL(musicclass)=whatever) in the dialplan, and the peer
-; channel putting this one on hold did not suggest a music class.
-;
-; If this option is set to "passthrough", then the hold message will always be
-; passed through as signalling instead of generating hold music locally. This
-; setting is only valid when used on a channel that uses digital signalling.
-;
-; This option may be specified globally, or on a per-user or per-peer basis.
-;
-;mohinterpret=default
-;
-; This option specifies which music on hold class to suggest to the peer channel
-; when this channel places the peer on hold. It may be specified globally or on
-; a per-user or per-peer basis.
-;
-;mohsuggest=default
-;
-; PRI channels can have an idle extension and a minunused number. So long as
-; at least "minunused" channels are idle, chan_zap will try to call "idledial"
-; on them, and then dump them into the PBX in the "idleext" extension (which
-; is of the form exten@context). When channels are needed the "idle" calls
-; are disconnected (so long as there are at least "minidle" calls still
-; running, of course) to make more channels available. The primary use of
-; this is to create a dynamic service, where idle channels are bundled through
-; multilink PPP, thus more efficiently utilizing combined voice/data services
-; than conventional fixed mappings/muxings.
-;
-;idledial=6999
-;idleext=6999@dialout
-;minunused=2
-;minidle=1
-;
-; Configure jitter buffers in zapata (each one is 20ms, default is 4)
-;
-;jitterbuffers=4
-;
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
-; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
- ; ZAP channel. Defaults to "no". An enabled jitterbuffer will
- ; be used only if the sending side can create and the receiving
- ; side can not accept jitter. The ZAP channel can't accept jitter,
- ; thus an enabled jitterbuffer on the receive ZAP side will always
- ; be used if the sending side can create jitter.
-
-; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
-
-; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
- ; resynchronized. Useful to improve the quality of the voice, with
- ; big jumps in/broken timestamps, usually sent from exotic devices
- ; and programs. Defaults to 1000.
-
-; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of a ZAP
- ; channel. Two implementations are currently available - "fixed"
- ; (with size always equals to jbmax-size) and "adaptive" (with
- ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
-; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
-;
-; You can define your own custom ring cadences here. You can define up to 8
-; pairs. If the silence is negative, it indicates where the callerid spill is
-; to be placed. Also, if you define any custom cadences, the default cadences
-; will be turned off.
-;
-; Syntax is: cadence=ring,silence[,ring,silence[...]]
-;
-; These are the default cadences:
-;
-;cadence=125,125,2000,-4000
-;cadence=250,250,500,1000,250,250,500,-4000
-;cadence=125,125,125,125,125,-4000
-;cadence=1000,500,2500,-5000
-;
-; Each channel consists of the channel number or range. It inherits the
-; parameters that were specified above its declaration.
-;
-; For GR-303, CRV's are created like channels except they must start with the
-; trunk group followed by a colon, e.g.:
-;
-; crv => 1:1
-; crv => 2:1-2,5-8
-;
-;
-;callerid="Green Phone"<(256) 428-6121>
-;channel => 1
-;callerid="Black Phone"<(256) 428-6122>
-;channel => 2
-;callerid="CallerID Phone" <(256) 428-6123>
-;callerid="CallerID Phone" <(630) 372-1564>
-;callerid="CallerID Phone" <(256) 704-4666>
-;channel => 3
-;callerid="Pac Tel Phone" <(256) 428-6124>
-;channel => 4
-;callerid="Uniden Dead" <(256) 428-6125>
-;channel => 5
-;callerid="Cortelco 2500" <(256) 428-6126>
-;channel => 6
-;callerid="Main TA 750" <(256) 428-6127>
-;channel => 44
-;
-; For example, maybe we have some other channels which start out in a
-; different context and use E & M signalling instead.
-;
-;context=remote
-;sigalling=em
-;channel => 15
-;channel => 16
-
-;signalling=em_w
-;
-; All those in group 0 I'll use for outgoing calls
-;
-; Strip most significant digit (9) before sending
-;
-;stripmsd=1
-;callerid=asreceived
-;group=0
-;signalling=fxs_ls
-;channel => 45
-
-;signalling=fxo_ls
-;group=1
-;callerid="Joe Schmoe" <(256) 428-6131>
-;channel => 25
-;callerid="Megan May" <(256) 428-6132>
-;channel => 26
-;callerid="Suzy Queue" <(256) 428-6233>
-;channel => 27
-;callerid="Larry Moe" <(256) 428-6234>
-;channel => 28
-;
-; Sample PRI (CPE) config: Specify the switchtype, the signalling as either
-; pri_cpe or pri_net for CPE or Network termination, and generally you will
-; want to create a single "group" for all channels of the PRI.
-;
-; switchtype = national
-; signalling = pri_cpe
-; group = 2
-; channel => 1-23
-
-;
-
-; Used for distinctive ring support for x100p.
-; You can see the dringX patterns is to set any one of the dringXcontext fields
-; and they will be printed on the console when an inbound call comes in.
-;
-;dring1=95,0,0
-;dring1context=internal1
-;dring2=325,95,0
-;dring2context=internal2
-; If no pattern is matched here is where we go.
-;context=default
-;channel => 1
-
diff --git a/1.4/configure b/1.4/configure
deleted file mode 100755
index 808acb706..000000000
--- a/1.4/configure
+++ /dev/null
@@ -1,36856 +0,0 @@
-#! /bin/sh
-# From configure.ac Revision: 115327 .
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for asterisk 1.4.
-#
-# Report bugs to <www.asterisk.org>.
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-#
-# "Asterisk"
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
- if (eval ":") 2>/dev/null; then
- as_have_required=yes
-else
- as_have_required=no
-fi
-
- if test $as_have_required = yes && (eval ":
-(as_func_return () {
- (exit \$1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0) || { (exit 1); exit 1; }
-
-(
- as_lineno_1=\$LINENO
- as_lineno_2=\$LINENO
- test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
- test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
- :
-else
- as_candidate_shells=
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- case $as_dir in
- /*)
- for as_base in sh bash ksh sh5; do
- as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
- done;;
- esac
-done
-IFS=$as_save_IFS
-
-
- for as_shell in $as_candidate_shells $SHELL; do
- # Try only shells that exist, to save several forks.
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { ("$as_shell") 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-:
-_ASEOF
-}; then
- CONFIG_SHELL=$as_shell
- as_have_required=yes
- if { "$as_shell" 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-:
-(as_func_return () {
- (exit $1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
- break
-fi
-
-fi
-
- done
-
- if test "x$CONFIG_SHELL" != x; then
- for as_var in BASH_ENV ENV
- do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- done
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
- if test $as_have_required = no; then
- echo This script requires a shell more modern than all the
- echo shells that I found on your system. Please install a
- echo modern shell, or manually run the script under such a
- echo shell if you do have one.
- { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
- (exit \$1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
- echo No shell found that supports shell functions.
- echo Please tell autoconf@gnu.org about your system,
- echo including any error possibly output before this
- echo message
-}
-
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line after each line using $LINENO; the second 'sed'
- # does the real work. The second script uses 'N' to pair each
- # line-number line with the line containing $LINENO, and appends
- # trailing '-' during substitution so that $LINENO is not a special
- # case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # scripts with optimization help from Paolo Bonzini. Blame Lee
- # E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) ECHO_C='\c';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Identity of this package.
-PACKAGE_NAME='asterisk'
-PACKAGE_TARNAME='asterisk'
-PACKAGE_VERSION='1.4'
-PACKAGE_STRING='asterisk 1.4'
-PACKAGE_BUGREPORT='www.asterisk.org'
-
-ac_unique_file="main/asterisk.c"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_header_list=
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-build
-build_cpu
-build_vendor
-build_os
-host
-host_cpu
-host_vendor
-host_os
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-CPP
-GREP
-EGREP
-BUILD_PLATFORM
-BUILD_CPU
-BUILD_VENDOR
-BUILD_OS
-HOST_PLATFORM
-HOST_CPU
-HOST_VENDOR
-HOST_OS
-OSARCH
-UNAME
-PBX_OSREV
-CXX
-LD
-RANLIB
-CXXFLAGS
-ac_ct_CXX
-CXXCPP
-SED
-AWK
-INSTALL_PROGRAM
-INSTALL_SCRIPT
-INSTALL_DATA
-LN_S
-GNU_MAKE
-STRIP
-AR
-GNU_LD
-FIND
-COMPRESS
-BASENAME
-ID
-DIRNAME
-LN
-DOT
-WGET
-FETCH
-DOWNLOAD
-SOXMIX
-acx_pthread_config
-PTHREAD_CC
-PTHREAD_LIBS
-PTHREAD_CFLAGS
-AST_DEVMODE
-ALSA_LIB
-ALSA_INCLUDE
-ALSA_DIR
-PBX_ALSA
-CURL_LIB
-CURL_INCLUDE
-CURL_DIR
-PBX_CURL
-CAP_LIB
-CAP_INCLUDE
-CAP_DIR
-PBX_CAP
-CURSES_LIB
-CURSES_INCLUDE
-CURSES_DIR
-PBX_CURSES
-GNUTLS_LIB
-GNUTLS_INCLUDE
-GNUTLS_DIR
-PBX_GNUTLS
-GSM_LIB
-GSM_INCLUDE
-GSM_DIR
-PBX_GSM
-IKSEMEL_LIB
-IKSEMEL_INCLUDE
-IKSEMEL_DIR
-PBX_IKSEMEL
-IMAP_TK_LIB
-IMAP_TK_INCLUDE
-IMAP_TK_DIR
-PBX_IMAP_TK
-ISDNNET_LIB
-ISDNNET_INCLUDE
-ISDNNET_DIR
-PBX_ISDNNET
-KDE_LIB
-KDE_INCLUDE
-KDE_DIR
-PBX_KDE
-LTDL_LIB
-LTDL_INCLUDE
-LTDL_DIR
-PBX_LTDL
-MISDN_LIB
-MISDN_INCLUDE
-MISDN_DIR
-PBX_MISDN
-NBS_LIB
-NBS_INCLUDE
-NBS_DIR
-PBX_NBS
-NCURSES_LIB
-NCURSES_INCLUDE
-NCURSES_DIR
-PBX_NCURSES
-NETSNMP_LIB
-NETSNMP_INCLUDE
-NETSNMP_DIR
-PBX_NETSNMP
-NEWT_LIB
-NEWT_INCLUDE
-NEWT_DIR
-PBX_NEWT
-UNIXODBC_LIB
-UNIXODBC_INCLUDE
-UNIXODBC_DIR
-PBX_UNIXODBC
-OGG_LIB
-OGG_INCLUDE
-OGG_DIR
-PBX_OGG
-OSPTK_LIB
-OSPTK_INCLUDE
-OSPTK_DIR
-PBX_OSPTK
-OSS_LIB
-OSS_INCLUDE
-OSS_DIR
-PBX_OSS
-POPT_LIB
-POPT_INCLUDE
-POPT_DIR
-PBX_POPT
-PGSQL_LIB
-PGSQL_INCLUDE
-PGSQL_DIR
-PBX_PGSQL
-PRI_LIB
-PRI_INCLUDE
-PRI_DIR
-PBX_PRI
-PWLIB_LIB
-PWLIB_INCLUDE
-PWLIB_DIR
-PBX_PWLIB
-OPENH323_LIB
-OPENH323_INCLUDE
-OPENH323_DIR
-PBX_OPENH323
-RADIUS_LIB
-RADIUS_INCLUDE
-RADIUS_DIR
-PBX_RADIUS
-SPEEX_LIB
-SPEEX_INCLUDE
-SPEEX_DIR
-PBX_SPEEX
-SPEEXDSP_LIB
-SPEEXDSP_INCLUDE
-SPEEXDSP_DIR
-PBX_SPEEXDSP
-SQLITE_LIB
-SQLITE_INCLUDE
-SQLITE_DIR
-PBX_SQLITE
-SUPPSERV_LIB
-SUPPSERV_INCLUDE
-SUPPSERV_DIR
-PBX_SUPPSERV
-OPENSSL_LIB
-OPENSSL_INCLUDE
-OPENSSL_DIR
-PBX_OPENSSL
-FREETDS_LIB
-FREETDS_INCLUDE
-FREETDS_DIR
-PBX_FREETDS
-TERMCAP_LIB
-TERMCAP_INCLUDE
-TERMCAP_DIR
-PBX_TERMCAP
-TINFO_LIB
-TINFO_INCLUDE
-TINFO_DIR
-PBX_TINFO
-TONEZONE_LIB
-TONEZONE_INCLUDE
-TONEZONE_DIR
-PBX_TONEZONE
-USB_LIB
-USB_INCLUDE
-USB_DIR
-PBX_USB
-VORBIS_LIB
-VORBIS_INCLUDE
-VORBIS_DIR
-PBX_VORBIS
-VPB_LIB
-VPB_INCLUDE
-VPB_DIR
-PBX_VPB
-ZLIB_LIB
-ZLIB_INCLUDE
-ZLIB_DIR
-PBX_ZLIB
-ZAPTEL_LIB
-ZAPTEL_INCLUDE
-ZAPTEL_DIR
-PBX_ZAPTEL
-ALLOCA
-LIBOBJS
-POW_LIB
-GC_CFLAGS
-GC_LDFLAGS
-AST_DECLARATION_AFTER_STATEMENT
-AST_NO_STRICT_OVERFLOW
-GSM_INTERNAL
-KDEINIT
-KDEDIR
-NETSNMP_CONFIG
-PG_CONFIG
-PTLIB_CONFIG
-PWLIBDIR
-PWLIB_INCDIR
-PWLIB_LIBDIR
-PWLIB_PLATFORM
-OPENH323DIR
-OPENH323_INCDIR
-OPENH323_LIBDIR
-OPENH323_SUFFIX
-OPENH323_BUILD
-PBX_SPEEX_PREPROCESS
-PBX_ZAPTEL_VLDTMF
-PBX_ZAPTEL_TRANSCODE
-EDITLINE_LIB
-PBX_H323
-PBX_IXJUSER
-GTKCONFIG
-PBX_GTK
-GTK_INCLUDE
-GTK_LIB
-PKGCONFIG
-PBX_GTK2
-GTK2_INCLUDE
-GTK2_LIB
-CURL_CONFIG
-LTLIBOBJS'
-ac_subst_files=''
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CPP
-CXX
-CXXFLAGS
-CCC
-CXXCPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
- eval enable_$ac_feature=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
- eval enable_$ac_feature=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
- eval with_$ac_package=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
- eval with_$ac_package=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; }
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
- { (exit 1); exit 1; }; }
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $ac_option" >&2
- { (exit 1); exit 1; }; }
-fi
-
-# Be sure to have absolute directory names.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; }
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- { echo "$as_me: error: Working directory cannot be determined" >&2
- { (exit 1); exit 1; }; }
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- { echo "$as_me: error: pwd does not report name of working directory" >&2
- { (exit 1); exit 1; }; }
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$0" ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$0" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
- { (exit 1); exit 1; }; }
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
- { (exit 1); exit 1; }; }
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures asterisk 1.4 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/asterisk]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-System types:
- --build=BUILD configure for building on BUILD [guessed]
- --host=HOST cross-compile to build programs to run on HOST [BUILD]
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
- case $ac_init_help in
- short | recursive ) echo "Configuration of asterisk 1.4:";;
- esac
- cat <<\_ACEOF
-
-Optional Features:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-dev-mode Turn on developer mode
- --disable-largefile omit support for large files
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-gnu-ld assume the C compiler uses GNU ld [default=no]
- --with-asound=PATH use Advanced Linux Sound Architecture files in PATH
- --with-curl=PATH use cURL files in PATH
- --with-cap=PATH use POSIX 1.e capabilities files in PATH
- --with-curses=PATH use curses files in PATH
- --with-gnutls=PATH use GNU TLS support (used for iksemel only) files in
- PATH
- --with-gsm=PATH use GSM files in PATH , or 'internal'
- --with-iksemel=PATH use Iksemel Jabber Library files in PATH
- --with-imap=PATH use UW IMAP Toolkit files in PATH
- --with-isdnnet=PATH use ISDN4Linux Library files in PATH
- --with-kde=PATH use KDE files in PATH
- --with-ltdl=PATH use libtool files in PATH
- --with-misdn=PATH use mISDN User Library files in PATH
- --with-nbs=PATH use Network Broadcast Sound files in PATH
- --with-ncurses=PATH use ncurses files in PATH
- --with-netsnmp=PATH use Net-SNMP files in PATH
- --with-newt=PATH use newt files in PATH
- --with-odbc=PATH use unixODBC files in PATH
- --with-ogg=PATH use OGG files in PATH
- --with-osptk=PATH use OSP Toolkit files in PATH
- --with-oss=PATH use Open Sound System files in PATH
- --with-popt=PATH use popt files in PATH
- --with-postgres=PATH use PostgreSQL files in PATH
- --with-pri=PATH use ISDN PRI files in PATH
- --with-pwlib=PATH use PWlib files in PATH
- --with-h323=PATH use OpenH323 files in PATH
- --with-radius=PATH use Radius Client files in PATH
- --with-speex=PATH use Speex files in PATH
- --with-speexdsp=PATH use Speexdsp files in PATH
- --with-sqlite=PATH use SQLite files in PATH
- --with-suppserv=PATH use mISDN Supplemental Services files in PATH
- --with-ssl=PATH use OpenSSL files in PATH
- --with-tds=PATH use FreeTDS files in PATH
- --with-termcap=PATH use Termcap files in PATH
- --with-tinfo=PATH use Term Info files in PATH
- --with-tonezone=PATH use tonezone files in PATH
- --with-usb=PATH use usb files in PATH
- --with-vorbis=PATH use Vorbis files in PATH
- --with-vpb=PATH use Voicetronix API files in PATH
- --with-z=PATH use zlib files in PATH
- --with-zaptel=PATH use Zaptel files in PATH
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CPP C preprocessor
- CXX C++ compiler command
- CXXFLAGS C++ compiler flags
- CXXCPP C++ preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <www.asterisk.org>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" || continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-asterisk configure 1.4
-generated by GNU Autoconf 2.61
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-
-"Asterisk"
-_ACEOF
- exit
-fi
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by asterisk $as_me 1.4, which was
-generated by GNU Autoconf 2.61. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- echo "PATH: $as_dir"
-done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
- 2)
- ac_configure_args1="$ac_configure_args1 '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- ac_configure_args="$ac_configure_args '$ac_arg'"
- ;;
- esac
- done
-done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- *) $as_unset $ac_var ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
- set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
- set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
- set x "$ac_default_prefix/share/config.site" \
- "$ac_default_prefix/etc/config.site"
-fi
-shift
-for ac_site_file
-do
- if test -r "$ac_site_file"; then
- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-ac_header_list="$ac_header_list utime.h"
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
-echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
-echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-# cross-compile macros
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
-echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
-echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
- { (exit 1); exit 1; }; }
-
-{ echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
-if test "${ac_cv_build+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
- { (exit 1); exit 1; }; }
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
-echo "$as_me: error: invalid value of canonical build" >&2;}
- { (exit 1); exit 1; }; };;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
-if test "${ac_cv_host+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
-echo "$as_me: error: invalid value of canonical host" >&2;}
- { (exit 1); exit 1; }; };;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
-
-
-# check existence of the package
-
-
-# specify output header file
-ac_config_headers="$ac_config_headers include/asterisk/autoconfig.h"
-
-
-
-
-
-
-cat >>confdefs.h <<\_ACEOF
-#define _GNU_SOURCE 1
-_ACEOF
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-#
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort. b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
-#
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions. Remove them first so a
-# subsequent execution test works.
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { (ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
-if test -z "$ac_file"; then
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
- fi
- fi
-fi
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- CFLAGS=""
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cc_c89=$ac_arg
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
- xno)
- { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
- # Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- ac_count=`expr $ac_count + 1`
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_GREP_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_GREP=$GREP
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
- # Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- ac_count=`expr $ac_count + 1`
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_EGREP_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
-
- fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-
-{ echo "$as_me:$LINENO: checking for AIX" >&5
-echo $ECHO_N "checking for AIX... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef _AIX
- yes
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "yes" >/dev/null 2>&1; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-cat >>confdefs.h <<\_ACEOF
-#define _ALL_SOURCE 1
-_ACEOF
-
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-rm -f conftest*
-
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header_stdc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_stdc=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_Header=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-if test "${ac_cv_header_minix_config_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for minix/config.h" >&5
-echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_minix_config_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
-echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking minix/config.h usability" >&5
-echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <minix/config.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking minix/config.h presence" >&5
-echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <minix/config.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for minix/config.h" >&5
-echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_minix_config_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_minix_config_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
-echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6; }
-
-fi
-if test $ac_cv_header_minix_config_h = yes; then
- MINIX=yes
-else
- MINIX=
-fi
-
-
-if test "$MINIX" = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define _POSIX_SOURCE 1
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define _POSIX_1_SOURCE 2
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define _MINIX 1
-_ACEOF
-
-fi
-
-
-
-
-
-
-
-
-
-
-
- { echo "$as_me:$LINENO: checking whether it is safe to define __EXTENSIONS__" >&5
-echo $ECHO_N "checking whether it is safe to define __EXTENSIONS__... $ECHO_C" >&6; }
-if test "${ac_cv_safe_to_define___extensions__+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-# define __EXTENSIONS__ 1
- $ac_includes_default
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_safe_to_define___extensions__=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_safe_to_define___extensions__=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_safe_to_define___extensions__" >&5
-echo "${ECHO_T}$ac_cv_safe_to_define___extensions__" >&6; }
- test $ac_cv_safe_to_define___extensions__ = yes &&
- cat >>confdefs.h <<\_ACEOF
-#define __EXTENSIONS__ 1
-_ACEOF
-
- cat >>confdefs.h <<\_ACEOF
-#define _POSIX_PTHREAD_SEMANTICS 1
-_ACEOF
-
- cat >>confdefs.h <<\_ACEOF
-#define _TANDEM_SOURCE 1
-_ACEOF
-
- # note- does not work on FreeBSD
-
-case "${host_os}" in
- freebsd*)
- ac_default_prefix=/usr/local
- CPPFLAGS=-I/usr/local/include
- LDFLAGS=-L/usr/local/lib
- ;;
- *)
- ac_default_prefix=/usr
- if test ${sysconfdir} = '${prefix}/etc'; then
- sysconfdir=/etc
- fi
- if test ${mandir} = '${prefix}/man'; then
- mandir=/usr/share/man
- fi
- ;;
-esac
-
-if test ${localstatedir} = '${prefix}/var'; then
- localstatedir=/var
-fi
-
-BUILD_PLATFORM=${build}
-BUILD_CPU=${build_cpu}
-BUILD_VENDOR=${build_vendor}
-BUILD_OS=${build_os}
-
-
-
-
-
-
-HOST_PLATFORM=${host}
-HOST_CPU=${host_cpu}
-HOST_VENDOR=${host_vendor}
-HOST_OS=${host_os}
-
-
-
-
-
-
-case "${host_os}" in
- freebsd*)
- OSARCH=FreeBSD
- ;;
- netbsd*)
- OSARCH=NetBSD
- ;;
- openbsd*)
- OSARCH=OpenBSD
- ;;
- solaris*)
- OSARCH=SunOS
- ;;
- *)
- OSARCH=${HOST_OS}
- ;;
-esac
-
-
-
-# check for uname
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}uname", so it can be a program name with args.
-set dummy ${ac_tool_prefix}uname; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_UNAME+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $UNAME in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_UNAME="$UNAME" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_UNAME="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-UNAME=$ac_cv_path_UNAME
-if test -n "$UNAME"; then
- { echo "$as_me:$LINENO: result: $UNAME" >&5
-echo "${ECHO_T}$UNAME" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_UNAME"; then
- ac_pt_UNAME=$UNAME
- # Extract the first word of "uname", so it can be a program name with args.
-set dummy uname; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_UNAME+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_UNAME in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_UNAME="$ac_pt_UNAME" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_UNAME="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_UNAME=$ac_cv_path_ac_pt_UNAME
-if test -n "$ac_pt_UNAME"; then
- { echo "$as_me:$LINENO: result: $ac_pt_UNAME" >&5
-echo "${ECHO_T}$ac_pt_UNAME" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_UNAME" = x; then
- UNAME="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- UNAME=$ac_pt_UNAME
- fi
-else
- UNAME="$ac_cv_path_UNAME"
-fi
-
-if test ! x"${UNAME}" = xNo; then
- PBX_OSREV=$(${UNAME} -r)
-fi
-
-
-
-
-
-
-
-
-# cross-compile checks
-if test "${cross_compiling}" = "yes";
-then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}g++", so it can be a program name with args.
-set dummy ${ac_tool_prefix}g++; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CXX="${ac_tool_prefix}g++"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- { echo "$as_me:$LINENO: result: $CXX" >&5
-echo "${ECHO_T}$CXX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CXX"; then
- ac_ct_CXX=$CXX
- # Extract the first word of "g++", so it can be a program name with args.
-set dummy g++; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CXX="g++"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
-echo "${ECHO_T}$ac_ct_CXX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_CXX" = x; then
- CXX=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CXX=$ac_ct_CXX
- fi
-else
- CXX="$ac_cv_prog_CXX"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ld; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$LD"; then
- ac_cv_prog_LD="$LD" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_LD="${ac_tool_prefix}ld"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-LD=$ac_cv_prog_LD
-if test -n "$LD"; then
- { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_LD"; then
- ac_ct_LD=$LD
- # Extract the first word of "ld", so it can be a program name with args.
-set dummy ld; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_LD"; then
- ac_cv_prog_ac_ct_LD="$ac_ct_LD" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_LD="ld"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_LD=$ac_cv_prog_ac_ct_LD
-if test -n "$ac_ct_LD"; then
- { echo "$as_me:$LINENO: result: $ac_ct_LD" >&5
-echo "${ECHO_T}$ac_ct_LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_LD" = x; then
- LD=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- LD=$ac_ct_LD
- fi
-else
- LD="$ac_cv_prog_LD"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-fi
-
-# Checks for programs.
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- CFLAGS=""
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cc_c89=$ac_arg
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
- xno)
- { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
- if test -n "$CCC"; then
- CXX=$CCC
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- { echo "$as_me:$LINENO: result: $CXX" >&5
-echo "${ECHO_T}$CXX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$CXX" && break
- done
-fi
-if test -z "$CXX"; then
- ac_ct_CXX=$CXX
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CXX="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
-echo "${ECHO_T}$ac_ct_CXX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_CXX" && break
-done
-
- if test "x$ac_ct_CXX" = x; then
- CXX="g++"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CXX=$ac_ct_CXX
- fi
-fi
-
- fi
-fi
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C++ compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
-GXX=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
-echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cxx_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_save_cxx_werror_flag=$ac_cxx_werror_flag
- ac_cxx_werror_flag=yes
- ac_cv_prog_cxx_g=no
- CXXFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cxx_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- CXXFLAGS=""
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
- CXXFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cxx_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
-echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
-if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
-echo "${ECHO_T}$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-# This macro is just copied into our local acinclude.m4 from libtool.m4 so that
-# the developers regenerating the configure script don't have to install libtool.
-{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
-echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
-if test "${ac_cv_path_SED+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for ac_i in 1 2 3 4 5 6 7; do
- ac_script="$ac_script$as_nl$ac_script"
- done
- echo "$ac_script" | sed 99q >conftest.sed
- $as_unset ac_script || ac_script=
- # Extract the first word of "sed gsed" to use in msg output
-if test -z "$SED"; then
-set dummy sed gsed; ac_prog_name=$2
-if test "${ac_cv_path_SED+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_SED_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
- # Check for GNU ac_path_SED and select it if it is found.
- # Check for GNU $ac_path_SED
-case `"$ac_path_SED" --version 2>&1` in
-*GNU*)
- ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- echo '' >> "conftest.nl"
- "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- ac_count=`expr $ac_count + 1`
- if test $ac_count -gt ${ac_path_SED_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_SED="$ac_path_SED"
- ac_path_SED_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_SED_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-SED="$ac_cv_path_SED"
-if test -z "$SED"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in \$PATH" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in \$PATH" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_SED=$SED
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_SED" >&5
-echo "${ECHO_T}$ac_cv_path_SED" >&6; }
- SED="$ac_cv_path_SED"
- rm -f conftest.sed
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_prog_egrep+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6; }
- EGREP=$ac_cv_prog_egrep
-
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
-else
- { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
-echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
- { (exit 1); exit 1; }; }
-{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
- # note - does not work on freebsd
-for ac_prog in gawk mawk nawk awk
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AWK="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { echo "$as_me:$LINENO: result: $AWK" >&5
-echo "${ECHO_T}$AWK" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in
- ./ | .// | /cC/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- done
- done
- ;;
-esac
-done
-IFS=$as_save_IFS
-
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
- { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6; }
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-{ echo "$as_me:$LINENO: checking for GNU make" >&5
-echo $ECHO_N "checking for GNU make... $ECHO_C" >&6; }
-if test "${GNU_MAKE+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- GNU_MAKE='Not Found' ;
- GNU_MAKE_VERSION_MAJOR=0 ;
- GNU_MAKE_VERSION_MINOR=0 ;
- for a in make gmake gnumake ; do
- if test -z "$a" ; then continue ; fi ;
- if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
- GNU_MAKE=$a ;
- GNU_MAKE_VERSION_MAJOR=`$GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'`
- GNU_MAKE_VERSION_MINOR=`$GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2`
- break;
- fi
- done ;
-
-fi
-{ echo "$as_me:$LINENO: result: $GNU_MAKE" >&5
-echo "${ECHO_T}$GNU_MAKE" >&6; } ;
-if test "x$GNU_MAKE" = "xNot Found" ; then
- { { echo "$as_me:$LINENO: error: *** Please install GNU make. It is required to build Asterisk!" >&5
-echo "$as_me: error: *** Please install GNU make. It is required to build Asterisk!" >&2;}
- { (exit 1); exit 1; }; }
- exit 1
-fi
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $STRIP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-STRIP=$ac_cv_path_STRIP
-if test -n "$STRIP"; then
- { echo "$as_me:$LINENO: result: $STRIP" >&5
-echo "${ECHO_T}$STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_STRIP"; then
- ac_pt_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_STRIP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_STRIP="$ac_pt_STRIP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_STRIP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_STRIP=$ac_cv_path_ac_pt_STRIP
-if test -n "$ac_pt_STRIP"; then
- { echo "$as_me:$LINENO: result: $ac_pt_STRIP" >&5
-echo "${ECHO_T}$ac_pt_STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_pt_STRIP
- fi
-else
- STRIP="$ac_cv_path_STRIP"
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $AR in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_AR="$AR" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-AR=$ac_cv_path_AR
-if test -n "$AR"; then
- { echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_AR"; then
- ac_pt_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_AR in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_AR="$ac_pt_AR" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_AR="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_AR=$ac_cv_path_ac_pt_AR
-if test -n "$ac_pt_AR"; then
- { echo "$as_me:$LINENO: result: $ac_pt_AR" >&5
-echo "${ECHO_T}$ac_pt_AR" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_AR" = x; then
- AR=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- AR=$ac_pt_AR
- fi
-else
- AR="$ac_cv_path_AR"
-fi
-
-
-GNU_LD=0
-if test "x$with_gnu_ld" = "xyes" ; then
- GNU_LD=1
-fi
-
-
-# Extract the first word of "awk", so it can be a program name with args.
-set dummy awk; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_AWK+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $AWK in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_AWK="$AWK" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_AWK="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_AWK" && ac_cv_path_AWK=":"
- ;;
-esac
-fi
-AWK=$ac_cv_path_AWK
-if test -n "$AWK"; then
- { echo "$as_me:$LINENO: result: $AWK" >&5
-echo "${ECHO_T}$AWK" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "grep", so it can be a program name with args.
-set dummy grep; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $GREP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_GREP="$GREP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_GREP" && ac_cv_path_GREP=":"
- ;;
-esac
-fi
-GREP=$ac_cv_path_GREP
-if test -n "$GREP"; then
- { echo "$as_me:$LINENO: result: $GREP" >&5
-echo "${ECHO_T}$GREP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "find", so it can be a program name with args.
-set dummy find; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_FIND+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $FIND in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_FIND="$FIND" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_FIND" && ac_cv_path_FIND=":"
- ;;
-esac
-fi
-FIND=$ac_cv_path_FIND
-if test -n "$FIND"; then
- { echo "$as_me:$LINENO: result: $FIND" >&5
-echo "${ECHO_T}$FIND" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "compress", so it can be a program name with args.
-set dummy compress; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_COMPRESS+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $COMPRESS in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_COMPRESS="$COMPRESS" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_COMPRESS" && ac_cv_path_COMPRESS=":"
- ;;
-esac
-fi
-COMPRESS=$ac_cv_path_COMPRESS
-if test -n "$COMPRESS"; then
- { echo "$as_me:$LINENO: result: $COMPRESS" >&5
-echo "${ECHO_T}$COMPRESS" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "basename", so it can be a program name with args.
-set dummy basename; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_BASENAME+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $BASENAME in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_BASENAME="$BASENAME" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_BASENAME="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_BASENAME" && ac_cv_path_BASENAME=":"
- ;;
-esac
-fi
-BASENAME=$ac_cv_path_BASENAME
-if test -n "$BASENAME"; then
- { echo "$as_me:$LINENO: result: $BASENAME" >&5
-echo "${ECHO_T}$BASENAME" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "id", so it can be a program name with args.
-set dummy id; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ID+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ID in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ID="$ID" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ID="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_ID" && ac_cv_path_ID=":"
- ;;
-esac
-fi
-ID=$ac_cv_path_ID
-if test -n "$ID"; then
- { echo "$as_me:$LINENO: result: $ID" >&5
-echo "${ECHO_T}$ID" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "dirname", so it can be a program name with args.
-set dummy dirname; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_DIRNAME+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $DIRNAME in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_DIRNAME="$DIRNAME" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_DIRNAME="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_DIRNAME" && ac_cv_path_DIRNAME=":"
- ;;
-esac
-fi
-DIRNAME=$ac_cv_path_DIRNAME
-if test -n "$DIRNAME"; then
- { echo "$as_me:$LINENO: result: $DIRNAME" >&5
-echo "${ECHO_T}$DIRNAME" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "sh", so it can be a program name with args.
-set dummy sh; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_SHELL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $SHELL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_SHELL="$SHELL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_SHELL="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_SHELL" && ac_cv_path_SHELL=":"
- ;;
-esac
-fi
-SHELL=$ac_cv_path_SHELL
-if test -n "$SHELL"; then
- { echo "$as_me:$LINENO: result: $SHELL" >&5
-echo "${ECHO_T}$SHELL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "ln", so it can be a program name with args.
-set dummy ln; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_LN+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $LN in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_LN="$LN" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_LN" && ac_cv_path_LN=":"
- ;;
-esac
-fi
-LN=$ac_cv_path_LN
-if test -n "$LN"; then
- { echo "$as_me:$LINENO: result: $LN" >&5
-echo "${ECHO_T}$LN" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "dot", so it can be a program name with args.
-set dummy dot; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_DOT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $DOT in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_DOT="$DOT" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_DOT" && ac_cv_path_DOT=":"
- ;;
-esac
-fi
-DOT=$ac_cv_path_DOT
-if test -n "$DOT"; then
- { echo "$as_me:$LINENO: result: $DOT" >&5
-echo "${ECHO_T}$DOT" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-# Extract the first word of "wget", so it can be a program name with args.
-set dummy wget; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_WGET+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $WGET in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_WGET="$WGET" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_WGET" && ac_cv_path_WGET=":"
- ;;
-esac
-fi
-WGET=$ac_cv_path_WGET
-if test -n "$WGET"; then
- { echo "$as_me:$LINENO: result: $WGET" >&5
-echo "${ECHO_T}$WGET" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-if test "${WGET}" != ":" ; then
- DOWNLOAD=${WGET}
-else
- # Extract the first word of "fetch", so it can be a program name with args.
-set dummy fetch; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_FETCH+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $FETCH in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_FETCH="$FETCH" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_FETCH="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_FETCH" && ac_cv_path_FETCH=":"
- ;;
-esac
-fi
-FETCH=$ac_cv_path_FETCH
-if test -n "$FETCH"; then
- { echo "$as_me:$LINENO: result: $FETCH" >&5
-echo "${ECHO_T}$FETCH" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- DOWNLOAD=${FETCH}
-fi
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}soxmix", so it can be a program name with args.
-set dummy ${ac_tool_prefix}soxmix; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_SOXMIX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$SOXMIX"; then
- ac_cv_prog_SOXMIX="$SOXMIX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_SOXMIX="${ac_tool_prefix}soxmix"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-SOXMIX=$ac_cv_prog_SOXMIX
-if test -n "$SOXMIX"; then
- { echo "$as_me:$LINENO: result: $SOXMIX" >&5
-echo "${ECHO_T}$SOXMIX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_SOXMIX"; then
- ac_ct_SOXMIX=$SOXMIX
- # Extract the first word of "soxmix", so it can be a program name with args.
-set dummy soxmix; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_SOXMIX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_SOXMIX"; then
- ac_cv_prog_ac_ct_SOXMIX="$ac_ct_SOXMIX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_SOXMIX="soxmix"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_SOXMIX=$ac_cv_prog_ac_ct_SOXMIX
-if test -n "$ac_ct_SOXMIX"; then
- { echo "$as_me:$LINENO: result: $ac_ct_SOXMIX" >&5
-echo "${ECHO_T}$ac_ct_SOXMIX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_SOXMIX" = x; then
- SOXMIX=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- SOXMIX=$ac_ct_SOXMIX
- fi
-else
- SOXMIX="$ac_cv_prog_SOXMIX"
-fi
-
-if test "${SOXMIX}" != ":" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_SOXMIX 1
-_ACEOF
-
-fi
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- { echo "$as_me:$LINENO: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
-echo $ECHO_N "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_join ();
-int
-main ()
-{
-return pthread_join ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- acx_pthread_ok=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- { echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
-echo "${ECHO_T}$acx_pthread_ok" >&6; }
- if test x"$acx_pthread_ok" = xno; then
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- fi
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important. Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-# other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-# doesn't hurt to check since this sometimes defines pthreads too;
-# also defines -D_REENTRANT)
-# ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
- *solaris*)
-
- # On Solaris (at least, for some versions), libc contains stubbed
- # (non-functional) versions of the pthreads routines, so link-based
- # tests will erroneously succeed. (We need to link with -pthreads/-mt/
- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
- # a function called by this macro, so we could check for that, but
- # who knows whether they'll stub that too in a future libc.) So,
- # we'll just look for -pthreads and -lpthread first:
-
- acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
- ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
- case $flag in
- none)
- { echo "$as_me:$LINENO: checking whether pthreads work without any flags" >&5
-echo $ECHO_N "checking whether pthreads work without any flags... $ECHO_C" >&6; }
- ;;
-
- -*)
- { echo "$as_me:$LINENO: checking whether pthreads work with $flag" >&5
-echo $ECHO_N "checking whether pthreads work with $flag... $ECHO_C" >&6; }
- PTHREAD_CFLAGS="$flag"
- ;;
-
- pthread-config)
- # Extract the first word of "pthread-config", so it can be a program name with args.
-set dummy pthread-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_acx_pthread_config+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$acx_pthread_config"; then
- ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_acx_pthread_config="yes"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
-fi
-fi
-acx_pthread_config=$ac_cv_prog_acx_pthread_config
-if test -n "$acx_pthread_config"; then
- { echo "$as_me:$LINENO: result: $acx_pthread_config" >&5
-echo "${ECHO_T}$acx_pthread_config" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- if test x"$acx_pthread_config" = xno; then continue; fi
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
- { echo "$as_me:$LINENO: checking for the pthreads library -l$flag" >&5
-echo $ECHO_N "checking for the pthreads library -l$flag... $ECHO_C" >&6; }
- PTHREAD_LIBS="-l$flag"
- ;;
- esac
-
- save_LIBS="$LIBS"
- save_CFLAGS="$CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <pthread.h>
-int
-main ()
-{
-pthread_t th; pthread_join(th, 0);
- pthread_attr_init(0); pthread_cleanup_push(0, 0);
- pthread_create(0,0,0,0); pthread_cleanup_pop(0);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- acx_pthread_ok=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- { echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
-echo "${ECHO_T}$acx_pthread_ok" >&6; }
- if test "x$acx_pthread_ok" = xyes; then
- break;
- fi
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
- { echo "$as_me:$LINENO: checking for joinable pthread attribute" >&5
-echo $ECHO_N "checking for joinable pthread attribute... $ECHO_C" >&6; }
- attr_name=unknown
- for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <pthread.h>
-int
-main ()
-{
-int attr=$attr; return attr;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- attr_name=$attr; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- done
- { echo "$as_me:$LINENO: result: $attr_name" >&5
-echo "${ECHO_T}$attr_name" >&6; }
- if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-
-cat >>confdefs.h <<_ACEOF
-#define PTHREAD_CREATE_JOINABLE $attr_name
-_ACEOF
-
- fi
-
- { echo "$as_me:$LINENO: checking if more special flags are required for pthreads" >&5
-echo $ECHO_N "checking if more special flags are required for pthreads... $ECHO_C" >&6; }
- flag=no
- case "${host_cpu}-${host_os}" in
- *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
- *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
- esac
- { echo "$as_me:$LINENO: result: ${flag}" >&5
-echo "${ECHO_T}${flag}" >&6; }
- if test "x$flag" != xno; then
- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
- fi
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- # More AIX lossage: must compile with xlc_r or cc_r
- if test x"$GCC" != xyes; then
- for ac_prog in xlc_r cc_r
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$PTHREAD_CC"; then
- ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_PTHREAD_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
-if test -n "$PTHREAD_CC"; then
- { echo "$as_me:$LINENO: result: $PTHREAD_CC" >&5
-echo "${ECHO_T}$PTHREAD_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$PTHREAD_CC" && break
-done
-test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}"
-
- else
- PTHREAD_CC=$CC
- fi
-else
- PTHREAD_CC="$CC"
-fi
-
-
-
-
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_PTHREAD 1
-_ACEOF
-
- :
-else
- acx_pthread_ok=no
-
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Check whether --enable-dev-mode was given.
-if test "${enable_dev_mode+set}" = set; then
- enableval=$enable_dev_mode; case "${enableval}" in
- y|ye|yes) AST_DEVMODE=yes ;;
- n|no) AST_DEVMODE=no ;;
- *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-dev-mode" >&5
-echo "$as_me: error: bad value ${enableval} for --enable-dev-mode" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
-fi
-
-
-
-# package option names should be in alphabetical order
-# by the --with option name, to make things easier for the users :-)
-
-
-ALSA_DESCRIP="Advanced Linux Sound Architecture"
-ALSA_OPTION="asound"
-
-# Check whether --with-asound was given.
-if test "${with_asound+set}" = set; then
- withval=$with_asound;
-case ${withval} in
- n|no)
- USE_ALSA=no
- ;;
- y|ye|yes)
- ALSA_MANDATORY="yes"
- ;;
- *)
- ALSA_DIR="${withval}"
- ALSA_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_ALSA=0
-
-
-
-
-
-
-CURL_DESCRIP="cURL"
-CURL_OPTION="curl"
-
-# Check whether --with-curl was given.
-if test "${with_curl+set}" = set; then
- withval=$with_curl;
-case ${withval} in
- n|no)
- USE_CURL=no
- ;;
- y|ye|yes)
- CURL_MANDATORY="yes"
- ;;
- *)
- CURL_DIR="${withval}"
- CURL_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_CURL=0
-
-
-
-
-
-
-CAP_DESCRIP="POSIX 1.e capabilities"
-CAP_OPTION="cap"
-
-# Check whether --with-cap was given.
-if test "${with_cap+set}" = set; then
- withval=$with_cap;
-case ${withval} in
- n|no)
- USE_CAP=no
- ;;
- y|ye|yes)
- CAP_MANDATORY="yes"
- ;;
- *)
- CAP_DIR="${withval}"
- CAP_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_CAP=0
-
-
-
-
-
-
-CURSES_DESCRIP="curses"
-CURSES_OPTION="curses"
-
-# Check whether --with-curses was given.
-if test "${with_curses+set}" = set; then
- withval=$with_curses;
-case ${withval} in
- n|no)
- USE_CURSES=no
- ;;
- y|ye|yes)
- CURSES_MANDATORY="yes"
- ;;
- *)
- CURSES_DIR="${withval}"
- CURSES_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_CURSES=0
-
-
-
-
-
-
-GNUTLS_DESCRIP="GNU TLS support (used for iksemel only)"
-GNUTLS_OPTION="gnutls"
-
-# Check whether --with-gnutls was given.
-if test "${with_gnutls+set}" = set; then
- withval=$with_gnutls;
-case ${withval} in
- n|no)
- USE_GNUTLS=no
- ;;
- y|ye|yes)
- GNUTLS_MANDATORY="yes"
- ;;
- *)
- GNUTLS_DIR="${withval}"
- GNUTLS_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_GNUTLS=0
-
-
-
-
-
-
-GSM_DESCRIP="GSM"
-GSM_OPTION="gsm"
-
-# Check whether --with-gsm was given.
-if test "${with_gsm+set}" = set; then
- withval=$with_gsm;
-case ${withval} in
- n|no)
- USE_GSM=no
- ;;
- y|ye|yes)
- GSM_MANDATORY="yes"
- ;;
- *)
- GSM_DIR="${withval}"
- GSM_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_GSM=0
-
-
-
-
-
-
-IKSEMEL_DESCRIP="Iksemel Jabber Library"
-IKSEMEL_OPTION="iksemel"
-
-# Check whether --with-iksemel was given.
-if test "${with_iksemel+set}" = set; then
- withval=$with_iksemel;
-case ${withval} in
- n|no)
- USE_IKSEMEL=no
- ;;
- y|ye|yes)
- IKSEMEL_MANDATORY="yes"
- ;;
- *)
- IKSEMEL_DIR="${withval}"
- IKSEMEL_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_IKSEMEL=0
-
-
-
-
-
-
-IMAP_TK_DESCRIP="UW IMAP Toolkit"
-IMAP_TK_OPTION="imap"
-
-# Check whether --with-imap was given.
-if test "${with_imap+set}" = set; then
- withval=$with_imap;
-case ${withval} in
- n|no)
- USE_IMAP_TK=no
- ;;
- y|ye|yes)
- IMAP_TK_MANDATORY="yes"
- ;;
- *)
- IMAP_TK_DIR="${withval}"
- IMAP_TK_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_IMAP_TK=0
-
-
-
-
-
-
-ISDNNET_DESCRIP="ISDN4Linux Library"
-ISDNNET_OPTION="isdnnet"
-
-# Check whether --with-isdnnet was given.
-if test "${with_isdnnet+set}" = set; then
- withval=$with_isdnnet;
-case ${withval} in
- n|no)
- USE_ISDNNET=no
- ;;
- y|ye|yes)
- ISDNNET_MANDATORY="yes"
- ;;
- *)
- ISDNNET_DIR="${withval}"
- ISDNNET_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_ISDNNET=0
-
-
-
-
-
-
-KDE_DESCRIP="KDE"
-KDE_OPTION="kde"
-
-# Check whether --with-kde was given.
-if test "${with_kde+set}" = set; then
- withval=$with_kde;
-case ${withval} in
- n|no)
- USE_KDE=no
- ;;
- y|ye|yes)
- KDE_MANDATORY="yes"
- ;;
- *)
- KDE_DIR="${withval}"
- KDE_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_KDE=0
-
-
-
-
-
-
-LTDL_DESCRIP="libtool"
-LTDL_OPTION="ltdl"
-
-# Check whether --with-ltdl was given.
-if test "${with_ltdl+set}" = set; then
- withval=$with_ltdl;
-case ${withval} in
- n|no)
- USE_LTDL=no
- ;;
- y|ye|yes)
- LTDL_MANDATORY="yes"
- ;;
- *)
- LTDL_DIR="${withval}"
- LTDL_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_LTDL=0
-
-
-
-
-
-
-MISDN_DESCRIP="mISDN User Library"
-MISDN_OPTION="misdn"
-
-# Check whether --with-misdn was given.
-if test "${with_misdn+set}" = set; then
- withval=$with_misdn;
-case ${withval} in
- n|no)
- USE_MISDN=no
- ;;
- y|ye|yes)
- MISDN_MANDATORY="yes"
- ;;
- *)
- MISDN_DIR="${withval}"
- MISDN_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_MISDN=0
-
-
-
-
-
-
-NBS_DESCRIP="Network Broadcast Sound"
-NBS_OPTION="nbs"
-
-# Check whether --with-nbs was given.
-if test "${with_nbs+set}" = set; then
- withval=$with_nbs;
-case ${withval} in
- n|no)
- USE_NBS=no
- ;;
- y|ye|yes)
- NBS_MANDATORY="yes"
- ;;
- *)
- NBS_DIR="${withval}"
- NBS_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_NBS=0
-
-
-
-
-
-
-NCURSES_DESCRIP="ncurses"
-NCURSES_OPTION="ncurses"
-
-# Check whether --with-ncurses was given.
-if test "${with_ncurses+set}" = set; then
- withval=$with_ncurses;
-case ${withval} in
- n|no)
- USE_NCURSES=no
- ;;
- y|ye|yes)
- NCURSES_MANDATORY="yes"
- ;;
- *)
- NCURSES_DIR="${withval}"
- NCURSES_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_NCURSES=0
-
-
-
-
-
-
-NETSNMP_DESCRIP="Net-SNMP"
-NETSNMP_OPTION="netsnmp"
-
-# Check whether --with-netsnmp was given.
-if test "${with_netsnmp+set}" = set; then
- withval=$with_netsnmp;
-case ${withval} in
- n|no)
- USE_NETSNMP=no
- ;;
- y|ye|yes)
- NETSNMP_MANDATORY="yes"
- ;;
- *)
- NETSNMP_DIR="${withval}"
- NETSNMP_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_NETSNMP=0
-
-
-
-
-
-
-NEWT_DESCRIP="newt"
-NEWT_OPTION="newt"
-
-# Check whether --with-newt was given.
-if test "${with_newt+set}" = set; then
- withval=$with_newt;
-case ${withval} in
- n|no)
- USE_NEWT=no
- ;;
- y|ye|yes)
- NEWT_MANDATORY="yes"
- ;;
- *)
- NEWT_DIR="${withval}"
- NEWT_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_NEWT=0
-
-
-
-
-
-
-UNIXODBC_DESCRIP="unixODBC"
-UNIXODBC_OPTION="odbc"
-
-# Check whether --with-odbc was given.
-if test "${with_odbc+set}" = set; then
- withval=$with_odbc;
-case ${withval} in
- n|no)
- USE_UNIXODBC=no
- ;;
- y|ye|yes)
- UNIXODBC_MANDATORY="yes"
- ;;
- *)
- UNIXODBC_DIR="${withval}"
- UNIXODBC_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_UNIXODBC=0
-
-
-
-
-
-
-OGG_DESCRIP="OGG"
-OGG_OPTION="ogg"
-
-# Check whether --with-ogg was given.
-if test "${with_ogg+set}" = set; then
- withval=$with_ogg;
-case ${withval} in
- n|no)
- USE_OGG=no
- ;;
- y|ye|yes)
- OGG_MANDATORY="yes"
- ;;
- *)
- OGG_DIR="${withval}"
- OGG_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_OGG=0
-
-
-
-
-
-
-OSPTK_DESCRIP="OSP Toolkit"
-OSPTK_OPTION="osptk"
-
-# Check whether --with-osptk was given.
-if test "${with_osptk+set}" = set; then
- withval=$with_osptk;
-case ${withval} in
- n|no)
- USE_OSPTK=no
- ;;
- y|ye|yes)
- OSPTK_MANDATORY="yes"
- ;;
- *)
- OSPTK_DIR="${withval}"
- OSPTK_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_OSPTK=0
-
-
-
-
-
-
-OSS_DESCRIP="Open Sound System"
-OSS_OPTION="oss"
-
-# Check whether --with-oss was given.
-if test "${with_oss+set}" = set; then
- withval=$with_oss;
-case ${withval} in
- n|no)
- USE_OSS=no
- ;;
- y|ye|yes)
- OSS_MANDATORY="yes"
- ;;
- *)
- OSS_DIR="${withval}"
- OSS_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_OSS=0
-
-
-
-
-
-
-POPT_DESCRIP="popt"
-POPT_OPTION="popt"
-
-# Check whether --with-popt was given.
-if test "${with_popt+set}" = set; then
- withval=$with_popt;
-case ${withval} in
- n|no)
- USE_POPT=no
- ;;
- y|ye|yes)
- POPT_MANDATORY="yes"
- ;;
- *)
- POPT_DIR="${withval}"
- POPT_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_POPT=0
-
-
-
-
-
-
-PGSQL_DESCRIP="PostgreSQL"
-PGSQL_OPTION="postgres"
-
-# Check whether --with-postgres was given.
-if test "${with_postgres+set}" = set; then
- withval=$with_postgres;
-case ${withval} in
- n|no)
- USE_PGSQL=no
- ;;
- y|ye|yes)
- PGSQL_MANDATORY="yes"
- ;;
- *)
- PGSQL_DIR="${withval}"
- PGSQL_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_PGSQL=0
-
-
-
-
-
-
-PRI_DESCRIP="ISDN PRI"
-PRI_OPTION="pri"
-
-# Check whether --with-pri was given.
-if test "${with_pri+set}" = set; then
- withval=$with_pri;
-case ${withval} in
- n|no)
- USE_PRI=no
- ;;
- y|ye|yes)
- PRI_MANDATORY="yes"
- ;;
- *)
- PRI_DIR="${withval}"
- PRI_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_PRI=0
-
-
-
-
-
-
-PWLIB_DESCRIP="PWlib"
-PWLIB_OPTION="pwlib"
-
-# Check whether --with-pwlib was given.
-if test "${with_pwlib+set}" = set; then
- withval=$with_pwlib;
-case ${withval} in
- n|no)
- USE_PWLIB=no
- ;;
- y|ye|yes)
- PWLIB_MANDATORY="yes"
- ;;
- *)
- PWLIB_DIR="${withval}"
- PWLIB_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_PWLIB=0
-
-
-
-
-
-
-OPENH323_DESCRIP="OpenH323"
-OPENH323_OPTION="h323"
-
-# Check whether --with-h323 was given.
-if test "${with_h323+set}" = set; then
- withval=$with_h323;
-case ${withval} in
- n|no)
- USE_OPENH323=no
- ;;
- y|ye|yes)
- OPENH323_MANDATORY="yes"
- ;;
- *)
- OPENH323_DIR="${withval}"
- OPENH323_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_OPENH323=0
-
-
-
-
-
-
-RADIUS_DESCRIP="Radius Client"
-RADIUS_OPTION="radius"
-
-# Check whether --with-radius was given.
-if test "${with_radius+set}" = set; then
- withval=$with_radius;
-case ${withval} in
- n|no)
- USE_RADIUS=no
- ;;
- y|ye|yes)
- RADIUS_MANDATORY="yes"
- ;;
- *)
- RADIUS_DIR="${withval}"
- RADIUS_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_RADIUS=0
-
-
-
-
-
-
-SPEEX_DESCRIP="Speex"
-SPEEX_OPTION="speex"
-
-# Check whether --with-speex was given.
-if test "${with_speex+set}" = set; then
- withval=$with_speex;
-case ${withval} in
- n|no)
- USE_SPEEX=no
- ;;
- y|ye|yes)
- SPEEX_MANDATORY="yes"
- ;;
- *)
- SPEEX_DIR="${withval}"
- SPEEX_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_SPEEX=0
-
-
-
-
-
-
-SPEEXDSP_DESCRIP="Speexdsp"
-SPEEXDSP_OPTION="speexdsp"
-
-# Check whether --with-speexdsp was given.
-if test "${with_speexdsp+set}" = set; then
- withval=$with_speexdsp;
-case ${withval} in
- n|no)
- USE_SPEEXDSP=no
- ;;
- y|ye|yes)
- SPEEXDSP_MANDATORY="yes"
- ;;
- *)
- SPEEXDSP_DIR="${withval}"
- SPEEXDSP_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_SPEEXDSP=0
-
-
-
-
-
-
-SQLITE_DESCRIP="SQLite"
-SQLITE_OPTION="sqlite"
-
-# Check whether --with-sqlite was given.
-if test "${with_sqlite+set}" = set; then
- withval=$with_sqlite;
-case ${withval} in
- n|no)
- USE_SQLITE=no
- ;;
- y|ye|yes)
- SQLITE_MANDATORY="yes"
- ;;
- *)
- SQLITE_DIR="${withval}"
- SQLITE_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_SQLITE=0
-
-
-
-
-
-
-SUPPSERV_DESCRIP="mISDN Supplemental Services"
-SUPPSERV_OPTION="suppserv"
-
-# Check whether --with-suppserv was given.
-if test "${with_suppserv+set}" = set; then
- withval=$with_suppserv;
-case ${withval} in
- n|no)
- USE_SUPPSERV=no
- ;;
- y|ye|yes)
- SUPPSERV_MANDATORY="yes"
- ;;
- *)
- SUPPSERV_DIR="${withval}"
- SUPPSERV_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_SUPPSERV=0
-
-
-
-
-
-
-OPENSSL_DESCRIP="OpenSSL"
-OPENSSL_OPTION="ssl"
-
-# Check whether --with-ssl was given.
-if test "${with_ssl+set}" = set; then
- withval=$with_ssl;
-case ${withval} in
- n|no)
- USE_OPENSSL=no
- ;;
- y|ye|yes)
- OPENSSL_MANDATORY="yes"
- ;;
- *)
- OPENSSL_DIR="${withval}"
- OPENSSL_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_OPENSSL=0
-
-
-
-
-
-
-FREETDS_DESCRIP="FreeTDS"
-FREETDS_OPTION="tds"
-
-# Check whether --with-tds was given.
-if test "${with_tds+set}" = set; then
- withval=$with_tds;
-case ${withval} in
- n|no)
- USE_FREETDS=no
- ;;
- y|ye|yes)
- FREETDS_MANDATORY="yes"
- ;;
- *)
- FREETDS_DIR="${withval}"
- FREETDS_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_FREETDS=0
-
-
-
-
-
-
-TERMCAP_DESCRIP="Termcap"
-TERMCAP_OPTION="termcap"
-
-# Check whether --with-termcap was given.
-if test "${with_termcap+set}" = set; then
- withval=$with_termcap;
-case ${withval} in
- n|no)
- USE_TERMCAP=no
- ;;
- y|ye|yes)
- TERMCAP_MANDATORY="yes"
- ;;
- *)
- TERMCAP_DIR="${withval}"
- TERMCAP_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_TERMCAP=0
-
-
-
-
-
-
-TINFO_DESCRIP="Term Info"
-TINFO_OPTION="tinfo"
-
-# Check whether --with-tinfo was given.
-if test "${with_tinfo+set}" = set; then
- withval=$with_tinfo;
-case ${withval} in
- n|no)
- USE_TINFO=no
- ;;
- y|ye|yes)
- TINFO_MANDATORY="yes"
- ;;
- *)
- TINFO_DIR="${withval}"
- TINFO_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_TINFO=0
-
-
-
-
-
-
-TONEZONE_DESCRIP="tonezone"
-TONEZONE_OPTION="tonezone"
-
-# Check whether --with-tonezone was given.
-if test "${with_tonezone+set}" = set; then
- withval=$with_tonezone;
-case ${withval} in
- n|no)
- USE_TONEZONE=no
- ;;
- y|ye|yes)
- TONEZONE_MANDATORY="yes"
- ;;
- *)
- TONEZONE_DIR="${withval}"
- TONEZONE_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_TONEZONE=0
-
-
-
-
-
-
-USB_DESCRIP="usb"
-USB_OPTION="usb"
-
-# Check whether --with-usb was given.
-if test "${with_usb+set}" = set; then
- withval=$with_usb;
-case ${withval} in
- n|no)
- USE_USB=no
- ;;
- y|ye|yes)
- USB_MANDATORY="yes"
- ;;
- *)
- USB_DIR="${withval}"
- USB_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_USB=0
-
-
-
-
-
-
-VORBIS_DESCRIP="Vorbis"
-VORBIS_OPTION="vorbis"
-
-# Check whether --with-vorbis was given.
-if test "${with_vorbis+set}" = set; then
- withval=$with_vorbis;
-case ${withval} in
- n|no)
- USE_VORBIS=no
- ;;
- y|ye|yes)
- VORBIS_MANDATORY="yes"
- ;;
- *)
- VORBIS_DIR="${withval}"
- VORBIS_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_VORBIS=0
-
-
-
-
-
-
-VPB_DESCRIP="Voicetronix API"
-VPB_OPTION="vpb"
-
-# Check whether --with-vpb was given.
-if test "${with_vpb+set}" = set; then
- withval=$with_vpb;
-case ${withval} in
- n|no)
- USE_VPB=no
- ;;
- y|ye|yes)
- VPB_MANDATORY="yes"
- ;;
- *)
- VPB_DIR="${withval}"
- VPB_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_VPB=0
-
-
-
-
-
-
-ZLIB_DESCRIP="zlib"
-ZLIB_OPTION="z"
-
-# Check whether --with-z was given.
-if test "${with_z+set}" = set; then
- withval=$with_z;
-case ${withval} in
- n|no)
- USE_ZLIB=no
- ;;
- y|ye|yes)
- ZLIB_MANDATORY="yes"
- ;;
- *)
- ZLIB_DIR="${withval}"
- ZLIB_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_ZLIB=0
-
-
-
-
-
-
-ZAPTEL_DESCRIP="Zaptel"
-ZAPTEL_OPTION="zaptel"
-
-# Check whether --with-zaptel was given.
-if test "${with_zaptel+set}" = set; then
- withval=$with_zaptel;
-case ${withval} in
- n|no)
- USE_ZAPTEL=no
- ;;
- y|ye|yes)
- ZAPTEL_MANDATORY="yes"
- ;;
- *)
- ZAPTEL_DIR="${withval}"
- ZAPTEL_MANDATORY="yes"
- ;;
-esac
-
-fi
-
-PBX_ZAPTEL=0
-
-
-
-
-
-
-# check for basic system features and functionality before
-# checking for package libraries
-
-# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-# for constant arguments. Useless!
-{ echo "$as_me:$LINENO: checking for working alloca.h" >&5
-echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; }
-if test "${ac_cv_working_alloca_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <alloca.h>
-int
-main ()
-{
-char *p = (char *) alloca (2 * sizeof (int));
- if (p) return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_working_alloca_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_working_alloca_h=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
-echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; }
-if test $ac_cv_working_alloca_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ALLOCA_H 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for alloca" >&5
-echo $ECHO_N "checking for alloca... $ECHO_C" >&6; }
-if test "${ac_cv_func_alloca_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# ifdef _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-# else
-# ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif
-# endif
-# endif
-# endif
-#endif
-
-int
-main ()
-{
-char *p = (char *) alloca (1);
- if (p) return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_func_alloca_works=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_alloca_works=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
-echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; }
-
-if test $ac_cv_func_alloca_works = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ALLOCA 1
-_ACEOF
-
-else
- # The SVR3 libPW and SVR4 libucb both contain incompatible functions
-# that cause trouble. Some versions do not even contain alloca or
-# contain a buggy version. If you still want to use their alloca,
-# use ar to extract alloca.o from them instead of compiling alloca.c.
-
-ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
-
-cat >>confdefs.h <<\_ACEOF
-#define C_ALLOCA 1
-_ACEOF
-
-
-{ echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
-echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; }
-if test "${ac_cv_os_cray+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#if defined CRAY && ! defined CRAY2
-webecray
-#else
-wenotbecray
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "webecray" >/dev/null 2>&1; then
- ac_cv_os_cray=yes
-else
- ac_cv_os_cray=no
-fi
-rm -f conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
-echo "${ECHO_T}$ac_cv_os_cray" >&6; }
-if test $ac_cv_os_cray = yes; then
- for ac_func in _getb67 GETB67 getb67; do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define CRAY_STACKSEG_END $ac_func
-_ACEOF
-
- break
-fi
-
- done
-fi
-
-{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
-echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; }
-if test "${ac_cv_c_stack_direction+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_stack_direction=0
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-find_stack_direction ()
-{
- static char *addr = 0;
- auto char dummy;
- if (addr == 0)
- {
- addr = &dummy;
- return find_stack_direction ();
- }
- else
- return (&dummy > addr) ? 1 : -1;
-}
-
-int
-main ()
-{
- return find_stack_direction () < 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_stack_direction=1
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_stack_direction=-1
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
-echo "${ECHO_T}$ac_cv_c_stack_direction" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define STACK_DIRECTION $ac_cv_c_stack_direction
-_ACEOF
-
-
-fi
-
-
-
-
-
-
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
- as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
-echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <$ac_hdr>
-
-int
-main ()
-{
-if ((DIR *) 0)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_Header=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
-_ACEOF
-
-ac_header_dirent=$ac_hdr; break
-fi
-
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
- { echo "$as_me:$LINENO: checking for library containing opendir" >&5
-echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; }
-if test "${ac_cv_search_opendir+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char opendir ();
-int
-main ()
-{
-return opendir ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' dir; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_search_opendir=$ac_res
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext
- if test "${ac_cv_search_opendir+set}" = set; then
- break
-fi
-done
-if test "${ac_cv_search_opendir+set}" = set; then
- :
-else
- ac_cv_search_opendir=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
-echo "${ECHO_T}$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-else
- { echo "$as_me:$LINENO: checking for library containing opendir" >&5
-echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; }
-if test "${ac_cv_search_opendir+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char opendir ();
-int
-main ()
-{
-return opendir ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' x; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_search_opendir=$ac_res
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext
- if test "${ac_cv_search_opendir+set}" = set; then
- break
-fi
-done
-if test "${ac_cv_search_opendir+set}" = set; then
- :
-else
- ac_cv_search_opendir=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
-echo "${ECHO_T}$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-fi
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header_stdc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_stdc=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
-echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; }
-if test "${ac_cv_header_sys_wait_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/wait.h>
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
-#endif
-#ifndef WIFEXITED
-# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif
-
-int
-main ()
-{
- int s;
- wait (&s);
- s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header_sys_wait_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_sys_wait_h=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; }
-if test $ac_cv_header_sys_wait_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_SYS_WAIT_H 1
-_ACEOF
-
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-for ac_header in arpa/inet.h fcntl.h inttypes.h libintl.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h termios.h unistd.h utime.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-# Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then
- enableval=$enable_largefile;
-fi
-
-if test "$enable_largefile" != no; then
-
- { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
-echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_largefile_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- ac_save_CC=$CC
- while :; do
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
- CC="$CC -n32"
- rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_sys_largefile_CC=' -n32'; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
- break
- done
- CC=$ac_save_CC
- rm -f conftest.$ac_ext
- fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC=$CC$ac_cv_sys_largefile_CC
- fi
-
- { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- while :; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_sys_file_offset_bits=no; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_sys_file_offset_bits=64; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_file_offset_bits=unknown
- break
-done
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
-echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
-case $ac_cv_sys_file_offset_bits in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-;;
-esac
-rm -f conftest*
- if test $ac_cv_sys_file_offset_bits = unknown; then
- { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
-echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_large_files+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- while :; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_sys_large_files=no; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_sys_large_files=1; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_large_files=unknown
- break
-done
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
-echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
-case $ac_cv_sys_large_files in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-;;
-esac
-rm -f conftest*
- fi
-fi
-
-
-# Checks for typedefs, structures, and compiler characteristics.
-{ echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5
-echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdbool_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#include <stdbool.h>
-#ifndef bool
- "error: bool is not defined"
-#endif
-#ifndef false
- "error: false is not defined"
-#endif
-#if false
- "error: false is not 0"
-#endif
-#ifndef true
- "error: true is not defined"
-#endif
-#if true != 1
- "error: true is not 1"
-#endif
-#ifndef __bool_true_false_are_defined
- "error: __bool_true_false_are_defined is not defined"
-#endif
-
- struct s { _Bool s: 1; _Bool t; } s;
-
- char a[true == 1 ? 1 : -1];
- char b[false == 0 ? 1 : -1];
- char c[__bool_true_false_are_defined == 1 ? 1 : -1];
- char d[(bool) 0.5 == true ? 1 : -1];
- bool e = &s;
- char f[(_Bool) 0.0 == false ? 1 : -1];
- char g[true];
- char h[sizeof (_Bool)];
- char i[sizeof s.t];
- enum { j = false, k = true, l = false * true, m = true * 256 };
- _Bool n[m];
- char o[sizeof n == m * sizeof n[0] ? 1 : -1];
- char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
-# if defined __xlc__ || defined __GNUC__
- /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
- reported by James Lemley on 2005-10-05; see
- http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
- This test is not quite right, since xlc is allowed to
- reject this program, as the initializer for xlcbug is
- not one of the forms that C requires support for.
- However, doing the test right would require a runtime
- test, and that would make cross-compilation harder.
- Let us hope that IBM fixes the xlc bug, and also adds
- support for this kind of constant expression. In the
- meantime, this test will reject xlc, which is OK, since
- our stdbool.h substitute should suffice. We also test
- this with GCC, where it should work, to detect more
- quickly whether someone messes up the test in the
- future. */
- char digs[] = "0123456789";
- int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
-# endif
- /* Catch a bug in an HP-UX C compiler. See
- http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
- http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
- */
- _Bool q = true;
- _Bool *pq = &q;
-
-int
-main ()
-{
-
- *pq |= q;
- *pq |= ! q;
- /* Refer to every declared value, to avoid compiler optimizations. */
- return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
- + !m + !n + !o + !p + !q + !pq);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header_stdbool_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_stdbool_h=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5
-echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6; }
-{ echo "$as_me:$LINENO: checking for _Bool" >&5
-echo $ECHO_N "checking for _Bool... $ECHO_C" >&6; }
-if test "${ac_cv_type__Bool+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef _Bool ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type__Bool=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type__Bool=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5
-echo "${ECHO_T}$ac_cv_type__Bool" >&6; }
-if test $ac_cv_type__Bool = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE__BOOL 1
-_ACEOF
-
-
-fi
-
-if test $ac_cv_header_stdbool_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STDBOOL_H 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
-echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
-if test "${ac_cv_c_const+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-/* FIXME: Include the comments suggested by Paul. */
-#ifndef __cplusplus
- /* Ultrix mips cc rejects this. */
- typedef int charset[2];
- const charset cs;
- /* SunOS 4.1.1 cc rejects this. */
- char const *const *pcpcc;
- char **ppc;
- /* NEC SVR4.0.2 mips cc rejects this. */
- struct point {int x, y;};
- static struct point const zero = {0,0};
- /* AIX XL C 1.02.0.0 rejects this.
- It does not let you subtract one const X* pointer from another in
- an arm of an if-expression whose if-part is not a constant
- expression */
- const char *g = "string";
- pcpcc = &g + (g ? g-g : 0);
- /* HPUX 7.0 cc rejects these. */
- ++pcpcc;
- ppc = (char**) pcpcc;
- pcpcc = (char const *const *) ppc;
- { /* SCO 3.2v4 cc rejects this. */
- char *t;
- char const *s = 0 ? (char *) 0 : (char const *) 0;
-
- *t++ = 0;
- if (s) return 0;
- }
- { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
- int x[] = {25, 17};
- const int *foo = &x[0];
- ++foo;
- }
- { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
- typedef const int *iptr;
- iptr p = 0;
- ++p;
- }
- { /* AIX XL C 1.02.0.0 rejects this saying
- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
- }
- { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
- const int foo = 10;
- if (!foo) return 0;
- }
- return !cs[0] && !zero.x;
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_c_const=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_c_const=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
-echo "${ECHO_T}$ac_cv_c_const" >&6; }
-if test $ac_cv_c_const = no; then
-
-cat >>confdefs.h <<\_ACEOF
-#define const
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
-echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; }
-if test "${ac_cv_type_uid_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "uid_t" >/dev/null 2>&1; then
- ac_cv_type_uid_t=yes
-else
- ac_cv_type_uid_t=no
-fi
-rm -f conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
-echo "${ECHO_T}$ac_cv_type_uid_t" >&6; }
-if test $ac_cv_type_uid_t = no; then
-
-cat >>confdefs.h <<\_ACEOF
-#define uid_t int
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define gid_t int
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for inline" >&5
-echo $ECHO_N "checking for inline... $ECHO_C" >&6; }
-if test "${ac_cv_c_inline+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_c_inline=no
-for ac_kw in inline __inline__ __inline; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifndef __cplusplus
-typedef int foo_t;
-static $ac_kw foo_t static_foo () {return 0; }
-$ac_kw foo_t foo () {return 0; }
-#endif
-
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_c_inline=$ac_kw
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- test "$ac_cv_c_inline" != no && break
-done
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
-echo "${ECHO_T}$ac_cv_c_inline" >&6; }
-
-
-case $ac_cv_c_inline in
- inline | yes) ;;
- *)
- case $ac_cv_c_inline in
- no) ac_val=;;
- *) ac_val=$ac_cv_c_inline;;
- esac
- cat >>confdefs.h <<_ACEOF
-#ifndef __cplusplus
-#define inline $ac_val
-#endif
-_ACEOF
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking for mode_t" >&5
-echo $ECHO_N "checking for mode_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_mode_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef mode_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_mode_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_mode_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5
-echo "${ECHO_T}$ac_cv_type_mode_t" >&6; }
-if test $ac_cv_type_mode_t = yes; then
- :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define mode_t int
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for off_t" >&5
-echo $ECHO_N "checking for off_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_off_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef off_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_off_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_off_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
-echo "${ECHO_T}$ac_cv_type_off_t" >&6; }
-if test $ac_cv_type_off_t = yes; then
- :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define off_t long int
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for pid_t" >&5
-echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_pid_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef pid_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_pid_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_pid_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
-echo "${ECHO_T}$ac_cv_type_pid_t" >&6; }
-if test $ac_cv_type_pid_t = yes; then
- :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for size_t" >&5
-echo $ECHO_N "checking for size_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_size_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef size_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_size_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_size_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
-echo "${ECHO_T}$ac_cv_type_size_t" >&6; }
-if test $ac_cv_type_size_t = yes; then
- :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5
-echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6; }
-if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static struct stat ac_aggr;
-if (ac_aggr.st_blksize)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_member_struct_stat_st_blksize=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static struct stat ac_aggr;
-if (sizeof ac_aggr.st_blksize)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_member_struct_stat_st_blksize=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_member_struct_stat_st_blksize=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5
-echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6; }
-if test $ac_cv_member_struct_stat_st_blksize = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-_ACEOF
-
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
-echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; }
-if test "${ac_cv_header_time+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
-int
-main ()
-{
-if ((struct tm *) 0)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header_time=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_time=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
-echo "${ECHO_T}$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define TIME_WITH_SYS_TIME 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
-echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6; }
-if test "${ac_cv_struct_tm+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <time.h>
-
-int
-main ()
-{
-struct tm tm;
- int *p = &tm.tm_sec;
- return !p;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_struct_tm=time.h
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_struct_tm=sys/time.h
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
-echo "${ECHO_T}$ac_cv_struct_tm" >&6; }
-if test $ac_cv_struct_tm = sys/time.h; then
-
-cat >>confdefs.h <<\_ACEOF
-#define TM_IN_SYS_TIME 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for working volatile" >&5
-echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; }
-if test "${ac_cv_c_volatile+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
-volatile int x;
-int * volatile y = (int *) 0;
-return !x && !y;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_c_volatile=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_c_volatile=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5
-echo "${ECHO_T}$ac_cv_c_volatile" >&6; }
-if test $ac_cv_c_volatile = no; then
-
-cat >>confdefs.h <<\_ACEOF
-#define volatile
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for ptrdiff_t" >&5
-echo $ECHO_N "checking for ptrdiff_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_ptrdiff_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef ptrdiff_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_ptrdiff_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_ptrdiff_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_ptrdiff_t" >&5
-echo "${ECHO_T}$ac_cv_type_ptrdiff_t" >&6; }
-if test $ac_cv_type_ptrdiff_t = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PTRDIFF_T 1
-_ACEOF
-
-
-fi
-
-
-# Checks for library functions.
-
-for ac_header in unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-{ echo "$as_me:$LINENO: checking for working chown" >&5
-echo $ECHO_N "checking for working chown... $ECHO_C" >&6; }
-if test "${ac_cv_func_chown_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_chown_works=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <fcntl.h>
-
-int
-main ()
-{
- char *f = "conftest.chown";
- struct stat before, after;
-
- if (creat (f, 0600) < 0)
- return 1;
- if (stat (f, &before) < 0)
- return 1;
- if (chown (f, (uid_t) -1, (gid_t) -1) == -1)
- return 1;
- if (stat (f, &after) < 0)
- return 1;
- return ! (before.st_uid == after.st_uid && before.st_gid == after.st_gid);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_chown_works=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_chown_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-rm -f conftest.chown
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_chown_works" >&5
-echo "${ECHO_T}$ac_cv_func_chown_works" >&6; }
-if test $ac_cv_func_chown_works = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CHOWN 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether closedir returns void" >&5
-echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6; }
-if test "${ac_cv_func_closedir_void+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_closedir_void=yes
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header_dirent>
-#ifndef __cplusplus
-int closedir ();
-#endif
-
-int
-main ()
-{
-return closedir (opendir (".")) != 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_closedir_void=no
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_closedir_void=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5
-echo "${ECHO_T}$ac_cv_func_closedir_void" >&6; }
-if test $ac_cv_func_closedir_void = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define CLOSEDIR_VOID 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for error_at_line" >&5
-echo $ECHO_N "checking for error_at_line... $ECHO_C" >&6; }
-if test "${ac_cv_lib_error_at_line+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <error.h>
-int
-main ()
-{
-error_at_line (0, 0, "", 0, "an error occurred");
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_error_at_line=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_error_at_line=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_error_at_line" >&5
-echo "${ECHO_T}$ac_cv_lib_error_at_line" >&6; }
-if test $ac_cv_lib_error_at_line = no; then
- case " $LIBOBJS " in
- *" error.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS error.$ac_objext"
- ;;
-esac
-
-fi
-
-
-for ac_header in vfork.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-for ac_func in fork vfork
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-if test "x$ac_cv_func_fork" = xyes; then
- { echo "$as_me:$LINENO: checking for working fork" >&5
-echo $ECHO_N "checking for working fork... $ECHO_C" >&6; }
-if test "${ac_cv_func_fork_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_fork_works=cross
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
- /* By Ruediger Kuhlmann. */
- return fork () < 0;
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_fork_works=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_fork_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5
-echo "${ECHO_T}$ac_cv_func_fork_works" >&6; }
-
-else
- ac_cv_func_fork_works=$ac_cv_func_fork
-fi
-if test "x$ac_cv_func_fork_works" = xcross; then
- case $host in
- *-*-amigaos* | *-*-msdosdjgpp* | *-*-uclinux* | *-*-linux-uclibc* )
- # Override, as these systems have only a dummy fork() stub
- ac_cv_func_fork_works=no
- ;;
- *)
- ac_cv_func_fork_works=yes
- ;;
- esac
- { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
-echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
-fi
-ac_cv_func_vfork_works=$ac_cv_func_vfork
-if test "x$ac_cv_func_vfork" = xyes; then
- { echo "$as_me:$LINENO: checking for working vfork" >&5
-echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; }
-if test "${ac_cv_func_vfork_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_vfork_works=cross
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Thanks to Paul Eggert for this test. */
-$ac_includes_default
-#include <sys/wait.h>
-#ifdef HAVE_VFORK_H
-# include <vfork.h>
-#endif
-/* On some sparc systems, changes by the child to local and incoming
- argument registers are propagated back to the parent. The compiler
- is told about this with #include <vfork.h>, but some compilers
- (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
- static variable whose address is put into a register that is
- clobbered by the vfork. */
-static void
-#ifdef __cplusplus
-sparc_address_test (int arg)
-# else
-sparc_address_test (arg) int arg;
-#endif
-{
- static pid_t child;
- if (!child) {
- child = vfork ();
- if (child < 0) {
- perror ("vfork");
- _exit(2);
- }
- if (!child) {
- arg = getpid();
- write(-1, "", 0);
- _exit (arg);
- }
- }
-}
-
-int
-main ()
-{
- pid_t parent = getpid ();
- pid_t child;
-
- sparc_address_test (0);
-
- child = vfork ();
-
- if (child == 0) {
- /* Here is another test for sparc vfork register problems. This
- test uses lots of local variables, at least as many local
- variables as main has allocated so far including compiler
- temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
- 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
- reuse the register of parent for one of the local variables,
- since it will think that parent can't possibly be used any more
- in this routine. Assigning to the local variable will thus
- munge parent in the parent process. */
- pid_t
- p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
- p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
- /* Convince the compiler that p..p7 are live; otherwise, it might
- use the same hardware register for all 8 local variables. */
- if (p != p1 || p != p2 || p != p3 || p != p4
- || p != p5 || p != p6 || p != p7)
- _exit(1);
-
- /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
- from child file descriptors. If the child closes a descriptor
- before it execs or exits, this munges the parent's descriptor
- as well. Test for this by closing stdout in the child. */
- _exit(close(fileno(stdout)) != 0);
- } else {
- int status;
- struct stat st;
-
- while (wait(&status) != child)
- ;
- return (
- /* Was there some problem with vforking? */
- child < 0
-
- /* Did the child fail? (This shouldn't happen.) */
- || status
-
- /* Did the vfork/compiler bug occur? */
- || parent != getpid()
-
- /* Did the file descriptor bug occur? */
- || fstat(fileno(stdout), &st) != 0
- );
- }
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_vfork_works=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_vfork_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5
-echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; }
-
-fi;
-if test "x$ac_cv_func_fork_works" = xcross; then
- ac_cv_func_vfork_works=$ac_cv_func_vfork
- { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
-echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
-fi
-
-if test "x$ac_cv_func_vfork_works" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_WORKING_VFORK 1
-_ACEOF
-
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define vfork fork
-_ACEOF
-
-fi
-if test "x$ac_cv_func_fork_works" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_WORKING_FORK 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
-echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_largefile_source+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- while :; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h> /* for off_t */
- #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
- return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_sys_largefile_source=no; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#define _LARGEFILE_SOURCE 1
-#include <sys/types.h> /* for off_t */
- #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
- return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_sys_largefile_source=1; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- ac_cv_sys_largefile_source=unknown
- break
-done
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6; }
-case $ac_cv_sys_largefile_source in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
-_ACEOF
-;;
-esac
-rm -f conftest*
-
-# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
-# in glibc 2.1.3, but that breaks too many other things.
-# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
-if test $ac_cv_sys_largefile_source != unknown; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_FSEEKO 1
-_ACEOF
-
-fi
-
-if test $ac_cv_c_compiler_gnu = yes; then
- { echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
-echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6; }
-if test "${ac_cv_prog_gcc_traditional+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_pattern="Autoconf.*'x'"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sgtty.h>
-Autoconf TIOCGETP
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "$ac_pattern" >/dev/null 2>&1; then
- ac_cv_prog_gcc_traditional=yes
-else
- ac_cv_prog_gcc_traditional=no
-fi
-rm -f conftest*
-
-
- if test $ac_cv_prog_gcc_traditional = no; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <termio.h>
-Autoconf TCGETA
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "$ac_pattern" >/dev/null 2>&1; then
- ac_cv_prog_gcc_traditional=yes
-fi
-rm -f conftest*
-
- fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
-echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6; }
- if test $ac_cv_prog_gcc_traditional = yes; then
- CC="$CC -traditional"
- fi
-fi
-
-# XXX: these are commented out until we determine whether it matters if our malloc()
-# acts exactly like glibc's or not
-# AC_FUNC_MALLOC
-# AC_FUNC_REALLOC
-{ echo "$as_me:$LINENO: checking for working memcmp" >&5
-echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6; }
-if test "${ac_cv_func_memcmp_working+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_memcmp_working=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
- /* Some versions of memcmp are not 8-bit clean. */
- char c0 = '\100', c1 = '\200', c2 = '\201';
- if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
- return 1;
-
- /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
- or more and with at least one buffer not starting on a 4-byte boundary.
- William Lewis provided this test program. */
- {
- char foo[21];
- char bar[21];
- int i;
- for (i = 0; i < 4; i++)
- {
- char *a = foo + i;
- char *b = bar + i;
- strcpy (a, "--------01111111");
- strcpy (b, "--------10000000");
- if (memcmp (a, b, 16) >= 0)
- return 1;
- }
- return 0;
- }
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_memcmp_working=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_memcmp_working=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
-echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6; }
-test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
- *" memcmp.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
- ;;
-esac
-
-
-
-
-for ac_header in stdlib.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in getpagesize
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-{ echo "$as_me:$LINENO: checking for working mmap" >&5
-echo $ECHO_N "checking for working mmap... $ECHO_C" >&6; }
-if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_mmap_fixed_mapped=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-/* malloc might have been renamed as rpl_malloc. */
-#undef malloc
-
-/* Thanks to Mike Haertel and Jim Avera for this test.
- Here is a matrix of mmap possibilities:
- mmap private not fixed
- mmap private fixed at somewhere currently unmapped
- mmap private fixed at somewhere already mapped
- mmap shared not fixed
- mmap shared fixed at somewhere currently unmapped
- mmap shared fixed at somewhere already mapped
- For private mappings, we should verify that changes cannot be read()
- back from the file, nor mmap's back from the file at a different
- address. (There have been systems where private was not correctly
- implemented like the infamous i386 svr4.0, and systems where the
- VM page cache was not coherent with the file system buffer cache
- like early versions of FreeBSD and possibly contemporary NetBSD.)
- For shared mappings, we should conversely verify that changes get
- propagated back to all the places they're supposed to be.
-
- Grep wants private fixed already mapped.
- The main things grep needs to know about mmap are:
- * does it exist and is it safe to write into the mmap'd area
- * how to use it (BSD variants) */
-
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H
-char *malloc ();
-#endif
-
-/* This mess was copied from the GNU getpagesize.h. */
-#ifndef HAVE_GETPAGESIZE
-/* Assume that all systems that can run configure have sys/param.h. */
-# ifndef HAVE_SYS_PARAM_H
-# define HAVE_SYS_PARAM_H 1
-# endif
-
-# ifdef _SC_PAGESIZE
-# define getpagesize() sysconf(_SC_PAGESIZE)
-# else /* no _SC_PAGESIZE */
-# ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-# ifdef EXEC_PAGESIZE
-# define getpagesize() EXEC_PAGESIZE
-# else /* no EXEC_PAGESIZE */
-# ifdef NBPG
-# define getpagesize() NBPG * CLSIZE
-# ifndef CLSIZE
-# define CLSIZE 1
-# endif /* no CLSIZE */
-# else /* no NBPG */
-# ifdef NBPC
-# define getpagesize() NBPC
-# else /* no NBPC */
-# ifdef PAGESIZE
-# define getpagesize() PAGESIZE
-# endif /* PAGESIZE */
-# endif /* no NBPC */
-# endif /* no NBPG */
-# endif /* no EXEC_PAGESIZE */
-# else /* no HAVE_SYS_PARAM_H */
-# define getpagesize() 8192 /* punt totally */
-# endif /* no HAVE_SYS_PARAM_H */
-# endif /* no _SC_PAGESIZE */
-
-#endif /* no HAVE_GETPAGESIZE */
-
-int
-main ()
-{
- char *data, *data2, *data3;
- int i, pagesize;
- int fd;
-
- pagesize = getpagesize ();
-
- /* First, make a file with some known garbage in it. */
- data = (char *) malloc (pagesize);
- if (!data)
- return 1;
- for (i = 0; i < pagesize; ++i)
- *(data + i) = rand ();
- umask (0);
- fd = creat ("conftest.mmap", 0600);
- if (fd < 0)
- return 1;
- if (write (fd, data, pagesize) != pagesize)
- return 1;
- close (fd);
-
- /* Next, try to mmap the file at a fixed address which already has
- something else allocated at it. If we can, also make sure that
- we see the same garbage. */
- fd = open ("conftest.mmap", O_RDWR);
- if (fd < 0)
- return 1;
- data2 = (char *) malloc (2 * pagesize);
- if (!data2)
- return 1;
- data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1);
- if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_FIXED, fd, 0L))
- return 1;
- for (i = 0; i < pagesize; ++i)
- if (*(data + i) != *(data2 + i))
- return 1;
-
- /* Finally, make sure that changes to the mapped area do not
- percolate back to the file as seen by read(). (This is a bug on
- some variants of i386 svr4.0.) */
- for (i = 0; i < pagesize; ++i)
- *(data2 + i) = *(data2 + i) + 1;
- data3 = (char *) malloc (pagesize);
- if (!data3)
- return 1;
- if (read (fd, data3, pagesize) != pagesize)
- return 1;
- for (i = 0; i < pagesize; ++i)
- if (*(data + i) != *(data3 + i))
- return 1;
- close (fd);
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_mmap_fixed_mapped=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_mmap_fixed_mapped=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
-echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6; }
-if test $ac_cv_func_mmap_fixed_mapped = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MMAP 1
-_ACEOF
-
-fi
-rm -f conftest.mmap
-
-
-
-for ac_header in sys/select.h sys/socket.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-{ echo "$as_me:$LINENO: checking types of arguments for select" >&5
-echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6; }
-if test "${ac_cv_func_select_args+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- for ac_arg234 in 'fd_set *' 'int *' 'void *'; do
- for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do
- for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-
-int
-main ()
-{
-extern int select ($ac_arg1,
- $ac_arg234, $ac_arg234, $ac_arg234,
- $ac_arg5);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- done
- done
-done
-# Provide a safe default value.
-: ${ac_cv_func_select_args='int,int *,struct timeval *'}
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5
-echo "${ECHO_T}$ac_cv_func_select_args" >&6; }
-ac_save_IFS=$IFS; IFS=','
-set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'`
-IFS=$ac_save_IFS
-shift
-
-cat >>confdefs.h <<_ACEOF
-#define SELECT_TYPE_ARG1 $1
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define SELECT_TYPE_ARG234 ($2)
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define SELECT_TYPE_ARG5 ($3)
-_ACEOF
-
-rm -f conftest*
-
-{ echo "$as_me:$LINENO: checking for function prototypes" >&5
-echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6; }
-if test "$ac_cv_prog_cc_c89" != no; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define PROTOTYPES 1
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define __PROTOTYPES 1
-_ACEOF
-
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-{ echo "$as_me:$LINENO: checking whether setvbuf arguments are reversed" >&5
-echo $ECHO_N "checking whether setvbuf arguments are reversed... $ECHO_C" >&6; }
-if test "${ac_cv_func_setvbuf_reversed+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_func_setvbuf_reversed=no
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdio.h>
-# ifdef PROTOTYPES
- int (setvbuf) (FILE *, int, char *, size_t);
-# endif
-int
-main ()
-{
-char buf; return setvbuf (stdout, _IOLBF, &buf, 1);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdio.h>
-# ifdef PROTOTYPES
- int (setvbuf) (FILE *, int, char *, size_t);
-# endif
-int
-main ()
-{
-char buf; return setvbuf (stdout, &buf, _IOLBF, 1);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- # It compiles and links either way, so it must not be declared
- # with a prototype and most likely this is a K&R C compiler.
- # Try running it.
- if test "$cross_compiling" = yes; then
- : # Assume setvbuf is not reversed when cross-compiling.
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-/* This call has the arguments reversed.
- A reversed system may check and see that the address of buf
- is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */
- char buf;
- if (setvbuf (stdout, _IOLBF, &buf, 1) != 0)
- return 1;
- putchar ('\r');
- return 0; /* Non-reversed systems SEGV here. */
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_setvbuf_reversed=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
- ac_cv_func_setvbuf_reversed=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_setvbuf_reversed" >&5
-echo "${ECHO_T}$ac_cv_func_setvbuf_reversed" >&6; }
-if test $ac_cv_func_setvbuf_reversed = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SETVBUF_REVERSED 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5
-echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; }
-if test "${ac_cv_type_signal+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <signal.h>
-
-int
-main ()
-{
-return *(signal (0, 0)) (0) == 1;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_signal=int
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_signal=void
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
-echo "${ECHO_T}$ac_cv_type_signal" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define RETSIGTYPE $ac_cv_type_signal
-_ACEOF
-
-
-{ echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5
-echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6; }
-if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- rm -f conftest.sym conftest.file
-echo >conftest.file
-if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
- if test "$cross_compiling" = yes; then
- ac_cv_func_lstat_dereferences_slashed_symlink=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-struct stat sbuf;
- /* Linux will dereference the symlink and fail.
- That is better in the sense that it means we will not
- have to compile and use the lstat wrapper. */
- return lstat ("conftest.sym/", &sbuf) == 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_lstat_dereferences_slashed_symlink=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_lstat_dereferences_slashed_symlink=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-else
- # If the `ln -s' command failed, then we probably don't even
- # have an lstat function.
- ac_cv_func_lstat_dereferences_slashed_symlink=no
-fi
-rm -f conftest.sym conftest.file
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
-echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; }
-
-test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
-
-cat >>confdefs.h <<_ACEOF
-#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
-_ACEOF
-
-
-if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
- case " $LIBOBJS " in
- *" lstat.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS lstat.$ac_objext"
- ;;
-esac
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5
-echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6; }
-if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_stat_empty_string_bug=yes
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-struct stat sbuf;
- return stat ("", &sbuf) == 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_stat_empty_string_bug=no
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_stat_empty_string_bug=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5
-echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6; }
-if test $ac_cv_func_stat_empty_string_bug = yes; then
- case " $LIBOBJS " in
- *" stat.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS stat.$ac_objext"
- ;;
-esac
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STAT_EMPTY_STRING_BUG 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for working strcoll" >&5
-echo $ECHO_N "checking for working strcoll... $ECHO_C" >&6; }
-if test "${ac_cv_func_strcoll_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_strcoll_works=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-return (strcoll ("abc", "def") >= 0 ||
- strcoll ("ABC", "DEF") >= 0 ||
- strcoll ("123", "456") >= 0)
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strcoll_works=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_strcoll_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_strcoll_works" >&5
-echo "${ECHO_T}$ac_cv_func_strcoll_works" >&6; }
-if test $ac_cv_func_strcoll_works = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRCOLL 1
-_ACEOF
-
-fi
-
-
-for ac_func in strftime
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-else
- # strftime is in -lintl on SCO UNIX.
-{ echo "$as_me:$LINENO: checking for strftime in -lintl" >&5
-echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_intl_strftime+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lintl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char strftime ();
-int
-main ()
-{
-return strftime ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_intl_strftime=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_intl_strftime=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5
-echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6; }
-if test $ac_cv_lib_intl_strftime = yes; then
- cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRFTIME 1
-_ACEOF
-
-LIBS="-lintl $LIBS"
-fi
-
-fi
-done
-
-{ echo "$as_me:$LINENO: checking for working strnlen" >&5
-echo $ECHO_N "checking for working strnlen... $ECHO_C" >&6; }
-if test "${ac_cv_func_strnlen_working+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_strnlen_working=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
-#define S "foobar"
-#define S_LEN (sizeof S - 1)
-
- /* At least one implementation is buggy: that of AIX 4.3 would
- give strnlen (S, 1) == 3. */
-
- int i;
- for (i = 0; i < S_LEN + 1; ++i)
- {
- int expected = i <= S_LEN ? i : S_LEN;
- if (strnlen (S, i) != expected)
- return 1;
- }
- return 0;
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strnlen_working=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_strnlen_working=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_strnlen_working" >&5
-echo "${ECHO_T}$ac_cv_func_strnlen_working" >&6; }
-test $ac_cv_func_strnlen_working = no && case " $LIBOBJS " in
- *" strnlen.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strnlen.$ac_objext"
- ;;
-esac
-
-
-{ echo "$as_me:$LINENO: checking for working strtod" >&5
-echo $ECHO_N "checking for working strtod... $ECHO_C" >&6; }
-if test "${ac_cv_func_strtod+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_strtod=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-$ac_includes_default
-#ifndef strtod
-double strtod ();
-#endif
-int
-main()
-{
- {
- /* Some versions of Linux strtod mis-parse strings with leading '+'. */
- char *string = " +69";
- char *term;
- double value;
- value = strtod (string, &term);
- if (value != 69 || term != (string + 4))
- return 1;
- }
-
- {
- /* Under Solaris 2.4, strtod returns the wrong value for the
- terminating character under some conditions. */
- char *string = "NaN";
- char *term;
- strtod (string, &term);
- if (term != string && *(term - 1) == 0)
- return 1;
- }
- return 0;
-}
-
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strtod=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_strtod=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5
-echo "${ECHO_T}$ac_cv_func_strtod" >&6; }
-if test $ac_cv_func_strtod = no; then
- case " $LIBOBJS " in
- *" strtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strtod.$ac_objext"
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking for pow" >&5
-echo $ECHO_N "checking for pow... $ECHO_C" >&6; }
-if test "${ac_cv_func_pow+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define pow to an innocuous variant, in case <limits.h> declares pow.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define pow innocuous_pow
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char pow (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef pow
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pow ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_pow || defined __stub___pow
-choke me
-#endif
-
-int
-main ()
-{
-return pow ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_func_pow=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_pow=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_pow" >&5
-echo "${ECHO_T}$ac_cv_func_pow" >&6; }
-
-if test $ac_cv_func_pow = no; then
- { echo "$as_me:$LINENO: checking for pow in -lm" >&5
-echo $ECHO_N "checking for pow in -lm... $ECHO_C" >&6; }
-if test "${ac_cv_lib_m_pow+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pow ();
-int
-main ()
-{
-return pow ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_m_pow=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_m_pow=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_pow" >&5
-echo "${ECHO_T}$ac_cv_lib_m_pow" >&6; }
-if test $ac_cv_lib_m_pow = yes; then
- POW_LIB=-lm
-else
- { echo "$as_me:$LINENO: WARNING: cannot find library containing definition of pow" >&5
-echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;}
-fi
-
-fi
-
-fi
-
-
-
-
-
-for ac_header in $ac_header_list
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-
-
-
-
-
-
-{ echo "$as_me:$LINENO: checking whether utime accepts a null argument" >&5
-echo $ECHO_N "checking whether utime accepts a null argument... $ECHO_C" >&6; }
-if test "${ac_cv_func_utime_null+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- rm -f conftest.data; >conftest.data
-# Sequent interprets utime(file, 0) to mean use start of epoch. Wrong.
-if test "$cross_compiling" = yes; then
- ac_cv_func_utime_null=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- #ifdef HAVE_UTIME_H
- # include <utime.h>
- #endif
-int
-main ()
-{
-struct stat s, t;
- return ! (stat ("conftest.data", &s) == 0
- && utime ("conftest.data", 0) == 0
- && stat ("conftest.data", &t) == 0
- && t.st_mtime >= s.st_mtime
- && t.st_mtime - s.st_mtime < 120);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_utime_null=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_utime_null=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_utime_null" >&5
-echo "${ECHO_T}$ac_cv_func_utime_null" >&6; }
-if test $ac_cv_func_utime_null = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_UTIME_NULL 1
-_ACEOF
-
-fi
-rm -f conftest.data
-
-
-for ac_func in vprintf
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-{ echo "$as_me:$LINENO: checking for _doprnt" >&5
-echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; }
-if test "${ac_cv_func__doprnt+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define _doprnt innocuous__doprnt
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char _doprnt (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef _doprnt
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char _doprnt ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub__doprnt || defined __stub____doprnt
-choke me
-#endif
-
-int
-main ()
-{
-return _doprnt ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_func__doprnt=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func__doprnt=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
-echo "${ECHO_T}$ac_cv_func__doprnt" >&6; }
-if test $ac_cv_func__doprnt = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_DOPRNT 1
-_ACEOF
-
-fi
-
-fi
-done
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-for ac_func in asprintf atexit bzero dup2 endpwent floor ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday inet_ntoa isascii localtime_r memchr memmove memset mkdir munmap pow putenv re_comp regcomp rint select setenv socket sqrt strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtol strtoq unsetenv utime vasprintf
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-# some systems already have gethostbyname_r so we don't need to build ours in main/utils.c
-{ echo "$as_me:$LINENO: checking for library containing gethostbyname_r" >&5
-echo $ECHO_N "checking for library containing gethostbyname_r... $ECHO_C" >&6; }
-if test "${ac_cv_search_gethostbyname_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gethostbyname_r ();
-int
-main ()
-{
-return gethostbyname_r ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' socket nsl; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_search_gethostbyname_r=$ac_res
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext
- if test "${ac_cv_search_gethostbyname_r+set}" = set; then
- break
-fi
-done
-if test "${ac_cv_search_gethostbyname_r+set}" = set; then
- :
-else
- ac_cv_search_gethostbyname_r=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname_r" >&5
-echo "${ECHO_T}$ac_cv_search_gethostbyname_r" >&6; }
-ac_res=$ac_cv_search_gethostbyname_r
-if test "$ac_res" != no; then
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-
-{ echo "$as_me:$LINENO: checking for gethostbyname_r with 6 arguments" >&5
-echo $ECHO_N "checking for gethostbyname_r with 6 arguments... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
- #include <netdb.h>
-int
-main ()
-{
-struct hostent *he = gethostbyname_r((const char *)NULL, (struct hostent *)NULL, (char *)NULL, (int)0, (struct hostent **)NULL, (int *)NULL);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYNAME_R_6 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-{ echo "$as_me:$LINENO: checking for gethostbyname_r with 5 arguments" >&5
-echo $ECHO_N "checking for gethostbyname_r with 5 arguments... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
- #include <netdb.h>
-int
-main ()
-{
-struct hostent *he = gethostbyname_r((const char *)NULL, (struct hostent *)NULL, (char *)NULL, (int)0, (int *)NULL);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYNAME_R_5 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-{ echo "$as_me:$LINENO: checking for PTHREAD_RWLOCK_INITIALIZER" >&5
-echo $ECHO_N "checking for PTHREAD_RWLOCK_INITIALIZER... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <pthread.h>
-int
-main ()
-{
-int foo = PTHREAD_RWLOCK_INITIALIZER;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_PTHREAD_RWLOCK_INITIALIZER 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-{ echo "$as_me:$LINENO: checking for PTHREAD_RWLOCK_PREFER_WRITER_NP" >&5
-echo $ECHO_N "checking for PTHREAD_RWLOCK_PREFER_WRITER_NP... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <pthread.h>
-int
-main ()
-{
-int foo = PTHREAD_RWLOCK_PREFER_WRITER_NP;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-{ echo "$as_me:$LINENO: checking for compiler atomic operations" >&5
-echo $ECHO_N "checking for compiler atomic operations... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-int foo1; int foo2 = __sync_fetch_and_add(&foo1, 1);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GCC_ATOMICS 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-
-{ echo "$as_me:$LINENO: checking for compiler 'attribute pure' support" >&5
-echo $ECHO_N "checking for compiler 'attribute pure' support... $ECHO_C" >&6; }
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-static void __attribute__((pure)) *test(void *muffin, ...) {}
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ATTRIBUTE_pure 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CFLAGS="$saved_CFLAGS"
-
-
-{ echo "$as_me:$LINENO: checking for compiler 'attribute malloc' support" >&5
-echo $ECHO_N "checking for compiler 'attribute malloc' support... $ECHO_C" >&6; }
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-static void __attribute__((malloc)) *test(void *muffin, ...) {}
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ATTRIBUTE_malloc 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CFLAGS="$saved_CFLAGS"
-
-
-{ echo "$as_me:$LINENO: checking for compiler 'attribute const' support" >&5
-echo $ECHO_N "checking for compiler 'attribute const' support... $ECHO_C" >&6; }
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-static void __attribute__((const)) *test(void *muffin, ...) {}
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ATTRIBUTE_const 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CFLAGS="$saved_CFLAGS"
-
-
-{ echo "$as_me:$LINENO: checking for compiler 'attribute unused' support" >&5
-echo $ECHO_N "checking for compiler 'attribute unused' support... $ECHO_C" >&6; }
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-static void __attribute__((unused)) *test(void *muffin, ...) {}
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ATTRIBUTE_unused 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CFLAGS="$saved_CFLAGS"
-
-
-{ echo "$as_me:$LINENO: checking for compiler 'attribute always_inline' support" >&5
-echo $ECHO_N "checking for compiler 'attribute always_inline' support... $ECHO_C" >&6; }
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-static void __attribute__((always_inline)) *test(void *muffin, ...) {}
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ATTRIBUTE_always_inline 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CFLAGS="$saved_CFLAGS"
-
-
-{ echo "$as_me:$LINENO: checking for compiler 'attribute deprecated' support" >&5
-echo $ECHO_N "checking for compiler 'attribute deprecated' support... $ECHO_C" >&6; }
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Werror"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-static void __attribute__((deprecated)) *test(void *muffin, ...) {}
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ATTRIBUTE_deprecated 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CFLAGS="$saved_CFLAGS"
-
-
-{ echo "$as_me:$LINENO: checking for -ffunction-sections support" >&5
-echo $ECHO_N "checking for -ffunction-sections support... $ECHO_C" >&6; }
-saved_CFLAGS="${CFLAGS}"
-CFLAGS="${CFLAGS} -ffunction-sections"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-int x = 1;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- saved_LDFLAGS="${LDFLAGS}"
- LDFLAGS="${LDFLAGS} -Wl,--gc-sections"
- { echo "$as_me:$LINENO: checking for --gc-sections support" >&5
-echo $ECHO_N "checking for --gc-sections support... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-int x = 1;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- GC_CFLAGS="-ffunction-sections"
- GC_LDFLAGS="-Wl,--gc-sections"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="${saved_LDFLAGS}"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-CFLAGS="${saved_CFLAGS}"
-
-
-
-{ echo "$as_me:$LINENO: checking for -Wdeclaration-after-statement support" >&5
-echo $ECHO_N "checking for -Wdeclaration-after-statement support... $ECHO_C" >&6; }
-if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- AST_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- AST_DECLARATION_AFTER_STATEMENT=
-fi
-
-
-{ echo "$as_me:$LINENO: checking for -fno-strict-overflow" >&5
-echo $ECHO_N "checking for -fno-strict-overflow... $ECHO_C" >&6; }
-if $(${CC} -O2 -fno-strict-overflow -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- AST_NO_STRICT_OVERFLOW=-fno-strict-overflow
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- AST_NO_STRICT_OVERFLOW=
-fi
-
-
-{ echo "$as_me:$LINENO: checking for res_ninit" >&5
-echo $ECHO_N "checking for res_ninit... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <resolv.h>
-int
-main ()
-{
-int foo = res_ninit(NULL);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_RES_NINIT 1
-_ACEOF
-
- { echo "$as_me:$LINENO: checking for res_ndestroy" >&5
-echo $ECHO_N "checking for res_ndestroy... $ECHO_C" >&6; }
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <resolv.h>
-int
-main ()
-{
-int foo = res_ndestroy(NULL);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_RES_NDESTROY 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-{ echo "$as_me:$LINENO: checking for RTLD_NOLOAD" >&5
-echo $ECHO_N "checking for RTLD_NOLOAD... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <dlfcn.h>
-int
-main ()
-{
-int foo = RTLD_NOLOAD;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_RTLD_NOLOAD 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-{ echo "$as_me:$LINENO: checking for IP_MTU_DISCOVER" >&5
-echo $ECHO_N "checking for IP_MTU_DISCOVER... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <netinet/in.h>
-int
-main ()
-{
-int foo = IP_MTU_DISCOVER;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_IP_MTU_DISCOVER 1
-_ACEOF
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
-if test "${ac_cv_header_libkern_OSAtomic_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for libkern/OSAtomic.h" >&5
-echo $ECHO_N "checking for libkern/OSAtomic.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libkern_OSAtomic_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libkern_OSAtomic_h" >&5
-echo "${ECHO_T}$ac_cv_header_libkern_OSAtomic_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking libkern/OSAtomic.h usability" >&5
-echo $ECHO_N "checking libkern/OSAtomic.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <libkern/OSAtomic.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking libkern/OSAtomic.h presence" >&5
-echo $ECHO_N "checking libkern/OSAtomic.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <libkern/OSAtomic.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: libkern/OSAtomic.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: libkern/OSAtomic.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for libkern/OSAtomic.h" >&5
-echo $ECHO_N "checking for libkern/OSAtomic.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libkern_OSAtomic_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_libkern_OSAtomic_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libkern_OSAtomic_h" >&5
-echo "${ECHO_T}$ac_cv_header_libkern_OSAtomic_h" >&6; }
-
-fi
-if test $ac_cv_header_libkern_OSAtomic_h = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OSX_ATOMICS 1
-_ACEOF
-
-fi
-
-
-
-{ echo "$as_me:$LINENO: checking for int" >&5
-echo $ECHO_N "checking for int... $ECHO_C" >&6; }
-if test "${ac_cv_type_int+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-typedef int ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_type_int=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_int=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
-echo "${ECHO_T}$ac_cv_type_int" >&6; }
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ echo "$as_me:$LINENO: checking size of int" >&5
-echo $ECHO_N "checking size of int... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_int+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- # Depending upon the size, compute the lo and hi bounds.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_lo=0 ac_mid=0
- while :; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_hi=$ac_mid; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_lo=`expr $ac_mid + 1`
- if test $ac_lo -le $ac_mid; then
- ac_lo= ac_hi=
- break
- fi
- ac_mid=`expr 2 '*' $ac_mid + 1`
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_hi=-1 ac_mid=-1
- while :; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_lo=$ac_mid; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_hi=`expr '(' $ac_mid ')' - 1`
- if test $ac_mid -le $ac_hi; then
- ac_lo= ac_hi=
- break
- fi
- ac_mid=`expr 2 '*' $ac_mid`
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_lo= ac_hi=
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
- ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- typedef int ac__type_sizeof_;
-int
-main ()
-{
-static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_hi=$ac_mid
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_lo=`expr '(' $ac_mid ')' + 1`
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-case $ac_lo in
-?*) ac_cv_sizeof_int=$ac_lo;;
-'') if test "$ac_cv_type_int" = yes; then
- { { echo "$as_me:$LINENO: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
- else
- ac_cv_sizeof_int=0
- fi ;;
-esac
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
- typedef int ac__type_sizeof_;
-static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
-static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
-
- FILE *f = fopen ("conftest.val", "w");
- if (! f)
- return 1;
- if (((long int) (sizeof (ac__type_sizeof_))) < 0)
- {
- long int i = longval ();
- if (i != ((long int) (sizeof (ac__type_sizeof_))))
- return 1;
- fprintf (f, "%ld\n", i);
- }
- else
- {
- unsigned long int i = ulongval ();
- if (i != ((long int) (sizeof (ac__type_sizeof_))))
- return 1;
- fprintf (f, "%lu\n", i);
- }
- return ferror (f) || fclose (f) != 0;
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sizeof_int=`cat conftest.val`
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-if test "$ac_cv_type_int" = yes; then
- { { echo "$as_me:$LINENO: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int)
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
- else
- ac_cv_sizeof_int=0
- fi
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f conftest.val
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
-echo "${ECHO_T}$ac_cv_sizeof_int" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-_ACEOF
-
-
-
-# do the package library checks now
-
-
-if test "${USE_ALSA}" != "no"; then
- pbxlibdir=""
- if test "x${ALSA_DIR}" != "x"; then
- if test -d ${ALSA_DIR}/lib; then
- pbxlibdir="-L${ALSA_DIR}/lib"
- else
- pbxlibdir="-L${ALSA_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for snd_spcm_init in -lasound" >&5
-echo $ECHO_N "checking for snd_spcm_init in -lasound... $ECHO_C" >&6; }
-if test "${ac_cv_lib_asound_snd_spcm_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lasound ${pbxlibdir} -lm -ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char snd_spcm_init ();
-int
-main ()
-{
-return snd_spcm_init ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_asound_snd_spcm_init=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_asound_snd_spcm_init=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_asound_snd_spcm_init" >&5
-echo "${ECHO_T}$ac_cv_lib_asound_snd_spcm_init" >&6; }
-if test $ac_cv_lib_asound_snd_spcm_init = yes; then
- AST_ALSA_FOUND=yes
-else
- AST_ALSA_FOUND=no
-fi
-
-
- if test "${AST_ALSA_FOUND}" = "yes"; then
- ALSA_LIB="-lasound -lm -ldl"
- ALSA_HEADER_FOUND="1"
- if test "x${ALSA_DIR}" != "x"; then
- ALSA_LIB="${pbxlibdir} ${ALSA_LIB}"
- ALSA_INCLUDE="-I${ALSA_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${ALSA_DIR}/include"
- if test "xalsa/asoundlib.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${ALSA_DIR}/include/alsa/asoundlib.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${ALSA_DIR}/include/alsa/asoundlib.h" >&5
-echo $ECHO_N "checking for ${ALSA_DIR}/include/alsa/asoundlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${ALSA_DIR}/include/alsa/asoundlib.h usability" >&5
-echo $ECHO_N "checking ${ALSA_DIR}/include/alsa/asoundlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${ALSA_DIR}/include/alsa/asoundlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${ALSA_DIR}/include/alsa/asoundlib.h presence" >&5
-echo $ECHO_N "checking ${ALSA_DIR}/include/alsa/asoundlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${ALSA_DIR}/include/alsa/asoundlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${ALSA_DIR}/include/alsa/asoundlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${ALSA_DIR}/include/alsa/asoundlib.h" >&5
-echo $ECHO_N "checking for ${ALSA_DIR}/include/alsa/asoundlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- ALSA_HEADER_FOUND=1
-else
- ALSA_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xalsa/asoundlib.h" != "x" ; then
- if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5
-echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking alsa/asoundlib.h usability" >&5
-echo $ECHO_N "checking alsa/asoundlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <alsa/asoundlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking alsa/asoundlib.h presence" >&5
-echo $ECHO_N "checking alsa/asoundlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <alsa/asoundlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5
-echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_alsa_asoundlib_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6; }
-
-fi
-if test $ac_cv_header_alsa_asoundlib_h = yes; then
- ALSA_HEADER_FOUND=1
-else
- ALSA_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${ALSA_HEADER_FOUND}" = "x0" ; then
- if test -n "${ALSA_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the asound development package installed." >&5
-echo "$as_me: *** It appears that you do not have the asound development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${ALSA_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${ALSA_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${ALSA_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${ALSA_OPTION}" >&6;}
- exit 1
- fi
- ALSA_LIB=""
- ALSA_INCLUDE=""
- PBX_ALSA=0
- else
- PBX_ALSA=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ALSA 1
-_ACEOF
-
- fi
- elif test -n "${ALSA_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${ALSA_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${ALSA_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${ALSA_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${ALSA_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_CURSES}" != "no"; then
- pbxlibdir=""
- if test "x${CURSES_DIR}" != "x"; then
- if test -d ${CURSES_DIR}/lib; then
- pbxlibdir="-L${CURSES_DIR}/lib"
- else
- pbxlibdir="-L${CURSES_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for initscr in -lcurses" >&5
-echo $ECHO_N "checking for initscr in -lcurses... $ECHO_C" >&6; }
-if test "${ac_cv_lib_curses_initscr+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcurses ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char initscr ();
-int
-main ()
-{
-return initscr ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_curses_initscr=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_curses_initscr=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_curses_initscr" >&5
-echo "${ECHO_T}$ac_cv_lib_curses_initscr" >&6; }
-if test $ac_cv_lib_curses_initscr = yes; then
- AST_CURSES_FOUND=yes
-else
- AST_CURSES_FOUND=no
-fi
-
-
- if test "${AST_CURSES_FOUND}" = "yes"; then
- CURSES_LIB="-lcurses "
- CURSES_HEADER_FOUND="1"
- if test "x${CURSES_DIR}" != "x"; then
- CURSES_LIB="${pbxlibdir} ${CURSES_LIB}"
- CURSES_INCLUDE="-I${CURSES_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${CURSES_DIR}/include"
- if test "xcurses.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${CURSES_DIR}/include/curses.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${CURSES_DIR}/include/curses.h" >&5
-echo $ECHO_N "checking for ${CURSES_DIR}/include/curses.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${CURSES_DIR}/include/curses.h usability" >&5
-echo $ECHO_N "checking ${CURSES_DIR}/include/curses.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${CURSES_DIR}/include/curses.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${CURSES_DIR}/include/curses.h presence" >&5
-echo $ECHO_N "checking ${CURSES_DIR}/include/curses.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${CURSES_DIR}/include/curses.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CURSES_DIR}/include/curses.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${CURSES_DIR}/include/curses.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${CURSES_DIR}/include/curses.h" >&5
-echo $ECHO_N "checking for ${CURSES_DIR}/include/curses.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- CURSES_HEADER_FOUND=1
-else
- CURSES_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xcurses.h" != "x" ; then
- if test "${ac_cv_header_curses_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for curses.h" >&5
-echo $ECHO_N "checking for curses.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_curses_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_curses_h" >&5
-echo "${ECHO_T}$ac_cv_header_curses_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking curses.h usability" >&5
-echo $ECHO_N "checking curses.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <curses.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking curses.h presence" >&5
-echo $ECHO_N "checking curses.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <curses.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: curses.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: curses.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: curses.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: curses.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: curses.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: curses.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: curses.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: curses.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: curses.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: curses.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for curses.h" >&5
-echo $ECHO_N "checking for curses.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_curses_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_curses_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_curses_h" >&5
-echo "${ECHO_T}$ac_cv_header_curses_h" >&6; }
-
-fi
-if test $ac_cv_header_curses_h = yes; then
- CURSES_HEADER_FOUND=1
-else
- CURSES_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${CURSES_HEADER_FOUND}" = "x0" ; then
- if test -n "${CURSES_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the curses development package installed." >&5
-echo "$as_me: *** It appears that you do not have the curses development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${CURSES_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${CURSES_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${CURSES_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${CURSES_OPTION}" >&6;}
- exit 1
- fi
- CURSES_LIB=""
- CURSES_INCLUDE=""
- PBX_CURSES=0
- else
- PBX_CURSES=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_CURSES 1
-_ACEOF
-
- fi
- elif test -n "${CURSES_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${CURSES_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${CURSES_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${CURSES_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${CURSES_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "x${host_os}" = "xlinux-gnu" ; then
-
-if test "${USE_CAP}" != "no"; then
- pbxlibdir=""
- if test "x${CAP_DIR}" != "x"; then
- if test -d ${CAP_DIR}/lib; then
- pbxlibdir="-L${CAP_DIR}/lib"
- else
- pbxlibdir="-L${CAP_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for cap_from_text in -lcap" >&5
-echo $ECHO_N "checking for cap_from_text in -lcap... $ECHO_C" >&6; }
-if test "${ac_cv_lib_cap_cap_from_text+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcap ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char cap_from_text ();
-int
-main ()
-{
-return cap_from_text ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_cap_cap_from_text=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_cap_cap_from_text=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_cap_cap_from_text" >&5
-echo "${ECHO_T}$ac_cv_lib_cap_cap_from_text" >&6; }
-if test $ac_cv_lib_cap_cap_from_text = yes; then
- AST_CAP_FOUND=yes
-else
- AST_CAP_FOUND=no
-fi
-
-
- if test "${AST_CAP_FOUND}" = "yes"; then
- CAP_LIB="-lcap "
- CAP_HEADER_FOUND="1"
- if test "x${CAP_DIR}" != "x"; then
- CAP_LIB="${pbxlibdir} ${CAP_LIB}"
- CAP_INCLUDE="-I${CAP_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${CAP_DIR}/include"
- if test "xsys/capability.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${CAP_DIR}/include/sys/capability.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${CAP_DIR}/include/sys/capability.h" >&5
-echo $ECHO_N "checking for ${CAP_DIR}/include/sys/capability.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${CAP_DIR}/include/sys/capability.h usability" >&5
-echo $ECHO_N "checking ${CAP_DIR}/include/sys/capability.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${CAP_DIR}/include/sys/capability.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${CAP_DIR}/include/sys/capability.h presence" >&5
-echo $ECHO_N "checking ${CAP_DIR}/include/sys/capability.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${CAP_DIR}/include/sys/capability.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${CAP_DIR}/include/sys/capability.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${CAP_DIR}/include/sys/capability.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${CAP_DIR}/include/sys/capability.h" >&5
-echo $ECHO_N "checking for ${CAP_DIR}/include/sys/capability.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- CAP_HEADER_FOUND=1
-else
- CAP_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xsys/capability.h" != "x" ; then
- if test "${ac_cv_header_sys_capability_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for sys/capability.h" >&5
-echo $ECHO_N "checking for sys/capability.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sys_capability_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_capability_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_capability_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking sys/capability.h usability" >&5
-echo $ECHO_N "checking sys/capability.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sys/capability.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking sys/capability.h presence" >&5
-echo $ECHO_N "checking sys/capability.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/capability.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sys/capability.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sys/capability.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sys/capability.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sys/capability.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sys/capability.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sys/capability.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sys/capability.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/capability.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sys/capability.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for sys/capability.h" >&5
-echo $ECHO_N "checking for sys/capability.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sys_capability_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sys_capability_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_capability_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_capability_h" >&6; }
-
-fi
-if test $ac_cv_header_sys_capability_h = yes; then
- CAP_HEADER_FOUND=1
-else
- CAP_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${CAP_HEADER_FOUND}" = "x0" ; then
- if test -n "${CAP_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the cap development package installed." >&5
-echo "$as_me: *** It appears that you do not have the cap development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${CAP_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${CAP_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${CAP_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${CAP_OPTION}" >&6;}
- exit 1
- fi
- CAP_LIB=""
- CAP_INCLUDE=""
- PBX_CAP=0
- else
- PBX_CAP=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_CAP 1
-_ACEOF
-
- fi
- elif test -n "${CAP_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${CAP_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${CAP_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${CAP_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${CAP_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-fi
-
-
- if test "x${PBX_GETIFADDRS}" != "x1" -a "${USE_GETIFADDRS}" != "no"; then
- { echo "$as_me:$LINENO: checking if \"struct ifaddrs *p; getifaddrs(&p)\" compiles using ifaddrs.h" >&5
-echo $ECHO_N "checking if \"struct ifaddrs *p; getifaddrs(&p)\" compiles using ifaddrs.h... $ECHO_C" >&6; }
- saved_cppflags="${CPPFLAGS}"
- if test "x${GETIFADDRS_DIR}" != "x"; then
- GETIFADDRS_INCLUDE="-I${GETIFADDRS_DIR}/include"
- fi
- CPPFLAGS="${CPPFLAGS} ${GETIFADDRS_INCLUDE}"
-
- cat >conftest.$ac_ext <<_ACEOF
- /* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ifaddrs.h>
-int
-main ()
-{
- struct ifaddrs *p; getifaddrs(&p);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- PBX_GETIFADDRS=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETIFADDRS 1
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETIFADDRS_VERSION
-_ACEOF
-
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CPPFLAGS="${saved_cppflags}"
- fi
-
-
-GSM_INTERNAL="yes"
-
-GSM_SYSTEM="yes"
-if test "${USE_GSM}" != "no"; then
- if test "${GSM_DIR}" = "internal"; then
- GSM_SYSTEM="no"
- elif test "${GSM_DIR}" != ""; then
- GSM_INTERNAL="no"
- fi
- if test "${GSM_SYSTEM}" = "yes"; then
- gsmlibdir=""
- if test "x${GSM_DIR}" != "x"; then
- if test -d ${GSM_DIR}/lib; then
- gsmlibdir="-L${GSM_DIR}/lib"
- else
- gsmlibdir="-L${GSM_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for gsm_create in -lgsm" >&5
-echo $ECHO_N "checking for gsm_create in -lgsm... $ECHO_C" >&6; }
-if test "${ac_cv_lib_gsm_gsm_create+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lgsm ${gsmlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gsm_create ();
-int
-main ()
-{
-return gsm_create ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_gsm_gsm_create=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_gsm_gsm_create=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_gsm_gsm_create" >&5
-echo "${ECHO_T}$ac_cv_lib_gsm_gsm_create" >&6; }
-if test $ac_cv_lib_gsm_gsm_create = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GSM 1
-_ACEOF
-
-fi
-
- if test "${ac_cv_lib_gsm_gsm_create}" = "yes"; then
- if test "x${GSM_DIR}" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${GSM_DIR}/include/gsm.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${GSM_DIR}/include/gsm.h" >&5
-echo $ECHO_N "checking for ${GSM_DIR}/include/gsm.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${GSM_DIR}/include/gsm.h usability" >&5
-echo $ECHO_N "checking ${GSM_DIR}/include/gsm.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${GSM_DIR}/include/gsm.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${GSM_DIR}/include/gsm.h presence" >&5
-echo $ECHO_N "checking ${GSM_DIR}/include/gsm.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${GSM_DIR}/include/gsm.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${GSM_DIR}/include/gsm.h" >&5
-echo $ECHO_N "checking for ${GSM_DIR}/include/gsm.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- GSM_HEADER_FOUND=1
-else
- GSM_HEADER_FOUND=0
-fi
-
-
- as_ac_Header=`echo "ac_cv_header_${GSM_DIR}/include/gsm/gsm.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${GSM_DIR}/include/gsm/gsm.h" >&5
-echo $ECHO_N "checking for ${GSM_DIR}/include/gsm/gsm.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${GSM_DIR}/include/gsm/gsm.h usability" >&5
-echo $ECHO_N "checking ${GSM_DIR}/include/gsm/gsm.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${GSM_DIR}/include/gsm/gsm.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${GSM_DIR}/include/gsm/gsm.h presence" >&5
-echo $ECHO_N "checking ${GSM_DIR}/include/gsm/gsm.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${GSM_DIR}/include/gsm/gsm.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GSM_DIR}/include/gsm/gsm.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${GSM_DIR}/include/gsm/gsm.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${GSM_DIR}/include/gsm/gsm.h" >&5
-echo $ECHO_N "checking for ${GSM_DIR}/include/gsm/gsm.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- GSM_GSM_HEADER_FOUND=1
-else
- GSM_GSM_HEADER_FOUND=0
-fi
-
-
- else
- if test "${ac_cv_header_gsm_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for gsm.h" >&5
-echo $ECHO_N "checking for gsm.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_gsm_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_gsm_h" >&5
-echo "${ECHO_T}$ac_cv_header_gsm_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking gsm.h usability" >&5
-echo $ECHO_N "checking gsm.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <gsm.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking gsm.h presence" >&5
-echo $ECHO_N "checking gsm.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <gsm.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: gsm.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: gsm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: gsm.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: gsm.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: gsm.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: gsm.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: gsm.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: gsm.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: gsm.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: gsm.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for gsm.h" >&5
-echo $ECHO_N "checking for gsm.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_gsm_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_gsm_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_gsm_h" >&5
-echo "${ECHO_T}$ac_cv_header_gsm_h" >&6; }
-
-fi
-if test $ac_cv_header_gsm_h = yes; then
- GSM_HEADER_FOUND=1
-else
- GSM_HEADER_FOUND=0
-fi
-
-
- if test "${ac_cv_header_gsm_gsm_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for gsm/gsm.h" >&5
-echo $ECHO_N "checking for gsm/gsm.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_gsm_gsm_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_gsm_gsm_h" >&5
-echo "${ECHO_T}$ac_cv_header_gsm_gsm_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking gsm/gsm.h usability" >&5
-echo $ECHO_N "checking gsm/gsm.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <gsm/gsm.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking gsm/gsm.h presence" >&5
-echo $ECHO_N "checking gsm/gsm.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <gsm/gsm.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: gsm/gsm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: gsm/gsm.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: gsm/gsm.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: gsm/gsm.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: gsm/gsm.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: gsm/gsm.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: gsm/gsm.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: gsm/gsm.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: gsm/gsm.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for gsm/gsm.h" >&5
-echo $ECHO_N "checking for gsm/gsm.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_gsm_gsm_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_gsm_gsm_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_gsm_gsm_h" >&5
-echo "${ECHO_T}$ac_cv_header_gsm_gsm_h" >&6; }
-
-fi
-if test $ac_cv_header_gsm_gsm_h = yes; then
- GSM_GSM_HEADER_FOUND=1
-else
- GSM_GSM_HEADER_FOUND=0
-fi
-
-
- fi
- if test "${GSM_HEADER_FOUND}" = "0" ; then
- if test "{GSM_GSM_HEADER_FOUND}" = "0" ; then
- if test "x${GSM_MANDATORY}" = "xyes" ; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the gsm development package installed." >&5
-echo "$as_me: *** It appears that you do not have the gsm development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${GSM_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${GSM_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${GSM_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${GSM_OPTION}" >&6;}
- exit 1
- fi
- fi
- fi
- GSM_OK=0
- if test "${GSM_HEADER_FOUND}" = "1" ; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GSM_HEADER 1
-_ACEOF
-
- GSM_OK=1
- else
- if test "${GSM_GSM_HEADER_FOUND}" = "1" ; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GSM_GSM_HEADER 1
-_ACEOF
-
- GSM_OK=1
- fi
- fi
- if test "${GSM_OK}" = "1" ; then
- GSM_LIB="-lgsm"
- if test "x${GSM_DIR}" != "x"; then
- GSM_LIB="${gsmlibdir} ${GSM_LIB}"
- GSM_INCLUDE="-I${GSM_DIR}/include"
- fi
- PBX_GSM=1
- GSM_INTERNAL="no"
- fi
- fi
- fi
- if test "${GSM_INTERNAL}" = "yes"; then
- PBX_GSM=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GSM_HEADER 1
-_ACEOF
-
- fi
-fi
-
-
-if test "${USE_IKSEMEL}" != "no"; then
- pbxlibdir=""
- if test "x${IKSEMEL_DIR}" != "x"; then
- if test -d ${IKSEMEL_DIR}/lib; then
- pbxlibdir="-L${IKSEMEL_DIR}/lib"
- else
- pbxlibdir="-L${IKSEMEL_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for iks_start_sasl in -liksemel" >&5
-echo $ECHO_N "checking for iks_start_sasl in -liksemel... $ECHO_C" >&6; }
-if test "${ac_cv_lib_iksemel_iks_start_sasl+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-liksemel ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char iks_start_sasl ();
-int
-main ()
-{
-return iks_start_sasl ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_iksemel_iks_start_sasl=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_iksemel_iks_start_sasl=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_iksemel_iks_start_sasl" >&5
-echo "${ECHO_T}$ac_cv_lib_iksemel_iks_start_sasl" >&6; }
-if test $ac_cv_lib_iksemel_iks_start_sasl = yes; then
- AST_IKSEMEL_FOUND=yes
-else
- AST_IKSEMEL_FOUND=no
-fi
-
-
- if test "${AST_IKSEMEL_FOUND}" = "yes"; then
- IKSEMEL_LIB="-liksemel "
- IKSEMEL_HEADER_FOUND="1"
- if test "x${IKSEMEL_DIR}" != "x"; then
- IKSEMEL_LIB="${pbxlibdir} ${IKSEMEL_LIB}"
- IKSEMEL_INCLUDE="-I${IKSEMEL_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${IKSEMEL_DIR}/include"
- if test "xiksemel.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${IKSEMEL_DIR}/include/iksemel.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${IKSEMEL_DIR}/include/iksemel.h" >&5
-echo $ECHO_N "checking for ${IKSEMEL_DIR}/include/iksemel.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${IKSEMEL_DIR}/include/iksemel.h usability" >&5
-echo $ECHO_N "checking ${IKSEMEL_DIR}/include/iksemel.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${IKSEMEL_DIR}/include/iksemel.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${IKSEMEL_DIR}/include/iksemel.h presence" >&5
-echo $ECHO_N "checking ${IKSEMEL_DIR}/include/iksemel.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${IKSEMEL_DIR}/include/iksemel.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${IKSEMEL_DIR}/include/iksemel.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${IKSEMEL_DIR}/include/iksemel.h" >&5
-echo $ECHO_N "checking for ${IKSEMEL_DIR}/include/iksemel.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- IKSEMEL_HEADER_FOUND=1
-else
- IKSEMEL_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xiksemel.h" != "x" ; then
- if test "${ac_cv_header_iksemel_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for iksemel.h" >&5
-echo $ECHO_N "checking for iksemel.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_iksemel_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_iksemel_h" >&5
-echo "${ECHO_T}$ac_cv_header_iksemel_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking iksemel.h usability" >&5
-echo $ECHO_N "checking iksemel.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <iksemel.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking iksemel.h presence" >&5
-echo $ECHO_N "checking iksemel.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <iksemel.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: iksemel.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: iksemel.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: iksemel.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: iksemel.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: iksemel.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: iksemel.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: iksemel.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: iksemel.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: iksemel.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: iksemel.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: iksemel.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: iksemel.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: iksemel.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: iksemel.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: iksemel.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: iksemel.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for iksemel.h" >&5
-echo $ECHO_N "checking for iksemel.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_iksemel_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_iksemel_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_iksemel_h" >&5
-echo "${ECHO_T}$ac_cv_header_iksemel_h" >&6; }
-
-fi
-if test $ac_cv_header_iksemel_h = yes; then
- IKSEMEL_HEADER_FOUND=1
-else
- IKSEMEL_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${IKSEMEL_HEADER_FOUND}" = "x0" ; then
- if test -n "${IKSEMEL_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the iksemel development package installed." >&5
-echo "$as_me: *** It appears that you do not have the iksemel development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${IKSEMEL_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${IKSEMEL_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${IKSEMEL_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${IKSEMEL_OPTION}" >&6;}
- exit 1
- fi
- IKSEMEL_LIB=""
- IKSEMEL_INCLUDE=""
- PBX_IKSEMEL=0
- else
- PBX_IKSEMEL=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_IKSEMEL 1
-_ACEOF
-
- fi
- elif test -n "${IKSEMEL_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${IKSEMEL_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${IKSEMEL_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${IKSEMEL_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${IKSEMEL_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${PBX_IKSEMEL}" = 1; then
-
-if test "${USE_GNUTLS}" != "no"; then
- pbxlibdir=""
- if test "x${GNUTLS_DIR}" != "x"; then
- if test -d ${GNUTLS_DIR}/lib; then
- pbxlibdir="-L${GNUTLS_DIR}/lib"
- else
- pbxlibdir="-L${GNUTLS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for gnutls_bye in -lgnutls" >&5
-echo $ECHO_N "checking for gnutls_bye in -lgnutls... $ECHO_C" >&6; }
-if test "${ac_cv_lib_gnutls_gnutls_bye+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lgnutls ${pbxlibdir} -lz -lgcrypt -lgpg-error $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gnutls_bye ();
-int
-main ()
-{
-return gnutls_bye ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_gnutls_gnutls_bye=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_gnutls_gnutls_bye=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_gnutls_gnutls_bye" >&5
-echo "${ECHO_T}$ac_cv_lib_gnutls_gnutls_bye" >&6; }
-if test $ac_cv_lib_gnutls_gnutls_bye = yes; then
- AST_GNUTLS_FOUND=yes
-else
- AST_GNUTLS_FOUND=no
-fi
-
-
- if test "${AST_GNUTLS_FOUND}" = "yes"; then
- GNUTLS_LIB="-lgnutls -lz -lgcrypt -lgpg-error"
- GNUTLS_HEADER_FOUND="1"
- if test "x${GNUTLS_DIR}" != "x"; then
- GNUTLS_LIB="${pbxlibdir} ${GNUTLS_LIB}"
- GNUTLS_INCLUDE="-I${GNUTLS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${GNUTLS_DIR}/include"
- if test "xgnutls/gnutls.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${GNUTLS_DIR}/include/gnutls/gnutls.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${GNUTLS_DIR}/include/gnutls/gnutls.h" >&5
-echo $ECHO_N "checking for ${GNUTLS_DIR}/include/gnutls/gnutls.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${GNUTLS_DIR}/include/gnutls/gnutls.h usability" >&5
-echo $ECHO_N "checking ${GNUTLS_DIR}/include/gnutls/gnutls.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${GNUTLS_DIR}/include/gnutls/gnutls.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${GNUTLS_DIR}/include/gnutls/gnutls.h presence" >&5
-echo $ECHO_N "checking ${GNUTLS_DIR}/include/gnutls/gnutls.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${GNUTLS_DIR}/include/gnutls/gnutls.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${GNUTLS_DIR}/include/gnutls/gnutls.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${GNUTLS_DIR}/include/gnutls/gnutls.h" >&5
-echo $ECHO_N "checking for ${GNUTLS_DIR}/include/gnutls/gnutls.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- GNUTLS_HEADER_FOUND=1
-else
- GNUTLS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xgnutls/gnutls.h" != "x" ; then
- if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for gnutls/gnutls.h" >&5
-echo $ECHO_N "checking for gnutls/gnutls.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_gnutls_gnutls_h" >&5
-echo "${ECHO_T}$ac_cv_header_gnutls_gnutls_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking gnutls/gnutls.h usability" >&5
-echo $ECHO_N "checking gnutls/gnutls.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <gnutls/gnutls.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking gnutls/gnutls.h presence" >&5
-echo $ECHO_N "checking gnutls/gnutls.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <gnutls/gnutls.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: gnutls/gnutls.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for gnutls/gnutls.h" >&5
-echo $ECHO_N "checking for gnutls/gnutls.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_gnutls_gnutls_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_gnutls_gnutls_h" >&5
-echo "${ECHO_T}$ac_cv_header_gnutls_gnutls_h" >&6; }
-
-fi
-if test $ac_cv_header_gnutls_gnutls_h = yes; then
- GNUTLS_HEADER_FOUND=1
-else
- GNUTLS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${GNUTLS_HEADER_FOUND}" = "x0" ; then
- if test -n "${GNUTLS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the gnutls development package installed." >&5
-echo "$as_me: *** It appears that you do not have the gnutls development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${GNUTLS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${GNUTLS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${GNUTLS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${GNUTLS_OPTION}" >&6;}
- exit 1
- fi
- GNUTLS_LIB=""
- GNUTLS_INCLUDE=""
- PBX_GNUTLS=0
- else
- PBX_GNUTLS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GNUTLS 1
-_ACEOF
-
- fi
- elif test -n "${GNUTLS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${GNUTLS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${GNUTLS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${GNUTLS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${GNUTLS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-fi
-
-if test "${USE_IMAP_TK}" != "no"; then
- saved_cppflags="${CPPFLAGS}"
- saved_libs="${LIBS}"
- switch_to_system_on_failure="no"
- if test "${IMAP_TK_DIR}" = ""; then
- IMAP_TK_DIR=`pwd`"/../imap-2004g"
- switch_to_system_on_failure="yes"
- fi
- if test "${IMAP_TK_DIR}" != "system"; then
- { echo "$as_me:$LINENO: checking for UW IMAP Toolkit c-client library" >&5
-echo $ECHO_N "checking for UW IMAP Toolkit c-client library... $ECHO_C" >&6; }
- if test -f "${IMAP_TK_DIR}/c-client/LDFLAGS"; then
- imap_ldflags=`cat ${IMAP_TK_DIR}/c-client/LDFLAGS`
- fi
- imap_libs="${IMAP_TK_DIR}/c-client/c-client.a"
- imap_include="-I${IMAP_TK_DIR}/c-client"
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} "`echo ${imap_ldflags}`
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- MAILSTREAM *foo = mail_open(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- if test "${ac_cv_imap_tk}" = "yes"; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- long check = mail_expunge_full(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk2006="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk2006="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- fi
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- if test "${ac_cv_imap_tk}" = "no"; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- if test "${switch_to_system_on_failure}" = "yes"; then
- IMAP_TK_DIR="system"
- else #This means they specified a directory. Search for a package installation there too
- { echo "$as_me:$LINENO: checking for system c-client library..." >&5
-echo $ECHO_N "checking for system c-client library...... $ECHO_C" >&6; }
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- imap_include="-I${IMAP_TK_DIR}/include"
- imap_ldflags="-L${IMAP_TK_DIR}/lib"
- imap_libs="-lc-client"
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} ${imap_ldflags}"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- MAILSTREAM *foo = mail_open(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- if test "${ac_cv_imap_tk}" = "yes"; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- long check = mail_expunge_full(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk2006="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk2006="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- fi
- fi
- fi
- fi
- if test "${IMAP_TK_DIR}" = "system"; then
- #We will enter here if user specified "system" or if any of above checks failed
- { echo "$as_me:$LINENO: checking for system c-client library..." >&5
-echo $ECHO_N "checking for system c-client library...... $ECHO_C" >&6; }
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- imap_ldflags=""
- imap_libs="-lc-client"
- imap_include="-DUSE_SYSTEM_IMAP" #Try the imap directory first
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} "`echo ${imap_ldflags}`
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdio.h>
- #include <imap/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- MAILSTREAM *foo = mail_open(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- if test "${ac_cv_imap_tk}" = "yes"; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdio.h>
- #include <imap/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- long check = mail_expunge_full(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk2006="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk2006="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- else #looking in imap directory didn't work, try c-client
- imap_ldflags=""
- imap_libs="-lc-client"
- imap_include="-DUSE_SYSTEM_CCLIENT"
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} "`echo ${imap_ldflags}`
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdio.h>
- #include <c-client/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- MAILSTREAM *foo = mail_open(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- if test "${ac_cv_imap_tk}" = "yes"; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdio.h>
- #include <c-client/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }
-int
-main ()
-{
-
- long check = mail_expunge_full(NULL, "", 0);
-
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_imap_tk2006="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_imap_tk2006="no"
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- fi
- fi
- fi
- if test "${ac_cv_imap_tk}" = "yes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- IMAP_TK_LIB="${imap_libs} "`echo ${imap_ldflags}`
- IMAP_TK_INCLUDE="${imap_include}"
- PBX_IMAP_TK=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_IMAP_TK 1
-_ACEOF
-
- if test "${ac_cv_imap_tk2006}" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_IMAP_TK2006 1
-_ACEOF
-
- fi
- elif test -n "${IMAP_TK_MANDATORY}"; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The UW IMAP Toolkit installation on this system appears to be broken." >&5
-echo "$as_me: *** The UW IMAP Toolkit installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-imap." >&5
-echo "$as_me: *** including --without-imap." >&6;}
- exit 1
- else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- fi
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
-fi
-
-# Needed by unixodbc
-
-if test "${USE_LTDL}" != "no"; then
- pbxlibdir=""
- if test "x${LTDL_DIR}" != "x"; then
- if test -d ${LTDL_DIR}/lib; then
- pbxlibdir="-L${LTDL_DIR}/lib"
- else
- pbxlibdir="-L${LTDL_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for lt_dlinit in -lltdl" >&5
-echo $ECHO_N "checking for lt_dlinit in -lltdl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ltdl_lt_dlinit+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lltdl ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char lt_dlinit ();
-int
-main ()
-{
-return lt_dlinit ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ltdl_lt_dlinit=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ltdl_lt_dlinit=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ltdl_lt_dlinit" >&5
-echo "${ECHO_T}$ac_cv_lib_ltdl_lt_dlinit" >&6; }
-if test $ac_cv_lib_ltdl_lt_dlinit = yes; then
- AST_LTDL_FOUND=yes
-else
- AST_LTDL_FOUND=no
-fi
-
-
- if test "${AST_LTDL_FOUND}" = "yes"; then
- LTDL_LIB="-lltdl "
- LTDL_HEADER_FOUND="1"
- if test "x${LTDL_DIR}" != "x"; then
- LTDL_LIB="${pbxlibdir} ${LTDL_LIB}"
- LTDL_INCLUDE="-I${LTDL_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${LTDL_DIR}/include"
- if test "xltdl.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${LTDL_DIR}/include/ltdl.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${LTDL_DIR}/include/ltdl.h" >&5
-echo $ECHO_N "checking for ${LTDL_DIR}/include/ltdl.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${LTDL_DIR}/include/ltdl.h usability" >&5
-echo $ECHO_N "checking ${LTDL_DIR}/include/ltdl.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${LTDL_DIR}/include/ltdl.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${LTDL_DIR}/include/ltdl.h presence" >&5
-echo $ECHO_N "checking ${LTDL_DIR}/include/ltdl.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${LTDL_DIR}/include/ltdl.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${LTDL_DIR}/include/ltdl.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${LTDL_DIR}/include/ltdl.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${LTDL_DIR}/include/ltdl.h" >&5
-echo $ECHO_N "checking for ${LTDL_DIR}/include/ltdl.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- LTDL_HEADER_FOUND=1
-else
- LTDL_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xltdl.h" != "x" ; then
- if test "${ac_cv_header_ltdl_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for ltdl.h" >&5
-echo $ECHO_N "checking for ltdl.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_ltdl_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_ltdl_h" >&5
-echo "${ECHO_T}$ac_cv_header_ltdl_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ltdl.h usability" >&5
-echo $ECHO_N "checking ltdl.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <ltdl.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ltdl.h presence" >&5
-echo $ECHO_N "checking ltdl.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ltdl.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ltdl.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ltdl.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ltdl.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ltdl.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ltdl.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ltdl.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ltdl.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ltdl.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ltdl.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ltdl.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ltdl.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ltdl.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ltdl.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ltdl.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ltdl.h" >&5
-echo $ECHO_N "checking for ltdl.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_ltdl_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_ltdl_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_ltdl_h" >&5
-echo "${ECHO_T}$ac_cv_header_ltdl_h" >&6; }
-
-fi
-if test $ac_cv_header_ltdl_h = yes; then
- LTDL_HEADER_FOUND=1
-else
- LTDL_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${LTDL_HEADER_FOUND}" = "x0" ; then
- if test -n "${LTDL_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the ltdl development package installed." >&5
-echo "$as_me: *** It appears that you do not have the ltdl development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${LTDL_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${LTDL_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${LTDL_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${LTDL_OPTION}" >&6;}
- exit 1
- fi
- LTDL_LIB=""
- LTDL_INCLUDE=""
- PBX_LTDL=0
- else
- PBX_LTDL=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_LTDL 1
-_ACEOF
-
- fi
- elif test -n "${LTDL_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${LTDL_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${LTDL_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${LTDL_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${LTDL_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-if test "${USE_KDE}" != "no"; then
- { echo "$as_me:$LINENO: checking for crashHandler in -lkdecore" >&5
-echo $ECHO_N "checking for crashHandler in -lkdecore... $ECHO_C" >&6; }
- saved_libs="${LIBS}"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${KDE_DIR}/include"
- if test -d ${KDE_DIR}/lib; then
- kdelibdir="${KDE_DIR}/lib"
- else
- kdelibdir="${KDE_DIR}"
- fi
- LIBS="${LIBS} -L${kdelibdir} -lkdecore"
-
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "kcrash.h"
-int
-main ()
-{
-KCrash::defaultCrashHandler(1);
- ;
- return 0;
-}
-
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_kde_crash="yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_kde_crash="no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
-
- if test "${ac_cv_lib_kde_crash}" = "yes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- KDE_LIB="-lkdecore -lkdeui"
- if test "${KDE_DIR}" != ""; then
- KDE_LIB="-L${kdelibdir} ${KDE_LIB}"
- KDE_INCLUDE="-I${KDE_DIR}/include"
- fi
- PBX_KDE=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LIBKDE 1
-_ACEOF
-
- elif test -n "${KDE_MANDATORY}"; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The KDE installation on this system appears to be broken." >&5
-echo "$as_me: *** The KDE installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-kde." >&5
-echo "$as_me: *** including --without-kde." >&6;}
- exit 1
- else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- fi
-fi
-if test "${PBX_KDE}" = 1; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}kdeinit", so it can be a program name with args.
-set dummy ${ac_tool_prefix}kdeinit; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_KDEINIT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $KDEINIT in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_KDEINIT="$KDEINIT" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_KDEINIT="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-KDEINIT=$ac_cv_path_KDEINIT
-if test -n "$KDEINIT"; then
- { echo "$as_me:$LINENO: result: $KDEINIT" >&5
-echo "${ECHO_T}$KDEINIT" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_KDEINIT"; then
- ac_pt_KDEINIT=$KDEINIT
- # Extract the first word of "kdeinit", so it can be a program name with args.
-set dummy kdeinit; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_KDEINIT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_KDEINIT in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_KDEINIT="$ac_pt_KDEINIT" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_KDEINIT="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_KDEINIT=$ac_cv_path_ac_pt_KDEINIT
-if test -n "$ac_pt_KDEINIT"; then
- { echo "$as_me:$LINENO: result: $ac_pt_KDEINIT" >&5
-echo "${ECHO_T}$ac_pt_KDEINIT" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_KDEINIT" = x; then
- KDEINIT="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- KDEINIT=$ac_pt_KDEINIT
- fi
-else
- KDEINIT="$ac_cv_path_KDEINIT"
-fi
-
- if test ! x"${KDEINIT}" = xNo; then
- KDEDIR=$(${DIRNAME} ${KDEINIT})
- KDEDIR=$(${DIRNAME} ${KDEDIR})
- fi
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-if test "${USE_MISDN}" != "no"; then
- pbxlibdir=""
- if test "x${MISDN_DIR}" != "x"; then
- if test -d ${MISDN_DIR}/lib; then
- pbxlibdir="-L${MISDN_DIR}/lib"
- else
- pbxlibdir="-L${MISDN_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for mISDN_open in -lmISDN" >&5
-echo $ECHO_N "checking for mISDN_open in -lmISDN... $ECHO_C" >&6; }
-if test "${ac_cv_lib_mISDN_mISDN_open+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lmISDN ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char mISDN_open ();
-int
-main ()
-{
-return mISDN_open ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_mISDN_mISDN_open=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_mISDN_mISDN_open=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_mISDN_mISDN_open" >&5
-echo "${ECHO_T}$ac_cv_lib_mISDN_mISDN_open" >&6; }
-if test $ac_cv_lib_mISDN_mISDN_open = yes; then
- AST_MISDN_FOUND=yes
-else
- AST_MISDN_FOUND=no
-fi
-
-
- if test "${AST_MISDN_FOUND}" = "yes"; then
- MISDN_LIB="-lmISDN "
- MISDN_HEADER_FOUND="1"
- if test "x${MISDN_DIR}" != "x"; then
- MISDN_LIB="${pbxlibdir} ${MISDN_LIB}"
- MISDN_INCLUDE="-I${MISDN_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${MISDN_DIR}/include"
- if test "xmISDNuser/mISDNlib.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${MISDN_DIR}/include/mISDNuser/mISDNlib.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${MISDN_DIR}/include/mISDNuser/mISDNlib.h" >&5
-echo $ECHO_N "checking for ${MISDN_DIR}/include/mISDNuser/mISDNlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${MISDN_DIR}/include/mISDNuser/mISDNlib.h usability" >&5
-echo $ECHO_N "checking ${MISDN_DIR}/include/mISDNuser/mISDNlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${MISDN_DIR}/include/mISDNuser/mISDNlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${MISDN_DIR}/include/mISDNuser/mISDNlib.h presence" >&5
-echo $ECHO_N "checking ${MISDN_DIR}/include/mISDNuser/mISDNlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${MISDN_DIR}/include/mISDNuser/mISDNlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${MISDN_DIR}/include/mISDNuser/mISDNlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${MISDN_DIR}/include/mISDNuser/mISDNlib.h" >&5
-echo $ECHO_N "checking for ${MISDN_DIR}/include/mISDNuser/mISDNlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- MISDN_HEADER_FOUND=1
-else
- MISDN_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xmISDNuser/mISDNlib.h" != "x" ; then
- if test "${ac_cv_header_mISDNuser_mISDNlib_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for mISDNuser/mISDNlib.h" >&5
-echo $ECHO_N "checking for mISDNuser/mISDNlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_mISDNuser_mISDNlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_mISDNuser_mISDNlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_mISDNuser_mISDNlib_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking mISDNuser/mISDNlib.h usability" >&5
-echo $ECHO_N "checking mISDNuser/mISDNlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <mISDNuser/mISDNlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking mISDNuser/mISDNlib.h presence" >&5
-echo $ECHO_N "checking mISDNuser/mISDNlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <mISDNuser/mISDNlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/mISDNlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: mISDNuser/mISDNlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for mISDNuser/mISDNlib.h" >&5
-echo $ECHO_N "checking for mISDNuser/mISDNlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_mISDNuser_mISDNlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_mISDNuser_mISDNlib_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_mISDNuser_mISDNlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_mISDNuser_mISDNlib_h" >&6; }
-
-fi
-if test $ac_cv_header_mISDNuser_mISDNlib_h = yes; then
- MISDN_HEADER_FOUND=1
-else
- MISDN_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${MISDN_HEADER_FOUND}" = "x0" ; then
- if test -n "${MISDN_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the mISDN development package installed." >&5
-echo "$as_me: *** It appears that you do not have the mISDN development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${MISDN_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${MISDN_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${MISDN_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${MISDN_OPTION}" >&6;}
- exit 1
- fi
- MISDN_LIB=""
- MISDN_INCLUDE=""
- PBX_MISDN=0
- else
- PBX_MISDN=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_MISDN 1
-_ACEOF
-
- fi
- elif test -n "${MISDN_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${MISDN_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${MISDN_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${MISDN_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${MISDN_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${PBX_MISDN}" = 1; then
-
-if test "${USE_ISDNNET}" != "no"; then
- pbxlibdir=""
- if test "x${ISDNNET_DIR}" != "x"; then
- if test -d ${ISDNNET_DIR}/lib; then
- pbxlibdir="-L${ISDNNET_DIR}/lib"
- else
- pbxlibdir="-L${ISDNNET_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for init_manager in -lisdnnet" >&5
-echo $ECHO_N "checking for init_manager in -lisdnnet... $ECHO_C" >&6; }
-if test "${ac_cv_lib_isdnnet_init_manager+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lisdnnet ${pbxlibdir} -lmISDN -lpthread $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char init_manager ();
-int
-main ()
-{
-return init_manager ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_isdnnet_init_manager=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_isdnnet_init_manager=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_isdnnet_init_manager" >&5
-echo "${ECHO_T}$ac_cv_lib_isdnnet_init_manager" >&6; }
-if test $ac_cv_lib_isdnnet_init_manager = yes; then
- AST_ISDNNET_FOUND=yes
-else
- AST_ISDNNET_FOUND=no
-fi
-
-
- if test "${AST_ISDNNET_FOUND}" = "yes"; then
- ISDNNET_LIB="-lisdnnet -lmISDN -lpthread"
- ISDNNET_HEADER_FOUND="1"
- if test "x${ISDNNET_DIR}" != "x"; then
- ISDNNET_LIB="${pbxlibdir} ${ISDNNET_LIB}"
- ISDNNET_INCLUDE="-I${ISDNNET_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${ISDNNET_DIR}/include"
- if test "xmISDNuser/isdn_net.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${ISDNNET_DIR}/include/mISDNuser/isdn_net.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h" >&5
-echo $ECHO_N "checking for ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h usability" >&5
-echo $ECHO_N "checking ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${ISDNNET_DIR}/include/mISDNuser/isdn_net.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h presence" >&5
-echo $ECHO_N "checking ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${ISDNNET_DIR}/include/mISDNuser/isdn_net.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h" >&5
-echo $ECHO_N "checking for ${ISDNNET_DIR}/include/mISDNuser/isdn_net.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- ISDNNET_HEADER_FOUND=1
-else
- ISDNNET_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xmISDNuser/isdn_net.h" != "x" ; then
- if test "${ac_cv_header_mISDNuser_isdn_net_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for mISDNuser/isdn_net.h" >&5
-echo $ECHO_N "checking for mISDNuser/isdn_net.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_mISDNuser_isdn_net_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_mISDNuser_isdn_net_h" >&5
-echo "${ECHO_T}$ac_cv_header_mISDNuser_isdn_net_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking mISDNuser/isdn_net.h usability" >&5
-echo $ECHO_N "checking mISDNuser/isdn_net.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <mISDNuser/isdn_net.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking mISDNuser/isdn_net.h presence" >&5
-echo $ECHO_N "checking mISDNuser/isdn_net.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <mISDNuser/isdn_net.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/isdn_net.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: mISDNuser/isdn_net.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for mISDNuser/isdn_net.h" >&5
-echo $ECHO_N "checking for mISDNuser/isdn_net.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_mISDNuser_isdn_net_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_mISDNuser_isdn_net_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_mISDNuser_isdn_net_h" >&5
-echo "${ECHO_T}$ac_cv_header_mISDNuser_isdn_net_h" >&6; }
-
-fi
-if test $ac_cv_header_mISDNuser_isdn_net_h = yes; then
- ISDNNET_HEADER_FOUND=1
-else
- ISDNNET_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${ISDNNET_HEADER_FOUND}" = "x0" ; then
- if test -n "${ISDNNET_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the isdnnet development package installed." >&5
-echo "$as_me: *** It appears that you do not have the isdnnet development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${ISDNNET_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${ISDNNET_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${ISDNNET_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${ISDNNET_OPTION}" >&6;}
- exit 1
- fi
- ISDNNET_LIB=""
- ISDNNET_INCLUDE=""
- PBX_ISDNNET=0
- else
- PBX_ISDNNET=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ISDNNET 1
-_ACEOF
-
- fi
- elif test -n "${ISDNNET_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${ISDNNET_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${ISDNNET_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${ISDNNET_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${ISDNNET_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${USE_SUPPSERV}" != "no"; then
- pbxlibdir=""
- if test "x${SUPPSERV_DIR}" != "x"; then
- if test -d ${SUPPSERV_DIR}/lib; then
- pbxlibdir="-L${SUPPSERV_DIR}/lib"
- else
- pbxlibdir="-L${SUPPSERV_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for encodeFac in -lsuppserv" >&5
-echo $ECHO_N "checking for encodeFac in -lsuppserv... $ECHO_C" >&6; }
-if test "${ac_cv_lib_suppserv_encodeFac+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsuppserv ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char encodeFac ();
-int
-main ()
-{
-return encodeFac ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_suppserv_encodeFac=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_suppserv_encodeFac=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_suppserv_encodeFac" >&5
-echo "${ECHO_T}$ac_cv_lib_suppserv_encodeFac" >&6; }
-if test $ac_cv_lib_suppserv_encodeFac = yes; then
- AST_SUPPSERV_FOUND=yes
-else
- AST_SUPPSERV_FOUND=no
-fi
-
-
- if test "${AST_SUPPSERV_FOUND}" = "yes"; then
- SUPPSERV_LIB="-lsuppserv "
- SUPPSERV_HEADER_FOUND="1"
- if test "x${SUPPSERV_DIR}" != "x"; then
- SUPPSERV_LIB="${pbxlibdir} ${SUPPSERV_LIB}"
- SUPPSERV_INCLUDE="-I${SUPPSERV_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${SUPPSERV_DIR}/include"
- if test "xmISDNuser/suppserv.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${SUPPSERV_DIR}/include/mISDNuser/suppserv.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h" >&5
-echo $ECHO_N "checking for ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h usability" >&5
-echo $ECHO_N "checking ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${SUPPSERV_DIR}/include/mISDNuser/suppserv.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h presence" >&5
-echo $ECHO_N "checking ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${SUPPSERV_DIR}/include/mISDNuser/suppserv.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h" >&5
-echo $ECHO_N "checking for ${SUPPSERV_DIR}/include/mISDNuser/suppserv.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- SUPPSERV_HEADER_FOUND=1
-else
- SUPPSERV_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xmISDNuser/suppserv.h" != "x" ; then
- if test "${ac_cv_header_mISDNuser_suppserv_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for mISDNuser/suppserv.h" >&5
-echo $ECHO_N "checking for mISDNuser/suppserv.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_mISDNuser_suppserv_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_mISDNuser_suppserv_h" >&5
-echo "${ECHO_T}$ac_cv_header_mISDNuser_suppserv_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking mISDNuser/suppserv.h usability" >&5
-echo $ECHO_N "checking mISDNuser/suppserv.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <mISDNuser/suppserv.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking mISDNuser/suppserv.h presence" >&5
-echo $ECHO_N "checking mISDNuser/suppserv.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <mISDNuser/suppserv.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: mISDNuser/suppserv.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: mISDNuser/suppserv.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for mISDNuser/suppserv.h" >&5
-echo $ECHO_N "checking for mISDNuser/suppserv.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_mISDNuser_suppserv_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_mISDNuser_suppserv_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_mISDNuser_suppserv_h" >&5
-echo "${ECHO_T}$ac_cv_header_mISDNuser_suppserv_h" >&6; }
-
-fi
-if test $ac_cv_header_mISDNuser_suppserv_h = yes; then
- SUPPSERV_HEADER_FOUND=1
-else
- SUPPSERV_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${SUPPSERV_HEADER_FOUND}" = "x0" ; then
- if test -n "${SUPPSERV_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the suppserv development package installed." >&5
-echo "$as_me: *** It appears that you do not have the suppserv development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${SUPPSERV_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${SUPPSERV_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SUPPSERV_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SUPPSERV_OPTION}" >&6;}
- exit 1
- fi
- SUPPSERV_LIB=""
- SUPPSERV_INCLUDE=""
- PBX_SUPPSERV=0
- else
- PBX_SUPPSERV=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_SUPPSERV 1
-_ACEOF
-
- fi
- elif test -n "${SUPPSERV_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${SUPPSERV_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${SUPPSERV_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SUPPSERV_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SUPPSERV_OPTION}" >&6;}
- exit 1
- fi
-fi
-
- if test "${ac_cv_header_linux_mISDNdsp_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for linux/mISDNdsp.h" >&5
-echo $ECHO_N "checking for linux/mISDNdsp.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_mISDNdsp_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_mISDNdsp_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_mISDNdsp_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking linux/mISDNdsp.h usability" >&5
-echo $ECHO_N "checking linux/mISDNdsp.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <linux/mISDNdsp.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking linux/mISDNdsp.h presence" >&5
-echo $ECHO_N "checking linux/mISDNdsp.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <linux/mISDNdsp.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/mISDNdsp.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: linux/mISDNdsp.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for linux/mISDNdsp.h" >&5
-echo $ECHO_N "checking for linux/mISDNdsp.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_mISDNdsp_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_linux_mISDNdsp_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_mISDNdsp_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_mISDNdsp_h" >&6; }
-
-fi
-if test $ac_cv_header_linux_mISDNdsp_h = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define MISDN_1_2 1
-_ACEOF
-
-fi
-
-
-fi
-
-
-if test "${USE_NBS}" != "no"; then
- pbxlibdir=""
- if test "x${NBS_DIR}" != "x"; then
- if test -d ${NBS_DIR}/lib; then
- pbxlibdir="-L${NBS_DIR}/lib"
- else
- pbxlibdir="-L${NBS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for nbs_connect in -lnbs" >&5
-echo $ECHO_N "checking for nbs_connect in -lnbs... $ECHO_C" >&6; }
-if test "${ac_cv_lib_nbs_nbs_connect+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnbs ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char nbs_connect ();
-int
-main ()
-{
-return nbs_connect ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_nbs_nbs_connect=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_nbs_nbs_connect=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_nbs_nbs_connect" >&5
-echo "${ECHO_T}$ac_cv_lib_nbs_nbs_connect" >&6; }
-if test $ac_cv_lib_nbs_nbs_connect = yes; then
- AST_NBS_FOUND=yes
-else
- AST_NBS_FOUND=no
-fi
-
-
- if test "${AST_NBS_FOUND}" = "yes"; then
- NBS_LIB="-lnbs "
- NBS_HEADER_FOUND="1"
- if test "x${NBS_DIR}" != "x"; then
- NBS_LIB="${pbxlibdir} ${NBS_LIB}"
- NBS_INCLUDE="-I${NBS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${NBS_DIR}/include"
- if test "xnbs.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${NBS_DIR}/include/nbs.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${NBS_DIR}/include/nbs.h" >&5
-echo $ECHO_N "checking for ${NBS_DIR}/include/nbs.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${NBS_DIR}/include/nbs.h usability" >&5
-echo $ECHO_N "checking ${NBS_DIR}/include/nbs.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${NBS_DIR}/include/nbs.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${NBS_DIR}/include/nbs.h presence" >&5
-echo $ECHO_N "checking ${NBS_DIR}/include/nbs.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${NBS_DIR}/include/nbs.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NBS_DIR}/include/nbs.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${NBS_DIR}/include/nbs.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${NBS_DIR}/include/nbs.h" >&5
-echo $ECHO_N "checking for ${NBS_DIR}/include/nbs.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- NBS_HEADER_FOUND=1
-else
- NBS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xnbs.h" != "x" ; then
- if test "${ac_cv_header_nbs_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for nbs.h" >&5
-echo $ECHO_N "checking for nbs.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_nbs_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_nbs_h" >&5
-echo "${ECHO_T}$ac_cv_header_nbs_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking nbs.h usability" >&5
-echo $ECHO_N "checking nbs.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <nbs.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking nbs.h presence" >&5
-echo $ECHO_N "checking nbs.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <nbs.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: nbs.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: nbs.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: nbs.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: nbs.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: nbs.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: nbs.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: nbs.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: nbs.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: nbs.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: nbs.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: nbs.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: nbs.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: nbs.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: nbs.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: nbs.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: nbs.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for nbs.h" >&5
-echo $ECHO_N "checking for nbs.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_nbs_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_nbs_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_nbs_h" >&5
-echo "${ECHO_T}$ac_cv_header_nbs_h" >&6; }
-
-fi
-if test $ac_cv_header_nbs_h = yes; then
- NBS_HEADER_FOUND=1
-else
- NBS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${NBS_HEADER_FOUND}" = "x0" ; then
- if test -n "${NBS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the nbs development package installed." >&5
-echo "$as_me: *** It appears that you do not have the nbs development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${NBS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${NBS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${NBS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${NBS_OPTION}" >&6;}
- exit 1
- fi
- NBS_LIB=""
- NBS_INCLUDE=""
- PBX_NBS=0
- else
- PBX_NBS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_NBS 1
-_ACEOF
-
- fi
- elif test -n "${NBS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${NBS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${NBS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${NBS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${NBS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_NCURSES}" != "no"; then
- pbxlibdir=""
- if test "x${NCURSES_DIR}" != "x"; then
- if test -d ${NCURSES_DIR}/lib; then
- pbxlibdir="-L${NCURSES_DIR}/lib"
- else
- pbxlibdir="-L${NCURSES_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for initscr in -lncurses" >&5
-echo $ECHO_N "checking for initscr in -lncurses... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ncurses_initscr+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncurses ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char initscr ();
-int
-main ()
-{
-return initscr ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ncurses_initscr=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ncurses_initscr=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_initscr" >&5
-echo "${ECHO_T}$ac_cv_lib_ncurses_initscr" >&6; }
-if test $ac_cv_lib_ncurses_initscr = yes; then
- AST_NCURSES_FOUND=yes
-else
- AST_NCURSES_FOUND=no
-fi
-
-
- if test "${AST_NCURSES_FOUND}" = "yes"; then
- NCURSES_LIB="-lncurses "
- NCURSES_HEADER_FOUND="1"
- if test "x${NCURSES_DIR}" != "x"; then
- NCURSES_LIB="${pbxlibdir} ${NCURSES_LIB}"
- NCURSES_INCLUDE="-I${NCURSES_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${NCURSES_DIR}/include"
- if test "xcurses.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${NCURSES_DIR}/include/curses.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${NCURSES_DIR}/include/curses.h" >&5
-echo $ECHO_N "checking for ${NCURSES_DIR}/include/curses.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${NCURSES_DIR}/include/curses.h usability" >&5
-echo $ECHO_N "checking ${NCURSES_DIR}/include/curses.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${NCURSES_DIR}/include/curses.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${NCURSES_DIR}/include/curses.h presence" >&5
-echo $ECHO_N "checking ${NCURSES_DIR}/include/curses.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${NCURSES_DIR}/include/curses.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NCURSES_DIR}/include/curses.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${NCURSES_DIR}/include/curses.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${NCURSES_DIR}/include/curses.h" >&5
-echo $ECHO_N "checking for ${NCURSES_DIR}/include/curses.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- NCURSES_HEADER_FOUND=1
-else
- NCURSES_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xcurses.h" != "x" ; then
- if test "${ac_cv_header_curses_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for curses.h" >&5
-echo $ECHO_N "checking for curses.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_curses_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_curses_h" >&5
-echo "${ECHO_T}$ac_cv_header_curses_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking curses.h usability" >&5
-echo $ECHO_N "checking curses.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <curses.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking curses.h presence" >&5
-echo $ECHO_N "checking curses.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <curses.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: curses.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: curses.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: curses.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: curses.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: curses.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: curses.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: curses.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: curses.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: curses.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: curses.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: curses.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for curses.h" >&5
-echo $ECHO_N "checking for curses.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_curses_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_curses_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_curses_h" >&5
-echo "${ECHO_T}$ac_cv_header_curses_h" >&6; }
-
-fi
-if test $ac_cv_header_curses_h = yes; then
- NCURSES_HEADER_FOUND=1
-else
- NCURSES_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${NCURSES_HEADER_FOUND}" = "x0" ; then
- if test -n "${NCURSES_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the ncurses development package installed." >&5
-echo "$as_me: *** It appears that you do not have the ncurses development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${NCURSES_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${NCURSES_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${NCURSES_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${NCURSES_OPTION}" >&6;}
- exit 1
- fi
- NCURSES_LIB=""
- NCURSES_INCLUDE=""
- PBX_NCURSES=0
- else
- PBX_NCURSES=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_NCURSES 1
-_ACEOF
-
- fi
- elif test -n "${NCURSES_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${NCURSES_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${NCURSES_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${NCURSES_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${NCURSES_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-NETSNMP_CONFIG=No
-if test "${USE_NETSNMP}" != "no"; then
- if test "x${NETSNMP_DIR}" != "x"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}net-snmp-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}net-snmp-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_NETSNMP_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $NETSNMP_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_NETSNMP_CONFIG="$NETSNMP_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in ${NETSNMP_DIR}/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_NETSNMP_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-NETSNMP_CONFIG=$ac_cv_path_NETSNMP_CONFIG
-if test -n "$NETSNMP_CONFIG"; then
- { echo "$as_me:$LINENO: result: $NETSNMP_CONFIG" >&5
-echo "${ECHO_T}$NETSNMP_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_NETSNMP_CONFIG"; then
- ac_pt_NETSNMP_CONFIG=$NETSNMP_CONFIG
- # Extract the first word of "net-snmp-config", so it can be a program name with args.
-set dummy net-snmp-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_NETSNMP_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_NETSNMP_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_NETSNMP_CONFIG="$ac_pt_NETSNMP_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in ${NETSNMP_DIR}/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_NETSNMP_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_NETSNMP_CONFIG=$ac_cv_path_ac_pt_NETSNMP_CONFIG
-if test -n "$ac_pt_NETSNMP_CONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_pt_NETSNMP_CONFIG" >&5
-echo "${ECHO_T}$ac_pt_NETSNMP_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_NETSNMP_CONFIG" = x; then
- NETSNMP_CONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- NETSNMP_CONFIG=$ac_pt_NETSNMP_CONFIG
- fi
-else
- NETSNMP_CONFIG="$ac_cv_path_NETSNMP_CONFIG"
-fi
-
- if test x"${NETSNMP_CONFIG}" = xNo; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** net-snmp-config was not found in the path you specified:" >&5
-echo "$as_me: *** net-snmp-config was not found in the path you specified:" >&6;}
- { echo "$as_me:$LINENO: *** ${NETSNMP_DIR}/bin" >&5
-echo "$as_me: *** ${NETSNMP_DIR}/bin" >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-netsnmp" >&5
-echo "$as_me: *** including --without-netsnmp" >&6;}
- exit 1
- fi
- else
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}net-snmp-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}net-snmp-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_NETSNMP_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $NETSNMP_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_NETSNMP_CONFIG="$NETSNMP_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_NETSNMP_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-NETSNMP_CONFIG=$ac_cv_path_NETSNMP_CONFIG
-if test -n "$NETSNMP_CONFIG"; then
- { echo "$as_me:$LINENO: result: $NETSNMP_CONFIG" >&5
-echo "${ECHO_T}$NETSNMP_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_NETSNMP_CONFIG"; then
- ac_pt_NETSNMP_CONFIG=$NETSNMP_CONFIG
- # Extract the first word of "net-snmp-config", so it can be a program name with args.
-set dummy net-snmp-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_NETSNMP_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_NETSNMP_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_NETSNMP_CONFIG="$ac_pt_NETSNMP_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_NETSNMP_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_NETSNMP_CONFIG=$ac_cv_path_ac_pt_NETSNMP_CONFIG
-if test -n "$ac_pt_NETSNMP_CONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_pt_NETSNMP_CONFIG" >&5
-echo "${ECHO_T}$ac_pt_NETSNMP_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_NETSNMP_CONFIG" = x; then
- NETSNMP_CONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- NETSNMP_CONFIG=$ac_pt_NETSNMP_CONFIG
- fi
-else
- NETSNMP_CONFIG="$ac_cv_path_NETSNMP_CONFIG"
-fi
-
- fi
-fi
-if test x"${NETSNMP_CONFIG}" != xNo; then
- NETSNMP_libs=`${NETSNMP_CONFIG} --agent-libs`
-
- { echo "$as_me:$LINENO: checking for snmp_register_callback in -lnetsnmp" >&5
-echo $ECHO_N "checking for snmp_register_callback in -lnetsnmp... $ECHO_C" >&6; }
-if test "${ac_cv_lib_netsnmp_snmp_register_callback+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnetsnmp ${NETSNMP_libs} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char snmp_register_callback ();
-int
-main ()
-{
-return snmp_register_callback ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_netsnmp_snmp_register_callback=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_netsnmp_snmp_register_callback=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_netsnmp_snmp_register_callback" >&5
-echo "${ECHO_T}$ac_cv_lib_netsnmp_snmp_register_callback" >&6; }
-if test $ac_cv_lib_netsnmp_snmp_register_callback = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_NETSNMP 1
-_ACEOF
-
-fi
-
-
- if test "${ac_cv_lib_netsnmp_snmp_register_callback}" = "yes"; then
- NETSNMP_LIB="${NETSNMP_libs}"
- PBX_NETSNMP=1
- elif test -n "${NETSNMP_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The Net-SNMP installation on this system appears to be broken." >&5
-echo "$as_me: *** The Net-SNMP installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-netsnmp" >&5
-echo "$as_me: *** including --without-netsnmp" >&6;}
- exit 1
- fi
-elif test -n "${NETSNMP_MANDATORY}";
-then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The Net-SNMP installation on this system appears to be broken." >&5
-echo "$as_me: *** The Net-SNMP installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-netsnmp" >&5
-echo "$as_me: *** including --without-netsnmp" >&6;}
- exit 1
-fi
-
-
-if test "${USE_NEWT}" != "no"; then
- pbxlibdir=""
- if test "x${NEWT_DIR}" != "x"; then
- if test -d ${NEWT_DIR}/lib; then
- pbxlibdir="-L${NEWT_DIR}/lib"
- else
- pbxlibdir="-L${NEWT_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for newtBell in -lnewt" >&5
-echo $ECHO_N "checking for newtBell in -lnewt... $ECHO_C" >&6; }
-if test "${ac_cv_lib_newt_newtBell+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnewt ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char newtBell ();
-int
-main ()
-{
-return newtBell ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_newt_newtBell=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_newt_newtBell=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_newt_newtBell" >&5
-echo "${ECHO_T}$ac_cv_lib_newt_newtBell" >&6; }
-if test $ac_cv_lib_newt_newtBell = yes; then
- AST_NEWT_FOUND=yes
-else
- AST_NEWT_FOUND=no
-fi
-
-
- if test "${AST_NEWT_FOUND}" = "yes"; then
- NEWT_LIB="-lnewt "
- NEWT_HEADER_FOUND="1"
- if test "x${NEWT_DIR}" != "x"; then
- NEWT_LIB="${pbxlibdir} ${NEWT_LIB}"
- NEWT_INCLUDE="-I${NEWT_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${NEWT_DIR}/include"
- if test "xnewt.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${NEWT_DIR}/include/newt.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${NEWT_DIR}/include/newt.h" >&5
-echo $ECHO_N "checking for ${NEWT_DIR}/include/newt.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${NEWT_DIR}/include/newt.h usability" >&5
-echo $ECHO_N "checking ${NEWT_DIR}/include/newt.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${NEWT_DIR}/include/newt.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${NEWT_DIR}/include/newt.h presence" >&5
-echo $ECHO_N "checking ${NEWT_DIR}/include/newt.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${NEWT_DIR}/include/newt.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${NEWT_DIR}/include/newt.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${NEWT_DIR}/include/newt.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${NEWT_DIR}/include/newt.h" >&5
-echo $ECHO_N "checking for ${NEWT_DIR}/include/newt.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- NEWT_HEADER_FOUND=1
-else
- NEWT_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xnewt.h" != "x" ; then
- if test "${ac_cv_header_newt_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for newt.h" >&5
-echo $ECHO_N "checking for newt.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_newt_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_newt_h" >&5
-echo "${ECHO_T}$ac_cv_header_newt_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking newt.h usability" >&5
-echo $ECHO_N "checking newt.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <newt.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking newt.h presence" >&5
-echo $ECHO_N "checking newt.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <newt.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: newt.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: newt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: newt.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: newt.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: newt.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: newt.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: newt.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: newt.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: newt.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: newt.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: newt.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: newt.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: newt.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: newt.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: newt.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: newt.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for newt.h" >&5
-echo $ECHO_N "checking for newt.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_newt_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_newt_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_newt_h" >&5
-echo "${ECHO_T}$ac_cv_header_newt_h" >&6; }
-
-fi
-if test $ac_cv_header_newt_h = yes; then
- NEWT_HEADER_FOUND=1
-else
- NEWT_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${NEWT_HEADER_FOUND}" = "x0" ; then
- if test -n "${NEWT_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the newt development package installed." >&5
-echo "$as_me: *** It appears that you do not have the newt development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${NEWT_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${NEWT_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${NEWT_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${NEWT_OPTION}" >&6;}
- exit 1
- fi
- NEWT_LIB=""
- NEWT_INCLUDE=""
- PBX_NEWT=0
- else
- PBX_NEWT=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_NEWT 1
-_ACEOF
-
- fi
- elif test -n "${NEWT_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${NEWT_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${NEWT_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${NEWT_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${NEWT_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_UNIXODBC}" != "no"; then
- pbxlibdir=""
- if test "x${UNIXODBC_DIR}" != "x"; then
- if test -d ${UNIXODBC_DIR}/lib; then
- pbxlibdir="-L${UNIXODBC_DIR}/lib"
- else
- pbxlibdir="-L${UNIXODBC_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for SQLConnect in -lodbc" >&5
-echo $ECHO_N "checking for SQLConnect in -lodbc... $ECHO_C" >&6; }
-if test "${ac_cv_lib_odbc_SQLConnect+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lodbc ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char SQLConnect ();
-int
-main ()
-{
-return SQLConnect ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_odbc_SQLConnect=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_odbc_SQLConnect=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_odbc_SQLConnect" >&5
-echo "${ECHO_T}$ac_cv_lib_odbc_SQLConnect" >&6; }
-if test $ac_cv_lib_odbc_SQLConnect = yes; then
- AST_UNIXODBC_FOUND=yes
-else
- AST_UNIXODBC_FOUND=no
-fi
-
-
- if test "${AST_UNIXODBC_FOUND}" = "yes"; then
- UNIXODBC_LIB="-lodbc "
- UNIXODBC_HEADER_FOUND="1"
- if test "x${UNIXODBC_DIR}" != "x"; then
- UNIXODBC_LIB="${pbxlibdir} ${UNIXODBC_LIB}"
- UNIXODBC_INCLUDE="-I${UNIXODBC_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${UNIXODBC_DIR}/include"
- if test "xsql.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${UNIXODBC_DIR}/include/sql.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${UNIXODBC_DIR}/include/sql.h" >&5
-echo $ECHO_N "checking for ${UNIXODBC_DIR}/include/sql.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${UNIXODBC_DIR}/include/sql.h usability" >&5
-echo $ECHO_N "checking ${UNIXODBC_DIR}/include/sql.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${UNIXODBC_DIR}/include/sql.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${UNIXODBC_DIR}/include/sql.h presence" >&5
-echo $ECHO_N "checking ${UNIXODBC_DIR}/include/sql.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${UNIXODBC_DIR}/include/sql.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${UNIXODBC_DIR}/include/sql.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${UNIXODBC_DIR}/include/sql.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${UNIXODBC_DIR}/include/sql.h" >&5
-echo $ECHO_N "checking for ${UNIXODBC_DIR}/include/sql.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- UNIXODBC_HEADER_FOUND=1
-else
- UNIXODBC_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xsql.h" != "x" ; then
- if test "${ac_cv_header_sql_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for sql.h" >&5
-echo $ECHO_N "checking for sql.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sql_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sql_h" >&5
-echo "${ECHO_T}$ac_cv_header_sql_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking sql.h usability" >&5
-echo $ECHO_N "checking sql.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sql.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking sql.h presence" >&5
-echo $ECHO_N "checking sql.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sql.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sql.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sql.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sql.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sql.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sql.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sql.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sql.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sql.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sql.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sql.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sql.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sql.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sql.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sql.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sql.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sql.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for sql.h" >&5
-echo $ECHO_N "checking for sql.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sql_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sql_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sql_h" >&5
-echo "${ECHO_T}$ac_cv_header_sql_h" >&6; }
-
-fi
-if test $ac_cv_header_sql_h = yes; then
- UNIXODBC_HEADER_FOUND=1
-else
- UNIXODBC_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${UNIXODBC_HEADER_FOUND}" = "x0" ; then
- if test -n "${UNIXODBC_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the odbc development package installed." >&5
-echo "$as_me: *** It appears that you do not have the odbc development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${UNIXODBC_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${UNIXODBC_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${UNIXODBC_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${UNIXODBC_OPTION}" >&6;}
- exit 1
- fi
- UNIXODBC_LIB=""
- UNIXODBC_INCLUDE=""
- PBX_UNIXODBC=0
- else
- PBX_UNIXODBC=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_UNIXODBC 1
-_ACEOF
-
- fi
- elif test -n "${UNIXODBC_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${UNIXODBC_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${UNIXODBC_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${UNIXODBC_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${UNIXODBC_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_OGG}" != "no"; then
- pbxlibdir=""
- if test "x${OGG_DIR}" != "x"; then
- if test -d ${OGG_DIR}/lib; then
- pbxlibdir="-L${OGG_DIR}/lib"
- else
- pbxlibdir="-L${OGG_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for ogg_sync_init in -logg" >&5
-echo $ECHO_N "checking for ogg_sync_init in -logg... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ogg_ogg_sync_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-logg ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ogg_sync_init ();
-int
-main ()
-{
-return ogg_sync_init ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ogg_ogg_sync_init=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ogg_ogg_sync_init=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ogg_ogg_sync_init" >&5
-echo "${ECHO_T}$ac_cv_lib_ogg_ogg_sync_init" >&6; }
-if test $ac_cv_lib_ogg_ogg_sync_init = yes; then
- AST_OGG_FOUND=yes
-else
- AST_OGG_FOUND=no
-fi
-
-
- if test "${AST_OGG_FOUND}" = "yes"; then
- OGG_LIB="-logg "
- OGG_HEADER_FOUND="1"
- if test "x${OGG_DIR}" != "x"; then
- OGG_LIB="${pbxlibdir} ${OGG_LIB}"
- OGG_INCLUDE="-I${OGG_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${OGG_DIR}/include"
- if test "x" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${OGG_DIR}/include/" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${OGG_DIR}/include/" >&5
-echo $ECHO_N "checking for ${OGG_DIR}/include/... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${OGG_DIR}/include/ usability" >&5
-echo $ECHO_N "checking ${OGG_DIR}/include/ usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${OGG_DIR}/include/>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${OGG_DIR}/include/ presence" >&5
-echo $ECHO_N "checking ${OGG_DIR}/include/ presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${OGG_DIR}/include/>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OGG_DIR}/include/: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${OGG_DIR}/include/: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${OGG_DIR}/include/" >&5
-echo $ECHO_N "checking for ${OGG_DIR}/include/... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- OGG_HEADER_FOUND=1
-else
- OGG_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "x" != "x" ; then
- if test "${ac_cv_header_+set}" = set; then
- { echo "$as_me:$LINENO: checking for " >&5
-echo $ECHO_N "checking for ... $ECHO_C" >&6; }
-if test "${ac_cv_header_+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_" >&5
-echo "${ECHO_T}$ac_cv_header_" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking usability" >&5
-echo $ECHO_N "checking usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking presence" >&5
-echo $ECHO_N "checking presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: : accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: : accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: : proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: : proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: : present but cannot be compiled" >&5
-echo "$as_me: WARNING: : present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: : check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: : check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: : see the Autoconf documentation" >&5
-echo "$as_me: WARNING: : see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: : section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: : section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: : proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: : proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: : in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: : in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for " >&5
-echo $ECHO_N "checking for ... $ECHO_C" >&6; }
-if test "${ac_cv_header_+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_" >&5
-echo "${ECHO_T}$ac_cv_header_" >&6; }
-
-fi
-if test $ac_cv_header_ = yes; then
- OGG_HEADER_FOUND=1
-else
- OGG_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${OGG_HEADER_FOUND}" = "x0" ; then
- if test -n "${OGG_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the ogg development package installed." >&5
-echo "$as_me: *** It appears that you do not have the ogg development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${OGG_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${OGG_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OGG_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OGG_OPTION}" >&6;}
- exit 1
- fi
- OGG_LIB=""
- OGG_INCLUDE=""
- PBX_OGG=0
- else
- PBX_OGG=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OGG 1
-_ACEOF
-
- fi
- elif test -n "${OGG_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${OGG_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${OGG_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OGG_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OGG_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${USE_OSS}" != "no"; then
-PBX_OSS=0
-if test "${ac_cv_header_linux_soundcard_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5
-echo $ECHO_N "checking for linux/soundcard.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_soundcard_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_soundcard_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking linux/soundcard.h usability" >&5
-echo $ECHO_N "checking linux/soundcard.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <linux/soundcard.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking linux/soundcard.h presence" >&5
-echo $ECHO_N "checking linux/soundcard.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <linux/soundcard.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: linux/soundcard.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: linux/soundcard.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5
-echo $ECHO_N "checking for linux/soundcard.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_soundcard_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_linux_soundcard_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_soundcard_h" >&6; }
-
-fi
-if test $ac_cv_header_linux_soundcard_h = yes; then
-
- PBX_OSS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OSS 1
-_ACEOF
-
-
-fi
-
-
-if test "$PBX_OSS" = "0"; then
- if test "${ac_cv_header_sys_soundcard_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for sys/soundcard.h" >&5
-echo $ECHO_N "checking for sys/soundcard.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sys_soundcard_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_soundcard_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_soundcard_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking sys/soundcard.h usability" >&5
-echo $ECHO_N "checking sys/soundcard.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sys/soundcard.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking sys/soundcard.h presence" >&5
-echo $ECHO_N "checking sys/soundcard.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/soundcard.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sys/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sys/soundcard.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sys/soundcard.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sys/soundcard.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sys/soundcard.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sys/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sys/soundcard.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/soundcard.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sys/soundcard.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for sys/soundcard.h" >&5
-echo $ECHO_N "checking for sys/soundcard.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sys_soundcard_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sys_soundcard_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_soundcard_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_soundcard_h" >&6; }
-
-fi
-if test $ac_cv_header_sys_soundcard_h = yes; then
-
- PBX_OSS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OSS 1
-_ACEOF
-
-
-fi
-
-
-fi
-if test "$PBX_OSS" = "0"; then
-
-if test "${USE_OSS}" != "no"; then
- pbxlibdir=""
- if test "x${OSS_DIR}" != "x"; then
- if test -d ${OSS_DIR}/lib; then
- pbxlibdir="-L${OSS_DIR}/lib"
- else
- pbxlibdir="-L${OSS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for oss_ioctl_mixer in -lossaudio" >&5
-echo $ECHO_N "checking for oss_ioctl_mixer in -lossaudio... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ossaudio_oss_ioctl_mixer+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lossaudio ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char oss_ioctl_mixer ();
-int
-main ()
-{
-return oss_ioctl_mixer ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ossaudio_oss_ioctl_mixer=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ossaudio_oss_ioctl_mixer=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ossaudio_oss_ioctl_mixer" >&5
-echo "${ECHO_T}$ac_cv_lib_ossaudio_oss_ioctl_mixer" >&6; }
-if test $ac_cv_lib_ossaudio_oss_ioctl_mixer = yes; then
- AST_OSS_FOUND=yes
-else
- AST_OSS_FOUND=no
-fi
-
-
- if test "${AST_OSS_FOUND}" = "yes"; then
- OSS_LIB="-lossaudio "
- OSS_HEADER_FOUND="1"
- if test "x${OSS_DIR}" != "x"; then
- OSS_LIB="${pbxlibdir} ${OSS_LIB}"
- OSS_INCLUDE="-I${OSS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${OSS_DIR}/include"
- if test "xsoundcard.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${OSS_DIR}/include/soundcard.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${OSS_DIR}/include/soundcard.h" >&5
-echo $ECHO_N "checking for ${OSS_DIR}/include/soundcard.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${OSS_DIR}/include/soundcard.h usability" >&5
-echo $ECHO_N "checking ${OSS_DIR}/include/soundcard.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${OSS_DIR}/include/soundcard.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${OSS_DIR}/include/soundcard.h presence" >&5
-echo $ECHO_N "checking ${OSS_DIR}/include/soundcard.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${OSS_DIR}/include/soundcard.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSS_DIR}/include/soundcard.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${OSS_DIR}/include/soundcard.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${OSS_DIR}/include/soundcard.h" >&5
-echo $ECHO_N "checking for ${OSS_DIR}/include/soundcard.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- OSS_HEADER_FOUND=1
-else
- OSS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xsoundcard.h" != "x" ; then
- if test "${ac_cv_header_soundcard_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for soundcard.h" >&5
-echo $ECHO_N "checking for soundcard.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_soundcard_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_soundcard_h" >&5
-echo "${ECHO_T}$ac_cv_header_soundcard_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking soundcard.h usability" >&5
-echo $ECHO_N "checking soundcard.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <soundcard.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking soundcard.h presence" >&5
-echo $ECHO_N "checking soundcard.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <soundcard.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: soundcard.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: soundcard.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: soundcard.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: soundcard.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: soundcard.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: soundcard.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: soundcard.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: soundcard.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: soundcard.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: soundcard.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: soundcard.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: soundcard.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: soundcard.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for soundcard.h" >&5
-echo $ECHO_N "checking for soundcard.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_soundcard_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_soundcard_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_soundcard_h" >&5
-echo "${ECHO_T}$ac_cv_header_soundcard_h" >&6; }
-
-fi
-if test $ac_cv_header_soundcard_h = yes; then
- OSS_HEADER_FOUND=1
-else
- OSS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${OSS_HEADER_FOUND}" = "x0" ; then
- if test -n "${OSS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the ossaudio development package installed." >&5
-echo "$as_me: *** It appears that you do not have the ossaudio development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${OSS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${OSS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OSS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OSS_OPTION}" >&6;}
- exit 1
- fi
- OSS_LIB=""
- OSS_INCLUDE=""
- PBX_OSS=0
- else
- PBX_OSS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OSS 1
-_ACEOF
-
- fi
- elif test -n "${OSS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${OSS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${OSS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OSS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OSS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-fi
-fi
-
-PG_CONFIG=No
-if test "${USE_PGSQL}" != "no"; then
- if test "x${PGSQL_DIR}" != "x"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}pg_config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pg_config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_PG_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in ${PGSQL_DIR}/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-PG_CONFIG=$ac_cv_path_PG_CONFIG
-if test -n "$PG_CONFIG"; then
- { echo "$as_me:$LINENO: result: $PG_CONFIG" >&5
-echo "${ECHO_T}$PG_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_PG_CONFIG"; then
- ac_pt_PG_CONFIG=$PG_CONFIG
- # Extract the first word of "pg_config", so it can be a program name with args.
-set dummy pg_config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_PG_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_PG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_PG_CONFIG="$ac_pt_PG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in ${PGSQL_DIR}/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_PG_CONFIG=$ac_cv_path_ac_pt_PG_CONFIG
-if test -n "$ac_pt_PG_CONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_pt_PG_CONFIG" >&5
-echo "${ECHO_T}$ac_pt_PG_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_PG_CONFIG" = x; then
- PG_CONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- PG_CONFIG=$ac_pt_PG_CONFIG
- fi
-else
- PG_CONFIG="$ac_cv_path_PG_CONFIG"
-fi
-
- if test x"${PG_CONFIG}" = xNo; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** pg_config was not found in the path you specified:" >&5
-echo "$as_me: *** pg_config was not found in the path you specified:" >&6;}
- { echo "$as_me:$LINENO: *** ${PGSQL_DIR}/bin" >&5
-echo "$as_me: *** ${PGSQL_DIR}/bin" >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-postgres" >&5
-echo "$as_me: *** including --without-postgres" >&6;}
- exit 1
- fi
- else
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}pg_config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pg_config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_PG_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-PG_CONFIG=$ac_cv_path_PG_CONFIG
-if test -n "$PG_CONFIG"; then
- { echo "$as_me:$LINENO: result: $PG_CONFIG" >&5
-echo "${ECHO_T}$PG_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_PG_CONFIG"; then
- ac_pt_PG_CONFIG=$PG_CONFIG
- # Extract the first word of "pg_config", so it can be a program name with args.
-set dummy pg_config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_PG_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_PG_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_PG_CONFIG="$ac_pt_PG_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_PG_CONFIG=$ac_cv_path_ac_pt_PG_CONFIG
-if test -n "$ac_pt_PG_CONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_pt_PG_CONFIG" >&5
-echo "${ECHO_T}$ac_pt_PG_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_PG_CONFIG" = x; then
- PG_CONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- PG_CONFIG=$ac_pt_PG_CONFIG
- fi
-else
- PG_CONFIG="$ac_cv_path_PG_CONFIG"
-fi
-
- fi
-fi
-if test "${PG_CONFIG}" != No; then
- PGSQL_libdir=`${PG_CONFIG} --libdir`
- PGSQL_includedir=`${PG_CONFIG} --includedir`
-
- if test "x$?" != "x0" ; then
- if test -n "${PGSQL_MANDATORY}" ; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The PostgreSQL installation on this system appears to be broken." >&5
-echo "$as_me: *** The PostgreSQL installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-postgres" >&5
-echo "$as_me: *** including --without-postgres" >&6;}
- exit 1
- fi
- else
- { echo "$as_me:$LINENO: checking for PQescapeStringConn in -lpq" >&5
-echo $ECHO_N "checking for PQescapeStringConn in -lpq... $ECHO_C" >&6; }
-if test "${ac_cv_lib_pq_PQescapeStringConn+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpq -L${PGSQL_libdir} -lz $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char PQescapeStringConn ();
-int
-main ()
-{
-return PQescapeStringConn ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_pq_PQescapeStringConn=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_pq_PQescapeStringConn=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_pq_PQescapeStringConn" >&5
-echo "${ECHO_T}$ac_cv_lib_pq_PQescapeStringConn" >&6; }
-if test $ac_cv_lib_pq_PQescapeStringConn = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PGSQL 1
-_ACEOF
-
-fi
-
-
- if test "${ac_cv_lib_pq_PQescapeStringConn}" = "yes"; then
- PGSQL_LIB="-L${PGSQL_libdir} -lpq -lz"
- PGSQL_INCLUDE="-I${PGSQL_includedir}"
- PBX_PGSQL=1
- elif test -n "${PGSQL_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The PostgreSQL installation on this system appears to be broken." >&5
-echo "$as_me: *** The PostgreSQL installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-postgres" >&5
-echo "$as_me: *** including --without-postgres" >&6;}
- exit 1
- fi
- fi
-elif test -n "${PGSQL_MANDATORY}";
-then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The PostgreSQL installation on this system appears to be broken." >&5
-echo "$as_me: *** The PostgreSQL installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-postgres" >&5
-echo "$as_me: *** including --without-postgres" >&6;}
- exit 1
-fi
-
-
-if test "${USE_POPT}" != "no"; then
- pbxlibdir=""
- if test "x${POPT_DIR}" != "x"; then
- if test -d ${POPT_DIR}/lib; then
- pbxlibdir="-L${POPT_DIR}/lib"
- else
- pbxlibdir="-L${POPT_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for poptStrerror in -lpopt" >&5
-echo $ECHO_N "checking for poptStrerror in -lpopt... $ECHO_C" >&6; }
-if test "${ac_cv_lib_popt_poptStrerror+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpopt ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char poptStrerror ();
-int
-main ()
-{
-return poptStrerror ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_popt_poptStrerror=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_popt_poptStrerror=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_popt_poptStrerror" >&5
-echo "${ECHO_T}$ac_cv_lib_popt_poptStrerror" >&6; }
-if test $ac_cv_lib_popt_poptStrerror = yes; then
- AST_POPT_FOUND=yes
-else
- AST_POPT_FOUND=no
-fi
-
-
- if test "${AST_POPT_FOUND}" = "yes"; then
- POPT_LIB="-lpopt "
- POPT_HEADER_FOUND="1"
- if test "x${POPT_DIR}" != "x"; then
- POPT_LIB="${pbxlibdir} ${POPT_LIB}"
- POPT_INCLUDE="-I${POPT_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${POPT_DIR}/include"
- if test "xpopt.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${POPT_DIR}/include/popt.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${POPT_DIR}/include/popt.h" >&5
-echo $ECHO_N "checking for ${POPT_DIR}/include/popt.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${POPT_DIR}/include/popt.h usability" >&5
-echo $ECHO_N "checking ${POPT_DIR}/include/popt.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${POPT_DIR}/include/popt.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${POPT_DIR}/include/popt.h presence" >&5
-echo $ECHO_N "checking ${POPT_DIR}/include/popt.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${POPT_DIR}/include/popt.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${POPT_DIR}/include/popt.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${POPT_DIR}/include/popt.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${POPT_DIR}/include/popt.h" >&5
-echo $ECHO_N "checking for ${POPT_DIR}/include/popt.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- POPT_HEADER_FOUND=1
-else
- POPT_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xpopt.h" != "x" ; then
- if test "${ac_cv_header_popt_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for popt.h" >&5
-echo $ECHO_N "checking for popt.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_popt_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_popt_h" >&5
-echo "${ECHO_T}$ac_cv_header_popt_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking popt.h usability" >&5
-echo $ECHO_N "checking popt.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <popt.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking popt.h presence" >&5
-echo $ECHO_N "checking popt.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <popt.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: popt.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: popt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: popt.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: popt.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: popt.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: popt.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: popt.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: popt.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: popt.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: popt.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: popt.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: popt.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: popt.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: popt.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: popt.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: popt.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for popt.h" >&5
-echo $ECHO_N "checking for popt.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_popt_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_popt_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_popt_h" >&5
-echo "${ECHO_T}$ac_cv_header_popt_h" >&6; }
-
-fi
-if test $ac_cv_header_popt_h = yes; then
- POPT_HEADER_FOUND=1
-else
- POPT_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${POPT_HEADER_FOUND}" = "x0" ; then
- if test -n "${POPT_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the popt development package installed." >&5
-echo "$as_me: *** It appears that you do not have the popt development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${POPT_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${POPT_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${POPT_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${POPT_OPTION}" >&6;}
- exit 1
- fi
- POPT_LIB=""
- POPT_INCLUDE=""
- PBX_POPT=0
- else
- PBX_POPT=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_POPT 1
-_ACEOF
-
- fi
- elif test -n "${POPT_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${POPT_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${POPT_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${POPT_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${POPT_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_PRI}" != "no"; then
- pbxlibdir=""
- if test "x${PRI_DIR}" != "x"; then
- if test -d ${PRI_DIR}/lib; then
- pbxlibdir="-L${PRI_DIR}/lib"
- else
- pbxlibdir="-L${PRI_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for pri_keypad_facility in -lpri" >&5
-echo $ECHO_N "checking for pri_keypad_facility in -lpri... $ECHO_C" >&6; }
-if test "${ac_cv_lib_pri_pri_keypad_facility+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpri ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pri_keypad_facility ();
-int
-main ()
-{
-return pri_keypad_facility ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_pri_pri_keypad_facility=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_pri_pri_keypad_facility=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_pri_pri_keypad_facility" >&5
-echo "${ECHO_T}$ac_cv_lib_pri_pri_keypad_facility" >&6; }
-if test $ac_cv_lib_pri_pri_keypad_facility = yes; then
- AST_PRI_FOUND=yes
-else
- AST_PRI_FOUND=no
-fi
-
-
- if test "${AST_PRI_FOUND}" = "yes"; then
- PRI_LIB="-lpri "
- PRI_HEADER_FOUND="1"
- if test "x${PRI_DIR}" != "x"; then
- PRI_LIB="${pbxlibdir} ${PRI_LIB}"
- PRI_INCLUDE="-I${PRI_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${PRI_DIR}/include"
- if test "xlibpri.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${PRI_DIR}/include/libpri.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${PRI_DIR}/include/libpri.h" >&5
-echo $ECHO_N "checking for ${PRI_DIR}/include/libpri.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${PRI_DIR}/include/libpri.h usability" >&5
-echo $ECHO_N "checking ${PRI_DIR}/include/libpri.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${PRI_DIR}/include/libpri.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${PRI_DIR}/include/libpri.h presence" >&5
-echo $ECHO_N "checking ${PRI_DIR}/include/libpri.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${PRI_DIR}/include/libpri.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${PRI_DIR}/include/libpri.h" >&5
-echo $ECHO_N "checking for ${PRI_DIR}/include/libpri.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- PRI_HEADER_FOUND=1
-else
- PRI_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xlibpri.h" != "x" ; then
- if test "${ac_cv_header_libpri_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for libpri.h" >&5
-echo $ECHO_N "checking for libpri.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libpri_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libpri_h" >&5
-echo "${ECHO_T}$ac_cv_header_libpri_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking libpri.h usability" >&5
-echo $ECHO_N "checking libpri.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <libpri.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking libpri.h presence" >&5
-echo $ECHO_N "checking libpri.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <libpri.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: libpri.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: libpri.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: libpri.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: libpri.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: libpri.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: libpri.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: libpri.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: libpri.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: libpri.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: libpri.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for libpri.h" >&5
-echo $ECHO_N "checking for libpri.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libpri_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_libpri_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libpri_h" >&5
-echo "${ECHO_T}$ac_cv_header_libpri_h" >&6; }
-
-fi
-if test $ac_cv_header_libpri_h = yes; then
- PRI_HEADER_FOUND=1
-else
- PRI_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${PRI_HEADER_FOUND}" = "x0" ; then
- if test -n "${PRI_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the pri development package installed." >&5
-echo "$as_me: *** It appears that you do not have the pri development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${PRI_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${PRI_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${PRI_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${PRI_OPTION}" >&6;}
- exit 1
- fi
- PRI_LIB=""
- PRI_INCLUDE=""
- PBX_PRI=0
- else
- PBX_PRI=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PRI 1
-_ACEOF
-
- fi
- elif test -n "${PRI_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${PRI_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${PRI_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${PRI_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${PRI_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_PRI_VERSION}" != "no"; then
- pbxlibdir=""
- if test "x${PRI_VERSION_DIR}" != "x"; then
- if test -d ${PRI_VERSION_DIR}/lib; then
- pbxlibdir="-L${PRI_VERSION_DIR}/lib"
- else
- pbxlibdir="-L${PRI_VERSION_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for pri_get_version in -lpri" >&5
-echo $ECHO_N "checking for pri_get_version in -lpri... $ECHO_C" >&6; }
-if test "${ac_cv_lib_pri_pri_get_version+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpri ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pri_get_version ();
-int
-main ()
-{
-return pri_get_version ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_pri_pri_get_version=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_pri_pri_get_version=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_pri_pri_get_version" >&5
-echo "${ECHO_T}$ac_cv_lib_pri_pri_get_version" >&6; }
-if test $ac_cv_lib_pri_pri_get_version = yes; then
- AST_PRI_VERSION_FOUND=yes
-else
- AST_PRI_VERSION_FOUND=no
-fi
-
-
- if test "${AST_PRI_VERSION_FOUND}" = "yes"; then
- PRI_VERSION_LIB="-lpri "
- PRI_VERSION_HEADER_FOUND="1"
- if test "x${PRI_VERSION_DIR}" != "x"; then
- PRI_VERSION_LIB="${pbxlibdir} ${PRI_VERSION_LIB}"
- PRI_VERSION_INCLUDE="-I${PRI_VERSION_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${PRI_VERSION_DIR}/include"
- if test "xlibpri.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${PRI_VERSION_DIR}/include/libpri.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${PRI_VERSION_DIR}/include/libpri.h" >&5
-echo $ECHO_N "checking for ${PRI_VERSION_DIR}/include/libpri.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${PRI_VERSION_DIR}/include/libpri.h usability" >&5
-echo $ECHO_N "checking ${PRI_VERSION_DIR}/include/libpri.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${PRI_VERSION_DIR}/include/libpri.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${PRI_VERSION_DIR}/include/libpri.h presence" >&5
-echo $ECHO_N "checking ${PRI_VERSION_DIR}/include/libpri.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${PRI_VERSION_DIR}/include/libpri.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${PRI_VERSION_DIR}/include/libpri.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${PRI_VERSION_DIR}/include/libpri.h" >&5
-echo $ECHO_N "checking for ${PRI_VERSION_DIR}/include/libpri.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- PRI_VERSION_HEADER_FOUND=1
-else
- PRI_VERSION_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xlibpri.h" != "x" ; then
- if test "${ac_cv_header_libpri_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for libpri.h" >&5
-echo $ECHO_N "checking for libpri.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libpri_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libpri_h" >&5
-echo "${ECHO_T}$ac_cv_header_libpri_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking libpri.h usability" >&5
-echo $ECHO_N "checking libpri.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <libpri.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking libpri.h presence" >&5
-echo $ECHO_N "checking libpri.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <libpri.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: libpri.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: libpri.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: libpri.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: libpri.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: libpri.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: libpri.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: libpri.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: libpri.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: libpri.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: libpri.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: libpri.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for libpri.h" >&5
-echo $ECHO_N "checking for libpri.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libpri_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_libpri_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libpri_h" >&5
-echo "${ECHO_T}$ac_cv_header_libpri_h" >&6; }
-
-fi
-if test $ac_cv_header_libpri_h = yes; then
- PRI_VERSION_HEADER_FOUND=1
-else
- PRI_VERSION_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${PRI_VERSION_HEADER_FOUND}" = "x0" ; then
- if test -n "${PRI_VERSION_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the pri development package installed." >&5
-echo "$as_me: *** It appears that you do not have the pri development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${PRI_VERSION_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${PRI_VERSION_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${PRI_VERSION_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${PRI_VERSION_OPTION}" >&6;}
- exit 1
- fi
- PRI_VERSION_LIB=""
- PRI_VERSION_INCLUDE=""
- PBX_PRI_VERSION=0
- else
- PBX_PRI_VERSION=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PRI_VERSION 1
-_ACEOF
-
- fi
- elif test -n "${PRI_VERSION_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${PRI_VERSION_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${PRI_VERSION_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${PRI_VERSION_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${PRI_VERSION_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${USE_PWLIB}" != "no"; then
- if test -n "${PWLIB_DIR}"; then
- PWLIBDIR="${PWLIB_DIR}"
- fi
-
-
-PWLIB_INCDIR=
-PWLIB_LIBDIR=
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-if test "${PWLIBDIR:-unset}" != "unset" ; then
- as_ac_Header=`echo "ac_cv_header_${PWLIBDIR}/version.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${PWLIBDIR}/version.h" >&5
-echo $ECHO_N "checking for ${PWLIBDIR}/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${PWLIBDIR}/version.h usability" >&5
-echo $ECHO_N "checking ${PWLIBDIR}/version.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${PWLIBDIR}/version.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${PWLIBDIR}/version.h presence" >&5
-echo $ECHO_N "checking ${PWLIBDIR}/version.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${PWLIBDIR}/version.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/version.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/version.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${PWLIBDIR}/version.h" >&5
-echo $ECHO_N "checking for ${PWLIBDIR}/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- HAS_PWLIB=1
-fi
-
-
-fi
-if test "${HAS_PWLIB:-unset}" = "unset" ; then
- if test "${OPENH323DIR:-unset}" != "unset"; then
- as_ac_Header=`echo "ac_cv_header_${OPENH323DIR}/../pwlib/version.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${OPENH323DIR}/../pwlib/version.h" >&5
-echo $ECHO_N "checking for ${OPENH323DIR}/../pwlib/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${OPENH323DIR}/../pwlib/version.h usability" >&5
-echo $ECHO_N "checking ${OPENH323DIR}/../pwlib/version.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${OPENH323DIR}/../pwlib/version.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${OPENH323DIR}/../pwlib/version.h presence" >&5
-echo $ECHO_N "checking ${OPENH323DIR}/../pwlib/version.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${OPENH323DIR}/../pwlib/version.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/../pwlib/version.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/../pwlib/version.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${OPENH323DIR}/../pwlib/version.h" >&5
-echo $ECHO_N "checking for ${OPENH323DIR}/../pwlib/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- HAS_PWLIB=1
-fi
-
-
- fi
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- PWLIBDIR="${OPENH323DIR}/../pwlib"
- else
- as_ac_Header=`echo "ac_cv_header_${HOME}/pwlib/include/ptlib.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${HOME}/pwlib/include/ptlib.h" >&5
-echo $ECHO_N "checking for ${HOME}/pwlib/include/ptlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${HOME}/pwlib/include/ptlib.h usability" >&5
-echo $ECHO_N "checking ${HOME}/pwlib/include/ptlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${HOME}/pwlib/include/ptlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${HOME}/pwlib/include/ptlib.h presence" >&5
-echo $ECHO_N "checking ${HOME}/pwlib/include/ptlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${HOME}/pwlib/include/ptlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/pwlib/include/ptlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${HOME}/pwlib/include/ptlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${HOME}/pwlib/include/ptlib.h" >&5
-echo $ECHO_N "checking for ${HOME}/pwlib/include/ptlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- HAS_PWLIB=1
-fi
-
-
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- PWLIBDIR="${HOME}/pwlib"
- else
- if test "${ac_cv_header__usr_local_include_ptlib_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for /usr/local/include/ptlib.h" >&5
-echo $ECHO_N "checking for /usr/local/include/ptlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_local_include_ptlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_local_include_ptlib_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_local_include_ptlib_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking /usr/local/include/ptlib.h usability" >&5
-echo $ECHO_N "checking /usr/local/include/ptlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include </usr/local/include/ptlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking /usr/local/include/ptlib.h presence" >&5
-echo $ECHO_N "checking /usr/local/include/ptlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include </usr/local/include/ptlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/ptlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: /usr/local/include/ptlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for /usr/local/include/ptlib.h" >&5
-echo $ECHO_N "checking for /usr/local/include/ptlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_local_include_ptlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header__usr_local_include_ptlib_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_local_include_ptlib_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_local_include_ptlib_h" >&6; }
-
-fi
-if test $ac_cv_header__usr_local_include_ptlib_h = yes; then
- HAS_PWLIB=1
-fi
-
-
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- # Extract the first word of "ptlib-config", so it can be a program name with args.
-set dummy ptlib-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_PTLIB_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PTLIB_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PTLIB_CONFIG="$PTLIB_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/local/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_PTLIB_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-PTLIB_CONFIG=$ac_cv_path_PTLIB_CONFIG
-if test -n "$PTLIB_CONFIG"; then
- { echo "$as_me:$LINENO: result: $PTLIB_CONFIG" >&5
-echo "${ECHO_T}$PTLIB_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- if test "${PTLIB_CONFIG:-unset}" = "unset" ; then
- # Extract the first word of "ptlib-config", so it can be a program name with args.
-set dummy ptlib-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_PTLIB_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PTLIB_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PTLIB_CONFIG="$PTLIB_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/local/share/pwlib/make
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_PTLIB_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-PTLIB_CONFIG=$ac_cv_path_PTLIB_CONFIG
-if test -n "$PTLIB_CONFIG"; then
- { echo "$as_me:$LINENO: result: $PTLIB_CONFIG" >&5
-echo "${ECHO_T}$PTLIB_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- fi
- PWLIB_INCDIR="/usr/local/include"
- PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir`
- if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/local/lib64"
- else
- PWLIB_LIBDIR="/usr/local/lib"
- fi
- fi
- PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs`
- PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`"
- else
- if test "${ac_cv_header__usr_include_ptlib_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for /usr/include/ptlib.h" >&5
-echo $ECHO_N "checking for /usr/include/ptlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_include_ptlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_include_ptlib_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_include_ptlib_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking /usr/include/ptlib.h usability" >&5
-echo $ECHO_N "checking /usr/include/ptlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include </usr/include/ptlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking /usr/include/ptlib.h presence" >&5
-echo $ECHO_N "checking /usr/include/ptlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include </usr/include/ptlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/include/ptlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: /usr/include/ptlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for /usr/include/ptlib.h" >&5
-echo $ECHO_N "checking for /usr/include/ptlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_include_ptlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header__usr_include_ptlib_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_include_ptlib_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_include_ptlib_h" >&6; }
-
-fi
-if test $ac_cv_header__usr_include_ptlib_h = yes; then
- HAS_PWLIB=1
-fi
-
-
- if test "${HAS_PWLIB:-unset}" != "unset" ; then
- # Extract the first word of "ptlib-config", so it can be a program name with args.
-set dummy ptlib-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_PTLIB_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PTLIB_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PTLIB_CONFIG="$PTLIB_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/share/pwlib/make
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_PTLIB_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-PTLIB_CONFIG=$ac_cv_path_PTLIB_CONFIG
-if test -n "$PTLIB_CONFIG"; then
- { echo "$as_me:$LINENO: result: $PTLIB_CONFIG" >&5
-echo "${ECHO_T}$PTLIB_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- PWLIB_INCDIR="/usr/include"
- PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir`
- if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/lib64"
- else
- PWLIB_LIBDIR="/usr/lib"
- fi
- fi
- PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs`
- PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`"
- fi
- fi
- fi
- fi
-fi
-
-#if test "${HAS_PWLIB:-unset}" = "unset" ; then
-# echo "Cannot find pwlib - please install or set PWLIBDIR and try again"
-# exit
-#fi
-
-if test "${HAS_PWLIB:-unset}" != "unset" ; then
- if test "${PWLIBDIR:-unset}" = "unset" ; then
- if test "${PTLIB_CONFIG:-unset}" != "unset" ; then
- PWLIBDIR=`$PTLIB_CONFIG --prefix`
- else
- echo "Cannot find ptlib-config - please install and try again"
- exit
- fi
- fi
-
- if test "x$PWLIBDIR" = "x/usr" -o "x$PWLIBDIR" = "x/usr/"; then
- PWLIBDIR="/usr/share/pwlib"
- PWLIB_INCDIR="/usr/include"
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/lib64"
- else
- PWLIB_LIBDIR="/usr/lib"
- fi
- fi
- if test "x$PWLIBDIR" = "x/usr/local" -o "x$PWLIBDIR" = "x/usr/"; then
- PWLIBDIR="/usr/local/share/pwlib"
- PWLIB_INCDIR="/usr/local/include"
- if test "x$LIB64" != "x"; then
- PWLIB_LIBDIR="/usr/local/lib64"
- else
- PWLIB_LIBDIR="/usr/local/lib"
- fi
- fi
-
- if test "${PWLIB_INCDIR:-unset}" = "unset"; then
- PWLIB_INCDIR="${PWLIBDIR}/include"
- fi
- if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
- PWLIB_LIBDIR="${PWLIBDIR}/lib"
- fi
-
-
-
-
-fi
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
- if test "${HAS_PWLIB:-unset}" != "unset"; then
- PWLIB_VERSION=`grep "PWLIB_VERSION" ${PWLIB_INCDIR}/ptbuildopts.h | cut -f2 -d ' ' | sed -e 's/"//g'`
- PWLIB_MAJOR_VERSION=`echo ${PWLIB_VERSION} | cut -f1 -d.`
- PWLIB_MINOR_VERSION=`echo ${PWLIB_VERSION} | cut -f2 -d.`
- PWLIB_BUILD_NUMBER=`echo ${PWLIB_VERSION} | cut -f3 -d.`
- let PWLIB_VER=${PWLIB_MAJOR_VERSION}*10000+${PWLIB_MINOR_VERSION}*100+${PWLIB_BUILD_NUMBER}
- let PWLIB_REQ=1*10000+9*100+2
-
- { echo "$as_me:$LINENO: checking if PWLib version ${PWLIB_VERSION} is compatible with chan_h323" >&5
-echo $ECHO_N "checking if PWLib version ${PWLIB_VERSION} is compatible with chan_h323... $ECHO_C" >&6; }
- if test ${PWLIB_VER} -lt ${PWLIB_REQ}; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- unset HAS_PWLIB
- else
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- fi
- fi
-
-
- if test "${HAS_PWLIB:-unset}" != "unset"; then
-
-PWLIB_OSTYPE=
-case "$host_os" in
- linux*) PWLIB_OSTYPE=linux ;
- ;;
- freebsd* ) PWLIB_OSTYPE=FreeBSD ;
- ;;
- openbsd* ) PWLIB_OSTYPE=OpenBSD ;
- ENDLDLIBS="-lossaudio" ;
- ;;
- netbsd* ) PWLIB_OSTYPE=NetBSD ;
- ENDLDLIBS="-lossaudio" ;
- ;;
- solaris* | sunos* ) PWLIB_OSTYPE=solaris ;
- ;;
- darwin* ) PWLIB_OSTYPE=Darwin ;
- ;;
- beos*) PWLIB_OSTYPE=beos ;
- STDCCFLAGS="$STDCCFLAGS -D__BEOS__"
- ;;
- cygwin*) PWLIB_OSTYPE=cygwin ;
- ;;
- mingw*) PWLIB_OSTYPE=mingw ;
- STDCCFLAGS="$STDCCFLAGS -mms-bitfields" ;
- ENDLDLIBS="-lwinmm -lwsock32 -lsnmpapi -lmpr -lcomdlg32 -lgdi32 -lavicap32" ;
- ;;
- * ) PWLIB_OSTYPE="$host_os" ;
- { echo "$as_me:$LINENO: WARNING: \"OS $PWLIB_OSTYPE not recognized - proceed with caution!\"" >&5
-echo "$as_me: WARNING: \"OS $PWLIB_OSTYPE not recognized - proceed with caution!\"" >&2;} ;
- ;;
-esac
-
-PWLIB_MACHTYPE=
-case "$host_cpu" in
- x86 | i686 | i586 | i486 | i386 ) PWLIB_MACHTYPE=x86
- ;;
-
- x86_64) PWLIB_MACHTYPE=x86_64 ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- alpha | alphaev56 | alphaev6 | alphaev67 | alphaev7) PWLIB_MACHTYPE=alpha ;
- P_64BIT=1 ;
- ;;
-
- sparc ) PWLIB_MACHTYPE=sparc ;
- ;;
-
- powerpc ) PWLIB_MACHTYPE=ppc ;
- ;;
-
- ppc ) PWLIB_MACHTYPE=ppc ;
- ;;
-
- powerpc64 ) PWLIB_MACHTYPE=ppc64 ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- ppc64 ) PWLIB_MACHTYPE=ppc64 ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- ia64) PWLIB_MACHTYPE=ia64 ;
- P_64BIT=1 ;
- ;;
-
- s390x) PWLIB_MACHTYPE=s390x ;
- P_64BIT=1 ;
- LIB64=1 ;
- ;;
-
- s390) PWLIB_MACHTYPE=s390 ;
- ;;
-
- * ) PWLIB_MACHTYPE="$host_cpu";
- { echo "$as_me:$LINENO: WARNING: \"CPU $PWLIB_MACHTYPE not recognized - proceed with caution!\"" >&5
-echo "$as_me: WARNING: \"CPU $PWLIB_MACHTYPE not recognized - proceed with caution!\"" >&2;} ;;
-esac
-
-PWLIB_PLATFORM="${PWLIB_OSTYPE}_${PWLIB_MACHTYPE}"
-
-
-
-
- PLATFORM_PWLIB="pt_${PWLIB_PLATFORM}_r"
-
-
- if test "${HAS_PWLIB:-unset}" != "unset"; then
- { echo "$as_me:$LINENO: checking PWLib installation validity" >&5
-echo $ECHO_N "checking PWLib installation validity... $ECHO_C" >&6; }
-
- saved_cppflags="${CPPFLAGS}"
- saved_libs="${LIBS}"
- if test "${PWLIB_LIB:-unset}" != "unset"; then
- LIBS="${LIBS} ${PWLIB_LIB} "
- else
- LIBS="${LIBS} -L${PWLIB_LIBDIR} -l${PLATFORM_PWLIB} "
- fi
- CPPFLAGS="${CPPFLAGS} -I${PWLIB_INCDIR} "
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "ptlib.h"
-int
-main ()
-{
-BOOL q = PTime::IsDaylightSavings();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_lib_PWLIB="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_lib_PWLIB="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
-
- if test "${ac_cv_lib_PWLIB}" = "yes"; then
- if test "${PWLIB_LIB:-undef}" = "undef"; then
- if test "${PWLIB_LIBDIR}" != "" -a "${PWLIB_LIBDIR}" != "/usr/lib"; then
- PWLIB_LIB="-L${PWLIB_LIBDIR} -l${PLATFORM_PWLIB}"
- else
- PWLIB_LIB="-l${PLATFORM_PWLIB}"
- fi
- fi
- if test "${PWLIB_INCDIR}" != "" -a "${PWLIB_INCDIR}" != "/usr/include"; then
- PWLIB_INCLUDE="-I${PWLIB_INCDIR}"
- fi
- PBX_PWLIB=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_PWLIB 1
-_ACEOF
-
- fi
- fi
-
- fi
-fi
-
-if test "${USE_PWLIB}" != "no" -a "x${ac_cv_lib_PWLIB}" != "xyes" -a -n "${PWLIB_MANDATORY}"; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The PWLIB installation on this system appears to be broken." >&5
-echo "$as_me: *** The PWLIB installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-pwlib" >&5
-echo "$as_me: *** including --without-pwlib" >&6;}
- exit 1
-fi
-
-if test "${PBX_PWLIB}" = "1" -a "${USE_OPENH323}" != "no" ; then
- if test -n "${OPENH323_DIR}"; then
- OPENH323DIR="${OPENH323_DIR}"
- fi
-
-OPENH323_INCDIR=
-OPENH323_LIBDIR=
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-if test "${OPENH323DIR:-unset}" != "unset" ; then
- as_ac_Header=`echo "ac_cv_header_${OPENH323DIR}/version.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${OPENH323DIR}/version.h" >&5
-echo $ECHO_N "checking for ${OPENH323DIR}/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${OPENH323DIR}/version.h usability" >&5
-echo $ECHO_N "checking ${OPENH323DIR}/version.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${OPENH323DIR}/version.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${OPENH323DIR}/version.h presence" >&5
-echo $ECHO_N "checking ${OPENH323DIR}/version.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${OPENH323DIR}/version.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENH323DIR}/version.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${OPENH323DIR}/version.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${OPENH323DIR}/version.h" >&5
-echo $ECHO_N "checking for ${OPENH323DIR}/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- HAS_OPENH323=1
-fi
-
-
-fi
-if test "${HAS_OPENH323:-unset}" = "unset" ; then
- as_ac_Header=`echo "ac_cv_header_${PWLIBDIR}/../openh323/version.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${PWLIBDIR}/../openh323/version.h" >&5
-echo $ECHO_N "checking for ${PWLIBDIR}/../openh323/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${PWLIBDIR}/../openh323/version.h usability" >&5
-echo $ECHO_N "checking ${PWLIBDIR}/../openh323/version.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${PWLIBDIR}/../openh323/version.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${PWLIBDIR}/../openh323/version.h presence" >&5
-echo $ECHO_N "checking ${PWLIBDIR}/../openh323/version.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${PWLIBDIR}/../openh323/version.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${PWLIBDIR}/../openh323/version.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${PWLIBDIR}/../openh323/version.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${PWLIBDIR}/../openh323/version.h" >&5
-echo $ECHO_N "checking for ${PWLIBDIR}/../openh323/version.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1
-fi
-
-
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="${PWLIBDIR}/../openh323"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${PWLIB_INCDIR}/openh323 -I${PWLIB_INCDIR}"
- as_ac_Header=`echo "ac_cv_header_${OPENH323DIR}/include/h323.h" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for ${OPENH323DIR}/include/h323.h" >&5
-echo $ECHO_N "checking for ${OPENH323DIR}/include/h323.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ptlib.h>
-
-#include <${OPENH323DIR}/include/h323.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_Header=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- :
-else
- OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}"
-fi
-
-
- CPPFLAGS="${saved_cppflags}"
- else
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${HOME}/openh323/include -I${PWLIB_INCDIR}"
- as_ac_Header=`echo "ac_cv_header_${HOME}/openh323/include/h323.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${HOME}/openh323/include/h323.h" >&5
-echo $ECHO_N "checking for ${HOME}/openh323/include/h323.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${HOME}/openh323/include/h323.h usability" >&5
-echo $ECHO_N "checking ${HOME}/openh323/include/h323.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${HOME}/openh323/include/h323.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${HOME}/openh323/include/h323.h presence" >&5
-echo $ECHO_N "checking ${HOME}/openh323/include/h323.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${HOME}/openh323/include/h323.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${HOME}/openh323/include/h323.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${HOME}/openh323/include/h323.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${HOME}/openh323/include/h323.h" >&5
-echo $ECHO_N "checking for ${HOME}/openh323/include/h323.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- HAS_OPENH323=1
-fi
-
-
- CPPFLAGS="${saved_cppflags}"
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="${HOME}/openh323"
- else
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I/usr/local/include/openh323 -I${PWLIB_INCDIR}"
- if test "${ac_cv_header__usr_local_include_openh323_h323_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for /usr/local/include/openh323/h323.h" >&5
-echo $ECHO_N "checking for /usr/local/include/openh323/h323.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_local_include_openh323_h323_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_local_include_openh323_h323_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_local_include_openh323_h323_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking /usr/local/include/openh323/h323.h usability" >&5
-echo $ECHO_N "checking /usr/local/include/openh323/h323.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include </usr/local/include/openh323/h323.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking /usr/local/include/openh323/h323.h presence" >&5
-echo $ECHO_N "checking /usr/local/include/openh323/h323.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include </usr/local/include/openh323/h323.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: /usr/local/include/openh323/h323.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: /usr/local/include/openh323/h323.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for /usr/local/include/openh323/h323.h" >&5
-echo $ECHO_N "checking for /usr/local/include/openh323/h323.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_local_include_openh323_h323_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header__usr_local_include_openh323_h323_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_local_include_openh323_h323_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_local_include_openh323_h323_h" >&6; }
-
-fi
-if test $ac_cv_header__usr_local_include_openh323_h323_h = yes; then
- HAS_OPENH323=1
-fi
-
-
- CPPFLAGS="${saved_cppflags}"
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="/usr/local/share/openh323"
- OPENH323_INCDIR="/usr/local/include/openh323"
- if test "x$LIB64" != "x"; then
- OPENH323_LIBDIR="/usr/local/lib64"
- else
- OPENH323_LIBDIR="/usr/local/lib"
- fi
- else
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I/usr/include/openh323 -I${PWLIB_INCDIR}"
- { echo "$as_me:$LINENO: checking for /usr/include/openh323/h323.h" >&5
-echo $ECHO_N "checking for /usr/include/openh323/h323.h... $ECHO_C" >&6; }
-if test "${ac_cv_header__usr_include_openh323_h323_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ptlib.h>
-
-#include </usr/include/openh323/h323.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header__usr_include_openh323_h323_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header__usr_include_openh323_h323_h=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header__usr_include_openh323_h323_h" >&5
-echo "${ECHO_T}$ac_cv_header__usr_include_openh323_h323_h" >&6; }
-if test $ac_cv_header__usr_include_openh323_h323_h = yes; then
- HAS_OPENH323=1
-fi
-
-
- CPPFLAGS="${saved_cppflags}"
- if test "${HAS_OPENH323:-unset}" != "unset" ; then
- OPENH323DIR="/usr/share/openh323"
- OPENH323_INCDIR="/usr/include/openh323"
- if test "x$LIB64" != "x"; then
- OPENH323_LIBDIR="/usr/lib64"
- else
- OPENH323_LIBDIR="/usr/lib"
- fi
- fi
- fi
- fi
- fi
-fi
-
-if test "${HAS_OPENH323:-unset}" != "unset" ; then
- if test "${OPENH323_INCDIR:-unset}" = "unset"; then
- OPENH323_INCDIR="${OPENH323DIR}/include"
- fi
- if test "${OPENH323_LIBDIR:-unset}" = "unset"; then
- OPENH323_LIBDIR="${OPENH323DIR}/lib"
- fi
-
- OPENH323_LIBDIR="`cd ${OPENH323_LIBDIR}; pwd`"
- OPENH323_INCDIR="`cd ${OPENH323_INCDIR}; pwd`"
- OPENH323DIR="`cd ${OPENH323DIR}; pwd`"
-
-
-
-
-fi
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
- if test "${HAS_OPENH323:-unset}" != "unset"; then
- OPENH323_VERSION=`grep "OPENH323_VERSION" ${OPENH323_INCDIR}/openh323buildopts.h | cut -f2 -d ' ' | sed -e 's/"//g'`
- OPENH323_MAJOR_VERSION=`echo ${OPENH323_VERSION} | cut -f1 -d.`
- OPENH323_MINOR_VERSION=`echo ${OPENH323_VERSION} | cut -f2 -d.`
- OPENH323_BUILD_NUMBER=`echo ${OPENH323_VERSION} | cut -f3 -d.`
- let OPENH323_VER=${OPENH323_MAJOR_VERSION}*10000+${OPENH323_MINOR_VERSION}*100+${OPENH323_BUILD_NUMBER}
- let OPENH323_REQ=1*10000+17*100+3
-
- { echo "$as_me:$LINENO: checking if OpenH323 version ${OPENH323_VERSION} is compatible with chan_h323" >&5
-echo $ECHO_N "checking if OpenH323 version ${OPENH323_VERSION} is compatible with chan_h323... $ECHO_C" >&6; }
- if test ${OPENH323_VER} -lt ${OPENH323_REQ}; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- unset HAS_OPENH323
- else
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- fi
- fi
-
-
- if test "${HAS_OPENH323:-unset}" != "unset"; then
- { echo "$as_me:$LINENO: checking OpenH323 build option" >&5
-echo $ECHO_N "checking OpenH323 build option... $ECHO_C" >&6; }
- OPENH323_SUFFIX=
- prefixes="h323_${PWLIB_PLATFORM}_ h323_ openh323"
- for pfx in $prefixes; do
- files=`ls -l ${OPENH323_LIBDIR}/lib${pfx}*.so* 2>/dev/null`
- libfile=
- if test -n "$files"; then
- for f in $files; do
- if test -f $f -a ! -L $f; then
- libfile=`basename $f`
- break;
- fi
- done
- fi
- if test -n "$libfile"; then
- OPENH323_PREFIX=$pfx
- break;
- fi
- done
- if test "${libfile:-unset}" != "unset"; then
- OPENH323_SUFFIX=`eval "echo ${libfile} | sed -e 's/lib${OPENH323_PREFIX}\([^.]*\)\..*/\1/'"`
- fi
- case "${OPENH323_SUFFIX}" in
- n)
- OPENH323_BUILD="notrace";;
- r)
- OPENH323_BUILD="opt";;
- d)
- OPENH323_BUILD="debug";;
- *)
- if test "${OPENH323_PREFIX:-undef}" = "openh323"; then
- notrace=`eval "grep NOTRACE ${OPENH323DIR}/openh323u.mak | grep = | sed -e 's/[A-Z0-9_]*[ ]*=[ ]*//'"`
- if test "x$notrace" = "x"; then
- notrace="0"
- fi
- if test "$notrace" -ne 0; then
- OPENH323_BUILD="notrace"
- else
- OPENH323_BUILD="opt"
- fi
- OPENH323_LIB="-l${OPENH323_PREFIX}"
- else
- OPENH323_BUILD="notrace"
- fi
- ;;
- esac
- { echo "$as_me:$LINENO: result: ${OPENH323_BUILD}" >&5
-echo "${ECHO_T}${OPENH323_BUILD}" >&6; }
-
-
-
- fi
-
- PLATFORM_OPENH323="h323_${PWLIB_PLATFORM}_${OPENH323_SUFFIX}"
-
- if test "${HAS_OPENH323:-unset}" != "unset"; then
- { echo "$as_me:$LINENO: checking OpenH323 installation validity" >&5
-echo $ECHO_N "checking OpenH323 installation validity... $ECHO_C" >&6; }
-
- saved_cppflags="${CPPFLAGS}"
- saved_libs="${LIBS}"
- if test "${OPENH323_LIB:-unset}" != "unset"; then
- LIBS="${LIBS} ${OPENH323_LIB} ${PWLIB_LIB}"
- else
- LIBS="${LIBS} -L${OPENH323_LIBDIR} -l${PLATFORM_OPENH323} ${PWLIB_LIB}"
- fi
- CPPFLAGS="${CPPFLAGS} -I${OPENH323_INCDIR} ${PWLIB_INCLUDE}"
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include "ptlib.h"
- #include "h323.h"
- #include "h323ep.h"
-int
-main ()
-{
-H323EndPoint ep = H323EndPoint();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_lib_OPENH323="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_lib_OPENH323="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
-
- if test "${ac_cv_lib_OPENH323}" = "yes"; then
- if test "${OPENH323_LIB:-undef}" = "undef"; then
- if test "${OPENH323_LIBDIR}" != "" -a "${OPENH323_LIBDIR}" != "/usr/lib"; then
- OPENH323_LIB="-L${OPENH323_LIBDIR} -l${PLATFORM_OPENH323}"
- else
- OPENH323_LIB="-l${PLATFORM_OPENH323}"
- fi
- fi
- if test "${OPENH323_INCDIR}" != "" -a "${OPENH323_INCDIR}" != "/usr/include"; then
- OPENH323_INCLUDE="-I${OPENH323_INCDIR}"
- fi
- PBX_OPENH323=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_OPENH323 1
-_ACEOF
-
- fi
- fi
-
-fi
-if test "${USE_OPENH323}" != "no" -a "x${ac_cv_lib_OPENH323}" != "xyes" -a -n "${OPENH323_MANDATORY}"; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The OPENH323 installation on this system appears to be broken." >&5
-echo "$as_me: *** The OPENH323 installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-h323" >&5
-echo "$as_me: *** including --without-h323" >&6;}
- exit 1
-fi
-
-
-if test "${USE_RADIUS}" != "no"; then
- pbxlibdir=""
- if test "x${RADIUS_DIR}" != "x"; then
- if test -d ${RADIUS_DIR}/lib; then
- pbxlibdir="-L${RADIUS_DIR}/lib"
- else
- pbxlibdir="-L${RADIUS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for rc_read_config in -lradiusclient-ng" >&5
-echo $ECHO_N "checking for rc_read_config in -lradiusclient-ng... $ECHO_C" >&6; }
-if test "${ac_cv_lib_radiusclient_ng_rc_read_config+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lradiusclient-ng ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char rc_read_config ();
-int
-main ()
-{
-return rc_read_config ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_radiusclient_ng_rc_read_config=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_radiusclient_ng_rc_read_config=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_radiusclient_ng_rc_read_config" >&5
-echo "${ECHO_T}$ac_cv_lib_radiusclient_ng_rc_read_config" >&6; }
-if test $ac_cv_lib_radiusclient_ng_rc_read_config = yes; then
- AST_RADIUS_FOUND=yes
-else
- AST_RADIUS_FOUND=no
-fi
-
-
- if test "${AST_RADIUS_FOUND}" = "yes"; then
- RADIUS_LIB="-lradiusclient-ng "
- RADIUS_HEADER_FOUND="1"
- if test "x${RADIUS_DIR}" != "x"; then
- RADIUS_LIB="${pbxlibdir} ${RADIUS_LIB}"
- RADIUS_INCLUDE="-I${RADIUS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${RADIUS_DIR}/include"
- if test "xradiusclient-ng.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${RADIUS_DIR}/include/radiusclient-ng.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${RADIUS_DIR}/include/radiusclient-ng.h" >&5
-echo $ECHO_N "checking for ${RADIUS_DIR}/include/radiusclient-ng.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${RADIUS_DIR}/include/radiusclient-ng.h usability" >&5
-echo $ECHO_N "checking ${RADIUS_DIR}/include/radiusclient-ng.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${RADIUS_DIR}/include/radiusclient-ng.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${RADIUS_DIR}/include/radiusclient-ng.h presence" >&5
-echo $ECHO_N "checking ${RADIUS_DIR}/include/radiusclient-ng.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${RADIUS_DIR}/include/radiusclient-ng.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${RADIUS_DIR}/include/radiusclient-ng.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${RADIUS_DIR}/include/radiusclient-ng.h" >&5
-echo $ECHO_N "checking for ${RADIUS_DIR}/include/radiusclient-ng.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- RADIUS_HEADER_FOUND=1
-else
- RADIUS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xradiusclient-ng.h" != "x" ; then
- if test "${ac_cv_header_radiusclient_ng_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for radiusclient-ng.h" >&5
-echo $ECHO_N "checking for radiusclient-ng.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_radiusclient_ng_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_radiusclient_ng_h" >&5
-echo "${ECHO_T}$ac_cv_header_radiusclient_ng_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking radiusclient-ng.h usability" >&5
-echo $ECHO_N "checking radiusclient-ng.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <radiusclient-ng.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking radiusclient-ng.h presence" >&5
-echo $ECHO_N "checking radiusclient-ng.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <radiusclient-ng.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: radiusclient-ng.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: radiusclient-ng.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for radiusclient-ng.h" >&5
-echo $ECHO_N "checking for radiusclient-ng.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_radiusclient_ng_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_radiusclient_ng_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_radiusclient_ng_h" >&5
-echo "${ECHO_T}$ac_cv_header_radiusclient_ng_h" >&6; }
-
-fi
-if test $ac_cv_header_radiusclient_ng_h = yes; then
- RADIUS_HEADER_FOUND=1
-else
- RADIUS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${RADIUS_HEADER_FOUND}" = "x0" ; then
- if test -n "${RADIUS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the radiusclient-ng development package installed." >&5
-echo "$as_me: *** It appears that you do not have the radiusclient-ng development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${RADIUS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${RADIUS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${RADIUS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${RADIUS_OPTION}" >&6;}
- exit 1
- fi
- RADIUS_LIB=""
- RADIUS_INCLUDE=""
- PBX_RADIUS=0
- else
- PBX_RADIUS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_RADIUS 1
-_ACEOF
-
- fi
- elif test -n "${RADIUS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${RADIUS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${RADIUS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${RADIUS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${RADIUS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_SPEEX}" != "no"; then
- pbxlibdir=""
- if test "x${SPEEX_DIR}" != "x"; then
- if test -d ${SPEEX_DIR}/lib; then
- pbxlibdir="-L${SPEEX_DIR}/lib"
- else
- pbxlibdir="-L${SPEEX_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for speex_encode in -lspeex" >&5
-echo $ECHO_N "checking for speex_encode in -lspeex... $ECHO_C" >&6; }
-if test "${ac_cv_lib_speex_speex_encode+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lspeex ${pbxlibdir} -lm $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char speex_encode ();
-int
-main ()
-{
-return speex_encode ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_speex_speex_encode=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_speex_speex_encode=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_speex_speex_encode" >&5
-echo "${ECHO_T}$ac_cv_lib_speex_speex_encode" >&6; }
-if test $ac_cv_lib_speex_speex_encode = yes; then
- AST_SPEEX_FOUND=yes
-else
- AST_SPEEX_FOUND=no
-fi
-
-
- if test "${AST_SPEEX_FOUND}" = "yes"; then
- SPEEX_LIB="-lspeex -lm"
- SPEEX_HEADER_FOUND="1"
- if test "x${SPEEX_DIR}" != "x"; then
- SPEEX_LIB="${pbxlibdir} ${SPEEX_LIB}"
- SPEEX_INCLUDE="-I${SPEEX_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${SPEEX_DIR}/include"
- if test "xspeex/speex.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${SPEEX_DIR}/include/speex/speex.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${SPEEX_DIR}/include/speex/speex.h" >&5
-echo $ECHO_N "checking for ${SPEEX_DIR}/include/speex/speex.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${SPEEX_DIR}/include/speex/speex.h usability" >&5
-echo $ECHO_N "checking ${SPEEX_DIR}/include/speex/speex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${SPEEX_DIR}/include/speex/speex.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${SPEEX_DIR}/include/speex/speex.h presence" >&5
-echo $ECHO_N "checking ${SPEEX_DIR}/include/speex/speex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${SPEEX_DIR}/include/speex/speex.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_DIR}/include/speex/speex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${SPEEX_DIR}/include/speex/speex.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${SPEEX_DIR}/include/speex/speex.h" >&5
-echo $ECHO_N "checking for ${SPEEX_DIR}/include/speex/speex.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- SPEEX_HEADER_FOUND=1
-else
- SPEEX_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xspeex/speex.h" != "x" ; then
- if test "${ac_cv_header_speex_speex_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for speex/speex.h" >&5
-echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_speex_speex_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5
-echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking speex/speex.h usability" >&5
-echo $ECHO_N "checking speex/speex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <speex/speex.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking speex/speex.h presence" >&5
-echo $ECHO_N "checking speex/speex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <speex/speex.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: speex/speex.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: speex/speex.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: speex/speex.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: speex/speex.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for speex/speex.h" >&5
-echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_speex_speex_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_speex_speex_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5
-echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; }
-
-fi
-if test $ac_cv_header_speex_speex_h = yes; then
- SPEEX_HEADER_FOUND=1
-else
- SPEEX_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${SPEEX_HEADER_FOUND}" = "x0" ; then
- if test -n "${SPEEX_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the speex development package installed." >&5
-echo "$as_me: *** It appears that you do not have the speex development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${SPEEX_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${SPEEX_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPEEX_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SPEEX_OPTION}" >&6;}
- exit 1
- fi
- SPEEX_LIB=""
- SPEEX_INCLUDE=""
- PBX_SPEEX=0
- else
- PBX_SPEEX=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_SPEEX 1
-_ACEOF
-
- fi
- elif test -n "${SPEEX_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${SPEEX_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${SPEEX_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPEEX_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SPEEX_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-# See if the main speex library contains the preprocess functions
-
-if test "${USE_SPEEX_PREPROCESS}" != "no"; then
- pbxlibdir=""
- if test "x${SPEEX_PREPROCESS_DIR}" != "x"; then
- if test -d ${SPEEX_PREPROCESS_DIR}/lib; then
- pbxlibdir="-L${SPEEX_PREPROCESS_DIR}/lib"
- else
- pbxlibdir="-L${SPEEX_PREPROCESS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for speex_preprocess_ctl in -lspeex" >&5
-echo $ECHO_N "checking for speex_preprocess_ctl in -lspeex... $ECHO_C" >&6; }
-if test "${ac_cv_lib_speex_speex_preprocess_ctl+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lspeex ${pbxlibdir} -lm $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char speex_preprocess_ctl ();
-int
-main ()
-{
-return speex_preprocess_ctl ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_speex_speex_preprocess_ctl=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_speex_speex_preprocess_ctl=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_speex_speex_preprocess_ctl" >&5
-echo "${ECHO_T}$ac_cv_lib_speex_speex_preprocess_ctl" >&6; }
-if test $ac_cv_lib_speex_speex_preprocess_ctl = yes; then
- AST_SPEEX_PREPROCESS_FOUND=yes
-else
- AST_SPEEX_PREPROCESS_FOUND=no
-fi
-
-
- if test "${AST_SPEEX_PREPROCESS_FOUND}" = "yes"; then
- SPEEX_PREPROCESS_LIB="-lspeex -lm"
- SPEEX_PREPROCESS_HEADER_FOUND="1"
- if test "x${SPEEX_PREPROCESS_DIR}" != "x"; then
- SPEEX_PREPROCESS_LIB="${pbxlibdir} ${SPEEX_PREPROCESS_LIB}"
- SPEEX_PREPROCESS_INCLUDE="-I${SPEEX_PREPROCESS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${SPEEX_PREPROCESS_DIR}/include"
- if test "xspeex/speex.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${SPEEX_PREPROCESS_DIR}/include/speex/speex.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h" >&5
-echo $ECHO_N "checking for ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h usability" >&5
-echo $ECHO_N "checking ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${SPEEX_PREPROCESS_DIR}/include/speex/speex.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h presence" >&5
-echo $ECHO_N "checking ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${SPEEX_PREPROCESS_DIR}/include/speex/speex.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h" >&5
-echo $ECHO_N "checking for ${SPEEX_PREPROCESS_DIR}/include/speex/speex.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- SPEEX_PREPROCESS_HEADER_FOUND=1
-else
- SPEEX_PREPROCESS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xspeex/speex.h" != "x" ; then
- if test "${ac_cv_header_speex_speex_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for speex/speex.h" >&5
-echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_speex_speex_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5
-echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking speex/speex.h usability" >&5
-echo $ECHO_N "checking speex/speex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <speex/speex.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking speex/speex.h presence" >&5
-echo $ECHO_N "checking speex/speex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <speex/speex.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: speex/speex.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: speex/speex.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: speex/speex.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: speex/speex.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for speex/speex.h" >&5
-echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_speex_speex_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_speex_speex_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5
-echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; }
-
-fi
-if test $ac_cv_header_speex_speex_h = yes; then
- SPEEX_PREPROCESS_HEADER_FOUND=1
-else
- SPEEX_PREPROCESS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${SPEEX_PREPROCESS_HEADER_FOUND}" = "x0" ; then
- if test -n "${SPEEX_PREPROCESS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the speex development package installed." >&5
-echo "$as_me: *** It appears that you do not have the speex development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${SPEEX_PREPROCESS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${SPEEX_PREPROCESS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPEEX_PREPROCESS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SPEEX_PREPROCESS_OPTION}" >&6;}
- exit 1
- fi
- SPEEX_PREPROCESS_LIB=""
- SPEEX_PREPROCESS_INCLUDE=""
- PBX_SPEEX_PREPROCESS=0
- else
- PBX_SPEEX_PREPROCESS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_SPEEX_PREPROCESS 1
-_ACEOF
-
- fi
- elif test -n "${SPEEX_PREPROCESS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${SPEEX_PREPROCESS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${SPEEX_PREPROCESS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPEEX_PREPROCESS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SPEEX_PREPROCESS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-if test "${PBX_SPEEX_PREPROCESS}" = 1; then
- PBX_SPEEX_PREPROCESS=1
-fi
-
-
-if test "${USE_SPEEXDSP}" != "no"; then
- pbxlibdir=""
- if test "x${SPEEXDSP_DIR}" != "x"; then
- if test -d ${SPEEXDSP_DIR}/lib; then
- pbxlibdir="-L${SPEEXDSP_DIR}/lib"
- else
- pbxlibdir="-L${SPEEXDSP_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for speex_preprocess_ctl in -lspeexdsp" >&5
-echo $ECHO_N "checking for speex_preprocess_ctl in -lspeexdsp... $ECHO_C" >&6; }
-if test "${ac_cv_lib_speexdsp_speex_preprocess_ctl+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lspeexdsp ${pbxlibdir} -lm $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char speex_preprocess_ctl ();
-int
-main ()
-{
-return speex_preprocess_ctl ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_speexdsp_speex_preprocess_ctl=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_speexdsp_speex_preprocess_ctl=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_speexdsp_speex_preprocess_ctl" >&5
-echo "${ECHO_T}$ac_cv_lib_speexdsp_speex_preprocess_ctl" >&6; }
-if test $ac_cv_lib_speexdsp_speex_preprocess_ctl = yes; then
- AST_SPEEXDSP_FOUND=yes
-else
- AST_SPEEXDSP_FOUND=no
-fi
-
-
- if test "${AST_SPEEXDSP_FOUND}" = "yes"; then
- SPEEXDSP_LIB="-lspeexdsp -lm"
- SPEEXDSP_HEADER_FOUND="1"
- if test "x${SPEEXDSP_DIR}" != "x"; then
- SPEEXDSP_LIB="${pbxlibdir} ${SPEEXDSP_LIB}"
- SPEEXDSP_INCLUDE="-I${SPEEXDSP_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${SPEEXDSP_DIR}/include"
- if test "xspeex/speex.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${SPEEXDSP_DIR}/include/speex/speex.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${SPEEXDSP_DIR}/include/speex/speex.h" >&5
-echo $ECHO_N "checking for ${SPEEXDSP_DIR}/include/speex/speex.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${SPEEXDSP_DIR}/include/speex/speex.h usability" >&5
-echo $ECHO_N "checking ${SPEEXDSP_DIR}/include/speex/speex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${SPEEXDSP_DIR}/include/speex/speex.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${SPEEXDSP_DIR}/include/speex/speex.h presence" >&5
-echo $ECHO_N "checking ${SPEEXDSP_DIR}/include/speex/speex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${SPEEXDSP_DIR}/include/speex/speex.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${SPEEXDSP_DIR}/include/speex/speex.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${SPEEXDSP_DIR}/include/speex/speex.h" >&5
-echo $ECHO_N "checking for ${SPEEXDSP_DIR}/include/speex/speex.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- SPEEXDSP_HEADER_FOUND=1
-else
- SPEEXDSP_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xspeex/speex.h" != "x" ; then
- if test "${ac_cv_header_speex_speex_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for speex/speex.h" >&5
-echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_speex_speex_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5
-echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking speex/speex.h usability" >&5
-echo $ECHO_N "checking speex/speex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <speex/speex.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking speex/speex.h presence" >&5
-echo $ECHO_N "checking speex/speex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <speex/speex.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: speex/speex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: speex/speex.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: speex/speex.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: speex/speex.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: speex/speex.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: speex/speex.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: speex/speex.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: speex/speex.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for speex/speex.h" >&5
-echo $ECHO_N "checking for speex/speex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_speex_speex_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_speex_speex_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_speex_speex_h" >&5
-echo "${ECHO_T}$ac_cv_header_speex_speex_h" >&6; }
-
-fi
-if test $ac_cv_header_speex_speex_h = yes; then
- SPEEXDSP_HEADER_FOUND=1
-else
- SPEEXDSP_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${SPEEXDSP_HEADER_FOUND}" = "x0" ; then
- if test -n "${SPEEXDSP_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the speexdsp development package installed." >&5
-echo "$as_me: *** It appears that you do not have the speexdsp development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${SPEEXDSP_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${SPEEXDSP_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPEEXDSP_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SPEEXDSP_OPTION}" >&6;}
- exit 1
- fi
- SPEEXDSP_LIB=""
- SPEEXDSP_INCLUDE=""
- PBX_SPEEXDSP=0
- else
- PBX_SPEEXDSP=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_SPEEXDSP 1
-_ACEOF
-
- fi
- elif test -n "${SPEEXDSP_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${SPEEXDSP_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${SPEEXDSP_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPEEXDSP_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SPEEXDSP_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-if test "${PBX_SPEEXDSP}" = 1; then
- PBX_SPEEX_PREPROCESS=1
-fi
-
-
-
-
-if test "${USE_SQLITE}" != "no"; then
- pbxlibdir=""
- if test "x${SQLITE_DIR}" != "x"; then
- if test -d ${SQLITE_DIR}/lib; then
- pbxlibdir="-L${SQLITE_DIR}/lib"
- else
- pbxlibdir="-L${SQLITE_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for sqlite_exec in -lsqlite" >&5
-echo $ECHO_N "checking for sqlite_exec in -lsqlite... $ECHO_C" >&6; }
-if test "${ac_cv_lib_sqlite_sqlite_exec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsqlite ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char sqlite_exec ();
-int
-main ()
-{
-return sqlite_exec ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_sqlite_sqlite_exec=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_sqlite_sqlite_exec=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_sqlite_sqlite_exec" >&5
-echo "${ECHO_T}$ac_cv_lib_sqlite_sqlite_exec" >&6; }
-if test $ac_cv_lib_sqlite_sqlite_exec = yes; then
- AST_SQLITE_FOUND=yes
-else
- AST_SQLITE_FOUND=no
-fi
-
-
- if test "${AST_SQLITE_FOUND}" = "yes"; then
- SQLITE_LIB="-lsqlite "
- SQLITE_HEADER_FOUND="1"
- if test "x${SQLITE_DIR}" != "x"; then
- SQLITE_LIB="${pbxlibdir} ${SQLITE_LIB}"
- SQLITE_INCLUDE="-I${SQLITE_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${SQLITE_DIR}/include"
- if test "xsqlite.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${SQLITE_DIR}/include/sqlite.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${SQLITE_DIR}/include/sqlite.h" >&5
-echo $ECHO_N "checking for ${SQLITE_DIR}/include/sqlite.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${SQLITE_DIR}/include/sqlite.h usability" >&5
-echo $ECHO_N "checking ${SQLITE_DIR}/include/sqlite.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${SQLITE_DIR}/include/sqlite.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${SQLITE_DIR}/include/sqlite.h presence" >&5
-echo $ECHO_N "checking ${SQLITE_DIR}/include/sqlite.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${SQLITE_DIR}/include/sqlite.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${SQLITE_DIR}/include/sqlite.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${SQLITE_DIR}/include/sqlite.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${SQLITE_DIR}/include/sqlite.h" >&5
-echo $ECHO_N "checking for ${SQLITE_DIR}/include/sqlite.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- SQLITE_HEADER_FOUND=1
-else
- SQLITE_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xsqlite.h" != "x" ; then
- if test "${ac_cv_header_sqlite_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for sqlite.h" >&5
-echo $ECHO_N "checking for sqlite.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sqlite_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sqlite_h" >&5
-echo "${ECHO_T}$ac_cv_header_sqlite_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking sqlite.h usability" >&5
-echo $ECHO_N "checking sqlite.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sqlite.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking sqlite.h presence" >&5
-echo $ECHO_N "checking sqlite.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sqlite.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sqlite.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sqlite.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sqlite.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sqlite.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sqlite.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sqlite.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sqlite.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sqlite.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sqlite.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sqlite.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sqlite.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sqlite.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sqlite.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sqlite.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sqlite.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sqlite.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for sqlite.h" >&5
-echo $ECHO_N "checking for sqlite.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_sqlite_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sqlite_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sqlite_h" >&5
-echo "${ECHO_T}$ac_cv_header_sqlite_h" >&6; }
-
-fi
-if test $ac_cv_header_sqlite_h = yes; then
- SQLITE_HEADER_FOUND=1
-else
- SQLITE_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${SQLITE_HEADER_FOUND}" = "x0" ; then
- if test -n "${SQLITE_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the sqlite development package installed." >&5
-echo "$as_me: *** It appears that you do not have the sqlite development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${SQLITE_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${SQLITE_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SQLITE_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SQLITE_OPTION}" >&6;}
- exit 1
- fi
- SQLITE_LIB=""
- SQLITE_INCLUDE=""
- PBX_SQLITE=0
- else
- PBX_SQLITE=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_SQLITE 1
-_ACEOF
-
- fi
- elif test -n "${SQLITE_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${SQLITE_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${SQLITE_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SQLITE_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${SQLITE_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_OPENSSL}" != "no"; then
- pbxlibdir=""
- if test "x${OPENSSL_DIR}" != "x"; then
- if test -d ${OPENSSL_DIR}/lib; then
- pbxlibdir="-L${OPENSSL_DIR}/lib"
- else
- pbxlibdir="-L${OPENSSL_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for ssl2_connect in -lssl" >&5
-echo $ECHO_N "checking for ssl2_connect in -lssl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ssl_ssl2_connect+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl ${pbxlibdir} -lcrypto $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ssl2_connect ();
-int
-main ()
-{
-return ssl2_connect ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ssl_ssl2_connect=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ssl_ssl2_connect=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_ssl2_connect" >&5
-echo "${ECHO_T}$ac_cv_lib_ssl_ssl2_connect" >&6; }
-if test $ac_cv_lib_ssl_ssl2_connect = yes; then
- AST_OPENSSL_FOUND=yes
-else
- AST_OPENSSL_FOUND=no
-fi
-
-
- if test "${AST_OPENSSL_FOUND}" = "yes"; then
- OPENSSL_LIB="-lssl -lcrypto"
- OPENSSL_HEADER_FOUND="1"
- if test "x${OPENSSL_DIR}" != "x"; then
- OPENSSL_LIB="${pbxlibdir} ${OPENSSL_LIB}"
- OPENSSL_INCLUDE="-I${OPENSSL_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${OPENSSL_DIR}/include"
- if test "xopenssl/ssl.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${OPENSSL_DIR}/include/openssl/ssl.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${OPENSSL_DIR}/include/openssl/ssl.h" >&5
-echo $ECHO_N "checking for ${OPENSSL_DIR}/include/openssl/ssl.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${OPENSSL_DIR}/include/openssl/ssl.h usability" >&5
-echo $ECHO_N "checking ${OPENSSL_DIR}/include/openssl/ssl.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${OPENSSL_DIR}/include/openssl/ssl.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${OPENSSL_DIR}/include/openssl/ssl.h presence" >&5
-echo $ECHO_N "checking ${OPENSSL_DIR}/include/openssl/ssl.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${OPENSSL_DIR}/include/openssl/ssl.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${OPENSSL_DIR}/include/openssl/ssl.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${OPENSSL_DIR}/include/openssl/ssl.h" >&5
-echo $ECHO_N "checking for ${OPENSSL_DIR}/include/openssl/ssl.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- OPENSSL_HEADER_FOUND=1
-else
- OPENSSL_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xopenssl/ssl.h" != "x" ; then
- if test "${ac_cv_header_openssl_ssl_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for openssl/ssl.h" >&5
-echo $ECHO_N "checking for openssl/ssl.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_openssl_ssl_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_openssl_ssl_h" >&5
-echo "${ECHO_T}$ac_cv_header_openssl_ssl_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking openssl/ssl.h usability" >&5
-echo $ECHO_N "checking openssl/ssl.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <openssl/ssl.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking openssl/ssl.h presence" >&5
-echo $ECHO_N "checking openssl/ssl.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <openssl/ssl.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: openssl/ssl.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: openssl/ssl.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: openssl/ssl.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: openssl/ssl.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: openssl/ssl.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: openssl/ssl.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for openssl/ssl.h" >&5
-echo $ECHO_N "checking for openssl/ssl.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_openssl_ssl_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_openssl_ssl_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_openssl_ssl_h" >&5
-echo "${ECHO_T}$ac_cv_header_openssl_ssl_h" >&6; }
-
-fi
-if test $ac_cv_header_openssl_ssl_h = yes; then
- OPENSSL_HEADER_FOUND=1
-else
- OPENSSL_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${OPENSSL_HEADER_FOUND}" = "x0" ; then
- if test -n "${OPENSSL_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the ssl development package installed." >&5
-echo "$as_me: *** It appears that you do not have the ssl development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${OPENSSL_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${OPENSSL_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OPENSSL_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OPENSSL_OPTION}" >&6;}
- exit 1
- fi
- OPENSSL_LIB=""
- OPENSSL_INCLUDE=""
- PBX_OPENSSL=0
- else
- PBX_OPENSSL=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OPENSSL 1
-_ACEOF
-
- fi
- elif test -n "${OPENSSL_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${OPENSSL_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${OPENSSL_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OPENSSL_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OPENSSL_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-if test "$PBX_OPENSSL" = "1";
-then
-
-if test "${USE_OSPTK}" != "no"; then
- pbxlibdir=""
- if test "x${OSPTK_DIR}" != "x"; then
- if test -d ${OSPTK_DIR}/lib; then
- pbxlibdir="-L${OSPTK_DIR}/lib"
- else
- pbxlibdir="-L${OSPTK_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for OSPPCryptoDecrypt in -losptk" >&5
-echo $ECHO_N "checking for OSPPCryptoDecrypt in -losptk... $ECHO_C" >&6; }
-if test "${ac_cv_lib_osptk_OSPPCryptoDecrypt+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-losptk ${pbxlibdir} -lcrypto -lssl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char OSPPCryptoDecrypt ();
-int
-main ()
-{
-return OSPPCryptoDecrypt ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_osptk_OSPPCryptoDecrypt=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_osptk_OSPPCryptoDecrypt=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_osptk_OSPPCryptoDecrypt" >&5
-echo "${ECHO_T}$ac_cv_lib_osptk_OSPPCryptoDecrypt" >&6; }
-if test $ac_cv_lib_osptk_OSPPCryptoDecrypt = yes; then
- AST_OSPTK_FOUND=yes
-else
- AST_OSPTK_FOUND=no
-fi
-
-
- if test "${AST_OSPTK_FOUND}" = "yes"; then
- OSPTK_LIB="-losptk -lcrypto -lssl"
- OSPTK_HEADER_FOUND="1"
- if test "x${OSPTK_DIR}" != "x"; then
- OSPTK_LIB="${pbxlibdir} ${OSPTK_LIB}"
- OSPTK_INCLUDE="-I${OSPTK_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${OSPTK_DIR}/include"
- if test "xosp/osp.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${OSPTK_DIR}/include/osp/osp.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${OSPTK_DIR}/include/osp/osp.h" >&5
-echo $ECHO_N "checking for ${OSPTK_DIR}/include/osp/osp.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${OSPTK_DIR}/include/osp/osp.h usability" >&5
-echo $ECHO_N "checking ${OSPTK_DIR}/include/osp/osp.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${OSPTK_DIR}/include/osp/osp.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${OSPTK_DIR}/include/osp/osp.h presence" >&5
-echo $ECHO_N "checking ${OSPTK_DIR}/include/osp/osp.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${OSPTK_DIR}/include/osp/osp.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${OSPTK_DIR}/include/osp/osp.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${OSPTK_DIR}/include/osp/osp.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${OSPTK_DIR}/include/osp/osp.h" >&5
-echo $ECHO_N "checking for ${OSPTK_DIR}/include/osp/osp.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- OSPTK_HEADER_FOUND=1
-else
- OSPTK_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xosp/osp.h" != "x" ; then
- if test "${ac_cv_header_osp_osp_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for osp/osp.h" >&5
-echo $ECHO_N "checking for osp/osp.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_osp_osp_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_osp_osp_h" >&5
-echo "${ECHO_T}$ac_cv_header_osp_osp_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking osp/osp.h usability" >&5
-echo $ECHO_N "checking osp/osp.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <osp/osp.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking osp/osp.h presence" >&5
-echo $ECHO_N "checking osp/osp.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <osp/osp.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: osp/osp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: osp/osp.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: osp/osp.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: osp/osp.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: osp/osp.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: osp/osp.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: osp/osp.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: osp/osp.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: osp/osp.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for osp/osp.h" >&5
-echo $ECHO_N "checking for osp/osp.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_osp_osp_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_osp_osp_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_osp_osp_h" >&5
-echo "${ECHO_T}$ac_cv_header_osp_osp_h" >&6; }
-
-fi
-if test $ac_cv_header_osp_osp_h = yes; then
- OSPTK_HEADER_FOUND=1
-else
- OSPTK_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${OSPTK_HEADER_FOUND}" = "x0" ; then
- if test -n "${OSPTK_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the osptk development package installed." >&5
-echo "$as_me: *** It appears that you do not have the osptk development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${OSPTK_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${OSPTK_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OSPTK_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OSPTK_OPTION}" >&6;}
- exit 1
- fi
- OSPTK_LIB=""
- OSPTK_INCLUDE=""
- PBX_OSPTK=0
- else
- PBX_OSPTK=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OSPTK 1
-_ACEOF
-
- fi
- elif test -n "${OSPTK_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${OSPTK_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${OSPTK_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${OSPTK_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${OSPTK_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-fi
-
-
-if test "${USE_FREETDS}" != "no"; then
- pbxlibdir=""
- if test "x${FREETDS_DIR}" != "x"; then
- if test -d ${FREETDS_DIR}/lib; then
- pbxlibdir="-L${FREETDS_DIR}/lib"
- else
- pbxlibdir="-L${FREETDS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for tds_version in -ltds" >&5
-echo $ECHO_N "checking for tds_version in -ltds... $ECHO_C" >&6; }
-if test "${ac_cv_lib_tds_tds_version+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ltds ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char tds_version ();
-int
-main ()
-{
-return tds_version ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_tds_tds_version=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_tds_tds_version=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_tds_tds_version" >&5
-echo "${ECHO_T}$ac_cv_lib_tds_tds_version" >&6; }
-if test $ac_cv_lib_tds_tds_version = yes; then
- AST_FREETDS_FOUND=yes
-else
- AST_FREETDS_FOUND=no
-fi
-
-
- if test "${AST_FREETDS_FOUND}" = "yes"; then
- FREETDS_LIB="-ltds "
- FREETDS_HEADER_FOUND="1"
- if test "x${FREETDS_DIR}" != "x"; then
- FREETDS_LIB="${pbxlibdir} ${FREETDS_LIB}"
- FREETDS_INCLUDE="-I${FREETDS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${FREETDS_DIR}/include"
- if test "xtds.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${FREETDS_DIR}/include/tds.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${FREETDS_DIR}/include/tds.h" >&5
-echo $ECHO_N "checking for ${FREETDS_DIR}/include/tds.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${FREETDS_DIR}/include/tds.h usability" >&5
-echo $ECHO_N "checking ${FREETDS_DIR}/include/tds.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${FREETDS_DIR}/include/tds.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${FREETDS_DIR}/include/tds.h presence" >&5
-echo $ECHO_N "checking ${FREETDS_DIR}/include/tds.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${FREETDS_DIR}/include/tds.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${FREETDS_DIR}/include/tds.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${FREETDS_DIR}/include/tds.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${FREETDS_DIR}/include/tds.h" >&5
-echo $ECHO_N "checking for ${FREETDS_DIR}/include/tds.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- FREETDS_HEADER_FOUND=1
-else
- FREETDS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xtds.h" != "x" ; then
- if test "${ac_cv_header_tds_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for tds.h" >&5
-echo $ECHO_N "checking for tds.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_tds_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_tds_h" >&5
-echo "${ECHO_T}$ac_cv_header_tds_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking tds.h usability" >&5
-echo $ECHO_N "checking tds.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <tds.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking tds.h presence" >&5
-echo $ECHO_N "checking tds.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <tds.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: tds.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: tds.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: tds.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: tds.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: tds.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: tds.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: tds.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: tds.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: tds.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: tds.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: tds.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: tds.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: tds.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: tds.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: tds.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: tds.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for tds.h" >&5
-echo $ECHO_N "checking for tds.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_tds_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_tds_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_tds_h" >&5
-echo "${ECHO_T}$ac_cv_header_tds_h" >&6; }
-
-fi
-if test $ac_cv_header_tds_h = yes; then
- FREETDS_HEADER_FOUND=1
-else
- FREETDS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${FREETDS_HEADER_FOUND}" = "x0" ; then
- if test -n "${FREETDS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the tds development package installed." >&5
-echo "$as_me: *** It appears that you do not have the tds development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${FREETDS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${FREETDS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${FREETDS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${FREETDS_OPTION}" >&6;}
- exit 1
- fi
- FREETDS_LIB=""
- FREETDS_INCLUDE=""
- PBX_FREETDS=0
- else
- PBX_FREETDS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_FREETDS 1
-_ACEOF
-
- fi
- elif test -n "${FREETDS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${FREETDS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${FREETDS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${FREETDS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${FREETDS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-if test "${PBX_FREETDS}" != "0";
-then
- if test "${FREETDS_DIR}x" = "x";
- then
- for tds_dir in /usr /usr/local;
- do
- if test -f "${tds_dir}/include/tdsver.h";
- then
- FREETDS_DIR="${tds_dir}"
- fi
- done
- fi
- case `${GREP} TDS_VERSION_NO ${FREETDS_DIR:-/usr}/include/tdsver.h` in
- *0.64*)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_0_64"
- ;;
- *0.63*)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_0_63"
- ;;
- *0.62*)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_0_62"
- ;;
- *)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_PRE_0_62"
- ;;
- esac
-fi
-
-
-if test "${USE_TERMCAP}" != "no"; then
- pbxlibdir=""
- if test "x${TERMCAP_DIR}" != "x"; then
- if test -d ${TERMCAP_DIR}/lib; then
- pbxlibdir="-L${TERMCAP_DIR}/lib"
- else
- pbxlibdir="-L${TERMCAP_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
-echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6; }
-if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ltermcap ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char tgetent ();
-int
-main ()
-{
-return tgetent ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_termcap_tgetent=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_termcap_tgetent=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
-echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6; }
-if test $ac_cv_lib_termcap_tgetent = yes; then
- AST_TERMCAP_FOUND=yes
-else
- AST_TERMCAP_FOUND=no
-fi
-
-
- if test "${AST_TERMCAP_FOUND}" = "yes"; then
- TERMCAP_LIB="-ltermcap "
- TERMCAP_HEADER_FOUND="1"
- if test "x${TERMCAP_DIR}" != "x"; then
- TERMCAP_LIB="${pbxlibdir} ${TERMCAP_LIB}"
- TERMCAP_INCLUDE="-I${TERMCAP_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${TERMCAP_DIR}/include"
- if test "x" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${TERMCAP_DIR}/include/" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${TERMCAP_DIR}/include/" >&5
-echo $ECHO_N "checking for ${TERMCAP_DIR}/include/... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${TERMCAP_DIR}/include/ usability" >&5
-echo $ECHO_N "checking ${TERMCAP_DIR}/include/ usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${TERMCAP_DIR}/include/>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${TERMCAP_DIR}/include/ presence" >&5
-echo $ECHO_N "checking ${TERMCAP_DIR}/include/ presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${TERMCAP_DIR}/include/>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TERMCAP_DIR}/include/: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${TERMCAP_DIR}/include/: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${TERMCAP_DIR}/include/" >&5
-echo $ECHO_N "checking for ${TERMCAP_DIR}/include/... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- TERMCAP_HEADER_FOUND=1
-else
- TERMCAP_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "x" != "x" ; then
- if test "${ac_cv_header_+set}" = set; then
- { echo "$as_me:$LINENO: checking for " >&5
-echo $ECHO_N "checking for ... $ECHO_C" >&6; }
-if test "${ac_cv_header_+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_" >&5
-echo "${ECHO_T}$ac_cv_header_" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking usability" >&5
-echo $ECHO_N "checking usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking presence" >&5
-echo $ECHO_N "checking presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: : accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: : accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: : proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: : proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: : present but cannot be compiled" >&5
-echo "$as_me: WARNING: : present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: : check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: : check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: : see the Autoconf documentation" >&5
-echo "$as_me: WARNING: : see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: : section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: : section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: : proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: : proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: : in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: : in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for " >&5
-echo $ECHO_N "checking for ... $ECHO_C" >&6; }
-if test "${ac_cv_header_+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_" >&5
-echo "${ECHO_T}$ac_cv_header_" >&6; }
-
-fi
-if test $ac_cv_header_ = yes; then
- TERMCAP_HEADER_FOUND=1
-else
- TERMCAP_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${TERMCAP_HEADER_FOUND}" = "x0" ; then
- if test -n "${TERMCAP_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the termcap development package installed." >&5
-echo "$as_me: *** It appears that you do not have the termcap development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${TERMCAP_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${TERMCAP_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${TERMCAP_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${TERMCAP_OPTION}" >&6;}
- exit 1
- fi
- TERMCAP_LIB=""
- TERMCAP_INCLUDE=""
- PBX_TERMCAP=0
- else
- PBX_TERMCAP=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_TERMCAP 1
-_ACEOF
-
- fi
- elif test -n "${TERMCAP_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${TERMCAP_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${TERMCAP_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${TERMCAP_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${TERMCAP_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_TINFO}" != "no"; then
- pbxlibdir=""
- if test "x${TINFO_DIR}" != "x"; then
- if test -d ${TINFO_DIR}/lib; then
- pbxlibdir="-L${TINFO_DIR}/lib"
- else
- pbxlibdir="-L${TINFO_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for tgetent in -ltinfo" >&5
-echo $ECHO_N "checking for tgetent in -ltinfo... $ECHO_C" >&6; }
-if test "${ac_cv_lib_tinfo_tgetent+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ltinfo ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char tgetent ();
-int
-main ()
-{
-return tgetent ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_tinfo_tgetent=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_tinfo_tgetent=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_tinfo_tgetent" >&5
-echo "${ECHO_T}$ac_cv_lib_tinfo_tgetent" >&6; }
-if test $ac_cv_lib_tinfo_tgetent = yes; then
- AST_TINFO_FOUND=yes
-else
- AST_TINFO_FOUND=no
-fi
-
-
- if test "${AST_TINFO_FOUND}" = "yes"; then
- TINFO_LIB="-ltinfo "
- TINFO_HEADER_FOUND="1"
- if test "x${TINFO_DIR}" != "x"; then
- TINFO_LIB="${pbxlibdir} ${TINFO_LIB}"
- TINFO_INCLUDE="-I${TINFO_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${TINFO_DIR}/include"
- if test "x" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${TINFO_DIR}/include/" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${TINFO_DIR}/include/" >&5
-echo $ECHO_N "checking for ${TINFO_DIR}/include/... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${TINFO_DIR}/include/ usability" >&5
-echo $ECHO_N "checking ${TINFO_DIR}/include/ usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${TINFO_DIR}/include/>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${TINFO_DIR}/include/ presence" >&5
-echo $ECHO_N "checking ${TINFO_DIR}/include/ presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${TINFO_DIR}/include/>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TINFO_DIR}/include/: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${TINFO_DIR}/include/: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${TINFO_DIR}/include/" >&5
-echo $ECHO_N "checking for ${TINFO_DIR}/include/... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- TINFO_HEADER_FOUND=1
-else
- TINFO_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "x" != "x" ; then
- if test "${ac_cv_header_+set}" = set; then
- { echo "$as_me:$LINENO: checking for " >&5
-echo $ECHO_N "checking for ... $ECHO_C" >&6; }
-if test "${ac_cv_header_+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_" >&5
-echo "${ECHO_T}$ac_cv_header_" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking usability" >&5
-echo $ECHO_N "checking usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking presence" >&5
-echo $ECHO_N "checking presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: : accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: : accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: : proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: : proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: : present but cannot be compiled" >&5
-echo "$as_me: WARNING: : present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: : check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: : check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: : see the Autoconf documentation" >&5
-echo "$as_me: WARNING: : see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: : section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: : section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: : proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: : proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: : in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: : in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for " >&5
-echo $ECHO_N "checking for ... $ECHO_C" >&6; }
-if test "${ac_cv_header_+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_" >&5
-echo "${ECHO_T}$ac_cv_header_" >&6; }
-
-fi
-if test $ac_cv_header_ = yes; then
- TINFO_HEADER_FOUND=1
-else
- TINFO_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${TINFO_HEADER_FOUND}" = "x0" ; then
- if test -n "${TINFO_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the tinfo development package installed." >&5
-echo "$as_me: *** It appears that you do not have the tinfo development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${TINFO_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${TINFO_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${TINFO_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${TINFO_OPTION}" >&6;}
- exit 1
- fi
- TINFO_LIB=""
- TINFO_INCLUDE=""
- PBX_TINFO=0
- else
- PBX_TINFO=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_TINFO 1
-_ACEOF
-
- fi
- elif test -n "${TINFO_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${TINFO_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${TINFO_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${TINFO_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${TINFO_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${host_os}" != "linux-gnu" ; then
- tonezone_extra="-lm"
-fi
-
-
-if test "${USE_TONEZONE}" != "no"; then
- pbxlibdir=""
- if test "x${TONEZONE_DIR}" != "x"; then
- if test -d ${TONEZONE_DIR}/lib; then
- pbxlibdir="-L${TONEZONE_DIR}/lib"
- else
- pbxlibdir="-L${TONEZONE_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for tone_zone_find in -ltonezone" >&5
-echo $ECHO_N "checking for tone_zone_find in -ltonezone... $ECHO_C" >&6; }
-if test "${ac_cv_lib_tonezone_tone_zone_find+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ltonezone ${pbxlibdir} ${tonezone_extra} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char tone_zone_find ();
-int
-main ()
-{
-return tone_zone_find ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_tonezone_tone_zone_find=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_tonezone_tone_zone_find=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_tonezone_tone_zone_find" >&5
-echo "${ECHO_T}$ac_cv_lib_tonezone_tone_zone_find" >&6; }
-if test $ac_cv_lib_tonezone_tone_zone_find = yes; then
- AST_TONEZONE_FOUND=yes
-else
- AST_TONEZONE_FOUND=no
-fi
-
-
- if test "${AST_TONEZONE_FOUND}" = "yes"; then
- TONEZONE_LIB="-ltonezone ${tonezone_extra}"
- TONEZONE_HEADER_FOUND="1"
- if test "x${TONEZONE_DIR}" != "x"; then
- TONEZONE_LIB="${pbxlibdir} ${TONEZONE_LIB}"
- TONEZONE_INCLUDE="-I${TONEZONE_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${TONEZONE_DIR}/include"
- if test "xzaptel/tonezone.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${TONEZONE_DIR}/include/zaptel/tonezone.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${TONEZONE_DIR}/include/zaptel/tonezone.h" >&5
-echo $ECHO_N "checking for ${TONEZONE_DIR}/include/zaptel/tonezone.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${TONEZONE_DIR}/include/zaptel/tonezone.h usability" >&5
-echo $ECHO_N "checking ${TONEZONE_DIR}/include/zaptel/tonezone.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${TONEZONE_DIR}/include/zaptel/tonezone.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${TONEZONE_DIR}/include/zaptel/tonezone.h presence" >&5
-echo $ECHO_N "checking ${TONEZONE_DIR}/include/zaptel/tonezone.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${TONEZONE_DIR}/include/zaptel/tonezone.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${TONEZONE_DIR}/include/zaptel/tonezone.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${TONEZONE_DIR}/include/zaptel/tonezone.h" >&5
-echo $ECHO_N "checking for ${TONEZONE_DIR}/include/zaptel/tonezone.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- TONEZONE_HEADER_FOUND=1
-else
- TONEZONE_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xzaptel/tonezone.h" != "x" ; then
- if test "${ac_cv_header_zaptel_tonezone_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for zaptel/tonezone.h" >&5
-echo $ECHO_N "checking for zaptel/tonezone.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zaptel_tonezone_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zaptel_tonezone_h" >&5
-echo "${ECHO_T}$ac_cv_header_zaptel_tonezone_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking zaptel/tonezone.h usability" >&5
-echo $ECHO_N "checking zaptel/tonezone.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <zaptel/tonezone.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking zaptel/tonezone.h presence" >&5
-echo $ECHO_N "checking zaptel/tonezone.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zaptel/tonezone.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: zaptel/tonezone.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: zaptel/tonezone.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for zaptel/tonezone.h" >&5
-echo $ECHO_N "checking for zaptel/tonezone.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zaptel_tonezone_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_zaptel_tonezone_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zaptel_tonezone_h" >&5
-echo "${ECHO_T}$ac_cv_header_zaptel_tonezone_h" >&6; }
-
-fi
-if test $ac_cv_header_zaptel_tonezone_h = yes; then
- TONEZONE_HEADER_FOUND=1
-else
- TONEZONE_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${TONEZONE_HEADER_FOUND}" = "x0" ; then
- if test -n "${TONEZONE_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the tonezone development package installed." >&5
-echo "$as_me: *** It appears that you do not have the tonezone development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${TONEZONE_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${TONEZONE_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${TONEZONE_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${TONEZONE_OPTION}" >&6;}
- exit 1
- fi
- TONEZONE_LIB=""
- TONEZONE_INCLUDE=""
- PBX_TONEZONE=0
- else
- PBX_TONEZONE=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_TONEZONE 1
-_ACEOF
-
- fi
- elif test -n "${TONEZONE_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${TONEZONE_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${TONEZONE_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${TONEZONE_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${TONEZONE_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_USB}" != "no"; then
- pbxlibdir=""
- if test "x${USB_DIR}" != "x"; then
- if test -d ${USB_DIR}/lib; then
- pbxlibdir="-L${USB_DIR}/lib"
- else
- pbxlibdir="-L${USB_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for usb_init in -lusb" >&5
-echo $ECHO_N "checking for usb_init in -lusb... $ECHO_C" >&6; }
-if test "${ac_cv_lib_usb_usb_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lusb ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char usb_init ();
-int
-main ()
-{
-return usb_init ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_usb_usb_init=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_usb_usb_init=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_init" >&5
-echo "${ECHO_T}$ac_cv_lib_usb_usb_init" >&6; }
-if test $ac_cv_lib_usb_usb_init = yes; then
- AST_USB_FOUND=yes
-else
- AST_USB_FOUND=no
-fi
-
-
- if test "${AST_USB_FOUND}" = "yes"; then
- USB_LIB="-lusb "
- USB_HEADER_FOUND="1"
- if test "x${USB_DIR}" != "x"; then
- USB_LIB="${pbxlibdir} ${USB_LIB}"
- USB_INCLUDE="-I${USB_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${USB_DIR}/include"
- if test "xusb.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${USB_DIR}/include/usb.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${USB_DIR}/include/usb.h" >&5
-echo $ECHO_N "checking for ${USB_DIR}/include/usb.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${USB_DIR}/include/usb.h usability" >&5
-echo $ECHO_N "checking ${USB_DIR}/include/usb.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${USB_DIR}/include/usb.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${USB_DIR}/include/usb.h presence" >&5
-echo $ECHO_N "checking ${USB_DIR}/include/usb.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${USB_DIR}/include/usb.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${USB_DIR}/include/usb.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${USB_DIR}/include/usb.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${USB_DIR}/include/usb.h" >&5
-echo $ECHO_N "checking for ${USB_DIR}/include/usb.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- USB_HEADER_FOUND=1
-else
- USB_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xusb.h" != "x" ; then
- if test "${ac_cv_header_usb_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for usb.h" >&5
-echo $ECHO_N "checking for usb.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_usb_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_usb_h" >&5
-echo "${ECHO_T}$ac_cv_header_usb_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking usb.h usability" >&5
-echo $ECHO_N "checking usb.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <usb.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking usb.h presence" >&5
-echo $ECHO_N "checking usb.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <usb.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: usb.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: usb.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: usb.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: usb.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: usb.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: usb.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: usb.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: usb.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: usb.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: usb.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: usb.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: usb.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: usb.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: usb.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: usb.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: usb.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for usb.h" >&5
-echo $ECHO_N "checking for usb.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_usb_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_usb_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_usb_h" >&5
-echo "${ECHO_T}$ac_cv_header_usb_h" >&6; }
-
-fi
-if test $ac_cv_header_usb_h = yes; then
- USB_HEADER_FOUND=1
-else
- USB_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${USB_HEADER_FOUND}" = "x0" ; then
- if test -n "${USB_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the usb development package installed." >&5
-echo "$as_me: *** It appears that you do not have the usb development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${USB_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${USB_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${USB_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${USB_OPTION}" >&6;}
- exit 1
- fi
- USB_LIB=""
- USB_INCLUDE=""
- PBX_USB=0
- else
- PBX_USB=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_USB 1
-_ACEOF
-
- fi
- elif test -n "${USB_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${USB_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${USB_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${USB_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${USB_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-
-if test "${USE_VORBIS}" != "no"; then
- pbxlibdir=""
- if test "x${VORBIS_DIR}" != "x"; then
- if test -d ${VORBIS_DIR}/lib; then
- pbxlibdir="-L${VORBIS_DIR}/lib"
- else
- pbxlibdir="-L${VORBIS_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for vorbis_info_init in -lvorbis" >&5
-echo $ECHO_N "checking for vorbis_info_init in -lvorbis... $ECHO_C" >&6; }
-if test "${ac_cv_lib_vorbis_vorbis_info_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lvorbis ${pbxlibdir} -lm -lvorbisenc $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char vorbis_info_init ();
-int
-main ()
-{
-return vorbis_info_init ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_vorbis_vorbis_info_init=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_vorbis_vorbis_info_init=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_vorbis_vorbis_info_init" >&5
-echo "${ECHO_T}$ac_cv_lib_vorbis_vorbis_info_init" >&6; }
-if test $ac_cv_lib_vorbis_vorbis_info_init = yes; then
- AST_VORBIS_FOUND=yes
-else
- AST_VORBIS_FOUND=no
-fi
-
-
- if test "${AST_VORBIS_FOUND}" = "yes"; then
- VORBIS_LIB="-lvorbis -lm -lvorbisenc"
- VORBIS_HEADER_FOUND="1"
- if test "x${VORBIS_DIR}" != "x"; then
- VORBIS_LIB="${pbxlibdir} ${VORBIS_LIB}"
- VORBIS_INCLUDE="-I${VORBIS_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${VORBIS_DIR}/include"
- if test "xvorbis/codec.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${VORBIS_DIR}/include/vorbis/codec.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${VORBIS_DIR}/include/vorbis/codec.h" >&5
-echo $ECHO_N "checking for ${VORBIS_DIR}/include/vorbis/codec.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${VORBIS_DIR}/include/vorbis/codec.h usability" >&5
-echo $ECHO_N "checking ${VORBIS_DIR}/include/vorbis/codec.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${VORBIS_DIR}/include/vorbis/codec.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${VORBIS_DIR}/include/vorbis/codec.h presence" >&5
-echo $ECHO_N "checking ${VORBIS_DIR}/include/vorbis/codec.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${VORBIS_DIR}/include/vorbis/codec.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${VORBIS_DIR}/include/vorbis/codec.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${VORBIS_DIR}/include/vorbis/codec.h" >&5
-echo $ECHO_N "checking for ${VORBIS_DIR}/include/vorbis/codec.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- VORBIS_HEADER_FOUND=1
-else
- VORBIS_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xvorbis/codec.h" != "x" ; then
- if test "${ac_cv_header_vorbis_codec_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for vorbis/codec.h" >&5
-echo $ECHO_N "checking for vorbis/codec.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_vorbis_codec_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_vorbis_codec_h" >&5
-echo "${ECHO_T}$ac_cv_header_vorbis_codec_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking vorbis/codec.h usability" >&5
-echo $ECHO_N "checking vorbis/codec.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <vorbis/codec.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking vorbis/codec.h presence" >&5
-echo $ECHO_N "checking vorbis/codec.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <vorbis/codec.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: vorbis/codec.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: vorbis/codec.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: vorbis/codec.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: vorbis/codec.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: vorbis/codec.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: vorbis/codec.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: vorbis/codec.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: vorbis/codec.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: vorbis/codec.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for vorbis/codec.h" >&5
-echo $ECHO_N "checking for vorbis/codec.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_vorbis_codec_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_vorbis_codec_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_vorbis_codec_h" >&5
-echo "${ECHO_T}$ac_cv_header_vorbis_codec_h" >&6; }
-
-fi
-if test $ac_cv_header_vorbis_codec_h = yes; then
- VORBIS_HEADER_FOUND=1
-else
- VORBIS_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${VORBIS_HEADER_FOUND}" = "x0" ; then
- if test -n "${VORBIS_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the vorbis development package installed." >&5
-echo "$as_me: *** It appears that you do not have the vorbis development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${VORBIS_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${VORBIS_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${VORBIS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${VORBIS_OPTION}" >&6;}
- exit 1
- fi
- VORBIS_LIB=""
- VORBIS_INCLUDE=""
- PBX_VORBIS=0
- else
- PBX_VORBIS=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_VORBIS 1
-_ACEOF
-
- fi
- elif test -n "${VORBIS_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${VORBIS_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${VORBIS_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${VORBIS_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${VORBIS_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-if test "${USE_VPB}" != "no"; then
- { echo "$as_me:$LINENO: checking for vpb_open in -lvpb" >&5
-echo $ECHO_N "checking for vpb_open in -lvpb... $ECHO_C" >&6; }
- saved_libs="${LIBS}"
- saved_cppflags="${CPPFLAGS}"
- if test "x${VPB_DIR}" != "x"; then
- if test -d ${VPB_DIR}/lib; then
- vpblibdir=${VPB_DIR}/lib
- else
- vpblibdir=${VPB_DIR}
- fi
- LIBS="${LIBS} -L${vpblibdir}"
- CPPFLAGS="${CPPFLAGS} -I${VPB_DIR}/include"
- fi
- LIBS="${LIBS} -lvpb -lpthread"
- cat >conftest.$ac_ext <<_ACEOF
-
- /* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <vpbapi.h>
-int
-main ()
-{
-int q = vpb_open(0,0);
- ;
- return 0;
-}
-
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_lib_vpb_vpb_open="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_lib_vpb_vpb_open="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_lib_vpb_vpb_open}" = "yes"; then
- VPB_LIB="-lvpb"
- if test "${VPB_DIR}" != ""; then
- VPB_LIB="-L${vpblibdir} ${VPB_LIB}"
- VPB_INCLUDE="-I${VPB_DIR}/include"
- fi
- PBX_VPB=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_VPB 1
-_ACEOF
-
- elif test -n "${VPB_MANDATORY}"; then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The VoiceTronix (vpb) installation on this system appears to be broken." >&5
-echo "$as_me: *** The VoiceTronix (vpb) installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-vpb." >&5
-echo "$as_me: *** including --without-vpb." >&6;}
- exit 1
- fi
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-if test "${USE_ZLIB}" != "no"; then
- pbxlibdir=""
- if test "x${ZLIB_DIR}" != "x"; then
- if test -d ${ZLIB_DIR}/lib; then
- pbxlibdir="-L${ZLIB_DIR}/lib"
- else
- pbxlibdir="-L${ZLIB_DIR}"
- fi
- fi
- { echo "$as_me:$LINENO: checking for compress in -lz" >&5
-echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_compress+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lz ${pbxlibdir} $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char compress ();
-int
-main ()
-{
-return compress ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_z_compress=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_z_compress=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5
-echo "${ECHO_T}$ac_cv_lib_z_compress" >&6; }
-if test $ac_cv_lib_z_compress = yes; then
- AST_ZLIB_FOUND=yes
-else
- AST_ZLIB_FOUND=no
-fi
-
-
- if test "${AST_ZLIB_FOUND}" = "yes"; then
- ZLIB_LIB="-lz "
- ZLIB_HEADER_FOUND="1"
- if test "x${ZLIB_DIR}" != "x"; then
- ZLIB_LIB="${pbxlibdir} ${ZLIB_LIB}"
- ZLIB_INCLUDE="-I${ZLIB_DIR}/include"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${ZLIB_DIR}/include"
- if test "xzlib.h" != "x" ; then
- as_ac_Header=`echo "ac_cv_header_${ZLIB_DIR}/include/zlib.h" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for ${ZLIB_DIR}/include/zlib.h" >&5
-echo $ECHO_N "checking for ${ZLIB_DIR}/include/zlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ${ZLIB_DIR}/include/zlib.h usability" >&5
-echo $ECHO_N "checking ${ZLIB_DIR}/include/zlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <${ZLIB_DIR}/include/zlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking ${ZLIB_DIR}/include/zlib.h presence" >&5
-echo $ECHO_N "checking ${ZLIB_DIR}/include/zlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <${ZLIB_DIR}/include/zlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: ${ZLIB_DIR}/include/zlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ${ZLIB_DIR}/include/zlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for ${ZLIB_DIR}/include/zlib.h" >&5
-echo $ECHO_N "checking for ${ZLIB_DIR}/include/zlib.h... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- ZLIB_HEADER_FOUND=1
-else
- ZLIB_HEADER_FOUND=0
-fi
-
-
- fi
- CPPFLAGS="${saved_cppflags}"
- else
- if test "xzlib.h" != "x" ; then
- if test "${ac_cv_header_zlib_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking zlib.h usability" >&5
-echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <zlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking zlib.h presence" >&5
-echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zlib.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_zlib_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; }
-
-fi
-if test $ac_cv_header_zlib_h = yes; then
- ZLIB_HEADER_FOUND=1
-else
- ZLIB_HEADER_FOUND=0
-fi
-
-
- fi
- fi
- if test "x${ZLIB_HEADER_FOUND}" = "x0" ; then
- if test -n "${ZLIB_MANDATORY}" ;
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** It appears that you do not have the z development package installed." >&5
-echo "$as_me: *** It appears that you do not have the z development package installed." >&6;}
- { echo "$as_me:$LINENO: *** Please install it to include ${ZLIB_DESCRIP} support, or re-run configure" >&5
-echo "$as_me: *** Please install it to include ${ZLIB_DESCRIP} support, or re-run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${ZLIB_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${ZLIB_OPTION}" >&6;}
- exit 1
- fi
- ZLIB_LIB=""
- ZLIB_INCLUDE=""
- PBX_ZLIB=0
- else
- PBX_ZLIB=1
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ZLIB 1
-_ACEOF
-
- fi
- elif test -n "${ZLIB_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The ${ZLIB_DESCRIP} installation on this system appears to be broken." >&5
-echo "$as_me: *** The ${ZLIB_DESCRIP} installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** without explicitly specifying --with-${ZLIB_OPTION}" >&5
-echo "$as_me: *** without explicitly specifying --with-${ZLIB_OPTION}" >&6;}
- exit 1
- fi
-fi
-
-
-if test "${USE_ZAPTEL}" != "no"; then
- { echo "$as_me:$LINENO: checking for ZT_DIAL_OP_CANCEL in zaptel/zaptel.h" >&5
-echo $ECHO_N "checking for ZT_DIAL_OP_CANCEL in zaptel/zaptel.h... $ECHO_C" >&6; }
- saved_cppflags="${CPPFLAGS}"
- if test "x${ZAPTEL_DIR}" != "x"; then
- CPPFLAGS="${CPPFLAGS} -I${ZAPTEL_DIR}/include"
- fi
- cat >conftest.$ac_ext <<_ACEOF
-
- /* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zaptel/zaptel.h>
-int
-main ()
-{
-int foo = ZT_DIAL_OP_CANCEL;
- ;
- return 0;
-}
-
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_zaptel_h="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_zaptel_h="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_zaptel_h}" = "yes"; then
- if test "${ZAPTEL_DIR}" != ""; then
- ZAPTEL_INCLUDE="-I${ZAPTEL_DIR}/include"
- fi
- PBX_ZAPTEL=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ZAPTEL 1
-_ACEOF
-
- elif test -n "${ZAPTEL_MANDATORY}";
- then
- { echo "$as_me:$LINENO: ***" >&5
-echo "$as_me: ***" >&6;}
- { echo "$as_me:$LINENO: *** The Zaptel installation on this system appears to be broken." >&5
-echo "$as_me: *** The Zaptel installation on this system appears to be broken." >&6;}
- { echo "$as_me:$LINENO: *** Either correct the installation, or run configure" >&5
-echo "$as_me: *** Either correct the installation, or run configure" >&6;}
- { echo "$as_me:$LINENO: *** including --without-zaptel." >&5
-echo "$as_me: *** including --without-zaptel." >&6;}
- exit 1
- fi
-fi
-
-if test "${PBX_ZAPTEL}" = 1; then
- { echo "$as_me:$LINENO: checking for ZT_EVENT_REMOVED in zaptel/zaptel.h" >&5
-echo $ECHO_N "checking for ZT_EVENT_REMOVED in zaptel/zaptel.h... $ECHO_C" >&6; }
- saved_cppflags="${CPPFLAGS}"
- if test "x${ZAPTEL_DIR}" != "x"; then
- CPPFLAGS="${CPPFLAGS} -I${ZAPTEL_DIR}/include"
- fi
- cat >conftest.$ac_ext <<_ACEOF
-
- /* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zaptel/zaptel.h>
-int
-main ()
-{
-int foo = ZT_EVENT_REMOVED;
- ;
- return 0;
-}
-
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_zaptel_vldtmf="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_zaptel_vldtmf="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_zaptel_vldtmf}" = "yes"; then
- PBX_ZAPTEL_VLDTMF=1
- fi
- { echo "$as_me:$LINENO: checking for ZT_TCOP_ALLOCATE in zaptel/zaptel.h" >&5
-echo $ECHO_N "checking for ZT_TCOP_ALLOCATE in zaptel/zaptel.h... $ECHO_C" >&6; }
- saved_cppflags="${CPPFLAGS}"
- if test "x${ZAPTEL_DIR}" != "x"; then
- CPPFLAGS="${CPPFLAGS} -I${ZAPTEL_DIR}/include"
- fi
- cat >conftest.$ac_ext <<_ACEOF
-
- /* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zaptel/zaptel.h>
-int
-main ()
-{
-int foo = ZT_TCOP_ALLOCATE;
- ;
- return 0;
-}
-
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_zaptel_transcode="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_zaptel_transcode="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_zaptel_transcode}" = "yes"; then
- PBX_ZAPTEL_TRANSCODE=1
- fi
-fi
-
-
-
-EDITLINE_LIB=""
-if test "x$TERMCAP_LIB" != "x" ; then
- EDITLINE_LIB="$TERMCAP_LIB"
-elif test "x$TINFO_LIB" != "x" ; then
- EDITLINE_LIB="$TINFO_LIB"
-elif test "x$CURSES_LIB" != "x" ; then
- EDITLINE_LIB="$CURSES_LIB"
-elif test "x$NCURSES_LIB" != "x" ; then
- EDITLINE_LIB="$NCURSES_LIB"
-else
- { { echo "$as_me:$LINENO: error: *** termcap support not found" >&5
-echo "$as_me: error: *** termcap support not found" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-if test "${ac_cv_header_h323_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for h323.h" >&5
-echo $ECHO_N "checking for h323.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_h323_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_h323_h" >&5
-echo "${ECHO_T}$ac_cv_header_h323_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking h323.h usability" >&5
-echo $ECHO_N "checking h323.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <h323.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking h323.h presence" >&5
-echo $ECHO_N "checking h323.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <h323.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: h323.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: h323.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: h323.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: h323.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: h323.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: h323.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: h323.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: h323.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: h323.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: h323.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: h323.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: h323.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: h323.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: h323.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: h323.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: h323.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for h323.h" >&5
-echo $ECHO_N "checking for h323.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_h323_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_h323_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_h323_h" >&5
-echo "${ECHO_T}$ac_cv_header_h323_h" >&6; }
-
-fi
-if test $ac_cv_header_h323_h = yes; then
- PBX_H323=1
-else
- PBX_H323=0
-fi
-
-
-
-
-if test "${ac_cv_header_linux_compiler_h+set}" = set; then
- { echo "$as_me:$LINENO: checking for linux/compiler.h" >&5
-echo $ECHO_N "checking for linux/compiler.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_compiler_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_compiler_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_compiler_h" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking linux/compiler.h usability" >&5
-echo $ECHO_N "checking linux/compiler.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <linux/compiler.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking linux/compiler.h presence" >&5
-echo $ECHO_N "checking linux/compiler.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <linux/compiler.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: linux/compiler.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: linux/compiler.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: linux/compiler.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: linux/compiler.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: linux/compiler.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: linux/compiler.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: linux/compiler.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: linux/compiler.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: linux/compiler.h: in the future, the compiler will take precedence" >&2;}
- ( cat <<\_ASBOX
-## ------------------------------- ##
-## Report this to www.asterisk.org ##
-## ------------------------------- ##
-_ASBOX
- ) | sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for linux/compiler.h" >&5
-echo $ECHO_N "checking for linux/compiler.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_compiler_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_linux_compiler_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_compiler_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_compiler_h" >&6; }
-
-fi
-if test $ac_cv_header_linux_compiler_h = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_LINUX_COMPILER_H 1
-_ACEOF
-
-fi
-
-
-
-{ echo "$as_me:$LINENO: checking for linux/ixjuser.h" >&5
-echo $ECHO_N "checking for linux/ixjuser.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_linux_ixjuser_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
- #include <linux/version.h>
- #ifdef HAVE_LINUX_COMPILER_H
- #include <linux/compiler.h>
- #endif
-
-
-#include <linux/ixjuser.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_header_linux_ixjuser_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_header_linux_ixjuser_h=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_ixjuser_h" >&5
-echo "${ECHO_T}$ac_cv_header_linux_ixjuser_h" >&6; }
-if test $ac_cv_header_linux_ixjuser_h = yes; then
- PBX_IXJUSER=1
-else
- PBX_IXJUSER=0
-fi
-
-
-
-
-if test "${cross_compiling}" = "no";
-then
- { echo "$as_me:$LINENO: checking for /sbin/launchd" >&5
-echo $ECHO_N "checking for /sbin/launchd... $ECHO_C" >&6; }
-if test "${ac_cv_file__sbin_launchd+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- test "$cross_compiling" = yes &&
- { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
- { (exit 1); exit 1; }; }
-if test -r "/sbin/launchd"; then
- ac_cv_file__sbin_launchd=yes
-else
- ac_cv_file__sbin_launchd=no
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_file__sbin_launchd" >&5
-echo "${ECHO_T}$ac_cv_file__sbin_launchd" >&6; }
-if test $ac_cv_file__sbin_launchd = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_SBIN_LAUNCHD 1
-_ACEOF
-
-fi
-
-fi
-
-PBX_GTK=0
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gtk-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gtk-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_GTKCONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$GTKCONFIG"; then
- ac_cv_prog_GTKCONFIG="$GTKCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_GTKCONFIG="${ac_tool_prefix}gtk-config"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-GTKCONFIG=$ac_cv_prog_GTKCONFIG
-if test -n "$GTKCONFIG"; then
- { echo "$as_me:$LINENO: result: $GTKCONFIG" >&5
-echo "${ECHO_T}$GTKCONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_GTKCONFIG"; then
- ac_ct_GTKCONFIG=$GTKCONFIG
- # Extract the first word of "gtk-config", so it can be a program name with args.
-set dummy gtk-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_GTKCONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_GTKCONFIG"; then
- ac_cv_prog_ac_ct_GTKCONFIG="$ac_ct_GTKCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_GTKCONFIG="gtk-config"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_GTKCONFIG=$ac_cv_prog_ac_ct_GTKCONFIG
-if test -n "$ac_ct_GTKCONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_ct_GTKCONFIG" >&5
-echo "${ECHO_T}$ac_ct_GTKCONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_GTKCONFIG" = x; then
- GTKCONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- GTKCONFIG=$ac_ct_GTKCONFIG
- fi
-else
- GTKCONFIG="$ac_cv_prog_GTKCONFIG"
-fi
-
-if test ! "x${GTKCONFIG}" = xNo; then
- GTK_INCLUDE=$(${GTKCONFIG} --cflags gthread)
- GTK_LIB=$(${GTKCONFIG} --libs gthread)
- PBX_GTK=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GTK 1
-_ACEOF
-
-fi
-
-
-
-
-PBX_GTK2=0
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_PKGCONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$PKGCONFIG"; then
- ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_PKGCONFIG="${ac_tool_prefix}pkg-config"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-PKGCONFIG=$ac_cv_prog_PKGCONFIG
-if test -n "$PKGCONFIG"; then
- { echo "$as_me:$LINENO: result: $PKGCONFIG" >&5
-echo "${ECHO_T}$PKGCONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_PKGCONFIG"; then
- ac_ct_PKGCONFIG=$PKGCONFIG
- # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_PKGCONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_PKGCONFIG"; then
- ac_cv_prog_ac_ct_PKGCONFIG="$ac_ct_PKGCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_PKGCONFIG="pkg-config"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_PKGCONFIG=$ac_cv_prog_ac_ct_PKGCONFIG
-if test -n "$ac_ct_PKGCONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_ct_PKGCONFIG" >&5
-echo "${ECHO_T}$ac_ct_PKGCONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_PKGCONFIG" = x; then
- PKGCONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- PKGCONFIG=$ac_ct_PKGCONFIG
- fi
-else
- PKGCONFIG="$ac_cv_prog_PKGCONFIG"
-fi
-
-if test ! "x${PKGCONFIG}" = xNo; then
- GTK2_INCLUDE=$(${PKGCONFIG} gtk+-2.0 --cflags 2>/dev/null)
- GTK2_LIB=$(${PKGCONFIG} gtk+-2.0 --libs)
- PBX_GTK2=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GTK2 1
-_ACEOF
-
-fi
-
-
-
-
-if test "${USE_CURL}" != "no"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}curl-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}curl-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_CURL_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $CURL_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_CURL_CONFIG="$CURL_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_CURL_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-CURL_CONFIG=$ac_cv_path_CURL_CONFIG
-if test -n "$CURL_CONFIG"; then
- { echo "$as_me:$LINENO: result: $CURL_CONFIG" >&5
-echo "${ECHO_T}$CURL_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_CURL_CONFIG"; then
- ac_pt_CURL_CONFIG=$CURL_CONFIG
- # Extract the first word of "curl-config", so it can be a program name with args.
-set dummy curl-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_ac_pt_CURL_CONFIG+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $ac_pt_CURL_CONFIG in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_ac_pt_CURL_CONFIG="$ac_pt_CURL_CONFIG" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_ac_pt_CURL_CONFIG="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-ac_pt_CURL_CONFIG=$ac_cv_path_ac_pt_CURL_CONFIG
-if test -n "$ac_pt_CURL_CONFIG"; then
- { echo "$as_me:$LINENO: result: $ac_pt_CURL_CONFIG" >&5
-echo "${ECHO_T}$ac_pt_CURL_CONFIG" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_pt_CURL_CONFIG" = x; then
- CURL_CONFIG="No"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- CURL_CONFIG=$ac_pt_CURL_CONFIG
- fi
-else
- CURL_CONFIG="$ac_cv_path_CURL_CONFIG"
-fi
-
- if test ! x"${CURL_CONFIG}" = xNo; then
- # check for version
- if test $(printf "%d" 0x$(${CURL_CONFIG} --vernum)) -ge $(printf "%d" 0x070907); then
- CURL_INCLUDE=$(${CURL_CONFIG} --cflags)
- CURL_LIB=$(${CURL_CONFIG} --libs)
-
- { echo "$as_me:$LINENO: checking for curl_version() in curl/curl.h" >&5
-echo $ECHO_N "checking for curl_version() in curl/curl.h... $ECHO_C" >&6; }
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} ${CURL_INCLUDE}"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <curl/curl.h>
-int
-main ()
-{
-curl_version();
- ;
- return 0;
-}
-
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
-
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- ac_cv_curl_h="yes"
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ac_cv_curl_h="no"
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_curl_h}" = "yes"; then
- PBX_CURL=1
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CURL 1
-_ACEOF
-
- fi
- fi
- fi
-fi
-
-ac_config_files="$ac_config_files build_tools/menuselect-deps makeopts channels/h323/Makefile"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- *) $as_unset $ac_var ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
- { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
- else
- { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: ${CONFIG_STATUS=./config.status}
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line after each line using $LINENO; the second 'sed'
- # does the real work. The second script uses 'N' to pair each
- # line-number line with the line containing $LINENO, and appends
- # trailing '-' during substitution so that $LINENO is not a special
- # case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # scripts with optimization help from Paolo Bonzini. Blame Lee
- # E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) ECHO_C='\c';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-
-# Save the log message, to keep $[0] and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by asterisk $as_me 1.4, which was
-generated by GNU Autoconf 2.61. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
-
-Usage: $0 [OPTIONS] [FILE]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- -q, --quiet do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
- --header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
-
-Configuration files:
-$config_files
-
-Configuration headers:
-$config_headers
-
-Report bugs to <bug-autoconf@gnu.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-ac_cs_version="\\
-asterisk config.status 1.4
-configured by $0, generated by GNU Autoconf 2.61,
- with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2006 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-INSTALL='$INSTALL'
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value. By we need to know if files were specified by the user.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- echo "$ac_cs_version"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- CONFIG_FILES="$CONFIG_FILES $ac_optarg"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
- ac_need_defaults=false;;
- --he | --h)
- # Conflict between --help and --header
- { echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; };;
- --help | --hel | -h )
- echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; } ;;
-
- *) ac_config_targets="$ac_config_targets $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-if \$ac_cs_recheck; then
- echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
- CONFIG_SHELL=$SHELL
- export CONFIG_SHELL
- exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "include/asterisk/autoconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS include/asterisk/autoconfig.h" ;;
- "build_tools/menuselect-deps") CONFIG_FILES="$CONFIG_FILES build_tools/menuselect-deps" ;;
- "makeopts") CONFIG_FILES="$CONFIG_FILES makeopts" ;;
- "channels/h323/Makefile") CONFIG_FILES="$CONFIG_FILES channels/h323/Makefile" ;;
-
- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
- { (exit 1); exit 1; }; };;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp=
- trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} ||
-{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
-}
-
-#
-# Set up the sed scripts for CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "$CONFIG_FILES"; then
-
-_ACEOF
-
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-build!$build$ac_delim
-build_cpu!$build_cpu$ac_delim
-build_vendor!$build_vendor$ac_delim
-build_os!$build_os$ac_delim
-host!$host$ac_delim
-host_cpu!$host_cpu$ac_delim
-host_vendor!$host_vendor$ac_delim
-host_os!$host_os$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CPP!$CPP$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-BUILD_PLATFORM!$BUILD_PLATFORM$ac_delim
-BUILD_CPU!$BUILD_CPU$ac_delim
-BUILD_VENDOR!$BUILD_VENDOR$ac_delim
-BUILD_OS!$BUILD_OS$ac_delim
-HOST_PLATFORM!$HOST_PLATFORM$ac_delim
-HOST_CPU!$HOST_CPU$ac_delim
-HOST_VENDOR!$HOST_VENDOR$ac_delim
-HOST_OS!$HOST_OS$ac_delim
-OSARCH!$OSARCH$ac_delim
-UNAME!$UNAME$ac_delim
-PBX_OSREV!$PBX_OSREV$ac_delim
-CXX!$CXX$ac_delim
-LD!$LD$ac_delim
-RANLIB!$RANLIB$ac_delim
-CXXFLAGS!$CXXFLAGS$ac_delim
-ac_ct_CXX!$ac_ct_CXX$ac_delim
-CXXCPP!$CXXCPP$ac_delim
-SED!$SED$ac_delim
-AWK!$AWK$ac_delim
-INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
-INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
-INSTALL_DATA!$INSTALL_DATA$ac_delim
-LN_S!$LN_S$ac_delim
-GNU_MAKE!$GNU_MAKE$ac_delim
-STRIP!$STRIP$ac_delim
-AR!$AR$ac_delim
-GNU_LD!$GNU_LD$ac_delim
-FIND!$FIND$ac_delim
-COMPRESS!$COMPRESS$ac_delim
-BASENAME!$BASENAME$ac_delim
-ID!$ID$ac_delim
-DIRNAME!$DIRNAME$ac_delim
-LN!$LN$ac_delim
-DOT!$DOT$ac_delim
-WGET!$WGET$ac_delim
-FETCH!$FETCH$ac_delim
-DOWNLOAD!$DOWNLOAD$ac_delim
-SOXMIX!$SOXMIX$ac_delim
-acx_pthread_config!$acx_pthread_config$ac_delim
-PTHREAD_CC!$PTHREAD_CC$ac_delim
-PTHREAD_LIBS!$PTHREAD_LIBS$ac_delim
-PTHREAD_CFLAGS!$PTHREAD_CFLAGS$ac_delim
-_ACEOF
-
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
- ac_eof=`expr $ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-CEOF$ac_eof
-_ACEOF
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-AST_DEVMODE!$AST_DEVMODE$ac_delim
-ALSA_LIB!$ALSA_LIB$ac_delim
-ALSA_INCLUDE!$ALSA_INCLUDE$ac_delim
-ALSA_DIR!$ALSA_DIR$ac_delim
-PBX_ALSA!$PBX_ALSA$ac_delim
-CURL_LIB!$CURL_LIB$ac_delim
-CURL_INCLUDE!$CURL_INCLUDE$ac_delim
-CURL_DIR!$CURL_DIR$ac_delim
-PBX_CURL!$PBX_CURL$ac_delim
-CAP_LIB!$CAP_LIB$ac_delim
-CAP_INCLUDE!$CAP_INCLUDE$ac_delim
-CAP_DIR!$CAP_DIR$ac_delim
-PBX_CAP!$PBX_CAP$ac_delim
-CURSES_LIB!$CURSES_LIB$ac_delim
-CURSES_INCLUDE!$CURSES_INCLUDE$ac_delim
-CURSES_DIR!$CURSES_DIR$ac_delim
-PBX_CURSES!$PBX_CURSES$ac_delim
-GNUTLS_LIB!$GNUTLS_LIB$ac_delim
-GNUTLS_INCLUDE!$GNUTLS_INCLUDE$ac_delim
-GNUTLS_DIR!$GNUTLS_DIR$ac_delim
-PBX_GNUTLS!$PBX_GNUTLS$ac_delim
-GSM_LIB!$GSM_LIB$ac_delim
-GSM_INCLUDE!$GSM_INCLUDE$ac_delim
-GSM_DIR!$GSM_DIR$ac_delim
-PBX_GSM!$PBX_GSM$ac_delim
-IKSEMEL_LIB!$IKSEMEL_LIB$ac_delim
-IKSEMEL_INCLUDE!$IKSEMEL_INCLUDE$ac_delim
-IKSEMEL_DIR!$IKSEMEL_DIR$ac_delim
-PBX_IKSEMEL!$PBX_IKSEMEL$ac_delim
-IMAP_TK_LIB!$IMAP_TK_LIB$ac_delim
-IMAP_TK_INCLUDE!$IMAP_TK_INCLUDE$ac_delim
-IMAP_TK_DIR!$IMAP_TK_DIR$ac_delim
-PBX_IMAP_TK!$PBX_IMAP_TK$ac_delim
-ISDNNET_LIB!$ISDNNET_LIB$ac_delim
-ISDNNET_INCLUDE!$ISDNNET_INCLUDE$ac_delim
-ISDNNET_DIR!$ISDNNET_DIR$ac_delim
-PBX_ISDNNET!$PBX_ISDNNET$ac_delim
-KDE_LIB!$KDE_LIB$ac_delim
-KDE_INCLUDE!$KDE_INCLUDE$ac_delim
-KDE_DIR!$KDE_DIR$ac_delim
-PBX_KDE!$PBX_KDE$ac_delim
-LTDL_LIB!$LTDL_LIB$ac_delim
-LTDL_INCLUDE!$LTDL_INCLUDE$ac_delim
-LTDL_DIR!$LTDL_DIR$ac_delim
-PBX_LTDL!$PBX_LTDL$ac_delim
-MISDN_LIB!$MISDN_LIB$ac_delim
-MISDN_INCLUDE!$MISDN_INCLUDE$ac_delim
-MISDN_DIR!$MISDN_DIR$ac_delim
-PBX_MISDN!$PBX_MISDN$ac_delim
-NBS_LIB!$NBS_LIB$ac_delim
-NBS_INCLUDE!$NBS_INCLUDE$ac_delim
-NBS_DIR!$NBS_DIR$ac_delim
-PBX_NBS!$PBX_NBS$ac_delim
-NCURSES_LIB!$NCURSES_LIB$ac_delim
-NCURSES_INCLUDE!$NCURSES_INCLUDE$ac_delim
-NCURSES_DIR!$NCURSES_DIR$ac_delim
-PBX_NCURSES!$PBX_NCURSES$ac_delim
-NETSNMP_LIB!$NETSNMP_LIB$ac_delim
-NETSNMP_INCLUDE!$NETSNMP_INCLUDE$ac_delim
-NETSNMP_DIR!$NETSNMP_DIR$ac_delim
-PBX_NETSNMP!$PBX_NETSNMP$ac_delim
-NEWT_LIB!$NEWT_LIB$ac_delim
-NEWT_INCLUDE!$NEWT_INCLUDE$ac_delim
-NEWT_DIR!$NEWT_DIR$ac_delim
-PBX_NEWT!$PBX_NEWT$ac_delim
-UNIXODBC_LIB!$UNIXODBC_LIB$ac_delim
-UNIXODBC_INCLUDE!$UNIXODBC_INCLUDE$ac_delim
-UNIXODBC_DIR!$UNIXODBC_DIR$ac_delim
-PBX_UNIXODBC!$PBX_UNIXODBC$ac_delim
-OGG_LIB!$OGG_LIB$ac_delim
-OGG_INCLUDE!$OGG_INCLUDE$ac_delim
-OGG_DIR!$OGG_DIR$ac_delim
-PBX_OGG!$PBX_OGG$ac_delim
-OSPTK_LIB!$OSPTK_LIB$ac_delim
-OSPTK_INCLUDE!$OSPTK_INCLUDE$ac_delim
-OSPTK_DIR!$OSPTK_DIR$ac_delim
-PBX_OSPTK!$PBX_OSPTK$ac_delim
-OSS_LIB!$OSS_LIB$ac_delim
-OSS_INCLUDE!$OSS_INCLUDE$ac_delim
-OSS_DIR!$OSS_DIR$ac_delim
-PBX_OSS!$PBX_OSS$ac_delim
-POPT_LIB!$POPT_LIB$ac_delim
-POPT_INCLUDE!$POPT_INCLUDE$ac_delim
-POPT_DIR!$POPT_DIR$ac_delim
-PBX_POPT!$PBX_POPT$ac_delim
-PGSQL_LIB!$PGSQL_LIB$ac_delim
-PGSQL_INCLUDE!$PGSQL_INCLUDE$ac_delim
-PGSQL_DIR!$PGSQL_DIR$ac_delim
-PBX_PGSQL!$PBX_PGSQL$ac_delim
-PRI_LIB!$PRI_LIB$ac_delim
-PRI_INCLUDE!$PRI_INCLUDE$ac_delim
-PRI_DIR!$PRI_DIR$ac_delim
-PBX_PRI!$PBX_PRI$ac_delim
-PWLIB_LIB!$PWLIB_LIB$ac_delim
-PWLIB_INCLUDE!$PWLIB_INCLUDE$ac_delim
-PWLIB_DIR!$PWLIB_DIR$ac_delim
-PBX_PWLIB!$PBX_PWLIB$ac_delim
-_ACEOF
-
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
- ac_eof=`expr $ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-CEOF$ac_eof
-_ACEOF
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-OPENH323_LIB!$OPENH323_LIB$ac_delim
-OPENH323_INCLUDE!$OPENH323_INCLUDE$ac_delim
-OPENH323_DIR!$OPENH323_DIR$ac_delim
-PBX_OPENH323!$PBX_OPENH323$ac_delim
-RADIUS_LIB!$RADIUS_LIB$ac_delim
-RADIUS_INCLUDE!$RADIUS_INCLUDE$ac_delim
-RADIUS_DIR!$RADIUS_DIR$ac_delim
-PBX_RADIUS!$PBX_RADIUS$ac_delim
-SPEEX_LIB!$SPEEX_LIB$ac_delim
-SPEEX_INCLUDE!$SPEEX_INCLUDE$ac_delim
-SPEEX_DIR!$SPEEX_DIR$ac_delim
-PBX_SPEEX!$PBX_SPEEX$ac_delim
-SPEEXDSP_LIB!$SPEEXDSP_LIB$ac_delim
-SPEEXDSP_INCLUDE!$SPEEXDSP_INCLUDE$ac_delim
-SPEEXDSP_DIR!$SPEEXDSP_DIR$ac_delim
-PBX_SPEEXDSP!$PBX_SPEEXDSP$ac_delim
-SQLITE_LIB!$SQLITE_LIB$ac_delim
-SQLITE_INCLUDE!$SQLITE_INCLUDE$ac_delim
-SQLITE_DIR!$SQLITE_DIR$ac_delim
-PBX_SQLITE!$PBX_SQLITE$ac_delim
-SUPPSERV_LIB!$SUPPSERV_LIB$ac_delim
-SUPPSERV_INCLUDE!$SUPPSERV_INCLUDE$ac_delim
-SUPPSERV_DIR!$SUPPSERV_DIR$ac_delim
-PBX_SUPPSERV!$PBX_SUPPSERV$ac_delim
-OPENSSL_LIB!$OPENSSL_LIB$ac_delim
-OPENSSL_INCLUDE!$OPENSSL_INCLUDE$ac_delim
-OPENSSL_DIR!$OPENSSL_DIR$ac_delim
-PBX_OPENSSL!$PBX_OPENSSL$ac_delim
-FREETDS_LIB!$FREETDS_LIB$ac_delim
-FREETDS_INCLUDE!$FREETDS_INCLUDE$ac_delim
-FREETDS_DIR!$FREETDS_DIR$ac_delim
-PBX_FREETDS!$PBX_FREETDS$ac_delim
-TERMCAP_LIB!$TERMCAP_LIB$ac_delim
-TERMCAP_INCLUDE!$TERMCAP_INCLUDE$ac_delim
-TERMCAP_DIR!$TERMCAP_DIR$ac_delim
-PBX_TERMCAP!$PBX_TERMCAP$ac_delim
-TINFO_LIB!$TINFO_LIB$ac_delim
-TINFO_INCLUDE!$TINFO_INCLUDE$ac_delim
-TINFO_DIR!$TINFO_DIR$ac_delim
-PBX_TINFO!$PBX_TINFO$ac_delim
-TONEZONE_LIB!$TONEZONE_LIB$ac_delim
-TONEZONE_INCLUDE!$TONEZONE_INCLUDE$ac_delim
-TONEZONE_DIR!$TONEZONE_DIR$ac_delim
-PBX_TONEZONE!$PBX_TONEZONE$ac_delim
-USB_LIB!$USB_LIB$ac_delim
-USB_INCLUDE!$USB_INCLUDE$ac_delim
-USB_DIR!$USB_DIR$ac_delim
-PBX_USB!$PBX_USB$ac_delim
-VORBIS_LIB!$VORBIS_LIB$ac_delim
-VORBIS_INCLUDE!$VORBIS_INCLUDE$ac_delim
-VORBIS_DIR!$VORBIS_DIR$ac_delim
-PBX_VORBIS!$PBX_VORBIS$ac_delim
-VPB_LIB!$VPB_LIB$ac_delim
-VPB_INCLUDE!$VPB_INCLUDE$ac_delim
-VPB_DIR!$VPB_DIR$ac_delim
-PBX_VPB!$PBX_VPB$ac_delim
-ZLIB_LIB!$ZLIB_LIB$ac_delim
-ZLIB_INCLUDE!$ZLIB_INCLUDE$ac_delim
-ZLIB_DIR!$ZLIB_DIR$ac_delim
-PBX_ZLIB!$PBX_ZLIB$ac_delim
-ZAPTEL_LIB!$ZAPTEL_LIB$ac_delim
-ZAPTEL_INCLUDE!$ZAPTEL_INCLUDE$ac_delim
-ZAPTEL_DIR!$ZAPTEL_DIR$ac_delim
-PBX_ZAPTEL!$PBX_ZAPTEL$ac_delim
-ALLOCA!$ALLOCA$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-POW_LIB!$POW_LIB$ac_delim
-GC_CFLAGS!$GC_CFLAGS$ac_delim
-GC_LDFLAGS!$GC_LDFLAGS$ac_delim
-AST_DECLARATION_AFTER_STATEMENT!$AST_DECLARATION_AFTER_STATEMENT$ac_delim
-AST_NO_STRICT_OVERFLOW!$AST_NO_STRICT_OVERFLOW$ac_delim
-GSM_INTERNAL!$GSM_INTERNAL$ac_delim
-KDEINIT!$KDEINIT$ac_delim
-KDEDIR!$KDEDIR$ac_delim
-NETSNMP_CONFIG!$NETSNMP_CONFIG$ac_delim
-PG_CONFIG!$PG_CONFIG$ac_delim
-PTLIB_CONFIG!$PTLIB_CONFIG$ac_delim
-PWLIBDIR!$PWLIBDIR$ac_delim
-PWLIB_INCDIR!$PWLIB_INCDIR$ac_delim
-PWLIB_LIBDIR!$PWLIB_LIBDIR$ac_delim
-PWLIB_PLATFORM!$PWLIB_PLATFORM$ac_delim
-OPENH323DIR!$OPENH323DIR$ac_delim
-OPENH323_INCDIR!$OPENH323_INCDIR$ac_delim
-OPENH323_LIBDIR!$OPENH323_LIBDIR$ac_delim
-OPENH323_SUFFIX!$OPENH323_SUFFIX$ac_delim
-OPENH323_BUILD!$OPENH323_BUILD$ac_delim
-PBX_SPEEX_PREPROCESS!$PBX_SPEEX_PREPROCESS$ac_delim
-PBX_ZAPTEL_VLDTMF!$PBX_ZAPTEL_VLDTMF$ac_delim
-PBX_ZAPTEL_TRANSCODE!$PBX_ZAPTEL_TRANSCODE$ac_delim
-EDITLINE_LIB!$EDITLINE_LIB$ac_delim
-PBX_H323!$PBX_H323$ac_delim
-PBX_IXJUSER!$PBX_IXJUSER$ac_delim
-GTKCONFIG!$GTKCONFIG$ac_delim
-PBX_GTK!$PBX_GTK$ac_delim
-GTK_INCLUDE!$GTK_INCLUDE$ac_delim
-GTK_LIB!$GTK_LIB$ac_delim
-PKGCONFIG!$PKGCONFIG$ac_delim
-_ACEOF
-
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
- ac_eof=`expr $ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-3.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-CEOF$ac_eof
-_ACEOF
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-PBX_GTK2!$PBX_GTK2$ac_delim
-GTK2_INCLUDE!$GTK2_INCLUDE$ac_delim
-GTK2_LIB!$GTK2_LIB$ac_delim
-CURL_CONFIG!$CURL_CONFIG$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
-
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 5; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
- ac_eof=`expr $ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-4.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
-_ACEOF
-
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-fi # test -n "$CONFIG_FILES"
-
-
-for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
- { (exit 1); exit 1; }; };;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
- { (exit 1); exit 1; }; };;
- esac
- ac_file_inputs="$ac_file_inputs $ac_f"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input="Generated from "`IFS=:
- echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- fi
-
- case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin";;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- { as_dir="$ac_dir"
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
- { (exit 1); exit 1; }; }; }
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
- esac
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
-
-case `sed -n '/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-s&@INSTALL@&$ac_INSTALL&;t t
-$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed -f "$tmp/subs-3.sed" | sed -f "$tmp/subs-4.sed" >$tmp/out
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
- { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&5
-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&2;}
-
- rm -f "$tmp/stdin"
- case $ac_file in
- -) cat "$tmp/out"; rm -f "$tmp/out";;
- *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
- esac
- ;;
- :H)
- #
- # CONFIG_HEADER
- #
-_ACEOF
-
-# Transform confdefs.h into a sed script `conftest.defines', that
-# substitutes the proper values into config.h.in to produce config.h.
-rm -f conftest.defines conftest.tail
-# First, append a space to every undef/define line, to ease matching.
-echo 's/$/ /' >conftest.defines
-# Then, protect against being on the right side of a sed subst, or in
-# an unquoted here document, in config.status. If some macros were
-# called several times there might be several #defines for the same
-# symbol, which is useless. But do not sort them, since the last
-# AC_DEFINE must be honored.
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
-# NAME is the cpp macro being defined, VALUE is the value it is being given.
-# PARAMS is the parameter list in the macro definition--in most cases, it's
-# just an empty string.
-ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*'
-ac_dB='\\)[ (].*,\\1define\\2'
-ac_dC=' '
-ac_dD=' ,'
-
-uniq confdefs.h |
- sed -n '
- t rset
- :rset
- s/^[ ]*#[ ]*define[ ][ ]*//
- t ok
- d
- :ok
- s/[\\&,]/\\&/g
- s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
- s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
- ' >>conftest.defines
-
-# Remove the space that was appended to ease matching.
-# Then replace #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-# (The regexp can be short, since the line contains either #define or #undef.)
-echo 's/ $//
-s,^[ #]*u.*,/* & */,' >>conftest.defines
-
-# Break up conftest.defines:
-ac_max_sed_lines=50
-
-# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1"
-# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2"
-# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1"
-# et cetera.
-ac_in='$ac_file_inputs'
-ac_out='"$tmp/out1"'
-ac_nxt='"$tmp/out2"'
-
-while :
-do
- # Write a here document:
- cat >>$CONFIG_STATUS <<_ACEOF
- # First, check the format of the line:
- cat >"\$tmp/defines.sed" <<\\CEOF
-/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def
-/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def
-b
-:def
-_ACEOF
- sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
- echo 'CEOF
- sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
- ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
- sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
- grep . conftest.tail >/dev/null || break
- rm -f conftest.defines
- mv conftest.tail conftest.defines
-done
-rm -f conftest.defines conftest.tail
-
-echo "ac_result=$ac_in" >>$CONFIG_STATUS
-cat >>$CONFIG_STATUS <<\_ACEOF
- if test x"$ac_file" != x-; then
- echo "/* $configure_input */" >"$tmp/config.h"
- cat "$ac_result" >>"$tmp/config.h"
- if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
- { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
-echo "$as_me: $ac_file is unchanged" >&6;}
- else
- rm -f $ac_file
- mv "$tmp/config.h" $ac_file
- fi
- else
- echo "/* $configure_input */"
- cat "$ac_result"
- fi
- rm -f "$tmp/out12"
- ;;
-
-
- esac
-
-done # for ac_tag
-
-
-{ (exit 0); exit 0; }
-_ACEOF
-chmod +x $CONFIG_STATUS
-ac_clean_files=$ac_clean_files_save
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || { (exit 1); exit 1; }
-fi
-
-
-if test "x${silent}" != "xyes" ; then
-echo
-echo " .\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$=.. "
-echo " .\$7\$7.. .7\$\$7:. "
-echo " .\$\$:. ,\$7.7 "
-echo " .\$7. 7\$\$\$\$ .\$\$77 "
-echo " ..\$\$. \$\$\$\$\$ .\$\$\$7 "
-echo " ..7\$ .?. \$\$\$\$\$ .?. 7\$\$\$."
-echo " \$.\$. .\$\$\$7. \$\$\$\$7 .7\$\$\$. .\$\$\$."
-echo " .777. .\$\$\$\$\$\$77\$\$\$77\$\$\$\$\$7. \$\$\$,"
-echo " \$\$\$~ .7\$\$\$\$\$\$\$\$\$\$\$\$\$7. .\$\$\$."
-echo ".\$\$7 .7\$\$\$\$\$\$\$7: ?\$\$\$."
-echo "\$\$\$ ?7\$\$\$\$\$\$\$\$\$\$I .\$\$\$7 "
-echo "\$\$\$ .7\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$ :\$\$\$. "
-echo "\$\$\$ \$\$\$\$\$\$7\$\$\$\$\$\$\$\$\$\$\$\$ .\$\$\$. "
-echo "\$\$\$ \$\$\$ 7\$\$\$7 .\$\$\$ .\$\$\$. "
-echo "\$\$\$\$ \$\$\$\$7 .\$\$\$. "
-echo "7\$\$\$7 7\$\$\$\$ 7\$\$\$ "
-echo " \$\$\$\$\$ \$\$\$ "
-echo " \$\$\$\$7. \$\$ (TM) "
-echo " \$\$\$\$\$\$\$. .7\$\$\$\$\$\$ \$\$ "
-echo " \$\$\$\$\$\$\$\$\$\$\$\$7\$\$\$\$\$\$\$\$\$.\$\$\$\$\$\$ "
-echo " \$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$. "
-echo
-fi
-
-{ echo "$as_me:$LINENO: Package configured for: " >&5
-echo "$as_me: Package configured for: " >&6;}
-{ echo "$as_me:$LINENO: OS type : $host_os" >&5
-echo "$as_me: OS type : $host_os" >&6;}
-{ echo "$as_me:$LINENO: Host CPU : $host_cpu" >&5
-echo "$as_me: Host CPU : $host_cpu" >&6;}
-if test "${cross_compiling}" = "yes"; then
- { echo "$as_me:$LINENO: Cross Compilation = YES" >&5
-echo "$as_me: Cross Compilation = YES" >&6;}
-fi
diff --git a/1.4/configure.ac b/1.4/configure.ac
deleted file mode 100644
index 432dbbaf6..000000000
--- a/1.4/configure.ac
+++ /dev/null
@@ -1,1596 +0,0 @@
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.60)
-
-AC_INIT(asterisk, 1.4, www.asterisk.org)
-
-# cross-compile macros
-AC_CANONICAL_BUILD
-AC_CANONICAL_HOST
-
-# check existence of the package
-AC_CONFIG_SRCDIR([main/asterisk.c])
-
-# specify output header file
-AC_CONFIG_HEADER(include/asterisk/autoconfig.h)
-
-AC_COPYRIGHT("Asterisk")
-AC_REVISION($Revision$)
-
-AC_GNU_SOURCE
-AC_USE_SYSTEM_EXTENSIONS # note- does not work on FreeBSD
-
-case "${host_os}" in
- freebsd*)
- ac_default_prefix=/usr/local
- CPPFLAGS=-I/usr/local/include
- LDFLAGS=-L/usr/local/lib
- ;;
- *)
- ac_default_prefix=/usr
- if test ${sysconfdir} = '${prefix}/etc'; then
- sysconfdir=/etc
- fi
- if test ${mandir} = '${prefix}/man'; then
- mandir=/usr/share/man
- fi
- ;;
-esac
-
-if test ${localstatedir} = '${prefix}/var'; then
- localstatedir=/var
-fi
-
-BUILD_PLATFORM=${build}
-BUILD_CPU=${build_cpu}
-BUILD_VENDOR=${build_vendor}
-BUILD_OS=${build_os}
-
-AC_SUBST(BUILD_PLATFORM)
-AC_SUBST(BUILD_CPU)
-AC_SUBST(BUILD_VENDOR)
-AC_SUBST(BUILD_OS)
-
-HOST_PLATFORM=${host}
-HOST_CPU=${host_cpu}
-HOST_VENDOR=${host_vendor}
-HOST_OS=${host_os}
-
-AC_SUBST(HOST_PLATFORM)
-AC_SUBST(HOST_CPU)
-AC_SUBST(HOST_VENDOR)
-AC_SUBST(HOST_OS)
-
-case "${host_os}" in
- freebsd*)
- OSARCH=FreeBSD
- ;;
- netbsd*)
- OSARCH=NetBSD
- ;;
- openbsd*)
- OSARCH=OpenBSD
- ;;
- solaris*)
- OSARCH=SunOS
- ;;
- *)
- OSARCH=${HOST_OS}
- ;;
-esac
-
-AC_SUBST(OSARCH)
-
-# check for uname
-AC_PATH_TOOL([UNAME], [uname], No)
-if test ! x"${UNAME}" = xNo; then
- PBX_OSREV=$(${UNAME} -r)
-fi
-AC_SUBST(PBX_OSREV)
-
-AH_TOP(
-#ifndef ASTERISK_AUTOCONFIG_H
-#define ASTERISK_AUTOCONFIG_H
-
-#include "asterisk/buildopts.h"
-
-)
-
-AH_BOTTOM(
-#endif
-)
-
-# cross-compile checks
-if test "${cross_compiling}" = "yes";
-then
- AC_CHECK_TOOL(CC, gcc, :)
- AC_CHECK_TOOL(CXX, g++, :)
- AC_CHECK_TOOL(LD, ld, :)
- AC_CHECK_TOOL(RANLIB, ranlib, :)
-fi
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_CXX
-AC_PROG_CPP
-AC_PROG_CXXCPP
-# This macro is just copied into our local acinclude.m4 from libtool.m4 so that
-# the developers regenerating the configure script don't have to install libtool.
-AST_PROG_LD # note - does not work on freebsd
-AC_PROG_AWK
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_RANLIB
-AST_CHECK_GNU_MAKE
-
-AC_PATH_TOOL([STRIP], [strip], :)
-AC_PATH_TOOL([AR], [ar], :)
-
-GNU_LD=0
-if test "x$with_gnu_ld" = "xyes" ; then
- GNU_LD=1
-fi
-AC_SUBST(GNU_LD)
-
-AC_PATH_PROG([AWK], [awk], :)
-AC_PATH_PROG([GREP], [grep], :)
-AC_PATH_PROG([FIND], [find], :)
-AC_PATH_PROG([COMPRESS], [compress], :)
-AC_PATH_PROG([BASENAME], [basename], :)
-AC_PATH_PROG([ID], [id], :)
-AC_PATH_PROG([DIRNAME], [dirname], :)
-AC_PATH_PROG([SHELL], [sh], :)
-AC_PATH_PROG([LN], [ln], :)
-AC_PATH_PROG([DOT], [dot], :)
-AC_PATH_PROG([WGET], [wget], :)
-if test "${WGET}" != ":" ; then
- DOWNLOAD=${WGET}
-else
- AC_PATH_PROG([FETCH], [fetch], [:])
- DOWNLOAD=${FETCH}
-fi
-AC_SUBST(DOWNLOAD)
-
-AC_CHECK_TOOL([SOXMIX], [soxmix], [:])
-if test "${SOXMIX}" != ":" ; then
- AC_DEFINE([HAVE_SOXMIX], 1, [Define to 1 if your system has soxmix application.])
-fi
-
-ACX_PTHREAD
-
-AC_LANG(C)
-
-AC_ARG_ENABLE(dev-mode,
- [ --enable-dev-mode Turn on developer mode],
- [case "${enableval}" in
- y|ye|yes) AST_DEVMODE=yes ;;
- n|no) AST_DEVMODE=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-dev-mode) ;;
- esac])
-AC_SUBST(AST_DEVMODE)
-
-# package option names should be in alphabetical order
-# by the --with option name, to make things easier for the users :-)
-
-AST_EXT_LIB_SETUP([ALSA], [Advanced Linux Sound Architecture], [asound])
-AST_EXT_LIB_SETUP([CURL], [cURL], [curl])
-AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capabilities], [cap])
-AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
-AST_EXT_LIB_SETUP([GNUTLS], [GNU TLS support (used for iksemel only)], [gnutls])
-AST_EXT_LIB_SETUP([GSM], [GSM], [gsm], [, or 'internal'])
-AST_EXT_LIB_SETUP([IKSEMEL], [Iksemel Jabber Library], [iksemel])
-AST_EXT_LIB_SETUP([IMAP_TK], [UW IMAP Toolkit], [imap])
-AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux Library], [isdnnet])
-AST_EXT_LIB_SETUP([KDE], [KDE], [kde])
-AST_EXT_LIB_SETUP([LTDL], [libtool], [ltdl])
-AST_EXT_LIB_SETUP([MISDN], [mISDN User Library], [misdn])
-AST_EXT_LIB_SETUP([NBS], [Network Broadcast Sound], [nbs])
-AST_EXT_LIB_SETUP([NCURSES], [ncurses], [ncurses])
-AST_EXT_LIB_SETUP([NETSNMP], [Net-SNMP], [netsnmp])
-AST_EXT_LIB_SETUP([NEWT], [newt], [newt])
-AST_EXT_LIB_SETUP([UNIXODBC], [unixODBC], [odbc])
-AST_EXT_LIB_SETUP([OGG], [OGG], [ogg])
-AST_EXT_LIB_SETUP([OSPTK], [OSP Toolkit], [osptk])
-AST_EXT_LIB_SETUP([OSS], [Open Sound System], [oss])
-AST_EXT_LIB_SETUP([POPT], [popt], [popt])
-AST_EXT_LIB_SETUP([PGSQL], [PostgreSQL], [postgres])
-AST_EXT_LIB_SETUP([PRI], [ISDN PRI], [pri])
-AST_EXT_LIB_SETUP([PWLIB], [PWlib], [pwlib])
-AST_EXT_LIB_SETUP([OPENH323], [OpenH323], [h323])
-AST_EXT_LIB_SETUP([RADIUS], [Radius Client], [radius])
-AST_EXT_LIB_SETUP([SPEEX], [Speex], [speex])
-AST_EXT_LIB_SETUP([SPEEXDSP], [Speexdsp], [speexdsp])
-AST_EXT_LIB_SETUP([SQLITE], [SQLite], [sqlite])
-AST_EXT_LIB_SETUP([SUPPSERV], [mISDN Supplemental Services], [suppserv])
-AST_EXT_LIB_SETUP([OPENSSL], [OpenSSL], [ssl])
-AST_EXT_LIB_SETUP([FREETDS], [FreeTDS], [tds])
-AST_EXT_LIB_SETUP([TERMCAP], [Termcap], [termcap])
-AST_EXT_LIB_SETUP([TINFO], [Term Info], [tinfo])
-AST_EXT_LIB_SETUP([TONEZONE], [tonezone], [tonezone])
-AST_EXT_LIB_SETUP([USB], [usb], [usb])
-AST_EXT_LIB_SETUP([VORBIS], [Vorbis], [vorbis])
-AST_EXT_LIB_SETUP([VPB], [Voicetronix API], [vpb])
-AST_EXT_LIB_SETUP([ZLIB], [zlib], [z])
-AST_EXT_LIB_SETUP([ZAPTEL], [Zaptel], [zaptel])
-
-# check for basic system features and functionality before
-# checking for package libraries
-
-AC_FUNC_ALLOCA
-AC_HEADER_DIRENT
-AC_HEADER_STDC
-AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h termios.h unistd.h utime.h])
-
-AC_SYS_LARGEFILE
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_HEADER_STDBOOL
-AC_C_CONST
-AC_TYPE_UID_T
-AC_C_INLINE
-AC_TYPE_MODE_T
-AC_TYPE_OFF_T
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_CHECK_MEMBERS([struct stat.st_blksize])
-AC_HEADER_TIME
-AC_STRUCT_TM
-AC_C_VOLATILE
-AC_CHECK_TYPES([ptrdiff_t])
-
-# Checks for library functions.
-AC_FUNC_CHOWN
-AC_FUNC_CLOSEDIR_VOID
-AC_FUNC_ERROR_AT_LINE
-AST_FUNC_FORK
-AC_FUNC_FSEEKO
-AC_PROG_GCC_TRADITIONAL
-# XXX: these are commented out until we determine whether it matters if our malloc()
-# acts exactly like glibc's or not
-# AC_FUNC_MALLOC
-# AC_FUNC_REALLOC
-AC_FUNC_MEMCMP
-AC_FUNC_MMAP
-AC_FUNC_SELECT_ARGTYPES
-AC_FUNC_SETVBUF_REVERSED
-AC_TYPE_SIGNAL
-AC_FUNC_STAT
-AC_FUNC_STRCOLL
-AC_FUNC_STRFTIME
-AC_FUNC_STRNLEN
-AC_FUNC_STRTOD
-AC_FUNC_UTIME_NULL
-AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([asprintf atexit bzero dup2 endpwent floor ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday inet_ntoa isascii localtime_r memchr memmove memset mkdir munmap pow putenv re_comp regcomp rint select setenv socket sqrt strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtol strtoq unsetenv utime vasprintf])
-
-# some systems already have gethostbyname_r so we don't need to build ours in main/utils.c
-AC_SEARCH_LIBS(gethostbyname_r, [socket nsl])
-
-AC_MSG_CHECKING(for gethostbyname_r with 6 arguments)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <stdlib.h>
- #include <netdb.h>],
- [struct hostent *he = gethostbyname_r((const char *)NULL, (struct hostent *)NULL, (char *)NULL, (int)0, (struct hostent **)NULL, (int *)NULL);]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_GETHOSTBYNAME_R_6], 1, [Define to 1 if your system has gethostbyname_r with 6 arguments.]),
- AC_MSG_RESULT(no)
-)
-
-AC_MSG_CHECKING(for gethostbyname_r with 5 arguments)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <stdlib.h>
- #include <netdb.h>],
- [struct hostent *he = gethostbyname_r((const char *)NULL, (struct hostent *)NULL, (char *)NULL, (int)0, (int *)NULL);]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_GETHOSTBYNAME_R_5], 1, [Define to 1 if your system has gethostbyname_r with 5 arguments.]),
- AC_MSG_RESULT(no)
-)
-
-AC_MSG_CHECKING(for PTHREAD_RWLOCK_INITIALIZER)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <pthread.h>],
- [int foo = PTHREAD_RWLOCK_INITIALIZER;]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_PTHREAD_RWLOCK_INITIALIZER], 1, [Define to 1 if your system has PTHREAD_RWLOCK_INITIALIZER.]),
- AC_MSG_RESULT(no)
-)
-
-AC_MSG_CHECKING(for PTHREAD_RWLOCK_PREFER_WRITER_NP)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <pthread.h>],
- [int foo = PTHREAD_RWLOCK_PREFER_WRITER_NP;]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP], 1, [Define to 1 if your system has PTHREAD_RWLOCK_PREFER_WRITER_NP.]),
- AC_MSG_RESULT(no)
-)
-
-AC_MSG_CHECKING(for compiler atomic operations)
-AC_LINK_IFELSE(
-AC_LANG_PROGRAM([], [int foo1; int foo2 = __sync_fetch_and_add(&foo1, 1);]),
-AC_MSG_RESULT(yes)
-AC_DEFINE([HAVE_GCC_ATOMICS], 1, [Define to 1 if your GCC C compiler provides atomic operations.]),
-AC_MSG_RESULT(no)
-)
-
-AST_GCC_ATTRIBUTE(pure)
-AST_GCC_ATTRIBUTE(malloc)
-AST_GCC_ATTRIBUTE(const)
-AST_GCC_ATTRIBUTE(unused)
-AST_GCC_ATTRIBUTE(always_inline)
-AST_GCC_ATTRIBUTE(deprecated)
-
-AC_MSG_CHECKING(for -ffunction-sections support)
-saved_CFLAGS="${CFLAGS}"
-CFLAGS="${CFLAGS} -ffunction-sections"
-AC_COMPILE_IFELSE(
- AC_LANG_PROGRAM([], [int x = 1;]),
- AC_MSG_RESULT(yes)
- [saved_LDFLAGS="${LDFLAGS}"]
- [LDFLAGS="${LDFLAGS} -Wl,--gc-sections"]
- AC_MSG_CHECKING(for --gc-sections support)
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM([], [int x = 1;]),
- AC_MSG_RESULT(yes)
- [GC_CFLAGS="-ffunction-sections"]
- [[GC_LDFLAGS="-Wl,--gc-sections"]],
- AC_MSG_RESULT(no)
- )
- [LDFLAGS="${saved_LDFLAGS}"],
- AC_MSG_RESULT(no)
-)
-CFLAGS="${saved_CFLAGS}"
-AC_SUBST(GC_CFLAGS)
-AC_SUBST(GC_LDFLAGS)
-
-AC_MSG_CHECKING(for -Wdeclaration-after-statement support)
-if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
- AC_MSG_RESULT(yes)
- AST_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement
-else
- AC_MSG_RESULT(no)
- AST_DECLARATION_AFTER_STATEMENT=
-fi
-AC_SUBST(AST_DECLARATION_AFTER_STATEMENT)
-
-AC_MSG_CHECKING(for -fno-strict-overflow)
-if $(${CC} -O2 -fno-strict-overflow -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
- AC_MSG_RESULT(yes)
- AST_NO_STRICT_OVERFLOW=-fno-strict-overflow
-else
- AC_MSG_RESULT(no)
- AST_NO_STRICT_OVERFLOW=
-fi
-AC_SUBST(AST_NO_STRICT_OVERFLOW)
-
-AC_MSG_CHECKING(for res_ninit)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <resolv.h>],
- [int foo = res_ninit(NULL);]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_RES_NINIT], 1, [Define to 1 if your system has the re-entrant resolver functions.])
- AC_MSG_CHECKING(for res_ndestroy)
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <resolv.h>],
- [int foo = res_ndestroy(NULL);]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_RES_NDESTROY], 1, [Define to 1 if your system has the ndestroy resolver function.]),
- AC_MSG_RESULT(no)
- ),
- AC_MSG_RESULT(no)
-)
-
-AC_MSG_CHECKING(for RTLD_NOLOAD)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <dlfcn.h>],
- [int foo = RTLD_NOLOAD;]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_RTLD_NOLOAD], 1, [Define to 1 if your system has a dynamic linker that supports RTLD_NOLOAD.]),
- AC_MSG_RESULT(no)
-)
-
-AC_MSG_CHECKING(for IP_MTU_DISCOVER)
-AC_LINK_IFELSE(
- AC_LANG_PROGRAM([#include <netinet/in.h>],
- [int foo = IP_MTU_DISCOVER;]),
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAVE_IP_MTU_DISCOVER], 1, [Define to 1 if your system has PMTU discovery on UDP sockets.]),
- AC_MSG_RESULT(no)
-)
-
-AC_CHECK_HEADER([libkern/OSAtomic.h],
- [AC_DEFINE_UNQUOTED([HAVE_OSX_ATOMICS], 1, [Define to 1 if OSX atomic operations are supported.])])
-
-AC_CHECK_SIZEOF(int)
-
-# do the package library checks now
-
-AST_EXT_LIB_CHECK([ALSA], [asound], [snd_spcm_init], [alsa/asoundlib.h], [-lm -ldl])
-
-AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h])
-
-if test "x${host_os}" = "xlinux-gnu" ; then
- AST_EXT_LIB_CHECK([CAP], [cap], [cap_from_text], [sys/capability.h])
-fi
-
-AST_C_COMPILE_CHECK([GETIFADDRS], [struct ifaddrs *p; getifaddrs(&p)], [ifaddrs.h])
-
-GSM_INTERNAL="yes"
-AC_SUBST(GSM_INTERNAL)
-GSM_SYSTEM="yes"
-if test "${USE_GSM}" != "no"; then
- if test "${GSM_DIR}" = "internal"; then
- GSM_SYSTEM="no"
- elif test "${GSM_DIR}" != ""; then
- GSM_INTERNAL="no"
- fi
- if test "${GSM_SYSTEM}" = "yes"; then
- gsmlibdir=""
- if test "x${GSM_DIR}" != "x"; then
- if test -d ${GSM_DIR}/lib; then
- gsmlibdir="-L${GSM_DIR}/lib"
- else
- gsmlibdir="-L${GSM_DIR}"
- fi
- fi
- AC_CHECK_LIB([gsm], [gsm_create], AC_DEFINE_UNQUOTED([HAVE_GSM], 1,
- [Define to indicate the GSM library]), [], ${gsmlibdir})
- if test "${ac_cv_lib_gsm_gsm_create}" = "yes"; then
- if test "x${GSM_DIR}" != "x" ; then
- AC_CHECK_HEADER([${GSM_DIR}/include/gsm.h], [GSM_HEADER_FOUND=1], [GSM_HEADER_FOUND=0])
- AC_CHECK_HEADER([${GSM_DIR}/include/gsm/gsm.h], [GSM_GSM_HEADER_FOUND=1], [GSM_GSM_HEADER_FOUND=0])
- else
- AC_CHECK_HEADER([gsm.h], [GSM_HEADER_FOUND=1], [GSM_HEADER_FOUND=0])
- AC_CHECK_HEADER([gsm/gsm.h], [GSM_GSM_HEADER_FOUND=1], [GSM_GSM_HEADER_FOUND=0])
- fi
- if test "${GSM_HEADER_FOUND}" = "0" ; then
- if test "{GSM_GSM_HEADER_FOUND}" = "0" ; then
- if test "x${GSM_MANDATORY}" = "xyes" ; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** It appears that you do not have the gsm development package installed.])
- AC_MSG_NOTICE([*** Please install it to include ${GSM_DESCRIP} support, or re-run configure])
- AC_MSG_NOTICE([*** without explicitly specifying --with-${GSM_OPTION}])
- exit 1
- fi
- fi
- fi
- GSM_OK=0
- if test "${GSM_HEADER_FOUND}" = "1" ; then
- AC_DEFINE_UNQUOTED([HAVE_GSM_HEADER], 1, [Define to indicate that gsm.h has no prefix for its location])
- GSM_OK=1
- else
- if test "${GSM_GSM_HEADER_FOUND}" = "1" ; then
- AC_DEFINE_UNQUOTED([HAVE_GSM_GSM_HEADER], 1, [Define to indicate that gsm.h is in gsm/gsm.h])
- GSM_OK=1
- fi
- fi
- if test "${GSM_OK}" = "1" ; then
- GSM_LIB="-lgsm"
- if test "x${GSM_DIR}" != "x"; then
- GSM_LIB="${gsmlibdir} ${GSM_LIB}"
- GSM_INCLUDE="-I${GSM_DIR}/include"
- fi
- PBX_GSM=1
- GSM_INTERNAL="no"
- fi
- fi
- fi
- if test "${GSM_INTERNAL}" = "yes"; then
- PBX_GSM=1
- AC_DEFINE_UNQUOTED([HAVE_GSM_HEADER], 1, [Define to indicate that gsm.h has no prefix for its location])
- fi
-fi
-
-AST_EXT_LIB_CHECK([IKSEMEL], [iksemel], [iks_start_sasl], [iksemel.h])
-
-if test "${PBX_IKSEMEL}" = 1; then
- AST_EXT_LIB_CHECK([GNUTLS], [gnutls], [gnutls_bye], [gnutls/gnutls.h], [-lz -lgcrypt -lgpg-error])
-fi
-
-if test "${USE_IMAP_TK}" != "no"; then
- saved_cppflags="${CPPFLAGS}"
- saved_libs="${LIBS}"
- switch_to_system_on_failure="no"
- if test "${IMAP_TK_DIR}" = ""; then
- IMAP_TK_DIR=`pwd`"/../imap-2004g"
- switch_to_system_on_failure="yes"
- fi
- if test "${IMAP_TK_DIR}" != "system"; then
- AC_MSG_CHECKING(for UW IMAP Toolkit c-client library)
- if test -f "${IMAP_TK_DIR}/c-client/LDFLAGS"; then
- imap_ldflags=`cat ${IMAP_TK_DIR}/c-client/LDFLAGS`
- fi
- imap_libs="${IMAP_TK_DIR}/c-client/c-client.a"
- imap_include="-I${IMAP_TK_DIR}/c-client"
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} "`echo ${imap_ldflags}`
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- MAILSTREAM *foo = mail_open(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk="yes"],
- [ac_cv_imap_tk="no"]
- )
- if test "${ac_cv_imap_tk}" = "yes"; then
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- long check = mail_expunge_full(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk2006="yes"],
- [ac_cv_imap_tk2006="no"]
- )
- fi
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- if test "${ac_cv_imap_tk}" = "no"; then
- AC_MSG_RESULT(no)
- if test "${switch_to_system_on_failure}" = "yes"; then
- IMAP_TK_DIR="system"
- else #This means they specified a directory. Search for a package installation there too
- AC_MSG_CHECKING([for system c-client library...])
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- imap_include="-I${IMAP_TK_DIR}/include"
- imap_ldflags="-L${IMAP_TK_DIR}/lib"
- imap_libs="-lc-client"
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} ${imap_ldflags}"
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- MAILSTREAM *foo = mail_open(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk="yes"],
- [ac_cv_imap_tk="no"]
- )
- if test "${ac_cv_imap_tk}" = "yes"; then
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include "c-client.h"
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- long check = mail_expunge_full(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk2006="yes"],
- [ac_cv_imap_tk2006="no"]
- )
- fi
- fi
- fi
- fi
- if test "${IMAP_TK_DIR}" = "system"; then
- #We will enter here if user specified "system" or if any of above checks failed
- AC_MSG_CHECKING([for system c-client library...])
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- imap_ldflags=""
- imap_libs="-lc-client"
- imap_include="-DUSE_SYSTEM_IMAP" #Try the imap directory first
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} "`echo ${imap_ldflags}`
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include <stdio.h>
- #include <imap/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- MAILSTREAM *foo = mail_open(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk="yes"],
- [ac_cv_imap_tk="no"]
- )
- if test "${ac_cv_imap_tk}" = "yes"; then
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include <stdio.h>
- #include <imap/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- long check = mail_expunge_full(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk2006="yes"],
- [ac_cv_imap_tk2006="no"]
- )
- else #looking in imap directory didn't work, try c-client
- imap_ldflags=""
- imap_libs="-lc-client"
- imap_include="-DUSE_SYSTEM_CCLIENT"
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
- CPPFLAGS="${CPPFLAGS} ${imap_include}"
- LIBS="${LIBS} ${imap_libs} "`echo ${imap_ldflags}`
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include <stdio.h>
- #include <c-client/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- MAILSTREAM *foo = mail_open(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk="yes"],
- [ac_cv_imap_tk="no"]
- )
- if test "${ac_cv_imap_tk}" = "yes"; then
- AC_LINK_IFELSE(
- AC_LANG_PROGRAM(
- [#include <stdio.h>
- #include <c-client/c-client.h>
- void mm_searched (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_exists (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_expunged (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_flags (MAILSTREAM *stream,unsigned long number)
- {
- }
- void mm_notify (MAILSTREAM *stream,char *string,long errflg)
- {
- }
- void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
- {
- }
- void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
- {
- }
- void mm_log (char *string,long errflg)
- {
- }
- void mm_dlog (char *string)
- {
- }
- void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
- {
- }
- void mm_critical (MAILSTREAM *stream)
- {
- }
- void mm_nocritical (MAILSTREAM *stream)
- {
- }
- long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
- {
- }
- void mm_fatal (char *string)
- {
- }],
- [
- long check = mail_expunge_full(NULL, "", 0);
- ]
- ),
- [ac_cv_imap_tk2006="yes"],
- [ac_cv_imap_tk2006="no"]
- )
- fi
- fi
- fi
- if test "${ac_cv_imap_tk}" = "yes"; then
- AC_MSG_RESULT(yes)
- IMAP_TK_LIB="${imap_libs} "`echo ${imap_ldflags}`
- IMAP_TK_INCLUDE="${imap_include}"
- PBX_IMAP_TK=1
- AC_DEFINE([HAVE_IMAP_TK], 1, [Define if your system has the UW IMAP Toolkit c-client library.])
- if test "${ac_cv_imap_tk2006}" = "yes"; then
- AC_DEFINE([HAVE_IMAP_TK2006], 1, [Define if your system has the UW IMAP Toolkit c-client library version 2006 or greater.])
- fi
- elif test -n "${IMAP_TK_MANDATORY}"; then
- AC_MSG_RESULT(no)
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The UW IMAP Toolkit installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-imap.])
- exit 1
- else
- AC_MSG_RESULT(no)
- fi
- CPPFLAGS="${saved_cppflags}"
- LIBS="${saved_libs}"
-fi
-
-# Needed by unixodbc
-AST_EXT_LIB_CHECK([LTDL], [ltdl], [lt_dlinit], [ltdl.h], [])
-
-AC_LANG_PUSH(C++)
-
-if test "${USE_KDE}" != "no"; then
- AC_MSG_CHECKING(for crashHandler in -lkdecore)
- saved_libs="${LIBS}"
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} -I${KDE_DIR}/include"
- if test -d ${KDE_DIR}/lib; then
- kdelibdir="${KDE_DIR}/lib"
- else
- kdelibdir="${KDE_DIR}"
- fi
- LIBS="${LIBS} -L${kdelibdir} -lkdecore"
-
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [#include "kcrash.h"],
- [KCrash::defaultCrashHandler(1);])
- ],
- [ac_cv_lib_kde_crash="yes"],
- [ac_cv_lib_kde_crash="no"])
-
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
-
- if test "${ac_cv_lib_kde_crash}" = "yes"; then
- AC_MSG_RESULT(yes)
- KDE_LIB="-lkdecore -lkdeui"
- if test "${KDE_DIR}" != ""; then
- KDE_LIB="-L${kdelibdir} ${KDE_LIB}"
- KDE_INCLUDE="-I${KDE_DIR}/include"
- fi
- PBX_KDE=1
- AC_DEFINE([HAVE_LIBKDE], 1, [Define if your system has the KDE libraries.])
- elif test -n "${KDE_MANDATORY}"; then
- AC_MSG_RESULT(no)
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The KDE installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-kde.])
- exit 1
- else
- AC_MSG_RESULT(no)
- fi
-fi
-if test "${PBX_KDE}" = 1; then
- AC_PATH_TOOL(KDEINIT, kdeinit, No)
- if test ! x"${KDEINIT}" = xNo; then
- KDEDIR=$(${DIRNAME} ${KDEINIT})
- KDEDIR=$(${DIRNAME} ${KDEDIR})
- fi
- AC_SUBST([KDEDIR])
-fi
-
-AC_LANG_POP
-
-AST_EXT_LIB_CHECK([MISDN], [mISDN], [mISDN_open], [mISDNuser/mISDNlib.h])
-
-if test "${PBX_MISDN}" = 1; then
- AST_EXT_LIB_CHECK([ISDNNET], [isdnnet], [init_manager], [mISDNuser/isdn_net.h], [-lmISDN -lpthread])
- AST_EXT_LIB_CHECK([SUPPSERV], [suppserv], [encodeFac], [mISDNuser/suppserv.h])
- AC_CHECK_HEADER([linux/mISDNdsp.h], [AC_DEFINE_UNQUOTED([MISDN_1_2], 1, [Build chan_misdn for mISDN 1.2 or later.])])
-fi
-
-AST_EXT_LIB_CHECK([NBS], [nbs], [nbs_connect], [nbs.h])
-
-AST_EXT_LIB_CHECK([NCURSES], [ncurses], [initscr], [curses.h])
-
-NETSNMP_CONFIG=No
-if test "${USE_NETSNMP}" != "no"; then
- if test "x${NETSNMP_DIR}" != "x"; then
- AC_PATH_TOOL([NETSNMP_CONFIG], [net-snmp-config], No, [${NETSNMP_DIR}/bin])
- if test x"${NETSNMP_CONFIG}" = xNo; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** net-snmp-config was not found in the path you specified:])
- AC_MSG_NOTICE([*** ${NETSNMP_DIR}/bin])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-netsnmp])
- exit 1
- fi
- else
- AC_PATH_TOOL([NETSNMP_CONFIG], [net-snmp-config], No)
- fi
-fi
-if test x"${NETSNMP_CONFIG}" != xNo; then
- NETSNMP_libs=`${NETSNMP_CONFIG} --agent-libs`
-
- AC_CHECK_LIB([netsnmp], [snmp_register_callback], AC_DEFINE_UNQUOTED([HAVE_NETSNMP], 1,
- [Define to indicate the Net-SNMP library]), [], ${NETSNMP_libs})
-
- if test "${ac_cv_lib_netsnmp_snmp_register_callback}" = "yes"; then
- NETSNMP_LIB="${NETSNMP_libs}"
- PBX_NETSNMP=1
- elif test -n "${NETSNMP_MANDATORY}";
- then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The Net-SNMP installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-netsnmp])
- exit 1
- fi
-elif test -n "${NETSNMP_MANDATORY}";
-then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The Net-SNMP installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-netsnmp])
- exit 1
-fi
-
-AST_EXT_LIB_CHECK([NEWT], [newt], [newtBell], [newt.h])
-
-AST_EXT_LIB_CHECK([UNIXODBC], [odbc], [SQLConnect], [sql.h], [])
-
-AST_EXT_LIB_CHECK([OGG], [ogg], [ogg_sync_init], [])
-
-if test "${USE_OSS}" != "no"; then
-PBX_OSS=0
-AC_CHECK_HEADER([linux/soundcard.h],
- [
- PBX_OSS=1
- AC_DEFINE_UNQUOTED([HAVE_OSS], 1, [Define to indicate the Open Sound System library])
- ])
-if test "$PBX_OSS" = "0"; then
- AC_CHECK_HEADER([sys/soundcard.h],
- [
- PBX_OSS=1
- AC_DEFINE_UNQUOTED([HAVE_OSS], 1, [Define to indicate the Open Sound System library])
- ])
-fi
-if test "$PBX_OSS" = "0"; then
- AST_EXT_LIB_CHECK([OSS], [ossaudio], [oss_ioctl_mixer], [soundcard.h])
-fi
-fi
-
-PG_CONFIG=No
-if test "${USE_PGSQL}" != "no"; then
- if test "x${PGSQL_DIR}" != "x"; then
- AC_PATH_TOOL([PG_CONFIG], [pg_config], No, [${PGSQL_DIR}/bin])
- if test x"${PG_CONFIG}" = xNo; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** pg_config was not found in the path you specified:])
- AC_MSG_NOTICE([*** ${PGSQL_DIR}/bin])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-postgres])
- exit 1
- fi
- else
- AC_PATH_TOOL([PG_CONFIG], [pg_config], No)
- fi
-fi
-if test "${PG_CONFIG}" != No; then
- PGSQL_libdir=`${PG_CONFIG} --libdir`
- PGSQL_includedir=`${PG_CONFIG} --includedir`
-
- if test "x$?" != "x0" ; then
- if test -n "${PGSQL_MANDATORY}" ; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The PostgreSQL installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-postgres])
- exit 1
- fi
- else
- AC_CHECK_LIB([pq], [PQescapeStringConn], AC_DEFINE_UNQUOTED([HAVE_PGSQL], 1,
- [Define to indicate the PostgreSQL library]), [], -L${PGSQL_libdir} -lz)
-
- if test "${ac_cv_lib_pq_PQescapeStringConn}" = "yes"; then
- PGSQL_LIB="-L${PGSQL_libdir} -lpq -lz"
- PGSQL_INCLUDE="-I${PGSQL_includedir}"
- PBX_PGSQL=1
- elif test -n "${PGSQL_MANDATORY}";
- then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The PostgreSQL installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-postgres])
- exit 1
- fi
- fi
-elif test -n "${PGSQL_MANDATORY}";
-then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The PostgreSQL installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-postgres])
- exit 1
-fi
-
-AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h])
-
-AST_EXT_LIB_CHECK([PRI], [pri], [pri_keypad_facility], [libpri.h])
-
-AST_EXT_LIB_CHECK([PRI_VERSION], [pri], [pri_get_version], [libpri.h])
-
-if test "${USE_PWLIB}" != "no"; then
- if test -n "${PWLIB_DIR}"; then
- PWLIBDIR="${PWLIB_DIR}"
- fi
- AST_CHECK_PWLIB()
- AST_CHECK_PWLIB_VERSION([PWLib], [PWLIB], [ptbuildopts.h], [1], [9], [2])
-
- if test "${HAS_PWLIB:-unset}" != "unset"; then
- AST_CHECK_OPENH323_PLATFORM()
-
- PLATFORM_PWLIB="pt_${PWLIB_PLATFORM}_r"
-
- AST_CHECK_PWLIB_BUILD([PWLib], [PWLIB],
- [Define if your system has the PWLib libraries.],
- [#include "ptlib.h"],
- [BOOL q = PTime::IsDaylightSavings();])
- fi
-fi
-
-if test "${USE_PWLIB}" != "no" -a "x${ac_cv_lib_PWLIB}" != "xyes" -a -n "${PWLIB_MANDATORY}"; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The PWLIB installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-pwlib])
- exit 1
-fi
-
-if test "${PBX_PWLIB}" = "1" -a "${USE_OPENH323}" != "no" ; then
- if test -n "${OPENH323_DIR}"; then
- OPENH323DIR="${OPENH323_DIR}"
- fi
- AST_CHECK_OPENH323()
- AST_CHECK_PWLIB_VERSION([OpenH323], [OPENH323], [openh323buildopts.h], [1], [17], [3])
- AST_CHECK_OPENH323_BUILD()
- PLATFORM_OPENH323="h323_${PWLIB_PLATFORM}_${OPENH323_SUFFIX}"
- AST_CHECK_PWLIB_BUILD([OpenH323], [OPENH323],
- [Define if your system has the OpenH323 libraries.],
- [#include "ptlib.h"
- #include "h323.h"
- #include "h323ep.h"],
- [H323EndPoint ep = H323EndPoint();],
- [${PWLIB_INCLUDE}], [${PWLIB_LIB}])
-fi
-if test "${USE_OPENH323}" != "no" -a "x${ac_cv_lib_OPENH323}" != "xyes" -a -n "${OPENH323_MANDATORY}"; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The OPENH323 installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-h323])
- exit 1
-fi
-
-AST_EXT_LIB_CHECK([RADIUS], [radiusclient-ng], [rc_read_config], [radiusclient-ng.h])
-
-AST_EXT_LIB_CHECK([SPEEX], [speex], [speex_encode], [speex/speex.h], [-lm])
-
-# See if the main speex library contains the preprocess functions
-AST_EXT_LIB_CHECK([SPEEX_PREPROCESS], [speex], [speex_preprocess_ctl], [speex/speex.h], [-lm])
-if test "${PBX_SPEEX_PREPROCESS}" = 1; then
- PBX_SPEEX_PREPROCESS=1
-fi
-
-AST_EXT_LIB_CHECK([SPEEXDSP], [speexdsp], [speex_preprocess_ctl], [speex/speex.h], [-lm])
-if test "${PBX_SPEEXDSP}" = 1; then
- PBX_SPEEX_PREPROCESS=1
-fi
-
-AC_SUBST(PBX_SPEEX_PREPROCESS)
-
-AST_EXT_LIB_CHECK([SQLITE], [sqlite], [sqlite_exec], [sqlite.h])
-
-AST_EXT_LIB_CHECK([OPENSSL], [ssl], [ssl2_connect], [openssl/ssl.h], [-lcrypto])
-if test "$PBX_OPENSSL" = "1";
-then
- AST_EXT_LIB_CHECK([OSPTK], [osptk], [OSPPCryptoDecrypt], [osp/osp.h], [-lcrypto -lssl])
-fi
-
-AST_EXT_LIB_CHECK([FREETDS], [tds], [tds_version], [tds.h])
-if test "${PBX_FREETDS}" != "0";
-then
- if test "${FREETDS_DIR}x" = "x";
- then
- for tds_dir in /usr /usr/local;
- do
- if test -f "${tds_dir}/include/tdsver.h";
- then
- FREETDS_DIR="${tds_dir}"
- fi
- done
- fi
- case `${GREP} TDS_VERSION_NO ${FREETDS_DIR:-/usr}/include/tdsver.h` in
- *0.64*)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_0_64"
- ;;
- *0.63*)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_0_63"
- ;;
- *0.62*)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_0_62"
- ;;
- *)
- FREETDS_INCLUDE="${FREETDS_INCLUDE} -DFREETDS_PRE_0_62"
- ;;
- esac
-fi
-
-AST_EXT_LIB_CHECK([TERMCAP], [termcap], [tgetent], [])
-
-AST_EXT_LIB_CHECK([TINFO], [tinfo], [tgetent], [])
-
-if test "${host_os}" != "linux-gnu" ; then
- tonezone_extra="-lm"
-fi
-
-AST_EXT_LIB_CHECK([TONEZONE], [tonezone], [tone_zone_find], [zaptel/tonezone.h], [${tonezone_extra}])
-
-AST_EXT_LIB_CHECK([USB], [usb], [usb_init], [usb.h], [])
-
-AST_EXT_LIB_CHECK([VORBIS], [vorbis], [vorbis_info_init], [vorbis/codec.h], [-lm -lvorbisenc])
-
-AC_LANG_PUSH(C++)
-
-if test "${USE_VPB}" != "no"; then
- AC_MSG_CHECKING(for vpb_open in -lvpb)
- saved_libs="${LIBS}"
- saved_cppflags="${CPPFLAGS}"
- if test "x${VPB_DIR}" != "x"; then
- if test -d ${VPB_DIR}/lib; then
- vpblibdir=${VPB_DIR}/lib
- else
- vpblibdir=${VPB_DIR}
- fi
- LIBS="${LIBS} -L${vpblibdir}"
- CPPFLAGS="${CPPFLAGS} -I${VPB_DIR}/include"
- fi
- LIBS="${LIBS} -lvpb -lpthread"
- AC_LINK_IFELSE(
- [
- AC_LANG_PROGRAM(
- [#include <vpbapi.h>],
- [int q = vpb_open(0,0);])
- ],
- [ AC_MSG_RESULT(yes)
- ac_cv_lib_vpb_vpb_open="yes"
- ],
- [ AC_MSG_RESULT(no)
- ac_cv_lib_vpb_vpb_open="no"
- ]
- )
- LIBS="${saved_libs}"
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_lib_vpb_vpb_open}" = "yes"; then
- VPB_LIB="-lvpb"
- if test "${VPB_DIR}" != ""; then
- VPB_LIB="-L${vpblibdir} ${VPB_LIB}"
- VPB_INCLUDE="-I${VPB_DIR}/include"
- fi
- PBX_VPB=1
- AC_DEFINE([HAVE_VPB], 1, [Define if your system has the VoiceTronix API libraries.])
- elif test -n "${VPB_MANDATORY}"; then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The VoiceTronix (vpb) installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-vpb.])
- exit 1
- fi
-fi
-
-AC_LANG_POP
-
-AST_EXT_LIB_CHECK([ZLIB], [z], [compress], [zlib.h])
-
-if test "${USE_ZAPTEL}" != "no"; then
- AC_MSG_CHECKING(for ZT_DIAL_OP_CANCEL in zaptel/zaptel.h)
- saved_cppflags="${CPPFLAGS}"
- if test "x${ZAPTEL_DIR}" != "x"; then
- CPPFLAGS="${CPPFLAGS} -I${ZAPTEL_DIR}/include"
- fi
- AC_COMPILE_IFELSE(
- [
- AC_LANG_PROGRAM(
- [#include <zaptel/zaptel.h>],
- [int foo = ZT_DIAL_OP_CANCEL;])
- ],
- [ AC_MSG_RESULT(yes)
- ac_cv_zaptel_h="yes"
- ],
- [ AC_MSG_RESULT(no)
- ac_cv_zaptel_h="no"
- ]
- )
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_zaptel_h}" = "yes"; then
- if test "${ZAPTEL_DIR}" != ""; then
- ZAPTEL_INCLUDE="-I${ZAPTEL_DIR}/include"
- fi
- PBX_ZAPTEL=1
- AC_DEFINE([HAVE_ZAPTEL], 1, [Define if your system has the Zaptel headers.])
- elif test -n "${ZAPTEL_MANDATORY}";
- then
- AC_MSG_NOTICE([***])
- AC_MSG_NOTICE([*** The Zaptel installation on this system appears to be broken.])
- AC_MSG_NOTICE([*** Either correct the installation, or run configure])
- AC_MSG_NOTICE([*** including --without-zaptel.])
- exit 1
- fi
-fi
-
-if test "${PBX_ZAPTEL}" = 1; then
- AC_MSG_CHECKING(for ZT_EVENT_REMOVED in zaptel/zaptel.h)
- saved_cppflags="${CPPFLAGS}"
- if test "x${ZAPTEL_DIR}" != "x"; then
- CPPFLAGS="${CPPFLAGS} -I${ZAPTEL_DIR}/include"
- fi
- AC_COMPILE_IFELSE(
- [
- AC_LANG_PROGRAM(
- [#include <zaptel/zaptel.h>],
- [int foo = ZT_EVENT_REMOVED;])
- ],
- [ AC_MSG_RESULT(yes)
- ac_cv_zaptel_vldtmf="yes"
- ],
- [ AC_MSG_RESULT(no)
- ac_cv_zaptel_vldtmf="no"
- ]
- )
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_zaptel_vldtmf}" = "yes"; then
- PBX_ZAPTEL_VLDTMF=1
- fi
- AC_MSG_CHECKING(for ZT_TCOP_ALLOCATE in zaptel/zaptel.h)
- saved_cppflags="${CPPFLAGS}"
- if test "x${ZAPTEL_DIR}" != "x"; then
- CPPFLAGS="${CPPFLAGS} -I${ZAPTEL_DIR}/include"
- fi
- AC_COMPILE_IFELSE(
- [
- AC_LANG_PROGRAM(
- [#include <zaptel/zaptel.h>],
- [int foo = ZT_TCOP_ALLOCATE;])
- ],
- [ AC_MSG_RESULT(yes)
- ac_cv_zaptel_transcode="yes"
- ],
- [ AC_MSG_RESULT(no)
- ac_cv_zaptel_transcode="no"
- ]
- )
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_zaptel_transcode}" = "yes"; then
- PBX_ZAPTEL_TRANSCODE=1
- fi
-fi
-AC_SUBST(PBX_ZAPTEL_VLDTMF)
-AC_SUBST(PBX_ZAPTEL_TRANSCODE)
-
-EDITLINE_LIB=""
-if test "x$TERMCAP_LIB" != "x" ; then
- EDITLINE_LIB="$TERMCAP_LIB"
-elif test "x$TINFO_LIB" != "x" ; then
- EDITLINE_LIB="$TINFO_LIB"
-elif test "x$CURSES_LIB" != "x" ; then
- EDITLINE_LIB="$CURSES_LIB"
-elif test "x$NCURSES_LIB" != "x" ; then
- EDITLINE_LIB="$NCURSES_LIB"
-else
- AC_MSG_ERROR(*** termcap support not found)
-fi
-AC_SUBST(EDITLINE_LIB)
-
-AC_CHECK_HEADER([h323.h], [PBX_H323=1], [PBX_H323=0])
-AC_SUBST(PBX_H323)
-
-AC_CHECK_HEADER([linux/compiler.h],
- [AC_DEFINE_UNQUOTED([HAVE_LINUX_COMPILER_H], 1, [Define to 1 if your system has linux/compiler.h.])])
-
-AC_CHECK_HEADER([linux/ixjuser.h], [PBX_IXJUSER=1], [PBX_IXJUSER=0], [
- #include <linux/version.h>
- #ifdef HAVE_LINUX_COMPILER_H
- #include <linux/compiler.h>
- #endif
- ])
-AC_SUBST(PBX_IXJUSER)
-
-if test "${cross_compiling}" = "no";
-then
- AC_CHECK_FILE(/sbin/launchd, AC_DEFINE([HAVE_SBIN_LAUNCHD], 1, [Define to 1 if your system has /sbin/launchd.]))
-fi
-
-PBX_GTK=0
-AC_CHECK_TOOL(GTKCONFIG, gtk-config, No)
-if test ! "x${GTKCONFIG}" = xNo; then
- GTK_INCLUDE=$(${GTKCONFIG} --cflags gthread)
- GTK_LIB=$(${GTKCONFIG} --libs gthread)
- PBX_GTK=1
- AC_DEFINE([HAVE_GTK], 1, [Define if your system has the GTK libraries.])
-fi
-AC_SUBST(PBX_GTK)
-AC_SUBST(GTK_INCLUDE)
-AC_SUBST(GTK_LIB)
-
-PBX_GTK2=0
-AC_CHECK_TOOL(PKGCONFIG, pkg-config, No)
-if test ! "x${PKGCONFIG}" = xNo; then
- GTK2_INCLUDE=$(${PKGCONFIG} gtk+-2.0 --cflags 2>/dev/null)
- GTK2_LIB=$(${PKGCONFIG} gtk+-2.0 --libs)
- PBX_GTK2=1
- AC_DEFINE([HAVE_GTK2], 1, [Define if your system has the GTK2 libraries.])
-fi
-AC_SUBST(PBX_GTK2)
-AC_SUBST(GTK2_INCLUDE)
-AC_SUBST(GTK2_LIB)
-
-if test "${USE_CURL}" != "no"; then
- AC_PATH_TOOL([CURL_CONFIG], [curl-config], No)
- if test ! x"${CURL_CONFIG}" = xNo; then
- # check for version
- if test $(printf "%d" 0x$(${CURL_CONFIG} --vernum)) -ge $(printf "%d" 0x070907); then
- CURL_INCLUDE=$(${CURL_CONFIG} --cflags)
- CURL_LIB=$(${CURL_CONFIG} --libs)
-
- AC_MSG_CHECKING(for curl_version() in curl/curl.h)
- saved_cppflags="${CPPFLAGS}"
- CPPFLAGS="${CPPFLAGS} ${CURL_INCLUDE}"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [#include <curl/curl.h>],
- [curl_version();])
- ],[
- AC_MSG_RESULT(yes)
- ac_cv_curl_h="yes"
- ],[
- AC_MSG_RESULT(no)
- ac_cv_curl_h="no"
- ]
- )
- CPPFLAGS="${saved_cppflags}"
- if test "${ac_cv_curl_h}" = "yes"; then
- PBX_CURL=1
- AC_DEFINE([HAVE_CURL], 1, [Define if your system has the curl libraries.])
- fi
- fi
- fi
-fi
-
-AC_CONFIG_FILES([build_tools/menuselect-deps makeopts channels/h323/Makefile])
-AC_OUTPUT
-
-if test "x${silent}" != "xyes" ; then
-echo
-echo " .\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$=.. "
-echo " .\$7\$7.. .7\$\$7:. "
-echo " .\$\$:. ,\$7.7 "
-echo " .\$7. 7\$\$\$\$ .\$\$77 "
-echo " ..\$\$. \$\$\$\$\$ .\$\$\$7 "
-echo " ..7\$ .?. \$\$\$\$\$ .?. 7\$\$\$."
-echo " \$.\$. .\$\$\$7. \$\$\$\$7 .7\$\$\$. .\$\$\$."
-echo " .777. .\$\$\$\$\$\$77\$\$\$77\$\$\$\$\$7. \$\$\$,"
-echo " \$\$\$~ .7\$\$\$\$\$\$\$\$\$\$\$\$\$7. .\$\$\$."
-echo ".\$\$7 .7\$\$\$\$\$\$\$7: ?\$\$\$."
-echo "\$\$\$ ?7\$\$\$\$\$\$\$\$\$\$I .\$\$\$7 "
-echo "\$\$\$ .7\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$ :\$\$\$. "
-echo "\$\$\$ \$\$\$\$\$\$7\$\$\$\$\$\$\$\$\$\$\$\$ .\$\$\$. "
-echo "\$\$\$ \$\$\$ 7\$\$\$7 .\$\$\$ .\$\$\$. "
-echo "\$\$\$\$ \$\$\$\$7 .\$\$\$. "
-echo "7\$\$\$7 7\$\$\$\$ 7\$\$\$ "
-echo " \$\$\$\$\$ \$\$\$ "
-echo " \$\$\$\$7. \$\$ (TM) "
-echo " \$\$\$\$\$\$\$. .7\$\$\$\$\$\$ \$\$ "
-echo " \$\$\$\$\$\$\$\$\$\$\$\$7\$\$\$\$\$\$\$\$\$.\$\$\$\$\$\$ "
-echo " \$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$. "
-echo
-fi
-
-AC_MSG_NOTICE(Package configured for: )
-AC_MSG_NOTICE( OS type : $host_os)
-AC_MSG_NOTICE( Host CPU : $host_cpu)
-if test "${cross_compiling}" = "yes"; then
- AC_MSG_NOTICE( Cross Compilation = YES)
-fi
diff --git a/1.4/contrib/README.festival b/1.4/contrib/README.festival
deleted file mode 100644
index 24912827c..000000000
--- a/1.4/contrib/README.festival
+++ /dev/null
@@ -1,47 +0,0 @@
-
-app_festival is an application that allows one to send text-to-speech commands
-to a background festival server, and to obtain the resulting waveform which
-gets sent down to the respective channel. app_festival also employs a waveform
-cache, so invariant text-to-speech strings ("Please press 1 for instructions")
-do not need to be dynamically generated all the time.
-
-You need :
-
-1) festival, patched to produce 8khz waveforms on output. Patch for Festival
-1.4.2 RELEASE are included. The patch adds a new command to festival
-(asterisk_tts).
-
-It is possible to run Festival without patches in the source-code. Just
-add this to your /etc/festival.scm or /usr/share/festival/festival/scm:
-
- (define (tts_textasterisk string mode)
- "(tts_textasterisk STRING MODE)
- Apply tts to STRING. This function is specifically designed for
- use in server mode so a single function call may synthesize the string.
- This function name may be added to the server safe functions."
- (let ((wholeutt (utt.synth (eval (list 'Utterance 'Text string)))))
- (utt.wave.resample wholeutt 8000)
- (utt.wave.rescale wholeutt 5)
- (utt.send.wave.client wholeutt)))
-
-[See the comment with subject "Using Debian
- festival >= 1.4.3-15 (no recompiling needed!)" on
- http://www.voip-info.org/wiki-Asterisk+festival+installation for the
- original mentioning of it]
-
-2) You may wish to obtain and install the asterisk-perl
-module by James Golovich <james@gnuinter.net>, from
-either CPAN, or his site: http://asterisk.gnuinter.net,
-as this contains a good example of how variable text
-can be tts'd via asterisk, namely the examples/tts-*.agi
-files there. It has been noted that the current expression
-evaluation capabilities of asterisk are not best suited
-for the generation and manipulation of text. AGI scripting
-can be ideal for these sorts of needs. For simpler usage,
-fixed, pre-recorded messages may be more amenable for your
-purposes.
-
-3) Before running asterisk, you have to run festival-server with a command
-like :
-
-/usr/local/festival/bin/festival --server > /dev/null 2>&1 &
diff --git a/1.4/contrib/asterisk-doxygen-header b/1.4/contrib/asterisk-doxygen-header
deleted file mode 100644
index a8eebd6c3..000000000
--- a/1.4/contrib/asterisk-doxygen-header
+++ /dev/null
@@ -1,10 +0,0 @@
-<HTML>
- <HEAD>
- <TITLE>Asterisk.org: Developer Documentation ($date)</TITLE>
- <LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
- </HEAD>
- <BODY BGCOLOR="#FFFFFF">
-<div><font size="2" align="right">$datetime</font></div>
-
-<h2>Asterisk developer's documentation</h2>
-<hr/>
diff --git a/1.4/contrib/asterisk-ices.xml b/1.4/contrib/asterisk-ices.xml
deleted file mode 100644
index abc028c75..000000000
--- a/1.4/contrib/asterisk-ices.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0"?>
-<ices>
-
- <!-- run in background -->
- <background>0</background>
- <!-- where logs go. -->
- <logpath>/var/log/ices</logpath>
- <logfile>ices.log</logfile>
- <!-- 1=error, 2=warn, 3=infoa ,4=debug -->
- <loglevel>4</loglevel>
- <!-- logfile is ignored if this is set to 1 -->
- <consolelog>0</consolelog>
-
- <!-- optional filename to write process id to -->
- <!-- <pidfile>/home/ices/ices.pid</pidfile> -->
-
- <stream>
- <!-- metadata used for stream listing -->
- <metadata>
- <name>Example stream name</name>
- <genre>Example genre</genre>
- <description>A short description of your stream</description>
- <url>http://mysite.org</url>
- </metadata>
-
- <!-- Input module.
-
- This example uses the 'oss' module. It takes input from the
- OSS audio device (e.g. line-in), and processes it for live
- encoding. -->
- <input>
- <module>stdinpcm</module>
- <param name="rate">8000</param>
- <param name="channels">1</param>
- <!-- Read metadata (from stdin by default, or -->
- <!-- filename defined below (if the latter, only on SIGUSR1) -->
- <param name="metadata">1</param>
- <param name="metadatafilename">test</param>
- </input>
-
- <!-- Stream instance.
-
- You may have one or more instances here. This allows you to
- send the same input data to one or more servers (or to different
- mountpoints on the same server). Each of them can have different
- parameters. This is primarily useful for a) relaying to multiple
- independent servers, and b) encoding/reencoding to multiple
- bitrates.
-
- If one instance fails (for example, the associated server goes
- down, etc), the others will continue to function correctly.
- This example defines a single instance doing live encoding at
- low bitrate. -->
-
- <instance>
- <!-- Server details.
-
- You define hostname and port for the server here, along
- with the source password and mountpoint. -->
-
- <hostname>localhost</hostname>
- <port>8000</port>
- <password>temppass</password>
- <mount>/example.ogg</mount>
- <yp>1</yp> <!-- allow stream to be advertised on YP, default 0 -->
-
- <!-- Live encoding/reencoding:
-
- channels and samplerate currently MUST match the channels
- and samplerate given in the parameters to the oss input
- module above or the remsaple/downmix section below. -->
-
- <encode>
- <quality>0</quality>
- <samplerate>8000</samplerate>
- <channels>1</channels>
- </encode>
-
- <!-- stereo->mono downmixing, enabled by setting this to 1 -->
- <downmix>0</downmix>
-
- <!-- resampling.
-
- Set to the frequency (in Hz) you wish to resample to, -->
-
- <!-- <resample>
- <in-rate>44100</in-rate>
- <out-rate>22050</out-rate>
- </resample> -->
- </instance>
-
- </stream>
-</ices>
diff --git a/1.4/contrib/asterisk-ng-doxygen b/1.4/contrib/asterisk-ng-doxygen
deleted file mode 100644
index 8fcf93cf6..000000000
--- a/1.4/contrib/asterisk-ng-doxygen
+++ /dev/null
@@ -1,1230 +0,0 @@
-# Doxyfile 1.4.2
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = "Asterisk - the Open Source PBX"
-
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = doc/api
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 3
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
-# only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = YES
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = YES
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 5
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation.
-
-SHOW_DIRECTORIES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the progam writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT =
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = ./ \
- main \
- include \
- include/asterisk \
- channels \
- channels/misdn \
- funcs \
- main/stdtime \
- apps \
- cdr \
- codecs \
- formats \
- pbx \
- res
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-
-FILE_PATTERNS = *.c \
- *.h
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH = ./ \
- doc \
- configs
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH = images
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = YES
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT =
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER = contrib/asterisk-doxygen-header
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = YES
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT =
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT =
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT =
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION =
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED = __GNUC__
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = NO
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-#Created by Asterisk Makefile
-#HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that a graph may be further truncated if the graph's
-# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
-# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
-# the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
diff --git a/1.4/contrib/dictionary.digium b/1.4/contrib/dictionary.digium
deleted file mode 100644
index 694605f54..000000000
--- a/1.4/contrib/dictionary.digium
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Digium's Asterisk specific radius attributes
-# markster@digium.com
-#
-#
-
-VENDOR Digium 22736
-
-BEGIN-VENDOR Digium
-
-ATTRIBUTE Asterisk-Acc-Code 101 string Digium
-ATTRIBUTE Asterisk-Src 102 string Digium
-ATTRIBUTE Asterisk-Dst 103 string Digium
-ATTRIBUTE Asterisk-Dst-Ctx 104 string Digium
-ATTRIBUTE Asterisk-Clid 105 string Digium
-ATTRIBUTE Asterisk-Chan 106 string Digium
-ATTRIBUTE Asterisk-Dst-Chan 107 string Digium
-ATTRIBUTE Asterisk-Last-App 108 string Digium
-ATTRIBUTE Asterisk-Last-Data 109 string Digium
-ATTRIBUTE Asterisk-Start-Time 110 string Digium
-ATTRIBUTE Asterisk-Answer-Time 111 string Digium
-ATTRIBUTE Asterisk-End-Time 112 string Digium
-ATTRIBUTE Asterisk-Duration 113 integer Digium
-ATTRIBUTE Asterisk-Bill-Sec 114 integer Digium
-ATTRIBUTE Asterisk-Disposition 115 string Digium
-ATTRIBUTE Asterisk-AMA-Flags 116 string Digium
-ATTRIBUTE Asterisk-Unique-ID 117 string Digium
-ATTRIBUTE Asterisk-User-Field 118 string Digium
-
-END-VENDOR Digium
-
diff --git a/1.4/contrib/festival-1.4.1-diff b/1.4/contrib/festival-1.4.1-diff
deleted file mode 100644
index 23702a3a1..000000000
--- a/1.4/contrib/festival-1.4.1-diff
+++ /dev/null
@@ -1,76 +0,0 @@
-diff -ruN festival/lib/tts.scm myfestival/lib/tts.scm
---- festival/lib/tts.scm Sun May 30 16:40:00 1999
-+++ myfestival/lib/tts.scm Wed Apr 17 22:29:34 2002
-@@ -200,6 +200,15 @@
- (utt.synth
- (eval (list 'Utterance 'Text string)))))
-
-+(define (tts_textasterisk string mode)
-+ "(tts_textasterisk STRING MODE)
-+Apply tts to STRING. This function is specifically designed for
-+use in server mode so a single function call may synthesize the string.
-+This function name maybe added to the server safe functions."
-+ (utt.send.wave.asterisk
-+ (utt.synth
-+ (eval (list 'Utterance 'Text string)))))
-+
- (define (tts_return_to_client)
- "(tts_return_to_client)
- This function is called by clients who wish to return waveforms of
-diff -ruN festival/src/arch/festival/wave.cc myfestival/src/arch/festival/wave.cc
---- festival/src/arch/festival/wave.cc Sat Jun 12 10:30:30 1999
-+++ myfestival/src/arch/festival/wave.cc Thu Apr 18 10:55:32 2002
-@@ -375,6 +375,38 @@
- type = "nist";
- else
- type = get_c_string(ltype);
-+
-+ w->save(tmpfile,type);
-+ write(ft_server_socket,"WV\n",3);
-+ socket_send_file(ft_server_socket,tmpfile);
-+ unlink(tmpfile);
-+
-+ return utt;
-+}
-+
-+static LISP utt_send_wave_asterisk(LISP utt)
-+{
-+ // Send the waveform to a client (must be acting as server)
-+ EST_Utterance *u = utterance(utt);
-+ EST_Wave *w;
-+ EST_String tmpfile = make_tmp_filename();
-+ LISP ltype;
-+ EST_String type;
-+
-+ w = get_utt_wave(u);
-+ if (ft_server_socket == -1)
-+ {
-+ cerr << "utt_send_wave_client: not in server mode" << endl;
-+ festival_error();
-+ }
-+
-+ ltype = ft_get_param("Wavefiletype");
-+ if (ltype == NIL)
-+ type = "nist";
-+ else
-+ type = get_c_string(ltype);
-+ w->resample(8000);
-+ w->rescale(5);
- w->save(tmpfile,type);
- write(ft_server_socket,"WV\n",3);
- socket_send_file(ft_server_socket,tmpfile);
-@@ -434,6 +466,13 @@
- "(utt.send.wave.client UTT)\n\
- Sends wave in UTT to client. If not in server mode gives an error\n\
- Note the client must be expecting to receive the waveform.");
-+
-+ init_subr_1("utt.send.wave.asterisk",utt_send_wave_asterisk,
-+ "(utt.send.wave.asterisk UTT)\n\
-+ Sends wave in UTT to client. If not in server mode gives an error\n\
-+ Note the client must be expecting to receive the waveform. The waveform\n\
-+ is rescaled and resampled according to what asterisk needs");
-+
- init_subr_2("utt.save.f0",utt_save_f0,
- "(utt.save.f0 UTT FILENAME)\n\
- Save F0 of UTT as esps track file in FILENAME.");
-
diff --git a/1.4/contrib/festival-1.4.2.diff b/1.4/contrib/festival-1.4.2.diff
deleted file mode 100644
index d5d1e5d54..000000000
--- a/1.4/contrib/festival-1.4.2.diff
+++ /dev/null
@@ -1,75 +0,0 @@
-diff -u -r festival-1.4.2/lib/tts.scm festival-1.4.2-asterisk/lib/tts.scm
---- festival-1.4.2/lib/tts.scm Wed Jan 8 09:54:14 2003
-+++ festival-1.4.2-asterisk/lib/tts.scm Tue Jan 7 08:51:44 2003
-@@ -236,6 +236,15 @@
- (utt.synth
- (eval (list 'Utterance 'Text string))))))
-
-+(define (tts_textasterisk string mode)
-+ "(tts_textasterisk STRING MODE)
-+Apply tts to STRING. This function is specifically designed for
-+use in server mode so a single function call may synthesize the string.
-+This function name may be added to the server safe functions."
-+ (utt.send.wave.asterisk
-+ (utt.synth
-+ (eval (list 'Utterance 'Text string)))))
-+
- (define (tts_return_to_client)
- "(tts_return_to_client)
- This function is called by clients who wish to return waveforms of
-diff -u -r festival-1.4.2/src/arch/festival/wave.cc festival-1.4.2-asterisk/src/arch/festival/wave.cc
---- festival-1.4.2/src/arch/festival/wave.cc Mon Jun 4 07:40:10 2001
-+++ festival-1.4.2-asterisk/src/arch/festival/wave.cc Tue Jan 7 08:53:09 2003
-@@ -377,6 +377,38 @@
- type = "nist";
- else
- type = get_c_string(ltype);
-+
-+ w->save(tmpfile,type);
-+ write(ft_server_socket,"WV\n",3);
-+ socket_send_file(ft_server_socket,tmpfile);
-+ unlink(tmpfile);
-+
-+ return utt;
-+}
-+
-+static LISP utt_send_wave_asterisk(LISP utt)
-+{
-+ // Send the waveform to a client (must be acting as server)
-+ EST_Utterance *u = utterance(utt);
-+ EST_Wave *w;
-+ EST_String tmpfile = make_tmp_filename();
-+ LISP ltype;
-+ EST_String type;
-+
-+ w = get_utt_wave(u);
-+ if (ft_server_socket == -1)
-+ {
-+ cerr << "utt_send_wave_client: not in server mode" << endl;
-+ festival_error();
-+ }
-+
-+ ltype = ft_get_param("Wavefiletype");
-+ if (ltype == NIL)
-+ type = "nist";
-+ else
-+ type = get_c_string(ltype);
-+ w->resample(8000);
-+ w->rescale(5);
- w->save(tmpfile,type);
- write(ft_server_socket,"WV\n",3);
- socket_send_file(ft_server_socket,tmpfile);
-@@ -454,6 +486,13 @@
- "(utt.send.wave.client UTT)\n\
- Sends wave in UTT to client. If not in server mode gives an error\n\
- Note the client must be expecting to receive the waveform.");
-+
-+ init_subr_1("utt.send.wave.asterisk",utt_send_wave_asterisk,
-+ "(utt.send.wave.asterisk UTT)\n\
-+ Sends wave in UTT to client. If not in server mode gives an error\n\
-+ Note the client must be expecting to receive the waveform. The waveform\n\
-+ is rescaled and resampled according to what asterisk needs");
-+
- init_subr_1("send_sexpr_to_client", send_sexpr_to_client,
- "(send_sexpr_to_client SEXPR)\n\
- Sends given sexpression to currently connected client.");
diff --git a/1.4/contrib/festival-1.4.3.diff b/1.4/contrib/festival-1.4.3.diff
deleted file mode 100644
index 13a9d92b8..000000000
--- a/1.4/contrib/festival-1.4.3.diff
+++ /dev/null
@@ -1,93 +0,0 @@
-diff -u -r festival-1.4.3/lib/tts.scm festival-1.4.3-asterisk/lib/tts.scm
---- festival-1.4.3/lib/tts.scm 2003-01-09 07:39:22.000000000 -0800
-+++ festival-1.4.3-asterisk/lib/tts.scm 2003-08-14 12:07:00.000000000 -0700
-@@ -234,6 +234,17 @@
- (utt.synth
- (eval (list 'Utterance 'Text string))))))
-
-+;; begin tts_textasterisk
-+(define (tts_textasterisk string mode)
-+ "(tts_textasterisk STRING MODE)
-+Apply tts to STRING. This function is specifically designed for
-+use in server mode so a single function call may synthesize the string.
-+This function name may be added to the server safe functions."
-+ (utt.send.wave.asterisk
-+ (utt.synth
-+ (eval (list 'Utterance 'Text string)))))
-+;; end tts_textasterisk
-+
- (define (tts_return_to_client)
- "(tts_return_to_client)
- This function is called by clients who wish to return waveforms of
-diff -u -r festival-1.4.3/src/arch/festival/wave.cc festival-1.4.3-asterisk/src/arch/festival/wave.cc
---- festival-1.4.3/src/arch/festival/wave.cc 2003-01-13 11:09:55.000000000 -0800
-+++ festival-1.4.3-asterisk/src/arch/festival/wave.cc 2003-08-14 12:10:53.000000000 -0700
-@@ -381,6 +381,7 @@
- type = "nist";
- else
- type = get_c_string(ltype);
-+
- w->save(tmpfile,type);
- #ifdef WIN32
- send(ft_server_socket,"WV\n",3,0);
-@@ -393,6 +394,44 @@
- return utt;
- }
-
-+// begin utt_send_wave_asterisk()
-+static LISP utt_send_wave_asterisk(LISP utt)
-+{
-+ // Send the waveform to a client (must be acting as server)
-+ EST_Utterance *u = utterance(utt);
-+ EST_Wave *w;
-+ EST_String tmpfile = make_tmp_filename();
-+ LISP ltype;
-+ EST_String type;
-+
-+ w = get_utt_wave(u);
-+ if (ft_server_socket == -1)
-+ {
-+ cerr << "utt_send_wave_client: not in server mode" << endl;
-+ festival_error();
-+ }
-+
-+ ltype = ft_get_param("Wavefiletype");
-+ if (ltype == NIL)
-+ type = "nist";
-+ else
-+ type = get_c_string(ltype);
-+ w->resample(8000);
-+ w->rescale(5);
-+
-+ w->save(tmpfile,type);
-+#ifdef WIN32
-+ send(ft_server_socket,"WV\n",3,0);
-+#else
-+ write(ft_server_socket,"WV\n",3);
-+#endif
-+ socket_send_file(ft_server_socket,tmpfile);
-+ unlink(tmpfile);
-+
-+ return utt;
-+}
-+// end utt_send_wave_asterisk()
-+
- static LISP send_sexpr_to_client(LISP l)
- {
- EST_String tmpfile = make_tmp_filename();
-@@ -465,6 +504,15 @@
- "(utt.send.wave.client UTT)\n\
- Sends wave in UTT to client. If not in server mode gives an error\n\
- Note the client must be expecting to receive the waveform.");
-+
-+// begin asterisk mod
-+ init_subr_1("utt.send.wave.asterisk",utt_send_wave_asterisk,
-+ "(utt.send.wave.asterisk UTT)\n\
-+ Sends wave in UTT to client. If not in server mode gives an error\n\
-+ Note the client must be expecting to receive the waveform. The waveform\n\
-+ is rescaled and resampled according to what asterisk needs");
-+// end asterisk mod
-+
- init_subr_1("send_sexpr_to_client", send_sexpr_to_client,
- "(send_sexpr_to_client SEXPR)\n\
- Sends given sexpression to currently connected client.");
diff --git a/1.4/contrib/festival-1.95.diff b/1.4/contrib/festival-1.95.diff
deleted file mode 100644
index 2035d7f0f..000000000
--- a/1.4/contrib/festival-1.95.diff
+++ /dev/null
@@ -1,107 +0,0 @@
-diff -ur festival-195orig/festival/lib/multisyn/multisyn_pauses.scm festival-195/festival/lib/multisyn/multisyn_pauses.scm
---- festival-195orig/festival/lib/multisyn/multisyn_pauses.scm 2004-06-21 08:19:30.000000000 -0600
-+++ festival-195/festival/lib/multisyn/multisyn_pauses.scm 2005-01-12 18:53:27.000000000 -0700
-@@ -85,8 +85,8 @@
- (let ((silence (car (cadr (car (PhoneSet.description '(silences))))))
- (seg (item.relation (find_last_seg word) 'Segment))
- pause_item)
-- (format t " inserting pause after: %s.\n" (item.name seg))
-- (format t " Inserting pause\n")
-+; (format t " inserting pause after: %s.\n" (item.name seg))
-+; (format t " Inserting pause\n")
- ; if next seg is not silence insert one.
- (if (or (not (item.next seg))
- (not (string-equal (item.name (item.next seg)) silence)))
-diff -ur festival-195orig/festival/lib/tts.scm festival-195/festival/lib/tts.scm
---- festival-195orig/festival/lib/tts.scm 2003-04-20 10:42:28.000000000 -0600
-+++ festival-195/festival/lib/tts.scm 2005-01-04 09:21:31.000000000 -0700
-@@ -235,6 +235,17 @@
- (utt.synth
- (eval (list 'Utterance 'Text string))))))
-
-+;; begin tts_textasterisk
-+(define (tts_textasterisk string mode)
-+ "(tts_textasterisk STRING MODE)
-+Apply tts to STRING. This function is specifically designed for
-+use in server mode so a single function call may synthesize the string.
-+This function name may be added to the server safe functions."
-+ (utt.send.wave.asterisk
-+ (utt.synth
-+ (eval (list 'Utterance 'Text string)))))
-+;; end tts_textasterisk
-+
- (define (tts_return_to_client)
- "(tts_return_to_client)
- This function is called by clients who wish to return waveforms of
-diff -ur festival-195orig/festival/src/arch/festival/wave.cc festival-195/festival/src/arch/festival/wave.cc
---- festival-195orig/festival/src/arch/festival/wave.cc 2004-06-21 14:52:42.000000000 -0600
-+++ festival-195/festival/src/arch/festival/wave.cc 2005-01-04 09:26:24.000000000 -0700
-@@ -482,6 +482,7 @@
- type = "nist";
- else
- type = get_c_string(ltype);
-+
- w->save(tmpfile,type);
- #ifdef WIN32
- send(ft_server_socket,"WV\n",3,0);
-@@ -494,6 +495,44 @@
- return utt;
- }
-
-+// begin utt_send_wave_asterisk()
-+static LISP utt_send_wave_asterisk(LISP utt)
-+{
-+ // Send the waveform to a client (must be acting as server)
-+ EST_Utterance *u = utterance(utt);
-+ EST_Wave *w;
-+ EST_String tmpfile = make_tmp_filename();
-+ LISP ltype;
-+ EST_String type;
-+
-+ w = get_utt_wave(u);
-+ if (ft_server_socket == -1)
-+ {
-+ cerr << "utt_send_wave_asterisk: not in server mode" << endl;
-+ festival_error();
-+ }
-+
-+ ltype = ft_get_param("Wavefiletype");
-+ if (ltype == NIL)
-+ type = "nist";
-+ else
-+ type = get_c_string(ltype);
-+ w->resample(8000);
-+ w->rescale(5);
-+
-+ w->save(tmpfile,type);
-+#ifdef WIN32
-+ send(ft_server_socket,"WV\n",3,0);
-+#else
-+ write(ft_server_socket,"WV\n",3);
-+#endif
-+ socket_send_file(ft_server_socket,tmpfile);
-+ unlink(tmpfile);
-+
-+ return utt;
-+}
-+// end utt_send_wave_asterisk()
-+
- static LISP send_sexpr_to_client(LISP l)
- {
- EST_String tmpfile = make_tmp_filename();
-@@ -595,6 +634,15 @@
- "(utt.send.wave.client UTT)\n\
- Sends wave in UTT to client. If not in server mode gives an error\n\
- Note the client must be expecting to receive the waveform.");
-+
-+// begin asterisk mod
-+ init_subr_1("utt.send.wave.asterisk",utt_send_wave_asterisk,
-+ "(utt.send.wave.asterisk UTT)\n\
-+ Sends wave in UTT to client. If not in server mode gives an error\n\
-+ Note the client must be expecting to receive the waveform. The waveform\n\
-+ is rescaled and resampled according to what asterisk needs");
-+// end asterisk mod
-+
- init_subr_1("send_sexpr_to_client", send_sexpr_to_client,
- "(send_sexpr_to_client SEXPR)\n\
- Sends given sexpression to currently connected client.");
diff --git a/1.4/contrib/firmware/iax/iaxy.bin b/1.4/contrib/firmware/iax/iaxy.bin
deleted file mode 100644
index 6f06c4cdb..000000000
--- a/1.4/contrib/firmware/iax/iaxy.bin
+++ /dev/null
Binary files differ
diff --git a/1.4/contrib/i18n.testsuite.conf b/1.4/contrib/i18n.testsuite.conf
deleted file mode 100644
index 8c4d1f705..000000000
--- a/1.4/contrib/i18n.testsuite.conf
+++ /dev/null
@@ -1,136 +0,0 @@
-; Test Internationalisation of SayNumber()
-; #include this into a suitable context
-; English
-exten => 841,1,Answer
-exten => 841,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 841,3,SetLanguage(en)
-exten => 841,4,SayNumber(183) ; one hundred eighty three (NB UK English would say one hundred & eighty three)
-exten => 841,5,Wait,1
-exten => 841,6,SayUnixTime() ; Say current date & time in "ABdY 'digits/at' IMp" format
-; French
-exten => 842,1,Answer
-exten => 842,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 842,3,SetLanguage(fr)
-exten => 842,4,SayNumber(1) ; one
-exten => 842,5,Wait,1
-exten => 842,6,SayNumber(1,f) ; one (feminine)
-exten => 842,7,Wait,1
-exten => 842,8,SayNumber(181) ; hundred eighty three
-exten => 842,9,Wait,1
-exten => 842,10,SayNumber(281) ; two hundred eighty three
-exten => 842,11,Wait,1
-exten => 842,12,SayNumber(1061) ; thousand sixty three
-exten => 842,13,Wait,1
-exten => 842,14,SayNumber(2061) ; two thousand sixty three
-exten => 842,15,Wait,1
-exten => 842,16,SayUnixTime()
-; Spanish
-exten => 843,1,Answer
-exten => 843,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 843,3,SetLanguage(es)
-exten => 843,4,Playback(digits/hundred)
-exten => 843,5,Wait,1
-exten => 843,6,SayNumber(1) ; one
-exten => 843,7,Wait,1
-exten => 843,8,SayNumber(1,f) ; one (feminine)
-exten => 843,9,Wait,1
-exten => 843,10,SayNumber(11) ; "dieci uno"
-exten => 843,11,Wait,1
-exten => 843,12,SayNumber(21) ; "veinti uno"
-exten => 843,13,Wait,1
-exten => 843,14,SayNumber(31) ; "thirty & one"
-exten => 843,15,Wait,1
-exten => 843,16,SayNumber(100) ; "cien"
-exten => 843,17,Wait,1
-exten => 843,18,SayNumber(101) ; "ciento uno"
-exten => 843,19,Wait,1
-exten => 843,20,SayNumber(200) ; "twohundred"
-exten => 843,21,Wait,1
-exten => 843,22,SayNumber(1000000) ; one million
-exten => 843,23,Wait,1
-exten => 843,24,SayNumber(2000000) ; two millions
-exten => 843,25,Wait,1
-exten => 843,26,SayUnixTime()
-; Portuguese
-exten => 844,1,Answer
-exten => 844,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 844,3,SetLanguage(pt)
-exten => 844,4,SayNumber(1) ; one
-exten => 844,5,Wait,1
-exten => 844,6,SayNumber(1,f) ; one (feminine)
-exten => 844,7,Wait,1
-exten => 844,8,SayNumber(2) ; two
-exten => 844,9,Wait,1
-exten => 844,10,SayNumber(2,f) ; two (feminine)
-exten => 844,11,Wait,1
-exten => 844,12,SayNumber(183) ; hundred& eighty three
-exten => 844,13,Wait,1
-exten => 844,14,SayUnixTime()
-; Italian
-exten => 845,1,Answer
-exten => 845,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 845,3,SetLanguage(it)
-exten => 845,4,SayNumber(21) ; "twentyone"
-exten => 845,5,Wait,1
-exten => 845,6,SayNumber(183) ; hundred eighty three
-exten => 845,7,Wait,1
-exten => 845,8,SayNumber(283) ; two hundred eighty three
-exten => 845,9,SayNumber(1063) ; thousand sixty three
-exten => 845,10,Wait,1
-exten => 845,11,SayNumber(2063) ; two thousands sixty three
-exten => 845,12,Wait,1
-exten => 845,13,SayUnixTime()
-; Dutch
-exten => 846,1,Answer
-exten => 846,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 846,3,SetLanguage(nl)
-exten => 846,4,SayUnixTime(||ABdY'digits/at'R)
-exten => 846,5,Wait,1
-; Danish
-exten => 847,1,Answer
-exten => 847,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 847,3,SetLanguage(da)
-exten => 847,4,SayNumber(68) ; eight-& sixty
-exten => 847,5,Wait,1
-exten => 847,6,SayNumber(2034) ; two thousand & four-& thirty
-exten => 847,7,Wait,1
-exten => 847,8,SayNumber(1000000) ; one million
-exten => 847,9,Wait,1
-exten => 847,10,SayNumber(2000000) ; two millions
-exten => 847,11,Wait,1
-exten => 847,12,SayUnixTime()
-; German
-exten => 848,1,Answer
-exten => 848,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 848,3,SetLanguage(de)
-exten => 848,4,SayNumber(68) ; eight-& sixty
-exten => 848,5,Wait,1
-exten => 848,6,SayNumber(100) ; "hundert"
-exten => 848,7,Wait,1
-exten => 848,8,SayNumber(101) ; "einhundert-einS"
-exten => 848,9,Wait,1
-exten => 848,10,SayNumber(1000) ; "tausend"
-exten => 848,11,Wait,1
-exten => 848,12,SayNumber(1001) ; "eintausend-einS" X tausend-einS
-exten => 848,13,Wait,1
-exten => 848,14,SayNumber(2134) ; two thousand one hundred four-& thirty
-exten => 848,15,Wait,1
-exten => 848,16,SayNumber(1001000) ; one million one thousand X million tausend
-exten => 848,17,Wait,1
-exten => 848,18,SayNumber(2002000) ; two millions two thousand
-exten => 848,19,Wait,1
-exten => 848,20,SayUnixTime()
-; Swedish
-exten => 849,1,Answer
-exten => 849,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 849,3,SetLanguage(se)
-exten => 849,4,SayUnixTime()
-exten => 849,5,Wait,1
-; Temp
-exten => 850,1,Answer
-exten => 850,2,Wait,1 ; Allow VoIP sessions time to initialise
-exten => 850,3,SetLanguage(de)
-exten => 850,4,Playback(digits/1)
-exten => 850,5,Wait,1
-exten => 850,6,Playback(digits/de-eins)
-exten => 850,7,Wait,1
diff --git a/1.4/contrib/init.d/rc.debian.asterisk b/1.4/contrib/init.d/rc.debian.asterisk
deleted file mode 100755
index b5b150c98..000000000
--- a/1.4/contrib/init.d/rc.debian.asterisk
+++ /dev/null
@@ -1,94 +0,0 @@
-#! /bin/sh
-# $Id$
-#
-# Mon Jun 04 2007 Iñaki Baz Castillo <ibc@in.ilimit.es>
-# - Eliminated SAFE_ASTERISK since it doesn't work as LSB script (it could require a independent "safe_asterisk" init script).
-# - Load and use the standar "/lib/lsb/init-functions".
-# - Addded "--oknodo" to "start-stop-daemon" for compatibility with LSB:
-# http://www.linux-foundation.org/spec/refspecs/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
-#
-# Thu Nov 17 2005 Gregory Boehnlein <damin@nacs.net>
-# - Reversed behavior of LD_ASSUME_KERNEL=2.4.1
-# - Added detailed failure messages
-#
-# Sun Jul 18 2004 Gregory Boehnlein <damin@nacs.net>
-# - Added test for safe_asterisk
-# - Changed "stop gracefully" to "stop now"
-# - Added support for -U and -G command line options
-# - Modified "reload" to call asterisk -rx 'reload'
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-NAME=asterisk
-DESC="Asterisk PBX"
-# Full path to asterisk binary
-DAEMON=/usr/sbin/asterisk
-
-# Uncomment this ONLY if you know what you are doing.
-# export LD_ASSUME_KERNEL=2.4.1
-
-# Uncomment the following and set them to the user/groups that you
-# want to run Asterisk as. NOTE: this requires substantial work to
-# be sure that Asterisk's environment has permission to write the
-# files required for its operation, including logs, its comm
-# socket, the asterisk database, etc.
-#AST_USER="asterisk"
-#AST_GROUP="asterisk"
-
-set -e
-
-if ! [ -x $DAEMON ] ; then
- echo "ERROR: $DAEMON not found"
- exit 0
-fi
-
-if ! [ -d /etc/asterisk ] ; then
- echo "ERROR: /etc/asterisk directory not found"
- exit 0
-fi
-
-# Use the LSB standar functions for services management
-. /lib/lsb/init-functions
-
-case "$1" in
- start)
- # Check if Asterisk is already running. If it is, then bug out, because
- # starting up Asterisk when Asterisk is already running is very bad.
- VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
- if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running. $0 will exit now."
- exit 1
- fi
-
- log_begin_msg "Starting $DESC: $NAME"
- if [ $AST_USER ] ; then
- ASTARGS="-U $AST_USER"
- fi
- if [ $AST_GROUP ] ; then
- ASTARGS="$ASTARGS -G $AST_GROUP"
- fi
- # "start-stop-daemon --oknodo" returns 0 even if Asterisk was already running (as LSB expects):
- start-stop-daemon --start --oknodo --exec $DAEMON -- $ASTARGS
- log_end_msg $?
- ;;
- stop)
- log_begin_msg "Stopping $DESC: $NAME"
- # "start-stop-daemon --oknodo" returns 0 even if Asterisk was already stopped (as LSB expects):
- start-stop-daemon --stop --oknodo --exec $DAEMON
- log_end_msg $?
- ;;
- reload)
- echo "Reloading $DESC configuration files."
- $DAEMON -rx 'reload' > /dev/null 2> /dev/null
- ;;
- restart|force-reload)
- $0 stop
- sleep 2 # It needs some time to really be stopped.
- $0 start
- # "restart|force-reload" starts Asterisk and returns 0 even if Asterisk was stopped (as LSB expects).
- ;;
- *)
- N=/etc/init.d/$NAME
- echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
- exit 1
- ;;
-esac
diff --git a/1.4/contrib/init.d/rc.gentoo.asterisk b/1.4/contrib/init.d/rc.gentoo.asterisk
deleted file mode 100755
index efc87afc7..000000000
--- a/1.4/contrib/init.d/rc.gentoo.asterisk
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/sbin/runscript
-# $Id$
-
-depend() {
- need net logger
-}
-
-start() {
- # Check if Asterisk is already running. If it is, then bug out, because
- # starting safe_asterisk when Asterisk is running is very bad.
- VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
- if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running. $0 will exit now."
- exit 1
- fi
-
- ebegin "Starting Asterisk"
- /usr/sbin/asterisk
- eend $? "Failed to start Asterisk"
-}
-
-stop() {
- ebegin "Stopping Asterisk"
- kill $(cat /var/run/asterisk.pid)
- eend $? "Failed to stop Asterisk"
-}
diff --git a/1.4/contrib/init.d/rc.mandrake.asterisk b/1.4/contrib/init.d/rc.mandrake.asterisk
deleted file mode 100755
index 8d4f0b70d..000000000
--- a/1.4/contrib/init.d/rc.mandrake.asterisk
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/bin/sh
-#
-# asterisk: Starts the asterisk service
-#
-# Version: @(#) /etc/rc.d/init.d/asterisk 1.0
-#
-# chkconfig: 2345 95 10
-# description: Starts the asterisk service
-#
-# processname: asterisk
-#
-
-# $Id$
-
-TTY=9 # TTY (if you want one) for Asterisk to run on
-CONSOLE=yes # Whether or not you want a console
-NOTIFY=root # Who to notify about crashes
-DUMPDROP=/tmp
-HOSTNAME=`hostname`
-if [ 0`readlink $0` = "0" ]; then
- CONFIGFILE=/etc/sysconfig/`basename $0`
-else
- CONFIG0=`readlink $0`
- CONFIGFILE=/etc/sysconfig/`basename $CONFIG0`
-fi
-
-# Setup environment
-cd /usr/src
-if [ -f /usr/lib/asterisk/modules/chan_h323.so -a `grep -c ^noload=chan_h323.so /etc/asterisk/modules.conf` -eq 0 ]; then
- OPENH323DIR=/usr/src/h323/openh323
- PWLIBDIR=/usr/src/h323/pwlib
-else
- OPENH323DIR=/usr/src/oh323/openh323
- PWLIBDIR=/usr/src/oh323/pwlib
-fi
-
-# Put overrides in /etc/sysconfig/asterisk
-[ -f $CONFIGFILE ] && . $CONFIGFILE
-
-LD_LIBRARY_PATH=$OPENH323DIR/lib:$PWLIBDIR/lib
-export OPENH323DIR PWLIBDIR LD_LIBRARY_PATH
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-#
-# Don't fork when running "safely"
-#
-ASTARGS="-p"
-if [ "$TTY" != "" ]; then
- if [ -c /dev/tty${TTY} ]; then
- TTY=tty${TTY}
- elif [ -c /dev/vc/${TTY} ]; then
- TTY=vc/${TTY}
- else
- echo "Cannot find your TTY (${TTY})" >&2
- exit 1
- fi
- ASTARGS="${ASTARGS} -vvv"
- if [ "$CONSOLE" != "no" ]; then
- ASTARGS="${ASTARGS} -c"
- fi
-fi
-if [ ! -w ${DUMPDROP} ]; then
- echo "Cannot write to ${DUMPDROP}" >&2
- exit 1
-fi
-
-#
-# Let Asterisk dump core
-#
-ulimit -c unlimited
-
-#launch_asterisk()
-#{
-#}
-
-SIGMSG=("None", "Hangup" "Interrupt" "Quit" "Illegal instruction" "Trace trap" "IOT Trap" "Bus Error" "Floating-point exception" "Killed" "User-defined signal 1" "Segmentation violation" "User-defined signal 2" "Broken pipe" "Alarm clock" "Termination" "Stack fault")
-
-run_asterisk()
-{
- while :; do
-
- if [ "$TTY" != "" ]; then
- cd /tmp
- stty sane < /dev/${TTY}
- asterisk ${ASTARGS} > /dev/${TTY} 2>&1 < /dev/${TTY}
- else
- cd /tmp
- asterisk ${ASTARGS}
- fi
- EXITSTATUS=$?
- echo "Asterisk ended with exit status $EXITSTATUS"
- if [ "$EXITSTATUS" = "0" ]; then
- # Properly shutdown....
- echo "Asterisk shutdown normally."
- exit 0
- elif [ $EXITSTATUS -gt 128 ]; then
- EXITSIGNAL=$(($EXITSTATUS - 128))
- EXITMSG=${SIGMSG[$EXITSIGNAL]}
- echo "Asterisk exited on signal $EXITSIGNAL - $EXITMSG."
- if [ "$NOTIFY" != "" ]; then
- echo "Asterisk exited on signal $EXITSIGNAL - $EXITMSG. Might want to take a peek." | \
- mail -s "Asterisk Died ($HOSTNAME)" $NOTIFY
- fi
- if [ -f /tmp/core ]; then
- mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
- fi
- else
- echo "Asterisk died with code $EXITSTATUS. Aborting."
- if [ -f /tmp/core ]; then
- mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
- fi
- exit 0
- fi
- echo "Automatically restarting Asterisk."
- done
-}
-
-case "$1" in
- start)
- # Check if Asterisk is already running. If it is, then bug out, because
- # starting Asterisk when Asterisk is already running is very bad.
- VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
- if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running. $0 will exit now."
- exit 1
- fi
-
- gprintf "Starting asterisk: "
- run_asterisk >/dev/null 2>&1 &
- sleep 2 # Give it time to die
- succeeded=`pidof asterisk|awk '{print NF}'`
- if [ $succeeded = "0" ]; then
- failure
- else
- success
- fi
- echo
- ;;
- stop)
- gprintf "Stopping asterisk: "
- asterisk -r -x "stop gracefully" >/dev/null 2>&1
- killall -9 mpg123 2>/dev/null
- success
- echo
- ;;
- restart)
- $0 stop
- usleep 100000
- $0 start
- ;;
- reload)
- gprintf "Reloading asterisk: "
- asterisk -r -x "reload" >/dev/null 2>&1
- success
- echo
- ;;
- stopnow)
- gprintf "Stopping asterisk: "
- asterisk -r -x "stop now" >/dev/null 2>&1
- success
- echo
- ;;
- restartnow)
- $0 stopnow
- $0 start
- ;;
- fullrestart)
- $0 stop
- service zaptel restart
- $0 start
- ;;
- fullrestartnow)
- $0 stopnow
- service zaptel restart
- $0 start
- ;;
- status)
- succeeded=`pidof asterisk|awk '{print NF}'`
- if [ $succeeded = "0" ]; then
- echo "Asterisk is not running"
- else
- echo "Asterisk is currently running with $succeeded threads"
- fi
- ;;
- *)
- gprintf "*** Usage: $0 {start|stop[now]|reload|[full]restart[now]|status}\n"
- exit 1
-esac
-
-exit 0
-
diff --git a/1.4/contrib/init.d/rc.mandrake.zaptel b/1.4/contrib/init.d/rc.mandrake.zaptel
deleted file mode 100755
index 2feaef4c7..000000000
--- a/1.4/contrib/init.d/rc.mandrake.zaptel
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/sh
-#
-# zaptel: Loads Asterisk modules
-#
-# Version: @(#) /etc/rc.d/init.d/zaptel 1.0
-#
-# chkconfig: 2345 90 10
-# description: Loads and unloads zaptel modules at boot time and shutdown.
-#
-# hide: true
-
-# $Id$
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-# Default modules - override in /etc/sysconfig/zaptel
-######################################
-MODULES="usb-uhci zaptel wcfxo wcusb"
-######################################
-
-# Resolve back to the basename (i.e. zaptel, not S90zaptel)
-if [ 0`readlink $0` = "0" ]; then
- CONFIGFILE=/etc/sysconfig/`basename $0`
-else
- CONFIG0=`readlink $0`
- CONFIGFILE=/etc/sysconfig/`basename $CONFIG0`
-fi
-
-[ -f $CONFIGFILE ] && . $CONFIGFILE
-
-function probe() {
- gprintf " $1"
- modprobe -i $1
- # It has to be in the module list, otherwise something is wrong
- if lsmod | grep -c ^$1 >/dev/null; then
- success
- else
- failure
- fi
- echo
-}
-
-function unprobe() {
- gprintf " $1"
- rmmod $1 >/dev/null 2>&1
- # If it's still in the module list after removing it, there's something wrong.
- if lsmod | grep -c ^$1 >/dev/null; then
- failure
- else
- success
- fi
- echo
-}
-
-function reverse_modules() {
- tmp=$MODULES
- MODULES=''
- for i in $tmp; do
- MODULES="$i $MODULES" ;
- done
-}
-
-# See how we were called.
-case "$1" in
- start)
- gprintf "Loading Asterisk modules:\n"
- for i in $MODULES; do
- probe $i
- usleep 100000 ;
- done
- ztcfg
- ;;
- stop)
- gprintf "Unloading Asterisk modules:\n"
- reverse_modules
- for i in $MODULES; do
- unprobe $i
- usleep 100000 ;
- done
- ;;
- status)
- #ztcfg -vv
- OK=1
- gprintf "Checking Asterisk modules"
- for i in $MODULES; do
- if [ `lsmod | grep -c $i` -eq 0 ]; then
- OK=0
- fi
- done
- if [ $OK -gt 0 ]; then
- success
- else
- failure
- fi
- echo
- ;;
- restart)
- $0 stop
- $0 start
- ;;
- *)
- gprintf "*** Usage: $0 {start|stop|status|restart}\n"
- exit 1
-esac
-
-exit 0
-
diff --git a/1.4/contrib/init.d/rc.redhat.asterisk b/1.4/contrib/init.d/rc.redhat.asterisk
deleted file mode 100755
index de821fe8a..000000000
--- a/1.4/contrib/init.d/rc.redhat.asterisk
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/sh
-# $Id$
-#
-# asterisk Starts, Stops and Reloads Asterisk.
-#
-# chkconfig: 2345 90 60
-# description: Asterisk PBX and telephony daemon.
-# processname: asterisk
-# pidfile: /var/run/asterisk.pid
-#
-# Thu Nov 17 2005 Gregory Boehnlein <damin@nacs.net>
-# - Updated Version to 1.3
-# - Reversed behavior of LD_ASSUME_KERNEL=2.4.1
-# - Added detailed failure messages
-#
-# Sun Jul 18 2004 Gregory Boehnlein <damin@nacs.net>
-# - Updated Version to 1.2
-# - Added test for safe_asterisk
-# - Verified SIGTERM issued by "killproc" ensures "stop gracefully"
-# - Added support for -U and -G command line options
-# - Modified "reload" to call asterisk -rx 'reload'
-
-# Use this option to specify a different configuration directory
-#AST_CONFIG=/etc/asterisk
-
-# Installation directory
-AST_SBIN=/usr/sbin
-
-# Uncomment the following and set them to the user/groups that you
-# want to run Asterisk as. NOTE: this requires substantial work to
-# be sure that Asterisk's environment has permission to write the
-# files required for its operation, including logs, its comm
-# socket, the asterisk database, etc.
-#AST_USER="asterisk"
-#AST_GROUP="asterisk"
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-if ! [ -x $AST_SBIN/asterisk ] ; then
- echo "ERROR: $AST_SBIN/asterisk not found"
- exit 0
-fi
-
-if ! [ -d $AST_CONFIG ] ; then
- echo "ERROR: $AST_CONFIG directory not found"
- exit 0
-fi
-
-# Uncomment this ONLY if you know what you are doing.
-# export LD_ASSUME_KERNEL=2.4.1
-
-# Full path to asterisk binary
-DAEMON=$AST_SBIN/asterisk
-
-# Full path to safe_asterisk script
-SAFE_ASTERISK=$AST_SBIN/safe_asterisk
-
-# Allow configuration overrides in /etc/sysconfig/asterisk
-CONFIG0=`readlink $0`
-if [ "$CONFIG0" = "" ]; then
- CONFIGFILE=/etc/sysconfig/`basename $0`
-else
- CONFIGFILE=/etc/sysconfig/`basename $CONFIG0`
-fi
-[ -x $CONFIGFILE ] && . $CONFIGFILE
-
-RETVAL=0
-
-start() {
- # Check if Asterisk is already running. If it is, then bug out, because
- # starting safe_asterisk when Asterisk is running is very bad.
- VERSION=`${AST_SBIN}/asterisk -rx 'core show version'`
- if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running."
- exit 1
- fi
-
- # Start daemons.
- echo -n $"Starting asterisk: "
- if [ -f $SAFE_ASTERISK ] ; then
- DAEMON=$SAFE_ASTERISK
- fi
- if [ $AST_USER ] ; then
- ASTARGS="-U $AST_USER"
- fi
- if [ $AST_GROUP ] ; then
- ASTARGS="$ASTARGS -G $AST_GROUP"
- fi
- if [ $AST_CONFIG ]; then
- ASTARGS="$ASTARGS -C $AST_CONFIG"
- fi
- daemon $DAEMON $ASTARGS
- RETVAL=$?
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/asterisk
- echo
- return $RETVAL
-}
-
-stop() {
- # Stop daemons.
- echo -n $"Shutting down asterisk: "
- killproc asterisk
- RETVAL=$?
- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/asterisk
- echo
- return $RETVAL
-}
-
-restart() {
- stop
- start
-}
-
-reload() {
- $DAEMON -rx 'reload' > /dev/null 2> /dev/null
-}
-
-# See how we were called.
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- reload
- ;;
- condrestart)
- [ -f /var/lock/subsys/asterisk ] && restart || :
- ;;
- status)
- status asterisk
- ;;
- *)
- echo "Usage: asterisk {start|stop|restart|reload|condrestart|status}"
- exit 1
-esac
-
-exit $?
diff --git a/1.4/contrib/init.d/rc.slackware.asterisk b/1.4/contrib/init.d/rc.slackware.asterisk
deleted file mode 100755
index 0b2d3a7c5..000000000
--- a/1.4/contrib/init.d/rc.slackware.asterisk
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-#
-# Start/stop/restart Asterisk PBX
-#
-# Version: 1.0 - Paul Belanger <pabelanger@gmail.com>
-#
-# 03.29.2005 - Initial Version
-#
-# $Id$
-
-asterisk_start() {
- if [ -x /usr/sbin/asterisk ]; then
- # Check if Asterisk is already running. If it is, then bug out, because
- # starting safe_asterisk when Asterisk is running is very bad.
- VERSION=`/usr/sbin/asterisk -rx 'core show version'`
- if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running. $0 will exit now."
- exit 1
- fi
-
- echo "Starting Asterisk /usr/sbin/asterisk"
- /usr/sbin/asterisk
- fi
-}
-
-asterisk_stop() {
- # If there is no PID file, ignore this request...
- if [ -r /var/run/asterisk.pid ]; then
- killall asterisk
- fi
-}
-
-asterisk_restart() {
- asterisk_stop
- asterisk_start
-}
-
-case "$1" in
- 'start')
- asterisk_start
- ;;
- 'stop')
- asterisk_stop
- ;;
- 'restart')
- asterisk_restart
- ;;
- *)
- echo "usage $0 start|stop|restart" ;;
-esac
-
diff --git a/1.4/contrib/init.d/rc.suse.asterisk b/1.4/contrib/init.d/rc.suse.asterisk
deleted file mode 100755
index c8d94df1c..000000000
--- a/1.4/contrib/init.d/rc.suse.asterisk
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/bin/sh
-# $Id: asterisk,v 1.3 2005/11/17 22:30:01 Gregory Boehnlein <damin@nacs.net>
-#
-# asterisk Starts, Stops and Reloads Asterisk.
-#
-# chkconfig: 2345 40 60
-# description: Asterisk PBX and telephony daemon.
-# processname: asterisk
-# pidfile: /var/run/asterisk.pid
-#
-# Thu Nov 17 2005 Gregory Boehnlein <damin@nacs.net>
-# - Updated Version to 1.3
-# - Reversed behavior of LD_ASSUME_KERNEL=2.4.1
-# - Added detailed failure messages
-#
-# Sun Jul 18 2004 Gregory Boehnlein <damin@nacs.net>
-# - Updated Version to 1.2
-# - Added test for safe_asterisk
-# - Verified SIGTERM issued by "killproc" ensures "stop gracefully"
-# - Added support for -U and -G command line options
-# - Modified "reload" to call asterisk -rx 'reload'
-
-### BEGIN INIT INFO
-# Provides: asterisk
-# Required-Start: +zaptel $network $named
-# Required-Stop:
-# Default-Start: 3 5
-# Default-Stop: 0 1 2 4 6
-# Description: zaptel - zaptel modules for Asterisk
-### END INIT INFO
-
-# Source function library.
-. /lib/lsb/init-functions
-
-if ! [ -x /usr/sbin/asterisk ] ; then
- echo "ERROR: /usr/sbin/asterisk not found"
- exit 0
-fi
-
-if ! [ -d /etc/asterisk ] ; then
- echo "ERROR: /etc/asterisk directory not found"
- exit 0
-fi
-
-# Uncomment this ONLY if you know what you are doing.
-# export LD_ASSUME_KERNEL=2.4.1
-
-# Full path to asterisk binary
-DAEMON=/usr/sbin/asterisk
-
-# Full path to safe_asterisk script
-SAFE_ASTERISK=/usr/sbin/safe_asterisk
-
-# Uncomment the following and set them to the user/groups that you
-# want to run Asterisk as. NOTE: this requires substantial work to
-# be sure that Asterisk's environment has permission to write the
-# files required for its operation, including logs, its comm
-# socket, the asterisk database, etc.
-#AST_USER="asterisk"
-#AST_GROUP="asterisk"
-
-RETVAL=0
-
-start() {
- # Start daemons.
-
- # Check if Asterisk is already running. If it is, then bug out, because
- # starting Asterisk when Asterisk is already running is very bad.
- VERSION=`/usr/sbin/asterisk -rx 'core show version'`
- if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running. $0 will exit now."
- exit 1
- fi
-
- echo -n $"Starting asterisk: "
- if [ -f $SAFE_ASTERISK ] ; then
- DAEMON=$SAFE_ASTERISK
- fi
- if [ $AST_USER ] ; then
- ASTARGS="-U $AST_USER"
- fi
- if [ $AST_GROUP ] ; then
- ASTARGS="`echo $ASTARGS` -G $AST_GROUP"
- fi
- $DAEMON $ASTARGS
- RETVAL=$?
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/asterisk
- echo
- return $RETVAL
-}
-
-stop() {
- # Stop daemons.
- echo -n $"Shutting down asterisk: "
- killproc asterisk
- RETVAL=$?
- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/asterisk
- echo
- return $RETVAL
-}
-
-restart() {
- stop
- start
-}
-
-reload() {
- $DAEMON -rx 'reload' > /dev/null 2> /dev/null
-}
-
-# See how we were called.
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- reload
- ;;
- condrestart)
- [ -f /var/lock/subsys/asterisk ] && restart || :
- ;;
- status)
- status asterisk
- ;;
- *)
- echo "Usage: asterisk {start|stop|restart|reload|condrestart|status}"
- exit 1
-esac
-
-exit $?
diff --git a/1.4/contrib/scripts/README.messages-expire b/1.4/contrib/scripts/README.messages-expire
deleted file mode 100644
index 12f2b0e9c..000000000
--- a/1.4/contrib/scripts/README.messages-expire
+++ /dev/null
@@ -1,20 +0,0 @@
-messages-expire.pl
-
-messages-expire finds messages more than X days old and deletes them.
-Because the older messages will be the lower numbers in the folder (msg0000
-will be older than msg0005), just deleting msg0000 will not work.
-expire-messages then runs a routine that goes into every folder in every
-mailbox to reorganize. If the folder contains msg0000, no action is taken.
-If the folder does not, the rename routine takes the oldest message and
-names it msg0000, the next oldest message and names it msg0001 and so on.
-
-The file deletion is done by the -exec parameter to 'find'. It would be far
-more efficient to take the output from 'find' and just reorganize the
-directories from which we deleted a file. Something for the future...
-
-Keep in mind that messages are deleted at the beginning of the script you
-will have mailbox trouble if you check messages before the script
-reorganizes your mailbox.
-
-To use it, make sure the paths are right. Adjust $age (originally set to
-31) if necessary.
diff --git a/1.4/contrib/scripts/agents.php b/1.4/contrib/scripts/agents.php
deleted file mode 100644
index 51f8bdee3..000000000
--- a/1.4/contrib/scripts/agents.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-ob_implicit_flush(false);
-
-$username = "drmac";
-$secret = "secret";
-
-$socket = fsockopen("127.0.0.1","5038", $errornum, $errorstr);
-
-$agents = array();
-$curr_agent = "";
-$better_status = array( 'AGENT_UNKNOWN' => 'Unknown',
- 'AGENT_IDLE' => 'Idle',
- 'AGENT_ONCALL' => 'On Call',
- 'AGENT_LOGGEDOFF' => 'Not Logged In' );
-
-if(!$socket) {
- print "Couldn't open socket. Error #" . $errornum . ": " . $errorstr;
-} else {
- fputs($socket, "Action: Login\r\n");
- fputs($socket, "UserName: $username\r\n");
- fputs($socket, "Secret: $secret\r\n\r\n");
- fputs($socket, "Action: Agents\r\n\r\n");
- fputs($socket, "Action: Logoff\r\n\r\n");
-
- while(!feof($socket)) {
- $info = fscanf($socket, "%s\t%s\r\n");
- switch($info[0]) {
- case "Agent:":
- $curr_agent = $info[1];
- $agents[$curr_agent] = array();
- break;
- case "Name:":
- $agents[$curr_agent]['Name'] = $info[1];
- break;
- case "Status:":
- $agents[$curr_agent]['Status'] = $better_status[$info[1]];
- break;
- case "LoggedInChan:":
- $agents[$curr_agent]['LoggedInChan'] = $info[1];
- break;
- case "LoggedInTime:":
- if($info[1] != "0") {
- $agents[$curr_agent]['LoggedInTime'] = date("D, M d Y g:ia", $info[1]);
- } else {
- $agents[$curr_agent]['LoggedInTime'] = "n/a";
- }
- break;
- case "TalkingTo:":
- $agents[$curr_agent]['TalkingTo'] = $info[1];
- break;
- default:
- break;
- }
- }
- fclose($socket);
-
- print "<html><head><title>Agents Status</title></head>\n<body>\n";
- print "<table width=\"800px\" border=\"1\">\n";
- print " <tr><th>Agent #</th><th>Agent Name</th><th>Agent Location</th><th>Agent Status</th><th>Agent Talking To</th><th>Agent Login Time</th></tr>\n";
-
- foreach( $agents as $agent=>$curr ) {
- print " <tr>\n <td>" . $agent . "</td>\n";
- print " <td>" . $curr['Name'] . "</td>\n";
- print " <td>" . $curr['LoggedInChan'] . "</td>\n";
- print " <td>" . $curr['Status'] . "</td>\n";
- print " <td>" . $curr['TalkingTo'] . "</td>\n";
- print " <td>" . $curr['LoggedInTime'] . "</td>\n </tr>\n";
- }
-
- print "</table>\n</body>\n</html>\n";
-}
-?>
diff --git a/1.4/contrib/scripts/ast_grab_core b/1.4/contrib/scripts/ast_grab_core
deleted file mode 100644
index b2bd7b2ed..000000000
--- a/1.4/contrib/scripts/ast_grab_core
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-# $Id$
-# lame quickie script to snarf a core of a hung asterisk process.
-# bugs to ast_grab_core, blinky-lights.org (derrick daugherty)
-
-# we have found that gcore doesn't yield as useful a core file
-# as that yielded by a signal-caused core dump. So we are going to change
-# the strategy to sending a SEGV signal to the asterisk process,
-# and have it 'burn to the ground', leaving behind a core file.
-# the main difference is that you cannot control where the
-# core file will end up. We will assume that safe_asterisk was
-# used to start asterisk, and the core file should therefore end
-# up in /tmp (because safe_asterisk cd's there before starting asterisk).
-# if this is not the case, set DUMPDIR to the place where the core
-# file can be found.
-
-DATE=`date +%Y%m%d%H%M`
-DUMPDIR=/tmp
-HOSTNAME=`hostname`
-ADMINEMAIL="root@localhost"
-
-#the following should be improved
-if [ -e /etc/asterisk/asterisk.conf ]; then
- RUNDIR=`awk -F"=>" '/astrundir/ {print $2}' /etc/asterisk/asterisk.conf`
- PID=`cat ${RUNDIR}/asterisk.pid`
-elif [ -e /var/run/asterisk.pid ] ; then
- PID=`cat /var/run/asterisk.pid`
-else
- echo Could not find an asterisk.conf definition for astrundir, using \'ps\'
- echo to try and determine process ID. This is not reliable.
- PID=`ps auxwf|grep asterisk|grep vv|head -1|awk '{print $2}'`
-fi
-
-echo Snarfing asterisk core, this could take a few seconds depending
-echo on how much memory is in use.
-echo
-echo \*\*\* WARNING \*\*\* If the system is not already locked this will cause the
-echo \*\*\* WARNING \*\*\* process to STOP while memory is dumped to disk.
-echo
-
-/bin/kill -11 ${PID}
-
-echo Snarfed! ${DUMPDIR}/core.${PID}
-echo
-
-
-echo Trying for a backtrace of the captured core.
-/usr/bin/gdb /usr/sbin/asterisk ${DUMPDIR}/core.${PID} > ${DUMPDIR}/gdb_dump.${PID}.txt 2> /dev/null << EOF
-set prompt \n
-set print pretty\n
-echo --------------------------------------------------------------------------------\n
-echo INFO THREAD
-info thread
-echo --------------------------------------------------------------------------------\n
-echo THREAD APPLY ALL BT
-thread apply all bt
-echo --------------------------------------------------------------------------------\n
-echo THREAD APPLY ALL BT FULL
-thread apply all bt full
-quit
-EOF
-echo Done trying for a bt.
-
-
-echo Notifying admins of the core.
-/usr/bin/mail -s "${HOSTNAME} core dumped at ${DUMPDIR}/core.${PID}" ${ADMINEMAIL} < ${DUMPDIR}/gdb_dump.${PID}.txt
-echo Done.
-echo
-echo Reproducible deadlocks should be posted with a full backtrace and instructions
-echo to reproduce the issue at http://bugs.digium.com/ Thanks!
diff --git a/1.4/contrib/scripts/astgenkey b/1.4/contrib/scripts/astgenkey
deleted file mode 100644
index 637604896..000000000
--- a/1.4/contrib/scripts/astgenkey
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/sh
-#
-# Usage: astgenkey [ -q ] [ -n ] [keyname]
-#
-DES3=-des3
-if [ "$1" = "-q" ]; then
- QUIET='y'
- if [ "$2" = "-n" ]; then
- DES3=
- KEY=$3
- else
- KEY=$2
- fi
-elif [ "$1" = "-n" ]; then
- DES3=
- if [ "$2" = "-q" ]; then
- QUIET='y'
- KEY=$3
- else
- KEY=$2
- fi
-else
- KEY=$1
-fi
-
-if [ "$QUIET" != 'y' ]; then
- echo ""
- echo "This script generates an RSA private and public key pair"
- echo "in PEM format for use by Asterisk. You will be asked to"
- echo "enter a passcode for your key multiple times. Please"
- echo "enter the same code each time. The resulting files will"
- echo "need to be moved to /var/lib/asterisk/keys if you want"
- echo "to use them, and any private keys (.key files) will"
- echo "need to be initialized at runtime either by running"
- echo "Asterisk with the '-i' option, or with the 'init keys'"
- echo "command once Asterisk is running."
- echo ""
- echo "Press ENTER to continue or ^C to cancel."
- read BLAH
-fi
-
-while [ "$KEY" = "" ]; do
- echo -n "Enter key name: "
- read KEY
-done
-
-rm -f ${KEY}.key ${KEY}.pub
-
-echo "Generating SSL key '$KEY': "
-openssl genrsa -out ${KEY}.key ${DES3} 1024
-openssl rsa -in ${KEY}.key -pubout -out ${KEY}.pub
-
-if [ -f "${KEY}.key" ] && [ -f "${KEY}.pub" ]; then
- if [ "$QUIET" != 'y' ]; then
- echo "Key creation successful."
- echo "Public key: ${KEY}.pub"
- echo "Private key: ${KEY}.key"
- fi
-else
- echo "Unknown error creating keys."
-fi
diff --git a/1.4/contrib/scripts/astgenkey.8 b/1.4/contrib/scripts/astgenkey.8
deleted file mode 100644
index 328a4d259..000000000
--- a/1.4/contrib/scripts/astgenkey.8
+++ /dev/null
@@ -1,144 +0,0 @@
-.\" $Header$
-.\"
-.\" transcript compatibility for postscript use.
-.\"
-.\" synopsis: .P! <file.ps>
-.\"
-.de P!
-.fl
-\!!1 setgray
-.fl
-\\&.\"
-.fl
-\!!0 setgray
-.fl \" force out current output buffer
-\!!save /psv exch def currentpoint translate 0 0 moveto
-\!!/showpage{}def
-.fl \" prolog
-.sy sed \-e 's/^/!/' \\$1\" bring in postscript file
-\!!psv restore
-.
-.de pF
-.ie \\*(f1 .ds f1 \\n(.f
-.el .ie \\*(f2 .ds f2 \\n(.f
-.el .ie \\*(f3 .ds f3 \\n(.f
-.el .ie \\*(f4 .ds f4 \\n(.f
-.el .tm ? font overflow
-.ft \\$1
-..
-.de fP
-.ie !\\*(f4 \{\
-. ft \\*(f4
-. ds f4\"
-' br \}
-.el .ie !\\*(f3 \{\
-. ft \\*(f3
-. ds f3\"
-' br \}
-.el .ie !\\*(f2 \{\
-. ft \\*(f2
-. ds f2\"
-' br \}
-.el .ie !\\*(f1 \{\
-. ft \\*(f1
-. ds f1\"
-' br \}
-.el .tm ? font underflow
-..
-.ds f1\"
-.ds f2\"
-.ds f3\"
-.ds f4\"
-'\" t
-.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n
-.TH ASTGENKEY 8 "May 14th, 2005" "Asterisk" "Linux Programmer's Manual"
-.SH NAME
-.B astgenkey
--- generates keys for for Asterisk IAX2 RSA authentication
-.SH SYNOPSIS
-.PP
-.B astgenkey
-[ -q ] [ -n ] [ \fIkeyname\fP ]
-
-.SH DESCRIPTION
-.B astgenkey
-This script generates an RSA private and public key pair in PEM format
-for use by Asterisk. The private key should be kept a secret, as it can
-be used to fake your system's identity. Thus by default (without the
-option
-.I -n
-) the script will create a passphrase-encrypted copy of your secret key:
-without entering the passphrase you won't be able to use it.
-
-However if you want to use such a key with Asterisk, you'll have to start
-it interactively, because the scripts that start asterisk can't use that
-encrypted key.
-
-The key is identified by a name. If you don't write the name on the
-command-line you'll be prompted for one. The outputs of the script are:
-
-.I name\fB.pub
-.RS
-The public key: not secret. Send this to the other side.
-.RE
-
-.I name\fB.key
-.RS
-The private key: secret.
-.RE
-
-Those files should be copied to
-.I /var/lib/asterisk/keys
-
-(The private key: on your system. The public key: on other systems)
-
-To see the currently-installed keys from the asterisk CLI, use the command
-
-.RS
-show keys
-.RE
-
-.SH OPTIONS
-.B -q
-.RS
-Run quietly.
-.RE
-
-.B -n
-.RS
-Don't encrypt the private key.
-.RE
-
-.SH SECURITY
-The keys are created, using the umask of the user running the command.
-To create the keys in a secure manner, you should check to ensure that
-your umask is first set to disallow the private key from being world-
-readable, such as with the following commands:
-
-.I umask 0066
-
-.I astgenkey yourkey
-
-And then make the key accessible to Asterisk (assuming you run it as
-user "asterisk").
-
- chown asterisk /var/lib/asterisk/keys/yourname.*
-
-.SH FILES
-.I /var/lib/asterisk/keys
-.RS
-.RE
-
-.SH "SEE ALSO"
-asterisk(8), genrsa(1), rsa(1),
-
-http://www.voip-info.org/wiki-Asterisk+iax+rsa+auth
-
-.SH "AUTHOR"
-This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
-Permission is granted to copy, distribute and/or modify this document under
-the terms of the GNU General Public License, Version 2 any
-later version published by the Free Software Foundation.
-
-On Debian systems, the complete text of the GNU General Public
-License can be found in /usr/share/common-licenses/GPL.
diff --git a/1.4/contrib/scripts/autosupport b/1.4/contrib/scripts/autosupport
deleted file mode 100644
index 83efef42a..000000000
--- a/1.4/contrib/scripts/autosupport
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/bin/sh
-#
-# Collect support information
-#
-# Copyright (C) 2005, Digium, Inc.
-#
-# Written by John Bigelow (support@digium.com)
-#
-# Distributed under the terms of the GNU General Public
-# License
-#
-
-OUTPUT=$HOME/digiuminfo
-
-MYUID=$(id -u);
-
-if [ $MYUID -ne 0 ]; then
-
- echo "You must be root to run this."
- exit 1
-fi
-
-clear
-
-echo
-echo "This will gather information about your system such as:"
-echo "pci listing, dmesg, running processes, and kernel version"
-echo "This may take up to half a minute to run. Please be patient."
-echo "To continue press 'y', to quit press any other key"
-read ans
-
-if [ "$ans" = "y" ]; then
-
- rm -f $OUTPUT
-
- echo "------------------" >> $OUTPUT;
- echo "PCI LIST" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- lspci -vvvb >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "PCI LIST(no lookup)" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- lspci -vvvbn >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "INTERRUPTS" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- cat /proc/interrupts >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "RUNNING PROCESSES" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- ps aux >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "KERNEL VERSION" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- uname -a >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "CPU INFO" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- cat /proc/cpuinfo >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "VERSION INFO" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- cat /proc/version >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "CMDLINE INFO" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- cat /proc/cmdline >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "KERNEL CONFIG" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- echo "/lib/modules/$(uname -r)/build/.config:" >> $OUTPUT;
- cat /lib/modules/$(uname -r)/build/.config >> $OUTPUT;
- echo >> $OUTPUT;
- echo "/usr/src/linux/.config:" >> $OUTPUT;
- cat /usr/src/linux/.config >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "ZAPTEL MODULE INFO" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- modinfo /lib/modules/$(uname -r)/misc/*.ko >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "OTHER INFO" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- echo "/etc/*issues*:" >> $OUTPUT;
- cat /etc/*issues* >> $OUTPUT;
- echo >> $OUTPUT;
- echo "/etc/*release*:" >> $OUTPUT;
- cat /etc/*release* >> $OUTPUT;
- echo >> $OUTPUT;
- echo "/etc/*motd*:" >> $OUTPUT;
- cat /etc/*motd* >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "LOADED MODULES" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- lsmod >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "ZTTEST" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- zttest -c 20 >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "DMESG OUTPUT" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- dmesg >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "DMIDECODE" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- dmidecode >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "ZAPTEL CONFIG" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- grep -v '^#' /etc/zaptel.conf >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "ZAPATA CONFIG" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- grep -v '^;' /etc/asterisk/zapata.conf >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
- echo "------------------" >> $OUTPUT;
- echo "EXTENSIONS CONFIG" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
- grep -v '^;' /etc/asterisk/extensions.conf >> $OUTPUT;
- echo >> $OUTPUT;
- echo >> $OUTPUT;
-
-else
- echo "terminated";
-exit
-fi
-
-clear
-
-echo
-echo "Digium may require root level access to the system to help debug";
-echo "the problem you are experiencing. Do you want to provide login";
-echo "information at this time? Please note that if you do so, change";
-echo "your root password to a secure temporary password for Digium support";
-echo "Press 'y' for yes and any other key to exit and save the previous info collected"
-read login
-
-if [ "$login" = "y" ]; then
-
- echo "------------------" >> $OUTPUT;
- echo "LOGIN INFORMATION" >> $OUTPUT;
- echo "------------------" >> $OUTPUT;
-
- echo
- echo "What is your root password?"
- read rootpass
-
- echo
- echo "Root pass: "$rootpass >> $OUTPUT
-
- echo
- echo "What is your PUBLIC IP address?"
- read ip
-
- echo "IP address: "$ip >> $OUTPUT
-
- echo
- echo "Please provide any other login information that the technician"
- echo "may need to know to login to the system'(press enter if not)'"
- read adinfo
-
- echo "Additional login info: "$adinfo >> $OUTPUT
-
- clear
- echo
- echo "All information has been stored in $OUTPUT,"
- echo "Please attach this file to an email case you already"
- echo "have open with Digium Tech Support."
-
-else
- clear
- echo
- echo "All information except login info has been stored in $OUTPUT,"
- echo "Please send this file to an email case you already"
- echo "have open with Digium Tech Support."
-exit
-fi
-
-
-
diff --git a/1.4/contrib/scripts/autosupport.8 b/1.4/contrib/scripts/autosupport.8
deleted file mode 100644
index e356fcdbb..000000000
--- a/1.4/contrib/scripts/autosupport.8
+++ /dev/null
@@ -1,41 +0,0 @@
-.TH AUTOSUPPORT 8 "Jul 5th, 2005" "Asterisk" "Linux Programmer's Manual"
-.SH NAME
-.B autosupport
-\(em interactive script to provide Digium[tm]'s support with information
-.SH SYNOPSIS
-.PP
-.B autosupport
-
-.SH DESCRIPTION
-.B autoasupport
-is a script that is normally run by a user contacting Digium's support
-to automate gathering support information.
-
-It will probe the system for some configuration and run-time information,
-and will also prompt the user for some optional access information (IP
-address, login and password).
-
-The information is written to /root/digiuminfo which the user is expected
-to attach to a support ticket to Digium.
-
-The script must be run as root as it reads Asterisk's configuration and
-the disk information using hdparm(8).
-
-.SH FILES
-.B /root/digiuminfo
-.RS
-The output of the script goes there
-.RE
-
-.SH SEE ALSO
-asterisk(8)
-
-.SH "AUTHOR"
-autosupport was written by John Bigelow <support@digium.com>.
-This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
-Permission is granted to copy, distribute and/or modify this document under
-the terms of the GNU General Public License, Version 2 any
-later version published by the Free Software Foundation.
-
-On Debian systems, the complete text of the GNU General Public
-License can be found in /usr/share/common-licenses/GPL.
diff --git a/1.4/contrib/scripts/get_ilbc_source.sh b/1.4/contrib/scripts/get_ilbc_source.sh
deleted file mode 100755
index 21333f14c..000000000
--- a/1.4/contrib/scripts/get_ilbc_source.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh -e
-
-if [ -f codecs/ilbc/iLBC_define.h ]; then
- echo "***"
- echo "The iLBC source code appears to already be present and does not"
- echo "need to be downloaded."
- echo "***"
-
- exit 1
-fi
-
-echo "***"
-echo "This script will download the Global IP Solutions iLBC encoder/decoder"
-echo "source code from http://ilbcfreeware.org. Use of this code requires"
-echo "agreeing to the license agreement present at that site."
-echo ""
-echo "This script assumes that you have already agreed to the license agreement."
-echo "If you have not done so, you can abort the script now."
-echo "***"
-
-read tmp
-
-wget -P codecs/ilbc http://www.ietf.org/rfc/rfc3951.txt
-
-wget -P codecs/ilbc http://www.ilbcfreeware.org/documentation/extract-cfile.awk
-
-(cd codecs/ilbc && awk -f extract-cfile.awk rfc3951.txt)
-
-echo "***"
-echo "The iLBC source code download is complete."
-echo "***"
-
-exit 0
diff --git a/1.4/contrib/scripts/iax-friends.sql b/1.4/contrib/scripts/iax-friends.sql
deleted file mode 100644
index 9f8cd5ccd..000000000
--- a/1.4/contrib/scripts/iax-friends.sql
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Table structure for table `iaxfriends`
-#
-
-CREATE TABLE `iaxfriends` (
- `name` varchar(40) NOT NULL default '',
- `username` varchar(40) NOT NULL default '',
- `secret` varchar(40) NOT NULL default '',
- `dbsecret` varchar(40) NOT NULL default '',
- `context` varchar(40) NOT NULL default '',
- `regcontext` varchar(40) NOT NULL default '',
- `host` varchar(40) NOT NULL default 'dynamic',
- `ipaddr` varchar(20) NOT NULL default '',
- `port` int(6) NOT NULL default '0',
- `defaultip` varchar(20) NOT NULL default '',
- `sourceaddress` varchar(20) NOT NULL default '',
- `mask` varchar(20) NOT NULL default '',
- `regexten` varchar(40) NOT NULL default '',
- `regseconds` int(11) NOT NULL default '0',
- `accountcode` varchar(20) NOT NULL default '',
- `mohinterpret` varchar(20) NOT NULL default '',
- `mohsuggest` varchar(20) NOT NULL default '',
- `inkeys` varchar(40) NOT NULL default '',
- `outkey` varchar(40) NOT NULL default '',
- `language` varchar(10) NOT NULL default '',
- `callerid` varchar(40) NOT NULL default '',
- `cid_number` varchar(40) NOT NULL default '',
- `sendani` varchar(10) NOT NULL default '',
- `fullname` varchar(40) NOT NULL default '',
- `trunk` varchar(10) NOT NULL default '',
- `auth` varchar(20) NOT NULL default '',
- `maxauthreq` varchar(15) NOT NULL default '',
- `encryption` varchar(20) NOT NULL default '',
- `transfer` varchar(10) NOT NULL default '',
- `jitterbuffer` varchar(10) NOT NULL default '',
- `forcejitterbuffer` varchar(10) NOT NULL default '',
- `disallow` varchar(40) NOT NULL default 'all',
- `allow` varchar(40) NOT NULL default '',
- `codecpriority` varchar(40) NOT NULL default '',
- `qualify` varchar(10) NOT NULL default '',
- `qualifysmoothing` varchar(10) NOT NULL default '',
- `qualifyfreqok` varchar(10) NOT NULL default '',
- `qualifyfreqnotok` varchar(10) NOT NULL default '',
- `timezone` varchar(20) NOT NULL default '',
- `adsi` varchar(10) NOT NULL default '',
- `amaflags` varchar(20) NOT NULL default '',
- `setvar` varchar(200) NOT NULL default '',
- PRIMARY KEY (`name`),
- INDEX name (name, host),
- INDEX name2 (name, ipaddr, port),
- INDEX ipaddr (ipaddr, port),
- INDEX host (host, port),
-) TYPE=MyISAM;
-
diff --git a/1.4/contrib/scripts/loadtest.tcl b/1.4/contrib/scripts/loadtest.tcl
deleted file mode 100644
index 9c50be338..000000000
--- a/1.4/contrib/scripts/loadtest.tcl
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/tclsh
-#
-# Usage (as root):
-#
-# $ tclsh loadtest.tcl
-#
-# Copyleft 2005 by Chris Maj <cmaj_at_freedomcorpse_dot_com>
-#
-# Create a (huge) bunch of call files to dial via pbx_spool.
-# Defaults are selected with 'Enter' and, if all defaults
-# are selected, you'll dial Zap/1/s into default|s|1
-#
-
-
-# where Asterisk's pbx/pbx_spool.c will be looking for work
-set SPOOLDIR /var/spool/asterisk/outgoing
-# pbx_spool is fairly aggresive, so make files here first
-set TEMPDIR /tmp
-
-if { ![file writable $SPOOLDIR] } {
- puts "Do you need to be root to write to $SPOOLDIR ?"
- exit
-}
-
-if { ![file readable $TEMPDIR] } {
- puts "Do you need to be root to read from $TEMPDIR ?"
- exit
-}
-
-if { ![file writable $TEMPDIR] } {
- puts "Do you need to be root to write to $TEMPDIR ?"
- exit
-}
-
-# gets some input from the user
-proc get {var_ default_ prompt_} {
- global $var_
- puts $prompt_
- if { $default_ != "" } {
- puts -nonewline "(default: $default_) ? "
- } else {
- puts -nonewline "? "
- }
- flush stdout
- gets stdin $var_
- if { [set $var_] == "" && $default_ != "" } {
- set $var_ $default_
- }
-}
-
-# puts the user requested channels into a neat, ordered list
-proc splitchans {inch_} {
- global changroup
- set outch [list]
- foreach range [split $inch_ {, }] {
- set start [lindex [split $range -] 0]
- set stop [lindex [split $range -] end]
- if { [string is digit $start] && [string is digit $stop] } {
- set ::changroup "channel"
- for {set ch $start} {$ch <= $stop} {incr ch} {
- if { [lsearch $outch $ch] == -1 } {
- lappend outch $ch
- }
- }
- } else {
- set ::changroup "group"
- foreach ch [split $range -] {
- lappend outch $ch
- }
- }
- }
- return [lsort -dictionary $outch]
-}
-
-# writes out a file in the temporary directory,
-# then changes the mtime of the file before
-# sticking it into the outgoing spool directory
-# (where pbx_spool will be looking)
-proc spool {channel_ callcnt_ when_} {
- set callstr "
-Channel: $::technology/$channel_/$::destination
-Context: $::context
-Extension: $::extension
-Priority: $::priority
-WaitTime: $::timeout
-RetryTime: $::retrytime
-MaxRetries: $::maxretries
-Callerid: $::clid
-SetVar: $::astvar
-Account: $::account
-"
- set fn "loadtest.call$callcnt_.ch$channel_"
- set fd [open $::TEMPDIR/$fn w]
- puts $fd $callstr
- close $fd
- file mtime $::TEMPDIR/$fn $when_
- file rename -force $::TEMPDIR/$fn $::SPOOLDIR/$fn
-}
-
-# prompt the user for some info
-get technology "Zap" "\nEnter technology type
-Zap, IAX, SIP, etc."
-get chans "1" "\nEnter channel(s) or group to test in formats like
-2\n1-4\n3 5 7 9\n1-23,25-47,49-71,73-95\ng4\ng2,g1"
-set channels [splitchans $chans]
-
-get destination "s" "\nEnter destination number"
-get context "default" "\nEnter context"
-get extension "s" "\nEnter extension"
-get priority "1" "\nEnter priority"
-get timeout "45" "\nEnter timeout for call to be answered in seconds"
-get maxretries "0" "\nEnter maximum number of retries"
-
-if { $maxretries > 0 } {
- get retrytime "300" "\nEnter time between retries in seconds"
-} else {
- set retrytime 300
-}
-
-get clid "" "\nEnter callerid"
-get astvar "" "\nEnter some extra variables"
-get account "loadtest" "\nEnter account code"
-get calls "1" "\nEnter number of test calls per $changroup"
-get period "60" "\nEnter period between placing calls on a particular $changroup in seconds"
-
-if { [llength $channels] > 1 } {
- get rate "0" "\nEnter period between placing each call in seconds
-0 will send a call on each $changroup every $period seconds
-1 will send a call on $changroup [lindex $channels 0] at [expr {$period + 0}]s, [lindex $channels 1] at [expr {$period + 1 }]s, etc.
-5 will send a call on $changroup [lindex $channels 0] at [expr {$period + 0}]s, [lindex $channels 1] at [expr {$period + 5 }]s, etc."
-} else {
- set rate 0
-}
-
-puts -nonewline "\nCreating spooled call files... "
-set now [clock seconds]
-set spoolcnt 0
-set spinner [list / - \\ |]
-for {set i 0} {$i < $calls} {incr i} {
- foreach ch $channels {
- set chidx [lsearch $channels $ch]
- spool $ch [incr spoolcnt] [expr {$now + ($i * $period) + ($rate * $chidx)}]
- puts -nonewline "\b"
- puts -nonewline [lindex $spinner [expr {$spoolcnt % 4}]]
- flush stdout
- }
-}
-puts "\b$spoolcnt calls placed into $SPOOLDIR !"
diff --git a/1.4/contrib/scripts/lookup.agi b/1.4/contrib/scripts/lookup.agi
deleted file mode 100644
index 4b682b837..000000000
--- a/1.4/contrib/scripts/lookup.agi
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/perl
-#
-# Use Reverse Lookups to populate valuable information
-#
-# Copyright (C) 2005 Digium, Inc.
-#
-# Mark Spencer <markster@digium.com>
-#
-# Based on work of Joe Fratantoni - BrakeDanceJ - Joe@UnrealDestination.com.
-#
-# This program is Free Software distributed under the terms of the GNU
-# General Public License version 2. See LICENSE for details.
-#
-#
-use LWP::UserAgent;
-my %AGI;
-my $debug = 0;
-$|=1;
-sub url_decode {
- my @args = @_;
- s/%([0-9A-F]{2})/chr hex $1/egios for @args;
- s/\"//egios for @args;
- return wantarray ? @args : $args[0];
-}
-
-while(<STDIN>) {
- chomp;
- last unless length($_);
- if (/^agi_(\w+)\:\s+(.*)$/) {
- $AGI{$1} = $2;
- }
-}
-
-alarm(4);
-my $number = $AGI{'callerid'};
-$number =~ /(\d+)/;
-$number = $1;
-die("You must specify a number") unless $number;
-my $ua = LWP::UserAgent->new;
-$ua->agent("Asterisk");
-my $req = HTTP::Request->new(POST => 'http://www.411.com/10668/search/Reverse_Phone');
-$req->content_type('application/x-www-form-urlencoded');
-$req->content("phone=$number");
-my $res = $ua->request($req);
-if ($res->is_success) {
- my $first, $last, $address, $street, $house, $city, $state, $zip, $phone;
- if ($res->content =~ /PAGE: PHONE_NOT_FOUND/) {
- # Limited Information
- $res->content =~ /is a \s+([A-Za-z -]*), ([A-Z]{2}) \s+based phone number and the registered carrier is (.*)\.\s+/;
- ($city, $state, $last) =
- map { url_decode($_) } ($1, $2, $3);
- $cidname = "$city, $state";
- } else {
- # Full Information
- $res->content =~ /RM_HTML_FIRST_ESC_=(.*)&_RM_HTML_LAST_ESC_=(.*)&_RM_HTML_ADDRESS_ESC_=(.*)&_RM_HTML_STREET_ESC_=(.*)&_RM_HTML_HOUSE_ESC_=(.*)&_RM_HTML_CITY_ESC_=(.*)&_RM_HTML_STATE_ESC_=(.*)&_RM_HTML_ZIP_ESC_=(.*)&_RM_HTML_PHONE_ESC_=(.*)&CITY=(.*)&STATE=(.*)/;
- ($first, $last, $address, $street, $house, $city, $state, $zip, $phone) =
- map { url_decode($_) } ($1, $2, $3, $4, $5, $6, $7, $8, $9);
- my $cidname = $last;
- if ($first) {
- $cidname = $first . " " . $last;
- } else {
- $cidname = $last;
- }
- }
- print STDOUT "SET VARIABLE CALLERID(name) \"$cidname\"\n";
- <STDIN>;
- print STDOUT "SET VARIABLE CALLER_ZIP \"$zip\"\n";
- <STDIN>;
- print STDOUT "SET VARIABLE CALLER_STATE \"$state\"\n";
- <STDIN>;
- print STDOUT "SET VARIABLE CALLER_CITY \"$city\"\n";
- <STDIN>;
- print STDOUT "SET VARIABLE CALLER_ADDRESS \"$address\"\n";
- <STDIN>;
- print STDOUT "SET VARIABLE CALLER_LAST \"$last\"\n";
- <STDIN>;
- print STDOUT "SET VARIABLE CALLER_FIRST \"$first\"\n";
- <STDIN>;
- print STDERR "First: $first\n" .
- "Last: $last\n" .
- "Address: $address\n" .
- "Street: $street\n" .
- "House: $house\n" .
- "City: $city\n" .
- "State: $state\n" .
- "Zip: $zip\n" .
- "Phone: $phone\n" if $debug;
-} else {
- print STDERR $res->status_line . "\n";
-}
diff --git a/1.4/contrib/scripts/managerproxy.pl b/1.4/contrib/scripts/managerproxy.pl
deleted file mode 100644
index cdf79a239..000000000
--- a/1.4/contrib/scripts/managerproxy.pl
+++ /dev/null
@@ -1,242 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Simple Asterisk Manager Proxy, Version 1.01
-# 2004-09-26
-# Copyright (c) 2004 David C. Troy <dave@popvox.com>
-#
-# This code is based on Flash Operator Panel 'op_server.pl'
-# by Nicolas Gudino
-#  Copyright (C) 2004.
-#
-# David C. Troy <dave@popvox.com>
-# Nicolas Gudino <nicolas@house.com.ar>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License.
-#
-# Security consideration: This script will open your manager port
-# for unauthenticated logins. Be careful out there :-)
-#############################
-
-#############################
-# Perl Prerequisites
-#############################
-use strict;
-use IO::Socket;
-use IO::Select;
-use POSIX qw(setsid);
-
-#############################
-# User Configurable Options
-#############################
-# Configuration for logging in to your asterisk server
-# Check you Asterisk config file "manager.conf" for details
-my $manager_host = '127.0.0.1';
-my $manager_port = 5038;
-my $manager_user = 'your_username';
-my $manager_secret = 'your_secret';
-# Port For this proxy
-my $listen_port = 1234;
-my $manager_pid = "/var/run/asterisk_managerproxy.pid";
-
-#############################
-# Declarations
-#############################
-my %proxy_clients;
-my $O;
-my $p;
-my @S;
-my %blocks;
-my $debug = 0;
-
-$SIG{PIPE} = 'IGNORE';
-$SIG{INT} = 'close_all';
-$SIG{USR1} = 'list_clients';
-
-if (defined($ARGV[0]))
-{
- if ($ARGV[0] eq "-d")
- {
- defined(my $pid = fork) or die "Can't Fork: $!";
- exit if $pid;
- setsid or die "Can't start a new session: $!";
- open MYPIDFILE, ">$manager_pid";
- print MYPIDFILE $$;
- close MYPIDFILE;
- }
-} else {
- $debug = 1;
-}
-
-
-# Connect to manager
-$p =
- new IO::Socket::INET->new(
- PeerAddr => $manager_host,
- PeerPort => $manager_port,
- Proto => "tcp",
- Type => SOCK_STREAM
- )
- or die "\nCould not connect to Asterisk Manager Port at $manager_host\n";
-
-$p->autoflush(1);
-
-# Login to Manager
-send_command_to_manager( "Action: Login\r\nUsername: $manager_user\r\nSecret: $manager_secret\r\n\r\n" );
-
-# Start up listener for new connections
-my $m =
- new IO::Socket::INET(Listen => 1, LocalPort => $listen_port, ReuseAddr => 1)
- or die "\nCan't listen to port $listen_port\n";
-$O = new IO::Select();
-$O->add($m);
-$O->add($p);
-$/ = "\0";
-
-sub manager_reconnect()
-{
- my $attempt = 1;
- my $total_attempts = 60;
-
- do
- {
- log_debug("** Attempt reconnection to manager port # $attempt", 16);
- $p =
- new IO::Socket::INET->new(
- PeerAddr => $manager_host,
- PeerPort => $manager_port,
- Proto => "tcp",
- Type => SOCK_STREAM
- );
- $attempt++;
- if ($attempt > $total_attempts)
- {
- die("!! Could not reconnect to Asterisk Manager port");
- }
- sleep(10); # wait 10 seconds before trying to reconnect
- } until $p;
- $O->add($p);
- send_command_to_manager(
- "Action: Login\r\nUsername: $manager_user\r\nSecret: $manager_secret\r\n\r\n"
- );
-}
-
-# Loop, continuously processing new connections, input from those connections, and input from Manager conn
-while (1)
-{
- while (@S = $O->can_read)
- {
- foreach (@S)
- {
- if ($_ == $m)
- {
- log_debug("** New client connection", 16);
- my $C = $m->accept;
- $proxy_clients{$C} = \$C;
- print "New Connection: $C\n" if $debug;
- $O->add($C);
- } else {
- # It's not a new client connection
- my $i;
- my $R = sysread($_, $i, 2); # 2048; interleave every two bytes?
- if (defined($R) && $R == 0)
- {
- # Confirm it's really dead by trying to write to it?
- my $T = syswrite($_, ' ', 2); # 2048
- if (!defined($T))
- {
- # connection went away...
- $O->remove($_);
- $_->close;
-
- # If we lost the socket for the Asterisk Mgr, then reconnect
- if ($_ == $p)
- {
- log_debug(
- "** Asterisk Manager connection lost!!!!!",
- 16);
- manager_reconnect();
- } else {
- # Remove handle from proxy_clients hash
- print "Closed Connection: $_\n" if $debug;
- delete $proxy_clients{$_};
- }
- }
- }
- else # Socket is active and we are ready to read something from it
- {
- $blocks{$_} .= $i;
- next if ($blocks{$_} !~ /\r\n\r\n$/);
- # do a 'next' unless we have completed a block; we are not ready to continue
-
- # Process the completed block
- # If block is from asterisk, send to clients
- if ($_ == $p) {
- # block is from asterisk, send to clients
- print "asterisk: $_\n$blocks{$_}" if $debug;
- my $cnt = 0;
- foreach my $client (values %proxy_clients) {
- print "writing to $$client...\n" if $debug;
- syswrite($$client, $blocks{$_});
- $cnt++;
- }
- print "sent block to $cnt clients\n" if $debug;
- } else {
- # Blocks are from clients, send to asterisk
- syswrite($p, $blocks{$_});
- print "client: $_\n$blocks{$_}\n" if $debug;
- }
- delete $blocks{$_};
-
- } # end if read succeeded
- } # end if new client connection
- } # end foreach @S -> can read
- } # while can read
-} # endless loop
-
-sub close_all
-{
- log_debug("Exiting...", 0);
-
- foreach my $hd ($O->handles)
- {
- $O->remove($hd);
- close($hd);
- }
-
- exit(0);
-}
-
-sub send_command_to_manager
-{
- my $comando = shift;
- if (defined $p)
- {
- my @lineas = split("\r\n", $comando);
- foreach my $linea (@lineas)
- {
- syswrite($p, "$linea\r\n");
- log_debug("-> $linea", 2);
- }
- log_debug(" ", 2);
- syswrite($p, "\r\n");
- }
-}
-
-sub log_debug
-{
- my $texto = shift;
- $texto =~ s/\0//g;
- print "$texto\n" if $debug;
-}
-
-sub list_clients()
-{
- my $cnt = 0;
- foreach my $client (values %proxy_clients) {
- print "client: $$client\n";
- $cnt++;
- }
- print "$cnt clients.\n\n";
-}
-
diff --git a/1.4/contrib/scripts/meetme.sql b/1.4/contrib/scripts/meetme.sql
deleted file mode 100644
index 19c4ed745..000000000
--- a/1.4/contrib/scripts/meetme.sql
+++ /dev/null
@@ -1,12 +0,0 @@
---
--- Table structure for Realtime meetme
---
-
-CREATE TABLE meetme (
- confno char(80) DEFAULT '0' NOT NULL,
- pin char(20) NULL,
- adminpin char(20) NULL,
- members integer DEFAULT 0 NOT NULL,
- PRIMARY KEY (confno)
-);
-
diff --git a/1.4/contrib/scripts/messages-expire.pl b/1.4/contrib/scripts/messages-expire.pl
deleted file mode 100644
index 993997899..000000000
--- a/1.4/contrib/scripts/messages-expire.pl
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/perl
-#
-# Script to expire voicemail after a specified number of days
-# by Steve Creel <screel@turbs.com>
-#
-
-# Directory housing the voicemail spool for asterisk
-$dir = "/var/spool/asterisk/voicemail";
-
-# Context for which the script should be running
-$context = "default";
-
-# Age (Delete files older than $age days old)
-$age = 31;
-
-# Age for unheard messages (Defaults to same age for all messages)
-# Set to 0 to not delete unheard messages
-$unheardage = $age;
-
-
-# Delete all files older than $age and $unheardage
-# (named msg????.??? to get the audio and txt files,
-# but we don't delete greetings or the user's name)
-
-if($age==$unheardage) {
-
- # Save time by doing one find if we're treating everything the same
- system('find '.$dir.'/'.$context.' -name msg????.??? -mtime +'.$age.' -exec rm {} \; -exec echo Deleted {} \;');
-
-} else {
-
- # Find everything not in a folder called 'INBOX' and delete it after $age days
- system('find '.$dir.'/'.$context.' -path \'*INBOX*\' -prune -o -name msg????.??? -mtime +'.$age.' -exec rm {} \; -exec echo Deleted {} \;');
-
- # If unheardage is set to 0, we won't delete any unheard messages
- if($unheardage > 0) {
-
- # Delete things that are in a folder called INBOX after $unheardage days
- system('find '.$dir.'/'.$context.' -path \'*INBOX*\' -name msg????.??? -mtime +'.$unheardage.' -exec rm {} \; -exec echo Deleted {} \;');
-
- }
-}
-
-# For testing - what number to we start when we renumber?
-$start = "0";
-
-# Rename to msg and a 4 digit number, 0 padded.
-$fnbase = sprintf "msg%04d", $start;
-
-# Make $dir include the context too
-$dir.="/".$context;
-
-( -d $dir ) || die "Can't read list of mailboxes ($dir): $!\n";
-@mailboxes = `ls -A1 $dir`;
-chomp(@mailboxes);
-
-$save_fnbase = $fnbase;
-
-foreach $mailbox (@mailboxes) {
-
- ( -d $dir."/".$mailbox) || die "Can't read list of folders (".$dir."/".$mailbox."): $!\n";
- @folders = `ls -A1 $dir/$mailbox`;
- chomp(@folders);
-
- foreach $folder (@folders) {
- if (-d $dir."/".$mailbox."/".$folder) {
- ( -d $dir."/".$mailbox."/".$folder) || die "Can't read list of messages (".$dir."/".$mailbox."/".$folder.") $!\n";
- @files = `ls -A1 $dir/$mailbox/$folder/`;
-
- # Sort so everything is in proper order.
- @files = sort @files;
- chomp(@files);
-
- # If there is still (after deleting old files earlier in the
- # script) a msg0000.txt, we don't need to shuffle anything
- # in this folder.
- if (-f $dir."/".$mailbox."/".$folder."/msg0000.txt") { next; }
-
- foreach $ext (("WAV", "wav", "gsm", "txt")) {
- # Reset the fnbase for each file type
- $fnbase = $save_fnbase;
-
- foreach $file (@files) {
- if ( $file =~ /$ext/ ) {
- chdir($dir."/".$mailbox."/".$folder."/") || die "Can't change folder: $!";
- print "Renaming: ".$dir."/".$mailbox."/".$folder."/".$file." to ".$fnbase.".".$ext."\n";
- rename($file, $fnbase.".".$ext) || die "Cannot rename: $!";
- $fnbase++;
- }
- }
- }
- }
- }
-}
-
-__END__ \ No newline at end of file
diff --git a/1.4/contrib/scripts/postgres_cdr.sql b/1.4/contrib/scripts/postgres_cdr.sql
deleted file mode 100644
index a4701bd77..000000000
--- a/1.4/contrib/scripts/postgres_cdr.sql
+++ /dev/null
@@ -1,33 +0,0 @@
-
-/*
- * Id: postgres_cdr.sql,v 1.8.2.11 2003/10/10 11:15:43 pnixon Exp $
- *
- * --- Peter Nixon [ codemonkey@peternixon.net ]
- *
- * This is a PostgreSQL schema for doing CDR accounting with Asterisk
- *
- * The calls will automatically be logged as long as the module is loaded.
- *
- */
-
-
-CREATE TABLE cdr (
- AcctId BIGSERIAL PRIMARY KEY,
- calldate TIMESTAMP with time zone NOT NULL DEFAULT now(),
- clid VARCHAR(80) NOT NULL default '',
- src VARCHAR(80) NOT NULL default '',
- dst VARCHAR(80) NOT NULL default '',
- dcontext VARCHAR(80) NOT NULL default '',
- channel VARCHAR(80) NOT NULL default '',
- dstchannel VARCHAR(80) NOT NULL default '',
- lastapp VARCHAR(80) NOT NULL default '',
- lastdata VARCHAR(80) NOT NULL default '',
- duration INTEGER NOT NULL default '0',
- billsec INTEGER NOT NULL default '0',
- disposition VARCHAR(45) NOT NULL default '',
- amaflags INTEGER NOT NULL default '0',
- accountcode VARCHAR(20) NOT NULL default '',
- uniqueid VARCHAR(32) NOT NULL default '',
- userfield VARCHAR(255) NOT NULL default ''
-);
-
diff --git a/1.4/contrib/scripts/qview.pl b/1.4/contrib/scripts/qview.pl
deleted file mode 100644
index 940e474f7..000000000
--- a/1.4/contrib/scripts/qview.pl
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/perl
-#
-# Asterisk Queue Viewer
-# Uses management interface to query call queues on a machine
-# (C) 2003 David C. Troy -- dave@toad.net
-#
-# This program is free software, distributed under the terms of the
-# GNU General Public License
-#
-
-use IO::Socket;
-use CGI qw(:standard);
-use CGI::Carp qw/fatalsToBrowser/;
-
-$host = "asterisk.yourdomain.com";
-$port = 5038;
-$user = "manager_user";
-$secret = "Manager_secret";
-$EOL = "\015\012";
-$BLANK = $EOL x 2;
-$queue = param('queue');
-
-$remote = IO::Socket::INET->new(
- Proto => 'tcp', # protocol
- PeerAddr=> $host, # Address of server
- PeerPort=> $port, # port of server
- Reuse => 1
- ) or die "$!";
-
-$remote->autoflush(1); # Send immediately
-
-# Login and get our booty from Asterisk
-$logres = send_cmd("Action: Login${EOL}Username: $user${EOL}Secret: $secret$BLANK");
-$qinfo = send_cmd("Action: queues$BLANK$EOL");
-$logres = send_cmd("Action: Logoff$BLANK");
-close $remote; # Close socket
-
-my %qcalls = map { /(\S+)\s+has (\d+) calls.*?\n\n/sg; } $qinfo;
-my %qmax = map { /(\S+)\s+has \d+ calls \(max (\S+)\).*?\n\n/sg; } $qinfo;
-my %qstrat = map { /(\S+)\s+has \d+ calls \(max \S+\) in (\S+) strategy.*?\n\n/sg; } $qinfo;
-my %qmems = map { /(\S+)\s+has \d+ calls.*?Members:.*?\s{6}(.*?)\s{3}\S*?\s*?Callers/sg; } $qinfo;
-my %qcallers = map { /(\S+)\s+has \d+ calls.*?([No ]*Callers.*?)\n\n/sg; } $qinfo;
-
-print header();
-print start_html(-head=>meta({-http_equiv=>'Refresh', -content=>'120'}),
- -title=>"PBX Queue Viewer",
- -style=>{'src'=>'/pbxinfo.css'});
-print "<table width=850><tr>";
-
-$col = 0;
-
-foreach $q (keys %qcalls) {
-
- $mems = $qmems{$q};
- $mems =~ s/ //g;
- $mems =~ s/\n/<br>\n/g;
- $callers = $qcallers{$q};
- $callers =~ s/ //g;
- $callers =~ s/Callers:.*\n//g;
- $callers =~ s/\n/<br>/g;
-
- print qq{<td valign=top width=48%><table width=100%>
-<tr><th colspan=2><A HREF=/mrtg/qmon-$q.html>$q</A>&nbsp;&nbsp;$qcalls{$q} calls (max $qmax{$q}), $qstrat{$q} strategy</th></tr>
-<tr><td valign=top width=55%>$mems</td><td valign=top width=45%>$callers</td></tr>
-</table></td>
-};
-
- print "</tr><tr>" if $col;
- $col = 0 if $col++;
-
-}
-
-print "</table>";
-
-print end_html();
-
-exit(0);
-
-sub read_conn {
-
- my $buf="";
- while (<$remote>) {
- last if $_ eq $EOL;
- s/$EOL/\n/g;
- $buf .= $_;
- }
-
- return $buf
-}
-
-sub send_cmd {
- my $cmd = @_[0];
-
- my $buf="";
- print $remote $cmd;
-
- $buf = read_conn();
-
- return $buf;
-}
diff --git a/1.4/contrib/scripts/realtime_pgsql.sql b/1.4/contrib/scripts/realtime_pgsql.sql
deleted file mode 100644
index c0de544ab..000000000
--- a/1.4/contrib/scripts/realtime_pgsql.sql
+++ /dev/null
@@ -1,141 +0,0 @@
-drop table extensions_conf;
-
-CREATE TABLE extensions_conf (
-id serial NOT NULL,
-context character varying(20) DEFAULT '' NOT NULL,
-exten character varying(20) DEFAULT '' NOT NULL,
-priority smallint DEFAULT 0 NOT NULL,
-app character varying(20) DEFAULT '' NOT NULL,
-appdata character varying(128)
-);
-
-drop table cdr;
-CREATE TABLE cdr (
-calldate timestamp with time zone DEFAULT now() NOT NULL,
-clid character varying(80) DEFAULT '' NOT NULL,
-src character varying(80) DEFAULT '' NOT NULL,
-dst character varying(80) DEFAULT '' NOT NULL,
-dcontext character varying(80) DEFAULT '' NOT NULL,
-channel character varying(80) DEFAULT '' NOT NULL,
-dstchannel character varying(80) DEFAULT '' NOT NULL,
-lastapp character varying(80) DEFAULT '' NOT NULL,
-lastdata character varying(80) DEFAULT '' NOT NULL,
-duration bigint DEFAULT 0::bigint NOT NULL,
-billsec bigint DEFAULT 0::bigint NOT NULL,
-disposition character varying(45) DEFAULT '' NOT NULL,
-amaflags bigint DEFAULT 0::bigint NOT NULL,
-accountcode character varying(20) DEFAULT '' NOT NULL,
-uniqueid character varying(32) DEFAULT '' NOT NULL,
-userfield character varying(255) DEFAULT '' NOT NULL
-);
-
-drop table sip_conf;
-CREATE TABLE sip_conf (
-id serial NOT NULL,
-name character varying(80) DEFAULT '' NOT NULL,
-accountcode character varying(20),
-amaflags character varying(7),
-callgroup character varying(10),
-callerid character varying(80),
-canreinvite character varying(3) DEFAULT 'yes',
-context character varying(80),
-defaultip character varying(15),
-dtmfmode character varying(7),
-fromuser character varying(80),
-fromdomain character varying(80),
-host character varying(31) DEFAULT '' NOT NULL,
-insecure character varying(4),
-"language" character varying(2),
-mailbox character varying(50),
-md5secret character varying(80),
-nat character varying(5) DEFAULT 'no' NOT NULL,
-permit character varying(95),
-deny character varying(95),
-mask character varying(95),
-pickupgroup character varying(10),
-port character varying(5) DEFAULT '' NOT NULL,
-qualify character varying(3),
-restrictcid character varying(1),
-rtptimeout character varying(3),
-rtpholdtimeout character varying(3),
-secret character varying(80),
-"type" character varying DEFAULT 'friend' NOT NULL,
-username character varying(80) DEFAULT '' NOT NULL,
-disallow character varying(100) DEFAULT 'all',
-allow character varying(100) DEFAULT 'g729;ilbc;gsm;ulaw;alaw',
-musiconhold character varying(100),
-regseconds bigint DEFAULT 0::bigint NOT NULL,
-ipaddr character varying(15) DEFAULT '' NOT NULL,
-regexten character varying(80) DEFAULT '' NOT NULL,
-cancallforward character varying(3) DEFAULT 'yes'
-);
-
-drop table voicemail_users;
-CREATE TABLE voicemail_users (
-id serial NOT NULL,
-customer_id bigint DEFAULT (0)::bigint NOT NULL,
-context character varying(50) DEFAULT '' NOT NULL,
-mailbox bigint DEFAULT (0)::bigint NOT NULL,
-"password" character varying(4) DEFAULT '0' NOT NULL,
-fullname character varying(50) DEFAULT '' NOT NULL,
-email character varying(50) DEFAULT '' NOT NULL,
-pager character varying(50) DEFAULT '' NOT NULL,
-stamp timestamp(6) without time zone NOT NULL
-);
-
-drop table queue_table;
-CREATE TABLE queue_table (
-name varchar(128),
-musiconhold varchar(128),
-announce varchar(128),
-context varchar(128),
-timeout int8,
-monitor_join bool,
-monitor_format varchar(128),
-queue_youarenext varchar(128),
-queue_thereare varchar(128),
-queue_callswaiting varchar(128),
-queue_holdtime varchar(128),
-queue_minutes varchar(128),
-queue_seconds varchar(128),
-queue_lessthan varchar(128),
-queue_thankyou varchar(128),
-queue_reporthold varchar(128),
-announce_frequency int8,
-announce_round_seconds int8,
-announce_holdtime varchar(128),
-retry int8,
-wrapuptime int8,
-maxlen int8,
-servicelevel int8,
-strategy varchar(128),
-joinempty varchar(128),
-leavewhenempty varchar(128),
-eventmemberstatus bool,
-eventwhencalled bool,
-reportholdtime bool,
-memberdelay int8,
-weight int8,
-timeoutrestart bool,
-PRIMARY KEY (name)
-) WITHOUT OIDS;
-ALTER TABLE queue_table OWNER TO asterisk;
-
-drop table queue_member_table;
-CREATE TABLE queue_member_table
-(
-queue_name varchar(128),
-interface varchar(128),
-penalty int8,
-PRIMARY KEY (queue_name, interface)
-) WITHOUT OIDS;
-
-GRANT ALL ON TABLE cdr TO asterisk;
-GRANT ALL ON TABLE extensions_conf TO asterisk;
-GRANT ALL ON TABLE sip_conf TO asterisk;
-GRANT ALL ON TABLE voicemail_users TO asterisk;
-GRANT ALL ON TABLE queue_member_table TO asterisk;
-GRANT ALL ON TABLE queue_table TO asterisk;
-
-
-
diff --git a/1.4/contrib/scripts/retrieve_extensions_from_mysql.pl b/1.4/contrib/scripts/retrieve_extensions_from_mysql.pl
deleted file mode 100644
index ca195cfe5..000000000
--- a/1.4/contrib/scripts/retrieve_extensions_from_mysql.pl
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/perl -Tw
-# Use these commands to create the appropriate tables in MySQL
-# If flags is 1 then this record is not included in the output extensions file
-#
-#CREATE TABLE extensions (
-# context CHAR(20) DEFAULT 'default' NOT NULL,
-# extension CHAR(20) NOT NULL,
-# priority INT(2) DEFAULT '1' NOT NULL,
-# application CHAR(20) NOT NULL,
-# args CHAR(50),
-# descr TEXT,
-# flags INT(1) DEFAULT '0' NOT NULL,
-# PRIMARY KEY(context, extension, priority)
-#);
-#
-#CREATE TABLE globals (
-# variable CHAR(20) NOT NULL,
-# value CHAR(50) NOT NULL,
-# PRIMARY KEY(variable, value)
-#);
-
-use DBI;
-################### BEGIN OF CONFIGURATION ####################
-
-# the name of the extensions table
-$table_name = "extensions";
-# the name of the globals table
-$global_table_name = "globals";
-# the path to the extensions.conf file
-# WARNING: this file will be substituted by the output of this program
-$extensions_conf = "/etc/asterisk/extensions.conf";
-# the name of the box the MySQL database is running on
-$hostname = "localhost";
-# the name of the database our tables are kept
-$database = "user";
-# username to connect to the database
-$username = "";
-# password to connect to the database
-$password = "";
-
-################### END OF CONFIGURATION #######################
-
-open EXTEN, ">$extensions_conf" || die "Cannot create/overwrite extensions file: $extensions_conf\n";
-
-$dbh = DBI->connect("dbi:mysql:dbname=$database;host=$hostname", "$username", "$password");
-$statement = "SELECT * from $global_table_name order by variable";
-my $result = $dbh->selectall_arrayref($statement);
-unless ($result) {
- # check for errors after every single database call
- print "dbh->selectall_arrayref($statement) failed!\n";
- print "DBI::err=[$DBI::err]\n";
- print "DBI::errstr=[$DBI::errstr]\n";
- exit;
-}
-my @resultSet = @{$result};
-if ( $#resultSet > -1 ) {
- print EXTEN "[globals]\n";
- foreach $row (@{ $result }) {
- my @result = @{ $row };
- print EXTEN "$result[0] = $result[1]\n";
- }
- print EXTEN "\n";
-}
-
-$statement = "SELECT context from $table_name group by context";
-
-$result = $dbh->selectall_arrayref($statement);
-unless ($result) {
- # check for errors after every single database call
- print "dbh->selectall_arrayref($statement) failed!\n";
- print "DBI::err=[$DBI::err]\n";
- print "DBI::errstr=[$DBI::errstr]\n";
-}
-
-@resultSet = @{$result};
-if ( $#resultSet == -1 ) {
- print "No extensions defined in $table_name\n";
- exit;
-}
-
-foreach my $row ( @{ $result } ) {
- my $context = @{ $row }[0];
- print EXTEN "[$context]\n";
- $statement = "SELECT * from $table_name where context='$context' order by extension, priority";
- my $result = $dbh->selectall_arrayref($statement);
- unless ($result) {
- # check for errors after every single database call
- print "dbh->selectall_arrayref($statement) failed!\n";
- print "DBI::err=[$DBI::err]\n";
- print "DBI::errstr=[$DBI::errstr]\n";
- exit;
- }
-
- my @resSet = @{$result};
- if ( $#resSet == -1 ) {
- print "no results\n";
- exit;
- }
- foreach my $row ( @{ $result } ) {
- my @result = @{ $row };
- if ($result[6] == 0) {
- print EXTEN "exten => $result[1],$result[2],$result[3]";
- print EXTEN "($result[4])" if defined $result[4];
- print EXTEN "\t" if not defined $result[4];
- print EXTEN "\t; $result[5]" if defined $result[5];
- print EXTEN "\n";
- }
- }
- print EXTEN "\n";
-}
-
-exit 0;
-
diff --git a/1.4/contrib/scripts/retrieve_extensions_from_sql.pl b/1.4/contrib/scripts/retrieve_extensions_from_sql.pl
deleted file mode 100644
index cf17d0351..000000000
--- a/1.4/contrib/scripts/retrieve_extensions_from_sql.pl
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/usr/bin/perl -Tw
-# Author: Peter Nixon <codemonkey@peternixon.net>
-# Date: April 2004
-# Copy Policy: GNU Public Licence Version 2 or later
-# URL: http://www.peternixon.net/code/
-# Supported: PostgreSQL, Oracle, MySQL
-# Copyright: 2004 Peter Nixon <codemonkey@petenixon.net>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# $Id$
-#
-# Use these commands to create the appropriate SQL tables
-# If flags is 1 then the record is not included in the output extensions file
-#
-#CREATE TABLE extensions (
-# context VARCHAR(20) DEFAULT 'default' NOT NULL,
-# extension VARCHAR(20) NOT NULL,
-# priority INTEGER DEFAULT '1' NOT NULL,
-# application VARCHAR(20) NOT NULL,
-# args VARCHAR(50),
-# descr TEXT,
-# flags BOOLEAN DEFAULT '0' NOT NULL,
-# PRIMARY KEY(context, extension, priority)
-#);
-
-#CREATE TABLE globals (
-# variable VARCHAR(20) NOT NULL,
-# value VARCHAR(50) NOT NULL,
-# PRIMARY KEY(variable, value)
-#);
-
-use strict; # Make sure we write decent perl code
-
-require DBI; # We need database drivers for this thing to work
-
-################### BEGIN OF CONFIGURATION ####################
-
-my $table_name = "extensions"; # name of the extensions table
-my $global_table_name = "globals"; # name of the globals table
-my $extensions_conf = "/etc/asterisk/extensions.conf"; # path to extensions.conf
-# WARNING: this file will be substituted by the output of this program
-my $dbbrand = "Pg"; # Hint: "mysql" or any other Perl DBI driver.
-my $hostname = "localhost"; # The SQL server's hostname or IP
-my $database = "peter"; # the name of the database our tables are kept
-my $username = "peter"; # username to connect to the database
-my $password = ""; # password to connect to the database
-my $verbose = 1; # Verbosity Level (0 - 2)
-
-################### END OF CONFIGURATION #######################
-
-# You should not need to edit anything below here
-my $dbh;
-
-sub db_connect {
- if ($verbose > 1) { print "DEBUG: Connecting to Database Host: $hostname\n" }
- if ($hostname eq 'localhost') {
- if ($verbose > 1) { print "DEBUG: SQL server is on localhost so using UNIX socket instead of network socket.\n" }
- $dbh = DBI->connect("DBI:$dbbrand:dbname=$database", "$username", "$password")
- or die "Couldn't connect to database: " . DBI->errstr;
- }
- else {
- $dbh = DBI->connect("DBI:$dbbrand:dbname=$database;host=$hostname", "$username", "$password")
- or die "Couldn't connect to database: " . DBI->errstr;
- }
-}
-
-sub db_disconnect {
- if ($verbose > 1) { print "DEBUG: Disconnecting from Database Host: $hostname\n" }
- $dbh->disconnect
- or warn "Disconnection failed: $DBI::errstr\n";
-}
-
-sub get_globals {
- if ($verbose > 0) { print "Checking Database for [global] variables\n"; }
- my $sth = $dbh->prepare("SELECT variable, value FROM $global_table_name ORDER BY variable")
- or die "Couldn't prepare statement: " . $dbh->errstr;
-
- $sth->execute() # Execute the query
- or die "Couldn't execute SELECT statement: " . $sth->errstr;
-
- if ($sth->rows > 0) {
- print EXTEN "[globals]\n";
- while (my @global = $sth->fetchrow_array()) {
- print EXTEN "$global[0] = $global[1]\n";
- }
- print EXTEN "\n";
- } else {
- print "WARNING: You have no global variables set\n";
- }
- $sth->finish;
-}
-
-sub get_contexts {
- if ($verbose > 0) { print "Checking Database for contexts\n"; }
- my $sth = $dbh->prepare("SELECT context FROM $table_name GROUP BY context")
- or die "Couldn't prepare statement: " . $dbh->errstr;
-
- $sth->execute() # Execute the query
- or die "Couldn't execute SELECT statement: " . $sth->errstr;
-
- if ($sth->rows > 0) {
- while (my @context = $sth->fetchrow_array()) {
- print EXTEN "[$context[0]]\n";
- &get_extensions($context[0]);
- print EXTEN "\n";
- }
- print EXTEN "\n";
- } else {
- print "WARNING: You have no contexts defined in the $table_name table\n";
- }
- $sth->finish;
-}
-
-sub get_extensions {
- my $context = $_[0]; my @extension;
- if ($verbose > 0) { print " Checking Database for [$context] extensions\n"; }
- my $sth = $dbh->prepare("SELECT extension, priority, application, args, descr FROM $table_name WHERE context='$context' AND flags = '0' ORDER BY extension, priority")
- or die "Couldn't prepare statement: " . $dbh->errstr;
-
- $sth->execute() # Execute the query
- or die "Couldn't execute SELECT statement: " . $sth->errstr;
-
- if ($sth->rows > 0) {
- while (@extension = $sth->fetchrow_array()) {
- print EXTEN "exten => $extension[0],$extension[1],$extension[2]";
- print EXTEN "($extension[3])" if defined $extension[3];
- print EXTEN " ; $extension[4]" if defined $extension[4];
- print EXTEN "\n";
- }
- } else {
- print "WARNING: You have no extensions for [$context]\n";
- }
- $sth->finish;
-}
-
-
-sub main {
- open EXTEN, ">$extensions_conf" || die "Cannot create/overwrite extensions file: $extensions_conf\n";
- &db_connect;
- &get_globals;
- &get_contexts;
- &db_disconnect;
- close EXTEN; # Close the file handle
- if ($verbose > 0) { print "New $extensions_conf successfully written.\n"; }
- return 1;
-}
-
-
-exit &main();
diff --git a/1.4/contrib/scripts/retrieve_sip_conf_from_mysql.pl b/1.4/contrib/scripts/retrieve_sip_conf_from_mysql.pl
deleted file mode 100644
index 03395a125..000000000
--- a/1.4/contrib/scripts/retrieve_sip_conf_from_mysql.pl
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/perl -Tw
-# Retrieves the sip user/peer entries from the database
-# Use these commands to create the appropriate tables in MySQL
-#
-#CREATE TABLE sip (id INT(11) DEFAULT -1 NOT NULL,keyword VARCHAR(20) NOT NULL,data VARCHAR(50) NOT NULL, flags INT(1) DEFAULT 0 NOT NULL,PRIMARY KEY (id,keyword));
-#
-# if flags = 1 then the records are not included in the output file
-
-use DBI;
-################### BEGIN OF CONFIGURATION ####################
-
-# the name of the extensions table
-$table_name = "sip";
-# the path to the extensions.conf file
-# WARNING: this file will be substituted by the output of this program
-$sip_conf = "/etc/asterisk/sip_additional.conf";
-# the name of the box the MySQL database is running on
-$hostname = "localhost";
-# the name of the database our tables are kept
-$database = "sip";
-# username to connect to the database
-$username = "root";
-# password to connect to the database
-$password = "";
-
-################### END OF CONFIGURATION #######################
-
-$additional = "";
-
-open EXTEN, ">$sip_conf" || die "Cannot create/overwrite extensions file: $sip_conf\n";
-
-$dbh = DBI->connect("dbi:mysql:dbname=$database;host=$hostname", "$username", "$password");
-$statement = "SELECT keyword,data from $table_name where id=0 and keyword <> 'account' and flags <> 1";
-my $result = $dbh->selectall_arrayref($statement);
-unless ($result) {
- # check for errors after every single database call
- print "dbh->selectall_arrayref($statement) failed!\n";
- print "DBI::err=[$DBI::err]\n";
- print "DBI::errstr=[$DBI::errstr]\n";
- exit;
-}
-my @resultSet = @{$result};
-if ( $#resultSet > -1 ) {
- foreach $row (@{ $result }) {
- my @result = @{ $row };
- $additional .= $result[0]."=".$result[1]."\n";
- }
-}
-
-$statement = "SELECT data,id from $table_name where keyword='account' and flags <> 1 group by data";
-
-$result = $dbh->selectall_arrayref($statement);
-unless ($result) {
- # check for errors after every single database call
- print "dbh->selectall_arrayref($statement) failed!\n";
- print "DBI::err=[$DBI::err]\n";
- print "DBI::errstr=[$DBI::errstr]\n";
-}
-
-@resultSet = @{$result};
-if ( $#resultSet == -1 ) {
- print "No sip accounts defined in $table_name\n";
- exit;
-}
-
-foreach my $row ( @{ $result } ) {
- my $account = @{ $row }[0];
- my $id = @{ $row }[1];
- print EXTEN "[$account]\n";
- $statement = "SELECT keyword,data from $table_name where id=$id and keyword <> 'account' and flags <> 1 order by keyword";
- my $result = $dbh->selectall_arrayref($statement);
- unless ($result) {
- # check for errors after every single database call
- print "dbh->selectall_arrayref($statement) failed!\n";
- print "DBI::err=[$DBI::err]\n";
- print "DBI::errstr=[$DBI::errstr]\n";
- exit;
- }
-
- my @resSet = @{$result};
- if ( $#resSet == -1 ) {
- print "no results\n";
- exit;
- }
- foreach my $row ( @{ $result } ) {
- my @result = @{ $row };
- print EXTEN "$result[0]=$result[1]\n";
- }
- print EXTEN "$additional\n";
-}
-
-exit 0;
-
diff --git a/1.4/contrib/scripts/safe_asterisk b/1.4/contrib/scripts/safe_asterisk
deleted file mode 100644
index 1cb5e8006..000000000
--- a/1.4/contrib/scripts/safe_asterisk
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/bin/bash
-# vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent:autoindent
-
-CLIARGS="$*" # Grab any args passed to safe_asterisk
-TTY=9 # TTY (if you want one) for Asterisk to run on
-CONSOLE=yes # Whether or not you want a console
-#NOTIFY=ben@alkaloid.net # Who to notify about crashes
-#EXEC=/path/to/somescript # Run this command if Asterisk crashes
-MACHINE=`hostname` # To specify which machine has crashed when getting the mail
-DUMPDROP=/tmp
-SLEEPSECS=4
-ASTSBINDIR=__ASTERISK_SBIN_DIR__
-ASTPIDFILE=__ASTERISK_VARRUN_DIR__/asterisk.pid
-
-# comment this line out to have this script _not_ kill all mpg123 processes when
-# asterisk exits
-KILLALLMPG123=1
-
-# run asterisk with this priority
-PRIORITY=0
-
-# set system filemax on supported OSes if this variable is set
-# SYSMAXFILES=262144
-
-# set max files open with ulimit. On linux systems, this will be automatically
-# set to the system's maximum files open devided by two, if not set here.
-# MAXFILES=32768
-
-# Check if Asterisk is already running. If it is, then bug out, because
-# starting safe_asterisk when Asterisk is running is very bad.
-VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
-if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
- echo "Asterisk is already running. $0 will exit now."
- exit 1
-fi
-
-# since we're going to change priority and open files limits, we need to be
-# root. if running asterisk as other users, pass that to asterisk on the command
-# line.
-# if we're not root, fall back to standard everything.
-if [ `id -u` != 0 ]
-then
- echo "Oops. I'm not root. Falling back to standard prio and file max." >&2
- echo "This is NOT suitable for large systems." >&2
- PRIORITY=0
-else
- if `echo $OSTYPE | grep linux 2>&1 > /dev/null `
- then
- # maximum number of open files is set to the system maximum divided by two if
- # MAXFILES is not set.
- if [ "$MAXFILES" = "" ]
- then
- # just check if file-max is readable
- if [ -r /proc/sys/fs/file-max ]
- then
- MAXFILES=$(( `cat /proc/sys/fs/file-max` / 2 ))
- fi
- fi
- SYSCTL_MAXFILES="fs.file-max"
- elif `echo $OSTYPE | grep darwin 2>&1 > /dev/null `
- then
- SYSCTL_MAXFILES="kern.maxfiles"
- fi
-
-
- if [ "$SYSMAXFILES" != "" ]
- then
- if [ "$SYSCTL_MAXFILES" != "" ]
- then
- sysctl -w $SYSCTL_MAXFILES=$SYSMAXFILES
- fi
- fi
-
- # set the process's filemax to whatever set above
- ulimit -n $MAXFILES
-
-fi
-
-#
-# Let Asterisk dump core
-#
-ulimit -c unlimited
-
-#
-# Don't fork when running "safely"
-#
-ASTARGS=""
-if [ "$TTY" != "" ]; then
- if [ -c /dev/tty${TTY} ]; then
- TTY=tty${TTY}
- elif [ -c /dev/vc/${TTY} ]; then
- TTY=vc/${TTY}
- else
- echo "Cannot find your TTY (${TTY})" >&2
- exit 1
- fi
- ASTARGS="${ASTARGS} -vvvg"
- if [ "$CONSOLE" != "no" ]; then
- ASTARGS="${ASTARGS} -c"
- fi
-fi
-if [ ! -w ${DUMPDROP} ]; then
- echo "Cannot write to ${DUMPDROP}" >&2
- exit 1
-fi
-
-#
-# Don't die if stdout/stderr can't be written to
-#
-trap '' PIPE
-
-#
-# Run scripts to set any environment variables or do any other system-specific setup needed
-#
-
-if [ -d /etc/asterisk/startup.d ]; then
- for script in /etc/asterisk/startup.d/*.sh; do
- if [ -x ${script} ]; then
- source ${script}
- fi
- done
-fi
-
-run_asterisk()
-{
- while :; do
-
- if [ "$TTY" != "" ]; then
- cd /tmp
- stty sane < /dev/${TTY}
- nice -n $PRIORITY ${ASTSBINDIR}/asterisk -f ${CLIARGS} ${ASTARGS} >& /dev/${TTY} < /dev/${TTY}
- else
- cd /tmp
- nice -n $PRIORITY ${ASTSBINDIR}/asterisk -f ${CLIARGS} ${ASTARGS}
- fi
- EXITSTATUS=$?
- echo "Asterisk ended with exit status $EXITSTATUS"
- if [ "$EXITSTATUS" = "0" ]; then
- # Properly shutdown....
- echo "Asterisk shutdown normally."
- exit 0
- elif [ $EXITSTATUS -gt 128 ]; then
- let EXITSIGNAL=EXITSTATUS-128
- echo "Asterisk exited on signal $EXITSIGNAL."
- if [ "$NOTIFY" != "" ]; then
- echo "Asterisk on $MACHINE exited on signal $EXITSIGNAL. Might want to take a peek." | \
- mail -s "Asterisk Died" $NOTIFY
- fi
- if [ "$EXEC" != "" ]; then
- $EXEC
- fi
-
- PID=`cat ${ASTPIDFILE}`
- if [ -f /tmp/core.${PID} ]; then
- mv /tmp/core.${PID} ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
- elif [ -f /tmp/core ]; then
- mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
- fi
- else
- echo "Asterisk died with code $EXITSTATUS."
-
- PID=`cat ${ASTPIDFILE}`
- if [ -f /tmp/core.${PID} ]; then
- mv /tmp/core.${PID} ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
- elif [ -f /tmp/core ]; then
- mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
- fi
- fi
- echo "Automatically restarting Asterisk."
- sleep $SLEEPSECS
- if [ $KILLALLMPG123 ]
- then
- killall -9 mpg123
- fi
- done
-}
-
-run_asterisk &
diff --git a/1.4/contrib/scripts/safe_asterisk.8 b/1.4/contrib/scripts/safe_asterisk.8
deleted file mode 100644
index ebd95142a..000000000
--- a/1.4/contrib/scripts/safe_asterisk.8
+++ /dev/null
@@ -1,69 +0,0 @@
-.TH SAFE_ASTERISK 8 "Jun 30th, 2005" "Asterisk" "Linux Programmer's Manual"
-.SH NAME
-.B safe_asterisk
-\(em A wrapper to run the asterisk executable in a loop
-.SH SYNOPSIS
-.PP
-.B safe_asterisk
-.I [ asterisk_params ]
-
-.SH DESCRIPTION
-.B safe_asterisk
-is a script that runs asterisk in a loop, which can be useful if you
-fear asterisk may crash.
-
-The script does not run in the background like a standard service. Rather,
-it runs in its own linux virtual console (9, by default).
-It also uses the option '-c' of asterisk(8) to avoid detaching asterisk
-from that terminal.
-
-safe_asterisk also runs asterisk with unlimited core file size, and thus
-asterisk will dump core in case of a crash.
-
-To get a "picture" of console 9, from another terminal (e.g: from a
-remote shell session) you can use:
-
- screendump 9
-
-The init script of the Debian package should be able to run safe_asterisk
-as the asterisk service, if so configured. See coments in
-/etc/default/asterisk
-
-.SH FILES
-.B /tmp
-.RS
-safe_asterisk runs in that directory, rather than in / as usual.
-.RE
-
-.B /tmp/core
-.RS
-If core files were generated there, they may be
-.RE
-
-.B /etc/asterisk/startup.d
-.RS
-Files in this directory will be 'source'd by the safe_asterisk script before
-it starts Asterisk proper, allowing them to set additional environment variables
-or run any other steps that are needed for your system.
-.RE
-
-.SH BUGS
-While showing the output on a console is useful, using screen(1) as
-the terminal may be better.
-
-The script does not read configuration from standard location under /etc
-
-It uses fixed locations under /tmp , and thus may be exposed to a
-symlink attacks.
-
-.SH SEE ALSO
-asterisk(8), screendump(9)
-
-.SH "AUTHOR"
-This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
-Permission is granted to copy, distribute and/or modify this document under
-the terms of the GNU General Public License, Version 2 any
-later version published by the Free Software Foundation.
-
-On Debian systems, the complete text of the GNU General Public
-License can be found in /usr/share/common-licenses/GPL.
diff --git a/1.4/contrib/scripts/safe_asterisk_restart b/1.4/contrib/scripts/safe_asterisk_restart
deleted file mode 100644
index 81783149a..000000000
--- a/1.4/contrib/scripts/safe_asterisk_restart
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/bash
-# vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent
-#
-# this scripts prompts the user thrice, then tells asterisk to please shut down,
-# then kills asterisk and related processes with SIGTERM, then kills asterisk
-# and related processes with SIGKILL, and then starts asterisk with
-# safe_asterisk. Three arguments are currently supported, --no-countdown,
-# --no-prompt and --no-stop-now-first
-
-LOGFILE=/var/log/asterisk/safe_asterisk_restart.log
-ASTERISK=/usr/sbin/asterisk
-SAFE_ASTERISK=/usr/sbin/safe_asterisk
-
-DELAY=1 # Seconds between steps in countdown
-COUNTDOWN_FROM=5 # Steps to count down
-DO_COUNTDOWN=1 # Should I do a countdown before restarting asterisk?
-DO_PROMPT=1 # Should I prompt the user?
-TRY_STOP_NOW_FIRST=1 # Attempt a 'stop now' before killing processes. Note
- # that this might make this script hang if asterisk
- # can't respond to the command.
-
-# processes to kill. Please list all AGI scripts here as well as the asterisk
-# processes, since asterisk may leave them unkilled.
-PROCVICTIMS="safe_asterisk asterisk mpg123"
-
-# helper functions
-# die ["string to print"]
-function die {
- if [[ "$1" != "" ]]; then
- echo $1
- else
- echo "ok. no harm done..."
- fi
- exit
-}
-
-# docmd "string to print" "cmd"
-function docmd {
- printf "$1..."
- `$2 >> $LOGFILE 2>&1`
- RETCODE=$?
- sleep $DELAY
- if [[ "$RETCODE" == "0" ]]; then
- echo " OK"
- else
- echo " FAILED"
- fi
-}
-
-# prompt "string" "positive answer"
-function prompt {
- printf "$1"
- read answer
- if [[ "$answer" != "$2" ]]; then
- die
- fi
-}
-
-# countdown secs
-function countdown {
- echo -n "$1 "
- if [[ $1 > 0 ]]; then
- sleep 1
- countdown $[ $1 - 1 ]
- else
- echo "boom!"
- fi
-}
-
-# am I really root?
-if [[ "$UID" != "0" ]]; then
- echo "Sorry, only root can do this." >&2
- exit;
-fi
-
-echo "`date`: $0 invoked" >> $LOGFILE
-
-# bash
-for i
-do
- if [[ "$i" == "--no-countdown" ]]
- then
- unset DO_COUNTDOWN
- fi
- if [[ "$i" == "--no-prompt" ]]
- then
- unset DO_PROMPT
- fi
- if [[ "$i" == "--no-stop-now-first" ]]
- then
- unset TRY_STOP_NOW_FIRST
- fi
-done
-
-[[ $DO_PROMPT ]] && prompt "Are you sure you want to restart asterisk? (yes/no)? " "yes"
-[[ $DO_PROMPT ]] && prompt "Really sure? (yes/no)? " "yes"
-[[ $DO_PROMPT ]] && prompt "Absolutely positive? (YES/no)? " "YES"
-
-[[ $DO_COUNTDOWN ]] && echo "OK, I'll do it, but if you're not sure about this, press ctrl+c now."
-[[ $DO_COUNTDOWN ]] && countdown $COUNTDOWN_FROM
-
-# doing the dirty work
-[[ $TRY_STOP_NOW_FIRST ]] && docmd "Asking asterisk kindly to shutdown" "$ASTERISK -rx 'stop now'"
-docmd "Sending asterisk processes the TERM signal" "killall -15 $PROCVICTIMS"
-docmd "Sending asterisk processes KILL signal" "killall -9 $PROCVICTIMS"
-docmd "Starting safe_asterisk" "$SAFE_ASTERISK"
-for i in $PROCVICTIMS
-do
- ps axf | grep -w $i | grep -v grep
-done
diff --git a/1.4/contrib/scripts/sip-friends.sql b/1.4/contrib/scripts/sip-friends.sql
deleted file mode 100644
index d76db7f93..000000000
--- a/1.4/contrib/scripts/sip-friends.sql
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Table structure for table `sipfriends`
-#
-
-CREATE TABLE `sipfriends` (
- `name` varchar(40) NOT NULL default '',
- `type` varchar(10) NOT NULL default '',
- `username` varchar(40),
- `fromuser` varchar(40),
- `fromdomain` varchar(40),
- `secret` varchar(40),
- `md5secret` varchar(40),
- `auth` varchar(10),
- `mailbox` varchar(20),
- `subscribemwi` varchar(10), -- yes/no
- `vmexten` varchar(20),
- `callerid` varchar(40),
- `cid_number` varchar(40),
- `callingpres` varchar(20),
- `usereqphone` varchar(10),
- `language` varchar(10),
- `incominglimit` varchar(10),
- `context` varchar(40) NOT NULL default '',
- `subscribecontext` varchar(40),
- `amaflags` varchar(20),
- `accountcode` varchar(20),
- `musicclass` varchar(20),
- `mohsuggest` varchar(20),
- `allowtransfer` varchar(20),
- `callgroup` varchar(20),
- `pickupgroup` varchar(20),
- `autoframing` varchar(10), -- yes/no
- `disallow` varchar(20) default 'all',
- `allow` varchar(20),
- `maxcallbitrate` varchar(15),
- `host` varchar(40) default 'dynamic',
- `outboundproxy` varchar(40),
- `ipaddr` varchar(20) NOT NULL default '',
- `defaultip` varchar(20),
- `port` int(6) NOT NULL default '0',
- `fullcontact` varchar(40),
- `insecure` varchar(20),
- `qualify` varchar(15),
- `regseconds` int(11) NOT NULL default '0',
- `regexten` varchar(20),
- `regserver` varchar(20),
- `rtptimeout` varchar(15),
- `rtpholdtimeout` varchar(15),
- `rtpkeepalive` varchar(15),
- `setvar` varchar(200),
- PRIMARY KEY (`name`),
- INDEX host (host, port),
- INDEX ipaddr (ipaddr, port),
-) TYPE=MyISAM;
diff --git a/1.4/contrib/scripts/vmail.cgi b/1.4/contrib/scripts/vmail.cgi
deleted file mode 100644
index 95bb9bb77..000000000
--- a/1.4/contrib/scripts/vmail.cgi
+++ /dev/null
@@ -1,1107 +0,0 @@
-#!/usr/bin/perl
-#
-# Web based Voicemail for Asterisk
-#
-# Copyright (C) 2002, Linux Support Services, Inc.
-#
-# Distributed under the terms of the GNU General Public License
-#
-# Written by Mark Spencer <markster@linux-support.net>
-#
-# (icky, I know.... if you know better perl please help!)
-#
-#
-# Synchronization added by GDS Partners (www.gdspartners.com)
-# Stojan Sljivic (stojan.sljivic@gdspartners.com)
-#
-use CGI qw/:standard/;
-use Carp::Heavy;
-use CGI::Carp qw(fatalsToBrowser);
-use DBI;
-use Fcntl qw ( O_WRONLY O_CREAT O_EXCL );
-use Time::HiRes qw ( usleep );
-
-$context=""; # Define here your by default context (so you dont need to put voicemail@context in the login)
-
-@validfolders = ( "INBOX", "Old", "Work", "Family", "Friends", "Cust1", "Cust2", "Cust3", "Cust4", "Cust5" );
-
-%formats = (
- "wav" => {
- name => "Uncompressed WAV",
- mime => "audio/x-wav",
- pref => 1
- },
- "WAV" => {
- name => "GSM Compressed WAV",
- mime => "audio/x-wav",
- pref => 2
- },
- "gsm" => {
- name => "Raw GSM Audio",
- mime => "audio/x-gsm",
- pref => 3
- }
-);
-
-$astpath = "/_asterisk";
-
-$stdcontainerstart = "<table align=center width=600><tr><td>\n";
-$footer = "<hr><font size=-1><a href=\"http://www.asterisk.org\">The Asterisk Open Source PBX</a> Copyright 2004-2008, <a href=\"http://www.digium.com\">Digium, Inc.</a></a>";
-$stdcontainerend = "</td></tr><tr><td align=right>$footer</td></tr></table>\n";
-
-sub lock_path($) {
-
- my($path) = @_;
- my $rand;
- my $rfile;
- my $start;
- my $res;
-
- $rand = rand 99999999;
- $rfile = "$path/.lock-$rand";
-
- sysopen(RFILE, $rfile, O_WRONLY | O_CREAT | O_EXCL, 0666) or return -1;
- close(RFILE);
-
- $res = link($rfile, "$path/.lock");
- $start = time;
- if ($res == 0) {
- while (($res == 0) && (time - $start <= 5)) {
- $res = link($rfile, "$path/.lock");
- usleep(1);
- }
- }
- unlink($rfile);
-
- if ($res == 0) {
- return -1;
- } else {
- return 0;
- }
-}
-
-sub unlock_path($) {
-
- my($path) = @_;
-
- unlink("$path/.lock");
-}
-
-sub untaint($) {
-
- my($data) = @_;
-
- if ($data =~ /^([-\@\w.]+)$/) {
- $data = $1;
- } else {
- die "Security violation.";
- }
-
- return $data;
-}
-
-sub login_screen($) {
- print header;
- my ($message) = @_;
- print <<_EOH;
-
-<TITLE>Asterisk Web-Voicemail</TITLE>
-<BODY BGCOLOR="white">
-$stdcontainerstart
-<FORM METHOD="post">
-<input type=hidden name="action" value="login">
-<table align=center>
-<tr><td valign=top align=center rowspan=6><img align=center src="$astpath/animlogo.gif"></td></tr>
-<tr><td align=center colspan=2><font size=+2>Comedian Mail Login</font></td></tr>
-<tr><td align=center colspan=2><font size=+1>$message</font></td></tr>
-<tr><td>Mailbox:</td><td><input type=text name="mailbox"></td></tr>
-<tr><td>Password:</td><td><input type=password name="password"></td></tr>
-<tr><td align=right colspan=2><input value="Login" type=submit></td></tr>
-<input type=hidden name="context" value="$context">
-</table>
-</FORM>
-$stdcontainerend
-</BODY>\n
-_EOH
-
-}
-
-sub check_login($$)
-{
- local ($filename, $startcat) = @_;
- local ($mbox, $context) = split(/\@/, param('mailbox'));
- local $pass = param('password');
- local $category = $startcat;
- local @fields;
- local $tmp;
- local (*VMAIL);
- if (!$category) {
- $category = "general";
- }
- if (!$context) {
- $context = param('context');
- }
- if (!$context) {
- $context = "default";
- }
- if (!$filename) {
- $filename = "/etc/asterisk/voicemail.conf";
- }
-# print header;
-# print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n";
- open(VMAIL, "<$filename") || die("Bleh, no $filename");
- while(<VMAIL>) {
- chomp;
- if (/include\s\"([^\"]+)\"$/) {
- ($tmp, $category) = &check_login("/etc/asterisk/$1", $category);
- if (length($tmp)) {
-# print "Got '$tmp'\n";
- return ($tmp, $category);
- }
- } elsif (/\[(.*)\]/) {
- $category = $1;
- } elsif ($category eq "general") {
- if (/([^\s]+)\s*\=\s*(.*)/) {
- if ($1 eq "dbname") {
- $dbname = $2;
- } elsif ($1 eq "dbpass") {
- $dbpass = $2;
- } elsif ($1 eq "dbhost") {
- $dbhost = $2;
- } elsif ($1 eq "dbuser") {
- $dbuser = $2;
- }
- }
- if ($dbname and $dbpass and $dbhost and $dbuser) {
-
- # db variables are present. Use db for authentication.
- my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
- my $sth = $dbh->prepare(qq{select fullname,context from voicemail where mailbox='$mbox' and password='$pass' and context='$context'});
- $sth->execute();
- if (($fullname, $category) = $sth->fetchrow_array()) {
- return ($fullname ? $fullname : "Extension $mbox in $context",$category);
- }
- }
- } elsif (($category ne "general") && ($category ne "zonemessages")) {
- if (/([^\s]+)\s*\=\>?\s*(.*)/) {
- @fields = split(/\,\s*/, $2);
-# print "<p>Mailbox is $1\n";
- if (($mbox eq $1) && (($pass eq $fields[0]) || ("-${pass}" eq $fields[0])) && ($context eq $category)) {
- return ($fields[1] ? $fields[1] : "Extension $mbox in $context", $category);
- }
- }
- }
- }
- close(VMAIL);
- return ("", $category);
-}
-
-sub validmailbox($$$$)
-{
- local ($context, $mbox, $filename, $startcat) = @_;
- local $category = $startcat;
- local @fields;
- local (*VMAIL);
- if (!$context) {
- $context = param('context');
- }
- if (!$context) {
- $context = "default";
- }
- if (!$filename) {
- $filename = "/etc/asterisk/voicemail.conf";
- }
- if (!$category) {
- $category = "general";
- }
- open(VMAIL, "<$filename") || die("Bleh, no $filename");
- while (<VMAIL>) {
- chomp;
- if (/include\s\"([^\"]+)\"$/) {
- ($tmp, $category) = &validmailbox($mbox, $context, "/etc/asterisk/$1");
- if ($tmp) {
- return ($tmp, $category);
- }
- } elsif (/\[(.*)\]/) {
- $category = $1;
- } elsif ($category eq "general") {
- if (/([^\s]+)\s*\=\s*(.*)/) {
- if ($1 eq "dbname") {
- $dbname = $2;
- } elsif ($1 eq "dbpass") {
- $dbpass = $2;
- } elsif ($1 eq "dbhost") {
- $dbhost = $2;
- } elsif ($1 eq "dbuser") {
- $dbuser = $2;
- }
- }
- if ($dbname and $dbpass and $dbhost and $dbuser) {
-
- # db variables are present. Use db for authentication.
- my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
- my $sth = $dbh->prepare(qq{select fullname,context from voicemail where mailbox='$mbox' and password='$pass' and context='$context'});
- $sth->execute();
- if (($fullname, $context) = $sth->fetchrow_array()) {
- return ($fullname ? $fullname : "unknown", $category);
- }
- }
- } elsif (($category ne "general") && ($category ne "zonemessages") && ($category eq $context)) {
- if (/([^\s]+)\s*\=\>?\s*(.*)/) {
- @fields = split(/\,\s*/, $2);
- if (($mbox eq $1) && ($context eq $category)) {
- return ($fields[2] ? $fields[2] : "unknown", $category);
- }
- }
- }
- }
- return ("", $category);
-}
-
-sub mailbox_options()
-{
- local($context, $current, $filename, $category) = @_;
- local (*VMAIL);
- local $tmp2;
- local $tmp;
- if (!$filename) {
- $filename = "/etc/asterisk/voicemail.conf";
- }
- if (!$category) {
- $category = "general";
- }
-# print header;
-# print "Including <h2>$filename</h2> while in <h2>$category</h2>...\n";
- open(VMAIL, "<$filename") || die("Bleh, no voicemail.conf");
- while(<VMAIL>) {
- chomp;
- s/\;.*$//;
- if (/include\s\"([^\"]+)\"$/) {
- ($tmp2, $category) = &mailbox_options($context, $current, "/etc/asterisk/$1", $category);
-# print "Got '$tmp2'...\n";
- $tmp .= $tmp2;
- } elsif (/\[(.*)\]/) {
- $category = $1;
- } elsif ($category eq "general") {
- if (/([^\s]+)\s*\=\s*(.*)/) {
- if ($1 eq "dbname") {
- $dbname = $2;
- } elsif ($1 eq "dbpass") {
- $dbpass = $2;
- } elsif ($1 eq "dbhost") {
- $dbhost = $2;
- } elsif ($1 eq "dbuser") {
- $dbuser = $2;
- }
- }
- if ($dbname and $dbpass and $dbhost and $dbuser) {
-
- # db variables are present. Use db for authentication.
- my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost",$dbuser,$dbpass);
- my $sth = $dbh->prepare(qq{select mailbox,fullname,context from voicemail where context='$context' order by mailbox});
- $sth->execute();
- while (($mailbox, $fullname, $category) = $sth->fetchrow_array()) {
- $text = $mailbox;
- if ($fullname) {
- $text .= " (".$fullname.")";
- }
- if ($mailbox eq $current) {
- $tmp .= "<OPTION SELECTED>$text</OPTION>\n";
- } else {
- $tmp .= "<OPTION>$text</OPTION>\n";
- }
- }
- return ($tmp, $category);
- }
- } elsif (($category ne "general") && ($category ne "zonemessages")) {
- if (/([^\s]+)\s*\=\>?\s*(.*)/) {
- @fields = split(/\,\s*/, $2);
- $text = "$1";
- if ($fields[1]) {
- $text .= " ($fields[1])";
- }
- if ($1 eq $current) {
- $tmp .= "<OPTION SELECTED>$text</OPTION>\n";
- } else {
- $tmp .= "<OPTION>$text</OPTION>\n";
- }
-
- }
- }
- }
- close(VMAIL);
- return ($tmp, $category);
-}
-
-sub mailbox_list()
-{
- local ($name, $context, $current) = @_;
- local $tmp;
- local $text;
- local $tmp;
- local $opts;
- if (!$context) {
- $context = "default";
- }
- $tmp = "<SELECT name=\"$name\">\n";
- ($opts) = &mailbox_options($context, $current);
- $tmp .= $opts;
- $tmp .= "</SELECT>\n";
-
-}
-
-sub msgcount()
-{
- my ($context, $mailbox, $folder) = @_;
- my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder";
- if (opendir(DIR, $path)) {
- my @msgs = grep(/^msg....\.txt$/, readdir(DIR));
- closedir(DIR);
- return sprintf "%d", $#msgs + 1;
- }
- return "0";
-}
-
-sub msgcountstr()
-{
- my ($context, $mailbox, $folder) = @_;
- my $count = &msgcount($context, $mailbox, $folder);
- if ($count > 1) {
- "$count messages";
- } elsif ($count > 0) {
- "$count message";
- } else {
- "no messages";
- }
-}
-sub messages()
-{
- my ($context, $mailbox, $folder) = @_;
- my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder";
- if (opendir(DIR, $path)) {
- my @msgs = sort grep(/^msg....\.txt$/, readdir(DIR));
- closedir(DIR);
- return map { s/^msg(....)\.txt$/$1/; $_ } @msgs;
- }
- return ();
-}
-
-sub getcookie()
-{
- my ($var) = @_;
- return cookie($var);
-}
-
-sub makecookie()
-{
- my ($format) = @_;
- cookie(-name => "format", -value =>["$format"], -expires=>"+1y");
-}
-
-sub getfields()
-{
- my ($context, $mailbox, $folder, $msg) = @_;
- my $fields;
- if (open(MSG, "</var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msg}.txt")) {
- while(<MSG>) {
- s/\#.*$//g;
- if (/^(\w+)\s*\=\s*(.*)$/) {
- $fields->{$1} = $2;
- }
- }
- close(MSG);
- $fields->{'msgid'} = $msg;
- } else { print "<BR>Unable to open '$msg' in '$mailbox', '$folder'\n<B>"; }
- $fields;
-}
-
-sub message_prefs()
-{
- my ($nextaction, $msgid) = @_;
- my $folder = param('folder');
- my $mbox = param('mailbox');
- my $context = param('context');
- my $passwd = param('password');
- my $format = param('format');
- if (!$format) {
- $format = &getcookie('format');
- }
- print header;
- print <<_EOH;
-
-<TITLE>Asterisk Web-Voicemail: Preferences</TITLE>
-<BODY BGCOLOR="white">
-$stdcontainerstart
-<FORM METHOD="post">
-<table width=100% align=center>
-<tr><td align=right colspan=3><font size=+2>Web Voicemail Preferences</font></td></tr>
-<tr><td align=left><font size=+1>Preferred&nbsp;Audio&nbsp;Format:</font></td><td colspan=2></td></tr>
-_EOH
-
-foreach $fmt (sort { $formats{$a}->{'pref'} <=> $formats{$b}->{'pref'} } keys %formats) {
- my $clicked = "checked" if $fmt eq $format;
- print "<tr><td></td><td align=left><input type=radio name=\"format\" $clicked value=\"$fmt\"></td><td width=100%>&nbsp;$formats{$fmt}->{name}</td></tr>\n";
-}
-
-print <<_EOH;
-<tr><td align=right colspan=3><input type=submit value="save settings..."></td></tr>
-</table>
-<input type=hidden name="action" value="$nextaction">
-<input type=hidden name="folder" value="$folder">
-<input type=hidden name="mailbox" value="$mbox">
-<input type=hidden name="context" value="$context">
-<input type=hidden name="password" value="$passwd">
-<input type=hidden name="msgid" value="$msgid">
-$stdcontainerend
-</BODY>\n
-_EOH
-
-}
-
-sub message_play()
-{
- my ($message, $msgid) = @_;
- my $folder = param('folder');
- my ($mbox, $context) = split(/\@/, param('mailbox'));
- my $passwd = param('password');
- my $format = param('format');
-
- my $fields;
- if (!$context) {
- $context = param('context');
- }
- if (!$context) {
- $context = "default";
- }
-
- my $folders = &folder_list('newfolder', $context, $mbox, $folder);
- my $mailboxes = &mailbox_list('forwardto', $context, $mbox);
- if (!$format) {
- $format = &getcookie('format');
- }
- if (!$format) {
- &message_prefs("play", $msgid);
- } else {
- print header(-cookie => &makecookie($format));
- $fields = &getfields($context, $mbox, $folder, $msgid);
- if (!$fields) {
- print "<BR>Bah!\n";
- return;
- }
- my $duration = $fields->{'duration'};
- if ($duration) {
- $duration = sprintf "%d:%02d", $duration/60, $duration % 60;
- } else {
- $duration = "<i>Unknown</i>";
- }
- print <<_EOH;
-
-<TITLE>Asterisk Web-Voicemail: $folder Message $msgid</TITLE>
-<BODY BGCOLOR="white">
-$stdcontainerstart
-<FORM METHOD="post">
-<table width=100% align=center>
-<tr><td align=right colspan=3><font size=+1>$folder Message $msgid</font></td></tr>
-_EOH
-
- print <<_EOH;
-<tr><td align=center colspan=3>
-<table>
- <tr><td colspan=2 align=center><font size=+1>$folder <b>$msgid</b></font></td></tr>
- <tr><td><b>Message:</b></td><td>$msgid</td></tr>\n
- <tr><td><b>Mailbox:</b></td><td>$mbox\@$context</td></tr>\n
- <tr><td><b>Folder:</b></td><td>$folder</td></tr>\n
- <tr><td><b>From:</b></td><td>$fields->{callerid}</td></tr>\n
- <tr><td><b>Duration:</b></td><td>$duration</td></tr>\n
- <tr><td><b>Original Date:</b></td><td>$fields->{origdate}</td></tr>\n
- <tr><td><b>Original Mailbox:</b></td><td>$fields->{origmailbox}</td></tr>\n
- <tr><td><b>Caller Channel:</b></td><td>$fields->{callerchan}</td></tr>\n
- <tr><td align=center colspan=2>
- <input name="action" type=submit value="index">&nbsp;
- <input name="action" type=submit value="delete ">&nbsp;
- <input name="action" type=submit value="forward to -> ">&nbsp;
- $mailboxes&nbsp;
- <input name="action" type=submit value="save to ->">
- $folders&nbsp;
- <input name="action" type=submit value="play ">
- <input name="action" type=submit value="download">
-</td></tr>
-<tr><td colspan=2 align=center>
-<embed width=400 height=40 src="vmail.cgi?action=audio&folder=$folder&mailbox=$mbox&context=$context&password=$passwd&msgid=$msgid&format=$format&dontcasheme=$$.$format" autostart=yes loop=false></embed>
-</td></tr></table>
-</td></tr>
-</table>
-<input type=hidden name="folder" value="$folder">
-<input type=hidden name="mailbox" value="$mbox">
-<input type=hidden name="context" value="$context">
-<input type=hidden name="password" value="$passwd">
-<input type=hidden name="msgid" value="$msgid">
-$stdcontainerend
-</BODY>\n
-_EOH
- }
-}
-
-sub message_audio()
-{
- my ($forcedownload) = @_;
- my $folder = &untaint(param('folder'));
- my $msgid = &untaint(param('msgid'));
- my $mailbox = &untaint(param('mailbox'));
- my $context = &untaint(param('context'));
- my $format = param('format');
- if (!$format) {
- $format = &getcookie('format');
- }
- &untaint($format);
-
- my $path = "/var/spool/asterisk/voicemail/$context/$mailbox/$folder/msg${msgid}.$format";
-
- $msgid =~ /^\d\d\d\d$/ || die("Msgid Liar ($msgid)!");
- grep(/^${format}$/, keys %formats) || die("Format Liar ($format)!");
-
- # Mailbox and folder are already verified
- if (open(AUDIO, "<$path")) {
- $size = -s $path;
- $|=1;
- if ($forcedownload) {
- print header(-type=>$formats{$format}->{'mime'}, -Content_length => $size, -attachment => "msg${msgid}.$format");
- } else {
- print header(-type=>$formats{$format}->{'mime'}, -Content_length => $size);
- }
-
- while(($amt = sysread(AUDIO, $data, 4096)) > 0) {
- syswrite(STDOUT, $data, $amt);
- }
- close(AUDIO);
- } else {
- die("Hrm, can't seem to open $path\n");
- }
-}
-
-sub message_index()
-{
- my ($folder, $message) = @_;
- my ($mbox, $context) = split(/\@/, param('mailbox'));
- my $passwd = param('password');
- my $message2;
- my $msgcount;
- my $hasmsg;
- my ($newmessages, $oldmessages);
- my $format = param('format');
- if (!$format) {
- $format = &getcookie('format');
- }
- if (!$context) {
- $context = param('context');
- }
- if (!$context) {
- $context = "default";
- }
- if ($folder) {
- $msgcount = &msgcountstr($context, $mbox, $folder);
- $message2 = "&nbsp;&nbsp;&nbsp;Folder '$folder' has " . &msgcountstr($context, $mbox, $folder);
- } else {
- $newmessages = &msgcount($context, $mbox, "INBOX");
- $oldmessages = &msgcount($context, $mbox, "Old");
- if (($newmessages > 0) || ($oldmessages < 1)) {
- $folder = "INBOX";
- } else {
- $folder = "Old";
- }
- $message2 = "You have";
- if ($newmessages > 0) {
- $message2 .= " <b>$newmessages</b> NEW";
- if ($oldmessages > 0) {
- $message2 .= "and <b>$oldmessages</b> OLD";
- if ($oldmessages != 1) {
- $message2 .= " messages.";
- } else {
- $message2 .= "message.";
- }
- } else {
- if ($newmessages != 1) {
- $message2 .= " messages.";
- } else {
- $message2 .= " message.";
- }
- }
- } else {
- if ($oldmessages > 0) {
- $message2 .= " <b>$oldmessages</b> OLD";
- if ($oldmessages != 1) {
- $message2 .= " messages.";
- } else {
- $message2 .= " message.";
- }
- } else {
- $message2 .= " <b>no</b> messages.";
- }
- }
- }
-
- my $folders = &folder_list('newfolder', $context, $mbox, $folder);
- my $cfolders = &folder_list('changefolder', $context, $mbox, $folder);
- my $mailboxes = &mailbox_list('forwardto', $context, $mbox);
- print header(-cookie => &makecookie($format));
- print <<_EOH;
-
-<TITLE>Asterisk Web-Voicemail: $mbox\@$context $folder</TITLE>
-<BODY BGCOLOR="white">
-$stdcontainerstart
-<FORM METHOD="post">
-<table width=100% align=center>
-<tr><td align=center colspan=2><font size=+2><I>$message</I></font></td></tr>
-<tr><td align=right colspan=2><font size=+1><b>$folder</b> Messages</font> <input type=submit name="action" value="change to ->">$cfolders</td></tr>
-<tr><td align=left colspan=2><font size=+1>$message2</font></td></tr>
-</table>
-<table width=100% align=center cellpadding=0 cellspacing=0>
-_EOH
-
-print "<tr><td>&nbsp;Msg</td><td>&nbsp;From</td><td>&nbsp;Duration</td><td>&nbsp;Date</td><td>&nbsp;</td></tr>\n";
-print "<tr><td><hr></td><td><hr></td><td><hr></td><td><hr></td><td></td></tr>\n";
-foreach $msg (&messages($context, $mbox, $folder)) {
-
- $fields = &getfields($context, $mbox, $folder, $msg);
- $duration = $fields->{'duration'};
- if ($duration) {
- $duration = sprintf "%d:%02d", $duration / 60, $duration % 60;
- } else {
- $duration = "<i>Unknown</i>";
- }
- $hasmsg++;
- print "<tr><td><input type=checkbox name=\"msgselect\" value=\"$msg\">&nbsp;<b>$msg</b></td><td>$fields->{'callerid'}</td><td>$duration</td><td>$fields->{'origdate'}</td><td><input name='play$msg' alt=\"Play message $msg\" border=0 type=image align=left src=\"$astpath/play.gif\"></td></tr>\n";
-
-}
-if (!$hasmsg) {
- print "<tr><td colspan=4 align=center><P><b><i>No messages</i></b><P></td></tr>";
-}
-
-print <<_EOH;
-</table>
-<table width=100% align=center>
-<tr><td align=right colspan=2>
- <input type="submit" name="action" value="refresh">&nbsp;
-_EOH
-
-if ($hasmsg) {
-print <<_EOH;
- <input type="submit" name="action" value="delete">&nbsp;
- <input type="submit" name="action" value="save to ->">
- $folders&nbsp;
- <input type="submit" name="action" value="forward to ->">
- $mailboxes
-_EOH
-}
-
-print <<_EOH;
-</td></tr>
-<tr><td align=right colspan=2>
- <input type="submit" name="action" value="preferences">
- <input type="submit" name="action" value="logout">
-</td></tr>
-</table>
-<input type=hidden name="folder" value="$folder">
-<input type=hidden name="mailbox" value="$mbox">
-<input type=hidden name="context" value="$context">
-<input type=hidden name="password" value="$passwd">
-</FORM>
-$stdcontainerend
-</BODY>\n
-_EOH
-}
-
-sub validfolder()
-{
- my ($folder) = @_;
- return grep(/^$folder$/, @validfolders);
-}
-
-sub folder_list()
-{
- my ($name, $context, $mbox, $selected) = @_;
- my $f;
- my $count;
- my $tmp = "<SELECT name=\"$name\">\n";
- foreach $f (@validfolders) {
- $count = &msgcount($context, $mbox, $f);
- if ($f eq $selected) {
- $tmp .= "<OPTION SELECTED>$f ($count)</OPTION>\n";
- } else {
- $tmp .= "<OPTION>$f ($count)</OPTION>\n";
- }
- }
- $tmp .= "</SELECT>";
-}
-
-sub message_rename()
-{
- my ($context, $mbox, $oldfolder, $old, $newfolder, $new) = @_;
- my ($oldfile, $newfile);
- return if ($old eq $new) && ($oldfolder eq $newfolder);
-
- if ($context =~ /^(\w+)$/) {
- $context = $1;
- } else {
- die("Invalid Context<BR>\n");
- }
-
- if ($mbox =~ /^(\w+)$/) {
- $mbox = $1;
- } else {
- die ("Invalid mailbox<BR>\n");
- }
-
- if ($oldfolder =~ /^(\w+)$/) {
- $oldfolder = $1;
- } else {
- die("Invalid old folder<BR>\n");
- }
-
- if ($newfolder =~ /^(\w+)$/) {
- $newfolder = $1;
- } else {
- die("Invalid new folder ($newfolder)<BR>\n");
- }
-
- if ($old =~ /^(\d\d\d\d)$/) {
- $old = $1;
- } else {
- die("Invalid old Message<BR>\n");
- }
-
- if ($new =~ /^(\d\d\d\d)$/) {
- $new = $1;
- } else {
- die("Invalid old Message<BR>\n");
- }
-
- my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$newfolder";
- $path =~ /^(.*)$/;
- $path = $1;
- mkdir $path, 0770;
- $path = "/var/spool/asterisk/voicemail/$context/$mbox/$oldfolder";
- opendir(DIR, $path) || die("Unable to open directory\n");
- my @files = grep /^msg${old}\.\w+$/, readdir(DIR);
- closedir(DIR);
- foreach $oldfile (@files) {
- my $tmp = $oldfile;
- if ($tmp =~ /^(msg${old}.\w+)$/) {
- $tmp = $1;
- $oldfile = $path . "/$tmp";
- $tmp =~ s/msg${old}/msg${new}/;
- $newfile = "/var/spool/asterisk/voicemail/$context/$mbox/$newfolder/$tmp";
-# print "Renaming $oldfile to $newfile<BR>\n";
- rename($oldfile, $newfile);
- }
- }
-}
-
-sub file_copy()
-{
- my ($orig, $new) = @_;
- my $res;
- my $data;
- $orig =~ /^(.*)$/;
- $orig = $1;
- $new =~ /^(.*)$/;
- $new = $1;
- open(IN, "<$orig") || die("Unable to open '$orig'\n");
- open(OUT, ">$new") || DIE("Unable to open '$new'\n");
- while(($res = sysread(IN, $data, 4096)) > 0) {
- syswrite(OUT, $data, $res);
- }
- close(OUT);
- close(IN);
-}
-
-sub message_copy()
-{
- my ($context, $mbox, $newmbox, $oldfolder, $old, $new) = @_;
- my ($oldfile, $newfile);
- return if ($mbox eq $newmbox);
-
- if ($mbox =~ /^(\w+)$/) {
- $mbox = $1;
- } else {
- die ("Invalid mailbox<BR>\n");
- }
-
- if ($newmbox =~ /^(\w+)$/) {
- $newmbox = $1;
- } else {
- die ("Invalid new mailbox<BR>\n");
- }
-
- if ($oldfolder =~ /^(\w+)$/) {
- $oldfolder = $1;
- } else {
- die("Invalid old folder<BR>\n");
- }
-
- if ($old =~ /^(\d\d\d\d)$/) {
- $old = $1;
- } else {
- die("Invalid old Message<BR>\n");
- }
-
- if ($new =~ /^(\d\d\d\d)$/) {
- $new = $1;
- } else {
- die("Invalid old Message<BR>\n");
- }
-
- my $path = "/var/spool/asterisk/voicemail/$context/$newmbox";
- $path =~ /^(.*)$/;
- $path = $1;
- mkdir $path, 0770;
- $path = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX";
- $path =~ /^(.*)$/;
- $path = $1;
- mkdir $path, 0770;
- $path = "/var/spool/asterisk/voicemail/$context/$mbox/$oldfolder";
- opendir(DIR, $path) || die("Unable to open directory\n");
- my @files = grep /^msg${old}\.\w+$/, readdir(DIR);
- closedir(DIR);
- foreach $oldfile (@files) {
- my $tmp = $oldfile;
- if ($tmp =~ /^(msg${old}.\w+)$/) {
- $tmp = $1;
- $oldfile = $path . "/$tmp";
- $tmp =~ s/msg${old}/msg${new}/;
- $newfile = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX/$tmp";
-# print "Copying $oldfile to $newfile<BR>\n";
- &file_copy($oldfile, $newfile);
- }
- }
-}
-
-sub message_delete()
-{
- my ($context, $mbox, $folder, $msg) = @_;
- if ($mbox =~ /^(\w+)$/) {
- $mbox = $1;
- } else {
- die ("Invalid mailbox<BR>\n");
- }
- if ($context =~ /^(\w+)$/) {
- $context = $1;
- } else {
- die ("Invalid context<BR>\n");
- }
- if ($folder =~ /^(\w+)$/) {
- $folder = $1;
- } else {
- die("Invalid folder<BR>\n");
- }
- if ($msg =~ /^(\d\d\d\d)$/) {
- $msg = $1;
- } else {
- die("Invalid Message<BR>\n");
- }
- my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$folder";
- opendir(DIR, $path) || die("Unable to open directory\n");
- my @files = grep /^msg${msg}\.\w+$/, readdir(DIR);
- closedir(DIR);
- foreach $oldfile (@files) {
- if ($oldfile =~ /^(msg${msg}.\w+)$/) {
- $oldfile = $path . "/$1";
-# print "Deleting $oldfile<BR>\n";
- unlink($oldfile);
- }
- }
-}
-
-sub message_forward()
-{
- my ($toindex, @msgs) = @_;
- my $folder = param('folder');
- my ($mbox, $context) = split(/\@/, param('mailbox'));
- my $newmbox = param('forwardto');
- my $msg;
- my $msgcount;
- if (!$context) {
- $context = param('context');
- }
- if (!$context) {
- $context = "default";
- }
- $newmbox =~ s/(\w+)(\s+.*)?$/$1/;
- if (!&validmailbox($context, $newmbox)) {
- die("Bah! Not a valid mailbox '$newmbox'\n");
- return "";
- }
-
- my $txt;
- $context = &untaint($context);
- $newmbox = &untaint($newmbox);
- my $path = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX";
- if ($msgs[0]) {
- if (&lock_path($path) == 0) {
- $msgcount = &msgcount($context, $newmbox, "INBOX");
-
- if ($newmbox ne $mbox) {
- # print header;
- foreach $msg (@msgs) {
- # print "Forwarding $msg from $mbox to $newmbox<BR>\n";
- &message_copy($context, $mbox, $newmbox, $folder, $msg, sprintf "%04d", $msgcount);
- $msgcount++;
- }
- $txt = "Forwarded messages " . join(', ', @msgs) . "to $newmbox";
- } else {
- $txt = "Can't forward messages to yourself!\n";
- }
- &unlock_path($path);
- } else {
- $txt = "Cannot forward messages: Unable to lock path.\n";
- }
- } else {
- $txt = "Please Select Message(s) for this action.\n";
- }
- if ($toindex) {
- &message_index($folder, $txt);
- } else {
- &message_play($txt, $msgs[0]);
- }
-}
-
-sub message_delete_or_move()
-{
- my ($toindex, $del, @msgs) = @_;
- my $txt;
- my $path;
- my ($y, $x);
- my $folder = param('folder');
- my $newfolder = param('newfolder') unless $del;
- $newfolder =~ s/^(\w+)\s+.*$/$1/;
- my ($mbox, $context) = split(/\@/, param('mailbox'));
- if (!$context) {
- $context = param('context');
- }
- if (!$context) {
- $context = "default";
- }
- my $passwd = param('password');
- $context = &untaint($context);
- $mbox = &untaint($mbox);
- $folder = &untaint($folder);
- $path = "/var/spool/asterisk/voicemail/$context/$mbox/$folder";
- if ($msgs[0]) {
- if (&lock_path($path) == 0) {
- my $msgcount = &msgcount($context, $mbox, $folder);
- my $omsgcount = &msgcount($context, $mbox, $newfolder) if $newfolder;
- # print header;
- if ($newfolder ne $folder) {
- $y = 0;
- for ($x=0;$x<$msgcount;$x++) {
- my $msg = sprintf "%04d", $x;
- my $newmsg = sprintf "%04d", $y;
- if (grep(/^$msg$/, @msgs)) {
- if ($newfolder) {
- &message_rename($context, $mbox, $folder, $msg, $newfolder, sprintf "%04d", $omsgcount);
- $omsgcount++;
- } else {
- &message_delete($context, $mbox, $folder, $msg);
- }
- } else {
- &message_rename($context, $mbox, $folder, $msg, $folder, $newmsg);
- $y++;
- }
- }
- if ($del) {
- $txt = "Deleted messages " . join (', ', @msgs);
- } else {
- $txt = "Moved messages " . join (', ', @msgs) . " to $newfolder";
- }
- } else {
- $txt = "Can't move a message to the same folder they're in already";
- }
- &unlock_path($path);
- } else {
- $txt = "Cannot move/delete messages: Unable to lock path.\n";
- }
- } else {
- $txt = "Please Select Message(s) for this action.\n";
- }
- # Not as many messages now
- $msgcount--;
- if ($toindex || ($msgs[0] >= $msgcount)) {
- &message_index($folder, $txt);
- } else {
- &message_play($txt, $msgs[0]);
- }
-}
-
-if (param()) {
- my $folder = param('folder');
- my $changefolder = param('changefolder');
- $changefolder =~ s/(\w+)\s+.*$/$1/;
-
- my $newfolder = param('newfolder');
- $newfolder =~ s/^(\w+)\s+.*$/$1/;
- if ($newfolder && !&validfolder($newfolder)) {
- print header;
- die("Bah! new folder '$newfolder' isn't a folder.");
- }
- $action = param('action');
- $msgid = param('msgid');
- if (!$action) {
- my ($tmp) = grep /^play\d\d\d\d\.x$/, param;
- if ($tmp =~ /^play(\d\d\d\d)/) {
- $msgid = $1;
- $action = "play";
- } else {
- print header;
- print "No message?<BR>\n";
- return;
- }
- }
- @msgs = param('msgselect');
- @msgs = ($msgid) unless @msgs;
- {
- ($mailbox) = &check_login();
- if (length($mailbox)) {
- if ($action eq 'login') {
- &message_index($folder, "Welcome, $mailbox");
- } elsif (($action eq 'refresh') || ($action eq 'index')) {
- &message_index($folder, "Welcome, $mailbox");
- } elsif ($action eq 'change to ->') {
- if (&validfolder($changefolder)) {
- $folder = $changefolder;
- &message_index($folder, "Welcome, $mailbox");
- } else {
- die("Bah! Not a valid change to folder '$changefolder'\n");
- }
- } elsif ($action eq 'play') {
- &message_play("$mailbox $folder $msgid", $msgid);
- } elsif ($action eq 'preferences') {
- &message_prefs("refresh", $msgid);
- } elsif ($action eq 'download') {
- &message_audio(1);
- } elsif ($action eq 'play ') {
- &message_audio(0);
- } elsif ($action eq 'audio') {
- &message_audio(0);
- } elsif ($action eq 'delete') {
- &message_delete_or_move(1, 1, @msgs);
- } elsif ($action eq 'delete ') {
- &message_delete_or_move(0, 1, @msgs);
- } elsif ($action eq 'forward to ->') {
- &message_forward(1, @msgs);
- } elsif ($action eq 'forward to -> ') {
- &message_forward(0, @msgs);
- } elsif ($action eq 'save to ->') {
- &message_delete_or_move(1, 0, @msgs);
- } elsif ($action eq 'save to -> ') {
- &message_delete_or_move(0, 0, @msgs);
- } elsif ($action eq 'logout') {
- &login_screen("Logged out!\n");
- }
- } else {
- sleep(1);
- &login_screen("Login Incorrect!\n");
- }
- }
-} else {
- &login_screen("\&nbsp;");
-}
diff --git a/1.4/contrib/scripts/vmdb.sql b/1.4/contrib/scripts/vmdb.sql
deleted file mode 100644
index c8148cfcb..000000000
--- a/1.4/contrib/scripts/vmdb.sql
+++ /dev/null
@@ -1,64 +0,0 @@
-DROP TABLE IF EXISTS voicemail;
-CREATE TABLE voicemail (
- -- All of these column names are very specific, including "uniqueid". Do not change them if you wish voicemail to work.
- uniqueid INT(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
- -- Mailbox context.
- context CHAR(80) NOT NULL DEFAULT 'default',
- -- Mailbox number. Should be numeric.
- mailbox CHAR(80) NOT NULL,
- -- Must be numeric. Negative if you don't want it to be changed from VoicemailMain
- password CHAR(80) NOT NULL,
- -- Used in email and for Directory app
- fullname CHAR(80),
- -- Email address (will get sound file if attach=yes)
- email CHAR(80),
- -- Email address (won't get sound file)
- pager CHAR(80),
- -- Attach sound file to email - YES/no
- attach CHAR(3),
- -- Which sound format to attach
- attachfmt CHAR(10),
- -- Send email from this address
- serveremail CHAR(80),
- -- Prompts in alternative language
- language CHAR(20),
- -- Alternative timezone, as defined in voicemail.conf
- tz CHAR(30),
- -- Delete voicemail from server after sending email notification - yes/NO
- deletevoicemail CHAR(3),
- -- Read back CallerID information during playback - yes/NO
- saycid CHAR(3),
- -- Allow user to send voicemail from within VoicemailMain - YES/no
- sendvoicemail CHAR(3),
- -- Listen to voicemail and approve before sending - yes/NO
- review CHAR(3),
- -- Warn user a temporary greeting exists - yes/NO
- tempgreetwarn CHAR(3),
- -- Allow '0' to jump out during greeting - yes/NO
- operator CHAR(3),
- -- Hear date/time of message within VoicemailMain - YES/no
- envelope CHAR(3),
- -- Hear length of message within VoicemailMain - yes/NO
- sayduration CHAR(3),
- -- Minimum duration in minutes to say
- saydurationm INT(3),
- -- Force new user to record name when entering voicemail - yes/NO
- forcename CHAR(3),
- -- Force new user to record greetings when entering voicemail - yes/NO
- forcegreetings CHAR(3),
- -- Context in which to dial extension for callback
- callback CHAR(80),
- -- Context in which to dial extension (from advanced menu)
- dialout CHAR(80),
- -- Context in which to execute 0 or * escape during greeting
- exitcontext CHAR(80),
- -- Maximum messages in a folder (100 if not specified)
- maxmsg INT(5),
- -- Increase DB gain on recorded message by this amount (0.0 means none)
- volgain DECIMAL(5,2),
- -- IMAP user for authentication (if using IMAP storage)
- imapuser VARCHAR(80),
- -- IMAP password for authentication (if using IMAP storage)
- imappassword VARCHAR(80),
- stamp timestamp
-);
diff --git a/1.4/contrib/thirdparty/spexxilbcfix_xlite.reg b/1.4/contrib/thirdparty/spexxilbcfix_xlite.reg
deleted file mode 100644
index 821fd5e2b..000000000
--- a/1.4/contrib/thirdparty/spexxilbcfix_xlite.reg
+++ /dev/null
Binary files differ
diff --git a/1.4/contrib/thirdparty/spexxilbcfix_xpro.reg b/1.4/contrib/thirdparty/spexxilbcfix_xpro.reg
deleted file mode 100644
index 472dcb44f..000000000
--- a/1.4/contrib/thirdparty/spexxilbcfix_xpro.reg
+++ /dev/null
Binary files differ
diff --git a/1.4/contrib/utils/README.rawplayer b/1.4/contrib/utils/README.rawplayer
deleted file mode 100644
index 146898a5c..000000000
--- a/1.4/contrib/utils/README.rawplayer
+++ /dev/null
@@ -1,37 +0,0 @@
-rawplayer is a simple C applet to stream raw music files in place of mpg123
-
-INSTALL
-
-compile the .c file and install:
-gcc -O2 rawplayer.c -o /usr/bin/rawplayer
-
-
-
-Converting MP3 to RAW
-
-Make track01.mp3 into track01.raw with sox (if compiled with mp3 support).
-sox -c 1 track01.mp3 -t raw -r 8000 -c 1 -s -w track01.raw
-
-Otherwise, use whatever app to turn track01.mp3 into track01.wav then use sox on the wav.
-sox -c 1 track01.wav -t raw -r 8000 -c 1 -s -w track01.raw
-
-
-Once you have the raw files put them in any dir on your system (eg /var/lib/asterisk/holdmusic_raw).
-and set up a class in musiconhold.conf like so:
-
-[classes]
-default => custom:/var/lib/asterisk/holdmusic_raw,/usr/bin/rawplayer
-
-
-This is the most efficient way to implement moh because no cpu usage is required to
-explode the very compressed mp3 data then downsample the music to the 8khz mono on the fly
-instead the data is already stored on the disk in the format that asterisk needs it to be
-and the player does little more than pick up frames from the file and hand them to right
-to the asterisk pipe where the audio is shared into all the channels who require it.
-
-
-If you have cpu to spare and want a simple mp3 solution consider the format_mp3 from
-asterisk-addons and the files based moh.
-
-
-
diff --git a/1.4/contrib/utils/rawplayer.c b/1.4/contrib/utils/rawplayer.c
deleted file mode 100644
index 2733264a0..000000000
--- a/1.4/contrib/utils/rawplayer.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Rawplayer.c simple raw file stdout player
- (c) Anthony C Minessale II <anthmct@yahoo.com>
-
- 2006-03-10: Bruno Rocha <bruno@3gnt.net>
- - include <stdlib.h> to remove compiler warning on some platforms
- - check for read/write errors (avoid 100% CPU usage in some asterisk failures)
-*/
-
-#define BUFLEN 320
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-static int deliver_file(char *path, int fdout) {
- int fd = 0, bytes = 0, error = 0;
- short buf[BUFLEN];
-
- if ((fd = open(path,O_RDONLY))) {
- while ((bytes=read(fd, buf, BUFLEN)) > 0) {
- if(write(fdout, buf, bytes) < 0){
- error = -2;
- break;
- }
- }
- if(fd)
- close(fd);
- } else
- return -1;
-
- return error;
-}
-
-
-int main(int argc, char *argv[]) {
- int x = 0, fdout = 0;
- fdout = fileno(stdout);
- for (;;)
- for (x = 1; x < argc ; x++) {
- if(deliver_file(argv[x], fdout))
- exit(1);
- }
-}
-
diff --git a/1.4/contrib/utils/zones2indications.c b/1.4/contrib/utils/zones2indications.c
deleted file mode 100644
index 186e53c9f..000000000
--- a/1.4/contrib/utils/zones2indications.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Tzafrir Cohen <tzafrir.cohen@xorcom.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.
- */
-
-/*! \file
- * \brief print libtonozone data as Asterisk indications.conf
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <zaptel/tonezone.h>
-#include <unistd.h>
-
-#define PROGRAM "zones2indication"
-
-void print_tone_zone_sound(struct tone_zone *zone_data, const char* name,
- int toneid) {
- int i;
- for (i=0; i<ZT_TONE_MAX; i++) {
- if (zone_data->tones[i].toneid == toneid){
- printf("%s = %s\n", name, zone_data->tones[i].data);
- break;
- }
- }
-}
-
-void print_indications(struct tone_zone *zone_data) {
- int i;
-
- printf (
- "[%s]\n"
- "; Source: libtonezone.\n"
- "description = %s\n"
- "\n",
- zone_data->country, zone_data->description
- );
-
- printf(
- "ringcadence = "
- );
- for(i=0; ; i++) {
- if (zone_data->ringcadence[i] == 0)
- break;
- if (i != 0)
- putchar(',');
- printf("%d",zone_data->ringcadence[i]);
- }
- putchar('\n');
-
- print_tone_zone_sound(zone_data, "dial", ZT_TONE_DIALTONE);
- print_tone_zone_sound(zone_data, "busy", ZT_TONE_BUSY);
- print_tone_zone_sound(zone_data, "ring", ZT_TONE_RINGTONE);
- print_tone_zone_sound(zone_data, "congestion", ZT_TONE_CONGESTION);
- print_tone_zone_sound(zone_data, "callwaiting", ZT_TONE_CALLWAIT);
- print_tone_zone_sound(zone_data, "dialrecall", ZT_TONE_DIALRECALL);
- print_tone_zone_sound(zone_data, "record", ZT_TONE_RECORDTONE);
- print_tone_zone_sound(zone_data, "info", ZT_TONE_INFO);
- print_tone_zone_sound(zone_data, "stutter", ZT_TONE_STUTTER);
- printf("\n\n");
-}
-
-int print_zone_by_id(int zone_num) {
- struct tone_zone *zone_data = tone_zone_find_by_num(zone_num);
-
- if (zone_data == NULL)
- return 1;
-
- print_indications(zone_data);
-
- return 0;
-}
-
-int print_zone_by_country(char* country) {
- struct tone_zone *zone_data = tone_zone_find(country);
-
- if (zone_data == NULL)
- return 1;
-
- print_indications(zone_data);
-
- return 0;
-}
-
-int print_all() {
- int i;
- /* loop over all possible zones */
- for (i=0; ; i++) {
- if (print_zone_by_id(i))
- break;
- }
- return 0;
-}
-
-void usage() {
- fprintf(stderr,
- PROGRAM ": print libtonozone data as Asterisk indications.conf\n"
- "\n"
- "Usage:\n"
- " " PROGRAM " -a Print all countries\n"
- " " PROGRAM " -c <code> Select country by two-letter country code\n"
- " " PROGRAM " -n <num> Select country by its internal libtonezone number\n"
- " " PROGRAM " -h Print this text.\n"
- );
-}
-
-int main(int argc, char* argv[]){
- int country_code = -1;
- int opt_print_all = 0;
- int opt;
- char* endptr = NULL;
-
- while((opt = getopt(argc, argv, "ac:hn:")) != -1) {
- switch(opt) {
- case 'a':
- return print_all();
- case 'c':
- return print_zone_by_country(optarg);
- case 'h':
- usage();
- return 0;
- case 'n':
- printf("number is %s.\n", optarg);
- country_code = strtol(optarg, &endptr, 10);
- return print_zone_by_id(country_code);
- /* FIXME: what if this is not a number?
- if (endptr != NULL) {
- fprintf(stderr, "Error: Invalid country code %s, %d.\n",optarg, country_code);
- usage();
- exit(1);
- }
- */
- break;
- }
- }
-
- /* If we got here, the user selected no option */
- usage();
- return 2;
-}
diff --git a/1.4/contrib/valgrind-RedHat-8.0.supp b/1.4/contrib/valgrind-RedHat-8.0.supp
deleted file mode 100644
index a404d43fa..000000000
--- a/1.4/contrib/valgrind-RedHat-8.0.supp
+++ /dev/null
@@ -1,41 +0,0 @@
-#This valgrind suppresion file is supposed to be working with
-#Red Hat Linux release 8.0 (Psyche)
-#You can use it by calling valgrind this way:
-#cd /usr/src/asterisk
-#valgrind --gdb-attach=yes --suppressions=valgrind-RedHat-8.0.supp asterisk -vvv
-
-{
- library_1
- PThread
- fun:pthread_error
- fun:__pthread_mutex_destroy
- obj:/lib/i686/libc-2.2.93.so
-}
-
-{
- library 2
- Cond
- fun:elf_dynamic_do_rel.7
- fun:_dl_relocate_object_internal
- obj:/lib/i686/libc-2.2.93.so
- fun:_dl_catch_error_internal
-}
-
-#==21922== Thread 16:
-#==21922== Syscall param ioctl(generic) contains uninitialised or
-#unaddressable byte(s)
-#==21922== at 0x420D3454: (within /lib/i686/libc-2.2.93.so)
-#==21922== by 0x8058D45: ast_call (channel.c:1356)
-#==21922== by 0x463027A7: ??? (app_dial.c:472)
-#==21922== by 0x805E2AE: pbx_exec (pbx.c:318)
-#==21922== Address 0x0 is not stack'd, malloc'd or free'd
-
-{
- ioctl(........,NULL);
- Param
- ioctl(generic)
- obj:/lib/i686/libc-2.2.93.so
- fun:ast_call
- fun:
- fun:pbx_exec
-}
diff --git a/1.4/doc/00README.1st b/1.4/doc/00README.1st
deleted file mode 100644
index c006d56a8..000000000
--- a/1.4/doc/00README.1st
+++ /dev/null
@@ -1,74 +0,0 @@
-Files in the /doc directory:
-----------------------------
-In addition to these files, there is a lot of documentation of various
-configuration options in the sample configuration files, in the /configs
-directory of your source code
-
-Start here
-----------
-security.txt IMPORTANT INFORMATION ABOUT ASTERISK SECURITY
-hardware.txt Hardware supported by Asterisk
-
-Configuration
--------------
-configuration.txt Features in the configuration parser
-extensions.txt Basics about the dialplan
-extconfig.txt How to use databases for configuration of Asterisk (ARA)
-ip-tos.txt About the IP Type Of Service settings
-realtime.txt The Asterisk Realtime Architecture - database support
-freetds.txt Information about the FreeTDS support
-ael.txt Information about the Asterisk Extension Language
-
-Misc
-----
-PEERING The General Peering Agreement for Dundi
-ajam.txt About the HTTP-based manager interface
-app_sms.txt How to configure the SMS application
-asterisk.conf.txt Documentation of various options in asterisk.conf
-callingpres.txt Settings for Caller ID presentation
-billing.txt Call Data Record information
-cliprompt.txt How to change the Asterisk CLI prompt
-dundi.txt Dundi - a discovery protocol
-enum.txt Enum support in Asterisk
-ices.txt Integrating ICEcast streaming in Asterisk
-jitterbuffer.txt About the IAX2 jitterbuffer implementation
-math.txt About the math() application
-mp3.txt About MP3 support in Asterisk
-musiconhold-fpm.txt Free Music On Hold music
-mysql.txt About MYSQL support in Asterisk
-odbcstorage.txt Voicemail storage of messages in UnixODBC
-privacy.txt Privacy enhancements in Asterisk
-queuelog.txt Agent and queue logging
-channelvariables.txt Channel variables
-cdrdrivers.txt About CDR storage in various databases (needs update)
-asterisk-mib.txt SNMP mib for Asterisk (net-snmp)
-digium-mib.txt SNMP mib for Asterisk (net-snmp)
-
-Channel drivers
----------------
-misdn.txt The mISDN channel driver for ISDN BRI cards
-h323.txt How to compile and configure the H.323 channel
-chaniax.txt About the IAX2 protocol support in Asterisk
-localchannel.txt The local channel is a "gosub" in the dialplan
-
-Portability
------------
-cygwin.txt Compiling Asterisk on CygWin platforms (Windows)
-
-For developers
---------------
-See http://www.asterisk.org/developers for more information
-
-manager.txt About the AMI - Asterisk Manager Interface
- for third party call control and PBX management
-backtrace.txt How to produce a backtrace when Asterisk crashes
-CODING-GUIDELINES Guidelines for developers
-channels.txt What is a channel?
-externalivr.txt Documentation of the protocol used in externalivr()
-linkedlists.txt How to develop linked lists in Asterisk (old)
-iax.txt About the IAX protocol
-apps.txt About application development
-model.txt About the call model in Asterisk (old)
-modules.txt How Asterisk modules work
-datastores.txt About channel data stores
-speechrec.txt The Generic Speech Recognition API
diff --git a/1.4/doc/CODING-GUIDELINES b/1.4/doc/CODING-GUIDELINES
deleted file mode 100644
index c3ffacd3c..000000000
--- a/1.4/doc/CODING-GUIDELINES
+++ /dev/null
@@ -1,543 +0,0 @@
-== Asterisk Patch/Coding Guidelines ==
---------------------------------------
-
-We are looking forward to your contributions to Asterisk - the
-Open Source PBX! As Asterisk is a large and in some parts very
-time-sensitive application, the code base needs to conform to
-a common set of coding rules so that many developers can enhance
-and maintain the code. Code also needs to be reviewed and tested
-so that it works and follows the general architecture and guide-
-lines, and is well documented.
-
-Asterisk is published under a dual-licensing scheme by Digium.
-To be accepted into the codebase, all non-trivial changes must be
-disclaimed to Digium or placed in the public domain. For more information
-see http://bugs.digium.com
-
-Patches should be in the form of a unified (-u) diff, made from a checkout
-from subversion.
-
-/usr/src/asterisk$ svn diff > mypatch
-
-If you would like to only include changes to certain files in the patch, you
-can list them in the "svn diff" command:
-
-/usr/src/asterisk$ svn diff somefile.c someotherfile.c > mypatch
-
-* General rules
----------------
-
-- All code, filenames, function names and comments must be in ENGLISH.
-
-- Don't annotate your changes with comments like "/* JMG 4/20/04 */";
- Comments should explain what the code does, not when something was changed
- or who changed it. If you have done a larger contribution, make sure
- that you are added to the CREDITS file.
-
-- Don't make unnecessary whitespace changes throughout the code.
- If you make changes, submit them to the tracker as separate patches
- that only include whitespace and formatting changes.
-
-- Don't use C++ type (//) comments.
-
-- Try to match the existing formatting of the file you are working on.
-
-- Use spaces instead of tabs when aligning in-line comments or #defines (this makes
- your comments aligned even if the code is viewed with another tabsize)
-
-* Declaration of functions and variables
-----------------------------------------
-
-- Do not declare variables mid-block (e.g. like recent GNU compilers support)
- since it is harder to read and not portable to GCC 2.95 and others.
-
-- Functions and variables that are not intended to be used outside the module
- must be declared static.
-
-- When reading integer numeric input with scanf (or variants), do _NOT_ use '%i'
- unless you specifically want to allow non-base-10 input; '%d' is always a better
- choice, since it will not silently turn numbers with leading zeros into base-8.
-
-- Strings that are coming from input should not be used as a first argument to
- a formatted *printf function.
-
-* Use the internal API
-----------------------
-
-- Make sure you are aware of the string and data handling functions that exist
- within Asterisk to enhance portability and in some cases to produce more
- secure and thread-safe code. Check utils.c/utils.h for these.
-
-
-* Code formatting
------------------
-
-Roughly, Asterisk code formatting guidelines are generally equivalent to the
-following:
-
-# indent -i4 -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -l90 foo.c
-
-this means in verbose:
- -i4: indent level 4
- -ts4: tab size 4
- -br: braces on if line
- -brs: braces on struct decl line
- -cdw: cuddle do while
- -lp: line up continuation below parenthesis
- -ce: cuddle else
- -nbfda: dont break function decl args
- -npcs: no space after function call names
- -nprs: no space after parentheses
- -npsl: dont break procedure type
- -saf: space after for
- -sai: space after if
- -saw: space after while
- -cs: space after cast
- -ln90: line length 90 columns
-
-Function calls and arguments should be spaced in a consistent way across
-the codebase.
- GOOD: foo(arg1, arg2);
- GOOD: foo(arg1,arg2); /* Acceptable but not preferred */
- BAD: foo (arg1, arg2);
- BAD: foo( arg1, arg2 );
- BAD: foo(arg1, arg2,arg3);
-
-Don't treat keywords (if, while, do, return) as if they were functions;
-leave space between the keyword and the expression used (if any). For 'return',
-don't even put parentheses around the expression, since they are not
-required.
-
-There is no shortage of whitespace characters :-) Use them when they make
-the code easier to read. For example:
-
- for (str=foo;str;str=str->next)
-
-is harder to read than
-
- for (str = foo; str; str = str->next)
-
-Following are examples of how code should be formatted.
-
-- Functions:
-int foo(int a, char *s)
-{
- return 0;
-}
-
-- If statements:
-if (foo) {
- bar();
-} else {
- blah();
-}
-
-- Case statements:
-switch (foo) {
-case BAR:
- blah();
- break;
-case OTHER:
- other();
- break;
-}
-
-- No nested statements without braces, e.g.:
-
-for (x = 0; x < 5; x++)
- if (foo)
- if (bar)
- baz();
-
-instead do:
-for (x = 0; x < 5; x++) {
- if (foo) {
- if (bar)
- baz();
- }
-}
-
-- Don't build code like this:
-
-if (foo) {
- /* .... 50 lines of code ... */
-} else {
- result = 0;
- return;
-}
-
-Instead, try to minimize the number of lines of code that need to be
-indented, by only indenting the shortest case of the 'if'
-statement, like so:
-
-if (!foo) {
- result = 0;
- return;
-}
-
-.... 50 lines of code ....
-
-When this technique is used properly, it makes functions much easier to read
-and follow, especially those with more than one or two 'setup' operations
-that must succeed for the rest of the function to be able to execute.
-
-- Labels/goto are acceptable
-Proper use of this technique may occasionally result in the need for a
-label/goto combination so that error/failure conditions can exit the
-function while still performing proper cleanup. This is not a bad thing!
-Use of goto in this situation is encouraged, since it removes the need
-for excess code indenting without requiring duplication of cleanup code.
-
-- Never use an uninitialized variable
-Make sure you never use an uninitialized variable. The compiler will
-usually warn you if you do so. However, do not go too far the other way,
-and needlessly initialize variables that do not require it. If the first
-time you use a variable in a function is to store a value there, then
-initializing it at declaration is pointless, and will generate extra
-object code and data in the resulting binary with no purpose. When in doubt,
-trust the compiler to tell you when you need to initialize a variable;
-if it does not warn you, initialization is not needed.
-
-- Do not cast 'void *'
-Do not explicitly cast 'void *' into any other type, nor should you cast any
-other type into 'void *'. Implicit casts to/from 'void *' are explicitly
-allowed by the C specification. This means the results of malloc(), calloc(),
-alloca(), and similar functions do not _ever_ need to be cast to a specific
-type, and when you are passing a pointer to (for example) a callback function
-that accepts a 'void *' you do not need to cast into that type.
-
-* Variable naming
------------------
-
-- Global variables
-Name global variables (or local variables when you have a lot of them or
-are in a long function) something that will make sense to aliens who
-find your code in 100 years. All variable names should be in lower
-case, except when following external APIs or specifications that normally
-use upper- or mixed-case variable names; in that situation, it is
-preferable to follow the external API/specification for ease of
-understanding.
-
-Make some indication in the name of global variables which represent
-options that they are in fact intended to be global.
- e.g.: static char global_something[80]
-
-- Don't use un-necessary typedef's
-Don't use 'typedef' just to shorten the amount of typing; there is no substantial
-benefit in this:
-
-struct foo {
- int bar;
-};
-typedef struct foo foo_t;
-
-In fact, don't use 'variable type' suffixes at all; it's much preferable to
-just type 'struct foo' rather than 'foo_s'.
-
-- Use enums instead of #define where possible
-Use enums rather than long lists of #define-d numeric constants when possible;
-this allows structure members, local variables and function arguments to
-be declared as using the enum's type. For example:
-
-enum option {
- OPT_FOO = 1
- OPT_BAR = 2
- OPT_BAZ = 4
-};
-
-static enum option global_option;
-
-static handle_option(const enum option opt)
-{
- ...
-}
-
-Note: The compiler will _not_ force you to pass an entry from the enum
-as an argument to this function; this recommendation serves only to make
-the code clearer and somewhat self-documenting. In addition, when using
-switch/case blocks that switch on enum values, the compiler will warn
-you if you forget to handle one or more of the enum values, which can be
-handy.
-
-* String handling
------------------
-
-Don't use strncpy for copying whole strings; it does not guarantee that the
-output buffer will be null-terminated. Use ast_copy_string instead, which
-is also slightly more efficient (and allows passing the actual buffer
-size, which makes the code clearer).
-
-Don't use ast_copy_string (or any length-limited copy function) for copying
-fixed (known at compile time) strings into buffers, if the buffer is something
-that has been allocated in the function doing the copying. In that case, you
-know at the time you are writing the code whether the buffer is large enough
-for the fixed string or not, and if it's not, your code won't work anyway!
-Use strcpy() for this operation, or directly set the first two characters
-of the buffer if you are just trying to store a one-character string in the
-buffer. If you are trying to 'empty' the buffer, just store a single
-NULL character ('\0') in the first byte of the buffer; nothing else is
-needed, and any other method is wasteful.
-
-In addition, if the previous operations in the function have already
-determined that the buffer in use is adequately sized to hold the string
-you wish to put into it (even if you did not allocate the buffer yourself),
-use a direct strcpy(), as it can be inlined and optimized to simple
-processor operations, unlike ast_copy_string().
-
-* Use of functions
-------------------
-
-When making applications, always ast_strdupa(data) to a local pointer if
-you intend to parse the incoming data string.
-
- if (data)
- mydata = ast_strdupa(data);
-
-
-- Separating arguments to dialplan applications and functions
-Use ast_app_separate_args() to separate the arguments to your application
-once you have made a local copy of the string.
-
-- Parsing strings with strsep
-Use strsep() for parsing strings when possible; there is no worry about
-'re-entrancy' as with strtok(), and even though it modifies the original
-string (which the man page warns about), in many cases that is exactly
-what you want!
-
-- Create generic code!
-If you do the same or a similar operation more than one time, make it a
-function or macro.
-
-Make sure you are not duplicating any functionality already found in an
-API call somewhere. If you are duplicating functionality found in
-another static function, consider the value of creating a new API call
-which can be shared.
-
-* Handling of pointers and allocations
---------------------------------------
-
-- Dereference or localize pointers
-Always dereference or localize pointers to things that are not yours like
-channel members in a channel that is not associated with the current
-thread and for which you do not have a lock.
- channame = ast_strdupa(otherchan->name);
-
-- Use const on pointer arguments if possible
-Use const on pointer arguments which your function will not be modifying, as this
-allows the compiler to make certain optimizations. In general, use 'const'
-on any argument that you have no direct intention of modifying, as it can
-catch logic/typing errors in your code when you use the argument variable
-in a way that you did not intend.
-
-- Do not create your own linked list code - reuse!
-As a common example of this point, make an effort to use the lockable
-linked-list macros found in include/asterisk/linkedlists.h. They are
-efficient, easy to use and provide every operation that should be
-necessary for managing a singly-linked list (if something is missing,
-let us know!). Just because you see other open-coded list implementations
-in the source tree is no reason to continue making new copies of
-that code... There are also a number of common string manipulation
-and timeval manipulation functions in asterisk/strings.h and asterisk/time.h;
-use them when possible.
-
-- Avoid needless allocations!
-Avoid needless malloc(), strdup() calls. If you only need the value in
-the scope of your function try ast_strdupa() or declare structs on the
-stack and pass a pointer to them. However, be careful to _never_ call
-alloca(), ast_strdupa() or similar functions in the argument list
-of a function you are calling; this can cause very strange stack
-arrangements and produce unexpected behavior.
-
--Allocations for structures
-When allocating/zeroing memory for a structure, use code like this:
-
-struct foo *tmp;
-
-...
-
-tmp = ast_calloc(1, sizeof(*tmp));
-
-Avoid the combination of ast_malloc() and memset(). Instead, always use
-ast_calloc(). This will allocate and zero the memory in a single operation.
-In the case that uninitialized memory is acceptable, there should be a comment
-in the code that states why this is the case.
-
-Using sizeof(*tmp) instead of sizeof(struct foo) eliminates duplication of the
-'struct foo' identifier, which makes the code easier to read and also ensures
-that if it is copy-and-pasted it won't require as much editing.
-
-The ast_* family of functions for memory allocation are functionally the same.
-They just add an Asterisk log error message in the case that the allocation
-fails for some reason. This eliminates the need to generate custom messages
-throughout the code to log that this has occurred.
-
--String Duplications
-
-The functions strdup and strndup can *not* accept a NULL argument. This results
-in having code like this:
-
- if (str)
- newstr = strdup(str);
- else
- newstr = NULL;
-
-However, the ast_strdup and ast_strdup functions will happily accept a NULL
-argument without generating an error. The same code can be written as:
-
- newstr = ast_strdup(str);
-
-Furthermore, it is unnecessary to have code that malloc/calloc's for the length
-of a string (+1 for the terminating '\0') and then using strncpy to copy the
-copy the string into the resulting buffer. This is the exact same thing as
-using ast_strdup.
-
-* CLI Commands
---------------
-
-New CLI commands should be named using the module's name, followed by a verb
-and then any parameters that the command needs. For example:
-
-*CLI> iax2 show peer <peername>
-
-not
-
-*CLI> show iax2 peer <peername>
-
-* New dialplan applications/functions
--------------------------------------
-
-There are two methods of adding functionality to the Asterisk
-dialplan: applications and functions. Applications (found generally in
-the apps/ directory) should be collections of code that interact with
-a channel and/or user in some significant way. Functions (which can be
-provided by any type of module) are used when the provided
-functionality is simple... getting/retrieving a value, for
-example. Functions should also be used when the operation is in no way
-related to a channel (a computation or string operation, for example).
-
-Applications are registered and invoked using the
-ast_register_application function; see the apps/app_skel.c file for an
-example.
-
-Functions are registered using 'struct ast_custom_function'
-structures and the ast_custom_function_register function.
-
-* Doxygen API Documentation Guidelines
---------------------------------------
-
-When writing Asterisk API documentation the following format should be
-followed. Do not use the javadoc style.
-
-/*!
- * \brief Do interesting stuff.
- * \param thing1 interesting parameter 1.
- * \param thing2 interesting parameter 2.
- *
- * This function does some interesting stuff.
- *
- * \return zero on success, -1 on error.
- */
-int ast_interesting_stuff(int thing1, int thing2)
-{
- return 0;
-}
-
-Notice the use of the \param, \brief, and \return constructs. These should be
-used to describe the corresponding pieces of the function being documented.
-Also notice the blank line after the last \param directive. All doxygen
-comments must be in one /*! */ block. If the function or struct does not need
-an extended description it can be left out.
-
-Please make sure to review the doxygen manual and make liberal use of the \a,
-\code, \c, \b, \note, \li and \e modifiers as appropriate.
-
-When documenting a 'static' function or an internal structure in a module,
-use the \internal modifier to ensure that the resulting documentation
-explicitly says 'for internal use only'.
-
-Structures should be documented as follows.
-
-/*!
- * \brief A very interesting structure.
- */
-struct interesting_struct
-{
- /*! \brief A data member. */
- int member1;
-
- int member2; /*!< \brief Another data member. */
-}
-
-Note that /*! */ blocks document the construct immediately following them
-unless they are written, /*!< */, in which case they document the construct
-preceding them.
-
-* Finishing up before you submit your code
-------------------------------------------
-
-- Look at the code once more
-When you achieve your desired functionality, make another few refactor
-passes over the code to optimize it.
-
-- Read the patch
-Before submitting a patch, *read* the actual patch file to be sure that
-all the changes you expect to be there are, and that there are no
-surprising changes you did not expect. During your development, that
-part of Asterisk may have changed, so make sure you compare with the
-latest CVS.
-
-- Listen to advice
-If you are asked to make changes to your patch, there is a good chance
-the changes will introduce bugs, check it even more at this stage.
-Also remember that the bug marshal or co-developer that adds comments
-is only human, they may be in error :-)
-
-- Optimize, optimize, optimize
-If you are going to reuse a computed value, save it in a variable
-instead of recomputing it over and over. This can prevent you from
-making a mistake in subsequent computations, making it easier to correct
-if the formula has an error and may or may not help optimization but
-will at least help readability.
-
-Just an example (so don't over analyze it, that'd be a shame):
-
-const char *prefix = "pre";
-const char *postfix = "post";
-char *newname;
-char *name = "data";
-
-if (name && (newname = alloca(strlen(name) + strlen(prefix) + strlen(postfix) + 3)))
- snprintf(newname, strlen(name) + strlen(prefix) + strlen(postfix) + 3, "%s/%s/%s", prefix, name, postfix);
-
-...vs this alternative:
-
-const char *prefix = "pre";
-const char *postfix = "post";
-char *newname;
-char *name = "data";
-int len = 0;
-
-if (name && (len = strlen(name) + strlen(prefix) + strlen(postfix) + 3) && (newname = alloca(len)))
- snprintf(newname, len, "%s/%s/%s", prefix, name, postfix);
-
-* Creating new manager events?
-------------------------------
-If you create new AMI events, please read manager.txt. Do not re-use
-existing headers for new purposes, but please re-use existing headers
-for the same type of data.
-
-Manager events that signal a status are required to have one
-event name, with a status header that shows the status.
-The old style, with one event named "ThisEventOn" and another named
-"ThisEventOff", is no longer approved.
-
-Check manager.txt for more information on manager and existing
-headers. Please update this file if you add new headers.
-
------------------------------------------------
-Welcome to the Asterisk development community!
-Meet you on the asterisk-dev mailing list.
-Subscribe at http://lists.digium.com!
-
-Mark Spencer, Kevin P. Fleming and
-the Asterisk.org Development Team
diff --git a/1.4/doc/PEERING b/1.4/doc/PEERING
deleted file mode 100644
index 253009221..000000000
--- a/1.4/doc/PEERING
+++ /dev/null
@@ -1,499 +0,0 @@
- DIGIUM GENERAL PEERING AGREEMENT (TM)
- Version 1.0.0, September 2004
- Copyright (C) 2004 Digium, Inc.
- 445 Jan Davis Drive, Huntsville, AL 35806 USA
-
- Everyone is permitted to copy and distribute complete verbatim copies
- of this General Peering Agreement provided it is not modified in any
- manner.
-
- ------------------------------------------------------
-
- DIGIUM GENERAL PEERING AGREEMENT
-
- PREAMBLE
-
- For most of the history of telecommunications, the power of being able
-to locate and communicate with another person in a system, be it across
-a hall or around the world, has always centered around a centralized
-authority -- from a local PBX administrator to regional and national
-RBOCs, generally requiring fees, taxes or regulation. By contrast,
-DUNDi is a technology developed to provide users the freedom to
-communicate with each other without the necessity of any centralized
-authority. This General Peering Agreement ("GPA") is used by individual
-parties (each, a "Participant") to allow them to build the E164 trust
-group for the DUNDi protocol.
-
- To protect the usefulness of the E164 trust group for those who use
-it, while keeping the system wholly decentralized, it is necessary to
-replace many of the responsibilities generally afforded to a company or
-government agency, with a set of responsibilities implemented by the
-parties who use the system, themselves. It is the goal of this document
-to provide all the protections necessary to keep the DUNDi E164 trust
-group useful and reliable.
-
- The Participants wish to protect competition, promote innovation and
-value added services and make this service valuable both commercially
-and non-commercially. To that end, this GPA provides special terms and
-conditions outlining some permissible and non-permissible revenue
-sources.
-
- This GPA is independent of any software license or other license
-agreement for a program or technology employing the DUNDi protocol. For
-example, the implementation of DUNDi used by Asterisk is covered under a
-separate license. Each Participant is responsible for compliance with
-any licenses or other agreements governing use of such program or
-technology that they use to peer.
-
- You do not have to execute this GPA to use a program or technology
-employing the DUNDi protocol, however if you do not execute this GPA,
-you will not be able to peer using DUNDi and the E164 context with
-anyone who is a member of the trust group by virtue of their having
-executed this GPA with another member.
-
-The parties to this GPA agree as follows:
-
- 0. DEFINITIONS. As used herein, certain terms shall be defined as
-follows:
-
- (a) The term "DUNDi" means the DUNDi protocol as published by
- Digium, Inc. or its successor in interest with respect to the
- DUNDi protocol specification.
-
- (b) The terms "E.164" and "E164" mean ITU-T specification E.164 as
- published by the International Telecommunications Union (ITU) in
- May, 1997.
-
- (c) The term "Service" refers to any communication facility (e.g.,
- telephone, fax, modem, etc.), identified by an E.164-compatible
- number, and assigned by the appropriate authority in that
- jurisdiction.
-
- (d) The term "Egress Gateway" refers an Internet facility that
- provides a communications path to a Service or Services that may
- not be directly addressable via the Internet.
-
- (e) The term "Route" refers to an Internet address, policies, and
- other characteristics defined by the DUNDi protocol and
- associated with the Service, or the Egress Gateway which
- provides access to the specified Service.
-
- (f) The term "Propagate" means to accept or transmit Service and/or
- Egress Gateway Routes only using the DUNDi protocol and the
- DUNDi context "e164" without regard to case, and does not apply
- to the exchange of information using any other protocol or
- context.
-
- (g) The term "Peering System" means the network of systems that
- Propagate Routes.
-
- (h) The term "Subscriber" means the owner of, or someone who
- contracts to receive, the services identified by an E.164
- number.
-
- (i) The term "Authorizing Individual" means the Subscriber to a
- number who has authorized a Participant to provide Routes
- regarding their services via this Peering System.
-
- (j) The term "Route Authority" refers to a Participant that provides
- an original source of said Route within the Peering System.
- Routes are propagated from the Route Authorities through the
- Peering System and may be cached at intermediate points. There
- may be multiple Route Authorities for any Service.
-
- (k) The term "Participant" (introduced above) refers to any member
- of the Peering System.
-
- (l) The term "Service Provider" refers to the carrier (e.g.,
- exchange carrier, Internet Telephony Service Provider, or other
- reseller) that provides communication facilities for a
- particular Service to a Subscriber, Customer or other End User.
-
- (m) The term "Weight" refers to a numeric quality assigned to a
- Route as per the DUNDi protocol specification. The current
- Weight definitions are shown in Exhibit A.
-
- 1. PEERING. The undersigned Participants agree to Propagate Routes
-with each other and any other member of the Peering System and further
-agree not to Propagate DUNDi Routes with a third party unless they have
-first have executed this GPA (in its unmodified form) with such third
-party. The Participants further agree only to Propagate Routes with
-Participants whom they reasonably believe to be honoring the terms of
-the GPA. Participants may not insert, remove, amend, or otherwise
-modify any of the terms of the GPA.
-
- 2. ACCEPTABLE USE POLICY. The DUNDi protocol contains information
-that reflect a Subscriber's or Egress Gateway's decisions to receive
-calls. In addition to the terms and conditions set forth in this GPA,
-the Participants agree to honor the intent of restrictions encoded in
-the DUNDi protocol. To that end, Participants agree to the following:
-
- (a) A Participant may not utilize or permit the utilization of
- Routes for which the Subscriber or Egress Gateway provider has
- indicated that they do not wish to receive "Unsolicited Calls"
- for the purpose of making an unsolicited phone call on behalf of
- any party or organization.
-
- (b) A Participant may not utilize or permit the utilization of
- Routes which have indicated that they do not wish to receive
- "Unsolicited Commercial Calls" for the purpose of making an
- unsolicited phone call on behalf of a commercial organization.
-
- (c) A Participant may never utilize or permit the utilization of any
- DUNDi route for the purpose of making harassing phone calls.
-
- (d) A Party may not utilize or permit the utilization of DUNDi
- provided Routes for any systematic or random calling of numbers
- (e.g., for the purpose of locating facsimile, modem services, or
- systematic telemarketing).
-
- (e) Initial control signaling for all communication sessions that
- utilize Routes obtained from the Peering System must be sent
- from a member of the Peering System to the Service or Egress
- Gateway identified in the selected Route. For example, 'SIP
- INVITES' and IAX2 "NEW" commands must be sent from the
- requesting DUNDi node to the terminating Service.
-
- (f) A Participant may not disclose any specific Route, Service or
- Participant contact information obtained from the Peering System
- to any party outside of the Peering System except as a
- by-product of facilitating communication in accordance with
- section 2e (e.g., phone books or other databases may not be
- published, but the Internet addresses of the Egress Gateway or
- Service does not need to be obfuscated.)
-
- (g) The DUNDi Protocol requires that each Participant include valid
- contact information about itself (including information about
- nodes connected to each Participant). Participants may use or
- disclose the contact information only to ensure enforcement of
- legal furtherance of this Agreement.
-
- 3. ROUTES. The Participants shall only propagate valid Routes, as
-defined herein, through the Peering System, regardless of the original
-source. The Participants may only provide Routes as set forth below,
-and then only if such Participant has no good faith reason to believe
-such Route to be invalid or unauthorized.
-
- (a) A Participant may provide Routes if each Route has as its
- original source another member of the Peering System who has
- duly executed the GPA and such Routes are provided in accordance
- with this Agreement; provided that the Routes are not modified
- (e.g., with regards to existence, destination, technology or
- Weight); or
-
- (b) A Participant may provide Routes for Services with any Weight
- for which it is the Subscriber; or
-
- (c) A Participant may provide Routes for those Services whose
- Subscriber has authorized the Participant to do so, provided
- that the Participant is able to confirm that the Authorizing
- Individual is the Subscriber through:
-
- i. a written statement of ownership from the Authorizing
- Individual, which the Participant believes in good faith
- to be accurate (e.g., a phone bill with the name of the
- Authorizing Individual and the number in question); or
-
- ii. the Participant's own direct personal knowledge that the
- Authorizing Individual is the Subscriber.
-
- (d) A Participant may provide Routes for Services, with Weight in
- accordance with the Current DUNDi Specification, if it can in
- good faith provide an Egress Gateway to that Service on the
- traditional telephone network without cost to the calling party.
-
- 4. REVOCATION. A Participant must provide a free, easily accessible
-mechanism by which a Subscriber may revoke permission to act as a Route
-Authority for his Service. A Participant must stop acting as a Route
-Authority for that Service within 7 days after:
-
- (a) receipt of a revocation request;
-
- (b) receiving other notice that the Service is no longer valid; or
-
- (c) determination that the Subscriber's information is no longer
- accurate (including that the Subscriber is no longer the service
- owner or the service owner's authorized delegate).
-
- 5. SERVICE FEES. A Participant may charge a fee to act as a Route
-Authority for a Service, with any Weight, provided that no Participant
-may charge a fee to propagate the Route received through the Peering
-System.
-
- 6. TOLL SERVICES. No Participant may provide Routes for any Services
-that require payment from the calling party or their customer for
-communication with the Service. Nothing in this section shall prohibit
-a Participant from providing routes for Services where the calling party
-may later enter into a financial transaction with the called party
-(e.g., a Participant may provide Routes for calling cards services).
-
- 7. QUALITY. A Participant may not intentionally impair communication
-using a Route provided to the Peering System (e.g. by adding delay,
-advertisements, reduced quality). If for any reason a Participant is
-unable to deliver a call via a Route provided to the Peering System,
-that Participant shall return out-of-band Network Congestion
-notification (e.g. "503 Service Unavailable" with SIP protocol or
-"CONGESTION" with IAX protocol).
-
- 8. PROTOCOL COMPLIANCE. Participants agree to Propagate Routes in
-strict compliance with current DUNDi protocol specifications.
-
- 9. ADMINISTRATIVE FEES. A Participant may charge (but is not required
-to charge) another Participant a reasonable fee to cover administrative
-expenses incurred in the execution of this Agreement. A Participant may
-not charge any fee to continue the relationship or to provide Routes to
-another Participant in the Peering System.
-
- 10. CALLER IDENTIFICATION. A Participant will make a good faith effort
-to ensure the accuracy and appropriate nature of any caller
-identification that it transmits via any Route obtained from the Peering
-System. Caller identification shall at least be provided as a valid
-E.164 number.
-
- 11. COMPLIANCE WITH LAWS. The Participants are solely responsible for
-determining to what extent, if any, the obligations set forth in this
-GPA conflict with any laws or regulations their region. A Participant
-may not provide any service or otherwise use DUNDi under this GPA if
-doing so is prohibited by law or regulation, or if any law or regulation
-imposes requirements on the Participant that are inconsistent with the
-terms of this GPA or the Acceptable Use Policy.
-
- 12. WARRANTY. EACH PARTICIPANT WARRANTS TO THE OTHER PARTICIPANTS THAT
-IT MADE, AND WILL CONTINUE TO MAKE, A GOOD FAITH EFFORT TO AUTHENTICATE
-OTHERS IN THE PEERING SYSTEM AND TO PROVIDE ACCURATE INFORMATION IN
-ACCORDANCE WITH THE TERMS OF THIS GPA. THIS WARRANTY IS MADE BETWEEN
-THE PARTICIPANTS, AND THE PARTICIPANTS MAY NOT EXTEND THIS WARRANTY TO
-ANY NON-PARTICIPANT INCLUDING END-USERS.
-
- 13. DISCLAIMER OF WARRANTIES. THE PARTICIPANTS UNDERSTAND AND AGREE
-THAT ANY SERVICE PROVIDED AS A RESULT OF THIS GPA IS "AS IS." EXCEPT FOR
-THOSE WARRANTIES OTHERWISE EXPRESSLY SET FORTH HEREIN, THE PARTICIPANTS
-DISCLAIM ANY REPRESENTATIONS OR WARRANTIES OF ANY KIND OR NATURE,
-EXPRESS OR IMPLIED, AS TO THE CONDITION, VALUE OR QUALITIES OF THE
-SERVICES PROVIDED HEREUNDER, AND SPECIFICALLY DISCLAIM ANY
-REPRESENTATION OR WARRANTY OF MERCHANTABILITY, SUITABILITY OR FITNESS
-FOR A PARTICULAR PURPOSE OR AS TO THE CONDITION OR WORKMANSHIP THEREOF,
-OR THE ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT,
-INCLUDING ANY WARRANTIES ARISING FROM A COURSE OF DEALING, USAGE OR
-TRADE PRACTICE. EXCEPT AS EXPRESSLY PROVIDED HEREIN, THE PARTICIPANTS
-EXPRESSLY DISCLAIM ANY REPRESENTATIONS OR WARRANTIES THAT THE PEERING
-SERVICE WILL BE CONTINUOUS, UNINTERRUPTED OR ERROR-FREE, THAT ANY DATA
-SHARED OR OTHERWISE MADE AVAILABLE WILL BE ACCURATE OR COMPLETE OR
-OTHERWISE COMPLETELY SECURE FROM UNAUTHORIZED ACCESS.
-
- 14. LIMITATION OF LIABILITIES. NO PARTICIPANT SHALL BE LIABLE TO ANY
-OTHER PARTICIPANT FOR INCIDENTAL, INDIRECT, CONSEQUENTIAL, SPECIAL,
-PUNITIVE OR EXEMPLARY DAMAGES OF ANY KIND (INCLUDING LOST REVENUES OR
-PROFITS, LOSS OF BUSINESS OR LOSS OF DATA) IN ANY WAY RELATED TO THIS
-GPA, WHETHER IN CONTRACT OR IN TORT, REGARDLESS OF WHETHER SUCH
-PARTICIPANT WAS ADVISED OF THE POSSIBILITY THEREOF.
-
- 15. END-USER AGREEMENTS. The Participants may independently enter
-into agreements with end-users to provide certain services (e.g., fees
-to a Subscriber to originate Routes for that Service). To the extent
-that provision of these services employs the Peering System, the Parties
-will include in their agreements with their end-users terms and
-conditions consistent with the terms of this GPA with respect to the
-exclusion of warranties, limitation of liability and Acceptable Use
-Policy. In no event may a Participant extend the warranty described in
-Section 12 in this GPA to any end-users.
-
- 16. INDEMNIFICATION. Each Participant agrees to defend, indemnify and
-hold harmless the other Participant or third-party beneficiaries to this
-GPA (including their affiliates, successors, assigns, agents and
-representatives and their respective officers, directors and employees)
-from and against any and all actions, suits, proceedings,
-investigations, demands, claims, judgments, liabilities, obligations,
-liens, losses, damages, expenses (including, without limitation,
-attorneys' fees) and any other fees arising out of or relating to (i)
-personal injury or property damage caused by that Participant, its
-employees, agents, servants, or other representatives; (ii) any act or
-omission by the Participant, its employees, agents, servants or other
-representatives, including, but not limited to, unauthorized
-representations or warranties made by the Participant; or (iii) any
-breach by the Participant of any of the terms or conditions of this GPA.
-
- 17. THIRD PARTY BENEFICIARIES. This GPA is intended to benefit those
-Participants who have executed the GPA and who are in the Peering
-System. It is the intent of the Parties to this GPA to give to those
-Participants who are in the Peering System standing to bring any
-necessary legal action to enforce the terms of this GPA.
-
- 18. TERMINATION. Any Participant may terminate this GPA at any time,
-with or without cause. A Participant that terminates must immediately
-cease to Propagate.
-
- 19. CHOICE OF LAW. This GPA and the rights and duties of the Parties
-hereto shall be construed and determined in accordance with the internal
-laws of the State of New York, United States of America, without regard
-to its conflict of laws principles and without application of the United
-Nations Convention on Contracts for the International Sale of Goods.
-
- 20. DISPUTE RESOLUTION. Unless otherwise agreed in writing, the
-exclusive procedure for handling disputes shall be as set forth herein.
-Notwithstanding such procedures, any Participant may, at any time, seek
-injunctive relief in addition to the process described below.
-
- (a) Prior to mediation or arbitration the disputing Participants
- shall seek informal resolution of disputes. The process shall be
- initiated with written notice of one Participant to the other
- describing the dispute with reasonable particularity followed
- with a written response within ten (10) days of receipt of
- notice. Each Participant shall promptly designate an executive
- with requisite authority to resolve the dispute. The informal
- procedure shall commence within ten (10) days of the date of
- response. All reasonable requests for non-privileged information
- reasonably related to the dispute shall be honored. If the
- dispute is not resolved within thirty (30) days of commencement
- of the procedure either Participant may proceed to mediation or
- arbitration pursuant to the rules set forth in (b) or (c) below.
-
- (b) If the dispute has not been resolved pursuant to (a) above or,
- if the disputing Participants fail to commence informal dispute
- resolution pursuant to (a) above, either Participant may, in
- writing and within twenty (20) days of the response date noted
- in (a) above, ask the other Participant to participate in a one
- (1) day mediation with an impartial mediator, and the other
- Participant shall do so. Each Participant will bear its own
- expenses and an equal share of the fees of the mediator. If the
- mediation is not successful the Participants may proceed with
- arbitration pursuant to (c) below.
-
- (c) If the dispute has not been resolved pursuant to (a) or (b)
- above, the dispute shall be promptly referred, no later than one
- (1) year from the date of original notice and subject to
- applicable statute of limitations, to binding arbitration in
- accordance with the UNCITRAL Arbitration Rules in effect on the
- date of this contract. The appointing authority shall be the
- International Centre for Dispute Resolution. The case shall be
- administered by the International Centre for Dispute Resolution
- under its Procedures for Cases under the UNCITRAL Arbitration
- Rules. Each Participant shall bear its own expenses and shall
- share equally in fees of the arbitrator. All arbitrators shall
- have substantial experience in information technology and/or in
- the telecommunications business and shall be selected by the
- disputing participants in accordance with UNCITRAL Arbitration
- Rules. If any arbitrator, once selected is unable or unwilling
- to continue for any reason, replacement shall be filled via the
- process described above and a re-hearing shall be conducted. The
- disputing Participants will provide each other with all
- requested documents and records reasonably related to the
- dispute in a manner that will minimize the expense and
- inconvenience of both parties. Discovery will not include
- depositions or interrogatories except as the arbitrators
- expressly allow upon a showing of need. If disputes arise
- concerning discovery requests, the arbitrators shall have sole
- and complete discretion to resolve the disputes. The parties and
- arbitrator shall be guided in resolving discovery disputes by
- the Federal Rules of Civil Procedure. The Participants agree
- that time of the essence principles shall guide the hearing and
- that the arbitrator shall have the right and authority to issue
- monetary sanctions in the event of unreasonable delay. The
- arbitrator shall deliver a written opinion setting forth
- findings of fact and the rationale for the award within thirty
- (30) days following conclusion of the hearing. The award of the
- arbitrator, which may include legal and equitable relief, but
- which may not include punitive damages, will be final and
- binding upon the disputing Participants, and judgment may be
- entered upon it in accordance with applicable law in any court
- having jurisdiction thereof. In addition to award the
- arbitrator shall have the discretion to award the prevailing
- Participant all or part of its attorneys' fees and costs,
- including fees associated with arbitrator, if the arbitrator
- determines that the positions taken by the other Participant on
- material issues of the dispute were without substantial
- foundation. Any conflict between the UNCITRAL Arbitration Rules
- and the provisions of this GPA shall be controlled by this GPA.
-
- 21. INTEGRATED AGREEMENT. This GPA, constitutes the complete
-integrated agreement between the parties concerning the subject matter
-hereof. All prior and contemporaneous agreements, understandings,
-negotiations or representations, whether oral or in writing, relating to
-the subject matter of this GPA are superseded and canceled in their
-entirety.
-
- 22. WAIVER. No waiver of any of the provisions of this GPA shall be
-deemed or shall constitute a waiver of any other provision of this GPA,
-whether or not similar, nor shall such waiver constitute a continuing
-waiver unless otherwise expressly so provided in writing. The failure
-of either party to enforce at any time any of the provisions of this
-GPA, or the failure to require at any time performance by either party
-of any of the provisions of this GPA, shall in no way be construed to be
-a present or future waiver of such provisions, nor in any way affect the
-ability of a Participant to enforce each and every such provision
-thereafter.
-
- 23. INDEPENDENT CONTRACTORS. Nothing in this GPA shall make the
-Parties partners, joint venturers, or otherwise associated in or with
-the business of the other. Parties are, and shall always remain,
-independent contractors. No Participant shall be liable for any debts,
-accounts, obligations, or other liabilities of the other Participant,
-its agents or employees. No party is authorized to incur debts or other
-obligations of any kind on the part of or as agent for the other. This
-GPA is not a franchise agreement and does not create a franchise
-relationship between the parties, and if any provision of this GPA is
-deemed to create a franchise between the parties, then this GPA shall
-automatically terminate.
-
- 24. CAPTIONS AND HEADINGS. The captions and headings used in this GPA
-are used for convenience only and are not to be given any legal effect.
-
- 25. EXECUTION. This GPA may be executed in counterparts, each of which
-so executed will be deemed to be an original and such counterparts
-together will constitute one and the same Agreement. The Parties shall
-transmit to each other a signed copy of the GPA by any means that
-faithfully reproduces the GPA along with the Signature. For purposes of
-this GPA, the term "signature" shall include digital signatures as
-defined by the jurisdiction of the Participant signing the GPA.
-
- Exhibit A
-
-Weight Range Requirements
-
-0-99 May only be used under authorization of Owner
-
-100-199 May only be used by the Owner's service
- provider, regardless of authorization.
-
-200-299 Reserved -- do not use for e164 context.
-
-300-399 May only be used by the owner of the code under
- which the Owner's number is a part of.
-
-400-499 May be used by any entity providing access via
- direct connectivity to the Public Switched
- Telephone Network.
-
-500-599 May be used by any entity providing access via
- indirect connectivity to the Public Switched
- Telephone Network (e.g. Via another VoIP
- provider)
-
-600- Reserved-- do not use for e164 context.
-
- Participant Participant
-
-Company:
-
-Address:
-
-Email:
-
-
- _________________________ _________________________
- Authorized Signature Authorized Signature
-
-Name:
-
-
-END OF GENERAL PEERING AGREEMENT
-
-------------------------------------------------
-
-How to Peer using this GPA If you wish to exchange routing information
-with parties using the e164 DUNDi context, all you must do is execute
-this GPA with any member of the Peering System and you will become a
-member of the Peering System and be able to make Routes available in
-accordance with this GPA.
-
-DUNDi, IAX, Asterisk and GPA are trademarks of Digium, Inc.
diff --git a/1.4/doc/ael.txt b/1.4/doc/ael.txt
deleted file mode 100644
index f72f2805b..000000000
--- a/1.4/doc/ael.txt
+++ /dev/null
@@ -1,1260 +0,0 @@
-The Asterisk Extension Language - v 2
-=====================================
-
-AEL is a specialized language intended purely for
-describing Asterisk dial plans.
-
-The current version was written by Steve Murphy, and is a rewrite of
-the original version.
-
-This new version further extends AEL, and
-provides more flexible syntax, better error messages, and some missing
-functionality.
-
-AEL is really the merger of 4 different 'languages', or syntaxes:
-
- * The first and most obvious is the AEL syntax itself. A BNF is
- provided near the end of this document.
-
- * The second syntax is the Expression Syntax, which is normally
- handled by Asterisk extension engine, as expressions enclosed in
- $[...]. The right hand side of assignments are wrapped in $[ ... ]
- by AEL, and so are the if and while expressions, among others.
-
- * The third syntax is the Variable Reference Syntax, the stuff
- enclosed in ${..} curly braces. It's a bit more involved than just
- putting a variable name in there. You can include one of dozens of
- 'functions', and their arguments, and there are even some string
- manipulation notation in there.
-
- * The last syntax that underlies AEL, and is not used
- directly in AEL, is the Extension Language Syntax. The
- extension language is what you see in extensions.conf, and AEL
- compiles the higher level AEL language into extensions and
- priorities, and passes them via function calls into
- Asterisk. Embedded in this language is the Application/AGI
- commands, of which one application call per step, or priority
- can be made. You can think of this as a "macro assembler"
- language, that AEL will compile into.
-
-
-Any programmer of AEL should be familiar with it's syntax, of course,
-as well as the Expression syntax, and the Variable syntax.
-
-**************************
-* Asterisk in a Nutshell *
-**************************
-
-Asterisk acts as a server. Devices involved in telephony, like Zapata
-cards, or Voip phones, all indicate some context that should be
-activated in their behalf. See the config file formats for IAX, SIP,
-zapata.conf, etc. They all help describe a device, and they all
-specify a context to activate when somebody picks up a phone, or a
-call comes in from the phone company, or a voip phone, etc.
-
-Contexts
---------
-
-Contexts are a grouping of extensions.
-
-Contexts can also include other contexts. Think of it as a sort of
-merge operation at runtime, whereby the included context's extensions
-are added to the contexts making the inclusion.
-
-Extensions and priorities
--------------------------
-
-A Context contains zero or more Extensions. There are several
-predefined extensions. The "s" extension is the "start" extension, and
-when a device activates a context the "s" extension is the one that is
-going to be run. Other extensions are the timeout "t" extension, the
-invalid response, or "i" extension, and there's a "fax" extension. For
-instance, a normal call will activate the "s" extension, but an
-incoming FAX call will come into the "fax" extension, if it
-exists. (BTW, asterisk can tell it's a fax call by the little "beep"
-that the calling fax machine emits every so many seconds.).
-
-Extensions contain several priorities, which are individual
-instructions to perform. Some are as simple as setting a variable to a
-value. Others are as complex as initiating the Voicemail application,
-for instance. Priorities are executed in order.
-
-When the 's" extension completes, asterisk waits until the timeout for
-a response. If the response matches an extension's pattern in the
-context, then control is transferred to that extension. Usually the
-responses are tones emitted when a user presses a button on their
-phone. For instance, a context associated with a desk phone might not
-have any "s" extension. It just plays a dialtone until someone starts
-hitting numbers on the keypad, gather the number, find a matching
-extension, and begin executing it. That extension might Dial out over
-a connected telephone line for the user, and then connect the two
-lines together.
-
-The extensions can also contain "goto" or "jump" commands to skip to
-extensions in other contexts. Conditionals provide the ability to
-react to different stimuli, and there you have it.
-
-Macros
-------
-
-Think of a macro as a combination of a context with one nameless
-extension, and a subroutine. It has arguments like a subroutine
-might. A macro call can be made within an extension, and the
-individual statements there are executed until it ends. At this point,
-execution returns to the next statement after the macro call. Macros
-can call other macros. And they work just like function calls.
-
-Applications
-------------
-
-Application calls, like "Dial()", or "Hangup()", or "Answer()", are
-available for users to use to accomplish the work of the
-dialplan. There are over 145 of them at the moment this was written,
-and the list grows as new needs and wants are uncovered. Some
-applications do fairly simple things, some provide amazingly complex
-services.
-
-Hopefully, the above objects will allow you do anything you need to in
-the Asterisk environment!
-
-
-*******************
-* Getting Started *
-*******************
-
-The AEL parser (pbx_ael.so) is completely separate from the module
-that parses extensions.conf (pbx_config.so). To use AEL, the only
-thing that has to be done is the module pbx_ael.so must be loaded by
-Asterisk. This will be done automatically if using 'autoload=yes' in
-/etc/asterisk/modules.conf. When the module is loaded, it will look
-for 'extensions.ael' in /etc/asterisk/. extensions.conf and
-extensions.ael can be used in conjunction with
-each other if that is what is desired. Some users may want to keep
-extensions.conf for the features that are configured in the 'general'
-section of extensions.conf.
-
-------------------------------
-- Reloading extensions.ael -
-------------------------------
-
-To reload extensions.ael, the following command can be issued at the
-CLI:
-
- *CLI> ael reload
-
-
-
-*************
-* Debugging *
-*************
-
-Right at this moment, the following commands are available, but do
-nothing:
-
-Enable AEL contexts debug
- *CLI> ael debug contexts
-
-Enable AEL macros debug
- *CLI> ael debug macros
-
-Enable AEL read debug
- *CLI> ael debug read
-
-Enable AEL tokens debug
- *CLI> ael debug tokens
-
-Disable AEL debug messages
- *CLI> ael no debug
-
-If things are going wrong in your dialplan, you can use the following
-facilities to debug your file:
-
-1. The messages log in /var/log/asterisk. (from the checks done at load time).
-2. the "show dialplan" command in asterisk
-3. the standalone executable, "aelparse" built in the utils/ dir in the source.
-
-
-*****************************
-* About "aelparse" *
-*****************************
-
-You can use the "aelparse" program to check your extensions.ael
-file before feeding it to asterisk. Wouldn't it be nice to eliminate
-most errors before giving the file to asterisk?
-
-aelparse is compiled in the utils directory of the asterisk release.
-It isn't installed anywhere (yet). You can copy it to your favorite
-spot in your PATH.
-
-aelparse has two optional arguments:
-
--d - Override the normal location of the config file dir, (usually
- /etc/asterisk), and use the current directory instead as the
- config file dir. Aelparse will then expect to find the file
- "./extensions.ael" in the current directory, and any included
- files in the current directory as well.
-
--n - don't show all the function calls to set priorities and contexts
- within asterisk. It will just show the errors and warnings from
- the parsing and semantic checking phases.
-
-
-******************************
-* General Notes about Syntax *
-******************************
-
-Note that the syntax and style are now a little more free-form. The
-opening '{' (curly-braces) do not have to be on the same line as the
-keyword that precedes them. Statements can be split across lines, as
-long as tokens are not broken by doing so. More than one statement can
-be included on a single line. Whatever you think is best!
-
-You can just as easily say,
-
-if(${x}=1) { NoOp(hello!); goto s|3; } else { NoOp(Goodbye!); goto s|12; }
-
-as you can say:
-
-if(${x}=1)
-{
- NoOp(hello!);
- goto s|3;
-}
-else
-{
- NoOp(Goodbye!);
- goto s|12;
-}
-
-or:
-
-if(${x}=1) {
- NoOp(hello!);
- goto s|3;
-} else {
- NoOp(Goodbye!);
- goto s|12;
-}
-
-or:
-
-if (${x}=1) {
- NoOp(hello!); goto s|3;
-} else {
- NoOp(Goodbye!); goto s|12;
-}
-
-or even:
-
-if
-(${x}=1)
-{
-NoOp(hello!);
-goto s|3;
-}
-else
-{
-NoOp(Goodbye!);
-goto s|12;
-}
-
-
-************
-* Keywords *
-************
-
-The AEL keywords are case-sensitive. If an application name and a
-keyword overlap, there is probably good reason, and you should
-consider replacing the application call with an AEL statement. If you
-do not wish to do so, you can still use the application, by using a
-capitalized letter somewhere in its name. In the Asterisk extension
-language, application names are NOT case-sensitive.
-
-The following are keywords in the AEL language:
-
- * abstract
- * context
- * macro
- * globals
- * ignorepat
- * switch
- * if
- * ifTime
- * else
- * random
- * goto
- * jump
- * return
- * break
- * continue
- * regexten
- * hint
- * for
- * while
- * case
- * pattern
- * default NOTE: the "default" keyword can be used as a context name,
- for those who would like to do so.
- * catch
- * switches
- * eswitches
- * includes
-
-
-
-
-
-Procedural Interface and Internals
-==================================
-
-AEL first parses the extensions.ael file into a memory structure representing the file.
-The entire file is represented by a tree of "pval" structures linked together.
-
-This tree is then handed to the semantic check routine.
-
-Then the tree is handed to the compiler.
-
-After that, it is freed from memory.
-
-A program could be written that could build a tree of pval structures, and
-a pretty printing function is provided, that would dump the data to a file,
-or the tree could be handed to the compiler to merge the data into the
-asterisk dialplan. The modularity of the design offers several opportunities
-for developers to simplify apps to generate dialplan data.
-
-
-
-=========================
- AEL version 2 BNF
-=========================
-
-
-
-(hopefully, something close to bnf).
-
-First, some basic objects
-
-------------------------
-
-<word> a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*
-
-<word3-list> a concatenation of up to 3 <word>s.
-
-<collected-word> all characters encountered until the character that follows the <collected-word> in the grammar.
-
--------------------------
-
-<file> :== <objects>
-
-<objects> :== <object>
- | <objects> <object>
-
-
-<object> :== <context>
- | <macro>
- | <globals>
- | ';'
-
-
-<context> :== 'context' <word> '{' <elements> '}'
- | 'context' <word> '{' '}'
- | 'context' 'default' '{' <elements> '}'
- | 'context' 'default' '{' '}'
- | 'abstract' 'context' <word> '{' <elements> '}'
- | 'abstract' 'context' <word> '{' '}'
- | 'abstract' 'context' 'default' '{' <elements> '}'
- | 'abstract' 'context' 'default' '{' '}'
-
-
-<macro> :== 'macro' <word> '(' <arglist> ')' '{' <macro_statements> '}'
- | 'macro' <word> '(' <arglist> ')' '{' '}'
- | 'macro' <word> '(' ')' '{' <macro_statements> '}'
- | 'macro' <word> '(' ')' '{' '}'
-
-
-<globals> :== 'globals' '{' <global_statements> '}'
- | 'globals' '{' '}'
-
-
-<global_statements> :== <global_statement>
- | <global_statements> <global_statement>
-
-
-<global_statement> :== <word> '=' <collected-word> ';'
-
-
-<arglist> :== <word>
- | <arglist> ',' <word>
-
-
-<elements> :== <element>
- | <elements> <element>
-
-
-<element> :== <extension>
- | <includes>
- | <switches>
- | <eswitches>
- | <ignorepat>
- | <word> '=' <collected-word> ';'
- | ';'
-
-
-<ignorepat> :== 'ignorepat' '=>' <word> ';'
-
-
-<extension> :== <word> '=>' <statement>
- | 'regexten' <word> '=>' <statement>
- | 'hint' '(' <word3-list> ')' <word> '=>' <statement>
- | 'regexten' 'hint' '(' <word3-list> ')' <word> '=>' <statement>
-
-
-<statements> :== <statement>
- | <statements> <statement>
-
-<if_head> :== 'if' '(' <collected-word> ')'
-
-<random_head> :== 'random' '(' <collected-word> ')'
-
-<ifTime_head> :== 'ifTime' '(' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
- | 'ifTime' '(' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
-
-
-<word3-list> :== <word>
- | <word> <word>
- | <word> <word> <word>
-
-<switch_head> :== 'switch' '(' <collected-word> ')' '{'
-
-
-<statement> :== '{' <statements> '}'
- | <word> '=' <collected-word> ';'
- | 'goto' <target> ';'
- | 'jump' <jumptarget> ';'
- | <word> ':'
- | 'for' '(' <collected-word> ';' <collected-word> ';' <collected-word> ')' <statement>
- | 'while' '(' <collected-word> ')' <statement>
- | <switch_head> '}'
- | <switch_head> <case_statements> '}'
- | '&' macro_call ';'
- | <application_call> ';'
- | <application_call> '=' <collected-word> ';'
- | 'break' ';'
- | 'return' ';'
- | 'continue' ';'
- | <random_head> <statement>
- | <random_head> <statement> 'else' <statement>
- | <if_head> <statement>
- | <if_head> <statement> 'else' <statement>
- | <ifTime_head> <statement>
- | <ifTime_head> <statement> 'else' <statement>
- | ';'
-
-<target> :== <word>
- | <word> '|' <word>
- | <word> '|' <word> '|' <word>
- | 'default' '|' <word> '|' <word>
- | <word> ',' <word>
- | <word> ',' <word> ',' <word>
- | 'default' ',' <word> ',' <word>
-
-<jumptarget> :== <word>
- | <word> ',' <word>
- | <word> ',' <word> '@' <word>
- | <word> '@' <word>
- | <word> ',' <word> '@' 'default'
- | <word> '@' 'default'
-
-<macro_call> :== <word> '(' <eval_arglist> ')'
- | <word> '(' ')'
-
-<application_call_head> :== <word> '('
-
-<application_call> :== <application_call_head> <eval_arglist> ')'
- | <application_call_head> ')'
-
-<eval_arglist> :== <collected-word>
- | <eval_arglist> ',' <collected-word>
- | /* nothing */
- | <eval_arglist> ',' /* nothing */
-
-<case_statements> :== <case_statement>
- | <case_statements> <case_statement>
-
-
-<case_statement> :== 'case' <word> ':' <statements>
- | 'default' ':' <statements>
- | 'pattern' <word> ':' <statements>
- | 'case' <word> ':'
- | 'default' ':'
- | 'pattern' <word> ':'
-
-<macro_statements> :== <macro_statement>
- | <macro_statements> <macro_statement>
-
-<macro_statement> :== <statement>
- | 'catch' <word> '{' <statements> '}'
-
-<switches> :== 'switches' '{' <switchlist> '}'
- | 'switches' '{' '}'
-
-<eswitches> :== 'eswitches' '{' <switchlist> '}'
- | 'eswitches' '{' '}'
-
-<switchlist> :== <word> ';'
- | <switchlist> <word> ';'
-
-<includeslist> :== <includedname> ';'
- | <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
- | <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
- | <includeslist> <includedname> ';'
- | <includeslist> <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
- | <includeslist> <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
-
-<includedname> :== <word>
- | 'default'
-
-<includes> :== 'includes' '{' <includeslist> '}'
- | 'includes' '{' '}'
-
-
-**************************
-* AEL Example USAGE *****
-**************************
-
-Comments
-========
-
-Comments begin with // and end with the end of the line.
-
-Comments are removed by the lexical scanner, and will not be
-recognized in places where it is busy gathering expressions to wrap in
-$[] , or inside application call argument lists. The safest place to put
-comments is after terminating semicolons, or on otherwise empty lines.
-
-
-Context
-=======
-
-Contexts in AEL represent a set of extensions in the same way that
-they do in extensions.conf.
-
-
-context default {
-
-}
-
-
-A context can be declared to be "abstract", in which case, this
-declaration expresses the intent of the writer, that this context will
-only be included by another context, and not "stand on its own". The
-current effect of this keyword is to prevent "goto " statements from
-being checked.
-
-
-abstract context longdist {
- _1NXXNXXXXXX => NoOp(generic long distance dialing actions in the US);
-}
-
-
-
-Extensions
-==========
-
-To specify an extension in a context, the following syntax is used. If
-more than one application is be called in an extension, they can be
-listed in order inside of a block.
-
-
-context default {
- 1234 => Playback(tt-monkeys);
- 8000 => {
- NoOp(one);
- NoOp(two);
- NoOp(three);
- };
- _5XXX => NoOp(it's a pattern!);
-}
-
-
-Two optional items have been added to the AEL syntax, that allow the
-specification of hints, and a keyword, regexten, that will force the
-numbering of priorities to start at 2.
-
-The ability to make extensions match by CID is preserved in
-AEL; just use '/' and the CID number in the specification. See below.
-
-
-context default {
-
- regexten _5XXX => NoOp(it's a pattern!);
-}
-
-
-
-context default {
-
- hint(Sip/1) _5XXX => NoOp(it's a pattern!);
-}
-
-
-
-context default {
-
- regexten hint(Sip/1) _5XXX => NoOp(it's a pattern!);
-}
-
-
-The regexten must come before the hint if they are both present.
-
-CID matching is done as with the extensions.conf file. Follow the extension
-name/number with a slash (/) and the number to match against the Caller ID:
-
-context zoombo
-{
- 819/7079953345 => { NoOp(hello, 3345); }
-}
-
-In the above, the 819/7079953345 extension will only be matched if the
-CallerID is 7079953345, and the dialed number is 819. Hopefully you have
-another 819 extension defined for all those who wish 819, that are not so lucky
-as to have 7079953345 as their CallerID!
-
-
-Includes
-========
-
-Contexts can be included in other contexts. All included contexts are
-listed within a single block.
-
-
-context default {
- includes {
- local;
- longdistance;
- international;
- }
-}
-
-
-Time-limited inclusions can be specified, as in extensions.conf
-format, with the fields described in the wiki page Asterisk cmd
-GotoIfTime.
-
-
-context default {
- includes {
- local;
- longdistance|16:00-23:59|mon-fri|*|*;
- international;
- }
-}
-
-
-#include
-========
-
-You can include other files with the #include "filepath" construct.
-
-
- #include "/etc/asterisk/testfor.ael"
-
-
-An interesting property of the #include, is that you can use it almost
-anywhere in the .ael file. It is possible to include the contents of
-a file in a macro, context, or even extension. The #include does not
-have to occur at the beginning of a line. Included files can include
-other files, up to 50 levels deep. If the path provided in quotes is a
-relative path, the parser looks in the config file directory for the
-file (usually /etc/asterisk).
-
-
-
-Dialplan Switches
-=================
-
-Switches are listed in their own block within a context. For clues as
-to what these are used for, see Asterisk - dual servers, and Asterisk
-config extensions.conf.
-
-
-context default {
- switches {
- DUNDi/e164;
- IAX2/box5;
- };
- eswitches {
- IAX2/context@${CURSERVER};
- }
-}
-
-
-
-Ignorepat
-=========
-
-ignorepat can be used to instruct channel drivers to not cancel
-dialtone upon receipt of a particular pattern. The most commonly used
-example is '9'.
-
-
-context outgoing {
- ignorepat => 9;
-}
-
-
-
-
-Variables
-=========
-
-Variables in Asterisk do not have a type, so to define a variable, it
-just has to be specified with a value.
-
-Global variables are set in their own block.
-
-
-globals {
- CONSOLE=Console/dsp;
- TRUNK=Zap/g2;
-}
-
-
-
-Variables can be set within extensions as well.
-
-
-context foo {
- 555 => {
- x=5;
- y=blah;
- divexample=10/2
- NoOp(x is ${x} and y is ${y} !);
- }
-}
-
-
-NOTE: AEL wraps the right hand side of an assignment with $[ ] to allow
-expressions to be used If this is unwanted, you can protect the right hand
-side from being wrapped by using the Set() application.
-Read the README.variables about the requirements and behavior
-of $[ ] expressions.
-
-NOTE: These things are wrapped up in a $[ ] expression: The while() test;
-the if() test; the middle expression in the for( x; y; z) statement
-(the y expression); Assignments - the right hand side, so a = b -> Set(a=$[b])
-
-Writing to a dialplan function is treated the same as writing to a variable.
-
-
-context blah {
- s => {
- CALLERID(name)=ChickenMan;
- NoOp(My name is ${CALLERID(name)} !);
- }
-}
-
-
-
-Loops
-=====
-
-AEL has implementations of 'for' and 'while' loops.
-
-
-context loops {
- 1 => {
- for (x=0; ${x} < 3; x=${x} + 1) {
- Verbose(x is ${x} !);
- }
- }
- 2 => {
- y=10;
- while (${y} >= 0) {
- Verbose(y is ${y} !);
- y=${y}-1;
- }
- }
-}
-
-
-NOTE: The conditional expression (the "${y} >= 0" above) is wrapped in
- $[ ] so it can be evaluated. NOTE: The for loop test expression
- (the "${x} < 3" above) is wrapped in $[ ] so it can be evaluated.
-
-
-
-Conditionals
-============
-
-AEL supports if and switch statements, like AEL, but adds ifTime, and
-random. Unlike the original AEL, though, you do NOT need to put curly
-braces around a single statement in the "true" branch of an if(), the
-random(), or an ifTime() statement. The if(), ifTime(), and random()
-statements allow optional else clause.
-
-
-context conditional {
- _8XXX => {
- Dial(SIP/${EXTEN});
- if ("${DIALSTATUS}" = "BUSY")
- {
- NoOp(yessir);
- Voicemail(${EXTEN}|b);
- }
- else
- Voicemail(${EXTEN}|u);
- ifTime (14:00-25:00|sat-sun|*|*)
- Voicemail(${EXTEN}|b);
- else
- {
- Voicemail(${EXTEN}|u);
- NoOp(hi, there!);
- }
- random(51) NoOp(This should appear 51% of the time);
-
- random( 60 )
- {
- NoOp( This should appear 60% of the time );
- }
- else
- {
- random(75)
- {
- NoOp( This should appear 30% of the time! );
- }
- else
- {
- NoOp( This should appear 10% of the time! );
- }
- }
- }
- _777X => {
- switch (${EXTEN}) {
- case 7771:
- NoOp(You called 7771!);
- break;
- case 7772:
- NoOp(You called 7772!);
- break;
- case 7773:
- NoOp(You called 7773!);
- // fall thru-
- pattern 777[4-9]:
- NoOp(You called 777 something!);
- default:
- NoOp(In the default clause!);
- }
- }
-}
-
-
-NOTE: The conditional expression in if() statements (the
- "${DIALSTATUS}" = "BUSY" above) is wrapped by the compiler in
- $[] for evaluation.
-
-NOTE: Neither the switch nor case values are wrapped in $[ ]; they can
- be constants, or ${var} type references only.
-
-NOTE: AEL generates each case as a separate extension. case clauses
- with no terminating 'break', or 'goto', have a goto inserted, to
- the next clause, which creates a 'fall thru' effect.
-
-NOTE: AEL introduces the ifTime keyword/statement, which works just
- like the if() statement, but the expression is a time value,
- exactly like that used by the application GotoIfTime(). See
- Asterisk cmd GotoIfTime
-
-NOTE: The pattern statement makes sure the new extension that is
- created has an '_' preceding it to make sure asterisk recognizes
- the extension name as a pattern.
-
-NOTE: Every character enclosed by the switch expression's parenthesis
- are included verbatim in the labels generated. So watch out for
- spaces!
-
-NOTE: NEW: Previous to version 0.13, the random statement used the
- "Random()" application, which has been deprecated. It now uses
- the RAND() function instead, in the GotoIf application.
-
-
-Break, Continue, and Return
-===========================
-
-
-Three keywords, break, continue, and return, are included in the
-syntax to provide flow of control to loops, and switches.
-
-The break can be used in switches and loops, to jump to the end of the
-loop or switch.
-
-The continue can be used in loops (while and for) to immediately jump
-to the end of the loop. In the case of a for loop, the increment and
-test will then be performed. In the case of the while loop, the
-continue will jump to the test at the top of the loop.
-
-The return keyword will cause an immediate jump to the end of the
-context, or macro, and can be used anywhere.
-
-
-
-goto, jump, and labels
-======================
-
-This is an example of how to do a goto in AEL.
-
-
-context gotoexample {
- s => {
-begin:
- NoOp(Infinite Loop! yay!);
- Wait(1);
- goto begin; // go to label in same extension
- }
- 3 => {
- goto s|begin; // go to label in different extension
- }
- 4 => {
- goto gotoexample|s|begin; // overkill go to label in same context
- }
-}
-
-context gotoexample2 {
- s => {
- end:
- goto gotoexample|s|begin; // go to label in different context
- }
-}
-
-You can use the special label of "1" in the goto and jump
-statements. It means the "first" statement in the extension. I would
-not advise trying to use numeric labels other than "1" in goto's or
-jumps, nor would I advise declaring a "1" label anywhere! As a matter
-of fact, it would be bad form to declare a numeric label, and it might
-conflict with the priority numbers used internally by asterisk.
-
-The syntax of the jump statement is: jump
-extension[,priority][@context] If priority is absent, it defaults to
-"1". If context is not present, it is assumed to be the same as that
-which contains the "jump".
-
-
-context gotoexample {
- s => {
-begin:
- NoOp(Infinite Loop! yay!);
- Wait(1);
- jump s; // go to first extension in same extension
- }
- 3 => {
- jump s,begin; // go to label in different extension
- }
- 4 => {
- jump s,begin@gotoexample; // overkill go to label in same context
- }
-}
-
-context gotoexample2 {
- s => {
- end:
- jump s@gotoexample; // go to label in different context
- }
-}
-
-NOTE: goto labels follow the same requirements as the Goto()
- application, except the last value has to be a label. If the
- label does not exist, you will have run-time errors. If the
- label exists, but in a different extension, you have to specify
- both the extension name and label in the goto, as in: goto s|z;
- if the label is in a different context, you specify
- context|extension|label. There is a note about using goto's in a
- switch statement below...
-
-NOTE AEL introduces the special label "1", which is the beginning
- context number for most extensions.
-
-NOTE: A NEW addition to AEL: you can now use ',' instead of '|' to
- separate the items in the target address. You can't have a mix,
- though, of '|' and ',' in the target. It's either one, or the other.
-
-
-
-
-Macros
-======
-
-A macro is defined in its own block like this. The arguments to the
-macro are specified with the name of the macro. They are then referred
-to by that same name. A catch block can be specified to catch special
-extensions.
-
-
-macro std-exten( ext , dev ) {
- Dial(${dev}/${ext},20);
- switch(${DIALSTATUS) {
- case BUSY:
- Voicemail(b${ext});
- break;
- default:
- Voicemail(u${ext});
-
- }
- catch a {
- VoiceMailMain(${ext});
- return;
- }
-}
-
-
-A macro is then called by preceding the macro name with an
-ampersand. Empty arguments can be passed simply with nothing between
-comments(0.11).
-
-
-context example {
- _5XXX => &std-exten(${EXTEN}, "IAX2");
- _6XXX => &std-exten(, "IAX2");
- _7XXX => &std-exten(${EXTEN},);
- _8XXX => &std-exten(,);
-}
-
-
-
-Examples
-========
-
-
-context demo {
- s => {
- Wait(1);
- Answer();
- TIMEOUT(digit)=5;
- TIMEOUT(response)=10;
-restart:
- Background(demo-congrats);
-instructions:
- for (x=0; ${x} < 3; x=${x} + 1) {
- Background(demo-instruct);
- WaitExten();
- }
- }
- 2 => {
- Background(demo-moreinfo);
- goto s|instructions;
- }
- 3 => {
- LANGUAGE()=fr;
- goto s|restart;
- }
-
- 500 => {
- Playback(demo-abouttotry);
- Dial(IAX2/guest@misery.digium.com);
- Playback(demo-nogo);
- goto s|instructions;
- }
- 600 => {
- Playback(demo-echotest);
- Echo();
- Playback(demo-echodone);
- goto s|instructions;
- }
- # => {
-hangup:
- Playback(demo-thanks);
- Hangup();
- }
- t => goto #|hangup;
- i => Playback(invalid);
-}
-
-
-Semantic Checks
-===============
-
-
-AEL, after parsing, but before compiling, traverses the dialplan
-tree, and makes several checks:
-
- * Macro calls to non-existent macros.
- * Macro calls to contexts.
- * Macro calls with argument count not matching the definition.
- * application call to macro. (missing the '&')
- * application calls to "GotoIf", "GotoIfTime", "while",
- "endwhile", "Random", and "execIf", will generate a message to
- consider converting the call to AEL goto, while, etc. constructs.
- * goto a label in an empty extension.
- * goto a non-existent label, either a within-extension,
- within-context, or in a different context, or in any included
- contexts. Will even check "sister" context references.
- * All the checks done on the time values in the dial plan, are
- done on the time values in the ifTime() and includes times:
- o the time range has to have two times separated by a dash;
- o the times have to be in range of 0 to 24 hours.
- o The weekdays have to match the internal list, if they are provided;
- o the day of the month, if provided, must be in range of 1 to 31;
- o the month name or names have to match those in the internal list.
- * (0.5) If an expression is wrapped in $[ ... ], and the compiler
- will wrap it again, a warning is issued.
- * (0.5) If an expression had operators (you know,
- +,-,*,/,%,!,etc), but no ${ } variables, a warning is
- issued. Maybe someone forgot to wrap a variable name?
- * (0.12) check for duplicate context names.
- * (0.12) check for abstract contexts that are not included by any context.
- * (0.13) Issue a warning if a label is a numeric value.
-
-There are a subset of checks that have been removed until the proposed
-AAL (Asterisk Argument Language) is developed and incorporated into Asterisk.
-These checks will be:
-
- * (if the application argument analyzer is working: the presence
- of the 'j' option is reported as error.
- * if options are specified, that are not available in an
- application.
- * if you specify too many arguments to an application.
- * a required argument is not present in an application call.
- * Switch-case using "known" variables that applications set, that
- does not cover all the possible values. (a "default" case will
- solve this problem. Each "unhandled" value is listed.
- * a Switch construct is used, which is uses a known variable, and
- the application that would set that variable is not called in
- the same extension. This is a warning only...
- * Calls to applications not in the "applist" database (installed
- in /var/lib/asterisk/applist" on most systems).
- * In an assignment statement, if the assignment is to a function,
- the function name used is checked to see if it one of the
- currently known functions. A warning is issued if it is not.
-
-
-
-Differences with the original version of AEL
-============================================
-
- 1. The $[...] expressions have been enhanced to include the ==, ||,
- and && operators. These operators are exactly equivalent to the
- =, |, and & operators, respectively. Why? So the C, Java, C++
- hackers feel at home here.
- 2. It is more free-form. The newline character means very little,
- and is pulled out of the white-space only for line numbers in
- error messages.
- 3. It generates more error messages -- by this I mean that any
- difference between the input and the grammar are reported, by
- file, line number, and column.
- 4. It checks the contents of $[ ] expressions (or what will end up
- being $[ ] expressions!) for syntax errors. It also does
- matching paren/bracket counts.
- 5. It runs several semantic checks after the parsing is over, but
- before the compiling begins, see the list above.
- 6. It handles #include "filepath" directives. -- ALMOST
- anywhere, in fact. You could easily include a file in a context,
- in an extension, or at the root level. Files can be included in
- files that are included in files, down to 50 levels of hierarchy...
- 7. Local Goto's inside Switch statements automatically have the
- extension of the location of the switch statement appended to them.
- 8. A pretty printer function is available within pbx_ael.so.
- 9. In the utils directory, two standalone programs are supplied for
- debugging AEL files. One is called "aelparse", and it reads in
- the /etc/asterisk/extensions.ael file, and shows the results of
- syntax and semantic checking on stdout, and also shows the
- results of compilation to stdout. The other is "aelparse1",
- which uses the original ael compiler to do the same work,
- reading in "/etc/asterisk/extensions.ael", using the original
- 'pbx_ael.so' instead.
- 10. AEL supports the "jump" statement, and the "pattern" statement
- in switch constructs. Hopefully these will be documented in the
- AEL README.
- 11. Added the "return" keyword, which will jump to the end of an
- extension/Macro.
- 12. Added the ifTime (<time range>|<days of week>|<days of
- month>|<months> ) {} [else {}] construct, which executes much
- like an if () statement, but the decision is based on the
- current time, and the time spec provided in the ifTime. See the
- example above. (Note: all the other time-dependent Applications
- can be used via ifTime)
- 13. Added the optional time spec to the contexts in the includes
- construct. See examples above.
- 14. You don't have to wrap a single "true" statement in curly
- braces, as in the original AEL. An "else" is attached to the
- closest if. As usual, be careful about nested if statements!
- When in doubt, use curlies!
- 15. Added the syntax [regexten] [hint(channel)] to precede an
- extension declaration. See examples above, under
- "Extension". The regexten keyword will cause the priorities in
- the extension to begin with 2 instead of 1. The hint keyword
- will cause its arguments to be inserted in the extension under
- the hint priority. They are both optional, of course, but the
- order is fixed at the moment-- the regexten must come before the
- hint, if they are both present.
- 16. Empty case/default/pattern statements will "fall thru" as
- expected. (0.6)
- 17. A trailing label in an extension, will automatically have a
- NoOp() added, to make sure the label exists in the extension on
- Asterisk. (0.6)
- 18. (0.9) the semicolon is no longer required after a closing brace!
- (i.e. "];" ===> "}". You can have them there if you like, but
- they are not necessary. Someday they may be rejected as a syntax
- error, maybe.
- 19. (0.9) the // comments are not recognized and removed in the
- spots where expressions are gathered, nor in application call
- arguments. You may have to move a comment if you get errors in
- existing files.
- 20. (0.10) the random statement has been added. Syntax: random (
- <expr> ) <lucky-statement> [ else <unlucky-statement> ]. The
- probability of the lucky-statement getting executed is <expr>,
- which should evaluate to an integer between 0 and 100. If the
- <lucky-statement> isn't so lucky this time around, then the
- <unlucky-statement> gets executed, if it is present.
-
-
-
-Hints and Bugs
-==============
-
- * The safest way to check for a null strings is to say $[ "${x}" =
- "" ] The old way would do as shell scripts often do, and append
- something on both sides, like this: $[ ${x}foo = foo ]. The
- trouble with the old way, is that, if x contains any spaces, then
- problems occur, usually syntax errors. It is better practice and
- safer wrap all such tests with double quotes! Also, there are now
- some functions that can be used in a variable reference,
- ISNULL(), and LEN(), that can be used to test for an empty string:
- ${ISNULL(${x})} or $[ ${LEN(${x}) = 0 ].
-
- * Assignment vs. Set(). Keep in mind that setting a variable to
- value can be done two different ways. If you choose say 'x=y;',
- keep in mind that AEL will wrap the right-hand-side with
- $[]. So, when compiled into extension language format, the end
- result will be 'Set(x=$[y])'. If you don't want this effect,
- then say "Set(x=y);" instead.
-
-
-The Full Power of AEL
-==============================
-
-A newcomer to Asterisk will look at the above constructs and
-descriptions, and ask, "Where's the string manipulation functions?",
-"Where's all the cool operators that other languages have to offer?",
-etc.
-
-The answer is that the rich capabilities of Asterisk are made
-available through AEL, via:
-
- * Applications: See Asterisk - documentation of application
- commands
-
- * Functions: Functions were implemented inside ${ .. } variable
- references, and supply many useful capabilities.
-
- * Expressions: An expression evaluation engine handles items
- wrapped inside $[...]. This includes some string manipulation
- facilities, arithmetic expressions, etc.
-
- * Application Gateway Interface: Asterisk can fork external
- processes that communicate via pipe. AGI applications can be
- written in any language. Very powerful applications can be added
- this way.
-
- * Variables: Channels of communication have variables associated
- with them, and asterisk provides some global variables. These can be
- manipulated and/or consulted by the above mechanisms.
-
diff --git a/1.4/doc/ajam.txt b/1.4/doc/ajam.txt
deleted file mode 100644
index d3babd0c2..000000000
--- a/1.4/doc/ajam.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-Asynchronous Javascript Asterisk Manger (AJAM)
-==============================================
-
-AJAM is a new technology which allows web browsers or other HTTP enabled
-applications and web pages to directly access the Asterisk Manger
-Interface (AMI) via HTTP. Setting up your server to process AJAM
-involves a few steps:
-
-Setup the Asterisk HTTP server
-------------------------------
-
-1) Uncomment the line "enabled=yes" in /etc/asterisk/http.conf to enable
- Asterisk's builtin micro HTTP server.
-
-2) If you want Asterisk to actually deliver simple HTML pages, CSS,
- javascript, etc. you should uncomment "enablestatic=yes"
-
-3) Adjust your "bindaddr" and "bindport" settings as appropriate for
- your desired accessibility
-
-4) Adjust your "prefix" if appropriate, which must be the beginning of
- any URI on the server to match. The default is "asterisk" and the
- rest of these instructions assume that value.
-
-Allow Manager Access via HTTP
------------------------------
-
-1) Make sure you have both "enabled = yes" and "webenabled = yes" setup
- in /etc/asterisk/manager.conf
-
-2) You may also use "httptimeout" to set a default timeout for HTTP
- connections.
-
-3) Make sure you have a manager username/secret
-
-Once those configurations are complete you can reload or restart
-Asterisk and you should be able to point your web browser to specific
-URI's which will allow you to access various web functions. A complete
-list can be found by typing "show http" at the Asterisk CLI.
-
-examples:
-
-http://localhost:8088/asterisk/manager?action=login&username=foo&secret=bar
-
-This logs you into the manager interface's "HTML" view. Once you're
-logged in, Asterisk stores a cookie on your browser (valid for the
-length of httptimeout) which is used to connect to the same session.
-
-http://localhost:8088/asterisk/rawman?action=status
-
-Assuming you've already logged into manager, this URI will give you a
-"raw" manager output for the "status" command.
-
-http://localhost:8088/asterisk/mxml?action=status
-
-This will give you the same status view but represented as AJAX data,
-theoretically compatible with RICO (http://www.openrico.org).
-
-http://localhost:8088/asterisk/static/ajamdemo.html
-
-If you have enabled static content support and have done a make install,
-Asterisk will serve up a demo page which presents a live, but very
-basic, "astman" like interface. You can login with your username/secret
-for manager and have a basic view of channels as well as transfer and
-hangup calls. It's only tested in Firefox, but could probably be made
-to run in other browsers as well.
-
-A sample library (astman.js) is included to help ease the creation of
-manager HTML interfaces.
-
-Note that for the demo, there is no need for *any* external web server.
-
-Integration with other web servers
-----------------------------------
-
-Asterisk's micro HTTP server is *not* designed to replace a general
-purpose web server and it is intentionally created to provide only the
-minimal interfaces required. Even without the addition of an external
-web server, one can use Asterisk's interfaces to implement screen pops
-and similar tools pulling data from other web servers using iframes,
-div's etc. If you want to integrate CGI's, databases, PHP, etc. you
-will likely need to use a more traditional web server like Apache and
-link in your Asterisk micro HTTP server with something like this:
-
-ProxyPass /asterisk http://localhost:8088/asterisk
-
-This is a fairly new technology so I'd love to hear if it's useful for
-you!
-
-Mark
-
diff --git a/1.4/doc/app-sms.txt b/1.4/doc/app-sms.txt
deleted file mode 100644
index 308376e46..000000000
--- a/1.4/doc/app-sms.txt
+++ /dev/null
@@ -1,470 +0,0 @@
-
- * Application SMS
-
- The SMS module for Asterisk was developed by Adrian Kennard, and is an
- implementation of the ETSI specification for landline SMS, ETSI ES 201
- 912, which is available from www.etsi.org. Landline SMS is starting to
- be available in various parts of Europe, and is available from BT in
- the UK. However, Asterisk would allow gateways to be created in other
- locations such as the US, and use of SMS capable phones such as the
- Magic Messenger. SMS works using analogue or ISDN lines.
-
-Background
-
- Short Message Service (SMS), or texting is very popular between mobile
- phones. A message can be sent between two phones, and normally
- contains 160 characters. There are ways in which various types of data
- can be encoded in a text message such as ring tones, and small
- graphic, etc. Text messaging is being used for voting and
- competitions, and also SPAM...
- Sending a message involves the mobile phone contacting a message
- centre (SMSC) and passing the message to it. The message centre then
- contacts the destination mobile to deliver the message. The SMSC is
- responsible for storing the message and trying to send it until the
- destination mobile is available, or a timeout.
- Landline SMS works in basically the same way. You would normally have
- a suitable text capable landline phone, or a separate texting box such
- as a Magic Messenger on your phone line. This sends a message to a
- message centre your telco provides by making a normal call and sending
- the data using 1200 Baud FSK signaling according to the ETSI spec. To
- receive a message the message centre calls the line with a specific
- calling number, and the text capable phone answers the call and
- receives the data using 1200 Baud FSK signaling. This works
- particularly well in the UK as the calling line identity is sent
- before the first ring, so no phones in the house would ring when a
- message arrives.
-
-Typical use with Asterisk
-
- Sending messages from an Asterisk box can be used for a variety of
- reasons, including notification from any monitoring systems, email
- subject lines, etc.
- Receiving messages to an Asterisk box is typically used just to email
- the messages to someone appropriate - we email and texts that are
- received to our direct numbers to the appropriate person. Received
- messages could also be used to control applications, manage
- competitions, votes, post items to IRC, anything.
- Using a terminal such as a magic messenger, an Asterisk box could ask
- as a message centre sending messages to the terminal, which will beep
- and pop up the message (and remember 100 or so messages in its
- memory).
-
-Terminology
-
- SMS
- Short Message Service
- i.e. text messages
- SMSC
- Short Message Service Centre
- The system responsible for storing and forwarding messages
- MO
- Mobile Originated
- A message on its way from a mobile or landline device to the SMSC
- MT
- Mobile Terminated
- A message on its way from the SMSC to the mobile or landline device
- RX
- Receive
- A message coming in to the Asterisk box
- TX
- Transmit
- A message going out of the Asterisk box
-
-Sub address
-
- When sending a message to a landline, you simply send to the landline
- number. In the UK, all of the mobile operators (bar one) understand
- sending messages to landlines and pass the messages to the BTText
- system for delivery to the landline.
- The specification for landline SMS allows for the possibility of more
- than one device on a single landline. These can be configured with Sub
- addresses which are a single digit. To send a message to a specific
- device the message is sent to the landline number with an extra digit
- appended to the end. The telco can define a default sub address (9 in
- the UK) which is used when the extra digit is not appended to the end.
- When the call comes in, part of the calling line ID is the sub
- address, so that only one device on the line answers the call and
- receives the message.
- Sub addresses also work for outgoing messages. Part of the number
- called by the device to send a message is its sub address. Sending
- from the default sub address (9 in the UK) means the message is
- delivered with the sender being the normal landline number. Sending
- from any other sub address makes the sender the landline number with
- an extra digit on the end.
- Using Asterisk, you can make use of the sub addresses for sending and
- receiving messages. Using DDI (DID, i.e. multiple numbers on the line
- on ISDN) you can also make use of many different numbers for SMS.
-
-Build / installation
-
- app_sms.c is included in the Asterisk source apps directory and is
- included in the object list (app_sms.so) in apps/Makefile.
- smsq.c is a stand alone helper application which is used to send SMSs
- from the command line. It uses the popt library. A line for your make
- file is:-
-smsq: smsq.c
- cc -O -o smsq smsq.c -lpopt
-
-extensions.conf
-
- The following contexts are recommended.
-; Mobile Terminated, RX. This is used when an incoming call from the SMS arrive
-s, with the queue (called number and sub address) in ${EXTEN}
-; Running an app after receipt of the text allows the app to find all messages
-in the queue and handle them, e.g. email them.
-; The app may be something like smsq --process=somecommand --queue=${EXTEN}
-to run a command for each received message
-; See below for usage
-[smsmtrx]
-exten = _X.,1, SMS(${EXTEN}|a)
-exten = _X.,2,System("someapptohandleincomingsms ${EXTEN}")
-exten = _X.,3,Hangup
-; Mobile originated, RX. This is receiving a message from a device, e.g. a Magi
-c Messenger on a sip extension
-; Running an app after receipt of the text allows the app to find all messages
-in the queue and handle then, e.g. sending them to the public SMSC
-; The app may be something like smsq --process=somecommand --queue=${EXTEN}
-to run a command for each received message
-; See below for example usage
-[smsmorx]
-exten = _X.,1, SMS(${EXTEN}|sa)
-exten = _X.,2,System("someapptohandlelocalsms ${EXTEN}")
-exten = _X.,3,Hangup
-
- smsmtrx is normally accessed by an incoming call from the SMSC. In the
- UK this call is from a CLI of 080058752X0 where X is the sub address.
- As such a typical usage in the extensions.conf at the point of
- handling an incoming call is:-
-exten = _X./8005875290,1,Goto(smsmtrx,${EXTEN},1)
-exten = _X./_80058752[0-8]0,1,Goto(smsmtrx,${EXTEN}-${CALLERIDNUM:8:1},1)
-
- Alternatively, if you have the correct national prefix on incoming
- CLI, e.g. using zaphfc, you might use:-
-exten = _X./08005875290,1,Goto(smsmtrx,${EXTEN},1)
-exten = _X./_080058752[0-8]0,1,Goto(smsmtrx,${EXTEN}-${CALLERIDNUM:9:1},1)
-
- smsmorx is normally accessed by a call from a local sip device
- connected to a Magic Messenger. It could however by that you are
- operating Asterisk as a message centre for calls from outside. Either
- way, you look at the called number and goto smsmorx. In the UK, the
- SMSC number that would be dialed is 1709400X where X is the caller sub
- address. As such typical usage in extension.config at the point of
- handling a call from a sip phone is:-
-exten = 17094009,1,Goto(smsmorx,${CALLERIDNUM},1)
-exten = _1709400[0-8],1,Goto(smsmorx,${CALLERIDNUM}-{EXTEN:7:1},1)
-
-Using smsq
-
- smsq is a simple helper application designed to make it easy to send
- messages from a command line. it is intended to run on the Asterisk
- box and have direct access to the queue directories for SMS and for
- Asterisk.
- In its simplest form you can send an SMS by a command such as
- smsq 0123456789 This is a test to 0123456789
- This would create a queue file for a mobile originated TX message in
- queue 0 to send the text "This is a test to 0123456789" to 0123456789.
- It would then place a file in the /var/spool/asterisk/outgoing
- directory to initiate a call to 17094009 (the default message centre
- in smsq) attached to application SMS with argument of the queue name
- (0).
- Normally smsq will queue a message ready to send, and will then create
- a file in the Asterisk outgoing directory causing Asterisk to actually
- connect to the message centre or device and actually send the pending
- message(s).
- Using --process, smsq can however be used on received queues to run a
- command for each file (matching the queue if specified) with various
- environment variables set based on the message (see below);
- smsq options:-
-
- --help
- Show help text
- --usage
- Show usage
- --queue
- -q
- Specify a specific queue
- In no specified, messages are queued under queue "0"
- --da
- -d
- Specify destination address
- --oa
- -o
- Specify originating address
- This also implies that we are generating a mobile terminated message
- --ud
- -m
- Specify the actual message
- --ud-file
- -f
- Specify a file to be read for the context of the message
- A blank filename (e.g. --ud-file= on its own) means read stdin. Very
- useful when using via ssh where command line parsing could mess up the
- message.
- --mt
- -t
- Mobile terminated message to be generated
- --mo
- Mobile originated message to be generated
- Default
- --tx
- Transmit message
- Default
- --rx
- -r
- Generate a message in the receive queue
- --UTF-8
- Treat the file as UTF-8 encoded (default)
- --UCS-1
- Treat the file as raw 8 bit UCS-1 data, not UTF-8 encoded
- --UCS-2
- Treat the file as raw 16 bit bigendian USC-2 data
- --process
- Specific a command to process for each file in the queue
- Implies --rx and --mt if not otherwise specified.
- Sets environment variables for every possible variable, and also ud,
- ud8 (USC-1 hex), and ud16 (USC-2 hex) for each call. Removes files.
- --motx-channel
- Specify the channel for motx calls
- May contain X to use sub address based on queue name or may be full
- number
- Default is Local/1709400X
- --motx-callerid
- Specify the caller ID for motx calls
- The default is the queue name without -X suffix
- --motx-wait
- Wait time for motx call
- Default 10
- --motx-delay
- Retry time for motx call
- Default 1
- --motx-retries
- Retries for motx call
- Default 10
- --mttx-channel
- Specify the channel for mttx calls
- Default is Local/ and the queue name without -X suffix
- --mtttx-callerid
- Specify the callerid for mttx calls
- May include X to use sub address based on queue name or may be full
- number
- Default is 080058752X0
- --mttx-wait
- Wait time for mttx call
- Default 10
- --mttx-delay
- Retry time for mttx call
- Default 30
- --mttx-retries
- Retries for mttx call
- Default 100
- --default-sub-address
- The default sub address assumed (e.g. for X in CLI and dialled numbers
- as above) when none added (-X) to queue
- Default 9
- --no-dial
- -x
- Create queue, but do not dial to send message
- --no-wait
- Do not wait if a call appears to be in progress
- This could have a small window where a message is queued but not
- sent, so regular calls to smsq should be done to pick up any missed
- messages
- --concurrent
- How many concurrent calls to allow (per queue), default 1
- --mr
- -n
- Message reference
- --pid
- -p
- Protocol ID
- --dcs
- Data coding scheme
- --udh
- Specific hex string of user data header specified (not including the
- initial length byte)
- May be a blank string to indicate header is included in the user data
- already but user data header indication to be set.
- --srr
- Status report requested
- --rp
- Return path requested
- --vp
- Specify validity period (seconds)
- --scts
- Specify timestamp (YYYY-MM-DDTHH:MM:SS)
- --spool-dir
- Spool dir (in which sms and outgoing are found)
- Default /var/spool/asterisk
-
- Other arguments starting '-' or '--' are invalid and will cause an
- error. Any trailing arguments are processed as follows:-
- * If the message is mobile originating and no destination address
- has been specified, then the first argument is assumed to be a
- destination address
- * If the message is mobile terminating and no destination address
- has been specified, then the first argument is assumed to be the
- queue name
- * If there is no user data, or user data file specified, then any
- following arguments are assumed to be the message, which are
- concatenated.
- * If no user data is specified, then no message is sent. However,
- unless --no-dial is specified, smsq checks for pending messages
- and generates an outgoing anyway
-
- Note that when smsq attempts to make a file in
- /var/spool/asterisk/outgoing, it checks if there is already a call
- queued for that queue. It will try several filenames, up to the
- --concurrent setting. If these files exist, then this means Asterisk
- is already queued to send all messages for that queue, and so Asterisk
- should pick up the message just queued. However, this alone could
- create a race condition, so if the files exist then smsq will wait up
- to 3 seconds to confirm it still exists or if the queued messages have
- been sent already. The --no-wait turns off this behaviour. Basically,
- this means that if you have a lot of messages to send all at once,
- Asterisk will not make unlimited concurrent calls to the same message
- centre or device for the same queue. This is because it is generally
- more efficient to make one call and send all of the messages one after
- the other.
- smsq can be used with no arguments, or with a queue name only, and it
- will check for any pending messages and cause an outgoing if there are
- any. It only sets up one outgoing call at a time based on the first
- queued message it finds. A outgoing call will normally send all queued
- messages for that queue. One way to use smsq would be to run with no
- queue name (so any queue) every minute or every few seconds to send
- pending message. This is not normally necessary unless --no-dial is
- selected. Note that smsq does only check motx or mttx depending on the
- options selected, so it would need to be called twice as a general
- check.
- UTF-8 is used to parse command line arguments for user data, and is
- the default when reading a file. If an invalid UTF-8 sequence is
- found, it is treated as UCS-1 data (i.e, as is).
- The --process option causes smsq to scan the specified queue (default
- is mtrx) for messages (matching the queue specified, or any if queue
- not specified) and run a command and delete the file. The command is
- run with a number of environment variables set as follows. Note that
- these are unset if not needed and not just taken from the calling
- environment. This allows simple processing of incoming messages
-
- $queue
- Set if a queue specified
- $?srr
- srr is set (to blank) if srr defined and has value 1.
- $?rp
- rp is set (to blank) if rp defined and has value 1.
- $ud
- User data, UTF-8 encoding, including any control characters, but with
- nulls stripped out
- Useful for the content of emails, for example, as it includes any
- newlines, etc.
- $ude
- User data, escaped UTF-8, including all characters, but control
- characters \n, \r, \t, \f, \xxx and \ is escaped as \\
- Useful guaranteed one line printable text, so useful in Subject lines
- of emails, etc
- $ud8
- Hex UCS-1 coding of user data (2 hex digits per character)
- Present only if all user data is in range U+0000 to U+00FF
- $ud16
- Hex UCS-2 coding of user data (4 hex digits per character)
- other
- Other fields set using their field name, e.g. mr, pid, dcs, etc. udh
- is a hex byte string
-
-File formats
-
- By default all queues are held in a director /var/spool/asterisk/sms.
- Within this directory are sub directories mtrx, mttx, morx, motx which
- hold the received messages and the messages ready to send. Also,
- /var/log/asterisk/sms is a log file of all messages handled.
- The file name in each queue directory starts with the queue parameter
- to SMS which is normally the CLI used for an outgoing message or the
- called number on an incoming message, and may have -X (X being sub
- address) appended. If no queue ID is known, then 0 is used by smsq by
- default. After this is a dot, and then any text. Files are scanned for
- matching queue ID and a dot at the start. This means temporary files
- being created can be given a different name not starting with a queue
- (we recommend a . on the start of the file name for temp files).
- Files in these queues are in the form of a simple text file where each
- line starts with a keyword and an = and then data. udh and ud have
- options for hex encoding, see below.
- UTF-8. The user data (ud) field is treated as being UTF-8 encoded
- unless the DCS is specified indicating 8 bit format. If 8 bit format
- is specified then the user data is sent as is.
- The keywords are as follows:-
-
- oa Originating address
- The phone number from which the message came
- Present on mobile terminated messages and is the CLI for morx messages
- da
- Destination Address
- The phone number to which the message is sent
- Present on mobile originated messages
- scts
- The service centre time stamp
- Format YYYY-MM-DDTHH:MM:SS
- Present on mobile terminated messages
- pid
- One byte decimal protocol ID
- See GSM specs for more details
- Normally 0 or absent
- dcs
- One byte decimal data coding scheme
- If omitted, a sensible default is used (see below)
- See GSM specs for more details
- mr
- One byte decimal message reference
- Present on mobile originated messages, added by default if absent
- srr
- 0 or 1 for status report request
- Does not work in UK yet, not implemented in app_sms yet
- rp
- 0 or 1 return path
- See GSM specs for details
- vp
- Validity period in seconds
- Does not work in UK yet
- udh
- Hex string of user data header prepended to the SMS contents,
- excluding initial length byte.
- Consistent with ud, this is specified as udh# rather than udh=
- If blank, this means that the udhi flag will be set but any user data
- header must be in the ud field
- ud
- User data, may be text, or hex, see below
-
- udh is specified as as udh# followed by hex (2 hex digits per byte).
- If present, then the user data header indicator bit is set, and the
- length plus the user data header is added to the start of the user
- data, with padding if necessary (to septet boundary in 7 bit format).
- User data can hold an USC character codes U+0000 to U+FFFF. Any other
- characters are coded as U+FEFF
- ud can be specified as ud= followed by UTF-8 encoded text if it
- contains no control characters, i.e. only (U+0020 to U+FFFF). Any
- invalid UTF-8 sequences are treated as is (U+0080-U+00FF).
- ud can also be specified as ud# followed by hex (2 hex digits per
- byte) containing characters U+0000 to U+00FF only.
- ud can also be specified as ud## followed by hex (4 hex digits per
- byte) containing UCS-2 characters.
- When written by app_sms (e.g. incoming messages), the file is written
- with ud= if it can be (no control characters). If it cannot, the a
- comment line ;ud= is used to show the user data for human readability
- and ud# or ud## is used.
-
-Delivery reports
-
- The SMS specification allows for delivery reports. These are requested
- using the srr bit. However, as these do not work in the UK yet they
- are not fully implemented in this application. If anyone has a telco
- that does implement these, please let me know. BT in the UK have a non
- standard way to do this by starting the message with *0#, and so this
- application may have a UK specific bodge in the near future to handle
- these.
- The main changes that are proposed for delivery report handling are :-
- * New queues for sent messages, one file for each destination
- address and message reference.
- * New field in message format, user reference, allowing applications
- to tie up their original message with a report.
- * Handling of the delivery confirmation/rejection and connecting to
- the outgoing message - the received message file would then have
- fields for the original outgoing message and user reference
- allowing applications to handle confirmations better.
diff --git a/1.4/doc/apps.txt b/1.4/doc/apps.txt
deleted file mode 100644
index c9696a1a5..000000000
--- a/1.4/doc/apps.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Asterisk applications register themselves with ast_application_register.
-They should have a short, unique name, and an exec function which takes
-as its arguments a channel and some data that might be useful for callback
-stuff. Remember to keep track of how many and which channels are using
-your application so that should the module need to be unloaded
-(particularly force unloaded), you will be able to ast_softhangup all the
-channels. An application should *never* call ast_hangup on the channel
-that it is running on (although it could conceivably hang up other
-channels that it allocates). See app_playback.c as an example of a simple
-application.
diff --git a/1.4/doc/asterisk-conf.txt b/1.4/doc/asterisk-conf.txt
deleted file mode 100644
index 9b4fb3e8b..000000000
--- a/1.4/doc/asterisk-conf.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-Asterisk Main Configuration File
------------------------------------------------------
-Below is a sample of the main Asterisk configuration file,
-asterisk.conf. Note that this file is _not_ provided in
-sample form, because the Makefile creates it when needed
-and does not touch it when it already exists.
-
----------------
-
-[directories]
-; Make sure these directories have the right permissions if not
-; running Asterisk as root
-
-; Where the configuration files (except for this one) are located
-astetcdir => /etc/asterisk
-
-; Where the Asterisk loadable modules are located
-astmoddir => /usr/lib/asterisk/modules
-
-; Where additional 'library' elements (scripts, etc.) are located
-astvarlibdir => /var/lib/asterisk
-
-; Where AGI scripts/programs are located
-astagidir => /var/lib/asterisk/agi-bin
-
-; Where spool directories are located
-; Voicemail, monitor, dictation and other apps will create files here
-; and outgoing call files (used with pbx_spool) must be placed here
-astspooldir => /var/spool/asterisk
-
-; Where the Asterisk process ID (pid) file should be created
-astrundir => /var/run/asterisk
-
-; Where the Asterisk log files should be created
-astlogdir => /var/log/asterisk
-
-
-[options]
-;Under "options" you can enter configuration options
-;that you also can set with command line options
-
-verbose = 0 ; Verbosity level for logging (-v)
-debug = 3 ; Debug: "No" or value (1-4)
-nofork=yes | no ; Background execution disabled (-f)
-alwaysfork=yes | no ; Always background, even with -v or -d (-F)
-console= yes | no ; Console mode (-c)
-highpriority = yes | no ; Execute with high priority (-p)
-initcrypto = yes | no ; Initialize crypto at startup (-i)
-nocolor = yes | no ; Disable ANSI colors (-n)
-dumpcore = yes | no ; Dump core on failure (-g)
-quiet = yes | no ; Run quietly (-q)
-timestamp = yes | no ; Force timestamping in CLI verbose output (-T)
-runuser = asterisk ; User to run asterisk as (-U) NOTE: will require changes to
- ; directory and device permissions
-rungroup = asterisk ; Group to run asterisk as (-G)
-internal_timing = yes | no ; Enable internal timing support (-I)
-
-;These options have no command line equivalent
-cache_record_files = yes | no ; Cache record() files in another directory until completion
-record_cache_dir = <dir>
-transcode_via_sln = yes | no ; Build transcode paths via SLINEAR
-transmit_silence_during_record = yes | no ; send SLINEAR silence while channel is being recorded
-maxload = 1.0 ; The maximum load average we accept calls for
-maxcalls = 255 ; The maximum number of concurrent calls you want to allow
-execincludes = yes | no ; Allow #exec entries in configuration files
-dontwarn = yes | no ; Don't over-inform the Asterisk sysadm, he's a guru
-systemname = <a_string> ; System name. Used to prefix CDR uniqueid and to fill ${SYSTEMNAME}
-languageprefix = yes | no ; Should language code be last component of sound file name or first?
- ; when off, sound files are searched as <path>/<lang>/<file>
- ; when on, sound files are search as <lang>/<path>/<file>
- ; (only affects relative paths for sound files)
-
-[files]
-; Changing the following lines may compromise your security
-; Asterisk.ctl is the pipe that is used to connect the remote CLI
-; (asterisk -r) to Asterisk. Changing these settings change the
-; permissions and ownership of this file.
-; The file is created when Asterisk starts, in the "astrundir" above.
-
-;astctlpermissions = 0660
-;astctlowner = root
-;astctlgroup = asterisk
-;astctl = asterisk.ctl
diff --git a/1.4/doc/asterisk-mib.txt b/1.4/doc/asterisk-mib.txt
deleted file mode 100644
index 56b9be9d2..000000000
--- a/1.4/doc/asterisk-mib.txt
+++ /dev/null
@@ -1,739 +0,0 @@
-ASTERISK-MIB DEFINITIONS ::= BEGIN
-
-IMPORTS
- OBJECT-TYPE, MODULE-IDENTITY, Integer32, Counter32, TimeTicks
- FROM SNMPv2-SMI
-
- TEXTUAL-CONVENTION, DisplayString, TruthValue
- FROM SNMPv2-TC
-
- digium
- FROM DIGIUM-MIB;
-
-asterisk MODULE-IDENTITY
- LAST-UPDATED "200603061840Z"
- ORGANIZATION "Digium, Inc."
- CONTACT-INFO
- "Mark A. Spencer
- Postal: Digium, Inc.
- 445 Jan Davis Drive
- Huntsville, AL 35806
- USA
- Tel: +1 256 428 6000
- Email: markster@digium.com
-
- Thorsten Lockert
- Postal: Voop AS
- Boehmergaten 42
- NO-5057 Bergen
- Norway
- Tel: +47 5598 7200
- Email: tholo@voop.no"
- DESCRIPTION
- "Asterisk is an Open Source PBX. This MIB defined
- objects for managing Asterisk instances."
- REVISION "200603061840Z"
- DESCRIPTION
- "Change audio codec identification from 3kAudio to
- Audio3k to conform better with specification.
-
- Expand on contact information."
- REVISION "200602041900Z"
- DESCRIPTION
- "Initial published revision."
- ::= { digium 1 }
-
-asteriskVersion OBJECT IDENTIFIER ::= { asterisk 1 }
-asteriskConfiguration OBJECT IDENTIFIER ::= { asterisk 2 }
-asteriskModules OBJECT IDENTIFIER ::= { asterisk 3 }
-asteriskIndications OBJECT IDENTIFIER ::= { asterisk 4 }
-asteriskChannels OBJECT IDENTIFIER ::= { asterisk 5 }
-
--- asteriskVersion
-
-astVersionString OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Text version string of the version of Asterisk that
- the SNMP Agent was compiled to run against."
- ::= { asteriskVersion 1 }
-
-astVersionTag OBJECT-TYPE
- SYNTAX Unsigned32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "SubVersion revision of the version of Asterisk that
- the SNMP Agent was compiled to run against -- this is
- typically 0 for release-versions of Asterisk."
- ::= { asteriskVersion 2 }
-
--- asteriskConfiguration
-
-astConfigUpTime OBJECT-TYPE
- SYNTAX TimeTicks
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Time ticks since Asterisk was started."
- ::= { asteriskConfiguration 1 }
-
-astConfigReloadTime OBJECT-TYPE
- SYNTAX TimeTicks
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Time ticks since Asterisk was last reloaded."
- ::= { asteriskConfiguration 2 }
-
-astConfigPid OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The process id of the running Asterisk process."
- ::= { asteriskConfiguration 3 }
-
-astConfigSocket OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The control socket for giving Asterisk commands."
- ::= { asteriskConfiguration 4 }
-
--- asteriskModules
-
-astNumModules OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Number of modules currently loaded into Asterisk."
- ::= { asteriskModules 1 }
-
--- asteriskIndications
-
-astNumIndications OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Number of indications currently defined in Asterisk."
- ::= { asteriskIndications 1 }
-
-astCurrentIndication OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Default indication zone to use."
- ::= { asteriskIndications 2 }
-
-astIndicationsTable OBJECT-TYPE
- SYNTAX SEQUENCE OF AstIndicationsEntry
- MAX-ACCESS not-accessible
- STATUS current
- DESCRIPTION
- "Table with all the indication zones currently know to
- the running Asterisk instance."
- ::= { asteriskIndications 3 }
-
-astIndicationsEntry OBJECT-TYPE
- SYNTAX AstIndicationsEntry
- MAX-ACCESS not-accessible
- STATUS current
- DESCRIPTION
- "Information about a single indication zone."
- INDEX { astIndIndex }
- ::= { astIndicationsTable 1 }
-
-AstIndicationsEntry ::= SEQUENCE {
- astIndIndex Integer32,
- astIndCountry DisplayString,
- astIndAlias DisplayString,
- astIndDescription DisplayString
-}
-
-astIndIndex OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Numerical index into the table of indication zones."
- ::= { astIndicationsEntry 1 }
-
-astIndCountry OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Country for which the indication zone is valid,
- typically this is the ISO 2-letter code of the country."
- ::= { astIndicationsEntry 2 }
-
-astIndAlias OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- ""
- ::= { astIndicationsEntry 3 }
-
-astIndDescription OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Description of the indication zone, usually the full
- name of the country it is valid for."
- ::= { astIndicationsEntry 4 }
-
--- asteriskChannels
-
-astNumChannels OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current number of active channels."
- ::= { asteriskChannels 1 }
-
-astChanTable OBJECT-TYPE
- SYNTAX SEQUENCE OF AstChanEntry
- MAX-ACCESS not-accessible
- STATUS current
- DESCRIPTION
- "Table with details of the currently active channels
- in the Asterisk instance."
- ::= { asteriskChannels 2 }
-
-astChanEntry OBJECT-TYPE
- SYNTAX AstChanEntry
- MAX-ACCESS not-accessible
- STATUS current
- DESCRIPTION
- "Details of a single channel."
- INDEX { astChanIndex }
- ::= { astChanTable 1 }
-
-AstChanEntry ::= SEQUENCE {
- astChanIndex Integer32,
- astChanName DisplayString,
- astChanLanguage DisplayString,
- astChanType DisplayString,
- astChanMusicClass DisplayString,
- astChanBridge DisplayString,
- astChanMasq DisplayString,
- astChanMasqr DisplayString,
- astChanWhenHangup TimeTicks,
- astChanApp DisplayString,
- astChanData DisplayString,
- astChanContext DisplayString,
- astChanMacroContext DisplayString,
- astChanMacroExten DisplayString,
- astChanMacroPri Integer32,
- astChanExten DisplayString,
- astChanPri Integer32,
- astChanAccountCode DisplayString,
- astChanForwardTo DisplayString,
- astChanUniqueId DisplayString,
- astChanCallGroup Unsigned32,
- astChanPickupGroup Unsigned32,
- astChanState INTEGER,
- astChanMuted TruthValue,
- astChanRings Integer32,
- astChanCidDNID DisplayString,
- astChanCidNum DisplayString,
- astChanCidName DisplayString,
- astChanCidANI DisplayString,
- astChanCidRDNIS DisplayString,
- astChanCidPresentation DisplayString,
- astChanCidANI2 Integer32,
- astChanCidTON Integer32,
- astChanCidTNS Integer32,
- astChanAMAFlags INTEGER,
- astChanADSI INTEGER,
- astChanToneZone DisplayString,
- astChanHangupCause INTEGER,
- astChanVariables DisplayString,
- astChanFlags BITS,
- astChanTransferCap INTEGER
-}
-
-astChanIndex OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Index into the channel table."
- ::= { astChanEntry 1 }
-
-astChanName OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Name of the current channel."
- ::= { astChanEntry 2 }
-
-astChanLanguage OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Which language the current channel is configured to
- use -- used mainly for prompts."
- ::= { astChanEntry 3 }
-
-astChanType OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Underlying technology for the current channel."
- ::= { astChanEntry 4 }
-
-astChanMusicClass OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Music class to be used for Music on Hold for this
- channel."
- ::= { astChanEntry 5 }
-
-astChanBridge OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Which channel this channel is currently bridged (in a
- conversation) with."
- ::= { astChanEntry 6 }
-
-astChanMasq OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Channel masquerading for us."
- ::= { astChanEntry 7 }
-
-astChanMasqr OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Channel we are masquerading for."
- ::= { astChanEntry 8 }
-
-astChanWhenHangup OBJECT-TYPE
- SYNTAX TimeTicks
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "How long until this channel will be hung up."
- ::= { astChanEntry 9 }
-
-astChanApp OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current application for the channel."
- ::= { astChanEntry 10 }
-
-astChanData OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Arguments passed to the current application."
- ::= { astChanEntry 11 }
-
-astChanContext OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current extension context."
- ::= { astChanEntry 12 }
-
-astChanMacroContext OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current macro context."
- ::= { astChanEntry 13 }
-
-astChanMacroExten OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current macro extension."
- ::= { astChanEntry 14 }
-
-astChanMacroPri OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current macro priority."
- ::= { astChanEntry 15 }
-
-astChanExten OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current extension."
- ::= { astChanEntry 16 }
-
-astChanPri OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Current priority."
- ::= { astChanEntry 17 }
-
-astChanAccountCode OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Account Code for billing."
- ::= { astChanEntry 18 }
-
-astChanForwardTo OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Where to forward to if asked to dial on this
- interface."
- ::= { astChanEntry 19 }
-
-astChanUniqueId OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Unique Channel Identifier."
- ::= { astChanEntry 20 }
-
-astChanCallGroup OBJECT-TYPE
- SYNTAX Unsigned32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Call Group."
- ::= { astChanEntry 21 }
-
-astChanPickupGroup OBJECT-TYPE
- SYNTAX Unsigned32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Pickup Group."
- ::= { astChanEntry 22 }
-
-astChanState OBJECT-TYPE
- SYNTAX INTEGER {
- stateDown(0),
- stateReserved(1),
- stateOffHook(2),
- stateDialing(3),
- stateRing(4),
- stateRinging(5),
- stateUp(6),
- stateBusy(7),
- stateDialingOffHook(8),
- statePreRing(9)
- }
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Channel state."
- ::= { astChanEntry 23 }
-
-astChanMuted OBJECT-TYPE
- SYNTAX TruthValue
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Transmission of voice data has been muted."
- ::= { astChanEntry 24 }
-
-astChanRings OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Number of rings so far."
- ::= { astChanEntry 25 }
-
-astChanCidDNID OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Dialled Number ID."
- ::= { astChanEntry 26 }
-
-astChanCidNum OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Caller Number."
- ::= { astChanEntry 27 }
-
-astChanCidName OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Caller Name."
- ::= { astChanEntry 28 }
-
-astCanCidANI OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "ANI"
- ::= { astChanEntry 29 }
-
-astChanCidRDNIS OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Redirected Dialled Number Service."
- ::= { astChanEntry 30 }
-
-astChanCidPresentation OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Number Presentation/Screening."
- ::= { astChanEntry 31 }
-
-astChanCidANI2 OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "ANI 2 (info digit)."
- ::= { astChanEntry 32 }
-
-astChanCidTON OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Type of Number."
- ::= { astChanEntry 33 }
-
-astChanCidTNS OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Transit Network Select."
- ::= { astChanEntry 34 }
-
-astChanAMAFlags OBJECT-TYPE
- SYNTAX INTEGER {
- Default(0),
- Omit(1),
- Billing(2),
- Documentation(3)
- }
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "AMA Flags."
- ::= { astChanEntry 35 }
-
-astChanADSI OBJECT-TYPE
- SYNTAX INTEGER {
- Unknown(0),
- Available(1),
- Unavailable(2),
- OffHookOnly(3)
- }
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Whether or not ADSI is detected on CPE."
- ::= { astChanEntry 36 }
-
-astChanToneZone OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Indication zone to use for channel."
- ::= { astChanEntry 37 }
-
-astChanHangupCause OBJECT-TYPE
- SYNTAX INTEGER {
- NotDefined(0),
- Unregistered(3),
- Normal(16),
- Busy(17),
- NoAnswer(19),
- Congestion(34),
- Failure(38),
- NoSuchDriver(66)
- }
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Why is the channel hung up."
- ::= { astChanEntry 38 }
-
-astChanVariables OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Channel Variables defined for this channel."
- ::= { astChanEntry 39 }
-
-astChanFlags OBJECT-TYPE
- SYNTAX BITS {
- WantsJitter(0),
- DeferDTMF(1),
- WriteInterrupt(2),
- Blocking(3),
- Zombie(4),
- Exception(5),
- MusicOnHold(6),
- Spying(7),
- NativeBridge(8),
- AutoIncrementingLoop(9)
- }
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Flags set on this channel."
- ::= { astChanEntry 40 }
-
-astChanTransferCap OBJECT-TYPE
- SYNTAX INTEGER {
- Speech(0),
- Digital(8),
- RestrictedDigital(9),
- Audio3k(16),
- DigitalWithTones(17),
- Video(24)
- }
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Transfer Capabilities for this channel."
- ::= { astChanEntry 41 }
-
-astNumChanTypes OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Number of channel types (technologies) supported."
- ::= { asteriskChannels 3 }
-
-astChanTypeTable OBJECT-TYPE
- SYNTAX SEQUENCE OF AstChanTypeEntry
- MAX-ACCESS not-accessible
- STATUS current
- DESCRIPTION
- "Table with details of the supported channel types."
- ::= { asteriskChannels 4 }
-
-astChanTypeEntry OBJECT-TYPE
- SYNTAX AstChanTypeEntry
- MAX-ACCESS not-accessible
- STATUS current
- DESCRIPTION
- "Information about a technology we support, including
- how many channels are currently using this technology."
- INDEX { astChanTypeIndex }
- ::= { astChanTypeTable 1 }
-
-AstChanTypeEntry ::= SEQUENCE {
- astChanTypeIndex Integer32,
- astChanTypeName DisplayString,
- astChanTypeDesc DisplayString,
- astChanTypeDeviceState Integer32,
- astChanTypeIndications Integer32,
- astChanTypeTransfer Integer32,
- astChanTypeChannels Gauge32
-}
-
-astChanTypeIndex OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Index into the table of channel types."
- ::= { astChanTypeEntry 1 }
-
-astChanTypeName OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Unique name of the technology we are describing."
- ::= { astChanTypeEntry 2 }
-
-astChanTypeDesc OBJECT-TYPE
- SYNTAX DisplayString
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Description of the channel type (technology)."
- ::= { astChanTypeEntry 3 }
-
-astChanTypeDeviceState OBJECT-TYPE
- SYNTAX TruthValue
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Whether the current technology can hold device states."
- ::= { astChanTypeEntry 4 }
-
-astChanTypeIndications OBJECT-TYPE
- SYNTAX TruthValue
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Whether the current technology supports progress indication."
- ::= { astChanTypeEntry 5 }
-
-astChanTypeTransfer OBJECT-TYPE
- SYNTAX TruthValue
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Whether the current technology supports transfers, where
- Asterisk can get out from inbetween two bridged channels."
- ::= { astChanTypeEntry 6 }
-
-astChanTypeChannels OBJECT-TYPE
- SYNTAX Gauge32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Number of active channels using the current technology."
- ::= { astChanTypeEntry 7 }
-
-END
diff --git a/1.4/doc/asterisk.8 b/1.4/doc/asterisk.8
deleted file mode 100644
index 9e0e6880f..000000000
--- a/1.4/doc/asterisk.8
+++ /dev/null
@@ -1,195 +0,0 @@
-.\" This manpage has been automatically generated by docbook2man
-.\" from a DocBook document. This tool can be found at:
-.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
-.\" Please send any bug reports, improvements, comments, patches,
-.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "ASTERISK" "8" "25 October 2005" "asterisk 1.2" ""
-
-.SH NAME
-asterisk \- All-purpose telephony server.
-.SH SYNOPSIS
-
-\fBasterisk\fR [ \fB-tThfdvVqpRgciIn\fR ] [ \fB-C \fIfile\fB\fR ] [ \fB-U \fIuser\fB\fR ] [ \fB-G \fIgroup\fB\fR ] [ \fB-x \fIcommand\fB\fR ] [ \fB-M \fIvalue\fB\fR ]
-
-
-\fBasterisk -r\fR [ \fB-v\fR ] [ \fB-x \fIcommand\fB\fR ]
-
-.SH "DESCRIPTION"
-.PP
-\fBasterisk\fR is a full-featured telephony server which
-provides Private Branch eXchange (PBX), Interactive Voice Response (IVR),
-Automated Call Distribution (ACD), Voice over IP (VoIP) gatewaying,
-Conferencing, and a plethora of other telephony applications to a broad
-range of telephony devices including packet voice (SIP, IAX2, MGCP, Skinny,
-H.323) devices (both endpoints and proxies), as well as traditional TDM
-hardware including T1, E1, ISDN PRI, GR-303, RBS, Loopstart, Groundstart,
-ISDN BRI, and many more.
-.PP
-At start, Asterisk reads the /etc/asterisk/asterisk.conf main configuration
-file and locates the rest of the configuration files from the configuration
-in that file. The -C option specifies an alternate main configuration file.
-Virtually all aspects of the operation of asterisk's configuration files
-can be found in the sample configuration files. The format for those files
-is generally beyond the scope of this man page.
-.PP
-When running with \fB-c\fR, \fB-r\fR or \fB-R\fR
-options, Asterisk supplies a powerful command line, including command
-completion, which may be used to monitors its status, perform a variety
-of administrative actions and even explore the applications that are
-currently loaded into the system.
-.PP
-Asterisk is a trademark of Digium, Inc.
-.SH "OPTIONS"
-.TP
-\fB-C \fIfile\fB\fR
-Use \fIfile\fR as master configuration file
-instead of the default, /etc/asterisk/asterisk.conf
-.TP
-\fB-c\fR
-Provide a control console on the calling terminal.
-Specifying this option implies \fB-f\fR and will cause
-asterisk to no longer fork or detach from the controlling terminal.
-.TP
-\fB-d\fR
-Enable extra debugging statements.
-
-Note: This always sets the debug level in the asterisk process,
-even if it is running in the background. This will affect the size
-of your log files.
-.TP
-\fB-f\fR
-Do not fork or detach from controlling terminal.
-.TP
-\fB-g\fR
-Remove resource limit on core size, thus forcing Asterisk to dump
-core in the unlikely event of a segmentation fault or abort signal.
-\fBNOTE:\fR in some cases this may be incompatible
-with the \fB-U\fR or \fB-G\fR flags.
-.TP
-\fB-G \fIgroup\fB\fR
-Run as group \fIgroup\fR instead of the
-calling group. \fBNOTE:\fR this requires substantial work
-to be sure that Asterisk's environment has permission to write
-the files required for its operation, including logs, its comm
-socket, the asterisk database, etc.
-.TP
-\fB-h\fR
-Provide brief summary of command line arguments and terminate.
-.TP
-\fB-i\fR
-Prompt user to initialize any encrypted private keys for IAX2
-secure authentication during startup.
-.TP
-\fB-L \fIloadaverage\fB\fR
-Limits the maximum load average before rejecting new calls. This can
-be useful to prevent a system from being brought down by terminating
-too many simultaneous calls.
-.TP
-\fB-m\fR
-Disable log and verbose output to remote (-r) consoles.
-.TP
-\fB-M \fIvalue\fB\fR
-Limits the maximum number of calls to the specified value. This can
-be useful to prevent a system from being brought down by terminating
-too many simultaneous calls.
-.TP
-\fB-n\fR
-Disable ANSI colors even on terminals capable of displaying them.
-.TP
-\fB-p\fR
-If supported by the operating system (and executing as root),
-attempt to run with realtime priority for increased performance and
-responsiveness within the Asterisk process, at the expense of other
-programs running on the same machine.
-.TP
-\fB-q\fR
-Reduce default console output when running in conjunction with
-console mode (\fB-c\fR).
-.TP
-\fB-r\fR
-Instead of running a new Asterisk process, attempt to connect
-to a running Asterisk process and provide a console interface
-for controlling it.
-.TP
-\fB-R\fR
-Much like \fB-r\fR\&. Instead of running a new Asterisk process, attempt to connect
-to a running Asterisk process and provide a console interface
-for controlling it. Additionally, if connection to the Asterisk
-process is lost, attempt to reconnect for as long as 30 seconds.
-.TP
-\fB-I\fR
-Enable internal timing if Zaptel timer is available
-The default behaviour is that outbound packets are phase locked
-to inbound packets. Enabling this switch causes them to be
-locked to the internal Zaptel timer instead.
-.TP
-\fB-t\fR
-When recording files, write them first into a temporary holding directory,
-then move them into the final location when done.
-.TP
-\fB-T\fR
-Add timestamp to all non-command related output going to the console
-when running with verbose and/or logging to the console.
-.TP
-\fB-U \fIuser\fB\fR
-Run as user \fIuser\fR instead of the
-calling user. \fBNOTE:\fR this requires substantial work
-to be sure that Asterisk's environment has permission to write
-the files required for its operation, including logs, its comm
-socket, the asterisk database, etc.
-.TP
-\fB-v\fR
-Increase the level of verboseness on the console. The more times
-\fB-v\fR is specified, the more verbose the output is.
-Specifying this option implies \fB-f\fR and will cause
-asterisk to no longer fork or detach from the controlling terminal.
-This option may also be used in conjunction with \fB-r\fR
-and \fB-R\fR\&.
-
-Note: This always sets the verbose level in the asterisk process,
-even if it is running in the background. This will affect the size
-of your log files.
-.TP
-\fB-V\fR
-Display version information and exit immediately.
-.TP
-\fB-x \fIcommand\fB\fR
-Connect to a running Asterisk process and execute a command on
-a command line, passing any output through to standard out and
-then terminating when the command execution completes. Implies
-\fB-r\fR when \fB-R\fR is not explicitly
-supplied.
-.SH "EXAMPLES"
-.PP
-\fBasterisk\fR - Begin Asterisk as a daemon
-.PP
-\fBasterisk -vvvgc\fR - Run on controlling terminal
-.PP
-\fBasterisk -rx "core show channels"\fR - Display channels on running server
-.SH "BUGS"
-.PP
-Bug reports and feature requests may be filed at http://bugs.digium.com
-.SH "SEE ALSO"
-.PP
-*CLI> \fBhelp\fR - Help on Asterisk CLI
-.PP
-*CLI> \fBcore show applications\fR - Show loaded dialplan applications
-.PP
-*CLI> \fBcore show functions\fR - Show loaded dialplan functions
-.PP
-*CLI> \fBdialplan show\fR - Show current dialplan
-.PP
-http://www.asterisk.org - The Asterisk Home Page
-.PP
-http://www.asteriskdocs.org - The Asterisk Documentation Project
-.PP
-http://www.voip-info.org/wiki-Asterisk - The Asterisk Wiki
-.PP
-http://www.digium.com/ - Asterisk sponsor and hardware supplier
-.PP
-http://www.markocam.com/ - Asterisk author's web cam
-.SH "AUTHOR"
-.PP
-Mark Spencer <markster@digium.com>
-.PP
-Countless other contributors, see CREDITS with distribution for more information
diff --git a/1.4/doc/asterisk.sgml b/1.4/doc/asterisk.sgml
deleted file mode 100644
index ff257ff67..000000000
--- a/1.4/doc/asterisk.sgml
+++ /dev/null
@@ -1,364 +0,0 @@
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-<refentry>
-<refentryinfo>
- <date>2005-10-18</date>
-</refentryinfo>
-<refmeta>
- <refentrytitle>
- <application>asterisk</application>
- </refentrytitle>
- <manvolnum>8</manvolnum>
- <refmiscinfo>asterisk 1.2</refmiscinfo>
-</refmeta>
-<refnamediv>
- <refname>
- <application>asterisk</application>
- </refname>
- <refpurpose>
- All-purpose telephony server.
- </refpurpose>
-</refnamediv>
-<refsynopsisdiv>
- <cmdsynopsis>
- <command>asterisk</command>
-<arg><option>-tThfdvVqpRgciIn</option></arg>
-<arg><option>-C </option><replaceable class="parameter">file</replaceable></arg>
-<arg><option>-U </option><replaceable class="parameter">user</replaceable></arg>
-<arg><option>-G </option><replaceable class="parameter">group</replaceable></arg>
-<arg><option>-x </option><replaceable class="parameter">command</replaceable></arg>
-<arg><option>-M </option><replaceable class="parameter">value</replaceable></arg>
-<arg><option>-L </option><replaceable class="parameter">loadaverage</replaceable></arg>
- </cmdsynopsis>
- <cmdsynopsis>
-
- <command>asterisk -r</command>
- <arg><option>-v</option></arg>
-<arg><option>-x </option><replaceable class="parameter">command</replaceable></arg>
- </cmdsynopsis>
-</refsynopsisdiv>
-<refsect1>
- <refsect1info>
- <date>2006-03-29</date>
- </refsect1info>
- <title>DESCRIPTION</title>
- <para>
- <command>asterisk</command> is a full-featured telephony server which
- provides Private Branch eXchange (PBX), Interactive Voice Response (IVR),
- Automated Call Distribution (ACD), Voice over IP (VoIP) gatewaying,
- Conferencing, and a plethora of other telephony applications to a broad
- range of telephony devices including packet voice (SIP, IAX2, MGCP, Skinny,
- H.323) devices (both endpoints and proxies), as well as traditional TDM
- hardware including T1, E1, ISDN PRI, GR-303, RBS, Loopstart, Groundstart,
- ISDN BRI, and many more.
- </para>
- <para>
- At start, Asterisk reads the /etc/asterisk/asterisk.conf main configuration
- file and locates the rest of the configuration files from the configuration
- in that file. The -C option specifies an alternate main configuration file.
- Virtually all aspects of the operation of asterisk's configuration files
- can be found in the sample configuration files. The format for those files
- is generally beyond the scope of this man page.
- </para>
- <para>
- When running with <command>-c</command>, <command>-r</command> or <command>-R</command>
- options, Asterisk supplies a powerful command line, including command
- completion, which may be used to monitors its status, perform a variety
- of administrative actions and even explore the applications that are
- currently loaded into the system.
- </para>
- <para>
- Asterisk is a trademark of Digium, Inc.
- </para>
-</refsect1>
-<refsect1>
- <title>OPTIONS</title>
- <variablelist>
- <varlistentry>
- <term>-C <replaceable class="parameter">file</replaceable></term>
- <listitem>
- <para>
- Use <filename>file</filename> as master configuration file
- instead of the default, /etc/asterisk/asterisk.conf
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-c</term>
- <listitem>
- <para>
- Provide a control console on the calling terminal.
- Specifying this option implies <command>-f</command> and will cause
- asterisk to no longer fork or detach from the controlling terminal.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-d</term>
- <listitem>
- <para>
- Enable extra debugging statements.
- </para>
- <para>
- Note: This always sets the debug level in the asterisk process,
- even if it is running in the background. This will affect the size
- of your log files.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-f</term>
- <listitem>
- <para>
- Do not fork or detach from controlling terminal.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-g</term>
- <listitem>
- <para>
- Remove resource limit on core size, thus forcing Asterisk to dump
- core in the unlikely event of a segmentation fault or abort signal.
- <command>NOTE:</command> in some cases this may be incompatible
- with the <command>-U</command> or <command>-G</command> flags.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-G <replaceable class="parameter">group</replaceable></term>
- <listitem>
- <para>
- Run as group <replaceable>group</replaceable> instead of the
- calling group. <command>NOTE:</command> this requires substantial work
- to be sure that Asterisk's environment has permission to write
- the files required for its operation, including logs, its comm
- socket, the asterisk database, etc.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-h</term>
- <listitem>
- <para>
- Provide brief summary of command line arguments and terminate.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-i</term>
- <listitem>
- <para>
- Prompt user to intialize any encrypted private keys for IAX2
- secure authentication during startup.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-I</term>
- <listitem>
- <para>
- Enable internal timing if Zaptel timing is available.
- The default behaviour is that outbound packets are phase locked
- to inbound packets. Enabling this switch causes them to be
- locked to the internal Zaptel timer instead.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-L <replaceable class="parameter">loadaverage</replaceable></term>
- <listitem>
- <para>
- Limits the maximum load average before rejecting new calls. This can
- be useful to prevent a system from being brought down by terminating
- too many simultaneous calls.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-M <replaceable class="parameter">value</replaceable></term>
- <listitem>
- <para>
- Limits the maximum number of calls to the specified value. This can
- be useful to prevent a system from being brought down by terminating
- too many simultaneous calls.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-n</term>
- <listitem>
- <para>
- Disable ANSI colors even on terminals capable of displaying them.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-p</term>
- <listitem>
- <para>
- If supported by the operating system (and executing as root),
- attempt to run with realtime priority for increased performance and
- responsiveness within the Asterisk process, at the expense of other
- programs running on the same machine.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-q</term>
- <listitem>
- <para>
- Reduce default console output when running in conjunction with
- console mode (<command>-c</command>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-r</term>
- <listitem>
- <para>
- Instead of running a new Asterisk process, attempt to connect
- to a running Asterisk process and provide a console interface
- for controlling it.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-R</term>
- <listitem>
- <para>
- Much like <command>-r</command>. Instead of running a new Asterisk process, attempt to connect
- to a running Asterisk process and provide a console interface
- for controlling it. Additionally, if connection to the Asterisk
- process is lost, attempt to reconnect for as long as 30 seconds.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-t</term>
- <listitem>
- <para>
- When recording files, write them first into a temporary holding directory,
- then move them into the final location when done.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-T</term>
- <listitem>
- <para>
- Add timestamp to all non-command related output going to the console
- when running with verbose and/or logging to the console.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-U <replaceable class="parameter">user</replaceable></term>
- <listitem>
- <para>
- Run as user <replaceable>user</replaceable> instead of the
- calling user. <command>NOTE:</command> this requires substantial work
- to be sure that Asterisk's environment has permission to write
- the files required for its operation, including logs, its comm
- socket, the asterisk database, etc.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-v</term>
- <listitem>
- <para>
- Increase the level of verboseness on the console. The more times
- <command>-v</command> is specified, the more verbose the output is.
- Specifying this option implies <command>-f</command> and will cause
- asterisk to no longer fork or detach from the controlling terminal.
- This option may also be used in conjunction with <command>-r</command>
- and <command>-R</command>.
- </para>
- <para>
- Note: This always sets the verbose level in the asterisk process,
- even if it is running in the background. This will affect the size
- of your log files.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-V</term>
- <listitem>
- <para>
- Display version information and exit immediately.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>-x <replaceable class="parameter">command</replaceable></term>
- <listitem>
- <para>
- Connect to a running Asterisk process and execute a command on
- a command line, passing any output through to standard out and
- then terminating when the command execution completes. Implies
- <command>-r</command> when <command>-R</command> is not explicitly
- supplied.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
-</refsect1>
-<refsect1>
- <title>EXAMPLES</title>
- <para>
- <command>asterisk</command> - Begin Asterisk as a daemon
- </para>
- <para>
- <command>asterisk -vvvgc</command> - Run on controlling terminal
- </para>
- <para>
- <command>asterisk -rx "show channels"</command> - Display channels on running server
- </para>
-</refsect1>
-<refsect1>
- <title>BUGS</title>
- <para>
- Bug reports and feature requests may be filed at http://bugs.digium.com
- </para>
-</refsect1>
-<refsect1>
- <title>SEE ALSO</title>
- <para>
- *CLI&gt; <command>help</command> - Help on Asterisk CLI
- </para>
- <para>
- *CLI&gt; <command>show applications</command> - Show loaded dialplan applications
- </para>
- <para>
- *CLI&gt; <command>show functions</command> - Show loaded dialplan functions
- </para>
- <para>
- http://www.asterisk.org - The Asterisk Home Page
- </para>
- <para>
- http://www.asteriskdocs.org - The Asterisk Documentation Project
- </para>
- <para>
- http://www.voip-info.org/wiki-Asterisk - The Asterisk Wiki
- </para>
- <para>
- http://www.digium.com/ - Asterisk sponsor and hardware supplier
- </para>
- <para>
- http://www.markocam.com/ - Asterisk author's web cam
- </para>
-</refsect1>
-<refsect1>
- <title>AUTHOR</title>
- <para>
- <author>
- <firstname>Mark Spencer &lt;markster@digium.com&gt;</firstname>
- </author>
- </para>
- <para>
- <author>
- <firstname>Countless other contributers, see CREDITS with distribution for more information</firstname>
- </author>
- </para>
-</refsect1>
-</refentry>
diff --git a/1.4/doc/backtrace.txt b/1.4/doc/backtrace.txt
deleted file mode 100644
index d4e13c863..000000000
--- a/1.4/doc/backtrace.txt
+++ /dev/null
@@ -1,191 +0,0 @@
-This document is intended to provide information on how to obtain the
-backtraces required on the asterisk bug tracker, available at
-http://bugs.digium.com. The information is required by developers to
-help fix problem with bugs of any kind. Backtraces provide information
-about what was wrong when a program crashed; in our case,
-Asterisk. There are two kind of backtraces (aka 'bt') which are
-useful: bt and bt full.
-
-First of all, when you start Asterisk, you MUST start it with option
--g. This tells Asterisk to produce a core file if it crashes.
-
-If you start Asterisk with the safe_asterisk script, it automatically
-starts using the option -g.
-
-If you're not sure if Asterisk is running with the -g option, type the
-following command in your shell:
-
-debian:/tmp# ps aux | grep asterisk
-root 17832 0.0 1.2 2348 788 pts/1 S Aug12 0:00 /bin/sh /usr/sbin/safe_asterisk
-root 26686 0.0 2.8 15544 1744 pts/1 S Aug13 0:02 asterisk -vvvg -c
-[...]
-
-The interesting information is located in the last column.
-
-Second, your copy of Asterisk must have been built without
-optimization or the backtrace will be (nearly) unusable. This can be
-done by selecting the 'DONT_OPTIMIZE' option in the Compiler Flags
-submenu in the 'make menuselect' tree before building Asterisk.
-
-After Asterisk crashes, a core file will be "dumped" in your /tmp/
-directory. To make sure it's really there, you can just type the
-following command in your shell:
-
-debian:/tmp# ls -l /tmp/core.*
--rw------- 1 root root 10592256 Aug 12 19:40 /tmp/core.26252
--rw------- 1 root root 9924608 Aug 12 20:12 /tmp/core.26340
--rw------- 1 root root 10862592 Aug 12 20:14 /tmp/core.26374
--rw------- 1 root root 9105408 Aug 12 20:19 /tmp/core.26426
--rw------- 1 root root 9441280 Aug 12 20:20 /tmp/core.26462
--rw------- 1 root root 8331264 Aug 13 00:32 /tmp/core.26647
-debian:/tmp#
-
-In the event that there are multiple core files present (as in the
-above example), it is important to look at the file timestamps in
-order to determine which one you really intend to look at.
-
-Now that we've verified the core file has been written to disk, the
-final part is to extract 'bt' from the core file. Core files are
-pretty big, don't be scared, it's normal.
-
-*** NOTE: Don't attach core files on the bug tracker, we only need the bt and bt full. ***
-
-For extraction, we use a really nice tool, called gdb. To verify that
-you have gdb installed on your system:
-
-debian:/tmp# gdb -v
-GNU gdb 6.3-debian
-Copyright 2004 Free Software Foundation, Inc.
-GDB is free software, covered by the GNU General Public License, and you are
-welcome to change it and/or distribute copies of it under certain conditions.
-Type "show copying" to see the conditions.
-There is absolutely no warranty for GDB. Type "show warranty" for details.
-This GDB was configured as "i386-linux".
-debian:/tmp#
-
-Which is great, we can continue. If you don't have gdb installed, go install gdb.
-
-Now load the core file in gdb, as follows:
-
-debian:/tmp# gdb asterisk /tmp/core.26252
-[...]
-(You would see a lot of output here.)
-[...]
-Reading symbols from /usr/lib/asterisk/modules/app_externalivr.so...done.
-Loaded symbols for /usr/lib/asterisk/modules/app_externalivr.so
-#0 0x29b45d7e in ?? ()
-(gdb)
-
-Now at the gdb prompt, type: bt
-You would see output similar to:
-(gdb) bt
-#0 0x29b45d7e in ?? ()
-#1 0x08180bf8 in ?? ()
-#2 0xbcdffa58 in ?? ()
-#3 0x08180bf8 in ?? ()
-#4 0xbcdffa60 in ?? ()
-#5 0x08180bf8 in ?? ()
-#6 0x180bf894 in ?? ()
-#7 0x0bf80008 in ?? ()
-#8 0x180b0818 in ?? ()
-#9 0x08068008 in ast_stopstream (tmp=0x40758d38) at file.c:180
-#10 0x000000a0 in ?? ()
-#11 0x000000a0 in ?? ()
-#12 0x00000000 in ?? ()
-#13 0x407513c3 in confcall_careful_stream (conf=0x8180bf8, filename=0x8181de8 "Zap/pseudo-1324221520") at app_meetme.c:262
-#14 0x40751332 in streamconfthread (args=0x8180bf8) at app_meetme.c:1965
-#15 0xbcdffbe0 in ?? ()
-#16 0x40028e51 in pthread_start_thread () from /lib/libpthread.so.0
-#17 0x401ec92a in clone () from /lib/libc.so.6
-(gdb)
-
-
-The bt's output is the information that we need on the bug tracker.
-
-Now do a bt full as follows:
-(gdb) bt full
-#0 0x29b45d7e in ?? ()
-No symbol table info available.
-#1 0x08180bf8 in ?? ()
-No symbol table info available.
-#2 0xbcdffa58 in ?? ()
-No symbol table info available.
-#3 0x08180bf8 in ?? ()
-No symbol table info available.
-#4 0xbcdffa60 in ?? ()
-No symbol table info available.
-#5 0x08180bf8 in ?? ()
-No symbol table info available.
-#6 0x180bf894 in ?? ()
-No symbol table info available.
-#7 0x0bf80008 in ?? ()
-No symbol table info available.
-#8 0x180b0818 in ?? ()
-No symbol table info available.
-#9 0x08068008 in ast_stopstream (tmp=0x40758d38) at file.c:180
-No locals.
-#10 0x000000a0 in ?? ()
-No symbol table info available.
-#11 0x000000a0 in ?? ()
-No symbol table info available.
-#12 0x00000000 in ?? ()
-No symbol table info available.
-#13 0x407513c3 in confcall_careful_stream (conf=0x8180bf8, filename=0x8181de8 "Zap/pseudo-1324221520") at app_meetme.c:262
- f = (struct ast_frame *) 0x8180bf8
- trans = (struct ast_trans_pvt *) 0x0
-#14 0x40751332 in streamconfthread (args=0x8180bf8) at app_meetme.c:1965
-No locals.
-#15 0xbcdffbe0 in ?? ()
-No symbol table info available.
-#16 0x40028e51 in pthread_start_thread () from /lib/libpthread.so.0
-No symbol table info available.
-#17 0x401ec92a in clone () from /lib/libc.so.6
-No symbol table info available.
-(gdb)
-
-We also need gdb's output. That output gives more details compared to
-the simple "bt". So we recommend that you use bt full instead of bt.
-But, if you could include both, we appreciate that.
-
-The final "extraction" would be to know all traces by all
-threads. Even if asterisk runs on the same thread for each call, it
-could have created some new threads.
-
-To make sure we have the correct information, just do:
-(gdb) thread apply all bt
-
-Thread 1 (process 26252):
-#0 0x29b45d7e in ?? ()
-#1 0x08180bf8 in ?? ()
-#2 0xbcdffa58 in ?? ()
-#3 0x08180bf8 in ?? ()
-#4 0xbcdffa60 in ?? ()
-#5 0x08180bf8 in ?? ()
-#6 0x180bf894 in ?? ()
-#7 0x0bf80008 in ?? ()
-#8 0x180b0818 in ?? ()
-#9 0x08068008 in ast_stopstream (tmp=0x40758d38) at file.c:180
-#10 0x000000a0 in ?? ()
-#11 0x000000a0 in ?? ()
-#12 0x00000000 in ?? ()
-#13 0x407513c3 in confcall_careful_stream (conf=0x8180bf8, filename=0x8181de8 "Zap/pseudo-1324221520") at app_meetme.c:262
-#14 0x40751332 in streamconfthread (args=0x8180bf8) at app_meetme.c:1965
-#15 0xbcdffbe0 in ?? ()
-#16 0x40028e51 in pthread_start_thread () from /lib/libpthread.so.0
-#17 0x401ec92a in clone () from /lib/libc.so.6
-(gdb)
-
-
-That output tells us crucial information about each thread.
-
-Now, just create an output.txt file and dump your "bt full"
-(and/or "bt") ALONG WITH "thread apply all bt" into it.
-
-Note: Please ATTACH your output, DO NOT paste it as a note.
-
-And you're ready for upload on the bug tracker.
-
-
-If you have questions or comments regarding this documentation, feel
-free to pass by the #asterisk-bugs channel on irc.freenode.net.
-
diff --git a/1.4/doc/billing.txt b/1.4/doc/billing.txt
deleted file mode 100644
index bca6b8fba..000000000
--- a/1.4/doc/billing.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-Asterisk billing support - Call Detail Records
-----------------------------------------------
-Asterisk generates Call Detail Records in a database or in a comma
-separated text file.
-
- * cdr_csv supports comma separated text file storage, this is the
- default driver
- * cdr_manager supports CDR information via the AMI, The Asterisk Manager
- interface
- * cdr_odbc supports UnixODBC databases, see http://www.unixodbc.org
- for an updated list of supported databases, from MySQL to MsSQL
- and text files.
- * cdr_tds supports FreeTDS databases (Among them MS SQL)
- NOTE: Please read doc/freetds.txt for information on possible
- problems with the FreeTDS driver
- * cdr_sqlite supports SQlite
- * cdr_pgsql supports PostgreSQL
-
-In the asterisk-addons subversion repository, there's a cdr_mysql driver for
-MySQL.
-
-Applications
-------------
-
- * SetAccount Set account code for billing
- * SetAMAFlags Sets AMA flags
- * NoCDR Make sure no CDR is saved for a specific call
- * ResetCDR Reset CDR
- * ForkCDR Save current CDR and start a new CDR for this call
- * Authenticate Authenticates and sets the account code
- * SetCDRUserField Set CDR user field
- * AppendCDRUserField Append data to CDR User field
-
-For more information, use the "show application" command.
-You can set default account codes and AMA flags for devices in
-channel configuration files, like sip.conf, iax.conf etc.
-
-
-Fields of the CDR in Asterisk
------------------------------
-
- 1. accountcode: What account number to use, (string, 20 characters)
- 2. src: Caller*ID number (string, 80 characters)
- 3. dst: Destination extension (string, 80 characters)
- 4. dcontext: Destination context (string, 80 characters)
- 5. clid: Caller*ID with text (80 characters)
- 6. channel: Channel used (80 characters)
- 7. dstchannel: Destination channel if appropriate (80 characters)
- 8. lastapp: Last application if appropriate (80 characters)
- 9. lastdata: Last application data (arguments) (80 characters)
- 10. start: Start of call (date/time)
- 11. answer: Answer of call (date/time)
- 12. end: End of call (date/time)
- 13. duration: Total time in system, in seconds (integer), from dial to hangup
- 14. billsec: Total time call is up, in seconds (integer), from answer to hangup
- 15. disposition: What happened to the call: ANSWERED, NO ANSWER, BUSY
- 16. amaflags: What flags to use: DOCUMENTATION, BILL, IGNORE etc,
- specified on a per channel basis like accountcode.
- 17. user field: A user-defined field, maximum 255 characters
-
-In some cases, uniqueid is appended:
-
- * uniqueid: Unique Channel Identifier (32 characters)
- This needs to be enabled in the source code at compile time
-
-
-NOTE: If you use IAX2 channels for your calls, and allow 'full' transfers
-(not media-only transfers), then when the calls is transferred the server
-in the middle will no longer be involved in the signaling path, and thus
-will not generate accurate CDRs for that call. If you can, use media-only
-transfers with IAX2 to avoid this problem, or turn off transfers completely
-(although this can result in a media latency increase since the media packets
-have to traverse the middle server(s) in the call).
-
-____________________________________
-CDR Variables
-------------------------------------
-
-If the channel has a cdr, that cdr record has its own set of variables which
-can be accessed just like channel variables. The following builtin variables
-are available.
-
-${CDR(clid)} Caller ID
-${CDR(src)} Source
-${CDR(dst)} Destination
-${CDR(dcontext)} Destination context
-${CDR(channel)} Channel name
-${CDR(dstchannel)} Destination channel
-${CDR(lastapp)} Last app executed
-${CDR(lastdata)} Last app's arguments
-${CDR(start)} Time the call started.
-${CDR(answer)} Time the call was answered.
-${CDR(end)} Time the call ended.
-${CDR(duration)} Duration of the call.
-${CDR(billsec)} Duration of the call once it was answered.
-${CDR(disposition)} ANSWERED, NO ANSWER, BUSY
-${CDR(amaflags)} DOCUMENTATION, BILL, IGNORE etc
-${CDR(accountcode)} The channel's account code.
-${CDR(uniqueid)} The channel's unique id.
-${CDR(userfield)} The channels uses specified field.
-
-In addition, you can set your own extra variables by using Set(CDR(name)=value).
-These variables can be output into a text-format CDR by using the cdr_custom
-CDR driver; see the cdr_custom.conf.sample file in the configs directory for
-an example of how to do this.
diff --git a/1.4/doc/callfiles.txt b/1.4/doc/callfiles.txt
deleted file mode 100644
index 3fe6cb09e..000000000
--- a/1.4/doc/callfiles.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-Asterisk call files
-===================
-
-Asterisk has the ability to initiate a call from outside of the normal
-methods such as the dialplan, manager interface, or spooling interface.
-
-Using the call file method, you must give Asterisk the following information:
-
-* How to perform the call, similar to the Dial() application
-* What to do when the call is answered
-
-With call files you submit this information simply by creating a file with
-the required syntax and placing it in the outgoing spooling directory, located
-by default in /var/spool/asterisk/outgoing/ (configurable in asterisk.conf).
-
-The pbx_spool module aggressively examines the directory contents every second,
-creating a new call for every call file it finds. Do NOT write or create
-the call file directly in the outgoing directory, but always create the file
-in another directory of the same filesystem and then move the file to the
-/var/spool/asterisk/outgoing directory, or Asterisk may read just a partial
-file.
-
-
-The call file syntax
-====================
-
-The call file consists of <Key>: <value> pairs; one per line.
-
-Comments are indicated by a '#' character that begins a line, or follows a space
-or tab character. To be consistent with the configuration files in Asterisk,
-comments can also be indicated by a semicolon. However, the multiline comments
-(;-- --;) used in Asterisk configuration files are not supported. Semicolons can
-be escaped by a backslash.
-
-
-The following keys-value pairs are used to specify how setup a call:
-
-Channel: <channel> the channel to use for the new call, in the form
- technology/resource as in the Dial application. This
- value is required.
-
-Callerid: <callerid> the caller id to use.
-
-WaitTime: <number> how many seconds to wait for an answer before the call
- fails (ring cycle). Default 45 seconds.
-
-Maxretries: <number> number of retries before failing, not including the
- initial attempt. Default = 0 e.g. don't retry if fails.
-
-RetryTime: <number> how many seconds to wait before retry. The default is
- 300 (5 minutes).
-
-Account: <account> the account code for the call. This value will be
- assigned to CDR(accountcode)
-
-
-
-When the call answers there are two choices:
-* Execute a single application, or
-* Execute the dialplan at the specified context/extension/priority.
-
-
-To execute an application:
---------------------------
-
-Application: <appname> the application to execute
-
-Data: <args> the application arguments
-
-
-To start executing applications in the dialplan:
-------------------------------------------------
-
-Context: <context> the context in the dialplan
-
-Extension: <exten> the extension in the specified context
-
-Priority: <priority> the priority of the specified extension
- (numeric or label)
-
-
-
-Setvar: <var=value> you may also assign values to variables that will be
- available to the channel, as if you had performed a
- Set(var=value) in the dialplan. More than one Setvar:
- maybe specified.
-
-
-The processing of the call file ends when the call is answered and terminated; when
-the call was not answered in the initial attempt and subsequent retries; or if
-the call file can't be successfully read and parsed.
-
-To specify what to do with the call file at the end of processing:
-
-Archive: <yes|no> if "no" the call file is deleted. If set to "yes" the
- call file is moved to the "outgoing_done" subdirectory
- of the Asterisk spool directory. The default is to
- delete the call file.
-
-
-If the call file is archived, Asterisk will append to the call file:
-
-Status: <exitstatus> can be "Expired", "Completed" or "Failed"
-
-
-
-Other lines generated by Asterisk:
-
-Asterisk keep track of how many retries the call has already attempted,
-appending to the call file the following key-pairs in the form:
-
-StartRetry: <pid> <retrycount> (<time>)
-EndRetry: <pid> <retrycount> (<time>)
-
-With the main process ID (pid) of the Asterisk process, the retry number, and
-the attempts start and end times in time_t format.
-
-
-
-Directory locations
-===================
-
-<astspooldir>/outgoing the outgoing dir, where call files are put
- for processing
-
-<astspooldir>/outgoing_done the archive dir
-
-
-<astspooldir> is specified in asterisk.conf, usually /var/spool/asterisk
-
-
-
-How to schedule a call
-======================
-
-Call files that have the time of the last modification in the future are ignored
-by Asterisk. This makes it possible to modify the time of a call file to the
-wanted time, move to the outgoing directory, and Asterisk will attempt to
-create the call at that time.
diff --git a/1.4/doc/callingpres.txt b/1.4/doc/callingpres.txt
deleted file mode 100644
index 0fa1ff469..000000000
--- a/1.4/doc/callingpres.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Caller ID presentation values
------------------------------
-
-In some channels it is possible to set Caller ID presentation for a device. It is
-also possible to set the presentation for an active channel in the dial plan
-with the setcallerpres() application.
-
-Valid values are:
-
- allowed_not_screened : Presentation Allowed, Not Screened
- allowed_passed_screen : Presentation Allowed, Passed Screen
- allowed_failed_screen : Presentation Allowed, Failed Screen
- allowed : Presentation Allowed, Network Number
- prohib_not_screened : Presentation Prohibited, Not Screened
- prohib_passed_screen : Presentation Prohibited, Passed Screen
- prohib_failed_screen : Presentation Prohibited, Failed Screen
- prohib : Presentation Prohibited, Network Number
- unavailable : Number Unavailable
diff --git a/1.4/doc/cdrdriver.txt b/1.4/doc/cdrdriver.txt
deleted file mode 100644
index 8a7e2e328..000000000
--- a/1.4/doc/cdrdriver.txt
+++ /dev/null
@@ -1,215 +0,0 @@
-Call data records can be stored in many different databases or even CSV text.
-
-MSSQL: Asterisk can currently store CDRs into an MSSQL database in
- two different ways: cdr_odbc.c or cdr_tds.c
-
- Call Data Records can be stored using unixODBC (which requires
- the FreeTDS package) [cdr_odbc.c] or directly by using just the
- FreeTDS package [cdr_tds.c] The following provide some
- examples known to get asterisk working with mssql.
- NOTE: Only choose one db connector.
-
- ODBC [cdr_odbc.c]:
- Compile, configure, and install the latest unixODBC package:
- tar -zxvf unixODBC-2.2.9.tar.gz &&
- cd unixODBC-2.2.9 &&
- ./configure --sysconfdir=/etc --prefix=/usr --disable-gui &&
- make &&
- make install
-
- Compile, configure, and install the latest FreeTDS package:
- tar -zxvf freetds-0.62.4.tar.gz &&
- cd freetds-0.62.4 &&
- ./configure --prefix=/usr --with-tdsver=7.0 \
- --with-unixodbc=/usr/lib &&
- make &&
- make install
-
- Compile, or recompile, asterisk so that it will now add support
- for cdr_odbc.c
-
- make clean &&
- make update &&
- make &&
- make install
-
- Setup odbc configuration files. These are working examples
- from my system. You will need to modify for your setup.
- You are not required to store usernames or passwords here.
-
- /etc/odbcinst.ini
- [FreeTDS]
- Description = FreeTDS ODBC driver for MSSQL
- Driver = /usr/lib/libtdsodbc.so
- Setup = /usr/lib/libtdsS.so
- FileUsage = 1
-
- /etc/odbc.ini
- [MSSQL-asterisk]
- description = Asterisk ODBC for MSSQL
- driver = FreeTDS
- server = 192.168.1.25
- port = 1433
- database = voipdb
- tds_version = 7.0
- language = us_english
-
- Only install one database connector. Do not confuse asterisk
- by using both ODBC (cdr_odbc.c) and FreeTDS (cdr_tds.c).
- This command will erase the contents of cdr_tds.conf
-
- [ -f /etc/asterisk/cdr_tds.conf ] > /etc/asterisk/cdr_tds.conf
-
- NOTE: unixODBC requires the freeTDS package, but asterisk does
- not call freeTDS directly.
-
- Setup cdr_odbc configuration files. These are working samples
- from my system. You will need to modify for your setup. Define
- your usernames and passwords here, secure file as well.
-
- /etc/asterisk/cdr_odbc.conf
- [global]
- dsn=MSSQL-asterisk
- username=voipdbuser
- password=voipdbpass
- loguniqueid=yes
-
- And finally, create the 'cdr' table in your mssql database.
-
- CREATE TABLE cdr (
- [calldate] [datetime] NOT NULL ,
- [clid] [varchar] (80) NOT NULL ,
- [src] [varchar] (80) NOT NULL ,
- [dst] [varchar] (80) NOT NULL ,
- [dcontext] [varchar] (80) NOT NULL ,
- [channel] [varchar] (80) NOT NULL ,
- [dstchannel] [varchar] (80) NOT NULL ,
- [lastapp] [varchar] (80) NOT NULL ,
- [lastdata] [varchar] (80) NOT NULL ,
- [duration] [int] NOT NULL ,
- [billsec] [int] NOT NULL ,
- [disposition] [varchar] (45) NOT NULL ,
- [amaflags] [int] NOT NULL ,
- [accountcode] [varchar] (20) NOT NULL ,
- [uniqueid] [varchar] (32) NOT NULL ,
- [userfield] [varchar] (255) NOT NULL
- )
-
- Start asterisk in verbose mode, you should see that asterisk
- logs a connection to the database and will now record every
- call to the database when it's complete.
-
- TDS [cdr_tds.c]:
- Compile, configure, and install the latest FreeTDS package:
- tar -zxvf freetds-0.62.4.tar.gz &&
- cd freetds-0.62.4 &&
- ./configure --prefix=/usr --with-tdsver=7.0
- make &&
- make install
-
- Compile, or recompile, asterisk so that it will now add support
- for cdr_tds.c
-
- make clean &&
- make update &&
- make &&
- make install
-
- Only install one database connector. Do not confuse asterisk
- by using both ODBC (cdr_odbc.c) and FreeTDS (cdr_tds.c).
- This command will erase the contents of cdr_odbc.conf
-
- [ -f /etc/asterisk/cdr_odbc.conf ] > /etc/asterisk/cdr_odbc.conf
-
- Setup cdr_tds configuration files. These are working samples
- from my system. You will need to modify for your setup. Define
- your usernames and passwords here, secure file as well.
-
- /etc/asterisk/cdr_tds.conf
- [global]
- hostname=192.168.1.25
- port=1433
- dbname=voipdb
- user=voipdbuser
- password=voipdpass
- charset=BIG5
-
- And finally, create the 'cdr' table in your mssql database.
-
- CREATE TABLE cdr (
- [accountcode] [varchar] (20) NULL ,
- [src] [varchar] (80) NULL ,
- [dst] [varchar] (80) NULL ,
- [dcontext] [varchar] (80) NULL ,
- [clid] [varchar] (80) NULL ,
- [channel] [varchar] (80) NULL ,
- [dstchannel] [varchar] (80) NULL ,
- [lastapp] [varchar] (80) NULL ,
- [lastdata] [varchar] (80) NULL ,
- [start] [datetime] NULL ,
- [answer] [datetime] NULL ,
- [end] [datetime] NULL ,
- [duration] [int] NULL ,
- [billsec] [int] NULL ,
- [disposition] [varchar] (20) NULL ,
- [amaflags] [varchar] (16) NULL ,
- [uniqueid] [varchar] (32) NULL
- )
-
- Start asterisk in verbose mode, you should see that asterisk
- logs a connection to the database and will now record every
- call to the database when it's complete.
-
-
-MYSQL:
-
-
-PGSQL:
- If you want to go directly to postgresql database, and have the cdr_pgsql.so
- compiled you can use the following sample setup.
- On Debian, before compiling asterisk, just install libpqxx-dev.
- Other distros will likely have a similiar package.
-
- Once you have the compile done,
- copy the sample cdr_pgsql.conf file or create your own.
-
- Here is a sample:
-
- /etc/asterisk/cdr_pgsql.conf
- ; Sample Asterisk config file for CDR logging to PostgresSQL
- [global]
- hostname=localhost
- port=5432
- dbname=asterisk
- password=password
- user=postgres
- table=cdr
-
- ;Now create a table in postgresql for your cdrs
-
- ;SQL table where CDRs will be inserted
- ;Copy and paste this into your postgresql prompt.
- CREATE TABLE cdr (
- calldate time NOT NULL ,
- clid varchar (80) NOT NULL ,
- src varchar (80) NOT NULL ,
- dst varchar (80) NOT NULL ,
- dcontext varchar (80) NOT NULL ,
- channel varchar (80) NOT NULL ,
- dstchannel varchar (80) NOT NULL ,
- lastapp varchar (80) NOT NULL ,
- lastdata varchar (80) NOT NULL ,
- duration int NOT NULL ,
- billsec int NOT NULL ,
- disposition varchar (45) NOT NULL ,
- amaflags int NOT NULL ,
- accountcode varchar (20) NOT NULL ,
- uniqueid varchar (32) NOT NULL ,
- userfield varchar (255) NOT NULL
- );
-
-
-SQLLITE:
-
-
-RADIUS: See doc/radius.txt for more information on cdr_radius
diff --git a/1.4/doc/chaniax.txt b/1.4/doc/chaniax.txt
deleted file mode 100644
index 0bac3046f..000000000
--- a/1.4/doc/chaniax.txt
+++ /dev/null
@@ -1,369 +0,0 @@
-Inter-Asterisk eXchange Protocol
-================================
-
-INTRODUCTION
-------------
-
-This document is intended as an introduction to the Inter-Asterisk
-eXchange (or simply IAX) protocol. It provides both a theoretical
-background and practical information on its use.
-
-WHY IAX
--------
-The first question most people are thinking at this point is "Why do you
-need another VoIP protocol? Why didn't you just use SIP or H.323?"
-
-Well, the answer is a fairly complicated one, but in a nutshell it's like
-this... Asterisk is intended as a very flexible and powerful
-communications tool. As such, the primary feature we need from a VoIP
-protocol is the ability to meet our own goals with Asterisk, and one with
-enough flexibility that we could use it as a kind of laboratory for
-inventing and implementing new concepts in the field. Neither H.323 or
-SIP fit the roles we needed, so we developed our own protocol, which,
-while not standards based, provides a number of advantages over both SIP
-and H.323, some of which are:
-
- * Interoperability with NAT/PAT/Masquerade firewalls
- IAX seamlessly interoperates through all sorts of NAT and PAT
- and other firewalls, including the ability to place and
- receive calls, and transfer calls to other stations.
-
- * High performance, low overhead protocol
- When running on low-bandwidth connections, or when running
- large numbers of calls, optimized bandwidth utilization is
- imperative. IAX uses only 4 bytes of overhead
-
- * Internationalization support
- IAX transmits language information, so that remote PBX
- content can be delivered in the native language of the
- calling party.
-
- * Remote dialplan polling
- IAX allows a PBX or IP phone to poll the availability of a
- number from a remote server. This allows PBX dialplans to
- be centralized.
-
- * Flexible authentication
- IAX supports cleartext, md5, and RSA authentication,
- providing flexible security models for outgoing calls and
- registration services.
-
- * Multimedia protocol
- IAX supports the transmission of voice, video, images, text,
- HTML, DTMF, and URL's. Voice menus can be presented in both
- audibly and visually.
-
- * Call statistic gathering
- IAX gathers statistics about network performance (including
- latency and jitter, as well as providing end-to-end latency
- measurement.
-
- * Call parameter communication
- Caller*ID, requested extension, requested context, etc are
- all communicated through the call.
-
- * Single socket design
- IAX's single socket design allows up to 32768 calls to be
- multiplexed.
-
-While we value the importance of standards based (i.e. SIP) call handling,
-hopefully this will provide a reasonable explanation of why we developed
-IAX rather than starting with SIP.
-
-CONFIG FILE CONVENTIONS
------------------------
-Lines beginning with '>' represent lines which might appear in an actual
-configuration file. The '>' is used to help separate them from the
-descriptive text and should not actually be included in the file itself.
-
-Lines within []'s by themselves represent section labels within the
-configuration file. like this:
-
-> [mysection]
-
-Options are set using the "=" sign, for example
-
-> myoption = value
-
-Sometimes an option will have a number of discrete values which it can
-take. In that case, in the documentation, the options will be listed
-within square brackets (the "[" and "]" ones) separated by the pipe symbol
-("|"). For example:
-
-> myoption = [value1|value2|value3]
-
-means the option "myoption" can be assigned a value of "value1", "value2",
-or "value3".
-
-Objects, or pseudo-objects are instantiated using the "=>" construct. For
-example:
-
-> myobject => parameter
-
-creates an object called "myobject" with some parameter whose definition
-would be specific to that object. Note that the config file parser
-considers "=>" and "=" to be equivalent and their use is purely to make
-configuration files more readable and easier to "humanly parse".
-
-The comment character in Asterisk configuration files is the semicolon
-";". The reason it is not "#" is because the "#" symbol can be used as
-parts of extensions and it didn't seem like a good idea to have to escape
-it.
-
-IAX CONFIGURATION IN ASTERISK
------------------------------
-
-Like everything else in Asterisk, IAX's configuration lies in
-/etc/asterisk -- specifically /etc/asterisk/iax.conf
-
-The IAX configuration file is a collection of sections, each of which
-(with the exception of the "general" section) represents an entity within
-the IAX scope.
-
-------------
-
-The first section is typically the "general" section. In this area,
-a number of parameters which affect the entire system are configured.
-Specifically, the default codecs, port and address, jitter behavior, TOS
-bits, and registrations.
-
-The first line of the "general" section is always:
-
-> [general]
-
-Following the first line are a number of other possibilities:
-
-> bindport = <portnum>
-
-This sets the port that IAX will bind to. The default IAX version 1
-port number is 5036. For IAX version 2, that is now the default in
-Asterisk, the default port is 4569.
-It is recommended that this value not be altered in general.
-
-> bindaddr = <ipaddr>
-
-This allows you to bind IAX to a specific local IP address instead of
-binding to all addresses. This could be used to enhance security if, for
-example, you only wanted IAX to be available to users on your LAN.
-
-> bandwidth = [low|medium|high]
-
-The bandwidth selection initializes the codec selection to appropriate
-values for given bandwidths. The "high" selection enables all codecs and
-is recommended only for 10Mbps or higher connections. The "medium"
-bandwidth eliminates signed linear, Mu-law and A-law codecs, leaving only
-the codecs which are 32kbps and smaller (with MP3 as a special case). It
-can be used with broadband connections if desired. "low" eliminates ADPCM
-and MP3 formats, leaving only the G.723.1, GSM, and LPC10.
-
-> allow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
-> disallow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
-
-The "allow" and "disallow" allow you to fine tune the codec selection
-beyond the initial bandwidth selection on a codec-by-codec basis.
-
-The recommended configuration is to select "low" bandwidth and then
-disallow the LPC10 codec just because it doesn't sound very good.
-
-> jitterbuffer = [yes|no]
-> dropcount = <dropamount>
-> maxjitterbuffer = <max>
-> maxexcessbuffer = <max>
-
-These parameters control the operation of the jitter buffer. The
-jitterbuffer should always be enabled unless you expect all your
-connections to be over a LAN.
-* drop count is the maximum number of voice packets to allow to drop
- (out of 100). Useful values are 3-10.
-* maxjitterbuffer is the maximum amount of jitter buffer to permit to be
- used.
-* maxexcessbuffer is the maximum amount of excess jitter buffer
- that is permitted before the jitter buffer is slowly shrunk to eliminate
- latency.
-* minexcessbuffer is the minimum amount of excess jitter buffer
-
-> accountcode = <code>
-> amaflags = [default|omit|billing|documentation]
-
-These parameters affect call detail record generation. The first sets the
-account code for records received with IAX. The account code can be
-overridden on a per-user basis for incoming calls (see below). The
-amaflags controls how the record is labeled ("omit" causes no record to be
-written. "billing" and "documentation" label the records as billing or
-documentation records respectively, and "default" selects the system
-default.
-
-> tos = [lowdelay|throughput|reliability|mincost|none]
-
-IAX can optionally set the TOS (Type of Service) bits to specified values
-to help improve performance in routing. The recommended value is
-"lowdelay", which many routers (including any Linux routers with 2.4
-kernels that have not been altered with ip tables) will give priority to
-these packets, improving voice quality.
-
-> register => <name>[:<secret>]@<host>[:port]
-
-Any number of registry entries may be instantiated in the general
-section. Registration allows Asterisk to notify a remote Asterisk server
-(with a fixed address) what our current address is. In order for
-registration to work, the remote Asterisk server will need to have a
-dynamic peer entry with the same name (and secret if provided).
-
-The name is a required field, and is the remote peer name that we wish to
-identify ourselves as. A secret may be provided as well. The secret is
-generally a shared password between the local server and the remote
-server. However, if the secret is in square brackets ([]'s) then it is
-interpreted as the name of a RSA key to use. In that case, the local Asterisk
-server must have the *private* key (/var/lib/asterisk/keys/<name>.key) and
-the remote server will have to have the corresponding public key.
-
-The "host" is a required field and is the hostname or IP address of the
-remote Asterisk server. The port specification is optional and is by
-default 4569 for iax2 if not specified.
-
-> notransfer = yes | no
-
-If an IAX phone calls another IAX phone by using a Asterisk server,
-Asterisk will transfer the call to go peer to peer. If you do not
-want this, turn on notransfer with a "yes". This is also settable
-for peers and users.
-
--------------
-
-The following sections, after "general" define either users, peers or
-friends. A "user" is someone who connects to us. A "peer" is someone
-that we connect to. A "friend" is simply shorthand for creating a "user"
-and "peer" with identical parameters (i.e. someone who can contact us and
-who we contact).
-
-> [identifier]
-
-The section begins with the identifier in square brackets. The identifier
-should be an alphanumeric string.
-
-> type = [user|peer|friend]
-
-This line tells Asterisk how to interpret this entity. Users are things
-that connect to us, while peers are phones we connect to, and a friend is
-shorthand for creating a user and a peer with identical information
-
-----------------
-User fields:
-
-> context = <context>
-
-One or more context lines may be specified in a user, thus giving the user
-access to place calls in the given contexts. Contexts are used by
-Asterisk to divide dialing plans into logical units each with the ability
-to have numbers interpreted differently, have their own security model,
-auxiliary switch handling, and include other contexts. Most users are
-given access to the default context. Trusted users could be given access
-to the local context for example.
-
-> permit = <ipaddr>/<netmask>
-> deny = <ipaddr>/<netmask>
-
-Permit and deny rules may be applied to users, allowing them to connect
-from certain IP addresses and not others. The permit and deny rules are
-interpreted in sequence and all are evaluated on a given IP address, with
-the final result being the decision. For example:
-
-> permit = 0.0.0.0/0.0.0.0
-> deny = 192.168.0.0/255.255.255.0
-
-would deny anyone in 192.168.0.0 with a netmask of 24 bits (class C),
-whereas:
-
-> deny = 192.168.0.0/24
-> permit = 0.0.0.0/0
-
-would not deny anyone since the final rule would permit anyone, thus
-overriding the denial.
-
-If no permit/deny rules are listed, it is assumed that someone may connect
-from anywhere.
-
-> callerid = <callerid>
-
-You may override the Caller*ID information passed by a user to you (if
-they choose to send it) in order that it always be accurate from the
-perspective of your server.
-
-> auth = [md5|plaintext|rsa]
-
-You may select which authentication methods are permitted to be used by
-the user to authenticate to us. Multiple methods may be specified,
-separated by commas. If md5 or plaintext authentication is selected, a
-secret must be provided. If RSA authentication is specified, then one or
-more key names must be specified with "inkeys"
-
-If no secret is specified and no authentication method is specified, then
-no authentication will be required.
-
-> secret = <secret>
-
-The "secret" line specifies the shared secret for md5 and plaintext
-authentication methods. It is never suggested to use plaintext except in
-some cases for debugging.
-
-> inkeys = key1[:key2...]
-
-The "inkeys" line specifies which keys we can use to authenticate the
-remote peer. If the peer's challenge passes with any of the given keys,
-then we accept its authentication. The key files live in
-/var/lib/asterisk/keys/<name>.pub and are *public keys*. Public keys are
-not typically DES3 encrypted and thus do not usually need initialization.
-
----------------
-Peer configuration
-
-> allow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
-> disallow = [gsm|lpc10|g723.1|adpcm|ulaw|alaw|mp3|slinear|all]
-
-The "allow" and "disallow" may be used to enable or disable specific codec
-support on a per-peer basis.
-
-> host = [<ipaddr>|dynamic]
-
-The host line specifies the hostname or IP address of the remote host, or
-may be the word "dynamic" signifying that the host will register with us
-(see register => in the general section above).
-
-> defaultip = <ipaddr>
-
-If the host uses dynamic registration, Asterisk may still be given a
-default IP address to use when dynamic registration has not been performed
-or has timed out.
-
-> peercontext = <context>
-
-Specifies the context name to be passed to the peer for it to use when routing
-the call through its dial plan. This entry will be used only if a context
-is not included in the IAX2 channel name passed to the Dial command.
-
-> qualify = [yes | no | <value>]
-
-Qualify turns on checking of availability of the remote peer. If the
-peer becomes unavailable, no calls are placed to the peer until
-it is reachable again. This is also helpful in certain NAT situations.
-
-> jitterbuffer = [yes | no]
-
-Turns on or off the jitterbuffer for this peer
-
-> mailbox = <mailbox>[@mailboxcontext]
-
-Specifies a mailbox to check for voicemail notification.
-
-> permit = <ipaddr>/<netmask>
-> deny = <ipaddr>/<netmask>
-
-Permit and deny rules may be applied to users, allowing them to connect
-from certain IP addresses and not others. The permit and deny rules are
-interpreted in sequence and all are evaluated on a given IP address, with
-the final result being the decision. See the user section above
-for examples.
-
-----------------------------------------------------------------------
-For more examples of a configuration, please see the iax.conf.sample in
-your the /configs directory of you source code distribution
diff --git a/1.4/doc/channels.txt b/1.4/doc/channels.txt
deleted file mode 100644
index b907a92aa..000000000
--- a/1.4/doc/channels.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-Implementing a Channel
-======================
-
-* What is a channel?
-
-A channel is a unit which brings in a call to the Asterisk PBX. A channel
-could be connected to a real telephone (like the Internet Phone Jack) or
-to a logical call (like an Internet phone call). Asterisk makes no
-distinction between "FXO" and "FXS" style channels (that is, it doesn't
-distinguish between telephone lines and telephones).
-
-Every call is placed or received on a distinct channel. Asterisk uses a
-channel driver (typically named chan_xxx.so) to support each type of
-hardware.
-
-* What do I need to create a channel?
-
-In order to support a new piece of hardware you need to write a channel
-driver. The easiest way to do so is to look at an existing channel driver
-and model your own code after it.
-
-* What's the general architecture?
-
-Typically, a channel reads a configuration file on startup which tells it
-something about the hardware it's going to be servicing. Then, it
-launches a thread which monitors all the idle channels (See the chan_modem
-or the chan_ixj for an example of this). When a "RING" or equivalent is
-detected, the monitoring thread should allocate a channel structure and
-assign all the callbacks to it (see ixj_new, for example), and then call
-ast_pbx_start on that channel. ast_pbx_start will launch a new thread to
-handle the channel as long as the call is up, so once pbx_start has
-successfully been run, the monitor should no longer monitor that channel.
-The PBX thread will use the channel, reading, writing, calling, etc., and
-multiplexing that channel with others using select() on the channel's
-file descriptor (if your channel doesn't have an associated file
-descriptor, you'll need to emulate one somehow, perhaps along the lines of
-what the translator API does with its channel.
-
-When the PBX is finished with the line, it will hang up the line, at which
-point it the hardware should again be monitored by the monitoring thread.
-
----------------
-For more information, please consult the Asterisk Developer's Documentation
-on http://www.asterisk.org
diff --git a/1.4/doc/channelvariables.txt b/1.4/doc/channelvariables.txt
deleted file mode 100644
index 761516fa7..000000000
--- a/1.4/doc/channelvariables.txt
+++ /dev/null
@@ -1,815 +0,0 @@
-----------------------------
-Asterisk dial plan variables
-----------------------------
-
-There are two levels of parameter evaluation done in the Asterisk
-dial plan in extensions.conf.
-* The first, and most frequently used, is the substitution of variable
- references with their values.
-* Then there are the evaluations of expressions done in $[ .. ].
- This will be discussed below.
-
-Asterisk has user-defined variables and standard variables set
-by various modules in Asterisk. These standard variables are
-listed at the end of this document.
-
-___________________________
-PARAMETER QUOTING:
----------------------------
-
-exten => s,5,BackGround,blabla
-
-The parameter (blabla) can be quoted ("blabla"). In this case, a
-comma does not terminate the field. However, the double quotes
-will be passed down to the Background command, in this example.
-
-Also, characters special to variable substitution, expression evaluation, etc
-(see below), can be quoted. For example, to literally use a $ on the
-string "$1231", quote it with a preceding \. Special characters that must
-be quoted to be used, are [ ] $ " \. (to write \ itself, use \\).
-
-These Double quotes and escapes are evaluated at the level of the
-asterisk config file parser.
-
-Double quotes can also be used inside expressions, as discussed below.
-
-___________________________
-VARIABLES:
----------------------------
-
-Parameter strings can include variables. Variable names are arbitrary strings.
-They are stored in the respective channel structure.
-
-To set a variable to a particular value, do :
-
- exten => 1,2,Set(varname=value)
-
-You can substitute the value of a variable everywhere using ${variablename}.
-For example, to stringwise append $lala to $blabla and store result in $koko,
-do:
-
- exten => 1,2,Set(koko=${blabla}${lala})
-
-
-There are two reference modes - reference by value and reference by name.
-To refer to a variable with its name (as an argument to a function that
-requires a variable), just write the name. To refer to the variable's value,
-enclose it inside ${}. For example, Set takes as the first argument
-(before the =) a variable name, so:
-
- exten => 1,2,Set(koko=lala)
- exten => 1,3,Set(${koko}=blabla)
-
-stores to the variable "koko" the value "lala" and to variable "lala" the
-value "blabla".
-
-In fact, everything contained ${here} is just replaced with the value of
-the variable "here".
-
-____________________
-VARIABLE INHERITANCE
---------------------
-
-Variable names which are prefixed by "_" will be inherited to channels
-that are created in the process of servicing the original channel in
-which the variable was set. When the inheritance takes place, the
-prefix will be removed in the channel inheriting the variable. If the
-name is prefixed by "__" in the channel, then the variable is
-inherited and the "__" will remain intact in the new channel.
-
-In the dialplan, all references to these variables refer to the same
-variable, regardless of having a prefix or not. Note that setting any
-version of the variable removes any other version of the variable,
-regardless of prefix.
-
-Example:
-
-Set(__FOO=bar) ; Sets an inherited version of "FOO" variable
-Set(FOO=bar) ; Removes the inherited version and sets a local
- ; variable.
-
-However,
-
-NoOp(${__FOO}) is identical to NoOp(${FOO})
-
-
-
-___________________________________
-SELECTING CHARACTERS FROM VARIABLES
------------------------------------
-
-The format for selecting characters from a variable can be expressed as:
-
- ${variable_name[:offset[:length]]}
-
-If you want to select the first N characters from the string assigned
-to a variable, simply append a colon and the number of characters to
-skip from the beginning of the string to the variable name.
-
- ;Remove the first character of extension, save in "number" variable
- exten => _9X.,1,Set(number=${EXTEN:1})
-
-Assuming we've dialed 918005551234, the value saved to the 'number' variable
-would be 18005551234. This is useful in situations when we require users to
-dial a number to access an outside line, but do not wish to pass the first
-digit.
-
-If you use a negative offset number, Asterisk starts counting from the end
-of the string and then selects everything after the new position. The following
-example will save the numbers 1234 to the 'number' variable, still assuming
-we've dialed 918005551234.
-
- ;Remove everything before the last four digits of the dialed string
- exten => _9X.,1,Set(number=${EXTEN:-4})
-
-We can also limit the number of characters from our offset position that we
-wish to use. This is done by appending a second colon and length value to the
-variable name. The following example will save the numbers 555 to the 'number'
-variable.
-
- ;Only save the middle numbers 555 from the string 918005551234
- exten => _9X.,1,Set(number=${EXTEN:5:3})
-
-The length value can also be used in conjunction with a negative offset. This
-may be useful if the length of the string is unknown, but the trailing digits
-are. The following example will save the numbers 555 to the 'number' variable,
-even if the string starts with more characters than expected (unlike the
-previous example).
-
- ;Save the numbers 555 to the 'number' variable
- exten => _9X.,1,Set(number=${EXTEN:-7:3})
-
-If a negative length value is entered, Asterisk will remove that many characters
-from the end of the string.
-
- ;Set pin to everything but the trailing #.
- exten => _XXXX#,1,Set(pin=${EXTEN:0:-1})
-
-___________________________
-EXPRESSIONS:
----------------------------
-
-Everything contained inside a bracket pair prefixed by a $ (like $[this]) is
-considered as an expression and it is evaluated. Evaluation works similar to
-(but is done on a later stage than) variable substitution: the expression
-(including the square brackets) is replaced by the result of the expression
-evaluation.
-
-For example, after the sequence:
-
-exten => 1,1,Set(lala=$[1 + 2])
-exten => 1,2,Set(koko=$[2 * ${lala}])
-
-the value of variable koko is "6".
-
-and, further:
-
-exten => 1,1,Set,(lala=$[ 1 + 2 ]);
-
-will parse as intended. Extra spaces are ignored.
-
-
-______________________________
-SPACES INSIDE VARIABLE VALUES
-------------------------------
-If the variable being evaluated contains spaces, there can be problems.
-
-For these cases, double quotes around text that may contain spaces
-will force the surrounded text to be evaluated as a single token.
-The double quotes will be counted as part of that lexical token.
-
-As an example:
-
-exten => s,6,GotoIf($[ "${CALLERIDNAME}" : "Privacy Manager" ]?callerid-liar|s|1:s|7)
-
-The variable CALLERIDNAME could evaluate to "DELOREAN MOTORS" (with a space)
-but the above will evaluate to:
-
-"DELOREAN MOTORS" : "Privacy Manager"
-
-and will evaluate to 0.
-
-The above without double quotes would have evaluated to:
-
-DELOREAN MOTORS : Privacy Manager
-
-and will result in syntax errors, because token DELOREAN is immediately
-followed by token MOTORS and the expression parser will not know how to
-evaluate this expression, because it does not match its grammar.
-
-_____________________
-OPERATORS
----------------------
-Operators are listed below in order of increasing precedence. Operators
-with equal precedence are grouped within { } symbols.
-
- expr1 | expr2
- Return the evaluation of expr1 if it is neither an empty string
- nor zero; otherwise, returns the evaluation of expr2.
-
- expr1 & expr2
- Return the evaluation of expr1 if neither expression evaluates to
- an empty string or zero; otherwise, returns zero.
-
- expr1 {=, >, >=, <, <=, !=} expr2
- Return the results of integer comparison if both arguments are
- integers; otherwise, returns the results of string comparison
- using the locale-specific collation sequence. The result of each
- comparison is 1 if the specified relation is true, or 0 if the
- relation is false.
-
- expr1 {+, -} expr2
- Return the results of addition or subtraction of integer-valued
- arguments.
-
- expr1 {*, /, %} expr2
- Return the results of multiplication, integer division, or
- remainder of integer-valued arguments.
-
- - expr1
- Return the result of subtracting expr1 from 0.
- This, the unary minus operator, is right associative, and
- has the same precedence as the ! operator.
-
- ! expr1
- Return the result of a logical complement of expr1.
- In other words, if expr1 is null, 0, an empty string,
- or the string "0", return a 1. Otherwise, return a 0.
- It has the same precedence as the unary minus operator, and
- is also right associative.
-
- expr1 : expr2
- The `:' operator matches expr1 against expr2, which must be a
- regular expression. The regular expression is anchored to the
- beginning of the string with an implicit `^'.
-
- If the match succeeds and the pattern contains at least one regu-
- lar expression subexpression `\(...\)', the string correspond-
- ing to `\1' is returned; otherwise the matching operator
- returns the number of characters matched. If the match fails and
- the pattern contains a regular expression subexpression the null
- string is returned; otherwise 0.
-
- Normally, the double quotes wrapping a string are left as part
- of the string. This is disastrous to the : operator. Therefore,
- before the regex match is made, beginning and ending double quote
- characters are stripped from both the pattern and the string.
-
- expr1 =~ expr2
- Exactly the same as the ':' operator, except that the match is
- not anchored to the beginning of the string. Pardon any similarity
- to seemingly similar operators in other programming languages!
- The ":" and "=~" operators share the same precedence.
-
- expr1 ? expr2 :: expr3
- Traditional Conditional operator. If expr1 is a number
- that evaluates to 0 (false), expr3 is result of the this
- expression evaluation. Otherwise, expr2 is the result.
- If expr1 is a string, and evaluates to an empty string,
- or the two characters (""), then expr3 is the
- result. Otherwise, expr2 is the result. In Asterisk, all
- 3 exprs will be "evaluated"; if expr1 is "true", expr2
- will be the result of the "evaluation" of this
- expression. expr3 will be the result otherwise. This
- operator has the lowest precedence.
-
-Parentheses are used for grouping in the usual manner.
-
-Operator precedence is applied as one would expect in any of the C
-or C derived languages.
-
-Examples
-
- "One Thousand Five Hundred" =~ "(T[^ ]+)"
- returns: Thousand
-
- "One Thousand Five Hundred" =~ "T[^ ]+"
- returns: 8
-
- "One Thousand Five Hundred" : "T[^ ]+"
- returns: 0
-
- "8015551212" : "(...)"
- returns: 801
-
- "3075551212":"...(...)"
- returns: 555
-
- ! "One Thousand Five Hundred" =~ "T[^ ]+"
- returns: 0 (because it applies to the string, which is non-null,
- which it turns to "0", and then looks for the pattern
- in the "0", and doesn't find it)
-
- !( "One Thousand Five Hundred" : "T[^ ]+" )
- returns: 1 (because the string doesn't start with a word starting
- with T, so the match evals to 0, and the ! operator
- inverts it to 1 ).
-
- 2 + 8 / 2
- returns 6. (because of operator precedence; the division is done first, then the addition).
-
- 2+8/2
- returns 6. Spaces aren't necessary.
-
-(2+8)/2
- returns 5, of course.
-
-Of course, all of the above examples use constants, but would work the
-same if any of the numeric or string constants were replaced with a
-variable reference ${CALLERIDNUM}, for instance.
-
-__________________________
-NUMBERS VS STRINGS
---------------------------
-
-Tokens consisting only of numbers are converted to 64-bit numbers for
-most of the operators. This means that overflows can occur when the
-numbers get above 18 digits. Warnings will appear in the logs in this
-case.
-___________________________
-CONDITIONALS
----------------------------
-
-There is one conditional application - the conditional goto :
-
- exten => 1,2,gotoif(condition?label1:label2)
-
-If condition is true go to label1, else go to label2. Labels are interpreted
-exactly as in the normal goto command.
-
-"condition" is just a string. If the string is empty or "0", the condition
-is considered to be false, if it's anything else, the condition is true.
-This is designed to be used together with the expression syntax described
-above, eg :
-
- exten => 1,2,gotoif($[${CALLERID} = 123456]?2|1:3|1)
-
-Example of use :
-
-exten => s,2,Set(vara=1)
-exten => s,3,Set(varb=$[${vara} + 2])
-exten => s,4,Set(varc=$[${varb} * 2])
-exten => s,5,GotoIf($[${varc} = 6]?99|1:s|6)
-
-___________________________
-PARSE ERRORS
----------------------------
-
-Syntax errors are now output with 3 lines.
-
-If the extensions.conf file contains a line like:
-
-exten => s,6,GotoIf($[ "${CALLERIDNUM}" = "3071234567" & & "${CALLERIDNAME}" : "Privacy Manager" ]?callerid-liar|s|1:s|7)
-
-You may see an error in /var/log/asterisk/messages like this:
-
-Jul 15 21:27:49 WARNING[1251240752]: ast_yyerror(): syntax error: parse error, unexpected TOK_AND, expecting TOK_MINUS or TOK_LP or TOKEN; Input:
-"3072312154" = "3071234567" & & "Steves Extension" : "Privacy Manager"
- ^
-
-The log line tells you that a syntax error was encountered. It now
-also tells you (in grand standard bison format) that it hit an "AND"
-(&) token unexpectedly, and that was hoping for for a MINUS (-), LP
-(left parenthesis), or a plain token (a string or number).
-
-The next line shows the evaluated expression, and the line after
-that, the position of the parser in the expression when it became confused,
-marked with the "^" character.
-
-___________________________
-NULL STRINGS
----------------------------
-
-Testing to see if a string is null can be done in one of two different ways:
-
- exten => _XX.,1,GotoIf($["${calledid}" != ""]?3)
-
- exten => _XX.,1,GotoIf($[foo${calledid} != foo]?3)
-
-
-The second example above is the way suggested by the WIKI. It will
-work as long as there are no spaces in the evaluated value.
-
-The first way should work in all cases, and indeed, might now
-be the safest way to handle this situation.
-
-___________________________
-WARNING
----------------------------
-
-If you need to do complicated things with strings, asterisk expressions
-is most likely NOT the best way to go about it. AGI scripts are an
-excellent option to this need, and make available the full power of
-whatever language you desire, be it Perl, C, C++, Cobol, RPG, Java,
-Snobol, PL/I, Scheme, Common Lisp, Shell scripts, Tcl, Forth, Modula,
-Pascal, APL, assembler, etc.
-
-----------------------------
-INCOMPATIBILITIES
-----------------------------
-
-The asterisk expression parser has undergone some evolution. It is hoped
-that the changes will be viewed as positive.
-
-The "original" expression parser had a simple, hand-written scanner,
-and a simple bison grammar. This was upgraded to a more involved bison
-grammar, and a hand-written scanner upgraded to allow extra spaces,
-and to generate better error diagnostics. This upgrade required bison
-1.85, and part of the user community felt the pain of having to
-upgrade their bison version.
-
-The next upgrade included new bison and flex input files, and the makefile
-was upgraded to detect current version of both flex and bison, conditionally
-compiling and linking the new files if the versions of flex and bison would
-allow it.
-
-If you have not touched your extensions.conf files in a year or so, the
-above upgrades may cause you some heartburn in certain circumstances, as
-several changes have been made, and these will affect asterisk's behavior on
-legacy extension.conf constructs. The changes have been engineered
-to minimize these conflicts, but there are bound to be problems.
-
-The following list gives some (and most likely, not all) of areas
-of possible concern with "legacy" extension.conf files:
-
-1. Tokens separated by space(s).
- Previously, tokens were separated by spaces. Thus, ' 1 + 1 ' would evaluate
- to the value '2', but '1+1' would evaluate to the string '1+1'. If this
- behavior was depended on, then the expression evaluation will break. '1+1'
- will now evaluate to '2', and something is not going to work right.
- To keep such strings from being evaluated, simply wrap them in double
- quotes: ' "1+1" '
-
-2. The colon operator. In versions previous to double quoting, the
- colon operator takes the right hand string, and using it as a
- regex pattern, looks for it in the left hand string. It is given
- an implicit ^ operator at the beginning, meaning the pattern
- will match only at the beginning of the left hand string.
- If the pattern or the matching string had double quotes around
- them, these could get in the way of the pattern match. Now,
- the wrapping double quotes are stripped from both the pattern
- and the left hand string before applying the pattern. This
- was done because it recognized that the new way of
- scanning the expression doesn't use spaces to separate tokens,
- and the average regex expression is full of operators that
- the scanner will recognize as expression operators. Thus, unless
- the pattern is wrapped in double quotes, there will be trouble.
- For instance, ${VAR1} : (Who|What*)+
- may have have worked before, but unless you wrap the pattern
- in double quotes now, look out for trouble! This is better:
- "${VAR1}" : "(Who|What*)+"
- and should work as previous.
-
-3. Variables and Double Quotes
- Before these changes, if a variable's value contained one or more double
- quotes, it was no reason for concern. It is now!
-
-4. LE, GE, NE operators removed. The code supported these operators,
- but they were not documented. The symbolic operators, <=, >=, and !=
- should be used instead.
-
-5. Added the unary '-' operator. So you can 3+ -4 and get -1.
-
-6. Added the unary '!' operator, which is a logical complement.
- Basically, if the string or number is null, empty, or '0',
- a '1' is returned. Otherwise a '0' is returned.
-
-7. Added the '=~' operator, just in case someone is just looking for
- match anywhere in the string. The only diff with the ':' is that
- match doesn't have to be anchored to the beginning of the string.
-
-8. Added the conditional operator 'expr1 ? true_expr :: false_expr'
- First, all 3 exprs are evaluated, and if expr1 is false, the 'false_expr'
- is returned as the result. See above for details.
-
-9. Unary operators '-' and '!' were made right associative.
-
---------------------------------------------------------
-DEBUGGING HINTS FOR $[ ] EXPRESSIONS
---------------------------------------------------------
-
-There are two utilities you can build to help debug the $[ ] in
-your extensions.conf file.
-
-The first, and most simplistic, is to issue the command:
-
-make testexpr2
-
-in the top level asterisk source directory. This will build a small
-executable, that is able to take the first command line argument, and
-run it thru the expression parser. No variable substitutions will be
-performed. It might be safest to wrap the expression in single
-quotes...
-
-testexpr2 '2*2+2/2'
-
-is an example.
-
-And, in the utils directory, you can say:
-
-make check_expr
-
-and a small program will be built, that will check the file mentioned
-in the first command line argument, for any expressions that might be
-have problems when you move to flex-2.5.31. It was originally
-designed to help spot possible incompatibilities when moving from the
-pre-2.5.31 world to the upgraded version of the lexer.
-
-But one more capability has been added to check_expr, that might make
-it more generally useful. It now does a simple minded evaluation of
-all variables, and then passes the $[] exprs to the parser. If there
-are any parse errors, they will be reported in the log file. You can
-use check_expr to do a quick sanity check of the expressions in your
-extensions.conf file, to see if they pass a crude syntax check.
-
-The "simple-minded" variable substitution replaces ${varname} variable
-references with '555'. You can override the 555 for variable values,
-by entering in var=val arguments after the filename on the command
-line. So...
-
- check_expr /etc/asterisk/extensions.conf CALLERIDNUM=3075551212 DIALSTATUS=TORTURE EXTEN=121
-
-will substitute any ${CALLERIDNUM} variable references with
-3075551212, any ${DIALSTATUS} variable references with 'TORTURE', and
-any ${EXTEN} references with '121'. If there is any fancy stuff
-going on in the reference, like ${EXTEN:2}, then the override will
-not work. Everything in the ${...} has to match. So, to substitute
-#{EXTEN:2} references, you'd best say:
-
- check_expr /etc/asterisk/extensions.conf CALLERIDNUM=3075551212 DIALSTATUS=TORTURE EXTEN:2=121
-
-on stdout, you will see something like:
-
- OK -- $[ "${DIALSTATUS}" = "TORTURE" | "${DIALSTATUS}" = "DONTCALL" ] at line 416
-
-In the expr2_log file that is generated, you will see:
-
- line 416, evaluation of $[ "TORTURE" = "TORTURE" | "TORTURE" = "DONTCALL" ] result: 1
-
-check_expr is a very simplistic algorithm, and it is far from being
-guaranteed to work in all cases, but it is hoped that it will be
-useful.
-
----------------------------------------------------------
-Asterisk standard channel variables
----------------------------------------------------------
-There are a number of variables that are defined or read
-by Asterisk. Here is a list of them. More information is
-available in each application's help text. All these variables
-are in UPPER CASE only.
-
-Variables marked with a * are builtin functions and can't be set,
-only read in the dialplan. Writes to such variables are silently
-ignored.
-
-${ACCOUNTCODE} * Account code (if specified) (Deprecated; use ${CDR(accountcode)})
-${BLINDTRANSFER} The name of the channel on the other side of a blind transfer
-${BRIDGEPEER} Bridged peer
-${CALLERANI} * Caller ANI (PRI channels) (Deprecated; use ${CALLERID(ani)})
-${CALLERID} * Caller ID (Deprecated; use ${CALLERID(all)})
-${CALLERIDNAME} * Caller ID Name only (Deprecated; use ${CALLERID(name)})
-${CALLERIDNUM} * Caller ID Number only (Deprecated; use ${CALLERID(num)})
-${CALLINGANI2} * Caller ANI2 (PRI channels)
-${CALLINGPRES} * Caller ID presentation for incoming calls (PRI channels)
-${CALLINGTNS} * Transit Network Selector (PRI channels)
-${CALLINGTON} * Caller Type of Number (PRI channels)
-${CHANNEL} * Current channel name
-${CONTEXT} * Current context
-${DATETIME} * Current date time in the format: DDMMYYYY-HH:MM:SS (Deprecated; use ${STRFTIME(${EPOCH},,%d%m%Y-%H:%M:%S)})
-${DB_RESULT} Result value of DB_EXISTS() dial plan function
-${DNID} * Dialed Number Identifier (Deprecated; use ${CALLERID(dnid)})
-${EPOCH} * Current unix style epoch
-${EXTEN} * Current extension
-${ENV(VAR)} Environmental variable VAR
-${GOTO_ON_BLINDXFR} Transfer to the specified context/extension/priority
- after a blind transfer (use ^ characters in place of
- | to separate context/extension/priority when setting
- this variable from the dialplan)
-${HANGUPCAUSE} * Asterisk cause of hangup (inbound/outbound)
-${HINT} * Channel hints for this extension
-${HINTNAME} * Suggested Caller*ID name for this extension
-${INVALID_EXTEN} The invalid called extension (used in the "i" extension)
-${LANGUAGE} * Current language (Deprecated; use ${LANGUAGE()})
-${LEN(VAR)} * String length of VAR (integer)
-${PRIORITY} * Current priority in the dialplan
-${PRIREDIRECTREASON} Reason for redirect on PRI, if a call was directed
-${RDNIS} * Redirected Dial Number ID Service (Deprecated; use ${CALLERID(rdnis)})
-${TIMESTAMP} * Current date time in the format: YYYYMMDD-HHMMSS (Deprecated; use ${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)})
-${TRANSFER_CONTEXT} Context for transferred calls
-${FORWARD_CONTEXT} Context for forwarded calls
-${UNIQUEID} * Current call unique identifier
-${SYSTEMNAME} * value of the systemname option of asterisk.conf
-
-Application return values
--------------------------
-In Asterisk 1.2, many applications return the result in a variable
-instead of, as in Asterisk 1.0, changing the dial plan priority (+101).
-For the various status values, see each application's help text.
-
-${AGISTATUS} * agi()
-${AQMSTATUS} * addqueuemember()
-${AVAILSTATUS} * chanisavail()
-${CHECKGROUPSTATUS} * checkgroup()
-${CHECKMD5STATUS} * checkmd5()
-${CPLAYBACKSTATUS} * controlplayback()
-${DIALSTATUS} * dial()
-${DBGETSTATUS} * dbget()
-${ENUMSTATUS} * enumlookup()
-${HASVMSTATUS} * hasnewvoicemail()
-${LOOKUPBLSTATUS} * lookupblacklist()
-${OSPAUTHSTATUS} * ospauth()
-${OSPLOOKUPSTATUS} * osplookup()
-${OSPNEXTSTATUS} * ospnext()
-${OSPFINISHSTATUS} * ospfinish()
-${PARKEDAT} * parkandannounce()
-${PLAYBACKSTATUS} * playback()
-${PQMSTATUS} * pausequeuemember()
-${PRIVACYMGRSTATUS} * privacymanager()
-${QUEUESTATUS} * queue()
-${RQMSTATUS} * removequeuemember()
-${SENDIMAGESTATUS} * sendimage()
-${SENDTEXTSTATUS} * sendtext()
-${SENDURLSTATUS} * sendurl()
-${SYSTEMSTATUS} * system()
-${TRANSFERSTATUS} * transfer()
-${TXTCIDNAMESTATUS} * txtcidname()
-${UPQMSTATUS} * unpausequeuemember()
-${VMSTATUS} * voicmail()
-${VMBOXEXISTSSTATUS} * vmboxexists()
-${WAITSTATUS} * waitforsilence()
-
-
-Various application variables
------------------------------
-${CURL} * Resulting page content for curl()
-${ENUM} * Result of application EnumLookup
-${EXITCONTEXT} Context to exit to in IVR menu (app background())
- or in the RetryDial() application
-${MONITOR} * Set to "TRUE" if the channel is/has been monitored (app monitor())
-${MONITOR_EXEC} Application to execute after monitoring a call
-${MONITOR_EXEC_ARGS} Arguments to application
-${MONITOR_FILENAME} File for monitoring (recording) calls in queue
-${QUEUE_PRIO} Queue priority
-${QUEUE_MAX_PENALTY} Maximum member penalty allowed to answer caller
-${QUEUESTATUS} Status of the call, one of:
- (TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL)
-${RECORDED_FILE} * Recorded file in record()
-${TALK_DETECTED} * Result from talkdetect()
-${TOUCH_MONITOR} The filename base to use with Touch Monitor (auto record)
-${TOUCH_MONITOR_FORMAT} The audio format to use with Touch Monitor (auto record)
-${TOUCH_MONITOR_OUTPUT} * Recorded file from Touch Monitor (auto record)
-${TXTCIDNAME} * Result of application TXTCIDName
-${VPB_GETDTMF} chan_vpb
-
-The MeetMe Conference Bridge uses the following variables:
-----------------------------------------------------------
-${MEETME_RECORDINGFILE} Name of file for recording a conference with
- the "r" option
-${MEETME_RECORDINGFORMAT} Format of file to be recorded
-${MEETME_EXIT_CONTEXT} Context for exit out of meetme meeting
-${MEETME_AGI_BACKGROUND} AGI script for Meetme (zap only)
-${MEETMESECS} * Number of seconds a user participated in a MeetMe conference
-
-The VoiceMail() application uses the following variables:
----------------------------------------------------------
-${VM_CATEGORY} Sets voicemail category
-${VM_NAME} * Full name in voicemail
-${VM_DUR} * Voicemail duration
-${VM_MSGNUM} * Number of voicemail message in mailbox
-${VM_CALLERID} * Voicemail Caller ID (Person leaving vm)
-${VM_CIDNAME} * Voicemail Caller ID Name
-${VM_CIDNUM} * Voicemail Caller ID Number
-${VM_DATE} * Voicemail Date
-${VM_MESSAGEFILE} * Path to message left by caller
-
-The VMAuthenticate() application uses the following variables:
----------------------------------------------------------
-${AUTH_MAILBOX} * Authenticated mailbox
-${AUTH_CONTEXT} * Authenticated mailbox context
-
-DUNDiLookup() uses the following variables
----------------------------------------------------------
-${DUNDTECH} * The Technology of the result from a call to DUNDiLookup()
-${DUNDDEST} * The Destination of the result from a call to DUNDiLookup()
-
-The Zaptel channel sets the following variables:
----------------------------------------------------------
-${ANI2} * The ANI2 Code provided by the network on the incoming call.
- (ie, Code 29 identifies call as a Prison/Inmate Call)
-${CALLTYPE} * Type of call (Speech, Digital, etc)
-${CALLEDTON} * Type of number for incoming PRI extension
- i.e. 0=unknown, 1=international, 2=domestic, 3=net_specific,
- 4=subscriber, 6=abbreviated, 7=reserved
-${CALLINGSUBADDR} * Called PRI Subaddress
-${FAXEXTEN} * The extension called before being redirected to "fax"
-${PRIREDIRECTREASON} * Reason for redirect, if a call was directed
-${SMDI_VM_TYPE} * When an call is received with an SMDI message, the 'type'
- of message 'b' or 'u'
-
-The SIP channel uses the following variables:
----------------------------------------------------------
-${SIPCALLID} * SIP Call-ID: header verbatim (for logging or CDR matching)
-${SIPDOMAIN} * SIP destination domain of an inbound call (if appropriate)
-${SIPUSERAGENT} * SIP user agent (deprecated)
-${SIPURI} * SIP uri
-${SIP_CODEC} Set the SIP codec for a call
-${SIP_URI_OPTIONS} * additional options to add to the URI for an outgoing call
-${RTPAUDIOQOS} RTCP QoS report for the audio of this call
-${RTPVIDEOQOS} RTCP QoS report for the video of this call
-
-The Agent channel uses the following variables:
----------------------------------------------------------
-${AGENTMAXLOGINTRIES} Set the maximum number of failed logins
-${AGENTUPDATECDR} Whether to update the CDR record with Agent channel data
-${AGENTGOODBYE} Sound file to use for "Good Bye" when agent logs out
-${AGENTACKCALL} Whether the agent should acknowledge the incoming call
-${AGENTAUTOLOGOFF} Auto logging off for an agent
-${AGENTWRAPUPTIME} Setting the time for wrapup between incoming calls
-${AGENTNUMBER} * Agent number (username) set at login
-${AGENTSTATUS} * Status of login ( fail | on | off )
-${AGENTEXTEN} * Extension for logged in agent
-
-The Dial() application uses the following variables:
----------------------------------------------------------
-${DIALEDPEERNAME} * Dialed peer name
-${DIALEDPEERNUMBER} * Dialed peer number
-${DIALEDTIME} * Time for the call (seconds)
-${ANSWEREDTIME} * Time from dial to answer (seconds)
-${DIALSTATUS} * Status of the call, one of:
- (CHANUNAVAIL | CONGESTION | BUSY | NOANSWER
- | ANSWER | CANCEL | DONTCALL | TORTURE)
-${DYNAMIC_FEATURES} * The list of features (from the [applicationmap] section of
- features.conf) to activate during the call, with feature
- names separated by '#' characters
-${LIMIT_PLAYAUDIO_CALLER} Soundfile for call limits
-${LIMIT_PLAYAUDIO_CALLEE} Soundfile for call limits
-${LIMIT_WARNING_FILE} Soundfile for call limits
-${LIMIT_TIMEOUT_FILE} Soundfile for call limits
-${LIMIT_CONNECT_FILE} Soundfile for call limits
-${OUTBOUND_GROUP} Default groups for peer channels (as in SetGroup)
-* See "show application dial" for more information
-
-The chanisavail() application sets the following variables:
------------------------------------------------------------
-${AVAILCHAN} * the name of the available channel if one was found
-${AVAILORIGCHAN} * the canonical channel name that was used to create the channel
-${AVAILSTATUS} * Status of requested channel
-
-When using macros in the dialplan, these variables are available
----------------------------------------------------------
-${MACRO_EXTEN} * The calling extensions
-${MACRO_CONTEXT} * The calling context
-${MACRO_PRIORITY} * The calling priority
-${MACRO_OFFSET} Offset to add to priority at return from macro
-
-The ChanSpy() application uses the following variables:
----------------------------------------------------------
-${SPYGROUP} * A ':' (colon) separated list of group names.
- (To be set on spied on channel and matched against the g(grp) option)
-
-If you compile with OSP support, these variables are used:
----------------------------------------------------------
-${OSPINHANDLE} OSP handle of in_bound call
-${OSPINTIMELIMIT} Duration limit for in_bound call
-${OSPOUTHANDLE} OSP handle of out_bound call
-${OSPTECH} OSP technology
-${OSPDEST} OSP destination
-${OSPCALLING} OSP calling number
-${OSPOUTTOKEN} OSP token to use for out_bound call
-${OSPOUTTIMELIMIT} Duration limit for out_bound call
-${OSPRESULTS} Number of remained destinations
-
-____________________________________
-CDR Variables
-------------------------------------
-
-If the channel has a cdr, that cdr record has it's own set of variables which
-can be accessed just like channel variables. The following builtin variables
-are available.
-
-${CDR(clid)} Caller ID
-${CDR(src)} Source
-${CDR(dst)} Destination
-${CDR(dcontext)} Destination context
-${CDR(channel)} Channel name
-${CDR(dstchannel)} Destination channel
-${CDR(lastapp)} Last app executed
-${CDR(lastdata)} Last app's arguments
-${CDR(start)} Time the call started.
-${CDR(answer)} Time the call was answered.
-${CDR(end)} Time the call ended.
-${CDR(duration)} Duration of the call.
-${CDR(billsec)} Duration of the call once it was answered.
-${CDR(disposition)} ANSWERED, NO ANSWER, BUSY
-${CDR(amaflags)} DOCUMENTATION, BILL, IGNORE etc
-${CDR(accountcode)} The channel's account code.
-${CDR(uniqueid)} The channel's unique id.
-${CDR(userfield)} The channels uses specified field.
-
-
-In addition, you can set your own extra variables with a traditional
-Set(CDR(var)=val) to anything you want.
-
-Certain functional variables may be accessed with ${foo(<args>)}. A list
-of these functional variables may be found by typing "show functions"
-at the Asterisk CLI.
diff --git a/1.4/doc/cliprompt.txt b/1.4/doc/cliprompt.txt
deleted file mode 100644
index fbd7dd99f..000000000
--- a/1.4/doc/cliprompt.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-* Changing the CLI Prompt
--------------------------
-
-The CLI prompt is set with the ASTERISK_PROMPT UNIX environment variable that
-you set from the Unix shell before starting Asterisk
-
-You may include the following variables, that will be replaced by
-the current value by Asterisk:
-
-%d Date (year-month-date)
-%s Asterisk system name (from asterisk.conf)
-%h Full hostname
-%H Short hostname
-%t Time
-%% Percent sign
-%# '#' if Asterisk is run in console mode, '>' if running as remote console
-%Cn[;n] Change terminal foreground (and optional background) color to specified
- A full list of colors may be found in include/asterisk/term.h
-
-On Linux systems, you may also use
-%l1 Load average over past minute
-%l2 Load average over past 5 minutes
-%l3 Load average over past 15 minutes
-%l4 Process fraction (processes running / total processes)
-%l5 The most recently allocated pid
-
-
------
-04-03-26
diff --git a/1.4/doc/configuration.txt b/1.4/doc/configuration.txt
deleted file mode 100644
index 43173b1b4..000000000
--- a/1.4/doc/configuration.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-Asterisk Configuration Parser (version 1.1 and later)
------------------------------------------------------
-
-The Asterisk configuration parser in the 1.1 development version (1.2
-stable) and beyond series has been improved in a number of ways. In
-addition to the realtime architecture, we now have the ability to create
-templates in configuration files, and use these as templates when we
-configure phones, voicemail accounts and queues.
-
-These changes are general to the configuration parser, and works in
-all configuration files.
-
-General syntax
---------------
-Asterisk configuration files are defined as follows:
-
- [section]
- label = value
- label2 = value
-
-In some files, (e.g. mgcp.conf, zapata.conf and agents.conf), the syntax
-is a bit different. In these files the syntax is as follows:
-
- [section]
- label1 = value1
- label2 = value2
- object => name
-
- label3 = value3
- label2 = value4
- object2 => name2
-
-In this syntax, we create objects with the settings defined above the object
-creation. Note that settings are inherited from the top, so in the example
-above object2 has inherited the setting for "label1" from the first object.
-
-For template configurations, the syntax for defining a section is changed
-to
- [section](options)
- label = value
-
-The options field is used to define templates, refer to templates and hide
-templates. Any object can be used as a template.
-
-No whitespace is allowed between the closing "]" and the parenthesis "(".
-
-Comments
---------
-All lines that starts with semi-colon ";" is treated as comments
-and is not parsed.
-
-The ";--" is a marker for a multi-line comment. Everything after
-that marker will be treated as a comment until the end-marker "--;"
-is found. Parsing begins directly after the end-marker.
-
- ;This is a comment
- label = value
- ;-- This is
- a comment --;
-
- ;-- Comment --; exten=> 1000,1,dial(SIP/lisa)
-
-Including other files
----------------------
-In all of the configuration files, you may include the content of another
-file with the #include statement. The content of the other file will be
-included at the row that the #include statement occurred.
-
- #include myusers.conf
-
-You may also include the output of a program with the #exec directive,
-if you enable it in asterisk.conf
-
-In asterisk.conf, add the execincludes = yes statement in the options
-section:
- [options]
- execincludes=yes
-
-The exec directive is used like this:
-
- #exec /usr/local/bin/myasteriskconfigurator.sh
-
-Adding to an existing section
------------------------------
-
- [section]
- label = value
-
- [section](+)
- label2 = value2
-
-In this case, the plus sign indicates that the second section (with the
-same name) is an addition to the first section. The second section can
-be in another file (by using the #include statement). If the section
-name referred to before the plus is missing, the configuration will fail
-to load.
-
-Defining a template-only section
---------------------------------
- [section](!)
- label = value
-
-The exclamation mark indicates to the config parser that this is a only
-a template and should not itself be used by the Asterisk module for
-configuration. The section can be inherited by other sections (see
-section "Using templates" below) but is not used by itself.
-
-Using templates (or other configuration sections)
--------------------------------------------------
- [section](name[,name])
- label = value
-
-The name within the parenthesis refers to other sections, either
-templates or standard sections. The referred sections are included
-before the configuration engine parses the local settings within the
-section as though their entire contents (and anything they were
-previously based upon) were included in the new section. For example
-consider the following:
-
-[foo]
-permit=192.168.0.2
-host=asdf
-deny=192.168.0.1
-
-[bar]
-permit=192.168.1.2
-host=jkl
-deny=192.168.1.1
-
-[baz](foo,bar)
-permit=192.168.3.1
-host=bnm
-
-The [baz] section will be processed as though it had been written in the
-following way:
-
-[baz]
-permit=192.168.0.2
-host=asdf
-deny=192.168.0.1
-permit=192.168.1.2
-host=jkl
-deny=192.168.1.1
-permit=192.168.3.1
-host=bnm
-
-Additional Examples:
---------------------
-
-(in top-level sip.conf)
-
-[defaults](!)
-type=friend
-nat=yes
-qualify=on
-dtmfmode=rfc2833
-disallow=all
-allow=alaw
-
-#include accounts/*/sip.conf
-
-(in accounts/customer1/sip.conf)
-
-[def-customer1](!,defaults)
-secret=this_is_not_secret
-context=from-customer1
-callerid=Customer 1 <300>
-accountcode=0001
-
-[phone1](def-customer1)
-mailbox=phone1@customer1
-
-[phone2](def-customer1)
-mailbox=phone2@customer1
-
-This example defines two phones - phone1 and phone2 with settings
-inherited from "def-customer1". The "def-customer1" is a template that
-inherits from "defaults", which also is a template.
-
-
diff --git a/1.4/doc/cygwin.txt b/1.4/doc/cygwin.txt
deleted file mode 100644
index 0273a1d37..000000000
--- a/1.4/doc/cygwin.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Cygwin support is completely experimental and unsupported at this time. The
-current state of cygwin support is that it will compile, and start the cli,
-but will not yet take calls properly.
-
-To compile with cygwin, you will need at least a standard base cygwin install plus the following packages:
-
-minires
-minires-devel
-
diff --git a/1.4/doc/datastores.txt b/1.4/doc/datastores.txt
deleted file mode 100644
index 64b5d35cc..000000000
--- a/1.4/doc/datastores.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-Asterisk Channel Data Stores
-============================
-
-* What is a data store?
-
-A data store is a way of storing complex data (such as a structure) on a channel
-so it can be retrieved at a later time by another application, or the same application.
-
-If the data store is not freed by said application though, a callback to a destroy function
-occurs which frees the memory used by the data in the data store so no memory loss occurs.
-
-* A datastore info structure
-static const struct example_datastore {
- .type = "example",
- .destroy = callback_destroy
-};
-
-This is a needed structure that contains information about a datastore, it's used by many API calls.
-
-* How do you create a data store?
-
-1. Use ast_channel_datastore_alloc function to return a pre-allocated structure
- Ex: datastore = ast_channel_datastore_alloc(&example_datastore, "uid");
- This function takes two arguments: (datastore info structure, uid)
-2. Attach data to pre-allocated structure.
- Ex: datastore->data = mysillydata;
-3. Add datastore to the channel
- Ex: ast_channel_datastore_add(chan, datastore);
- This function takes two arguments: (pointer to channel, pointer to data store)
-
-Full Example:
-
-void callback_destroy(void *data)
-{
- ast_free(data);
-}
-
-struct ast_datastore *datastore = NULL;
-datastore = ast_channel_datastore_alloc(&example_datastore, NULL);
-datastore->data = mysillydata;
-ast_channel_datastore_add(chan, datastore);
-
-NOTE: Because you're passing a pointer to a function in your module, you'll want to include
-this in your use count. When allocated increment, when destroyed decrement.
-
-* How do you remove a data store?
-
-1. Find the data store
- Ex: datastore = ast_channel_datastore_find(chan, &example_datastore, NULL);
- This function takes three arguments: (pointer to channel, datastore info structure, uid)
-2. Remove the data store from the channel
- Ex: ast_channel_datastore_remove(chan, datastore);
- This function takes two arguments: (pointer to channel, pointer to data store)
-3. If we want to now do stuff to the data on the data store
-4. Free the data store (this will call the destroy call back)
- Ex: ast_channel_datastore_free(datastore);
- This function takes one argument: (pointer to data store)
-
-* How do you find a data store?
-
-1. Find the data store
- Ex: datastore = ast_channel_datastore_find(chan, &example_datastore, NULL);
- This function takes three arguments: (pointer to channel, datastore info structure, uid)
diff --git a/1.4/doc/digium-mib.txt b/1.4/doc/digium-mib.txt
deleted file mode 100644
index 018a080dd..000000000
--- a/1.4/doc/digium-mib.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-DIGIUM-MIB DEFINITIONS ::= BEGIN
-
-IMPORTS
- enterprises
- FROM SNMPv2-SMI;
-
-digium MODULE-IDENTITY
- LAST-UPDATED "200602041900Z"
- ORGANIZATION "Digium, Inc."
- CONTACT-INFO
- "Mark Spencer
- Email: markster@digium.com"
- DESCRIPTION
- ""
- ::= { enterprises 22736 }
-
-END
diff --git a/1.4/doc/dundi.txt b/1.4/doc/dundi.txt
deleted file mode 100644
index ffcefc7b8..000000000
--- a/1.4/doc/dundi.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Distributed Universal Number Directory (DUNDi) (tm)
-===================================================
-http://www.dundi.com
-Mark Spencer, Digium, Inc.
-
-DUNDi is essentially a trusted, peer-to-peer system for being able to
-call any phone number from the Internet. DUNDi works by creating a
-network of nodes called the "DUNDi E.164 Trust Group" which are bound by
-a common peering agreement known as the General Peering Agreement or
-GPA. The GPA legally binds the members of the Trust Group to provide
-good-faith accurate information to the other nodes on the network, and
-provides standards by which the community can insure the integrity of
-the information on the nodes themselves. Unlike ENUM or similar
-systems, DUNDi is explicitly designed to preclude any necessity for a
-single centralized system which could be a source of fees, regulation,
-etc.
-
-You can find the PEERING agreement in the doc directory.
-
-Much less dramatically, DUNDi can also be used within a private
-enterprise to share a dialplan efficiently between multiple nodes,
-without incurring a risk of a single point of failure. In this way,
-administrators can locally add extensions which become immediately
-available to the other nodes in the system.
-
-For more information visit http://www.dundi.com
diff --git a/1.4/doc/enum.txt b/1.4/doc/enum.txt
deleted file mode 100644
index 3d3d03b0c..000000000
--- a/1.4/doc/enum.txt
+++ /dev/null
@@ -1,308 +0,0 @@
-Enum support in the ENUMLOOKUP dialplan function
-------------------------------------------------
-2005-09-06
-jtodd@loligo.com
-
-The ENUMLOOKUP function is more complex than it first may appear, and
-this guide is to give a general overview and set of examples that may
-be well-suited for the advanced user to evaluate in their
-consideration of ENUM or ENUM-like lookup strategies. This document
-assumes a familiarity with ENUM (RFC3761) or ENUM-like methods, as
-well as familiarity with NAPTR DNS records (RFC2915, RFC3401-3404).
-For an overview of NAPTR records, and the use of NAPTRs in the ENUM
-global phone-number-to-DNS mapping scheme, please see
-http://www.voip-info.org/tiki-index.php?page=ENUM for more detail.
-
-Using ENUM within Asterisk can be simple or complex, depending on how
-many failover methods and redundancy procedures you wish to utilize.
-Implementation of ENUM paths is supposedly defined by the person
-creating the NAPTR records, but the local administrator may choose to
-ignore certain NAPTR response methods (URI types) or prefer some over
-others, which is in contradiction to the RFC. The ENUMLOOKUP method
-simply provides administrators a method for determining NAPTR results
-in either the globally unique ENUM (e164.arpa) DNS tree, or in other
-ENUM-like DNS trees which are not globally unique. The methods to
-actually create channels ("dial") results given by the ENUMLOOKUP
-function is then up to the administrator to implement in a way that
-best suits their environment.
-
-Function: ENUMLOOKUP(number[|Method-type[|options[|record#[|zone-suffix]]]])
-
- Performs an ENUM tree lookup on the specified number, method type, and
- ordinal record offset, and returns one of four different values:
-
- 1) post-parsed NAPTR of one method (URI) type
- 2) count of elements of one method (URI) type
- 3) count of all method types
- 4) full URI of method at a particular point in the list of all possible methods
-
-Arguments:
-
-number = telephone number or search string. Only numeric values
-within this string are parsed; all other digits are ignored for
-search, but are re-written during NAPTR regexp expansion.
-
-service_type = tel, sip, h323, iax2, mailto, ...[any other string],
- ALL. Default type is "sip".
- Special name of "ALL" will create a list of method types across
- all NAPTR records for the search number, and then put the results
- in an ordinal list starting with 1. The position <number>
- specified will then be returned, starting with 1 as the first
- record (lowest value) in the list. The service types are not
- hardcoded in Asterisk except for the default (sip) if no other
- service type specified; any method type string (IANA-approved or
- not) may be used except for the string "ALL".
-
-options = optional specifiers.
- c = count. Returns the number of records of this type are returned
- (regardless of order or priority.) If "ALL" is the specified
- service_type, then a count of all methods will be returned for the
- DNS record.
-
-record# = which record to present if multiple answers are returned
- <integer> = The record in priority/order sequence based on the
- total count of records passed back by the query. If a service_type
- is specified, all entries of that type will be sorted into an
- ordinal list starting with 1 (by order first, then priority).
- The default of <options> is "1"
-
-zone_suffix = allows customization of the ENUM zone. Default is e164.arpa.
-
-
-EXAMPLE USES:
-
-Let's use this ENUM list as an example (note that these examples exist
-in the DNS, and will hopefully remain in place as example
-destinations, but they may change or become invalid over time. The
-end result URIs are not guaranteed to actually work, since some of
-these hostnames or SIP proxies are imaginary. Of course, the tel:
-replies go to directory assistance for New York City and San
-Francisco...) Also note that the complex SIP NAPTR at weight 30 will
-strip off the leading "+" from the dialed string if it exists. This
-is probably a better NAPTR than hard-coding the number into the NAPTR,
-and it is included as a more complex regexp example, though other
-simpler NAPTRs will work just as well.
-
-
-0.2.0.1.1.6.5.1.0.3.1.loligo.com. 3600 IN NAPTR 10 100 "u" "E2U+tel" "!^\\+13015611020$!tel:+12125551212!" .
-0.2.0.1.1.6.5.1.0.3.1.loligo.com. 3600 IN NAPTR 21 100 "u" "E2U+tel" "!^\\+13015611020$!tel:+14155551212!" .
-0.2.0.1.1.6.5.1.0.3.1.loligo.com. 3600 IN NAPTR 25 100 "u" "E2U+sip" "!^\\+13015611020$!sip:2203@sip.fox-den.com!" .
-0.2.0.1.1.6.5.1.0.3.1.loligo.com. 3600 IN NAPTR 26 100 "u" "E2U+sip" "!^\\+13015611020$!sip:1234@sip-2.fox-den.com!" .
-0.2.0.1.1.6.5.1.0.3.1.loligo.com. 3600 IN NAPTR 30 100 "u" "E2U+sip" "!^\\+*([^\\*]*)!sip:\\1@sip-3.fox-den.com!" .
-0.2.0.1.1.6.5.1.0.3.1.loligo.com. 3600 IN NAPTR 55 100 "u" "E2U+mailto" "!^\\+13015611020$!mailto:jtodd@fox-den.com!" .
-
-Example 1: Simplest case, using first SIP return (use all defaults
-except for domain name)
-exten => 100,1,Set(foo=${ENUMLOOKUP(+13015611020,,,,loligo.com)})
- returns: ${foo}="2203@sip.fox-den.com"
-
-Example 2: What is the first "tel" pointer type for this number?
-(after sorting by order/preference; default of "1" is assumed in
-options field)
-exten => 100,1,Set(foo=${ENUMLOOKUP(+13015611020,tel,,,loligo.com)})
- returns: ${foo}="+12125551212"
-
-Example 3: How many "sip" pointer type entries are there for this number?
-exten => 100,1,Set(foo=${ENUMLOOKUP(+13015611020,sip,c,,loligo.com)})
- returns: ${foo}=3
-
-Example 4: For all the "tel" pointer type entries, what is the second
-one in the list? (after sorting by preference)
-exten => 100,1,Set(foo=${ENUMLOOKUP(+13015611020,tel,,2,loligo.com)})
- returns: ${foo}="+14155551212"
-
-Example 5: How many NAPTRs (tel, sip, mailto, etc.) are in the list for this number?
-exten => 100,1,Set(foo=${ENUMLOOKUP(+13015611020,ALL,c,,loligo.com)})
- returns: ${foo}=6
-
-Example 6: Give back the second full URI in the sorted list of all NAPTR URIs:
-exten => 100,1,Set(foo=${ENUMLOOKUP(+13015611020,ALL,,2,loligo.com)})
- returns: ${foo}="tel:+14155551212" [note the "tel:" prefix in the string]
-
-Example 7: Look up first SIP entry for the number in the e164.arpa zone (all defaults)
-exten => 100,1,Set(foo=${ENUMLOOKUP(+437203001721)})
- returns: ${foo}="enum-test@sip.nemox.net" [note: this result is
- subject to change as it is "live" DNS and not under my control]
-
-
-Example 8: Look up the ISN mapping in freenum.org alpha test zone
-exten => 100,1,Set(foo=${ENUMLOOKUP(1234*256,,,,freenum.org)})
- returns: ${foo}="1234@204.91.156.10" [note: this result is subject
- to change as it is "live" DNS]
-
-Example 9: Give back the first SIP pointer for a number in the
-enum.yoydynelabs.com zone (invalid lookup)
-exten => 100,1,Set(foo=${ENUMLOOKUP(1234567890,sip,,1,enum.yoyodynelabs.com)})
- returns: ${foo}=""
-
-
-Usage notes and subtle features:
-
- a) The use of "+" in lookups is confusing, and warrants further
- explanation. All E.164 numbers ("global phone numbers") by
- definition need a leading "+" during ENUM lookup. If you neglect to
- add a leading "+", you may discover that numbers that seem to exist
- in the DNS aren't getting matched by the system or are returned with
- a null string result. This is due to the NAPTR reply requiring a
- "+" in the regular expression matching sequence. Older versions of
- Asterisk add a "+" from within the code, which may confuse
- administrators converting to the new function. Please ensure that
- all ENUM (e164.arpa) lookups contain a leading "+" before lookup, so
- ensure your lookup includes the leading plus sign. Other DNS trees
- may or may not require a leading "+" - check before using those
- trees, as it is possible the parsed NAPTRs will not provide correct
- results unless you have the correct dialed string. If you get
- console messages like "WARNING[24907]: enum.c:222 parse_naptr: NAPTR
- Regex match failed." then it is very possible that the returned
- NAPTR expects a leading "+" in the search string (or the returned
- NAPTR is mis-formed.)
-
- b) If a query is performed of type "c" ("count") and let's say you
- get back 5 records and then some seconds later a query is made
- against record 5 in the list, it may not be the case that the DNS
- resolver has the same answers as it did a second or two ago - maybe
- there are only 4 records in the list in the newest query. The
- resolver should be the canonical storage location for DNS records,
- since that is the intent of ENUM. However, some obscure future
- cases may have wildly changing NAPTR records within several seconds.
- This is a corner case, and probably only worth noting as a very rare
- circumstance. (note: I do not object to Asterisk's dnsmgr method of
- locally caching DNS replies, but this method needs to honor the TTL
- given by the remote zone master. Currently, the ENUMLOOKUP function
- does not use the dnsmgr method of caching local DNS replies.)
-
- c) If you want strict NAPTR value ordering, then it will be
- necessary to use the "ALL" method to incrementally step through the
- different returned NAPTR pointers. You will need to use string
- manipulation to strip off the returned method types, since the
- results will look like "sip:12125551212" in the returned value.
- This is a non-trivial task, though it is required in order to have
- strict RFC compliance and to comply with the desires of the remote
- party who is presenting NAPTRs in a particular order for a reason.
-
- d) Default behavior for the function (even in event of an error) is
- to move to the next priority, and the result is a null value. Most
- ENUM lookups are going to be failures, and it is the responsibility
- of the dialplan administrator to manage error conditions within
- their dialplan. This is a change from the old app_enumlookup method
- and it's arbitrary priority jumping based on result type or failure.
-
- e) Anything other than digits will be ignored in lookup strings.
- Example: a search string of "+4372030blah01721" will turn into
- 1.2.7.1.0.0.3.0.2.7.3.4.e164.arpa. for the lookup. The NAPTR
- parsing may cause unexpected results if there are strings inside
- your NAPTR lookups.
-
- f) If there exist multiple records with the same weight and order as
- a result of your query, the function will RANDOMLY select a single
- NAPTR from those equal results.
-
- g) Currently, the function ignores the settings in enum.conf as the
- search zone name is now specified within the function, and the H323
- driver can be chosen by the user via the dialplan. There were no
- other values in this file, and so it becomes deprecated.
-
- h) The function will digest and return NAPTRs which use older
- (deprecated) style, reversed method strings such as "sip+E2U"
- instead of the more modern "E2U+sip"
-
- i) There is no provision for multi-part methods at this time. If
- there are multiple NAPTRs with (as an example) a method of
- "E2U+voice:sip" and then another NAPTR in the same DNS record with a
- method of ""E2U+sip", the system will treat these both as method
- "sip" and they will be separate records from the perspective of the
- function. Of course, if both records point to the same URI and have
- equal priority/weight (as is often the case) then this will cause no
- serious difficulty, but it bears mentioning.
-
- j) ISN (ITAD Subscriber Number) usage: If the search number is of
- the form ABC*DEF (where ABC and DEF are at least one numeric digit)
- then perform an ISN-style lookup where the lookup is manipulated to
- C.B.A.DEF.domain.tld (all other settings and options apply.) See
- http://www.freenum.org/ for more details on ISN lookups. In the
- unlikely event you wish to avoid ISN re-writes, put an "n" as the
- first digit of the search string - the "n" will be ignored for the search.
-
-
-==EXAMPLES==
-
-All examples below except where noted use "e164.arpa" as the
-referenced domain, which is the default domain name for ENUMLOOKUP.
-All numbers are assumed to not have a leading "+" as dialed by the
-inbound channel, so that character is added where necessary during
-ENUMLOOKUP function calls.
-
-; example 1
-;
-; Assumes North American international dialing (011) prefix.
-; Look up the first SIP result and send the call there, otherwise
-; send the call out a PRI. This is the most simple possible
-; ENUM example, but only uses the first SIP reply in the list of
-; NAPTR(s).
-;
-exten => _011.,1,Set(enumresult=${ENUMLOOKUP(+${EXTEN:3})})
-exten => _011.,n,Dial(SIP/${enumresult})
-exten => _011.,n,Dial(Zap/g1/${EXTEN})
-;
-; end example 1
-
-; example 2
-;
-; Assumes North American international dialing (011) prefix.
-; Check to see if there are multiple SIP NAPTRs returned by
-; the lookup, and dial each in order. If none work (or none
-; exist) then send the call out a PRI, group 1.
-;
-exten => _011.,1,Set(sipcount=${ENUMLOOKUP(${EXTEN:3},sip,c)}|counter=0)
-exten => _011.,n,While($["${counter}"<"${sipcount}"])
-exten => _011.,n,Set(counter=$[${counter}+1])
-exten => _011.,n,Dial(SIP/${ENUMLOOKUP(+${EXTEN:3},sip,,${counter})})
-exten => _011.,n,EndWhile
-exten => _011.,n,Dial(Zap/g1/${EXTEN})
-;
-; end example 2
-
-; example 3
-;
-; This example expects an ${EXTEN} that is an e.164 number (like
-; 14102241145 or 437203001721)
-; Search through e164.arpa and then also search through e164.org
-; to see if there are any valid SIP or IAX termination capabilities.
-; If none, send call out via Zap channel 1.
-;
-; Start first with e164.arpa zone...
-;
-exten => _X.,1,Set(sipcount=${ENUMLOOKUP(+${EXTEN},sip,c)}|counter=0)
-exten => _X.,2,GotoIf($["${counter}"<"${sipcount}"]?3:6)
-exten => _X.,3,Set(counter=$[${counter}+1])
-exten => _X.,4,Dial(SIP/${ENUMLOOKUP(+${EXTEN},sip,,${counter})})
-exten => _X.,5,GotoIf($["${counter}"<"${sipcount}"]?3:6)
-;
-exten => _X.,6,Set(iaxcount=${ENUMLOOKUP(+${EXTEN},iax2,c)}|counter=0)
-exten => _X.,7,GotoIf($["${counter}"<"${iaxcount}"]?8:11)
-exten => _X.,8,Set(counter=$[${counter}+1])
-exten => _X.,9,Dial(IAX2/${ENUMLOOKUP(+${EXTEN},iax2,,${counter})})
-exten => _X.,10,GotoIf($["${counter}"<"${iaxcount}"]?8:11)
-;
-exten => _X.,11,NoOp("No valid entries in e164.arpa for ${EXTEN} - checking in e164.org")
-;
-; ...then also try e164.org, and look for SIP and IAX NAPTRs...
-;
-exten => _X.,12,Set(sipcount=${ENUMLOOKUP(+${EXTEN},sip,c,,e164.org)}|counter=0)
-exten => _X.,13,GotoIf($["${counter}"<"${sipcount}"]?14:17)
-exten => _X.,14,Set(counter=$[${counter}+1])
-exten => _X.,15,Dial(SIP/${ENUMLOOKUP(+${EXTEN},sip,,${counter},e164.org)})
-exten => _X.,16,GotoIf($["${counter}"<"${sipcount}"]?14:17)
-;
-exten => _X.,17,Set(iaxcount=${ENUMLOOKUP(+${EXTEN},iax2,c,,e164.org)}|counter=0)
-exten => _X.,18,GotoIf($["${counter}"<"${iaxcount}"]?19:22)
-exten => _X.,19,Set(counter=$[${counter}+1])
-exten => _X.,20,Dial(IAX2/${ENUMLOOKUP(+${EXTEN},iax2,,${counter},e164.org)})
-exten => _X.,21,GotoIf($["${counter}"<"${iaxcount}"]?19:22)
-;
-; ...then send out PRI.
-;
-exten => _X.,22,NoOp("No valid entries in e164.org for ${EXTEN} - sending out via Zap")
-exten => _X.,23,Dial(Zap/g1/${EXTEN})
-;
-; end example 3
diff --git a/1.4/doc/extconfig.txt b/1.4/doc/extconfig.txt
deleted file mode 100644
index 0a95997ce..000000000
--- a/1.4/doc/extconfig.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-Asterisk external configuration
-===============================
-
-The Asterisk external configuration engine is the result of work by
-Anthony Minessale II, Mark Spencer and Constantine Filin.
-
-It is designed to provide a flexible, seamless integration between
-Asterisk's internal configuration structure and external SQL other other
-databases (maybe even LDAP one day).
-
-The external configuration engine is the basis for the ARA, the
-Asterisk Realtime Architecture (see doc/realtime.txt for more
-information).
-
-* Configuration
-
-External configuration is configured in /etc/asterisk/extconfig.conf
-allowing you to map any configuration file (static mappings) to
-be pulled from the database, or to map special runtime entries which
-permit the dynamic creation of objects, entities, peers, etc. without
-the necessity of a reload.
-
-Generally speaking, the columns in your tables should line up with the
-fields you would specify in the given entity declaration. If an entry
-would appear more than once, in the column it should be separated by a
-semicolon. For example, an entity that looks like:
-
-[foo]
-host=dynamic
-secret=bar
-context=default
-context=local
-
-could be stored in a table like this:
-
-+------+--------+-------+--------------+----------+-----+-----------+
-| name | host | secret| context | ipaddr | port| regseconds|
-+------+--------+-------+--------------+----------+-----+-----------+
-| foo | dynamic| bar | default;local| 127.0.0.1| 4569| 1096954152|
-+------+--------+-------+--------------+----------+-----+-----------+
-
-Note that for use with IAX or SIP, the table will also need the "name",
-"ipaddr", "port", "regseconds" columns. If you wanted to be able to
-configure the callerid, you could just add a callerid column to the
-table, for example.
-
-A SIP table would look more like this:
-
-+------+--------+-------+----------+-----+------------+----------+
-| name | host | secret| ipaddr | port| regseconds | username |
-+------+--------+-------+----------+-----+------------+----------+
-| foo | dynamic| bar | 127.0.0.1| 4569| 1096954152 | 1234 |
-+------+--------+-------+----------+-----+------------+----------+
-
-in order to store appropriate parameters required for SIP.
-
-In addition to this, if you add a field named "regserver" to the
-SIP peers table and have the system name set in asterisk.conf,
-Asterisk will store the system name that the user registered on in
-the database. This can be used to direct calls to go through the server
-that holds the registration (for NAT traversal purposes).
-
-A Voicemail table would look more like this:
-
-+----------+---------+----------+----------+-----------+---------------+
-| uniqueid | mailbox | context | password |email | fullname |
-+----------+---------+----------+----------+-----------+---------------+
-| 1 | 1234 | default | 4242 | a@b.com | Joe Schmoe |
-+----------+---------+----------+----------+-----------+---------------+
-
-The uniqueid should be unique to each voicemail user and can be
-autoincrement. It need not have any relation to the mailbox or context.
-
-An extension table would look more like this:
-
-+----------+---------+----------+-------+-----------+
-| context | exten | priority | app | appdata |
-+----------+---------+----------+-------+-----------+
-| default | 1234 | 1 | Dial | Zap/1 |
-+----------+---------+----------+-------+-----------+
-
-In the dialplan you just use the Realtime switch:
-
-[foo]
-switch => Realtime
-
-or:
-
-[bar]
-switch => Realtime/bar@extensions
-
diff --git a/1.4/doc/extensions.txt b/1.4/doc/extensions.txt
deleted file mode 100644
index 90826f15f..000000000
--- a/1.4/doc/extensions.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-The Asterisk dialplan
-=====================
-
-The Asterisk dialplan is divided into contexts. A context is simply a group
-of extensions. For each "line" that should be able to be called, an extension
-must be added to a context. Then, you configure the calling "line" to have
-access to this context.
-
-If you change the dialplan, you can use the Asterisk CLI command
-"extensions reload" to load the new dialplan without disrupting
-service in your PBX.
-
-Extensions are routed according to priority and may be based on any set
-of characters (a-z), digits, #, and *. Please note that when matching a
-pattern, "N", "X", and "Z" are interpreted as classes of digits.
-
-For each extension, several actions may be listed and must be given a unique
-priority. When each action completes, the call continues at the next priority
-(except for some modules which use explicitly GOTO's).
-
-When each action completes, it generally moves to the next priority (except for
-some modules which use explicitly GOTO's.
-
-Extensions frequently have data they pass to the executing application
-(most frequently a string). You can see the available dialplan applications
-by entering the "show applications" command in the CLI.
-
-In this version of Asterisk, dialplan functions are added. These can
-be used as arguments to any application. For a list of the installed
-functions in your Asterisk, use the "show functions" command.
-
-* Example dial plan
-
-The example dial plan, in the configs/extensions.conf.sample file
-is installed as extensions.conf if you run "make samples" after
-installation of Asterisk. This file includes many more instructions
-and examples than this file, so it's worthwhile to read it.
-
-* Special extensions
-
-There are some extensions with important meanings:
-
- s: What to do when an extension context is entered (unless
- overridden by the low level channel interface)
- This is used in macros, and some special cases.
- "s" is not a generic catch-all wildcard extension.
- i: What to do if an invalid extension is entered
- h: The hangup extension, executed at hangup
- t: What to do if nothing is entered in the requisite amount
- of time.
- T: This is the extension that is executed when the 'absolute'
- timeout is reached. See "show function TIMEOUT" for more
- information on setting timeouts.
-
-And finally, the extension context "default" is used when either a) an
-extension context is deleted while an extension is in use, or b) a specific
-starting extension handler has not been defined (unless overridden by the
-low level channel interface).
diff --git a/1.4/doc/externalivr.txt b/1.4/doc/externalivr.txt
deleted file mode 100644
index a1d4757e7..000000000
--- a/1.4/doc/externalivr.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-Asterisk External IVR Interface
--------------------------------
-
-If you load app_externalivr.so in your Asterisk instance, you will
-have an ExternalIVR() application available in your dialplan. This
-application implements a simple protocol for bidirectional
-communication with an external process, while simultaneous playing
-audio files to the connected channel (without interruption or
-blocking).
-
-The arguments to ExternalIVR() consist of the command to execute and
-any arguments to pass to it, the same as the System() application
-accepts. The external command will be executed in a child process,
-with its standard file handles connected to the Asterisk process as
-follows:
-
-stdin (0) - DTMF and hangup events will be received on this handle
-stdout (1) - Playback and hangup commands can be sent on this handle
-stderr (2) - Error messages can be sent on this handle
-
-The application will also create an audio generator to play audio to
-the channel, and will start playing silence. When your application
-wants to send audio to the channel, it can send a command (see below)
-to add file(s) to the generator's playlist. The generator will then
-work its way through the list, playing each file in turn until it
-either runs out of files to play, the channel is hung up, or a command
-is received to clear the list and start with a new file. At any time,
-more files can be added to the list and the generator will play them
-in sequence.
-
-While the generator is playing audio (or silence), any DTMF events
-received on the channel will be sent to the child process (see
-below). Note that this can happen at any time, since the generator,
-the child process and the channel thread are all executing
-independently. It is very important that your external application be
-ready to receive events from Asterisk at all times (without blocking),
-or you could cause the channel to become non-responsive.
-
-If the child process dies, ExternalIVR() will notice this and hang up
-the channel immediately (and also send a message to the log).
-
-DTMF (and other) events
------------------------
-
-All events will be newline-terminated strings.
-
-Events send to the child's stdin will be in the following format:
-
-tag,timestamp[,data]
-
-The tag can be one of the following characters:
-
-0-9: DTMF event for keys 0 through 9
-A-D: DTMF event for keys A through D
-*: DTMF event for key *
-#: DTMF event for key #
-H: the channel was hung up by the connected party
-Z: the previous command was unable to be executed (file does not
-exist, etc.)
-T: the play list was interrupted (see below)
-D: a file was dropped from the play list due to interruption (the
-data element will be the dropped file name)
-F: a file has finished playing (the data element will be the file
-name)
-
-The timestamp will be 10 digits long, and will be a decimal
-representation of a standard Unix epoch-based timestamp.
-
-Commands
---------
-
-All commands must be newline-terminated strings.
-
-The child process can send commands on stdout in the following formats:
-
-S,filename
-A,filename
-H,message
-O,option
-
-The 'S' command checks to see if there is a playable audio file with
-the specified name, and if so, clear's the generator's playlist and
-places the file onto the list. Note that the playability check does
-not take into account transcoding requirements, so it is possible for
-the file to not be played even though it was found. If the file cannot
-be found, a 'Z' event (see above) will be sent to the child. If the
-generator is not currently playing silence, then T and D events will
-be sent to the child to signal the playlist interruption and notify
-it of the files that will not be played.
-
-The 'A' command checks to see if there is a playable audio file with
-the specified name, and if so, adds it to the generator's
-playlist. The same playability and exception rules apply as for the
-'S' command.
-
-The 'H' command stops the generator and hangs up the channel, and logs
-the supplied message to the Asterisk log.
-
-The 'O' command allows the child to set/clear options in the
-ExternalIVR() application. The supported options are:
- autoclear/noautoclear:
- Automatically interrupt and clear the playlist upon reception
- of DTMF input.
-
-Errors
-------
-
-Any newline-terminated output generated by the child process on its
-stderr handle will be copied into the Asterisk log.
diff --git a/1.4/doc/freetds.txt b/1.4/doc/freetds.txt
deleted file mode 100644
index e1c27fba3..000000000
--- a/1.4/doc/freetds.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-PLEASE NOTE
-
-The cdr_tds module is NOT compatible with version 0.63 of FreeTDS.
-
-The cdr_tds module is known to work with FreeTDS version 0.62.1;
-it should also work with 0.62.2, 0.62.3 and 0.62.4, which are bug
-fix releases.
-
-The cdr_tds module uses the raw "libtds" API of FreeTDS. It appears
-that from 0.63 onwards, this is not considered a published API
-of FreeTDS and is subject to change without notice.
-
-Between 0.62.x and 0.63 of FreeTDS, many incompatible changes
-have been made to the libtds API.
-
-For newer versions of FreeTDS, it is recommended that you use the
-ODBC driver.
-
diff --git a/1.4/doc/h323.txt b/1.4/doc/h323.txt
deleted file mode 100644
index c7383e7af..000000000
--- a/1.4/doc/h323.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-The Asterisk PBX supports H.323 via two totally separate
-channel drivers.
-
-You can find more information Asterisk's native H.323
-support in /path/to/asterisk/channels/h323/README or
-you can download a third party driver at
-http://www.inaccessnetworks.com/projects/asterisk-oh323
-
-Asterisk's native H.323 is supported and maintained by
-Jeremy McNamara (JerJer in irc). Support for the third
-party H.323 driver is supplied by inAccessNetworks.
-
-If you have trouble with either driver you should direct
-your debug and comments to the appropriate party, making
-sure to be specific in exactly which H.323 driver you are
-running.
-
-Please, read all supplied documentation before contacting
-either party for support. Many issues can be quickly
-resolved by simply following the instructions that are
-provided.
-
diff --git a/1.4/doc/hardware.txt b/1.4/doc/hardware.txt
deleted file mode 100644
index 01f8f7f06..000000000
--- a/1.4/doc/hardware.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-A PBX is only really useful if you can get calls into it. Of course, you
-can use Asterisk with VoIP calls (SIP, H.323, IAX), but you can also talk
-to the real PSTN through various cards.
-
-Supported Hardware is divided into two general groups: Zaptel devices and
-non-zaptel devices. The Zaptel compatible hardware supports pseudo-TDM
-conferencing and all call features through chan_zap, whereas non-zaptel
-compatible hardware may have different features.
-
-Zaptel compatible hardware
-==========================
-
--- Digium (Primary author of Asterisk)
- http://www.digium.com, http://store.digium.com
-
- * Wildcard T400P (obsolete) - Quad T1 interface connects to four T1/PRI
- interfaces. Supports RBS and PRI voice and PPP, FR, and HDLC data.
-
- * Wildcard E400P (obsolete)- Quad E1 interface connects to four E1/PRI
- (or PRA) interfaces. Supports PRA/PRI, EuroISDN voice and data.
-
- * Wildcard T100P - Single T1 interface connects to a single T1/PRI
- interface. Supports RBS and PRI voice and PPP, FR, and HDLC data.
-
- * Wildcard E100P - Single E1 interface connects to a single E1/PRI (or PRA)
- interface. Supports PRA/PRI, EuroISDN voice and PPP, FR, HDLC data.
-
- * Wildcard TDM400P - Quad Modular FXS interface connects to standard
- analog telephones.
-
- * Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and
- RBS signalling, as well as PPP, FR, and HDLC data modes.
-
-Non-zaptel compatible hardware
-==============================
-
--- QuickNet, Inc.
- http://www.quicknet.net
-
- * Internet PhoneJack - Single FXS interface. Supports Linux telephony
- interface. DSP compression built-in.
-
- * Internet LineJack - Single FXS or FXO interface. Supports Linux
- telephony interface.
-
-mISDN compatible hardware
-=========================
-mISDN homepage: http://www.isdn4linux.de/mISDN/
-
-Any adapter with an mISDN driver should be compatible with
-chan_misdn. See misdn.txt for information.
-
--- beroNet
- http://www.beronet.com
-
- * BN4S0 - 4 Port BRI card (TE/NT)
-
- * BN8S0 - 8 Port BRI card (TE/NT)
-
- * Billion Card - Single Port BRI card (TE (/NT with crossed cable) )
-
-
-Miscellaneous other interfaces
-==============================
-
--- ALSA
- http://www.alsa-project.org
-
- * Any ALSA compatible full-duplex sound card
-
--- OSS
- http://www.opensound.com
-
- * Any OSS compatible full-duplex sound card
diff --git a/1.4/doc/iax.txt b/1.4/doc/iax.txt
deleted file mode 100644
index cf952a113..000000000
--- a/1.4/doc/iax.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-Inter-Asterisk eXchange Protocol
-================================
-
-Usage:
-======
-The format for the dialing string on Asterisk is:
-IAX/[user@]peer[:exten[@context]]
-
-(Note, []'s denote optional fields). The peer is either an IP address
-or a peer as specified in the /etc/asterisk/iax.conf file. Exten is
-an optional requested extension (otherwise "s" will be used), and
-"context" is an optional context to request. The user is an optional
-username specified in the peer's iax.conf. If the user is not specified,
-the peer will select one.
-
-The peer uses a score to determine the best user entry to match against if
-one is not specified:
-
-1. User entry with secret and no ACL specified.
-2. User entry with secret specified and ACL specified.
-3. User entry with no secret specified and no ACL specified.
-4. User entry with no secret specified and ACL specified.
-5. User entry matched via username.
-
-The higher the score the better it is with 5 being an exact match and the maximum
-score possible.
-
-Protocol and rationale:
-=======================
-IAX is a simple, low overhead and low bandwidth VoIP protocol designed to
-allow multiple Asterisk PBX's to communicate with one another without
-the overhead of more complex protocols like H.323. Payload is sent with
-a header overhead of only 4 octets. Control functions (and one payload packet
-per minute or so) is sent with a more complex header of 12 octets.
-
-IAX is slightly stateful.
-
-IAX contains two kinds of packets: The full header packet type, which
-contains much information about the frame, in addition to its contents,
-and the mini header type, which is used only for non-reliable voice
-packet delivery.
-
-All packets are immediately transmitted. Packets are received, but not
-delivered to the actual channels until a given time quantum has passed, in
-order to try to eliminate jitter.
-
-All full header packets must be ackd (except, obviously for the ACK packets
-themselves and not so obviously for hangup packets). The "timestamp" field of
-ack packets is not the normal offset, but rather a quote of the timestamp as
-included with the original packet that you're acking, and likewise the
-seqno field is the seqno of the packet you're acking, not your own seqno,
-and you do not increment your own sequence number. ACKing is based on the
-sequence number.
-
-See iax.h for a description of the frame formats.
-
-IAX internal frames use the AST_FRAME_IAX type. The subclass of these
-frames is the IAX control number, as seen in iax.h. The first frame sent
-must be an AST_FRAME_IAX with the control AST_IAX_CONTROL_NEW.
-
-The AST_IAX_CONTROL_NEW establishes a new connection.
-
-The first frame sent MUST be an AST_CONTROL_NEW to start a connection.
-
-IAX connnections may require authentication using either simple plaintext
-passwords or an md5 challenge/response pair.
-
diff --git a/1.4/doc/ices.txt b/1.4/doc/ices.txt
deleted file mode 100644
index d75236357..000000000
--- a/1.4/doc/ices.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Icecast + Asterisk
-==================
-The advent of icecast into Asterisk allows you to do neat things like have
-a caller stream right into an ice-cast stream as well as using chan_local
-to place things like conferences, music on hold, etc. into the stream.
-
-You'll need to specify a config file for the ices encoder. An example is
-included in contrib/asterisk-ices.xml
-
-Anyway hope you like it.
-
-Mark
diff --git a/1.4/doc/imapstorage.txt b/1.4/doc/imapstorage.txt
deleted file mode 100644
index f1803bf1e..000000000
--- a/1.4/doc/imapstorage.txt
+++ /dev/null
@@ -1,213 +0,0 @@
-======================
-IMAP Voicemail Storage
-======================
-
-03-01-2006 - James Rothenberger <jar@onebiztone.com>
-
-By enabling IMAP Storage, Asterisk will use native IMAP as the storage
-mechanism for voicemail messages instead of using the standard file structure.
-
-Tighter integration of Asterisk voicemail and IMAP email services allows
-additional voicemail functionality, including:
-
- - Listening to a voicemail on the phone will set its state to "read" in
- a user's mailbox automatically.
- - Deleting a voicemail on the phone will delete it from the user's
- mailbox automatically.
- - Accessing a voicemail recording email message will turn off the message
- waiting indicator (MWI) on the user's phone.
- - Deleting a voicemail recording email will also turn off the message
- waiting indicator, and delete the message from the voicemail system.
-
-=====================
-Contents of this file
-=====================
-
- - Installation Notes
- - Separate vs. Shared Email Accounts
- - IMAP Server Implementations
- - Quota Support
- - Application Notes
- - Known Issues
-
-
-==================
-Installation Notes
-==================
-
---------------------------------------
-University of Washington IMAP C-Client
---------------------------------------
-You will need a source distribution of University of Washington's IMAP
-c-client (http://www.washington.edu/imap/). Asterisk supports both the
-2004 and 2006 versions of c-client, however mail_expunge_full is enabled
-in the 2006 version.
-
-Note that Asterisk only uses the 'client' portion of the UW IMAP toolkit,
-but building it also builds an IMAP server and various other utilities.
-Because of this, the build instructions for the IMAP toolkit are somewhat
-complicated and can lead to confusion about what is needed.
-
-If you are going to be connecting Asterisk to an existing IMAP server,
-then you don't need to care about the server or utilities in the IMAP
-toolkit at all. If you want to also install the UW IMAPD server, that
-is outside the scope of this document.
-
-Building the c-client library is fairly straightforward; for example, on a
-Debian system there are two possibilities:
-
-1) if you will not be using SSL to connect to the IMAP server:
- $ make slx SSLTYPE=none
-
-2) if you will be using SSL to connect to the IMAP server:
- $ make slx EXTRACFLAGS="-I/usr/include/openssl"
-
-Once this completes you can proceed with the Asterisk build; there is no
-need to run 'make install'.
-
-------------------
-Compiling Asterisk
-------------------
-
-Configure with ./configure --with-imap=/usr/src/imap
-or where ever you built thfe UWashington IMAP Toolkit. This directory
-will be searched for a source installation. If no source installation is
-found there, then a package installation of the IMAP c-client will be
-searched for in this directory. If one is not found, then configure will fail
-
-A second configure option is to not specify a directory (i.e.
-./configure --with-imap). This will assume that you have the
-imap-2004g source installed in the .. directory relative to the
-Asterisk source. If you do not have this source, then configure will
-default to the "system" option defined in the next paragraph
-
-A third option is ./configure --with-imap=system. This will assume
-that you have installed a dynamically linked version of the c-client
-library (most likely via a package provided by your distro). This will
-attempt to link agains -lc-client and will search for c-client headers
-in your include path starting with the imap directory, and upon failure,
-in the c-client directory.
-
-When you run 'make menuselect', choose 'Voicemail Build Options' and the
-IMAP_STORAGE option should be available for selection.
-
-After selecting it, use the 'x' key to exit menuselect and save
-your changes, and the build/install Asterisk normally.
-
----------------------
-Modify voicemail.conf
----------------------
-The following directives have been added to voicemail.conf:
-
-imapserver=<name or IP address of IMAP mail server>
-imapport=<IMAP port, defaults to 143>
-imapflags=<IMAP flags, "novalidate-cert" for example>
-expungeonhangup=<yes or no>
-authuser=<username>
-authpassword=<password>
-
-The "expungeonhangup" flag is used to determine if the voicemail system should
-expunge all messages marked for deletion when the user hangs up the phone.
-
-Each mailbox definition should also have imapuser=<imap username>.
-For example:
-
-4123=>4123,James Rothenberger,jar@onebiztone.com,,attach=yes|imapuser=jar
-
-The directives "authuser" and "authpassword" are not needed when using
-Kerberos. They are defined to allow Asterisk to authenticate as a single
-user that has access to all mailboxes as an alternative to Kerberos.
-
---------------
-IMAP Folders
---------------
-Besides INBOX, users should create "Old", "Work", "Family" and "Friends"
-IMAP folders at the same level of hierarchy as the INBOX. These will be
-used as alternate folders for storing voicemail messages to mimic the
-behavior of the current (file-based) voicemail system.
-
-
-==================================
-Separate vs. Shared Email Accounts
-==================================
-As administrator you will have to decide if you want to send the voicemail
-messages to a separate IMAP account or use each user's existing IMAP mailbox
-for voicemail storage. The IMAP storage mechanism will work either way.
-
-By implementing a single IMAP mailbox, the user will see voicemail messages
-appear in the same INBOX as other messages. The disadvantage of this method
-is that if the IMAP server does NOT support UIDPLUS, Asterisk voicemail will
-expunge ALL messages marked for deletion when the user exits the voicemail
-system, not just the VOICEMAIL messages marked for deletion.
-
-By implementing separate IMAP mailboxes for voicemail and email, voicemail
-expunges will not remove regular email flagged for deletion.
-
-===========================
-IMAP Server Implementations
-===========================
-There are various IMAP server implementations, each supports a potentially
-different set of features.
-
------------------------
-UW IMAP-2005 or earlier
------------------------
-UIDPLUS is currently NOT supported on these versions of UW-IMAP. Please note
-that without UID_EXPUNGE, Asterisk voicemail will expunge ALL messages marked
-for deletion when a user exits the voicemail system (hangs up the phone).
-
--------------------------------
-UW IMAP-2006 Development Branch
--------------------------------
-This version supports UIDPLUS, which allows UID_EXPUNGE capabilities. This
-feature allow the system to expunge ONLY pertinent messages, instead of the
-default behavior, which is to expunge ALL messages marked for deletion when
-EXPUNGE is called. The IMAP storage mechanism is this version of Asterisk
-will check if the UID_EXPUNGE feature is supported by the server, and use it
-if possible.
-
-----------
-Cyrus IMAP
-----------
-Cyrus IMAP server v2.3.3 has been tested using a hierarchy delimiter of '/'.
-
-
-=============
-Quota Support
-=============
-If the IMAP server supports quotas, Asterisk will check the quota when
-accessing voicemail. Currently only a warning is given to the user that
-their quota is exceeded.
-
-
-=================
-Application Notes
-=================
-Since the primary storage mechanism is IMAP, all message information that
-was previously stored in an associated text file, AND the recording itself,
-is now stored in a single email message. This means that the .gsm recording
-will ALWAYS be attached to the message (along with the user's preference of
-recording format if different - ie. .WAV). The voicemail message information
-is stored in the email message headers. These headers include:
-
-X-Asterisk-VM-Message-Num
-X-Asterisk-VM-Server-Name
-X-Asterisk-VM-Context
-X-Asterisk-VM-Extension
-X-Asterisk-VM-Priority
-X-Asterisk-VM-Caller-channel
-X-Asterisk-VM-Caller-ID-Num
-X-Asterisk-VM-Caller-ID-Name
-X-Asterisk-VM-Duration
-X-Asterisk-VM-Category
-X-Asterisk-VM-Orig-date
-X-Asterisk-VM-Orig-time
-
-=================
-Known Issues
-=================
-
- - Forward With Comment advanced option is not currently supported.
- This feature will be added in the near future.
- - Message Waiting Indicator blinks off and back on when a message arrives.
- This should be fixed soon.
diff --git a/1.4/doc/ip-tos.txt b/1.4/doc/ip-tos.txt
deleted file mode 100644
index 36febd99a..000000000
--- a/1.4/doc/ip-tos.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-IP Type of Service settings for VoIP channels
----------------------------------------------
-
-Asterisk can set the Type of Service (TOS) byte on outgoing IP packets
-for various protocols. The TOS byte is used by the network to provide
-some level of Quality of Service (QoS) even if the network is
-congested with other traffic.
-
-* SIP
------
-In sip.conf, there are three parameters that control the TOS settings:
-"tos_sip", "tos_audio", and "tos_video". tos_sip controls what TOS SIP call
-signalling packets are set to. tos_audio controls what TOS RTP audio
-packets are set to. tos_video controls what TOS RTP video packets are
-set to.
-There is a "tos" parameter that is supported for backwards
-compatibility. The tos parameter should be avoided in sip.conf
-because it sets all three tos settings in sip.conf to the same value.
-
-* IAX2
-------
-In iax.conf, there is a "tos" parameter that sets the global default TOS
-for IAX packets generated by chan_iax2. Since IAX connections combine
-signalling, audio, and video into one UDP stream, it is not possible
-to set the TOS separately for the different types of traffic.
-
-In iaxprov.conf, there is a "tos" parameter that tells the IAXy what TOS
-to set on packets it generates. As with the parameter in iax.conf,
-IAX packets generated by an IAXy cannot have different TOS settings
-based upon the type of packet. However different IAXy devices can
-have different TOS settings.
-
-The allowable values for any of the tos* parameters are:
-CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, AF11, AF12, AF13,
-AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43 and
-ef (expedited forwarding),
-
-The tos* parameters also take numeric values.
-
-The lowdelay, throughput, reliability, mincost, and none values are
-deprecated because they set the IP TOS using the outdated "IP
-precedence" model as defined in RFC 791 and RFC 1349. They still
-work in this version of Asterisk, but will be removed in future releases.
-
-===========================================
-Configuration Parameter Recommended
-File Setting
--------------------------------------------
-sip.conf tos_sip cs3
-sip.conf tos_audio ef
-sip.conf tos_video af41
--------------------------------------------
-iax.conf tos ef
--------------------------------------------
-iaxprov.conf tos ef
-===========================================
-
-
-* REFERENCE
------------
-RFC 2474 - "Definition of the Differentiated Services Field
-(DS field) in the IPv4 and IPv6 Headers", Nichols, K., et al,
-December 1998.
-
-IANA Assignments, DSCP registry
-Differentiated Services Field Codepoints
-http://www.iana.org/assignments/dscp-registry
-
-To get the most out of setting the TOS on packets generated by
-Asterisk, you will need to ensure that your network handles packets
-with a TOS properly. For Cisco devices, see the previously mentioned
-"Enterprise QoS Solution Reference Network Design Guide". For Linux
-systems see the "Linux Advanced Routing & Traffic Control HOWTO" at
-<http://www.lartc.org/>.
-
-For more information on Quality of
-Service for VoIP networks see the "Enterprise QoS Solution Reference
-Network Design Guide" version 3.3 from Cisco at:
-
-<http://www.cisco.com/application/pdf/en/us/guest/netsol/ns432/c649/ccmigration_09186a008049b062.pdf>
-
diff --git a/1.4/doc/jabber.txt b/1.4/doc/jabber.txt
deleted file mode 100644
index ca3e0f528..000000000
--- a/1.4/doc/jabber.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-(res_jabber is very experimental!)
-
-Jabber(xmpp) is an xml based protocol primarily for presence and messaging.
-It is an open standard and there are several open server implementations,
-ejabberd, jabberd(2), wildfire, and many others, as well as several open source
-clients, Psi, gajim, gaim etc. Jabber differs from other IM applications as it
-is immensly extendable. This allows us to easily integrate Asterisk with
-jabber. The Asterisk Jabber Interface is provided by res_jabber.so. res_jabber
-allows for Asterisk to connect to any jabber server via the standard client
-protocol or also as a simple client. Several simple functions are exposed to
-the dial plan, jabberstatus, jabbersend, and soon jabberrecv. res_jabber is also used
-to provide the connection interface for chan_jingle.
-
-The maintainer of res_jabber is Matthew O'Gorman <mogorman@digium.com> or
-mog_work on irc or (preferred) mogorman@astjab.org over jabber.
diff --git a/1.4/doc/jingle.txt b/1.4/doc/jingle.txt
deleted file mode 100644
index 76398f10a..000000000
--- a/1.4/doc/jingle.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-(Jingle support in asterisk is experimental)
-Jingle is an xmpp based protocol for signalling the transfer of media.
-Currently asterisk supports the proprietary GoogleTalk protocol that is
-very similar to jingle, and hopes to soon support true jingle specs
-(JEP-166,167,176,177,180,181 etc) as more clients support the true standard.
-Jingle's configuration is very similar to sip.conf only as we are not the
-jabber server in this case you must provide a connection for the peer to
-travel out on.
-chan_gtalk is for supporting the non-jingle google/libjingle spec and
-chan_jingle will continue to move in the direction of the correct spec. but
-not be supported in version 1.4
diff --git a/1.4/doc/jitterbuffer.txt b/1.4/doc/jitterbuffer.txt
deleted file mode 100644
index e5cd81ce0..000000000
--- a/1.4/doc/jitterbuffer.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-The new Jitterbuffer in Asterisk
---------------------------------
-Steve Kann
-
-
-
-The new jitterbuffer, PLC, and the IAX2-integration of the new jitterbuffer
-have been integrated into Asterisk. The jitterbuffer is generic and work is
-going on to implement it in SIP/RTP as well.
-
-Also, we've added a feature called "trunktimestamps", which adds individual
-timestamps to trunked frames within a trunk frame.
-
-Here's how to use this stuff:
-
-1) The new jitterbuffer:
-------------------------
-You must add "jitterbuffer=yes" to either the [general] part of
-iax.conf, or to a peer or a user. (just like the old jitterbuffer).
-Also, you can set "maxjitterbuffer=n", which puts a hard-limit on the size of the
-jitterbuffer of "n milliseconds". It is not necessary to have the new jitterbuffer
-on both sides of a call; it works on the receive side only.
-
-2) PLC:
--------
-The new jitterbuffer detects packet loss. PLC is done to try to recreate these
-lost packets in the codec decoding stage, as the encoded audio is translated to slinear.
-PLC is also used to mask jitterbuffer growth.
-
-This facility is enabled by default in iLBC and speex, as it has no additional cost.
-This facility can be enabled in adpcm, alaw, g726, gsm, lpc10, and ulaw by setting
-genericplc => true in the [plc] section of codecs.conf.
-
-3) Trunktimestamps:
--------------------
-To use this, both sides must be using Asterisk v1.2.
-Setting "trunktimestamps=yes" in iax.conf will cause your box to send 16-bit timestamps
-for each trunked frame inside of a trunk frame. This will enable you to use jitterbuffer
-for an IAX2 trunk, something that was not possible in the old architecture.
-
-The other side must also support this functionality, or else, well, bad things will happen.
-If you don't use trunktimestamps, there's lots of ways the jitterbuffer can get confused because
-timestamps aren't necessarily sent through the trunk correctly.
-
-4) Communication with Asterisk v1.0.x systems
----------------------------------------------
-You can set up communication with v1.0.x systems with the new jitterbuffer, but
-you can't use trunks with trunktimestamps in this communication.
-
-If you are connecting to an Asterisk server with earlier versions of the software (1.0.x),
-do not enable both jitterbuffer and trunking for the involved peers/users
-in order to be able to communicate. Earlier systems will not support trunktimestamps.
-
-You may also compile chan_iax2.c without the new jitterbuffer, enabling the old
-backwards compatible architecture. Look in the source code for instructions.
-
-
-5) Testing and monitoring:
---------------------------
-You can test the effectiveness of PLC and the new jitterbuffer's detection of loss by using
-the new CLI command "iax2 test losspct <n>". This will simulate n percent packet loss
-coming _in_ to chan_iax2. You should find that with PLC and the new JB, 10 percent packet
-loss should lead to just a tiny amount of distortion, while without PLC, it would lead to
-silent gaps in your audio.
-
-"iax2 show netstats" shows you statistics for each iax2 call you have up.
-The columns are "RTT" which is the round-trip time for the last PING, and then a bunch of s
-tats for both the local side (what you're receiving), and the remote side (what the other
-end is telling us they are seeing). The remote stats may not be complete if the remote
-end isn't using the new jitterbuffer.
-
-The stats shown are:
-* Jit: The jitter we have measured (milliseconds)
-* Del: The maximum delay imposed by the jitterbuffer (milliseconds)
-* Lost: The number of packets we've detected as lost.
-* %: The percentage of packets we've detected as lost recently.
-* Drop: The number of packets we've purposely dropped (to lower latency).
-* OOO: The number of packets we've received out-of-order
-* Kpkts: The number of packets we've received / 1000.
-
-Reporting problems
-==================
-
-There's a couple of things that can make calls sound bad using the jitterbuffer:
-
-1) The JB and PLC can make your calls sound better, but they can't fix everything.
-If you lost 10 frames in a row, it can't possibly fix that. It really can't help much
-more than one or two consecutive frames.
-
-2) Bad timestamps: If whatever is generating timestamps to be sent to you generates
-nonsensical timestamps, it can confuse the jitterbuffer. In particular, discontinuities
-in timestamps will really upset it: Things like timestamps sequences which go 0, 20, 40,
-60, 80, 34000, 34020, 34040, 34060... It's going to think you've got about 34 seconds
-of jitter in this case, etc..
-The right solution to this is to find out what's causing the sender to send us such nonsense,
-and fix that. But we should also figure out how to make the receiver more robust in
-cases like this.
-
-chan_iax2 will actually help fix this a bit if it's more than 3 seconds or so, but at
-some point we should try to think of a better way to detect this kind of thing and
-resynchronize.
-
-Different clock rates are handled very gracefully though; it will actually deal with a
-sender sending 20% faster or slower than you expect just fine.
-
-3) Really strange network delays: If your network "pauses" for like 5 seconds, and then
-when it restarts, you are sent some packets that are 5 seconds old, we are going to see
-that as a lot of jitter. We already throw away up to the worst 20 frames like this,
-though, and the "maxjitterbuffer" parameter should put a limit on what we do in this case.
-
-Reporting possible bugs
------------------------
-If you do find bad behaviors, here's the information that will help to diagnose this:
-
-1) Describe
-
-a) the source of the timestamps and frames: i.e. if they're coming from another chan_iax2 box,
-a bridged RTP-based channel, an IAX2 softphone, etc..
-
-b) The network between, in brief (i.e. the internet, a local lan, etc).
-
-c) What is the problem you're seeing.
-
-
-2) Take a look and see what iax2 show netstats is saying about the call, and if it makes sense.
-
-3) a tcpdump of the frames, (or, tethereal output from), so we can see the timestamps and delivery
-times of the frames you're receiving. You can make such a tcpdump with:
-
-tcpdump -s 2048 -w /tmp/example.dump udp and port 4569 [and host <other-end>]
-
-Report bugs in the Asterisk bugtracker, http://bugs.digium.com.
-Please read the bug guidelines before you post a bug.
-
-Have fun!
-
--SteveK
diff --git a/1.4/doc/linkedlists.txt b/1.4/doc/linkedlists.txt
deleted file mode 100644
index 340933548..000000000
--- a/1.4/doc/linkedlists.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-As of 2004-12-23, this documentation is no longer maintained. The doxygen documentation
-generated from linkedlists.h should be referred to in its place, as it is more complete
-and better maintained.
-
-2nd version, implemented as macros.
-
- include <asterisk/linkedlists.h>
-
-AST_LIST_ENTRY declares pointers inside the object structure :
-
- struct ast_var_t {
- char *name;
- char *value;
- AST_LIST_ENTRY(ast_var_t) listpointers;
- };
-
-AST_LIST_HEAD declares a head structure, which is initialized
-to AST_LIST_HEAD_NULL :
-
- AST_LIST_HEAD(head, ast_var_t) head
-
-Next, we declare a pointer to this structure :
-
- struct headtype *headp = head;
-
-AST_LIST_INIT initializes the head pointer to a null value
-
- AST_LIST_INIT(headp);
-
-AST_LIST_INSERT_HEAD inserts an element to the head of the list :
-
- struct ast_var_t *node;
-
- node=malloc(sizeof(struct ast_var_t));
- (...we fill data in struct....)
- data->name=malloc(100);
- strcpy(data->name,"lalalalaa");
- etc etc
-
- (then we insert the node in the head of the list :)
-
- AST_LIST_INSERT_HEAD(headp,node,listpointers);
-
-AST_LIST_INSERT_HEAD_AFTER inserts an element after another :
-
- struct ast_var_t *node1;
- ...
- AST_LIST_INSERT_AFTER(node,node1,listpointers);
-
-AST_LIST_REMOVE removes an arbitrary element from the head:
-
- AST_LIST_REMOVE(headp,node1,ast_var_t,listpointers);
-
-AST_LIST_REMOVE_HEAD removes the entry at the head of the list and
-returns a pointer to the removed entry:
-
- AST_LIST_REMOVE_HEAD(headp,node,listpointers);
-
-AST_LIST_FIRST returns a pointer to the first element of the list;
-
- struct ast_var_t *firstnode;
- firstnode=AST_LIST_FIRST(headp);
-
-AST_LIST_NEXT returns a pointer to the next element :
-
- struct ast_var_t *nextnode;
- nextnode=AST_LIST_NEXT(firstnode,listpointers);
-
-AST_LIST_TRAVERSE traverses all elements of the list :
-
- struct ast_var_t *node;
-
- AST_LIST_TRAVERSE(headp,node,listpointers) {
- printf("%s\n",node->name);
- }
-
-AST_LIST_EMPTY evaluates to a true condition if there are no elements on
-the list.
-
-To completely delete a list :
-
- struct ast_var_t *vardata;
-
- while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */
- vardata = AST_LIST_REMOVE_HEAD(head, ast_var_t, listpointers);
- free(vardata->name);
- free(vardata->value);
- }
-
-AST_LIST_LOCK returns true if it can lock the list, AST_LIST_UNLOCK unlocks
-the list :
-
-if (AST_LIST_LOCK(headp)) {
- ...do all list operations here...
- AST_LIST_UNLOCK(headp);
-} else {
- ast_log(LOG_WARNING,"List locked bla bla bla\n");
-}
diff --git a/1.4/doc/localchannel.txt b/1.4/doc/localchannel.txt
deleted file mode 100644
index ccedbebed..000000000
--- a/1.4/doc/localchannel.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-The Local channel
------------------
-
-chan_local is a pseudo-channel. Use of this channel simply loops calls back into the dialplan in a different context. Useful for recursive routing.
-
-* Syntax:
-
- Local/extension@context[/n]
-
-Adding "/n" at the end of the string will make the Local channel not do a native transfer (the "n" stands for "n"o release) upon the remote end answering the line. This is an esoteric, but important feature if you expect the Local channel to handle calls exactly like a normal channel. If you do not have the "no release" feature set, then as soon as the destination (inside of the Local channel) answers the line and one audio frame passes, the variables and dial plan will revert back to that of the original call, and the Local channel will become a zombie and be removed from the active channels list. This is desirable in some circumstances, but can result in unexpected dialplan behavior if you are doing fancy things with variables in your call handling.
-
-* Purpose:
-
-The Local channel construct can be used to establish dialing into any part of the dialplan.
-
-Imagine you have a TE410P in your box. You want to do something for which you must use a Dial statement (for instance when dropping files in /var/spool/outgoing) but you do want to be able to use your dialplans least-cost-routes or other intelligent stuff. What you could do before we had chan_local was create a cross-link between two ports of the TE410P and then Dial out one port and in the other. This way you could control where the call was going.
-
-Of course, this was a nasty hack, and to make it more sensible, chan_local was built.
-
-The "Local" channel driver allows you to convert an arbitrary extension into a channel. It is used in a variety of places, including agents, etc.
-
-This also allows us to hop to contexts like a GoSub routine; See examples below.
-
-Examples:
----------
-
-[inbound] ; here falls all incoming calls
-exten => s,1,Answer
-exten => s,2,Dial(local/200@internal,30,r)
-exten => s,3,Playback(sorrynoanswer)
-exten => s,4,Hangup
-
-[internal] ; here where our phones falls for default
-exten => 200,1,Dial(sip/blah)
-exten => 200,102,VoiceMail(${EXTEN}@default)
-
-exten => 201,1,Dial(zap/1)
-exten => 201,102,VoiceMail(${EXTEN}@default)
-
-exten => _0.,1,Dial(Zap/g1/${EXTEN:1}) ; outgoing calls with 0+number
-
-
-Caveats:
-If you use chan_local from a call-file and you want to pass channel variables into your context, make sure you append the '/n', because otherwise chan_local will 'optimize' itself out of the call-path, and the variables will get lost. i.e.
-
- Local/00531234567@pbx becomes Local/00531234567@pbx/n
-
-----------
-2004-01-17
diff --git a/1.4/doc/macroexclusive.txt b/1.4/doc/macroexclusive.txt
deleted file mode 100644
index 3a3111493..000000000
--- a/1.4/doc/macroexclusive.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-About the MacroExclusive application
-------------------------------------
-
-Steve Davies <steve@connection-telecom.com
-
-
-The MacroExclusive application was added to solve the problem of
-synchronisation between calls running at the same time.
-
-This is usually an issue when you have calls manipulating global
-variables or the Asterisk database, but may be useful elsewhere.
-
-Consider this example macro, intended to return a "next" number -
-each caller is intended to get a different number:
-
-[macro-next]
-exten => s,1,Set(RESULT=${COUNT})
-exten => s,n,SetGlobalVar(COUNT=$[${COUNT} + 1])
-
-The problem is that in a box with high activity, you can be sure
-that two calls will come along together - both will get the same
-"RESULT", or the "COUNT" value will get mangled.
-
-Calling this Macro via MacroExclusive will use a mutex to make sure
-that only one call executes in the Macro at a time. This ensures
-that the two lines execute as a unit.
-
-Note that even the s,2 line above has its own race problem. Two
-calls running that line at once will step on each other and
-the count will end up as +1 rather than +2.
-
-I've also been able to use MacroExclusive where I have two Macros
-that need to be mutually exclusive.
-
-Here's the example:
-
-[macro-push]
-; push value ${ARG2} onto stack ${ARG1}
-exten => s,1,Set(DB(STACK/${ARG1})=${ARG2}^${DB(STACK/${ARG1})})
-
-[macro-pop]
-; pop top value from stack ${ARG1}
-exten => s,1,Set(RESULT=${DB(STACK/${ARG1})})
-exten => s,n,Set(DB(STACK/${ARG1})=${CUT(RESULT,^,2)})
-exten => s,n,Set(RESULT=${CUT(RESULT,^,1)})
-
-All that futzing with the STACK/${ARG1} in the astdb needs protecting
-if this is to work. But neither push nor pop can run together.
-
-So add this "pattern":
-
-[macro-stack]
-exten => Macro(${ARG1},${ARG2},${ARG3})
-
-... and use it like so:
-
-exten => s,1,MacroExclusive(stack,push,MYSTACK,bananas)
-exten => s,n,MacroExclusive(stack,push,MYSTACK,apples)
-exten => s,n,MacroExclusive(stack,push,MYSTACK,guavas)
-exten => s,n,MacroExclusive(stack,push,MYSTACK,pawpaws)
-exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets pawpaws (yum)
-exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets guavas
-exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets apples
-exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets bananas
-
-We get to the push and pop macros "via" the stack macro. But only one call
-can execute the stack macro at a time; ergo, only one of push OR pop can
-run at a time.
-
-Hope people find this useful.
-
-Lastly, its worth pointing out that only Macros that access shared data
-will require this MacroExclusive protection. And Macro's that you call
-with macroExclusive should run quickly or you will clog up your Asterisk
-system.
-
-Regards,
-Steve
diff --git a/1.4/doc/manager.txt b/1.4/doc/manager.txt
deleted file mode 100644
index a0a832c8d..000000000
--- a/1.4/doc/manager.txt
+++ /dev/null
@@ -1,311 +0,0 @@
-The Asterisk Manager TCP/IP API - AMI
-=====================================
-
-The manager is a client/server model over TCP. With the manager interface,
-you'll be able to control the PBX, originate calls, check mailbox status,
-monitor channels and queues as well as execute Asterisk commands.
-
-AMI is the standard management interface into your Asterisk server.
-You configure AMI in manager.conf. By default, AMI is available on
-TCP port 5038 if you enable it in manager.conf.
-
-AMI receive commands, called "actions". These generate a "response"
-from Asterisk. Asterisk will also send "Events" containing various
-information messages about changes within Asterisk. Some actions
-generate an initial response and data in the form list of events.
-This format is created to make sure that extensive reports do not
-block the manager interface fully.
-
-Management users are configured in the configuration file manager.conf and are
-given permissions for read and write, where write represents their ability
-to perform this class of "action", and read represents their ability to
-receive this class of "event".
-
-The Asterisk manager interface in version 1.0.x of Asterisk is
-not very well standardized. Work is under way to change this
-to Asterisk 1.2. If you develop AMI applications, treat the headers
-in Actions, Events and Responses as local to that particular
-message. There is no cross-message standardization of headers.
-
-If you develop applications, please try to reuse existing manager
-headers and their interpretation. If you are unsure, discuss on
-the asterisk-dev mailing list.
-
-Device status reports
----------------------
-Manager subscribes to extension status reports from all channels,
-to be able to generate events when an extension or device changes
-state. The level of details in these events may depend on the channel
-and device configuration. Please check each channel configuration
-file for more information. (in sip.conf, check the section on
-subscriptions and call limits)
-
-
-Command Syntax
---------------
-Management communication consists of tags of the form "header: value",
-terminated with an empty newline (\r\n) in the style of SMTP, HTTP, and
-other headers.
-
-
-The first tag MUST be one of the following:
-
- * Action: An action requested by the CLIENT to the Asterisk SERVER. Only one "Action" may be outstanding at any time.
- * Response: A response to an action from the Asterisk SERVER to the CLIENT.
- * Event: An event reported by the Asterisk SERVER to the CLIENT
-
-
-Manager commands
-----------------
-Output from the CLI command 'show manager' command:
-
- * Ping: Ping
- * Logoff: Logoff Manager
- * Hangup: Hangup Channel
- * Status: Status
- * Redirect: Redirect
- * Originate: Originate Call
- * MailboxStatus: Check Mailbox
- * Command: Execute Command
- * ExtensionState: Check Extension Status
- * AbsoluteTimeout: Set Absolute Timeout
- * MailboxCount: Check Mailbox Message Count
- * Monitor: Monitor a channel
- * StopMonitor: Stop monitoring a channel
- * ChangeMonitor: Change monitoring filename of a channel
- * IAXpeers: List IAX Peers (Defaults to IAX2)
- * SIPpeers: List SIP peers
- * SIPshowpeer: Show data about one SIP peer
- * Queues: Queues
- * QueueStatus: Queue Status
-
-This list depends on the version of Asterisk you are using, as
-well as which modules that are loaded.
-
-Command Summary
---------------
-
-Command: Command
-Parameters: Command
-
-Command: ExtensionState
-Parameters: Exten, Context, ActionID
-
-Command: Hangup
-Parameters: Channel
-
-Command: Logoff
-Parameters: None
-
-Command: MailboxCount
-Parameters: Mailbox, ActionID
-
-Command: MailboxStatus
-Parameters: Mailbox, ActionID
-
-Command: Originate
-Parameters: Channel, Exten, Context, Priority, Timeout,
- CallerID, Variable, Account, Application, Data, Async
-
-Command: Ping
-Parameters: None
-
-Command: PlayDTMF
-Parameters: Channel, Digit
-
-Command: Redirect
-Parameters: Channel, ExtraChannel, Exten, Context, Priority
-
-Command: Timeout
-Parameters: Channel, Timeout
-
-You can always get more information about a manager command
-with the "show manager command <command>" CLI command in Asterisk.
-
-Examples
---------
-Login - Log a user into the manager interface.
-
- Action: Login
- Username: testuser
- Secret: testsecret
-
-Originate - Originate a call from a channel to an extension.
-
- Action: Originate
- Channel: sip/12345
- Exten: 1234
- Context: default
-
-Originate - Originate a call from a channel to an extension without waiting
-for call to complete.
-
- Action: Originate
- Channel: sip/12345
- Exten: 1234
- Context: default
- Async: yes
-
-
-Redirect with ExtraChannel:
- Attempted goal:
- Have a 'robot' program Redirect both ends of an already-connected call
- to a meetme room using the ExtraChannel feature through the management interface.
-
- Action: Redirect
- Channel: Zap/1-1
- ExtraChannel: SIP/3064-7e00 (varies)
- Exten: 680
- Priority: 1
-
-Where 680 is an extension that sends you to a MeetMe room.
-
-There are a number of GUI tools that use the manager interface, please search
-the mailing list archives and the documentation page on the
-http://www.asterisk.org web site for more information.
-
-
-Some standard AMI headers:
---------------------------
-
- Account: -- Account Code (Status)
- AccountCode: -- Account Code (cdr_manager)
- ACL: <Y | N> -- Does ACL exist for object ?
- Action: <action> -- request or notification of a particular action
- Address-IP: -- IPaddress
- Address-Port: -- IP port number
- Agent: <string> -- Agent name
- AMAflags: -- AMA flag (cdr_manager, sippeers)
- AnswerTime: -- Time of answer (cdr_manager)
- Append: <bool> -- CDR userfield Append flag
- Application: -- Application to use
- Async: -- Whether or not to use fast setup
- AuthType: -- Authentication type (for login or challenge)
- "md5"
- BillableSeconds: -- Billable seconds for call (cdr_manager)
- CallerID: -- Caller id (name and number in Originate & cdr_manager)
- CallerID: -- CallerID number
- Number or "<unknown>" or "unknown"
- (should change to "<unknown>" in app_queue)
- CallerID1: -- Channel 1 CallerID (Link event)
- CallerID2: -- Channel 2 CallerID (Link event)
- CallerIDName: -- CallerID name
- Name or "<unknown>" or "unknown"
- (should change to "<unknown>" in app_queue)
- Callgroup: -- Call group for peer/user
- CallsTaken: <num> -- Queue status variable
- Cause: <value> -- Event change cause - "Expired"
- Cause: <value> -- Hangupcause (channel.c)
- CID-CallingPres: -- Caller ID calling presentation
- Channel: <channel> -- Channel specifier
- Channel: <dialstring> -- Dialstring in Originate
- Channel: <tech/[peer/username]> -- Channel in Registry events (SIP, IAX2)
- Channel: <tech> -- Technology (SIP/IAX2 etc) in Registry events
- ChannelType: -- Tech: SIP, IAX2, ZAP, MGCP etc
- Channel1: -- Link channel 1
- Channel2: -- Link channel 2
- ChanObjectType: -- "peer", "user"
- Codecs: -- Codec list
- CodecOrder: -- Codec order, separated with comma ","
- Command: -- Cli command to run
- Context: -- Context
- Count: <num> -- Number of callers in queue
- Data: -- Application data
- Default-addr-IP: -- IP address to use before registration
- Default-Username: -- Username part of URI to use before registration
- Destination: -- Destination for call (Dialstring ) (dial, cdr_manager)
- DestinationContext: -- Destination context (cdr_manager)
- DestinationChannel: -- Destination channel (cdr_manager)
- DestUniqueID: -- UniqueID of destination (dial event)
- Disposition: -- Call disposition (CDR manager)
- Domain: <domain> -- DNS domain
- Duration: <secs> -- Duration of call (cdr_manager)
- Dynamic: <Y | N> -- Device registration supported?
- Endtime: -- End time stamp of call (cdr_manager)
- EventList: <flag> -- Flag being "Start", "End", "Cancelled" or "ListObject"
- Events: <eventmask> -- Eventmask filter ("on", "off", "system", "call", "log")
- Exten: -- Extension (Redirect command)
- Extension: -- Extension (Status)
- Family: <string> -- ASTdb key family
- File: <filename> -- Filename (monitor)
- Format: <format> -- Format of sound file (monitor)
- From: <time> -- Parking time (ParkedCall event)
- Hint: -- Extension hint
- Incominglimit: -- SIP Peer incoming limit
- Key:
- Key: -- ASTdb Database key
- LastApplication: -- Last application executed (cdr_manager)
- LastCall: <num> -- Last call in queue
- LastData: -- Data for last application (cdr_manager)
- Link: -- (Status)
- ListItems: <number> -- Number of items in Eventlist (Optionally sent in "end" packet)
- Location: -- Interface (whatever that is -maybe tech/name in app_queue )
- Loginchan: -- Login channel for agent
- Logintime: <number> -- Login time for agent
- Mailbox: -- VM Mailbox (id@vmcontext) (mailboxstatus, mailboxcount)
- MD5SecretExist: <Y | N> -- Whether secret exists in MD5 format
- Membership: <string> -- "Dynamic" or "static" member in queue
- Message: <text> -- Text message in ACKs, errors (explanation)
- Mix: <bool> -- Boolean parameter (monitor)
- NewMessages: <count> -- Count of new Mailbox messages (mailboxcount)
- Newname:
- ObjectName: -- Name of object in list
- OldName: -- Something in Rename (channel.c)
- OldMessages: <count> -- Count of old mailbox messages (mailboxcount)
- Outgoinglimit: -- SIP Peer outgoing limit
- Paused: <num> -- Queue member paused status
- Peer: <tech/name> -- "channel" specifier :-)
- PeerStatus: <tech/name> -- Peer status code
- "Unregistered", "Registered", "Lagged", "Reachable"
- Penalty: <num> -- Queue penalty
- Priority: -- Extension priority
- Privilege: <privilege> -- AMI authorization class (system, call, log, verbose, command, agent, user)
- Pickupgroup: -- Pickup group for peer
- Position: <num> -- Position in Queue
- Queue: -- Queue name
- Reason: -- "Autologoff"
- Reason: -- "Chanunavail"
- Response: <response> -- response code, like "200 OK"
- "Success", "Error", "Follows"
- Restart: -- "True", "False"
- RegExpire: -- SIP registry expire
- RegExpiry: -- SIP registry expiry
- Reason: -- Originate reason code
- Seconds: -- Seconds (Status)
- Secret: <password> -- Authentication secret (for login)
- SecretExist: <Y | N> -- Whether secret exists
- Shutdown: -- "Uncleanly", "Cleanly"
- SIP-AuthInsecure:
- SIP-FromDomain: -- Peer FromDomain
- SIP-FromUser: -- Peer FromUser
- SIP-NatSupport:
- SIPLastMsg:
- Source: -- Source of call (dial event, cdr_manager)
- SrcUniqueID: -- UniqueID of source (dial event)
- StartTime: -- Start time of call (cdr_manager)
- State: -- Channel state
- Status: -- Registration status (Registry events SIP)
- Status: -- Extension status (Extensionstate)
- Status: -- Peer status (if monitored) ** Will change name **
- "unknown", "lagged", "ok"
- Status: <num> -- Queue Status
- Status: -- DND status (DNDState)
- Time: <sec> -- Roundtrip time (latency)
- Timeout: -- Parking timeout time
- Timeout: -- Timeout for call setup (Originate)
- Timeout: <seconds> -- Timeout for call
- Uniqueid: -- Channel Unique ID
- Uniqueid1: -- Channel 1 Unique ID (Link event)
- Uniqueid2: -- Channel 2 Unique ID (Link event)
- User: -- Username (SIP registry)
- UserField: -- CDR userfield (cdr_manager)
- Val: -- Value to set/read in ASTdb
- Variable: -- Variable AND value to set (multiple separated with | in Originate)
- Variable: <name> -- For channel variables
- Value: <value> -- Value to set
- VoiceMailbox: -- VM Mailbox in SIPpeers
- Waiting: -- Count of mailbox messages (mailboxstatus)
-
- ** Please try to re-use existing headers to simplify manager message parsing in clients.
-
-Read the CODING-GUIDELINES if you develop new manager commands or events.
diff --git a/1.4/doc/math.txt b/1.4/doc/math.txt
deleted file mode 100644
index 7718f9e44..000000000
--- a/1.4/doc/math.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-
-Mathematical dialplan function
-
-Yeah, I thought it was a little insane too..
-
-adds:
-
-Sum, Multiply, Divide, Subtract, Modulus, GT, LT, GTE, LTE, EQ functions to Asterisk
-
-All functions follow the same basic pattern for parameters:
-
-parameter 1 = the math expression
-parameter 2 = the type of result
-
-Perform calculation on number 1 to number 2. Valid ops are:
- +,-,/,*,%,<,>,>=,<=,==
-and behave as their C equivalents.
-
-<type_of_result> - wanted type of result:
- f, float - float(default)
- i, int - integer,
- h, hex - hex,
- c, char - char
-
-Each math expression is performed as
-
- Action param1 on param2
-
-eg:
-
- Action = Divide
- Param1 = 10
- Param2 = 2
-
-Results in
-
- Divide 10 by 2
-
-
-Example dialplan:
-
-exten => 11099,1,Set(RV=${MATH(1+20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(10*2)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(10*2)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(10-2)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(2%10)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(10/0)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(10-200)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(1-20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(1<20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(1>=20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(101>20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(1==20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(20<=20)})
-exten => 11099,n,NOOP(${RV})
-exten => 11099,n,Set(RV=${MATH(123%16,int)})
-exten => 11099,n,NOOP(${RV})
diff --git a/1.4/doc/misdn.txt b/1.4/doc/misdn.txt
deleted file mode 100644
index 74f9742fb..000000000
--- a/1.4/doc/misdn.txt
+++ /dev/null
@@ -1,291 +0,0 @@
-mISDN Channel Driver for Asterisk PBX
-======================================
-
-
-This package contains the mISDN Channel Driver for the Asterisk PBX. It
-supports every mISDN Hardware and provides an interface for asterisk.
-
-Features:
----------
-
-* NT and TE mode
-* PP and PMP mode
-* BRI and PRI (with BNE1 and BN2E1 Cards)
-* Hardware Bridging
-* DTMF Detection in HW+mISDNdsp
-* Display Messages on Phones (on those that support display msg)
-* app_SendText
-* HOLD/RETRIEVE/TRANSFER on ISDN Phones : )
-* Screen/ Not Screen User Number
-* EchoCancellation
-* Volume Control
-* Crypting with mISDNdsp (Blowfish)
-* Data (HDLC) callthrough
-* Data Calling (with app_ptyfork +pppd)
-* Echo cancellation
-* CallDeflection
-* Some other
-
-Supported Hardware:
--------------------
-
-chan_misdn supports any mISDN compatible Hardware.
-
-Overview
---------
-
-- Fast Installation Guide
-- Pre-Requisites
-- Configuration
-- Dial and Options String
-- misdn cli commands
-- mISDN Variables
-- Debugging and sending Bugreports
-- Examples
-- Known Problems
-- Changes
-
-
-Fast Installation Guide
------------------------
-
-It is easy to install mISDN and mISDNuser. Just fetch the newest head of the
-cvs, this can be done by:
-
-cvs -d:pserver:anonymous:readonly@cvs.isdn4linux.de:/i4ldev co mISDN mISDNuser
-
-the compile and install both with:
-
-cd mISDN ;
-make && make install
-
-(you will need at least your kernel headers to compile mISDN).
-
-cd mISDNuser ;
-make && make install
-
-Now you can compile chan_misdn, just by making asterisk:
-
-cd asterisk ;
-make && make install
-
-That's all!
-
-
-Follow the instructions in the mISDN Package for howto loading the Kernel
-Modules.
-
-Pre-Requisites
---------------
-
-To compile and install this driver, you'll need at least one mISDN Driver and
-the mISDNuser package. Chan_misdn works with both, the current release version
-and the development (svn trunk) version of Asterisk. mISDNuser and mISDN must
-be fetched from cvs.isdn4linux.de.
-
-You should use Kernels >= 2.6.9
-
-
-Configuration
--------------
-
-First of all you must configure the mISDN drivers, please follow the
-instructions in the mISDN package to do that, the main config file and config
-script is:
-
-/etc/init.d/misdn-init and
-/etc/misdn-init.conf
-
-
-Now you will want to configure the misdn.conf file which resides in the
-asterisk config directory (normally /etc/asterisk).
-
-- misdn.conf: [general]
-The misdn.conf file contains a "general" Section, and user sections which
-contain misdn port settings and different Asterisk contexts.
-
-In the general Section you can set options that are not directly port
-related. There is for example the very important debug variable which you can
-set from the Asterisk cli (command line interface) or in this configuration
-file, bigger numbers will lead to more debug output. There's also a tracefile
-option, which takes a path+filename where debug output is written to.
-
-- misdn.conf: [default] section
-
-The default section is another special section which can contain all the
-options available in the user/port sections. the user/port section inherit
-their parameters from the default section.
-
-- misdn.conf: user/port sections
-
-The user sections have names which are unequal to "general". Those sections
-contain the ports variable which mean the mISDN Ports. Here you can add
-multiple ports, comma separated.
-
-Espacially for TE-Mode Ports there is a msns option. This option tells the
-chan_misdn driver to listen for incoming calls with the given msns, you can
-insert a '*' as single msn, which leads in getting every incoming call (if you
-want to share on PMP TE S0 with a asterisk and a phone or isdn card you should
-insert here the msns which you'll like to give the Asterisk). Finally a
-context variable resides in the user sections, which tells chan_misdn where to
-send incoming calls to in the Asterisk dial plan (extension.conf).
-
-
-Dial and Options String
------------------------
-
-The dial string of chan_misdn got more complex, because we added more features,
-so the generic dial string looks like:
-
-mISDN/<port>|g:<group>/<extension>[/<OPTIONSSTRING>]
-
-The Optionsstring looks Like:
-:<optchar1><OptParam1>:<optchar2><OptParam2>
-
-the ":" character is the delimiter.
-
-The available Optchars are:
- d - Send display text on called phone, text is the optparam
- n - don't detect dtmf tones on called channel
- h - make digital outgoing call
- c - make crypted outgoing call, param is keyindex
- e - perform echo cancellation on this channel,
- takes taps as arguments (32,64,128,256)
- s - send Non Inband DTMF as inband
- vr - rxgain control
- vt - txgain control
-
-
-chan_misdn registers a new dial plan application "misdn_set_opt" when
-loaded. This application takes the Optionsstring as argument. The Syntax is:
-
-misdn_set_opt(<OPTIONSSTRING>)
-
-
-When you set options in the dialstring, the options are set in the external
-channel. When you set options with misdn_set_opt, they are set in the current
-incoming channel. So if you like to use static encryption, the scenario looks
-as follows:
-
-Phone1 --> * Box 1 --> PSTN_TE
-PSTN_TE --> * Box 2 --> Phone2
-
-The Encryption must be done on the PSTN sides, so the dialplan on the boxes
-are:
-
-* Box 1:
-exten => _${CRYPT_PREFIX}X.,1,Dial(mISDN/g:outbound/:c1)
-
-* Box 2:
-exten => ${CRYPT_MSN},1,misdn_set_opt(:c1)
-exten => ${CRYPT_MSN},2,dial(${PHONE2})
-
-
-
-
-misdn cli commands
-------------------
-
-At the Asterisk cli you can try to type in:
-
-misdn <tab> <tab>
-
-Now you should see the misdn cli commands:
-
-- clean
- -> pid (cleans a broken call, use with care, leads often
- to a segmentation fault)
-- send
- -> display (sends a Text Message to a Asterisk channel,
- this channel must be an misdn channel)
-- set
- -> debug (sets debug level)
-- show
- -> config (shows the configuration options)
- -> channels (shows the current active misdn channels)
- -> channel (shows details about the given misdn channels)
- -> stacks (shows the current ports, their protocols and states)
- -> fullstacks (shows the current active and inactive misdn channels)
-
-- restart
- -> port (restarts given port (L2 Restart) )
-
-- reload (reloads misdn.conf)
-
-You can only use "misdn send display" when an Asterisk channel is created and
-isdn is in the correct state. "correct state" means that you have established a
-call to another phone (mustn't be isdn though).
-
-Then you use it like this:
-
-misdn send display mISDN/1/101 "Hello World!"
-
-where 1 is the Port of the Card where the phone is plugged in, and 101 is the
-msn (callerid) of the Phone to send the text to.
-
-
-mISDN Variables
----------------
-
-mISDN Exports/Imports a few Variables:
-
-- MISDN_ADDRESS_COMPLETE : Is either set to 1 from the Provider, or you
- can set it to 1 to force a sending complete.
-
-
-
-Debugging and sending bug reports
----------------------------------
-
-If you encounter problems, you should set up the debugging flag, usually
-debug=2 should be enough. the messages are divided in asterisk and misdn
-parts. Misdn Debug messages begin with an 'I', asterisk messages begin with
-an '*', the rest is clear I think.
-
-Please take a trace of the problem and open a report in the Asterisk issue
-tracker at http://bugs.digium.com in the "channel drivers" project,
-"chan_misdn" category. Read the bug guidelines to make sure you
-provide all the information needed.
-
-
-Examples
---------
-
-Here are some examples of how to use chan_misdn in the dialplan
-(extensions.conf):
-
-
-[globals]
-OUT_PORT=1 ; The physical Port of the Card
-OUT_GROUP=ExternE1 ; The Group of Ports defined in misdn.conf
-
-[misdnIn]
-exten => _X.,1,Dial(mISDN/${OUT_PORT}/${EXTEN})
-exten => _0X.,1,Dial(mISDN/g:${OUT_GROUP}/${EXTEN:1})
-exten => _1X.,1,Dial(mISDN/g:${OUT_GROUP}/${EXTEN:1}/:dHello)
-exten => _1X.,1,Dial(mISDN/g:${OUT_GROUP}/${EXTEN:1}/:dHello Test:n)
-
-On the last line, you will notice the last argument (Hello); this is sent
-as Display Message to the Phone.
-
-Known Problems
---------------
-
-* When I use mISDN->IAX I cannot make Trunk calls
-
--> You need to use ztdummy as dummy zaptel interface for the iax timing in
-trunking mode, simply grab libpri, zaptel and compile them (i think you need
-to modify the makefile in zaptel to add ztdummy to the default compiled
-modules) then modprobe ztdummy, this resolves the problem.
-
-
-* I cannot hear any tone after a successful CONNECT to the other end
-
--> you forgot to load mISDNdsp, which is now needed by chan_misdn for switching
-and dtmf tone detection
-
-
-Changes
--------
-in the Changes File
-
diff --git a/1.4/doc/model.txt b/1.4/doc/model.txt
deleted file mode 100644
index 10d2d0e05..000000000
--- a/1.4/doc/model.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Description of call model:
-
-Incoming Call:
-
- Channel backend waits for a RING or equivalent on some sort of
-interface. Typically this is done in its own thread. When a RING is
-detected, the backend should create a channel structure and then call
-ast_pbx_start() on that channel, which will create a thread to monitor
-that interface. At this point, the PBX and/or applications it launches
-will manage the interface, and it need not be monitored by the
-aforementioned thread. When the applications are finished, the requisite
-hangup function will be called, at which the channel can be considered to
-be no longer valid, and the thread that controls it will imminently be
-terminated.
-
diff --git a/1.4/doc/modules.txt b/1.4/doc/modules.txt
deleted file mode 100644
index 4f6d4c67b..000000000
--- a/1.4/doc/modules.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-All modules must have at least the following functions:
-
-int load_module():
-
- Do what you need to do when you get started. This function
-returns 0 on success and non-zero on failure (it is not considered loaded
-if it fails.
-
-int unload_module():
-
- The module will soon be unloaded. If any channels are using your
-features, you should give them a softhangup in an effort to keep the
-program from crashing. Generally, unload_module is only called when the
-usecount is 0 or less, but the user can force unloading at their
-discretion, and thus a module should do its best to comply (although in
-some cases there may be no way to avoid a crash). This function should
-return 0 on success and non-zero on failure (i.e. it cannot yet be
-unloaded).
-
-char *description():
-
- Return a description of the module's functionality.
-
-int usecnt():
-
- Return the number of channels, etc that are using you.
diff --git a/1.4/doc/mp3.txt b/1.4/doc/mp3.txt
deleted file mode 100644
index 82205fdc0..000000000
--- a/1.4/doc/mp3.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-* Asterisk MP3 Support
-======================
-
-* MP3 Music On Hold
-Use of the mpg123 for your music on hold is no longer recommended and is now
-officially deprecated. You should now use one of the native formats for your
-music on hold selections.
-
-However, if you still need to use mp3 as your music on hold format, a format
-driver for reading MP3 audio files is available in the asterisk-addons SVN
-repository on svn.digium.com or in the asterisk-addons release at
-http://downloads.digium.com/pub/telephony/asterisk/.
-
diff --git a/1.4/doc/musiconhold-fpm.txt b/1.4/doc/musiconhold-fpm.txt
deleted file mode 100644
index ad11c4815..000000000
--- a/1.4/doc/musiconhold-fpm.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-About Hold Music
-================
-Digium has licensed the music included with
-the Asterisk distribution From FreePlayMusic
-for use and distribution with Asterisk. It
-is licensed ONLY for use as hold music within
-an Asterisk based PBX.
-
diff --git a/1.4/doc/mysql.txt b/1.4/doc/mysql.txt
deleted file mode 100644
index 27adaa956..000000000
--- a/1.4/doc/mysql.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-MYSQL LICENSING UPDATE
-======================
-We were recently contacted by MySQL and informed that the MySQL client
-libraries are now under GPL license and not LGPL license as before.
-
-Since Asterisk does allow exceptions to GPL, we are removing MySQL support
-from standard Asterisk. We will, where appropriate, make it available via
-a separate package which will only be usable when Asterisk is used completely
-within GPL (i.e. not in conjunction with G.729, OpenH.323, etc). We
-apologize for the confusion.
-
-You may find this in the new "asterisk-addons" package.
-
-Mark Spencer
-Digium
diff --git a/1.4/doc/odbcstorage.txt b/1.4/doc/odbcstorage.txt
deleted file mode 100644
index 435574b0e..000000000
--- a/1.4/doc/odbcstorage.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-ODBC Voicemail Storage
-======================
-
-ODBC Storage allows you to store voicemail messages within a database
-instead of using a file. This is *not* a full realtime engine and
-*only* supports ODBC. The table description for the "voicemessages"
-table is as follows:
-
-+----------------+-------------+------+-----+---------+-------+
-| Field | Type | Null | Key | Default | Extra |
-+----------------+-------------+------+-----+---------+-------+
-| msgnum | int(11) | YES | | NULL | |
-| dir | varchar(80) | YES | MUL | NULL | |
-| context | varchar(80) | YES | | NULL | |
-| macrocontext | varchar(80) | YES | | NULL | |
-| callerid | varchar(40) | YES | | NULL | |
-| origtime | varchar(40) | YES | | NULL | |
-| duration | varchar(20) | YES | | NULL | |
-| mailboxuser | varchar(80) | YES | | NULL | |
-| mailboxcontext | varchar(80) | YES | | NULL | |
-| recording | longblob | YES | | NULL | |
-+----------------+-------------+------+-----+---------+-------+
-
-The database name (from /etc/asterisk/res_odbc.conf) is in the
-"odbcstorage" variable in the general section of voicemail.conf.
-
-You may modify the voicemessages table name by using
-odbctable=??? in voicemail.conf
-
-
diff --git a/1.4/doc/osp.txt b/1.4/doc/osp.txt
deleted file mode 100644
index aff5cd088..000000000
--- a/1.4/doc/osp.txt
+++ /dev/null
@@ -1,421 +0,0 @@
-Asterisk V1.4 OSP Module
-User Guide
-February 9, 2007
-
-Table of Contents
-1 Introduction 3
-2 OSP Toolkit 3
-2.1 Build OSP Toolkit 3
-2.1.1 Unpacking the Toolkit 3
-2.1.2 Preparing to build the OSP Toolkit 4
-2.1.3 Building the OSP Toolkit 4
-2.1.4 Installing the OSP Toolkit 5
-2.1.5 Building the Enrollment Utility 5
-2.2 Obtain Crypto Files 5
-3 Asterisk 7
-3.1 OSP Support Implementation 7
-3.1.1 OSPAuth 7
-3.1.2 OSPLookup 7
-3.1.3 OSPNext 8
-3.1.4 OSPFinish 8
-3.2 Build with OSP Support 8
-3.3 Configure with OSP Support 9
-3.3.1 osp.conf 9
-3.3.2 zapata/sip/iax.conf 10
-3.3.3 extensions.conf 10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Asterisk is a trademark of Digium, Inc.
-TransNexus and OSP Secured are trademarks of TransNexus, Inc.
-
-1 Introduction
-This document provides instructions on how to build and configure Asterisk V1.4 with the OSP Toolkit to enable secure, multi-lateral peering. The OSP Toolkit is an open source implementation of the OSP peering protocol and is freely available from www.sourceforge.net. The OSP standard defined by the European Telecommunications Standards Institute (ETSI TS 101 321) www.etsi.org. If you have questions or need help, building Asterisk with the OSP Toolkit, please post your question on the OSP mailing list at https://lists.sourceforge.net/lists/listinfo/osp-toolkit-client.
-
-2 OSP Toolkit
-Please reference the OSP Toolkit document "How to Build and Test the OSP Toolkit” available from https://sourceforge.net/projects/osp-toolkit.
-
-2.1 Build OSP Toolkit
-The software listed below is required ti build and use the OSP Toolkit:
-* OpenSSL (required for building) - Open Source SSL protocol and Cryptographic Algorithms (version 0.9.7g recommended) from www.openssl.org. Pre-compiled OpenSSL binary packages are not recommended because of the binary compatibility issue.
-* Perl (required for building) - A programming language used by OpenSSL for compilation. Any version of Perl should work. One version of Perl is available from www.activestate.com/ActivePerl. If pre-compiled OpenSSL packages are used, Perl package is not required.
-* C compiler (required for building) - Any C compiler should work. The GNU Compiler Collection from www.gnu.org is routinely used for building the OSP Toolkit for testing.
-* OSP Server (required for testing) - Access to any OSP server should work. OpenOSP is a reference OSP server implementation created by Cisco Systems and is available at http://www.vovida.org/applications/downloads/openosp/. RAMS is a java based open source OSP server available from https://sourceforge.net/projects/rams. A free commercial OSP server may be downloaded from www.transnexus.com.
-
-2.1.1 Unpacking the Toolkit
-After downloading the OSP Toolkit (version 3.3.4 or later release) from https://sourceforge.net/projects/osp-toolkit, perform the following steps in order:
-
-1) Copy the OSP Toolkit distribution into the directory where it will reside, say /usr/src.
-
-2) Un-package the distribution file by executing the following command:
-gunzip –c OSPToolkit-###.tar.gz | tar xvf –
-Where ### is the version number separated by underlines. For example, if the version is 3.3.4, then the above command would be:
-gunzip –c OSPToolkit-3_3_4.tar.gz | tar xvf –
-A new directory (TK-3_3_4-20051103) will be created within the same directory as the tar file.
-
-3) Go to the TK-3_3_4-20051103 directory by running this command:
-cd TK-3_3_4-20051103
-Within this directory, you will find directories and files similar to what is listed below if the command "ls -F" is executed):
-ls -F
-enroll/
-RelNotes.txt lib/
-README.txt license.txt
-bin/ src/
-crypto/ test/
-include/
-
-2.1.2 Preparing to build the OSP Toolkit
-4) Compile OpenSSL according to the instructions provided with the OpenSSL distribution (You would need to do this only if you don’t have openssl already).
-
-5) Copy the OpenSSL header files (the *.h files) into the crypto/openssl directory within the osptoolkit directory. The OpenSSL header files are located under the openssl/include/openssl directory.
-
-6) Copy the OpenSSL library files (libcrypto.a and libssl.a) into the lib directory within the osptoolkit directory. The OpenSSL library files are located under the openssl directory.
-Note: Since the Asterisk requires the OpenSSL package. If the OpenSSL package has been installed, 4~6 are not necessary.
-2.1.3 Building the OSP Toolkit
-
-7) Optionally, change the install directory of the OSP Toolkit. Open the Makefile in the /usr/src/TK-3_3_4-20051103/src directory, look for the install path variable – INSTALL_PATH, and edit it to be anywhere you want (defaults /usr/local).
-Note: Please change the install path variable only if you are familiar with both the OSP Toolkit and the Asterisk. Otherwise, it may case that the Asterisk does not support the OSP protocol.
-
-8) From within the OSP Toolkit directory (/usr/src/TK-3_3_4-20051103), start the compilation script by executing the following commands:
-cd src
-make clean; make build
-
-2.1.4 Installing the OSP Toolkit
-The header files and the library of the OSP Toolkit should be installed. Otherwise, you must specify the OSP Toolkit path for the Asterisk.
-
-9) Use the same script to install the Toolkit.
-make install
-The make script is also used to install the OSP Toolkit header files and the library into the INSTALL_PATH specified in the Makefile.
-Note: Please make sure you have the rights to access the INSTALL_PATH directory. For example, in order to access /usr/local directory, normally, you should be root.
-By default, the OSP Toolkit is compiled in the production mode. The following table identifies which default features are activated with each compile option:
-Default Feature
-Production
-Development
-Debug Information Displayed
-No
-Yes
-The "Development" option is recommended for a first time build. The “CFLAGS” definition in the Makefile must be modified to build in development mode.
-
-2.1.5 Building the Enrollment Utility
-Device enrollment is the process of establishing a trusted cryptographic relationship between the VoIP device and the OSP Server. The Enroll program is a utility application for establishing a trusted relationship between and OSP client and an OSP server. Please see the document "Device Enrollment" at http://www.transnexus.com/OSP%20Toolkit/OSP%20Toolkit%20Documents/Device_Enrollment.pdf for more information about the enroll application.
-
-10) From within the OSP Toolkit directory (/usr/src/TK-3_3_4-20051103), execute the following commands at the command prompt:
-cd enroll
-make clean; make linux
-Compilation is successful if there are no errors anywhere in the compiler output. The enroll program is now located in the /usr/src/TK-3_3_4-20051103/bin directory. By this point, a fully functioning OSP Toolkit should have been successfully built.
-
-2.2 Obtain Crypto Files
-The OSP module in Asterisk requires three crypto files containing local certificate (localcert.pem), private key (pkey.pem), and CA certificate (cacert_0.pem). Asterisk will try to load the files from the Asterisk public/private key directory - /var/lib/asterisk/key. If the files are not present, the OSP module will not start and the Asterisk will not support the OSP protocol. Use the enroll.sh script from the toolkit distribution to enroll the Asterisk OSP module with an OSP server to obtain the crypto files. Documentation explaining how to use the enroll.sh script (Device Enrollment) to enroll with an OSP server is available at http://www.transnexus.com/OSP%20Toolkit/OSP%20Toolkit%20Documents/Device_Enrollment.pdf. Copy the files file generated by the enrollment process to the Asterisk configuration directory.
-
-Note: The osptestserver.transnexus.com is configured only for sending and receiving non-SSL messages, and issuing signed tokens. If you need help, post a message on the OSP mailing list at https://lists.sourceforge.net/lists/listinfo/osp-toolkit-client.
-
-The enroll.sh script takes the domain name or IP addresses of the OSP servers that the OSP Toolkit needs to enroll with as arguments, and then generates pem files – cacert_#.pem, certreq.pem, localcert.pem, and pkey.pem. The ‘#’ in the cacert file name is used to differentiate the ca certificate file names for the various SP’s (OSP servers). If only one address is provided at the command line, cacert_0.pem will be generated. If 2 addresses are provided at the command line, 2 files will be generated – cacert_0.pem and cacert_1.pem, one for each SP. The example below shows the usage when the client is registering with osptestserver.transnexus.com. If all goes well, the following text will be displayed.
-
-./enroll.sh osptestserver.transnexus.com
-Generating a 512 bit RSA private key
-........................++++++++++++
-.........++++++++++++
-writing new private key to 'pkey.pem'
------
-You are about to be asked to enter information that will be incorporated
-into your certificate request.
-What you are about to enter is what is called a Distinguished Name or a DN.
-There are quite a few fields but you can leave some blank
-For some fields there will be a default value,
-If you enter '.', the field will be left blank.
------
-Country Name (2 letter code) [AU]: _______
-State or Province Name (full name) [Some-State]: _______
-Locality Name (eg, city) []:_______
-Organization Name (eg, company) [Internet Widgits Pty Ltd]: _______
-Organizational Unit Name (eg, section) []:_______
-Common Name (eg, YOUR name) []:_______
-Email Address []:_______
-
-Please enter the following 'extra' attributes
-to be sent with your certificate request
-A challenge password []:_______
-An optional company name []:_______
-
-Error Code returned from openssl command : 0
-
-CA certificate received
-[SP: osptestserver.transnexus.com]Error Code returned from getcacert command : 0
-
-output buffer after operation: operation=request
-output buffer after nonce: operation=request&nonce=1655976791184458
-X509 CertInfo context is null pointer
-Unable to get Local Certificate
-depth=0 /CN=osptestserver.transnexus.com/O=OSPServer
-verify error:num=18:self signed certificate
-verify return:1
-depth=0 /CN=osptestserver.transnexus.com/O=OSPServer
-verify return:1
-The certificate request was successful.
-Error Code returned from localcert command : 0
-
-The files generated should be copied to the /var/lib/asterisk/key directory.
-Note: The script enroll.sh requires AT&T korn shell (ksh) or any of its compatible variants. The /usr/src/TK-3_3_4-20051103/bin directory should be in the PATH variable. Otherwise, enroll.sh cannot find the enroll file.
-
-3 Asterisk
-3.1 OSP Support Implementation
-In Asterisk, all OSP support is implemented as dial plan functions.
-
-3.1.1 OSPAuth
-OSP token validation function.
-Input:
-* OSPPEERIP: last hop IP address
-* OSPINTOKEN: inbound OSP token
-* provider: OSP service provider configured in osp.conf. If it is empty, default provider is used.
-* priority jump
-Output:
-* OSPINHANDLE: inbound OSP transaction handle
-* OSPINTIMELIMIT: inbound call duration limit
-* OSPAUTHSTATUS: OSPAuth return value. SUCCESS/FAILED/ERROR
-
-3.1.2 OSPLookup
-OSP lookup function.
-Input:
-* OSPPEERIP: last hop IP address
-* OSPINHANDLE: inbound OSP transaction handle
-* OSPINTIMELIMIT: inbound call duration limit
-* exten: called number
-* provider: OSP service provider configured in osp.conf. If it is empty, default provider is used.
-* priority jump
-Output:
-* OSPOUTHANDLE: outbound transaction handle
-* OSPTECH: outbound protocol
-* OSPDEST: outbound destination
-* OSPCALLING: outbound calling number
-* OSPOUTTOKEN: outbound OSP token
-* OSPRESULTS: number of remain destinations
-* OSPOUTTIMELIMIT: outbound call duration limit
-* OSPLOOKUPSTATUS: OSPLookup return value. SUCCESS/FAILED/ERROR
-
-3.1.3 OSPNext
-OSP lookup next function.
-Input:
-* OSPINHANDLE: inbound transaction handle
-* OSPOUTHANDLE: outbound transaction handle
-* OSPINTIMELIMIT: inbound call duration limit
-* OSPRESULTS: number of remain destinations
-* cause: last destination disconnect cause
-* priority jump
-Output:
-* OSPTECH: outbound protocol
-* OSPDEST: outbound destination
-* OSPCALLING: outbound calling number
-* OSPOUTTOKEN: outbound OSP token
-* OSPRESULTS: number of remain destinations
-* OSPOUTTIMELIMIT: outbound call duration limit
-* OSPNEXTSTATUS: OSPLookup return value. SUCCESS/FAILED/ERROR
-
-3.1.4 OSPFinish
-OSP report usage function.
-Input:
-* OSPINHANDLE: inbound transaction handle
-* OSPOUTHANDLE: outbound transaction handle
-* OSPAUTHSTATUS: OSPAuth return value
-* OSPLOOKUPTSTATUS: OSPLookup return value
-* OSPNEXTSTATUS: OSPNext return value
-* cause: last destination disconnect cause
-* priority jump
-Output:
-* OSPFINISHSTATUS: OSPLookup return value. SUCCESS/FAILED/ERROR
-
-3.2 Build with OSP Support
-If the OSP Toolkit is installed in the default install directory, /usr/local, no additional configuration is required. If the OSP Toolkit is installed in another directory, say /myosp, Asterisk must be configured with the location of the OSP Toolkit.
---with-osptk=/myosp
-Note: Please change the install path only if you familiar with both the OSP Toolkit and the Asterisk. Otherwise, the change may results Asterisk not supporting the OSP protocol.
-Now, you can compile Asterisk according to the instructions provided with the Asterisk distribution.
-
-3.3 Configure with OSP Support
-3.3.1 osp.conf
-;
-; Open Settlement Protocol Sample Configuration File
-;
-; This file contains configuration of providers that
-; are used by the OSP subsystem of Asterisk. The section
-; "general" is reserved for global options. Each other
-; section declares an OSP Provider. The provider "default"
-; is used when no provider is otherwise specified.
-;
-[general]
-;
-; Should hardware accelleration be enabled? May not be changed
-; on a reload.
-;
-accelerate=no
-;
-; Defines the token format that Asterisk can validate.
-; 0 - signed tokens only
-; 1 - unsigned tokens only
-; 2 - both signed and unsigned
-; The defaults to 0, i.e. the Asterisk can validate signed tokens only.
-;
-tokenformat=0
-;
-[default]
-;
-; All paths are presumed to be under /var/lib/asterisk/keys unless
-; the path begins with '/'
-;
-; Specify the private keyfile. If unspecified, defaults to the name
-; of the section followed by "-privatekey.pem" (e.g. default-privatekey.pem)
-;
-privatekey=pkey.pem
-;
-; Specify the local certificate file. If unspecified, defaults to
-; the name of the section followed by "-localcert.pem"
-;
-localcert=localcert.pem
-;
-; Specify one or more Certificate Authority keys. If none are listed,
-; a single one is added with the name "-cacert.pem"
-;
-cacert=cacert_0.pem
-;
-; Specific parameters can be tuned as well:
-;
-; maxconnections: Max number of simultaneous connections to the provider (default=20)
-; retrydelay: Extra delay between retries (default=0)
-; retrylimit: Max number of retries before giving up (default=2)
-; timeout: Timeout for response in milliseconds (default=500)
-;
-maxconnections=20
-retrydelay=0
-retrylimit=2
-timeout=500
-;
-; List all service points for this provider
-;
-;servicepoint=http://osptestserver.transnexus.com:1080/osp
-servicepoint=http://OSP server IP:1080/osp
-;
-; Set the "source" for requesting authorization
-;
-;source=foo
-source=[host IP]
-;
-; Set the authentication policy.
-; 0 - NO
-; 1 - YES
-; 2 - EXCLUSIVE
-; Default is 1, validate token but allow no token.
-;
-authpolicy=1
-
-3.3.2 zapata/sip/iax.conf
-There is no configuration required for OSP.
-
-3.3.3 extensions.conf
-An Asterisk box can be configured as OSP source/destination gateway or OSP proxy.
-
-3.3.3.1 OSP Source Gateway
-[PhoneSrcGW]
-; Set calling number if necessary
-exten => _XXXX.,1,Set(CALLERID(numner)=CallingNumber)
-; OSP lookup using default provider, if fail/error jump to 2+101
-exten => _XXXX.,2,OSPLookup(${EXTEN}||j)
-; Set calling number which may be translated
-exten => _XXXX.,3,Set(CALLERID(number)=${OSPCALLING})
-; Dial to destination, 60 timeout, with call duration limit
-exten => _XXXX.,4,Dial(${OSPTECH}/${OSPDEST},60,oL($[${OSPOUTTIMELIMIT}*1000]))
-; Wait 3 seconds
-exten => _XXXX.,5,Wait,3
-; Hangup
-exten => _XXXX.,6,Hangup
-; Deal with OSPLookup fail/error
-exten => _XXXX.,2+101,Hangup
-; OSP report usage
-exten => h,1,OSPFinish(${HANGUPCAUSE})
-3.3.3.2 OSP Destination Gateway
-[PhoneDstGW]
-; Get peer IP
-exten => _XXXX.,1,Set(OSPPEERIP=${SIPCHANINFO(peerip)})
-; Get OSP token
-exten => _XXXX.,2,Set(OSPINTOKEN=${SIP_HEADER(P-OSP-Auth-Token)})
-; Validate token using default provider, if fail/error jump to 3+101
-exten => _XXXX.,3,OSPAuth(|j)
-; Ringing
-exten => _XXXX.,4,Ringing
-; Wait 1 second
-exten => _XXXX.,5,Wait,1
-; Dial phone, timeout 15 seconds, with call duration limit
-exten => _XXXX.,6,Dial(${DIALOUTANALOG}/${EXTEN:1},15,oL($[${OSPINTIMELIMIT}*1000]))
-; Wait 3 seconds
-exten => _XXXX.,7,Wait,3
-; Hangup
-exten => _XXXX.,8,Hangup
-; Deal with OSPAuth fail/error
-exten => _XXXX.,3+101,Hangup
-; OSP report usage
-exten => h,1,OSPFinish(${HANGUPCAUSE})
-
-3.3.3.3 Proxy
-[GeneralProxy]
-; Get peer IP
-exten => _XXXX.,1,Set(OSPPEERIP=${SIPCHANINFO(peerip)})
-; Get OSP token
-exten => _XXXX.,2,Set(OSPINTOKEN=${SIP_HEADER(P-OSP-Auth-Token)})
-; Validate token using default provider, if fail/error jump to 3+101
-exten => _XXXX.,3,OSPAuth(|j)
-; OSP lookup using default provider, if fail/error jump to 4+101
-exten => _XXXX.,4,OSPLookup(${EXTEN}||j)
-; Set calling number which may be translated
-exten => _XXXX.,5,Set(CALLERID(number)=${OSPCALLING})
-; Dial to 1st destination, 60 timeout, with call duration limit
-exten => _XXXX.,6,Dial(${OSPTECH}/${OSPDEST},24,oL($[${OSPOUTTIMELIMIT}*1000]))
-; OSP lookup next, if fail/error jump to 7+101
-exten => _XXXX.,7,OSPNext(${HANGUPCAUSE}||j)
-; Set calling number which may be translated
-exten => _XXXX.,8,Set(CALLERID(number)=${OSPCALLING})
-; Dial to 2nd destination, 60 timeout, with call duration limit
-exten => _XXXX.,9,Dial(${OSPTECH}/${OSPDEST},25,oL($[${OSPOUTTIMELIMIT}*1000]))
-; OSP lookup next, if fail/error jump to 10+101
-exten => _XXXX.,10,OSPNext(${HANGUPCAUSE}||j)
-; Set calling number which may be translated
-exten => _XXXX.,11,Set(CALLERID(number)=${OSPCALLING})
-; Dial to 3rd destination, 60 timeout, with call duration limit
-exten => _XXXX.,12,Dial(${OSPTECH}/${OSPDEST},26,oL($[${OSPOUTTIMELIMIT}*1000]))
-; Hangup
-exten => _XXXX.,13,Hangup
-; Deal with OSPAuth fail/error
-exten => _XXXX.,3+101,Hangup
-; Deal with OSPLookup fail/error
-exten => _XXXX.,4+101,Hangup
-; Deal with 1st OSPNext fail/error
-exten => _XXXX.,7+101,Hangup
-; Deal with 2nd OSPNext fail/error
-exten => _XXXX.,10+101,Hangup
-; OSP report usage
-exten => h,1,OSPFinish(${HANGUPCAUSE})
-
-5
-
diff --git a/1.4/doc/privacy.txt b/1.4/doc/privacy.txt
deleted file mode 100644
index 3a990fa4b..000000000
--- a/1.4/doc/privacy.txt
+++ /dev/null
@@ -1,361 +0,0 @@
-Title: Everything About The Privacy Options In The Dial Command That
-You Never Wanted To Know, And Even A Little More On Zapateller and
-PrivacyManager:
-
-by Steve Murphy
-
-
-So, you want to avoid talking to pesky telemarketers/charity
-seekers/poll takers/magazine renewers/etc?
-
-=============
-First of all:
-=============
-
-Try the FTC "Don't call" database, this alone will reduce your
-telemarketing call volume considerably. (see:
-https://www.donotcall.gov/default.aspx ) But, this list won't protect
-from the Charities, previous business relationships, etc.
-
-
-=================================
-Next, Fight against autodialers!!
-=================================
-
-Zapateller detects if callerid is present, and if not, plays the
-da-da-da tones that immediately precede messages like, "I'm sorry,
-the number you have called is no longer in service."
-
-Most humans, even those with unlisted/callerid-blocked numbers, will
-not immediately slam the handset down on the hook the moment they hear
-the three tones. But autodialers seem pretty quick to do this.
-
-I just counted 40 hangups in Zapateller over the last year in my
-CDR's. So, that is possibly 40 different telemarketers/charities that have
-hopefully slashed my back-waters, out-of-the-way, humble home phone
-number from their lists.
-
-I highly advise Zapateller for those seeking the nirvana of "privacy".
-
-
-=======================================
-Next, Fight against the empty CALLERID!
-=======================================
-
-A considerable percentage of the calls you don't want, come from
-sites that do not provide CallerID.
-
-Null callerid's are a fact of life, and could be a friend with an
-unlisted number, or some charity looking for a handout. The
-PrivacyManager application can help here. It will ask the caller to
-enter a 10-digit phone number. They get 3 tries(configurable), and this is
-configurable, with control being passed to priority+101 if they won't
-supply one.
-
-PrivacyManager can't guarantee that the number they supply is any
-good, tho, as there is no way to find out, short of hanging up and
-calling them back. But some answers are obviously wrong. For instance,
-it seems a common practice for telemarketers to use your own number
-instead of giving you theirs. A simple test can detect this. More
-advanced tests would be to look for -555- numbers, numbers that count
-up or down, numbers of all the same digit, etc.
-
-My logs show that 39 have hung up in the PrivacyManager script over
-the last year.
-
-(Note: Demanding all unlisted incoming callers to enter their CID may
-not always be appropriate for all users. Another option might be to
-use call screening. See below.)
-
-==========================
-Next, use a WELCOME MENU !
-==========================
-
-Experience has shown that simply presenting incoming callers with
-a set of options, no matter how simple, will deter them from calling
-you. In the vast majority of situations, a telemarketer will simply
-hang up rather than make a choice and press a key.
-
-This will also immediately foil all autodialers that simply belch a
-message in your ear and hang up.
-
-
-----------------------------------------------
-Example usage of Zapateller and PrivacyManager:
-----------------------------------------------
-
-[homeline]
-exten => s,1,Answer
-exten => s,2,SetVar,repeatcount=0
-exten => s,3,Zapateller,nocallerid
-exten => s,4,PrivacyManager
-exten => s,105,Background(tt-allbusy) ;; do this if they don't enter a number to Privacy Manager
-exten => s,106,Background(tt-somethingwrong)
-exten => s,107,Background(tt-monkeysintro)
-exten => s,108,Background(tt-monkeys)
-exten => s,109,Background(tt-weasels)
-exten => s,110,Hangup
-exten => s,5,GotoIf($[ "${CALLERIDNUM}" = "7773334444" & "${CALLERIDNAME}" : "Privacy Manager" ]?callerid-liar|s|1:s|7)
-
-I suggest using Zapateller at the beginning of the context, before
-anything else, on incoming calls.This can be followed by the
-PrivacyManager App.
-
-Make sure, if you do the PrivacyManager app, that you take care of the
-error condition! or their non-compliance will be rewarded with access
-to the system. In the above, if they can't enter a 10-digit number in
-3 tries, they get the humorous "I'm sorry, but all household members
-are currently helping other telemarketers...", "something is terribly
-wrong", "monkeys have carried them away...", various loud monkey
-screechings, "weasels have...", and a hangup. There are plenty of
-other paths to my torture scripts, I wanted to have some fun.
-
-In nearly all cases now, the telemarketers/charity-seekers that
-usually get thru to my main intro, hang up. I guess they can see it's
-pointless, or the average telemarketer/charity-seeker is instructed
-not to enter options when encountering such systems. Don't know.
-
-===================
-Next: Torture Them!
-===================
-
-I have developed an elaborate script to torture Telemarketers, and
-entertain friends. (See
-http://www.voip-info.org/wiki-Asterisk+Telemarketer+Torture )
-
-While mostly those that call in and traverse my teletorture scripts
-are those we know, and are doing so out of curiosity, there have been
-these others from Jan 1st,2004 thru June 1st, 2004:
-(the numbers may or may not be correct.)
-
-603890zzzz hung up telemarket options.
-"Integrated Sale" called a couple times. hung up in telemarket options
-"UNITED STATES GOV" (-- maybe a military recruiter, trying to lure one of my sons).
-800349zzzz -- hung up in charity intro
-800349zzzz -- hung up in charity choices, intro, about the only one who actually travelled to the bitter bottom of the scripts!
-216377zzzz -- hung up the magazine section
-626757zzzz = "LIR " (pronounced "Liar"?) hung up in telemarket intro, then choices
-757821zzzz -- hung up in new magazine subscription options.
-
-That averages out to maybe 1 a month. That puts into question whether
-the ratio of the amount of labor it took to make the scripts versus
-the benefits of lower call volumes was worth it, but, well, I had fun,
-so what the heck.
-
-but, that's about it. Not a whole lot. But I haven't had to say "NO"
-or "GO AWAY" to any of these folks for about a year now ...!
-
-========================================
- Using Call Screening
-=======================================
-
-Another option is to use call screening in the Dial command. It has
-two main privacy modes, one that remembers the CID of the caller, and
-how the callee wants the call handled, and the other, which does not
-have a "memory".
-
-Turning on these modes in the dial command results in this sequence of
-events, when someone calls you at an extension:
-
-1. The caller calls the Asterisk system, and at some point, selects an
-option or enters an extension number that would dial your extension.
-
-2. Before ringing your extension, the caller is asked to supply an
-introduction. The application asks them: "After the tone, say your
-name". They are allowed 4 seconds of introduction.
-
-3. After that, they are told "Hang on, we will attempt to connect you
-to your party. Depending on your dial options, they will hear ringing
-indications, or get music on hold. I suggest music on hold.
-
-4. Your extension is then dialed. When (and if) you pick up, you are
-told that a caller presenting themselves as <their recorded intro is
-played> is calling, and you have options, like being connected,
-sending them to voicemail, torture, etc.
-
-5. You make your selection, and the call is handled as you chose.
-
-
-There are some variations, and these will be explained in due course.
-
-
-To use these options, set your Dial to something like:
-
-exten => 3,3,Dial(Zap/5r3&Zap/6r3|35|tmPA(beep))
-
-or
-
-exten => 3,3,Dial(Zap/5r3&Zap/6r3|35|tmP(something)A(beep))
-
-or
-
-exten => 3,3,Dial(Zap/5r3&Zap/6r3|35|tmpA(beep))
-
-
-The 't' allows the dialed party to transfer the call using '#'. It's
-optional.
-
-The 'm' is for music on hold. I suggest it. Otherwise, the calling
-party gets to hear all the ringing, and lack thereof. It is generally
-better to use Music On Hold. Lots of folks hang up after the 3rd or
-4th ring, and you might lose the call before you can enter an option!
-
-The 'P' option alone will database everything using the extension as a
-default 'tree'. To get multiple extensions sharing the same database, use
-P(some-shared-key). Also, if the same person has multiple extensions,
-use P(unique-id) on all their dial commands.
-
-Use little 'p' for screening. Every incoming call will include a
-prompt for the callee's choice.
-
-the A(beep), will generate a 'beep' that the callee will hear if they
-choose to talk to the caller. It's kind of a prompt to let the callee
-know that he has to say 'hi'. It's not required, but I find it
-helpful.
-
-When there is no CallerID, P and p options will always record an intro
-for the incoming caller. This intro will be stored temporarily in the
-/var/lib/asterisk/sounds/priv-callerintros dir, under the name
-NOCALLERID_<extension><channelname> and will be erased after the
-callee decides what to do with the call.
-
-Of course, NOCALLERID is not stored in the database. All those with no
-CALLERID will be considered "Unknown".
-
-========================
- The 'N' and 'n' options
-========================
-
-Two other options exist, that act as modifiers to the privacy options
-'P' and 'p'. They are 'N' and 'n'. You can enter them as dialing
-options, but they only affect things if P or p are also in the
-options.
-
-'N' says, "Only screen the call if no CallerID is present". So, if a
-callerID were supplied, it will come straight thru to your extension.
-
-'n' says, "Don't save any introductions". Folks will be asked to
-supply an introduction ("At the tone, say your name") every time they
-call. Their introductions will be removed after the callee makes a
-choice on how to handle the call. Whether the P option or the p option
-is used, the incoming caller will have to supply their intro every
-time they call.
-
-=======================
-Recorded Introductions
-=======================
-
-[Philosophical Side Note:
-The 'P' option stores the CALLERID in the database, along with the
-callee's choice of actions, as a convenience to the CALLEE, whereas
-introductions are stored and re-used for the convenience of the CALLER.]
-
-Unless instructed to not save introductions (see the 'n' option above),
-the screening modes will save the recordings of the caller's names in
-the directory /var/lib/asterisk/sounds/priv-callerintros, if they have
-a CallerID. Just the 10-digit callerid numbers are used as filenames,
-with a ".gsm" at the end.
-
-Having these recordings around can be very useful, however...
-
-First of all, if a callerid is supplied, and a recorded intro for that
-number is already present, the caller is spared the inconvenience of
-having to supply their name, which shortens their call a bit.
-
-Next of all, these intros can be used in voicemail, played over
-loudspeakers, and perhaps other nifty things. For instance:
-
-exten => s,7,System(/usr/bin/play /var/lib/asterisk/sounds/priv-callerintros/${CALLERIDNUM}.gsm&|0)
-
-When a call comes in at the house, the above priority gets executed,
-and the callers intro is played over the phone systems speakers. This
-gives us a hint who is calling.
-
-(Note: the |0 option at the end of the System command above, is a
-local mod I made to the System command. It forces a 0 result code to
-be returned, whether the play command successfully completed or
-not. Therefore, I don't have to ensure that the file exists or
-not. While I've turned this mod into the developers, it hasn't been
-incorporated yet. You might want to write an AGI or shell script to
-handle it a little more intelligently)
-
-And one other thing. You can easily supply your callers with an option
-to listen to, and re-record their introductions. Here's what I did in
-the home system's extensions.conf. (assume that a
-Goto(home-introduction|s|1) exists somewhere in your main menu as an
-option):
-
-[home-introduction]
-exten => s,1,Background,intro-options ;; Script: To hear your Introduction, dial 1.
- ;; to record a new introduction, dial 2.
- ;; to return to the main menu, dial 3.
- ;; to hear what this is all about, dial 4.
-exten => 1,1,Playback,priv-callerintros/${CALLERIDNUM}
-exten => 1,2,Goto(s,1)
-exten => 2,1,Goto(home-introduction-record,s,1)
-exten => 3,1,Goto(homeline,s,7)
-exten => 4,1,Playback,intro-intro ;; Script:
- ;; This may seem a little strange, but it really is a neat
- ;; thing, both for you and for us. I've taped a short introduction
- ;; for many of the folks who normally call us. Using the Caller ID
- ;; from each incoming call, the system plays the introduction
- ;; for that phone number over a speaker, just as the call comes in.
- ;; This helps the folks
- ;; here in the house more quickly determine who is calling.
- ;; and gets the right ones to gravitate to the phone.
- ;; You can listen to, and record a new intro for your phone number
- ;; using this menu.
-exten => 4,2,Goto(s,1)
-exten => t,1,Goto(s,1)
-exten => i,1,Background,invalid
-exten => i,2,Goto(s,1)
-exten => o,1,Goto(s,1)
-
-[home-introduction-record]
-exten => s,1,Background,intro-record-choices ;; Script:
- ;; If you want some advice about recording your
- ;; introduction, dial 1.
- ;; otherwise, dial 2, and introduce yourself after
- ;; the beep.
-exten => 1,1,Playback,intro-record
- ;; Your introduction should be short and sweet and crisp.
- ;; Your introduction will be limited to 4 seconds.
- ;; This is NOT meant to be a voice mail message, so
- ;; please, don't say anything about why you are calling.
- ;; After we are done making the recording, your introduction
- ;; will be saved for playback.
- ;; If you are the only person that would call from this number,
- ;; please state your name. Otherwise, state your business
- ;; or residence name instead. For instance, if you are
- ;; friend of the family, say, Olie McPherson, and both
- ;; you and your kids might call here a lot, you might
- ;; say: "This is the distinguished Olie McPherson Residence!"
- ;; If you are the only person calling, you might say this:
- ;; "This is the illustrious Kermit McFrog! Pick up the Phone, someone!!"
- ;; If you are calling from a business, you might pronounce a more sedate introduction,like,
- ;; "Fritz from McDonalds calling.", or perhaps the more original introduction:
- ;; "John, from the Park County Morgue. You stab 'em, we slab 'em!".
- ;; Just one caution: the kids will hear what you record every time
- ;; you call. So watch your language!
- ;; I will begin recording after the tone.
- ;; When you are done, hit the # key. Gather your thoughts and get
- ;; ready. Remember, the # key will end the recording, and play back
- ;; your intro. Good Luck, and Thank you!"
-exten => 1,2,Goto(2,1)
-exten => 2,1,Background,intro-start
- ;; OK, here we go! After the beep, please give your introduction.
-exten => 2,2,Background,beep
-exten => 2,3,Record,priv-callerintros/${CALLERIDNUM}:gsm|4
-exten => 2,4,Background,priv-callerintros/${CALLERIDNUM}
-exten => 2,5,Goto(home-introduction,s,1)
-exten => t,1,Goto(s,1)
-exten => i,1,Background,invalid
-exten => i,2,Goto(s,1)
-exten => o,1,Goto(s,1)
-
-
-In the above, you'd most likely reword the messages to your liking,
-and maybe do more advanced things with the 'error' conditions (i,o,t priorities),
-but I hope it conveys the idea...
-
-
diff --git a/1.4/doc/queuelog.txt b/1.4/doc/queuelog.txt
deleted file mode 100644
index fa8cb48e8..000000000
--- a/1.4/doc/queuelog.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-Queue Log Information
-=====================
-
-In order to properly manage ACD queues, it is important to be able to
-keep track of details of call setups and teardowns in much greater detail
-than traditional call detail records provide. In order to support this,
-extensive and detailed tracing of every queued call is stored in the
-queue log, located (by default) in /var/log/asterisk/queue_log.
-
-These are the events (and associated information) in the queue log:
-
-ABANDON(position|origposition|waittime)
-The caller abandoned their position in the queue. The position is the
-caller's position in the queue when they hungup, the origposition is
-the original position the caller was when they first entered the
-queue, and the waittime is how long the call had been waiting in the
-queue at the time of disconnect.
-
-AGENTDUMP
-The agent dumped the caller while listening to the queue announcement.
-
-AGENTLOGIN(channel)
-The agent logged in. The channel is recorded.
-
-AGENTCALLBACKLOGIN(exten@context)
-The callback agent logged in. The login extension and context is recorded.
-
-AGENTLOGOFF(channel|logintime)
-The agent logged off. The channel is recorded, along with the total time
-the agent was logged in.
-
-AGENTCALLBACKLOGOFF(exten@context|logintime|reason)
-The callback agent logged off. The last login extension and context is
-recorded, along with the total time the agent was logged in, and the
-reason for the logoff if it was not a normal logoff
-(e.g., Autologoff, Chanunavail)
-
-COMPLETEAGENT(holdtime|calltime|origposition)
-The caller was connected to an agent, and the call was terminated normally
-by the *agent*. The caller's hold time and the length of the call are both
-recorded. The caller's original position in the queue is recorded in
-origposition.
-
-COMPLETECALLER(holdtime|calltime|origposition)
-The caller was connected to an agent, and the call was terminated normally
-by the *caller*. The caller's hold time and the length of the call are both
-recorded. The caller's original position in the queue is recorded in
-origposition.
-
-CONFIGRELOAD
-The configuration has been reloaded (e.g. with asterisk -rx reload)
-
-CONNECT(holdtime|bridgedchanneluniqueid)
-The caller was connected to an agent. Hold time represents the amount
-of time the caller was on hold. The bridged channel unique ID contains
-the unique ID of the queue member channel that is taking the call. This
-is useful when trying to link recording filenames to a particular
-call in the queue.
-
-ENTERQUEUE(url|callerid)
-A call has entered the queue. URL (if specified) and Caller*ID are placed
-in the log.
-
-EXITEMPTY(position|origposition|waittime)
-The caller was exited from the queue forcefully because the queue had no
-reachable members and it's configured to do that to callers when there
-are no reachable members. The position is the caller's position in the
-queue when they hungup, the origposition is the original position the
-caller was when they first entered the queue, and the waittime is how
-long the call had been waiting in the queue at the time of disconnect.
-
-EXITWITHKEY(key|position)
-The caller elected to use a menu key to exit the queue. The key and
-the caller's position in the queue are recorded.
-
-EXITWITHTIMEOUT(position)
-The caller was on hold too long and the timeout expired.
-
-QUEUESTART
-The queueing system has been started for the first time this session.
-
-RINGNOANSWER(ringtime)
-After trying for ringtime ms to connect to the available queue member,
-the attempt ended without the member picking up the call. Bad queue
-member!
-
-SYSCOMPAT
-A call was answered by an agent, but the call was dropped because the
-channels were not compatible.
-
-TRANSFER(extension|context|holdtime|calltime)
-Caller was transferred to a different extension. Context and extension
-are recorded. The caller's hold time and the length of the call are both
-recorded. PLEASE remember that transfers performed by SIP UA's by way
-of a reinvite may not always be caught by Asterisk and trigger off this
-event. The only way to be 100% sure that you will get this event when
-a transfer is performed by a queue member is to use the built-in transfer
-functionality of Asterisk.
-
diff --git a/1.4/doc/queues-with-callback-members.txt b/1.4/doc/queues-with-callback-members.txt
deleted file mode 100644
index c58c30a28..000000000
--- a/1.4/doc/queues-with-callback-members.txt
+++ /dev/null
@@ -1,521 +0,0 @@
-
-Setting up Call Queues -- A Tutorial
-
-Pardon, but the dialplan in this tutorial will be expressed
-in AEL, the new Asterisk Extension Language. If you are
-not used to its syntax, we hope you will find it to some
-degree intuitive. If not, there are documents explaining
-its syntax and constructs.
-
-
-====== Configuring Call Queues
-
-First of all, set up call queues in queue.conf
-
-Here is an example:
-
- =========== queues.conf ===========
- | ; Cool Digium Queues |
- | [general] |
- | persistentmembers = yes |
- | |
- | ; General sales queue |
- | [sales-general] |
- | music=default |
- | context=sales |
- | strategy=ringall |
- | joinempty=strict |
- | leavewhenempty=strict |
- | |
- | ; Customer service queue |
- | [customerservice] |
- | music=default |
- | context=customerservice |
- | strategy=ringall |
- | joinempty=strict |
- | leavewhenempty=strict |
- | |
- | ; Support dispatch queue |
- | [support-dispatch] |
- | music=default |
- | context=dispatch |
- | strategy=ringall |
- | joinempty=strict |
- | leavewhenempty=strict |
- ===================================
-
-In the above, we have defined 3 separate calling queues:
-sales-general, customerservice, and support-dispatch.
-
-Please note that the sales-general queue specifies a
-context of "sales", and that customerservice specifies the
-context of "customerservice", and the support-dispatch
-queue specifies the context "dispatch". These three
-contexts must be defined somewhere in your dialplan.
-We will show them after the main menu below.
-
-<verbage explaining options above>
-In the [general] section, specifying the persistentmembers=yes,
-will cause the agent lists to be stored in astdb, and
-recalled on startup.
-
-The strategy=ringall will cause all agents to be dialed
-together, the first to answer is then assigned the incoming
-call.
-
-"joinempty" set to "strict" will keep incoming callers from
-being placed in queues where there are no agents to take calls.
-The Queue() application will return, and the dial plan can
-determine what to do next.
-
-If there are calls queued, and the last agent logs out, the
-remaining incoming callers will immediately be removed from
-the queue, and the Queue() call will return, IF the "leavewhenempty" is
-set to "strict".
-
-
-=====================================
-| Routing incoming Calls to Queues |
-=====================================
-
-
-Then in extensions.ael, you can do these things:
-
-================ The Main Menu
-
-At Digium, incoming callers are sent to the "mainmenu" context, where they
-are greeted, and directed to the numbers they choose...
-
-context mainmenu {
-
- includes {
- digium;
- queues-loginout;
- }
-
- 0 => goto dispatch|s|1;
- 2 => goto sales|s|1;
- 3 => goto customerservice|s|1;
- 4 => goto dispatch|s|1;
-
- s => {
- Ringing();
- Wait(1);
- Set(attempts=0);
- Answer();
- Wait(1);
- Background(digium/ThankYouForCallingDigium);
- Background(digium/YourOpenSourceTelecommunicationsSupplier);
- WaitExten(0.3);
- repeat:
- Set(attempts=$[${attempts} + 1]);
- Background(digium/IfYouKnowYourPartysExtensionYouMayDialItAtAnyTime);
- WaitExten(0.1);
- Background(digium/Otherwise);
- WaitExten(0.1);
- Background(digium/ForSalesPleasePress2);
- WaitExten(0.2);
- Background(digium/ForCustomerServicePleasePress3);
- WaitExten(0.2);
- Background(digium/ForAllOtherDepartmentsPleasePress4);
- WaitExten(0.2);
- Background(digium/ToSpeakWithAnOperatorPleasePress0AtAnyTime);
- if( ${attempts} < 2 ) {
- WaitExten(0.3);
- Background(digium/ToHearTheseOptionsRepeatedPleaseHold);
- }
- WaitExten(5);
- if( ${attempts} < 2 ) goto repeat;
- Background(digium/YouHaveMadeNoSelection);
- Background(digium/ThisCallWillBeEnded);
- Background(goodbye);
- Hangup();
- }
-}
-
-
-============= The Contexts referenced from the queues.conf file
-
-
-
-context sales {
-
- 0 => goto dispatch|s|1;
- 8 => Voicemail(${SALESVM});
-
- s => {
- Ringing();
- Wait(2);
- Background(digium/ThankYouForContactingTheDigiumSalesDepartment);
- WaitExten(0.3);
- Background(digium/PleaseHoldAndYourCallWillBeAnsweredByOurNextAvailableSalesRepresentative);
- WaitExten(0.3);
- Background(digium/AtAnyTimeYouMayPress0ToSpeakWithAnOperatorOr8ToLeaveAMessage);
- Set(CALLERID(name)=Sales);
- Queue(sales-general|t);
- Set(CALLERID(name)=EmptySalQ);
- goto dispatch|s|1;
- Playback(goodbye);
- Hangup();
- }
-}
-
-Please note that there is only one attempt to queue a call in the sales queue. All sales agents that
-are logged in will be rung.
-
-
-context customerservice {
-
- 0 => {
- SetCIDName(CSVTrans);
- goto dispatch|s|1;
- }
- 8 => Voicemail(${CUSTSERVVM});
-
- s => {
- Ringing();
- Wait(2);
- Background(digium/ThankYouForCallingDigiumCustomerService);
- WaitExten(0.3);
- notracking:
- Background(digium/PleaseWaitForTheNextAvailableCustomerServiceRepresentative);
- WaitExten(0.3);
- Background(digium/AtAnyTimeYouMayPress0ToSpeakWithAnOperatorOr8ToLeaveAMessage);
- Set(CALLERID(name)=Cust Svc);
- Set(QUEUE_MAX_PENALTY=10);
- Queue(customerservice|t);
- Set(QUEUE_MAX_PENALTY=0);
- Queue(customerservice|t);
- Set(CALLERID(name)=EmptyCSVQ);
- goto dispatch|s|1;
- Background(digium/NoCustomerServiceRepresentativesAreAvailableAtThisTime);
- Background(digium/PleaseLeaveAMessageInTheCustomerServiceVoiceMailBox);
- Voicemail(${CUSTSERVVM});
- Playback(goodbye);
- Hangup();
- }
-}
-
-Note that calls coming into customerservice will first be try to queue
-calls to those agents with a QUEUE_MAX_PENALTY of 10, and if none are available,
-then all agents are rung.
-
-
-context dispatch
-{
-
- s => {
- Ringing();
- Wait(2);
- Background(digium/ThankYouForCallingDigium);
- WaitExten(0.3);
- Background(digium/YourCallWillBeAnsweredByOurNextAvailableOperator);
- Background(digium/PleaseHold);
- Set(QUEUE_MAX_PENALTY=10);
- Queue(dispatch|t);
- Set(QUEUE_MAX_PENALTY=20);
- Queue(dispatch|t);
- Set(QUEUE_MAX_PENALTY=0);
- Queue(dispatch|t);
- Background(digium/NoOneIsAvailableToTakeYourCall);
- Background(digium/PleaseLeaveAMessageInOurGeneralVoiceMailBox);
- Voicemail(${DISPATCHVM});
- Playback(goodbye);
- Hangup();
- }
-}
-
-And in the dispatch context, first agents of priority 10 are tried, then
-20, and if none are available, all agents are tried.
-
-Notice that a common pattern is followed in each of the three queue contexts:
-
-First, you set QUEUE_MAX_PENALTY to a value, then you call
-Queue(<queue-name>,option,... (see the documentation for the Queue application));
-
-In the above, note that the "t" option is specified, and this allows the
-agent picking up the incoming call the luxury of transferring the call to
-other parties.
-
-The purpose of specifying the QUEUE_MAX_PENALTY is to develop a set of priorities
-amongst agents. By the above usage, agents with lower number priorities will
-be given the calls first, and then, if no-one picks up the call, the QUEUE_MAX_PENALTY
-will be incremented, and the queue tried again. Hopefully, along the line, someone
-will pick up the call, and the Queue application will end with a hangup.
-
-The final attempt to queue in most of our examples sets the QUEUE_MAX_PENALTY
-to zero, which means to try all available agents.
-
-
-=========================================
-| Assigning agents to Queues |
-=========================================
-
-In this example dialplan, we want to be able to add and remove agents to
-handle incoming calls, as they feel they are available. As they log in,
-they are added to the queue's agent list, and as they log out, they are
-removed. If no agents are available, the queue command will terminate, and
-it is the duty of the dialplan to do something appropriate, be it sending
-the incoming caller to voicemail, or trying the queue again with a higher
-QUEUE_MAX_PENALTY.
-
-Because a single agent can make themselves available to more than one queue,
-the process of joining multiple queues can be handled automatically by the
-dialplan.
-
-
-================= Agents Log In and Out
-
-
-context queues-loginout
-{
- 6092 => {
- Answer();
- Read(AGENT_NUMBER,agent-enternum);
- VMAuthenticate(${AGENT_NUMBER}@default,s);
- Set(queue-announce-success=1);
- goto queues-manip,I${AGENT_NUMBER},1;
- }
-
- 6093 => {
- Answer();
- Read(AGENT_NUMBER,agent-enternum);
- Set(queue-announce-success=1);
- goto queues-manip,O${AGENT_NUMBER},1;
- }
-}
-
-
-In the above contexts, the agents dial 6092 to log into their queues,
-and they dial 6093 to log out of their queues. The agent is prompted
-for their agent number, and if they are logging in, their passcode,
-and then they are transferred to the proper extension in the
-queues-manip context. The queues-manip context does all the
-actual work:
-
-
-context queues-manip {
-
- // Raquel Squelch
- _[IO]6121 => {
- &queue-addremove(dispatch,10);
- &queue-success();
- }
-
- // Brittanica Spears
- _[IO]6165 => {
- &queue-addremove(dispatch,20);
- &queue-success();
- }
-
- // Rock Hudson
- _[IO]6170 => {
- &queue-addremove(sales-general,10);
- &queue-addremove(customerservice,20);
- &queue-addremove(dispatch,30);
- &queue-success();
- }
-
- // Saline Dye-on
- _[IO]6070 => {
- &queue-addremove(sales-general,20);
- &queue-addremove(customerservice,30);
- &queue-addremove(dispatch,30);
- &queue-success();
- }
-}
-
-In the above extensions, note that the queue-addremove macro is used
-to actually add or remove the agent from the applicable queue,
-with the applicable priority level. Note that agents with a
-priority level of 10 will be called before agents with levels
-of 20 or 30.
-
-In the above example, Raquel will be dialed first in the dispatch
-queue, if she has logged in. If she is not, then the second call of
-Queue() with priority of 20 will dial Brittanica if she is present,
-otherwise the third call of Queue() with MAX_PENALTY of 0 will
-dial Rock and Saline simultaneously.
-
-Also note that Rock will be among the first to be called in the sales-general
-queue, and among the last in the dispatch queue. As you can see in
-main menu, the callerID is set in the main menu so they can tell
-which queue incoming calls are coming from.
-
-The call to queue-success() gives some feedback to the agent
-as they log in and out, that the process has completed.
-
-macro queue-success()
-{
- if( ${queue-announce-success} > 0 )
- {
- switch(${MACRO_EXTEN:0:1})
- {
- case I:
- Playback(agent-loginok);
- Hangup();
- break;
- case O:
- Playback(agent-loggedoff);
- Hangup();
- break;
- }
- }
-}
-
-
-The queue-addremove macro is defined in this manner:
-
-macro queue-addremove(queuename,penalty)
-{
- switch(${MACRO_EXTEN:0:1})
- {
- case I: // Login
- AddQueueMember(${queuename},Local/${MACRO_EXTEN:1}@agents,${penalty});
- break;
- case O: // Logout
- RemoveQueueMember(${queuename},Local/${MACRO_EXTEN:1}@agents);
- break;
- case P: // Pause
- PauseQueueMember(${queuename},Local/${MACRO_EXTEN:1}@agents);
- break;
- case U: // Unpause
- UnpauseQueueMember(${queuename},Local/${MACRO_EXTEN:1}@agents);
- break;
- default: // Invalid
- Playback(invalid);
- break;
- }
-}
-
-Basically, it uses the first character of the MACRO_EXTEN variable, to determine the
-proper actions to take. In the above dial plan code, only the cases I or O are used,
-which correspond to the Login and Logout actions.
-
-
-=======================================================
-| Controlling The Way Queues Call the Agents |
-=======================================================
-
-Notice in the above, that the commands to manipulate agents in queues have
-"@agents" in their arguments. This is a reference to the agents context:
-
-context agents
-{
- // General sales queue
- 8010 =>
- {
- Set(QUEUE_MAX_PENALTY=10);
- Queue(sales-general|t);
- Set(QUEUE_MAX_PENALTY=0);
- Queue(sales-general|t);
- Set(CALLERID(name)=EmptySalQ);
- goto dispatch|s|1;
- }
- // Customer Service queue
- 8011 =>
- {
- Set(QUEUE_MAX_PENALTY=10);
- Queue(customerservice|t);
- Set(QUEUE_MAX_PENALTY=0);
- Queue(customerservice|t);
- Set(CALLERID(name)=EMptyCSVQ);
- goto dispatch|s|1;
- }
- 8013 =>
- {
- Dial(iax2/sweatshop/9456@from-ecstacy);
-
- Set(CALLERID(name)=EmptySupQ);
- Set(QUEUE_MAX_PENALTY=10);
- Queue(support-dispatch,t);
- Set(QUEUE_MAX_PENALTY=20);
- Queue(support-dispatch,t);
- Set(QUEUE_MAX_PENALTY=0); // means no max
- Queue(support-dispatch,t);
- goto dispatch|s|1;
- }
- 6121 => &callagent(${RAQUEL});
- 6165 => &callagent(${SPEARS});
- 6170 => &callagent(${ROCK});
- 6070 => &callagent(${SALINE});
-}
-
-In the above, the variables ${RAQUEL}, etc stand for
-actual devices to ring that person's
-phone (like Zap/37).
-
-The 8010, 8011, and 8013 extensions are purely for transferring
-incoming callers to queues. For instance, a customer service
-agent might want to transfer the caller to talk to sales. The
-agent only has to transfer to extension 8010, in this case.
-
-Here is the callagent macro, note that if a person in the
-queue is called, but does not answer, then they are automatically
-removed from the queue.
-
-macro callagent(device)
-{
- if( ${GROUP_COUNT(${MACRO_EXTEN}@agents)}=0 )
- {
- Set(OUTBOUND_GROUP=${MACRO_EXTEN}@agents);
- Dial(${device}|300|t);
- switch(${DIALSTATUS})
- {
- case BUSY:
- Busy();
- break;
- case NOANSWER:
- Set(queue-announce-success=0);
- goto queues-manip|O${MACRO_EXTEN}|1;
- default:
- Hangup();
- break;
- }
- }
- else
- {
- Busy();
- }
-}
-
-In the callagent macro above, the ${MACRO_EXTEN} will
-be 6121, or 6165, etc, which is the extension of the agent.
-
-The use of the GROUP_COUNT, and OUTBOUND_GROUP follow this line
-of thinking. Incoming calls can be queued to ring all agents in the
-current priority. If some of those agents are already talking, they
-would get bothersome call-waiting tones. To avoid this inconvenience,
-when an agent gets a call, the OUTBOUND_GROUP assigns that
-conversation to the group specified, for instance 6171@agents.
-The ${GROUP_COUNT()} variable on a subsequent call should return
-"1" for that group. If GROUP_COUNT returns 1, then the busy()
-is returned without actually trying to dial the agent.
-
-================ Pre Acknowledgement Message
-
-If you would like to have a pre acknowledge message with option to reject the message
-you can use the following dialplan Macro as a base with the 'M' dial argument.
-
-[macro-screen]
-exten=>s,1,Wait(.25)
-exten=>s,2,Read(ACCEPT|screen-callee-options|1)
-exten=>s,3,Gotoif($[${ACCEPT} = 1] ?50)
-exten=>s,4,Gotoif($[${ACCEPT} = 2] ?30)
-exten=>s,5,Gotoif($[${ACCEPT} = 3] ?40)
-exten=>s,6,Gotoif($[${ACCEPT} = 4] ?30:30)
-exten=>s,30,Set(MACRO_RESULT=CONTINUE)
-exten=>s,40,Read(TEXTEN|custom/screen-exten|)
-exten=>s,41,Gotoif($[${LEN(${TEXTEN})} = 3]?42:45)
-exten=>s,42,Set(MACRO_RESULT=GOTO:from-internal^${TEXTEN}^1)
-exten=>s,45,Gotoif($[${TEXTEN} = 0] ?46:4)
-exten=>s,46,Set(MACRO_RESULT=CONTINUE)
-exten=>s,50,Playback(after-the-tone)
-exten=>s,51,Playback(connected)
-exten=>s,52,Playback(beep)
-
-================ Caveats
-
-In the above examples, some of the possible error checking has been omitted,
-to reduce clutter and make the examples clearer.
-
diff --git a/1.4/doc/radius.txt b/1.4/doc/radius.txt
deleted file mode 100644
index 041f072ac..000000000
--- a/1.4/doc/radius.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-Call Detail Recording to RADIUS Server
-======================================
-
-
-Configuration of Asterisk to send CDRs to (Free)RADIUS servers.
-
-
-A. What is needed :
- * FreeRADIUS server
- * Radiusclient-ng library
- * Asterisk PBX
-
-
- +--------------------+
- | Asterisk PBX |
- | |
- |********************|
- | | +---------------+
- | RADIUS client |------->| RADIUS server |
- | |<-------| (FreeRADIUS) |
- +--------------------+ +---------------+
-
-
-
-
-B. Steps to follow in order to have RADIUS support:
-
- 1.Radiusclient library
- 1.a Installation
-
- Download the sources from:
-
- http://developer.berlios.de/projects/radiusclient-ng/
-
- Untar the source tarball.
- root@localhost:/usr/local/src# tar xvfz radiusclient-ng-0.5.2.tar.gz
-
- Compile and install the library.
- root@localhost:/usr/local/src# cd radiusclient-ng-0.5.2
- root@localhost:/usr/local/src/radiusclient-ng-0.5.2# ./configure
- root@localhost:/usr/local/src/radiusclient-ng-0.5.2# make
- root@localhost:/usr/local/src/radiusclient-ng-0.5.2# make install
-
- 1.b Configuration
-
- By default all the configuration files of the radiusclient library will
- be in /usr/local/etc/radiusclient-ng directory.
-
- File "radiusclient.conf"
- Open the file and find lines containing the following:
-
- authserver localhost
-
- This is the hostname or IP address of the RADIUS server used for
- authentication. You will have to change this unless the server is
- running on the same host as your Asterisk PBX.
-
- acctserver localhost
-
- This is the hostname or IP address of the RADIUS server used for
- accounting. You will have to change this unless the server is running
- on the same host as your Asterisk PBX.
-
- File "servers"
-
- RADIUS protocol uses simple access control mechanism based on shared
- secrets that allows RADIUS servers to limit access from RADIUS clients.
-
- A RADIUS server is configured with a secret string and only RADIUS
- clients that have the same secret will be accepted.
-
- You need to configure a shared secret for each server you have
- configured in radiusclient.conf file in the previous step. The shared
- secrets are stored in /usr/local/etc/radiusclient-ng/servers file.
-
- Each line contains hostname of a RADIUS server and shared secret
- used in communication with that server. The two values are separated
- by white spaces. Configure shared secrets for every RADIUS server you
- are going to use.
-
- File "dictionary"
-
- Asterisk uses some attributes that are not included in the
- dictionary of radiusclient library, therefore it is necessary to add
- them. A file called dictionary.digium (kept in the contrib dir)
- was created to list all new attributes used by Asterisk.
- Add to the end of the main dictionary file
- /usr/local/etc/radiusclient-ng/dictionary
- the line:
-
- $INCLUDE /path/to/dictionary.digium
-
- 2.FreeRADIUS Server (Version 1.1.1)
- 2.a Installation
-
- Download sources tarball from:
-
- http://freeradius.org/
-
- Untar, configure, build, and install the server:
-
- root@localhost:/usr/local/src# tar xvfz freeradius-1.1.1.tar.gz
- root@localhost:/usr/local/src# cd freeradius-1.1.1
- root@localhost"/usr/local/src/freeradius-1.1.1# ./configure
- root@localhost"/usr/local/src/freeradius-1.1.1# make
- root@localhost"/usr/local/src/freeradius-1.1.1# make install
-
- All the configuration files of FreeRADIUS server will be in
- /usr/local/etc/raddb directory.
-
-
- 2.b Configuration
-
- There are several file that have to be modified to configure the
- RADIUS server. These are presented next.
-
- File "clients.conf"
-
- File /usr/local/etc/raddb/clients.conf contains description of
- RADIUS clients that are allowed to use the server. For each of the
- clients you need to specify its hostname or IP address and also a
- shared secret. The shared secret must be the same string you configured
- in radiusclient library.
-
- Example:
- client myhost {
- secret = mysecret
- shortname = foo
- }
-
- This fragment allows access from RADIUS clients on "myhost" if they use
- "mysecret" as the shared secret.
- The file already contains an entry for localhost (127.0.0.1), so if you
- are running the RADIUS server on the same host as your Asterisk server,
- then modify the existing entry instead, replacing the default password.
-
- File "dictionary"
-
- Note : as of version 1.1.2, the dictionary.digium file ships with FreeRADIUS.
- The following procedure brings the dictionary.digium file to previous versions
- of FreeRADIUS.
-
- File /usr/local/etc/raddb/dictionary contains the dictionary of
- FreeRADIUS server. You have to add the same dictionary file
- (dictionary.digium), which you added to the dictionary of radiusclient-ng
- library. You can include it into the main file, adding the following line at the
- end of file '/usr/local/etc/raddb/dictionary':
-
- $INCLUDE /path/to/dictionary.digium
-
- That will include the same new attribute definitions that are used
- in radiusclient-ng library so the client and server will understand each
- other.
-
-
- 3. Asterisk Accounting Configuration
-
- Compilation and installation:
- The module will be compiled as long as the radiusclient-ng
- library has been detected on your system.
-
- By default FreeRADIUS server will log all accounting requests into
- /usr/local/var/log/radius/radacct directory in form of plain text files.
- The server will create one file for each hostname in the directory. The
- following example shows how the log files look like.
-
- Asterisk now generates Call Detail Records. See /include/asterisk/cdr.h
- for all the fields which are recorded. By default, records in comma
- separated values will be created in /var/log/asterisk/cdr-csv.
-
- The configuration file for cdr_radius.so module is :
-
- /etc/asterisk/cdr.conf
- This is where you can set CDR related parameters as well as the path to
- the radiusclient-ng library configuration file.
-
-
- 4. Logged Values
-
- "Asterisk-Acc-Code", The account name of detail records
- "Asterisk-Src",
- "Asterisk-Dst",
- "Asterisk-Dst-Ctx", The destination context
- "Asterisk-Clid",
- "Asterisk-Chan", The channel
- "Asterisk-Dst-Chan", (if applicable)
- "Asterisk-Last-App", Last application run on the channel
- "Asterisk-Last-Data", Argument to the last channel
- "Asterisk-Start-Time",
- "Asterisk-Answer-Time",
- "Asterisk-End-Time",
- "Asterisk-Duration", Duration is the whole length that the entire
- call lasted. ie. call rx'd to hangup
- "end time" minus "start time"
- "Asterisk-Bill-Sec", The duration that a call was up after other
- end answered which will be <= to duration
- "end time" minus "answer time"
- "Asterisk-Disposition", ANSWERED, NO ANSWER, BUSY
- "Asterisk-AMA-Flags", DOCUMENTATION, BILL, IGNORE etc, specified on
- a per channel basis like accountcode.
- "Asterisk-Unique-ID", Unique call identifier
- "Asterisk-User-Field" User field set via SetCDRUserField
-
diff --git a/1.4/doc/realtime.txt b/1.4/doc/realtime.txt
deleted file mode 100644
index cc90e5f71..000000000
--- a/1.4/doc/realtime.txt
+++ /dev/null
@@ -1,138 +0,0 @@
-The Asterisk Realtime Architecture
-----------------------------------
-
-The Asterisk Realtime Architecture is a new set of drivers and
-functions implemented in Asterisk.
-
-The benefits of this architecture are many, both from a code management
-standpoint and from an installation perspective.
-
-Additional information on the configuration of Realtime with Asterisk
-can be found in doc/extconfig.txt
-
-The ARA is designed to be independent of storage. Currently, most
-drivers are based on SQL, but the architecture should be able to handle
-other storage methods in the future, like LDAP.
-
-The main benefit comes in the database support. In Asterisk v1.0 some
-functions supported MySQL database, some PostgreSQL and other ODBC.
-With the ARA, we have a unified database interface internally in Asterisk,
-so if one function supports database integration, all databases that has a
-realtime driver will be supported in that function.
-
-Currently there are three realtime database drivers:
-
-* ODBC: Support for UnixODBC, integrated into Asterisk
- The UnixODBC subsystem supports many different databases,
- please check www.unixodbc.org for more information.
-* MySQL: Found in the asterisk-addons subversion repository on svn.digium.com
-* PostgreSQL: Native support for Postgres, integrated into Asterisk
-
-* Two modes: Static and Realtime
---------------------------------
-The ARA realtime mode is used to dynamically load and update objects.
-This mode is used in the SIP and IAX2 channels, as well as in the voicemail
-system. For SIP and IAX2 this is similar to the v1.0 MYSQL_FRIENDS
-functionality. With the ARA, we now support many more databases for
-dynamic configuration of phones.
-
-The ARA static mode is used to load configuration files. For the Asterisk
-modules that read configurations, there's no difference between a static
-file in the file system, like extensions.conf, and a configuration loaded
-from a database.
-
-You just have to always make sure the var_metric values are properly set and
-ordered as you expect in your database server if you're using the static mode
-with ARA (either sequentially or with the same var_metric value for everybody).
-
-If you have an option that depends on another one in a given configuration
-file (i.e, 'musiconhold' depending on 'agent' from agents.conf) but their
-var_metric are not sequential you'll probably get default values being assigned for
-those options instead of the desired ones. You can still use the same
-var_metric for all entries in your DB, just make sure the entries
-are recorded in an order that does not break the option dependency.
-
-That doesn't happen when you use a static file in the file system. Although
-this might be interpreted as a bug or limitation, it is not.
-
-* Realtime SIP friends
-----------------------
-The SIP realtime objects are users and peers that are loaded in memory
-when needed, then deleted. This means that Asterisk currently can't handle
-voicemail notification and NAT keepalives for these peers. Other than that,
-most of the functionality works the same way for realtime friends as for
-the ones in static configuration.
-
-With caching, the device stays in memory for a specified time. More
-information about this is to be found in the sip.conf sample file.
-
-* Realtime H.323 friends
-------------------------
-Like SIP realtime friends, H.323 friends also can be configured using
-dynamic realtime objects.
-
-* New function in the dial plan: The Realtime Switch
-----------------------------------------------------
-The realtime switch is more than a port of functionality in v1.0 to the
-new architecture, this is a new feature of Asterisk based on the
-ARA. The realtime switch lets your Asterisk server do database lookups
-of extensions in realtime from your dial plan. You can have many Asterisk
-servers sharing a dynamically updated dial plan in real time with this
-solution.
-
-Note that this switch does _NOT_ support Caller ID matching, only
-extension name/pattern matching.
-
-* So what can you do?
----------------------
-The realtime Architecture lets you store all of your configuration in
-databases and reload it whenever you want. You can force a reload over
-the AMI, Asterisk Manager Interface or by calling Asterisk from a
-shell script with
- asterisk -rx "reload"
-
-You may also dynamically add SIP and IAX devices and extensions
-and making them available without a reload, by using the realtime
-objects and the realtime switch.
-
-
-* Configuration in extconfig.conf
----------------------------------
-You configure the ARA in extconfig.conf (yes, it's a strange name, but
-is was defined in the early days of the realtime architecture and kind
-of stuck). Please see doc/extconfig.txt for database schemas.
-
-The part of Asterisk that connects to the ARA use a well defined family
-name to find the proper database driver. The syntax is easy:
- <family> => <realtime driver>,<db name>[,<table>]
-
-The options following the realtime driver identified depends on the
-driver.
-
-Defined well-known family names are:
-
-* sippeers, sipusers SIP peers and users
-* iaxpeers, iaxusers IAX2 peers and users
-* voicemail Voicemail accounts
-* queues Queues
-* queue_members Queue members
-* extensions Realtime extensions (switch)
-
-There is documentation of the SQL database in the file
-doc/extconfig.txt in your Asterisk source code tree.
-
-For voicemail storage with the support of ODBC, there is a
-doc/odbcstorage.txt documentation file.
-
-
-* Limitations
--------------
-Currently, realtime extensions do not support realtime hints.
-
-
-* FreeTDS supported with connection pooling
--------------------------------------------
-In order to use a FreeTDS-based database with realtime, you need to turn
-connection pooling on in res_odbc.conf. This is due to a limitation within
-the FreeTDS protocol itself. Please note that this includes databases such
-as MS SQL Server and Sybase. This support is new in the current release.
diff --git a/1.4/doc/rtp-packetization.txt b/1.4/doc/rtp-packetization.txt
deleted file mode 100644
index 647375a98..000000000
--- a/1.4/doc/rtp-packetization.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-Overview
--------
-Asterisk currently supports configurable RTP packetization per codec for
-select RTP-based channels.
-
-Channels
--------
-These channel drivers allow RTP packetization on a user/peer/friend
-or global level:
- chan_sip
- chan_skinny
- chan_h323
- chan_ooh323 (Asterisk-Addons)
-
-Configuration
--------
-To set a desired packetization interval on a specific codec,
-append that inteval to the allow= statement.
-
-Example:
-allow=ulaw:30,alaw,g729:60
-
-No packetization is specified in the case of alaw in this example,
-so the default of 20ms is used.
-
-Autoframing
--------
-In addition, chan_sip has the ability to negotiate the desired
-framing at call establishment.
-
-In sip.conf if autoframing=yes is set in the global section, then
-all calls will try to set the packetization based on the remote
-endpoint's preferences. This behaviour depends on the endpoints
-ability to present the desired packetization (ptime:) in the SDP.
-If the endpoint does not include a ptime attribute, the call will
-be established with 20ms packetization.
-
-Autoframing can be set at the global level or on a user/peer/friend
-basis. If it is enabled at the global level, it applies to all
-users/peers/friends regardless of their prefered codec packetization.
-
-Codec framing options
--------
-The following table lists the minimum and maximum values that are
-valid per codec, as well as the increment value used for each.
-Please note that the maximum values here are only recommended
-maximums, and should not exceed the RTP MTU.
-
-Name Min Max Default Increment
-g723 30 300 30 30
-gsm 20 300 20 20
-ulaw 10 150 20 10
-alaw 10 150 20 10
-g726 10 300 20 10
-ADPCM 10 300 20 10
-SLIN 10 70 20 10
-lpc10 20 20 20 20
-g729 10 230 20 10
-speex 10 60 20 10
-ilbc 30 30 30 30
-g726_aal2 10 300 20 10
-
-Invalid framing options are handled based on the following rules:
- 1. If the specified framing is less than the codec's minimum, then
- the minimum value is used.
- 2. If the specific framing is greater than the codec's maximum, then
- the maximum value is used
- 3. If the specificed framing does not meet the increment requirement,
- the specified framing is rounded down to the closest valid
- framing options.
- example allow=ulaw:33 will set the codec to 30ms framing
- 4. If no framing is specified in the allow= directive, then the
- codec default is used.
diff --git a/1.4/doc/security.txt b/1.4/doc/security.txt
deleted file mode 100644
index 3adf53624..000000000
--- a/1.4/doc/security.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-==== Security Notes with Asterisk ====
-
-PLEASE READ THE FOLLOWING IMPORTANT SECURITY RELATED INFORMATION.
-IMPROPER CONFIGURATION OF ASTERISK COULD ALLOW UNAUTHORIZED USE OF YOUR
-FACILITIES, POTENTIALLY INCURRING SUBSTANTIAL CHARGES.
-
-Asterisk security involves both network security (encryption, authentication)
-as well as dialplan security (authorization - who can access services in
-your pbx). If you are setting up Asterisk in production use, please make
-sure you understand the issues involved.
-
-* NETWORK SECURITY
-
-If you install Asterisk and use the "make samples" command to install
-a demonstration configuration, Asterisk will open a few ports for accepting
-VoIP calls. Check the channel configuration files for the ports and IP addresses.
-
-If you enable the manager interface in manager.conf, please make sure that
-you access manager in a safe environment or protect it with SSH or other
-VPN solutions.
-
-For all TCP/IP connections in Asterisk, you can set ACL lists that
-will permit or deny network access to Asterisk services. Please check
-the "permit" and "deny" configuration options in manager.conf and
-the VoIP channel configurations - i.e. sip.conf and iax.conf.
-
-The IAX2 protocol supports strong RSA key authentication as well as
-AES encryption of voice and signalling. The SIP channel does not
-support encryption in this version of Asterisk.
-
-By default, if you have libcap available, Asterisk will try to retain the
-CAP_NET_ADMIN capability when running as a non-root user. If you do not need
-that capability you may want to configure Asterisk with --without-cap; however,
-this will prevent Asterisk from being able to mark high ToS bits under Linux.
-More information on CAP_NET_ADMIN is available at:
-http://www.lids.org/lids-howto/node48.html
-
-* DIALPLAN SECURITY
-
-First and foremost remember this:
-
-USE THE EXTENSION CONTEXTS TO ISOLATE OUTGOING OR TOLL SERVICES FROM ANY
-INCOMING CONNECTIONS.
-
-You should consider that if any channel, incoming line, etc can enter an
-extension context that it has the capability of accessing any extension
-within that context.
-
-Therefore, you should NOT allow access to outgoing or toll services in
-contexts that are accessible (especially without a password) from incoming
-channels, be they IAX channels, FX or other trunks, or even untrusted
-stations within you network. In particular, never ever put outgoing toll
-services in the "default" context. To make things easier, you can include
-the "default" context within other private contexts by using:
-
- include => default
-
-in the appropriate section. A well designed PBX might look like this:
-
-[longdistance]
-exten => _91NXXNXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
-include => local
-
-[local]
-exten => _9NXXNXXX,1,Dial(Zap/g2/${EXTEN:1})
-include => default
-
-[default]
-exten => 6123,Dial(Zap/1)
-
-
-DON'T FORGET TO TAKE THE DEMO CONTEXT OUT OF YOUR DEFAULT CONTEXT. There
-isn't really a security reason, it just will keep people from wanting to
-play with your Asterisk setup remotely.
-
-* LOG SECURITY
-
-Please note that the Asterisk log files, as well as information printed to the
-Asterisk CLI, may contain sensitive information such as passwords and call
-history. Keep this in mind when providing access to these resources.
diff --git a/1.4/doc/sla.pdf b/1.4/doc/sla.pdf
deleted file mode 100644
index c9f927ee8..000000000
--- a/1.4/doc/sla.pdf
+++ /dev/null
Binary files differ
diff --git a/1.4/doc/sla.tex b/1.4/doc/sla.tex
deleted file mode 100644
index c1159ce43..000000000
--- a/1.4/doc/sla.tex
+++ /dev/null
@@ -1,378 +0,0 @@
-\documentclass[12pt,a4]{article}
-\usepackage{hyperref}
-
-\author{Russell Bryant \\ Software Engineer \\ Digium, Inc.}
-\title{Shared Line Appearances}
-
-\begin{document}
-\maketitle
-
-\tableofcontents
-
-\section{Introduction}
-
-The "SLA" functionality in Asterisk is intended to allow a setup that emulates
-a simple key system. It uses the various abstraction layers already built into
-Asterisk to emulate key system functionality across various devices, including
-IP channels.
-
-\section{Configuration}
-
-\subsection{Summary}
-
-An SLA system is built up of virtual trunks and stations mapped to real
-Asterisk devices. The configuration for all of this is done in three
-different files: extensions.conf, sla.conf, and the channel specific
-configuration file such as sip.conf or zapata.conf.
-
-\subsection{Dialplan}
-
-The SLA implementation can automatically generate the dialplan necessary for
-basic operation if the "autocontext" option is set for trunks and stations in
-sla.conf. However, for reference, here is an automatically generated dialplan
-to help with custom building of the dialplan to include other features, such as
-voicemail (\ref{voicemail}).
-
-However, note that there is a little bit of additional configuration needed if
-the trunk is an IP channel. This is discussed in the section on trunks (\ref{trunks}).
-
-There are extensions for incoming calls on a specific trunk, which execute the SLATrunk
-application, as well as incoming calls from a station, which execute SLAStation.
-Note that there are multiple extensions for incoming calls from a station. This is
-because the SLA system has to know whether the phone just went off hook, or if the
-user pressed a specific line button.
-
-Also note that there is a hint for every line on every station. This lets the SLA
-system control each individual light on every phone to ensure that it shows the
-correct state of the line. The phones must subscribe to the state of each of their
-line appearances.
-
-Please refer to the examples section for full dialplan samples for SLA.
-
-\subsection{Trunks}
-\label{trunks}
-
-An SLA trunk is a mapping between a virtual trunk and a real Asterisk device.
-This device may be an analog FXO line, or something like a SIP trunk. A trunk
-must be configured in two places. First, configure the device itself in the
-channel specific configuration file such as zapata.conf or sip.conf. Once the
-trunk is configured, then map it to an SLA trunk in sla.conf.
-
-\begin{verbatim}
-[line1]
-type=trunk
-device=Zap/1
-\end{verbatim}
-
-Be sure to configure the trunk's context to be the same one that is set for the
-"autocontext" option in sla.conf if automatic dialplan configuration is used.
-This would be done in the regular device entry in zapata.conf, sip.conf, etc.
-Note that the automatic dialplan generation creates the SLATrunk() extension
-at extension 's'. This is perfect for Zap channels that are FXO trunks, for
-example. However, it may not be good enough for an IP trunk, since the call
-coming in over the trunk may specify an actual number.
-
-If the dialplan is being built manually, ensure that calls coming in on a trunk
-execute the SLATrunk() application with an argument of the trunk name, as shown
-in the dialplan example before.
-
-IP trunks can be used, but they require some additional configuration to work.
-
-For this example, let's say we have a SIP trunk called "mytrunk" that is going
-to be used as line4. Furthermore, when calls come in on this trunk, they are
-going to say that they are calling the number "12564286000". Also, let's say
-that the numbers that are valid for calling out this trunk are NANP numbers,
-of the form \_1NXXNXXXXXX.
-
-In sip.conf, there would be an entry for [mytrunk]. For [mytrunk],
-set context=line4.
-
-
-\begin{verbatim}
-[line4]
-type=trunk
-device=Local/disa@line4_outbound
-\end{verbatim}
-
-
-\begin{verbatim}
-[line4]
-exten => 12564286000,1,SLATrunk(line4)
-
-[line4_outbound]
-exten => disa,1,Disa(no-password|line4_outbound)
-exten => _1NXXNXXXXXX,1,Dial(SIP/\${EXTEN}@mytrunk)
-\end{verbatim}
-
-
-So, when a station picks up their phone and connects to line 4, they are
-connected to the local dialplan. The Disa application plays dialtone to the
-phone and collects digits until it matches an extension. In this case, once
-the phone dials a number like 12565551212, the call will proceed out the
-SIP trunk.
-
-\subsection{Stations}
-
-An SLA station is a mapping between a virtual station and a real Asterisk device.
-Currently, the only channel driver that has all of the features necessary to
-support an SLA environment is chan\_sip. So, to configure a SIP phone to use
-as a station, you must configure sla.conf and sip.conf.
-
-\begin{verbatim}
-[station1]
-type=station
-device=SIP/station1
-trunk=line1
-trunk=line2
-\end{verbatim}
-
-Here are some hints on configuring a SIP phone for use with SLA:
-
-\begin{enumerate}
-\item Add the SIP channel as a [station] in sla.conf.
-
-\item Configure the phone in sip.conf. If automatic dialplan configuration was
- used by enabling the "autocontext" option in sla.conf, then this entry in
- sip.conf should have the same context setting.
-
-\item On the phone itself, there are various things that must be configured to
- make everything work correctly:
-
- Let's say this phone is called "station1" in sla.conf, and it uses trunks
- named "line1" and line2".
- \begin{enumerate}
-
- \item Two line buttons must be configured to subscribe to the state of the
- following extensions:
- - station1\_line1
- - station1\_line2
-
- \item The line appearance buttons should be configured to dial the extensions
- that they are subscribed to when they are pressed.
-
- \item If you would like the phone to automatically connect to a trunk when it
- is taken off hook, then the phone should be automatically configured to
- dial "station1" when it is taken off hook.
-
- \end{enumerate}
-\end{enumerate}
-
-
-\section{Configuration Examples}
-\subsection{Basic SLA}
-
-This is an example of the most basic SLA setup. It uses the automatic
-dialplan generation so the configuration is minimal.
-
-sla.conf:
-\begin{verbatim}
-[line1]
-type=trunk
-device=Zap/1
-autocontext=line1
-
-[line2]
-type=trunk
-device=Zap/2
-autocontext=line2
-
-[station](!)
-type=station
-trunk=line1
-trunk=line2
-autocontext=sla_stations
-
-[station1](station)
-device=SIP/station1
-
-[station2](station)
-device=SIP/station2
-
-[station3](station)
-device=SIP/station3
-
-\end{verbatim}
-
-With this configuration, the dialplan is generated automatically. The first
-zap channel should have its context set to "line1" and the second should be
-set to "line2" in zapata.conf. In sip.conf, station1, station2, and station3
-should all have their context set to "sla\_stations".
-
-For reference, here is the automatically generated dialplan for this situation:
-\begin{verbatim}
-[line1]
-exten => s,1,SLATrunk(line1)
-
-[line2]
-exten => s,2,SLATrunk(line2)
-
-[sla_stations]
-exten => station1,1,SLAStation(station1)
-exten => station1_line1,hint,SLA:station1_line1
-exten => station1_line1,1,SLAStation(station1_line1)
-exten => station1_line2,hint,SLA:station1_line2
-exten => station1_line2,1,SLAStation(station1_line2)
-
-exten => station2,1,SLAStation(station2)
-exten => station2_line1,hint,SLA:station2_line1
-exten => station2_line1,1,SLAStation(station2_line1)
-exten => station2_line2,hint,SLA:station2_line2
-exten => station2_line2,1,SLAStation(station2_line2)
-
-exten => station3,1,SLAStation(station3)
-exten => station3_line1,hint,SLA:station3_line1
-exten => station3_line1,1,SLAStation(station3_line1)
-exten => station3_line2,hint,SLA:station3_line2
-exten => station3_line2,1,SLAStation(station3_line2)
-\end{verbatim}
-
-
-\subsection{SLA and Voicemail}
-\label{voicemail}
-
-This is an example of how you could set up a single voicemail box for the
-phone system. The voicemail box number used in this example is 1234, which
-would be configured in voicemail.conf.
-
-For this example, assume that there are 2 trunks and 3 stations. The trunks
-are Zap/1 and Zap/2. The stations are SIP/station1, SIP/station2, and
-SIP/station3.
-
-In zapata.conf, channel 1 has context=line1 and channel 2 has context=line2.
-
-In sip.conf, all three stations are configured with context=sla\_stations.
-
-When the stations pick up their phones to dial, they are allowed to dial
-NANP numbers for outbound calls, or 8500 for checking voicemail.
-
-
-sla.conf:
-\begin{verbatim}
-[line1]
-type=trunk
-device=Local/disa@line1_outbound
-
-[line2]
-type=trunk
-device=Local/disa@line2_outbound
-
-[station](!)
-type=station
-trunk=line1
-trunk=line2
-
-[station1](station)
-device=SIP/station1
-
-[station2](station)
-device=SIP/station2
-
-[station3](station)
-device=SIP/station3
-
-\end{verbatim}
-
-
-extensions.conf:
-\begin{verbatim}
-[macro-slaline]
-exten => s,1,SLATrunk(${ARG1})
-exten => s,n,Goto(s-${SLATRUNK_STATUS}|1)
-exten => s-FAILURE,1,Voicemail(1234|u)
-exten => s-UNANSWERED,1,Voicemail(1234|u)
-
-[line1]
-exten => s,1,Macro(slaline|line1)
-
-[line2]
-exten => s,2,Macro(slaline|line2)
-
-[line1_outbound]
-exten => disa,1,Disa(no-password|line1_outbound)
-exten => _1NXXNXXXXXX,1,Dial(Zap/1/${EXTEN})
-exten => 8500,1,VoicemailMain(1234)
-
-[line2_outbound]
-exten => disa,1,Disa(no-password|line2_outbound)
-exten => _1NXXNXXXXXX,1,Dial(Zap/2/${EXTEN})
-exten => 8500,1,VoicemailMain(1234)
-
-[sla_stations]
-
-exten => station1,1,SLAStation(station1)
-exten => station1_line1,hint,SLA:station1_line1
-exten => station1_line1,1,SLAStation(station1_line1)
-exten => station1_line2,hint,SLA:station1_line2
-exten => station1_line2,1,SLAStation(station1_line2)
-
-exten => station2,1,SLAStation(station2)
-exten => station2_line1,hint,SLA:station2_line1
-exten => station2_line1,1,SLAStation(station2_line1)
-exten => station2_line2,hint,SLA:station2_line2
-exten => station2_line2,1,SLAStation(station2_line2)
-
-exten => station3,1,SLAStation(station3)
-exten => station3_line1,hint,SLA:station3_line1
-exten => station3_line1,1,SLAStation(station3_line1)
-exten => station3_line2,hint,SLA:station3_line2
-exten => station3_line2,1,SLAStation(station3_line2)
-
-\end{verbatim}
-
-\section{Call Handling}
-\subsection{Summary}
-
-This section is intended to describe how Asterisk handles calls inside of the
-SLA system so that it is clear what behavior is expected.
-
-\subsection{Station goes off hook (not ringing)}
-
-When a station goes off hook, it should initiate a call to Asterisk with the
-extension that indicates that the phone went off hook without specifying a
-specific line. In the examples in this document, for the station named
-"station1", this extension is simply named, "station1".
-
-Asterisk will attempt to connect this station to the first available trunk
-that is not in use. Asterisk will check the trunks in the order that they
-were specified in the station entry in sla.conf. If all trunks are in use,
-the call will be denied.
-
-If Asterisk is able to acquire an idle trunk for this station, then trunk
-is connected to the station and the station will hear dialtone. The station
-can then proceed to dial a number to call. As soon as a trunk is acquired,
-all appearances of this line on stations will show that the line is in use.
-
-\subsection{Station goes off hook (ringing)}
-
-When a station goes off hook while it is ringing, it should simply answer
-the call that had been initiated to it to make it ring. Once the station
-has answered, Asterisk will figure out which trunk to connect it to. It
-will connect it to the highest priority trunk that is currently ringing.
-Trunk priority is determined by the order that the trunks are listed in
-the station entry in sla.conf.
-
-\subsection{Line button on a station is pressed}
-
-When a line button is pressed on a station, the station should initiate a
-call to Asterisk with the extension that indicates which line button was
-pressed. In the examples given in this document, for a station named
-"station1" and a trunk named "line1", the extension would be "station1\_line1".
-
-If the specified trunk is not in use, then the station will be connected to it and
-will hear dialtone. All appearances of this trunk will then show that it
-is now in use.
-
-If the specified trunk is on hold by this station, then this station will be
-reconnected to the trunk. The line appearance for this trunk on this station
-will now show in use. If this was the only station that had the call on hold,
-then all appearances of this trunk will now show that it is in use. Otherwise,
-all stations that are not currently connected to this trunk will show it
-on hold.
-
-If the specified trunk is on hold by a different station, then this station
-will be connected to the trunk only if the trunk itself and the station(s) that
-have it on hold do not have private hold enabled. If connected, the appeareance
-of this trunk on this station will then show in use. All stations that are not
-currently connected to this trunk will show it on hold.
-
-\end{document}
diff --git a/1.4/doc/smdi.txt b/1.4/doc/smdi.txt
deleted file mode 100644
index a4aa6bbd6..000000000
--- a/1.4/doc/smdi.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Asterisk SMDI (Simple Message Desk Interface) integration
----------------------------------------------------------
-
-SMDI integration is configured in smdi.conf, zaptel.conf, and voicemail.conf.
-Various characteristics of the SMDI interfaces to be used (serial ports) are
-defined in smdi.conf. SMDI integration for callerid and MWI are defined in
-zaptel.conf and voicemail.conf respectively. SMDI only works with Zaptel
-interfaces configured for FXS signalling.
-
-When SMDI is enabled and a call comes into Asterisk, the forwarding station
-number is used as the destination for the call and any callerid information
-present is used. This way you can configure your extensions.conf as follows to
-behave as a message desk.
-
-[default]
-
-exten => _XXXXXXX,1,VoiceMail(${EXTEN}|${SMDI_VM_TYPE})
-exten => _XXXXXXX,n,Hangup
-
-exten => s,1,VoiceMailMain(${CALLERID(num)})
-exten => s,n,Hangup
-
-The ${SMDI_VM_TYPE} variable will be set to u, b, or nothing depending on the
-contents of the type of SMDI message received.
-
diff --git a/1.4/doc/sms.txt b/1.4/doc/sms.txt
deleted file mode 100644
index fe0ec8d85..000000000
--- a/1.4/doc/sms.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-* The SMS application
----------------------
-SMS() is an application to handles calls to/from text message capable phones and
-message centres using ETSI ES 201 912 protocol 1 FSK messaging over analog calls.
-
-Basically it allows sending and receiving of text messages over the PSTN. It is
-compatible with BT Text service in the UK and works on ISDN and PSTN lines. It is
-designed to connect to an ISDN or zap interface directly and uses FSK so would
-probably not work over any sort of compressed link (like a VoIP call using GSM codec).
-
-Typical applications include:-
-
-1. Connection to a message centre to send text messages - probably initiated via the
- manager interface or "outgoing" directory
-2. Connection to an POTS line with an SMS capable phone to send messages - probably
- initiated via the manager interface or "outgoing" directory
-3. Acceptance of calls from the message centre (based on CLI) and storage of
- received messages
-4. Acceptance of calls from a POTS line with an SMS capable phone and storage of
- received messages
-
-* Arguments to sms():
-
-- First argument is queue name
-- Second is options:
- a: SMS() is to act as the answering side, and so send the initial FSK frame
- s: SMS() is to act as a service centre side rather than as terminal equipment
-
-- If a third argument is specified, then SMS does not handle the call at all,
- but takes the third argument as a destination number to send an SMS to
-- The forth argument onward is a message to be queued to the number in the
- third argument. All this does is create the file in the me-sc directory.
- If 's' is set then the number is the source
- address and the message placed in the sc-me directory.
-
-All text messages are stored in /var/spool/asterisk/sms
-A log is recorded in /var/log/asterisk/sms
-
-There are two subdirectories called sc-me.<queuename> holding all
-messages from service centre to phone, and me-sc.<queuename> holding all
-messages from phone to service centre.
-
-In each directory are messages in files, one per file, using any filename not
-starting with a dot.
-
-When connected as a service centre, SMS(s) will send all messages waiting in
-the sc-me-<queuename> directory, deleting the files as it goes. Any
-received in this mode are placed in the me-sc-<queuename> directory.
-
-When connected as a client, SMS() will send all messages waiting in the
-me-sc-<queuename> directory, deleting the files as it goes. Any received in
-this mode are placed in the sc-me-<queuename> directory.
-
-Message files created by SMS() use a time stamp/reference based filename.
-
-The format of the sms file is lines that have the form of key=value
-Keys are :
-
-oa Originating Address
- Telephone number, national number if just digits
- Telephone number starting with + then digits for international
- Ignored on sending messages to service centre (CLI used)
-da Destination Address
- Telephone number, national number if just digits
- Telephone number starting with + then digits for international
-scts Service Centre Time Stamp
- In the format YYYY-MM-DD HH:MM:SS
-pid Protocol Identifier (decimal octet value)
-dcs Data coding scheme (decimal octet value)
-mr Message reference (decimal octet value)
-ud The message (see escaping below)
-srr 0/1 Status Report Request
-rp 0/1 Return Path
-vp mins validity period
-
-Omitted fields have default values.
-
-Note that there is special format for ud, ud# instead of ud= which is followed
-by raw hex (2 characters per octet). This is used in output where characters
-other than 10,13,32-126,128-255 are included in the data. In this case a comment (line
-starting ;) is added showing the printable characters
-
-When generating files to send to a service centre, only da and ud need be
-specified. oa is ignored.
-
-When generating files to send to a phone, only oa and ud need be specified. da is ignored.
-
-When receiving a message as a service centre, only the destination address is
-sent, so the originating address is set to the callerid.
-
-EXAMPLES
-
-The following are examples of use within the UK using BT Text SMS/landline
-service.
-
-This is a context to use with a manager script.
-
-[smsdial]
-; create and send a text message, expects number+message and
-; connect to 17094009
-exten => _X.,1,SMS(${CALLERIDNUM},,${EXTEN},${CALLERIDNAME})
-exten => _X.,n,SMS(${CALLERIDNUM})
-exten => _X.,n,Hangup
-
-The script sends
-
- action: originate
- callerid: message <from>
- exten: to
- channel: Local/17094009
- context: smsdial
- priority: 1
-
-You put the message as the name of the caller ID (messy, I know), the
-originating number and hence queue name as the number of the caller ID and the
-exten as the number to which the sms is to be sent. The context uses SMS to
-create the message in the queue and then SMS to communicate with 17094009 to
-actually send the message.
-
-Note that the 9 on the end of 17094009 is the sub address 9 meaning no sub
-address (BT specific). If a different digit is used then that is the sub
-address for the sending message source address (appended to the outgoing CLI
-by BT).
-
-For incoming calls you can use a context like this :-
-
-[incoming]
-exten => _XXXXXX/_8005875290,1,SMS(${EXTEN:3},a)
-exten => _XXXXXX/_8005875290,n,System(/usr/lib/asterisk/smsin ${EXTEN:3})
-exten => _XXXXXX/_80058752[0-8]0,1,SMS(${EXTEN:3}${CALLERIDNUM:8:1},a)
-exten => _XXXXXX/_80058752[0-8]0,n,System(/usr/lib/asterisk/smsin ${EXTEN>:3}${CALLERIDNUM:8:1})
-exten => _XXXXXX/_80058752[0-8]0,n,Hangup
-
-
-In this case the called number we get from BT is 6 digits (XXXXXX) and we are
-using the last 3 digits as the queue name.
-
-Priority 1 causes the SMS to be received and processed for the incoming call.
-It is from 080058752X0. The two versions handle the queue name as 3 digits (no
-sub address) or 4 digits (with sub address). In both cases, after the call a
-script (smsin) is run - this is optional, but is useful to actually processed
-the received queued SMS. In our case we email them based on the target number.
-Priority 3 hangs up.
-
-If using the CAPI drivers they send the right CLI and so the _800... would be
-_0800...
-
diff --git a/1.4/doc/snmp.txt b/1.4/doc/snmp.txt
deleted file mode 100644
index f1667ee15..000000000
--- a/1.4/doc/snmp.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Asterisk SNMP Support
----------------------
-
-Rudimentary support for SNMP access to Asterisk is available. To build
-this, one needs to have Net-SNMP development headers and libraries on
-the build system, including any libraries Net-SNMP depends on.
-
-Note that on some (many?) Linux-distributions the dependency list in
-the net-snmp-devel list is not complete, and additional RPMs will need
-to be installed. This is typically seen as attempts to build res_snmp
-as net-snmp-devel is available, but then fails to find certain
-libraries. The packages may include the following:
- * bzip2-devel
- * lm_sensors-devel
- * newt-devel
-
-SNMP support comes in two varieties -- as a sub-agent to a running SNMP
-daemon using the AgentX protocol, or as a full standalone agent. If
-you wish to run a full standalone agent, Asterisk must run as root in
-order to bind to port 161.
-
-Configuring access when running as a full agent is something that is
-left as an exercise to the reader.
-
-To enable access to the Asterisk SNMP subagent from a master SNMP
-daemon, one will need to enable AgentX support, and also make sure that
-Asterisk will be able to access the Unix domain socket. One way of
-doing this is to add the following to /etc/snmp/snmpd.conf:
-
- # Enable AgentX support
- master agentx
-
- # Set permissions on AgentX socket and containing
- # directory such that process in group 'asterisk'
- # will be able to connect
- agentXPerms 0660 0550 nobody asterisk
-
-This assumes that you run Asterisk under group 'asterisk' (and does
-not care what user you run as).
diff --git a/1.4/doc/speechrec.txt b/1.4/doc/speechrec.txt
deleted file mode 100644
index 1e5bf6f49..000000000
--- a/1.4/doc/speechrec.txt
+++ /dev/null
@@ -1,295 +0,0 @@
-The Asterisk Speech Recognition API
-===================================
-
-The generic speech recognition engine is implemented in the res_speech.so module.
-This module connects through the API to speech recognition software, that is
-not included in the module.
-
-To use the API, you must load the res_speech.so module before any connectors.
-For your convenience, there is a preload line commented out in the modules.conf
-sample file.
-
-* Dialplan Applications:
-------------------------
-
-The dialplan API is based around a single speech utilities application file,
-which exports many applications to be used for speech recognition. These include an
-application to prepare for speech recognition, activate a grammar, and play back a
-sound file while waiting for the person to speak. Using a combination of these applications
-you can easily make a dialplan use speech recognition without worrying about what
-speech recognition engine is being used.
-
-- SpeechCreate(Engine Name):
-
-This application creates information to be used by all the other applications.
-It must be called before doing any speech recognition activities such as activating a
-grammar. It takes the engine name to use as the argument, if not specified the default
-engine will be used.
-
-If an error occurs are you are not able to create an object, the variable ERROR will be
-set to 1. You can then exit your speech recognition specific context and play back an
-error message, or resort to a DTMF based IVR.
-
-- SpeechLoadGrammar(Grammar Name|Path):
-
-Loads grammar locally on a channel. Note that the grammar is only available as long as the
-channel exists, and you must call SpeechUnloadGrammar before all is done or you may cause a
-memory leak. First argument is the grammar name that it will be loaded as and second
-argument is the path to the grammar.
-
-- SpeechUnloadGrammar(Grammar Name):
-
-Unloads a locally loaded grammar and frees any memory used by it. The only argument is the
-name of the grammar to unload.
-
-- SpeechActivateGrammar(Grammar Name):
-
-This activates the specified grammar to be recognized by the engine. A grammar tells the
-speech recognition engine what to recognize, and how to portray it back to you in the
-dialplan. The grammar name is the only argument to this application.
-
-- SpeechStart():
-
-Tell the speech recognition engine that it should start trying to get results from audio
-being fed to it. This has no arguments.
-
-- SpeechBackground(Sound File|Timeout):
-
-This application plays a sound file and waits for the person to speak. Once they start
-speaking playback of the file stops, and silence is heard. Once they stop talking the
-processing sound is played to indicate the speech recognition engine is working. Note it is
-possible to have more then one result. The first argument is the sound file and the second is the
-timeout. Note the timeout will only start once the sound file has stopped playing.
-
-- SpeechDeactivateGrammar(Grammar Name):
-
-This deactivates the specified grammar so that it is no longer recognized. The
-only argument is the grammar name to deactivate.
-
-- SpeechProcessingSound(Sound File):
-
-This changes the processing sound that SpeechBackground plays back when the speech
-recognition engine is processing and working to get results. It takes the sound file as the
-only argument.
-
-- SpeechDestroy():
-
-This destroys the information used by all the other speech recognition applications.
-If you call this application but end up wanting to recognize more speech, you must call
-SpeechCreate again before calling any other application. It takes no arguments.
-
-* Getting Result Information:
------------------------------
-
-The speech recognition utilities module exports several dialplan functions that you can use to
-examine results.
-
-- ${SPEECH(status)}:
-
-Returns 1 if SpeechCreate has been called. This uses the same check that applications do to see if a
-speech object is setup. If it returns 0 then you know you can not use other speech applications.
-
-- ${SPEECH(spoke)}:
-
-Returns 1 if the speaker spoke something, or 0 if they were silent.
-
-- ${SPEECH(results)}:
-
-Returns the number of results that are available.
-
-- ${SPEECH_SCORE(result number)}:
-
-Returns the score of a result.
-
-- ${SPEECH_TEXT(result number)}:
-
-Returns the recognized text of a result.
-
-- ${SPEECH_GRAMMAR(result number)}:
-
-Returns the matched grammar of the result.
-
-- SPEECH_ENGINE(name)=value
-
-Sets a speech engine specific attribute.
-
-* Dialplan Flow:
------------------
-
-1. Create a speech recognition object using SpeechCreate()
-2. Activate your grammars using SpeechActivateGrammar(Grammar Name)
-3. Call SpeechStart() to indicate you are going to do speech recognition immediately
-4. Play back your audio and wait for recognition using SpeechBackground(Sound File|Timeout)
-5. Check the results and do things based on them
-6. Deactivate your grammars using SpeechDeactivateGrammar(Grammar Name)
-7. Destroy your speech recognition object using SpeechDestroy()
-
-* Dialplan Examples:
-
-This is pretty cheeky in that it does not confirmation of results. As well the way the
-grammar is written it returns the person's extension instead of their name so we can
-just do a Goto based on the result text.
-
-- Grammar: company-directory.gram
-
-#ABNF 1.0;
-language en-US;
-mode voice;
-tag-format <lumenvox/1.0>;
-root $company_directory;
-
-$josh = ((Joshua | Josh) [Colp]):"6066";
-$mark = (Mark [Spencer] | Markster):"4569";
-$kevin = (Kevin [Fleming]):"2567";
-
-$company_directory = ($josh | $mark | $kevin) { $ = $$ };
-
-- Dialplan logic
-
- [dial-by-name]
- exten => s,1,SpeechCreate()
- exten => s,2,SpeechActivateGrammar(company-directory)
- exten => s,3,SpeechStart()
- exten => s,4,SpeechBackground(who-would-you-like-to-dial)
- exten => s,5,SpeechDeactivateGrammar(company-directory)
- exten => s,6,Goto(internal-extensions-${SPEECH_TEXT(0)})
-
-- Useful Dialplan Tidbits:
-
-A simple macro that can be used for confirm of a result. Requires some sound files.
-ARG1 is equal to the file to play back after "I heard..." is played.
-
- [macro-speech-confirm]
- exten => s,1,SpeechActivateGrammar(yes_no)
- exten => s,2,Set(OLDTEXT0=${SPEECH_TEXT(0)})
- exten => s,3,Playback(heard)
- exten => s,4,Playback(${ARG1})
- exten => s,5,SpeechStart()
- exten => s,6,SpeechBackground(correct)
- exten => s,7,Set(CONFIRM=${SPEECH_TEXT(0)})
- exten => s,8,GotoIf($["${SPEECH_TEXT(0)}" = "1"]?9:10)
- exten => s,9,Set(CONFIRM=yes)
- exten => s,10,Set(CONFIRMED=${OLDTEXT0})
- exten => s,11,SpeechDeactivateGrammar(yes_no)
-
-* The Asterisk Speech Recognition C API
----------------------------------------
-
-The module res_speech.so exports a C based API that any developer can use to speech
-recognize enable their application. The API gives greater control, but requires the
-developer to do more on their end in comparison to the dialplan speech utilities.
-
-For all API calls that return an integer value, a non-zero value indicates an error has occurred.
-
-- Creating a speech structure:
-
- struct ast_speech *ast_speech_new(char *engine_name, int format)
-
- struct ast_speech *speech = ast_speech_new(NULL, AST_FORMAT_SLINEAR);
-
-This will create a new speech structure that will be returned to you. The speech recognition
-engine name is optional and if NULL the default one will be used. As well for now format should
-always be AST_FORMAT_SLINEAR.
-
-- Activating a grammar:
-
- int ast_speech_grammar_activate(struct ast_speech *speech, char *grammar_name)
-
- res = ast_speech_grammar_activate(speech, "yes_no");
-
-This activates the specified grammar on the speech structure passed to it.
-
-- Start recognizing audio:
-
- void ast_speech_start(struct ast_speech *speech)
-
- ast_speech_start(speech);
-
-This essentially tells the speech recognition engine that you will be feeding audio to it from
-then on. It MUST be called every time before you start feeding audio to the speech structure.
-
-- Send audio to be recognized:
-
- int ast_speech_write(struct ast_speech *speech, void *data, int len)
-
- res = ast_speech_write(speech, fr->data, fr->datalen);
-
-This writes audio to the speech structure that will then be recognized. It must be written
-signed linear only at this time. In the future other formats may be supported.
-
-- Checking for results:
-
-The way the generic speech recognition API is written is that the speech structure will
-undergo state changes to indicate progress of recognition. The states are outlined below:
-
- AST_SPEECH_STATE_NOT_READY - The speech structure is not ready to accept audio
- AST_SPEECH_STATE_READY - You may write audio to the speech structure
- AST_SPEECH_STATE_WAIT - No more audio should be written, and results will be available soon.
- AST_SPEECH_STATE_DONE - Results are available and the speech structure can only be used again by
- calling ast_speech_start
-
-It is up to you to monitor these states. Current state is available via a variable on the speech
-structure. (state)
-
-- Knowing when to stop playback:
-
-If you are playing back a sound file to the user and you want to know when to stop play back because the
-individual started talking use the following.
-
- ast_test_flag(speech, AST_SPEECH_QUIET) - This will return a positive value when the person has started talking.
-
-- Getting results:
-
- struct ast_speech_result *ast_speech_results_get(struct ast_speech *speech)
-
- struct ast_speech_result *results = ast_speech_results_get(speech);
-
-This will return a linked list of result structures. A result structure looks like the following:
-
- struct ast_speech_result {
- char *text; /*!< Recognized text */
- int score; /*!< Result score */
- char *grammar; /*!< Matched grammar */
- struct ast_speech_result *next; /*!< List information */
- };
-
-- Freeing a set of results:
-
- int ast_speech_results_free(struct ast_speech_result *result)
-
- res = ast_speech_results_free(results);
-
-This will free all results on a linked list. Results MAY NOT be used as the memory will have been freed.
-
-- Deactivating a grammar:
-
- int ast_speech_grammar_deactivate(struct ast_speech *speech, char *grammar_name)
-
- res = ast_speech_grammar_deactivate(speech, "yes_no");
-
-This deactivates the specified grammar on the speech structure.
-
-- Destroying a speech structure:
-
- int ast_speech_destroy(struct ast_speech *speech)
-
- res = ast_speech_destroy(speech);
-
-This will free all associated memory with the speech structure and destroy it with the speech recognition engine.
-
-- Loading a grammar on a speech structure:
-
- int ast_speech_grammar_load(struct ast_speech *speech, char *grammar_name, char *grammar)
-
- res = ast_speech_grammar_load(speech, "builtin:yes_no", "yes_no");
-
-- Unloading a grammar on a speech structure:
-
-If you load a grammar on a speech structure it is preferred that you unload it as well,
-or you may cause a memory leak. Don't say I didn't warn you.
-
- int ast_speech_grammar_unload(struct ast_speech *speech, char *grammar_name)
-
- res = ast_speech_grammar_unload(speech, "yes_no");
-
-This unloads the specified grammar from the speech structure.
diff --git a/1.4/doc/valgrind.txt b/1.4/doc/valgrind.txt
deleted file mode 100644
index 4b89eec9c..000000000
--- a/1.4/doc/valgrind.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-If you're having certain types of crashes, such as those associated with
-memory corruption, a bug marshal may ask you to run Asterisk under valgrind.
-You should follow these steps, to give the bug marshal the maximum amount
-of information about the crash.
-
-1. Run 'make menuselect' and in the Compiler Options, enable MALLOC_DEBUG
- and DONT_OPTIMIZE. A bug marshal may also ask you to enable additional
- compiler flags, such as DEBUG_THREADS, depending upon the nature of the
- issue.
-
-2. Rebuild and install Asterisk.
-
-3. Run Asterisk as follows:
- valgrind --log-file-exactly=valgrind.txt asterisk -vvvvcg 2>malloc_debug.txt
-
- UPDATE: The newest version of valgrind has eliminated the
- --log-file-exactly option. If you are running valgrind 3.3.0 or higher,
- just use the --log-file option, keeping in mind that Valgrind will append
- a trailing suffix onto valgrind.txt.
-
-4. Reproduce the issue. Following the manifestation of the issue (or when
- the process crashes), upload the two files, valgrind.txt and
- malloc_debug.txt to the issue tracker. If you are using the --log-file
- option, note that valgrind.txt will have a trailing suffix. That's fine,
- just upload that file.
-
diff --git a/1.4/doc/video.txt b/1.4/doc/video.txt
deleted file mode 100644
index d7bd282f9..000000000
--- a/1.4/doc/video.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-Asterisk and Video telephony
-----------------------------
-
-Asterisk supports video telephony in the core infrastructure. Internally, it's one audio stream
-and one video stream in the same call. Some channel drivers and applications has video support,
-but not all.
-
-Codecs and formats
-------------------
-Asterisk supports the following video codecs and file formats. There's no video
-transcoding so you have to make sure that both ends support the same video format.
-
- Codec Format
- ----- ----------
- H.263 read/write
- H.264 read/write
- H.261 - Passthrough only
-
-Note that the file produced by Asterisk video format drivers is in no generic
-video format. Gstreamer has support for producing these files and converting from
-various video files to Asterisk video+audio files.
-
-Note that H.264 is not enabled by default. You need to add that in the channel
-configuration file.
-
-Channel drivers
----------------
-SIP The SIP channel driver (chan_sip.so) has support for video
-IAX2 Supports video calls (over trunks too)
-Local Forwards video calls as a proxy channel
-Agent Forwards video calls as a proxy channel
-
-Applications
-------------
-This is not yet a complete list. These dialplan applications are known to handle video:
-
-voicemail Video voicemail storage (does not attach video to e-mail)
-record Records audio and video files (give audio format as argument)
-playback Plays a video while being instructed to play audio
-echo Echos audio and video back to the user
-
-There is a development group working on enhancing video support for Asterisk.
-If you want to participate, join the asterisk-video mailing list on http://lists.digium.com
-
----
-Updates to this file are more than welcome!
diff --git a/1.4/doc/voicemail_odbc_postgresql.txt b/1.4/doc/voicemail_odbc_postgresql.txt
deleted file mode 100644
index 622501365..000000000
--- a/1.4/doc/voicemail_odbc_postgresql.txt
+++ /dev/null
@@ -1,453 +0,0 @@
-GETTING ODBC STORAGE WITH POSTGRESQL WORKING WITH VOICEMAIL
-
-1) Install PostgreSQL, PostgreSQL-devel, unixODBC, and unixODBC-devel, and
-PostgreSQL-ODBC. Make sure PostgreSQL is running and listening on a TCP socket.
-
-2) Log into your server as root, and then type:
-
-[root@localhost ~]# su - postgres
-
-This will log you into the system as the "postgres" user, so that you can
-create a new role and database within the PostgreSQL database system. At the
-new prompt, type:
-
-$ createuser -s -D -R -l -P -e asterisk
-Enter password for new role:
-Enter it again:
-
-Obviously you should enter a password when prompted. This creates the
-database role (or user).
-
-Next we need to create the asterisk database. Type:
-
-$ createdb -O asterisk -e asterisk
-
-This creates the database and sets the owner of the database to the asterisk
-role.
-
-
-Next, make sure that
-you are using md5 authentication for the database user. The line in my
-/var/lib/pgsql/data/pg_hba.conf looks like:
-
-# "local" is for Unix domain socket connections only
-local asterisk asterisk md5
-local all all ident sameuser
-# IPv4 local connections:
-host all all 127.0.0.1/32 md5
-
-As soon as you're done editing that file, log out as the postgres user.
-
-3) Make sure you have the PostgreSQL odbc driver setup in /etc/odbcinst.ini.
-Mine looks like:
-
-[PostgreSQL]
-Description = ODBC for PostgreSQL
-Driver = /usr/lib/libodbcpsql.so
-Setup = /usr/lib/libodbcpsqlS.so
-FileUsage = 1
-
-You can confirm that unixODBC is seeing the driver by typing:
-
-[jsmith2@localhost tmp]$ odbcinst -q -d
-[PostgreSQL]
-
-
-4) Setup a DSN in /etc/odbc.ini, pointing at the PostgreSQL database and
-driver. Mine looks like:
-
-[testing]
-Description = ODBC Testing
-Driver = PostgreSQL
-Trace = No
-TraceFile = sql.log
-Database = asterisk
-Servername = 127.0.0.1
-UserName = asterisk
-Password = supersecret
-Port = 5432
-ReadOnly = No
-RowVersioning = No
-ShowSystemTables = No
-ShowOidColumn = No
-FakeOidIndex = No
-ConnSettings =
-
-You can confirm that unixODBC sees your DSN by typing:
-
-[jsmith2@localhost tmp]$ odbcinst -q -s
-[testing]
-
-
-5) Test your database connectivity through ODBC. If this doesn't work,
-something is wrong with your ODBC setup.
-
-[jsmith2@localhost tmp]$ echo "select 1" | isql -v testing
-+---------------------------------------+
-| Connected! |
-| |
-| sql-statement |
-| help [tablename] |
-| quit |
-| |
-+---------------------------------------+
-SQL> +------------+
-| ?column? |
-+------------+
-| 1 |
-+------------+
-SQLRowCount returns 1
-1 rows fetched
-
-If your ODBC connectivity to PostgreSQL isn't working, you'll see an error
-message instead, like this:
-
-[jsmith2@localhost tmp]$ echo "select 1" | isql -v testing
-[S1000][unixODBC]Could not connect to the server;
-Could not connect to remote socket.
-[ISQL]ERROR: Could not SQLConnect
-bash: echo: write error: Broken pipe
-
-6) Compile Asterisk with support for ODBC voicemail. Go to your Asterisk
-source directory and run `make menuselect`. Under "Voicemail Build Options",
-enable "ODBC_STORAGE".
-# See doc/README.odbcstorage for more information
-
-Recompile Asterisk and install the new version.
-
-
-7) Once you've recompiled and re-installed Asterisk, check to make sure
-res_odbc.so has been compiled.
-
-localhost*CLI> show modules like res_odbc.so
-Module Description Use Count
-res_odbc.so ODBC Resource 0
-1 modules loaded
-
-
-8) Now it's time to get Asterisk configured. First, we need to tell Asterisk
-about our ODBC setup. Open /etc/asterisk/res_odbc.conf and add the following:
-
-[postgres]
-enabled => yes
-dsn => testing
-pre-connect => yes
-
-9) At the Asterisk CLI, unload and then load the res_odbc.so module. (You
-could restart Asterisk as well, but this way makes it easier to tell what's
-happening.) Notice how it says it's connected to "postgres", which is our ODBC
-connection as defined in res_odbc.conf, which points to the "testing" DSN in
-ODBC.
-
-localhost*CLI> unload res_odbc.so
-Jan 2 21:19:36 WARNING[8130]: res_odbc.c:498 odbc_obj_disconnect: res_odbc: disconnected 0 from postgres [testing]
-Jan 2 21:19:36 NOTICE[8130]: res_odbc.c:589 unload_module: res_odbc unloaded.
-localhost*CLI> load res_odbc.so
- Loaded /usr/lib/asterisk/modules/res_odbc.so => (ODBC Resource)
- == Parsing '/etc/asterisk/res_odbc.conf': Found
-Jan 2 21:19:40 NOTICE[8130]: res_odbc.c:266 load_odbc_config: Adding ENV var: INFORMIXSERVER=my_special_database
-Jan 2 21:19:40 NOTICE[8130]: res_odbc.c:266 load_odbc_config: Adding ENV var: INFORMIXDIR=/opt/informix
-Jan 2 21:19:40 NOTICE[8130]: res_odbc.c:295 load_odbc_config: registered database handle 'postgres' dsn->[testing]
-Jan 2 21:19:40 NOTICE[8130]: res_odbc.c:555 odbc_obj_connect: Connecting postgres
-Jan 2 21:19:40 NOTICE[8130]: res_odbc.c:570 odbc_obj_connect: res_odbc: Connected to postgres [testing]
-Jan 2 21:19:40 NOTICE[8130]: res_odbc.c:600 load_module: res_odbc loaded.
-
-You can also check the status of your ODBC connection at any time from the
-Asterisk CLI:
-
-localhost*CLI> odbc show
-Name: postgres
-DSN: testing
-Connected: yes
-
-10) Now we can setup our voicemail table in PostgreSQL. Log into PostgreSQL and
-type (or copy and paste) the following:
-
---
--- First, let's create our large object type, called "lo"
---
-CREATE FUNCTION loin (cstring) RETURNS lo AS 'oidin' LANGUAGE internal IMMUTABLE STRICT;
-CREATE FUNCTION loout (lo) RETURNS cstring AS 'oidout' LANGUAGE internal IMMUTABLE STRICT;
-CREATE FUNCTION lorecv (internal) RETURNS lo AS 'oidrecv' LANGUAGE internal IMMUTABLE STRICT;
-CREATE FUNCTION losend (lo) RETURNS bytea AS 'oidrecv' LANGUAGE internal IMMUTABLE STRICT;
-
-CREATE TYPE lo ( INPUT = loin, OUTPUT = loout, RECEIVE = lorecv, SEND = losend, INTERNALLENGTH = 4, PASSEDBYVALUE );
-CREATE CAST (lo AS oid) WITHOUT FUNCTION AS IMPLICIT;
-CREATE CAST (oid AS lo) WITHOUT FUNCTION AS IMPLICIT;
-
---
--- If we're not already using plpgsql, then let's use it!
---
-CREATE TRUSTED LANGUAGE plpgsql;
-
---
--- Next, let's create a trigger to cleanup the large object table
--- whenever we update or delete a row from the voicemessages table
---
-
-CREATE FUNCTION vm_lo_cleanup() RETURNS "trigger"
- AS $$
- declare
- msgcount INTEGER;
- begin
- -- raise notice 'Starting lo_cleanup function for large object with oid %',old.recording;
- -- If it is an update action but the BLOB (lo) field was not changed, dont do anything
- if (TG_OP = 'UPDATE') then
- if ((old.recording = new.recording) or (old.recording is NULL)) then
- raise notice 'Not cleaning up the large object table, as recording has not changed';
- return new;
- end if;
- end if;
- if (old.recording IS NOT NULL) then
- SELECT INTO msgcount COUNT(*) AS COUNT FROM voicemessages WHERE recording = old.recording;
- if (msgcount > 0) then
- raise notice 'Not deleting record from the large object table, as object is still referenced';
- return new;
- else
- perform lo_unlink(old.recording);
- if found then
- raise notice 'Cleaning up the large object table';
- return new;
- else
- raise exception 'Failed to cleanup the large object table';
- return old;
- end if;
- end if;
- else
- raise notice 'No need to cleanup the large object table, no recording on old row';
- return new;
- end if;
- end$$
- LANGUAGE plpgsql;
-
---
--- Now, let's create our voicemessages table
--- This is what holds the voicemail from Asterisk
---
-
-CREATE TABLE voicemessages
-(
- uniqueid serial PRIMARY KEY,
- msgnum int4,
- dir varchar(80),
- context varchar(80),
- macrocontext varchar(80),
- callerid varchar(40),
- origtime varchar(40),
- duration varchar(20),
- mailboxuser varchar(80),
- mailboxcontext varchar(80),
- recording lo,
- label varchar(30),
- "read" bool DEFAULT false
-);
-
---
--- Let's not forget to make the voicemessages table use the trigger
---
-
-CREATE TRIGGER vm_cleanup AFTER DELETE OR UPDATE ON voicemessages FOR EACH ROW EXECUTE PROCEDURE vm_lo_cleanup();
-
-
-11) Just as a sanity check, make sure you check the voicemessages table via the
-isql utility.
-
-[jsmith2@localhost ODBC]$ echo "SELECT id, msgnum, dir, duration FROM voicemessages WHERE msgnum = 1" | isql testing
-+---------------------------------------+
-| Connected! |
-| |
-| sql-statement |
-| help [tablename] |
-| quit |
-| |
-+---------------------------------------+
-SQL> +------------+------------+---------------------------------------------------------------------------------+---------------------+
-| id | msgnum | dir | duration |
-+------------+------------+---------------------------------------------------------------------------------+---------------------+
-+------------+------------+---------------------------------------------------------------------------------+---------------------+
-SQLRowCount returns 0
-
-
-12) Now we can finally configure voicemail in Asterisk to use our database.
-Open /etc/asterisk/voicemail.conf, and look in the [general] section. I've
-changed the format to gsm (as I can't seem to get WAV or wav working), and
-specify both the odbc connection and database table to use.
-
-[general]
-; Default formats for writing Voicemail
-;format=g723sf|wav49|wav
-format=gsm
-odbcstorage=postgres
-odbctable=voicemessages
-
-You'll also want to create a new voicemail context called "odbctest" to do some
-testing, and create a sample mailbox inside that context. Add the following to
-the very bottom of voicemail.conf:
-
-[odbctest]
-101 => 5555,Example Mailbox
-
-
-13) Once you've updated voicemail.conf, let's make the changes take effect:
-
-localhost*CLI> unload app_voicemail.so
- == Unregistered application 'VoiceMail'
- == Unregistered application 'VoiceMailMain'
- == Unregistered application 'MailboxExists'
- == Unregistered application 'VMAuthenticate'
-localhost*CLI> load app_voicemail.so
- Loaded /usr/lib/asterisk/modules/app_voicemail.so => (Comedian Mail (Voicemail System))
- == Registered application 'VoiceMail'
- == Registered application 'VoiceMailMain'
- == Registered application 'MailboxExists'
- == Registered application 'VMAuthenticate'
- == Parsing '/etc/asterisk/voicemail.conf': Found
-
-You can check to make sure your new mailbox exists by typing:
-
-localhost*CLI> show voicemail users for odbctest
-Context Mbox User Zone NewMsg
-odbctest 101 Example Mailbox 0
-
-
-14) Now, let's add a new context called "odbc" to extensions.conf. We'll use
-these extensions to do some testing:
-
-[odbc]
-exten => 100,1,Voicemail(101@odbctest)
-exten => 200,1,VoicemailMain(101@odbctest)
-
-
-15) Next, we need to point a phone at the odbc context. In my case, I've got a
-SIP phone called "linksys" that is registering to Asterisk, so I'm setting its
-context to the [odbc] context we created in the previous step. The relevant
-section of my sip.conf file looks like:
-
-[linksys]
-type=friend
-secret=verysecret
-disallow=all
-allow=ulaw
-allow=gsm
-context=odbc
-host=dynamic
-qualify=yes
-
-I can check to see that my linksys phone is registered with Asterisk correctly:
-
-localhost*CLI> sip show peers like linksys
-Name/username Host Dyn Nat ACL Port Status
-linksys/linksys 192.168.0.103 D 5060 OK (9 ms)
-1 sip peers [1 online , 0 offline]
-
-
-16) At last, we're finally ready to leave a voicemail message and have it
-stored in our database! (Who'd have guessed it would be this much trouble?!?)
-Pick up the phone, dial extension 100, and leave yourself a voicemail message.
-In my case, this is what appeared on the Asterisk CLI:
-
-localhost*CLI>
- -- Executing VoiceMail("SIP/linksys-10228cac", "101@odbctest") in new stack
- -- Playing 'vm-intro' (language 'en')
- -- Playing 'beep' (language 'en')
- -- Recording the message
- -- x=0, open writing: /var/spool/asterisk/voicemail/odbctest/101/tmp/dlZunm format: gsm, 0x101f6534
- -- User ended message by pressing #
- -- Playing 'auth-thankyou' (language 'en')
- == Parsing '/var/spool/asterisk/voicemail/odbctest/101/INBOX/msg0000.txt': Found
-
-Now, we can check the database and make sure the record actually made it into
-PostgreSQL, from within the psql utility.
-
-[jsmith2@localhost ~]$ psql
-Password:
-Welcome to psql 8.1.4, the PostgreSQL interactive terminal.
-
-Type: \copyright for distribution terms
- \h for help with SQL commands
- \? for help with psql commands
- \g or terminate with semicolon to execute query
- \q to quit
-
-asterisk=# SELECT * FROM voicemessages;
- id | msgnum | dir | context | macrocontext | callerid | origtime | duration | mailboxuser | mailboxcontext | recording | label | read | sip_id | pabx_id | iax_id
-----+--------+--------------------------------------------------+---------+--------------+-----------------------+------------+----------+-------------+----------------+-----------+-------+------+--------+---------+--------
- 26 | 0 | /var/spool/asterisk/voicemail/odbctest/101/INBOX | odbc | | "linksys" <linksys> | 1167794179 | 7 | 101 | odbctest | 16599 | | f | | |
-(1 row)
-
-Did you notice the the recording column is just a number? When a recording
-gets stuck in the database, the audio isn't actually stored in the
-voicemessages table. It's stored in a system table called the large object
-table. We can look in the large object table and verify that the object
-actually exists there:
-
-asterisk=# \lo_list
- Large objects
- ID | Description
--------+-------------
- 16599 |
-(1 row)
-
-In my case, the OID is 16599. Your OID will almost surely be different. Just
-make sure the OID number in the recording column in the voicemessages table
-corresponds with a record in the large object table. (The trigger we added to
-our voicemessages table was designed to make sure this is always the case.)
-
-We can also pull a copy of the voicemail message back out of the database and
-write it to a file, to help us as we debug things:
-
-asterisk=# \lo_export 16599 /tmp/odcb-16599.gsm
-lo_export
-
-We can even listen to the file from the Linux command line:
-
-[jsmith2@localhost tmp]$ play /tmp/odcb-16599.gsm
-
-Input Filename : /tmp/odcb-16599.gsm
-Sample Size : 8-bits
-Sample Encoding: gsm
-Channels : 1
-Sample Rate : 8000
-
-Time: 00:06.22 [00:00.00] of 00:00.00 ( 0.0%) Output Buffer: 298.36K
-
-Done.
-
-
-17) Last but not least, we can pull the voicemail message back out of the
-database by dialing extension 200 and entering "5555" at the password prompt.
-You should see something like this on the Asterisk CLI:
-
-localhost*CLI>
- -- Executing VoiceMailMain("SIP/linksys-10228cac", "101@odbctest") in new stack
- -- Playing 'vm-password' (language 'en')
- -- Playing 'vm-youhave' (language 'en')
- -- Playing 'digits/1' (language 'en')
- -- Playing 'vm-INBOX' (language 'en')
- -- Playing 'vm-message' (language 'en')
- -- Playing 'vm-onefor' (language 'en')
- -- Playing 'vm-INBOX' (language 'en')
- -- Playing 'vm-messages' (language 'en')
- -- Playing 'vm-opts' (language 'en')
- -- Playing 'vm-first' (language 'en')
- -- Playing 'vm-message' (language 'en')
- == Parsing '/var/spool/asterisk/voicemail/odbctest/101/INBOX/msg0000.txt': Found
- -- Playing 'vm-received' (language 'en')
- -- Playing 'digits/at' (language 'en')
- -- Playing 'digits/10' (language 'en')
- -- Playing 'digits/16' (language 'en')
- -- Playing 'digits/p-m' (language 'en')
- -- Playing '/var/spool/asterisk/voicemail/odbctest/101/INBOX/msg0000' (language 'en')
- -- Playing 'vm-advopts' (language 'en')
- -- Playing 'vm-repeat' (language 'en')
- -- Playing 'vm-delete' (language 'en')
- -- Playing 'vm-toforward' (language 'en')
- -- Playing 'vm-savemessage' (language 'en')
- -- Playing 'vm-helpexit' (language 'en')
- -- Playing 'vm-goodbye' (language 'en')
-
-That's it!
-
-Jared Smith
-2 Jan 2006
-(updated 11 Mar 2007)
diff --git a/1.4/formats/Makefile b/1.4/formats/Makefile
deleted file mode 100644
index 9e77de644..000000000
--- a/1.4/formats/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for file format modules
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=FORMATS
-MENUSELECT_DESCRIPTION=Format Interpreters
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard format_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard format_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_FORMATS),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_FORMATS),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring formats,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
diff --git a/1.4/formats/format_g723.c b/1.4/formats/format_g723.c
deleted file mode 100644
index dd5a1e6af..000000000
--- a/1.4/formats/format_g723.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*!
- * \file
- *
- * \brief Old-style G.723.1 frame/timestamp format.
- *
- * \arg Extensions: g723, g723sf
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-
-#define G723_MAX_SIZE 1024
-
-static struct ast_frame *g723_read(struct ast_filestream *s, int *whennext)
-{
- unsigned short size;
- int res;
- int delay;
- /* Read the delay for the next packet, and schedule again if necessary */
- /* XXX is this ignored ? */
- if (fread(&delay, 1, 4, s->f) == 4)
- delay = ntohl(delay);
- else
- delay = -1;
- if (fread(&size, 1, 2, s->f) != 2) {
- /* Out of data, or the file is no longer valid. In any case
- go ahead and stop the stream */
- return NULL;
- }
- /* Looks like we have a frame to read from here */
- size = ntohs(size);
- if (size > G723_MAX_SIZE) {
- ast_log(LOG_WARNING, "Size %d is invalid\n", size);
- /* The file is apparently no longer any good, as we
- shouldn't ever get frames even close to this
- size. */
- return NULL;
- }
- /* Read the data into the buffer */
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_G723_1;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, size);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != size) {
- ast_log(LOG_WARNING, "Short read (%d of %d bytes) (%s)!\n", res, size, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples = 240;
- return &s->fr;
-}
-
-static int g723_write(struct ast_filestream *s, struct ast_frame *f)
-{
- uint32_t delay;
- uint16_t size;
- int res;
- /* XXX there used to be a check s->fr means a read stream */
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_G723_1) {
- ast_log(LOG_WARNING, "Asked to write non-g723 frame!\n");
- return -1;
- }
- delay = 0;
- if (f->datalen <= 0) {
- ast_log(LOG_WARNING, "Short frame ignored (%d bytes long?)\n", f->datalen);
- return 0;
- }
- if ((res = fwrite(&delay, 1, 4, s->f)) != 4) {
- ast_log(LOG_WARNING, "Unable to write delay: res=%d (%s)\n", res, strerror(errno));
- return -1;
- }
- size = htons(f->datalen);
- if ((res = fwrite(&size, 1, 2, s->f)) != 2) {
- ast_log(LOG_WARNING, "Unable to write size: res=%d (%s)\n", res, strerror(errno));
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, s->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Unable to write frame: res=%d (%s)\n", res, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int g723_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- return -1;
-}
-
-static int g723_trunc(struct ast_filestream *fs)
-{
- /* Truncate file to current length */
- if (ftruncate(fileno(fs->f), ftello(fs->f)) < 0)
- return -1;
- return 0;
-}
-
-static off_t g723_tell(struct ast_filestream *fs)
-{
- return -1;
-}
-
-static const struct ast_format g723_1_f = {
- .name = "g723sf",
- .exts = "g723|g723sf",
- .format = AST_FORMAT_G723_1,
- .write = g723_write,
- .seek = g723_seek,
- .trunc = g723_trunc,
- .tell = g723_tell,
- .read = g723_read,
- .buf_size = G723_MAX_SIZE + AST_FRIENDLY_OFFSET,
-};
-
-static int load_module(void)
-{
- return ast_format_register(&g723_1_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(g723_1_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "G.723.1 Simple Timestamp File Format");
diff --git a/1.4/formats/format_g726.c b/1.4/formats/format_g726.c
deleted file mode 100644
index 499d545d2..000000000
--- a/1.4/formats/format_g726.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2004 - 2005, inAccess Networks
- *
- * Michael Manousos <manousos@inaccessnetworks.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.
- */
-
-/*!\file
- *
- * \brief Headerless G.726 (16/24/32/40kbps) data format for Asterisk.
- *
- * File name extensions:
- * \arg 40 kbps: g726-40
- * \arg 32 kbps: g726-32
- * \arg 24 kbps: g726-24
- * \arg 16 kbps: g726-16
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-#define RATE_40 0
-#define RATE_32 1
-#define RATE_24 2
-#define RATE_16 3
-
-/* We can only read/write chunks of FRAME_TIME ms G.726 data */
-#define FRAME_TIME 10 /* 10 ms size */
-
-#define BUF_SIZE (5*FRAME_TIME) /* max frame size in bytes ? */
-/* Frame sizes in bytes */
-static int frame_size[4] = {
- FRAME_TIME * 5,
- FRAME_TIME * 4,
- FRAME_TIME * 3,
- FRAME_TIME * 2
-};
-
-struct g726_desc {
- int rate; /* RATE_* defines */
-};
-
-/*
- * Rate dependant format functions (open, rewrite)
- */
-static int g726_open(struct ast_filestream *tmp, int rate)
-{
- struct g726_desc *s = (struct g726_desc *)tmp->_private;
- s->rate = rate;
- if (option_debug)
- ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
- 40 - s->rate * 8);
- return 0;
-}
-
-static int g726_40_open(struct ast_filestream *s)
-{
- return g726_open(s, RATE_40);
-}
-
-static int g726_32_open(struct ast_filestream *s)
-{
- return g726_open(s, RATE_32);
-}
-
-static int g726_24_open(struct ast_filestream *s)
-{
- return g726_open(s, RATE_24);
-}
-
-static int g726_16_open(struct ast_filestream *s)
-{
- return g726_open(s, RATE_16);
-}
-
-static int g726_40_rewrite(struct ast_filestream *s, const char *comment)
-{
- return g726_open(s, RATE_40);
-}
-
-static int g726_32_rewrite(struct ast_filestream *s, const char *comment)
-{
- return g726_open(s, RATE_32);
-}
-
-static int g726_24_rewrite(struct ast_filestream *s, const char *comment)
-{
- return g726_open(s, RATE_24);
-}
-
-static int g726_16_rewrite(struct ast_filestream *s, const char *comment)
-{
- return g726_open(s, RATE_16);
-}
-
-/*
- * Rate independent format functions (read, write)
- */
-
-static struct ast_frame *g726_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- struct g726_desc *fs = (struct g726_desc *)s->_private;
-
- /* Send a frame from the file to the appropriate channel */
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_G726;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, frame_size[fs->rate]);
- s->fr.samples = 8 * FRAME_TIME;
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples;
- return &s->fr;
-}
-
-static int g726_write(struct ast_filestream *s, struct ast_frame *f)
-{
- int res;
- struct g726_desc *fs = (struct g726_desc *)s->_private;
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_G726) {
- ast_log(LOG_WARNING, "Asked to write non-G726 frame (%d)!\n",
- f->subclass);
- return -1;
- }
- if (f->datalen % frame_size[fs->rate]) {
- ast_log(LOG_WARNING, "Invalid data length %d, should be multiple of %d\n",
- f->datalen, frame_size[fs->rate]);
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, s->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n",
- res, frame_size[fs->rate], strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int g726_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- return -1;
-}
-
-static int g726_trunc(struct ast_filestream *fs)
-{
- return -1;
-}
-
-static off_t g726_tell(struct ast_filestream *fs)
-{
- return -1;
-}
-
-static const struct ast_format f[] = {
- {
- .name = "g726-40",
- .exts = "g726-40",
- .format = AST_FORMAT_G726,
- .open = g726_40_open,
- .rewrite = g726_40_rewrite,
- .write = g726_write,
- .seek = g726_seek,
- .trunc = g726_trunc,
- .tell = g726_tell,
- .read = g726_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct g726_desc),
- },
- {
- .name = "g726-32",
- .exts = "g726-32",
- .format = AST_FORMAT_G726,
- .open = g726_32_open,
- .rewrite = g726_32_rewrite,
- .write = g726_write,
- .seek = g726_seek,
- .trunc = g726_trunc,
- .tell = g726_tell,
- .read = g726_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct g726_desc),
- },
- {
- .name = "g726-24",
- .exts = "g726-24",
- .format = AST_FORMAT_G726,
- .open = g726_24_open,
- .rewrite = g726_24_rewrite,
- .write = g726_write,
- .seek = g726_seek,
- .trunc = g726_trunc,
- .tell = g726_tell,
- .read = g726_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct g726_desc),
- },
- {
- .name = "g726-16",
- .exts = "g726-16",
- .format = AST_FORMAT_G726,
- .open = g726_16_open,
- .rewrite = g726_16_rewrite,
- .write = g726_write,
- .seek = g726_seek,
- .trunc = g726_trunc,
- .tell = g726_tell,
- .read = g726_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct g726_desc),
- },
- { .format = 0 } /* terminator */
-};
-
-static int load_module(void)
-{
- int i;
-
- for (i = 0; f[i].format ; i++) {
- if (ast_format_register(&f[i])) { /* errors are fatal */
- ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
- return -1;
- }
- }
- return 0;
-}
-
-static int unload_module(void)
-{
- int i;
-
- for (i = 0; f[i].format ; i++) {
- if (ast_format_unregister(f[i].name))
- ast_log(LOG_WARNING, "Failed to unregister format %s.\n", f[i].name);
- }
- return(0);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw G.726 (16/24/32/40kbps) data");
diff --git a/1.4/formats/format_g729.c b/1.4/formats/format_g729.c
deleted file mode 100644
index 3f46bcbff..000000000
--- a/1.4/formats/format_g729.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Save to raw, headerless G729 data.
- * \note This is not an encoder/decoder. The codec fo g729 is only
- * available with a commercial license from Digium, due to patent
- * restrictions. Check http://www.digium.com for information.
- * \arg Extensions: g729
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-/* Some Ideas for this code came from makeg729e.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-
-#define BUF_SIZE 20 /* two G729 frames */
-#define G729A_SAMPLES 160
-
-static struct ast_frame *g729_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- /* Send a frame from the file to the appropriate channel */
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_G729A;
- s->fr.mallocd = 0;
- s->fr.samples = G729A_SAMPLES;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
- if (res && (res != 10)) /* XXX what for ? */
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples;
- return &s->fr;
-}
-
-static int g729_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res;
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_G729A) {
- ast_log(LOG_WARNING, "Asked to write non-G729 frame (%d)!\n", f->subclass);
- return -1;
- }
- if (f->datalen % 10) {
- ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 10\n", f->datalen);
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/10): %s\n", res, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int g729_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- long bytes;
- off_t min,cur,max,offset=0;
- min = 0;
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
-
- bytes = BUF_SIZE * (sample_offset / G729A_SAMPLES);
- if (whence == SEEK_SET)
- offset = bytes;
- else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = cur + bytes;
- else if (whence == SEEK_END)
- offset = max - bytes;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max)?max:offset;
- }
- /* protect against seeking beyond begining. */
- offset = (offset < min)?min:offset;
- if (fseeko(fs->f, offset, SEEK_SET) < 0)
- return -1;
- return 0;
-}
-
-static int g729_trunc(struct ast_filestream *fs)
-{
- /* Truncate file to current length */
- if (ftruncate(fileno(fs->f), ftello(fs->f)) < 0)
- return -1;
- return 0;
-}
-
-static off_t g729_tell(struct ast_filestream *fs)
-{
- off_t offset = ftello(fs->f);
- return (offset/BUF_SIZE)*G729A_SAMPLES;
-}
-
-static const struct ast_format g729_f = {
- .name = "g729",
- .exts = "g729",
- .format = AST_FORMAT_G729A,
- .write = g729_write,
- .seek = g729_seek,
- .trunc = g729_trunc,
- .tell = g729_tell,
- .read = g729_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
-};
-
-static int load_module(void)
-{
- return ast_format_register(&g729_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(g729_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw G729 data");
diff --git a/1.4/formats/format_gsm.c b/1.4/formats/format_gsm.c
deleted file mode 100644
index f997af119..000000000
--- a/1.4/formats/format_gsm.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Save to raw, headerless GSM data.
- * \arg File name extension: gsm
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-#include "msgsm.h"
-
-/* Some Ideas for this code came from makegsme.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-
-#define GSM_FRAME_SIZE 33
-#define GSM_SAMPLES 160
-
-/* silent gsm frame */
-/* begin binary data: */
-char gsm_silence[] = /* 33 */
-{0xD8,0x20,0xA2,0xE1,0x5A,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49
-,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24
-,0x92,0x49,0x24};
-/* end binary data. size = 33 bytes */
-
-static struct ast_frame *gsm_read(struct ast_filestream *s, int *whennext)
-{
- int res;
-
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_GSM;
- AST_FRAME_SET_BUFFER(&(s->fr), s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE)
- s->fr.mallocd = 0;
- if ((res = fread(s->fr.data, 1, GSM_FRAME_SIZE, s->f)) != GSM_FRAME_SIZE) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples = GSM_SAMPLES;
- return &s->fr;
-}
-
-static int gsm_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res;
- unsigned char gsm[2*GSM_FRAME_SIZE];
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_GSM) {
- ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
- return -1;
- }
- if (!(f->datalen % 65)) {
- /* This is in MSGSM format, need to be converted */
- int len=0;
- while(len < f->datalen) {
- conv65(f->data + len, gsm);
- if ((res = fwrite(gsm, 1, 2*GSM_FRAME_SIZE, fs->f)) != 2*GSM_FRAME_SIZE) {
- ast_log(LOG_WARNING, "Bad write (%d/66): %s\n", res, strerror(errno));
- return -1;
- }
- len += 65;
- }
- } else {
- if (f->datalen % GSM_FRAME_SIZE) {
- ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 33\n", f->datalen);
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/33): %s\n", res, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
-static int gsm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t offset=0,min,cur,max,distance;
-
- min = 0;
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
- /* have to fudge to frame here, so not fully to sample */
- distance = (sample_offset/GSM_SAMPLES) * GSM_FRAME_SIZE;
- if(whence == SEEK_SET)
- offset = distance;
- else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = distance + cur;
- else if(whence == SEEK_END)
- offset = max - distance;
- /* Always protect against seeking past the begining. */
- offset = (offset < min)?min:offset;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max)?max:offset;
- } else if (offset > max) {
- int i;
- fseeko(fs->f, 0, SEEK_END);
- for (i=0; i< (offset - max) / GSM_FRAME_SIZE; i++) {
- fwrite(gsm_silence, 1, GSM_FRAME_SIZE, fs->f);
- }
- }
- return fseeko(fs->f, offset, SEEK_SET);
-}
-
-static int gsm_trunc(struct ast_filestream *fs)
-{
- return ftruncate(fileno(fs->f), ftello(fs->f));
-}
-
-static off_t gsm_tell(struct ast_filestream *fs)
-{
- off_t offset = ftello(fs->f);
- return (offset/GSM_FRAME_SIZE)*GSM_SAMPLES;
-}
-
-static const struct ast_format gsm_f = {
- .name = "gsm",
- .exts = "gsm",
- .format = AST_FORMAT_GSM,
- .write = gsm_write,
- .seek = gsm_seek,
- .trunc = gsm_trunc,
- .tell = gsm_tell,
- .read = gsm_read,
- .buf_size = 2*GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET, /* 2 gsm frames */
-};
-
-static int load_module(void)
-{
- return ast_format_register(&gsm_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(gsm_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw GSM data");
diff --git a/1.4/formats/format_h263.c b/1.4/formats/format_h263.c
deleted file mode 100644
index baa7a3efd..000000000
--- a/1.4/formats/format_h263.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Save to raw, headerless h263 data.
- * \arg File name extension: h263
- * \ingroup formats
- * \arg See \ref AstVideo
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-/* Some Ideas for this code came from makeh263e.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-
-/* According to:
- * http://lists.mpegif.org/pipermail/mp4-tech/2005-July/005741.html
- * the maximum actual frame size is not 2048, but 8192. Since the maximum
- * theoretical limit is not much larger (32k = 15bits), we'll go for that
- * size to ensure we don't corrupt frames sent to us (unless they're
- * ridiculously large). */
-#define BUF_SIZE 32768 /* Four real h.263 Frames */
-
-struct h263_desc {
- unsigned int lastts;
-};
-
-
-static int h263_open(struct ast_filestream *s)
-{
- unsigned int ts;
- int res;
-
- if ((res = fread(&ts, 1, sizeof(ts), s->f)) < sizeof(ts)) {
- ast_log(LOG_WARNING, "Empty file!\n");
- return -1;
- }
- return 0;
-}
-
-static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- int mark;
- unsigned short len;
- unsigned int ts;
- struct h263_desc *fs = (struct h263_desc *)s->_private;
-
- /* Send a frame from the file to the appropriate channel */
- if ((res = fread(&len, 1, sizeof(len), s->f)) < 1)
- return NULL;
- len = ntohs(len);
- mark = (len & 0x8000) ? 1 : 0;
- len &= 0x7fff;
- if (len > BUF_SIZE) {
- ast_log(LOG_WARNING, "Length %d is too long\n", len);
- return NULL;
- }
- s->fr.frametype = AST_FRAME_VIDEO;
- s->fr.subclass = AST_FORMAT_H263;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- s->fr.samples = fs->lastts; /* XXX what ? */
- s->fr.datalen = len;
- s->fr.subclass |= mark;
- s->fr.delivery.tv_sec = 0;
- s->fr.delivery.tv_usec = 0;
- if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
- fs->lastts = ntohl(ts);
- *whennext = fs->lastts * 4/45;
- } else
- *whennext = 0;
- return &s->fr;
-}
-
-static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res;
- unsigned int ts;
- unsigned short len;
- int subclass;
- int mark=0;
- if (f->frametype != AST_FRAME_VIDEO) {
- ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
- return -1;
- }
- subclass = f->subclass;
- if (subclass & 0x1)
- mark=0x8000;
- subclass &= ~0x1;
- if (subclass != AST_FORMAT_H263) {
- ast_log(LOG_WARNING, "Asked to write non-h263 frame (%d)!\n", f->subclass);
- return -1;
- }
- ts = htonl(f->samples);
- if ((res = fwrite(&ts, 1, sizeof(ts), fs->f)) != sizeof(ts)) {
- ast_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
- return -1;
- }
- len = htons(f->datalen | mark);
- if ((res = fwrite(&len, 1, sizeof(len), fs->f)) != sizeof(len)) {
- ast_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int h263_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- /* No way Jose */
- return -1;
-}
-
-static int h263_trunc(struct ast_filestream *fs)
-{
- /* Truncate file to current length */
- if (ftruncate(fileno(fs->f), ftello(fs->f)) < 0)
- return -1;
- return 0;
-}
-
-static off_t h263_tell(struct ast_filestream *fs)
-{
- off_t offset = ftello(fs->f);
- return offset; /* XXX totally bogus, needs fixing */
-}
-
-static const struct ast_format h263_f = {
- .name = "h263",
- .exts = "h263",
- .format = AST_FORMAT_H263,
- .open = h263_open,
- .write = h263_write,
- .seek = h263_seek,
- .trunc = h263_trunc,
- .tell = h263_tell,
- .read = h263_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct h263_desc),
-};
-
-static int load_module(void)
-{
- return ast_format_register(&h263_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(h263_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw H.263 data");
diff --git a/1.4/formats/format_h264.c b/1.4/formats/format_h264.c
deleted file mode 100644
index bc70a75c7..000000000
--- a/1.4/formats/format_h264.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Save to raw, headerless h264 data.
- * \arg File name extension: h264
- * \ingroup formats
- * \arg See \ref AstVideo
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-/* Some Ideas for this code came from makeh264e.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-/*! \todo Check this buf size estimate, it may be totally wrong for large frame video */
-
-#define BUF_SIZE 4096 /* Two Real h264 Frames */
-struct h264_desc {
- unsigned int lastts;
-};
-
-static int h264_open(struct ast_filestream *s)
-{
- unsigned int ts;
- int res;
- if ((res = fread(&ts, 1, sizeof(ts), s->f)) < sizeof(ts)) {
- ast_log(LOG_WARNING, "Empty file!\n");
- return -1;
- }
- return 0;
-}
-
-static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- int mark=0;
- unsigned short len;
- unsigned int ts;
- struct h264_desc *fs = (struct h264_desc *)s->_private;
-
- /* Send a frame from the file to the appropriate channel */
- if ((res = fread(&len, 1, sizeof(len), s->f)) < 1)
- return NULL;
- len = ntohs(len);
- mark = (len & 0x8000) ? 1 : 0;
- len &= 0x7fff;
- if (len > BUF_SIZE) {
- ast_log(LOG_WARNING, "Length %d is too long\n", len);
- len = BUF_SIZE; /* XXX truncate */
- }
- s->fr.frametype = AST_FRAME_VIDEO;
- s->fr.subclass = AST_FORMAT_H264;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d of %d) (%s)!\n", res, len, strerror(errno));
- return NULL;
- }
- s->fr.samples = fs->lastts;
- s->fr.datalen = len;
- s->fr.subclass |= mark;
- s->fr.delivery.tv_sec = 0;
- s->fr.delivery.tv_usec = 0;
- if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
- fs->lastts = ntohl(ts);
- *whennext = fs->lastts * 4/45;
- } else
- *whennext = 0;
- return &s->fr;
-}
-
-static int h264_write(struct ast_filestream *s, struct ast_frame *f)
-{
- int res;
- unsigned int ts;
- unsigned short len;
- int mark;
-
- if (f->frametype != AST_FRAME_VIDEO) {
- ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
- return -1;
- }
- mark = (f->subclass & 0x1) ? 0x8000 : 0;
- if ((f->subclass & ~0x1) != AST_FORMAT_H264) {
- ast_log(LOG_WARNING, "Asked to write non-h264 frame (%d)!\n", f->subclass);
- return -1;
- }
- ts = htonl(f->samples);
- if ((res = fwrite(&ts, 1, sizeof(ts), s->f)) != sizeof(ts)) {
- ast_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
- return -1;
- }
- len = htons(f->datalen | mark);
- if ((res = fwrite(&len, 1, sizeof(len), s->f)) != sizeof(len)) {
- ast_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, s->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int h264_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- /* No way Jose */
- return -1;
-}
-
-static int h264_trunc(struct ast_filestream *fs)
-{
- /* Truncate file to current length */
- if (ftruncate(fileno(fs->f), ftell(fs->f)) < 0)
- return -1;
- return 0;
-}
-
-static off_t h264_tell(struct ast_filestream *fs)
-{
- off_t offset = ftell(fs->f);
- return offset; /* XXX totally bogus, needs fixing */
-}
-
-static const struct ast_format h264_f = {
- .name = "h264",
- .exts = "h264",
- .format = AST_FORMAT_H264,
- .open = h264_open,
- .write = h264_write,
- .seek = h264_seek,
- .trunc = h264_trunc,
- .tell = h264_tell,
- .read = h264_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct h264_desc),
-};
-
-static int load_module(void)
-{
- return ast_format_register(&h264_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(h264_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw H.264 data");
diff --git a/1.4/formats/format_ilbc.c b/1.4/formats/format_ilbc.c
deleted file mode 100644
index 78d117910..000000000
--- a/1.4/formats/format_ilbc.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Brian K. West <brian@bkw.org>
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Save to raw, headerless iLBC data.
- * \arg File name extension: ilbc
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-/* Some Ideas for this code came from makeg729e.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-
-#define ILBC_BUF_SIZE 50 /* One Real iLBC Frame */
-#define ILBC_SAMPLES 240
-
-static struct ast_frame *ilbc_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- /* Send a frame from the file to the appropriate channel */
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_ILBC;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, ILBC_BUF_SIZE);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples = ILBC_SAMPLES;
- return &s->fr;
-}
-
-static int ilbc_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res;
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_ILBC) {
- ast_log(LOG_WARNING, "Asked to write non-iLBC frame (%d)!\n", f->subclass);
- return -1;
- }
- if (f->datalen % 50) {
- ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 50\n", f->datalen);
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/50): %s\n", res, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int ilbc_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- long bytes;
- off_t min,cur,max,offset=0;
- min = 0;
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
-
- bytes = ILBC_BUF_SIZE * (sample_offset / ILBC_SAMPLES);
- if (whence == SEEK_SET)
- offset = bytes;
- else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = cur + bytes;
- else if (whence == SEEK_END)
- offset = max - bytes;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max)?max:offset;
- }
- /* protect against seeking beyond begining. */
- offset = (offset < min)?min:offset;
- if (fseeko(fs->f, offset, SEEK_SET) < 0)
- return -1;
- return 0;
-}
-
-static int ilbc_trunc(struct ast_filestream *fs)
-{
- /* Truncate file to current length */
- if (ftruncate(fileno(fs->f), ftello(fs->f)) < 0)
- return -1;
- return 0;
-}
-
-static off_t ilbc_tell(struct ast_filestream *fs)
-{
- off_t offset = ftello(fs->f);
- return (offset/ILBC_BUF_SIZE)*ILBC_SAMPLES;
-}
-
-static const struct ast_format ilbc_f = {
- .name = "iLBC",
- .exts = "ilbc",
- .format = AST_FORMAT_ILBC,
- .write = ilbc_write,
- .seek = ilbc_seek,
- .trunc = ilbc_trunc,
- .tell = ilbc_tell,
- .read = ilbc_read,
- .buf_size = ILBC_BUF_SIZE + AST_FRIENDLY_OFFSET,
-};
-
-static int load_module(void)
-{
- return ast_format_register(&ilbc_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(ilbc_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw iLBC data");
diff --git a/1.4/formats/format_jpeg.c b/1.4/formats/format_jpeg.c
deleted file mode 100644
index edef171d2..000000000
--- a/1.4/formats/format_jpeg.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief JPEG File format support.
- *
- * \arg File name extension: jpeg, jpg
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/image.h"
-#include "asterisk/lock.h"
-#include "asterisk/endian.h"
-
-static struct ast_frame *jpeg_read_image(int fd, int len)
-{
- struct ast_frame fr;
- int res;
- char buf[65536];
- if (len > sizeof(buf) || len < 0) {
- ast_log(LOG_WARNING, "JPEG image too large to read\n");
- return NULL;
- }
- res = read(fd, buf, len);
- if (res < len) {
- ast_log(LOG_WARNING, "Only read %d of %d bytes: %s\n", res, len, strerror(errno));
- }
- memset(&fr, 0, sizeof(fr));
- fr.frametype = AST_FRAME_IMAGE;
- fr.subclass = AST_FORMAT_JPEG;
- fr.data = buf;
- fr.src = "JPEG Read";
- fr.datalen = len;
- return ast_frisolate(&fr);
-}
-
-static int jpeg_identify(int fd)
-{
- char buf[10];
- int res;
- res = read(fd, buf, sizeof(buf));
- if (res < sizeof(buf))
- return 0;
- if (memcmp(buf + 6, "JFIF", 4))
- return 0;
- return 1;
-}
-
-static int jpeg_write_image(int fd, struct ast_frame *fr)
-{
- int res=0;
- if (fr->frametype != AST_FRAME_IMAGE) {
- ast_log(LOG_WARNING, "Not an image\n");
- return -1;
- }
- if (fr->subclass != AST_FORMAT_JPEG) {
- ast_log(LOG_WARNING, "Not a jpeg image\n");
- return -1;
- }
- if (fr->datalen) {
- res = write(fd, fr->data, fr->datalen);
- if (res != fr->datalen) {
- ast_log(LOG_WARNING, "Only wrote %d of %d bytes: %s\n", res, fr->datalen, strerror(errno));
- return -1;
- }
- }
- return res;
-}
-
-static struct ast_imager jpeg_format = {
- "jpg",
- "JPEG (Joint Picture Experts Group)",
- "jpg|jpeg",
- AST_FORMAT_JPEG,
- jpeg_read_image,
- jpeg_identify,
- jpeg_write_image,
-};
-
-static int load_module(void)
-{
- return ast_image_register(&jpeg_format);
-}
-
-static int unload_module(void)
-{
- ast_image_unregister(&jpeg_format);
-
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "JPEG (Joint Picture Experts Group) Image Format");
diff --git a/1.4/formats/format_ogg_vorbis.c b/1.4/formats/format_ogg_vorbis.c
deleted file mode 100644
index ff796e79f..000000000
--- a/1.4/formats/format_ogg_vorbis.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Jeff Ollie
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief OGG/Vorbis streams.
- * \arg File name extension: ogg
- * \ingroup formats
- */
-
-/* the order of these dependencies is important... it also specifies
- the link order of the libraries during linking
-*/
-
-/*** MODULEINFO
- <depend>vorbis</depend>
- <depend>ogg</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#include <vorbis/codec.h>
-#include <vorbis/vorbisenc.h>
-
-#ifdef _WIN32
-#include <io.h>
-#include <fcntl.h>
-#endif
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-
-/*
- * this is the number of samples we deal with. Samples are converted
- * to SLINEAR so each one uses 2 bytes in the buffer.
- */
-#define SAMPLES_MAX 160
-#define BUF_SIZE (2*SAMPLES_MAX)
-
-#define BLOCK_SIZE 4096 /* used internally in the vorbis routines */
-
-struct vorbis_desc { /* format specific parameters */
- /* structures for handling the Ogg container */
- ogg_sync_state oy;
- ogg_stream_state os;
- ogg_page og;
- ogg_packet op;
-
- /* structures for handling Vorbis audio data */
- vorbis_info vi;
- vorbis_comment vc;
- vorbis_dsp_state vd;
- vorbis_block vb;
-
- /*! \brief Indicates whether this filestream is set up for reading or writing. */
- int writing;
-
- /*! \brief Indicates whether an End of Stream condition has been detected. */
- int eos;
-};
-
-/*!
- * \brief Create a new OGG/Vorbis filestream and set it up for reading.
- * \param s File that points to on disk storage of the OGG/Vorbis data.
- * \return The new filestream.
- */
-static int ogg_vorbis_open(struct ast_filestream *s)
-{
- int i;
- int bytes;
- int result;
- char **ptr;
- char *buffer;
- struct vorbis_desc *tmp = (struct vorbis_desc *)s->_private;
-
- tmp->writing = 0;
-
- ogg_sync_init(&tmp->oy);
-
- buffer = ogg_sync_buffer(&tmp->oy, BLOCK_SIZE);
- bytes = fread(buffer, 1, BLOCK_SIZE, s->f);
- ogg_sync_wrote(&tmp->oy, bytes);
-
- result = ogg_sync_pageout(&tmp->oy, &tmp->og);
- if (result != 1) {
- if(bytes < BLOCK_SIZE) {
- ast_log(LOG_ERROR, "Run out of data...\n");
- } else {
- ast_log(LOG_ERROR, "Input does not appear to be an Ogg bitstream.\n");
- }
- ogg_sync_clear(&tmp->oy);
- return -1;
- }
-
- ogg_stream_init(&tmp->os, ogg_page_serialno(&tmp->og));
- vorbis_info_init(&tmp->vi);
- vorbis_comment_init(&tmp->vc);
-
- if (ogg_stream_pagein(&tmp->os, &tmp->og) < 0) {
- ast_log(LOG_ERROR, "Error reading first page of Ogg bitstream data.\n");
-error:
- ogg_stream_clear(&tmp->os);
- vorbis_comment_clear(&tmp->vc);
- vorbis_info_clear(&tmp->vi);
- ogg_sync_clear(&tmp->oy);
- return -1;
- }
-
- if (ogg_stream_packetout(&tmp->os, &tmp->op) != 1) {
- ast_log(LOG_ERROR, "Error reading initial header packet.\n");
- goto error;
- }
-
- if (vorbis_synthesis_headerin(&tmp->vi, &tmp->vc, &tmp->op) < 0) {
- ast_log(LOG_ERROR, "This Ogg bitstream does not contain Vorbis audio data.\n");
- goto error;
- }
-
- for (i = 0; i < 2 ; ) {
- while (i < 2) {
- result = ogg_sync_pageout(&tmp->oy, &tmp->og);
- if (result == 0)
- break;
- if (result == 1) {
- ogg_stream_pagein(&tmp->os, &tmp->og);
- while(i < 2) {
- result = ogg_stream_packetout(&tmp->os,&tmp->op);
- if(result == 0)
- break;
- if(result < 0) {
- ast_log(LOG_ERROR, "Corrupt secondary header. Exiting.\n");
- goto error;
- }
- vorbis_synthesis_headerin(&tmp->vi, &tmp->vc, &tmp->op);
- i++;
- }
- }
- }
-
- buffer = ogg_sync_buffer(&tmp->oy, BLOCK_SIZE);
- bytes = fread(buffer, 1, BLOCK_SIZE, s->f);
- if (bytes == 0 && i < 2) {
- ast_log(LOG_ERROR, "End of file before finding all Vorbis headers!\n");
- goto error;
- }
- ogg_sync_wrote(&tmp->oy, bytes);
- }
-
- for (ptr = tmp->vc.user_comments; *ptr; ptr++)
- ast_log(LOG_DEBUG, "OGG/Vorbis comment: %s\n", *ptr);
- ast_log(LOG_DEBUG, "OGG/Vorbis bitstream is %d channel, %ldHz\n", tmp->vi.channels, tmp->vi.rate);
- ast_log(LOG_DEBUG, "OGG/Vorbis file encoded by: %s\n", tmp->vc.vendor);
-
- if (tmp->vi.channels != 1) {
- ast_log(LOG_ERROR, "Only monophonic OGG/Vorbis files are currently supported!\n");
- goto error;
- }
-
- if (tmp->vi.rate != DEFAULT_SAMPLE_RATE) {
- ast_log(LOG_ERROR, "Only 8000Hz OGG/Vorbis files are currently supported!\n");
- vorbis_block_clear(&tmp->vb);
- vorbis_dsp_clear(&tmp->vd);
- goto error;
- }
-
- vorbis_synthesis_init(&tmp->vd, &tmp->vi);
- vorbis_block_init(&tmp->vd, &tmp->vb);
-
- return 0;
-}
-
-/*!
- * \brief Create a new OGG/Vorbis filestream and set it up for writing.
- * \param s File pointer that points to on-disk storage.
- * \param comment Comment that should be embedded in the OGG/Vorbis file.
- * \return A new filestream.
- */
-static int ogg_vorbis_rewrite(struct ast_filestream *s,
- const char *comment)
-{
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
- struct vorbis_desc *tmp = (struct vorbis_desc *)s->_private;
-
- tmp->writing = 1;
-
- vorbis_info_init(&tmp->vi);
-
- if (vorbis_encode_init_vbr(&tmp->vi, 1, DEFAULT_SAMPLE_RATE, 0.4)) {
- ast_log(LOG_ERROR, "Unable to initialize Vorbis encoder!\n");
- return -1;
- }
-
- vorbis_comment_init(&tmp->vc);
- vorbis_comment_add_tag(&tmp->vc, "ENCODER", "Asterisk PBX");
- if (comment)
- vorbis_comment_add_tag(&tmp->vc, "COMMENT", (char *) comment);
-
- vorbis_analysis_init(&tmp->vd, &tmp->vi);
- vorbis_block_init(&tmp->vd, &tmp->vb);
-
- ogg_stream_init(&tmp->os, ast_random());
-
- vorbis_analysis_headerout(&tmp->vd, &tmp->vc, &header, &header_comm,
- &header_code);
- ogg_stream_packetin(&tmp->os, &header);
- ogg_stream_packetin(&tmp->os, &header_comm);
- ogg_stream_packetin(&tmp->os, &header_code);
-
- while (!tmp->eos) {
- if (ogg_stream_flush(&tmp->os, &tmp->og) == 0)
- break;
- fwrite(tmp->og.header, 1, tmp->og.header_len, s->f);
- fwrite(tmp->og.body, 1, tmp->og.body_len, s->f);
- if (ogg_page_eos(&tmp->og))
- tmp->eos = 1;
- }
-
- return 0;
-}
-
-/*!
- * \brief Write out any pending encoded data.
- * \param s An OGG/Vorbis filestream.
- * \param f The file to write to.
- */
-static void write_stream(struct vorbis_desc *s, FILE *f)
-{
- while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
- vorbis_analysis(&s->vb, NULL);
- vorbis_bitrate_addblock(&s->vb);
-
- while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
- ogg_stream_packetin(&s->os, &s->op);
- while (!s->eos) {
- if (ogg_stream_pageout(&s->os, &s->og) == 0) {
- break;
- }
- fwrite(s->og.header, 1, s->og.header_len, f);
- fwrite(s->og.body, 1, s->og.body_len, f);
- if (ogg_page_eos(&s->og)) {
- s->eos = 1;
- }
- }
- }
- }
-}
-
-/*!
- * \brief Write audio data from a frame to an OGG/Vorbis filestream.
- * \param fs An OGG/Vorbis filestream.
- * \param f A frame containing audio to be written to the filestream.
- * \return -1 if there was an error, 0 on success.
- */
-static int ogg_vorbis_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int i;
- float **buffer;
- short *data;
- struct vorbis_desc *s = (struct vorbis_desc *)fs->_private;
-
- if (!s->writing) {
- ast_log(LOG_ERROR, "This stream is not set up for writing!\n");
- return -1;
- }
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_SLINEAR) {
- ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%d)!\n",
- f->subclass);
- return -1;
- }
- if (!f->datalen)
- return -1;
-
- data = (short *) f->data;
-
- buffer = vorbis_analysis_buffer(&s->vd, f->samples);
-
- for (i = 0; i < f->samples; i++)
- buffer[0][i] = (double)data[i] / 32768.0;
-
- vorbis_analysis_wrote(&s->vd, f->samples);
-
- write_stream(s, fs->f);
-
- return 0;
-}
-
-/*!
- * \brief Close a OGG/Vorbis filestream.
- * \param fs A OGG/Vorbis filestream.
- */
-static void ogg_vorbis_close(struct ast_filestream *fs)
-{
- struct vorbis_desc *s = (struct vorbis_desc *)fs->_private;
-
- if (s->writing) {
- /* Tell the Vorbis encoder that the stream is finished
- * and write out the rest of the data */
- vorbis_analysis_wrote(&s->vd, 0);
- write_stream(s, fs->f);
- }
-
- ogg_stream_clear(&s->os);
- vorbis_block_clear(&s->vb);
- vorbis_dsp_clear(&s->vd);
- vorbis_comment_clear(&s->vc);
- vorbis_info_clear(&s->vi);
-
- if (s->writing) {
- ogg_sync_clear(&s->oy);
- }
-}
-
-/*!
- * \brief Get audio data.
- * \param fs An OGG/Vorbis filestream.
- * \param pcm Pointer to a buffere to store audio data in.
- */
-
-static int read_samples(struct ast_filestream *fs, float ***pcm)
-{
- int samples_in;
- int result;
- char *buffer;
- int bytes;
- struct vorbis_desc *s = (struct vorbis_desc *)fs->_private;
-
- while (1) {
- samples_in = vorbis_synthesis_pcmout(&s->vd, pcm);
- if (samples_in > 0) {
- return samples_in;
- }
-
- /* The Vorbis decoder needs more data... */
- /* See ifOGG has any packets in the current page for the Vorbis decoder. */
- result = ogg_stream_packetout(&s->os, &s->op);
- if (result > 0) {
- /* Yes OGG had some more packets for the Vorbis decoder. */
- if (vorbis_synthesis(&s->vb, &s->op) == 0) {
- vorbis_synthesis_blockin(&s->vd, &s->vb);
- }
-
- continue;
- }
-
- if (result < 0)
- ast_log(LOG_WARNING,
- "Corrupt or missing data at this page position; continuing...\n");
-
- /* No more packets left in the current page... */
-
- if (s->eos) {
- /* No more pages left in the stream */
- return -1;
- }
-
- while (!s->eos) {
- /* See ifOGG has any pages in it's internal buffers */
- result = ogg_sync_pageout(&s->oy, &s->og);
- if (result > 0) {
- /* Yes, OGG has more pages in it's internal buffers,
- add the page to the stream state */
- result = ogg_stream_pagein(&s->os, &s->og);
- if (result == 0) {
- /* Yes, got a new,valid page */
- if (ogg_page_eos(&s->og)) {
- s->eos = 1;
- }
- break;
- }
- ast_log(LOG_WARNING,
- "Invalid page in the bitstream; continuing...\n");
- }
-
- if (result < 0)
- ast_log(LOG_WARNING,
- "Corrupt or missing data in bitstream; continuing...\n");
-
- /* No, we need to read more data from the file descrptor */
- /* get a buffer from OGG to read the data into */
- buffer = ogg_sync_buffer(&s->oy, BLOCK_SIZE);
- /* read more data from the file descriptor */
- bytes = fread(buffer, 1, BLOCK_SIZE, fs->f);
- /* Tell OGG how many bytes we actually read into the buffer */
- ogg_sync_wrote(&s->oy, bytes);
- if (bytes == 0) {
- s->eos = 1;
- }
- }
- }
-}
-
-/*!
- * \brief Read a frame full of audio data from the filestream.
- * \param fs The filestream.
- * \param whennext Number of sample times to schedule the next call.
- * \return A pointer to a frame containing audio data or NULL ifthere is no more audio data.
- */
-static struct ast_frame *ogg_vorbis_read(struct ast_filestream *fs,
- int *whennext)
-{
- int clipflag = 0;
- int i;
- int j;
- double accumulator[SAMPLES_MAX];
- int val;
- int samples_in;
- int samples_out = 0;
- struct vorbis_desc *s = (struct vorbis_desc *)fs->_private;
- short *buf; /* SLIN data buffer */
-
- fs->fr.frametype = AST_FRAME_VOICE;
- fs->fr.subclass = AST_FORMAT_SLINEAR;
- fs->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&fs->fr, fs->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
- buf = (short *)(fs->fr.data); /* SLIN data buffer */
-
- while (samples_out != SAMPLES_MAX) {
- float **pcm;
- int len = SAMPLES_MAX - samples_out;
-
- /* See ifVorbis decoder has some audio data for us ... */
- samples_in = read_samples(fs, &pcm);
- if (samples_in <= 0)
- break;
-
- /* Got some audio data from Vorbis... */
- /* Convert the float audio data to 16-bit signed linear */
-
- clipflag = 0;
- if (samples_in > len)
- samples_in = len;
- for (j = 0; j < samples_in; j++)
- accumulator[j] = 0.0;
-
- for (i = 0; i < s->vi.channels; i++) {
- float *mono = pcm[i];
- for (j = 0; j < samples_in; j++)
- accumulator[j] += mono[j];
- }
-
- for (j = 0; j < samples_in; j++) {
- val = accumulator[j] * 32767.0 / s->vi.channels;
- if (val > 32767) {
- val = 32767;
- clipflag = 1;
- } else if (val < -32768) {
- val = -32768;
- clipflag = 1;
- }
- buf[samples_out + j] = val;
- }
-
- if (clipflag)
- ast_log(LOG_WARNING, "Clipping in frame %ld\n", (long) (s->vd.sequence));
- /* Tell the Vorbis decoder how many samples we actually used. */
- vorbis_synthesis_read(&s->vd, samples_in);
- samples_out += samples_in;
- }
-
- if (samples_out > 0) {
- fs->fr.datalen = samples_out * 2;
- fs->fr.samples = samples_out;
- *whennext = samples_out;
-
- return &fs->fr;
- } else {
- return NULL;
- }
-}
-
-/*!
- * \brief Trucate an OGG/Vorbis filestream.
- * \param s The filestream to truncate.
- * \return 0 on success, -1 on failure.
- */
-
-static int ogg_vorbis_trunc(struct ast_filestream *s)
-{
- ast_log(LOG_WARNING, "Truncation is not supported on OGG/Vorbis streams!\n");
- return -1;
-}
-
-/*!
- * \brief Seek to a specific position in an OGG/Vorbis filestream.
- * \param s The filestream to truncate.
- * \param sample_offset New position for the filestream, measured in 8KHz samples.
- * \param whence Location to measure
- * \return 0 on success, -1 on failure.
- */
-static int ogg_vorbis_seek(struct ast_filestream *s, off_t sample_offset, int whence)
-{
- ast_log(LOG_WARNING, "Seeking is not supported on OGG/Vorbis streams!\n");
- return -1;
-}
-
-static off_t ogg_vorbis_tell(struct ast_filestream *s)
-{
- ast_log(LOG_WARNING, "Telling is not supported on OGG/Vorbis streams!\n");
- return -1;
-}
-
-static const struct ast_format vorbis_f = {
- .name = "ogg_vorbis",
- .exts = "ogg",
- .format = AST_FORMAT_SLINEAR,
- .open = ogg_vorbis_open,
- .rewrite = ogg_vorbis_rewrite,
- .write = ogg_vorbis_write,
- .seek = ogg_vorbis_seek,
- .trunc = ogg_vorbis_trunc,
- .tell = ogg_vorbis_tell,
- .read = ogg_vorbis_read,
- .close = ogg_vorbis_close,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct vorbis_desc),
-};
-
-static int load_module(void)
-{
- return ast_format_register(&vorbis_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(vorbis_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "OGG/Vorbis audio");
-
diff --git a/1.4/formats/format_pcm.c b/1.4/formats/format_pcm.c
deleted file mode 100644
index 7b186e602..000000000
--- a/1.4/formats/format_pcm.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Flat, binary, ulaw PCM file format.
- * \arg File name extension: pcm, ulaw, ul, mu
- *
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/alaw.h"
-
-#define BUF_SIZE 160 /* 160 bytes, and same number of samples */
-
-static char ulaw_silence[BUF_SIZE];
-static char alaw_silence[BUF_SIZE];
-
-/* #define REALTIME_WRITE */ /* XXX does it work at all ? */
-
-#ifdef REALTIME_WRITE
-struct pcm_desc {
- unsigned long start_time;
-};
-
-/* Returns time in msec since system boot. */
-static unsigned long get_time(void)
-{
- struct tms buf;
- clock_t cur;
-
- cur = times( &buf );
- if( cur < 0 ) {
- ast_log( LOG_WARNING, "Cannot get current time\n" );
- return 0;
- }
- return cur * 1000 / sysconf( _SC_CLK_TCK );
-}
-
-static int pcma_open(struct ast_filestream *s)
-{
- if (s->fmt->format == AST_FORMAT_ALAW)
- pd->starttime = get_time();
- return 0;
-}
-
-static int pcma_rewrite(struct ast_filestream *s, const char *comment)
-{
- return pcma_open(s);
-}
-#endif
-
-static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
-{
- int res;
-
- /* Send a frame from the file to the appropriate channel */
-
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = s->fmt->format;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) < 1) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- s->fr.datalen = res;
- if (s->fmt->format == AST_FORMAT_G722)
- *whennext = s->fr.samples = res * 2;
- else
- *whennext = s->fr.samples = res;
- return &s->fr;
-}
-
-static int pcm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t cur, max, offset = 0;
- int ret = -1; /* assume error */
-
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
-
- switch (whence) {
- case SEEK_SET:
- offset = sample_offset;
- break;
- case SEEK_END:
- offset = max - sample_offset;
- break;
- case SEEK_CUR:
- case SEEK_FORCECUR:
- offset = cur + sample_offset;
- break;
- default:
- ast_log(LOG_WARNING, "invalid whence %d, assuming SEEK_SET\n", whence);
- offset = sample_offset;
- }
- if (offset < 0) {
- ast_log(LOG_WARNING, "negative offset %ld, resetting to 0\n", (long) offset);
- offset = 0;
- }
- if (whence == SEEK_FORCECUR && offset > max) { /* extend the file */
- size_t left = offset - max;
- const char *src = (fs->fmt->format == AST_FORMAT_ALAW) ? alaw_silence : ulaw_silence;
-
- while (left) {
- size_t written = fwrite(src, 1, (left > BUF_SIZE) ? BUF_SIZE : left, fs->f);
- if (written == -1)
- break; /* error */
- left -= written;
- }
- ret = 0; /* successful */
- } else {
- if (offset > max) {
- ast_log(LOG_WARNING, "offset too large %ld, truncating to %ld\n", (long) offset, (long) max);
- offset = max;
- }
- ret = fseeko(fs->f, offset, SEEK_SET);
- }
- return ret;
-}
-
-static int pcm_trunc(struct ast_filestream *fs)
-{
- return ftruncate(fileno(fs->f), ftello(fs->f));
-}
-
-static off_t pcm_tell(struct ast_filestream *fs)
-{
- return ftello(fs->f);
-}
-
-static int pcm_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res;
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != fs->fmt->format) {
- ast_log(LOG_WARNING, "Asked to write incompatible format frame (%d)!\n", f->subclass);
- return -1;
- }
-
-#ifdef REALTIME_WRITE
- if (s->fmt->format == AST_FORMAT_ALAW) {
- struct pcm_desc *pd = (struct pcm_desc *)fs->_private;
- struct stat stat_buf;
- unsigned long cur_time = get_time();
- unsigned long fpos = ( cur_time - pd->start_time ) * 8; /* 8 bytes per msec */
- /* Check if we have written to this position yet. If we have, then increment pos by one frame
- * for some degree of protection against receiving packets in the same clock tick.
- */
-
- fstat(fileno(fs->f), &stat_buf );
- if (stat_buf.st_size > fpos )
- fpos += f->datalen; /* Incrementing with the size of this current frame */
-
- if (stat_buf.st_size < fpos) {
- /* fill the gap with 0x55 rather than 0. */
- char buf[1024];
- unsigned long cur, to_write;
-
- cur = stat_buf.st_size;
- if (fseek(fs->f, cur, SEEK_SET) < 0) {
- ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) );
- return -1;
- }
- memset(buf, 0x55, 512);
- while (cur < fpos) {
- to_write = fpos - cur;
- if (to_write > sizeof(buf))
- to_write = sizeof(buf);
- fwrite(buf, 1, to_write, fs->f);
- cur += to_write;
- }
- }
-
- if (fseek(s->f, fpos, SEEK_SET) < 0) {
- ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) );
- return -1;
- }
- }
-#endif /* REALTIME_WRITE */
-
- if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-/* SUN .au support routines */
-
-#define AU_HEADER_SIZE 24
-#define AU_HEADER(var) uint32_t var[6]
-
-#define AU_HDR_MAGIC_OFF 0
-#define AU_HDR_HDR_SIZE_OFF 1
-#define AU_HDR_DATA_SIZE_OFF 2
-#define AU_HDR_ENCODING_OFF 3
-#define AU_HDR_SAMPLE_RATE_OFF 4
-#define AU_HDR_CHANNELS_OFF 5
-
-#define AU_ENC_8BIT_ULAW 1
-
-#define AU_MAGIC 0x2e736e64
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define htoll(b) (b)
-#define htols(b) (b)
-#define ltohl(b) (b)
-#define ltohs(b) (b)
-#else
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define htoll(b) \
- (((((b) ) & 0xFF) << 24) | \
- ((((b) >> 8) & 0xFF) << 16) | \
- ((((b) >> 16) & 0xFF) << 8) | \
- ((((b) >> 24) & 0xFF) ))
-#define htols(b) \
- (((((b) ) & 0xFF) << 8) | \
- ((((b) >> 8) & 0xFF) ))
-#define ltohl(b) htoll(b)
-#define ltohs(b) htols(b)
-#else
-#error "Endianess not defined"
-#endif
-#endif
-
-static int check_header(FILE *f)
-{
- AU_HEADER(header);
- uint32_t magic;
- uint32_t hdr_size;
- uint32_t data_size;
- uint32_t encoding;
- uint32_t sample_rate;
- uint32_t channels;
-
- if (fread(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) {
- ast_log(LOG_WARNING, "Read failed (header)\n");
- return -1;
- }
- magic = ltohl(header[AU_HDR_MAGIC_OFF]);
- if (magic != (uint32_t) AU_MAGIC) {
- ast_log(LOG_WARNING, "Bad magic: 0x%x\n", magic);
- }
-/* hdr_size = ltohl(header[AU_HDR_HDR_SIZE_OFF]);
- if (hdr_size < AU_HEADER_SIZE)*/
- hdr_size = AU_HEADER_SIZE;
-/* data_size = ltohl(header[AU_HDR_DATA_SIZE_OFF]); */
- encoding = ltohl(header[AU_HDR_ENCODING_OFF]);
- if (encoding != AU_ENC_8BIT_ULAW) {
- ast_log(LOG_WARNING, "Unexpected format: %d. Only 8bit ULAW allowed (%d)\n", encoding, AU_ENC_8BIT_ULAW);
- return -1;
- }
- sample_rate = ltohl(header[AU_HDR_SAMPLE_RATE_OFF]);
- if (sample_rate != DEFAULT_SAMPLE_RATE) {
- ast_log(LOG_WARNING, "Sample rate can only be 8000 not %d\n", sample_rate);
- return -1;
- }
- channels = ltohl(header[AU_HDR_CHANNELS_OFF]);
- if (channels != 1) {
- ast_log(LOG_WARNING, "Not in mono: channels=%d\n", channels);
- return -1;
- }
- /* Skip to data */
- fseek(f, 0, SEEK_END);
- data_size = ftell(f) - hdr_size;
- if (fseek(f, hdr_size, SEEK_SET) == -1 ) {
- ast_log(LOG_WARNING, "Failed to skip to data: %d\n", hdr_size);
- return -1;
- }
- return data_size;
-}
-
-static int update_header(FILE *f)
-{
- off_t cur, end;
- uint32_t datalen;
- int bytes;
-
- cur = ftell(f);
- fseek(f, 0, SEEK_END);
- end = ftell(f);
- /* data starts 24 bytes in */
- bytes = end - AU_HEADER_SIZE;
- datalen = htoll(bytes);
-
- if (cur < 0) {
- ast_log(LOG_WARNING, "Unable to find our position\n");
- return -1;
- }
- if (fseek(f, AU_HDR_DATA_SIZE_OFF * sizeof(uint32_t), SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to set our position\n");
- return -1;
- }
- if (fwrite(&datalen, 1, sizeof(datalen), f) != sizeof(datalen)) {
- ast_log(LOG_WARNING, "Unable to set write file size\n");
- return -1;
- }
- if (fseek(f, cur, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to return to position\n");
- return -1;
- }
- return 0;
-}
-
-static int write_header(FILE *f)
-{
- AU_HEADER(header);
-
- header[AU_HDR_MAGIC_OFF] = htoll((uint32_t) AU_MAGIC);
- header[AU_HDR_HDR_SIZE_OFF] = htoll(AU_HEADER_SIZE);
- header[AU_HDR_DATA_SIZE_OFF] = 0;
- header[AU_HDR_ENCODING_OFF] = htoll(AU_ENC_8BIT_ULAW);
- header[AU_HDR_SAMPLE_RATE_OFF] = htoll(DEFAULT_SAMPLE_RATE);
- header[AU_HDR_CHANNELS_OFF] = htoll(1);
-
- /* Write an au header, ignoring sizes which will be filled in later */
- fseek(f, 0, SEEK_SET);
- if (fwrite(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- return 0;
-}
-
-static int au_open(struct ast_filestream *s)
-{
- if (check_header(s->f) < 0)
- return -1;
- return 0;
-}
-
-static int au_rewrite(struct ast_filestream *s, const char *comment)
-{
- if (write_header(s->f))
- return -1;
- return 0;
-}
-
-/* XXX check this, probably incorrect */
-static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t min, max, cur;
- long offset = 0, bytes;
-
- if (fs->fmt->format == AST_FORMAT_G722)
- bytes = sample_offset / 2;
- else
- bytes = sample_offset;
-
- min = AU_HEADER_SIZE;
- cur = ftello(fs->f);
- fseek(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
-
- if (whence == SEEK_SET)
- offset = bytes + min;
- else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = bytes + cur;
- else if (whence == SEEK_END)
- offset = max - bytes;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max) ? max : offset;
- }
-
- /* always protect the header space. */
- offset = (offset < min) ? min : offset;
-
- return fseeko(fs->f, offset, SEEK_SET);
-}
-
-static int au_trunc(struct ast_filestream *fs)
-{
- if (ftruncate(fileno(fs->f), ftell(fs->f)))
- return -1;
- return update_header(fs->f);
-}
-
-static off_t au_tell(struct ast_filestream *fs)
-{
- off_t offset = ftello(fs->f);
- return offset - AU_HEADER_SIZE;
-}
-
-static const struct ast_format alaw_f = {
- .name = "alaw",
- .exts = "alaw|al",
- .format = AST_FORMAT_ALAW,
- .write = pcm_write,
- .seek = pcm_seek,
- .trunc = pcm_trunc,
- .tell = pcm_tell,
- .read = pcm_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
-#ifdef REALTIME_WRITE
- .open = pcma_open,
- .rewrite = pcma_rewrite,
- .desc_size = sizeof(struct pcm_desc),
-#endif
-};
-
-static const struct ast_format pcm_f = {
- .name = "pcm",
- .exts = "pcm|ulaw|ul|mu",
- .format = AST_FORMAT_ULAW,
- .write = pcm_write,
- .seek = pcm_seek,
- .trunc = pcm_trunc,
- .tell = pcm_tell,
- .read = pcm_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
-};
-
-static const struct ast_format g722_f = {
- .name = "g722",
- .exts = "g722",
- .format = AST_FORMAT_G722,
- .write = pcm_write,
- .seek = pcm_seek,
- .trunc = pcm_trunc,
- .tell = pcm_tell,
- .read = pcm_read,
- .buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
-};
-
-static const struct ast_format au_f = {
- .name = "au",
- .exts = "au",
- .format = AST_FORMAT_ULAW,
- .open = au_open,
- .rewrite = au_rewrite,
- .write = pcm_write,
- .seek = au_seek,
- .trunc = au_trunc,
- .tell = au_tell,
- .read = pcm_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET, /* this many shorts */
-};
-
-static int load_module(void)
-{
- int index;
-
- /* XXX better init ? */
- for (index = 0; index < (sizeof(ulaw_silence) / sizeof(ulaw_silence[0])); index++)
- ulaw_silence[index] = AST_LIN2MU(0);
- for (index = 0; index < (sizeof(alaw_silence) / sizeof(alaw_silence[0])); index++)
- alaw_silence[index] = AST_LIN2A(0);
-
- return ast_format_register(&pcm_f)
- || ast_format_register(&alaw_f)
- || ast_format_register(&au_f)
- || ast_format_register(&g722_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(pcm_f.name)
- || ast_format_unregister(alaw_f.name)
- || ast_format_unregister(au_f.name)
- || ast_format_unregister(g722_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz");
diff --git a/1.4/formats/format_sln.c b/1.4/formats/format_sln.c
deleted file mode 100644
index c8c5cc04b..000000000
--- a/1.4/formats/format_sln.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Anthony Minessale
- * Anthony Minessale (anthmct@yahoo.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.
- */
-
-/*! \file
- *
- * \brief RAW SLINEAR Format
- * \arg File name extensions: sln, raw
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-#define BUF_SIZE 320 /* 320 bytes, 160 samples */
-#define SLIN_SAMPLES 160
-
-static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- /* Send a frame from the file to the appropriate channel */
-
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_SLINEAR;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) < 1) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples = res/2;
- s->fr.datalen = res;
- return &s->fr;
-}
-
-static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res;
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_SLINEAR) {
- ast_log(LOG_WARNING, "Asked to write non-slinear frame (%d)!\n", f->subclass);
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t offset=0,min,cur,max;
-
- min = 0;
- sample_offset <<= 1;
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
- if (whence == SEEK_SET)
- offset = sample_offset;
- else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = sample_offset + cur;
- else if (whence == SEEK_END)
- offset = max - sample_offset;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max)?max:offset;
- }
- /* always protect against seeking past begining. */
- offset = (offset < min)?min:offset;
- return fseeko(fs->f, offset, SEEK_SET);
-}
-
-static int slinear_trunc(struct ast_filestream *fs)
-{
- return ftruncate(fileno(fs->f), ftello(fs->f));
-}
-
-static off_t slinear_tell(struct ast_filestream *fs)
-{
- return ftello(fs->f) / 2;
-}
-
-static const struct ast_format slin_f = {
- .name = "sln",
- .exts = "sln|raw",
- .format = AST_FORMAT_SLINEAR,
- .write = slinear_write,
- .seek = slinear_seek,
- .trunc = slinear_trunc,
- .tell = slinear_tell,
- .read = slinear_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
-};
-
-static int load_module(void)
-{
- return ast_format_register(&slin_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(slin_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw Signed Linear Audio support (SLN)");
diff --git a/1.4/formats/format_vox.c b/1.4/formats/format_vox.c
deleted file mode 100644
index c729f3b5c..000000000
--- a/1.4/formats/format_vox.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Flat, binary, ADPCM vox file format.
- * \arg File name extensions: vox
- *
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-#define BUF_SIZE 80 /* 80 bytes, 160 samples */
-#define VOX_SAMPLES 160
-
-static struct ast_frame *vox_read(struct ast_filestream *s, int *whennext)
-{
- int res;
-
- /* Send a frame from the file to the appropriate channel */
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_ADPCM;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
- if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) < 1) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- *whennext = s->fr.samples = res * 2;
- s->fr.datalen = res;
- return &s->fr;
-}
-
-static int vox_write(struct ast_filestream *s, struct ast_frame *f)
-{
- int res;
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_ADPCM) {
- ast_log(LOG_WARNING, "Asked to write non-ADPCM frame (%d)!\n", f->subclass);
- return -1;
- }
- if ((res = fwrite(f->data, 1, f->datalen, s->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int vox_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t offset=0,min,cur,max,distance;
-
- min = 0;
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
-
- /* have to fudge to frame here, so not fully to sample */
- distance = sample_offset/2;
- if(whence == SEEK_SET)
- offset = distance;
- else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = distance + cur;
- else if(whence == SEEK_END)
- offset = max - distance;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max)?max:offset;
- offset = (offset < min)?min:offset;
- }
- return fseeko(fs->f, offset, SEEK_SET);
-}
-
-static int vox_trunc(struct ast_filestream *fs)
-{
- return ftruncate(fileno(fs->f), ftello(fs->f));
-}
-
-static off_t vox_tell(struct ast_filestream *fs)
-{
- off_t offset;
- offset = ftello(fs->f) << 1;
- return offset;
-}
-
-static const struct ast_format vox_f = {
- .name = "vox",
- .exts = "vox",
- .format = AST_FORMAT_ADPCM,
- .write = vox_write,
- .seek = vox_seek,
- .trunc = vox_trunc,
- .tell = vox_tell,
- .read = vox_read,
- .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
-};
-
-static int load_module(void)
-{
- return ast_format_register(&vox_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(vox_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialogic VOX (ADPCM) File Format");
diff --git a/1.4/formats/format_wav.c b/1.4/formats/format_wav.c
deleted file mode 100644
index df808590f..000000000
--- a/1.4/formats/format_wav.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Work with WAV in the proprietary Microsoft format.
- * Microsoft WAV format (8000hz Signed Linear)
- * \arg File name extension: wav (lower case)
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-/* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-
-#define WAV_BUF_SIZE 320
-
-struct wav_desc { /* format-specific parameters */
- int bytes;
- int needsgain;
- int lasttimeout;
- int maxlen;
- struct timeval last;
-};
-
-#define BLOCKSIZE 160
-
-#define GAIN 0 /* 2^GAIN is the multiple to increase the volume by. The original value of GAIN was 2, or 4x (12 dB),
- * but there were many reports of the clipping of loud signal peaks (issue 5823 for example). */
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define htoll(b) (b)
-#define htols(b) (b)
-#define ltohl(b) (b)
-#define ltohs(b) (b)
-#else
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define htoll(b) \
- (((((b) ) & 0xFF) << 24) | \
- ((((b) >> 8) & 0xFF) << 16) | \
- ((((b) >> 16) & 0xFF) << 8) | \
- ((((b) >> 24) & 0xFF) ))
-#define htols(b) \
- (((((b) ) & 0xFF) << 8) | \
- ((((b) >> 8) & 0xFF) ))
-#define ltohl(b) htoll(b)
-#define ltohs(b) htols(b)
-#else
-#error "Endianess not defined"
-#endif
-#endif
-
-
-static int check_header(FILE *f)
-{
- int type, size, formtype;
- int fmt, hsize;
- short format, chans, bysam, bisam;
- int bysec;
- int freq;
- int data;
- if (fread(&type, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (type)\n");
- return -1;
- }
- if (fread(&size, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (size)\n");
- return -1;
- }
- size = ltohl(size);
- if (fread(&formtype, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (formtype)\n");
- return -1;
- }
- if (memcmp(&type, "RIFF", 4)) {
- ast_log(LOG_WARNING, "Does not begin with RIFF\n");
- return -1;
- }
- if (memcmp(&formtype, "WAVE", 4)) {
- ast_log(LOG_WARNING, "Does not contain WAVE\n");
- return -1;
- }
- if (fread(&fmt, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (fmt)\n");
- return -1;
- }
- if (memcmp(&fmt, "fmt ", 4)) {
- ast_log(LOG_WARNING, "Does not say fmt\n");
- return -1;
- }
- if (fread(&hsize, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (formtype)\n");
- return -1;
- }
- if (ltohl(hsize) < 16) {
- ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
- return -1;
- }
- if (fread(&format, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Read failed (format)\n");
- return -1;
- }
- if (ltohs(format) != 1) {
- ast_log(LOG_WARNING, "Not a wav file %d\n", ltohs(format));
- return -1;
- }
- if (fread(&chans, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Read failed (format)\n");
- return -1;
- }
- if (ltohs(chans) != 1) {
- ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
- return -1;
- }
- if (fread(&freq, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (freq)\n");
- return -1;
- }
- if (ltohl(freq) != DEFAULT_SAMPLE_RATE) {
- ast_log(LOG_WARNING, "Unexpected freqency %d\n", ltohl(freq));
- return -1;
- }
- /* Ignore the byte frequency */
- if (fread(&bysec, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (BYTES_PER_SECOND)\n");
- return -1;
- }
- /* Check bytes per sample */
- if (fread(&bysam, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Read failed (BYTES_PER_SAMPLE)\n");
- return -1;
- }
- if (ltohs(bysam) != 2) {
- ast_log(LOG_WARNING, "Can only handle 16bits per sample: %d\n", ltohs(bysam));
- return -1;
- }
- if (fread(&bisam, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Read failed (Bits Per Sample): %d\n", ltohs(bisam));
- return -1;
- }
- /* Skip any additional header */
- if (fseek(f,ltohl(hsize)-16,SEEK_CUR) == -1 ) {
- ast_log(LOG_WARNING, "Failed to skip remaining header bytes: %d\n", ltohl(hsize)-16 );
- return -1;
- }
- /* Skip any facts and get the first data block */
- for(;;)
- {
- char buf[4];
-
- /* Begin data chunk */
- if (fread(&buf, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (data)\n");
- return -1;
- }
- /* Data has the actual length of data in it */
- if (fread(&data, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (data)\n");
- return -1;
- }
- data = ltohl(data);
- if(memcmp(buf, "data", 4) == 0 )
- break;
- if(memcmp(buf, "fact", 4) != 0 ) {
- ast_log(LOG_WARNING, "Unknown block - not fact or data\n");
- return -1;
- }
- if (fseek(f,data,SEEK_CUR) == -1 ) {
- ast_log(LOG_WARNING, "Failed to skip fact block: %d\n", data );
- return -1;
- }
- }
-#if 0
- curpos = lseek(fd, 0, SEEK_CUR);
- truelength = lseek(fd, 0, SEEK_END);
- lseek(fd, curpos, SEEK_SET);
- truelength -= curpos;
-#endif
- return data;
-}
-
-static int update_header(FILE *f)
-{
- off_t cur,end;
- int datalen,filelen,bytes;
-
- cur = ftello(f);
- fseek(f, 0, SEEK_END);
- end = ftello(f);
- /* data starts 44 bytes in */
- bytes = end - 44;
- datalen = htoll(bytes);
- /* chunk size is bytes of data plus 36 bytes of header */
- filelen = htoll(36 + bytes);
-
- if (cur < 0) {
- ast_log(LOG_WARNING, "Unable to find our position\n");
- return -1;
- }
- if (fseek(f, 4, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to set our position\n");
- return -1;
- }
- if (fwrite(&filelen, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to set write file size\n");
- return -1;
- }
- if (fseek(f, 40, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to set our position\n");
- return -1;
- }
- if (fwrite(&datalen, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to set write datalen\n");
- return -1;
- }
- if (fseeko(f, cur, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to return to position\n");
- return -1;
- }
- return 0;
-}
-
-static int write_header(FILE *f)
-{
- unsigned int hz=htoll(8000);
- unsigned int bhz = htoll(16000);
- unsigned int hs = htoll(16);
- unsigned short fmt = htols(1);
- unsigned short chans = htols(1);
- unsigned short bysam = htols(2);
- unsigned short bisam = htols(16);
- unsigned int size = htoll(0);
- /* Write a wav header, ignoring sizes which will be filled in later */
- fseek(f,0,SEEK_SET);
- if (fwrite("RIFF", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&size, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite("WAVEfmt ", 1, 8, f) != 8) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&hs, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&fmt, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&chans, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&hz, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&bhz, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&bysam, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&bisam, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite("data", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- if (fwrite(&size, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- return 0;
-}
-
-static int wav_open(struct ast_filestream *s)
-{
- /* We don't have any header to read or anything really, but
- if we did, it would go here. We also might want to check
- and be sure it's a valid file. */
- struct wav_desc *tmp = (struct wav_desc *)s->_private;
- if ((tmp->maxlen = check_header(s->f)) < 0)
- return -1;
- return 0;
-}
-
-static int wav_rewrite(struct ast_filestream *s, const char *comment)
-{
- /* We don't have any header to read or anything really, but
- if we did, it would go here. We also might want to check
- and be sure it's a valid file. */
-
- if (write_header(s->f))
- return -1;
- return 0;
-}
-
-static void wav_close(struct ast_filestream *s)
-{
- char zero = 0;
- struct wav_desc *fs = (struct wav_desc *)s->_private;
- /* Pad to even length */
- if (fs->bytes & 0x1)
- fwrite(&zero, 1, 1, s->f);
-}
-
-static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
-{
- int res;
- int samples; /* actual samples read */
- int x;
- short *tmp;
- int bytes = WAV_BUF_SIZE; /* in bytes */
- off_t here;
- /* Send a frame from the file to the appropriate channel */
- struct wav_desc *fs = (struct wav_desc *)s->_private;
-
- here = ftello(s->f);
- if (fs->maxlen - here < bytes) /* truncate if necessary */
- bytes = fs->maxlen - here;
- if (bytes < 0)
- bytes = 0;
-/* ast_log(LOG_DEBUG, "here: %d, maxlen: %d, bytes: %d\n", here, s->maxlen, bytes); */
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_SLINEAR;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, bytes);
-
- if ( (res = fread(s->fr.data, 1, s->fr.datalen, s->f)) <= 0 ) {
- if (res)
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- s->fr.datalen = res;
- s->fr.samples = samples = res / 2;
-
- tmp = (short *)(s->fr.data);
-#if __BYTE_ORDER == __BIG_ENDIAN
- /* file format is little endian so we need to swap */
- for( x = 0; x < samples; x++)
- tmp[x] = (tmp[x] << 8) | ((tmp[x] & 0xff00) >> 8);
-#endif
-
- if (fs->needsgain) {
- for (x=0; x < samples; x++) {
- if (tmp[x] & ((1 << GAIN) - 1)) {
- /* If it has data down low, then it's not something we've artificially increased gain
- on, so we don't need to gain adjust it */
- fs->needsgain = 0;
- break;
- }
- }
- if (fs->needsgain) {
- for (x=0; x < samples; x++)
- tmp[x] = tmp[x] >> GAIN;
- }
- }
-
- *whennext = samples;
- return &s->fr;
-}
-
-static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
-{
- int x;
- short tmp[8000], *tmpi;
- float tmpf;
- struct wav_desc *s = (struct wav_desc *)fs->_private;
- int res;
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_SLINEAR) {
- ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%d)!\n", f->subclass);
- return -1;
- }
- if (f->datalen > sizeof(tmp)) {
- ast_log(LOG_WARNING, "Data length is too long\n");
- return -1;
- }
- if (!f->datalen)
- return -1;
-
-#if 0
- printf("Data Length: %d\n", f->datalen);
-#endif
-
- tmpi = f->data;
- /* Volume adjust here to accomodate */
- for (x=0;x<f->datalen/2;x++) {
- tmpf = ((float)tmpi[x]) * ((float)(1 << GAIN));
- if (tmpf > 32767.0)
- tmpf = 32767.0;
- if (tmpf < -32768.0)
- tmpf = -32768.0;
- tmp[x] = tmpf;
- tmp[x] &= ~((1 << GAIN) - 1);
-
-#if __BYTE_ORDER == __BIG_ENDIAN
- tmp[x] = (tmp[x] << 8) | ((tmp[x] & 0xff00) >> 8);
-#endif
-
- }
- if ((res = fwrite(tmp, 1, f->datalen, fs->f)) != f->datalen ) {
- ast_log(LOG_WARNING, "Bad write (%d): %s\n", res, strerror(errno));
- return -1;
- }
-
- s->bytes += f->datalen;
- update_header(fs->f);
-
- return 0;
-
-}
-
-static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t min, max, cur, offset = 0, samples;
-
- samples = sample_offset * 2; /* SLINEAR is 16 bits mono, so sample_offset * 2 = bytes */
- min = 44; /* wav header is 44 bytes */
- cur = ftello(fs->f);
- fseeko(fs->f, 0, SEEK_END);
- max = ftello(fs->f);
- if (whence == SEEK_SET)
- offset = samples + min;
- else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = samples + cur;
- else if (whence == SEEK_END)
- offset = max - samples;
- if (whence != SEEK_FORCECUR) {
- offset = (offset > max)?max:offset;
- }
- /* always protect the header space. */
- offset = (offset < min)?min:offset;
- return fseeko(fs->f, offset, SEEK_SET);
-}
-
-static int wav_trunc(struct ast_filestream *fs)
-{
- if (ftruncate(fileno(fs->f), ftello(fs->f)))
- return -1;
- return update_header(fs->f);
-}
-
-static off_t wav_tell(struct ast_filestream *fs)
-{
- off_t offset;
- offset = ftello(fs->f);
- /* subtract header size to get samples, then divide by 2 for 16 bit samples */
- return (offset - 44)/2;
-}
-
-static const struct ast_format wav_f = {
- .name = "wav",
- .exts = "wav",
- .format = AST_FORMAT_SLINEAR,
- .open = wav_open,
- .rewrite = wav_rewrite,
- .write = wav_write,
- .seek = wav_seek,
- .trunc = wav_trunc,
- .tell = wav_tell,
- .read = wav_read,
- .close = wav_close,
- .buf_size = WAV_BUF_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct wav_desc),
-};
-
-static int load_module(void)
-{
- return ast_format_register(&wav_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(wav_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Microsoft WAV format (8000Hz Signed Linear)");
diff --git a/1.4/formats/format_wav_gsm.c b/1.4/formats/format_wav_gsm.c
deleted file mode 100644
index 1655cbd21..000000000
--- a/1.4/formats/format_wav_gsm.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Save GSM in the proprietary Microsoft format.
- *
- * Microsoft WAV format (Proprietary GSM)
- * \arg File name extension: WAV,wav49 (Upper case WAV, lower case is another format)
- * This format can be played on Windows systems, used for
- * e-mail attachments mainly.
- * \ingroup formats
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/module.h"
-#include "asterisk/endian.h"
-
-#include "msgsm.h"
-
-/* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
-
-/* Portions of the conversion code are by guido@sienanet.it */
-
-#define GSM_FRAME_SIZE 33
-#define MSGSM_FRAME_SIZE 65
-#define MSGSM_DATA_OFFSET 60 /* offset of data bytes */
-#define GSM_SAMPLES 160 /* samples in a GSM block */
-#define MSGSM_SAMPLES (2*GSM_SAMPLES) /* samples in an MSGSM block */
-
-/* begin binary data: */
-char msgsm_silence[] = /* 65 */
-{0x48,0x17,0xD6,0x84,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49
-,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92
-,0x24,0x09,0x82,0x74,0x61,0x4D,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00
-,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48
-,0x92,0x24,0x49,0x92,0x00};
-/* end binary data. size = 65 bytes */
-
-struct wavg_desc {
- /* Believe it or not, we must decode/recode to account for the
- weird MS format */
- int secondhalf; /* Are we on the second half */
-};
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define htoll(b) (b)
-#define htols(b) (b)
-#define ltohl(b) (b)
-#define ltohs(b) (b)
-#else
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define htoll(b) \
- (((((b) ) & 0xFF) << 24) | \
- ((((b) >> 8) & 0xFF) << 16) | \
- ((((b) >> 16) & 0xFF) << 8) | \
- ((((b) >> 24) & 0xFF) ))
-#define htols(b) \
- (((((b) ) & 0xFF) << 8) | \
- ((((b) >> 8) & 0xFF) ))
-#define ltohl(b) htoll(b)
-#define ltohs(b) htols(b)
-#else
-#error "Endianess not defined"
-#endif
-#endif
-
-
-static int check_header(FILE *f)
-{
- int type, size, formtype;
- int fmt, hsize, fact;
- short format, chans;
- int freq;
- int data;
- if (fread(&type, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (type)\n");
- return -1;
- }
- if (fread(&size, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (size)\n");
- return -1;
- }
- size = ltohl(size);
- if (fread(&formtype, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (formtype)\n");
- return -1;
- }
- if (memcmp(&type, "RIFF", 4)) {
- ast_log(LOG_WARNING, "Does not begin with RIFF\n");
- return -1;
- }
- if (memcmp(&formtype, "WAVE", 4)) {
- ast_log(LOG_WARNING, "Does not contain WAVE\n");
- return -1;
- }
- if (fread(&fmt, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (fmt)\n");
- return -1;
- }
- if (memcmp(&fmt, "fmt ", 4)) {
- ast_log(LOG_WARNING, "Does not say fmt\n");
- return -1;
- }
- if (fread(&hsize, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (formtype)\n");
- return -1;
- }
- if (ltohl(hsize) != 20) {
- ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
- return -1;
- }
- if (fread(&format, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Read failed (format)\n");
- return -1;
- }
- if (ltohs(format) != 49) {
- ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
- return -1;
- }
- if (fread(&chans, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Read failed (format)\n");
- return -1;
- }
- if (ltohs(chans) != 1) {
- ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
- return -1;
- }
- if (fread(&freq, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (freq)\n");
- return -1;
- }
- if (ltohl(freq) != DEFAULT_SAMPLE_RATE) {
- ast_log(LOG_WARNING, "Unexpected freqency %d\n", ltohl(freq));
- return -1;
- }
- /* Ignore the byte frequency */
- if (fread(&freq, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (X_1)\n");
- return -1;
- }
- /* Ignore the two weird fields */
- if (fread(&freq, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
- return -1;
- }
- /* Ignore the byte frequency */
- if (fread(&freq, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (Y_1)\n");
- return -1;
- }
- /* Check for the word fact */
- if (fread(&fact, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (fact)\n");
- return -1;
- }
- if (memcmp(&fact, "fact", 4)) {
- ast_log(LOG_WARNING, "Does not say fact\n");
- return -1;
- }
- /* Ignore the "fact value" */
- if (fread(&fact, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (fact header)\n");
- return -1;
- }
- if (fread(&fact, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (fact value)\n");
- return -1;
- }
- /* Check for the word data */
- if (fread(&data, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (data)\n");
- return -1;
- }
- if (memcmp(&data, "data", 4)) {
- ast_log(LOG_WARNING, "Does not say data\n");
- return -1;
- }
- /* Ignore the data length */
- if (fread(&data, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Read failed (data)\n");
- return -1;
- }
- return 0;
-}
-
-static int update_header(FILE *f)
-{
- off_t cur,end,bytes;
- int datalen, filelen, samples;
-
- cur = ftello(f);
- fseek(f, 0, SEEK_END);
- end = ftello(f);
- /* in a gsm WAV, data starts 60 bytes in */
- bytes = end - MSGSM_DATA_OFFSET;
- samples = htoll(bytes / MSGSM_FRAME_SIZE * MSGSM_SAMPLES);
- datalen = htoll(bytes);
- filelen = htoll(MSGSM_DATA_OFFSET - 8 + bytes);
- if (cur < 0) {
- ast_log(LOG_WARNING, "Unable to find our position\n");
- return -1;
- }
- if (fseek(f, 4, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to set our position\n");
- return -1;
- }
- if (fwrite(&filelen, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write file size\n");
- return -1;
- }
- if (fseek(f, 48, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to set our position\n");
- return -1;
- }
- if (fwrite(&samples, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write samples\n");
- return -1;
- }
- if (fseek(f, 56, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to set our position\n");
- return -1;
- }
- if (fwrite(&datalen, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write datalen\n");
- return -1;
- }
- if (fseeko(f, cur, SEEK_SET)) {
- ast_log(LOG_WARNING, "Unable to return to position\n");
- return -1;
- }
- return 0;
-}
-
-static int write_header(FILE *f)
-{
- /* Samples per second (always 8000 for this format). */
- unsigned int sample_rate = htoll(8000);
- /* Bytes per second (always 1625 for this format). */
- unsigned int byte_sample_rate = htoll(1625);
- /* This is the size of the "fmt " subchunk */
- unsigned int fmtsize = htoll(20);
- /* WAV #49 */
- unsigned short fmt = htols(49);
- /* Mono = 1 channel */
- unsigned short chans = htols(1);
- /* Each block of data is exactly 65 bytes in size. */
- unsigned int block_align = htoll(MSGSM_FRAME_SIZE);
- /* Not actually 2, but rounded up to the nearest bit */
- unsigned short bits_per_sample = htols(2);
- /* Needed for compressed formats */
- unsigned short extra_format = htols(MSGSM_SAMPLES);
- /* This is the size of the "fact" subchunk */
- unsigned int factsize = htoll(4);
- /* Number of samples in the data chunk */
- unsigned int num_samples = htoll(0);
- /* Number of bytes in the data chunk */
- unsigned int size = htoll(0);
- /* Write a GSM header, ignoring sizes which will be filled in later */
-
- /* 0: Chunk ID */
- if (fwrite("RIFF", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 4: Chunk Size */
- if (fwrite(&size, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 8: Chunk Format */
- if (fwrite("WAVE", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 12: Subchunk 1: ID */
- if (fwrite("fmt ", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 16: Subchunk 1: Size (minus 8) */
- if (fwrite(&fmtsize, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 20: Subchunk 1: Audio format (49) */
- if (fwrite(&fmt, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 22: Subchunk 1: Number of channels */
- if (fwrite(&chans, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 24: Subchunk 1: Sample rate */
- if (fwrite(&sample_rate, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 28: Subchunk 1: Byte rate */
- if (fwrite(&byte_sample_rate, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 32: Subchunk 1: Block align */
- if (fwrite(&block_align, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 36: Subchunk 1: Bits per sample */
- if (fwrite(&bits_per_sample, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 38: Subchunk 1: Extra format bytes */
- if (fwrite(&extra_format, 1, 2, f) != 2) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 40: Subchunk 2: ID */
- if (fwrite("fact", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 44: Subchunk 2: Size (minus 8) */
- if (fwrite(&factsize, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 48: Subchunk 2: Number of samples */
- if (fwrite(&num_samples, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 52: Subchunk 3: ID */
- if (fwrite("data", 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- /* 56: Subchunk 3: Size */
- if (fwrite(&size, 1, 4, f) != 4) {
- ast_log(LOG_WARNING, "Unable to write header\n");
- return -1;
- }
- return 0;
-}
-
-static int wav_open(struct ast_filestream *s)
-{
- /* We don't have any header to read or anything really, but
- if we did, it would go here. We also might want to check
- and be sure it's a valid file. */
- struct wavg_desc *fs = (struct wavg_desc *)s->_private;
-
- if (check_header(s->f))
- return -1;
- fs->secondhalf = 0; /* not strictly necessary */
- return 0;
-}
-
-static int wav_rewrite(struct ast_filestream *s, const char *comment)
-{
- /* We don't have any header to read or anything really, but
- if we did, it would go here. We also might want to check
- and be sure it's a valid file. */
-
- if (write_header(s->f))
- return -1;
- return 0;
-}
-
-static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
-{
- /* Send a frame from the file to the appropriate channel */
- struct wavg_desc *fs = (struct wavg_desc *)s->_private;
-
- s->fr.frametype = AST_FRAME_VOICE;
- s->fr.subclass = AST_FORMAT_GSM;
- s->fr.offset = AST_FRIENDLY_OFFSET;
- s->fr.samples = GSM_SAMPLES;
- s->fr.mallocd = 0;
- AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE);
- if (fs->secondhalf) {
- /* Just return a frame based on the second GSM frame */
- s->fr.data = (char *)s->fr.data + GSM_FRAME_SIZE;
- s->fr.offset += GSM_FRAME_SIZE;
- } else {
- /* read and convert */
- unsigned char msdata[MSGSM_FRAME_SIZE];
- int res;
-
- if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
- if (res && (res != 1))
- ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
- return NULL;
- }
- /* Convert from MS format to two real GSM frames */
- conv65(msdata, s->fr.data);
- }
- fs->secondhalf = !fs->secondhalf;
- *whennext = GSM_SAMPLES;
- return &s->fr;
-}
-
-static int wav_write(struct ast_filestream *s, struct ast_frame *f)
-{
- int len;
- int size;
- struct wavg_desc *fs = (struct wavg_desc *)s->_private;
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
- return -1;
- }
- if (f->subclass != AST_FORMAT_GSM) {
- ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
- return -1;
- }
- /* XXX this might fail... if the input is a multiple of MSGSM_FRAME_SIZE
- * we assume it is already in the correct format.
- */
- if (!(f->datalen % MSGSM_FRAME_SIZE)) {
- size = MSGSM_FRAME_SIZE;
- fs->secondhalf = 0;
- } else {
- size = GSM_FRAME_SIZE;
- }
- for (len = 0; len < f->datalen ; len += size) {
- int res;
- unsigned char *src, msdata[MSGSM_FRAME_SIZE];
- if (fs->secondhalf) { /* second half of raw gsm to be converted */
- memcpy(s->buf + GSM_FRAME_SIZE, f->data + len, GSM_FRAME_SIZE);
- conv66((unsigned char *) s->buf, msdata);
- src = msdata;
- fs->secondhalf = 0;
- } else if (size == GSM_FRAME_SIZE) { /* first half of raw gsm */
- memcpy(s->buf, f->data + len, GSM_FRAME_SIZE);
- src = NULL; /* nothing to write */
- fs->secondhalf = 1;
- } else { /* raw msgsm data */
- src = f->data + len;
- }
- if (src && (res = fwrite(src, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
- ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
- return -1;
- }
- update_header(s->f); /* XXX inefficient! */
- }
- return 0;
-}
-
-static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- off_t offset=0, distance, max;
- struct wavg_desc *s = (struct wavg_desc *)fs->_private;
-
- off_t min = MSGSM_DATA_OFFSET;
- off_t cur = ftello(fs->f);
- fseek(fs->f, 0, SEEK_END);
- max = ftello(fs->f); /* XXX ideally, should round correctly */
- /* Compute the distance in bytes, rounded to the block size */
- distance = (sample_offset/MSGSM_SAMPLES) * MSGSM_FRAME_SIZE;
- if (whence == SEEK_SET)
- offset = distance + min;
- else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = distance + cur;
- else if (whence == SEEK_END)
- offset = max - distance;
- /* always protect against seeking past end of header */
- if (offset < min)
- offset = min;
- if (whence != SEEK_FORCECUR) {
- if (offset > max)
- offset = max;
- } else if (offset > max) {
- int i;
- fseek(fs->f, 0, SEEK_END);
- for (i=0; i< (offset - max) / MSGSM_FRAME_SIZE; i++) {
- fwrite(msgsm_silence, 1, MSGSM_FRAME_SIZE, fs->f);
- }
- }
- s->secondhalf = 0;
- return fseeko(fs->f, offset, SEEK_SET);
-}
-
-static int wav_trunc(struct ast_filestream *fs)
-{
- if (ftruncate(fileno(fs->f), ftello(fs->f)))
- return -1;
- return update_header(fs->f);
-}
-
-static off_t wav_tell(struct ast_filestream *fs)
-{
- off_t offset;
- offset = ftello(fs->f);
- /* since this will most likely be used later in play or record, lets stick
- * to that level of resolution, just even frames boundaries */
- return (offset - MSGSM_DATA_OFFSET)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES;
-}
-
-static const struct ast_format wav49_f = {
- .name = "wav49",
- .exts = "WAV|wav49",
- .format = AST_FORMAT_GSM,
- .open = wav_open,
- .rewrite = wav_rewrite,
- .write = wav_write,
- .seek = wav_seek,
- .trunc = wav_trunc,
- .tell = wav_tell,
- .read = wav_read,
- .buf_size = 2*GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET,
- .desc_size = sizeof(struct wavg_desc),
-};
-
-static int load_module(void)
-{
- return ast_format_register(&wav49_f);
-}
-
-static int unload_module(void)
-{
- return ast_format_unregister(wav49_f.name);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Microsoft WAV format (Proprietary GSM)");
diff --git a/1.4/formats/msgsm.h b/1.4/formats/msgsm.h
deleted file mode 100644
index f951cc271..000000000
--- a/1.4/formats/msgsm.h
+++ /dev/null
@@ -1,689 +0,0 @@
-/* Conversion routines derived from code by guido@sienanet.it */
-
-#define GSM_MAGIC 0xD
-
-#ifndef GSM_H
-typedef unsigned char gsm_byte;
-#endif
-typedef unsigned char wav_byte;
-typedef unsigned int uword;
-
-#define readGSM_33(c1) { \
- gsm_byte *c = (c1); \
- LARc[0] = (*c++ & 0xF) << 2; /* 1 */ \
- LARc[0] |= (*c >> 6) & 0x3; \
- LARc[1] = *c++ & 0x3F; \
- LARc[2] = (*c >> 3) & 0x1F; \
- LARc[3] = (*c++ & 0x7) << 2; \
- LARc[3] |= (*c >> 6) & 0x3; \
- LARc[4] = (*c >> 2) & 0xF; \
- LARc[5] = (*c++ & 0x3) << 2; \
- LARc[5] |= (*c >> 6) & 0x3; \
- LARc[6] = (*c >> 3) & 0x7; \
- LARc[7] = *c++ & 0x7; \
- Nc[0] = (*c >> 1) & 0x7F; \
- bc[0] = (*c++ & 0x1) << 1; \
- bc[0] |= (*c >> 7) & 0x1; \
- Mc[0] = (*c >> 5) & 0x3; \
- xmaxc[0] = (*c++ & 0x1F) << 1; \
- xmaxc[0] |= (*c >> 7) & 0x1; \
- xmc[0] = (*c >> 4) & 0x7; \
- xmc[1] = (*c >> 1) & 0x7; \
- xmc[2] = (*c++ & 0x1) << 2; \
- xmc[2] |= (*c >> 6) & 0x3; \
- xmc[3] = (*c >> 3) & 0x7; \
- xmc[4] = *c++ & 0x7; \
- xmc[5] = (*c >> 5) & 0x7; \
- xmc[6] = (*c >> 2) & 0x7; \
- xmc[7] = (*c++ & 0x3) << 1; /* 10 */ \
- xmc[7] |= (*c >> 7) & 0x1; \
- xmc[8] = (*c >> 4) & 0x7; \
- xmc[9] = (*c >> 1) & 0x7; \
- xmc[10] = (*c++ & 0x1) << 2; \
- xmc[10] |= (*c >> 6) & 0x3; \
- xmc[11] = (*c >> 3) & 0x7; \
- xmc[12] = *c++ & 0x7; \
- Nc[1] = (*c >> 1) & 0x7F; \
- bc[1] = (*c++ & 0x1) << 1; \
- bc[1] |= (*c >> 7) & 0x1; \
- Mc[1] = (*c >> 5) & 0x3; \
- xmaxc[1] = (*c++ & 0x1F) << 1; \
- xmaxc[1] |= (*c >> 7) & 0x1; \
- xmc[13] = (*c >> 4) & 0x7; \
- xmc[14] = (*c >> 1) & 0x7; \
- xmc[15] = (*c++ & 0x1) << 2; \
- xmc[15] |= (*c >> 6) & 0x3; \
- xmc[16] = (*c >> 3) & 0x7; \
- xmc[17] = *c++ & 0x7; \
- xmc[18] = (*c >> 5) & 0x7; \
- xmc[19] = (*c >> 2) & 0x7; \
- xmc[20] = (*c++ & 0x3) << 1; \
- xmc[20] |= (*c >> 7) & 0x1; \
- xmc[21] = (*c >> 4) & 0x7; \
- xmc[22] = (*c >> 1) & 0x7; \
- xmc[23] = (*c++ & 0x1) << 2; \
- xmc[23] |= (*c >> 6) & 0x3; \
- xmc[24] = (*c >> 3) & 0x7; \
- xmc[25] = *c++ & 0x7; \
- Nc[2] = (*c >> 1) & 0x7F; \
- bc[2] = (*c++ & 0x1) << 1; /* 20 */ \
- bc[2] |= (*c >> 7) & 0x1; \
- Mc[2] = (*c >> 5) & 0x3; \
- xmaxc[2] = (*c++ & 0x1F) << 1; \
- xmaxc[2] |= (*c >> 7) & 0x1; \
- xmc[26] = (*c >> 4) & 0x7; \
- xmc[27] = (*c >> 1) & 0x7; \
- xmc[28] = (*c++ & 0x1) << 2; \
- xmc[28] |= (*c >> 6) & 0x3; \
- xmc[29] = (*c >> 3) & 0x7; \
- xmc[30] = *c++ & 0x7; \
- xmc[31] = (*c >> 5) & 0x7; \
- xmc[32] = (*c >> 2) & 0x7; \
- xmc[33] = (*c++ & 0x3) << 1; \
- xmc[33] |= (*c >> 7) & 0x1; \
- xmc[34] = (*c >> 4) & 0x7; \
- xmc[35] = (*c >> 1) & 0x7; \
- xmc[36] = (*c++ & 0x1) << 2; \
- xmc[36] |= (*c >> 6) & 0x3; \
- xmc[37] = (*c >> 3) & 0x7; \
- xmc[38] = *c++ & 0x7; \
- Nc[3] = (*c >> 1) & 0x7F; \
- bc[3] = (*c++ & 0x1) << 1; \
- bc[3] |= (*c >> 7) & 0x1; \
- Mc[3] = (*c >> 5) & 0x3; \
- xmaxc[3] = (*c++ & 0x1F) << 1; \
- xmaxc[3] |= (*c >> 7) & 0x1; \
- xmc[39] = (*c >> 4) & 0x7; \
- xmc[40] = (*c >> 1) & 0x7; \
- xmc[41] = (*c++ & 0x1) << 2; \
- xmc[41] |= (*c >> 6) & 0x3; \
- xmc[42] = (*c >> 3) & 0x7; \
- xmc[43] = *c++ & 0x7; /* 30 */ \
- xmc[44] = (*c >> 5) & 0x7; \
- xmc[45] = (*c >> 2) & 0x7; \
- xmc[46] = (*c++ & 0x3) << 1; \
- xmc[46] |= (*c >> 7) & 0x1; \
- xmc[47] = (*c >> 4) & 0x7; \
- xmc[48] = (*c >> 1) & 0x7; \
- xmc[49] = (*c++ & 0x1) << 2; \
- xmc[49] |= (*c >> 6) & 0x3; \
- xmc[50] = (*c >> 3) & 0x7; \
- xmc[51] = *c & 0x7; /* 33 */ \
-}
-
-static inline void conv66(gsm_byte * d, wav_byte * c) {
- gsm_byte frame_chain;
- unsigned int sr;
- unsigned int LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
-
- readGSM_33(d);
- sr = 0;
- sr = (sr >> 6) | (LARc[0] << 10);
- sr = (sr >> 6) | (LARc[1] << 10);
- *c++ = sr >> 4;
- sr = (sr >> 5) | (LARc[2] << 11);
- *c++ = sr >> 7;
- sr = (sr >> 5) | (LARc[3] << 11);
- sr = (sr >> 4) | (LARc[4] << 12);
- *c++ = sr >> 6;
- sr = (sr >> 4) | (LARc[5] << 12);
- sr = (sr >> 3) | (LARc[6] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3) | (LARc[7] << 13);
- sr = (sr >> 7) | (Nc[0] << 9);
- *c++ = sr >> 5;
- sr = (sr >> 2) | (bc[0] << 14);
- sr = (sr >> 2) | (Mc[0] << 14);
- sr = (sr >> 6) | (xmaxc[0] << 10);
- *c++ = sr >> 3;
- sr = (sr >> 3 )|( xmc[0] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[1] << 13);
- sr = (sr >> 3 )|( xmc[2] << 13);
- sr = (sr >> 3 )|( xmc[3] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[4] << 13);
- sr = (sr >> 3 )|( xmc[5] << 13);
- sr = (sr >> 3 )|( xmc[6] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[7] << 13);
- sr = (sr >> 3 )|( xmc[8] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[9] << 13);
- sr = (sr >> 3 )|( xmc[10] << 13);
- sr = (sr >> 3 )|( xmc[11] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[12] << 13);
- sr = (sr >> 7 )|( Nc[1] << 9);
- *c++ = sr >> 5;
- sr = (sr >> 2 )|( bc[1] << 14);
- sr = (sr >> 2 )|( Mc[1] << 14);
- sr = (sr >> 6 )|( xmaxc[1] << 10);
- *c++ = sr >> 3;
- sr = (sr >> 3 )|( xmc[13] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[14] << 13);
- sr = (sr >> 3 )|( xmc[15] << 13);
- sr = (sr >> 3 )|( xmc[16] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[17] << 13);
- sr = (sr >> 3 )|( xmc[18] << 13);
- sr = (sr >> 3 )|( xmc[19] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[20] << 13);
- sr = (sr >> 3 )|( xmc[21] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[22] << 13);
- sr = (sr >> 3 )|( xmc[23] << 13);
- sr = (sr >> 3 )|( xmc[24] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[25] << 13);
- sr = (sr >> 7 )|( Nc[2] << 9);
- *c++ = sr >> 5;
- sr = (sr >> 2 )|( bc[2] << 14);
- sr = (sr >> 2 )|( Mc[2] << 14);
- sr = (sr >> 6 )|( xmaxc[2] << 10);
- *c++ = sr >> 3;
- sr = (sr >> 3 )|( xmc[26] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[27] << 13);
- sr = (sr >> 3 )|( xmc[28] << 13);
- sr = (sr >> 3 )|( xmc[29] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[30] << 13);
- sr = (sr >> 3 )|( xmc[31] << 13);
- sr = (sr >> 3 )|( xmc[32] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[33] << 13);
- sr = (sr >> 3 )|( xmc[34] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[35] << 13);
- sr = (sr >> 3 )|( xmc[36] << 13);
- sr = (sr >> 3 )|( xmc[37] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[38] << 13);
- sr = (sr >> 7 )|( Nc[3] << 9);
- *c++ = sr >> 5;
- sr = (sr >> 2 )|( bc[3] << 14);
- sr = (sr >> 2 )|( Mc[3] << 14);
- sr = (sr >> 6 )|( xmaxc[3] << 10);
- *c++ = sr >> 3;
- sr = (sr >> 3 )|( xmc[39] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[40] << 13);
- sr = (sr >> 3 )|( xmc[41] << 13);
- sr = (sr >> 3 )|( xmc[42] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[43] << 13);
- sr = (sr >> 3 )|( xmc[44] << 13);
- sr = (sr >> 3 )|( xmc[45] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[46] << 13);
- sr = (sr >> 3 )|( xmc[47] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[48] << 13);
- sr = (sr >> 3 )|( xmc[49] << 13);
- sr = (sr >> 3 )|( xmc[50] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[51] << 13);
- sr = sr >> 4;
- *c = sr >> 8;
- frame_chain = *c;
- readGSM_33(d+33); /* puts all the parameters into LARc etc. */
-
-
- sr = 0;
-/* sr = (sr >> 4 )|( s->frame_chain << 12); */
- sr = (sr >> 4 )|( frame_chain << 12);
-
- sr = (sr >> 6 )|( LARc[0] << 10);
- *c++ = sr >> 6;
- sr = (sr >> 6 )|( LARc[1] << 10);
- *c++ = sr >> 8;
- sr = (sr >> 5 )|( LARc[2] << 11);
- sr = (sr >> 5 )|( LARc[3] << 11);
- *c++ = sr >> 6;
- sr = (sr >> 4 )|( LARc[4] << 12);
- sr = (sr >> 4 )|( LARc[5] << 12);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( LARc[6] << 13);
- sr = (sr >> 3 )|( LARc[7] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 7 )|( Nc[0] << 9);
- sr = (sr >> 2 )|( bc[0] << 14);
- *c++ = sr >> 7;
- sr = (sr >> 2 )|( Mc[0] << 14);
- sr = (sr >> 6 )|( xmaxc[0] << 10);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[0] << 13);
- sr = (sr >> 3 )|( xmc[1] << 13);
- sr = (sr >> 3 )|( xmc[2] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[3] << 13);
- sr = (sr >> 3 )|( xmc[4] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[5] << 13);
- sr = (sr >> 3 )|( xmc[6] << 13);
- sr = (sr >> 3 )|( xmc[7] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[8] << 13);
- sr = (sr >> 3 )|( xmc[9] << 13);
- sr = (sr >> 3 )|( xmc[10] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[11] << 13);
- sr = (sr >> 3 )|( xmc[12] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 7 )|( Nc[1] << 9);
- sr = (sr >> 2 )|( bc[1] << 14);
- *c++ = sr >> 7;
- sr = (sr >> 2 )|( Mc[1] << 14);
- sr = (sr >> 6 )|( xmaxc[1] << 10);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[13] << 13);
- sr = (sr >> 3 )|( xmc[14] << 13);
- sr = (sr >> 3 )|( xmc[15] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[16] << 13);
- sr = (sr >> 3 )|( xmc[17] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[18] << 13);
- sr = (sr >> 3 )|( xmc[19] << 13);
- sr = (sr >> 3 )|( xmc[20] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[21] << 13);
- sr = (sr >> 3 )|( xmc[22] << 13);
- sr = (sr >> 3 )|( xmc[23] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[24] << 13);
- sr = (sr >> 3 )|( xmc[25] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 7 )|( Nc[2] << 9);
- sr = (sr >> 2 )|( bc[2] << 14);
- *c++ = sr >> 7;
- sr = (sr >> 2 )|( Mc[2] << 14);
- sr = (sr >> 6 )|( xmaxc[2] << 10);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[26] << 13);
- sr = (sr >> 3 )|( xmc[27] << 13);
- sr = (sr >> 3 )|( xmc[28] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[29] << 13);
- sr = (sr >> 3 )|( xmc[30] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[31] << 13);
- sr = (sr >> 3 )|( xmc[32] << 13);
- sr = (sr >> 3 )|( xmc[33] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[34] << 13);
- sr = (sr >> 3 )|( xmc[35] << 13);
- sr = (sr >> 3 )|( xmc[36] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[37] << 13);
- sr = (sr >> 3 )|( xmc[38] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 7 )|( Nc[3] << 9);
- sr = (sr >> 2 )|( bc[3] << 14);
- *c++ = sr >> 7;
- sr = (sr >> 2 )|( Mc[3] << 14);
- sr = (sr >> 6 )|( xmaxc[3] << 10);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[39] << 13);
- sr = (sr >> 3 )|( xmc[40] << 13);
- sr = (sr >> 3 )|( xmc[41] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[42] << 13);
- sr = (sr >> 3 )|( xmc[43] << 13);
- *c++ = sr >> 8;
- sr = (sr >> 3 )|( xmc[44] << 13);
- sr = (sr >> 3 )|( xmc[45] << 13);
- sr = (sr >> 3 )|( xmc[46] << 13);
- *c++ = sr >> 7;
- sr = (sr >> 3 )|( xmc[47] << 13);
- sr = (sr >> 3 )|( xmc[48] << 13);
- sr = (sr >> 3 )|( xmc[49] << 13);
- *c++ = sr >> 6;
- sr = (sr >> 3 )|( xmc[50] << 13);
- sr = (sr >> 3 )|( xmc[51] << 13);
- *c++ = sr >> 8;
-
-}
-
-#define writeGSM_33(c1) { \
- gsm_byte *c = (c1); \
- *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ \
- | ((LARc[0] >> 2) & 0xF); \
- *c++ = ((LARc[0] & 0x3) << 6) \
- | (LARc[1] & 0x3F); \
- *c++ = ((LARc[2] & 0x1F) << 3) \
- | ((LARc[3] >> 2) & 0x7); \
- *c++ = ((LARc[3] & 0x3) << 6) \
- | ((LARc[4] & 0xF) << 2) \
- | ((LARc[5] >> 2) & 0x3); \
- *c++ = ((LARc[5] & 0x3) << 6) \
- | ((LARc[6] & 0x7) << 3) \
- | (LARc[7] & 0x7); \
- *c++ = ((Nc[0] & 0x7F) << 1) \
- | ((bc[0] >> 1) & 0x1); \
- *c++ = ((bc[0] & 0x1) << 7) \
- | ((Mc[0] & 0x3) << 5) \
- | ((xmaxc[0] >> 1) & 0x1F); \
- *c++ = ((xmaxc[0] & 0x1) << 7) \
- | ((xmc[0] & 0x7) << 4) \
- | ((xmc[1] & 0x7) << 1) \
- | ((xmc[2] >> 2) & 0x1); \
- *c++ = ((xmc[2] & 0x3) << 6) \
- | ((xmc[3] & 0x7) << 3) \
- | (xmc[4] & 0x7); \
- *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ \
- | ((xmc[6] & 0x7) << 2) \
- | ((xmc[7] >> 1) & 0x3); \
- *c++ = ((xmc[7] & 0x1) << 7) \
- | ((xmc[8] & 0x7) << 4) \
- | ((xmc[9] & 0x7) << 1) \
- | ((xmc[10] >> 2) & 0x1); \
- *c++ = ((xmc[10] & 0x3) << 6) \
- | ((xmc[11] & 0x7) << 3) \
- | (xmc[12] & 0x7); \
- *c++ = ((Nc[1] & 0x7F) << 1) \
- | ((bc[1] >> 1) & 0x1); \
- *c++ = ((bc[1] & 0x1) << 7) \
- | ((Mc[1] & 0x3) << 5) \
- | ((xmaxc[1] >> 1) & 0x1F); \
- *c++ = ((xmaxc[1] & 0x1) << 7) \
- | ((xmc[13] & 0x7) << 4) \
- | ((xmc[14] & 0x7) << 1) \
- | ((xmc[15] >> 2) & 0x1); \
- *c++ = ((xmc[15] & 0x3) << 6) \
- | ((xmc[16] & 0x7) << 3) \
- | (xmc[17] & 0x7); \
- *c++ = ((xmc[18] & 0x7) << 5) \
- | ((xmc[19] & 0x7) << 2) \
- | ((xmc[20] >> 1) & 0x3); \
- *c++ = ((xmc[20] & 0x1) << 7) \
- | ((xmc[21] & 0x7) << 4) \
- | ((xmc[22] & 0x7) << 1) \
- | ((xmc[23] >> 2) & 0x1); \
- *c++ = ((xmc[23] & 0x3) << 6) \
- | ((xmc[24] & 0x7) << 3) \
- | (xmc[25] & 0x7); \
- *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ \
- | ((bc[2] >> 1) & 0x1); \
- *c++ = ((bc[2] & 0x1) << 7) \
- | ((Mc[2] & 0x3) << 5) \
- | ((xmaxc[2] >> 1) & 0x1F); \
- *c++ = ((xmaxc[2] & 0x1) << 7) \
- | ((xmc[26] & 0x7) << 4) \
- | ((xmc[27] & 0x7) << 1) \
- | ((xmc[28] >> 2) & 0x1); \
- *c++ = ((xmc[28] & 0x3) << 6) \
- | ((xmc[29] & 0x7) << 3) \
- | (xmc[30] & 0x7); \
- *c++ = ((xmc[31] & 0x7) << 5) \
- | ((xmc[32] & 0x7) << 2) \
- | ((xmc[33] >> 1) & 0x3); \
- *c++ = ((xmc[33] & 0x1) << 7) \
- | ((xmc[34] & 0x7) << 4) \
- | ((xmc[35] & 0x7) << 1) \
- | ((xmc[36] >> 2) & 0x1); \
- *c++ = ((xmc[36] & 0x3) << 6) \
- | ((xmc[37] & 0x7) << 3) \
- | (xmc[38] & 0x7); \
- *c++ = ((Nc[3] & 0x7F) << 1) \
- | ((bc[3] >> 1) & 0x1); \
- *c++ = ((bc[3] & 0x1) << 7) \
- | ((Mc[3] & 0x3) << 5) \
- | ((xmaxc[3] >> 1) & 0x1F); \
- *c++ = ((xmaxc[3] & 0x1) << 7) \
- | ((xmc[39] & 0x7) << 4) \
- | ((xmc[40] & 0x7) << 1) \
- | ((xmc[41] >> 2) & 0x1); \
- *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ \
- | ((xmc[42] & 0x7) << 3) \
- | (xmc[43] & 0x7); \
- *c++ = ((xmc[44] & 0x7) << 5) \
- | ((xmc[45] & 0x7) << 2) \
- | ((xmc[46] >> 1) & 0x3); \
- *c++ = ((xmc[46] & 0x1) << 7) \
- | ((xmc[47] & 0x7) << 4) \
- | ((xmc[48] & 0x7) << 1) \
- | ((xmc[49] >> 2) & 0x1); \
- *c++ = ((xmc[49] & 0x3) << 6) \
- | ((xmc[50] & 0x7) << 3) \
- | (xmc[51] & 0x7); \
-}
-
-static inline void conv65( wav_byte * c, gsm_byte * d){
-
- unsigned int sr = 0;
- unsigned int frame_chain;
- unsigned int LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4];
- /* silence bogus compiler warning */
- unsigned int xmc[13*4] = { 0, };
-
- sr = *c++;
- LARc[0] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 2;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr |= (uword)*c++ << 4;
- LARc[2] = sr & 0x1f; sr >>= 5;
- LARc[3] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 2;
- LARc[4] = sr & 0xf; sr >>= 4;
- LARc[5] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2; /* 5 */
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[0] = sr & 0x7f; sr >>= 7;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
- xmc[0] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[1] = sr & 0x7; sr >>= 3;
- xmc[2] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- xmc[5] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 10 */
- xmc[6] = sr & 0x7; sr >>= 3;
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[9] = sr & 0x7; sr >>= 3;
- xmc[10] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[1] = sr & 0x7f; sr >>= 7;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
- xmc[13] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 15 */
- xmc[14] = sr & 0x7; sr >>= 3;
- xmc[15] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- xmc[18] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[19] = sr & 0x7; sr >>= 3;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[22] = sr & 0x7; sr >>= 3;
- xmc[23] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4; /* 20 */
- Nc[2] = sr & 0x7f; sr >>= 7;
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
- xmc[26] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[27] = sr & 0x7; sr >>= 3;
- xmc[28] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- xmc[31] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[32] = sr & 0x7; sr >>= 3;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 25 */
- xmc[35] = sr & 0x7; sr >>= 3;
- xmc[36] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 4;
- Nc[3] = sr & 0x7f; sr >>= 7;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 1;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
- xmc[39] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[40] = sr & 0x7; sr >>= 3;
- xmc[41] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 30 */
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- xmc[44] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[45] = sr & 0x7; sr >>= 3;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[49] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
-
- frame_chain = sr & 0xf;
-
-
- writeGSM_33(d);/* LARc etc. -> array of 33 GSM bytes */
-
-
- sr = frame_chain;
- sr |= (uword)*c++ << 4; /* 1 */
- LARc[0] = sr & 0x3f; sr >>= 6;
- LARc[1] = sr & 0x3f; sr >>= 6;
- sr = *c++;
- LARc[2] = sr & 0x1f; sr >>= 5;
- sr |= (uword)*c++ << 3;
- LARc[3] = sr & 0x1f; sr >>= 5;
- LARc[4] = sr & 0xf; sr >>= 4;
- sr |= (uword)*c++ << 2;
- LARc[5] = sr & 0xf; sr >>= 4;
- LARc[6] = sr & 0x7; sr >>= 3;
- LARc[7] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 5 */
- Nc[0] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[0] = sr & 0x3; sr >>= 2;
- Mc[0] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[0] = sr & 0x3f; sr >>= 6;
- xmc[0] = sr & 0x7; sr >>= 3;
- xmc[1] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[2] = sr & 0x7; sr >>= 3;
- xmc[3] = sr & 0x7; sr >>= 3;
- xmc[4] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[5] = sr & 0x7; sr >>= 3;
- xmc[6] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2; /* 10 */
- xmc[7] = sr & 0x7; sr >>= 3;
- xmc[8] = sr & 0x7; sr >>= 3;
- xmc[9] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[10] = sr & 0x7; sr >>= 3;
- xmc[11] = sr & 0x7; sr >>= 3;
- xmc[12] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[1] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[1] = sr & 0x3; sr >>= 2;
- Mc[1] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[1] = sr & 0x3f; sr >>= 6;
- xmc[13] = sr & 0x7; sr >>= 3;
- xmc[14] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 15 */
- xmc[15] = sr & 0x7; sr >>= 3;
- xmc[16] = sr & 0x7; sr >>= 3;
- xmc[17] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[18] = sr & 0x7; sr >>= 3;
- xmc[19] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[20] = sr & 0x7; sr >>= 3;
- xmc[21] = sr & 0x7; sr >>= 3;
- xmc[22] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[23] = sr & 0x7; sr >>= 3;
- xmc[24] = sr & 0x7; sr >>= 3;
- xmc[25] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[2] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1; /* 20 */
- bc[2] = sr & 0x3; sr >>= 2;
- Mc[2] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[2] = sr & 0x3f; sr >>= 6;
- xmc[26] = sr & 0x7; sr >>= 3;
- xmc[27] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[28] = sr & 0x7; sr >>= 3;
- xmc[29] = sr & 0x7; sr >>= 3;
- xmc[30] = sr & 0x7; sr >>= 3;
- sr = *c++;
- xmc[31] = sr & 0x7; sr >>= 3;
- xmc[32] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[33] = sr & 0x7; sr >>= 3;
- xmc[34] = sr & 0x7; sr >>= 3;
- xmc[35] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1; /* 25 */
- xmc[36] = sr & 0x7; sr >>= 3;
- xmc[37] = sr & 0x7; sr >>= 3;
- xmc[38] = sr & 0x7; sr >>= 3;
- sr = *c++;
- Nc[3] = sr & 0x7f; sr >>= 7;
- sr |= (uword)*c++ << 1;
- bc[3] = sr & 0x3; sr >>= 2;
- Mc[3] = sr & 0x3; sr >>= 2;
- sr |= (uword)*c++ << 5;
- xmaxc[3] = sr & 0x3f; sr >>= 6;
- xmc[39] = sr & 0x7; sr >>= 3;
- xmc[40] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[41] = sr & 0x7; sr >>= 3;
- xmc[42] = sr & 0x7; sr >>= 3;
- xmc[43] = sr & 0x7; sr >>= 3;
- sr = *c++; /* 30 */
- xmc[44] = sr & 0x7; sr >>= 3;
- xmc[45] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 2;
- xmc[46] = sr & 0x7; sr >>= 3;
- xmc[47] = sr & 0x7; sr >>= 3;
- xmc[48] = sr & 0x7; sr >>= 3;
- sr |= (uword)*c++ << 1;
- xmc[49] = sr & 0x7; sr >>= 3;
- xmc[50] = sr & 0x7; sr >>= 3;
- xmc[51] = sr & 0x7; sr >>= 3;
- writeGSM_33(d+33);
-
-}
diff --git a/1.4/funcs/Makefile b/1.4/funcs/Makefile
deleted file mode 100644
index 7b55e6efb..000000000
--- a/1.4/funcs/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for dialplan functions
-#
-# Copyright (C) 2005-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=FUNCS
-MENUSELECT_DESCRIPTION=Dialplan Functions
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard func_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard func_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_FUNCS),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_FUNCS),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring funcs,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
diff --git a/1.4/funcs/func_base64.c b/1.4/funcs/func_base64.c
deleted file mode 100644
index 463e6dd87..000000000
--- a/1.4/funcs/func_base64.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005 - 2006, Digium, Inc.
- * Copyright (C) 2005, Claude Patry
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Use the base64 as functions
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int base64_encode(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: BASE64_ENCODE(<data>) - missing argument!\n");
- return -1;
- }
-
- ast_base64encode(buf, (unsigned char *) data, strlen(data), len);
-
- return 0;
-}
-
-static int base64_decode(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: BASE64_DECODE(<base_64 string>) - missing argument!\n");
- return -1;
- }
-
- ast_base64decode((unsigned char *) buf, data, len);
-
- return 0;
-}
-
-static struct ast_custom_function base64_encode_function = {
- .name = "BASE64_ENCODE",
- .synopsis = "Encode a string in base64",
- .desc = "Returns the base64 string\n",
- .syntax = "BASE64_ENCODE(<string>)",
- .read = base64_encode,
-};
-
-static struct ast_custom_function base64_decode_function = {
- .name = "BASE64_DECODE",
- .synopsis = "Decode a base64 string",
- .desc = "Returns the plain text string\n",
- .syntax = "BASE64_DECODE(<base64_string>)",
- .read = base64_decode,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&base64_encode_function) |
- ast_custom_function_unregister(&base64_decode_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&base64_encode_function) |
- ast_custom_function_register(&base64_decode_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "base64 encode/decode dialplan functions");
diff --git a/1.4/funcs/func_callerid.c b/1.4/funcs/func_callerid.c
deleted file mode 100644
index ef3c447bb..000000000
--- a/1.4/funcs/func_callerid.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999-2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Caller ID related dialplan functions
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-#include "asterisk/callerid.h"
-
-static int callerid_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- char *opt = data;
-
- if (!chan)
- return -1;
-
- if (strchr(opt, '|')) {
- char name[80], num[80];
-
- data = strsep(&opt, "|");
- ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
-
- if (!strncasecmp("all", data, 3)) {
- snprintf(buf, len, "\"%s\" <%s>", name, num);
- } else if (!strncasecmp("name", data, 4)) {
- ast_copy_string(buf, name, len);
- } else if (!strncasecmp("num", data, 3) ||
- !strncasecmp("number", data, 6)) {
-
- ast_copy_string(buf, num, len);
- } else {
- ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
- }
- } else {
- ast_channel_lock(chan);
-
- if (!strncasecmp("all", data, 3)) {
- snprintf(buf, len, "\"%s\" <%s>",
- S_OR(chan->cid.cid_name, ""),
- S_OR(chan->cid.cid_num, ""));
- } else if (!strncasecmp("name", data, 4)) {
- if (chan->cid.cid_name) {
- ast_copy_string(buf, chan->cid.cid_name, len);
- }
- } else if (!strncasecmp("num", data, 3)
- || !strncasecmp("number", data, 6)) {
- if (chan->cid.cid_num) {
- ast_copy_string(buf, chan->cid.cid_num, len);
- }
- } else if (!strncasecmp("ani", data, 3)) {
- if (chan->cid.cid_ani) {
- ast_copy_string(buf, chan->cid.cid_ani, len);
- }
- } else if (!strncasecmp("dnid", data, 4)) {
- if (chan->cid.cid_dnid) {
- ast_copy_string(buf, chan->cid.cid_dnid, len);
- }
- } else if (!strncasecmp("rdnis", data, 5)) {
- if (chan->cid.cid_rdnis) {
- ast_copy_string(buf, chan->cid.cid_rdnis, len);
- }
- } else {
- ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
- }
-
- ast_channel_unlock(chan);
- }
-
- return 0;
-}
-
-static int callerid_write(struct ast_channel *chan, char *cmd, char *data,
- const char *value)
-{
- if (!value || !chan)
- return -1;
-
- if (!strncasecmp("all", data, 3)) {
- char name[256];
- char num[256];
-
- if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
- ast_set_callerid(chan, num, name, num);
- } else if (!strncasecmp("name", data, 4)) {
- ast_set_callerid(chan, NULL, value, NULL);
- } else if (!strncasecmp("num", data, 3) ||
- !strncasecmp("number", data, 6)) {
- ast_set_callerid(chan, value, NULL, NULL);
- } else if (!strncasecmp("ani", data, 3)) {
- ast_set_callerid(chan, NULL, NULL, value);
- } else if (!strncasecmp("dnid", data, 4)) {
- ast_channel_lock(chan);
- if (chan->cid.cid_dnid)
- free(chan->cid.cid_dnid);
- chan->cid.cid_dnid = ast_strdup(value);
- ast_channel_unlock(chan);
- } else if (!strncasecmp("rdnis", data, 5)) {
- ast_channel_lock(chan);
- if (chan->cid.cid_rdnis)
- free(chan->cid.cid_rdnis);
- chan->cid.cid_rdnis = ast_strdup(value);
- ast_channel_unlock(chan);
- } else {
- ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
- }
-
- return 0;
-}
-
-static struct ast_custom_function callerid_function = {
- .name = "CALLERID",
- .synopsis = "Gets or sets Caller*ID data on the channel.",
- .syntax = "CALLERID(datatype[,<optional-CID>])",
- .desc =
- "Gets or sets Caller*ID data on the channel. The allowable datatypes\n"
- "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\".\n"
- "Uses channel callerid by default or optional callerid, if specified.\n",
- .read = callerid_read,
- .write = callerid_write,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&callerid_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&callerid_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan function");
diff --git a/1.4/funcs/func_cdr.c b/1.4/funcs/func_cdr.c
deleted file mode 100644
index 50efc995d..000000000
--- a/1.4/funcs/func_cdr.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999-2006, Digium, Inc.
- *
- * Portions Copyright (C) 2005, Anthony Minessale II
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Call Detail Record related dialplan functions
- *
- * \author Anthony Minessale II
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/cdr.h"
-
-enum {
- OPT_RECURSIVE = (1 << 0),
- OPT_UNPARSED = (1 << 1),
- OPT_LAST = (1 << 2),
-} cdr_option_flags;
-
-AST_APP_OPTIONS(cdr_func_options, {
- AST_APP_OPTION('l', OPT_LAST),
- AST_APP_OPTION('r', OPT_RECURSIVE),
- AST_APP_OPTION('u', OPT_UNPARSED),
-});
-
-static int cdr_read(struct ast_channel *chan, char *cmd, char *parse,
- char *buf, size_t len)
-{
- char *ret;
- struct ast_flags flags = { 0 };
- struct ast_cdr *cdr = chan ? chan->cdr : NULL;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(variable);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(parse))
- return -1;
-
- if (!cdr)
- return -1;
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (!ast_strlen_zero(args.options))
- ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
-
- if (ast_test_flag(&flags, OPT_LAST))
- while (cdr->next)
- cdr = cdr->next;
-
- ast_cdr_getvar(cdr, args.variable, &ret, buf, len,
- ast_test_flag(&flags, OPT_RECURSIVE),
- ast_test_flag(&flags, OPT_UNPARSED));
-
- return 0;
-}
-
-static int cdr_write(struct ast_channel *chan, char *cmd, char *parse,
- const char *value)
-{
- struct ast_flags flags = { 0 };
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(variable);
- AST_APP_ARG(options);
- );
-
- if (ast_strlen_zero(parse) || !value || !chan)
- return -1;
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (!ast_strlen_zero(args.options))
- ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
-
- if (!strcasecmp(args.variable, "accountcode"))
- ast_cdr_setaccount(chan, value);
- else if (!strcasecmp(args.variable, "userfield"))
- ast_cdr_setuserfield(chan, value);
- else if (!strcasecmp(args.variable, "amaflags"))
- ast_cdr_setamaflags(chan, value);
- else if (chan->cdr)
- ast_cdr_setvar(chan->cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
- /* No need to worry about the u flag, as all fields for which setting
- * 'u' would do anything are marked as readonly. */
-
- return 0;
-}
-
-static struct ast_custom_function cdr_function = {
- .name = "CDR",
- .synopsis = "Gets or sets a CDR variable",
- .syntax = "CDR(<name>[|options])",
- .read = cdr_read,
- .write = cdr_write,
- .desc =
-"Options:\n"
-" 'l' uses the most recent CDR on a channel with multiple records\n"
-" 'r' searches the entire stack of CDRs on the channel\n"
-" 'u' retrieves the raw, unprocessed value\n"
-" For example, 'start', 'answer', and 'end' will be retrieved as epoch\n"
-" values, when the 'u' option is passed, but formatted as YYYY-MM-DD HH:MM:SS\n"
-" otherwise. Similarly, disposition and amaflags will return their raw\n"
-" integral values.\n"
-" Here is a list of all the available cdr field names:\n"
-" clid lastdata disposition\n"
-" src start amaflags\n"
-" dst answer accountcode\n"
-" dcontext end uniqueid\n"
-" dstchannel duration userfield\n"
-" lastapp billsec channel\n"
-" All of the above variables are read-only, except for accountcode,\n"
-" userfield, and amaflags. You may, however, supply\n"
-" a name not on the above list, and create your own\n"
-" variable, whose value can be changed with this function,\n"
-" and this variable will be stored on the cdr.\n"
-" raw values for disposition:\n"
-" 1 = NO ANSWER\n"
-" 2 = BUSY\n"
-" 3 = FAILED\n"
-" 4 = ANSWERED\n"
-" raw values for amaflags:\n"
-" 1 = OMIT\n"
-" 2 = BILLING\n"
-" 3 = DOCUMENTATION\n",
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&cdr_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&cdr_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR dialplan function");
diff --git a/1.4/funcs/func_channel.c b/1.4/funcs/func_channel.c
deleted file mode 100644
index 9184cf955..000000000
--- a/1.4/funcs/func_channel.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Channel info dialplan function
- *
- * \author Kevin P. Fleming <kpfleming@digium.com>
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/indications.h"
-#include "asterisk/stringfields.h"
-
-#define locked_copy_string(chan, dest, source, len) \
- do { \
- ast_channel_lock(chan); \
- ast_copy_string(dest, source, len); \
- ast_channel_unlock(chan); \
- } while (0)
-#define locked_string_field_set(chan, field, source) \
- do { \
- ast_channel_lock(chan); \
- ast_string_field_set(chan, field, source); \
- ast_channel_unlock(chan); \
- } while (0)
-
-char *transfercapability_table[0x20] = {
- "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
- "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
- "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
- "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", };
-
-static int func_channel_read(struct ast_channel *chan, char *function,
- char *data, char *buf, size_t len)
-{
- int ret = 0;
-
- if (!strcasecmp(data, "audionativeformat"))
- /* use the _multiple version when chan->nativeformats holds multiple formats */
- /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_AUDIO_MASK); */
- ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_AUDIO_MASK), len);
- else if (!strcasecmp(data, "videonativeformat"))
- /* use the _multiple version when chan->nativeformats holds multiple formats */
- /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_VIDEO_MASK); */
- ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_VIDEO_MASK), len);
- else if (!strcasecmp(data, "audioreadformat"))
- ast_copy_string(buf, ast_getformatname(chan->readformat), len);
- else if (!strcasecmp(data, "audiowriteformat"))
- ast_copy_string(buf, ast_getformatname(chan->writeformat), len);
- else if (!strcasecmp(data, "tonezone") && chan->zone)
- locked_copy_string(chan, buf, chan->zone->country, len);
- else if (!strcasecmp(data, "language"))
- locked_copy_string(chan, buf, chan->language, len);
- else if (!strcasecmp(data, "musicclass"))
- locked_copy_string(chan, buf, chan->musicclass, len);
- else if (!strcasecmp(data, "state"))
- locked_copy_string(chan, buf, ast_state2str(chan->_state), len);
- else if (!strcasecmp(data, "channeltype"))
- locked_copy_string(chan, buf, chan->tech->type, len);
- else if (!strcasecmp(data, "transfercapability"))
- locked_copy_string(chan, buf, transfercapability_table[chan->transfercapability & 0x1f], len);
- else if (!strcasecmp(data, "callgroup")) {
- char groupbuf[256];
- locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), chan->callgroup), len);
- } else if (!chan->tech->func_channel_read
- || chan->tech->func_channel_read(chan, function, data, buf, len)) {
- ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
- ret = -1;
- }
-
- return ret;
-}
-
-static int func_channel_write(struct ast_channel *chan, char *function,
- char *data, const char *value)
-{
- int ret = 0;
- signed char gainset;
-
- if (!strcasecmp(data, "language"))
- locked_string_field_set(chan, language, value);
- else if (!strcasecmp(data, "musicclass"))
- locked_string_field_set(chan, musicclass, value);
- else if (!strcasecmp(data, "tonezone")) {
- struct tone_zone *new_zone;
- if (!(new_zone = ast_get_indication_zone(value))) {
- ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
- ret = -1;
- } else
- chan->zone = new_zone;
- } else if (!strcasecmp(data, "callgroup"))
- chan->callgroup = ast_get_group(value);
- else if (!strcasecmp(data, "txgain")) {
- sscanf(value, "%hhd", &gainset);
- ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
- } else if (!strcasecmp(data, "rxgain")) {
- sscanf(value, "%hhd", &gainset);
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
- } else if (!strcasecmp(data, "transfercapability")) {
- unsigned short i;
- for (i = 0; i < 0x20; i++) {
- if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
- chan->transfercapability = i;
- break;
- }
- }
- } else if (!chan->tech->func_channel_write
- || chan->tech->func_channel_write(chan, function, data, value)) {
- ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
- data);
- ret = -1;
- }
-
- return ret;
-}
-
-static struct ast_custom_function channel_function = {
- .name = "CHANNEL",
- .synopsis = "Gets/sets various pieces of information about the channel.",
- .syntax = "CHANNEL(item)",
- .desc = "Gets/set various pieces of information about the channel.\n"
- "Standard items (provided by all channel technologies) are:\n"
- "R/O audioreadformat format currently being read\n"
- "R/O audionativeformat format used natively for audio\n"
- "R/O audiowriteformat format currently being written\n"
- "R/W callgroup call groups for call pickup\n"
- "R/O channeltype technology used for channel\n"
- "R/W language language for sounds played\n"
- "R/W musicclass class (from musiconhold.conf) for hold music\n"
- "R/W rxgain set rxgain level on channel drivers that support it\n"
- "R/O state state for channel\n"
- "R/W tonezone zone for indications played\n"
- "R/W txgain set txgain level on channel drivers that support it\n"
- "R/O videonativeformat format used natively for video\n"
- "\n"
- "chan_sip provides the following additional options:\n"
- "R/O rtpqos Get QOS information about the RTP stream\n"
- " This option takes two additional arguments:\n"
- " Argument 1:\n"
- " audio Get data about the audio stream\n"
- " video Get data about the video stream\n"
- " Argument 2:\n"
- " local_ssrc Local SSRC (stream ID)\n"
- " local_lostpackets Local lost packets\n"
- " local_jitter Local calculated jitter\n"
- " local_count Number of received packets\n"
- " remote_ssrc Remote SSRC (stream ID)\n"
- " remote_lostpackets Remote lost packets\n"
- " remote_jitter Remote reported jitter\n"
- " remote_count Number of transmitted packets\n"
- " rtt Round trip time\n"
- " all All statistics (in a form suited to logging, but not for parsing)\n"
- "\n"
- "Additional items may be available from the channel driver providing\n"
- "the channel; see its documentation for details.\n"
- "\n"
- "Any item requested that is not available on the current channel will\n"
- "return an empty string.\n",
- .read = func_channel_read,
- .write = func_channel_write,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&channel_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&channel_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel information dialplan function");
diff --git a/1.4/funcs/func_curl.c b/1.4/funcs/func_curl.c
deleted file mode 100644
index 63d6a0597..000000000
--- a/1.4/funcs/func_curl.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2006, Tilghman Lesher
- *
- * Tilghman Lesher <curl-20050919@the-tilghman.com>
- * and Brian Wilkins <bwilkins@cfl.rr.com> (Added POST option)
- *
- * app_curl.c is distributed with no restrictions on usage or
- * redistribution.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief Curl - Load a URL
- *
- * \author Tilghman Lesher <curl-20050919@the-tilghman.com>
- *
- * \note Brian Wilkins <bwilkins@cfl.rr.com> (Added POST option)
- *
- * \ingroup functions
- */
-
-/*** MODULEINFO
- <depend>curl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <curl/curl.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/cli.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/app.h"
-#include "asterisk/utils.h"
-#include "asterisk/threadstorage.h"
-
-struct MemoryStruct {
- char *memory;
- size_t size;
-};
-
-static void *myrealloc(void *ptr, size_t size)
-{
- /* There might be a realloc() out there that doesn't like reallocing
- NULL pointers, so we take care of it here */
- if (ptr)
- return ast_realloc(ptr, size);
- else
- return ast_malloc(size);
-}
-
-static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
-{
- register int realsize = size * nmemb;
- struct MemoryStruct *mem = (struct MemoryStruct *)data;
-
- mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
- if (mem->memory) {
- memcpy(&(mem->memory[mem->size]), ptr, realsize);
- mem->size += realsize;
- mem->memory[mem->size] = 0;
- }
- return realsize;
-}
-
-static const char *global_useragent = "asterisk-libcurl-agent/1.0";
-
-static void curl_instance_cleanup(void *data)
-{
- CURL **curl = data;
-
- curl_easy_cleanup(*curl);
-}
-
-AST_THREADSTORAGE_CUSTOM(curl_instance, curl_instance_init, curl_instance_cleanup);
-
-static int curl_internal(struct MemoryStruct *chunk, char *url, char *post)
-{
- CURL **curl;
-
- if (!(curl = ast_threadstorage_get(&curl_instance, sizeof(*curl))))
- return -1;
-
- if (!*curl) {
- if (!(*curl = curl_easy_init()))
- return -1;
- curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(*curl, CURLOPT_TIMEOUT, 180);
- curl_easy_setopt(*curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
- curl_easy_setopt(*curl, CURLOPT_USERAGENT, global_useragent);
- }
-
- curl_easy_setopt(*curl, CURLOPT_URL, url);
- curl_easy_setopt(*curl, CURLOPT_WRITEDATA, (void *) chunk);
-
- if (post) {
- curl_easy_setopt(*curl, CURLOPT_POST, 1);
- curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, post);
- }
-
- curl_easy_perform(*curl);
-
- if (post)
- curl_easy_setopt(*curl, CURLOPT_POST, 0);
-
- return 0;
-}
-
-static int acf_curl_exec(struct ast_channel *chan, char *cmd, char *info, char *buf, size_t len)
-{
- struct ast_module_user *u;
- struct MemoryStruct chunk = { NULL, 0 };
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(url);
- AST_APP_ARG(postdata);
- );
-
- *buf = '\0';
-
- if (ast_strlen_zero(info)) {
- ast_log(LOG_WARNING, "CURL requires an argument (URL)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- AST_STANDARD_APP_ARGS(args, info);
-
- if (chan)
- ast_autoservice_start(chan);
-
- if (!curl_internal(&chunk, args.url, args.postdata)) {
- if (chunk.memory) {
- chunk.memory[chunk.size] = '\0';
- if (chunk.memory[chunk.size - 1] == 10)
- chunk.memory[chunk.size - 1] = '\0';
-
- ast_copy_string(buf, chunk.memory, len);
- free(chunk.memory);
- }
- } else {
- ast_log(LOG_ERROR, "Cannot allocate curl structure\n");
- }
-
- if (chan)
- ast_autoservice_stop(chan);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-struct ast_custom_function acf_curl = {
- .name = "CURL",
- .synopsis = "Retrieves the contents of a URL",
- .syntax = "CURL(url[|post-data])",
- .desc =
- " url - URL to retrieve\n"
- " post-data - Optional data to send as a POST (GET is default action)\n",
- .read = acf_curl_exec,
-};
-
-static int unload_module(void)
-{
- int res;
-
- res = ast_custom_function_unregister(&acf_curl);
-
- ast_module_user_hangup_all();
-
- curl_global_cleanup();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res;
-
- if (curl_global_init(CURL_GLOBAL_ALL)) {
- ast_log(LOG_ERROR, "Unable to initialize the CURL library. Cannot load func_curl\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- res = ast_custom_function_register(&acf_curl);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Load external URL");
-
diff --git a/1.4/funcs/func_cut.c b/1.4/funcs/func_cut.c
deleted file mode 100644
index 51b9adc70..000000000
--- a/1.4/funcs/func_cut.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2003-2006 Tilghman Lesher. All rights reserved.
- *
- * Tilghman Lesher <app_cut__v003@the-tilghman.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief CUT function
- *
- * \author Tilghman Lesher <app_cut__v003@the-tilghman.com>
- *
- * \ingroup functions
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/app.h"
-
-/* Maximum length of any variable */
-#define MAXRESULT 1024
-
-struct sortable_keys {
- char *key;
- float value;
-};
-
-static int sort_subroutine(const void *arg1, const void *arg2)
-{
- const struct sortable_keys *one=arg1, *two=arg2;
- if (one->value < two->value)
- return -1;
- else if (one->value == two->value)
- return 0;
- else
- return 1;
-}
-
-#define ERROR_NOARG (-1)
-#define ERROR_NOMEM (-2)
-#define ERROR_USAGE (-3)
-
-static int sort_internal(struct ast_channel *chan, char *data, char *buffer, size_t buflen)
-{
- char *strings, *ptrkey, *ptrvalue;
- int count=1, count2, element_count=0;
- struct sortable_keys *sortable_keys;
-
- memset(buffer, 0, buflen);
-
- if (!data)
- return ERROR_NOARG;
-
- strings = ast_strdupa(data);
-
- for (ptrkey = strings; *ptrkey; ptrkey++) {
- if (*ptrkey == '|')
- count++;
- }
-
- sortable_keys = alloca(count * sizeof(struct sortable_keys));
-
- memset(sortable_keys, 0, count * sizeof(struct sortable_keys));
-
- /* Parse each into a struct */
- count2 = 0;
- while ((ptrkey = strsep(&strings, "|"))) {
- ptrvalue = index(ptrkey, ':');
- if (!ptrvalue) {
- count--;
- continue;
- }
- *ptrvalue++ = '\0';
- sortable_keys[count2].key = ptrkey;
- sscanf(ptrvalue, "%f", &sortable_keys[count2].value);
- count2++;
- }
-
- /* Sort the structs */
- qsort(sortable_keys, count, sizeof(struct sortable_keys), sort_subroutine);
-
- for (count2 = 0; count2 < count; count2++) {
- int blen = strlen(buffer);
- if (element_count++) {
- strncat(buffer + blen, ",", buflen - blen - 1);
- blen++;
- }
- strncat(buffer + blen, sortable_keys[count2].key, buflen - blen - 1);
- }
-
- return 0;
-}
-
-static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size_t buflen)
-{
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(varname);
- AST_APP_ARG(delimiter);
- AST_APP_ARG(field);
- );
-
- memset(buffer, 0, buflen);
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- /* Check and parse arguments */
- if(args.argc < 3){
- return ERROR_NOARG;
- } else {
- char d, ds[2];
- char *tmp = alloca(strlen(args.varname) + 4);
- char varvalue[MAXRESULT], *tmp2=varvalue;
-
- if (tmp) {
- snprintf(tmp, strlen(args.varname) + 4, "${%s}", args.varname);
- memset(varvalue, 0, sizeof(varvalue));
- } else {
- return ERROR_NOMEM;
- }
-
- if (args.delimiter[0] == '\\') {
- if (args.delimiter[1] == 'n')
- d = '\n';
- else if (args.delimiter[1] == 't')
- d = '\t';
- else if (args.delimiter[1] == 'r')
- d = '\r';
- else if (args.delimiter[1])
- d = args.delimiter[1];
- else
- d = '-';
- } else if (args.delimiter[0])
- d = args.delimiter[0];
- else
- d = '-';
-
- /* String form of the delimiter, for use with strsep(3) */
- snprintf(ds, sizeof(ds), "%c", d);
-
- pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);
-
- if (tmp2) {
- int curfieldnum = 1;
- while (tmp2 != NULL && args.field != NULL) {
- char *nextgroup = strsep(&(args.field), "&");
- int num1 = 0, num2 = MAXRESULT;
- char trashchar;
-
- if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) {
- /* range with both start and end */
- } else if (sscanf(nextgroup, "-%d", &num2) == 1) {
- /* range with end */
- num1 = 0;
- } else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) {
- /* range with start */
- num2 = MAXRESULT;
- } else if (sscanf(nextgroup, "%d", &num1) == 1) {
- /* single number */
- num2 = num1;
- } else {
- return ERROR_USAGE;
- }
-
- /* Get to start, if any */
- if (num1 > 0) {
- while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) {
- tmp2 = index(tmp2, d) + 1;
- curfieldnum++;
- }
- }
-
- /* Most frequent problem is the expectation of reordering fields */
- if ((num1 > 0) && (curfieldnum > num1))
- ast_log(LOG_WARNING, "We're already past the field you wanted?\n");
-
- /* Re-null tmp2 if we added 1 to NULL */
- if (tmp2 == (char *)NULL + 1)
- tmp2 = NULL;
-
- /* Output fields until we either run out of fields or num2 is reached */
- while (tmp2 != NULL && curfieldnum <= num2) {
- char *tmp3 = strsep(&tmp2, ds);
- int curlen = strlen(buffer);
-
- if (curlen)
- snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3);
- else
- snprintf(buffer, buflen, "%s", tmp3);
-
- curfieldnum++;
- }
- }
- }
- }
- return 0;
-}
-
-static int acf_sort_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct ast_module_user *u;
- int ret = -1;
-
- u = ast_module_user_add(chan);
-
- switch (sort_internal(chan, data, buf, len)) {
- case ERROR_NOARG:
- ast_log(LOG_ERROR, "SORT() requires an argument\n");
- break;
- case ERROR_NOMEM:
- ast_log(LOG_ERROR, "Out of memory\n");
- break;
- case 0:
- ret = 0;
- break;
- default:
- ast_log(LOG_ERROR, "Unknown internal error\n");
- }
-
- ast_module_user_remove(u);
-
- return ret;
-}
-
-static int acf_cut_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- int ret = -1;
- struct ast_module_user *u = NULL;
-
- if (chan) {
- ast_autoservice_start(chan);
- u = ast_module_user_add(chan);
- }
-
- switch (cut_internal(chan, data, buf, len)) {
- case ERROR_NOARG:
- ast_log(LOG_ERROR, "Syntax: CUT(<varname>,<char-delim>,<range-spec>) - missing argument!\n");
- break;
- case ERROR_NOMEM:
- ast_log(LOG_ERROR, "Out of memory\n");
- break;
- case ERROR_USAGE:
- ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n");
- break;
- case 0:
- ret = 0;
- break;
- default:
- ast_log(LOG_ERROR, "Unknown internal error\n");
- }
-
- if (chan) {
- ast_module_user_remove(u);
- ast_autoservice_stop(chan);
- }
-
- return ret;
-}
-
-struct ast_custom_function acf_sort = {
- .name = "SORT",
- .synopsis = "Sorts a list of key/vals into a list of keys, based upon the vals",
- .syntax = "SORT(key1:val1[...][,keyN:valN])",
- .desc =
-"Takes a comma-separated list of keys and values, each separated by a colon, and returns a\n"
-"comma-separated list of the keys, sorted by their values. Values will be evaluated as\n"
-"floating-point numbers.\n",
- .read = acf_sort_exec,
-};
-
-struct ast_custom_function acf_cut = {
- .name = "CUT",
- .synopsis = "Slices and dices strings, based upon a named delimiter.",
- .syntax = "CUT(<varname>,<char-delim>,<range-spec>)",
- .desc =
-" varname - variable you want cut\n"
-" char-delim - defaults to '-'\n"
-" range-spec - number of the field you want (1-based offset)\n"
-" may also be specified as a range (with -)\n"
-" or group of ranges and fields (with &)\n",
- .read = acf_cut_exec,
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&acf_cut);
- res |= ast_custom_function_unregister(&acf_sort);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&acf_cut);
- res |= ast_custom_function_register(&acf_sort);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Cut out information from a string");
diff --git a/1.4/funcs/func_db.c b/1.4/funcs/func_db.c
deleted file mode 100644
index 13932d27d..000000000
--- a/1.4/funcs/func_db.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005-2006, Russell Bryant <russelb@clemson.edu>
- *
- * func_db.c adapted from the old app_db.c, copyright by the following people
- * Copyright (C) 2005, Mark Spencer <markster@digium.com>
- * Copyright (C) 2003, Jefferson Noxon <jeff@debian.org>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Functions for interaction with the Asterisk database
- *
- * \author Russell Bryant <russelb@clemson.edu>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <regex.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/astdb.h"
-
-static int function_db_read(struct ast_channel *chan, char *cmd,
- char *parse, char *buf, size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(family);
- AST_APP_ARG(key);
- );
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(parse)) {
- ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
- return -1;
- }
-
- AST_NONSTANDARD_APP_ARGS(args, parse, '/');
-
- if (args.argc < 2) {
- ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
- return -1;
- }
-
- if (ast_db_get(args.family, args.key, buf, len - 1)) {
- ast_log(LOG_DEBUG, "DB: %s/%s not found in database.\n", args.family,
- args.key);
- } else
- pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
-
- return 0;
-}
-
-static int function_db_write(struct ast_channel *chan, char *cmd, char *parse,
- const char *value)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(family);
- AST_APP_ARG(key);
- );
-
- if (ast_strlen_zero(parse)) {
- ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=<value>\n");
- return -1;
- }
-
- AST_NONSTANDARD_APP_ARGS(args, parse, '/');
-
- if (args.argc < 2) {
- ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=value\n");
- return -1;
- }
-
- if (ast_db_put(args.family, args.key, (char *) value))
- ast_log(LOG_WARNING, "DB: Error writing value to database.\n");
-
- return 0;
-}
-
-static struct ast_custom_function db_function = {
- .name = "DB",
- .synopsis = "Read from or write to the Asterisk database",
- .syntax = "DB(<family>/<key>)",
- .desc =
-"This function will read from or write a value to the Asterisk database. On a\n"
-"read, this function returns the corresponding value from the database, or blank\n"
-"if it does not exist. Reading a database value will also set the variable\n"
-"DB_RESULT. If you wish to find out if an entry exists, use the DB_EXISTS\n"
-"function.\n",
- .read = function_db_read,
- .write = function_db_write,
-};
-
-static int function_db_exists(struct ast_channel *chan, char *cmd,
- char *parse, char *buf, size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(family);
- AST_APP_ARG(key);
- );
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(parse)) {
- ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
- return -1;
- }
-
- AST_NONSTANDARD_APP_ARGS(args, parse, '/');
-
- if (args.argc < 2) {
- ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
- return -1;
- }
-
- if (ast_db_get(args.family, args.key, buf, len - 1))
- strcpy(buf, "0");
- else {
- pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
- strcpy(buf, "1");
- }
-
- return 0;
-}
-
-static struct ast_custom_function db_exists_function = {
- .name = "DB_EXISTS",
- .synopsis = "Check to see if a key exists in the Asterisk database",
- .syntax = "DB_EXISTS(<family>/<key>)",
- .desc =
- "This function will check to see if a key exists in the Asterisk\n"
- "database. If it exists, the function will return \"1\". If not,\n"
- "it will return \"0\". Checking for existence of a database key will\n"
- "also set the variable DB_RESULT to the key's value if it exists.\n",
- .read = function_db_exists,
-};
-
-static int function_db_delete(struct ast_channel *chan, char* cmd,
- char *parse, char *buf, size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(family);
- AST_APP_ARG(key);
- );
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(parse)) {
- ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
- return -1;
- }
-
- AST_NONSTANDARD_APP_ARGS(args, parse, '/');
-
- if (args.argc < 2) {
- ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
- return -1;
- }
-
- if (ast_db_get(args.family, args.key, buf, len - 1)) {
- ast_log(LOG_DEBUG, "DB_DELETE: %s/%s not found in database.\n", args.family, args.key);
- } else {
- if (ast_db_del(args.family, args.key)) {
- ast_log(LOG_DEBUG, "DB_DELETE: %s/%s could not be deleted from the database\n",
- args.family, args.key);
- }
- }
- pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
-
- return 0;
-}
-
-
-static struct ast_custom_function db_delete_function = {
- .name = "DB_DELETE",
- .synopsis = "Return a value from the database and delete it",
- .syntax = "DB_DELETE(<family>/<key>)",
- .desc =
- "This function will retrieve a value from the Asterisk database\n"
- " and then remove that key from the database. DB_RESULT\n"
- "will be set to the key's value if it exists.\n",
- .read = function_db_delete,
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&db_function);
- res |= ast_custom_function_unregister(&db_exists_function);
- res |= ast_custom_function_unregister(&db_delete_function);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&db_function);
- res |= ast_custom_function_register(&db_exists_function);
- res |= ast_custom_function_register(&db_delete_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Database (astdb) related dialplan functions");
diff --git a/1.4/funcs/func_enum.c b/1.4/funcs/func_enum.c
deleted file mode 100644
index 554937908..000000000
--- a/1.4/funcs/func_enum.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006
- *
- * Mark Spencer <markster@digium.com>
- * Oleksiy Krivoshey <oleksiyk@gmail.com>
- * Russell Bryant <russelb@clemson.edu>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ENUM Functions
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Oleksiy Krivoshey <oleksiyk@gmail.com>
- * \author Russell Bryant <russelb@clemson.edu>
- *
- * \arg See also AstENUM
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/enum.h"
-#include "asterisk/app.h"
-
- static char *synopsis = "Syntax: ENUMLOOKUP(number[|Method-type[|options[|record#[|zone-suffix]]]])\n";
-
-static int function_enum(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(number);
- AST_APP_ARG(tech);
- AST_APP_ARG(options);
- AST_APP_ARG(record);
- AST_APP_ARG(zone);
- );
- int res = 0;
- char tech[80];
- char dest[256] = "", tmp[2] = "", num[AST_MAX_EXTENSION] = "";
- struct ast_module_user *u;
- char *s, *p;
- unsigned int record = 1;
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, synopsis);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, data);
-
- if (args.argc < 1) {
- ast_log(LOG_WARNING, synopsis);
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- ast_copy_string(tech, args.tech ? args.tech : "sip", sizeof(tech));
-
- if (!args.zone)
- args.zone = "e164.arpa";
-
- if (!args.options)
- args.options = "";
-
- if (args.record)
- record = atoi(args.record);
-
- /* strip any '-' signs from number */
- for (s = p = args.number; *s; s++) {
- if (*s != '-') {
- snprintf(tmp, sizeof(tmp), "%c", *s);
- strncat(num, tmp, sizeof(num) - strlen(num) - 1);
- }
-
- }
-
- res = ast_get_enum(chan, num, dest, sizeof(dest), tech, sizeof(tech), args.zone,
- args.options, record);
-
- p = strchr(dest, ':');
- if (p && strcasecmp(tech, "ALL"))
- ast_copy_string(buf, p + 1, len);
- else
- ast_copy_string(buf, dest, len);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static struct ast_custom_function enum_function = {
- .name = "ENUMLOOKUP",
- .synopsis =
- "ENUMLOOKUP allows for general or specific querying of NAPTR records"
- " or counts of NAPTR types for ENUM or ENUM-like DNS pointers",
- .syntax =
- "ENUMLOOKUP(number[|Method-type[|options[|record#[|zone-suffix]]]])",
- .desc =
- "Option 'c' returns an integer count of the number of NAPTRs of a certain RR type.\n"
- "Combination of 'c' and Method-type of 'ALL' will return a count of all NAPTRs for the record.\n"
- "Defaults are: Method-type=sip, no options, record=1, zone-suffix=e164.arpa\n\n"
- "For more information, see doc/enum.txt",
- .read = function_enum,
-};
-
-static int function_txtcidname(struct ast_channel *chan, char *cmd,
- char *data, char *buf, size_t len)
-{
- int res;
- char tech[80];
- char txt[256] = "";
- char dest[80];
- struct ast_module_user *u;
-
- buf[0] = '\0';
-
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "TXTCIDNAME requires an argument (number)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- res = ast_get_txt(chan, data, dest, sizeof(dest), tech, sizeof(tech), txt,
- sizeof(txt));
-
- if (!ast_strlen_zero(txt))
- ast_copy_string(buf, txt, len);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static struct ast_custom_function txtcidname_function = {
- .name = "TXTCIDNAME",
- .synopsis = "TXTCIDNAME looks up a caller name via DNS",
- .syntax = "TXTCIDNAME(<number>)",
- .desc =
- "This function looks up the given phone number in DNS to retrieve\n"
- "the caller id name. The result will either be blank or be the value\n"
- "found in the TXT record in DNS.\n",
- .read = function_txtcidname,
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&enum_function);
- res |= ast_custom_function_unregister(&txtcidname_function);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&enum_function);
- res |= ast_custom_function_register(&txtcidname_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ENUM related dialplan functions");
diff --git a/1.4/funcs/func_env.c b/1.4/funcs/func_env.c
deleted file mode 100644
index 01ec4958d..000000000
--- a/1.4/funcs/func_env.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Environment related dialplan functions
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int env_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- char *ret = NULL;
-
- *buf = '\0';
-
- if (data)
- ret = getenv(data);
-
- if (ret)
- ast_copy_string(buf, ret, len);
-
- return 0;
-}
-
-static int env_write(struct ast_channel *chan, char *cmd, char *data,
- const char *value)
-{
- if (!ast_strlen_zero(data)) {
- if (!ast_strlen_zero(value)) {
- setenv(data, value, 1);
- } else {
- unsetenv(data);
- }
- }
-
- return 0;
-}
-
-static int stat_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- char *action;
- struct stat s;
-
- ast_copy_string(buf, "0", len);
-
- action = strsep(&data, "|");
- if (stat(data, &s)) {
- return 0;
- } else {
- switch (*action) {
- case 'e':
- strcpy(buf, "1");
- break;
- case 's':
- snprintf(buf, len, "%d", (unsigned int) s.st_size);
- break;
- case 'f':
- snprintf(buf, len, "%d", S_ISREG(s.st_mode) ? 1 : 0);
- break;
- case 'd':
- snprintf(buf, len, "%d", S_ISDIR(s.st_mode) ? 1 : 0);
- break;
- case 'M':
- snprintf(buf, len, "%d", (int) s.st_mtime);
- break;
- case 'A':
- snprintf(buf, len, "%d", (int) s.st_mtime);
- break;
- case 'C':
- snprintf(buf, len, "%d", (int) s.st_ctime);
- break;
- case 'm':
- snprintf(buf, len, "%o", (int) s.st_mode);
- break;
- }
- }
-
- return 0;
-}
-
-static struct ast_custom_function env_function = {
- .name = "ENV",
- .synopsis = "Gets or sets the environment variable specified",
- .syntax = "ENV(<envname>)",
- .read = env_read,
- .write = env_write,
-};
-
-static struct ast_custom_function stat_function = {
- .name = "STAT",
- .synopsis = "Does a check on the specified file",
- .syntax = "STAT(<flag>,<filename>)",
- .read = stat_read,
- .desc =
- "flag may be one of the following:\n"
- " d - Checks if the file is a directory\n"
- " e - Checks if the file exists\n"
- " f - Checks if the file is a regular file\n"
- " m - Returns the file mode (in octal)\n"
- " s - Returns the size (in bytes) of the file\n"
- " A - Returns the epoch at which the file was last accessed\n"
- " C - Returns the epoch at which the inode was last changed\n"
- " M - Returns the epoch at which the file was last modified\n",
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&env_function);
- res |= ast_custom_function_unregister(&stat_function);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&env_function);
- res |= ast_custom_function_register(&stat_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Environment/filesystem dialplan functions");
diff --git a/1.4/funcs/func_global.c b/1.4/funcs/func_global.c
deleted file mode 100644
index 50a84afde..000000000
--- a/1.4/funcs/func_global.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Tilghman Lesher
- *
- * Tilghman Lesher <func_global__200605@the-tilghman.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.
- */
-
-/*! \file
- *
- * \brief Global variable dialplan functions
- *
- * \author Tilghman Lesher <func_global__200605@the-tilghman.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/utils.h"
-
-static int global_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- const char *var = pbx_builtin_getvar_helper(NULL, data);
-
- *buf = '\0';
-
- if (var)
- ast_copy_string(buf, var, len);
-
- return 0;
-}
-
-static int global_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
-{
- pbx_builtin_setvar_helper(NULL, data, value);
-
- return 0;
-}
-
-static struct ast_custom_function global_function = {
- .name = "GLOBAL",
- .synopsis = "Gets or sets the global variable specified",
- .syntax = "GLOBAL(<varname>)",
- .read = global_read,
- .write = global_write,
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&global_function);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&global_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Global variable dialplan functions");
diff --git a/1.4/funcs/func_groupcount.c b/1.4/funcs/func_groupcount.c
deleted file mode 100644
index bb2bcf49c..000000000
--- a/1.4/funcs/func_groupcount.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Channel group related dialplan functions
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int group_count_function_read(struct ast_channel *chan, char *cmd,
- char *data, char *buf, size_t len)
-{
- int count = -1;
- char group[80] = "", category[80] = "";
-
- ast_app_group_split_group(data, group, sizeof(group), category,
- sizeof(category));
-
- /* If no group has been provided let's find one */
- if (ast_strlen_zero(group)) {
- struct ast_group_info *gi = NULL;
-
- ast_app_group_list_lock();
- for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, list)) {
- if (gi->chan != chan)
- continue;
- if (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))
- break;
- }
- if (gi) {
- ast_copy_string(group, gi->group, sizeof(group));
- if (!ast_strlen_zero(gi->category))
- ast_copy_string(category, gi->category, sizeof(category));
- }
- ast_app_group_list_unlock();
- }
-
- if ((count = ast_app_group_get_count(group, category)) == -1)
- ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", chan->name);
- else
- snprintf(buf, len, "%d", count);
-
- return 0;
-}
-
-static struct ast_custom_function group_count_function = {
- .name = "GROUP_COUNT",
- .syntax = "GROUP_COUNT([groupname][@category])",
- .synopsis = "Counts the number of channels in the specified group",
- .desc =
- "Calculates the group count for the specified group, or uses the\n"
- "channel's current group if not specifed (and non-empty).\n",
- .read = group_count_function_read,
-};
-
-static int group_match_count_function_read(struct ast_channel *chan,
- char *cmd, char *data, char *buf,
- size_t len)
-{
- int count;
- char group[80] = "";
- char category[80] = "";
-
- ast_app_group_split_group(data, group, sizeof(group), category,
- sizeof(category));
-
- if (!ast_strlen_zero(group)) {
- count = ast_app_group_match_get_count(group, category);
- snprintf(buf, len, "%d", count);
- }
-
- return 0;
-}
-
-static struct ast_custom_function group_match_count_function = {
- .name = "GROUP_MATCH_COUNT",
- .syntax = "GROUP_MATCH_COUNT(groupmatch[@category])",
- .synopsis =
- "Counts the number of channels in the groups matching the specified pattern",
- .desc =
- "Calculates the group count for all groups that match the specified pattern.\n"
- "Uses standard regular expression matching (see regex(7)).\n",
- .read = group_match_count_function_read,
- .write = NULL,
-};
-
-static int group_function_read(struct ast_channel *chan, char *cmd,
- char *data, char *buf, size_t len)
-{
- struct ast_group_info *gi = NULL;
-
- ast_app_group_list_lock();
-
- for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, list)) {
- if (gi->chan != chan)
- continue;
- if (ast_strlen_zero(data))
- break;
- if (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, data))
- break;
- }
-
- if (gi)
- ast_copy_string(buf, gi->group, len);
-
- ast_app_group_list_unlock();
-
- return 0;
-}
-
-static int group_function_write(struct ast_channel *chan, char *cmd,
- char *data, const char *value)
-{
- char grpcat[256];
-
- if (!ast_strlen_zero(data)) {
- snprintf(grpcat, sizeof(grpcat), "%s@%s", value, data);
- } else {
- ast_copy_string(grpcat, value, sizeof(grpcat));
- }
-
- if (ast_app_group_set_channel(chan, grpcat))
- ast_log(LOG_WARNING,
- "Setting a group requires an argument (group name)\n");
-
- return 0;
-}
-
-static struct ast_custom_function group_function = {
- .name = "GROUP",
- .syntax = "GROUP([category])",
- .synopsis = "Gets or sets the channel group.",
- .desc = "Gets or sets the channel group.\n",
- .read = group_function_read,
- .write = group_function_write,
-};
-
-static int group_list_function_read(struct ast_channel *chan, char *cmd,
- char *data, char *buf, size_t len)
-{
- struct ast_group_info *gi = NULL;
- char tmp1[1024] = "";
- char tmp2[1024] = "";
-
- if (!chan)
- return -1;
-
- ast_app_group_list_lock();
-
- for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, list)) {
- if (gi->chan != chan)
- continue;
- if (!ast_strlen_zero(tmp1)) {
- ast_copy_string(tmp2, tmp1, sizeof(tmp2));
- if (!ast_strlen_zero(gi->category))
- snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category);
- else
- snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group);
- } else {
- if (!ast_strlen_zero(gi->category))
- snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category);
- else
- snprintf(tmp1, sizeof(tmp1), "%s", gi->group);
- }
- }
-
- ast_app_group_list_unlock();
-
- ast_copy_string(buf, tmp1, len);
-
- return 0;
-}
-
-static struct ast_custom_function group_list_function = {
- .name = "GROUP_LIST",
- .syntax = "GROUP_LIST()",
- .synopsis = "Gets a list of the groups set on a channel.",
- .desc = "Gets a list of the groups set on a channel.\n",
- .read = group_list_function_read,
- .write = NULL,
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&group_count_function);
- res |= ast_custom_function_unregister(&group_match_count_function);
- res |= ast_custom_function_unregister(&group_list_function);
- res |= ast_custom_function_unregister(&group_function);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&group_count_function);
- res |= ast_custom_function_register(&group_match_count_function);
- res |= ast_custom_function_register(&group_list_function);
- res |= ast_custom_function_register(&group_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel group dialplan functions");
diff --git a/1.4/funcs/func_language.c b/1.4/funcs/func_language.c
deleted file mode 100644
index 43b368f4f..000000000
--- a/1.4/funcs/func_language.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Language related dialplan functions
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/stringfields.h"
-
-static int depwarning = 0;
-
-static int language_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (!depwarning) {
- depwarning = 1;
- ast_log(LOG_WARNING,
- "LANGUAGE() is deprecated; use CHANNEL(language) instead.\n");
- }
-
- ast_copy_string(buf, chan ? chan->language : "", len);
-
- return 0;
-}
-
-static int language_write(struct ast_channel *chan, char *cmd, char *data,
- const char *value)
-{
- if (!depwarning) {
- depwarning = 1;
- ast_log(LOG_WARNING,
- "LANGUAGE() is deprecated; use CHANNEL(language) instead.\n");
- }
-
- if (chan && value)
- ast_string_field_set(chan, language, value);
-
- return 0;
-}
-
-static struct ast_custom_function language_function = {
- .name = "LANGUAGE",
- .synopsis = "Gets or sets the channel's language.",
- .syntax = "LANGUAGE()",
- .desc = "Deprecated. Use CHANNEL(language) instead.\n",
- .read = language_read,
- .write = language_write,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&language_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&language_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel language dialplan function");
diff --git a/1.4/funcs/func_logic.c b/1.4/funcs/func_logic.c
deleted file mode 100644
index c5619fbfe..000000000
--- a/1.4/funcs/func_logic.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- * Portions Copyright (C) 2005, Anthony Minessale II
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Conditional logic dialplan functions
- *
- * \author Anthony Minessale II
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int isnull(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- strcpy(buf, data && *data ? "0" : "1");
-
- return 0;
-}
-
-static int exists(struct ast_channel *chan, char *cmd, char *data, char *buf,
- size_t len)
-{
- strcpy(buf, data && *data ? "1" : "0");
-
- return 0;
-}
-
-static int iftime(struct ast_channel *chan, char *cmd, char *data, char *buf,
- size_t len)
-{
- struct ast_timing timing;
- char *expr;
- char *iftrue;
- char *iffalse;
-
- data = ast_strip_quoted(data, "\"", "\"");
- expr = strsep(&data, "?");
- iftrue = strsep(&data, ":");
- iffalse = data;
-
- if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
- ast_log(LOG_WARNING,
- "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
- return -1;
- }
-
- if (!ast_build_timing(&timing, expr)) {
- ast_log(LOG_WARNING, "Invalid Time Spec.\n");
- return -1;
- }
-
- if (iftrue)
- iftrue = ast_strip_quoted(iftrue, "\"", "\"");
- if (iffalse)
- iffalse = ast_strip_quoted(iffalse, "\"", "\"");
-
- ast_copy_string(buf, ast_check_timing(&timing) ? iftrue : iffalse, len);
-
- return 0;
-}
-
-static int acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf,
- size_t len)
-{
- AST_DECLARE_APP_ARGS(args1,
- AST_APP_ARG(expr);
- AST_APP_ARG(remainder);
- );
- AST_DECLARE_APP_ARGS(args2,
- AST_APP_ARG(iftrue);
- AST_APP_ARG(iffalse);
- );
- args2.iftrue = args2.iffalse = NULL; /* you have to set these, because if there is nothing after the '?',
- then args1.remainder will be NULL, not a pointer to a null string, and
- then any garbage in args2.iffalse will not be cleared, and you'll crash.
- -- and if you mod the ast_app_separate_args func instead, you'll really
- mess things up badly, because the rest of everything depends on null args
- for non-specified stuff. */
-
- AST_NONSTANDARD_APP_ARGS(args1, data, '?');
- AST_NONSTANDARD_APP_ARGS(args2, args1.remainder, ':');
-
- if (ast_strlen_zero(args1.expr) || !(args2.iftrue || args2.iffalse)) {
- ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>]) (expr must be non-null, and either <true> or <false> must be non-null)\n");
- ast_log(LOG_WARNING, " In this case, <expr>='%s', <true>='%s', and <false>='%s'\n", args1.expr, args2.iftrue, args2.iffalse);
- return -1;
- }
-
- args1.expr = ast_strip(args1.expr);
- if (args2.iftrue)
- args2.iftrue = ast_strip(args2.iftrue);
- if (args2.iffalse)
- args2.iffalse = ast_strip(args2.iffalse);
-
- ast_copy_string(buf, pbx_checkcondition(args1.expr) ? (S_OR(args2.iftrue, "")) : (S_OR(args2.iffalse, "")), len);
-
- return 0;
-}
-
-static int set(struct ast_channel *chan, char *cmd, char *data, char *buf,
- size_t len)
-{
- char *varname;
- char *val;
-
- varname = strsep(&data, "=");
- val = data;
-
- if (ast_strlen_zero(varname) || !val) {
- ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
- return -1;
- }
-
- varname = ast_strip(varname);
- val = ast_strip(val);
- pbx_builtin_setvar_helper(chan, varname, val);
- ast_copy_string(buf, val, len);
-
- return 0;
-}
-
-static struct ast_custom_function isnull_function = {
- .name = "ISNULL",
- .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
- .syntax = "ISNULL(<data>)",
- .read = isnull,
-};
-
-static struct ast_custom_function set_function = {
- .name = "SET",
- .synopsis = "SET assigns a value to a channel variable",
- .syntax = "SET(<varname>=[<value>])",
- .read = set,
-};
-
-static struct ast_custom_function exists_function = {
- .name = "EXISTS",
- .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
- .syntax = "EXISTS(<data>)",
- .read = exists,
-};
-
-static struct ast_custom_function if_function = {
- .name = "IF",
- .synopsis =
- "Conditional: Returns the data following '?' if true else the data following ':'",
- .syntax = "IF(<expr>?[<true>][:<false>])",
- .read = acf_if,
-};
-
-static struct ast_custom_function if_time_function = {
- .name = "IFTIME",
- .synopsis =
- "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
- .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
- .read = iftime,
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&isnull_function);
- res |= ast_custom_function_unregister(&set_function);
- res |= ast_custom_function_unregister(&exists_function);
- res |= ast_custom_function_unregister(&if_function);
- res |= ast_custom_function_unregister(&if_time_function);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&isnull_function);
- res |= ast_custom_function_register(&set_function);
- res |= ast_custom_function_register(&exists_function);
- res |= ast_custom_function_register(&if_function);
- res |= ast_custom_function_register(&if_time_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Logical dialplan functions");
diff --git a/1.4/funcs/func_math.c b/1.4/funcs/func_math.c
deleted file mode 100644
index cefc94d93..000000000
--- a/1.4/funcs/func_math.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2006, Andy Powell
- *
- * Updated by 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.
- */
-
-/*! \file
- *
- * \brief Math related dialplan function
- *
- * \author Andy Powell
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/config.h"
-
-enum TypeOfFunctions {
- ADDFUNCTION,
- DIVIDEFUNCTION,
- MULTIPLYFUNCTION,
- SUBTRACTFUNCTION,
- MODULUSFUNCTION,
- GTFUNCTION,
- LTFUNCTION,
- GTEFUNCTION,
- LTEFUNCTION,
- EQFUNCTION
-};
-
-enum TypeOfResult {
- FLOAT_RESULT,
- INT_RESULT,
- HEX_RESULT,
- CHAR_RESULT
-};
-
-static int math(struct ast_channel *chan, char *cmd, char *parse,
- char *buf, size_t len)
-{
- double fnum1;
- double fnum2;
- double ftmp = 0;
- char *op;
- int iaction = -1;
- int type_of_result = FLOAT_RESULT;
- char *mvalue1, *mvalue2 = NULL, *mtype_of_result;
- int negvalue1 = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(argv0);
- AST_APP_ARG(argv1);
- );
-
- if (ast_strlen_zero(parse)) {
- ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.argc < 1) {
- ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
- return -1;
- }
-
- mvalue1 = args.argv0;
-
- if (mvalue1[0] == '-') {
- negvalue1 = 1;
- mvalue1++;
- }
-
- if ((op = strchr(mvalue1, '*'))) {
- iaction = MULTIPLYFUNCTION;
- *op = '\0';
- } else if ((op = strchr(mvalue1, '/'))) {
- iaction = DIVIDEFUNCTION;
- *op = '\0';
- } else if ((op = strchr(mvalue1, '%'))) {
- iaction = MODULUSFUNCTION;
- *op = '\0';
- } else if ((op = strchr(mvalue1, '>'))) {
- iaction = GTFUNCTION;
- *op = '\0';
- if (*(op + 1) == '=') {
- *++op = '\0';
- iaction = GTEFUNCTION;
- }
- } else if ((op = strchr(mvalue1, '<'))) {
- iaction = LTFUNCTION;
- *op = '\0';
- if (*(op + 1) == '=') {
- *++op = '\0';
- iaction = LTEFUNCTION;
- }
- } else if ((op = strchr(mvalue1, '='))) {
- *op = '\0';
- if (*(op + 1) == '=') {
- *++op = '\0';
- iaction = EQFUNCTION;
- } else
- op = NULL;
- } else if ((op = strchr(mvalue1, '+'))) {
- iaction = ADDFUNCTION;
- *op = '\0';
- } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative first number */
- iaction = SUBTRACTFUNCTION;
- *op = '\0';
- }
-
- if (op)
- mvalue2 = op + 1;
-
- /* detect wanted type of result */
- mtype_of_result = args.argv1;
- if (mtype_of_result) {
- if (!strcasecmp(mtype_of_result, "float")
- || !strcasecmp(mtype_of_result, "f"))
- type_of_result = FLOAT_RESULT;
- else if (!strcasecmp(mtype_of_result, "int")
- || !strcasecmp(mtype_of_result, "i"))
- type_of_result = INT_RESULT;
- else if (!strcasecmp(mtype_of_result, "hex")
- || !strcasecmp(mtype_of_result, "h"))
- type_of_result = HEX_RESULT;
- else if (!strcasecmp(mtype_of_result, "char")
- || !strcasecmp(mtype_of_result, "c"))
- type_of_result = CHAR_RESULT;
- else {
- ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n",
- mtype_of_result);
- return -1;
- }
- }
-
- if (!mvalue1 || !mvalue2) {
- ast_log(LOG_WARNING,
- "Supply all the parameters - just this once, please\n");
- return -1;
- }
-
- if (sscanf(mvalue1, "%lf", &fnum1) != 1) {
- ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
- return -1;
- }
-
- if (sscanf(mvalue2, "%lf", &fnum2) != 1) {
- ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
- return -1;
- }
-
- if (negvalue1)
- fnum1 = 0 - fnum1;
-
- switch (iaction) {
- case ADDFUNCTION:
- ftmp = fnum1 + fnum2;
- break;
- case DIVIDEFUNCTION:
- if (fnum2 <= 0)
- ftmp = 0; /* can't do a divide by 0 */
- else
- ftmp = (fnum1 / fnum2);
- break;
- case MULTIPLYFUNCTION:
- ftmp = (fnum1 * fnum2);
- break;
- case SUBTRACTFUNCTION:
- ftmp = (fnum1 - fnum2);
- break;
- case MODULUSFUNCTION:
- {
- int inum1 = fnum1;
- int inum2 = fnum2;
-
- ftmp = (inum1 % inum2);
-
- break;
- }
- case GTFUNCTION:
- ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len);
- break;
- case LTFUNCTION:
- ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len);
- break;
- case GTEFUNCTION:
- ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len);
- break;
- case LTEFUNCTION:
- ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len);
- break;
- case EQFUNCTION:
- ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len);
- break;
- default:
- ast_log(LOG_WARNING,
- "Something happened that neither of us should be proud of %d\n",
- iaction);
- return -1;
- }
-
- if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
- if (type_of_result == FLOAT_RESULT)
- snprintf(buf, len, "%f", ftmp);
- else if (type_of_result == INT_RESULT)
- snprintf(buf, len, "%i", (int) ftmp);
- else if (type_of_result == HEX_RESULT)
- snprintf(buf, len, "%x", (unsigned int) ftmp);
- else if (type_of_result == CHAR_RESULT)
- snprintf(buf, len, "%c", (unsigned char) ftmp);
- }
-
- return 0;
-}
-
-static struct ast_custom_function math_function = {
- .name = "MATH",
- .synopsis = "Performs Mathematical Functions",
- .syntax = "MATH(<number1><op><number 2>[,<type_of_result>])",
- .desc = "Perform calculation on number 1 to number 2. Valid ops are: \n"
- " +,-,/,*,%,<,>,>=,<=,==\n"
- "and behave as their C equivalents.\n"
- "<type_of_result> - wanted type of result:\n"
- " f, float - float(default)\n"
- " i, int - integer,\n"
- " h, hex - hex,\n"
- " c, char - char\n"
- "Example: Set(i=${MATH(123%16,int)}) - sets var i=11",
- .read = math
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&math_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&math_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Mathematical dialplan function");
diff --git a/1.4/funcs/func_md5.c b/1.4/funcs/func_md5.c
deleted file mode 100644
index db6be8f7b..000000000
--- a/1.4/funcs/func_md5.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005-2006, Digium, Inc.
- * Copyright (C) 2005, Olle E. Johansson, Edvina.net
- * Copyright (C) 2005, Russell Bryant <russelb@clemson.edu>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief MD5 digest related dialplan functions
- *
- * \author Olle E. Johansson <oej@edvina.net>
- * \author Russell Bryant <russelb@clemson.edu>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int md5(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: MD5(<data>) - missing argument!\n");
- return -1;
- }
-
- ast_md5_hash(buf, data);
- buf[32] = '\0';
-
- return 0;
-}
-
-static int checkmd5(struct ast_channel *chan, char *cmd, char *parse,
- char *buf, size_t len)
-{
- char newmd5[33];
- static int deprecated = 0;
- AST_DECLARE_APP_ARGS(args, AST_APP_ARG(digest); AST_APP_ARG(data););
-
- if (ast_strlen_zero(parse)) {
- ast_log(LOG_WARNING,
- "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.argc < 2) {
- ast_log(LOG_WARNING,
- "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
- return -1;
- }
-
- if (!deprecated) {
- deprecated = 1;
- ast_log(LOG_WARNING, "CHECK_MD5() is deprecated in Asterisk 1.4 and later.\n");
- }
-
- ast_md5_hash(newmd5, args.data);
-
- if (!strcasecmp(newmd5, args.digest)) /* they match */
- ast_copy_string(buf, "1", len);
- else
- ast_copy_string(buf, "0", len);
-
- return 0;
-}
-
-static struct ast_custom_function md5_function = {
- .name = "MD5",
- .synopsis = "Computes an MD5 digest",
- .syntax = "MD5(<data>)",
- .read = md5,
-};
-
-static struct ast_custom_function checkmd5_function = {
- .name = "CHECK_MD5",
- .synopsis = "Checks an MD5 digest",
- .desc = "Returns 1 on a match, 0 otherwise\n",
- .syntax = "CHECK_MD5(<digest>,<data>)",
- .read = checkmd5,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&md5_function) |
- ast_custom_function_unregister(&checkmd5_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&md5_function) |
- ast_custom_function_register(&checkmd5_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "MD5 digest dialplan functions");
diff --git a/1.4/funcs/func_moh.c b/1.4/funcs/func_moh.c
deleted file mode 100644
index 86701b161..000000000
--- a/1.4/funcs/func_moh.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Russell Bryant <russelb@clemson.edu>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Functions for reading or setting the MusicOnHold class
- *
- * \author Russell Bryant <russelb@clemson.edu>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/utils.h"
-#include "asterisk/stringfields.h"
-
-static int depwarning = 0;
-
-static int moh_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (!depwarning) {
- depwarning = 1;
- ast_log(LOG_WARNING, "MUSICCLASS() is deprecated; use CHANNEL(musicclass) instead.\n");
- }
-
- ast_copy_string(buf, chan ? chan->musicclass : "", len);
-
- return 0;
-}
-
-static int moh_write(struct ast_channel *chan, char *cmd, char *data,
- const char *value)
-{
- if (!depwarning) {
- depwarning = 1;
- ast_log(LOG_WARNING, "MUSICCLASS() is deprecated; use CHANNEL(musicclass) instead.\n");
- }
-
- if (chan)
- ast_string_field_set(chan, musicclass, value);
-
- return 0;
-}
-
-static struct ast_custom_function moh_function = {
- .name = "MUSICCLASS",
- .synopsis = "Read or Set the MusicOnHold class",
- .syntax = "MUSICCLASS()",
- .desc = "Deprecated. Use CHANNEL(musicclass) instead.\n",
- .read = moh_read,
- .write = moh_write,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&moh_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&moh_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Music-on-hold dialplan function");
diff --git a/1.4/funcs/func_odbc.c b/1.4/funcs/func_odbc.c
deleted file mode 100644
index 8bc070767..000000000
--- a/1.4/funcs/func_odbc.c
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (c) 2005, 2006 Tilghman Lesher
- *
- * Tilghman Lesher <func_odbc__200508@the-tilghman.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.
- */
-
-/*!
- * \file
- *
- * \brief ODBC lookups
- *
- * \author Tilghman Lesher <func_odbc__200508@the-tilghman.com>
- */
-
-/*** MODULEINFO
- <depend>unixodbc</depend>
- <depend>ltdl</depend>
- <depend>res_odbc</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/module.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/res_odbc.h"
-#include "asterisk/app.h"
-
-static char *config = "func_odbc.conf";
-
-enum {
- OPT_ESCAPECOMMAS = (1 << 0),
-} odbc_option_flags;
-
-struct acf_odbc_query {
- AST_LIST_ENTRY(acf_odbc_query) list;
- char dsn[30];
- char sql_read[2048];
- char sql_write[2048];
- unsigned int flags;
- struct ast_custom_function *acf;
-};
-
-AST_LIST_HEAD_STATIC(queries, acf_odbc_query);
-
-static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
-{
- int res;
- char *sql = data;
- SQLHSTMT stmt;
-
- res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
- return NULL;
- }
-
- res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
- SQLCloseCursor(stmt);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- return NULL;
- }
-
- return stmt;
-}
-
-/*
- * Master control routine
- */
-static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const char *value)
-{
- struct odbc_obj *obj;
- struct acf_odbc_query *query;
- char *t, buf[2048]="", varname[15];
- int i, bogus_chan = 0;
- AST_DECLARE_APP_ARGS(values,
- AST_APP_ARG(field)[100];
- );
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(field)[100];
- );
- SQLHSTMT stmt;
- SQLLEN rows=0;
-
- AST_LIST_LOCK(&queries);
- AST_LIST_TRAVERSE(&queries, query, list) {
- if (!strcmp(query->acf->name, cmd)) {
- break;
- }
- }
-
- if (!query) {
- ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
- AST_LIST_UNLOCK(&queries);
- return -1;
- }
-
- obj = ast_odbc_request_obj(query->dsn, 0);
-
- if (!obj) {
- ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", query->dsn);
- AST_LIST_UNLOCK(&queries);
- return -1;
- }
-
- if (!chan) {
- if ((chan = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/func_odbc")))
- bogus_chan = 1;
- }
-
- if (chan)
- ast_autoservice_start(chan);
-
- /* Parse our arguments */
- t = value ? ast_strdupa(value) : "";
-
- if (!s || !t) {
- ast_log(LOG_ERROR, "Out of memory\n");
- AST_LIST_UNLOCK(&queries);
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, s);
- for (i = 0; i < args.argc; i++) {
- snprintf(varname, sizeof(varname), "ARG%d", i + 1);
- pbx_builtin_pushvar_helper(chan, varname, args.field[i]);
- }
-
- /* Parse values, just like arguments */
- /* Can't use the pipe, because app Set removes them */
- AST_NONSTANDARD_APP_ARGS(values, t, ',');
- for (i = 0; i < values.argc; i++) {
- snprintf(varname, sizeof(varname), "VAL%d", i + 1);
- pbx_builtin_pushvar_helper(chan, varname, values.field[i]);
- }
-
- /* Additionally set the value as a whole (but push an empty string if value is NULL) */
- pbx_builtin_pushvar_helper(chan, "VALUE", value ? value : "");
-
- pbx_substitute_variables_helper(chan, query->sql_write, buf, sizeof(buf) - 1);
-
- /* Restore prior values */
- for (i = 0; i < args.argc; i++) {
- snprintf(varname, sizeof(varname), "ARG%d", i + 1);
- pbx_builtin_setvar_helper(chan, varname, NULL);
- }
-
- for (i = 0; i < values.argc; i++) {
- snprintf(varname, sizeof(varname), "VAL%d", i + 1);
- pbx_builtin_setvar_helper(chan, varname, NULL);
- }
- pbx_builtin_setvar_helper(chan, "VALUE", NULL);
-
- AST_LIST_UNLOCK(&queries);
-
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, buf);
-
- if (stmt) {
- /* Rows affected */
- SQLRowCount(stmt, &rows);
- }
-
- /* Output the affected rows, for all cases. In the event of failure, we
- * flag this as -1 rows. Note that this is different from 0 affected rows
- * which would be the case if we succeeded in our query, but the values did
- * not change. */
- snprintf(varname, sizeof(varname), "%d", (int)rows);
- pbx_builtin_setvar_helper(chan, "ODBCROWS", varname);
-
- if (stmt) {
- SQLCloseCursor(stmt);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- }
- if (obj)
- ast_odbc_release_obj(obj);
-
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
-
- return 0;
-}
-
-static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf, size_t len)
-{
- struct odbc_obj *obj;
- struct acf_odbc_query *query;
- char sql[2048] = "", varname[15];
- int res, x, buflen = 0, escapecommas, bogus_chan = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(field)[100];
- );
- SQLHSTMT stmt;
- SQLSMALLINT colcount=0;
- SQLLEN indicator;
-
- AST_LIST_LOCK(&queries);
- AST_LIST_TRAVERSE(&queries, query, list) {
- if (!strcmp(query->acf->name, cmd)) {
- break;
- }
- }
-
- if (!query) {
- ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
- AST_LIST_UNLOCK(&queries);
- return -1;
- }
-
- obj = ast_odbc_request_obj(query->dsn, 0);
-
- if (!obj) {
- ast_log(LOG_ERROR, "No such DSN registered (or out of connections): %s (check res_odbc.conf)\n", query->dsn);
- AST_LIST_UNLOCK(&queries);
- return -1;
- }
-
- if (!chan) {
- if ((chan = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/func_odbc")))
- bogus_chan = 1;
- }
-
- if (chan)
- ast_autoservice_start(chan);
-
- AST_STANDARD_APP_ARGS(args, s);
- for (x = 0; x < args.argc; x++) {
- snprintf(varname, sizeof(varname), "ARG%d", x + 1);
- pbx_builtin_pushvar_helper(chan, varname, args.field[x]);
- }
-
- pbx_substitute_variables_helper(chan, query->sql_read, sql, sizeof(sql) - 1);
-
- /* Restore prior values */
- for (x = 0; x < args.argc; x++) {
- snprintf(varname, sizeof(varname), "ARG%d", x + 1);
- pbx_builtin_setvar_helper(chan, varname, NULL);
- }
-
- /* Save this flag, so we can release the lock */
- escapecommas = ast_test_flag(query, OPT_ESCAPECOMMAS);
-
- AST_LIST_UNLOCK(&queries);
-
- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, sql);
-
- if (!stmt) {
- ast_odbc_release_obj(obj);
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
- return -1;
- }
-
- res = SQLNumResultCols(stmt, &colcount);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
- SQLCloseCursor(stmt);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
- return -1;
- }
-
- *buf = '\0';
-
- res = SQLFetch(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- int res1 = -1;
- if (res == SQL_NO_DATA) {
- if (option_verbose > 3) {
- ast_verbose(VERBOSE_PREFIX_4 "Found no rows [%s]\n", sql);
- }
- res1 = 0;
- } else if (option_verbose > 3) {
- ast_log(LOG_WARNING, "Error %d in FETCH [%s]\n", res, sql);
- }
- SQLCloseCursor(stmt);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
- return res1;
- }
-
- for (x = 0; x < colcount; x++) {
- int i;
- char coldata[256];
-
- buflen = strlen(buf);
- res = SQLGetData(stmt, x + 1, SQL_CHAR, coldata, sizeof(coldata), &indicator);
- if (indicator == SQL_NULL_DATA) {
- coldata[0] = '\0';
- res = SQL_SUCCESS;
- }
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLCloseCursor(stmt);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
- return -1;
- }
-
- /* Copy data, encoding '\' and ',' for the argument parser */
- for (i = 0; i < sizeof(coldata); i++) {
- if (escapecommas && (coldata[i] == '\\' || coldata[i] == ',')) {
- buf[buflen++] = '\\';
- }
- buf[buflen++] = coldata[i];
-
- if (buflen >= len - 2)
- break;
-
- if (coldata[i] == '\0')
- break;
- }
-
- buf[buflen - 1] = ',';
- buf[buflen] = '\0';
- }
- /* Trim trailing comma */
- buf[buflen - 1] = '\0';
-
- SQLCloseCursor(stmt);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- if (chan)
- ast_autoservice_stop(chan);
- if (bogus_chan)
- ast_channel_free(chan);
- return 0;
-}
-
-static int acf_escape(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- char *out = buf;
-
- for (; *data && out - buf < len; data++) {
- if (*data == '\'') {
- *out = '\'';
- out++;
- }
- *out++ = *data;
- }
- *out = '\0';
-
- return 0;
-}
-
-static struct ast_custom_function escape_function = {
- .name = "SQL_ESC",
- .synopsis = "Escapes single ticks for use in SQL statements",
- .syntax = "SQL_ESC(<string>)",
- .desc =
-"Used in SQL templates to escape data which may contain single ticks (') which\n"
-"are otherwise used to delimit data. For example:\n"
-"SELECT foo FROM bar WHERE baz='${SQL_ESC(${ARG1})}'\n",
- .read = acf_escape,
- .write = NULL,
-};
-
-static int init_acf_query(struct ast_config *cfg, char *catg, struct acf_odbc_query **query)
-{
- const char *tmp;
-
- if (!cfg || !catg) {
- return -1;
- }
-
- *query = ast_calloc(1, sizeof(struct acf_odbc_query));
- if (! (*query))
- return -1;
-
- if ((tmp = ast_variable_retrieve(cfg, catg, "dsn"))) {
- ast_copy_string((*query)->dsn, tmp, sizeof((*query)->dsn));
- } else {
- free(*query);
- *query = NULL;
- return -1;
- }
-
- if ((tmp = ast_variable_retrieve(cfg, catg, "read"))) {
- ast_copy_string((*query)->sql_read, tmp, sizeof((*query)->sql_read));
- }
-
- if ((tmp = ast_variable_retrieve(cfg, catg, "write"))) {
- ast_copy_string((*query)->sql_write, tmp, sizeof((*query)->sql_write));
- }
-
- /* Allow escaping of embedded commas in fields to be turned off */
- ast_set_flag((*query), OPT_ESCAPECOMMAS);
- if ((tmp = ast_variable_retrieve(cfg, catg, "escapecommas"))) {
- if (ast_false(tmp))
- ast_clear_flag((*query), OPT_ESCAPECOMMAS);
- }
-
- (*query)->acf = ast_calloc(1, sizeof(struct ast_custom_function));
- if (! (*query)->acf) {
- free(*query);
- *query = NULL;
- return -1;
- }
-
- if ((tmp = ast_variable_retrieve(cfg, catg, "prefix")) && !ast_strlen_zero(tmp)) {
- asprintf((char **)&((*query)->acf->name), "%s_%s", tmp, catg);
- } else {
- asprintf((char **)&((*query)->acf->name), "ODBC_%s", catg);
- }
-
- if (!((*query)->acf->name)) {
- free((*query)->acf);
- free(*query);
- *query = NULL;
- return -1;
- }
-
- asprintf((char **)&((*query)->acf->syntax), "%s(<arg1>[...[,<argN>]])", (*query)->acf->name);
-
- if (!((*query)->acf->syntax)) {
- free((char *)(*query)->acf->name);
- free((*query)->acf);
- free(*query);
- *query = NULL;
- return -1;
- }
-
- (*query)->acf->synopsis = "Runs the referenced query with the specified arguments";
- if (!ast_strlen_zero((*query)->sql_read) && !ast_strlen_zero((*query)->sql_write)) {
- asprintf((char **)&((*query)->acf->desc),
- "Runs the following query, as defined in func_odbc.conf, performing\n"
- "substitution of the arguments into the query as specified by ${ARG1},\n"
- "${ARG2}, ... ${ARGn}. When setting the function, the values are provided\n"
- "either in whole as ${VALUE} or parsed as ${VAL1}, ${VAL2}, ... ${VALn}.\n"
- "\nRead:\n%s\n\nWrite:\n%s\n",
- (*query)->sql_read,
- (*query)->sql_write);
- } else if (!ast_strlen_zero((*query)->sql_read)) {
- asprintf((char **)&((*query)->acf->desc),
- "Runs the following query, as defined in func_odbc.conf, performing\n"
- "substitution of the arguments into the query as specified by ${ARG1},\n"
- "${ARG2}, ... ${ARGn}. This function may only be read, not set.\n\nSQL:\n%s\n",
- (*query)->sql_read);
- } else if (!ast_strlen_zero((*query)->sql_write)) {
- asprintf((char **)&((*query)->acf->desc),
- "Runs the following query, as defined in func_odbc.conf, performing\n"
- "substitution of the arguments into the query as specified by ${ARG1},\n"
- "${ARG2}, ... ${ARGn}. The values are provided either in whole as\n"
- "${VALUE} or parsed as ${VAL1}, ${VAL2}, ... ${VALn}.\n"
- "This function may only be set.\nSQL:\n%s\n",
- (*query)->sql_write);
- }
-
- /* Could be out of memory, or could be we have neither sql_read nor sql_write */
- if (! ((*query)->acf->desc)) {
- free((char *)(*query)->acf->syntax);
- free((char *)(*query)->acf->name);
- free((*query)->acf);
- free(*query);
- *query = NULL;
- return -1;
- }
-
- if (ast_strlen_zero((*query)->sql_read)) {
- (*query)->acf->read = NULL;
- } else {
- (*query)->acf->read = acf_odbc_read;
- }
-
- if (ast_strlen_zero((*query)->sql_write)) {
- (*query)->acf->write = NULL;
- } else {
- (*query)->acf->write = acf_odbc_write;
- }
-
- return 0;
-}
-
-static int free_acf_query(struct acf_odbc_query *query)
-{
- if (query) {
- if (query->acf) {
- if (query->acf->name)
- free((char *)query->acf->name);
- if (query->acf->syntax)
- free((char *)query->acf->syntax);
- if (query->acf->desc)
- free((char *)query->acf->desc);
- free(query->acf);
- }
- free(query);
- }
- return 0;
-}
-
-static int odbc_load_module(void)
-{
- int res = 0;
- struct ast_config *cfg;
- char *catg;
-
- AST_LIST_LOCK(&queries);
-
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config for func_odbc: %s\n", config);
- AST_LIST_UNLOCK(&queries);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- for (catg = ast_category_browse(cfg, NULL);
- catg;
- catg = ast_category_browse(cfg, catg)) {
- struct acf_odbc_query *query = NULL;
-
- if (init_acf_query(cfg, catg, &query)) {
- free_acf_query(query);
- } else {
- AST_LIST_INSERT_HEAD(&queries, query, list);
- ast_custom_function_register(query->acf);
- }
- }
-
- ast_config_destroy(cfg);
- ast_custom_function_register(&escape_function);
-
- AST_LIST_UNLOCK(&queries);
- return res;
-}
-
-static int odbc_unload_module(void)
-{
- struct acf_odbc_query *query;
-
- AST_LIST_LOCK(&queries);
- while (!AST_LIST_EMPTY(&queries)) {
- query = AST_LIST_REMOVE_HEAD(&queries, list);
- ast_custom_function_unregister(query->acf);
- free_acf_query(query);
- }
-
- ast_custom_function_unregister(&escape_function);
-
- /* Allow any threads waiting for this lock to pass (avoids a race) */
- AST_LIST_UNLOCK(&queries);
- AST_LIST_LOCK(&queries);
-
- AST_LIST_UNLOCK(&queries);
- return 0;
-}
-
-static int reload(void)
-{
- int res = 0;
- struct ast_config *cfg;
- struct acf_odbc_query *oldquery;
- char *catg;
-
- AST_LIST_LOCK(&queries);
-
- while (!AST_LIST_EMPTY(&queries)) {
- oldquery = AST_LIST_REMOVE_HEAD(&queries, list);
- ast_custom_function_unregister(oldquery->acf);
- free_acf_query(oldquery);
- }
-
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_WARNING, "Unable to load config for func_odbc: %s\n", config);
- goto reload_out;
- }
-
- for (catg = ast_category_browse(cfg, NULL);
- catg;
- catg = ast_category_browse(cfg, catg)) {
- struct acf_odbc_query *query = NULL;
-
- if (init_acf_query(cfg, catg, &query)) {
- ast_log(LOG_ERROR, "Cannot initialize query %s\n", catg);
- } else {
- AST_LIST_INSERT_HEAD(&queries, query, list);
- ast_custom_function_register(query->acf);
- }
- }
-
- ast_config_destroy(cfg);
-reload_out:
- AST_LIST_UNLOCK(&queries);
- return res;
-}
-
-static int unload_module(void)
-{
- return odbc_unload_module();
-}
-
-static int load_module(void)
-{
- return odbc_load_module();
-}
-
-/* XXX need to revise usecount - set if query_lock is set */
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ODBC lookups",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
diff --git a/1.4/funcs/func_rand.c b/1.4/funcs/func_rand.c
deleted file mode 100644
index 53952d341..000000000
--- a/1.4/funcs/func_rand.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- * Copyright (C) 2006, Claude Patry
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Generate Random Number
- *
- * \author Claude Patry <cpatry@gmail.com>
- * \author Tilghman Lesher ( http://asterisk.drunkcoder.com/ )
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int acf_rand_exec(struct ast_channel *chan, char *cmd,
- char *parse, char *buffer, size_t buflen)
-{
- struct ast_module_user *u;
- int min_int, response_int, max_int;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(min);
- AST_APP_ARG(max);
- );
-
- u = ast_module_user_add(chan);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.min) || sscanf(args.min, "%d", &min_int) != 1)
- min_int = 0;
-
- if (ast_strlen_zero(args.max) || sscanf(args.max, "%d", &max_int) != 1)
- max_int = RAND_MAX;
-
- if (max_int < min_int) {
- int tmp = max_int;
-
- max_int = min_int;
- min_int = tmp;
- ast_log(LOG_DEBUG, "max<min\n");
- }
-
- response_int = min_int + (ast_random() % (max_int - min_int + 1));
- ast_log(LOG_DEBUG, "%d was the lucky number in range [%d,%d]\n",
- response_int, min_int, max_int);
- snprintf(buffer, buflen, "%d", response_int);
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static struct ast_custom_function acf_rand = {
- .name = "RAND",
- .synopsis = "Choose a random number in a range",
- .syntax = "RAND([min][|max])",
- .desc =
- "Choose a random number between min and max. Min defaults to 0, if not\n"
- "specified, while max defaults to RAND_MAX (2147483647 on many systems).\n"
- " Example: Set(junky=${RAND(1|8)}); \n"
- " Sets junky to a random number between 1 and 8, inclusive.\n",
- .read = acf_rand_exec,
-};
-
-static int unload_module(void)
-{
- ast_custom_function_unregister(&acf_rand);
-
- return 0;
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&acf_rand);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Random number dialplan function");
diff --git a/1.4/funcs/func_realtime.c b/1.4/funcs/func_realtime.c
deleted file mode 100644
index 6442190e4..000000000
--- a/1.4/funcs/func_realtime.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005-2006, BJ Weschke. All rights reserved.
- *
- * BJ Weschke <bweschke@btwtech.com>
- *
- * This code is released by the author with no restrictions on usage.
- *
- * 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.
- *
- */
-
-/*! \file
- *
- * \brief REALTIME dialplan function
- *
- * \author BJ Weschke <bweschke@btwtech.com>
- *
- * \ingroup functions
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/file.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int function_realtime_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct ast_variable *var, *head;
- struct ast_module_user *u;
- char *results, *result_begin;
- size_t resultslen = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(family);
- AST_APP_ARG(fieldmatch);
- AST_APP_ARG(value);
- AST_APP_ARG(delim1);
- AST_APP_ARG(delim2);
- );
-
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: REALTIME(family|fieldmatch[|value[|delim1[|delim2]]]) - missing argument!\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- AST_STANDARD_APP_ARGS(args, data);
-
- if (!args.delim1)
- args.delim1 = "|";
- if (!args.delim2)
- args.delim2 = "=";
-
- if (chan)
- ast_autoservice_start(chan);
-
- head = ast_load_realtime(args.family, args.fieldmatch, args.value, NULL);
-
- if (!head) {
- ast_module_user_remove(u);
- if (chan)
- ast_autoservice_stop(chan);
- return -1;
- }
- for (var = head; var; var = var->next)
- resultslen += strlen(var->name) + strlen(var->value) + 2;
-
- result_begin = results = alloca(resultslen);
- for (var = head; var; var = var->next)
- ast_build_string(&results, &resultslen, "%s%s%s%s", var->name, args.delim2, var->value, args.delim1);
- ast_copy_string(buf, result_begin, len);
-
- ast_module_user_remove(u);
-
- if (chan)
- ast_autoservice_stop(chan);
-
- return 0;
-}
-
-static int function_realtime_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
-{
- struct ast_module_user *u = NULL;
- int res = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(family);
- AST_APP_ARG(fieldmatch);
- AST_APP_ARG(value);
- AST_APP_ARG(field);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: REALTIME(family|fieldmatch|value|newcol) - missing argument!\n");
- return -1;
- }
-
- if (chan) {
- ast_autoservice_start(chan);
- u = ast_module_user_add(chan);
- }
-
- AST_STANDARD_APP_ARGS(args, data);
-
- res = ast_update_realtime(args.family, args.fieldmatch, args.value, args.field, (char *)value, NULL);
-
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to update. Check the debug log for possible data repository related entries.\n");
- }
-
- if (chan) {
- ast_module_user_remove(u);
- ast_autoservice_stop(chan);
- }
-
- return 0;
-}
-
-struct ast_custom_function realtime_function = {
- .name = "REALTIME",
- .synopsis = "RealTime Read/Write Functions",
- .syntax = "REALTIME(family|fieldmatch[|value[|delim1[|delim2]]]) on read\n"
- "REALTIME(family|fieldmatch|value|field) on write\n",
- .desc = "This function will read or write values from/to a RealTime repository.\n"
- "REALTIME(....) will read names/values from the repository, and \n"
- "REALTIME(....)= will write a new value/field to the repository. On a\n"
- "read, this function returns a delimited text string. The name/value \n"
- "pairs are delimited by delim1, and the name and value are delimited \n"
- "between each other with delim2. The default for delim1 is '|' and \n"
- "the default for delim2 is '='. If there is no match, NULL will be \n"
- "returned by the function. On a write, this function will always \n"
- "return NULL. \n",
- .read = function_realtime_read,
- .write = function_realtime_write,
-};
-
-static int unload_module(void)
-{
- int res = ast_custom_function_unregister(&realtime_function);
-
- ast_module_user_hangup_all();
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = ast_custom_function_register(&realtime_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Read/Write values from a RealTime repository");
diff --git a/1.4/funcs/func_sha1.c b/1.4/funcs/func_sha1.c
deleted file mode 100644
index 01c7eb023..000000000
--- a/1.4/funcs/func_sha1.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- * Copyright (C) 2006, Claude Patry
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief SHA1 digest related dialplan functions
- *
- * \author Claude Patry <cpatry@gmail.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-static int sha1(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- *buf = '\0';
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: SHA1(<data>) - missing argument!\n");
- return -1;
- }
-
- if (len >= 41)
- ast_sha1_hash(buf, data);
- else {
- ast_log(LOG_ERROR,
- "Insufficient space to produce SHA1 hash result (%d < 41)\n",
- (int) len);
- }
-
- return 0;
-}
-
-static struct ast_custom_function sha1_function = {
- .name = "SHA1",
- .synopsis = "Computes a SHA1 digest",
- .syntax = "SHA1(<data>)",
- .read = sha1,
- .desc = "Generate a SHA1 digest via the SHA1 algorythm.\n"
- " Example: Set(sha1hash=${SHA1(junky)})\n"
- " Sets the asterisk variable sha1hash to the string '60fa5675b9303eb62f99a9cd47f9f5837d18f9a0'\n"
- " which is known as his hash\n",
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&sha1_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&sha1_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SHA-1 computation dialplan function");
diff --git a/1.4/funcs/func_strings.c b/1.4/funcs/func_strings.c
deleted file mode 100644
index 10c274efd..000000000
--- a/1.4/funcs/func_strings.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005-2006, Digium, Inc.
- * Portions Copyright (C) 2005, Tilghman Lesher. All rights reserved.
- * Portions Copyright (C) 2005, Anthony Minessale II
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief String manipulation dialplan functions
- *
- * \author Tilghman Lesher
- * \author Anothony Minessale II
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <regex.h>
-
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/localtime.h"
-
-static int function_fieldqty(struct ast_channel *chan, char *cmd,
- char *parse, char *buf, size_t len)
-{
- char *varsubst, varval[8192] = "", *varval2 = varval;
- int fieldcount = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(varname);
- AST_APP_ARG(delim);
- );
-
- if (chan)
- ast_autoservice_start(chan);
-
- AST_STANDARD_APP_ARGS(args, parse);
- if (args.delim) {
- varsubst = alloca(strlen(args.varname) + 4);
-
- sprintf(varsubst, "${%s}", args.varname);
- pbx_substitute_variables_helper(chan, varsubst, varval, sizeof(varval) - 1);
- if (ast_strlen_zero(varval2))
- fieldcount = 0;
- else {
- while (strsep(&varval2, args.delim))
- fieldcount++;
- }
- } else {
- fieldcount = 1;
- }
- snprintf(buf, len, "%d", fieldcount);
-
- if (chan)
- ast_autoservice_stop(chan);
-
- return 0;
-}
-
-static struct ast_custom_function fieldqty_function = {
- .name = "FIELDQTY",
- .synopsis = "Count the fields, with an arbitrary delimiter",
- .syntax = "FIELDQTY(<varname>|<delim>)",
- .read = function_fieldqty,
-};
-
-static int filter(struct ast_channel *chan, char *cmd, char *parse, char *buf,
- size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(allowed);
- AST_APP_ARG(string);
- );
- char *outbuf = buf;
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (!args.string) {
- ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>|<string>)\n");
- return -1;
- }
-
- for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
- if (strchr(args.allowed, *(args.string)))
- *outbuf++ = *(args.string);
- }
- *outbuf = '\0';
-
- return 0;
-}
-
-static struct ast_custom_function filter_function = {
- .name = "FILTER",
- .synopsis = "Filter the string to include only the allowed characters",
- .syntax = "FILTER(<allowed-chars>|<string>)",
- .read = filter,
-};
-
-static int regex(struct ast_channel *chan, char *cmd, char *parse, char *buf,
- size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(null);
- AST_APP_ARG(reg);
- AST_APP_ARG(str);
- );
- int errcode;
- regex_t regexbuf;
-
- buf[0] = '\0';
-
- AST_NONSTANDARD_APP_ARGS(args, parse, '"');
-
- if (args.argc != 3) {
- ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
- return -1;
- }
- if ((*args.str == ' ') || (*args.str == '\t'))
- args.str++;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
-
- if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
- regerror(errcode, &regexbuf, buf, len);
- ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
- return -1;
- }
-
- strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
-
- regfree(&regexbuf);
-
- return 0;
-}
-
-static struct ast_custom_function regex_function = {
- .name = "REGEX",
- .synopsis = "Regular Expression",
- .desc =
- "Returns 1 if data matches regular expression, or 0 otherwise.\n"
- "Please note that the space following the double quotes separating the regex from the data\n"
- "is optional and if present, is skipped. If a space is desired at the beginning of the data,\n"
- "then put two spaces there; the second will not be skipped.\n",
- .syntax = "REGEX(\"<regular expression>\" <data>)",
- .read = regex,
-};
-
-static int array(struct ast_channel *chan, char *cmd, char *var,
- const char *value)
-{
- AST_DECLARE_APP_ARGS(arg1,
- AST_APP_ARG(var)[100];
- );
- AST_DECLARE_APP_ARGS(arg2,
- AST_APP_ARG(val)[100];
- );
- char *value2;
- int i;
-
- value2 = ast_strdupa(value);
- if (!var || !value2)
- return -1;
-
- if (chan)
- ast_autoservice_start(chan);
-
- /* The functions this will generally be used with are SORT and ODBC_*, which
- * both return comma-delimited lists. However, if somebody uses literal lists,
- * their commas will be translated to vertical bars by the load, and I don't
- * want them to be surprised by the result. Hence, we prefer commas as the
- * delimiter, but we'll fall back to vertical bars if commas aren't found.
- */
- if (option_debug)
- ast_log(LOG_DEBUG, "array (%s=%s)\n", var, value2);
- if (strchr(var, ','))
- AST_NONSTANDARD_APP_ARGS(arg1, var, ',');
- else
- AST_STANDARD_APP_ARGS(arg1, var);
-
- if (strchr(value2, ','))
- AST_NONSTANDARD_APP_ARGS(arg2, value2, ',');
- else
- AST_STANDARD_APP_ARGS(arg2, value2);
-
- for (i = 0; i < arg1.argc; i++) {
- if (option_debug)
- ast_log(LOG_DEBUG, "array set value (%s=%s)\n", arg1.var[i],
- arg2.val[i]);
- if (i < arg2.argc) {
- pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
- } else {
- /* We could unset the variable, by passing a NULL, but due to
- * pushvar semantics, that could create some undesired behavior. */
- pbx_builtin_setvar_helper(chan, arg1.var[i], "");
- }
- }
-
- if (chan)
- ast_autoservice_stop(chan);
-
- return 0;
-}
-
-static struct ast_custom_function array_function = {
- .name = "ARRAY",
- .synopsis = "Allows setting multiple variables at once",
- .syntax = "ARRAY(var1[|var2[...][|varN]])",
- .write = array,
- .desc =
- "The comma-separated list passed as a value to which the function is set will\n"
- "be interpreted as a set of values to which the comma-separated list of\n"
- "variable names in the argument should be set.\n"
- "Hence, Set(ARRAY(var1|var2)=1\\,2) will set var1 to 1 and var2 to 2\n"
- "Note: remember to either backslash your commas in extensions.conf or quote the\n"
- "entire argument, since Set can take multiple arguments itself.\n",
-};
-
-static int acf_sprintf(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
-#define SPRINTF_FLAG 0
-#define SPRINTF_WIDTH 1
-#define SPRINTF_PRECISION 2
-#define SPRINTF_LENGTH 3
-#define SPRINTF_CONVERSION 4
- int i, state = -1, argcount = 0;
- char *formatstart = NULL, *bufptr = buf;
- char formatbuf[256] = "";
- int tmpi;
- double tmpd;
- AST_DECLARE_APP_ARGS(arg,
- AST_APP_ARG(format);
- AST_APP_ARG(var)[100];
- );
-
- AST_STANDARD_APP_ARGS(arg, data);
-
- /* Scan the format, converting each argument into the requisite format type. */
- for (i = 0; arg.format[i]; i++) {
- switch (state) {
- case SPRINTF_FLAG:
- if (strchr("#0- +'I", arg.format[i]))
- break;
- state = SPRINTF_WIDTH;
- case SPRINTF_WIDTH:
- if (arg.format[i] >= '0' && arg.format[i] <= '9')
- break;
-
- /* Next character must be a period to go into a precision */
- if (arg.format[i] == '.') {
- state = SPRINTF_PRECISION;
- } else {
- state = SPRINTF_LENGTH;
- i--;
- }
- break;
- case SPRINTF_PRECISION:
- if (arg.format[i] >= '0' && arg.format[i] <= '9')
- break;
- state = SPRINTF_LENGTH;
- case SPRINTF_LENGTH:
- if (strchr("hl", arg.format[i])) {
- if (arg.format[i + 1] == arg.format[i])
- i++;
- state = SPRINTF_CONVERSION;
- break;
- } else if (strchr("Lqjzt", arg.format[i])) {
- state = SPRINTF_CONVERSION;
- break;
- }
- state = SPRINTF_CONVERSION;
- case SPRINTF_CONVERSION:
- if (strchr("diouxXc", arg.format[i])) {
- /* Integer */
-
- /* Isolate this format alone */
- ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
- formatbuf[&arg.format[i] - formatstart + 1] = '\0';
-
- /* Convert the argument into the required type */
- if (sscanf(arg.var[argcount++], "%d", &tmpi) != 1) {
- ast_log(LOG_ERROR, "Argument '%s' is not an integer number for format '%s'\n", arg.var[argcount - 1], formatbuf);
- goto sprintf_fail;
- }
-
- /* Format the argument */
- snprintf(bufptr, buf + len - bufptr, formatbuf, tmpi);
-
- /* Update the position of the next parameter to print */
- bufptr = strchr(buf, '\0');
- } else if (strchr("eEfFgGaA", arg.format[i])) {
- /* Double */
-
- /* Isolate this format alone */
- ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
- formatbuf[&arg.format[i] - formatstart + 1] = '\0';
-
- /* Convert the argument into the required type */
- if (sscanf(arg.var[argcount++], "%lf", &tmpd) != 1) {
- ast_log(LOG_ERROR, "Argument '%s' is not a floating point number for format '%s'\n", arg.var[argcount - 1], formatbuf);
- goto sprintf_fail;
- }
-
- /* Format the argument */
- snprintf(bufptr, buf + len - bufptr, formatbuf, tmpd);
-
- /* Update the position of the next parameter to print */
- bufptr = strchr(buf, '\0');
- } else if (arg.format[i] == 's') {
- /* String */
-
- /* Isolate this format alone */
- ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
- formatbuf[&arg.format[i] - formatstart + 1] = '\0';
-
- /* Format the argument */
- snprintf(bufptr, buf + len - bufptr, formatbuf, arg.var[argcount++]);
-
- /* Update the position of the next parameter to print */
- bufptr = strchr(buf, '\0');
- } else if (arg.format[i] == '%') {
- /* Literal data to copy */
- *bufptr++ = arg.format[i];
- } else {
- /* Not supported */
-
- /* Isolate this format alone */
- ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
- formatbuf[&arg.format[i] - formatstart + 1] = '\0';
-
- ast_log(LOG_ERROR, "Format type not supported: '%s' with argument '%s'\n", formatbuf, arg.var[argcount++]);
- goto sprintf_fail;
- }
- state = -1;
- break;
- default:
- if (arg.format[i] == '%') {
- state = SPRINTF_FLAG;
- formatstart = &arg.format[i];
- break;
- } else {
- /* Literal data to copy */
- *bufptr++ = arg.format[i];
- }
- }
- }
- return 0;
-sprintf_fail:
- return -1;
-}
-
-static struct ast_custom_function sprintf_function = {
- .name = "SPRINTF",
- .synopsis = "Format a variable according to a format string",
- .syntax = "SPRINTF(<format>|<arg1>[|...<argN>])",
- .read = acf_sprintf,
- .desc =
-"Parses the format string specified and returns a string matching that format.\n"
-"Supports most options supported by sprintf(3). Returns a shortened string if\n"
-"a format specifier is not recognized.\n",
-};
-
-static int quote(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- char *bufptr = buf, *dataptr = data;
- *bufptr++ = '"';
- for (; bufptr < buf + len - 1; dataptr++) {
- if (*dataptr == '\\') {
- *bufptr++ = '\\';
- *bufptr++ = '\\';
- } else if (*dataptr == '"') {
- *bufptr++ = '\\';
- *bufptr++ = '"';
- } else if (*dataptr == '\0') {
- break;
- } else {
- *bufptr++ = *dataptr;
- }
- }
- *bufptr++ = '"';
- *bufptr = '\0';
- return 0;
-}
-
-static struct ast_custom_function quote_function = {
- .name = "QUOTE",
- .synopsis = "Quotes a given string, escaping embedded quotes as necessary",
- .syntax = "QUOTE(<string>)",
- .read = quote,
-};
-
-
-static int len(struct ast_channel *chan, char *cmd, char *data, char *buf,
- size_t len)
-{
- int length = 0;
-
- if (data)
- length = strlen(data);
-
- snprintf(buf, len, "%d", length);
-
- return 0;
-}
-
-static struct ast_custom_function len_function = {
- .name = "LEN",
- .synopsis = "Returns the length of the argument given",
- .syntax = "LEN(<string>)",
- .read = len,
-};
-
-static int acf_strftime(struct ast_channel *chan, char *cmd, char *parse,
- char *buf, size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(epoch);
- AST_APP_ARG(timezone);
- AST_APP_ARG(format);
- );
- time_t epochi;
- struct tm tm;
-
- buf[0] = '\0';
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- ast_get_time_t(args.epoch, &epochi, time(NULL), NULL);
- ast_localtime(&epochi, &tm, args.timezone);
-
- if (!args.format)
- args.format = "%c";
-
- if (!strftime(buf, len, args.format, &tm))
- ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
-
- buf[len - 1] = '\0';
-
- return 0;
-}
-
-static struct ast_custom_function strftime_function = {
- .name = "STRFTIME",
- .synopsis = "Returns the current date/time in a specified format.",
- .syntax = "STRFTIME([<epoch>][|[timezone][|format]])",
- .read = acf_strftime,
-};
-
-static int acf_strptime(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(timestring);
- AST_APP_ARG(timezone);
- AST_APP_ARG(format);
- );
- struct tm time;
-
- memset(&time, 0, sizeof(struct tm));
-
- buf[0] = '\0';
-
- if (!data) {
- ast_log(LOG_ERROR,
- "Asterisk function STRPTIME() requires an argument.\n");
- return -1;
- }
-
- AST_STANDARD_APP_ARGS(args, data);
-
- if (ast_strlen_zero(args.format)) {
- ast_log(LOG_ERROR,
- "No format supplied to STRPTIME(<timestring>|<timezone>|<format>)");
- return -1;
- }
-
- if (!strptime(args.timestring, args.format, &time)) {
- ast_log(LOG_WARNING, "C function strptime() output nothing?!!\n");
- } else {
- /* Since strptime(3) does not check DST, force ast_mktime() to calculate it. */
- time.tm_isdst = -1;
- snprintf(buf, len, "%d", (int) ast_mktime(&time, args.timezone));
- }
-
- return 0;
-}
-
-static struct ast_custom_function strptime_function = {
- .name = "STRPTIME",
- .synopsis =
- "Returns the epoch of the arbitrary date/time string structured as described in the format.",
- .syntax = "STRPTIME(<datetime>|<timezone>|<format>)",
- .desc =
- "This is useful for converting a date into an EPOCH time, possibly to pass to\n"
- "an application like SayUnixTime or to calculate the difference between two\n"
- "date strings.\n"
- "\n"
- "Example:\n"
- " ${STRPTIME(2006-03-01 07:30:35|America/Chicago|%Y-%m-%d %H:%M:%S)} returns 1141219835\n",
- .read = acf_strptime,
-};
-
-static int function_eval(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- memset(buf, 0, len);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
- return -1;
- }
-
- if (chan)
- ast_autoservice_start(chan);
- pbx_substitute_variables_helper(chan, data, buf, len - 1);
- if (chan)
- ast_autoservice_stop(chan);
-
- return 0;
-}
-
-static struct ast_custom_function eval_function = {
- .name = "EVAL",
- .synopsis = "Evaluate stored variables.",
- .syntax = "EVAL(<variable>)",
- .desc = "Using EVAL basically causes a string to be evaluated twice.\n"
- "When a variable or expression is in the dialplan, it will be\n"
- "evaluated at runtime. However, if the result of the evaluation\n"
- "is in fact a variable or expression, using EVAL will have it\n"
- "evaluated a second time. For example, if the variable ${MYVAR}\n"
- "contains \"${OTHERVAR}\", then the result of putting ${EVAL(${MYVAR})}\n"
- "in the dialplan will be the contents of the variable, OTHERVAR.\n"
- "Normally, by just putting ${MYVAR} in the dialplan, you would be\n"
- "left with \"${OTHERVAR}\".\n",
- .read = function_eval,
-};
-
-static int keypadhash(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- char *bufptr, *dataptr;
-
- for (bufptr = buf, dataptr = data; bufptr < buf + len - 1; dataptr++) {
- if (*dataptr == '1') {
- *bufptr++ = '1';
- } else if (strchr("AaBbCc2", *dataptr)) {
- *bufptr++ = '2';
- } else if (strchr("DdEeFf3", *dataptr)) {
- *bufptr++ = '3';
- } else if (strchr("GgHhIi4", *dataptr)) {
- *bufptr++ = '4';
- } else if (strchr("JjKkLl5", *dataptr)) {
- *bufptr++ = '5';
- } else if (strchr("MmNnOo6", *dataptr)) {
- *bufptr++ = '6';
- } else if (strchr("PpQqRrSs7", *dataptr)) {
- *bufptr++ = '7';
- } else if (strchr("TtUuVv8", *dataptr)) {
- *bufptr++ = '8';
- } else if (strchr("WwXxYyZz9", *dataptr)) {
- *bufptr++ = '9';
- } else if (*dataptr == '0') {
- *bufptr++ = '0';
- } else if (*dataptr == '\0') {
- *bufptr++ = '\0';
- break;
- }
- }
- buf[len - 1] = '\0';
-
- return 0;
-}
-
-static struct ast_custom_function keypadhash_function = {
- .name = "KEYPADHASH",
- .synopsis = "Hash the letters in the string into the equivalent keypad numbers.",
- .syntax = "KEYPADHASH(<string>)",
- .read = keypadhash,
- .desc = "Example: ${KEYPADHASH(Les)} returns \"537\"\n",
-};
-
-static int unload_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_unregister(&fieldqty_function);
- res |= ast_custom_function_unregister(&filter_function);
- res |= ast_custom_function_unregister(&regex_function);
- res |= ast_custom_function_unregister(&array_function);
- res |= ast_custom_function_unregister(&quote_function);
- res |= ast_custom_function_unregister(&len_function);
- res |= ast_custom_function_unregister(&strftime_function);
- res |= ast_custom_function_unregister(&strptime_function);
- res |= ast_custom_function_unregister(&eval_function);
- res |= ast_custom_function_unregister(&keypadhash_function);
- res |= ast_custom_function_unregister(&sprintf_function);
-
- return res;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- res |= ast_custom_function_register(&fieldqty_function);
- res |= ast_custom_function_register(&filter_function);
- res |= ast_custom_function_register(&regex_function);
- res |= ast_custom_function_register(&array_function);
- res |= ast_custom_function_register(&quote_function);
- res |= ast_custom_function_register(&len_function);
- res |= ast_custom_function_register(&strftime_function);
- res |= ast_custom_function_register(&strptime_function);
- res |= ast_custom_function_register(&eval_function);
- res |= ast_custom_function_register(&keypadhash_function);
- res |= ast_custom_function_register(&sprintf_function);
-
- return res;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "String handling dialplan functions");
diff --git a/1.4/funcs/func_timeout.c b/1.4/funcs/func_timeout.c
deleted file mode 100644
index f327e7608..000000000
--- a/1.4/funcs/func_timeout.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Channel timeout related dialplan functions
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-
-static int timeout_read(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- time_t myt;
-
- if (!chan)
- return -1;
-
- if (!data) {
- ast_log(LOG_ERROR, "Must specify type of timeout to get.\n");
- return -1;
- }
-
- switch (*data) {
- case 'a':
- case 'A':
- if (chan->whentohangup == 0) {
- ast_copy_string(buf, "0", len);
- } else {
- time(&myt);
- snprintf(buf, len, "%d", (int) (chan->whentohangup - myt));
- }
- break;
-
- case 'r':
- case 'R':
- if (chan->pbx) {
- snprintf(buf, len, "%d", chan->pbx->rtimeout);
- }
- break;
-
- case 'd':
- case 'D':
- if (chan->pbx) {
- snprintf(buf, len, "%d", chan->pbx->dtimeout);
- }
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
- break;
- }
-
- return 0;
-}
-
-static int timeout_write(struct ast_channel *chan, char *cmd, char *data,
- const char *value)
-{
- int x;
- char timestr[64];
- struct tm myt;
-
- if (!chan)
- return -1;
-
- if (!data) {
- ast_log(LOG_ERROR, "Must specify type of timeout to set.\n");
- return -1;
- }
-
- if (!value)
- return -1;
-
- x = atoi(value);
- if (x < 0)
- x = 0;
-
- switch (*data) {
- case 'a':
- case 'A':
- ast_channel_setwhentohangup(chan, x);
- if (option_verbose > 2) {
- if (chan->whentohangup) {
- strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S UTC",
- gmtime_r(&chan->whentohangup, &myt));
- ast_verbose(VERBOSE_PREFIX_3 "Channel will hangup at %s.\n",
- timestr);
- } else {
- ast_verbose(VERBOSE_PREFIX_3 "Channel hangup cancelled.\n");
- }
- }
- break;
-
- case 'r':
- case 'R':
- if (chan->pbx) {
- chan->pbx->rtimeout = x;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Response timeout set to %d\n",
- chan->pbx->rtimeout);
- }
- break;
-
- case 'd':
- case 'D':
- if (chan->pbx) {
- chan->pbx->dtimeout = x;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Digit timeout set to %d\n",
- chan->pbx->dtimeout);
- }
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
- break;
- }
-
- return 0;
-}
-
-static struct ast_custom_function timeout_function = {
- .name = "TIMEOUT",
- .synopsis = "Gets or sets timeouts on the channel.",
- .syntax = "TIMEOUT(timeouttype)",
- .desc =
- "Gets or sets various channel timeouts. The timeouts that can be\n"
- "manipulated are:\n" "\n"
- "absolute: The absolute maximum amount of time permitted for a call. A\n"
- " setting of 0 disables the timeout.\n" "\n"
- "digit: The maximum amount of time permitted between digits when the\n"
- " user is typing in an extension. When this timeout expires,\n"
- " after the user has started to type in an extension, the\n"
- " extension will be considered complete, and will be\n"
- " interpreted. Note that if an extension typed in is valid,\n"
- " it will not have to timeout to be tested, so typically at\n"
- " the expiry of this timeout, the extension will be considered\n"
- " invalid (and thus control would be passed to the 'i'\n"
- " extension, or if it doesn't exist the call would be\n"
- " terminated). The default timeout is 5 seconds.\n" "\n"
- "response: The maximum amount of time permitted after falling through a\n"
- " series of priorities for a channel in which the user may\n"
- " begin typing an extension. If the user does not type an\n"
- " extension in this amount of time, control will pass to the\n"
- " 't' extension if it exists, and if not the call would be\n"
- " terminated. The default timeout is 10 seconds.\n",
- .read = timeout_read,
- .write = timeout_write,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&timeout_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&timeout_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel timeout dialplan functions");
diff --git a/1.4/funcs/func_uri.c b/1.4/funcs/func_uri.c
deleted file mode 100644
index 2680dd678..000000000
--- a/1.4/funcs/func_uri.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Created by Olle E. Johansson, Edvina.net
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief URI encoding / decoding
- *
- * \author Olle E. Johansson <oej@edvina.net>
- *
- * \note For now this code only supports 8 bit characters, not unicode,
- which we ultimately will need to support.
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-
-/*! \brief uriencode: Encode URL according to RFC 2396 */
-static int uriencode(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: URIENCODE(<data>) - missing argument!\n");
- return -1;
- }
-
- ast_uri_encode(data, buf, len, 1);
-
- return 0;
-}
-
-/*!\brief uridecode: Decode URI according to RFC 2396 */
-static int uridecode(struct ast_channel *chan, char *cmd, char *data,
- char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: URIDECODE(<data>) - missing argument!\n");
- return -1;
- }
-
- ast_copy_string(buf, data, len);
- ast_uri_decode(buf);
-
- return 0;
-}
-
-static struct ast_custom_function urldecode_function = {
- .name = "URIDECODE",
- .synopsis = "Decodes a URI-encoded string according to RFC 2396.",
- .syntax = "URIDECODE(<data>)",
- .read = uridecode,
-};
-
-static struct ast_custom_function urlencode_function = {
- .name = "URIENCODE",
- .synopsis = "Encodes a string to URI-safe encoding according to RFC 2396.",
- .syntax = "URIENCODE(<data>)",
- .read = uriencode,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&urldecode_function)
- || ast_custom_function_unregister(&urlencode_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&urldecode_function)
- || ast_custom_function_register(&urlencode_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "URI encode/decode dialplan functions");
diff --git a/1.4/images/animlogo.gif b/1.4/images/animlogo.gif
deleted file mode 100644
index 9b75989fc..000000000
--- a/1.4/images/animlogo.gif
+++ /dev/null
Binary files differ
diff --git a/1.4/images/asterisk-intro.jpg b/1.4/images/asterisk-intro.jpg
deleted file mode 100644
index 278f018ce..000000000
--- a/1.4/images/asterisk-intro.jpg
+++ /dev/null
Binary files differ
diff --git a/1.4/images/play.gif b/1.4/images/play.gif
deleted file mode 100644
index 4d457b19d..000000000
--- a/1.4/images/play.gif
+++ /dev/null
Binary files differ
diff --git a/1.4/include/asterisk.h b/1.4/include/asterisk.h
deleted file mode 100644
index 4fcb5f8ed..000000000
--- a/1.4/include/asterisk.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * General Definitions for Asterisk top level program
- *
- * Copyright (C) 1999-2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Asterisk main include file. File version handling, generic pbx functions.
- */
-
-#ifndef _ASTERISK_H
-#define _ASTERISK_H
-
-/* The include of 'autoconfig.h' is not necessary for any modules that
- are part of the Asterisk source tree, because the top-level Makefile
- will forcibly include that header in all compilations before all
- other headers (even system headers). However, leaving this here will
- help out-of-tree module builders, and doesn't cause any harm for the
- in-tree modules.
-*/
-#include "asterisk/autoconfig.h"
-
-#include "asterisk/compat.h"
-
-#include "asterisk/paths.h"
-
-#define DEFAULT_LANGUAGE "en"
-
-#define DEFAULT_SAMPLE_RATE 8000
-#define DEFAULT_SAMPLES_PER_MS ((DEFAULT_SAMPLE_RATE)/1000)
-#define setpriority __PLEASE_USE_ast_set_priority_INSTEAD_OF_setpriority__
-#define sched_setscheduler __PLEASE_USE_ast_set_priority_INSTEAD_OF_sched_setscheduler__
-
-/* provided in asterisk.c */
-extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
-extern char ast_config_AST_CONFIG_FILE[PATH_MAX];
-extern char ast_config_AST_MODULE_DIR[PATH_MAX];
-extern char ast_config_AST_SPOOL_DIR[PATH_MAX];
-extern char ast_config_AST_MONITOR_DIR[PATH_MAX];
-extern char ast_config_AST_VAR_DIR[PATH_MAX];
-extern char ast_config_AST_DATA_DIR[PATH_MAX];
-extern char ast_config_AST_LOG_DIR[PATH_MAX];
-extern char ast_config_AST_AGI_DIR[PATH_MAX];
-extern char ast_config_AST_DB[PATH_MAX];
-extern char ast_config_AST_KEY_DIR[PATH_MAX];
-extern char ast_config_AST_PID[PATH_MAX];
-extern char ast_config_AST_SOCKET[PATH_MAX];
-extern char ast_config_AST_RUN_DIR[PATH_MAX];
-extern char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
-extern char ast_config_AST_CTL_OWNER[PATH_MAX];
-extern char ast_config_AST_CTL_GROUP[PATH_MAX];
-extern char ast_config_AST_CTL[PATH_MAX];
-extern char ast_config_AST_SYSTEM_NAME[20];
-
-int ast_set_priority(int); /*!< Provided by asterisk.c */
-int load_modules(unsigned int); /*!< Provided by loader.c */
-int load_pbx(void); /*!< Provided by pbx.c */
-int init_logger(void); /*!< Provided by logger.c */
-void close_logger(void); /*!< Provided by logger.c */
-int reload_logger(int); /*!< Provided by logger.c */
-int init_framer(void); /*!< Provided by frame.c */
-int ast_term_init(void); /*!< Provided by term.c */
-int astdb_init(void); /*!< Provided by db.c */
-void ast_channels_init(void); /*!< Provided by channel.c */
-void ast_builtins_init(void); /*!< Provided by cli.c */
-int dnsmgr_init(void); /*!< Provided by dnsmgr.c */
-void dnsmgr_start_refresh(void); /*!< Provided by dnsmgr.c */
-int dnsmgr_reload(void); /*!< Provided by dnsmgr.c */
-void threadstorage_init(void); /*!< Provided by threadstorage.c */
-int astobj2_init(void); /*! Provided by astobj2.c */
-void ast_autoservice_init(void); /*!< Provided by autoservice.c */
-
-/* Many headers need 'ast_channel' to be defined */
-struct ast_channel;
-
-/* Many headers need 'ast_module' to be defined */
-struct ast_module;
-
-/*!
- * \brief Reload asterisk modules.
- * \param name the name of the module to reload
- *
- * This function reloads the specified module, or if no modules are specified,
- * it will reload all loaded modules.
- *
- * \note Modules are reloaded using their reload() functions, not unloading
- * them and loading them again.
- *
- * \return Zero if the specified module was not found, 1 if the module was
- * found but cannot be reloaded, -1 if a reload operation is already in
- * progress, and 2 if the specfied module was found and reloaded.
- */
-int ast_module_reload(const char *name);
-
-/*!
- * \brief Register a function to be executed before Asterisk exits.
- * \param func The callback function to use.
- *
- * \return Zero on success, -1 on error.
- */
-int ast_register_atexit(void (*func)(void));
-
-/*!
- * \brief Unregister a function registered with ast_register_atexit().
- * \param func The callback function to unregister.
- */
-void ast_unregister_atexit(void (*func)(void));
-
-#if !defined(LOW_MEMORY)
-/*!
- * \brief Register the version of a source code file with the core.
- * \param file the source file name
- * \param version the version string (typically a CVS revision keyword string)
- * \return nothing
- *
- * This function should not be called directly, but instead the
- * ASTERISK_FILE_VERSION macro should be used to register a file with the core.
- */
-void ast_register_file_version(const char *file, const char *version);
-
-/*!
- * \brief Unregister a source code file from the core.
- * \param file the source file name
- * \return nothing
- *
- * This function should not be called directly, but instead the
- * ASTERISK_FILE_VERSION macro should be used to automatically unregister
- * the file when the module is unloaded.
- */
-void ast_unregister_file_version(const char *file);
-
-/*!
- * \brief Register/unregister a source code file with the core.
- * \param file the source file name
- * \param version the version string (typically a CVS revision keyword string)
- *
- * This macro will place a file-scope constructor and destructor into the
- * source of the module using it; this will cause the version of this file
- * to registered with the Asterisk core (and unregistered) at the appropriate
- * times.
- *
- * Example:
- *
- * \code
- * ASTERISK_FILE_VERSION(__FILE__, "\$Revision\$")
- * \endcode
- *
- * \note The dollar signs above have been protected with backslashes to keep
- * CVS from modifying them in this file; under normal circumstances they would
- * not be present and CVS would expand the Revision keyword into the file's
- * revision number.
- */
-#ifdef MTX_PROFILE
-#define HAVE_MTX_PROFILE /* used in lock.h */
-#define ASTERISK_FILE_VERSION(file, version) \
- static int mtx_prof = -1; /* profile mutex */ \
- static void __attribute__((constructor)) __register_file_version(void) \
- { \
- mtx_prof = ast_add_profile("mtx_lock_" file, 0); \
- ast_register_file_version(file, version); \
- } \
- static void __attribute__((destructor)) __unregister_file_version(void) \
- { \
- ast_unregister_file_version(file); \
- }
-#else /* !MTX_PROFILE */
-#define ASTERISK_FILE_VERSION(file, version) \
- static void __attribute__((constructor)) __register_file_version(void) \
- { \
- ast_register_file_version(file, version); \
- } \
- static void __attribute__((destructor)) __unregister_file_version(void) \
- { \
- ast_unregister_file_version(file); \
- }
-#endif /* !MTX_PROFILE */
-#else /* LOW_MEMORY */
-#define ASTERISK_FILE_VERSION(file, x)
-#endif /* LOW_MEMORY */
-
-#if !defined(LOW_MEMORY)
-/*!
- * \brief support for event profiling
- *
- * (note, this must be documented a lot more)
- * ast_add_profile allocates a generic 'counter' with a given name,
- * which can be shown with the command 'show profile <name>'
- *
- * The counter accumulates positive or negative values supplied by
- * ast_add_profile(), dividing them by the 'scale' value passed in the
- * create call, and also counts the number of 'events'.
- * Values can also be taked by the TSC counter on ia32 architectures,
- * in which case you can mark the start of an event calling ast_mark(id, 1)
- * and then the end of the event with ast_mark(id, 0).
- * For non-i386 architectures, these two calls return 0.
- */
-int ast_add_profile(const char *, uint64_t scale);
-int64_t ast_profile(int, int64_t);
-int64_t ast_mark(int, int start1_stop0);
-#else /* LOW_MEMORY */
-#define ast_add_profile(a, b) 0
-#define ast_profile(a, b) do { } while (0)
-#define ast_mark(a, b) do { } while (0)
-#endif /* LOW_MEMORY */
-
-#endif /* _ASTERISK_H */
diff --git a/1.4/include/asterisk/abstract_jb.h b/1.4/include/asterisk/abstract_jb.h
deleted file mode 100644
index fc2bf5c90..000000000
--- a/1.4/include/asterisk/abstract_jb.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * abstract_jb: common implementation-independent jitterbuffer stuff
- *
- * Copyright (C) 2005, Attractel OOD
- *
- * Contributors:
- * Slav Klenov <slav@securax.org>
- *
- * 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.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-/*! \file
- *
- * \brief Common implementation-independent jitterbuffer stuff.
- *
- * \author Slav Klenov <slav@securax.org>
- */
-
-#ifndef _ABSTRACT_JB_H_
-#define _ABSTRACT_JB_H_
-
-#include <stdio.h>
-#include <sys/time.h>
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-struct ast_channel;
-struct ast_frame;
-
-/* Configuration flags */
-enum {
- AST_JB_ENABLED = (1 << 0),
- AST_JB_FORCED = (1 << 1),
- AST_JB_LOG = (1 << 2)
-};
-
-#define AST_JB_IMPL_NAME_SIZE 12
-
-/*!
- * \brief General jitterbuffer configuration.
- */
-struct ast_jb_conf
-{
- /*! \brief Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags. */
- unsigned int flags;
- /*! \brief Max size of the jitterbuffer implementation. */
- long max_size;
- /*! \brief Resynchronization threshold of the jitterbuffer implementation. */
- long resync_threshold;
- /*! \brief Name of the jitterbuffer implementation to be used. */
- char impl[AST_JB_IMPL_NAME_SIZE];
-};
-
-
-/* Jitterbuffer configuration property names */
-#define AST_JB_CONF_PREFIX "jb"
-#define AST_JB_CONF_ENABLE "enable"
-#define AST_JB_CONF_FORCE "force"
-#define AST_JB_CONF_MAX_SIZE "maxsize"
-#define AST_JB_CONF_RESYNCH_THRESHOLD "resyncthreshold"
-#define AST_JB_CONF_IMPL "impl"
-#define AST_JB_CONF_LOG "log"
-
-
-struct ast_jb_impl;
-
-
-/*!
- * \brief General jitterbuffer state.
- */
-struct ast_jb
-{
- /*! \brief Jitterbuffer configuration. */
- struct ast_jb_conf conf;
- /*! \brief Jitterbuffer implementation to be used. */
- struct ast_jb_impl *impl;
- /*! \brief Jitterbuffer object, passed to the implementation. */
- void *jbobj;
- /*! \brief The time the jitterbuffer was created. */
- struct timeval timebase;
- /*! \brief The time the next frame should be played. */
- long next;
- /*! \brief Voice format of the last frame in. */
- int last_format;
- /*! \brief File for frame timestamp tracing. */
- FILE *logfile;
- /*! \brief Jitterbuffer internal state flags. */
- unsigned int flags;
-};
-
-
-/*!
- * \brief Checks the need of a jb use in a generic bridge.
- * \param c0 first bridged channel.
- * \param c1 second bridged channel.
- *
- * Called from ast_generic_bridge() when two channels are entering in a bridge.
- * The function checks the need of a jitterbuffer, depending on both channel's
- * configuration and technology properties. As a result, this function sets
- * appropriate internal jb flags to the channels, determining further behaviour
- * of the bridged jitterbuffers.
- *
- * \return zero if there are no jitter buffers in use, non-zero if there are
- */
-int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1);
-
-
-/*!
- * \brief Calculates the time, left to the closest delivery moment in a bridge.
- * \param c0 first bridged channel.
- * \param c1 second bridged channel.
- * \param time_left bridge time limit, or -1 if not set.
- *
- * Called from ast_generic_bridge() to determine the maximum time to wait for
- * activity in ast_waitfor_n() call. If neihter of the channels is using jb,
- * this function returns the time limit passed.
- *
- * \return maximum time to wait.
- */
-int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left);
-
-
-/*!
- * \brief Puts a frame into a channel jitterbuffer.
- * \param chan channel.
- * \param f frame.
- *
- * Called from ast_generic_bridge() to put a frame into a channel's jitterbuffer.
- * The function will successfuly enqueue a frame if and only if:
- * 1. the channel is using a jitterbuffer (as determined by ast_jb_do_usecheck()),
- * 2. the frame's type is AST_FRAME_VOICE,
- * 3. the frame has timing info set and has length >= 2 ms,
- * 4. there is no some internal error happened (like failed memory allocation).
- * Frames, successfuly queued, should be delivered by the channel's jitterbuffer,
- * when their delivery time has came.
- * Frames, not successfuly queued, should be delivered immediately.
- * Dropped by the jb implementation frames are considered successfuly enqueued as
- * far as they should not be delivered at all.
- *
- * \return zero if the frame was queued, -1 if not.
- */
-int ast_jb_put(struct ast_channel *chan, struct ast_frame *f);
-
-
-/*!
- * \brief Deliver the queued frames that should be delivered now for both channels.
- * \param c0 first bridged channel.
- * \param c1 second bridged channel.
- *
- * Called from ast_generic_bridge() to deliver any frames, that should be delivered
- * for the moment of invocation. Does nothing if neihter of the channels is using jb
- * or has any frames currently queued in. The function delivers frames usig ast_write()
- * each of the channels.
- */
-void ast_jb_get_and_deliver(struct ast_channel *c0, struct ast_channel *c1);
-
-
-/*!
- * \brief Destroys jitterbuffer on a channel.
- * \param chan channel.
- *
- * Called from ast_channel_free() when a channel is destroyed.
- */
-void ast_jb_destroy(struct ast_channel *chan);
-
-
-/*!
- * \brief Sets jitterbuffer configuration property.
- * \param conf configuration to store the property in.
- * \param varname property name.
- * \param value property value.
- *
- * Called from a channel driver to build a jitterbuffer configuration tipically when
- * reading a configuration file. It is not neccessary for a channel driver to know
- * each of the jb configuration property names. The jitterbuffer itself knows them.
- * The channel driver can pass each config var it reads through this function. It will
- * return 0 if the variable was consumed from the jb conf.
- *
- * \return zero if the property was set to the configuration, -1 if not.
- */
-int ast_jb_read_conf(struct ast_jb_conf *conf, char *varname, char *value);
-
-
-/*!
- * \brief Configures a jitterbuffer on a channel.
- * \param chan channel to configure.
- * \param conf configuration to apply.
- *
- * Called from a channel driver when a channel is created and its jitterbuffer needs
- * to be configured.
- */
-void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf);
-
-
-/*!
- * \brief Copies a channel's jitterbuffer configuration.
- * \param chan channel.
- * \param conf destination.
- */
-void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf);
-
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ABSTRACT_JB_H_ */
diff --git a/1.4/include/asterisk/acl.h b/1.4/include/asterisk/acl.h
deleted file mode 100644
index f9114ce11..000000000
--- a/1.4/include/asterisk/acl.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief Access Control of various sorts
- */
-
-#ifndef _ASTERISK_ACL_H
-#define _ASTERISK_ACL_H
-
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <netinet/in.h>
-#include "asterisk/io.h"
-
-#define AST_SENSE_DENY 0
-#define AST_SENSE_ALLOW 1
-
-/* Host based access control */
-
-struct ast_ha;
-
-void ast_free_ha(struct ast_ha *ha);
-struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path);
-int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin);
-int ast_get_ip(struct sockaddr_in *sin, const char *value);
-int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service);
-int ast_ouraddrfor(struct in_addr *them, struct in_addr *us);
-int ast_lookup_iface(char *iface, struct in_addr *address);
-struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);
-int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr);
-int ast_str2tos(const char *value, unsigned int *tos);
-const char *ast_tos2str(unsigned int tos);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_ACL_H */
diff --git a/1.4/include/asterisk/adsi.h b/1.4/include/asterisk/adsi.h
deleted file mode 100644
index 0c894b8f3..000000000
--- a/1.4/include/asterisk/adsi.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief ADSI Support (built upon Caller*ID)
- */
-
-#ifndef _ASTERISK_ADSI_H
-#define _ASTERISK_ADSI_H
-
-#include "asterisk/callerid.h"
-
-/* ADSI Message types */
-#define ADSI_MSG_DISPLAY 132
-#define ADSI_MSG_DOWNLOAD 133
-
-/* ADSI Parameters (display) */
-#define ADSI_LOAD_SOFTKEY 128
-#define ADSI_INIT_SOFTKEY_LINE 129
-#define ADSI_LOAD_VIRTUAL_DISP 130
-#define ADSI_LINE_CONTROL 131
-#define ADSI_INFORMATION 132
-#define ADSI_DISC_SESSION 133
-#define ADSI_SWITCH_TO_DATA 134
-#define ADSI_SWITCH_TO_VOICE 135
-#define ADSI_CLEAR_SOFTKEY 136
-#define ADSI_INPUT_CONTROL 137
-#define ADSI_INPUT_FORMAT 138
-#define ADSI_SWITCH_TO_PERIPH 139
-#define ADSI_MOVE_DATA 140
-#define ADSI_LOAD_DEFAULT 141
-#define ADSI_CONNECT_SESSION 142
-#define ADSI_CLEAR_TYPE_AHEAD 143
-#define ADSI_DISPLAY_CALL_BUF 144
-#define ADSI_CLEAR_CALL_BUF 145
-#define ADSI_SWITCH_TO_ALT 146
-#define ADSI_SWITCH_TO_GRAPHICS 147
-#define ADSI_CLEAR_SCREEN 148
-#define ADSI_QUERY_CONFIG 149
-#define ADSI_QUERY_CPEID 150
-#define ADSI_SWITCH_TO_APP 151
-
-/* Feature download messages */
-#define ADSI_LOAD_SOFTKEY_TABLE 128 /* Conveniently identical to the soft version */
-#define ADSI_LOAD_PREDEF_DISP 129 /* Load predefined display */
-#define ADSI_LOAD_SCRIPT 130
-#define ADSI_DOWNLOAD_CONNECT 131
-#define ADSI_DOWNLOAD_DISC 132
-
-/* Special return string codes */
-#define ADSI_ENCODED_DTMF 0x80 /* Transmit following chars with encoded dtmf */
-#define ADSI_ON_HOOK 0x81 /* Open switch-hook */
-#define ADSI_OFF_HOOK 0x82 /* Close switch-hook */
-#define ADSI_FLASH 0x83 /* Flash switch-hook */
-#define ADSI_DIAL_TONE_DETECT 0x84 /* Wait for dialtone */
-#define ADSI_LINE_NUMBER 0x85 /* Send current line number using DTMF/encoded DTMF */
-#define ADSI_BLANK 0x86 /* Blank (does nothing) */
-#define ADSI_SEND_CHARS 0x87 /* Send collected digits/characters */
-#define ADSI_CLEAR_CHARS 0x88 /* Clear characters/digits collected */
-#define ADSI_BACKSPACE 0x89 /* Erase last collected digit */
-#define ADSI_TAB_COLUMN 0x8A /* Display specified display column of current line */
-#define ADSI_GOTO_LINE 0x8B /* Go to given page and line number */
-#define ADSI_GOTO_LINE_REL 0x8C /* Go to given line (relative to current) */
-#define ADSI_PAGE_UP 0x8D /* Go up one page */
-#define ADSI_PAGE_DOWN 0x8E /* Go down one page */
-#define ADSI_EXTENDED_DTMF 0x8F /* Send DTMF tones for 250ms instead of 60 ms */
-#define ADSI_DELAY 0x90 /* Delay for given # (times 10) of ms */
-#define ADSI_DIAL_PULSE_ONE 0x91 /* Send a dial pulse "1" */
-#define ADSI_SWITCH_TO_DATA2 0x92 /* Switch CPE to data mode */
-#define ADSI_SWITCH_TO_VOICE2 0x93 /* Switch CPE to voice mode */
-#define ADSI_DISP_CALL_BUF 0x94 /* Display specified call buffer */
-#define ADSI_CLEAR_CALL_B 0x95 /* Clear specified call buffer */
-
-#ifdef __ADSI_CPE
-/* These messages are reserved for the ADSI CPE only */
-#define ADSI_DISPLAY_CONTROL 0x98 /* Store predefined display identified next / Display status display page */
-#define ADSI_DISPLAY_SOFT_KEYS 0x99 /* Display the script soft keys identified next */
-#define ADSI_CHANGE_STATE 0x9A /* Change state of service script */
-#define ADSI_START_CLEAR_TIMER 0x9B /* Start / Clear timer */
-#define ADSI_SET_SCRIPT_FLAG 0x9C /* Set / clear a script flag */
-#define ADSI_JUMP_TO_SUBSCRIPT 0x9D /* Jump to specified subscript */
-#define ADSI_EVENT_22_TRIGGER 0x9E /* Trigger an occurance of event 22 */
-#define ADSI_EVENT_23_TRIGGER 0x9f /* Trigger an occurance of event 23 */
-#define ADSI_EXIT 0xA0 /* Exit the service script interpreter */
-#endif
-
-/* Display pages */
-#define ADSI_INFO_PAGE 0x0
-#define ADSI_COMM_PAGE 0x1
-
-#define ADSI_KEY_APPS 16 /* 16 to 33 reserved for applications */
-
-/* Justification */
-#define ADSI_JUST_LEFT 0x2
-#define ADSI_JUST_RIGHT 0x1
-#define ADSI_JUST_CENT 0x0 /* Center */
-#define ADSI_JUST_IND 0x3 /* Indent */
-
-#define ADSI_KEY_SKT 0x80 /* Load from SKT */
-#define ADSI_KEY_HILITE 0x40 /* Highlight key */
-
-#define ADSI_DIR_FROM_LEFT (0)
-#define ADSI_DIR_FROM_RIGHT (1)
-
-/*! Perform Asterisk ADSI initialization (for channel drivers that want */
-/* to support ADSI when the handset is first lifted) */
-/*!
- * \param chan Channel to initialize for ADSI (if supported)
- *
- * Returns 0 on success (or adsi unavailable) and -1 on hangup
- *
- */
-int ast_adsi_channel_init(struct ast_channel *chan);
-
-int ast_adsi_begin_download(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version);
-
-int ast_adsi_end_download(struct ast_channel *chan);
-
-/*! Restore ADSI initialization (for applications that play with ADSI */
-/* and want to restore it to normal. If you touch "INFO" then you */
-/* have to use the ast_adsi_channel_init again instead. */
-/*!
- * \param chan Channel to restore
- *
- * Returns 0 on success (or adsi unavailable) and -1 on hangup
- *
- */
-int ast_adsi_channel_restore(struct ast_channel *chan);
-
-/*! Display some stuff on the screen */
-/*!
- * \param chan Channel to display on
- * \param lines NULL-terminated list of things to print (no more than 4 recommended)
- * \param align list of alignments to use (ADSI_JUST_LEFT, ADSI_JUST_RIGHT, ADSI_JUST_CEN, etc..)
- * \param voice whether to jump into voice mode when finished
- *
- * Return 0 on success (or adsi unavailable) and -1 on hangup
- *
- */
-int ast_adsi_print(struct ast_channel *chan, char **lines, int *align, int voice);
-
-/*! Check if scripts for a given app are already loaded. Version may be -1 */
-/* if any version is okay, or 0-255 for a specific version. */
-/*!
- * \param chan Channel to test for loaded app
- * \param app Four character app name (must be unique to your application)
- * \param ver optional version number
- * \param data Non-zero if you want to be put in data mode
- *
- * Returns 0 if scripts is not loaded or not an ADSI CPE. Returns -1
- * on hangup. Returns 1 if script already loaded.
- */
-int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data);
-int ast_adsi_unload_session(struct ast_channel *chan);
-
-/* ADSI Layer 2 transmission functions */
-int ast_adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype);
-int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype);
-int ast_adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait);
-/*! Read some encoded DTMF data. */
-/*!
- * Returns number of bytes received
- */
-int ast_adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen);
-
-/* ADSI Layer 3 creation functions */
-
-/*! Connects an ADSI Display Session */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param fdn Optional 4 byte Feature Download Number (for loading soft keys)
- * \param ver Optional version number (0-255, or -1 to omit)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-
-int ast_adsi_connect_session(unsigned char *buf, unsigned char *fdn, int ver);
-
-/*! Build Query CPE ID of equipment */
-/*!
- * Returns number of bytes added to message
- */
-int ast_adsi_query_cpeid(unsigned char *buf);
-int ast_adsi_query_cpeinfo(unsigned char *buf);
-
-/*! Get CPE ID from an attached ADSI compatible CPE. */
-/*!
- * Returns 1 on success, storing 4 bytes of CPE ID at buf
- * or -1 on hangup, or 0 if there was no hangup but it failed to find the
- * device ID. Returns to voice mode if "voice" is non-zero.
- */
-int ast_adsi_get_cpeid(struct ast_channel *chan, unsigned char *cpeid, int voice);
-
-int ast_adsi_get_cpeinfo(struct ast_channel *chan, int *width, int *height, int *buttons, int voice);
-
-/*! Begin an ADSI script download */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param service a 1-18 byte name of the feature
- * \param fdn 4 byte Feature Download Number (for loading soft keys)
- * \param sec 4 byte vendor security code
- * \param ver version number (0-255, or -1 to omit)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-
-int ast_adsi_download_connect(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver);
-
-/*! Disconnects a running session */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_disconnect_session(unsigned char *buf);
-
-/*! Disconnects (and hopefully saves) a downloaded script */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_download_disconnect(unsigned char *buf);
-
-/*! Puts CPE in data mode... */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_data_mode(unsigned char *buf);
-int ast_adsi_clear_soft_keys(unsigned char *buf);
-int ast_adsi_clear_screen(unsigned char *buf);
-
-/*! Puts CPE in voice mode... */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param when (a time in seconds) to make the switch
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_voice_mode(unsigned char *buf, int when);
-
-/*! Returns non-zero if Channel does or might support ADSI */
-/*!
- * \param chan Channel to check
- *
- */
-int ast_adsi_available(struct ast_channel *chan);
-
-/*! Loads a line of info into the display */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param page Page to load (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
- * \param line Line number to load (1-4 for Comm page, 1-33 for info page)
- * \param just Line justification (ADSI_JUST_LEFT, ADSI_JUST_RIGHT, ADSI_JUST_CENT, ADSI_JUST_IND)
- * \param wrap Wrap (1 = yes, 0 = no)
- * \param col1 Text to place in first column
- * \param col2 Text to place in second column
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-
-int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2);
-
-/*! Sets the current line and page */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param page Which page (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
- * \param line Line number (1-33 for info page, 1-4 for comm page)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-
-int ast_adsi_set_line(unsigned char *buf, int page, int line);
-
-/*! Creates "load soft key" parameters */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param key Key code from 2 to 33, for which key we are loading
- * \param llabel Long label for key (1-18 bytes)
- * \param slabel Short label for key (1-7 bytes)
- * \param ret Optional return sequence (NULL for none)
- * \param data whether to put CPE in data mode before sending digits
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_load_soft_key(unsigned char *buf, int key, const char *llabel, const char *slabel, const char *ret, int data);
-
-/*! Set which soft keys should be displayed */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param keys Array of 8 unsigned chars with the key numbers, may be OR'd with ADSI_KEY_HILITE
- * But remember, the last two keys aren't real keys, they're for scrolling
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys);
-
-/*! Set input information */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param page Which page to input on (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
- * \param line Line number to input on
- * \param display Set to zero to obscure input, or 1 to leave visible
- * \param format Format number to use (0-7)
- * \param just Justification (left, right center, indent)
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_input_control(unsigned char *buf, int page, int line, int display, int format, int just);
-
-/*! Set input format */
-/*!
- * \param buf Character buffer to create parameter in (must have at least 256 free)
- * \param num Which format we are setting
- * \param dir Which direction (ADSI_DIR_FROM_LEFT or ADSI_DIR_FROM_RIGHT)
- * \param wrap Set to 1 to permit line wrap, or 0 if not
- * \param format1 Format for column 1
- * \param format2 Format for column 2
- *
- * Returns number of bytes added to buffer or -1 on error.
- *
- */
-int ast_adsi_input_format(unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2);
-
-#endif /* _ASTERISK_ADSI_H */
diff --git a/1.4/include/asterisk/ael_structs.h b/1.4/include/asterisk/ael_structs.h
deleted file mode 100644
index 01a4244e1..000000000
--- a/1.4/include/asterisk/ael_structs.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#ifndef _ASTERISK_AEL_STRUCTS_H
-#define _ASTERISK_AEL_STRUCTS_H
-
-#if !defined(SOLARIS) && !defined(__CYGWIN__)
-/* #include <err.h> */
-#else
-#define quad_t int64_t
-#endif
-
-#if defined(LONG_LONG_MIN) && !defined(QUAD_MIN)
-#define QUAD_MIN LONG_LONG_MIN
-#endif
-#if defined(LONG_LONG_MAX) && !defined(QUAD_MAX)
-#define QUAD_MAX LONG_LONG_MAX
-#endif
-
-# if ! defined(QUAD_MIN)
-# define QUAD_MIN (-0x7fffffffffffffffLL-1)
-# endif
-# if ! defined(QUAD_MAX)
-# define QUAD_MAX (0x7fffffffffffffffLL)
-# endif
-
-
-typedef enum
-{
- PV_WORD, /* an ident, string, name, label, etc. A user-supplied string. */ /* 0 */
- PV_MACRO, /* 1 */
- PV_CONTEXT, /* 2 */
- PV_MACRO_CALL, /* 3 */
- PV_APPLICATION_CALL, /* 4 */
- PV_CASE, /* 5 */
- PV_PATTERN, /* 6 */
- PV_DEFAULT, /* 7 */
- PV_CATCH, /* 8 */
- PV_SWITCHES, /* 9 */
- PV_ESWITCHES, /* 10 */
- PV_INCLUDES, /* 11 */
- PV_STATEMENTBLOCK, /* 12 */
- PV_VARDEC, /* you know, var=val; */ /* 13 */
- PV_GOTO, /* 14 */
- PV_LABEL, /* 15 */
- PV_FOR, /* 16 */
- PV_WHILE, /* 17 */
- PV_BREAK, /* 18 */
- PV_RETURN, /* 19 */
- PV_CONTINUE, /* 20 */
- PV_IF, /* 21 */
- PV_IFTIME, /* 22 */
- PV_RANDOM, /* 23 */
- PV_SWITCH, /* 24 */
- PV_EXTENSION, /* 25 */
- PV_IGNOREPAT, /* 26 */
- PV_GLOBALS, /* 27 */
-
-} pvaltype;
-
-/* why this horrible mess? It's always been a tradeoff-- tons of structs,
- each storing it's specific lists of goodies, or a 'simple' single struct,
- with lots of fields, that catches all uses at once. Either you have a long
- list of struct names and subnames, or you have a long list of field names,
- and where/how they are used. I'm going with a single struct, using unions
- to reduce storage. Some simple generalizations, and a long list of types,
- and a book about what is used with what types.... Sorry!
-*/
-
-struct pval
-{
- pvaltype type;
- int startline;
- int endline;
- int startcol;
- int endcol;
- char *filename;
-
- union
- {
- char *str; /* wow, used almost everywhere! */
- struct pval *list; /* used in SWITCHES, ESWITCHES, INCLUDES, STATEMENTBLOCK, GOTO */
- struct pval *statements;/* used in EXTENSION */
- char *for_init; /* used in FOR */
- } u1;
- struct pval *u1_last; /* to build in-order lists -- looks like we only need one */
-
- union
- {
- struct pval *arglist; /* used in macro_call, application_call, MACRO def, also attached to PWORD, the 4 timevals for includes */
- struct pval *statements; /* used in case, default, catch, while's statement, CONTEXT elements, GLOBALS */
- char *val; /* used in VARDEC */
- char *for_test; /* used in FOR */
- int label_in_case; /* a boolean for LABELs */
- struct pval *goto_target; /* used in GOTO */
- } u2;
-
- union
- {
- char *for_inc; /* used in FOR */
- struct pval *else_statements; /* used in IF */
- struct pval *macro_statements; /* used in MACRO */
- int abstract; /* used for context 1=abstract; 2=extend; 3=both */
- char *hints; /* used in EXTENSION */
- int goto_target_in_case; /* used in GOTO */
- struct ael_extension *compiled_label;
- struct pval *extend; /* to link extended contexts to the 'original' */
- } u3;
-
- union
- {
- struct pval *for_statements; /* used in PV_FOR */
- int regexten; /* used in EXTENSION */
- } u4;
-
- struct pval *next; /* the pval at the end of this ptr will ALWAYS be of the same type as this one!
- EXCEPT for objects of the different types, that are in the same list, like contexts & macros, etc */
-
- struct pval *dad; /* the 'container' of this struct instance */
- struct pval *prev; /* the opposite of the 'next' pointer */
-} ;
-
-
-typedef struct pval pval;
-
-#if 0
-pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
-void linku1(pval *head, pval *tail);
-void print_pval_list(FILE *f, pval *item, int depth);
-void print_pval(FILE *f, pval *item, int depth);
-void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
-struct pval *find_label_in_current_context(char *exten, char *label);
-struct pval *find_label_in_current_extension(char *label);
-int count_labels_in_current_context(char *label);
-struct pval *find_label_in_current_db(char *context, char *exten, char *label);
-void ael2_print(char *fname, pval *tree);
-#endif
-struct pval *ael2_parse(char *fname, int *errs); /* in ael.flex */
-void destroy_pval(pval *item);
-
-extern char *prev_word; /* in ael.flex */
-
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* for passing info into and out of yyparse */
-struct parse_io
-{
- struct pval *pval; /* yyparse will set this to point to the parse tree */
- yyscan_t scanner; /* yylex needs a scanner. Set it up, and pass it in */
- int syntax_error_count; /* the count of syntax errors encountered */
-};
-
-/* for CODE GENERATION */
-
-typedef enum { AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_RAND_CONTROL, AEL_LABEL, AEL_RETURN } ael_priority_type;
-
-
-struct ael_priority
-{
- int priority_num;
- ael_priority_type type;
-
- char *app;
- char *appargs;
-
- struct pval *origin;
- struct ael_extension *exten;
-
- struct ael_priority *goto_true;
- struct ael_priority *goto_false;
- struct ael_priority *next;
-};
-
-struct ael_extension
-{
- char *name;
- char *cidmatch;
- char *hints;
- int regexten;
- int is_switch;
- int has_switch;
-
- struct ast_context *context;
-
- struct ael_priority *plist;
- struct ael_priority *plist_last;
- struct ael_extension *next_exten;
-
- struct ael_priority *loop_break; /* set by latest loop for breaks */
- struct ael_priority *loop_continue; /* set by lastest loop for continuing */
- struct ael_priority *return_target;
- int return_needed;
-};
-
-#endif /* _ASTERISK_AEL_STRUCTS_H */
diff --git a/1.4/include/asterisk/aes.h b/1.4/include/asterisk/aes.h
deleted file mode 100644
index af648e8ee..000000000
--- a/1.4/include/asterisk/aes.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * 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.
- */
-
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 26/08/2003
-*/
-/*!\file
-
- \brief This file contains the definitions required to use AES in C. See aesopt.h
- for optimisation details.
-*/
-
-#ifndef _AES_H
-#define _AES_H
-
-/* This include is used to find 8 & 32 bit unsigned integer types */
-#include "limits.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define AES_128 /* define if AES with 128 bit keys is needed */
-#undef AES_192 /* define if AES with 192 bit keys is needed */
-#undef AES_256 /* define if AES with 256 bit keys is needed */
-#undef AES_VAR /* define if a variable key size is needed */
-
-/* The following must also be set in assembler files if being used */
-
-#define AES_ENCRYPT /* if support for encryption is needed */
-#define AES_DECRYPT /* if support for decryption is needed */
-#define AES_ERR_CHK /* for parameter checks & error return codes */
-
-#if UCHAR_MAX == 0xff /* an unsigned 8 bit type */
- typedef unsigned char aes_08t;
-#else
-#error Please define aes_08t as an 8-bit unsigned integer type in aes.h
-#endif
-
-#if UINT_MAX == 0xffffffff /* an unsigned 32 bit type */
- typedef unsigned int aes_32t;
-#elif ULONG_MAX == 0xffffffff
- typedef unsigned long aes_32t;
-#else
-#error Please define aes_32t as a 32-bit unsigned integer type in aes.h
-#endif
-
-#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
-#define N_COLS 4 /* the number of columns in the state */
-
-/* a maximum of 60 32-bit words are needed for the key schedule but */
-/* 64 are claimed to allow space at the top for a CBC xor buffer. */
-/* If this is not needed, this value can be reduced to 60. A value */
-/* of 64 may also help in maintaining alignment in some situations */
-#define KS_LENGTH 64
-
-#ifdef AES_ERR_CHK
-#define aes_ret int
-#define aes_good 0
-#define aes_error -1
-#else
-#define aes_ret void
-#endif
-
-#ifndef AES_DLL /* implement normal/DLL functions */
-#define aes_rval aes_ret
-#else
-#define aes_rval aes_ret __declspec(dllexport) _stdcall
-#endif
-
-/* This routine must be called before first use if non-static */
-/* tables are being used */
-
-void gen_tabs(void);
-
-/* The key length (klen) is input in bytes when it is in the range */
-/* 16 <= klen <= 32 or in bits when in the range 128 <= klen <= 256 */
-
-#ifdef AES_ENCRYPT
-
-typedef struct
-{ aes_32t ks[KS_LENGTH];
-} aes_encrypt_ctx;
-
-#if defined(AES_128) || defined(AES_VAR)
-aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined(AES_192) || defined(AES_VAR)
-aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined(AES_256) || defined(AES_VAR)
-aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined(AES_VAR)
-aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1]);
-#endif
-
-aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1]);
-#endif
-
-#ifdef AES_DECRYPT
-
-typedef struct
-{ aes_32t ks[KS_LENGTH];
-} aes_decrypt_ctx;
-
-#if defined(AES_128) || defined(AES_VAR)
-aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined(AES_192) || defined(AES_VAR)
-aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined(AES_256) || defined(AES_VAR)
-aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined(AES_VAR)
-aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1]);
-#endif
-
-aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/1.4/include/asterisk/agi.h b/1.4/include/asterisk/agi.h
deleted file mode 100644
index 5797176fe..000000000
--- a/1.4/include/asterisk/agi.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief AGI Extension interfaces - Asterisk Gateway Interface
- */
-
-#ifndef _ASTERISK_AGI_H
-#define _ASTERISK_AGI_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-typedef struct agi_state {
- int fd; /* FD for general output */
- int audio; /* FD for audio output */
- int ctrl; /* FD for input control */
- unsigned int fast:1; /* flag for fast agi or not */
-} AGI;
-
-typedef struct agi_command {
- /* Null terminated list of the words of the command */
- char *cmda[AST_MAX_CMD_LEN];
- /* Handler for the command (channel, AGI state, # of arguments, argument list).
- Returns RESULT_SHOWUSAGE for improper arguments */
- int (*handler)(struct ast_channel *chan, AGI *agi, int argc, char *argv[]);
- /* Summary of the command (< 60 characters) */
- char *summary;
- /* Detailed usage information */
- char *usage;
- struct agi_command *next;
-} agi_command;
-
-int ast_agi_register(agi_command *cmd);
-void ast_agi_unregister(agi_command *cmd);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_AGI_H */
diff --git a/1.4/include/asterisk/alaw.h b/1.4/include/asterisk/alaw.h
deleted file mode 100644
index 44b3bad86..000000000
--- a/1.4/include/asterisk/alaw.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief A-Law to Signed linear conversion
- */
-
-#ifndef _ASTERISK_ALAW_H
-#define _ASTERISK_ALAW_H
-
-/*! Init the ulaw conversion stuff */
-/*!
- * To init the ulaw to slinear conversion stuff, this needs to be run.
- */
-void ast_alaw_init(void);
-
-/*! converts signed linear to mulaw */
-/*!
- */
-extern unsigned char __ast_lin2a[8192];
-
-/*! help */
-extern short __ast_alaw[256];
-
-#define AST_LIN2A(a) (__ast_lin2a[((unsigned short)(a)) >> 3])
-#define AST_ALAW(a) (__ast_alaw[(int)(a)])
-
-#endif /* _ASTERISK_ALAW_H */
diff --git a/1.4/include/asterisk/app.h b/1.4/include/asterisk/app.h
deleted file mode 100644
index 7abff8e53..000000000
--- a/1.4/include/asterisk/app.h
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Application convenience functions, designed to give consistent
- look and feel to Asterisk apps.
- */
-
-#ifndef _ASTERISK_APP_H
-#define _ASTERISK_APP_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/* IVR stuff */
-
-/*! \brief Callback function for IVR
- \return returns 0 on completion, -1 on hangup or digit if interrupted
- */
-typedef int (*ast_ivr_callback)(struct ast_channel *chan, char *option, void *cbdata);
-
-typedef enum {
- AST_ACTION_UPONE, /*!< adata is unused */
- AST_ACTION_EXIT, /*!< adata is the return value for ast_ivr_menu_run if channel was not hungup */
- AST_ACTION_CALLBACK, /*!< adata is an ast_ivr_callback */
- AST_ACTION_PLAYBACK, /*!< adata is file to play */
- AST_ACTION_BACKGROUND, /*!< adata is file to play */
- AST_ACTION_PLAYLIST, /*!< adata is list of files, separated by ; to play */
- AST_ACTION_MENU, /*!< adata is a pointer to an ast_ivr_menu */
- AST_ACTION_REPEAT, /*!< adata is max # of repeats, cast to a pointer */
- AST_ACTION_RESTART, /*!< adata is like repeat, but resets repeats to 0 */
- AST_ACTION_TRANSFER, /*!< adata is a string with exten[@context] */
- AST_ACTION_WAITOPTION, /*!< adata is a timeout, or 0 for defaults */
- AST_ACTION_NOOP, /*!< adata is unused */
- AST_ACTION_BACKLIST, /*!< adata is list of files separated by ; allows interruption */
-} ast_ivr_action;
-
-/*!
- Special "options" are:
- \arg "s" - "start here (one time greeting)"
- \arg "g" - "greeting/instructions"
- \arg "t" - "timeout"
- \arg "h" - "hangup"
- \arg "i" - "invalid selection"
-
-*/
-struct ast_ivr_option {
- char *option;
- ast_ivr_action action;
- void *adata;
-};
-
-struct ast_ivr_menu {
- char *title; /*!< Title of menu */
- unsigned int flags; /*!< Flags */
- struct ast_ivr_option *options; /*!< All options */
-};
-
-#define AST_IVR_FLAG_AUTORESTART (1 << 0)
-
-#define AST_IVR_DECLARE_MENU(holder, title, flags, foo...) \
- static struct ast_ivr_option __options_##holder[] = foo;\
- static struct ast_ivr_menu holder = { title, flags, __options_##holder }
-
-
-/*! \brief Runs an IVR menu
- \return returns 0 on successful completion, -1 on hangup, or -2 on user error in menu */
-int ast_ivr_menu_run(struct ast_channel *c, struct ast_ivr_menu *menu, void *cbdata);
-
-/*! \brief Plays a stream and gets DTMF data from a channel
- * \param c Which channel one is interacting with
- * \param prompt File to pass to ast_streamfile (the one that you wish to play)
- * \param s The location where the DTMF data will be stored
- * \param maxlen Max Length of the data
- * \param timeout Timeout length waiting for data(in milliseconds). Set to 0 for standard timeout(six seconds), or -1 for no time out.
- *
- * This function was designed for application programmers for situations where they need
- * to play a message and then get some DTMF data in response to the message. If a digit
- * is pressed during playback, it will immediately break out of the message and continue
- * execution of your code.
- */
-int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout);
-
-/*! \brief Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions */
-int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd);
-
-void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
- int (*inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs),
- int (*messagecount_func)(const char *context, const char *mailbox, const char *folder));
-
-void ast_uninstall_vm_functions(void);
-
-/*! Determine if a given mailbox has any voicemail */
-int ast_app_has_voicemail(const char *mailbox, const char *folder);
-
-/*! Determine number of new/old messages in a mailbox */
-int ast_app_inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs);
-
-/*! Determine number of messages in a given mailbox and folder */
-int ast_app_messagecount(const char *context, const char *mailbox, const char *folder);
-
-/*! Safely spawn an external program while closing file descriptors
- \note This replaces the \b system call in all Asterisk modules
-*/
-int ast_safe_system(const char *s);
-
-/*!
- * \brief Replace the SIGCHLD handler
- *
- * Normally, Asterisk has a SIGCHLD handler that is cleaning up all zombie
- * processes from forking elsewhere in Asterisk. However, if you want to
- * wait*() on the process to retrieve information about it's exit status,
- * then this signal handler needs to be temporaraly replaced.
- *
- * Code that executes this function *must* call ast_unreplace_sigchld()
- * after it is finished doing the wait*().
- */
-void ast_replace_sigchld(void);
-
-/*!
- * \brief Restore the SIGCHLD handler
- *
- * This function is called after a call to ast_replace_sigchld. It restores
- * the SIGCHLD handler that cleans up any zombie processes.
- */
-void ast_unreplace_sigchld(void);
-
-/*!
- \brief Send DTMF to a channel
-
- \param chan The channel that will receive the DTMF frames
- \param peer (optional) Peer channel that will be autoserviced while the
- primary channel is receiving DTMF
- \param digits This is a string of characters representing the DTMF digits
- to be sent to the channel. Valid characters are
- "0123456789*#abcdABCD". Note: You can pass arguments 'f' or
- 'F', if you want to Flash the channel (if supported by the
- channel), or 'w' to add a 500 millisecond pause to the DTMF
- sequence.
- \param between This is the number of milliseconds to wait in between each
- DTMF digit. If zero milliseconds is specified, then the
- default value of 100 will be used.
-*/
-int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between);
-
-/*! Stream a filename (or file descriptor) as a generator. */
-int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, int allowoverride);
-
-/*! Stream a file with fast forward, pause, reverse, restart. */
-int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms);
-
-/*! Play a stream and wait for a digit, returning the digit that was pressed */
-int ast_play_and_wait(struct ast_channel *chan, const char *fn);
-
-int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf);
-
-/*! Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum
- \n
- permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults.
- calls ast_unlock_path() on 'path' if passed */
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path);
-
-/*! Record a message and prepend the message to the given record file after
- playing the optional playfile (or a beep), storing the duration in
- 'duration' and with a maximum
-\n
- permitted silence time in milliseconds of 'maxsilence' under
- 'silencethreshold' or use '-1' for either or both parameters for defaults. */
-int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms);
-
-enum AST_LOCK_RESULT {
- AST_LOCK_SUCCESS = 0,
- AST_LOCK_TIMEOUT = -1,
- AST_LOCK_PATH_NOT_FOUND = -2,
- AST_LOCK_FAILURE = -3,
-};
-
-/*!
- * \brief Lock a filesystem path.
- * \param path the path to be locked
- * \return one of \ref AST_LOCK_RESULT values
- */
-enum AST_LOCK_RESULT ast_lock_path(const char *path);
-
-/*! Unlock a path */
-int ast_unlock_path(const char *path);
-
-/*! Read a file into asterisk*/
-char *ast_read_textfile(const char *file);
-
-struct ast_group_info {
- struct ast_channel *chan;
- char *category;
- char *group;
- AST_LIST_ENTRY(ast_group_info) list;
-};
-
-/*! Split a group string into group and category, returning a default category if none is provided. */
-int ast_app_group_split_group(const char *data, char *group, int group_max, char *category, int category_max);
-
-/*! Set the group for a channel, splitting the provided data into group and category, if specified. */
-int ast_app_group_set_channel(struct ast_channel *chan, const char *data);
-
-/*! Get the current channel count of the specified group and category. */
-int ast_app_group_get_count(const char *group, const char *category);
-
-/*! Get the current channel count of all groups that match the specified pattern and category. */
-int ast_app_group_match_get_count(const char *groupmatch, const char *category);
-
-/*! Discard all group counting for a channel */
-int ast_app_group_discard(struct ast_channel *chan);
-
-/*! Update all group counting for a channel to a new one */
-int ast_app_group_update(struct ast_channel *oldchan, struct ast_channel *newchan);
-
-/*! Lock the group count list */
-int ast_app_group_list_lock(void);
-
-/*! Get the head of the group count list */
-struct ast_group_info *ast_app_group_list_head(void);
-
-/*! Unlock the group count list */
-int ast_app_group_list_unlock(void);
-
-/*!
- \brief Define an application argument
- \param name The name of the argument
-*/
-#define AST_APP_ARG(name) char *name
-
-/*!
- \brief Declare a structure to hold the application's arguments.
- \param name The name of the structure
- \param arglist The list of arguments, defined using AST_APP_ARG
-
- This macro defines a structure intended to be used in a call
- to ast_app_separate_args(). The structure includes all the
- arguments specified, plus an argv array that overlays them and an
- argc argument counter. The arguments must be declared using AST_APP_ARG,
- and they will all be character pointers (strings).
-
- \note The structure is <b>not</b> initialized, as the call to
- ast_app_separate_args() will perform that function before parsing
- the arguments.
- */
-#define AST_DECLARE_APP_ARGS(name, arglist) \
- struct { \
- unsigned int argc; \
- char *argv[0]; \
- arglist \
- } name
-
-/*!
- \brief Performs the 'standard' argument separation process for an application.
- \param args An argument structure defined using AST_DECLARE_APP_ARGS
- \param parse A modifiable buffer containing the input to be parsed
-
- This function will separate the input string using the standard argument
- separator character '|' and fill in the provided structure, including
- the argc argument counter field.
- */
-#define AST_STANDARD_APP_ARGS(args, parse) \
- args.argc = ast_app_separate_args(parse, '|', args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
-
-/*!
- \brief Performs the 'nonstandard' argument separation process for an application.
- \param args An argument structure defined using AST_DECLARE_APP_ARGS
- \param parse A modifiable buffer containing the input to be parsed
- \param sep A nonstandard separator character
-
- This function will separate the input string using the nonstandard argument
- separator character and fill in the provided structure, including
- the argc argument counter field.
- */
-#define AST_NONSTANDARD_APP_ARGS(args, parse, sep) \
- args.argc = ast_app_separate_args(parse, sep, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
-
-/*!
- \brief Separate a string into arguments in an array
- \param buf The string to be parsed (this must be a writable copy, as it will be modified)
- \param delim The character to be used to delimit arguments
- \param array An array of 'char *' to be filled in with pointers to the found arguments
- \param arraylen The number of elements in the array (i.e. the number of arguments you will accept)
-
- Note: if there are more arguments in the string than the array will hold, the last element of
- the array will contain the remaining arguments, not separated.
-
- The array will be completely zeroed by this function before it populates any entries.
-
- \return The number of arguments found, or zero if the function arguments are not valid.
-*/
-unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen);
-
-/*!
- \brief A structure to hold the description of an application 'option'.
-
- Application 'options' are single-character flags that can be supplied
- to the application to affect its behavior; they can also optionally
- accept arguments enclosed in parenthesis.
-
- These structures are used by the ast_app_parse_options function, uses
- this data to fill in a flags structure (to indicate which options were
- supplied) and array of argument pointers (for those options that had
- arguments supplied).
- */
-struct ast_app_option {
- /*! \brief The flag bit that represents this option. */
- unsigned int flag;
- /*! \brief The index of the entry in the arguments array
- that should be used for this option's argument. */
- unsigned int arg_index;
-};
-
-#define BEGIN_OPTIONS {
-#define END_OPTIONS }
-
-/*!
- \brief Declares an array of options for an application.
- \param holder The name of the array to be created
- \param options The actual options to be placed into the array
- \sa ast_app_parse_options
-
- This macro declares a 'static const' array of \c struct \c ast_option
- elements to hold the list of available options for an application.
- Each option must be declared using either the AST_APP_OPTION()
- or AST_APP_OPTION_ARG() macros.
-
- Example usage:
- \code
- enum {
- OPT_JUMP = (1 << 0),
- OPT_BLAH = (1 << 1),
- OPT_BLORT = (1 << 2),
- } my_app_option_flags;
-
- enum {
- OPT_ARG_BLAH = 0,
- OPT_ARG_BLORT,
- !! this entry tells how many possible arguments there are,
- and must be the last entry in the list
- OPT_ARG_ARRAY_SIZE,
- } my_app_option_args;
-
- AST_APP_OPTIONS(my_app_options, {
- AST_APP_OPTION('j', OPT_JUMP),
- AST_APP_OPTION_ARG('b', OPT_BLAH, OPT_ARG_BLAH),
- AST_APP_OPTION_BLORT('B', OPT_BLORT, OPT_ARG_BLORT),
- });
-
- static int my_app_exec(struct ast_channel *chan, void *data)
- {
- char *options;
- struct ast_flags opts = { 0, };
- char *opt_args[OPT_ARG_ARRAY_SIZE];
-
- ... do any argument parsing here ...
-
- if (ast_parseoptions(my_app_options, &opts, opt_args, options)) {
- LOCAL_USER_REMOVE(u);
- return -1;
- }
- }
- \endcode
- */
-#define AST_APP_OPTIONS(holder, options...) \
- static const struct ast_app_option holder[128] = options
-
-/*!
- \brief Declares an application option that does not accept an argument.
- \param option The single character representing the option
- \param flagno The flag index to be set if this option is present
- \sa AST_APP_OPTIONS, ast_app_parse_options
- */
-#define AST_APP_OPTION(option, flagno) \
- [option] = { .flag = flagno }
-
-/*!
- \brief Declares an application option that accepts an argument.
- \param option The single character representing the option
- \param flagno The flag index to be set if this option is present
- \param argno The index into the argument array where the argument should
- be placed
- \sa AST_APP_OPTIONS, ast_app_parse_options
- */
-#define AST_APP_OPTION_ARG(option, flagno, argno) \
- [option] = { .flag = flagno, .arg_index = argno + 1 }
-
-/*!
- \brief Parses a string containing application options and sets flags/arguments.
- \param options The array of possible options declared with AST_APP_OPTIONS
- \param flags The flag structure to have option flags set
- \param args The array of argument pointers to hold arguments found
- \param optstr The string containing the options to be parsed
- \return zero for success, non-zero if an error occurs
- \sa AST_APP_OPTIONS
- */
-int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr);
-
-/*! \brief Present a dialtone and collect a certain length extension.
- \return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
-\note Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
-int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
-
-/*! Allow to record message and have a review option */
-int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_APP_H */
diff --git a/1.4/include/asterisk/ast_expr.h b/1.4/include/asterisk/ast_expr.h
deleted file mode 100644
index bc0331309..000000000
--- a/1.4/include/asterisk/ast_expr.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-#ifndef _ASTERISK_EXPR_H
-#define _ASTERISK_EXPR_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-int ast_expr(char *expr, char *buf, int length);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_EXPR_H */
diff --git a/1.4/include/asterisk/astdb.h b/1.4/include/asterisk/astdb.h
deleted file mode 100644
index 828fe9725..000000000
--- a/1.4/include/asterisk/astdb.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Persistant data storage (akin to *doze registry)
- */
-
-#ifndef _ASTERISK_ASTDB_H
-#define _ASTERISK_ASTDB_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-struct ast_db_entry {
- struct ast_db_entry *next;
- char *key;
- char data[0];
-};
-
-int ast_db_get(const char *family, const char *key, char *out, int outlen);
-
-int ast_db_put(const char *family, const char *key, char *value);
-
-int ast_db_del(const char *family, const char *key);
-
-int ast_db_deltree(const char *family, const char *keytree);
-
-struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree);
-
-void ast_db_freetree(struct ast_db_entry *entry);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_ASTDB_H */
diff --git a/1.4/include/asterisk/astmm.h b/1.4/include/asterisk/astmm.h
deleted file mode 100644
index f1f838ef0..000000000
--- a/1.4/include/asterisk/astmm.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief Asterisk memory usage debugging
- */
-
-#ifndef _ASTERISK_ASTMM_H
-#define _ASTERISK_ASTMM_H
-
-#define __AST_DEBUG_MALLOC
-
-#include "asterisk.h"
-
-/* Include these now to prevent them from being needed later */
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-/* Undefine any macros */
-#undef malloc
-#undef calloc
-#undef realloc
-#undef strdup
-#undef strndup
-#undef asprintf
-#undef vasprintf
-
-void *__ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
-void *__ast_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
-void *__ast_malloc(size_t size, const char *file, int lineno, const char *func);
-void __ast_free(void *ptr, const char *file, int lineno, const char *func);
-void *__ast_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func);
-char *__ast_strdup(const char *s, const char *file, int lineno, const char *func);
-char *__ast_strndup(const char *s, size_t n, const char *file, int lineno, const char *func);
-int __ast_asprintf(const char *file, int lineno, const char *func, char **strp, const char *format, ...);
-int __ast_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func);
-
-void __ast_mm_init(void);
-
-
-/* Provide our own definitions */
-#define calloc(a,b) \
- __ast_calloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define ast_calloc_cache(a,b) \
- __ast_calloc_cache(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define malloc(a) \
- __ast_malloc(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define free(a) \
- __ast_free(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define realloc(a,b) \
- __ast_realloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define strdup(a) \
- __ast_strdup(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define strndup(a,b) \
- __ast_strndup(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#define asprintf(a, b, c...) \
- __ast_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, b, c)
-
-#define vasprintf(a,b,c) \
- __ast_vasprintf(a,b,c,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
-#error "NEVER INCLUDE astmm.h DIRECTLY!!"
-#endif /* _ASTERISK_ASTMM_H */
diff --git a/1.4/include/asterisk/astobj.h b/1.4/include/asterisk/astobj.h
deleted file mode 100644
index dd6207ff8..000000000
--- a/1.4/include/asterisk/astobj.h
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*
- * Object Model for Asterisk
- */
-
-#ifndef _ASTERISK_ASTOBJ_H
-#define _ASTERISK_ASTOBJ_H
-
-#include <string.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/compiler.h"
-
-/*! \file
- * \brief A set of macros implementing objects and containers.
- * Macros are used for maximum performance, to support multiple inheritance,
- * and to be easily integrated into existing structures without additional
- * malloc calls, etc.
- *
- * These macros expect to operate on two different object types, ASTOBJs and
- * ASTOBJ_CONTAINERs. These are not actual types, as any struct can be
- * converted into an ASTOBJ compatible object or container using the supplied
- * macros.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_object {
- * ASTOBJ_COMPONENTS(struct sample_object);
- * };
- *
- * struct sample_container {
- * ASTOBJ_CONTAINER_COMPONENTS(struct sample_object);
- * } super_container;
- *
- * void sample_object_destroy(struct sample_object *obj)
- * {
- * free(obj);
- * }
- *
- * int init_stuff()
- * {
- * struct sample_object *obj1;
- * struct sample_object *found_obj;
- *
- * obj1 = malloc(sizeof(struct sample_object));
- *
- * ASTOBJ_CONTAINER_INIT(&super_container);
- *
- * ASTOBJ_INIT(obj1);
- * ASTOBJ_WRLOCK(obj1);
- * ast_copy_string(obj1->name, "obj1", sizeof(obj1->name));
- * ASTOBJ_UNLOCK(obj1);
- *
- * ASTOBJ_CONTAINER_LINK(&super_container, obj1);
- *
- * found_obj = ASTOBJ_CONTAINER_FIND(&super_container, "obj1");
- *
- * if(found_obj) {
- * printf("Found object: %s", found_obj->name);
- * ASTOBJ_UNREF(found_obj,sample_object_destroy);
- * }
- *
- * ASTOBJ_CONTAINER_DESTROYALL(&super_container,sample_object_destroy);
- * ASTOBJ_CONTAINER_DESTROY(&super_container);
- *
- * return 0;
- * }
- * \endcode
- */
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define ASTOBJ_DEFAULT_NAMELEN 80
-#define ASTOBJ_DEFAULT_BUCKETS 256
-#define ASTOBJ_DEFAULT_HASH ast_strhash
-
-#define ASTOBJ_FLAG_MARKED (1 << 0) /* Object has been marked for future operation */
-
-/* C++ is simply a syntactic crutch for those who cannot think for themselves
- in an object oriented way. */
-
-/*! \brief Lock an ASTOBJ for reading.
- */
-#define ASTOBJ_RDLOCK(object) ast_mutex_lock(&(object)->_lock)
-
-/*! \brief Lock an ASTOBJ for writing.
- */
-#define ASTOBJ_WRLOCK(object) ast_mutex_lock(&(object)->_lock)
-
-/*! \brief Unlock a locked object. */
-#define ASTOBJ_UNLOCK(object) ast_mutex_unlock(&(object)->_lock)
-
-#ifdef ASTOBJ_CONTAINER_HASHMODEL
-#define __ASTOBJ_HASH(type,hashes) \
- type *next[hashes]
-#else
-#define __ASTOBJ_HASH(type,hashes) \
- type *next[1]
-#endif
-
-/*! \brief Add ASTOBJ components to a struct (without locking support).
- *
- * \param type The datatype of the object.
- * \param namelen The length to make the name char array.
- * \param hashes The number of containers the object can be present in.
- *
- * This macro adds components to a struct to make it an ASTOBJ. This macro
- * differs from ASTOBJ_COMPONENTS_FULL in that it does not create a mutex for
- * locking.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct {
- * ASTOBJ_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1);
- * };
- * \endcode
- */
-#define ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes) \
- char name[namelen]; \
- unsigned int refcount; \
- unsigned int objflags; \
- __ASTOBJ_HASH(type,hashes)
-
-/*! \brief Add ASTOBJ components to a struct (without locking support).
- *
- * \param type The datatype of the object.
- *
- * This macro works like #ASTOBJ_COMPONENTS_NOLOCK_FULL() except it only accepts a
- * type and uses default values for namelen and hashes.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct_componets {
- * ASTOBJ_COMPONENTS_NOLOCK(struct sample_struct);
- * };
- * \endcode
- */
-#define ASTOBJ_COMPONENTS_NOLOCK(type) \
- ASTOBJ_COMPONENTS_NOLOCK_FULL(type,ASTOBJ_DEFAULT_NAMELEN,1)
-
-/*! \brief Add ASTOBJ components to a struct (with locking support).
- *
- * \param type The datatype of the object.
- *
- * This macro works like #ASTOBJ_COMPONENTS_NOLOCK() except it includes locking
- * support.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct {
- * ASTOBJ_COMPONENTS(struct sample_struct);
- * };
- * \endcode
- */
-#define ASTOBJ_COMPONENTS(type) \
- ASTOBJ_COMPONENTS_NOLOCK(type); \
- ast_mutex_t _lock;
-
-/*! \brief Add ASTOBJ components to a struct (with locking support).
- *
- * \param type The datatype of the object.
- * \param namelen The length to make the name char array.
- * \param hashes The number of containers the object can be present in.
- *
- * This macro adds components to a struct to make it an ASTOBJ and includes
- * support for locking.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct {
- * ASTOBJ_COMPONENTS_FULL(struct sample_struct,1,1);
- * };
- * \endcode
- */
-#define ASTOBJ_COMPONENTS_FULL(type,namelen,hashes) \
- ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes); \
- ast_mutex_t _lock;
-
-/*! \brief Increment an object reference count.
- * \param object A pointer to the object to operate on.
- * \return The object.
- */
-#define ASTOBJ_REF(object) \
- ({ \
- ASTOBJ_WRLOCK(object); \
- (object)->refcount++; \
- ASTOBJ_UNLOCK(object); \
- (object); \
- })
-
-/*! \brief Decrement the reference count on an object.
- *
- * \param object A pointer the object to operate on.
- * \param destructor The destructor to call if the object is no longer referenced. It will be passed the pointer as an argument.
- *
- * This macro unreferences an object and calls the specfied destructor if the
- * object is no longer referenced. The destructor should free the object if it
- * was dynamically allocated.
- */
-#define ASTOBJ_UNREF(object,destructor) \
- do { \
- int newcount = 0; \
- ASTOBJ_WRLOCK(object); \
- if (__builtin_expect((object)->refcount > 0, 1)) \
- newcount = --((object)->refcount); \
- else \
- ast_log(LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \
- ASTOBJ_UNLOCK(object); \
- if (newcount == 0) { \
- ast_mutex_destroy(&(object)->_lock); \
- destructor((object)); \
- } \
- (object) = NULL; \
- } while(0)
-
-/*! \brief Mark an ASTOBJ by adding the #ASTOBJ_FLAG_MARKED flag to its objflags mask.
- * \param object A pointer to the object to operate on.
- *
- * This macro "marks" an object. Marked objects can later be unlinked from a container using
- * #ASTOBJ_CONTAINER_PRUNE_MARKED().
- *
- */
-#define ASTOBJ_MARK(object) \
- do { \
- ASTOBJ_WRLOCK(object); \
- (object)->objflags |= ASTOBJ_FLAG_MARKED; \
- ASTOBJ_UNLOCK(object); \
- } while(0)
-
-/*! \brief Unmark an ASTOBJ by subtracting the #ASTOBJ_FLAG_MARKED flag from its objflags mask.
- * \param object A pointer to the object to operate on.
- */
-#define ASTOBJ_UNMARK(object) \
- do { \
- ASTOBJ_WRLOCK(object); \
- (object)->objflags &= ~ASTOBJ_FLAG_MARKED; \
- ASTOBJ_UNLOCK(object); \
- } while(0)
-
-/*! \brief Initialize an object.
- * \param object A pointer to the object to operate on.
- *
- * \note This should only be used on objects that support locking (objects
- * created with #ASTOBJ_COMPONENTS() or #ASTOBJ_COMPONENTS_FULL())
- */
-#define ASTOBJ_INIT(object) \
- do { \
- ast_mutex_init(&(object)->_lock); \
- object->name[0] = '\0'; \
- object->refcount = 1; \
- } while(0)
-
-/* Containers for objects -- current implementation is linked lists, but
- should be able to be converted to hashes relatively easily */
-
-/*! \brief Lock an ASTOBJ_CONTAINER for reading.
- */
-#define ASTOBJ_CONTAINER_RDLOCK(container) ast_mutex_lock(&(container)->_lock)
-
-/*! \brief Lock an ASTOBJ_CONTAINER for writing.
- */
-#define ASTOBJ_CONTAINER_WRLOCK(container) ast_mutex_lock(&(container)->_lock)
-
-/*! \brief Unlock an ASTOBJ_CONTAINER. */
-#define ASTOBJ_CONTAINER_UNLOCK(container) ast_mutex_unlock(&(container)->_lock)
-
-#ifdef ASTOBJ_CONTAINER_HASHMODEL
-#error "Hash model for object containers not yet implemented!"
-#else
-/* Linked lists */
-
-/*! \brief Create a container for ASTOBJs (without locking support).
- *
- * \param type The type of objects the container will hold.
- * \param hashes Currently unused.
- * \param buckets Currently unused.
- *
- * This macro is used to create a container for ASTOBJs without locking
- * support.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct_nolock_container {
- * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1);
- * };
- * \endcode
- */
-#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,hashes,buckets) \
- type *head
-
-/*! \brief Initialize a container.
- *
- * \param container A pointer to the container to initialize.
- * \param hashes Currently unused.
- * \param buckets Currently unused.
- *
- * This macro initializes a container. It should only be used on containers
- * that support locking.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct_container {
- * ASTOBJ_CONTAINER_COMPONENTS_FULL(struct sample_struct,1,1);
- * } container;
- *
- * int func()
- * {
- * ASTOBJ_CONTAINER_INIT_FULL(&container,1,1);
- * }
- * \endcode
- */
-#define ASTOBJ_CONTAINER_INIT_FULL(container,hashes,buckets) \
- do { \
- ast_mutex_init(&(container)->_lock); \
- } while(0)
-
-/*! \brief Destroy a container.
- *
- * \param container A pointer to the container to destroy.
- * \param hashes Currently unused.
- * \param buckets Currently unused.
- *
- * This macro frees up resources used by a container. It does not operate on
- * the objects in the container. To unlink the objects from the container use
- * #ASTOBJ_CONTAINER_DESTROYALL().
- *
- * \note This macro should only be used on containers with locking support.
- */
-#define ASTOBJ_CONTAINER_DESTROY_FULL(container,hashes,buckets) \
- do { \
- ast_mutex_destroy(&(container)->_lock); \
- } while(0)
-
-/*! \brief Iterate through the objects in a container.
- *
- * \param container A pointer to the container to traverse.
- * \param continue A condition to allow the traversal to continue.
- * \param eval A statement to evaluate in the iteration loop.
- *
- * This is macro is a little complicated, but it may help to think of it as a
- * loop. Basically it iterates through the specfied containter as long as the
- * condition is met. Two variables, iterator and next, are provided for use in
- * your \p eval statement. See the sample code for an example.
- *
- * <b>Sample Usage:</b>
- * \code
- * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, {
- * ASTOBJ_RDLOCK(iterator);
- * printf("Currently iterating over '%s'\n", iterator->name);
- * ASTOBJ_UNLOCK(iterator);
- * } );
- * \endcode
- *
- * \code
- * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, sample_func(iterator));
- * \endcode
- */
-#define ASTOBJ_CONTAINER_TRAVERSE(container,continue,eval) \
- do { \
- typeof((container)->head) iterator; \
- typeof((container)->head) next; \
- ASTOBJ_CONTAINER_RDLOCK(container); \
- next = (container)->head; \
- while((continue) && (iterator = next)) { \
- next = iterator->next[0]; \
- eval; \
- } \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } while(0)
-
-/*! \brief Find an object in a container.
- *
- * \param container A pointer to the container to search.
- * \param namestr The name to search for.
- *
- * Use this function to find an object with the specfied name in a container.
- *
- * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should
- * be used to free the additional reference created by this macro.
- *
- * \return A new reference to the object located or NULL if nothing is found.
- */
-#define ASTOBJ_CONTAINER_FIND(container,namestr) \
- ({ \
- typeof((container)->head) found = NULL; \
- ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
- if (!(strcasecmp(iterator->name, (namestr)))) \
- found = ASTOBJ_REF(iterator); \
- } while (0)); \
- found; \
- })
-
-/*! \brief Find an object in a container.
- *
- * \param container A pointer to the container to search.
- * \param data The data to search for.
- * \param field The field/member of the container's objects to search.
- * \param hashfunc The hash function to use, currently not implemented.
- * \param hashoffset The hash offset to use, currently not implemented.
- * \param comparefunc The function used to compare the field and data values.
- *
- * This macro iterates through a container passing the specified field and data
- * elements to the specified comparefunc. The function should return 0 when a match is found.
- *
- * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should
- * be used to free the additional reference created by this macro.
- *
- * \return A pointer to the object located or NULL if nothing is found.
- */
-#define ASTOBJ_CONTAINER_FIND_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \
- ({ \
- typeof((container)->head) found = NULL; \
- ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
- ASTOBJ_RDLOCK(iterator); \
- if (!(comparefunc(iterator->field, (data)))) { \
- found = ASTOBJ_REF(iterator); \
- } \
- ASTOBJ_UNLOCK(iterator); \
- } while (0)); \
- found; \
- })
-
-/*! \brief Empty a container.
- *
- * \param container A pointer to the container to operate on.
- * \param destructor A destructor function to call on each object.
- *
- * This macro loops through a container removing all the items from it using
- * #ASTOBJ_UNREF(). This does not destroy the container itself, use
- * #ASTOBJ_CONTAINER_DESTROY() for that.
- *
- * \note If any object in the container is only referenced by the container,
- * the destructor will be called for that object once it has been removed.
- */
-#define ASTOBJ_CONTAINER_DESTROYALL(container,destructor) \
- do { \
- typeof((container)->head) iterator; \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- while((iterator = (container)->head)) { \
- (container)->head = (iterator)->next[0]; \
- ASTOBJ_UNREF(iterator,destructor); \
- } \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } while(0)
-
-/*! \brief Remove an object from a container.
- *
- * \param container A pointer to the container to operate on.
- * \param obj A pointer to the object to remove.
- *
- * This macro iterates through a container and removes the specfied object if
- * it exists in the container.
- *
- * \note This macro does not destroy any objects, it simply unlinks
- * them from the list. No destructors are called.
- *
- * \return The container's reference to the removed object or NULL if no
- * matching object was found.
- */
-#define ASTOBJ_CONTAINER_UNLINK(container,obj) \
- ({ \
- typeof((container)->head) found = NULL; \
- typeof((container)->head) prev = NULL; \
- ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
- if (iterator == obj) { \
- found = iterator; \
- found->next[0] = NULL; \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- if (prev) \
- prev->next[0] = next; \
- else \
- (container)->head = next; \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } \
- prev = iterator; \
- } while (0)); \
- found; \
- })
-
-/*! \brief Find and remove an object from a container.
- *
- * \param container A pointer to the container to operate on.
- * \param namestr The name of the object to remove.
- *
- * This macro iterates through a container and removes the first object with
- * the specfied name from the container.
- *
- * \note This macro does not destroy any objects, it simply unlinks
- * them. No destructors are called.
- *
- * \return The container's reference to the removed object or NULL if no
- * matching object was found.
- */
-#define ASTOBJ_CONTAINER_FIND_UNLINK(container,namestr) \
- ({ \
- typeof((container)->head) found = NULL; \
- typeof((container)->head) prev = NULL; \
- ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
- if (!(strcasecmp(iterator->name, (namestr)))) { \
- found = iterator; \
- found->next[0] = NULL; \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- if (prev) \
- prev->next[0] = next; \
- else \
- (container)->head = next; \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } \
- prev = iterator; \
- } while (0)); \
- found; \
- })
-
-/*! \brief Find and remove an object in a container.
- *
- * \param container A pointer to the container to search.
- * \param data The data to search for.
- * \param field The field/member of the container's objects to search.
- * \param hashfunc The hash function to use, currently not implemented.
- * \param hashoffset The hash offset to use, currently not implemented.
- * \param comparefunc The function used to compare the field and data values.
- *
- * This macro iterates through a container passing the specified field and data
- * elements to the specified comparefunc. The function should return 0 when a match is found.
- * If a match is found it is removed from the list.
- *
- * \note This macro does not destroy any objects, it simply unlinks
- * them. No destructors are called.
- *
- * \return The container's reference to the removed object or NULL if no match
- * was found.
- */
-#define ASTOBJ_CONTAINER_FIND_UNLINK_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \
- ({ \
- typeof((container)->head) found = NULL; \
- typeof((container)->head) prev = NULL; \
- ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
- ASTOBJ_RDLOCK(iterator); \
- if (!(comparefunc(iterator->field, (data)))) { \
- found = iterator; \
- found->next[0] = NULL; \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- if (prev) \
- prev->next[0] = next; \
- else \
- (container)->head = next; \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } \
- ASTOBJ_UNLOCK(iterator); \
- prev = iterator; \
- } while (0)); \
- found; \
- })
-
-/*! \brief Add an object to the end of a container.
- *
- * \param container A pointer to the container to operate on.
- * \param newobj A pointer to the object to be added.
- *
- * This macro adds an object to the end of a container.
- */
-#define ASTOBJ_CONTAINER_LINK_END(container,newobj) \
- do { \
- typeof((container)->head) iterator; \
- typeof((container)->head) next; \
- typeof((container)->head) prev; \
- ASTOBJ_CONTAINER_RDLOCK(container); \
- prev = NULL; \
- next = (container)->head; \
- while((iterator = next)) { \
- next = iterator->next[0]; \
- prev = iterator; \
- } \
- if(prev) { \
- ASTOBJ_CONTAINER_WRLOCK((container)); \
- prev->next[0] = ASTOBJ_REF(newobj); \
- (newobj)->next[0] = NULL; \
- ASTOBJ_CONTAINER_UNLOCK((container)); \
- } else { \
- ASTOBJ_CONTAINER_LINK_START((container),(newobj)); \
- } \
- ASTOBJ_CONTAINER_UNLOCK((container)); \
- } while(0)
-
-/*! \brief Add an object to the front of a container.
- *
- * \param container A pointer to the container to operate on.
- * \param newobj A pointer to the object to be added.
- *
- * This macro adds an object to the start of a container.
- */
-#define ASTOBJ_CONTAINER_LINK_START(container,newobj) \
- do { \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- (newobj)->next[0] = (container)->head; \
- (container)->head = ASTOBJ_REF(newobj); \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } while(0)
-
-/*! \brief Remove an object from the front of a container.
- *
- * \param container A pointer to the container to operate on.
- *
- * This macro removes the first object in a container.
- *
- * \note This macro does not destroy any objects, it simply unlinks
- * them from the list. No destructors are called.
- *
- * \return The container's reference to the removed object or NULL if no
- * matching object was found.
- */
-#define ASTOBJ_CONTAINER_UNLINK_START(container) \
- ({ \
- typeof((container)->head) found = NULL; \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- if((container)->head) { \
- found = (container)->head; \
- (container)->head = (container)->head->next[0]; \
- found->next[0] = NULL; \
- } \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- found; \
- })
-
-/*! \brief Prune marked objects from a container.
- *
- * \param container A pointer to the container to prune.
- * \param destructor A destructor function to call on each marked object.
- *
- * This macro iterates through the specfied container and prunes any marked
- * objects executing the specfied destructor if necessary.
- */
-#define ASTOBJ_CONTAINER_PRUNE_MARKED(container,destructor) \
- do { \
- typeof((container)->head) prev = NULL; \
- ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { \
- ASTOBJ_RDLOCK(iterator); \
- if (iterator->objflags & ASTOBJ_FLAG_MARKED) { \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- if (prev) \
- prev->next[0] = next; \
- else \
- (container)->head = next; \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- ASTOBJ_UNLOCK(iterator); \
- ASTOBJ_UNREF(iterator,destructor); \
- continue; \
- } \
- ASTOBJ_UNLOCK(iterator); \
- prev = iterator; \
- } while (0)); \
- } while(0)
-
-/*! \brief Add an object to a container.
- *
- * \param container A pointer to the container to operate on.
- * \param newobj A pointer to the object to be added.
- * \param data Currently unused.
- * \param field Currently unused.
- * \param hashfunc Currently unused.
- * \param hashoffset Currently unused.
- * \param comparefunc Currently unused.
- *
- * Currently this function adds an object to the head of the list. One day it
- * will support adding objects atthe position specified using the various
- * options this macro offers.
- */
-#define ASTOBJ_CONTAINER_LINK_FULL(container,newobj,data,field,hashfunc,hashoffset,comparefunc) \
- do { \
- ASTOBJ_CONTAINER_WRLOCK(container); \
- (newobj)->next[0] = (container)->head; \
- (container)->head = ASTOBJ_REF(newobj); \
- ASTOBJ_CONTAINER_UNLOCK(container); \
- } while(0)
-
-#endif /* List model */
-
-/* Common to hash and linked list models */
-
-/*! \brief Create a container for ASTOBJs (without locking support).
- *
- * \param type The type of objects the container will hold.
- *
- * This macro is used to create a container for ASTOBJs without locking
- * support.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct_nolock_container {
- * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(struct sample_struct);
- * };
- * \endcode
- */
-#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type) \
- ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,1,ASTOBJ_DEFAULT_BUCKETS)
-
-
-/*! \brief Create a container for ASTOBJs (with locking support).
- *
- * \param type The type of objects the container will hold.
- *
- * This macro is used to create a container for ASTOBJs with locking support.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct_container {
- * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct);
- * };
- * \endcode
- */
-#define ASTOBJ_CONTAINER_COMPONENTS(type) \
- ast_mutex_t _lock; \
- ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type)
-
-/*! \brief Initialize a container.
- *
- * \param container A pointer to the container to initialize.
- *
- * This macro initializes a container. It should only be used on containers
- * that support locking.
- *
- * <b>Sample Usage:</b>
- * \code
- * struct sample_struct_container {
- * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct);
- * } container;
- *
- * int func()
- * {
- * ASTOBJ_CONTAINER_INIT(&container);
- * }
- * \endcode
- */
-#define ASTOBJ_CONTAINER_INIT(container) \
- ASTOBJ_CONTAINER_INIT_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS)
-
-/*! \brief Destroy a container.
- *
- * \param container A pointer to the container to destory.
- *
- * This macro frees up resources used by a container. It does not operate on
- * the objects in the container. To unlink the objects from the container use
- * #ASTOBJ_CONTAINER_DESTROYALL().
- *
- * \note This macro should only be used on containers with locking support.
- */
-#define ASTOBJ_CONTAINER_DESTROY(container) \
- ASTOBJ_CONTAINER_DESTROY_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS)
-
-/*! \brief Add an object to a container.
- *
- * \param container A pointer to the container to operate on.
- * \param newobj A pointer to the object to be added.
- *
- * Currently this macro adds an object to the head of a container. One day it
- * should add an object in alphabetical order.
- */
-#define ASTOBJ_CONTAINER_LINK(container,newobj) \
- ASTOBJ_CONTAINER_LINK_FULL(container,newobj,(newobj)->name,name,ASTOBJ_DEFAULT_HASH,0,strcasecmp)
-
-/*! \brief Mark all the objects in a container.
- * \param container A pointer to the container to operate on.
- */
-#define ASTOBJ_CONTAINER_MARKALL(container) \
- ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_MARK(iterator))
-
-/*! \brief Unmark all the objects in a container.
- * \param container A pointer to the container to operate on.
- */
-#define ASTOBJ_CONTAINER_UNMARKALL(container) \
- ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_UNMARK(iterator))
-
-/*! \brief Dump information about an object into a string.
- *
- * \param s A pointer to the string buffer to use.
- * \param slen The length of s.
- * \param obj A pointer to the object to dump.
- *
- * This macro dumps a text representation of the name, objectflags, and
- * refcount fields of an object to the specfied string buffer.
- */
-#define ASTOBJ_DUMP(s,slen,obj) \
- snprintf((s),(slen),"name: %s\nobjflags: %d\nrefcount: %d\n\n", (obj)->name, (obj)->objflags, (obj)->refcount);
-
-/*! \brief Dump information about all the objects in a container to a file descriptor.
- *
- * \param fd The file descriptor to write to.
- * \param s A string buffer, same as #ASTOBJ_DUMP().
- * \param slen The length of s, same as #ASTOBJ_DUMP().
- * \param container A pointer to the container to dump.
- *
- * This macro dumps a text representation of the name, objectflags, and
- * refcount fields of all the objects in a container to the specified file
- * descriptor.
- */
-#define ASTOBJ_CONTAINER_DUMP(fd,s,slen,container) \
- ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { ASTOBJ_DUMP(s,slen,iterator); ast_cli(fd, "%s", s); } while(0))
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_ASTOBJ_H */
diff --git a/1.4/include/asterisk/astobj2.h b/1.4/include/asterisk/astobj2.h
deleted file mode 100644
index bcb8addda..000000000
--- a/1.4/include/asterisk/astobj2.h
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * astobj2 - replacement containers for asterisk data structures.
- *
- * Copyright (C) 2006 Marta Carbone, Luigi Rizzo - Univ. di Pisa, Italy
- *
- * 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.
- */
-
-#ifndef _ASTERISK_ASTOBJ2_H
-#define _ASTERISK_ASTOBJ2_H
-
-/*! \file
- *
- * \brief Object Model implementing objects and containers.
-
-These functions implement an abstraction for objects (with
-locks and reference counts) and containers for these user-defined objects,
-supporting locking, reference counting and callbacks.
-
-The internal implementation of the container is opaque to the user,
-so we can use different data structures as needs arise.
-
-At the moment, however, the only internal data structure is a hash
-table. When other structures will be implemented, the initialization
-function may change.
-
-USAGE - OBJECTS
-
-An object is a block of memory that must be allocated with the
-function ao2_alloc(), and for which the system keeps track (with
-abit of help from the programmer) of the number of references around.
-When an object has no more references, it is destroyed, by first
-invoking whatever 'destructor' function the programmer specifies
-(it can be NULL), and then freeing the memory.
-This way objects can be shared without worrying who is in charge
-of freeing them.
-
-Basically, creating an object requires the size of the object and
-and a pointer to the destructor function:
-
- struct foo *o;
-
- o = ao2_alloc(sizeof(struct foo), my_destructor_fn);
-
-The object returned has a refcount = 1.
-Note that the memory for the object is allocated and zeroed.
-- We cannot realloc() the object itself.
-- We cannot call free(o) to dispose of the object; rather we
- tell the system that we do not need the reference anymore:
-
- ao2_ref(o, -1)
-
- causing the destructor to be called (and then memory freed) when
- the refcount goes to 0. This is also available as ao2_unref(o),
- and returns NULL as a convenience, so you can do things like
- o = ao2_unref(o);
- and clean the original pointer to prevent errors.
-
-- ao2_ref(o, +1) can be used to modify the refcount on the
- object in case we want to pass it around.
-
-
-- other calls on the object are ao2_lock(obj), ao2_unlock(),
- ao2_trylock(), to manipulate the lock.
-
-
-USAGE - CONTAINERS
-
-A containers is an abstract data structure where we can store
-objects, search them (hopefully in an efficient way), and iterate
-or apply a callback function to them. A container is just an object
-itself.
-
-A container must first be allocated, specifying the initial
-parameters. At the moment, this is done as follows:
-
- <b>Sample Usage:</b>
- \code
-
- struct ao2_container *c;
-
- c = ao2_container_alloc(MAX_BUCKETS, my_hash_fn, my_cmp_fn);
-
-where
-- MAX_BUCKETS is the number of buckets in the hash table,
-- my_hash_fn() is the (user-supplied) function that returns a
- hash key for the object (further reduced moduly MAX_BUCKETS
- by the container's code);
-- my_cmp_fn() is the default comparison function used when doing
- searches on the container,
-
-A container knows little or nothing about the object itself,
-other than the fact that it has been created by ao2_alloc()
-All knowledge of the (user-defined) internals of the object
-is left to the (user-supplied) functions passed as arguments
-to ao2_container_alloc().
-
-If we want to insert the object in the container, we should
-initialize its fields -- especially, those used by my_hash_fn() --
-to compute the bucket to use.
-Once done, we can link an object to a container with
-
- ao2_link(c, o);
-
-The function returns NULL in case of errors (and the object
-is not inserted in the container). Other values mean success
-(we are not supposed to use the value as a pointer to anything).
-
-\note While an object o is in a container, we expect that
-my_hash_fn(o) will always return the same value. The function
-does not lock the object to be computed, so modifications of
-those fields that affect the computation of the hash should
-be done by extractiong the object from the container, and
-reinserting it after the change (this is not terribly expensive).
-
-\note A container with a single buckets is effectively a linked
-list. However there is no ordering among elements.
-
-Objects implement a reference counter keeping the count
-of the number of references that reference an object.
-
-When this number becomes zero the destructor will be
-called and the object will be free'd.
- */
-
-/*!
- * Invoked just before freeing the memory for the object.
- * It is passed a pointer to user data.
- */
-typedef void (*ao2_destructor_fn)(void *);
-
-void ao2_bt(void); /* backtrace */
-/*!
- * Allocate and initialize an object.
- *
- * \param data_size The sizeof() of user-defined structure.
- * \param destructor_fn The function destructor (can be NULL)
- * \return A pointer to user data.
- *
- * Allocates a struct astobj2 with sufficient space for the
- * user-defined structure.
- * \notes:
- * - storage is zeroed; XXX maybe we want a flag to enable/disable this.
- * - the refcount of the object just created is 1
- * - the returned pointer cannot be free()'d or realloc()'ed;
- * rather, we just call ao2_ref(o, -1);
- */
-void *ao2_alloc(const size_t data_size, ao2_destructor_fn destructor_fn);
-
-/*!
- * Reference/unreference an object and return the old refcount.
- *
- * \param o A pointer to the object
- * \param delta Value to add to the reference counter.
- * \return The value of the reference counter before the operation.
- *
- * Increase/decrease the reference counter according
- * the value of delta.
- *
- * If the refcount goes to zero, the object is destroyed.
- *
- * \note The object must not be locked by the caller of this function, as
- * it is invalid to try to unlock it after releasing the reference.
- *
- * \note if we know the pointer to an object, it is because we
- * have a reference count to it, so the only case when the object
- * can go away is when we release our reference, and it is
- * the last one in existence.
- */
-int ao2_ref(void *o, int delta);
-
-/*!
- * Lock an object.
- *
- * \param a A pointer to the object we want lock.
- * \return 0 on success, other values on error.
- */
-int ao2_lock(void *a);
-
-/*!
- * Unlock an object.
- *
- * \param a A pointer to the object we want unlock.
- * \return 0 on success, other values on error.
- */
-int ao2_unlock(void *a);
-
-/*!
- *
- * Containers
-
-containers are data structures meant to store several objects,
-and perform various operations on them.
-Internally, objects are stored in lists, hash tables or other
-data structures depending on the needs.
-
-NOTA BENE: at the moment the only container we support is the
-hash table and its degenerate form, the list.
-
-Operations on container include:
-
- c = ao2_container_alloc(size, cmp_fn, hash_fn)
- allocate a container with desired size and default compare
- and hash function
-
- ao2_find(c, arg, flags)
- returns zero or more element matching a given criteria
- (specified as arg). Flags indicate how many results we
- want (only one or all matching entries), and whether we
- should unlink the object from the container.
-
- ao2_callback(c, flags, fn, arg)
- apply fn(obj, arg) to all objects in the container.
- Similar to find. fn() can tell when to stop, and
- do anything with the object including unlinking it.
- Note that the entire operation is run with the container
- locked, so noone else can change its content while we work on it.
- However, we pay this with the fact that doing
- anything blocking in the callback keeps the container
- blocked.
- The mechanism is very flexible because the callback function fn()
- can do basically anything e.g. counting, deleting records, etc.
- possibly using arg to store the results.
-
- iterate on a container
- this is done with the following sequence
-
- struct ao2_container *c = ... // our container
- struct ao2_iterator i;
- void *o;
-
- i = ao2_iterator_init(c, flags);
-
- while ( (o = ao2_iterator_next(&i)) ) {
- ... do something on o ...
- ao2_ref(o, -1);
- }
-
- The difference with the callback is that the control
- on how to iterate is left to us.
-
- ao2_ref(c, -1)
- dropping a reference to a container destroys it, very simple!
-
-Containers are astobj2 object themselves, and this is why their
-implementation is simple too.
-
- */
-
-/*!
- * We can perform different operation on an object. We do this
- * according the following flags.
- */
-enum search_flags {
- /*! unlink the object found */
- OBJ_UNLINK = (1 << 0),
- /*! on match, don't return the object or increase its reference count. */
- OBJ_NODATA = (1 << 1),
- /*! don't stop at the first match
- * \note This is not fully implemented. */
- OBJ_MULTIPLE = (1 << 2),
- /*! obj is an object of the same type as the one being searched for.
- * This implies that it can be passed to the object's hash function
- * for optimized searching. */
- OBJ_POINTER = (1 << 3),
-};
-
-/*!
- * Type of a generic function to generate a hash value from an object.
- *
- */
-typedef int (*ao2_hash_fn)(const void *obj, const int flags);
-
-/*!
- * valid callback results:
- * We return a combination of
- * CMP_MATCH when the object matches the request,
- * and CMP_STOP when we should not continue the search further.
- */
-enum _cb_results {
- CMP_MATCH = 0x1,
- CMP_STOP = 0x2,
-};
-
-/*!
- * generic function to compare objects.
- * This, as other callbacks, should return a combination of
- * _cb_results as described above.
- *
- * \param o object from container
- * \param arg search parameters (directly from ao2_find)
- * \param flags passed directly from ao2_find
- * XXX explain.
- */
-
-/*!
- * Type of a generic callback function
- * \param obj pointer to the (user-defined part) of an object.
- * \param arg callback argument from ao2_callback()
- * \param flags flags from ao2_callback()
- * The return values are the same as a compare function.
- * In fact, they are the same thing.
- */
-typedef int (*ao2_callback_fn)(void *obj, void *arg, int flags);
-
-/*!
- * Here start declarations of containers.
- */
-struct ao2_container;
-
-/*!
- * Allocate and initialize a container
- * with the desired number of buckets.
- *
- * We allocate space for a struct astobj_container, struct container
- * and the buckets[] array.
- *
- * \param my_hash_fn Pointer to a function computing a hash value.
- * \param my_cmp_fn Pointer to a function comparating key-value
- * with a string. (can be NULL)
- * \return A pointer to a struct container.
- *
- * destructor is set implicitly.
- */
-struct ao2_container *ao2_container_alloc(const uint n_buckets,
- ao2_hash_fn hash_fn, ao2_callback_fn cmp_fn);
-
-/*!
- * Returns the number of elements in a container.
- */
-int ao2_container_count(struct ao2_container *c);
-
-/*
- * Here we have functions to manage objects.
- *
- * We can use the functions below on any kind of
- * object defined by the user.
- */
-
-/*!
- * \brief Add an object to a container.
- *
- * \param c the container to operate on.
- * \param newobj the object to be added.
- *
- * \return NULL on errors, other values on success.
- *
- * This function inserts an object in a container according its key.
- *
- * \note Remember to set the key before calling this function.
- *
- * \note This function automatically increases the reference count to
- * account for the reference to the object that the container now holds.
- *
- * For Asterisk 1.4 only, there is a dirty hack here to ensure that chan_iax2
- * can have objects linked in to the container at the head instead of tail
- * when it is just a linked list. This is to maintain some existing behavior
- * where the order must be maintained as it was before this conversion so that
- * matching behavior doesn't change.
- */
-#define ao2_link(c, o) __ao2_link(c, o, 0)
-void *__ao2_link(struct ao2_container *c, void *newobj, int iax2_hack);
-
-/*!
- * \brief Remove an object from the container
- *
- * \arg c the container
- * \arg obj the object to unlink
- *
- * \retval NULL, always
- *
- * \note The object requested to be unlinked must be valid. However, if it turns
- * out that it is not in the container, this function is still safe to
- * be called.
- *
- * \note If the object gets unlinked from the container, the container's
- * reference to the object will be automatically released.
- */
-void *ao2_unlink(struct ao2_container *c, void *obj);
-
-/*! \struct Used as return value if the flag OBJ_MULTIPLE is set */
-struct ao2_list {
- struct ao2_list *next;
- void *obj; /* pointer to the user portion of the object */
-};
-
-/*!
- * ao2_callback() and astob2_find() are the same thing with only one difference:
- * the latter uses as a callback the function passed as my_cmp_f() at
- * the time of the creation of the container.
- *
- * \param c A pointer to the container to operate on.
- * \param arg passed to the callback.
- * \param flags A set of flags specifying the operation to perform,
- partially used by the container code, but also passed to
- the callback.
- * \return A pointer to the object found/marked,
- * a pointer to a list of objects matching comparison function,
- * NULL if not found.
- * If the function returns any objects, their refcount is incremented,
- * and the caller is in charge of decrementing them once done.
- * Also, in case of multiple values returned, the list used
- * to store the objects must be freed by the caller.
- *
- * This function searches through a container and performs operations
- * on objects according on flags passed.
- * XXX describe better
- * The comparison is done calling the compare function set implicitly.
- * The p pointer can be a pointer to an object or to a key,
- * we can say this looking at flags value.
- * If p points to an object we will search for the object pointed
- * by this value, otherwise we serch for a key value.
- * If the key is not uniq we only find the first matching valued.
- * If we use the OBJ_MARK flags, we mark all the objects matching
- * the condition.
- *
- * The use of flags argument is the follow:
- *
- * OBJ_UNLINK unlinks the object found
- * OBJ_NODATA on match, do return an object
- * Callbacks use OBJ_NODATA as a default
- * functions such as find() do
- * OBJ_MULTIPLE return multiple matches
- * Default for _find() is no.
- * to a key (not yet supported)
- * OBJ_POINTER the pointer is an object pointer
- *
- * In case we return a list, the callee must take care to destroy
- * that list when no longer used.
- *
- * \note When the returned object is no longer in use, ao2_ref() should
- * be used to free the additional reference possibly created by this function.
- */
-/* XXX order of arguments to find */
-void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags);
-void *ao2_callback(struct ao2_container *c,
- enum search_flags flags,
- ao2_callback_fn cb_fn, void *arg);
-
-int ao2_match_by_addr(void *user_data, void *arg, int flags);
-/*!
- *
- *
- * When we need to walk through a container, we use
- * ao2_iterator to keep track of the current position.
- *
- * Because the navigation is typically done without holding the
- * lock on the container across the loop,
- * objects can be inserted or deleted or moved
- * while we work. As a consequence, there is no guarantee that
- * the we manage to touch all the elements on the list, or it
- * is possible that we touch the same object multiple times.
- * However, within the current hash table container, the following is true:
- * - It is not possible to miss an object in the container while iterating
- * unless it gets added after the iteration begins and is added to a bucket
- * that is before the one the current object is in. In this case, even if
- * you locked the container around the entire iteration loop, you still would
- * not see this object, because it would still be waiting on the container
- * lock so that it can be added.
- * - It would be extremely rare to see an object twice. The only way this can
- * happen is if an object got unlinked from the container and added again
- * during the same iteration. Furthermore, when the object gets added back,
- * it has to be in the current or later bucket for it to be seen again.
- *
- * An iterator must be first initialized with ao2_iterator_init(),
- * then we can use o = ao2_iterator_next() to move from one
- * element to the next. Remember that the object returned by
- * ao2_iterator_next() has its refcount incremented,
- * and the reference must be explicitly released when done with it.
- *
- * Example:
- *
- * \code
- *
- * struct ao2_container *c = ... // the container we want to iterate on
- * struct ao2_iterator i;
- * struct my_obj *o;
- *
- * i = ao2_iterator_init(c, flags);
- *
- * while ( (o = ao2_iterator_next(&i)) ) {
- * ... do something on o ...
- * ao2_ref(o, -1);
- * }
- *
- * \endcode
- *
- */
-
-/*!
- * You are not supposed to know the internals of an iterator!
- * We would like the iterator to be opaque, unfortunately
- * its size needs to be known if we want to store it around
- * without too much trouble.
- * Anyways...
- * The iterator has a pointer to the container, and a flags
- * field specifying various things e.g. whether the container
- * should be locked or not while navigating on it.
- * The iterator "points" to the current object, which is identified
- * by three values:
- * - a bucket number;
- * - the object_id, which is also the container version number
- * when the object was inserted. This identifies the object
- * univoquely, however reaching the desired object requires
- * scanning a list.
- * - a pointer, and a container version when we saved the pointer.
- * If the container has not changed its version number, then we
- * can safely follow the pointer to reach the object in constant time.
- * Details are in the implementation of ao2_iterator_next()
- * A freshly-initialized iterator has bucket=0, version = 0.
- */
-
-struct ao2_iterator {
- /*! the container */
- struct ao2_container *c;
- /*! operation flags */
- int flags;
-#define F_AO2I_DONTLOCK 1 /*!< don't lock when iterating */
- /*! current bucket */
- int bucket;
- /*! container version */
- uint c_version;
- /*! pointer to the current object */
- void *obj;
- /*! container version when the object was created */
- uint version;
-};
-
-struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
-
-void *ao2_iterator_next(struct ao2_iterator *a);
-
-#endif /* _ASTERISK_ASTOBJ2_H */
diff --git a/1.4/include/asterisk/astosp.h b/1.4/include/asterisk/astosp.h
deleted file mode 100644
index 75ee76fc5..000000000
--- a/1.4/include/asterisk/astosp.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*!
- * \file
- * \brief Open Settlement Protocol (OSP)
- */
-
-#ifndef _ASTERISK_OSP_H
-#define _ASTERISK_OSP_H
-
-#define AST_OSP_SUCCESS ((char*)"SUCCESS") /* Return status, success */
-#define AST_OSP_FAILED ((char*)"FAILED") /* Return status, failed */
-#define AST_OSP_ERROR ((char*)"ERROR") /* Return status, error */
-
-#endif /* _ASTERISK_OSP_H */
diff --git a/1.4/include/asterisk/audiohook.h b/1.4/include/asterisk/audiohook.h
deleted file mode 100644
index cafc5ef14..000000000
--- a/1.4/include/asterisk/audiohook.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- * \brief Audiohooks Architecture
- */
-
-#ifndef _ASTERISK_AUDIOHOOK_H
-#define _ASTERISK_AUDIOHOOK_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include "asterisk/slinfactory.h"
-
-enum ast_audiohook_type {
- AST_AUDIOHOOK_TYPE_SPY = 0, /*!< Audiohook wants to receive audio */
- AST_AUDIOHOOK_TYPE_WHISPER, /*!< Audiohook wants to provide audio to be mixed with existing audio */
- AST_AUDIOHOOK_TYPE_MANIPULATE, /*!< Audiohook wants to manipulate the audio */
-};
-
-enum ast_audiohook_status {
- AST_AUDIOHOOK_STATUS_NEW = 0, /*!< Audiohook was just created, not in use yet */
- AST_AUDIOHOOK_STATUS_RUNNING, /*!< Audiohook is running on a channel */
- AST_AUDIOHOOK_STATUS_SHUTDOWN, /*!< Audiohook is being shutdown */
- AST_AUDIOHOOK_STATUS_DONE, /*!< Audiohook has shutdown and is not running on a channel any longer */
-};
-
-enum ast_audiohook_direction {
- AST_AUDIOHOOK_DIRECTION_READ = 0, /*!< Reading audio in */
- AST_AUDIOHOOK_DIRECTION_WRITE, /*!< Writing audio out */
- AST_AUDIOHOOK_DIRECTION_BOTH, /*!< Both reading audio in and writing audio out */
-};
-
-enum ast_audiohook_flags {
- AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0), /*!< When audiohook should be triggered to do something */
- AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), /*!< Audiohook wants to be triggered when reading audio in */
- AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */
- AST_AUDIOHOOK_WANTS_DTMF = (1 << 1), /*!< Audiohook also wants to receive DTMF frames */
- AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2), /*!< Audiohook wants to be triggered when both sides have combined audio available */
-};
-
-struct ast_audiohook;
-
-/*! \brief Callback function for manipulate audiohook type
- * \param audiohook Audiohook structure
- * \param chan Channel
- * \param frame Frame of audio to manipulate
- * \param direction Direction frame came from
- * \return Returns 0 on success, -1 on failure
- * \note An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data
- * via it's own method. An example would be datastores.
- */
-typedef int (*ast_audiohook_manipulate_callback)(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction);
-
-struct ast_audiohook_options {
- int read_volume; /*!< Volume adjustment on frames read from the channel the hook is on */
- int write_volume; /*!< Volume adjustment on frames written to the channel the hook is on */
-};
-
-struct ast_audiohook {
- ast_mutex_t lock; /*!< Lock that protects the audiohook structure */
- ast_cond_t trigger; /*!< Trigger condition (if enabled) */
- enum ast_audiohook_type type; /*!< Type of audiohook */
- enum ast_audiohook_status status; /*!< Status of the audiohook */
- const char *source; /*!< Who this audiohook ultimately belongs to */
- unsigned int flags; /*!< Flags on the audiohook */
- struct ast_slinfactory read_factory; /*!< Factory where frames read from the channel, or read from the whisper source will go through */
- struct ast_slinfactory write_factory; /*!< Factory where frames written to the channel will go through */
- struct timeval read_time; /*!< Last time read factory was fed */
- struct timeval write_time; /*!< Last time write factory was fed */
- int format; /*!< Format translation path is setup as */
- struct ast_trans_pvt *trans_pvt; /*!< Translation path for reading frames */
- ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */
- struct ast_audiohook_options options; /*!< Applicable options */
- AST_LIST_ENTRY(ast_audiohook) list; /*!< Linked list information */
-};
-
-struct ast_audiohook_list;
-
-/*! \brief Initialize an audiohook structure
- * \param audiohook Audiohook structure
- * \param type Type of audiohook to initialize this as
- * \param source Who is initializing this audiohook
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source);
-
-/*! \brief Destroys an audiohook structure
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_destroy(struct ast_audiohook *audiohook);
-
-/*! \brief Writes a frame into the audiohook structure
- * \param audiohook Audiohook structure
- * \param direction Direction the audio frame came from
- * \param frame Frame to write in
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame);
-
-/*! \brief Reads a frame in from the audiohook structure
- * \param audiohook Audiohook structure
- * \param samples Number of samples wanted
- * \param direction Direction the audio frame came from
- * \param format Format of frame remote side wants back
- * \return Returns frame on success, NULL on failure
- */
-struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, int format);
-
-/*! \brief Attach audiohook to channel
- * \param chan Channel
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook);
-
-/*! \brief Detach audiohook from channel
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach(struct ast_audiohook *audiohook);
-
-/*! \brief Detach audiohooks from list and destroy said list
- * \param audiohook_list List of audiohooks
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list);
-
-/*! \brief Detach specified source audiohook from channel
- * \param chan Channel to detach from
- * \param source Name of source to detach
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach_source(struct ast_channel *chan, const char *source);
-
-/*! \brief Pass a frame off to be handled by the audiohook core
- * \param chan Channel that the list is coming off of
- * \param audiohook_list List of audiohooks
- * \param direction Direction frame is coming in from
- * \param frame The frame itself
- * \return Return frame on success, NULL on failure
- */
-struct ast_frame *ast_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame);
-
-/*! \brief Wait for audiohook trigger to be triggered
- * \param audiohook Audiohook to wait on
- */
-void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook);
-
-/*! \brief Lock an audiohook
- * \param ah Audiohook structure
- */
-#define ast_audiohook_lock(ah) ast_mutex_lock(&(ah)->lock)
-
-/*! \brief Unlock an audiohook
- * \param ah Audiohook structure
- */
-#define ast_audiohook_unlock(ah) ast_mutex_unlock(&(ah)->lock)
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_AUDIOHOOK_H */
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- * \brief Audiohooks Architecture
- */
-
-#ifndef _ASTERISK_AUDIOHOOK_H
-#define _ASTERISK_AUDIOHOOK_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include "asterisk/slinfactory.h"
-
-enum ast_audiohook_type {
- AST_AUDIOHOOK_TYPE_SPY = 0, /*!< Audiohook wants to receive audio */
- AST_AUDIOHOOK_TYPE_WHISPER, /*!< Audiohook wants to provide audio to be mixed with existing audio */
- AST_AUDIOHOOK_TYPE_MANIPULATE, /*!< Audiohook wants to manipulate the audio */
-};
-
-enum ast_audiohook_status {
- AST_AUDIOHOOK_STATUS_NEW = 0, /*!< Audiohook was just created, not in use yet */
- AST_AUDIOHOOK_STATUS_RUNNING, /*!< Audiohook is running on a channel */
- AST_AUDIOHOOK_STATUS_SHUTDOWN, /*!< Audiohook is being shutdown */
- AST_AUDIOHOOK_STATUS_DONE, /*!< Audiohook has shutdown and is not running on a channel any longer */
-};
-
-enum ast_audiohook_direction {
- AST_AUDIOHOOK_DIRECTION_READ = 0, /*!< Reading audio in */
- AST_AUDIOHOOK_DIRECTION_WRITE, /*!< Writing audio out */
- AST_AUDIOHOOK_DIRECTION_BOTH, /*!< Both reading audio in and writing audio out */
-};
-
-enum ast_audiohook_flags {
- AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0), /*!< When audiohook should be triggered to do something */
- AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), /*!< Audiohook wants to be triggered when reading audio in */
- AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */
- AST_AUDIOHOOK_WANTS_DTMF = (1 << 1), /*!< Audiohook also wants to receive DTMF frames */
-};
-
-struct ast_audiohook;
-
-/*! \brief Callback function for manipulate audiohook type
- * \param audiohook Audiohook structure
- * \param chan Channel
- * \param frame Frame of audio to manipulate
- * \param direction Direction frame came from
- * \return Returns 0 on success, -1 on failure
- * \note An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data
- * via it's own method. An example would be datastores.
- */
-typedef int (*ast_audiohook_manipulate_callback)(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction);
-
-struct ast_audiohook_options {
- int read_volume; /*!< Volume adjustment on frames read from the channel the hook is on */
- int write_volume; /*!< Volume adjustment on frames written to the channel the hook is on */
-};
-
-struct ast_audiohook {
- ast_mutex_t lock; /*!< Lock that protects the audiohook structure */
- ast_cond_t trigger; /*!< Trigger condition (if enabled) */
- enum ast_audiohook_type type; /*!< Type of audiohook */
- enum ast_audiohook_status status; /*!< Status of the audiohook */
- const char *source; /*!< Who this audiohook ultimately belongs to */
- unsigned int flags; /*!< Flags on the audiohook */
- struct ast_slinfactory read_factory; /*!< Factory where frames read from the channel, or read from the whisper source will go through */
- struct ast_slinfactory write_factory; /*!< Factory where frames written to the channel will go through */
- int format; /*!< Format translation path is setup as */
- struct ast_trans_pvt *trans_pvt; /*!< Translation path for reading frames */
- ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */
- struct ast_audiohook_options options; /*!< Applicable options */
- AST_LIST_ENTRY(ast_audiohook) list; /*!< Linked list information */
-};
-
-struct ast_audiohook_list;
-
-/*! \brief Initialize an audiohook structure
- * \param audiohook Audiohook structure
- * \param type Type of audiohook to initialize this as
- * \param source Who is initializing this audiohook
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source);
-
-/*! \brief Destroys an audiohook structure
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_destroy(struct ast_audiohook *audiohook);
-
-/*! \brief Writes a frame into the audiohook structure
- * \param audiohook Audiohook structure
- * \param direction Direction the audio frame came from
- * \param frame Frame to write in
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame);
-
-/*! \brief Reads a frame in from the audiohook structure
- * \param audiohook Audiohook structure
- * \param samples Number of samples wanted
- * \param direction Direction the audio frame came from
- * \param format Format of frame remote side wants back
- * \return Returns frame on success, NULL on failure
- */
-struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, int format);
-
-/*! \brief Attach audiohook to channel
- * \param chan Channel
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook);
-
-/*! \brief Detach audiohook from channel
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach(struct ast_audiohook *audiohook);
-
-/*! \brief Detach audiohooks from list and destroy said list
- * \param audiohook_list List of audiohooks
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list);
-
-/*! \brief Detach specified source audiohook from channel
- * \param chan Channel to detach from
- * \param source Name of source to detach
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach_source(struct ast_channel *chan, const char *source);
-
-/*! \brief Pass a frame off to be handled by the audiohook core
- * \param chan Channel that the list is coming off of
- * \param audiohook_list List of audiohooks
- * \param direction Direction frame is coming in from
- * \param frame The frame itself
- * \return Return frame on success, NULL on failure
- */
-struct ast_frame *ast_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame);
-
-/*! \brief Wait for audiohook trigger to be triggered
- * \param audiohook Audiohook to wait on
- */
-void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook);
-
-/*! \brief Lock an audiohook
- * \param ah Audiohook structure
- */
-#define ast_audiohook_lock(ah) ast_mutex_lock(&(ah)->lock)
-
-/*! \brief Unlock an audiohook
- * \param ah Audiohook structure
- */
-#define ast_audiohook_unlock(ah) ast_mutex_unlock(&(ah)->lock)
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_AUDIOHOOK_H */
diff --git a/1.4/include/asterisk/autoconfig.h.in b/1.4/include/asterisk/autoconfig.h.in
deleted file mode 100644
index 07496c355..000000000
--- a/1.4/include/asterisk/autoconfig.h.in
+++ /dev/null
@@ -1,689 +0,0 @@
-/* include/asterisk/autoconfig.h.in. Generated from configure.ac by autoheader. */
-
-#ifndef ASTERISK_AUTOCONFIG_H
-#define ASTERISK_AUTOCONFIG_H
-
-#include "asterisk/buildopts.h"
-
-
-
-/* Define to 1 if the `closedir' function returns void instead of `int'. */
-#undef CLOSEDIR_VOID
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
- systems. This function is required for `alloca.c' support on those systems.
- */
-#undef CRAY_STACKSEG_END
-
-/* Define to 1 if using `alloca.c'. */
-#undef C_ALLOCA
-
-/* Define to 1 if you have `alloca', as a function or macro. */
-#undef HAVE_ALLOCA
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
- */
-#undef HAVE_ALLOCA_H
-
-/* Define to indicate the ${ALSA_DESCRIP} library */
-#undef HAVE_ALSA
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Define to 1 if you have the `asprintf' function. */
-#undef HAVE_ASPRINTF
-
-/* Define to 1 if you have the `atexit' function. */
-#undef HAVE_ATEXIT
-
-/* Define to 1 if your GCC C compiler supports the 'always_inline' attribute.
- */
-#undef HAVE_ATTRIBUTE_always_inline
-
-/* Define to 1 if your GCC C compiler supports the 'const' attribute. */
-#undef HAVE_ATTRIBUTE_const
-
-/* Define to 1 if your GCC C compiler supports the 'deprecated' attribute. */
-#undef HAVE_ATTRIBUTE_deprecated
-
-/* Define to 1 if your GCC C compiler supports the 'malloc' attribute. */
-#undef HAVE_ATTRIBUTE_malloc
-
-/* Define to 1 if your GCC C compiler supports the 'pure' attribute. */
-#undef HAVE_ATTRIBUTE_pure
-
-/* Define to 1 if your GCC C compiler supports the 'unused' attribute. */
-#undef HAVE_ATTRIBUTE_unused
-
-/* Define to 1 if you have the `bzero' function. */
-#undef HAVE_BZERO
-
-/* Define to indicate the ${CAP_DESCRIP} library */
-#undef HAVE_CAP
-
-/* Define to 1 if your system has a working `chown' function. */
-#undef HAVE_CHOWN
-
-/* Define if your system has the curl libraries. */
-#undef HAVE_CURL
-
-/* Define to indicate the ${CURSES_DESCRIP} library */
-#undef HAVE_CURSES
-
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
- */
-#undef HAVE_DIRENT_H
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
-/* Define to 1 if you have the `dup2' function. */
-#undef HAVE_DUP2
-
-/* Define to 1 if you have the `endpwent' function. */
-#undef HAVE_ENDPWENT
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `floor' function. */
-#undef HAVE_FLOOR
-
-/* Define to 1 if you have the `fork' function. */
-#undef HAVE_FORK
-
-/* Define to indicate the ${FREETDS_DESCRIP} library */
-#undef HAVE_FREETDS
-
-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
-#undef HAVE_FSEEKO
-
-/* Define to 1 if you have the `ftruncate' function. */
-#undef HAVE_FTRUNCATE
-
-/* Define to 1 if your GCC C compiler provides atomic operations. */
-#undef HAVE_GCC_ATOMICS
-
-/* Define to 1 if you have the `getcwd' function. */
-#undef HAVE_GETCWD
-
-/* Define to 1 if you have the `gethostbyname' function. */
-#undef HAVE_GETHOSTBYNAME
-
-/* Define to 1 if your system has gethostbyname_r with 5 arguments. */
-#undef HAVE_GETHOSTBYNAME_R_5
-
-/* Define to 1 if your system has gethostbyname_r with 6 arguments. */
-#undef HAVE_GETHOSTBYNAME_R_6
-
-/* Define to 1 if you have the `gethostname' function. */
-#undef HAVE_GETHOSTNAME
-
-/* Define if your system has the GETIFADDRS headers. */
-#undef HAVE_GETIFADDRS
-
-/* Define GETIFADDRS headers version */
-#undef HAVE_GETIFADDRS_VERSION
-
-/* Define to 1 if you have the `getloadavg' function. */
-#undef HAVE_GETLOADAVG
-
-/* Define to 1 if you have the `getpagesize' function. */
-#undef HAVE_GETPAGESIZE
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define to indicate the ${GNUTLS_DESCRIP} library */
-#undef HAVE_GNUTLS
-
-/* Define to indicate the GSM library */
-#undef HAVE_GSM
-
-/* Define to indicate that gsm.h is in gsm/gsm.h */
-#undef HAVE_GSM_GSM_HEADER
-
-/* Define to indicate that gsm.h has no prefix for its location */
-#undef HAVE_GSM_HEADER
-
-/* Define if your system has the GTK libraries. */
-#undef HAVE_GTK
-
-/* Define if your system has the GTK2 libraries. */
-#undef HAVE_GTK2
-
-/* Define to indicate the ${IKSEMEL_DESCRIP} library */
-#undef HAVE_IKSEMEL
-
-/* Define if your system has the UW IMAP Toolkit c-client library. */
-#undef HAVE_IMAP_TK
-
-/* Define if your system has the UW IMAP Toolkit c-client library version 2006
- or greater. */
-#undef HAVE_IMAP_TK2006
-
-/* Define to 1 if you have the `inet_ntoa' function. */
-#undef HAVE_INET_NTOA
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if your system has PMTU discovery on UDP sockets. */
-#undef HAVE_IP_MTU_DISCOVER
-
-/* Define to 1 if you have the `isascii' function. */
-#undef HAVE_ISASCII
-
-/* Define to indicate the ${ISDNNET_DESCRIP} library */
-#undef HAVE_ISDNNET
-
-/* Define to 1 if you have the <libintl.h> header file. */
-#undef HAVE_LIBINTL_H
-
-/* Define if your system has the KDE libraries. */
-#undef HAVE_LIBKDE
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if your system has linux/compiler.h. */
-#undef HAVE_LINUX_COMPILER_H
-
-/* Define to 1 if you have the <locale.h> header file. */
-#undef HAVE_LOCALE_H
-
-/* Define to 1 if you have the `localtime_r' function. */
-#undef HAVE_LOCALTIME_R
-
-/* Define to indicate the ${LTDL_DESCRIP} library */
-#undef HAVE_LTDL
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
-/* Define to 1 if you have the `memchr' function. */
-#undef HAVE_MEMCHR
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `memset' function. */
-#undef HAVE_MEMSET
-
-/* Define to indicate the ${MISDN_DESCRIP} library */
-#undef HAVE_MISDN
-
-/* Define to 1 if you have the `mkdir' function. */
-#undef HAVE_MKDIR
-
-/* Define to 1 if you have a working `mmap' system call. */
-#undef HAVE_MMAP
-
-/* Define to 1 if you have the `munmap' function. */
-#undef HAVE_MUNMAP
-
-/* Define to indicate the ${NBS_DESCRIP} library */
-#undef HAVE_NBS
-
-/* Define to indicate the ${NCURSES_DESCRIP} library */
-#undef HAVE_NCURSES
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-#undef HAVE_NDIR_H
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#undef HAVE_NETDB_H
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
-
-/* Define to indicate the Net-SNMP library */
-#undef HAVE_NETSNMP
-
-/* Define to indicate the ${NEWT_DESCRIP} library */
-#undef HAVE_NEWT
-
-/* Define to indicate the ${OGG_DESCRIP} library */
-#undef HAVE_OGG
-
-/* Define if your system has the OpenH323 libraries. */
-#undef HAVE_OPENH323
-
-/* Define to indicate the ${OPENSSL_DESCRIP} library */
-#undef HAVE_OPENSSL
-
-/* Define to indicate the ${OSPTK_DESCRIP} library */
-#undef HAVE_OSPTK
-
-/* Define to indicate the ${OSS_DESCRIP} library */
-#undef HAVE_OSS
-
-/* Define to 1 if OSX atomic operations are supported. */
-#undef HAVE_OSX_ATOMICS
-
-/* Define to indicate the PostgreSQL library */
-#undef HAVE_PGSQL
-
-/* Define to indicate the ${POPT_DESCRIP} library */
-#undef HAVE_POPT
-
-/* Define to 1 if you have the `pow' function. */
-#undef HAVE_POW
-
-/* Define to indicate the ${PRI_DESCRIP} library */
-#undef HAVE_PRI
-
-/* Define to indicate the ${PRI_VERSION_DESCRIP} library */
-#undef HAVE_PRI_VERSION
-
-/* Define if you have POSIX threads libraries and header files. */
-#undef HAVE_PTHREAD
-
-/* Define to 1 if your system has PTHREAD_RWLOCK_INITIALIZER. */
-#undef HAVE_PTHREAD_RWLOCK_INITIALIZER
-
-/* Define to 1 if your system has PTHREAD_RWLOCK_PREFER_WRITER_NP. */
-#undef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
-
-/* Define to 1 if the system has the type `ptrdiff_t'. */
-#undef HAVE_PTRDIFF_T
-
-/* Define to 1 if you have the `putenv' function. */
-#undef HAVE_PUTENV
-
-/* Define if your system has the PWLib libraries. */
-#undef HAVE_PWLIB
-
-/* Define to indicate the ${RADIUS_DESCRIP} library */
-#undef HAVE_RADIUS
-
-/* Define to 1 if you have the `regcomp' function. */
-#undef HAVE_REGCOMP
-
-/* Define to 1 if your system has the ndestroy resolver function. */
-#undef HAVE_RES_NDESTROY
-
-/* Define to 1 if your system has the re-entrant resolver functions. */
-#undef HAVE_RES_NINIT
-
-/* Define to 1 if you have the `re_comp' function. */
-#undef HAVE_RE_COMP
-
-/* Define to 1 if you have the `rint' function. */
-#undef HAVE_RINT
-
-/* Define to 1 if your system has a dynamic linker that supports RTLD_NOLOAD.
- */
-#undef HAVE_RTLD_NOLOAD
-
-/* Define to 1 if your system has /sbin/launchd. */
-#undef HAVE_SBIN_LAUNCHD
-
-/* Define to 1 if you have the `select' function. */
-#undef HAVE_SELECT
-
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
-/* Define to 1 if you have the `socket' function. */
-#undef HAVE_SOCKET
-
-/* Define to 1 if your system has soxmix application. */
-#undef HAVE_SOXMIX
-
-/* Define to indicate the ${SPEEX_DESCRIP} library */
-#undef HAVE_SPEEX
-
-/* Define to indicate the ${SPEEXDSP_DESCRIP} library */
-#undef HAVE_SPEEXDSP
-
-/* Define to indicate the ${SPEEX_PREPROCESS_DESCRIP} library */
-#undef HAVE_SPEEX_PREPROCESS
-
-/* Define to indicate the ${SQLITE_DESCRIP} library */
-#undef HAVE_SQLITE
-
-/* Define to 1 if you have the `sqrt' function. */
-#undef HAVE_SQRT
-
-/* Define to 1 if `stat' has the bug that it succeeds when given the
- zero-length file name argument. */
-#undef HAVE_STAT_EMPTY_STRING_BUG
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#undef HAVE_STDBOOL_H
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#undef HAVE_STDDEF_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strcasestr' function. */
-#undef HAVE_STRCASESTR
-
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the `strcoll' function and it is properly defined.
- */
-#undef HAVE_STRCOLL
-
-/* Define to 1 if you have the `strcspn' function. */
-#undef HAVE_STRCSPN
-
-/* Define to 1 if you have the `strdup' function. */
-#undef HAVE_STRDUP
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
-/* Define to 1 if you have the `strftime' function. */
-#undef HAVE_STRFTIME
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strlcat' function. */
-#undef HAVE_STRLCAT
-
-/* Define to 1 if you have the `strlcpy' function. */
-#undef HAVE_STRLCPY
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#undef HAVE_STRNCASECMP
-
-/* Define to 1 if you have the `strndup' function. */
-#undef HAVE_STRNDUP
-
-/* Define to 1 if you have the `strnlen' function. */
-#undef HAVE_STRNLEN
-
-/* Define to 1 if you have the `strrchr' function. */
-#undef HAVE_STRRCHR
-
-/* Define to 1 if you have the `strsep' function. */
-#undef HAVE_STRSEP
-
-/* Define to 1 if you have the `strspn' function. */
-#undef HAVE_STRSPN
-
-/* Define to 1 if you have the `strstr' function. */
-#undef HAVE_STRSTR
-
-/* Define to 1 if you have the `strtol' function. */
-#undef HAVE_STRTOL
-
-/* Define to 1 if you have the `strtoq' function. */
-#undef HAVE_STRTOQ
-
-/* Define to 1 if `st_blksize' is member of `struct stat'. */
-#undef HAVE_STRUCT_STAT_ST_BLKSIZE
-
-/* Define to indicate the ${SUPPSERV_DESCRIP} library */
-#undef HAVE_SUPPSERV
-
-/* Define to 1 if you have the <syslog.h> header file. */
-#undef HAVE_SYSLOG_H
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-#undef HAVE_SYS_DIR_H
-
-/* Define to 1 if you have the <sys/file.h> header file. */
-#undef HAVE_SYS_FILE_H
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#undef HAVE_SYS_IOCTL_H
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-#undef HAVE_SYS_NDIR_H
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to indicate the ${TERMCAP_DESCRIP} library */
-#undef HAVE_TERMCAP
-
-/* Define to 1 if you have the <termios.h> header file. */
-#undef HAVE_TERMIOS_H
-
-/* Define to indicate the ${TINFO_DESCRIP} library */
-#undef HAVE_TINFO
-
-/* Define to indicate the ${TONEZONE_DESCRIP} library */
-#undef HAVE_TONEZONE
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to indicate the ${UNIXODBC_DESCRIP} library */
-#undef HAVE_UNIXODBC
-
-/* Define to 1 if you have the `unsetenv' function. */
-#undef HAVE_UNSETENV
-
-/* Define to indicate the ${USB_DESCRIP} library */
-#undef HAVE_USB
-
-/* Define to 1 if you have the `utime' function. */
-#undef HAVE_UTIME
-
-/* Define to 1 if you have the <utime.h> header file. */
-#undef HAVE_UTIME_H
-
-/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
-#undef HAVE_UTIME_NULL
-
-/* Define to 1 if you have the `vasprintf' function. */
-#undef HAVE_VASPRINTF
-
-/* Define to 1 if you have the `vfork' function. */
-#undef HAVE_VFORK
-
-/* Define to 1 if you have the <vfork.h> header file. */
-#undef HAVE_VFORK_H
-
-/* Define to indicate the ${VORBIS_DESCRIP} library */
-#undef HAVE_VORBIS
-
-/* Define if your system has the VoiceTronix API libraries. */
-#undef HAVE_VPB
-
-/* Define to 1 if you have the `vprintf' function. */
-#undef HAVE_VPRINTF
-
-/* Define to 1 if `fork' works. */
-#undef HAVE_WORKING_FORK
-
-/* Define to 1 if `vfork' works. */
-#undef HAVE_WORKING_VFORK
-
-/* Define if your system has the Zaptel headers. */
-#undef HAVE_ZAPTEL
-
-/* Define to indicate the ${ZLIB_DESCRIP} library */
-#undef HAVE_ZLIB
-
-/* Define to 1 if the system has the type `_Bool'. */
-#undef HAVE__BOOL
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
-
-/* Build chan_misdn for mISDN 1.2 or later. */
-#undef MISDN_1_2
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if the C compiler supports function prototypes. */
-#undef PROTOTYPES
-
-/* Define to necessary symbol if this constant uses a non-standard name on
- your system. */
-#undef PTHREAD_CREATE_JOINABLE
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Define to the type of arg 1 for `select'. */
-#undef SELECT_TYPE_ARG1
-
-/* Define to the type of args 2, 3 and 4 for `select'. */
-#undef SELECT_TYPE_ARG234
-
-/* Define to the type of arg 5 for `select'. */
-#undef SELECT_TYPE_ARG5
-
-/* Define to 1 if the `setvbuf' function takes the buffering type as its
- second argument and the buffer pointer as the third, as on System V before
- release 3. */
-#undef SETVBUF_REVERSED
-
-/* The size of `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at runtime.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-#undef STACK_DIRECTION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-#undef TM_IN_SYS_TIME
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
-#endif
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-#undef _LARGEFILE_SOURCE
-
-/* Define for large files, on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
-
-/* Enable extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-
-/* Define like PROTOTYPES; this can be used by system headers. */
-#undef __PROTOTYPES
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef mode_t
-
-/* Define to `long int' if <sys/types.h> does not define. */
-#undef off_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
-
-/* Define as `fork' if `vfork' does not work. */
-#undef vfork
-
-/* Define to empty if the keyword `volatile' does not work. Warning: valid
- code using `volatile' can become incorrect without. Disable with care. */
-#undef volatile
-
-#endif
-
diff --git a/1.4/include/asterisk/callerid.h b/1.4/include/asterisk/callerid.h
deleted file mode 100644
index 7347dd9d0..000000000
--- a/1.4/include/asterisk/callerid.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief CallerID (and other GR30) management and generation
- * Includes code and algorithms from the Zapata library.
- *
- */
-
-/*!
- * \page CID Caller ID names and numbers
- *
- * Caller ID names are currently 8 bit characters, propably
- * ISO8859-1, depending on what your channel drivers handle.
- *
- * IAX2 and SIP caller ID names are UTF8
- * On ISDN Caller ID names are 7 bit, Almost ASCII
- * (See http://www.zytrax.com/tech/ia5.html )
- *
- * \note Asterisk does not currently support SIP utf8 caller ID names or caller ID's.
- *
- * \par See also
- * \arg \ref callerid.c
- * \arg \ref callerid.h
- * \arg \ref Def_CallerPres
- */
-
-#ifndef _ASTERISK_CALLERID_H
-#define _ASTERISK_CALLERID_H
-
-#define MAX_CALLERID_SIZE 32000
-
-#define CID_PRIVATE_NAME (1 << 0)
-#define CID_PRIVATE_NUMBER (1 << 1)
-#define CID_UNKNOWN_NAME (1 << 2)
-#define CID_UNKNOWN_NUMBER (1 << 3)
-
-#define CID_SIG_BELL 1
-#define CID_SIG_V23 2
-#define CID_SIG_DTMF 3
-#define CID_SIG_V23_JP 4
-#define CID_SIG_SMDI 5
-
-#define CID_START_RING 1
-#define CID_START_POLARITY 2
-
-
-#define AST_LIN2X(a) ((codec == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a)))
-#define AST_XLAW(a) ((codec == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a)))
-
-
-struct callerid_state;
-typedef struct callerid_state CIDSTATE;
-
-/*! \brief CallerID Initialization
- * \par
- * Initializes the callerid system. Mostly stuff for inverse FFT
- */
-void callerid_init(void);
-
-/*! \brief Generates a CallerID FSK stream in ulaw format suitable for transmission.
- * \param buf Buffer to use. If "buf" is supplied, it will use that buffer instead of allocating its own. "buf" must be at least 32000 bytes in size of you want to be sure you don't have an overrun.
- * \param number Use NULL for no number or "P" for "private"
- * \param name name to be used
- * \param flags passed flags
- * \param callwaiting callwaiting flag
- * \param codec -- either AST_FORMAT_ULAW or AST_FORMAT_ALAW
- * This function creates a stream of callerid (a callerid spill) data in ulaw format.
- * \return It returns the size
- * (in bytes) of the data (if it returns a size of 0, there is probably an error)
-*/
-int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec);
-
-/*! \brief Create a callerID state machine
- * \param cid_signalling Type of signalling in use
- *
- * This function returns a malloc'd instance of the callerid_state data structure.
- * \return Returns a pointer to a malloc'd callerid_state structure, or NULL on error.
- */
-struct callerid_state *callerid_new(int cid_signalling);
-
-/*! \brief Read samples into the state machine.
- * \param cid Which state machine to act upon
- * \param ubuf containing your samples
- * \param samples number of samples contained within the buffer.
- * \param codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
- *
- * Send received audio to the Caller*ID demodulator.
- * \return Returns -1 on error, 0 for "needs more samples",
- * and 1 if the CallerID spill reception is complete.
- */
-int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, int codec);
-
-/*! \brief Read samples into the state machine.
- * \param cid Which state machine to act upon
- * \param ubuf containing your samples
- * \param samples number of samples contained within the buffer.
- * \param codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
- *
- * Send received audio to the Caller*ID demodulator (for japanese style lines).
- * \return Returns -1 on error, 0 for "needs more samples",
- * and 1 if the CallerID spill reception is complete.
- */
-int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, int codec);
-
-/*! \brief Extract info out of callerID state machine. Flags are listed above
- * \param cid Callerid state machine to act upon
- * \param number Pass the address of a pointer-to-char (will contain the phone number)
- * \param name Pass the address of a pointer-to-char (will contain the name)
- * \param flags Pass the address of an int variable(will contain the various callerid flags)
- *
- * This function extracts a callerid string out of a callerid_state state machine.
- * If no number is found, *number will be set to NULL. Likewise for the name.
- * Flags can contain any of the following:
- *
- * \return Returns nothing.
- */
-void callerid_get(struct callerid_state *cid, char **number, char **name, int *flags);
-
-/*! Get and parse DTMF-based callerid */
-/*!
- * \param cidstring The actual transmitted string.
- * \param number The cid number is returned here.
- * \param flags The cid flags are returned here.
- * This function parses DTMF callerid.
- */
-void callerid_get_dtmf(char *cidstring, char *number, int *flags);
-
-/*! \brief Free a callerID state
- * \param cid This is the callerid_state state machine to free
- * This function frees callerid_state cid.
- */
-void callerid_free(struct callerid_state *cid);
-
-/*! \brief Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)
- * \param buf buffer for output samples. See callerid_generate() for details regarding buffer.
- * \param name Caller-ID Name
- * \param number Caller-ID Number
- * \param codec Asterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)
- *
- * Acts like callerid_generate except uses an asterisk format callerid string.
- */
-int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec);
-
-/*! \brief Generate message waiting indicator (stutter tone) */
-int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec);
-
-/*! \brief Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
- * See ast_callerid_generate() for other details
- */
-int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec);
-
-/*! \brief Destructively parse inbuf into name and location (or number)
- * Parses callerid stream from inbuf and changes into useable form, outputed in name and location.
- * \param instr buffer of callerid stream (in audio form) to be parsed. Warning, data in buffer is changed.
- * \param name address of a pointer-to-char for the name value of the stream.
- * \param location address of a pointer-to-char for the phone number value of the stream.
- * \return Returns 0 on success, -1 on failure.
- */
-int ast_callerid_parse(char *instr, char **name, char **location);
-
-/*! Generate a CAS (CPE Alert Signal) tone for 'n' samples */
-/*!
- * \param outbuf Allocated buffer for data. Must be at least 2400 bytes unless no SAS is desired
- * \param sas Non-zero if CAS should be preceeded by SAS
- * \param len How many samples to generate.
- * \param codec Which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
- * \return Returns -1 on error (if len is less than 2400), 0 on success.
- */
-int ast_gen_cas(unsigned char *outbuf, int sas, int len, int codec);
-
-/*! \brief Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s... */
-/*!
- * \param n The number to be stripped/shrunk
- * \return Returns nothing important
- */
-void ast_shrink_phone_number(char *n);
-
-/*! \brief Check if a string consists only of digits and + \#
- \param n number to be checked.
- \return Returns 0 if n is a number, 1 if it's not.
- */
-int ast_isphonenumber(const char *n);
-
-/*! \brief Check if a string consists only of digits and and + \# ( ) - .
- (meaning it can be cleaned with ast_shrink_phone_number)
- \param exten The extension (or URI) to be checked.
- \return Returns 0 if n is a number, 1 if it's not.
- */
-int ast_is_shrinkable_phonenumber(const char *exten);
-
-int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen);
-
-char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown);
-
-/*
- * Caller*ID and other GR-30 compatible generation
- * routines (used by ADSI for example)
- */
-
-extern float cid_dr[4];
-extern float cid_di[4];
-extern float clidsb;
-
-static inline float callerid_getcarrier(float *cr, float *ci, int bit)
-{
- /* Move along. There's nothing to see here... */
- float t;
- t = *cr * cid_dr[bit] - *ci * cid_di[bit];
- *ci = *cr * cid_di[bit] + *ci * cid_dr[bit];
- *cr = t;
-
- t = 2.0 - (*cr * *cr + *ci * *ci);
- *cr *= t;
- *ci *= t;
- return *cr;
-}
-
-#define PUT_BYTE(a) do { \
- *(buf++) = (a); \
- bytes++; \
-} while(0)
-
-#define PUT_AUDIO_SAMPLE(y) do { \
- int index = (short)(rint(8192.0 * (y))); \
- *(buf++) = AST_LIN2X(index); \
- bytes++; \
-} while(0)
-
-#define PUT_CLID_MARKMS do { \
- int x; \
- for (x=0;x<8;x++) \
- PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, 1)); \
-} while(0)
-
-#define PUT_CLID_BAUD(bit) do { \
- while(scont < clidsb) { \
- PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, bit)); \
- scont += 1.0; \
- } \
- scont -= clidsb; \
-} while(0)
-
-
-#define PUT_CLID(byte) do { \
- int z; \
- unsigned char b = (byte); \
- PUT_CLID_BAUD(0); /* Start bit */ \
- for (z=0;z<8;z++) { \
- PUT_CLID_BAUD(b & 1); \
- b >>= 1; \
- } \
- PUT_CLID_BAUD(1); /* Stop bit */ \
-} while(0)
-
-/* Various defines and bits for handling PRI- and SS7-type restriction */
-
-#define AST_PRES_NUMBER_TYPE 0x03
-#define AST_PRES_USER_NUMBER_UNSCREENED 0x00
-#define AST_PRES_USER_NUMBER_PASSED_SCREEN 0x01
-#define AST_PRES_USER_NUMBER_FAILED_SCREEN 0x02
-#define AST_PRES_NETWORK_NUMBER 0x03
-
-#define AST_PRES_RESTRICTION 0x60
-#define AST_PRES_ALLOWED 0x00
-#define AST_PRES_RESTRICTED 0x20
-#define AST_PRES_UNAVAILABLE 0x40
-#define AST_PRES_RESERVED 0x60
-
-#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED \
- AST_PRES_USER_NUMBER_UNSCREENED + AST_PRES_ALLOWED
-
-#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN \
- AST_PRES_USER_NUMBER_PASSED_SCREEN + AST_PRES_ALLOWED
-
-#define AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN \
- AST_PRES_USER_NUMBER_FAILED_SCREEN + AST_PRES_ALLOWED
-
-#define AST_PRES_ALLOWED_NETWORK_NUMBER \
- AST_PRES_NETWORK_NUMBER + AST_PRES_ALLOWED
-
-#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED \
- AST_PRES_USER_NUMBER_UNSCREENED + AST_PRES_RESTRICTED
-
-#define AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN \
- AST_PRES_USER_NUMBER_PASSED_SCREEN + AST_PRES_RESTRICTED
-
-#define AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN \
- AST_PRES_USER_NUMBER_FAILED_SCREEN + AST_PRES_RESTRICTED
-
-#define AST_PRES_PROHIB_NETWORK_NUMBER \
- AST_PRES_NETWORK_NUMBER + AST_PRES_RESTRICTED
-
-#define AST_PRES_NUMBER_NOT_AVAILABLE \
- AST_PRES_NETWORK_NUMBER + AST_PRES_UNAVAILABLE
-
-int ast_parse_caller_presentation(const char *data);
-const char *ast_describe_caller_presentation(int data);
-
-/*! \page Def_CallerPres Caller ID Presentation
-
- Caller ID presentation values are used to set properties to a
- caller ID in PSTN networks, and as RPID value in SIP transactions.
-
- The following values are available to use:
- \arg \b Defined value, text string in config file, explanation
-
- \arg \b AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", Presentation Allowed, Not Screened,
- \arg \b AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", Presentation Allowed, Passed Screen,
- \arg \b AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", Presentation Allowed, Failed Screen,
- \arg \b AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", Presentation Allowed, Network Number,
- \arg \b AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", Presentation Prohibited, Not Screened,
- \arg \b AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", Presentation Prohibited, Passed Screen,
- \arg \b AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", Presentation Prohibited, Failed Screen,
- \arg \b AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", Presentation Prohibited, Network Number,
-
- \par References
- \arg \ref callerid.h Definitions
- \arg \ref callerid.c Functions
- \arg \ref CID Caller ID names and numbers
-*/
-
-
-#endif /* _ASTERISK_CALLERID_H */
diff --git a/1.4/include/asterisk/causes.h b/1.4/include/asterisk/causes.h
deleted file mode 100644
index fc27c7970..000000000
--- a/1.4/include/asterisk/causes.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Martin Pycko <martinp@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.
- */
-
-/*! \file
- * \brief Internal Asterisk hangup causes
- */
-
-#ifndef _ASTERISK_CAUSES_H
-#define _ASTERISK_CAUSES_H
-
-/* Causes for disconnection (from Q.931) */
-#define AST_CAUSE_UNALLOCATED 1
-#define AST_CAUSE_NO_ROUTE_TRANSIT_NET 2
-#define AST_CAUSE_NO_ROUTE_DESTINATION 3
-#define AST_CAUSE_CHANNEL_UNACCEPTABLE 6
-#define AST_CAUSE_CALL_AWARDED_DELIVERED 7
-#define AST_CAUSE_NORMAL_CLEARING 16
-#define AST_CAUSE_USER_BUSY 17
-#define AST_CAUSE_NO_USER_RESPONSE 18
-#define AST_CAUSE_NO_ANSWER 19
-#define AST_CAUSE_CALL_REJECTED 21
-#define AST_CAUSE_NUMBER_CHANGED 22
-#define AST_CAUSE_DESTINATION_OUT_OF_ORDER 27
-#define AST_CAUSE_INVALID_NUMBER_FORMAT 28
-#define AST_CAUSE_FACILITY_REJECTED 29
-#define AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY 30
-#define AST_CAUSE_NORMAL_UNSPECIFIED 31
-#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION 34
-#define AST_CAUSE_NETWORK_OUT_OF_ORDER 38
-#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE 41
-#define AST_CAUSE_SWITCH_CONGESTION 42
-#define AST_CAUSE_ACCESS_INFO_DISCARDED 43
-#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL 44
-#define AST_CAUSE_PRE_EMPTED 45
-#define AST_CAUSE_FACILITY_NOT_SUBSCRIBED 50
-#define AST_CAUSE_OUTGOING_CALL_BARRED 52
-#define AST_CAUSE_INCOMING_CALL_BARRED 54
-#define AST_CAUSE_BEARERCAPABILITY_NOTAUTH 57
-#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL 58
-#define AST_CAUSE_BEARERCAPABILITY_NOTIMPL 65
-#define AST_CAUSE_CHAN_NOT_IMPLEMENTED 66
-#define AST_CAUSE_FACILITY_NOT_IMPLEMENTED 69
-#define AST_CAUSE_INVALID_CALL_REFERENCE 81
-#define AST_CAUSE_INCOMPATIBLE_DESTINATION 88
-#define AST_CAUSE_INVALID_MSG_UNSPECIFIED 95
-#define AST_CAUSE_MANDATORY_IE_MISSING 96
-#define AST_CAUSE_MESSAGE_TYPE_NONEXIST 97
-#define AST_CAUSE_WRONG_MESSAGE 98
-#define AST_CAUSE_IE_NONEXIST 99
-#define AST_CAUSE_INVALID_IE_CONTENTS 100
-#define AST_CAUSE_WRONG_CALL_STATE 101
-#define AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE 102
-#define AST_CAUSE_MANDATORY_IE_LENGTH_ERROR 103
-#define AST_CAUSE_PROTOCOL_ERROR 111
-#define AST_CAUSE_INTERWORKING 127
-
-/* Special Asterisk aliases */
-#define AST_CAUSE_BUSY AST_CAUSE_USER_BUSY
-#define AST_CAUSE_FAILURE AST_CAUSE_NETWORK_OUT_OF_ORDER
-#define AST_CAUSE_NORMAL AST_CAUSE_NORMAL_CLEARING
-#define AST_CAUSE_NOANSWER AST_CAUSE_NO_ANSWER
-#define AST_CAUSE_CONGESTION AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
-#define AST_CAUSE_UNREGISTERED AST_CAUSE_NO_ROUTE_DESTINATION
-#define AST_CAUSE_NOTDEFINED 0
-#define AST_CAUSE_NOSUCHDRIVER AST_CAUSE_CHAN_NOT_IMPLEMENTED
-
-#endif /* _ASTERISK_CAUSES_H */
diff --git a/1.4/include/asterisk/cdr.h b/1.4/include/asterisk/cdr.h
deleted file mode 100644
index b61e25014..000000000
--- a/1.4/include/asterisk/cdr.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Call Detail Record API
- */
-
-#ifndef _ASTERISK_CDR_H
-#define _ASTERISK_CDR_H
-
-#include <sys/time.h>
-#define AST_CDR_FLAG_KEEP_VARS (1 << 0)
-#define AST_CDR_FLAG_POSTED (1 << 1)
-#define AST_CDR_FLAG_LOCKED (1 << 2)
-#define AST_CDR_FLAG_CHILD (1 << 3)
-#define AST_CDR_FLAG_POST_DISABLED (1 << 4)
-
-#define AST_CDR_NULL 0
-#define AST_CDR_FAILED (1 << 0)
-#define AST_CDR_BUSY (1 << 1)
-#define AST_CDR_NOANSWER (1 << 2)
-#define AST_CDR_ANSWERED (1 << 3)
-
-/*! AMA Flags */
-#define AST_CDR_OMIT (1)
-#define AST_CDR_BILLING (2)
-#define AST_CDR_DOCUMENTATION (3)
-
-#define AST_MAX_USER_FIELD 256
-#define AST_MAX_ACCOUNT_CODE 20
-
-/* Include channel.h after relevant declarations it will need */
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-
-/*! Responsible for call detail data */
-struct ast_cdr {
- /*! Caller*ID with text */
- char clid[AST_MAX_EXTENSION];
- /*! Caller*ID number */
- char src[AST_MAX_EXTENSION];
- /*! Destination extension */
- char dst[AST_MAX_EXTENSION];
- /*! Destination context */
- char dcontext[AST_MAX_EXTENSION];
-
- char channel[AST_MAX_EXTENSION];
- /*! Destination channel if appropriate */
- char dstchannel[AST_MAX_EXTENSION];
- /*! Last application if appropriate */
- char lastapp[AST_MAX_EXTENSION];
- /*! Last application data */
- char lastdata[AST_MAX_EXTENSION];
-
- struct timeval start;
-
- struct timeval answer;
-
- struct timeval end;
- /*! Total time in system, in seconds */
- long int duration;
- /*! Total time call is up, in seconds */
- long int billsec;
- /*! What happened to the call */
- long int disposition;
- /*! What flags to use */
- long int amaflags;
- /*! What account number to use */
- char accountcode[AST_MAX_ACCOUNT_CODE];
- /*! flags */
- unsigned int flags;
- /* Unique Channel Identifier */
- char uniqueid[32];
- /* User field */
- char userfield[AST_MAX_USER_FIELD];
-
- /* A linked list for variables */
- struct varshead varshead;
-
- struct ast_cdr *next;
-};
-
-void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw);
-int ast_cdr_setvar(struct ast_cdr *cdr, const char *name, const char *value, int recur);
-int ast_cdr_serialize_variables(struct ast_cdr *cdr, char *buf, size_t size, char delim, char sep, int recur);
-void ast_cdr_free_vars(struct ast_cdr *cdr, int recur);
-int ast_cdr_copy_vars(struct ast_cdr *to_cdr, struct ast_cdr *from_cdr);
-
-typedef int (*ast_cdrbe)(struct ast_cdr *cdr);
-
-/*! \brief Allocate a CDR record
- * Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure)
- */
-struct ast_cdr *ast_cdr_alloc(void);
-
-/*! \brief Duplicate a record
- * Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure)
- */
-struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr);
-
-/*! \brief Free a CDR record
- * \param cdr ast_cdr structure to free
- * Returns nothing
- */
-void ast_cdr_free(struct ast_cdr *cdr);
-
-/*! \brief Discard and free a CDR record
- * \param cdr ast_cdr structure to free
- * Returns nothing -- same as free, but no checks or complaints
- */
-void ast_cdr_discard(struct ast_cdr *cdr);
-
-/*! \brief Initialize based on a channel
- * \param cdr Call Detail Record to use for channel
- * \param chan Channel to bind CDR with
- * Initializes a CDR and associates it with a particular channel
- * Return is negligible. (returns 0 by default)
- */
-int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *chan);
-
-/*! Initialize based on a channel */
-/*!
- * \param cdr Call Detail Record to use for channel
- * \param chan Channel to bind CDR with
- * Initializes a CDR and associates it with a particular channel
- * Return is negligible. (returns 0 by default)
- */
-int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *chan);
-
-/*! Register a CDR handling engine */
-/*!
- * \param name name associated with the particular CDR handler
- * \param desc description of the CDR handler
- * \param be function pointer to a CDR handler
- * Used to register a Call Detail Record handler.
- * Returns -1 on error, 0 on success.
- */
-int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be);
-
-/*! Unregister a CDR handling engine */
-/*!
- * \param name name of CDR handler to unregister
- * Unregisters a CDR by it's name
- */
-void ast_cdr_unregister(const char *name);
-
-/*! Start a call */
-/*!
- * \param cdr the cdr you wish to associate with the call
- * Starts all CDR stuff necessary for monitoring a call
- * Returns nothing
- */
-void ast_cdr_start(struct ast_cdr *cdr);
-
-/*! Answer a call */
-/*!
- * \param cdr the cdr you wish to associate with the call
- * Starts all CDR stuff necessary for doing CDR when answering a call
- * NULL argument is just fine.
- */
-void ast_cdr_answer(struct ast_cdr *cdr);
-
-/*! A call wasn't answered */
-/*!
- * \param cdr the cdr you wish to associate with the call
- * Marks the channel disposition as "NO ANSWER"
- */
-extern void ast_cdr_noanswer(struct ast_cdr *cdr);
-
-/*! Busy a call */
-/*!
- * \param cdr the cdr you wish to associate with the call
- * Returns nothing
- */
-void ast_cdr_busy(struct ast_cdr *cdr);
-
-/*! Fail a call */
-/*!
- * \param cdr the cdr you wish to associate with the call
- * Returns nothing
- */
-void ast_cdr_failed(struct ast_cdr *cdr);
-
-/*! Save the result of the call based on the AST_CAUSE_* */
-/*!
- * \param cdr the cdr you wish to associate with the call
- * Returns nothing
- * \param cause the AST_CAUSE_*
- */
-int ast_cdr_disposition(struct ast_cdr *cdr, int cause);
-
-/*! End a call */
-/*!
- * \param cdr the cdr you have associated the call with
- * Registers the end of call time in the cdr structure.
- * Returns nothing
- */
-void ast_cdr_end(struct ast_cdr *cdr);
-
-/*! Detaches the detail record for posting (and freeing) either now or at a
- * later time in bulk with other records during batch mode operation */
-/*!
- * \param cdr Which CDR to detach from the channel thread
- * Prevents the channel thread from blocking on the CDR handling
- * Returns nothing
- */
-void ast_cdr_detach(struct ast_cdr *cdr);
-
-/*! Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines */
-/*!
- * \param shutdown Whether or not we are shutting down
- * Blocks the asterisk shutdown procedures until the CDR data is submitted.
- * Returns nothing
- */
-void ast_cdr_submit_batch(int shutdown);
-
-/*! Set the destination channel, if there was one */
-/*!
- * \param cdr Which cdr it's applied to
- * \param chan Channel to which dest will be
- * Sets the destination channel the CDR is applied to
- * Returns nothing
- */
-void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chan);
-
-/*! Set the last executed application */
-/*!
- * \param cdr which cdr to act upon
- * \param app the name of the app you wish to change it to
- * \param data the data you want in the data field of app you set it to
- * Changes the value of the last executed app
- * Returns nothing
- */
-void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data);
-
-/*! Convert a string to a detail record AMA flag */
-/*!
- * \param flag string form of flag
- * Converts the string form of the flag to the binary form.
- * Returns the binary form of the flag
- */
-int ast_cdr_amaflags2int(const char *flag);
-
-/*! Disposition to a string */
-/*!
- * \param disposition input binary form
- * Converts the binary form of a disposition to string form.
- * Returns a pointer to the string form
- */
-char *ast_cdr_disp2str(int disposition);
-
-/*! Reset the detail record, optionally posting it first */
-/*!
- * \param cdr which cdr to act upon
- * \param flags |AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it
- * |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's
- */
-void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *flags);
-
-/*! Flags to a string */
-/*!
- * \param flags binary flag
- * Converts binary flags to string flags
- * Returns string with flag name
- */
-char *ast_cdr_flags2str(int flags);
-
-/*! Move the non-null data from the "from" cdr to the "to" cdr
- * \param to the cdr to get the goodies
- * \param from the cdr to give the goodies
- */
-void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from);
-
-int ast_cdr_setaccount(struct ast_channel *chan, const char *account);
-int ast_cdr_setamaflags(struct ast_channel *chan, const char *amaflags);
-
-
-int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield);
-int ast_cdr_appenduserfield(struct ast_channel *chan, const char *userfield);
-
-
-/* Update CDR on a channel */
-int ast_cdr_update(struct ast_channel *chan);
-
-
-extern int ast_default_amaflags;
-
-extern char ast_default_accountcode[AST_MAX_ACCOUNT_CODE];
-
-struct ast_cdr *ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr);
-
-/*! Reload the configuration file cdr.conf and start/stop CDR scheduling thread */
-int ast_cdr_engine_reload(void);
-
-/*! Load the configuration file cdr.conf and possibly start the CDR scheduling thread */
-int ast_cdr_engine_init(void);
-
-/*! Submit any remaining CDRs and prepare for shutdown */
-void ast_cdr_engine_term(void);
-
-#endif /* _ASTERISK_CDR_H */
diff --git a/1.4/include/asterisk/channel.h b/1.4/include/asterisk/channel.h
deleted file mode 100644
index 1172274f7..000000000
--- a/1.4/include/asterisk/channel.h
+++ /dev/null
@@ -1,1420 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief General Asterisk PBX channel definitions.
- * \par See also:
- * \arg \ref Def_Channel
- * \arg \ref channel_drivers
- */
-
-/*! \page Def_Channel Asterisk Channels
- \par What is a Channel?
- A phone call through Asterisk consists of an incoming
- connection and an outbound connection. Each call comes
- in through a channel driver that supports one technology,
- like SIP, ZAP, IAX2 etc.
- \par
- Each channel driver, technology, has it's own private
- channel or dialog structure, that is technology-dependent.
- Each private structure is "owned" by a generic Asterisk
- channel structure, defined in channel.h and handled by
- channel.c .
- \par Call scenario
- This happens when an incoming call arrives to Asterisk
- -# Call arrives on a channel driver interface
- -# Channel driver creates a PBX channel and starts a
- pbx thread on the channel
- -# The dial plan is executed
- -# At this point at least two things can happen:
- -# The call is answered by Asterisk and
- Asterisk plays a media stream or reads media
- -# The dial plan forces Asterisk to create an outbound
- call somewhere with the dial (see \ref app_dial.c)
- application
- .
-
- \par Bridging channels
- If Asterisk dials out this happens:
- -# Dial creates an outbound PBX channel and asks one of the
- channel drivers to create a call
- -# When the call is answered, Asterisk bridges the media streams
- so the caller on the first channel can speak with the callee
- on the second, outbound channel
- -# In some cases where we have the same technology on both
- channels and compatible codecs, a native bridge is used.
- In a native bridge, the channel driver handles forwarding
- of incoming audio to the outbound stream internally, without
- sending audio frames through the PBX.
- -# In SIP, theres an "external native bridge" where Asterisk
- redirects the endpoint, so audio flows directly between the
- caller's phone and the callee's phone. Signalling stays in
- Asterisk in order to be able to provide a proper CDR record
- for the call.
-
-
- \par Masquerading channels
- In some cases, a channel can masquerade itself into another
- channel. This happens frequently in call transfers, where
- a new channel takes over a channel that is already involved
- in a call. The new channel sneaks in and takes over the bridge
- and the old channel, now a zombie, is hung up.
-
- \par Reference
- \arg channel.c - generic functions
- \arg channel.h - declarations of functions, flags and structures
- \arg translate.h - Transcoding support functions
- \arg \ref channel_drivers - Implemented channel drivers
- \arg \ref Def_Frame Asterisk Multimedia Frames
-
-*/
-
-#ifndef _ASTERISK_CHANNEL_H
-#define _ASTERISK_CHANNEL_H
-
-#include "asterisk/abstract_jb.h"
-
-#include <unistd.h>
-#ifdef POLLCOMPAT
-#include "asterisk/poll-compat.h"
-#else
-#include <sys/poll.h>
-#endif
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
-#define AST_MAX_CONTEXT 80 /*!< Max length of a context */
-#define AST_CHANNEL_NAME 80 /*!< Max length of an ast_channel name */
-#define MAX_LANGUAGE 20 /*!< Max length of the language setting */
-#define MAX_MUSICCLASS 80 /*!< Max length of the music class setting */
-
-#include "asterisk/compat.h"
-#include "asterisk/frame.h"
-#include "asterisk/sched.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/config.h"
-#include "asterisk/lock.h"
-#include "asterisk/cdr.h"
-#include "asterisk/utils.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/compiler.h"
-
-#define DATASTORE_INHERIT_FOREVER INT_MAX
-
-#define AST_MAX_FDS 8
-/*
- * We have AST_MAX_FDS file descriptors in a channel.
- * Some of them have a fixed use:
- */
-#define AST_ALERT_FD (AST_MAX_FDS-1) /*!< used for alertpipe */
-#define AST_TIMING_FD (AST_MAX_FDS-2) /*!< used for timingfd */
-#define AST_AGENT_FD (AST_MAX_FDS-3) /*!< used by agents for pass through */
-#define AST_GENERATOR_FD (AST_MAX_FDS-4) /*!< used by generator */
-
-enum ast_bridge_result {
- AST_BRIDGE_COMPLETE = 0,
- AST_BRIDGE_FAILED = -1,
- AST_BRIDGE_FAILED_NOWARN = -2,
- AST_BRIDGE_RETRY = -3,
-};
-
-typedef unsigned long long ast_group_t;
-
-struct ast_generator {
- void *(*alloc)(struct ast_channel *chan, void *params);
- void (*release)(struct ast_channel *chan, void *data);
- /*! This function gets called with the channel unlocked, but is called in
- * the context of the channel thread so we know the channel is not going
- * to disappear. This callback is responsible for locking the channel as
- * necessary. */
- int (*generate)(struct ast_channel *chan, void *data, int len, int samples);
-};
-
-/*! \brief Structure for a data store type */
-struct ast_datastore_info {
- const char *type; /*!< Type of data store */
- void *(*duplicate)(void *data); /*!< Duplicate item data (used for inheritance) */
- void (*destroy)(void *data); /*!< Destroy function */
- /*!
- * \brief Fix up channel references
- *
- * \arg data The datastore data
- * \arg old_chan The old channel owning the datastore
- * \arg new_chan The new channel owning the datastore
- *
- * This is exactly like the fixup callback of the channel technology interface.
- * It allows a datastore to fix any pointers it saved to the owning channel
- * in case that the owning channel has changed. Generally, this would happen
- * when the datastore is set to be inherited, and a masquerade occurs.
- *
- * \return nothing.
- */
- void (*chan_fixup)(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
-};
-
-/*! \brief Structure for a channel data store */
-struct ast_datastore {
- char *uid; /*!< Unique data store identifier */
- void *data; /*!< Contained data */
- const struct ast_datastore_info *info; /*!< Data store type information */
- unsigned int inheritance; /*!Number of levels this item will continue to be inherited */
- AST_LIST_ENTRY(ast_datastore) entry; /*!< Used for easy linking */
-};
-
-/*! \brief Structure for all kinds of caller ID identifications.
- * \note All string fields here are malloc'ed, so they need to be
- * freed when the structure is deleted.
- * Also, NULL and "" must be considered equivalent.
- */
-struct ast_callerid {
- char *cid_dnid; /*!< Malloc'd Dialed Number Identifier */
- char *cid_num; /*!< Malloc'd Caller Number */
- char *cid_name; /*!< Malloc'd Caller Name */
- char *cid_ani; /*!< Malloc'd ANI */
- char *cid_rdnis; /*!< Malloc'd RDNIS */
- int cid_pres; /*!< Callerid presentation/screening */
- int cid_ani2; /*!< Callerid ANI 2 (Info digits) */
- int cid_ton; /*!< Callerid Type of Number */
- int cid_tns; /*!< Callerid Transit Network Select */
-};
-
-/*! \brief
- Structure to describe a channel "technology", ie a channel driver
- See for examples:
- \arg chan_iax2.c - The Inter-Asterisk exchange protocol
- \arg chan_sip.c - The SIP channel driver
- \arg chan_zap.c - PSTN connectivity (TDM, PRI, T1/E1, FXO, FXS)
-
- If you develop your own channel driver, this is where you
- tell the PBX at registration of your driver what properties
- this driver supports and where different callbacks are
- implemented.
-*/
-struct ast_channel_tech {
- const char * const type;
- const char * const description;
-
- int capabilities; /*!< Bitmap of formats this channel can handle */
-
- int properties; /*!< Technology Properties */
-
- /*! \brief Requester - to set up call data structures (pvt's) */
- struct ast_channel *(* const requester)(const char *type, int format, void *data, int *cause);
-
- int (* const devicestate)(void *data); /*!< Devicestate call back */
-
- /*! \brief Start sending a literal DTMF digit */
- int (* const send_digit_begin)(struct ast_channel *chan, char digit);
-
- /*! \brief Stop sending a literal DTMF digit */
- int (* const send_digit_end)(struct ast_channel *chan, char digit, unsigned int duration);
-
- /*! \brief Call a given phone number (address, etc), but don't
- take longer than timeout seconds to do so. */
- int (* const call)(struct ast_channel *chan, char *addr, int timeout);
-
- /*! \brief Hangup (and possibly destroy) the channel */
- int (* const hangup)(struct ast_channel *chan);
-
- /*! \brief Answer the channel */
- int (* const answer)(struct ast_channel *chan);
-
- /*! \brief Read a frame, in standard format (see frame.h) */
- struct ast_frame * (* const read)(struct ast_channel *chan);
-
- /*! \brief Write a frame, in standard format (see frame.h) */
- int (* const write)(struct ast_channel *chan, struct ast_frame *frame);
-
- /*! \brief Display or transmit text */
- int (* const send_text)(struct ast_channel *chan, const char *text);
-
- /*! \brief Display or send an image */
- int (* const send_image)(struct ast_channel *chan, struct ast_frame *frame);
-
- /*! \brief Send HTML data */
- int (* const send_html)(struct ast_channel *chan, int subclass, const char *data, int len);
-
- /*! \brief Handle an exception, reading a frame */
- struct ast_frame * (* const exception)(struct ast_channel *chan);
-
- /*! \brief Bridge two channels of the same type together */
- enum ast_bridge_result (* const bridge)(struct ast_channel *c0, struct ast_channel *c1, int flags,
- struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-
- /*! \brief Indicate a particular condition (e.g. AST_CONTROL_BUSY or AST_CONTROL_RINGING or AST_CONTROL_CONGESTION */
- int (* const indicate)(struct ast_channel *c, int condition, const void *data, size_t datalen);
-
- /*! \brief Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links */
- int (* const fixup)(struct ast_channel *oldchan, struct ast_channel *newchan);
-
- /*! \brief Set a given option */
- int (* const setoption)(struct ast_channel *chan, int option, void *data, int datalen);
-
- /*! \brief Query a given option */
- int (* const queryoption)(struct ast_channel *chan, int option, void *data, int *datalen);
-
- /*! \brief Blind transfer other side (see app_transfer.c and ast_transfer() */
- int (* const transfer)(struct ast_channel *chan, const char *newdest);
-
- /*! \brief Write a frame, in standard format */
- int (* const write_video)(struct ast_channel *chan, struct ast_frame *frame);
-
- /*! \brief Find bridged channel */
- struct ast_channel *(* const bridged_channel)(struct ast_channel *chan, struct ast_channel *bridge);
-
- /*! \brief Provide additional read items for CHANNEL() dialplan function */
- int (* func_channel_read)(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
-
- /*! \brief Provide additional write items for CHANNEL() dialplan function */
- int (* func_channel_write)(struct ast_channel *chan, char *function, char *data, const char *value);
-
- /*! \brief Retrieve base channel (agent and local) */
- struct ast_channel* (* get_base_channel)(struct ast_channel *chan);
-
- /*! \brief Set base channel (agent and local) */
- int (* set_base_channel)(struct ast_channel *chan, struct ast_channel *base);
-};
-
-#define DEBUGCHAN_FLAG 0x80000000
-#define FRAMECOUNT_INC(x) ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) )
-
-enum ast_channel_adsicpe {
- AST_ADSI_UNKNOWN,
- AST_ADSI_AVAILABLE,
- AST_ADSI_UNAVAILABLE,
- AST_ADSI_OFFHOOKONLY,
-};
-
-/*!
- * \brief ast_channel states
- *
- * \note Bits 0-15 of state are reserved for the state (up/down) of the line
- * Bits 16-32 of state are reserved for flags
- */
-enum ast_channel_state {
- /*! Channel is down and available */
- AST_STATE_DOWN,
- /*! Channel is down, but reserved */
- AST_STATE_RESERVED,
- /*! Channel is off hook */
- AST_STATE_OFFHOOK,
- /*! Digits (or equivalent) have been dialed */
- AST_STATE_DIALING,
- /*! Line is ringing */
- AST_STATE_RING,
- /*! Remote end is ringing */
- AST_STATE_RINGING,
- /*! Line is up */
- AST_STATE_UP,
- /*! Line is busy */
- AST_STATE_BUSY,
- /*! Digits (or equivalent) have been dialed while offhook */
- AST_STATE_DIALING_OFFHOOK,
- /*! Channel has detected an incoming call and is waiting for ring */
- AST_STATE_PRERING,
-
- /*! Do not transmit voice data */
- AST_STATE_MUTE = (1 << 16),
-};
-
-/*! \brief Main Channel structure associated with a channel.
- * This is the side of it mostly used by the pbx and call management.
- *
- * \note XXX It is important to remember to increment .cleancount each time
- * this structure is changed. XXX
- */
-struct ast_channel {
- /*! \brief Technology (point to channel driver) */
- const struct ast_channel_tech *tech;
-
- /*! \brief Private data used by the technology driver */
- void *tech_pvt;
-
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name); /*!< ASCII unique channel name */
- AST_STRING_FIELD(language); /*!< Language requested for voice prompts */
- AST_STRING_FIELD(musicclass); /*!< Default music class */
- AST_STRING_FIELD(accountcode); /*!< Account code for billing */
- AST_STRING_FIELD(call_forward); /*!< Where to forward to if asked to dial on this interface */
- AST_STRING_FIELD(uniqueid); /*!< Unique Channel Identifier */
- );
-
- /*! \brief File descriptor for channel -- Drivers will poll on these file descriptors, so at least one must be non -1. */
- int fds[AST_MAX_FDS];
-
- void *music_state; /*!< Music State*/
- void *generatordata; /*!< Current generator data if there is any */
- struct ast_generator *generator; /*!< Current active data generator */
-
- /*! \brief Who are we bridged to, if we're bridged. Who is proxying for us,
- if we are proxied (i.e. chan_agent).
- Do not access directly, use ast_bridged_channel(chan) */
- struct ast_channel *_bridge;
- struct ast_channel *masq; /*!< Channel that will masquerade as us */
- struct ast_channel *masqr; /*!< Who we are masquerading as */
- int cdrflags; /*!< Call Detail Record Flags */
-
- /*! \brief Whether or not we have been hung up... Do not set this value
- directly, use ast_softhangup */
- int _softhangup;
- time_t whentohangup; /*!< Non-zero, set to actual time when channel is to be hung up */
- pthread_t blocker; /*!< If anyone is blocking, this is them */
- ast_mutex_t lock; /*!< Lock, can be used to lock a channel for some operations */
- const char *blockproc; /*!< Procedure causing blocking */
-
- const char *appl; /*!< Current application */
- const char *data; /*!< Data passed to current application */
- int fdno; /*!< Which fd had an event detected on */
- struct sched_context *sched; /*!< Schedule context */
- int streamid; /*!< For streaming playback, the schedule ID */
- struct ast_filestream *stream; /*!< Stream itself. */
- int vstreamid; /*!< For streaming video playback, the schedule ID */
- struct ast_filestream *vstream; /*!< Video Stream itself. */
- int oldwriteformat; /*!< Original writer format */
-
- int timingfd; /*!< Timing fd */
- int (*timingfunc)(const void *data);
- void *timingdata;
-
- enum ast_channel_state _state; /*!< State of line -- Don't write directly, use ast_setstate */
- int rings; /*!< Number of rings so far */
- struct ast_callerid cid; /*!< Caller ID, name, presentation etc */
- char dtmfq[AST_MAX_EXTENSION]; /*!< Any/all queued DTMF characters */
- struct ast_frame dtmff; /*!< DTMF frame */
-
- char context[AST_MAX_CONTEXT]; /*!< Dialplan: Current extension context */
- char exten[AST_MAX_EXTENSION]; /*!< Dialplan: Current extension number */
- int priority; /*!< Dialplan: Current extension priority */
- char macrocontext[AST_MAX_CONTEXT]; /*!< Macro: Current non-macro context. See app_macro.c */
- char macroexten[AST_MAX_EXTENSION]; /*!< Macro: Current non-macro extension. See app_macro.c */
- int macropriority; /*!< Macro: Current non-macro priority. See app_macro.c */
- char dialcontext[AST_MAX_CONTEXT]; /*!< Dial: Extension context that we were called from */
-
- struct ast_pbx *pbx; /*!< PBX private structure for this channel */
- int amaflags; /*!< Set BEFORE PBX is started to determine AMA flags */
- struct ast_cdr *cdr; /*!< Call Detail Record */
- enum ast_channel_adsicpe adsicpe; /*!< Whether or not ADSI is detected on CPE */
-
- struct tone_zone *zone; /*!< Tone zone as set in indications.conf or
- in the CHANNEL dialplan function */
-
- struct ast_channel_monitor *monitor; /*!< Channel monitoring */
-
- /*! Track the read/written samples for monitor use */
- unsigned long insmpl;
- unsigned long outsmpl;
-
- /* Frames in/out counters. The high bit is a debug mask, so
- * the counter is only in the remaining bits
- */
- unsigned int fin;
- unsigned int fout;
- int hangupcause; /*!< Why is the channel hanged up. See causes.h */
- struct varshead varshead; /*!< A linked list for channel variables */
- ast_group_t callgroup; /*!< Call group for call pickups */
- ast_group_t pickupgroup; /*!< Pickup group - which calls groups can be picked up? */
- unsigned int flags; /*!< channel flags of AST_FLAG_ type */
- unsigned short transfercapability; /*!< ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */
- AST_LIST_HEAD_NOLOCK(, ast_frame) readq;
- int alertpipe[2];
-
- int nativeformats; /*!< Kinds of data this channel can natively handle */
- int readformat; /*!< Requested read format */
- int writeformat; /*!< Requested write format */
- struct ast_trans_pvt *writetrans; /*!< Write translation path */
- struct ast_trans_pvt *readtrans; /*!< Read translation path */
- int rawreadformat; /*!< Raw read format */
- int rawwriteformat; /*!< Raw write format */
-
- struct ast_audiohook_list *audiohooks;
- void *unused; /*! This pointer should stay for Asterisk 1.4. It just keeps the struct size the same
- * for the sake of ABI compatability. */
-
- AST_LIST_ENTRY(ast_channel) chan_list; /*!< For easy linking */
-
- struct ast_jb jb; /*!< The jitterbuffer state */
-
- char emulate_dtmf_digit; /*!< Digit being emulated */
- unsigned int emulate_dtmf_duration; /*!< Number of ms left to emulate DTMF for */
- struct timeval dtmf_tv; /*!< The time that an in process digit began, or the last digit ended */
-
- int visible_indication; /*!< Indication currently playing on the channel */
-
- /*! \brief Data stores on the channel */
- AST_LIST_HEAD_NOLOCK(datastores, ast_datastore) datastores;
-};
-
-/*! \brief ast_channel_tech Properties */
-enum {
- /*! \brief Channels have this property if they can accept input with jitter;
- * i.e. most VoIP channels */
- AST_CHAN_TP_WANTSJITTER = (1 << 0),
- /*! \brief Channels have this property if they can create jitter;
- * i.e. most VoIP channels */
- AST_CHAN_TP_CREATESJITTER = (1 << 1),
-};
-
-/*! \brief ast_channel flags */
-enum {
- /*! Queue incoming dtmf, to be released when this flag is turned off */
- AST_FLAG_DEFER_DTMF = (1 << 1),
- /*! write should be interrupt generator */
- AST_FLAG_WRITE_INT = (1 << 2),
- /*! a thread is blocking on this channel */
- AST_FLAG_BLOCKING = (1 << 3),
- /*! This is a zombie channel */
- AST_FLAG_ZOMBIE = (1 << 4),
- /*! There is an exception pending */
- AST_FLAG_EXCEPTION = (1 << 5),
- /*! Listening to moh XXX anthm promises me this will disappear XXX */
- AST_FLAG_MOH = (1 << 6),
- /*! This channel is spying on another channel */
- AST_FLAG_SPYING = (1 << 7),
- /*! This channel is in a native bridge */
- AST_FLAG_NBRIDGE = (1 << 8),
- /*! the channel is in an auto-incrementing dialplan processor,
- * so when ->priority is set, it will get incremented before
- * finding the next priority to run */
- AST_FLAG_IN_AUTOLOOP = (1 << 9),
- /*! This is an outgoing call */
- AST_FLAG_OUTGOING = (1 << 10),
- /*! This channel is being whispered on */
- AST_FLAG_WHISPER = (1 << 11),
- /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */
- AST_FLAG_IN_DTMF = (1 << 12),
- /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is
- * currently being emulated */
- AST_FLAG_EMULATE_DTMF = (1 << 13),
- /*! This is set to tell the channel not to generate DTMF begin frames, and
- * to instead only generate END frames. */
- AST_FLAG_END_DTMF_ONLY = (1 << 14),
- /*! This flag indicates that on a masquerade, an active stream should not
- * be carried over */
- AST_FLAG_MASQ_NOSTREAM = (1 << 15),
-};
-
-/*! \brief ast_bridge_config flags */
-enum {
- AST_FEATURE_PLAY_WARNING = (1 << 0),
- AST_FEATURE_REDIRECT = (1 << 1),
- AST_FEATURE_DISCONNECT = (1 << 2),
- AST_FEATURE_ATXFER = (1 << 3),
- AST_FEATURE_AUTOMON = (1 << 4),
- AST_FEATURE_PARKCALL = (1 << 5),
-};
-
-struct ast_bridge_config {
- struct ast_flags features_caller;
- struct ast_flags features_callee;
- struct timeval start_time;
- long feature_timer;
- long timelimit;
- long play_warning;
- long warning_freq;
- const char *warning_sound;
- const char *end_sound;
- const char *start_sound;
- int firstpass;
- unsigned int flags;
-};
-
-struct chanmon;
-
-#define LOAD_OH(oh) { \
- oh.context = context; \
- oh.exten = exten; \
- oh.priority = priority; \
- oh.cid_num = cid_num; \
- oh.cid_name = cid_name; \
- oh.account = account; \
- oh.vars = vars; \
- oh.parent_channel = NULL; \
-}
-
-struct outgoing_helper {
- const char *context;
- const char *exten;
- int priority;
- const char *cid_num;
- const char *cid_name;
- const char *account;
- struct ast_variable *vars;
- struct ast_channel *parent_channel;
-};
-
-enum {
- AST_CDR_TRANSFER = (1 << 0),
- AST_CDR_FORWARD = (1 << 1),
- AST_CDR_CALLWAIT = (1 << 2),
- AST_CDR_CONFERENCE = (1 << 3),
-};
-
-enum {
- /*! Soft hangup by device */
- AST_SOFTHANGUP_DEV = (1 << 0),
- /*! Soft hangup for async goto */
- AST_SOFTHANGUP_ASYNCGOTO = (1 << 1),
- AST_SOFTHANGUP_SHUTDOWN = (1 << 2),
- AST_SOFTHANGUP_TIMEOUT = (1 << 3),
- AST_SOFTHANGUP_APPUNLOAD = (1 << 4),
- AST_SOFTHANGUP_EXPLICIT = (1 << 5),
- AST_SOFTHANGUP_UNBRIDGE = (1 << 6),
-};
-
-
-/*! \brief Channel reload reasons for manager events at load or reload of configuration */
-enum channelreloadreason {
- CHANNEL_MODULE_LOAD,
- CHANNEL_MODULE_RELOAD,
- CHANNEL_CLI_RELOAD,
- CHANNEL_MANAGER_RELOAD,
-};
-
-/*! \brief Create a channel datastore structure */
-struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid);
-
-/*! \brief Free a channel datastore structure */
-int ast_channel_datastore_free(struct ast_datastore *datastore);
-
-/*! \brief Inherit datastores from a parent to a child. */
-int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to);
-
-/*! \brief Add a datastore to a channel */
-int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore);
-
-/*! \brief Remove a datastore from a channel */
-int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore);
-
-/*! \brief Find a datastore on a channel */
-struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid);
-
-/*! \brief Change the state of a channel */
-int ast_setstate(struct ast_channel *chan, enum ast_channel_state);
-
-/*! \brief Create a channel structure
- \return Returns NULL on failure to allocate.
- \note New channels are
- by default set to the "default" context and
- extension "s"
- */
-struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...);
-
-/*! \brief Queue an outgoing frame */
-int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
-
-/*! \brief Queue a hangup frame */
-int ast_queue_hangup(struct ast_channel *chan);
-
-/*!
- \brief Queue a control frame with payload
- \param chan channel to queue frame onto
- \param control type of control frame
- \return zero on success, non-zero on failure
-*/
-int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control);
-
-/*!
- \brief Queue a control frame with payload
- \param chan channel to queue frame onto
- \param control type of control frame
- \param data pointer to payload data to be included in frame
- \param datalen number of bytes of payload data
- \return zero on success, non-zero on failure
-
- The supplied payload data is copied into the frame, so the caller's copy
- is not modified nor freed, and the resulting frame will retain a copy of
- the data even if the caller frees their local copy.
-
- \note This method should be treated as a 'network transport'; in other
- words, your frames may be transferred across an IAX2 channel to another
- system, which may be a different endianness than yours. Because of this,
- you should ensure that either your frames will never be expected to work
- across systems, or that you always put your payload data into 'network byte
- order' before calling this function.
-*/
-int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
- const void *data, size_t datalen);
-
-/*! \brief Change channel name */
-void ast_change_name(struct ast_channel *chan, char *newname);
-
-/*! \brief Free a channel structure */
-void ast_channel_free(struct ast_channel *);
-
-/*! \brief Requests a channel
- * \param type type of channel to request
- * \param format requested channel format (codec)
- * \param data data to pass to the channel requester
- * \param status status
- * Request a channel of a given type, with data as optional information used
- * by the low level module
- * \return Returns an ast_channel on success, NULL on failure.
- */
-struct ast_channel *ast_request(const char *type, int format, void *data, int *status);
-
-/*!
- * \brief Request a channel of a given type, with data as optional information used
- * by the low level module and attempt to place a call on it
- * \param type type of channel to request
- * \param format requested channel format
- * \param data data to pass to the channel requester
- * \param timeout maximum amount of time to wait for an answer
- * \param reason why unsuccessful (if unsuceessful)
- * \param cidnum Caller-ID Number
- * \param cidname Caller-ID Name
- * \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state
- * to know if the call was answered or not.
- */
-struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname);
-
-struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh);
-
-/*!\brief Register a channel technology (a new channel driver)
- * Called by a channel module to register the kind of channels it supports.
- * \param tech Structure defining channel technology or "type"
- * \return Returns 0 on success, -1 on failure.
- */
-int ast_channel_register(const struct ast_channel_tech *tech);
-
-/*! \brief Unregister a channel technology
- * \param tech Structure defining channel technology or "type" that was previously registered
- * \return No return value.
- */
-void ast_channel_unregister(const struct ast_channel_tech *tech);
-
-/*! \brief Get a channel technology structure by name
- * \param name name of technology to find
- * \return a pointer to the structure, or NULL if no matching technology found
- */
-const struct ast_channel_tech *ast_get_channel_tech(const char *name);
-
-/*! \brief Hang up a channel
- * \note This function performs a hard hangup on a channel. Unlike the soft-hangup, this function
- * performs all stream stopping, etc, on the channel that needs to end.
- * chan is no longer valid after this call.
- * \param chan channel to hang up
- * \return Returns 0 on success, -1 on failure.
- */
-int ast_hangup(struct ast_channel *chan);
-
-/*! \brief Softly hangup up a channel
- * \param chan channel to be soft-hung-up
- * Call the protocol layer, but don't destroy the channel structure (use this if you are trying to
- * safely hangup a channel managed by another thread.
- * \param cause Ast hangupcause for hangup
- * \return Returns 0 regardless
- */
-int ast_softhangup(struct ast_channel *chan, int cause);
-
-/*! \brief Softly hangup up a channel (no channel lock)
- * \param chan channel to be soft-hung-up
- * \param cause Ast hangupcause for hangup (see cause.h) */
-int ast_softhangup_nolock(struct ast_channel *chan, int cause);
-
-/*! \brief Check to see if a channel is needing hang up
- * \param chan channel on which to check for hang up
- * This function determines if the channel is being requested to be hung up.
- * \return Returns 0 if not, or 1 if hang up is requested (including time-out).
- */
-int ast_check_hangup(struct ast_channel *chan);
-
-/*! \brief Compare a offset with the settings of when to hang a channel up
- * \param chan channel on which to check for hang up
- * \param offset offset in seconds from current time
- * \return 1, 0, or -1
- * This function compares a offset from current time with the absolute time
- * out on a channel (when to hang up). If the absolute time out on a channel
- * is earlier than current time plus the offset, it returns 1, if the two
- * time values are equal, it return 0, otherwise, it retturn -1.
- */
-int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset);
-
-/*! \brief Set when to hang a channel up
- * \param chan channel on which to check for hang up
- * \param offset offset in seconds from current time of when to hang up
- * This function sets the absolute time out on a channel (when to hang up).
- */
-void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset);
-
-/*! \brief Answer a ringing call
- * \param chan channel to answer
- * This function answers a channel and handles all necessary call
- * setup functions.
- * \return Returns 0 on success, -1 on failure
- */
-int ast_answer(struct ast_channel *chan);
-
-/*! \brief Make a call
- * \param chan which channel to make the call on
- * \param addr destination of the call
- * \param timeout time to wait on for connect
- * Place a call, take no longer than timeout ms.
- \return Returns -1 on failure, 0 on not enough time
- (does not automatically stop ringing), and
- the number of seconds the connect took otherwise.
- */
-int ast_call(struct ast_channel *chan, char *addr, int timeout);
-
-/*! \brief Indicates condition of channel
- * \note Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
- * \param chan channel to change the indication
- * \param condition which condition to indicate on the channel
- * \return Returns 0 on success, -1 on failure
- */
-int ast_indicate(struct ast_channel *chan, int condition);
-
-/*! \brief Indicates condition of channel, with payload
- * \note Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
- * \param chan channel to change the indication
- * \param condition which condition to indicate on the channel
- * \param data pointer to payload data
- * \param datalen size of payload data
- * \return Returns 0 on success, -1 on failure
- */
-int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen);
-
-/* Misc stuff ------------------------------------------------ */
-
-/*! \brief Wait for input on a channel
- * \param chan channel to wait on
- * \param ms length of time to wait on the channel
- * Wait for input on a channel for a given # of milliseconds (<0 for indefinite).
- \return Returns < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise */
-int ast_waitfor(struct ast_channel *chan, int ms);
-
-/*! \brief Wait for a specied amount of time, looking for hangups
- * \param chan channel to wait for
- * \param ms length of time in milliseconds to sleep
- * Waits for a specified amount of time, servicing the channel as required.
- * \return returns -1 on hangup, otherwise 0.
- */
-int ast_safe_sleep(struct ast_channel *chan, int ms);
-
-/*! \brief Wait for a specied amount of time, looking for hangups and a condition argument
- * \param chan channel to wait for
- * \param ms length of time in milliseconds to sleep
- * \param cond a function pointer for testing continue condition
- * \param data argument to be passed to the condition test function
- * \return returns -1 on hangup, otherwise 0.
- * Waits for a specified amount of time, servicing the channel as required. If cond
- * returns 0, this function returns.
- */
-int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data );
-
-/*! \brief Waits for activity on a group of channels
- * \param chan an array of pointers to channels
- * \param n number of channels that are to be waited upon
- * \param fds an array of fds to wait upon
- * \param nfds the number of fds to wait upon
- * \param exception exception flag
- * \param outfd fd that had activity on it
- * \param ms how long the wait was
- * Big momma function here. Wait for activity on any of the n channels, or any of the nfds
- file descriptors.
- \return Returns the channel with activity, or NULL on error or if an FD
- came first. If the FD came first, it will be returned in outfd, otherwise, outfd
- will be -1 */
-struct ast_channel *ast_waitfor_nandfds(struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms);
-
-/*! \brief Waits for input on a group of channels
- Wait for input on an array of channels for a given # of milliseconds.
- \return Return channel with activity, or NULL if none has activity.
- \param chan an array of pointers to channels
- \param n number of channels that are to be waited upon
- \param ms time "ms" is modified in-place, if applicable */
-struct ast_channel *ast_waitfor_n(struct ast_channel **chan, int n, int *ms);
-
-/*! \brief Waits for input on an fd
- This version works on fd's only. Be careful with it. */
-int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception);
-
-
-/*! \brief Reads a frame
- * \param chan channel to read a frame from
- Read a frame.
- \return Returns a frame, or NULL on error. If it returns NULL, you
- best just stop reading frames and assume the channel has been
- disconnected. */
-struct ast_frame *ast_read(struct ast_channel *chan);
-
-/*! \brief Reads a frame, returning AST_FRAME_NULL frame if audio.
- * Read a frame.
- \param chan channel to read a frame from
- \return Returns a frame, or NULL on error. If it returns NULL, you
- best just stop reading frames and assume the channel has been
- disconnected.
- \note Audio is replaced with AST_FRAME_NULL to avoid
- transcode when the resulting audio is not necessary. */
-struct ast_frame *ast_read_noaudio(struct ast_channel *chan);
-
-/*! \brief Write a frame to a channel
- * This function writes the given frame to the indicated channel.
- * \param chan destination channel of the frame
- * \param frame frame that will be written
- * \return It returns 0 on success, -1 on failure.
- */
-int ast_write(struct ast_channel *chan, struct ast_frame *frame);
-
-/*! \brief Write video frame to a channel
- * This function writes the given frame to the indicated channel.
- * \param chan destination channel of the frame
- * \param frame frame that will be written
- * \return It returns 1 on success, 0 if not implemented, and -1 on failure.
- */
-int ast_write_video(struct ast_channel *chan, struct ast_frame *frame);
-
-/*! \brief Send empty audio to prime a channel driver */
-int ast_prod(struct ast_channel *chan);
-
-/*! \brief Sets read format on channel chan
- * Set read format for channel to whichever component of "format" is best.
- * \param chan channel to change
- * \param format format to change to
- * \return Returns 0 on success, -1 on failure
- */
-int ast_set_read_format(struct ast_channel *chan, int format);
-
-/*! \brief Sets write format on channel chan
- * Set write format for channel to whichever compoent of "format" is best.
- * \param chan channel to change
- * \param format new format for writing
- * \return Returns 0 on success, -1 on failure
- */
-int ast_set_write_format(struct ast_channel *chan, int format);
-
-/*! \brief Sends text to a channel
- * Write text to a display on a channel
- * \param chan channel to act upon
- * \param text string of text to send on the channel
- * \return Returns 0 on success, -1 on failure
- */
-int ast_sendtext(struct ast_channel *chan, const char *text);
-
-/*! \brief Receives a text character from a channel
- * \param chan channel to act upon
- * \param timeout timeout in milliseconds (0 for infinite wait)
- * Read a char of text from a channel
- * Returns 0 on success, -1 on failure
- */
-int ast_recvchar(struct ast_channel *chan, int timeout);
-
-/*! \brief Send a DTMF digit to a channel
- * Send a DTMF digit to a channel.
- * \param chan channel to act upon
- * \param digit the DTMF digit to send, encoded in ASCII
- * \return Returns 0 on success, -1 on failure
- */
-int ast_senddigit(struct ast_channel *chan, char digit);
-
-int ast_senddigit_begin(struct ast_channel *chan, char digit);
-int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration);
-
-/*! \brief Receives a text string from a channel
- * Read a string of text from a channel
- * \param chan channel to act upon
- * \param timeout timeout in milliseconds (0 for infinite wait)
- * \return the received text, or NULL to signify failure.
- */
-char *ast_recvtext(struct ast_channel *chan, int timeout);
-
-/*! \brief Browse channels in use
- * Browse the channels currently in use
- * \param prev where you want to start in the channel list
- * \return Returns the next channel in the list, NULL on end.
- * If it returns a channel, that channel *has been locked*!
- */
-struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev);
-
-/*! \brief Get channel by name (locks channel) */
-struct ast_channel *ast_get_channel_by_name_locked(const char *chan);
-
-/*! \brief Get channel by name prefix (locks channel) */
-struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen);
-
-/*! \brief Get channel by name prefix (locks channel) */
-struct ast_channel *ast_walk_channel_by_name_prefix_locked(const struct ast_channel *chan, const char *name, const int namelen);
-
-/*! \brief Get channel by exten (and optionally context) and lock it */
-struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context);
-
-/*! \brief Get next channel by exten (and optionally context) and lock it */
-struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *chan, const char *exten,
- const char *context);
-
-/*! ! \brief Waits for a digit
- * \param c channel to wait for a digit on
- * \param ms how many milliseconds to wait
- * \return Returns <0 on error, 0 on no entry, and the digit on success. */
-int ast_waitfordigit(struct ast_channel *c, int ms);
-
-/*! \brief Wait for a digit
- Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
- * \param c channel to wait for a digit on
- * \param ms how many milliseconds to wait
- * \param audiofd audio file descriptor to write to if audio frames are received
- * \param ctrlfd control file descriptor to monitor for reading
- * \return Returns 1 if ctrlfd becomes available */
-int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int ctrlfd);
-
-/*! Reads multiple digits
- * \param c channel to read from
- * \param s string to read in to. Must be at least the size of your length
- * \param len how many digits to read (maximum)
- * \param timeout how long to timeout between digits
- * \param rtimeout timeout to wait on the first digit
- * \param enders digits to end the string
- * Read in a digit string "s", max length "len", maximum timeout between
- digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout
- for the first digit. Returns 0 on normal return, or 1 on a timeout. In the case of
- a timeout, any digits that were read before the timeout will still be available in s.
- RETURNS 2 in full version when ctrlfd is available, NOT 1*/
-int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders);
-int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd);
-
-/*! \brief Report DTMF on channel 0 */
-#define AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0)
-/*! \brief Report DTMF on channel 1 */
-#define AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1)
-/*! \brief Return all voice frames on channel 0 */
-#define AST_BRIDGE_REC_CHANNEL_0 (1 << 2)
-/*! \brief Return all voice frames on channel 1 */
-#define AST_BRIDGE_REC_CHANNEL_1 (1 << 3)
-/*! \brief Ignore all signal frames except NULL */
-#define AST_BRIDGE_IGNORE_SIGS (1 << 4)
-
-
-/*! \brief Makes two channel formats compatible
- * \param c0 first channel to make compatible
- * \param c1 other channel to make compatible
- * Set two channels to compatible formats -- call before ast_channel_bridge in general .
- * \return Returns 0 on success and -1 if it could not be done */
-int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1);
-
-/*! Bridge two channels together
- * \param c0 first channel to bridge
- * \param c1 second channel to bridge
- * \param config config for the channels
- * \param fo destination frame(?)
- * \param rc destination channel(?)
- * Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in
- *rf (remember, it could be NULL) and which channel (0 or 1) in rc */
-/* int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc); */
-int ast_channel_bridge(struct ast_channel *c0,struct ast_channel *c1,struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc);
-
-/*! \brief Weird function made for call transfers
- * \param original channel to make a copy of
- * \param clone copy of the original channel
- * This is a very strange and freaky function used primarily for transfer. Suppose that
- "original" and "clone" are two channels in random situations. This function takes
- the guts out of "clone" and puts them into the "original" channel, then alerts the
- channel driver of the change, asking it to fixup any private information (like the
- p->owner pointer) that is affected by the change. The physical layer of the original
- channel is hung up. */
-int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone);
-
-/*! Gives the string form of a given cause code */
-/*!
- * \param state cause to get the description of
- * Give a name to a cause code
- * Returns the text form of the binary cause code given
- */
-const char *ast_cause2str(int state) attribute_pure;
-
-/*! Convert the string form of a cause code to a number */
-/*!
- * \param name string form of the cause
- * Returns the cause code
- */
-int ast_str2cause(const char *name) attribute_pure;
-
-/*! Gives the string form of a given channel state */
-/*!
- * \param ast_channel_state state to get the name of
- * Give a name to a state
- * Returns the text form of the binary state given
- */
-char *ast_state2str(enum ast_channel_state);
-
-/*! Gives the string form of a given transfer capability */
-/*!
- * \param transfercapability transfercapabilty to get the name of
- * Give a name to a transfercapbility
- * See above
- * Returns the text form of the binary transfer capbility
- */
-char *ast_transfercapability2str(int transfercapability) attribute_const;
-
-/* Options: Some low-level drivers may implement "options" allowing fine tuning of the
- low level channel. See frame.h for options. Note that many channel drivers may support
- none or a subset of those features, and you should not count on this if you want your
- asterisk application to be portable. They're mainly useful for tweaking performance */
-
-/*! Sets an option on a channel */
-/*!
- * \param channel channel to set options on
- * \param option option to change
- * \param data data specific to option
- * \param datalen length of the data
- * \param block blocking or not
- * Set an option on a channel (see frame.h), optionally blocking awaiting the reply
- * Returns 0 on success and -1 on failure
- */
-int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block);
-
-/*! Pick the best codec */
-/* Choose the best codec... Uhhh... Yah. */
-int ast_best_codec(int fmts);
-
-
-/*! Checks the value of an option */
-/*!
- * Query the value of an option, optionally blocking until a reply is received
- * Works similarly to setoption except only reads the options.
- */
-struct ast_frame *ast_channel_queryoption(struct ast_channel *channel, int option, void *data, int *datalen, int block);
-
-/*! Checks for HTML support on a channel */
-/*! Returns 0 if channel does not support HTML or non-zero if it does */
-int ast_channel_supports_html(struct ast_channel *channel);
-
-/*! Sends HTML on given channel */
-/*! Send HTML or URL on link. Returns 0 on success or -1 on failure */
-int ast_channel_sendhtml(struct ast_channel *channel, int subclass, const char *data, int datalen);
-
-/*! Sends a URL on a given link */
-/*! Send URL on link. Returns 0 on success or -1 on failure */
-int ast_channel_sendurl(struct ast_channel *channel, const char *url);
-
-/*! Defers DTMF */
-/*! Defer DTMF so that you only read things like hangups and audio. Returns
- non-zero if channel was already DTMF-deferred or 0 if channel is just now
- being DTMF-deferred */
-int ast_channel_defer_dtmf(struct ast_channel *chan);
-
-/*! Undeos a defer */
-/*! Undo defer. ast_read will return any dtmf characters that were queued */
-void ast_channel_undefer_dtmf(struct ast_channel *chan);
-
-/*! Initiate system shutdown -- prevents new channels from being allocated.
- If "hangup" is non-zero, all existing channels will receive soft
- hangups */
-void ast_begin_shutdown(int hangup);
-
-/*! Cancels an existing shutdown and returns to normal operation */
-void ast_cancel_shutdown(void);
-
-/*! Returns number of active/allocated channels */
-int ast_active_channels(void);
-
-/*! Returns non-zero if Asterisk is being shut down */
-int ast_shutting_down(void);
-
-/*! Activate a given generator */
-int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params);
-
-/*! Deactive an active generator */
-void ast_deactivate_generator(struct ast_channel *chan);
-
-/*!
- * \note The channel does not need to be locked before calling this function.
- */
-void ast_set_callerid(struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani);
-
-
-/*! return a mallocd string with the result of sprintf of the fmt and following args */
-char *ast_safe_string_alloc(const char *fmt, ...);
-
-
-
-/*! Start a tone going */
-int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol);
-/*! Stop a tone from playing */
-void ast_tonepair_stop(struct ast_channel *chan);
-/*! Play a tone pair for a given amount of time */
-int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol);
-
-/*!
- * \brief Automatically service a channel for us...
- *
- * \retval 0 success
- * \retval -1 failure, or the channel is already being autoserviced
- */
-int ast_autoservice_start(struct ast_channel *chan);
-
-/*!
- * \brief Stop servicing a channel for us...
- *
- * \retval 0 success
- * \retval -1 error, or the channel has been hungup
- */
-int ast_autoservice_stop(struct ast_channel *chan);
-
-/* If built with zaptel optimizations, force a scheduled expiration on the
- timer fd, at which point we call the callback function / data */
-int ast_settimeout(struct ast_channel *c, int samples, int (*func)(const void *data), void *data);
-
-/*! \brief Transfer a channel (if supported). Returns -1 on error, 0 if not supported
- and 1 if supported and requested
- \param chan current channel
- \param dest destination extension for transfer
-*/
-int ast_transfer(struct ast_channel *chan, char *dest);
-
-/*! \brief Start masquerading a channel
- XXX This is a seriously wacked out operation. We're essentially putting the guts of
- the clone channel into the original channel. Start by killing off the original
- channel's backend. I'm not sure we're going to keep this function, because
- while the features are nice, the cost is very high in terms of pure nastiness. XXX
- \param chan Channel to masquerade
-*/
-int ast_do_masquerade(struct ast_channel *chan);
-
-/*! \brief Find bridged channel
- \param chan Current channel
-*/
-struct ast_channel *ast_bridged_channel(struct ast_channel *chan);
-
-/*!
- \brief Inherits channel variable from parent to child channel
- \param parent Parent channel
- \param child Child channel
-
- Scans all channel variables in the parent channel, looking for those
- that should be copied into the child channel.
- Variables whose names begin with a single '_' are copied into the
- child channel with the prefix removed.
- Variables whose names begin with '__' are copied into the child
- channel with their names unchanged.
-*/
-void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child);
-
-/*!
- \brief adds a list of channel variables to a channel
- \param chan the channel
- \param vars a linked list of variables
-
- Variable names can be for a regular channel variable or a dialplan function
- that has the ability to be written to.
-*/
-void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars);
-
-/*!
- \brief An opaque 'object' structure use by silence generators on channels.
- */
-struct ast_silence_generator;
-
-/*!
- \brief Starts a silence generator on the given channel.
- \param chan The channel to generate silence on
- \return An ast_silence_generator pointer, or NULL if an error occurs
-
- This function will cause SLINEAR silence to be generated on the supplied
- channel until it is disabled; if the channel cannot be put into SLINEAR
- mode then the function will fail.
-
- The pointer returned by this function must be preserved and passed to
- ast_channel_stop_silence_generator when you wish to stop the silence
- generation.
- */
-struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan);
-
-/*!
- \brief Stops a previously-started silence generator on the given channel.
- \param chan The channel to operate on
- \param state The ast_silence_generator pointer return by a previous call to
- ast_channel_start_silence_generator.
- \return nothing
-
- This function will stop the operating silence generator and return the channel
- to its previous write format.
- */
-void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state);
-
-/*!
- \brief Check if the channel can run in internal timing mode.
- \param chan The channel to check
- \return boolean
-
- This function will return 1 if internal timing is enabled and the timing
- device is available.
- */
-int ast_internal_timing_enabled(struct ast_channel *chan);
-
-/* Misc. functions below */
-
-/*! \brief if fd is a valid descriptor, set *pfd with the descriptor
- * \return Return 1 (not -1!) if added, 0 otherwise (so we can add the
- * return value to the index into the array)
- */
-static inline int ast_add_fd(struct pollfd *pfd, int fd)
-{
- pfd->fd = fd;
- pfd->events = POLLIN | POLLPRI;
- return fd >= 0;
-}
-
-/*! \brief Helper function for migrating select to poll */
-static inline int ast_fdisset(struct pollfd *pfds, int fd, int max, int *start)
-{
- int x;
- int dummy=0;
-
- if (fd < 0)
- return 0;
- if (!start)
- start = &dummy;
- for (x = *start; x<max; x++)
- if (pfds[x].fd == fd) {
- if (x == *start)
- (*start)++;
- return pfds[x].revents;
- }
- return 0;
-}
-
-#ifdef SOLARIS
-static inline void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
-{
- tvdiff->tv_sec = tvend->tv_sec - tvstart->tv_sec;
- tvdiff->tv_usec = tvend->tv_usec - tvstart->tv_usec;
- if (tvdiff->tv_usec < 0) {
- tvdiff->tv_sec --;
- tvdiff->tv_usec += 1000000;
- }
-
-}
-#endif
-
-/*! \brief Waits for activity on a group of channels
- * \param nfds the maximum number of file descriptors in the sets
- * \param rfds file descriptors to check for read availability
- * \param wfds file descriptors to check for write availability
- * \param efds file descriptors to check for exceptions (OOB data)
- * \param tvp timeout while waiting for events
- * This is the same as a standard select(), except it guarantees the
- * behaviour where the passed struct timeval is updated with how much
- * time was not slept while waiting for the specified events
- */
-static inline int ast_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tvp)
-{
-#ifdef __linux__
- return select(nfds, rfds, wfds, efds, tvp);
-#else
- if (tvp) {
- struct timeval tv, tvstart, tvend, tvlen;
- int res;
-
- tv = *tvp;
- gettimeofday(&tvstart, NULL);
- res = select(nfds, rfds, wfds, efds, tvp);
- gettimeofday(&tvend, NULL);
- timersub(&tvend, &tvstart, &tvlen);
- timersub(&tv, &tvlen, tvp);
- if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) {
- tvp->tv_sec = 0;
- tvp->tv_usec = 0;
- }
- return res;
- }
- else
- return select(nfds, rfds, wfds, efds, NULL);
-#endif
-}
-
-#ifdef DO_CRASH
-#define CRASH do { fprintf(stderr, "!! Forcing immediate crash a-la abort !!\n"); *((int *)0) = 0; } while(0)
-#else
-#define CRASH do { } while(0)
-#endif
-
-#define CHECK_BLOCKING(c) do { \
- if (ast_test_flag(c, AST_FLAG_BLOCKING)) {\
- if (option_debug) \
- ast_log(LOG_DEBUG, "Thread %ld Blocking '%s', already blocked by thread %ld in procedure %s\n", (long) pthread_self(), (c)->name, (long) (c)->blocker, (c)->blockproc); \
- CRASH; \
- } else { \
- (c)->blocker = pthread_self(); \
- (c)->blockproc = __PRETTY_FUNCTION__; \
- ast_set_flag(c, AST_FLAG_BLOCKING); \
- } } while (0)
-
-ast_group_t ast_get_group(const char *s);
-
-/*! \brief print call- and pickup groups into buffer */
-char *ast_print_group(char *buf, int buflen, ast_group_t group);
-
-/*! \brief Convert enum channelreloadreason to text string for manager event
- \param reason Enum channelreloadreason - reason for reload (manager, cli, start etc)
-*/
-const char *channelreloadreason2txt(enum channelreloadreason reason);
-
-/*! \brief return an ast_variable list of channeltypes */
-struct ast_variable *ast_channeltype_list(void);
-
-/*!
- \brief Begin 'whispering' onto a channel
- \param chan The channel to whisper onto
- \return 0 for success, non-zero for failure
-
- This function will add a whisper buffer onto a channel and set a flag
- causing writes to the channel to reduce the volume level of the written
- audio samples, and then to mix in audio from the whisper buffer if it
- is available.
-
- Note: This function performs no locking; you must hold the channel's lock before
- calling this function.
- */
-int ast_channel_whisper_start(struct ast_channel *chan);
-
-/*!
- \brief Feed an audio frame into the whisper buffer on a channel
- \param chan The channel to whisper onto
- \param f The frame to to whisper onto chan
- \return 0 for success, non-zero for failure
- */
-int ast_channel_whisper_feed(struct ast_channel *chan, struct ast_frame *f);
-
-/*!
- \brief Stop 'whispering' onto a channel
- \param chan The channel to whisper onto
- \return 0 for success, non-zero for failure
-
- Note: This function performs no locking; you must hold the channel's lock before
- calling this function.
- */
-void ast_channel_whisper_stop(struct ast_channel *chan);
-
-
-
-/*!
- \brief return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
- \param reason The integer argument, usually taken from AST_CONTROL_ macros
- \return char pointer explaining the code
- */
-char *ast_channel_reason2str(int reason);
-
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_CHANNEL_H */
diff --git a/1.4/include/asterisk/chanvars.h b/1.4/include/asterisk/chanvars.h
deleted file mode 100644
index 63de58429..000000000
--- a/1.4/include/asterisk/chanvars.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Channel Variables
- */
-
-#ifndef _ASTERISK_CHANVARS_H
-#define _ASTERISK_CHANVARS_H
-
-#include "asterisk/linkedlists.h"
-
-struct ast_var_t {
- AST_LIST_ENTRY(ast_var_t) entries;
- char *value;
- char name[0];
-};
-
-AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
-
-struct ast_var_t *ast_var_assign(const char *name, const char *value);
-void ast_var_delete(struct ast_var_t *var);
-const char *ast_var_name(const struct ast_var_t *var);
-const char *ast_var_full_name(const struct ast_var_t *var);
-const char *ast_var_value(const struct ast_var_t *var);
-
-#endif /* _ASTERISK_CHANVARS_H */
diff --git a/1.4/include/asterisk/cli.h b/1.4/include/asterisk/cli.h
deleted file mode 100644
index 9a7b53a36..000000000
--- a/1.4/include/asterisk/cli.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Standard Command Line Interface
- */
-
-#ifndef _ASTERISK_CLI_H
-#define _ASTERISK_CLI_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <stdarg.h>
-
-#include "asterisk/linkedlists.h"
-
-void ast_cli(int fd, char *fmt, ...)
- __attribute__ ((format (printf, 2, 3)));
-
-#define RESULT_SUCCESS 0
-#define RESULT_SHOWUSAGE 1
-#define RESULT_FAILURE 2
-
-#define AST_MAX_CMD_LEN 16
-
-#define AST_MAX_ARGS 64
-
-#define AST_CLI_COMPLETE_EOF "_EOF_"
-
-/*! \brief A command line entry */
-struct ast_cli_entry {
- char * const cmda[AST_MAX_CMD_LEN];
- /*! Handler for the command (fd for output, # of args, argument list).
- Returns RESULT_SHOWUSAGE for improper arguments.
- argv[] has argc 'useful' entries, and an additional NULL entry
- at the end so that clients requiring NULL terminated arrays
- can use it without need for copies.
- You can overwrite argv or the strings it points to, but remember
- that this memory is deallocated after the handler returns.
- */
- int (*handler)(int fd, int argc, char *argv[]);
- /*! Summary of the command (< 60 characters) */
- const char *summary;
- /*! Detailed usage information */
- const char *usage;
- /*! Generate the n-th (starting from 0) possible completion
- for a given 'word' following 'line' in position 'pos'.
- 'line' and 'word' must not be modified.
- Must return a malloc'ed string with the n-th value when available,
- or NULL if the n-th completion does not exist.
- Typically, the function is called with increasing values for n
- until a NULL is returned.
- */
- char *(*generator)(const char *line, const char *word, int pos, int n);
- struct ast_cli_entry *deprecate_cmd;
- /*! For keeping track of usage */
- int inuse;
- struct module *module; /*! module this belongs to */
- char *_full_cmd; /* built at load time from cmda[] */
- /* This gets set in ast_cli_register()
- It then gets set to something different when the deprecated command
- is run for the first time (ie; after we warn the user that it's deprecated)
- */
- int deprecated;
- char *_deprecated_by; /* copied from the "parent" _full_cmd, on deprecated commands */
- /*! For linking */
- AST_LIST_ENTRY(ast_cli_entry) list;
-};
-
-/*!
- * \brief Helper function to generate cli entries from a NULL-terminated array.
- * Returns the n-th matching entry from the array, or NULL if not found.
- * Can be used to implement generate() for static entries as below
- * (in this example we complete the word in position 2):
- \code
- char *my_generate(const char *line, const char *word, int pos, int n)
- {
- static char *choices = { "one", "two", "three", NULL };
- if (pos == 2)
- return ast_cli_complete(word, choices, n);
- else
- return NULL;
- }
- \endcode
- */
-char *ast_cli_complete(const char *word, char *const choices[], int pos);
-
-/*! \brief Interprets a command
- * Interpret a command s, sending output to fd
- * Returns 0 on succes, -1 on failure
- */
-int ast_cli_command(int fd, const char *s);
-
-/*!
- * \brief Executes multiple CLI commands
- * Interpret strings separated by '\0' and execute each one, sending output to fd
- * \param size is the total size of the string
- * \retval number of commands executed
- */
-int ast_cli_command_multiple(int fd, size_t size, const char *s);
-
-/*! \brief Registers a command or an array of commands
- * \param e which cli entry to register
- * Register your own command
- * Returns 0 on success, -1 on failure
- */
-int ast_cli_register(struct ast_cli_entry *e);
-
-/*!
- * \brief Register multiple commands
- * \param e pointer to first cli entry to register
- * \param len number of entries to register
- */
-void ast_cli_register_multiple(struct ast_cli_entry *e, int len);
-
-/*! \brief Unregisters a command or an array of commands
- *
- * \param e which cli entry to unregister
- * Unregister your own command. You must pass a completed ast_cli_entry structure
- * Returns 0.
- */
-int ast_cli_unregister(struct ast_cli_entry *e);
-
-/*!
- * \brief Unregister multiple commands
- * \param e pointer to first cli entry to unregister
- * \param len number of entries to unregister
- */
-void ast_cli_unregister_multiple(struct ast_cli_entry *e, int len);
-
-/*! \brief Readline madness
- * Useful for readline, that's about it
- * Returns 0 on success, -1 on failure
- */
-char *ast_cli_generator(const char *, const char *, int);
-
-int ast_cli_generatornummatches(const char *, const char *);
-
-/*!
- * \brief Generates a NULL-terminated array of strings that
- * 1) begin with the string in the second parameter, and
- * 2) are valid in a command after the string in the first parameter.
- *
- * The first entry (offset 0) of the result is the longest common substring
- * in the results, useful to extend the string that has been completed.
- * Subsequent entries are all possible values, followe by a NULL.
- * All strings and the array itself are malloc'ed and must be freed
- * by the caller.
- */
-char **ast_cli_completion_matches(const char *, const char *);
-
-/*!
- * \brief Command completion for the list of active channels
- *
- * This can be called from a CLI command completion function that wants to
- * complete from the list of active channels. 'rpos' is the required
- * position in the command. This function will return NULL immediately if
- * 'rpos' is not the same as the current position, 'pos'.
- */
-char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_CLI_H */
diff --git a/1.4/include/asterisk/compat.h b/1.4/include/asterisk/compat.h
deleted file mode 100644
index 2c131527d..000000000
--- a/1.4/include/asterisk/compat.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Copyright (C) 1999-2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief General Definitions for Asterisk top level program
- */
-
-#ifndef _COMPAT_H
-#define _COMPAT_H
-
-#include "asterisk/autoconfig.h"
-#include <inttypes.h>
-#include <sys/types.h>
-#include <stdarg.h>
-
-#if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
-int asprintf(char **str, const char *fmt, ...);
-#endif
-
-#ifndef HAVE_GETLOADAVG
-int getloadavg(double *list, int nelem);
-#endif
-
-#ifndef HAVE_SETENV
-int setenv(const char *name, const char *value, int overwrite);
-#endif
-
-#ifndef HAVE_STRCASESTR
-char *strcasestr(const char *, const char *);
-#endif
-
-#if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
-char *strndup(const char *, size_t);
-#endif
-
-#ifndef HAVE_STRNLEN
-size_t strnlen(const char *, size_t);
-#endif
-
-#ifndef HAVE_STRSEP
-char* strsep(char** str, const char* delims);
-#endif
-
-#ifndef HAVE_STRTOQ
-uint64_t strtoq(const char *nptr, char **endptr, int base);
-#endif
-
-#ifndef HAVE_UNSETENV
-int unsetenv(const char *name);
-#endif
-
-#if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
-int vasprintf(char **strp, const char *fmt, va_list ap);
-#endif
-
-#ifndef HAVE_STRLCAT
-size_t strlcat(char *dst, const char *src, size_t siz);
-#endif
-
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t siz);
-#endif
-
-#ifdef SOLARIS
-#define __BEGIN_DECLS
-#define __END_DECLS
-
-#ifndef __P
-#define __P(p) p
-#endif
-
-#include <alloca.h>
-#include <strings.h>
-#include <string.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <netinet/in.h>
-#include <sys/loadavg.h>
-#include <dat/dat_platform_specific.h>
-
-#ifndef BYTE_ORDER
-#define LITTLE_ENDIAN 1234
-#define BIG_ENDIAN 4321
-
-#ifdef __sparc__
-#define BYTE_ORDER BIG_ENDIAN
-#else
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
-#endif
-
-#ifndef __BYTE_ORDER
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#define __BYTE_ORDER BYTE_ORDER
-#endif
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-typedef unsigned char u_int8_t;
-typedef unsigned short u_int16_t;
-typedef unsigned int u_int32_t;
-#endif
-
-#endif /* SOLARIS */
-
-#ifdef __CYGWIN__
-#define _WIN32_WINNT 0x0500
-#ifndef INET_ADDRSTRLEN
-#define INET_ADDRSTRLEN 16
-#endif
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif
-#endif /* __CYGWIN__ */
-
-#ifdef __CYGWIN__
-typedef unsigned long long uint64_t;
-#endif
-
-#endif
diff --git a/1.4/include/asterisk/compiler.h b/1.4/include/asterisk/compiler.h
deleted file mode 100644
index 618950017..000000000
--- a/1.4/include/asterisk/compiler.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Compiler-specific macros and other items
- */
-
-#ifndef _ASTERISK_COMPILER_H
-#define _ASTERISK_COMPILER_H
-
-#ifdef HAVE_ATTRIBUTE_always_inline
-#define force_inline __attribute__((always_inline)) inline
-#else
-#define force_inline inline
-#endif
-
-#ifdef HAVE_ATTRIBUTE_pure
-#define attribute_pure __attribute__((pure))
-#else
-#define attribute_pure
-#endif
-
-#ifdef HAVE_ATTRIBUTE_const
-#define attribute_const __attribute__((const))
-#else
-#define attribute_const
-#endif
-
-#ifdef HAVE_ATTRIBUTE_unused
-#define attribute_unused __attribute__((unused))
-#else
-#define attribute_unused
-#endif
-
-#ifdef HAVE_ATTRIBUTE_malloc
-#define attribute_malloc __attribute__((malloc))
-#else
-#define attribute_malloc
-#endif
-
-#ifdef HAVE_ATTRIBUTE_deprecated
-#define attribute_deprecated __attribute__((deprecated))
-#else
-#define attribute_deprecated
-#endif
-
-#endif /* _ASTERISK_COMPILER_H */
diff --git a/1.4/include/asterisk/config.h b/1.4/include/asterisk/config.h
deleted file mode 100644
index 160636588..000000000
--- a/1.4/include/asterisk/config.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Configuration File Parser
- */
-
-#ifndef _ASTERISK_CONFIG_H
-#define _ASTERISK_CONFIG_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <stdarg.h>
-
-struct ast_config;
-
-struct ast_category;
-
-struct ast_variable {
- char *name;
- char *value;
- int lineno;
- int object; /*!< 0 for variable, 1 for object */
- int blanklines; /*!< Number of blanklines following entry */
- struct ast_comment *precomments;
- struct ast_comment *sameline;
- struct ast_variable *next;
- char stuff[0];
-};
-
-typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments);
-typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
-typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
-typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
-
-struct ast_config_engine {
- char *name;
- config_load_func *load_func;
- realtime_var_get *realtime_func;
- realtime_multi_get *realtime_multi_func;
- realtime_update *update_func;
- struct ast_config_engine *next;
-};
-
-/*! \brief Load a config file
- * \param filename path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR
- * Create a config structure from a given configuration file.
- *
- * Returns NULL on error, or an ast_config data structure on success
- */
-struct ast_config *ast_config_load(const char *filename);
-struct ast_config *ast_config_load_with_comments(const char *filename);
-
-/*! \brief Destroys a config
- * \param config pointer to config data structure
- * Free memory associated with a given config
- *
- */
-void ast_config_destroy(struct ast_config *config);
-
-/*! \brief returns the root ast_variable of a config
- * \param config pointer to an ast_config data structure
- * \param cat name of the category for which you want the root
- *
- * Returns the category specified
- */
-struct ast_variable *ast_category_root(struct ast_config *config, char *cat);
-
-/*! \brief Goes through categories
- * \param config Which config structure you wish to "browse"
- * \param prev A pointer to a previous category.
- * This funtion is kind of non-intuitive in it's use. To begin, one passes NULL as the second arguement. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards.
- *
- * Returns a category on success, or NULL on failure/no-more-categories
- */
-char *ast_category_browse(struct ast_config *config, const char *prev);
-
-/*! \brief Goes through variables
- * Somewhat similar in intent as the ast_category_browse.
- * List variables of config file category
- *
- * Returns ast_variable list on success, or NULL on failure
- */
-struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
-
-/*! \brief Gets a variable
- * \param config which (opened) config to use
- * \param category category under which the variable lies
- * \param variable which variable you wish to get the data for
- * Goes through a given config file in the given category and searches for the given variable
- *
- * Returns the variable value on success, or NULL if unable to find it.
- */
-const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
-
-/*! \brief Retrieve a category if it exists
- * \param config which config to use
- * \param category_name name of the category you're looking for
- * This will search through the categories within a given config file for a match.
- *
- * Returns pointer to category if found, NULL if not.
- */
-struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name);
-
-/*! \brief Check for category duplicates
- * \param config which config to use
- * \param category_name name of the category you're looking for
- * This will search through the categories within a given config file for a match.
- *
- * Return non-zero if found
- */
-int ast_category_exist(const struct ast_config *config, const char *category_name);
-
-/*! \brief Retrieve realtime configuration
- * \param family which family/config to lookup
- * This will use builtin configuration backends to look up a particular
- * entity in realtime and return a variable list of its parameters. Note
- * that unlike the variables in ast_config, the resulting list of variables
- * MUST be freed with ast_variables_destroy() as there is no container.
- */
-struct ast_variable *ast_load_realtime(const char *family, ...);
-
-/*! \brief Retrieve realtime configuration
- * \param family which family/config to lookup
- * This will use builtin configuration backends to look up a particular
- * entity in realtime and return a variable list of its parameters. Unlike
- * the ast_load_realtime, this function can return more than one entry and
- * is thus stored inside a taditional ast_config structure rather than
- * just returning a linked list of variables.
- */
-struct ast_config *ast_load_realtime_multientry(const char *family, ...);
-
-/*! \brief Update realtime configuration
- * \param family which family/config to be updated
- * \param keyfield which field to use as the key
- * \param lookup which value to look for in the key field to match the entry.
- * This function is used to update a parameter in realtime configuration space.
- *
- */
-int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...);
-
-/*! \brief Check if realtime engine is configured for family
- * returns 1 if family is configured in realtime and engine exists
- * \param family which family/config to be checked
-*/
-int ast_check_realtime(const char *family);
-
-/*! \brief Free variable list
- * \param var the linked list of variables to free
- * This function frees a list of variables.
- */
-void ast_variables_destroy(struct ast_variable *var);
-
-/*! \brief Register config engine */
-int ast_config_engine_register(struct ast_config_engine *newconfig);
-
-/*! \brief Deegister config engine */
-int ast_config_engine_deregister(struct ast_config_engine *del);
-
-int register_config_cli(void);
-int read_config_maps(void);
-
-struct ast_config *ast_config_new(void);
-struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
-void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat);
-const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var);
-
-struct ast_category *ast_category_new(const char *name);
-void ast_category_append(struct ast_config *config, struct ast_category *cat);
-int ast_category_delete(struct ast_config *cfg, char *category);
-void ast_category_destroy(struct ast_category *cat);
-struct ast_variable *ast_category_detach_variables(struct ast_category *cat);
-void ast_category_rename(struct ast_category *cat, const char *name);
-
-struct ast_variable *ast_variable_new(const char *name, const char *value);
-void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
-int ast_variable_delete(struct ast_category *category, char *variable, char *match);
-int ast_variable_update(struct ast_category *category, const char *variable,
- const char *value, const char *match, unsigned int object);
-
-int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);
-
-struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, int withcomments);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_CONFIG_H */
diff --git a/1.4/include/asterisk/crypto.h b/1.4/include/asterisk/crypto.h
deleted file mode 100644
index 32233fc17..000000000
--- a/1.4/include/asterisk/crypto.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Provide cryptographic signature routines
- */
-
-#ifndef _ASTERISK_CRYPTO_H
-#define _ASTERISK_CRYPTO_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define AST_KEY_PUBLIC (1 << 0)
-#define AST_KEY_PRIVATE (1 << 1)
-
-struct ast_key;
-
-/*! \brief Retrieve a key
- * \param name of the key we are retrieving
- * \param int type of key (AST_KEY_PUBLIC or AST_KEY_PRIVATE)
- *
- * Returns the key on success or NULL on failure
- */
-struct ast_key *(*ast_key_get)(const char *key, int type);
-
-/*! \brief Check the authenticity of a message signature using a given public key
- * \param key a public key to use to verify
- * \param msg the message that has been signed
- * \param sig the proposed valid signature in mime64-like encoding
- *
- * Returns 0 if the signature is valid, or -1 otherwise
- *
- */
-int (*ast_check_signature)(struct ast_key *key, const char *msg, const char *sig);
-
-/*! \brief Check the authenticity of a message signature using a given public key
- * \param key a public key to use to verify
- * \param msg the message that has been signed
- * \param sig the proposed valid signature in raw binary representation
- *
- * Returns 0 if the signature is valid, or -1 otherwise
- *
- */
-int (*ast_check_signature_bin)(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig);
-
-/*!
- * \param key a private key to use to create the signature
- * \param msg the message to sign
- * \param sig a pointer to a buffer of at least 256 bytes in which the
- * mime64-like encoded signature will be stored
- *
- * Returns 0 on success or -1 on failure.
- *
- */
-int (*ast_sign)(struct ast_key *key, char *msg, char *sig);
-
-/*!
- * \param key a private key to use to create the signature
- * \param msg the message to sign
- * \param sig a pointer to a buffer of at least 128 bytes in which the
- * raw encoded signature will be stored
- *
- * Returns 0 on success or -1 on failure.
- *
- */
-int (*ast_sign_bin)(struct ast_key *key, const char *msg, int msglen, unsigned char *sig);
-
-/*!
- * \param key a private key to use to encrypt
- * \param src the message to encrypt
- * \param srclen the length of the message to encrypt
- * \param dst a pointer to a buffer of at least srclen * 1.5 bytes in which the encrypted
- * answer will be stored
- *
- * Returns length of encrypted data on success or -1 on failure.
- *
- */
-int (*ast_encrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key);
-
-/*!
- * \param key a private key to use to decrypt
- * \param src the message to decrypt
- * \param srclen the length of the message to decrypt
- * \param dst a pointer to a buffer of at least srclen bytes in which the decrypted
- * answer will be stored
- *
- * Returns length of decrypted data on success or -1 on failure.
- *
- */
-int (*ast_decrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key);
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_CRYPTO_H */
diff --git a/1.4/include/asterisk/devicestate.h b/1.4/include/asterisk/devicestate.h
deleted file mode 100644
index ed9022fbd..000000000
--- a/1.4/include/asterisk/devicestate.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Device state management
- */
-
-#ifndef _ASTERISK_DEVICESTATE_H
-#define _ASTERISK_DEVICESTATE_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! Device is valid but channel didn't know state */
-#define AST_DEVICE_UNKNOWN 0
-/*! Device is not used */
-#define AST_DEVICE_NOT_INUSE 1
-/*! Device is in use */
-#define AST_DEVICE_INUSE 2
-/*! Device is busy */
-#define AST_DEVICE_BUSY 3
-/*! Device is invalid */
-#define AST_DEVICE_INVALID 4
-/*! Device is unavailable */
-#define AST_DEVICE_UNAVAILABLE 5
-/*! Device is ringing */
-#define AST_DEVICE_RINGING 6
-/*! Device is ringing *and* in use */
-#define AST_DEVICE_RINGINUSE 7
-/*! Device is on hold */
-#define AST_DEVICE_ONHOLD 8
-
-/*! \brief Devicestate watcher call back */
-typedef int (*ast_devstate_cb_type)(const char *dev, int state, void *data);
-
-/*! \brief Devicestate provider call back */
-typedef int (*ast_devstate_prov_cb_type)(const char *data);
-
-/*! \brief Convert device state to text string for output
- * \param devstate Current device state
- */
-const char *devstate2str(int devstate);
-
-/*! \brief Search the Channels by Name
- * \param device like a dialstring
- * Search the Device in active channels by compare the channelname against
- * the devicename. Compared are only the first chars to the first '-' char.
- * Returns an AST_DEVICE_UNKNOWN if no channel found or
- * AST_DEVICE_INUSE if a channel is found
- */
-int ast_parse_device_state(const char *device);
-
-/*! \brief Asks a channel for device state
- * \param device like a dialstring
- * Asks a channel for device state, data is normaly a number from dialstring
- * used by the low level module
- * Trys the channel devicestate callback if not supported search in the
- * active channels list for the device.
- * Returns an AST_DEVICE_??? state -1 on failure
- */
-int ast_device_state(const char *device);
-
-/*! \brief Tells Asterisk the State for Device is changed
- * \param fmt devicename like a dialstring with format parameters
- * Asterisk polls the new extensionstates and calls the registered
- * callbacks for the changed extensions
- * Returns 0 on success, -1 on failure
- */
-int ast_device_state_changed(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-
-/*! \brief Tells Asterisk the State for Device is changed
- * \param device devicename like a dialstring
- * Asterisk polls the new extensionstates and calls the registered
- * callbacks for the changed extensions
- * Returns 0 on success, -1 on failure
- */
-int ast_device_state_changed_literal(const char *device);
-
-/*! \brief Registers a device state change callback
- * \param callback Callback
- * \param data to pass to callback
- * The callback is called if the state for extension is changed
- * Return -1 on failure, ID on success
- */
-int ast_devstate_add(ast_devstate_cb_type callback, void *data);
-
-/*! \brief Unregisters a device state change callback
- * \param callback Callback
- * \param data to pass to callback
- * The callback is called if the state for extension is changed
- * Return -1 on failure, ID on success
- */
-void ast_devstate_del(ast_devstate_cb_type callback, void *data);
-
-/*! \brief Add device state provider
- * \param label to use in hint, like label:object
- * \param callback Callback
- * \retval -1 failure
- * \retval 0 success
- */
-int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback);
-
-/*! \brief Remove device state provider
- * \param label to use in hint, like label:object
- * \return nothing
- */
-void ast_devstate_prov_del(const char *label);
-
-int ast_device_state_engine_init(void);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_DEVICESTATE_H */
diff --git a/1.4/include/asterisk/dial.h b/1.4/include/asterisk/dial.h
deleted file mode 100644
index 525f425a0..000000000
--- a/1.4/include/asterisk/dial.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- * \brief Dialing API
- */
-
-#ifndef _ASTERISK_DIAL_H
-#define _ASTERISK_DIAL_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */
-struct ast_dial;
-
-/*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */
-struct ast_dial_channel;
-
-typedef void (*ast_dial_state_callback)(struct ast_dial *);
-
-/*! \brief List of options that are applicable either globally or per dialed channel */
-enum ast_dial_option {
- AST_DIAL_OPTION_RINGING, /*!< Always indicate ringing to caller */
- AST_DIAL_OPTION_ANSWER_EXEC, /*!< Execute application upon answer in async mode */
- AST_DIAL_OPTION_MAX, /*!< End terminator -- must always remain last */
-};
-
-/*! \brief List of return codes for dial run API calls */
-enum ast_dial_result {
- AST_DIAL_RESULT_INVALID, /*!< Invalid options were passed to run function */
- AST_DIAL_RESULT_FAILED, /*!< Attempts to dial failed before reaching critical state */
- AST_DIAL_RESULT_TRYING, /*!< Currently trying to dial */
- AST_DIAL_RESULT_RINGING, /*!< Dial is presently ringing */
- AST_DIAL_RESULT_PROGRESS, /*!< Dial is presently progressing */
- AST_DIAL_RESULT_PROCEEDING, /*!< Dial is presently proceeding */
- AST_DIAL_RESULT_ANSWERED, /*!< A channel was answered */
- AST_DIAL_RESULT_TIMEOUT, /*!< Timeout was tripped, nobody answered */
- AST_DIAL_RESULT_HANGUP, /*!< Caller hung up */
- AST_DIAL_RESULT_UNANSWERED, /*!< Nobody answered */
-};
-
-/*! \brief New dialing structure
- * \note Create a dialing structure
- * \return Returns a calloc'd ast_dial structure, NULL on failure
- */
-struct ast_dial *ast_dial_create(void);
-
-/*! \brief Append a channel
- * \note Appends a channel to a dialing structure
- * \return Returns channel reference number on success, -1 on failure
- */
-int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device);
-
-/*! \brief Execute dialing synchronously or asynchronously
- * \note Dials channels in a dial structure.
- * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
- */
-enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async);
-
-/*! \brief Return channel that answered
- * \note Returns the Asterisk channel that answered
- * \param dial Dialing structure
- */
-struct ast_channel *ast_dial_answered(struct ast_dial *dial);
-
-/*! \brief Return state of dial
- * \note Returns the state of the dial attempt
- * \param dial Dialing structure
- */
-enum ast_dial_result ast_dial_state(struct ast_dial *dial);
-
-/*! \brief Cancel async thread
- * \note Cancel a running async thread
- * \param dial Dialing structure
- */
-enum ast_dial_result ast_dial_join(struct ast_dial *dial);
-
-/*! \brief Hangup channels
- * \note Hangup all active channels
- * \param dial Dialing structure
- */
-void ast_dial_hangup(struct ast_dial *dial);
-
-/*! \brief Destroys a dialing structure
- * \note Cancels dialing and destroys (free's) the given ast_dial structure
- * \param dial Dialing structure to free
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_destroy(struct ast_dial *dial);
-
-/*! \brief Enables an option globally
- * \param dial Dial structure to enable option on
- * \param option Option to enable
- * \param data Data to pass to this option (not always needed)
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data);
-
-/*! \brief Enables an option per channel
- * \param dial Dial structure
- * \param num Channel number to enable option on
- * \param option Option to enable
- * \param data Data to pass to this option (not always needed)
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data);
-
-/*! \brief Disables an option globally
- * \param dial Dial structure to disable option on
- * \param option Option to disable
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option option);
-
-/*! \brief Disables an option per channel
- * \param dial Dial structure
- * \param num Channel number to disable option on
- * \param option Option to disable
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option);
-
-/*! \brief Set a callback for state changes
- * \param dial The dial structure to watch for state changes
- * \param callback the callback
- * \return nothing
- */
-void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_DIAL_H */
diff --git a/1.4/include/asterisk/dlfcn-compat.h b/1.4/include/asterisk/dlfcn-compat.h
deleted file mode 100644
index 2ce827a6a..000000000
--- a/1.4/include/asterisk/dlfcn-compat.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * 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.
- */
-
-/*
-Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
- Peter O'Gorman <ogorman@users.sourceforge.net>
-
-Portions may be copyright others, see the AUTHORS file included with this
-distribution.
-
-Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
-
-Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef _DLFCN_H_
-#define _DLFCN_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined (__GNUC__) && __GNUC__ > 3
-#define dl_restrict __restrict
-#else
-#define dl_restrict
-#endif
-/*
- * Structure filled in by dladdr().
- */
-
-typedef struct dl_info {
- const char *dli_fname; /* Pathname of shared object */
- void *dli_fbase; /* Base address of shared object */
- const char *dli_sname; /* Name of nearest symbol */
- void *dli_saddr; /* Address of nearest symbol */
-} Dl_info;
-
-extern void * dlopen(const char *path, int mode);
-extern void * dlsym(void * dl_restrict handle, const char * dl_restrict symbol);
-extern const char * dlerror(void);
-extern int dlclose(void * handle);
-extern int dladdr(const void * dl_restrict, Dl_info * dl_restrict);
-
-#define RTLD_LAZY 0x1
-#define RTLD_NOW 0x2
-#define RTLD_LOCAL 0x4
-#define RTLD_GLOBAL 0x8
-#define RTLD_NOLOAD 0x10
-#define RTLD_NODELETE 0x80
-
-/*
- * Special handle arguments for dlsym().
- */
-#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
-#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DLFCN_H_ */
diff --git a/1.4/include/asterisk/dns.h b/1.4/include/asterisk/dns.h
deleted file mode 100644
index 64cf68c10..000000000
--- a/1.4/include/asterisk/dns.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Written by Thorsten Lockert <tholo@trollphone.org>
- *
- * Funding provided by Troll Phone Networks AS
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- * \brief DNS support for Asterisk
- * \author Thorsten Lockert <tholo@trollphone.org>
- */
-
-#ifndef _ASTERISK_DNS_H
-#define _ASTERISK_DNS_H
-
-/*! \brief Perform DNS lookup (used by DNS, enum and SRV lookups)
- \param context
- \param dname Domain name to lookup (host, SRV domain, TXT record name)
- \param class Record Class (see "man res_search")
- \param type Record type (see "man res_search")
- \param callback Callback function for handling DNS result
- \note Asterisk DNS is synchronus at this time. This means that if your DNS
- services does not work, Asterisk may lock while waiting for response.
-*/
-int ast_search_dns(void *context, const char *dname, int class, int type,
- int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer));
-
-#endif /* _ASTERISK_DNS_H */
diff --git a/1.4/include/asterisk/dnsmgr.h b/1.4/include/asterisk/dnsmgr.h
deleted file mode 100644
index c9061dc42..000000000
--- a/1.4/include/asterisk/dnsmgr.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- * \brief Background DNS update manager
- */
-
-#ifndef _ASTERISK_DNSMGR_H
-#define _ASTERISK_DNSMGR_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <netinet/in.h>
-
-struct ast_dnsmgr_entry;
-
-struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct in_addr *result);
-
-void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry);
-
-int ast_dnsmgr_lookup(const char *name, struct in_addr *result, struct ast_dnsmgr_entry **dnsmgr);
-
-/*!
- * \brief Force a refresh of a dnsmgr entry
- *
- * \retval non-zero if the result is different than the previous result
- * \retval zero if the result is the same as the previous result
- */
-int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry);
-
-/*!
- * \brief Check is see if a dnsmgr entry has changed
- *
- * \retval non-zero if the dnsmgr entry has changed since the last call to
- * this function
- * \retval zero if the dnsmgr entry has not changed since the last call to
- * this function
- */
-int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif /* c_plusplus */
-
-#endif /* ASTERISK_DNSMGR_H */
diff --git a/1.4/include/asterisk/doxyref.h b/1.4/include/asterisk/doxyref.h
deleted file mode 100644
index 49e282816..000000000
--- a/1.4/include/asterisk/doxyref.h
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/* \file This file generates Doxygen pages from files in the /doc
- directory of the Asterisk source code tree
- */
-
-/* The following is for Doxygen Developer's documentation generated
- * by running "make progdocs" with doxygen installed on your
- * system.
- */
-/*! \page DevDoc Asterisk Developer's Documentation - appendices
- * \arg \ref CodeGuide : The must-read document for all developer's
- * \arg \ref AstAPI
- * \arg \ref Def_Channel : What's a channel, anyway?
- * \arg \ref channel_drivers : Existing channel drivers
- * \arg \ref AstDebug : Hints on debugging
- * \arg \ref AstAMI : The Call management socket API
- * \arg \ref AstARA : A generic data storage and retrieval API for Asterisk
- * \arg \ref AstDUNDi : A way to find phone services dynamically by using the DUNDi protocol
- * \arg \ref AstCDR
- * \arg \ref AstREADME
- * \arg \ref AstVar
- * \arg \ref AstVideo
- * \arg \ref AstENUM : The IETF way to redirect from phone numbers to VoIP calls
- * \arg \ref AstHTTP
- * \arg \ref AstSpeech
- * \arg \ref DataStores
- * \arg \ref ConfigFiles
- * \arg \ref SoundFiles included in the Asterisk distribution
- * \arg \ref AstCREDITS : A Thank You to contributors
- \n\n
- * \section weblinks Web sites
- * \arg \b Main: Asterisk Developer's website http://www.asterisk.org/developers/
- * \arg \b Bugs: The Issue tracker http://bugs.digium.com
- * \arg \b Lists: List server http://lists.digium.com
- * \arg \b Wiki: The Asterisk Wiki http://www.voip-info.org
- * \arg \b Docs: The Asterisk Documentation Project http://www.asteriskdocs.org
- * \arg \b Digium: The Asterisk company http://www.digium.com
- *
- */
-
-/*! \page CodeGuide Coding Guidelines
- * \section Coding Guidelines
- * This file is in the /doc directory in your Asterisk source tree.
- * Make sure to stay up to date with the latest guidelines.
- * \verbinclude CODING-GUIDELINES
- */
-
-/*! \page AstAPI Asterisk API
- * \section Asteriskapi Asterisk API
- * Some generic documents on the Asterisk architecture
- * \subsection model_txt Generic Model
- * \verbinclude model.txt
- * \subsection channel_txt Channels
- * \arg See \ref Def_Channel
- */
-
-/*! \page AstDebug Debugging
- * \section debug Debugging
- * \verbinclude backtrace.txt
- */
-
-/*! \page AstSpeech The Generic Speech Recognition API
- * \section debug The Generic Speech Recognition API
- * \verbinclude speechrec.txt
- */
-
-/*! \page DataStores Channel Data Stores
- * \section debug Channel Data Stores
- * \verbinclude datastores.txt
- */
-
-/*! \page AstAMI AMI - The Manager Interface
- * \section ami AMI - The manager Interface
- * \arg \link Config_ami Configuration file \endlink
- * \arg \ref manager.c
- * \verbinclude manager.txt
- */
-
-/*! \page AstARA ARA - The Asterisk Realtime Interface
- * \section realtime ARA - a generic API to storage and retrieval
- * Implemented in \ref config.c
- * Implemented in \ref pbx_realtime.c
- * \verbinclude realtime.txt
- * \verbinclude extconfig.txt
- */
-
-/*! \page AstDUNDi DUNDi
-DUNDi is a peer-to-peer system for locating Internet gateways to telephony services. Unlike traditional centralized services (such as the remarkably simple and concise ENUM standard), DUNDi is fully-distributed with no centralized authority whatsoever.
-
-DUNDi is not itself a Voice-over IP signaling or media protocol. Instead, it publishes routes which are in turn accessed via industry standard protocols such as IAX, SIP and H.323.
-
- \par References
- \arg DUNDi is documented at http://www.dundi.com
- \arg Implemented in \ref pbx_dundi.c and \ref dundi-parser.c
- \arg Configuration in \link Config_dun dundi.conf \endlink
- */
-
-/*! \page AstCDR CDR - Call Data Records and billing
- * \section cdr Call Data Records
- * \par See also
- * \arg \ref cdr.c
- * \arg \ref cdr_drivers
- * \arg \ref Config_cdr CDR configuration files
- *
- * \verbinclude cdrdriver.txt
- */
-
-/*! \page AstREADME README - the general administrator introduction
- * \verbinclude README
- */
-
-/*! \page AstCREDITS CREDITS
- * \verbinclude CREDITS
- */
-
-/*! \page AstVideo Video support in Asterisk
- * \section sectAstVideo Video support in Asterisk
- * \verbinclude video.txt
- */
-
-/*! \page AstVar Global channel variables
- * \section globchan Global Channel Variables
- * \verbinclude channelvariables.txt
- */
-
-/*! \page AstENUM ENUM
- * \section enumreadme ENUM
- * \arg Configuration: \ref Config_enum
- * \arg \ref enum.c
- * \arg \ref func_enum.c
- *
- * \verbinclude enum.txt
- */
-
-/*! \page ConfigFiles Configuration files
- * \section config Main configuration files
- * \arg \link Config_ast asterisk.conf - the main configuration file \endlink
- * \arg \link Config_ext extensions.conf - The Dial Plan \endlink
- * \arg \link Config_mod modules.conf - which modules to load and not to load \endlink
- * \arg \link Config_fea features.conf - call features (transfer, parking, etc) \endlink
- * \section chanconf Channel configuration files
- * \arg \link Config_iax IAX2 configuration \endlink
- * \arg \link Config_sip SIP configuration \endlink
- * \arg \link Config_mgcp MGCP configuration \endlink
- * \arg \link Config_rtp RTP configuration \endlink
- * \arg \link Config_zap Zaptel configuration \endlink
- * \arg \link Config_oss OSS (sound card) configuration \endlink
- * \arg \link Config_alsa ALSA (sound card) configuration \endlink
- * \arg \link Config_agent Agent (proxy channel) configuration \endlink
- * \arg \link Config_misdn MISDN Experimental ISDN BRI channel configuration \endlink
- * \arg \link Config_h323 H.323 configuration \endlink
- * \section appconf Application configuration files
- * \arg \link Config_mm Meetme (conference bridge) configuration \endlink
- * \arg \link Config_qu Queue system configuration \endlink
- * \arg \link Config_vm Voicemail configuration \endlink
- * \arg \link Config_followme Followme configuration \endlink
- * \section cdrconf CDR configuration files
- * \arg \link Config_cdr CDR configuration \endlink
- * \arg \link cdr_custom Custom CDR driver configuration \endlink
- * \arg \link cdr_ami Manager CDR driver configuration \endlink
- * \arg \link cdr_odbc ODBC CDR driver configuration \endlink
- * \arg \link cdr_pgsql PostgreSQL CDR driver configuration \endlink
- * \arg \link cdr_sqlite SQLite CDR driver configuration \endlink
- * \arg \link cdr_tds FreeTDS CDR driver configuration (Microsoft SQL Server) \endlink
- * \section miscconf Miscellenaous configuration files
- * \arg \link Config_adsi ADSI configuration \endlink
- * \arg \link Config_ami AMI - Manager configuration \endlink
- * \arg \link Config_ara Realtime configuration \endlink
- * \arg \link Config_codec Codec configuration \endlink
- * \arg \link Config_dun DUNDi configuration \endlink
- * \arg \link Config_enum ENUM configuration \endlink
- * \arg \link Config_moh Music on Hold configuration \endlink
- * \arg \link Config_vm Voicemail configuration \endlink
- */
-
-/*! \page Config_ast Asterisk.conf
- * \verbinclude asterisk-conf.txt
- */
-/*! \page Config_mod Modules configuration
- * All res_ resource modules are loaded with globals on, which means
- * that non-static functions are callable from other modules.
- *
- * If you want your non res_* module to export functions to other modules
- * you have to include it in the [global] section.
- * \verbinclude modules.conf.sample
- */
-
-/*! \page Config_fea Call features configuration
- * \par See also
- * \arg \ref res_features.c : Call feature implementation
- * \section featconf features.conf
- * \verbinclude features.conf.sample
- */
-
-/*! \page Config_followme followme.conf
- * \section followmeconf Followme.conf
- * - See app_followme.c
- * \verbinclude followme.conf.sample
- */
-
-/*! \page Config_ext Extensions.conf - the Dial Plan
- * \section dialplan Extensions.conf
- * \verbinclude extensions.conf.sample
- */
-
-/*! \page Config_iax IAX2 configuration
- * IAX2 is implemented in \ref chan_iax2.c
- * \arg \link Config_iax iax.conf Configuration file example \endlink
- * \section iaxreadme IAX readme file
- * \verbinclude iax.txt
- * \section Config_iax IAX Configuration example
- * \verbinclude iax.conf.sample
- * \section iaxjitter IAX Jitterbuffer information
- * \verbinclude jitterbuffer.txt
- */
-
-/*! \page Config_iax IAX configuration
- * \arg Implemented in \ref chan_iax2.c
- * \section iaxconf iax.conf
- * \verbinclude iax.conf.sample
- */
-
-/*! \page Config_sip SIP configuration
- * Also see \ref Config_rtp RTP configuration
- * \arg Implemented in \ref chan_sip.c
- * \section sipconf sip.conf
- * \verbinclude sip.conf.sample
- *
- * \arg \b Back \ref chanconf
- */
-
-/*! \page Config_mgcp MGCP configuration
- * Also see \ref Config_rtp RTP configuration
- * \arg Implemented in \ref chan_mgcp.c
- * \section mgcpconf mgcp.conf
- * \verbinclude mgcp.conf.sample
- */
-
-/*! \page README_misdn MISDN documentation
- * \arg See \ref Config_misdn
- * \section mISDN configuration
- * \verbinclude misdn.txt
- */
-
-/*! \page Config_misdn MISDN configuration
- * \arg Implemented in \ref chan_misdn.c
- * \arg \ref README_misdn
- * \arg See the mISDN home page: http://www.isdn4linux.de/mISDN/
- * \section misdnconf misdn.conf
- * \verbinclude misdn.conf.sample
- */
-
-/*! \page Config_vm VoiceMail configuration
- * \section vmconf voicemail.conf
- * \arg Implemented in \ref app_voicemail.c
- * \verbinclude voicemail.conf.sample
- */
-
-/*! \page Config_zap Zaptel configuration
- * \section zapconf zapata.conf
- * \arg Implemented in \ref chan_zap.c
- * \verbinclude zapata.conf.sample
- */
-
-/*! \page Config_h323 H.323 channel driver information
- * This is the configuration of the H.323 channel driver within the Asterisk
- * distribution. There's another one, called OH323, in asterisk-addons
- * \arg Implemented in \ref chan_h323.c
- * \section h323conf h323.conf
- * \ref chan_h323.c
- * \verbinclude h323.txt
- */
-
-/*! \page Config_oss OSS configuration
- * \section ossconf oss.conf
- * \arg Implemented in \ref chan_oss.c
- * \verbinclude oss.conf.sample
- */
-
-/*! \page Config_alsa ALSA configuration
- * \section alsaconf alsa.conf
- * \arg Implemented in \ref chan_alsa.c
- * \verbinclude alsa.conf.sample
- */
-
-/*! \page Config_agent Agent configuration
- * \section agentconf agents.conf
- * The agent channel is a proxy channel for queues
- * \arg Implemented in \ref chan_agent.c
- * \verbinclude agents.conf.sample
- */
-
-/*! \page Config_rtp RTP configuration
- * \arg Implemented in \ref rtp.c
- * Used in \ref chan_sip.c and \ref chan_mgcp.c (and various H.323 channels)
- * \section rtpconf rtp.conf
- * \verbinclude rtp.conf.sample
- */
-
-/*! \page Config_dun DUNDi Configuration
- * \arg See also \ref AstDUNDi
- * \section dundiconf dundi.conf
- * \verbinclude dundi.conf.sample
- */
-
-/*! \page Config_enum ENUM Configuration
- * \section enumconf enum.conf
- * \arg See also \ref enumreadme
- * \arg Implemented in \ref func_enum.c and \ref enum.c
- * \verbinclude enum.conf.sample
- */
-
-/*! \page cdr_custom Custom CDR Configuration
- * \par See also
- * \arg \ref cdrconf
- * \arg \ref cdr_custom.c
- * \verbinclude cdr_custom.conf.sample
- */
-
-/*! \page cdr_ami Manager CDR driver configuration
- * \par See also
- * \arg \ref cdrconf
- * \arg \ref AstAMI
- * \arg \ref cdr_manager.c
- * \verbinclude cdr_manager.conf.sample
- */
-
-/*! \page cdr_odbc ODBC CDR driver configuration
- * \arg See also \ref cdrconf
- * \arg \ref cdr_odbc.c
- * \verbinclude cdr_odbc.conf.sample
- * See also:
- * \arg http://www.unixodbc.org
- */
-
-/*! \page cdr_pgsql PostgreSQL CDR driver configuration
- * \arg See also \ref cdrconf
- * \arg \ref cdr_pgsql.c
- * See also:
- * \arg http://www.postgresql.org
- * \verbinclude cdr_pgsql.conf.sample
- */
-
-/*! \page cdr_sqlite SQLite CDR driver configuration
- * \arg See also \ref cdrconf
- * \arg \ref cdr_sqlite.c
- * See also:
- * \arg http://www.sqlite.org
- */
-
-/*! \page cdr_tds FreeTDS CDR driver configuration
- * \arg See also \ref cdrconf
- * See also:
- * \arg http://www.freetds.org
- * \verbinclude cdr_tds.conf.sample
- */
-
-/*! \page Config_cdr CDR configuration
- * \par See also
- * \arg \ref cdr_drivers
- * \arg \link Config_cdr CDR configuration \endlink
- * \arg \link cdr_custom Custom CDR driver configuration \endlink
- * \arg \link cdr_ami Manager CDR driver configuration \endlink
- * \arg \link cdr_odbc ODBC CDR driver configuration \endlink
- * \arg \link cdr_pgsql PostgreSQL CDR driver configuration \endlink
- * \arg \link cdr_sqlite SQLite CDR driver configuration \endlink
- * \arg \link cdr_tds FreeTDS CDR driver configuration (Microsoft SQL Server) \endlink
- * \verbinclude cdr.conf.sample
- */
-
-/*! \page Config_moh Music on Hold Configuration
- * \arg Implemented in \ref res_musiconhold.c
- * \section mohconf musiconhold.conf
- * \verbinclude musiconhold.conf.sample
- */
-
-/*! \page Config_adsi ADSI Configuration
- * \section adsiconf adsi.conf
- * \verbinclude adsi.conf.sample
- */
-
-/*! \page Config_codec CODEC Configuration
- * \section codecsconf codecs.conf
- * \verbinclude codecs.conf.sample
- */
-
-/*! \page Config_ara REALTIME Configuration
- * \arg See also: \arg \link AstARA \endlink
- * \section extconf extconfig.conf
- * \verbinclude extconfig.conf.sample
- */
-
-/*! \page Config_ami AMI configuration
- * \arg See also: \arg \link AstAMI \endlink
- * \section amiconf manager.conf
- * \verbinclude manager.conf.sample
- */
-
-/*! \page Config_qu ACD - Queue system configuration
- * \arg Implemented in \ref app_queue.c
- * \section quconf queues.conf
- * \verbinclude queues.conf.sample
- */
-
-/*! \page Config_mm Meetme - The conference bridge configuration
- * \arg Implemented in \ref app_meetme.c
- * \section mmconf meetme.conf
- * \verbinclude meetme.conf.sample
- */
-
-/*! \page SoundFiles Sound files
- * \section SecSound Asterisk Sound files
- * Asterisk includes a large number of sound files. Many of these
- * are used by applications and demo scripts within asterisk.
- *
- * Additional sound files are available in the asterisk-addons
- * repository on svn.digium.com
- */
-
-/*! \addtogroup cdr_drivers Module: CDR Drivers
- * \section CDR_generic Asterisk CDR Drivers
- * \brief CDR drivers are loaded dynamically (see \ref Config_mod "Modules Configuration"). Each loaded CDR driver produce a billing record for each call.
- * \arg \ref Config_cdr "CDR Configuration"
- */
-
-
-/*! \addtogroup channel_drivers Module: Asterisk Channel Drivers
- * \section channel_generic Asterisk Channel Drivers
- * \brief Channel drivers are loaded dynamically (see \ref Config_mod "Modules Configuration").
- */
-
-/*! \addtogroup applications Module: Dial plan applications
- * \section app_generic Asterisk Dial Plan Applications
- * \brief Applications support the dialplan. They register dynamically with \ref ast_register_application() and unregister with ast_unregister_application()
- * \par See also
- * \arg \ref functions
- *
- */
-
-/*! \addtogroup functions Module: Dial plan functions
- * \section func_generic Asterisk Dial Plan Functions
- * \brief Functions support the dialplan. They do not change any property of a channel
- * or touch a channel in any way.
- * \par See also
- * \arg \ref applications
- *
- */
-
-/*! \addtogroup codecs Module: Codecs
- * \section codec_generic Asterisk Codec Modules
- * Codecs are referenced in configuration files by name
- * \par See also
- * \arg \ref formats
- *
- */
-
-/*! \addtogroup formats Module: Media File Formats
- * \section codec_generic Asterisk Format drivers
- * Formats are modules that read or write media files to disk.
- * \par See also
- * \arg \ref codecs
- */
-
-/*! \page AstHTTP AMI over HTTP support
- * The http.c file includes support for manager transactions over
- * http.
- * \section ami AMI - The manager Interface
- * \arg \link Config_ami Configuration file \endlink
- * \verbinclude ajam.txt
- */
-
diff --git a/1.4/include/asterisk/dsp.h b/1.4/include/asterisk/dsp.h
deleted file mode 100644
index ccc484c14..000000000
--- a/1.4/include/asterisk/dsp.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Convenient Signal Processing routines
- */
-
-#ifndef _ASTERISK_DSP_H
-#define _ASTERISK_DSP_H
-
-#define DSP_FEATURE_SILENCE_SUPPRESS (1 << 0)
-#define DSP_FEATURE_BUSY_DETECT (1 << 1)
-#define DSP_FEATURE_DTMF_DETECT (1 << 3)
-#define DSP_FEATURE_FAX_DETECT (1 << 4)
-
-#define DSP_DIGITMODE_DTMF 0 /* Detect DTMF digits */
-#define DSP_DIGITMODE_MF 1 /* Detect MF digits */
-
-#define DSP_DIGITMODE_NOQUELCH (1 << 8) /* Do not quelch DTMF from in-band */
-#define DSP_DIGITMODE_MUTECONF (1 << 9) /* Mute conference */
-#define DSP_DIGITMODE_MUTEMAX (1 << 10) /* Delay audio by a frame to try to extra quelch */
-#define DSP_DIGITMODE_RELAXDTMF (1 << 11) /* "Radio" mode (relaxed DTMF) */
-
-#define DSP_PROGRESS_TALK (1 << 16) /* Enable talk detection */
-#define DSP_PROGRESS_RINGING (1 << 17) /* Enable calling tone detection */
-#define DSP_PROGRESS_BUSY (1 << 18) /* Enable busy tone detection */
-#define DSP_PROGRESS_CONGESTION (1 << 19) /* Enable congestion tone detection */
-#define DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)
-
-#define DSP_TONE_STATE_SILENCE 0
-#define DSP_TONE_STATE_RINGING 1
-#define DSP_TONE_STATE_DIALTONE 2
-#define DSP_TONE_STATE_TALKING 3
-#define DSP_TONE_STATE_BUSY 4
-#define DSP_TONE_STATE_SPECIAL1 5
-#define DSP_TONE_STATE_SPECIAL2 6
-#define DSP_TONE_STATE_SPECIAL3 7
-#define DSP_TONE_STATE_HUNGUP 8
-
-struct ast_dsp;
-
-struct ast_dsp *ast_dsp_new(void);
-void ast_dsp_free(struct ast_dsp *dsp);
-
-/*! \brief Set threshold value for silence */
-void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold);
-
-/*! \brief Set number of required cadences for busy */
-void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences);
-
-/*! \brief Set expected lengths of the busy tone */
-void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength);
-
-/*! \brief Scans for progress indication in audio */
-int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf);
-
-/*! \brief Set zone for doing progress detection */
-int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone);
-
-/*! \brief Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on
- busies, and call progress, all dependent upon which features are enabled */
-struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf);
-
-/*! \brief Return non-zero if this is silence. Updates "totalsilence" with the total
- number of seconds of silence */
-int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence);
-
-/*! \brief Return non-zero if historically this should be a busy, request that
- ast_dsp_silence has already been called */
-int ast_dsp_busydetect(struct ast_dsp *dsp);
-
-/*! \brief Return non-zero if DTMF hit was found */
-int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *f);
-
-/*! \brief Reset total silence count */
-void ast_dsp_reset(struct ast_dsp *dsp);
-
-/*! \brief Reset DTMF detector */
-void ast_dsp_digitreset(struct ast_dsp *dsp);
-
-/*! \brief Select feature set */
-void ast_dsp_set_features(struct ast_dsp *dsp, int features);
-
-/*! \brief Get pending DTMF/MF digits */
-int ast_dsp_getdigits(struct ast_dsp *dsp, char *buf, int max);
-
-/*! \brief Set digit mode */
-int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode);
-
-/*! \brief Get tstate (Tone State) */
-int ast_dsp_get_tstate(struct ast_dsp *dsp);
-
-/*! \brief Get tcount (Threshold counter) */
-int ast_dsp_get_tcount(struct ast_dsp *dsp);
-
-/*!
- * \brief Hint that a frame from a dsp was freed
- *
- * This is called from ast_frame_free if AST_FRFLAG_FROM_DSP is set. This occurs
- * because it is possible for the dsp to be freed while someone still holds a reference
- * to the frame that is in that dsp. This has been known to happen when the dsp on a Zap
- * channel detects a busy signal. The channel is hung up, and the application that read the
- * frame to begin with still has a reference to the frame.
- *
- * \return nothing
- */
-void ast_dsp_frame_freed(struct ast_frame *fr);
-
-#endif /* _ASTERISK_DSP_H */
diff --git a/1.4/include/asterisk/dundi.h b/1.4/include/asterisk/dundi.h
deleted file mode 100644
index 9290536d6..000000000
--- a/1.4/include/asterisk/dundi.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Distributed Universal Number Discovery (DUNDi)
- * See also \ref AstDUNDi
- */
-
-#ifndef _ASTERISK_DUNDI_H
-#define _ASTERISK_DUNDI_H
-
-#include "asterisk/channel.h"
-
-#define DUNDI_PORT 4520
-
-/*!\brief A DUNDi Entity ID is essentially a MAC address, brief and unique */
-struct _dundi_eid {
- unsigned char eid[6];
-} __attribute__ ((__packed__));
-
-typedef struct _dundi_eid dundi_eid;
-
-struct dundi_hdr {
- unsigned short strans; /*!< Source transaction */
- unsigned short dtrans; /*!< Destination transaction */
- unsigned char iseqno; /*!< Next expected incoming sequence number */
- unsigned char oseqno; /*!< Outgoing sequence number */
- unsigned char cmdresp; /*!< Command / Response */
- unsigned char cmdflags; /*!< Command / Response specific flags*/
- unsigned char ies[0];
-} __attribute__ ((__packed__));
-
-struct dundi_ie_hdr {
- unsigned char ie;
- unsigned char len;
- unsigned char iedata[0];
-} __attribute__ ((__packed__));
-
-#define DUNDI_FLAG_RETRANS (1 << 16) /*!< Applies to dtrans */
-#define DUNDI_FLAG_RESERVED (1 << 16) /*!< Applies to strans */
-
-#define DUNDI_PROTO_NONE 0 /*!< No answer yet */
-#define DUNDI_PROTO_IAX 1 /*!< IAX version 2 */
-#define DUNDI_PROTO_SIP 2 /*!< Session Initiation Protocol */
-#define DUNDI_PROTO_H323 3 /*!< ITU H.323 */
-
-#define DUNDI_FLAG_NONEXISTENT (0) /*!< Isn't and can't be a valid number */
-#define DUNDI_FLAG_EXISTS (1 << 0) /*!< Is a valid number */
-#define DUNDI_FLAG_MATCHMORE (1 << 1) /*!< Might be valid if you add more digits */
-#define DUNDI_FLAG_CANMATCH (1 << 2) /*!< Might be a match */
-#define DUNDI_FLAG_IGNOREPAT (1 << 3) /*!< Keep dialtone */
-#define DUNDI_FLAG_RESIDENTIAL (1 << 4) /*!< Destination known to be residential */
-#define DUNDI_FLAG_COMMERCIAL (1 << 5) /*!< Destination known to be commercial */
-#define DUNDI_FLAG_MOBILE (1 << 6) /*!< Destination known to be cellular/mobile */
-#define DUNDI_FLAG_NOUNSOLICITED (1 << 7) /*!< No unsolicited calls of any kind through this route */
-#define DUNDI_FLAG_NOCOMUNSOLICIT (1 << 8) /*!< No commercial unsolicited calls through this route */
-
-#define DUNDI_HINT_NONE (0)
-#define DUNDI_HINT_TTL_EXPIRED (1 << 0) /*!< TTL Expired */
-#define DUNDI_HINT_DONT_ASK (1 << 1) /*!< Don't ask for anything beginning with data */
-#define DUNDI_HINT_UNAFFECTED (1 << 2) /*!< Answer not affected by entity list */
-
-struct dundi_encblock { /*!< AES-128 encrypted block */
- unsigned char iv[16]; /*!< Initialization vector of random data */
- unsigned char encdata[0]; /*!< Encrypted / compressed data */
-} __attribute__ ((__packed__));
-
-struct dundi_answer {
- dundi_eid eid; /*!< Original source of answer */
- unsigned char protocol; /*!< Protocol (DUNDI_PROTO_*) */
- unsigned short flags; /*!< Flags relating to answer */
- unsigned short weight; /*!< Weight of answers */
- unsigned char data[0]; /*!< Protocol specific URI */
-} __attribute__ ((__packed__));
-
-struct dundi_hint {
- unsigned short flags; /*!< Flags relating to answer */
- unsigned char data[0]; /*!< For data for hint */
-} __attribute__ ((__packed__));
-
-#define DUNDI_CAUSE_SUCCESS 0 /*!< Success */
-#define DUNDI_CAUSE_GENERAL 1 /*!< General unspecified failure */
-#define DUNDI_CAUSE_DYNAMIC 2 /*!< Requested entity is dynamic */
-#define DUNDI_CAUSE_NOAUTH 3 /*!< No or improper authorization */
-#define DUNDI_CAUSE_DUPLICATE 4 /*!< Duplicate request */
-#define DUNDI_CAUSE_TTL_EXPIRED 5 /*!< Expired TTL */
-#define DUNDI_CAUSE_NEEDKEY 6 /*!< Need new session key to decode */
-#define DUNDI_CAUSE_BADENCRYPT 7 /*!< Badly encrypted data */
-
-struct dundi_cause {
- unsigned char causecode; /*!< Numerical cause (DUNDI_CAUSE_*) */
- char desc[0]; /*!< Textual description */
-} __attribute__ ((__packed__));
-
-struct dundi_peer_status {
- unsigned int flags;
- unsigned short netlag;
- unsigned short querylag;
- dundi_eid peereid;
-} __attribute__ ((__packed__));
-
-#define DUNDI_PEER_PRIMARY (1 << 0)
-#define DUNDI_PEER_SECONDARY (1 << 1)
-#define DUNDI_PEER_UNAVAILABLE (1 << 2)
-#define DUNDI_PEER_REGISTERED (1 << 3)
-#define DUNDI_PEER_MOD_OUTBOUND (1 << 4)
-#define DUNDI_PEER_MOD_INBOUND (1 << 5)
-#define DUNDI_PEER_PCMOD_OUTBOUND (1 << 6)
-#define DUNDI_PEER_PCMOD_INBOUND (1 << 7)
-
-#define DUNDI_COMMAND_FINAL (0x80) /*!< Or'd with other flags */
-
-#define DUNDI_COMMAND_ACK (0 | 0x40) /*!< Ack a message */
-#define DUNDI_COMMAND_DPDISCOVER 1 /*!< Request discovery */
-#define DUNDI_COMMAND_DPRESPONSE (2 | 0x40) /*!< Respond to a discovery request */
-#define DUNDI_COMMAND_EIDQUERY 3 /*!< Request information for a peer */
-#define DUNDI_COMMAND_EIDRESPONSE (4 | 0x40) /*!< Response to a peer query */
-#define DUNDI_COMMAND_PRECACHERQ 5 /*!< Pre-cache Request */
-#define DUNDI_COMMAND_PRECACHERP (6 | 0x40) /*!< Pre-cache Response */
-#define DUNDI_COMMAND_INVALID (7 | 0x40) /*!< Invalid dialog state (does not require ack) */
-#define DUNDI_COMMAND_UNKNOWN (8 | 0x40) /*!< Unknown command */
-#define DUNDI_COMMAND_NULL 9 /*!< No-op */
-#define DUNDI_COMMAND_REGREQ (10) /*!< Register Request */
-#define DUNDI_COMMAND_REGRESPONSE (11 | 0x40) /*!< Register Response */
-#define DUNDI_COMMAND_CANCEL (12) /*!< Cancel transaction entirely */
-#define DUNDI_COMMAND_ENCRYPT (13) /*!< Send an encrypted message */
-#define DUNDI_COMMAND_ENCREJ (14 | 0x40) /*!< Reject an encrypted message */
-
-#define DUNDI_COMMAND_STATUS 15 /*!< Status command */
-
-/*
- * Remember that some information elements may occur
- * more than one time within a message
- */
-
-#define DUNDI_IE_EID 1 /*!< Entity identifier (dundi_eid) */
-#define DUNDI_IE_CALLED_CONTEXT 2 /*!< DUNDi Context (string) */
-#define DUNDI_IE_CALLED_NUMBER 3 /*!< Number of equivalent (string) */
-#define DUNDI_IE_EID_DIRECT 4 /*!< Entity identifier (dundi_eid), direct connect */
-#define DUNDI_IE_ANSWER 5 /*!< An answer (struct dundi_answer) */
-#define DUNDI_IE_TTL 6 /*!< Max TTL for this request / Remaining TTL for the response (short)*/
-#define DUNDI_IE_VERSION 10 /*!< DUNDi version (should be 1) (short) */
-#define DUNDI_IE_EXPIRATION 11 /*!< Recommended expiration (short) */
-#define DUNDI_IE_UNKNOWN 12 /*!< Unknown command (byte) */
-#define DUNDI_IE_CAUSE 14 /*!< Success or cause of failure */
-#define DUNDI_IE_REQEID 15 /*!< EID being requested for EIDQUERY*/
-#define DUNDI_IE_ENCDATA 16 /*!< AES-128 encrypted data */
-#define DUNDI_IE_SHAREDKEY 17 /*!< RSA encrypted AES-128 key */
-#define DUNDI_IE_SIGNATURE 18 /*!< RSA Signature of encrypted shared key */
-#define DUNDI_IE_KEYCRC32 19 /*!< CRC32 of encrypted key (int) */
-#define DUNDI_IE_HINT 20 /*!< Answer hints (struct ast_hint) */
-
-#define DUNDI_IE_DEPARTMENT 21 /*!< Department, for EIDQUERY (string) */
-#define DUNDI_IE_ORGANIZATION 22 /*!< Organization, for EIDQUERY (string) */
-#define DUNDI_IE_LOCALITY 23 /*!< City/Locality, for EIDQUERY (string) */
-#define DUNDI_IE_STATE_PROV 24 /*!< State/Province, for EIDQUERY (string) */
-#define DUNDI_IE_COUNTRY 25 /*!< Country, for EIDQUERY (string) */
-#define DUNDI_IE_EMAIL 26 /*!< E-mail addy, for EIDQUERY (string) */
-#define DUNDI_IE_PHONE 27 /*!< Contact Phone, for EIDQUERY (string) */
-#define DUNDI_IE_IPADDR 28 /*!< IP Address, for EIDQUERY (string) */
-#define DUNDI_IE_CACHEBYPASS 29 /*!< Bypass cache (empty) */
-
-#define DUNDI_IE_PEERSTATUS 30 /*!< Peer/peer status (struct dundi_peer_status) */
-
-#define DUNDI_FLUFF_TIME 2000 /*!< Amount of time for answer */
-#define DUNDI_TTL_TIME 200 /*!< Incremental average time */
-
-#define DUNDI_DEFAULT_RETRANS 5
-#define DUNDI_DEFAULT_RETRANS_TIMER 1000
-#define DUNDI_DEFAULT_TTL 120 /*!< In seconds/hops like TTL */
-#define DUNDI_DEFAULT_VERSION 1
-#define DUNDI_DEFAULT_CACHE_TIME 3600 /*!< In seconds */
-#define DUNDI_DEFAULT_KEY_EXPIRE 3600 /*!< Life of shared key In seconds */
-#define DUNDI_DEF_EMPTY_CACHE_TIME 60 /*!< In seconds, cache of empty answer */
-#define DUNDI_WINDOW 1 /*!< Max 1 message in window */
-
-#define DEFAULT_MAXMS 2000
-
-struct dundi_result {
- unsigned int flags;
- int weight;
- int expiration;
- int techint;
- dundi_eid eid;
- char eid_str[20];
- char tech[10];
- char dest[256];
-};
-
-struct dundi_entity_info {
- char country[80];
- char stateprov[80];
- char locality[80];
- char org[80];
- char orgunit[80];
- char email[80];
- char phone[80];
- char ipaddr[80];
-};
-
-/*! \brief Lookup the given number in the given dundi context (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified.
- returns the number of results found or -1 on a hangup of teh channel. */
-int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int nocache);
-
-/*! \brief Retrieve information on a specific EID */
-int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid);
-
-/*! \brief Pre-cache to push upstream peers */
-int dundi_precache(const char *dcontext, const char *number);
-
-#endif /* _ASTERISK_DUNDI_H */
diff --git a/1.4/include/asterisk/endian.h b/1.4/include/asterisk/endian.h
deleted file mode 100644
index 98bff15a2..000000000
--- a/1.4/include/asterisk/endian.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Asterisk architecture endianess compatibility definitions
- */
-
-#ifndef _ASTERISK_ENDIAN_H
-#define _ASTERISK_ENDIAN_H
-
-/*
- * Autodetect system endianess
- */
-
-#include "asterisk/compat.h"
-
-#ifndef __BYTE_ORDER
-#ifdef __linux__
-#include <endian.h>
-#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
-#include <machine/endian.h>
-#define __BYTE_ORDER BYTE_ORDER
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#else
-#ifdef __LITTLE_ENDIAN__
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif /* __LITTLE_ENDIAN */
-
-#if defined(i386) || defined(__i386__)
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif /* defined i386 */
-
-#if defined(sun) && defined(unix) && defined(sparc)
-#define __BYTE_ORDER __BIG_ENDIAN
-#endif /* sun unix sparc */
-
-#endif /* linux */
-
-#endif /* __BYTE_ORDER */
-
-#ifndef __BYTE_ORDER
-#error Need to know endianess
-#endif /* __BYTE_ORDER */
-
-#endif /* _ASTERISK_ENDIAN_H */
-
diff --git a/1.4/include/asterisk/enum.h b/1.4/include/asterisk/enum.h
deleted file mode 100644
index c2fe3b592..000000000
--- a/1.4/include/asterisk/enum.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file enum.h
- \brief DNS and ENUM functions
-*/
-
-#ifndef _ASTERISK_ENUM_H
-#define _ASTERISK_ENUM_H
-
-#include "asterisk/channel.h"
-
-/*! \brief Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup
- \param chan Channel
- \param number E164 number with or without the leading +
- \param location Number returned (or SIP uri)
- \param maxloc Max length
- \param technology Technology (from url scheme in response)
- You can set it to get particular answer RR, if there are many techs in DNS response, example: "sip"
- If you need any record, then set it to empty string
- \param maxtech Max length
- \param suffix Zone suffix (if is NULL then use enum.conf 'search' variable)
- \param options Options ('c' to count number of NAPTR RR)
- \param record The position of required RR in the answer list
-*/
-int ast_get_enum(struct ast_channel *chan, const char *number, char *location, int maxloc, char *technology,
- int maxtech, char* suffix, char* options, unsigned int record);
-
-/*! \brief Lookup DNS TXT record (used by app TXTCIDnum
- \param chan Channel
- \param number E164 number with or without the leading +
- \param location Number returned (or SIP uri)
- \param maxloc Max length of number
- \param technology Technology (not used in TXT records)
- \param maxtech Max length
- \param txt Text string (return value)
- \param maxtxt Max length of "txt"
-*/
-int ast_get_txt(struct ast_channel *chan, const char *number, char *location, int maxloc, char *technology, int maxtech, char *txt, int maxtxt);
-
-int ast_enum_init(void);
-int ast_enum_reload(void);
-
-#endif /* _ASTERISK_ENUM_H */
diff --git a/1.4/include/asterisk/features.h b/1.4/include/asterisk/features.h
deleted file mode 100644
index 7072406ab..000000000
--- a/1.4/include/asterisk/features.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Call Parking and Pickup API
- * Includes code and algorithms from the Zapata library.
- */
-
-#ifndef _AST_FEATURES_H
-#define _AST_FEATURES_H
-
-#define FEATURE_MAX_LEN 11
-#define FEATURE_APP_LEN 64
-#define FEATURE_APP_ARGS_LEN 256
-#define FEATURE_SNAME_LEN 32
-#define FEATURE_EXTEN_LEN 32
-#define FEATURE_MOH_LEN 80 /* same as MAX_MUSICCLASS from channel.h */
-
-/*! \brief main call feature structure */
-struct ast_call_feature {
- int feature_mask;
- char *fname;
- char sname[FEATURE_SNAME_LEN];
- char exten[FEATURE_MAX_LEN];
- char default_exten[FEATURE_MAX_LEN];
- int (*operation)(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data);
- unsigned int flags;
- char app[FEATURE_APP_LEN];
- char app_args[FEATURE_APP_ARGS_LEN];
- char moh_class[FEATURE_MOH_LEN];
- AST_LIST_ENTRY(ast_call_feature) feature_entry;
-};
-
-
-
-/*! \brief Park a call and read back parked location
- * \param chan the channel to actually be parked
- \param host the channel which will have the parked location read to
- Park the channel chan, and read back the parked location to the
- host. If the call is not picked up within a specified period of
- time, then the call will return to the last step that it was in
- (in terms of exten, priority and context)
- \param timeout is a timeout in milliseconds
- \param extout is a parameter to an int that will hold the parked location, or NULL if you want
-*/
-int ast_park_call(struct ast_channel *chan, struct ast_channel *host, int timeout, int *extout);
-
-/*! \brief Park a call via a masqueraded channel
- * \param rchan the real channel to be parked
- \param host the channel to have the parking read to
- Masquerade the channel rchan into a new, empty channel which is then
- parked with ast_park_call
- \param timeout is a timeout in milliseconds
- \param extout is a parameter to an int that will hold the parked location, or NULL if you want
-*/
-int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *host, int timeout, int *extout);
-
-/*! \brief Determine system parking extension
- * Returns the call parking extension for drivers that provide special
- call parking help */
-char *ast_parking_ext(void);
-
-/*! \brief Determine system call pickup extension */
-char *ast_pickup_ext(void);
-
-/*! \brief Bridge a call, optionally allowing redirection */
-int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
-
-/*! \brief Pickup a call */
-int ast_pickup_call(struct ast_channel *chan);
-
-/*! \brief register new feature into feature_set
- \param feature an ast_call_feature object which contains a keysequence
- and a callback function which is called when this keysequence is pressed
- during a call. */
-void ast_register_feature(struct ast_call_feature *feature);
-
-/*! \brief unregister feature from feature_set
- \param feature the ast_call_feature object which was registered before*/
-void ast_unregister_feature(struct ast_call_feature *feature);
-
-#endif /* _AST_FEATURES_H */
diff --git a/1.4/include/asterisk/file.h b/1.4/include/asterisk/file.h
deleted file mode 100644
index 636309bc4..000000000
--- a/1.4/include/asterisk/file.h
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief Generic File Format Support.
- */
-
-#ifndef _ASTERISK_FILE_H
-#define _ASTERISK_FILE_H
-
-#ifndef stdin
-#error You must include stdio.h before file.h!
-#endif /* !stdin */
-
-#include "asterisk/channel.h"
-#include "asterisk/frame.h"
-#include <fcntl.h>
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-
-/*! Convenient for waiting */
-#define AST_DIGIT_ANY "0123456789#*ABCD"
-#define AST_DIGIT_ANYNUM "0123456789"
-
-/*! structure used for lock and refcount of format handlers.
- * Should not be here, but this is a temporary workaround
- * until we implement a more general mechanism.
- * The format handler should include a pointer to
- * this structure.
- * As a trick, if usecnt is initialized with -1,
- * ast_format_register will init the mutex for you.
- */
-struct ast_format_lock {
- ast_mutex_t lock;
- int usecnt; /* number of active clients */
-};
-
-/*!
- * Each supported file format is described by the following fields.
- * Not all are necessary, the support routine implement default
- * values for some of them.
- * A handler typically fills a structure initializing the desired
- * fields, and then calls ast_format_register() with the (readonly)
- * structure as an argument.
- */
-struct ast_format {
- char name[80]; /*! Name of format */
- char exts[80]; /*! Extensions (separated by | if more than one)
- this format can read. First is assumed for writing (e.g. .mp3) */
- int format; /*! Format of frames it uses/provides (one only) */
- /*! Prepare an input stream for playback. Return 0 on success, -1 on error.
- * The FILE is already open (in s->f) so this function only needs to perform
- * any applicable validity checks on the file. If none is required, the
- * function can be omitted.
- */
- int (*open)(struct ast_filestream *s);
- /*! Prepare a stream for output, and comment it appropriately if applicable.
- * Return 0 on success, -1 on error. Same as the open, the FILE is already
- * open so the function just needs to prepare any header and other fields,
- * if any. The function can be omitted if nothing is needed.
- */
- int (*rewrite)(struct ast_filestream *s, const char *comment);
- /*! Write a frame to a channel */
- int (*write)(struct ast_filestream *, struct ast_frame *);
- /*! seek num samples into file, whence - like a normal seek but with offset in samples */
- int (*seek)(struct ast_filestream *, off_t, int);
- int (*trunc)(struct ast_filestream *fs); /*! trunc file to current position */
- off_t (*tell)(struct ast_filestream *fs); /*! tell current position */
- /*! Read the next frame from the filestream (if available) and report
- * when to get next frame (in samples)
- */
- struct ast_frame * (*read)(struct ast_filestream *, int *whennext);
- /*! Do any closing actions, if any. The descriptor and structure are closed
- * and destroyed by the generic routines, so they must not be done here. */
- void (*close)(struct ast_filestream *);
- char * (*getcomment)(struct ast_filestream *); /*! Retrieve file comment */
-
- AST_LIST_ENTRY(ast_format) list; /*! Link */
-
- /*!
- * If the handler needs a buffer (for read, typically)
- * and/or a private descriptor, put here the
- * required size (in bytes) and the support routine will allocate them
- * for you, pointed by s->buf and s->private, respectively.
- * When allocating a buffer, remember to leave AST_FRIENDLY_OFFSET
- * spare bytes at the bginning.
- */
- int buf_size; /*! size of frame buffer, if any, aligned to 8 bytes. */
- int desc_size; /*! size of private descriptor, if any */
-
- struct ast_module *module;
-};
-
-/*
- * This structure is allocated by file.c in one chunk,
- * together with buf_size and desc_size bytes of memory
- * to be used for private purposes (e.g. buffers etc.)
- */
-struct ast_filestream {
- /*! Everybody reserves a block of AST_RESERVED_POINTERS pointers for us */
- struct ast_format *fmt; /* need to write to the lock and usecnt */
- int flags;
- mode_t mode;
- char *filename;
- char *realfilename;
- /*! Video file stream */
- struct ast_filestream *vfs;
- /*! Transparently translate from another format -- just once */
- struct ast_trans_pvt *trans;
- struct ast_tranlator_pvt *tr;
- int lastwriteformat;
- int lasttimeout;
- struct ast_channel *owner;
- FILE *f;
- struct ast_frame fr; /* frame produced by read, typically */
- char *buf; /* buffer pointed to by ast_frame; */
- /* pointer to private buffer */
- union {
- void *_private;
-#if !defined(__cplusplus) && !defined(c_plusplus)
- void *private attribute_deprecated;
-#endif
- };
- const char *orig_chan_name;
-};
-
-#define SEEK_FORCECUR 10
-
-/*! Register a new file format capability
- * Adds a format to Asterisk's format abilities.
- * returns 0 on success, -1 on failure
- */
-int __ast_format_register(const struct ast_format *f, struct ast_module *mod);
-#define ast_format_register(f) __ast_format_register(f, ast_module_info->self)
-
-/*! Unregisters a file format */
-/*!
- * \param name the name of the format you wish to unregister
- * Unregisters a format based on the name of the format.
- * Returns 0 on success, -1 on failure to unregister
- */
-int ast_format_unregister(const char *name);
-
-/*! Streams a file */
-/*!
- * \param c channel to stream the file to
- * \param filename the name of the file you wish to stream, minus the extension
- * \param preflang the preferred language you wish to have the file streamed to you in
- * Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel
- * Also, it will stop any existing streams on the channel.
- * Returns 0 on success, or -1 on failure.
- */
-int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang);
-
-/*
- * if the file name is non-empty, try to play it.
- * Return 0 if success, -1 if error, digit if interrupted by a digit.
- * If digits == "" then we can simply check for non-zero.
- */
-int ast_stream_and_wait(struct ast_channel *chan, const char *file,
- const char *language, const char *digits);
-
-/*!
- * \brief Stops a stream
- *
- * \param c The channel you wish to stop playback on
- *
- * Stop playback of a stream
- *
- * \retval 0 always
- *
- * \note The channel does not need to be locked before calling this function.
- */
-int ast_stopstream(struct ast_channel *c);
-
-/*! Checks for the existence of a given file */
-/*!
- * \param filename name of the file you wish to check, minus the extension
- * \param fmt the format you wish to check (the extension)
- * \param preflang (the preferred language you wisht to find the file in)
- * See if a given file exists in a given format. If fmt is NULL, any format is accepted.
- * Returns -1 if file does not exist, non-zero positive otherwise.
- */
-int ast_fileexists(const char *filename, const char *fmt, const char *preflang);
-
-/*! Renames a file */
-/*!
- * \param oldname the name of the file you wish to act upon (minus the extension)
- * \param newname the name you wish to rename the file to (minus the extension)
- * \param fmt the format of the file
- * Rename a given file in a given format, or if fmt is NULL, then do so for all
- * Returns -1 on failure
- */
-int ast_filerename(const char *oldname, const char *newname, const char *fmt);
-
-/*! Deletes a file */
-/*!
- * \param filename name of the file you wish to delete (minus the extension)
- * \param fmt of the file
- * Delete a given file in a given format, or if fmt is NULL, then do so for all
- */
-int ast_filedelete(const char *filename, const char *fmt);
-
-/*! Copies a file */
-/*!
- * \param oldname name of the file you wish to copy (minus extension)
- * \param newname name you wish the file to be copied to (minus extension)
- * \param fmt the format of the file
- * Copy a given file in a given format, or if fmt is NULL, then do so for all
- */
-int ast_filecopy(const char *oldname, const char *newname, const char *fmt);
-
-/*! Waits for a stream to stop or digit to be pressed */
-/*!
- * \param c channel to waitstream on
- * \param breakon string of DTMF digits to break upon
- * Begins playback of a stream...
- * Wait for a stream to stop or for any one of a given digit to arrive, Returns 0
- * if the stream finishes, the character if it was interrupted, and -1 on error
- */
-int ast_waitstream(struct ast_channel *c, const char *breakon);
-
-/*! Waits for a stream to stop or digit matching a valid one digit exten to be pressed */
-/*!
- * \param c channel to waitstream on
- * \param context string of context to match digits to break upon
- * Begins playback of a stream...
- * Wait for a stream to stop or for any one of a valid extension digit to arrive, Returns 0
- * if the stream finishes, the character if it was interrupted, and -1 on error
- */
-int ast_waitstream_exten(struct ast_channel *c, const char *context);
-
-/*! Same as waitstream but allows stream to be forwarded or rewound */
-/*!
- * \param c channel to waitstream on
- * \param breakon string of DTMF digits to break upon
- * \param forward DTMF digit to fast forward upon
- * \param rewind DTMF digit to rewind upon
- * \param ms How many miliseconds to skip forward/back
- * Begins playback of a stream...
- * Wait for a stream to stop or for any one of a given digit to arrive, Returns 0
- * if the stream finishes, the character if it was interrupted, and -1 on error
- */
-int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms);
-
-/* Same as waitstream, but with audio output to fd and monitored fd checking. Returns
- 1 if monfd is ready for reading */
-int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd);
-
-/*! Starts reading from a file */
-/*!
- * \param filename the name of the file to read from
- * \param type format of file you wish to read from
- * \param comment comment to go with
- * \param flags file flags
- * \param check (unimplemented, hence negligible)
- * \param mode Open mode
- * Open an incoming file stream. flags are flags for the open() command, and
- * if check is non-zero, then it will not read a file if there are any files that
- * start with that name and have an extension
- * Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
- * Returns a struct ast_filestream on success, NULL on failure
- */
-struct ast_filestream *ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode);
-
-/*! Starts writing a file */
-/*!
- * \param filename the name of the file to write to
- * \param type format of file you wish to write out to
- * \param comment comment to go with
- * \param flags output file flags
- * \param check (unimplemented, hence negligible)
- * \param mode Open mode
- * Create an outgoing file stream. oflags are flags for the open() command, and
- * if check is non-zero, then it will not write a file if there are any files that
- * start with that name and have an extension
- * Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
- * Returns a struct ast_filestream on success, NULL on failure
- */
-struct ast_filestream *ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode);
-
-/*! Writes a frame to a stream */
-/*!
- * \param fs filestream to write to
- * \param f frame to write to the filestream
- * Send a frame to a filestream -- note: does NOT free the frame, call ast_frfree manually
- * Returns 0 on success, -1 on failure.
- */
-int ast_writestream(struct ast_filestream *fs, struct ast_frame *f);
-
-/*! Closes a stream */
-/*!
- * \param f filestream to close
- * Close a playback or recording stream
- * Returns 0 on success, -1 on failure
- */
-int ast_closestream(struct ast_filestream *f);
-
-/*! Opens stream for use in seeking, playing */
-/*!
- * \param chan channel to work with
- * \param filename to use
- * \param preflang prefered language to use
- * Returns a ast_filestream pointer if it opens the file, NULL on error
- */
-struct ast_filestream *ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang);
-
-/*! Opens stream for use in seeking, playing */
-/*!
- * \param chan channel to work with
- * \param filename to use
- * \param preflang prefered language to use
- * \param asis if set, don't clear generators
- * Returns a ast_filestream pointer if it opens the file, NULL on error
- */
-struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char *filename, const char *preflang, int asis);
-/*! Opens stream for use in seeking, playing */
-/*!
- * \param chan channel to work with
- * \param filename to use
- * \param preflang prefered language to use
- * Returns a ast_filestream pointer if it opens the file, NULL on error
- */
-struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang);
-
-/*! Applys a open stream to a channel. */
-/*!
- * \param chan channel to work
- * \param s ast_filestream to apply
- * Returns 0 for success, -1 on failure
- */
-int ast_applystream(struct ast_channel *chan, struct ast_filestream *s);
-
-/*! play a open stream on a channel. */
-/*!
- * \param s filestream to play
- * Returns 0 for success, -1 on failure
- */
-int ast_playstream(struct ast_filestream *s);
-
-/*! Seeks into stream */
-/*!
- * \param fs ast_filestream to perform seek on
- * \param sample_offset numbers of samples to seek
- * \param whence SEEK_SET, SEEK_CUR, SEEK_END
- * Returns 0 for success, or -1 for error
- */
-int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence);
-
-/*! Trunc stream at current location */
-/*!
- * \param fs filestream to act on
- * Returns 0 for success, or -1 for error
- */
-int ast_truncstream(struct ast_filestream *fs);
-
-/*! Fast forward stream ms */
-/*!
- * \param fs filestream to act on
- * \param ms milliseconds to move
- * Returns 0 for success, or -1 for error
- */
-int ast_stream_fastforward(struct ast_filestream *fs, off_t ms);
-
-/*! Rewind stream ms */
-/*!
- * \param fs filestream to act on
- * \param ms milliseconds to move
- * Returns 0 for success, or -1 for error
- */
-int ast_stream_rewind(struct ast_filestream *fs, off_t ms);
-
-/*! Tell where we are in a stream */
-/*!
- * \param fs fs to act on
- * Returns a long as a sample offset into stream
- */
-off_t ast_tellstream(struct ast_filestream *fs);
-
-/*! Read a frame from a filestream */
-/*!
- * \param s ast_filestream to act on
- * Returns a frame or NULL if read failed
- */
-struct ast_frame *ast_readframe(struct ast_filestream *s);
-
-/*! Initialize file stuff */
-/*!
- * Initializes all the various file stuff. Basically just registers the cli stuff
- * Returns 0 all the time
- */
-int ast_file_init(void);
-
-
-#define AST_RESERVED_POINTERS 20
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_FILE_H */
diff --git a/1.4/include/asterisk/frame.h b/1.4/include/asterisk/frame.h
deleted file mode 100644
index 30686efde..000000000
--- a/1.4/include/asterisk/frame.h
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Asterisk internal frame definitions.
- * \arg For an explanation of frames, see \ref Def_Frame
- * \arg Frames are send of Asterisk channels, see \ref Def_Channel
- */
-
-#ifndef _ASTERISK_FRAME_H
-#define _ASTERISK_FRAME_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include "asterisk/compiler.h"
-#include "asterisk/endian.h"
-#include "asterisk/linkedlists.h"
-
-struct ast_codec_pref {
- char order[32];
- char framing[32];
-};
-
-/*! \page Def_Frame AST Multimedia and signalling frames
- \section Def_AstFrame What is an ast_frame ?
- A frame of data read used to communicate between
- between channels and applications.
- Frames are divided into frame types and subclasses.
-
- \par Frame types
- \arg \b VOICE: Voice data, subclass is codec (AST_FORMAT_*)
- \arg \b VIDEO: Video data, subclass is codec (AST_FORMAT_*)
- \arg \b DTMF: A DTMF digit, subclass is the digit
- \arg \b IMAGE: Image transport, mostly used in IAX
- \arg \b TEXT: Text messages
- \arg \b HTML: URL's and web pages
- \arg \b MODEM: Modulated data encodings, such as T.38 and V.150
- \arg \b IAX: Private frame type for the IAX protocol
- \arg \b CNG: Comfort noice frames
- \arg \b CONTROL: A control frame, subclass defined as AST_CONTROL_
- \arg \b NULL: Empty, useless frame
-
- \par Files
- \arg frame.h Definitions
- \arg frame.c Function library
- \arg \ref Def_Channel Asterisk channels
- \section Def_ControlFrame Control Frames
- Control frames send signalling information between channels
- and devices. They are prefixed with AST_CONTROL_, like AST_CONTROL_FRAME_HANGUP
- \arg \b HANGUP The other end has hungup
- \arg \b RING Local ring
- \arg \b RINGING The other end is ringing
- \arg \b ANSWER The other end has answered
- \arg \b BUSY Remote end is busy
- \arg \b TAKEOFFHOOK Make it go off hook (what's "it" ? )
- \arg \b OFFHOOK Line is off hook
- \arg \b CONGESTION Congestion (circuit is busy, not available)
- \arg \b FLASH Other end sends flash hook
- \arg \b WINK Other end sends wink
- \arg \b OPTION Send low-level option
- \arg \b RADIO_KEY Key radio (see app_rpt.c)
- \arg \b RADIO_UNKEY Un-key radio (see app_rpt.c)
- \arg \b PROGRESS Other end indicates call progress
- \arg \b PROCEEDING Indicates proceeding
- \arg \b HOLD Call is placed on hold
- \arg \b UNHOLD Call is back from hold
- \arg \b VIDUPDATE Video update requested
- \arg \b SRCUPDATE The source of media has changed
-
-*/
-
-/*!
- * \brief Frame types
- *
- * \note It is important that the values of each frame type are never changed,
- * because it will break backwards compatability with older versions.
- */
-enum ast_frame_type {
- /*! DTMF end event, subclass is the digit */
- AST_FRAME_DTMF_END = 1,
- /*! Voice data, subclass is AST_FORMAT_* */
- AST_FRAME_VOICE,
- /*! Video frame, maybe?? :) */
- AST_FRAME_VIDEO,
- /*! A control frame, subclass is AST_CONTROL_* */
- AST_FRAME_CONTROL,
- /*! An empty, useless frame */
- AST_FRAME_NULL,
- /*! Inter Asterisk Exchange private frame type */
- AST_FRAME_IAX,
- /*! Text messages */
- AST_FRAME_TEXT,
- /*! Image Frames */
- AST_FRAME_IMAGE,
- /*! HTML Frame */
- AST_FRAME_HTML,
- /*! Comfort Noise frame (subclass is level of CNG in -dBov),
- body may include zero or more 8-bit quantization coefficients */
- AST_FRAME_CNG,
- /*! Modem-over-IP data streams */
- AST_FRAME_MODEM,
- /*! DTMF begin event, subclass is the digit */
- AST_FRAME_DTMF_BEGIN,
-};
-#define AST_FRAME_DTMF AST_FRAME_DTMF_END
-
-enum {
- /*! This frame contains valid timing information */
- AST_FRFLAG_HAS_TIMING_INFO = (1 << 0),
- /*! This frame came from a translator and is still the original frame.
- * The translator can not be free'd if the frame inside of it still has
- * this flag set. */
- AST_FRFLAG_FROM_TRANSLATOR = (1 << 1),
- /*! This frame came from a dsp and is still the original frame.
- * The dsp cannot be free'd if the frame inside of it still has
- * this flag set. */
- AST_FRFLAG_FROM_DSP = (1 << 2),
-};
-
-/*! \brief Data structure associated with a single frame of data
- */
-struct ast_frame {
- /*! Kind of frame */
- enum ast_frame_type frametype;
- /*! Subclass, frame dependent */
- int subclass;
- /*! Length of data */
- int datalen;
- /*! Number of 8khz samples in this frame */
- int samples;
- /*! Was the data malloc'd? i.e. should we free it when we discard the frame? */
- int mallocd;
- /*! The number of bytes allocated for a malloc'd frame header */
- size_t mallocd_hdr_len;
- /*! How many bytes exist _before_ "data" that can be used if needed */
- int offset;
- /*! Optional source of frame for debugging */
- const char *src;
- /*! Pointer to actual data */
- void *data;
- /*! Global delivery time */
- struct timeval delivery;
- /*! For placing in a linked list */
- AST_LIST_ENTRY(ast_frame) frame_list;
- /*! Misc. frame flags */
- unsigned int flags;
- /*! Timestamp in milliseconds */
- long ts;
- /*! Length in milliseconds */
- long len;
- /*! Sequence number */
- int seqno;
-};
-
-/*!
- * Set the various field of a frame to point to a buffer.
- * Typically you set the base address of the buffer, the offset as
- * AST_FRIENDLY_OFFSET, and the datalen as the amount of bytes queued.
- * The remaining things (to be done manually) is set the number of
- * samples, which cannot be derived from the datalen unless you know
- * the number of bits per sample.
- */
-#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen) \
- { \
- (fr)->data = (char *)_base + (_ofs); \
- (fr)->offset = (_ofs); \
- (fr)->datalen = (_datalen); \
- }
-
-/*! Queueing a null frame is fairly common, so we declare a global null frame object
- for this purpose instead of having to declare one on the stack */
-extern struct ast_frame ast_null_frame;
-
-#define AST_FRIENDLY_OFFSET 64 /*! It's polite for a a new frame to
- have this number of bytes for additional
- headers. */
-#define AST_MIN_OFFSET 32 /*! Make sure we keep at least this much handy */
-
-/*! Need the header be free'd? */
-#define AST_MALLOCD_HDR (1 << 0)
-/*! Need the data be free'd? */
-#define AST_MALLOCD_DATA (1 << 1)
-/*! Need the source be free'd? (haha!) */
-#define AST_MALLOCD_SRC (1 << 2)
-
-/* MODEM subclasses */
-/*! T.38 Fax-over-IP */
-#define AST_MODEM_T38 1
-/*! V.150 Modem-over-IP */
-#define AST_MODEM_V150 2
-
-/* HTML subclasses */
-/*! Sending a URL */
-#define AST_HTML_URL 1
-/*! Data frame */
-#define AST_HTML_DATA 2
-/*! Beginning frame */
-#define AST_HTML_BEGIN 4
-/*! End frame */
-#define AST_HTML_END 8
-/*! Load is complete */
-#define AST_HTML_LDCOMPLETE 16
-/*! Peer is unable to support HTML */
-#define AST_HTML_NOSUPPORT 17
-/*! Send URL, and track */
-#define AST_HTML_LINKURL 18
-/*! No more HTML linkage */
-#define AST_HTML_UNLINK 19
-/*! Reject link request */
-#define AST_HTML_LINKREJECT 20
-
-/* Data formats for capabilities and frames alike */
-/*! G.723.1 compression */
-#define AST_FORMAT_G723_1 (1 << 0)
-/*! GSM compression */
-#define AST_FORMAT_GSM (1 << 1)
-/*! Raw mu-law data (G.711) */
-#define AST_FORMAT_ULAW (1 << 2)
-/*! Raw A-law data (G.711) */
-#define AST_FORMAT_ALAW (1 << 3)
-/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
-#define AST_FORMAT_G726_AAL2 (1 << 4)
-/*! ADPCM (IMA) */
-#define AST_FORMAT_ADPCM (1 << 5)
-/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
-#define AST_FORMAT_SLINEAR (1 << 6)
-/*! LPC10, 180 samples/frame */
-#define AST_FORMAT_LPC10 (1 << 7)
-/*! G.729A audio */
-#define AST_FORMAT_G729A (1 << 8)
-/*! SpeeX Free Compression */
-#define AST_FORMAT_SPEEX (1 << 9)
-/*! iLBC Free Compression */
-#define AST_FORMAT_ILBC (1 << 10)
-/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
-#define AST_FORMAT_G726 (1 << 11)
-/*! G.722 */
-#define AST_FORMAT_G722 (1 << 12)
-/*! Maximum audio format */
-#define AST_FORMAT_MAX_AUDIO (1 << 15)
-/*! Maximum audio mask */
-#define AST_FORMAT_AUDIO_MASK ((1 << 16)-1)
-/*! JPEG Images */
-#define AST_FORMAT_JPEG (1 << 16)
-/*! PNG Images */
-#define AST_FORMAT_PNG (1 << 17)
-/*! H.261 Video */
-#define AST_FORMAT_H261 (1 << 18)
-/*! H.263 Video */
-#define AST_FORMAT_H263 (1 << 19)
-/*! H.263+ Video */
-#define AST_FORMAT_H263_PLUS (1 << 20)
-/*! H.264 Video */
-#define AST_FORMAT_H264 (1 << 21)
-/*! Maximum video format */
-#define AST_FORMAT_MAX_VIDEO (1 << 24)
-#define AST_FORMAT_VIDEO_MASK (((1 << 25)-1) & ~(AST_FORMAT_AUDIO_MASK))
-
-enum ast_control_frame_type {
- AST_CONTROL_HANGUP = 1, /*!< Other end has hungup */
- AST_CONTROL_RING = 2, /*!< Local ring */
- AST_CONTROL_RINGING = 3, /*!< Remote end is ringing */
- AST_CONTROL_ANSWER = 4, /*!< Remote end has answered */
- AST_CONTROL_BUSY = 5, /*!< Remote end is busy */
- AST_CONTROL_TAKEOFFHOOK = 6, /*!< Make it go off hook */
- AST_CONTROL_OFFHOOK = 7, /*!< Line is off hook */
- AST_CONTROL_CONGESTION = 8, /*!< Congestion (circuits busy) */
- AST_CONTROL_FLASH = 9, /*!< Flash hook */
- AST_CONTROL_WINK = 10, /*!< Wink */
- AST_CONTROL_OPTION = 11, /*!< Set a low-level option */
- AST_CONTROL_RADIO_KEY = 12, /*!< Key Radio */
- AST_CONTROL_RADIO_UNKEY = 13, /*!< Un-Key Radio */
- AST_CONTROL_PROGRESS = 14, /*!< Indicate PROGRESS */
- AST_CONTROL_PROCEEDING = 15, /*!< Indicate CALL PROCEEDING */
- AST_CONTROL_HOLD = 16, /*!< Indicate call is placed on hold */
- AST_CONTROL_UNHOLD = 17, /*!< Indicate call is left from hold */
- AST_CONTROL_VIDUPDATE = 18, /*!< Indicate video frame update */
- AST_CONTROL_SRCUPDATE = 20, /*!< Indicate source of media has changed */
-};
-
-#define AST_SMOOTHER_FLAG_G729 (1 << 0)
-#define AST_SMOOTHER_FLAG_BE (1 << 1)
-
-/* Option identifiers and flags */
-#define AST_OPTION_FLAG_REQUEST 0
-#define AST_OPTION_FLAG_ACCEPT 1
-#define AST_OPTION_FLAG_REJECT 2
-#define AST_OPTION_FLAG_QUERY 4
-#define AST_OPTION_FLAG_ANSWER 5
-#define AST_OPTION_FLAG_WTF 6
-
-/*! Verify touchtones by muting audio transmission
- (and reception) and verify the tone is still present */
-#define AST_OPTION_TONE_VERIFY 1
-
-/*! Put a compatible channel into TDD (TTY for the hearing-impared) mode */
-#define AST_OPTION_TDD 2
-
-/*! Relax the parameters for DTMF reception (mainly for radio use) */
-#define AST_OPTION_RELAXDTMF 3
-
-/*! Set (or clear) Audio (Not-Clear) Mode */
-#define AST_OPTION_AUDIO_MODE 4
-
-/*! Set channel transmit gain
- * Option data is a single signed char
- representing number of decibels (dB)
- to set gain to (on top of any gain
- specified in channel driver)
-*/
-#define AST_OPTION_TXGAIN 5
-
-/*! Set channel receive gain
- * Option data is a single signed char
- representing number of decibels (dB)
- to set gain to (on top of any gain
- specified in channel driver)
-*/
-#define AST_OPTION_RXGAIN 6
-
-/* set channel into "Operator Services" mode */
-#define AST_OPTION_OPRMODE 7
-
-/*! Explicitly enable or disable echo cancelation for the given channel */
-#define AST_OPTION_ECHOCAN 8
-
-struct oprmode {
- struct ast_channel *peer;
- int mode;
-} ;
-
-struct ast_option_header {
- /* Always keep in network byte order */
-#if __BYTE_ORDER == __BIG_ENDIAN
- uint16_t flag:3;
- uint16_t option:13;
-#else
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- uint16_t option:13;
- uint16_t flag:3;
-#else
-#error Byte order not defined
-#endif
-#endif
- uint8_t data[0];
-};
-
-
-/*! \brief Definition of supported media formats (codecs) */
-struct ast_format_list {
- int visible; /*!< Can we see this entry */
- int bits; /*!< bitmask value */
- char *name; /*!< short name */
- char *desc; /*!< Description */
- int fr_len; /*!< Single frame length in bytes */
- int min_ms; /*!< Min value */
- int max_ms; /*!< Max value */
- int inc_ms; /*!< Increment */
- int def_ms; /*!< Default value */
- unsigned int flags; /*!< Smoother flags */
- int cur_ms; /*!< Current value */
-};
-
-
-/*! \brief Requests a frame to be allocated
- *
- * \param source
- * Request a frame be allocated. source is an optional source of the frame,
- * len is the requested length, or "0" if the caller will supply the buffer
- */
-#if 0 /* Unimplemented */
-struct ast_frame *ast_fralloc(char *source, int len);
-#endif
-
-/*!
- * \brief Frees a frame
- *
- * \param fr Frame to free
- * \param cache Whether to consider this frame for frame caching
- */
-void ast_frame_free(struct ast_frame *fr, int cache);
-
-#define ast_frfree(fr) ast_frame_free(fr, 1)
-
-/*! \brief Makes a frame independent of any static storage
- * \param fr frame to act upon
- * Take a frame, and if it's not been malloc'd, make a malloc'd copy
- * and if the data hasn't been malloced then make the
- * data malloc'd. If you need to store frames, say for queueing, then
- * you should call this function.
- * \return Returns a frame on success, NULL on error
- */
-struct ast_frame *ast_frisolate(struct ast_frame *fr);
-
-/*! \brief Copies a frame
- * \param fr frame to copy
- * Duplicates a frame -- should only rarely be used, typically frisolate is good enough
- * \return Returns a frame on success, NULL on error
- */
-struct ast_frame *ast_frdup(const struct ast_frame *fr);
-
-void ast_swapcopy_samples(void *dst, const void *src, int samples);
-
-/* Helpers for byteswapping native samples to/from
- little-endian and big-endian. */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define ast_frame_byteswap_le(fr) do { ; } while(0)
-#define ast_frame_byteswap_be(fr) do { struct ast_frame *__f = (fr); ast_swapcopy_samples(__f->data, __f->data, __f->samples); } while(0)
-#else
-#define ast_frame_byteswap_le(fr) do { struct ast_frame *__f = (fr); ast_swapcopy_samples(__f->data, __f->data, __f->samples); } while(0)
-#define ast_frame_byteswap_be(fr) do { ; } while(0)
-#endif
-
-
-/*! \brief Get the name of a format
- * \param format id of format
- * \return A static string containing the name of the format or "unknown" if unknown.
- */
-char* ast_getformatname(int format);
-
-/*! \brief Get the names of a set of formats
- * \param buf a buffer for the output string
- * \param size size of buf (bytes)
- * \param format the format (combined IDs of codecs)
- * Prints a list of readable codec names corresponding to "format".
- * ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)"
- * \return The return value is buf.
- */
-char* ast_getformatname_multiple(char *buf, size_t size, int format);
-
-/*!
- * \brief Gets a format from a name.
- * \param name string of format
- * \return This returns the form of the format in binary on success, 0 on error.
- */
-int ast_getformatbyname(const char *name);
-
-/*! \brief Get a name from a format
- * Gets a name from a format
- * \param codec codec number (1,2,4,8,16,etc.)
- * \return This returns a static string identifying the format on success, 0 on error.
- */
-char *ast_codec2str(int codec);
-
-struct ast_smoother;
-
-struct ast_format_list *ast_get_format_list_index(int index);
-struct ast_format_list *ast_get_format_list(size_t *size);
-struct ast_smoother *ast_smoother_new(int bytes);
-void ast_smoother_set_flags(struct ast_smoother *smoother, int flags);
-int ast_smoother_get_flags(struct ast_smoother *smoother);
-int ast_smoother_test_flag(struct ast_smoother *s, int flag);
-void ast_smoother_free(struct ast_smoother *s);
-void ast_smoother_reset(struct ast_smoother *s, int bytes);
-int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap);
-struct ast_frame *ast_smoother_read(struct ast_smoother *s);
-#define ast_smoother_feed(s,f) __ast_smoother_feed(s, f, 0)
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 1)
-#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 0)
-#else
-#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 0)
-#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 1)
-#endif
-
-void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix);
-
-/*! \page AudioCodecPref Audio Codec Preferences
- In order to negotiate audio codecs in the order they are configured
- in <channel>.conf for a device, we set up codec preference lists
- in addition to the codec capabilities setting. The capabilities
- setting is a bitmask of audio and video codecs with no internal
- order. This will reflect the offer given to the other side, where
- the prefered codecs will be added to the top of the list in the
- order indicated by the "allow" lines in the device configuration.
-
- Video codecs are not included in the preference lists since they
- can't be transcoded and we just have to pick whatever is supported
-*/
-
-/*! \brief Initialize an audio codec preference to "no preference" See \ref AudioCodecPref */
-void ast_codec_pref_init(struct ast_codec_pref *pref);
-
-/*! \brief Codec located at a particular place in the preference index See \ref AudioCodecPref */
-int ast_codec_pref_index(struct ast_codec_pref *pref, int index);
-
-/*! \brief Remove audio a codec from a preference list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, int format);
-
-/*! \brief Append a audio codec to a preference list, removing it first if it was already there
-*/
-int ast_codec_pref_append(struct ast_codec_pref *pref, int format);
-
-/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there
-*/
-void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing);
-
-/*! \brief Select the best audio format according to preference list from supplied options.
- If "find_best" is non-zero then if nothing is found, the "Best" format of
- the format list is selected, otherwise 0 is returned. */
-int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best);
-
-/*! \brief Set packet size for codec
-*/
-int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems);
-
-/*! \brief Get packet size for codec
-*/
-struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int format);
-
-/*! \brief Parse an "allow" or "deny" line in a channel or device configuration
- and update the capabilities mask and pref if provided.
- Video codecs are not added to codec preference lists, since we can not transcode
- */
-void ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing);
-
-/*! \brief Dump audio codec preference list into a string */
-int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
-
-/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string */
-void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right);
-
-/*! \brief Returns the number of samples contained in the frame */
-int ast_codec_get_samples(struct ast_frame *f);
-
-/*! \brief Returns the number of bytes for the number of samples of the given format */
-int ast_codec_get_len(int format, int samples);
-
-/*! \brief Appends a frame to the end of a list of frames, truncating the maximum length of the list */
-struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe);
-
-
-/*! \brief Gets duration in ms of interpolation frame for a format */
-static inline int ast_codec_interp_len(int format)
-{
- return (format == AST_FORMAT_ILBC) ? 30 : 20;
-}
-
-/*!
- \brief Adjusts the volume of the audio samples contained in a frame.
- \param f The frame containing the samples (must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR)
- \param adjustment The number of dB to adjust up or down.
- \return 0 for success, non-zero for an error
- */
-int ast_frame_adjust_volume(struct ast_frame *f, int adjustment);
-
-/*!
- \brief Sums two frames of audio samples.
- \param f1 The first frame (which will contain the result)
- \param f2 The second frame
- \return 0 for success, non-zero for an error
-
- The frames must be AST_FRAME_VOICE and must contain AST_FORMAT_SLINEAR samples,
- and must contain the same number of samples.
- */
-int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2);
-
-/*!
- * \brief Get the sample rate for a given format.
- */
-static force_inline int ast_format_rate(int format)
-{
- if (format == AST_FORMAT_G722)
- return 16000;
-
- return 8000;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_FRAME_H */
diff --git a/1.4/include/asterisk/fskmodem.h b/1.4/include/asterisk/fskmodem.h
deleted file mode 100644
index e6d1a5419..000000000
--- a/1.4/include/asterisk/fskmodem.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief FSK Modem Support
- * \note Includes code and algorithms from the Zapata library.
- * \todo Translate Emiliano Zapata's spanish comments to english, please.
- */
-
-#ifndef _ASTERISK_FSKMODEM_H
-#define _ASTERISK_FSKMODEM_H
-
-#define PARITY_NONE 0
-#define PARITY_EVEN 1
-#define PARITY_ODD 2
-
-
-#define NCOLA 0x4000
-
-typedef struct {
- float spb; /*!< Samples / Bit */
- int nbit; /*!< Number of Data Bits (5,7,8) */
- float nstop; /*!< Number of Stop Bits 1,1.5,2 */
- int paridad; /*!< Parity 0=none 1=even 2=odd */
- int hdlc; /*!< Modo Packet */
- float x0;
- float x1;
- float x2;
- float cont;
- int bw; /*!< Ancho de Banda */
- double fmxv[8],fmyv[8]; /*!< filter stuff for M filter */
- int fmp; /*!< pointer for M filter */
- double fsxv[8],fsyv[8]; /*!< filter stuff for S filter */
- int fsp; /*!< pointer for S filter */
- double flxv[8],flyv[8]; /*!< filter stuff for L filter */
- int flp; /*!< pointer for L filter */
- int f_mark_idx; /*!< Indice de frecuencia de marca (f_M-500)/5 */
- int f_space_idx; /*!< Indice de frecuencia de espacio (f_S-500)/5 */
- int state;
- int pcola; /*!< Puntero de las colas de datos */
- float cola_in[NCOLA]; /*!< Cola de muestras de entrada */
- float cola_filtro[NCOLA]; /*!< Cola de muestras tras filtros */
- float cola_demod[NCOLA]; /*!< Cola de muestras demoduladas */
-} fsk_data;
-
-/* \brief Retrieve a serial byte into outbyte.
- Buffer is a pointer into a series of
- shorts and len records the number of bytes in the buffer. len will be
- overwritten with the number of bytes left that were not consumed.
- \return return value is as follows:
- \arg 0: Still looking for something...
- \arg 1: An output byte was received and stored in outbyte
- \arg -1: An error occured in the transmission
- He must be called with at least 80 bytes of buffer. */
-int fsk_serie(fsk_data *fskd, short *buffer, int *len, int *outbyte);
-
-#endif /* _ASTERISK_FSKMODEM_H */
diff --git a/1.4/include/asterisk/global_datastores.h b/1.4/include/asterisk/global_datastores.h
deleted file mode 100644
index 72edabac5..000000000
--- a/1.4/include/asterisk/global_datastores.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Mark Michelson <mmichelson@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.
- */
-
-/*! \file
- * \brief globally accessible channel datastores
- * \author Mark Michelson <mmichelson@digium.com>
- */
-
-#ifndef _ASTERISK_GLOBAL_DATASTORE_H
-#define _ASTERISK_GLOBAL_DATASTORE_H
-
-#include "asterisk/channel.h"
-
-extern const struct ast_datastore_info dialed_interface_info;
-
-struct ast_dialed_interface {
- AST_LIST_ENTRY(ast_dialed_interface) list;
- char interface[1];
-};
-
-#endif
diff --git a/1.4/include/asterisk/http.h b/1.4/include/asterisk/http.h
deleted file mode 100644
index ba6f094e4..000000000
--- a/1.4/include/asterisk/http.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _ASTERISK_HTTP_H
-#define _ASTERISK_HTTP_H
-
-#include "asterisk/config.h"
-
-/*!
- \file http.h
- \brief Support for Private Asterisk HTTP Servers.
- \note Note: The Asterisk HTTP servers are extremely simple and minimal and
- only support the "GET" method.
- \author Mark Spencer <markster@digium.com>
-*/
-
-/*! \brief HTTP Callbacks take the socket, the method and the path as arguments and should
- return the content, allocated with malloc(). Status should be changed to reflect
- the status of the request if it isn't 200 and title may be set to a malloc()'d string
- to an appropriate title for non-200 responses. Content length may also be specified.
- The return value may include additional headers at the front and MUST include a blank
- line with \r\n to provide separation between user headers and content (even if no
- content is specified) */
-typedef char *(*ast_http_callback)(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
-
-struct ast_http_uri {
- struct ast_http_uri *next;
- const char *description;
- const char *uri;
- unsigned int has_subtree:1;
- /*! This URI mapping serves static content */
- unsigned int static_content:1;
- ast_http_callback callback;
-};
-
-/*! \brief Link into the Asterisk HTTP server */
-int ast_http_uri_link(struct ast_http_uri *urihandler);
-
-/*! \brief Return a malloc()'d string containing an HTTP error message */
-char *ast_http_error(int status, const char *title, const char *extra_header, const char *text);
-
-/*! \brief Destroy an HTTP server */
-void ast_http_uri_unlink(struct ast_http_uri *urihandler);
-
-char *ast_http_setcookie(const char *var, const char *val, int expires, char *buf, size_t buflen);
-
-int ast_http_init(void);
-int ast_http_reload(void);
-
-#endif /* _ASTERISK_SRV_H */
diff --git a/1.4/include/asterisk/image.h b/1.4/include/asterisk/image.h
deleted file mode 100644
index 72d1a4018..000000000
--- a/1.4/include/asterisk/image.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief General Asterisk channel definitions for image handling
- */
-
-#ifndef _ASTERISK_IMAGE_H
-#define _ASTERISK_IMAGE_H
-
-/*! \brief structure associated with registering an image format */
-struct ast_imager {
- /*! Name */
- char *name;
- /*! Description */
- char *desc;
- /*! Extension(s) (separated by '|' ) */
- char *exts;
- /*! Image format */
- int format;
- /*! Read an image from a file descriptor */
- struct ast_frame *(*read_image)(int fd, int len);
- /*! Identify if this is that type of file */
- int (*identify)(int fd);
- /*! Returns length written */
- int (*write_image)(int fd, struct ast_frame *frame);
- /*! For linked list */
- AST_LIST_ENTRY(ast_imager) list;
-};
-
-/*! Check for image support on a channel */
-/*!
- * \param chan channel to check
- * Checks the channel to see if it supports the transmission of images
- * Returns non-zero if image transmission is supported
- */
-int ast_supports_images(struct ast_channel *chan);
-
-/*! Sends an image */
-/*!
- * \param chan channel to send image on
- * \param filename filename of image to send (minus extension)
- * Sends an image on the given channel.
- * Returns 0 on success, -1 on error
- */
-int ast_send_image(struct ast_channel *chan, char *filename);
-
-/*! Make an image */
-/*!
- * \param filename filename of image to prepare
- * \param preflang preferred language to get the image...?
- * \param format the format of the file
- * Make an image from a filename ??? No estoy positivo
- * Returns an ast_frame on success, NULL on failure
- */
-struct ast_frame *ast_read_image(char *filename, const char *preflang, int format);
-
-/*! Register image format */
-/*!
- * \param imgdrv Populated ast_imager structure with info to register
- * Registers an image format
- * Returns 0 regardless
- */
-int ast_image_register(struct ast_imager *imgdrv);
-
-/*! Unregister an image format */
-/*!
- * \param imgdrv pointer to the ast_imager structure you wish to unregister
- * Unregisters the image format passed in
- * Returns nothing
- */
-void ast_image_unregister(struct ast_imager *imgdrv);
-
-/*! Initialize image stuff */
-/*!
- * Initializes all the various image stuff. Basically just registers the cli stuff
- * Returns 0 all the time
- */
-int ast_image_init(void);
-
-#endif /* _ASTERISK_IMAGE_H */
diff --git a/1.4/include/asterisk/indications.h b/1.4/include/asterisk/indications.h
deleted file mode 100644
index a6c1d7c9d..000000000
--- a/1.4/include/asterisk/indications.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * 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.
- */
-
-/*! \file
- * \brief BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Primary Author: Pauline Middelink <middelink@polyware.nl>
- *
- */
-
-#ifndef _ASTERISK_INDICATIONS_H
-#define _ASTERISK_INDICATIONS_H
-
-#include "asterisk/lock.h"
-
-struct tone_zone_sound {
- struct tone_zone_sound *next; /* next element */
- const char *name; /* Identifing name */
- const char *data; /* Actual zone description */
- /* Description is a series of tones of the format:
- [!]freq1[+freq2][/duration] separated by commas. There
- are no spaces. The sequence is repeated back to the
- first tone description not preceeded by !. Duration is
- specified in milliseconds */
-};
-
-struct tone_zone {
- struct tone_zone* next; /* next in list */
- char country[5]; /* Country code */
- char alias[5]; /* is this an alias? */
- char description[40]; /* Description */
- int nrringcadence; /* # registered ringcadence elements */
- int *ringcadence; /* Ring cadence */
- struct tone_zone_sound *tones; /* The known tones for this zone */
-};
-
-/* set the default tone country */
-int ast_set_indication_country(const char *country);
-
-/* locate tone_zone, given the country. if country == NULL, use the default country */
-struct tone_zone *ast_get_indication_zone(const char *country);
-/* locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone */
-struct tone_zone_sound *ast_get_indication_tone(const struct tone_zone *zone, const char *indication);
-
-/* add a new country, if country exists, it will be replaced. */
-int ast_register_indication_country(struct tone_zone *country);
-/* remove an existing country and all its indications, country must exist */
-int ast_unregister_indication_country(const char *country);
-/* add a new indication to a tone_zone. tone_zone must exist. if the indication already
- * exists, it will be replaced. */
-int ast_register_indication(struct tone_zone *zone, const char *indication, const char *tonelist);
-/* remove an existing tone_zone's indication. tone_zone must exist */
-int ast_unregister_indication(struct tone_zone *zone, const char *indication);
-
-/* Start a tone-list going */
-int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
-/*! Stop the tones from playing */
-void ast_playtones_stop(struct ast_channel *chan);
-
-/* support for walking through a list of indications */
-struct tone_zone *ast_walk_indications(const struct tone_zone *cur);
-
-#if 0
-extern struct tone_zone *tone_zones;
-extern ast_mutex_t tzlock;
-#endif
-
-#endif /* _ASTERISK_INDICATIONS_H */
diff --git a/1.4/include/asterisk/inline_api.h b/1.4/include/asterisk/inline_api.h
deleted file mode 100644
index 2347d09d7..000000000
--- a/1.4/include/asterisk/inline_api.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@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.
- */
-
-#ifndef __ASTERISK_INLINEAPI_H
-#define __ASTERISK_INLINEAPI_H
-
-/*! \file
- * \brief Inlinable API function macro
-
- Small API functions that are candidates for inlining need to be specially
- declared and defined, to ensure that the 'right thing' always happens.
- For example:
- - there must _always_ be a non-inlined version of the function
- available for modules compiled out of the tree to link to
- - references to a function that cannot be inlined (for any
- reason that the compiler deems proper) must devolve into an
- 'extern' reference, instead of 'static', so that multiple
- copies of the function body are not built in different modules
- - when LOW_MEMORY is defined, inlining should be disabled
- completely, even if the compiler is configured to support it
-
- The AST_INLINE_API macro allows this to happen automatically, when
- used to define your function. Proper usage is as follows:
- - define your function one place, in a header file, using the macro
- to wrap the function (see strings.h or time.h for examples)
- - choose a module to 'host' the function body for non-inline
- usages, and in that module _only_, define AST_API_MODULE before
- including the header file
- */
-
-#if !defined(LOW_MEMORY)
-
-#if !defined(AST_API_MODULE)
-#define AST_INLINE_API(hdr, body) hdr; extern inline hdr body
-#else
-#define AST_INLINE_API(hdr, body) hdr; hdr body
-#endif
-
-#else /* defined(LOW_MEMORY) */
-
-#if !defined(AST_API_MODULE)
-#define AST_INLINE_API(hdr, body) hdr;
-#else
-#define AST_INLINE_API(hdr, body) hdr; hdr body
-#endif
-
-#endif
-
-#undef AST_API_MODULE
-
-#endif /* __ASTERISK_INLINEAPI_H */
diff --git a/1.4/include/asterisk/io.h b/1.4/include/asterisk/io.h
deleted file mode 100644
index 66ebceea0..000000000
--- a/1.4/include/asterisk/io.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief I/O Management (derived from Cheops-NG)
- */
-
-#ifndef _ASTERISK_IO_H
-#define _ASTERISK_IO_H
-
-#ifdef POLLCOMPAT
-#include "asterisk/poll-compat.h"
-#else
-#include <sys/poll.h> /* For POLL* constants */
-#endif
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! Input ready */
-#define AST_IO_IN POLLIN
-/*! Output ready */
-#define AST_IO_OUT POLLOUT
-/*! Priority input ready */
-#define AST_IO_PRI POLLPRI
-
-/* Implicitly polled for */
-/*! Error condition (errno or getsockopt) */
-#define AST_IO_ERR POLLERR
-/*! Hangup */
-#define AST_IO_HUP POLLHUP
-/*! Invalid fd */
-#define AST_IO_NVAL POLLNVAL
-
-/*
- * An Asterisk IO callback takes its id, a file descriptor, list of events, and
- * callback data as arguments and returns 0 if it should not be
- * run again, or non-zero if it should be run again.
- */
-
-struct io_context;
-
-/*! Creates a context */
-/*!
- * Create a context for I/O operations
- * Basically mallocs an IO structure and sets up some default values.
- * Returns an allocated io_context structure
- */
-struct io_context *io_context_create(void);
-
-/*! Destroys a context */
-/*
- * \param ioc structure to destroy
- * Destroy a context for I/O operations
- * Frees all memory associated with the given io_context structure along with the structure itself
- */
-void io_context_destroy(struct io_context *ioc);
-
-typedef int (*ast_io_cb)(int *id, int fd, short events, void *cbdata);
-#define AST_IO_CB(a) ((ast_io_cb)(a))
-
-/*! Adds an IO context */
-/*!
- * \param ioc which context to use
- * \param fd which fd to monitor
- * \param callback callback function to run
- * \param events event mask of events to wait for
- * \param data data to pass to the callback
- * Watch for any of revents activites on fd, calling callback with data as
- * callback data. Returns a pointer to ID of the IO event, or NULL on failure.
- */
-int *ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data);
-
-/*! Changes an IO handler */
-/*!
- * \param ioc which context to use
- * \param id
- * \param fd the fd you wish it to contain now
- * \param callback new callback function
- * \param events event mask to wait for
- * \param data data to pass to the callback function
- * Change an i/o handler, updating fd if > -1, callback if non-null, and revents
- * if >-1, and data if non-null. Returns a pointero to the ID of the IO event,
- * or NULL on failure.
- */
-int *ast_io_change(struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data);
-
-/*! Removes an IO context */
-/*!
- * \param ioc which io_context to remove it from
- * \param id which ID to remove
- * Remove an I/O id from consideration Returns 0 on success or -1 on failure.
- */
-int ast_io_remove(struct io_context *ioc, int *id);
-
-/*! Waits for IO */
-/*!
- * \param ioc which context to act upon
- * \param howlong how many milliseconds to wait
- * Wait for I/O to happen, returning after
- * howlong milliseconds, and after processing
- * any necessary I/O. Returns the number of
- * I/O events which took place.
- */
-int ast_io_wait(struct io_context *ioc, int howlong);
-
-/*! Dumps the IO array */
-/*
- * Debugging: Dump everything in the I/O array
- */
-void ast_io_dump(struct io_context *ioc);
-
-/*! Set fd into non-echoing mode (if fd is a tty) */
-
-int ast_hide_password(int fd);
-
-/*! Restores TTY mode */
-/*
- * Call with result from previous ast_hide_password
- */
-int ast_restore_tty(int fd, int oldstatus);
-
-int ast_get_termcols(int fd);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_IO_H */
diff --git a/1.4/include/asterisk/jabber.h b/1.4/include/asterisk/jabber.h
deleted file mode 100644
index 39618cd4b..000000000
--- a/1.4/include/asterisk/jabber.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Matt O'Gorman <mogorman@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.
- */
-
-#ifndef _ASTERISK_JABBER_H
-#define _ASTERISK_JABBER_H
-
-#include <iksemel.h>
-#include "asterisk/astobj.h"
-#include "asterisk/linkedlists.h"
-
-/*
- * As per RFC 3920 - section 3.1, the maximum length for a full Jabber ID
- * is 3071 bytes.
- * The ABNF syntax for jid :
- * jid = [node "@" ] domain [ "/" resource ]
- * Each allowable portion of a JID (node identifier, domain identifier,
- * and resource identifier) MUST NOT be more than 1023 bytes in length,
- * resulting in a maximum total size (including the '@' and '/' separators)
- * of 3071 bytes.
- */
-#define AJI_MAX_JIDLEN 3071
-#define AJI_MAX_RESJIDLEN 1023
-
-enum aji_state {
- AJI_DISCONNECTING,
- AJI_DISCONNECTED,
- AJI_CONNECTING,
- AJI_CONNECTED
-};
-
-enum {
- AJI_AUTOPRUNE = (1 << 0),
- AJI_AUTOREGISTER = (1 << 1)
-};
-
-enum aji_btype {
- AJI_USER=0,
- AJI_TRANS=1,
- AJI_UTRANS=2
-};
-
-struct aji_version {
- char version[50];
- int jingle;
- struct aji_capabilities *parent;
- struct aji_version *next;
-};
-
-struct aji_capabilities {
- char node[200];
- struct aji_version *versions;
- struct aji_capabilities *next;
-};
-
-struct aji_resource {
- int status;
- char resource[AJI_MAX_RESJIDLEN];
- char *description;
- struct aji_version *cap;
- int priority;
- struct aji_resource *next;
-};
-
-struct aji_message {
- char *from;
- char *message;
- char id[25];
- time_t arrived;
- AST_LIST_ENTRY(aji_message) list;
-};
-
-struct aji_buddy {
- ASTOBJ_COMPONENTS_FULL(struct aji_buddy, AJI_MAX_JIDLEN, 1);
- struct aji_resource *resources;
- unsigned int flags;
-};
-
-struct aji_buddy_container {
- ASTOBJ_CONTAINER_COMPONENTS(struct aji_buddy);
-};
-
-struct aji_transport_container {
- ASTOBJ_CONTAINER_COMPONENTS(struct aji_transport);
-};
-
-struct aji_client {
- ASTOBJ_COMPONENTS(struct aji_client);
- char password[160];
- char user[AJI_MAX_JIDLEN];
- char serverhost[AJI_MAX_RESJIDLEN];
- char statusmessage[256];
- char sid[10]; /* Session ID */
- char mid[6]; /* Message ID */
- iksid *jid;
- iksparser *p;
- iksfilter *f;
- ikstack *stack;
- enum aji_state state;
- int port;
- int debug;
- int usetls;
- int forcessl;
- int usesasl;
- int keepalive;
- int allowguest;
- int timeout;
- int message_timeout;
- int authorized;
- unsigned int flags;
- int component; /* 0 client, 1 component */
- struct aji_buddy_container buddies;
- AST_LIST_HEAD(messages,aji_message) messages;
- void *jingle;
- pthread_t thread;
-};
-
-struct aji_client_container{
- ASTOBJ_CONTAINER_COMPONENTS(struct aji_client);
-};
-
-int ast_aji_send(struct aji_client *client, const char *address, const char *message);
-int ast_aji_disconnect(struct aji_client *client);
-int ast_aji_check_roster(void);
-void ast_aji_increment_mid(char *mid);
-int ast_aji_create_chat(struct aji_client *client,char *room, char *server, char *topic);
-int ast_aji_invite_chat(struct aji_client *client, char *user, char *room, char *message);
-int ast_aji_join_chat(struct aji_client *client,char *room);
-struct aji_client *ast_aji_get_client(const char *name);
-struct aji_client_container *ast_aji_get_clients(void);
-
-#endif
diff --git a/1.4/include/asterisk/jingle.h b/1.4/include/asterisk/jingle.h
deleted file mode 100644
index 0968b7394..000000000
--- a/1.4/include/asterisk/jingle.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Matt O'Gorman <mogorman@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.
- */
-
-#ifndef _ASTERISK_JINGLE_H
-#define _ASTERISK_JINGLE_H
-
-#include <iksemel.h>
-#include "asterisk/astobj.h"
-
-
-/* Jingle Constants */
-
-#define JINGLE_NODE "jingle"
-#define GOOGLE_NODE "session"
-
-#define JINGLE_NS "http://jabber.org/protocol/jingle"
-#define GOOGLE_NS "http://www.google.com/session"
-
-#define JINGLE_SID "sid"
-#define GOOGLE_SID "id"
-
-#define JINGLE_INITIATE "initiate"
-
-#define JINGLE_ACCEPT "accept"
-#define GOOGLE_ACCEPT "accept"
-
-#define JINGLE_NEGOTIATE "negotiate"
-#define GOOGLE_NEGOTIATE "candidates"
-
-#endif
diff --git a/1.4/include/asterisk/linkedlists.h b/1.4/include/asterisk/linkedlists.h
deleted file mode 100644
index a8d90ecbe..000000000
--- a/1.4/include/asterisk/linkedlists.h
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@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.
- */
-
-#ifndef ASTERISK_LINKEDLISTS_H
-#define ASTERISK_LINKEDLISTS_H
-
-#include "asterisk/lock.h"
-
-/*!
- \file linkedlists.h
- \brief A set of macros to manage forward-linked lists.
-*/
-
-/*!
- \brief Locks a list.
- \param head This is a pointer to the list head structure
-
- This macro attempts to place an exclusive lock in the
- list head structure pointed to by head.
- Returns 0 on success, non-zero on failure
-*/
-#define AST_LIST_LOCK(head) \
- ast_mutex_lock(&(head)->lock)
-
-/*!
- \brief Write locks a list.
- \param head This is a pointer to the list head structure
-
- This macro attempts to place an exclusive write lock in the
- list head structure pointed to by head.
- Returns 0 on success, non-zero on failure
-*/
-#define AST_RWLIST_WRLOCK(head) \
- ast_rwlock_wrlock(&(head)->lock)
-
-/*!
- \brief Read locks a list.
- \param head This is a pointer to the list head structure
-
- This macro attempts to place a read lock in the
- list head structure pointed to by head.
- Returns 0 on success, non-zero on failure
-*/
-#define AST_RWLIST_RDLOCK(head) \
- ast_rwlock_rdlock(&(head)->lock)
-
-/*!
- \brief Locks a list, without blocking if the list is locked.
- \param head This is a pointer to the list head structure
-
- This macro attempts to place an exclusive lock in the
- list head structure pointed to by head.
- Returns 0 on success, non-zero on failure
-*/
-#define AST_LIST_TRYLOCK(head) \
- ast_mutex_trylock(&(head)->lock)
-
-/*!
- \brief Write locks a list, without blocking if the list is locked.
- \param head This is a pointer to the list head structure
-
- This macro attempts to place an exclusive write lock in the
- list head structure pointed to by head.
- Returns 0 on success, non-zero on failure
-*/
-#define AST_RWLIST_TRYWRLOCK(head) \
- ast_rwlock_trywrlock(&(head)->lock)
-
-/*!
- \brief Read locks a list, without blocking if the list is locked.
- \param head This is a pointer to the list head structure
-
- This macro attempts to place a read lock in the
- list head structure pointed to by head.
- Returns 0 on success, non-zero on failure
-*/
-#define AST_RWLIST_TRYRDLOCK(head) \
- ast_rwlock_tryrdlock(&(head)->lock)
-
-/*!
- \brief Attempts to unlock a list.
- \param head This is a pointer to the list head structure
-
- This macro attempts to remove an exclusive lock from the
- list head structure pointed to by head. If the list
- was not locked by this thread, this macro has no effect.
-*/
-#define AST_LIST_UNLOCK(head) \
- ast_mutex_unlock(&(head)->lock)
-
-/*!
- \brief Attempts to unlock a read/write based list.
- \param head This is a pointer to the list head structure
-
- This macro attempts to remove a read or write lock from the
- list head structure pointed to by head. If the list
- was not locked by this thread, this macro has no effect.
-*/
-#define AST_RWLIST_UNLOCK(head) \
- ast_rwlock_unlock(&(head)->lock)
-
-/*!
- \brief Defines a structure to be used to hold a list of specified type.
- \param name This will be the name of the defined structure.
- \param type This is the type of each list entry.
-
- This macro creates a structure definition that can be used
- to hold a list of the entries of type \a type. It does not actually
- declare (allocate) a structure; to do that, either follow this
- macro with the desired name of the instance you wish to declare,
- or use the specified \a name to declare instances elsewhere.
-
- Example usage:
- \code
- static AST_LIST_HEAD(entry_list, entry) entries;
- \endcode
-
- This would define \c struct \c entry_list, and declare an instance of it named
- \a entries, all intended to hold a list of type \c struct \c entry.
-*/
-#define AST_LIST_HEAD(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
- ast_mutex_t lock; \
-}
-
-/*!
- \brief Defines a structure to be used to hold a read/write list of specified type.
- \param name This will be the name of the defined structure.
- \param type This is the type of each list entry.
-
- This macro creates a structure definition that can be used
- to hold a list of the entries of type \a type. It does not actually
- declare (allocate) a structure; to do that, either follow this
- macro with the desired name of the instance you wish to declare,
- or use the specified \a name to declare instances elsewhere.
-
- Example usage:
- \code
- static AST_RWLIST_HEAD(entry_list, entry) entries;
- \endcode
-
- This would define \c struct \c entry_list, and declare an instance of it named
- \a entries, all intended to hold a list of type \c struct \c entry.
-*/
-#define AST_RWLIST_HEAD(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
- ast_rwlock_t lock; \
-}
-
-/*!
- \brief Defines a structure to be used to hold a list of specified type (with no lock).
- \param name This will be the name of the defined structure.
- \param type This is the type of each list entry.
-
- This macro creates a structure definition that can be used
- to hold a list of the entries of type \a type. It does not actually
- declare (allocate) a structure; to do that, either follow this
- macro with the desired name of the instance you wish to declare,
- or use the specified \a name to declare instances elsewhere.
-
- Example usage:
- \code
- static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
- \endcode
-
- This would define \c struct \c entry_list, and declare an instance of it named
- \a entries, all intended to hold a list of type \c struct \c entry.
-*/
-#define AST_LIST_HEAD_NOLOCK(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
-}
-
-/*!
- \brief Defines initial values for a declaration of AST_LIST_HEAD
-*/
-#define AST_LIST_HEAD_INIT_VALUE { \
- .first = NULL, \
- .last = NULL, \
- .lock = AST_MUTEX_INIT_VALUE, \
- }
-
-/*!
- \brief Defines initial values for a declaration of AST_RWLIST_HEAD
-*/
-#define AST_RWLIST_HEAD_INIT_VALUE { \
- .first = NULL, \
- .last = NULL, \
- .lock = AST_RWLOCK_INIT_VALUE, \
- }
-
-/*!
- \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
-*/
-#define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
- .first = NULL, \
- .last = NULL, \
- }
-
-/*!
- \brief Defines a structure to be used to hold a list of specified type, statically initialized.
- \param name This will be the name of the defined structure.
- \param type This is the type of each list entry.
-
- This macro creates a structure definition that can be used
- to hold a list of the entries of type \a type, and allocates an instance
- of it, initialized to be empty.
-
- Example usage:
- \code
- static AST_LIST_HEAD_STATIC(entry_list, entry);
- \endcode
-
- This would define \c struct \c entry_list, intended to hold a list of
- type \c struct \c entry.
-*/
-#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
-#define AST_LIST_HEAD_STATIC(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
- ast_mutex_t lock; \
-} name; \
-static void __attribute__ ((constructor)) init_##name(void) \
-{ \
- AST_LIST_HEAD_INIT(&name); \
-} \
-static void __attribute__ ((destructor)) fini_##name(void) \
-{ \
- AST_LIST_HEAD_DESTROY(&name); \
-} \
-struct __dummy_##name
-#else
-#define AST_LIST_HEAD_STATIC(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
- ast_mutex_t lock; \
-} name = AST_LIST_HEAD_INIT_VALUE
-#endif
-
-/*!
- \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
- \param name This will be the name of the defined structure.
- \param type This is the type of each list entry.
-
- This macro creates a structure definition that can be used
- to hold a list of the entries of type \a type, and allocates an instance
- of it, initialized to be empty.
-
- Example usage:
- \code
- static AST_RWLIST_HEAD_STATIC(entry_list, entry);
- \endcode
-
- This would define \c struct \c entry_list, intended to hold a list of
- type \c struct \c entry.
-*/
-#ifndef AST_RWLOCK_INIT_VALUE
-#define AST_RWLIST_HEAD_STATIC(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
- ast_rwlock_t lock; \
-} name; \
-static void __attribute__ ((constructor)) init_##name(void) \
-{ \
- AST_RWLIST_HEAD_INIT(&name); \
-} \
-static void __attribute__ ((destructor)) fini_##name(void) \
-{ \
- AST_RWLIST_HEAD_DESTROY(&name); \
-} \
-struct __dummy_##name
-#else
-#define AST_RWLIST_HEAD_STATIC(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
- ast_rwlock_t lock; \
-} name = AST_RWLIST_HEAD_INIT_VALUE
-#endif
-
-/*!
- \brief Defines a structure to be used to hold a list of specified type, statically initialized.
-
- This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
-*/
-#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
-struct name { \
- struct type *first; \
- struct type *last; \
-} name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
-
-/*!
- \brief Initializes a list head structure with a specified first entry.
- \param head This is a pointer to the list head structure
- \param entry pointer to the list entry that will become the head of the list
-
- This macro initializes a list head structure by setting the head
- entry to the supplied value and recreating the embedded lock.
-*/
-#define AST_LIST_HEAD_SET(head, entry) do { \
- (head)->first = (entry); \
- (head)->last = (entry); \
- ast_mutex_init(&(head)->lock); \
-} while (0)
-
-/*!
- \brief Initializes an rwlist head structure with a specified first entry.
- \param head This is a pointer to the list head structure
- \param entry pointer to the list entry that will become the head of the list
-
- This macro initializes a list head structure by setting the head
- entry to the supplied value and recreating the embedded lock.
-*/
-#define AST_RWLIST_HEAD_SET(head, entry) do { \
- (head)->first = (entry); \
- (head)->last = (entry); \
- ast_rwlock_init(&(head)->lock); \
-} while (0)
-
-/*!
- \brief Initializes a list head structure with a specified first entry.
- \param head This is a pointer to the list head structure
- \param entry pointer to the list entry that will become the head of the list
-
- This macro initializes a list head structure by setting the head
- entry to the supplied value.
-*/
-#define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
- (head)->first = (entry); \
- (head)->last = (entry); \
-} while (0)
-
-/*!
- \brief Declare a forward link structure inside a list entry.
- \param type This is the type of each list entry.
-
- This macro declares a structure to be used to link list entries together.
- It must be used inside the definition of the structure named in
- \a type, as follows:
-
- \code
- struct list_entry {
- ...
- AST_LIST_ENTRY(list_entry) list;
- }
- \endcode
-
- The field name \a list here is arbitrary, and can be anything you wish.
-*/
-#define AST_LIST_ENTRY(type) \
-struct { \
- struct type *next; \
-}
-
-#define AST_RWLIST_ENTRY AST_LIST_ENTRY
-
-/*!
- \brief Returns the first entry contained in a list.
- \param head This is a pointer to the list head structure
- */
-#define AST_LIST_FIRST(head) ((head)->first)
-
-#define AST_RWLIST_FIRST AST_LIST_FIRST
-
-/*!
- \brief Returns the last entry contained in a list.
- \param head This is a pointer to the list head structure
- */
-#define AST_LIST_LAST(head) ((head)->last)
-
-#define AST_RWLIST_LAST AST_LIST_LAST
-
-/*!
- \brief Returns the next entry in the list after the given entry.
- \param elm This is a pointer to the current entry.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-*/
-#define AST_LIST_NEXT(elm, field) ((elm)->field.next)
-
-#define AST_RWLIST_NEXT AST_LIST_NEXT
-
-/*!
- \brief Checks whether the specified list contains any entries.
- \param head This is a pointer to the list head structure
-
- Returns non-zero if the list has entries, zero if not.
- */
-#define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
-
-#define AST_RWLIST_EMPTY AST_LIST_EMPTY
-
-/*!
- \brief Loops over (traverses) the entries in a list.
- \param head This is a pointer to the list head structure
- \param var This is the name of the variable that will hold a pointer to the
- current list entry on each iteration. It must be declared before calling
- this macro.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- This macro is use to loop over (traverse) the entries in a list. It uses a
- \a for loop, and supplies the enclosed code with a pointer to each list
- entry as it loops. It is typically used as follows:
- \code
- static AST_LIST_HEAD(entry_list, list_entry) entries;
- ...
- struct list_entry {
- ...
- AST_LIST_ENTRY(list_entry) list;
- }
- ...
- struct list_entry *current;
- ...
- AST_LIST_TRAVERSE(&entries, current, list) {
- (do something with current here)
- }
- \endcode
- \warning If you modify the forward-link pointer contained in the \a current entry while
- inside the loop, the behavior will be unpredictable. At a minimum, the following
- macros will modify the forward-link pointer, and should not be used inside
- AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
- careful consideration of their consequences:
- \li AST_LIST_NEXT() (when used as an lvalue)
- \li AST_LIST_INSERT_AFTER()
- \li AST_LIST_INSERT_HEAD()
- \li AST_LIST_INSERT_TAIL()
-*/
-#define AST_LIST_TRAVERSE(head,var,field) \
- for((var) = (head)->first; (var); (var) = (var)->field.next)
-
-#define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
-
-/*!
- \brief Loops safely over (traverses) the entries in a list.
- \param head This is a pointer to the list head structure
- \param var This is the name of the variable that will hold a pointer to the
- current list entry on each iteration. It must be declared before calling
- this macro.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- This macro is used to safely loop over (traverse) the entries in a list. It
- uses a \a for loop, and supplies the enclosed code with a pointer to each list
- entry as it loops. It is typically used as follows:
-
- \code
- static AST_LIST_HEAD(entry_list, list_entry) entries;
- ...
- struct list_entry {
- ...
- AST_LIST_ENTRY(list_entry) list;
- }
- ...
- struct list_entry *current;
- ...
- AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
- (do something with current here)
- }
- AST_LIST_TRAVERSE_SAFE_END;
- \endcode
-
- It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
- (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
- the \a current pointer without affecting the loop traversal.
-*/
-#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
- typeof((head)->first) __list_next; \
- typeof((head)->first) __list_prev = NULL; \
- typeof((head)->first) __new_prev = NULL; \
- for ((var) = (head)->first, __new_prev = (var), \
- __list_next = (var) ? (var)->field.next : NULL; \
- (var); \
- __list_prev = __new_prev, (var) = __list_next, \
- __new_prev = (var), \
- __list_next = (var) ? (var)->field.next : NULL \
- )
-
-#define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
-
-/*!
- \brief Removes the \a current entry from a list during a traversal.
- \param head This is a pointer to the list head structure
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
- block; it is used to unlink the current entry from the list without affecting
- the list traversal (and without having to re-traverse the list to modify the
- previous entry, if any).
- */
-#define AST_LIST_REMOVE_CURRENT(head, field) do { \
- __new_prev->field.next = NULL; \
- __new_prev = __list_prev; \
- if (__list_prev) \
- __list_prev->field.next = __list_next; \
- else \
- (head)->first = __list_next; \
- if (!__list_next) \
- (head)->last = __list_prev; \
- } while (0)
-
-#define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
-
-/*!
- \brief Inserts a list entry before the current entry during a traversal.
- \param head This is a pointer to the list head structure
- \param elm This is a pointer to the entry to be inserted.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
- block.
- */
-#define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
- if (__list_prev) { \
- (elm)->field.next = __list_prev->field.next; \
- __list_prev->field.next = elm; \
- } else { \
- (elm)->field.next = (head)->first; \
- (head)->first = (elm); \
- } \
- __new_prev = (elm); \
-} while (0)
-
-#define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
-
-/*!
- \brief Closes a safe loop traversal block.
- */
-#define AST_LIST_TRAVERSE_SAFE_END }
-
-#define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
-
-/*!
- \brief Initializes a list head structure.
- \param head This is a pointer to the list head structure
-
- This macro initializes a list head structure by setting the head
- entry to \a NULL (empty list) and recreating the embedded lock.
-*/
-#define AST_LIST_HEAD_INIT(head) { \
- (head)->first = NULL; \
- (head)->last = NULL; \
- ast_mutex_init(&(head)->lock); \
-}
-
-/*!
- \brief Initializes an rwlist head structure.
- \param head This is a pointer to the list head structure
-
- This macro initializes a list head structure by setting the head
- entry to \a NULL (empty list) and recreating the embedded lock.
-*/
-#define AST_RWLIST_HEAD_INIT(head) { \
- (head)->first = NULL; \
- (head)->last = NULL; \
- ast_rwlock_init(&(head)->lock); \
-}
-
-/*!
- \brief Destroys a list head structure.
- \param head This is a pointer to the list head structure
-
- This macro destroys a list head structure by setting the head
- entry to \a NULL (empty list) and destroying the embedded lock.
- It does not free the structure from memory.
-*/
-#define AST_LIST_HEAD_DESTROY(head) { \
- (head)->first = NULL; \
- (head)->last = NULL; \
- ast_mutex_destroy(&(head)->lock); \
-}
-
-/*!
- \brief Destroys an rwlist head structure.
- \param head This is a pointer to the list head structure
-
- This macro destroys a list head structure by setting the head
- entry to \a NULL (empty list) and destroying the embedded lock.
- It does not free the structure from memory.
-*/
-#define AST_RWLIST_HEAD_DESTROY(head) { \
- (head)->first = NULL; \
- (head)->last = NULL; \
- ast_rwlock_destroy(&(head)->lock); \
-}
-
-/*!
- \brief Initializes a list head structure.
- \param head This is a pointer to the list head structure
-
- This macro initializes a list head structure by setting the head
- entry to \a NULL (empty list). There is no embedded lock handling
- with this macro.
-*/
-#define AST_LIST_HEAD_INIT_NOLOCK(head) { \
- (head)->first = NULL; \
- (head)->last = NULL; \
-}
-
-/*!
- \brief Inserts a list entry after a given entry.
- \param head This is a pointer to the list head structure
- \param listelm This is a pointer to the entry after which the new entry should
- be inserted.
- \param elm This is a pointer to the entry to be inserted.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
- */
-#define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.next = (listelm)->field.next; \
- (listelm)->field.next = (elm); \
- if ((head)->last == (listelm)) \
- (head)->last = (elm); \
-} while (0)
-
-#define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
-
-/*!
- \brief Inserts a list entry at the head of a list.
- \param head This is a pointer to the list head structure
- \param elm This is a pointer to the entry to be inserted.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
- */
-#define AST_LIST_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.next = (head)->first; \
- (head)->first = (elm); \
- if (!(head)->last) \
- (head)->last = (elm); \
-} while (0)
-
-#define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
-
-/*!
- \brief Appends a list entry to the tail of a list.
- \param head This is a pointer to the list head structure
- \param elm This is a pointer to the entry to be appended.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- Note: The link field in the appended entry is \b not modified, so if it is
- actually the head of a list itself, the entire list will be appended
- temporarily (until the next AST_LIST_INSERT_TAIL is performed).
- */
-#define AST_LIST_INSERT_TAIL(head, elm, field) do { \
- if (!(head)->first) { \
- (head)->first = (elm); \
- (head)->last = (elm); \
- } else { \
- (head)->last->field.next = (elm); \
- (head)->last = (elm); \
- } \
-} while (0)
-
-#define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
-
-/*!
- \brief Appends a whole list to the tail of a list.
- \param head This is a pointer to the list head structure
- \param list This is a pointer to the list to be appended.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- Note: The source list (the \a list parameter) will be empty after
- calling this macro (the list entries are \b moved to the target list).
- */
-#define AST_LIST_APPEND_LIST(head, list, field) do { \
- if (!(head)->first) { \
- (head)->first = (list)->first; \
- (head)->last = (list)->last; \
- } else { \
- (head)->last->field.next = (list)->first; \
- (head)->last = (list)->last; \
- } \
- (list)->first = NULL; \
- (list)->last = NULL; \
-} while (0)
-
-#define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
-
-/*!
- \brief Removes and returns the head entry from a list.
- \param head This is a pointer to the list head structure
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
-
- Removes the head entry from the list, and returns a pointer to it.
- This macro is safe to call on an empty list.
- */
-#define AST_LIST_REMOVE_HEAD(head, field) ({ \
- typeof((head)->first) cur = (head)->first; \
- if (cur) { \
- (head)->first = cur->field.next; \
- cur->field.next = NULL; \
- if ((head)->last == cur) \
- (head)->last = NULL; \
- } \
- cur; \
- })
-
-#define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
-
-/*!
- \brief Removes a specific entry from a list.
- \param head This is a pointer to the list head structure
- \param elm This is a pointer to the entry to be removed.
- \param field This is the name of the field (declared using AST_LIST_ENTRY())
- used to link entries of this list together.
- \warning The removed entry is \b not freed nor modified in any way.
- */
-#define AST_LIST_REMOVE(head, elm, field) ({ \
- __typeof(elm) __res = NULL; \
- if ((head)->first == (elm)) { \
- __res = (head)->first; \
- (head)->first = (elm)->field.next; \
- if ((head)->last == (elm)) \
- (head)->last = NULL; \
- } else { \
- typeof(elm) curelm = (head)->first; \
- while (curelm && (curelm->field.next != (elm))) \
- curelm = curelm->field.next; \
- if (curelm) { \
- __res = (elm); \
- curelm->field.next = (elm)->field.next; \
- if ((head)->last == (elm)) \
- (head)->last = curelm; \
- } \
- } \
- (elm)->field.next = NULL; \
- (__res); \
-})
-
-#define AST_RWLIST_REMOVE AST_LIST_REMOVE
-
-#endif /* _ASTERISK_LINKEDLISTS_H */
diff --git a/1.4/include/asterisk/localtime.h b/1.4/include/asterisk/localtime.h
deleted file mode 100644
index 313a8ddb6..000000000
--- a/1.4/include/asterisk/localtime.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Tilghman Lesher <tlesher@vcch.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.
- */
-
-/*! \file
- * \brief Custom localtime functions for multiple timezones
- */
-
-#ifndef _ASTERISK_LOCALTIME_H
-#define _ASTERISK_LOCALTIME_H
-
-struct tm *ast_localtime(const time_t *timep, struct tm *p_tm, const char *zone);
-time_t ast_mktime(struct tm * const tmp, const char *zone);
-
-#endif /* _ASTERISK_LOCALTIME_H */
diff --git a/1.4/include/asterisk/lock.h b/1.4/include/asterisk/lock.h
deleted file mode 100644
index cc68a13aa..000000000
--- a/1.4/include/asterisk/lock.h
+++ /dev/null
@@ -1,1213 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief General Asterisk channel locking definitions.
- *
- * - See \ref LockDef
- */
-
-/*! \page LockDef Asterisk thread locking models
- *
- * This file provides different implementation of the functions,
- * depending on the platform, the use of DEBUG_THREADS, and the way
- * module-level mutexes are initialized.
- *
- * - \b static: the mutex is assigned the value AST_MUTEX_INIT_VALUE
- * this is done at compile time, and is the way used on Linux.
- * This method is not applicable to all platforms e.g. when the
- * initialization needs that some code is run.
- *
- * - \b through constructors: for each mutex, a constructor function is
- * defined, which then runs when the program (or the module)
- * starts. The problem with this approach is that there is a
- * lot of code duplication (a new block of code is created for
- * each mutex). Also, it does not prevent a user from declaring
- * a global mutex without going through the wrapper macros,
- * so sane programming practices are still required.
- */
-
-#ifndef _ASTERISK_LOCK_H
-#define _ASTERISK_LOCK_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <time.h>
-#include <sys/param.h>
-
-#include "asterisk/logger.h"
-
-/* internal macro to profile mutexes. Only computes the delay on
- * non-blocking calls.
- */
-#ifndef HAVE_MTX_PROFILE
-#define __MTX_PROF(a) return pthread_mutex_lock((a))
-#else
-#define __MTX_PROF(a) do { \
- int i; \
- /* profile only non-blocking events */ \
- ast_mark(mtx_prof, 1); \
- i = pthread_mutex_trylock((a)); \
- ast_mark(mtx_prof, 0); \
- if (!i) \
- return i; \
- else \
- return pthread_mutex_lock((a)); \
- } while (0)
-#endif /* HAVE_MTX_PROFILE */
-
-#define AST_PTHREADT_NULL (pthread_t) -1
-#define AST_PTHREADT_STOP (pthread_t) -2
-
-#if defined(SOLARIS) || defined(BSD)
-#define AST_MUTEX_INIT_W_CONSTRUCTORS
-#endif /* SOLARIS || BSD */
-
-/* Asterisk REQUIRES recursive (not error checking) mutexes
- and will not run without them. */
-#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
-#define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
-#else
-#define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
-#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
-#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
-
-#ifdef DEBUG_THREADS
-
-#define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
-
-#ifdef THREAD_CRASH
-#define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
-#else
-#define DO_THREAD_CRASH do { } while (0)
-#endif
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
-#define AST_MUTEX_INIT_VALUE_NOTRACKING \
- { PTHREAD_MUTEX_INIT_VALUE, 0, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
-
-#define AST_MAX_REENTRANCY 10
-
-struct ast_mutex_info {
- pthread_mutex_t mutex;
- /*! Track which thread holds this lock */
- unsigned int track:1;
- const char *file[AST_MAX_REENTRANCY];
- int lineno[AST_MAX_REENTRANCY];
- int reentrancy;
- const char *func[AST_MAX_REENTRANCY];
- pthread_t thread[AST_MAX_REENTRANCY];
- pthread_mutex_t reentr_mutex;
-};
-
-typedef struct ast_mutex_info ast_mutex_t;
-
-typedef pthread_cond_t ast_cond_t;
-
-static pthread_mutex_t empty_mutex;
-
-enum ast_lock_type {
- AST_MUTEX,
- AST_RDLOCK,
- AST_WRLOCK,
-};
-
-/*!
- * \brief Store lock info for the current thread
- *
- * This function gets called in ast_mutex_lock() and ast_mutex_trylock() so
- * that information about this lock can be stored in this thread's
- * lock info struct. The lock is marked as pending as the thread is waiting
- * on the lock. ast_mark_lock_acquired() will mark it as held by this thread.
- */
-#if !defined(LOW_MEMORY)
-void ast_store_lock_info(enum ast_lock_type type, const char *filename,
- int line_num, const char *func, const char *lock_name, void *lock_addr);
-#else
-#define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS)
-#endif
-
-
-/*!
- * \brief Mark the last lock as acquired
- */
-#if !defined(LOW_MEMORY)
-void ast_mark_lock_acquired(void *lock_addr);
-#else
-#define ast_mark_lock_acquired(ignore)
-#endif
-
-/*!
- * \brief Mark the last lock as failed (trylock)
- */
-#if !defined(LOW_MEMORY)
-void ast_mark_lock_failed(void *lock_addr);
-#else
-#define ast_mark_lock_failed(ignore)
-#endif
-
-/*!
- * \brief remove lock info for the current thread
- *
- * this gets called by ast_mutex_unlock so that information on the lock can
- * be removed from the current thread's lock info struct.
- */
-#if !defined(LOW_MEMORY)
-void ast_remove_lock_info(void *lock_addr);
-#else
-#define ast_remove_lock_info(ignore)
-#endif
-
-static void __attribute__((constructor)) init_empty_mutex(void)
-{
- memset(&empty_mutex, 0, sizeof(empty_mutex));
-}
-
-static inline void ast_reentrancy_lock(ast_mutex_t *p_ast_mutex)
-{
- pthread_mutex_lock(&p_ast_mutex->reentr_mutex);
-}
-
-static inline void ast_reentrancy_unlock(ast_mutex_t *p_ast_mutex)
-{
- pthread_mutex_unlock(&p_ast_mutex->reentr_mutex);
-}
-
-static inline void ast_reentrancy_init(ast_mutex_t *p_ast_mutex)
-{
- int i;
- pthread_mutexattr_t reentr_attr;
-
- for (i = 0; i < AST_MAX_REENTRANCY; i++) {
- p_ast_mutex->file[i] = NULL;
- p_ast_mutex->lineno[i] = 0;
- p_ast_mutex->func[i] = NULL;
- p_ast_mutex->thread[i] = 0;
- }
-
- p_ast_mutex->reentrancy = 0;
-
- pthread_mutexattr_init(&reentr_attr);
- pthread_mutexattr_settype(&reentr_attr, AST_MUTEX_KIND);
- pthread_mutex_init(&p_ast_mutex->reentr_mutex, &reentr_attr);
- pthread_mutexattr_destroy(&reentr_attr);
-}
-
-static inline void delete_reentrancy_cs(ast_mutex_t * p_ast_mutex)
-{
- pthread_mutex_destroy(&p_ast_mutex->reentr_mutex);
-}
-
-static inline int __ast_pthread_mutex_init(int track, const char *filename, int lineno, const char *func,
- const char *mutex_name, ast_mutex_t *t)
-{
- int res;
- pthread_mutexattr_t attr;
-
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
-
- if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
-/*
- int canlog = strcmp(filename, "logger.c") & track;
- __ast_mutex_logger("%s line %d (%s): NOTICE: mutex '%s' is already initialized.\n",
- filename, lineno, func, mutex_name);
- DO_THREAD_CRASH;
-*/
- return 0;
- }
-
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_reentrancy_init(t);
- t->track = track;
-
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
-
- res = pthread_mutex_init(&t->mutex, &attr);
- pthread_mutexattr_destroy(&attr);
- return res;
-}
-
-#define ast_mutex_init(pmutex) __ast_pthread_mutex_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
-#define ast_mutex_init_notracking(pmutex) \
- __ast_pthread_mutex_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
-
-static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
- const char *mutex_name, ast_mutex_t *t)
-{
- int res;
- int canlog = strcmp(filename, "logger.c") & t->track;
-
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- /* Don't try to uninitialize non initialized mutex
- * This may no effect on linux
- * And always ganerate core on *BSD with
- * linked libpthread
- * This not error condition if the mutex created on the fly.
- */
- __ast_mutex_logger("%s line %d (%s): NOTICE: mutex '%s' is uninitialized.\n",
- filename, lineno, func, mutex_name);
- return 0;
- }
-#endif
-
- res = pthread_mutex_trylock(&t->mutex);
- switch (res) {
- case 0:
- pthread_mutex_unlock(&t->mutex);
- break;
- case EINVAL:
- __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
- filename, lineno, func, mutex_name);
- break;
- case EBUSY:
- __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
- filename, lineno, func, mutex_name);
- ast_reentrancy_lock(t);
- __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
- t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
- ast_reentrancy_unlock(t);
- break;
- }
-
- if ((res = pthread_mutex_destroy(&t->mutex)))
- __ast_mutex_logger("%s line %d (%s): Error destroying mutex %s: %s\n",
- filename, lineno, func, mutex_name, strerror(res));
-#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
- else
- t->mutex = PTHREAD_MUTEX_INIT_VALUE;
-#endif
- ast_reentrancy_lock(t);
- t->file[0] = filename;
- t->lineno[0] = lineno;
- t->func[0] = func;
- t->reentrancy = 0;
- t->thread[0] = 0;
- ast_reentrancy_unlock(t);
- delete_reentrancy_cs(t);
-
- return res;
-}
-
-static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
- const char* mutex_name, ast_mutex_t *t)
-{
- int res;
- int canlog = strcmp(filename, "logger.c") & t->track;
-
-#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- /* Don't warn abount uninitialized mutex.
- * Simple try to initialize it.
- * May be not needed in linux system.
- */
- res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
- filename, lineno, func, mutex_name);
- return res;
- }
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- if (t->track)
- ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
-
-#ifdef DETECT_DEADLOCKS
- {
- time_t seconds = time(NULL);
- time_t wait_time, reported_wait = 0;
- do {
-#ifdef HAVE_MTX_PROFILE
- ast_mark(mtx_prof, 1);
-#endif
- res = pthread_mutex_trylock(&t->mutex);
-#ifdef HAVE_MTX_PROFILE
- ast_mark(mtx_prof, 0);
-#endif
- if (res == EBUSY) {
- wait_time = time(NULL) - seconds;
- if (wait_time > reported_wait && (wait_time % 5) == 0) {
- __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
- filename, lineno, func, (int) wait_time, mutex_name);
- ast_reentrancy_lock(t);
- __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
- t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
- t->func[t->reentrancy-1], mutex_name);
- ast_reentrancy_unlock(t);
- reported_wait = wait_time;
- }
- usleep(200);
- }
- } while (res == EBUSY);
- }
-#else
-#ifdef HAVE_MTX_PROFILE
- ast_mark(mtx_prof, 1);
- res = pthread_mutex_trylock(&t->mutex);
- ast_mark(mtx_prof, 0);
- if (res)
-#endif
- res = pthread_mutex_lock(&t->mutex);
-#endif /* DETECT_DEADLOCKS */
-
- if (!res) {
- ast_reentrancy_lock(t);
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = filename;
- t->lineno[t->reentrancy] = lineno;
- t->func[t->reentrancy] = func;
- t->thread[t->reentrancy] = pthread_self();
- t->reentrancy++;
- } else {
- __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
- filename, lineno, func, mutex_name);
- }
- ast_reentrancy_unlock(t);
- if (t->track)
- ast_mark_lock_acquired(&t->mutex);
- } else {
- if (t->track)
- ast_remove_lock_info(&t->mutex);
- __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
- filename, lineno, func, strerror(res));
- DO_THREAD_CRASH;
- }
-
- return res;
-}
-
-static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
- const char* mutex_name, ast_mutex_t *t)
-{
- int res;
- int canlog = strcmp(filename, "logger.c") & t->track;
-
-#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- /* Don't warn abount uninitialized mutex.
- * Simple try to initialize it.
- * May be not needed in linux system.
- */
- res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
- filename, lineno, func, mutex_name);
- return res;
- }
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- if (t->track)
- ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
-
- if (!(res = pthread_mutex_trylock(&t->mutex))) {
- ast_reentrancy_lock(t);
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = filename;
- t->lineno[t->reentrancy] = lineno;
- t->func[t->reentrancy] = func;
- t->thread[t->reentrancy] = pthread_self();
- t->reentrancy++;
- } else {
- __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
- filename, lineno, func, mutex_name);
- }
- ast_reentrancy_unlock(t);
- if (t->track)
- ast_mark_lock_acquired(&t->mutex);
- } else if (t->track) {
- ast_mark_lock_failed(&t->mutex);
- }
-
- return res;
-}
-
-static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
- const char *mutex_name, ast_mutex_t *t)
-{
- int res;
- int canlog = strcmp(filename, "logger.c") & t->track;
-
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
- filename, lineno, func, mutex_name);
- res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
- filename, lineno, func, mutex_name);
- }
- return res;
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_reentrancy_lock(t);
- if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
- __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
- filename, lineno, func, mutex_name);
- __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
- t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
- DO_THREAD_CRASH;
- }
-
- if (--t->reentrancy < 0) {
- __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
- filename, lineno, func, mutex_name);
- t->reentrancy = 0;
- }
-
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = NULL;
- t->lineno[t->reentrancy] = 0;
- t->func[t->reentrancy] = NULL;
- t->thread[t->reentrancy] = 0;
- }
- ast_reentrancy_unlock(t);
-
- if (t->track)
- ast_remove_lock_info(&t->mutex);
-
- if ((res = pthread_mutex_unlock(&t->mutex))) {
- __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n",
- filename, lineno, func, strerror(res));
- DO_THREAD_CRASH;
- }
-
- return res;
-}
-
-static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
- const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
-{
- return pthread_cond_init(cond, cond_attr);
-}
-
-static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
- const char *cond_name, ast_cond_t *cond)
-{
- return pthread_cond_signal(cond);
-}
-
-static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
- const char *cond_name, ast_cond_t *cond)
-{
- return pthread_cond_broadcast(cond);
-}
-
-static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
- const char *cond_name, ast_cond_t *cond)
-{
- return pthread_cond_destroy(cond);
-}
-
-static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
- const char *cond_name, const char *mutex_name,
- ast_cond_t *cond, ast_mutex_t *t)
-{
- int res;
- int canlog = strcmp(filename, "logger.c") & t->track;
-
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
- filename, lineno, func, mutex_name);
- res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
- filename, lineno, func, mutex_name);
- }
- return res;
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_reentrancy_lock(t);
- if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
- __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
- filename, lineno, func, mutex_name);
- __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
- t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
- DO_THREAD_CRASH;
- }
-
- if (--t->reentrancy < 0) {
- __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
- filename, lineno, func, mutex_name);
- t->reentrancy = 0;
- }
-
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = NULL;
- t->lineno[t->reentrancy] = 0;
- t->func[t->reentrancy] = NULL;
- t->thread[t->reentrancy] = 0;
- }
- ast_reentrancy_unlock(t);
-
- if (t->track)
- ast_remove_lock_info(&t->mutex);
-
- if ((res = pthread_cond_wait(cond, &t->mutex))) {
- __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
- filename, lineno, func, strerror(res));
- DO_THREAD_CRASH;
- } else {
- ast_reentrancy_lock(t);
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = filename;
- t->lineno[t->reentrancy] = lineno;
- t->func[t->reentrancy] = func;
- t->thread[t->reentrancy] = pthread_self();
- t->reentrancy++;
- } else {
- __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
- filename, lineno, func, mutex_name);
- }
- ast_reentrancy_unlock(t);
-
- if (t->track)
- ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
- }
-
- return res;
-}
-
-static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
- const char *cond_name, const char *mutex_name, ast_cond_t *cond,
- ast_mutex_t *t, const struct timespec *abstime)
-{
- int res;
- int canlog = strcmp(filename, "logger.c") & t->track;
-
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
- filename, lineno, func, mutex_name);
- res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
- if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
- __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
- filename, lineno, func, mutex_name);
- }
- return res;
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_reentrancy_lock(t);
- if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
- __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
- filename, lineno, func, mutex_name);
- __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
- t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
- DO_THREAD_CRASH;
- }
-
- if (--t->reentrancy < 0) {
- __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
- filename, lineno, func, mutex_name);
- t->reentrancy = 0;
- }
-
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = NULL;
- t->lineno[t->reentrancy] = 0;
- t->func[t->reentrancy] = NULL;
- t->thread[t->reentrancy] = 0;
- }
- ast_reentrancy_unlock(t);
-
- if (t->track)
- ast_remove_lock_info(&t->mutex);
-
- if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
- __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
- filename, lineno, func, strerror(res));
- DO_THREAD_CRASH;
- } else {
- ast_reentrancy_lock(t);
- if (t->reentrancy < AST_MAX_REENTRANCY) {
- t->file[t->reentrancy] = filename;
- t->lineno[t->reentrancy] = lineno;
- t->func[t->reentrancy] = func;
- t->thread[t->reentrancy] = pthread_self();
- t->reentrancy++;
- } else {
- __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
- filename, lineno, func, mutex_name);
- }
- ast_reentrancy_unlock(t);
-
- if (t->track)
- ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
- }
-
- return res;
-}
-
-#define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
-#define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
-#define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
-#define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
-#define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
-#define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
-#define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
-#define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
-#define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
-#define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
-
-#else /* !DEBUG_THREADS */
-
-
-typedef pthread_mutex_t ast_mutex_t;
-
-#define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
-#define AST_MUTEX_INIT_VALUE_NOTRACKING \
- ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
-
-#define ast_mutex_init_notracking(m) ast_mutex_init(m)
-
-static inline int ast_mutex_init(ast_mutex_t *pmutex)
-{
- int res;
- pthread_mutexattr_t attr;
-
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
-
- res = pthread_mutex_init(pmutex, &attr);
- pthread_mutexattr_destroy(&attr);
- return res;
-}
-
-#define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
-
-static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
-{
- return pthread_mutex_unlock(pmutex);
-}
-
-static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
-{
- return pthread_mutex_destroy(pmutex);
-}
-
-static inline int ast_mutex_lock(ast_mutex_t *pmutex)
-{
- __MTX_PROF(pmutex);
-}
-
-static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
-{
- return pthread_mutex_trylock(pmutex);
-}
-
-typedef pthread_cond_t ast_cond_t;
-
-static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
-{
- return pthread_cond_init(cond, cond_attr);
-}
-
-static inline int ast_cond_signal(ast_cond_t *cond)
-{
- return pthread_cond_signal(cond);
-}
-
-static inline int ast_cond_broadcast(ast_cond_t *cond)
-{
- return pthread_cond_broadcast(cond);
-}
-
-static inline int ast_cond_destroy(ast_cond_t *cond)
-{
- return pthread_cond_destroy(cond);
-}
-
-static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
-{
- return pthread_cond_wait(cond, t);
-}
-
-static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
-{
- return pthread_cond_timedwait(cond, t, abstime);
-}
-
-#endif /* !DEBUG_THREADS */
-
-#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
-/* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
- destructors to destroy mutexes and create it on the fly. */
-#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) \
- scope ast_mutex_t mutex = init_val; \
-static void __attribute__ ((constructor)) init_##mutex(void) \
-{ \
- if (track) \
- ast_mutex_init(&mutex); \
- else \
- ast_mutex_init_notracking(&mutex); \
-} \
-static void __attribute__ ((destructor)) fini_##mutex(void) \
-{ \
- ast_mutex_destroy(&mutex); \
-}
-#else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
-/* By default, use static initialization of mutexes. */
-#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) \
- scope ast_mutex_t mutex = init_val
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
-#define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
-#define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
-#define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
-#define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
-#define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
-#define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
-#define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
-#define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
-#define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
-#define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
-#define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
-#define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
-#define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
-
-#define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE, 1)
-#define AST_MUTEX_DEFINE_STATIC_NOTRACKING(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE_NOTRACKING, 0)
-
-#define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
-
-#define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
-
-#ifndef __linux__
-#define pthread_create __use_ast_pthread_create_instead__
-#endif
-
-typedef pthread_rwlock_t ast_rwlock_t;
-
-#ifdef HAVE_PTHREAD_RWLOCK_INITIALIZER
-#define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
-#else
-#define AST_RWLOCK_INIT_VALUE NULL
-#endif
-
-#ifdef DEBUG_THREADS
-
-#define ast_rwlock_init(rwlock) __ast_rwlock_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
-
-
-static inline int __ast_rwlock_init(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *prwlock)
-{
- int res;
- pthread_rwlockattr_t attr;
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- int canlog = strcmp(filename, "logger.c");
-
- if (*prwlock != ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is already initialized.\n",
- filename, lineno, func, rwlock_name);
- return 0;
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
- pthread_rwlockattr_init(&attr);
-
-#ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
- pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
-#endif
-
- res = pthread_rwlock_init(prwlock, &attr);
- pthread_rwlockattr_destroy(&attr);
- return res;
-}
-
-#define ast_rwlock_destroy(rwlock) __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
-
-static inline int __ast_rwlock_destroy(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *prwlock)
-{
- int res;
- int canlog = strcmp(filename, "logger.c");
-
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- if (*prwlock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is uninitialized.\n",
- filename, lineno, func, rwlock_name);
- return 0;
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- if ((res = pthread_rwlock_destroy(prwlock)))
- __ast_mutex_logger("%s line %d (%s): Error destroying rwlock %s: %s\n",
- filename, lineno, func, rwlock_name, strerror(res));
-
- return res;
-}
-
-#define ast_rwlock_unlock(a) \
- _ast_rwlock_unlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-static inline int _ast_rwlock_unlock(ast_rwlock_t *lock, const char *name,
- const char *file, int line, const char *func)
-{
- int res;
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- int canlog = strcmp(file, "logger.c");
-
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is uninitialized.\n",
- file, line, func, name);
- res = __ast_rwlock_init(file, line, func, name, lock);
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
- file, line, func, name);
- }
- return res;
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- res = pthread_rwlock_unlock(lock);
- ast_remove_lock_info(lock);
- return res;
-}
-
-#define ast_rwlock_rdlock(a) \
- _ast_rwlock_rdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-static inline int _ast_rwlock_rdlock(ast_rwlock_t *lock, const char *name,
- const char *file, int line, const char *func)
-{
- int res;
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- int canlog = strcmp(file, "logger.c");
-
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- /* Don't warn abount uninitialized lock.
- * Simple try to initialize it.
- * May be not needed in linux system.
- */
- res = __ast_rwlock_init(file, line, func, name, lock);
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
- file, line, func, name);
- return res;
- }
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
- res = pthread_rwlock_rdlock(lock);
- if (!res)
- ast_mark_lock_acquired(lock);
- else
- ast_remove_lock_info(lock);
- return res;
-}
-
-#define ast_rwlock_wrlock(a) \
- _ast_rwlock_wrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-static inline int _ast_rwlock_wrlock(ast_rwlock_t *lock, const char *name,
- const char *file, int line, const char *func)
-{
- int res;
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- int canlog = strcmp(file, "logger.c");
-
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- /* Don't warn abount uninitialized lock.
- * Simple try to initialize it.
- * May be not needed in linux system.
- */
- res = __ast_rwlock_init(file, line, func, name, lock);
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
- file, line, func, name);
- return res;
- }
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
- res = pthread_rwlock_wrlock(lock);
- if (!res)
- ast_mark_lock_acquired(lock);
- else
- ast_remove_lock_info(lock);
- return res;
-}
-
-#define ast_rwlock_tryrdlock(a) \
- _ast_rwlock_tryrdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-static inline int _ast_rwlock_tryrdlock(ast_rwlock_t *lock, const char *name,
- const char *file, int line, const char *func)
-{
- int res;
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- int canlog = strcmp(file, "logger.c");
-
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- /* Don't warn abount uninitialized lock.
- * Simple try to initialize it.
- * May be not needed in linux system.
- */
- res = __ast_rwlock_init(file, line, func, name, lock);
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
- file, line, func, name);
- return res;
- }
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
- res = pthread_rwlock_tryrdlock(lock);
- if (!res)
- ast_mark_lock_acquired(lock);
- else
- ast_remove_lock_info(lock);
- return res;
-}
-
-#define ast_rwlock_trywrlock(a) \
- _ast_rwlock_trywrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-static inline int _ast_rwlock_trywrlock(ast_rwlock_t *lock, const char *name,
- const char *file, int line, const char *func)
-{
- int res;
-#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
- int canlog = strcmp(file, "logger.c");
-
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- /* Don't warn abount uninitialized lock.
- * Simple try to initialize it.
- * May be not needed in linux system.
- */
- res = __ast_rwlock_init(file, line, func, name, lock);
- if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
- __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
- file, line, func, name);
- return res;
- }
- }
-#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
-
- ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
- res = pthread_rwlock_trywrlock(lock);
- if (!res)
- ast_mark_lock_acquired(lock);
- else
- ast_remove_lock_info(lock);
- return res;
-}
-
-#else /* !DEBUG_THREADS */
-
-static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
-{
- int res;
- pthread_rwlockattr_t attr;
-
- pthread_rwlockattr_init(&attr);
-
-#ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
- pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
-#endif
-
- res = pthread_rwlock_init(prwlock, &attr);
- pthread_rwlockattr_destroy(&attr);
- return res;
-}
-
-static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
-{
- return pthread_rwlock_destroy(prwlock);
-}
-
-static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
-{
- return pthread_rwlock_unlock(prwlock);
-}
-
-static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
-{
- return pthread_rwlock_rdlock(prwlock);
-}
-
-static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
-{
- return pthread_rwlock_tryrdlock(prwlock);
-}
-
-static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
-{
- return pthread_rwlock_wrlock(prwlock);
-}
-
-static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
-{
- return pthread_rwlock_trywrlock(prwlock);
-}
-#endif /* !DEBUG_THREADS */
-
-/* Statically declared read/write locks */
-
-#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
-#define __AST_RWLOCK_DEFINE(scope, rwlock) \
- scope ast_rwlock_t rwlock; \
-static void __attribute__ ((constructor)) init_##rwlock(void) \
-{ \
- ast_rwlock_init(&rwlock); \
-} \
-static void __attribute__ ((destructor)) fini_##rwlock(void) \
-{ \
- ast_rwlock_destroy(&rwlock); \
-}
-#else
-#define __AST_RWLOCK_DEFINE(scope, rwlock) \
- scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
-#endif
-
-#define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
-
-/*
- * Initial support for atomic instructions.
- * For platforms that have it, use the native cpu instruction to
- * implement them. For other platforms, resort to a 'slow' version
- * (defined in utils.c) that protects the atomic instruction with
- * a single lock.
- * The slow versions is always available, for testing purposes,
- * as ast_atomic_fetchadd_int_slow()
- */
-
-int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
-
-#include "asterisk/inline_api.h"
-
-#if defined(HAVE_OSX_ATOMICS)
-#include "libkern/OSAtomic.h"
-#endif
-
-/*! \brief Atomically add v to *p and return * the previous value of *p.
- * This can be used to handle reference counts, and the return value
- * can be used to generate unique identifiers.
- */
-
-#if defined(HAVE_GCC_ATOMICS)
-AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
-{
- return __sync_fetch_and_add(p, v);
-})
-#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
-AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
-{
- return OSAtomicAdd32(v, (int32_t *) p) - v;
-})
-#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
-AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
-{
- return OSAtomicAdd64(v, (int64_t *) p) - v;
-#elif defined (__i386__)
-#ifdef sun
-AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
-{
- __asm __volatile (
- " lock; xaddl %0, %1 ; "
- : "+r" (v), /* 0 (result) */
- "=m" (*p) /* 1 */
- : "m" (*p)); /* 2 */
- return (v);
-})
-#else /* ifndef sun */
-AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
-{
- __asm __volatile (
- " lock xaddl %0, %1 ; "
- : "+r" (v), /* 0 (result) */
- "=m" (*p) /* 1 */
- : "m" (*p)); /* 2 */
- return (v);
-})
-#endif
-#else /* low performance version in utils.c */
-AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
-{
- return ast_atomic_fetchadd_int_slow(p, v);
-})
-#endif
-
-/*! \brief decrement *p by 1 and return true if the variable has reached 0.
- * Useful e.g. to check if a refcount has reached 0.
- */
-#if defined(HAVE_GCC_ATOMICS)
-AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
-{
- return __sync_sub_and_fetch(p, 1) == 0;
-})
-#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
-AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
-{
- return OSAtomicAdd32( -1, (int32_t *) p) == 0;
-})
-#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
-AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
-{
- return OSAtomicAdd64( -1, (int64_t *) p) == 0;
-#else
-AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
-{
- int a = ast_atomic_fetchadd_int(p, -1);
- return a == 1; /* true if the value is 0 now (so it was 1 previously) */
-})
-#endif
-
-#ifndef DEBUG_CHANNEL_LOCKS
-/*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined
- in the Makefile, print relevant output for debugging */
-#define ast_channel_lock(x) ast_mutex_lock(&x->lock)
-/*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
- in the Makefile, print relevant output for debugging */
-#define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
-/*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
- in the Makefile, print relevant output for debugging */
-#define ast_channel_trylock(x) ast_mutex_trylock(&x->lock)
-#else
-
-struct ast_channel;
-
-/*! \brief Lock AST channel (and print debugging output)
-\note You need to enable DEBUG_CHANNEL_LOCKS for this function */
-int ast_channel_lock(struct ast_channel *chan);
-
-/*! \brief Unlock AST channel (and print debugging output)
-\note You need to enable DEBUG_CHANNEL_LOCKS for this function
-*/
-int ast_channel_unlock(struct ast_channel *chan);
-
-/*! \brief Lock AST channel (and print debugging output)
-\note You need to enable DEBUG_CHANNEL_LOCKS for this function */
-int ast_channel_trylock(struct ast_channel *chan);
-#endif
-
-#endif /* _ASTERISK_LOCK_H */
diff --git a/1.4/include/asterisk/logger.h b/1.4/include/asterisk/logger.h
deleted file mode 100644
index 58bf1804b..000000000
--- a/1.4/include/asterisk/logger.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*!
- \file logger.h
- \brief Support for logging to various files, console and syslog
- Configuration in file logger.conf
-*/
-
-#ifndef _ASTERISK_LOGGER_H
-#define _ASTERISK_LOGGER_H
-
-#include "asterisk/compat.h"
-
-#include <stdarg.h>
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define EVENTLOG "event_log"
-#define QUEUELOG "queue_log"
-
-#define DEBUG_M(a) { \
- a; \
-}
-
-#define VERBOSE_PREFIX_1 " "
-#define VERBOSE_PREFIX_2 " == "
-#define VERBOSE_PREFIX_3 " -- "
-#define VERBOSE_PREFIX_4 " > "
-
-/*! Used for sending a log message */
-/*!
- \brief This is the standard logger function. Probably the only way you will invoke it would be something like this:
- ast_log(LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10);
- where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending
- on which log you wish to output to. These are implemented as macros, that
- will provide the function with the needed arguments.
-
- \param level Type of log event
- \param file Will be provided by the LOG_* macro
- \param line Will be provided by the LOG_* macro
- \param function Will be provided by the LOG_* macro
- \param fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)
- */
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
- __attribute__ ((format (printf, 5, 6)));
-
-void ast_backtrace(void);
-
-/*! \brief Reload logger without rotating log files */
-int logger_reload(void);
-
-void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
- __attribute__ ((format (printf, 5, 6)));
-
-/*! Send a verbose message (based on verbose level)
- \brief This works like ast_log, but prints verbose messages to the console depending on verbosity level set.
- ast_verbose(VERBOSE_PREFIX_3 "Whatever %s is happening\n", "nothing");
- This will print the message to the console if the verbose level is set to a level >= 3
- Note the abscence of a comma after the VERBOSE_PREFIX_3. This is important.
- VERBOSE_PREFIX_1 through VERBOSE_PREFIX_3 are defined.
- */
-void ast_verbose(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-int ast_register_verbose(void (*verboser)(const char *string));
-int ast_unregister_verbose(void (*verboser)(const char *string));
-
-void ast_console_puts(const char *string);
-
-void ast_console_puts_mutable(const char *string);
-void ast_console_toggle_mute(int fd, int silent);
-
-#define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
-
-#ifdef LOG_DEBUG
-#undef LOG_DEBUG
-#endif
-#define __LOG_DEBUG 0
-#define LOG_DEBUG __LOG_DEBUG, _A_
-
-#ifdef LOG_EVENT
-#undef LOG_EVENT
-#endif
-#define __LOG_EVENT 1
-#define LOG_EVENT __LOG_EVENT, _A_
-
-#ifdef LOG_NOTICE
-#undef LOG_NOTICE
-#endif
-#define __LOG_NOTICE 2
-#define LOG_NOTICE __LOG_NOTICE, _A_
-
-#ifdef LOG_WARNING
-#undef LOG_WARNING
-#endif
-#define __LOG_WARNING 3
-#define LOG_WARNING __LOG_WARNING, _A_
-
-#ifdef LOG_ERROR
-#undef LOG_ERROR
-#endif
-#define __LOG_ERROR 4
-#define LOG_ERROR __LOG_ERROR, _A_
-
-#ifdef LOG_VERBOSE
-#undef LOG_VERBOSE
-#endif
-#define __LOG_VERBOSE 5
-#define LOG_VERBOSE __LOG_VERBOSE, _A_
-
-#ifdef LOG_DTMF
-#undef LOG_DTMF
-#endif
-#define __LOG_DTMF 6
-#define LOG_DTMF __LOG_DTMF, _A_
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_LOGGER_H */
diff --git a/1.4/include/asterisk/manager.h b/1.4/include/asterisk/manager.h
deleted file mode 100644
index cc4e971c9..000000000
--- a/1.4/include/asterisk/manager.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-#ifndef _ASTERISK_MANAGER_H
-#define _ASTERISK_MANAGER_H
-
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "asterisk/lock.h"
-
-/*!
- \file
- \brief The AMI - Asterisk Manager Interface - is a TCP protocol created to
- manage Asterisk with third-party software.
-
- Manager protocol packages are text fields of the form a: b. There is
- always exactly one space after the colon.
-
- The first header type is the "Event" header. Other headers vary from
- event to event. Headers end with standard \r\n termination.
- The last line of the manager response or event is an empty line.
- (\r\n)
-
- ** Please try to re-use existing headers to simplify manager message parsing in clients.
- Don't re-use an existing header with a new meaning, please.
- You can find a reference of standard headers in doc/manager.txt
- */
-
-#define DEFAULT_MANAGER_PORT 5038 /* Default port for Asterisk management via TCP */
-
-#define EVENT_FLAG_SYSTEM (1 << 0) /* System events such as module load/unload */
-#define EVENT_FLAG_CALL (1 << 1) /* Call event, such as state change, etc */
-#define EVENT_FLAG_LOG (1 << 2) /* Log events */
-#define EVENT_FLAG_VERBOSE (1 << 3) /* Verbose messages */
-#define EVENT_FLAG_COMMAND (1 << 4) /* Ability to read/set commands */
-#define EVENT_FLAG_AGENT (1 << 5) /* Ability to read/set agent info */
-#define EVENT_FLAG_USER (1 << 6) /* Ability to read/set user info */
-#define EVENT_FLAG_CONFIG (1 << 7) /* Ability to modify configurations */
-
-/* Export manager structures */
-#define AST_MAX_MANHEADERS 128
-
-struct mansession;
-
-struct message {
- unsigned int hdrcount;
- const char *headers[AST_MAX_MANHEADERS];
-};
-
-struct manager_action {
- /*! Name of the action */
- const char *action;
- /*! Short description of the action */
- const char *synopsis;
- /*! Detailed description of the action */
- const char *description;
- /*! Permission required for action. EVENT_FLAG_* */
- int authority;
- /*! Function to be called */
- int (*func)(struct mansession *s, const struct message *m);
- /*! For easy linking */
- struct manager_action *next;
-};
-
-/* External routines may register/unregister manager callbacks this way */
-#define ast_manager_register(a, b, c, d) ast_manager_register2(a, b, c, d, NULL)
-
-/* Use ast_manager_register2 to register with help text for new manager commands */
-
-/*! Register a manager command with the manager interface */
-/*! \param action Name of the requested Action:
- \param authority Required authority for this command
- \param func Function to call for this command
- \param synopsis Help text (one line, up to 30 chars) for CLI manager show commands
- \param description Help text, several lines
-*/
-int ast_manager_register2(
- const char *action,
- int authority,
- int (*func)(struct mansession *s, const struct message *m),
- const char *synopsis,
- const char *description);
-
-/*! Unregister a registred manager command */
-/*! \param action Name of registred Action:
-*/
-int ast_manager_unregister( char *action );
-
-/*!
- * \brief Verify a session's read permissions against a permission mask.
- * \param ident session identity
- * \param perm permission mask to verify
- * \returns 1 if the session has the permission mask capabilities, otherwise 0
- */
-int astman_verify_session_readpermissions(uint32_t ident, int perm);
-
-/*!
- * \brief Verify a session's write permissions against a permission mask.
- * \param ident session identity
- * \param perm permission mask to verify
- * \returns 1 if the session has the permission mask capabilities, otherwise 0
- */
-int astman_verify_session_writepermissions(uint32_t ident, int perm);
-
-/*! External routines may send asterisk manager events this way */
-/*! \param category Event category, matches manager authorization
- \param event Event name
- \param contents Contents of event
-*/
-int __attribute__ ((format (printf, 3,4))) manager_event(int category, const char *event, const char *contents, ...);
-
-/*! Get header from mananger transaction */
-const char *astman_get_header(const struct message *m, char *var);
-
-/*! Get a linked list of the Variable: headers */
-struct ast_variable *astman_get_variables(const struct message *m);
-
-/*! Send error in manager transaction */
-void astman_send_error(struct mansession *s, const struct message *m, char *error);
-void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg);
-void astman_send_ack(struct mansession *s, const struct message *m, char *msg);
-
-void __attribute__ ((format (printf, 2, 3))) astman_append(struct mansession *s, const char *fmt, ...);
-
-/*! Called by Asterisk initialization */
-int init_manager(void);
-int reload_manager(void);
-
-#endif /* _ASTERISK_MANAGER_H */
diff --git a/1.4/include/asterisk/md5.h b/1.4/include/asterisk/md5.h
deleted file mode 100644
index f738bd5b6..000000000
--- a/1.4/include/asterisk/md5.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*!\file
- * \brief MD5 digest functions
- */
-
-#ifndef _ASTERISK_MD5_H
-#define _ASTERISK_MD5_H
-
-#include <inttypes.h>
-
-struct MD5Context {
- uint32_t buf[4];
- uint32_t bits[2];
- unsigned char in[64];
-};
-
-void MD5Init(struct MD5Context *context);
-void MD5Update(struct MD5Context *context, unsigned char const *buf,
- unsigned len);
-void MD5Final(unsigned char digest[16], struct MD5Context *context);
-void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
-
-#endif /* _ASTERISK_MD5_H */
diff --git a/1.4/include/asterisk/module.h b/1.4/include/asterisk/module.h
deleted file mode 100644
index 4c1e40b1d..000000000
--- a/1.4/include/asterisk/module.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@digium.com>
- * Luigi Rizzo <rizzo@icir.org>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- * \brief Asterisk module definitions.
- *
- * This file contains the definitons for functions Asterisk modules should
- * provide and some other module related functions.
- */
-
-#ifndef _ASTERISK_MODULE_H
-#define _ASTERISK_MODULE_H
-
-#include "asterisk/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! \brief The text the key() function should return. */
-#define ASTERISK_GPL_KEY \
-"This paragraph is copyright (c) 2006 by Digium, Inc. \
-In order for your module to load, it must return this \
-key via a function called \"key\". Any code which \
-includes this paragraph must be licensed under the GNU \
-General Public License version 2 or later (at your \
-option). In addition to Digium's general reservations \
-of rights, Digium expressly reserves the right to \
-allow other parties to license this paragraph under \
-different terms. Any use of Digium, Inc. trademarks or \
-logos (including \"Asterisk\" or \"Digium\") without \
-express written permission of Digium, Inc. is prohibited.\n"
-
-#define AST_MODULE_CONFIG "modules.conf" /*!< \brief Module configuration file */
-
-enum ast_module_unload_mode {
- AST_FORCE_SOFT = 0, /*!< Softly unload a module, only if not in use */
- AST_FORCE_FIRM = 1, /*!< Firmly unload a module, even if in use */
- AST_FORCE_HARD = 2, /*!< as FIRM, plus dlclose() on the module. Not recommended
- as it may cause crashes */
-};
-
-enum ast_module_load_result {
- AST_MODULE_LOAD_SUCCESS = 0, /*!< Module loaded and configured */
- AST_MODULE_LOAD_DECLINE = 1, /*!< Module is not configured */
- AST_MODULE_LOAD_SKIP = 2, /*!< Module was skipped for some reason */
- AST_MODULE_LOAD_FAILURE = -1, /*!< Module could not be loaded properly */
-};
-
-/*!
- * \brief Load a module.
- * \param resource_name The name of the module to load.
- *
- * This function is run by the PBX to load the modules. It performs
- * all loading and initilization tasks. Basically, to load a module, just
- * give it the name of the module and it will do the rest.
- *
- * \return See possible enum values for ast_module_load_result.
- */
-enum ast_module_load_result ast_load_resource(const char *resource_name);
-
-/*!
- * \brief Unload a module.
- * \param resource_name The name of the module to unload.
- * \param ast_module_unload_mode The force flag. This should be set using one of the AST_FORCE flags.
- *
- * This function unloads a module. It will only unload modules that are not in
- * use (usecount not zero), unless #AST_FORCE_FIRM or #AST_FORCE_HARD is
- * specified. Setting #AST_FORCE_FIRM or #AST_FORCE_HARD will unload the
- * module regardless of consequences (NOT RECOMMENDED).
- *
- * \return Zero on success, -1 on error.
- */
-int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode);
-
-/*!
- * \brief Notify when usecount has been changed.
- *
- * This function calulates use counts and notifies anyone trying to keep track
- * of them. It should be called whenever your module's usecount changes.
- *
- * \note The LOCAL_USER macros take care of calling this function for you.
- */
-void ast_update_use_count(void);
-
-/*!
- * \brief Ask for a list of modules, descriptions, and use counts.
- * \param modentry A callback to an updater function.
- * \param like
- *
- * For each of the modules loaded, modentry will be executed with the resource,
- * description, and usecount values of each particular module.
- *
- * \return the number of modules loaded
- */
-int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
- const char *like);
-
-/*!
- * \brief Add a procedure to be run when modules have been updated.
- * \param updater The function to run when modules have been updated.
- *
- * This function adds the given function to a linked list of functions to be
- * run when the modules are updated.
- *
- * \return Zero on success and -1 on failure.
- */
-int ast_loader_register(int (*updater)(void));
-
-/*!
- * \brief Remove a procedure to be run when modules are updated.
- * \param updater The updater function to unregister.
- *
- * This removes the given function from the updater list.
- *
- * \return Zero on success, -1 on failure.
- */
-int ast_loader_unregister(int (*updater)(void));
-
-/*!
- * \brief Run the unload() callback for all loaded modules
- *
- * This function should be called when Asterisk is shutting down gracefully.
- */
-void ast_module_shutdown(void);
-
-/*!
- * \brief Match modules names for the Asterisk cli.
- * \param line Unused by this function, but this should be the line we are
- * matching.
- * \param word The partial name to match.
- * \param pos The position the word we are completing is in.
- * \param state The possible match to return.
- * \param rpos The position we should be matching. This should be the same as
- * pos.
- * \param needsreload This should be 1 if we need to reload this module and 0
- * otherwise. This function will only return modules that are reloadble
- * if this is 1.
- *
- * \return A possible completion of the partial match, or NULL if no matches
- * were found.
- */
-char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload);
-
-/* Opaque type for module handles generated by the loader */
-
-struct ast_module;
-
-/* User count routines keep track of which channels are using a given module
- resource. They can help make removing modules safer, particularly if
- they're in use at the time they have been requested to be removed */
-
-struct ast_module_user;
-struct ast_module_user_list;
-
-/*! \page ModMngmnt The Asterisk Module management interface
- *
- * All modules must implement the module API (load, unload...)
- * whose functions are exported through fields of a "struct module_symbol";
- */
-
-enum ast_module_flags {
- AST_MODFLAG_DEFAULT = 0,
- AST_MODFLAG_GLOBAL_SYMBOLS = (1 << 0),
- AST_MODFLAG_BUILDSUM = (1 << 1),
-};
-
-struct ast_module_info {
-
- /*!
- * The 'self' pointer for a module; it will be set by the loader before
- * it calls the module's load_module() entrypoint, and used by various
- * other macros that need to identify the module.
- */
-
- struct ast_module *self;
- enum ast_module_load_result (*load)(void); /* register stuff etc. Optional. */
- int (*reload)(void); /* config etc. Optional. */
- int (*unload)(void); /* unload. called with the module locked */
- const char *name; /* name of the module for loader reference and CLI commands */
- const char *description; /* user friendly description of the module. */
-
- /*!
- * This holds the ASTERISK_GPL_KEY, signifiying that you agree to the terms of
- * the Asterisk license as stated in the ASTERISK_GPL_KEY. Your module will not
- * load if it does not return the EXACT key string.
- */
-
- const char *key;
- unsigned int flags;
-
- /*! The value of AST_BUILDOPT_SUM when this module was compiled */
- const char buildopt_sum[33];
-};
-
-void ast_module_register(const struct ast_module_info *);
-void ast_module_unregister(const struct ast_module_info *);
-
-struct ast_module_user *__ast_module_user_add(struct ast_module *, struct ast_channel *);
-void __ast_module_user_remove(struct ast_module *, struct ast_module_user *);
-void __ast_module_user_hangup_all(struct ast_module *);
-
-#define ast_module_user_add(chan) __ast_module_user_add(ast_module_info->self, chan)
-#define ast_module_user_remove(user) __ast_module_user_remove(ast_module_info->self, user)
-#define ast_module_user_hangup_all() __ast_module_user_hangup_all(ast_module_info->self)
-
-struct ast_module *ast_module_ref(struct ast_module *);
-void ast_module_unref(struct ast_module *);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-#define AST_MODULE_INFO(keystr, flags_to_set, desc, load_func, unload_func, reload_func) \
- static struct ast_module_info __mod_info = { \
- NULL, \
- load_func, \
- reload_func, \
- unload_func, \
- AST_MODULE, \
- desc, \
- keystr, \
- flags_to_set | AST_MODFLAG_BUILDSUM, \
- AST_BUILDOPT_SUM, \
- }; \
- static void __attribute__ ((constructor)) __reg_module(void) \
- { \
- ast_module_register(&__mod_info); \
- } \
- static void __attribute__ ((destructor)) __unreg_module(void) \
- { \
- ast_module_unregister(&__mod_info); \
- } \
- const static __attribute__((unused)) struct ast_module_info *ast_module_info = &__mod_info
-
-#define AST_MODULE_INFO_STANDARD(keystr, desc) \
- AST_MODULE_INFO(keystr, AST_MODFLAG_DEFAULT, desc, \
- load_module, \
- unload_module, \
- NULL \
- )
-#else
-/* forward declare this pointer in modules, so that macro/function
- calls that need it can get it, since it will actually be declared
- and populated at the end of the module's source file... */
-const static __attribute__((unused)) struct ast_module_info *ast_module_info;
-
-#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...) \
- static struct ast_module_info __mod_info = { \
- .name = AST_MODULE, \
- .flags = flags_to_set | AST_MODFLAG_BUILDSUM, \
- .description = desc, \
- .key = keystr, \
- .buildopt_sum = AST_BUILDOPT_SUM, \
- fields \
- }; \
- static void __attribute__ ((constructor)) __reg_module(void) \
- { \
- ast_module_register(&__mod_info); \
- } \
- static void __attribute__ ((destructor)) __unreg_module(void) \
- { \
- ast_module_unregister(&__mod_info); \
- } \
- const static struct ast_module_info *ast_module_info = &__mod_info
-
-#define AST_MODULE_INFO_STANDARD(keystr, desc) \
- AST_MODULE_INFO(keystr, AST_MODFLAG_DEFAULT, desc, \
- .load = load_module, \
- .unload = unload_module, \
- )
-#endif
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_MODULE_H */
diff --git a/1.4/include/asterisk/monitor.h b/1.4/include/asterisk/monitor.h
deleted file mode 100644
index 935a33240..000000000
--- a/1.4/include/asterisk/monitor.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Channel monitoring
- */
-
-#ifndef _ASTERISK_MONITOR_H
-#define _ASTERISK_MONITOR_H
-
-#include "asterisk/channel.h"
-
-enum AST_MONITORING_STATE {
- AST_MONITOR_RUNNING,
- AST_MONITOR_PAUSED
-};
-
-/*! Responsible for channel monitoring data */
-struct ast_channel_monitor {
- struct ast_filestream *read_stream;
- struct ast_filestream *write_stream;
- char read_filename[FILENAME_MAX];
- char write_filename[FILENAME_MAX];
- char filename_base[FILENAME_MAX];
- int filename_changed;
- char *format;
- int joinfiles;
- enum AST_MONITORING_STATE state;
- int (*stop)(struct ast_channel *chan, int need_lock);
-};
-
-/* Start monitoring a channel */
-int ast_monitor_start(struct ast_channel *chan, const char *format_spec,
- const char *fname_base, int need_lock );
-
-/* Stop monitoring a channel */
-int ast_monitor_stop(struct ast_channel *chan, int need_lock);
-
-/* Change monitoring filename of a channel */
-int ast_monitor_change_fname(struct ast_channel *chan,
- const char *fname_base, int need_lock);
-
-void ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon);
-
-/* Pause monitoring of a channel */
-int ast_monitor_pause(struct ast_channel *chan);
-
-/* Unpause monitoring of a channel */
-int ast_monitor_unpause(struct ast_channel *chan);
-
-#endif /* _ASTERISK_MONITOR_H */
diff --git a/1.4/include/asterisk/musiconhold.h b/1.4/include/asterisk/musiconhold.h
deleted file mode 100644
index 8a8018d19..000000000
--- a/1.4/include/asterisk/musiconhold.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Music on hold handling
- */
-
-#ifndef _ASTERISK_MOH_H
-#define _ASTERISK_MOH_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*!
- * \brief Turn on music on hold on a given channel
- *
- * \param chan The channel structure that will get music on hold
- * \param mclass The class to use if the musicclass is not currently set on
- * the channel structure.
- * \param interpclass The class to use if the musicclass is not currently set on
- * the channel structure or in the mclass argument.
- *
- * \retval 0 success
- * \retval non-zero failure
- */
-int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass);
-
-/*! Turn off music on hold on a given channel */
-void ast_moh_stop(struct ast_channel *chan);
-
-void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
- void (*stop_ptr)(struct ast_channel *),
- void (*cleanup_ptr)(struct ast_channel *));
-
-void ast_uninstall_music_functions(void);
-
-void ast_moh_cleanup(struct ast_channel *chan);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_MOH_H */
diff --git a/1.4/include/asterisk/netsock.h b/1.4/include/asterisk/netsock.h
deleted file mode 100644
index 73a2dd224..000000000
--- a/1.4/include/asterisk/netsock.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- * \brief Network socket handling
- */
-
-#ifndef _ASTERISK_NETSOCK_H
-#define _ASTERISK_NETSOCK_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <netinet/in.h>
-#include "asterisk/io.h"
-#include "asterisk/astobj.h"
-
-struct ast_netsock;
-
-struct ast_netsock_list;
-
-struct ast_netsock_list *ast_netsock_list_alloc(void);
-
-int ast_netsock_init(struct ast_netsock_list *list);
-
-struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc,
- const char *bindinfo, int defaultport, int tos, ast_io_cb callback, void *data);
-
-struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc,
- struct sockaddr_in *bindaddr, int tos, ast_io_cb callback, void *data);
-
-int ast_netsock_free(struct ast_netsock_list *list, struct ast_netsock *netsock);
-
-int ast_netsock_release(struct ast_netsock_list *list);
-
-struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list,
- struct sockaddr_in *sa);
-
-int ast_netsock_sockfd(const struct ast_netsock *ns);
-
-const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns);
-
-void *ast_netsock_data(const struct ast_netsock *ns);
-
-void ast_netsock_unref(struct ast_netsock *ns);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_NETSOCK_H */
diff --git a/1.4/include/asterisk/options.h b/1.4/include/asterisk/options.h
deleted file mode 100644
index 6ec2a7e0b..000000000
--- a/1.4/include/asterisk/options.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Options provided by main asterisk program
- */
-
-#ifndef _ASTERISK_OPTIONS_H
-#define _ASTERISK_OPTIONS_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define AST_CACHE_DIR_LEN 512
-#define AST_FILENAME_MAX 80
-
-/*! \ingroup main_options */
-enum ast_option_flags {
- /*! Allow \#exec in config files */
- AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
- /*! Do not fork() */
- AST_OPT_FLAG_NO_FORK = (1 << 1),
- /*! Keep quiet */
- AST_OPT_FLAG_QUIET = (1 << 2),
- /*! Console mode */
- AST_OPT_FLAG_CONSOLE = (1 << 3),
- /*! Run in realtime Linux priority */
- AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
- /*! Initialize keys for RSA authentication */
- AST_OPT_FLAG_INIT_KEYS = (1 << 5),
- /*! Remote console */
- AST_OPT_FLAG_REMOTE = (1 << 6),
- /*! Execute an asterisk CLI command upon startup */
- AST_OPT_FLAG_EXEC = (1 << 7),
- /*! Don't use termcap colors */
- AST_OPT_FLAG_NO_COLOR = (1 << 8),
- /*! Are we fully started yet? */
- AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
- /*! Trascode via signed linear */
- AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
- /*! Enable priority jumping in applications */
- AST_OPT_FLAG_PRIORITY_JUMPING = (1 << 11),
- /*! Dump core on a seg fault */
- AST_OPT_FLAG_DUMP_CORE = (1 << 12),
- /*! Cache sound files */
- AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
- /*! Display timestamp in CLI verbose output */
- AST_OPT_FLAG_TIMESTAMP = (1 << 14),
- /*! Override config */
- AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
- /*! Reconnect */
- AST_OPT_FLAG_RECONNECT = (1 << 16),
- /*! Transmit Silence during Record() and DTMF Generation */
- AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
- /*! Suppress some warnings */
- AST_OPT_FLAG_DONT_WARN = (1 << 18),
- /*! End CDRs before the 'h' extension */
- AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
- /*! Use Zaptel Timing for generators if available */
- AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20),
- /*! Always fork, even if verbose or debug settings are non-zero */
- AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
- /*! Disable log/verbose output to remote consoles */
- AST_OPT_FLAG_MUTE = (1 << 22)
-};
-
-/*! These are the options that set by default when Asterisk starts */
-#define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
-
-#define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
-#define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
-#define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
-#define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
-#define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
-#define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
-#define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
-#define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
-#define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
-#define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
-#define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
-#define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
-#define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
-#define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
-#define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
-#define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
-#define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
-#define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
-#define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
-#define ast_opt_end_cdr_before_h_exten ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
-#define ast_opt_internal_timing ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
-#define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
-#define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
-
-extern struct ast_flags ast_options;
-
-extern int option_verbose;
-extern int option_debug; /*!< Debugging */
-extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
-extern double option_maxload;
-extern char defaultlanguage[];
-
-extern time_t ast_startuptime;
-extern time_t ast_lastreloadtime;
-extern pid_t ast_mainpid;
-
-extern char record_cache_dir[AST_CACHE_DIR_LEN];
-extern char debug_filename[AST_FILENAME_MAX];
-
-extern int ast_language_is_prefix;
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_OPTIONS_H */
diff --git a/1.4/include/asterisk/paths.h b/1.4/include/asterisk/paths.h
deleted file mode 100644
index d90dd9544..000000000
--- a/1.4/include/asterisk/paths.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Paths to configurable Asterisk directories
- *
- * Copyright (C) 1999-2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Asterisk file paths, configured in asterisk.conf
- */
-
-#ifndef _ASTERISK_PATHS_H
-#define _ASTERISK_PATHS_H
-
-#include <limits.h>
-
-extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
-extern char ast_config_AST_CONFIG_FILE[PATH_MAX];
-extern char ast_config_AST_MODULE_DIR[PATH_MAX];
-extern char ast_config_AST_SPOOL_DIR[PATH_MAX];
-extern char ast_config_AST_MONITOR_DIR[PATH_MAX];
-extern char ast_config_AST_VAR_DIR[PATH_MAX];
-extern char ast_config_AST_DATA_DIR[PATH_MAX];
-extern char ast_config_AST_LOG_DIR[PATH_MAX];
-extern char ast_config_AST_AGI_DIR[PATH_MAX];
-extern char ast_config_AST_DB[PATH_MAX];
-extern char ast_config_AST_KEY_DIR[PATH_MAX];
-extern char ast_config_AST_PID[PATH_MAX];
-extern char ast_config_AST_SOCKET[PATH_MAX];
-extern char ast_config_AST_RUN_DIR[PATH_MAX];
-extern char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
-extern char ast_config_AST_CTL_OWNER[PATH_MAX];
-extern char ast_config_AST_CTL_GROUP[PATH_MAX];
-extern char ast_config_AST_CTL[PATH_MAX];
-extern char ast_config_AST_SYSTEM_NAME[20];
-
-#endif /* _ASTERISK_PATHS_H */
diff --git a/1.4/include/asterisk/pbx.h b/1.4/include/asterisk/pbx.h
deleted file mode 100644
index 41c04ce9c..000000000
--- a/1.4/include/asterisk/pbx.h
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief Core PBX routines and definitions.
- */
-
-#ifndef _ASTERISK_PBX_H
-#define _ASTERISK_PBX_H
-
-#include "asterisk/sched.h"
-#include "asterisk/channel.h"
-#include "asterisk/linkedlists.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define AST_MAX_APP 32 /*!< Max length of an application */
-
-#define AST_PBX_KEEP 0
-#define AST_PBX_REPLACE 1
-
-/*! \brief Special return values from applications to the PBX { */
-#define AST_PBX_KEEPALIVE 10 /*!< Destroy the thread, but don't hang up the channel */
-#define AST_PBX_NO_HANGUP_PEER 11
-/*! } */
-
-#define PRIORITY_HINT -1 /*!< Special Priority for a hint */
-
-/*! \brief Extension states */
-enum ast_extension_states {
- AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
- AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
- AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
- AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
- AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
- AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
- AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
- AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
-};
-
-
-struct ast_context;
-struct ast_exten;
-struct ast_include;
-struct ast_ignorepat;
-struct ast_sw;
-
-/*! \brief Typedef for devicestate and hint callbacks */
-typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
-
-/*! \brief Data structure associated with a custom dialplan function */
-struct ast_custom_function {
- const char *name; /*!< Name */
- const char *synopsis; /*!< Short description for "show functions" */
- const char *desc; /*!< Help text that explains it all */
- const char *syntax; /*!< Syntax description */
- int (*read)(struct ast_channel *, char *, char *, char *, size_t); /*!< Read function, if read is supported */
- int (*write)(struct ast_channel *, char *, char *, const char *); /*!< Write function, if write is supported */
- AST_LIST_ENTRY(ast_custom_function) acflist;
-};
-
-/*! \brief All switch functions have the same interface, so define a type for them */
-typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
- const char *exten, int priority, const char *callerid, const char *data);
-
-/*!< Data structure associated with an Asterisk switch */
-struct ast_switch {
- AST_LIST_ENTRY(ast_switch) list;
- const char *name; /*!< Name of the switch */
- const char *description; /*!< Description of the switch */
-
- ast_switch_f *exists;
- ast_switch_f *canmatch;
- ast_switch_f *exec;
- ast_switch_f *matchmore;
-};
-
-struct ast_timing {
- int hastime; /*!< If time construct exists */
- unsigned int monthmask; /*!< Mask for month */
- unsigned int daymask; /*!< Mask for date */
- unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
- unsigned int minmask[24]; /*!< Mask for minute */
-};
-
-int ast_build_timing(struct ast_timing *i, const char *info);
-int ast_check_timing(const struct ast_timing *i);
-
-struct ast_pbx {
- int dtimeout; /*!< Timeout between digits (seconds) */
- int rtimeout; /*!< Timeout for response (seconds) */
-};
-
-
-/*!
- * \brief Register an alternative dialplan switch
- *
- * \param sw switch to register
- *
- * This function registers a populated ast_switch structure with the
- * asterisk switching architecture.
- *
- * \return 0 on success, and other than 0 on failure
- */
-int ast_register_switch(struct ast_switch *sw);
-
-/*!
- * \brief Unregister an alternative switch
- *
- * \param sw switch to unregister
- *
- * Unregisters a switch from asterisk.
- *
- * \return nothing
- */
-void ast_unregister_switch(struct ast_switch *sw);
-
-/*!
- * \brief Look up an application
- *
- * \param app name of the app
- *
- * This function searches for the ast_app structure within
- * the apps that are registered for the one with the name
- * you passed in.
- *
- * \return the ast_app structure that matches on success, or NULL on failure
- */
-struct ast_app *pbx_findapp(const char *app);
-
-/*!
- * \brief Execute an application
- *
- * \param c channel to execute on
- * \param app which app to execute
- * \param data the data passed into the app
- *
- * This application executes an application on a given channel. It
- * saves the stack and executes the given appliation passing in
- * the given data.
- *
- * \return 0 on success, and -1 on failure
- */
-int pbx_exec(struct ast_channel *c, struct ast_app *app, void *data);
-
-/*!
- * \brief Register a new context
- *
- * \param extcontexts pointer to the ast_context structure pointer
- * \param name name of the new context
- * \param registrar registrar of the context
- *
- * This will first search for a context with your name. If it exists already, it will not
- * create a new one. If it does not exist, it will create a new one with the given name
- * and registrar.
- *
- * \return NULL on failure, and an ast_context structure on success
- */
-struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar);
-struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, const char *name, const char *registrar);
-
-/*!
- * \brief Merge the temporary contexts into a global contexts list and delete from the
- * global list the ones that are being added
- *
- * \param extcontexts pointer to the ast_context structure pointer
- * \param registrar of the context; if it's set the routine will delete all contexts
- * that belong to that registrar; if NULL only the contexts that are specified
- * in extcontexts
- */
-void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
-
-/*!
- * \brief Destroy a context (matches the specified context (or ANY context if NULL)
- *
- * \param con context to destroy
- * \param registrar who registered it
- *
- * You can optionally leave out either parameter. It will find it
- * based on either the ast_context or the registrar name.
- *
- * \return nothing
- */
-void ast_context_destroy(struct ast_context *con, const char *registrar);
-
-/*!
- * \brief Find a context
- *
- * \param name name of the context to find
- *
- * Will search for the context with the given name.
- *
- * \return the ast_context on success, NULL on failure.
- */
-struct ast_context *ast_context_find(const char *name);
-
-enum ast_pbx_result {
- AST_PBX_SUCCESS = 0,
- AST_PBX_FAILED = -1,
- AST_PBX_CALL_LIMIT = -2,
-};
-
-/*!
- * \brief Create a new thread and start the PBX
- *
- * \param c channel to start the pbx on
- *
- * See ast_pbx_run for a synchronous function to run the PBX in the
- * current thread, as opposed to starting a new one.
- *
- * \return Zero on success, non-zero on failure
- */
-enum ast_pbx_result ast_pbx_start(struct ast_channel *c);
-
-/*!
- * \brief Execute the PBX in the current thread
- *
- * \param c channel to run the pbx on
- *
- * This executes the PBX on a given channel. It allocates a new
- * PBX structure for the channel, and provides all PBX functionality.
- * See ast_pbx_start for an asynchronous function to run the PBX in a
- * new thread as opposed to the current one.
- *
- * \return Zero on success, non-zero on failure
- */
-enum ast_pbx_result ast_pbx_run(struct ast_channel *c);
-
-/*!
- * \brief Add and extension to an extension context.
- *
- * \param context context to add the extension to
- * \param replace
- * \param extension extension to add
- * \param priority priority level of extension addition
- * \param label extension label
- * \param callerid pattern to match CallerID, or NULL to match any CallerID
- * \param application application to run on the extension with that priority level
- * \param data data to pass to the application
- * \param datad
- * \param registrar who registered the extension
- *
- * \retval 0 success
- * \retval -1 failure
- */
-int ast_add_extension(const char *context, int replace, const char *extension,
- int priority, const char *label, const char *callerid,
- const char *application, void *data, void (*datad)(void *), const char *registrar);
-
-/*!
- * \brief Add an extension to an extension context, this time with an ast_context *.
- *
- * \note For details about the arguments, check ast_add_extension()
- */
-int ast_add_extension2(struct ast_context *con, int replace, const char *extension,
- int priority, const char *label, const char *callerid,
- const char *application, void *data, void (*datad)(void *), const char *registrar);
-
-
-/*!
- * \brief Register an application.
- *
- * \param app Short name of the application
- * \param execute a function callback to execute the application. It should return
- * non-zero if the channel needs to be hung up.
- * \param synopsis a short description (one line synopsis) of the application
- * \param description long description with all of the details about the use of
- * the application
- *
- * This registers an application with Asterisk's internal application list.
- * \note The individual applications themselves are responsible for registering and unregistering
- * and unregistering their own CLI commands.
- *
- * \retval 0 success
- * \retval -1 failure.
- */
-int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *),
- const char *synopsis, const char *description);
-
-/*!
- * \brief Unregister an application
- *
- * \param app name of the application (does not have to be the same string as the one that was registered)
- *
- * This unregisters an application from Asterisk's internal application list.
- *
- * \retval 0 success
- * \retval -1 failure
- */
-int ast_unregister_application(const char *app);
-
-/*!
- * \brief Uses hint and devicestate callback to get the state of an extension
- *
- * \param c this is not important
- * \param context which context to look in
- * \param exten which extension to get state
- *
- * \return extension state as defined in the ast_extension_states enum
- */
-int ast_extension_state(struct ast_channel *c, const char *context, const char *exten);
-
-/*!
- * \brief Return string representation of the state of an extension
- *
- * \param extension_state is the numerical state delivered by ast_extension_state
- *
- * \return the state of an extension as string
- */
-const char *ast_extension_state2str(int extension_state);
-
-/*!
- * \brief Registers a state change callback
- *
- * \param context which context to look in
- * \param exten which extension to get state
- * \param callback callback to call if state changed
- * \param data to pass to callback
- *
- * The callback is called if the state of an extension is changed.
- *
- * \retval -1 on failure
- * \retval ID on success
- */
-int ast_extension_state_add(const char *context, const char *exten,
- ast_state_cb_type callback, void *data);
-
-/*!
- * \brief Deletes a registered state change callback by ID
- *
- * \param id of the callback to delete
- * \param callback callback
- *
- * Removes the callback from list of callbacks
- *
- * \retval 0 success
- * \retval -1 failure
- */
-int ast_extension_state_del(int id, ast_state_cb_type callback);
-
-/*!
- * \brief If an extension exists, return non-zero
- *
- * \param hint buffer for hint
- * \param maxlen size of hint buffer
- * \param name buffer for name portion of hint
- * \param maxnamelen size of name buffer
- * \param c this is not important
- * \param context which context to look in
- * \param exten which extension to search for
- *
- * \return If an extension within the given context with the priority PRIORITY_HINT
- * is found a non zero value will be returned.
- * Otherwise, 0 is returned.
- */
-int ast_get_hint(char *hint, int maxlen, char *name, int maxnamelen,
- struct ast_channel *c, const char *context, const char *exten);
-
-/*!
- * \brief Determine whether an extension exists
- *
- * \param c this is not important
- * \param context which context to look in
- * \param exten which extension to search for
- * \param priority priority of the action within the extension
- * \param callerid callerid to search for
- *
- * \return If an extension within the given context(or callerid) with the given priority
- * is found a non zero value will be returned. Otherwise, 0 is returned.
- */
-int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten,
- int priority, const char *callerid);
-
-/*!
- * \brief Find the priority of an extension that has the specified label
- *
- * \param c this is not important
- * \param context which context to look in
- * \param exten which extension to search for
- * \param label label of the action within the extension to match to priority
- * \param callerid callerid to search for
- *
- * \return the priority which matches the given label in the extension or -1 if not found.
- */
-int ast_findlabel_extension(struct ast_channel *c, const char *context,
- const char *exten, const char *label, const char *callerid);
-
-/*!
- * \brief Find the priority of an extension that has the specified label
- *
- * \note This function is the same as ast_findlabel_extension, except that it accepts
- * a pointer to an ast_context structure to specify the context instead of the
- * name of the context. Otherwise, the functions behave the same.
- */
-int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con,
- const char *exten, const char *label, const char *callerid);
-
-/*!
- * \brief Looks for a valid matching extension
- *
- * \param c not really important
- * \param context context to serach within
- * \param exten extension to check
- * \param priority priority of extension path
- * \param callerid callerid of extension being searched for
- *
- * \return If "exten" *could be* a valid extension in this context with or without
- * some more digits, return non-zero. Basically, when this returns 0, no matter
- * what you add to exten, it's not going to be a valid extension anymore
- */
-int ast_canmatch_extension(struct ast_channel *c, const char *context,
- const char *exten, int priority, const char *callerid);
-
-/*!
- * \brief Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
- *
- * \param c not really important XXX
- * \param context context to serach within
- * \param exten extension to check
- * \param priority priority of extension path
- * \param callerid callerid of extension being searched for
- *
- * \return If "exten" *could match* a valid extension in this context with
- * some more digits, return non-zero. Does NOT return non-zero if this is
- * an exact-match only. Basically, when this returns 0, no matter
- * what you add to exten, it's not going to be a valid extension anymore
- */
-int ast_matchmore_extension(struct ast_channel *c, const char *context,
- const char *exten, int priority, const char *callerid);
-
-/*!
- * \brief Determine if a given extension matches a given pattern (in NXX format)
- *
- * \param pattern pattern to match
- * \param extension extension to check against the pattern.
- *
- * Checks whether or not the given extension matches the given pattern.
- *
- * \retval 1 on match
- * \retval 0 on failure
- */
-int ast_extension_match(const char *pattern, const char *extension);
-
-int ast_extension_close(const char *pattern, const char *data, int needmore);
-
-/*!
- * \brief Launch a new extension (i.e. new stack)
- *
- * \param c not important
- * \param context which context to generate the extension within
- * \param exten new extension to add
- * \param priority priority of new extension
- * \param callerid callerid of extension
- *
- * This adds a new extension to the asterisk extension list.
- *
- * \retval 0 on success
- * \retval -1 on failure.
- */
-int ast_spawn_extension(struct ast_channel *c, const char *context,
- const char *exten, int priority, const char *callerid);
-
-/*!
- * \brief Add a context include
- *
- * \param context context to add include to
- * \param include new include to add
- * \param registrar who's registering it
- *
- * Adds an include taking a char * string as the context parameter
- *
- * \retval 0 on success
- * \retval -1 on error
-*/
-int ast_context_add_include(const char *context, const char *include,
- const char *registrar);
-
-/*!
- * \brief Add a context include
- *
- * \param con context to add the include to
- * \param include include to add
- * \param registrar who registered the context
- *
- * Adds an include taking a struct ast_context as the first parameter
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_add_include2(struct ast_context *con, const char *include,
- const char *registrar);
-
-/*!
- * \brief Remove a context include
- *
- * \note See ast_context_add_include for information on arguments
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_remove_include(const char *context, const char *include,
- const char *registrar);
-
-/*!
- * \brief Removes an include by an ast_context structure
- *
- * \note See ast_context_add_include2 for information on arguments
- *
- * \retval 0 on success
- * \retval -1 on success
- */
-int ast_context_remove_include2(struct ast_context *con, const char *include,
- const char *registrar);
-
-/*!
- * \brief Verifies includes in an ast_contect structure
- *
- * \param con context in which to verify the includes
- *
- * \retval 0 if no problems found
- * \retval -1 if there were any missing context
- */
-int ast_context_verify_includes(struct ast_context *con);
-
-/*!
- * \brief Add a switch
- *
- * \param context context to which to add the switch
- * \param sw switch to add
- * \param data data to pass to switch
- * \param eval whether to evaluate variables when running switch
- * \param registrar whoever registered the switch
- *
- * This function registers a switch with the asterisk switch architecture
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_add_switch(const char *context, const char *sw, const char *data,
- int eval, const char *registrar);
-
-/*!
- * \brief Adds a switch (first param is a ast_context)
- *
- * \note See ast_context_add_switch() for argument information, with the exception of
- * the first argument. In this case, it's a pointer to an ast_context structure
- * as opposed to the name.
- */
-int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data,
- int eval, const char *registrar);
-
-/*!
- * \brief Remove a switch
- *
- * Removes a switch with the given parameters
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_remove_switch(const char *context, const char *sw,
- const char *data, const char *registrar);
-
-int ast_context_remove_switch2(struct ast_context *con, const char *sw,
- const char *data, const char *registrar);
-
-/*!
- * \brief Simply remove extension from context
- *
- * \param context context to remove extension from
- * \param extension which extension to remove
- * \param priority priority of extension to remove
- * \param registrar registrar of the extension
- *
- * This function removes an extension from a given context.
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_remove_extension(const char *context, const char *extension, int priority,
- const char *registrar);
-
-int ast_context_remove_extension2(struct ast_context *con, const char *extension,
- int priority, const char *registrar);
-
-/*!
- * \brief Add an ignorepat
- *
- * \param context which context to add the ignorpattern to
- * \param ignorepat ignorepattern to set up for the extension
- * \param registrar registrar of the ignore pattern
- *
- * Adds an ignore pattern to a particular context.
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_add_ignorepat(const char *context, const char *ignorepat, const char *registrar);
-
-int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar);
-
-/*
- * \brief Remove an ignorepat
- *
- * \param context context from which to remove the pattern
- * \param ignorepat the pattern to remove
- * \param registrar the registrar of the ignore pattern
- *
- * This removes the given ignorepattern
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar);
-
-int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar);
-
-/*!
- * \brief Checks to see if a number should be ignored
- *
- * \param context context to search within
- * \param pattern to check whether it should be ignored or not
- *
- * Check if a number should be ignored with respect to dialtone cancellation.
- *
- * \retval 0 if the pattern should not be ignored
- * \retval non-zero if the pattern should be ignored
- */
-int ast_ignore_pattern(const char *context, const char *pattern);
-
-/* Locking functions for outer modules, especially for completion functions */
-
-/*!
- * \brief Locks the context list
- *
- * \retval 0 on success
- * \retval -1 on error
- */
-int ast_lock_contexts(void); /* equivalent to wrlock */
-int ast_rdlock_contexts(void);
-int ast_wrlock_contexts(void);
-
-/*!
- * \brief Unlocks contexts
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_unlock_contexts(void);
-
-/*!
- * \brief Locks a given context
- *
- * \param con context to lock
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_lock_context(struct ast_context *con);
-
-/*!
- * \retval Unlocks the given context
- *
- * \param con context to unlock
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_unlock_context(struct ast_context *con);
-
-/*!
- * \brief locks the macrolock in the given given context
- *
- * \param macrocontext name of the macro-context to lock
- *
- * Locks the given macro-context to ensure only one thread (call) can execute it at a time
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_lockmacro(const char *macrocontext);
-
-/*!
- * \brief Unlocks the macrolock in the given context
- *
- * \param macrocontext name of the macro-context to unlock
- *
- * Unlocks the given macro-context so that another thread (call) can execute it
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_context_unlockmacro(const char *macrocontext);
-
-int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority);
-
-int ast_async_goto_by_name(const char *chan, const char *context, const char *exten, int priority);
-
-/*! Synchronously or asynchronously make an outbound call and send it to a
- particular extension */
-int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
-
-/*! Synchronously or asynchronously make an outbound call and send it to a
- particular application with given extension */
-int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
-
-/*!
- * \brief Evaluate a condition
- *
- * \retval 0 if the condition is NULL or of zero length
- * \retval int If the string is an integer, the integer representation of
- * the integer is returned
- * \retval 1 Any other non-empty string
- */
-int pbx_checkcondition(const char *condition);
-
-/* Functions for returning values from structures */
-const char *ast_get_context_name(struct ast_context *con);
-const char *ast_get_extension_name(struct ast_exten *exten);
-struct ast_context *ast_get_extension_context(struct ast_exten *exten);
-const char *ast_get_include_name(struct ast_include *include);
-const char *ast_get_ignorepat_name(struct ast_ignorepat *ip);
-const char *ast_get_switch_name(struct ast_sw *sw);
-const char *ast_get_switch_data(struct ast_sw *sw);
-
-/* Other extension stuff */
-int ast_get_extension_priority(struct ast_exten *exten);
-int ast_get_extension_matchcid(struct ast_exten *e);
-const char *ast_get_extension_cidmatch(struct ast_exten *e);
-const char *ast_get_extension_app(struct ast_exten *e);
-const char *ast_get_extension_label(struct ast_exten *e);
-void *ast_get_extension_app_data(struct ast_exten *e);
-
-/* Registrar info functions ... */
-const char *ast_get_context_registrar(struct ast_context *c);
-const char *ast_get_extension_registrar(struct ast_exten *e);
-const char *ast_get_include_registrar(struct ast_include *i);
-const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip);
-const char *ast_get_switch_registrar(struct ast_sw *sw);
-
-/* Walking functions ... */
-struct ast_context *ast_walk_contexts(struct ast_context *con);
-struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
- struct ast_exten *priority);
-struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
- struct ast_exten *priority);
-struct ast_include *ast_walk_context_includes(struct ast_context *con,
- struct ast_include *inc);
-struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
- struct ast_ignorepat *ip);
-struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw);
-
-/*!
- * \note Will lock the channel.
- */
-int pbx_builtin_serialize_variables(struct ast_channel *chan, char *buf, size_t size);
-
-/*!
- * \note Will lock the channel.
- */
-const char *pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name);
-
-/*!
- * \note Will lock the channel.
- */
-void pbx_builtin_pushvar_helper(struct ast_channel *chan, const char *name, const char *value);
-
-/*!
- * \note Will lock the channel.
- */
-void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value);
-
-/*!
- * \note Will lock the channel.
- */
-void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp);
-void pbx_builtin_clear_globals(void);
-
-/*!
- * \note Will lock the channel.
- */
-int pbx_builtin_setvar(struct ast_channel *chan, void *data);
-
-void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
-void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count);
-
-int ast_extension_patmatch(const char *pattern, const char *data);
-
-/*! Set "autofallthrough" flag, if newval is <0, does not acutally set. If
- set to 1, sets to auto fall through. If newval set to 0, sets to no auto
- fall through (reads extension instead). Returns previous value. */
-int pbx_set_autofallthrough(int newval);
-
-/*!
- * \note This function will handle locking the channel as needed.
- */
-int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);
-
-/*!
- * \note I can find neither parsable nor parseable at dictionary.com,
- * but google gives me 169000 hits for parseable and only 49,800
- * for parsable
- *
- * \note This function will handle locking the channel as needed.
- */
-int ast_parseable_goto(struct ast_channel *chan, const char *goto_string);
-
-/*!
- * \note This function will handle locking the channel as needed.
- */
-int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority);
-
-/*!
- * \note This function will handle locking the channel as needed.
- */
-int ast_async_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);
-
-struct ast_custom_function* ast_custom_function_find(const char *name);
-
-/*!
- * \brief Unregister a custom function
- */
-int ast_custom_function_unregister(struct ast_custom_function *acf);
-
-/*!
- * \brief Reigster a custom function
- */
-int ast_custom_function_register(struct ast_custom_function *acf);
-
-/*!
- * \brief Retrieve the number of active calls
- */
-int ast_active_calls(void);
-
-/*!
- * \brief executes a read operation on a function
- *
- * \param chan Channel to execute on
- * \param function Data containing the function call string (will be modified)
- * \param workspace A pointer to safe memory to use for a return value
- * \param len the number of bytes in workspace
- *
- * This application executes a function in read mode on a given channel.
- *
- * \return zero on success, non-zero on failure
- */
-int ast_func_read(struct ast_channel *chan, char *function, char *workspace, size_t len);
-
-/*!
- * \brief executes a write operation on a function
- *
- * \param chan Channel to execute on
- * \param function Data containing the function call string (will be modified)
- * \param value A value parameter to pass for writing
- *
- * This application executes a function in write mode on a given channel.
- *
- * \return zero on success, non-zero on failure
- */
-int ast_func_write(struct ast_channel *chan, char *function, const char *value);
-
-void ast_hint_state_changed(const char *device);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_PBX_H */
diff --git a/1.4/include/asterisk/plc.h b/1.4/include/asterisk/plc.h
deleted file mode 100644
index 762504952..000000000
--- a/1.4/include/asterisk/plc.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*! \file
- * \brief SpanDSP - a series of DSP components for telephony
- *
- * plc.h
- *
- * \author Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2004 Steve Underwood
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This version may be optionally licenced under the GNU LGPL licence.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-
-#if !defined(_PLC_H_)
-#define _PLC_H_
-
-#ifdef SOLARIS
-#include <sys/int_types.h>
-#else
-#if defined(__OpenBSD__) || defined( __FreeBSD__)
-#include <inttypes.h>
-#else
-#include <stdint.h>
-#endif
-#endif
-
-/*! \page plc_page Packet loss concealment
-\section plc_page_sec_1 What does it do?
-The packet loss concealment module provides a suitable synthetic fill-in signal,
-to minimise the audible effect of lost packets in VoIP applications. It is not
-tied to any particular codec, and could be used with almost any codec which does not
-specify its own procedure for packet loss concealment.
-
-Where a codec specific concealment procedure exists, the algorithm is usually built
-around knowledge of the characteristics of the particular codec. It will, therefore,
-generally give better results for that particular codec than this generic concealer will.
-
-\section plc_page_sec_2 How does it work?
-While good packets are being received, the plc_rx() routine keeps a record of the trailing
-section of the known speech signal. If a packet is missed, plc_fillin() is called to produce
-a synthetic replacement for the real speech signal. The average mean difference function
-(AMDF) is applied to the last known good signal, to determine its effective pitch.
-Based on this, the last pitch period of signal is saved. Essentially, this cycle of speech
-will be repeated over and over until the real speech resumes. However, several refinements
-are needed to obtain smooth pleasant sounding results.
-
-- The two ends of the stored cycle of speech will not always fit together smoothly. This can
- cause roughness, or even clicks, at the joins between cycles. To soften this, the
- 1/4 pitch period of real speech preceeding the cycle to be repeated is blended with the last
- 1/4 pitch period of the cycle to be repeated, using an overlap-add (OLA) technique (i.e.
- in total, the last 5/4 pitch periods of real speech are used).
-
-- The start of the synthetic speech will not always fit together smoothly with the tail of
- real speech passed on before the erasure was identified. Ideally, we would like to modify
- the last 1/4 pitch period of the real speech, to blend it into the synthetic speech. However,
- it is too late for that. We could have delayed the real speech a little, but that would
- require more buffer manipulation, and hurt the efficiency of the no-lost-packets case
- (which we hope is the dominant case). Instead we use a degenerate form of OLA to modify
- the start of the synthetic data. The last 1/4 pitch period of real speech is time reversed,
- and OLA is used to blend it with the first 1/4 pitch period of synthetic speech. The result
- seems quite acceptable.
-
-- As we progress into the erasure, the chances of the synthetic signal being anything like
- correct steadily fall. Therefore, the volume of the synthesized signal is made to decay
- linearly, such that after 50ms of missing audio it is reduced to silence.
-
-- When real speech resumes, an extra 1/4 pitch period of sythetic speech is blended with the
- start of the real speech. If the erasure is small, this smoothes the transition. If the erasure
- is long, and the synthetic signal has faded to zero, the blending softens the start up of the
- real signal, avoiding a kind of "click" or "pop" effect that might occur with a sudden onset.
-
-\section plc_page_sec_3 How do I use it?
-Before audio is processed, call plc_init() to create an instance of the packet loss
-concealer. For each received audio packet that is acceptable (i.e. not including those being
-dropped for being too late) call plc_rx() to record the content of the packet. Note this may
-modify the packet a little after a period of packet loss, to blend real synthetic data smoothly.
-When a real packet is not available in time, call plc_fillin() to create a sythetic substitute.
-That's it!
-*/
-
-/*! Minimum allowed pitch (66 Hz) */
-#define PLC_PITCH_MIN 120
-/*! Maximum allowed pitch (200 Hz) */
-#define PLC_PITCH_MAX 40
-/*! Maximum pitch OLA window */
-#define PLC_PITCH_OVERLAP_MAX (PLC_PITCH_MIN >> 2)
-/*! The length over which the AMDF function looks for similarity (20 ms) */
-#define CORRELATION_SPAN 160
-/*! History buffer length. The buffer much also be at leat 1.25 times
- PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for
- the pitch assessment. */
-#define PLC_HISTORY_LEN (CORRELATION_SPAN + PLC_PITCH_MIN)
-
-typedef struct
-{
- /*! Consecutive erased samples */
- int missing_samples;
- /*! Current offset into pitch period */
- int pitch_offset;
- /*! Pitch estimate */
- int pitch;
- /*! Buffer for a cycle of speech */
- float pitchbuf[PLC_PITCH_MIN];
- /*! History buffer */
- int16_t history[PLC_HISTORY_LEN];
- /*! Current pointer into the history buffer */
- int buf_ptr;
-} plc_state_t;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*! Process a block of received audio samples.
- \brief Process a block of received audio samples.
- \param s The packet loss concealer context.
- \param amp The audio sample buffer.
- \param len The number of samples in the buffer.
- \return The number of samples in the buffer. */
-int plc_rx(plc_state_t *s, int16_t amp[], int len);
-
-/*! Fill-in a block of missing audio samples.
- \brief Fill-in a block of missing audio samples.
- \param s The packet loss concealer context.
- \param amp The audio sample buffer.
- \param len The number of samples to be synthesised.
- \return The number of samples synthesized. */
-int plc_fillin(plc_state_t *s, int16_t amp[], int len);
-
-/*! Process a block of received V.29 modem audio samples.
- \brief Process a block of received V.29 modem audio samples.
- \param s The packet loss concealer context.
- \return A pointer to the he packet loss concealer context. */
-plc_state_t *plc_init(plc_state_t *s);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-/*- End of file ------------------------------------------------------------*/
diff --git a/1.4/include/asterisk/poll-compat.h b/1.4/include/asterisk/poll-compat.h
deleted file mode 100644
index 5f795a894..000000000
--- a/1.4/include/asterisk/poll-compat.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * 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.
- */
-
-/*---------------------------------------------------------------------------*\
- $Id$
-
- NAME
-
- poll - select(2)-based poll() emulation function for BSD systems.
-
- SYNOPSIS
- #include "poll.h"
-
- struct pollfd
- {
- int fd;
- short events;
- short revents;
- }
-
- int poll (struct pollfd *pArray, unsigned long n_fds, int timeout)
-
- DESCRIPTION
-
- This file, and the accompanying "poll.c", implement the System V
- poll(2) system call for BSD systems (which typically do not provide
- poll()). Poll() provides a method for multiplexing input and output
- on multiple open file descriptors; in traditional BSD systems, that
- capability is provided by select(). While the semantics of select()
- differ from those of poll(), poll() can be readily emulated in terms
- of select() -- which is how this function is implemented.
-
- REFERENCES
- Stevens, W. Richard. Unix Network Programming. Prentice-Hall, 1990.
-
- NOTES
- 1. This software requires an ANSI C compiler.
-
- LICENSE
-
- This software is released under the following license:
-
- Copyright (c) 1995-2002 Brian M. Clapper
- All rights reserved.
-
- Redistribution and use in source and binary forms are
- permitted provided that: (1) source distributions retain
- this entire copyright notice and comment; (2) modifications
- made to the software are prominently mentioned, and a copy
- of the original software (or a pointer to its location) are
- included; and (3) distributions including binaries display
- the following acknowledgement: "This product includes
- software developed by Brian M. Clapper <bmc@clapper.org>"
- in the documentation or other materials provided with the
- distribution. The name of the author may not be used to
- endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE.
-
- Effectively, this means you can do what you want with the software
- except remove this notice or take advantage of the author's name.
- If you modify the software and redistribute your modified version,
- you must indicate that your version is a modification of the
- original, and you must provide either a pointer to or a copy of the
- original.
-\*---------------------------------------------------------------------------*/
-
-#ifndef _POLL_EMUL_H_
-#define _POLL_EMUL_H_
-
-#define POLLIN 0x01
-#define POLLPRI 0x02
-#define POLLOUT 0x04
-#define POLLERR 0x08
-#define POLLHUP 0x10
-#define POLLNVAL 0x20
-
-struct pollfd
-{
- int fd;
- short events;
- short revents;
-};
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#if (__STDC__ > 0) || defined(__cplusplus)
-extern int poll (struct pollfd *pArray, unsigned long n_fds, int timeout);
-#else
-extern int poll();
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _POLL_EMUL_H_ */
diff --git a/1.4/include/asterisk/privacy.h b/1.4/include/asterisk/privacy.h
deleted file mode 100644
index 686a14d75..000000000
--- a/1.4/include/asterisk/privacy.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Persistant data storage (akin to *doze registry)
- */
-
-#ifndef _ASTERISK_PRIVACY_H
-#define _ASTERISK_PRIVACY_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define AST_PRIVACY_DENY (1 << 0) /* Don't bother ringing, send to voicemail */
-#define AST_PRIVACY_ALLOW (1 << 1) /* Pass directly to me */
-#define AST_PRIVACY_KILL (1 << 2) /* Play anti-telemarketer message and hangup */
-#define AST_PRIVACY_TORTURE (1 << 3) /* Send directly to tele-torture */
-#define AST_PRIVACY_UNKNOWN (1 << 16)
-
-int ast_privacy_check(char *dest, char *cid);
-
-int ast_privacy_set(char *dest, char *cid, int status);
-
-int ast_privacy_reset(char *dest);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_PRIVACY_H */
diff --git a/1.4/include/asterisk/res_odbc.h b/1.4/include/asterisk/res_odbc.h
deleted file mode 100644
index 4d023c066..000000000
--- a/1.4/include/asterisk/res_odbc.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- * Copyright (C) 2004 - 2005, Anthony Minessale II
- * Copyright (C) 2006, Tilghman Lesher
- *
- * Mark Spencer <markster@digium.com>
- * Anthony Minessale <anthmct@yahoo.com>
- * Tilghman Lesher <res_odbc_200603@the-tilghman.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.
- */
-
-/*! \file
- * \brief ODBC resource manager
- */
-
-#ifndef _ASTERISK_RES_ODBC_H
-#define _ASTERISK_RES_ODBC_H
-
-#include <sql.h>
-#include <sqlext.h>
-#include <sqltypes.h>
-
-typedef enum { ODBC_SUCCESS=0, ODBC_FAIL=-1} odbc_status;
-
-struct odbc_obj {
- ast_mutex_t lock;
- SQLHDBC con; /* ODBC Connection Handle */
- struct odbc_class *parent; /* Information about the connection is protected */
- struct timeval last_used;
- unsigned int used:1;
- unsigned int up:1;
- AST_LIST_ENTRY(odbc_obj) list;
-};
-
-/* functions */
-
-/*! \brief Executes a prepared statement handle
- * \param obj The non-NULL result of odbc_request_obj()
- * \param stmt The prepared statement handle
- * \return Returns 0 on success or -1 on failure
- *
- * This function was originally designed simply to execute a prepared
- * statement handle and to retry if the initial execution failed.
- * Unfortunately, it did this by disconnecting and reconnecting the database
- * handle which on most databases causes the statement handle to become
- * invalid. Therefore, this method has been deprecated in favor of
- * odbc_prepare_and_execute() which allows the statement to be prepared
- * multiple times, if necessary, in case of a loss of connection.
- *
- * This function really only ever worked with MySQL, where the statement handle is
- * not prepared on the server. If you are not using MySQL, you should avoid it.
- */
-int ast_odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt) __attribute__ ((deprecated));
-
-/*! \brief Retrieves a connected ODBC object
- * \param name The name of the ODBC class for which a connection is needed.
- * \param check Whether to ensure that a connection is valid before returning the handle. Usually unnecessary.
- * \return Returns an ODBC object or NULL if there is no connection available with the requested name.
- *
- * Connection classes may, in fact, contain multiple connection handles. If
- * the connection is pooled, then each connection will be dedicated to the
- * thread which requests it. Note that all connections should be released
- * when the thread is done by calling odbc_release_obj(), below.
- */
-struct odbc_obj *ast_odbc_request_obj(const char *name, int check);
-
-/*! \brief Releases an ODBC object previously allocated by odbc_request_obj()
- * \param obj The ODBC object
- */
-void ast_odbc_release_obj(struct odbc_obj *obj);
-
-/*! \brief Checks an ODBC object to ensure it is still connected
- * \param obj The ODBC object
- * \return Returns 0 if connected, -1 otherwise.
- */
-int ast_odbc_sanity_check(struct odbc_obj *obj);
-
-/*! \brief Checks if the database natively supports backslash as an escape character.
- * \param obj The ODBC object
- * \return Returns 1 if backslash is a native escape character, 0 if an ESCAPE clause is needed to support '\'
- */
-int ast_odbc_backslash_is_escape(struct odbc_obj *obj);
-
-/*! \brief Prepares, executes, and returns the resulting statement handle.
- * \param obj The ODBC object
- * \param prepare_cb A function callback, which, when called, should return a statement handle prepared, with any necessary parameters or result columns bound.
- * \param data A parameter to be passed to the prepare_cb parameter function, indicating which statement handle is to be prepared.
- * \return Returns a statement handle or NULL on error.
- */
-SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_cb)(struct odbc_obj *obj, void *data), void *data);
-
-#endif /* _ASTERISK_RES_ODBC_H */
diff --git a/1.4/include/asterisk/rtp.h b/1.4/include/asterisk/rtp.h
deleted file mode 100644
index 870529e5d..000000000
--- a/1.4/include/asterisk/rtp.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * 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.
- */
-
-/*!
- * \file rtp.h
- * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
- *
- * RTP is defined in RFC 3550.
- */
-
-#ifndef _ASTERISK_RTP_H
-#define _ASTERISK_RTP_H
-
-#include <netinet/in.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/io.h"
-#include "asterisk/sched.h"
-#include "asterisk/channel.h"
-#include "asterisk/linkedlists.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
-/*! DTMF (RFC2833) */
-#define AST_RTP_DTMF (1 << 0)
-/*! 'Comfort Noise' (RFC3389) */
-#define AST_RTP_CN (1 << 1)
-/*! DTMF (Cisco Proprietary) */
-#define AST_RTP_CISCO_DTMF (1 << 2)
-/*! Maximum RTP-specific code */
-#define AST_RTP_MAX AST_RTP_CISCO_DTMF
-
-#define MAX_RTP_PT 256
-
-enum ast_rtp_options {
- AST_RTP_OPT_G726_NONSTANDARD = (1 << 0),
-};
-
-enum ast_rtp_get_result {
- /*! Failed to find the RTP structure */
- AST_RTP_GET_FAILED = 0,
- /*! RTP structure exists but true native bridge can not occur so try partial */
- AST_RTP_TRY_PARTIAL,
- /*! RTP structure exists and native bridge can occur */
- AST_RTP_TRY_NATIVE,
-};
-
-struct ast_rtp;
-
-struct ast_rtp_protocol {
- /*! Get RTP struct, or NULL if unwilling to transfer */
- enum ast_rtp_get_result (* const get_rtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
- /*! Get RTP struct, or NULL if unwilling to transfer */
- enum ast_rtp_get_result (* const get_vrtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
- /*! Set RTP peer */
- int (* const set_rtp_peer)(struct ast_channel *chan, struct ast_rtp *peer, struct ast_rtp *vpeer, int codecs, int nat_active);
- int (* const get_codec)(struct ast_channel *chan);
- const char * const type;
- AST_LIST_ENTRY(ast_rtp_protocol) list;
-};
-
-struct ast_rtp_quality {
- unsigned int local_ssrc; /* Our SSRC */
- unsigned int local_lostpackets; /* Our lost packets */
- double local_jitter; /* Our calculated jitter */
- unsigned int local_count; /* Number of received packets */
- unsigned int remote_ssrc; /* Their SSRC */
- unsigned int remote_lostpackets; /* Their lost packets */
- double remote_jitter; /* Their reported jitter */
- unsigned int remote_count; /* Number of transmitted packets */
- double rtt; /* Round trip time */
-};
-
-
-#define FLAG_3389_WARNING (1 << 0)
-
-typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data);
-
-/*!
- * \brief Get the amount of space required to hold an RTP session
- * \return number of bytes required
- */
-size_t ast_rtp_alloc_size(void);
-
-/*!
- * \brief Initializate a RTP session.
- *
- * \param sched
- * \param io
- * \param rtcpenable
- * \param callbackmode
- * \returns A representation (structure) of an RTP session.
- */
-struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
-
-/*!
- * \brief Initializate a RTP session using an in_addr structure.
- *
- * This fuction gets called by ast_rtp_new().
- *
- * \param sched
- * \param io
- * \param rtcpenable
- * \param callbackmode
- * \param in
- * \returns A representation (structure) of an RTP session.
- */
-struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in);
-
-void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
-
-/* Copies from rtp to them and returns 1 if there was a change or 0 if it was already the same */
-int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
-
-void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us);
-
-struct ast_rtp *ast_rtp_get_bridged(struct ast_rtp *rtp);
-
-void ast_rtp_destroy(struct ast_rtp *rtp);
-
-void ast_rtp_reset(struct ast_rtp *rtp);
-
-void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username);
-
-void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback);
-
-void ast_rtp_set_data(struct ast_rtp *rtp, void *data);
-
-int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *f);
-
-struct ast_frame *ast_rtp_read(struct ast_rtp *rtp);
-
-struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp);
-
-int ast_rtp_fd(struct ast_rtp *rtp);
-
-int ast_rtcp_fd(struct ast_rtp *rtp);
-
-int ast_rtp_senddigit_begin(struct ast_rtp *rtp, char digit);
-
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
-
-int ast_rtp_sendcng(struct ast_rtp *rtp, int level);
-
-int ast_rtp_settos(struct ast_rtp *rtp, int tos);
-
-void ast_rtp_new_source(struct ast_rtp *rtp);
-
-/*! \brief Setting RTP payload types from lines in a SDP description: */
-void ast_rtp_pt_clear(struct ast_rtp* rtp);
-/*! \brief Set payload types to defaults */
-void ast_rtp_pt_default(struct ast_rtp* rtp);
-
-/*! \brief Copy payload types between RTP structures */
-void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src);
-
-/*! \brief Activate payload type */
-void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt);
-
-/*! \brief clear payload type */
-void ast_rtp_unset_m_type(struct ast_rtp* rtp, int pt);
-
-/*! \brief Initiate payload type to a known MIME media type for a codec */
-int ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
- char *mimeType, char *mimeSubtype,
- enum ast_rtp_options options);
-
-/*! \brief Mapping between RTP payload format codes and Asterisk codes: */
-struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
-int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
-
-void ast_rtp_get_current_formats(struct ast_rtp* rtp,
- int* astFormats, int* nonAstFormats);
-
-/*! \brief Mapping an Asterisk code into a MIME subtype (string): */
-const char *ast_rtp_lookup_mime_subtype(int isAstFormat, int code,
- enum ast_rtp_options options);
-
-/*! \brief Build a string of MIME subtype names from a capability list */
-char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
- const int isAstFormat, enum ast_rtp_options options);
-
-void ast_rtp_setnat(struct ast_rtp *rtp, int nat);
-
-int ast_rtp_getnat(struct ast_rtp *rtp);
-
-/*! \brief Indicate whether this RTP session is carrying DTMF or not */
-void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf);
-
-/*! \brief Compensate for devices that send RFC2833 packets all at once */
-void ast_rtp_setdtmfcompensate(struct ast_rtp *rtp, int compensate);
-
-/*! \brief Enable STUN capability */
-void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable);
-
-int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-
-int ast_rtp_proto_register(struct ast_rtp_protocol *proto);
-
-void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto);
-
-int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media);
-
-/*! \brief If possible, create an early bridge directly between the devices without
- having to send a re-invite later */
-int ast_rtp_early_bridge(struct ast_channel *dest, struct ast_channel *src);
-
-void ast_rtp_stop(struct ast_rtp *rtp);
-
-/*! \brief Return RTCP quality string */
-char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual);
-
-/*! \brief Send an H.261 fast update request. Some devices need this rather than the XML message in SIP */
-int ast_rtcp_send_h261fur(void *data);
-
-void ast_rtp_new_init(struct ast_rtp *rtp);
-
-void ast_rtp_init(void);
-
-int ast_rtp_reload(void);
-
-int ast_rtp_codec_setpref(struct ast_rtp *rtp, struct ast_codec_pref *prefs);
-
-struct ast_codec_pref *ast_rtp_codec_getpref(struct ast_rtp *rtp);
-
-int ast_rtp_codec_getformat(int pt);
-
-/*! \brief Set rtp timeout */
-void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout);
-/*! \brief Set rtp hold timeout */
-void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout);
-/*! \brief set RTP keepalive interval */
-void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period);
-/*! \brief Get RTP keepalive interval */
-int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp);
-/*! \brief Get rtp hold timeout */
-int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp);
-/*! \brief Get rtp timeout */
-int ast_rtp_get_rtptimeout(struct ast_rtp *rtp);
-/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
-void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_RTP_H */
diff --git a/1.4/include/asterisk/say.h b/1.4/include/asterisk/say.h
deleted file mode 100644
index 17070c2c4..000000000
--- a/1.4/include/asterisk/say.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Say numbers and dates (maybe words one day too)
- */
-
-#ifndef _ASTERISK_SAY_H
-#define _ASTERISK_SAY_H
-
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-
-#include <time.h>
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! \brief
- * The basic ast_say_* functions are implemented as function pointers,
- * initialized to the function say_stub() which simply returns an error.
- * Other interfaces, declared here as regular functions, are simply
- * wrappers around the basic functions.
- *
- * An implementation of the basic ast_say functions (e.g. from say.c or from
- * a dynamically loaded module) will just have to reassign the pointers
- * to the relevant functions to override the previous implementation.
- *
- * \todo XXX
- * As the conversion from the old implementation of say.c to the new
- * implementation will be completed, and the API suitably reworked by
- * removing redundant functions and/or arguments, this mechanism may be
- * reverted back to pure static functions, if needed.
- */
-#if defined(SAY_STUBS)
-/* provide declarations for the *say*() functions
- * and initialize them to the stub function
- */
-static int say_stub(struct ast_channel *chan, ...)
-{
- ast_log(LOG_WARNING, "no implementation for the say() functions\n");
- return -1;
-};
-
-#undef SAY_STUBS
-#define SAY_INIT(x) = (typeof (x))say_stub
-#define SAY_EXTERN
-#else
-#define SAY_INIT(x)
-#define SAY_EXTERN extern
-#endif
-
-/* says a number
- * \param chan channel to say them number on
- * \param num number to say on the channel
- * \param ints which dtmf to interrupt on
- * \param lang language to speak the number
- * \param options set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural
- * Vocally says a number on a given channel
- * Returns 0 on success, DTMF digit on interrupt, -1 on failure
- */
-int ast_say_number(struct ast_channel *chan, int num,
- const char *ints, const char *lang, const char *options);
-
-/* Same as above with audiofd for received audio and returns 1 on ctrlfd being readable */
-SAY_EXTERN int (* ast_say_number_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_number_full);
-
-/* says an enumeration
- * \param chan channel to say them enumeration on
- * \param num number to say on the channel
- * \param ints which dtmf to interrupt on
- * \param lang language to speak the enumeration
- * \param options set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural
- * Vocally says a enumeration on a given channel (first, sencond, third, forth, thirtyfirst, hundredth, ....)
- * especially useful for dates and messages. says 'last' if num equals to INT_MAX
- * Returns 0 on success, DTMF digit on interrupt, -1 on failure
- */
-int ast_say_enumeration(struct ast_channel *chan, int num,
- const char *ints, const char *lang, const char *options);
-
-SAY_EXTERN int (* ast_say_enumeration_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_enumeration_full);
-
-/* says digits
- * \param chan channel to act upon
- * \param num number to speak
- * \param ints which dtmf to interrupt on
- * \param lang language to speak
- * Vocally says digits of a given number
- * Returns 0 on success, dtmf if interrupted, -1 on failure
- */
-int ast_say_digits(struct ast_channel *chan, int num,
- const char *ints, const char *lang);
-
-int ast_say_digits_full(struct ast_channel *chan, int num,
- const char *ints, const char *lang, int audiofd, int ctrlfd);
-
-/* says digits of a string
- * \param chan channel to act upon
- * \param num string to speak
- * \param ints which dtmf to interrupt on
- * \param lang language to speak in
- * Vocally says the digits of a given string
- * Returns 0 on success, dtmf if interrupted, -1 on failure
- */
-int ast_say_digit_str(struct ast_channel *chan, const char *num,
- const char *ints, const char *lang);
-
-SAY_EXTERN int (* ast_say_digit_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_digit_str_full);
-
-/*
- * the generic 'say' routine, with the first chars in the string
- * defining the format to use
- */
-SAY_EXTERN int (* ast_say_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_full);
-
-/*
- * other function to pronounce character and phonetic strings
- */
-int ast_say_character_str(struct ast_channel *chan, const char *num,
- const char *ints, const char *lang);
-
-SAY_EXTERN int (* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full);
-
-int ast_say_phonetic_str(struct ast_channel *chan, const char *num,
- const char *ints, const char *lang);
-
-SAY_EXTERN int (* ast_say_phonetic_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_phonetic_str_full);
-
-SAY_EXTERN int (* ast_say_datetime)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime);
-SAY_EXTERN int (* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time);
-
-SAY_EXTERN int (* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date);
-
-SAY_EXTERN int (* ast_say_datetime_from_now)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime_from_now);
-
-SAY_EXTERN int (* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_SAY_H */
diff --git a/1.4/include/asterisk/sched.h b/1.4/include/asterisk/sched.h
deleted file mode 100644
index d2508bfa8..000000000
--- a/1.4/include/asterisk/sched.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Scheduler Routines (derived from cheops)
- */
-
-#ifndef _ASTERISK_SCHED_H
-#define _ASTERISK_SCHED_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! \brief Max num of schedule structs
- * \note The max number of schedule structs to keep around
- * for use. Undefine to disable schedule structure
- * caching. (Only disable this on very low memory
- * machines)
- */
-#define SCHED_MAX_CACHE 128
-
-/*! \brief a loop construct to ensure that
- * the scheduled task get deleted. The idea is that
- * if we loop attempting to remove the scheduled task,
- * then whatever callback had been running will complete
- * and reinsert the task into the scheduler.
- *
- * Since macro expansion essentially works like pass-by-name
- * parameter passing, this macro will still work correctly even
- * if the id of the task to delete changes. This holds as long as
- * the name of the id which could change is passed to the macro
- * and not a copy of the value of the id.
- */
-#define AST_SCHED_DEL(sched, id) \
- ({ \
- int _count = 0; \
- int _sched_res = -1; \
- while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) \
- usleep(1); \
- if (_count == 10 && option_debug > 2) { \
- ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \
- } \
- id = -1; \
- (_sched_res); \
- })
-
-struct sched_context;
-
-/*! \brief New schedule context
- * \note Create a scheduling context
- * \return Returns a malloc'd sched_context structure, NULL on failure
- */
-struct sched_context *sched_context_create(void);
-
-/*! \brief destroys a schedule context
- * Destroys (free's) the given sched_context structure
- * \param c Context to free
- * \return Returns 0 on success, -1 on failure
- */
-void sched_context_destroy(struct sched_context *c);
-
-/*! \brief callback for a cheops scheduler
- * A cheops scheduler callback takes a pointer with callback data and
- * \return returns a 0 if it should not be run again, or non-zero if it should be
- * rescheduled to run again
- */
-typedef int (*ast_sched_cb)(const void *data);
-#define AST_SCHED_CB(a) ((ast_sched_cb)(a))
-
-/*! \brief Adds a scheduled event
- * Schedule an event to take place at some point in the future. callback
- * will be called with data as the argument, when milliseconds into the
- * future (approximately)
- * If callback returns 0, no further events will be re-scheduled
- * \param con Scheduler context to add
- * \param when how many milliseconds to wait for event to occur
- * \param callback function to call when the amount of time expires
- * \param data data to pass to the callback
- * \return Returns a schedule item ID on success, -1 on failure
- */
-int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data);
-
-/*!Adds a scheduled event with rescheduling support
- * \param con Scheduler context to add
- * \param when how many milliseconds to wait for event to occur
- * \param callback function to call when the amount of time expires
- * \param data data to pass to the callback
- * \param variable If true, the result value of callback function will be
- * used for rescheduling
- * Schedule an event to take place at some point in the future. Callback
- * will be called with data as the argument, when milliseconds into the
- * future (approximately)
- * If callback returns 0, no further events will be re-scheduled
- * \return Returns a schedule item ID on success, -1 on failure
- */
-int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable);
-
-/*! \brief Deletes a scheduled event
- * Remove this event from being run. A procedure should not remove its
- * own event, but return 0 instead.
- * \param con scheduling context to delete item from
- * \param id ID of the scheduled item to delete
- * \return Returns 0 on success, -1 on failure
- */
-int ast_sched_del(struct sched_context *con, int id);
-
-/*! \brief Determines number of seconds until the next outstanding event to take place
- * Determine the number of seconds until the next outstanding event
- * should take place, and return the number of milliseconds until
- * it needs to be run. This value is perfect for passing to the poll
- * call.
- * \param con context to act upon
- * \return Returns "-1" if there is nothing there are no scheduled events
- * (and thus the poll should not timeout)
- */
-int ast_sched_wait(struct sched_context *con);
-
-/*! \brief Runs the queue
- * \param con Scheduling context to run
- * Run the queue, executing all callbacks which need to be performed
- * at this time.
- * \param con context to act upon
- * \return Returns the number of events processed.
- */
-int ast_sched_runq(struct sched_context *con);
-
-/*! \brief Dumps the scheduler contents
- * Debugging: Dump the contents of the scheduler to stderr
- * \param con Context to dump
- */
-void ast_sched_dump(const struct sched_context *con);
-
-/*! \brief Returns the number of seconds before an event takes place
- * \param con Context to use
- * \param id Id to dump
- */
-long ast_sched_when(struct sched_context *con,int id);
-
-/*!
- * \brief Convenience macro for objects and reference (add)
- *
- */
-#define ast_sched_add_object(obj,con,when,callback) ast_sched_add((con),(when),(callback), ASTOBJ_REF((obj)))
-
-/*!
- * \brief Convenience macro for objects and reference (del)
- *
- */
-#define ast_sched_del_object(obj,destructor,con,id) do { \
- if ((id) > -1) { \
- ast_sched_del((con),(id)); \
- (id) = -1; \
- ASTOBJ_UNREF((obj),(destructor)); \
- } \
-} while(0)
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_SCHED_H */
diff --git a/1.4/include/asterisk/sha1.h b/1.4/include/asterisk/sha1.h
deleted file mode 100644
index fa8e2155b..000000000
--- a/1.4/include/asterisk/sha1.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * sha1.h
- *
- * Description:
- * This is the header file for code which implements the Secure
- * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
- * April 17, 1995.
- *
- * Many of the variable names in this code, especially the
- * single character names, were used because those were the names
- * used in the publication.
- *
- * Please read the file sha1.c for more information.
- *
- */
-
-
-#ifndef _SHA1_H_
-#define _SHA1_H_
-
-
-
-#if defined(__OpenBSD__) || defined( __FreeBSD__)
-#include <inttypes.h>
-#else
-#include <stdint.h>
-#endif
-
-/*
- * If you do not have the ISO standard stdint.h header file, then you
- * must typdef the following:
- * name meaning
- * uint32_t unsigned 32 bit integer
- * uint8_t unsigned 8 bit integer (i.e., unsigned char)
- *
- */
-
-#ifndef _SHA_enum_
-#define _SHA_enum_
-enum
-{
- shaSuccess = 0,
- shaNull, /* Null pointer parameter */
- shaInputTooLong, /* input data too long */
- shaStateError /* called Input after Result */
-};
-#endif
-#define SHA1HashSize 20
-
-/*
- * This structure will hold context information for the SHA-1
- * hashing operation
- */
-typedef struct SHA1Context
-{
- uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */
-
- uint32_t Length_Low; /* Message length in bits */
- uint32_t Length_High; /* Message length in bits */
-
- /* Index into message block array */
- uint32_t Message_Block_Index; /* 8 bits actually suffice */
- uint8_t Message_Block[64]; /* 512-bit message blocks */
-
- int Computed; /* Is the digest computed? */
- int Corrupted; /* Is the message digest corrupted? */
-} SHA1Context;
-
-/*
- * Function Prototypes
- */
-
-
-int SHA1Reset( SHA1Context *);
-int SHA1Input( SHA1Context *,
- const uint8_t *,
- unsigned int);
-int SHA1Result( SHA1Context *,
- uint8_t Message_Digest[SHA1HashSize]);
-
-#endif
diff --git a/1.4/include/asterisk/slinfactory.h b/1.4/include/asterisk/slinfactory.h
deleted file mode 100644
index 939384efd..000000000
--- a/1.4/include/asterisk/slinfactory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Anthony Minessale II
- *
- * Anthony Minessale <anthmct@yahoo.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.
- */
-
-/*! \file
- * \brief A machine to gather up arbitrary frames and convert them
- * to raw slinear on demand.
- */
-
-#ifndef _ASTERISK_SLINFACTORY_H
-#define _ASTERISK_SLINFACTORY_H
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define AST_SLINFACTORY_MAX_HOLD 1280
-
-struct ast_slinfactory {
- AST_LIST_HEAD_NOLOCK(, ast_frame) queue;
- struct ast_trans_pvt *trans;
- short hold[AST_SLINFACTORY_MAX_HOLD];
- short *offset;
- size_t holdlen; /*!< in samples */
- unsigned int size; /*!< in samples */
- unsigned int format;
-};
-
-void ast_slinfactory_init(struct ast_slinfactory *sf);
-void ast_slinfactory_destroy(struct ast_slinfactory *sf);
-int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f);
-int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples);
-unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf);
-void ast_slinfactory_flush(struct ast_slinfactory *sf);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_SLINFACTORY_H */
diff --git a/1.4/include/asterisk/smdi.h b/1.4/include/asterisk/smdi.h
deleted file mode 100644
index 6c79b2bc8..000000000
--- a/1.4/include/asterisk/smdi.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Copyright (C) 2005-2008, Digium, Inc.
- *
- * Matthew A. Nicholson <mnicholson@digium.com>
- * Russell Bryant <russell@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.
- */
-
-/*!
- * \file
- * \brief SMDI support for Asterisk.
- * \author Matthew A. Nicholson <mnicholson@digium.com>
- * \author Russell Bryant <russell@digium.com>
- */
-
-
-/* C is simply a ego booster for those who want to do objects the hard way. */
-
-
-#ifndef ASTERISK_SMDI_H
-#define ASTERISK_SMDI_H
-
-#include <termios.h>
-#include <time.h>
-
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/astobj.h"
-
-#define SMDI_MESG_DESK_NUM_LEN 3
-#define SMDI_MESG_DESK_TERM_LEN 4
-#define SMDI_MWI_FAIL_CAUSE_LEN 3
-#define SMDI_MAX_STATION_NUM_LEN 10
-#define SMDI_MAX_FILENAME_LEN 256
-
-/*!
- * \brief An SMDI message waiting indicator message.
- *
- * The ast_smdi_mwi_message structure contains the parsed out parts of an smdi
- * message. Each ast_smdi_interface structure has a message queue consisting
- * ast_smdi_mwi_message structures.
- */
-struct ast_smdi_mwi_message {
- ASTOBJ_COMPONENTS(struct ast_smdi_mwi_message);
- char fwd_st[SMDI_MAX_STATION_NUM_LEN + 1]; /* forwarding station number */
- char cause[SMDI_MWI_FAIL_CAUSE_LEN + 1]; /* the type of failure */
- struct timeval timestamp; /* a timestamp for the message */
-};
-
-/*!
- * \brief An SMDI message desk message.
- *
- * The ast_smdi_md_message structure contains the parsed out parts of an smdi
- * message. Each ast_smdi_interface structure has a message queue consisting
- * ast_smdi_md_message structures.
- */
-struct ast_smdi_md_message {
- ASTOBJ_COMPONENTS(struct ast_smdi_md_message);
- char mesg_desk_num[SMDI_MESG_DESK_NUM_LEN + 1]; /* message desk number */
- char mesg_desk_term[SMDI_MESG_DESK_TERM_LEN + 1]; /* message desk terminal */
- char fwd_st[SMDI_MAX_STATION_NUM_LEN + 1]; /* forwarding station number */
- char calling_st[SMDI_MAX_STATION_NUM_LEN + 1]; /* calling station number */
- char type; /* the type of the call */
- struct timeval timestamp; /* a timestamp for the message */
-};
-
-/*!
- * \brief SMDI interface structure.
- *
- * The ast_smdi_interface structure holds information on a serial port that
- * should be monitored for SMDI activity. The structure contains a message
- * queue of messages that have been recieved on the interface.
- */
-struct ast_smdi_interface;
-
-void ast_smdi_interface_unref(struct ast_smdi_interface *iface);
-
-/*!
- * \brief Get the next SMDI message from the queue.
- * \param iface a pointer to the interface to use.
- *
- * This function pulls the first unexpired message from the SMDI message queue
- * on the specified interface. It will purge all expired SMDI messages before
- * returning.
- *
- * \return the next SMDI message, or NULL if there were no pending messages.
- */
-struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *iface);
-
-/*!
- * \brief Get the next SMDI message from the queue.
- * \param iface a pointer to the interface to use.
- * \param timeout the time to wait before returning in milliseconds.
- *
- * This function pulls a message from the SMDI message queue on the specified
- * interface. If no message is available this function will wait the specified
- * amount of time before returning.
- *
- * \return the next SMDI message, or NULL if there were no pending messages and
- * the timeout has expired.
- */
-struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout);
-
-/*!
- * \brief Put an SMDI message back in the front of the queue.
- * \param iface a pointer to the interface to use.
- * \param md_msg a pointer to the message to use.
- *
- * This function puts a message back in the front of the specified queue. It
- * should be used if a message was popped but is not going to be processed for
- * some reason, and the message needs to be returned to the queue.
- */
-void ast_smdi_md_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_md_message *msg);
-
-/*!
- * \brief Get the next SMDI message from the queue.
- * \param iface a pointer to the interface to use.
- *
- * This function pulls the first unexpired message from the SMDI message queue
- * on the specified interface. It will purge all expired SMDI messages before
- * returning.
- *
- * \return the next SMDI message, or NULL if there were no pending messages.
- */
-struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface);
-
-/*!
- * \brief Get the next SMDI message from the queue.
- * \param iface a pointer to the interface to use.
- * \param timeout the time to wait before returning in milliseconds.
- *
- * This function pulls a message from the SMDI message queue on the specified
- * interface. If no message is available this function will wait the specified
- * amount of time before returning.
- *
- * \return the next SMDI message, or NULL if there were no pending messages and
- * the timeout has expired.
- */
-struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout);
-struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface,
- int timeout, const char *station);
-
-/*!
- * \brief Put an SMDI message back in the front of the queue.
- * \param iface a pointer to the interface to use.
- * \param mwi_msg a pointer to the message to use.
- *
- * This function puts a message back in the front of the specified queue. It
- * should be used if a message was popped but is not going to be processed for
- * some reason, and the message needs to be returned to the queue.
- */
-void ast_smdi_mwi_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *msg);
-
-/*!
- * \brief Find an SMDI interface with the specified name.
- * \param iface_name the name/port of the interface to search for.
- *
- * \return a pointer to the interface located or NULL if none was found. This
- * actually returns an ASTOBJ reference and should be released using
- * #ASTOBJ_UNREF(iface, ast_smdi_interface_destroy).
- */
-struct ast_smdi_interface *ast_smdi_interface_find(const char *iface_name);
-
-/*!
- * \brief Set the MWI indicator for a mailbox.
- * \param iface the interface to use.
- * \param mailbox the mailbox to use.
- */
-int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox);
-
-/*!
- * \brief Unset the MWI indicator for a mailbox.
- * \param iface the interface to use.
- * \param mailbox the mailbox to use.
- */
-int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox);
-
-/*! \brief ast_smdi_md_message destructor. */
-void ast_smdi_md_message_destroy(struct ast_smdi_md_message *msg);
-
-/*! \brief ast_smdi_mwi_message destructor. */
-void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg);
-
-#endif /* !ASTERISK_SMDI_H */
diff --git a/1.4/include/asterisk/speech.h b/1.4/include/asterisk/speech.h
deleted file mode 100644
index 6e6432342..000000000
--- a/1.4/include/asterisk/speech.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- * \brief Generic Speech Recognition API
- */
-
-#ifndef _ASTERISK_SPEECH_H
-#define _ASTERISK_SPEECH_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/* Speech structure flags */
-#define AST_SPEECH_QUIET (1 << 0) /* Quiet down output... they are talking */
-#define AST_SPEECH_SPOKE (1 << 1) /* Speaker did not speak */
-#define AST_SPEECH_HAVE_RESULTS (1 << 2) /* Results are present */
-
-/* Speech structure states - in order of expected change */
-#define AST_SPEECH_STATE_NOT_READY 0 /* Not ready to accept audio */
-#define AST_SPEECH_STATE_READY 1 /* Accepting audio */
-#define AST_SPEECH_STATE_WAIT 2 /* Wait for results to become available */
-#define AST_SPEECH_STATE_DONE 3 /* Processing is done */
-
-enum ast_speech_results_type {
- AST_SPEECH_RESULTS_TYPE_NORMAL = 0,
- AST_SPEECH_RESULTS_TYPE_NBEST,
-};
-
-/* Speech structure */
-struct ast_speech {
- /*! Structure lock */
- ast_mutex_t lock;
- /*! Set flags */
- unsigned int flags;
- /*! Processing sound (used when engine is processing audio and getting results) */
- char *processing_sound;
- /*! Current state of structure */
- int state;
- /*! Expected write format */
- int format;
- /*! Data for speech engine */
- void *data;
- /*! Cached results */
- struct ast_speech_result *results;
- /*! Type of results we want */
- enum ast_speech_results_type results_type;
- /*! Pointer to the engine used by this speech structure */
- struct ast_speech_engine *engine;
-};
-
-/* Speech recognition engine structure */
-struct ast_speech_engine {
- /*! Name of speech engine */
- char *name;
- /*! Set up the speech structure within the engine */
- int (*create)(struct ast_speech *speech);
- /*! Destroy any data set on the speech structure by the engine */
- int (*destroy)(struct ast_speech *speech);
- /*! Load a local grammar on the speech structure */
- int (*load)(struct ast_speech *speech, char *grammar_name, char *grammar);
- /*! Unload a local grammar */
- int (*unload)(struct ast_speech *speech, char *grammar_name);
- /*! Activate a loaded grammar */
- int (*activate)(struct ast_speech *speech, char *grammar_name);
- /*! Deactivate a loaded grammar */
- int (*deactivate)(struct ast_speech *speech, char *grammar_name);
- /*! Write audio to the speech engine */
- int (*write)(struct ast_speech *speech, void *data, int len);
- /*! Signal DTMF was received */
- int (*dtmf)(struct ast_speech *speech, const char *dtmf);
- /*! Prepare engine to accept audio */
- int (*start)(struct ast_speech *speech);
- /*! Change an engine specific setting */
- int (*change)(struct ast_speech *speech, char *name, const char *value);
- /*! Change the type of results we want back */
- int (*change_results_type)(struct ast_speech *speech, enum ast_speech_results_type results_type);
- /*! Try to get results */
- struct ast_speech_result *(*get)(struct ast_speech *speech);
- /*! Accepted formats by the engine */
- int formats;
- AST_LIST_ENTRY(ast_speech_engine) list;
-};
-
-/* Result structure */
-struct ast_speech_result {
- /*! Recognized text */
- char *text;
- /*! Result score */
- int score;
- /*! NBest Alternative number if in NBest results type */
- int nbest_num;
- /*! Matched grammar */
- char *grammar;
- /*! List information */
- struct ast_speech_result *next;
-};
-
-/*! \brief Activate a grammar on a speech structure */
-int ast_speech_grammar_activate(struct ast_speech *speech, char *grammar_name);
-/*! \brief Deactivate a grammar on a speech structure */
-int ast_speech_grammar_deactivate(struct ast_speech *speech, char *grammar_name);
-/*! \brief Load a grammar on a speech structure (not globally) */
-int ast_speech_grammar_load(struct ast_speech *speech, char *grammar_name, char *grammar);
-/*! \brief Unload a grammar */
-int ast_speech_grammar_unload(struct ast_speech *speech, char *grammar_name);
-/*! \brief Get speech recognition results */
-struct ast_speech_result *ast_speech_results_get(struct ast_speech *speech);
-/*! \brief Free a set of results */
-int ast_speech_results_free(struct ast_speech_result *result);
-/*! \brief Indicate to the speech engine that audio is now going to start being written */
-void ast_speech_start(struct ast_speech *speech);
-/*! \brief Create a new speech structure */
-struct ast_speech *ast_speech_new(char *engine_name, int format);
-/*! \brief Destroy a speech structure */
-int ast_speech_destroy(struct ast_speech *speech);
-/*! \brief Write audio to the speech engine */
-int ast_speech_write(struct ast_speech *speech, void *data, int len);
-/*! \brief Signal to the engine that DTMF was received */
-int ast_speech_dtmf(struct ast_speech *speech, const char *dtmf);
-/*! \brief Change an engine specific attribute */
-int ast_speech_change(struct ast_speech *speech, char *name, const char *value);
-/*! \brief Change the type of results we want */
-int ast_speech_change_results_type(struct ast_speech *speech, enum ast_speech_results_type results_type);
-/*! \brief Change state of a speech structure */
-int ast_speech_change_state(struct ast_speech *speech, int state);
-/*! \brief Register a speech recognition engine */
-int ast_speech_register(struct ast_speech_engine *engine);
-/*! \brief Unregister a speech recognition engine */
-int ast_speech_unregister(char *engine_name);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_SPEECH_H */
diff --git a/1.4/include/asterisk/srv.h b/1.4/include/asterisk/srv.h
deleted file mode 100644
index 567b40844..000000000
--- a/1.4/include/asterisk/srv.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*
- * DNS SRV record support
- */
-
-#ifndef _ASTERISK_SRV_H
-#define _ASTERISK_SRV_H
-
-/*!
- \file srv.h
- \brief Support for DNS SRV records, used in to locate SIP services.
- \note Note: This SRV record support will respect the priority and
- weight elements of the records that are returned, but there are
- no provisions for retrying or failover between records.
-*/
-
-/*! Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup
- Only do SRV record lookup if you get a domain without a port. If you get a port #, it's a DNS host name.
-*/
-/*! \param chan Ast channel
- \param host host name (return value)
- \param hostlen Length of string "host"
- \param port Port number (return value)
- \param service Service tag for SRV lookup (like "_sip._udp" or "_stun._udp"
-*/
-extern int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service);
-
-#endif /* _ASTERISK_SRV_H */
diff --git a/1.4/include/asterisk/stringfields.h b/1.4/include/asterisk/stringfields.h
deleted file mode 100644
index 8b32f9ee7..000000000
--- a/1.4/include/asterisk/stringfields.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- \brief String fields in structures
-
- This file contains objects and macros used to manage string
- fields in structures without requiring them to be allocated
- as fixed-size buffers or requiring individual allocations for
- for each field.
-
- Using this functionality is quite simple... an example structure
- with three fields is defined like this:
-
- \code
- struct sample_fields {
- int x1;
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(address);
- AST_STRING_FIELD(password);
- );
- long x2;
- };
- \endcode
-
- When an instance of this structure is allocated, the fields
- (and the pool of storage for them) must be initialized:
-
- \code
- struct sample_fields *sample;
-
- sample = calloc(1, sizeof(*sample));
- if (sample) {
- if (ast_string_field_init(sample, 256)) {
- free(sample);
- sample = NULL;
- }
- }
-
- if (!sample) {
- ...
- }
- \endcode
-
- Fields will default to pointing to an empty string, and will
- revert to that when ast_string_field_free() is called. This means
- that a string field will \b never contain NULL.
-
- Using the fields is much like using regular 'char *' fields
- in the structure, except that writing into them must be done
- using wrapper macros defined in this file.
-
- Storing simple values into fields can be done using ast_string_field_set();
- more complex values (using printf-style format strings) can be stored
- using ast_string_field_build().
-
- When the structure instance is no longer needed, the fields
- and their storage pool must be freed:
-
- \code
- ast_string_field_free_memory(sample);
- free(sample);
- \endcode
-*/
-
-#ifndef _ASTERISK_STRINGFIELDS_H
-#define _ASTERISK_STRINGFIELDS_H
-
-#include <string.h>
-#include <stdarg.h>
-#include <stddef.h>
-
-#include "asterisk/inline_api.h"
-#include "asterisk/compiler.h"
-#include "asterisk/compat.h"
-
-/*!
- \internal
- \brief An opaque type for managed string fields in structures
-
- Don't declare instances of this type directly; use the AST_STRING_FIELD()
- macro instead.
-*/
-typedef const char * ast_string_field;
-
-/*!
- \internal
- \brief A constant empty string used for fields that have no other value
-*/
-extern const char __ast_string_field_empty[];
-
-/*!
- \internal
- \brief Structure used to hold a pool of space for string fields
-*/
-struct ast_string_field_pool {
- struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */
- char base[0]; /*!< storage space for the fields */
-};
-
-/*!
- \internal
- \brief Structure used to manage the storage for a set of string fields
-*/
-struct ast_string_field_mgr {
- struct ast_string_field_pool *pool; /*!< the address of the pool's structure */
- size_t size; /*!< the total size of the current pool */
- size_t space; /*!< the space available in the current pool */
- size_t used; /*!< the space used in the current pool */
-};
-
-/*!
- \internal
- \brief Initialize a field pool manager and fields
- \param mgr Pointer to the pool manager structure
- \param size Amount of storage to allocate
- \param fields Pointer to the first entry of the field array
- \param num_fields Number of fields in the array
- \return 0 on success, non-zero on failure
-*/
-int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
- ast_string_field *fields, int num_fields);
-
-/*!
- \internal
- \brief Allocate space for a field
- \param mgr Pointer to the pool manager structure
- \param needed Amount of space needed for this field
- \param fields Pointer to the first entry of the field array
- \param num_fields Number of fields in the array
- \return NULL on failure, an address for the field on success
-
- This function will allocate the requested amount of space from
- the field pool. If the requested amount of space is not available,
- an additional pool will be allocated.
-*/
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
- ast_string_field *fields, int num_fields);
-
-/*!
- \internal
- \brief Set a field to a complex (built) value
- \param mgr Pointer to the pool manager structure
- \param fields Pointer to the first entry of the field array
- \param num_fields Number of fields in the array
- \param index Index position of the field within the structure
- \param format printf-style format string
- \return nothing
-*/
-void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
- ast_string_field *fields, int num_fields,
- int index, const char *format, ...);
-
-/*!
- \internal
- \brief Set a field to a complex (built) value
- \param mgr Pointer to the pool manager structure
- \param fields Pointer to the first entry of the field array
- \param num_fields Number of fields in the array
- \param index Index position of the field within the structure
- \param format printf-style format string
- \param args va_list of the args for the format_string
- \param args_again a copy of the first va_list for the sake of bsd not having a copy routine
- \return nothing
-*/
-void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
- ast_string_field *fields, int num_fields,
- int index, const char *format, va_list a1, va_list a2);
-
-/*!
- \brief Declare a string field
- \param name The field name
-*/
-#define AST_STRING_FIELD(name) const ast_string_field name
-
-/*!
- \brief Declare the fields needed in a structure
- \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one
-*/
-#define AST_DECLARE_STRING_FIELDS(field_list) \
- ast_string_field __begin_field[0]; \
- field_list \
- ast_string_field __end_field[0]; \
- struct ast_string_field_mgr __field_mgr
-
-/*!
- \brief Get the number of string fields in a structure
- \param x Pointer to a structure containing fields
- \return the number of fields in the structure's definition
-*/
-#define ast_string_field_count(x) \
- (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field)
-
-/*!
- \brief Get the index of a field in a structure
- \param x Pointer to a structure containing fields
- \param field Name of the field to locate
- \return the position (index) of the field within the structure's
- array of fields
-*/
-#define ast_string_field_index(x, field) \
- (offsetof(typeof(*x), field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field)
-
-/*!
- \brief Initialize a field pool and fields
- \param x Pointer to a structure containing fields
- \param size Amount of storage to allocate
- \return 0 on success, non-zero on failure
-*/
-#define ast_string_field_init(x, size) \
- __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x))
-
-/*!
- \brief Set a field to a simple string value
- \param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
- \param data String value to be copied into the field
- \return nothing
-*/
-#define ast_string_field_index_set(x, index, data) do { \
- char *__zz__ = (char*)(x)->__begin_field[index]; \
- size_t __dlen__ = strlen(data); \
- if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
- } else { \
- if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
- strcpy(__zz__, data); \
- } else { \
- if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0], ast_string_field_count(x)))) \
- strcpy((char*)(x)->__begin_field[index], data); \
- } \
- } \
- } while (0)
-
-#ifdef FOR_TEST
-#define ast_string_field_index_logset(x, index, data, logstr) do { \
- char *__zz__ = (char*)(x)->__begin_field[index]; \
- size_t __dlen__ = strlen(data); \
- if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
- } else { \
- if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
- ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, data); \
- strcpy(__zz__, data); \
- } else { \
- ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, data, __zz__); \
- if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0], ast_string_field_count(x)))) \
- strcpy((char*)(x)->__begin_field[index], data); \
- } \
- } \
- } while (0)
-#endif
-
-/*!
- \brief Set a field to a simple string value
- \param x Pointer to a structure containing fields
- \param field Name of the field to set
- \param data String value to be copied into the field
- \return nothing
-*/
-#define ast_string_field_set(x, field, data) \
- ast_string_field_index_set(x, ast_string_field_index(x, field), data)
-
-#ifdef FOR_TEST
-#define ast_string_field_logset(x, field, data, logstr) \
- ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr)
-#endif
-
-/*!
- \brief Set a field to a complex (built) value
- \param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
- \param fmt printf-style format string
- \param args Arguments for format string
- \return nothing
-*/
-#define ast_string_field_index_build(x, index, fmt, args...) \
- __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args)
-
-/*!
- \brief Set a field to a complex (built) value with prebuilt va_lists.
- \param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
- \param fmt printf-style format string
- \param args1 Arguments for format string in va_list format
- \param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation
- \return nothing
-*/
-#define ast_string_field_index_build_va(x, index, fmt, args1, args2) \
- __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args1, args2)
-
-/*!
- \brief Set a field to a complex (built) value
- \param x Pointer to a structure containing fields
- \param field Name of the field to set
- \param fmt printf-style format string
- \param args Arguments for format string
- \return nothing
-*/
-#define ast_string_field_build(x, field, fmt, args...) \
- ast_string_field_index_build(x, ast_string_field_index(x, field), fmt, args)
-
-/*!
- \brief Set a field to a complex (built) value
- \param x Pointer to a structure containing fields
- \param field Name of the field to set
- \param fmt printf-style format string
- \param argslist a va_list of the args
- \return nothing
-*/
-#define ast_string_field_build_va(x, field, fmt, args1, args2) \
- ast_string_field_index_build_va(x, ast_string_field_index(x, field), fmt, args1, args2)
-
-/*!
- \brief Free a field's value.
- \param x Pointer to a structure containing fields
- \param index Index position of the field within the structure
- \return nothing
-
- \note Because of the storage pool used, the memory
- occupied by the field's value is \b not recovered; the field
- pointer is just changed to point to an empty string.
-*/
-#define ast_string_field_index_free(x, index) do { \
- (x)->__begin_field[index] = __ast_string_field_empty; \
- } while(0)
-
-/*!
- \brief Free a field's value.
- \param x Pointer to a structure containing fields
- \param field Name of the field to free
- \return nothing
-
- \note Because of the storage pool used, the memory
- occupied by the field's value is \b not recovered; the field
- pointer is just changed to point to an empty string.
-*/
-#define ast_string_field_free(x, field) \
- ast_string_field_index_free(x, ast_string_field_index(x, field))
-
-/*!
- \brief Free the stringfield storage pools attached to a structure
- \param x Pointer to a structure containing fields
- \return nothing
-
- After calling this macro, fields can no longer be accessed in
- structure; it should only be called immediately before freeing
- the structure itself.
-*/
-#define ast_string_field_free_memory(x) do { \
- struct ast_string_field_pool *this, *prev; \
- for (this = (x)->__field_mgr.pool; this; this = prev) { \
- prev = this->prev; \
- free(this); \
- } \
- } while(0)
-
-/*!
- \brief Free the stringfields in a structure
- \param x Pointer to a structure containing fields
- \return nothing
-
- After calling this macro, the most recently allocated pool
- attached to the structure will be available for use by
- stringfields again.
-*/
-#define ast_string_field_reset_all(x) do { \
- int index; \
- for (index = 0; index < ast_string_field_count(x); index++) \
- ast_string_field_index_free(x, index); \
- (x)->__field_mgr.used = 0; \
- (x)->__field_mgr.space = (x)->__field_mgr.size; \
- } while(0)
-
-#endif /* _ASTERISK_STRINGFIELDS_H */
diff --git a/1.4/include/asterisk/strings.h b/1.4/include/asterisk/strings.h
deleted file mode 100644
index 70517a4d6..000000000
--- a/1.4/include/asterisk/strings.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief String manipulation functions
- */
-
-#ifndef _ASTERISK_STRINGS_H
-#define _ASTERISK_STRINGS_H
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include "asterisk/inline_api.h"
-#include "asterisk/compiler.h"
-#include "asterisk/compat.h"
-
-static force_inline int ast_strlen_zero(const char *s)
-{
- return (!s || (*s == '\0'));
-}
-
-/*! \brief returns the equivalent of logic or for strings:
- * first one if not empty, otherwise second one.
- */
-#define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
-
-/*!
- \brief Gets a pointer to the first non-whitespace character in a string.
- \param ast_skip_blanks function being used
- \param str the input string
- \return a pointer to the first non-whitespace character
- */
-AST_INLINE_API(
-char *ast_skip_blanks(const char *str),
-{
- while (*str && ((unsigned char) *str) < 33)
- str++;
- return (char *)str;
-}
-)
-
-/*!
- \brief Trims trailing whitespace characters from a string.
- \param ast_trim_blanks function being used
- \param str the input string
- \return a pointer to the modified string
- */
-AST_INLINE_API(
-char *ast_trim_blanks(char *str),
-{
- char *work = str;
-
- if (work) {
- work += strlen(work) - 1;
- /* It's tempting to only want to erase after we exit this loop,
- but since ast_trim_blanks *could* receive a constant string
- (which we presumably wouldn't have to touch), we shouldn't
- actually set anything unless we must, and it's easier just
- to set each position to \0 than to keep track of a variable
- for it */
- while ((work >= str) && ((unsigned char) *work) < 33)
- *(work--) = '\0';
- }
- return str;
-}
-)
-
-/*!
- \brief Gets a pointer to first whitespace character in a string.
- \param ast_skip_noblanks function being used
- \param str the input string
- \return a pointer to the first whitespace character
- */
-AST_INLINE_API(
-char *ast_skip_nonblanks(char *str),
-{
- while (*str && ((unsigned char) *str) > 32)
- str++;
- return str;
-}
-)
-
-/*!
- \brief Strip leading/trailing whitespace from a string.
- \param s The string to be stripped (will be modified).
- \return The stripped string.
-
- This functions strips all leading and trailing whitespace
- characters from the input string, and returns a pointer to
- the resulting string. The string is modified in place.
-*/
-AST_INLINE_API(
-char *ast_strip(char *s),
-{
- s = ast_skip_blanks(s);
- if (s)
- ast_trim_blanks(s);
- return s;
-}
-)
-
-/*!
- \brief Strip leading/trailing whitespace and quotes from a string.
- \param s The string to be stripped (will be modified).
- \param beg_quotes The list of possible beginning quote characters.
- \param end_quotes The list of matching ending quote characters.
- \return The stripped string.
-
- This functions strips all leading and trailing whitespace
- characters from the input string, and returns a pointer to
- the resulting string. The string is modified in place.
-
- It can also remove beginning and ending quote (or quote-like)
- characters, in matching pairs. If the first character of the
- string matches any character in beg_quotes, and the last
- character of the string is the matching character in
- end_quotes, then they are removed from the string.
-
- Examples:
- \code
- ast_strip_quoted(buf, "\"", "\"");
- ast_strip_quoted(buf, "'", "'");
- ast_strip_quoted(buf, "[{(", "]})");
- \endcode
- */
-char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes);
-
-/*!
- \brief Strip backslash for "escaped" semicolons.
- \brief s The string to be stripped (will be modified).
- \return The stripped string.
- */
-char *ast_unescape_semicolon(char *s);
-
-/*!
- \brief Size-limited null-terminating string copy.
- \param ast_copy_string function being used
- \param dst The destination buffer.
- \param src The source string
- \param size The size of the destination buffer
- \return Nothing.
-
- This is similar to \a strncpy, with two important differences:
- - the destination buffer will \b always be null-terminated
- - the destination buffer is not filled with zeros past the copied string length
- These differences make it slightly more efficient, and safer to use since it will
- not leave the destination buffer unterminated. There is no need to pass an artificially
- reduced buffer size to this function (unlike \a strncpy), and the buffer does not need
- to be initialized to zeroes prior to calling this function.
-*/
-AST_INLINE_API(
-void ast_copy_string(char *dst, const char *src, size_t size),
-{
- while (*src && size) {
- *dst++ = *src++;
- size--;
- }
- if (__builtin_expect(!size, 0))
- dst--;
- *dst = '\0';
-}
-)
-
-
-/*!
- \brief Build a string in a buffer, designed to be called repeatedly
-
- This is a wrapper for snprintf, that properly handles the buffer pointer
- and buffer space available.
-
- \param buffer current position in buffer to place string into (will be updated on return)
- \param space remaining space in buffer (will be updated on return)
- \param fmt printf-style format string
- \return 0 on success, non-zero on failure.
-*/
-int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
-
-/*!
- \brief Build a string in a buffer, designed to be called repeatedly
-
- This is a wrapper for snprintf, that properly handles the buffer pointer
- and buffer space available.
-
- \return 0 on success, non-zero on failure.
- \param buffer current position in buffer to place string into (will be updated on return)
- \param space remaining space in buffer (will be updated on return)
- \param fmt printf-style format string
- \param ap varargs list of arguments for format
-*/
-int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap);
-
-/*! Make sure something is true */
-/*!
- * Determine if a string containing a boolean value is "true".
- * This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
- *
- * Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise.
- */
-int ast_true(const char *val);
-
-/*! Make sure something is false */
-/*!
- * Determine if a string containing a boolean value is "false".
- * This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0".
- *
- * Returns 0 if val is a NULL pointer, -1 if "false", and 0 otherwise.
- */
-int ast_false(const char *val);
-
-/*
- \brief Join an array of strings into a single string.
- \param s the resulting string buffer
- \param len the length of the result buffer, s
- \param w an array of strings to join
-
- This function will join all of the strings in the array 'w' into a single
- string. It will also place a space in the result buffer in between each
- string from 'w'.
-*/
-void ast_join(char *s, size_t len, char * const w[]);
-
-/*
- \brief Parse a time (integer) string.
- \param src String to parse
- \param dst Destination
- \param _default Value to use if the string does not contain a valid time
- \param consumed The number of characters 'consumed' in the string by the parse (see 'man sscanf' for details)
- \return zero on success, non-zero on failure
-*/
-int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed);
-
-/* The realloca lets us ast_restrdupa(), but you can't mix any other ast_strdup calls! */
-
-struct ast_realloca {
- char *ptr;
- int alloclen;
-};
-
-#define ast_restrdupa(ra, s) \
- ({ \
- if ((ra)->ptr && strlen(s) + 1 < (ra)->alloclen) { \
- strcpy((ra)->ptr, s); \
- } else { \
- (ra)->ptr = alloca(strlen(s) + 1 - (ra)->alloclen); \
- if ((ra)->ptr) (ra)->alloclen = strlen(s) + 1; \
- } \
- (ra)->ptr; \
- })
-
-/*!
- * \brief Compute a hash value on a string
- *
- * This famous hash algorithm was written by Dan Bernstein and is
- * commonly used.
- *
- * http://www.cse.yorku.ca/~oz/hash.html
- */
-static force_inline int ast_str_hash(const char *str)
-{
- int hash = 5381;
-
- while (*str)
- hash = hash * 33 ^ *str++;
-
- return abs(hash);
-}
-
-#endif /* _ASTERISK_STRINGS_H */
diff --git a/1.4/include/asterisk/tdd.h b/1.4/include/asterisk/tdd.h
deleted file mode 100644
index bdd02bb40..000000000
--- a/1.4/include/asterisk/tdd.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief TTY/TDD Generation support
- * \note Includes code and algorithms from the Zapata library.
- */
-
-#ifndef _ASTERISK_TDD_H
-#define _ASTERISK_TDD_H
-
-#define TDD_BYTES_PER_CHAR 2700
-
-struct tdd_state;
-typedef struct tdd_state TDDSTATE;
-
-/*! CallerID Initialization */
-/*!
- * Initializes the TDD system. Mostly stuff for inverse FFT
- */
-void tdd_init(void);
-
-/*! Generates a CallerID FSK stream in ulaw format suitable for transmission. */
-/*!
- * \param tdd tdd structure
- * \param buf Buffer to use. This needs to be large enough to accomodate all the generated samples.
- * \param string This is the string to send.
- * This function creates a stream of TDD data in ulaw format. It returns the size
- * (in bytes) of the data (if it returns a size of 0, there is probably an error)
-*/
-int tdd_generate(struct tdd_state *tdd, unsigned char *buf, const char *string);
-
-/*! Create a TDD state machine */
-/*!
- * This function returns a malloc'd instance of the tdd_state data structure.
- * Returns a pointer to a malloc'd tdd_state structure, or NULL on error.
- */
-struct tdd_state *tdd_new(void);
-
-/*! Read samples into the state machine, and return character (if any). */
-/*!
- * \param tdd Which state machine to act upon
- * \param ubuf containing your samples
- * \param samples number of samples contained within the buffer.
- *
- * Send received audio to the TDD demodulator.
- * Returns -1 on error, 0 for "needs more samples",
- * and > 0 (the character) if reception of a character is complete.
- */
-int tdd_feed(struct tdd_state *tdd, unsigned char *ubuf, int samples);
-
-/*! Free a TDD state machine */
-/*!
- * \param tdd This is the tdd_state state machine to free
- * This function frees tdd_state tdd.
- */
-void tdd_free(struct tdd_state *tdd);
-
-/*! Generate Echo Canceller diable tone (2100HZ) */
-/*!
- * \param outbuf This is the buffer to receive the tone data
- * \param len This is the length (in samples) of the tone data to generate
- * Returns 0 if no error, and -1 if error.
- */
-int ast_tdd_gen_ecdisa(unsigned char *outbuf, int len);
-
-#endif /* _ASTERISK_TDD_H */
diff --git a/1.4/include/asterisk/term.h b/1.4/include/asterisk/term.h
deleted file mode 100644
index 3b454ce2c..000000000
--- a/1.4/include/asterisk/term.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Handy terminal functions for vt* terms
- */
-
-#ifndef _ASTERISK_TERM_H
-#define _ASTERISK_TERM_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define ESC 0x1b
-#define ATTR_RESET 0
-#define ATTR_BRIGHT 1
-#define ATTR_DIM 2
-#define ATTR_UNDER 4
-#define ATTR_BLINK 5
-#define ATTR_REVER 7
-#define ATTR_HIDDEN 8
-
-#define COLOR_BLACK 30
-#define COLOR_GRAY (30 | 128)
-#define COLOR_RED 31
-#define COLOR_BRRED (31 | 128)
-#define COLOR_GREEN 32
-#define COLOR_BRGREEN (32 | 128)
-#define COLOR_BROWN 33
-#define COLOR_YELLOW (33 | 128)
-#define COLOR_BLUE 34
-#define COLOR_BRBLUE (34 | 128)
-#define COLOR_MAGENTA 35
-#define COLOR_BRMAGENTA (35 | 128)
-#define COLOR_CYAN 36
-#define COLOR_BRCYAN (36 | 128)
-#define COLOR_WHITE 37
-#define COLOR_BRWHITE (37 | 128)
-
-char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout);
-
-char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout);
-
-char *term_strip(char *outbuf, char *inbuf, int maxout);
-
-void term_filter_escapes(char *line);
-
-char *term_prompt(char *outbuf, const char *inbuf, int maxout);
-
-char *term_prep(void);
-
-char *term_end(void);
-
-char *term_quit(void);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_TERM_H */
diff --git a/1.4/include/asterisk/threadstorage.h b/1.4/include/asterisk/threadstorage.h
deleted file mode 100644
index 9021aa551..000000000
--- a/1.4/include/asterisk/threadstorage.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Russell Bryant <russell@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.
- */
-
-/*!
- * \file threadstorage.h
- * \author Russell Bryant <russell@digium.com>
- *
- * \brief Definitions to aid in the use of thread local storage
-*/
-
-#ifndef ASTERISK_THREADSTORAGE_H
-#define ASTERISK_THREADSTORAGE_H
-
-#include <pthread.h>
-
-#include "asterisk/utils.h"
-#include "asterisk/inline_api.h"
-
-/*!
- * \brief data for a thread locally stored variable
- */
-struct ast_threadstorage {
- /*! Ensure that the key is only initialized by one thread */
- pthread_once_t once;
- /*! The key used to retrieve this thread's data */
- pthread_key_t key;
- /*! The function that initializes the key */
- void (*key_init)(void);
-};
-
-#ifdef SOLARIS
-#define THREADSTORAGE_ONCE_INIT {PTHREAD_ONCE_INIT}
-#else
-#define THREADSTORAGE_ONCE_INIT PTHREAD_ONCE_INIT
-#endif
-
-#if defined(DEBUG_THREADLOCALS)
-void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line);
-void __ast_threadstorage_object_remove(void *key);
-void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len);
-#endif /* defined(DEBUG_THREADLOCALS) */
-
-/*!
- * \brief Define a thread storage variable
- *
- * \arg name The name of the thread storage
- * \arg name_init This is a name used to create the function that gets called
- * to initialize this thread storage. It can be anything since it will not
- * be referred to anywhere else
- *
- * This macro would be used to declare an instance of thread storage in a file.
- *
- * Example usage:
- * \code
- * AST_THREADSTORAGE(my_buf, my_buf_init);
- * \endcode
- */
-#define AST_THREADSTORAGE(name, name_init) \
- AST_THREADSTORAGE_CUSTOM(name, name_init, ast_free)
-
-#if !defined(DEBUG_THREADLOCALS)
-#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup) \
-static void name_init(void); \
-static struct ast_threadstorage name = { \
- .once = THREADSTORAGE_ONCE_INIT, \
- .key_init = name_init, \
-}; \
-static void name_init(void) \
-{ \
- pthread_key_create(&(name).key, cleanup); \
-}
-#else /* defined(DEBUG_THREADLOCALS) */
-#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup) \
-static void name_init(void); \
-static struct ast_threadstorage name = { \
- .once = THREADSTORAGE_ONCE_INIT, \
- .key_init = name_init, \
-}; \
-static void __cleanup_##name(void *data) \
-{ \
- __ast_threadstorage_object_remove(data); \
- cleanup(data); \
-} \
-static void name_init(void) \
-{ \
- pthread_key_create(&(name).key, __cleanup_##name); \
-}
-#endif /* defined(DEBUG_THREADLOCALS) */
-
-/*!
- * \brief Retrieve thread storage
- *
- * \arg ts This is a pointer to the thread storage structure declared by using
- * the AST_THREADSTORAGE macro. If declared with
- * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
- * (&my_buf).
- * \arg init_size This is the amount of space to be allocated the first time
- * this thread requests its data. Thus, this should be the size that the
- * code accessing this thread storage is assuming the size to be.
- *
- * \return This function will return the thread local storage associated with
- * the thread storage management variable passed as the first argument.
- * The result will be NULL in the case of a memory allocation error.
- *
- * Example usage:
- * \code
- * AST_THREADSTORAGE(my_buf, my_buf_init);
- * #define MY_BUF_SIZE 128
- * ...
- * void my_func(const char *fmt, ...)
- * {
- * void *buf;
- *
- * if (!(buf = ast_threadstorage_get(&my_buf, MY_BUF_SIZE)))
- * return;
- * ...
- * }
- * \endcode
- */
-#if !defined(DEBUG_THREADLOCALS)
-AST_INLINE_API(
-void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
-{
- void *buf;
-
- pthread_once(&ts->once, ts->key_init);
- if (!(buf = pthread_getspecific(ts->key))) {
- if (!(buf = ast_calloc(1, init_size)))
- return NULL;
- pthread_setspecific(ts->key, buf);
- }
-
- return buf;
-}
-)
-#else /* defined(DEBUG_THREADLOCALS) */
-AST_INLINE_API(
-void *__ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size, const char *file, const char *function, unsigned int line),
-{
- void *buf;
-
- pthread_once(&ts->once, ts->key_init);
- if (!(buf = pthread_getspecific(ts->key))) {
- if (!(buf = ast_calloc(1, init_size)))
- return NULL;
- pthread_setspecific(ts->key, buf);
- __ast_threadstorage_object_add(buf, init_size, file, function, line);
- }
-
- return buf;
-}
-)
-
-#define ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#endif /* defined(DEBUG_THREADLOCALS) */
-
-/*!
- * \brief A dynamic length string
- */
-struct ast_dynamic_str {
- /* The current maximum length of the string */
- size_t len;
- /* The string buffer */
- char str[0];
-};
-
-/*!
- * \brief Create a dynamic length string
- *
- * \arg init_len This is the initial length of the string buffer
- *
- * \return This function returns a pointer to the dynamic string length. The
- * result will be NULL in the case of a memory allocation error.
- *
- * /note The result of this function is dynamically allocated memory, and must
- * be free()'d after it is no longer needed.
- */
-AST_INLINE_API(
-struct ast_dynamic_str * attribute_malloc ast_dynamic_str_create(size_t init_len),
-{
- struct ast_dynamic_str *buf;
-
- if (!(buf = ast_calloc(1, sizeof(*buf) + init_len)))
- return NULL;
-
- buf->len = init_len;
-
- return buf;
-}
-)
-
-/*!
- * \brief Retrieve a thread locally stored dynamic string
- *
- * \arg ts This is a pointer to the thread storage structure declared by using
- * the AST_THREADSTORAGE macro. If declared with
- * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
- * (&my_buf).
- * \arg init_len This is the initial length of the thread's dynamic string. The
- * current length may be bigger if previous operations in this thread have
- * caused it to increase.
- *
- * \return This function will return the thread locally storaged dynamic string
- * associated with the thread storage management variable passed as the
- * first argument.
- * The result will be NULL in the case of a memory allocation error.
- *
- * Example usage:
- * \code
- * AST_THREADSTORAGE(my_str, my_str_init);
- * #define MY_STR_INIT_SIZE 128
- * ...
- * void my_func(const char *fmt, ...)
- * {
- * struct ast_dynamic_str *buf;
- *
- * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
- * return;
- * ...
- * }
- * \endcode
- */
-#if !defined(DEBUG_THREADLOCALS)
-AST_INLINE_API(
-struct ast_dynamic_str *ast_dynamic_str_thread_get(struct ast_threadstorage *ts,
- size_t init_len),
-{
- struct ast_dynamic_str *buf;
-
- if (!(buf = ast_threadstorage_get(ts, sizeof(*buf) + init_len)))
- return NULL;
-
- if (!buf->len)
- buf->len = init_len;
-
- return buf;
-}
-)
-#else /* defined(DEBUG_THREADLOCALS) */
-AST_INLINE_API(
-struct ast_dynamic_str *__ast_dynamic_str_thread_get(struct ast_threadstorage *ts,
- size_t init_len, const char *file, const char *function, unsigned int line),
-{
- struct ast_dynamic_str *buf;
-
- if (!(buf = __ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line)))
- return NULL;
-
- if (!buf->len)
- buf->len = init_len;
-
- return buf;
-}
-)
-
-#define ast_dynamic_str_thread_get(ts, init_len) __ast_dynamic_str_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#endif /* defined(DEBUG_THREADLOCALS) */
-
-/*!
- * \brief Error codes from ast_dynamic_str_thread_build_va()
- */
-enum {
- /*! An error has occured and the contents of the dynamic string
- * are undefined */
- AST_DYNSTR_BUILD_FAILED = -1,
- /*! The buffer size for the dynamic string had to be increased, and
- * ast_dynamic_str_thread_build_va() needs to be called again after
- * a va_end() and va_start().
- */
- AST_DYNSTR_BUILD_RETRY = -2
-};
-
-/*!
- * \brief Set a thread locally stored dynamic string from a va_list
- *
- * \arg buf This is the address of a pointer to an ast_dynamic_str which should
- * have been retrieved using ast_dynamic_str_thread_get. It will need to
- * be updated in the case that the buffer has to be reallocated to
- * accomodate a longer string than what it currently has space for.
- * \arg max_len This is the maximum length to allow the string buffer to grow
- * to. If this is set to 0, then there is no maximum length.
- * \arg ts This is a pointer to the thread storage structure declared by using
- * the AST_THREADSTORAGE macro. If declared with
- * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
- * (&my_buf).
- * \arg fmt This is the format string (printf style)
- * \arg ap This is the va_list
- *
- * \return The return value of this function is the same as that of the printf
- * family of functions.
- *
- * Example usage:
- * \code
- * AST_THREADSTORAGE(my_str, my_str_init);
- * #define MY_STR_INIT_SIZE 128
- * ...
- * void my_func(const char *fmt, ...)
- * {
- * struct ast_dynamic_str *buf;
- * va_list ap;
- *
- * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
- * return;
- * ...
- * va_start(fmt, ap);
- * ast_dynamic_str_thread_set_va(&buf, 0, &my_str, fmt, ap);
- * va_end(ap);
- *
- * printf("This is the string we just built: %s\n", buf->str);
- * ...
- * }
- * \endcode
- */
-#define ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap) \
- ({ \
- int __res; \
- while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
- ts, 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
- va_end(ap); \
- va_start(ap, fmt); \
- } \
- (__res); \
- })
-
-/*!
- * \brief Append to a thread local dynamic string using a va_list
- *
- * The arguments, return values, and usage of this are the same as those for
- * ast_dynamic_str_thread_set_va(). However, instead of setting a new value
- * for the string, this will append to the current value.
- */
-#define ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap) \
- ({ \
- int __res; \
- while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
- ts, 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
- va_end(ap); \
- va_start(ap, fmt); \
- } \
- (__res); \
- })
-
-/*!
- * \brief Core functionality of ast_dynamic_str_thread_(set|append)_va
- *
- * The arguments to this function are the same as those described for
- * ast_dynamic_str_thread_set_va except for an addition argument, append.
- * If append is non-zero, this will append to the current string instead of
- * writing over it.
- */
-int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
- struct ast_threadstorage *ts, int append, const char *fmt, va_list ap);
-
-/*!
- * \brief Set a thread locally stored dynamic string using variable arguments
- *
- * \arg buf This is the address of a pointer to an ast_dynamic_str which should
- * have been retrieved using ast_dynamic_str_thread_get. It will need to
- * be updated in the case that the buffer has to be reallocated to
- * accomodate a longer string than what it currently has space for.
- * \arg max_len This is the maximum length to allow the string buffer to grow
- * to. If this is set to 0, then there is no maximum length.
- * \arg ts This is a pointer to the thread storage structure declared by using
- * the AST_THREADSTORAGE macro. If declared with
- * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
- * (&my_buf).
- * \arg fmt This is the format string (printf style)
- *
- * \return The return value of this function is the same as that of the printf
- * family of functions.
- *
- * Example usage:
- * \code
- * AST_THREADSTORAGE(my_str, my_str_init);
- * #define MY_STR_INIT_SIZE 128
- * ...
- * void my_func(int arg1, int arg2)
- * {
- * struct ast_dynamic_str *buf;
- * va_list ap;
- *
- * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
- * return;
- * ...
- * ast_dynamic_str_thread_set(&buf, 0, &my_str, "arg1: %d arg2: %d\n",
- * arg1, arg2);
- *
- * printf("This is the string we just built: %s\n", buf->str);
- * ...
- * }
- * \endcode
- */
-AST_INLINE_API(
-int __attribute__ ((format (printf, 4, 5))) ast_dynamic_str_thread_set(
- struct ast_dynamic_str **buf, size_t max_len,
- struct ast_threadstorage *ts, const char *fmt, ...),
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap);
- va_end(ap);
-
- return res;
-}
-)
-
-/*!
- * \brief Append to a thread local dynamic string
- *
- * The arguments, return values, and usage of this function are the same as
- * ast_dynamic_str_thread_set(). However, instead of setting a new value for
- * the string, this function appends to the current value.
- */
-AST_INLINE_API(
-int __attribute__ ((format (printf, 4, 5))) ast_dynamic_str_thread_append(
- struct ast_dynamic_str **buf, size_t max_len,
- struct ast_threadstorage *ts, const char *fmt, ...),
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap);
- va_end(ap);
-
- return res;
-}
-)
-
-/*!
- * \brief Set a dynamic string
- *
- * \arg buf This is the address of a pointer to an ast_dynamic_str. It will
- * need to be updated in the case that the buffer has to be reallocated to
- * accomodate a longer string than what it currently has space for.
- * \arg max_len This is the maximum length to allow the string buffer to grow
- * to. If this is set to 0, then there is no maximum length.
- *
- * \return The return value of this function is the same as that of the printf
- * family of functions.
- */
-AST_INLINE_API(
-int __attribute__ ((format (printf, 3, 4))) ast_dynamic_str_set(
- struct ast_dynamic_str **buf, size_t max_len,
- const char *fmt, ...),
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(buf, max_len, NULL, fmt, ap);
- va_end(ap);
-
- return res;
-}
-)
-
-/*!
- * \brief Append to a dynatic string
- *
- * The arguments, return values, and usage of this function are the same as
- * ast_dynamic_str_set(). However, this function appends to the string instead
- * of setting a new value.
- */
-AST_INLINE_API(
-int __attribute__ ((format (printf, 3, 4))) ast_dynamic_str_append(
- struct ast_dynamic_str **buf, size_t max_len,
- const char *fmt, ...),
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_append_va(buf, max_len, NULL, fmt, ap);
- va_end(ap);
-
- return res;
-}
-)
-
-#endif /* ASTERISK_THREADSTORAGE_H */
diff --git a/1.4/include/asterisk/time.h b/1.4/include/asterisk/time.h
deleted file mode 100644
index 92a5346a5..000000000
--- a/1.4/include/asterisk/time.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Time-related functions and macros
- */
-
-#ifndef _ASTERISK_TIME_H
-#define _ASTERISK_TIME_H
-
-#include <sys/time.h>
-#include <stdlib.h>
-
-#include "asterisk/inline_api.h"
-
-/* We have to let the compiler learn what types to use for the elements of a
- struct timeval since on linux, it's time_t and suseconds_t, but on *BSD,
- they are just a long. */
-extern struct timeval tv;
-typedef typeof(tv.tv_sec) ast_time_t;
-typedef typeof(tv.tv_usec) ast_suseconds_t;
-
-/*!
- * \brief Computes the difference (in milliseconds) between two \c struct \c timeval instances.
- * \param end end of the time period
- * \param start beginning of the time period
- * \return the difference in milliseconds
- */
-AST_INLINE_API(
-int ast_tvdiff_ms(struct timeval end, struct timeval start),
-{
- /* the offset by 1,000,000 below is intentional...
- it avoids differences in the way that division
- is handled for positive and negative numbers, by ensuring
- that the divisor is always positive
- */
- return ((end.tv_sec - start.tv_sec) * 1000) +
- (((1000000 + end.tv_usec - start.tv_usec) / 1000) - 1000);
-}
-)
-
-/*!
- * \brief Returns true if the argument is 0,0
- */
-AST_INLINE_API(
-int ast_tvzero(const struct timeval t),
-{
- return (t.tv_sec == 0 && t.tv_usec == 0);
-}
-)
-
-/*!
- * \brief Compres two \c struct \c timeval instances returning
- * -1, 0, 1 if the first arg is smaller, equal or greater to the second.
- */
-AST_INLINE_API(
-int ast_tvcmp(struct timeval _a, struct timeval _b),
-{
- if (_a.tv_sec < _b.tv_sec)
- return -1;
- if (_a.tv_sec > _b.tv_sec)
- return 1;
- /* now seconds are equal */
- if (_a.tv_usec < _b.tv_usec)
- return -1;
- if (_a.tv_usec > _b.tv_usec)
- return 1;
- return 0;
-}
-)
-
-/*!
- * \brief Returns true if the two \c struct \c timeval arguments are equal.
- */
-AST_INLINE_API(
-int ast_tveq(struct timeval _a, struct timeval _b),
-{
- return (_a.tv_sec == _b.tv_sec && _a.tv_usec == _b.tv_usec);
-}
-)
-
-/*!
- * \brief Returns current timeval. Meant to replace calls to gettimeofday().
- */
-AST_INLINE_API(
-struct timeval ast_tvnow(void),
-{
- struct timeval t;
- gettimeofday(&t, NULL);
- return t;
-}
-)
-
-/*!
- * \brief Returns the sum of two timevals a + b
- */
-struct timeval ast_tvadd(struct timeval a, struct timeval b);
-
-/*!
- * \brief Returns the difference of two timevals a - b
- */
-struct timeval ast_tvsub(struct timeval a, struct timeval b);
-
-/*!
- * \brief Returns a timeval from sec, usec
- */
-AST_INLINE_API(
-struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec),
-{
- struct timeval t;
- t.tv_sec = sec;
- t.tv_usec = usec;
- return t;
-}
-)
-
-/*!
- * \brief Returns a timeval corresponding to the duration of n samples at rate r.
- * Useful to convert samples to timevals, or even milliseconds to timevals
- * in the form ast_samp2tv(milliseconds, 1000)
- */
-AST_INLINE_API(
-struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate),
-{
- return ast_tv(_nsamp / _rate, (_nsamp % _rate) * (1000000 / _rate));
-}
-)
-
-#endif /* _ASTERISK_TIME_H */
diff --git a/1.4/include/asterisk/transcap.h b/1.4/include/asterisk/transcap.h
deleted file mode 100644
index 5da8329dc..000000000
--- a/1.4/include/asterisk/transcap.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Matthew Fredrickson <creslin@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.
- */
-
-/*! \file
- * \brief General Asterisk channel transcoding definitions.
- */
-
-#ifndef _ASTERISK_TRANSCAP_H
-#define _ASTERISK_TRANSCAP_H
-
-/* These definitions are taken directly out of libpri.h and used here.
- * DO NOT change them as it will cause unexpected behavior in channels
- * that utilize these fields.
- */
-
-#define AST_TRANS_CAP_SPEECH 0x0
-#define AST_TRANS_CAP_DIGITAL 0x08
-#define AST_TRANS_CAP_RESTRICTED_DIGITAL 0x09
-#define AST_TRANS_CAP_3_1K_AUDIO 0x10
-#define AST_TRANS_CAP_7K_AUDIO 0x11 /* Depriciated ITU Q.931 (05/1998)*/
-#define AST_TRANS_CAP_DIGITAL_W_TONES 0x11
-#define AST_TRANS_CAP_VIDEO 0x18
-
-#define IS_DIGITAL(cap)\
- (cap) & AST_TRANS_CAP_DIGITAL ? 1 : 0
-
-#endif /* _ASTERISK_TRANSCAP_H */
diff --git a/1.4/include/asterisk/translate.h b/1.4/include/asterisk/translate.h
deleted file mode 100644
index a81d0072a..000000000
--- a/1.4/include/asterisk/translate.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief Support for translation of data formats.
- */
-
-#ifndef _ASTERISK_TRANSLATE_H
-#define _ASTERISK_TRANSLATE_H
-
-#define MAX_AUDIO_FORMAT 15 /* Do not include video here */
-#define MAX_FORMAT 32 /* Do include video here */
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#if 1 /* need lots of stuff... */
-#include "asterisk/frame.h"
-#include "asterisk/plc.h"
-#include "asterisk/linkedlists.h"
-// XXX #include "asterisk/module.h"
-#endif
-
-struct ast_trans_pvt; /* declared below */
-
-/*! \brief
- * Descriptor of a translator. Name, callbacks, and various options
- * related to run-time operation (size of buffers, auxiliary
- * descriptors, etc).
- *
- * A coded registers itself by filling the relevant fields
- * of a structure and passing it as an argument to
- * ast_register_translator(). The structure should not be
- * modified after a successful registration, and its address
- * must be used as an argument to ast_unregister_translator().
- *
- * As a minimum, a translator should supply name, srcfmt and dstfmt,
- * the required buf_size (in bytes) and buffer_samples (in samples),
- * and a few callbacks (framein, frameout, sample).
- * The outbuf is automatically prepended by AST_FRIENDLY_OFFSET
- * spare bytes so generic routines can place data in there.
- *
- * Note, the translator is not supposed to do any memory allocation
- * or deallocation, nor any locking, because all of this is done in
- * the generic code.
- *
- * Translators using generic plc (packet loss concealment) should
- * supply a non-zero plc_samples indicating the size (in samples)
- * of artificially generated frames and incoming data.
- * Generic plc is only available for dstfmt = SLINEAR
- */
-struct ast_translator {
- const char name[80]; /*!< Name of translator */
- int srcfmt; /*!< Source format (note: bit position,
- converted to index during registration) */
- int dstfmt; /*!< Destination format (note: bit position,
- converted to index during registration) */
-
- int (*newpvt)(struct ast_trans_pvt *); /*!< initialize private data
- associated with the translator */
-
- int (*framein)(struct ast_trans_pvt *pvt, struct ast_frame *in);
- /*!< Input frame callback. Store
- (and possibly convert) input frame. */
-
- struct ast_frame * (*frameout)(struct ast_trans_pvt *pvt);
- /*!< Output frame callback. Generate a frame
- with outbuf content. */
-
- void (*destroy)(struct ast_trans_pvt *pvt);
- /*!< cleanup private data, if needed
- (often unnecessary). */
-
- struct ast_frame * (*sample)(void); /*!< Generate an example frame */
-
- /*! \brief size of outbuf, in samples. Leave it 0 if you want the framein
- * callback deal with the frame. Set it appropriately if you
- * want the code to checks if the incoming frame fits the
- * outbuf (this is e.g. required for plc).
- */
- int buffer_samples; /*< size of outbuf, in samples */
-
- /*! \brief size of outbuf, in bytes. Mandatory. The wrapper code will also
- * allocate an AST_FRIENDLY_OFFSET space before.
- */
- int buf_size;
-
- int desc_size; /*!< size of private descriptor in pvt->pvt, if any */
- int plc_samples; /*!< set to the plc block size if used, 0 otherwise */
- int useplc; /*!< current status of plc, changed at runtime */
- int native_plc; /*!< true if the translator can do native plc */
-
- struct ast_module *module; /* opaque reference to the parent module */
-
- int cost; /*!< Cost in milliseconds for encoding/decoding 1 second of sound */
- int active; /*!< Whether this translator should be used or not */
- AST_LIST_ENTRY(ast_translator) list; /*!< link field */
-};
-
-/*! \brief
- * Default structure for translators, with the basic fields and buffers,
- * all allocated as part of the same chunk of memory. The buffer is
- * preceded by AST_FRIENDLY_OFFSET bytes in front of the user portion.
- * 'buf' points right after this space.
- *
- * *_framein() routines operate in two ways:
- * 1. some convert on the fly and place the data directly in outbuf;
- * in this case 'samples' and 'datalen' contain the number of samples
- * and number of bytes available in the buffer.
- * In this case we can use a generic *_frameout() routine that simply
- * takes whatever is there and places it into the output frame.
- * 2. others simply store the (unconverted) samples into a working
- * buffer, and leave the conversion task to *_frameout().
- * In this case, the intermediate buffer must be in the private
- * descriptor, 'datalen' is left to 0, while 'samples' is still
- * updated with the number of samples received.
- */
-struct ast_trans_pvt {
- struct ast_translator *t;
- struct ast_frame f; /*!< used in frameout */
- int samples; /*!< samples available in outbuf */
- /*!
- * \brief actual space used in outbuf
- *
- * Also, for the sake of ABI compatability, a magic value of -1 in this
- * field means that the pvt has been requested to be destroyed, but is
- * pending destruction until ast_translate_frame_freed() gets called.
- */
- int datalen;
- void *pvt; /*!< more private data, if any */
- char *outbuf; /*!< the useful portion of the buffer */
- plc_state_t *plc; /*!< optional plc pointer */
- struct ast_trans_pvt *next; /*!< next in translator chain */
- struct timeval nextin;
- struct timeval nextout;
-};
-
-/*! \brief generic frameout function */
-struct ast_frame *ast_trans_frameout(struct ast_trans_pvt *pvt,
- int datalen, int samples);
-
-struct ast_trans_pvt;
-
-/*!
- * \brief Register a translator
- * This registers a codec translator with asterisk
- * \param t populated ast_translator structure
- * \param module handle to the module that owns this translator
- * \return 0 on success, -1 on failure
- */
-int __ast_register_translator(struct ast_translator *t, struct ast_module *module);
-#define ast_register_translator(t) __ast_register_translator(t, ast_module_info->self)
-
-/*!
- * \brief Unregister a translator
- * Unregisters the given tranlator
- * \param t translator to unregister
- * \return 0 on success, -1 on failure
- */
-int ast_unregister_translator(struct ast_translator *t);
-
-/*!
- * \brief Activate a previously deactivated translator
- * \param t translator to activate
- * \return nothing
- *
- * Enables the specified translator for use.
- */
-void ast_translator_activate(struct ast_translator *t);
-
-/*!
- * \brief Deactivate a translator
- * \param t translator to deactivate
- * \return nothing
- *
- * Disables the specified translator from being used.
- */
-void ast_translator_deactivate(struct ast_translator *t);
-
-/*!
- * \brief Chooses the best translation path
- *
- * Given a list of sources, and a designed destination format, which should
- * I choose?
- * \return Returns 0 on success, -1 if no path could be found.
- * \note Modifies dests and srcs in place
- */
-int ast_translator_best_choice(int *dsts, int *srcs);
-
-/*!
- * \brief Builds a translator path
- * Build a path (possibly NULL) from source to dest
- * \param dest destination format
- * \param source source format
- * \return ast_trans_pvt on success, NULL on failure
- * */
-struct ast_trans_pvt *ast_translator_build_path(int dest, int source);
-
-/*!
- * \brief Frees a translator path
- * Frees the given translator path structure
- * \param tr translator path to get rid of
- */
-void ast_translator_free_path(struct ast_trans_pvt *tr);
-
-/*!
- * \brief translates one or more frames
- * Apply an input frame into the translator and receive zero or one output frames. Consume
- * determines whether the original frame should be freed
- * \param tr translator structure to use for translation
- * \param f frame to translate
- * \param consume Whether or not to free the original frame
- * \return an ast_frame of the new translation format on success, NULL on failure
- */
-struct ast_frame *ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume);
-
-/*!
- * \brief Returns the number of steps required to convert from 'src' to 'dest'.
- * \param dest destination format
- * \param src source format
- * \return the number of translation steps required, or -1 if no path is available
- */
-unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src);
-
-/*!
- * \brief Mask off unavailable formats from a format bitmask
- * \param dest possible destination formats
- * \param src source formats
- * \return the destination formats that are available in the source or translatable
- *
- * The result will include all formats from 'dest' that are either present
- * in 'src' or translatable from a format present in 'src'.
- *
- * Note that only a single audio format and a single video format can be
- * present in 'src', or the function will produce unexpected results.
- */
-unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src);
-
-/*!
- * \brief Hint that a frame from a translator has been freed
- *
- * This is sort of a hack. This function gets called when ast_frame_free() gets
- * called on a frame that has the AST_FRFLAG_FROM_TRANSLATOR flag set. This is
- * because it is possible for a translation path to be destroyed while a frame
- * from a translator is still in use. Specifically, this happens if a masquerade
- * happens after a call to ast_read() but before the frame is done being processed,
- * since the frame processing is generally done without the channel lock held.
- *
- * \return nothing
- */
-void ast_translate_frame_freed(struct ast_frame *fr);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_TRANSLATE_H */
diff --git a/1.4/include/asterisk/udptl.h b/1.4/include/asterisk/udptl.h
deleted file mode 100644
index 1615a19ef..000000000
--- a/1.4/include/asterisk/udptl.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * UDPTL support for T.38
- *
- * Copyright (C) 2005, Steve Underwood, partly based on RTP code which is
- * Copyright (C) 1999-2004, Digium, Inc.
- *
- * Steve Underwood <steveu@coppice.org>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-#ifndef _ASTERISK_UDPTL_H
-#define _ASTERISK_UDPTL_H
-
-#include "asterisk/frame.h"
-#include "asterisk/io.h"
-#include "asterisk/sched.h"
-#include "asterisk/channel.h"
-
-#include <netinet/in.h>
-
-enum
-{
- UDPTL_ERROR_CORRECTION_NONE,
- UDPTL_ERROR_CORRECTION_FEC,
- UDPTL_ERROR_CORRECTION_REDUNDANCY
-};
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-struct ast_udptl_protocol {
- /* Get UDPTL struct, or NULL if unwilling to transfer */
- struct ast_udptl *(*get_udptl_info)(struct ast_channel *chan);
- /* Set UDPTL peer */
- int (* const set_udptl_peer)(struct ast_channel *chan, struct ast_udptl *peer);
- const char * const type;
- struct ast_udptl_protocol *next;
-};
-
-struct ast_udptl;
-
-typedef int (*ast_udptl_callback)(struct ast_udptl *udptl, struct ast_frame *f, void *data);
-
-struct ast_udptl *ast_udptl_new(struct sched_context *sched, struct io_context *io, int callbackmode);
-
-struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr in);
-
-void ast_udptl_set_peer(struct ast_udptl *udptl, struct sockaddr_in *them);
-
-void ast_udptl_get_peer(struct ast_udptl *udptl, struct sockaddr_in *them);
-
-void ast_udptl_get_us(struct ast_udptl *udptl, struct sockaddr_in *us);
-
-void ast_udptl_destroy(struct ast_udptl *udptl);
-
-void ast_udptl_reset(struct ast_udptl *udptl);
-
-void ast_udptl_set_callback(struct ast_udptl *udptl, ast_udptl_callback callback);
-
-void ast_udptl_set_data(struct ast_udptl *udptl, void *data);
-
-int ast_udptl_write(struct ast_udptl *udptl, struct ast_frame *f);
-
-struct ast_frame *ast_udptl_read(struct ast_udptl *udptl);
-
-int ast_udptl_fd(struct ast_udptl *udptl);
-
-int ast_udptl_settos(struct ast_udptl *udptl, int tos);
-
-void ast_udptl_set_m_type(struct ast_udptl* udptl, int pt);
-
-void ast_udptl_set_udptlmap_type(struct ast_udptl* udptl, int pt,
- char* mimeType, char* mimeSubtype);
-
-int ast_udptl_lookup_code(struct ast_udptl* udptl, int isAstFormat, int code);
-
-void ast_udptl_offered_from_local(struct ast_udptl* udptl, int local);
-
-int ast_udptl_get_error_correction_scheme(struct ast_udptl* udptl);
-
-void ast_udptl_set_error_correction_scheme(struct ast_udptl* udptl, int ec);
-
-int ast_udptl_get_local_max_datagram(struct ast_udptl* udptl);
-
-void ast_udptl_set_local_max_datagram(struct ast_udptl* udptl, int max_datagram);
-
-int ast_udptl_get_far_max_datagram(struct ast_udptl* udptl);
-
-void ast_udptl_set_far_max_datagram(struct ast_udptl* udptl, int max_datagram);
-
-void ast_udptl_get_current_formats(struct ast_udptl* udptl,
- int* astFormats, int* nonAstFormats);
-
-void ast_udptl_setnat(struct ast_udptl *udptl, int nat);
-
-int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
-
-int ast_udptl_proto_register(struct ast_udptl_protocol *proto);
-
-void ast_udptl_proto_unregister(struct ast_udptl_protocol *proto);
-
-void ast_udptl_stop(struct ast_udptl *udptl);
-
-void ast_udptl_init(void);
-
-void ast_udptl_reload(void);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif
diff --git a/1.4/include/asterisk/ulaw.h b/1.4/include/asterisk/ulaw.h
deleted file mode 100644
index d9ab0d178..000000000
--- a/1.4/include/asterisk/ulaw.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief u-Law to Signed linear conversion
- */
-
-#ifndef _ASTERISK_ULAW_H
-#define _ASTERISK_ULAW_H
-
-/*! Init the ulaw conversion stuff */
-/*!
- * To init the ulaw to slinear conversion stuff, this needs to be run.
- */
-void ast_ulaw_init(void);
-
-/*! converts signed linear to mulaw */
-/*!
- */
-extern unsigned char __ast_lin2mu[16384];
-
-/*! help */
-extern short __ast_mulaw[256];
-
-#define AST_LIN2MU(a) (__ast_lin2mu[((unsigned short)(a)) >> 2])
-#define AST_MULAW(a) (__ast_mulaw[(a)])
-
-#endif /* _ASTERISK_ULAW_H */
diff --git a/1.4/include/asterisk/unaligned.h b/1.4/include/asterisk/unaligned.h
deleted file mode 100644
index 16791d6f0..000000000
--- a/1.4/include/asterisk/unaligned.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- * \brief Handle unaligned data access
- */
-
-#ifndef _ASTERISK_UNALIGNED_H
-#define _ASTERISK_UNALIGNED_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#ifdef __GNUC__
-/* If we just tell GCC what's going on, we can trust it to behave optimally */
-static inline unsigned int get_unaligned_uint32(void *p)
-{
- struct { unsigned int d; } __attribute__((packed)) *pp = (void *)p;
-
- return pp->d;
-}
-static inline unsigned short get_unaligned_uint16(void *p)
-{
- struct { unsigned short d; } __attribute__((packed)) *pp = (void *)p;
-
- return pp->d;
-}
-
-static inline void put_unaligned_uint32(void *p, unsigned int datum)
-{
- struct { unsigned int d; } __attribute__((packed)) *pp = (void *)p;
-
- pp->d = datum;
-}
-
-static inline void put_unaligned_uint16(void *p, unsigned short datum)
-{
- struct { unsigned short d; } __attribute__((packed)) *pp = (void *)p;
-
- pp->d = datum;
-}
-#elif defined(SOLARIS) && defined(__sparc__)
-static inline unsigned int get_unaligned_uint32(void *p)
-{
- unsigned char *cp = p;
-
- return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
-}
-
-static inline unsigned short get_unaligned_uint16(void *p)
-{
- unsigned char *cp = p;
-
- return (cp[0] << 8) | cp[1] ;
-}
-
-static inline void put_unaligned_uint32(void *p, unsigned int datum)
-{
- unsigned char *cp = p;
-
- cp[0] = datum >> 24;
- cp[1] = datum >> 16;
- cp[2] = datum >> 8;
- cp[3] = datum;
-}
-
-static inline void put_unaligned_uint16(void *p, unsigned int datum)
-{
- unsigned char *cp = p;
-
- cp[0] = datum >> 8;
- cp[1] = datum;
-}
-#else /* Not GCC, not Solaris/SPARC. Assume we can handle direct load/store. */
-#define get_unaligned_uint32(p) (*((unsigned int *)(p)))
-#define get_unaligned_uint16(p) (*((unsigned short *)(p)))
-#define put_unaligned_uint32(p,d) do { unsigned int *__P = (p); *__P = d; } while(0)
-#define put_unaligned_uint16(p,d) do { unsigned short *__P = (p); *__P = d; } while(0)
-#endif
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-
-#endif /* _ASTERISK_UNALIGNED_H */
diff --git a/1.4/include/asterisk/utils.h b/1.4/include/asterisk/utils.h
deleted file mode 100644
index 1e5203671..000000000
--- a/1.4/include/asterisk/utils.h
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- * \brief Utility functions
- */
-
-#ifndef _ASTERISK_UTILS_H
-#define _ASTERISK_UTILS_H
-
-#include "asterisk/compat.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <netinet/in.h>
-#include <arpa/inet.h> /* we want to override inet_ntoa */
-#include <netdb.h>
-#include <limits.h>
-#include <time.h> /* we want to override localtime_r */
-
-#include "asterisk/lock.h"
-#include "asterisk/time.h"
-#include "asterisk/strings.h"
-#include "asterisk/logger.h"
-#include "asterisk/compiler.h"
-#include "asterisk/localtime.h"
-
-/*! \note
- \verbatim
- Note:
- It is very important to use only unsigned variables to hold
- bit flags, as otherwise you can fall prey to the compiler's
- sign-extension antics if you try to use the top two bits in
- your variable.
-
- The flag macros below use a set of compiler tricks to verify
- that the caller is using an "unsigned int" variable to hold
- the flags, and nothing else. If the caller uses any other
- type of variable, a warning message similar to this:
-
- warning: comparison of distinct pointer types lacks cast
- will be generated.
-
- The "dummy" variable below is used to make these comparisons.
-
- Also note that at -O2 or above, this type-safety checking
- does _not_ produce any additional object code at all.
- \endverbatim
-*/
-
-extern unsigned int __unsigned_int_flags_dummy;
-
-#define ast_test_flag(p,flag) ({ \
- typeof ((p)->flags) __p = (p)->flags; \
- typeof (__unsigned_int_flags_dummy) __x = 0; \
- (void) (&__p == &__x); \
- ((p)->flags & (flag)); \
- })
-
-#define ast_set_flag(p,flag) do { \
- typeof ((p)->flags) __p = (p)->flags; \
- typeof (__unsigned_int_flags_dummy) __x = 0; \
- (void) (&__p == &__x); \
- ((p)->flags |= (flag)); \
- } while(0)
-
-#define ast_clear_flag(p,flag) do { \
- typeof ((p)->flags) __p = (p)->flags; \
- typeof (__unsigned_int_flags_dummy) __x = 0; \
- (void) (&__p == &__x); \
- ((p)->flags &= ~(flag)); \
- } while(0)
-
-#define ast_copy_flags(dest,src,flagz) do { \
- typeof ((dest)->flags) __d = (dest)->flags; \
- typeof ((src)->flags) __s = (src)->flags; \
- typeof (__unsigned_int_flags_dummy) __x = 0; \
- (void) (&__d == &__x); \
- (void) (&__s == &__x); \
- (dest)->flags &= ~(flagz); \
- (dest)->flags |= ((src)->flags & (flagz)); \
- } while (0)
-
-#define ast_set2_flag(p,value,flag) do { \
- typeof ((p)->flags) __p = (p)->flags; \
- typeof (__unsigned_int_flags_dummy) __x = 0; \
- (void) (&__p == &__x); \
- if (value) \
- (p)->flags |= (flag); \
- else \
- (p)->flags &= ~(flag); \
- } while (0)
-
-#define ast_set_flags_to(p,flag,value) do { \
- typeof ((p)->flags) __p = (p)->flags; \
- typeof (__unsigned_int_flags_dummy) __x = 0; \
- (void) (&__p == &__x); \
- (p)->flags &= ~(flag); \
- (p)->flags |= (value); \
- } while (0)
-
-/* Non-type checking variations for non-unsigned int flags. You
- should only use non-unsigned int flags where required by
- protocol etc and if you know what you're doing :) */
-#define ast_test_flag_nonstd(p,flag) \
- ((p)->flags & (flag))
-
-#define ast_set_flag_nonstd(p,flag) do { \
- ((p)->flags |= (flag)); \
- } while(0)
-
-#define ast_clear_flag_nonstd(p,flag) do { \
- ((p)->flags &= ~(flag)); \
- } while(0)
-
-#define ast_copy_flags_nonstd(dest,src,flagz) do { \
- (dest)->flags &= ~(flagz); \
- (dest)->flags |= ((src)->flags & (flagz)); \
- } while (0)
-
-#define ast_set2_flag_nonstd(p,value,flag) do { \
- if (value) \
- (p)->flags |= (flag); \
- else \
- (p)->flags &= ~(flag); \
- } while (0)
-
-#define AST_FLAGS_ALL UINT_MAX
-
-struct ast_flags {
- unsigned int flags;
-};
-
-struct ast_hostent {
- struct hostent hp;
- char buf[1024];
-};
-
-struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
-
-/* ast_md5_hash
- \brief Produces MD5 hash based on input string */
-void ast_md5_hash(char *output, char *input);
-/* ast_sha1_hash
- \brief Produces SHA1 hash based on input string */
-void ast_sha1_hash(char *output, char *input);
-
-int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
-int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
-int ast_base64decode(unsigned char *dst, const char *src, int max);
-
-/*! ast_uri_encode
- \brief Turn text string to URI-encoded %XX version
- At this point, we're converting from ISO-8859-x (8-bit), not UTF8
- as in the SIP protocol spec
- If doreserved == 1 we will convert reserved characters also.
- RFC 2396, section 2.4
- outbuf needs to have more memory allocated than the instring
- to have room for the expansion. Every char that is converted
- is replaced by three ASCII characters.
- \param string String to be converted
- \param outbuf Resulting encoded string
- \param buflen Size of output buffer
- \param doreserved Convert reserved characters
-*/
-
-char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
-
-/*! \brief Decode URI, URN, URL (overwrite string)
- \param s String to be decoded
- */
-void ast_uri_decode(char *s);
-
-static force_inline void ast_slinear_saturated_add(short *input, short *value)
-{
- int res;
-
- res = (int) *input + *value;
- if (res > 32767)
- *input = 32767;
- else if (res < -32767)
- *input = -32767;
- else
- *input = (short) res;
-}
-
-static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
-{
- int res;
-
- res = (int) *input * *value;
- if (res > 32767)
- *input = 32767;
- else if (res < -32767)
- *input = -32767;
- else
- *input = (short) res;
-}
-
-static force_inline void ast_slinear_saturated_divide(short *input, short *value)
-{
- *input /= *value;
-}
-
-int test_for_thread_safety(void);
-
-/*!
- * \brief thread-safe replacement for inet_ntoa().
- *
- * \note It is very important to note that even though this is a thread-safe
- * replacement for inet_ntoa(), it is *not* reentrant. In a single
- * thread, the result from a previous call to this function is no longer
- * valid once it is called again. If the result from multiple calls to
- * this function need to be kept or used at once, then the result must be
- * copied to a local buffer before calling this function again.
- */
-const char *ast_inet_ntoa(struct in_addr ia);
-
-#ifdef inet_ntoa
-#undef inet_ntoa
-#endif
-#define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
-
-#ifdef localtime_r
-#undef localtime_r
-#endif
-#define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
-
-int ast_utils_init(void);
-int ast_wait_for_input(int fd, int ms);
-
-/*! ast_carefulwrite
- \brief Try to write string, but wait no more than ms milliseconds
- before timing out.
-
- \note If you are calling ast_carefulwrite, it is assumed that you are calling
- it on a file descriptor that _DOES_ have NONBLOCK set. This way,
- there is only one system call made to do a write, unless we actually
- have a need to wait. This way, we get better performance.
-*/
-int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
-
-/*! Compares the source address and port of two sockaddr_in */
-static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
-{
- return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
- || (sin1->sin_port != sin2->sin_port));
-}
-
-#define AST_STACKSIZE 240 * 1024
-
-#if defined(LOW_MEMORY)
-#define AST_BACKGROUND_STACKSIZE 48 * 1024
-#else
-#define AST_BACKGROUND_STACKSIZE 240 * 1024
-#endif
-
-void ast_register_thread(char *name);
-void ast_unregister_thread(void *id);
-
-int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
- void *data, size_t stacksize, const char *file, const char *caller,
- int line, const char *start_fn);
-
-#define ast_pthread_create(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
- 0, \
- __FILE__, __FUNCTION__, \
- __LINE__, #c)
-
-#define ast_pthread_create_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
- AST_BACKGROUND_STACKSIZE, \
- __FILE__, __FUNCTION__, \
- __LINE__, #c)
-
-/*!
- \brief Process a string to find and replace characters
- \param start The string to analyze
- \param find The character to find
- \param replace_with The character that will replace the one we are looking for
-*/
-char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
-
-#ifdef linux
-#define ast_random random
-#else
-long int ast_random(void);
-#endif
-
-/*!
- * \brief free() wrapper
- *
- * ast_free should be used when a function pointer for free() needs to be passed
- * as the argument to a function. Otherwise, astmm will cause seg faults.
- */
-#ifdef __AST_DEBUG_MALLOC
-static void ast_free(void *ptr) attribute_unused;
-static void ast_free(void *ptr)
-{
- free(ptr);
-}
-#else
-#define ast_free free
-#endif
-
-#ifndef __AST_DEBUG_MALLOC
-
-#define MALLOC_FAILURE_MSG \
- ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
-/*!
- * \brief A wrapper for malloc()
- *
- * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * The argument and return value are the same as malloc()
- */
-#define ast_malloc(len) \
- _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-AST_INLINE_API(
-void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
-{
- void *p;
-
- if (!(p = malloc(len)))
- MALLOC_FAILURE_MSG;
-
- return p;
-}
-)
-
-/*!
- * \brief A wrapper for calloc()
- *
- * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * The arguments and return value are the same as calloc()
- */
-#define ast_calloc(num, len) \
- _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-AST_INLINE_API(
-void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
-{
- void *p;
-
- if (!(p = calloc(num, len)))
- MALLOC_FAILURE_MSG;
-
- return p;
-}
-)
-
-/*!
- * \brief A wrapper for calloc() for use in cache pools
- *
- * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
- * message in the case that the allocation fails. When memory debugging is in use,
- * the memory allocated by this function will be marked as 'cache' so it can be
- * distinguished from normal memory allocations.
- *
- * The arguments and return value are the same as calloc()
- */
-#define ast_calloc_cache(num, len) \
- _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-/*!
- * \brief A wrapper for realloc()
- *
- * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * The arguments and return value are the same as realloc()
- */
-#define ast_realloc(p, len) \
- _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-AST_INLINE_API(
-void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
-{
- void *newp;
-
- if (!(newp = realloc(p, len)))
- MALLOC_FAILURE_MSG;
-
- return newp;
-}
-)
-
-/*!
- * \brief A wrapper for strdup()
- *
- * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
- * argument is provided, ast_strdup will return NULL without generating any
- * kind of error log message.
- *
- * The argument and return value are the same as strdup()
- */
-#define ast_strdup(str) \
- _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-AST_INLINE_API(
-char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
-{
- char *newstr = NULL;
-
- if (str) {
- if (!(newstr = strdup(str)))
- MALLOC_FAILURE_MSG;
- }
-
- return newstr;
-}
-)
-
-/*!
- * \brief A wrapper for strndup()
- *
- * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
- * string to duplicate. If a NULL argument is provided, ast_strdup will return
- * NULL without generating any kind of error log message.
- *
- * The arguments and return value are the same as strndup()
- */
-#define ast_strndup(str, len) \
- _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-AST_INLINE_API(
-char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
-{
- char *newstr = NULL;
-
- if (str) {
- if (!(newstr = strndup(str, len)))
- MALLOC_FAILURE_MSG;
- }
-
- return newstr;
-}
-)
-
-/*!
- * \brief A wrapper for asprintf()
- *
- * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * The arguments and return value are the same as asprintf()
- */
-#define ast_asprintf(ret, fmt, ...) \
- _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
-
-AST_INLINE_API(
-int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- if ((res = vasprintf(ret, fmt, ap)) == -1)
- MALLOC_FAILURE_MSG;
- va_end(ap);
-
- return res;
-}
-)
-
-/*!
- * \brief A wrapper for vasprintf()
- *
- * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
- * message in the case that the allocation fails.
- *
- * The arguments and return value are the same as vasprintf()
- */
-#define ast_vasprintf(ret, fmt, ap) \
- _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
-
-AST_INLINE_API(
-int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
-{
- int res;
-
- if ((res = vasprintf(ret, fmt, ap)) == -1)
- MALLOC_FAILURE_MSG;
-
- return res;
-}
-)
-
-#else
-
-/* If astmm is in use, let it handle these. Otherwise, it will report that
- all allocations are coming from this header file */
-
-#define ast_malloc(a) malloc(a)
-#define ast_calloc(a,b) calloc(a,b)
-#define ast_realloc(a,b) realloc(a,b)
-#define ast_strdup(a) strdup(a)
-#define ast_strndup(a,b) strndup(a,b)
-#define ast_asprintf(a,b,c) asprintf(a,b,c)
-#define ast_vasprintf(a,b,c) vasprintf(a,b,c)
-
-#endif /* AST_DEBUG_MALLOC */
-
-#if !defined(ast_strdupa) && defined(__GNUC__)
-/*!
- \brief duplicate a string in memory from the stack
- \param s The string to duplicate
-
- This macro will duplicate the given string. It returns a pointer to the stack
- allocatted memory for the new string.
-*/
-#define ast_strdupa(s) \
- (__extension__ \
- ({ \
- const char *__old = (s); \
- size_t __len = strlen(__old) + 1; \
- char *__new = __builtin_alloca(__len); \
- memcpy (__new, __old, __len); \
- __new; \
- }))
-#endif
-
-/*!
- \brief Disable PMTU discovery on a socket
- \param sock The socket to manipulate
- \return Nothing
-
- On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
- bit set. This is supposedly done to allow the application to do PMTU
- discovery, but Asterisk does not do this.
-
- Because of this, UDP packets sent by Asterisk that are larger than the MTU
- of any hop in the path will be lost. This function can be called on a socket
- to ensure that the DF bit will not be set.
- */
-void ast_enable_packet_fragmentation(int sock);
-
-#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
-
-#endif /* _ASTERISK_UTILS_H */
diff --git a/1.4/include/jitterbuf.h b/1.4/include/jitterbuf.h
deleted file mode 100644
index dac903e83..000000000
--- a/1.4/include/jitterbuf.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * jitterbuf: an application-independent jitterbuffer
- *
- * Copyrights:
- * Copyright (C) 2004-2005, Horizon Wimba, Inc.
- *
- * Contributors:
- * Steve Kann <stevek@stevek.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU Lesser (Library) General Public License
- *
- * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
- */
-
-#ifndef _JITTERBUF_H_
-#define _JITTERBUF_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* configuration constants */
- /* Number of historical timestamps to use in calculating jitter and drift */
-#define JB_HISTORY_SZ 500
- /* what percentage of timestamps should we drop from the history when we examine it;
- * this might eventually be something made configurable */
-#define JB_HISTORY_DROPPCT 3
- /* the maximum droppct we can handle (say it was configurable). */
-#define JB_HISTORY_DROPPCT_MAX 4
- /* the size of the buffer we use to keep the top and botton timestamps for dropping */
-#define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
- /* amount of additional jitterbuffer adjustment */
-#define JB_TARGET_EXTRA 40
- /* ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
-#define JB_ADJUST_DELAY 40
-
-enum jb_return_code {
- /* return codes */
- JB_OK, /* 0 */
- JB_EMPTY, /* 1 */
- JB_NOFRAME, /* 2 */
- JB_INTERP, /* 3 */
- JB_DROP, /* 4 */
- JB_SCHED /* 5 */
-};
-
-enum jb_frame_type {
- /* frame types */
- JB_TYPE_CONTROL, /* 0 */
- JB_TYPE_VOICE, /* 1 */
- JB_TYPE_VIDEO, /* 2 - reserved */
- JB_TYPE_SILENCE /* 3 */
-};
-
-typedef struct jb_conf {
- /* settings */
- long max_jitterbuf; /* defines a hard clamp to use in setting the jitter buffer delay */
- long resync_threshold; /* the jb will resync when delay increases to (2 * jitter) + this param */
- long max_contig_interp; /* the max interp frames to return in a row */
-} jb_conf;
-
-typedef struct jb_info {
- jb_conf conf;
-
- /* statistics */
- long frames_in; /* number of frames input to the jitterbuffer.*/
- long frames_out; /* number of frames output from the jitterbuffer.*/
- long frames_late; /* number of frames which were too late, and dropped.*/
- long frames_lost; /* number of missing frames.*/
- long frames_dropped; /* number of frames dropped (shrinkage) */
- long frames_ooo; /* number of frames received out-of-order */
- long frames_cur; /* number of frames presently in jb, awaiting delivery.*/
- long jitter; /* jitter measured within current history interval*/
- long min; /* minimum lateness within current history interval */
- long current; /* the present jitterbuffer adjustment */
- long target; /* the target jitterbuffer adjustment */
- long losspct; /* recent lost frame percentage (* 1000) */
- long next_voice_ts; /* the ts of the next frame to be read from the jb - in receiver's time */
- long last_voice_ms; /* the duration of the last voice frame */
- long silence_begin_ts; /* the time of the last CNG frame, when in silence */
- long last_adjustment; /* the time of the last adjustment */
- long last_delay; /* the last now added to history */
- long cnt_delay_discont; /* the count of discontinuous delays */
- long resync_offset; /* the amount to offset ts to support resyncs */
- long cnt_contig_interp; /* the number of contiguous interp frames returned */
-} jb_info;
-
-typedef struct jb_frame {
- void *data; /* the frame data */
- long ts; /* the relative delivery time expected */
- long ms; /* the time covered by this frame, in sec/8000 */
- enum jb_frame_type type; /* the type of frame */
- struct jb_frame *next, *prev;
-} jb_frame;
-
-typedef struct jitterbuf {
- jb_info info;
-
- /* history */
- long history[JB_HISTORY_SZ]; /* history */
- int hist_ptr; /* points to index in history for next entry */
- long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the max delays (highest first) */
- long hist_minbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the min delays (lowest first) */
- int hist_maxbuf_valid; /* are the "maxbuf"/minbuf valid? */
- unsigned int dropem:1; /* flag to indicate dropping frames (overload) */
-
- jb_frame *frames; /* queued frames */
- jb_frame *free; /* free frames (avoid malloc?) */
-} jitterbuf;
-
-
-/* new jitterbuf */
-jitterbuf * jb_new(void);
-
-/* destroy jitterbuf */
-void jb_destroy(jitterbuf *jb);
-
-/* reset jitterbuf */
-/* NOTE: The jitterbuffer should be empty before you call this, otherwise
- * you will leak queued frames, and some internal structures */
-void jb_reset(jitterbuf *jb);
-
-/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
- * now=now (in receiver's time) return value is one of
- * JB_OK: Frame added. Last call to jb_next() still valid
- * JB_DROP: Drop this frame immediately
- * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
- */
-enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now);
-
-/* get a frame for time now (receiver's time) return value is one of
- * JB_OK: You've got frame!
- * JB_DROP: Here's an audio frame you should just drop. Ask me again for this time..
- * JB_NOFRAME: There's no frame scheduled for this time.
- * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
- * JB_EMPTY: The jb is empty.
- */
-enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl);
-
-/* unconditionally get frames from jitterbuf until empty */
-enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout);
-
-/* when is the next frame due out, in receiver's time (0=EMPTY)
- * This value may change as frames are added (esp non-audio frames) */
-long jb_next(jitterbuf *jb);
-
-/* get jitterbuf info: only "statistics" may be valid */
-enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats);
-
-/* set jitterbuf conf */
-enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf);
-
-typedef void (*jb_output_function_t)(const char *fmt, ...);
-void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/1.4/include/solaris-compat/compat.h b/1.4/include/solaris-compat/compat.h
deleted file mode 100644
index b34cf11f4..000000000
--- a/1.4/include/solaris-compat/compat.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _SOLARIS_COMPAT_H
-#define _SOLARIS_COMPAT_H
-
-#define __BEGIN_DECLS
-#define __END_DECLS
-
-#ifndef __P
-#define __P(p) p
-#endif
-
-#include <alloca.h>
-#include <strings.h>
-#include <string.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <netinet/in.h>
-
-#ifndef BYTE_ORDER
-#define LITTLE_ENDIAN 1234
-#define BIG_ENDIAN 4321
-
-#ifdef __sparc__
-#define BYTE_ORDER BIG_ENDIAN
-#else
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
-#endif
-
-#ifndef __BYTE_ORDER
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#define __BYTE_ORDER BYTE_ORDER
-#endif
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-typedef unsigned char u_int8_t;
-typedef unsigned short u_int16_t;
-typedef unsigned int u_int32_t;
-#endif
-
-char* strsep(char** str, const char* delims);
-int setenv(const char *name, const char *value, int overwrite);
-int unsetenv(const char *name);
-#endif
diff --git a/1.4/include/solaris-compat/sys/cdefs.h b/1.4/include/solaris-compat/sys/cdefs.h
deleted file mode 100644
index 40f76af87..000000000
--- a/1.4/include/solaris-compat/sys/cdefs.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __SYS_CDEFS_H_
-#define __SYS_CDEFS_H_
-
-#define __BEGIN_DECLS
-#define __END_DECLS
-
-#define __P(p) p
-
-
-#endif
diff --git a/1.4/include/solaris-compat/sys/queue.h b/1.4/include/solaris-compat/sys/queue.h
deleted file mode 100644
index ac273dfe3..000000000
--- a/1.4/include/solaris-compat/sys/queue.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- * $FreeBSD: src/sys/sys/queue.h,v 1.24.2.4 2000/05/05 01:41:41 archie Exp $
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * singly-linked tail queues, lists, tail queues, and circular queues.
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction. Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A singly-linked tail queue is headed by a pair of pointers, one to the
- * head of the list and the other to the tail of the list. The elements are
- * singly linked for minimum space and pointer manipulation overhead at the
- * expense of O(n) removal for arbitrary elements. New elements can be added
- * to the list after an existing element, at the head of the list, or at the
- * end of the list. Elements being removed from the head of the tail queue
- * should use the explicit macro for this purpose for optimum efficiency.
- * A singly-linked tail queue may only be traversed in the forward direction.
- * Singly-linked tail queues are ideal for applications with large datasets
- * and few or no removals or for implementing a FIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *
- *
- * SLIST LIST STAILQ TAILQ CIRCLEQ
- * _HEAD + + + + +
- * _ENTRY + + + + +
- * _INIT + + + + +
- * _EMPTY + + + + +
- * _FIRST + + + + +
- * _NEXT + + + + +
- * _PREV - - - + +
- * _LAST - - + + +
- * _FOREACH + + + + +
- * _FOREACH_REVERSE - - - + +
- * _INSERT_HEAD + + + + +
- * _INSERT_BEFORE - + - + +
- * _INSERT_AFTER + + + + +
- * _INSERT_TAIL - - + + +
- * _REMOVE_HEAD + - + - -
- * _REMOVE + + + + +
- *
- */
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type) \
-struct name { \
- struct type *slh_first; /* first element */ \
-}
-
-#define SLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define SLIST_ENTRY(type) \
-struct { \
- struct type *sle_next; /* next element */ \
-}
-
-/*
- * Singly-linked List functions.
- */
-#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
-
-#define SLIST_FIRST(head) ((head)->slh_first)
-
-#define SLIST_FOREACH(var, head, field) \
- for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-#define SLIST_INIT(head) { \
- (head)->slh_first = NULL; \
-}
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
- (elm)->field.sle_next = (slistelm)->field.sle_next; \
- (slistelm)->field.sle_next = (elm); \
-} while (0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.sle_next = (head)->slh_first; \
- (head)->slh_first = (elm); \
-} while (0)
-
-#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-#define SLIST_REMOVE_HEAD(head, field) do { \
- (head)->slh_first = (head)->slh_first->field.sle_next; \
-} while (0)
-
-#define SLIST_REMOVE(head, elm, type, field) do { \
- if ((head)->slh_first == (elm)) { \
- SLIST_REMOVE_HEAD((head), field); \
- } \
- else { \
- struct type *curelm = (head)->slh_first; \
- while( curelm->field.sle_next != (elm) ) \
- curelm = curelm->field.sle_next; \
- curelm->field.sle_next = \
- curelm->field.sle_next->field.sle_next; \
- } \
-} while (0)
-
-/*
- * Singly-linked Tail queue definitions.
- */
-#define STAILQ_HEAD(name, type) \
-struct name { \
- struct type *stqh_first;/* first element */ \
- struct type **stqh_last;/* addr of last next element */ \
-}
-
-#define STAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).stqh_first }
-
-#define STAILQ_ENTRY(type) \
-struct { \
- struct type *stqe_next; /* next element */ \
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
-
-#define STAILQ_INIT(head) do { \
- (head)->stqh_first = NULL; \
- (head)->stqh_last = &(head)->stqh_first; \
-} while (0)
-
-#define STAILQ_FIRST(head) ((head)->stqh_first)
-#define STAILQ_LAST(head) (*(head)->stqh_last)
-
-#define STAILQ_FOREACH(var, head, field) \
- for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
-
-#define STAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
- (head)->stqh_last = &(elm)->field.stqe_next; \
- (head)->stqh_first = (elm); \
-} while (0)
-
-#define STAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.stqe_next = NULL; \
- *(head)->stqh_last = (elm); \
- (head)->stqh_last = &(elm)->field.stqe_next; \
-} while (0)
-
-#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
- if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
- (head)->stqh_last = &(elm)->field.stqe_next; \
- (tqelm)->field.stqe_next = (elm); \
-} while (0)
-
-#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
-
-#define STAILQ_REMOVE_HEAD(head, field) do { \
- if (((head)->stqh_first = \
- (head)->stqh_first->field.stqe_next) == NULL) \
- (head)->stqh_last = &(head)->stqh_first; \
-} while (0)
-
-#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
- if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
- (head)->stqh_last = &(head)->stqh_first; \
-} while (0)
-
-#define STAILQ_REMOVE(head, elm, type, field) do { \
- if ((head)->stqh_first == (elm)) { \
- STAILQ_REMOVE_HEAD(head, field); \
- } \
- else { \
- struct type *curelm = (head)->stqh_first; \
- while( curelm->field.stqe_next != (elm) ) \
- curelm = curelm->field.stqe_next; \
- if((curelm->field.stqe_next = \
- curelm->field.stqe_next->field.stqe_next) == NULL) \
- (head)->stqh_last = &(curelm)->field.stqe_next; \
- } \
-} while (0)
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-
-#define LIST_EMPTY(head) ((head)->lh_first == NULL)
-
-#define LIST_FIRST(head) ((head)->lh_first)
-
-#define LIST_FOREACH(var, head, field) \
- for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
-
-#define LIST_INIT(head) do { \
- (head)->lh_first = NULL; \
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (0)
-
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
-
-#define TAILQ_FOREACH(var, head, field) \
- for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for ((var) = TAILQ_LAST((head), headname); \
- (var); \
- (var) = TAILQ_PREV((var), headname, field))
-
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-
-#define TAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define TAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-#define TAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
-
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for((var) = (head)->cqh_first; \
- (var) != (void *)(head); \
- (var) = (var)->field.cqe_next)
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for((var) = (head)->cqh_last; \
- (var) != (void *)(head); \
- (var) = (var)->field.cqe_prev)
-
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (0)
-
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-
-#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
-
-#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-} while (0)
-
-#ifdef KERNEL
-
-/*
- * XXX insque() and remque() are an old way of handling certain queues.
- * They bogusly assumes that all queue heads look alike.
- */
-
-struct quehead {
- struct quehead *qh_link;
- struct quehead *qh_rlink;
-};
-
-#ifdef __GNUC__
-
-static __inline void
-insque(void *a, void *b)
-{
- struct quehead *element = a, *head = b;
-
- element->qh_link = head->qh_link;
- element->qh_rlink = head;
- head->qh_link = element;
- element->qh_link->qh_rlink = element;
-}
-
-static __inline void
-remque(void *a)
-{
- struct quehead *element = a;
-
- element->qh_link->qh_rlink = element->qh_rlink;
- element->qh_rlink->qh_link = element->qh_link;
- element->qh_rlink = 0;
-}
-
-#else /* !__GNUC__ */
-
-void insque __P((void *a, void *b));
-void remque __P((void *a));
-
-#endif /* __GNUC__ */
-
-#endif /* KERNEL */
-
-#endif /* !_SYS_QUEUE_H_ */
-
diff --git a/1.4/install-sh b/1.4/install-sh
deleted file mode 100755
index d4744f0c7..000000000
--- a/1.4/install-sh
+++ /dev/null
@@ -1,269 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-#
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- chmodcmd=""
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/1.4/keys/freeworlddialup.pub b/1.4/keys/freeworlddialup.pub
deleted file mode 100644
index 4ba3faf66..000000000
--- a/1.4/keys/freeworlddialup.pub
+++ /dev/null
@@ -1,6 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcE53oHNoe3sBSkvW3JaO8v5Z1
-CC+Cm+JgocGwmUek0hlQST1NUsFWfYIMd5z/Iunnd1GziXLqDYzCQeZUtJ6Y9J4A
-cA9wNv1eYWrlH7ozKWOv592+Y5xF0kqQ1jFt+5zFTP5myL9N439Evu/BWALHw0B4
-aML+CsGHg0uIe5ZjNwIDAQAB
------END PUBLIC KEY-----
diff --git a/1.4/keys/iaxtel.pub b/1.4/keys/iaxtel.pub
deleted file mode 100644
index d7c8f6cc8..000000000
--- a/1.4/keys/iaxtel.pub
+++ /dev/null
@@ -1,6 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3+joshldCUFgjj5DeYOgRLSPS
-0t7gxTHiy1BTfynadPzgn447dy9iIQfBykE0pEdIPgaPMEt+ZPqPtln1P4dX3Ynx
-I+RYKgtjsmYYnyJRMGHfHuLXwkbFkxyiEg0KDvbdBWbz7GUNZlp49BLXewWGY9DJ
-MauE7FXVyCVDchn0YQIDAQAB
------END PUBLIC KEY-----
diff --git a/1.4/main/Makefile b/1.4/main/Makefile
deleted file mode 100644
index 6cf1c5e83..000000000
--- a/1.4/main/Makefile
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile to build main Asterisk binary
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# Mark Spencer <markster@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include $(ASTTOPDIR)/menuselect.makeopts $(ASTTOPDIR)/menuselect.makedeps $(ASTTOPDIR)/makeopts.embed_rules
-
-all: asterisk
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
-
-OBJS= io.o sched.o logger.o frame.o loader.o config.o channel.o \
- translate.o file.o pbx.o cli.o md5.o term.o \
- ulaw.o alaw.o callerid.o fskmodem.o image.o app.o \
- cdr.o tdd.o acl.o rtp.o udptl.o manager.o asterisk.o \
- dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \
- astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
- utils.o plc.o jitterbuf.o dnsmgr.o devicestate.o \
- netsock.o slinfactory.o ast_expr2.o ast_expr2f.o \
- cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
- strcompat.o threadstorage.o dial.o astobj2.o global_datastores.o \
- audiohook.o
-
-# we need to link in the objects statically, not as a library, because
-# otherwise modules will not have them available if none of the static
-# objects use it.
-OBJS+=stdtime/localtime.o
-
-# At the moment say.o is an optional component which can be overridden
-# by a module.
-OBJS+=say.o
-
-ifneq ($(findstring darwin,$(OSARCH)),)
- OBJS+=poll.o
- ASTCFLAGS+=-DPOLLCOMPAT
-else
- ifeq ($(wildcard /usr/include/sys/poll.h),)
- OBJS+=poll.o
- ASTCFLAGS+=-DPOLLCOMPAT
- endif
-endif
-
-ifeq ($(wildcard /usr/include/dlfcn.h),)
- OBJS+=dlfcn.o
-endif
-
-ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc ),)
- ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)
- AST_LIBS+=-ldl
- endif
- ifneq (x$(CAP_LIB),x)
- AST_LIBS+=$(CAP_LIB)
- endif
- AST_LIBS+=-lpthread $(EDITLINE_LIB) -lm -lresolv
-else
- AST_LIBS+=$(EDITLINE_LIB) -lm
-endif
-
-ifneq ($(findstring darwin,$(OSARCH)),)
- AST_LIBS+=-lresolv
- ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)
- ASTLINK=-Wl,-dynamic
- endif
-else
-# These are used for all but Darwin
- ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)
- ASTLINK+=-Wl,--export-dynamic
- else
- ASTLINK+=${GC_LDFLAGS}
- endif
- ifneq ($(findstring BSD,$(OSARCH)),)
- LDFLAGS+=-L/usr/local/lib
- endif
-endif
-
-ifeq ($(OSARCH),FreeBSD)
- AST_LIBS+=-lcrypto
-endif
-
-ifeq ($(OSARCH),NetBSD)
- AST_LIBS+=-lpthread -lcrypto -lm -L/usr/pkg/lib $(EDITLINE_LIB)
-endif
-
-ifeq ($(OSARCH),OpenBSD)
- AST_LIBS+=-lcrypto -lpthread -lm $(EDITLINE_LIB)
-endif
-
-ifeq ($(OSARCH),SunOS)
- AST_LIBS+=-lpthread -ldl -lnsl -lsocket -lresolv -L/opt/ssl/lib -L/usr/local/ssl/lib
- ASTLINK=
-endif
-
-editline/libedit.a:
- cd editline && test -f config.h || CFLAGS="$(PTHREAD_CFLAGS) $(subst $(ASTTOPDIR),../../,$(ASTCFLAGS:-Werror=))" LDFLAGS="$(ASTLDFLAGS)" ./configure --build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM) --with-ncurses=$(NCURSES_DIR) --with-curses=$(CURSES_DIR) --with-termcap=$(TERMCAP_DIR) --with-tinfo=$(TINFO_DIR)
- $(MAKE) -C editline libedit.a
-
-db1-ast/libdb1.a:
- CFLAGS="$(subst $(ASTTOPDIR),../../,$(ASTCFLAGS))" LDFLAGS="$(ASTLDFLAGS)" $(MAKE) -C db1-ast libdb1.a
-
-ast_expr2.c ast_expr2.h:
- bison -o $@ -d --name-prefix=ast_yy ast_expr2.y
-
-ast_expr2f.c:
- flex -o $@ --full ast_expr2.fl # moved the correction of yyfree into the flex input file itself.
- sed 's@#if __STDC_VERSION__ >= 199901L@#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L@' ast_expr2f.c > zz
- mv zz ast_expr2f.c
-
-ast_expr2f.o: ASTCFLAGS+=-Wno-unused
-
-testexpr2: ast_expr2f.c ast_expr2.c ast_expr2.h
- $(CC) -g -c -Iinclude -DSTANDALONE ast_expr2f.c
- $(CC) -g -c -Iinclude -DSTANDALONE ast_expr2.c
- $(CC) -g -o testexpr2 ast_expr2f.o ast_expr2.o
- rm ast_expr2.o ast_expr2f.o
-
-channel.o: ASTCFLAGS+=$(ZAPTEL_INCLUDE)
-asterisk.o: ASTCFLAGS+=$(ZAPTEL_INCLUDE)
-
-stdtime/localtime.o: ASTCFLAGS+=$(AST_NO_STRICT_OVERFLOW)
-
-AST_EMBED_LDSCRIPTS:=$(sort $(EMBED_LDSCRIPTS))
-AST_EMBED_LDFLAGS:=$(foreach dep,$(EMBED_LDFLAGS),$(value $(dep)))
-AST_EMBED_LIBS:=$(foreach dep,$(EMBED_LIBS),$(value $(dep)))
-OBJS:=$(sort $(OBJS))
-
-ifneq ($(wildcard ../channels/h323/Makefile.ast),)
- include ../channels/h323/Makefile.ast
-else
- H323LDFLAGS=
- H323LDLIBS=
-endif
-
-asterisk: $(OBJS) editline/libedit.a db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS)
- @$(ASTTOPDIR)/build_tools/make_build_h > $(ASTTOPDIR)/include/asterisk/build.h.tmp
- @if cmp -s $(ASTTOPDIR)/include/asterisk/build.h.tmp $(ASTTOPDIR)/include/asterisk/build.h ; then echo ; else \
- mv $(ASTTOPDIR)/include/asterisk/build.h.tmp $(ASTTOPDIR)/include/asterisk/build.h ; \
- fi
- @rm -f $(ASTTOPDIR)/include/asterisk/build.h.tmp
- @$(CC) -c -o buildinfo.o $(ASTCFLAGS) buildinfo.c
- $(ECHO_PREFIX) echo " [LD] $^ -> $@"
-ifneq ($(findstring chan_h323,$(MENUSELECT_CHANNELS)),)
- $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS)
-else
- $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS)
-endif
- $(CMD_PREFIX) $(ASTTOPDIR)/build_tools/strip_nonapi $@ || rm $@
-
-clean::
- rm -f asterisk
- rm -f db1-ast/.*.d
- @if [ -f editline/Makefile ]; then $(MAKE) -C editline distclean ; fi
- @$(MAKE) -C db1-ast clean
- @$(MAKE) -C stdtime clean
diff --git a/1.4/main/abstract_jb.c b/1.4/main/abstract_jb.c
deleted file mode 100644
index ed2600070..000000000
--- a/1.4/main/abstract_jb.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * abstract_jb: common implementation-independent jitterbuffer stuff
- *
- * Copyright (C) 2005, Attractel OOD
- *
- * Contributors:
- * Slav Klenov <slav@securax.org>
- *
- * 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.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-/*! \file
- *
- * \brief Common implementation-independent jitterbuffer stuff.
- *
- * \author Slav Klenov <slav@securax.org>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/term.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-
-#include "asterisk/abstract_jb.h"
-#include "fixedjitterbuf.h"
-#include "jitterbuf.h"
-
-/*! Internal jb flags */
-enum {
- JB_USE = (1 << 0),
- JB_TIMEBASE_INITIALIZED = (1 << 1),
- JB_CREATED = (1 << 2)
-};
-
-/* Hooks for the abstract jb implementation */
-
-/*! \brief Create */
-typedef void * (*jb_create_impl)(struct ast_jb_conf *general_config, long resynch_threshold);
-/*! \brief Destroy */
-typedef void (*jb_destroy_impl)(void *jb);
-/*! \brief Put first frame */
-typedef int (*jb_put_first_impl)(void *jb, struct ast_frame *fin, long now);
-/*! \brief Put frame */
-typedef int (*jb_put_impl)(void *jb, struct ast_frame *fin, long now);
-/*! \brief Get frame for now */
-typedef int (*jb_get_impl)(void *jb, struct ast_frame **fout, long now, long interpl);
-/*! \brief Get next */
-typedef long (*jb_next_impl)(void *jb);
-/*! \brief Remove first frame */
-typedef int (*jb_remove_impl)(void *jb, struct ast_frame **fout);
-/*! \brief Force resynch */
-typedef void (*jb_force_resynch_impl)(void *jb);
-
-
-/*!
- * \brief Jitterbuffer implementation private struct.
- */
-struct ast_jb_impl
-{
- char name[AST_JB_IMPL_NAME_SIZE];
- jb_create_impl create;
- jb_destroy_impl destroy;
- jb_put_first_impl put_first;
- jb_put_impl put;
- jb_get_impl get;
- jb_next_impl next;
- jb_remove_impl remove;
- jb_force_resynch_impl force_resync;
-};
-
-/* Implementation functions */
-/* fixed */
-static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold);
-static void jb_destroy_fixed(void *jb);
-static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now);
-static int jb_put_fixed(void *jb, struct ast_frame *fin, long now);
-static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl);
-static long jb_next_fixed(void *jb);
-static int jb_remove_fixed(void *jb, struct ast_frame **fout);
-static void jb_force_resynch_fixed(void *jb);
-/* adaptive */
-static void * jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold);
-static void jb_destroy_adaptive(void *jb);
-static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now);
-static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now);
-static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl);
-static long jb_next_adaptive(void *jb);
-static int jb_remove_adaptive(void *jb, struct ast_frame **fout);
-static void jb_force_resynch_adaptive(void *jb);
-
-/* Available jb implementations */
-static struct ast_jb_impl avail_impl[] =
-{
- {
- .name = "fixed",
- .create = jb_create_fixed,
- .destroy = jb_destroy_fixed,
- .put_first = jb_put_first_fixed,
- .put = jb_put_fixed,
- .get = jb_get_fixed,
- .next = jb_next_fixed,
- .remove = jb_remove_fixed,
- .force_resync = jb_force_resynch_fixed
- },
- {
- .name = "adaptive",
- .create = jb_create_adaptive,
- .destroy = jb_destroy_adaptive,
- .put_first = jb_put_first_adaptive,
- .put = jb_put_adaptive,
- .get = jb_get_adaptive,
- .next = jb_next_adaptive,
- .remove = jb_remove_adaptive,
- .force_resync = jb_force_resynch_adaptive
- }
-};
-
-static int default_impl = 0;
-
-
-/*! Abstract return codes */
-enum {
- JB_IMPL_OK,
- JB_IMPL_DROP,
- JB_IMPL_INTERP,
- JB_IMPL_NOFRAME
-};
-
-/* Translations between impl and abstract return codes */
-static int fixed_to_abstract_code[] =
- {JB_IMPL_OK, JB_IMPL_DROP, JB_IMPL_INTERP, JB_IMPL_NOFRAME};
-static int adaptive_to_abstract_code[] =
- {JB_IMPL_OK, JB_IMPL_NOFRAME, JB_IMPL_NOFRAME, JB_IMPL_INTERP, JB_IMPL_DROP, JB_IMPL_OK};
-
-/* JB_GET actions (used only for the frames log) */
-static char *jb_get_actions[] = {"Delivered", "Dropped", "Interpolated", "No"};
-
-/*! \brief Macros for the frame log files */
-#define jb_framelog(...) do { \
- if (jb->logfile) { \
- fprintf(jb->logfile, __VA_ARGS__); \
- fflush(jb->logfile); \
- } \
-} while (0)
-
-
-/* Internal utility functions */
-static void jb_choose_impl(struct ast_channel *chan);
-static void jb_get_and_deliver(struct ast_channel *chan);
-static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame);
-static long get_now(struct ast_jb *jb, struct timeval *tv);
-
-
-/* Interface ast jb functions impl */
-
-
-static void jb_choose_impl(struct ast_channel *chan)
-{
- struct ast_jb *jb = &chan->jb;
- struct ast_jb_conf *jbconf = &jb->conf;
- struct ast_jb_impl *test_impl;
- int i, avail_impl_count = sizeof(avail_impl) / sizeof(avail_impl[0]);
-
- jb->impl = &avail_impl[default_impl];
-
- if (ast_strlen_zero(jbconf->impl))
- return;
-
- for (i = 0; i < avail_impl_count; i++) {
- test_impl = &avail_impl[i];
- if (!strcasecmp(jbconf->impl, test_impl->name)) {
- jb->impl = test_impl;
- return;
- }
- }
-}
-
-int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1)
-{
- struct ast_jb *jb0 = &c0->jb;
- struct ast_jb *jb1 = &c1->jb;
- struct ast_jb_conf *conf0 = &jb0->conf;
- struct ast_jb_conf *conf1 = &jb1->conf;
- int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER;
- int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER;
- int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED);
- int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED);
- int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED);
- int c0_jb_created = ast_test_flag(jb0, JB_CREATED);
- int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER;
- int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER;
- int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED);
- int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED);
- int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED);
- int c1_jb_created = ast_test_flag(jb1, JB_CREATED);
- int inuse = 0;
-
- /* Determine whether audio going to c0 needs a jitter buffer */
- if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
- ast_set_flag(jb0, JB_USE);
- if (!c0_jb_timebase_initialized) {
- if (c1_jb_timebase_initialized) {
- memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval));
- } else {
- gettimeofday(&jb0->timebase, NULL);
- }
- ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED);
- }
-
- if (!c0_jb_created) {
- jb_choose_impl(c0);
- }
-
- inuse = 1;
- }
-
- /* Determine whether audio going to c1 needs a jitter buffer */
- if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
- ast_set_flag(jb1, JB_USE);
- if (!c1_jb_timebase_initialized) {
- if (c0_jb_timebase_initialized) {
- memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval));
- } else {
- gettimeofday(&jb1->timebase, NULL);
- }
- ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED);
- }
-
- if (!c1_jb_created) {
- jb_choose_impl(c1);
- }
-
- inuse = 1;
- }
-
- return inuse;
-}
-
-int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left)
-{
- struct ast_jb *jb0 = &c0->jb;
- struct ast_jb *jb1 = &c1->jb;
- int c0_use_jb = ast_test_flag(jb0, JB_USE);
- int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
- int c1_use_jb = ast_test_flag(jb1, JB_USE);
- int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
- int wait, wait0, wait1;
- struct timeval tv_now;
-
- if (time_left == 0) {
- /* No time left - the bridge will be retried */
- /* TODO: Test disable this */
- /*return 0;*/
- }
-
- if (time_left < 0) {
- time_left = INT_MAX;
- }
-
- gettimeofday(&tv_now, NULL);
-
- wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left;
- wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left;
-
- wait = wait0 < wait1 ? wait0 : wait1;
- wait = wait < time_left ? wait : time_left;
-
- if (wait == INT_MAX) {
- wait = -1;
- } else if (wait < 1) {
- /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */
- wait = 1;
- }
-
- return wait;
-}
-
-
-int ast_jb_put(struct ast_channel *chan, struct ast_frame *f)
-{
- struct ast_jb *jb = &chan->jb;
- struct ast_jb_impl *jbimpl = jb->impl;
- void *jbobj = jb->jbobj;
- struct ast_frame *frr;
- long now = 0;
-
- if (!ast_test_flag(jb, JB_USE))
- return -1;
-
- if (f->frametype != AST_FRAME_VOICE) {
- if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) {
- jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
- jbimpl->force_resync(jbobj);
- }
-
- return -1;
- }
-
- /* We consider an enabled jitterbuffer should receive frames with valid timing info. */
- if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) {
- ast_log(LOG_WARNING, "%s recieved frame with invalid timing info: "
- "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n",
- chan->name, ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src);
- return -1;
- }
-
- frr = ast_frdup(f);
-
- if (!frr) {
- ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", chan->name);
- return -1;
- }
-
- if (!ast_test_flag(jb, JB_CREATED)) {
- if (create_jb(chan, frr)) {
- ast_frfree(frr);
- /* Disable the jitterbuffer */
- ast_clear_flag(jb, JB_USE);
- return -1;
- }
-
- ast_set_flag(jb, JB_CREATED);
- return 0;
- } else {
- now = get_now(jb, NULL);
- if (jbimpl->put(jbobj, frr, now) != JB_IMPL_OK) {
- jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
- ast_frfree(frr);
- /*return -1;*/
- /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't
- be delivered at all */
- return 0;
- }
-
- jb->next = jbimpl->next(jbobj);
-
- jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
-
- return 0;
- }
-}
-
-
-void ast_jb_get_and_deliver(struct ast_channel *c0, struct ast_channel *c1)
-{
- struct ast_jb *jb0 = &c0->jb;
- struct ast_jb *jb1 = &c1->jb;
- int c0_use_jb = ast_test_flag(jb0, JB_USE);
- int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
- int c1_use_jb = ast_test_flag(jb1, JB_USE);
- int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
-
- if (c0_use_jb && c0_jb_is_created)
- jb_get_and_deliver(c0);
-
- if (c1_use_jb && c1_jb_is_created)
- jb_get_and_deliver(c1);
-}
-
-
-static void jb_get_and_deliver(struct ast_channel *chan)
-{
- struct ast_jb *jb = &chan->jb;
- struct ast_jb_impl *jbimpl = jb->impl;
- void *jbobj = jb->jbobj;
- struct ast_frame *f, finterp;
- long now;
- int interpolation_len, res;
-
- now = get_now(jb, NULL);
- jb->next = jbimpl->next(jbobj);
- if (now < jb->next) {
- jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next);
- return;
- }
-
- while (now >= jb->next) {
- interpolation_len = ast_codec_interp_len(jb->last_format);
-
- res = jbimpl->get(jbobj, &f, now, interpolation_len);
-
- switch(res) {
- case JB_IMPL_OK:
- /* deliver the frame */
- ast_write(chan, f);
- case JB_IMPL_DROP:
- jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n",
- now, jb_get_actions[res], f->ts, f->len);
- jb->last_format = f->subclass;
- ast_frfree(f);
- break;
- case JB_IMPL_INTERP:
- /* interpolate a frame */
- f = &finterp;
- f->frametype = AST_FRAME_VOICE;
- f->subclass = jb->last_format;
- f->datalen = 0;
- f->samples = interpolation_len * 8;
- f->mallocd = 0;
- f->src = "JB interpolation";
- f->data = NULL;
- f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000));
- f->offset = AST_FRIENDLY_OFFSET;
- /* deliver the interpolated frame */
- ast_write(chan, f);
- jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len);
- break;
- case JB_IMPL_NOFRAME:
- ast_log(LOG_WARNING,
- "JB_IMPL_NOFRAME is retuned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n",
- jbimpl->name, now, jb->next, jbimpl->next(jbobj));
- jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now);
- return;
- default:
- ast_log(LOG_ERROR, "This should never happen!\n");
- CRASH;
- break;
- }
-
- jb->next = jbimpl->next(jbobj);
- }
-}
-
-
-static int create_jb(struct ast_channel *chan, struct ast_frame *frr)
-{
- struct ast_jb *jb = &chan->jb;
- struct ast_jb_conf *jbconf = &jb->conf;
- struct ast_jb_impl *jbimpl = jb->impl;
- void *jbobj;
- struct ast_channel *bridged;
- long now;
- char logfile_pathname[20 + AST_JB_IMPL_NAME_SIZE + 2*AST_CHANNEL_NAME + 1];
- char name1[AST_CHANNEL_NAME], name2[AST_CHANNEL_NAME], *tmp;
- int res;
-
- jbobj = jb->jbobj = jbimpl->create(jbconf, jbconf->resync_threshold);
- if (!jbobj) {
- ast_log(LOG_WARNING, "Failed to create jitterbuffer on channel '%s'\n", chan->name);
- return -1;
- }
-
- now = get_now(jb, NULL);
- res = jbimpl->put_first(jbobj, frr, now);
-
- /* The result of putting the first frame should not differ from OK. However, its possible
- some implementations (i.e. adaptive's when resynch_threshold is specified) to drop it. */
- if (res != JB_IMPL_OK) {
- ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", chan->name);
- /*
- jbimpl->destroy(jbobj);
- return -1;
- */
- }
-
- /* Init next */
- jb->next = jbimpl->next(jbobj);
-
- /* Init last format for a first time. */
- jb->last_format = frr->subclass;
-
- /* Create a frame log file */
- if (ast_test_flag(jbconf, AST_JB_LOG)) {
- snprintf(name2, sizeof(name2), "%s", chan->name);
- tmp = strchr(name2, '/');
- if (tmp)
- *tmp = '#';
-
- bridged = ast_bridged_channel(chan);
- if (!bridged) {
- /* We should always have bridged chan if a jitterbuffer is in use */
- CRASH;
- }
- snprintf(name1, sizeof(name1), "%s", bridged->name);
- tmp = strchr(name1, '/');
- if (tmp)
- *tmp = '#';
-
- snprintf(logfile_pathname, sizeof(logfile_pathname),
- "/tmp/ast_%s_jb_%s--%s.log", jbimpl->name, name1, name2);
- jb->logfile = fopen(logfile_pathname, "w+b");
-
- if (!jb->logfile)
- ast_log(LOG_WARNING, "Failed to create frame log file with pathname '%s'\n", logfile_pathname);
-
- if (res == JB_IMPL_OK)
- jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n",
- now, frr->ts, frr->len);
- else
- jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n",
- now, frr->ts, frr->len);
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s jitterbuffer created on channel %s\n", jbimpl->name, chan->name);
-
- /* Free the frame if it has not been queued in the jb */
- if (res != JB_IMPL_OK)
- ast_frfree(frr);
-
- return 0;
-}
-
-
-void ast_jb_destroy(struct ast_channel *chan)
-{
- struct ast_jb *jb = &chan->jb;
- struct ast_jb_impl *jbimpl = jb->impl;
- void *jbobj = jb->jbobj;
- struct ast_frame *f;
-
- if (jb->logfile) {
- fclose(jb->logfile);
- jb->logfile = NULL;
- }
-
- if (ast_test_flag(jb, JB_CREATED)) {
- /* Remove and free all frames still queued in jb */
- while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) {
- ast_frfree(f);
- }
-
- jbimpl->destroy(jbobj);
- jb->jbobj = NULL;
-
- ast_clear_flag(jb, JB_CREATED);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name);
- }
-}
-
-
-static long get_now(struct ast_jb *jb, struct timeval *tv)
-{
- struct timeval now;
-
- if (!tv) {
- tv = &now;
- gettimeofday(tv, NULL);
- }
-
- return ast_tvdiff_ms(*tv, jb->timebase);
-}
-
-
-int ast_jb_read_conf(struct ast_jb_conf *conf, char *varname, char *value)
-{
- int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
- char *name;
- int tmp;
-
- if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen))
- return -1;
-
- name = varname + prefixlen;
-
- if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
- ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED);
- } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
- ast_set2_flag(conf, ast_true(value), AST_JB_FORCED);
- } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
- if ((tmp = atoi(value)) > 0)
- conf->max_size = tmp;
- } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
- if ((tmp = atoi(value)) > 0)
- conf->resync_threshold = tmp;
- } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
- if (!ast_strlen_zero(value))
- snprintf(conf->impl, sizeof(conf->impl), "%s", value);
- } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
- ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
- } else {
- return -1;
- }
-
- return 0;
-}
-
-
-void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
-{
- memcpy(&chan->jb.conf, conf, sizeof(*conf));
-}
-
-
-void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
-{
- memcpy(conf, &chan->jb.conf, sizeof(*conf));
-}
-
-
-/* Implementation functions */
-
-/* fixed */
-
-static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold)
-{
- struct fixed_jb_conf conf;
-
- conf.jbsize = general_config->max_size;
- conf.resync_threshold = resynch_threshold;
-
- return fixed_jb_new(&conf);
-}
-
-
-static void jb_destroy_fixed(void *jb)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
-
- /* destroy the jb */
- fixed_jb_destroy(fixedjb);
-}
-
-
-static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
- int res;
-
- res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
-
- return fixed_to_abstract_code[res];
-}
-
-
-static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
- int res;
-
- res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
-
- return fixed_to_abstract_code[res];
-}
-
-
-static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
- struct fixed_jb_frame frame;
- int res;
-
- res = fixed_jb_get(fixedjb, &frame, now, interpl);
- *fout = frame.data;
-
- return fixed_to_abstract_code[res];
-}
-
-
-static long jb_next_fixed(void *jb)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
-
- return fixed_jb_next(fixedjb);
-}
-
-
-static int jb_remove_fixed(void *jb, struct ast_frame **fout)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
- struct fixed_jb_frame frame;
- int res;
-
- res = fixed_jb_remove(fixedjb, &frame);
- *fout = frame.data;
-
- return fixed_to_abstract_code[res];
-}
-
-
-static void jb_force_resynch_fixed(void *jb)
-{
- struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
-
- fixed_jb_set_force_resynch(fixedjb);
-}
-
-
-/* adaptive */
-
-static void *jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold)
-{
- jb_conf jbconf;
- jitterbuf *adaptivejb;
-
- adaptivejb = jb_new();
- if (adaptivejb) {
- jbconf.max_jitterbuf = general_config->max_size;
- jbconf.resync_threshold = general_config->resync_threshold;
- jbconf.max_contig_interp = 10;
- jb_setconf(adaptivejb, &jbconf);
- }
-
- return adaptivejb;
-}
-
-
-static void jb_destroy_adaptive(void *jb)
-{
- jitterbuf *adaptivejb = (jitterbuf *) jb;
-
- jb_destroy(adaptivejb);
-}
-
-
-static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
-{
- return jb_put_adaptive(jb, fin, now);
-}
-
-
-static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
-{
- jitterbuf *adaptivejb = (jitterbuf *) jb;
- int res;
-
- res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
-
- return adaptive_to_abstract_code[res];
-}
-
-
-static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
-{
- jitterbuf *adaptivejb = (jitterbuf *) jb;
- jb_frame frame;
- int res;
-
- res = jb_get(adaptivejb, &frame, now, interpl);
- *fout = frame.data;
-
- return adaptive_to_abstract_code[res];
-}
-
-
-static long jb_next_adaptive(void *jb)
-{
- jitterbuf *adaptivejb = (jitterbuf *) jb;
-
- return jb_next(adaptivejb);
-}
-
-
-static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
-{
- jitterbuf *adaptivejb = (jitterbuf *) jb;
- jb_frame frame;
- int res;
-
- res = jb_getall(adaptivejb, &frame);
- *fout = frame.data;
-
- return adaptive_to_abstract_code[res];
-}
-
-
-static void jb_force_resynch_adaptive(void *jb)
-{
-}
diff --git a/1.4/main/acl.c b/1.4/main/acl.c
deleted file mode 100644
index 72e354532..000000000
--- a/1.4/main/acl.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Various sorts of access control
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/ioctl.h>
-
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__)
-#include <fcntl.h>
-#include <net/route.h>
-#endif
-
-#if defined(SOLARIS)
-#include <sys/sockio.h>
-#include <net/if.h>
-#elif defined(HAVE_GETIFADDRS)
-#include <ifaddrs.h>
-#endif
-
-/* netinet/ip.h may not define the following (See RFCs 791 and 1349) */
-#if !defined(IPTOS_LOWCOST)
-#define IPTOS_LOWCOST 0x02
-#endif
-
-#if !defined(IPTOS_MINCOST)
-#define IPTOS_MINCOST IPTOS_LOWCOST
-#endif
-
-#include "asterisk/acl.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/srv.h"
-
-struct ast_ha {
- /* Host access rule */
- struct in_addr netaddr;
- struct in_addr netmask;
- int sense;
- struct ast_ha *next;
-};
-
-/* Default IP - if not otherwise set, don't breathe garbage */
-static struct in_addr __ourip = { .s_addr = 0x00000000, };
-
-struct my_ifreq {
- char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "eth0", "ppp0", etc. */
- struct sockaddr_in ifru_addr;
-};
-
-#if (!defined(SOLARIS) && !defined(HAVE_GETIFADDRS))
-static int get_local_address(struct in_addr *ourip)
-{
- return -1;
-}
-#else
-static void score_address(const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
-{
- const char *address;
- int score;
-
- address = ast_inet_ntoa(sin->sin_addr);
-
- /* RFC 1700 alias for the local network */
- if (address[0] == '0')
- score = -25;
- /* RFC 1700 localnet */
- else if (strncmp(address, "127", 3) == 0)
- score = -20;
- /* RFC 1918 non-public address space */
- else if (strncmp(address, "10.", 3) == 0)
- score = -5;
- /* RFC 1918 non-public address space */
- else if (strncmp(address, "172", 3) == 0) {
- /* 172.16.0.0 - 172.19.255.255, but not 172.160.0.0 - 172.169.255.255 */
- if (address[4] == '1' && address[5] >= '6' && address[6] == '.')
- score = -5;
- /* 172.20.0.0 - 172.29.255.255, but not 172.200.0.0 - 172.255.255.255 nor 172.2.0.0 - 172.2.255.255 */
- else if (address[4] == '2' && address[6] == '.')
- score = -5;
- /* 172.30.0.0 - 172.31.255.255 */
- else if (address[4] == '3' && address[5] <= '1')
- score = -5;
- /* All other 172 addresses are public */
- else
- score = 0;
- /* RFC 2544 Benchmark test range */
- } else if (strncmp(address, "198.1", 5) == 0 && address[5] >= '8' && address[6] == '.')
- score = -10;
- /* RFC 1918 non-public address space */
- else if (strncmp(address, "192.168", 7) == 0)
- score = -5;
- /* RFC 3330 Zeroconf network */
- else if (strncmp(address, "169.254", 7) == 0)
- /*!\note Better score than a test network, but not quite as good as RFC 1918
- * address space. The reason is that some Linux distributions automatically
- * configure a Zeroconf address before trying DHCP, so we want to prefer a
- * DHCP lease to a Zeroconf address.
- */
- score = -10;
- /* RFC 3330 Test network */
- else if (strncmp(address, "192.0.2.", 8) == 0)
- score = -15;
- /* Every other address should be publically routable */
- else
- score = 0;
-
- if (score > *best_score) {
- *best_score = score;
- memcpy(best_addr, &sin->sin_addr, sizeof(*best_addr));
- }
-}
-
-static int get_local_address(struct in_addr *ourip)
-{
- int s, res = -1;
-#ifdef SOLARIS
- struct lifreq *ifr = NULL;
- struct lifnum ifn;
- struct lifconf ifc;
- struct sockaddr_in *sa;
- char *buf = NULL;
- int bufsz, x;
-#endif /* SOLARIS */
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
- struct ifaddrs *ifap, *ifaphead;
- int rtnerr;
- const struct sockaddr_in *sin;
-#endif /* BSD_OR_LINUX */
- struct in_addr best_addr;
- int best_score = -100;
- memset(&best_addr, 0, sizeof(best_addr));
-
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
- rtnerr = getifaddrs(&ifaphead);
- if (rtnerr) {
- perror(NULL);
- return -1;
- }
-#endif /* BSD_OR_LINUX */
-
- s = socket(AF_INET, SOCK_STREAM, 0);
-
- if (s > 0) {
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
- for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
-
- if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET) {
- sin = (const struct sockaddr_in *) ifap->ifa_addr;
- score_address(sin, &best_addr, &best_score);
- res = 0;
-
- if (best_score == 0)
- break;
- }
- }
-#endif /* BSD_OR_LINUX */
-
- /* There is no reason whatsoever that this shouldn't work on Linux or BSD also. */
-#ifdef SOLARIS
- /* Get a count of interfaces on the machine */
- ifn.lifn_family = AF_INET;
- ifn.lifn_flags = 0;
- ifn.lifn_count = 0;
- if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
- close(s);
- return -1;
- }
-
- bufsz = ifn.lifn_count * sizeof(struct lifreq);
- if (!(buf = malloc(bufsz))) {
- close(s);
- return -1;
- }
- memset(buf, 0, bufsz);
-
- /* Get a list of interfaces on the machine */
- ifc.lifc_len = bufsz;
- ifc.lifc_buf = buf;
- ifc.lifc_family = AF_INET;
- ifc.lifc_flags = 0;
- if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
- close(s);
- free(buf);
- return -1;
- }
-
- for (ifr = (struct lifreq *)buf, x = 0; x < ifn.lifn_count; ifr++, x++) {
- sa = (struct sockaddr_in *)&(ifr->lifr_addr);
- score_address(sa, &best_addr, &best_score);
- res = 0;
-
- if (best_score == 0)
- break;
- }
-
- free(buf);
-#endif /* SOLARIS */
-
- close(s);
- }
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
- freeifaddrs(ifaphead);
-#endif /* BSD_OR_LINUX */
-
- if (res == 0 && ourip)
- memcpy(ourip, &best_addr, sizeof(*ourip));
- return res;
-}
-#endif /* HAVE_GETIFADDRS */
-
-/* Free HA structure */
-void ast_free_ha(struct ast_ha *ha)
-{
- struct ast_ha *hal;
- while (ha) {
- hal = ha;
- ha = ha->next;
- free(hal);
- }
-}
-
-/* Copy HA structure */
-static void ast_copy_ha(struct ast_ha *from, struct ast_ha *to)
-{
- memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr));
- memcpy(&to->netmask, &from->netmask, sizeof(from->netmask));
- to->sense = from->sense;
-}
-
-/* Create duplicate of ha structure */
-static struct ast_ha *ast_duplicate_ha(struct ast_ha *original)
-{
- struct ast_ha *new_ha;
-
- if ((new_ha = ast_malloc(sizeof(*new_ha)))) {
- /* Copy from original to new object */
- ast_copy_ha(original, new_ha);
- }
-
- return new_ha;
-}
-
-/* Create duplicate HA link list */
-/* Used in chan_sip2 templates */
-struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original)
-{
- struct ast_ha *start = original;
- struct ast_ha *ret = NULL;
- struct ast_ha *link, *prev = NULL;
-
- while (start) {
- link = ast_duplicate_ha(start); /* Create copy of this object */
- if (prev)
- prev->next = link; /* Link previous to this object */
-
- if (!ret)
- ret = link; /* Save starting point */
-
- start = start->next; /* Go to next object */
- prev = link; /* Save pointer to this object */
- }
- return ret; /* Return start of list */
-}
-
-struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path)
-{
- struct ast_ha *ha;
- char *nm = "255.255.255.255";
- char tmp[256];
- struct ast_ha *prev = NULL;
- struct ast_ha *ret;
- int x, z;
- unsigned int y;
-
- ret = path;
- while (path) {
- prev = path;
- path = path->next;
- }
- if ((ha = ast_malloc(sizeof(*ha)))) {
- ast_copy_string(tmp, stuff, sizeof(tmp));
- nm = strchr(tmp, '/');
- if (!nm) {
- nm = "255.255.255.255";
- } else {
- *nm = '\0';
- nm++;
- }
- if (!strchr(nm, '.')) {
- if ((sscanf(nm, "%d", &x) == 1) && (x >= 0) && (x <= 32)) {
- y = 0;
- for (z = 0; z < x; z++) {
- y >>= 1;
- y |= 0x80000000;
- }
- ha->netmask.s_addr = htonl(y);
- }
- } else if (!inet_aton(nm, &ha->netmask)) {
- ast_log(LOG_WARNING, "%s is not a valid netmask\n", nm);
- free(ha);
- return ret;
- }
- if (!inet_aton(tmp, &ha->netaddr)) {
- ast_log(LOG_WARNING, "%s is not a valid IP\n", tmp);
- free(ha);
- return ret;
- }
- ha->netaddr.s_addr &= ha->netmask.s_addr;
- if (!strncasecmp(sense, "p", 1)) {
- ha->sense = AST_SENSE_ALLOW;
- } else {
- ha->sense = AST_SENSE_DENY;
- }
- ha->next = NULL;
- if (prev) {
- prev->next = ha;
- } else {
- ret = ha;
- }
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "%s/%s appended to acl for peer\n", stuff, nm);
- return ret;
-}
-
-int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
-{
- /* Start optimistic */
- int res = AST_SENSE_ALLOW;
- while (ha) {
- char iabuf[INET_ADDRSTRLEN];
- char iabuf2[INET_ADDRSTRLEN];
- /* DEBUG */
- ast_copy_string(iabuf, ast_inet_ntoa(sin->sin_addr), sizeof(iabuf));
- ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
- if (option_debug)
- ast_log(LOG_DEBUG, "##### Testing %s with %s\n", iabuf, iabuf2);
- /* For each rule, if this address and the netmask = the net address
- apply the current rule */
- if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == ha->netaddr.s_addr)
- res = ha->sense;
- ha = ha->next;
- }
- return res;
-}
-
-int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service)
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- char srv[256];
- char host[256];
- int tportno = ntohs(sin->sin_port);
- if (inet_aton(value, &sin->sin_addr))
- return 0;
- if (service) {
- snprintf(srv, sizeof(srv), "%s.%s", service, value);
- if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
- sin->sin_port = htons(tportno);
- value = host;
- }
- }
- hp = ast_gethostbyname(value, &ahp);
- if (hp) {
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- } else {
- ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
- return -1;
- }
- return 0;
-}
-
-struct dscp_codepoint {
- char *name;
- unsigned int space;
-};
-
-/* IANA registered DSCP codepoints */
-
-static const struct dscp_codepoint dscp_pool1[] = {
- { "CS0", 0x00 },
- { "CS1", 0x08 },
- { "CS2", 0x10 },
- { "CS3", 0x18 },
- { "CS4", 0x20 },
- { "CS5", 0x28 },
- { "CS6", 0x30 },
- { "CS7", 0x38 },
- { "AF11", 0x0A },
- { "AF12", 0x0C },
- { "AF13", 0x0E },
- { "AF21", 0x12 },
- { "AF22", 0x14 },
- { "AF23", 0x16 },
- { "AF31", 0x1A },
- { "AF32", 0x1C },
- { "AF33", 0x1E },
- { "AF41", 0x22 },
- { "AF42", 0x24 },
- { "AF43", 0x26 },
- { "EF", 0x2E },
-};
-
-int ast_str2tos(const char *value, unsigned int *tos)
-{
- int fval;
- unsigned int x;
-
- if (sscanf(value, "%i", &fval) == 1) {
- *tos = fval & 0xFF;
- return 0;
- }
-
- for (x = 0; x < sizeof(dscp_pool1) / sizeof(dscp_pool1[0]); x++) {
- if (!strcasecmp(value, dscp_pool1[x].name)) {
- *tos = dscp_pool1[x].space << 2;
- return 0;
- }
- }
-
- if (!strcasecmp(value, "lowdelay"))
- *tos = IPTOS_LOWDELAY;
- else if (!strcasecmp(value, "throughput"))
- *tos = IPTOS_THROUGHPUT;
- else if (!strcasecmp(value, "reliability"))
- *tos = IPTOS_RELIABILITY;
- else if (!strcasecmp(value, "mincost"))
- *tos = IPTOS_MINCOST;
- else if (!strcasecmp(value, "none"))
- *tos = 0;
- else
- return -1;
-
- ast_log(LOG_WARNING, "TOS value %s is deprecated. Please see doc/ip-tos.txt for more information.\n", value);
-
- return 0;
-}
-
-const char *ast_tos2str(unsigned int tos)
-{
- unsigned int x;
-
- switch (tos) {
- case 0:
- return "none";
- case IPTOS_LOWDELAY:
- return "lowdelay";
- case IPTOS_THROUGHPUT:
- return "throughput";
- case IPTOS_RELIABILITY:
- return "reliability";
- case IPTOS_MINCOST:
- return "mincost";
- default:
- for (x = 0; x < sizeof(dscp_pool1) / sizeof(dscp_pool1[0]); x++) {
- if (dscp_pool1[x].space == (tos >> 2))
- return dscp_pool1[x].name;
- }
- }
-
- return "unknown";
-}
-
-int ast_get_ip(struct sockaddr_in *sin, const char *value)
-{
- return ast_get_ip_or_srv(sin, value, NULL);
-}
-
-/* iface is the interface (e.g. eth0); address is the return value */
-int ast_lookup_iface(char *iface, struct in_addr *address)
-{
- int mysock, res = 0;
- struct my_ifreq ifreq;
-
- memset(&ifreq, 0, sizeof(ifreq));
- ast_copy_string(ifreq.ifrn_name, iface, sizeof(ifreq.ifrn_name));
-
- mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
- res = ioctl(mysock, SIOCGIFADDR, &ifreq);
-
- close(mysock);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
- memcpy((char *)address, (char *)&__ourip, sizeof(__ourip));
- return -1;
- } else {
- memcpy((char *)address, (char *)&ifreq.ifru_addr.sin_addr, sizeof(ifreq.ifru_addr.sin_addr));
- return 0;
- }
-}
-
-int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
-{
- int s;
- struct sockaddr_in sin;
- socklen_t slen;
-
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- ast_log(LOG_WARNING, "Cannot create socket\n");
- return -1;
- }
- sin.sin_family = AF_INET;
- sin.sin_port = 5060;
- sin.sin_addr = *them;
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) {
- ast_log(LOG_WARNING, "Cannot connect\n");
- close(s);
- return -1;
- }
- slen = sizeof(sin);
- if (getsockname(s, (struct sockaddr *)&sin, &slen)) {
- ast_log(LOG_WARNING, "Cannot get socket name\n");
- close(s);
- return -1;
- }
- close(s);
- *us = sin.sin_addr;
- return 0;
-}
-
-int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr)
-{
- char ourhost[MAXHOSTNAMELEN] = "";
- struct ast_hostent ahp;
- struct hostent *hp;
- struct in_addr saddr;
-
- /* just use the bind address if it is nonzero */
- if (ntohl(bindaddr.sin_addr.s_addr)) {
- memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip));
- return 0;
- }
- /* try to use our hostname */
- if (gethostname(ourhost, sizeof(ourhost) - 1)) {
- ast_log(LOG_WARNING, "Unable to get hostname\n");
- } else {
- hp = ast_gethostbyname(ourhost, &ahp);
- if (hp) {
- memcpy(ourip, hp->h_addr, sizeof(*ourip));
- return 0;
- }
- }
- /* A.ROOT-SERVERS.NET. */
- if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip))
- return 0;
- return get_local_address(ourip);
-}
-
diff --git a/1.4/main/aescrypt.c b/1.4/main/aescrypt.c
deleted file mode 100644
index 1ccddf3f5..000000000
--- a/1.4/main/aescrypt.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 26/08/2003
-
-*/
-
-/*! \file
- *
- * \brief This file contains the code for implementing encryption and decryption
- * for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
- * can optionally be replaced by code written in assembler using NASM. For
- * further details see the file aesopt.h
- *
- * \author Dr Brian Gladman <brg@gladman.me.uk>
- */
-
-#include "aesopt.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
-#define so(y,x,c) word_out(y, c, s(x,c))
-
-#if defined(ARRAYS)
-#define locals(y,x) x[4],y[4]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-#endif
-
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#if defined(ENCRYPTION) && !defined(AES_ASM)
-
-/* Visual C++ .Net v7.1 provides the fastest encryption code when using
- Pentium optimiation with small code but this is poor for decryption
- so we need to control this with the following VC++ pragmas
-*/
-
-#if defined(_MSC_VER)
-#pragma optimize( "s", on )
-#endif
-
-/* Given the column (c) of the output state variable, the following
- macros give the input state variables which are needed in its
- computation for each row (r) of the state. All the alternative
- macros give the same end values but expand into different ways
- of calculating these values. In particular the complex macro
- used for dynamically variable block sizes is designed to expand
- to a compile time constant whenever possible but will expand to
- conditional clauses on some branches (I am grateful to Frank
- Yellin for this construction)
-*/
-
-#define fwd_var(x,r,c)\
- ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
- : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
- : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
- : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
-
-#if defined(FT4_SET)
-#undef dec_fmvars
-#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
-#elif defined(FT1_SET)
-#undef dec_fmvars
-#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
-#else
-#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
-#else
-#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
-#endif
-
-aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1])
-{ aes_32t locals(b0, b1);
- const aes_32t *kp = cx->ks;
-#ifdef dec_fmvars
- dec_fmvars; /* declare variables for fwd_mcol() if needed */
-#endif
-
- aes_32t nr = (kp[45] ^ kp[52] ^ kp[53] ? kp[52] : 14);
-
-#ifdef AES_ERR_CHK
- if( (nr != 10 || !(kp[0] | kp[3] | kp[4]))
- && (nr != 12 || !(kp[0] | kp[5] | kp[6]))
- && (nr != 14 || !(kp[0] | kp[7] | kp[8])) )
- return aes_error;
-#endif
-
- state_in(b0, in_blk, kp);
-
-#if (ENC_UNROLL == FULL)
-
- switch(nr)
- {
- case 14:
- round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
- kp += 2 * N_COLS;
- case 12:
- round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
- kp += 2 * N_COLS;
- case 10:
- round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
- round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
- }
-
-#else
-
-#if (ENC_UNROLL == PARTIAL)
- { aes_32t rnd;
- for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
- {
- kp += N_COLS;
- round(fwd_rnd, b1, b0, kp);
- kp += N_COLS;
- round(fwd_rnd, b0, b1, kp);
- }
- kp += N_COLS;
- round(fwd_rnd, b1, b0, kp);
-#else
- { aes_32t rnd;
- for(rnd = 0; rnd < nr - 1; ++rnd)
- {
- kp += N_COLS;
- round(fwd_rnd, b1, b0, kp);
- l_copy(b0, b1);
- }
-#endif
- kp += N_COLS;
- round(fwd_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(DECRYPTION) && !defined(AES_ASM)
-
-/* Visual C++ .Net v7.1 provides the fastest encryption code when using
- Pentium optimiation with small code but this is poor for decryption
- so we need to control this with the following VC++ pragmas
-*/
-
-#if defined(_MSC_VER)
-#pragma optimize( "t", on )
-#endif
-
-/* Given the column (c) of the output state variable, the following
- macros give the input state variables which are needed in its
- computation for each row (r) of the state. All the alternative
- macros give the same end values but expand into different ways
- of calculating these values. In particular the complex macro
- used for dynamically variable block sizes is designed to expand
- to a compile time constant whenever possible but will expand to
- conditional clauses on some branches (I am grateful to Frank
- Yellin for this construction)
-*/
-
-#define inv_var(x,r,c)\
- ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
- : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
- : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
- : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
-
-#if defined(IT4_SET)
-#undef dec_imvars
-#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
-#elif defined(IT1_SET)
-#undef dec_imvars
-#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
-#else
-#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
-#else
-#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
-#endif
-
-aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1])
-{ aes_32t locals(b0, b1);
-#ifdef dec_imvars
- dec_imvars; /* declare variables for inv_mcol() if needed */
-#endif
-
- aes_32t nr = (cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] ? cx->ks[52] : 14);
- const aes_32t *kp = cx->ks + nr * N_COLS;
-
-#ifdef AES_ERR_CHK
- if( (nr != 10 || !(cx->ks[0] | cx->ks[3] | cx->ks[4]))
- && (nr != 12 || !(cx->ks[0] | cx->ks[5] | cx->ks[6]))
- && (nr != 14 || !(cx->ks[0] | cx->ks[7] | cx->ks[8])) )
- return aes_error;
-#endif
-
- state_in(b0, in_blk, kp);
-
-#if (DEC_UNROLL == FULL)
-
- switch(nr)
- {
- case 14:
- round(inv_rnd, b1, b0, kp - 1 * N_COLS);
- round(inv_rnd, b0, b1, kp - 2 * N_COLS);
- kp -= 2 * N_COLS;
- case 12:
- round(inv_rnd, b1, b0, kp - 1 * N_COLS);
- round(inv_rnd, b0, b1, kp - 2 * N_COLS);
- kp -= 2 * N_COLS;
- case 10:
- round(inv_rnd, b1, b0, kp - 1 * N_COLS);
- round(inv_rnd, b0, b1, kp - 2 * N_COLS);
- round(inv_rnd, b1, b0, kp - 3 * N_COLS);
- round(inv_rnd, b0, b1, kp - 4 * N_COLS);
- round(inv_rnd, b1, b0, kp - 5 * N_COLS);
- round(inv_rnd, b0, b1, kp - 6 * N_COLS);
- round(inv_rnd, b1, b0, kp - 7 * N_COLS);
- round(inv_rnd, b0, b1, kp - 8 * N_COLS);
- round(inv_rnd, b1, b0, kp - 9 * N_COLS);
- round(inv_lrnd, b0, b1, kp - 10 * N_COLS);
- }
-
-#else
-
-#if (DEC_UNROLL == PARTIAL)
- { aes_32t rnd;
- for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
- {
- kp -= N_COLS;
- round(inv_rnd, b1, b0, kp);
- kp -= N_COLS;
- round(inv_rnd, b0, b1, kp);
- }
- kp -= N_COLS;
- round(inv_rnd, b1, b0, kp);
-#else
- { aes_32t rnd;
- for(rnd = 0; rnd < nr - 1; ++rnd)
- {
- kp -= N_COLS;
- round(inv_rnd, b1, b0, kp);
- l_copy(b0, b1);
- }
-#endif
- kp -= N_COLS;
- round(inv_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/1.4/main/aeskey.c b/1.4/main/aeskey.c
deleted file mode 100644
index d34badc6b..000000000
--- a/1.4/main/aeskey.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 26/08/2003
-
-*/
-
-/*! \file
- *
- * \brief This file contains the code for implementing the key schedule for AES
- * (Rijndael) for block and key sizes of 16, 24, and 32 bytes. See aesopt.h
- * for further details including optimisation.
- *
- * \author Dr Brian Gladman <brg@gladman.me.uk>
- */
-
-#include "aesopt.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
- length can be specified in bytes, with legal values of 16, 24
- and 32, or in bits, with legal values of 128, 192 and 256. These
- values correspond with Nk values of 4, 6 and 8 respectively.
-
- The following macros implement a single cycle in the key
- schedule generation process. The number of cycles needed
- for each cx->n_col and nk value is:
-
- nk = 4 5 6 7 8
- ------------------------------
- cx->n_col = 4 10 9 8 7 7
- cx->n_col = 5 14 11 10 9 9
- cx->n_col = 6 19 15 12 11 11
- cx->n_col = 7 21 19 16 13 14
- cx->n_col = 8 29 23 19 17 14
-*/
-
-#define ke4(k,i) \
-{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
- k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-#define kel4(k,i) \
-{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
- k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-
-#define ke6(k,i) \
-{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
- k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
- k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
-}
-#define kel6(k,i) \
-{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
- k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-}
-
-#define ke8(k,i) \
-{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
- k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
- k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
- k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
-}
-#define kel8(k,i) \
-{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
- k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
-}
-
-#if defined(ENCRYPTION_KEY_SCHEDULE)
-
-#if defined(AES_128) || defined(AES_VAR)
-
-aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1])
-{ aes_32t ss[4];
-
- cx->ks[0] = ss[0] = word_in(in_key, 0);
- cx->ks[1] = ss[1] = word_in(in_key, 1);
- cx->ks[2] = ss[2] = word_in(in_key, 2);
- cx->ks[3] = ss[3] = word_in(in_key, 3);
-
-#if ENC_UNROLL == NONE
- { aes_32t i;
-
- for(i = 0; i < ((11 * N_COLS - 1) / 4); ++i)
- ke4(cx->ks, i);
- }
-#else
- ke4(cx->ks, 0); ke4(cx->ks, 1);
- ke4(cx->ks, 2); ke4(cx->ks, 3);
- ke4(cx->ks, 4); ke4(cx->ks, 5);
- ke4(cx->ks, 6); ke4(cx->ks, 7);
- ke4(cx->ks, 8); kel4(cx->ks, 9);
-#endif
-
- /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
- /* key and must be non-zero for 128 and 192 bits keys */
- cx->ks[53] = cx->ks[45] = 0;
- cx->ks[52] = 10;
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(AES_192) || defined(AES_VAR)
-
-aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1])
-{ aes_32t ss[6];
-
- cx->ks[0] = ss[0] = word_in(in_key, 0);
- cx->ks[1] = ss[1] = word_in(in_key, 1);
- cx->ks[2] = ss[2] = word_in(in_key, 2);
- cx->ks[3] = ss[3] = word_in(in_key, 3);
- cx->ks[4] = ss[4] = word_in(in_key, 4);
- cx->ks[5] = ss[5] = word_in(in_key, 5);
-
-#if ENC_UNROLL == NONE
- { aes_32t i;
-
- for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
- ke6(cx->ks, i);
- }
-#else
- ke6(cx->ks, 0); ke6(cx->ks, 1);
- ke6(cx->ks, 2); ke6(cx->ks, 3);
- ke6(cx->ks, 4); ke6(cx->ks, 5);
- ke6(cx->ks, 6); kel6(cx->ks, 7);
-#endif
-
- /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
- /* key and must be non-zero for 128 and 192 bits keys */
- cx->ks[53] = cx->ks[45];
- cx->ks[52] = 12;
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(AES_256) || defined(AES_VAR)
-
-aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1])
-{ aes_32t ss[8];
-
- cx->ks[0] = ss[0] = word_in(in_key, 0);
- cx->ks[1] = ss[1] = word_in(in_key, 1);
- cx->ks[2] = ss[2] = word_in(in_key, 2);
- cx->ks[3] = ss[3] = word_in(in_key, 3);
- cx->ks[4] = ss[4] = word_in(in_key, 4);
- cx->ks[5] = ss[5] = word_in(in_key, 5);
- cx->ks[6] = ss[6] = word_in(in_key, 6);
- cx->ks[7] = ss[7] = word_in(in_key, 7);
-
-#if ENC_UNROLL == NONE
- { aes_32t i;
-
- for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
- ke8(cx->ks, i);
- }
-#else
- ke8(cx->ks, 0); ke8(cx->ks, 1);
- ke8(cx->ks, 2); ke8(cx->ks, 3);
- ke8(cx->ks, 4); ke8(cx->ks, 5);
- kel8(cx->ks, 6);
-#endif
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(AES_VAR)
-
-aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1])
-{
- switch(key_len)
- {
-#ifdef AES_ERR_CHK
- case 16: case 128: return aes_encrypt_key128(in_key, cx);
- case 24: case 192: return aes_encrypt_key192(in_key, cx);
- case 32: case 256: return aes_encrypt_key256(in_key, cx);
- default: return aes_error;
-#else
- case 16: case 128: aes_encrypt_key128(in_key, cx); return;
- case 24: case 192: aes_encrypt_key192(in_key, cx); return;
- case 32: case 256: aes_encrypt_key256(in_key, cx); return;
-#endif
- }
-}
-
-#endif
-
-#endif
-
-#if defined(DECRYPTION_KEY_SCHEDULE)
-
-#if DEC_ROUND == NO_TABLES
-#define ff(x) (x)
-#else
-#define ff(x) inv_mcol(x)
-#ifdef dec_imvars
-#define d_vars dec_imvars
-#endif
-#endif
-
-#if 1
-#define kdf4(k,i) \
-{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
- ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
- ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
- ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
-}
-#define kd4(k,i) \
-{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
- k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
- k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
-}
-#define kdl4(k,i) \
-{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
- k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
- k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
-}
-#else
-#define kdf4(k,i) \
-{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
-}
-#define kd4(k,i) \
-{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
- ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
- ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
- ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
- ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
-}
-#define kdl4(k,i) \
-{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
- ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
-}
-#endif
-
-#define kdf6(k,i) \
-{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
- ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
-}
-#define kd6(k,i) \
-{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
- ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
- ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
- ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
- ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
- ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
- ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
-}
-#define kdl6(k,i) \
-{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
- ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
-}
-
-#define kdf8(k,i) \
-{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
- ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
- ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
-}
-#define kd8(k,i) \
-{ aes_32t g = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
- ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
- ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
- ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
- ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
- g = ls_box(ss[3],0); \
- ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
- ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
- ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
- ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
-}
-#define kdl8(k,i) \
-{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
- ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
-}
-
-#if defined(AES_128) || defined(AES_VAR)
-
-aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1])
-{ aes_32t ss[5];
-#ifdef d_vars
- d_vars;
-#endif
- cx->ks[0] = ss[0] = word_in(in_key, 0);
- cx->ks[1] = ss[1] = word_in(in_key, 1);
- cx->ks[2] = ss[2] = word_in(in_key, 2);
- cx->ks[3] = ss[3] = word_in(in_key, 3);
-
-#if DEC_UNROLL == NONE
- { aes_32t i;
-
- for(i = 0; i < (11 * N_COLS - 1) / 4; ++i)
- ke4(cx->ks, i);
-#if !(DEC_ROUND == NO_TABLES)
- for(i = N_COLS; i < 10 * N_COLS; ++i)
- cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
- }
-#else
- kdf4(cx->ks, 0); kd4(cx->ks, 1);
- kd4(cx->ks, 2); kd4(cx->ks, 3);
- kd4(cx->ks, 4); kd4(cx->ks, 5);
- kd4(cx->ks, 6); kd4(cx->ks, 7);
- kd4(cx->ks, 8); kdl4(cx->ks, 9);
-#endif
-
- /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
- /* key and must be non-zero for 128 and 192 bits keys */
- cx->ks[53] = cx->ks[45] = 0;
- cx->ks[52] = 10;
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(AES_192) || defined(AES_VAR)
-
-aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1])
-{ aes_32t ss[7];
-#ifdef d_vars
- d_vars;
-#endif
- cx->ks[0] = ss[0] = word_in(in_key, 0);
- cx->ks[1] = ss[1] = word_in(in_key, 1);
- cx->ks[2] = ss[2] = word_in(in_key, 2);
- cx->ks[3] = ss[3] = word_in(in_key, 3);
-
-#if DEC_UNROLL == NONE
- cx->ks[4] = ss[4] = word_in(in_key, 4);
- cx->ks[5] = ss[5] = word_in(in_key, 5);
- { aes_32t i;
-
- for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
- ke6(cx->ks, i);
-#if !(DEC_ROUND == NO_TABLES)
- for(i = N_COLS; i < 12 * N_COLS; ++i)
- cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
- }
-#else
- cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
- cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
- kdf6(cx->ks, 0); kd6(cx->ks, 1);
- kd6(cx->ks, 2); kd6(cx->ks, 3);
- kd6(cx->ks, 4); kd6(cx->ks, 5);
- kd6(cx->ks, 6); kdl6(cx->ks, 7);
-#endif
-
- /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
- /* key and must be non-zero for 128 and 192 bits keys */
- cx->ks[53] = cx->ks[45];
- cx->ks[52] = 12;
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(AES_256) || defined(AES_VAR)
-
-aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1])
-{ aes_32t ss[8];
-#ifdef d_vars
- d_vars;
-#endif
- cx->ks[0] = ss[0] = word_in(in_key, 0);
- cx->ks[1] = ss[1] = word_in(in_key, 1);
- cx->ks[2] = ss[2] = word_in(in_key, 2);
- cx->ks[3] = ss[3] = word_in(in_key, 3);
-
-#if DEC_UNROLL == NONE
- cx->ks[4] = ss[4] = word_in(in_key, 4);
- cx->ks[5] = ss[5] = word_in(in_key, 5);
- cx->ks[6] = ss[6] = word_in(in_key, 6);
- cx->ks[7] = ss[7] = word_in(in_key, 7);
- { aes_32t i;
-
- for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
- ke8(cx->ks, i);
-#if !(DEC_ROUND == NO_TABLES)
- for(i = N_COLS; i < 14 * N_COLS; ++i)
- cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
- }
-#else
- cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
- cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
- cx->ks[6] = ff(ss[6] = word_in(in_key, 6));
- cx->ks[7] = ff(ss[7] = word_in(in_key, 7));
- kdf8(cx->ks, 0); kd8(cx->ks, 1);
- kd8(cx->ks, 2); kd8(cx->ks, 3);
- kd8(cx->ks, 4); kd8(cx->ks, 5);
- kdl8(cx->ks, 6);
-#endif
-#ifdef AES_ERR_CHK
- return aes_good;
-#endif
-}
-
-#endif
-
-#if defined(AES_VAR)
-
-aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1])
-{
- switch(key_len)
- {
-#ifdef AES_ERR_CHK
- case 16: case 128: return aes_decrypt_key128(in_key, cx);
- case 24: case 192: return aes_decrypt_key192(in_key, cx);
- case 32: case 256: return aes_decrypt_key256(in_key, cx);
- default: return aes_error;
-#else
- case 16: case 128: aes_decrypt_key128(in_key, cx); return;
- case 24: case 192: aes_decrypt_key192(in_key, cx); return;
- case 32: case 256: aes_decrypt_key256(in_key, cx); return;
-#endif
- }
-}
-
-#endif
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/1.4/main/aesopt.h b/1.4/main/aesopt.h
deleted file mode 100644
index bb4f05a0b..000000000
--- a/1.4/main/aesopt.h
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 26/08/2003
-
- My thanks go to Dag Arne Osvik for devising the schemes used here for key
- length derivation from the form of the key schedule
-
- This file contains the compilation options for AES (Rijndael) and code
- that is common across encryption, key scheduling and table generation.
-
- OPERATION
-
- These source code files implement the AES algorithm Rijndael designed by
- Joan Daemen and Vincent Rijmen. This version is designed for the standard
- block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
- and 32 bytes).
-
- This version is designed for flexibility and speed using operations on
- 32-bit words rather than operations on bytes. It can be compiled with
- either big or little endian internal byte order but is faster when the
- native byte order for the processor is used.
-
- THE CIPHER INTERFACE
-
- The cipher interface is implemented as an array of bytes in which lower
- AES bit sequence indexes map to higher numeric significance within bytes.
-
- aes_08t (an unsigned 8-bit type)
- aes_32t (an unsigned 32-bit type)
- struct aes_encrypt_ctx (structure for the cipher encryption context)
- struct aes_decrypt_ctx (structure for the cipher decryption context)
- aes_rval the function return type
-
- C subroutine calls:
-
- aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1]);
- aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1]);
- aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1]);
- aes_rval aes_encrypt(const void *in_blk,
- void *out_blk, const aes_encrypt_ctx cx[1]);
-
- aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1]);
- aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1]);
- aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1]);
- aes_rval aes_decrypt(const void *in_blk,
- void *out_blk, const aes_decrypt_ctx cx[1]);
-
- IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
- you call genTabs() before AES is used so that the tables are initialised.
-
- C++ aes class subroutines:
-
- Class AESencrypt for encryption
-
- Construtors:
- AESencrypt(void)
- AESencrypt(const void *in_key) - 128 bit key
- Members:
- void key128(const void *in_key)
- void key192(const void *in_key)
- void key256(const void *in_key)
- void encrypt(const void *in_blk, void *out_blk) const
-
- Class AESdecrypt for encryption
- Construtors:
- AESdecrypt(void)
- AESdecrypt(const void *in_key) - 128 bit key
- Members:
- void key128(const void *in_key)
- void key192(const void *in_key)
- void key256(const void *in_key)
- void decrypt(const void *in_blk, void *out_blk) const
-
- COMPILATION
-
- The files used to provide AES (Rijndael) are
-
- a. aes.h for the definitions needed for use in C.
- b. aescpp.h for the definitions needed for use in C++.
- c. aesopt.h for setting compilation options (also includes common code).
- d. aescrypt.c for encryption and decrytpion, or
- e. aeskey.c for key scheduling.
- f. aestab.c for table loading or generation.
- g. aescrypt.asm for encryption and decryption using assembler code.
- h. aescrypt.mmx.asm for encryption and decryption using MMX assembler.
-
- To compile AES (Rijndael) for use in C code use aes.h and set the
- defines here for the facilities you need (key lengths, encryption
- and/or decryption). Do not define AES_DLL or AES_CPP. Set the options
- for optimisations and table sizes here.
-
- To compile AES (Rijndael) for use in in C++ code use aescpp.h but do
- not define AES_DLL
-
- To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
- aes.h and include the AES_DLL define.
-
- CONFIGURATION OPTIONS (here and in aes.h)
-
- a. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
- b. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
- c. If you want the code to run in a specific internal byte order, then
- ALGORITHM_BYTE_ORDER must be set accordingly.
- d. set other configuration options decribed below.
-*/
-
-#ifndef _AESOPT_H
-#define _AESOPT_H
-
-#include "asterisk/aes.h"
-#include "asterisk/endian.h"
-
-/* CONFIGURATION - USE OF DEFINES
-
- Later in this section there are a number of defines that control the
- operation of the code. In each section, the purpose of each define is
- explained so that the relevant form can be included or excluded by
- setting either 1's or 0's respectively on the branches of the related
- #if clauses.
-*/
-
-/* BYTE ORDER IN 32-BIT WORDS
-
- To obtain the highest speed on processors with 32-bit words, this code
- needs to determine the byte order of the target machine. The following
- block of code is an attempt to capture the most obvious ways in which
- various environemnts define byte order. It may well fail, in which case
- the definitions will need to be set by editing at the points marked
- **** EDIT HERE IF NECESSARY **** below. My thanks to Peter Gutmann for
- some of these defines (from cryptlib).
-*/
-
-#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
-#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
-
-#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
- defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
- defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
- defined( vax ) || defined( vms ) || defined( VMS ) || \
- defined( __VMS )
-
-#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-
-#endif
-
-#if defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
- defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
- defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
- defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
- defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
- defined( __TANDEM ) || defined( THINK_C ) || defined( __VMCMS__ )
-
-#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-
-#endif
-
-/* if the platform is still not known, try to find its byte order */
-/* from commonly used definitions in the headers included earlier */
-
-#if !defined(PLATFORM_BYTE_ORDER)
-
-#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
-# if defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-# elif defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-# elif defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-# endif
-
-#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
-# if defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-# elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-# elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)
-# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-# endif
-
-#elif defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)
-# if defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
-# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-# elif !defined(__LITTLE_ENDIAN__) && defined(__BIG_ENDIAN__)
-# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
-# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)
-# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-# endif
-
-#elif 0 /* **** EDIT HERE IF NECESSARY **** */
-#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
-
-#elif 0 /* **** EDIT HERE IF NECESSARY **** */
-#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
-
-#else
-#error Please edit aesopt.h (line 235 or 238) to set the platform byte order
-#endif
-
-#endif
-
-/* SOME LOCAL DEFINITIONS */
-
-#define NO_TABLES 0
-#define ONE_TABLE 1
-#define FOUR_TABLES 4
-#define NONE 0
-#define PARTIAL 1
-#define FULL 2
-
-#if defined(bswap32)
-#define aes_sw32 bswap32
-#elif defined(bswap_32)
-#define aes_sw32 bswap_32
-#else
-#define brot(x,n) (((aes_32t)(x) << n) | ((aes_32t)(x) >> (32 - n)))
-#define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
-#endif
-
-/* 1. FUNCTIONS REQUIRED
-
- This implementation provides subroutines for encryption, decryption
- and for setting the three key lengths (separately) for encryption
- and decryption. When the assembler code is not being used the following
- definition blocks allow the selection of the routines that are to be
- included in the compilation.
-*/
-#ifdef AES_ENCRYPT
-#define ENCRYPTION
-#define ENCRYPTION_KEY_SCHEDULE
-#endif
-
-#ifdef AES_DECRYPT
-#define DECRYPTION
-#define DECRYPTION_KEY_SCHEDULE
-#endif
-
-/* 2. ASSEMBLER SUPPORT
-
- This define (which can be on the command line) enables the use of the
- assembler code routines for encryption and decryption with the C code
- only providing key scheduling
-*/
-#if 0
-#define AES_ASM
-#endif
-
-/* 3. BYTE ORDER WITHIN 32 BIT WORDS
-
- The fundamental data processing units in Rijndael are 8-bit bytes. The
- input, output and key input are all enumerated arrays of bytes in which
- bytes are numbered starting at zero and increasing to one less than the
- number of bytes in the array in question. This enumeration is only used
- for naming bytes and does not imply any adjacency or order relationship
- from one byte to another. When these inputs and outputs are considered
- as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
- byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
- In this implementation bits are numbered from 0 to 7 starting at the
- numerically least significant end of each byte (bit n represents 2^n).
-
- However, Rijndael can be implemented more efficiently using 32-bit
- words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
- into word[n]. While in principle these bytes can be assembled into words
- in any positions, this implementation only supports the two formats in
- which bytes in adjacent positions within words also have adjacent byte
- numbers. This order is called big-endian if the lowest numbered bytes
- in words have the highest numeric significance and little-endian if the
- opposite applies.
-
- This code can work in either order irrespective of the order used by the
- machine on which it runs. Normally the internal byte order will be set
- to the order of the processor on which the code is to be run but this
- define can be used to reverse this in special situations
-
- NOTE: Assembler code versions rely on PLATFORM_BYTE_ORDER being set
-*/
-#if 1 || defined(AES_ASM)
-#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
-#elif 0
-#define ALGORITHM_BYTE_ORDER BRG_LITTLE_ENDIAN
-#elif 0
-#define ALGORITHM_BYTE_ORDER BRG_BIG_ENDIAN
-#else
-#error The algorithm byte order is not defined
-#endif
-
-/* 4. FAST INPUT/OUTPUT OPERATIONS.
-
- On some machines it is possible to improve speed by transferring the
- bytes in the input and output arrays to and from the internal 32-bit
- variables by addressing these arrays as if they are arrays of 32-bit
- words. On some machines this will always be possible but there may
- be a large performance penalty if the byte arrays are not aligned on
- the normal word boundaries. On other machines this technique will
- lead to memory access errors when such 32-bit word accesses are not
- properly aligned. The option SAFE_IO avoids such problems but will
- often be slower on those machines that support misaligned access
- (especially so if care is taken to align the input and output byte
- arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
- assumed that access to byte arrays as if they are arrays of 32-bit
- words will not cause problems when such accesses are misaligned.
-*/
-#if 1 && !defined(_MSC_VER)
-#define SAFE_IO
-#endif
-
-/* 5. LOOP UNROLLING
-
- The code for encryption and decrytpion cycles through a number of rounds
- that can be implemented either in a loop or by expanding the code into a
- long sequence of instructions, the latter producing a larger program but
- one that will often be much faster. The latter is called loop unrolling.
- There are also potential speed advantages in expanding two iterations in
- a loop with half the number of iterations, which is called partial loop
- unrolling. The following options allow partial or full loop unrolling
- to be set independently for encryption and decryption
-*/
-#if 1
-#define ENC_UNROLL FULL
-#elif 0
-#define ENC_UNROLL PARTIAL
-#else
-#define ENC_UNROLL NONE
-#endif
-
-#if 1
-#define DEC_UNROLL FULL
-#elif 0
-#define DEC_UNROLL PARTIAL
-#else
-#define DEC_UNROLL NONE
-#endif
-
-/* 6. FAST FINITE FIELD OPERATIONS
-
- If this section is included, tables are used to provide faster finite
- field arithmetic (this has no effect if FIXED_TABLES is defined).
-*/
-#if 1
-#define FF_TABLES
-#endif
-
-/* 7. INTERNAL STATE VARIABLE FORMAT
-
- The internal state of Rijndael is stored in a number of local 32-bit
- word varaibles which can be defined either as an array or as individual
- names variables. Include this section if you want to store these local
- varaibles in arrays. Otherwise individual local variables will be used.
-*/
-#if 1
-#define ARRAYS
-#endif
-
-/* In this implementation the columns of the state array are each held in
- 32-bit words. The state array can be held in various ways: in an array
- of words, in a number of individual word variables or in a number of
- processor registers. The following define maps a variable name x and
- a column number c to the way the state array variable is to be held.
- The first define below maps the state into an array x[c] whereas the
- second form maps the state into a number of individual variables x0,
- x1, etc. Another form could map individual state colums to machine
- register names.
-*/
-
-#if defined(ARRAYS)
-#define s(x,c) x[c]
-#else
-#define s(x,c) x##c
-#endif
-
-/* 8. FIXED OR DYNAMIC TABLES
-
- When this section is included the tables used by the code are compiled
- statically into the binary file. Otherwise the subroutine gen_tabs()
- must be called to compute them before the code is first used.
-*/
-#if 1
-#define FIXED_TABLES
-#endif
-
-/* 9. TABLE ALIGNMENT
-
- On some sytsems speed will be improved by aligning the AES large lookup
- tables on particular boundaries. This define should be set to a power of
- two giving the desired alignment. It can be left undefined if alignment
- is not needed. This option is specific to the Microsft VC++ compiler -
- it seems to sometimes cause trouble for the VC++ version 6 compiler.
-*/
-
-#if 0 && defined(_MSC_VER) && (_MSC_VER >= 1300)
-#define TABLE_ALIGN 64
-#endif
-
-/* 10. INTERNAL TABLE CONFIGURATION
-
- This cipher proceeds by repeating in a number of cycles known as 'rounds'
- which are implemented by a round function which can optionally be speeded
- up using tables. The basic tables are each 256 32-bit words, with either
- one or four tables being required for each round function depending on
- how much speed is required. The encryption and decryption round functions
- are different and the last encryption and decrytpion round functions are
- different again making four different round functions in all.
-
- This means that:
- 1. Normal encryption and decryption rounds can each use either 0, 1
- or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
- 2. The last encryption and decryption rounds can also use either 0, 1
- or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-
- Include or exclude the appropriate definitions below to set the number
- of tables used by this implementation.
-*/
-
-#if 1 /* set tables for the normal encryption round */
-#define ENC_ROUND FOUR_TABLES
-#elif 0
-#define ENC_ROUND ONE_TABLE
-#else
-#define ENC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the last encryption round */
-#define LAST_ENC_ROUND FOUR_TABLES
-#elif 0
-#define LAST_ENC_ROUND ONE_TABLE
-#else
-#define LAST_ENC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the normal decryption round */
-#define DEC_ROUND FOUR_TABLES
-#elif 0
-#define DEC_ROUND ONE_TABLE
-#else
-#define DEC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the last decryption round */
-#define LAST_DEC_ROUND FOUR_TABLES
-#elif 0
-#define LAST_DEC_ROUND ONE_TABLE
-#else
-#define LAST_DEC_ROUND NO_TABLES
-#endif
-
-/* The decryption key schedule can be speeded up with tables in the same
- way that the round functions can. Include or exclude the following
- defines to set this requirement.
-*/
-#if 1
-#define KEY_SCHED FOUR_TABLES
-#elif 0
-#define KEY_SCHED ONE_TABLE
-#else
-#define KEY_SCHED NO_TABLES
-#endif
-
-/* END OF CONFIGURATION OPTIONS */
-
-#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
-
-/* Disable or report errors on some combinations of options */
-
-#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
-#undef LAST_ENC_ROUND
-#define LAST_ENC_ROUND NO_TABLES
-#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
-#undef LAST_ENC_ROUND
-#define LAST_ENC_ROUND ONE_TABLE
-#endif
-
-#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
-#undef ENC_UNROLL
-#define ENC_UNROLL NONE
-#endif
-
-#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
-#undef LAST_DEC_ROUND
-#define LAST_DEC_ROUND NO_TABLES
-#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
-#undef LAST_DEC_ROUND
-#define LAST_DEC_ROUND ONE_TABLE
-#endif
-
-#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
-#undef DEC_UNROLL
-#define DEC_UNROLL NONE
-#endif
-
-/* upr(x,n): rotates bytes within words by n positions, moving bytes to
- higher index positions with wrap around into low positions
- ups(x,n): moves bytes by n positions to higher index positions in
- words but without wrap around
- bval(x,n): extracts a byte from a word
-
- NOTE: The definitions given here are intended only for use with
- unsigned variables and with shift counts that are compile
- time constants
-*/
-
-#if (ALGORITHM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
-#define upr(x,n) (((aes_32t)(x) << (8 * (n))) | ((aes_32t)(x) >> (32 - 8 * (n))))
-#define ups(x,n) ((aes_32t) (x) << (8 * (n)))
-#define bval(x,n) ((aes_08t)((x) >> (8 * (n))))
-#define bytes2word(b0, b1, b2, b3) \
- (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
-#endif
-
-#if (ALGORITHM_BYTE_ORDER == BRG_BIG_ENDIAN)
-#define upr(x,n) (((aes_32t)(x) >> (8 * (n))) | ((aes_32t)(x) << (32 - 8 * (n))))
-#define ups(x,n) ((aes_32t) (x) >> (8 * (n))))
-#define bval(x,n) ((aes_08t)((x) >> (24 - 8 * (n))))
-#define bytes2word(b0, b1, b2, b3) \
- (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
-#endif
-
-#if defined(SAFE_IO)
-
-#define word_in(x,c) bytes2word(((aes_08t*)(x)+4*c)[0], ((aes_08t*)(x)+4*c)[1], \
- ((aes_08t*)(x)+4*c)[2], ((aes_08t*)(x)+4*c)[3])
-#define word_out(x,c,v) { ((aes_08t*)(x)+4*c)[0] = bval(v,0); ((aes_08t*)(x)+4*c)[1] = bval(v,1); \
- ((aes_08t*)(x)+4*c)[2] = bval(v,2); ((aes_08t*)(x)+4*c)[3] = bval(v,3); }
-
-#elif (ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER)
-
-#define word_in(x,c) (*((aes_32t*)(x)+(c)))
-#define word_out(x,c,v) (*((aes_32t*)(x)+(c)) = (v))
-
-#else
-
-#define word_in(x,c) aes_sw32(*((aes_32t*)(x)+(c)))
-#define word_out(x,c,v) (*((aes_32t*)(x)+(c)) = aes_sw32(v))
-
-#endif
-
-/* the finite field modular polynomial and elements */
-
-#define WPOLY 0x011b
-#define BPOLY 0x1b
-
-/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
-#define m1 0x80808080
-#define m2 0x7f7f7f7f
-#define gf_mulx(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
-
-/* The following defines provide alternative definitions of gf_mulx that might
- give improved performance if a fast 32-bit multiply is not available. Note
- that a temporary variable u needs to be defined where gf_mulx is used.
-
-#define gf_mulx(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-#define m4 (0x01010101 * BPOLY)
-#define gf_mulx(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-*/
-
-/* Work out which tables are needed for the different options */
-
-#ifdef AES_ASM
-#ifdef ENC_ROUND
-#undef ENC_ROUND
-#endif
-#define ENC_ROUND FOUR_TABLES
-#ifdef LAST_ENC_ROUND
-#undef LAST_ENC_ROUND
-#endif
-#define LAST_ENC_ROUND FOUR_TABLES
-#ifdef DEC_ROUND
-#undef DEC_ROUND
-#endif
-#define DEC_ROUND FOUR_TABLES
-#ifdef LAST_DEC_ROUND
-#undef LAST_DEC_ROUND
-#endif
-#define LAST_DEC_ROUND FOUR_TABLES
-#ifdef KEY_SCHED
-#undef KEY_SCHED
-#define KEY_SCHED FOUR_TABLES
-#endif
-#endif
-
-#if defined(ENCRYPTION) || defined(AES_ASM)
-#if ENC_ROUND == ONE_TABLE
-#define FT1_SET
-#elif ENC_ROUND == FOUR_TABLES
-#define FT4_SET
-#else
-#define SBX_SET
-#endif
-#if LAST_ENC_ROUND == ONE_TABLE
-#define FL1_SET
-#elif LAST_ENC_ROUND == FOUR_TABLES
-#define FL4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
-#endif
-
-#if defined(DECRYPTION) || defined(AES_ASM)
-#if DEC_ROUND == ONE_TABLE
-#define IT1_SET
-#elif DEC_ROUND == FOUR_TABLES
-#define IT4_SET
-#else
-#define ISB_SET
-#endif
-#if LAST_DEC_ROUND == ONE_TABLE
-#define IL1_SET
-#elif LAST_DEC_ROUND == FOUR_TABLES
-#define IL4_SET
-#elif !defined(ISB_SET)
-#define ISB_SET
-#endif
-#endif
-
-#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
-#if KEY_SCHED == ONE_TABLE
-#define LS1_SET
-#define IM1_SET
-#elif KEY_SCHED == FOUR_TABLES
-#define LS4_SET
-#define IM4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
-#endif
-
-/* generic definitions of Rijndael macros that use tables */
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
- box[bval(vf(x,0,c),rf(0,c))], \
- box[bval(vf(x,1,c),rf(1,c))], \
- box[bval(vf(x,2,c),rf(2,c))], \
- box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- ( tab[bval(vf(x,0,c),rf(0,c))] \
- ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
- ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
- ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- ( tab[0][bval(vf(x,0,c),rf(0,c))] \
- ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
- ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
- ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c) (x)
-#define rf1(r,c) (r)
-#define rf2(r,c) ((8+r-c)&3)
-
-/* perform forward and inverse column mix operation on four bytes in long word x in */
-/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
-
-#if defined(FM4_SET) /* not currently used */
-#define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0)
-#elif defined(FM1_SET) /* not currently used */
-#define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
-#else
-#define dec_fmvars aes_32t g2
-#define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
-#endif
-
-#if defined(IM4_SET)
-#define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
-#elif defined(IM1_SET)
-#define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
-#else
-#define dec_imvars aes_32t g2, g4, g9
-#define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
- (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
-#endif
-
-#if defined(FL4_SET)
-#define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c)
-#elif defined(LS4_SET)
-#define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c)
-#elif defined(FL1_SET)
-#define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c)
-#elif defined(LS1_SET)
-#define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c)
-#else
-#define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c)
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* If there are no global variables, the definitions here can be
- used to put the AES tables in a structure so that a pointer
- can then be added to the AES context to pass them to the AES
- routines that need them. If this facility is used, the calling
- program has to ensure that this pointer is managed appropriately.
- In particular, the value of the t_dec(in,it) item in the table
- structure must be set to zero in order to ensure that the tables
- are initialised. In practice the three code sequences in aeskey.c
- that control the calls to gen_tabs() and the gen_tabs() routine
- itself will have to be changed for a specific implementation. If
- global variables are available it will generally be preferable to
- use them with the precomputed FIXED_TABLES option that uses static
- global tables.
-
- The following defines can be used to control the way the tables
- are defined, initialised and used in embedded environments that
- require special features for these purposes
-
- the 't_dec' construction is used to declare fixed table arrays
- the 't_set' construction is used to set fixed table values
- the 't_use' construction is used to access fixed table values
-
- 256 byte tables:
-
- t_xxx(s,box) => forward S box
- t_xxx(i,box) => inverse S box
-
- 256 32-bit word OR 4 x 256 32-bit word tables:
-
- t_xxx(f,n) => forward normal round
- t_xxx(f,l) => forward last round
- t_xxx(i,n) => inverse normal round
- t_xxx(i,l) => inverse last round
- t_xxx(l,s) => key schedule table
- t_xxx(i,m) => key schedule table
-
- Other variables and tables:
-
- t_xxx(r,c) => the rcon table
-*/
-
-#define t_dec(m,n) t_##m##n
-#define t_set(m,n) t_##m##n
-#define t_use(m,n) t_##m##n
-
-#if defined(DO_TABLES) /* declare and instantiate tables */
-
-/* finite field arithmetic operations for table generation */
-
-#if defined(FIXED_TABLES) || !defined(FF_TABLES)
-
-#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
-#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
-#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
- ^ (((x>>5) & 4) * WPOLY))
-#define f3(x) (f2(x) ^ x)
-#define f9(x) (f8(x) ^ x)
-#define fb(x) (f8(x) ^ f2(x) ^ x)
-#define fd(x) (f8(x) ^ f4(x) ^ x)
-#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
-
-#else
-
-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
-#define fi(x) ((x) ? pow[ 255 - log[x]] : 0)
-
-#endif
-
-#if defined(FIXED_TABLES) /* declare and set values for static tables */
-
-#define sb_data(w) \
- w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
- w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
- w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
- w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
- w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
- w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
- w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
- w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
- w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
- w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
- w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
- w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
- w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
- w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
- w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
- w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
- w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
- w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
- w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
- w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
- w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
- w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
- w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
- w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
- w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
- w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
- w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
- w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
- w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
- w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
- w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
- w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
-
-#define isb_data(w) \
- w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
- w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
- w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
- w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
- w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
- w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
- w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
- w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
- w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
- w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
- w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
- w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
- w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
- w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
- w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
- w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
- w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
- w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
- w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
- w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
- w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
- w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
- w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
- w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
- w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
- w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
- w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
- w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
- w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
- w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
- w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
- w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
-
-#define mm_data(w) \
- w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
- w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
- w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
- w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
- w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
- w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
- w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
- w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
- w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
- w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
- w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
- w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
- w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
- w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
- w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
- w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
- w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
- w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
- w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
- w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
- w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
- w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
- w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
- w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
- w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
- w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
- w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
- w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
- w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
- w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
- w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
- w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
-
-#define h0(x) (x)
-
-/* These defines are used to ensure tables are generated in the
- right format depending on the internal byte order required
-*/
-
-#define w0(p) bytes2word(p, 0, 0, 0)
-#define w1(p) bytes2word(0, p, 0, 0)
-#define w2(p) bytes2word(0, 0, p, 0)
-#define w3(p) bytes2word(0, 0, 0, p)
-
-#define u0(p) bytes2word(f2(p), p, p, f3(p))
-#define u1(p) bytes2word(f3(p), f2(p), p, p)
-#define u2(p) bytes2word(p, f3(p), f2(p), p)
-#define u3(p) bytes2word(p, p, f3(p), f2(p))
-
-#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
-#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
-#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
-#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
-
-const aes_32t t_dec(r,c)[RC_LENGTH] =
-{
- w0(0x01), w0(0x02), w0(0x04), w0(0x08), w0(0x10),
- w0(0x20), w0(0x40), w0(0x80), w0(0x1b), w0(0x36)
-};
-
-#define d_1(t,n,b,v) const t n[256] = { b(v##0) }
-#define d_4(t,n,b,v) const t n[4][256] = { { b(v##0) }, { b(v##1) }, { b(v##2) }, { b(v##3) } }
-
-#else /* declare and instantiate tables for dynamic value generation in in tab.c */
-
-aes_32t t_dec(r,c)[RC_LENGTH];
-
-#define d_1(t,n,b,v) t n[256]
-#define d_4(t,n,b,v) t n[4][256]
-
-#endif
-
-#else /* declare tables without instantiation */
-
-#if defined(FIXED_TABLES)
-
-extern const aes_32t t_dec(r,c)[RC_LENGTH];
-
-#if defined(_MSC_VER) && defined(TABLE_ALIGN)
-#define d_1(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) const t n[256]
-#define d_4(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) const t n[4][256]
-#else
-#define d_1(t,n,b,v) extern const t n[256]
-#define d_4(t,n,b,v) extern const t n[4][256]
-#endif
-#else
-
-extern aes_32t t_dec(r,c)[RC_LENGTH];
-
-#if defined(_MSC_VER) && defined(TABLE_ALIGN)
-#define d_1(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) t n[256]
-#define d_4(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) t n[4][256]
-#else
-#define d_1(t,n,b,v) extern t n[256]
-#define d_4(t,n,b,v) extern t n[4][256]
-#endif
-#endif
-
-#endif
-
-#ifdef SBX_SET
- d_1(aes_08t, t_dec(s,box), sb_data, h);
-#endif
-#ifdef ISB_SET
- d_1(aes_08t, t_dec(i,box), isb_data, h);
-#endif
-
-#ifdef FT1_SET
- d_1(aes_32t, t_dec(f,n), sb_data, u);
-#endif
-#ifdef FT4_SET
- d_4(aes_32t, t_dec(f,n), sb_data, u);
-#endif
-
-#ifdef FL1_SET
- d_1(aes_32t, t_dec(f,l), sb_data, w);
-#endif
-#ifdef FL4_SET
- d_4(aes_32t, t_dec(f,l), sb_data, w);
-#endif
-
-#ifdef IT1_SET
- d_1(aes_32t, t_dec(i,n), isb_data, v);
-#endif
-#ifdef IT4_SET
- d_4(aes_32t, t_dec(i,n), isb_data, v);
-#endif
-
-#ifdef IL1_SET
- d_1(aes_32t, t_dec(i,l), isb_data, w);
-#endif
-#ifdef IL4_SET
- d_4(aes_32t, t_dec(i,l), isb_data, w);
-#endif
-
-#ifdef LS1_SET
-#ifdef FL1_SET
-#undef LS1_SET
-#else
- d_1(aes_32t, t_dec(l,s), sb_data, w);
-#endif
-#endif
-
-#ifdef LS4_SET
-#ifdef FL4_SET
-#undef LS4_SET
-#else
- d_4(aes_32t, t_dec(l,s), sb_data, w);
-#endif
-#endif
-
-#ifdef IM1_SET
- d_1(aes_32t, t_dec(i,m), mm_data, v);
-#endif
-#ifdef IM4_SET
- d_4(aes_32t, t_dec(i,m), mm_data, v);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/1.4/main/aestab.c b/1.4/main/aestab.c
deleted file mode 100644
index c84a480af..000000000
--- a/1.4/main/aestab.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 26/08/2003
-
-*/
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define DO_TABLES
-
-#include "aesopt.h"
-
-#if defined(FIXED_TABLES)
-
-/* implemented in case of wrong call for fixed tables */
-
-void gen_tabs(void)
-{
-}
-
-#else /* dynamic table generation */
-
-#if !defined(FF_TABLES)
-
-/* Generate the tables for the dynamic table option
-
- It will generally be sensible to use tables to compute finite
- field multiplies and inverses but where memory is scarse this
- code might sometimes be better. But it only has effect during
- initialisation so its pretty unimportant in overall terms.
-*/
-
-/* return 2 ^ (n - 1) where n is the bit number of the highest bit
- set in x with x in the range 1 < x < 0x00000200. This form is
- used so that locals within fi can be bytes rather than words
-*/
-
-static aes_08t hibit(const aes_32t x)
-{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
-
- r |= (r >> 2);
- r |= (r >> 4);
- return (r + 1) >> 1;
-}
-
-/* return the inverse of the finite field element x */
-
-static aes_08t fi(const aes_08t x)
-{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
- if(x < 2) return x;
-
- for(;;)
- {
- if(!n1) return v1;
-
- while(n2 >= n1)
- {
- n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
- }
-
- if(!n2) return v2;
-
- while(n1 >= n2)
- {
- n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
- }
- }
-}
-
-#endif
-
-/* The forward and inverse affine transformations used in the S-box */
-
-#define fwd_affine(x) \
- (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
-
-#define inv_affine(x) \
- (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
-
-static int init = 0;
-
-void gen_tabs(void)
-{ aes_32t i, w;
-
-#if defined(FF_TABLES)
-
- aes_08t pow[512], log[256];
-
- if(init) return;
- /* log and power tables for GF(2^8) finite field with
- WPOLY as modular polynomial - the simplest primitive
- root is 0x03, used here to generate the tables
- */
-
- i = 0; w = 1;
- do
- {
- pow[i] = (aes_08t)w;
- pow[i + 255] = (aes_08t)w;
- log[w] = (aes_08t)i++;
- w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
- }
- while (w != 1);
-
-#else
- if(init) return;
-#endif
-
- for(i = 0, w = 1; i < RC_LENGTH; ++i)
- {
- t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
- w = f2(w);
- }
-
- for(i = 0; i < 256; ++i)
- { aes_08t b;
-
- b = fwd_affine(fi((aes_08t)i));
- w = bytes2word(f2(b), b, b, f3(b));
-
-#ifdef SBX_SET
- t_set(s,box)[i] = b;
-#endif
-
-#ifdef FT1_SET /* tables for a normal encryption round */
- t_set(f,n)[i] = w;
-#endif
-#ifdef FT4_SET
- t_set(f,n)[0][i] = w;
- t_set(f,n)[1][i] = upr(w,1);
- t_set(f,n)[2][i] = upr(w,2);
- t_set(f,n)[3][i] = upr(w,3);
-#endif
- w = bytes2word(b, 0, 0, 0);
-
-#ifdef FL1_SET /* tables for last encryption round (may also */
- t_set(f,l)[i] = w; /* be used in the key schedule) */
-#endif
-#ifdef FL4_SET
- t_set(f,l)[0][i] = w;
- t_set(f,l)[1][i] = upr(w,1);
- t_set(f,l)[2][i] = upr(w,2);
- t_set(f,l)[3][i] = upr(w,3);
-#endif
-
-#ifdef LS1_SET /* table for key schedule if t_set(f,l) above is */
- t_set(l,s)[i] = w; /* not of the required form */
-#endif
-#ifdef LS4_SET
- t_set(l,s)[0][i] = w;
- t_set(l,s)[1][i] = upr(w,1);
- t_set(l,s)[2][i] = upr(w,2);
- t_set(l,s)[3][i] = upr(w,3);
-#endif
-
- b = fi(inv_affine((aes_08t)i));
- w = bytes2word(fe(b), f9(b), fd(b), fb(b));
-
-#ifdef IM1_SET /* tables for the inverse mix column operation */
- t_set(i,m)[b] = w;
-#endif
-#ifdef IM4_SET
- t_set(i,m)[0][b] = w;
- t_set(i,m)[1][b] = upr(w,1);
- t_set(i,m)[2][b] = upr(w,2);
- t_set(i,m)[3][b] = upr(w,3);
-#endif
-
-#ifdef ISB_SET
- t_set(i,box)[i] = b;
-#endif
-#ifdef IT1_SET /* tables for a normal decryption round */
- t_set(i,n)[i] = w;
-#endif
-#ifdef IT4_SET
- t_set(i,n)[0][i] = w;
- t_set(i,n)[1][i] = upr(w,1);
- t_set(i,n)[2][i] = upr(w,2);
- t_set(i,n)[3][i] = upr(w,3);
-#endif
- w = bytes2word(b, 0, 0, 0);
-#ifdef IL1_SET /* tables for last decryption round */
- t_set(i,l)[i] = w;
-#endif
-#ifdef IL4_SET
- t_set(i,l)[0][i] = w;
- t_set(i,l)[1][i] = upr(w,1);
- t_set(i,l)[2][i] = upr(w,2);
- t_set(i,l)[3][i] = upr(w,3);
-#endif
- }
- init = 1;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
diff --git a/1.4/main/alaw.c b/1.4/main/alaw.c
deleted file mode 100644
index b94772ea6..000000000
--- a/1.4/main/alaw.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief u-Law to Signed linear conversion
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/alaw.h"
-
-#define AMI_MASK 0x55
-
-static inline unsigned char linear2alaw (short int linear)
-{
- int mask;
- int seg;
- int pcm_val;
- static int seg_end[8] =
- {
- 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
- };
-
- pcm_val = linear;
- if (pcm_val >= 0)
- {
- /* Sign (7th) bit = 1 */
- mask = AMI_MASK | 0x80;
- }
- else
- {
- /* Sign bit = 0 */
- mask = AMI_MASK;
- pcm_val = -pcm_val;
- }
-
- /* Convert the scaled magnitude to segment number. */
- for (seg = 0; seg < 8; seg++)
- {
- if (pcm_val <= seg_end[seg])
- break;
- }
- /* Combine the sign, segment, and quantization bits. */
- return ((seg << 4) | ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
-}
-/*- End of function --------------------------------------------------------*/
-
-static inline short int alaw2linear (unsigned char alaw)
-{
- int i;
- int seg;
-
- alaw ^= AMI_MASK;
- i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
- seg = (((int) alaw & 0x70) >> 4);
- if (seg)
- i = (i + 0x100) << (seg - 1);
- return (short int) ((alaw & 0x80) ? i : -i);
-}
-
-unsigned char __ast_lin2a[8192];
-short __ast_alaw[256];
-
-void ast_alaw_init(void)
-{
- int i;
- /*
- * Set up mu-law conversion table
- */
- for(i = 0;i < 256;i++)
- {
- __ast_alaw[i] = alaw2linear(i);
- }
- /* set up the reverse (mu-law) conversion table */
- for(i = -32768; i < 32768; i++)
- {
- __ast_lin2a[((unsigned short)i) >> 3] = linear2alaw(i);
- }
-
-}
-
diff --git a/1.4/main/app.c b/1.4/main/app.c
deleted file mode 100644
index ffad73507..000000000
--- a/1.4/main/app.c
+++ /dev/null
@@ -1,1427 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Convenient Application Routines
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <regex.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/file.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/indications.h"
-#include "asterisk/linkedlists.h"
-
-#define MAX_OTHER_FORMATS 10
-
-static AST_LIST_HEAD_STATIC(groups, ast_group_info);
-
-/* !
-This function presents a dialtone and reads an extension into 'collect'
-which must be a pointer to a **pre-initialized** array of char having a
-size of 'size' suitable for writing to. It will collect no more than the smaller
-of 'maxlen' or 'size' minus the original strlen() of collect digits.
-\return 0 if extension does not exist, 1 if extension exists
-*/
-int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout)
-{
- struct tone_zone_sound *ts;
- int res=0, x=0;
-
- if (maxlen > size)
- maxlen = size;
-
- if (!timeout && chan->pbx)
- timeout = chan->pbx->dtimeout;
- else if (!timeout)
- timeout = 5;
-
- ts = ast_get_indication_tone(chan->zone,"dial");
- if (ts && ts->data[0])
- res = ast_playtones_start(chan, 0, ts->data, 0);
- else
- ast_log(LOG_NOTICE,"Huh....? no dial for indications?\n");
-
- for (x = strlen(collect); x < maxlen; ) {
- res = ast_waitfordigit(chan, timeout);
- if (!ast_ignore_pattern(context, collect))
- ast_playtones_stop(chan);
- if (res < 1)
- break;
- if (res == '#')
- break;
- collect[x++] = res;
- if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num))
- break;
- }
- if (res >= 0)
- res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0;
- return res;
-}
-
-/*! \param c The channel to read from
- * \param prompt The file to stream to the channel
- * \param s The string to read in to. Must be at least the size of your length
- * \param maxlen How many digits to read (maximum)
- * \param timeout set timeout to 0 for "standard" timeouts. Set timeout to -1 for
- * "ludicrous time" (essentially never times out) */
-int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout)
-{
- int res,to,fto;
- /* XXX Merge with full version? XXX */
- if (maxlen)
- s[0] = '\0';
- if (prompt) {
- res = ast_streamfile(c, prompt, c->language);
- if (res < 0)
- return res;
- }
- fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000;
- to = c->pbx ? c->pbx->dtimeout * 1000 : 2000;
-
- if (timeout > 0)
- fto = to = timeout;
- if (timeout < 0)
- fto = to = 1000000000;
- res = ast_readstring(c, s, maxlen, to, fto, "#");
- return res;
-}
-
-
-int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd)
-{
- int res, to, fto;
- if (prompt) {
- res = ast_streamfile(c, prompt, c->language);
- if (res < 0)
- return res;
- }
- fto = 6000;
- to = 2000;
- if (timeout > 0)
- fto = to = timeout;
- if (timeout < 0)
- fto = to = 1000000000;
- res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd);
- return res;
-}
-
-static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL;
-static int (*ast_inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL;
-static int (*ast_messagecount_func)(const char *context, const char *mailbox, const char *folder) = NULL;
-
-void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
- int (*inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs),
- int (*messagecount_func)(const char *context, const char *mailbox, const char *folder))
-{
- ast_has_voicemail_func = has_voicemail_func;
- ast_inboxcount_func = inboxcount_func;
- ast_messagecount_func = messagecount_func;
-}
-
-void ast_uninstall_vm_functions(void)
-{
- ast_has_voicemail_func = NULL;
- ast_inboxcount_func = NULL;
- ast_messagecount_func = NULL;
-}
-
-int ast_app_has_voicemail(const char *mailbox, const char *folder)
-{
- static int warned = 0;
- if (ast_has_voicemail_func)
- return ast_has_voicemail_func(mailbox, folder);
-
- if ((option_verbose > 2) && !warned) {
- ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX");
- warned++;
- }
- return 0;
-}
-
-
-int ast_app_inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
-{
- static int warned = 0;
- if (newmsgs)
- *newmsgs = 0;
- if (oldmsgs)
- *oldmsgs = 0;
- if (ast_inboxcount_func)
- return ast_inboxcount_func(mailbox, newmsgs, oldmsgs);
-
- if (!warned && (option_verbose > 2)) {
- warned++;
- ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox);
- }
-
- return 0;
-}
-
-int ast_app_messagecount(const char *context, const char *mailbox, const char *folder)
-{
- static int warned = 0;
- if (ast_messagecount_func)
- return ast_messagecount_func(context, mailbox, folder);
-
- if (!warned && (option_verbose > 2)) {
- warned++;
- ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s@%s/%s but voicemail not loaded.\n", mailbox, context, folder);
- }
-
- return 0;
-}
-
-int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between)
-{
- const char *ptr;
- int res = 0;
- struct ast_silence_generator *silgen = NULL;
-
- if (!between)
- between = 100;
-
- if (peer)
- res = ast_autoservice_start(peer);
-
- if (!res)
- res = ast_waitfor(chan, 100);
-
- /* ast_waitfor will return the number of remaining ms on success */
- if (res < 0)
- return res;
-
- if (ast_opt_transmit_silence) {
- silgen = ast_channel_start_silence_generator(chan);
- }
-
- for (ptr = digits; *ptr; ptr++) {
- if (*ptr == 'w') {
- /* 'w' -- wait half a second */
- if ((res = ast_safe_sleep(chan, 500)))
- break;
- } else if (strchr("0123456789*#abcdfABCDF", *ptr)) {
- /* Character represents valid DTMF */
- if (*ptr == 'f' || *ptr == 'F') {
- /* ignore return values if not supported by channel */
- ast_indicate(chan, AST_CONTROL_FLASH);
- } else
- ast_senddigit(chan, *ptr);
- /* pause between digits */
- if ((res = ast_safe_sleep(chan, between)))
- break;
- } else
- ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr);
- }
-
- if (peer) {
- /* Stop autoservice on the peer channel, but don't overwrite any error condition
- that has occurred previously while acting on the primary channel */
- if (ast_autoservice_stop(peer) && !res)
- res = -1;
- }
-
- if (silgen) {
- ast_channel_stop_silence_generator(chan, silgen);
- }
-
- return res;
-}
-
-struct linear_state {
- int fd;
- int autoclose;
- int allowoverride;
- int origwfmt;
-};
-
-static void linear_release(struct ast_channel *chan, void *params)
-{
- struct linear_state *ls = params;
- if (ls->origwfmt && ast_set_write_format(chan, ls->origwfmt)) {
- ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, ls->origwfmt);
- }
- if (ls->autoclose)
- close(ls->fd);
- free(params);
-}
-
-static int linear_generator(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct ast_frame f;
- short buf[2048 + AST_FRIENDLY_OFFSET / 2];
- struct linear_state *ls = data;
- int res;
- len = samples * 2;
- if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
- ast_log(LOG_WARNING, "Can't generate %d bytes of data!\n" ,len);
- len = sizeof(buf) - AST_FRIENDLY_OFFSET;
- }
- memset(&f, 0, sizeof(f));
- res = read(ls->fd, buf + AST_FRIENDLY_OFFSET/2, len);
- if (res > 0) {
- f.frametype = AST_FRAME_VOICE;
- f.subclass = AST_FORMAT_SLINEAR;
- f.data = buf + AST_FRIENDLY_OFFSET/2;
- f.datalen = res;
- f.samples = res / 2;
- f.offset = AST_FRIENDLY_OFFSET;
- ast_write(chan, &f);
- if (res == len)
- return 0;
- }
- return -1;
-}
-
-static void *linear_alloc(struct ast_channel *chan, void *params)
-{
- struct linear_state *ls;
- /* In this case, params is already malloc'd */
- if (params) {
- ls = params;
- if (ls->allowoverride)
- ast_set_flag(chan, AST_FLAG_WRITE_INT);
- else
- ast_clear_flag(chan, AST_FLAG_WRITE_INT);
- ls->origwfmt = chan->writeformat;
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
- ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name);
- free(ls);
- ls = params = NULL;
- }
- }
- return params;
-}
-
-static struct ast_generator linearstream =
-{
- alloc: linear_alloc,
- release: linear_release,
- generate: linear_generator,
-};
-
-int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, int allowoverride)
-{
- struct linear_state *lin;
- char tmpf[256];
- int res = -1;
- int autoclose = 0;
- if (fd < 0) {
- if (ast_strlen_zero(filename))
- return -1;
- autoclose = 1;
- if (filename[0] == '/')
- ast_copy_string(tmpf, filename, sizeof(tmpf));
- else
- snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", (char *)ast_config_AST_DATA_DIR, "sounds", filename);
- fd = open(tmpf, O_RDONLY);
- if (fd < 0){
- ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno));
- return -1;
- }
- }
- if ((lin = ast_calloc(1, sizeof(*lin)))) {
- lin->fd = fd;
- lin->allowoverride = allowoverride;
- lin->autoclose = autoclose;
- res = ast_activate_generator(chan, &linearstream, lin);
- }
- return res;
-}
-
-int ast_control_streamfile(struct ast_channel *chan, const char *file,
- const char *fwd, const char *rev,
- const char *stop, const char *pause,
- const char *restart, int skipms)
-{
- char *breaks = NULL;
- char *end = NULL;
- int blen = 2;
- int res;
- long pause_restart_point = 0;
-
- if (stop)
- blen += strlen(stop);
- if (pause)
- blen += strlen(pause);
- if (restart)
- blen += strlen(restart);
-
- if (blen > 2) {
- breaks = alloca(blen + 1);
- breaks[0] = '\0';
- if (stop)
- strcat(breaks, stop);
- if (pause)
- strcat(breaks, pause);
- if (restart)
- strcat(breaks, restart);
- }
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
-
- if (file) {
- if ((end = strchr(file,':'))) {
- if (!strcasecmp(end, ":end")) {
- *end = '\0';
- end++;
- }
- }
- }
-
- for (;;) {
- ast_stopstream(chan);
- res = ast_streamfile(chan, file, chan->language);
- if (!res) {
- if (pause_restart_point) {
- ast_seekstream(chan->stream, pause_restart_point, SEEK_SET);
- pause_restart_point = 0;
- }
- else if (end) {
- ast_seekstream(chan->stream, 0, SEEK_END);
- end = NULL;
- };
- res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms);
- }
-
- if (res < 1)
- break;
-
- /* We go at next loop if we got the restart char */
- if (restart && strchr(restart, res)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "we'll restart the stream here at next loop\n");
- pause_restart_point = 0;
- continue;
- }
-
- if (pause && strchr(pause, res)) {
- pause_restart_point = ast_tellstream(chan->stream);
- for (;;) {
- ast_stopstream(chan);
- res = ast_waitfordigit(chan, 1000);
- if (!res)
- continue;
- else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res)))
- break;
- }
- if (res == *pause) {
- res = 0;
- continue;
- }
- }
-
- if (res == -1)
- break;
-
- /* if we get one of our stop chars, return it to the calling function */
- if (stop && strchr(stop, res))
- break;
- }
-
- /* If we are returning a digit cast it as char */
- if (res > 0 || chan->stream)
- res = (char)res;
-
- ast_stopstream(chan);
-
- return res;
-}
-
-int ast_play_and_wait(struct ast_channel *chan, const char *fn)
-{
- int d;
- d = ast_streamfile(chan, fn, chan->language);
- if (d)
- return d;
- d = ast_waitstream(chan, AST_DIGIT_ANY);
- ast_stopstream(chan);
- return d;
-}
-
-static int global_silence_threshold = 128;
-static int global_maxsilence = 0;
-
-/*! Optionally play a sound file or a beep, then record audio and video from the channel.
- * @param chan Channel to playback to/record from.
- * @param playfile Filename of sound to play before recording begins.
- * @param recordfile Filename to record to.
- * @param maxtime Maximum length of recording (in milliseconds).
- * @param fmt Format(s) to record message in. Multiple formats may be specified by separating them with a '|'.
- * @param duration Where to store actual length of the recorded message (in milliseconds).
- * @param beep Whether to play a beep before starting to record.
- * @param silencethreshold
- * @param maxsilence Length of silence that will end a recording (in milliseconds).
- * @param path Optional filesystem path to unlock.
- * @param prepend If true, prepend the recorded audio to an existing file.
- * @param acceptdtmf DTMF digits that will end the recording.
- * @param canceldtmf DTMF digits that will cancel the recording.
- */
-
-static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf)
-{
- int d = 0;
- char *fmts;
- char comment[256];
- int x, fmtcnt = 1, res = -1, outmsg = 0;
- struct ast_filestream *others[MAX_OTHER_FORMATS];
- char *sfmt[MAX_OTHER_FORMATS];
- char *stringp = NULL;
- time_t start, end;
- struct ast_dsp *sildet = NULL; /* silence detector dsp */
- int totalsilence = 0;
- int rfmt = 0;
- struct ast_silence_generator *silgen = NULL;
- char prependfile[80];
-
- if (silencethreshold < 0)
- silencethreshold = global_silence_threshold;
-
- if (maxsilence < 0)
- maxsilence = global_maxsilence;
-
- /* barf if no pointer passed to store duration in */
- if (duration == NULL) {
- ast_log(LOG_WARNING, "Error play_and_record called without duration pointer\n");
- return -1;
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
- snprintf(comment, sizeof(comment), "Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);
-
- if (playfile || beep) {
- if (!beep)
- d = ast_play_and_wait(chan, playfile);
- if (d > -1)
- d = ast_stream_and_wait(chan, "beep", chan->language, "");
- if (d < 0)
- return -1;
- }
-
- if (prepend) {
- ast_copy_string(prependfile, recordfile, sizeof(prependfile));
- strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
- }
-
- fmts = ast_strdupa(fmt);
-
- stringp = fmts;
- strsep(&stringp, "|");
- if (option_debug)
- ast_log(LOG_DEBUG, "Recording Formats: sfmts=%s\n", fmts);
- sfmt[0] = ast_strdupa(fmts);
-
- while ((fmt = strsep(&stringp, "|"))) {
- if (fmtcnt > MAX_OTHER_FORMATS - 1) {
- ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n");
- break;
- }
- sfmt[fmtcnt++] = ast_strdupa(fmt);
- }
-
- end = start = time(NULL); /* pre-initialize end to be same as start in case we never get into loop */
- for (x = 0; x < fmtcnt; x++) {
- others[x] = ast_writefile(prepend ? prependfile : recordfile, sfmt[x], comment, O_TRUNC, 0, 0777);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]);
-
- if (!others[x])
- break;
- }
-
- if (path)
- ast_unlock_path(path);
-
- if (maxsilence > 0) {
- sildet = ast_dsp_new(); /* Create the silence detector */
- if (!sildet) {
- ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
- return -1;
- }
- ast_dsp_set_threshold(sildet, silencethreshold);
- rfmt = chan->readformat;
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
- ast_dsp_free(sildet);
- return -1;
- }
- }
-
- if (!prepend) {
- /* Request a video update */
- ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-
- if (ast_opt_transmit_silence)
- silgen = ast_channel_start_silence_generator(chan);
- }
-
- if (x == fmtcnt) {
- /* Loop forever, writing the packets we read to the writer(s), until
- we read a digit or get a hangup */
- struct ast_frame *f;
- for (;;) {
- res = ast_waitfor(chan, 2000);
- if (!res) {
- if (option_debug)
- ast_log(LOG_DEBUG, "One waitfor failed, trying another\n");
- /* Try one more time in case of masq */
- res = ast_waitfor(chan, 2000);
- if (!res) {
- ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
- res = -1;
- }
- }
-
- if (res < 0) {
- f = NULL;
- break;
- }
- f = ast_read(chan);
- if (!f)
- break;
- if (f->frametype == AST_FRAME_VOICE) {
- /* write each format */
- for (x = 0; x < fmtcnt; x++) {
- if (prepend && !others[x])
- break;
- res = ast_writestream(others[x], f);
- }
-
- /* Silence Detection */
- if (maxsilence > 0) {
- int dspsilence = 0;
- ast_dsp_silence(sildet, f, &dspsilence);
- if (dspsilence)
- totalsilence = dspsilence;
- else
- totalsilence = 0;
-
- if (totalsilence > maxsilence) {
- /* Ended happily with silence */
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
- res = 'S';
- outmsg = 2;
- break;
- }
- }
- /* Exit on any error */
- if (res) {
- ast_log(LOG_WARNING, "Error writing frame\n");
- break;
- }
- } else if (f->frametype == AST_FRAME_VIDEO) {
- /* Write only once */
- ast_writestream(others[0], f);
- } else if (f->frametype == AST_FRAME_DTMF) {
- if (prepend) {
- /* stop recording with any digit */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
- res = 't';
- outmsg = 2;
- break;
- }
- if (strchr(acceptdtmf, f->subclass)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
- res = f->subclass;
- outmsg = 2;
- break;
- }
- if (strchr(canceldtmf, f->subclass)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User cancelled message by pressing %c\n", f->subclass);
- res = f->subclass;
- outmsg = 0;
- break;
- }
- }
- if (maxtime) {
- end = time(NULL);
- if (maxtime < (end - start)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
- res = 't';
- outmsg = 2;
- break;
- }
- }
- ast_frfree(f);
- }
- if (!f) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User hung up\n");
- res = -1;
- outmsg = 1;
- } else {
- ast_frfree(f);
- }
- } else {
- ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]);
- }
-
- if (!prepend) {
- if (silgen)
- ast_channel_stop_silence_generator(chan, silgen);
- }
-
- /*!\note
- * Instead of asking how much time passed (end - start), calculate the number
- * of seconds of audio which actually went into the file. This fixes a
- * problem where audio is stopped up on the network and never gets to us.
- *
- * Note that we still want to use the number of seconds passed for the max
- * message, otherwise we could get a situation where this stream is never
- * closed (which would create a resource leak).
- */
- *duration = others[0] ? ast_tellstream(others[0]) / 8000 : 0;
-
- if (!prepend) {
- for (x = 0; x < fmtcnt; x++) {
- if (!others[x])
- break;
- /*!\note
- * If we ended with silence, trim all but the first 200ms of silence
- * off the recording. However, if we ended with '#', we don't want
- * to trim ANY part of the recording.
- */
- if (res > 0 && totalsilence)
- ast_stream_rewind(others[x], totalsilence - 200);
- ast_truncstream(others[x]);
- ast_closestream(others[x]);
- }
- }
-
- if (prepend && outmsg) {
- struct ast_filestream *realfiles[MAX_OTHER_FORMATS];
- struct ast_frame *fr;
-
- for (x = 0; x < fmtcnt; x++) {
- snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
- realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
- if (!others[x] || !realfiles[x])
- break;
- /*!\note Same logic as above. */
- if (totalsilence)
- ast_stream_rewind(others[x], totalsilence - 200);
- ast_truncstream(others[x]);
- /* add the original file too */
- while ((fr = ast_readframe(realfiles[x]))) {
- ast_writestream(others[x], fr);
- ast_frfree(fr);
- }
- ast_closestream(others[x]);
- ast_closestream(realfiles[x]);
- ast_filerename(prependfile, recordfile, sfmt[x]);
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile);
- ast_filedelete(prependfile, sfmt[x]);
- }
- }
- if (rfmt && ast_set_read_format(chan, rfmt)) {
- ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
- }
- if (outmsg == 2) {
- ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
- }
- if (sildet)
- ast_dsp_free(sildet);
- return res;
-}
-
-static char default_acceptdtmf[] = "#";
-static char default_canceldtmf[] = "";
-
-int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf)
-{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf));
-}
-
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path)
-{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf);
-}
-
-int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence)
-{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf);
-}
-
-/* Channel group core functions */
-
-int ast_app_group_split_group(const char *data, char *group, int group_max, char *category, int category_max)
-{
- int res=0;
- char tmp[256];
- char *grp=NULL, *cat=NULL;
-
- if (!ast_strlen_zero(data)) {
- ast_copy_string(tmp, data, sizeof(tmp));
- grp = tmp;
- cat = strchr(tmp, '@');
- if (cat) {
- *cat = '\0';
- cat++;
- }
- }
-
- if (!ast_strlen_zero(grp))
- ast_copy_string(group, grp, group_max);
- else
- *group = '\0';
-
- if (!ast_strlen_zero(cat))
- ast_copy_string(category, cat, category_max);
-
- return res;
-}
-
-int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
-{
- int res = 0;
- char group[80] = "", category[80] = "";
- struct ast_group_info *gi = NULL;
- size_t len = 0;
-
- if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category)))
- return -1;
-
- /* Calculate memory we will need if this is new */
- len = sizeof(*gi) + strlen(group) + 1;
- if (!ast_strlen_zero(category))
- len += strlen(category) + 1;
-
- AST_LIST_LOCK(&groups);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) {
- if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
- AST_LIST_REMOVE_CURRENT(&groups, list);
- free(gi);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- if (ast_strlen_zero(group)) {
- /* Enable unsetting the group */
- } else if ((gi = calloc(1, len))) {
- gi->chan = chan;
- gi->group = (char *) gi + sizeof(*gi);
- strcpy(gi->group, group);
- if (!ast_strlen_zero(category)) {
- gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1;
- strcpy(gi->category, category);
- }
- AST_LIST_INSERT_TAIL(&groups, gi, list);
- } else {
- res = -1;
- }
-
- AST_LIST_UNLOCK(&groups);
-
- return res;
-}
-
-int ast_app_group_get_count(const char *group, const char *category)
-{
- struct ast_group_info *gi = NULL;
- int count = 0;
-
- if (ast_strlen_zero(group))
- return 0;
-
- AST_LIST_LOCK(&groups);
- AST_LIST_TRAVERSE(&groups, gi, list) {
- if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category))))
- count++;
- }
- AST_LIST_UNLOCK(&groups);
-
- return count;
-}
-
-int ast_app_group_match_get_count(const char *groupmatch, const char *category)
-{
- struct ast_group_info *gi = NULL;
- regex_t regexbuf;
- int count = 0;
-
- if (ast_strlen_zero(groupmatch))
- return 0;
-
- /* if regex compilation fails, return zero matches */
- if (regcomp(&regexbuf, groupmatch, REG_EXTENDED | REG_NOSUB))
- return 0;
-
- AST_LIST_LOCK(&groups);
- AST_LIST_TRAVERSE(&groups, gi, list) {
- if (!regexec(&regexbuf, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category))))
- count++;
- }
- AST_LIST_UNLOCK(&groups);
-
- regfree(&regexbuf);
-
- return count;
-}
-
-int ast_app_group_update(struct ast_channel *old, struct ast_channel *new)
-{
- struct ast_group_info *gi = NULL;
-
- AST_LIST_LOCK(&groups);
- AST_LIST_TRAVERSE(&groups, gi, list) {
- if (gi->chan == old)
- gi->chan = new;
- }
- AST_LIST_UNLOCK(&groups);
-
- return 0;
-}
-
-int ast_app_group_discard(struct ast_channel *chan)
-{
- struct ast_group_info *gi = NULL;
-
- AST_LIST_LOCK(&groups);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) {
- if (gi->chan == chan) {
- AST_LIST_REMOVE_CURRENT(&groups, list);
- free(gi);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&groups);
-
- return 0;
-}
-
-int ast_app_group_list_lock(void)
-{
- return AST_LIST_LOCK(&groups);
-}
-
-struct ast_group_info *ast_app_group_list_head(void)
-{
- return AST_LIST_FIRST(&groups);
-}
-
-int ast_app_group_list_unlock(void)
-{
- return AST_LIST_UNLOCK(&groups);
-}
-
-unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
-{
- int argc;
- char *scan;
- int paren = 0, quote = 0;
-
- if (!buf || !array || !arraylen)
- return 0;
-
- memset(array, 0, arraylen * sizeof(*array));
-
- scan = buf;
-
- for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
- array[argc] = scan;
- for (; *scan; scan++) {
- if (*scan == '(')
- paren++;
- else if (*scan == ')') {
- if (paren)
- paren--;
- } else if (*scan == '"' && delim != '"') {
- quote = quote ? 0 : 1;
- /* Remove quote character from argument */
- memmove(scan, scan + 1, strlen(scan));
- scan--;
- } else if (*scan == '\\') {
- /* Literal character, don't parse */
- memmove(scan, scan + 1, strlen(scan));
- } else if ((*scan == delim) && !paren && !quote) {
- *scan++ = '\0';
- break;
- }
- }
- }
-
- if (*scan)
- array[argc++] = scan;
-
- return argc;
-}
-
-enum AST_LOCK_RESULT ast_lock_path(const char *path)
-{
- char *s;
- char *fs;
- int res;
- int fd;
- int lp = strlen(path);
- time_t start;
-
- if (!(s = alloca(lp + 10)) || !(fs = alloca(lp + 20))) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- return AST_LOCK_FAILURE;
- }
-
- snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, ast_random());
- fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600);
- if (fd < 0) {
- ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno));
- return AST_LOCK_PATH_NOT_FOUND;
- }
- close(fd);
-
- snprintf(s, strlen(path) + 9, "%s/.lock", path);
- start = time(NULL);
- while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5))
- usleep(1);
-
- unlink(fs);
-
- if (res) {
- ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
- return AST_LOCK_TIMEOUT;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Locked path '%s'\n", path);
- return AST_LOCK_SUCCESS;
- }
-}
-
-int ast_unlock_path(const char *path)
-{
- char *s;
- int res;
-
- if (!(s = alloca(strlen(path) + 10))) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- return -1;
- }
-
- snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
-
- if ((res = unlink(s)))
- ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno));
- else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path);
- }
-
- return res;
-}
-
-int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
-{
- int silencethreshold = 128;
- int maxsilence=0;
- int res = 0;
- int cmd = 0;
- int max_attempts = 3;
- int attempts = 0;
- int recorded = 0;
- int message_exists = 0;
- /* Note that urgent and private are for flagging messages as such in the future */
-
- /* barf if no pointer passed to store duration in */
- if (duration == NULL) {
- ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n");
- return -1;
- }
-
- cmd = '3'; /* Want to start by recording */
-
- while ((cmd >= 0) && (cmd != 't')) {
- switch (cmd) {
- case '1':
- if (!message_exists) {
- /* In this case, 1 is to record a message */
- cmd = '3';
- break;
- } else {
- ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
- cmd = 't';
- return res;
- }
- case '2':
- /* Review */
- ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n");
- cmd = ast_stream_and_wait(chan, recordfile, chan->language, AST_DIGIT_ANY);
- break;
- case '3':
- message_exists = 0;
- /* Record */
- if (recorded == 1)
- ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n");
- else
- ast_verbose(VERBOSE_PREFIX_3 "Recording\n");
- recorded = 1;
- cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path);
- if (cmd == -1) {
- /* User has hung up, no options to give */
- return cmd;
- }
- if (cmd == '0') {
- break;
- } else if (cmd == '*') {
- break;
- }
- else {
- /* If all is well, a message exists */
- message_exists = 1;
- cmd = 0;
- }
- break;
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '*':
- case '#':
- cmd = ast_play_and_wait(chan, "vm-sorry");
- break;
- default:
- if (message_exists) {
- cmd = ast_play_and_wait(chan, "vm-review");
- }
- else {
- cmd = ast_play_and_wait(chan, "vm-torerecord");
- if (!cmd)
- cmd = ast_waitfordigit(chan, 600);
- }
-
- if (!cmd)
- cmd = ast_waitfordigit(chan, 6000);
- if (!cmd) {
- attempts++;
- }
- if (attempts > max_attempts) {
- cmd = 't';
- }
- }
- }
- if (cmd == 't')
- cmd = 0;
- return cmd;
-}
-
-#define RES_UPONE (1 << 16)
-#define RES_EXIT (1 << 17)
-#define RES_REPEAT (1 << 18)
-#define RES_RESTART ((1 << 19) | RES_REPEAT)
-
-static int ast_ivr_menu_run_internal(struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata);
-
-static int ivr_dispatch(struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata)
-{
- int res;
- int (*ivr_func)(struct ast_channel *, void *);
- char *c;
- char *n;
-
- switch(option->action) {
- case AST_ACTION_UPONE:
- return RES_UPONE;
- case AST_ACTION_EXIT:
- return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff);
- case AST_ACTION_REPEAT:
- return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff);
- case AST_ACTION_RESTART:
- return RES_RESTART ;
- case AST_ACTION_NOOP:
- return 0;
- case AST_ACTION_BACKGROUND:
- res = ast_stream_and_wait(chan, (char *)option->adata, chan->language, AST_DIGIT_ANY);
- if (res < 0) {
- ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
- res = 0;
- }
- return res;
- case AST_ACTION_PLAYBACK:
- res = ast_stream_and_wait(chan, (char *)option->adata, chan->language, "");
- if (res < 0) {
- ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
- res = 0;
- }
- return res;
- case AST_ACTION_MENU:
- res = ast_ivr_menu_run_internal(chan, (struct ast_ivr_menu *)option->adata, cbdata);
- /* Do not pass entry errors back up, treaat ast though ti was an "UPONE" */
- if (res == -2)
- res = 0;
- return res;
- case AST_ACTION_WAITOPTION:
- res = ast_waitfordigit(chan, 1000 * (chan->pbx ? chan->pbx->rtimeout : 10));
- if (!res)
- return 't';
- return res;
- case AST_ACTION_CALLBACK:
- ivr_func = option->adata;
- res = ivr_func(chan, cbdata);
- return res;
- case AST_ACTION_TRANSFER:
- res = ast_parseable_goto(chan, option->adata);
- return 0;
- case AST_ACTION_PLAYLIST:
- case AST_ACTION_BACKLIST:
- res = 0;
- c = ast_strdupa(option->adata);
- while ((n = strsep(&c, ";"))) {
- if ((res = ast_stream_and_wait(chan, n, chan->language,
- (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : "")))
- break;
- }
- ast_stopstream(chan);
- return res;
- default:
- ast_log(LOG_NOTICE, "Unknown dispatch function %d, ignoring!\n", option->action);
- return 0;
- };
- return -1;
-}
-
-static int option_exists(struct ast_ivr_menu *menu, char *option)
-{
- int x;
- for (x = 0; menu->options[x].option; x++)
- if (!strcasecmp(menu->options[x].option, option))
- return x;
- return -1;
-}
-
-static int option_matchmore(struct ast_ivr_menu *menu, char *option)
-{
- int x;
- for (x = 0; menu->options[x].option; x++)
- if ((!strncasecmp(menu->options[x].option, option, strlen(option))) &&
- (menu->options[x].option[strlen(option)]))
- return x;
- return -1;
-}
-
-static int read_newoption(struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten)
-{
- int res=0;
- int ms;
- while (option_matchmore(menu, exten)) {
- ms = chan->pbx ? chan->pbx->dtimeout : 5000;
- if (strlen(exten) >= maxexten - 1)
- break;
- res = ast_waitfordigit(chan, ms);
- if (res < 1)
- break;
- exten[strlen(exten) + 1] = '\0';
- exten[strlen(exten)] = res;
- }
- return res > 0 ? 0 : res;
-}
-
-static int ast_ivr_menu_run_internal(struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
-{
- /* Execute an IVR menu structure */
- int res=0;
- int pos = 0;
- int retries = 0;
- char exten[AST_MAX_EXTENSION] = "s";
- if (option_exists(menu, "s") < 0) {
- strcpy(exten, "g");
- if (option_exists(menu, "g") < 0) {
- ast_log(LOG_WARNING, "No 's' nor 'g' extension in menu '%s'!\n", menu->title);
- return -1;
- }
- }
- while(!res) {
- while(menu->options[pos].option) {
- if (!strcasecmp(menu->options[pos].option, exten)) {
- res = ivr_dispatch(chan, menu->options + pos, exten, cbdata);
- if (option_debug)
- ast_log(LOG_DEBUG, "IVR Dispatch of '%s' (pos %d) yields %d\n", exten, pos, res);
- if (res < 0)
- break;
- else if (res & RES_UPONE)
- return 0;
- else if (res & RES_EXIT)
- return res;
- else if (res & RES_REPEAT) {
- int maxretries = res & 0xffff;
- if ((res & RES_RESTART) == RES_RESTART) {
- retries = 0;
- } else
- retries++;
- if (!maxretries)
- maxretries = 3;
- if ((maxretries > 0) && (retries >= maxretries)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Max retries %d exceeded\n", maxretries);
- return -2;
- } else {
- if (option_exists(menu, "g") > -1)
- strcpy(exten, "g");
- else if (option_exists(menu, "s") > -1)
- strcpy(exten, "s");
- }
- pos = 0;
- continue;
- } else if (res && strchr(AST_DIGIT_ANY, res)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Got start of extension, %c\n", res);
- exten[1] = '\0';
- exten[0] = res;
- if ((res = read_newoption(chan, menu, exten, sizeof(exten))))
- break;
- if (option_exists(menu, exten) < 0) {
- if (option_exists(menu, "i")) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Invalid extension entered, going to 'i'!\n");
- strcpy(exten, "i");
- pos = 0;
- continue;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Aborting on invalid entry, with no 'i' option!\n");
- res = -2;
- break;
- }
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "New existing extension: %s\n", exten);
- pos = 0;
- continue;
- }
- }
- }
- pos++;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Stopping option '%s', res is %d\n", exten, res);
- pos = 0;
- if (!strcasecmp(exten, "s"))
- strcpy(exten, "g");
- else
- break;
- }
- return res;
-}
-
-int ast_ivr_menu_run(struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
-{
- int res = ast_ivr_menu_run_internal(chan, menu, cbdata);
- /* Hide internal coding */
- return res > 0 ? 0 : res;
-}
-
-char *ast_read_textfile(const char *filename)
-{
- int fd;
- char *output = NULL;
- struct stat filesize;
- int count = 0;
- int res;
- if (stat(filename, &filesize) == -1) {
- ast_log(LOG_WARNING, "Error can't stat %s\n", filename);
- return NULL;
- }
- count = filesize.st_size + 1;
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno));
- return NULL;
- }
- if ((output = ast_malloc(count))) {
- res = read(fd, output, count - 1);
- if (res == count - 1) {
- output[res] = '\0';
- } else {
- ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno));
- free(output);
- output = NULL;
- }
- }
- close(fd);
- return output;
-}
-
-int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
-{
- char *s;
- int curarg;
- unsigned int argloc;
- char *arg;
- int res = 0;
-
- ast_clear_flag(flags, AST_FLAGS_ALL);
-
- if (!optstr)
- return 0;
-
- s = optstr;
- while (*s) {
- curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */
- argloc = options[curarg].arg_index;
- if (*s == '(') {
- /* Has argument */
- arg = ++s;
- if ((s = strchr(s, ')'))) {
- if (argloc)
- args[argloc - 1] = arg;
- *s++ = '\0';
- } else {
- ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg);
- res = -1;
- break;
- }
- } else if (argloc) {
- args[argloc - 1] = "";
- }
- ast_set_flag(flags, options[curarg].flag);
- }
-
- return res;
-}
-
diff --git a/1.4/main/ast_expr2.c b/1.4/main/ast_expr2.c
deleted file mode 100644
index 4acd56d54..000000000
--- a/1.4/main/ast_expr2.c
+++ /dev/null
@@ -1,2859 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.1a. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Bison version. */
-#define YYBISON_VERSION "2.1a"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 1
-
-/* Using locations. */
-#define YYLSP_NEEDED 1
-
-/* Substitute the variable and function names. */
-#define yyparse ast_yyparse
-#define yylex ast_yylex
-#define yyerror ast_yyerror
-#define yylval ast_yylval
-#define yychar ast_yychar
-#define yydebug ast_yydebug
-#define yynerrs ast_yynerrs
-#define yylloc ast_yylloc
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- TOK_COLONCOLON = 258,
- TOK_COND = 259,
- TOK_OR = 260,
- TOK_AND = 261,
- TOK_NE = 262,
- TOK_LE = 263,
- TOK_GE = 264,
- TOK_LT = 265,
- TOK_GT = 266,
- TOK_EQ = 267,
- TOK_MINUS = 268,
- TOK_PLUS = 269,
- TOK_MOD = 270,
- TOK_DIV = 271,
- TOK_MULT = 272,
- TOK_COMPL = 273,
- TOK_EQTILDE = 274,
- TOK_COLON = 275,
- TOK_LP = 276,
- TOK_RP = 277,
- TOKEN = 278
- };
-#endif
-/* Tokens. */
-#define TOK_COLONCOLON 258
-#define TOK_COND 259
-#define TOK_OR 260
-#define TOK_AND 261
-#define TOK_NE 262
-#define TOK_LE 263
-#define TOK_GE 264
-#define TOK_LT 265
-#define TOK_GT 266
-#define TOK_EQ 267
-#define TOK_MINUS 268
-#define TOK_PLUS 269
-#define TOK_MOD 270
-#define TOK_DIV 271
-#define TOK_MULT 272
-#define TOK_COMPL 273
-#define TOK_EQTILDE 274
-#define TOK_COLON 275
-#define TOK_LP 276
-#define TOK_RP 277
-#define TOKEN 278
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 1 "ast_expr2.y"
-
-/* Written by Pace Willisson (pace@blitz.com)
- * and placed in the public domain.
- *
- * Largely rewritten by J.T. Conklin (jtc@wimsey.com)
- *
- * And then overhauled twice by Steve Murphy (murf@digium.com)
- * to add double-quoted strings, allow mult. spaces, improve
- * error messages, and then to fold in a flex scanner for the
- * yylex operation.
- *
- * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
- */
-
-#include "asterisk.h"
-
-#ifndef STANDALONE
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-#include <unistd.h>
-#include <ctype.h>
-#if !defined(SOLARIS) && !defined(__CYGWIN__)
-/* #include <err.h> */
-#else
-#define quad_t int64_t
-#endif
-#include <errno.h>
-#include <regex.h>
-#include <limits.h>
-
-#include "asterisk/ast_expr.h"
-#include "asterisk/logger.h"
-
-#if defined(LONG_LONG_MIN) && !defined(QUAD_MIN)
-#define QUAD_MIN LONG_LONG_MIN
-#endif
-#if defined(LONG_LONG_MAX) && !defined(QUAD_MAX)
-#define QUAD_MAX LONG_LONG_MAX
-#endif
-
-# if ! defined(QUAD_MIN)
-# define QUAD_MIN (-0x7fffffffffffffffLL-1)
-# endif
-# if ! defined(QUAD_MAX)
-# define QUAD_MAX (0x7fffffffffffffffLL)
-# endif
-
-#define YYPARSE_PARAM parseio
-#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
-#define YYERROR_VERBOSE 1
-extern char extra_error_message[4095];
-extern int extra_error_message_supplied;
-
-enum valtype {
- AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
-} ;
-
-#ifdef STANDALONE
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
-#endif
-
-struct val {
- enum valtype type;
- union {
- char *s;
- quad_t i;
- } u;
-} ;
-
-typedef void *yyscan_t;
-
-struct parse_io
-{
- char *string;
- struct val *val;
- yyscan_t scanner;
-};
-
-static int chk_div __P((quad_t, quad_t));
-static int chk_minus __P((quad_t, quad_t, quad_t));
-static int chk_plus __P((quad_t, quad_t, quad_t));
-static int chk_times __P((quad_t, quad_t, quad_t));
-static void free_value __P((struct val *));
-static int is_zero_or_null __P((struct val *));
-static int isstring __P((struct val *));
-static struct val *make_integer __P((quad_t));
-static struct val *make_str __P((const char *));
-static struct val *op_and __P((struct val *, struct val *));
-static struct val *op_colon __P((struct val *, struct val *));
-static struct val *op_eqtilde __P((struct val *, struct val *));
-static struct val *op_div __P((struct val *, struct val *));
-static struct val *op_eq __P((struct val *, struct val *));
-static struct val *op_ge __P((struct val *, struct val *));
-static struct val *op_gt __P((struct val *, struct val *));
-static struct val *op_le __P((struct val *, struct val *));
-static struct val *op_lt __P((struct val *, struct val *));
-static struct val *op_cond __P((struct val *, struct val *, struct val *));
-static struct val *op_minus __P((struct val *, struct val *));
-static struct val *op_negate __P((struct val *));
-static struct val *op_compl __P((struct val *));
-static struct val *op_ne __P((struct val *, struct val *));
-static struct val *op_or __P((struct val *, struct val *));
-static struct val *op_plus __P((struct val *, struct val *));
-static struct val *op_rem __P((struct val *, struct val *));
-static struct val *op_times __P((struct val *, struct val *));
-static quad_t to_integer __P((struct val *));
-static void to_string __P((struct val *));
-
-/* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
-typedef struct yyltype
-{
- int first_line;
- int first_column;
-
- int last_line;
- int last_column;
-} yyltype;
-
-# define YYLTYPE yyltype
-# define YYLTYPE_IS_TRIVIAL 1
-
-/* we will get warning about no prototype for yylex! But we can't
- define it here, we have no definition yet for YYSTYPE. */
-
-int ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
-
-/* I wanted to add args to the yyerror routine, so I could print out
- some useful info about the error. Not as easy as it looks, but it
- is possible. */
-#define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
-#define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
-
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 147 "ast_expr2.y"
-{
- struct val *val;
-}
-/* Line 198 of yacc.c. */
-#line 283 "ast_expr2.c"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-/* Copy the second part of user declarations. */
-#line 151 "ast_expr2.y"
-
-extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
-
-
-/* Line 221 of yacc.c. */
-#line 311 "ast_expr2.c"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int i)
-#else
-static int
-YYID (i)
- int i;
-#endif
-{
- return i;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# ifdef __cplusplus
-extern "C" {
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifdef __cplusplus
-}
-# endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yytype_int16 yyss;
- YYSTYPE yyvs;
- YYLTYPE yyls;
-};
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 10
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 140
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 24
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 3
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 23
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 46
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 278
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const yytype_uint8 yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint8 yyprhs[] =
-{
- 0, 0, 3, 5, 6, 8, 12, 16, 20, 24,
- 28, 32, 36, 40, 44, 48, 52, 55, 58, 62,
- 66, 70, 74, 78
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 25, 0, -1, 26, -1, -1, 23, -1, 21, 26,
- 22, -1, 26, 5, 26, -1, 26, 6, 26, -1,
- 26, 12, 26, -1, 26, 11, 26, -1, 26, 10,
- 26, -1, 26, 9, 26, -1, 26, 8, 26, -1,
- 26, 7, 26, -1, 26, 14, 26, -1, 26, 13,
- 26, -1, 13, 26, -1, 18, 26, -1, 26, 17,
- 26, -1, 26, 16, 26, -1, 26, 15, 26, -1,
- 26, 20, 26, -1, 26, 19, 26, -1, 26, 4,
- 26, 3, 26, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint16 yyrline[] =
-{
- 0, 175, 175, 183, 190, 191, 195, 199, 203, 207,
- 211, 215, 219, 223, 227, 231, 235, 239, 243, 247,
- 251, 255, 259, 263
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "TOK_COLONCOLON", "TOK_COND", "TOK_OR",
- "TOK_AND", "TOK_NE", "TOK_LE", "TOK_GE", "TOK_LT", "TOK_GT", "TOK_EQ",
- "TOK_MINUS", "TOK_PLUS", "TOK_MOD", "TOK_DIV", "TOK_MULT", "TOK_COMPL",
- "TOK_EQTILDE", "TOK_COLON", "TOK_LP", "TOK_RP", "TOKEN", "$accept",
- "start", "expr", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const yytype_uint16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 24, 25, 25, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 1, 0, 1, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 2, 2, 3, 3,
- 3, 3, 3, 5
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
- 3, 0, 0, 0, 4, 0, 2, 16, 17, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 5, 0, 6,
- 7, 13, 12, 11, 10, 9, 8, 15, 14, 20,
- 19, 18, 22, 21, 0, 23
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] =
-{
- -1, 5, 6
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -13
-static const yytype_int8 yypact[] =
-{
- 109, 109, 109, 109, -13, 6, 59, 106, 106, 22,
- -13, 109, 109, 109, 109, 109, 109, 109, 109, 109,
- 109, 109, 109, 109, 109, 109, 109, -13, 42, 90,
- 104, 120, 120, 120, 120, 120, 120, -12, -12, 106,
- 106, 106, -13, -13, 109, 75
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int8 yypgoto[] =
-{
- -13, -13, -1
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -1
-static const yytype_uint8 yytable[] =
-{
- 7, 8, 9, 22, 23, 24, 10, 25, 26, 0,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 42, 43, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 0, 25, 26, 45, 27, 44, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 0, 25, 26, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 0, 25, 26,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 0, 25, 26, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 0, 25,
- 26, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 1, 25, 26, 25, 26, 2, 0, 0,
- 3, 0, 4, 20, 21, 22, 23, 24, 0, 25,
- 26
-};
-
-static const yytype_int8 yycheck[] =
-{
- 1, 2, 3, 15, 16, 17, 0, 19, 20, -1,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- -1, 19, 20, 44, 22, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- -1, 19, 20, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, -1, 19, 20,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, -1, 19, 20, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, -1, 19,
- 20, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 13, 19, 20, 19, 20, 18, -1, -1,
- 21, -1, 23, 13, 14, 15, 16, 17, -1, 19,
- 20
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
-{
- 0, 13, 18, 21, 23, 25, 26, 26, 26, 26,
- 0, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 19, 20, 22, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 3, 26
-};
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (0))
-
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval, &yylloc)
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value, Location); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
- FILE *yyoutput;
- int yytype;
- const YYSTYPE * const yyvaluep;
- const YYLTYPE * const yylocationp;
-#endif
-{
- if (!yyvaluep)
- return;
- YYUSE (yylocationp);
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
-# endif
- switch (yytype)
- {
- default:
- break;
- }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
- FILE *yyoutput;
- int yytype;
- const YYSTYPE * const yyvaluep;
- const YYLTYPE * const yylocationp;
-#endif
-{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- YY_LOCATION_PRINT (yyoutput, *yylocationp);
- YYFPRINTF (yyoutput, ": ");
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
- YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
-#else
-static void
-yy_stack_print (bottom, top)
- yytype_int16 *bottom;
- yytype_int16 *top;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yylsp, yyrule
- )
- YYSTYPE *yyvsp;
- YYLTYPE *yylsp;
- int yyrule;
-#endif
-{
- int yynrhs = yyr2[yyrule];
- int yyi;
- unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- fprintf (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- , &(yylsp[(yyi + 1) - (yynrhs)]) );
- fprintf (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, yylsp, Rule); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- size_t yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
-
- if (! (YYPACT_NINF < yyn && yyn < YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
-
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
-
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
-
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
- }
-}
-#endif /* YYERROR_VERBOSE */
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, yylocationp)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
- YYLTYPE *yylocationp;
-#endif
-{
- YYUSE (yyvaluep);
- YYUSE (yylocationp);
-
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
- switch (yytype)
- {
- case 3: /* "TOK_COLONCOLON" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1257 "ast_expr2.c"
- break;
- case 4: /* "TOK_COND" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1262 "ast_expr2.c"
- break;
- case 5: /* "TOK_OR" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1267 "ast_expr2.c"
- break;
- case 6: /* "TOK_AND" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1272 "ast_expr2.c"
- break;
- case 7: /* "TOK_NE" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1277 "ast_expr2.c"
- break;
- case 8: /* "TOK_LE" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1282 "ast_expr2.c"
- break;
- case 9: /* "TOK_GE" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1287 "ast_expr2.c"
- break;
- case 10: /* "TOK_LT" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1292 "ast_expr2.c"
- break;
- case 11: /* "TOK_GT" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1297 "ast_expr2.c"
- break;
- case 12: /* "TOK_EQ" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1302 "ast_expr2.c"
- break;
- case 13: /* "TOK_MINUS" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1307 "ast_expr2.c"
- break;
- case 14: /* "TOK_PLUS" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1312 "ast_expr2.c"
- break;
- case 15: /* "TOK_MOD" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1317 "ast_expr2.c"
- break;
- case 16: /* "TOK_DIV" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1322 "ast_expr2.c"
- break;
- case 17: /* "TOK_MULT" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1327 "ast_expr2.c"
- break;
- case 18: /* "TOK_COMPL" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1332 "ast_expr2.c"
- break;
- case 19: /* "TOK_EQTILDE" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1337 "ast_expr2.c"
- break;
- case 20: /* "TOK_COLON" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1342 "ast_expr2.c"
- break;
- case 21: /* "TOK_LP" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1347 "ast_expr2.c"
- break;
- case 22: /* "TOK_RP" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1352 "ast_expr2.c"
- break;
- case 23: /* "TOKEN" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1357 "ast_expr2.c"
- break;
- case 26: /* "expr" */
-#line 169 "ast_expr2.y"
- { free_value((yyvaluep->val)); };
-#line 1362 "ast_expr2.c"
- break;
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
- /* The look-ahead symbol. */
-int yychar;
-
-/* The semantic value of the look-ahead symbol. */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far. */
-int yynerrs;
-/* Location data for the look-ahead symbol. */
-YYLTYPE yylloc;
-
- int yystate;
- int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Look-ahead token as an internal (translated) token number. */
- int yytoken = 0;
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss = yyssa;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- YYSTYPE *yyvsp;
-
- /* The location stack. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
- /* The locations where the error started and ended. */
- YYLTYPE yyerror_range[2];
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
- YYSIZE_T yystacksize = YYINITDEPTH;
-
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
- YYLTYPE yyloc;
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss;
- yyvsp = yyvs;
- yylsp = yyls;
-#if YYLTYPE_IS_TRIVIAL
- /* Initialize the default location before parsing starts. */
- yylloc.first_line = yylloc.last_line = 1;
- yylloc.first_column = yylloc.last_column = 0;
-#endif
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
- YYLTYPE *yyls1 = yyls;
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yyls1, yysize * sizeof (*yylsp),
- &yystacksize);
- yyls = yyls1;
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
- YYSTACK_RELOCATE (yyls);
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
- yylsp = yyls + yysize - 1;
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
- /* Do appropriate processing given the current state. Read a
- look-ahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to look-ahead token. */
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a look-ahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the look-ahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- yystate = yyn;
- *++yyvsp = yylval;
- *++yylsp = yylloc;
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
- /* Default location. */
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 2:
-#line 175 "ast_expr2.y"
- { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
- ((struct parse_io *)parseio)->val->type = (yyvsp[(1) - (1)].val)->type;
- if( (yyvsp[(1) - (1)].val)->type == AST_EXPR_integer )
- ((struct parse_io *)parseio)->val->u.i = (yyvsp[(1) - (1)].val)->u.i;
- else
- ((struct parse_io *)parseio)->val->u.s = (yyvsp[(1) - (1)].val)->u.s;
- free((yyvsp[(1) - (1)].val));
- ;}
- break;
-
- case 3:
-#line 183 "ast_expr2.y"
- {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
- ((struct parse_io *)parseio)->val->type = AST_EXPR_string;
- ((struct parse_io *)parseio)->val->u.s = strdup("");
- ;}
- break;
-
- case 4:
-#line 190 "ast_expr2.y"
- { (yyval.val)= (yyvsp[(1) - (1)].val);;}
- break;
-
- case 5:
-#line 191 "ast_expr2.y"
- { (yyval.val) = (yyvsp[(2) - (3)].val);
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;
- DESTROY((yyvsp[(1) - (3)].val)); DESTROY((yyvsp[(3) - (3)].val)); ;}
- break;
-
- case 6:
-#line 195 "ast_expr2.y"
- { (yyval.val) = op_or ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 7:
-#line 199 "ast_expr2.y"
- { (yyval.val) = op_and ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 8:
-#line 203 "ast_expr2.y"
- { (yyval.val) = op_eq ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 9:
-#line 207 "ast_expr2.y"
- { (yyval.val) = op_gt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 10:
-#line 211 "ast_expr2.y"
- { (yyval.val) = op_lt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 11:
-#line 215 "ast_expr2.y"
- { (yyval.val) = op_ge ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 12:
-#line 219 "ast_expr2.y"
- { (yyval.val) = op_le ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 13:
-#line 223 "ast_expr2.y"
- { (yyval.val) = op_ne ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 14:
-#line 227 "ast_expr2.y"
- { (yyval.val) = op_plus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 15:
-#line 231 "ast_expr2.y"
- { (yyval.val) = op_minus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 16:
-#line 235 "ast_expr2.y"
- { (yyval.val) = op_negate ((yyvsp[(2) - (2)].val));
- DESTROY((yyvsp[(1) - (2)].val));
- (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 17:
-#line 239 "ast_expr2.y"
- { (yyval.val) = op_compl ((yyvsp[(2) - (2)].val));
- DESTROY((yyvsp[(1) - (2)].val));
- (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 18:
-#line 243 "ast_expr2.y"
- { (yyval.val) = op_times ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 19:
-#line 247 "ast_expr2.y"
- { (yyval.val) = op_div ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 20:
-#line 251 "ast_expr2.y"
- { (yyval.val) = op_rem ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 21:
-#line 255 "ast_expr2.y"
- { (yyval.val) = op_colon ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 22:
-#line 259 "ast_expr2.y"
- { (yyval.val) = op_eqtilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
- DESTROY((yyvsp[(2) - (3)].val));
- (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
- case 23:
-#line 263 "ast_expr2.y"
- { (yyval.val) = op_cond ((yyvsp[(1) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(5) - (5)].val));
- DESTROY((yyvsp[(2) - (5)].val));
- DESTROY((yyvsp[(4) - (5)].val));
- (yyloc).first_column = (yylsp[(1) - (5)]).first_column; (yyloc).last_column = (yylsp[(3) - (5)]).last_column;
- (yyloc).first_line=0; (yyloc).last_line=0;;}
- break;
-
-
-/* Line 1270 of yacc.c. */
-#line 1864 "ast_expr2.c"
- default: break;
- }
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
- *++yylsp = yyloc;
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
-#else
- {
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
- }
-#endif
- }
-
- yyerror_range[0] = yylloc;
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse look-ahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval, &yylloc);
- yychar = YYEMPTY;
- }
- }
-
- /* Else will try to reuse look-ahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
-
- yyerror_range[0] = yylsp[1-yylen];
- /* Do not reclaim the symbols of the rule which action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
- yyerror_range[0] = *yylsp;
- yydestruct ("Error: popping",
- yystos[yystate], yyvsp, yylsp);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- *++yyvsp = yylval;
-
- yyerror_range[1] = yylloc;
- /* Using YYLLOC is tempting, but would change the location of
- the look-ahead. YYLOC is available though. */
- YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
- *++yylsp = yyloc;
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#ifndef yyoverflow
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
-yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
- if (yychar != YYEOF && yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval, &yylloc);
- /* Do not reclaim the symbols of the rule which action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp, yylsp);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
- return yyresult;
-}
-
-
-#line 270 "ast_expr2.y"
-
-
-static struct val *
-make_integer (quad_t i)
-{
- struct val *vp;
-
- vp = (struct val *) malloc (sizeof (*vp));
- if (vp == NULL) {
- ast_log(LOG_WARNING, "malloc() failed\n");
- return(NULL);
- }
-
- vp->type = AST_EXPR_integer;
- vp->u.i = i;
- return vp;
-}
-
-static struct val *
-make_str (const char *s)
-{
- struct val *vp;
- size_t i;
- int isint;
-
- vp = (struct val *) malloc (sizeof (*vp));
- if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
- ast_log(LOG_WARNING,"malloc() failed\n");
- return(NULL);
- }
-
- for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
- isint && i < strlen(s);
- i++)
- {
- if(!isdigit(s[i]))
- isint = 0;
- }
-
- if (isint)
- vp->type = AST_EXPR_numeric_string;
- else
- vp->type = AST_EXPR_string;
-
- return vp;
-}
-
-
-static void
-free_value (struct val *vp)
-{
- if (vp==NULL) {
- return;
- }
- if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
- free (vp->u.s);
- free(vp);
-}
-
-
-static quad_t
-to_integer (struct val *vp)
-{
- quad_t i;
-
- if (vp == NULL) {
- ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
- return(0);
- }
-
- if (vp->type == AST_EXPR_integer)
- return 1;
-
- if (vp->type == AST_EXPR_string)
- return 0;
-
- /* vp->type == AST_EXPR_numeric_string, make it numeric */
- errno = 0;
- i = strtoll(vp->u.s, (char**)NULL, 10);
- if (errno != 0) {
- ast_log(LOG_WARNING,"Conversion of %s to integer under/overflowed!\n", vp->u.s);
- free(vp->u.s);
- vp->u.s = 0;
- return(0);
- }
- free (vp->u.s);
- vp->u.i = i;
- vp->type = AST_EXPR_integer;
- return 1;
-}
-
-static void
-strip_quotes(struct val *vp)
-{
- if (vp->type != AST_EXPR_string && vp->type != AST_EXPR_numeric_string)
- return;
-
- if( vp->u.s[0] == '"' && vp->u.s[strlen(vp->u.s)-1] == '"' )
- {
- char *f, *t;
- f = vp->u.s;
- t = vp->u.s;
-
- while( *f )
- {
- if( *f && *f != '"' )
- *t++ = *f++;
- else
- f++;
- }
- *t = *f;
- }
-}
-
-static void
-to_string (struct val *vp)
-{
- char *tmp;
-
- if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
- return;
-
- tmp = malloc ((size_t)25);
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"malloc() failed\n");
- return;
- }
-
- sprintf(tmp, "%ld", (long int) vp->u.i);
- vp->type = AST_EXPR_string;
- vp->u.s = tmp;
-}
-
-
-static int
-isstring (struct val *vp)
-{
- /* only TRUE if this string is not a valid integer */
- return (vp->type == AST_EXPR_string);
-}
-
-
-static int
-is_zero_or_null (struct val *vp)
-{
- if (vp->type == AST_EXPR_integer) {
- return (vp->u.i == 0);
- } else {
- return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
- }
- /* NOTREACHED */
-}
-
-#ifdef STANDALONE
-
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
-{
- va_list vars;
- va_start(vars,fmt);
-
- printf("LOG: lev:%d file:%s line:%d func: %s ",
- level, file, line, function);
- vprintf(fmt, vars);
- fflush(stdout);
- va_end(vars);
-}
-
-
-int main(int argc,char **argv) {
- char s[4096];
- char out[4096];
- FILE *infile;
-
- if( !argv[1] )
- exit(20);
-
- if( access(argv[1],F_OK)== 0 )
- {
- int ret;
-
- infile = fopen(argv[1],"r");
- if( !infile )
- {
- printf("Sorry, couldn't open %s for reading!\n", argv[1]);
- exit(10);
- }
- while( fgets(s,sizeof(s),infile) )
- {
- if( s[strlen(s)-1] == '\n' )
- s[strlen(s)-1] = 0;
-
- ret = ast_expr(s, out, sizeof(out));
- printf("Expression: %s Result: [%d] '%s'\n",
- s, ret, out);
- }
- fclose(infile);
- }
- else
- {
- if (ast_expr(argv[1], s, sizeof(s)))
- printf("=====%s======\n",s);
- else
- printf("No result\n");
- }
-}
-
-#endif
-
-#undef ast_yyerror
-#define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parse_io *parseio)
-
-/* I put the ast_yyerror func in the flex input file,
- because it refers to the buffer state. Best to
- let it access the BUFFER stuff there and not trying
- define all the structs, macros etc. in this file! */
-
-
-static struct val *
-op_or (struct val *a, struct val *b)
-{
- if (is_zero_or_null (a)) {
- free_value (a);
- return (b);
- } else {
- free_value (b);
- return (a);
- }
-}
-
-static struct val *
-op_and (struct val *a, struct val *b)
-{
- if (is_zero_or_null (a) || is_zero_or_null (b)) {
- free_value (a);
- free_value (b);
- return (make_integer ((quad_t)0));
- } else {
- free_value (b);
- return (a);
- }
-}
-
-static struct val *
-op_eq (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
- } else {
-#ifdef DEBUG_FOR_CONVERSIONS
- char buffer[2000];
- sprintf(buffer,"Converting '%s' and '%s' ", a->u.s, b->u.s);
-#endif
- (void)to_integer(a);
- (void)to_integer(b);
-#ifdef DEBUG_FOR_CONVERSIONS
- ast_log(LOG_WARNING,"%s to '%lld' and '%lld'\n", buffer, a->u.i, b->u.i);
-#endif
- r = make_integer ((quad_t)(a->u.i == b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_gt (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i > b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_lt (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i < b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_ge (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i >= b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_le (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i <= b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_cond (struct val *a, struct val *b, struct val *c)
-{
- struct val *r;
-
- if( isstring(a) )
- {
- if( strlen(a->u.s) && strcmp(a->u.s, "\"\"") != 0 && strcmp(a->u.s,"0") != 0 )
- {
- free_value(a);
- free_value(c);
- r = b;
- }
- else
- {
- free_value(a);
- free_value(b);
- r = c;
- }
- }
- else
- {
- (void)to_integer(a);
- if( a->u.i )
- {
- free_value(a);
- free_value(c);
- r = b;
- }
- else
- {
- free_value(a);
- free_value(b);
- r = c;
- }
- }
- return r;
-}
-
-static struct val *
-op_ne (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i != b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static int
-chk_plus (quad_t a, quad_t b, quad_t r)
-{
- /* sum of two positive numbers must be positive */
- if (a > 0 && b > 0 && r <= 0)
- return 1;
- /* sum of two negative numbers must be negative */
- if (a < 0 && b < 0 && r >= 0)
- return 1;
- /* all other cases are OK */
- return 0;
-}
-
-static struct val *
-op_plus (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING,"non-numeric argument\n");
- if (!to_integer (b)) {
- free_value(a);
- free_value(b);
- return make_integer(0);
- } else {
- free_value(a);
- return (b);
- }
- } else if (!to_integer(b)) {
- free_value(b);
- return (a);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
- if (chk_plus (a->u.i, b->u.i, r->u.i)) {
- ast_log(LOG_WARNING,"overflow\n");
- }
- free_value (a);
- free_value (b);
- return r;
-}
-
-static int
-chk_minus (quad_t a, quad_t b, quad_t r)
-{
- /* special case subtraction of QUAD_MIN */
- if (b == QUAD_MIN) {
- if (a >= 0)
- return 1;
- else
- return 0;
- }
- /* this is allowed for b != QUAD_MIN */
- return chk_plus (a, -b, r);
-}
-
-static struct val *
-op_minus (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- if (!to_integer (b)) {
- free_value(a);
- free_value(b);
- return make_integer(0);
- } else {
- r = make_integer(0 - b->u.i);
- free_value(a);
- free_value(b);
- return (r);
- }
- } else if (!to_integer(b)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- free_value(b);
- return (a);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
- if (chk_minus (a->u.i, b->u.i, r->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_negate (struct val *a)
-{
- struct val *r;
-
- if (!to_integer (a) ) {
- free_value(a);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return make_integer(0);
- }
-
- r = make_integer (/*(quad_t)*/(- a->u.i));
- if (chk_minus (0, a->u.i, r->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- return r;
-}
-
-static struct val *
-op_compl (struct val *a)
-{
- int v1 = 1;
- struct val *r;
-
- if( !a )
- {
- v1 = 0;
- }
- else
- {
- switch( a->type )
- {
- case AST_EXPR_integer:
- if( a->u.i == 0 )
- v1 = 0;
- break;
-
- case AST_EXPR_string:
- if( a->u.s == 0 )
- v1 = 0;
- else
- {
- if( a->u.s[0] == 0 )
- v1 = 0;
- else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
- v1 = 0;
- }
- break;
-
- case AST_EXPR_numeric_string:
- if( a->u.s == 0 )
- v1 = 0;
- else
- {
- if( a->u.s[0] == 0 )
- v1 = 0;
- else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
- v1 = 0;
- }
- break;
- }
- }
-
- r = make_integer (!v1);
- free_value (a);
- return r;
-}
-
-static int
-chk_times (quad_t a, quad_t b, quad_t r)
-{
- /* special case: first operand is 0, no overflow possible */
- if (a == 0)
- return 0;
- /* cerify that result of division matches second operand */
- if (r / a != b)
- return 1;
- return 0;
-}
-
-static struct val *
-op_times (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a) || !to_integer (b)) {
- free_value(a);
- free_value(b);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return(make_integer(0));
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
- if (chk_times (a->u.i, b->u.i, r->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- free_value (b);
- return (r);
-}
-
-static int
-chk_div (quad_t a, quad_t b)
-{
- /* div by zero has been taken care of before */
- /* only QUAD_MIN / -1 causes overflow */
- if (a == QUAD_MIN && b == -1)
- return 1;
- /* everything else is OK */
- return 0;
-}
-
-static struct val *
-op_div (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a)) {
- free_value(a);
- free_value(b);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return make_integer(0);
- } else if (!to_integer (b)) {
- free_value(a);
- free_value(b);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return make_integer(INT_MAX);
- }
-
- if (b->u.i == 0) {
- ast_log(LOG_WARNING, "division by zero\n");
- free_value(a);
- free_value(b);
- return make_integer(INT_MAX);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
- if (chk_div (a->u.i, b->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_rem (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a) || !to_integer (b)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- free_value(a);
- free_value(b);
- return make_integer(0);
- }
-
- if (b->u.i == 0) {
- ast_log(LOG_WARNING, "div by zero\n");
- free_value(a);
- return(b);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
- /* chk_rem necessary ??? */
- free_value (a);
- free_value (b);
- return r;
-}
-
-
-static struct val *
-op_colon (struct val *a, struct val *b)
-{
- regex_t rp;
- regmatch_t rm[2];
- char errbuf[256];
- int eval;
- struct val *v;
-
- /* coerce to both arguments to strings */
- to_string(a);
- to_string(b);
- /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
- strip_quotes(a);
- strip_quotes(b);
- /* compile regular expression */
- if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
- regerror (eval, &rp, errbuf, sizeof(errbuf));
- ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
- free_value(a);
- free_value(b);
- return make_str("");
- }
-
- /* compare string against pattern */
- /* remember that patterns are anchored to the beginning of the line */
- if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
- if (rm[1].rm_so >= 0) {
- *(a->u.s + rm[1].rm_eo) = '\0';
- v = make_str (a->u.s + rm[1].rm_so);
-
- } else {
- v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
- }
- } else {
- if (rp.re_nsub == 0) {
- v = make_integer ((quad_t)0);
- } else {
- v = make_str ("");
- }
- }
-
- /* free arguments and pattern buffer */
- free_value (a);
- free_value (b);
- regfree (&rp);
-
- return v;
-}
-
-
-static struct val *
-op_eqtilde (struct val *a, struct val *b)
-{
- regex_t rp;
- regmatch_t rm[2];
- char errbuf[256];
- int eval;
- struct val *v;
-
- /* coerce to both arguments to strings */
- to_string(a);
- to_string(b);
- /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
- strip_quotes(a);
- strip_quotes(b);
- /* compile regular expression */
- if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
- regerror (eval, &rp, errbuf, sizeof(errbuf));
- ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
- free_value(a);
- free_value(b);
- return make_str("");
- }
-
- /* compare string against pattern */
- /* remember that patterns are anchored to the beginning of the line */
- if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 ) {
- if (rm[1].rm_so >= 0) {
- *(a->u.s + rm[1].rm_eo) = '\0';
- v = make_str (a->u.s + rm[1].rm_so);
-
- } else {
- v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
- }
- } else {
- if (rp.re_nsub == 0) {
- v = make_integer ((quad_t)0);
- } else {
- v = make_str ("");
- }
- }
-
- /* free arguments and pattern buffer */
- free_value (a);
- free_value (b);
- regfree (&rp);
-
- return v;
-}
-
diff --git a/1.4/main/ast_expr2.fl b/1.4/main/ast_expr2.fl
deleted file mode 100644
index 68db50428..000000000
--- a/1.4/main/ast_expr2.fl
+++ /dev/null
@@ -1,414 +0,0 @@
-%{
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Dialplan Expression Lexical Scanner
- */
-
-#include "asterisk.h"
-
-#ifndef STANDALONE
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-#include <ctype.h>
-#if !defined(SOLARIS) && !defined(__CYGWIN__)
-/* #include <err.h> */
-#else
-#define quad_t int64_t
-#endif
-#include <errno.h>
-#include <regex.h>
-#include <limits.h>
-
-#include "asterisk/ast_expr.h"
-#include "asterisk/logger.h"
-#include "asterisk/strings.h"
-
-enum valtype {
- AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
-} ;
-
-struct val {
- enum valtype type;
- union {
- char *s;
- quad_t i;
- } u;
-} ;
-
-#include "ast_expr2.h" /* the o/p of the bison on ast_expr2.y */
-
-#define SET_COLUMNS do { \
- yylloc_param->first_column = (int)(yyg->yytext_r - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); \
- yylloc_param->last_column += yyleng - 1; \
- yylloc_param->first_line = yylloc_param->last_line = 1; \
- } while (0)
-
-#define SET_STRING do { \
- yylval_param->val = calloc(1, sizeof(struct val)); \
- yylval_param->val->type = AST_EXPR_string; \
- yylval_param->val->u.s = strdup(yytext); \
- } while (0)
-
-#define SET_NUMERIC_STRING do { \
- yylval_param->val = calloc(1, sizeof(struct val)); \
- yylval_param->val->type = AST_EXPR_numeric_string; \
- yylval_param->val->u.s = strdup(yytext); \
- } while (0)
-
-struct parse_io
-{
- char *string;
- struct val *val;
- yyscan_t scanner;
-};
-
-void ast_yyset_column(int column_no, yyscan_t yyscanner);
-int ast_yyget_column(yyscan_t yyscanner);
-static int curlycount = 0;
-static char *expr2_token_subst(const char *mess);
-%}
-
-%option prefix="ast_yy"
-%option batch
-%option outfile="ast_expr2f.c"
-%option reentrant
-%option bison-bridge
-%option bison-locations
-%option noyywrap
-%option noyyfree
-%x var trail
-
-%%
-
-\| { SET_COLUMNS; SET_STRING; return TOK_OR;}
-\& { SET_COLUMNS; SET_STRING; return TOK_AND;}
-\= { SET_COLUMNS; SET_STRING; return TOK_EQ;}
-\|\| { SET_COLUMNS; SET_STRING; return TOK_OR;}
-\&\& { SET_COLUMNS; SET_STRING; return TOK_AND;}
-\=\= { SET_COLUMNS; SET_STRING; return TOK_EQ;}
-\=~ { SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
-\> { SET_COLUMNS; SET_STRING; return TOK_GT;}
-\< { SET_COLUMNS; SET_STRING; return TOK_LT;}
-\>\= { SET_COLUMNS; SET_STRING; return TOK_GE;}
-\<\= { SET_COLUMNS; SET_STRING; return TOK_LE;}
-\!\= { SET_COLUMNS; SET_STRING; return TOK_NE;}
-\+ { SET_COLUMNS; SET_STRING; return TOK_PLUS;}
-\- { SET_COLUMNS; SET_STRING; return TOK_MINUS;}
-\* { SET_COLUMNS; SET_STRING; return TOK_MULT;}
-\/ { SET_COLUMNS; SET_STRING; return TOK_DIV;}
-\% { SET_COLUMNS; SET_STRING; return TOK_MOD;}
-\? { SET_COLUMNS; SET_STRING; return TOK_COND;}
-\! { SET_COLUMNS; SET_STRING; return TOK_COMPL;}
-\: { SET_COLUMNS; SET_STRING; return TOK_COLON;}
-\:\: { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
-\( { SET_COLUMNS; SET_STRING; return TOK_LP;}
-\) { SET_COLUMNS; SET_STRING; return TOK_RP;}
-\$\{ {
- /* gather the contents of ${} expressions, with trailing stuff,
- * into a single TOKEN.
- * They are much more complex now than they used to be
- */
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
-
-[ \t\r] {}
-\"[^"]*\" {SET_COLUMNS; SET_STRING; return TOKEN;}
-
-[\n] {/* what to do with eol */}
-[0-9]+ {
- SET_COLUMNS;
- /* the original behavior of the expression parser was
- * to bring in numbers as a numeric string
- */
- SET_NUMERIC_STRING;
- return TOKEN;
- }
-
-[a-zA-Z0-9,.';\\_^$#@]+ {
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
-
-
-<var>[^{}]*\} {
- curlycount--;
- if (curlycount < 0) {
- BEGIN(trail);
- yymore();
- } else {
- yymore();
- }
- }
-
-<var>[^{}]*\{ {
- curlycount++;
- yymore();
- }
-
-
-<trail>[^-\t\r \n$():?%/+=*<>!|&]* {
- BEGIN(0);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
-
-<trail>[-\t\r \n$():?%/+=*<>!|&] {
- char c = yytext[yyleng-1];
- BEGIN(0);
- unput(c);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
-
-<trail>\$\{ {
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
-
-<trail><<EOF>> {
- BEGIN(0);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- /*actually, if an expr is only a variable ref, this could happen a LOT */
- }
-
-%%
-
-/* I'm putting the interface routine to the whole parse here in the flexer input file
- mainly because of all the flexer initialization that has to be done. Shouldn't matter
- where it is, as long as it's somewhere. I didn't want to define a prototype for the
- ast_yy_scan_string in the .y file, because then, I'd have to define YY_BUFFER_STATE there...
- UGH! that would be inappropriate. */
-
-int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */
-int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */
-
-void ast_yyfree(void *ptr, yyscan_t yyscanner)
-{
- if (ptr) /* the normal generated yyfree func just frees its first arg;
- this get complaints on some systems, as sometimes this
- arg is a nil ptr! It's usually not fatal, but is irritating! */
- free( (char *) ptr );
-}
-
-int ast_expr(char *expr, char *buf, int length)
-{
- struct parse_io io;
- int return_value = 0;
-
- memset(&io, 0, sizeof(io));
- io.string = expr; /* to pass to the error routine */
-
- ast_yylex_init(&io.scanner);
-
- ast_yy_scan_string(expr, io.scanner);
-
- ast_yyparse ((void *) &io);
-
- ast_yylex_destroy(io.scanner);
-
- if (!io.val) {
- if (length > 1) {
- strcpy(buf, "0");
- return_value = 1;
- }
- } else {
- if (io.val->type == AST_EXPR_integer) {
- int res_length;
-
- res_length = snprintf(buf, length, "%ld", (long int) io.val->u.i);
- return_value = (res_length <= length) ? res_length : length;
- } else {
-#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL)
- strncpy(buf, io.val->u.s, length - 1);
-#else /* !STANDALONE && !LOW_MEMORY */
- ast_copy_string(buf, io.val->u.s, length);
-#endif /* STANDALONE || LOW_MEMORY */
- return_value = strlen(buf);
- free(io.val->u.s);
- }
- free(io.val);
- }
- return return_value;
-}
-
-
-char extra_error_message[4095];
-int extra_error_message_supplied = 0;
-void ast_expr_register_extra_error_info(char *message);
-void ast_expr_clear_extra_error_info(void);
-
-void ast_expr_register_extra_error_info(char *message)
-{
- extra_error_message_supplied=1;
- strcpy(extra_error_message, message);
-}
-
-void ast_expr_clear_extra_error_info(void)
-{
- extra_error_message_supplied=0;
- extra_error_message[0] = 0;
-}
-
-static char *expr2_token_equivs1[] =
-{
- "TOKEN",
- "TOK_COND",
- "TOK_COLONCOLON",
- "TOK_OR",
- "TOK_AND",
- "TOK_EQ",
- "TOK_GT",
- "TOK_LT",
- "TOK_GE",
- "TOK_LE",
- "TOK_NE",
- "TOK_PLUS",
- "TOK_MINUS",
- "TOK_MULT",
- "TOK_DIV",
- "TOK_MOD",
- "TOK_COMPL",
- "TOK_COLON",
- "TOK_EQTILDE",
- "TOK_RP",
- "TOK_LP"
-};
-
-static char *expr2_token_equivs2[] =
-{
- "<token>",
- "?",
- "::",
- "|",
- "&",
- "=",
- ">",
- "<",
- ">=",
- "<=",
- "!=",
- "+",
- "-",
- "*",
- "/",
- "%",
- "!",
- ":",
- "=~",
- ")",
- "("
-};
-
-
-static char *expr2_token_subst(const char *mess)
-{
- /* calc a length, malloc, fill, and return; yyerror had better free it! */
- int len=0,i;
- const char *p;
- char *res, *s,*t;
- int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*);
-
- for (p=mess; *p; p++) {
- for (i=0; i<expr2_token_equivs_entries; i++) {
- if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 )
- {
- len+=strlen(expr2_token_equivs2[i])+2;
- p += strlen(expr2_token_equivs1[i])-1;
- break;
- }
- }
- len++;
- }
- res = (char*)malloc(len+1);
- res[0] = 0;
- s = res;
- for (p=mess; *p;) {
- int found = 0;
- for (i=0; i<expr2_token_equivs_entries; i++) {
- if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) {
- *s++ = '\'';
- for (t=expr2_token_equivs2[i]; *t;) {
- *s++ = *t++;
- }
- *s++ = '\'';
- p += strlen(expr2_token_equivs1[i]);
- found = 1;
- break;
- }
- }
- if( !found )
- *s++ = *p++;
- }
- *s++ = 0;
- return res;
-}
-
-int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner);
- char spacebuf[8000]; /* best safe than sorry */
- char spacebuf2[8000]; /* best safe than sorry */
- int i=0;
- char *s2 = expr2_token_subst(s);
- spacebuf[0] = 0;
-
- for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' '; /* uh... assuming yyg is defined, then I can use the yycolumn macro,
- which is the same thing as... get this:
- yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column
- I was tempted to just use yy_buf_pos in the STATE, but..., well:
- a. the yy_buf_pos is the current position in the buffer, which
- may not relate to the entire string/buffer because of the
- buffering.
- b. but, analysis of the situation is that when you use the
- yy_scan_string func, it creates a single buffer the size of
- string, so the two would be the same...
- so, in the end, the yycolumn macro is available, shorter, therefore easier. */
- spacebuf2[i++]='^';
- spacebuf2[i]= 0;
-
-#ifdef STANDALONE3
- /* easier to read in the standalone version */
- printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
- (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
-#else
- ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
- (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
-#endif
-#ifndef STANDALONE
- ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");
-#endif
- free(s2);
- return(0);
-}
diff --git a/1.4/main/ast_expr2.h b/1.4/main/ast_expr2.h
deleted file mode 100644
index d4490512e..000000000
--- a/1.4/main/ast_expr2.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.1a. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- TOK_COLONCOLON = 258,
- TOK_COND = 259,
- TOK_OR = 260,
- TOK_AND = 261,
- TOK_NE = 262,
- TOK_LE = 263,
- TOK_GE = 264,
- TOK_LT = 265,
- TOK_GT = 266,
- TOK_EQ = 267,
- TOK_MINUS = 268,
- TOK_PLUS = 269,
- TOK_MOD = 270,
- TOK_DIV = 271,
- TOK_MULT = 272,
- TOK_COMPL = 273,
- TOK_EQTILDE = 274,
- TOK_COLON = 275,
- TOK_LP = 276,
- TOK_RP = 277,
- TOKEN = 278
- };
-#endif
-/* Tokens. */
-#define TOK_COLONCOLON 258
-#define TOK_COND 259
-#define TOK_OR 260
-#define TOK_AND 261
-#define TOK_NE 262
-#define TOK_LE 263
-#define TOK_GE 264
-#define TOK_LT 265
-#define TOK_GT 266
-#define TOK_EQ 267
-#define TOK_MINUS 268
-#define TOK_PLUS 269
-#define TOK_MOD 270
-#define TOK_DIV 271
-#define TOK_MULT 272
-#define TOK_COMPL 273
-#define TOK_EQTILDE 274
-#define TOK_COLON 275
-#define TOK_LP 276
-#define TOK_RP 277
-#define TOKEN 278
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 147 "ast_expr2.y"
-{
- struct val *val;
-}
-/* Line 1536 of yacc.c. */
-#line 89 "ast_expr2.h"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-
diff --git a/1.4/main/ast_expr2.y b/1.4/main/ast_expr2.y
deleted file mode 100644
index e47c2e721..000000000
--- a/1.4/main/ast_expr2.y
+++ /dev/null
@@ -1,1045 +0,0 @@
-%{
-/* Written by Pace Willisson (pace@blitz.com)
- * and placed in the public domain.
- *
- * Largely rewritten by J.T. Conklin (jtc@wimsey.com)
- *
- * And then overhauled twice by Steve Murphy (murf@digium.com)
- * to add double-quoted strings, allow mult. spaces, improve
- * error messages, and then to fold in a flex scanner for the
- * yylex operation.
- *
- * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
- */
-
-#include "asterisk.h"
-
-#ifndef STANDALONE
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-#include <unistd.h>
-#include <ctype.h>
-#if !defined(SOLARIS) && !defined(__CYGWIN__)
-/* #include <err.h> */
-#else
-#define quad_t int64_t
-#endif
-#include <errno.h>
-#include <regex.h>
-#include <limits.h>
-
-#include "asterisk/ast_expr.h"
-#include "asterisk/logger.h"
-
-#if defined(LONG_LONG_MIN) && !defined(QUAD_MIN)
-#define QUAD_MIN LONG_LONG_MIN
-#endif
-#if defined(LONG_LONG_MAX) && !defined(QUAD_MAX)
-#define QUAD_MAX LONG_LONG_MAX
-#endif
-
-# if ! defined(QUAD_MIN)
-# define QUAD_MIN (-0x7fffffffffffffffLL-1)
-# endif
-# if ! defined(QUAD_MAX)
-# define QUAD_MAX (0x7fffffffffffffffLL)
-# endif
-
-#define YYPARSE_PARAM parseio
-#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
-#define YYERROR_VERBOSE 1
-extern char extra_error_message[4095];
-extern int extra_error_message_supplied;
-
-enum valtype {
- AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
-} ;
-
-#ifdef STANDALONE
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
-#endif
-
-struct val {
- enum valtype type;
- union {
- char *s;
- quad_t i;
- } u;
-} ;
-
-typedef void *yyscan_t;
-
-struct parse_io
-{
- char *string;
- struct val *val;
- yyscan_t scanner;
-};
-
-static int chk_div __P((quad_t, quad_t));
-static int chk_minus __P((quad_t, quad_t, quad_t));
-static int chk_plus __P((quad_t, quad_t, quad_t));
-static int chk_times __P((quad_t, quad_t, quad_t));
-static void free_value __P((struct val *));
-static int is_zero_or_null __P((struct val *));
-static int isstring __P((struct val *));
-static struct val *make_integer __P((quad_t));
-static struct val *make_str __P((const char *));
-static struct val *op_and __P((struct val *, struct val *));
-static struct val *op_colon __P((struct val *, struct val *));
-static struct val *op_eqtilde __P((struct val *, struct val *));
-static struct val *op_div __P((struct val *, struct val *));
-static struct val *op_eq __P((struct val *, struct val *));
-static struct val *op_ge __P((struct val *, struct val *));
-static struct val *op_gt __P((struct val *, struct val *));
-static struct val *op_le __P((struct val *, struct val *));
-static struct val *op_lt __P((struct val *, struct val *));
-static struct val *op_cond __P((struct val *, struct val *, struct val *));
-static struct val *op_minus __P((struct val *, struct val *));
-static struct val *op_negate __P((struct val *));
-static struct val *op_compl __P((struct val *));
-static struct val *op_ne __P((struct val *, struct val *));
-static struct val *op_or __P((struct val *, struct val *));
-static struct val *op_plus __P((struct val *, struct val *));
-static struct val *op_rem __P((struct val *, struct val *));
-static struct val *op_times __P((struct val *, struct val *));
-static quad_t to_integer __P((struct val *));
-static void to_string __P((struct val *));
-
-/* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
-typedef struct yyltype
-{
- int first_line;
- int first_column;
-
- int last_line;
- int last_column;
-} yyltype;
-
-# define YYLTYPE yyltype
-# define YYLTYPE_IS_TRIVIAL 1
-
-/* we will get warning about no prototype for yylex! But we can't
- define it here, we have no definition yet for YYSTYPE. */
-
-int ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
-
-/* I wanted to add args to the yyerror routine, so I could print out
- some useful info about the error. Not as easy as it looks, but it
- is possible. */
-#define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
-#define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
-%}
-
-%pure-parser
-%locations
-/* %debug for when you are having big problems */
-
-/* %name-prefix="ast_yy" */
-
-%union
-{
- struct val *val;
-}
-
-%{
-extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
-%}
-%left <val> TOK_COND TOK_COLONCOLON
-%left <val> TOK_OR
-%left <val> TOK_AND
-%left <val> TOK_EQ TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE
-%left <val> TOK_PLUS TOK_MINUS
-%left <val> TOK_MULT TOK_DIV TOK_MOD
-%right <val> TOK_COMPL
-%left <val> TOK_COLON TOK_EQTILDE
-%left <val> TOK_RP TOK_LP
-
-
-%token <val> TOKEN
-%type <val> start expr
-
-
-%destructor { free_value($$); } expr TOKEN TOK_COND TOK_COLONCOLON TOK_OR TOK_AND TOK_EQ
- TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE TOK_PLUS TOK_MINUS TOK_MULT TOK_DIV TOK_MOD TOK_COMPL TOK_COLON TOK_EQTILDE
- TOK_RP TOK_LP
-
-%%
-
-start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
- ((struct parse_io *)parseio)->val->type = $1->type;
- if( $1->type == AST_EXPR_integer )
- ((struct parse_io *)parseio)->val->u.i = $1->u.i;
- else
- ((struct parse_io *)parseio)->val->u.s = $1->u.s;
- free($1);
- }
- | {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
- ((struct parse_io *)parseio)->val->type = AST_EXPR_string;
- ((struct parse_io *)parseio)->val->u.s = strdup("");
- }
-
- ;
-
-expr: TOKEN { $$= $1;}
- | TOK_LP expr TOK_RP { $$ = $2;
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;
- DESTROY($1); DESTROY($3); }
- | expr TOK_OR expr { $$ = op_or ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_AND expr { $$ = op_and ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_EQ expr { $$ = op_eq ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_GT expr { $$ = op_gt ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_LT expr { $$ = op_lt ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_GE expr { $$ = op_ge ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_LE expr { $$ = op_le ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_NE expr { $$ = op_ne ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_PLUS expr { $$ = op_plus ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_MINUS expr { $$ = op_minus ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | TOK_MINUS expr %prec TOK_COMPL { $$ = op_negate ($2);
- DESTROY($1);
- @$.first_column = @1.first_column; @$.last_column = @2.last_column;
- @$.first_line=0; @$.last_line=0;}
- | TOK_COMPL expr { $$ = op_compl ($2);
- DESTROY($1);
- @$.first_column = @1.first_column; @$.last_column = @2.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_MULT expr { $$ = op_times ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_DIV expr { $$ = op_div ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_MOD expr { $$ = op_rem ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_COLON expr { $$ = op_colon ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_EQTILDE expr { $$ = op_eqtilde ($1, $3);
- DESTROY($2);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- | expr TOK_COND expr TOK_COLONCOLON expr { $$ = op_cond ($1, $3, $5);
- DESTROY($2);
- DESTROY($4);
- @$.first_column = @1.first_column; @$.last_column = @3.last_column;
- @$.first_line=0; @$.last_line=0;}
- ;
-
-%%
-
-static struct val *
-make_integer (quad_t i)
-{
- struct val *vp;
-
- vp = (struct val *) malloc (sizeof (*vp));
- if (vp == NULL) {
- ast_log(LOG_WARNING, "malloc() failed\n");
- return(NULL);
- }
-
- vp->type = AST_EXPR_integer;
- vp->u.i = i;
- return vp;
-}
-
-static struct val *
-make_str (const char *s)
-{
- struct val *vp;
- size_t i;
- int isint;
-
- vp = (struct val *) malloc (sizeof (*vp));
- if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
- ast_log(LOG_WARNING,"malloc() failed\n");
- return(NULL);
- }
-
- for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
- isint && i < strlen(s);
- i++)
- {
- if(!isdigit(s[i]))
- isint = 0;
- }
-
- if (isint)
- vp->type = AST_EXPR_numeric_string;
- else
- vp->type = AST_EXPR_string;
-
- return vp;
-}
-
-
-static void
-free_value (struct val *vp)
-{
- if (vp==NULL) {
- return;
- }
- if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
- free (vp->u.s);
- free(vp);
-}
-
-
-static quad_t
-to_integer (struct val *vp)
-{
- quad_t i;
-
- if (vp == NULL) {
- ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
- return(0);
- }
-
- if (vp->type == AST_EXPR_integer)
- return 1;
-
- if (vp->type == AST_EXPR_string)
- return 0;
-
- /* vp->type == AST_EXPR_numeric_string, make it numeric */
- errno = 0;
- i = strtoll(vp->u.s, (char**)NULL, 10);
- if (errno != 0) {
- ast_log(LOG_WARNING,"Conversion of %s to integer under/overflowed!\n", vp->u.s);
- free(vp->u.s);
- vp->u.s = 0;
- return(0);
- }
- free (vp->u.s);
- vp->u.i = i;
- vp->type = AST_EXPR_integer;
- return 1;
-}
-
-static void
-strip_quotes(struct val *vp)
-{
- if (vp->type != AST_EXPR_string && vp->type != AST_EXPR_numeric_string)
- return;
-
- if( vp->u.s[0] == '"' && vp->u.s[strlen(vp->u.s)-1] == '"' )
- {
- char *f, *t;
- f = vp->u.s;
- t = vp->u.s;
-
- while( *f )
- {
- if( *f && *f != '"' )
- *t++ = *f++;
- else
- f++;
- }
- *t = *f;
- }
-}
-
-static void
-to_string (struct val *vp)
-{
- char *tmp;
-
- if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
- return;
-
- tmp = malloc ((size_t)25);
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"malloc() failed\n");
- return;
- }
-
- sprintf(tmp, "%ld", (long int) vp->u.i);
- vp->type = AST_EXPR_string;
- vp->u.s = tmp;
-}
-
-
-static int
-isstring (struct val *vp)
-{
- /* only TRUE if this string is not a valid integer */
- return (vp->type == AST_EXPR_string);
-}
-
-
-static int
-is_zero_or_null (struct val *vp)
-{
- if (vp->type == AST_EXPR_integer) {
- return (vp->u.i == 0);
- } else {
- return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
- }
- /* NOTREACHED */
-}
-
-#ifdef STANDALONE
-
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
-{
- va_list vars;
- va_start(vars,fmt);
-
- printf("LOG: lev:%d file:%s line:%d func: %s ",
- level, file, line, function);
- vprintf(fmt, vars);
- fflush(stdout);
- va_end(vars);
-}
-
-
-int main(int argc,char **argv) {
- char s[4096];
- char out[4096];
- FILE *infile;
-
- if( !argv[1] )
- exit(20);
-
- if( access(argv[1],F_OK)== 0 )
- {
- int ret;
-
- infile = fopen(argv[1],"r");
- if( !infile )
- {
- printf("Sorry, couldn't open %s for reading!\n", argv[1]);
- exit(10);
- }
- while( fgets(s,sizeof(s),infile) )
- {
- if( s[strlen(s)-1] == '\n' )
- s[strlen(s)-1] = 0;
-
- ret = ast_expr(s, out, sizeof(out));
- printf("Expression: %s Result: [%d] '%s'\n",
- s, ret, out);
- }
- fclose(infile);
- }
- else
- {
- if (ast_expr(argv[1], s, sizeof(s)))
- printf("=====%s======\n",s);
- else
- printf("No result\n");
- }
-}
-
-#endif
-
-#undef ast_yyerror
-#define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parse_io *parseio)
-
-/* I put the ast_yyerror func in the flex input file,
- because it refers to the buffer state. Best to
- let it access the BUFFER stuff there and not trying
- define all the structs, macros etc. in this file! */
-
-
-static struct val *
-op_or (struct val *a, struct val *b)
-{
- if (is_zero_or_null (a)) {
- free_value (a);
- return (b);
- } else {
- free_value (b);
- return (a);
- }
-}
-
-static struct val *
-op_and (struct val *a, struct val *b)
-{
- if (is_zero_or_null (a) || is_zero_or_null (b)) {
- free_value (a);
- free_value (b);
- return (make_integer ((quad_t)0));
- } else {
- free_value (b);
- return (a);
- }
-}
-
-static struct val *
-op_eq (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
- } else {
-#ifdef DEBUG_FOR_CONVERSIONS
- char buffer[2000];
- sprintf(buffer,"Converting '%s' and '%s' ", a->u.s, b->u.s);
-#endif
- (void)to_integer(a);
- (void)to_integer(b);
-#ifdef DEBUG_FOR_CONVERSIONS
- ast_log(LOG_WARNING,"%s to '%lld' and '%lld'\n", buffer, a->u.i, b->u.i);
-#endif
- r = make_integer ((quad_t)(a->u.i == b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_gt (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i > b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_lt (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i < b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_ge (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i >= b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_le (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i <= b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_cond (struct val *a, struct val *b, struct val *c)
-{
- struct val *r;
-
- if( isstring(a) )
- {
- if( strlen(a->u.s) && strcmp(a->u.s, "\"\"") != 0 && strcmp(a->u.s,"0") != 0 )
- {
- free_value(a);
- free_value(c);
- r = b;
- }
- else
- {
- free_value(a);
- free_value(b);
- r = c;
- }
- }
- else
- {
- (void)to_integer(a);
- if( a->u.i )
- {
- free_value(a);
- free_value(c);
- r = b;
- }
- else
- {
- free_value(a);
- free_value(b);
- r = c;
- }
- }
- return r;
-}
-
-static struct val *
-op_ne (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (isstring (a) || isstring (b)) {
- to_string (a);
- to_string (b);
- r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
- } else {
- (void)to_integer(a);
- (void)to_integer(b);
- r = make_integer ((quad_t)(a->u.i != b->u.i));
- }
-
- free_value (a);
- free_value (b);
- return r;
-}
-
-static int
-chk_plus (quad_t a, quad_t b, quad_t r)
-{
- /* sum of two positive numbers must be positive */
- if (a > 0 && b > 0 && r <= 0)
- return 1;
- /* sum of two negative numbers must be negative */
- if (a < 0 && b < 0 && r >= 0)
- return 1;
- /* all other cases are OK */
- return 0;
-}
-
-static struct val *
-op_plus (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING,"non-numeric argument\n");
- if (!to_integer (b)) {
- free_value(a);
- free_value(b);
- return make_integer(0);
- } else {
- free_value(a);
- return (b);
- }
- } else if (!to_integer(b)) {
- free_value(b);
- return (a);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
- if (chk_plus (a->u.i, b->u.i, r->u.i)) {
- ast_log(LOG_WARNING,"overflow\n");
- }
- free_value (a);
- free_value (b);
- return r;
-}
-
-static int
-chk_minus (quad_t a, quad_t b, quad_t r)
-{
- /* special case subtraction of QUAD_MIN */
- if (b == QUAD_MIN) {
- if (a >= 0)
- return 1;
- else
- return 0;
- }
- /* this is allowed for b != QUAD_MIN */
- return chk_plus (a, -b, r);
-}
-
-static struct val *
-op_minus (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- if (!to_integer (b)) {
- free_value(a);
- free_value(b);
- return make_integer(0);
- } else {
- r = make_integer(0 - b->u.i);
- free_value(a);
- free_value(b);
- return (r);
- }
- } else if (!to_integer(b)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- free_value(b);
- return (a);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
- if (chk_minus (a->u.i, b->u.i, r->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_negate (struct val *a)
-{
- struct val *r;
-
- if (!to_integer (a) ) {
- free_value(a);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return make_integer(0);
- }
-
- r = make_integer (/*(quad_t)*/(- a->u.i));
- if (chk_minus (0, a->u.i, r->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- return r;
-}
-
-static struct val *
-op_compl (struct val *a)
-{
- int v1 = 1;
- struct val *r;
-
- if( !a )
- {
- v1 = 0;
- }
- else
- {
- switch( a->type )
- {
- case AST_EXPR_integer:
- if( a->u.i == 0 )
- v1 = 0;
- break;
-
- case AST_EXPR_string:
- if( a->u.s == 0 )
- v1 = 0;
- else
- {
- if( a->u.s[0] == 0 )
- v1 = 0;
- else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
- v1 = 0;
- }
- break;
-
- case AST_EXPR_numeric_string:
- if( a->u.s == 0 )
- v1 = 0;
- else
- {
- if( a->u.s[0] == 0 )
- v1 = 0;
- else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
- v1 = 0;
- }
- break;
- }
- }
-
- r = make_integer (!v1);
- free_value (a);
- return r;
-}
-
-static int
-chk_times (quad_t a, quad_t b, quad_t r)
-{
- /* special case: first operand is 0, no overflow possible */
- if (a == 0)
- return 0;
- /* cerify that result of division matches second operand */
- if (r / a != b)
- return 1;
- return 0;
-}
-
-static struct val *
-op_times (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a) || !to_integer (b)) {
- free_value(a);
- free_value(b);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return(make_integer(0));
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
- if (chk_times (a->u.i, b->u.i, r->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- free_value (b);
- return (r);
-}
-
-static int
-chk_div (quad_t a, quad_t b)
-{
- /* div by zero has been taken care of before */
- /* only QUAD_MIN / -1 causes overflow */
- if (a == QUAD_MIN && b == -1)
- return 1;
- /* everything else is OK */
- return 0;
-}
-
-static struct val *
-op_div (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a)) {
- free_value(a);
- free_value(b);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return make_integer(0);
- } else if (!to_integer (b)) {
- free_value(a);
- free_value(b);
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- return make_integer(INT_MAX);
- }
-
- if (b->u.i == 0) {
- ast_log(LOG_WARNING, "division by zero\n");
- free_value(a);
- free_value(b);
- return make_integer(INT_MAX);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
- if (chk_div (a->u.i, b->u.i)) {
- ast_log(LOG_WARNING, "overflow\n");
- }
- free_value (a);
- free_value (b);
- return r;
-}
-
-static struct val *
-op_rem (struct val *a, struct val *b)
-{
- struct val *r;
-
- if (!to_integer (a) || !to_integer (b)) {
- if( !extra_error_message_supplied )
- ast_log(LOG_WARNING, "non-numeric argument\n");
- free_value(a);
- free_value(b);
- return make_integer(0);
- }
-
- if (b->u.i == 0) {
- ast_log(LOG_WARNING, "div by zero\n");
- free_value(a);
- return(b);
- }
-
- r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
- /* chk_rem necessary ??? */
- free_value (a);
- free_value (b);
- return r;
-}
-
-
-static struct val *
-op_colon (struct val *a, struct val *b)
-{
- regex_t rp;
- regmatch_t rm[2];
- char errbuf[256];
- int eval;
- struct val *v;
-
- /* coerce to both arguments to strings */
- to_string(a);
- to_string(b);
- /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
- strip_quotes(a);
- strip_quotes(b);
- /* compile regular expression */
- if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
- regerror (eval, &rp, errbuf, sizeof(errbuf));
- ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
- free_value(a);
- free_value(b);
- return make_str("");
- }
-
- /* compare string against pattern */
- /* remember that patterns are anchored to the beginning of the line */
- if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
- if (rm[1].rm_so >= 0) {
- *(a->u.s + rm[1].rm_eo) = '\0';
- v = make_str (a->u.s + rm[1].rm_so);
-
- } else {
- v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
- }
- } else {
- if (rp.re_nsub == 0) {
- v = make_integer ((quad_t)0);
- } else {
- v = make_str ("");
- }
- }
-
- /* free arguments and pattern buffer */
- free_value (a);
- free_value (b);
- regfree (&rp);
-
- return v;
-}
-
-
-static struct val *
-op_eqtilde (struct val *a, struct val *b)
-{
- regex_t rp;
- regmatch_t rm[2];
- char errbuf[256];
- int eval;
- struct val *v;
-
- /* coerce to both arguments to strings */
- to_string(a);
- to_string(b);
- /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
- strip_quotes(a);
- strip_quotes(b);
- /* compile regular expression */
- if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
- regerror (eval, &rp, errbuf, sizeof(errbuf));
- ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
- free_value(a);
- free_value(b);
- return make_str("");
- }
-
- /* compare string against pattern */
- /* remember that patterns are anchored to the beginning of the line */
- if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 ) {
- if (rm[1].rm_so >= 0) {
- *(a->u.s + rm[1].rm_eo) = '\0';
- v = make_str (a->u.s + rm[1].rm_so);
-
- } else {
- v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
- }
- } else {
- if (rp.re_nsub == 0) {
- v = make_integer ((quad_t)0);
- } else {
- v = make_str ("");
- }
- }
-
- /* free arguments and pattern buffer */
- free_value (a);
- free_value (b);
- regfree (&rp);
-
- return v;
-}
diff --git a/1.4/main/ast_expr2f.c b/1.4/main/ast_expr2f.c
deleted file mode 100644
index 9b8ef1532..000000000
--- a/1.4/main/ast_expr2f.c
+++ /dev/null
@@ -1,2478 +0,0 @@
-#line 2 "ast_expr2f.c"
-
-#line 4 "ast_expr2f.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-int ast_yylex_init (yyscan_t* scanner);
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE ast_yyrestart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = yyg->yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via ast_yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
- ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void ast_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void ast_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE ast_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void ast_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void ast_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void ast_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void ast_yypop_buffer_state (yyscan_t yyscanner );
-
-static void ast_yyensure_buffer_stack (yyscan_t yyscanner );
-static void ast_yy_load_buffer_state (yyscan_t yyscanner );
-static void ast_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER ast_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE ast_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE ast_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE ast_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *ast_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *ast_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void ast_yyfree (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer ast_yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- ast_yyensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- ast_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- ast_yyensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- ast_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define ast_yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yyg->yytext_ptr = yy_bp; \
- yyg->yytext_ptr -= yyg->yy_more_len; \
- yyleng = (size_t) (yy_cp - yyg->yytext_ptr); \
- yyg->yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 35
-#define YY_END_OF_BUFFER 36
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[55] =
- { 0,
- 0, 0, 0, 0, 32, 32, 36, 35, 25, 27,
- 19, 35, 29, 29, 17, 2, 22, 23, 15, 13,
- 14, 16, 28, 20, 9, 3, 8, 18, 1, 35,
- 31, 30, 32, 33, 33, 12, 0, 26, 29, 24,
- 5, 28, 21, 11, 6, 7, 10, 4, 0, 31,
- 30, 32, 34, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 5, 6, 7, 8, 9, 6, 10,
- 11, 12, 13, 6, 14, 6, 15, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 17, 6, 18,
- 19, 20, 21, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 1, 6, 1, 6, 6, 1, 6, 6, 6, 6,
-
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 22, 23, 24, 25, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[26] =
- { 0,
- 1, 2, 2, 2, 1, 3, 4, 2, 2, 2,
- 2, 2, 2, 2, 2, 3, 2, 2, 2, 2,
- 2, 3, 2, 1, 1
- } ;
-
-static yyconst flex_int16_t yy_base[61] =
- { 0,
- 0, 0, 4, 5, 29, 54, 71, 101, 101, 101,
- 50, 63, 25, 45, 101, 56, 101, 101, 101, 101,
- 101, 101, 31, 47, 44, 14, 43, 101, 29, 18,
- 101, 101, 0, 101, 28, 101, 38, 101, 42, 101,
- 101, 50, 101, 101, 101, 101, 101, 101, 22, 101,
- 101, 0, 101, 101, 79, 83, 87, 89, 93, 97
- } ;
-
-static yyconst flex_int16_t yy_def[61] =
- { 0,
- 54, 1, 55, 55, 56, 56, 54, 54, 54, 54,
- 54, 57, 54, 58, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 59,
- 54, 54, 60, 54, 54, 54, 57, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 59, 54,
- 54, 60, 54, 0, 54, 54, 54, 54, 54, 54
- } ;
-
-static yyconst flex_int16_t yy_nxt[127] =
- { 0,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 8, 29, 8, 8, 31, 31, 32, 32, 33,
- 39, 39, 45, 33, 33, 35, 39, 39, 46, 50,
- 39, 51, 38, 50, 33, 51, 42, 39, 39, 53,
- 33, 48, 33, 33, 33, 39, 39, 39, 33, 33,
- 35, 47, 44, 43, 41, 42, 40, 38, 36, 33,
- 54, 54, 54, 54, 54, 33, 54, 33, 33, 30,
- 30, 30, 30, 34, 34, 34, 34, 37, 37, 37,
- 37, 39, 39, 49, 49, 49, 49, 52, 54, 52,
-
- 7, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54
- } ;
-
-static yyconst flex_int16_t yy_chk[127] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 3, 4, 3, 4, 5,
- 13, 13, 26, 5, 5, 5, 23, 23, 26, 30,
- 13, 30, 37, 49, 5, 49, 23, 39, 39, 35,
- 5, 29, 5, 5, 6, 42, 42, 39, 6, 6,
- 6, 27, 25, 24, 16, 42, 14, 12, 11, 6,
- 7, 0, 0, 0, 0, 6, 0, 6, 6, 55,
- 55, 55, 55, 56, 56, 56, 56, 57, 57, 57,
- 57, 58, 58, 59, 59, 59, 59, 60, 0, 60,
-
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54
- } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() (yyg->yy_more_flag = 1)
-#define YY_MORE_ADJ yyg->yy_more_len
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "ast_expr2.fl"
-#line 2 "ast_expr2.fl"
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Dialplan Expression Lexical Scanner
- */
-
-#include "asterisk.h"
-
-#ifndef STANDALONE
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-#include <ctype.h>
-#if !defined(SOLARIS) && !defined(__CYGWIN__)
-/* #include <err.h> */
-#else
-#define quad_t int64_t
-#endif
-#include <errno.h>
-#include <regex.h>
-#include <limits.h>
-
-#include "asterisk/ast_expr.h"
-#include "asterisk/logger.h"
-#include "asterisk/strings.h"
-
-enum valtype {
- AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
-} ;
-
-struct val {
- enum valtype type;
- union {
- char *s;
- quad_t i;
- } u;
-} ;
-
-#include "ast_expr2.h" /* the o/p of the bison on ast_expr2.y */
-
-#define SET_COLUMNS do { \
- yylloc_param->first_column = (int)(yyg->yytext_r - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); \
- yylloc_param->last_column += yyleng - 1; \
- yylloc_param->first_line = yylloc_param->last_line = 1; \
- } while (0)
-
-#define SET_STRING do { \
- yylval_param->val = calloc(1, sizeof(struct val)); \
- yylval_param->val->type = AST_EXPR_string; \
- yylval_param->val->u.s = strdup(yytext); \
- } while (0)
-
-#define SET_NUMERIC_STRING do { \
- yylval_param->val = calloc(1, sizeof(struct val)); \
- yylval_param->val->type = AST_EXPR_numeric_string; \
- yylval_param->val->u.s = strdup(yytext); \
- } while (0)
-
-struct parse_io
-{
- char *string;
- struct val *val;
- yyscan_t scanner;
-};
-
-void ast_yyset_column(int column_no, yyscan_t yyscanner);
-int ast_yyget_column(yyscan_t yyscanner);
-static int curlycount = 0;
-static char *expr2_token_subst(const char *mess);
-
-#line 575 "ast_expr2f.c"
-
-#define INITIAL 0
-#define var 1
-#define trail 2
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
- {
-
- /* User-defined. Not touched by flex. */
- YY_EXTRA_TYPE yyextra_r;
-
- /* The rest are the same as the globals declared in the non-reentrant scanner. */
- FILE *yyin_r, *yyout_r;
- size_t yy_buffer_stack_top; /**< index of top of stack. */
- size_t yy_buffer_stack_max; /**< capacity of stack. */
- YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
- char yy_hold_char;
- int yy_n_chars;
- int yyleng_r;
- char *yy_c_buf_p;
- int yy_init;
- int yy_start;
- int yy_did_buffer_switch_on_eof;
- int yy_start_stack_ptr;
- int yy_start_stack_depth;
- int *yy_start_stack;
- yy_state_type yy_last_accepting_state;
- char* yy_last_accepting_cpos;
-
- int yylineno_r;
- int yy_flex_debug_r;
-
- char *yytext_r;
- int yy_more_flag;
- int yy_more_len;
-
- YYSTYPE * yylval_r;
-
- YYLTYPE * yylloc_r;
-
- }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
- /* This must go here because YYSTYPE and YYLTYPE are included
- * from bison output in section 1.*/
- # define yylval yyg->yylval_r
-
- # define yylloc yyg->yylloc_r
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int ast_yylex_destroy (yyscan_t yyscanner );
-
-int ast_yyget_debug (yyscan_t yyscanner );
-
-void ast_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE ast_yyget_extra (yyscan_t yyscanner );
-
-void ast_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *ast_yyget_in (yyscan_t yyscanner );
-
-void ast_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *ast_yyget_out (yyscan_t yyscanner );
-
-void ast_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-
-int ast_yyget_leng (yyscan_t yyscanner );
-
-char *ast_yyget_text (yyscan_t yyscanner );
-
-int ast_yyget_lineno (yyscan_t yyscanner );
-
-void ast_yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-YYSTYPE * ast_yyget_lval (yyscan_t yyscanner );
-
-void ast_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
-
- YYLTYPE *ast_yyget_lloc (yyscan_t yyscanner );
-
- void ast_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int ast_yywrap (yyscan_t yyscanner );
-#else
-extern int ast_yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- size_t n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int ast_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
-
-#define YY_DECL int ast_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 105 "ast_expr2.fl"
-
-
-#line 815 "ast_expr2f.c"
-
- yylval = yylval_param;
-
- yylloc = yylloc_param;
-
- if ( !yyg->yy_init )
- {
- yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yyg->yy_start )
- yyg->yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- ast_yyensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- ast_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- ast_yy_load_buffer_state(yyscanner );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yyg->yy_more_len = 0;
- if ( yyg->yy_more_flag )
- {
- yyg->yy_more_len = yyg->yy_c_buf_p - yyg->yytext_ptr;
- yyg->yy_more_flag = 0;
- }
- yy_cp = yyg->yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yyg->yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yyg->yy_start;
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 55 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_current_state != 54 );
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yyg->yy_hold_char;
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 107 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_OR;}
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 108 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_AND;}
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 109 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_EQ;}
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 110 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_OR;}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 111 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_AND;}
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 112 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_EQ;}
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 113 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 114 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_GT;}
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 115 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_LT;}
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 116 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_GE;}
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 117 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_LE;}
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 118 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_NE;}
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 119 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_PLUS;}
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 120 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_MINUS;}
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 121 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_MULT;}
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 122 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_DIV;}
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 123 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_MOD;}
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 124 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COND;}
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 125 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COMPL;}
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 126 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COLON;}
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 127 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 128 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_LP;}
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 129 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_RP;}
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 130 "ast_expr2.fl"
-{
- /* gather the contents of ${} expressions, with trailing stuff,
- * into a single TOKEN.
- * They are much more complex now than they used to be
- */
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 140 "ast_expr2.fl"
-{}
- YY_BREAK
-case 26:
-/* rule 26 can match eol */
-YY_RULE_SETUP
-#line 141 "ast_expr2.fl"
-{SET_COLUMNS; SET_STRING; return TOKEN;}
- YY_BREAK
-case 27:
-/* rule 27 can match eol */
-YY_RULE_SETUP
-#line 143 "ast_expr2.fl"
-{/* what to do with eol */}
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 144 "ast_expr2.fl"
-{
- SET_COLUMNS;
- /* the original behavior of the expression parser was
- * to bring in numbers as a numeric string
- */
- SET_NUMERIC_STRING;
- return TOKEN;
- }
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 153 "ast_expr2.fl"
-{
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
- YY_BREAK
-case 30:
-/* rule 30 can match eol */
-YY_RULE_SETUP
-#line 160 "ast_expr2.fl"
-{
- curlycount--;
- if (curlycount < 0) {
- BEGIN(trail);
- yymore();
- } else {
- yymore();
- }
- }
- YY_BREAK
-case 31:
-/* rule 31 can match eol */
-YY_RULE_SETUP
-#line 170 "ast_expr2.fl"
-{
- curlycount++;
- yymore();
- }
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 176 "ast_expr2.fl"
-{
- BEGIN(0);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
- YY_BREAK
-case 33:
-/* rule 33 can match eol */
-YY_RULE_SETUP
-#line 183 "ast_expr2.fl"
-{
- char c = yytext[yyleng-1];
- BEGIN(0);
- unput(c);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- }
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 192 "ast_expr2.fl"
-{
- curlycount = 0;
- BEGIN(var);
- yymore();
- }
- YY_BREAK
-case YY_STATE_EOF(trail):
-#line 198 "ast_expr2.fl"
-{
- BEGIN(0);
- SET_COLUMNS;
- SET_STRING;
- return TOKEN;
- /*actually, if an expr is only a variable ref, this could happen a LOT */
- }
- YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 206 "ast_expr2.fl"
-ECHO;
- YY_BREAK
-#line 1140 "ast_expr2f.c"
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(var):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yyg->yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * ast_yylex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yyg->yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yyg->yy_did_buffer_switch_on_eof = 0;
-
- if ( ast_yywrap(yyscanner ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p =
- yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yyg->yy_c_buf_p =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of ast_yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- ast_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- yyg->yy_n_chars, num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- if ( yyg->yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- ast_yyrestart(yyin ,yyscanner);
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- yyg->yy_n_chars += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_current_state = yyg->yy_start;
-
- for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 55 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
- register int yy_is_jam;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 55 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 54);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
-{
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_cp = yyg->yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yyg->yy_hold_char;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = yyg->yy_n_chars + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- yyg->yytext_ptr = yy_bp;
- yyg->yy_hold_char = *yy_cp;
- yyg->yy_c_buf_p = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (yyscan_t yyscanner)
-#else
- static int input (yyscan_t yyscanner)
-#endif
-
-{
- int c;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
- if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- /* This was really a NUL. */
- *yyg->yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
- ++yyg->yy_c_buf_p;
-
- switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- ast_yyrestart(yyin ,yyscanner);
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( ast_yywrap(yyscanner ) )
- return EOF;
-
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput(yyscanner);
-#else
- return input(yyscanner);
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
- *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
- yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void ast_yyrestart (FILE * input_file , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! YY_CURRENT_BUFFER ){
- ast_yyensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- ast_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- ast_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- ast_yy_load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
- void ast_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* TODO. We should be able to replace this entire function body
- * with
- * ast_yypop_buffer_state();
- * ast_yypush_buffer_state(new_buffer);
- */
- ast_yyensure_buffer_stack (yyscanner);
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- ast_yy_load_buffer_state(yyscanner );
-
- /* We don't actually know whether we did this switch during
- * EOF (ast_yywrap()) processing, but the only time this flag
- * is looked at is after ast_yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-static void ast_yy_load_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- yyg->yy_hold_char = *yyg->yy_c_buf_p;
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE ast_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) ast_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in ast_yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) ast_yyalloc(b->yy_buf_size + 2 ,yyscanner );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in ast_yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- ast_yy_init_buffer(b,file ,yyscanner);
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with ast_yy_create_buffer()
- * @param yyscanner The scanner object.
- */
- void ast_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- ast_yyfree((void *) b->yy_ch_buf ,yyscanner );
-
- ast_yyfree((void *) b ,yyscanner );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a ast_yyrestart() or at EOF.
- */
- static void ast_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
-
-{
- int oerrno = errno;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- ast_yy_flush_buffer(b ,yyscanner);
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then ast_yy_init_buffer was _probably_
- * called from ast_yyrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
- void ast_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- ast_yy_load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- * @param yyscanner The scanner object.
- */
-void ast_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (new_buffer == NULL)
- return;
-
- ast_yyensure_buffer_stack(yyscanner);
-
- /* This block is copied from ast_yy_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- yyg->yy_buffer_stack_top++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from ast_yy_switch_to_buffer. */
- ast_yy_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- * @param yyscanner The scanner object.
- */
-void ast_yypop_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (!YY_CURRENT_BUFFER)
- return;
-
- ast_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if (yyg->yy_buffer_stack_top > 0)
- --yyg->yy_buffer_stack_top;
-
- if (YY_CURRENT_BUFFER) {
- ast_yy_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void ast_yyensure_buffer_stack (yyscan_t yyscanner)
-{
- int num_to_alloc;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (!yyg->yy_buffer_stack) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ast_yyalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
-
- memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- yyg->yy_buffer_stack_max = num_to_alloc;
- yyg->yy_buffer_stack_top = 0;
- return;
- }
-
- if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ast_yyrealloc
- (yyg->yy_buffer_stack,
- num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
-
- /* zero only the new slots.*/
- memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
- yyg->yy_buffer_stack_max = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE ast_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) ast_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in ast_yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- ast_yy_switch_to_buffer(b ,yyscanner );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to ast_yylex() will
- * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * ast_yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE ast_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-
- return ast_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to ast_yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE ast_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) ast_yyalloc(n ,yyscanner );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in ast_yy_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = ast_yy_scan_buffer(buf,n ,yyscanner);
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in ast_yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = yyg->yy_hold_char; \
- yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
- yyg->yy_hold_char = *yyg->yy_c_buf_p; \
- *yyg->yy_c_buf_p = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE ast_yyget_extra (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int ast_yyget_lineno (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int ast_yyget_column (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *ast_yyget_in (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *ast_yyget_out (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int ast_yyget_leng (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *ast_yyget_text (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void ast_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void ast_yyset_lineno (int line_number , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* lineno is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ast_yyset_lineno called with no buffer" , yyscanner);
-
- yylineno = line_number;
-}
-
-/** Set the current column.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void ast_yyset_column (int column_no , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* column is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ast_yyset_column called with no buffer" , yyscanner);
-
- yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see ast_yy_switch_to_buffer
- */
-void ast_yyset_in (FILE * in_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
-}
-
-void ast_yyset_out (FILE * out_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
-}
-
-int ast_yyget_debug (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yy_flex_debug;
-}
-
-void ast_yyset_debug (int bdebug , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-YYSTYPE * ast_yyget_lval (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yylval;
-}
-
-void ast_yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yylval = yylval_param;
-}
-
-YYLTYPE *ast_yyget_lloc (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yylloc;
-}
-
-void ast_yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yylloc = yylloc_param;
-}
-
-/* User-visible API */
-
-/* ast_yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int ast_yylex_init(yyscan_t* ptr_yy_globals)
-
-{
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) ast_yyalloc ( sizeof( struct yyguts_t ), NULL );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from ast_yylex_destroy(), so don't allocate here.
- */
-
- yyg->yy_buffer_stack = 0;
- yyg->yy_buffer_stack_top = 0;
- yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
- yyg->yy_init = 0;
- yyg->yy_start = 0;
-
- yyg->yy_start_stack_ptr = 0;
- yyg->yy_start_stack_depth = 0;
- yyg->yy_start_stack = NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * ast_yylex_init()
- */
- return 0;
-}
-
-/* ast_yylex_destroy is for both reentrant and non-reentrant scanners. */
-int ast_yylex_destroy (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- ast_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- ast_yypop_buffer_state(yyscanner);
- }
-
- /* Destroy the stack itself. */
- ast_yyfree(yyg->yy_buffer_stack ,yyscanner);
- yyg->yy_buffer_stack = NULL;
-
- /* Destroy the start condition stack. */
- ast_yyfree(yyg->yy_start_stack ,yyscanner );
- yyg->yy_start_stack = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * ast_yylex() is called, initialization will occur. */
- yy_init_globals( yyscanner);
-
- /* Destroy the main struct (reentrant only). */
- ast_yyfree ( yyscanner , yyscanner );
- yyscanner = NULL;
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *ast_yyalloc (yy_size_t size , yyscan_t yyscanner)
-{
- return (void *) malloc( size );
-}
-
-void *ast_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 206 "ast_expr2.fl"
-
-
-
-/* I'm putting the interface routine to the whole parse here in the flexer input file
- mainly because of all the flexer initialization that has to be done. Shouldn't matter
- where it is, as long as it's somewhere. I didn't want to define a prototype for the
- ast_yy_scan_string in the .y file, because then, I'd have to define YY_BUFFER_STATE there...
- UGH! that would be inappropriate. */
-
-int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */
-int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */
-
-void ast_yyfree(void *ptr, yyscan_t yyscanner)
-{
- if (ptr) /* the normal generated ast_yyfree func just frees its first arg;
- this get complaints on some systems, as sometimes this
- arg is a nil ptr! It's usually not fatal, but is irritating! */
- free( (char *) ptr );
-}
-
-int ast_expr(char *expr, char *buf, int length)
-{
- struct parse_io io;
- int return_value = 0;
-
- memset(&io, 0, sizeof(io));
- io.string = expr; /* to pass to the error routine */
-
- ast_yylex_init(&io.scanner);
-
- ast_yy_scan_string(expr, io.scanner);
-
- ast_yyparse ((void *) &io);
-
- ast_yylex_destroy(io.scanner);
-
- if (!io.val) {
- if (length > 1) {
- strcpy(buf, "0");
- return_value = 1;
- }
- } else {
- if (io.val->type == AST_EXPR_integer) {
- int res_length;
-
- res_length = snprintf(buf, length, "%ld", (long int) io.val->u.i);
- return_value = (res_length <= length) ? res_length : length;
- } else {
-#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL)
- strncpy(buf, io.val->u.s, length - 1);
-#else /* !STANDALONE && !LOW_MEMORY */
- ast_copy_string(buf, io.val->u.s, length);
-#endif /* STANDALONE || LOW_MEMORY */
- return_value = strlen(buf);
- free(io.val->u.s);
- }
- free(io.val);
- }
- return return_value;
-}
-
-
-char extra_error_message[4095];
-int extra_error_message_supplied = 0;
-void ast_expr_register_extra_error_info(char *message);
-void ast_expr_clear_extra_error_info(void);
-
-void ast_expr_register_extra_error_info(char *message)
-{
- extra_error_message_supplied=1;
- strcpy(extra_error_message, message);
-}
-
-void ast_expr_clear_extra_error_info(void)
-{
- extra_error_message_supplied=0;
- extra_error_message[0] = 0;
-}
-
-static char *expr2_token_equivs1[] =
-{
- "TOKEN",
- "TOK_COND",
- "TOK_COLONCOLON",
- "TOK_OR",
- "TOK_AND",
- "TOK_EQ",
- "TOK_GT",
- "TOK_LT",
- "TOK_GE",
- "TOK_LE",
- "TOK_NE",
- "TOK_PLUS",
- "TOK_MINUS",
- "TOK_MULT",
- "TOK_DIV",
- "TOK_MOD",
- "TOK_COMPL",
- "TOK_COLON",
- "TOK_EQTILDE",
- "TOK_RP",
- "TOK_LP"
-};
-
-static char *expr2_token_equivs2[] =
-{
- "<token>",
- "?",
- "::",
- "|",
- "&",
- "=",
- ">",
- "<",
- ">=",
- "<=",
- "!=",
- "+",
- "-",
- "*",
- "/",
- "%",
- "!",
- ":",
- "=~",
- ")",
- "("
-};
-
-
-static char *expr2_token_subst(const char *mess)
-{
- /* calc a length, malloc, fill, and return; yyerror had better free it! */
- int len=0,i;
- const char *p;
- char *res, *s,*t;
- int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*);
-
- for (p=mess; *p; p++) {
- for (i=0; i<expr2_token_equivs_entries; i++) {
- if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 )
- {
- len+=strlen(expr2_token_equivs2[i])+2;
- p += strlen(expr2_token_equivs1[i])-1;
- break;
- }
- }
- len++;
- }
- res = (char*)malloc(len+1);
- res[0] = 0;
- s = res;
- for (p=mess; *p;) {
- int found = 0;
- for (i=0; i<expr2_token_equivs_entries; i++) {
- if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) {
- *s++ = '\'';
- for (t=expr2_token_equivs2[i]; *t;) {
- *s++ = *t++;
- }
- *s++ = '\'';
- p += strlen(expr2_token_equivs1[i]);
- found = 1;
- break;
- }
- }
- if( !found )
- *s++ = *p++;
- }
- *s++ = 0;
- return res;
-}
-
-int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner);
- char spacebuf[8000]; /* best safe than sorry */
- char spacebuf2[8000]; /* best safe than sorry */
- int i=0;
- char *s2 = expr2_token_subst(s);
- spacebuf[0] = 0;
-
- for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' '; /* uh... assuming yyg is defined, then I can use the yycolumn macro,
- which is the same thing as... get this:
- yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column
- I was tempted to just use yy_buf_pos in the STATE, but..., well:
- a. the yy_buf_pos is the current position in the buffer, which
- may not relate to the entire string/buffer because of the
- buffering.
- b. but, analysis of the situation is that when you use the
- ast_yy_scan_string func, it creates a single buffer the size of
- string, so the two would be the same...
- so, in the end, the yycolumn macro is available, shorter, therefore easier. */
- spacebuf2[i++]='^';
- spacebuf2[i]= 0;
-
-#ifdef STANDALONE3
- /* easier to read in the standalone version */
- printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
- (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
-#else
- ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
- (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
-#endif
-#ifndef STANDALONE
- ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");
-#endif
- free(s2);
- return(0);
-}
-
diff --git a/1.4/main/asterisk.c b/1.4/main/asterisk.c
deleted file mode 100644
index 37823e989..000000000
--- a/1.4/main/asterisk.c
+++ /dev/null
@@ -1,3105 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2008, 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.
- */
-
-
-/* Doxygenified Copyright Header */
-/*!
- * \mainpage Asterisk -- An Open Source Telephony Toolkit
- *
- * \par Developer Documentation for Asterisk
- * This is the main developer documentation for Asterisk. It is
- * generated by running "make progdocs".
- * \par Additional documentation
- * \arg \ref DevDoc
- * \arg \ref ConfigFiles
- *
- * \section copyright Copyright and author
- *
- * Copyright (C) 1999 - 2008, Digium, Inc.
- * Asterisk is a trademark registered by Digium, Inc.
- *
- * \author Mark Spencer <markster@digium.com>
- * Also see \ref AstCREDITS
- *
- * \section license License
- * 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.
- *
- * \verbinclude LICENSE
- *
- */
-
-/*! \file
- \brief Top level source file for Asterisk - the Open Source PBX. Implementation
- of PBX core functions and CLI interface.
-
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#undef sched_setscheduler
-#undef setpriority
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sched.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/resource.h>
-#include <grp.h>
-#include <pwd.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_ZAPTEL
-#include <sys/ioctl.h>
-#include <zaptel/zaptel.h>
-#endif
-
-#ifdef linux
-#include <sys/prctl.h>
-#ifdef HAVE_CAP
-#include <sys/capability.h>
-#endif /* HAVE_CAP */
-#endif /* linux */
-#include <regex.h>
-
-#if defined(__FreeBSD__) || defined( __NetBSD__ ) || defined(SOLARIS)
-#include <netdb.h>
-#if defined(SOLARIS)
-int daemon(int, int); /* defined in libresolv of all places */
-#endif
-#endif
-
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/channel.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/alaw.h"
-#include "asterisk/callerid.h"
-#include "asterisk/image.h"
-#include "asterisk/tdd.h"
-#include "asterisk/term.h"
-#include "asterisk/manager.h"
-#include "asterisk/cdr.h"
-#include "asterisk/pbx.h"
-#include "asterisk/enum.h"
-#include "asterisk/rtp.h"
-#include "asterisk/http.h"
-#include "asterisk/udptl.h"
-#include "asterisk/app.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/file.h"
-#include "asterisk/io.h"
-#include "asterisk/lock.h"
-#include "editline/histedit.h"
-#include "asterisk/config.h"
-#include "asterisk/version.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/module.h"
-
-#include "asterisk/doxyref.h" /* Doxygen documentation */
-
-#include "../defaults.h"
-
-#ifndef AF_LOCAL
-#define AF_LOCAL AF_UNIX
-#define PF_LOCAL PF_UNIX
-#endif
-
-#define AST_MAX_CONNECTS 128
-#define NUM_MSGS 64
-
-/*! \brief Welcome message when starting a CLI interface */
-#define WELCOME_MESSAGE \
- ast_verbose("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2008 Digium, Inc. and others.\n"); \
- ast_verbose("Created by Mark Spencer <markster@digium.com>\n"); \
- ast_verbose("Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.\n"); \
- ast_verbose("This is free software, with components licensed under the GNU General Public\n"); \
- ast_verbose("License version 2 and other licenses; you are welcome to redistribute it under\n"); \
- ast_verbose("certain conditions. Type 'core show license' for details.\n"); \
- ast_verbose("=========================================================================\n")
-
-/*! \defgroup main_options Main Configuration Options
- \brief Main configuration options from \ref Config_ast "asterisk.conf" or
- the operating system command line when starting Asterisk
- Some of them can be changed in the CLI
- */
-/*! @{ */
-
-struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
-
-int option_verbose; /*!< Verbosity level */
-int option_debug; /*!< Debug level */
-
-double option_maxload; /*!< Max load avg on system */
-int option_maxcalls; /*!< Max number of active calls */
-
-/*! @} */
-
-char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR;
-char debug_filename[AST_FILENAME_MAX] = "";
-
-static int ast_socket = -1; /*!< UNIX Socket for allowing remote control */
-static int ast_consock = -1; /*!< UNIX Socket for controlling another asterisk */
-pid_t ast_mainpid;
-struct console {
- int fd; /*!< File descriptor */
- int p[2]; /*!< Pipe */
- pthread_t t; /*!< Thread of handler */
- int mute; /*!< Is the console muted for logs */
-};
-
-struct ast_atexit {
- void (*func)(void);
- AST_LIST_ENTRY(ast_atexit) list;
-};
-
-static AST_LIST_HEAD_STATIC(atexits, ast_atexit);
-
-time_t ast_startuptime;
-time_t ast_lastreloadtime;
-
-static History *el_hist;
-static EditLine *el;
-static char *remotehostname;
-
-struct console consoles[AST_MAX_CONNECTS];
-
-char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE;
-
-static int ast_el_add_history(char *);
-static int ast_el_read_history(char *);
-static int ast_el_write_history(char *);
-
-char ast_config_AST_CONFIG_DIR[PATH_MAX];
-char ast_config_AST_CONFIG_FILE[PATH_MAX];
-char ast_config_AST_MODULE_DIR[PATH_MAX];
-char ast_config_AST_SPOOL_DIR[PATH_MAX];
-char ast_config_AST_MONITOR_DIR[PATH_MAX];
-char ast_config_AST_VAR_DIR[PATH_MAX];
-char ast_config_AST_DATA_DIR[PATH_MAX];
-char ast_config_AST_LOG_DIR[PATH_MAX];
-char ast_config_AST_AGI_DIR[PATH_MAX];
-char ast_config_AST_DB[PATH_MAX];
-char ast_config_AST_KEY_DIR[PATH_MAX];
-char ast_config_AST_PID[PATH_MAX];
-char ast_config_AST_SOCKET[PATH_MAX];
-char ast_config_AST_RUN_DIR[PATH_MAX];
-char ast_config_AST_RUN_USER[PATH_MAX];
-char ast_config_AST_RUN_GROUP[PATH_MAX];
-char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
-char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0";
-char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0";
-char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl";
-char ast_config_AST_SYSTEM_NAME[20] = "";
-
-extern const char *ast_build_hostname;
-extern const char *ast_build_kernel;
-extern const char *ast_build_machine;
-extern const char *ast_build_os;
-extern const char *ast_build_date;
-extern const char *ast_build_user;
-
-static char *_argv[256];
-static int shuttingdown;
-static int restartnow;
-static pthread_t consolethread = AST_PTHREADT_NULL;
-
-static char randompool[256];
-
-static int sig_alert_pipe[2] = { -1, -1 };
-static struct {
- unsigned int need_reload:1;
- unsigned int need_quit:1;
-} sig_flags;
-
-#if !defined(LOW_MEMORY)
-struct file_version {
- AST_LIST_ENTRY(file_version) list;
- const char *file;
- char *version;
-};
-
-static AST_LIST_HEAD_STATIC(file_versions, file_version);
-
-void ast_register_file_version(const char *file, const char *version)
-{
- struct file_version *new;
- char *work;
- size_t version_length;
-
- work = ast_strdupa(version);
- work = ast_strip(ast_strip_quoted(work, "$", "$"));
- version_length = strlen(work) + 1;
-
- if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
- return;
-
- new->file = file;
- new->version = (char *) new + sizeof(*new);
- memcpy(new->version, work, version_length);
- AST_LIST_LOCK(&file_versions);
- AST_LIST_INSERT_HEAD(&file_versions, new, list);
- AST_LIST_UNLOCK(&file_versions);
-}
-
-void ast_unregister_file_version(const char *file)
-{
- struct file_version *find;
-
- AST_LIST_LOCK(&file_versions);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
- if (!strcasecmp(find->file, file)) {
- AST_LIST_REMOVE_CURRENT(&file_versions, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&file_versions);
- if (find)
- free(find);
-}
-
-struct thread_list_t {
- AST_LIST_ENTRY(thread_list_t) list;
- char *name;
- pthread_t id;
-};
-
-static AST_LIST_HEAD_STATIC(thread_list, thread_list_t);
-
-static char show_threads_help[] =
-"Usage: core show threads\n"
-" List threads currently active in the system.\n";
-
-void ast_register_thread(char *name)
-{
- struct thread_list_t *new = ast_calloc(1, sizeof(*new));
-
- if (!new)
- return;
- new->id = pthread_self();
- new->name = name; /* steal the allocated memory for the thread name */
- AST_LIST_LOCK(&thread_list);
- AST_LIST_INSERT_HEAD(&thread_list, new, list);
- AST_LIST_UNLOCK(&thread_list);
-}
-
-void ast_unregister_thread(void *id)
-{
- struct thread_list_t *x;
-
- AST_LIST_LOCK(&thread_list);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
- if ((void *) x->id == id) {
- AST_LIST_REMOVE_CURRENT(&thread_list, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&thread_list);
- if (x) {
- free(x->name);
- free(x);
- }
-}
-
-static int handle_show_threads(int fd, int argc, char *argv[])
-{
- int count = 0;
- struct thread_list_t *cur;
-
- AST_LIST_LOCK(&thread_list);
- AST_LIST_TRAVERSE(&thread_list, cur, list) {
- ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name);
- count++;
- }
- AST_LIST_UNLOCK(&thread_list);
- ast_cli(fd, "%d threads listed.\n", count);
- return 0;
-}
-
-struct profile_entry {
- const char *name;
- uint64_t scale; /* if non-zero, values are scaled by this */
- int64_t mark;
- int64_t value;
- int64_t events;
-};
-
-struct profile_data {
- int entries;
- int max_size;
- struct profile_entry e[0];
-};
-
-static struct profile_data *prof_data;
-
-/*! \brief allocates a counter with a given name and scale.
- * \return Returns the identifier of the counter.
- */
-int ast_add_profile(const char *name, uint64_t scale)
-{
- int l = sizeof(struct profile_data);
- int n = 10; /* default entries */
-
- if (prof_data == NULL) {
- prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
- if (prof_data == NULL)
- return -1;
- prof_data->entries = 0;
- prof_data->max_size = n;
- }
- if (prof_data->entries >= prof_data->max_size) {
- void *p;
- n = prof_data->max_size + 20;
- p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
- if (p == NULL)
- return -1;
- prof_data = p;
- prof_data->max_size = n;
- }
- n = prof_data->entries++;
- prof_data->e[n].name = ast_strdup(name);
- prof_data->e[n].value = 0;
- prof_data->e[n].events = 0;
- prof_data->e[n].mark = 0;
- prof_data->e[n].scale = scale;
- return n;
-}
-
-int64_t ast_profile(int i, int64_t delta)
-{
- if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
- return 0;
- if (prof_data->e[i].scale > 1)
- delta /= prof_data->e[i].scale;
- prof_data->e[i].value += delta;
- prof_data->e[i].events++;
- return prof_data->e[i].value;
-}
-
-#if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
-#if defined(__FreeBSD__)
-#include <machine/cpufunc.h>
-#elif defined(linux)
-static __inline uint64_t
-rdtsc(void)
-{
- uint64_t rv;
-
- __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
- return (rv);
-}
-#endif
-#else /* supply a dummy function on other platforms */
-static __inline uint64_t
-rdtsc(void)
-{
- return 0;
-}
-#endif
-
-int64_t ast_mark(int i, int startstop)
-{
- if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
- return 0;
- if (startstop == 1)
- prof_data->e[i].mark = rdtsc();
- else {
- prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
- if (prof_data->e[i].scale > 1)
- prof_data->e[i].mark /= prof_data->e[i].scale;
- prof_data->e[i].value += prof_data->e[i].mark;
- prof_data->e[i].events++;
- }
- return prof_data->e[i].mark;
-}
-
-static int handle_show_profile_deprecated(int fd, int argc, char *argv[])
-{
- int i, min, max;
- char *search = NULL;
-
- if (prof_data == NULL)
- return 0;
-
- min = 0;
- max = prof_data->entries;
- if (argc >= 3) { /* specific entries */
- if (isdigit(argv[2][0])) {
- min = atoi(argv[2]);
- if (argc == 4 && strcmp(argv[3], "-"))
- max = atoi(argv[3]);
- } else
- search = argv[2];
- }
- if (max > prof_data->entries)
- max = prof_data->entries;
- if (!strcmp(argv[0], "clear")) {
- for (i= min; i < max; i++) {
- if (!search || strstr(prof_data->e[i].name, search)) {
- prof_data->e[i].value = 0;
- prof_data->e[i].events = 0;
- }
- }
- return 0;
- }
- ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
- prof_data->entries, prof_data->max_size);
- ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
- "Value", "Average", "Name");
- for (i = min; i < max; i++) {
- struct profile_entry *e = &prof_data->e[i];
- if (!search || strstr(prof_data->e[i].name, search))
- ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
- i,
- (long)e->scale,
- (long)e->events, (long long)e->value,
- (long long)(e->events ? e->value / e->events : e->value),
- e->name);
- }
- return 0;
-}
-
-static int handle_show_profile(int fd, int argc, char *argv[])
-{
- int i, min, max;
- char *search = NULL;
-
- if (prof_data == NULL)
- return 0;
-
- min = 0;
- max = prof_data->entries;
- if (argc > 3) { /* specific entries */
- if (isdigit(argv[3][0])) {
- min = atoi(argv[3]);
- if (argc == 5 && strcmp(argv[4], "-"))
- max = atoi(argv[4]);
- } else
- search = argv[3];
- }
- if (max > prof_data->entries)
- max = prof_data->entries;
- if (!strcmp(argv[1], "clear")) {
- for (i= min; i < max; i++) {
- if (!search || strstr(prof_data->e[i].name, search)) {
- prof_data->e[i].value = 0;
- prof_data->e[i].events = 0;
- }
- }
- return 0;
- }
- ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
- prof_data->entries, prof_data->max_size);
- ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
- "Value", "Average", "Name");
- for (i = min; i < max; i++) {
- struct profile_entry *e = &prof_data->e[i];
- if (!search || strstr(prof_data->e[i].name, search))
- ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
- i,
- (long)e->scale,
- (long)e->events, (long long)e->value,
- (long long)(e->events ? e->value / e->events : e->value),
- e->name);
- }
- return 0;
-}
-
-static char show_version_files_help[] =
-"Usage: core show file version [like <pattern>]\n"
-" Lists the revision numbers of the files used to build this copy of Asterisk.\n"
-" Optional regular expression pattern is used to filter the file list.\n";
-
-/*! \brief CLI command to list module versions */
-static int handle_show_version_files_deprecated(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-25.25s %-40.40s\n"
- struct file_version *iterator;
- regex_t regexbuf;
- int havepattern = 0;
- int havename = 0;
- int count_files = 0;
-
- switch (argc) {
- case 5:
- if (!strcasecmp(argv[3], "like")) {
- if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = 1;
- } else
- return RESULT_SHOWUSAGE;
- break;
- case 4:
- havename = 1;
- break;
- case 3:
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
- ast_cli(fd, FORMAT, "File", "Revision");
- ast_cli(fd, FORMAT, "----", "--------");
- AST_LIST_LOCK(&file_versions);
- AST_LIST_TRAVERSE(&file_versions, iterator, list) {
- if (havename && strcasecmp(iterator->file, argv[3]))
- continue;
-
- if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
- continue;
-
- ast_cli(fd, FORMAT, iterator->file, iterator->version);
- count_files++;
- if (havename)
- break;
- }
- AST_LIST_UNLOCK(&file_versions);
- if (!havename) {
- ast_cli(fd, "%d files listed.\n", count_files);
- }
-
- if (havepattern)
- regfree(&regexbuf);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-}
-
-static int handle_show_version_files(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-25.25s %-40.40s\n"
- struct file_version *iterator;
- regex_t regexbuf;
- int havepattern = 0;
- int havename = 0;
- int count_files = 0;
-
- switch (argc) {
- case 6:
- if (!strcasecmp(argv[4], "like")) {
- if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = 1;
- } else
- return RESULT_SHOWUSAGE;
- break;
- case 5:
- havename = 1;
- break;
- case 4:
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
-
- ast_cli(fd, FORMAT, "File", "Revision");
- ast_cli(fd, FORMAT, "----", "--------");
- AST_LIST_LOCK(&file_versions);
- AST_LIST_TRAVERSE(&file_versions, iterator, list) {
- if (havename && strcasecmp(iterator->file, argv[4]))
- continue;
-
- if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
- continue;
-
- ast_cli(fd, FORMAT, iterator->file, iterator->version);
- count_files++;
- if (havename)
- break;
- }
- AST_LIST_UNLOCK(&file_versions);
- if (!havename) {
- ast_cli(fd, "%d files listed.\n", count_files);
- }
-
- if (havepattern)
- regfree(&regexbuf);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-}
-
-static char *complete_show_version_files_deprecated(const char *line, const char *word, int pos, int state)
-{
- struct file_version *find;
- int which = 0;
- char *ret = NULL;
- int matchlen = strlen(word);
-
- if (pos != 3)
- return NULL;
-
- AST_LIST_LOCK(&file_versions);
- AST_LIST_TRAVERSE(&file_versions, find, list) {
- if (!strncasecmp(word, find->file, matchlen) && ++which > state) {
- ret = ast_strdup(find->file);
- break;
- }
- }
- AST_LIST_UNLOCK(&file_versions);
-
- return ret;
-}
-
-static char *complete_show_version_files(const char *line, const char *word, int pos, int state)
-{
- struct file_version *find;
- int which = 0;
- char *ret = NULL;
- int matchlen = strlen(word);
-
- if (pos != 4)
- return NULL;
-
- AST_LIST_LOCK(&file_versions);
- AST_LIST_TRAVERSE(&file_versions, find, list) {
- if (!strncasecmp(word, find->file, matchlen) && ++which > state) {
- ret = ast_strdup(find->file);
- break;
- }
- }
- AST_LIST_UNLOCK(&file_versions);
-
- return ret;
-}
-
-#endif /* ! LOW_MEMORY */
-
-int ast_register_atexit(void (*func)(void))
-{
- struct ast_atexit *ae;
-
- if (!(ae = ast_calloc(1, sizeof(*ae))))
- return -1;
-
- ae->func = func;
-
- ast_unregister_atexit(func);
-
- AST_LIST_LOCK(&atexits);
- AST_LIST_INSERT_HEAD(&atexits, ae, list);
- AST_LIST_UNLOCK(&atexits);
-
- return 0;
-}
-
-void ast_unregister_atexit(void (*func)(void))
-{
- struct ast_atexit *ae = NULL;
-
- AST_LIST_LOCK(&atexits);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
- if (ae->func == func) {
- AST_LIST_REMOVE_CURRENT(&atexits, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&atexits);
-
- if (ae)
- free(ae);
-}
-
-static int fdprint(int fd, const char *s)
-{
- return write(fd, s, strlen(s) + 1);
-}
-
-/*! \brief NULL handler so we can collect the child exit status */
-static void null_sig_handler(int signal)
-{
-
-}
-
-AST_MUTEX_DEFINE_STATIC(safe_system_lock);
-/*! \brief Keep track of how many threads are currently trying to wait*() on
- * a child process */
-static unsigned int safe_system_level = 0;
-static void *safe_system_prev_handler;
-
-void ast_replace_sigchld(void)
-{
- unsigned int level;
-
- ast_mutex_lock(&safe_system_lock);
- level = safe_system_level++;
-
- /* only replace the handler if it has not already been done */
- if (level == 0)
- safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
-
- ast_mutex_unlock(&safe_system_lock);
-}
-
-void ast_unreplace_sigchld(void)
-{
- unsigned int level;
-
- ast_mutex_lock(&safe_system_lock);
- level = --safe_system_level;
-
- /* only restore the handler if we are the last one */
- if (level == 0)
- signal(SIGCHLD, safe_system_prev_handler);
-
- ast_mutex_unlock(&safe_system_lock);
-}
-
-int ast_safe_system(const char *s)
-{
- pid_t pid;
-#ifdef HAVE_WORKING_FORK
- int x;
-#endif
- int res;
- struct rusage rusage;
- int status;
-
-#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
- ast_replace_sigchld();
-
-#ifdef HAVE_WORKING_FORK
- pid = fork();
-#else
- pid = vfork();
-#endif
-
- if (pid == 0) {
-#ifdef HAVE_WORKING_FORK
- if (ast_opt_high_priority)
- ast_set_priority(0);
- /* Close file descriptors and launch system command */
- for (x = STDERR_FILENO + 1; x < 4096; x++)
- close(x);
-#endif
- execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
- _exit(1);
- } else if (pid > 0) {
- for(;;) {
- res = wait4(pid, &status, 0, &rusage);
- if (res > -1) {
- res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
- break;
- } else if (errno != EINTR)
- break;
- }
- } else {
- ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
- res = -1;
- }
-
- ast_unreplace_sigchld();
-#else
- res = -1;
-#endif
-
- return res;
-}
-
-/*!
- * \brief mute or unmute a console from logging
- */
-void ast_console_toggle_mute(int fd, int silent) {
- int x;
- for (x = 0;x < AST_MAX_CONNECTS; x++) {
- if (fd == consoles[x].fd) {
- if (consoles[x].mute) {
- consoles[x].mute = 0;
- if (!silent)
- ast_cli(fd, "Console is not muted anymore.\n");
- } else {
- consoles[x].mute = 1;
- if (!silent)
- ast_cli(fd, "Console is muted.\n");
- }
- return;
- }
- }
- ast_cli(fd, "Couldn't find remote console.\n");
-}
-
-/*!
- * \brief log the string to all attached console clients
- */
-static void ast_network_puts_mutable(const char *string)
-{
- int x;
- for (x = 0;x < AST_MAX_CONNECTS; x++) {
- if (consoles[x].mute)
- continue;
- if (consoles[x].fd > -1)
- fdprint(consoles[x].p[1], string);
- }
-}
-
-/*!
- * \brief log the string to the console, and all attached
- * console clients
- */
-void ast_console_puts_mutable(const char *string)
-{
- fputs(string, stdout);
- fflush(stdout);
- ast_network_puts_mutable(string);
-}
-
-/*!
- * \brief write the string to all attached console clients
- */
-static void ast_network_puts(const char *string)
-{
- int x;
- for (x=0; x < AST_MAX_CONNECTS; x++) {
- if (consoles[x].fd > -1)
- fdprint(consoles[x].p[1], string);
- }
-}
-
-/*!
- * write the string to the console, and all attached
- * console clients
- */
-void ast_console_puts(const char *string)
-{
- fputs(string, stdout);
- fflush(stdout);
- ast_network_puts(string);
-}
-
-static void network_verboser(const char *s)
-{
- ast_network_puts_mutable(s);
-}
-
-static pthread_t lthread;
-
-static void *netconsole(void *vconsole)
-{
- struct console *con = vconsole;
- char hostname[MAXHOSTNAMELEN] = "";
- char tmp[512];
- int res;
- struct pollfd fds[2];
-
- if (gethostname(hostname, sizeof(hostname)-1))
- ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
- snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ASTERISK_VERSION);
- fdprint(con->fd, tmp);
- for(;;) {
- fds[0].fd = con->fd;
- fds[0].events = POLLIN;
- fds[0].revents = 0;
- fds[1].fd = con->p[0];
- fds[1].events = POLLIN;
- fds[1].revents = 0;
-
- res = poll(fds, 2, -1);
- if (res < 0) {
- if (errno != EINTR)
- ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
- continue;
- }
- if (fds[0].revents) {
- res = read(con->fd, tmp, sizeof(tmp));
- if (res < 1) {
- break;
- }
- tmp[res] = 0;
- ast_cli_command_multiple(con->fd, res, tmp);
- }
- if (fds[1].revents) {
- res = read(con->p[0], tmp, sizeof(tmp));
- if (res < 1) {
- ast_log(LOG_ERROR, "read returned %d\n", res);
- break;
- }
- res = write(con->fd, tmp, res);
- if (res < 1)
- break;
- }
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n");
- close(con->fd);
- close(con->p[0]);
- close(con->p[1]);
- con->fd = -1;
-
- return NULL;
-}
-
-static void *listener(void *unused)
-{
- struct sockaddr_un sunaddr;
- int s;
- socklen_t len;
- int x;
- int flags;
- struct pollfd fds[1];
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- for (;;) {
- if (ast_socket < 0)
- return NULL;
- fds[0].fd = ast_socket;
- fds[0].events = POLLIN;
- s = poll(fds, 1, -1);
- pthread_testcancel();
- if (s < 0) {
- if (errno != EINTR)
- ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
- continue;
- }
- len = sizeof(sunaddr);
- s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
- if (s < 0) {
- if (errno != EINTR)
- ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
- } else {
- for (x = 0; x < AST_MAX_CONNECTS; x++) {
- if (consoles[x].fd < 0) {
- if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
- ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
- consoles[x].fd = -1;
- fdprint(s, "Server failed to create pipe\n");
- close(s);
- break;
- }
- flags = fcntl(consoles[x].p[1], F_GETFL);
- fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
- consoles[x].fd = s;
- consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
- if (ast_pthread_create_background(&consoles[x].t, &attr, netconsole, &consoles[x])) {
- ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
- close(consoles[x].p[0]);
- close(consoles[x].p[1]);
- consoles[x].fd = -1;
- fdprint(s, "Server failed to spawn thread\n");
- close(s);
- }
- break;
- }
- }
- if (x >= AST_MAX_CONNECTS) {
- fdprint(s, "No more connections allowed\n");
- ast_log(LOG_WARNING, "No more connections allowed\n");
- close(s);
- } else if (consoles[x].fd > -1) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n");
- }
- }
- }
- return NULL;
-}
-
-static int ast_makesocket(void)
-{
- struct sockaddr_un sunaddr;
- int res;
- int x;
- uid_t uid = -1;
- gid_t gid = -1;
-
- for (x = 0; x < AST_MAX_CONNECTS; x++)
- consoles[x].fd = -1;
- unlink(ast_config_AST_SOCKET);
- ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (ast_socket < 0) {
- ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
- return -1;
- }
- memset(&sunaddr, 0, sizeof(sunaddr));
- sunaddr.sun_family = AF_LOCAL;
- ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
- res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
- if (res) {
- ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
- close(ast_socket);
- ast_socket = -1;
- return -1;
- }
- res = listen(ast_socket, 2);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
- close(ast_socket);
- ast_socket = -1;
- return -1;
- }
- ast_register_verbose(network_verboser);
- ast_pthread_create_background(&lthread, NULL, listener, NULL);
-
- if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
- struct passwd *pw;
- if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) {
- ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
- } else {
- uid = pw->pw_uid;
- }
- }
-
- if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
- struct group *grp;
- if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) {
- ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
- } else {
- gid = grp->gr_gid;
- }
- }
-
- if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
- ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
-
- if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
- int p1;
- mode_t p;
- sscanf(ast_config_AST_CTL_PERMISSIONS, "%o", &p1);
- p = p1;
- if ((chmod(ast_config_AST_SOCKET, p)) < 0)
- ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
- }
-
- return 0;
-}
-
-static int ast_tryconnect(void)
-{
- struct sockaddr_un sunaddr;
- int res;
- ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (ast_consock < 0) {
- ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
- return 0;
- }
- memset(&sunaddr, 0, sizeof(sunaddr));
- sunaddr.sun_family = AF_LOCAL;
- ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
- res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
- if (res) {
- close(ast_consock);
- ast_consock = -1;
- return 0;
- } else
- return 1;
-}
-
-/*! \brief Urgent handler
-
- Called by soft_hangup to interrupt the poll, read, or other
- system call. We don't actually need to do anything though.
- Remember: Cannot EVER ast_log from within a signal handler
- */
-static void urg_handler(int num)
-{
- signal(num, urg_handler);
- return;
-}
-
-static void hup_handler(int num)
-{
- int a = 0;
- if (option_verbose > 1)
- printf("Received HUP signal -- Reloading configs\n");
- if (restartnow)
- execvp(_argv[0], _argv);
- sig_flags.need_reload = 1;
- if (sig_alert_pipe[1] != -1)
- write(sig_alert_pipe[1], &a, sizeof(a));
- signal(num, hup_handler);
-}
-
-static void child_handler(int sig)
-{
- /* Must not ever ast_log or ast_verbose within signal handler */
- int n, status;
-
- /*
- * Reap all dead children -- not just one
- */
- for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
- ;
- if (n == 0 && option_debug)
- printf("Huh? Child handler, but nobody there?\n");
- signal(sig, child_handler);
-}
-
-/*! \brief Set an X-term or screen title */
-static void set_title(char *text)
-{
- if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
- fprintf(stdout, "\033]2;%s\007", text);
-}
-
-static void set_icon(char *text)
-{
- if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
- fprintf(stdout, "\033]1;%s\007", text);
-}
-
-/*! \brief We set ourselves to a high priority, that we might pre-empt everything
- else. If your PBX has heavy activity on it, this is a good thing. */
-int ast_set_priority(int pri)
-{
- struct sched_param sched;
- memset(&sched, 0, sizeof(sched));
-#ifdef __linux__
- if (pri) {
- sched.sched_priority = 10;
- if (sched_setscheduler(0, SCHED_RR, &sched)) {
- ast_log(LOG_WARNING, "Unable to set high priority\n");
- return -1;
- } else
- if (option_verbose)
- ast_verbose("Set to realtime thread\n");
- } else {
- sched.sched_priority = 0;
- /* According to the manpage, these parameters can never fail. */
- sched_setscheduler(0, SCHED_OTHER, &sched);
- }
-#else
- if (pri) {
- if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
- ast_log(LOG_WARNING, "Unable to set high priority\n");
- return -1;
- } else
- if (option_verbose)
- ast_verbose("Set to high priority\n");
- } else {
- /* According to the manpage, these parameters can never fail. */
- setpriority(PRIO_PROCESS, 0, 0);
- }
-#endif
- return 0;
-}
-
-static void ast_run_atexits(void)
-{
- struct ast_atexit *ae;
- AST_LIST_LOCK(&atexits);
- AST_LIST_TRAVERSE(&atexits, ae, list) {
- if (ae->func)
- ae->func();
- }
- AST_LIST_UNLOCK(&atexits);
-}
-
-static void quit_handler(int num, int nice, int safeshutdown, int restart)
-{
- char filename[80] = "";
- time_t s,e;
- int x;
- /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
- ast_cdr_engine_term();
- if (safeshutdown) {
- shuttingdown = 1;
- if (!nice) {
- /* Begin shutdown routine, hanging up active channels */
- ast_begin_shutdown(1);
- if (option_verbose && ast_opt_console)
- ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
- time(&s);
- for (;;) {
- time(&e);
- /* Wait up to 15 seconds for all channels to go away */
- if ((e - s) > 15)
- break;
- if (!ast_active_channels())
- break;
- if (!shuttingdown)
- break;
- /* Sleep 1/10 of a second */
- usleep(100000);
- }
- } else {
- if (nice < 2)
- ast_begin_shutdown(0);
- if (option_verbose && ast_opt_console)
- ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
- for (;;) {
- if (!ast_active_channels())
- break;
- if (!shuttingdown)
- break;
- sleep(1);
- }
- }
-
- if (!shuttingdown) {
- if (option_verbose && ast_opt_console)
- ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
- return;
- }
-
- if (nice)
- ast_module_shutdown();
- }
- if (ast_opt_console || ast_opt_remote) {
- if (getenv("HOME"))
- snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
- if (!ast_strlen_zero(filename))
- ast_el_write_history(filename);
- if (el != NULL)
- el_end(el);
- if (el_hist != NULL)
- history_end(el_hist);
- }
- if (option_verbose)
- ast_verbose("Executing last minute cleanups\n");
- ast_run_atexits();
- /* Called on exit */
- if (option_verbose && ast_opt_console)
- ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
- if (option_debug)
- ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num);
- manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
- if (ast_socket > -1) {
- pthread_cancel(lthread);
- close(ast_socket);
- ast_socket = -1;
- unlink(ast_config_AST_SOCKET);
- }
- if (ast_consock > -1)
- close(ast_consock);
- if (!ast_opt_remote)
- unlink(ast_config_AST_PID);
- printf(term_quit());
- if (restart) {
- if (option_verbose || ast_opt_console)
- ast_verbose("Preparing for Asterisk restart...\n");
- /* Mark all FD's for closing on exec */
- for (x=3; x < 32768; x++) {
- fcntl(x, F_SETFD, FD_CLOEXEC);
- }
- if (option_verbose || ast_opt_console)
- ast_verbose("Asterisk is now restarting...\n");
- restartnow = 1;
-
- /* close logger */
- close_logger();
-
- /* If there is a consolethread running send it a SIGHUP
- so it can execvp, otherwise we can do it ourselves */
- if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
- pthread_kill(consolethread, SIGHUP);
- /* Give the signal handler some time to complete */
- sleep(2);
- } else
- execvp(_argv[0], _argv);
-
- } else {
- /* close logger */
- close_logger();
- }
- exit(0);
-}
-
-static void __quit_handler(int num)
-{
- int a = 0;
- sig_flags.need_quit = 1;
- if (sig_alert_pipe[1] != -1)
- write(sig_alert_pipe[1], &a, sizeof(a));
- /* There is no need to restore the signal handler here, since the app
- * is going to exit */
-}
-
-static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp)
-{
- const char *c;
-
- /* Check for verboser preamble */
- if (*s == 127) {
- s++;
- }
-
- if (!strncmp(s, cmp, strlen(cmp))) {
- c = s + strlen(cmp);
- term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
- return c;
- }
- return NULL;
-}
-
-static void console_verboser(const char *s)
-{
- char tmp[80];
- const char *c = NULL;
-
- if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
- (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
- (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
- (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
- fputs(tmp, stdout);
- fputs(c, stdout);
- } else
- fputs(s, stdout);
-
- fflush(stdout);
-
- /* Wake up a poll()ing console */
- if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
- pthread_kill(consolethread, SIGURG);
-}
-
-static int ast_all_zeros(char *s)
-{
- while (*s) {
- if (*s > 32)
- return 0;
- s++;
- }
- return 1;
-}
-
-static void consolehandler(char *s)
-{
- printf(term_end());
- fflush(stdout);
-
- /* Called when readline data is available */
- if (!ast_all_zeros(s))
- ast_el_add_history(s);
- /* The real handler for bang */
- if (s[0] == '!') {
- if (s[1])
- ast_safe_system(s+1);
- else
- ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
- } else
- ast_cli_command(STDOUT_FILENO, s);
-}
-
-static int remoteconsolehandler(char *s)
-{
- int ret = 0;
-
- /* Called when readline data is available */
- if (!ast_all_zeros(s))
- ast_el_add_history(s);
- /* The real handler for bang */
- if (s[0] == '!') {
- if (s[1])
- ast_safe_system(s+1);
- else
- ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
- ret = 1;
- }
- if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
- (s[4] == '\0' || isspace(s[4]))) {
- quit_handler(0, 0, 0, 0);
- ret = 1;
- }
-
- return ret;
-}
-
-static char abort_halt_help[] =
-"Usage: abort shutdown\n"
-" Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
-" call operations.\n";
-
-static char shutdown_now_help[] =
-"Usage: stop now\n"
-" Shuts down a running Asterisk immediately, hanging up all active calls .\n";
-
-static char shutdown_gracefully_help[] =
-"Usage: stop gracefully\n"
-" Causes Asterisk to not accept new calls, and exit when all\n"
-" active calls have terminated normally.\n";
-
-static char shutdown_when_convenient_help[] =
-"Usage: stop when convenient\n"
-" Causes Asterisk to perform a shutdown when all active calls have ended.\n";
-
-static char restart_now_help[] =
-"Usage: restart now\n"
-" Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
-" restart.\n";
-
-static char restart_gracefully_help[] =
-"Usage: restart gracefully\n"
-" Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
-" restart when all active calls have ended.\n";
-
-static char restart_when_convenient_help[] =
-"Usage: restart when convenient\n"
-" Causes Asterisk to perform a cold restart when all active calls have ended.\n";
-
-static char bang_help[] =
-"Usage: !<command>\n"
-" Executes a given shell command\n";
-
-static char show_warranty_help[] =
-"Usage: core show warranty\n"
-" Shows the warranty (if any) for this copy of Asterisk.\n";
-
-static char show_license_help[] =
-"Usage: core show license\n"
-" Shows the license(s) for this copy of Asterisk.\n";
-
-static char version_help[] =
-"Usage: core show version\n"
-" Shows Asterisk version information.\n";
-
-static int handle_version_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
- ASTERISK_VERSION, ast_build_user, ast_build_hostname,
- ast_build_machine, ast_build_os, ast_build_date);
- return RESULT_SUCCESS;
-}
-
-static int handle_version(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
- ASTERISK_VERSION, ast_build_user, ast_build_hostname,
- ast_build_machine, ast_build_os, ast_build_date);
- return RESULT_SUCCESS;
-}
-
-#if 0
-static int handle_quit(int fd, int argc, char *argv[])
-{
- if (argc != 1)
- return RESULT_SHOWUSAGE;
- quit_handler(0, 0, 1, 0);
- return RESULT_SUCCESS;
-}
-#endif
-
-static int handle_shutdown_now(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
- return RESULT_SUCCESS;
-}
-
-static int handle_shutdown_gracefully(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
- return RESULT_SUCCESS;
-}
-
-static int handle_shutdown_when_convenient(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, "Waiting for inactivity to perform halt\n");
- quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
- return RESULT_SUCCESS;
-}
-
-static int handle_restart_now(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
- return RESULT_SUCCESS;
-}
-
-static int handle_restart_gracefully(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
- return RESULT_SUCCESS;
-}
-
-static int handle_restart_when_convenient(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, "Waiting for inactivity to perform restart\n");
- quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
- return RESULT_SUCCESS;
-}
-
-static int handle_abort_halt(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- ast_cancel_shutdown();
- shuttingdown = 0;
- return RESULT_SUCCESS;
-}
-
-static int handle_bang(int fd, int argc, char *argv[])
-{
- return RESULT_SUCCESS;
-}
-static const char *warranty_lines[] = {
- "\n",
- " NO WARRANTY\n",
- "\n",
- "BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n",
- "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n",
- "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n",
- "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n",
- "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n",
- "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n",
- "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n",
- "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n",
- "REPAIR OR CORRECTION.\n",
- "\n",
- "IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n",
- "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n",
- "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n",
- "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n",
- "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n",
- "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n",
- "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n",
- "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n",
- "POSSIBILITY OF SUCH DAMAGES.\n",
-};
-
-static int show_warranty(int fd, int argc, char *argv[])
-{
- int x;
-
- for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++)
- ast_cli(fd, (char *) warranty_lines[x]);
-
- return RESULT_SUCCESS;
-}
-
-static const char *license_lines[] = {
- "\n",
- "This program is free software; you can redistribute it and/or modify\n",
- "it under the terms of the GNU General Public License version 2 as\n",
- "published by the Free Software Foundation.\n",
- "\n",
- "This program also contains components licensed under other licenses.\n",
- "They include:\n",
- "\n",
- "This program is distributed in the hope that it will be useful,\n",
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n",
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n",
- "GNU General Public License for more details.\n",
- "\n",
- "You should have received a copy of the GNU General Public License\n",
- "along with this program; if not, write to the Free Software\n",
- "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n",
-};
-
-static int show_license(int fd, int argc, char *argv[])
-{
- int x;
-
- for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++)
- ast_cli(fd, (char *) license_lines[x]);
-
- return RESULT_SUCCESS;
-}
-
-#define ASTERISK_PROMPT "*CLI> "
-
-#define ASTERISK_PROMPT2 "%s*CLI> "
-
-static struct ast_cli_entry cli_show_version_deprecated = {
- { "show", "version", NULL },
- handle_version_deprecated, "Display version info",
- version_help };
-
-#if !defined(LOW_MEMORY)
-static struct ast_cli_entry cli_show_version_files_deprecated = {
- { "show", "version", "files", NULL },
- handle_show_version_files_deprecated, NULL,
- NULL, complete_show_version_files_deprecated };
-
-static struct ast_cli_entry cli_show_profile_deprecated = {
- { "show", "profile", NULL },
- handle_show_profile_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_clear_profile_deprecated = {
- { "clear", "profile", NULL },
- handle_show_profile_deprecated, NULL,
- NULL };
-#endif /* ! LOW_MEMORY */
-
-static struct ast_cli_entry cli_asterisk[] = {
- { { "abort", "halt", NULL },
- handle_abort_halt, "Cancel a running halt",
- abort_halt_help },
-
- { { "stop", "now", NULL },
- handle_shutdown_now, "Shut down Asterisk immediately",
- shutdown_now_help },
-
- { { "stop", "gracefully", NULL },
- handle_shutdown_gracefully, "Gracefully shut down Asterisk",
- shutdown_gracefully_help },
-
- { { "stop", "when", "convenient", NULL },
- handle_shutdown_when_convenient, "Shut down Asterisk at empty call volume",
- shutdown_when_convenient_help },
-
- { { "restart", "now", NULL },
- handle_restart_now, "Restart Asterisk immediately", restart_now_help },
-
- { { "restart", "gracefully", NULL },
- handle_restart_gracefully, "Restart Asterisk gracefully",
- restart_gracefully_help },
-
- { { "restart", "when", "convenient", NULL },
- handle_restart_when_convenient, "Restart Asterisk at empty call volume",
- restart_when_convenient_help },
-
- { { "core", "show", "warranty", NULL },
- show_warranty, "Show the warranty (if any) for this copy of Asterisk",
- show_warranty_help },
-
- { { "core", "show", "license", NULL },
- show_license, "Show the license(s) for this copy of Asterisk",
- show_license_help },
-
- { { "core", "show", "version", NULL },
- handle_version, "Display version info",
- version_help, NULL, &cli_show_version_deprecated },
-
- { { "!", NULL },
- handle_bang, "Execute a shell command",
- bang_help },
-
-#if !defined(LOW_MEMORY)
- { { "core", "show", "file", "version", NULL },
- handle_show_version_files, "List versions of files used to build Asterisk",
- show_version_files_help, complete_show_version_files, &cli_show_version_files_deprecated },
-
- { { "core", "show", "threads", NULL },
- handle_show_threads, "Show running threads",
- show_threads_help },
-
- { { "core", "show", "profile", NULL },
- handle_show_profile, "Display profiling info",
- NULL, NULL, &cli_show_profile_deprecated },
-
- { { "core", "clear", "profile", NULL },
- handle_show_profile, "Clear profiling info",
- NULL, NULL, &cli_clear_profile_deprecated },
-#endif /* ! LOW_MEMORY */
-};
-
-static int ast_el_read_char(EditLine *el, char *cp)
-{
- int num_read = 0;
- int lastpos = 0;
- struct pollfd fds[2];
- int res;
- int max;
-#define EL_BUF_SIZE 512
- char buf[EL_BUF_SIZE];
-
- for (;;) {
- max = 1;
- fds[0].fd = ast_consock;
- fds[0].events = POLLIN;
- if (!ast_opt_exec) {
- fds[1].fd = STDIN_FILENO;
- fds[1].events = POLLIN;
- max++;
- }
- res = poll(fds, max, -1);
- if (res < 0) {
- if (errno == EINTR)
- continue;
- ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
- break;
- }
-
- if (!ast_opt_exec && fds[1].revents) {
- num_read = read(STDIN_FILENO, cp, 1);
- if (num_read < 1) {
- break;
- } else
- return (num_read);
- }
- if (fds[0].revents) {
- res = read(ast_consock, buf, sizeof(buf) - 1);
- /* if the remote side disappears exit */
- if (res < 1) {
- fprintf(stderr, "\nDisconnected from Asterisk server\n");
- if (!ast_opt_reconnect) {
- quit_handler(0, 0, 0, 0);
- } else {
- int tries;
- int reconnects_per_second = 20;
- fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
- for (tries=0; tries < 30 * reconnects_per_second; tries++) {
- if (ast_tryconnect()) {
- fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
- printf(term_quit());
- WELCOME_MESSAGE;
- if (!ast_opt_mute)
- fdprint(ast_consock, "logger mute silent");
- else
- printf("log and verbose output currently muted ('logger mute' to unmute)\n");
- break;
- } else {
- usleep(1000000 / reconnects_per_second);
- }
- }
- if (tries >= 30 * reconnects_per_second) {
- fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
- quit_handler(0, 0, 0, 0);
- }
- }
- }
-
- buf[res] = '\0';
-
- /* Write over the CLI prompt */
- if (!ast_opt_exec && !lastpos)
- write(STDOUT_FILENO, "\r", 1);
- write(STDOUT_FILENO, buf, res);
- if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
- *cp = CC_REFRESH;
- return(1);
- } else {
- lastpos = 1;
- }
- }
- }
-
- *cp = '\0';
- return (0);
-}
-
-static char *cli_prompt(EditLine *el)
-{
- static char prompt[200];
- char *pfmt;
- int color_used = 0;
- char term_code[20];
-
- if ((pfmt = getenv("ASTERISK_PROMPT"))) {
- char *t = pfmt, *p = prompt;
- memset(prompt, 0, sizeof(prompt));
- while (*t != '\0' && *p < sizeof(prompt)) {
- if (*t == '%') {
- char hostname[MAXHOSTNAMELEN]="";
- int i;
- time_t ts;
- struct tm tm;
-#ifdef linux
- FILE *LOADAVG;
-#endif
- int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
-
- t++;
- switch (*t) {
- case 'C': /* color */
- t++;
- if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
- strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
- t += i - 1;
- } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
- strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
- t += i - 1;
- }
-
- /* If the color has been reset correctly, then there's no need to reset it later */
- if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
- color_used = 0;
- } else {
- color_used = 1;
- }
- break;
- case 'd': /* date */
- memset(&tm, 0, sizeof(tm));
- time(&ts);
- if (ast_localtime(&ts, &tm, NULL)) {
- strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
- }
- break;
- case 'h': /* hostname */
- if (!gethostname(hostname, sizeof(hostname) - 1)) {
- strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
- } else {
- strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
- }
- break;
- case 'H': /* short hostname */
- if (!gethostname(hostname, sizeof(hostname) - 1)) {
- for (i = 0; i < sizeof(hostname); i++) {
- if (hostname[i] == '.') {
- hostname[i] = '\0';
- break;
- }
- }
- strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
- } else {
- strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
- }
- break;
-#ifdef linux
- case 'l': /* load avg */
- t++;
- if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
- float avg1, avg2, avg3;
- int actproc, totproc, npid, which;
- fscanf(LOADAVG, "%f %f %f %d/%d %d",
- &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
- if (sscanf(t, "%d", &which) == 1) {
- switch (which) {
- case 1:
- snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
- break;
- case 2:
- snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
- break;
- case 3:
- snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
- break;
- case 4:
- snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
- break;
- case 5:
- snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
- break;
- }
- }
- }
- break;
-#endif
- case 's': /* Asterisk system name (from asterisk.conf) */
- strncat(p, ast_config_AST_SYSTEM_NAME, sizeof(prompt) - strlen(prompt) - 1);
- break;
- case 't': /* time */
- memset(&tm, 0, sizeof(tm));
- time(&ts);
- if (ast_localtime(&ts, &tm, NULL)) {
- strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
- }
- break;
- case '#': /* process console or remote? */
- if (!ast_opt_remote) {
- strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
- } else {
- strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
- }
- break;
- case '%': /* literal % */
- strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
- break;
- case '\0': /* % is last character - prevent bug */
- t--;
- break;
- }
- while (*p != '\0') {
- p++;
- }
- t++;
- } else {
- *p = *t;
- p++;
- t++;
- }
- }
- if (color_used) {
- /* Force colors back to normal at end */
- term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
- if (strlen(term_code) > sizeof(prompt) - strlen(prompt) - 1) {
- ast_copy_string(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code) + 1);
- } else {
- /* This looks wrong, but we've already checked the length of term_code to ensure it's safe */
- strncat(p, term_code, sizeof(term_code));
- }
- }
- } else if (remotehostname)
- snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname);
- else
- snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT);
-
- return(prompt);
-}
-
-static char **ast_el_strtoarr(char *buf)
-{
- char **match_list = NULL, *retstr;
- size_t match_list_len;
- int matches = 0;
-
- match_list_len = 1;
- while ( (retstr = strsep(&buf, " ")) != NULL) {
-
- if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
- break;
- if (matches + 1 >= match_list_len) {
- match_list_len <<= 1;
- if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
- /* TODO: Handle memory allocation failure */
- }
- }
-
- match_list[matches++] = strdup(retstr);
- }
-
- if (!match_list)
- return (char **) NULL;
-
- if (matches >= match_list_len) {
- if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
- /* TODO: Handle memory allocation failure */
- }
- }
-
- match_list[matches] = (char *) NULL;
-
- return match_list;
-}
-
-static int ast_el_sort_compare(const void *i1, const void *i2)
-{
- char *s1, *s2;
-
- s1 = ((char **)i1)[0];
- s2 = ((char **)i2)[0];
-
- return strcasecmp(s1, s2);
-}
-
-static int ast_cli_display_match_list(char **matches, int len, int max)
-{
- int i, idx, limit, count;
- int screenwidth = 0;
- int numoutput = 0, numoutputline = 0;
-
- screenwidth = ast_get_termcols(STDOUT_FILENO);
-
- /* find out how many entries can be put on one line, with two spaces between strings */
- limit = screenwidth / (max + 2);
- if (limit == 0)
- limit = 1;
-
- /* how many lines of output */
- count = len / limit;
- if (count * limit < len)
- count++;
-
- idx = 1;
-
- qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
-
- for (; count > 0; count--) {
- numoutputline = 0;
- for (i=0; i < limit && matches[idx]; i++, idx++) {
-
- /* Don't print dupes */
- if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
- i--;
- free(matches[idx]);
- matches[idx] = NULL;
- continue;
- }
-
- numoutput++;
- numoutputline++;
- fprintf(stdout, "%-*s ", max, matches[idx]);
- free(matches[idx]);
- matches[idx] = NULL;
- }
- if (numoutputline > 0)
- fprintf(stdout, "\n");
- }
-
- return numoutput;
-}
-
-
-static char *cli_complete(EditLine *el, int ch)
-{
- int len = 0;
- char *ptr;
- int nummatches = 0;
- char **matches;
- int retval = CC_ERROR;
- char buf[2048];
- int res;
-
- LineInfo *lf = (LineInfo *)el_line(el);
-
- *(char *)lf->cursor = '\0';
- ptr = (char *)lf->cursor;
- if (ptr) {
- while (ptr > lf->buffer) {
- if (isspace(*ptr)) {
- ptr++;
- break;
- }
- ptr--;
- }
- }
-
- len = lf->cursor - ptr;
-
- if (ast_opt_remote) {
- snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
- fdprint(ast_consock, buf);
- res = read(ast_consock, buf, sizeof(buf));
- buf[res] = '\0';
- nummatches = atoi(buf);
-
- if (nummatches > 0) {
- char *mbuf;
- int mlen = 0, maxmbuf = 2048;
- /* Start with a 2048 byte buffer */
- if (!(mbuf = ast_malloc(maxmbuf)))
- return (char *)(CC_ERROR);
- snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
- fdprint(ast_consock, buf);
- res = 0;
- mbuf[0] = '\0';
- while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
- if (mlen + 1024 > maxmbuf) {
- /* Every step increment buffer 1024 bytes */
- maxmbuf += 1024;
- if (!(mbuf = ast_realloc(mbuf, maxmbuf)))
- return (char *)(CC_ERROR);
- }
- /* Only read 1024 bytes at a time */
- res = read(ast_consock, mbuf + mlen, 1024);
- if (res > 0)
- mlen += res;
- }
- mbuf[mlen] = '\0';
-
- matches = ast_el_strtoarr(mbuf);
- free(mbuf);
- } else
- matches = (char **) NULL;
- } else {
- char **p, *oldbuf=NULL;
- nummatches = 0;
- matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
- for (p = matches; p && *p; p++) {
- if (!oldbuf || strcmp(*p,oldbuf))
- nummatches++;
- oldbuf = *p;
- }
- }
-
- if (matches) {
- int i;
- int matches_num, maxlen, match_len;
-
- if (matches[0][0] != '\0') {
- el_deletestr(el, (int) len);
- el_insertstr(el, matches[0]);
- retval = CC_REFRESH;
- }
-
- if (nummatches == 1) {
- /* Found an exact match */
- el_insertstr(el, " ");
- retval = CC_REFRESH;
- } else {
- /* Must be more than one match */
- for (i=1, maxlen=0; matches[i]; i++) {
- match_len = strlen(matches[i]);
- if (match_len > maxlen)
- maxlen = match_len;
- }
- matches_num = i - 1;
- if (matches_num >1) {
- fprintf(stdout, "\n");
- ast_cli_display_match_list(matches, nummatches, maxlen);
- retval = CC_REDISPLAY;
- } else {
- el_insertstr(el," ");
- retval = CC_REFRESH;
- }
- }
- for (i = 0; matches[i]; i++)
- free(matches[i]);
- free(matches);
- }
-
- return (char *)(long)retval;
-}
-
-static int ast_el_initialize(void)
-{
- HistEvent ev;
- char *editor = getenv("AST_EDITOR");
-
- if (el != NULL)
- el_end(el);
- if (el_hist != NULL)
- history_end(el_hist);
-
- el = el_init("asterisk", stdin, stdout, stderr);
- el_set(el, EL_PROMPT, cli_prompt);
-
- el_set(el, EL_EDITMODE, 1);
- el_set(el, EL_EDITOR, editor ? editor : "emacs");
- el_hist = history_init();
- if (!el || !el_hist)
- return -1;
-
- /* setup history with 100 entries */
- history(el_hist, &ev, H_SETSIZE, 100);
-
- el_set(el, EL_HIST, history, el_hist);
-
- el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
- /* Bind <tab> to command completion */
- el_set(el, EL_BIND, "^I", "ed-complete", NULL);
- /* Bind ? to command completion */
- el_set(el, EL_BIND, "?", "ed-complete", NULL);
- /* Bind ^D to redisplay */
- el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
-
- return 0;
-}
-
-static int ast_el_add_history(char *buf)
-{
- HistEvent ev;
-
- if (el_hist == NULL || el == NULL)
- ast_el_initialize();
- if (strlen(buf) > 256)
- return 0;
- return (history(el_hist, &ev, H_ENTER, buf));
-}
-
-static int ast_el_write_history(char *filename)
-{
- HistEvent ev;
-
- if (el_hist == NULL || el == NULL)
- ast_el_initialize();
-
- return (history(el_hist, &ev, H_SAVE, filename));
-}
-
-static int ast_el_read_history(char *filename)
-{
- char buf[256];
- FILE *f;
- int ret = -1;
-
- if (el_hist == NULL || el == NULL)
- ast_el_initialize();
-
- if ((f = fopen(filename, "r")) == NULL)
- return ret;
-
- while (!feof(f)) {
- fgets(buf, sizeof(buf), f);
- if (!strcmp(buf, "_HiStOrY_V2_\n"))
- continue;
- if (ast_all_zeros(buf))
- continue;
- if ((ret = ast_el_add_history(buf)) == -1)
- break;
- }
- fclose(f);
-
- return ret;
-}
-
-static void ast_remotecontrol(char * data)
-{
- char buf[80];
- int res;
- char filename[80] = "";
- char *hostname;
- char *cpid;
- char *version;
- int pid;
- char tmp[80];
- char *stringp = NULL;
-
- char *ebuf;
- int num = 0;
-
- read(ast_consock, buf, sizeof(buf));
- if (data)
- write(ast_consock, data, strlen(data) + 1);
- stringp = buf;
- hostname = strsep(&stringp, "/");
- cpid = strsep(&stringp, "/");
- version = strsep(&stringp, "\n");
- if (!version)
- version = "<Version Unknown>";
- stringp = hostname;
- strsep(&stringp, ".");
- if (cpid)
- pid = atoi(cpid);
- else
- pid = -1;
- if (!data) {
- snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
- fdprint(ast_consock, tmp);
- snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
- fdprint(ast_consock, tmp);
- if (!ast_opt_mute)
- fdprint(ast_consock, "logger mute silent");
- else
- printf("log and verbose output currently muted ('logger mute' to unmute)\n");
- }
- ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
- remotehostname = hostname;
- if (getenv("HOME"))
- snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
- if (el_hist == NULL || el == NULL)
- ast_el_initialize();
-
- el_set(el, EL_GETCFN, ast_el_read_char);
-
- if (!ast_strlen_zero(filename))
- ast_el_read_history(filename);
-
- if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
- struct pollfd fds;
- fds.fd = ast_consock;
- fds.events = POLLIN;
- fds.revents = 0;
- while (poll(&fds, 1, 500) > 0) {
- char buf[512] = "", *curline = buf, *nextline;
- int not_written = 1;
-
- if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
- break;
- }
-
- do {
- if ((nextline = strchr(curline, '\n'))) {
- nextline++;
- } else {
- nextline = strchr(curline, '\0');
- }
-
- /* Skip verbose lines */
- if (*curline != 127) {
- not_written = 0;
- write(STDOUT_FILENO, curline, nextline - curline);
- }
- curline = nextline;
- } while (!ast_strlen_zero(curline));
-
- /* No non-verbose output in 500ms */
- if (not_written) {
- break;
- }
- }
- return;
- }
- for (;;) {
- ebuf = (char *)el_gets(el, &num);
-
- if (!ebuf && write(1, "", 1) < 0)
- break;
-
- if (!ast_strlen_zero(ebuf)) {
- if (ebuf[strlen(ebuf)-1] == '\n')
- ebuf[strlen(ebuf)-1] = '\0';
- if (!remoteconsolehandler(ebuf)) {
- res = write(ast_consock, ebuf, strlen(ebuf) + 1);
- if (res < 1) {
- ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
- break;
- }
- }
- }
- }
- printf("\nDisconnected from Asterisk server\n");
-}
-
-static int show_version(void)
-{
- printf("Asterisk " ASTERISK_VERSION "\n");
- return 0;
-}
-
-static int show_cli_help(void) {
- printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2008, Digium, Inc. and others.\n");
- printf("Usage: asterisk [OPTIONS]\n");
- printf("Valid Options:\n");
- printf(" -V Display version number and exit\n");
- printf(" -C <configfile> Use an alternate configuration file\n");
- printf(" -G <group> Run as a group other than the caller\n");
- printf(" -U <user> Run as a user other than the caller\n");
- printf(" -c Provide console CLI\n");
- printf(" -d Enable extra debugging\n");
-#if HAVE_WORKING_FORK
- printf(" -f Do not fork\n");
- printf(" -F Always fork\n");
-#endif
- printf(" -g Dump core in case of a crash\n");
- printf(" -h This help screen\n");
- printf(" -i Initialize crypto keys at startup\n");
- printf(" -I Enable internal timing if Zaptel timer is available\n");
- printf(" -L <load> Limit the maximum load average before rejecting new calls\n");
- printf(" -M <value> Limit the maximum number of calls to the specified value\n");
- printf(" -m Mute debugging and console output on the console\n");
- printf(" -n Disable console colorization\n");
- printf(" -p Run as pseudo-realtime thread\n");
- printf(" -q Quiet mode (suppress output)\n");
- printf(" -r Connect to Asterisk on this machine\n");
- printf(" -R Same as -r, except attempt to reconnect if disconnected\n");
- printf(" -t Record soundfiles in /var/tmp and move them where they\n");
- printf(" belong after they are done\n");
- printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n");
- printf(" of output to the CLI\n");
- printf(" -v Increase verbosity (multiple v's = more verbose)\n");
- printf(" -x <cmd> Execute command <cmd> (only valid with -r)\n");
- printf("\n");
- return 0;
-}
-
-static void ast_readconfig(void)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- char *config = AST_CONFIG_FILE;
-
- if (ast_opt_override_config) {
- cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
- if (!cfg)
- ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
- } else {
- cfg = ast_config_load(config);
- }
-
- /* init with buildtime config */
- ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
- ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
- ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
- snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
- ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
- ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
- ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
- ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
- ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
- ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
- ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
- ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
- ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
-
- /* no asterisk.conf? no problem, use buildtime config! */
- if (!cfg) {
- return;
- }
-
- for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
- if (!strcasecmp(v->name, "astctlpermissions")) {
- ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
- } else if (!strcasecmp(v->name, "astctlowner")) {
- ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
- } else if (!strcasecmp(v->name, "astctlgroup")) {
- ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
- } else if (!strcasecmp(v->name, "astctl")) {
- ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
- }
- }
-
- for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
- if (!strcasecmp(v->name, "astetcdir")) {
- ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
- } else if (!strcasecmp(v->name, "astspooldir")) {
- ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
- snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
- } else if (!strcasecmp(v->name, "astvarlibdir")) {
- ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
- snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
- } else if (!strcasecmp(v->name, "astdatadir")) {
- ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
- snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
- } else if (!strcasecmp(v->name, "astlogdir")) {
- ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
- } else if (!strcasecmp(v->name, "astagidir")) {
- ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
- } else if (!strcasecmp(v->name, "astrundir")) {
- snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
- snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
- ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
- } else if (!strcasecmp(v->name, "astmoddir")) {
- ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
- }
- }
-
- for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
- /* verbose level (-v at startup) */
- if (!strcasecmp(v->name, "verbose")) {
- option_verbose = atoi(v->value);
- /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
- } else if (!strcasecmp(v->name, "timestamp")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
- /* whether or not to support #exec in config files */
- } else if (!strcasecmp(v->name, "execincludes")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
- /* debug level (-d at startup) */
- } else if (!strcasecmp(v->name, "debug")) {
- option_debug = 0;
- if (sscanf(v->value, "%d", &option_debug) != 1) {
- option_debug = ast_true(v->value);
- }
-#if HAVE_WORKING_FORK
- /* Disable forking (-f at startup) */
- } else if (!strcasecmp(v->name, "nofork")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
- /* Always fork, even if verbose or debug are enabled (-F at startup) */
- } else if (!strcasecmp(v->name, "alwaysfork")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
-#endif
- /* Run quietly (-q at startup ) */
- } else if (!strcasecmp(v->name, "quiet")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
- /* Run as console (-c at startup, implies nofork) */
- } else if (!strcasecmp(v->name, "console")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE);
- /* Run with high priority if the O/S permits (-p at startup) */
- } else if (!strcasecmp(v->name, "highpriority")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
- /* Initialize RSA auth keys (IAX2) (-i at startup) */
- } else if (!strcasecmp(v->name, "initcrypto")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
- /* Disable ANSI colors for console (-c at startup) */
- } else if (!strcasecmp(v->name, "nocolor")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
- /* Disable some usage warnings for picky people :p */
- } else if (!strcasecmp(v->name, "dontwarn")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
- /* Dump core in case of crash (-g) */
- } else if (!strcasecmp(v->name, "dumpcore")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
- /* Cache recorded sound files to another directory during recording */
- } else if (!strcasecmp(v->name, "cache_record_files")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
- /* Specify cache directory */
- } else if (!strcasecmp(v->name, "record_cache_dir")) {
- ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
- /* Build transcode paths via SLINEAR, instead of directly */
- } else if (!strcasecmp(v->name, "transcode_via_sln")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
- /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
- } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
- /* Enable internal timing */
- } else if (!strcasecmp(v->name, "internal_timing")) {
- ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
- } else if (!strcasecmp(v->name, "maxcalls")) {
- if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
- option_maxcalls = 0;
- }
- } else if (!strcasecmp(v->name, "maxload")) {
- double test[1];
-
- if (getloadavg(test, 1) == -1) {
- ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
- option_maxload = 0.0;
- } else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
- option_maxload = 0.0;
- }
- /* What user to run as */
- } else if (!strcasecmp(v->name, "runuser")) {
- ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER));
- /* What group to run as */
- } else if (!strcasecmp(v->name, "rungroup")) {
- ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
- } else if (!strcasecmp(v->name, "systemname")) {
- ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
- } else if (!strcasecmp(v->name, "languageprefix")) {
- ast_language_is_prefix = ast_true(v->value);
- }
- }
- ast_config_destroy(cfg);
-}
-
-static void *monitor_sig_flags(void *unused)
-{
- for (;;) {
- struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
- int a;
- poll(&p, 1, -1);
- if (sig_flags.need_reload) {
- sig_flags.need_reload = 0;
- ast_module_reload(NULL);
- }
- if (sig_flags.need_quit) {
- sig_flags.need_quit = 0;
- quit_handler(0, 0, 1, 0);
- }
- read(sig_alert_pipe[0], &a, sizeof(a));
- }
-
- return NULL;
-}
-
-int main(int argc, char *argv[])
-{
- int c;
- char filename[80] = "";
- char hostname[MAXHOSTNAMELEN] = "";
- char tmp[80];
- char * xarg = NULL;
- int x;
- FILE *f;
- sigset_t sigs;
- int num;
- int isroot = 1;
- char *buf;
- char *runuser = NULL, *rungroup = NULL;
-
- /* Remember original args for restart */
- if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
- fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
- argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
- }
- for (x=0; x<argc; x++)
- _argv[x] = argv[x];
- _argv[x] = NULL;
-
- if (geteuid() != 0)
- isroot = 0;
-
- /* if the progname is rasterisk consider it a remote console */
- if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
- }
- if (gethostname(hostname, sizeof(hostname)-1))
- ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
- ast_mainpid = getpid();
- ast_ulaw_init();
- ast_alaw_init();
- callerid_init();
- ast_builtins_init();
- ast_utils_init();
- tdd_init();
-
- if (getenv("HOME"))
- snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
- /* Check for options */
- while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) {
- switch (c) {
-#if HAVE_WORKING_FORK
- case 'F':
- ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
- break;
- case 'f':
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
- break;
-#endif
- case 'd':
- option_debug++;
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
- break;
- case 'c':
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
- break;
- case 'n':
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
- break;
- case 'r':
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
- break;
- case 'R':
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
- break;
- case 'p':
- ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
- break;
- case 'v':
- option_verbose++;
- ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
- break;
- case 'm':
- ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
- break;
- case 'M':
- if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
- option_maxcalls = 0;
- break;
- case 'L':
- if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0))
- option_maxload = 0.0;
- break;
- case 'q':
- ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
- break;
- case 't':
- ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
- break;
- case 'T':
- ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
- break;
- case 'x':
- ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
- xarg = ast_strdupa(optarg);
- break;
- case 'C':
- ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE));
- ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
- break;
- case 'I':
- ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
- break;
- case 'i':
- ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
- break;
- case 'g':
- ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
- break;
- case 'h':
- show_cli_help();
- exit(0);
- case 'V':
- show_version();
- exit(0);
- case 'U':
- runuser = ast_strdupa(optarg);
- break;
- case 'G':
- rungroup = ast_strdupa(optarg);
- break;
- case '?':
- exit(1);
- }
- }
-
- if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
- ast_register_verbose(console_verboser);
- WELCOME_MESSAGE;
- }
-
- if (ast_opt_console && !option_verbose)
- ast_verbose("[ Booting...\n");
-
- if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
- ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
- ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
- }
-
- /* For remote connections, change the name of the remote connection.
- * We do this for the benefit of init scripts (which need to know if/when
- * the main asterisk process has died yet). */
- if (ast_opt_remote) {
- strcpy(argv[0], "rasterisk");
- for (x = 1; x < argc; x++) {
- argv[x] = argv[0] + 10;
- }
- }
-
- if (ast_opt_console && !option_verbose)
- ast_verbose("[ Reading Master Configuration ]\n");
- ast_readconfig();
-
- if (ast_opt_dump_core) {
- struct rlimit l;
- memset(&l, 0, sizeof(l));
- l.rlim_cur = RLIM_INFINITY;
- l.rlim_max = RLIM_INFINITY;
- if (setrlimit(RLIMIT_CORE, &l)) {
- ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
- }
- }
-
- if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
- rungroup = ast_config_AST_RUN_GROUP;
- if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
- runuser = ast_config_AST_RUN_USER;
-
-#ifndef __CYGWIN__
-
- if (isroot)
- ast_set_priority(ast_opt_high_priority);
-
- if (isroot && rungroup) {
- struct group *gr;
- gr = getgrnam(rungroup);
- if (!gr) {
- ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
- exit(1);
- }
- if (setgid(gr->gr_gid)) {
- ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
- exit(1);
- }
- if (setgroups(0, NULL)) {
- ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
- exit(1);
- }
- if (option_verbose)
- ast_verbose("Running as group '%s'\n", rungroup);
- }
-
- if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
-#ifdef HAVE_CAP
- int has_cap = 1;
-#endif /* HAVE_CAP */
- struct passwd *pw;
- pw = getpwnam(runuser);
- if (!pw) {
- ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
- exit(1);
- }
-#ifdef HAVE_CAP
- if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
- ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
- has_cap = 0;
- }
-#endif /* HAVE_CAP */
- if (!isroot && pw->pw_uid != geteuid()) {
- ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
- exit(1);
- }
- if (!rungroup) {
- if (setgid(pw->pw_gid)) {
- ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
- exit(1);
- }
- if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
- ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
- exit(1);
- }
- }
- if (setuid(pw->pw_uid)) {
- ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
- exit(1);
- }
- if (option_verbose)
- ast_verbose("Running as user '%s'\n", runuser);
-#ifdef HAVE_CAP
- if (has_cap) {
- cap_t cap;
-
- cap = cap_from_text("cap_net_admin=ep");
-
- if (cap_set_proc(cap))
- ast_log(LOG_WARNING, "Unable to install capabilities.\n");
-
- if (cap_free(cap))
- ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
- }
-#endif /* HAVE_CAP */
- }
-
-#endif /* __CYGWIN__ */
-
-#ifdef linux
- if (geteuid() && ast_opt_dump_core) {
- if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
- ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
- }
- }
-#endif
-
- ast_term_init();
- printf(term_end());
- fflush(stdout);
-
- if (ast_opt_console && !option_verbose)
- ast_verbose("[ Initializing Custom Configuration Options ]\n");
- /* custom config setup */
- register_config_cli();
- read_config_maps();
-
- if (ast_opt_console) {
- if (el_hist == NULL || el == NULL)
- ast_el_initialize();
-
- if (!ast_strlen_zero(filename))
- ast_el_read_history(filename);
- }
-
- if (ast_tryconnect()) {
- /* One is already running */
- if (ast_opt_remote) {
- if (ast_opt_exec) {
- ast_remotecontrol(xarg);
- quit_handler(0, 0, 0, 0);
- exit(0);
- }
- printf(term_quit());
- ast_remotecontrol(NULL);
- quit_handler(0, 0, 0, 0);
- exit(0);
- } else {
- ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
- printf(term_quit());
- exit(1);
- }
- } else if (ast_opt_remote || ast_opt_exec) {
- ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
- printf(term_quit());
- exit(1);
- }
- /* Blindly write pid file since we couldn't connect */
- unlink(ast_config_AST_PID);
- f = fopen(ast_config_AST_PID, "w");
- if (f) {
- fprintf(f, "%ld\n", (long)getpid());
- fclose(f);
- } else
- ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
-
-#if HAVE_WORKING_FORK
- if (ast_opt_always_fork || !ast_opt_no_fork) {
-#ifndef HAVE_SBIN_LAUNCHD
- daemon(1, 0);
- ast_mainpid = getpid();
- /* Blindly re-write pid file since we are forking */
- unlink(ast_config_AST_PID);
- f = fopen(ast_config_AST_PID, "w");
- if (f) {
- fprintf(f, "%ld\n", (long)ast_mainpid);
- fclose(f);
- } else
- ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
-#else
- ast_log(LOG_WARNING, "Mac OS X detected. Use '/sbin/launchd -d' to launch with the nofork option.\n");
-#endif
- }
-#endif
-
- /* Test recursive mutex locking. */
- if (test_for_thread_safety())
- ast_verbose("Warning! Asterisk is not thread safe.\n");
-
- ast_makesocket();
- sigemptyset(&sigs);
- sigaddset(&sigs, SIGHUP);
- sigaddset(&sigs, SIGTERM);
- sigaddset(&sigs, SIGINT);
- sigaddset(&sigs, SIGPIPE);
- sigaddset(&sigs, SIGWINCH);
- pthread_sigmask(SIG_BLOCK, &sigs, NULL);
- signal(SIGURG, urg_handler);
- signal(SIGINT, __quit_handler);
- signal(SIGTERM, __quit_handler);
- signal(SIGHUP, hup_handler);
- signal(SIGCHLD, child_handler);
- signal(SIGPIPE, SIG_IGN);
-
- /* ensure that the random number generators are seeded with a different value every time
- Asterisk is started
- */
- srand((unsigned int) getpid() + (unsigned int) time(NULL));
- initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
-
- if (init_logger()) {
- printf(term_quit());
- exit(1);
- }
-#ifdef HAVE_ZAPTEL
- {
- int fd;
- int x = 160;
- fd = open("/dev/zap/timer", O_RDWR);
- if (fd >= 0) {
- if (ioctl(fd, ZT_TIMERCONFIG, &x)) {
- ast_log(LOG_ERROR, "You have Zaptel built and drivers loaded, but the Zaptel timer test failed to set ZT_TIMERCONFIG to %d.\n", x);
- exit(1);
- }
- if ((x = ast_wait_for_input(fd, 300)) < 0) {
- ast_log(LOG_ERROR, "You have Zaptel built and drivers loaded, but the Zaptel timer could not be polled during the Zaptel timer test.\n");
- exit(1);
- }
- if (!x) {
- const char zaptel_timer_error[] = {
- "Asterisk has detected a problem with your Zaptel configuration and will shutdown for your protection. You have options:"
- "\n\t1. You only have to compile Zaptel support into Asterisk if you need it. One option is to recompile without Zaptel support."
- "\n\t2. You only have to load Zaptel drivers if you want to take advantage of Zaptel services. One option is to unload zaptel modules if you don't need them."
- "\n\t3. If you need Zaptel services, you must correctly configure Zaptel."
- };
- ast_log(LOG_ERROR, "%s\n", zaptel_timer_error);
- exit(1);
- }
- close(fd);
- }
- }
-#endif
- threadstorage_init();
-
- astobj2_init();
-
- ast_autoservice_init();
-
- if (load_modules(1)) {
- printf(term_quit());
- exit(1);
- }
-
- if (dnsmgr_init()) {
- printf(term_quit());
- exit(1);
- }
-
- ast_http_init();
-
- ast_channels_init();
-
- if (init_manager()) {
- printf(term_quit());
- exit(1);
- }
-
- if (ast_cdr_engine_init()) {
- printf(term_quit());
- exit(1);
- }
-
- if (ast_device_state_engine_init()) {
- printf(term_quit());
- exit(1);
- }
-
- ast_rtp_init();
-
- ast_udptl_init();
-
- if (ast_image_init()) {
- printf(term_quit());
- exit(1);
- }
-
- if (ast_file_init()) {
- printf(term_quit());
- exit(1);
- }
-
- if (load_pbx()) {
- printf(term_quit());
- exit(1);
- }
-
- if (init_framer()) {
- printf(term_quit());
- exit(1);
- }
-
- if (astdb_init()) {
- printf(term_quit());
- exit(1);
- }
-
- if (ast_enum_init()) {
- printf(term_quit());
- exit(1);
- }
-
- if (load_modules(0)) {
- printf(term_quit());
- exit(1);
- }
-
- dnsmgr_start_refresh();
-
- /* We might have the option of showing a console, but for now just
- do nothing... */
- if (ast_opt_console && !option_verbose)
- ast_verbose(" ]\n");
- if (option_verbose || ast_opt_console)
- ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
- if (ast_opt_no_fork)
- consolethread = pthread_self();
-
- if (pipe(sig_alert_pipe))
- sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
-
- ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
- pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
-
-#ifdef __AST_DEBUG_MALLOC
- __ast_mm_init();
-#endif
-
- time(&ast_startuptime);
- ast_cli_register_multiple(cli_asterisk, sizeof(cli_asterisk) / sizeof(struct ast_cli_entry));
-
- if (ast_opt_console) {
- /* Console stuff now... */
- /* Register our quit function */
- char title[256];
- pthread_attr_t attr;
- pthread_t dont_care;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&dont_care, &attr, monitor_sig_flags, NULL);
- pthread_attr_destroy(&attr);
-
- set_icon("Asterisk");
- snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
- set_title(title);
-
- for (;;) {
- buf = (char *)el_gets(el, &num);
-
- if (!buf && write(1, "", 1) < 0)
- goto lostterm;
-
- if (buf) {
- if (buf[strlen(buf)-1] == '\n')
- buf[strlen(buf)-1] = '\0';
-
- consolehandler((char *)buf);
- } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
- strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
- /* Whoa, stdout disappeared from under us... Make /dev/null's */
- int fd;
- fd = open("/dev/null", O_RDWR);
- if (fd > -1) {
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDIN_FILENO);
- } else
- ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
- break;
- }
- }
- }
-
- monitor_sig_flags(NULL);
-
-lostterm:
- return 0;
-}
diff --git a/1.4/main/astmm.c b/1.4/main/astmm.c
deleted file mode 100644
index eeeaf5bd8..000000000
--- a/1.4/main/astmm.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Memory Management
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#ifdef __AST_DEBUG_MALLOC
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include "asterisk/cli.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/lock.h"
-#include "asterisk/strings.h"
-#include "asterisk/unaligned.h"
-
-#define SOME_PRIME 563
-
-enum func_type {
- FUNC_CALLOC = 1,
- FUNC_MALLOC,
- FUNC_REALLOC,
- FUNC_STRDUP,
- FUNC_STRNDUP,
- FUNC_VASPRINTF,
- FUNC_ASPRINTF
-};
-
-/* Undefine all our macros */
-#undef malloc
-#undef calloc
-#undef realloc
-#undef strdup
-#undef strndup
-#undef free
-#undef vasprintf
-#undef asprintf
-
-#define FENCE_MAGIC 0xdeadbeef
-
-static FILE *mmlog;
-
-static struct ast_region {
- struct ast_region *next;
- char file[40];
- char func[40];
- unsigned int lineno;
- enum func_type which;
- unsigned int cache; /* region was allocated as part of a cache pool */
- size_t len;
- unsigned int fence;
- unsigned char data[0];
-} *regions[SOME_PRIME];
-
-#define HASH(a) \
- (((unsigned long)(a)) % SOME_PRIME)
-
-AST_MUTEX_DEFINE_STATIC_NOTRACKING(reglock);
-
-#define astmm_log(...) \
- do { \
- fprintf(stderr, __VA_ARGS__); \
- if (mmlog) { \
- fprintf(mmlog, __VA_ARGS__); \
- fflush(mmlog); \
- } \
- } while (0)
-
-static inline void *__ast_alloc_region(size_t size, const enum func_type which, const char *file, int lineno, const char *func, unsigned int cache)
-{
- struct ast_region *reg;
- void *ptr = NULL;
- unsigned int *fence;
- int hash;
-
- if (!(reg = malloc(size + sizeof(*reg) + sizeof(*fence)))) {
- astmm_log("Memory Allocation Failure - '%d' bytes in function %s "
- "at line %d of %s\n", (int) size, func, lineno, file);
- }
-
- ast_copy_string(reg->file, file, sizeof(reg->file));
- ast_copy_string(reg->func, func, sizeof(reg->func));
- reg->lineno = lineno;
- reg->len = size;
- reg->which = which;
- reg->cache = cache;
- ptr = reg->data;
- hash = HASH(ptr);
- reg->fence = FENCE_MAGIC;
- fence = (ptr + reg->len);
- put_unaligned_uint32(fence, FENCE_MAGIC);
-
- ast_mutex_lock(&reglock);
- reg->next = regions[hash];
- regions[hash] = reg;
- ast_mutex_unlock(&reglock);
-
- return ptr;
-}
-
-static inline size_t __ast_sizeof_region(void *ptr)
-{
- int hash = HASH(ptr);
- struct ast_region *reg;
- size_t len = 0;
-
- ast_mutex_lock(&reglock);
- for (reg = regions[hash]; reg; reg = reg->next) {
- if (reg->data == ptr) {
- len = reg->len;
- break;
- }
- }
- ast_mutex_unlock(&reglock);
-
- return len;
-}
-
-static void __ast_free_region(void *ptr, const char *file, int lineno, const char *func)
-{
- int hash = HASH(ptr);
- struct ast_region *reg, *prev = NULL;
- unsigned int *fence;
-
- ast_mutex_lock(&reglock);
- for (reg = regions[hash]; reg; reg = reg->next) {
- if (reg->data == ptr) {
- if (prev)
- prev->next = reg->next;
- else
- regions[hash] = reg->next;
- break;
- }
- prev = reg;
- }
- ast_mutex_unlock(&reglock);
-
- if (reg) {
- fence = (unsigned int *)(reg->data + reg->len);
- if (reg->fence != FENCE_MAGIC) {
- astmm_log("WARNING: Low fence violation at %p, in %s of %s, "
- "line %d\n", reg->data, reg->func, reg->file, reg->lineno);
- }
- if (get_unaligned_uint32(fence) != FENCE_MAGIC) {
- astmm_log("WARNING: High fence violation at %p, in %s of %s, "
- "line %d\n", reg->data, reg->func, reg->file, reg->lineno);
- }
- free(reg);
- } else {
- astmm_log("WARNING: Freeing unused memory at %p, in %s of %s, line %d\n",
- ptr, func, file, lineno);
- }
-}
-
-void *__ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
-{
- void *ptr;
-
- if ((ptr = __ast_alloc_region(size * nmemb, FUNC_CALLOC, file, lineno, func, 0)))
- memset(ptr, 0, size * nmemb);
-
- return ptr;
-}
-
-void *__ast_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
-{
- void *ptr;
-
- if ((ptr = __ast_alloc_region(size * nmemb, FUNC_CALLOC, file, lineno, func, 1)))
- memset(ptr, 0, size * nmemb);
-
- return ptr;
-}
-
-void *__ast_malloc(size_t size, const char *file, int lineno, const char *func)
-{
- return __ast_alloc_region(size, FUNC_MALLOC, file, lineno, func, 0);
-}
-
-void __ast_free(void *ptr, const char *file, int lineno, const char *func)
-{
- __ast_free_region(ptr, file, lineno, func);
-}
-
-void *__ast_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func)
-{
- void *tmp;
- size_t len = 0;
-
- if (ptr && !(len = __ast_sizeof_region(ptr))) {
- astmm_log("WARNING: Realloc of unalloced memory at %p, in %s of %s, "
- "line %d\n", ptr, func, file, lineno);
- return NULL;
- }
-
- if (!(tmp = __ast_alloc_region(size, FUNC_REALLOC, file, lineno, func, 0)))
- return NULL;
-
- if (len > size)
- len = size;
- if (ptr) {
- memcpy(tmp, ptr, len);
- __ast_free_region(ptr, file, lineno, func);
- }
-
- return tmp;
-}
-
-char *__ast_strdup(const char *s, const char *file, int lineno, const char *func)
-{
- size_t len;
- void *ptr;
-
- if (!s)
- return NULL;
-
- len = strlen(s) + 1;
- if ((ptr = __ast_alloc_region(len, FUNC_STRDUP, file, lineno, func, 0)))
- strcpy(ptr, s);
-
- return ptr;
-}
-
-char *__ast_strndup(const char *s, size_t n, const char *file, int lineno, const char *func)
-{
- size_t len;
- void *ptr;
-
- if (!s)
- return NULL;
-
- len = strlen(s) + 1;
- if (len > n)
- len = n;
- if ((ptr = __ast_alloc_region(len, FUNC_STRNDUP, file, lineno, func, 0)))
- strcpy(ptr, s);
-
- return ptr;
-}
-
-int __ast_asprintf(const char *file, int lineno, const char *func, char **strp, const char *fmt, ...)
-{
- int size;
- va_list ap, ap2;
- char s;
-
- *strp = NULL;
- va_start(ap, fmt);
- va_copy(ap2, ap);
- size = vsnprintf(&s, 1, fmt, ap2);
- va_end(ap2);
- if (!(*strp = __ast_alloc_region(size + 1, FUNC_ASPRINTF, file, lineno, func, 0))) {
- va_end(ap);
- return -1;
- }
- vsnprintf(*strp, size + 1, fmt, ap);
- va_end(ap);
-
- return size;
-}
-
-int __ast_vasprintf(char **strp, const char *fmt, va_list ap, const char *file, int lineno, const char *func)
-{
- int size;
- va_list ap2;
- char s;
-
- *strp = NULL;
- va_copy(ap2, ap);
- size = vsnprintf(&s, 1, fmt, ap2);
- va_end(ap2);
- if (!(*strp = __ast_alloc_region(size + 1, FUNC_VASPRINTF, file, lineno, func, 0))) {
- va_end(ap);
- return -1;
- }
- vsnprintf(*strp, size + 1, fmt, ap);
-
- return size;
-}
-
-static int handle_show_memory(int fd, int argc, char *argv[])
-{
- char *fn = NULL;
- struct ast_region *reg;
- unsigned int x;
- unsigned int len = 0;
- unsigned int cache_len = 0;
- unsigned int count = 0;
- unsigned int *fence;
-
- if (argc > 3)
- fn = argv[3];
-
- ast_mutex_lock(&reglock);
- for (x = 0; x < SOME_PRIME; x++) {
- for (reg = regions[x]; reg; reg = reg->next) {
- if (!fn || !strcasecmp(fn, reg->file) || !strcasecmp(fn, "anomolies")) {
- fence = (unsigned int *)(reg->data + reg->len);
- if (reg->fence != FENCE_MAGIC) {
- astmm_log("WARNING: Low fence violation at %p, "
- "in %s of %s, line %d\n", reg->data,
- reg->func, reg->file, reg->lineno);
- }
- if (get_unaligned_uint32(fence) != FENCE_MAGIC) {
- astmm_log("WARNING: High fence violation at %p, in %s of %s, "
- "line %d\n", reg->data, reg->func, reg->file, reg->lineno);
- }
- }
- if (!fn || !strcasecmp(fn, reg->file)) {
- ast_cli(fd, "%10d bytes allocated%s in %20s at line %5d of %s\n",
- (int) reg->len, reg->cache ? " (cache)" : "",
- reg->func, reg->lineno, reg->file);
- len += reg->len;
- if (reg->cache)
- cache_len += reg->len;
- count++;
- }
- }
- }
- ast_mutex_unlock(&reglock);
-
- if (cache_len)
- ast_cli(fd, "%d bytes allocated (%d in caches) in %d allocations\n", len, cache_len, count);
- else
- ast_cli(fd, "%d bytes allocated in %d allocations\n", len, count);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_show_memory_summary(int fd, int argc, char *argv[])
-{
- char *fn = NULL;
- int x;
- struct ast_region *reg;
- unsigned int len = 0;
- unsigned int cache_len = 0;
- int count = 0;
- struct file_summary {
- char fn[80];
- int len;
- int cache_len;
- int count;
- struct file_summary *next;
- } *list = NULL, *cur;
-
- if (argc > 3)
- fn = argv[3];
-
- ast_mutex_lock(&reglock);
- for (x = 0; x < SOME_PRIME; x++) {
- for (reg = regions[x]; reg; reg = reg->next) {
- if (fn && strcasecmp(fn, reg->file))
- continue;
-
- for (cur = list; cur; cur = cur->next) {
- if ((!fn && !strcmp(cur->fn, reg->file)) || (fn && !strcmp(cur->fn, reg->func)))
- break;
- }
- if (!cur) {
- cur = alloca(sizeof(*cur));
- memset(cur, 0, sizeof(*cur));
- ast_copy_string(cur->fn, fn ? reg->func : reg->file, sizeof(cur->fn));
- cur->next = list;
- list = cur;
- }
-
- cur->len += reg->len;
- if (reg->cache)
- cur->cache_len += reg->len;
- cur->count++;
- }
- }
- ast_mutex_unlock(&reglock);
-
- /* Dump the whole list */
- for (cur = list; cur; cur = cur->next) {
- len += cur->len;
- cache_len += cur->cache_len;
- count += cur->count;
- if (cur->cache_len) {
- if (fn) {
- ast_cli(fd, "%10d bytes (%10d cache) in %d allocations in function '%s' of '%s'\n",
- cur->len, cur->cache_len, cur->count, cur->fn, fn);
- } else {
- ast_cli(fd, "%10d bytes (%10d cache) in %d allocations in file '%s'\n",
- cur->len, cur->cache_len, cur->count, cur->fn);
- }
- } else {
- if (fn) {
- ast_cli(fd, "%10d bytes in %d allocations in function '%s' of '%s'\n",
- cur->len, cur->count, cur->fn, fn);
- } else {
- ast_cli(fd, "%10d bytes in %d allocations in file '%s'\n",
- cur->len, cur->count, cur->fn);
- }
- }
- }
-
- if (cache_len)
- ast_cli(fd, "%d bytes allocated (%d in caches) in %d allocations\n", len, cache_len, count);
- else
- ast_cli(fd, "%d bytes allocated in %d allocations\n", len, count);
-
- return RESULT_SUCCESS;
-}
-
-static char show_memory_help[] =
-"Usage: memory show allocations [<file>]\n"
-" Dumps a list of all segments of allocated memory, optionally\n"
-"limited to those from a specific file\n";
-
-static char show_memory_summary_help[] =
-"Usage: memory show summary [<file>]\n"
-" Summarizes heap memory allocations by file, or optionally\n"
-"by function, if a file is specified\n";
-
-static struct ast_cli_entry cli_show_memory_allocations_deprecated = {
- { "show", "memory", "allocations", NULL },
- handle_show_memory, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_memory_summary_deprecated = {
- { "show", "memory", "summary", NULL },
- handle_show_memory_summary, NULL,
- NULL };
-
-static struct ast_cli_entry cli_memory[] = {
- { { "memory", "show", "allocations", NULL },
- handle_show_memory, "Display outstanding memory allocations",
- show_memory_help, NULL, &cli_show_memory_allocations_deprecated },
-
- { { "memory", "show", "summary", NULL },
- handle_show_memory_summary, "Summarize outstanding memory allocations",
- show_memory_summary_help, NULL, &cli_show_memory_summary_deprecated },
-};
-
-void __ast_mm_init(void)
-{
- char filename[PATH_MAX];
-
- ast_cli_register_multiple(cli_memory, sizeof(cli_memory) / sizeof(struct ast_cli_entry));
-
- snprintf(filename, sizeof(filename), "%s/mmlog", (char *)ast_config_AST_LOG_DIR);
-
- if (option_verbose)
- ast_verbose("Asterisk Malloc Debugger Started (see %s))\n", filename);
-
- if ((mmlog = fopen(filename, "a+"))) {
- fprintf(mmlog, "%ld - New session\n", (long)time(NULL));
- fflush(mmlog);
- }
-}
-
-#endif
diff --git a/1.4/main/astobj2.c b/1.4/main/astobj2.c
deleted file mode 100644
index 7cbf70cce..000000000
--- a/1.4/main/astobj2.c
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * astobj2 - replacement containers for asterisk data structures.
- *
- * Copyright (C) 2006 Marta Carbone, Luigi Rizzo - Univ. di Pisa, Italy
- *
- * 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.
- */
-
-/*
- * Function implementing astobj2 objects.
- */
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/astobj2.h"
-#include "asterisk/utils.h"
-#include "asterisk/cli.h"
-
-/*!
- * astobj2 objects are always prepended this data structure,
- * which contains a lock, a reference counter,
- * the flags and a pointer to a destructor.
- * The refcount is used to decide when it is time to
- * invoke the destructor.
- * The magic number is used for consistency check.
- * XXX the lock is not always needed, and its initialization may be
- * expensive. Consider making it external.
- */
-struct __priv_data {
- ast_mutex_t lock;
- int ref_counter;
- ao2_destructor_fn destructor_fn;
- /*! for stats */
- size_t data_size;
- /*! magic number. This is used to verify that a pointer passed in is a
- * valid astobj2 */
- uint32_t magic;
-};
-
-#define AO2_MAGIC 0xa570b123
-
-/*!
- * What an astobj2 object looks like: fixed-size private data
- * followed by variable-size user data.
- */
-struct astobj2 {
- struct __priv_data priv_data;
- void *user_data[0];
-};
-
-#ifdef AST_DEVMODE
-#define AO2_DEBUG 1
-#endif
-
-#ifdef AO2_DEBUG
-struct ao2_stats {
- volatile int total_objects;
- volatile int total_mem;
- volatile int total_containers;
- volatile int total_refs;
- volatile int total_locked;
-};
-
-static struct ao2_stats ao2;
-#endif
-
-#ifndef HAVE_BKTR /* backtrace support */
-void ao2_bt(void) {}
-#else
-#include <execinfo.h> /* for backtrace */
-
-void ao2_bt(void)
-{
- int c, i;
-#define N1 20
- void *addresses[N1];
- char **strings;
-
- c = backtrace(addresses, N1);
- strings = backtrace_symbols(addresses,c);
- ast_verbose("backtrace returned: %d\n", c);
- for(i = 0; i < c; i++) {
- ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]);
- }
- free(strings);
-}
-#endif
-
-/*!
- * \brief convert from a pointer _p to a user-defined object
- *
- * \return the pointer to the astobj2 structure
- */
-static inline struct astobj2 *INTERNAL_OBJ(void *user_data)
-{
- struct astobj2 *p;
-
- if (!user_data) {
- ast_log(LOG_ERROR, "user_data is NULL\n");
- return NULL;
- }
-
- p = (struct astobj2 *) ((char *) user_data - sizeof(*p));
- if (AO2_MAGIC != (p->priv_data.magic) ) {
- ast_log(LOG_ERROR, "bad magic number 0x%x for %p\n", p->priv_data.magic, p);
- p = NULL;
- }
-
- return p;
-}
-
-/*!
- * \brief convert from a pointer _p to an astobj2 object
- *
- * \return the pointer to the user-defined portion.
- */
-#define EXTERNAL_OBJ(_p) ((_p) == NULL ? NULL : (_p)->user_data)
-
-int ao2_lock(void *user_data)
-{
- struct astobj2 *p = INTERNAL_OBJ(user_data);
-
- if (p == NULL)
- return -1;
-
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_locked, 1);
-#endif
-
- return ast_mutex_lock(&p->priv_data.lock);
-}
-
-int ao2_unlock(void *user_data)
-{
- struct astobj2 *p = INTERNAL_OBJ(user_data);
-
- if (p == NULL)
- return -1;
-
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_locked, -1);
-#endif
-
- return ast_mutex_unlock(&p->priv_data.lock);
-}
-
-/*
- * The argument is a pointer to the user portion.
- */
-int ao2_ref(void *user_data, const int delta)
-{
- int current_value;
- int ret;
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
-
- if (obj == NULL)
- return -1;
-
- /* if delta is 0, just return the refcount */
- if (delta == 0)
- return (obj->priv_data.ref_counter);
-
- /* we modify with an atomic operation the reference counter */
- ret = ast_atomic_fetchadd_int(&obj->priv_data.ref_counter, delta);
- current_value = ret + delta;
-
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_refs, delta);
-#endif
-
- /* this case must never happen */
- if (current_value < 0)
- ast_log(LOG_ERROR, "refcount %d on object %p\n", current_value, user_data);
-
- if (current_value <= 0) { /* last reference, destroy the object */
- if (obj->priv_data.destructor_fn != NULL)
- obj->priv_data.destructor_fn(user_data);
-
- ast_mutex_destroy(&obj->priv_data.lock);
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_mem, - obj->priv_data.data_size);
- ast_atomic_fetchadd_int(&ao2.total_objects, -1);
-#endif
- /* for safety, zero-out the astobj2 header and also the
- * first word of the user-data, which we make sure is always
- * allocated. */
- bzero(obj, sizeof(struct astobj2 *) + sizeof(void *) );
- free(obj);
- }
-
- return ret;
-}
-
-/*
- * We always alloc at least the size of a void *,
- * for debugging purposes.
- */
-void *ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn)
-{
- /* allocation */
- struct astobj2 *obj;
-
- if (data_size < sizeof(void *))
- data_size = sizeof(void *);
-
- obj = ast_calloc(1, sizeof(*obj) + data_size);
-
- if (obj == NULL)
- return NULL;
-
- ast_mutex_init(&obj->priv_data.lock);
- obj->priv_data.magic = AO2_MAGIC;
- obj->priv_data.data_size = data_size;
- obj->priv_data.ref_counter = 1;
- obj->priv_data.destructor_fn = destructor_fn; /* can be NULL */
-
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_objects, 1);
- ast_atomic_fetchadd_int(&ao2.total_mem, data_size);
- ast_atomic_fetchadd_int(&ao2.total_refs, 1);
-#endif
-
- /* return a pointer to the user data */
- return EXTERNAL_OBJ(obj);
-}
-
-/* internal callback to destroy a container. */
-static void container_destruct(void *c);
-
-/* each bucket in the container is a tailq. */
-AST_LIST_HEAD_NOLOCK(bucket, bucket_list);
-
-/*!
- * A container; stores the hash and callback functions, information on
- * the size, the hash bucket heads, and a version number, starting at 0
- * (for a newly created, empty container)
- * and incremented every time an object is inserted or deleted.
- * The assumption is that an object is never moved in a container,
- * but removed and readded with the new number.
- * The version number is especially useful when implementing iterators.
- * In fact, we can associate a unique, monotonically increasing number to
- * each object, which means that, within an iterator, we can store the
- * version number of the current object, and easily look for the next one,
- * which is the next one in the list with a higher number.
- * Since all objects have a version >0, we can use 0 as a marker for
- * 'we need the first object in the bucket'.
- *
- * \todo Linking and unlink objects is typically expensive, as it
- * involves a malloc() of a small object which is very inefficient.
- * To optimize this, we allocate larger arrays of bucket_list's
- * when we run out of them, and then manage our own freelist.
- * This will be more efficient as we can do the freelist management while
- * we hold the lock (that we need anyways).
- */
-struct ao2_container {
- ao2_hash_fn hash_fn;
- ao2_callback_fn cmp_fn;
- int n_buckets;
- /*! Number of elements in the container */
- int elements;
- /*! described above */
- int version;
- /*! variable size */
- struct bucket buckets[0];
-};
-
-/*!
- * \brief always zero hash function
- *
- * it is convenient to have a hash function that always returns 0.
- * This is basically used when we want to have a container that is
- * a simple linked list.
- *
- * \returns 0
- */
-static int hash_zero(const void *user_obj, const int flags)
-{
- return 0;
-}
-
-/*
- * A container is just an object, after all!
- */
-struct ao2_container *
-ao2_container_alloc(const uint n_buckets, ao2_hash_fn hash_fn,
- ao2_callback_fn cmp_fn)
-{
- /* XXX maybe consistency check on arguments ? */
- /* compute the container size */
- size_t container_size = sizeof(struct ao2_container) + n_buckets * sizeof(struct bucket);
-
- struct ao2_container *c = ao2_alloc(container_size, container_destruct);
-
- if (!c)
- return NULL;
-
- c->version = 1; /* 0 is a reserved value here */
- c->n_buckets = n_buckets;
- c->hash_fn = hash_fn ? hash_fn : hash_zero;
- c->cmp_fn = cmp_fn;
-
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_containers, 1);
-#endif
-
- return c;
-}
-
-/*!
- * return the number of elements in the container
- */
-int ao2_container_count(struct ao2_container *c)
-{
- return c->elements;
-}
-
-/*!
- * A structure to create a linked list of entries,
- * used within a bucket.
- * XXX \todo this should be private to the container code
- */
-struct bucket_list {
- AST_LIST_ENTRY(bucket_list) entry;
- int version;
- struct astobj2 *astobj; /* pointer to internal data */
-};
-
-/*
- * link an object to a container
- */
-void *__ao2_link(struct ao2_container *c, void *user_data, int iax2_hack)
-{
- int i;
- /* create a new list entry */
- struct bucket_list *p;
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
-
- if (!obj)
- return NULL;
-
- if (INTERNAL_OBJ(c) == NULL)
- return NULL;
-
- p = ast_calloc(1, sizeof(*p));
- if (!p)
- return NULL;
-
- i = c->hash_fn(user_data, OBJ_POINTER);
-
- ao2_lock(c);
- i %= c->n_buckets;
- p->astobj = obj;
- p->version = ast_atomic_fetchadd_int(&c->version, 1);
- if (iax2_hack)
- AST_LIST_INSERT_HEAD(&c->buckets[i], p, entry);
- else
- AST_LIST_INSERT_TAIL(&c->buckets[i], p, entry);
- ast_atomic_fetchadd_int(&c->elements, 1);
- ao2_ref(user_data, +1);
- ao2_unlock(c);
-
- return p;
-}
-
-/*!
- * \brief another convenience function is a callback that matches on address
- */
-int ao2_match_by_addr(void *user_data, void *arg, int flags)
-{
- return (user_data == arg) ? (CMP_MATCH | CMP_STOP) : 0;
-}
-
-/*
- * Unlink an object from the container
- * and destroy the associated * ao2_bucket_list structure.
- */
-void *ao2_unlink(struct ao2_container *c, void *user_data)
-{
- if (INTERNAL_OBJ(user_data) == NULL) /* safety check on the argument */
- return NULL;
-
- ao2_callback(c, OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA, ao2_match_by_addr, user_data);
-
- return NULL;
-}
-
-/*!
- * \brief special callback that matches all
- */
-static int cb_true(void *user_data, void *arg, int flags)
-{
- return CMP_MATCH;
-}
-
-/*!
- * Browse the container using different stategies accoding the flags.
- * \return Is a pointer to an object or to a list of object if OBJ_MULTIPLE is
- * specified.
- */
-void *ao2_callback(struct ao2_container *c,
- const enum search_flags flags,
- ao2_callback_fn cb_fn, void *arg)
-{
- int i, last; /* search boundaries */
- void *ret = NULL;
-
- if (INTERNAL_OBJ(c) == NULL) /* safety check on the argument */
- return NULL;
-
- if ((flags & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) {
- ast_log(LOG_WARNING, "multiple data return not implemented yet (flags %x)\n", flags);
- return NULL;
- }
-
- /* override the match function if necessary */
-#if 0
- /* Removing this slightly changes the meaning of OBJ_POINTER, but makes it
- * do what I want it to. I'd like to hint to ao2_callback that the arg is
- * of the same object type, so it can be passed to the hash function.
- * However, I don't want to imply that this is the object being searched for. */
- if (flags & OBJ_POINTER)
- cb_fn = match_by_addr;
- else
-#endif
- if (cb_fn == NULL) /* if NULL, match everything */
- cb_fn = cb_true;
- /*
- * XXX this can be optimized.
- * If we have a hash function and lookup by pointer,
- * run the hash function. Otherwise, scan the whole container
- * (this only for the time being. We need to optimize this.)
- */
- if ((flags & OBJ_POINTER)) /* we know hash can handle this case */
- i = c->hash_fn(arg, flags & OBJ_POINTER) % c->n_buckets;
- else /* don't know, let's scan all buckets */
- i = -1; /* XXX this must be fixed later. */
-
- /* determine the search boundaries: i..last-1 */
- if (i < 0) {
- i = 0;
- last = c->n_buckets;
- } else {
- last = i + 1;
- }
-
- ao2_lock(c); /* avoid modifications to the content */
-
- for (; i < last ; i++) {
- /* scan the list with prev-cur pointers */
- struct bucket_list *cur;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&c->buckets[i], cur, entry) {
- int match = cb_fn(EXTERNAL_OBJ(cur->astobj), arg, flags) & (CMP_MATCH | CMP_STOP);
-
- /* we found the object, performing operations according flags */
- if (match == 0) { /* no match, no stop, continue */
- continue;
- } else if (match == CMP_STOP) { /* no match but stop, we are done */
- i = last;
- break;
- }
- /* we have a match (CMP_MATCH) here */
- if (!(flags & OBJ_NODATA)) { /* if must return the object, record the value */
- /* it is important to handle this case before the unlink */
- ret = EXTERNAL_OBJ(cur->astobj);
- ao2_ref(ret, 1);
- }
-
- if (flags & OBJ_UNLINK) { /* must unlink */
- struct bucket_list *x = cur;
-
- /* we are going to modify the container, so update version */
- ast_atomic_fetchadd_int(&c->version, 1);
- AST_LIST_REMOVE_CURRENT(&c->buckets[i], entry);
- /* update number of elements and version */
- ast_atomic_fetchadd_int(&c->elements, -1);
- ao2_ref(EXTERNAL_OBJ(x->astobj), -1);
- free(x); /* free the link record */
- }
-
- if ((match & CMP_STOP) || (flags & OBJ_MULTIPLE) == 0) {
- /* We found the only match we need */
- i = last; /* force exit from outer loop */
- break;
- }
- if (!(flags & OBJ_NODATA)) {
-#if 0 /* XXX to be completed */
- /*
- * This is the multiple-return case. We need to link
- * the object in a list. The refcount is already increased.
- */
-#endif
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- }
- ao2_unlock(c);
- return ret;
-}
-
-/*!
- * the find function just invokes the default callback with some reasonable flags.
- */
-void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags)
-{
- return ao2_callback(c, flags, c->cmp_fn, arg);
-}
-
-/*!
- * initialize an iterator so we start from the first object
- */
-struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
-{
- struct ao2_iterator a = {
- .c = c,
- .flags = flags
- };
-
- return a;
-}
-
-/*
- * move to the next element in the container.
- */
-void * ao2_iterator_next(struct ao2_iterator *a)
-{
- int lim;
- struct bucket_list *p = NULL;
- void *ret = NULL;
-
- if (INTERNAL_OBJ(a->c) == NULL)
- return NULL;
-
- if (!(a->flags & F_AO2I_DONTLOCK))
- ao2_lock(a->c);
-
- /* optimization. If the container is unchanged and
- * we have a pointer, try follow it
- */
- if (a->c->version == a->c_version && (p = a->obj) ) {
- if ( (p = AST_LIST_NEXT(p, entry)) )
- goto found;
- /* nope, start from the next bucket */
- a->bucket++;
- a->version = 0;
- a->obj = NULL;
- }
-
- lim = a->c->n_buckets;
-
- /* Browse the buckets array, moving to the next
- * buckets if we don't find the entry in the current one.
- * Stop when we find an element with version number greater
- * than the current one (we reset the version to 0 when we
- * switch buckets).
- */
- for (; a->bucket < lim; a->bucket++, a->version = 0) {
- /* scan the current bucket */
- AST_LIST_TRAVERSE(&a->c->buckets[a->bucket], p, entry) {
- if (p->version > a->version)
- goto found;
- }
- }
-
-found:
- if (p) {
- a->version = p->version;
- a->obj = p;
- a->c_version = a->c->version;
- ret = EXTERNAL_OBJ(p->astobj);
- /* inc refcount of returned object */
- ao2_ref(ret, 1);
- }
-
- if (!(a->flags & F_AO2I_DONTLOCK))
- ao2_unlock(a->c);
-
- return ret;
-}
-
-/* callback for destroying container.
- * we can make it simple as we know what it does
- */
-static int cd_cb(void *obj, void *arg, int flag)
-{
- ao2_ref(obj, -1);
- return 0;
-}
-
-static void container_destruct(void *_c)
-{
- struct ao2_container *c = _c;
-
- ao2_callback(c, OBJ_UNLINK, cd_cb, NULL);
-
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_containers, -1);
-#endif
-}
-
-#ifdef AO2_DEBUG
-static int print_cb(void *obj, void *arg, int flag)
-{
- int *fd = arg;
- char *s = (char *)obj;
-
- ast_cli(*fd, "string <%s>\n", s);
- return 0;
-}
-
-/*
- * Print stats
- */
-static int handle_astobj2_stats(int fd, int argc, char *argv[])
-{
- ast_cli(fd, "Objects : %d\n", ao2.total_objects);
- ast_cli(fd, "Containers : %d\n", ao2.total_containers);
- ast_cli(fd, "Memory : %d\n", ao2.total_mem);
- ast_cli(fd, "Locked : %d\n", ao2.total_locked);
- ast_cli(fd, "Refs : %d\n", ao2.total_refs);
- return 0;
-}
-
-/*
- * This is testing code for astobj
- */
-static int handle_astobj2_test(int fd, int argc, char *argv[])
-{
- struct ao2_container *c1;
- int i, lim;
- char *obj;
- static int prof_id = -1;
-
- if (prof_id == -1)
- prof_id = ast_add_profile("ao2_alloc", 0);
-
- ast_cli(fd, "argc %d argv %s %s %s\n", argc, argv[0], argv[1], argv[2]);
- lim = atoi(argv[2]);
- ast_cli(fd, "called astobj_test\n");
-
- handle_astobj2_stats(fd, 0, NULL);
- /*
- * allocate a container with no default callback, and no hash function.
- * No hash means everything goes in the same bucket.
- */
- c1 = ao2_container_alloc(100, NULL /* no callback */, NULL /* no hash */);
- ast_cli(fd, "container allocated as %p\n", c1);
-
- /*
- * fill the container with objects.
- * ao2_alloc() gives us a reference which we pass to the
- * container when we do the insert.
- */
- for (i = 0; i < lim; i++) {
- ast_mark(prof_id, 1 /* start */);
- obj = ao2_alloc(80, NULL);
- ast_mark(prof_id, 0 /* stop */);
- ast_cli(fd, "object %d allocated as %p\n", i, obj);
- sprintf(obj, "-- this is obj %d --", i);
- ao2_link(c1, obj);
- }
- ast_cli(fd, "testing callbacks\n");
- ao2_callback(c1, 0, print_cb, &fd);
-
- ast_cli(fd, "testing iterators, remove every second object\n");
- {
- struct ao2_iterator ai;
- int x = 0;
-
- ai = ao2_iterator_init(c1, 0);
- while ( (obj = ao2_iterator_next(&ai)) ) {
- ast_cli(fd, "iterator on <%s>\n", obj);
- if (x++ & 1)
- ao2_unlink(c1, obj);
- ao2_ref(obj, -1);
- }
- ast_cli(fd, "testing iterators again\n");
- ai = ao2_iterator_init(c1, 0);
- while ( (obj = ao2_iterator_next(&ai)) ) {
- ast_cli(fd, "iterator on <%s>\n", obj);
- ao2_ref(obj, -1);
- }
- }
- ast_cli(fd, "testing callbacks again\n");
- ao2_callback(c1, 0, print_cb, &fd);
-
- ast_verbose("now you should see an error message:\n");
- ao2_ref(&i, -1); /* i is not a valid object so we print an error here */
-
- ast_cli(fd, "destroy container\n");
- ao2_ref(c1, -1); /* destroy container */
- handle_astobj2_stats(fd, 0, NULL);
- return 0;
-}
-
-static struct ast_cli_entry cli_astobj2[] = {
- { { "astobj2", "stats", NULL },
- handle_astobj2_stats, "Print astobj2 statistics", },
- { { "astobj2", "test", NULL } , handle_astobj2_test, "Test astobj2", },
-};
-#endif /* AO2_DEBUG */
-
-int astobj2_init(void)
-{
-#ifdef AO2_DEBUG
- ast_cli_register_multiple(cli_astobj2, ARRAY_LEN(cli_astobj2));
-#endif
-
- return 0;
-}
diff --git a/1.4/main/audiohook.c b/1.4/main/audiohook.c
deleted file mode 100644
index c6f1abec8..000000000
--- a/1.4/main/audiohook.c
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- *
- * \brief Audiohooks Architecture
- *
- * \author Joshua Colp <jcolp@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/audiohook.h"
-#include "asterisk/slinfactory.h"
-#include "asterisk/frame.h"
-#include "asterisk/translate.h"
-
-struct ast_audiohook_translate {
- struct ast_trans_pvt *trans_pvt;
- int format;
-};
-
-struct ast_audiohook_list {
- struct ast_audiohook_translate in_translate[2];
- struct ast_audiohook_translate out_translate[2];
- AST_LIST_HEAD_NOLOCK(, ast_audiohook) spy_list;
- AST_LIST_HEAD_NOLOCK(, ast_audiohook) whisper_list;
- AST_LIST_HEAD_NOLOCK(, ast_audiohook) manipulate_list;
-};
-
-/*! \brief Initialize an audiohook structure
- * \param audiohook Audiohook structure
- * \param type
- * \param source
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
-{
- /* Need to keep the type and source */
- audiohook->type = type;
- audiohook->source = source;
-
- /* Initialize lock that protects our audiohook */
- ast_mutex_init(&audiohook->lock);
- ast_cond_init(&audiohook->trigger, NULL);
-
- /* Setup the factories that are needed for this audiohook type */
- switch (type) {
- case AST_AUDIOHOOK_TYPE_SPY:
- ast_slinfactory_init(&audiohook->read_factory);
- case AST_AUDIOHOOK_TYPE_WHISPER:
- ast_slinfactory_init(&audiohook->write_factory);
- break;
- default:
- break;
- }
-
- /* Since we are just starting out... this audiohook is new */
- audiohook->status = AST_AUDIOHOOK_STATUS_NEW;
-
- return 0;
-}
-
-/*! \brief Destroys an audiohook structure
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_destroy(struct ast_audiohook *audiohook)
-{
- /* Drop the factories used by this audiohook type */
- switch (audiohook->type) {
- case AST_AUDIOHOOK_TYPE_SPY:
- ast_slinfactory_destroy(&audiohook->read_factory);
- case AST_AUDIOHOOK_TYPE_WHISPER:
- ast_slinfactory_destroy(&audiohook->write_factory);
- break;
- default:
- break;
- }
-
- /* Destroy translation path if present */
- if (audiohook->trans_pvt)
- ast_translator_free_path(audiohook->trans_pvt);
-
- /* Lock and trigger be gone! */
- ast_cond_destroy(&audiohook->trigger);
- ast_mutex_destroy(&audiohook->lock);
-
- return 0;
-}
-
-/*! \brief Writes a frame into the audiohook structure
- * \param audiohook Audiohook structure
- * \param direction Direction the audio frame came from
- * \param frame Frame to write in
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame)
-{
- struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
- struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
- struct timeval *time = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *time;
-
- /* Update last feeding time to be current */
- *time = ast_tvnow();
-
- /* If we are using a sync trigger and this factory suddenly got audio fed in after a lapse, then flush both factories to ensure they remain in sync */
- if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && ast_slinfactory_available(other_factory) && (ast_tvdiff_ms(*time, previous_time) > (ast_slinfactory_available(other_factory) / 8))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Flushing audiohook %p so it remains in sync\n", audiohook);
- ast_slinfactory_flush(factory);
- ast_slinfactory_flush(other_factory);
- }
-
- /* Write frame out to respective factory */
- ast_slinfactory_feed(factory, frame);
-
- /* If we need to notify the respective handler of this audiohook, do so */
- if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) {
- ast_cond_signal(&audiohook->trigger);
- } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) {
- ast_cond_signal(&audiohook->trigger);
- } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
- ast_cond_signal(&audiohook->trigger);
- }
-
- return 0;
-}
-
-static struct ast_frame *audiohook_read_frame_single(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction)
-{
- struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
- int vol = (direction == AST_AUDIOHOOK_DIRECTION_READ ? audiohook->options.read_volume : audiohook->options.write_volume);
- short buf[samples];
- struct ast_frame frame = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_SLINEAR,
- .data = buf,
- .datalen = sizeof(buf),
- .samples = samples,
- };
-
- /* Ensure the factory is able to give us the samples we want */
- if (samples > ast_slinfactory_available(factory))
- return NULL;
-
- /* Read data in from factory */
- if (!ast_slinfactory_read(factory, buf, samples))
- return NULL;
-
- /* If a volume adjustment needs to be applied apply it */
- if (vol)
- ast_frame_adjust_volume(&frame, vol);
-
- return ast_frdup(&frame);
-}
-
-static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples)
-{
- int i = 0, usable_read, usable_write;
- short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
- struct ast_frame frame = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_SLINEAR,
- .data = NULL,
- .datalen = sizeof(buf1),
- .samples = samples,
- };
-
- /* Make sure both factories have the required samples */
- usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
- usable_write = (ast_slinfactory_available(&audiohook->write_factory) >= samples ? 1 : 0);
-
- if (!usable_read && !usable_write) {
- /* If both factories are unusable bail out */
- if (option_debug)
- ast_log(LOG_DEBUG, "Read factory %p and write factory %p both fail to provide %zd samples\n", &audiohook->read_factory, &audiohook->write_factory, samples);
- return NULL;
- }
-
- /* If we want to provide only a read factory make sure we aren't waiting for other audio */
- if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Write factory %p was pretty quick last time, waiting for them.\n", &audiohook->write_factory);
- return NULL;
- }
-
- /* If we want to provide only a write factory make sure we aren't waiting for other audio */
- if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
- return NULL;
- }
-
- /* Start with the read factory... if there are enough samples, read them in */
- if (usable_read && ast_slinfactory_available(&audiohook->read_factory) >= samples) {
- if (ast_slinfactory_read(&audiohook->read_factory, buf1, samples)) {
- read_buf = buf1;
- /* Adjust read volume if need be */
- if (audiohook->options.read_volume) {
- int count = 0;
- short adjust_value = abs(audiohook->options.read_volume);
- for (count = 0; count < samples; count++) {
- if (audiohook->options.read_volume > 0)
- ast_slinear_saturated_multiply(&buf1[count], &adjust_value);
- else if (audiohook->options.read_volume < 0)
- ast_slinear_saturated_divide(&buf1[count], &adjust_value);
- }
- }
- }
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Failed to get %zd samples from read factory %p\n", samples, &audiohook->read_factory);
-
- /* Move on to the write factory... if there are enough samples, read them in */
- if (usable_write && ast_slinfactory_available(&audiohook->write_factory) >= samples) {
- if (ast_slinfactory_read(&audiohook->write_factory, buf2, samples)) {
- write_buf = buf2;
- /* Adjust write volume if need be */
- if (audiohook->options.write_volume) {
- int count = 0;
- short adjust_value = abs(audiohook->options.write_volume);
- for (count = 0; count < samples; count++) {
- if (audiohook->options.write_volume > 0)
- ast_slinear_saturated_multiply(&buf2[count], &adjust_value);
- else if (audiohook->options.write_volume < 0)
- ast_slinear_saturated_divide(&buf2[count], &adjust_value);
- }
- }
- }
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Failed to get %zd samples from write factory %p\n", samples, &audiohook->write_factory);
-
- /* Basically we figure out which buffer to use... and if mixing can be done here */
- if (!read_buf && !write_buf)
- return NULL;
- else if (read_buf && write_buf) {
- for (i = 0, data1 = read_buf, data2 = write_buf; i < samples; i++, data1++, data2++)
- ast_slinear_saturated_add(data1, data2);
- final_buf = buf1;
- } else if (read_buf)
- final_buf = buf1;
- else if (write_buf)
- final_buf = buf2;
-
- /* Make the final buffer part of the frame, so it gets duplicated fine */
- frame.data = final_buf;
-
- /* Yahoo, a combined copy of the audio! */
- return ast_frdup(&frame);
-}
-
-/*! \brief Reads a frame in from the audiohook structure
- * \param audiohook Audiohook structure
- * \param samples Number of samples wanted
- * \param direction Direction the audio frame came from
- * \param format Format of frame remote side wants back
- * \return Returns frame on success, NULL on failure
- */
-struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, int format)
-{
- struct ast_frame *read_frame = NULL, *final_frame = NULL;
-
- if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction))))
- return NULL;
-
- /* If they don't want signed linear back out, we'll have to send it through the translation path */
- if (format != AST_FORMAT_SLINEAR) {
- /* Rebuild translation path if different format then previously */
- if (audiohook->format != format) {
- if (audiohook->trans_pvt) {
- ast_translator_free_path(audiohook->trans_pvt);
- audiohook->trans_pvt = NULL;
- }
- /* Setup new translation path for this format... if we fail we can't very well return signed linear so free the frame and return nothing */
- if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) {
- ast_frfree(read_frame);
- return NULL;
- }
- }
- /* Convert to requested format, and allow the read in frame to be freed */
- final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1);
- } else {
- final_frame = read_frame;
- }
-
- return final_frame;
-}
-
-/*! \brief Attach audiohook to channel
- * \param chan Channel
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
-{
- ast_channel_lock(chan);
-
- if (!chan->audiohooks) {
- /* Whoops... allocate a new structure */
- if (!(chan->audiohooks = ast_calloc(1, sizeof(*chan->audiohooks)))) {
- ast_channel_unlock(chan);
- return -1;
- }
- AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->spy_list);
- AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->whisper_list);
- AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->manipulate_list);
- }
-
- /* Drop into respective list */
- if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
- AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list);
- else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
- AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list);
- else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
- AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list);
-
- /* Change status over to running since it is now attached */
- audiohook->status = AST_AUDIOHOOK_STATUS_RUNNING;
-
- ast_channel_unlock(chan);
-
- return 0;
-}
-
-/*! \brief Detach audiohook from channel
- * \param audiohook Audiohook structure
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach(struct ast_audiohook *audiohook)
-{
- if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE)
- return 0;
-
- audiohook->status = AST_AUDIOHOOK_STATUS_SHUTDOWN;
-
- while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE)
- ast_audiohook_trigger_wait(audiohook);
-
- return 0;
-}
-
-/*! \brief Detach audiohooks from list and destroy said list
- * \param audiohook_list List of audiohooks
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list)
-{
- int i = 0;
- struct ast_audiohook *audiohook = NULL;
-
- /* Drop any spies */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- AST_LIST_REMOVE_CURRENT(&audiohook_list->spy_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_cond_signal(&audiohook->trigger);
- ast_audiohook_unlock(audiohook);
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- /* Drop any whispering sources */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- AST_LIST_REMOVE_CURRENT(&audiohook_list->whisper_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_cond_signal(&audiohook->trigger);
- ast_audiohook_unlock(audiohook);
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- /* Drop any manipulaters */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- AST_LIST_REMOVE_CURRENT(&audiohook_list->manipulate_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_audiohook_unlock(audiohook);
- audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- /* Drop translation paths if present */
- for (i = 0; i < 2; i++) {
- if (audiohook_list->in_translate[i].trans_pvt)
- ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt);
- if (audiohook_list->out_translate[i].trans_pvt)
- ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt);
- }
-
- /* Free ourselves */
- ast_free(audiohook_list);
-
- return 0;
-}
-
-static struct ast_audiohook *find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source)
-{
- struct ast_audiohook *audiohook = NULL;
-
- AST_LIST_TRAVERSE(&audiohook_list->spy_list, audiohook, list) {
- if (!strcasecmp(audiohook->source, source))
- return audiohook;
- }
-
- AST_LIST_TRAVERSE(&audiohook_list->whisper_list, audiohook, list) {
- if (!strcasecmp(audiohook->source, source))
- return audiohook;
- }
-
- AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, audiohook, list) {
- if (!strcasecmp(audiohook->source, source))
- return audiohook;
- }
-
- return NULL;
-}
-
-/*! \brief Detach specified source audiohook from channel
- * \param chan Channel to detach from
- * \param source Name of source to detach
- * \return Returns 0 on success, -1 on failure
- */
-int ast_audiohook_detach_source(struct ast_channel *chan, const char *source)
-{
- struct ast_audiohook *audiohook = NULL;
-
- ast_channel_lock(chan);
-
- /* Ensure the channel has audiohooks on it */
- if (!chan->audiohooks) {
- ast_channel_unlock(chan);
- return -1;
- }
-
- audiohook = find_audiohook_by_source(chan->audiohooks, source);
-
- ast_channel_unlock(chan);
-
- if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE)
- audiohook->status = AST_AUDIOHOOK_STATUS_SHUTDOWN;
-
- return (audiohook ? 0 : -1);
-}
-
-/*! \brief Pass a DTMF frame off to be handled by the audiohook core
- * \param chan Channel that the list is coming off of
- * \param audiohook_list List of audiohooks
- * \param direction Direction frame is coming in from
- * \param frame The frame itself
- * \return Return frame on success, NULL on failure
- */
-static struct ast_frame *dtmf_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
-{
- struct ast_audiohook *audiohook = NULL;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
- AST_LIST_REMOVE_CURRENT(&audiohook_list->manipulate_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_audiohook_unlock(audiohook);
- audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
- continue;
- }
- if (ast_test_flag(audiohook, AST_AUDIOHOOK_WANTS_DTMF))
- audiohook->manipulate_callback(audiohook, chan, frame, direction);
- ast_audiohook_unlock(audiohook);
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- return frame;
-}
-
-/*! \brief Pass an AUDIO frame off to be handled by the audiohook core
- * \param chan Channel that the list is coming off of
- * \param audiohook_list List of audiohooks
- * \param direction Direction frame is coming in from
- * \param frame The frame itself
- * \return Return frame on success, NULL on failure
- */
-static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
-{
- struct ast_audiohook_translate *in_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->in_translate[0] : &audiohook_list->in_translate[1]);
- struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
- struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
- struct ast_audiohook *audiohook = NULL;
- int samples = frame->samples;
-
- /* If the frame coming in is not signed linear we have to send it through the in_translate path */
- if (frame->subclass != AST_FORMAT_SLINEAR) {
- if (in_translate->format != frame->subclass) {
- if (in_translate->trans_pvt)
- ast_translator_free_path(in_translate->trans_pvt);
- if (!(in_translate->trans_pvt = ast_translator_build_path(AST_FORMAT_SLINEAR, frame->subclass)))
- return frame;
- in_translate->format = frame->subclass;
- }
- if (!(middle_frame = ast_translate(in_translate->trans_pvt, frame, 0)))
- return frame;
- }
-
- /* Queue up signed linear frame to each spy */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
- AST_LIST_REMOVE_CURRENT(&audiohook_list->spy_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_cond_signal(&audiohook->trigger);
- ast_audiohook_unlock(audiohook);
- continue;
- }
- ast_audiohook_write_frame(audiohook, direction, middle_frame);
- ast_audiohook_unlock(audiohook);
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- /* If this frame is being written out to the channel then we need to use whisper sources */
- if (direction == AST_AUDIOHOOK_DIRECTION_WRITE && !AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
- int i = 0;
- short read_buf[samples], combine_buf[samples], *data1 = NULL, *data2 = NULL;
- memset(&combine_buf, 0, sizeof(combine_buf));
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
- AST_LIST_REMOVE_CURRENT(&audiohook_list->whisper_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_cond_signal(&audiohook->trigger);
- ast_audiohook_unlock(audiohook);
- continue;
- }
- if (ast_slinfactory_available(&audiohook->write_factory) >= samples && ast_slinfactory_read(&audiohook->write_factory, read_buf, samples)) {
- /* Take audio from this whisper source and combine it into our main buffer */
- for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++)
- ast_slinear_saturated_add(data1, data2);
- }
- ast_audiohook_unlock(audiohook);
- }
- AST_LIST_TRAVERSE_SAFE_END
- /* We take all of the combined whisper sources and combine them into the audio being written out */
- for (i = 0, data1 = middle_frame->data, data2 = combine_buf; i < samples; i++, data1++, data2++)
- ast_slinear_saturated_add(data1, data2);
- end_frame = middle_frame;
- }
-
- /* Pass off frame to manipulate audiohooks */
- if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
- AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
- ast_audiohook_lock(audiohook);
- if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
- AST_LIST_REMOVE_CURRENT(&audiohook_list->manipulate_list, list);
- audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
- ast_audiohook_unlock(audiohook);
- /* We basically drop all of our links to the manipulate audiohook and prod it to do it's own destructive things */
- audiohook->manipulate_callback(audiohook, chan, NULL, direction);
- continue;
- }
- /* Feed in frame to manipulation */
- audiohook->manipulate_callback(audiohook, chan, middle_frame, direction);
- ast_audiohook_unlock(audiohook);
- }
- AST_LIST_TRAVERSE_SAFE_END
- end_frame = middle_frame;
- }
-
- /* Now we figure out what to do with our end frame (whether to transcode or not) */
- if (middle_frame == end_frame) {
- /* Middle frame was modified and became the end frame... let's see if we need to transcode */
- if (end_frame->subclass != start_frame->subclass) {
- if (out_translate->format != start_frame->subclass) {
- if (out_translate->trans_pvt)
- ast_translator_free_path(out_translate->trans_pvt);
- if (!(out_translate->trans_pvt = ast_translator_build_path(start_frame->subclass, AST_FORMAT_SLINEAR))) {
- /* We can't transcode this... drop our middle frame and return the original */
- ast_frfree(middle_frame);
- return start_frame;
- }
- out_translate->format = start_frame->subclass;
- }
- /* Transcode from our middle (signed linear) frame to new format of the frame that came in */
- if (!(end_frame = ast_translate(out_translate->trans_pvt, middle_frame, 0))) {
- /* Failed to transcode the frame... drop it and return the original */
- ast_frfree(middle_frame);
- return start_frame;
- }
- /* Here's the scoop... middle frame is no longer of use to us */
- ast_frfree(middle_frame);
- }
- } else {
- /* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
- ast_frfree(middle_frame);
- }
-
- return end_frame;
-}
-
-/*! \brief Pass a frame off to be handled by the audiohook core
- * \param chan Channel that the list is coming off of
- * \param audiohook_list List of audiohooks
- * \param direction Direction frame is coming in from
- * \param frame The frame itself
- * \return Return frame on success, NULL on failure
- */
-struct ast_frame *ast_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
-{
- /* Pass off frame to it's respective list write function */
- if (frame->frametype == AST_FRAME_VOICE)
- return audio_audiohook_write_list(chan, audiohook_list, direction, frame);
- else if (frame->frametype == AST_FRAME_DTMF)
- return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame);
- else
- return frame;
-}
-
-
-/*! \brief Wait for audiohook trigger to be triggered
- * \param audiohook Audiohook to wait on
- */
-void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
-{
- struct timeval tv;
- struct timespec ts;
-
- tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
-
- ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts);
-
- return;
-}
diff --git a/1.4/main/autoservice.c b/1.4/main/autoservice.c
deleted file mode 100644
index 88ab0d4e6..000000000
--- a/1.4/main/autoservice.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2008, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Russell Bryant <russell@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.
- */
-
-/*! \file
- *
- * \brief Automatic channel service routines
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Russell Bryant <russell@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "asterisk/pbx.h"
-#include "asterisk/frame.h"
-#include "asterisk/sched.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/file.h"
-#include "asterisk/translate.h"
-#include "asterisk/manager.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/indications.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-#define MAX_AUTOMONS 1500
-
-struct asent {
- struct ast_channel *chan;
- /*! This gets incremented each time autoservice gets started on the same
- * channel. It will ensure that it doesn't actually get stopped until
- * it gets stopped for the last time. */
- unsigned int use_count;
- unsigned int orig_end_dtmf_flag:1;
- AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
- AST_LIST_ENTRY(asent) list;
-};
-
-static AST_LIST_HEAD_STATIC(aslist, asent);
-static ast_cond_t as_cond;
-
-static pthread_t asthread = AST_PTHREADT_NULL;
-
-static int as_chan_list_state;
-
-static void defer_frame(struct ast_channel *chan, struct ast_frame *f)
-{
- struct ast_frame *dup_f;
- struct asent *as;
-
- AST_LIST_LOCK(&aslist);
- AST_LIST_TRAVERSE(&aslist, as, list) {
- if (as->chan != chan)
- continue;
- if ((dup_f = ast_frdup(f)))
- AST_LIST_INSERT_TAIL(&as->dtmf_frames, dup_f, frame_list);
- }
- AST_LIST_UNLOCK(&aslist);
-}
-
-static void *autoservice_run(void *ign)
-{
- for (;;) {
- struct ast_channel *mons[MAX_AUTOMONS];
- struct ast_channel *chan;
- struct asent *as;
- int x = 0, ms = 50;
-
- AST_LIST_LOCK(&aslist);
-
- /* At this point, we know that no channels that have been removed are going
- * to get used again. */
- as_chan_list_state++;
-
- if (AST_LIST_EMPTY(&aslist))
- ast_cond_wait(&as_cond, &aslist.lock);
-
- AST_LIST_TRAVERSE(&aslist, as, list) {
- if (!as->chan->_softhangup) {
- if (x < MAX_AUTOMONS)
- mons[x++] = as->chan;
- else
- ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n");
- }
- }
-
- AST_LIST_UNLOCK(&aslist);
-
- chan = ast_waitfor_n(mons, x, &ms);
- if (chan) {
- struct ast_frame *f = ast_read(chan);
-
- if (!f) {
- struct ast_frame hangup_frame = { 0, };
- /* No frame means the channel has been hung up.
- * A hangup frame needs to be queued here as ast_waitfor() may
- * never return again for the condition to be detected outside
- * of autoservice. So, we'll leave a HANGUP queued up so the
- * thread in charge of this channel will know. */
-
- hangup_frame.frametype = AST_FRAME_CONTROL;
- hangup_frame.subclass = AST_CONTROL_HANGUP;
-
- defer_frame(chan, &hangup_frame);
-
- continue;
- }
-
- /* Do not add a default entry in this switch statement. Each new
- * frame type should be addressed directly as to whether it should
- * be queued up or not. */
- switch (f->frametype) {
- /* Save these frames */
- case AST_FRAME_DTMF_END:
- case AST_FRAME_CONTROL:
- case AST_FRAME_TEXT:
- case AST_FRAME_IMAGE:
- case AST_FRAME_HTML:
- defer_frame(chan, f);
- break;
-
- /* Throw these frames away */
- case AST_FRAME_DTMF_BEGIN:
- case AST_FRAME_VOICE:
- case AST_FRAME_VIDEO:
- case AST_FRAME_NULL:
- case AST_FRAME_IAX:
- case AST_FRAME_CNG:
- case AST_FRAME_MODEM:
- break;
- }
-
- if (f)
- ast_frfree(f);
- }
- }
- asthread = AST_PTHREADT_NULL;
- return NULL;
-}
-
-int ast_autoservice_start(struct ast_channel *chan)
-{
- int res = 0;
- struct asent *as;
-
- /* Check if the channel already has autoservice */
- AST_LIST_LOCK(&aslist);
- AST_LIST_TRAVERSE(&aslist, as, list) {
- if (as->chan == chan) {
- as->use_count++;
- break;
- }
- }
- AST_LIST_UNLOCK(&aslist);
-
- if (as) {
- /* Entry exists, autoservice is already handling this channel */
- return 0;
- }
-
- if (!(as = ast_calloc(1, sizeof(*as))))
- return -1;
-
- /* New entry created */
- as->chan = chan;
- as->use_count = 1;
-
- ast_channel_lock(chan);
- as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0;
- if (!as->orig_end_dtmf_flag)
- ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
- ast_channel_unlock(chan);
-
- AST_LIST_LOCK(&aslist);
- if (AST_LIST_EMPTY(&aslist))
- ast_cond_signal(&as_cond);
- AST_LIST_INSERT_HEAD(&aslist, as, list);
- AST_LIST_UNLOCK(&aslist);
-
- if (asthread == AST_PTHREADT_NULL) { /* need start the thread */
- if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) {
- ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
- /* There will only be a single member in the list at this point,
- the one we just added. */
- AST_LIST_LOCK(&aslist);
- AST_LIST_REMOVE(&aslist, as, list);
- AST_LIST_UNLOCK(&aslist);
- free(as);
- res = -1;
- } else
- pthread_kill(asthread, SIGURG);
- }
-
- return res;
-}
-
-int ast_autoservice_stop(struct ast_channel *chan)
-{
- int res = -1;
- struct asent *as;
- AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
- struct ast_frame *f;
- int removed = 0;
- int orig_end_dtmf_flag = 0;
- int chan_list_state;
-
- AST_LIST_HEAD_INIT_NOLOCK(&dtmf_frames);
-
- AST_LIST_LOCK(&aslist);
-
- /* Save the autoservice channel list state. We _must_ verify that the channel
- * list has been rebuilt before we return. Because, after we return, the channel
- * could get destroyed and we don't want our poor autoservice thread to step on
- * it after its gone! */
- chan_list_state = as_chan_list_state;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {
- if (as->chan == chan) {
- as->use_count--;
- if (as->use_count)
- break;
- AST_LIST_REMOVE_CURRENT(&aslist, list);
- AST_LIST_APPEND_LIST(&dtmf_frames, &as->dtmf_frames, frame_list);
- orig_end_dtmf_flag = as->orig_end_dtmf_flag;
- free(as);
- removed = 1;
- if (!chan->_softhangup)
- res = 0;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- if (removed && asthread != AST_PTHREADT_NULL)
- pthread_kill(asthread, SIGURG);
-
- AST_LIST_UNLOCK(&aslist);
-
- if (!removed)
- return 0;
-
- if (!orig_end_dtmf_flag)
- ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
-
- while ((f = AST_LIST_REMOVE_HEAD(&dtmf_frames, frame_list))) {
- ast_queue_frame(chan, f);
- ast_frfree(f);
- }
-
- while (chan_list_state == as_chan_list_state)
- usleep(1000);
-
- return res;
-}
-
-void ast_autoservice_init(void)
-{
- ast_cond_init(&as_cond, NULL);
-}
diff --git a/1.4/main/buildinfo.c b/1.4/main/buildinfo.c
deleted file mode 100644
index 964e06eb3..000000000
--- a/1.4/main/buildinfo.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- *
- * \brief Build timestamp variables
- *
- * \author Kevin P. Fleming <kpfleming@digium.com>
- */
-
-#include "asterisk/build.h"
-
-const char *ast_build_hostname = BUILD_HOSTNAME;
-const char *ast_build_kernel = BUILD_KERNEL;
-const char *ast_build_machine = BUILD_MACHINE;
-const char *ast_build_os = BUILD_OS;
-const char *ast_build_date = BUILD_DATE;
-const char *ast_build_user = BUILD_USER;
diff --git a/1.4/main/callerid.c b/1.4/main/callerid.c
deleted file mode 100644
index 38789c790..000000000
--- a/1.4/main/callerid.c
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief CallerID Generation support
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <time.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <math.h>
-#include <ctype.h>
-
-#include "asterisk/ulaw.h"
-#include "asterisk/alaw.h"
-#include "asterisk/frame.h"
-#include "asterisk/channel.h"
-#include "asterisk/callerid.h"
-#include "asterisk/logger.h"
-#include "asterisk/fskmodem.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-
-struct callerid_state {
- fsk_data fskd;
- char rawdata[256];
- short oldstuff[160];
- int oldlen;
- int pos;
- int type;
- int cksum;
- char name[64];
- char number[64];
- int flags;
- int sawflag;
- int len;
-
- int skipflag;
- unsigned short crc;
-};
-
-
-float cid_dr[4], cid_di[4];
-float clidsb = 8000.0 / 1200.0;
-float sasdr, sasdi;
-float casdr1, casdi1, casdr2, casdi2;
-
-#define CALLERID_SPACE 2200.0 /*!< 2200 hz for "0" */
-#define CALLERID_MARK 1200.0 /*!< 1200 hz for "1" */
-#define SAS_FREQ 440.0
-#define CAS_FREQ1 2130.0
-#define CAS_FREQ2 2750.0
-
-#define AST_CALLERID_UNKNOWN "<unknown>"
-
-static inline void gen_tones(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
-{
- int x;
- float t;
- for (x=0;x<len;x++) {
- t = *cr1 * ddr1 - *ci1 * ddi1;
- *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
- *cr1 = t;
- t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
- *cr1 *= t;
- *ci1 *= t;
-
- t = *cr2 * ddr2 - *ci2 * ddi2;
- *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
- *cr2 = t;
- t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
- *cr2 *= t;
- *ci2 *= t;
- buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
- }
-}
-
-static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
-{
- int x;
- float t;
- for (x=0;x<len;x++) {
- t = *cr1 * ddr1 - *ci1 * ddi1;
- *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
- *cr1 = t;
- t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
- *cr1 *= t;
- *ci1 *= t;
- buf[x] = AST_LIN2X(*cr1 * 8192.0);
- }
-}
-
-/*! \brief Initialize stuff for inverse FFT */
-void callerid_init(void)
-{
- cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
- cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
- cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
- cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
- sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
- sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
- casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
- casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
- casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
- casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
-}
-
-struct callerid_state *callerid_new(int cid_signalling)
-{
- struct callerid_state *cid;
-
- if ((cid = ast_calloc(1, sizeof(*cid)))) {
- cid->fskd.spb = 7.0; /* 1200 baud */
- /* cid->fskd.hdlc = 0; */ /* Async */
- cid->fskd.nbit = 8; /* 8 bits */
- cid->fskd.nstop = 1.0; /* 1 stop bit */
- /* cid->fskd.paridad = 0; */ /* No parity */
- cid->fskd.bw = 1; /* Filter 800 Hz */
- if (cid_signalling == 2) { /* v23 signalling */
- cid->fskd.f_mark_idx = 4; /* 1300 Hz */
- cid->fskd.f_space_idx = 5; /* 2100 Hz */
- } else { /* Bell 202 signalling as default */
- cid->fskd.f_mark_idx = 2; /* 1200 Hz */
- cid->fskd.f_space_idx = 3; /* 2200 Hz */
- }
- /* cid->fskd.pcola = 0; */ /* No clue */
- /* cid->fskd.cont = 0.0; */ /* Digital PLL reset */
- /* cid->fskd.x0 = 0.0; */
- /* cid->fskd.state = 0; */
- cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
- /* cid->pos = 0; */
- }
-
- return cid;
-}
-
-void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
-{
- *flags = cid->flags;
- if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NAME))
- *name = NULL;
- else
- *name = cid->name;
- if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
- *number = NULL;
- else
- *number = cid->number;
-}
-
-void callerid_get_dtmf(char *cidstring, char *number, int *flags)
-{
- int i;
- int code;
-
- /* "Clear" the number-buffer. */
- number[0] = 0;
-
- if (strlen(cidstring) < 2) {
- ast_log(LOG_DEBUG, "No cid detected\n");
- *flags = CID_UNKNOWN_NUMBER;
- return;
- }
-
- /* Detect protocol and special types */
- if (cidstring[0] == 'B') {
- /* Handle special codes */
- code = atoi(&cidstring[1]);
- if (code == 0)
- *flags = CID_UNKNOWN_NUMBER;
- else if (code == 10)
- *flags = CID_PRIVATE_NUMBER;
- else
- ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code);
- } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
- /* .DK special code */
- if (cidstring[1] == '1')
- *flags = CID_PRIVATE_NUMBER;
- if (cidstring[1] == '2' || cidstring[1] == '3')
- *flags = CID_UNKNOWN_NUMBER;
- } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
- /* "Standard" callerid */
- for (i = 1; i < strlen(cidstring); i++ ) {
- if (cidstring[i] == 'C' || cidstring[i] == '#')
- break;
- if (isdigit(cidstring[i]))
- number[i-1] = cidstring[i];
- else
- ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n",
- cidstring[i]);
- }
- number[i-1] = 0;
- } else if (isdigit(cidstring[0])) {
- /* It begins with a digit, so we parse it as a number and hope
- * for the best */
- ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
- "parsing might be unreliable\n");
- for (i = 0; i < strlen(cidstring); i++) {
- if (isdigit(cidstring[i]))
- number[i] = cidstring[i];
- else
- break;
- }
- number[i] = 0;
- } else {
- ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n",
- cidstring[0]);
- *flags = CID_UNKNOWN_NUMBER;
- }
-}
-
-int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
-{
- int pos = 0;
- int saslen=2400;
- float cr1 = 1.0;
- float ci1 = 0.0;
- float cr2 = 1.0;
- float ci2 = 0.0;
- if (sendsas) {
- if (len < saslen)
- return -1;
- gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
- len -= saslen;
- pos += saslen;
- cr2 = cr1;
- ci2 = ci1;
- }
- gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
- return 0;
-}
-
-static unsigned short calc_crc(unsigned short crc, unsigned char data)
-{
- unsigned int i, j, org, dst;
- org = data;
- dst = 0;
-
- for (i=0; i < CHAR_BIT; i++) {
- org <<= 1;
- dst >>= 1;
- if (org & 0x100) {
- dst |= 0x80;
- }
- }
- data = (unsigned char)dst;
- crc ^= (unsigned int)data << (16 - CHAR_BIT);
- for ( j=0; j<CHAR_BIT; j++ ) {
- if ( crc & 0x8000U )
- crc = (crc << 1) ^ 0x1021U ;
- else
- crc <<= 1 ;
- }
- return crc;
-}
-
-int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
-{
- int mylen = len;
- int olen;
- int b = 'X';
- int b2 ;
- int res;
- int x;
- short *buf;
- short *obuf;
-
- if (!(buf = ast_calloc(1, 2 * len + cid->oldlen))) {
- return -1;
- }
-
- obuf = buf;
- memcpy(buf, cid->oldstuff, cid->oldlen);
- mylen += cid->oldlen/2;
-
- for (x=0;x<len;x++)
- buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
-
- while (mylen >= 160) {
- b = b2 = 0;
- olen = mylen;
- res = fsk_serie(&cid->fskd, buf, &mylen, &b);
-
- if (mylen < 0) {
- ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
- free(obuf);
- return -1;
- }
-
- buf += (olen - mylen);
-
- if (res < 0) {
- ast_log(LOG_NOTICE, "fsk_serie failed\n");
- free(obuf);
- return -1;
- }
-
- if (res == 1) {
-
- b2 = b ;
- b = b & 0x7f ;
-
- /* crc checksum calculation */
- if ( cid->sawflag > 1 ) {
- cid->crc = calc_crc(cid->crc, (unsigned char)b2);
- }
-
- /* Ignore invalid bytes */
- if (b > 0xff) {
- continue;
- }
-
- /* skip DLE if needed */
- if ( cid->sawflag > 0 ) {
- if ( cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10 ) {
- cid->skipflag = 1 ;
- continue ;
- }
- }
- if ( cid->skipflag == 1 ) {
- cid->skipflag = 0 ;
- }
-
- /* caller id retrieval */
- switch(cid->sawflag) {
- case 0: /* DLE */
- if (b == 0x10) {
- cid->sawflag = 1;
- cid->skipflag = 0;
- cid->crc = 0;
- }
- break;
- case 1: /* SOH */
- if (b == 0x01) {
- cid->sawflag = 2;
- }
- break ;
- case 2: /* HEADER */
- if (b == 0x07) {
- cid->sawflag = 3;
- }
- break;
- case 3: /* STX */
- if (b == 0x02) {
- cid->sawflag = 4;
- }
- break;
- case 4: /* SERVICE TYPE */
- if (b == 0x40) {
- cid->sawflag = 5;
- }
- break;
- case 5: /* Frame Length */
- cid->sawflag = 6;
- break;
- case 6: /* NUMBER TYPE */
- cid->sawflag = 7;
- cid->pos = 0;
- cid->rawdata[cid->pos++] = b;
- break;
- case 7: /* NUMBER LENGTH */
- cid->sawflag = 8;
- cid->len = b;
- if ( (cid->len+2) >= sizeof( cid->rawdata ) ) {
- ast_log(LOG_WARNING, "too long caller id string\n" ) ;
- free(obuf);
- return -1;
- }
- cid->rawdata[cid->pos++] = b;
- break;
- case 8: /* Retrieve message */
- cid->rawdata[cid->pos++] = b;
- cid->len--;
- if (cid->len<=0) {
- cid->rawdata[cid->pos] = '\0';
- cid->sawflag = 9;
- }
- break;
- case 9: /* ETX */
- cid->sawflag = 10;
- break;
- case 10: /* CRC Checksum 1 */
- cid->sawflag = 11;
- break;
- case 11: /* CRC Checksum 2 */
- cid->sawflag = 12;
- if ( cid->crc != 0 ) {
- ast_log(LOG_WARNING, "crc checksum error\n" ) ;
- free(obuf);
- return -1;
- }
- /* extract caller id data */
- for (x=0; x<cid->pos; ) {
- switch (cid->rawdata[x++]) {
- case 0x02: /* caller id number */
- cid->number[0] = '\0';
- cid->name[0] = '\0';
- cid->flags = 0;
- res = cid->rawdata[x++];
- ast_copy_string(cid->number, &cid->rawdata[x], res+1 );
- x += res;
- break;
- case 0x21: /* additional information */
- /* length */
- x++;
- /* number type */
- switch (cid->rawdata[x]) {
- case 0x00: /* unknown */
- case 0x01: /* international number */
- case 0x02: /* domestic number */
- case 0x03: /* network */
- case 0x04: /* local call */
- case 0x06: /* short dial number */
- case 0x07: /* reserved */
- default: /* reserved */
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "cid info:#1=%X\n", cid->rawdata[x]);
- break ;
- }
- x++;
- /* numbering plan octed 4 */
- x++;
- /* numbering plan octed 5 */
- switch (cid->rawdata[x]) {
- case 0x00: /* unknown */
- case 0x01: /* recommendation E.164 ISDN */
- case 0x03: /* recommendation X.121 */
- case 0x04: /* telex dial plan */
- case 0x08: /* domestic dial plan */
- case 0x09: /* private dial plan */
- case 0x05: /* reserved */
- default: /* reserved */
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "cid info:#2=%X\n", cid->rawdata[x]);
- break ;
- }
- x++;
- break ;
- case 0x04: /* no callerid reason */
- /* length */
- x++;
- /* no callerid reason code */
- switch (cid->rawdata[x]) {
- case 'P': /* caller id denied by user */
- case 'O': /* service not available */
- case 'C': /* pay phone */
- case 'S': /* service congested */
- cid->flags |= CID_UNKNOWN_NUMBER;
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "no cid reason:%c\n",cid->rawdata[x]);
- break ;
- }
- x++;
- break ;
- case 0x09: /* dialed number */
- /* length */
- res = cid->rawdata[x++];
- /* dialed number */
- x += res;
- break ;
- case 0x22: /* dialed number additional information */
- /* length */
- x++;
- /* number type */
- switch (cid->rawdata[x]) {
- case 0x00: /* unknown */
- case 0x01: /* international number */
- case 0x02: /* domestic number */
- case 0x03: /* network */
- case 0x04: /* local call */
- case 0x06: /* short dial number */
- case 0x07: /* reserved */
- default: /* reserved */
- if (option_debug > 1)
- ast_log(LOG_NOTICE, "did info:#1=%X\n", cid->rawdata[x]);
- break ;
- }
- x++;
- /* numbering plan octed 4 */
- x++;
- /* numbering plan octed 5 */
- switch (cid->rawdata[x]) {
- case 0x00: /* unknown */
- case 0x01: /* recommendation E.164 ISDN */
- case 0x03: /* recommendation X.121 */
- case 0x04: /* telex dial plan */
- case 0x08: /* domestic dial plan */
- case 0x09: /* private dial plan */
- case 0x05: /* reserved */
- default: /* reserved */
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "did info:#2=%X\n", cid->rawdata[x]);
- break ;
- }
- x++;
- break ;
- }
- }
- free(obuf);
- return 1;
- break;
- default:
- ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
- }
- }
- }
- if (mylen) {
- memcpy(cid->oldstuff, buf, mylen * 2);
- cid->oldlen = mylen * 2;
- } else
- cid->oldlen = 0;
- free(obuf);
- return 0;
-}
-
-
-int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
-{
- int mylen = len;
- int olen;
- int b = 'X';
- int res;
- int x;
- short *buf;
- short *obuf;
-
- if (!(buf = ast_calloc(1, 2 * len + cid->oldlen))) {
- return -1;
- }
-
- obuf = buf;
- memcpy(buf, cid->oldstuff, cid->oldlen);
- mylen += cid->oldlen/2;
-
- for (x=0;x<len;x++)
- buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
- while(mylen >= 160) {
- olen = mylen;
- res = fsk_serie(&cid->fskd, buf, &mylen, &b);
- if (mylen < 0) {
- ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
- free(obuf);
- return -1;
- }
- buf += (olen - mylen);
- if (res < 0) {
- ast_log(LOG_NOTICE, "fsk_serie failed\n");
- free(obuf);
- return -1;
- }
- if (res == 1) {
- /* Ignore invalid bytes */
- if (b > 0xff)
- continue;
- switch(cid->sawflag) {
- case 0: /* Look for flag */
- if (b == 'U')
- cid->sawflag = 2;
- break;
- case 2: /* Get lead-in */
- if ((b == 0x04) || (b == 0x80)) {
- cid->type = b;
- cid->sawflag = 3;
- cid->cksum = b;
- }
- break;
- case 3: /* Get length */
- /* Not a lead in. We're ready */
- cid->sawflag = 4;
- cid->len = b;
- cid->pos = 0;
- cid->cksum += b;
- break;
- case 4: /* Retrieve message */
- if (cid->pos >= 128) {
- ast_log(LOG_WARNING, "Caller ID too long???\n");
- free(obuf);
- return -1;
- }
- cid->rawdata[cid->pos++] = b;
- cid->len--;
- cid->cksum += b;
- if (!cid->len) {
- cid->rawdata[cid->pos] = '\0';
- cid->sawflag = 5;
- }
- break;
- case 5: /* Check checksum */
- if (b != (256 - (cid->cksum & 0xff))) {
- ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
- /* Try again */
- cid->sawflag = 0;
- break;
- }
-
- cid->number[0] = '\0';
- cid->name[0] = '\0';
- /* If we get this far we're fine. */
- if (cid->type == 0x80) {
- /* MDMF */
- /* Go through each element and process */
- for (x=0;x< cid->pos;) {
- switch(cid->rawdata[x++]) {
- case 1:
- /* Date */
- break;
- case 2: /* Number */
- case 3: /* Number (for Zebble) */
- case 4: /* Number */
- res = cid->rawdata[x];
- if (res > 32) {
- ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
- res = 32;
- }
- if (ast_strlen_zero(cid->number)) {
- memcpy(cid->number, cid->rawdata + x + 1, res);
- /* Null terminate */
- cid->number[res] = '\0';
- }
- break;
- case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
- break;
- case 7: /* Name */
- case 8: /* Name */
- res = cid->rawdata[x];
- if (res > 32) {
- ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
- res = 32;
- }
- memcpy(cid->name, cid->rawdata + x + 1, res);
- cid->name[res] = '\0';
- break;
- case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */
- case 19: /* UK: Network message system status (Number of messages waiting) */
- case 22: /* Something French */
- break;
- default:
- ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
- }
- res = cid->rawdata[x];
- if (0 > res){ /* Negative offset in the CID Spill */
- ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
- /* Try again */
- cid->sawflag = 0;
- break; /* Exit the loop */
- }
- x += cid->rawdata[x];
- x++;
- }
- } else {
- /* SDMF */
- ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
- }
- /* Update flags */
- cid->flags = 0;
- if (!strcmp(cid->number, "P")) {
- strcpy(cid->number, "");
- cid->flags |= CID_PRIVATE_NUMBER;
- } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
- strcpy(cid->number, "");
- cid->flags |= CID_UNKNOWN_NUMBER;
- }
- if (!strcmp(cid->name, "P")) {
- strcpy(cid->name, "");
- cid->flags |= CID_PRIVATE_NAME;
- } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
- strcpy(cid->name, "");
- cid->flags |= CID_UNKNOWN_NAME;
- }
- free(obuf);
- return 1;
- break;
- default:
- ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
- }
- }
- }
- if (mylen) {
- memcpy(cid->oldstuff, buf, mylen * 2);
- cid->oldlen = mylen * 2;
- } else
- cid->oldlen = 0;
- free(obuf);
- return 0;
-}
-
-void callerid_free(struct callerid_state *cid)
-{
- free(cid);
-}
-
-static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
-{
- time_t t;
- struct tm tm;
- char *ptr;
- int res;
- int i,x;
- /* Get the time */
- time(&t);
- ast_localtime(&t, &tm, NULL);
-
- ptr = msg;
-
- /* Format time and message header */
- res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
- tm.tm_mday, tm.tm_hour, tm.tm_min);
- size -= res;
- ptr += res;
- if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
- /* Indicate number not known */
- res = snprintf(ptr, size, "\004\001O");
- size -= res;
- ptr += res;
- } else if (flags & CID_PRIVATE_NUMBER) {
- /* Indicate number is private */
- res = snprintf(ptr, size, "\004\001P");
- size -= res;
- ptr += res;
- } else {
- /* Send up to 16 digits of number MAX */
- i = strlen(number);
- if (i > 16) i = 16;
- res = snprintf(ptr, size, "\002%c", i);
- size -= res;
- ptr += res;
- for (x = 0; x < i; x++)
- ptr[x] = number[x];
- ptr[i] = '\0';
- ptr += i;
- size -= i;
- }
-
- if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
- /* Indicate name not known */
- res = snprintf(ptr, size, "\010\001O");
- size -= res;
- ptr += res;
- } else if (flags & CID_PRIVATE_NAME) {
- /* Indicate name is private */
- res = snprintf(ptr, size, "\010\001P");
- size -= res;
- ptr += res;
- } else {
- /* Send up to 16 digits of name MAX */
- i = strlen(name);
- if (i > 16) i = 16;
- res = snprintf(ptr, size, "\007%c", i);
- size -= res;
- ptr += res;
- for (x=0;x<i;x++)
- ptr[x] = name[x];
- ptr[i] = '\0';
- ptr += i;
- size -= i;
- }
- return (ptr - msg);
-
-}
-
-int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
-{
- unsigned char msg[256];
- int len=0;
- int sum;
- int x;
- int bytes = 0;
- float cr = 1.0;
- float ci = 0.0;
- float scont = 0.0;
- if (mdmf) {
- /* MDMF Message waiting */
- msg[len++] = 0x82;
- /* Length is 3 */
- msg[len++] = 3;
- /* IE is "Message Waiting Parameter" */
- msg[len++] = 0xb;
- /* Length of IE is one */
- msg[len++] = 1;
- /* Active or not */
- if (active)
- msg[len++] = 0xff;
- else
- msg[len++] = 0x00;
- } else {
- /* SDMF Message waiting */
- msg[len++] = 0x6;
- /* Length is 3 */
- msg[len++] = 3;
- if (active) {
- msg[len++] = 0x42;
- msg[len++] = 0x42;
- msg[len++] = 0x42;
- } else {
- msg[len++] = 0x6f;
- msg[len++] = 0x6f;
- msg[len++] = 0x6f;
- }
- }
- sum = 0;
- for (x=0; x<len; x++)
- sum += msg[x];
- sum = (256 - (sum & 255));
- msg[len++] = sum;
- /* Wait a half a second */
- for (x=0; x<4000; x++)
- PUT_BYTE(0x7f);
- /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
- for (x=0; x<30; x++)
- PUT_CLID(0x55);
- /* Send 170ms of callerid marks */
- for (x=0; x<170; x++)
- PUT_CLID_MARKMS;
- for (x=0; x<len; x++) {
- PUT_CLID(msg[x]);
- }
- /* Send 50 more ms of marks */
- for (x=0; x<50; x++)
- PUT_CLID_MARKMS;
- return bytes;
-}
-
-int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec)
-{
- int bytes=0;
- int x, sum;
- int len;
-
- /* Initial carriers (real/imaginary) */
- float cr = 1.0;
- float ci = 0.0;
- float scont = 0.0;
- char msg[256];
- len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
- if (!callwaiting) {
- /* Wait a half a second */
- for (x=0; x<4000; x++)
- PUT_BYTE(0x7f);
- /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
- for (x=0; x<30; x++)
- PUT_CLID(0x55);
- }
- /* Send 150ms of callerid marks */
- for (x=0; x<150; x++)
- PUT_CLID_MARKMS;
- /* Send 0x80 indicating MDMF format */
- PUT_CLID(0x80);
- /* Put length of whole message */
- PUT_CLID(len);
- sum = 0x80 + strlen(msg);
- /* Put each character of message and update checksum */
- for (x=0; x<len; x++) {
- PUT_CLID(msg[x]);
- sum += msg[x];
- }
- /* Send 2's compliment of sum */
- PUT_CLID(256 - (sum & 255));
-
- /* Send 50 more ms of marks */
- for (x=0; x<50; x++)
- PUT_CLID_MARKMS;
-
- return bytes;
-}
-
-/*! \brief Clean up phone string
- * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
- * Basically, remove anything that could be invalid in a pattern.
- */
-void ast_shrink_phone_number(char *n)
-{
- int x, y=0;
- int bracketed = 0;
-
- for (x=0; n[x]; x++) {
- switch(n[x]) {
- case '[':
- bracketed++;
- n[y++] = n[x];
- break;
- case ']':
- bracketed--;
- n[y++] = n[x];
- break;
- case '-':
- if (bracketed)
- n[y++] = n[x];
- break;
- case '.':
- if (!n[x+1])
- n[y++] = n[x];
- break;
- default:
- if (!strchr("( )", n[x]))
- n[y++] = n[x];
- }
- }
- n[y] = '\0';
-}
-
-/*! \brief Checks if phone number consists of valid characters
- \param exten String that needs to be checked
- \param valid Valid characters in string
- \return 1 if valid string, 0 if string contains invalid characters
-*/
-static int ast_is_valid_string(const char *exten, const char *valid)
-{
- int x;
-
- if (ast_strlen_zero(exten))
- return 0;
- for (x=0; exten[x]; x++)
- if (!strchr(valid, exten[x]))
- return 0;
- return 1;
-}
-
-/*! \brief checks if string consists only of digits and * \# and +
- \return 1 if string is valid AST phone number
- \return 0 if not
-*/
-int ast_isphonenumber(const char *n)
-{
- return ast_is_valid_string(n, "0123456789*#+");
-}
-
-/*! \brief checks if string consists only of digits and ( ) - * \# and +
- Pre-qualifies the string for ast_shrink_phone_number()
- \return 1 if string is valid AST shrinkable phone number
- \return 0 if not
-*/
-int ast_is_shrinkable_phonenumber(const char *exten)
-{
- return ast_is_valid_string(exten, "0123456789*#+()-.");
-}
-
-/*! \brief parse string for caller id information
- \return always returns 0, as the code always returns something.
- XXX note that 'name' is not parsed consistently e.g. we have
-
- input location name
- " foo bar " <123> 123 ' foo bar ' (with spaces around)
- " foo bar " NULL 'foo bar' (without spaces around)
- " foo bar <123>" 123 '" foo bar'
- The parsing of leading and trailing space/quotes should be more consistent.
-*/
-int ast_callerid_parse(char *instr, char **name, char **location)
-{
- char *ns, *ne, *ls, *le;
-
- /* Try "name" <location> format or name <location> format */
- if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
- *ls = *le = '\0'; /* location found, trim off the brackets */
- *location = ls + 1; /* and this is the result */
- if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
- *ns = *ne = '\0'; /* trim off the quotes */
- *name = ns + 1; /* and this is the name */
- } else { /* no quotes, trim off leading and trailing spaces */
- *name = ast_skip_blanks(instr);
- ast_trim_blanks(*name);
- }
- } else { /* no valid brackets */
- char tmp[256];
-
- ast_copy_string(tmp, instr, sizeof(tmp));
- ast_shrink_phone_number(tmp);
- if (ast_isphonenumber(tmp)) { /* Assume it's just a location */
- *name = NULL;
- strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
- *location = instr;
- } else { /* Assume it's just a name. */
- *location = NULL;
- if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
- *ns = *ne = '\0'; /* trim off the quotes */
- *name = ns + 1; /* and this is the name */
- } else { /* no quotes, trim off leading and trailing spaces */
- *name = ast_skip_blanks(instr);
- ast_trim_blanks(*name);
- }
- }
- }
- return 0;
-}
-
-static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, int codec)
-{
- if (ast_strlen_zero(name))
- name = NULL;
- if (ast_strlen_zero(number))
- number = NULL;
- return callerid_generate(buf, number, name, 0, callwaiting, codec);
-}
-
-int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec)
-{
- return __ast_callerid_generate(buf, name, number, 0, codec);
-}
-
-int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec)
-{
- return __ast_callerid_generate(buf, name, number, 1, codec);
-}
-
-char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
-{
- if (!unknown)
- unknown = "<unknown>";
- if (name && num)
- snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
- else if (name)
- ast_copy_string(buf, name, bufsiz);
- else if (num)
- ast_copy_string(buf, num, bufsiz);
- else
- ast_copy_string(buf, unknown, bufsiz);
- return buf;
-}
-
-int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
-{
- char *tmp;
- char *l = NULL, *n = NULL;
-
- tmp = ast_strdupa(buf);
- ast_callerid_parse(tmp, &n, &l);
- if (n)
- ast_copy_string(name, n, namelen);
- else
- name[0] = '\0';
- if (l) {
- ast_shrink_phone_number(l);
- ast_copy_string(num, l, numlen);
- } else
- num[0] = '\0';
- return 0;
-}
-
-/*! \brief Translation table for Caller ID Presentation settings */
-static struct {
- int val;
- char *name;
- char *description;
-} pres_types[] = {
- { AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
- { AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
- { AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
- { AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
- { AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
- { AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
- { AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
- { AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
- { AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
-};
-
-/*! \brief Convert caller ID text code to value
- used in config file parsing
- \param data text string
- \return value AST_PRES_ from callerid.h
-*/
-int ast_parse_caller_presentation(const char *data)
-{
- int i;
-
- for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
- if (!strcasecmp(pres_types[i].name, data))
- return pres_types[i].val;
- }
-
- return -1;
-}
-
-/*! \brief Convert caller ID pres value to explanatory string
- \param data value (see callerid.h AST_PRES_ )
- \return string for human presentation
-*/
-const char *ast_describe_caller_presentation(int data)
-{
- int i;
-
- for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
- if (pres_types[i].val == data)
- return pres_types[i].description;
- }
-
- return "unknown";
-}
diff --git a/1.4/main/cdr.c b/1.4/main/cdr.c
deleted file mode 100644
index 377ee09ac..000000000
--- a/1.4/main/cdr.c
+++ /dev/null
@@ -1,1446 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Call Detail Record API
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note Includes code and algorithms from the Zapata library.
- *
- * \note We do a lot of checking here in the CDR code to try to be sure we don't ever let a CDR slip
- * through our fingers somehow. If someone allocates a CDR, it must be completely handled normally
- * or a WARNING shall be logged, so that we can best keep track of any escape condition where the CDR
- * isn't properly generated and posted.
- */
-
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/logger.h"
-#include "asterisk/callerid.h"
-#include "asterisk/causes.h"
-#include "asterisk/options.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/utils.h"
-#include "asterisk/sched.h"
-#include "asterisk/config.h"
-#include "asterisk/cli.h"
-#include "asterisk/stringfields.h"
-
-/*! Default AMA flag for billing records (CDR's) */
-int ast_default_amaflags = AST_CDR_DOCUMENTATION;
-char ast_default_accountcode[AST_MAX_ACCOUNT_CODE];
-
-struct ast_cdr_beitem {
- char name[20];
- char desc[80];
- ast_cdrbe be;
- AST_LIST_ENTRY(ast_cdr_beitem) list;
-};
-
-static AST_LIST_HEAD_STATIC(be_list, ast_cdr_beitem);
-
-struct ast_cdr_batch_item {
- struct ast_cdr *cdr;
- struct ast_cdr_batch_item *next;
-};
-
-static struct ast_cdr_batch {
- int size;
- struct ast_cdr_batch_item *head;
- struct ast_cdr_batch_item *tail;
-} *batch = NULL;
-
-static struct sched_context *sched;
-static int cdr_sched = -1;
-static pthread_t cdr_thread = AST_PTHREADT_NULL;
-
-#define BATCH_SIZE_DEFAULT 100
-#define BATCH_TIME_DEFAULT 300
-#define BATCH_SCHEDULER_ONLY_DEFAULT 0
-#define BATCH_SAFE_SHUTDOWN_DEFAULT 1
-
-static int enabled; /*! Is the CDR subsystem enabled ? */
-static int unanswered;
-static int batchmode;
-static int batchsize;
-static int batchtime;
-static int batchscheduleronly;
-static int batchsafeshutdown;
-
-AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
-
-/* these are used to wake up the CDR thread when there's work to do */
-AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
-static ast_cond_t cdr_pending_cond;
-
-
-/*! Register a CDR driver. Each registered CDR driver generates a CDR
- \return 0 on success, -1 on failure
-*/
-int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
-{
- struct ast_cdr_beitem *i;
-
- if (!name)
- return -1;
- if (!be) {
- ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
- return -1;
- }
-
- AST_LIST_LOCK(&be_list);
- AST_LIST_TRAVERSE(&be_list, i, list) {
- if (!strcasecmp(name, i->name))
- break;
- }
- AST_LIST_UNLOCK(&be_list);
-
- if (i) {
- ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
- return -1;
- }
-
- if (!(i = ast_calloc(1, sizeof(*i))))
- return -1;
-
- i->be = be;
- ast_copy_string(i->name, name, sizeof(i->name));
- ast_copy_string(i->desc, desc, sizeof(i->desc));
-
- AST_LIST_LOCK(&be_list);
- AST_LIST_INSERT_HEAD(&be_list, i, list);
- AST_LIST_UNLOCK(&be_list);
-
- return 0;
-}
-
-/*! unregister a CDR driver */
-void ast_cdr_unregister(const char *name)
-{
- struct ast_cdr_beitem *i = NULL;
-
- AST_LIST_LOCK(&be_list);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
- if (!strcasecmp(name, i->name)) {
- AST_LIST_REMOVE_CURRENT(&be_list, list);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s' CDR backend\n", name);
- free(i);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&be_list);
-}
-
-/*! Duplicate a CDR record
- \returns Pointer to new CDR record
-*/
-struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
-{
- struct ast_cdr *newcdr;
-
- if (!cdr) /* don't die if we get a null cdr pointer */
- return NULL;
- newcdr = ast_cdr_alloc();
- if (!newcdr)
- return NULL;
-
- memcpy(newcdr, cdr, sizeof(*newcdr));
- /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */
- memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
- ast_cdr_copy_vars(newcdr, cdr);
- newcdr->next = NULL;
-
- return newcdr;
-}
-
-static const char *ast_cdr_getvar_internal(struct ast_cdr *cdr, const char *name, int recur)
-{
- if (ast_strlen_zero(name))
- return NULL;
-
- for (; cdr; cdr = recur ? cdr->next : NULL) {
- struct ast_var_t *variables;
- struct varshead *headp = &cdr->varshead;
- AST_LIST_TRAVERSE(headp, variables, entries) {
- if (!strcasecmp(name, ast_var_name(variables)))
- return ast_var_value(variables);
- }
- }
-
- return NULL;
-}
-
-static void cdr_get_tv(struct timeval tv, const char *fmt, char *buf, int bufsize)
-{
- if (fmt == NULL) { /* raw mode */
- snprintf(buf, bufsize, "%ld.%06ld", (long)tv.tv_sec, (long)tv.tv_usec);
- } else {
- time_t t = tv.tv_sec;
- if (t) {
- struct tm tm;
-
- ast_localtime(&t, &tm, NULL);
- strftime(buf, bufsize, fmt, &tm);
- }
- }
-}
-
-/*! CDR channel variable retrieval */
-void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw)
-{
- const char *fmt = "%Y-%m-%d %T";
- const char *varbuf;
-
- if (!cdr) /* don't die if the cdr is null */
- return;
-
- *ret = NULL;
- /* special vars (the ones from the struct ast_cdr when requested by name)
- I'd almost say we should convert all the stringed vals to vars */
-
- if (!strcasecmp(name, "clid"))
- ast_copy_string(workspace, cdr->clid, workspacelen);
- else if (!strcasecmp(name, "src"))
- ast_copy_string(workspace, cdr->src, workspacelen);
- else if (!strcasecmp(name, "dst"))
- ast_copy_string(workspace, cdr->dst, workspacelen);
- else if (!strcasecmp(name, "dcontext"))
- ast_copy_string(workspace, cdr->dcontext, workspacelen);
- else if (!strcasecmp(name, "channel"))
- ast_copy_string(workspace, cdr->channel, workspacelen);
- else if (!strcasecmp(name, "dstchannel"))
- ast_copy_string(workspace, cdr->dstchannel, workspacelen);
- else if (!strcasecmp(name, "lastapp"))
- ast_copy_string(workspace, cdr->lastapp, workspacelen);
- else if (!strcasecmp(name, "lastdata"))
- ast_copy_string(workspace, cdr->lastdata, workspacelen);
- else if (!strcasecmp(name, "start"))
- cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
- else if (!strcasecmp(name, "answer"))
- cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
- else if (!strcasecmp(name, "end"))
- cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
- else if (!strcasecmp(name, "duration"))
- snprintf(workspace, workspacelen, "%ld", cdr->duration);
- else if (!strcasecmp(name, "billsec"))
- snprintf(workspace, workspacelen, "%ld", cdr->billsec);
- else if (!strcasecmp(name, "disposition")) {
- if (raw) {
- snprintf(workspace, workspacelen, "%ld", cdr->disposition);
- } else {
- ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
- }
- } else if (!strcasecmp(name, "amaflags")) {
- if (raw) {
- snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
- } else {
- ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen);
- }
- } else if (!strcasecmp(name, "accountcode"))
- ast_copy_string(workspace, cdr->accountcode, workspacelen);
- else if (!strcasecmp(name, "uniqueid"))
- ast_copy_string(workspace, cdr->uniqueid, workspacelen);
- else if (!strcasecmp(name, "userfield"))
- ast_copy_string(workspace, cdr->userfield, workspacelen);
- else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur)))
- ast_copy_string(workspace, varbuf, workspacelen);
- else
- workspace[0] = '\0';
-
- if (!ast_strlen_zero(workspace))
- *ret = workspace;
-}
-
-/* readonly cdr variables */
-static const char *cdr_readonly_vars[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel",
- "lastapp", "lastdata", "start", "answer", "end", "duration",
- "billsec", "disposition", "amaflags", "accountcode", "uniqueid",
- "userfield", NULL };
-/*! Set a CDR channel variable
- \note You can't set the CDR variables that belong to the actual CDR record, like "billsec".
-*/
-int ast_cdr_setvar(struct ast_cdr *cdr, const char *name, const char *value, int recur)
-{
- struct ast_var_t *newvariable;
- struct varshead *headp;
- int x;
-
- if (!cdr) /* don't die if the cdr is null */
- return -1;
-
- for(x = 0; cdr_readonly_vars[x]; x++) {
- if (!strcasecmp(name, cdr_readonly_vars[x])) {
- ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!.\n", name);
- return -1;
- }
- }
-
- if (!cdr) {
- ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n");
- return -1;
- }
-
- for (; cdr; cdr = recur ? cdr->next : NULL) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- headp = &cdr->varshead;
- AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
- if (!strcasecmp(ast_var_name(newvariable), name)) {
- /* there is already such a variable, delete it */
- AST_LIST_REMOVE_CURRENT(headp, entries);
- ast_var_delete(newvariable);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- if (value) {
- newvariable = ast_var_assign(name, value);
- AST_LIST_INSERT_HEAD(headp, newvariable, entries);
- }
- }
- }
-
- return 0;
-}
-
-int ast_cdr_copy_vars(struct ast_cdr *to_cdr, struct ast_cdr *from_cdr)
-{
- struct ast_var_t *variables, *newvariable = NULL;
- struct varshead *headpa, *headpb;
- const char *var, *val;
- int x = 0;
-
- if (!to_cdr || !from_cdr) /* don't die if one of the pointers is null */
- return 0;
-
- headpa = &from_cdr->varshead;
- headpb = &to_cdr->varshead;
-
- AST_LIST_TRAVERSE(headpa,variables,entries) {
- if (variables &&
- (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
- !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
- newvariable = ast_var_assign(var, val);
- AST_LIST_INSERT_HEAD(headpb, newvariable, entries);
- x++;
- }
- }
-
- return x;
-}
-
-int ast_cdr_serialize_variables(struct ast_cdr *cdr, char *buf, size_t size, char delim, char sep, int recur)
-{
- struct ast_var_t *variables;
- const char *var, *val;
- char *tmp;
- char workspace[256];
- int total = 0, x = 0, i;
-
- memset(buf, 0, size);
-
- for (; cdr; cdr = recur ? cdr->next : NULL) {
- if (++x > 1)
- ast_build_string(&buf, &size, "\n");
-
- AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
- if (variables &&
- (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
- !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
- if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, var, delim, val, sep)) {
- ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
- break;
- } else
- total++;
- } else
- break;
- }
-
- for (i = 0; cdr_readonly_vars[i]; i++) {
- ast_cdr_getvar(cdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0);
- if (!tmp)
- continue;
-
- if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, tmp, sep)) {
- ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
- break;
- } else
- total++;
- }
- }
-
- return total;
-}
-
-
-void ast_cdr_free_vars(struct ast_cdr *cdr, int recur)
-{
-
- /* clear variables */
- for (; cdr; cdr = recur ? cdr->next : NULL) {
- struct ast_var_t *vardata;
- struct varshead *headp = &cdr->varshead;
- while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
- ast_var_delete(vardata);
- }
-}
-
-/*! \brief print a warning if cdr already posted */
-static void check_post(struct ast_cdr *cdr)
-{
- if (!cdr)
- return;
- if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
- ast_log(LOG_NOTICE, "CDR on channel '%s' already posted\n", S_OR(cdr->channel, "<unknown>"));
-}
-
-void ast_cdr_free(struct ast_cdr *cdr)
-{
-
- while (cdr) {
- struct ast_cdr *next = cdr->next;
- char *chan = S_OR(cdr->channel, "<unknown>");
- if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
- ast_log(LOG_NOTICE, "CDR on channel '%s' not posted\n", chan);
- if (ast_tvzero(cdr->end))
- ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan);
- if (ast_tvzero(cdr->start))
- ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan);
-
- ast_cdr_free_vars(cdr, 0);
- free(cdr);
- cdr = next;
- }
-}
-
-/*! \brief the same as a cdr_free call, only with no checks; just get rid of it */
-void ast_cdr_discard(struct ast_cdr *cdr)
-{
- while (cdr) {
- struct ast_cdr *next = cdr->next;
-
- ast_cdr_free_vars(cdr, 0);
- free(cdr);
- cdr = next;
- }
-}
-
-struct ast_cdr *ast_cdr_alloc(void)
-{
- struct ast_cdr *x = ast_calloc(1, sizeof(struct ast_cdr));
- if (!x)
- ast_log(LOG_ERROR,"Allocation Failure for a CDR!\n");
- return x;
-}
-
-static void cdr_merge_vars(struct ast_cdr *to, struct ast_cdr *from)
-{
- struct ast_var_t *variablesfrom,*variablesto;
- struct varshead *headpfrom = &to->varshead;
- struct varshead *headpto = &from->varshead;
- AST_LIST_TRAVERSE_SAFE_BEGIN(headpfrom, variablesfrom, entries) {
- /* for every var in from, stick it in to */
- const char *fromvarname = NULL, *fromvarval = NULL;
- const char *tovarname = NULL, *tovarval = NULL;
- fromvarname = ast_var_name(variablesfrom);
- fromvarval = ast_var_value(variablesfrom);
- tovarname = 0;
-
- /* now, quick see if that var is in the 'to' cdr already */
- AST_LIST_TRAVERSE(headpto, variablesto, entries) {
-
- /* now, quick see if that var is in the 'to' cdr already */
- if ( strcasecmp(fromvarname, ast_var_name(variablesto)) == 0 ) {
- tovarname = ast_var_name(variablesto);
- tovarval = ast_var_value(variablesto);
- break;
- }
- }
- if (tovarname && strcasecmp(fromvarval,tovarval) != 0) { /* this message here to see how irritating the userbase finds it */
- ast_log(LOG_NOTICE, "Merging CDR's: variable %s value %s dropped in favor of value %s\n", tovarname, fromvarval, tovarval);
- continue;
- } else if (tovarname && strcasecmp(fromvarval,tovarval) == 0) /* if they are the same, the job is done */
- continue;
-
- /*rip this var out of the from cdr, and stick it in the to cdr */
- AST_LIST_REMOVE_CURRENT(headpfrom, entries);
- AST_LIST_INSERT_HEAD(headpto, variablesfrom, entries);
- }
- AST_LIST_TRAVERSE_SAFE_END;
-}
-
-void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
-{
- struct ast_cdr *zcdr;
- struct ast_cdr *lto = NULL;
- struct ast_cdr *lfrom = NULL;
- int discard_from = 0;
-
- if (!to || !from)
- return;
-
- /* don't merge into locked CDR's -- it's bad business */
- if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) {
- zcdr = to; /* safety valve? */
- while (to->next) {
- lto = to;
- to = to->next;
- }
-
- if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) {
- ast_log(LOG_WARNING, "Merging into locked CDR... no choice.");
- to = zcdr; /* safety-- if all there are is locked CDR's, then.... ?? */
- lto = NULL;
- }
- }
-
- if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) {
- discard_from = 1;
- if (lto) {
- struct ast_cdr *llfrom = NULL;
- /* insert the from stuff after lto */
- lto->next = from;
- lfrom = from;
- while (lfrom && lfrom->next) {
- if (!lfrom->next->next)
- llfrom = lfrom;
- lfrom = lfrom->next;
- }
- /* rip off the last entry and put a copy of the to at the end */
- llfrom->next = to;
- from = lfrom;
- } else {
- /* save copy of the current *to cdr */
- struct ast_cdr tcdr;
- struct ast_cdr *llfrom = NULL;
- memcpy(&tcdr, to, sizeof(tcdr));
- /* copy in the locked from cdr */
- memcpy(to, from, sizeof(*to));
- lfrom = from;
- while (lfrom && lfrom->next) {
- if (!lfrom->next->next)
- llfrom = lfrom;
- lfrom = lfrom->next;
- }
- from->next = NULL;
- /* rip off the last entry and put a copy of the to at the end */
- if (llfrom == from)
- to = to->next = ast_cdr_dup(&tcdr);
- else
- to = llfrom->next = ast_cdr_dup(&tcdr);
- from = lfrom;
- }
- }
-
- if (!ast_tvzero(from->start)) {
- if (!ast_tvzero(to->start)) {
- if (ast_tvcmp(to->start, from->start) > 0 ) {
- to->start = from->start; /* use the earliest time */
- from->start = ast_tv(0,0); /* we actively "steal" these values */
- }
- /* else nothing to do */
- } else {
- to->start = from->start;
- from->start = ast_tv(0,0); /* we actively "steal" these values */
- }
- }
- if (!ast_tvzero(from->answer)) {
- if (!ast_tvzero(to->answer)) {
- if (ast_tvcmp(to->answer, from->answer) > 0 ) {
- to->answer = from->answer; /* use the earliest time */
- from->answer = ast_tv(0,0); /* we actively "steal" these values */
- }
- /* we got the earliest answer time, so we'll settle for that? */
- } else {
- to->answer = from->answer;
- from->answer = ast_tv(0,0); /* we actively "steal" these values */
- }
- }
- if (!ast_tvzero(from->end)) {
- if (!ast_tvzero(to->end)) {
- if (ast_tvcmp(to->end, from->end) < 0 ) {
- to->end = from->end; /* use the latest time */
- from->end = ast_tv(0,0); /* we actively "steal" these values */
- to->duration = to->end.tv_sec - to->start.tv_sec; /* don't forget to update the duration, billsec, when we set end */
- to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
- }
- /* else, nothing to do */
- } else {
- to->end = from->end;
- from->end = ast_tv(0,0); /* we actively "steal" these values */
- to->duration = to->end.tv_sec - to->start.tv_sec;
- to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
- }
- }
- if (to->disposition < from->disposition) {
- to->disposition = from->disposition;
- from->disposition = AST_CDR_NOANSWER;
- }
- if (ast_strlen_zero(to->lastapp) && !ast_strlen_zero(from->lastapp)) {
- ast_copy_string(to->lastapp, from->lastapp, sizeof(to->lastapp));
- from->lastapp[0] = 0; /* theft */
- }
- if (ast_strlen_zero(to->lastdata) && !ast_strlen_zero(from->lastdata)) {
- ast_copy_string(to->lastdata, from->lastdata, sizeof(to->lastdata));
- from->lastdata[0] = 0; /* theft */
- }
- if (ast_strlen_zero(to->dcontext) && !ast_strlen_zero(from->dcontext)) {
- ast_copy_string(to->dcontext, from->dcontext, sizeof(to->dcontext));
- from->dcontext[0] = 0; /* theft */
- }
- if (ast_strlen_zero(to->dstchannel) && !ast_strlen_zero(from->dstchannel)) {
- ast_copy_string(to->dstchannel, from->dstchannel, sizeof(to->dstchannel));
- from->dstchannel[0] = 0; /* theft */
- }
- if (!ast_strlen_zero(from->channel) && (ast_strlen_zero(to->channel) || !strncasecmp(from->channel, "Agent/", 6))) {
- ast_copy_string(to->channel, from->channel, sizeof(to->channel));
- from->channel[0] = 0; /* theft */
- }
- if (ast_strlen_zero(to->src) && !ast_strlen_zero(from->src)) {
- ast_copy_string(to->src, from->src, sizeof(to->src));
- from->src[0] = 0; /* theft */
- }
- if (ast_strlen_zero(to->clid) && !ast_strlen_zero(from->clid)) {
- ast_copy_string(to->clid, from->clid, sizeof(to->clid));
- from->clid[0] = 0; /* theft */
- }
- if (ast_strlen_zero(to->dst) && !ast_strlen_zero(from->dst)) {
- ast_copy_string(to->dst, from->dst, sizeof(to->dst));
- from->dst[0] = 0; /* theft */
- }
- if (!to->amaflags)
- to->amaflags = AST_CDR_DOCUMENTATION;
- if (!from->amaflags)
- from->amaflags = AST_CDR_DOCUMENTATION; /* make sure both amaflags are set to something (DOC is default) */
- if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (to->amaflags == AST_CDR_DOCUMENTATION && from->amaflags != AST_CDR_DOCUMENTATION)) {
- to->amaflags = from->amaflags;
- }
- if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (ast_strlen_zero(to->accountcode) && !ast_strlen_zero(from->accountcode))) {
- ast_copy_string(to->accountcode, from->accountcode, sizeof(to->accountcode));
- }
- if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (ast_strlen_zero(to->userfield) && !ast_strlen_zero(from->userfield))) {
- ast_copy_string(to->userfield, from->userfield, sizeof(to->userfield));
- }
- /* flags, varsead, ? */
- cdr_merge_vars(from, to);
-
- if (ast_test_flag(from, AST_CDR_FLAG_KEEP_VARS))
- ast_set_flag(to, AST_CDR_FLAG_KEEP_VARS);
- if (ast_test_flag(from, AST_CDR_FLAG_POSTED))
- ast_set_flag(to, AST_CDR_FLAG_POSTED);
- if (ast_test_flag(from, AST_CDR_FLAG_LOCKED))
- ast_set_flag(to, AST_CDR_FLAG_LOCKED);
- if (ast_test_flag(from, AST_CDR_FLAG_CHILD))
- ast_set_flag(to, AST_CDR_FLAG_CHILD);
- if (ast_test_flag(from, AST_CDR_FLAG_POST_DISABLED))
- ast_set_flag(to, AST_CDR_FLAG_POST_DISABLED);
-
- /* last, but not least, we need to merge any forked CDRs to the 'to' cdr */
- while (from->next) {
- /* just rip 'em off the 'from' and insert them on the 'to' */
- zcdr = from->next;
- from->next = zcdr->next;
- zcdr->next = NULL;
- /* zcdr is now ripped from the current list; */
- ast_cdr_append(to, zcdr);
- }
- if (discard_from)
- ast_cdr_discard(from);
-}
-
-void ast_cdr_start(struct ast_cdr *cdr)
-{
- char *chan;
-
- for (; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- chan = S_OR(cdr->channel, "<unknown>");
- check_post(cdr);
- cdr->start = ast_tvnow();
- }
- }
-}
-
-void ast_cdr_answer(struct ast_cdr *cdr)
-{
-
- for (; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- check_post(cdr);
- if (cdr->disposition < AST_CDR_ANSWERED)
- cdr->disposition = AST_CDR_ANSWERED;
- if (ast_tvzero(cdr->answer))
- cdr->answer = ast_tvnow();
- }
- }
-}
-
-void ast_cdr_busy(struct ast_cdr *cdr)
-{
-
- for (; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- check_post(cdr);
- if (cdr->disposition < AST_CDR_BUSY)
- cdr->disposition = AST_CDR_BUSY;
- }
- }
-}
-
-void ast_cdr_failed(struct ast_cdr *cdr)
-{
- for (; cdr; cdr = cdr->next) {
- check_post(cdr);
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- if (cdr->disposition < AST_CDR_FAILED)
- cdr->disposition = AST_CDR_FAILED;
- }
- }
-}
-
-void ast_cdr_noanswer(struct ast_cdr *cdr)
-{
- char *chan;
-
- while (cdr) {
- chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
- if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
- ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- if (cdr->disposition < AST_CDR_NOANSWER)
- cdr->disposition = AST_CDR_NOANSWER;
- }
- cdr = cdr->next;
- }
-}
-
-/* everywhere ast_cdr_disposition is called, it will call ast_cdr_failed()
- if ast_cdr_disposition returns a non-zero value */
-
-int ast_cdr_disposition(struct ast_cdr *cdr, int cause)
-{
- int res = 0;
-
- for (; cdr; cdr = cdr->next) {
- switch(cause) { /* handle all the non failure, busy cases, return 0 not to set disposition,
- return -1 to set disposition to FAILED */
- case AST_CAUSE_BUSY:
- ast_cdr_busy(cdr);
- break;
- case AST_CAUSE_NORMAL:
- break;
- default:
- res = -1;
- }
- }
- return res;
-}
-
-void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chann)
-{
- for (; cdr; cdr = cdr->next) {
- check_post(cdr);
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
- ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel));
- }
-}
-
-void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data)
-{
-
- for (; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- check_post(cdr);
- ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp));
- ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata));
- }
- }
-}
-
-/* set cid info for one record */
-static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
-{
- /* Grab source from ANI or normal Caller*ID */
- const char *num = S_OR(c->cid.cid_ani, c->cid.cid_num);
- if (!cdr)
- return;
- if (!ast_strlen_zero(c->cid.cid_name)) {
- if (!ast_strlen_zero(num)) /* both name and number */
- snprintf(cdr->clid, sizeof(cdr->clid), "\"%s\" <%s>", c->cid.cid_name, num);
- else /* only name */
- ast_copy_string(cdr->clid, c->cid.cid_name, sizeof(cdr->clid));
- } else if (!ast_strlen_zero(num)) { /* only number */
- ast_copy_string(cdr->clid, num, sizeof(cdr->clid));
- } else { /* nothing known */
- cdr->clid[0] = '\0';
- }
- ast_copy_string(cdr->src, S_OR(num, ""), sizeof(cdr->src));
-
-}
-int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *c)
-{
- for (; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
- set_one_cid(cdr, c);
- }
- return 0;
-}
-
-int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *c)
-{
- char *chan;
-
- for ( ; cdr ; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- chan = S_OR(cdr->channel, "<unknown>");
- ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel));
- set_one_cid(cdr, c);
-
- cdr->disposition = (c->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
- cdr->amaflags = c->amaflags ? c->amaflags : ast_default_amaflags;
- ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
- /* Destination information */
- ast_copy_string(cdr->dst, S_OR(c->macroexten,c->exten), sizeof(cdr->dst));
- ast_copy_string(cdr->dcontext, S_OR(c->macrocontext,c->context), sizeof(cdr->dcontext));
- /* Unique call identifier */
- ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid));
- }
- }
- return 0;
-}
-
-void ast_cdr_end(struct ast_cdr *cdr)
-{
- for ( ; cdr ; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- check_post(cdr);
- if (ast_tvzero(cdr->end))
- cdr->end = ast_tvnow();
- if (ast_tvzero(cdr->start)) {
- ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>"));
- cdr->disposition = AST_CDR_FAILED;
- } else
- cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
- cdr->billsec = ast_tvzero(cdr->answer) ? 0 : cdr->end.tv_sec - cdr->answer.tv_sec;
- }
- }
-}
-
-char *ast_cdr_disp2str(int disposition)
-{
- switch (disposition) {
- case AST_CDR_NULL:
- return "NO ANSWER"; /* by default, for backward compatibility */
- case AST_CDR_NOANSWER:
- return "NO ANSWER";
- case AST_CDR_FAILED:
- return "FAILED";
- case AST_CDR_BUSY:
- return "BUSY";
- case AST_CDR_ANSWERED:
- return "ANSWERED";
- }
- return "UNKNOWN";
-}
-
-/*! Converts AMA flag to printable string */
-char *ast_cdr_flags2str(int flag)
-{
- switch(flag) {
- case AST_CDR_OMIT:
- return "OMIT";
- case AST_CDR_BILLING:
- return "BILLING";
- case AST_CDR_DOCUMENTATION:
- return "DOCUMENTATION";
- }
- return "Unknown";
-}
-
-int ast_cdr_setaccount(struct ast_channel *chan, const char *account)
-{
- struct ast_cdr *cdr = chan->cdr;
-
- ast_string_field_set(chan, accountcode, account);
- for ( ; cdr ; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode));
- }
- }
- return 0;
-}
-
-int ast_cdr_setamaflags(struct ast_channel *chan, const char *flag)
-{
- struct ast_cdr *cdr;
- int newflag = ast_cdr_amaflags2int(flag);
- if (newflag) {
- for (cdr = chan->cdr; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- cdr->amaflags = newflag;
- }
- }
- }
-
- return 0;
-}
-
-int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield)
-{
- struct ast_cdr *cdr = chan->cdr;
-
- for ( ; cdr ; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
- ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield));
- }
-
- return 0;
-}
-
-int ast_cdr_appenduserfield(struct ast_channel *chan, const char *userfield)
-{
- struct ast_cdr *cdr = chan->cdr;
-
- for ( ; cdr ; cdr = cdr->next) {
- int len = strlen(cdr->userfield);
-
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
- ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len);
- }
-
- return 0;
-}
-
-int ast_cdr_update(struct ast_channel *c)
-{
- struct ast_cdr *cdr = c->cdr;
-
- for ( ; cdr ; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- set_one_cid(cdr, c);
-
- /* Copy account code et-al */
- ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
-
- /* Destination information */ /* XXX privilege macro* ? */
- ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst));
- ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext));
- }
- }
-
- return 0;
-}
-
-int ast_cdr_amaflags2int(const char *flag)
-{
- if (!strcasecmp(flag, "default"))
- return 0;
- if (!strcasecmp(flag, "omit"))
- return AST_CDR_OMIT;
- if (!strcasecmp(flag, "billing"))
- return AST_CDR_BILLING;
- if (!strcasecmp(flag, "documentation"))
- return AST_CDR_DOCUMENTATION;
- return -1;
-}
-
-static void post_cdr(struct ast_cdr *cdr)
-{
- char *chan;
- struct ast_cdr_beitem *i;
-
- for ( ; cdr ; cdr = cdr->next) {
- if (!unanswered && cdr->disposition < AST_CDR_ANSWERED && (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
- /* For people, who don't want to see unanswered single-channel events */
- ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
- continue;
- }
-
- chan = S_OR(cdr->channel, "<unknown>");
- check_post(cdr);
- if (ast_tvzero(cdr->end))
- ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
- if (ast_tvzero(cdr->start))
- ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
- ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
- if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
- continue;
- AST_LIST_LOCK(&be_list);
- AST_LIST_TRAVERSE(&be_list, i, list) {
- i->be(cdr);
- }
- AST_LIST_UNLOCK(&be_list);
- }
-}
-
-void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *_flags)
-{
- struct ast_cdr *dup;
- struct ast_flags flags = { 0 };
-
- if (_flags)
- ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
-
- for ( ; cdr ; cdr = cdr->next) {
- /* Detach if post is requested */
- if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) {
- ast_cdr_end(cdr);
- if ((dup = ast_cdr_dup(cdr))) {
- ast_cdr_detach(dup);
- }
- ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
- }
-
- /* clear variables */
- if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
- ast_cdr_free_vars(cdr, 0);
- }
-
- /* Reset to initial state */
- ast_clear_flag(cdr, AST_FLAGS_ALL);
- memset(&cdr->start, 0, sizeof(cdr->start));
- memset(&cdr->end, 0, sizeof(cdr->end));
- memset(&cdr->answer, 0, sizeof(cdr->answer));
- cdr->billsec = 0;
- cdr->duration = 0;
- ast_cdr_start(cdr);
- cdr->disposition = AST_CDR_NULL;
- }
- }
-}
-
-struct ast_cdr *ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr)
-{
- struct ast_cdr *ret;
-
- if (cdr) {
- ret = cdr;
-
- while (cdr->next)
- cdr = cdr->next;
- cdr->next = newcdr;
- } else {
- ret = newcdr;
- }
-
- return ret;
-}
-
-/*! \note Don't call without cdr_batch_lock */
-static void reset_batch(void)
-{
- batch->size = 0;
- batch->head = NULL;
- batch->tail = NULL;
-}
-
-/*! \note Don't call without cdr_batch_lock */
-static int init_batch(void)
-{
- /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
- if (!(batch = ast_malloc(sizeof(*batch))))
- return -1;
-
- reset_batch();
-
- return 0;
-}
-
-static void *do_batch_backend_process(void *data)
-{
- struct ast_cdr_batch_item *processeditem;
- struct ast_cdr_batch_item *batchitem = data;
-
- /* Push each CDR into storage mechanism(s) and free all the memory */
- while (batchitem) {
- post_cdr(batchitem->cdr);
- ast_cdr_free(batchitem->cdr);
- processeditem = batchitem;
- batchitem = batchitem->next;
- free(processeditem);
- }
-
- return NULL;
-}
-
-void ast_cdr_submit_batch(int shutdown)
-{
- struct ast_cdr_batch_item *oldbatchitems = NULL;
- pthread_attr_t attr;
- pthread_t batch_post_thread = AST_PTHREADT_NULL;
-
- /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
- if (!batch || !batch->head)
- return;
-
- /* move the old CDRs aside, and prepare a new CDR batch */
- ast_mutex_lock(&cdr_batch_lock);
- oldbatchitems = batch->head;
- reset_batch();
- ast_mutex_unlock(&cdr_batch_lock);
-
- /* if configured, spawn a new thread to post these CDRs,
- also try to save as much as possible if we are shutting down safely */
- if (batchscheduleronly || shutdown) {
- if (option_debug)
- ast_log(LOG_DEBUG, "CDR single-threaded batch processing begins now\n");
- do_batch_backend_process(oldbatchitems);
- } else {
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create_background(&batch_post_thread, &attr, do_batch_backend_process, oldbatchitems)) {
- ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
- do_batch_backend_process(oldbatchitems);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "CDR multi-threaded batch processing begins now\n");
- }
- pthread_attr_destroy(&attr);
- }
-}
-
-static int submit_scheduled_batch(const void *data)
-{
- ast_cdr_submit_batch(0);
- /* manually reschedule from this point in time */
- cdr_sched = ast_sched_add(sched, batchtime * 1000, submit_scheduled_batch, NULL);
- /* returning zero so the scheduler does not automatically reschedule */
- return 0;
-}
-
-static void submit_unscheduled_batch(void)
-{
- /* this is okay since we are not being called from within the scheduler */
- AST_SCHED_DEL(sched, cdr_sched);
- /* schedule the submission to occur ASAP (1 ms) */
- cdr_sched = ast_sched_add(sched, 1, submit_scheduled_batch, NULL);
- /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */
- ast_mutex_lock(&cdr_pending_lock);
- ast_cond_signal(&cdr_pending_cond);
- ast_mutex_unlock(&cdr_pending_lock);
-}
-
-void ast_cdr_detach(struct ast_cdr *cdr)
-{
- struct ast_cdr_batch_item *newtail;
- int curr;
-
- if (!cdr)
- return;
-
- /* maybe they disabled CDR stuff completely, so just drop it */
- if (!enabled) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping CDR !\n");
- ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
- ast_cdr_free(cdr);
- return;
- }
-
- /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
- if (!batchmode) {
- post_cdr(cdr);
- ast_cdr_free(cdr);
- return;
- }
-
- /* otherwise, each CDR gets put into a batch list (at the end) */
- if (option_debug)
- ast_log(LOG_DEBUG, "CDR detaching from this thread\n");
-
- /* we'll need a new tail for every CDR */
- if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
- post_cdr(cdr);
- ast_cdr_free(cdr);
- return;
- }
-
- /* don't traverse a whole list (just keep track of the tail) */
- ast_mutex_lock(&cdr_batch_lock);
- if (!batch)
- init_batch();
- if (!batch->head) {
- /* new batch is empty, so point the head at the new tail */
- batch->head = newtail;
- } else {
- /* already got a batch with something in it, so just append a new tail */
- batch->tail->next = newtail;
- }
- newtail->cdr = cdr;
- batch->tail = newtail;
- curr = batch->size++;
- ast_mutex_unlock(&cdr_batch_lock);
-
- /* if we have enough stuff to post, then do it */
- if (curr >= (batchsize - 1))
- submit_unscheduled_batch();
-}
-
-static void *do_cdr(void *data)
-{
- struct timespec timeout;
- int schedms;
- int numevents = 0;
-
- for(;;) {
- struct timeval now;
- schedms = ast_sched_wait(sched);
- /* this shouldn't happen, but provide a 1 second default just in case */
- if (schedms <= 0)
- schedms = 1000;
- now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000));
- timeout.tv_sec = now.tv_sec;
- timeout.tv_nsec = now.tv_usec * 1000;
- /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */
- ast_mutex_lock(&cdr_pending_lock);
- ast_cond_timedwait(&cdr_pending_cond, &cdr_pending_lock, &timeout);
- numevents = ast_sched_runq(sched);
- ast_mutex_unlock(&cdr_pending_lock);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Processed %d scheduled CDR batches from the run queue\n", numevents);
- }
-
- return NULL;
-}
-
-static int handle_cli_status(int fd, int argc, char *argv[])
-{
- struct ast_cdr_beitem *beitem=NULL;
- int cnt=0;
- long nextbatchtime=0;
-
- if (argc > 2)
- return RESULT_SHOWUSAGE;
-
- ast_cli(fd, "CDR logging: %s\n", enabled ? "enabled" : "disabled");
- ast_cli(fd, "CDR mode: %s\n", batchmode ? "batch" : "simple");
- if (enabled) {
- ast_cli(fd, "CDR output unanswered calls: %s\n", unanswered ? "yes" : "no");
- if (batchmode) {
- if (batch)
- cnt = batch->size;
- if (cdr_sched > -1)
- nextbatchtime = ast_sched_when(sched, cdr_sched);
- ast_cli(fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled");
- ast_cli(fd, "CDR batch threading model: %s\n", batchscheduleronly ? "scheduler only" : "scheduler plus separate threads");
- ast_cli(fd, "CDR current batch size: %d record%s\n", cnt, (cnt != 1) ? "s" : "");
- ast_cli(fd, "CDR maximum batch size: %d record%s\n", batchsize, (batchsize != 1) ? "s" : "");
- ast_cli(fd, "CDR maximum batch time: %d second%s\n", batchtime, (batchtime != 1) ? "s" : "");
- ast_cli(fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, (nextbatchtime != 1) ? "s" : "");
- }
- AST_LIST_LOCK(&be_list);
- AST_LIST_TRAVERSE(&be_list, beitem, list) {
- ast_cli(fd, "CDR registered backend: %s\n", beitem->name);
- }
- AST_LIST_UNLOCK(&be_list);
- }
-
- return 0;
-}
-
-static int handle_cli_submit(int fd, int argc, char *argv[])
-{
- if (argc > 2)
- return RESULT_SHOWUSAGE;
-
- submit_unscheduled_batch();
- ast_cli(fd, "Submitted CDRs to backend engines for processing. This may take a while.\n");
-
- return 0;
-}
-
-static struct ast_cli_entry cli_submit = {
- { "cdr", "submit", NULL },
- handle_cli_submit, "Posts all pending batched CDR data",
- "Usage: cdr submit\n"
- " Posts all pending batched CDR data to the configured CDR backend engine modules.\n"
-};
-
-static struct ast_cli_entry cli_status = {
- { "cdr", "status", NULL },
- handle_cli_status, "Display the CDR status",
- "Usage: cdr status\n"
- " Displays the Call Detail Record engine system status.\n"
-};
-
-static int do_reload(void)
-{
- struct ast_config *config;
- const char *enabled_value;
- const char *unanswered_value;
- const char *batched_value;
- const char *scheduleronly_value;
- const char *batchsafeshutdown_value;
- const char *size_value;
- const char *time_value;
- const char *end_before_h_value;
- int cfg_size;
- int cfg_time;
- int was_enabled;
- int was_batchmode;
- int res=0;
-
- ast_mutex_lock(&cdr_batch_lock);
-
- batchsize = BATCH_SIZE_DEFAULT;
- batchtime = BATCH_TIME_DEFAULT;
- batchscheduleronly = BATCH_SCHEDULER_ONLY_DEFAULT;
- batchsafeshutdown = BATCH_SAFE_SHUTDOWN_DEFAULT;
- was_enabled = enabled;
- was_batchmode = batchmode;
- enabled = 1;
- batchmode = 0;
-
- /* don't run the next scheduled CDR posting while reloading */
- AST_SCHED_DEL(sched, cdr_sched);
-
- if ((config = ast_config_load("cdr.conf"))) {
- if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
- enabled = ast_true(enabled_value);
- }
- if ((unanswered_value = ast_variable_retrieve(config, "general", "unanswered"))) {
- unanswered = ast_true(unanswered_value);
- }
- if ((batched_value = ast_variable_retrieve(config, "general", "batch"))) {
- batchmode = ast_true(batched_value);
- }
- if ((scheduleronly_value = ast_variable_retrieve(config, "general", "scheduleronly"))) {
- batchscheduleronly = ast_true(scheduleronly_value);
- }
- if ((batchsafeshutdown_value = ast_variable_retrieve(config, "general", "safeshutdown"))) {
- batchsafeshutdown = ast_true(batchsafeshutdown_value);
- }
- if ((size_value = ast_variable_retrieve(config, "general", "size"))) {
- if (sscanf(size_value, "%d", &cfg_size) < 1)
- ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", size_value);
- else if (size_value < 0)
- ast_log(LOG_WARNING, "Invalid maximum batch size '%d' specified, using default\n", cfg_size);
- else
- batchsize = cfg_size;
- }
- if ((time_value = ast_variable_retrieve(config, "general", "time"))) {
- if (sscanf(time_value, "%d", &cfg_time) < 1)
- ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", time_value);
- else if (time_value < 0)
- ast_log(LOG_WARNING, "Invalid maximum batch time '%d' specified, using default\n", cfg_time);
- else
- batchtime = cfg_time;
- }
- if ((end_before_h_value = ast_variable_retrieve(config, "general", "endbeforehexten")))
- ast_set2_flag(&ast_options, ast_true(end_before_h_value), AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN);
- }
-
- if (enabled && !batchmode) {
- ast_log(LOG_NOTICE, "CDR simple logging enabled.\n");
- } else if (enabled && batchmode) {
- cdr_sched = ast_sched_add(sched, batchtime * 1000, submit_scheduled_batch, NULL);
- ast_log(LOG_NOTICE, "CDR batch mode logging enabled, first of either size %d or time %d seconds.\n", batchsize, batchtime);
- } else {
- ast_log(LOG_NOTICE, "CDR logging disabled, data will be lost.\n");
- }
-
- /* if this reload enabled the CDR batch mode, create the background thread
- if it does not exist */
- if (enabled && batchmode && (!was_enabled || !was_batchmode) && (cdr_thread == AST_PTHREADT_NULL)) {
- ast_cond_init(&cdr_pending_cond, NULL);
- if (ast_pthread_create_background(&cdr_thread, NULL, do_cdr, NULL) < 0) {
- ast_log(LOG_ERROR, "Unable to start CDR thread.\n");
- AST_SCHED_DEL(sched, cdr_sched);
- } else {
- ast_cli_register(&cli_submit);
- ast_register_atexit(ast_cdr_engine_term);
- res = 0;
- }
- /* if this reload disabled the CDR and/or batch mode and there is a background thread,
- kill it */
- } else if (((!enabled && was_enabled) || (!batchmode && was_batchmode)) && (cdr_thread != AST_PTHREADT_NULL)) {
- /* wake up the thread so it will exit */
- pthread_cancel(cdr_thread);
- pthread_kill(cdr_thread, SIGURG);
- pthread_join(cdr_thread, NULL);
- cdr_thread = AST_PTHREADT_NULL;
- ast_cond_destroy(&cdr_pending_cond);
- ast_cli_unregister(&cli_submit);
- ast_unregister_atexit(ast_cdr_engine_term);
- res = 0;
- /* if leaving batch mode, then post the CDRs in the batch,
- and don't reschedule, since we are stopping CDR logging */
- if (!batchmode && was_batchmode) {
- ast_cdr_engine_term();
- }
- } else {
- res = 0;
- }
-
- ast_mutex_unlock(&cdr_batch_lock);
- ast_config_destroy(config);
-
- return res;
-}
-
-int ast_cdr_engine_init(void)
-{
- int res;
-
- sched = sched_context_create();
- if (!sched) {
- ast_log(LOG_ERROR, "Unable to create schedule context.\n");
- return -1;
- }
-
- ast_cli_register(&cli_status);
-
- res = do_reload();
- if (res) {
- ast_mutex_lock(&cdr_batch_lock);
- res = init_batch();
- ast_mutex_unlock(&cdr_batch_lock);
- }
-
- return res;
-}
-
-/* \note This actually gets called a couple of times at shutdown. Once, before we start
- hanging up channels, and then again, after the channel hangup timeout expires */
-void ast_cdr_engine_term(void)
-{
- ast_cdr_submit_batch(batchsafeshutdown);
-}
-
-int ast_cdr_engine_reload(void)
-{
- return do_reload();
-}
-
diff --git a/1.4/main/channel.c b/1.4/main/channel.c
deleted file mode 100644
index f61d365b7..000000000
--- a/1.4/main/channel.c
+++ /dev/null
@@ -1,4695 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Channel Management
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <math.h>
-
-#ifdef HAVE_ZAPTEL
-#include <sys/ioctl.h>
-#include <zaptel/zaptel.h>
-#endif
-
-#include "asterisk/pbx.h"
-#include "asterisk/frame.h"
-#include "asterisk/sched.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/audiohook.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/logger.h"
-#include "asterisk/say.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/translate.h"
-#include "asterisk/manager.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/indications.h"
-#include "asterisk/monitor.h"
-#include "asterisk/causes.h"
-#include "asterisk/callerid.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-#include "asterisk/transcap.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/sha1.h"
-#include "asterisk/threadstorage.h"
-#include "asterisk/slinfactory.h"
-
-/* uncomment if you have problems with 'monitoring' synchronized files */
-#if 0
-#define MONITOR_CONSTANT_DELAY
-#define MONITOR_DELAY 150 * 8 /* 150 ms of MONITORING DELAY */
-#endif
-
-/*! Prevent new channel allocation if shutting down. */
-static int shutting_down;
-
-static int uniqueint;
-
-unsigned long global_fin, global_fout;
-
-AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init);
-#define STATE2STR_BUFSIZE 32
-
-/*! Default amount of time to use when emulating a digit as a begin and end
- * 100ms */
-#define AST_DEFAULT_EMULATE_DTMF_DURATION 100
-
-/*! Minimum allowed digit length - 80ms */
-#define AST_MIN_DTMF_DURATION 80
-
-/*! Minimum amount of time between the end of the last digit and the beginning
- * of a new one - 45ms */
-#define AST_MIN_DTMF_GAP 45
-
-struct chanlist {
- const struct ast_channel_tech *tech;
- AST_LIST_ENTRY(chanlist) list;
-};
-
-/*! the list of registered channel types */
-static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
-
-/*! the list of channels we have. Note that the lock for this list is used for
- both the channels list and the backends list. */
-static AST_LIST_HEAD_STATIC(channels, ast_channel);
-
-/*! map AST_CAUSE's to readable string representations */
-const struct ast_cause {
- int cause;
- const char *name;
- const char *desc;
-} causes[] = {
- { AST_CAUSE_UNALLOCATED, "UNALLOCATED", "Unallocated (unassigned) number" },
- { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "NO_ROUTE_TRANSIT_NET", "No route to specified transmit network" },
- { AST_CAUSE_NO_ROUTE_DESTINATION, "NO_ROUTE_DESTINATION", "No route to destination" },
- { AST_CAUSE_CHANNEL_UNACCEPTABLE, "CHANNEL_UNACCEPTABLE", "Channel unacceptable" },
- { AST_CAUSE_CALL_AWARDED_DELIVERED, "CALL_AWARDED_DELIVERED", "Call awarded and being delivered in an established channel" },
- { AST_CAUSE_NORMAL_CLEARING, "NORMAL_CLEARING", "Normal Clearing" },
- { AST_CAUSE_USER_BUSY, "USER_BUSY", "User busy" },
- { AST_CAUSE_NO_USER_RESPONSE, "NO_USER_RESPONSE", "No user responding" },
- { AST_CAUSE_NO_ANSWER, "NO_ANSWER", "User alerting, no answer" },
- { AST_CAUSE_CALL_REJECTED, "CALL_REJECTED", "Call Rejected" },
- { AST_CAUSE_NUMBER_CHANGED, "NUMBER_CHANGED", "Number changed" },
- { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "DESTINATION_OUT_OF_ORDER", "Destination out of order" },
- { AST_CAUSE_INVALID_NUMBER_FORMAT, "INVALID_NUMBER_FORMAT", "Invalid number format" },
- { AST_CAUSE_FACILITY_REJECTED, "FACILITY_REJECTED", "Facility rejected" },
- { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "RESPONSE_TO_STATUS_ENQUIRY", "Response to STATus ENQuiry" },
- { AST_CAUSE_NORMAL_UNSPECIFIED, "NORMAL_UNSPECIFIED", "Normal, unspecified" },
- { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "NORMAL_CIRCUIT_CONGESTION", "Circuit/channel congestion" },
- { AST_CAUSE_NETWORK_OUT_OF_ORDER, "NETWORK_OUT_OF_ORDER", "Network out of order" },
- { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "NORMAL_TEMPORARY_FAILURE", "Temporary failure" },
- { AST_CAUSE_SWITCH_CONGESTION, "SWITCH_CONGESTION", "Switching equipment congestion" },
- { AST_CAUSE_ACCESS_INFO_DISCARDED, "ACCESS_INFO_DISCARDED", "Access information discarded" },
- { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "REQUESTED_CHAN_UNAVAIL", "Requested channel not available" },
- { AST_CAUSE_PRE_EMPTED, "PRE_EMPTED", "Pre-empted" },
- { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "FACILITY_NOT_SUBSCRIBED", "Facility not subscribed" },
- { AST_CAUSE_OUTGOING_CALL_BARRED, "OUTGOING_CALL_BARRED", "Outgoing call barred" },
- { AST_CAUSE_INCOMING_CALL_BARRED, "INCOMING_CALL_BARRED", "Incoming call barred" },
- { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "BEARERCAPABILITY_NOTAUTH", "Bearer capability not authorized" },
- { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "BEARERCAPABILITY_NOTAVAIL", "Bearer capability not available" },
- { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "BEARERCAPABILITY_NOTIMPL", "Bearer capability not implemented" },
- { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "CHAN_NOT_IMPLEMENTED", "Channel not implemented" },
- { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "FACILITY_NOT_IMPLEMENTED", "Facility not implemented" },
- { AST_CAUSE_INVALID_CALL_REFERENCE, "INVALID_CALL_REFERENCE", "Invalid call reference value" },
- { AST_CAUSE_INCOMPATIBLE_DESTINATION, "INCOMPATIBLE_DESTINATION", "Incompatible destination" },
- { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "INVALID_MSG_UNSPECIFIED", "Invalid message unspecified" },
- { AST_CAUSE_MANDATORY_IE_MISSING, "MANDATORY_IE_MISSING", "Mandatory information element is missing" },
- { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "MESSAGE_TYPE_NONEXIST", "Message type nonexist." },
- { AST_CAUSE_WRONG_MESSAGE, "WRONG_MESSAGE", "Wrong message" },
- { AST_CAUSE_IE_NONEXIST, "IE_NONEXIST", "Info. element nonexist or not implemented" },
- { AST_CAUSE_INVALID_IE_CONTENTS, "INVALID_IE_CONTENTS", "Invalid information element contents" },
- { AST_CAUSE_WRONG_CALL_STATE, "WRONG_CALL_STATE", "Message not compatible with call state" },
- { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "RECOVERY_ON_TIMER_EXPIRE", "Recover on timer expiry" },
- { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "MANDATORY_IE_LENGTH_ERROR", "Mandatory IE length error" },
- { AST_CAUSE_PROTOCOL_ERROR, "PROTOCOL_ERROR", "Protocol error, unspecified" },
- { AST_CAUSE_INTERWORKING, "INTERWORKING", "Interworking, unspecified" },
-};
-
-struct ast_variable *ast_channeltype_list(void)
-{
- struct chanlist *cl;
- struct ast_variable *var=NULL, *prev = NULL;
- AST_LIST_TRAVERSE(&backends, cl, list) {
- if (prev) {
- if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description)))
- prev = prev->next;
- } else {
- var = ast_variable_new(cl->tech->type, cl->tech->description);
- prev = var;
- }
- }
- return var;
-}
-
-static int show_channeltypes(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
- struct chanlist *cl;
- int count_chan = 0;
-
- ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
- ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return -1;
- }
- AST_LIST_TRAVERSE(&backends, cl, list) {
- ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
- (cl->tech->devicestate) ? "yes" : "no",
- (cl->tech->indicate) ? "yes" : "no",
- (cl->tech->transfer) ? "yes" : "no");
- count_chan++;
- }
- AST_LIST_UNLOCK(&channels);
- ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
- return RESULT_SUCCESS;
-
-#undef FORMAT
-
-}
-
-static int show_channeltype_deprecated(int fd, int argc, char *argv[])
-{
- struct chanlist *cl = NULL;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return RESULT_FAILURE;
- }
-
- AST_LIST_TRAVERSE(&backends, cl, list) {
- if (!strncasecmp(cl->tech->type, argv[2], strlen(cl->tech->type))) {
- break;
- }
- }
-
-
- if (!cl) {
- ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]);
- AST_LIST_UNLOCK(&channels);
- return RESULT_FAILURE;
- }
-
- ast_cli(fd,
- "-- Info about channel driver: %s --\n"
- " Device State: %s\n"
- " Indication: %s\n"
- " Transfer : %s\n"
- " Capabilities: %d\n"
- " Digit Begin: %s\n"
- " Digit End: %s\n"
- " Send HTML : %s\n"
- " Image Support: %s\n"
- " Text Support: %s\n",
- cl->tech->type,
- (cl->tech->devicestate) ? "yes" : "no",
- (cl->tech->indicate) ? "yes" : "no",
- (cl->tech->transfer) ? "yes" : "no",
- (cl->tech->capabilities) ? cl->tech->capabilities : -1,
- (cl->tech->send_digit_begin) ? "yes" : "no",
- (cl->tech->send_digit_end) ? "yes" : "no",
- (cl->tech->send_html) ? "yes" : "no",
- (cl->tech->send_image) ? "yes" : "no",
- (cl->tech->send_text) ? "yes" : "no"
-
- );
-
- AST_LIST_UNLOCK(&channels);
- return RESULT_SUCCESS;
-}
-
-static int show_channeltype(int fd, int argc, char *argv[])
-{
- struct chanlist *cl = NULL;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return RESULT_FAILURE;
- }
-
- AST_LIST_TRAVERSE(&backends, cl, list) {
- if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
- break;
- }
- }
-
-
- if (!cl) {
- ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
- AST_LIST_UNLOCK(&channels);
- return RESULT_FAILURE;
- }
-
- ast_cli(fd,
- "-- Info about channel driver: %s --\n"
- " Device State: %s\n"
- " Indication: %s\n"
- " Transfer : %s\n"
- " Capabilities: %d\n"
- " Digit Begin: %s\n"
- " Digit End: %s\n"
- " Send HTML : %s\n"
- " Image Support: %s\n"
- " Text Support: %s\n",
- cl->tech->type,
- (cl->tech->devicestate) ? "yes" : "no",
- (cl->tech->indicate) ? "yes" : "no",
- (cl->tech->transfer) ? "yes" : "no",
- (cl->tech->capabilities) ? cl->tech->capabilities : -1,
- (cl->tech->send_digit_begin) ? "yes" : "no",
- (cl->tech->send_digit_end) ? "yes" : "no",
- (cl->tech->send_html) ? "yes" : "no",
- (cl->tech->send_image) ? "yes" : "no",
- (cl->tech->send_text) ? "yes" : "no"
-
- );
-
- AST_LIST_UNLOCK(&channels);
- return RESULT_SUCCESS;
-}
-
-static char *complete_channeltypes_deprecated(const char *line, const char *word, int pos, int state)
-{
- struct chanlist *cl;
- int which = 0;
- int wordlen;
- char *ret = NULL;
-
- if (pos != 2)
- return NULL;
-
- wordlen = strlen(word);
-
- AST_LIST_TRAVERSE(&backends, cl, list) {
- if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
- ret = strdup(cl->tech->type);
- break;
- }
- }
-
- return ret;
-}
-
-static char *complete_channeltypes(const char *line, const char *word, int pos, int state)
-{
- struct chanlist *cl;
- int which = 0;
- int wordlen;
- char *ret = NULL;
-
- if (pos != 3)
- return NULL;
-
- wordlen = strlen(word);
-
- AST_LIST_TRAVERSE(&backends, cl, list) {
- if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
- ret = strdup(cl->tech->type);
- break;
- }
- }
-
- return ret;
-}
-
-static char show_channeltypes_usage[] =
-"Usage: core show channeltypes\n"
-" Lists available channel types registered in your Asterisk server.\n";
-
-static char show_channeltype_usage[] =
-"Usage: core show channeltype <name>\n"
-" Show details about the specified channel type, <name>.\n";
-
-static struct ast_cli_entry cli_show_channeltypes_deprecated = {
- { "show", "channeltypes", NULL },
- show_channeltypes, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_channeltype_deprecated = {
- { "show", "channeltype", NULL },
- show_channeltype_deprecated, NULL,
- NULL, complete_channeltypes_deprecated };
-
-static struct ast_cli_entry cli_channel[] = {
- { { "core", "show", "channeltypes", NULL },
- show_channeltypes, "List available channel types",
- show_channeltypes_usage, NULL, &cli_show_channeltypes_deprecated },
-
- { { "core", "show", "channeltype", NULL },
- show_channeltype, "Give more details on that channel type",
- show_channeltype_usage, complete_channeltypes, &cli_show_channeltype_deprecated },
-};
-
-/*! \brief Checks to see if a channel is needing hang up */
-int ast_check_hangup(struct ast_channel *chan)
-{
- if (chan->_softhangup) /* yes if soft hangup flag set */
- return 1;
- if (!chan->tech_pvt) /* yes if no technology private data */
- return 1;
- if (!chan->whentohangup) /* no if no hangup scheduled */
- return 0;
- if (chan->whentohangup > time(NULL)) /* no if hangup time has not come yet. */
- return 0;
- chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
- return 1;
-}
-
-static int ast_check_hangup_locked(struct ast_channel *chan)
-{
- int res;
- ast_channel_lock(chan);
- res = ast_check_hangup(chan);
- ast_channel_unlock(chan);
- return res;
-}
-
-/*! \brief printf the string into a correctly sized mallocd buffer, and return the buffer */
-char *ast_safe_string_alloc(const char *fmt, ...)
-{
- char *b2, buf[1];
- int len;
- va_list args;
-
- va_start(args, fmt);
- len = vsnprintf(buf, 1, fmt, args);
- va_end(args);
-
- if (!(b2 = ast_malloc(len + 1)))
- return NULL;
-
- va_start(args, fmt);
- vsnprintf(b2, len + 1, fmt, args);
- va_end(args);
-
- return b2;
-}
-
-/*! \brief Initiate system shutdown */
-void ast_begin_shutdown(int hangup)
-{
- struct ast_channel *c;
- shutting_down = 1;
- if (hangup) {
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list)
- ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
- AST_LIST_UNLOCK(&channels);
- }
-}
-
-/*! \brief returns number of active/allocated channels */
-int ast_active_channels(void)
-{
- struct ast_channel *c;
- int cnt = 0;
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list)
- cnt++;
- AST_LIST_UNLOCK(&channels);
- return cnt;
-}
-
-/*! \brief Cancel a shutdown in progress */
-void ast_cancel_shutdown(void)
-{
- shutting_down = 0;
-}
-
-/*! \brief Returns non-zero if Asterisk is being shut down */
-int ast_shutting_down(void)
-{
- return shutting_down;
-}
-
-/*! \brief Set when to hangup channel */
-void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
-{
- chan->whentohangup = offset ? time(NULL) + offset : 0;
- ast_queue_frame(chan, &ast_null_frame);
- return;
-}
-
-/*! \brief Compare a offset with when to hangup channel */
-int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
-{
- time_t whentohangup;
-
- if (chan->whentohangup == 0) {
- return (offset == 0) ? 0 : -1;
- } else {
- if (offset == 0) /* XXX why is this special ? */
- return (1);
- else {
- whentohangup = offset + time (NULL);
- if (chan->whentohangup < whentohangup)
- return (1);
- else if (chan->whentohangup == whentohangup)
- return (0);
- else
- return (-1);
- }
- }
-}
-
-/*! \brief Register a new telephony channel in Asterisk */
-int ast_channel_register(const struct ast_channel_tech *tech)
-{
- struct chanlist *chan;
-
- AST_LIST_LOCK(&channels);
-
- AST_LIST_TRAVERSE(&backends, chan, list) {
- if (!strcasecmp(tech->type, chan->tech->type)) {
- ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
- AST_LIST_UNLOCK(&channels);
- return -1;
- }
- }
-
- if (!(chan = ast_calloc(1, sizeof(*chan)))) {
- AST_LIST_UNLOCK(&channels);
- return -1;
- }
- chan->tech = tech;
- AST_LIST_INSERT_HEAD(&backends, chan, list);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
- chan->tech->description);
-
- AST_LIST_UNLOCK(&channels);
- return 0;
-}
-
-void ast_channel_unregister(const struct ast_channel_tech *tech)
-{
- struct chanlist *chan;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
-
- AST_LIST_LOCK(&channels);
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
- if (chan->tech == tech) {
- AST_LIST_REMOVE_CURRENT(&backends, list);
- free(chan);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- AST_LIST_UNLOCK(&channels);
-}
-
-const struct ast_channel_tech *ast_get_channel_tech(const char *name)
-{
- struct chanlist *chanls;
- const struct ast_channel_tech *ret = NULL;
-
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
- return NULL;
- }
-
- AST_LIST_TRAVERSE(&backends, chanls, list) {
- if (!strcasecmp(name, chanls->tech->type)) {
- ret = chanls->tech;
- break;
- }
- }
-
- AST_LIST_UNLOCK(&channels);
-
- return ret;
-}
-
-/*! \brief Gives the string form of a given hangup cause */
-const char *ast_cause2str(int cause)
-{
- int x;
-
- for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
- if (causes[x].cause == cause)
- return causes[x].desc;
- }
-
- return "Unknown";
-}
-
-/*! \brief Convert a symbolic hangup cause to number */
-int ast_str2cause(const char *name)
-{
- int x;
-
- for (x = 0; x < sizeof(causes) / sizeof(causes[0]); x++)
- if (strncasecmp(causes[x].name, name, strlen(causes[x].name)) == 0)
- return causes[x].cause;
-
- return -1;
-}
-
-/*! \brief Gives the string form of a given channel state */
-char *ast_state2str(enum ast_channel_state state)
-{
- char *buf;
-
- switch(state) {
- case AST_STATE_DOWN:
- return "Down";
- case AST_STATE_RESERVED:
- return "Rsrvd";
- case AST_STATE_OFFHOOK:
- return "OffHook";
- case AST_STATE_DIALING:
- return "Dialing";
- case AST_STATE_RING:
- return "Ring";
- case AST_STATE_RINGING:
- return "Ringing";
- case AST_STATE_UP:
- return "Up";
- case AST_STATE_BUSY:
- return "Busy";
- case AST_STATE_DIALING_OFFHOOK:
- return "Dialing Offhook";
- case AST_STATE_PRERING:
- return "Pre-ring";
- default:
- if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
- return "Unknown";
- snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
- return buf;
- }
-}
-
-/*! \brief Gives the string form of a given transfer capability */
-char *ast_transfercapability2str(int transfercapability)
-{
- switch(transfercapability) {
- case AST_TRANS_CAP_SPEECH:
- return "SPEECH";
- case AST_TRANS_CAP_DIGITAL:
- return "DIGITAL";
- case AST_TRANS_CAP_RESTRICTED_DIGITAL:
- return "RESTRICTED_DIGITAL";
- case AST_TRANS_CAP_3_1K_AUDIO:
- return "3K1AUDIO";
- case AST_TRANS_CAP_DIGITAL_W_TONES:
- return "DIGITAL_W_TONES";
- case AST_TRANS_CAP_VIDEO:
- return "VIDEO";
- default:
- return "UNKNOWN";
- }
-}
-
-/*! \brief Pick the best audio codec */
-int ast_best_codec(int fmts)
-{
- /* This just our opinion, expressed in code. We are asked to choose
- the best codec to use, given no information */
- int x;
- static int prefs[] =
- {
- /*! Okay, ulaw is used by all telephony equipment, so start with it */
- AST_FORMAT_ULAW,
- /*! Unless of course, you're a silly European, so then prefer ALAW */
- AST_FORMAT_ALAW,
- /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
- AST_FORMAT_G722,
- /*! Okay, well, signed linear is easy to translate into other stuff */
- AST_FORMAT_SLINEAR,
- /*! G.726 is standard ADPCM, in RFC3551 packing order */
- AST_FORMAT_G726,
- /*! G.726 is standard ADPCM, in AAL2 packing order */
- AST_FORMAT_G726_AAL2,
- /*! ADPCM has great sound quality and is still pretty easy to translate */
- AST_FORMAT_ADPCM,
- /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
- translate and sounds pretty good */
- AST_FORMAT_GSM,
- /*! iLBC is not too bad */
- AST_FORMAT_ILBC,
- /*! Speex is free, but computationally more expensive than GSM */
- AST_FORMAT_SPEEX,
- /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
- to use it */
- AST_FORMAT_LPC10,
- /*! G.729a is faster than 723 and slightly less expensive */
- AST_FORMAT_G729A,
- /*! Down to G.723.1 which is proprietary but at least designed for voice */
- AST_FORMAT_G723_1,
- };
-
- /* Strip out video */
- fmts &= AST_FORMAT_AUDIO_MASK;
-
- /* Find the first preferred codec in the format given */
- for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
- if (fmts & prefs[x])
- return prefs[x];
- ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
- return 0;
-}
-
-static const struct ast_channel_tech null_tech = {
- .type = "NULL",
- .description = "Null channel (should not see this)",
-};
-
-/*! \brief Create a new channel structure */
-struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...)
-{
- struct ast_channel *tmp;
- int x;
- int flags;
- struct varshead *headp;
- va_list ap1, ap2;
-
- /* If shutting down, don't allocate any new channels */
- if (shutting_down) {
- ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
- return NULL;
- }
-
- if (!(tmp = ast_calloc(1, sizeof(*tmp))))
- return NULL;
-
- if (!(tmp->sched = sched_context_create())) {
- ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
- free(tmp);
- return NULL;
- }
-
- if ((ast_string_field_init(tmp, 128))) {
- sched_context_destroy(tmp->sched);
- free(tmp);
- return NULL;
- }
-
- /* Don't bother initializing the last two FD here, because they
- will *always* be set just a few lines down (AST_TIMING_FD,
- AST_ALERT_FD). */
- for (x = 0; x < AST_MAX_FDS - 2; x++)
- tmp->fds[x] = -1;
-
-#ifdef HAVE_ZAPTEL
- tmp->timingfd = open("/dev/zap/timer", O_RDWR);
- if (tmp->timingfd > -1) {
- /* Check if timing interface supports new
- ping/pong scheme */
- flags = 1;
- if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
- needqueue = 0;
- }
-#else
- tmp->timingfd = -1;
-#endif
-
- if (needqueue) {
- if (pipe(tmp->alertpipe)) {
- ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
-#ifdef HAVE_ZAPTEL
- if (tmp->timingfd > -1)
- close(tmp->timingfd);
-#endif
- sched_context_destroy(tmp->sched);
- ast_string_field_free_memory(tmp);
- free(tmp);
- return NULL;
- } else {
- flags = fcntl(tmp->alertpipe[0], F_GETFL);
- fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
- flags = fcntl(tmp->alertpipe[1], F_GETFL);
- fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
- }
- } else /* Make sure we've got it done right if they don't */
- tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
-
- /* Always watch the alertpipe */
- tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
- /* And timing pipe */
- tmp->fds[AST_TIMING_FD] = tmp->timingfd;
- ast_string_field_set(tmp, name, "**Unknown**");
-
- /* Initial state */
- tmp->_state = state;
-
- tmp->streamid = -1;
-
- tmp->fin = global_fin;
- tmp->fout = global_fout;
-
- if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
- ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL),
- ast_atomic_fetchadd_int(&uniqueint, 1));
- } else {
- ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME,
- (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
- }
-
- tmp->cid.cid_name = ast_strdup(cid_name);
- tmp->cid.cid_num = ast_strdup(cid_num);
-
- if (!ast_strlen_zero(name_fmt)) {
- /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
- * And they all use slightly different formats for their name string.
- * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
- * This means, that the stringfields must have a routine that takes the va_lists directly, and
- * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
- * This new function was written so this can be accomplished.
- */
- va_start(ap1, name_fmt);
- va_start(ap2, name_fmt);
- ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
- va_end(ap1);
- va_end(ap2);
- }
-
- /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
-
- /* These 4 variables need to be set up for the cdr_init() to work right */
- if (amaflag)
- tmp->amaflags = amaflag;
- else
- tmp->amaflags = ast_default_amaflags;
-
- if (!ast_strlen_zero(acctcode))
- ast_string_field_set(tmp, accountcode, acctcode);
- else
- ast_string_field_set(tmp, accountcode, ast_default_accountcode);
-
- if (!ast_strlen_zero(context))
- ast_copy_string(tmp->context, context, sizeof(tmp->context));
- else
- strcpy(tmp->context, "default");
-
- if (!ast_strlen_zero(exten))
- ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
- else
- strcpy(tmp->exten, "s");
-
- tmp->priority = 1;
-
- tmp->cdr = ast_cdr_alloc();
- ast_cdr_init(tmp->cdr, tmp);
- ast_cdr_start(tmp->cdr);
-
- headp = &tmp->varshead;
- AST_LIST_HEAD_INIT_NOLOCK(headp);
-
- ast_mutex_init(&tmp->lock);
-
- AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
-
- ast_string_field_set(tmp, language, defaultlanguage);
-
- tmp->tech = &null_tech;
-
- AST_LIST_LOCK(&channels);
- AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
- AST_LIST_UNLOCK(&channels);
-
- /*\!note
- * and now, since the channel structure is built, and has its name, let's
- * call the manager event generator with this Newchannel event. This is the
- * proper and correct place to make this call, but you sure do have to pass
- * a lot of data into this func to do it here!
- */
- if (!ast_strlen_zero(name_fmt)) {
- manager_event(EVENT_FLAG_CALL, "Newchannel",
- "Channel: %s\r\n"
- "State: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n",
- tmp->name, ast_state2str(state),
- S_OR(cid_num, "<unknown>"),
- S_OR(cid_name, "<unknown>"),
- tmp->uniqueid);
- }
-
- return tmp;
-}
-
-/*! \brief Queue an outgoing media frame */
-int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
-{
- struct ast_frame *f;
- struct ast_frame *cur;
- int blah = 1;
- int qlen = 0;
-
- /* Build us a copy and free the original one */
- if (!(f = ast_frdup(fin))) {
- ast_log(LOG_WARNING, "Unable to duplicate frame\n");
- return -1;
- }
- ast_channel_lock(chan);
-
- /* See if the last frame on the queue is a hangup, if so don't queue anything */
- if ((cur = AST_LIST_LAST(&chan->readq)) && (cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
- ast_frfree(f);
- ast_channel_unlock(chan);
- return 0;
- }
-
- /* Count how many frames exist on the queue */
- AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
- qlen++;
- }
-
- /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
- if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
- if (fin->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
- CRASH;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
- ast_frfree(f);
- ast_channel_unlock(chan);
- return 0;
- }
- }
- AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
- if (chan->alertpipe[1] > -1) {
- if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
- ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
- chan->name, f->frametype, f->subclass, qlen, strerror(errno));
-#ifdef HAVE_ZAPTEL
- } else if (chan->timingfd > -1) {
- ioctl(chan->timingfd, ZT_TIMERPING, &blah);
-#endif
- } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
- pthread_kill(chan->blocker, SIGURG);
- }
- ast_channel_unlock(chan);
- return 0;
-}
-
-/*! \brief Queue a hangup frame for channel */
-int ast_queue_hangup(struct ast_channel *chan)
-{
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
- /* Yeah, let's not change a lock-critical value without locking */
- if (!ast_channel_trylock(chan)) {
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_channel_unlock(chan);
- }
- return ast_queue_frame(chan, &f);
-}
-
-/*! \brief Queue a control frame */
-int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
-{
- struct ast_frame f = { AST_FRAME_CONTROL, };
-
- f.subclass = control;
-
- return ast_queue_frame(chan, &f);
-}
-
-/*! \brief Queue a control frame with payload */
-int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
- const void *data, size_t datalen)
-{
- struct ast_frame f = { AST_FRAME_CONTROL, };
-
- f.subclass = control;
- f.data = (void *) data;
- f.datalen = datalen;
-
- return ast_queue_frame(chan, &f);
-}
-
-/*! \brief Set defer DTMF flag on channel */
-int ast_channel_defer_dtmf(struct ast_channel *chan)
-{
- int pre = 0;
-
- if (chan) {
- pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
- ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
- }
- return pre;
-}
-
-/*! \brief Unset defer DTMF flag on channel */
-void ast_channel_undefer_dtmf(struct ast_channel *chan)
-{
- if (chan)
- ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
-}
-
-/*!
- * \brief Helper function to find channels.
- *
- * It supports these modes:
- *
- * prev != NULL : get channel next in list after prev
- * name != NULL : get channel with matching name
- * name != NULL && namelen != 0 : get channel whose name starts with prefix
- * exten != NULL : get channel whose exten or macroexten matches
- * context != NULL && exten != NULL : get channel whose context or macrocontext
- *
- * It returns with the channel's lock held. If getting the individual lock fails,
- * unlock and retry quickly up to 10 times, then give up.
- *
- * \note XXX Note that this code has cost O(N) because of the need to verify
- * that the object is still on the global list.
- *
- * \note XXX also note that accessing fields (e.g. c->name in ast_log())
- * can only be done with the lock held or someone could delete the
- * object while we work on it. This causes some ugliness in the code.
- * Note that removing the first ast_log() may be harmful, as it would
- * shorten the retry period and possibly cause failures.
- * We should definitely go for a better scheme that is deadlock-free.
- */
-static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
- const char *name, const int namelen,
- const char *context, const char *exten)
-{
- const char *msg = prev ? "deadlock" : "initial deadlock";
- int retries;
- struct ast_channel *c;
- const struct ast_channel *_prev = prev;
-
- for (retries = 0; retries < 200; retries++) {
- int done;
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list) {
- prev = _prev;
- if (prev) { /* look for next item */
- if (c != prev) /* not this one */
- continue;
- /* found, prepare to return c->next */
- if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break;
- /* If prev was the last item on the channel list, then we just
- * want to return NULL, instead of trying to deref NULL in the
- * next section.
- */
- prev = NULL;
- /* We want prev to be NULL in case we end up doing more searching through
- * the channel list to find the channel (ie: name searching). If we didn't
- * set this to NULL the logic would just blow up
- * XXX Need a better explanation for this ...
- */
- }
- if (name) { /* want match by name */
- if ((!namelen && strcasecmp(c->name, name)) ||
- (namelen && strncasecmp(c->name, name, namelen)))
- continue; /* name match failed */
- } else if (exten) {
- if (context && strcasecmp(c->context, context) &&
- strcasecmp(c->macrocontext, context))
- continue; /* context match failed */
- if (strcasecmp(c->exten, exten) &&
- strcasecmp(c->macroexten, exten))
- continue; /* exten match failed */
- }
- /* if we get here, c points to the desired record */
- break;
- }
- /* exit if chan not found or mutex acquired successfully */
- /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
- done = c == NULL || ast_channel_trylock(c) == 0;
- if (!done) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
- if (retries == 199) {
- /* We are about to fail due to a deadlock, so report this
- * while we still have the list lock.
- */
- if (option_debug)
- ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n", c, retries);
- /* As we have deadlocked, we will skip this channel and
- * see if there is another match.
- * NOTE: No point doing this for a full-name match,
- * as there can be no more matches.
- */
- if (!(name && !namelen)) {
- prev = c;
- retries = -1;
- }
- }
- }
- AST_LIST_UNLOCK(&channels);
- if (done)
- return c;
- /* If we reach this point we basically tried to lock a channel and failed. Instead of
- * starting from the beginning of the list we can restore our saved pointer to the previous
- * channel and start from there.
- */
- prev = _prev;
- usleep(1); /* give other threads a chance before retrying */
- }
-
- return NULL;
-}
-
-/*! \brief Browse channels in use */
-struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev)
-{
- return channel_find_locked(prev, NULL, 0, NULL, NULL);
-}
-
-/*! \brief Get channel by name and lock it */
-struct ast_channel *ast_get_channel_by_name_locked(const char *name)
-{
- return channel_find_locked(NULL, name, 0, NULL, NULL);
-}
-
-/*! \brief Get channel by name prefix and lock it */
-struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen)
-{
- return channel_find_locked(NULL, name, namelen, NULL, NULL);
-}
-
-/*! \brief Get next channel by name prefix and lock it */
-struct ast_channel *ast_walk_channel_by_name_prefix_locked(const struct ast_channel *chan, const char *name,
- const int namelen)
-{
- return channel_find_locked(chan, name, namelen, NULL, NULL);
-}
-
-/*! \brief Get channel by exten (and optionally context) and lock it */
-struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context)
-{
- return channel_find_locked(NULL, NULL, 0, context, exten);
-}
-
-/*! \brief Get next channel by exten (and optionally context) and lock it */
-struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *chan, const char *exten,
- const char *context)
-{
- return channel_find_locked(chan, NULL, 0, context, exten);
-}
-
-/*! \brief Wait, look for hangups and condition arg */
-int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data)
-{
- struct ast_frame *f;
-
- while (ms > 0) {
- if (cond && ((*cond)(data) == 0))
- return 0;
- ms = ast_waitfor(chan, ms);
- if (ms < 0)
- return -1;
- if (ms > 0) {
- f = ast_read(chan);
- if (!f)
- return -1;
- ast_frfree(f);
- }
- }
- return 0;
-}
-
-/*! \brief Wait, look for hangups */
-int ast_safe_sleep(struct ast_channel *chan, int ms)
-{
- return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
-}
-
-static void free_cid(struct ast_callerid *cid)
-{
- if (cid->cid_dnid)
- free(cid->cid_dnid);
- if (cid->cid_num)
- free(cid->cid_num);
- if (cid->cid_name)
- free(cid->cid_name);
- if (cid->cid_ani)
- free(cid->cid_ani);
- if (cid->cid_rdnis)
- free(cid->cid_rdnis);
-}
-
-/*! \brief Free a channel structure */
-void ast_channel_free(struct ast_channel *chan)
-{
- int fd;
- struct ast_var_t *vardata;
- struct ast_frame *f;
- struct varshead *headp;
- struct ast_datastore *datastore = NULL;
- char name[AST_CHANNEL_NAME];
-
- headp=&chan->varshead;
-
- AST_LIST_LOCK(&channels);
- if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
- AST_LIST_UNLOCK(&channels);
- ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
- }
- /* Lock and unlock the channel just to be sure nobody has it locked still
- due to a reference retrieved from the channel list. */
- ast_channel_lock(chan);
- ast_channel_unlock(chan);
-
- /* Get rid of each of the data stores on the channel */
- while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
- /* Free the data store */
- ast_channel_datastore_free(datastore);
-
- /* Lock and unlock the channel just to be sure nobody has it locked still
- due to a reference that was stored in a datastore. (i.e. app_chanspy) */
- ast_channel_lock(chan);
- ast_channel_unlock(chan);
-
- if (chan->tech_pvt) {
- ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
- free(chan->tech_pvt);
- }
-
- if (chan->sched)
- sched_context_destroy(chan->sched);
-
- ast_copy_string(name, chan->name, sizeof(name));
-
- /* Stop monitoring */
- if (chan->monitor)
- chan->monitor->stop( chan, 0 );
-
- /* If there is native format music-on-hold state, free it */
- if (chan->music_state)
- ast_moh_cleanup(chan);
-
- /* Free translators */
- if (chan->readtrans)
- ast_translator_free_path(chan->readtrans);
- if (chan->writetrans)
- ast_translator_free_path(chan->writetrans);
- if (chan->pbx)
- ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
- free_cid(&chan->cid);
- /* Close pipes if appropriate */
- if ((fd = chan->alertpipe[0]) > -1)
- close(fd);
- if ((fd = chan->alertpipe[1]) > -1)
- close(fd);
- if ((fd = chan->timingfd) > -1)
- close(fd);
- while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
- ast_frfree(f);
-
- /* loop over the variables list, freeing all data and deleting list items */
- /* no need to lock the list, as the channel is already locked */
-
- while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
- ast_var_delete(vardata);
-
- ast_app_group_discard(chan);
-
- /* Destroy the jitterbuffer */
- ast_jb_destroy(chan);
-
- ast_mutex_destroy(&chan->lock);
-
- ast_string_field_free_memory(chan);
- free(chan);
- AST_LIST_UNLOCK(&channels);
-
- ast_device_state_changed_literal(name);
-}
-
-struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid)
-{
- struct ast_datastore *datastore = NULL;
-
- /* Make sure we at least have type so we can identify this */
- if (info == NULL) {
- return NULL;
- }
-
- /* Allocate memory for datastore and clear it */
- datastore = ast_calloc(1, sizeof(*datastore));
- if (datastore == NULL) {
- return NULL;
- }
-
- datastore->info = info;
-
- datastore->uid = ast_strdup(uid);
-
- return datastore;
-}
-
-int ast_channel_datastore_free(struct ast_datastore *datastore)
-{
- int res = 0;
-
- /* Using the destroy function (if present) destroy the data */
- if (datastore->info->destroy != NULL && datastore->data != NULL) {
- datastore->info->destroy(datastore->data);
- datastore->data = NULL;
- }
-
- /* Free allocated UID memory */
- if (datastore->uid != NULL) {
- free(datastore->uid);
- datastore->uid = NULL;
- }
-
- /* Finally free memory used by ourselves */
- free(datastore);
-
- return res;
-}
-
-int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
-{
- struct ast_datastore *datastore = NULL, *datastore2;
-
- AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
- if (datastore->inheritance > 0) {
- datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
- if (datastore2) {
- datastore2->data = datastore->info->duplicate(datastore->data);
- datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
- AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
- }
- }
- }
- return 0;
-}
-
-int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
-{
- int res = 0;
-
- AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
-
- return res;
-}
-
-int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
-{
- struct ast_datastore *datastore2 = NULL;
- int res = -1;
-
- /* Find our position and remove ourselves */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
- if (datastore2 == datastore) {
- AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
- res = 0;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- return res;
-}
-
-struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
-{
- struct ast_datastore *datastore = NULL;
-
- if (info == NULL)
- return NULL;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
- if (datastore->info == info) {
- if (uid != NULL && datastore->uid != NULL) {
- if (!strcasecmp(uid, datastore->uid)) {
- /* Matched by type AND uid */
- break;
- }
- } else {
- /* Matched by type at least */
- break;
- }
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- return datastore;
-}
-
-/*! \brief Softly hangup a channel, don't lock */
-int ast_softhangup_nolock(struct ast_channel *chan, int cause)
-{
- if (option_debug)
- ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
- /* Inform channel driver that we need to be hung up, if it cares */
- chan->_softhangup |= cause;
- ast_queue_frame(chan, &ast_null_frame);
- /* Interrupt any poll call or such */
- if (ast_test_flag(chan, AST_FLAG_BLOCKING))
- pthread_kill(chan->blocker, SIGURG);
- return 0;
-}
-
-/*! \brief Softly hangup a channel, lock */
-int ast_softhangup(struct ast_channel *chan, int cause)
-{
- int res;
- ast_channel_lock(chan);
- res = ast_softhangup_nolock(chan, cause);
- ast_channel_unlock(chan);
- return res;
-}
-
-static void free_translation(struct ast_channel *clone)
-{
- if (clone->writetrans)
- ast_translator_free_path(clone->writetrans);
- if (clone->readtrans)
- ast_translator_free_path(clone->readtrans);
- clone->writetrans = NULL;
- clone->readtrans = NULL;
- clone->rawwriteformat = clone->nativeformats;
- clone->rawreadformat = clone->nativeformats;
-}
-
-/*! \brief Hangup a channel */
-int ast_hangup(struct ast_channel *chan)
-{
- int res = 0;
- struct ast_cdr *cdr = NULL;
-
- /* Don't actually hang up a channel that will masquerade as someone else, or
- if someone is going to masquerade as us */
- ast_channel_lock(chan);
-
- if (chan->audiohooks) {
- ast_audiohook_detach_list(chan->audiohooks);
- chan->audiohooks = NULL;
- }
-
- ast_autoservice_stop(chan);
-
- if (chan->masq) {
- if (ast_do_masquerade(chan))
- ast_log(LOG_WARNING, "Failed to perform masquerade\n");
- }
-
- if (chan->masq) {
- ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
- ast_channel_unlock(chan);
- return 0;
- }
- /* If this channel is one which will be masqueraded into something,
- mark it as a zombie already, so we know to free it later */
- if (chan->masqr) {
- ast_set_flag(chan, AST_FLAG_ZOMBIE);
- ast_channel_unlock(chan);
- return 0;
- }
- free_translation(chan);
- /* Close audio stream */
- if (chan->stream) {
- ast_closestream(chan->stream);
- chan->stream = NULL;
- }
- /* Close video stream */
- if (chan->vstream) {
- ast_closestream(chan->vstream);
- chan->vstream = NULL;
- }
- if (chan->sched) {
- sched_context_destroy(chan->sched);
- chan->sched = NULL;
- }
-
- if (chan->generatordata) /* Clear any tone stuff remaining */
- chan->generator->release(chan, chan->generatordata);
- chan->generatordata = NULL;
- chan->generator = NULL;
- if (chan->cdr) { /* End the CDR if it hasn't already */
- ast_cdr_end(chan->cdr);
- cdr = chan->cdr;
- chan->cdr = NULL;
- }
- if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
- ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
- "is blocked by thread %ld in procedure %s! Expect a failure\n",
- (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
- CRASH;
- }
- if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
- if (chan->tech->hangup)
- res = chan->tech->hangup(chan);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
- }
-
- ast_channel_unlock(chan);
- manager_event(EVENT_FLAG_CALL, "Hangup",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Cause: %d\r\n"
- "Cause-txt: %s\r\n",
- chan->name,
- chan->uniqueid,
- chan->hangupcause,
- ast_cause2str(chan->hangupcause)
- );
- ast_channel_free(chan);
-
- if (cdr)
- ast_cdr_detach(cdr);
-
- return res;
-}
-
-int ast_answer(struct ast_channel *chan)
-{
- int res = 0;
- ast_channel_lock(chan);
- /* You can't answer an outbound call */
- if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
- ast_channel_unlock(chan);
- return 0;
- }
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
- ast_channel_unlock(chan);
- return -1;
- }
- switch(chan->_state) {
- case AST_STATE_RINGING:
- case AST_STATE_RING:
- if (chan->tech->answer)
- res = chan->tech->answer(chan);
- ast_setstate(chan, AST_STATE_UP);
- ast_cdr_answer(chan->cdr);
- break;
- case AST_STATE_UP:
- ast_cdr_answer(chan->cdr);
- break;
- default:
- break;
- }
- chan->visible_indication = 0;
- ast_channel_unlock(chan);
- return res;
-}
-
-void ast_deactivate_generator(struct ast_channel *chan)
-{
- ast_channel_lock(chan);
- if (chan->generatordata) {
- if (chan->generator && chan->generator->release)
- chan->generator->release(chan, chan->generatordata);
- chan->generatordata = NULL;
- chan->generator = NULL;
- chan->fds[AST_GENERATOR_FD] = -1;
- ast_clear_flag(chan, AST_FLAG_WRITE_INT);
- ast_settimeout(chan, 0, NULL, NULL);
- }
- ast_channel_unlock(chan);
-}
-
-static int generator_force(const void *data)
-{
- /* Called if generator doesn't have data */
- void *tmp;
- int res;
- int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
- struct ast_channel *chan = (struct ast_channel *)data;
-
- ast_channel_lock(chan);
- tmp = chan->generatordata;
- chan->generatordata = NULL;
- if (chan->generator)
- generate = chan->generator->generate;
- ast_channel_unlock(chan);
-
- if (!tmp || !generate)
- return 0;
-
- res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
-
- chan->generatordata = tmp;
-
- if (res) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
- ast_deactivate_generator(chan);
- }
-
- return 0;
-}
-
-int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
-{
- int res = 0;
-
- ast_channel_lock(chan);
-
- if (chan->generatordata) {
- if (chan->generator && chan->generator->release)
- chan->generator->release(chan, chan->generatordata);
- chan->generatordata = NULL;
- }
-
- ast_prod(chan);
- if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
- res = -1;
- }
-
- if (!res) {
- ast_settimeout(chan, 160, generator_force, chan);
- chan->generator = gen;
- }
-
- ast_channel_unlock(chan);
-
- return res;
-}
-
-/*! \brief Wait for x amount of time on a file descriptor to have input. */
-int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
-{
- int winner = -1;
- ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
- return winner;
-}
-
-/*! \brief Wait for x amount of time on a file descriptor to have input. */
-struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
- int *exception, int *outfd, int *ms)
-{
- struct timeval start = { 0 , 0 };
- struct pollfd *pfds = NULL;
- int res;
- long rms;
- int x, y, max;
- int sz;
- time_t now = 0;
- long whentohangup = 0, diff;
- struct ast_channel *winner = NULL;
- struct fdmap {
- int chan;
- int fdno;
- } *fdmap = NULL;
-
- if ((sz = n * AST_MAX_FDS + nfds)) {
- pfds = alloca(sizeof(*pfds) * sz);
- fdmap = alloca(sizeof(*fdmap) * sz);
- }
-
- if (outfd)
- *outfd = -99999;
- if (exception)
- *exception = 0;
-
- /* Perform any pending masquerades */
- for (x=0; x < n; x++) {
- ast_channel_lock(c[x]);
- if (c[x]->masq) {
- if (ast_do_masquerade(c[x])) {
- ast_log(LOG_WARNING, "Masquerade failed\n");
- *ms = -1;
- ast_channel_unlock(c[x]);
- return NULL;
- }
- }
- if (c[x]->whentohangup) {
- if (!whentohangup)
- time(&now);
- diff = c[x]->whentohangup - now;
- if (diff < 1) {
- /* Should already be hungup */
- c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
- ast_channel_unlock(c[x]);
- return c[x];
- }
- if (!whentohangup || (diff < whentohangup))
- whentohangup = diff;
- }
- ast_channel_unlock(c[x]);
- }
- /* Wait full interval */
- rms = *ms;
- if (whentohangup) {
- rms = whentohangup * 1000; /* timeout in milliseconds */
- if (*ms >= 0 && *ms < rms) /* original *ms still smaller */
- rms = *ms;
- }
- /*
- * Build the pollfd array, putting the channels' fds first,
- * followed by individual fds. Order is important because
- * individual fd's must have priority over channel fds.
- */
- max = 0;
- for (x=0; x<n; x++) {
- for (y=0; y<AST_MAX_FDS; y++) {
- fdmap[max].fdno = y; /* fd y is linked to this pfds */
- fdmap[max].chan = x; /* channel x is linked to this pfds */
- max += ast_add_fd(&pfds[max], c[x]->fds[y]);
- }
- CHECK_BLOCKING(c[x]);
- }
- /* Add the individual fds */
- for (x=0; x<nfds; x++) {
- fdmap[max].chan = -1;
- max += ast_add_fd(&pfds[max], fds[x]);
- }
-
- if (*ms > 0)
- start = ast_tvnow();
-
- if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
- do {
- int kbrms = rms;
- if (kbrms > 600000)
- kbrms = 600000;
- res = poll(pfds, max, kbrms);
- if (!res)
- rms -= kbrms;
- } while (!res && (rms > 0));
- } else {
- res = poll(pfds, max, rms);
- }
- for (x=0; x<n; x++)
- ast_clear_flag(c[x], AST_FLAG_BLOCKING);
- if (res < 0) { /* Simulate a timeout if we were interrupted */
- if (errno != EINTR)
- *ms = -1;
- return NULL;
- }
- if (whentohangup) { /* if we have a timeout, check who expired */
- time(&now);
- for (x=0; x<n; x++) {
- if (c[x]->whentohangup && now >= c[x]->whentohangup) {
- c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
- if (winner == NULL)
- winner = c[x];
- }
- }
- }
- if (res == 0) { /* no fd ready, reset timeout and done */
- *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
- return winner;
- }
- /*
- * Then check if any channel or fd has a pending event.
- * Remember to check channels first and fds last, as they
- * must have priority on setting 'winner'
- */
- for (x = 0; x < max; x++) {
- res = pfds[x].revents;
- if (res == 0)
- continue;
- if (fdmap[x].chan >= 0) { /* this is a channel */
- winner = c[fdmap[x].chan]; /* override previous winners */
- if (res & POLLPRI)
- ast_set_flag(winner, AST_FLAG_EXCEPTION);
- else
- ast_clear_flag(winner, AST_FLAG_EXCEPTION);
- winner->fdno = fdmap[x].fdno;
- } else { /* this is an fd */
- if (outfd)
- *outfd = pfds[x].fd;
- if (exception)
- *exception = (res & POLLPRI) ? -1 : 0;
- winner = NULL;
- }
- }
- if (*ms > 0) {
- *ms -= ast_tvdiff_ms(ast_tvnow(), start);
- if (*ms < 0)
- *ms = 0;
- }
- return winner;
-}
-
-struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
-{
- return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
-}
-
-int ast_waitfor(struct ast_channel *c, int ms)
-{
- int oldms = ms; /* -1 if no timeout */
-
- ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
- if ((ms < 0) && (oldms < 0))
- ms = 0;
- return ms;
-}
-
-/* XXX never to be called with ms = -1 */
-int ast_waitfordigit(struct ast_channel *c, int ms)
-{
- return ast_waitfordigit_full(c, ms, -1, -1);
-}
-
-int ast_settimeout(struct ast_channel *c, int samples, int (*func)(const void *data), void *data)
-{
- int res = -1;
-#ifdef HAVE_ZAPTEL
- if (c->timingfd > -1) {
- if (!func) {
- samples = 0;
- data = 0;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
- res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
- c->timingfunc = func;
- c->timingdata = data;
- }
-#endif
- return res;
-}
-
-int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
-{
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
- return -1;
-
- /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
- ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
-
- /* Wait for a digit, no more than ms milliseconds total. */
- while (ms) {
- struct ast_channel *rchan;
- int outfd;
-
- errno = 0;
- rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
- if (!rchan && outfd < 0 && ms) {
- if (errno == 0 || errno == EINTR)
- continue;
- ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return -1;
- } else if (outfd > -1) {
- /* The FD we were watching has something waiting */
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return 1;
- } else if (rchan) {
- int res;
- struct ast_frame *f = ast_read(c);
- if (!f)
- return -1;
-
- switch(f->frametype) {
- case AST_FRAME_DTMF_BEGIN:
- break;
- case AST_FRAME_DTMF_END:
- res = f->subclass;
- ast_frfree(f);
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return res;
- case AST_FRAME_CONTROL:
- switch(f->subclass) {
- case AST_CONTROL_HANGUP:
- ast_frfree(f);
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return -1;
- case AST_CONTROL_RINGING:
- case AST_CONTROL_ANSWER:
- case AST_CONTROL_SRCUPDATE:
- /* Unimportant */
- break;
- default:
- ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
- break;
- }
- break;
- case AST_FRAME_VOICE:
- /* Write audio if appropriate */
- if (audiofd > -1)
- write(audiofd, f->data, f->datalen);
- default:
- /* Ignore */
- break;
- }
- ast_frfree(f);
- }
- }
-
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
-
- return 0; /* Time is up */
-}
-
-static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
-{
- if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
- void *tmp = chan->generatordata;
- int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
- int res;
- int samples;
-
- if (chan->timingfunc) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
- ast_settimeout(chan, 0, NULL, NULL);
- }
-
- chan->generatordata = NULL; /* reset, to let writes go through */
-
- if (f->subclass != chan->writeformat) {
- float factor;
- factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass));
- samples = (int) ( ((float) f->samples) * factor );
- } else {
- samples = f->samples;
- }
-
- if (chan->generator->generate) {
- generate = chan->generator->generate;
- }
- /* This unlock is here based on two assumptions that hold true at this point in the
- * code. 1) this function is only called from within __ast_read() and 2) all generators
- * call ast_write() in their generate callback.
- *
- * The reason this is added is so that when ast_write is called, the lock that occurs
- * there will not recursively lock the channel. Doing this will cause intended deadlock
- * avoidance not to work in deeper functions
- */
- ast_channel_unlock(chan);
- res = generate(chan, tmp, f->datalen, samples);
- ast_channel_lock(chan);
- chan->generatordata = tmp;
- if (res) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
- ast_deactivate_generator(chan);
- }
-
- } else if (f->frametype == AST_FRAME_CNG) {
- if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
- ast_settimeout(chan, 160, generator_force, chan);
- }
- }
-}
-
-static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
-{
- struct ast_frame *f = NULL; /* the return value */
- int blah;
- int prestate;
- int count = 0;
-
- /* this function is very long so make sure there is only one return
- * point at the end (there are only two exceptions to this).
- */
- while(ast_channel_trylock(chan)) {
- if(count++ > 10)
- /*cannot goto done since the channel is not locked*/
- return &ast_null_frame;
- usleep(1);
- }
-
- if (chan->masq) {
- if (ast_do_masquerade(chan))
- ast_log(LOG_WARNING, "Failed to perform masquerade\n");
- else
- f = &ast_null_frame;
- goto done;
- }
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
- if (chan->generator)
- ast_deactivate_generator(chan);
- goto done;
- }
- prestate = chan->_state;
-
- if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) &&
- !ast_strlen_zero(chan->dtmfq) &&
- (ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {
- /* We have DTMF that has been deferred. Return it now */
- chan->dtmff.subclass = chan->dtmfq[0];
- /* Drop first digit from the buffer */
- memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
- f = &chan->dtmff;
- if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
- ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
- chan->dtmff.frametype = AST_FRAME_DTMF_END;
- } else {
- ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %d queued on %s\n", f->subclass, AST_DEFAULT_EMULATE_DTMF_DURATION, chan->name);
- chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
- ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = f->subclass;
- chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
- }
- chan->dtmf_tv = ast_tvnow();
- goto done;
- }
-
- /* Read and ignore anything on the alertpipe, but read only
- one sizeof(blah) per frame that we send from it */
- if (chan->alertpipe[0] > -1)
- read(chan->alertpipe[0], &blah, sizeof(blah));
-
-#ifdef HAVE_ZAPTEL
- if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
- int res;
-
- ast_clear_flag(chan, AST_FLAG_EXCEPTION);
- blah = -1;
- /* IF we can't get event, assume it's an expired as-per the old interface */
- res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
- if (res)
- blah = ZT_EVENT_TIMER_EXPIRED;
-
- if (blah == ZT_EVENT_TIMER_PING) {
- if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
- /* Acknowledge PONG unless we need it again */
- if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
- ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
- }
- }
- } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
- ioctl(chan->timingfd, ZT_TIMERACK, &blah);
- if (chan->timingfunc) {
- /* save a copy of func/data before unlocking the channel */
- int (*func)(const void *) = chan->timingfunc;
- void *data = chan->timingdata;
- ast_channel_unlock(chan);
- func(data);
- } else {
- blah = 0;
- ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
- chan->timingdata = NULL;
- ast_channel_unlock(chan);
- }
- /* cannot 'goto done' because the channel is already unlocked */
- return &ast_null_frame;
- } else
- ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
- } else
-#endif
- if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
- /* if the AST_GENERATOR_FD is set, call the generator with args
- * set to -1 so it can do whatever it needs to.
- */
- void *tmp = chan->generatordata;
- chan->generatordata = NULL; /* reset to let ast_write get through */
- chan->generator->generate(chan, tmp, -1, -1);
- chan->generatordata = tmp;
- f = &ast_null_frame;
- goto done;
- }
-
- /* Check for pending read queue */
- if (!AST_LIST_EMPTY(&chan->readq)) {
- f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
- /* Interpret hangup and return NULL */
- /* XXX why not the same for frames from the channel ? */
- if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
- ast_frfree(f);
- f = NULL;
- }
- } else {
- chan->blocker = pthread_self();
- if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
- if (chan->tech->exception)
- f = chan->tech->exception(chan);
- else {
- ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
- f = &ast_null_frame;
- }
- /* Clear the exception flag */
- ast_clear_flag(chan, AST_FLAG_EXCEPTION);
- } else if (chan->tech->read)
- f = chan->tech->read(chan);
- else
- ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
- }
-
- if (f) {
- /* if the channel driver returned more than one frame, stuff the excess
- into the readq for the next ast_read call (note that we can safely assume
- that the readq is empty, because otherwise we would not have called into
- the channel driver and f would be only a single frame)
- */
- if (AST_LIST_NEXT(f, frame_list)) {
- AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
- AST_LIST_NEXT(f, frame_list) = NULL;
- }
-
- switch (f->frametype) {
- case AST_FRAME_CONTROL:
- if (f->subclass == AST_CONTROL_ANSWER) {
- if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
- ast_frfree(f);
- f = &ast_null_frame;
- } else if (prestate == AST_STATE_UP) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
- ast_frfree(f);
- f = &ast_null_frame;
- } else {
- /* Answer the CDR */
- ast_setstate(chan, AST_STATE_UP);
- if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
- to keep from throwing off the basic order of the universe,
- we will try to keep this cdr from getting posted. */
- chan->cdr = ast_cdr_alloc();
- ast_cdr_init(chan->cdr, chan);
- ast_cdr_start(chan->cdr);
- }
-
- ast_cdr_answer(chan->cdr);
- }
- }
- break;
- case AST_FRAME_DTMF_END:
- ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
- /* Queue it up if DTMF is deffered, or if DTMF emulation is forced.
- * However, only let emulation be forced if the other end cares about BEGIN frames */
- if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
- (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
- if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
- ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
- chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
- } else
- ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
- ast_frfree(f);
- f = &ast_null_frame;
- } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
- if (!ast_tvzero(chan->dtmf_tv) &&
- ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
- /* If it hasn't been long enough, defer this digit */
- if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
- ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
- chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
- } else
- ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
- ast_frfree(f);
- f = &ast_null_frame;
- } else {
- /* There was no begin, turn this into a begin and send the end later */
- f->frametype = AST_FRAME_DTMF_BEGIN;
- ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = f->subclass;
- chan->dtmf_tv = ast_tvnow();
- if (f->len) {
- if (f->len > AST_MIN_DTMF_DURATION)
- chan->emulate_dtmf_duration = f->len;
- else
- chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
- } else
- chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
- ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
- }
- if (chan->audiohooks) {
- struct ast_frame *old_frame = f;
- f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
- if (old_frame != f)
- ast_frfree(old_frame);
- }
- } else {
- struct timeval now = ast_tvnow();
- if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
- ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
- ast_clear_flag(chan, AST_FLAG_IN_DTMF);
- if (!f->len)
- f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
- } else if (!f->len) {
- ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
- f->len = AST_MIN_DTMF_DURATION;
- }
- if (f->len < AST_MIN_DTMF_DURATION) {
- ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
- ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = f->subclass;
- chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
- ast_frfree(f);
- f = &ast_null_frame;
- } else {
- ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
- chan->dtmf_tv = now;
- }
- if (chan->audiohooks) {
- struct ast_frame *old_frame = f;
- f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
- if (old_frame != f)
- ast_frfree(old_frame);
- }
- }
- break;
- case AST_FRAME_DTMF_BEGIN:
- ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
- if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
- (!ast_tvzero(chan->dtmf_tv) &&
- ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
- ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
- ast_frfree(f);
- f = &ast_null_frame;
- } else {
- ast_set_flag(chan, AST_FLAG_IN_DTMF);
- chan->dtmf_tv = ast_tvnow();
- ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
- }
- break;
- case AST_FRAME_NULL:
- /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
- * is reached , because we want to make sure we pass at least one
- * voice frame through before starting the next digit, to ensure a gap
- * between DTMF digits. */
- if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
- struct timeval now = ast_tvnow();
- if (!chan->emulate_dtmf_duration) {
- ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = 0;
- } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
- chan->emulate_dtmf_duration = 0;
- ast_frfree(f);
- f = &chan->dtmff;
- f->frametype = AST_FRAME_DTMF_END;
- f->subclass = chan->emulate_dtmf_digit;
- f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
- chan->dtmf_tv = now;
- ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = 0;
- ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
- }
- }
- break;
- case AST_FRAME_VOICE:
- /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
- * is reached , because we want to make sure we pass at least one
- * voice frame through before starting the next digit, to ensure a gap
- * between DTMF digits. */
- if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
- ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
- chan->emulate_dtmf_digit = 0;
- }
-
- if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
- if (dropaudio)
- ast_read_generator_actions(chan, f);
- ast_frfree(f);
- f = &ast_null_frame;
- }
-
- if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
- struct timeval now = ast_tvnow();
- if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
- chan->emulate_dtmf_duration = 0;
- ast_frfree(f);
- f = &chan->dtmff;
- f->frametype = AST_FRAME_DTMF_END;
- f->subclass = chan->emulate_dtmf_digit;
- f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
- chan->dtmf_tv = now;
- if (chan->audiohooks) {
- struct ast_frame *old_frame = f;
- f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
- if (old_frame != f)
- ast_frfree(old_frame);
- }
- ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
- } else {
- /* Drop voice frames while we're still in the middle of the digit */
- ast_frfree(f);
- f = &ast_null_frame;
- }
- } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
- /* This frame can't be from the current native formats -- drop it on the
- floor */
- ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
- chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
- ast_frfree(f);
- f = &ast_null_frame;
- } else if ((f->frametype == AST_FRAME_VOICE)) {
- if (chan->audiohooks) {
- struct ast_frame *old_frame = f;
- f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
- if (old_frame != f)
- ast_frfree(old_frame);
- }
- if (chan->monitor && chan->monitor->read_stream ) {
- /* XXX what does this do ? */
-#ifndef MONITOR_CONSTANT_DELAY
- int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
- if (jump >= 0) {
- jump = chan->outsmpl - chan->insmpl;
- if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
- ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
- chan->insmpl += jump + f->samples;
- } else
- chan->insmpl+= f->samples;
-#else
- int jump = chan->outsmpl - chan->insmpl;
- if (jump - MONITOR_DELAY >= 0) {
- if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
- ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
- chan->insmpl += jump;
- } else
- chan->insmpl += f->samples;
-#endif
- if (chan->monitor->state == AST_MONITOR_RUNNING) {
- if (ast_writestream(chan->monitor->read_stream, f) < 0)
- ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
- }
- }
-
- if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
- f = &ast_null_frame;
-
- /* Run generator sitting on the line if timing device not available
- * and synchronous generation of outgoing frames is necessary */
- ast_read_generator_actions(chan, f);
- }
- default:
- /* Just pass it on! */
- break;
- }
- } else {
- /* Make sure we always return NULL in the future */
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- if (chan->generator)
- ast_deactivate_generator(chan);
- /* End the CDR if appropriate */
- if (chan->cdr)
- ast_cdr_end(chan->cdr);
- }
-
- /* High bit prints debugging */
- if (chan->fin & DEBUGCHAN_FLAG)
- ast_frame_dump(chan->name, f, "<<");
- chan->fin = FRAMECOUNT_INC(chan->fin);
-
-done:
- ast_channel_unlock(chan);
- return f;
-}
-
-int ast_internal_timing_enabled(struct ast_channel *chan)
-{
- int ret = ast_opt_internal_timing && chan->timingfd > -1;
- if (option_debug > 4)
- ast_log(LOG_DEBUG, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd);
- return ret;
-}
-
-struct ast_frame *ast_read(struct ast_channel *chan)
-{
- return __ast_read(chan, 0);
-}
-
-struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
-{
- return __ast_read(chan, 1);
-}
-
-int ast_indicate(struct ast_channel *chan, int condition)
-{
- return ast_indicate_data(chan, condition, NULL, 0);
-}
-
-int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
-{
- int res = -1;
-
- ast_channel_lock(chan);
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
- ast_channel_unlock(chan);
- return -1;
- }
- if (chan->tech->indicate)
- res = chan->tech->indicate(chan, condition, data, datalen);
- ast_channel_unlock(chan);
- if (!chan->tech->indicate || res) {
- /*
- * Device does not support (that) indication, lets fake
- * it by doing our own tone generation. (PM2002)
- */
- if (condition < 0)
- ast_playtones_stop(chan);
- else {
- const struct tone_zone_sound *ts = NULL;
- switch (condition) {
- case AST_CONTROL_RINGING:
- ts = ast_get_indication_tone(chan->zone, "ring");
- break;
- case AST_CONTROL_BUSY:
- ts = ast_get_indication_tone(chan->zone, "busy");
- break;
- case AST_CONTROL_CONGESTION:
- ts = ast_get_indication_tone(chan->zone, "congestion");
- break;
- }
- if (ts && ts->data[0]) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
- ast_playtones_start(chan,0,ts->data, 1);
- res = 0;
- chan->visible_indication = condition;
- } else if (condition == AST_CONTROL_PROGRESS) {
- /* ast_playtones_stop(chan); */
- } else if (condition == AST_CONTROL_PROCEEDING) {
- /* Do nothing, really */
- } else if (condition == AST_CONTROL_HOLD) {
- /* Do nothing.... */
- } else if (condition == AST_CONTROL_UNHOLD) {
- /* Do nothing.... */
- } else if (condition == AST_CONTROL_VIDUPDATE) {
- /* Do nothing.... */
- } else if (condition == AST_CONTROL_SRCUPDATE) {
- /* Do nothing... */
- } else {
- /* not handled */
- ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
- res = -1;
- }
- }
- } else
- chan->visible_indication = condition;
-
- return res;
-}
-
-int ast_recvchar(struct ast_channel *chan, int timeout)
-{
- int c;
- char *buf = ast_recvtext(chan, timeout);
- if (buf == NULL)
- return -1; /* error or timeout */
- c = *(unsigned char *)buf;
- free(buf);
- return c;
-}
-
-char *ast_recvtext(struct ast_channel *chan, int timeout)
-{
- int res, done = 0;
- char *buf = NULL;
-
- while (!done) {
- struct ast_frame *f;
- if (ast_check_hangup(chan))
- break;
- res = ast_waitfor(chan, timeout);
- if (res <= 0) /* timeout or error */
- break;
- timeout = res; /* update timeout */
- f = ast_read(chan);
- if (f == NULL)
- break; /* no frame */
- if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
- done = 1; /* force a break */
- else if (f->frametype == AST_FRAME_TEXT) { /* what we want */
- buf = ast_strndup((char *) f->data, f->datalen); /* dup and break */
- done = 1;
- }
- ast_frfree(f);
- }
- return buf;
-}
-
-int ast_sendtext(struct ast_channel *chan, const char *text)
-{
- int res = 0;
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
- return -1;
- CHECK_BLOCKING(chan);
- if (chan->tech->send_text)
- res = chan->tech->send_text(chan, text);
- ast_clear_flag(chan, AST_FLAG_BLOCKING);
- return res;
-}
-
-int ast_senddigit_begin(struct ast_channel *chan, char digit)
-{
- /* Device does not support DTMF tones, lets fake
- * it by doing our own generation. */
- static const char* dtmf_tones[] = {
- "941+1336", /* 0 */
- "697+1209", /* 1 */
- "697+1336", /* 2 */
- "697+1477", /* 3 */
- "770+1209", /* 4 */
- "770+1336", /* 5 */
- "770+1477", /* 6 */
- "852+1209", /* 7 */
- "852+1336", /* 8 */
- "852+1477", /* 9 */
- "697+1633", /* A */
- "770+1633", /* B */
- "852+1633", /* C */
- "941+1633", /* D */
- "941+1209", /* * */
- "941+1477" /* # */
- };
-
- if (!chan->tech->send_digit_begin)
- return 0;
-
- if (!chan->tech->send_digit_begin(chan, digit))
- return 0;
-
- if (digit >= '0' && digit <='9')
- ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
- else if (digit >= 'A' && digit <= 'D')
- ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
- else if (digit == '*')
- ast_playtones_start(chan, 0, dtmf_tones[14], 0);
- else if (digit == '#')
- ast_playtones_start(chan, 0, dtmf_tones[15], 0);
- else {
- /* not handled */
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
- }
-
- return 0;
-}
-
-int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
-{
- int res = -1;
-
- if (chan->tech->send_digit_end)
- res = chan->tech->send_digit_end(chan, digit, duration);
-
- if (res && chan->generator)
- ast_playtones_stop(chan);
-
- return 0;
-}
-
-int ast_senddigit(struct ast_channel *chan, char digit)
-{
- if (chan->tech->send_digit_begin) {
- ast_senddigit_begin(chan, digit);
- ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
- }
-
- return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
-}
-
-int ast_prod(struct ast_channel *chan)
-{
- struct ast_frame a = { AST_FRAME_VOICE };
- char nothing[128];
-
- /* Send an empty audio frame to get things moving */
- if (chan->_state != AST_STATE_UP) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
- a.subclass = chan->rawwriteformat;
- a.data = nothing + AST_FRIENDLY_OFFSET;
- a.src = "ast_prod";
- if (ast_write(chan, &a))
- ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
- }
- return 0;
-}
-
-int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
-{
- int res;
- if (!chan->tech->write_video)
- return 0;
- res = ast_write(chan, fr);
- if (!res)
- res = 1;
- return res;
-}
-
-int ast_write(struct ast_channel *chan, struct ast_frame *fr)
-{
- int res = -1;
- int count = 0;
- struct ast_frame *f = NULL, *f2 = NULL;
-
- /*Deadlock avoidance*/
- while(ast_channel_trylock(chan)) {
- /*cannot goto done since the channel is not locked*/
- if(count++ > 10) {
- if(option_debug)
- ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
- return 0;
- }
- usleep(1);
- }
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
- goto done;
-
- /* Handle any pending masquerades */
- if (chan->masq && ast_do_masquerade(chan)) {
- ast_log(LOG_WARNING, "Failed to perform masquerade\n");
- goto done;
- }
- if (chan->masqr) {
- res = 0; /* XXX explain, why 0 ? */
- goto done;
- }
- if (chan->generatordata) {
- if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
- ast_deactivate_generator(chan);
- else {
- if (fr->frametype == AST_FRAME_DTMF_END) {
- /* There is a generator running while we're in the middle of a digit.
- * It's probably inband DTMF, so go ahead and pass it so it can
- * stop the generator */
- ast_clear_flag(chan, AST_FLAG_BLOCKING);
- ast_channel_unlock(chan);
- res = ast_senddigit_end(chan, fr->subclass, fr->len);
- ast_channel_lock(chan);
- CHECK_BLOCKING(chan);
- } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
- /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
- res = (chan->tech->indicate == NULL) ? 0 :
- chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
- }
- res = 0; /* XXX explain, why 0 ? */
- goto done;
- }
- }
- /* High bit prints debugging */
- if (chan->fout & DEBUGCHAN_FLAG)
- ast_frame_dump(chan->name, fr, ">>");
- CHECK_BLOCKING(chan);
- switch(fr->frametype) {
- case AST_FRAME_CONTROL:
- res = (chan->tech->indicate == NULL) ? 0 :
- chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
- break;
- case AST_FRAME_DTMF_BEGIN:
- if (chan->audiohooks) {
- struct ast_frame *old_frame = fr;
- fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
- if (old_frame != fr)
- f = fr;
- }
- ast_clear_flag(chan, AST_FLAG_BLOCKING);
- ast_channel_unlock(chan);
- res = ast_senddigit_begin(chan, fr->subclass);
- ast_channel_lock(chan);
- CHECK_BLOCKING(chan);
- break;
- case AST_FRAME_DTMF_END:
- if (chan->audiohooks) {
- struct ast_frame *old_frame = fr;
- fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
- if (old_frame != fr)
- f = fr;
- }
- ast_clear_flag(chan, AST_FLAG_BLOCKING);
- ast_channel_unlock(chan);
- res = ast_senddigit_end(chan, fr->subclass, fr->len);
- ast_channel_lock(chan);
- CHECK_BLOCKING(chan);
- break;
- case AST_FRAME_TEXT:
- res = (chan->tech->send_text == NULL) ? 0 :
- chan->tech->send_text(chan, (char *) fr->data);
- break;
- case AST_FRAME_HTML:
- res = (chan->tech->send_html == NULL) ? 0 :
- chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
- break;
- case AST_FRAME_VIDEO:
- /* XXX Handle translation of video codecs one day XXX */
- res = (chan->tech->write_video == NULL) ? 0 :
- chan->tech->write_video(chan, fr);
- break;
- case AST_FRAME_MODEM:
- res = (chan->tech->write == NULL) ? 0 :
- chan->tech->write(chan, fr);
- break;
- case AST_FRAME_VOICE:
- if (chan->tech->write == NULL)
- break; /*! \todo XXX should return 0 maybe ? */
-
- if (chan->audiohooks) {
- struct ast_frame *old_frame = fr;
- fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
- if (old_frame != fr)
- f2 = fr;
- }
-
- /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
- if (fr->subclass == chan->rawwriteformat)
- f = fr;
- else
- f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
-
- /* If we have no frame of audio, then we have to bail out */
- if (!f) {
- res = 0;
- break;
- }
-
- /* If Monitor is running on this channel, then we have to write frames out there too */
- if (chan->monitor && chan->monitor->write_stream) {
- /* XXX must explain this code */
-#ifndef MONITOR_CONSTANT_DELAY
- int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
- if (jump >= 0) {
- jump = chan->insmpl - chan->outsmpl;
- if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
- ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
- chan->outsmpl += jump + f->samples;
- } else
- chan->outsmpl += f->samples;
-#else
- int jump = chan->insmpl - chan->outsmpl;
- if (jump - MONITOR_DELAY >= 0) {
- if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
- ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
- chan->outsmpl += jump;
- } else
- chan->outsmpl += f->samples;
-#endif
- if (chan->monitor->state == AST_MONITOR_RUNNING) {
- if (ast_writestream(chan->monitor->write_stream, f) < 0)
- ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
- }
- }
-
- if (f)
- res = chan->tech->write(chan,f);
- else
- res = 0;
- break;
- case AST_FRAME_NULL:
- case AST_FRAME_IAX:
- /* Ignore these */
- res = 0;
- break;
- default:
- /* At this point, fr is the incoming frame and f is NULL. Channels do
- * not expect to get NULL as a frame pointer and will segfault. Hence,
- * we output the original frame passed in. */
- res = chan->tech->write(chan, fr);
- break;
- }
-
- if (f && f != fr)
- ast_frfree(f);
- if (f2)
- ast_frfree(f2);
- ast_clear_flag(chan, AST_FLAG_BLOCKING);
- /* Consider a write failure to force a soft hangup */
- if (res < 0)
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- else {
- chan->fout = FRAMECOUNT_INC(chan->fout);
- }
-done:
- ast_channel_unlock(chan);
- return res;
-}
-
-static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,
- struct ast_trans_pvt **trans, const int direction)
-{
- int native;
- int res;
-
- /* Make sure we only consider audio */
- fmt &= AST_FORMAT_AUDIO_MASK;
-
- native = chan->nativeformats;
- /* Find a translation path from the native format to one of the desired formats */
- if (!direction)
- /* reading */
- res = ast_translator_best_choice(&fmt, &native);
- else
- /* writing */
- res = ast_translator_best_choice(&native, &fmt);
-
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
- ast_getformatname(native), ast_getformatname(fmt));
- return -1;
- }
-
- /* Now we have a good choice for both. */
- ast_channel_lock(chan);
-
- if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
- /* the channel is already in these formats, so nothing to do */
- ast_channel_unlock(chan);
- return 0;
- }
-
- *rawformat = native;
- /* User perspective is fmt */
- *format = fmt;
- /* Free any read translation we have right now */
- if (*trans)
- ast_translator_free_path(*trans);
- /* Build a translation path from the raw format to the desired format */
- if (!direction)
- /* reading */
- *trans = ast_translator_build_path(*format, *rawformat);
- else
- /* writing */
- *trans = ast_translator_build_path(*rawformat, *format);
- ast_channel_unlock(chan);
- if (option_debug)
- ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
- direction ? "write" : "read", ast_getformatname(fmt));
- return 0;
-}
-
-int ast_set_read_format(struct ast_channel *chan, int fmt)
-{
- return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
- &chan->readtrans, 0);
-}
-
-int ast_set_write_format(struct ast_channel *chan, int fmt)
-{
- return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
- &chan->writetrans, 1);
-}
-
-char *ast_channel_reason2str(int reason)
-{
- switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
- {
- case 0:
- return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
- case AST_CONTROL_HANGUP:
- return "Hangup";
- case AST_CONTROL_RING:
- return "Local Ring";
- case AST_CONTROL_RINGING:
- return "Remote end Ringing";
- case AST_CONTROL_ANSWER:
- return "Remote end has Answered";
- case AST_CONTROL_BUSY:
- return "Remote end is Busy";
- case AST_CONTROL_CONGESTION:
- return "Congestion (circuits busy)";
- default:
- return "Unknown Reason!!";
- }
-}
-
-struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
-{
- int dummy_outstate;
- int cause = 0;
- struct ast_channel *chan;
- int res = 0;
- int last_subclass = 0;
-
- if (outstate)
- *outstate = 0;
- else
- outstate = &dummy_outstate; /* make outstate always a valid pointer */
-
- chan = ast_request(type, format, data, &cause);
- if (!chan) {
- ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
- /* compute error and return */
- if (cause == AST_CAUSE_BUSY)
- *outstate = AST_CONTROL_BUSY;
- else if (cause == AST_CAUSE_CONGESTION)
- *outstate = AST_CONTROL_CONGESTION;
- return NULL;
- }
-
- if (oh) {
- if (oh->vars)
- ast_set_variables(chan, oh->vars);
- /* XXX why is this necessary, for the parent_channel perhaps ? */
- if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
- ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
- if (oh->parent_channel)
- ast_channel_inherit_variables(oh->parent_channel, chan);
- if (oh->account)
- ast_cdr_setaccount(chan, oh->account);
- }
- ast_set_callerid(chan, cid_num, cid_name, cid_num);
-
-
-
- if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
- to keep from throwing off the basic order of the universe,
- we will try to keep this cdr from getting posted. */
- chan->cdr = ast_cdr_alloc();
- ast_cdr_init(chan->cdr, chan);
- ast_cdr_start(chan->cdr);
- }
- if (ast_call(chan, data, 0)) { /* ast_call failed... */
- ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
- } else {
- res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
- while (timeout && chan->_state != AST_STATE_UP) {
- struct ast_frame *f;
- res = ast_waitfor(chan, timeout);
- if (res <= 0) /* error, timeout, or done */
- break;
- if (timeout > -1)
- timeout = res;
- f = ast_read(chan);
- if (!f) {
- *outstate = AST_CONTROL_HANGUP;
- res = 0;
- break;
- }
- if (f->frametype == AST_FRAME_CONTROL) {
- switch (f->subclass) {
- case AST_CONTROL_RINGING: /* record but keep going */
- *outstate = f->subclass;
- break;
-
- case AST_CONTROL_BUSY:
- case AST_CONTROL_CONGESTION:
- case AST_CONTROL_ANSWER:
- *outstate = f->subclass;
- timeout = 0; /* trick to force exit from the while() */
- break;
-
- /* Ignore these */
- case AST_CONTROL_PROGRESS:
- case AST_CONTROL_PROCEEDING:
- case AST_CONTROL_HOLD:
- case AST_CONTROL_UNHOLD:
- case AST_CONTROL_VIDUPDATE:
- case AST_CONTROL_SRCUPDATE:
- case -1: /* Ignore -- just stopping indications */
- break;
-
- default:
- ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
- }
- last_subclass = f->subclass;
- }
- ast_frfree(f);
- }
- }
-
- /* Final fixups */
- if (oh) {
- if (!ast_strlen_zero(oh->context))
- ast_copy_string(chan->context, oh->context, sizeof(chan->context));
- if (!ast_strlen_zero(oh->exten))
- ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
- if (oh->priority)
- chan->priority = oh->priority;
- }
- if (chan->_state == AST_STATE_UP)
- *outstate = AST_CONTROL_ANSWER;
-
- if (res <= 0) {
- if ( AST_CONTROL_RINGING == last_subclass )
- chan->hangupcause = AST_CAUSE_NO_ANSWER;
- if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
- ast_cdr_init(chan->cdr, chan);
- if (chan->cdr) {
- char tmp[256];
- snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
- ast_cdr_setapp(chan->cdr,"Dial",tmp);
- ast_cdr_update(chan);
- ast_cdr_start(chan->cdr);
- ast_cdr_end(chan->cdr);
- /* If the cause wasn't handled properly */
- if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
- ast_cdr_failed(chan->cdr);
- }
- ast_hangup(chan);
- chan = NULL;
- }
- return chan;
-}
-
-struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
-{
- return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
-}
-
-struct ast_channel *ast_request(const char *type, int format, void *data, int *cause)
-{
- struct chanlist *chan;
- struct ast_channel *c;
- int capabilities;
- int fmt;
- int res;
- int foo;
- int videoformat = format & AST_FORMAT_VIDEO_MASK;
-
- if (!cause)
- cause = &foo;
- *cause = AST_CAUSE_NOTDEFINED;
-
- if (AST_LIST_LOCK(&channels)) {
- ast_log(LOG_WARNING, "Unable to lock channel list\n");
- return NULL;
- }
-
- AST_LIST_TRAVERSE(&backends, chan, list) {
- if (strcasecmp(type, chan->tech->type))
- continue;
-
- capabilities = chan->tech->capabilities;
- fmt = format & AST_FORMAT_AUDIO_MASK;
- res = ast_translator_best_choice(&fmt, &capabilities);
- if (res < 0) {
- ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
- *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
- AST_LIST_UNLOCK(&channels);
- return NULL;
- }
- AST_LIST_UNLOCK(&channels);
- if (!chan->tech->requester)
- return NULL;
-
- if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
- return NULL;
-
- /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
- return c;
- }
-
- ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
- *cause = AST_CAUSE_NOSUCHDRIVER;
- AST_LIST_UNLOCK(&channels);
-
- return NULL;
-}
-
-int ast_call(struct ast_channel *chan, char *addr, int timeout)
-{
- /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
- If the remote end does not answer within the timeout, then do NOT hang up, but
- return anyway. */
- int res = -1;
- /* Stop if we're a zombie or need a soft hangup */
- ast_channel_lock(chan);
- if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
- if (chan->tech->call)
- res = chan->tech->call(chan, addr, timeout);
- ast_set_flag(chan, AST_FLAG_OUTGOING);
- }
- ast_channel_unlock(chan);
- return res;
-}
-
-/*!
- \brief Transfer a call to dest, if the channel supports transfer
-
- Called by:
- \arg app_transfer
- \arg the manager interface
-*/
-int ast_transfer(struct ast_channel *chan, char *dest)
-{
- int res = -1;
-
- /* Stop if we're a zombie or need a soft hangup */
- ast_channel_lock(chan);
- if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
- if (chan->tech->transfer) {
- res = chan->tech->transfer(chan, dest);
- if (!res)
- res = 1;
- } else
- res = 0;
- }
- ast_channel_unlock(chan);
- return res;
-}
-
-int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
-{
- return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
-}
-
-int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
-{
- int pos = 0; /* index in the buffer where we accumulate digits */
- int to = ftimeout;
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
- return -1;
- if (!len)
- return -1;
- for (;;) {
- int d;
- if (c->stream) {
- d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
- ast_stopstream(c);
- usleep(1000);
- if (!d)
- d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
- } else {
- d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
- }
- if (d < 0)
- return -1;
- if (d == 0) {
- s[pos]='\0';
- return 1;
- }
- if (d == 1) {
- s[pos]='\0';
- return 2;
- }
- if (!strchr(enders, d))
- s[pos++] = d;
- if (strchr(enders, d) || (pos >= len)) {
- s[pos]='\0';
- return 0;
- }
- to = timeout;
- }
- /* Never reached */
- return 0;
-}
-
-int ast_channel_supports_html(struct ast_channel *chan)
-{
- return (chan->tech->send_html) ? 1 : 0;
-}
-
-int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
-{
- if (chan->tech->send_html)
- return chan->tech->send_html(chan, subclass, data, datalen);
- return -1;
-}
-
-int ast_channel_sendurl(struct ast_channel *chan, const char *url)
-{
- return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
-}
-
-int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
-{
- int src;
- int dst;
-
- if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
- /* Already compatible! Moving on ... */
- return 0;
- }
-
- /* Set up translation from the chan to the peer */
- src = chan->nativeformats;
- dst = peer->nativeformats;
- if (ast_translator_best_choice(&dst, &src) < 0) {
- ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
- return -1;
- }
-
- /* if the best path is not 'pass through', then
- transcoding is needed; if desired, force transcode path
- to use SLINEAR between channels, but only if there is
- no direct conversion available */
- if ((src != dst) && ast_opt_transcode_via_slin &&
- (ast_translate_path_steps(dst, src) != 1))
- dst = AST_FORMAT_SLINEAR;
- if (ast_set_read_format(chan, dst) < 0) {
- ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
- return -1;
- }
- if (ast_set_write_format(peer, dst) < 0) {
- ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
- return -1;
- }
-
- /* Set up translation from the peer to the chan */
- src = peer->nativeformats;
- dst = chan->nativeformats;
- if (ast_translator_best_choice(&dst, &src) < 0) {
- ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
- return -1;
- }
-
- /* if the best path is not 'pass through', then
- transcoding is needed; if desired, force transcode path
- to use SLINEAR between channels, but only if there is
- no direct conversion available */
- if ((src != dst) && ast_opt_transcode_via_slin &&
- (ast_translate_path_steps(dst, src) != 1))
- dst = AST_FORMAT_SLINEAR;
- if (ast_set_read_format(peer, dst) < 0) {
- ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
- return -1;
- }
- if (ast_set_write_format(chan, dst) < 0) {
- ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
- return -1;
- }
- return 0;
-}
-
-int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
-{
- int res = -1;
- struct ast_channel *final_orig, *final_clone, *base;
-
-retrymasq:
- final_orig = original;
- final_clone = clone;
-
- ast_channel_lock(original);
- while (ast_channel_trylock(clone)) {
- ast_channel_unlock(original);
- usleep(1);
- ast_channel_lock(original);
- }
-
- /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
- and if so, we don't really want to masquerade it, but its proxy */
- if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
- final_orig = original->_bridge;
-
- if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
- final_clone = clone->_bridge;
-
- if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
- final_clone = base;
- }
-
- if ((final_orig != original) || (final_clone != clone)) {
- /* Lots and lots of deadlock avoidance. The main one we're competing with
- * is ast_write(), which locks channels recursively, when working with a
- * proxy channel. */
- if (ast_channel_trylock(final_orig)) {
- ast_channel_unlock(clone);
- ast_channel_unlock(original);
- goto retrymasq;
- }
- if (ast_channel_trylock(final_clone)) {
- ast_channel_unlock(final_orig);
- ast_channel_unlock(clone);
- ast_channel_unlock(original);
- goto retrymasq;
- }
- ast_channel_unlock(clone);
- ast_channel_unlock(original);
- original = final_orig;
- clone = final_clone;
- }
-
- if (original == clone) {
- ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
- ast_channel_unlock(clone);
- ast_channel_unlock(original);
- return -1;
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
- clone->name, original->name);
- if (original->masq) {
- ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
- original->masq->name, original->name);
- } else if (clone->masqr) {
- ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
- clone->name, clone->masqr->name);
- } else {
- original->masq = clone;
- clone->masqr = original;
- ast_queue_frame(original, &ast_null_frame);
- ast_queue_frame(clone, &ast_null_frame);
- if (option_debug)
- ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
- res = 0;
- }
-
- ast_channel_unlock(clone);
- ast_channel_unlock(original);
-
- return res;
-}
-
-void ast_change_name(struct ast_channel *chan, char *newname)
-{
- manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
- ast_string_field_set(chan, name, newname);
-}
-
-void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
-{
- struct ast_var_t *current, *newvar;
- const char *varname;
-
- AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
- int vartype = 0;
-
- varname = ast_var_full_name(current);
- if (!varname)
- continue;
-
- if (varname[0] == '_') {
- vartype = 1;
- if (varname[1] == '_')
- vartype = 2;
- }
-
- switch (vartype) {
- case 1:
- newvar = ast_var_assign(&varname[1], ast_var_value(current));
- if (newvar) {
- AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
- if (option_debug)
- ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
- }
- break;
- case 2:
- newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
- if (newvar) {
- AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
- if (option_debug)
- ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
- }
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
- break;
- }
- }
-}
-
-/*!
- \brief Clone channel variables from 'clone' channel into 'original' channel
-
- All variables except those related to app_groupcount are cloned.
- Variables are actually _removed_ from 'clone' channel, presumably
- because it will subsequently be destroyed.
-
- \note Assumes locks will be in place on both channels when called.
-*/
-static void clone_variables(struct ast_channel *original, struct ast_channel *clone)
-{
- struct ast_var_t *current, *newvar;
- /* Append variables from clone channel into original channel */
- /* XXX Is this always correct? We have to in order to keep MACROS working XXX */
- if (AST_LIST_FIRST(&clone->varshead))
- AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
-
- /* then, dup the varshead list into the clone */
-
- AST_LIST_TRAVERSE(&original->varshead, current, entries) {
- newvar = ast_var_assign(current->name, current->value);
- if (newvar)
- AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
- }
-}
-
-/*!
- \brief Masquerade a channel
-
- \note Assumes channel will be locked when called
-*/
-int ast_do_masquerade(struct ast_channel *original)
-{
- int x,i;
- int res=0;
- int origstate;
- struct ast_frame *cur;
- const struct ast_channel_tech *t;
- void *t_pvt;
- struct ast_callerid tmpcid;
- struct ast_channel *clone = original->masq;
- struct ast_cdr *cdr;
- int rformat = original->readformat;
- int wformat = original->writeformat;
- char newn[100];
- char orig[100];
- char masqn[100];
- char zombn[100];
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
- clone->name, clone->_state, original->name, original->_state);
-
- /* XXX This is a seriously wacked out operation. We're essentially putting the guts of
- the clone channel into the original channel. Start by killing off the original
- channel's backend. I'm not sure we're going to keep this function, because
- while the features are nice, the cost is very high in terms of pure nastiness. XXX */
-
- /* We need the clone's lock, too */
- ast_channel_lock(clone);
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
-
- /* Having remembered the original read/write formats, we turn off any translation on either
- one */
- free_translation(clone);
- free_translation(original);
-
-
- /* Unlink the masquerade */
- original->masq = NULL;
- clone->masqr = NULL;
-
- /* Save the original name */
- ast_copy_string(orig, original->name, sizeof(orig));
- /* Save the new name */
- ast_copy_string(newn, clone->name, sizeof(newn));
- /* Create the masq name */
- snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
-
- /* Copy the name from the clone channel */
- ast_string_field_set(original, name, newn);
-
- /* Mangle the name of the clone channel */
- ast_string_field_set(clone, name, masqn);
-
- /* Notify any managers of the change, first the masq then the other */
- manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
- manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
-
- /* Swap the technologies */
- t = original->tech;
- original->tech = clone->tech;
- clone->tech = t;
-
- /* Swap the cdrs */
- cdr = original->cdr;
- original->cdr = clone->cdr;
- clone->cdr = cdr;
-
- t_pvt = original->tech_pvt;
- original->tech_pvt = clone->tech_pvt;
- clone->tech_pvt = t_pvt;
-
- /* Swap the alertpipes */
- for (i = 0; i < 2; i++) {
- x = original->alertpipe[i];
- original->alertpipe[i] = clone->alertpipe[i];
- clone->alertpipe[i] = x;
- }
-
- /*
- * Swap the readq's. The end result should be this:
- *
- * 1) All frames should be on the new (original) channel.
- * 2) Any frames that were already on the new channel before this
- * masquerade need to be at the end of the readq, after all of the
- * frames on the old (clone) channel.
- * 3) The alertpipe needs to get poked for every frame that was already
- * on the new channel, since we are now using the alert pipe from the
- * old (clone) channel.
- */
- {
- AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
- AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
-
- AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
- AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
-
- while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
- AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
- if (original->alertpipe[1] > -1) {
- int poke = 0;
- write(original->alertpipe[1], &poke, sizeof(poke));
- }
- }
- }
-
- /* Swap the raw formats */
- x = original->rawreadformat;
- original->rawreadformat = clone->rawreadformat;
- clone->rawreadformat = x;
- x = original->rawwriteformat;
- original->rawwriteformat = clone->rawwriteformat;
- clone->rawwriteformat = x;
-
- clone->_softhangup = AST_SOFTHANGUP_DEV;
-
- /* And of course, so does our current state. Note we need not
- call ast_setstate since the event manager doesn't really consider
- these separate. We do this early so that the clone has the proper
- state of the original channel. */
- origstate = original->_state;
- original->_state = clone->_state;
- clone->_state = origstate;
-
- if (clone->tech->fixup){
- res = clone->tech->fixup(original, clone);
- if (res)
- ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
- }
-
- /* Start by disconnecting the original's physical side */
- if (clone->tech->hangup)
- res = clone->tech->hangup(clone);
- if (res) {
- ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
- ast_channel_unlock(clone);
- return -1;
- }
-
- snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
- /* Mangle the name of the clone channel */
- ast_string_field_set(clone, name, zombn);
- manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
-
- /* Update the type. */
- t_pvt = original->monitor;
- original->monitor = clone->monitor;
- clone->monitor = t_pvt;
-
- /* Keep the same language. */
- ast_string_field_set(original, language, clone->language);
- /* Copy the FD's other than the generator fd */
- for (x = 0; x < AST_MAX_FDS; x++) {
- if (x != AST_GENERATOR_FD)
- original->fds[x] = clone->fds[x];
- }
-
- ast_app_group_update(clone, original);
- /* Move data stores over */
- if (AST_LIST_FIRST(&clone->datastores)) {
- struct ast_datastore *ds;
- AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
- AST_LIST_TRAVERSE(&original->datastores, ds, entry) {
- if (ds->info->chan_fixup)
- ds->info->chan_fixup(ds->data, clone, original);
- }
- }
-
- clone_variables(original, clone);
- /* Presense of ADSI capable CPE follows clone */
- original->adsicpe = clone->adsicpe;
- /* Bridge remains the same */
- /* CDR fields remain the same */
- /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
- /* Application and data remain the same */
- /* Clone exception becomes real one, as with fdno */
- ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
- original->fdno = clone->fdno;
- /* Schedule context remains the same */
- /* Stream stuff stays the same */
- /* Keep the original state. The fixup code will need to work with it most likely */
-
- /* Just swap the whole structures, nevermind the allocations, they'll work themselves
- out. */
- tmpcid = original->cid;
- original->cid = clone->cid;
- clone->cid = tmpcid;
-
- /* Restore original timing file descriptor */
- original->fds[AST_TIMING_FD] = original->timingfd;
-
- /* Our native formats are different now */
- original->nativeformats = clone->nativeformats;
-
- /* Context, extension, priority, app data, jump table, remain the same */
- /* pvt switches. pbx stays the same, as does next */
-
- /* Set the write format */
- ast_set_write_format(original, wformat);
-
- /* Set the read format */
- ast_set_read_format(original, rformat);
-
- /* Copy the music class */
- ast_string_field_set(original, musicclass, clone->musicclass);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
-
- /* Okay. Last thing is to let the channel driver know about all this mess, so he
- can fix up everything as best as possible */
- if (original->tech->fixup) {
- res = original->tech->fixup(clone, original);
- if (res) {
- ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
- original->tech->type, original->name);
- ast_channel_unlock(clone);
- return -1;
- }
- } else
- ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
- original->tech->type, original->name);
-
- /* If an indication is currently playing maintain it on the channel that is taking the place of original */
- if (original->visible_indication)
- ast_indicate(original, original->visible_indication);
-
- /* Now, at this point, the "clone" channel is totally F'd up. We mark it as
- a zombie so nothing tries to touch it. If it's already been marked as a
- zombie, then free it now (since it already is considered invalid). */
- if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
- ast_channel_unlock(clone);
- manager_event(EVENT_FLAG_CALL, "Hangup",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Cause: %d\r\n"
- "Cause-txt: %s\r\n",
- clone->name,
- clone->uniqueid,
- clone->hangupcause,
- ast_cause2str(clone->hangupcause)
- );
- ast_channel_free(clone);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
- ast_set_flag(clone, AST_FLAG_ZOMBIE);
- ast_queue_frame(clone, &ast_null_frame);
- ast_channel_unlock(clone);
- }
-
- /* Signal any blocker */
- if (ast_test_flag(original, AST_FLAG_BLOCKING))
- pthread_kill(original->blocker, SIGURG);
- if (option_debug)
- ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
- return 0;
-}
-
-void ast_set_callerid(struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
-{
- ast_channel_lock(chan);
-
- if (callerid) {
- if (chan->cid.cid_num)
- free(chan->cid.cid_num);
- chan->cid.cid_num = ast_strdup(callerid);
- }
- if (calleridname) {
- if (chan->cid.cid_name)
- free(chan->cid.cid_name);
- chan->cid.cid_name = ast_strdup(calleridname);
- }
- if (ani) {
- if (chan->cid.cid_ani)
- free(chan->cid.cid_ani);
- chan->cid.cid_ani = ast_strdup(ani);
- }
- if (chan->cdr)
- ast_cdr_setcid(chan->cdr, chan);
- manager_event(EVENT_FLAG_CALL, "Newcallerid",
- "Channel: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n"
- "CID-CallingPres: %d (%s)\r\n",
- chan->name,
- S_OR(chan->cid.cid_num, "<Unknown>"),
- S_OR(chan->cid.cid_name, "<Unknown>"),
- chan->uniqueid,
- chan->cid.cid_pres,
- ast_describe_caller_presentation(chan->cid.cid_pres)
- );
-
- ast_channel_unlock(chan);
-}
-
-int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
-{
- int oldstate = chan->_state;
-
- if (oldstate == state)
- return 0;
-
- chan->_state = state;
- ast_device_state_changed_literal(chan->name);
- /* setstate used to conditionally report Newchannel; this is no more */
- manager_event(EVENT_FLAG_CALL,
- "Newstate",
- "Channel: %s\r\n"
- "State: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n",
- chan->name, ast_state2str(chan->_state),
- S_OR(chan->cid.cid_num, "<unknown>"),
- S_OR(chan->cid.cid_name, "<unknown>"),
- chan->uniqueid);
-
- return 0;
-}
-
-/*! \brief Find bridged channel */
-struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
-{
- struct ast_channel *bridged;
- bridged = chan->_bridge;
- if (bridged && bridged->tech->bridged_channel)
- bridged = bridged->tech->bridged_channel(chan, bridged);
- return bridged;
-}
-
-static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
-{
- int min = 0, sec = 0, check;
-
- check = ast_autoservice_start(peer);
- if (check)
- return;
-
- if (remain > 0) {
- if (remain / 60 > 1) {
- min = remain / 60;
- sec = remain % 60;
- } else {
- sec = remain;
- }
- }
-
- if (!strcmp(sound,"timeleft")) { /* Queue support */
- ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
- if (min) {
- ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
- ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
- }
- if (sec) {
- ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
- ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
- }
- } else {
- ast_stream_and_wait(chan, sound, chan->language, "");
- }
-
- ast_autoservice_stop(peer);
-}
-
-static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
- struct ast_bridge_config *config, struct ast_frame **fo,
- struct ast_channel **rc, struct timeval bridge_end)
-{
- /* Copy voice back and forth between the two channels. */
- struct ast_channel *cs[3];
- struct ast_frame *f;
- enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
- int o0nativeformats;
- int o1nativeformats;
- int watch_c0_dtmf;
- int watch_c1_dtmf;
- void *pvt0, *pvt1;
- /* Indicates whether a frame was queued into a jitterbuffer */
- int frame_put_in_jb = 0;
- int jb_in_use;
- int to;
-
- cs[0] = c0;
- cs[1] = c1;
- pvt0 = c0->tech_pvt;
- pvt1 = c1->tech_pvt;
- o0nativeformats = c0->nativeformats;
- o1nativeformats = c1->nativeformats;
- watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
- watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
-
- /* Check the need of a jitterbuffer for each channel */
- jb_in_use = ast_jb_do_usecheck(c0, c1);
-
- for (;;) {
- struct ast_channel *who, *other;
-
- if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
- (o0nativeformats != c0->nativeformats) ||
- (o1nativeformats != c1->nativeformats)) {
- /* Check for Masquerade, codec changes, etc */
- res = AST_BRIDGE_RETRY;
- break;
- }
- if (bridge_end.tv_sec) {
- to = ast_tvdiff_ms(bridge_end, ast_tvnow());
- if (to <= 0) {
- if (config->timelimit)
- res = AST_BRIDGE_RETRY;
- else
- res = AST_BRIDGE_COMPLETE;
- break;
- }
- } else
- to = -1;
- /* Calculate the appropriate max sleep interval - in general, this is the time,
- left to the closest jb delivery moment */
- if (jb_in_use)
- to = ast_jb_get_when_to_wakeup(c0, c1, to);
- who = ast_waitfor_n(cs, 2, &to);
- if (!who) {
- /* No frame received within the specified timeout - check if we have to deliver now */
- if (jb_in_use)
- ast_jb_get_and_deliver(c0, c1);
- if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
- if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
- c0->_softhangup = 0;
- if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
- c1->_softhangup = 0;
- c0->_bridge = c1;
- c1->_bridge = c0;
- }
- continue;
- }
- f = ast_read(who);
- if (!f) {
- *fo = NULL;
- *rc = who;
- if (option_debug)
- ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
- break;
- }
-
- other = (who == c0) ? c1 : c0; /* the 'other' channel */
- /* Try add the frame info the who's bridged channel jitterbuff */
- if (jb_in_use)
- frame_put_in_jb = !ast_jb_put(other, f);
-
- if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
- int bridge_exit = 0;
-
- switch (f->subclass) {
- case AST_CONTROL_HOLD:
- case AST_CONTROL_UNHOLD:
- case AST_CONTROL_VIDUPDATE:
- case AST_CONTROL_SRCUPDATE:
- ast_indicate_data(other, f->subclass, f->data, f->datalen);
- break;
- default:
- *fo = f;
- *rc = who;
- bridge_exit = 1;
- if (option_debug)
- ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
- break;
- }
- if (bridge_exit)
- break;
- }
- if ((f->frametype == AST_FRAME_VOICE) ||
- (f->frametype == AST_FRAME_DTMF_BEGIN) ||
- (f->frametype == AST_FRAME_DTMF) ||
- (f->frametype == AST_FRAME_VIDEO) ||
- (f->frametype == AST_FRAME_IMAGE) ||
- (f->frametype == AST_FRAME_HTML) ||
- (f->frametype == AST_FRAME_MODEM) ||
- (f->frametype == AST_FRAME_TEXT)) {
- /* monitored dtmf causes exit from bridge */
- int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
-
- if (monitored_source &&
- (f->frametype == AST_FRAME_DTMF_END ||
- f->frametype == AST_FRAME_DTMF_BEGIN)) {
- *fo = f;
- *rc = who;
- if (option_debug)
- ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n",
- f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
- who->name);
- break;
- }
- /* Write immediately frames, not passed through jb */
- if (!frame_put_in_jb)
- ast_write(other, f);
-
- /* Check if we have to deliver now */
- if (jb_in_use)
- ast_jb_get_and_deliver(c0, c1);
- }
- /* XXX do we want to pass on also frames not matched above ? */
- ast_frfree(f);
-
- /* Swap who gets priority */
- cs[2] = cs[0];
- cs[0] = cs[1];
- cs[1] = cs[2];
- }
- return res;
-}
-
-/*! \brief Bridge two channels together */
-enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
- struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
-{
- struct ast_channel *who = NULL;
- enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
- int nativefailed=0;
- int firstpass;
- int o0nativeformats;
- int o1nativeformats;
- long time_left_ms=0;
- struct timeval nexteventts = { 0, };
- char caller_warning = 0;
- char callee_warning = 0;
-
- if (c0->_bridge) {
- ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
- c0->name, c0->_bridge->name);
- return -1;
- }
- if (c1->_bridge) {
- ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
- c1->name, c1->_bridge->name);
- return -1;
- }
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
- ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
- return -1;
-
- *fo = NULL;
- firstpass = config->firstpass;
- config->firstpass = 0;
-
- if (ast_tvzero(config->start_time))
- config->start_time = ast_tvnow();
- time_left_ms = config->timelimit;
-
- caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
- callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
-
- if (config->start_sound && firstpass) {
- if (caller_warning)
- bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
- if (callee_warning)
- bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
- }
-
- /* Keep track of bridge */
- c0->_bridge = c1;
- c1->_bridge = c0;
-
- /* \todo XXX here should check that cid_num is not NULL */
- manager_event(EVENT_FLAG_CALL, "Link",
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
-
- o0nativeformats = c0->nativeformats;
- o1nativeformats = c1->nativeformats;
-
- if (config->feature_timer) {
- nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
- } else if (config->timelimit) {
- nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
- if (caller_warning || callee_warning)
- nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
- }
-
- if (!c0->tech->send_digit_begin)
- ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
- if (!c1->tech->send_digit_begin)
- ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
-
- /* Before we enter in and bridge these two together tell them both the source of audio has changed */
- ast_indicate(c0, AST_CONTROL_SRCUPDATE);
- ast_indicate(c1, AST_CONTROL_SRCUPDATE);
-
- for (/* ever */;;) {
- struct timeval now = { 0, };
- int to;
-
- to = -1;
-
- if (!ast_tvzero(nexteventts)) {
- now = ast_tvnow();
- to = ast_tvdiff_ms(nexteventts, now);
- if (to <= 0) {
- if (!config->timelimit) {
- res = AST_BRIDGE_COMPLETE;
- break;
- }
- to = 0;
- }
- }
-
- if (config->timelimit) {
- time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
- if (time_left_ms < to)
- to = time_left_ms;
-
- if (time_left_ms <= 0) {
- if (caller_warning && config->end_sound)
- bridge_playfile(c0, c1, config->end_sound, 0);
- if (callee_warning && config->end_sound)
- bridge_playfile(c1, c0, config->end_sound, 0);
- *fo = NULL;
- if (who)
- *rc = who;
- res = 0;
- break;
- }
-
- if (!to) {
- if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
- int t = (time_left_ms + 500) / 1000; /* round to nearest second */
- if (caller_warning)
- bridge_playfile(c0, c1, config->warning_sound, t);
- if (callee_warning)
- bridge_playfile(c1, c0, config->warning_sound, t);
- }
- if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
- nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
- else
- nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
- }
- }
-
- if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
- if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
- c0->_softhangup = 0;
- if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
- c1->_softhangup = 0;
- c0->_bridge = c1;
- c1->_bridge = c0;
- if (option_debug)
- ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
- continue;
- }
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
- ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
- *fo = NULL;
- if (who)
- *rc = who;
- res = 0;
- if (option_debug)
- ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
- c0->name, c1->name,
- ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
- ast_check_hangup(c0) ? "Yes" : "No",
- ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
- ast_check_hangup(c1) ? "Yes" : "No");
- break;
- }
-
- /* See if the BRIDGEPEER variable needs to be updated */
- if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
- pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
- if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
- pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
-
- if (c0->tech->bridge &&
- (config->timelimit == 0) &&
- (c0->tech->bridge == c1->tech->bridge) &&
- !nativefailed && !c0->monitor && !c1->monitor &&
- !c0->audiohooks && !c1->audiohooks && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
- !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
- !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
- /* Looks like they share a bridge method and nothing else is in the way */
- ast_set_flag(c0, AST_FLAG_NBRIDGE);
- ast_set_flag(c1, AST_FLAG_NBRIDGE);
- if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
- /* \todo XXX here should check that cid_num is not NULL */
- manager_event(EVENT_FLAG_CALL, "Unlink",
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
- if (option_debug)
- ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
-
- ast_clear_flag(c0, AST_FLAG_NBRIDGE);
- ast_clear_flag(c1, AST_FLAG_NBRIDGE);
-
- if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
- continue;
-
- c0->_bridge = NULL;
- c1->_bridge = NULL;
-
- return res;
- } else {
- ast_clear_flag(c0, AST_FLAG_NBRIDGE);
- ast_clear_flag(c1, AST_FLAG_NBRIDGE);
- }
- switch (res) {
- case AST_BRIDGE_RETRY:
- continue;
- default:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
- c0->name, c1->name);
- /* fallthrough */
- case AST_BRIDGE_FAILED_NOWARN:
- nativefailed++;
- break;
- }
- }
-
- if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
- (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
- !(c0->generator || c1->generator)) {
- if (ast_channel_make_compatible(c0, c1)) {
- ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
- /* \todo XXX here should check that cid_num is not NULL */
- manager_event(EVENT_FLAG_CALL, "Unlink",
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
- return AST_BRIDGE_FAILED;
- }
- o0nativeformats = c0->nativeformats;
- o1nativeformats = c1->nativeformats;
- }
- res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
- if (res != AST_BRIDGE_RETRY)
- break;
- }
-
- ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
- ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
-
- /* Now that we have broken the bridge the source will change yet again */
- ast_indicate(c0, AST_CONTROL_SRCUPDATE);
- ast_indicate(c1, AST_CONTROL_SRCUPDATE);
-
- c0->_bridge = NULL;
- c1->_bridge = NULL;
-
- /* \todo XXX here should check that cid_num is not NULL */
- manager_event(EVENT_FLAG_CALL, "Unlink",
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
- if (option_debug)
- ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
-
- return res;
-}
-
-/*! \brief Sets an option on a channel */
-int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
-{
- int res;
-
- if (chan->tech->setoption) {
- res = chan->tech->setoption(chan, option, data, datalen);
- if (res < 0)
- return res;
- } else {
- errno = ENOSYS;
- return -1;
- }
- if (block) {
- /* XXX Implement blocking -- just wait for our option frame reply, discarding
- intermediate packets. XXX */
- ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
- return -1;
- }
- return 0;
-}
-
-struct tonepair_def {
- int freq1;
- int freq2;
- int duration;
- int vol;
-};
-
-struct tonepair_state {
- int fac1;
- int fac2;
- int v1_1;
- int v2_1;
- int v3_1;
- int v1_2;
- int v2_2;
- int v3_2;
- int origwfmt;
- int pos;
- int duration;
- int modulate;
- struct ast_frame f;
- unsigned char offset[AST_FRIENDLY_OFFSET];
- short data[4000];
-};
-
-static void tonepair_release(struct ast_channel *chan, void *params)
-{
- struct tonepair_state *ts = params;
-
- if (chan)
- ast_set_write_format(chan, ts->origwfmt);
- free(ts);
-}
-
-static void *tonepair_alloc(struct ast_channel *chan, void *params)
-{
- struct tonepair_state *ts;
- struct tonepair_def *td = params;
-
- if (!(ts = ast_calloc(1, sizeof(*ts))))
- return NULL;
- ts->origwfmt = chan->writeformat;
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
- ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
- tonepair_release(NULL, ts);
- ts = NULL;
- } else {
- ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
- ts->v1_1 = 0;
- ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
- ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
- ts->v2_1 = 0;
- ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
- ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
- ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
- ts->duration = td->duration;
- ts->modulate = 0;
- }
- /* Let interrupts interrupt :) */
- ast_set_flag(chan, AST_FLAG_WRITE_INT);
- return ts;
-}
-
-static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct tonepair_state *ts = data;
- int x;
-
- /* we need to prepare a frame with 16 * timelen samples as we're
- * generating SLIN audio
- */
- len = samples * 2;
-
- if (len > sizeof(ts->data) / 2 - 1) {
- ast_log(LOG_WARNING, "Can't generate that much data!\n");
- return -1;
- }
- memset(&ts->f, 0, sizeof(ts->f));
- for (x=0;x<len/2;x++) {
- ts->v1_1 = ts->v2_1;
- ts->v2_1 = ts->v3_1;
- ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
-
- ts->v1_2 = ts->v2_2;
- ts->v2_2 = ts->v3_2;
- ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
- if (ts->modulate) {
- int p;
- p = ts->v3_2 - 32768;
- if (p < 0) p = -p;
- p = ((p * 9) / 10) + 1;
- ts->data[x] = (ts->v3_1 * p) >> 15;
- } else
- ts->data[x] = ts->v3_1 + ts->v3_2;
- }
- ts->f.frametype = AST_FRAME_VOICE;
- ts->f.subclass = AST_FORMAT_SLINEAR;
- ts->f.datalen = len;
- ts->f.samples = samples;
- ts->f.offset = AST_FRIENDLY_OFFSET;
- ts->f.data = ts->data;
- ast_write(chan, &ts->f);
- ts->pos += x;
- if (ts->duration > 0) {
- if (ts->pos >= ts->duration * 8)
- return -1;
- }
- return 0;
-}
-
-static struct ast_generator tonepair = {
- alloc: tonepair_alloc,
- release: tonepair_release,
- generate: tonepair_generator,
-};
-
-int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
-{
- struct tonepair_def d = { 0, };
-
- d.freq1 = freq1;
- d.freq2 = freq2;
- d.duration = duration;
- d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
- if (ast_activate_generator(chan, &tonepair, &d))
- return -1;
- return 0;
-}
-
-void ast_tonepair_stop(struct ast_channel *chan)
-{
- ast_deactivate_generator(chan);
-}
-
-int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
-{
- int res;
-
- if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
- return res;
-
- /* Give us some wiggle room */
- while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
- struct ast_frame *f = ast_read(chan);
- if (f)
- ast_frfree(f);
- else
- return -1;
- }
- return 0;
-}
-
-ast_group_t ast_get_group(const char *s)
-{
- char *piece;
- char *c;
- int start=0, finish=0, x;
- ast_group_t group = 0;
-
- if (ast_strlen_zero(s))
- return 0;
-
- c = ast_strdupa(s);
-
- while ((piece = strsep(&c, ","))) {
- if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
- /* Range */
- } else if (sscanf(piece, "%d", &start)) {
- /* Just one */
- finish = start;
- } else {
- ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
- continue;
- }
- for (x = start; x <= finish; x++) {
- if ((x > 63) || (x < 0)) {
- ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
- } else
- group |= ((ast_group_t) 1 << x);
- }
- }
- return group;
-}
-
-static int (*ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL;
-static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
-static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
-
-void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
- void (*stop_ptr)(struct ast_channel *),
- void (*cleanup_ptr)(struct ast_channel *))
-{
- ast_moh_start_ptr = start_ptr;
- ast_moh_stop_ptr = stop_ptr;
- ast_moh_cleanup_ptr = cleanup_ptr;
-}
-
-void ast_uninstall_music_functions(void)
-{
- ast_moh_start_ptr = NULL;
- ast_moh_stop_ptr = NULL;
- ast_moh_cleanup_ptr = NULL;
-}
-
-/*! \brief Turn on music on hold on a given channel */
-int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
-{
- if (ast_moh_start_ptr)
- return ast_moh_start_ptr(chan, mclass, interpclass);
-
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n",
- mclass ? mclass : (interpclass ? interpclass : "default"));
- }
-
- return 0;
-}
-
-/*! \brief Turn off music on hold on a given channel */
-void ast_moh_stop(struct ast_channel *chan)
-{
- if (ast_moh_stop_ptr)
- ast_moh_stop_ptr(chan);
-}
-
-void ast_moh_cleanup(struct ast_channel *chan)
-{
- if (ast_moh_cleanup_ptr)
- ast_moh_cleanup_ptr(chan);
-}
-
-void ast_channels_init(void)
-{
- ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
-}
-
-/*! \brief Print call group and pickup group ---*/
-char *ast_print_group(char *buf, int buflen, ast_group_t group)
-{
- unsigned int i;
- int first=1;
- char num[3];
-
- buf[0] = '\0';
-
- if (!group) /* Return empty string if no group */
- return buf;
-
- for (i = 0; i <= 63; i++) { /* Max group is 63 */
- if (group & ((ast_group_t) 1 << i)) {
- if (!first) {
- strncat(buf, ", ", buflen - strlen(buf) - 1);
- } else {
- first=0;
- }
- snprintf(num, sizeof(num), "%u", i);
- strncat(buf, num, buflen - strlen(buf) - 1);
- }
- }
- return buf;
-}
-
-void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
-{
- struct ast_variable *cur;
-
- for (cur = vars; cur; cur = cur->next)
- pbx_builtin_setvar_helper(chan, cur->name, cur->value);
-}
-
-static void *silence_generator_alloc(struct ast_channel *chan, void *data)
-{
- /* just store the data pointer in the channel structure */
- return data;
-}
-
-static void silence_generator_release(struct ast_channel *chan, void *data)
-{
- /* nothing to do */
-}
-
-static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
-{
- short buf[samples];
- struct ast_frame frame = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_SLINEAR,
- .data = buf,
- .samples = samples,
- .datalen = sizeof(buf),
- };
- memset(buf, 0, sizeof(buf));
- if (ast_write(chan, &frame))
- return -1;
- return 0;
-}
-
-static struct ast_generator silence_generator = {
- .alloc = silence_generator_alloc,
- .release = silence_generator_release,
- .generate = silence_generator_generate,
-};
-
-struct ast_silence_generator {
- int old_write_format;
-};
-
-struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
-{
- struct ast_silence_generator *state;
-
- if (!(state = ast_calloc(1, sizeof(*state)))) {
- return NULL;
- }
-
- state->old_write_format = chan->writeformat;
-
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
- ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
- free(state);
- return NULL;
- }
-
- ast_activate_generator(chan, &silence_generator, state);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
-
- return state;
-}
-
-void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
-{
- if (!state)
- return;
-
- ast_deactivate_generator(chan);
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
-
- if (ast_set_write_format(chan, state->old_write_format) < 0)
- ast_log(LOG_ERROR, "Could not return write format to its original state\n");
-
- free(state);
-}
-
-
-/*! \ brief Convert channel reloadreason (ENUM) to text string for manager event */
-const char *channelreloadreason2txt(enum channelreloadreason reason)
-{
- switch (reason) {
- case CHANNEL_MODULE_LOAD:
- return "LOAD (Channel module load)";
-
- case CHANNEL_MODULE_RELOAD:
- return "RELOAD (Channel module reload)";
-
- case CHANNEL_CLI_RELOAD:
- return "CLIRELOAD (Channel module reload by CLI command)";
-
- default:
- return "MANAGERRELOAD (Channel module reload by manager)";
- }
-};
-
-#ifdef DEBUG_CHANNEL_LOCKS
-
-/*! \brief Unlock AST channel (and print debugging output)
-\note You need to enable DEBUG_CHANNEL_LOCKS for this function
-*/
-int ast_channel_unlock(struct ast_channel *chan)
-{
- int res = 0;
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "::::==== Unlocking AST channel %s\n", chan->name);
-
- if (!chan) {
- if (option_debug)
- ast_log(LOG_DEBUG, "::::==== Unlocking non-existing channel \n");
- return 0;
- }
-
- res = ast_mutex_unlock(&chan->lock);
-
- if (option_debug > 2) {
-#ifdef DEBUG_THREADS
- int count = 0;
- if ((count = chan->lock.reentrancy))
- ast_log(LOG_DEBUG, ":::=== Still have %d locks (recursive)\n", count);
-#endif
- if (!res)
- if (option_debug)
- ast_log(LOG_DEBUG, "::::==== Channel %s was unlocked\n", chan->name);
- if (res == EINVAL) {
- if (option_debug)
- ast_log(LOG_DEBUG, "::::==== Channel %s had no lock by this thread. Failed unlocking\n", chan->name);
- }
- }
- if (res == EPERM) {
- /* We had no lock, so okay any way*/
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "::::==== Channel %s was not locked at all \n", chan->name);
- res = 0;
- }
- return res;
-}
-
-/*! \brief Lock AST channel (and print debugging output)
-\note You need to enable DEBUG_CHANNEL_LOCKS for this function */
-int ast_channel_lock(struct ast_channel *chan)
-{
- int res;
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "====:::: Locking AST channel %s\n", chan->name);
-
- res = ast_mutex_lock(&chan->lock);
-
- if (option_debug > 3) {
-#ifdef DEBUG_THREADS
- int count = 0;
- if ((count = chan->lock.reentrancy))
- ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
-#endif
- if (!res)
- ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
- if (res == EDEADLK) {
- /* We had no lock, so okey any way */
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "::::==== Channel %s was not locked by us. Lock would cause deadlock.\n", chan->name);
- }
- if (res == EINVAL) {
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name);
- }
- }
- return res;
-}
-
-/*! \brief Lock AST channel (and print debugging output)
-\note You need to enable DEBUG_CHANNEL_LOCKS for this function */
-int ast_channel_trylock(struct ast_channel *chan)
-{
- int res;
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "====:::: Trying to lock AST channel %s\n", chan->name);
-
- res = ast_mutex_trylock(&chan->lock);
-
- if (option_debug > 2) {
-#ifdef DEBUG_THREADS
- int count = 0;
- if ((count = chan->lock.reentrancy))
- ast_log(LOG_DEBUG, ":::=== Now have %d locks (recursive)\n", count);
-#endif
- if (!res)
- ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
- if (res == EBUSY) {
- /* We failed to lock */
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "::::==== Channel %s failed to lock. Not waiting around...\n", chan->name);
- }
- if (res == EDEADLK) {
- /* We had no lock, so okey any way*/
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "::::==== Channel %s was not locked. Lock would cause deadlock.\n", chan->name);
- }
- if (res == EINVAL && option_debug > 2)
- ast_log(LOG_DEBUG, "::::==== Channel %s lock failed. No mutex.\n", chan->name);
- }
- return res;
-}
-
-#endif
-
-/*
- * Wrappers for various ast_say_*() functions that call the full version
- * of the same functions.
- * The proper place would be say.c, but that file is optional and one
- * must be able to build asterisk even without it (using a loadable 'say'
- * implementation that only supplies the 'full' version of the functions.
- */
-
-int ast_say_number(struct ast_channel *chan, int num,
- const char *ints, const char *language, const char *options)
-{
- return ast_say_number_full(chan, num, ints, language, options, -1, -1);
-}
-
-int ast_say_enumeration(struct ast_channel *chan, int num,
- const char *ints, const char *language, const char *options)
-{
- return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
-}
-
-int ast_say_digits(struct ast_channel *chan, int num,
- const char *ints, const char *lang)
-{
- return ast_say_digits_full(chan, num, ints, lang, -1, -1);
-}
-
-int ast_say_digit_str(struct ast_channel *chan, const char *str,
- const char *ints, const char *lang)
-{
- return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
-}
-
-int ast_say_character_str(struct ast_channel *chan, const char *str,
- const char *ints, const char *lang)
-{
- return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
-}
-
-int ast_say_phonetic_str(struct ast_channel *chan, const char *str,
- const char *ints, const char *lang)
-{
- return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
-}
-
-int ast_say_digits_full(struct ast_channel *chan, int num,
- const char *ints, const char *lang, int audiofd, int ctrlfd)
-{
- char buf[256];
-
- snprintf(buf, sizeof(buf), "%d", num);
- return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
-}
-
diff --git a/1.4/main/chanvars.c b/1.4/main/chanvars.c
deleted file mode 100644
index 7e617c1fb..000000000
--- a/1.4/main/chanvars.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Channel Variables
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "asterisk/chanvars.h"
-#include "asterisk/logger.h"
-#include "asterisk/strings.h"
-#include "asterisk/utils.h"
-
-struct ast_var_t *ast_var_assign(const char *name, const char *value)
-{
- struct ast_var_t *var;
- int name_len = strlen(name) + 1;
- int value_len = strlen(value) + 1;
-
- if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
- return NULL;
- }
-
- ast_copy_string(var->name, name, name_len);
- var->value = var->name + name_len;
- ast_copy_string(var->value, value, value_len);
-
- return var;
-}
-
-void ast_var_delete(struct ast_var_t *var)
-{
- if (var)
- free(var);
-}
-
-const char *ast_var_name(const struct ast_var_t *var)
-{
- const char *name;
-
- if (var == NULL || (name = var->name) == NULL)
- return NULL;
- /* Return the name without the initial underscores */
- if (name[0] == '_') {
- name++;
- if (name[0] == '_')
- name++;
- }
- return name;
-}
-
-const char *ast_var_full_name(const struct ast_var_t *var)
-{
- return (var ? var->name : NULL);
-}
-
-const char *ast_var_value(const struct ast_var_t *var)
-{
- return (var ? var->value : NULL);
-}
-
-
diff --git a/1.4/main/cli.c b/1.4/main/cli.c
deleted file mode 100644
index 2ecf20a3d..000000000
--- a/1.4/main/cli.c
+++ /dev/null
@@ -1,2037 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Standard Command Line Interface
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/signal.h>
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#include <ctype.h>
-#include <regex.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/module.h"
-#include "asterisk/pbx.h"
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/lock.h"
-#include "editline/readline/readline.h"
-#include "asterisk/threadstorage.h"
-
-extern unsigned long global_fin, global_fout;
-
-AST_THREADSTORAGE(ast_cli_buf, ast_cli_buf_init);
-
-/*! \brief Initial buffer size for resulting strings in ast_cli() */
-#define AST_CLI_INITLEN 256
-
-void ast_cli(int fd, char *fmt, ...)
-{
- int res;
- struct ast_dynamic_str *buf;
- va_list ap;
-
- if (!(buf = ast_dynamic_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN)))
- return;
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(&buf, 0, &ast_cli_buf, fmt, ap);
- va_end(ap);
-
- if (res != AST_DYNSTR_BUILD_FAILED)
- ast_carefulwrite(fd, buf->str, strlen(buf->str), 100);
-}
-
-static AST_LIST_HEAD_STATIC(helpers, ast_cli_entry);
-
-static char load_help[] =
-"Usage: module load <module name>\n"
-" Loads the specified module into Asterisk.\n";
-
-static char unload_help[] =
-"Usage: module unload [-f|-h] <module name>\n"
-" Unloads the specified module from Asterisk. The -f\n"
-" option causes the module to be unloaded even if it is\n"
-" in use (may cause a crash) and the -h module causes the\n"
-" module to be unloaded even if the module says it cannot, \n"
-" which almost always will cause a crash.\n";
-
-static char help_help[] =
-"Usage: help [topic]\n"
-" When called with a topic as an argument, displays usage\n"
-" information on the given command. If called without a\n"
-" topic, it provides a list of commands.\n";
-
-static char chanlist_help[] =
-"Usage: core show channels [concise|verbose]\n"
-" Lists currently defined channels and some information about them. If\n"
-" 'concise' is specified, the format is abridged and in a more easily\n"
-" machine parsable format. If 'verbose' is specified, the output includes\n"
-" more and longer fields.\n";
-
-static char reload_help[] =
-"Usage: module reload [module ...]\n"
-" Reloads configuration files for all listed modules which support\n"
-" reloading, or for all supported modules if none are listed.\n";
-
-static char verbose_help[] =
-"Usage: core set verbose <level>\n"
-" Sets level of verbose messages to be displayed. 0 means\n"
-" no messages should be displayed. Equivalent to -v[v[v...]]\n"
-" on startup\n";
-
-static char debug_help[] =
-"Usage: core set debug <level> [filename]\n"
-" Sets level of core debug messages to be displayed. 0 means\n"
-" no messages should be displayed. Equivalent to -d[d[d...]]\n"
-" on startup. If filename is specified, debugging will be\n"
-" limited to just that file.\n";
-
-static char nodebug_help[] =
-"Usage: core set debug off\n"
-" Turns off core debug messages.\n";
-
-static char logger_mute_help[] =
-"Usage: logger mute\n"
-" Disables logging output to the current console, making it possible to\n"
-" gather information without being disturbed by scrolling lines.\n";
-
-static char softhangup_help[] =
-"Usage: soft hangup <channel>\n"
-" Request that a channel be hung up. The hangup takes effect\n"
-" the next time the driver reads or writes from the channel\n";
-
-static char group_show_channels_help[] =
-"Usage: group show channels [pattern]\n"
-" Lists all currently active channels with channel group(s) specified.\n"
-" Optional regular expression pattern is matched to group names for each\n"
-" channel.\n";
-
-static int handle_load_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- if (ast_load_resource(argv[1])) {
- ast_cli(fd, "Unable to load module %s\n", argv[1]);
- return RESULT_FAILURE;
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_load(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- if (ast_load_resource(argv[2])) {
- ast_cli(fd, "Unable to load module %s\n", argv[2]);
- return RESULT_FAILURE;
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_reload_deprecated(int fd, int argc, char *argv[])
-{
- int x;
- int res;
- if (argc < 1)
- return RESULT_SHOWUSAGE;
- if (argc > 1) {
- for (x = 1; x < argc; x++) {
- res = ast_module_reload(argv[x]);
- switch(res) {
- case 0:
- ast_cli(fd, "No such module '%s'\n", argv[x]);
- break;
- case 1:
- ast_cli(fd, "Module '%s' does not support reload\n", argv[x]);
- break;
- }
- }
- } else
- ast_module_reload(NULL);
- return RESULT_SUCCESS;
-}
-
-static int handle_reload(int fd, int argc, char *argv[])
-{
- int x;
- int res;
- if (argc < 2)
- return RESULT_SHOWUSAGE;
- if (argc > 2) {
- for (x = 2; x < argc; x++) {
- res = ast_module_reload(argv[x]);
- switch(res) {
- case 0:
- ast_cli(fd, "No such module '%s'\n", argv[x]);
- break;
- case 1:
- ast_cli(fd, "Module '%s' does not support reload\n", argv[x]);
- break;
- }
- }
- } else
- ast_module_reload(NULL);
- return RESULT_SUCCESS;
-}
-
-static int handle_set_verbose_deprecated(int fd, int argc, char *argv[])
-{
- int val = 0;
- int oldval = option_verbose;
-
- /* "set verbose [atleast] N" */
- if (argc == 3)
- option_verbose = atoi(argv[2]);
- else if (argc == 4) {
- if (strcasecmp(argv[2], "atleast"))
- return RESULT_SHOWUSAGE;
- val = atoi(argv[3]);
- if (val > option_verbose)
- option_verbose = val;
- } else
- return RESULT_SHOWUSAGE;
-
- if (oldval != option_verbose && option_verbose > 0)
- ast_cli(fd, "Verbosity was %d and is now %d\n", oldval, option_verbose);
- else if (oldval > 0 && option_verbose > 0)
- ast_cli(fd, "Verbosity is at least %d\n", option_verbose);
- else if (oldval > 0 && option_verbose == 0)
- ast_cli(fd, "Verbosity is now OFF\n");
-
- return RESULT_SUCCESS;
-}
-
-static int handle_verbose(int fd, int argc, char *argv[])
-{
- int oldval = option_verbose;
- int newlevel;
- int atleast = 0;
-
- if ((argc < 4) || (argc > 5))
- return RESULT_SHOWUSAGE;
-
- if (!strcasecmp(argv[3], "atleast"))
- atleast = 1;
-
- if (!atleast) {
- if (argc > 4)
- return RESULT_SHOWUSAGE;
-
- option_verbose = atoi(argv[3]);
- } else {
- if (argc < 5)
- return RESULT_SHOWUSAGE;
-
- newlevel = atoi(argv[4]);
- if (newlevel > option_verbose)
- option_verbose = newlevel;
- }
- if (oldval > 0 && option_verbose == 0)
- ast_cli(fd, "Verbosity is now OFF\n");
- else if (option_verbose > 0) {
- if (oldval == option_verbose)
- ast_cli(fd, "Verbosity is at least %d\n", option_verbose);
- else
- ast_cli(fd, "Verbosity was %d and is now %d\n", oldval, option_verbose);
- }
-
- return RESULT_SUCCESS;
-}
-
-static int handle_set_debug_deprecated(int fd, int argc, char *argv[])
-{
- int val = 0;
- int oldval = option_debug;
-
- /* "set debug [atleast] N" */
- if (argc == 3)
- option_debug = atoi(argv[2]);
- else if (argc == 4) {
- if (strcasecmp(argv[2], "atleast"))
- return RESULT_SHOWUSAGE;
- val = atoi(argv[3]);
- if (val > option_debug)
- option_debug = val;
- } else
- return RESULT_SHOWUSAGE;
-
- if (oldval != option_debug && option_debug > 0)
- ast_cli(fd, "Core debug was %d and is now %d\n", oldval, option_debug);
- else if (oldval > 0 && option_debug > 0)
- ast_cli(fd, "Core debug is at least %d\n", option_debug);
- else if (oldval > 0 && option_debug == 0)
- ast_cli(fd, "Core debug is now OFF\n");
-
- return RESULT_SUCCESS;
-}
-
-static int handle_set_debug(int fd, int argc, char *argv[])
-{
- int oldval = option_debug;
- int newlevel;
- int atleast = 0;
- char *filename = '\0';
-
- /* 'core set debug <level>'
- * 'core set debug <level> <fn>'
- * 'core set debug atleast <level>'
- * 'core set debug atleast <level> <fn>'
- */
- if ((argc < 4) || (argc > 6))
- return RESULT_SHOWUSAGE;
-
- if (!strcasecmp(argv[3], "atleast"))
- atleast = 1;
-
- if (!atleast) {
- if (argc > 5)
- return RESULT_SHOWUSAGE;
-
- if (sscanf(argv[3], "%d", &newlevel) != 1)
- return RESULT_SHOWUSAGE;
-
- if (argc == 4) {
- debug_filename[0] = '\0';
- } else {
- filename = argv[4];
- ast_copy_string(debug_filename, filename, sizeof(debug_filename));
- }
-
- option_debug = newlevel;
- } else {
- if (argc < 5 || argc > 6)
- return RESULT_SHOWUSAGE;
-
- if (sscanf(argv[4], "%d", &newlevel) != 1)
- return RESULT_SHOWUSAGE;
-
- if (argc == 5) {
- debug_filename[0] = '\0';
- } else {
- filename = argv[5];
- ast_copy_string(debug_filename, filename, sizeof(debug_filename));
- }
-
- if (newlevel > option_debug)
- option_debug = newlevel;
- }
-
- if (oldval > 0 && option_debug == 0)
- ast_cli(fd, "Core debug is now OFF\n");
- else if (option_debug > 0) {
- if (filename) {
- if (oldval == option_debug)
- ast_cli(fd, "Core debug is at least %d, file '%s'\n", option_debug, filename);
- else
- ast_cli(fd, "Core debug was %d and is now %d, file '%s'\n", oldval, option_debug, filename);
- } else {
- if (oldval == option_debug)
- ast_cli(fd, "Core debug is at least %d\n", option_debug);
- else
- ast_cli(fd, "Core debug was %d and is now %d\n", oldval, option_debug);
- }
- }
-
- return RESULT_SUCCESS;
-}
-
-static int handle_nodebug(int fd, int argc, char *argv[])
-{
- int oldval = option_debug;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- option_debug = 0;
- debug_filename[0] = '\0';
-
- if (oldval > 0)
- ast_cli(fd, "Core debug is now OFF\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_debuglevel_deprecated(int fd, int argc, char *argv[])
-{
- int newlevel;
- char *filename = "<any>";
- if ((argc < 3) || (argc > 4))
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[2], "%d", &newlevel) != 1)
- return RESULT_SHOWUSAGE;
- option_debug = newlevel;
- if (argc == 4) {
- filename = argv[3];
- ast_copy_string(debug_filename, filename, sizeof(debug_filename));
- } else {
- debug_filename[0] = '\0';
- }
- ast_cli(fd, "Debugging level set to %d, file '%s'\n", newlevel, filename);
- return RESULT_SUCCESS;
-}
-
-static int handle_logger_mute(int fd, int argc, char *argv[])
-{
- if (argc < 2 || argc > 3)
- return RESULT_SHOWUSAGE;
- if (argc == 3 && !strcasecmp(argv[2], "silent"))
- ast_console_toggle_mute(fd, 1);
- else
- ast_console_toggle_mute(fd, 0);
- return RESULT_SUCCESS;
-}
-
-static int handle_unload_deprecated(int fd, int argc, char *argv[])
-{
- int x;
- int force = AST_FORCE_SOFT;
- if (argc < 2)
- return RESULT_SHOWUSAGE;
- for (x = 1; x < argc; x++) {
- if (argv[x][0] == '-') {
- switch(argv[x][1]) {
- case 'f':
- force = AST_FORCE_FIRM;
- break;
- case 'h':
- force = AST_FORCE_HARD;
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
- } else if (x != argc - 1)
- return RESULT_SHOWUSAGE;
- else if (ast_unload_resource(argv[x], force)) {
- ast_cli(fd, "Unable to unload resource %s\n", argv[x]);
- return RESULT_FAILURE;
- }
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_unload(int fd, int argc, char *argv[])
-{
- int x;
- int force = AST_FORCE_SOFT;
- if (argc < 3)
- return RESULT_SHOWUSAGE;
- for (x = 2; x < argc; x++) {
- if (argv[x][0] == '-') {
- switch(argv[x][1]) {
- case 'f':
- force = AST_FORCE_FIRM;
- break;
- case 'h':
- force = AST_FORCE_HARD;
- break;
- default:
- return RESULT_SHOWUSAGE;
- }
- } else if (x != argc - 1)
- return RESULT_SHOWUSAGE;
- else if (ast_unload_resource(argv[x], force)) {
- ast_cli(fd, "Unable to unload resource %s\n", argv[x]);
- return RESULT_FAILURE;
- }
- }
- return RESULT_SUCCESS;
-}
-
-#define MODLIST_FORMAT "%-30s %-40.40s %-10d\n"
-#define MODLIST_FORMAT2 "%-30s %-40.40s %-10s\n"
-
-AST_MUTEX_DEFINE_STATIC(climodentrylock);
-static int climodentryfd = -1;
-
-static int modlist_modentry(const char *module, const char *description, int usecnt, const char *like)
-{
- /* Comparing the like with the module */
- if (strcasestr(module, like) ) {
- ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt);
- return 1;
- }
- return 0;
-}
-
-static char modlist_help[] =
-"Usage: module show [like <keyword>]\n"
-" Shows Asterisk modules currently in use, and usage statistics.\n";
-
-static char uptime_help[] =
-"Usage: core show uptime [seconds]\n"
-" Shows Asterisk uptime information.\n"
-" The seconds word returns the uptime in seconds only.\n";
-
-static void print_uptimestr(int fd, time_t timeval, const char *prefix, int printsec)
-{
- int x; /* the main part - years, weeks, etc. */
- char timestr[256]="", *s = timestr;
- size_t maxbytes = sizeof(timestr);
-
-#define SECOND (1)
-#define MINUTE (SECOND*60)
-#define HOUR (MINUTE*60)
-#define DAY (HOUR*24)
-#define WEEK (DAY*7)
-#define YEAR (DAY*365)
-#define ESS(x) ((x == 1) ? "" : "s") /* plural suffix */
-#define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */
- if (timeval < 0) /* invalid, nothing to show */
- return;
- if (printsec) { /* plain seconds output */
- ast_build_string(&s, &maxbytes, "%lu", (u_long)timeval);
- timeval = 0; /* bypass the other cases */
- }
- if (timeval > YEAR) {
- x = (timeval / YEAR);
- timeval -= (x * YEAR);
- ast_build_string(&s, &maxbytes, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval));
- }
- if (timeval > WEEK) {
- x = (timeval / WEEK);
- timeval -= (x * WEEK);
- ast_build_string(&s, &maxbytes, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval));
- }
- if (timeval > DAY) {
- x = (timeval / DAY);
- timeval -= (x * DAY);
- ast_build_string(&s, &maxbytes, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval));
- }
- if (timeval > HOUR) {
- x = (timeval / HOUR);
- timeval -= (x * HOUR);
- ast_build_string(&s, &maxbytes, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval));
- }
- if (timeval > MINUTE) {
- x = (timeval / MINUTE);
- timeval -= (x * MINUTE);
- ast_build_string(&s, &maxbytes, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval));
- }
- x = timeval;
- if (x > 0)
- ast_build_string(&s, &maxbytes, "%d second%s ", x, ESS(x));
- if (timestr[0] != '\0')
- ast_cli(fd, "%s: %s\n", prefix, timestr);
-}
-
-static int handle_showuptime_deprecated(int fd, int argc, char *argv[])
-{
- /* 'show uptime [seconds]' */
- time_t curtime = time(NULL);
- int printsec = (argc == 3 && !strcasecmp(argv[2],"seconds"));
-
- if (argc != 2 && !printsec)
- return RESULT_SHOWUSAGE;
- if (ast_startuptime)
- print_uptimestr(fd, curtime - ast_startuptime, "System uptime", printsec);
- if (ast_lastreloadtime)
- print_uptimestr(fd, curtime - ast_lastreloadtime, "Last reload", printsec);
- return RESULT_SUCCESS;
-}
-
-static int handle_showuptime(int fd, int argc, char *argv[])
-{
- /* 'core show uptime [seconds]' */
- time_t curtime = time(NULL);
- int printsec = (argc == 4 && !strcasecmp(argv[3],"seconds"));
-
- if (argc != 3 && !printsec)
- return RESULT_SHOWUSAGE;
- if (ast_startuptime)
- print_uptimestr(fd, curtime - ast_startuptime, "System uptime", printsec);
- if (ast_lastreloadtime)
- print_uptimestr(fd, curtime - ast_lastreloadtime, "Last reload", printsec);
- return RESULT_SUCCESS;
-}
-
-static int handle_modlist(int fd, int argc, char *argv[])
-{
- char *like = "";
- if (argc == 3)
- return RESULT_SHOWUSAGE;
- else if (argc >= 4) {
- if (strcmp(argv[2],"like"))
- return RESULT_SHOWUSAGE;
- like = argv[3];
- }
-
- ast_mutex_lock(&climodentrylock);
- climodentryfd = fd; /* global, protected by climodentrylock */
- ast_cli(fd, MODLIST_FORMAT2, "Module", "Description", "Use Count");
- ast_cli(fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like));
- climodentryfd = -1;
- ast_mutex_unlock(&climodentrylock);
- return RESULT_SUCCESS;
-}
-#undef MODLIST_FORMAT
-#undef MODLIST_FORMAT2
-
-#define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n"
-#define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
-#define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s\n"
-#define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
-#define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
-
-static int handle_chanlist_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_channel *c = NULL;
- char durbuf[10] = "-";
- char locbuf[40];
- char appdata[40];
- int duration;
- int durh, durm, durs;
- int numchans = 0, concise = 0, verbose = 0;
-
- concise = (argc == 3 && (!strcasecmp(argv[2],"concise")));
- verbose = (argc == 3 && (!strcasecmp(argv[2],"verbose")));
-
- if (argc < 2 || argc > 3 || (argc == 3 && !concise && !verbose))
- return RESULT_SHOWUSAGE;
-
- if (!concise && !verbose)
- ast_cli(fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
- else if (verbose)
- ast_cli(fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data",
- "CallerID", "Duration", "Accountcode", "BridgedTo");
-
- while ((c = ast_channel_walk_locked(c)) != NULL) {
- struct ast_channel *bc = ast_bridged_channel(c);
- if ((concise || verbose) && c->cdr && !ast_tvzero(c->cdr->start)) {
- duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
- if (verbose) {
- durh = duration / 3600;
- durm = (duration % 3600) / 60;
- durs = duration % 60;
- snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
- } else {
- snprintf(durbuf, sizeof(durbuf), "%d", duration);
- }
- } else {
- durbuf[0] = '\0';
- }
- if (concise) {
- ast_cli(fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
- c->appl ? c->appl : "(None)",
- S_OR(c->data, ""), /* XXX different from verbose ? */
- S_OR(c->cid.cid_num, ""),
- S_OR(c->accountcode, ""),
- c->amaflags,
- durbuf,
- bc ? bc->name : "(None)");
- } else if (verbose) {
- ast_cli(fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
- c->appl ? c->appl : "(None)",
- c->data ? S_OR(c->data, "(Empty)" ): "(None)",
- S_OR(c->cid.cid_num, ""),
- durbuf,
- S_OR(c->accountcode, ""),
- bc ? bc->name : "(None)");
- } else {
- if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten))
- snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority);
- else
- strcpy(locbuf, "(None)");
- if (c->appl)
- snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, c->data ? c->data : "");
- else
- strcpy(appdata, "(None)");
- ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata);
- }
- numchans++;
- ast_channel_unlock(c);
- }
- if (!concise) {
- ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans));
- if (option_maxcalls)
- ast_cli(fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
- ast_active_calls(), option_maxcalls, ESS(ast_active_calls()),
- ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
- else
- ast_cli(fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_chanlist(int fd, int argc, char *argv[])
-{
- struct ast_channel *c = NULL;
- char durbuf[10] = "-";
- char locbuf[40];
- char appdata[40];
- int duration;
- int durh, durm, durs;
- int numchans = 0, concise = 0, verbose = 0;
-
- concise = (argc == 4 && (!strcasecmp(argv[3],"concise")));
- verbose = (argc == 4 && (!strcasecmp(argv[3],"verbose")));
-
- if (argc < 3 || argc > 4 || (argc == 4 && !concise && !verbose))
- return RESULT_SHOWUSAGE;
-
- if (!concise && !verbose)
- ast_cli(fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
- else if (verbose)
- ast_cli(fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data",
- "CallerID", "Duration", "Accountcode", "BridgedTo");
-
- while ((c = ast_channel_walk_locked(c)) != NULL) {
- struct ast_channel *bc = ast_bridged_channel(c);
- if ((concise || verbose) && c->cdr && !ast_tvzero(c->cdr->start)) {
- duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
- if (verbose) {
- durh = duration / 3600;
- durm = (duration % 3600) / 60;
- durs = duration % 60;
- snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
- } else {
- snprintf(durbuf, sizeof(durbuf), "%d", duration);
- }
- } else {
- durbuf[0] = '\0';
- }
- if (concise) {
- ast_cli(fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
- c->appl ? c->appl : "(None)",
- S_OR(c->data, ""), /* XXX different from verbose ? */
- S_OR(c->cid.cid_num, ""),
- S_OR(c->accountcode, ""),
- c->amaflags,
- durbuf,
- bc ? bc->name : "(None)");
- } else if (verbose) {
- ast_cli(fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
- c->appl ? c->appl : "(None)",
- c->data ? S_OR(c->data, "(Empty)" ): "(None)",
- S_OR(c->cid.cid_num, ""),
- durbuf,
- S_OR(c->accountcode, ""),
- bc ? bc->name : "(None)");
- } else {
- if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten))
- snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority);
- else
- strcpy(locbuf, "(None)");
- if (c->appl)
- snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, c->data ? c->data : "");
- else
- strcpy(appdata, "(None)");
- ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata);
- }
- numchans++;
- ast_channel_unlock(c);
- }
- if (!concise) {
- ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans));
- if (option_maxcalls)
- ast_cli(fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
- ast_active_calls(), option_maxcalls, ESS(ast_active_calls()),
- ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
- else
- ast_cli(fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
- }
- return RESULT_SUCCESS;
-}
-
-#undef FORMAT_STRING
-#undef FORMAT_STRING2
-#undef CONCISE_FORMAT_STRING
-#undef VERBOSE_FORMAT_STRING
-#undef VERBOSE_FORMAT_STRING2
-
-static char showchan_help[] =
-"Usage: core show channel <channel>\n"
-" Shows lots of information about the specified channel.\n";
-
-static char debugchan_help[] =
-"Usage: core set debug channel <channel> [off]\n"
-" Enables/disables debugging on a specific channel.\n";
-
-static char commandcomplete_help[] =
-"Usage: _command complete \"<line>\" text state\n"
-" This function is used internally to help with command completion and should.\n"
-" never be called by the user directly.\n";
-
-static char commandnummatches_help[] =
-"Usage: _command nummatches \"<line>\" text \n"
-" This function is used internally to help with command completion and should.\n"
-" never be called by the user directly.\n";
-
-static char commandmatchesarray_help[] =
-"Usage: _command matchesarray \"<line>\" text \n"
-" This function is used internally to help with command completion and should.\n"
-" never be called by the user directly.\n";
-
-static int handle_softhangup(int fd, int argc, char *argv[])
-{
- struct ast_channel *c=NULL;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- c = ast_get_channel_by_name_locked(argv[2]);
- if (c) {
- ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name);
- ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(c);
- } else
- ast_cli(fd, "%s is not a known channel\n", argv[2]);
- return RESULT_SUCCESS;
-}
-
-static char *__ast_cli_generator(const char *text, const char *word, int state, int lock);
-
-static int handle_commandmatchesarray(int fd, int argc, char *argv[])
-{
- char *buf, *obuf;
- int buflen = 2048;
- int len = 0;
- char **matches;
- int x, matchlen;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (!(buf = ast_malloc(buflen)))
- return RESULT_FAILURE;
- buf[len] = '\0';
- matches = ast_cli_completion_matches(argv[2], argv[3]);
- if (matches) {
- for (x=0; matches[x]; x++) {
- matchlen = strlen(matches[x]) + 1;
- if (len + matchlen >= buflen) {
- buflen += matchlen * 3;
- obuf = buf;
- if (!(buf = ast_realloc(obuf, buflen)))
- /* Memory allocation failure... Just free old buffer and be done */
- free(obuf);
- }
- if (buf)
- len += sprintf( buf + len, "%s ", matches[x]);
- free(matches[x]);
- matches[x] = NULL;
- }
- free(matches);
- }
-
- if (buf) {
- ast_cli(fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
- free(buf);
- } else
- ast_cli(fd, "NULL\n");
-
- return RESULT_SUCCESS;
-}
-
-
-
-static int handle_commandnummatches(int fd, int argc, char *argv[])
-{
- int matches = 0;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- matches = ast_cli_generatornummatches(argv[2], argv[3]);
-
- ast_cli(fd, "%d", matches);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_commandcomplete(int fd, int argc, char *argv[])
-{
- char *buf;
-
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- buf = __ast_cli_generator(argv[2], argv[3], atoi(argv[4]), 0);
- if (buf) {
- ast_cli(fd, buf);
- free(buf);
- } else
- ast_cli(fd, "NULL\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_debugchan_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_channel *c=NULL;
- int is_all;
-
- /* 'debug channel {all|chan_id}' */
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- is_all = !strcasecmp("all", argv[2]);
- if (is_all) {
- global_fin |= DEBUGCHAN_FLAG;
- global_fout |= DEBUGCHAN_FLAG;
- c = ast_channel_walk_locked(NULL);
- } else {
- c = ast_get_channel_by_name_locked(argv[2]);
- if (c == NULL)
- ast_cli(fd, "No such channel %s\n", argv[2]);
- }
- while (c) {
- if (!(c->fin & DEBUGCHAN_FLAG) || !(c->fout & DEBUGCHAN_FLAG)) {
- c->fin |= DEBUGCHAN_FLAG;
- c->fout |= DEBUGCHAN_FLAG;
- ast_cli(fd, "Debugging enabled on channel %s\n", c->name);
- }
- ast_channel_unlock(c);
- if (!is_all)
- break;
- c = ast_channel_walk_locked(c);
- }
- ast_cli(fd, "Debugging on new channels is enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_core_set_debug_channel(int fd, int argc, char *argv[])
-{
- struct ast_channel *c = NULL;
- int is_all, is_off = 0;
-
- /* 'core set debug channel {all|chan_id}' */
- if (argc == 6 && strcmp(argv[5], "off") == 0)
- is_off = 1;
- else if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- is_all = !strcasecmp("all", argv[4]);
- if (is_all) {
- if (is_off) {
- global_fin &= ~DEBUGCHAN_FLAG;
- global_fout &= ~DEBUGCHAN_FLAG;
- } else {
- global_fin |= DEBUGCHAN_FLAG;
- global_fout |= DEBUGCHAN_FLAG;
- }
- c = ast_channel_walk_locked(NULL);
- } else {
- c = ast_get_channel_by_name_locked(argv[4]);
- if (c == NULL)
- ast_cli(fd, "No such channel %s\n", argv[4]);
- }
- while (c) {
- if (!(c->fin & DEBUGCHAN_FLAG) || !(c->fout & DEBUGCHAN_FLAG)) {
- if (is_off) {
- c->fin &= ~DEBUGCHAN_FLAG;
- c->fout &= ~DEBUGCHAN_FLAG;
- } else {
- c->fin |= DEBUGCHAN_FLAG;
- c->fout |= DEBUGCHAN_FLAG;
- }
- ast_cli(fd, "Debugging %s on channel %s\n", is_off ? "disabled" : "enabled", c->name);
- }
- ast_channel_unlock(c);
- if (!is_all)
- break;
- c = ast_channel_walk_locked(c);
- }
- ast_cli(fd, "Debugging on new channels is %s\n", is_off ? "disabled" : "enabled");
- return RESULT_SUCCESS;
-}
-
-static int handle_nodebugchan_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_channel *c=NULL;
- int is_all;
- /* 'no debug channel {all|chan_id}' */
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- is_all = !strcasecmp("all", argv[3]);
- if (is_all) {
- global_fin &= ~DEBUGCHAN_FLAG;
- global_fout &= ~DEBUGCHAN_FLAG;
- c = ast_channel_walk_locked(NULL);
- } else {
- c = ast_get_channel_by_name_locked(argv[3]);
- if (c == NULL)
- ast_cli(fd, "No such channel %s\n", argv[3]);
- }
- while(c) {
- if ((c->fin & DEBUGCHAN_FLAG) || (c->fout & DEBUGCHAN_FLAG)) {
- c->fin &= ~DEBUGCHAN_FLAG;
- c->fout &= ~DEBUGCHAN_FLAG;
- ast_cli(fd, "Debugging disabled on channel %s\n", c->name);
- }
- ast_channel_unlock(c);
- if (!is_all)
- break;
- c = ast_channel_walk_locked(c);
- }
- ast_cli(fd, "Debugging on new channels is disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_showchan_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_channel *c=NULL;
- struct timeval now;
- char buf[2048];
- char cdrtime[256];
- char nf[256], wf[256], rf[256];
- long elapsed_seconds=0;
- int hour=0, min=0, sec=0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- now = ast_tvnow();
- c = ast_get_channel_by_name_locked(argv[2]);
- if (!c) {
- ast_cli(fd, "%s is not a known channel\n", argv[2]);
- return RESULT_SUCCESS;
- }
- if(c->cdr) {
- elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
- hour = elapsed_seconds / 3600;
- min = (elapsed_seconds % 3600) / 60;
- sec = elapsed_seconds % 60;
- snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
- } else
- strcpy(cdrtime, "N/A");
- ast_cli(fd,
- " -- General --\n"
- " Name: %s\n"
- " Type: %s\n"
- " UniqueID: %s\n"
- " Caller ID: %s\n"
- " Caller ID Name: %s\n"
- " DNID Digits: %s\n"
- " State: %s (%d)\n"
- " Rings: %d\n"
- " NativeFormats: %s\n"
- " WriteFormat: %s\n"
- " ReadFormat: %s\n"
- " WriteTranscode: %s\n"
- " ReadTranscode: %s\n"
- "1st File Descriptor: %d\n"
- " Frames in: %d%s\n"
- " Frames out: %d%s\n"
- " Time to Hangup: %ld\n"
- " Elapsed Time: %s\n"
- " Direct Bridge: %s\n"
- "Indirect Bridge: %s\n"
- " -- PBX --\n"
- " Context: %s\n"
- " Extension: %s\n"
- " Priority: %d\n"
- " Call Group: %llu\n"
- " Pickup Group: %llu\n"
- " Application: %s\n"
- " Data: %s\n"
- " Blocking in: %s\n",
- c->name, c->tech->type, c->uniqueid,
- S_OR(c->cid.cid_num, "(N/A)"),
- S_OR(c->cid.cid_name, "(N/A)"),
- S_OR(c->cid.cid_dnid, "(N/A)"), ast_state2str(c->_state), c->_state, c->rings,
- ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats),
- ast_getformatname_multiple(wf, sizeof(wf), c->writeformat),
- ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
- c->writetrans ? "Yes" : "No",
- c->readtrans ? "Yes" : "No",
- c->fds[0],
- c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
- c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
- (long)c->whentohangup,
- cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>",
- c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
- ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
- (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
-
- if(pbx_builtin_serialize_variables(c,buf,sizeof(buf)))
- ast_cli(fd," Variables:\n%s\n",buf);
- if(c->cdr && ast_cdr_serialize_variables(c->cdr,buf, sizeof(buf), '=', '\n', 1))
- ast_cli(fd," CDR Variables:\n%s\n",buf);
-
- ast_channel_unlock(c);
- return RESULT_SUCCESS;
-}
-
-static int handle_showchan(int fd, int argc, char *argv[])
-{
- struct ast_channel *c=NULL;
- struct timeval now;
- char buf[2048];
- char cdrtime[256];
- char nf[256], wf[256], rf[256];
- long elapsed_seconds=0;
- int hour=0, min=0, sec=0;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- now = ast_tvnow();
- c = ast_get_channel_by_name_locked(argv[3]);
- if (!c) {
- ast_cli(fd, "%s is not a known channel\n", argv[3]);
- return RESULT_SUCCESS;
- }
- if(c->cdr) {
- elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
- hour = elapsed_seconds / 3600;
- min = (elapsed_seconds % 3600) / 60;
- sec = elapsed_seconds % 60;
- snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
- } else
- strcpy(cdrtime, "N/A");
- ast_cli(fd,
- " -- General --\n"
- " Name: %s\n"
- " Type: %s\n"
- " UniqueID: %s\n"
- " Caller ID: %s\n"
- " Caller ID Name: %s\n"
- " DNID Digits: %s\n"
- " State: %s (%d)\n"
- " Rings: %d\n"
- " NativeFormats: %s\n"
- " WriteFormat: %s\n"
- " ReadFormat: %s\n"
- " WriteTranscode: %s\n"
- " ReadTranscode: %s\n"
- "1st File Descriptor: %d\n"
- " Frames in: %d%s\n"
- " Frames out: %d%s\n"
- " Time to Hangup: %ld\n"
- " Elapsed Time: %s\n"
- " Direct Bridge: %s\n"
- "Indirect Bridge: %s\n"
- " -- PBX --\n"
- " Context: %s\n"
- " Extension: %s\n"
- " Priority: %d\n"
- " Call Group: %llu\n"
- " Pickup Group: %llu\n"
- " Application: %s\n"
- " Data: %s\n"
- " Blocking in: %s\n",
- c->name, c->tech->type, c->uniqueid,
- S_OR(c->cid.cid_num, "(N/A)"),
- S_OR(c->cid.cid_name, "(N/A)"),
- S_OR(c->cid.cid_dnid, "(N/A)"), ast_state2str(c->_state), c->_state, c->rings,
- ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats),
- ast_getformatname_multiple(wf, sizeof(wf), c->writeformat),
- ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
- c->writetrans ? "Yes" : "No",
- c->readtrans ? "Yes" : "No",
- c->fds[0],
- c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
- c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
- (long)c->whentohangup,
- cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>",
- c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
- ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
- (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
-
- if(pbx_builtin_serialize_variables(c,buf,sizeof(buf)))
- ast_cli(fd," Variables:\n%s\n",buf);
- if(c->cdr && ast_cdr_serialize_variables(c->cdr,buf, sizeof(buf), '=', '\n', 1))
- ast_cli(fd," CDR Variables:\n%s\n",buf);
-
- ast_channel_unlock(c);
- return RESULT_SUCCESS;
-}
-
-/*
- * helper function to generate CLI matches from a fixed set of values.
- * A NULL word is acceptable.
- */
-char *ast_cli_complete(const char *word, char *const choices[], int state)
-{
- int i, which = 0, len;
- len = ast_strlen_zero(word) ? 0 : strlen(word);
-
- for (i = 0; choices[i]; i++) {
- if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
- return ast_strdup(choices[i]);
- }
- return NULL;
-}
-
-static char *complete_show_channels_deprecated(const char *line, const char *word, int pos, int state)
-{
- static char *choices[] = { "concise", "verbose", NULL };
-
- return (pos != 2) ? NULL : ast_cli_complete(word, choices, state);
-}
-
-static char *complete_show_channels(const char *line, const char *word, int pos, int state)
-{
- static char *choices[] = { "concise", "verbose", NULL };
-
- return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);
-}
-
-char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
-{
- struct ast_channel *c = NULL;
- int which = 0;
- int wordlen;
- char notfound = '\0';
- char *ret = &notfound; /* so NULL can break the loop */
-
- if (pos != rpos)
- return NULL;
-
- wordlen = strlen(word);
-
- while (ret == &notfound && (c = ast_channel_walk_locked(c))) {
- if (!strncasecmp(word, c->name, wordlen) && ++which > state)
- ret = ast_strdup(c->name);
- ast_channel_unlock(c);
- }
- return ret == &notfound ? NULL : ret;
-}
-
-static char *complete_ch_3(const char *line, const char *word, int pos, int state)
-{
- return ast_complete_channels(line, word, pos, state, 2);
-}
-
-static char *complete_ch_4(const char *line, const char *word, int pos, int state)
-{
- return ast_complete_channels(line, word, pos, state, 3);
-}
-
-static char *complete_ch_5(const char *line, const char *word, int pos, int state)
-{
- return ast_complete_channels(line, word, pos, state, 4);
-}
-
-static char *complete_mod_2(const char *line, const char *word, int pos, int state)
-{
- return ast_module_helper(line, word, pos, state, 1, 1);
-}
-
-static char *complete_mod_3_nr(const char *line, const char *word, int pos, int state)
-{
- return ast_module_helper(line, word, pos, state, 2, 0);
-}
-
-static char *complete_mod_3(const char *line, const char *word, int pos, int state)
-{
- return ast_module_helper(line, word, pos, state, 2, 1);
-}
-
-static char *complete_mod_4(const char *line, const char *word, int pos, int state)
-{
- return ast_module_helper(line, word, pos, state, 3, 0);
-}
-
-static char *complete_fn_2(const char *line, const char *word, int pos, int state)
-{
- char *c, *d;
- char filename[256];
-
- if (pos != 1)
- return NULL;
-
- if (word[0] == '/')
- ast_copy_string(filename, word, sizeof(filename));
- else
- snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
-
- c = d = filename_completion_function(filename, state);
-
- if (c && word[0] != '/')
- c += (strlen(ast_config_AST_MODULE_DIR) + 1);
- if (c)
- c = strdup(c);
- free(d);
-
- return c;
-}
-
-static char *complete_fn_3(const char *line, const char *word, int pos, int state)
-{
- char *c, *d;
- char filename[256];
-
- if (pos != 2)
- return NULL;
-
- if (word[0] == '/')
- ast_copy_string(filename, word, sizeof(filename));
- else
- snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
-
- c = d = filename_completion_function(filename, state);
-
- if (c && word[0] != '/')
- c += (strlen(ast_config_AST_MODULE_DIR) + 1);
- if (c)
- c = strdup(c);
- free(d);
-
- return c;
-}
-
-static int group_show_channels(int fd, int argc, char *argv[])
-{
-#define FORMAT_STRING "%-25s %-20s %-20s\n"
-
- struct ast_group_info *gi = NULL;
- int numchans = 0;
- regex_t regexbuf;
- int havepattern = 0;
-
- if (argc < 3 || argc > 4)
- return RESULT_SHOWUSAGE;
-
- if (argc == 4) {
- if (regcomp(&regexbuf, argv[3], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- havepattern = 1;
- }
-
- ast_cli(fd, FORMAT_STRING, "Channel", "Group", "Category");
-
- ast_app_group_list_lock();
-
- gi = ast_app_group_list_head();
- while (gi) {
- if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
- ast_cli(fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
- numchans++;
- }
- gi = AST_LIST_NEXT(gi, list);
- }
-
- ast_app_group_list_unlock();
-
- if (havepattern)
- regfree(&regexbuf);
-
- ast_cli(fd, "%d active channel%s\n", numchans, (numchans != 1) ? "s" : "");
- return RESULT_SUCCESS;
-#undef FORMAT_STRING
-}
-
-static int handle_help(int fd, int argc, char *argv[]);
-
-static char * complete_help(const char *text, const char *word, int pos, int state)
-{
- /* skip first 4 or 5 chars, "help "*/
- int l = strlen(text);
-
- if (l > 5)
- l = 5;
- text += l;
- /* XXX watch out, should stop to the non-generator parts */
- return __ast_cli_generator(text, word, state, 0);
-}
-
-/* XXX Nothing in this array can currently be deprecated...
- You have to change the way find_cli works in order to remove this array
- I recommend doing this eventually...
- */
-static struct ast_cli_entry builtins[] = {
- /* Keep alphabetized, with longer matches first (example: abcd before abc) */
- { { "_command", "complete", NULL },
- handle_commandcomplete, "Command complete",
- commandcomplete_help },
-
- { { "_command", "nummatches", NULL },
- handle_commandnummatches, "Returns number of command matches",
- commandnummatches_help },
-
- { { "_command", "matchesarray", NULL },
- handle_commandmatchesarray, "Returns command matches array",
- commandmatchesarray_help },
-
- { { NULL }, NULL, NULL, NULL }
-};
-
-static struct ast_cli_entry cli_debug_channel_deprecated = {
- { "debug", "channel", NULL },
- handle_debugchan_deprecated, NULL,
- NULL, complete_ch_3 };
-
-static struct ast_cli_entry cli_debug_level_deprecated = {
- { "debug", "level", NULL },
- handle_debuglevel_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_set_debug_deprecated = {
- { "set", "debug", NULL },
- handle_set_debug_deprecated, NULL,
- NULL, NULL, &cli_debug_level_deprecated };
-
-static struct ast_cli_entry cli_set_verbose_deprecated = {
- { "set", "verbose", NULL },
- handle_set_verbose_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_channel_deprecated = {
- { "show", "channel", NULL },
- handle_showchan_deprecated, NULL,
- NULL, complete_ch_3 };
-
-static struct ast_cli_entry cli_show_channels_deprecated = {
- { "show", "channels", NULL },
- handle_chanlist_deprecated, NULL,
- NULL, complete_show_channels_deprecated };
-
-static struct ast_cli_entry cli_show_modules_deprecated = {
- { "show", "modules", NULL },
- handle_modlist, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_modules_like_deprecated = {
- { "show", "modules", "like", NULL },
- handle_modlist, NULL,
- NULL, complete_mod_4 };
-
-static struct ast_cli_entry cli_module_load_deprecated = {
- { "load", NULL },
- handle_load_deprecated, NULL,
- NULL, complete_fn_2 };
-
-static struct ast_cli_entry cli_module_reload_deprecated = {
- { "reload", NULL },
- handle_reload_deprecated, NULL,
- NULL, complete_mod_2 };
-
-static struct ast_cli_entry cli_module_unload_deprecated = {
- { "unload", NULL },
- handle_unload_deprecated, NULL,
- NULL, complete_mod_2 };
-
-static struct ast_cli_entry cli_show_uptime_deprecated = {
- { "show", "uptime", NULL },
- handle_showuptime_deprecated, "Show uptime information",
- NULL };
-
-static struct ast_cli_entry cli_cli[] = {
- /* Deprecated, but preferred command is now consolidated (and already has a deprecated command for it). */
- { { "no", "debug", "channel", NULL },
- handle_nodebugchan_deprecated, NULL,
- NULL, complete_ch_4 },
-
- { { "core", "show", "channels", NULL },
- handle_chanlist, "Display information on channels",
- chanlist_help, complete_show_channels, &cli_show_channels_deprecated },
-
- { { "core", "show", "channel", NULL },
- handle_showchan, "Display information on a specific channel",
- showchan_help, complete_ch_4, &cli_show_channel_deprecated },
-
- { { "core", "set", "debug", "channel", NULL },
- handle_core_set_debug_channel, "Enable/disable debugging on a channel",
- debugchan_help, complete_ch_5, &cli_debug_channel_deprecated },
-
- { { "core", "set", "debug", NULL },
- handle_set_debug, "Set level of debug chattiness",
- debug_help, NULL, &cli_set_debug_deprecated },
-
- { { "core", "set", "debug", "off", NULL },
- handle_nodebug, "Turns off debug chattiness",
- nodebug_help },
-
- { { "core", "set", "verbose", NULL },
- handle_verbose, "Set level of verboseness",
- verbose_help, NULL, &cli_set_verbose_deprecated },
-
- { { "group", "show", "channels", NULL },
- group_show_channels, "Display active channels with group(s)",
- group_show_channels_help },
-
- { { "help", NULL },
- handle_help, "Display help list, or specific help on a command",
- help_help, complete_help },
-
- { { "logger", "mute", NULL },
- handle_logger_mute, "Toggle logging output to a console",
- logger_mute_help },
-
- { { "module", "show", NULL },
- handle_modlist, "List modules and info",
- modlist_help, NULL, &cli_show_modules_deprecated },
-
- { { "module", "show", "like", NULL },
- handle_modlist, "List modules and info",
- modlist_help, complete_mod_4, &cli_show_modules_like_deprecated },
-
- { { "module", "load", NULL },
- handle_load, "Load a module by name",
- load_help, complete_fn_3, &cli_module_load_deprecated },
-
- { { "module", "reload", NULL },
- handle_reload, "Reload configuration",
- reload_help, complete_mod_3, &cli_module_reload_deprecated },
-
- { { "module", "unload", NULL },
- handle_unload, "Unload a module by name",
- unload_help, complete_mod_3_nr, &cli_module_unload_deprecated },
-
- { { "core", "show", "uptime", NULL },
- handle_showuptime, "Show uptime information",
- uptime_help, NULL, &cli_show_uptime_deprecated },
-
- { { "soft", "hangup", NULL },
- handle_softhangup, "Request a hangup on a given channel",
- softhangup_help, complete_ch_3 },
-};
-
-/*! \brief initialize the _full_cmd string in * each of the builtins. */
-void ast_builtins_init(void)
-{
- struct ast_cli_entry *e;
-
- for (e = builtins; e->cmda[0] != NULL; e++) {
- char buf[80];
- ast_join(buf, sizeof(buf), e->cmda);
- e->_full_cmd = strdup(buf);
- if (!e->_full_cmd)
- ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
- }
-
- ast_cli_register_multiple(cli_cli, sizeof(cli_cli) / sizeof(struct ast_cli_entry));
-}
-
-/*
- * We have two sets of commands: builtins are stored in a
- * NULL-terminated array of ast_cli_entry, whereas external
- * commands are in a list.
- * When navigating, we need to keep two pointers and get
- * the next one in lexicographic order. For the purpose,
- * we use a structure.
- */
-
-struct cli_iterator {
- struct ast_cli_entry *builtins;
- struct ast_cli_entry *helpers;
-};
-
-static struct ast_cli_entry *cli_next(struct cli_iterator *i)
-{
- struct ast_cli_entry *e;
-
- if (i->builtins == NULL && i->helpers == NULL) {
- /* initialize */
- i->builtins = builtins;
- i->helpers = AST_LIST_FIRST(&helpers);
- }
- e = i->builtins; /* temporary */
- if (!e->cmda[0] || (i->helpers &&
- strcmp(i->helpers->_full_cmd, e->_full_cmd) < 0)) {
- /* Use helpers */
- e = i->helpers;
- if (e)
- i->helpers = AST_LIST_NEXT(e, list);
- } else { /* use builtin. e is already set */
- (i->builtins)++; /* move to next */
- }
- return e;
-}
-
-/*!
- * \brief locate a cli command in the 'helpers' list (which must be locked).
- * exact has 3 values:
- * 0 returns if the search key is equal or longer than the entry.
- * -1 true if the mismatch is on the last word XXX not true!
- * 1 true only on complete, exact match.
- */
-static struct ast_cli_entry *find_cli(char *const cmds[], int match_type)
-{
- int matchlen = -1; /* length of longest match so far */
- struct ast_cli_entry *cand = NULL, *e=NULL;
- struct cli_iterator i = { NULL, NULL};
-
- while( (e = cli_next(&i)) ) {
- int y;
- for (y = 0 ; cmds[y] && e->cmda[y]; y++) {
- if (strcasecmp(e->cmda[y], cmds[y]))
- break;
- }
- if (e->cmda[y] == NULL) { /* no more words in candidate */
- if (cmds[y] == NULL) /* this is an exact match, cannot do better */
- break;
- /* here the search key is longer than the candidate */
- if (match_type != 0) /* but we look for almost exact match... */
- continue; /* so we skip this one. */
- /* otherwise we like it (case 0) */
- } else { /* still words in candidate */
- if (cmds[y] == NULL) /* search key is shorter, not good */
- continue;
- /* if we get here, both words exist but there is a mismatch */
- if (match_type == 0) /* not the one we look for */
- continue;
- if (match_type == 1) /* not the one we look for */
- continue;
- if (cmds[y+1] != NULL || e->cmda[y+1] != NULL) /* not the one we look for */
- continue;
- /* we are in case match_type == -1 and mismatch on last word */
- }
- if (y > matchlen) { /* remember the candidate */
- matchlen = y;
- cand = e;
- }
- }
- return e ? e : cand;
-}
-
-static char *find_best(char *argv[])
-{
- static char cmdline[80];
- int x;
- /* See how close we get, then print the candidate */
- char *myargv[AST_MAX_CMD_LEN];
- for (x=0;x<AST_MAX_CMD_LEN;x++)
- myargv[x]=NULL;
- AST_LIST_LOCK(&helpers);
- for (x=0;argv[x];x++) {
- myargv[x] = argv[x];
- if (!find_cli(myargv, -1))
- break;
- }
- AST_LIST_UNLOCK(&helpers);
- ast_join(cmdline, sizeof(cmdline), myargv);
- return cmdline;
-}
-
-static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed)
-{
- if (e->deprecate_cmd) {
- __ast_cli_unregister(e->deprecate_cmd, e);
- }
- if (e->inuse) {
- ast_log(LOG_WARNING, "Can't remove command that is in use\n");
- } else {
- AST_LIST_LOCK(&helpers);
- AST_LIST_REMOVE(&helpers, e, list);
- AST_LIST_UNLOCK(&helpers);
- free(e->_full_cmd);
- }
- return 0;
-}
-
-static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
-{
- struct ast_cli_entry *cur;
- char fulle[80] ="";
- int lf, ret = -1;
-
- ast_join(fulle, sizeof(fulle), e->cmda);
- AST_LIST_LOCK(&helpers);
-
- if (find_cli(e->cmda, 1)) {
- ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle);
- goto done;
- }
- e->_full_cmd = ast_strdup(fulle);
- if (!e->_full_cmd)
- goto done;
-
- if (ed) {
- e->deprecated = 1;
- e->summary = ed->summary;
- e->usage = ed->usage;
- /* XXX If command A deprecates command B, and command B deprecates command C...
- Do we want to show command A or command B when telling the user to use new syntax?
- This currently would show command A.
- To show command B, you just need to always use ed->_full_cmd.
- */
- e->_deprecated_by = S_OR(ed->_deprecated_by, ed->_full_cmd);
- } else {
- e->deprecated = 0;
- }
-
- lf = strlen(fulle);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
- int len = strlen(cur->_full_cmd);
- if (lf < len)
- len = lf;
- if (strncasecmp(fulle, cur->_full_cmd, len) < 0) {
- AST_LIST_INSERT_BEFORE_CURRENT(&helpers, e, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- if (!cur)
- AST_LIST_INSERT_TAIL(&helpers, e, list);
- ret = 0; /* success */
-
-done:
- AST_LIST_UNLOCK(&helpers);
-
- if (e->deprecate_cmd) {
- /* This command deprecates another command. Register that one also. */
- __ast_cli_register(e->deprecate_cmd, e);
- }
-
- return ret;
-}
-
-/* wrapper function, so we can unregister deprecated commands recursively */
-int ast_cli_unregister(struct ast_cli_entry *e)
-{
- return __ast_cli_unregister(e, NULL);
-}
-
-/* wrapper function, so we can register deprecated commands recursively */
-int ast_cli_register(struct ast_cli_entry *e)
-{
- return __ast_cli_register(e, NULL);
-}
-
-/*
- * register/unregister an array of entries.
- */
-void ast_cli_register_multiple(struct ast_cli_entry *e, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- ast_cli_register(e + i);
-}
-
-void ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- ast_cli_unregister(e + i);
-}
-
-
-/*! \brief helper for help_workhorse and final part of handle_help
- * if locked = 0 it's just help_workhorse, otherwise assume the
- * list is already locked.
- */
-static int help1(int fd, char *match[], int locked)
-{
- char matchstr[80] = "";
- struct ast_cli_entry *e;
- int len = 0;
- int found = 0;
- struct cli_iterator i = { NULL, NULL};
-
- if (match) {
- ast_join(matchstr, sizeof(matchstr), match);
- len = strlen(matchstr);
- }
- if (!locked)
- AST_LIST_LOCK(&helpers);
- while ( (e = cli_next(&i)) ) {
- /* Hide commands that start with '_' */
- if (e->_full_cmd[0] == '_')
- continue;
- /* Hide commands that are marked as deprecated. */
- if (e->deprecated)
- continue;
- if (match && strncasecmp(matchstr, e->_full_cmd, len))
- continue;
- ast_cli(fd, "%25.25s %s\n", e->_full_cmd, S_OR(e->summary, ""));
- found++;
- }
- if (!locked)
- AST_LIST_UNLOCK(&helpers);
- if (!found && matchstr[0])
- ast_cli(fd, "No such command '%s'.\n", matchstr);
- return RESULT_SUCCESS;
-}
-
-static int help_workhorse(int fd, char *match[])
-{
- return help1(fd, match, 0 /* do not print errors */);
-}
-
-static int handle_help(int fd, int argc, char *argv[])
-{
- char fullcmd[80];
- struct ast_cli_entry *e;
- int res = RESULT_SUCCESS;
-
- if (argc < 1)
- return RESULT_SHOWUSAGE;
- if (argc == 1)
- return help_workhorse(fd, NULL);
-
- AST_LIST_LOCK(&helpers);
- e = find_cli(argv + 1, 1); /* try exact match first */
- if (!e) {
- res = help1(fd, argv + 1, 1 /* locked */);
- AST_LIST_UNLOCK(&helpers);
- return res;
- }
- if (e->usage)
- ast_cli(fd, "%s", e->usage);
- else {
- ast_join(fullcmd, sizeof(fullcmd), argv+1);
- ast_cli(fd, "No help text available for '%s'.\n", fullcmd);
- }
- AST_LIST_UNLOCK(&helpers);
- return res;
-}
-
-static char *parse_args(const char *s, int *argc, char *argv[], int max, int *trailingwhitespace)
-{
- char *dup, *cur;
- int x = 0;
- int quoted = 0;
- int escaped = 0;
- int whitespace = 1;
-
- *trailingwhitespace = 0;
- if (s == NULL) /* invalid, though! */
- return NULL;
- /* make a copy to store the parsed string */
- if (!(dup = ast_strdup(s)))
- return NULL;
-
- cur = dup;
- /* scan the original string copying into cur when needed */
- for (; *s ; s++) {
- if (x >= max - 1) {
- ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
- break;
- }
- if (*s == '"' && !escaped) {
- quoted = !quoted;
- if (quoted && whitespace) {
- /* start a quoted string from previous whitespace: new argument */
- argv[x++] = cur;
- whitespace = 0;
- }
- } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
- /* If we are not already in whitespace, and not in a quoted string or
- processing an escape sequence, and just entered whitespace, then
- finalize the previous argument and remember that we are in whitespace
- */
- if (!whitespace) {
- *cur++ = '\0';
- whitespace = 1;
- }
- } else if (*s == '\\' && !escaped) {
- escaped = 1;
- } else {
- if (whitespace) {
- /* we leave whitespace, and are not quoted. So it's a new argument */
- argv[x++] = cur;
- whitespace = 0;
- }
- *cur++ = *s;
- escaped = 0;
- }
- }
- /* Null terminate */
- *cur++ = '\0';
- /* XXX put a NULL in the last argument, because some functions that take
- * the array may want a null-terminated array.
- * argc still reflects the number of non-NULL entries.
- */
- argv[x] = NULL;
- *argc = x;
- *trailingwhitespace = whitespace;
- return dup;
-}
-
-/*! \brief Return the number of unique matches for the generator */
-int ast_cli_generatornummatches(const char *text, const char *word)
-{
- int matches = 0, i = 0;
- char *buf = NULL, *oldbuf = NULL;
-
- while ((buf = ast_cli_generator(text, word, i++))) {
- if (!oldbuf || strcmp(buf,oldbuf))
- matches++;
- if (oldbuf)
- free(oldbuf);
- oldbuf = buf;
- }
- if (oldbuf)
- free(oldbuf);
- return matches;
-}
-
-char **ast_cli_completion_matches(const char *text, const char *word)
-{
- char **match_list = NULL, *retstr, *prevstr;
- size_t match_list_len, max_equal, which, i;
- int matches = 0;
-
- /* leave entry 0 free for the longest common substring */
- match_list_len = 1;
- while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
- if (matches + 1 >= match_list_len) {
- match_list_len <<= 1;
- if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list))))
- return NULL;
- }
- match_list[++matches] = retstr;
- }
-
- if (!match_list)
- return match_list; /* NULL */
-
- /* Find the longest substring that is common to all results
- * (it is a candidate for completion), and store a copy in entry 0.
- */
- prevstr = match_list[1];
- max_equal = strlen(prevstr);
- for (which = 2; which <= matches; which++) {
- for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
- continue;
- max_equal = i;
- }
-
- if (!(retstr = ast_malloc(max_equal + 1)))
- return NULL;
-
- ast_copy_string(retstr, match_list[1], max_equal + 1);
- match_list[0] = retstr;
-
- /* ensure that the array is NULL terminated */
- if (matches + 1 >= match_list_len) {
- if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list))))
- return NULL;
- }
- match_list[matches + 1] = NULL;
-
- return match_list;
-}
-
-static char *__ast_cli_generator(const char *text, const char *word, int state, int lock)
-{
- char *argv[AST_MAX_ARGS];
- struct ast_cli_entry *e;
- struct cli_iterator i = { NULL, NULL };
- int x = 0, argindex, matchlen;
- int matchnum=0;
- char *ret = NULL;
- char matchstr[80] = "";
- int tws = 0;
- char *dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws);
-
- if (!dup) /* error */
- return NULL;
- argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
- /* rebuild the command, ignore tws */
- ast_join(matchstr, sizeof(matchstr)-1, argv);
- matchlen = strlen(matchstr);
- if (tws) {
- strcat(matchstr, " "); /* XXX */
- if (matchlen)
- matchlen++;
- }
- if (lock)
- AST_LIST_LOCK(&helpers);
- while( !ret && (e = cli_next(&i)) ) {
- int lc = strlen(e->_full_cmd);
- if (e->_full_cmd[0] != '_' && lc > 0 && matchlen <= lc &&
- !strncasecmp(matchstr, e->_full_cmd, matchlen)) {
- /* Found initial part, return a copy of the next word... */
- if (e->cmda[argindex] && ++matchnum > state)
- ret = strdup(e->cmda[argindex]); /* we need a malloced string */
- } else if (e->generator && !strncasecmp(matchstr, e->_full_cmd, lc) && matchstr[lc] < 33) {
- /* We have a command in its entirity within us -- theoretically only one
- command can have this occur */
- ret = e->generator(matchstr, word, argindex, state);
- }
- }
- if (lock)
- AST_LIST_UNLOCK(&helpers);
- free(dup);
- return ret;
-}
-
-char *ast_cli_generator(const char *text, const char *word, int state)
-{
- return __ast_cli_generator(text, word, state, 1);
-}
-
-int ast_cli_command(int fd, const char *s)
-{
- char *argv[AST_MAX_ARGS];
- struct ast_cli_entry *e;
- int x;
- char *dup;
- int tws;
-
- if (!(dup = parse_args(s, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws)))
- return -1;
-
- /* We need at least one entry, or ignore */
- if (x > 0) {
- AST_LIST_LOCK(&helpers);
- e = find_cli(argv, 0);
- if (e)
- e->inuse++;
- AST_LIST_UNLOCK(&helpers);
- if (e) {
- switch(e->handler(fd, x, argv)) {
- case RESULT_SHOWUSAGE:
- if (e->usage)
- ast_cli(fd, "%s", e->usage);
- else
- ast_cli(fd, "Invalid usage, but no usage information available.\n");
- AST_LIST_LOCK(&helpers);
- if (e->deprecated)
- ast_cli(fd, "The '%s' command is deprecated and will be removed in a future release. Please use '%s' instead.\n", e->_full_cmd, e->_deprecated_by);
- AST_LIST_UNLOCK(&helpers);
- break;
- default:
- AST_LIST_LOCK(&helpers);
- if (e->deprecated == 1) {
- ast_cli(fd, "The '%s' command is deprecated and will be removed in a future release. Please use '%s' instead.\n", e->_full_cmd, e->_deprecated_by);
- e->deprecated = 2;
- }
- AST_LIST_UNLOCK(&helpers);
- break;
- }
- } else
- ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
- if (e)
- ast_atomic_fetchadd_int(&e->inuse, -1);
- }
- free(dup);
-
- return 0;
-}
-
-int ast_cli_command_multiple(int fd, size_t size, const char *s)
-{
- char cmd[512];
- int x, y = 0, count = 0;
-
- for (x = 0; x < size; x++) {
- cmd[y] = s[x];
- y++;
- if (s[x] == '\0') {
- ast_cli_command(fd, cmd);
- y = 0;
- count++;
- }
- }
- return count;
-}
diff --git a/1.4/main/coef_in.h b/1.4/main/coef_in.h
deleted file mode 100644
index 9aba022f6..000000000
--- a/1.4/main/coef_in.h
+++ /dev/null
@@ -1,13 +0,0 @@
- { { 1.8229206611e-04,-7.8997325866e-01,2.2401819940e+00,-4.6751353581e+00,5.5080745712e+00,-5.0571565772e+00,2.6215820004e+00,0.0000000000e+00,
- }, { 9.8532175289e-02,-5.6297236492e-02,3.3146713415e-01,-9.2239200436e-01,1.4844365184e+00,-2.0183258642e+00,2.0074154497e+00,0.0000000000e+00,
- }, }, { { 1.8229206610e-04,-7.8997325866e-01,7.7191410839e-01,-2.8075643964e+00,1.6948618347e+00,-3.0367273700e+00,9.0333559408e-01,0.0000000000e+00,
- }, { 9.8531161839e-02,-5.6297236492e-02,1.1421579050e-01,-4.8122536483e-01,4.0121072432e-01,-7.4834487567e-01,6.9170822332e-01,0.0000000000e+00,
- }, }, { { 1.8229206611e-04,-7.8997325866e-01,2.9003821430e+00,-6.1082779024e+00,7.7169345751e+00,-6.6075999680e+00,3.3941838836e+00,0.0000000000e+00,
- }, { 9.8539686961e-02,-5.6297236492e-02,4.2915323820e-01,-1.2609358633e+00,2.2399213250e+00,-2.9928879142e+00,2.5990173742e+00,0.0000000000e+00,
- }, }, { { 1.8229206610e-04,-7.8997325866e-01,-7.7191410839e-01,-2.8075643964e+00,-1.6948618347e+00,-3.0367273700e+00,-9.0333559408e-01,0.0000000000e+00,
- }, { 9.8531161839e-02,-5.6297236492e-02,-1.1421579050e-01,-4.8122536483e-01,-4.0121072432e-01,-7.4834487567e-01,-6.9170822332e-01,0.0000000000e+00,
- }, }, { { 1.8229206611e-04,-7.8997325866e-01,2.5782298908e+00,-5.3629717478e+00,6.5890882172e+00,-5.8012914776e+00,3.0171839130e+00,0.0000000000e+00,
- }, { 9.8534230718e-02,-5.6297236492e-02,3.8148618075e-01,-1.0848760410e+00,1.8441165168e+00,-2.4860666655e+00,2.3103384142e+00,0.0000000000e+00,
- }, }, { { 1.8229206610e-04,-7.8997325866e-01,-3.8715051001e-01,-2.6192408538e+00,-8.3977994034e-01,-2.8329897913e+00,-4.5306444352e-01,0.0000000000e+00,
- }, { 9.8531160936e-02,-5.6297236492e-02,-5.7284484199e-02,-4.3673866734e-01,-1.9564766257e-01,-6.2028156584e-01,-3.4692356122e-01,0.0000000000e+00,
- }, },
diff --git a/1.4/main/coef_out.h b/1.4/main/coef_out.h
deleted file mode 100644
index d80f5c490..000000000
--- a/1.4/main/coef_out.h
+++ /dev/null
@@ -1,4 +0,0 @@
- { 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00,
- }, { 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00
- },
-
diff --git a/1.4/main/config.c b/1.4/main/config.c
deleted file mode 100644
index 00cc0d836..000000000
--- a/1.4/main/config.c
+++ /dev/null
@@ -1,1514 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Configuration File Parser
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * Includes the Asterisk Realtime API - ARA
- * See doc/realtime.txt and doc/extconfig.txt
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/stat.h>
-#define AST_INCLUDE_GLOB 1
-#ifdef AST_INCLUDE_GLOB
-#if defined(__Darwin__) || defined(__CYGWIN__)
-#define GLOB_ABORTED GLOB_ABEND
-#endif
-# include <glob.h>
-#endif
-
-#include "asterisk/config.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/channel.h"
-#include "asterisk/app.h"
-
-#define MAX_NESTED_COMMENTS 128
-#define COMMENT_START ";--"
-#define COMMENT_END "--;"
-#define COMMENT_META ';'
-#define COMMENT_TAG '-'
-
-static char *extconfig_conf = "extconfig.conf";
-
-
-/*! \brief Structure to keep comments for rewriting configuration files */
-struct ast_comment {
- struct ast_comment *next;
- char cmt[0];
-};
-
-#define CB_INCR 250
-
-static void CB_INIT(char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
-{
- if (!(*comment_buffer)) {
- *comment_buffer = ast_malloc(CB_INCR);
- if (!(*comment_buffer))
- return;
- (*comment_buffer)[0] = 0;
- *comment_buffer_size = CB_INCR;
- *lline_buffer = ast_malloc(CB_INCR);
- if (!(*lline_buffer))
- return;
- (*lline_buffer)[0] = 0;
- *lline_buffer_size = CB_INCR;
- } else {
- (*comment_buffer)[0] = 0;
- (*lline_buffer)[0] = 0;
- }
-}
-
-static void CB_ADD(char **comment_buffer, int *comment_buffer_size, char *str)
-{
- int rem = *comment_buffer_size - strlen(*comment_buffer) - 1;
- int siz = strlen(str);
- if (rem < siz+1) {
- *comment_buffer = ast_realloc(*comment_buffer, *comment_buffer_size + CB_INCR + siz + 1);
- if (!(*comment_buffer))
- return;
- *comment_buffer_size += CB_INCR+siz+1;
- }
- strcat(*comment_buffer,str);
-}
-
-static void CB_ADD_LEN(char **comment_buffer, int *comment_buffer_size, char *str, int len)
-{
- int cbl = strlen(*comment_buffer) + 1;
- int rem = *comment_buffer_size - cbl;
- if (rem < len+1) {
- *comment_buffer = ast_realloc(*comment_buffer, *comment_buffer_size + CB_INCR + len + 1);
- if (!(*comment_buffer))
- return;
- *comment_buffer_size += CB_INCR+len+1;
- }
- strncat(*comment_buffer,str,len);
- (*comment_buffer)[cbl+len-1] = 0;
-}
-
-static void LLB_ADD(char **lline_buffer, int *lline_buffer_size, char *str)
-{
- int rem = *lline_buffer_size - strlen(*lline_buffer) - 1;
- int siz = strlen(str);
- if (rem < siz+1) {
- *lline_buffer = ast_realloc(*lline_buffer, *lline_buffer_size + CB_INCR + siz + 1);
- if (!(*lline_buffer))
- return;
- *lline_buffer_size += CB_INCR + siz + 1;
- }
- strcat(*lline_buffer,str);
-}
-
-static void CB_RESET(char **comment_buffer, char **lline_buffer)
-{
- (*comment_buffer)[0] = 0;
- (*lline_buffer)[0] = 0;
-}
-
-
-static struct ast_comment *ALLOC_COMMENT(const char *buffer)
-{
- struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
- strcpy(x->cmt, buffer);
- return x;
-}
-
-
-static struct ast_config_map {
- struct ast_config_map *next;
- char *name;
- char *driver;
- char *database;
- char *table;
- char stuff[0];
-} *config_maps = NULL;
-
-AST_MUTEX_DEFINE_STATIC(config_lock);
-static struct ast_config_engine *config_engine_list;
-
-#define MAX_INCLUDE_LEVEL 10
-
-struct ast_category_template_instance {
- char name[80]; /* redundant? */
- const struct ast_category *inst;
- AST_LIST_ENTRY(ast_category_template_instance) next;
-};
-
-struct ast_category {
- char name[80];
- int ignored; /*!< do not let user of the config see this category */
- int include_level;
- AST_LIST_HEAD_NOLOCK(template_instance_list, ast_category_template_instance) template_instances;
- struct ast_comment *precomments;
- struct ast_comment *sameline;
- struct ast_variable *root;
- struct ast_variable *last;
- struct ast_category *next;
-};
-
-struct ast_config {
- struct ast_category *root;
- struct ast_category *last;
- struct ast_category *current;
- struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
- int include_level;
- int max_include_level;
-};
-
-struct ast_variable *ast_variable_new(const char *name, const char *value)
-{
- struct ast_variable *variable;
- int name_len = strlen(name) + 1;
-
- if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + sizeof(*variable)))) {
- variable->name = variable->stuff;
- variable->value = variable->stuff + name_len;
- strcpy(variable->name,name);
- strcpy(variable->value,value);
- }
-
- return variable;
-}
-
-void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
-{
- if (!variable)
- return;
- if (category->last)
- category->last->next = variable;
- else
- category->root = variable;
- category->last = variable;
- while (category->last->next)
- category->last = category->last->next;
-}
-
-void ast_variables_destroy(struct ast_variable *v)
-{
- struct ast_variable *vn;
-
- while(v) {
- vn = v;
- v = v->next;
- free(vn);
- }
-}
-
-struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
-{
- struct ast_category *cat = NULL;
-
- if (category && config->last_browse && (config->last_browse->name == category))
- cat = config->last_browse;
- else
- cat = ast_category_get(config, category);
-
- return (cat) ? cat->root : NULL;
-}
-
-const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
-{
- const char *tmp;
- tmp = ast_variable_retrieve(cfg, cat, var);
- if (!tmp)
- tmp = ast_variable_retrieve(cfg, "general", var);
- return tmp;
-}
-
-
-const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
-{
- struct ast_variable *v;
-
- if (category) {
- for (v = ast_variable_browse(config, category); v; v = v->next) {
- if (!strcasecmp(variable, v->name))
- return v->value;
- }
- } else {
- struct ast_category *cat;
-
- for (cat = config->root; cat; cat = cat->next)
- for (v = cat->root; v; v = v->next)
- if (!strcasecmp(variable, v->name))
- return v->value;
- }
-
- return NULL;
-}
-
-static struct ast_variable *variable_clone(const struct ast_variable *old)
-{
- struct ast_variable *new = ast_variable_new(old->name, old->value);
-
- if (new) {
- new->lineno = old->lineno;
- new->object = old->object;
- new->blanklines = old->blanklines;
- /* TODO: clone comments? */
- }
-
- return new;
-}
-
-static void move_variables(struct ast_category *old, struct ast_category *new)
-{
- struct ast_variable *var = old->root;
- old->root = NULL;
-#if 1
- /* we can just move the entire list in a single op */
- ast_variable_append(new, var);
-#else
- while (var) {
- struct ast_variable *next = var->next;
- var->next = NULL;
- ast_variable_append(new, var);
- var = next;
- }
-#endif
-}
-
-struct ast_category *ast_category_new(const char *name)
-{
- struct ast_category *category;
-
- if ((category = ast_calloc(1, sizeof(*category))))
- ast_copy_string(category->name, name, sizeof(category->name));
- return category;
-}
-
-static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
-{
- struct ast_category *cat;
-
- /* try exact match first, then case-insensitive match */
- for (cat = config->root; cat; cat = cat->next) {
- if (cat->name == category_name && (ignored || !cat->ignored))
- return cat;
- }
-
- for (cat = config->root; cat; cat = cat->next) {
- if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
- return cat;
- }
-
- return NULL;
-}
-
-struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
-{
- return category_get(config, category_name, 0);
-}
-
-int ast_category_exist(const struct ast_config *config, const char *category_name)
-{
- return !!ast_category_get(config, category_name);
-}
-
-void ast_category_append(struct ast_config *config, struct ast_category *category)
-{
- if (config->last)
- config->last->next = category;
- else
- config->root = category;
- category->include_level = config->include_level;
- config->last = category;
- config->current = category;
-}
-
-static void ast_destroy_comments(struct ast_category *cat)
-{
- struct ast_comment *n, *p;
- for (p=cat->precomments; p; p=n) {
- n = p->next;
- free(p);
- }
- for (p=cat->sameline; p; p=n) {
- n = p->next;
- free(p);
- }
- cat->precomments = NULL;
- cat->sameline = NULL;
-}
-
-static void ast_destroy_template_list(struct ast_category *cat)
-{
- struct ast_category_template_instance *x;
- AST_LIST_TRAVERSE_SAFE_BEGIN(&cat->template_instances, x, next) {
- AST_LIST_REMOVE_CURRENT(&cat->template_instances, next);
- free(x);
- }
- AST_LIST_TRAVERSE_SAFE_END;
-}
-
-void ast_category_destroy(struct ast_category *cat)
-{
- ast_variables_destroy(cat->root);
- ast_destroy_comments(cat);
- ast_destroy_template_list(cat);
- free(cat);
-}
-
-static struct ast_category *next_available_category(struct ast_category *cat)
-{
- for (; cat && cat->ignored; cat = cat->next);
-
- return cat;
-}
-
-struct ast_variable *ast_category_root(struct ast_config *config, char *cat)
-{
- struct ast_category *category = ast_category_get(config, cat);
- if (category)
- return category->root;
- return NULL;
-}
-
-char *ast_category_browse(struct ast_config *config, const char *prev)
-{
- struct ast_category *cat = NULL;
-
- if (prev && config->last_browse && (config->last_browse->name == prev))
- cat = config->last_browse->next;
- else if (!prev && config->root)
- cat = config->root;
- else if (prev) {
- for (cat = config->root; cat; cat = cat->next) {
- if (cat->name == prev) {
- cat = cat->next;
- break;
- }
- }
- if (!cat) {
- for (cat = config->root; cat; cat = cat->next) {
- if (!strcasecmp(cat->name, prev)) {
- cat = cat->next;
- break;
- }
- }
- }
- }
-
- if (cat)
- cat = next_available_category(cat);
-
- config->last_browse = cat;
- return (cat) ? cat->name : NULL;
-}
-
-struct ast_variable *ast_category_detach_variables(struct ast_category *cat)
-{
- struct ast_variable *v;
-
- v = cat->root;
- cat->root = NULL;
- cat->last = NULL;
-
- return v;
-}
-
-void ast_category_rename(struct ast_category *cat, const char *name)
-{
- ast_copy_string(cat->name, name, sizeof(cat->name));
-}
-
-static void inherit_category(struct ast_category *new, const struct ast_category *base)
-{
- struct ast_variable *var;
- struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance));
- strcpy(x->name, base->name);
- x->inst = base;
- AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
- for (var = base->root; var; var = var->next)
- ast_variable_append(new, variable_clone(var));
-}
-
-struct ast_config *ast_config_new(void)
-{
- struct ast_config *config;
-
- if ((config = ast_calloc(1, sizeof(*config))))
- config->max_include_level = MAX_INCLUDE_LEVEL;
- return config;
-}
-
-int ast_variable_delete(struct ast_category *category, char *variable, char *match)
-{
- struct ast_variable *cur, *prev=NULL, *curn;
- int res = -1;
- cur = category->root;
- while (cur) {
- if (cur->name == variable) {
- if (prev) {
- prev->next = cur->next;
- if (cur == category->last)
- category->last = prev;
- } else {
- category->root = cur->next;
- if (cur == category->last)
- category->last = NULL;
- }
- cur->next = NULL;
- ast_variables_destroy(cur);
- return 0;
- }
- prev = cur;
- cur = cur->next;
- }
-
- prev = NULL;
- cur = category->root;
- while (cur) {
- curn = cur->next;
- if (!strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match))) {
- if (prev) {
- prev->next = cur->next;
- if (cur == category->last)
- category->last = prev;
- } else {
- category->root = cur->next;
- if (cur == category->last)
- category->last = NULL;
- }
- cur->next = NULL;
- ast_variables_destroy(cur);
- res = 0;
- } else
- prev = cur;
-
- cur = curn;
- }
- return res;
-}
-
-int ast_variable_update(struct ast_category *category, const char *variable,
- const char *value, const char *match, unsigned int object)
-{
- struct ast_variable *cur, *prev=NULL, *newer;
-
- if (!(newer = ast_variable_new(variable, value)))
- return -1;
-
- newer->object = object;
-
- for (cur = category->root; cur; prev = cur, cur = cur->next) {
- if (strcasecmp(cur->name, variable) ||
- (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
- continue;
-
- newer->next = cur->next;
- newer->object = cur->object || object;
- if (prev)
- prev->next = newer;
- else
- category->root = newer;
- if (category->last == cur)
- category->last = newer;
-
- cur->next = NULL;
- ast_variables_destroy(cur);
-
- return 0;
- }
-
- if (prev)
- prev->next = newer;
- else
- category->root = newer;
-
- return 0;
-}
-
-int ast_category_delete(struct ast_config *cfg, char *category)
-{
- struct ast_category *prev=NULL, *cat;
- cat = cfg->root;
- while(cat) {
- if (cat->name == category) {
- if (prev) {
- prev->next = cat->next;
- if (cat == cfg->last)
- cfg->last = prev;
- } else {
- cfg->root = cat->next;
- if (cat == cfg->last)
- cfg->last = NULL;
- }
- ast_category_destroy(cat);
- return 0;
- }
- prev = cat;
- cat = cat->next;
- }
-
- prev = NULL;
- cat = cfg->root;
- while(cat) {
- if (!strcasecmp(cat->name, category)) {
- if (prev) {
- prev->next = cat->next;
- if (cat == cfg->last)
- cfg->last = prev;
- } else {
- cfg->root = cat->next;
- if (cat == cfg->last)
- cfg->last = NULL;
- }
- ast_category_destroy(cat);
- return 0;
- }
- prev = cat;
- cat = cat->next;
- }
- return -1;
-}
-
-void ast_config_destroy(struct ast_config *cfg)
-{
- struct ast_category *cat, *catn;
-
- if (!cfg)
- return;
-
- cat = cfg->root;
- while(cat) {
- catn = cat;
- cat = cat->next;
- ast_category_destroy(catn);
- }
- free(cfg);
-}
-
-struct ast_category *ast_config_get_current_category(const struct ast_config *cfg)
-{
- return cfg->current;
-}
-
-void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
-{
- /* cast below is just to silence compiler warning about dropping "const" */
- cfg->current = (struct ast_category *) cat;
-}
-
-static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments,
- char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
-{
- char *c;
- char *cur = buf;
- struct ast_variable *v;
- char cmd[512], exec_file[512];
- int object, do_exec, do_include;
-
- /* Actually parse the entry */
- if (cur[0] == '[') {
- struct ast_category *newcat = NULL;
- char *catname;
-
- /* A category header */
- c = strchr(cur, ']');
- if (!c) {
- ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
- return -1;
- }
- *c++ = '\0';
- cur++;
- if (*c++ != '(')
- c = NULL;
- catname = cur;
- if (!(*cat = newcat = ast_category_new(catname))) {
- return -1;
- }
- /* add comments */
- if (withcomments && *comment_buffer && (*comment_buffer)[0] ) {
- newcat->precomments = ALLOC_COMMENT(*comment_buffer);
- }
- if (withcomments && *lline_buffer && (*lline_buffer)[0] ) {
- newcat->sameline = ALLOC_COMMENT(*lline_buffer);
- }
- if( withcomments )
- CB_RESET(comment_buffer, lline_buffer);
-
- /* If there are options or categories to inherit from, process them now */
- if (c) {
- if (!(cur = strchr(c, ')'))) {
- ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
- return -1;
- }
- *cur = '\0';
- while ((cur = strsep(&c, ","))) {
- if (!strcasecmp(cur, "!")) {
- (*cat)->ignored = 1;
- } else if (!strcasecmp(cur, "+")) {
- *cat = category_get(cfg, catname, 1);
- if (!(*cat)) {
- if (newcat)
- ast_category_destroy(newcat);
- ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
- return -1;
- }
- if (newcat) {
- move_variables(newcat, *cat);
- ast_category_destroy(newcat);
- newcat = NULL;
- }
- } else {
- struct ast_category *base;
-
- base = category_get(cfg, cur, 1);
- if (!base) {
- ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
- return -1;
- }
- inherit_category(*cat, base);
- }
- }
- }
- if (newcat)
- ast_category_append(cfg, *cat);
- } else if (cur[0] == '#') {
- /* A directive */
- cur++;
- c = cur;
- while(*c && (*c > 32)) c++;
- if (*c) {
- *c = '\0';
- /* Find real argument */
- c = ast_skip_blanks(c + 1);
- if (!(*c))
- c = NULL;
- } else
- c = NULL;
- do_include = !strcasecmp(cur, "include");
- if(!do_include)
- do_exec = !strcasecmp(cur, "exec");
- else
- do_exec = 0;
- if (do_exec && !ast_opt_exec_includes) {
- ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
- do_exec = 0;
- }
- if (do_include || do_exec) {
- if (c) {
- /* Strip off leading and trailing "'s and <>'s */
- while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
- /* Get rid of leading mess */
- cur = c;
- while (!ast_strlen_zero(cur)) {
- c = cur + strlen(cur) - 1;
- if ((*c == '>') || (*c == '<') || (*c == '\"'))
- *c = '\0';
- else
- break;
- }
- /* #exec </path/to/executable>
- We create a tmp file, then we #include it, then we delete it. */
- if (do_exec) {
- snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
- snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
- ast_safe_system(cmd);
- cur = exec_file;
- } else
- exec_file[0] = '\0';
- /* A #include */
- do_include = ast_config_internal_load(cur, cfg, withcomments) ? 1 : 0;
- if(!ast_strlen_zero(exec_file))
- unlink(exec_file);
- if (!do_include) {
- ast_log(LOG_ERROR, "*********************************************************\n");
- ast_log(LOG_ERROR, "*********** YOU SHOULD REALLY READ THIS ERROR ***********\n");
- ast_log(LOG_ERROR, "Future versions of Asterisk will treat a #include of a "
- "file that does not exist as an error, and will fail to "
- "load that configuration file. Please ensure that the "
- "file '%s' exists, even if it is empty.\n", cur);
- ast_log(LOG_ERROR, "*********** YOU SHOULD REALLY READ THIS ERROR ***********\n");
- ast_log(LOG_ERROR, "*********************************************************\n");
- return 0;
- }
-
- } else {
- ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
- do_exec ? "exec" : "include",
- do_exec ? "/path/to/executable" : "filename",
- lineno,
- configfile);
- }
- }
- else
- ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
- } else {
- /* Just a line (variable = value) */
- if (!(*cat)) {
- ast_log(LOG_WARNING,
- "parse error: No category context for line %d of %s\n", lineno, configfile);
- return -1;
- }
- c = strchr(cur, '=');
- if (c) {
- *c = 0;
- c++;
- /* Ignore > in => */
- if (*c== '>') {
- object = 1;
- c++;
- } else
- object = 0;
- if ((v = ast_variable_new(ast_strip(cur), ast_strip(c)))) {
- v->lineno = lineno;
- v->object = object;
- /* Put and reset comments */
- v->blanklines = 0;
- ast_variable_append(*cat, v);
- /* add comments */
- if (withcomments && *comment_buffer && (*comment_buffer)[0] ) {
- v->precomments = ALLOC_COMMENT(*comment_buffer);
- }
- if (withcomments && *lline_buffer && (*lline_buffer)[0] ) {
- v->sameline = ALLOC_COMMENT(*lline_buffer);
- }
- if( withcomments )
- CB_RESET(comment_buffer, lline_buffer);
-
- } else {
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
- }
- }
- return 0;
-}
-
-static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments)
-{
- char fn[256];
- char buf[8192];
- char *new_buf, *comment_p, *process_buf;
- FILE *f;
- int lineno=0;
- int comment = 0, nest[MAX_NESTED_COMMENTS];
- struct ast_category *cat = NULL;
- int count = 0;
- struct stat statbuf;
- /*! Growable string buffer */
- char *comment_buffer=0; /*!< this will be a comment collector.*/
- int comment_buffer_size=0; /*!< the amount of storage so far alloc'd for the comment_buffer */
-
- char *lline_buffer=0; /*!< A buffer for stuff behind the ; */
- int lline_buffer_size=0;
-
-
- cat = ast_config_get_current_category(cfg);
-
- if (filename[0] == '/') {
- ast_copy_string(fn, filename, sizeof(fn));
- } else {
- snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, filename);
- }
-
- if (withcomments) {
- CB_INIT(&comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size);
- if (!lline_buffer || !comment_buffer) {
- ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
- return NULL;
- }
- }
-#ifdef AST_INCLUDE_GLOB
- {
- int glob_ret;
- glob_t globbuf;
- globbuf.gl_offs = 0; /* initialize it to silence gcc */
-#ifdef SOLARIS
- glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);
-#else
- glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
-#endif
- if (glob_ret == GLOB_NOSPACE)
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
- else if (glob_ret == GLOB_ABORTED)
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: Read error\n", fn);
- else {
- /* loop over expanded files */
- int i;
- for (i=0; i<globbuf.gl_pathc; i++) {
- ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
-#endif
- do {
- if (stat(fn, &statbuf))
- continue;
-
- if (!S_ISREG(statbuf.st_mode)) {
- ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
- continue;
- }
- if (option_verbose > 1) {
- ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
- fflush(stdout);
- }
- if (!(f = fopen(fn, "r"))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
- if (option_verbose > 1)
- ast_verbose( "Not found (%s)\n", strerror(errno));
- continue;
- }
- count++;
- if (option_debug)
- ast_log(LOG_DEBUG, "Parsing %s\n", fn);
- if (option_verbose > 1)
- ast_verbose("Found\n");
- while(!feof(f)) {
- lineno++;
- if (fgets(buf, sizeof(buf), f)) {
- if ( withcomments ) {
- CB_ADD(&comment_buffer, &comment_buffer_size, lline_buffer); /* add the current lline buffer to the comment buffer */
- lline_buffer[0] = 0; /* erase the lline buffer */
- }
-
- new_buf = buf;
- if (comment)
- process_buf = NULL;
- else
- process_buf = buf;
-
- while ((comment_p = strchr(new_buf, COMMENT_META))) {
- if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
- /* Escaped semicolons aren't comments. */
- new_buf = comment_p + 1;
- } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
- /* Meta-Comment start detected ";--" */
- if (comment < MAX_NESTED_COMMENTS) {
- *comment_p = '\0';
- new_buf = comment_p + 3;
- comment++;
- nest[comment-1] = lineno;
- } else {
- ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
- }
- } else if ((comment_p >= new_buf + 2) &&
- (*(comment_p - 1) == COMMENT_TAG) &&
- (*(comment_p - 2) == COMMENT_TAG)) {
- /* Meta-Comment end detected */
- comment--;
- new_buf = comment_p + 1;
- if (!comment) {
- /* Back to non-comment now */
- if (process_buf) {
- /* Actually have to move what's left over the top, then continue */
- char *oldptr;
- oldptr = process_buf + strlen(process_buf);
- if ( withcomments ) {
- CB_ADD(&comment_buffer, &comment_buffer_size, ";");
- CB_ADD_LEN(&comment_buffer, &comment_buffer_size, oldptr+1, new_buf-oldptr-1);
- }
-
- memmove(oldptr, new_buf, strlen(new_buf) + 1);
- new_buf = oldptr;
- } else
- process_buf = new_buf;
- }
- } else {
- if (!comment) {
- /* If ; is found, and we are not nested in a comment,
- we immediately stop all comment processing */
- if ( withcomments ) {
- LLB_ADD(&lline_buffer, &lline_buffer_size, comment_p);
- }
- *comment_p = '\0';
- new_buf = comment_p;
- } else
- new_buf = comment_p + 1;
- }
- }
- if( withcomments && comment && !process_buf )
- {
- CB_ADD(&comment_buffer, &comment_buffer_size, buf); /* the whole line is a comment, store it */
- }
-
- if (process_buf) {
- char *buf = ast_strip(process_buf);
- if (!ast_strlen_zero(buf)) {
- if (process_text_line(cfg, &cat, buf, lineno, fn, withcomments, &comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size)) {
- cfg = NULL;
- break;
- }
- }
- }
- }
- }
- fclose(f);
- } while(0);
- if (comment) {
- ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
- }
-#ifdef AST_INCLUDE_GLOB
- if (!cfg)
- break;
- }
- globfree(&globbuf);
- }
- }
-#endif
-
- if (cfg && cfg->include_level == 1 && withcomments && comment_buffer) {
- free(comment_buffer);
- free(lline_buffer);
- comment_buffer = NULL;
- lline_buffer = NULL;
- comment_buffer_size = 0;
- lline_buffer_size = 0;
- }
-
- if (count == 0)
- return NULL;
-
- return cfg;
-}
-
-int config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
-{
- FILE *f = NULL;
- int fd = -1;
- char fn[256], fntmp[256];
- char date[256]="";
- time_t t;
- struct ast_variable *var;
- struct ast_category *cat;
- struct ast_comment *cmt;
- struct stat s;
- int blanklines = 0;
-
- if (configfile[0] == '/') {
- snprintf(fntmp, sizeof(fntmp), "%s.XXXXXX", configfile);
- ast_copy_string(fn, configfile, sizeof(fn));
- } else {
- snprintf(fntmp, sizeof(fntmp), "%s/%s.XXXXXX", ast_config_AST_CONFIG_DIR, configfile);
- snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
- }
- time(&t);
- ast_copy_string(date, ctime(&t), sizeof(date));
- if ((fd = mkstemp(fntmp)) > 0 && (f = fdopen(fd, "w")) != NULL) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Saving '%s': ", fn);
- fprintf(f, ";!\n");
- fprintf(f, ";! Automatically generated configuration file\n");
- if (strcmp(configfile, fn))
- fprintf(f, ";! Filename: %s (%s)\n", configfile, fn);
- else
- fprintf(f, ";! Filename: %s\n", configfile);
- fprintf(f, ";! Generator: %s\n", generator);
- fprintf(f, ";! Creation Date: %s", date);
- fprintf(f, ";!\n");
- cat = cfg->root;
- while(cat) {
- /* Dump section with any appropriate comment */
- for (cmt = cat->precomments; cmt; cmt=cmt->next)
- {
- if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
- fprintf(f,"%s", cmt->cmt);
- }
- if (!cat->precomments)
- fprintf(f,"\n");
- fprintf(f, "[%s]", cat->name);
- if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
- fprintf(f, "(");
- if (cat->ignored) {
- fprintf(f, "!");
- }
- if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
- fprintf(f, ",");
- }
- if (!AST_LIST_EMPTY(&cat->template_instances)) {
- struct ast_category_template_instance *x;
- AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
- fprintf(f,"%s",x->name);
- if (x != AST_LIST_LAST(&cat->template_instances))
- fprintf(f,",");
- }
- }
- fprintf(f, ")");
- }
- for(cmt = cat->sameline; cmt; cmt=cmt->next)
- {
- fprintf(f,"%s", cmt->cmt);
- }
- if (!cat->sameline)
- fprintf(f,"\n");
- var = cat->root;
- while(var) {
- struct ast_category_template_instance *x;
- struct ast_variable *v2;
- int found = 0;
- AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
-
- for (v2 = x->inst->root; v2; v2 = v2->next) {
- if (!strcasecmp(var->name, v2->name))
- break;
- }
- if (v2 && v2->value && !strcmp(v2->value, var->value)) {
- found = 1;
- break;
- }
- }
- if (found) {
- var = var->next;
- continue;
- }
- for (cmt = var->precomments; cmt; cmt=cmt->next)
- {
- if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
- fprintf(f,"%s", cmt->cmt);
- }
- if (var->sameline)
- fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
- else
- fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
- if (var->blanklines) {
- blanklines = var->blanklines;
- while (blanklines--)
- fprintf(f, "\n");
- }
-
- var = var->next;
- }
-#if 0
- /* Put an empty line */
- fprintf(f, "\n");
-#endif
- cat = cat->next;
- }
- if ((option_verbose > 1) && !option_debug)
- ast_verbose("Saved\n");
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to open for writing: %s (%s)\n", fn, strerror(errno));
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
- if (fd > -1)
- close(fd);
- return -1;
- }
- stat(fn, &s);
- fchmod(fd, s.st_mode);
- fclose(f);
- if (unlink(fn) || link(fntmp, fn)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to open for writing: %s (%s)\n", fn, strerror(errno));
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
- unlink(fntmp);
- return -1;
- }
- unlink(fntmp);
- return 0;
-}
-
-static void clear_config_maps(void)
-{
- struct ast_config_map *map;
-
- ast_mutex_lock(&config_lock);
-
- while (config_maps) {
- map = config_maps;
- config_maps = config_maps->next;
- free(map);
- }
-
- ast_mutex_unlock(&config_lock);
-}
-
-static int append_mapping(char *name, char *driver, char *database, char *table)
-{
- struct ast_config_map *map;
- int length;
-
- length = sizeof(*map);
- length += strlen(name) + 1;
- length += strlen(driver) + 1;
- length += strlen(database) + 1;
- if (table)
- length += strlen(table) + 1;
-
- if (!(map = ast_calloc(1, length)))
- return -1;
-
- map->name = map->stuff;
- strcpy(map->name, name);
- map->driver = map->name + strlen(map->name) + 1;
- strcpy(map->driver, driver);
- map->database = map->driver + strlen(map->driver) + 1;
- strcpy(map->database, database);
- if (table) {
- map->table = map->database + strlen(map->database) + 1;
- strcpy(map->table, table);
- }
- map->next = config_maps;
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Binding %s to %s/%s/%s\n",
- map->name, map->driver, map->database, map->table ? map->table : map->name);
-
- config_maps = map;
- return 0;
-}
-
-int read_config_maps(void)
-{
- struct ast_config *config, *configtmp;
- struct ast_variable *v;
- char *driver, *table, *database, *stringp, *tmp;
-
- clear_config_maps();
-
- configtmp = ast_config_new();
- configtmp->max_include_level = 1;
- config = ast_config_internal_load(extconfig_conf, configtmp, 0);
- if (!config) {
- ast_config_destroy(configtmp);
- return 0;
- }
-
- for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
- stringp = v->value;
- driver = strsep(&stringp, ",");
-
- if ((tmp = strchr(stringp, '\"')))
- stringp = tmp;
-
- /* check if the database text starts with a double quote */
- if (*stringp == '"') {
- stringp++;
- database = strsep(&stringp, "\"");
- strsep(&stringp, ",");
- } else {
- /* apparently this text has no quotes */
- database = strsep(&stringp, ",");
- }
-
- table = strsep(&stringp, ",");
-
- if (!strcmp(v->name, extconfig_conf)) {
- ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
- continue;
- }
-
- if (!strcmp(v->name, "asterisk.conf")) {
- ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
- continue;
- }
-
- if (!strcmp(v->name, "logger.conf")) {
- ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
- continue;
- }
-
- if (!driver || !database)
- continue;
- if (!strcasecmp(v->name, "sipfriends")) {
- ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sipusers and sippeers, though they can point to the same table.\n");
- append_mapping("sipusers", driver, database, table ? table : "sipfriends");
- append_mapping("sippeers", driver, database, table ? table : "sipfriends");
- } else if (!strcasecmp(v->name, "iaxfriends")) {
- ast_log(LOG_WARNING, "The 'iaxfriends' table is obsolete, update your config to use iaxusers and iaxpeers, though they can point to the same table.\n");
- append_mapping("iaxusers", driver, database, table ? table : "iaxfriends");
- append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends");
- } else
- append_mapping(v->name, driver, database, table);
- }
-
- ast_config_destroy(config);
- return 0;
-}
-
-int ast_config_engine_register(struct ast_config_engine *new)
-{
- struct ast_config_engine *ptr;
-
- ast_mutex_lock(&config_lock);
-
- if (!config_engine_list) {
- config_engine_list = new;
- } else {
- for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
- ptr->next = new;
- }
-
- ast_mutex_unlock(&config_lock);
- ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);
-
- return 1;
-}
-
-int ast_config_engine_deregister(struct ast_config_engine *del)
-{
- struct ast_config_engine *ptr, *last=NULL;
-
- ast_mutex_lock(&config_lock);
-
- for (ptr = config_engine_list; ptr; ptr=ptr->next) {
- if (ptr == del) {
- if (last)
- last->next = ptr->next;
- else
- config_engine_list = ptr->next;
- break;
- }
- last = ptr;
- }
-
- ast_mutex_unlock(&config_lock);
-
- return 0;
-}
-
-/*! \brief Find realtime engine for realtime family */
-static struct ast_config_engine *find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz)
-{
- struct ast_config_engine *eng, *ret = NULL;
- struct ast_config_map *map;
-
- ast_mutex_lock(&config_lock);
-
- for (map = config_maps; map; map = map->next) {
- if (!strcasecmp(family, map->name)) {
- if (database)
- ast_copy_string(database, map->database, dbsiz);
- if (table)
- ast_copy_string(table, map->table ? map->table : family, tabsiz);
- break;
- }
- }
-
- /* Check if the required driver (engine) exist */
- if (map) {
- for (eng = config_engine_list; !ret && eng; eng = eng->next) {
- if (!strcasecmp(eng->name, map->driver))
- ret = eng;
- }
- }
-
- ast_mutex_unlock(&config_lock);
-
- /* if we found a mapping, but the engine is not available, then issue a warning */
- if (map && !ret)
- ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
-
- return ret;
-}
-
-static struct ast_config_engine text_file_engine = {
- .name = "text",
- .load_func = config_text_file_load,
-};
-
-struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments)
-{
- char db[256];
- char table[256];
- struct ast_config_engine *loader = &text_file_engine;
- struct ast_config *result;
-
- /* The config file itself bumps include_level by 1 */
- if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
- ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
- return NULL;
- }
-
- cfg->include_level++;
-
- if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
- struct ast_config_engine *eng;
-
- eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
-
-
- if (eng && eng->load_func) {
- loader = eng;
- } else {
- eng = find_engine("global", db, sizeof(db), table, sizeof(table));
- if (eng && eng->load_func)
- loader = eng;
- }
- }
-
- result = loader->load_func(db, table, filename, cfg, withcomments);
-
- if (result)
- result->include_level--;
- else
- cfg->include_level--;
-
- return result;
-}
-
-struct ast_config *ast_config_load(const char *filename)
-{
- struct ast_config *cfg;
- struct ast_config *result;
-
- cfg = ast_config_new();
- if (!cfg)
- return NULL;
-
- result = ast_config_internal_load(filename, cfg, 0);
- if (!result)
- ast_config_destroy(cfg);
-
- return result;
-}
-
-struct ast_config *ast_config_load_with_comments(const char *filename)
-{
- struct ast_config *cfg;
- struct ast_config *result;
-
- cfg = ast_config_new();
- if (!cfg)
- return NULL;
-
- result = ast_config_internal_load(filename, cfg, 1);
- if (!result)
- ast_config_destroy(cfg);
-
- return result;
-}
-
-struct ast_variable *ast_load_realtime(const char *family, ...)
-{
- struct ast_config_engine *eng;
- char db[256]="";
- char table[256]="";
- struct ast_variable *res=NULL;
- va_list ap;
-
- va_start(ap, family);
- eng = find_engine(family, db, sizeof(db), table, sizeof(table));
- if (eng && eng->realtime_func)
- res = eng->realtime_func(db, table, ap);
- va_end(ap);
-
- return res;
-}
-
-/*! \brief Check if realtime engine is configured for family */
-int ast_check_realtime(const char *family)
-{
- struct ast_config_engine *eng;
-
- eng = find_engine(family, NULL, 0, NULL, 0);
- if (eng)
- return 1;
- return 0;
-
-}
-
-struct ast_config *ast_load_realtime_multientry(const char *family, ...)
-{
- struct ast_config_engine *eng;
- char db[256]="";
- char table[256]="";
- struct ast_config *res=NULL;
- va_list ap;
-
- va_start(ap, family);
- eng = find_engine(family, db, sizeof(db), table, sizeof(table));
- if (eng && eng->realtime_multi_func)
- res = eng->realtime_multi_func(db, table, ap);
- va_end(ap);
-
- return res;
-}
-
-int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...)
-{
- struct ast_config_engine *eng;
- int res = -1;
- char db[256]="";
- char table[256]="";
- va_list ap;
-
- va_start(ap, lookup);
- eng = find_engine(family, db, sizeof(db), table, sizeof(table));
- if (eng && eng->update_func)
- res = eng->update_func(db, table, keyfield, lookup, ap);
- va_end(ap);
-
- return res;
-}
-
-static int config_command(int fd, int argc, char **argv)
-{
- struct ast_config_engine *eng;
- struct ast_config_map *map;
-
- ast_mutex_lock(&config_lock);
-
- ast_cli(fd, "\n\n");
- for (eng = config_engine_list; eng; eng = eng->next) {
- ast_cli(fd, "\nConfig Engine: %s\n", eng->name);
- for (map = config_maps; map; map = map->next)
- if (!strcasecmp(map->driver, eng->name)) {
- ast_cli(fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
- map->table ? map->table : map->name);
- }
- }
- ast_cli(fd,"\n\n");
-
- ast_mutex_unlock(&config_lock);
-
- return 0;
-}
-
-static char show_config_help[] =
- "Usage: core show config mappings\n"
- " Shows the filenames to config engines.\n";
-
-static struct ast_cli_entry cli_show_config_mappings_deprecated = {
- { "show", "config", "mappings", NULL },
- config_command, NULL,
- NULL };
-
-static struct ast_cli_entry cli_config[] = {
- { { "core", "show", "config", "mappings", NULL },
- config_command, "Display config mappings (file names to config engines)",
- show_config_help, NULL, &cli_show_config_mappings_deprecated },
-};
-
-int register_config_cli()
-{
- ast_cli_register_multiple(cli_config, sizeof(cli_config) / sizeof(struct ast_cli_entry));
- return 0;
-}
diff --git a/1.4/main/cryptostub.c b/1.4/main/cryptostub.c
deleted file mode 100644
index 676110374..000000000
--- a/1.4/main/cryptostub.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Stubs for res_crypto routines
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "asterisk/crypto.h"
-#include "asterisk/logger.h"
-
-/* Hrm, I wonder if the compiler is smart enough to only create two functions
- for all these... I could force it to only make two, but those would be some
- really nasty looking casts. */
-
-static struct ast_key *stub_ast_key_get(const char *kname, int ktype)
-{
- ast_log(LOG_NOTICE, "Crypto support not loaded!\n");
- return NULL;
-}
-
-static int stub_ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
-{
- ast_log(LOG_NOTICE, "Crypto support not loaded!\n");
- return -1;
-}
-
-static int stub_ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig)
-{
- ast_log(LOG_NOTICE, "Crypto support not loaded!\n");
- return -1;
-}
-
-static int stub_ast_sign(struct ast_key *key, char *msg, char *sig)
-{
- ast_log(LOG_NOTICE, "Crypto support not loaded!\n");
- return -1;
-}
-
-static int stub_ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *sig)
-{
- ast_log(LOG_NOTICE, "Crypto support not loaded!\n");
- return -1;
-}
-
-static int stub_ast_encdec_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
-{
- ast_log(LOG_NOTICE, "Crypto support not loaded!\n");
- return -1;
-}
-
-struct ast_key *(*ast_key_get)(const char *key, int type) =
- stub_ast_key_get;
-
-int (*ast_check_signature)(struct ast_key *key, const char *msg, const char *sig) =
- stub_ast_check_signature;
-
-int (*ast_check_signature_bin)(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig) =
- stub_ast_check_signature_bin;
-
-int (*ast_sign)(struct ast_key *key, char *msg, char *sig) =
- stub_ast_sign;
-
-int (*ast_sign_bin)(struct ast_key *key, const char *msg, int msglen, unsigned char *sig) =
- stub_ast_sign_bin;
-
-int (*ast_encrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key) =
- stub_ast_encdec_bin;
-
-int (*ast_decrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key) =
- stub_ast_encdec_bin;
diff --git a/1.4/main/db.c b/1.4/main/db.c
deleted file mode 100644
index ef381c092..000000000
--- a/1.4/main/db.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief ASTdb Management
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note DB3 is licensed under Sleepycat Public License and is thus incompatible
- * with GPL. To avoid having to make another exception (and complicate
- * licensing even further) we elect to use DB1 which is BSD licensed
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/astdb.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/manager.h"
-#include "db1-ast/include/db.h"
-
-#ifdef __CYGWIN__
-#define dbopen __dbopen
-#endif
-
-static DB *astdb;
-AST_MUTEX_DEFINE_STATIC(dblock);
-
-static int dbinit(void)
-{
- if (!astdb && !(astdb = dbopen((char *)ast_config_AST_DB, O_CREAT | O_RDWR, 0664, DB_BTREE, NULL))) {
- ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", ast_config_AST_DB, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-
-static inline int keymatch(const char *key, const char *prefix)
-{
- int preflen = strlen(prefix);
- if (!preflen)
- return 1;
- if (!strcasecmp(key, prefix))
- return 1;
- if ((strlen(key) > preflen) && !strncasecmp(key, prefix, preflen)) {
- if (key[preflen] == '/')
- return 1;
- }
- return 0;
-}
-
-static inline int subkeymatch(const char *key, const char *suffix)
-{
- int suffixlen = strlen(suffix);
- if (suffixlen) {
- const char *subkey = key + strlen(key) - suffixlen;
- if (subkey < key)
- return 0;
- if (!strcasecmp(subkey, suffix))
- return 1;
- }
- return 0;
-}
-
-int ast_db_deltree(const char *family, const char *keytree)
-{
- char prefix[256];
- DBT key, data;
- char *keys;
- int res;
- int pass;
-
- if (family) {
- if (keytree) {
- snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
- } else {
- snprintf(prefix, sizeof(prefix), "/%s", family);
- }
- } else if (keytree) {
- return -1;
- } else {
- prefix[0] = '\0';
- }
-
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- return -1;
- }
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- pass = 0;
- while (!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
- if (key.size) {
- keys = key.data;
- keys[key.size - 1] = '\0';
- } else {
- keys = "<bad key>";
- }
- if (keymatch(keys, prefix)) {
- astdb->del(astdb, &key, 0);
- }
- }
- astdb->sync(astdb, 0);
- ast_mutex_unlock(&dblock);
- return 0;
-}
-
-int ast_db_put(const char *family, const char *keys, char *value)
-{
- char fullkey[256];
- DBT key, data;
- int res, fullkeylen;
-
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- return -1;
- }
-
- fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- key.data = fullkey;
- key.size = fullkeylen + 1;
- data.data = value;
- data.size = strlen(value) + 1;
- res = astdb->put(astdb, &key, &data, 0);
- astdb->sync(astdb, 0);
- ast_mutex_unlock(&dblock);
- if (res)
- ast_log(LOG_WARNING, "Unable to put value '%s' for key '%s' in family '%s'\n", value, keys, family);
- return res;
-}
-
-int ast_db_get(const char *family, const char *keys, char *value, int valuelen)
-{
- char fullkey[256] = "";
- DBT key, data;
- int res, fullkeylen;
-
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- return -1;
- }
-
- fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- memset(value, 0, valuelen);
- key.data = fullkey;
- key.size = fullkeylen + 1;
-
- res = astdb->get(astdb, &key, &data, 0);
-
- ast_mutex_unlock(&dblock);
-
- /* Be sure to NULL terminate our data either way */
- if (res) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to find key '%s' in family '%s'\n", keys, family);
- } else {
-#if 0
- printf("Got value of size %d\n", data.size);
-#endif
- if (data.size) {
- ((char *)data.data)[data.size - 1] = '\0';
- /* Make sure that we don't write too much to the dst pointer or we don't read too much from the source pointer */
- ast_copy_string(value, data.data, (valuelen > data.size) ? data.size : valuelen);
- } else {
- ast_log(LOG_NOTICE, "Strange, empty value for /%s/%s\n", family, keys);
- }
- }
- return res;
-}
-
-int ast_db_del(const char *family, const char *keys)
-{
- char fullkey[256];
- DBT key;
- int res, fullkeylen;
-
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- return -1;
- }
-
- fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
- memset(&key, 0, sizeof(key));
- key.data = fullkey;
- key.size = fullkeylen + 1;
-
- res = astdb->del(astdb, &key, 0);
- astdb->sync(astdb, 0);
-
- ast_mutex_unlock(&dblock);
-
- if (res && option_debug)
- ast_log(LOG_DEBUG, "Unable to find key '%s' in family '%s'\n", keys, family);
- return res;
-}
-
-static int database_put(int fd, int argc, char *argv[])
-{
- int res;
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- res = ast_db_put(argv[2], argv[3], argv[4]);
- if (res) {
- ast_cli(fd, "Failed to update entry\n");
- } else {
- ast_cli(fd, "Updated database successfully\n");
- }
- return RESULT_SUCCESS;
-}
-
-static int database_get(int fd, int argc, char *argv[])
-{
- int res;
- char tmp[256];
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
- if (res) {
- ast_cli(fd, "Database entry not found.\n");
- } else {
- ast_cli(fd, "Value: %s\n", tmp);
- }
- return RESULT_SUCCESS;
-}
-
-static int database_del(int fd, int argc, char *argv[])
-{
- int res;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- res = ast_db_del(argv[2], argv[3]);
- if (res) {
- ast_cli(fd, "Database entry does not exist.\n");
- } else {
- ast_cli(fd, "Database entry removed.\n");
- }
- return RESULT_SUCCESS;
-}
-
-static int database_deltree(int fd, int argc, char *argv[])
-{
- int res;
- if ((argc < 3) || (argc > 4))
- return RESULT_SHOWUSAGE;
- if (argc == 4) {
- res = ast_db_deltree(argv[2], argv[3]);
- } else {
- res = ast_db_deltree(argv[2], NULL);
- }
- if (res) {
- ast_cli(fd, "Database entries do not exist.\n");
- } else {
- ast_cli(fd, "Database entries removed.\n");
- }
- return RESULT_SUCCESS;
-}
-
-static int database_show(int fd, int argc, char *argv[])
-{
- char prefix[256];
- DBT key, data;
- char *keys, *values;
- int res;
- int pass;
-
- if (argc == 4) {
- /* Family and key tree */
- snprintf(prefix, sizeof(prefix), "/%s/%s", argv[2], argv[3]);
- } else if (argc == 3) {
- /* Family only */
- snprintf(prefix, sizeof(prefix), "/%s", argv[2]);
- } else if (argc == 2) {
- /* Neither */
- prefix[0] = '\0';
- } else {
- return RESULT_SHOWUSAGE;
- }
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- ast_cli(fd, "Database unavailable\n");
- return RESULT_SUCCESS;
- }
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- pass = 0;
- while (!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
- if (key.size) {
- keys = key.data;
- keys[key.size - 1] = '\0';
- } else {
- keys = "<bad key>";
- }
- if (data.size) {
- values = data.data;
- values[data.size - 1]='\0';
- } else {
- values = "<bad value>";
- }
- if (keymatch(keys, prefix)) {
- ast_cli(fd, "%-50s: %-25s\n", keys, values);
- }
- }
- ast_mutex_unlock(&dblock);
- return RESULT_SUCCESS;
-}
-
-static int database_showkey(int fd, int argc, char *argv[])
-{
- char suffix[256];
- DBT key, data;
- char *keys, *values;
- int res;
- int pass;
-
- if (argc == 3) {
- /* Key only */
- snprintf(suffix, sizeof(suffix), "/%s", argv[2]);
- } else {
- return RESULT_SHOWUSAGE;
- }
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- ast_cli(fd, "Database unavailable\n");
- return RESULT_SUCCESS;
- }
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- pass = 0;
- while (!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
- if (key.size) {
- keys = key.data;
- keys[key.size - 1] = '\0';
- } else {
- keys = "<bad key>";
- }
- if (data.size) {
- values = data.data;
- values[data.size - 1]='\0';
- } else {
- values = "<bad value>";
- }
- if (subkeymatch(keys, suffix)) {
- ast_cli(fd, "%-50s: %-25s\n", keys, values);
- }
- }
- ast_mutex_unlock(&dblock);
- return RESULT_SUCCESS;
-}
-
-struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
-{
- char prefix[256];
- DBT key, data;
- char *keys, *values;
- int values_len;
- int res;
- int pass;
- struct ast_db_entry *last = NULL;
- struct ast_db_entry *cur, *ret=NULL;
-
- if (!ast_strlen_zero(family)) {
- if (!ast_strlen_zero(keytree)) {
- /* Family and key tree */
- snprintf(prefix, sizeof(prefix), "/%s/%s", family, prefix);
- } else {
- /* Family only */
- snprintf(prefix, sizeof(prefix), "/%s", family);
- }
- } else {
- prefix[0] = '\0';
- }
- ast_mutex_lock(&dblock);
- if (dbinit()) {
- ast_mutex_unlock(&dblock);
- ast_log(LOG_WARNING, "Database unavailable\n");
- return NULL;
- }
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- pass = 0;
- while (!(res = astdb->seq(astdb, &key, &data, pass++ ? R_NEXT : R_FIRST))) {
- if (key.size) {
- keys = key.data;
- keys[key.size - 1] = '\0';
- } else {
- keys = "<bad key>";
- }
- if (data.size) {
- values = data.data;
- values[data.size - 1] = '\0';
- } else {
- values = "<bad value>";
- }
- values_len = strlen(values) + 1;
- if (keymatch(keys, prefix) && (cur = ast_malloc(sizeof(*cur) + strlen(keys) + 1 + values_len))) {
- cur->next = NULL;
- cur->key = cur->data + values_len;
- strcpy(cur->data, values);
- strcpy(cur->key, keys);
- if (last) {
- last->next = cur;
- } else {
- ret = cur;
- }
- last = cur;
- }
- }
- ast_mutex_unlock(&dblock);
- return ret;
-}
-
-void ast_db_freetree(struct ast_db_entry *dbe)
-{
- struct ast_db_entry *last;
- while (dbe) {
- last = dbe;
- dbe = dbe->next;
- free(last);
- }
-}
-
-static char database_show_usage[] =
-"Usage: database show [family [keytree]]\n"
-" Shows Asterisk database contents, optionally restricted\n"
-"to a given family, or family and keytree.\n";
-
-static char database_showkey_usage[] =
-"Usage: database showkey <keytree>\n"
-" Shows Asterisk database contents, restricted to a given key.\n";
-
-static char database_put_usage[] =
-"Usage: database put <family> <key> <value>\n"
-" Adds or updates an entry in the Asterisk database for\n"
-"a given family, key, and value.\n";
-
-static char database_get_usage[] =
-"Usage: database get <family> <key>\n"
-" Retrieves an entry in the Asterisk database for a given\n"
-"family and key.\n";
-
-static char database_del_usage[] =
-"Usage: database del <family> <key>\n"
-" Deletes an entry in the Asterisk database for a given\n"
-"family and key.\n";
-
-static char database_deltree_usage[] =
-"Usage: database deltree <family> [keytree]\n"
-" Deletes a family or specific keytree within a family\n"
-"in the Asterisk database.\n";
-
-struct ast_cli_entry cli_database[] = {
- { { "database", "show", NULL },
- database_show, "Shows database contents",
- database_show_usage },
-
- { { "database", "showkey", NULL },
- database_showkey, "Shows database contents",
- database_showkey_usage },
-
- { { "database", "get", NULL },
- database_get, "Gets database value",
- database_get_usage },
-
- { { "database", "put", NULL },
- database_put, "Adds/updates database value",
- database_put_usage },
-
- { { "database", "del", NULL },
- database_del, "Removes database key/value",
- database_del_usage },
-
- { { "database", "deltree", NULL },
- database_deltree, "Removes database keytree/values",
- database_deltree_usage },
-};
-
-static int manager_dbput(struct mansession *s, const struct message *m)
-{
- const char *family = astman_get_header(m, "Family");
- const char *key = astman_get_header(m, "Key");
- const char *val = astman_get_header(m, "Val");
- int res;
-
- if (ast_strlen_zero(family)) {
- astman_send_error(s, m, "No family specified");
- return 0;
- }
- if (ast_strlen_zero(key)) {
- astman_send_error(s, m, "No key specified");
- return 0;
- }
-
- res = ast_db_put(family, key, (char *) S_OR(val, ""));
- if (res) {
- astman_send_error(s, m, "Failed to update entry");
- } else {
- astman_send_ack(s, m, "Updated database successfully");
- }
- return 0;
-}
-
-static int manager_dbget(struct mansession *s, const struct message *m)
-{
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
- const char *family = astman_get_header(m, "Family");
- const char *key = astman_get_header(m, "Key");
- char tmp[256];
- int res;
-
- if (ast_strlen_zero(family)) {
- astman_send_error(s, m, "No family specified.");
- return 0;
- }
- if (ast_strlen_zero(key)) {
- astman_send_error(s, m, "No key specified.");
- return 0;
- }
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
-
- res = ast_db_get(family, key, tmp, sizeof(tmp));
- if (res) {
- astman_send_error(s, m, "Database entry not found");
- } else {
- astman_send_ack(s, m, "Result will follow");
- astman_append(s, "Event: DBGetResponse\r\n"
- "Family: %s\r\n"
- "Key: %s\r\n"
- "Val: %s\r\n"
- "%s"
- "\r\n",
- family, key, tmp, idText);
- }
- return 0;
-}
-
-int astdb_init(void)
-{
- dbinit();
- ast_cli_register_multiple(cli_database, sizeof(cli_database) / sizeof(struct ast_cli_entry));
- ast_manager_register("DBGet", EVENT_FLAG_SYSTEM, manager_dbget, "Get DB Entry");
- ast_manager_register("DBPut", EVENT_FLAG_SYSTEM, manager_dbput, "Put DB Entry");
- return 0;
-}
diff --git a/1.4/main/db1-ast/Makefile b/1.4/main/db1-ast/Makefile
deleted file mode 100644
index 4b9bb25d7..000000000
--- a/1.4/main/db1-ast/Makefile
+++ /dev/null
@@ -1,71 +0,0 @@
-# @(#)Makefile 8.9 (Berkeley) 7/14/94
-
-LIBDB= libdb1.a
-ARCH=$(shell uname -m)
-ifeq ($(ARCH),alpha)
-SOVER=2.1
-else
-SOVER=2
-endif
-
-ifeq ($(OSARCH),Darwin)
- OSARCH_DEFINE+=-D__Darwin__
-endif
-
-LIBDBSO=libdb.so.$(SOVER)
-PROG= db_dump185
-OBJ1= hash/hash.o hash/hash_bigkey.o hash/hash_buf.o hash/hash_func.o hash/hash_log2.o hash/hash_page.o \
- hash/ndbm.o
-OBJ2= btree/bt_close.o btree/bt_conv.o btree/bt_debug.o btree/bt_delete.o btree/bt_get.o btree/bt_open.o \
- btree/bt_overflow.o btree/bt_page.o btree/bt_put.o btree/bt_search.o btree/bt_seq.o btree/bt_split.o \
- btree/bt_utils.o
-OBJ3= db/db.o
-OBJ4= mpool/mpool.o
-OBJ5= recno/rec_close.o recno/rec_delete.o recno/rec_get.o recno/rec_open.o recno/rec_put.o recno/rec_search.o \
- recno/rec_seq.o recno/rec_utils.o
-MISC=
-OBJS= $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(MISC)
-SHOBJS= $(patsubst %.o,%.os,$(OBJS))
-
-include $(ASTTOPDIR)/Makefile.rules
-
-all: $(LIBDB) #$(LIBDBSO) $(PROG)
-
-$(LIBDB): $(OBJS)
- $(ECHO_PREFIX) echo " [AR] $^ -> $@"
- $(CMD_PREFIX) $(AR) cr $@ $^
- $(CMD_PREFIX) $(RANLIB) $@
-
-$(LIBDBSO): $(SHOBJS)
- $(CC) -Wl,-O1 -Wl,--version-script=libdb.map -Wl,-soname=$(LIBDBSO) -shared -o $@ $^
- ln -sf $@ libdb.so
-
-$(PROG): db_dump185.o $(LIBDBSO)
- $(CC) -o $@ db_dump185.o -L. -ldb
-
-clean-depend:
-
-clean:
- rm -f $(LIBDB) $(LIBDBSO) $(OBJS) $(SHOBJS) *.s *.i
-
-ASTCFLAGS:=-Wall -D__DBINTERFACE_PRIVATE -I. -I.. -Iinclude -Ihash -Ibtree -Irecno $(ASTCFLAGS)
-
-OSTYPE=$(shell uname -s)
-ifeq ($(OSTYPE),SunOS)
-ASTCFLAGS+=-I../../include -I../../include/solaris-compat -DSOLARIS
-endif
-
-db_dump185.o: db_dump185.c
- $(CL) -o $@ $<
-x%.o: hash/%.c
- $(CL) -Ihash $(OSARCH_DEFINE) -o $@ $<
-%.os: hash/%.c
- $(CL) -Ihash -fPIC -o $@ $<
-x%.o: btree/%.c
- $(CL) -Ibtree -o $@ $<
-%.os: btree/%.c
- $(CL) -Ibtree -fPIC -o $@ $<
-x%.o: recno/%.c
- $(CL) -Irecno -o $@ $<
-%.os: recno/%.c
- $(CL) -Irecno -fPIC -o $@ $<
diff --git a/1.4/main/db1-ast/btree/bt_close.c b/1.4/main/db1-ast/btree/bt_close.c
deleted file mode 100644
index 67a6e5340..000000000
--- a/1.4/main/db1-ast/btree/bt_close.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static int bt_meta __P((BTREE *));
-
-/*
- * BT_CLOSE -- Close a btree.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_close(dbp)
- DB *dbp;
-{
- BTREE *t;
- int fd;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Sync the tree. */
- if (__bt_sync(dbp, 0) == RET_ERROR)
- return (RET_ERROR);
-
- /* Close the memory pool. */
- if (mpool_close(t->bt_mp) == RET_ERROR)
- return (RET_ERROR);
-
- /* Free random memory. */
- if (t->bt_cursor.key.data != NULL) {
- free(t->bt_cursor.key.data);
- t->bt_cursor.key.size = 0;
- t->bt_cursor.key.data = NULL;
- }
- if (t->bt_rkey.data) {
- free(t->bt_rkey.data);
- t->bt_rkey.size = 0;
- t->bt_rkey.data = NULL;
- }
- if (t->bt_rdata.data) {
- free(t->bt_rdata.data);
- t->bt_rdata.size = 0;
- t->bt_rdata.data = NULL;
- }
-
- fd = t->bt_fd;
- free(t);
- free(dbp);
- return (close(fd) ? RET_ERROR : RET_SUCCESS);
-}
-
-/*
- * BT_SYNC -- sync the btree to disk.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_sync(dbp, flags)
- const DB *dbp;
- u_int flags;
-{
- BTREE *t;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Sync doesn't currently take any flags. */
- if (flags != 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
- return (RET_SUCCESS);
-
- if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
- return (RET_ERROR);
-
- if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
- F_CLR(t, B_MODIFIED);
-
- return (status);
-}
-
-/*
- * BT_META -- write the tree meta data to disk.
- *
- * Parameters:
- * t: tree
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_meta(t)
- BTREE *t;
-{
- BTMETA m;
- void *p;
-
- if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
- return (RET_ERROR);
-
- /* Fill in metadata. */
- m.magic = BTREEMAGIC;
- m.version = BTREEVERSION;
- m.psize = t->bt_psize;
- m.free = t->bt_free;
- m.nrecs = t->bt_nrecs;
- m.flags = F_ISSET(t, SAVEMETA);
-
- memmove(p, &m, sizeof(BTMETA));
- mpool_put(t->bt_mp, p, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/btree/bt_conv.c b/1.4/main/db1-ast/btree/bt_conv.c
deleted file mode 100644
index d2ebdc57b..000000000
--- a/1.4/main/db1-ast/btree/bt_conv.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static void mswap __P((PAGE *));
-
-/*
- * __BT_BPGIN, __BT_BPGOUT --
- * Convert host-specific number layout to/from the host-independent
- * format stored on disk.
- *
- * Parameters:
- * t: tree
- * pg: page number
- * h: page to convert
- */
-void
-__bt_pgin(t, pg, pp)
- void *t;
- pgno_t pg;
- void *pp;
-{
- PAGE *h;
- indx_t i, top;
- u_char flags;
- char *p;
-
- if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
- return;
- if (pg == P_META) {
- mswap(pp);
- return;
- }
-
- h = pp;
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prevpg);
- M_32_SWAP(h->nextpg);
- M_32_SWAP(h->flags);
- M_16_SWAP(h->lower);
- M_16_SWAP(h->upper);
-
- top = NEXTINDEX(h);
- if ((h->flags & P_TYPE) == P_BINTERNAL)
- for (i = 0; i < top; i++) {
- M_16_SWAP(h->linp[i]);
- p = (char *)GETBINTERNAL(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- if (*(u_char *)p & P_BIGKEY) {
- p += sizeof(u_char);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- else if ((h->flags & P_TYPE) == P_BLEAF)
- for (i = 0; i < top; i++) {
- M_16_SWAP(h->linp[i]);
- p = (char *)GETBLEAF(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- flags = *(u_char *)p;
- if (flags & (P_BIGKEY | P_BIGDATA)) {
- p += sizeof(u_char);
- if (flags & P_BIGKEY) {
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- if (flags & P_BIGDATA) {
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- }
-}
-
-void
-__bt_pgout(t, pg, pp)
- void *t;
- pgno_t pg;
- void *pp;
-{
- PAGE *h;
- indx_t i, top;
- u_char flags;
- char *p;
-
- if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
- return;
- if (pg == P_META) {
- mswap(pp);
- return;
- }
-
- h = pp;
- top = NEXTINDEX(h);
- if ((h->flags & P_TYPE) == P_BINTERNAL)
- for (i = 0; i < top; i++) {
- p = (char *)GETBINTERNAL(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- if (*(u_char *)p & P_BIGKEY) {
- p += sizeof(u_char);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- M_16_SWAP(h->linp[i]);
- }
- else if ((h->flags & P_TYPE) == P_BLEAF)
- for (i = 0; i < top; i++) {
- p = (char *)GETBLEAF(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- flags = *(u_char *)p;
- if (flags & (P_BIGKEY | P_BIGDATA)) {
- p += sizeof(u_char);
- if (flags & P_BIGKEY) {
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- if (flags & P_BIGDATA) {
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- M_16_SWAP(h->linp[i]);
- }
-
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prevpg);
- M_32_SWAP(h->nextpg);
- M_32_SWAP(h->flags);
- M_16_SWAP(h->lower);
- M_16_SWAP(h->upper);
-}
-
-/*
- * MSWAP -- Actually swap the bytes on the meta page.
- *
- * Parameters:
- * p: page to convert
- */
-static void
-mswap(pg)
- PAGE *pg;
-{
- char *p;
-
- p = (char *)pg;
- P_32_SWAP(p); /* magic */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* version */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* psize */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* free */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* nrecs */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* flags */
- p += sizeof(u_int32_t);
-}
diff --git a/1.4/main/db1-ast/btree/bt_debug.c b/1.4/main/db1-ast/btree/bt_debug.c
deleted file mode 100644
index e035851a8..000000000
--- a/1.4/main/db1-ast/btree/bt_debug.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-#ifdef DEBUG
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-/*
- * BT_DUMP -- Dump the tree
- *
- * Parameters:
- * dbp: pointer to the DB
- */
-void
-__bt_dump(dbp)
- DB *dbp;
-{
- BTREE *t;
- PAGE *h;
- pgno_t i;
- char *sep;
-
- t = dbp->internal;
- (void)fprintf(stderr, "%s: pgsz %d",
- F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
- if (F_ISSET(t, R_RECNO))
- (void)fprintf(stderr, " keys %lu", t->bt_nrecs);
-#undef X
-#define X(flag, name) \
- if (F_ISSET(t, flag)) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- if (t->flags != 0) {
- sep = " flags (";
- X(R_FIXLEN, "FIXLEN");
- X(B_INMEM, "INMEM");
- X(B_NODUPS, "NODUPS");
- X(B_RDONLY, "RDONLY");
- X(R_RECNO, "RECNO");
- X(B_METADIRTY,"METADIRTY");
- (void)fprintf(stderr, ")\n");
- }
-#undef X
-
- for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
- __bt_dpage(h);
- (void)mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * BT_DMPAGE -- Dump the meta page
- *
- * Parameters:
- * h: pointer to the PAGE
- */
-void
-__bt_dmpage(h)
- PAGE *h;
-{
- BTMETA *m;
- char *sep;
-
- m = (BTMETA *)h;
- (void)fprintf(stderr, "magic %lx\n", m->magic);
- (void)fprintf(stderr, "version %lu\n", m->version);
- (void)fprintf(stderr, "psize %lu\n", m->psize);
- (void)fprintf(stderr, "free %lu\n", m->free);
- (void)fprintf(stderr, "nrecs %lu\n", m->nrecs);
- (void)fprintf(stderr, "flags %lu", m->flags);
-#undef X
-#define X(flag, name) \
- if (m->flags & flag) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- if (m->flags) {
- sep = " (";
- X(B_NODUPS, "NODUPS");
- X(R_RECNO, "RECNO");
- (void)fprintf(stderr, ")");
- }
-}
-
-/*
- * BT_DNPAGE -- Dump the page
- *
- * Parameters:
- * n: page number to dump.
- */
-void
-__bt_dnpage(dbp, pgno)
- DB *dbp;
- pgno_t pgno;
-{
- BTREE *t;
- PAGE *h;
-
- t = dbp->internal;
- if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
- __bt_dpage(h);
- (void)mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * BT_DPAGE -- Dump the page
- *
- * Parameters:
- * h: pointer to the PAGE
- */
-void
-__bt_dpage(h)
- PAGE *h;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- RINTERNAL *ri;
- RLEAF *rl;
- indx_t cur, top;
- char *sep;
-
- (void)fprintf(stderr, " page %d: (", h->pgno);
-#undef X
-#define X(flag, name) \
- if (h->flags & flag) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- sep = "";
- X(P_BINTERNAL, "BINTERNAL") /* types */
- X(P_BLEAF, "BLEAF")
- X(P_RINTERNAL, "RINTERNAL") /* types */
- X(P_RLEAF, "RLEAF")
- X(P_OVERFLOW, "OVERFLOW")
- X(P_PRESERVE, "PRESERVE");
- (void)fprintf(stderr, ")\n");
-#undef X
-
- (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
- if (h->flags & P_OVERFLOW)
- return;
-
- top = NEXTINDEX(h);
- (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
- h->lower, h->upper, top);
- for (cur = 0; cur < top; cur++) {
- (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- bi = GETBINTERNAL(h, cur);
- (void)fprintf(stderr,
- "size %03d pgno %03d", bi->ksize, bi->pgno);
- if (bi->flags & P_BIGKEY)
- (void)fprintf(stderr, " (indirect)");
- else if (bi->ksize)
- (void)fprintf(stderr,
- " {%.*s}", (int)bi->ksize, bi->bytes);
- break;
- case P_RINTERNAL:
- ri = GETRINTERNAL(h, cur);
- (void)fprintf(stderr, "entries %03d pgno %03d",
- ri->nrecs, ri->pgno);
- break;
- case P_BLEAF:
- bl = GETBLEAF(h, cur);
- if (bl->flags & P_BIGKEY)
- (void)fprintf(stderr,
- "big key page %lu size %u/",
- *(pgno_t *)bl->bytes,
- *(u_int32_t *)(bl->bytes + sizeof(pgno_t)));
- else if (bl->ksize)
- (void)fprintf(stderr, "%s/", bl->bytes);
- if (bl->flags & P_BIGDATA)
- (void)fprintf(stderr,
- "big data page %lu size %u",
- *(pgno_t *)(bl->bytes + bl->ksize),
- *(u_int32_t *)(bl->bytes + bl->ksize +
- sizeof(pgno_t)));
- else if (bl->dsize)
- (void)fprintf(stderr, "%.*s",
- (int)bl->dsize, bl->bytes + bl->ksize);
- break;
- case P_RLEAF:
- rl = GETRLEAF(h, cur);
- if (rl->flags & P_BIGDATA)
- (void)fprintf(stderr,
- "big data page %lu size %u",
- *(pgno_t *)rl->bytes,
- *(u_int32_t *)(rl->bytes + sizeof(pgno_t)));
- else if (rl->dsize)
- (void)fprintf(stderr,
- "%.*s", (int)rl->dsize, rl->bytes);
- break;
- }
- (void)fprintf(stderr, "\n");
- }
-}
-#endif
-
-#ifdef STATISTICS
-/*
- * BT_STAT -- Gather/print the tree statistics
- *
- * Parameters:
- * dbp: pointer to the DB
- */
-void
-__bt_stat(dbp)
- DB *dbp;
-{
- extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit;
- extern u_long bt_sortsplit, bt_split;
- BTREE *t;
- PAGE *h;
- pgno_t i, pcont, pinternal, pleaf;
- u_long ifree, lfree, nkeys;
- int levels;
-
- t = dbp->internal;
- pcont = pinternal = pleaf = 0;
- nkeys = ifree = lfree = 0;
- for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- case P_RINTERNAL:
- ++pinternal;
- ifree += h->upper - h->lower;
- break;
- case P_BLEAF:
- case P_RLEAF:
- ++pleaf;
- lfree += h->upper - h->lower;
- nkeys += NEXTINDEX(h);
- break;
- case P_OVERFLOW:
- ++pcont;
- break;
- }
- (void)mpool_put(t->bt_mp, h, 0);
- }
-
- /* Count the levels of the tree. */
- for (i = P_ROOT, levels = 0 ;; ++levels) {
- h = mpool_get(t->bt_mp, i, 0);
- if (h->flags & (P_BLEAF|P_RLEAF)) {
- if (levels == 0)
- levels = 1;
- (void)mpool_put(t->bt_mp, h, 0);
- break;
- }
- i = F_ISSET(t, R_RECNO) ?
- GETRINTERNAL(h, 0)->pgno :
- GETBINTERNAL(h, 0)->pgno;
- (void)mpool_put(t->bt_mp, h, 0);
- }
-
- (void)fprintf(stderr, "%d level%s with %ld keys",
- levels, levels == 1 ? "" : "s", nkeys);
- if (F_ISSET(t, R_RECNO))
- (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
- (void)fprintf(stderr,
- "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
- pinternal + pleaf + pcont, pleaf, pinternal, pcont);
- (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
- bt_cache_hit, bt_cache_miss);
- (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
- bt_split, bt_rootsplit, bt_sortsplit);
- pleaf *= t->bt_psize - BTDATAOFF;
- if (pleaf)
- (void)fprintf(stderr,
- "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
- ((double)(pleaf - lfree) / pleaf) * 100,
- pleaf - lfree, lfree);
- pinternal *= t->bt_psize - BTDATAOFF;
- if (pinternal)
- (void)fprintf(stderr,
- "%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
- ((double)(pinternal - ifree) / pinternal) * 100,
- pinternal - ifree, ifree);
- if (bt_pfxsaved)
- (void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
- bt_pfxsaved);
-}
-#endif
diff --git a/1.4/main/db1-ast/btree/bt_delete.c b/1.4/main/db1-ast/btree/bt_delete.c
deleted file mode 100644
index e816c432a..000000000
--- a/1.4/main/db1-ast/btree/bt_delete.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static int __bt_bdelete __P((BTREE *, const DBT *));
-static int __bt_curdel __P((BTREE *, const DBT *, PAGE *, u_int));
-static int __bt_pdelete __P((BTREE *, PAGE *));
-static int __bt_relink __P((BTREE *, PAGE *));
-static int __bt_stkacq __P((BTREE *, PAGE **, CURSOR *));
-
-/*
- * __bt_delete
- * Delete the item(s) referenced by a key.
- *
- * Return RET_SPECIAL if the key is not found.
- */
-int
-__bt_delete(dbp, key, flags)
- const DB *dbp;
- const DBT *key;
- u_int flags;
-{
- BTREE *t;
- CURSOR *c;
- PAGE *h;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Check for change to a read-only tree. */
- if (F_ISSET(t, B_RDONLY)) {
- errno = EPERM;
- return (RET_ERROR);
- }
-
- switch (flags) {
- case 0:
- status = __bt_bdelete(t, key);
- break;
- case R_CURSOR:
- /*
- * If flags is R_CURSOR, delete the cursor. Must already
- * have started a scan and not have already deleted it.
- */
- c = &t->bt_cursor;
- if (F_ISSET(c, CURS_INIT)) {
- if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
- return (RET_ERROR);
-
- /*
- * If the page is about to be emptied, we'll need to
- * delete it, which means we have to acquire a stack.
- */
- if (NEXTINDEX(h) == 1)
- if (__bt_stkacq(t, &h, &t->bt_cursor))
- return (RET_ERROR);
-
- status = __bt_dleaf(t, NULL, h, c->pg.index);
-
- if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- } else
- mpool_put(t->bt_mp,
- h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);
- break;
- }
- /* FALLTHROUGH */
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
- if (status == RET_SUCCESS)
- F_SET(t, B_MODIFIED);
- return (status);
-}
-
-/*
- * __bt_stkacq --
- * Acquire a stack so we can delete a cursor entry.
- *
- * Parameters:
- * t: tree
- * hp: pointer to current, pinned PAGE pointer
- * c: pointer to the cursor
- *
- * Returns:
- * 0 on success, 1 on failure
- */
-static int
-__bt_stkacq(t, hp, c)
- BTREE *t;
- PAGE **hp;
- CURSOR *c;
-{
- BINTERNAL *bi;
- EPG *e;
- EPGNO *parent;
- PAGE *h;
- indx_t index = 0;
- pgno_t pgno;
- recno_t nextpg, prevpg;
- int exact, level;
-
- /*
- * Find the first occurrence of the key in the tree. Toss the
- * currently locked page so we don't hit an already-locked page.
- */
- h = *hp;
- mpool_put(t->bt_mp, h, 0);
- if ((e = __bt_search(t, &c->key, &exact)) == NULL)
- return (1);
- h = e->page;
-
- /* See if we got it in one shot. */
- if (h->pgno == c->pg.pgno)
- goto ret;
-
- /*
- * Move right, looking for the page. At each move we have to move
- * up the stack until we don't have to move to the next page. If
- * we have to change pages at an internal level, we have to fix the
- * stack back up.
- */
- while (h->pgno != c->pg.pgno) {
- if ((nextpg = h->nextpg) == P_INVALID)
- break;
- mpool_put(t->bt_mp, h, 0);
-
- /* Move up the stack. */
- for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (1);
-
- /* Move to the next index. */
- if (parent->index != NEXTINDEX(h) - 1) {
- index = parent->index + 1;
- BT_PUSH(t, h->pgno, index);
- break;
- }
- mpool_put(t->bt_mp, h, 0);
- }
-
- /* Restore the stack. */
- while (level--) {
- /* Push the next level down onto the stack. */
- bi = GETBINTERNAL(h, index);
- pgno = bi->pgno;
- BT_PUSH(t, pgno, 0);
-
- /* Lose the currently pinned page. */
- mpool_put(t->bt_mp, h, 0);
-
- /* Get the next level down. */
- if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
- return (1);
- index = 0;
- }
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
- return (1);
- }
-
- if (h->pgno == c->pg.pgno)
- goto ret;
-
- /* Reacquire the original stack. */
- mpool_put(t->bt_mp, h, 0);
- if ((e = __bt_search(t, &c->key, &exact)) == NULL)
- return (1);
- h = e->page;
-
- /*
- * Move left, looking for the page. At each move we have to move
- * up the stack until we don't have to change pages to move to the
- * next page. If we have to change pages at an internal level, we
- * have to fix the stack back up.
- */
- while (h->pgno != c->pg.pgno) {
- if ((prevpg = h->prevpg) == P_INVALID)
- break;
- mpool_put(t->bt_mp, h, 0);
-
- /* Move up the stack. */
- for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (1);
-
- /* Move to the next index. */
- if (parent->index != 0) {
- index = parent->index - 1;
- BT_PUSH(t, h->pgno, index);
- break;
- }
- mpool_put(t->bt_mp, h, 0);
- }
-
- /* Restore the stack. */
- while (level--) {
- /* Push the next level down onto the stack. */
- bi = GETBINTERNAL(h, index);
- pgno = bi->pgno;
-
- /* Lose the currently pinned page. */
- mpool_put(t->bt_mp, h, 0);
-
- /* Get the next level down. */
- if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
- return (1);
-
- index = NEXTINDEX(h) - 1;
- BT_PUSH(t, pgno, index);
- }
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
- return (1);
- }
-
-
-ret: mpool_put(t->bt_mp, h, 0);
- return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
-}
-
-/*
- * __bt_bdelete --
- * Delete all key/data pairs matching the specified key.
- *
- * Parameters:
- * t: tree
- * key: key to delete
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-static int
-__bt_bdelete(t, key)
- BTREE *t;
- const DBT *key;
-{
- EPG *e;
- PAGE *h;
- int deleted, exact, redo;
-
- deleted = 0;
-
- /* Find any matching record; __bt_search pins the page. */
-loop: if ((e = __bt_search(t, key, &exact)) == NULL)
- return (deleted ? RET_SUCCESS : RET_ERROR);
- if (!exact) {
- mpool_put(t->bt_mp, e->page, 0);
- return (deleted ? RET_SUCCESS : RET_SPECIAL);
- }
-
- /*
- * Delete forward, then delete backward, from the found key. If
- * there are duplicates and we reach either side of the page, do
- * the key search again, so that we get them all.
- */
- redo = 0;
- h = e->page;
- do {
- if (__bt_dleaf(t, key, h, e->index)) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- if (F_ISSET(t, B_NODUPS)) {
- if (NEXTINDEX(h) == 0) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- } else
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
- }
- deleted = 1;
- } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
-
- /* Check for right-hand edge of the page. */
- if (e->index == NEXTINDEX(h))
- redo = 1;
-
- /* Delete from the key to the beginning of the page. */
- while (e->index-- > 0) {
- if (__bt_cmp(t, key, e) != 0)
- break;
- if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- if (e->index == 0)
- redo = 1;
- }
-
- /* Check for an empty page. */
- if (NEXTINDEX(h) == 0) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- goto loop;
- }
-
- /* Put the page. */
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- if (redo)
- goto loop;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_pdelete --
- * Delete a single page from the tree.
- *
- * Parameters:
- * t: tree
- * h: leaf page
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- *
- * Side-effects:
- * mpool_put's the page
- */
-static int
-__bt_pdelete(t, h)
- BTREE *t;
- PAGE *h;
-{
- BINTERNAL *bi;
- PAGE *pg;
- EPGNO *parent;
- indx_t cnt, index, *ip, offset;
- u_int32_t nksize;
- char *from;
-
- /*
- * Walk the parent page stack -- a LIFO stack of the pages that were
- * traversed when we searched for the page where the delete occurred.
- * Each stack entry is a page number and a page index offset. The
- * offset is for the page traversed on the search. We've just deleted
- * a page, so we have to delete the key from the parent page.
- *
- * If the delete from the parent page makes it empty, this process may
- * continue all the way up the tree. We stop if we reach the root page
- * (which is never deleted, it's just not worth the effort) or if the
- * delete does not empty the page.
- */
- while ((parent = BT_POP(t)) != NULL) {
- /* Get the parent page. */
- if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (RET_ERROR);
-
- index = parent->index;
- bi = GETBINTERNAL(pg, index);
-
- /* Free any overflow pages. */
- if (bi->flags & P_BIGKEY &&
- __ovfl_delete(t, bi->bytes) == RET_ERROR) {
- mpool_put(t->bt_mp, pg, 0);
- return (RET_ERROR);
- }
-
- /*
- * Free the parent if it has only the one key and it's not the
- * root page. If it's the rootpage, turn it back into an empty
- * leaf page.
- */
- if (NEXTINDEX(pg) == 1) {
- if (pg->pgno == P_ROOT) {
- pg->lower = BTDATAOFF;
- pg->upper = t->bt_psize;
- pg->flags = P_BLEAF;
- } else {
- if (__bt_relink(t, pg) || __bt_free(t, pg))
- return (RET_ERROR);
- continue;
- }
- } else {
- /* Pack remaining key items at the end of the page. */
- nksize = NBINTERNAL(bi->ksize);
- from = (char *)pg + pg->upper;
- memmove(from + nksize, from, (char *)bi - from);
- pg->upper += nksize;
-
- /* Adjust indices' offsets, shift the indices down. */
- offset = pg->linp[index];
- for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nksize;
- for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];
- pg->lower -= sizeof(indx_t);
- }
-
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- break;
- }
-
- /* Free the leaf page, as long as it wasn't the root. */
- if (h->pgno == P_ROOT) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
- }
- return (__bt_relink(t, h) || __bt_free(t, h));
-}
-
-/*
- * __bt_dleaf --
- * Delete a single record from a leaf page.
- *
- * Parameters:
- * t: tree
- * key: referenced key
- * h: page
- * index: index on page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_dleaf(t, key, h, index)
- BTREE *t;
- const DBT *key;
- PAGE *h;
- u_int index;
-{
- BLEAF *bl;
- indx_t cnt, *ip, offset;
- u_int32_t nbytes;
- void *to;
- char *from;
-
- /* If this record is referenced by the cursor, delete the cursor. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&
- __bt_curdel(t, key, h, index))
- return (RET_ERROR);
-
- /* If the entry uses overflow pages, make them available for reuse. */
- to = bl = GETBLEAF(h, index);
- if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
- return (RET_ERROR);
- if (bl->flags & P_BIGDATA &&
- __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
- return (RET_ERROR);
-
- /* Pack the remaining key/data items at the end of the page. */
- nbytes = NBLEAF(bl);
- from = (char *)h + h->upper;
- memmove(from + nbytes, from, (char *)to - from);
- h->upper += nbytes;
-
- /* Adjust the indices' offsets, shift the indices down. */
- offset = h->linp[index];
- for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nbytes;
- for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
- h->lower -= sizeof(indx_t);
-
- /* If the cursor is on this page, adjust it as necessary. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)
- --t->bt_cursor.pg.index;
-
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_curdel --
- * Delete the cursor.
- *
- * Parameters:
- * t: tree
- * key: referenced key (or NULL)
- * h: page
- * index: index on page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-static int
-__bt_curdel(t, key, h, index)
- BTREE *t;
- const DBT *key;
- PAGE *h;
- u_int index;
-{
- CURSOR *c;
- EPG e;
- PAGE *pg;
- int curcopy, status;
-
- /*
- * If there are duplicates, move forward or backward to one.
- * Otherwise, copy the key into the cursor area.
- */
- c = &t->bt_cursor;
- F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);
-
- curcopy = 0;
- if (!F_ISSET(t, B_NODUPS)) {
- /*
- * We're going to have to do comparisons. If we weren't
- * provided a copy of the key, i.e. the user is deleting
- * the current cursor position, get one.
- */
- if (key == NULL) {
- e.page = h;
- e.index = index;
- if ((status = __bt_ret(t, &e,
- &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)
- return (status);
- curcopy = 1;
- key = &c->key;
- }
- /* Check previous key, if not at the beginning of the page. */
- if (index > 0) {
- e.page = h;
- e.index = index - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_BEFORE);
- goto dup2;
- }
- }
- /* Check next key, if not at the end of the page. */
- if (index < NEXTINDEX(h) - 1) {
- e.page = h;
- e.index = index + 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_AFTER);
- goto dup2;
- }
- }
- /* Check previous key if at the beginning of the page. */
- if (index == 0 && h->prevpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (RET_ERROR);
- e.page = pg;
- e.index = NEXTINDEX(pg) - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_BEFORE);
- goto dup1;
- }
- mpool_put(t->bt_mp, pg, 0);
- }
- /* Check next key if at the end of the page. */
- if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (RET_ERROR);
- e.page = pg;
- e.index = 0;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_AFTER);
-dup1: mpool_put(t->bt_mp, pg, 0);
-dup2: c->pg.pgno = e.page->pgno;
- c->pg.index = e.index;
- return (RET_SUCCESS);
- }
- mpool_put(t->bt_mp, pg, 0);
- }
- }
- e.page = h;
- e.index = index;
- if (curcopy || (status =
- __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {
- F_SET(c, CURS_ACQUIRE);
- return (RET_SUCCESS);
- }
- return (status);
-}
-
-/*
- * __bt_relink --
- * Link around a deleted page.
- *
- * Parameters:
- * t: tree
- * h: page to be deleted
- */
-static int
-__bt_relink(t, h)
- BTREE *t;
- PAGE *h;
-{
- PAGE *pg;
-
- if (h->nextpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (RET_ERROR);
- pg->prevpg = h->prevpg;
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- }
- if (h->prevpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (RET_ERROR);
- pg->nextpg = h->nextpg;
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- }
- return (0);
-}
diff --git a/1.4/main/db1-ast/btree/bt_get.c b/1.4/main/db1-ast/btree/bt_get.c
deleted file mode 100644
index b5e18022c..000000000
--- a/1.4/main/db1-ast/btree/bt_get.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-/*
- * __BT_GET -- Get a record from the btree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to find
- * data: data to return
- * flag: currently unused
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__bt_get(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- int exact, status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Get currently doesn't take any flags. */
- if (flags) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if ((e = __bt_search(t, key, &exact)) == NULL)
- return (RET_ERROR);
- if (!exact) {
- mpool_put(t->bt_mp, e->page, 0);
- return (RET_SPECIAL);
- }
-
- status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
-
- /*
- * If the user is doing concurrent access, we copied the
- * key/data, toss the page.
- */
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
diff --git a/1.4/main/db1-ast/btree/bt_open.c b/1.4/main/db1-ast/btree/bt_open.c
deleted file mode 100644
index 5d40e4593..000000000
--- a/1.4/main/db1-ast/btree/bt_open.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Implementation of btree access method for 4.4BSD.
- *
- * The design here was originally based on that of the btree access method
- * used in the Postgres database system at UC Berkeley. This implementation
- * is wholly independent of the Postgres code.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-#ifdef DEBUG
-#undef MINPSIZE
-#define MINPSIZE 128
-#endif
-
-static int byteorder __P((void));
-static int nroot __P((BTREE *));
-static int tmp __P((void));
-
-/*
- * __BT_OPEN -- Open a btree.
- *
- * Creates and fills a DB struct, and calls the routine that actually
- * opens the btree.
- *
- * Parameters:
- * fname: filename (NULL for in-memory trees)
- * flags: open flag bits
- * mode: open permission bits
- * b: BTREEINFO pointer
- *
- * Returns:
- * NULL on failure, pointer to DB on success.
- *
- */
-DB *
-__bt_open(fname, flags, mode, openinfo, dflags)
- const char *fname;
- int flags, mode, dflags;
- const BTREEINFO *openinfo;
-{
- struct stat sb;
- BTMETA m;
- BTREE *t;
- BTREEINFO b;
- DB *dbp;
- pgno_t ncache;
- ssize_t nr;
- int machine_lorder;
-
- t = NULL;
-
- /*
- * Intention is to make sure all of the user's selections are okay
- * here and then use them without checking. Can't be complete, since
- * we don't know the right page size, lorder or flags until the backing
- * file is opened. Also, the file's page size can cause the cachesize
- * to change.
- */
- machine_lorder = byteorder();
- if (openinfo) {
- b = *openinfo;
-
- /* Flags: R_DUP. */
- if (b.flags & ~(R_DUP))
- goto einval;
-
- /*
- * Page size must be indx_t aligned and >= MINPSIZE. Default
- * page size is set farther on, based on the underlying file
- * transfer size.
- */
- if (b.psize &&
- (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
- b.psize & (sizeof(indx_t) - 1)))
- goto einval;
-
- /* Minimum number of keys per page; absolute minimum is 2. */
- if (b.minkeypage) {
- if (b.minkeypage < 2)
- goto einval;
- } else
- b.minkeypage = DEFMINKEYPAGE;
-
- /* If no comparison, use default comparison and prefix. */
- if (b.compare == NULL) {
- b.compare = __bt_defcmp;
- if (b.prefix == NULL)
- b.prefix = __bt_defpfx;
- }
-
- if (b.lorder == 0)
- b.lorder = machine_lorder;
- } else {
- b.compare = __bt_defcmp;
- b.cachesize = 0;
- b.flags = 0;
- b.lorder = machine_lorder;
- b.minkeypage = DEFMINKEYPAGE;
- b.prefix = __bt_defpfx;
- b.psize = 0;
- }
-
- /* Check for the ubiquitous PDP-11. */
- if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
- goto einval;
-
- /* Allocate and initialize DB and BTREE structures. */
- if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
- goto err;
- memset(t, 0, sizeof(BTREE));
- t->bt_fd = -1; /* Don't close unopened fd on error. */
- t->bt_lorder = b.lorder;
- t->bt_order = NOT;
- t->bt_cmp = b.compare;
- t->bt_pfx = b.prefix;
- t->bt_rfd = -1;
-
- if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
- goto err;
- memset(t->bt_dbp, 0, sizeof(DB));
- if (t->bt_lorder != machine_lorder)
- F_SET(t, B_NEEDSWAP);
-
- dbp->type = DB_BTREE;
- dbp->internal = t;
- dbp->close = __bt_close;
- dbp->del = __bt_delete;
- dbp->fd = __bt_fd;
- dbp->get = __bt_get;
- dbp->put = __bt_put;
- dbp->seq = __bt_seq;
- dbp->sync = __bt_sync;
-
- /*
- * If no file name was supplied, this is an in-memory btree and we
- * open a backing temporary file. Otherwise, it's a disk-based tree.
- */
- if (fname) {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, B_RDONLY);
- break;
- case O_RDWR:
- break;
- case O_WRONLY:
- default:
- goto einval;
- }
-
- if ((t->bt_fd = open(fname, flags, mode)) < 0)
- goto err;
-
- } else {
- if ((flags & O_ACCMODE) != O_RDWR)
- goto einval;
- if ((t->bt_fd = tmp()) == -1)
- goto err;
- F_SET(t, B_INMEM);
- }
-
- if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
- goto err;
-
- if (fstat(t->bt_fd, &sb))
- goto err;
- if (sb.st_size) {
- if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
- goto err;
- if (nr != sizeof(BTMETA))
- goto eftype;
-
- /*
- * Read in the meta-data. This can change the notion of what
- * the lorder, page size and flags are, and, when the page size
- * changes, the cachesize value can change too. If the user
- * specified the wrong byte order for an existing database, we
- * don't bother to return an error, we just clear the NEEDSWAP
- * bit.
- */
- if (m.magic == BTREEMAGIC)
- F_CLR(t, B_NEEDSWAP);
- else {
- F_SET(t, B_NEEDSWAP);
- M_32_SWAP(m.magic);
- M_32_SWAP(m.version);
- M_32_SWAP(m.psize);
- M_32_SWAP(m.free);
- M_32_SWAP(m.nrecs);
- M_32_SWAP(m.flags);
- }
- if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
- goto eftype;
- if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
- m.psize & (sizeof(indx_t) - 1))
- goto eftype;
- if (m.flags & ~SAVEMETA)
- goto eftype;
- b.psize = m.psize;
- F_SET(t, m.flags);
- t->bt_free = m.free;
- t->bt_nrecs = m.nrecs;
- } else {
- /*
- * Set the page size to the best value for I/O to this file.
- * Don't overflow the page offset type.
- */
- if (b.psize == 0) {
-#ifdef _STATBUF_ST_BLKSIZE
- b.psize = sb.st_blksize;
-#endif
- if (b.psize < MINPSIZE)
- b.psize = MINPSIZE;
- if (b.psize > MAX_PAGE_OFFSET + 1)
- b.psize = MAX_PAGE_OFFSET + 1;
- }
-
- /* Set flag if duplicates permitted. */
- if (!(b.flags & R_DUP))
- F_SET(t, B_NODUPS);
-
- t->bt_free = P_INVALID;
- t->bt_nrecs = 0;
- F_SET(t, B_METADIRTY);
- }
-
- t->bt_psize = b.psize;
-
- /* Set the cache size; must be a multiple of the page size. */
- if (b.cachesize && b.cachesize & (b.psize - 1))
- b.cachesize += (~b.cachesize & (b.psize - 1)) + 1;
- if (b.cachesize < b.psize * MINCACHE)
- b.cachesize = b.psize * MINCACHE;
-
- /* Calculate number of pages to cache. */
- ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
-
- /*
- * The btree data structure requires that at least two keys can fit on
- * a page, but other than that there's no fixed requirement. The user
- * specified a minimum number per page, and we translated that into the
- * number of bytes a key/data pair can use before being placed on an
- * overflow page. This calculation includes the page header, the size
- * of the index referencing the leaf item and the size of the leaf item
- * structure. Also, don't let the user specify a minkeypage such that
- * a key/data pair won't fit even if both key and data are on overflow
- * pages.
- */
- t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
- (sizeof(indx_t) + NBLEAFDBT(0, 0));
- if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
- t->bt_ovflsize =
- NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
-
- /* Initialize the buffer pool. */
- if ((t->bt_mp =
- mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
- goto err;
- if (!F_ISSET(t, B_INMEM))
- mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
-
- /* Create a root page if new tree. */
- if (nroot(t) == RET_ERROR)
- goto err;
-
- /* Global flags. */
- if (dflags & DB_LOCK)
- F_SET(t, B_DB_LOCK);
- if (dflags & DB_SHMEM)
- F_SET(t, B_DB_SHMEM);
- if (dflags & DB_TXN)
- F_SET(t, B_DB_TXN);
-
- return (dbp);
-
-einval: errno = EINVAL;
- goto err;
-
-eftype: errno = EFTYPE;
- goto err;
-
-err: if (t) {
- if (t->bt_dbp)
- free(t->bt_dbp);
- if (t->bt_fd != -1)
- (void)close(t->bt_fd);
- free(t);
- }
- return (NULL);
-}
-
-/*
- * NROOT -- Create the root of a new tree.
- *
- * Parameters:
- * t: tree
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-nroot(t)
- BTREE *t;
-{
- PAGE *meta, *root;
- pgno_t npg;
-
- if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
- mpool_put(t->bt_mp, meta, 0);
- return (RET_SUCCESS);
- }
- if (errno != EINVAL) /* It's OK to not exist. */
- return (RET_ERROR);
- errno = 0;
-
- if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
- return (RET_ERROR);
-
- if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
- return (RET_ERROR);
-
- if (npg != P_ROOT)
- return (RET_ERROR);
- root->pgno = npg;
- root->prevpg = root->nextpg = P_INVALID;
- root->lower = BTDATAOFF;
- root->upper = t->bt_psize;
- root->flags = P_BLEAF;
- memset(meta, 0, t->bt_psize);
- mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
- mpool_put(t->bt_mp, root, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-static int
-tmp()
-{
- sigset_t set, oset;
- int fd;
- const char *envtmp;
- char *path;
- static const char fmt[] = "%s/bt.XXXXXX";
- size_t n;
-
- envtmp = getenv("TMPDIR");
- if (!envtmp)
- envtmp = "/tmp";
- n = strlen (envtmp) + sizeof fmt;
-#ifdef __GNUC__
- path = __builtin_alloca(n);
-#else
- path = malloc(n);
-#endif
- (void)snprintf(path, n, fmt, envtmp ? envtmp : "/tmp");
-
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((fd = mkstemp(path)) != -1)
- (void)unlink(path);
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
-#ifndef __GNUC__
- free(path);
-#endif
- return(fd);
-}
-
-static int
-byteorder()
-{
- u_int32_t x;
- u_char *p;
-
- x = 0x01020304;
- p = (u_char *)&x;
- switch (*p) {
- case 1:
- return (BIG_ENDIAN);
- case 4:
- return (LITTLE_ENDIAN);
- default:
- return (0);
- }
-}
-
-int
-__bt_fd(dbp)
- const DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* In-memory database can't have a file descriptor. */
- if (F_ISSET(t, B_INMEM)) {
- errno = ENOENT;
- return (-1);
- }
- return (t->bt_fd);
-}
diff --git a/1.4/main/db1-ast/btree/bt_overflow.c b/1.4/main/db1-ast/btree/bt_overflow.c
deleted file mode 100644
index d8f310d91..000000000
--- a/1.4/main/db1-ast/btree/bt_overflow.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-/*
- * Big key/data code.
- *
- * Big key and data entries are stored on linked lists of pages. The initial
- * reference is byte string stored with the key or data and is the page number
- * and size. The actual record is stored in a chain of pages linked by the
- * nextpg field of the PAGE header.
- *
- * The first page of the chain has a special property. If the record is used
- * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
- * in the header.
- *
- * XXX
- * A single DBT is written to each chain, so a lot of space on the last page
- * is wasted. This is a fairly major bug for some data sets.
- */
-
-/*
- * __OVFL_GET -- Get an overflow key/data item.
- *
- * Parameters:
- * t: tree
- * p: pointer to { pgno_t, u_int32_t }
- * buf: storage address
- * bufsz: storage size
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_get(t, p, ssz, buf, bufsz)
- BTREE *t;
- void *p;
- size_t *ssz;
- void **buf;
- size_t *bufsz;
-{
- PAGE *h;
- pgno_t pg;
- size_t nb, plen;
- u_int32_t sz;
-
- memmove(&pg, p, sizeof(pgno_t));
- memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
- *ssz = sz;
-
-#ifdef DEBUG
- if (pg == P_INVALID || sz == 0)
- abort();
-#endif
- /* Make the buffer bigger as necessary. */
- if (*bufsz < sz) {
- *buf = (char *)(*buf == NULL ? malloc(sz) : realloc(*buf, sz));
- if (*buf == NULL)
- return (RET_ERROR);
- *bufsz = sz;
- }
-
- /*
- * Step through the linked list of pages, copying the data on each one
- * into the buffer. Never copy more than the data's length.
- */
- plen = t->bt_psize - BTDATAOFF;
- for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- nb = MIN(sz, plen);
- memmove(p, (char *)h + BTDATAOFF, nb);
- mpool_put(t->bt_mp, h, 0);
-
- if ((sz -= nb) == 0)
- break;
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __OVFL_PUT -- Store an overflow key/data item.
- *
- * Parameters:
- * t: tree
- * data: DBT to store
- * pgno: storage page number
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_put(t, dbt, pg)
- BTREE *t;
- const DBT *dbt;
- pgno_t *pg;
-{
- PAGE *h, *last;
- void *p;
- pgno_t npg;
- size_t nb, plen;
- u_int32_t sz;
-
- /*
- * Allocate pages and copy the key/data record into them. Store the
- * number of the first page in the chain.
- */
- plen = t->bt_psize - BTDATAOFF;
- for (last = NULL, p = dbt->data, sz = dbt->size;;
- p = (char *)p + plen, last = h) {
- if ((h = __bt_new(t, &npg)) == NULL)
- return (RET_ERROR);
-
- h->pgno = npg;
- h->nextpg = h->prevpg = P_INVALID;
- h->flags = P_OVERFLOW;
- h->lower = h->upper = 0;
-
- nb = MIN(sz, plen);
- memmove((char *)h + BTDATAOFF, p, nb);
-
- if (last) {
- last->nextpg = h->pgno;
- mpool_put(t->bt_mp, last, MPOOL_DIRTY);
- } else
- *pg = h->pgno;
-
- if ((sz -= nb) == 0) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- }
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __OVFL_DELETE -- Delete an overflow chain.
- *
- * Parameters:
- * t: tree
- * p: pointer to { pgno_t, u_int32_t }
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_delete(t, p)
- BTREE *t;
- void *p;
-{
- PAGE *h;
- pgno_t pg;
- size_t plen;
- u_int32_t sz;
-
- memmove(&pg, p, sizeof(pgno_t));
- memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
-
-#ifdef DEBUG
- if (pg == P_INVALID || sz == 0)
- abort();
-#endif
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Don't delete chains used by internal pages. */
- if (h->flags & P_PRESERVE) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SUCCESS);
- }
-
- /* Step through the chain, calling the free routine for each page. */
- for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
- pg = h->nextpg;
- __bt_free(t, h);
- if (sz <= plen)
- break;
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- }
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/btree/bt_page.c b/1.4/main/db1-ast/btree/bt_page.c
deleted file mode 100644
index e77a1d6b5..000000000
--- a/1.4/main/db1-ast/btree/bt_page.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-/*
- * __bt_free --
- * Put a page on the freelist.
- *
- * Parameters:
- * t: tree
- * h: page to free
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- *
- * Side-effect:
- * mpool_put's the page.
- */
-int
-__bt_free(t, h)
- BTREE *t;
- PAGE *h;
-{
- /* Insert the page at the head of the free list. */
- h->prevpg = P_INVALID;
- h->nextpg = t->bt_free;
- t->bt_free = h->pgno;
- F_SET(t, B_METADIRTY);
-
- /* Make sure the page gets written back. */
- return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
-}
-
-/*
- * __bt_new --
- * Get a new page, preferably from the freelist.
- *
- * Parameters:
- * t: tree
- * npg: storage for page number.
- *
- * Returns:
- * Pointer to a page, NULL on error.
- */
-PAGE *
-__bt_new(t, npg)
- BTREE *t;
- pgno_t *npg;
-{
- PAGE *h;
-
- if (t->bt_free != P_INVALID &&
- (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
- *npg = t->bt_free;
- t->bt_free = h->nextpg;
- F_SET(t, B_METADIRTY);
- return (h);
- }
- return (mpool_new(t->bt_mp, npg));
-}
diff --git a/1.4/main/db1-ast/btree/bt_put.c b/1.4/main/db1-ast/btree/bt_put.c
deleted file mode 100644
index aeb0bb16c..000000000
--- a/1.4/main/db1-ast/btree/bt_put.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *));
-
-/*
- * __BT_PUT -- Add a btree item to the tree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key
- * data: data
- * flag: R_NOOVERWRITE
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
- * tree and R_NOOVERWRITE specified.
- */
-int
-__bt_put(dbp, key, data, flags)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int flags;
-{
- BTREE *t;
- DBT tkey, tdata;
- EPG *e = 0;
- PAGE *h;
- indx_t index, nxtindex;
- pgno_t pg;
- u_int32_t nbytes;
- int dflags, exact, status;
- char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Check for change to a read-only tree. */
- if (F_ISSET(t, B_RDONLY)) {
- errno = EPERM;
- return (RET_ERROR);
- }
-
- switch (flags) {
- case 0:
- case R_NOOVERWRITE:
- break;
- case R_CURSOR:
- /*
- * If flags is R_CURSOR, put the cursor. Must already
- * have started a scan and not have already deleted it.
- */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor,
- CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
- break;
- /* FALLTHROUGH */
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * If the key/data pair won't fit on a page, store it on overflow
- * pages. Only put the key on the overflow page if the pair are
- * still too big after moving the data to an overflow page.
- *
- * XXX
- * If the insert fails later on, the overflow pages aren't recovered.
- */
- dflags = 0;
- if (key->size + data->size > t->bt_ovflsize) {
- if (key->size > t->bt_ovflsize) {
-storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
- return (RET_ERROR);
- tkey.data = kb;
- tkey.size = NOVFLSIZE;
- memmove(kb, &pg, sizeof(pgno_t));
- memmove(kb + sizeof(pgno_t),
- &key->size, sizeof(u_int32_t));
- dflags |= P_BIGKEY;
- key = &tkey;
- }
- if (key->size + data->size > t->bt_ovflsize) {
- if (__ovfl_put(t, data, &pg) == RET_ERROR)
- return (RET_ERROR);
- tdata.data = db;
- tdata.size = NOVFLSIZE;
- memmove(db, &pg, sizeof(pgno_t));
- memmove(db + sizeof(pgno_t),
- &data->size, sizeof(u_int32_t));
- dflags |= P_BIGDATA;
- data = &tdata;
- }
- if (key->size + data->size > t->bt_ovflsize)
- goto storekey;
- }
-
- /* Replace the cursor. */
- if (flags == R_CURSOR) {
- if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
- return (RET_ERROR);
- index = t->bt_cursor.pg.index;
- goto delete;
- }
-
- /*
- * Find the key to delete, or, the location at which to insert.
- * Bt_fast and __bt_search both pin the returned page.
- */
- if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
- if ((e = __bt_search(t, key, &exact)) == NULL)
- return (RET_ERROR);
- h = e->page;
- index = e->index;
-
- /*
- * Add the key/data pair to the tree. If an identical key is already
- * in the tree, and R_NOOVERWRITE is set, an error is returned. If
- * R_NOOVERWRITE is not set, the key is either added (if duplicates are
- * permitted) or an error is returned.
- */
- switch (flags) {
- case R_NOOVERWRITE:
- if (!exact)
- break;
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- default:
- if (!exact || !F_ISSET(t, B_NODUPS))
- break;
- /*
- * !!!
- * Note, the delete may empty the page, so we need to put a
- * new entry into the page immediately.
- */
-delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- break;
- }
-
- /*
- * If not enough room, or the user has put a ceiling on the number of
- * keys permitted in the page, split the page. The split code will
- * insert the key and data and unpin the current page. If inserting
- * into the offset array, shift the pointers up.
- */
- nbytes = NBLEAFDBT(key->size, data->size);
- if ((u_int32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t)) {
- if ((status = __bt_split(t, h, key,
- data, dflags, nbytes, index)) != RET_SUCCESS)
- return (status);
- goto success;
- }
-
- if (index < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + index + 1, h->linp + index,
- (nxtindex - index) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
-
- h->linp[index] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_BLEAF(dest, key, data, dflags);
-
- /* If the cursor is on this page, adjust it as necessary. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index)
- ++t->bt_cursor.pg.index;
-
- if (t->bt_order == NOT) {
- if (h->nextpg == P_INVALID) {
- if (index == NEXTINDEX(h) - 1) {
- t->bt_order = FORWARD;
- t->bt_last.index = index;
- t->bt_last.pgno = h->pgno;
- }
- } else if (h->prevpg == P_INVALID) {
- if (index == 0) {
- t->bt_order = BACK;
- t->bt_last.index = 0;
- t->bt_last.pgno = h->pgno;
- }
- }
- }
-
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
-success:
- if (flags == R_SETCURSOR)
- __bt_setcur(t, e->page->pgno, e->index);
-
- F_SET(t, B_MODIFIED);
- return (RET_SUCCESS);
-}
-
-#ifdef STATISTICS
-u_long bt_cache_hit, bt_cache_miss;
-#endif
-
-/*
- * BT_FAST -- Do a quick check for sorted data.
- *
- * Parameters:
- * t: tree
- * key: key to insert
- *
- * Returns:
- * EPG for new record or NULL if not found.
- */
-static EPG *
-bt_fast(t, key, data, exactp)
- BTREE *t;
- const DBT *key, *data;
- int *exactp;
-{
- PAGE *h;
- u_int32_t nbytes;
- int cmp;
-
- if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
- t->bt_order = NOT;
- return (NULL);
- }
- t->bt_cur.page = h;
- t->bt_cur.index = t->bt_last.index;
-
- /*
- * If won't fit in this page or have too many keys in this page,
- * have to search to get split stack.
- */
- nbytes = NBLEAFDBT(key->size, data->size);
- if ((u_int32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t))
- goto miss;
-
- if (t->bt_order == FORWARD) {
- if (t->bt_cur.page->nextpg != P_INVALID)
- goto miss;
- if (t->bt_cur.index != NEXTINDEX(h) - 1)
- goto miss;
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
- goto miss;
- t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
- } else {
- if (t->bt_cur.page->prevpg != P_INVALID)
- goto miss;
- if (t->bt_cur.index != 0)
- goto miss;
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
- goto miss;
- t->bt_last.index = 0;
- }
- *exactp = cmp == 0;
-#ifdef STATISTICS
- ++bt_cache_hit;
-#endif
- return (&t->bt_cur);
-
-miss:
-#ifdef STATISTICS
- ++bt_cache_miss;
-#endif
- t->bt_order = NOT;
- mpool_put(t->bt_mp, h, 0);
- return (NULL);
-}
diff --git a/1.4/main/db1-ast/btree/bt_search.c b/1.4/main/db1-ast/btree/bt_search.c
deleted file mode 100644
index 623f43949..000000000
--- a/1.4/main/db1-ast/btree/bt_search.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static int __bt_snext __P((BTREE *, PAGE *, const DBT *, int *));
-static int __bt_sprev __P((BTREE *, PAGE *, const DBT *, int *));
-
-/*
- * __bt_search --
- * Search a btree for a key.
- *
- * Parameters:
- * t: tree to search
- * key: key to find
- * exactp: pointer to exact match flag
- *
- * Returns:
- * The EPG for matching record, if any, or the EPG for the location
- * of the key, if it were inserted into the tree, is entered into
- * the bt_cur field of the tree. A pointer to the field is returned.
- */
-EPG *
-__bt_search(t, key, exactp)
- BTREE *t;
- const DBT *key;
- int *exactp;
-{
- PAGE *h;
- indx_t base, index, lim;
- pgno_t pg;
- int cmp;
-
- BT_CLR(t);
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (NULL);
-
- /* Do a binary search on the current page. */
- t->bt_cur.page = h;
- for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
- t->bt_cur.index = index = base + (lim >> 1);
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) {
- if (h->flags & P_BLEAF) {
- *exactp = 1;
- return (&t->bt_cur);
- }
- goto next;
- }
- if (cmp > 0) {
- base = index + 1;
- --lim;
- }
- }
-
- /*
- * If it's a leaf page, we're almost done. If no duplicates
- * are allowed, or we have an exact match, we're done. Else,
- * it's possible that there were matching keys on this page,
- * which later deleted, and we're on a page with no matches
- * while there are matches on other pages. If at the start or
- * end of a page, check the adjacent page.
- */
- if (h->flags & P_BLEAF) {
- if (!F_ISSET(t, B_NODUPS)) {
- if (base == 0 &&
- h->prevpg != P_INVALID &&
- __bt_sprev(t, h, key, exactp))
- return (&t->bt_cur);
- if (base == NEXTINDEX(h) &&
- h->nextpg != P_INVALID &&
- __bt_snext(t, h, key, exactp))
- return (&t->bt_cur);
- }
- *exactp = 0;
- t->bt_cur.index = base;
- return (&t->bt_cur);
- }
-
- /*
- * No match found. Base is the smallest index greater than
- * key and may be zero or a last + 1 index. If it's non-zero,
- * decrement by one, and record the internal page which should
- * be a parent page for the key. If a split later occurs, the
- * inserted page will be to the right of the saved page.
- */
- index = base ? base - 1 : base;
-
-next: BT_PUSH(t, h->pgno, index);
- pg = GETBINTERNAL(h, index)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * __bt_snext --
- * Check for an exact match after the key.
- *
- * Parameters:
- * t: tree
- * h: current page
- * key: key
- * exactp: pointer to exact match flag
- *
- * Returns:
- * If an exact match found.
- */
-static int
-__bt_snext(t, h, key, exactp)
- BTREE *t;
- PAGE *h;
- const DBT *key;
- int *exactp;
-{
- EPG e;
-
- /*
- * Get the next page. The key is either an exact
- * match, or not as good as the one we already have.
- */
- if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (0);
- e.index = 0;
- if (__bt_cmp(t, key, &e) == 0) {
- mpool_put(t->bt_mp, h, 0);
- t->bt_cur = e;
- *exactp = 1;
- return (1);
- }
- mpool_put(t->bt_mp, e.page, 0);
- return (0);
-}
-
-/*
- * __bt_sprev --
- * Check for an exact match before the key.
- *
- * Parameters:
- * t: tree
- * h: current page
- * key: key
- * exactp: pointer to exact match flag
- *
- * Returns:
- * If an exact match found.
- */
-static int
-__bt_sprev(t, h, key, exactp)
- BTREE *t;
- PAGE *h;
- const DBT *key;
- int *exactp;
-{
- EPG e;
-
- /*
- * Get the previous page. The key is either an exact
- * match, or not as good as the one we already have.
- */
- if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (0);
- e.index = NEXTINDEX(e.page) - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- mpool_put(t->bt_mp, h, 0);
- t->bt_cur = e;
- *exactp = 1;
- return (1);
- }
- mpool_put(t->bt_mp, e.page, 0);
- return (0);
-}
diff --git a/1.4/main/db1-ast/btree/bt_seq.c b/1.4/main/db1-ast/btree/bt_seq.c
deleted file mode 100644
index 3f1724274..000000000
--- a/1.4/main/db1-ast/btree/bt_seq.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static int __bt_first __P((BTREE *, const DBT *, EPG *, int *));
-static int __bt_seqadv __P((BTREE *, EPG *, int));
-static int __bt_seqset __P((BTREE *, EPG *, DBT *, int));
-
-/*
- * Sequential scan support.
- *
- * The tree can be scanned sequentially, starting from either end of the
- * tree or from any specific key. A scan request before any scanning is
- * done is initialized as starting from the least node.
- */
-
-/*
- * __bt_seq --
- * Btree sequential scan interface.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key for positioning and return value
- * data: data return value
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-int
-__bt_seq(dbp, key, data, flags)
- const DB *dbp;
- DBT *key, *data;
- u_int flags;
-{
- BTREE *t;
- EPG e;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /*
- * If scan uninitialized as yet, or starting at a specific record, set
- * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin
- * the page the cursor references if they're successful.
- */
- switch (flags) {
- case R_NEXT:
- case R_PREV:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- status = __bt_seqadv(t, &e, flags);
- break;
- }
- /* FALLTHROUGH */
- case R_FIRST:
- case R_LAST:
- case R_CURSOR:
- status = __bt_seqset(t, &e, key, flags);
- break;
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (status == RET_SUCCESS) {
- __bt_setcur(t, e.page->pgno, e.index);
-
- status =
- __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0);
-
- /*
- * If the user is doing concurrent access, we copied the
- * key/data, toss the page.
- */
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e.page, 0);
- else
- t->bt_pinned = e.page;
- }
- return (status);
-}
-
-/*
- * __bt_seqset --
- * Set the sequential scan to a specific key.
- *
- * Parameters:
- * t: tree
- * ep: storage for returned key
- * key: key for initial scan position
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
- *
- * Side effects:
- * Pins the page the cursor references.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-static int
-__bt_seqset(t, ep, key, flags)
- BTREE *t;
- EPG *ep;
- DBT *key;
- int flags;
-{
- PAGE *h;
- pgno_t pg;
- int exact;
-
- /*
- * Find the first, last or specific key in the tree and point the
- * cursor at it. The cursor may not be moved until a new key has
- * been found.
- */
- switch (flags) {
- case R_CURSOR: /* Keyed scan. */
- /*
- * Find the first instance of the key or the smallest key
- * which is greater than or equal to the specified key.
- */
- if (key->data == NULL || key->size == 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
- return (__bt_first(t, key, ep, &exact));
- case R_FIRST: /* First record. */
- case R_NEXT:
- /* Walk down the left-hand side of the tree. */
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Check for an empty tree. */
- if (NEXTINDEX(h) == 0) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- }
-
- if (h->flags & (P_BLEAF | P_RLEAF))
- break;
- pg = GETBINTERNAL(h, 0)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
- ep->page = h;
- ep->index = 0;
- break;
- case R_LAST: /* Last record. */
- case R_PREV:
- /* Walk down the right-hand side of the tree. */
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Check for an empty tree. */
- if (NEXTINDEX(h) == 0) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- }
-
- if (h->flags & (P_BLEAF | P_RLEAF))
- break;
- pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
-
- ep->page = h;
- ep->index = NEXTINDEX(h) - 1;
- break;
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_seqadvance --
- * Advance the sequential scan.
- *
- * Parameters:
- * t: tree
- * flags: R_NEXT, R_PREV
- *
- * Side effects:
- * Pins the page the new key/data record is on.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-static int
-__bt_seqadv(t, ep, flags)
- BTREE *t;
- EPG *ep;
- int flags;
-{
- CURSOR *c;
- PAGE *h;
- indx_t index = 0;
- pgno_t pg;
- int exact;
-
- /*
- * There are a couple of states that we can be in. The cursor has
- * been initialized by the time we get here, but that's all we know.
- */
- c = &t->bt_cursor;
-
- /*
- * The cursor was deleted where there weren't any duplicate records,
- * so the key was saved. Find out where that key would go in the
- * current tree. It doesn't matter if the returned key is an exact
- * match or not -- if it's an exact match, the record was added after
- * the delete so we can just return it. If not, as long as there's
- * a record there, return it.
- */
- if (F_ISSET(c, CURS_ACQUIRE))
- return (__bt_first(t, &c->key, ep, &exact));
-
- /* Get the page referenced by the cursor. */
- if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
- return (RET_ERROR);
-
- /*
- * Find the next/previous record in the tree and point the cursor at
- * it. The cursor may not be moved until a new key has been found.
- */
- switch (flags) {
- case R_NEXT: /* Next record. */
- /*
- * The cursor was deleted in duplicate records, and moved
- * forward to a record that has yet to be returned. Clear
- * that flag, and return the record.
- */
- if (F_ISSET(c, CURS_AFTER))
- goto usecurrent;
- index = c->pg.index;
- if (++index == NEXTINDEX(h)) {
- pg = h->nextpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- index = 0;
- }
- break;
- case R_PREV: /* Previous record. */
- /*
- * The cursor was deleted in duplicate records, and moved
- * backward to a record that has yet to be returned. Clear
- * that flag, and return the record.
- */
- if (F_ISSET(c, CURS_BEFORE)) {
-usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
- ep->page = h;
- ep->index = c->pg.index;
- return (RET_SUCCESS);
- }
- index = c->pg.index;
- if (index == 0) {
- pg = h->prevpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- index = NEXTINDEX(h) - 1;
- } else
- --index;
- break;
- }
-
- ep->page = h;
- ep->index = index;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_first --
- * Find the first entry.
- *
- * Parameters:
- * t: the tree
- * key: the key
- * erval: return EPG
- * exactp: pointer to exact match flag
- *
- * Returns:
- * The first entry in the tree greater than or equal to key,
- * or RET_SPECIAL if no such key exists.
- */
-static int
-__bt_first(t, key, erval, exactp)
- BTREE *t;
- const DBT *key;
- EPG *erval;
- int *exactp;
-{
- PAGE *h;
- EPG *ep, save;
- pgno_t pg;
-
- /*
- * Find any matching record; __bt_search pins the page.
- *
- * If it's an exact match and duplicates are possible, walk backwards
- * in the tree until we find the first one. Otherwise, make sure it's
- * a valid key (__bt_search may return an index just past the end of a
- * page) and return it.
- */
- if ((ep = __bt_search(t, key, exactp)) == NULL)
- return (RET_SPECIAL);
- if (*exactp) {
- if (F_ISSET(t, B_NODUPS)) {
- *erval = *ep;
- return (RET_SUCCESS);
- }
-
- /*
- * Walk backwards, as long as the entry matches and there are
- * keys left in the tree. Save a copy of each match in case
- * we go too far.
- */
- save = *ep;
- h = ep->page;
- do {
- if (save.page->pgno != ep->page->pgno) {
- mpool_put(t->bt_mp, save.page, 0);
- save = *ep;
- } else
- save.index = ep->index;
-
- /*
- * Don't unpin the page the last (or original) match
- * was on, but make sure it's unpinned if an error
- * occurs.
- */
- if (ep->index == 0) {
- if (h->prevpg == P_INVALID)
- break;
- if (h->pgno != save.page->pgno)
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp,
- h->prevpg, 0)) == NULL) {
- if (h->pgno == save.page->pgno)
- mpool_put(t->bt_mp,
- save.page, 0);
- return (RET_ERROR);
- }
- ep->page = h;
- ep->index = NEXTINDEX(h);
- }
- --ep->index;
- } while (__bt_cmp(t, key, ep) == 0);
-
- /*
- * Reach here with the last page that was looked at pinned,
- * which may or may not be the same as the last (or original)
- * match page. If it's not useful, release it.
- */
- if (h->pgno != save.page->pgno)
- mpool_put(t->bt_mp, h, 0);
-
- *erval = save;
- return (RET_SUCCESS);
- }
-
- /* If at the end of a page, find the next entry. */
- if (ep->index == NEXTINDEX(ep->page)) {
- h = ep->page;
- pg = h->nextpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- ep->index = 0;
- ep->page = h;
- }
- *erval = *ep;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_setcur --
- * Set the cursor to an entry in the tree.
- *
- * Parameters:
- * t: the tree
- * pgno: page number
- * index: page index
- */
-void
-__bt_setcur(t, pgno, index)
- BTREE *t;
- pgno_t pgno;
- u_int index;
-{
- /* Lose any already deleted key. */
- if (t->bt_cursor.key.data != NULL) {
- free(t->bt_cursor.key.data);
- t->bt_cursor.key.size = 0;
- t->bt_cursor.key.data = NULL;
- }
- F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE);
-
- /* Update the cursor. */
- t->bt_cursor.pg.pgno = pgno;
- t->bt_cursor.pg.index = index;
- F_SET(&t->bt_cursor, CURS_INIT);
-}
diff --git a/1.4/main/db1-ast/btree/bt_split.c b/1.4/main/db1-ast/btree/bt_split.c
deleted file mode 100644
index 8fede1e45..000000000
--- a/1.4/main/db1-ast/btree/bt_split.c
+++ /dev/null
@@ -1,829 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *));
-static PAGE *bt_page
- __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
-static int bt_preserve __P((BTREE *, pgno_t));
-static PAGE *bt_psplit
- __P((BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t));
-static PAGE *bt_root
- __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
-static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *));
-static recno_t rec_total __P((PAGE *));
-
-#ifdef STATISTICS
-u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
-#endif
-
-/*
- * __BT_SPLIT -- Split the tree.
- *
- * Parameters:
- * t: tree
- * sp: page to split
- * key: key to insert
- * data: data to insert
- * flags: BIGKEY/BIGDATA flags
- * ilen: insert length
- * skip: index to leave open
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_split(t, sp, key, data, flags, ilen, argskip)
- BTREE *t;
- PAGE *sp;
- const DBT *key, *data;
- int flags;
- size_t ilen;
- u_int32_t argskip;
-{
- BINTERNAL *bi = 0;
- BLEAF *bl = 0, *tbl;
- DBT a, b;
- EPGNO *parent;
- PAGE *h, *l, *r, *lchild, *rchild;
- indx_t nxtindex;
- u_int16_t skip;
- u_int32_t n, nbytes, nksize = 0;
- int parentsplit;
- char *dest;
-
- /*
- * Split the page into two pages, l and r. The split routines return
- * a pointer to the page into which the key should be inserted and with
- * skip set to the offset which should be used. Additionally, l and r
- * are pinned.
- */
- skip = argskip;
- h = sp->pgno == P_ROOT ?
- bt_root(t, sp, &l, &r, &skip, ilen) :
- bt_page(t, sp, &l, &r, &skip, ilen);
- if (h == NULL)
- return (RET_ERROR);
-
- /*
- * Insert the new key/data pair into the leaf page. (Key inserts
- * always cause a leaf page to split first.)
- */
- h->linp[skip] = h->upper -= ilen;
- dest = (char *)h + h->upper;
- if (F_ISSET(t, R_RECNO))
- WR_RLEAF(dest, data, flags)
- else
- WR_BLEAF(dest, key, data, flags)
-
- /* If the root page was split, make it look right. */
- if (sp->pgno == P_ROOT &&
- (F_ISSET(t, R_RECNO) ?
- bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
- goto err2;
-
- /*
- * Now we walk the parent page stack -- a LIFO stack of the pages that
- * were traversed when we searched for the page that split. Each stack
- * entry is a page number and a page index offset. The offset is for
- * the page traversed on the search. We've just split a page, so we
- * have to insert a new key into the parent page.
- *
- * If the insert into the parent page causes it to split, may have to
- * continue splitting all the way up the tree. We stop if the root
- * splits or the page inserted into didn't have to split to hold the
- * new key. Some algorithms replace the key for the old page as well
- * as the new page. We don't, as there's no reason to believe that the
- * first key on the old page is any better than the key we have, and,
- * in the case of a key being placed at index 0 causing the split, the
- * key is unavailable.
- *
- * There are a maximum of 5 pages pinned at any time. We keep the left
- * and right pages pinned while working on the parent. The 5 are the
- * two children, left parent and right parent (when the parent splits)
- * and the root page or the overflow key page when calling bt_preserve.
- * This code must make sure that all pins are released other than the
- * root page or overflow page which is unlocked elsewhere.
- */
- while ((parent = BT_POP(t)) != NULL) {
- lchild = l;
- rchild = r;
-
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- goto err2;
-
- /*
- * The new key goes ONE AFTER the index, because the split
- * was to the right.
- */
- skip = parent->index + 1;
-
- /*
- * Calculate the space needed on the parent page.
- *
- * Prefix trees: space hack when inserting into BINTERNAL
- * pages. Retain only what's needed to distinguish between
- * the new entry and the LAST entry on the page to its left.
- * If the keys compare equal, retain the entire key. Note,
- * we don't touch overflow keys, and the entire key must be
- * retained for the next-to-left most key on the leftmost
- * page of each level, or the search will fail. Applicable
- * ONLY to internal pages that have leaf pages as children.
- * Further reduction of the key between pairs of internal
- * pages loses too much information.
- */
- switch (rchild->flags & P_TYPE) {
- case P_BINTERNAL:
- bi = GETBINTERNAL(rchild, 0);
- nbytes = NBINTERNAL(bi->ksize);
- break;
- case P_BLEAF:
- bl = GETBLEAF(rchild, 0);
- nbytes = NBINTERNAL(bl->ksize);
- if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
- (h->prevpg != P_INVALID || skip > 1)) {
- tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
- a.size = tbl->ksize;
- a.data = tbl->bytes;
- b.size = bl->ksize;
- b.data = bl->bytes;
- nksize = t->bt_pfx(&a, &b);
- n = NBINTERNAL(nksize);
- if (n < nbytes) {
-#ifdef STATISTICS
- bt_pfxsaved += nbytes - n;
-#endif
- nbytes = n;
- } else
- nksize = 0;
- } else
- nksize = 0;
- break;
- case P_RINTERNAL:
- case P_RLEAF:
- nbytes = NRINTERNAL;
- break;
- default:
- abort();
- }
-
- /* Split the parent page if necessary or shift the indices. */
- if ((u_int32_t) (h->upper - h->lower)
- < nbytes + sizeof(indx_t)) {
- sp = h;
- h = h->pgno == P_ROOT ?
- bt_root(t, h, &l, &r, &skip, nbytes) :
- bt_page(t, h, &l, &r, &skip, nbytes);
- if (h == NULL)
- goto err1;
- parentsplit = 1;
- } else {
- if (skip < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + skip + 1, h->linp + skip,
- (nxtindex - skip) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
- parentsplit = 0;
- }
-
- /* Insert the key into the parent page. */
- switch (rchild->flags & P_TYPE) {
- case P_BINTERNAL:
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- memmove(dest, bi, nbytes);
- ((BINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- case P_BLEAF:
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
- rchild->pgno, bl->flags & P_BIGKEY);
- memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
- if (bl->flags & P_BIGKEY &&
- bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
- goto err1;
- break;
- case P_RINTERNAL:
- /*
- * Update the left page count. If split
- * added at index 0, fix the correct page.
- */
- if (skip > 0)
- dest = (char *)h + h->linp[skip - 1];
- else
- dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
- ((RINTERNAL *)dest)->nrecs = rec_total(lchild);
- ((RINTERNAL *)dest)->pgno = lchild->pgno;
-
- /* Update the right page count. */
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- ((RINTERNAL *)dest)->nrecs = rec_total(rchild);
- ((RINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- case P_RLEAF:
- /*
- * Update the left page count. If split
- * added at index 0, fix the correct page.
- */
- if (skip > 0)
- dest = (char *)h + h->linp[skip - 1];
- else
- dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
- ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
- ((RINTERNAL *)dest)->pgno = lchild->pgno;
-
- /* Update the right page count. */
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
- ((RINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- default:
- abort();
- }
-
- /* Unpin the held pages. */
- if (!parentsplit) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- }
-
- /* If the root page was split, make it look right. */
- if (sp->pgno == P_ROOT &&
- (F_ISSET(t, R_RECNO) ?
- bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
- goto err1;
-
- mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
- mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
- }
-
- /* Unpin the held pages. */
- mpool_put(t->bt_mp, l, MPOOL_DIRTY);
- mpool_put(t->bt_mp, r, MPOOL_DIRTY);
-
- /* Clear any pages left on the stack. */
- return (RET_SUCCESS);
-
- /*
- * If something fails in the above loop we were already walking back
- * up the tree and the tree is now inconsistent. Nothing much we can
- * do about it but release any memory we're holding.
- */
-err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
- mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
-
-err2: mpool_put(t->bt_mp, l, 0);
- mpool_put(t->bt_mp, r, 0);
- __dbpanic(t->bt_dbp);
- return (RET_ERROR);
-}
-
-/*
- * BT_PAGE -- Split a non-root page of a btree.
- *
- * Parameters:
- * t: tree
- * h: root page
- * lp: pointer to left page pointer
- * rp: pointer to right page pointer
- * skip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert or NULL on error.
- */
-static PAGE *
-bt_page(t, h, lp, rp, skip, ilen)
- BTREE *t;
- PAGE *h, **lp, **rp;
- indx_t *skip;
- size_t ilen;
-{
- PAGE *l, *r, *tp;
- pgno_t npg;
-
-#ifdef STATISTICS
- ++bt_split;
-#endif
- /* Put the new right page for the split into place. */
- if ((r = __bt_new(t, &npg)) == NULL)
- return (NULL);
- r->pgno = npg;
- r->lower = BTDATAOFF;
- r->upper = t->bt_psize;
- r->nextpg = h->nextpg;
- r->prevpg = h->pgno;
- r->flags = h->flags & P_TYPE;
-
- /*
- * If we're splitting the last page on a level because we're appending
- * a key to it (skip is NEXTINDEX()), it's likely that the data is
- * sorted. Adding an empty page on the side of the level is less work
- * and can push the fill factor much higher than normal. If we're
- * wrong it's no big deal, we'll just do the split the right way next
- * time. It may look like it's equally easy to do a similar hack for
- * reverse sorted data, that is, split the tree left, but it's not.
- * Don't even try.
- */
- if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
-#ifdef STATISTICS
- ++bt_sortsplit;
-#endif
- h->nextpg = r->pgno;
- r->lower = BTDATAOFF + sizeof(indx_t);
- *skip = 0;
- *lp = h;
- *rp = r;
- return (r);
- }
-
- /* Put the new left page for the split into place. */
- if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) {
- mpool_put(t->bt_mp, r, 0);
- return (NULL);
- }
-#ifdef PURIFY
- memset(l, 0xff, t->bt_psize);
-#endif
- l->pgno = h->pgno;
- l->nextpg = r->pgno;
- l->prevpg = h->prevpg;
- l->lower = BTDATAOFF;
- l->upper = t->bt_psize;
- l->flags = h->flags & P_TYPE;
-
- /* Fix up the previous pointer of the page after the split page. */
- if (h->nextpg != P_INVALID) {
- if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
- free(l);
- /* XXX mpool_free(t->bt_mp, r->pgno); */
- return (NULL);
- }
- tp->prevpg = r->pgno;
- mpool_put(t->bt_mp, tp, MPOOL_DIRTY);
- }
-
- /*
- * Split right. The key/data pairs aren't sorted in the btree page so
- * it's simpler to copy the data from the split page onto two new pages
- * instead of copying half the data to the right page and compacting
- * the left page in place. Since the left page can't change, we have
- * to swap the original and the allocated left page after the split.
- */
- tp = bt_psplit(t, h, l, r, skip, ilen);
-
- /* Move the new left page onto the old left page. */
- memmove(h, l, t->bt_psize);
- if (tp == l)
- tp = h;
- free(l);
-
- *lp = h;
- *rp = r;
- return (tp);
-}
-
-/*
- * BT_ROOT -- Split the root page of a btree.
- *
- * Parameters:
- * t: tree
- * h: root page
- * lp: pointer to left page pointer
- * rp: pointer to right page pointer
- * skip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert or NULL on error.
- */
-static PAGE *
-bt_root(t, h, lp, rp, skip, ilen)
- BTREE *t;
- PAGE *h, **lp, **rp;
- indx_t *skip;
- size_t ilen;
-{
- PAGE *l, *r, *tp;
- pgno_t lnpg, rnpg;
-
-#ifdef STATISTICS
- ++bt_split;
- ++bt_rootsplit;
-#endif
- /* Put the new left and right pages for the split into place. */
- if ((l = __bt_new(t, &lnpg)) == NULL ||
- (r = __bt_new(t, &rnpg)) == NULL)
- return (NULL);
- l->pgno = lnpg;
- r->pgno = rnpg;
- l->nextpg = r->pgno;
- r->prevpg = l->pgno;
- l->prevpg = r->nextpg = P_INVALID;
- l->lower = r->lower = BTDATAOFF;
- l->upper = r->upper = t->bt_psize;
- l->flags = r->flags = h->flags & P_TYPE;
-
- /* Split the root page. */
- tp = bt_psplit(t, h, l, r, skip, ilen);
-
- *lp = l;
- *rp = r;
- return (tp);
-}
-
-/*
- * BT_RROOT -- Fix up the recno root page after it has been split.
- *
- * Parameters:
- * t: tree
- * h: root page
- * l: left page
- * r: right page
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_rroot(t, h, l, r)
- BTREE *t;
- PAGE *h, *l, *r;
-{
- char *dest;
-
- /* Insert the left and right keys, set the header information. */
- h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
- dest = (char *)h + h->upper;
- WR_RINTERNAL(dest,
- l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
-
- h->linp[1] = h->upper -= NRINTERNAL;
- dest = (char *)h + h->upper;
- WR_RINTERNAL(dest,
- r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
-
- h->lower = BTDATAOFF + 2 * sizeof(indx_t);
-
- /* Unpin the root page, set to recno internal page. */
- h->flags &= ~P_TYPE;
- h->flags |= P_RINTERNAL;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
-
-/*
- * BT_BROOT -- Fix up the btree root page after it has been split.
- *
- * Parameters:
- * t: tree
- * h: root page
- * l: left page
- * r: right page
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_broot(t, h, l, r)
- BTREE *t;
- PAGE *h, *l, *r;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- u_int32_t nbytes;
- char *dest;
-
- /*
- * If the root page was a leaf page, change it into an internal page.
- * We copy the key we split on (but not the key's data, in the case of
- * a leaf page) to the new root page.
- *
- * The btree comparison code guarantees that the left-most key on any
- * level of the tree is never used, so it doesn't need to be filled in.
- */
- nbytes = NBINTERNAL(0);
- h->linp[0] = h->upper = t->bt_psize - nbytes;
- dest = (char *)h + h->upper;
- WR_BINTERNAL(dest, 0, l->pgno, 0);
-
- switch (h->flags & P_TYPE) {
- case P_BLEAF:
- bl = GETBLEAF(r, 0);
- nbytes = NBINTERNAL(bl->ksize);
- h->linp[1] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
- memmove(dest, bl->bytes, bl->ksize);
-
- /*
- * If the key is on an overflow page, mark the overflow chain
- * so it isn't deleted when the leaf copy of the key is deleted.
- */
- if (bl->flags & P_BIGKEY &&
- bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
- return (RET_ERROR);
- break;
- case P_BINTERNAL:
- bi = GETBINTERNAL(r, 0);
- nbytes = NBINTERNAL(bi->ksize);
- h->linp[1] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- memmove(dest, bi, nbytes);
- ((BINTERNAL *)dest)->pgno = r->pgno;
- break;
- default:
- abort();
- }
-
- /* There are two keys on the page. */
- h->lower = BTDATAOFF + 2 * sizeof(indx_t);
-
- /* Unpin the root page, set to btree internal page. */
- h->flags &= ~P_TYPE;
- h->flags |= P_BINTERNAL;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
-
-/*
- * BT_PSPLIT -- Do the real work of splitting the page.
- *
- * Parameters:
- * t: tree
- * h: page to be split
- * l: page to put lower half of data
- * r: page to put upper half of data
- * pskip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert.
- */
-static PAGE *
-bt_psplit(t, h, l, r, pskip, ilen)
- BTREE *t;
- PAGE *h, *l, *r;
- indx_t *pskip;
- size_t ilen;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- CURSOR *c;
- RLEAF *rl;
- PAGE *rval;
- void *src = 0;
- indx_t full, half, nxt, off, skip, top, used;
- u_int32_t nbytes;
- int bigkeycnt, isbigkey;
-
- /*
- * Split the data to the left and right pages. Leave the skip index
- * open. Additionally, make some effort not to split on an overflow
- * key. This makes internal page processing faster and can save
- * space as overflow keys used by internal pages are never deleted.
- */
- bigkeycnt = 0;
- skip = *pskip;
- full = t->bt_psize - BTDATAOFF;
- half = full / 2;
- used = 0;
- for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
- if (skip == off) {
- nbytes = ilen;
- isbigkey = 0; /* XXX: not really known. */
- } else
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- src = bi = GETBINTERNAL(h, nxt);
- nbytes = NBINTERNAL(bi->ksize);
- isbigkey = bi->flags & P_BIGKEY;
- break;
- case P_BLEAF:
- src = bl = GETBLEAF(h, nxt);
- nbytes = NBLEAF(bl);
- isbigkey = bl->flags & P_BIGKEY;
- break;
- case P_RINTERNAL:
- src = GETRINTERNAL(h, nxt);
- nbytes = NRINTERNAL;
- isbigkey = 0;
- break;
- case P_RLEAF:
- src = rl = GETRLEAF(h, nxt);
- nbytes = NRLEAF(rl);
- isbigkey = 0;
- break;
- default:
- abort();
- }
-
- /*
- * If the key/data pairs are substantial fractions of the max
- * possible size for the page, it's possible to get situations
- * where we decide to try and copy too much onto the left page.
- * Make sure that doesn't happen.
- */
- if ((skip <= off && used + nbytes + sizeof(indx_t) >= full)
- || nxt == top - 1) {
- --off;
- break;
- }
-
- /* Copy the key/data pair, if not the skipped index. */
- if (skip != off) {
- ++nxt;
-
- l->linp[off] = l->upper -= nbytes;
- memmove((char *)l + l->upper, src, nbytes);
- }
-
- used += nbytes + sizeof(indx_t);
- if (used >= half) {
- if (!isbigkey || bigkeycnt == 3)
- break;
- else
- ++bigkeycnt;
- }
- }
-
- /*
- * Off is the last offset that's valid for the left page.
- * Nxt is the first offset to be placed on the right page.
- */
- l->lower += (off + 1) * sizeof(indx_t);
-
- /*
- * If splitting the page that the cursor was on, the cursor has to be
- * adjusted to point to the same record as before the split. If the
- * cursor is at or past the skipped slot, the cursor is incremented by
- * one. If the cursor is on the right page, it is decremented by the
- * number of records split to the left page.
- */
- c = &t->bt_cursor;
- if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) {
- if (c->pg.index >= skip)
- ++c->pg.index;
- if (c->pg.index < nxt) /* Left page. */
- c->pg.pgno = l->pgno;
- else { /* Right page. */
- c->pg.pgno = r->pgno;
- c->pg.index -= nxt;
- }
- }
-
- /*
- * If the skipped index was on the left page, just return that page.
- * Otherwise, adjust the skip index to reflect the new position on
- * the right page.
- */
- if (skip <= off) {
- skip = 0;
- rval = l;
- } else {
- rval = r;
- *pskip -= nxt;
- }
-
- for (off = 0; nxt < top; ++off) {
- if (skip == nxt) {
- ++off;
- skip = 0;
- }
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- src = bi = GETBINTERNAL(h, nxt);
- nbytes = NBINTERNAL(bi->ksize);
- break;
- case P_BLEAF:
- src = bl = GETBLEAF(h, nxt);
- nbytes = NBLEAF(bl);
- break;
- case P_RINTERNAL:
- src = GETRINTERNAL(h, nxt);
- nbytes = NRINTERNAL;
- break;
- case P_RLEAF:
- src = rl = GETRLEAF(h, nxt);
- nbytes = NRLEAF(rl);
- break;
- default:
- abort();
- }
- ++nxt;
- r->linp[off] = r->upper -= nbytes;
- memmove((char *)r + r->upper, src, nbytes);
- }
- r->lower += off * sizeof(indx_t);
-
- /* If the key is being appended to the page, adjust the index. */
- if (skip == top)
- r->lower += sizeof(indx_t);
-
- return (rval);
-}
-
-/*
- * BT_PRESERVE -- Mark a chain of pages as used by an internal node.
- *
- * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
- * record that references them gets deleted. Chains pointed to by internal
- * pages never get deleted. This routine marks a chain as pointed to by an
- * internal page.
- *
- * Parameters:
- * t: tree
- * pg: page number of first page in the chain.
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-static int
-bt_preserve(t, pg)
- BTREE *t;
- pgno_t pg;
-{
- PAGE *h;
-
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- h->flags |= P_PRESERVE;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-/*
- * REC_TOTAL -- Return the number of recno entries below a page.
- *
- * Parameters:
- * h: page
- *
- * Returns:
- * The number of recno entries below a page.
- *
- * XXX
- * These values could be set by the bt_psplit routine. The problem is that the
- * entry has to be popped off of the stack etc. or the values have to be passed
- * all the way back to bt_split/bt_rroot and it's not very clean.
- */
-static recno_t
-rec_total(h)
- PAGE *h;
-{
- recno_t recs;
- indx_t nxt, top;
-
- for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
- recs += GETRINTERNAL(h, nxt)->nrecs;
- return (recs);
-}
diff --git a/1.4/main/db1-ast/btree/bt_utils.c b/1.4/main/db1-ast/btree/bt_utils.c
deleted file mode 100644
index 2ecb5e678..000000000
--- a/1.4/main/db1-ast/btree/bt_utils.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "btree.h"
-
-/*
- * __bt_ret --
- * Build return key/data pair.
- *
- * Parameters:
- * t: tree
- * e: key/data pair to be returned
- * key: user's key structure (NULL if not to be filled in)
- * rkey: memory area to hold key
- * data: user's data structure (NULL if not to be filled in)
- * rdata: memory area to hold data
- * copy: always copy the key/data item
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_ret(t, e, key, rkey, data, rdata, copy)
- BTREE *t;
- EPG *e;
- DBT *key, *rkey, *data, *rdata;
- int copy;
-{
- BLEAF *bl;
- void *p;
-
- bl = GETBLEAF(e->page, e->index);
-
- /*
- * We must copy big keys/data to make them contiguous. Otherwise,
- * leave the page pinned and don't copy unless the user specified
- * concurrent access.
- */
- if (key == NULL)
- goto dataonly;
-
- if (bl->flags & P_BIGKEY) {
- if (__ovfl_get(t, bl->bytes,
- &key->size, &rkey->data, &rkey->size))
- return (RET_ERROR);
- key->data = rkey->data;
- } else if (copy || F_ISSET(t, B_DB_LOCK)) {
- if (bl->ksize > rkey->size) {
- p = (void *)(rkey->data == NULL ?
- malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
- if (p == NULL)
- return (RET_ERROR);
- rkey->data = p;
- rkey->size = bl->ksize;
- }
- memmove(rkey->data, bl->bytes, bl->ksize);
- key->size = bl->ksize;
- key->data = rkey->data;
- } else {
- key->size = bl->ksize;
- key->data = bl->bytes;
- }
-
-dataonly:
- if (data == NULL)
- return (RET_SUCCESS);
-
- if (bl->flags & P_BIGDATA) {
- if (__ovfl_get(t, bl->bytes + bl->ksize,
- &data->size, &rdata->data, &rdata->size))
- return (RET_ERROR);
- data->data = rdata->data;
- } else if (copy || F_ISSET(t, B_DB_LOCK)) {
- /* Use +1 in case the first record retrieved is 0 length. */
- if (bl->dsize + 1 > rdata->size) {
- p = (void *)(rdata->data == NULL ?
- malloc(bl->dsize + 1) :
- realloc(rdata->data, bl->dsize + 1));
- if (p == NULL)
- return (RET_ERROR);
- rdata->data = p;
- rdata->size = bl->dsize + 1;
- }
- memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
- data->size = bl->dsize;
- data->data = rdata->data;
- } else {
- data->size = bl->dsize;
- data->data = bl->bytes + bl->ksize;
- }
-
- return (RET_SUCCESS);
-}
-
-/*
- * __BT_CMP -- Compare a key to a given record.
- *
- * Parameters:
- * t: tree
- * k1: DBT pointer of first arg to comparison
- * e: pointer to EPG for comparison
- *
- * Returns:
- * < 0 if k1 is < record
- * = 0 if k1 is = record
- * > 0 if k1 is > record
- */
-int
-__bt_cmp(t, k1, e)
- BTREE *t;
- const DBT *k1;
- EPG *e;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- DBT k2;
- PAGE *h;
- void *bigkey;
-
- /*
- * The left-most key on internal pages, at any level of the tree, is
- * guaranteed by the following code to be less than any user key.
- * This saves us from having to update the leftmost key on an internal
- * page when the user inserts a new key in the tree smaller than
- * anything we've yet seen.
- */
- h = e->page;
- if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
- return (1);
-
- bigkey = NULL;
- if (h->flags & P_BLEAF) {
- bl = GETBLEAF(h, e->index);
- if (bl->flags & P_BIGKEY)
- bigkey = bl->bytes;
- else {
- k2.data = bl->bytes;
- k2.size = bl->ksize;
- }
- } else {
- bi = GETBINTERNAL(h, e->index);
- if (bi->flags & P_BIGKEY)
- bigkey = bi->bytes;
- else {
- k2.data = bi->bytes;
- k2.size = bi->ksize;
- }
- }
-
- if (bigkey) {
- if (__ovfl_get(t, bigkey,
- &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
- return (RET_ERROR);
- k2.data = t->bt_rdata.data;
- }
- return ((*t->bt_cmp)(k1, &k2));
-}
-
-/*
- * __BT_DEFCMP -- Default comparison routine.
- *
- * Parameters:
- * a: DBT #1
- * b: DBT #2
- *
- * Returns:
- * < 0 if a is < b
- * = 0 if a is = b
- * > 0 if a is > b
- */
-int
-__bt_defcmp(a, b)
- const DBT *a, *b;
-{
- register size_t len;
- register u_char *p1, *p2;
-
- /*
- * XXX
- * If a size_t doesn't fit in an int, this routine can lose.
- * What we need is a integral type which is guaranteed to be
- * larger than a size_t, and there is no such thing.
- */
- len = MIN(a->size, b->size);
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
- if (*p1 != *p2)
- return ((int)*p1 - (int)*p2);
- return ((int)a->size - (int)b->size);
-}
-
-/*
- * __BT_DEFPFX -- Default prefix routine.
- *
- * Parameters:
- * a: DBT #1
- * b: DBT #2
- *
- * Returns:
- * Number of bytes needed to distinguish b from a.
- */
-size_t
-__bt_defpfx(a, b)
- const DBT *a, *b;
-{
- register u_char *p1, *p2;
- register size_t cnt, len;
-
- cnt = 1;
- len = MIN(a->size, b->size);
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
- if (*p1 != *p2)
- return (cnt);
-
- /* a->size must be <= b->size, or they wouldn't be in this order. */
- return (a->size < b->size ? a->size + 1 : a->size);
-}
diff --git a/1.4/main/db1-ast/btree/btree.h b/1.4/main/db1-ast/btree/btree.h
deleted file mode 100644
index 1f4a9ec91..000000000
--- a/1.4/main/db1-ast/btree/btree.h
+++ /dev/null
@@ -1,391 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)btree.h 8.11 (Berkeley) 8/17/94
- */
-
-/* Macros to set/clear/test flags. */
-#define F_SET(p, f) (p)->flags |= (f)
-#define F_CLR(p, f) (p)->flags &= ~(f)
-#define F_ISSET(p, f) ((p)->flags & (f))
-
-#include <mpool.h>
-
-#define mpool_open __mpool_open
-#define mpool_filter __mpool_filter
-#define mpool_new __mpool_new
-#define mpool_get __mpool_get
-#define mpool_put __mpool_put
-#define mpool_sync __mpool_sync
-#define mpool_close __mpool_close
-
-#define DEFMINKEYPAGE (2) /* Minimum keys per page */
-#define MINCACHE (5) /* Minimum cached pages */
-#define MINPSIZE (512) /* Minimum page size */
-
-/*
- * Page 0 of a btree file contains a copy of the meta-data. This page is also
- * used as an out-of-band page, i.e. page pointers that point to nowhere point
- * to page 0. Page 1 is the root of the btree.
- */
-#define P_INVALID 0 /* Invalid tree page number. */
-#define P_META 0 /* Tree metadata page number. */
-#define P_ROOT 1 /* Tree root page number. */
-
-/*
- * There are five page layouts in the btree: btree internal pages (BINTERNAL),
- * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
- * (RLEAF) and overflow pages. All five page types have a page header (PAGE).
- * This implementation requires that values within structures NOT be padded.
- * (ANSI C permits random padding.) If your compiler pads randomly you'll have
- * to do some work to get this package to run.
- */
-typedef struct _page {
- pgno_t pgno; /* this page's page number */
- pgno_t prevpg; /* left sibling */
- pgno_t nextpg; /* right sibling */
-
-#define P_BINTERNAL 0x01 /* btree internal page */
-#define P_BLEAF 0x02 /* leaf page */
-#define P_OVERFLOW 0x04 /* overflow page */
-#define P_RINTERNAL 0x08 /* recno internal page */
-#define P_RLEAF 0x10 /* leaf page */
-#define P_TYPE 0x1f /* type mask */
-#define P_PRESERVE 0x20 /* never delete this chain of pages */
- u_int32_t flags;
-
- indx_t lower; /* lower bound of free space on page */
- indx_t upper; /* upper bound of free space on page */
- indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */
-} PAGE;
-
-/* First and next index. */
-#define BTDATAOFF \
- (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
- sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
-#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
-
-/*
- * For pages other than overflow pages, there is an array of offsets into the
- * rest of the page immediately following the page header. Each offset is to
- * an item which is unique to the type of page. The h_lower offset is just
- * past the last filled-in index. The h_upper offset is the first item on the
- * page. Offsets are from the beginning of the page.
- *
- * If an item is too big to store on a single page, a flag is set and the item
- * is a { page, size } pair such that the page is the first page of an overflow
- * chain with size bytes of item. Overflow pages are simply bytes without any
- * external structure.
- *
- * The page number and size fields in the items are pgno_t-aligned so they can
- * be manipulated without copying. (This presumes that 32 bit items can be
- * manipulated on this system.)
- */
-#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
-#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
-
-/*
- * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
- * pairs, such that the key compares less than or equal to all of the records
- * on that page. For a tree without duplicate keys, an internal page with two
- * consecutive keys, a and b, will have all records greater than or equal to a
- * and less than b stored on the page associated with a. Duplicate keys are
- * somewhat special and can cause duplicate internal and leaf page records and
- * some minor modifications of the above rule.
- */
-typedef struct _binternal {
- u_int32_t ksize; /* key size */
- pgno_t pgno; /* page number stored on */
-#define P_BIGDATA 0x01 /* overflow data */
-#define P_BIGKEY 0x02 /* overflow key */
- u_char flags;
- char bytes[1]; /* data */
-} BINTERNAL;
-
-/* Get the page's BINTERNAL structure at index indx. */
-#define GETBINTERNAL(pg, indx) \
- ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NBINTERNAL(len) \
- LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
-
-/* Copy a BINTERNAL entry to the page. */
-#define WR_BINTERNAL(p, size, pgno, flags) { \
- *(u_int32_t *)p = size; \
- p += sizeof(u_int32_t); \
- *(pgno_t *)p = pgno; \
- p += sizeof(pgno_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
-}
-
-/*
- * For the recno internal pages, the item is a page number with the number of
- * keys found on that page and below.
- */
-typedef struct _rinternal {
- recno_t nrecs; /* number of records */
- pgno_t pgno; /* page number stored below */
-} RINTERNAL;
-
-/* Get the page's RINTERNAL structure at index indx. */
-#define GETRINTERNAL(pg, indx) \
- ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NRINTERNAL \
- LALIGN(sizeof(recno_t) + sizeof(pgno_t))
-
-/* Copy a RINTERNAL entry to the page. */
-#define WR_RINTERNAL(p, nrecs, pgno) { \
- *(recno_t *)p = nrecs; \
- p += sizeof(recno_t); \
- *(pgno_t *)p = pgno; \
-}
-
-/* For the btree leaf pages, the item is a key and data pair. */
-typedef struct _bleaf {
- u_int32_t ksize; /* size of key */
- u_int32_t dsize; /* size of data */
- u_char flags; /* P_BIGDATA, P_BIGKEY */
- char bytes[1]; /* data */
-} BLEAF;
-
-/* Get the page's BLEAF structure at index indx. */
-#define GETBLEAF(pg, indx) \
- ((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
-
-/* Get the number of bytes in the user's key/data pair. */
-#define NBLEAFDBT(ksize, dsize) \
- LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
- (ksize) + (dsize))
-
-/* Copy a BLEAF entry to the page. */
-#define WR_BLEAF(p, key, data, flags) { \
- *(u_int32_t *)p = key->size; \
- p += sizeof(u_int32_t); \
- *(u_int32_t *)p = data->size; \
- p += sizeof(u_int32_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
- memmove(p, key->data, key->size); \
- p += key->size; \
- memmove(p, data->data, data->size); \
-}
-
-/* For the recno leaf pages, the item is a data entry. */
-typedef struct _rleaf {
- u_int32_t dsize; /* size of data */
- u_char flags; /* P_BIGDATA */
- char bytes[1];
-} RLEAF;
-
-/* Get the page's RLEAF structure at index indx. */
-#define GETRLEAF(pg, indx) \
- ((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NRLEAF(p) NRLEAFDBT((p)->dsize)
-
-/* Get the number of bytes from the user's data. */
-#define NRLEAFDBT(dsize) \
- LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
-
-/* Copy a RLEAF entry to the page. */
-#define WR_RLEAF(p, data, flags) { \
- *(u_int32_t *)p = data->size; \
- p += sizeof(u_int32_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
- memmove(p, data->data, data->size); \
-}
-
-/*
- * A record in the tree is either a pointer to a page and an index in the page
- * or a page number and an index. These structures are used as a cursor, stack
- * entry and search returns as well as to pass records to other routines.
- *
- * One comment about searches. Internal page searches must find the largest
- * record less than key in the tree so that descents work. Leaf page searches
- * must find the smallest record greater than key so that the returned index
- * is the record's correct position for insertion.
- */
-typedef struct _epgno {
- pgno_t pgno; /* the page number */
- indx_t index; /* the index on the page */
-} EPGNO;
-
-typedef struct _epg {
- PAGE *page; /* the (pinned) page */
- indx_t index; /* the index on the page */
-} EPG;
-
-/*
- * About cursors. The cursor (and the page that contained the key/data pair
- * that it referenced) can be deleted, which makes things a bit tricky. If
- * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
- * or there simply aren't any duplicates of the key) we copy the key that it
- * referenced when it's deleted, and reacquire a new cursor key if the cursor
- * is used again. If there are duplicates keys, we move to the next/previous
- * key, and set a flag so that we know what happened. NOTE: if duplicate (to
- * the cursor) keys are added to the tree during this process, it is undefined
- * if they will be returned or not in a cursor scan.
- *
- * The flags determine the possible states of the cursor:
- *
- * CURS_INIT The cursor references *something*.
- * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
- * we can reacquire the right position in the tree.
- * CURS_AFTER, CURS_BEFORE
- * The cursor was deleted, and now references a key/data pair
- * that has not yet been returned, either before or after the
- * deleted key/data pair.
- * XXX
- * This structure is broken out so that we can eventually offer multiple
- * cursors as part of the DB interface.
- */
-typedef struct _cursor {
- EPGNO pg; /* B: Saved tree reference. */
- DBT key; /* B: Saved key, or key.data == NULL. */
- recno_t rcursor; /* R: recno cursor (1-based) */
-
-#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
-#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
-#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
-#define CURS_INIT 0x08 /* RB: Cursor initialized. */
- u_int8_t flags;
-} CURSOR;
-
-/*
- * The metadata of the tree. The nrecs field is used only by the RECNO code.
- * This is because the btree doesn't really need it and it requires that every
- * put or delete call modify the metadata.
- */
-typedef struct _btmeta {
- u_int32_t magic; /* magic number */
- u_int32_t version; /* version */
- u_int32_t psize; /* page size */
- u_int32_t free; /* page number of first free page */
- u_int32_t nrecs; /* R: number of records */
-
-#define SAVEMETA (B_NODUPS | R_RECNO)
- u_int32_t flags; /* bt_flags & SAVEMETA */
-} BTMETA;
-
-/* The in-memory btree/recno data structure. */
-typedef struct _btree {
- MPOOL *bt_mp; /* memory pool cookie */
-
- DB *bt_dbp; /* pointer to enclosing DB */
-
- EPG bt_cur; /* current (pinned) page */
- PAGE *bt_pinned; /* page pinned across calls */
-
- CURSOR bt_cursor; /* cursor */
-
-#define BT_PUSH(t, p, i) { \
- t->bt_sp->pgno = p; \
- t->bt_sp->index = i; \
- ++t->bt_sp; \
-}
-#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
-#define BT_CLR(t) (t->bt_sp = t->bt_stack)
- EPGNO bt_stack[50]; /* stack of parent pages */
- EPGNO *bt_sp; /* current stack pointer */
-
- DBT bt_rkey; /* returned key */
- DBT bt_rdata; /* returned data */
-
- int bt_fd; /* tree file descriptor */
-
- pgno_t bt_free; /* next free page */
- u_int32_t bt_psize; /* page size */
- indx_t bt_ovflsize; /* cut-off for key/data overflow */
- int bt_lorder; /* byte order */
- /* sorted order */
- enum { NOT, BACK, FORWARD } bt_order;
- EPGNO bt_last; /* last insert */
-
- /* B: key comparison function */
- int (*bt_cmp) __P((const DBT *, const DBT *));
- /* B: prefix comparison function */
- size_t (*bt_pfx) __P((const DBT *, const DBT *));
- /* R: recno input function */
- int (*bt_irec) __P((struct _btree *, recno_t));
-
- FILE *bt_rfp; /* R: record FILE pointer */
- int bt_rfd; /* R: record file descriptor */
-
- caddr_t bt_cmap; /* R: current point in mapped space */
- caddr_t bt_smap; /* R: start of mapped space */
- caddr_t bt_emap; /* R: end of mapped space */
- size_t bt_msize; /* R: size of mapped region. */
-
- recno_t bt_nrecs; /* R: number of records */
- size_t bt_reclen; /* R: fixed record length */
- u_char bt_bval; /* R: delimiting byte/pad character */
-
-/*
- * NB:
- * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
- */
-#define B_INMEM 0x00001 /* in-memory tree */
-#define B_METADIRTY 0x00002 /* need to write metadata */
-#define B_MODIFIED 0x00004 /* tree modified */
-#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
-#define B_RDONLY 0x00010 /* read-only tree */
-
-#define B_NODUPS 0x00020 /* no duplicate keys permitted */
-#define R_RECNO 0x00080 /* record oriented tree */
-
-#define R_CLOSEFP 0x00040 /* opened a file pointer */
-#define R_EOF 0x00100 /* end of input file reached. */
-#define R_FIXLEN 0x00200 /* fixed length records */
-#define R_MEMMAPPED 0x00400 /* memory mapped file. */
-#define R_INMEM 0x00800 /* in-memory file */
-#define R_MODIFIED 0x01000 /* modified file */
-#define R_RDONLY 0x02000 /* read-only file */
-
-#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
-#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
-#define B_DB_TXN 0x10000 /* DB_TXN specified. */
- u_int32_t flags;
-} BTREE;
-
-#include "extern.h"
diff --git a/1.4/main/db1-ast/btree/extern.h b/1.4/main/db1-ast/btree/extern.h
deleted file mode 100644
index ebd9c5492..000000000
--- a/1.4/main/db1-ast/btree/extern.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.10 (Berkeley) 7/20/94
- */
-
-int __bt_close __P((DB *));
-int __bt_cmp __P((BTREE *, const DBT *, EPG *));
-int __bt_crsrdel __P((BTREE *, EPGNO *));
-int __bt_defcmp __P((const DBT *, const DBT *));
-size_t __bt_defpfx __P((const DBT *, const DBT *));
-int __bt_delete __P((const DB *, const DBT *, u_int));
-int __bt_dleaf __P((BTREE *, const DBT *, PAGE *, u_int));
-int __bt_fd __P((const DB *));
-int __bt_free __P((BTREE *, PAGE *));
-int __bt_get __P((const DB *, const DBT *, DBT *, u_int));
-PAGE *__bt_new __P((BTREE *, pgno_t *));
-void __bt_pgin __P((void *, pgno_t, void *));
-void __bt_pgout __P((void *, pgno_t, void *));
-int __bt_push __P((BTREE *, pgno_t, int));
-int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int));
-int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int));
-EPG *__bt_search __P((BTREE *, const DBT *, int *));
-int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
-void __bt_setcur __P((BTREE *, pgno_t, u_int));
-int __bt_split __P((BTREE *, PAGE *,
- const DBT *, const DBT *, int, size_t, u_int32_t));
-int __bt_sync __P((const DB *, u_int));
-
-int __ovfl_delete __P((BTREE *, void *));
-int __ovfl_get __P((BTREE *, void *, size_t *, void **, size_t *));
-int __ovfl_put __P((BTREE *, const DBT *, pgno_t *));
-
-#ifdef DEBUG
-void __bt_dnpage __P((DB *, pgno_t));
-void __bt_dpage __P((PAGE *));
-void __bt_dump __P((DB *));
-#endif
-#ifdef STATISTICS
-void __bt_stat __P((DB *));
-#endif
diff --git a/1.4/main/db1-ast/db/db.c b/1.4/main/db1-ast/db/db.c
deleted file mode 100644
index 8c0584d4c..000000000
--- a/1.4/main/db1-ast/db/db.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include "../include/db.h"
-
-DB *
-dbopen(fname, flags, mode, type, openinfo)
- const char *fname;
- int flags, mode;
- DBTYPE type;
- const void *openinfo;
-{
-
-#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
-#define USE_OPEN_FLAGS \
- (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
- O_RDWR | O_SHLOCK | O_TRUNC)
-
- if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
- switch (type) {
- case DB_BTREE:
- return (__bt_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_HASH:
- return (__hash_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_RECNO:
- return (__rec_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- }
- errno = EINVAL;
- return (NULL);
-}
-
-static int
-__dberr __P((void))
-{
- return (RET_ERROR);
-}
-
-/*
- * __DBPANIC -- Stop.
- *
- * Parameters:
- * dbp: pointer to the DB structure.
- */
-void
-__dbpanic(dbp)
- DB *dbp;
-{
- /* The only thing that can succeed is a close. */
- dbp->del = (int (*)__P((const struct __db *,
- const DBT *, u_int))) __dberr;
- dbp->get = (int (*)__P((const struct __db *,
- const DBT *, DBT *, u_int))) __dberr;
- dbp->put = (int (*)__P((const struct __db *,
- DBT *, const DBT *, u_int))) __dberr;
- dbp->seq = (int (*)__P((const struct __db *,
- DBT *, DBT *, u_int))) __dberr;
- dbp->sync = (int (*)__P((const struct __db *, u_int))) __dberr;
- dbp->fd = (int (*)__P((const struct __db *))) __dberr;
-}
diff --git a/1.4/main/db1-ast/hash/README b/1.4/main/db1-ast/hash/README
deleted file mode 100644
index f29ccf7e1..000000000
--- a/1.4/main/db1-ast/hash/README
+++ /dev/null
@@ -1,72 +0,0 @@
-# @(#)README 8.1 (Berkeley) 6/4/93
-
-This package implements a superset of the hsearch and dbm/ndbm libraries.
-
-Test Programs:
- All test programs which need key/data pairs expect them entered
- with key and data on separate lines
-
- tcreat3.c
- Takes
- bucketsize (bsize),
- fill factor (ffactor), and
- initial number of elements (nelem).
- Creates a hash table named hashtest containing the
- keys/data pairs entered from standard in.
- thash4.c
- Takes
- bucketsize (bsize),
- fill factor (ffactor),
- initial number of elements (nelem)
- bytes of cache (ncached), and
- file from which to read data (fname)
- Creates a table from the key/data pairs on standard in and
- then does a read of each key/data in fname
- tdel.c
- Takes
- bucketsize (bsize), and
- fill factor (ffactor).
- file from which to read data (fname)
- Reads each key/data pair from fname and deletes the
- key from the hash table hashtest
- tseq.c
- Reads the key/data pairs in the file hashtest and writes them
- to standard out.
- tread2.c
- Takes
- butes of cache (ncached).
- Reads key/data pairs from standard in and looks them up
- in the file hashtest.
- tverify.c
- Reads key/data pairs from standard in, looks them up
- in the file hashtest, and verifies that the data is
- correct.
-
-NOTES:
-
-The file search.h is provided for using the hsearch compatible interface
-on BSD systems. On System V derived systems, search.h should appear in
-/usr/include.
-
-The man page ../man/db.3 explains the interface to the hashing system.
-The file hash.ps is a postscript copy of a paper explaining
-the history, implementation, and performance of the hash package.
-
-"bugs" or idiosyncracies
-
-If you have a lot of overflows, it is possible to run out of overflow
-pages. Currently, this will cause a message to be printed on stderr.
-Eventually, this will be indicated by a return error code.
-
-If you are using the ndbm interface and exit without flushing or closing the
-file, you may lose updates since the package buffers all writes. Also,
-the db interface only creates a single database file. To avoid overwriting
-the user's original file, the suffix ".db" is appended to the file name
-passed to dbm_open. Additionally, if your code "knows" about the historic
-.dir and .pag files, it will break.
-
-There is a fundamental difference between this package and the old hsearch.
-Hsearch requires the user to maintain the keys and data in the application's
-allocated memory while hash takes care of all storage management. The down
-side is that the byte strings passed in the ENTRY structure must be null
-terminated (both the keys and the data).
diff --git a/1.4/main/db1-ast/hash/extern.h b/1.4/main/db1-ast/hash/extern.h
deleted file mode 100644
index 4f1f23d67..000000000
--- a/1.4/main/db1-ast/hash/extern.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.4 (Berkeley) 6/16/94
- */
-
-BUFHEAD *__add_ovflpage __P((HTAB *, BUFHEAD *));
-int __addel __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
-int __big_delete __P((HTAB *, BUFHEAD *));
-int __big_insert __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
-int __big_keydata __P((HTAB *, BUFHEAD *, DBT *, DBT *, int));
-int __big_return __P((HTAB *, BUFHEAD *, int, DBT *, int));
-int __big_split __P((HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
- int, u_int32_t, SPLIT_RETURN *));
-int __buf_free __P((HTAB *, int, int));
-void __buf_init __P((HTAB *, int));
-u_int32_t __call_hash __P((HTAB *, char *, int));
-int __delpair __P((HTAB *, BUFHEAD *, int));
-int __expand_table __P((HTAB *));
-int __find_bigpair __P((HTAB *, BUFHEAD *, int, char *, int));
-u_int16_t __find_last_page __P((HTAB *, BUFHEAD **));
-void __free_ovflpage __P((HTAB *, BUFHEAD *));
-BUFHEAD *__get_buf __P((HTAB *, u_int32_t, BUFHEAD *, int));
-int __get_page __P((HTAB *, char *, u_int32_t, int, int, int));
-int __ibitmap __P((HTAB *, int, int, int));
-u_int32_t __hash_log2 __P((u_int32_t));
-int __put_page __P((HTAB *, char *, u_int32_t, int, int));
-void __reclaim_buf __P((HTAB *, BUFHEAD *));
-int __split_page __P((HTAB *, u_int32_t, u_int32_t));
-
-/* Default hash routine. */
-extern u_int32_t (*__default_hash) __P((const void *, size_t));
-
-#ifdef HASH_STATISTICS
-extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
-#endif
diff --git a/1.4/main/db1-ast/hash/hash.c b/1.4/main/db1-ast/hash/hash.c
deleted file mode 100644
index 47dc52a0e..000000000
--- a/1.4/main/db1-ast/hash/hash.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include "../include/db.h"
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static int alloc_segs __P((HTAB *, int));
-static int flush_meta __P((HTAB *));
-static int hash_access __P((HTAB *, ACTION, DBT *, DBT *));
-static int hash_close __P((DB *));
-static int hash_delete __P((const DB *, const DBT *, u_int32_t));
-static int hash_fd __P((const DB *));
-static int hash_get __P((const DB *, const DBT *, DBT *, u_int32_t));
-static int hash_put __P((const DB *, DBT *, const DBT *, u_int32_t));
-static void *hash_realloc __P((SEGMENT **, int, int));
-static int hash_seq __P((const DB *, DBT *, DBT *, u_int32_t));
-static int hash_sync __P((const DB *, u_int32_t));
-static int hdestroy __P((HTAB *));
-static HTAB *init_hash __P((HTAB *, const char *, const HASHINFO *));
-static int init_htab __P((HTAB *, int));
-#if BYTE_ORDER == LITTLE_ENDIAN
-static void swap_header __P((HTAB *));
-static void swap_header_copy __P((HASHHDR *, HASHHDR *));
-#endif
-
-/* Fast arithmetic, relying on powers of 2, */
-#define MOD(x, y) ((x) & ((y) - 1))
-
-#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
-
-/* Return values */
-#define SUCCESS (0)
-#define ERROR (-1)
-#define ABNORMAL (1)
-
-#ifdef HASH_STATISTICS
-int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
-#endif
-
-/************************** INTERFACE ROUTINES ***************************/
-/* OPEN/CLOSE */
-
-extern DB *
-__hash_open(file, flags, mode, info, dflags)
- const char *file;
- int flags, mode, dflags;
- const HASHINFO *info; /* Special directives for create */
-{
- HTAB *hashp;
- struct stat statbuf;
- DB *dbp;
- int bpages, hdrsize, new_table, nsegs, save_errno;
-
- if ((flags & O_ACCMODE) == O_WRONLY) {
- errno = EINVAL;
- return (NULL);
- }
-
- if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
- return (NULL);
- hashp->fp = -1;
-
- /*
- * Even if user wants write only, we need to be able to read
- * the actual file, so we need to open it read/write. But, the
- * field in the hashp structure needs to be accurate so that
- * we can check accesses.
- */
- hashp->flags = flags;
-
- new_table = 0;
- if (!file || (flags & O_TRUNC) ||
- (stat(file, &statbuf) && (errno == ENOENT))) {
- if (errno == ENOENT)
- errno = 0; /* Just in case someone looks at errno */
- new_table = 1;
- }
- if (file) {
- if ((hashp->fp = open(file, flags, mode)) == -1)
- RETURN_ERROR(errno, error0);
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
- if (new_table) {
- if (!(hashp = init_hash(hashp, file, info)))
- RETURN_ERROR(errno, error1);
- } else {
- /* Table already exists */
- if (info && info->hash)
- hashp->hash = info->hash;
- else
- hashp->hash = __default_hash;
-
- hdrsize = read(hashp->fp, &hashp->hdr, sizeof(HASHHDR));
-#if BYTE_ORDER == LITTLE_ENDIAN
- swap_header(hashp);
-#endif
- if (hdrsize == -1)
- RETURN_ERROR(errno, error1);
- if (hdrsize != sizeof(HASHHDR))
- RETURN_ERROR(EFTYPE, error1);
- /* Verify file type, versions and hash function */
- if (hashp->MAGIC != HASHMAGIC)
- RETURN_ERROR(EFTYPE, error1);
-#define OLDHASHVERSION 1
- if (hashp->VERSION != HASHVERSION &&
- hashp->VERSION != OLDHASHVERSION)
- RETURN_ERROR(EFTYPE, error1);
- if (hashp->hash(CHARKEY, sizeof(CHARKEY))
- != (u_int32_t) hashp->H_CHARKEY)
- RETURN_ERROR(EFTYPE, error1);
- /*
- * Figure out how many segments we need. Max_Bucket is the
- * maximum bucket number, so the number of buckets is
- * max_bucket + 1.
- */
- nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
- hashp->SGSIZE;
- hashp->nsegs = 0;
- if (alloc_segs(hashp, nsegs))
- /*
- * If alloc_segs fails, table will have been destroyed
- * and errno will have been set.
- */
- return (NULL);
- /* Read in bitmaps */
- bpages = (hashp->SPARES[hashp->OVFL_POINT] +
- (hashp->BSIZE << BYTE_SHIFT) - 1) >>
- (hashp->BSHIFT + BYTE_SHIFT);
-
- hashp->nmaps = bpages;
- (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
- }
-
- /* Initialize Buffer Manager */
- if (info && info->cachesize)
- __buf_init(hashp, info->cachesize);
- else
- __buf_init(hashp, DEF_BUFSIZE);
-
- hashp->new_file = new_table;
- hashp->save_file = file && (hashp->flags & O_ACCMODE) != O_RDONLY;
- hashp->cbucket = -1;
- if (!(dbp = (DB *)malloc(sizeof(DB)))) {
- save_errno = errno;
- hdestroy(hashp);
- errno = save_errno;
- return (NULL);
- }
- dbp->internal = hashp;
- dbp->close = hash_close;
- dbp->del = hash_delete;
- dbp->fd = hash_fd;
- dbp->get = hash_get;
- dbp->put = hash_put;
- dbp->seq = hash_seq;
- dbp->sync = hash_sync;
- dbp->type = DB_HASH;
-
-#ifdef DEBUG
- (void)fprintf(stderr,
-"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
- "init_htab:",
- "TABLE POINTER ", hashp,
- "BUCKET SIZE ", hashp->BSIZE,
- "BUCKET SHIFT ", hashp->BSHIFT,
- "DIRECTORY SIZE ", hashp->DSIZE,
- "SEGMENT SIZE ", hashp->SGSIZE,
- "SEGMENT SHIFT ", hashp->SSHIFT,
- "FILL FACTOR ", hashp->FFACTOR,
- "MAX BUCKET ", hashp->MAX_BUCKET,
- "OVFL POINT ", hashp->OVFL_POINT,
- "LAST FREED ", hashp->LAST_FREED,
- "HIGH MASK ", hashp->HIGH_MASK,
- "LOW MASK ", hashp->LOW_MASK,
- "NSEGS ", hashp->nsegs,
- "NKEYS ", hashp->NKEYS);
-#endif
-#ifdef HASH_STATISTICS
- hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
-#endif
- return (dbp);
-
-error1:
- if (hashp != NULL)
- (void)close(hashp->fp);
-
-error0:
- free(hashp);
- errno = save_errno;
- return (NULL);
-}
-
-static int
-hash_close(dbp)
- DB *dbp;
-{
- HTAB *hashp;
- int retval;
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- retval = hdestroy(hashp);
- free(dbp);
- return (retval);
-}
-
-static int
-hash_fd(dbp)
- const DB *dbp;
-{
- HTAB *hashp;
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if (hashp->fp == -1) {
- errno = ENOENT;
- return (-1);
- }
- return (hashp->fp);
-}
-
-/************************** LOCAL CREATION ROUTINES **********************/
-static HTAB *
-init_hash(hashp, file, info)
- HTAB *hashp;
- const char *file;
- const HASHINFO *info;
-{
-#ifdef _STATBUF_ST_BLKSIZE
- struct stat statbuf;
-#endif
- int nelem;
-
- nelem = 1;
- hashp->NKEYS = 0;
- hashp->LORDER = BYTE_ORDER;
- hashp->BSIZE = DEF_BUCKET_SIZE;
- hashp->BSHIFT = DEF_BUCKET_SHIFT;
- hashp->SGSIZE = DEF_SEGSIZE;
- hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
- hashp->DSIZE = DEF_DIRSIZE;
- hashp->FFACTOR = DEF_FFACTOR;
- hashp->hash = __default_hash;
- memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
- memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
-
- /* Fix bucket size to be optimal for file system */
-#ifdef _STATBUF_ST_BLKSIZE
- if (file != NULL) {
- if (stat(file, &statbuf))
- return (NULL);
- hashp->BSIZE = statbuf.st_blksize;
- hashp->BSHIFT = __hash_log2(hashp->BSIZE);
- }
-#endif
-
- if (info) {
- if (info->bsize) {
- /* Round pagesize up to power of 2 */
- hashp->BSHIFT = __hash_log2(info->bsize);
- hashp->BSIZE = 1 << hashp->BSHIFT;
- if (hashp->BSIZE > MAX_BSIZE) {
- errno = EINVAL;
- return (NULL);
- }
- }
- if (info->ffactor)
- hashp->FFACTOR = info->ffactor;
- if (info->hash)
- hashp->hash = info->hash;
- if (info->nelem)
- nelem = info->nelem;
- if (info->lorder) {
- if (info->lorder != BIG_ENDIAN &&
- info->lorder != LITTLE_ENDIAN) {
- errno = EINVAL;
- return (NULL);
- }
- hashp->LORDER = info->lorder;
- }
- }
- /* init_htab should destroy the table and set errno if it fails */
- if (init_htab(hashp, nelem))
- return (NULL);
- else
- return (hashp);
-}
-/*
- * This calls alloc_segs which may run out of memory. Alloc_segs will destroy
- * the table and set errno, so we just pass the error information along.
- *
- * Returns 0 on No Error
- */
-static int
-init_htab(hashp, nelem)
- HTAB *hashp;
- int nelem;
-{
- register int nbuckets, nsegs;
- int l2;
-
- /*
- * Divide number of elements by the fill factor and determine a
- * desired number of buckets. Allocate space for the next greater
- * power of two number of buckets.
- */
- nelem = (nelem - 1) / hashp->FFACTOR + 1;
-
- l2 = __hash_log2(MAX(nelem, 2));
- nbuckets = 1 << l2;
-
- hashp->SPARES[l2] = l2 + 1;
- hashp->SPARES[l2 + 1] = l2 + 1;
- hashp->OVFL_POINT = l2;
- hashp->LAST_FREED = 2;
-
- /* First bitmap page is at: splitpoint l2 page offset 1 */
- if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
- return (-1);
-
- hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
- hashp->HIGH_MASK = (nbuckets << 1) - 1;
- hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
- hashp->BSHIFT) + 1;
-
- nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
- nsegs = 1 << __hash_log2(nsegs);
-
- if (nsegs > hashp->DSIZE)
- hashp->DSIZE = nsegs;
- return (alloc_segs(hashp, nsegs));
-}
-
-/********************** DESTROY/CLOSE ROUTINES ************************/
-
-/*
- * Flushes any changes to the file if necessary and destroys the hashp
- * structure, freeing all allocated space.
- */
-static int
-hdestroy(hashp)
- HTAB *hashp;
-{
- int i, save_errno;
-
- save_errno = 0;
-
-#ifdef HASH_STATISTICS
- (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
- hash_accesses, hash_collisions);
- (void)fprintf(stderr, "hdestroy: expansions %ld\n",
- hash_expansions);
- (void)fprintf(stderr, "hdestroy: overflows %ld\n",
- hash_overflows);
- (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
- hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
-
- for (i = 0; i < NCACHED; i++)
- (void)fprintf(stderr,
- "spares[%d] = %d\n", i, hashp->SPARES[i]);
-#endif
- /*
- * Call on buffer manager to free buffers, and if required,
- * write them to disk.
- */
- if (__buf_free(hashp, 1, hashp->save_file))
- save_errno = errno;
- if (hashp->dir) {
- free(*hashp->dir); /* Free initial segments */
- /* Free extra segments */
- while (hashp->exsegs--)
- free(hashp->dir[--hashp->nsegs]);
- free(hashp->dir);
- }
- if (flush_meta(hashp) && !save_errno)
- save_errno = errno;
- /* Free Bigmaps */
- for (i = 0; i < hashp->nmaps; i++)
- if (hashp->mapp[i])
- free(hashp->mapp[i]);
-
- if (hashp->fp != -1)
- (void)close(hashp->fp);
-
- free(hashp);
-
- if (save_errno) {
- errno = save_errno;
- return (ERROR);
- }
- return (SUCCESS);
-}
-/*
- * Write modified pages to disk
- *
- * Returns:
- * 0 == OK
- * -1 ERROR
- */
-static int
-hash_sync(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- HTAB *hashp;
-
- if (flags != 0) {
- errno = EINVAL;
- return (ERROR);
- }
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if (!hashp->save_file)
- return (0);
- if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
- return (ERROR);
- hashp->new_file = 0;
- return (0);
-}
-
-/*
- * Returns:
- * 0 == OK
- * -1 indicates that errno should be set
- */
-static int
-flush_meta(hashp)
- HTAB *hashp;
-{
- HASHHDR *whdrp;
-#if BYTE_ORDER == LITTLE_ENDIAN
- HASHHDR whdr;
-#endif
- int fp, i, wsize;
-
- if (!hashp->save_file)
- return (0);
- hashp->MAGIC = HASHMAGIC;
- hashp->VERSION = HASHVERSION;
- hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
-
- fp = hashp->fp;
- whdrp = &hashp->hdr;
-#if BYTE_ORDER == LITTLE_ENDIAN
- whdrp = &whdr;
- swap_header_copy(&hashp->hdr, whdrp);
-#endif
- if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
- ((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1))
- return (-1);
- else
- if (wsize != sizeof(HASHHDR)) {
- errno = EFTYPE;
- hashp->errnum = errno;
- return (-1);
- }
- for (i = 0; i < NCACHED; i++)
- if (hashp->mapp[i])
- if (__put_page(hashp, (char *)hashp->mapp[i],
- hashp->BITMAPS[i], 0, 1))
- return (-1);
- return (0);
-}
-
-/*******************************SEARCH ROUTINES *****************************/
-/*
- * All the access routines return
- *
- * Returns:
- * 0 on SUCCESS
- * 1 to indicate an external ERROR (i.e. key not found, etc)
- * -1 to indicate an internal ERROR (i.e. out of memory, etc)
- */
-static int
-hash_get(dbp, key, data, flag)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int32_t flag;
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
- return (hash_access(hashp, HASH_GET, (DBT *)key, data));
-}
-
-static int
-hash_put(dbp, key, data, flag)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int32_t flag;
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_NOOVERWRITE) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->errnum = errno = EPERM;
- return (ERROR);
- }
- return (hash_access(hashp, flag == R_NOOVERWRITE ?
- HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));
-}
-
-static int
-hash_delete(dbp, key, flag)
- const DB *dbp;
- const DBT *key;
- u_int32_t flag; /* Ignored */
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_CURSOR) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->errnum = errno = EPERM;
- return (ERROR);
- }
- return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
-}
-
-/*
- * Assume that hashp has been set in wrapper routine.
- */
-static int
-hash_access(hashp, action, key, val)
- HTAB *hashp;
- ACTION action;
- DBT *key, *val;
-{
- register BUFHEAD *rbufp;
- BUFHEAD *bufp, *save_bufp;
- register u_int16_t *bp;
- register int n, ndx, off, size;
- register char *kp;
- u_int16_t pageno;
-
-#ifdef HASH_STATISTICS
- hash_accesses++;
-#endif
-
- off = hashp->BSIZE;
- size = key->size;
- kp = (char *)key->data;
- rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
- if (!rbufp)
- return (ERROR);
- save_bufp = rbufp;
-
- /* Pin the bucket chain */
- rbufp->flags |= BUF_PIN;
- for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
- if (bp[1] >= REAL_KEY) {
- /* Real key/data pair */
- if (size == off - *bp &&
- memcmp(kp, rbufp->page + *bp, size) == 0)
- goto found;
- off = bp[1];
-#ifdef HASH_STATISTICS
- hash_collisions++;
-#endif
- bp += 2;
- ndx += 2;
- } else if (bp[1] == OVFLPAGE) {
- rbufp = __get_buf(hashp, *bp, rbufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- /* FOR LOOP INIT */
- bp = (u_int16_t *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else if (bp[1] < REAL_KEY) {
- if ((ndx =
- __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)
- goto found;
- if (ndx == -2) {
- bufp = rbufp;
- if (!(pageno =
- __find_last_page(hashp, &bufp))) {
- ndx = 0;
- rbufp = bufp;
- break; /* FOR */
- }
- rbufp = __get_buf(hashp, pageno, bufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- /* FOR LOOP INIT */
- bp = (u_int16_t *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- }
-
- /* Not found */
- switch (action) {
- case HASH_PUT:
- case HASH_PUTNEW:
- if (__addel(hashp, rbufp, key, val)) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
- }
- case HASH_GET:
- case HASH_DELETE:
- default:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- }
-
-found:
- switch (action) {
- case HASH_PUTNEW:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- case HASH_GET:
- bp = (u_int16_t *)rbufp->page;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_return(hashp, rbufp, ndx, val, 0))
- return (ERROR);
- } else {
- val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];
- val->size = bp[ndx] - bp[ndx + 1];
- }
- break;
- case HASH_PUT:
- if ((__delpair(hashp, rbufp, ndx)) ||
- (__addel(hashp, rbufp, key, val))) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- break;
- case HASH_DELETE:
- if (__delpair(hashp, rbufp, ndx))
- return (ERROR);
- break;
- default:
- abort();
- }
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
-}
-
-static int
-hash_seq(dbp, key, data, flag)
- const DB *dbp;
- DBT *key, *data;
- u_int32_t flag;
-{
- register u_int32_t bucket;
- register BUFHEAD *bufp = NULL;
- HTAB *hashp;
- u_int16_t *bp, ndx;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_FIRST && flag != R_NEXT) {
- hashp->errnum = errno = EINVAL;
- return (ERROR);
- }
-#ifdef HASH_STATISTICS
- hash_accesses++;
-#endif
- if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
- hashp->cbucket = 0;
- hashp->cndx = 1;
- hashp->cpage = NULL;
- }
-
- for (bp = NULL; !bp || !bp[0]; ) {
- if (!(bufp = hashp->cpage)) {
- for (bucket = hashp->cbucket;
- bucket <= (u_int32_t) hashp->MAX_BUCKET;
- bucket++, hashp->cndx = 1) {
- bufp = __get_buf(hashp, bucket, NULL, 0);
- if (!bufp)
- return (ERROR);
- hashp->cpage = bufp;
- bp = (u_int16_t *)bufp->page;
- if (bp[0])
- break;
- }
- hashp->cbucket = bucket;
- if (hashp->cbucket > hashp->MAX_BUCKET) {
- hashp->cbucket = -1;
- return (ABNORMAL);
- }
- } else
- bp = (u_int16_t *)hashp->cpage->page;
-
-#ifdef DEBUG
- assert(bp);
- assert(bufp);
-#endif
- while (bp[hashp->cndx + 1] == OVFLPAGE) {
- bufp = hashp->cpage =
- __get_buf(hashp, bp[hashp->cndx], bufp, 0);
- if (!bufp)
- return (ERROR);
- bp = (u_int16_t *)(bufp->page);
- hashp->cndx = 1;
- }
- if (!bp[0]) {
- hashp->cpage = NULL;
- ++hashp->cbucket;
- }
- }
- ndx = hashp->cndx;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_keydata(hashp, bufp, key, data, 1))
- return (ERROR);
- } else {
- key->data = (u_char *)hashp->cpage->page + bp[ndx];
- key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
- data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];
- data->size = bp[ndx] - bp[ndx + 1];
- ndx += 2;
- if (ndx > bp[0]) {
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else
- hashp->cndx = ndx;
- }
- return (SUCCESS);
-}
-
-/********************************* UTILITIES ************************/
-
-/*
- * Returns:
- * 0 ==> OK
- * -1 ==> Error
- */
-extern int
-__expand_table(hashp)
- HTAB *hashp;
-{
- u_int32_t old_bucket, new_bucket;
- int dirsize, new_segnum, spare_ndx;
-
-#ifdef HASH_STATISTICS
- hash_expansions++;
-#endif
- new_bucket = ++hashp->MAX_BUCKET;
- old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
-
- new_segnum = new_bucket >> hashp->SSHIFT;
-
- /* Check if we need a new segment */
- if (new_segnum >= hashp->nsegs) {
- /* Check if we need to expand directory */
- if (new_segnum >= hashp->DSIZE) {
- /* Reallocate directory */
- dirsize = hashp->DSIZE * sizeof(SEGMENT *);
- if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
- return (-1);
- hashp->DSIZE = dirsize << 1;
- }
- if ((hashp->dir[new_segnum] =
- (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
- return (-1);
- hashp->exsegs++;
- hashp->nsegs++;
- }
- /*
- * If the split point is increasing (MAX_BUCKET's log base 2
- * * increases), we need to copy the current contents of the spare
- * split bucket to the next bucket.
- */
- spare_ndx = __hash_log2(hashp->MAX_BUCKET + 1);
- if (spare_ndx > hashp->OVFL_POINT) {
- hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
- hashp->OVFL_POINT = spare_ndx;
- }
-
- if (new_bucket > (u_int32_t) hashp->HIGH_MASK) {
- /* Starting a new doubling */
- hashp->LOW_MASK = hashp->HIGH_MASK;
- hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
- }
- /* Relocate records to the new bucket */
- return (__split_page(hashp, old_bucket, new_bucket));
-}
-
-/*
- * If realloc guarantees that the pointer is not destroyed if the realloc
- * fails, then this routine can go away.
- */
-static void *
-hash_realloc(p_ptr, oldsize, newsize)
- SEGMENT **p_ptr;
- int oldsize, newsize;
-{
- register void *p;
-
- if ((p = malloc(newsize))) {
- memmove(p, *p_ptr, oldsize);
- memset((char *)p + oldsize, 0, newsize - oldsize);
- free(*p_ptr);
- *p_ptr = p;
- }
- return (p);
-}
-
-extern u_int32_t
-__call_hash(hashp, k, len)
- HTAB *hashp;
- char *k;
- int len;
-{
- int n, bucket;
-
- n = hashp->hash(k, len);
- bucket = n & hashp->HIGH_MASK;
- if (bucket > hashp->MAX_BUCKET)
- bucket = bucket & hashp->LOW_MASK;
- return (bucket);
-}
-
-/*
- * Allocate segment table. On error, destroy the table and set errno.
- *
- * Returns 0 on success
- */
-static int
-alloc_segs(hashp, nsegs)
- HTAB *hashp;
- int nsegs;
-{
- register int i;
- register SEGMENT store;
-
- int save_errno;
-
- if ((hashp->dir =
- (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
- save_errno = errno;
- (void)hdestroy(hashp);
- errno = save_errno;
- return (-1);
- }
- /* Allocate segments */
- if ((store =
- (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
- save_errno = errno;
- (void)hdestroy(hashp);
- errno = save_errno;
- return (-1);
- }
- for (i = 0; i < nsegs; i++, hashp->nsegs++)
- hashp->dir[i] = &store[i << hashp->SSHIFT];
- return (0);
-}
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-/*
- * Hashp->hdr needs to be byteswapped.
- */
-static void
-swap_header_copy(srcp, destp)
- HASHHDR *srcp, *destp;
-{
- int i;
-
- P_32_COPY(srcp->magic, destp->magic);
- P_32_COPY(srcp->version, destp->version);
- P_32_COPY(srcp->lorder, destp->lorder);
- P_32_COPY(srcp->bsize, destp->bsize);
- P_32_COPY(srcp->bshift, destp->bshift);
- P_32_COPY(srcp->dsize, destp->dsize);
- P_32_COPY(srcp->ssize, destp->ssize);
- P_32_COPY(srcp->sshift, destp->sshift);
- P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
- P_32_COPY(srcp->last_freed, destp->last_freed);
- P_32_COPY(srcp->max_bucket, destp->max_bucket);
- P_32_COPY(srcp->high_mask, destp->high_mask);
- P_32_COPY(srcp->low_mask, destp->low_mask);
- P_32_COPY(srcp->ffactor, destp->ffactor);
- P_32_COPY(srcp->nkeys, destp->nkeys);
- P_32_COPY(srcp->hdrpages, destp->hdrpages);
- P_32_COPY(srcp->h_charkey, destp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- P_32_COPY(srcp->spares[i], destp->spares[i]);
- P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
- }
-}
-
-static void
-swap_header(hashp)
- HTAB *hashp;
-{
- HASHHDR *hdrp;
- int i;
-
- hdrp = &hashp->hdr;
-
- M_32_SWAP(hdrp->magic);
- M_32_SWAP(hdrp->version);
- M_32_SWAP(hdrp->lorder);
- M_32_SWAP(hdrp->bsize);
- M_32_SWAP(hdrp->bshift);
- M_32_SWAP(hdrp->dsize);
- M_32_SWAP(hdrp->ssize);
- M_32_SWAP(hdrp->sshift);
- M_32_SWAP(hdrp->ovfl_point);
- M_32_SWAP(hdrp->last_freed);
- M_32_SWAP(hdrp->max_bucket);
- M_32_SWAP(hdrp->high_mask);
- M_32_SWAP(hdrp->low_mask);
- M_32_SWAP(hdrp->ffactor);
- M_32_SWAP(hdrp->nkeys);
- M_32_SWAP(hdrp->hdrpages);
- M_32_SWAP(hdrp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- M_32_SWAP(hdrp->spares[i]);
- M_16_SWAP(hdrp->bitmaps[i]);
- }
-}
-#endif
diff --git a/1.4/main/db1-ast/hash/hash.h b/1.4/main/db1-ast/hash/hash.h
deleted file mode 100644
index d07db6f07..000000000
--- a/1.4/main/db1-ast/hash/hash.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)hash.h 8.3 (Berkeley) 5/31/94
- */
-
-/* Operations */
-typedef enum {
- HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
-} ACTION;
-
-/* Buffer Management structures */
-typedef struct _bufhead BUFHEAD;
-
-struct _bufhead {
- BUFHEAD *prev; /* LRU links */
- BUFHEAD *next; /* LRU links */
- BUFHEAD *ovfl; /* Overflow page buffer header */
- u_int32_t addr; /* Address of this page */
- char *page; /* Actual page data */
- char flags;
-#define BUF_MOD 0x0001
-#define BUF_DISK 0x0002
-#define BUF_BUCKET 0x0004
-#define BUF_PIN 0x0008
-};
-
-#define IS_BUCKET(X) ((X) & BUF_BUCKET)
-
-typedef BUFHEAD **SEGMENT;
-
-/* Hash Table Information */
-typedef struct hashhdr { /* Disk resident portion */
- int magic; /* Magic NO for hash tables */
- int version; /* Version ID */
- u_int32_t lorder; /* Byte Order */
- int bsize; /* Bucket/Page Size */
- int bshift; /* Bucket shift */
- int dsize; /* Directory Size */
- int ssize; /* Segment Size */
- int sshift; /* Segment shift */
- int ovfl_point; /* Where overflow pages are being
- * allocated */
- int last_freed; /* Last overflow page freed */
- int max_bucket; /* ID of Maximum bucket in use */
- int high_mask; /* Mask to modulo into entire table */
- int low_mask; /* Mask to modulo into lower half of
- * table */
- int ffactor; /* Fill factor */
- int nkeys; /* Number of keys in hash table */
- int hdrpages; /* Size of table header */
- int h_charkey; /* value of hash(CHARKEY) */
-#define NCACHED 32 /* number of bit maps and spare
- * points */
- int spares[NCACHED];/* spare pages for overflow */
- u_int16_t bitmaps[NCACHED]; /* address of overflow page
- * bitmaps */
-} HASHHDR;
-
-typedef struct htab { /* Memory resident data structure */
- HASHHDR hdr; /* Header */
- int nsegs; /* Number of allocated segments */
- int exsegs; /* Number of extra allocated
- * segments */
- u_int32_t /* Hash function */
- (*hash)__P((const void *, size_t));
- int flags; /* Flag values */
- int fp; /* File pointer */
- char *tmp_buf; /* Temporary Buffer for BIG data */
- char *tmp_key; /* Temporary Buffer for BIG keys */
- BUFHEAD *cpage; /* Current page */
- int cbucket; /* Current bucket */
- int cndx; /* Index of next item on cpage */
- int errnum; /* Error Number -- for DBM
- * compatibility */
- int new_file; /* Indicates if fd is backing store
- * or no */
- int save_file; /* Indicates whether we need to flush
- * file at
- * exit */
- u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
- int nmaps; /* Initial number of bitmaps */
- int nbufs; /* Number of buffers left to
- * allocate */
- BUFHEAD bufhead; /* Header of buffer lru list */
- SEGMENT *dir; /* Hash Bucket directory */
-} HTAB;
-
-/*
- * Constants
- */
-#define MAX_BSIZE 65536 /* 2^16 */
-#define MIN_BUFFERS 6
-#define MINHDRSIZE 512
-#define DEF_BUFSIZE 65536 /* 64 K */
-#define DEF_BUCKET_SIZE 4096
-#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
-#define DEF_SEGSIZE 256
-#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
-#define DEF_DIRSIZE 256
-#define DEF_FFACTOR 65536
-#define MIN_FFACTOR 4
-#define SPLTMAX 8
-#define CHARKEY "%$sniglet^&"
-#define NUMKEY 1038583
-#define BYTE_SHIFT 3
-#define INT_TO_BYTE 2
-#define INT_BYTE_SHIFT 5
-#define ALL_SET ((u_int32_t)0xFFFFFFFF)
-#define ALL_CLEAR 0
-
-#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
-#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
-#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
-#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
-#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
-
-#define BITS_PER_MAP 32
-
-/* Given the address of the beginning of a big map, clear/set the nth bit */
-#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
-#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
-#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
-
-/* Overflow management */
-/*
- * Overflow page numbers are allocated per split point. At each doubling of
- * the table, we can allocate extra pages. So, an overflow page number has
- * the top 5 bits indicate which split point and the lower 11 bits indicate
- * which page at that split point is indicated (pages within split points are
- * numberered starting with 1).
- */
-
-#define SPLITSHIFT 11
-#define SPLITMASK 0x7FF
-#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
-#define OPAGENUM(N) ((N) & SPLITMASK)
-#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
-
-#define BUCKET_TO_PAGE(B) \
- (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__hash_log2((B)+1)-1] : 0)
-#define OADDR_TO_PAGE(B) \
- BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
-
-/*
- * page.h contains a detailed description of the page format.
- *
- * Normally, keys and data are accessed from offset tables in the top of
- * each page which point to the beginning of the key and data. There are
- * four flag values which may be stored in these offset tables which indicate
- * the following:
- *
- *
- * OVFLPAGE Rather than a key data pair, this pair contains
- * the address of an overflow page. The format of
- * the pair is:
- * OVERFLOW_PAGE_NUMBER OVFLPAGE
- *
- * PARTIAL_KEY This must be the first key/data pair on a page
- * and implies that page contains only a partial key.
- * That is, the key is too big to fit on a single page
- * so it starts on this page and continues on the next.
- * The format of the page is:
- * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * PARTIAL_KEY -- 1
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * FULL_KEY This must be the first key/data pair on the page. It
- * is used in two cases.
- *
- * Case 1:
- * There is a complete key on the page but no data
- * (because it wouldn't fit). The next page contains
- * the data.
- *
- * Page format it:
- * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * Case 2:
- * This page contains no key, but part of a large
- * data field, which is continued on the next page.
- *
- * Page format it:
- * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
- *
- * KEY_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * FULL_KEY_DATA
- * This must be the first key/data pair on the page.
- * There are two cases:
- *
- * Case 1:
- * This page contains a key and the beginning of the
- * data field, but the data field is continued on the
- * next page.
- *
- * Page format is:
- * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
- *
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * DATA_OFF -- offset of the beginning of the data
- *
- * Case 2:
- * This page contains the last page of a big data pair.
- * There is no key, only the tail end of the data
- * on this page.
- *
- * Page format is:
- * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
- *
- * DATA_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * OVFL_PAGENO and OVFLPAGE are optional (they are
- * not present if there is no next page).
- */
-
-#define OVFLPAGE 0
-#define PARTIAL_KEY 1
-#define FULL_KEY 2
-#define FULL_KEY_DATA 3
-#define REAL_KEY 4
-
-/* Short hands for accessing structure */
-#define BSIZE hdr.bsize
-#define BSHIFT hdr.bshift
-#define DSIZE hdr.dsize
-#define SGSIZE hdr.ssize
-#define SSHIFT hdr.sshift
-#define LORDER hdr.lorder
-#define OVFL_POINT hdr.ovfl_point
-#define LAST_FREED hdr.last_freed
-#define MAX_BUCKET hdr.max_bucket
-#define FFACTOR hdr.ffactor
-#define HIGH_MASK hdr.high_mask
-#define LOW_MASK hdr.low_mask
-#define NKEYS hdr.nkeys
-#define HDRPAGES hdr.hdrpages
-#define SPARES hdr.spares
-#define BITMAPS hdr.bitmaps
-#define VERSION hdr.version
-#define MAGIC hdr.magic
-#define NEXT_FREE hdr.next_free
-#define H_CHARKEY hdr.h_charkey
diff --git a/1.4/main/db1-ast/hash/hash_bigkey.c b/1.4/main/db1-ast/hash/hash_bigkey.c
deleted file mode 100644
index daa8c1f17..000000000
--- a/1.4/main/db1-ast/hash/hash_bigkey.c
+++ /dev/null
@@ -1,668 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * PACKAGE: hash
- * DESCRIPTION:
- * Big key/data handling for the hashing package.
- *
- * ROUTINES:
- * External
- * __big_keydata
- * __big_split
- * __big_insert
- * __big_return
- * __big_delete
- * __find_last_page
- * Internal
- * collect_key
- * collect_data
- */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include "../include/db.h"
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int));
-static int collect_data __P((HTAB *, BUFHEAD *, int, int));
-
-/*
- * Big_insert
- *
- * You need to do an insert and the key/data pair is too big
- *
- * Returns:
- * 0 ==> OK
- *-1 ==> ERROR
- */
-extern int
-__big_insert(hashp, bufp, key, val)
- HTAB *hashp;
- BUFHEAD *bufp;
- const DBT *key, *val;
-{
- register u_int16_t *p;
- int key_size, n, val_size;
- u_int16_t space, move_bytes, off;
- char *cp, *key_data, *val_data;
-
- cp = bufp->page; /* Character pointer of p. */
- p = (u_int16_t *)cp;
-
- key_data = (char *)key->data;
- key_size = key->size;
- val_data = (char *)val->data;
- val_size = val->size;
-
- /* First move the Key */
- for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = MIN(space, key_size);
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, key_data, move_bytes);
- key_size -= move_bytes;
- key_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- p[n] = PARTIAL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- n = p[0];
- if (!key_size) {
- if (FREESPACE(p)) {
- move_bytes = MIN(FREESPACE(p), val_size);
- off = OFFSET(p) - move_bytes;
- p[n] = off;
- memmove(cp + off, val_data, move_bytes);
- val_data += move_bytes;
- val_size -= move_bytes;
- p[n - 2] = FULL_KEY_DATA;
- FREESPACE(p) = FREESPACE(p) - move_bytes;
- OFFSET(p) = off;
- } else
- p[n - 2] = FULL_KEY;
- }
- p = (u_int16_t *)bufp->page;
- cp = bufp->page;
- bufp->flags |= BUF_MOD;
- }
-
- /* Now move the data */
- for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = MIN(space, val_size);
- /*
- * Here's the hack to make sure that if the data ends on the
- * same page as the key ends, FREESPACE is at least one.
- */
- if ((int) space == val_size && (size_t) val_size == val->size)
- move_bytes--;
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, val_data, move_bytes);
- val_size -= move_bytes;
- val_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- if (val_size) {
- p[n] = FULL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- cp = bufp->page;
- p = (u_int16_t *)cp;
- } else
- p[n] = FULL_KEY_DATA;
- bufp->flags |= BUF_MOD;
- }
- return (0);
-}
-
-/*
- * Called when bufp's page contains a partial key (index should be 1)
- *
- * All pages in the big key/data pair except bufp are freed. We cannot
- * free bufp because the page pointing to it is lost and we can't get rid
- * of its pointer.
- *
- * Returns:
- * 0 => OK
- *-1 => ERROR
- */
-extern int
-__big_delete(hashp, bufp)
- HTAB *hashp;
- BUFHEAD *bufp;
-{
- register BUFHEAD *last_bfp, *rbufp;
- u_int16_t *bp, pageno;
- int key_done, n;
-
- rbufp = bufp;
- last_bfp = NULL;
- bp = (u_int16_t *)bufp->page;
- pageno = 0;
- key_done = 0;
-
- while (!key_done || (bp[2] != FULL_KEY_DATA)) {
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
- key_done = 1;
-
- /*
- * If there is freespace left on a FULL_KEY_DATA page, then
- * the data is short and fits entirely on this page, and this
- * is the last page.
- */
- if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
- break;
- pageno = bp[bp[0] - 1];
- rbufp->flags |= BUF_MOD;
- rbufp = __get_buf(hashp, pageno, rbufp, 0);
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = rbufp;
- if (!rbufp)
- return (-1); /* Error. */
- bp = (u_int16_t *)rbufp->page;
- }
-
- /*
- * If we get here then rbufp points to the last page of the big
- * key/data pair. Bufp points to the first one -- it should now be
- * empty pointing to the next page after this pair. Can't free it
- * because we don't have the page pointing to it.
- */
-
- /* This is information from the last page of the pair. */
- n = bp[0];
- pageno = bp[n - 1];
-
- /* Now, bp is the first page of the pair. */
- bp = (u_int16_t *)bufp->page;
- if (n > 2) {
- /* There is an overflow page. */
- bp[1] = pageno;
- bp[2] = OVFLPAGE;
- bufp->ovfl = rbufp->ovfl;
- } else
- /* This is the last page. */
- bufp->ovfl = NULL;
- n -= 2;
- bp[0] = n;
- FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
- OFFSET(bp) = hashp->BSIZE - 1;
-
- bufp->flags |= BUF_MOD;
- if (rbufp)
- __free_ovflpage(hashp, rbufp);
- if (last_bfp && last_bfp != rbufp)
- __free_ovflpage(hashp, last_bfp);
-
- hashp->NKEYS--;
- return (0);
-}
-/*
- * Returns:
- * 0 = key not found
- * -1 = get next overflow page
- * -2 means key not found and this is big key/data
- * -3 error
- */
-extern int
-__find_bigpair(hashp, bufp, ndx, key, size)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
- char *key;
- int size;
-{
- register u_int16_t *bp;
- register char *p;
- int ksize;
- u_int16_t bytes;
- char *kkey;
-
- bp = (u_int16_t *)bufp->page;
- p = bufp->page;
- ksize = size;
- kkey = key;
-
- for (bytes = hashp->BSIZE - bp[ndx];
- bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
- bytes = hashp->BSIZE - bp[ndx]) {
- if (memcmp(p + bp[ndx], kkey, bytes))
- return (-2);
- kkey += bytes;
- ksize -= bytes;
- bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
- if (!bufp)
- return (-3);
- p = bufp->page;
- bp = (u_int16_t *)p;
- ndx = 1;
- }
-
- if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
-#ifdef HASH_STATISTICS
- ++hash_collisions;
-#endif
- return (-2);
- } else
- return (ndx);
-}
-
-/*
- * Given the buffer pointer of the first overflow page of a big pair,
- * find the end of the big pair
- *
- * This will set bpp to the buffer header of the last page of the big pair.
- * It will return the pageno of the overflow page following the last page
- * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
- * bucket)
- */
-extern u_int16_t
-__find_last_page(hashp, bpp)
- HTAB *hashp;
- BUFHEAD **bpp;
-{
- BUFHEAD *bufp;
- u_int16_t *bp, pageno;
- int n;
-
- bufp = *bpp;
- bp = (u_int16_t *)bufp->page;
- for (;;) {
- n = bp[0];
-
- /*
- * This is the last page if: the tag is FULL_KEY_DATA and
- * either only 2 entries OVFLPAGE marker is explicit there
- * is freespace on the page.
- */
- if (bp[2] == FULL_KEY_DATA &&
- ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
- break;
-
- pageno = bp[n - 1];
- bufp = __get_buf(hashp, pageno, bufp, 0);
- if (!bufp)
- return (0); /* Need to indicate an error! */
- bp = (u_int16_t *)bufp->page;
- }
-
- *bpp = bufp;
- if (bp[0] > 2)
- return (bp[3]);
- else
- return (0);
-}
-
-/*
- * Return the data for the key/data pair that begins on this page at this
- * index (index should always be 1).
- */
-extern int
-__big_return(hashp, bufp, ndx, val, set_current)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
- DBT *val;
- int set_current;
-{
- BUFHEAD *save_p;
- u_int16_t *bp, len, off, save_addr;
- char *tp;
-
- bp = (u_int16_t *)bufp->page;
- while (bp[ndx + 1] == PARTIAL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- ndx = 1;
- }
-
- if (bp[ndx + 1] == FULL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- save_p = bufp;
- save_addr = save_p->addr;
- off = bp[1];
- len = 0;
- } else
- if (!FREESPACE(bp)) {
- /*
- * This is a hack. We can't distinguish between
- * FULL_KEY_DATA that contains complete data or
- * incomplete data, so we require that if the data
- * is complete, there is at least 1 byte of free
- * space left.
- */
- off = bp[bp[0]];
- len = bp[1] - off;
- save_p = bufp;
- save_addr = bufp->addr;
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- } else {
- /* The data is all on one page. */
- tp = (char *)bp;
- off = bp[bp[0]];
- val->data = (u_char *)tp + off;
- val->size = bp[1] - off;
- if (set_current) {
- if (bp[0] == 2) { /* No more buckets in
- * chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else {
- hashp->cpage = __get_buf(hashp,
- bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- hashp->cndx = 1;
- if (!((u_int16_t *)
- hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- return (0);
- }
-
- val->size = collect_data(hashp, bufp, (int)len, set_current);
- if (val->size == (size_t) -1)
- return (-1);
- if (save_p->addr != save_addr) {
- /* We are pretty short on buffers. */
- errno = EINVAL; /* OUT OF BUFFERS */
- return (-1);
- }
- memmove(hashp->tmp_buf, (save_p->page) + off, len);
- val->data = (u_char *)hashp->tmp_buf;
- return (0);
-}
-/*
- * Count how big the total datasize is by recursing through the pages. Then
- * allocate a buffer and copy the data as you recurse up.
- */
-static int
-collect_data(hashp, bufp, len, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- int len, set;
-{
- register u_int16_t *bp;
- register char *p;
- BUFHEAD *xbp;
- u_int16_t save_addr;
- int mylen, totlen;
-
- p = bufp->page;
- bp = (u_int16_t *)p;
- mylen = hashp->BSIZE - bp[1];
- save_addr = bufp->addr;
-
- if (bp[2] == FULL_KEY_DATA) { /* End of Data */
- totlen = len + mylen;
- if (hashp->tmp_buf)
- free(hashp->tmp_buf);
- if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
- return (-1);
- if (set) {
- hashp->cndx = 1;
- if (bp[0] == 2) { /* No more buckets in chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- } else {
- hashp->cpage =
- __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- else if (!((u_int16_t *)hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_data(hashp, xbp, len + mylen, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* Out of buffers. */
- return (-1);
- }
- memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
- return (totlen);
-}
-
-/*
- * Fill in the key and data for this big pair.
- */
-extern int
-__big_keydata(hashp, bufp, key, val, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- DBT *key, *val;
- int set;
-{
- key->size = collect_key(hashp, bufp, 0, val, set);
- if (key->size == (size_t) -1)
- return (-1);
- key->data = (u_char *)hashp->tmp_key;
- return (0);
-}
-
-/*
- * Count how big the total key size is by recursing through the pages. Then
- * collect the data, allocate a buffer and copy the key as you recurse up.
- */
-static int
-collect_key(hashp, bufp, len, val, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- int len;
- DBT *val;
- int set;
-{
- BUFHEAD *xbp;
- char *p;
- int mylen, totlen;
- u_int16_t *bp, save_addr;
-
- p = bufp->page;
- bp = (u_int16_t *)p;
- mylen = hashp->BSIZE - bp[1];
-
- save_addr = bufp->addr;
- totlen = len + mylen;
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
- if (hashp->tmp_key != NULL)
- free(hashp->tmp_key);
- if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
- return (-1);
- if (__big_return(hashp, bufp, 1, val, set))
- return (-1);
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_key(hashp, xbp, totlen, val, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* MIS -- OUT OF BUFFERS */
- return (-1);
- }
- memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
- return (totlen);
-}
-
-/*
- * Returns:
- * 0 => OK
- * -1 => error
- */
-extern int
-__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
- HTAB *hashp;
- BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
- BUFHEAD *np; /* Pointer to new bucket page */
- /* Pointer to first page containing the big key/data */
- BUFHEAD *big_keyp;
- int addr; /* Address of big_keyp */
- u_int32_t obucket;/* Old Bucket */
- SPLIT_RETURN *ret;
-{
- register BUFHEAD *tmpp;
- register u_int16_t *tp;
- BUFHEAD *bp;
- DBT key, val;
- u_int32_t change;
- u_int16_t free_space, n, off;
-
- bp = big_keyp;
-
- /* Now figure out where the big key/data goes */
- if (__big_keydata(hashp, big_keyp, &key, &val, 0))
- return (-1);
- change = (__call_hash(hashp, key.data, key.size) != obucket);
-
- if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) {
- if (!(ret->nextp =
- __get_buf(hashp, ret->next_addr, big_keyp, 0)))
- return (-1);;
- } else
- ret->nextp = NULL;
-
- /* Now make one of np/op point to the big key/data pair */
-#ifdef DEBUG
- assert(np->ovfl == NULL);
-#endif
- if (change)
- tmpp = np;
- else
- tmpp = op;
-
- tmpp->flags |= BUF_MOD;
-#ifdef DEBUG1
- (void)fprintf(stderr,
- "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
- (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
-#endif
- tmpp->ovfl = bp; /* one of op/np point to big_keyp */
- tp = (u_int16_t *)tmpp->page;
-#ifdef DEBUG
- assert(FREESPACE(tp) >= OVFLSIZE);
-#endif
- n = tp[0];
- off = OFFSET(tp);
- free_space = FREESPACE(tp);
- tp[++n] = (u_int16_t)addr;
- tp[++n] = OVFLPAGE;
- tp[0] = n;
- OFFSET(tp) = off;
- FREESPACE(tp) = free_space - OVFLSIZE;
-
- /*
- * Finally, set the new and old return values. BIG_KEYP contains a
- * pointer to the last page of the big key_data pair. Make sure that
- * big_keyp has no following page (2 elements) or create an empty
- * following page.
- */
-
- ret->newp = np;
- ret->oldp = op;
-
- tp = (u_int16_t *)big_keyp->page;
- big_keyp->flags |= BUF_MOD;
- if (tp[0] > 2) {
- /*
- * There may be either one or two offsets on this page. If
- * there is one, then the overflow page is linked on normally
- * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
- * the second offset and needs to get stuffed in after the
- * next overflow page is added.
- */
- n = tp[4];
- free_space = FREESPACE(tp);
- off = OFFSET(tp);
- tp[0] -= 2;
- FREESPACE(tp) = free_space + OVFLSIZE;
- OFFSET(tp) = off;
- tmpp = __add_ovflpage(hashp, big_keyp);
- if (!tmpp)
- return (-1);
- tp[4] = n;
- } else
- tmpp = big_keyp;
-
- if (change)
- ret->newp = tmpp;
- else
- ret->oldp = tmpp;
- return (0);
-}
diff --git a/1.4/main/db1-ast/hash/hash_buf.c b/1.4/main/db1-ast/hash/hash_buf.c
deleted file mode 100644
index 063dd8229..000000000
--- a/1.4/main/db1-ast/hash/hash_buf.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * PACKAGE: hash
- *
- * DESCRIPTION:
- * Contains buffer management
- *
- * ROUTINES:
- * External
- * __buf_init
- * __get_buf
- * __buf_free
- * __reclaim_buf
- * Internal
- * newbuf
- */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include "../include/db.h"
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static BUFHEAD *newbuf __P((HTAB *, u_int32_t, BUFHEAD *));
-
-/* Unlink B from its place in the lru */
-#define BUF_REMOVE(B) { \
- (B)->prev->next = (B)->next; \
- (B)->next->prev = (B)->prev; \
-}
-
-/* Insert B after P */
-#define BUF_INSERT(B, P) { \
- (B)->next = (P)->next; \
- (B)->prev = (P); \
- (P)->next = (B); \
- (B)->next->prev = (B); \
-}
-
-#define MRU hashp->bufhead.next
-#define LRU hashp->bufhead.prev
-
-#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
-#define LRU_INSERT(B) BUF_INSERT((B), LRU)
-
-/*
- * We are looking for a buffer with address "addr". If prev_bp is NULL, then
- * address is a bucket index. If prev_bp is not NULL, then it points to the
- * page previous to an overflow page that we are trying to find.
- *
- * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
- * be valid. Therefore, you must always verify that its address matches the
- * address you are seeking.
- */
-extern BUFHEAD *
-__get_buf(hashp, addr, prev_bp, newpage)
- HTAB *hashp;
- u_int32_t addr;
- BUFHEAD *prev_bp;
- int newpage; /* If prev_bp set, indicates a new overflow page. */
-{
- register BUFHEAD *bp;
- register u_int32_t is_disk_mask;
- register int is_disk, segment_ndx = 0;
- SEGMENT segp = 0;
-
- is_disk = 0;
- is_disk_mask = 0;
- if (prev_bp) {
- bp = prev_bp->ovfl;
- if (!bp || (bp->addr != addr))
- bp = NULL;
- if (!newpage)
- is_disk = BUF_DISK;
- } else {
- /* Grab buffer out of directory */
- segment_ndx = addr & (hashp->SGSIZE - 1);
-
- /* valid segment ensured by __call_hash() */
- segp = hashp->dir[addr >> hashp->SSHIFT];
-#ifdef DEBUG
- assert(segp != NULL);
-#endif
- bp = PTROF(segp[segment_ndx]);
- is_disk_mask = ISDISK(segp[segment_ndx]);
- is_disk = is_disk_mask || !hashp->new_file;
- }
-
- if (!bp) {
- bp = newbuf(hashp, addr, prev_bp);
- if (!bp ||
- __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
- return (NULL);
- if (!prev_bp)
- segp[segment_ndx] =
- (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
- } else {
- BUF_REMOVE(bp);
- MRU_INSERT(bp);
- }
- return (bp);
-}
-
-/*
- * We need a buffer for this page. Either allocate one, or evict a resident
- * one (if we have as many buffers as we're allowed) and put this one in.
- *
- * If newbuf finds an error (returning NULL), it also sets errno.
- */
-static BUFHEAD *
-newbuf(hashp, addr, prev_bp)
- HTAB *hashp;
- u_int32_t addr;
- BUFHEAD *prev_bp;
-{
- register BUFHEAD *bp; /* The buffer we're going to use */
- register BUFHEAD *xbp; /* Temp pointer */
- register BUFHEAD *next_xbp;
- SEGMENT segp;
- int segment_ndx;
- u_int16_t oaddr, *shortp;
-
- oaddr = 0;
- bp = LRU;
- /*
- * If LRU buffer is pinned, the buffer pool is too small. We need to
- * allocate more buffers.
- */
- if (hashp->nbufs || (bp->flags & BUF_PIN)) {
- /* Allocate a new one */
- if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
- return (NULL);
-#ifdef PURIFY
- memset(bp, 0xff, sizeof(BUFHEAD));
-#endif
- if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
- free(bp);
- return (NULL);
- }
-#ifdef PURIFY
- memset(bp->page, 0xff, hashp->BSIZE);
-#endif
- if (hashp->nbufs)
- hashp->nbufs--;
- } else {
- /* Kick someone out */
- BUF_REMOVE(bp);
- /*
- * If this is an overflow page with addr 0, it's already been
- * flushed back in an overflow chain and initialized.
- */
- if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
- /*
- * Set oaddr before __put_page so that you get it
- * before bytes are swapped.
- */
- shortp = (u_int16_t *)bp->page;
- if (shortp[0])
- oaddr = shortp[shortp[0] - 1];
- if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
- bp->addr, (int)IS_BUCKET(bp->flags), 0))
- return (NULL);
- /*
- * Update the pointer to this page (i.e. invalidate it).
- *
- * If this is a new file (i.e. we created it at open
- * time), make sure that we mark pages which have been
- * written to disk so we retrieve them from disk later,
- * rather than allocating new pages.
- */
- if (IS_BUCKET(bp->flags)) {
- segment_ndx = bp->addr & (hashp->SGSIZE - 1);
- segp = hashp->dir[bp->addr >> hashp->SSHIFT];
-#ifdef DEBUG
- assert(segp != NULL);
-#endif
-
- if (hashp->new_file &&
- ((bp->flags & BUF_MOD) ||
- ISDISK(segp[segment_ndx])))
- segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
- else
- segp[segment_ndx] = NULL;
- }
- /*
- * Since overflow pages can only be access by means of
- * their bucket, free overflow pages associated with
- * this bucket.
- */
- for (xbp = bp; xbp->ovfl;) {
- next_xbp = xbp->ovfl;
- xbp->ovfl = 0;
- xbp = next_xbp;
-
- /* Check that ovfl pointer is up date. */
- if (IS_BUCKET(xbp->flags) ||
- (oaddr != xbp->addr))
- break;
-
- shortp = (u_int16_t *)xbp->page;
- if (shortp[0])
- /* set before __put_page */
- oaddr = shortp[shortp[0] - 1];
- if ((xbp->flags & BUF_MOD) && __put_page(hashp,
- xbp->page, xbp->addr, 0, 0))
- return (NULL);
- xbp->addr = 0;
- xbp->flags = 0;
- BUF_REMOVE(xbp);
- LRU_INSERT(xbp);
- }
- }
- }
-
- /* Now assign this buffer */
- bp->addr = addr;
-#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
- bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
-#endif
- bp->ovfl = NULL;
- if (prev_bp) {
- /*
- * If prev_bp is set, this is an overflow page, hook it in to
- * the buffer overflow links.
- */
-#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
- prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
- (bp ? bp->addr : 0));
-#endif
- prev_bp->ovfl = bp;
- bp->flags = 0;
- } else
- bp->flags = BUF_BUCKET;
- MRU_INSERT(bp);
- return (bp);
-}
-
-extern void
-__buf_init(hashp, nbytes)
- HTAB *hashp;
- int nbytes;
-{
- BUFHEAD *bfp;
- int npages;
-
- bfp = &(hashp->bufhead);
- npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
- npages = MAX(npages, MIN_BUFFERS);
-
- hashp->nbufs = npages;
- bfp->next = bfp;
- bfp->prev = bfp;
- /*
- * This space is calloc'd so these are already null.
- *
- * bfp->ovfl = NULL;
- * bfp->flags = 0;
- * bfp->page = NULL;
- * bfp->addr = 0;
- */
-}
-
-extern int
-__buf_free(hashp, do_free, to_disk)
- HTAB *hashp;
- int do_free, to_disk;
-{
- BUFHEAD *bp;
-
- /* Need to make sure that buffer manager has been initialized */
- if (!LRU)
- return (0);
- for (bp = LRU; bp != &hashp->bufhead;) {
- /* Check that the buffer is valid */
- if (bp->addr || IS_BUCKET(bp->flags)) {
- if (to_disk && (bp->flags & BUF_MOD) &&
- __put_page(hashp, bp->page,
- bp->addr, IS_BUCKET(bp->flags), 0))
- return (-1);
- }
- /* Check if we are freeing stuff */
- if (do_free) {
- if (bp->page)
- free(bp->page);
- BUF_REMOVE(bp);
- free(bp);
- bp = LRU;
- } else
- bp = bp->prev;
- }
- return (0);
-}
-
-extern void
-__reclaim_buf(hashp, bp)
- HTAB *hashp;
- BUFHEAD *bp;
-{
- bp->ovfl = 0;
- bp->addr = 0;
- bp->flags = 0;
- BUF_REMOVE(bp);
- LRU_INSERT(bp);
-}
diff --git a/1.4/main/db1-ast/hash/hash_func.c b/1.4/main/db1-ast/hash/hash_func.c
deleted file mode 100644
index 4d7907b57..000000000
--- a/1.4/main/db1-ast/hash/hash_func.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include "../include/db.h"
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-/* only one of these can be defined */
-/* #define HASH1_EJB 1 */
-/* #define HASH2_PHONG 1 */
-/* #define HASH3_SDBM 1 */
-#define HASH4_TOREK 1
-
-static u_int32_t hashfunc __P((const void *, size_t));
-
-/* Global default hash function */
-u_int32_t (*__default_hash) __P((const void *, size_t)) = hashfunc;
-
-/*
- * HASH FUNCTIONS
- *
- * Assume that we've already split the bucket to which this key hashes,
- * calculate that bucket, and check that in fact we did already split it.
- *
- * This came from ejb's hsearch.
- */
-
-#ifdef HASH1_EJB
-
-#define PRIME1 37
-#define PRIME2 1048583
-
-static u_int32_t
-hashfunc(keyarg, len)
- const void *keyarg;
- register size_t len;
-{
- register const u_char *key;
- register u_int32_t h;
-
- /* Convert string to integer */
- for (key = keyarg, h = 0; len--;)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
- return (h);
-}
-
-#endif
-
-#ifdef HASH2_PHONG
-/*
- * Phong's linear congruential hash
- */
-#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
-
-static u_int32_t
-hashfunc(keyarg, len)
- const void *keyarg;
- size_t len;
-{
- register const u_char *e, *key;
- register u_int32_t h;
- register u_char c;
-
- key = keyarg;
- e = key + len;
- for (h = 0; key != e;) {
- c = *key++;
- if (!c && key > e)
- break;
- dcharhash(h, c);
- }
- return (h);
-}
-#endif
-
-#ifdef HASH3_SDBM
-/*
- * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
- * units. On the first time through the loop we get the "leftover bytes"
- * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
- * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
- * this routine is heavily used enough, it's worth the ugly coding.
- *
- * OZ's original sdbm hash
- */
-static u_int32_t
-hashfunc(keyarg, len)
- const void *keyarg;
- register size_t len;
-{
- register const u_char *key;
- register size_t loop;
- register u_int32_t h;
-
-#define HASHC h = *key++ + 65599 * h
-
- h = 0;
- key = keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASHC;
- /* FALLTHROUGH */
- case 7:
- HASHC;
- /* FALLTHROUGH */
- case 6:
- HASHC;
- /* FALLTHROUGH */
- case 5:
- HASHC;
- /* FALLTHROUGH */
- case 4:
- HASHC;
- /* FALLTHROUGH */
- case 3:
- HASHC;
- /* FALLTHROUGH */
- case 2:
- HASHC;
- /* FALLTHROUGH */
- case 1:
- HASHC;
- } while (--loop);
- }
- }
- return (h);
-}
-#endif
-
-#ifdef HASH4_TOREK
-/* Hash function from Chris Torek. */
-static u_int32_t
-hashfunc(keyarg, len)
- const void *keyarg;
- register size_t len;
-{
- register const u_char *key;
- register size_t loop;
- register u_int32_t h;
-
-#define HASH4a h = (h << 5) - h + *key++;
-#define HASH4b h = (h << 5) + h + *key++;
-#define HASH4 HASH4b
-
- h = 0;
- key = keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASH4;
- /* FALLTHROUGH */
- case 7:
- HASH4;
- /* FALLTHROUGH */
- case 6:
- HASH4;
- /* FALLTHROUGH */
- case 5:
- HASH4;
- /* FALLTHROUGH */
- case 4:
- HASH4;
- /* FALLTHROUGH */
- case 3:
- HASH4;
- /* FALLTHROUGH */
- case 2:
- HASH4;
- /* FALLTHROUGH */
- case 1:
- HASH4;
- } while (--loop);
- }
- }
- return (h);
-}
-#endif
diff --git a/1.4/main/db1-ast/hash/hash_log2.c b/1.4/main/db1-ast/hash/hash_log2.c
deleted file mode 100644
index b86655d47..000000000
--- a/1.4/main/db1-ast/hash/hash_log2.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include "../include/db.h"
-
-u_int32_t __hash_log2 __P((u_int32_t));
-
-u_int32_t
-__hash_log2(num)
- u_int32_t num;
-{
- register u_int32_t i, limit;
-
- limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++);
- return (i);
-}
diff --git a/1.4/main/db1-ast/hash/hash_page.c b/1.4/main/db1-ast/hash/hash_page.c
deleted file mode 100644
index 737b97d32..000000000
--- a/1.4/main/db1-ast/hash/hash_page.c
+++ /dev/null
@@ -1,944 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * PACKAGE: hashing
- *
- * DESCRIPTION:
- * Page manipulation for hashing package.
- *
- * ROUTINES:
- *
- * External
- * __get_page
- * __add_ovflpage
- * Internal
- * overflow_page
- * open_temp
- */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include "../include/db.h"
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static u_int32_t *fetch_bitmap __P((HTAB *, int));
-static u_int32_t first_free __P((u_int32_t));
-static int open_temp __P((HTAB *));
-static u_int16_t overflow_page __P((HTAB *));
-static void putpair __P((char *, const DBT *, const DBT *));
-static void squeeze_key __P((u_int16_t *, const DBT *, const DBT *));
-static int ugly_split
- __P((HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int));
-
-#define PAGE_INIT(P) { \
- ((u_int16_t *)(P))[0] = 0; \
- ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
- ((u_int16_t *)(P))[2] = hashp->BSIZE; \
-}
-
-/*
- * This is called AFTER we have verified that there is room on the page for
- * the pair (PAIRFITS has returned true) so we go right ahead and start moving
- * stuff on.
- */
-static void
-putpair(p, key, val)
- char *p;
- const DBT *key, *val;
-{
- register u_int16_t *bp, n, off;
-
- bp = (u_int16_t *)p;
-
- /* Enter the key first. */
- n = bp[0];
-
- off = OFFSET(bp) - key->size;
- memmove(p + off, key->data, key->size);
- bp[++n] = off;
-
- /* Now the data. */
- off -= val->size;
- memmove(p + off, val->data, val->size);
- bp[++n] = off;
-
- /* Adjust page info. */
- bp[0] = n;
- bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
- bp[n + 2] = off;
-}
-
-/*
- * Returns:
- * 0 OK
- * -1 error
- */
-extern int
-__delpair(hashp, bufp, ndx)
- HTAB *hashp;
- BUFHEAD *bufp;
- register int ndx;
-{
- register u_int16_t *bp, newoff;
- register int n;
- u_int16_t pairlen;
-
- bp = (u_int16_t *)bufp->page;
- n = bp[0];
-
- if (bp[ndx + 1] < REAL_KEY)
- return (__big_delete(hashp, bufp));
- if (ndx != 1)
- newoff = bp[ndx - 1];
- else
- newoff = hashp->BSIZE;
- pairlen = newoff - bp[ndx + 1];
-
- if (ndx != (n - 1)) {
- /* Hard Case -- need to shuffle keys */
- register int i;
- register char *src = bufp->page + (int)OFFSET(bp);
- register char *dst = src + (int)pairlen;
- memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
-
- /* Now adjust the pointers */
- for (i = ndx + 2; i <= n; i += 2) {
- if (bp[i + 1] == OVFLPAGE) {
- bp[i - 2] = bp[i];
- bp[i - 1] = bp[i + 1];
- } else {
- bp[i - 2] = bp[i] + pairlen;
- bp[i - 1] = bp[i + 1] + pairlen;
- }
- }
- }
- /* Finally adjust the page data */
- bp[n] = OFFSET(bp) + pairlen;
- bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
- bp[0] = n - 2;
- hashp->NKEYS--;
-
- bufp->flags |= BUF_MOD;
- return (0);
-}
-/*
- * Returns:
- * 0 ==> OK
- * -1 ==> Error
- */
-extern int
-__split_page(hashp, obucket, nbucket)
- HTAB *hashp;
- u_int32_t obucket, nbucket;
-{
- register BUFHEAD *new_bufp, *old_bufp;
- register u_int16_t *ino;
- register char *np;
- DBT key, val;
- int n, ndx, retval;
- u_int16_t copyto, diff, off, moved;
- char *op;
-
- copyto = (u_int16_t)hashp->BSIZE;
- off = (u_int16_t)hashp->BSIZE;
- old_bufp = __get_buf(hashp, obucket, NULL, 0);
- if (old_bufp == NULL)
- return (-1);
- new_bufp = __get_buf(hashp, nbucket, NULL, 0);
- if (new_bufp == NULL)
- return (-1);
-
- old_bufp->flags |= (BUF_MOD | BUF_PIN);
- new_bufp->flags |= (BUF_MOD | BUF_PIN);
-
- ino = (u_int16_t *)(op = old_bufp->page);
- np = new_bufp->page;
-
- moved = 0;
-
- for (n = 1, ndx = 1; n < ino[0]; n += 2) {
- if (ino[n + 1] < REAL_KEY) {
- retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
- (int)copyto, (int)moved);
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (retval);
-
- }
- key.data = (u_char *)op + ino[n];
- key.size = off - ino[n];
-
- if (__call_hash(hashp, key.data, key.size) == obucket) {
- /* Don't switch page */
- diff = copyto - off;
- if (diff) {
- copyto = ino[n + 1] + diff;
- memmove(op + copyto, op + ino[n + 1],
- off - ino[n + 1]);
- ino[ndx] = copyto + ino[n] - ino[n + 1];
- ino[ndx + 1] = copyto;
- } else
- copyto = ino[n + 1];
- ndx += 2;
- } else {
- /* Switch page */
- val.data = (u_char *)op + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- putpair(np, &key, &val);
- moved += 2;
- }
-
- off = ino[n + 1];
- }
-
- /* Now clean up the page */
- ino[0] -= moved;
- FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
- OFFSET(ino) = copyto;
-
-#ifdef DEBUG3
- (void)fprintf(stderr, "split %d/%d\n",
- ((u_int16_t *)np)[0] / 2,
- ((u_int16_t *)op)[0] / 2);
-#endif
- /* unpin both pages */
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (0);
-}
-
-/*
- * Called when we encounter an overflow or big key/data page during split
- * handling. This is special cased since we have to begin checking whether
- * the key/data pairs fit on their respective pages and because we may need
- * overflow pages for both the old and new pages.
- *
- * The first page might be a page with regular key/data pairs in which case
- * we have a regular overflow condition and just need to go on to the next
- * page or it might be a big key/data pair in which case we need to fix the
- * big key/data pair.
- *
- * Returns:
- * 0 ==> success
- * -1 ==> failure
- */
-static int
-ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
- HTAB *hashp;
- u_int32_t obucket; /* Same as __split_page. */
- BUFHEAD *old_bufp, *new_bufp;
- int copyto; /* First byte on page which contains key/data values. */
- int moved; /* Number of pairs moved to new page. */
-{
- register BUFHEAD *bufp; /* Buffer header for ino */
- register u_int16_t *ino; /* Page keys come off of */
- register u_int16_t *np; /* New page */
- register u_int16_t *op; /* Page keys go on to if they aren't moving */
-
- BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
- DBT key, val;
- SPLIT_RETURN ret;
- u_int16_t n, off, ov_addr, scopyto;
- char *cino; /* Character value of ino */
-
- bufp = old_bufp;
- ino = (u_int16_t *)old_bufp->page;
- np = (u_int16_t *)new_bufp->page;
- op = (u_int16_t *)old_bufp->page;
- last_bfp = NULL;
- scopyto = (u_int16_t)copyto; /* ANSI */
-
- n = ino[0] - 1;
- while (n < ino[0]) {
- if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
- if (__big_split(hashp, old_bufp,
- new_bufp, bufp, bufp->addr, obucket, &ret))
- return (-1);
- old_bufp = ret.oldp;
- if (!old_bufp)
- return (-1);
- op = (u_int16_t *)old_bufp->page;
- new_bufp = ret.newp;
- if (!new_bufp)
- return (-1);
- np = (u_int16_t *)new_bufp->page;
- bufp = ret.nextp;
- if (!bufp)
- return (0);
- cino = (char *)bufp->page;
- ino = (u_int16_t *)cino;
- last_bfp = ret.nextp;
- } else if (ino[n + 1] == OVFLPAGE) {
- ov_addr = ino[n];
- /*
- * Fix up the old page -- the extra 2 are the fields
- * which contained the overflow information.
- */
- ino[0] -= (moved + 2);
- FREESPACE(ino) =
- scopyto - sizeof(u_int16_t) * (ino[0] + 3);
- OFFSET(ino) = scopyto;
-
- bufp = __get_buf(hashp, ov_addr, bufp, 0);
- if (!bufp)
- return (-1);
-
- ino = (u_int16_t *)bufp->page;
- n = 1;
- scopyto = hashp->BSIZE;
- moved = 0;
-
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = bufp;
- }
- /* Move regular sized pairs of there are any */
- off = hashp->BSIZE;
- for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
- cino = (char *)ino;
- key.data = (u_char *)cino + ino[n];
- key.size = off - ino[n];
- val.data = (u_char *)cino + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- off = ino[n + 1];
-
- if (__call_hash(hashp, key.data, key.size) == obucket) {
- /* Keep on old page */
- if (PAIRFITS(op, (&key), (&val)))
- putpair((char *)op, &key, &val);
- else {
- old_bufp =
- __add_ovflpage(hashp, old_bufp);
- if (!old_bufp)
- return (-1);
- op = (u_int16_t *)old_bufp->page;
- putpair((char *)op, &key, &val);
- }
- old_bufp->flags |= BUF_MOD;
- } else {
- /* Move to new page */
- if (PAIRFITS(np, (&key), (&val)))
- putpair((char *)np, &key, &val);
- else {
- new_bufp =
- __add_ovflpage(hashp, new_bufp);
- if (!new_bufp)
- return (-1);
- np = (u_int16_t *)new_bufp->page;
- putpair((char *)np, &key, &val);
- }
- new_bufp->flags |= BUF_MOD;
- }
- }
- }
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- return (0);
-}
-
-/*
- * Add the given pair to the page
- *
- * Returns:
- * 0 ==> OK
- * 1 ==> failure
- */
-extern int
-__addel(hashp, bufp, key, val)
- HTAB *hashp;
- BUFHEAD *bufp;
- const DBT *key, *val;
-{
- register u_int16_t *bp, *sop;
- int do_expand;
-
- bp = (u_int16_t *)bufp->page;
- do_expand = 0;
- while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
- /* Exception case */
- if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
- /* This is the last page of a big key/data pair
- and we need to add another page */
- break;
- else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- } else
- /* Try to squeeze key on this page */
- if (FREESPACE(bp) > PAIRSIZE(key, val)) {
- squeeze_key(bp, key, val);
- return (0);
- } else {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- }
-
- if (PAIRFITS(bp, key, val))
- putpair(bufp->page, key, val);
- else {
- do_expand = 1;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- sop = (u_int16_t *)bufp->page;
-
- if (PAIRFITS(sop, key, val))
- putpair((char *)sop, key, val);
- else
- if (__big_insert(hashp, bufp, key, val))
- return (-1);
- }
- bufp->flags |= BUF_MOD;
- /*
- * If the average number of keys per bucket exceeds the fill factor,
- * expand the table.
- */
- hashp->NKEYS++;
- if (do_expand ||
- (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
- return (__expand_table(hashp));
- return (0);
-}
-
-/*
- *
- * Returns:
- * pointer on success
- * NULL on error
- */
-extern BUFHEAD *
-__add_ovflpage(hashp, bufp)
- HTAB *hashp;
- BUFHEAD *bufp;
-{
- register u_int16_t *sp;
- u_int16_t ndx, ovfl_num;
-#ifdef DEBUG1
- int tmp1, tmp2;
-#endif
- sp = (u_int16_t *)bufp->page;
-
- /* Check if we are dynamically determining the fill factor */
- if (hashp->FFACTOR == DEF_FFACTOR) {
- hashp->FFACTOR = sp[0] >> 1;
- if (hashp->FFACTOR < MIN_FFACTOR)
- hashp->FFACTOR = MIN_FFACTOR;
- }
- bufp->flags |= BUF_MOD;
- ovfl_num = overflow_page(hashp);
-#ifdef DEBUG1
- tmp1 = bufp->addr;
- tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
-#endif
- if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
- return (NULL);
- bufp->ovfl->flags |= BUF_MOD;
-#ifdef DEBUG1
- (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
- tmp1, tmp2, bufp->ovfl->addr);
-#endif
- ndx = sp[0];
- /*
- * Since a pair is allocated on a page only if there's room to add
- * an overflow page, we know that the OVFL information will fit on
- * the page.
- */
- sp[ndx + 4] = OFFSET(sp);
- sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
- sp[ndx + 1] = ovfl_num;
- sp[ndx + 2] = OVFLPAGE;
- sp[0] = ndx + 2;
-#ifdef HASH_STATISTICS
- hash_overflows++;
-#endif
- return (bufp->ovfl);
-}
-
-/*
- * Returns:
- * 0 indicates SUCCESS
- * -1 indicates FAILURE
- */
-extern int
-__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
- HTAB *hashp;
- char *p;
- u_int32_t bucket;
- int is_bucket, is_disk, is_bitmap;
-{
- register int fd, page, size;
- int rsize;
- u_int16_t *bp;
-
- fd = hashp->fp;
- size = hashp->BSIZE;
-
- if ((fd == -1) || !is_disk) {
- PAGE_INIT(p);
- return (0);
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((rsize = read(fd, p, size)) == -1))
- return (-1);
- bp = (u_int16_t *)p;
- if (!rsize)
- bp[0] = 0; /* We hit the EOF, so initialize a new page */
- else
- if (rsize != size) {
- errno = EFTYPE;
- return (-1);
- }
- if (!is_bitmap && !bp[0]) {
- PAGE_INIT(p);
- } else
- if (hashp->LORDER != BYTE_ORDER) {
- register int i, max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- M_16_SWAP(bp[0]);
- max = bp[0] + 2;
- for (i = 1; i <= max; i++)
- M_16_SWAP(bp[i]);
- }
- }
- return (0);
-}
-
-/*
- * Write page p to disk
- *
- * Returns:
- * 0 ==> OK
- * -1 ==>failure
- */
-extern int
-__put_page(hashp, p, bucket, is_bucket, is_bitmap)
- HTAB *hashp;
- char *p;
- u_int32_t bucket;
- int is_bucket, is_bitmap;
-{
- register int fd, page, size;
- int wsize;
-
- size = hashp->BSIZE;
- if ((hashp->fp == -1) && open_temp(hashp))
- return (-1);
- fd = hashp->fp;
-
- if (hashp->LORDER != BYTE_ORDER) {
- register int i;
- register int max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- max = ((u_int16_t *)p)[0] + 2;
- for (i = 0; i <= max; i++)
- M_16_SWAP(((u_int16_t *)p)[i]);
- }
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((wsize = write(fd, p, size)) == -1))
- /* Errno is set */
- return (-1);
- if (wsize != size) {
- errno = EFTYPE;
- return (-1);
- }
- return (0);
-}
-
-#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
-/*
- * Initialize a new bitmap page. Bitmap pages are left in memory
- * once they are read in.
- */
-extern int
-__ibitmap(hashp, pnum, nbits, ndx)
- HTAB *hashp;
- int pnum, nbits, ndx;
-{
- u_int32_t *ip;
- int clearbytes, clearints;
-
- if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
- return (1);
- hashp->nmaps++;
- clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
- clearbytes = clearints << INT_TO_BYTE;
- (void)memset((char *)ip, 0, clearbytes);
- (void)memset(((char *)ip) + clearbytes, 0xFF,
- hashp->BSIZE - clearbytes);
- ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
- SETBIT(ip, 0);
- hashp->BITMAPS[ndx] = (u_int16_t)pnum;
- hashp->mapp[ndx] = ip;
- return (0);
-}
-
-static u_int32_t
-first_free(map)
- u_int32_t map;
-{
- register u_int32_t i, mask;
-
- mask = 0x1;
- for (i = 0; i < BITS_PER_MAP; i++) {
- if (!(mask & map))
- return (i);
- mask = mask << 1;
- }
- return (i);
-}
-
-static u_int16_t
-overflow_page(hashp)
- HTAB *hashp;
-{
- register u_int32_t *freep = 0;
- register int max_free, offset, splitnum;
- u_int16_t addr;
- int bit, first_page, free_bit, free_page, i, in_use_bits, j;
-#ifdef DEBUG2
- int tmp1, tmp2;
-#endif
- splitnum = hashp->OVFL_POINT;
- max_free = hashp->SPARES[splitnum];
-
- free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
- free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- /* Look through all the free maps to find the first free block */
- first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
- for ( i = first_page; i <= free_page; i++ ) {
- if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
- !(freep = fetch_bitmap(hashp, i)))
- return (0);
- if (i == free_page)
- in_use_bits = free_bit;
- else
- in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
-
- if (i == first_page) {
- bit = hashp->LAST_FREED &
- ((hashp->BSIZE << BYTE_SHIFT) - 1);
- j = bit / BITS_PER_MAP;
- bit = bit & ~(BITS_PER_MAP - 1);
- } else {
- bit = 0;
- j = 0;
- }
- for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
- if (freep[j] != ALL_SET)
- goto found;
- }
-
- /* No Free Page Found */
- hashp->LAST_FREED = hashp->SPARES[splitnum];
- hashp->SPARES[splitnum]++;
- offset = hashp->SPARES[splitnum] -
- (splitnum ? hashp->SPARES[splitnum - 1] : 0);
-
-#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 1;
- }
-
- /* Check if we need to allocate a new bitmap page */
- if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
- free_page++;
- if (free_page >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (0);
- }
- /*
- * This is tricky. The 1 indicates that you want the new page
- * allocated with 1 clear bit. Actually, you are going to
- * allocate 2 pages from this map. The first is going to be
- * the map page, the second is the overflow page we were
- * looking for. The init_bitmap routine automatically, sets
- * the first bit of itself to indicate that the bitmap itself
- * is in use. We would explicitly set the second bit, but
- * don't have to if we tell init_bitmap not to leave it clear
- * in the first place.
- */
- if (__ibitmap(hashp,
- (int)OADDR_OF(splitnum, offset), 1, free_page))
- return (0);
- hashp->SPARES[splitnum]++;
-#ifdef DEBUG2
- free_bit = 2;
-#endif
- offset++;
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG,
- sizeof(OVMSG) - 1);
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 0;
- }
- } else {
- /*
- * Free_bit addresses the last used bit. Bump it to address
- * the first available bit.
- */
- free_bit++;
- SETBIT(freep, free_bit);
- }
-
- /* Calculate address of the new overflow page */
- addr = OADDR_OF(splitnum, offset);
-#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, free_bit, free_page);
-#endif
- return (addr);
-
-found:
- bit = bit + first_free(freep[j]);
- SETBIT(freep, bit);
-#ifdef DEBUG2
- tmp1 = bit;
- tmp2 = i;
-#endif
- /*
- * Bits are addressed starting with 0, but overflow pages are addressed
- * beginning at 1. Bit is a bit addressnumber, so we need to increment
- * it to convert it to a page number.
- */
- bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
- if (bit >= hashp->LAST_FREED)
- hashp->LAST_FREED = bit - 1;
-
- /* Calculate the split number for this page */
- for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
- offset = (i ? bit - hashp->SPARES[i - 1] : bit);
- if (offset >= SPLITMASK)
- return (0); /* Out of overflow pages */
- addr = OADDR_OF(i, offset);
-#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, tmp1, tmp2);
-#endif
-
- /* Allocate and return the overflow page */
- return (addr);
-}
-
-/*
- * Mark this overflow page as free.
- */
-extern void
-__free_ovflpage(hashp, obufp)
- HTAB *hashp;
- BUFHEAD *obufp;
-{
- register u_int16_t addr;
- u_int32_t *freep;
- int bit_address, free_page, free_bit;
- u_int16_t ndx;
-
- addr = obufp->addr;
-#ifdef DEBUG1
- (void)fprintf(stderr, "Freeing %d\n", addr);
-#endif
- ndx = (((u_int16_t)addr) >> SPLITSHIFT);
- bit_address =
- (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
- if (bit_address < hashp->LAST_FREED)
- hashp->LAST_FREED = bit_address;
- free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
- free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- if (!(freep = hashp->mapp[free_page]))
- freep = fetch_bitmap(hashp, free_page);
-#ifdef DEBUG
- /*
- * This had better never happen. It means we tried to read a bitmap
- * that has already had overflow pages allocated off it, and we
- * failed to read it from the file.
- */
- if (!freep)
- assert(0);
-#endif
- CLRBIT(freep, free_bit);
-#ifdef DEBUG2
- (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
- obufp->addr, free_bit, free_page);
-#endif
- __reclaim_buf(hashp, obufp);
-}
-
-/*
- * Returns:
- * 0 success
- * -1 failure
- */
-static int
-open_temp(hashp)
- HTAB *hashp;
-{
- sigset_t set, oset;
- static char namestr[] = "_hashXXXXXX";
-
- /* Block signals; make sure file goes away at process exit. */
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((hashp->fp = mkstemp(namestr)) != -1) {
- (void)unlink(namestr);
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
- (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
- return (hashp->fp != -1 ? 0 : -1);
-}
-
-/*
- * We have to know that the key will fit, but the last entry on the page is
- * an overflow pair, so we need to shift things.
- */
-static void
-squeeze_key(sp, key, val)
- u_int16_t *sp;
- const DBT *key, *val;
-{
- register char *p;
- u_int16_t free_space, n, off, pageno;
-
- p = (char *)sp;
- n = sp[0];
- free_space = FREESPACE(sp);
- off = OFFSET(sp);
-
- pageno = sp[n - 1];
- off -= key->size;
- sp[n - 1] = off;
- memmove(p + off, key->data, key->size);
- off -= val->size;
- sp[n] = off;
- memmove(p + off, val->data, val->size);
- sp[0] = n + 2;
- sp[n + 1] = pageno;
- sp[n + 2] = OVFLPAGE;
- FREESPACE(sp) = free_space - PAIRSIZE(key, val);
- OFFSET(sp) = off;
-}
-
-static u_int32_t *
-fetch_bitmap(hashp, ndx)
- HTAB *hashp;
- int ndx;
-{
- if (ndx >= hashp->nmaps)
- return (NULL);
- if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
- return (NULL);
- if (__get_page(hashp,
- (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
- free(hashp->mapp[ndx]);
- return (NULL);
- }
- return (hashp->mapp[ndx]);
-}
-
-#ifdef DEBUG4
-int
-print_chain(addr)
- int addr;
-{
- BUFHEAD *bufp;
- short *bp, oaddr;
-
- (void)fprintf(stderr, "%d ", addr);
- bufp = __get_buf(hashp, addr, NULL, 0);
- bp = (short *)bufp->page;
- while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
- ((bp[0] > 2) && bp[2] < REAL_KEY))) {
- oaddr = bp[bp[0] - 1];
- (void)fprintf(stderr, "%d ", (int)oaddr);
- bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
- bp = (short *)bufp->page;
- }
- (void)fprintf(stderr, "\n");
-}
-#endif
diff --git a/1.4/main/db1-ast/hash/hsearch.c b/1.4/main/db1-ast/hash/hsearch.c
deleted file mode 100644
index 2971f9308..000000000
--- a/1.4/main/db1-ast/hash/hsearch.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hsearch.c 8.4 (Berkeley) 7/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "search.h"
-
-static DB *dbp = NULL;
-static ENTRY retval;
-
-extern int
-hcreate(nel)
- u_int nel;
-{
- HASHINFO info;
-
- info.nelem = nel;
- info.bsize = 256;
- info.ffactor = 8;
- info.cachesize = 0;
- info.hash = NULL;
- info.lorder = 0;
- dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0);
- return ((int)dbp);
-}
-
-extern ENTRY *
-hsearch(item, action)
- ENTRY item;
- ACTION action;
-{
- DBT key, val;
- int status;
-
- if (!dbp)
- return (NULL);
- key.data = (u_char *)item.key;
- key.size = strlen(item.key) + 1;
-
- if (action == ENTER) {
- val.data = (u_char *)item.data;
- val.size = strlen(item.data) + 1;
- status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE);
- if (status)
- return (NULL);
- } else {
- /* FIND */
- status = (dbp->get)(dbp, &key, &val, 0);
- if (status)
- return (NULL);
- else
- item.data = (char *)val.data;
- }
- retval.key = item.key;
- retval.data = item.data;
- return (&retval);
-}
-
-extern void
-hdestroy()
-{
- if (dbp) {
- (void)(dbp->close)(dbp);
- dbp = NULL;
- }
-}
diff --git a/1.4/main/db1-ast/hash/ndbm.c b/1.4/main/db1-ast/hash/ndbm.c
deleted file mode 100644
index d702f737a..000000000
--- a/1.4/main/db1-ast/hash/ndbm.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * This package provides a dbm compatible interface to the new hashing
- * package described in db(3).
- */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <ndbm.h>
-#include "hash.h"
-
-/*
- * Returns:
- * *DBM on success
- * NULL on failure
- */
-extern DBM *
-dbm_open(file, flags, mode)
- const char *file;
- int flags, mode;
-{
- DBM *db;
- HASHINFO info;
- const size_t len = strlen(file) + sizeof (DBM_SUFFIX);
-#ifdef __GNUC__
- char path[len];
-#else
- char *path = malloc(len);
- if (path == NULL)
- return NULL;
-#endif
-
- info.bsize = 4096;
- info.ffactor = 40;
- info.nelem = 1;
- info.cachesize = 0;
- info.hash = NULL;
- info.lorder = 0;
- (void)strncpy(path, file, len - 1);
- (void)strncat(path, DBM_SUFFIX, len - strlen(path) - 1);
- db = (DBM *)__hash_open(path, flags, mode, &info, 0);
-#ifndef __GNUC__
- free(path);
-#endif
- return db;
-}
-
-extern void
-dbm_close(db)
- DBM *db;
-{
- (void)(db->close)(db);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_fetch(db, key)
- DBM *db;
- datum key;
-{
- datum retdata;
- int status;
- DBT dbtkey, dbtretdata;
-
- dbtkey.data = key.dptr;
- dbtkey.size = key.dsize;
- status = (db->get)(db, &dbtkey, &dbtretdata, 0);
- if (status) {
- dbtretdata.data = NULL;
- dbtretdata.size = 0;
- }
- retdata.dptr = dbtretdata.data;
- retdata.dsize = dbtretdata.size;
- return (retdata);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_firstkey(db)
- DBM *db;
-{
- int status;
- datum retkey;
- DBT dbtretkey, dbtretdata;
-
- status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
- if (status)
- dbtretkey.data = NULL;
- retkey.dptr = dbtretkey.data;
- retkey.dsize = dbtretkey.size;
- return (retkey);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_nextkey(db)
- DBM *db;
-{
- int status;
- datum retkey;
- DBT dbtretkey, dbtretdata;
-
- status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
- if (status)
- dbtretkey.data = NULL;
- retkey.dptr = dbtretkey.data;
- retkey.dsize = dbtretkey.size;
- return (retkey);
-}
-/*
- * Returns:
- * 0 on success
- * <0 failure
- */
-extern int
-dbm_delete(db, key)
- DBM *db;
- datum key;
-{
- int status;
- DBT dbtkey;
-
- dbtkey.data = key.dptr;
- dbtkey.size = key.dsize;
- status = (db->del)(db, &dbtkey, 0);
- if (status)
- return (-1);
- else
- return (0);
-}
-
-/*
- * Returns:
- * 0 on success
- * <0 failure
- * 1 if DBM_INSERT and entry exists
- */
-extern int
-dbm_store(db, key, data, flags)
- DBM *db;
- datum key, data;
- int flags;
-{
- DBT dbtkey, dbtdata;
-
- dbtkey.data = key.dptr;
- dbtkey.size = key.dsize;
- dbtdata.data = data.dptr;
- dbtdata.size = data.dsize;
- return ((db->put)(db, &dbtkey, &dbtdata,
- (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
-}
-
-extern int
-dbm_error(db)
- DBM *db;
-{
- HTAB *hp;
-
- hp = (HTAB *)db->internal;
- return (hp->errnum);
-}
-
-extern int
-dbm_clearerr(db)
- DBM *db;
-{
- HTAB *hp;
-
- hp = (HTAB *)db->internal;
- hp->errnum = 0;
- return (0);
-}
-
-extern int
-dbm_dirfno(db)
- DBM *db;
-{
- return(((HTAB *)db->internal)->fp);
-}
diff --git a/1.4/main/db1-ast/hash/page.h b/1.4/main/db1-ast/hash/page.h
deleted file mode 100644
index 0fc0d5a3e..000000000
--- a/1.4/main/db1-ast/hash/page.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)page.h 8.2 (Berkeley) 5/31/94
- */
-
-/*
- * Definitions for hashing page file format.
- */
-
-/*
- * routines dealing with a data page
- *
- * page format:
- * +------------------------------+
- * p | n | keyoff | datoff | keyoff |
- * +------------+--------+--------+
- * | datoff | free | ptr | --> |
- * +--------+---------------------+
- * | F R E E A R E A |
- * +--------------+---------------+
- * | <---- - - - | data |
- * +--------+-----+----+----------+
- * | key | data | key |
- * +--------+----------+----------+
- *
- * Pointer to the free space is always: p[p[0] + 2]
- * Amount of free space on the page is: p[p[0] + 1]
- */
-
-/*
- * How many bytes required for this pair?
- * 2 shorts in the table at the top of the page + room for the
- * key and room for the data
- *
- * We prohibit entering a pair on a page unless there is also room to append
- * an overflow page. The reason for this it that you can get in a situation
- * where a single key/data pair fits on a page, but you can't append an
- * overflow page and later you'd have to split the key/data and handle like
- * a big pair.
- * You might as well do this up front.
- */
-
-#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size)
-#define BIGOVERHEAD (4*sizeof(u_int16_t))
-#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size);
-#define OVFLSIZE (2*sizeof(u_int16_t))
-#define FREESPACE(P) ((P)[(P)[0]+1])
-#define OFFSET(P) ((P)[(P)[0]+2])
-#define PAIRFITS(P,K,D) \
- (((P)[2] >= REAL_KEY) && \
- (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
-#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))
-
-typedef struct {
- BUFHEAD *newp;
- BUFHEAD *oldp;
- BUFHEAD *nextp;
- u_int16_t next_addr;
-} SPLIT_RETURN;
diff --git a/1.4/main/db1-ast/hash/search.h b/1.4/main/db1-ast/hash/search.h
deleted file mode 100644
index 4d3b9143e..000000000
--- a/1.4/main/db1-ast/hash/search.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)search.h 8.1 (Berkeley) 6/4/93
- */
-
-/* Backward compatibility to hsearch interface. */
-typedef struct entry {
- char *key;
- char *data;
-} ENTRY;
-
-typedef enum {
- FIND, ENTER
-} ACTION;
-
-int hcreate __P((unsigned int));
-void hdestroy __P((void));
-ENTRY *hsearch __P((ENTRY, ACTION));
diff --git a/1.4/main/db1-ast/include/circ-queue.h b/1.4/main/db1-ast/include/circ-queue.h
deleted file mode 100644
index 33ba9115b..000000000
--- a/1.4/main/db1-ast/include/circ-queue.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- * $FreeBSD: ports/misc/44bsd-more/files/queue.h,v 1.1 2001/01/06 03:41:36 hoek Exp $
- */
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
-
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for((var) = (head)->cqh_first; \
- (var) != (void *)(head); \
- (var) = (var)->field.cqe_next)
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for((var) = (head)->cqh_last; \
- (var) != (void *)(head); \
- (var) = (var)->field.cqe_prev)
-
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (0)
-
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-
-#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
-
-#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-} while (0)
diff --git a/1.4/main/db1-ast/include/compat.h b/1.4/main/db1-ast/include/compat.h
deleted file mode 100644
index 706e58265..000000000
--- a/1.4/main/db1-ast/include/compat.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Values for building 4.4 BSD db routines in the GNU C library. */
-
-#ifndef _compat_h_
-#define _compat_h_
-
-#include <fcntl.h>
-
-/*
- * If you can't provide lock values in the open(2) call. Note, this
- * allows races to happen.
- */
-#ifndef O_EXLOCK /* 4.4BSD extension. */
-#define O_EXLOCK 0
-#endif
-
-#ifndef O_SHLOCK /* 4.4BSD extension. */
-#define O_SHLOCK 0
-#endif
-
-#include <errno.h>
-
-#ifndef EFTYPE
-#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
-#endif
-
-#include <unistd.h>
-#include <limits.h>
-
-#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */
-#define _POSIX_VDISABLE 0 /* Some systems used 0. */
-#endif
-
-#include <termios.h>
-
-#ifndef TCSASOFT /* 4.4BSD extension. */
-#define TCSASOFT 0
-#endif
-
-#include <sys/param.h>
-
-#ifndef MAX /* Usually found in <sys/param.h>. */
-#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
-#endif
-#ifndef MIN /* Usually found in <sys/param.h>. */
-#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
-#endif
-
-
-#endif /* compat.h */
diff --git a/1.4/main/db1-ast/include/db.h b/1.4/main/db1-ast/include/db.h
deleted file mode 100644
index a58724bdd..000000000
--- a/1.4/main/db1-ast/include/db.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)db.h 8.7 (Berkeley) 6/16/94
- */
-
-#ifndef _DB_H
-#define _DB_H 1
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#include <limits.h>
-
-#ifdef __DBINTERFACE_PRIVATE
-#include <compat.h>
-#endif
-
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#endif
-
-#define RET_ERROR -1 /* Return values. */
-#define RET_SUCCESS 0
-#define RET_SPECIAL 1
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-#if (!defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__APPLE__))
-typedef __signed char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef unsigned char u_int8_t;
-typedef unsigned short u_int16_t;
-typedef unsigned int u_int32_t;
-#ifdef WE_DONT_NEED_QUADS
-typedef long long int64_t;
-typedef unsigned long long u_int64_t;
-#endif
-#endif /* __FreeBSD__ */
-#endif
-
-#ifdef SOLARIS
-#define __P(p) p
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
-typedef u_int32_t pgno_t;
-#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
-typedef u_int16_t indx_t;
-#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
-typedef u_int32_t recno_t;
-
-/* Key/data structure -- a Data-Base Thang. */
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT;
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-
-/*
- * !!!
- * The following flags are included in the dbopen(3) call as part of the
- * open(2) flags. In order to avoid conflicts with the open flags, start
- * at the top of the 16 or 32-bit number space and work our way down. If
- * the open flags were significantly expanded in the future, it could be
- * a problem. Wish I'd left another flags word in the dbopen call.
- *
- * !!!
- * None of this stuff is implemented yet. The only reason that it's here
- * is so that the access methods can skip copying the key/data pair when
- * the DB_LOCK flag isn't set.
- */
-#if UINT_MAX > 65535
-#define DB_LOCK 0x20000000 /* Do locking. */
-#define DB_SHMEM 0x40000000 /* Use shared memory. */
-#define DB_TXN 0x80000000 /* Do transactions. */
-#else
-#define DB_LOCK 0x2000 /* Do locking. */
-#define DB_SHMEM 0x4000 /* Use shared memory. */
-#define DB_TXN 0x8000 /* Do transactions. */
-#endif
-
-/* Access method description structure. */
-typedef struct __db {
- DBTYPE type; /* Underlying db type. */
- int (*close) __P((struct __db *));
- int (*del) __P((const struct __db *, const DBT *, u_int));
- int (*get) __P((const struct __db *, const DBT *, DBT *, u_int));
- int (*put) __P((const struct __db *, DBT *, const DBT *, u_int));
- int (*seq) __P((const struct __db *, DBT *, DBT *, u_int));
- int (*sync) __P((const struct __db *, u_int));
- void *internal; /* Access method private. */
- int (*fd) __P((const struct __db *));
-} DB;
-
-#define BTREEMAGIC 0x053162
-#define BTREEVERSION 3
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_long flags;
- u_int cachesize; /* bytes to cache */
- int maxkeypage; /* maximum keys per page */
- int minkeypage; /* minimum keys per page */
- u_int psize; /* page size */
- int (*compare) /* comparison function */
- __P((const DBT *, const DBT *));
- size_t (*prefix) /* prefix function */
- __P((const DBT *, const DBT *));
- int lorder; /* byte order */
-} BTREEINFO;
-
-#define HASHMAGIC 0x061561
-#define HASHVERSION 2
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- u_int bsize; /* bucket size */
- u_int ffactor; /* fill factor */
- u_int nelem; /* number of elements */
- u_int cachesize; /* bytes to cache */
- u_int32_t /* hash function */
- (*hash) __P((const void *, size_t));
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_long flags;
- u_int cachesize; /* bytes to cache */
- u_int psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-
-#ifdef __DBINTERFACE_PRIVATE
-/*
- * Little endian <==> big endian 32-bit swap macros.
- * M_32_SWAP swap a memory location
- * P_32_SWAP swap a referenced memory location
- * P_32_COPY swap from one location to another
- */
-#define M_32_SWAP(a) { \
- u_int32_t _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[3]; \
- ((char *)&a)[1] = ((char *)&_tmp)[2]; \
- ((char *)&a)[2] = ((char *)&_tmp)[1]; \
- ((char *)&a)[3] = ((char *)&_tmp)[0]; \
-}
-#define P_32_SWAP(a) { \
- u_int32_t _tmp = *(u_int32_t *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[3]; \
- ((char *)a)[1] = ((char *)&_tmp)[2]; \
- ((char *)a)[2] = ((char *)&_tmp)[1]; \
- ((char *)a)[3] = ((char *)&_tmp)[0]; \
-}
-#define P_32_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[3]; \
- ((char *)&(b))[1] = ((char *)&(a))[2]; \
- ((char *)&(b))[2] = ((char *)&(a))[1]; \
- ((char *)&(b))[3] = ((char *)&(a))[0]; \
-}
-
-/*
- * Little endian <==> big endian 16-bit swap macros.
- * M_16_SWAP swap a memory location
- * P_16_SWAP swap a referenced memory location
- * P_16_COPY swap from one location to another
- */
-#define M_16_SWAP(a) { \
- u_int16_t _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[1]; \
- ((char *)&a)[1] = ((char *)&_tmp)[0]; \
-}
-#define P_16_SWAP(a) { \
- u_int16_t _tmp = *(u_int16_t *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[1]; \
- ((char *)a)[1] = ((char *)&_tmp)[0]; \
-}
-#define P_16_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[1]; \
- ((char *)&(b))[1] = ((char *)&(a))[0]; \
-}
-#endif
-
-__BEGIN_DECLS
-DB *__dbopen __P((const char *, int, int, DBTYPE, const void *));
-DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
-
-#ifdef __DBINTERFACE_PRIVATE
-DB *__bt_open __P((const char *, int, int, const BTREEINFO *, int));
-DB *__hash_open __P((const char *, int, int, const HASHINFO *, int));
-DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int));
-void __dbpanic __P((DB *dbp));
-#endif
-__END_DECLS
-
-#endif /* db.h */
diff --git a/1.4/main/db1-ast/include/mpool.h b/1.4/main/db1-ast/include/mpool.h
deleted file mode 100644
index 0cfc5741c..000000000
--- a/1.4/main/db1-ast/include/mpool.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)mpool.h 8.2 (Berkeley) 7/14/94
- */
-
-#ifndef _MPOOL_H
-#define _MPOOL_H 1
-
-#include <sys/queue.h>
-#ifndef CIRCLEQ_HEAD
-#include <circ-queue.h>
-#endif
-
-/*
- * The memory pool scheme is a simple one. Each in-memory page is referenced
- * by a bucket which is threaded in up to two of three ways. All active pages
- * are threaded on a hash chain (hashed by page number) and an lru chain.
- * Inactive pages are threaded on a free chain. Each reference to a memory
- * pool is handed an opaque MPOOL cookie which stores all of this information.
- */
-#define HASHSIZE 128
-#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)
-
-/* The BKT structures are the elements of the queues. */
-typedef struct _bkt {
- CIRCLEQ_ENTRY(_bkt) hq; /* hash queue */
- CIRCLEQ_ENTRY(_bkt) q; /* lru queue */
- void *page; /* page */
- pgno_t pgno; /* page number */
-
-#define MPOOL_DIRTY 0x01 /* page needs to be written */
-#define MPOOL_PINNED 0x02 /* page is pinned into memory */
- u_int8_t flags; /* flags */
-} BKT;
-
-typedef struct MPOOL {
- CIRCLEQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */
- /* hash queue array */
- CIRCLEQ_HEAD(_hqh, _bkt) hqh[HASHSIZE];
- pgno_t curcache; /* current number of cached pages */
- pgno_t maxcache; /* max number of cached pages */
- pgno_t npages; /* number of pages in the file */
- u_long pagesize; /* file page size */
- int fd; /* file descriptor */
- /* page in conversion routine */
- void (*pgin) __P((void *, pgno_t, void *));
- /* page out conversion routine */
- void (*pgout) __P((void *, pgno_t, void *));
- void *pgcookie; /* cookie for page in/out routines */
-#ifdef STATISTICS
- u_long cachehit;
- u_long cachemiss;
- u_long pagealloc;
- u_long pageflush;
- u_long pageget;
- u_long pagenew;
- u_long pageput;
- u_long pageread;
- u_long pagewrite;
-#endif
-} MPOOL;
-
-__BEGIN_DECLS
-MPOOL *__mpool_open __P((void *, int, pgno_t, pgno_t));
-MPOOL *mpool_open __P((void *, int, pgno_t, pgno_t));
-void __mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
- void (*)(void *, pgno_t, void *), void *));
-void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
- void (*)(void *, pgno_t, void *), void *));
-void *__mpool_new __P((MPOOL *, pgno_t *));
-void *mpool_new __P((MPOOL *, pgno_t *));
-void *__mpool_get __P((MPOOL *, pgno_t, u_int));
-void *mpool_get __P((MPOOL *, pgno_t, u_int));
-int __mpool_put __P((MPOOL *, void *, u_int));
-int mpool_put __P((MPOOL *, void *, u_int));
-int __mpool_sync __P((MPOOL *));
-int mpool_sync __P((MPOOL *));
-int __mpool_close __P((MPOOL *));
-int mpool_close __P((MPOOL *));
-#ifdef STATISTICS
-void mpool_stat __P((MPOOL *));
-#endif
-__END_DECLS
-
-#endif /* mpool.h */
diff --git a/1.4/main/db1-ast/include/ndbm.h b/1.4/main/db1-ast/include/ndbm.h
deleted file mode 100644
index d2079b0a5..000000000
--- a/1.4/main/db1-ast/include/ndbm.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ndbm.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _NDBM_H
-#define _NDBM_H 1
-
-#include "db.h"
-
-/* Map dbm interface onto db(3). */
-#define DBM_RDONLY O_RDONLY
-
-/* Flags to dbm_store(). */
-#define DBM_INSERT 0
-#define DBM_REPLACE 1
-
-/*
- * The db(3) support for ndbm(3) always appends this suffix to the
- * file name to avoid overwriting the user's original database.
- */
-#define DBM_SUFFIX ".db"
-
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-
-typedef DB DBM;
-#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
-
-__BEGIN_DECLS
-void dbm_close __P((DBM *));
-int dbm_delete __P((DBM *, datum));
-datum dbm_fetch __P((DBM *, datum));
-datum dbm_firstkey __P((DBM *));
-long dbm_forder __P((DBM *, datum));
-datum dbm_nextkey __P((DBM *));
-DBM *dbm_open __P((const char *, int, int));
-int dbm_store __P((DBM *, datum, datum, int));
-int dbm_dirfno __P((DBM *));
-int dbm_error __P((DBM *));
-int dbm_clearerr __P((DBM *));
-__END_DECLS
-
-#endif /* ndbm.h */
diff --git a/1.4/main/db1-ast/libdb.map b/1.4/main/db1-ast/libdb.map
deleted file mode 100644
index 87e34c430..000000000
--- a/1.4/main/db1-ast/libdb.map
+++ /dev/null
@@ -1,11 +0,0 @@
-GLIBC_2.0 {
- global:
- # the real DB entry point.
- dbopen; __dbopen;
-
- # The compatibility functions.
- dbm_clearerr; dbm_close; dbm_delete; dbm_dirfno; dbm_error;
- dbm_fetch; dbm_firstkey; dbm_nextkey; dbm_open; dbm_store;
- local:
- *;
-};
diff --git a/1.4/main/db1-ast/mpool/README b/1.4/main/db1-ast/mpool/README
deleted file mode 100644
index 0f01fbcdb..000000000
--- a/1.4/main/db1-ast/mpool/README
+++ /dev/null
@@ -1,7 +0,0 @@
-# @(#)README 8.1 (Berkeley) 6/4/93
-
-These are the current memory pool routines.
-They aren't ready for prime time, yet, and
-the interface is expected to change.
-
---keith
diff --git a/1.4/main/db1-ast/mpool/mpool.c b/1.4/main/db1-ast/mpool/mpool.c
deleted file mode 100644
index b5b7c86d6..000000000
--- a/1.4/main/db1-ast/mpool/mpool.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "../include/db.h"
-
-#define __MPOOLINTERFACE_PRIVATE
-#include <mpool.h>
-
-#undef __APPLE__
-
-#ifndef __APPLE__
-#define mpool_open __mpool_open
-#define mpool_filter __mpool_filter
-#define mpool_new __mpool_new
-#define mpool_get __mpool_get
-#define mpool_put __mpool_put
-#define mpool_sync __mpool_sync
-#define mpool_close __mpool_close
-#endif
-
-static BKT *mpool_bkt __P((MPOOL *));
-static BKT *mpool_look __P((MPOOL *, pgno_t));
-static int mpool_write __P((MPOOL *, BKT *));
-
-/*
- * mpool_open --
- * Initialize a memory pool.
- */
-MPOOL *
-mpool_open(key, fd, pagesize, maxcache)
- void *key;
- int fd;
- pgno_t pagesize, maxcache;
-{
- struct stat sb;
- MPOOL *mp;
- int entry;
-
- /*
- * Get information about the file.
- *
- * XXX
- * We don't currently handle pipes, although we should.
- */
- if (fstat(fd, &sb))
- return (NULL);
- if (!S_ISREG(sb.st_mode)) {
- errno = ESPIPE;
- return (NULL);
- }
-
- /* Allocate and initialize the MPOOL cookie. */
- if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
- return (NULL);
- CIRCLEQ_INIT(&mp->lqh);
- for (entry = 0; entry < HASHSIZE; ++entry)
- CIRCLEQ_INIT(&mp->hqh[entry]);
- mp->maxcache = maxcache;
- mp->npages = sb.st_size / pagesize;
- mp->pagesize = pagesize;
- mp->fd = fd;
- return (mp);
-}
-
-/*
- * mpool_filter --
- * Initialize input/output filters.
- */
-void
-mpool_filter(mp, pgin, pgout, pgcookie)
- MPOOL *mp;
- void (*pgin) __P((void *, pgno_t, void *));
- void (*pgout) __P((void *, pgno_t, void *));
- void *pgcookie;
-{
- mp->pgin = pgin;
- mp->pgout = pgout;
- mp->pgcookie = pgcookie;
-}
-
-/*
- * mpool_new --
- * Get a new page of memory.
- */
-void *
-mpool_new(mp, pgnoaddr)
- MPOOL *mp;
- pgno_t *pgnoaddr;
-{
- struct _hqh *head;
- BKT *bp;
-
- if (mp->npages == MAX_PAGE_NUMBER) {
- (void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
- abort();
- }
-#ifdef STATISTICS
- ++mp->pagenew;
-#endif
- /*
- * Get a BKT from the cache. Assign a new page number, attach
- * it to the head of the hash chain, the tail of the lru chain,
- * and return.
- */
- if ((bp = mpool_bkt(mp)) == NULL)
- return (NULL);
- *pgnoaddr = bp->pgno = mp->npages++;
- bp->flags = MPOOL_PINNED;
-
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
- return (bp->page);
-}
-
-/*
- * mpool_get
- * Get a page.
- */
-void *
-mpool_get(mp, pgno, flags)
- MPOOL *mp;
- pgno_t pgno;
- u_int flags; /* XXX not used? */
-{
- struct _hqh *head;
- BKT *bp;
- off_t off;
- int nr;
-
- /* Check for attempt to retrieve a non-existent page. */
- if (pgno >= mp->npages) {
- errno = EINVAL;
- return (NULL);
- }
-
-#ifdef STATISTICS
- ++mp->pageget;
-#endif
-
- /* Check for a page that is cached. */
- if ((bp = mpool_look(mp, pgno)) != NULL) {
-#ifdef DEBUG
- if (bp->flags & MPOOL_PINNED) {
- (void)fprintf(stderr,
- "mpool_get: page %d already pinned\n", bp->pgno);
- abort();
- }
-#endif
- /*
- * Move the page to the head of the hash chain and the tail
- * of the lru chain.
- */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
-
- /* Return a pinned page. */
- bp->flags |= MPOOL_PINNED;
- return (bp->page);
- }
-
- /* Get a page from the cache. */
- if ((bp = mpool_bkt(mp)) == NULL)
- return (NULL);
-
- /* Read in the contents. */
-#ifdef STATISTICS
- ++mp->pageread;
-#endif
- off = mp->pagesize * pgno;
- if (lseek(mp->fd, off, SEEK_SET) != off)
- return (NULL);
- if ((u_long) (nr = read(mp->fd, bp->page, mp->pagesize))
- != mp->pagesize) {
- if (nr >= 0)
- errno = EFTYPE;
- return (NULL);
- }
-
- /* Set the page number, pin the page. */
- bp->pgno = pgno;
- bp->flags = MPOOL_PINNED;
-
- /*
- * Add the page to the head of the hash chain and the tail
- * of the lru chain.
- */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
-
- /* Run through the user's filter. */
- if (mp->pgin != NULL)
- (mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
-
- return (bp->page);
-}
-
-/*
- * mpool_put
- * Return a page.
- */
-int
-mpool_put(mp, page, flags)
- MPOOL *mp;
- void *page;
- u_int flags;
-{
- BKT *bp;
-
-#ifdef STATISTICS
- ++mp->pageput;
-#endif
- bp = (BKT *)((char *)page - sizeof(BKT));
-#ifdef DEBUG
- if (!(bp->flags & MPOOL_PINNED)) {
- (void)fprintf(stderr,
- "mpool_put: page %d not pinned\n", bp->pgno);
- abort();
- }
-#endif
- bp->flags &= ~MPOOL_PINNED;
- bp->flags |= flags & MPOOL_DIRTY;
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_close
- * Close the buffer pool.
- */
-int
-mpool_close(mp)
- MPOOL *mp;
-{
- BKT *bp;
-
- /* Free up any space allocated to the lru pages. */
- while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
- CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
- free(bp);
- }
-
- /* Free the MPOOL cookie. */
- free(mp);
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_sync
- * Sync the pool to disk.
- */
-int
-mpool_sync(mp)
- MPOOL *mp;
-{
- BKT *bp;
-
- /* Walk the lru chain, flushing any dirty pages to disk. */
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
- if (bp->flags & MPOOL_DIRTY &&
- mpool_write(mp, bp) == RET_ERROR)
- return (RET_ERROR);
-
- /* Sync the file descriptor. */
- return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
-}
-
-#define __APPLE__
-
-#ifndef __APPLE__
-#undef mpool_open
-#undef mpool_filter
-#undef mpool_new
-#undef mpool_get
-#undef mpool_put
-#undef mpool_close
-#undef mpool_sync
-
-#define weak_alias(original, alias) \
- asm (".weak " #alias "\n" #alias " = " #original);
-weak_alias (__mpool_open, mpool_open)
-weak_alias (__mpool_filter, mpool_filter)
-weak_alias (__mpool_new, mpool_new)
-weak_alias (__mpool_get, mpool_get)
-weak_alias (__mpool_put, mpool_put)
-weak_alias (__mpool_close, mpool_close)
-weak_alias (__mpool_sync, mpool_sync)
-#endif
-
-/*
- * mpool_bkt
- * Get a page from the cache (or create one).
- */
-static BKT *
-mpool_bkt(mp)
- MPOOL *mp;
-{
- struct _hqh *head;
- BKT *bp;
-
- /* If under the max cached, always create a new page. */
- if (mp->curcache < mp->maxcache)
- goto new;
-
- /*
- * If the cache is max'd out, walk the lru list for a buffer we
- * can flush. If we find one, write it (if necessary) and take it
- * off any lists. If we don't find anything we grow the cache anyway.
- * The cache never shrinks.
- */
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
- if (!(bp->flags & MPOOL_PINNED)) {
- /* Flush if dirty. */
- if (bp->flags & MPOOL_DIRTY &&
- mpool_write(mp, bp) == RET_ERROR)
- return (NULL);
-#ifdef STATISTICS
- ++mp->pageflush;
-#endif
- /* Remove from the hash and lru queues. */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
-#ifdef DEBUG
- { void *spage;
- spage = bp->page;
- memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
- bp->page = spage;
- }
-#endif
- return (bp);
- }
-
-new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
- return (NULL);
-#ifdef STATISTICS
- ++mp->pagealloc;
-#endif
-#if defined(DEBUG) || defined(PURIFY)
- memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
-#endif
- bp->page = (char *)bp + sizeof(BKT);
- ++mp->curcache;
- return (bp);
-}
-
-/*
- * mpool_write
- * Write a page to disk.
- */
-static int
-mpool_write(mp, bp)
- MPOOL *mp;
- BKT *bp;
-{
- off_t off;
-
-#ifdef STATISTICS
- ++mp->pagewrite;
-#endif
-
- /* Run through the user's filter. */
- if (mp->pgout)
- (mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
-
- off = mp->pagesize * bp->pgno;
- if (lseek(mp->fd, off, SEEK_SET) != off)
- return (RET_ERROR);
- if ((u_long) write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
- return (RET_ERROR);
-
- bp->flags &= ~MPOOL_DIRTY;
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_look
- * Lookup a page in the cache.
- */
-static BKT *
-mpool_look(mp, pgno)
- MPOOL *mp;
- pgno_t pgno;
-{
- struct _hqh *head;
- BKT *bp;
-
- head = &mp->hqh[HASHKEY(pgno)];
- for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
- if (bp->pgno == pgno) {
-#ifdef STATISTICS
- ++mp->cachehit;
-#endif
- return (bp);
- }
-#ifdef STATISTICS
- ++mp->cachemiss;
-#endif
- return (NULL);
-}
-
-#ifdef STATISTICS
-/*
- * mpool_stat
- * Print out cache statistics.
- */
-void
-mpool_stat(mp)
- MPOOL *mp;
-{
- BKT *bp;
- int cnt;
- char *sep;
-
- (void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
- (void)fprintf(stderr,
- "page size %lu, cacheing %lu pages of %lu page max cache\n",
- mp->pagesize, mp->curcache, mp->maxcache);
- (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
- mp->pageput, mp->pageget, mp->pagenew);
- (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
- mp->pagealloc, mp->pageflush);
- if (mp->cachehit + mp->cachemiss)
- (void)fprintf(stderr,
- "%.0f%% cache hit rate (%lu hits, %lu misses)\n",
- ((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
- * 100, mp->cachehit, mp->cachemiss);
- (void)fprintf(stderr, "%lu page reads, %lu page writes\n",
- mp->pageread, mp->pagewrite);
-
- sep = "";
- cnt = 0;
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next) {
- (void)fprintf(stderr, "%s%d", sep, bp->pgno);
- if (bp->flags & MPOOL_DIRTY)
- (void)fprintf(stderr, "d");
- if (bp->flags & MPOOL_PINNED)
- (void)fprintf(stderr, "P");
- if (++cnt == 10) {
- sep = "\n";
- cnt = 0;
- } else
- sep = ", ";
-
- }
- (void)fprintf(stderr, "\n");
-}
-#endif
diff --git a/1.4/main/db1-ast/recno/extern.h b/1.4/main/db1-ast/recno/extern.h
deleted file mode 100644
index feed43445..000000000
--- a/1.4/main/db1-ast/recno/extern.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.3 (Berkeley) 6/4/94
- */
-
-#include "../btree/extern.h"
-
-int __rec_close __P((DB *));
-int __rec_delete __P((const DB *, const DBT *, u_int));
-int __rec_dleaf __P((BTREE *, PAGE *, u_int32_t));
-int __rec_fd __P((const DB *));
-int __rec_fmap __P((BTREE *, recno_t));
-int __rec_fout __P((BTREE *));
-int __rec_fpipe __P((BTREE *, recno_t));
-int __rec_get __P((const DB *, const DBT *, DBT *, u_int));
-int __rec_iput __P((BTREE *, recno_t, const DBT *, u_int));
-int __rec_put __P((const DB *dbp, DBT *, const DBT *, u_int));
-int __rec_ret __P((BTREE *, EPG *, recno_t, DBT *, DBT *));
-EPG *__rec_search __P((BTREE *, recno_t, enum SRCHOP));
-int __rec_seq __P((const DB *, DBT *, DBT *, u_int));
-int __rec_sync __P((const DB *, u_int));
-int __rec_vmap __P((BTREE *, recno_t));
-int __rec_vout __P((BTREE *));
-int __rec_vpipe __P((BTREE *, recno_t));
diff --git a/1.4/main/db1-ast/recno/rec_close.c b/1.4/main/db1-ast/recno/rec_close.c
deleted file mode 100644
index 20b00f52c..000000000
--- a/1.4/main/db1-ast/recno/rec_close.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-/*
- * __REC_CLOSE -- Close a recno tree.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_close(dbp)
- DB *dbp;
-{
- BTREE *t;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- if (__rec_sync(dbp, 0) == RET_ERROR)
- return (RET_ERROR);
-
- /* Committed to closing. */
- status = RET_SUCCESS;
- if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
- status = RET_ERROR;
-
- if (!F_ISSET(t, R_INMEM)) {
- if (F_ISSET(t, R_CLOSEFP)) {
- if (fclose(t->bt_rfp))
- status = RET_ERROR;
- } else
- if (close(t->bt_rfd))
- status = RET_ERROR;
- }
-
- if (__bt_close(dbp) == RET_ERROR)
- status = RET_ERROR;
-
- return (status);
-}
-
-/*
- * __REC_SYNC -- sync the recno tree to disk.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_sync(dbp, flags)
- const DB *dbp;
- u_int flags;
-{
- struct iovec iov[2];
- BTREE *t;
- DBT data, key;
- off_t off;
- recno_t scursor, trec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- if (flags == R_RECNOSYNC)
- return (__bt_sync(dbp, 0));
-
- if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
- return (RET_SUCCESS);
-
- /* Read any remaining records into the tree. */
- if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- return (RET_ERROR);
-
- /* Rewind the file descriptor. */
- if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
- return (RET_ERROR);
-
- /* Save the cursor. */
- scursor = t->bt_cursor.rcursor;
-
- key.size = sizeof(recno_t);
- key.data = &trec;
-
- if (F_ISSET(t, R_FIXLEN)) {
- /*
- * We assume that fixed length records are all fixed length.
- * Any that aren't are either EINVAL'd or corrected by the
- * record put code.
- */
- status = (dbp->seq)(dbp, &key, &data, R_FIRST);
- while (status == RET_SUCCESS) {
- if ((size_t) write(t->bt_rfd, data.data, data.size) != data.size)
- return (RET_ERROR);
- status = (dbp->seq)(dbp, &key, &data, R_NEXT);
- }
- } else {
- iov[1].iov_base = &t->bt_bval;
- iov[1].iov_len = 1;
-
- status = (dbp->seq)(dbp, &key, &data, R_FIRST);
- while (status == RET_SUCCESS) {
- iov[0].iov_base = data.data;
- iov[0].iov_len = data.size;
- if ((size_t) writev(t->bt_rfd, iov, 2) != data.size + 1)
- return (RET_ERROR);
- status = (dbp->seq)(dbp, &key, &data, R_NEXT);
- }
- }
-
- /* Restore the cursor. */
- t->bt_cursor.rcursor = scursor;
-
- if (status == RET_ERROR)
- return (RET_ERROR);
- if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
- return (RET_ERROR);
- if (ftruncate(t->bt_rfd, off))
- return (RET_ERROR);
- F_CLR(t, R_MODIFIED);
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/recno/rec_delete.c b/1.4/main/db1-ast/recno/rec_delete.c
deleted file mode 100644
index fc2047226..000000000
--- a/1.4/main/db1-ast/recno/rec_delete.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-static int rec_rdelete __P((BTREE *, recno_t));
-
-/*
- * __REC_DELETE -- Delete the item(s) referenced by a key.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to delete
- * flags: R_CURSOR if deleting what the cursor references
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__rec_delete(dbp, key, flags)
- const DB *dbp;
- const DBT *key;
- u_int flags;
-{
- BTREE *t;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- switch(flags) {
- case 0:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- if (nrec > t->bt_nrecs)
- return (RET_SPECIAL);
- --nrec;
- status = rec_rdelete(t, nrec);
- break;
- case R_CURSOR:
- if (!F_ISSET(&t->bt_cursor, CURS_INIT))
- goto einval;
- if (t->bt_nrecs == 0)
- return (RET_SPECIAL);
- status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
- if (status == RET_SUCCESS)
- --t->bt_cursor.rcursor;
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (status == RET_SUCCESS)
- F_SET(t, B_MODIFIED | R_MODIFIED);
- return (status);
-}
-
-/*
- * REC_RDELETE -- Delete the data matching the specified key.
- *
- * Parameters:
- * tree: tree
- * nrec: record to delete
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-static int
-rec_rdelete(t, nrec)
- BTREE *t;
- recno_t nrec;
-{
- EPG *e;
- PAGE *h;
- int status;
-
- /* Find the record; __rec_search pins the page. */
- if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
- return (RET_ERROR);
-
- /* Delete the record. */
- h = e->page;
- status = __rec_dleaf(t, h, e->index);
- if (status != RET_SUCCESS) {
- mpool_put(t->bt_mp, h, 0);
- return (status);
- }
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_DLEAF -- Delete a single record from a recno leaf page.
- *
- * Parameters:
- * t: tree
- * index: index on current page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_dleaf(t, h, index)
- BTREE *t;
- PAGE *h;
- u_int32_t index;
-{
- RLEAF *rl;
- indx_t *ip, cnt, offset;
- u_int32_t nbytes;
- char *from;
- void *to;
-
- /*
- * Delete a record from a recno leaf page. Internal records are never
- * deleted from internal pages, regardless of the records that caused
- * them to be added being deleted. Pages made empty by deletion are
- * not reclaimed. They are, however, made available for reuse.
- *
- * Pack the remaining entries at the end of the page, shift the indices
- * down, overwriting the deleted record and its index. If the record
- * uses overflow pages, make them available for reuse.
- */
- to = rl = GETRLEAF(h, index);
- if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
- return (RET_ERROR);
- nbytes = NRLEAF(rl);
-
- /*
- * Compress the key/data pairs. Compress and adjust the [BR]LEAF
- * offsets. Reset the headers.
- */
- from = (char *)h + h->upper;
- memmove(from + nbytes, from, (char *)to - from);
- h->upper += nbytes;
-
- offset = h->linp[index];
- for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nbytes;
- for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
- h->lower -= sizeof(indx_t);
- --t->bt_nrecs;
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/recno/rec_get.c b/1.4/main/db1-ast/recno/rec_get.c
deleted file mode 100644
index 7038cc81a..000000000
--- a/1.4/main/db1-ast/recno/rec_get.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-/*
- * __REC_GET -- Get a record from the btree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to find
- * data: data to return
- * flag: currently unused
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__rec_get(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Get currently doesn't take any flags, and keys of 0 are illegal. */
- if (flags || (nrec = *(recno_t *)key->data) == 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * If we haven't seen this record yet, try to find it in the
- * original file.
- */
- if (nrec > t->bt_nrecs) {
- if (F_ISSET(t, R_EOF | R_INMEM))
- return (RET_SPECIAL);
- if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
- return (status);
- }
-
- --nrec;
- if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
- return (RET_ERROR);
-
- status = __rec_ret(t, e, 0, NULL, data);
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
-
-/*
- * __REC_FPIPE -- Get fixed length records from a pipe.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_fpipe(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- size_t len;
- int ch;
- u_char *p;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- realloc(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- data.data = t->bt_rdata.data;
- data.size = t->bt_reclen;
-
- for (nrec = t->bt_nrecs; nrec < top;) {
- len = t->bt_reclen;
- for (p = t->bt_rdata.data;; *p++ = ch)
- if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
- if (ch != EOF)
- *p = ch;
- if (len != 0)
- memset(p, t->bt_bval, len);
- if (__rec_iput(t,
- nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- ++nrec;
- break;
- }
- if (ch == EOF)
- break;
- }
- if (nrec < top) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_VPIPE -- Get variable length records from a pipe.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_vpipe(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- indx_t len;
- size_t sz;
- int bval, ch;
- u_char *p;
-
- bval = t->bt_bval;
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- for (p = t->bt_rdata.data,
- sz = t->bt_rdata.size;; *p++ = ch, --sz) {
- if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
- data.data = t->bt_rdata.data;
- data.size = p - (u_char *)t->bt_rdata.data;
- if (ch == EOF && data.size == 0)
- break;
- if (__rec_iput(t, nrec, &data, 0)
- != RET_SUCCESS)
- return (RET_ERROR);
- break;
- }
- if (sz == 0) {
- len = p - (u_char *)t->bt_rdata.data;
- t->bt_rdata.size += (sz = 256);
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_rdata.size) :
- realloc(t->bt_rdata.data, t->bt_rdata.size);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- p = (u_char *)t->bt_rdata.data + len;
- }
- }
- if (ch == EOF)
- break;
- }
- if (nrec < top) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_FMAP -- Get fixed length records from a file.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_fmap(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- u_char *sp, *ep, *p;
- size_t len;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- realloc(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- data.data = t->bt_rdata.data;
- data.size = t->bt_reclen;
-
- sp = (u_char *)t->bt_cmap;
- ep = (u_char *)t->bt_emap;
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- if (sp >= ep) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- len = t->bt_reclen;
- for (p = t->bt_rdata.data;
- sp < ep && len > 0; *p++ = *sp++, --len);
- if (len != 0)
- memset(p, t->bt_bval, len);
- if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- }
- t->bt_cmap = (caddr_t)sp;
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_VMAP -- Get variable length records from a file.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_vmap(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- u_char *sp, *ep;
- recno_t nrec;
- int bval;
-
- sp = (u_char *)t->bt_cmap;
- ep = (u_char *)t->bt_emap;
- bval = t->bt_bval;
-
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- if (sp >= ep) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- for (data.data = sp; sp < ep && *sp != bval; ++sp);
- data.size = sp - (u_char *)data.data;
- if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- ++sp;
- }
- t->bt_cmap = (caddr_t)sp;
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/recno/rec_open.c b/1.4/main/db1-ast/recno/rec_open.c
deleted file mode 100644
index 0ebc8c7c4..000000000
--- a/1.4/main/db1-ast/recno/rec_open.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-DB *
-__rec_open(fname, flags, mode, openinfo, dflags)
- const char *fname;
- int flags, mode, dflags;
- const RECNOINFO *openinfo;
-{
- BTREE *t;
- BTREEINFO btopeninfo;
- DB *dbp;
- PAGE *h;
- struct stat sb;
- int rfd = 0, sverrno;
-
- /* Open the user's file -- if this fails, we're done. */
- if (fname != NULL && (rfd = open(fname, flags, mode)) < 0)
- return (NULL);
-
- /* Create a btree in memory (backed by disk). */
- dbp = NULL;
- if (openinfo) {
- if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
- goto einval;
- btopeninfo.flags = 0;
- btopeninfo.cachesize = openinfo->cachesize;
- btopeninfo.maxkeypage = 0;
- btopeninfo.minkeypage = 0;
- btopeninfo.psize = openinfo->psize;
- btopeninfo.compare = NULL;
- btopeninfo.prefix = NULL;
- btopeninfo.lorder = openinfo->lorder;
- dbp = __bt_open(openinfo->bfname,
- O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
- } else
- dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
- if (dbp == NULL)
- goto err;
-
- /*
- * Some fields in the tree structure are recno specific. Fill them
- * in and make the btree structure look like a recno structure. We
- * don't change the bt_ovflsize value, it's close enough and slightly
- * bigger.
- */
- t = dbp->internal;
- if (openinfo) {
- if (openinfo->flags & R_FIXEDLEN) {
- F_SET(t, R_FIXLEN);
- t->bt_reclen = openinfo->reclen;
- if (t->bt_reclen == 0)
- goto einval;
- }
- t->bt_bval = openinfo->bval;
- } else
- t->bt_bval = '\n';
-
- F_SET(t, R_RECNO);
- if (fname == NULL)
- F_SET(t, R_EOF | R_INMEM);
- else
- t->bt_rfd = rfd;
-
- if (fname != NULL) {
- /*
- * In 4.4BSD, stat(2) returns true for ISSOCK on pipes.
- * Unfortunately, that's not portable, so we use lseek
- * and check the errno values.
- */
- errno = 0;
- if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, R_RDONLY);
- break;
- default:
- goto einval;
- }
-slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
- goto err;
- F_SET(t, R_CLOSEFP);
- t->bt_irec =
- F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
- } else {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, R_RDONLY);
- break;
- case O_RDWR:
- break;
- default:
- goto einval;
- }
-
- if (fstat(rfd, &sb))
- goto err;
- /*
- * Kluge -- we'd like to test to see if the file is too
- * big to mmap. Since, we don't know what size or type
- * off_t's or size_t's are, what the largest unsigned
- * integral type is, or what random insanity the local
- * C compiler will perpetrate, doing the comparison in
- * a portable way is flatly impossible. Hope that mmap
- * fails if the file is too large.
- */
- if (sb.st_size == 0)
- F_SET(t, R_EOF);
- else {
-#ifdef MMAP_NOT_AVAILABLE
- /*
- * XXX
- * Mmap doesn't work correctly on many current
- * systems. In particular, it can fail subtly,
- * with cache coherency problems. Don't use it
- * for now.
- */
- t->bt_msize = sb.st_size;
- if ((t->bt_smap = mmap(NULL, t->bt_msize,
- PROT_READ, MAP_PRIVATE, rfd,
- (off_t)0)) == (caddr_t)-1)
- goto slow;
- t->bt_cmap = t->bt_smap;
- t->bt_emap = t->bt_smap + sb.st_size;
- t->bt_irec = F_ISSET(t, R_FIXLEN) ?
- __rec_fmap : __rec_vmap;
- F_SET(t, R_MEMMAPPED);
-#else
- goto slow;
-#endif
- }
- }
- }
-
- /* Use the recno routines. */
- dbp->close = __rec_close;
- dbp->del = __rec_delete;
- dbp->fd = __rec_fd;
- dbp->get = __rec_get;
- dbp->put = __rec_put;
- dbp->seq = __rec_seq;
- dbp->sync = __rec_sync;
-
- /* If the root page was created, reset the flags. */
- if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
- goto err;
- if ((h->flags & P_TYPE) == P_BLEAF) {
- F_CLR(h, P_TYPE);
- F_SET(h, P_RLEAF);
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- } else
- mpool_put(t->bt_mp, h, 0);
-
- if (openinfo && openinfo->flags & R_SNAPSHOT &&
- !F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- goto err;
- return (dbp);
-
-einval: errno = EINVAL;
-err: sverrno = errno;
- if (dbp != NULL)
- (void)__bt_close(dbp);
- if (fname != NULL)
- (void)close(rfd);
- errno = sverrno;
- return (NULL);
-}
-
-int
-__rec_fd(dbp)
- const DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* In-memory database can't have a file descriptor. */
- if (F_ISSET(t, R_INMEM)) {
- errno = ENOENT;
- return (-1);
- }
- return (t->bt_rfd);
-}
diff --git a/1.4/main/db1-ast/recno/rec_put.c b/1.4/main/db1-ast/recno/rec_put.c
deleted file mode 100644
index 331699867..000000000
--- a/1.4/main/db1-ast/recno/rec_put.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-/*
- * __REC_PUT -- Add a recno item to the tree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key
- * data: data
- * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
- * already in the tree and R_NOOVERWRITE specified.
- */
-int
-__rec_put(dbp, key, data, flags)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int flags;
-{
- BTREE *t;
- DBT fdata, tdata;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /*
- * If using fixed-length records, and the record is long, return
- * EINVAL. If it's short, pad it out. Use the record data return
- * memory, it's only short-term.
- */
- if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
- if (data->size > t->bt_reclen)
- goto einval;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- realloc(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- memmove(t->bt_rdata.data, data->data, data->size);
- memset((char *)t->bt_rdata.data + data->size,
- t->bt_bval, t->bt_reclen - data->size);
- fdata.data = t->bt_rdata.data;
- fdata.size = t->bt_reclen;
- } else {
- fdata.data = data->data;
- fdata.size = data->size;
- }
-
- switch (flags) {
- case R_CURSOR:
- if (!F_ISSET(&t->bt_cursor, CURS_INIT))
- goto einval;
- nrec = t->bt_cursor.rcursor;
- break;
- case R_SETCURSOR:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_IAFTER:
- if ((nrec = *(recno_t *)key->data) == 0) {
- nrec = 1;
- flags = R_IBEFORE;
- }
- break;
- case 0:
- case R_IBEFORE:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_NOOVERWRITE:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- if (nrec <= t->bt_nrecs)
- return (RET_SPECIAL);
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * Make sure that records up to and including the put record are
- * already in the database. If skipping records, create empty ones.
- */
- if (nrec > t->bt_nrecs) {
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, nrec) == RET_ERROR)
- return (RET_ERROR);
- if (nrec > t->bt_nrecs + 1) {
- if (F_ISSET(t, R_FIXLEN)) {
- if ((tdata.data =
- (void *)malloc(t->bt_reclen)) == NULL)
- return (RET_ERROR);
- tdata.size = t->bt_reclen;
- memset(tdata.data, t->bt_bval, tdata.size);
- } else {
- tdata.data = NULL;
- tdata.size = 0;
- }
- while (nrec > t->bt_nrecs + 1)
- if (__rec_iput(t,
- t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
- return (RET_ERROR);
- if (F_ISSET(t, R_FIXLEN))
- free(tdata.data);
- }
- }
-
- if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
- return (status);
-
- if (flags == R_SETCURSOR)
- t->bt_cursor.rcursor = nrec;
-
- F_SET(t, R_MODIFIED);
- return (__rec_ret(t, NULL, nrec, key, NULL));
-}
-
-/*
- * __REC_IPUT -- Add a recno item to the tree.
- *
- * Parameters:
- * t: tree
- * nrec: record number
- * data: data
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_iput(t, nrec, data, flags)
- BTREE *t;
- recno_t nrec;
- const DBT *data;
- u_int flags;
-{
- DBT tdata;
- EPG *e;
- PAGE *h;
- indx_t index, nxtindex;
- pgno_t pg;
- u_int32_t nbytes;
- int dflags, status;
- char *dest, db[NOVFLSIZE];
-
- /*
- * If the data won't fit on a page, store it on indirect pages.
- *
- * XXX
- * If the insert fails later on, these pages aren't recovered.
- */
- if (data->size > t->bt_ovflsize) {
- if (__ovfl_put(t, data, &pg) == RET_ERROR)
- return (RET_ERROR);
- tdata.data = db;
- tdata.size = NOVFLSIZE;
- *(pgno_t *)db = pg;
- *(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
- dflags = P_BIGDATA;
- data = &tdata;
- } else
- dflags = 0;
-
- /* __rec_search pins the returned page. */
- if ((e = __rec_search(t, nrec,
- nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
- SINSERT : SEARCH)) == NULL)
- return (RET_ERROR);
-
- h = e->page;
- index = e->index;
-
- /*
- * Add the specified key/data pair to the tree. The R_IAFTER and
- * R_IBEFORE flags insert the key after/before the specified key.
- *
- * Pages are split as required.
- */
- switch (flags) {
- case R_IAFTER:
- ++index;
- break;
- case R_IBEFORE:
- break;
- default:
- if (nrec < t->bt_nrecs &&
- __rec_dleaf(t, h, index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- break;
- }
-
- /*
- * If not enough room, split the page. The split code will insert
- * the key and data and unpin the current page. If inserting into
- * the offset array, shift the pointers up.
- */
- nbytes = NRLEAFDBT(data->size);
- if ((u_int32_t) (h->upper - h->lower) < nbytes + sizeof(indx_t)) {
- status = __bt_split(t, h, NULL, data, dflags, nbytes, index);
- if (status == RET_SUCCESS)
- ++t->bt_nrecs;
- return (status);
- }
-
- if (index < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + index + 1, h->linp + index,
- (nxtindex - index) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
-
- h->linp[index] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_RLEAF(dest, data, dflags);
-
- ++t->bt_nrecs;
- F_SET(t, B_MODIFIED);
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/recno/rec_search.c b/1.4/main/db1-ast/recno/rec_search.c
deleted file mode 100644
index e70fe4c13..000000000
--- a/1.4/main/db1-ast/recno/rec_search.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-/*
- * __REC_SEARCH -- Search a btree for a key.
- *
- * Parameters:
- * t: tree to search
- * recno: key to find
- * op: search operation
- *
- * Returns:
- * EPG for matching record, if any, or the EPG for the location of the
- * key, if it were inserted into the tree.
- *
- * Returns:
- * The EPG for matching record, if any, or the EPG for the location
- * of the key, if it were inserted into the tree, is entered into
- * the bt_cur field of the tree. A pointer to the field is returned.
- */
-EPG *
-__rec_search(t, recno, op)
- BTREE *t;
- recno_t recno;
- enum SRCHOP op;
-{
- register indx_t index;
- register PAGE *h;
- EPGNO *parent;
- RINTERNAL *r;
- pgno_t pg;
- indx_t top;
- recno_t total;
- int sverrno;
-
- BT_CLR(t);
- for (pg = P_ROOT, total = 0;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- goto err;
- if (h->flags & P_RLEAF) {
- t->bt_cur.page = h;
- t->bt_cur.index = recno - total;
- return (&t->bt_cur);
- }
- for (index = 0, top = NEXTINDEX(h);;) {
- r = GETRINTERNAL(h, index);
- if (++index == top || total + r->nrecs > recno)
- break;
- total += r->nrecs;
- }
-
- BT_PUSH(t, pg, index - 1);
-
- pg = r->pgno;
- switch (op) {
- case SDELETE:
- --GETRINTERNAL(h, (index - 1))->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- case SINSERT:
- ++GETRINTERNAL(h, (index - 1))->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- case SEARCH:
- mpool_put(t->bt_mp, h, 0);
- break;
- }
-
- }
- /* Try and recover the tree. */
-err: sverrno = errno;
- if (op != SEARCH)
- while ((parent = BT_POP(t)) != NULL) {
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- break;
- if (op == SINSERT)
- --GETRINTERNAL(h, parent->index)->nrecs;
- else
- ++GETRINTERNAL(h, parent->index)->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- }
- errno = sverrno;
- return (NULL);
-}
diff --git a/1.4/main/db1-ast/recno/rec_seq.c b/1.4/main/db1-ast/recno/rec_seq.c
deleted file mode 100644
index ca3451ca6..000000000
--- a/1.4/main/db1-ast/recno/rec_seq.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-/*
- * __REC_SEQ -- Recno sequential scan interface.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key for positioning and return value
- * data: data return value
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-int
-__rec_seq(dbp, key, data, flags)
- const DB *dbp;
- DBT *key, *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- switch(flags) {
- case R_CURSOR:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_NEXT:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- nrec = t->bt_cursor.rcursor + 1;
- break;
- }
- /* FALLTHROUGH */
- case R_FIRST:
- nrec = 1;
- break;
- case R_PREV:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- if ((nrec = t->bt_cursor.rcursor - 1) == 0)
- return (RET_SPECIAL);
- break;
- }
- /* FALLTHROUGH */
- case R_LAST:
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- return (RET_ERROR);
- nrec = t->bt_nrecs;
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
- return (status);
- if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
- return (RET_SPECIAL);
- }
-
- if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
- return (RET_ERROR);
-
- F_SET(&t->bt_cursor, CURS_INIT);
- t->bt_cursor.rcursor = nrec;
-
- status = __rec_ret(t, e, nrec, key, data);
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
diff --git a/1.4/main/db1-ast/recno/rec_utils.c b/1.4/main/db1-ast/recno/rec_utils.c
deleted file mode 100644
index ddc309712..000000000
--- a/1.4/main/db1-ast/recno/rec_utils.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../include/db.h"
-#include "recno.h"
-
-/*
- * __rec_ret --
- * Build return data.
- *
- * Parameters:
- * t: tree
- * e: key/data pair to be returned
- * nrec: record number
- * key: user's key structure
- * data: user's data structure
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_ret(t, e, nrec, key, data)
- BTREE *t;
- EPG *e;
- recno_t nrec;
- DBT *key, *data;
-{
- RLEAF *rl;
- void *p;
-
- if (key == NULL)
- goto dataonly;
-
- /* We have to copy the key, it's not on the page. */
- if (sizeof(recno_t) > t->bt_rkey.size) {
- p = (void *)(t->bt_rkey.data == NULL ?
- malloc(sizeof(recno_t)) :
- realloc(t->bt_rkey.data, sizeof(recno_t)));
- if (p == NULL)
- return (RET_ERROR);
- t->bt_rkey.data = p;
- t->bt_rkey.size = sizeof(recno_t);
- }
- memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
- key->size = sizeof(recno_t);
- key->data = t->bt_rkey.data;
-
-dataonly:
- if (data == NULL)
- return (RET_SUCCESS);
-
- /*
- * We must copy big keys/data to make them contiguous. Otherwise,
- * leave the page pinned and don't copy unless the user specified
- * concurrent access.
- */
- rl = GETRLEAF(e->page, e->index);
- if (rl->flags & P_BIGDATA) {
- if (__ovfl_get(t, rl->bytes,
- &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
- return (RET_ERROR);
- data->data = t->bt_rdata.data;
- } else if (F_ISSET(t, B_DB_LOCK)) {
- /* Use +1 in case the first record retrieved is 0 length. */
- if (rl->dsize + 1 > t->bt_rdata.size) {
- p = (void *)(t->bt_rdata.data == NULL ?
- malloc(rl->dsize + 1) :
- realloc(t->bt_rdata.data, rl->dsize + 1));
- if (p == NULL)
- return (RET_ERROR);
- t->bt_rdata.data = p;
- t->bt_rdata.size = rl->dsize + 1;
- }
- memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
- data->size = rl->dsize;
- data->data = t->bt_rdata.data;
- } else {
- data->size = rl->dsize;
- data->data = rl->bytes;
- }
- return (RET_SUCCESS);
-}
diff --git a/1.4/main/db1-ast/recno/recno.h b/1.4/main/db1-ast/recno/recno.h
deleted file mode 100644
index bec772c2f..000000000
--- a/1.4/main/db1-ast/recno/recno.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)recno.h 8.1 (Berkeley) 6/4/93
- */
-
-enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
-
-#include "../btree/btree.h"
-#include "extern.h"
diff --git a/1.4/main/devicestate.c b/1.4/main/devicestate.c
deleted file mode 100644
index cc647a823..000000000
--- a/1.4/main/devicestate.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Device state management
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/logger.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/pbx.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-
-/*! \brief Device state strings for printing */
-static const char *devstatestring[] = {
- /* 0 AST_DEVICE_UNKNOWN */ "Unknown", /*!< Valid, but unknown state */
- /* 1 AST_DEVICE_NOT_INUSE */ "Not in use", /*!< Not used */
- /* 2 AST_DEVICE IN USE */ "In use", /*!< In use */
- /* 3 AST_DEVICE_BUSY */ "Busy", /*!< Busy */
- /* 4 AST_DEVICE_INVALID */ "Invalid", /*!< Invalid - not known to Asterisk */
- /* 5 AST_DEVICE_UNAVAILABLE */ "Unavailable", /*!< Unavailable (not registred) */
- /* 6 AST_DEVICE_RINGING */ "Ringing", /*!< Ring, ring, ring */
- /* 7 AST_DEVICE_RINGINUSE */ "Ring+Inuse", /*!< Ring and in use */
- /* 8 AST_DEVICE_ONHOLD */ "On Hold" /*!< On Hold */
-};
-
-/*! \brief A device state provider (not a channel) */
-struct devstate_prov {
- char label[40];
- ast_devstate_prov_cb_type callback;
- AST_LIST_ENTRY(devstate_prov) list;
-};
-
-/*! \brief A list of providers */
-static AST_LIST_HEAD_STATIC(devstate_provs, devstate_prov);
-
-/*! \brief A device state watcher (callback) */
-struct devstate_cb {
- void *data;
- ast_devstate_cb_type callback;
- AST_LIST_ENTRY(devstate_cb) list;
-};
-
-/*! \brief A device state watcher list */
-static AST_LIST_HEAD_STATIC(devstate_cbs, devstate_cb);
-
-struct state_change {
- AST_LIST_ENTRY(state_change) list;
- char device[1];
-};
-
-/*! \brief The state change queue. State changes are queued
- for processing by a separate thread */
-static AST_LIST_HEAD_STATIC(state_changes, state_change);
-
-/*! \brief The device state change notification thread */
-static pthread_t change_thread = AST_PTHREADT_NULL;
-
-/*! \brief Flag for the queue */
-static ast_cond_t change_pending;
-
-/* Forward declarations */
-static int getproviderstate(const char *provider, const char *address);
-
-/*! \brief Find devicestate as text message for output */
-const char *devstate2str(int devstate)
-{
- return devstatestring[devstate];
-}
-
-/*! \brief Find out if device is active in a call or not
- \note find channels with the device's name in it
- This function is only used for channels that does not implement
- devicestate natively
-*/
-int ast_parse_device_state(const char *device)
-{
- struct ast_channel *chan;
- char match[AST_CHANNEL_NAME];
- int res;
-
- ast_copy_string(match, device, sizeof(match)-1);
- strcat(match, "-");
- chan = ast_get_channel_by_name_prefix_locked(match, strlen(match));
-
- if (!chan)
- return AST_DEVICE_UNKNOWN;
-
- if (chan->_state == AST_STATE_RINGING)
- res = AST_DEVICE_RINGING;
- else
- res = AST_DEVICE_INUSE;
-
- ast_channel_unlock(chan);
-
- return res;
-}
-
-/*! \brief Check device state through channel specific function or generic function */
-int ast_device_state(const char *device)
-{
- char *buf;
- char *number;
- const struct ast_channel_tech *chan_tech;
- int res = 0;
- /*! \brief Channel driver that provides device state */
- char *tech;
- /*! \brief Another provider of device state */
- char *provider = NULL;
-
- buf = ast_strdupa(device);
- tech = strsep(&buf, "/");
- number = buf;
- if (!number) {
- provider = strsep(&tech, ":");
- if (!provider)
- return AST_DEVICE_INVALID;
- /* We have a provider */
- number = tech;
- tech = NULL;
- }
-
- if (provider) {
- if(option_debug > 2)
- ast_log(LOG_DEBUG, "Checking if I can find provider for \"%s\" - number: %s\n", provider, number);
- return getproviderstate(provider, number);
- }
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "No provider found, checking channel drivers for %s - %s\n", tech, number);
-
- chan_tech = ast_get_channel_tech(tech);
- if (!chan_tech)
- return AST_DEVICE_INVALID;
-
- if (!chan_tech->devicestate) /* Does the channel driver support device state notification? */
- return ast_parse_device_state(device); /* No, try the generic function */
- else {
- res = chan_tech->devicestate(number); /* Ask the channel driver for device state */
- if (res == AST_DEVICE_UNKNOWN) {
- res = ast_parse_device_state(device);
- /* at this point we know the device exists, but the channel driver
- could not give us a state; if there is no channel state available,
- it must be 'not in use'
- */
- if (res == AST_DEVICE_UNKNOWN)
- res = AST_DEVICE_NOT_INUSE;
- return res;
- } else
- return res;
- }
-}
-
-/*! \brief Add device state provider */
-int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
-{
- struct devstate_prov *devprov;
-
- if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov))))
- return -1;
-
- devprov->callback = callback;
- ast_copy_string(devprov->label, label, sizeof(devprov->label));
-
- AST_LIST_LOCK(&devstate_provs);
- AST_LIST_INSERT_HEAD(&devstate_provs, devprov, list);
- AST_LIST_UNLOCK(&devstate_provs);
-
- return 0;
-}
-
-/*! \brief Remove device state provider */
-void ast_devstate_prov_del(const char *label)
-{
- struct devstate_prov *devcb;
-
- AST_LIST_LOCK(&devstate_provs);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) {
- if (!strcasecmp(devcb->label, label)) {
- AST_LIST_REMOVE_CURRENT(&devstate_provs, list);
- free(devcb);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&devstate_provs);
-}
-
-/*! \brief Get provider device state */
-static int getproviderstate(const char *provider, const char *address)
-{
- struct devstate_prov *devprov;
- int res = AST_DEVICE_INVALID;
-
-
- AST_LIST_LOCK(&devstate_provs);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devprov, list) {
- if(option_debug > 4)
- ast_log(LOG_DEBUG, "Checking provider %s with %s\n", devprov->label, provider);
-
- if (!strcasecmp(devprov->label, provider)) {
- res = devprov->callback(address);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&devstate_provs);
- return res;
-}
-
-/*! \brief Add device state watcher */
-int ast_devstate_add(ast_devstate_cb_type callback, void *data)
-{
- struct devstate_cb *devcb;
-
- if (!callback || !(devcb = ast_calloc(1, sizeof(*devcb))))
- return -1;
-
- devcb->data = data;
- devcb->callback = callback;
-
- AST_LIST_LOCK(&devstate_cbs);
- AST_LIST_INSERT_HEAD(&devstate_cbs, devcb, list);
- AST_LIST_UNLOCK(&devstate_cbs);
-
- return 0;
-}
-
-/*! \brief Remove device state watcher */
-void ast_devstate_del(ast_devstate_cb_type callback, void *data)
-{
- struct devstate_cb *devcb;
-
- AST_LIST_LOCK(&devstate_cbs);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_cbs, devcb, list) {
- if ((devcb->callback == callback) && (devcb->data == data)) {
- AST_LIST_REMOVE_CURRENT(&devstate_cbs, list);
- free(devcb);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&devstate_cbs);
-}
-
-/*! \brief Notify callback watchers of change, and notify PBX core for hint updates
- Normally executed within a separate thread
-*/
-static void do_state_change(const char *device)
-{
- int state;
- struct devstate_cb *devcb;
-
- state = ast_device_state(device);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Changing state for %s - state %d (%s)\n", device, state, devstate2str(state));
-
- AST_LIST_LOCK(&devstate_cbs);
- AST_LIST_TRAVERSE(&devstate_cbs, devcb, list)
- devcb->callback(device, state, devcb->data);
- AST_LIST_UNLOCK(&devstate_cbs);
-
- ast_hint_state_changed(device);
-}
-
-static int __ast_device_state_changed_literal(char *buf, int norecurse)
-{
- char *device;
- struct state_change *change;
- char *tmp = NULL;
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Notification of state change to be queued on device/channel %s\n", buf);
-
- device = buf;
-
- if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
- /* we could not allocate a change struct, or */
- /* there is no background thread, so process the change now */
- do_state_change(device);
- } else {
- /* queue the change */
- strcpy(change->device, device);
- AST_LIST_LOCK(&state_changes);
- AST_LIST_INSERT_TAIL(&state_changes, change, list);
- if (AST_LIST_FIRST(&state_changes) == change)
- /* the list was empty, signal the thread */
- ast_cond_signal(&change_pending);
- AST_LIST_UNLOCK(&state_changes);
- }
-
- /* The problem with this API is that a device may be called with the unique
- * identifier appended or not, but it's separated from the channel name
- * with a '-', which is also a legitimate character in a channel name. So,
- * we have to force both names to get their names checked for state changes
- * to ensure that the right one gets notified. Not a huge performance hit,
- * but it might could be fixed by an enterprising programmer in trunk.
- */
- if (!norecurse && (tmp = strrchr(device, '-'))) {
- *tmp = '\0';
- __ast_device_state_changed_literal(device, 1);
- }
-
- return 1;
-}
-
-int ast_device_state_changed_literal(const char *dev)
-{
- char *buf;
- buf = ast_strdupa(dev);
- return __ast_device_state_changed_literal(buf, 0);
-}
-
-/*! \brief Accept change notification, add it to change queue */
-int ast_device_state_changed(const char *fmt, ...)
-{
- char buf[AST_MAX_EXTENSION];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- return __ast_device_state_changed_literal(buf, 0);
-}
-
-/*! \brief Go through the dev state change queue and update changes in the dev state thread */
-static void *do_devstate_changes(void *data)
-{
- struct state_change *cur;
-
- AST_LIST_LOCK(&state_changes);
- for(;;) {
- /* the list lock will _always_ be held at this point in the loop */
- cur = AST_LIST_REMOVE_HEAD(&state_changes, list);
- if (cur) {
- /* we got an entry, so unlock the list while we process it */
- AST_LIST_UNLOCK(&state_changes);
- do_state_change(cur->device);
- free(cur);
- AST_LIST_LOCK(&state_changes);
- } else {
- /* there was no entry, so atomically unlock the list and wait for
- the condition to be signalled (returns with the lock held) */
- ast_cond_wait(&change_pending, &state_changes.lock);
- }
- }
-
- return NULL;
-}
-
-/*! \brief Initialize the device state engine in separate thread */
-int ast_device_state_engine_init(void)
-{
- ast_cond_init(&change_pending, NULL);
- if (ast_pthread_create_background(&change_thread, NULL, do_devstate_changes, NULL) < 0) {
- ast_log(LOG_ERROR, "Unable to start device state change thread.\n");
- return -1;
- }
-
- return 0;
-}
diff --git a/1.4/main/dial.c b/1.4/main/dial.c
deleted file mode 100644
index 401e5af6c..000000000
--- a/1.4/main/dial.c
+++ /dev/null
@@ -1,894 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- *
- * \brief Dialing API
- *
- * \author Joshua Colp <jcolp@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/dial.h"
-#include "asterisk/pbx.h"
-
-/*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */
-struct ast_dial {
- int num; /*! Current number to give to next dialed channel */
- enum ast_dial_result state; /*! Status of dial */
- void *options[AST_DIAL_OPTION_MAX]; /*! Global options */
- ast_dial_state_callback state_callback; /*! Status callback */
- AST_LIST_HEAD(, ast_dial_channel) channels; /*! Channels being dialed */
- pthread_t thread; /*! Thread (if running in async) */
- ast_mutex_t lock; /*! Lock to protect the thread information above */
-};
-
-/*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */
-struct ast_dial_channel {
- int num; /*! Unique number for dialed channel */
- const char *tech; /*! Technology being dialed */
- const char *device; /*! Device being dialed */
- void *options[AST_DIAL_OPTION_MAX]; /*! Channel specific options */
- int cause; /*! Cause code in case of failure */
- int is_running_app:1; /*! Is this running an application? */
- struct ast_channel *owner; /*! Asterisk channel */
- AST_LIST_ENTRY(ast_dial_channel) list; /*! Linked list information */
-};
-
-/*! \brief Typedef for dial option enable */
-typedef void *(*ast_dial_option_cb_enable)(void *data);
-
-/*! \brief Typedef for dial option disable */
-typedef int (*ast_dial_option_cb_disable)(void *data);
-
-/* Structure for 'ANSWER_EXEC' option */
-struct answer_exec_struct {
- char app[AST_MAX_APP]; /* Application name */
- char *args; /* Application arguments */
-};
-
-/* Enable function for 'ANSWER_EXEC' option */
-static void *answer_exec_enable(void *data)
-{
- struct answer_exec_struct *answer_exec = NULL;
- char *app = ast_strdupa((char*)data), *args = NULL;
-
- /* Not giving any data to this option is bad, mmmk? */
- if (ast_strlen_zero(app))
- return NULL;
-
- /* Create new data structure */
- if (!(answer_exec = ast_calloc(1, sizeof(*answer_exec))))
- return NULL;
-
- /* Parse out application and arguments */
- if ((args = strchr(app, '|'))) {
- *args++ = '\0';
- answer_exec->args = ast_strdup(args);
- }
-
- /* Copy application name */
- ast_copy_string(answer_exec->app, app, sizeof(answer_exec->app));
-
- return answer_exec;
-}
-
-/* Disable function for 'ANSWER_EXEC' option */
-static int answer_exec_disable(void *data)
-{
- struct answer_exec_struct *answer_exec = data;
-
- /* Make sure we have a value */
- if (!answer_exec)
- return -1;
-
- /* If arguments are present, free them too */
- if (answer_exec->args)
- free(answer_exec->args);
-
- /* This is simple - just free the structure */
- free(answer_exec);
-
- return 0;
-}
-
-/* Application execution function for 'ANSWER_EXEC' option */
-static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args)
-{
- struct ast_channel *chan = dial_channel->owner;
- struct ast_app *ast_app = pbx_findapp(app);
-
- /* If the application was not found, return immediately */
- if (!ast_app)
- return;
-
- /* All is well... execute the application */
- pbx_exec(chan, ast_app, args);
-
- /* If another thread is not taking over hang up the channel */
- ast_mutex_lock(&dial->lock);
- if (dial->thread != AST_PTHREADT_STOP) {
- ast_hangup(chan);
- dial_channel->owner = NULL;
- }
- ast_mutex_unlock(&dial->lock);
-
- return;
-}
-
-/*! \brief Options structure - maps options to respective handlers (enable/disable). This list MUST be perfectly kept in order, or else madness will happen. */
-static const struct ast_option_types {
- enum ast_dial_option option;
- ast_dial_option_cb_enable enable;
- ast_dial_option_cb_disable disable;
-} option_types[] = {
- { AST_DIAL_OPTION_RINGING, NULL, NULL }, /*! Always indicate ringing to caller */
- { AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*! Execute application upon answer in async mode */
- { AST_DIAL_OPTION_MAX, NULL, NULL }, /*! Terminator of list */
-};
-
-/* free the buffer if allocated, and set the pointer to the second arg */
-#define S_REPLACE(s, new_val) \
- do { \
- if (s) \
- free(s); \
- s = (new_val); \
- } while (0)
-
-/*! \brief Maximum number of channels we can watch at a time */
-#define AST_MAX_WATCHERS 256
-
-/*! \brief Macro for finding the option structure to use on a dialed channel */
-#define FIND_RELATIVE_OPTION(dial, dial_channel, ast_dial_option) (dial_channel->options[ast_dial_option] ? dial_channel->options[ast_dial_option] : dial->options[ast_dial_option])
-
-/*! \brief Macro that determines whether a channel is the caller or not */
-#define IS_CALLER(chan, owner) (chan == owner ? 1 : 0)
-
-/*! \brief New dialing structure
- * \note Create a dialing structure
- * \return Returns a calloc'd ast_dial structure, NULL on failure
- */
-struct ast_dial *ast_dial_create(void)
-{
- struct ast_dial *dial = NULL;
-
- /* Allocate new memory for structure */
- if (!(dial = ast_calloc(1, sizeof(*dial))))
- return NULL;
-
- /* Initialize list of channels */
- AST_LIST_HEAD_INIT(&dial->channels);
-
- /* Initialize thread to NULL */
- dial->thread = AST_PTHREADT_NULL;
-
- /* Can't forget about the lock */
- ast_mutex_init(&dial->lock);
-
- return dial;
-}
-
-/*! \brief Append a channel
- * \note Appends a channel to a dialing structure
- * \return Returns channel reference number on success, -1 on failure
- */
-int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
-{
- struct ast_dial_channel *channel = NULL;
-
- /* Make sure we have required arguments */
- if (!dial || !tech || !device)
- return -1;
-
- /* Allocate new memory for dialed channel structure */
- if (!(channel = ast_calloc(1, sizeof(*channel))))
- return -1;
-
- /* Record technology and device for when we actually dial */
- channel->tech = tech;
- channel->device = device;
-
- /* Grab reference number from dial structure */
- channel->num = ast_atomic_fetchadd_int(&dial->num, +1);
-
- /* Insert into channels list */
- AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
-
- return channel->num;
-}
-
-/*! \brief Helper function that does the beginning dialing */
-static int begin_dial(struct ast_dial *dial, struct ast_channel *chan)
-{
- struct ast_dial_channel *channel = NULL;
- int success = 0, res = 0;
-
- /* Iterate through channel list, requesting and calling each one */
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- char numsubst[AST_MAX_EXTENSION];
-
- /* Copy device string over */
- ast_copy_string(numsubst, channel->device, sizeof(numsubst));
-
- /* Request that the channel be created */
- if (!(channel->owner = ast_request(channel->tech,
- chan ? chan->nativeformats : AST_FORMAT_AUDIO_MASK, numsubst, &channel->cause))) {
- continue;
- }
-
- channel->owner->appl = "AppDial2";
- channel->owner->data = "(Outgoing Line)";
- channel->owner->whentohangup = 0;
-
- /* Inherit everything from he who spawned this Dial */
- if (chan) {
- ast_channel_inherit_variables(chan, channel->owner);
-
- /* Copy over callerid information */
- S_REPLACE(channel->owner->cid.cid_num, ast_strdup(chan->cid.cid_num));
- S_REPLACE(channel->owner->cid.cid_name, ast_strdup(chan->cid.cid_name));
- S_REPLACE(channel->owner->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
- S_REPLACE(channel->owner->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
-
- ast_string_field_set(channel->owner, language, chan->language);
- ast_string_field_set(channel->owner, accountcode, chan->accountcode);
- channel->owner->cdrflags = chan->cdrflags;
- if (ast_strlen_zero(channel->owner->musicclass))
- ast_string_field_set(channel->owner, musicclass, chan->musicclass);
-
- channel->owner->cid.cid_pres = chan->cid.cid_pres;
- channel->owner->cid.cid_ton = chan->cid.cid_ton;
- channel->owner->cid.cid_tns = chan->cid.cid_tns;
- channel->owner->adsicpe = chan->adsicpe;
- channel->owner->transfercapability = chan->transfercapability;
- }
-
- /* Actually call the device */
- if ((res = ast_call(channel->owner, numsubst, 0))) {
- ast_hangup(channel->owner);
- channel->owner = NULL;
- } else {
- success++;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
- }
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- /* If number of failures matches the number of channels, then this truly failed */
- return success;
-}
-
-/*! \brief Helper function that finds the dialed channel based on owner */
-static struct ast_dial_channel *find_relative_dial_channel(struct ast_dial *dial, struct ast_channel *owner)
-{
- struct ast_dial_channel *channel = NULL;
-
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->owner == owner)
- break;
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- return channel;
-}
-
-static void set_state(struct ast_dial *dial, enum ast_dial_result state)
-{
- dial->state = state;
-
- if (dial->state_callback)
- dial->state_callback(dial);
-}
-
-/*! \brief Helper function that handles control frames WITH owner */
-static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan)
-{
- if (fr->frametype == AST_FRAME_CONTROL) {
- switch (fr->subclass) {
- case AST_CONTROL_ANSWER:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name);
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_REMOVE(&dial->channels, channel, list);
- AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
- AST_LIST_UNLOCK(&dial->channels);
- set_state(dial, AST_DIAL_RESULT_ANSWERED);
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", channel->owner->name);
- ast_hangup(channel->owner);
- channel->owner = NULL;
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", channel->owner->name);
- ast_hangup(channel->owner);
- channel->owner = NULL;
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name);
- ast_indicate(chan, AST_CONTROL_RINGING);
- set_state(dial, AST_DIAL_RESULT_RINGING);
- break;
- case AST_CONTROL_PROGRESS:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is making progress, passing it to %s\n", channel->owner->name, chan->name);
- ast_indicate(chan, AST_CONTROL_PROGRESS);
- set_state(dial, AST_DIAL_RESULT_PROGRESS);
- break;
- case AST_CONTROL_VIDUPDATE:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", channel->owner->name, chan->name);
- ast_indicate(chan, AST_CONTROL_VIDUPDATE);
- break;
- case AST_CONTROL_SRCUPDATE:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", channel->owner->name, chan->name);
- ast_indicate(chan, AST_CONTROL_SRCUPDATE);
- break;
- case AST_CONTROL_PROCEEDING:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding, passing it to %s\n", channel->owner->name, chan->name);
- ast_indicate(chan, AST_CONTROL_PROCEEDING);
- set_state(dial, AST_DIAL_RESULT_PROCEEDING);
- break;
- case AST_CONTROL_HOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", chan->name);
- ast_indicate(chan, AST_CONTROL_HOLD);
- break;
- case AST_CONTROL_UNHOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", chan->name);
- ast_indicate(chan, AST_CONTROL_UNHOLD);
- break;
- case AST_CONTROL_OFFHOOK:
- case AST_CONTROL_FLASH:
- break;
- case -1:
- /* Prod the channel */
- ast_indicate(chan, -1);
- break;
- default:
- break;
- }
- }
-
- return;
-}
-
-/*! \brief Helper function that handles control frames WITHOUT owner */
-static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr)
-{
- /* If we have no owner we can only update the state of the dial structure, so only look at control frames */
- if (fr->frametype != AST_FRAME_CONTROL)
- return;
-
- switch (fr->subclass) {
- case AST_CONTROL_ANSWER:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered\n", channel->owner->name);
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_REMOVE(&dial->channels, channel, list);
- AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
- AST_LIST_UNLOCK(&dial->channels);
- set_state(dial, AST_DIAL_RESULT_ANSWERED);
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", channel->owner->name);
- ast_hangup(channel->owner);
- channel->owner = NULL;
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", channel->owner->name);
- ast_hangup(channel->owner);
- channel->owner = NULL;
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name);
- set_state(dial, AST_DIAL_RESULT_RINGING);
- break;
- case AST_CONTROL_PROGRESS:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is making progress\n", channel->owner->name);
- set_state(dial, AST_DIAL_RESULT_PROGRESS);
- break;
- case AST_CONTROL_PROCEEDING:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding\n", channel->owner->name);
- set_state(dial, AST_DIAL_RESULT_PROCEEDING);
- break;
- default:
- break;
- }
-
- return;
-}
-
-/*! \brief Helper function that basically keeps tabs on dialing attempts */
-static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
-{
- int timeout = -1, count = 0;
- struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
- struct ast_dial_channel *channel = NULL;
- struct answer_exec_struct *answer_exec = NULL;
-
- set_state(dial, AST_DIAL_RESULT_TRYING);
-
- /* If the "always indicate ringing" option is set, change state to ringing and indicate to the owner if present */
- if (dial->options[AST_DIAL_OPTION_RINGING]) {
- set_state(dial, AST_DIAL_RESULT_RINGING);
- if (chan)
- ast_indicate(chan, AST_CONTROL_RINGING);
- }
-
- /* Go into an infinite loop while we are trying */
- while ((dial->state != AST_DIAL_RESULT_UNANSWERED) && (dial->state != AST_DIAL_RESULT_ANSWERED) && (dial->state != AST_DIAL_RESULT_HANGUP) && (dial->state != AST_DIAL_RESULT_TIMEOUT)) {
- int pos = 0;
- struct ast_frame *fr = NULL;
-
- /* Set up channel structure array */
- pos = count = 0;
- if (chan)
- cs[pos++] = chan;
-
- /* Add channels we are attempting to dial */
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->owner) {
- cs[pos++] = channel->owner;
- count++;
- }
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- /* If we have no outbound channels in progress, switch state to unanswered and stop */
- if (!count) {
- set_state(dial, AST_DIAL_RESULT_UNANSWERED);
- break;
- }
-
- /* Just to be safe... */
- if (dial->thread == AST_PTHREADT_STOP)
- break;
-
- /* Wait for frames from channels */
- who = ast_waitfor_n(cs, pos, &timeout);
-
- /* Check to see if our thread is being cancelled */
- if (dial->thread == AST_PTHREADT_STOP)
- break;
-
- /* If we are not being cancelled and we have no channel, then timeout was tripped */
- if (!who)
- continue;
-
- /* Find relative dial channel */
- if (!chan || !IS_CALLER(chan, who))
- channel = find_relative_dial_channel(dial, who);
-
- /* Attempt to read in a frame */
- if (!(fr = ast_read(who))) {
- /* If this is the caller then we switch state to hangup and stop */
- if (chan && IS_CALLER(chan, who)) {
- set_state(dial, AST_DIAL_RESULT_HANGUP);
- break;
- }
- ast_hangup(who);
- channel->owner = NULL;
- continue;
- }
-
- /* Process the frame */
- if (chan)
- handle_frame(dial, channel, fr, chan);
- else
- handle_frame_ownerless(dial, channel, fr);
-
- /* Free the received frame and start all over */
- ast_frfree(fr);
- }
-
- /* Do post-processing from loop */
- if (dial->state == AST_DIAL_RESULT_ANSWERED) {
- /* Hangup everything except that which answered */
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (!channel->owner || channel->owner == who)
- continue;
- ast_hangup(channel->owner);
- channel->owner = NULL;
- }
- AST_LIST_UNLOCK(&dial->channels);
- /* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
- if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) {
- channel->is_running_app = 1;
- answer_exec_run(dial, channel, answer_exec->app, answer_exec->args);
- channel->is_running_app = 0;
- }
- } else if (dial->state == AST_DIAL_RESULT_HANGUP) {
- /* Hangup everything */
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (!channel->owner)
- continue;
- ast_hangup(channel->owner);
- channel->owner = NULL;
- }
- AST_LIST_UNLOCK(&dial->channels);
- }
-
- return dial->state;
-}
-
-/*! \brief Dial async thread function */
-static void *async_dial(void *data)
-{
- struct ast_dial *dial = data;
-
- /* This is really really simple... we basically pass monitor_dial a NULL owner and it changes it's behavior */
- monitor_dial(dial, NULL);
-
- return NULL;
-}
-
-/*! \brief Execute dialing synchronously or asynchronously
- * \note Dials channels in a dial structure.
- * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
- */
-enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
-{
- enum ast_dial_result res = AST_DIAL_RESULT_TRYING;
-
- /* Ensure required arguments are passed */
- if (!dial || (!chan && !async)) {
- ast_log(LOG_DEBUG, "invalid #1\n");
- return AST_DIAL_RESULT_INVALID;
- }
-
- /* If there are no channels to dial we can't very well try to dial them */
- if (AST_LIST_EMPTY(&dial->channels)) {
- ast_log(LOG_DEBUG, "invalid #2\n");
- return AST_DIAL_RESULT_INVALID;
- }
-
- /* Dial each requested channel */
- if (!begin_dial(dial, chan))
- return AST_DIAL_RESULT_FAILED;
-
- /* If we are running async spawn a thread and send it away... otherwise block here */
- if (async) {
- dial->state = AST_DIAL_RESULT_TRYING;
- /* Try to create a thread */
- if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) {
- /* Failed to create the thread - hangup all dialed channels and return failed */
- ast_dial_hangup(dial);
- res = AST_DIAL_RESULT_FAILED;
- }
- } else {
- res = monitor_dial(dial, chan);
- }
-
- return res;
-}
-
-/*! \brief Return channel that answered
- * \note Returns the Asterisk channel that answered
- * \param dial Dialing structure
- */
-struct ast_channel *ast_dial_answered(struct ast_dial *dial)
-{
- if (!dial)
- return NULL;
-
- return ((dial->state == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
-}
-
-/*! \brief Return state of dial
- * \note Returns the state of the dial attempt
- * \param dial Dialing structure
- */
-enum ast_dial_result ast_dial_state(struct ast_dial *dial)
-{
- return dial->state;
-}
-
-/*! \brief Cancel async thread
- * \note Cancel a running async thread
- * \param dial Dialing structure
- */
-enum ast_dial_result ast_dial_join(struct ast_dial *dial)
-{
- pthread_t thread;
-
- /* If the dial structure is not running in async, return failed */
- if (dial->thread == AST_PTHREADT_NULL)
- return AST_DIAL_RESULT_FAILED;
-
- /* Record thread */
- thread = dial->thread;
-
- /* Boom, commence locking */
- ast_mutex_lock(&dial->lock);
-
- /* Stop the thread */
- dial->thread = AST_PTHREADT_STOP;
-
- /* If the answered channel is running an application we have to soft hangup it, can't just poke the thread */
- AST_LIST_LOCK(&dial->channels);
- if (AST_LIST_FIRST(&dial->channels)->is_running_app) {
- struct ast_channel *chan = AST_LIST_FIRST(&dial->channels)->owner;
- if (chan) {
- ast_channel_lock(chan);
- ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(chan);
- }
- } else {
- /* Now we signal it with SIGURG so it will break out of it's waitfor */
- pthread_kill(thread, SIGURG);
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- /* Yay done with it */
- ast_mutex_unlock(&dial->lock);
-
- /* Finally wait for the thread to exit */
- pthread_join(thread, NULL);
-
- /* Yay thread is all gone */
- dial->thread = AST_PTHREADT_NULL;
-
- return dial->state;
-}
-
-/*! \brief Hangup channels
- * \note Hangup all active channels
- * \param dial Dialing structure
- */
-void ast_dial_hangup(struct ast_dial *dial)
-{
- struct ast_dial_channel *channel = NULL;
-
- if (!dial)
- return;
-
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->owner) {
- ast_hangup(channel->owner);
- channel->owner = NULL;
- }
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- return;
-}
-
-/*! \brief Destroys a dialing structure
- * \note Destroys (free's) the given ast_dial structure
- * \param dial Dialing structure to free
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_destroy(struct ast_dial *dial)
-{
- int i = 0;
- struct ast_dial_channel *channel = NULL;
-
- if (!dial)
- return -1;
-
- /* Hangup and deallocate all the dialed channels */
- AST_LIST_LOCK(&dial->channels);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&dial->channels, channel, list) {
- /* Disable any enabled options */
- for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
- if (!channel->options[i])
- continue;
- if (option_types[i].disable)
- option_types[i].disable(channel->options[i]);
- channel->options[i] = NULL;
- }
- /* Hang up channel if need be */
- if (channel->owner) {
- ast_hangup(channel->owner);
- channel->owner = NULL;
- }
- /* Free structure */
- AST_LIST_REMOVE_CURRENT(&dial->channels, list);
- free(channel);
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&dial->channels);
-
- /* Disable any enabled options globally */
- for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
- if (!dial->options[i])
- continue;
- if (option_types[i].disable)
- option_types[i].disable(dial->options[i]);
- dial->options[i] = NULL;
- }
-
- /* Lock be gone! */
- ast_mutex_destroy(&dial->lock);
-
- /* Free structure */
- free(dial);
-
- return 0;
-}
-
-/*! \brief Enables an option globally
- * \param dial Dial structure to enable option on
- * \param option Option to enable
- * \param data Data to pass to this option (not always needed)
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
-{
- /* If the option is already enabled, return failure */
- if (dial->options[option])
- return -1;
-
- /* Execute enable callback if it exists, if not simply make sure the value is set */
- if (option_types[option].enable)
- dial->options[option] = option_types[option].enable(data);
- else
- dial->options[option] = (void*)1;
-
- return 0;
-}
-
-/*! \brief Enables an option per channel
- * \param dial Dial structure
- * \param num Channel number to enable option on
- * \param option Option to enable
- * \param data Data to pass to this option (not always needed)
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
-{
- struct ast_dial_channel *channel = NULL;
-
- /* Ensure we have required arguments */
- if (!dial || AST_LIST_EMPTY(&dial->channels))
- return -1;
-
- /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */
- AST_LIST_LOCK(&dial->channels);
- if (AST_LIST_LAST(&dial->channels)->num != num) {
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->num == num)
- break;
- }
- } else {
- channel = AST_LIST_LAST(&dial->channels);
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- /* If none found, return failure */
- if (!channel)
- return -1;
-
- /* If the option is already enabled, return failure */
- if (channel->options[option])
- return -1;
-
- /* Execute enable callback if it exists, if not simply make sure the value is set */
- if (option_types[option].enable)
- channel->options[option] = option_types[option].enable(data);
- else
- channel->options[option] = (void*)1;
-
- return 0;
-}
-
-/*! \brief Disables an option globally
- * \param dial Dial structure to disable option on
- * \param option Option to disable
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option option)
-{
- /* If the option is not enabled, return failure */
- if (!dial->options[option])
- return -1;
-
- /* Execute callback of option to disable if it exists */
- if (option_types[option].disable)
- option_types[option].disable(dial->options[option]);
-
- /* Finally disable option on the structure */
- dial->options[option] = NULL;
-
- return 0;
-}
-
-/*! \brief Disables an option per channel
- * \param dial Dial structure
- * \param num Channel number to disable option on
- * \param option Option to disable
- * \return Returns 0 on success, -1 on failure
- */
-int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option)
-{
- struct ast_dial_channel *channel = NULL;
-
- /* Ensure we have required arguments */
- if (!dial || AST_LIST_EMPTY(&dial->channels))
- return -1;
-
- /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */
- AST_LIST_LOCK(&dial->channels);
- if (AST_LIST_LAST(&dial->channels)->num != num) {
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->num == num)
- break;
- }
- } else {
- channel = AST_LIST_LAST(&dial->channels);
- }
- AST_LIST_UNLOCK(&dial->channels);
-
- /* If none found, return failure */
- if (!channel)
- return -1;
-
- /* If the option is not enabled, return failure */
- if (!channel->options[option])
- return -1;
-
- /* Execute callback of option to disable it if it exists */
- if (option_types[option].disable)
- option_types[option].disable(channel->options[option]);
-
- /* Finally disable the option on the structure */
- channel->options[option] = NULL;
-
- return 0;
-}
-
-void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
-{
- dial->state_callback = callback;
-}
diff --git a/1.4/main/dlfcn.c b/1.4/main/dlfcn.c
deleted file mode 100644
index cc6fe40f9..000000000
--- a/1.4/main/dlfcn.c
+++ /dev/null
@@ -1,1314 +0,0 @@
-/*
-Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
- Peter O'Gorman <ogorman@users.sourceforge.net>
-
-Portions may be copyright others, see the AUTHORS file included with this
-distribution.
-
-Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
-
-Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <mach-o/dyld.h>
-#include <mach-o/nlist.h>
-#include <mach-o/getsect.h>
-/* Just playing to see if it would compile with the freebsd headers, it does,
- * but because of the different values for RTLD_LOCAL etc, it would break binary
- * compat... oh well
- */
-#ifndef __BSD_VISIBLE
-#define __BSD_VISIBLE 1
-#endif
-
-#include "asterisk/dlfcn-compat.h"
-
-#ifndef dl_restrict
-#define dl_restrict __restrict
-#endif
-/* This is not available on 10.1 */
-#ifndef LC_LOAD_WEAK_DYLIB
-#define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
-#endif
-
-/* With this stuff here, this thing may actually compile/run on 10.0 systems
- * Not that I have a 10.0 system to test it on anylonger
- */
-#ifndef LC_REQ_DYLD
-#define LC_REQ_DYLD 0x80000000
-#endif
-#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
-#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
-#endif
-#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
-#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
-#endif
-#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
-#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
-#endif
-#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
-#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
-#endif
-/* These symbols will be looked for in dyld */
-static const struct mach_header *(*dyld_NSAddImage) (const char *, unsigned long) = 0;
-static int (*dyld_NSIsSymbolNameDefinedInImage) (const struct mach_header *, const char *) = 0;
-static NSSymbol(*dyld_NSLookupSymbolInImage)
- (const struct mach_header *, const char *, unsigned long) = 0;
-
-/* Define this to make dlcompat reuse data block. This way in theory we save
- * a little bit of overhead. However we then couldn't correctly catch excess
- * calls to dlclose(). Hence we don't use this feature
- */
-#undef REUSE_STATUS
-
-/* Size of the internal error message buffer (used by dlerror()) */
-#define ERR_STR_LEN 251
-
-/* Maximum number of search paths supported by getSearchPath */
-#define MAX_SEARCH_PATHS 32
-
-
-#define MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF')
-#define MAGIC_DYLIB_MOD ((NSModule) 'DYMO')
-
-/* internal flags */
-#define DL_IN_LIST 0x01
-
-/* our mutex */
-static pthread_mutex_t dlcompat_mutex;
-/* Our thread specific storage
- */
-static pthread_key_t dlerror_key;
-
-struct dlthread
-{
- int lockcnt;
- unsigned char errset;
- char errstr[ERR_STR_LEN];
-};
-
-/* This is our central data structure. Whenever a module is loaded via
- * dlopen(), we create such a struct.
- */
-struct dlstatus
-{
- struct dlstatus *next; /* pointer to next element in the linked list */
- NSModule module;
- const struct mach_header *lib;
- int refs; /* reference count */
- int mode; /* mode in which this module was loaded */
- dev_t device;
- ino_t inode;
- int flags; /* Any internal flags we may need */
-};
-
-/* Head node of the dlstatus list */
-static struct dlstatus mainStatus = { 0, MAGIC_DYLIB_MOD, NULL, -1, RTLD_GLOBAL, 0, 0, 0 };
-static struct dlstatus *stqueue = &mainStatus;
-
-
-/* Storage for the last error message (used by dlerror()) */
-/* static char err_str[ERR_STR_LEN]; */
-/* static int err_filled = 0; */
-
-/* Prototypes to internal functions */
-static void debug(const char *fmt, ...);
-static void error(const char *str, ...);
-static const char *safegetenv(const char *s);
-static const char *searchList(void);
-static const char *getSearchPath(int i);
-static const char *getFullPath(int i, const char *file);
-static const struct stat *findFile(const char *file, const char **fullPath);
-static int isValidStatus(struct dlstatus *status);
-static inline int isFlagSet(int mode, int flag);
-static struct dlstatus *lookupStatus(const struct stat *sbuf);
-static void insertStatus(struct dlstatus *dls, const struct stat *sbuf);
-static int promoteLocalToGlobal(struct dlstatus *dls);
-static void *reference(struct dlstatus *dls, int mode);
-static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError);
-static struct dlstatus *allocStatus(void);
-static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode);
-static NSSymbol *search_linked_libs(const struct mach_header *mh, const char *symbol);
-static const char *get_lib_name(const struct mach_header *mh);
-static const struct mach_header *get_mach_header_from_NSModule(NSModule * mod);
-static void dlcompat_init_func(void);
-static inline void dolock(void);
-static inline void dounlock(void);
-static void dlerrorfree(void *data);
-static void resetdlerror(void);
-static const struct mach_header *my_find_image(const char *name);
-static const struct mach_header *image_for_address(const void *address);
-static void dlcompat_cleanup(void);
-static inline const char *dyld_error_str(void);
-
-#if FINK_BUILD
-/* Two Global Functions */
-void *dlsym_prepend_underscore(void *handle, const char *symbol);
-void *dlsym_auto_underscore(void *handle, const char *symbol);
-
-/* And their _intern counterparts */
-static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol);
-static void *dlsym_auto_underscore_intern(void *handle, const char *symbol);
-#endif
-
-/* Functions */
-
-static void debug(const char *fmt, ...)
-{
-#if DEBUG > 1
- va_list arg;
- va_start(arg, fmt);
- fprintf(stderr, "DLDEBUG: ");
- vfprintf(stderr, fmt, arg);
- fprintf(stderr, "\n");
- fflush(stderr);
- va_end(arg);
-#endif
-}
-
-static void error(const char *str, ...)
-{
- va_list arg;
- struct dlthread *tss;
- char * err_str;
- va_start(arg, str);
- tss = pthread_getspecific(dlerror_key);
- err_str = tss->errstr;
- strncpy(err_str, "dlcompat: ", ERR_STR_LEN);
- vsnprintf(err_str + 10, ERR_STR_LEN - 10, str, arg);
- va_end(arg);
- debug("ERROR: %s\n", err_str);
- tss->errset = 1;
-}
-
-static void warning(const char *str)
-{
-#if DEBUG > 0
- fprintf(stderr, "WARNING: dlcompat: %s\n", str);
-#endif
-}
-
-static const char *safegetenv(const char *s)
-{
- const char *ss = getenv(s);
- return ss ? ss : "";
-}
-
-/* because this is only used for debugging and error reporting functions, we
- * don't really care about how elegant it is... it could use the load
- * commands to find the install name of the library, but...
- */
-static const char *get_lib_name(const struct mach_header *mh)
-{
- unsigned long count = _dyld_image_count();
- unsigned long i;
- const char *val = NULL;
- if (mh)
- {
- for (i = 0; i < count; i++)
- {
- if (mh == _dyld_get_image_header(i))
- {
- val = _dyld_get_image_name(i);
- break;
- }
- }
- }
- return val;
-}
-
-/* Returns the mach_header for the module bu going through all the loaded images
- * and finding the one with the same name as the module. There really ought to be
- * an api for doing this, would be faster, but there isn't one right now
- */
-static const struct mach_header *get_mach_header_from_NSModule(NSModule * mod)
-{
- const char *mod_name = NSNameOfModule(mod);
- struct mach_header *mh = NULL;
- unsigned long count = _dyld_image_count();
- unsigned long i;
- debug("Module name: %s", mod_name);
- for (i = 0; i < count; i++)
- {
- if (!strcmp(mod_name, _dyld_get_image_name(i)))
- {
- mh = _dyld_get_image_header(i);
- break;
- }
- }
- return mh;
-}
-
-
-/* Compute and return a list of all directories that we should search when
- * trying to locate a module. We first look at the values of LD_LIBRARY_PATH
- * and DYLD_LIBRARY_PATH, and then finally fall back to looking into
- * /usr/lib and /lib. Since both of the environments variables can contain a
- * list of colon separated paths, we simply concat them and the two other paths
- * into one big string, which we then can easily parse.
- * Splitting this string into the actual path list is done by getSearchPath()
- */
-static const char *searchList()
-{
- size_t buf_size;
- static char *buf=NULL;
- const char *ldlp = safegetenv("LD_LIBRARY_PATH");
- const char *dyldlp = safegetenv("DYLD_LIBRARY_PATH");
- const char *stdpath = getenv("DYLD_FALLBACK_LIBRARY_PATH");
- if (!stdpath)
- stdpath = "/usr/local/lib:/lib:/usr/lib";
- if (!buf)
- {
- buf_size = strlen(ldlp) + strlen(dyldlp) + strlen(stdpath) + 4;
- buf = malloc(buf_size);
- snprintf(buf, buf_size, "%s%s%s%s%s%c", dyldlp, (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""),
- stdpath, '\0');
- }
- return buf;
-}
-
-/* Returns the ith search path from the list as computed by searchList() */
-static const char *getSearchPath(int i)
-{
- static const char *list = 0;
- static char **path = (char **)0;
- static int end = 0;
- static int numsize = MAX_SEARCH_PATHS;
- static char **tmp;
- /* So we can call free() in the "destructor" we use i=-1 to return the alloc'd array */
- if (i == -1)
- {
- return (const char*)path;
- }
- if (!path)
- {
- path = (char **)calloc(MAX_SEARCH_PATHS, sizeof(char **));
- }
- if (!list && !end)
- list = searchList();
- if (i >= (numsize))
- {
- debug("Increasing size for long PATH");
- tmp = (char **)calloc((MAX_SEARCH_PATHS + numsize), sizeof(char **));
- if (tmp)
- {
- memcpy(tmp, path, sizeof(char **) * numsize);
- free(path);
- path = tmp;
- numsize += MAX_SEARCH_PATHS;
- }
- else
- {
- return 0;
- }
- }
-
- while (!path[i] && !end)
- {
- path[i] = strsep((char **)&list, ":");
-
- if (path[i][0] == 0)
- path[i] = 0;
- end = (list == 0);
- }
- return path[i];
-}
-
-static const char *getFullPath(int i, const char *file)
-{
- static char buf[PATH_MAX];
- const char *path = getSearchPath(i);
- if (path)
- {
- snprintf(buf, PATH_MAX, "%s/%s", path, file);
- }
- return path ? buf : 0;
-}
-
-/* Given a file name, try to determine the full path for that file. Starts
- * its search in the current directory, and then tries all paths in the
- * search list in the order they are specified there.
- */
-static const struct stat *findFile(const char *file, const char **fullPath)
-{
- int i = 0;
- static struct stat sbuf;
- char *fileName;
- debug("finding file %s", file);
- *fullPath = file;
- if (0 == stat(file, &sbuf))
- return &sbuf;
- if (strchr(file, '/'))
- return 0; /* If the path had a / we don't look in env var places */
- fileName = NULL;
- if (!fileName)
- fileName = (char *)file;
- while ((*fullPath = getFullPath(i++, fileName)))
- {
- if (0 == stat(*fullPath, &sbuf))
- return &sbuf;
- }
- ;
- return 0;
-}
-
-/* Determine whether a given dlstatus is valid or not */
-static int isValidStatus(struct dlstatus *status)
-{
- /* Walk the list to verify status is contained in it */
- struct dlstatus *dls = stqueue;
- while (dls && status != dls)
- dls = dls->next;
- if (dls == 0)
- error("invalid handle");
- else if ((dls->module == 0) || (dls->refs == 0))
- error("handle to closed library");
- else
- return TRUE;
- return FALSE;
-}
-
-static inline int isFlagSet(int mode, int flag)
-{
- return (mode & flag) == flag;
-}
-
-static struct dlstatus *lookupStatus(const struct stat *sbuf)
-{
- struct dlstatus *dls = stqueue;
- debug("looking for status");
- while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0
- || sbuf->st_dev != dls->device || sbuf->st_ino != dls->inode))
- dls = dls->next;
- return dls;
-}
-
-static void insertStatus(struct dlstatus *dls, const struct stat *sbuf)
-{
- debug("inserting status");
- dls->inode = sbuf->st_ino;
- dls->device = sbuf->st_dev;
- dls->refs = 0;
- dls->mode = 0;
- if ((dls->flags & DL_IN_LIST) == 0)
- {
- dls->next = stqueue;
- stqueue = dls;
- dls->flags |= DL_IN_LIST;
- }
-}
-
-static struct dlstatus *allocStatus()
-{
- struct dlstatus *dls;
-#ifdef REUSE_STATUS
- dls = stqueue;
- while (dls && dls->module)
- dls = dls->next;
- if (!dls)
-#endif
- dls = malloc(sizeof(*dls));
- dls->flags = 0;
- return dls;
-}
-
-static int promoteLocalToGlobal(struct dlstatus *dls)
-{
- static int (*p) (NSModule module) = 0;
- debug("promoting");
- if (!p)
- _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (unsigned long *)&p);
- return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module));
-}
-
-static void *reference(struct dlstatus *dls, int mode)
-{
- if (dls)
- {
- if (dls->module == MAGIC_DYLIB_MOD && !isFlagSet(mode, RTLD_GLOBAL))
- {
- warning("trying to open a .dylib with RTLD_LOCAL");
- error("unable to open a .dylib with RTLD_LOCAL");
- return NULL;
- }
- if (isFlagSet(mode, RTLD_GLOBAL) &&
- !isFlagSet(dls->mode, RTLD_GLOBAL) && !promoteLocalToGlobal(dls))
- {
- error("unable to promote local module to global");
- return NULL;
- }
- dls->mode |= mode;
- dls->refs++;
- }
- else
- debug("reference called with NULL argument");
-
- return dls;
-}
-
-static const struct mach_header *my_find_image(const char *name)
-{
- const struct mach_header *mh = 0;
- const char *id = NULL;
- int i = _dyld_image_count();
- int j;
- mh = (struct mach_header *)
- dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
- NSADDIMAGE_OPTION_RETURN_ON_ERROR);
- if (!mh)
- {
- for (j = 0; j < i; j++)
- {
- id = _dyld_get_image_name(j);
- if (!strcmp(id, name))
- {
- mh = _dyld_get_image_header(j);
- break;
- }
- }
- }
- return mh;
-}
-
-/*
- * dyld adds libraries by first adding the directly dependant libraries in link order, and
- * then adding the dependencies for those libraries, so we should do the same... but we don't
- * bother adding the extra dependencies, if the symbols are neither in the loaded image nor
- * any of it's direct dependencies, then it probably isn't there.
- */
-NSSymbol *search_linked_libs(const struct mach_header * mh, const char *symbol)
-{
- int n;
- struct load_command *lc = 0;
- struct mach_header *wh;
- NSSymbol *nssym = 0;
- if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
- {
- lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
- for (n = 0; n < mh->ncmds; n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
- {
- if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
- {
- if ((wh = (struct mach_header *)
- my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
- (char *)lc))))
- {
- if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol))
- {
- nssym = dyld_NSLookupSymbolInImage(wh,
- symbol,
- NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
- NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
- break;
- }
- }
- }
- }
- if ((!nssym) && NSIsSymbolNameDefined(symbol))
- {
- /* I've never seen this debug message...*/
- debug("Symbol \"%s\" is defined but was not found", symbol);
- }
- }
- return nssym;
-}
-
-/* Up to the caller to free() returned string */
-static inline const char *dyld_error_str()
-{
- NSLinkEditErrors dylder;
- int dylderno;
- const char *dylderrstr;
- const char *dyldfile;
- const char* retStr = NULL;
- NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr);
- if (dylderrstr && strlen(dylderrstr))
- {
- retStr = malloc(strlen(dylderrstr) +1);
- strcpy((char*)retStr,dylderrstr);
- }
- return retStr;
-}
-
-static void *dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError)
-{
- NSSymbol *nssym = 0;
- void *caller = __builtin_return_address(1); /* Be *very* careful about inlining */
- const struct mach_header *caller_mh = 0;
- const char* savedErrorStr = NULL;
- resetdlerror();
-#ifndef RTLD_SELF
-#define RTLD_SELF ((void *) -3)
-#endif
- if (NULL == dls)
- dls = RTLD_SELF;
- if ((RTLD_NEXT == dls) || (RTLD_SELF == dls))
- {
- if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
- {
- caller_mh = image_for_address(caller);
- if (RTLD_SELF == dls)
- {
- /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE
- * But it appears to work anyway, and looking at the code in dyld_libfuncs.c
- * this is acceptable.
- */
- if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol))
- {
- nssym = dyld_NSLookupSymbolInImage(caller_mh,
- symbol,
- NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
- NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
- }
- }
- if (!nssym)
- {
- if (RTLD_SELF == dls)
- savedErrorStr = dyld_error_str();
- nssym = search_linked_libs(caller_mh, symbol);
- }
- }
- else
- {
- if (canSetError)
- error("RTLD_SELF and RTLD_NEXT are not supported");
- return NULL;
- }
- }
- if (!nssym)
- {
-
- if (RTLD_DEFAULT == dls)
- {
- dls = &mainStatus;
- }
- if (!isValidStatus(dls))
- return NULL;
-
- if (dls->module != MAGIC_DYLIB_MOD)
- {
- nssym = NSLookupSymbolInModule(dls->module, symbol);
- if (!nssym && NSIsSymbolNameDefined(symbol))
- {
- debug("Searching dependencies");
- savedErrorStr = dyld_error_str();
- nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol);
- }
- }
- else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
- {
- if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol))
- {
- nssym = dyld_NSLookupSymbolInImage(dls->lib,
- symbol,
- NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
- NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
- }
- else if (NSIsSymbolNameDefined(symbol))
- {
- debug("Searching dependencies");
- savedErrorStr = dyld_error_str();
- nssym = search_linked_libs(dls->lib, symbol);
- }
- }
- else if (dls->module == MAGIC_DYLIB_MOD)
- {
- /* Global context, use NSLookupAndBindSymbol */
- if (NSIsSymbolNameDefined(symbol))
- {
- /* There doesn't seem to be a return on error option for this call???
- this is potentially broken, if binding fails, it will improperly
- exit the application. */
- nssym = NSLookupAndBindSymbol(symbol);
- }
- else
- {
- if (savedErrorStr)
- free((char*)savedErrorStr);
- savedErrorStr = malloc(256);
- snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol);
- }
- }
- }
- /* Error reporting */
- if (!nssym)
- {
- if (!savedErrorStr || !strlen(savedErrorStr))
- {
- if (savedErrorStr)
- free((char*)savedErrorStr);
- savedErrorStr = malloc(256);
- snprintf((char*)savedErrorStr, 256,"Symbol \"%s\" not found",symbol);
- }
- if (canSetError)
- {
- error(savedErrorStr);
- }
- else
- {
- debug(savedErrorStr);
- }
- if (savedErrorStr)
- free((char*)savedErrorStr);
- return NULL;
- }
- return NSAddressOfSymbol(nssym);
-}
-
-static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode)
-{
- NSObjectFileImage ofi = 0;
- NSObjectFileImageReturnCode ofirc;
- struct dlstatus *dls;
- NSLinkEditErrors ler;
- int lerno;
- const char *errstr;
- const char *file;
- void (*init) (void);
- ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
- switch (ofirc)
- {
- case NSObjectFileImageSuccess:
- break;
- case NSObjectFileImageInappropriateFile:
- if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
- {
- if (!isFlagSet(mode, RTLD_GLOBAL))
- {
- warning("trying to open a .dylib with RTLD_LOCAL");
- error("unable to open this file with RTLD_LOCAL");
- return NULL;
- }
- }
- else
- {
- error("opening this file is unsupported on this system");
- return NULL;
- }
- break;
- case NSObjectFileImageFailure:
- error("object file setup failure");
- return NULL;
- case NSObjectFileImageArch:
- error("no object for this architecture");
- return NULL;
- case NSObjectFileImageFormat:
- error("bad object file format");
- return NULL;
- case NSObjectFileImageAccess:
- error("can't read object file");
- return NULL;
- default:
- error("unknown error from NSCreateObjectFileImageFromFile()");
- return NULL;
- }
- dls = lookupStatus(sbuf);
- if (!dls)
- {
- dls = allocStatus();
- }
- if (!dls)
- {
- error("unable to allocate memory");
- return NULL;
- }
- dls->lib = 0;
- if (ofirc == NSObjectFileImageInappropriateFile)
- {
- if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR)))
- {
- debug("Dynamic lib loaded at %ld", dls->lib);
- ofi = MAGIC_DYLIB_OFI;
- dls->module = MAGIC_DYLIB_MOD;
- ofirc = NSObjectFileImageSuccess;
- /* Although it is possible with a bit of work to modify this so it works and
- functions with RTLD_NOW, I don't deem it necessary at the moment */
- }
- if (!(dls->module))
- {
- NSLinkEditError(&ler, &lerno, &file, &errstr);
- if (!errstr || (!strlen(errstr)))
- error("Can't open this file type");
- else
- error(errstr);
- if ((dls->flags & DL_IN_LIST) == 0)
- {
- free(dls);
- }
- return NULL;
- }
- }
- else
- {
- dls->module = NSLinkModule(ofi, path,
- NSLINKMODULE_OPTION_RETURN_ON_ERROR |
- NSLINKMODULE_OPTION_PRIVATE |
- (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0));
- NSDestroyObjectFileImage(ofi);
- if (dls->module)
- {
- dls->lib = get_mach_header_from_NSModule(dls->module);
- }
- }
- if (!dls->module)
- {
- NSLinkEditError(&ler, &lerno, &file, &errstr);
- if ((dls->flags & DL_IN_LIST) == 0)
- {
- free(dls);
- }
- error(errstr);
- return NULL;
- }
-
- insertStatus(dls, sbuf);
- dls = reference(dls, mode);
- if ((init = dlsymIntern(dls, "__init", 0)))
- {
- debug("calling _init()");
- init();
- }
- return dls;
-}
-
-static void dlcompat_init_func(void)
-{
- static int inited = 0;
- if (!inited)
- {
- inited = 1;
- _dyld_func_lookup("__dyld_NSAddImage", (unsigned long *)&dyld_NSAddImage);
- _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",
- (unsigned long *)&dyld_NSIsSymbolNameDefinedInImage);
- _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (unsigned long *)&dyld_NSLookupSymbolInImage);
- if (pthread_mutex_init(&dlcompat_mutex, NULL))
- exit(1);
- if (pthread_key_create(&dlerror_key, &dlerrorfree))
- exit(1);
- /* And be neat and tidy and clean up after ourselves */
- atexit(dlcompat_cleanup);
- }
-}
-
-#if 0
-#pragma CALL_ON_LOAD dlcompat_init_func
-#endif
-
-static void dlcompat_cleanup(void)
-{
- struct dlstatus *dls;
- struct dlstatus *next;
- char *data;
- data = (char *)searchList();
- if ( data )
- free( data );
- data = (char *)getSearchPath(-1);
- if ( data )
- free( data );
- pthread_mutex_destroy(&dlcompat_mutex);
- pthread_key_delete(dlerror_key);
- next = stqueue;
- while (next && (next != &mainStatus))
- {
- dls = next;
- next = dls->next;
- free(dls);
- }
-}
-
-static void resetdlerror()
-{
- struct dlthread *tss;
- tss = pthread_getspecific(dlerror_key);
- tss->errset = 0;
-}
-
-static void dlerrorfree(void *data)
-{
- free(data);
-}
-
-/* We kind of want a recursive lock here, but meet a little trouble
- * because they are not available pre OS X 10.2, so we fake it
- * using thread specific storage to keep a lock count
- */
-static inline void dolock(void)
-{
- int err = 0;
- struct dlthread *tss;
- tss = pthread_getspecific(dlerror_key);
- if (!tss)
- {
- tss = malloc(sizeof(struct dlthread));
- tss->lockcnt = 0;
- tss->errset = 0;
- if (pthread_setspecific(dlerror_key, tss))
- {
- fprintf(stderr,"dlcompat: pthread_setspecific failed\n");
- exit(1);
- }
- }
- if (!tss->lockcnt)
- err = pthread_mutex_lock(&dlcompat_mutex);
- tss->lockcnt = tss->lockcnt +1;
- if (err)
- exit(err);
-}
-
-static inline void dounlock(void)
-{
- int err = 0;
- struct dlthread *tss;
- tss = pthread_getspecific(dlerror_key);
- tss->lockcnt = tss->lockcnt -1;
- if (!tss->lockcnt)
- err = pthread_mutex_unlock(&dlcompat_mutex);
- if (err)
- exit(err);
-}
-
-void *dlopen(const char *path, int mode)
-{
- const struct stat *sbuf;
- struct dlstatus *dls;
- const char *fullPath;
- dlcompat_init_func(); /* Just in case */
- dolock();
- resetdlerror();
- if (!path)
- {
- dls = &mainStatus;
- goto dlopenok;
- }
- if (!(sbuf = findFile(path, &fullPath)))
- {
- error("file \"%s\" not found", path);
- goto dlopenerror;
- }
- /* Now checks that it hasn't been closed already */
- if ((dls = lookupStatus(sbuf)) && (dls->refs > 0))
- {
- /* debug("status found"); */
- dls = reference(dls, mode);
- goto dlopenok;
- }
-#ifdef RTLD_NOLOAD
- if (isFlagSet(mode, RTLD_NOLOAD))
- {
- error("no existing handle and RTLD_NOLOAD specified");
- goto dlopenerror;
- }
-#endif
- if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW))
- {
- error("how can I load something both RTLD_LAZY and RTLD_NOW?");
- goto dlopenerror;
- }
- dls = loadModule(fullPath, sbuf, mode);
-
- dlopenok:
- dounlock();
- return (void *)dls;
- dlopenerror:
- dounlock();
- return NULL;
-}
-
-#if !FINK_BUILD
-void *dlsym(void * dl_restrict handle, const char * dl_restrict symbol)
-{
- int sym_len = strlen(symbol);
- void *value = NULL;
- char *malloc_sym = NULL;
- dolock();
- malloc_sym = malloc(sym_len + 2);
- if (malloc_sym)
- {
- sprintf(malloc_sym, "_%s", symbol);
- value = dlsymIntern(handle, malloc_sym, 1);
- free(malloc_sym);
- }
- else
- {
- error("Unable to allocate memory");
- goto dlsymerror;
- }
- dounlock();
- return value;
- dlsymerror:
- dounlock();
- return NULL;
-}
-#endif
-
-#if FINK_BUILD
-
-void *dlsym_prepend_underscore(void *handle, const char *symbol)
-{
- void *answer;
- dolock();
- answer = dlsym_prepend_underscore_intern(handle, symbol);
- dounlock();
- return answer;
-}
-
-static void *dlsym_prepend_underscore_intern(void *handle, const char *symbol)
-{
-/*
- * A quick and easy way for porting packages which call dlsym(handle,"sym")
- * If the porter adds -Ddlsym=dlsym_prepend_underscore to the CFLAGS then
- * this function will be called, and will add the required underscore.
- *
- * Note that I haven't figured out yet which should be "standard", prepend
- * the underscore always, or not at all. These global functions need to go away
- * for opendarwin.
- */
- int sym_len = strlen(symbol);
- void *value = NULL;
- char *malloc_sym = NULL;
- malloc_sym = malloc(sym_len + 2);
- if (malloc_sym)
- {
- sprintf(malloc_sym, "_%s", symbol);
- value = dlsymIntern(handle, malloc_sym, 1);
- free(malloc_sym);
- }
- else
- {
- error("Unable to allocate memory");
- }
- return value;
-}
-
-void *dlsym_auto_underscore(void *handle, const char *symbol)
-{
- void *answer;
- dolock();
- answer = dlsym_auto_underscore_intern(handle, symbol);
- dounlock();
- return answer;
-
-}
-static void *dlsym_auto_underscore_intern(void *handle, const char *symbol)
-{
- struct dlstatus *dls = handle;
- void *addr = 0;
- addr = dlsymIntern(dls, symbol, 0);
- if (!addr)
- addr = dlsym_prepend_underscore_intern(handle, symbol);
- return addr;
-}
-
-
-void *dlsym(void * dl_restrict handle, const char * dl_restrict symbol)
-{
- struct dlstatus *dls = handle;
- void *addr = 0;
- dolock();
- addr = dlsymIntern(dls, symbol, 1);
- dounlock();
- return addr;
-}
-#endif
-
-int dlclose(void *handle)
-{
- struct dlstatus *dls = handle;
- dolock();
- resetdlerror();
- if (!isValidStatus(dls))
- {
- goto dlcloseerror;
- }
- if (dls->module == MAGIC_DYLIB_MOD)
- {
- const char *name;
- if (!dls->lib)
- {
- name = "global context";
- }
- else
- {
- name = get_lib_name(dls->lib);
- }
- warning("trying to close a .dylib!");
- error("Not closing \"%s\" - dynamic libraries cannot be closed", name);
- goto dlcloseerror;
- }
- if (!dls->module)
- {
- error("module already closed");
- goto dlcloseerror;
- }
-
- if (dls->refs == 1)
- {
- unsigned long options = 0;
- void (*fini) (void);
- if ((fini = dlsymIntern(dls, "__fini", 0)))
- {
- debug("calling _fini()");
- fini();
- }
-#ifdef __ppc__
- options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
-#endif
-#if 1
-/* Currently, if a module contains c++ static destructors and it is unloaded, we
- * get a segfault in atexit(), due to compiler and dynamic loader differences of
- * opinion, this works around that.
- * I really need a way to figure out from code if this is still necessary.
- */
- if ((const struct section *)NULL !=
- getsectbynamefromheader(get_mach_header_from_NSModule(dls->module),
- "__DATA", "__mod_term_func"))
- {
- options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
- }
-#endif
-#ifdef RTLD_NODELETE
- if (isFlagSet(dls->mode, RTLD_NODELETE))
- options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
-#endif
- if (!NSUnLinkModule(dls->module, options))
- {
- error("unable to unlink module");
- goto dlcloseerror;
- }
- dls->refs--;
- dls->module = 0;
- /* Note: the dlstatus struct dls is neither removed from the list
- * nor is the memory it occupies freed. This shouldn't pose a
- * problem in mostly all cases, though.
- */
- }
- dounlock();
- return 0;
- dlcloseerror:
- dounlock();
- return 1;
-}
-
-const char *dlerror(void)
-{
- struct dlthread *tss;
- char * err_str;
- tss = pthread_getspecific(dlerror_key);
- err_str = tss->errstr;
- tss = pthread_getspecific(dlerror_key);
- if (tss->errset == 0)
- return 0;
- tss->errset = 0;
- return (err_str );
-}
-
-/* Given an address, return the mach_header for the image containing it
- * or zero if the given address is not contained in any loaded images.
- */
-const struct mach_header *image_for_address(const void *address)
-{
- unsigned long i;
- unsigned long j;
- unsigned long count = _dyld_image_count();
- struct mach_header *mh = 0;
- struct load_command *lc = 0;
- unsigned long addr = NULL;
- for (i = 0; i < count; i++)
- {
- addr = (unsigned long)address - _dyld_get_image_vmaddr_slide(i);
- mh = _dyld_get_image_header(i);
- if (mh)
- {
- lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
- for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
- {
- if (LC_SEGMENT == lc->cmd &&
- addr >= ((struct segment_command *)lc)->vmaddr &&
- addr <
- ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
- {
- goto image_found;
- }
- }
- }
- mh = 0;
- }
- image_found:
- return mh;
-}
-
-int dladdr(const void * dl_restrict p, Dl_info * dl_restrict info)
-{
-/*
- FIXME: USe the routine image_for_address.
-*/
- unsigned long i;
- unsigned long j;
- unsigned long count = _dyld_image_count();
- struct mach_header *mh = 0;
- struct load_command *lc = 0;
- unsigned long addr = NULL;
- unsigned long table_off = (unsigned long)0;
- int found = 0;
- if (!info)
- return 0;
- dolock();
- resetdlerror();
- info->dli_fname = 0;
- info->dli_fbase = 0;
- info->dli_sname = 0;
- info->dli_saddr = 0;
-/* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com>
- * to darwin-development AT lists DOT apple DOT com and slightly modified
- */
- for (i = 0; i < count; i++)
- {
- addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
- mh = _dyld_get_image_header(i);
- if (mh)
- {
- lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
- for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
- {
- if (LC_SEGMENT == lc->cmd &&
- addr >= ((struct segment_command *)lc)->vmaddr &&
- addr <
- ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
- {
- info->dli_fname = _dyld_get_image_name(i);
- info->dli_fbase = (void *)mh;
- found = 1;
- break;
- }
- }
- if (found)
- break;
- }
- }
- if (!found)
- {
- dounlock();
- return 0;
- }
- lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
- for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
- {
- if (LC_SEGMENT == lc->cmd)
- {
- if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT"))
- break;
- }
- }
- table_off =
- ((unsigned long)((struct segment_command *)lc)->vmaddr) -
- ((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
- debug("table off %x", table_off);
-
- lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
- for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
- {
- if (LC_SYMTAB == lc->cmd)
- {
-
- struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off);
- unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
- struct nlist *nearest = NULL;
- unsigned long diff = 0xffffffff;
- unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off);
- debug("symtable %x", symtable);
- for (i = 0; i < numsyms; i++)
- {
- /* Ignore the following kinds of Symbols */
- if ((!symtable->n_value) /* Undefined */
- || (symtable->n_type >= N_PEXT) /* Debug symbol */
- || (!(symtable->n_type & N_EXT)) /* Local Symbol */
- )
- {
- symtable++;
- continue;
- }
- if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
- {
- diff = (unsigned long)symtable->n_value - addr;
- nearest = symtable;
- }
- symtable++;
- }
- if (nearest)
- {
- info->dli_saddr = nearest->n_value + ((void *)p - addr);
- info->dli_sname = (char *)(strtable + nearest->n_un.n_strx);
- }
- }
- }
- dounlock();
- return 1;
-}
-
-
-/*
- * Implement the dlfunc() interface, which behaves exactly the same as
- * dlsym() except that it returns a function pointer instead of a data
- * pointer. This can be used by applications to avoid compiler warnings
- * about undefined behavior, and is intended as prior art for future
- * POSIX standardization. This function requires that all pointer types
- * have the same representation, which is true on all platforms FreeBSD
- * runs on, but is not guaranteed by the C standard.
- */
-#if 0
-dlfunc_t dlfunc(void * dl_restrict handle, const char * dl_restrict symbol)
-{
- union
- {
- void *d;
- dlfunc_t f;
- } rv;
- int sym_len = strlen(symbol);
- char *malloc_sym = NULL;
- dolock();
- malloc_sym = malloc(sym_len + 2);
- if (malloc_sym)
- {
- sprintf(malloc_sym, "_%s", symbol);
- rv.d = dlsymIntern(handle, malloc_sym, 1);
- free(malloc_sym);
- }
- else
- {
- error("Unable to allocate memory");
- goto dlfuncerror;
- }
- dounlock();
- return rv.f;
- dlfuncerror:
- dounlock();
- return NULL;
-}
-#endif
diff --git a/1.4/main/dns.c b/1.4/main/dns.c
deleted file mode 100644
index d57e6227a..000000000
--- a/1.4/main/dns.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006 Thorsten Lockert
- *
- * Written by Thorsten Lockert <tholo@trollphone.org>
- *
- * Funding provided by Troll Phone Networks AS
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief DNS Support for Asterisk
- *
- * \author Thorsten Lockert <tholo@trollphone.org>
- *
- * \par Reference
- * - DNR SRV records http://www.ietf.org/rfc/rfc2782.txt
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <unistd.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/dns.h"
-#include "asterisk/endian.h"
-
-#define MAX_SIZE 4096
-
-/* The dns_HEADER structure definition below originated
- in the arpa/nameser.h header file distributed with ISC
- BIND, which contains the following copyright and license
- notices:
-
- * ++Copyright++ 1983, 1989, 1993
- * -
- * Copyright (c) 1983, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-typedef struct {
- unsigned id:16; /*!< query identification number */
-#if __BYTE_ORDER == __BIG_ENDIAN
- /* fields in third byte */
- unsigned qr:1; /*!< response flag */
- unsigned opcode:4; /*!< purpose of message */
- unsigned aa:1; /*!< authoritive answer */
- unsigned tc:1; /*!< truncated message */
- unsigned rd:1; /*!< recursion desired */
- /* fields in fourth byte */
- unsigned ra:1; /*!< recursion available */
- unsigned unused:1; /*!< unused bits (MBZ as of 4.9.3a3) */
- unsigned ad:1; /*!< authentic data from named */
- unsigned cd:1; /*!< checking disabled by resolver */
- unsigned rcode:4; /*!< response code */
-#endif
-#if __BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __PDP_ENDIAN
- /* fields in third byte */
- unsigned rd:1; /*!< recursion desired */
- unsigned tc:1; /*!< truncated message */
- unsigned aa:1; /*!< authoritive answer */
- unsigned opcode:4; /*!< purpose of message */
- unsigned qr:1; /*!< response flag */
- /* fields in fourth byte */
- unsigned rcode:4; /*!< response code */
- unsigned cd:1; /*!< checking disabled by resolver */
- unsigned ad:1; /*!< authentic data from named */
- unsigned unused:1; /*!< unused bits (MBZ as of 4.9.3a3) */
- unsigned ra:1; /*!< recursion available */
-#endif
- /* remaining bytes */
- unsigned qdcount:16; /*!< number of question entries */
- unsigned ancount:16; /*!< number of answer entries */
- unsigned nscount:16; /*!< number of authority entries */
- unsigned arcount:16; /*!< number of resource entries */
-} dns_HEADER;
-
-struct dn_answer {
- unsigned short rtype;
- unsigned short class;
- unsigned int ttl;
- unsigned short size;
-} __attribute__ ((__packed__));
-
-static int skip_name(unsigned char *s, int len)
-{
- int x = 0;
-
- while (x < len) {
- if (*s == '\0') {
- s++;
- x++;
- break;
- }
- if ((*s & 0xc0) == 0xc0) {
- s += 2;
- x += 2;
- break;
- }
- x += *s + 1;
- s += *s + 1;
- }
- if (x >= len)
- return -1;
- return x;
-}
-
-/*! \brief Parse DNS lookup result, call callback */
-static int dns_parse_answer(void *context,
- int class, int type, unsigned char *answer, int len,
- int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
-{
- unsigned char *fullanswer = answer;
- struct dn_answer *ans;
- dns_HEADER *h;
- int res;
- int x;
-
- h = (dns_HEADER *)answer;
- answer += sizeof(dns_HEADER);
- len -= sizeof(dns_HEADER);
-
- for (x = 0; x < ntohs(h->qdcount); x++) {
- if ((res = skip_name(answer, len)) < 0) {
- ast_log(LOG_WARNING, "Couldn't skip over name\n");
- return -1;
- }
- answer += res + 4; /* Skip name and QCODE / QCLASS */
- len -= res + 4;
- if (len < 0) {
- ast_log(LOG_WARNING, "Strange query size\n");
- return -1;
- }
- }
-
- for (x = 0; x < ntohs(h->ancount); x++) {
- if ((res = skip_name(answer, len)) < 0) {
- ast_log(LOG_WARNING, "Failed skipping name\n");
- return -1;
- }
- answer += res;
- len -= res;
- ans = (struct dn_answer *)answer;
- answer += sizeof(struct dn_answer);
- len -= sizeof(struct dn_answer);
- if (len < 0) {
- ast_log(LOG_WARNING, "Strange result size\n");
- return -1;
- }
- if (len < 0) {
- ast_log(LOG_WARNING, "Length exceeds frame\n");
- return -1;
- }
-
- if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
- if (callback) {
- if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
- ast_log(LOG_WARNING, "Failed to parse result\n");
- return -1;
- }
- if (res > 0)
- return 1;
- }
- }
- answer += ntohs(ans->size);
- len -= ntohs(ans->size);
- }
- return 0;
-}
-
-#ifndef HAVE_RES_NINIT
-AST_MUTEX_DEFINE_STATIC(res_lock);
-#endif
-
-/*! \brief Lookup record in DNS
-\note Asterisk DNS is synchronus at this time. This means that if your DNS does
-not work properly, Asterisk might not start properly or a channel may lock.
-*/
-int ast_search_dns(void *context,
- const char *dname, int class, int type,
- int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
-{
-#ifdef HAVE_RES_NINIT
- struct __res_state dnsstate;
-#endif
- unsigned char answer[MAX_SIZE];
- int res, ret = -1;
-
-#ifdef HAVE_RES_NINIT
- memset(&dnsstate, 0, sizeof(dnsstate));
- res_ninit(&dnsstate);
- res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer));
-#else
- ast_mutex_lock(&res_lock);
- res_init();
- res = res_search(dname, class, type, answer, sizeof(answer));
-#endif
- if (res > 0) {
- if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) {
- ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname);
- ret = -1;
- }
- else if (res == 0) {
- ast_log(LOG_DEBUG, "No matches found in DNS for %s\n", dname);
- ret = 0;
- }
- else
- ret = 1;
- }
-#ifdef HAVE_RES_NINIT
-#ifdef HAVE_RES_NDESTROY
- res_ndestroy(&dnsstate);
-#else
- res_nclose(&dnsstate);
-#endif
-#else
-#ifndef __APPLE__
- res_close();
-#endif
- ast_mutex_unlock(&res_lock);
-#endif
-
- return ret;
-}
diff --git a/1.4/main/dnsmgr.c b/1.4/main/dnsmgr.c
deleted file mode 100644
index 5598523f8..000000000
--- a/1.4/main/dnsmgr.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005-2006, Kevin P. Fleming
- *
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- *
- * \brief Background DNS update manager
- *
- * \author Kevin P. Fleming <kpfleming@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <regex.h>
-#include <signal.h>
-
-#include "asterisk/dnsmgr.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/utils.h"
-#include "asterisk/config.h"
-#include "asterisk/logger.h"
-#include "asterisk/sched.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-
-static struct sched_context *sched;
-static int refresh_sched = -1;
-static pthread_t refresh_thread = AST_PTHREADT_NULL;
-
-struct ast_dnsmgr_entry {
- /*! where we will store the resulting address */
- struct in_addr *result;
- /*! the last result, used to check if address has changed */
- struct in_addr last;
- /*! Set to 1 if the entry changes */
- int changed:1;
- ast_mutex_t lock;
- AST_LIST_ENTRY(ast_dnsmgr_entry) list;
- /*! just 1 here, but we use calloc to allocate the correct size */
- char name[1];
-};
-
-static AST_LIST_HEAD_STATIC(entry_list, ast_dnsmgr_entry);
-
-AST_MUTEX_DEFINE_STATIC(refresh_lock);
-
-#define REFRESH_DEFAULT 300
-
-static int enabled;
-static int refresh_interval;
-
-struct refresh_info {
- struct entry_list *entries;
- int verbose;
- unsigned int regex_present:1;
- regex_t filter;
-};
-
-static struct refresh_info master_refresh_info = {
- .entries = &entry_list,
- .verbose = 0,
-};
-
-struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct in_addr *result)
-{
- struct ast_dnsmgr_entry *entry;
-
- if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, sizeof(*entry) + strlen(name))))
- return NULL;
-
- entry->result = result;
- ast_mutex_init(&entry->lock);
- strcpy(entry->name, name);
- memcpy(&entry->last, result, sizeof(entry->last));
-
- AST_LIST_LOCK(&entry_list);
- AST_LIST_INSERT_HEAD(&entry_list, entry, list);
- AST_LIST_UNLOCK(&entry_list);
-
- return entry;
-}
-
-void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
-{
- if (!entry)
- return;
-
- AST_LIST_LOCK(&entry_list);
- AST_LIST_REMOVE(&entry_list, entry, list);
- AST_LIST_UNLOCK(&entry_list);
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "removing dns manager for '%s'\n", entry->name);
-
- ast_mutex_destroy(&entry->lock);
- free(entry);
-}
-
-int ast_dnsmgr_lookup(const char *name, struct in_addr *result, struct ast_dnsmgr_entry **dnsmgr)
-{
- struct ast_hostent ahp;
- struct hostent *hp;
-
- if (ast_strlen_zero(name) || !result || !dnsmgr)
- return -1;
-
- if (*dnsmgr && !strcasecmp((*dnsmgr)->name, name))
- return 0;
-
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "doing dnsmgr_lookup for '%s'\n", name);
-
- /* if it's actually an IP address and not a name,
- there's no need for a managed lookup */
- if (inet_aton(name, result))
- return 0;
-
- /* do a lookup now but add a manager so it will automagically get updated in the background */
- if ((hp = ast_gethostbyname(name, &ahp)))
- memcpy(result, hp->h_addr, sizeof(result));
-
- /* if dnsmgr is not enable don't bother adding an entry */
- if (!enabled)
- return 0;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "adding dns manager for '%s'\n", name);
- *dnsmgr = ast_dnsmgr_get(name, result);
- return !*dnsmgr;
-}
-
-/*
- * Refresh a dnsmgr entry
- */
-static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
-{
- struct ast_hostent ahp;
- struct hostent *hp;
- char iabuf[INET_ADDRSTRLEN];
- char iabuf2[INET_ADDRSTRLEN];
- struct in_addr tmp;
- int changed = 0;
-
- ast_mutex_lock(&entry->lock);
- if (verbose && (option_verbose > 2))
- ast_verbose(VERBOSE_PREFIX_2 "refreshing '%s'\n", entry->name);
-
- if ((hp = ast_gethostbyname(entry->name, &ahp))) {
- /* check to see if it has changed, do callback if requested (where de callback is defined ????) */
- memcpy(&tmp, hp->h_addr, sizeof(tmp));
- if (tmp.s_addr != entry->last.s_addr) {
- ast_copy_string(iabuf, ast_inet_ntoa(entry->last), sizeof(iabuf));
- ast_copy_string(iabuf2, ast_inet_ntoa(tmp), sizeof(iabuf2));
- ast_log(LOG_NOTICE, "host '%s' changed from %s to %s\n",
- entry->name, iabuf, iabuf2);
- memcpy(entry->result, hp->h_addr, sizeof(entry->result));
- memcpy(&entry->last, hp->h_addr, sizeof(entry->last));
- changed = entry->changed = 1;
- }
-
- }
- ast_mutex_unlock(&entry->lock);
- return changed;
-}
-
-int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
-{
- return dnsmgr_refresh(entry, 0);
-}
-
-/*
- * Check if dnsmgr entry has changed from since last call to this function
- */
-int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry)
-{
- int changed;
-
- ast_mutex_lock(&entry->lock);
-
- changed = entry->changed;
- entry->changed = 0;
-
- ast_mutex_unlock(&entry->lock);
-
- return changed;
-}
-
-static void *do_refresh(void *data)
-{
- for (;;) {
- pthread_testcancel();
- usleep((ast_sched_wait(sched)*1000));
- pthread_testcancel();
- ast_sched_runq(sched);
- }
- return NULL;
-}
-
-static int refresh_list(const void *data)
-{
- struct refresh_info *info = (struct refresh_info *)data;
- struct ast_dnsmgr_entry *entry;
-
- /* if a refresh or reload is already in progress, exit now */
- if (ast_mutex_trylock(&refresh_lock)) {
- if (info->verbose)
- ast_log(LOG_WARNING, "DNS Manager refresh already in progress.\n");
- return -1;
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "Refreshing DNS lookups.\n");
- AST_LIST_LOCK(info->entries);
- AST_LIST_TRAVERSE(info->entries, entry, list) {
- if (info->regex_present && regexec(&info->filter, entry->name, 0, NULL, 0))
- continue;
-
- dnsmgr_refresh(entry, info->verbose);
- }
- AST_LIST_UNLOCK(info->entries);
-
- ast_mutex_unlock(&refresh_lock);
-
- /* automatically reschedule based on the interval */
- return refresh_interval * 1000;
-}
-
-void dnsmgr_start_refresh(void)
-{
- if (refresh_sched > -1) {
- AST_SCHED_DEL(sched, refresh_sched);
- refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
- }
-}
-
-static int do_reload(int loading);
-
-static int handle_cli_reload(int fd, int argc, char *argv[])
-{
- if (argc > 2)
- return RESULT_SHOWUSAGE;
-
- do_reload(0);
- return 0;
-}
-
-static int handle_cli_refresh(int fd, int argc, char *argv[])
-{
- struct refresh_info info = {
- .entries = &entry_list,
- .verbose = 1,
- };
-
- if (argc > 3)
- return RESULT_SHOWUSAGE;
-
- if (argc == 3) {
- if (regcomp(&info.filter, argv[2], REG_EXTENDED | REG_NOSUB))
- return RESULT_SHOWUSAGE;
- else
- info.regex_present = 1;
- }
-
- refresh_list(&info);
-
- if (info.regex_present)
- regfree(&info.filter);
-
- return 0;
-}
-
-static int handle_cli_status(int fd, int argc, char *argv[])
-{
- int count = 0;
- struct ast_dnsmgr_entry *entry;
-
- if (argc > 2)
- return RESULT_SHOWUSAGE;
-
- ast_cli(fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled");
- ast_cli(fd, "Refresh Interval: %d seconds\n", refresh_interval);
- AST_LIST_LOCK(&entry_list);
- AST_LIST_TRAVERSE(&entry_list, entry, list)
- count++;
- AST_LIST_UNLOCK(&entry_list);
- ast_cli(fd, "Number of entries: %d\n", count);
-
- return 0;
-}
-
-static struct ast_cli_entry cli_reload = {
- { "dnsmgr", "reload", NULL },
- handle_cli_reload, "Reloads the DNS manager configuration",
- "Usage: dnsmgr reload\n"
- " Reloads the DNS manager configuration.\n"
-};
-
-static struct ast_cli_entry cli_refresh = {
- { "dnsmgr", "refresh", NULL },
- handle_cli_refresh, "Performs an immediate refresh",
- "Usage: dnsmgr refresh [pattern]\n"
- " Peforms an immediate refresh of the managed DNS entries.\n"
- " Optional regular expression pattern is used to filter the entries to refresh.\n",
-};
-
-static struct ast_cli_entry cli_status = {
- { "dnsmgr", "status", NULL },
- handle_cli_status, "Display the DNS manager status",
- "Usage: dnsmgr status\n"
- " Displays the DNS manager status.\n"
-};
-
-int dnsmgr_init(void)
-{
- if (!(sched = sched_context_create())) {
- ast_log(LOG_ERROR, "Unable to create schedule context.\n");
- return -1;
- }
- ast_cli_register(&cli_reload);
- ast_cli_register(&cli_status);
- return do_reload(1);
-}
-
-int dnsmgr_reload(void)
-{
- return do_reload(0);
-}
-
-static int do_reload(int loading)
-{
- struct ast_config *config;
- const char *interval_value;
- const char *enabled_value;
- int interval;
- int was_enabled;
- int res = -1;
-
- /* ensure that no refresh cycles run while the reload is in progress */
- ast_mutex_lock(&refresh_lock);
-
- /* reset defaults in preparation for reading config file */
- refresh_interval = REFRESH_DEFAULT;
- was_enabled = enabled;
- enabled = 0;
-
- AST_SCHED_DEL(sched, refresh_sched);
-
- if ((config = ast_config_load("dnsmgr.conf"))) {
- if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
- enabled = ast_true(enabled_value);
- }
- if ((interval_value = ast_variable_retrieve(config, "general", "refreshinterval"))) {
- if (sscanf(interval_value, "%d", &interval) < 1)
- ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", interval_value);
- else if (interval < 0)
- ast_log(LOG_WARNING, "Invalid refresh interval '%d' specified, using default\n", interval);
- else
- refresh_interval = interval;
- }
- ast_config_destroy(config);
- }
-
- if (enabled && refresh_interval)
- ast_log(LOG_NOTICE, "Managed DNS entries will be refreshed every %d seconds.\n", refresh_interval);
-
- /* if this reload enabled the manager, create the background thread
- if it does not exist */
- if (enabled) {
- if (!was_enabled && (refresh_thread == AST_PTHREADT_NULL)) {
- if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
- ast_log(LOG_ERROR, "Unable to start refresh thread.\n");
- }
- ast_cli_register(&cli_refresh);
- }
- /* make a background refresh happen right away */
- refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
- res = 0;
- }
- /* if this reload disabled the manager and there is a background thread,
- kill it */
- else if (!enabled && was_enabled && (refresh_thread != AST_PTHREADT_NULL)) {
- /* wake up the thread so it will exit */
- pthread_cancel(refresh_thread);
- pthread_kill(refresh_thread, SIGURG);
- pthread_join(refresh_thread, NULL);
- refresh_thread = AST_PTHREADT_NULL;
- ast_cli_unregister(&cli_refresh);
- res = 0;
- }
- else
- res = 0;
-
- ast_mutex_unlock(&refresh_lock);
-
- return res;
-}
diff --git a/1.4/main/dsp.c b/1.4/main/dsp.c
deleted file mode 100644
index 3caf65027..000000000
--- a/1.4/main/dsp.c
+++ /dev/null
@@ -1,1819 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
- * DTMF detector.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Convenience Signal Processing routines
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Steve Underwood <steveu@coppice.org>
- */
-
-/* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
-/*
- tone_detect.c - General telephony tone detection, and specific
- detection of DTMF.
-
- Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
-
- Despite my general liking of the GPL, I place this code in the
- public domain for the benefit of all mankind - even the slimy
- ones who might try to proprietize my work and use it to my
- detriment.
-*/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <math.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/dsp.h"
-#include "asterisk/ulaw.h"
-#include "asterisk/alaw.h"
-#include "asterisk/utils.h"
-
-/*! Number of goertzels for progress detect */
-enum gsamp_size {
- GSAMP_SIZE_NA = 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
- GSAMP_SIZE_CR = 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */
- GSAMP_SIZE_UK = 160 /*!< UK disconnect goertzel feed - should trigger 400hz */
-};
-
-enum prog_mode {
- PROG_MODE_NA = 0,
- PROG_MODE_CR,
- PROG_MODE_UK
-};
-
-enum freq_index {
- /*! For US modes { */
- HZ_350 = 0,
- HZ_440,
- HZ_480,
- HZ_620,
- HZ_950,
- HZ_1400,
- HZ_1800, /*!< } */
-
- /*! For CR/BR modes */
- HZ_425 = 0,
-
- /*! For UK mode */
- HZ_400 = 0
-};
-
-static struct progalias {
- char *name;
- enum prog_mode mode;
-} aliases[] = {
- { "us", PROG_MODE_NA },
- { "ca", PROG_MODE_NA },
- { "cr", PROG_MODE_CR },
- { "br", PROG_MODE_CR },
- { "uk", PROG_MODE_UK },
-};
-
-static struct progress {
- enum gsamp_size size;
- int freqs[7];
-} modes[] = {
- { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
- { GSAMP_SIZE_CR, { 425 } }, /*!< Costa Rica, Brazil */
- { GSAMP_SIZE_UK, { 400 } }, /*!< UK */
-};
-
-#define DEFAULT_THRESHOLD 512
-
-enum busy_detect {
- BUSY_PERCENT = 10, /*!< The percentage difference between the two last silence periods */
- BUSY_PAT_PERCENT = 7, /*!< The percentage difference between measured and actual pattern */
- BUSY_THRESHOLD = 100, /*!< Max number of ms difference between max and min times in busy */
- BUSY_MIN = 75, /*!< Busy must be at least 80 ms in half-cadence */
- BUSY_MAX =3100 /*!< Busy can't be longer than 3100 ms in half-cadence */
-};
-
-/*! Remember last 15 units */
-#define DSP_HISTORY 15
-
-/*! Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */
-#define FAX_DETECT
-
-#define TONE_THRESH 10.0 /*!< How much louder the tone should be than channel energy */
-#define TONE_MIN_THRESH 1e8 /*!< How much tone there should be at least to attempt */
-
-/*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
-enum gsamp_thresh {
- THRESH_RING = 8, /*!< Need at least 150ms ring to accept */
- THRESH_TALK = 2, /*!< Talk detection does not work continuously */
- THRESH_BUSY = 4, /*!< Need at least 80ms to accept */
- THRESH_CONGESTION = 4, /*!< Need at least 80ms to accept */
- THRESH_HANGUP = 60, /*!< Need at least 1300ms to accept hangup */
- THRESH_RING2ANSWER = 300 /*!< Timeout from start of ring to answer (about 6600 ms) */
-};
-
-#define MAX_DTMF_DIGITS 128
-
-/* Basic DTMF specs:
- *
- * Minimum tone on = 40ms
- * Minimum tone off = 50ms
- * Maximum digit rate = 10 per second
- * Normal twist <= 8dB accepted
- * Reverse twist <= 4dB accepted
- * S/N >= 15dB will detect OK
- * Attenuation <= 26dB will detect OK
- * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
- */
-
-#define DTMF_THRESHOLD 8.0e7
-#define FAX_THRESHOLD 8.0e7
-#define FAX_2ND_HARMONIC 2.0 /* 4dB */
-
-#ifdef RADIO_RELAX
-#define DTMF_NORMAL_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 11.3 : 6.3) /* 8dB sph 12.3 was 6.3 */
-#define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 9.5 : 2.5) /* 4dB normal sph 12.5 : 5.5 was 6.5 : 2.5 */
-#define DTMF_RELATIVE_PEAK_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 3.3 : 6.3) /* 8dB sph was 6.3 */
-#define DTMF_RELATIVE_PEAK_COL ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 3.3 : 6.3) /* 8dB sph was 6.3 */
-#define DTMF_TO_TOTAL_ENERGY ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 26.0 : 42.0)
-#else
-#define DTMF_NORMAL_TWIST 6.3
-#define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5) /* 4dB normal */
-#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
-#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
-#define DTMF_TO_TOTAL_ENERGY 42.0
-#endif
-
-#ifdef OLD_DSP_ROUTINES
-#define DTMF_2ND_HARMONIC_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5) /* 4dB normal */
-#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
-
-#define MF_THRESHOLD 8.0e7
-#define MF_NORMAL_TWIST 5.3 /* 8dB */
-#define MF_REVERSE_TWIST 4.0 /* was 2.5 */
-#define MF_RELATIVE_PEAK 5.3 /* 8dB */
-#define MF_2ND_HARMONIC 1.7 /* was 2.5 */
-#else
-#define BELL_MF_THRESHOLD 1.6e9
-#define BELL_MF_TWIST 4.0 /* 6dB */
-#define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */
-#endif
-
-#if !defined(BUSYDETECT_MARTIN) && !defined(BUSYDETECT) && !defined(BUSYDETECT_TONEONLY) && !defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
-#define BUSYDETECT_MARTIN
-#endif
-
-typedef struct {
- float v2;
- float v3;
- float fac;
-#ifndef OLD_DSP_ROUTINES
- int samples;
-#endif
-} goertzel_state_t;
-
-typedef struct
-{
- goertzel_state_t row_out[4];
- goertzel_state_t col_out[4];
-#ifdef FAX_DETECT
- goertzel_state_t fax_tone;
-#endif
-#ifdef OLD_DSP_ROUTINES
- goertzel_state_t row_out2nd[4];
- goertzel_state_t col_out2nd[4];
-#ifdef FAX_DETECT
- goertzel_state_t fax_tone2nd;
-#endif
- int hit1;
- int hit2;
- int hit3;
- int hit4;
-#else
- int lasthit;
-#endif
- int mhit;
- float energy;
- int current_sample;
-
- char digits[MAX_DTMF_DIGITS + 1];
-
- int current_digits;
- int detected_digits;
- int lost_digits;
- int digit_hits[16];
-#ifdef FAX_DETECT
- int fax_hits;
-#endif
-} dtmf_detect_state_t;
-
-typedef struct
-{
- goertzel_state_t tone_out[6];
- int mhit;
-#ifdef OLD_DSP_ROUTINES
- int hit1;
- int hit2;
- int hit3;
- int hit4;
- goertzel_state_t tone_out2nd[6];
- float energy;
-#else
- int hits[5];
-#endif
- int current_sample;
-
- char digits[MAX_DTMF_DIGITS + 1];
-
- int current_digits;
- int detected_digits;
- int lost_digits;
-#ifdef FAX_DETECT
- int fax_hits;
-#endif
-} mf_detect_state_t;
-
-static float dtmf_row[] =
-{
- 697.0, 770.0, 852.0, 941.0
-};
-static float dtmf_col[] =
-{
- 1209.0, 1336.0, 1477.0, 1633.0
-};
-
-static float mf_tones[] =
-{
- 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
-};
-
-#ifdef FAX_DETECT
-static float fax_freq = 1100.0;
-#endif
-
-static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
-
-#ifdef OLD_DSP_ROUTINES
-static char mf_hit[6][6] = {
- /* 700 + */ { 0, '1', '2', '4', '7', 'C' },
- /* 900 + */ { '1', 0, '3', '5', '8', 'A' },
- /* 1100 + */ { '2', '3', 0, '6', '9', '*' },
- /* 1300 + */ { '4', '5', '6', 0, '0', 'B' },
- /* 1500 + */ { '7', '8', '9', '0', 0, '#' },
- /* 1700 + */ { 'C', 'A', '*', 'B', '#', 0 },
-};
-#else
-static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
-#endif
-
-static inline void goertzel_sample(goertzel_state_t *s, short sample)
-{
- float v1;
- float fsamp = sample;
-
- v1 = s->v2;
- s->v2 = s->v3;
- s->v3 = s->fac * s->v2 - v1 + fsamp;
-}
-
-static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
-{
- int i;
-
- for (i=0;i<count;i++)
- goertzel_sample(s, samps[i]);
-}
-
-
-static inline float goertzel_result(goertzel_state_t *s)
-{
- return s->v3 * s->v3 + s->v2 * s->v2 - s->v2 * s->v3 * s->fac;
-}
-
-static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
-{
- s->v2 = s->v3 = 0.0;
- s->fac = 2.0 * cos(2.0 * M_PI * (freq / 8000.0));
-#ifndef OLD_DSP_ROUTINES
- s->samples = samples;
-#endif
-}
-
-static inline void goertzel_reset(goertzel_state_t *s)
-{
- s->v2 = s->v3 = 0.0;
-}
-
-struct ast_dsp {
- struct ast_frame f;
- int threshold;
- int totalsilence;
- int totalnoise;
- int features;
- int ringtimeout;
- int busymaybe;
- int busycount;
- int busy_tonelength;
- int busy_quietlength;
- int historicnoise[DSP_HISTORY];
- int historicsilence[DSP_HISTORY];
- goertzel_state_t freqs[7];
- int freqcount;
- int gsamps;
- enum gsamp_size gsamp_size;
- enum prog_mode progmode;
- int tstate;
- int tcount;
- int digitmode;
- int thinkdigit;
- float genergy;
- union {
- dtmf_detect_state_t dtmf;
- mf_detect_state_t mf;
- } td;
-};
-
-static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
-{
- int i;
-
-#ifdef OLD_DSP_ROUTINES
- s->hit1 =
- s->mhit =
- s->hit3 =
- s->hit4 =
- s->hit2 = 0;
-#else
- s->lasthit = 0;
-#endif
- for (i = 0; i < 4; i++) {
- goertzel_init (&s->row_out[i], dtmf_row[i], 102);
- goertzel_init (&s->col_out[i], dtmf_col[i], 102);
-#ifdef OLD_DSP_ROUTINES
- goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102);
- goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102);
-#endif
- s->energy = 0.0;
- }
-#ifdef FAX_DETECT
- /* Same for the fax dector */
- goertzel_init (&s->fax_tone, fax_freq, 102);
-
-#ifdef OLD_DSP_ROUTINES
- /* Same for the fax dector 2nd harmonic */
- goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
-#endif
-#endif /* FAX_DETECT */
- s->current_sample = 0;
- s->detected_digits = 0;
- s->current_digits = 0;
- memset(&s->digits, 0, sizeof(s->digits));
- s->lost_digits = 0;
- s->digits[0] = '\0';
-}
-
-static void ast_mf_detect_init (mf_detect_state_t *s)
-{
- int i;
-#ifdef OLD_DSP_ROUTINES
- s->hit1 =
- s->hit2 = 0;
-#else
- s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
-#endif
- for (i = 0; i < 6; i++) {
- goertzel_init (&s->tone_out[i], mf_tones[i], 160);
-#ifdef OLD_DSP_ROUTINES
- goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
- s->energy = 0.0;
-#endif
- }
- s->current_digits = 0;
- memset(&s->digits, 0, sizeof(s->digits));
- s->current_sample = 0;
- s->detected_digits = 0;
- s->lost_digits = 0;
- s->digits[0] = '\0';
- s->mhit = 0;
-}
-
-static int dtmf_detect (dtmf_detect_state_t *s, int16_t amp[], int samples,
- int digitmode, int *writeback, int faxdetect)
-{
- float row_energy[4];
- float col_energy[4];
-#ifdef FAX_DETECT
- float fax_energy;
-#ifdef OLD_DSP_ROUTINES
- float fax_energy_2nd;
-#endif
-#endif /* FAX_DETECT */
- float famp;
- float v1;
- int i;
- int j;
- int sample;
- int best_row;
- int best_col;
- int hit;
- int limit;
-
- hit = 0;
- for (sample = 0; sample < samples; sample = limit) {
- /* 102 is optimised to meet the DTMF specs. */
- if ((samples - sample) >= (102 - s->current_sample))
- limit = sample + (102 - s->current_sample);
- else
- limit = samples;
-#if defined(USE_3DNOW)
- _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
- _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
-#ifdef OLD_DSP_ROUTINES
- _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
- _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
-#endif
- /* XXX Need to fax detect for 3dnow too XXX */
- #warning "Fax Support Broken"
-#else
- /* The following unrolled loop takes only 35% (rough estimate) of the
- time of a rolled loop on the machine on which it was developed */
- for (j=sample;j<limit;j++) {
- famp = amp[j];
- s->energy += famp*famp;
- /* With GCC 2.95, the following unrolled code seems to take about 35%
- (rough estimate) as long as a neat little 0-3 loop */
- v1 = s->row_out[0].v2;
- s->row_out[0].v2 = s->row_out[0].v3;
- s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp;
- v1 = s->col_out[0].v2;
- s->col_out[0].v2 = s->col_out[0].v3;
- s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp;
- v1 = s->row_out[1].v2;
- s->row_out[1].v2 = s->row_out[1].v3;
- s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp;
- v1 = s->col_out[1].v2;
- s->col_out[1].v2 = s->col_out[1].v3;
- s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp;
- v1 = s->row_out[2].v2;
- s->row_out[2].v2 = s->row_out[2].v3;
- s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp;
- v1 = s->col_out[2].v2;
- s->col_out[2].v2 = s->col_out[2].v3;
- s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp;
- v1 = s->row_out[3].v2;
- s->row_out[3].v2 = s->row_out[3].v3;
- s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp;
- v1 = s->col_out[3].v2;
- s->col_out[3].v2 = s->col_out[3].v3;
- s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
-#ifdef FAX_DETECT
- /* Update fax tone */
- v1 = s->fax_tone.v2;
- s->fax_tone.v2 = s->fax_tone.v3;
- s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp;
-#endif /* FAX_DETECT */
-#ifdef OLD_DSP_ROUTINES
- v1 = s->col_out2nd[0].v2;
- s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
- s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
- v1 = s->row_out2nd[0].v2;
- s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
- s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
- v1 = s->col_out2nd[1].v2;
- s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
- s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
- v1 = s->row_out2nd[1].v2;
- s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
- s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
- v1 = s->col_out2nd[2].v2;
- s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
- s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
- v1 = s->row_out2nd[2].v2;
- s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
- s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
- v1 = s->col_out2nd[3].v2;
- s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
- s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
- v1 = s->row_out2nd[3].v2;
- s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
- s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
-#ifdef FAX_DETECT
- /* Update fax tone */
- v1 = s->fax_tone.v2;
- s->fax_tone2nd.v2 = s->fax_tone2nd.v3;
- s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp;
-#endif /* FAX_DETECT */
-#endif
- }
-#endif
- s->current_sample += (limit - sample);
- if (s->current_sample < 102) {
- if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
- /* If we had a hit last time, go ahead and clear this out since likely it
- will be another hit */
- for (i=sample;i<limit;i++)
- amp[i] = 0;
- *writeback = 1;
- }
- continue;
- }
-#ifdef FAX_DETECT
- /* Detect the fax energy, too */
- fax_energy = goertzel_result(&s->fax_tone);
-#endif
- /* We are at the end of a DTMF detection block */
- /* Find the peak row and the peak column */
- row_energy[0] = goertzel_result (&s->row_out[0]);
- col_energy[0] = goertzel_result (&s->col_out[0]);
-
- for (best_row = best_col = 0, i = 1; i < 4; i++) {
- row_energy[i] = goertzel_result (&s->row_out[i]);
- if (row_energy[i] > row_energy[best_row])
- best_row = i;
- col_energy[i] = goertzel_result (&s->col_out[i]);
- if (col_energy[i] > col_energy[best_col])
- best_col = i;
- }
- hit = 0;
- /* Basic signal level test and the twist test */
- if (row_energy[best_row] >= DTMF_THRESHOLD &&
- col_energy[best_col] >= DTMF_THRESHOLD &&
- col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
- col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
- /* Relative peak test */
- for (i = 0; i < 4; i++) {
- if ((i != best_col &&
- col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
- (i != best_row
- && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
- break;
- }
- }
-#ifdef OLD_DSP_ROUTINES
- /* ... and second harmonic test */
- if (i >= 4 &&
- (row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy &&
- goertzel_result(&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
- && goertzel_result(&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
-#else
- /* ... and fraction of total energy test */
- if (i >= 4 &&
- (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy) {
-#endif
- /* Got a hit */
- hit = dtmf_positions[(best_row << 2) + best_col];
- if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
- /* Zero out frame data if this is part DTMF */
- for (i=sample;i<limit;i++)
- amp[i] = 0;
- *writeback = 1;
- }
-#ifdef OLD_DSP_ROUTINES
- /* Look for two successive similar results */
- /* The logic in the next test is:
- We need two successive identical clean detects, with
- something different preceeding it. This can work with
- back to back differing digits. More importantly, it
- can work with nasty phones that give a very wobbly start
- to a digit */
- if (hit == s->hit3 && s->hit3 != s->hit2) {
- s->mhit = hit;
- s->digit_hits[(best_row << 2) + best_col]++;
- s->detected_digits++;
- if (s->current_digits < MAX_DTMF_DIGITS) {
- s->digits[s->current_digits++] = hit;
- s->digits[s->current_digits] = '\0';
- } else {
- s->lost_digits++;
- }
- }
-#endif
- }
- }
-
-#ifndef OLD_DSP_ROUTINES
- /* Look for two successive similar results */
- /* The logic in the next test is:
- We need two successive identical clean detects, with
- something different preceeding it. This can work with
- back to back differing digits. More importantly, it
- can work with nasty phones that give a very wobbly start
- to a digit */
- if (hit == s->lasthit && hit != s->mhit) {
- if (hit) {
- s->digit_hits[(best_row << 2) + best_col]++;
- s->detected_digits++;
- if (s->current_digits < MAX_DTMF_DIGITS) {
- s->digits[s->current_digits++] = hit;
- s->digits[s->current_digits] = '\0';
- } else {
- s->lost_digits++;
- }
- }
- s->mhit = hit;
- }
-#endif
-
-#ifdef FAX_DETECT
- if (!hit && (fax_energy >= FAX_THRESHOLD) &&
- (fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) &&
- (faxdetect)) {
-#if 0
- printf("Fax energy/Second Harmonic: %f\n", fax_energy);
-#endif
- /* XXX Probably need better checking than just this the energy XXX */
- hit = 'f';
- s->fax_hits++;
- } else {
- if (s->fax_hits > 5) {
- hit = 'f';
- s->mhit = 'f';
- s->detected_digits++;
- if (s->current_digits < MAX_DTMF_DIGITS) {
- s->digits[s->current_digits++] = hit;
- s->digits[s->current_digits] = '\0';
- } else {
- s->lost_digits++;
- }
- }
- s->fax_hits = 0;
- }
-#endif /* FAX_DETECT */
-#ifdef OLD_DSP_ROUTINES
- s->hit1 = s->hit2;
- s->hit2 = s->hit3;
- s->hit3 = hit;
-#else
- s->lasthit = hit;
-#endif
- /* Reinitialise the detector for the next block */
- for (i = 0; i < 4; i++) {
- goertzel_reset(&s->row_out[i]);
- goertzel_reset(&s->col_out[i]);
-#ifdef OLD_DSP_ROUTINES
- goertzel_reset(&s->row_out2nd[i]);
- goertzel_reset(&s->col_out2nd[i]);
-#endif
- }
-#ifdef FAX_DETECT
- goertzel_reset (&s->fax_tone);
-#ifdef OLD_DSP_ROUTINES
- goertzel_reset (&s->fax_tone2nd);
-#endif
-#endif
- s->energy = 0.0;
- s->current_sample = 0;
- }
-#ifdef OLD_DSP_ROUTINES
- if ((!s->mhit) || (s->mhit != hit)) {
- s->mhit = 0;
- return(0);
- }
- return (hit);
-#else
- return (s->mhit); /* return the debounced hit */
-#endif
-}
-
-/* MF goertzel size */
-#ifdef OLD_DSP_ROUTINES
-#define MF_GSIZE 160
-#else
-#define MF_GSIZE 120
-#endif
-
-static int mf_detect (mf_detect_state_t *s, int16_t amp[],
- int samples, int digitmode, int *writeback)
-{
-#ifdef OLD_DSP_ROUTINES
- float tone_energy[6];
- int best1;
- int best2;
- float max;
- int sofarsogood;
-#else
- float energy[6];
- int best;
- int second_best;
-#endif
- float famp;
- float v1;
- int i;
- int j;
- int sample;
- int hit;
- int limit;
-
- hit = 0;
- for (sample = 0; sample < samples; sample = limit) {
- /* 80 is optimised to meet the MF specs. */
- if ((samples - sample) >= (MF_GSIZE - s->current_sample))
- limit = sample + (MF_GSIZE - s->current_sample);
- else
- limit = samples;
-#if defined(USE_3DNOW)
- _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
- _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
-#ifdef OLD_DSP_ROUTINES
- _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
- _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
-#endif
- /* XXX Need to fax detect for 3dnow too XXX */
- #warning "Fax Support Broken"
-#else
- /* The following unrolled loop takes only 35% (rough estimate) of the
- time of a rolled loop on the machine on which it was developed */
- for (j = sample; j < limit; j++) {
- famp = amp[j];
-#ifdef OLD_DSP_ROUTINES
- s->energy += famp*famp;
-#endif
- /* With GCC 2.95, the following unrolled code seems to take about 35%
- (rough estimate) as long as a neat little 0-3 loop */
- v1 = s->tone_out[0].v2;
- s->tone_out[0].v2 = s->tone_out[0].v3;
- s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
- v1 = s->tone_out[1].v2;
- s->tone_out[1].v2 = s->tone_out[1].v3;
- s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
- v1 = s->tone_out[2].v2;
- s->tone_out[2].v2 = s->tone_out[2].v3;
- s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
- v1 = s->tone_out[3].v2;
- s->tone_out[3].v2 = s->tone_out[3].v3;
- s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
- v1 = s->tone_out[4].v2;
- s->tone_out[4].v2 = s->tone_out[4].v3;
- s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
- v1 = s->tone_out[5].v2;
- s->tone_out[5].v2 = s->tone_out[5].v3;
- s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
-#ifdef OLD_DSP_ROUTINES
- v1 = s->tone_out2nd[0].v2;
- s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
- s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
- v1 = s->tone_out2nd[1].v2;
- s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
- s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
- v1 = s->tone_out2nd[2].v2;
- s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
- s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
- v1 = s->tone_out2nd[3].v2;
- s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
- s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
- v1 = s->tone_out2nd[4].v2;
- s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
- s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
- v1 = s->tone_out2nd[3].v2;
- s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
- s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
-#endif
- }
-#endif
- s->current_sample += (limit - sample);
- if (s->current_sample < MF_GSIZE) {
- if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
- /* If we had a hit last time, go ahead and clear this out since likely it
- will be another hit */
- for (i=sample;i<limit;i++)
- amp[i] = 0;
- *writeback = 1;
- }
- continue;
- }
-#ifdef OLD_DSP_ROUTINES
- /* We're at the end of an MF detection block. Go ahead and calculate
- all the energies. */
- for (i=0;i<6;i++) {
- tone_energy[i] = goertzel_result(&s->tone_out[i]);
- }
- /* Find highest */
- best1 = 0;
- max = tone_energy[0];
- for (i=1;i<6;i++) {
- if (tone_energy[i] > max) {
- max = tone_energy[i];
- best1 = i;
- }
- }
-
- /* Find 2nd highest */
- if (best1) {
- max = tone_energy[0];
- best2 = 0;
- } else {
- max = tone_energy[1];
- best2 = 1;
- }
-
- for (i=0;i<6;i++) {
- if (i == best1) continue;
- if (tone_energy[i] > max) {
- max = tone_energy[i];
- best2 = i;
- }
- }
- hit = 0;
- if (best1 != best2)
- sofarsogood=1;
- else
- sofarsogood=0;
- /* Check for relative energies */
- for (i=0;i<6;i++) {
- if (i == best1)
- continue;
- if (i == best2)
- continue;
- if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
- sofarsogood = 0;
- break;
- }
- if (tone_energy[best2] < tone_energy[i] * MF_RELATIVE_PEAK) {
- sofarsogood = 0;
- break;
- }
- }
-
- if (sofarsogood) {
- /* Check for 2nd harmonic */
- if (goertzel_result(&s->tone_out2nd[best1]) * MF_2ND_HARMONIC > tone_energy[best1])
- sofarsogood = 0;
- else if (goertzel_result(&s->tone_out2nd[best2]) * MF_2ND_HARMONIC > tone_energy[best2])
- sofarsogood = 0;
- }
- if (sofarsogood) {
- hit = mf_hit[best1][best2];
- if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
- /* Zero out frame data if this is part DTMF */
- for (i=sample;i<limit;i++)
- amp[i] = 0;
- *writeback = 1;
- }
- /* Look for two consecutive clean hits */
- if ((hit == s->hit3) && (s->hit3 != s->hit2)) {
- s->mhit = hit;
- s->detected_digits++;
- if (s->current_digits < MAX_DTMF_DIGITS - 2) {
- s->digits[s->current_digits++] = hit;
- s->digits[s->current_digits] = '\0';
- } else {
- s->lost_digits++;
- }
- }
- }
-
- s->hit1 = s->hit2;
- s->hit2 = s->hit3;
- s->hit3 = hit;
- /* Reinitialise the detector for the next block */
- for (i = 0; i < 6; i++) {
- goertzel_reset(&s->tone_out[i]);
- goertzel_reset(&s->tone_out2nd[i]);
- }
- s->energy = 0.0;
- s->current_sample = 0;
- }
-#else
- /* We're at the end of an MF detection block. */
- /* Find the two highest energies. The spec says to look for
- two tones and two tones only. Taking this literally -ie
- only two tones pass the minimum threshold - doesn't work
- well. The sinc function mess, due to rectangular windowing
- ensure that! Find the two highest energies and ensure they
- are considerably stronger than any of the others. */
- energy[0] = goertzel_result(&s->tone_out[0]);
- energy[1] = goertzel_result(&s->tone_out[1]);
- if (energy[0] > energy[1]) {
- best = 0;
- second_best = 1;
- } else {
- best = 1;
- second_best = 0;
- }
- /*endif*/
- for (i=2;i<6;i++) {
- energy[i] = goertzel_result(&s->tone_out[i]);
- if (energy[i] >= energy[best]) {
- second_best = best;
- best = i;
- } else if (energy[i] >= energy[second_best]) {
- second_best = i;
- }
- }
- /* Basic signal level and twist tests */
- hit = 0;
- if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
- && energy[best] < energy[second_best]*BELL_MF_TWIST
- && energy[best]*BELL_MF_TWIST > energy[second_best]) {
- /* Relative peak test */
- hit = -1;
- for (i=0;i<6;i++) {
- if (i != best && i != second_best) {
- if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
- /* The best two are not clearly the best */
- hit = 0;
- break;
- }
- }
- }
- }
- if (hit) {
- /* Get the values into ascending order */
- if (second_best < best) {
- i = best;
- best = second_best;
- second_best = i;
- }
- best = best*5 + second_best - 1;
- hit = bell_mf_positions[best];
- /* Look for two successive similar results */
- /* The logic in the next test is:
- For KP we need 4 successive identical clean detects, with
- two blocks of something different preceeding it. For anything
- else we need two successive identical clean detects, with
- two blocks of something different preceeding it. */
- if (hit == s->hits[4] && hit == s->hits[3] &&
- ((hit != '*' && hit != s->hits[2] && hit != s->hits[1])||
- (hit == '*' && hit == s->hits[2] && hit != s->hits[1] &&
- hit != s->hits[0]))) {
- s->detected_digits++;
- if (s->current_digits < MAX_DTMF_DIGITS) {
- s->digits[s->current_digits++] = hit;
- s->digits[s->current_digits] = '\0';
- } else {
- s->lost_digits++;
- }
- }
- } else {
- hit = 0;
- }
- s->hits[0] = s->hits[1];
- s->hits[1] = s->hits[2];
- s->hits[2] = s->hits[3];
- s->hits[3] = s->hits[4];
- s->hits[4] = hit;
- /* Reinitialise the detector for the next block */
- for (i = 0; i < 6; i++)
- goertzel_reset(&s->tone_out[i]);
- s->current_sample = 0;
- }
-#endif
- if ((!s->mhit) || (s->mhit != hit)) {
- s->mhit = 0;
- return(0);
- }
- return (hit);
-}
-
-static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
-{
- int res;
-
- if (dsp->digitmode & DSP_DIGITMODE_MF)
- res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
- else
- res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->features & DSP_FEATURE_FAX_DETECT);
- return res;
-}
-
-int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
-{
- short *s;
- int len;
- int ign=0;
-
- if (inf->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
- return 0;
- }
- if (inf->subclass != AST_FORMAT_SLINEAR) {
- ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
- return 0;
- }
- s = inf->data;
- len = inf->datalen / 2;
- return __ast_dsp_digitdetect(dsp, s, len, &ign);
-}
-
-static inline int pair_there(float p1, float p2, float i1, float i2, float e)
-{
- /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
- /* Make sure absolute levels are high enough */
- if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
- return 0;
- /* Amplify ignored stuff */
- i2 *= TONE_THRESH;
- i1 *= TONE_THRESH;
- e *= TONE_THRESH;
- /* Check first tone */
- if ((p1 < i1) || (p1 < i2) || (p1 < e))
- return 0;
- /* And second */
- if ((p2 < i1) || (p2 < i2) || (p2 < e))
- return 0;
- /* Guess it's there... */
- return 1;
-}
-
-int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
-{
- if (dsp->digitmode & DSP_DIGITMODE_MF) {
- if (max > dsp->td.mf.current_digits)
- max = dsp->td.mf.current_digits;
- if (max > 0) {
- memcpy(buf, dsp->td.mf.digits, max);
- memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
- dsp->td.mf.current_digits -= max;
- }
- buf[max] = '\0';
- return max;
- } else {
- if (max > dsp->td.dtmf.current_digits)
- max = dsp->td.dtmf.current_digits;
- if (max > 0) {
- memcpy (buf, dsp->td.dtmf.digits, max);
- memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
- dsp->td.dtmf.current_digits -= max;
- }
- buf[max] = '\0';
- return max;
- }
-}
-
-static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
-{
- int x;
- int y;
- int pass;
- int newstate = DSP_TONE_STATE_SILENCE;
- int res = 0;
- while(len) {
- /* Take the lesser of the number of samples we need and what we have */
- pass = len;
- if (pass > dsp->gsamp_size - dsp->gsamps)
- pass = dsp->gsamp_size - dsp->gsamps;
- for (x=0;x<pass;x++) {
- for (y=0;y<dsp->freqcount;y++)
- goertzel_sample(&dsp->freqs[y], s[x]);
- dsp->genergy += s[x] * s[x];
- }
- s += pass;
- dsp->gsamps += pass;
- len -= pass;
- if (dsp->gsamps == dsp->gsamp_size) {
- float hz[7];
- for (y=0;y<7;y++)
- hz[y] = goertzel_result(&dsp->freqs[y]);
-#if 0
- printf("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n");
- printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n",
- hz[HZ_350], hz[HZ_425], hz[HZ_440], hz[HZ_480], hz[HZ_620], hz[HZ_950], hz[HZ_1400], hz[HZ_1800], dsp->genergy);
-#endif
- switch(dsp->progmode) {
- case PROG_MODE_NA:
- if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
- newstate = DSP_TONE_STATE_BUSY;
- } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
- newstate = DSP_TONE_STATE_RINGING;
- } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
- newstate = DSP_TONE_STATE_DIALTONE;
- } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
- newstate = DSP_TONE_STATE_SPECIAL1;
- } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
- if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
- newstate = DSP_TONE_STATE_SPECIAL2;
- } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
- if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
- newstate = DSP_TONE_STATE_SPECIAL3;
- } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
- newstate = DSP_TONE_STATE_TALKING;
- } else
- newstate = DSP_TONE_STATE_SILENCE;
- break;
- case PROG_MODE_CR:
- if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
- newstate = DSP_TONE_STATE_RINGING;
- } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
- newstate = DSP_TONE_STATE_TALKING;
- } else
- newstate = DSP_TONE_STATE_SILENCE;
- break;
- case PROG_MODE_UK:
- if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
- newstate = DSP_TONE_STATE_HUNGUP;
- }
- break;
- default:
- ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
- }
- if (newstate == dsp->tstate) {
- dsp->tcount++;
- if (dsp->ringtimeout)
- dsp->ringtimeout++;
- switch (dsp->tstate) {
- case DSP_TONE_STATE_RINGING:
- if ((dsp->features & DSP_PROGRESS_RINGING) &&
- (dsp->tcount==THRESH_RING)) {
- res = AST_CONTROL_RINGING;
- dsp->ringtimeout= 1;
- }
- break;
- case DSP_TONE_STATE_BUSY:
- if ((dsp->features & DSP_PROGRESS_BUSY) &&
- (dsp->tcount==THRESH_BUSY)) {
- res = AST_CONTROL_BUSY;
- dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
- }
- break;
- case DSP_TONE_STATE_TALKING:
- if ((dsp->features & DSP_PROGRESS_TALK) &&
- (dsp->tcount==THRESH_TALK)) {
- res = AST_CONTROL_ANSWER;
- dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
- }
- break;
- case DSP_TONE_STATE_SPECIAL3:
- if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
- (dsp->tcount==THRESH_CONGESTION)) {
- res = AST_CONTROL_CONGESTION;
- dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
- }
- break;
- case DSP_TONE_STATE_HUNGUP:
- if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
- (dsp->tcount==THRESH_HANGUP)) {
- res = AST_CONTROL_HANGUP;
- dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
- }
- break;
- }
- if (dsp->ringtimeout==THRESH_RING2ANSWER) {
-#if 0
- ast_log(LOG_NOTICE, "Consider call as answered because of timeout after last ring\n");
-#endif
- res = AST_CONTROL_ANSWER;
- dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
- }
- } else {
-#if 0
- ast_log(LOG_NOTICE, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
- ast_log(LOG_NOTICE, "Start state %d\n", newstate);
-#endif
- dsp->tstate = newstate;
- dsp->tcount = 1;
- }
-
- /* Reset goertzel */
- for (x=0;x<7;x++)
- dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
- dsp->gsamps = 0;
- dsp->genergy = 0.0;
- }
- }
-#if 0
- if (res)
- printf("Returning %d\n", res);
-#endif
- return res;
-}
-
-int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
-{
- if (inf->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
- return 0;
- }
- if (inf->subclass != AST_FORMAT_SLINEAR) {
- ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
- return 0;
- }
- return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
-}
-
-static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
-{
- int accum;
- int x;
- int res = 0;
-
- if (!len)
- return 0;
- accum = 0;
- for (x=0;x<len; x++)
- accum += abs(s[x]);
- accum /= len;
- if (accum < dsp->threshold) {
- /* Silent */
- dsp->totalsilence += len/8;
- if (dsp->totalnoise) {
- /* Move and save history */
- memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
- dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
-/* we don't want to check for busydetect that frequently */
-#if 0
- dsp->busymaybe = 1;
-#endif
- }
- dsp->totalnoise = 0;
- res = 1;
- } else {
- /* Not silent */
- dsp->totalnoise += len/8;
- if (dsp->totalsilence) {
- int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
- int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
- /* Move and save history */
- memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
- dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
- /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
- if (silence1 < silence2) {
- if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
- dsp->busymaybe = 1;
- else
- dsp->busymaybe = 0;
- } else {
- if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
- dsp->busymaybe = 1;
- else
- dsp->busymaybe = 0;
- }
- }
- dsp->totalsilence = 0;
- }
- if (totalsilence)
- *totalsilence = dsp->totalsilence;
- return res;
-}
-
-#ifdef BUSYDETECT_MARTIN
-int ast_dsp_busydetect(struct ast_dsp *dsp)
-{
- int res = 0, x;
-#ifndef BUSYDETECT_TONEONLY
- int avgsilence = 0, hitsilence = 0;
-#endif
- int avgtone = 0, hittone = 0;
- if (!dsp->busymaybe)
- return res;
- for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
-#ifndef BUSYDETECT_TONEONLY
- avgsilence += dsp->historicsilence[x];
-#endif
- avgtone += dsp->historicnoise[x];
- }
-#ifndef BUSYDETECT_TONEONLY
- avgsilence /= dsp->busycount;
-#endif
- avgtone /= dsp->busycount;
- for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
-#ifndef BUSYDETECT_TONEONLY
- if (avgsilence > dsp->historicsilence[x]) {
- if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
- hitsilence++;
- } else {
- if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
- hitsilence++;
- }
-#endif
- if (avgtone > dsp->historicnoise[x]) {
- if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
- hittone++;
- } else {
- if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
- hittone++;
- }
- }
-#ifndef BUSYDETECT_TONEONLY
- if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
- (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
- (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
-#else
- if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
-#endif
-#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
-#ifdef BUSYDETECT_TONEONLY
-#error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
-#endif
- if (avgtone > avgsilence) {
- if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
- res = 1;
- } else {
- if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
- res = 1;
- }
-#else
- res = 1;
-#endif
- }
- /* If we know the expected busy tone length, check we are in the range */
- if (res && (dsp->busy_tonelength > 0)) {
- if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
-#if 0
- ast_log(LOG_NOTICE, "busy detector: avgtone of %d not close enough to desired %d\n",
- avgtone, dsp->busy_tonelength);
-#endif
- res = 0;
- }
- }
-#ifndef BUSYDETECT_TONEONLY
- /* If we know the expected busy tone silent-period length, check we are in the range */
- if (res && (dsp->busy_quietlength > 0)) {
- if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
-#if 0
- ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
- avgsilence, dsp->busy_quietlength);
-#endif
- res = 0;
- }
- }
-#endif
-#ifndef BUSYDETECT_TONEONLY
-#if 1
- if (res)
- ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
-#endif
-#endif
- return res;
-}
-#endif
-
-#ifdef BUSYDETECT
-int ast_dsp_busydetect(struct ast_dsp *dsp)
-{
- int x;
- int res = 0;
- int max, min;
-
-#if 0
- if (dsp->busy_hits > 5);
- return 0;
-#endif
- if (dsp->busymaybe) {
-#if 0
- printf("Maybe busy!\n");
-#endif
- dsp->busymaybe = 0;
- min = 9999;
- max = 0;
- for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
-#if 0
- printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
-#endif
- if (dsp->historicsilence[x] < min)
- min = dsp->historicsilence[x];
- if (dsp->historicnoise[x] < min)
- min = dsp->historicnoise[x];
- if (dsp->historicsilence[x] > max)
- max = dsp->historicsilence[x];
- if (dsp->historicnoise[x] > max)
- max = dsp->historicnoise[x];
- }
- if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
-#if 0
- printf("Busy!\n");
-#endif
- res = 1;
- }
-#if 0
- printf("Min: %d, max: %d\n", min, max);
-#endif
- }
- return res;
-}
-#endif
-
-int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
-{
- short *s;
- int len;
-
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
- return 0;
- }
- if (f->subclass != AST_FORMAT_SLINEAR) {
- ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
- return 0;
- }
- s = f->data;
- len = f->datalen/2;
- return __ast_dsp_silence(dsp, s, len, totalsilence);
-}
-
-struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
-{
- int silence;
- int res;
- int digit;
- int x;
- short *shortdata;
- unsigned char *odata;
- int len;
- int writeback = 0;
-
-#define FIX_INF(inf) do { \
- if (writeback) { \
- switch(inf->subclass) { \
- case AST_FORMAT_SLINEAR: \
- break; \
- case AST_FORMAT_ULAW: \
- for (x=0;x<len;x++) \
- odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
- break; \
- case AST_FORMAT_ALAW: \
- for (x=0;x<len;x++) \
- odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
- break; \
- } \
- } \
- } while(0)
-
- if (!af)
- return NULL;
- if (af->frametype != AST_FRAME_VOICE)
- return af;
- odata = af->data;
- len = af->datalen;
- /* Make sure we have short data */
- switch(af->subclass) {
- case AST_FORMAT_SLINEAR:
- shortdata = af->data;
- len = af->datalen / 2;
- break;
- case AST_FORMAT_ULAW:
- shortdata = alloca(af->datalen * 2);
- for (x = 0;x < len; x++)
- shortdata[x] = AST_MULAW(odata[x]);
- break;
- case AST_FORMAT_ALAW:
- shortdata = alloca(af->datalen * 2);
- for (x = 0; x < len; x++)
- shortdata[x] = AST_ALAW(odata[x]);
- break;
- default:
- ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
- return af;
- }
- silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
- if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_NULL;
- ast_frfree(af);
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- }
- if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_CONTROL;
- dsp->f.subclass = AST_CONTROL_BUSY;
- ast_frfree(af);
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- }
- if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
- digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
-#if 0
- if (digit)
- printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
-#endif
- if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
- if (!dsp->thinkdigit) {
- if (digit) {
- /* Looks like we might have something.
- * Request a conference mute for the moment */
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_DTMF;
- dsp->f.subclass = 'm';
- dsp->thinkdigit = 'x';
- FIX_INF(af);
- if (chan)
- ast_queue_frame(chan, af);
- ast_frfree(af);
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- }
- } else {
- if (digit) {
- /* Thought we saw one last time. Pretty sure we really have now */
- if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
- /* If we found a digit, and we're changing digits, go
- ahead and send this one, but DON'T stop confmute because
- we're detecting something else, too... */
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_DTMF_END;
- dsp->f.subclass = dsp->thinkdigit;
- FIX_INF(af);
- if (chan)
- ast_queue_frame(chan, af);
- ast_frfree(af);
- } else {
- dsp->thinkdigit = digit;
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
- dsp->f.subclass = dsp->thinkdigit;
- FIX_INF(af);
- if (chan)
- ast_queue_frame(chan, af);
- ast_frfree(af);
- }
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- } else {
- memset(&dsp->f, 0, sizeof(dsp->f));
- if (dsp->thinkdigit != 'x') {
- /* If we found a digit, send it now */
- dsp->f.frametype = AST_FRAME_DTMF_END;
- dsp->f.subclass = dsp->thinkdigit;
- dsp->thinkdigit = 0;
- } else {
- dsp->f.frametype = AST_FRAME_DTMF;
- dsp->f.subclass = 'u';
- dsp->thinkdigit = 0;
- }
- FIX_INF(af);
- if (chan)
- ast_queue_frame(chan, af);
- ast_frfree(af);
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- }
- }
- } else if (!digit) {
- /* Only check when there is *not* a hit... */
- if (dsp->digitmode & DSP_DIGITMODE_MF) {
- if (dsp->td.mf.current_digits) {
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_DTMF;
- dsp->f.subclass = dsp->td.mf.digits[0];
- memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
- dsp->td.mf.current_digits--;
- FIX_INF(af);
- if (chan)
- ast_queue_frame(chan, af);
- ast_frfree(af);
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- }
- } else {
- if (dsp->td.dtmf.current_digits) {
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_DTMF_END;
- dsp->f.subclass = dsp->td.dtmf.digits[0];
- memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
- dsp->td.dtmf.current_digits--;
- FIX_INF(af);
- if (chan)
- ast_queue_frame(chan, af);
- ast_frfree(af);
- ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
- return &dsp->f;
- }
- }
- }
- }
- if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
- res = __ast_dsp_call_progress(dsp, shortdata, len);
- if (res) {
- switch(res) {
- case AST_CONTROL_ANSWER:
- case AST_CONTROL_BUSY:
- case AST_CONTROL_RINGING:
- case AST_CONTROL_CONGESTION:
- case AST_CONTROL_HANGUP:
- memset(&dsp->f, 0, sizeof(dsp->f));
- dsp->f.frametype = AST_FRAME_CONTROL;
- dsp->f.subclass = res;
- dsp->f.src = "dsp_progress";
- if (chan)
- ast_queue_frame(chan, &dsp->f);
- break;
- default:
- ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
- }
- }
- }
- FIX_INF(af);
- return af;
-}
-
-static void ast_dsp_prog_reset(struct ast_dsp *dsp)
-{
- int max = 0;
- int x;
-
- dsp->gsamp_size = modes[dsp->progmode].size;
- dsp->gsamps = 0;
- for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
- if (modes[dsp->progmode].freqs[x]) {
- goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
- max = x + 1;
- }
- }
- dsp->freqcount = max;
- dsp->ringtimeout= 0;
-}
-
-struct ast_dsp *ast_dsp_new(void)
-{
- struct ast_dsp *dsp;
-
- if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
- dsp->threshold = DEFAULT_THRESHOLD;
- dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
- dsp->busycount = DSP_HISTORY;
- /* Initialize DTMF detector */
- ast_dtmf_detect_init(&dsp->td.dtmf);
- /* Initialize initial DSP progress detect parameters */
- ast_dsp_prog_reset(dsp);
- }
- return dsp;
-}
-
-void ast_dsp_set_features(struct ast_dsp *dsp, int features)
-{
- dsp->features = features;
-}
-
-void ast_dsp_free(struct ast_dsp *dsp)
-{
- if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) {
- /* If this flag is still set, that means that the dsp's destruction
- * been torn down, while we still have a frame out there being used.
- * When ast_frfree() gets called on that frame, this ast_trans_pvt
- * will get destroyed, too. */
-
- /* Set the magic hint that this has been requested to be destroyed. */
- dsp->freqcount = -1;
-
- return;
- }
- free(dsp);
-}
-
-void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
-{
- dsp->threshold = threshold;
-}
-
-void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
-{
- if (cadences < 4)
- cadences = 4;
- if (cadences > DSP_HISTORY)
- cadences = DSP_HISTORY;
- dsp->busycount = cadences;
-}
-
-void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
-{
- dsp->busy_tonelength = tonelength;
- dsp->busy_quietlength = quietlength;
- ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
-}
-
-void ast_dsp_digitreset(struct ast_dsp *dsp)
-{
- int i;
-
- dsp->thinkdigit = 0;
- if (dsp->digitmode & DSP_DIGITMODE_MF) {
- memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
- dsp->td.mf.current_digits = 0;
- /* Reinitialise the detector for the next block */
- for (i = 0; i < 6; i++) {
- goertzel_reset(&dsp->td.mf.tone_out[i]);
-#ifdef OLD_DSP_ROUTINES
- goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
-#endif
- }
-#ifdef OLD_DSP_ROUTINES
- dsp->td.mf.energy = 0.0;
- dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
-#else
- dsp->td.mf.hits[4] = dsp->td.mf.hits[3] = dsp->td.mf.hits[2] = dsp->td.mf.hits[1] = dsp->td.mf.hits[0] = dsp->td.mf.mhit = 0;
-#endif
- dsp->td.mf.current_sample = 0;
- } else {
- memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
- dsp->td.dtmf.current_digits = 0;
- /* Reinitialise the detector for the next block */
- for (i = 0; i < 4; i++) {
- goertzel_reset(&dsp->td.dtmf.row_out[i]);
- goertzel_reset(&dsp->td.dtmf.col_out[i]);
-#ifdef OLD_DSP_ROUTINES
- goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
- goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
-#endif
- }
-#ifdef FAX_DETECT
- goertzel_reset (&dsp->td.dtmf.fax_tone);
-#endif
-#ifdef OLD_DSP_ROUTINES
-#ifdef FAX_DETECT
- goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
-#endif
- dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
-#else
- dsp->td.dtmf.lasthit = dsp->td.dtmf.mhit = 0;
-#endif
- dsp->td.dtmf.energy = 0.0;
- dsp->td.dtmf.current_sample = 0;
- }
-}
-
-void ast_dsp_reset(struct ast_dsp *dsp)
-{
- int x;
-
- dsp->totalsilence = 0;
- dsp->gsamps = 0;
- for (x=0;x<4;x++)
- dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
- memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
- memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
- dsp->ringtimeout= 0;
-}
-
-int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
-{
- int new;
- int old;
-
- old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
- new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
- if (old != new) {
- /* Must initialize structures if switching from MF to DTMF or vice-versa */
- if (new & DSP_DIGITMODE_MF)
- ast_mf_detect_init(&dsp->td.mf);
- else
- ast_dtmf_detect_init(&dsp->td.dtmf);
- }
- dsp->digitmode = digitmode;
- return 0;
-}
-
-int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
-{
- int x;
-
- for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
- if (!strcasecmp(aliases[x].name, zone)) {
- dsp->progmode = aliases[x].mode;
- ast_dsp_prog_reset(dsp);
- return 0;
- }
- }
- return -1;
-}
-
-int ast_dsp_get_tstate(struct ast_dsp *dsp)
-{
- return dsp->tstate;
-}
-
-int ast_dsp_get_tcount(struct ast_dsp *dsp)
-{
- return dsp->tcount;
-}
-
-void ast_dsp_frame_freed(struct ast_frame *fr)
-{
- struct ast_dsp *dsp;
-
- ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
-
- dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f));
-
- if (dsp->freqcount != -1)
- return;
-
- ast_dsp_free(dsp);
-}
diff --git a/1.4/main/ecdisa.h b/1.4/main/ecdisa.h
deleted file mode 100644
index df6f773a0..000000000
--- a/1.4/main/ecdisa.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* ecdisa.h: Generated from frequency 2100
- by gentone. 80 samples */
-static unsigned char ecdisa[80] = {
- 255, 143, 58, 16, 171, 146, 34, 20,
- 156, 151, 25, 26, 149, 159, 19, 38,
- 145, 177, 16, 73, 143, 73, 16, 177,
- 145, 38, 19, 159, 149, 26, 25, 151,
- 156, 20, 34, 146, 171, 16, 58, 143,
- 255, 15, 186, 144, 43, 18, 162, 148,
- 28, 23, 153, 154, 21, 31, 147, 166,
- 17, 49, 144, 201, 15, 201, 144, 49,
- 17, 166, 147, 31, 21, 154, 153, 23,
- 28, 148, 162, 18, 43, 144, 186, 15,
-
-};
diff --git a/1.4/main/editline/CHANGES b/1.4/main/editline/CHANGES
deleted file mode 100644
index c18b56cdf..000000000
--- a/1.4/main/editline/CHANGES
+++ /dev/null
@@ -1,42 +0,0 @@
-2002-02-25 : Christos Zoulas <christos@netbsd.org>
- * Bring in constification fixes from NetBSD tree.
- * Use NetBSD's vis, fgetln
-
-2002-02-10 : Jason Evans <jasone@freebsd.org>
-
- * Makefile.in : Append "" arguments to for loops, to avoid syntax errors
- with some shells that occur if there are no arguments to the for
- loops.
-
-2002-02-09 : Jason Evans <jasone@freebsd.org>
-
- * Install man pages in @prefix@/man/, rather than @prefix@/share/man.
-
- * Fix the Darwin -install_name S_LDFLAGS argument to default to a prefix
- of /usr/local if --prefix is not specified.
-
-2002-02-05 : Jason Evans <jasone@freebsd.org>
-
- * Convert to using an autoconf-generated config.h, rather than passing
- -D_HAVE_<foo>=1 definitions on the command line. Include sys.h in
- config.h, and include config.h in .c files rather than sys.h.
-
- * Mangle function names for implementations in the np directory in order
- to avoid namespace collisions with other code that may provide copies
- of the same unimplemented functions. For example:
-
- #define fgetln libedit_fgetln
-
-2002-02-03 : Jason Evans <jasone@freebsd.org>
-
- * Add autoconf infrastructure, plus a generic Makefile that works with
- at least BSD make, GNU make and Sun make.
-
- * Port and/or test on FreeBSD 4.5, FreeBSD-current, NetBSD 1.5 (sparc64
- and arm32), Apple OS X 10.1.2, Solaris 2.6, and Red Hat Linux 2.6.
- Add the np directory, which contains implementations of non-portable
- functions.
-
- * Add the LIBEDIT_MAJOR and LIBEDIT_MINOR macros to histedit.h, since
- there is otherwise no straightforward method of programmatically
- detecting the library version.
diff --git a/1.4/main/editline/INSTALL b/1.4/main/editline/INSTALL
deleted file mode 100644
index 16fb6ffd1..000000000
--- a/1.4/main/editline/INSTALL
+++ /dev/null
@@ -1,64 +0,0 @@
-Building this distribution in many cases is as simple as typing the following
-while in the root directory of the source tree:
-
- ./configure
- make
-
-To install, do the above, then type:
-
- make install
-
-Additional build targets of finer granularity include:
-
- lib_a
- lib_s
- install_hdr
- install_lib
- install_lib_a
- install_lib_s
- install_man
- test
-
-Cleanup targets include:
-
- clean
- distclean
-
-Optionally, pass any of the following (not a definitive list) arguments to
-'configure':
-
---prefix=<install-root-dir>
- Set the base directory in which to install. For example:
-
- ./configure --prefix=/usr/local
-
- will cause files to be installed into /usr/local/bin, /usr/local/man,
- /usr/local/include, /usr/local/lib, and /usr/local/share.
-
---disable-readline
- By default, libedit is built and installed such that it works as a
- drop-in replacement for the readline library. This option turns that
- behavior off.
-
---enable-debug
- Build debugging code (for libedit development).
-
-Optionally, define environment variables, including (not exclusively):
-
-CFLAGS="?"
- Pass these flags to the compiler. You probably shouldn't define this
- unless you know what you are doing.
-
-CPPFLAGS="?"
- Pass these flags to the C preprocessor. Note that CFLAGS is not passed
- to 'cpp' when 'configure' is looking for include files, so you must use
- CPPFLAGS instead if you need to help 'configure' find header files.
-
-LD_LIBRARY_PATH="?"
- 'ld' uses this colon-separated list to find libraries.
-
-LDFLAGS="?"
- Flags passed to 'gcc', which should normally be passed on to 'ld'.
-
-PATH="?"
- 'configure' uses this to find programs.
diff --git a/1.4/main/editline/Makefile.in b/1.4/main/editline/Makefile.in
deleted file mode 100644
index 47fbb8d09..000000000
--- a/1.4/main/editline/Makefile.in
+++ /dev/null
@@ -1,234 +0,0 @@
-#
-# Generic Makefile for libedit.
-#
-
-OSTYPE=$(shell uname -s)
-define cyg_subst_sys
- if uname -s | ${GREP} -qi cygwin; then \
- cat $@ | sed -e s/"sys\.h"/"config.h"/g > $@.copy; \
- mv --force $@.copy $@; \
- fi
-endef
-
-SHELL = /bin/sh
-
-CC = @CC@
-AR = @AR@
-RANLIB = @RANLIB@
-CPPFLAGS = @CPPFLAGS@ -I.
-CFLAGS = @CFLAGS@
-A_CFLAGS = @A_CFLAGS@
-S_CFLAGS = @S_CFLAGS@
-LDFLAGS = @LDFLAGS@
-S_LDFLAGS = @S_LDFLAGS@
-LIBS = @LIBS@
-
-INSTALL = @INSTALL@
-PREFIX = @prefix@
-
-ifeq ($(OSTYPE),SunOS)
-CFLAGS+=-DSOLARIS -I../../include/solaris-compat
-endif
-
-# .c files.
-ACSRCS = @ACSRCS@
-BCSRCS = @BCSRCS@
-CCSRCS = @CCSRCS@
-
-# Generated .c files.
-AGCSRCS = @AGCSRCS@
-BGCSRCS = @BGCSRCS@
-
-# .h files.
-HDRS = @HDRS@
-
-# Generated .h files.
-AGHDRS = @AGHDRS@
-BGHDRS = @BGHDRS@
-
-# Installed .h files.
-IHDRS = @IHDRS@
-IHDR_LINKS = @IHDR_LINKS@
-HDR_DIRS = @HDR_DIRS@
-
-# Man pages.
-MAN3 = @MAN3@
-MAN5 = @MAN5@
-MAN3_LINKS = @MAN3_LINKS@
-MAN_DIRS = @MAN_DIRS@
-
-# Library.
-LIB_DIRS = @LIB_DIRS@
-LIB_VER = @LIB_VER@
-LIB_A = @LIB_A@
-LIB_A_LINKS = @LIB_A_LINKS@
-LIB_S = @LIB_S@
-LIB_S_LINKS = @LIB_S_LINKS@
-
-# Test program.
-TEST = @TEST@
-TCSRCS = @TCSRCS@
-
-# Clear out all paths, then set just one (default path) for the main build
-# directory.
-.PATH :
-.PATH : .
-
-.SUFFIXES :
-.SUFFIXES : .c .o .o_a .o_s
-
-all : lib_a lib_s
-
-lib_a : $(LIB_A)
-lib_s : $(LIB_S)
-
-test : $(TEST)
-
-install : install_hdr install_lib install_man
-
-install_hdr :
- @for i in $(HDR_DIRS) ; do \
- echo "$(INSTALL) -d $(PREFIX)/$$i/"; \
- $(INSTALL) -d $(PREFIX)/$$i/; \
- done
- @for i in $(IHDRS); do \
- echo "$(INSTALL) -m 0444 $$i $(PREFIX)/include/`dirname $$i`/"; \
- $(INSTALL) -m 0444 $$i $(PREFIX)/include/`dirname $$i`/; \
- done
- @f=; \
- for i in $(IHDR_LINKS) ""; do \
- if test -z "$$f" ; then \
- f=$$i; \
- else \
- echo "rm -f $(PREFIX)/include/$$i"; \
- rm -f $(PREFIX)/include/$$i; \
- echo "ln -s $$f $(PREFIX)/include/$$i"; \
- ln -s $$f $(PREFIX)/include/$$i; \
- f=; \
- fi; \
- done
-
-install_lib : install_lib_a install_lib_s
-
-install_lib_common :
- @for i in $(LIB_DIRS) ; do \
- echo "$(INSTALL) -d $(PREFIX)/$$i/"; \
- $(INSTALL) -d $(PREFIX)/$$i/; \
- done
-
-install_lib_a : $(LIB_A) install_lib_common
- $(INSTALL) -m 0644 $(LIB_A) $(PREFIX)/lib/
- @f=; \
- for i in $(LIB_A_LINKS) ""; do \
- if test -z "$$f" ; then \
- f=$$i; \
- else \
- echo "rm -f $(PREFIX)/lib/$$i"; \
- rm -f $(PREFIX)/lib/$$i; \
- echo "ln -s $$f $(PREFIX)/lib/$$i"; \
- ln -s $$f $(PREFIX)/lib/$$i; \
- f=; \
- fi; \
- done
-
-install_lib_s : $(LIB_S) install_lib_common
- $(INSTALL) -m 0755 $(LIB_S) $(PREFIX)/lib/
- @f=; \
- for i in $(LIB_S_LINKS) ""; do \
- if test -z "$$f" ; then \
- f=$$i; \
- else \
- echo "rm -f $(PREFIX)/lib/$$i"; \
- rm -f $(PREFIX)/lib/$$i; \
- echo "ln -s $$f $(PREFIX)/lib/$$i"; \
- ln -s $$f $(PREFIX)/lib/$$i; \
- f=; \
- fi; \
- done
-
-install_man :
- @for i in $(MAN_DIRS) ; do \
- echo "$(INSTALL) -d $(PREFIX)/$$i/"; \
- $(INSTALL) -d $(PREFIX)/$$i/; \
- done
- @for i in $(MAN3); do \
- echo $(INSTALL) -m 0444 $$i $(PREFIX)/man/man3/; \
- $(INSTALL) -m 0444 $$i $(PREFIX)/man/man3/; \
- done
- @f=; \
- for i in $(MAN3_LINKS) ""; do \
- if test -z "$$f" ; then \
- f=$$i; \
- else \
- echo "rm -f $(PREFIX)/man/man3/$$i"; \
- rm -f $(PREFIX)/man/man3/$$i; \
- echo "ln -s $$f $(PREFIX)/man/man3/$$i"; \
- ln -s $$f $(PREFIX)/man/man3/$$i; \
- f=; \
- fi; \
- done
- @for i in $(MAN5); do\
- echo $(INSTALL) -m 0444 $$i $(PREFIX)/man/man5/; \
- $(INSTALL) -m 0444 $$i $(PREFIX)/man/man5/; \
- done
-
-clean :
- rm -f $(AGCSRCS) $(BGCSRCS) $(AGHDRS) $(BGHDRS) $(LIB_A) $(LIB_S)
- rm -f $(BGCSRCS:.c=.o_a) $(CCSRCS:.c=.o_a)
- rm -f $(BGCSRCS:.c=.o_s) $(CCSRCS:.c=.o_s)
- rm -f $(TCSRCS:.c=.o) $(TEST)
- rm -f *.s *.i
-
-distclean : clean
- rm -f config.cache config.log config.status config.h Makefile
-
-#
-# Internal targets and rules.
-#
-
-$(LIB_A) : $(BGCSRCS:.c=.o_a) $(CCSRCS:.c=.o_a)
- $(AR) cru $@ $?
- $(RANLIB) $@
-
-$(LIB_S) : $(BGCSRCS:.c=.o_s) $(CCSRCS:.c=.o_s)
- $(CC) $(S_LDFLAGS) -o $@ $(BGCSRCS:.c=.o_s) $(CCSRCS:.c=.o_s) $(LIBS)
-
-$(TEST) : $(TCSRCS:.c=.o) $(LIB_A)
- $(CC) -o $@ $(TCSRCS:.c=.o) $(LIB_A) $(LIBS)
-
-common.h : common.c
- $(SHELL) makelist -h common.c > $@
-
-emacs.h : emacs.c
- $(SHELL) makelist -h emacs.c> $@
-
-vi.h : vi.c
- $(SHELL) makelist -h vi.c > $@
-
-fcns.h : $(AGHDRS)
- $(SHELL) makelist -fh $(AGHDRS) > $@
-
-fcns.c : $(AGHDRS) fcns.h
- $(SHELL) makelist -fc $(AGHDRS) > $@
- $(cyg_subst_sys)
-
-help.h : $(ACSRCS)
- $(SHELL) makelist -bh $(ACSRCS) > $@
-
-help.c : $(ACSRCS) help.h
- $(SHELL) makelist -bc $(ACSRCS) > $@
- $(cyg_subst_sys)
-
-editline.c : $(ACSRCS) $(BCSRCS) $(AGCSRCS)
- $(SHELL) makelist -e $(ACSRCS) $(BCSRCS) $(AGCSRCS) > $@
-
-.c.o :
- $(CC) -c $(A_CFLAGS) $(CFLAGS) $(CPPFLAGS) $< -o $@
-
-.c.o_a : $(AGHDRS) $(BGHDRS)
- $(CC) -c $(A_CFLAGS) $(CFLAGS) $(CPPFLAGS) $< -o $@
-
-.c.o_s : $(AGHDRS) $(BGHDRS)
- $(CC) -c $(S_CFLAGS) $(CFLAGS) $(CPPFLAGS) $< -o $@
-
-$(CCSRCS) : $(BGHDRS)
diff --git a/1.4/main/editline/PLATFORMS b/1.4/main/editline/PLATFORMS
deleted file mode 100644
index ea7c5bb68..000000000
--- a/1.4/main/editline/PLATFORMS
+++ /dev/null
@@ -1,13 +0,0 @@
-This distribution of libedit is expected to work on at least the following
-platforms. It may also work on additional platforms, but no explicit support
-for them is built into the configuration system.
-
-* Apple OS X 10.1.
-
-* FreeBSD 4.x.
-
-* NetBSD 1.5.
-
-* Red Hat Linux 7.2.
-
-* Sun Solaris 2.6.
diff --git a/1.4/main/editline/README b/1.4/main/editline/README
deleted file mode 100644
index 49a2a6947..000000000
--- a/1.4/main/editline/README
+++ /dev/null
@@ -1,11 +0,0 @@
-libedit is a command line editing and history library. It is designed to be
-used by interactive programs that allow the user to type commands at a terminal
-prompt.
-
-The following files may be of direct interest to the user:
-
-* CHANGES - Software change log.
-
-* INSTALL - Installation information.
-
-* PLATFORMS - Supported platforms and platform-specific information.
diff --git a/1.4/main/editline/TEST/test.c b/1.4/main/editline/TEST/test.c
deleted file mode 100644
index 3169a2071..000000000
--- a/1.4/main/editline/TEST/test.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
- The Regents of the University of California. All rights reserved.\n");
-#endif /* not lint */
-
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * test.c: A little test program
- */
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#include "histedit.h"
-#include "tokenizer.h"
-
-static int continuation = 0;
-static EditLine *el = NULL;
-
-static u_char complete(EditLine *, int);
- int main(int, char **);
-static char *prompt(EditLine *);
-static void sig(int);
-
-static char *
-prompt(EditLine *el)
-{
- static char a[] = "Edit$";
- static char b[] = "Edit>";
-
- return (continuation ? b : a);
-}
-
-static void
-sig(int i)
-{
-
- (void) fprintf(stderr, "Got signal %d.\n", i);
- el_reset(el);
-}
-
-static unsigned char
-complete(EditLine *el, int ch)
-{
- DIR *dd = opendir(".");
- struct dirent *dp;
- const char* ptr;
- const LineInfo *lf = el_line(el);
- int len;
-
- /*
- * Find the last word
- */
- for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--)
- continue;
- len = lf->cursor - ++ptr;
-
- for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
- if (len > strlen(dp->d_name))
- continue;
- if (strncmp(dp->d_name, ptr, len) == 0) {
- closedir(dd);
- if (el_insertstr(el, &dp->d_name[len]) == -1)
- return (CC_ERROR);
- else
- return (CC_REFRESH);
- }
- }
-
- closedir(dd);
- return (CC_ERROR);
-}
-
-int
-main(int argc, char *argv[])
-{
- int num;
- const char *buf;
- Tokenizer *tok;
-#if 0
- int lastevent = 0;
-#endif
- int ncontinuation;
- History *hist;
- HistEvent ev;
-
- (void) signal(SIGINT, sig);
- (void) signal(SIGQUIT, sig);
- (void) signal(SIGHUP, sig);
- (void) signal(SIGTERM, sig);
-
- hist = history_init(); /* Init the builtin history */
- /* Remember 100 events */
- history(hist, &ev, H_SETSIZE, 100);
-
- tok = tok_init(NULL); /* Initialize the tokenizer */
-
- /* Initialize editline */
- el = el_init(*argv, stdin, stdout, stderr);
-
- el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
- el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
- el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
-
- /* Tell editline to use this history interface */
- el_set(el, EL_HIST, history, hist);
-
- /* Add a user-defined function */
- el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
-
- /* Bind tab to it */
- el_set(el, EL_BIND, "^I", "ed-complete", NULL);
-
- /*
- * Bind j, k in vi command mode to previous and next line, instead
- * of previous and next history.
- */
- el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
- el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
-
- /*
- * Source the user's defaults file.
- */
- el_source(el, NULL);
-
- while ((buf = el_gets(el, &num)) != NULL && num != 0) {
- int ac;
- const char **av;
-#ifdef DEBUG
- (void) fprintf(stderr, "got %d %s", num, buf);
-#endif
- if (!continuation && num == 1)
- continue;
-
- ncontinuation = tok_line(tok, buf, &ac, &av) > 0;
-#if 0
- if (continuation) {
- /*
- * Append to the right event in case the user
- * moved around in history.
- */
- if (history(hist, &ev, H_SET, lastevent) == -1)
- err(1, "%d: %s\n", lastevent, ev.str);
- history(hist, &ev, H_ADD , buf);
- } else {
- history(hist, &ev, H_ENTER, buf);
- lastevent = ev.num;
- }
-#else
- /* Simpler */
- history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
-#endif
-
- continuation = ncontinuation;
- ncontinuation = 0;
-
- if (strcmp(av[0], "history") == 0) {
- int rv;
-
- switch (ac) {
- case 1:
- for (rv = history(hist, &ev, H_LAST); rv != -1;
- rv = history(hist, &ev, H_PREV))
- (void) fprintf(stdout, "%4d %s",
- ev.num, ev.str);
- break;
-
- case 2:
- if (strcmp(av[1], "clear") == 0)
- history(hist, &ev, H_CLEAR);
- else
- goto badhist;
- break;
-
- case 3:
- if (strcmp(av[1], "load") == 0)
- history(hist, &ev, H_LOAD, av[2]);
- else if (strcmp(av[1], "save") == 0)
- history(hist, &ev, H_SAVE, av[2]);
- break;
-
- badhist:
- default:
- (void) fprintf(stderr,
- "Bad history arguments\n");
- break;
- }
- } else if (el_parse(el, ac, av) == -1) {
- switch (fork()) {
- case 0:
- execvp(av[0], (char *const *)av);
- perror(av[0]);
- _exit(1);
- /*NOTREACHED*/
- break;
-
- case -1:
- perror("fork");
- break;
-
- default:
- if (wait(&num) == -1)
- perror("wait");
- (void) fprintf(stderr, "Exit %x\n", num);
- break;
- }
- }
-
- tok_reset(tok);
- }
-
- el_end(el);
- tok_end(tok);
- history_end(hist);
-
- return (0);
-}
diff --git a/1.4/main/editline/chared.c b/1.4/main/editline/chared.c
deleted file mode 100644
index 8eaeb3b54..000000000
--- a/1.4/main/editline/chared.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/* $NetBSD: chared.c,v 1.15 2002/03/18 16:00:50 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: chared.c,v 1.15 2002/03/18 16:00:50 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * chared.c: Character editor utilities
- */
-#include <stdlib.h>
-#include "el.h"
-
-/* value to leave unused in line buffer */
-#define EL_LEAVE 2
-
-/* cv_undo():
- * Handle state for the vi undo command
- */
-protected void
-cv_undo(EditLine *el,int action, size_t size, char *ptr)
-{
- c_undo_t *vu = &el->el_chared.c_undo;
- vu->action = action;
- vu->ptr = ptr;
- vu->isize = size;
- (void) memcpy(vu->buf, vu->ptr, size);
-#ifdef DEBUG_UNDO
- (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n",
- vu->ptr, vu->isize, vu->dsize);
-#endif
-}
-
-
-/* c_insert():
- * Insert num characters
- */
-protected void
-c_insert(EditLine *el, int num)
-{
- char *cp;
-
- if (el->el_line.lastchar + num >= el->el_line.limit)
- return; /* can't go past end of buffer */
-
- if (el->el_line.cursor < el->el_line.lastchar) {
- /* if I must move chars */
- for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
- cp[num] = *cp;
- }
- el->el_line.lastchar += num;
-}
-
-
-/* c_delafter():
- * Delete num characters after the cursor
- */
-protected void
-c_delafter(EditLine *el, int num)
-{
-
- if (el->el_line.cursor + num > el->el_line.lastchar)
- num = el->el_line.lastchar - el->el_line.cursor;
-
- if (num > 0) {
- char *cp;
-
- if (el->el_map.current != el->el_map.emacs)
- cv_undo(el, INSERT, (size_t)num, el->el_line.cursor);
-
- for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
- *cp = cp[num];
-
- el->el_line.lastchar -= num;
- }
-}
-
-
-/* c_delbefore():
- * Delete num characters before the cursor
- */
-protected void
-c_delbefore(EditLine *el, int num)
-{
-
- if (el->el_line.cursor - num < el->el_line.buffer)
- num = el->el_line.cursor - el->el_line.buffer;
-
- if (num > 0) {
- char *cp;
-
- if (el->el_map.current != el->el_map.emacs)
- cv_undo(el, INSERT, (size_t)num,
- el->el_line.cursor - num);
-
- for (cp = el->el_line.cursor - num;
- cp <= el->el_line.lastchar;
- cp++)
- *cp = cp[num];
-
- el->el_line.lastchar -= num;
- }
-}
-
-
-/* ce__isword():
- * Return if p is part of a word according to emacs
- */
-protected int
-ce__isword(int p)
-{
- return (isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL);
-}
-
-
-/* cv__isword():
- * Return if p is part of a word according to vi
- */
-protected int
-cv__isword(int p)
-{
- return (!isspace(p));
-}
-
-
-/* c__prev_word():
- * Find the previous word
- */
-protected char *
-c__prev_word(char *p, char *low, int n, int (*wtest)(int))
-{
- p--;
-
- while (n--) {
- while ((p >= low) && !(*wtest)((unsigned char) *p))
- p--;
- while ((p >= low) && (*wtest)((unsigned char) *p))
- p--;
- }
-
- /* cp now points to one character before the word */
- p++;
- if (p < low)
- p = low;
- /* cp now points where we want it */
- return (p);
-}
-
-
-/* c__next_word():
- * Find the next word
- */
-protected char *
-c__next_word(char *p, char *high, int n, int (*wtest)(int))
-{
- while (n--) {
- while ((p < high) && !(*wtest)((unsigned char) *p))
- p++;
- while ((p < high) && (*wtest)((unsigned char) *p))
- p++;
- }
- if (p > high)
- p = high;
- /* p now points where we want it */
- return (p);
-}
-
-/* cv_next_word():
- * Find the next word vi style
- */
-protected char *
-cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
-{
- int test;
-
- while (n--) {
- test = (*wtest)((unsigned char) *p);
- while ((p < high) && (*wtest)((unsigned char) *p) == test)
- p++;
- /*
- * vi historically deletes with cw only the word preserving the
- * trailing whitespace! This is not what 'w' does..
- */
- if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
- while ((p < high) && isspace((unsigned char) *p))
- p++;
- }
-
- /* p now points where we want it */
- if (p > high)
- return (high);
- else
- return (p);
-}
-
-
-/* cv_prev_word():
- * Find the previous word vi style
- */
-protected char *
-cv_prev_word(EditLine *el, char *p, char *low, int n, int (*wtest)(int))
-{
- int test;
-
- while (n--) {
- p--;
- /*
- * vi historically deletes with cb only the word preserving the
- * leading whitespace! This is not what 'b' does..
- */
- if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
- while ((p > low) && isspace((unsigned char) *p))
- p--;
- test = (*wtest)((unsigned char) *p);
- while ((p >= low) && (*wtest)((unsigned char) *p) == test)
- p--;
- p++;
- while (isspace((unsigned char) *p))
- p++;
- }
-
- /* p now points where we want it */
- if (p < low)
- return (low);
- else
- return (p);
-}
-
-
-#ifdef notdef
-/* c__number():
- * Ignore character p points to, return number appearing after that.
- * A '$' by itself means a big number; "$-" is for negative; '^' means 1.
- * Return p pointing to last char used.
- */
-protected char *
-c__number(
- char *p, /* character position */
- int *num, /* Return value */
- int dval) /* dval is the number to subtract from like $-3 */
-{
- int i;
- int sign = 1;
-
- if (*++p == '^') {
- *num = 1;
- return (p);
- }
- if (*p == '$') {
- if (*++p != '-') {
- *num = 0x7fffffff; /* Handle $ */
- return (--p);
- }
- sign = -1; /* Handle $- */
- ++p;
- }
- for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
- continue;
- *num = (sign < 0 ? dval - i : i);
- return (--p);
-}
-#endif
-
-/* cv_delfini():
- * Finish vi delete action
- */
-protected void
-cv_delfini(EditLine *el)
-{
- int size;
- int oaction;
-
- if (el->el_chared.c_vcmd.action & INSERT)
- el->el_map.current = el->el_map.key;
-
- oaction = el->el_chared.c_vcmd.action;
- el->el_chared.c_vcmd.action = NOP;
-
- if (el->el_chared.c_vcmd.pos == 0)
- return;
-
-
- if (el->el_line.cursor > el->el_chared.c_vcmd.pos) {
- size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
- c_delbefore(el, size);
- el->el_line.cursor = el->el_chared.c_vcmd.pos;
- re_refresh_cursor(el);
- } else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
- size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
- c_delafter(el, size);
- } else {
- size = 1;
- c_delafter(el, size);
- }
- switch (oaction) {
- case DELETE|INSERT:
- el->el_chared.c_undo.action = DELETE|INSERT;
- break;
- case DELETE:
- el->el_chared.c_undo.action = INSERT;
- break;
- case NOP:
- case INSERT:
- default:
- EL_ABORT((el->el_errfile, "Bad oaction %d\n", oaction));
- break;
- }
-
-
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.dsize = size;
-}
-
-
-#ifdef notdef
-/* ce__endword():
- * Go to the end of this word according to emacs
- */
-protected char *
-ce__endword(char *p, char *high, int n)
-{
- p++;
-
- while (n--) {
- while ((p < high) && isspace((unsigned char) *p))
- p++;
- while ((p < high) && !isspace((unsigned char) *p))
- p++;
- }
-
- p--;
- return (p);
-}
-#endif
-
-
-/* cv__endword():
- * Go to the end of this word according to vi
- */
-protected char *
-cv__endword(char *p, char *high, int n)
-{
- p++;
-
- while (n--) {
- while ((p < high) && isspace((unsigned char) *p))
- p++;
-
- if (isalnum((unsigned char) *p))
- while ((p < high) && isalnum((unsigned char) *p))
- p++;
- else
- while ((p < high) && !(isspace((unsigned char) *p) ||
- isalnum((unsigned char) *p)))
- p++;
- }
- p--;
- return (p);
-}
-
-/* ch_init():
- * Initialize the character editor
- */
-protected int
-ch_init(EditLine *el)
-{
- el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
- if (el->el_line.buffer == NULL)
- return (-1);
-
- (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
- el->el_line.cursor = el->el_line.buffer;
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2];
-
- el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
- if (el->el_chared.c_undo.buf == NULL)
- return (-1);
- (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
- el->el_chared.c_undo.action = NOP;
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- el->el_chared.c_undo.ptr = el->el_line.buffer;
-
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_vcmd.pos = el->el_line.buffer;
- el->el_chared.c_vcmd.ins = el->el_line.buffer;
-
- el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
- if (el->el_chared.c_kill.buf == NULL)
- return (-1);
- (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
- el->el_chared.c_kill.mark = el->el_line.buffer;
- el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
-
- el->el_map.current = el->el_map.key;
-
- el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
- el->el_state.doingarg = 0;
- el->el_state.metanext = 0;
- el->el_state.argument = 1;
- el->el_state.lastcmd = ED_UNASSIGNED;
-
- el->el_chared.c_macro.nline = NULL;
- el->el_chared.c_macro.level = -1;
- el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO *
- sizeof(char *));
- if (el->el_chared.c_macro.macro == NULL)
- return (-1);
- return (0);
-}
-
-/* ch_reset():
- * Reset the character editor
- */
-protected void
-ch_reset(EditLine *el)
-{
- el->el_line.cursor = el->el_line.buffer;
- el->el_line.lastchar = el->el_line.buffer;
-
- el->el_chared.c_undo.action = NOP;
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- el->el_chared.c_undo.ptr = el->el_line.buffer;
-
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_vcmd.pos = el->el_line.buffer;
- el->el_chared.c_vcmd.ins = el->el_line.buffer;
-
- el->el_chared.c_kill.mark = el->el_line.buffer;
-
- el->el_map.current = el->el_map.key;
-
- el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
- el->el_state.doingarg = 0;
- el->el_state.metanext = 0;
- el->el_state.argument = 1;
- el->el_state.lastcmd = ED_UNASSIGNED;
-
- el->el_chared.c_macro.level = -1;
-
- el->el_history.eventno = 0;
-}
-
-/* ch_enlargebufs():
- * Enlarge line buffer to be able to hold twice as much characters.
- * Returns 1 if successful, 0 if not.
- */
-protected int
-ch_enlargebufs(el, addlen)
- EditLine *el;
- size_t addlen;
-{
- size_t sz, newsz;
- char *newbuffer, *oldbuf, *oldkbuf;
-
- sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
- newsz = sz * 2;
- /*
- * If newly required length is longer than current buffer, we need
- * to make the buffer big enough to hold both old and new stuff.
- */
- if (addlen > sz) {
- while(newsz - sz < addlen)
- newsz *= 2;
- }
-
- /*
- * Reallocate line buffer.
- */
- newbuffer = el_realloc(el->el_line.buffer, newsz);
- if (!newbuffer)
- return 0;
-
- /* zero the newly added memory, leave old data in */
- (void) memset(&newbuffer[sz], 0, newsz - sz);
-
- oldbuf = el->el_line.buffer;
-
- el->el_line.buffer = newbuffer;
- el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
- el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
- el->el_line.limit = &newbuffer[newsz - EL_LEAVE];
-
- /*
- * Reallocate kill buffer.
- */
- newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
- if (!newbuffer)
- return 0;
-
- /* zero the newly added memory, leave old data in */
- (void) memset(&newbuffer[sz], 0, newsz - sz);
-
- oldkbuf = el->el_chared.c_kill.buf;
-
- el->el_chared.c_kill.buf = newbuffer;
- el->el_chared.c_kill.last = newbuffer +
- (el->el_chared.c_kill.last - oldkbuf);
- el->el_chared.c_kill.mark = el->el_line.buffer +
- (el->el_chared.c_kill.mark - oldbuf);
-
- /*
- * Reallocate undo buffer.
- */
- newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
- if (!newbuffer)
- return 0;
-
- /* zero the newly added memory, leave old data in */
- (void) memset(&newbuffer[sz], 0, newsz - sz);
-
- el->el_chared.c_undo.ptr = el->el_line.buffer +
- (el->el_chared.c_undo.ptr - oldbuf);
- el->el_chared.c_undo.buf = newbuffer;
-
- if (!hist_enlargebuf(el, sz, newsz))
- return 0;
-
- return 1;
-}
-
-/* ch_end():
- * Free the data structures used by the editor
- */
-protected void
-ch_end(EditLine *el)
-{
- el_free((ptr_t) el->el_line.buffer);
- el->el_line.buffer = NULL;
- el->el_line.limit = NULL;
- el_free((ptr_t) el->el_chared.c_undo.buf);
- el->el_chared.c_undo.buf = NULL;
- el_free((ptr_t) el->el_chared.c_kill.buf);
- el->el_chared.c_kill.buf = NULL;
- el_free((ptr_t) el->el_chared.c_macro.macro);
- el->el_chared.c_macro.macro = NULL;
- ch_reset(el);
-}
-
-
-/* el_insertstr():
- * Insert string at cursorI
- */
-public int
-el_insertstr(EditLine *el, const char *s)
-{
- size_t len;
-
- if ((len = strlen(s)) == 0)
- return (-1);
- if (el->el_line.lastchar + len >= el->el_line.limit) {
- if (!ch_enlargebufs(el, len))
- return (-1);
- }
-
- c_insert(el, (int)len);
- while (*s)
- *el->el_line.cursor++ = *s++;
- return (0);
-}
-
-
-/* el_deletestr():
- * Delete num characters before the cursor
- */
-public void
-el_deletestr(EditLine *el, int n)
-{
- if (n <= 0)
- return;
-
- if (el->el_line.cursor < &el->el_line.buffer[n])
- return;
-
- c_delbefore(el, n); /* delete before dot */
- el->el_line.cursor -= n;
- if (el->el_line.cursor < el->el_line.buffer)
- el->el_line.cursor = el->el_line.buffer;
-}
-
-/* c_gets():
- * Get a string
- */
-protected int
-c_gets(EditLine *el, char *buf)
-{
- char ch;
- int len = 0;
-
- for (ch = 0; ch == 0;) {
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
- switch (ch) {
- case 0010: /* Delete and backspace */
- case 0177:
- if (len > 1) {
- *el->el_line.cursor-- = '\0';
- el->el_line.lastchar = el->el_line.cursor;
- buf[len--] = '\0';
- } else {
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
- }
- re_refresh(el);
- ch = 0;
- break;
-
- case 0033: /* ESC */
- case '\r': /* Newline */
- case '\n':
- break;
-
- default:
- if (len >= EL_BUFSIZ)
- term_beep(el);
- else {
- buf[len++] = ch;
- *el->el_line.cursor++ = ch;
- el->el_line.lastchar = el->el_line.cursor;
- }
- re_refresh(el);
- ch = 0;
- break;
- }
- }
- buf[len] = ch;
- return (len);
-}
-
-
-/* c_hpos():
- * Return the current horizontal position of the cursor
- */
-protected int
-c_hpos(EditLine *el)
-{
- char *ptr;
-
- /*
- * Find how many characters till the beginning of this line.
- */
- if (el->el_line.cursor == el->el_line.buffer)
- return (0);
- else {
- for (ptr = el->el_line.cursor - 1;
- ptr >= el->el_line.buffer && *ptr != '\n';
- ptr--)
- continue;
- return (el->el_line.cursor - ptr - 1);
- }
-}
diff --git a/1.4/main/editline/chared.h b/1.4/main/editline/chared.h
deleted file mode 100644
index 403eca011..000000000
--- a/1.4/main/editline/chared.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $NetBSD: chared.h,v 1.8 2002/03/18 16:00:51 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)chared.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.chared.h: Character editor interface
- */
-#ifndef _h_el_chared
-#define _h_el_chared
-
-#include <ctype.h>
-#include <string.h>
-
-#include "histedit.h"
-
-#define EL_MAXMACRO 10
-
-/*
- * This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works
- * like real vi: i.e. the transition from command<->insert modes moves
- * the cursor.
- *
- * On the other hand we really don't want to move the cursor, because
- * all the editing commands don't include the character under the cursor.
- * Probably the best fix is to make all the editing commands aware of
- * this fact.
- */
-#define VI_MOVE
-
-
-typedef struct c_macro_t {
- int level;
- char **macro;
- char *nline;
-} c_macro_t;
-
-/*
- * Undo information for both vi and emacs
- */
-typedef struct c_undo_t {
- int action;
- size_t isize;
- size_t dsize;
- char *ptr;
- char *buf;
-} c_undo_t;
-
-/*
- * Current action information for vi
- */
-typedef struct c_vcmd_t {
- int action;
- char *pos;
- char *ins;
-} c_vcmd_t;
-
-/*
- * Kill buffer for emacs
- */
-typedef struct c_kill_t {
- char *buf;
- char *last;
- char *mark;
-} c_kill_t;
-
-/*
- * Note that we use both data structures because the user can bind
- * commands from both editors!
- */
-typedef struct el_chared_t {
- c_undo_t c_undo;
- c_kill_t c_kill;
- c_vcmd_t c_vcmd;
- c_macro_t c_macro;
-} el_chared_t;
-
-
-#define STReof "^D\b\b"
-#define STRQQ "\"\""
-
-#define isglob(a) (strchr("*[]?", (a)) != NULL)
-#define isword(a) (isprint(a))
-
-#define NOP 0x00
-#define DELETE 0x01
-#define INSERT 0x02
-#define CHANGE 0x04
-
-#define CHAR_FWD 0
-#define CHAR_BACK 1
-
-#define MODE_INSERT 0
-#define MODE_REPLACE 1
-#define MODE_REPLACE_1 2
-
-#include "common.h"
-#include "vi.h"
-#include "emacs.h"
-#include "search.h"
-#include "fcns.h"
-
-
-protected int cv__isword(int);
-protected void cv_delfini(EditLine *);
-protected char *cv__endword(char *, char *, int);
-protected int ce__isword(int);
-protected void cv_undo(EditLine *, int, size_t, char *);
-protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
-protected char *cv_prev_word(EditLine*, char *, char *, int, int (*)(int));
-protected char *c__next_word(char *, char *, int, int (*)(int));
-protected char *c__prev_word(char *, char *, int, int (*)(int));
-protected void c_insert(EditLine *, int);
-protected void c_delbefore(EditLine *, int);
-protected void c_delafter(EditLine *, int);
-protected int c_gets(EditLine *, char *);
-protected int c_hpos(EditLine *);
-
-protected int ch_init(EditLine *);
-protected void ch_reset(EditLine *);
-protected int ch_enlargebufs(EditLine *, size_t);
-protected void ch_end(EditLine *);
-
-#endif /* _h_el_chared */
diff --git a/1.4/main/editline/common.c b/1.4/main/editline/common.c
deleted file mode 100644
index c831e79a3..000000000
--- a/1.4/main/editline/common.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/* $NetBSD: common.c,v 1.11 2002/03/18 16:00:51 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: common.c,v 1.11 2002/03/18 16:00:51 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * common.c: Common Editor functions
- */
-#include "el.h"
-
-/* ed_end_of_file():
- * Indicate end of file
- * [^D]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_end_of_file(EditLine *el, int c)
-{
-
- re_goto_bottom(el);
- *el->el_line.lastchar = '\0';
- return (CC_EOF);
-}
-
-
-/* ed_insert():
- * Add character to the line
- * Insert a character [bound to all insert keys]
- */
-protected el_action_t
-ed_insert(EditLine *el, int c)
-{
- int i;
-
- if (c == '\0')
- return (CC_ERROR);
-
- if (el->el_line.lastchar + el->el_state.argument >=
- el->el_line.limit) {
- /* end of buffer space, try to allocate more */
- if (!ch_enlargebufs(el, (size_t) el->el_state.argument))
- return CC_ERROR; /* error allocating more */
- }
-
- if (el->el_state.argument == 1) {
- if (el->el_state.inputmode != MODE_INSERT) {
- el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
- *el->el_line.cursor;
- el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
- '\0';
- c_delafter(el, 1);
- }
- c_insert(el, 1);
-
- *el->el_line.cursor++ = c;
- el->el_state.doingarg = 0; /* just in case */
- re_fastaddc(el); /* fast refresh for one char. */
- } else {
- if (el->el_state.inputmode != MODE_INSERT) {
- for (i = 0; i < el->el_state.argument; i++)
- el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
- el->el_line.cursor[i];
-
- el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
- '\0';
- c_delafter(el, el->el_state.argument);
- }
- c_insert(el, el->el_state.argument);
-
- while (el->el_state.argument--)
- *el->el_line.cursor++ = c;
- re_refresh(el);
- }
-
- if (el->el_state.inputmode == MODE_REPLACE_1)
- (void) vi_command_mode(el, 0);
-
- return (CC_NORM);
-}
-
-
-/* ed_delete_prev_word():
- * Delete from beginning of current word to cursor
- * [M-^?] [^W]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_delete_prev_word(EditLine *el, int c)
-{
- char *cp, *p, *kp;
-
- if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
-
- cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
- el->el_state.argument, ce__isword);
-
- for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
- *kp++ = *p;
- el->el_chared.c_kill.last = kp;
-
- c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
- el->el_line.cursor = cp;
- if (el->el_line.cursor < el->el_line.buffer)
- el->el_line.cursor = el->el_line.buffer; /* bounds check */
- return (CC_REFRESH);
-}
-
-
-/* ed_delete_next_char():
- * Delete character under cursor
- * [^D] [x]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_delete_next_char(EditLine *el, int c)
-{
-#ifdef notdef /* XXX */
-#define EL el->el_line
- (void) fprintf(el->el_errlfile,
- "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
- EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
- EL.lastchar, EL.limit, EL.limit);
-#endif
- if (el->el_line.cursor == el->el_line.lastchar) {
- /* if I'm at the end */
- if (el->el_map.type == MAP_VI) {
- if (el->el_line.cursor == el->el_line.buffer) {
- /* if I'm also at the beginning */
-#ifdef KSHVI
- return (CC_ERROR);
-#else
- term_overwrite(el, STReof, 4);
- /* then do a EOF */
- term__flush();
- return (CC_EOF);
-#endif
- } else {
-#ifdef KSHVI
- el->el_line.cursor--;
-#else
- return (CC_ERROR);
-#endif
- }
- } else {
- if (el->el_line.cursor != el->el_line.buffer)
- el->el_line.cursor--;
- else
- return (CC_ERROR);
- }
- }
- c_delafter(el, el->el_state.argument); /* delete after dot */
- if (el->el_line.cursor >= el->el_line.lastchar &&
- el->el_line.cursor > el->el_line.buffer)
- /* bounds check */
- el->el_line.cursor = el->el_line.lastchar - 1;
- return (CC_REFRESH);
-}
-
-
-/* ed_kill_line():
- * Cut to the end of line
- * [^K] [^K]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_kill_line(EditLine *el, int c)
-{
- char *kp, *cp;
-
- cp = el->el_line.cursor;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.lastchar)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- /* zap! -- delete to end */
- el->el_line.lastchar = el->el_line.cursor;
- return (CC_REFRESH);
-}
-
-
-/* ed_move_to_end():
- * Move cursor to the end of line
- * [^E] [^E]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_move_to_end(EditLine *el, int c)
-{
-
- el->el_line.cursor = el->el_line.lastchar;
- if (el->el_map.type == MAP_VI) {
-#ifdef VI_MOVE
- el->el_line.cursor--;
-#endif
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- }
- return (CC_CURSOR);
-}
-
-
-/* ed_move_to_beg():
- * Move cursor to the beginning of line
- * [^A] [^A]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_move_to_beg(EditLine *el, int c)
-{
-
- el->el_line.cursor = el->el_line.buffer;
-
- if (el->el_map.type == MAP_VI) {
- /* We want FIRST non space character */
- while (isspace((unsigned char) *el->el_line.cursor))
- el->el_line.cursor++;
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- }
- return (CC_CURSOR);
-}
-
-
-/* ed_transpose_chars():
- * Exchange the character to the left of the cursor with the one under it
- * [^T] [^T]
- */
-protected el_action_t
-ed_transpose_chars(EditLine *el, int c)
-{
-
- if (el->el_line.cursor < el->el_line.lastchar) {
- if (el->el_line.lastchar <= &el->el_line.buffer[1])
- return (CC_ERROR);
- else
- el->el_line.cursor++;
- }
- if (el->el_line.cursor > &el->el_line.buffer[1]) {
- /* must have at least two chars entered */
- c = el->el_line.cursor[-2];
- el->el_line.cursor[-2] = el->el_line.cursor[-1];
- el->el_line.cursor[-1] = c;
- return (CC_REFRESH);
- } else
- return (CC_ERROR);
-}
-
-
-/* ed_next_char():
- * Move to the right one character
- * [^F] [^F]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_next_char(EditLine *el, int c)
-{
-
- if (el->el_line.cursor >= el->el_line.lastchar)
- return (CC_ERROR);
-
- el->el_line.cursor += el->el_state.argument;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
-
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* ed_prev_word():
- * Move to the beginning of the current word
- * [M-b] [b]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_prev_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
-
- el->el_line.cursor = c__prev_word(el->el_line.cursor,
- el->el_line.buffer,
- el->el_state.argument,
- ce__isword);
-
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* ed_prev_char():
- * Move to the left one character
- * [^B] [^B]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_prev_char(EditLine *el, int c)
-{
-
- if (el->el_line.cursor > el->el_line.buffer) {
- el->el_line.cursor -= el->el_state.argument;
- if (el->el_line.cursor < el->el_line.buffer)
- el->el_line.cursor = el->el_line.buffer;
-
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
- } else
- return (CC_ERROR);
-}
-
-
-/* ed_quoted_insert():
- * Add the next character typed verbatim
- * [^V] [^V]
- */
-protected el_action_t
-ed_quoted_insert(EditLine *el, int c)
-{
- int num;
- char tc;
-
- tty_quotemode(el);
- num = el_getc(el, &tc);
- c = (unsigned char) tc;
- tty_noquotemode(el);
- if (num == 1)
- return (ed_insert(el, c));
- else
- return (ed_end_of_file(el, 0));
-}
-
-
-/* ed_digit():
- * Adds to argument or enters a digit
- */
-protected el_action_t
-ed_digit(EditLine *el, int c)
-{
-
- if (!isdigit(c))
- return (CC_ERROR);
-
- if (el->el_state.doingarg) {
- /* if doing an arg, add this in... */
- if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
- el->el_state.argument = c - '0';
- else {
- if (el->el_state.argument > 1000000)
- return (CC_ERROR);
- el->el_state.argument =
- (el->el_state.argument * 10) + (c - '0');
- }
- return (CC_ARGHACK);
- } else {
- if (el->el_line.lastchar + 1 >= el->el_line.limit) {
- if (!ch_enlargebufs(el, 1))
- return (CC_ERROR);
- }
-
- if (el->el_state.inputmode != MODE_INSERT) {
- el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
- *el->el_line.cursor;
- el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
- '\0';
- c_delafter(el, 1);
- }
- c_insert(el, 1);
- *el->el_line.cursor++ = c;
- el->el_state.doingarg = 0;
- re_fastaddc(el);
- }
- return (CC_NORM);
-}
-
-
-/* ed_argument_digit():
- * Digit that starts argument
- * For ESC-n
- */
-protected el_action_t
-ed_argument_digit(EditLine *el, int c)
-{
-
- if (!isdigit(c))
- return (CC_ERROR);
-
- if (el->el_state.doingarg) {
- if (el->el_state.argument > 1000000)
- return (CC_ERROR);
- el->el_state.argument = (el->el_state.argument * 10) +
- (c - '0');
- } else { /* else starting an argument */
- el->el_state.argument = c - '0';
- el->el_state.doingarg = 1;
- }
- return (CC_ARGHACK);
-}
-
-
-/* ed_unassigned():
- * Indicates unbound character
- * Bound to keys that are not assigned
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_unassigned(EditLine *el, int c)
-{
-
- term_beep(el);
- term__flush();
- return (CC_NORM);
-}
-
-
-/**
- ** TTY key handling.
- **/
-
-/* ed_tty_sigint():
- * Tty interrupt character
- * [^C]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_sigint(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_tty_dsusp():
- * Tty delayed suspend character
- * [^Y]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_dsusp(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_tty_flush_output():
- * Tty flush output characters
- * [^O]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_flush_output(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_tty_sigquit():
- * Tty quit character
- * [^\]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_sigquit(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_tty_sigtstp():
- * Tty suspend character
- * [^Z]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_sigtstp(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_tty_stop_output():
- * Tty disallow output characters
- * [^S]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_stop_output(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_tty_start_output():
- * Tty allow output characters
- * [^Q]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_tty_start_output(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_newline():
- * Execute command
- * [^J]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_newline(EditLine *el, int c)
-{
-
- re_goto_bottom(el);
- *el->el_line.lastchar++ = '\n';
- *el->el_line.lastchar = '\0';
- if (el->el_map.type == MAP_VI)
- el->el_chared.c_vcmd.ins = el->el_line.buffer;
- return (CC_NEWLINE);
-}
-
-
-/* ed_delete_prev_char():
- * Delete the character to the left of the cursor
- * [^?]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_delete_prev_char(EditLine *el, int c)
-{
-
- if (el->el_line.cursor <= el->el_line.buffer)
- return (CC_ERROR);
-
- c_delbefore(el, el->el_state.argument);
- el->el_line.cursor -= el->el_state.argument;
- if (el->el_line.cursor < el->el_line.buffer)
- el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
-}
-
-
-/* ed_clear_screen():
- * Clear screen leaving current line at the top
- * [^L]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_clear_screen(EditLine *el, int c)
-{
-
- term_clear_screen(el); /* clear the whole real screen */
- re_clear_display(el); /* reset everything */
- return (CC_REFRESH);
-}
-
-
-/* ed_redisplay():
- * Redisplay everything
- * ^R
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_redisplay(EditLine *el, int c)
-{
-
- return (CC_REDISPLAY);
-}
-
-
-/* ed_start_over():
- * Erase current line and start from scratch
- * [^G]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_start_over(EditLine *el, int c)
-{
-
- ch_reset(el);
- return (CC_REFRESH);
-}
-
-
-/* ed_sequence_lead_in():
- * First character in a bound sequence
- * Placeholder for external keys
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_sequence_lead_in(EditLine *el, int c)
-{
-
- return (CC_NORM);
-}
-
-
-/* ed_prev_history():
- * Move to the previous history line
- * [^P] [k]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_prev_history(EditLine *el, int c)
-{
- char beep = 0;
-
- el->el_chared.c_undo.action = NOP;
- *el->el_line.lastchar = '\0'; /* just in case */
-
- if (el->el_history.eventno == 0) { /* save the current buffer
- * away */
- (void) strncpy(el->el_history.buf, el->el_line.buffer,
- EL_BUFSIZ - 1);
- el->el_history.last = el->el_history.buf +
- (el->el_line.lastchar - el->el_line.buffer);
- }
- el->el_history.eventno += el->el_state.argument;
-
- if (hist_get(el) == CC_ERROR) {
- beep = 1;
- /* el->el_history.eventno was fixed by first call */
- (void) hist_get(el);
- }
- re_refresh(el);
- if (beep)
- return (CC_ERROR);
- else
- return (CC_NORM); /* was CC_UP_HIST */
-}
-
-
-/* ed_next_history():
- * Move to the next history line
- * [^N] [j]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_next_history(EditLine *el, int c)
-{
-
- el->el_chared.c_undo.action = NOP;
- *el->el_line.lastchar = '\0'; /* just in case */
-
- el->el_history.eventno -= el->el_state.argument;
-
- if (el->el_history.eventno < 0) {
- el->el_history.eventno = 0;
- return (CC_ERROR);/* make it beep */
- }
- return (hist_get(el));
-}
-
-
-/* ed_search_prev_history():
- * Search previous in history for a line matching the current
- * next search history [M-P] [K]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_search_prev_history(EditLine *el, int c)
-{
- const char *hp;
- int h;
- bool_t found = 0;
-
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_undo.action = NOP;
- *el->el_line.lastchar = '\0'; /* just in case */
- if (el->el_history.eventno < 0) {
-#ifdef DEBUG_EDIT
- (void) fprintf(el->el_errfile,
- "e_prev_search_hist(): eventno < 0;\n");
-#endif
- el->el_history.eventno = 0;
- return (CC_ERROR);
- }
- if (el->el_history.eventno == 0) {
- (void) strncpy(el->el_history.buf, el->el_line.buffer,
- EL_BUFSIZ - 1);
- el->el_history.last = el->el_history.buf +
- (el->el_line.lastchar - el->el_line.buffer);
- }
- if (el->el_history.ref == NULL)
- return (CC_ERROR);
-
- hp = HIST_FIRST(el);
- if (hp == NULL)
- return (CC_ERROR);
-
- c_setpat(el); /* Set search pattern !! */
-
- for (h = 1; h <= el->el_history.eventno; h++)
- hp = HIST_NEXT(el);
-
- while (hp != NULL) {
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
-#endif
- if ((strncmp(hp, el->el_line.buffer, (size_t)
- (el->el_line.lastchar - el->el_line.buffer)) ||
- hp[el->el_line.lastchar - el->el_line.buffer]) &&
- c_hmatch(el, hp)) {
- found++;
- break;
- }
- h++;
- hp = HIST_NEXT(el);
- }
-
- if (!found) {
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "not found\n");
-#endif
- return (CC_ERROR);
- }
- el->el_history.eventno = h;
-
- return (hist_get(el));
-}
-
-
-/* ed_search_next_history():
- * Search next in history for a line matching the current
- * [M-N] [J]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_search_next_history(EditLine *el, int c)
-{
- const char *hp;
- int h;
- bool_t found = 0;
-
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_undo.action = NOP;
- *el->el_line.lastchar = '\0'; /* just in case */
-
- if (el->el_history.eventno == 0)
- return (CC_ERROR);
-
- if (el->el_history.ref == NULL)
- return (CC_ERROR);
-
- hp = HIST_FIRST(el);
- if (hp == NULL)
- return (CC_ERROR);
-
- c_setpat(el); /* Set search pattern !! */
-
- for (h = 1; h < el->el_history.eventno && hp; h++) {
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
-#endif
- if ((strncmp(hp, el->el_line.buffer, (size_t)
- (el->el_line.lastchar - el->el_line.buffer)) ||
- hp[el->el_line.lastchar - el->el_line.buffer]) &&
- c_hmatch(el, hp))
- found = h;
- hp = HIST_NEXT(el);
- }
-
- if (!found) { /* is it the current history number? */
- if (!c_hmatch(el, el->el_history.buf)) {
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "not found\n");
-#endif
- return (CC_ERROR);
- }
- }
- el->el_history.eventno = found;
-
- return (hist_get(el));
-}
-
-
-/* ed_prev_line():
- * Move up one line
- * Could be [k] [^p]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_prev_line(EditLine *el, int c)
-{
- char *ptr;
- int nchars = c_hpos(el);
-
- /*
- * Move to the line requested
- */
- if (*(ptr = el->el_line.cursor) == '\n')
- ptr--;
-
- for (; ptr >= el->el_line.buffer; ptr--)
- if (*ptr == '\n' && --el->el_state.argument <= 0)
- break;
-
- if (el->el_state.argument > 0)
- return (CC_ERROR);
-
- /*
- * Move to the beginning of the line
- */
- for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
- continue;
-
- /*
- * Move to the character requested
- */
- for (ptr++;
- nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
- ptr++)
- continue;
-
- el->el_line.cursor = ptr;
- return (CC_CURSOR);
-}
-
-
-/* ed_next_line():
- * Move down one line
- * Could be [j] [^n]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_next_line(EditLine *el, int c)
-{
- char *ptr;
- int nchars = c_hpos(el);
-
- /*
- * Move to the line requested
- */
- for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
- if (*ptr == '\n' && --el->el_state.argument <= 0)
- break;
-
- if (el->el_state.argument > 0)
- return (CC_ERROR);
-
- /*
- * Move to the character requested
- */
- for (ptr++;
- nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
- ptr++)
- continue;
-
- el->el_line.cursor = ptr;
- return (CC_CURSOR);
-}
-
-
-/* ed_command():
- * Editline extended command
- * [M-X] [:]
- */
-protected el_action_t
-/*ARGSUSED*/
-ed_command(EditLine *el, int c)
-{
- char tmpbuf[EL_BUFSIZ];
- int tmplen;
-
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
-
- c_insert(el, 3); /* prompt + ": " */
- *el->el_line.cursor++ = '\n';
- *el->el_line.cursor++ = ':';
- *el->el_line.cursor++ = ' ';
- re_refresh(el);
-
- tmplen = c_gets(el, tmpbuf);
- tmpbuf[tmplen] = '\0';
-
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
-
- if (parse_line(el, tmpbuf) == -1)
- return (CC_ERROR);
- else
- return (CC_REFRESH);
-}
diff --git a/1.4/main/editline/config.guess b/1.4/main/editline/config.guess
deleted file mode 100755
index a6d8a945f..000000000
--- a/1.4/main/editline/config.guess
+++ /dev/null
@@ -1,1449 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-
-timestamp='2004-06-24'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
- --version | -v )
- echo "$version" ; exit 0 ;;
- --help | --h* | -h )
- echo "$usage"; exit 0 ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit 0 ;;
- amd64:OpenBSD:*:*)
- echo x86_64-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- cats:OpenBSD:*:*)
- echo arm-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- luna88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- macppc:OpenBSD:*:*)
- echo powerpc-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvmeppc:OpenBSD:*:*)
- echo powerpc-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mipseb-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit 0 ;;
- macppc:MirBSD:*:*)
- echo powerppc-unknown-mirbsd${UNAME_RELEASE}
- exit 0 ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit 0 ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit 0 ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit 0 ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit 0 ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit 0;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit 0 ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit 0 ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit 0 ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit 0 ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit 0;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit 0 ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit 0 ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit 0 ;;
- DRS?6000:UNIX_SV:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7 && exit 0 ;;
- esac ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit 0 ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit 0 ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit 0 ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit 0 ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit 0 ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit 0 ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit 0 ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit 0 ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit 0 ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c \
- && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && exit 0
- echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit 0 ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit 0 ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit 0 ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit 0 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit 0 ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit 0 ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit 0 ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit 0 ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit 0 ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit 0 ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit 0 ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit 0 ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit 0 ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit 0 ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
- echo rs6000-ibm-aix3.2.5
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit 0 ;;
- *:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit 0 ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit 0 ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit 0 ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit 0 ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit 0 ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit 0 ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit 0 ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- # avoid double evaluation of $set_cc_for_build
- test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit 0 ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
- echo unknown-hitachi-hiuxwe2
- exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit 0 ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit 0 ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit 0 ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit 0 ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit 0 ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit 0 ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit 0 ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit 0 ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit 0 ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit 0 ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit 0 ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit 0 ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit 0 ;;
- i*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit 0 ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit 0 ;;
- x86:Interix*:[34]*)
- echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
- exit 0 ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit 0 ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit 0 ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit 0 ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit 0 ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit 0 ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit 0 ;;
- arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit 0 ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
- test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
- test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
- ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit 0 ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit 0 ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit 0 ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit 0 ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit 0 ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit 0 ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit 0 ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit 0 ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit 0 ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit 0 ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #ifdef __INTEL_COMPILER
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
- test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
- ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit 0 ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit 0 ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit 0 ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit 0 ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit 0 ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit 0 ;;
- i*86:*:5:[78]*)
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit 0 ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit 0 ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit 0 ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit 0 ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit 0 ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit 0 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit 0 ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit 0 ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit 0 ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3${OS_REL} && exit 0
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit 0 ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit 0 ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit 0 ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit 0 ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit 0 ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit 0 ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit 0 ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit 0 ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit 0 ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit 0 ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit 0 ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit 0 ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
- *:Darwin:*:*)
- case `uname -p` in
- *86) UNAME_PROCESSOR=i686 ;;
- powerpc) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit 0 ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit 0 ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit 0 ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit 0 ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit 0 ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit 0 ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit 0 ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit 0 ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit 0 ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit 0 ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit 0 ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit 0 ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit 0 ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit 0 ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit 0 ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms && exit 0 ;;
- I*) echo ia64-dec-vms && exit 0 ;;
- V*) echo vax-dec-vms && exit 0 ;;
- esac
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit 0 ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- c34*)
- echo c34-convex-bsd
- exit 0 ;;
- c38*)
- echo c38-convex-bsd
- exit 0 ;;
- c4*)
- echo c4-convex-bsd
- exit 0 ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- ftp://ftp.gnu.org/pub/gnu/config/
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/1.4/main/editline/config.h.in b/1.4/main/editline/config.h.in
deleted file mode 100644
index 151fb226d..000000000
--- a/1.4/main/editline/config.h.in
+++ /dev/null
@@ -1,21 +0,0 @@
-#undef SUNOS
-#undef CYGWIN
-
-#undef HAVE_SYS_CDEFS_H
-#undef HAVE_TERMCAP_H
-#undef HAVE_CURSES_H
-#undef HAVE_NCURSES_H
-#undef HAVE_TERM_H
-#undef HAVE_VIS_H
-#undef HAVE_ISSETUGID
-
-#undef HAVE_STRLCAT
-#undef HAVE_STRLCPY
-#undef HAVE_FGETLN
-#undef HAVE_STRVIS
-#undef HAVE_STRUNVIS
-
-#include "sys.h"
-#ifdef CYGWIN
-# include "cygdef.h"
-#endif
diff --git a/1.4/main/editline/config.sub b/1.4/main/editline/config.sub
deleted file mode 100755
index 838237e98..000000000
--- a/1.4/main/editline/config.sub
+++ /dev/null
@@ -1,1412 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
-
-timestamp='2001-09-14'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Please send patches to <config-patches@gnu.org>.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
- --version | -v )
- echo "$version" ; exit 0 ;;
- --help | --h* | -h )
- echo "$usage"; exit 0 ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit 0;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
- | c4x | clipper \
- | d10v | d30v | dsp16xx \
- | fr30 \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | m32r | m68000 | m68k | m88k | mcore \
- | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el | mips64vr4300 \
- | mips64vr4300el | mips64vr5000 | mips64vr5000el \
- | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
- | mipsisa32 \
- | mn10200 | mn10300 \
- | ns16k | ns32k \
- | openrisc \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | s390 | s390x \
- | sh | sh[34] | sh[34]eb | shbe | shle \
- | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
- | stormy16 | strongarm \
- | tahoe | thumb | tic80 | tron \
- | v850 \
- | we32k \
- | x86 | xscale \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alphapca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armv*-* \
- | avr-* \
- | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c54x-* \
- | clipper-* | cray2-* | cydra-* \
- | d10v-* | d30v-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fr30-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | m32r-* \
- | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | mcore-* \
- | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
- | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
- | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* \
- | s390-* | s390x-* \
- | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
- | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
- | v850-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
- | ymp-* \
- | z8k-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- [cjt]90)
- basic_machine=${basic_machine}-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- os=-linux-gnu
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- os=-linux-gnu
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- mmix*)
- basic_machine=mmix-knuth
- os=-mmixware
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium | p5 | k5 | k6 | nexgen)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2)
- basic_machine=i686-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sparclite-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=t3e-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- windows32)
- basic_machine=i386-pc
- os=-windows32-msvcrt
- ;;
- xmp)
- basic_machine=xmp-cray
- os=-unicos
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- mips)
- if [ x$os = x-linux-gnu ]; then
- basic_machine=mips-unknown
- else
- basic_machine=mips-mips
- fi
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh3 | sh4 | sh3eb | sh4eb)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv9 | sparcv9b)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- c4x*)
- basic_machine=c4x-none
- os=-coff
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto*)
- os=-nto-qnx
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-ibm)
- os=-aix
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -vxsim* | -vxworks*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/1.4/main/editline/configure b/1.4/main/editline/configure
deleted file mode 100755
index 8f9075c5f..000000000
--- a/1.4/main/editline/configure
+++ /dev/null
@@ -1,2421 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
- --disable-readline Disable readline compatibility"
-ac_help="$ac_help
- --enable-debug Enable debugging code"
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=Makefile.in
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-
-CFLAGS=$CFLAGS
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:534: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:564: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_prog_rejected=no
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- if test -z "$CC"; then
- case "`uname -s`" in
- *win32* | *WIN32*)
- # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:615: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="cl"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
- ;;
- esac
- fi
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:647: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 658 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
- else
- ac_cv_prog_cc_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:689: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:694: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:703: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
-else
- GCC=
-fi
-
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:722: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_cc_g=yes
-else
- ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-
-if test "x$CFLAGS" = "x" ; then
- no_CFLAGS="yes"
-fi
-if test "x$no_CFLAGS" = "xyes" -a "x$GCC" = "xyes" ; then
- CFLAGS="-Wall -pipe -g3"
-fi
-A_CFLAGS=""
-
-S_CFLAGS="-fPIC -DPIC"
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:764: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 779 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 796 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -nologo -E"
- cat > conftest.$ac_ext <<EOF
-#line 813 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:819: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-
-ac_aux_dir=
-for ac_dir in ${GNUSYSTEM_AUX_DIR} $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Make sure we can run config.sub.
-if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:870: checking host system type" >&5
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-case "${host}" in
- *-*-darwin*)
- CFLAGS="$CFLAGS -fno-common -no-cpp-precomp"
- ABI="macho"
- ;;
- *-*-freebsd*)
- ABI="elf"
- ;;
- *-*-linux* | *cygwin*)
- if echo ${host} | grep -q cygwin ; then \
- echo "cygwin detected"; \
- S_CFLAGS=""; \
- echo "/* cygdef.h. Generated automatically by configure. */
-#ifndef _CYGDEF_H_
-#define _CYGDEF_H_ 1
-#include <sys/ioctl.h>
-#define __linux__ 1
-
-
-typedef void (*sig_t)(int);
-
-
-#endif /* _CYGDEF_H_ */" > cygdef.h; \
- echo "
- #define CYGWIN 1
-" > confdefs.h; \
- fi
- ABI="elf"
- ;;
- *-*-netbsd*)
- echo $ac_n "checking ABI""... $ac_c" 1>&6
-echo "configure:903: checking ABI" >&5
- cat > conftest.$ac_ext <<EOF
-#line 905 "configure"
-#include "confdefs.h"
-#ifdef __ELF__
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- rm -rf conftest*
- ABI="elf"
-else
- rm -rf conftest*
- ABI="aout"
-fi
-rm -f conftest*
-
- echo "$ac_t""$ABI" 1>&6
- ;;
- *-*-solaris2*)
- ABI="elf"
- cat >> confdefs.h <<\EOF
-#define SUNOS 1
-EOF
-
- ;;
- *)
- echo "$ac_t""Unsupported operating system: ${host}" 1>&6
- ABI="elf"
- ;;
-esac
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:949: checking for a BSD compatible install" >&5
-if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
- for ac_dir in $PATH; do
- # Account for people who put trailing slashes in PATH elements.
- case "$ac_dir/" in
- /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- if test -f $ac_dir/$ac_prog; then
- if test $ac_prog = install &&
- grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- else
- ac_cv_path_install="$ac_dir/$ac_prog -c"
- break 2
- fi
- fi
- done
- ;;
- esac
- done
- IFS="$ac_save_IFS"
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL="$ac_cv_path_install"
- else
- # As a last resort, use the slow shell script. We don't cache a
- # path for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the path is relative.
- INSTALL="$ac_install_sh"
- fi
-fi
-echo "$ac_t""$INSTALL" 1>&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1004: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-# Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1034: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$AR" in
- /*)
- ac_cv_path_AR="$AR" # Let the user override the test with a path.
- ;;
- ?:/*)
- ac_cv_path_AR="$AR" # Let the user override the test with a dos path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_path_AR="$ac_dir/$ac_word"
- break
- fi
- done
- IFS="$ac_save_ifs"
- ;;
-esac
-fi
-AR="$ac_cv_path_AR"
-if test -n "$AR"; then
- echo "$ac_t""$AR" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
-echo "configure:1068: checking for tgetent in -ltermcap" >&5
-ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ltermcap $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1076 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char tgetent();
-
-int main() {
-tgetent()
-; return 0; }
-EOF
-if { (eval echo configure:1087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo termcap | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-ltermcap $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-\
- echo $ac_n "checking for tgetent in -ltinfo""... $ac_c" 1>&6
-echo "configure:1114: checking for tgetent in -ltinfo" >&5
-ac_lib_var=`echo tinfo'_'tgetent | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ltinfo $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1122 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char tgetent();
-
-int main() {
-tgetent()
-; return 0; }
-EOF
-if { (eval echo configure:1133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo tinfo | sed -e 's/^a-zA-Z0-9_/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-ltinfo $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-\
- echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6
-echo "configure:1160: checking for tgetent in -lcurses" >&5
-ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lcurses $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1168 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char tgetent();
-
-int main() {
-tgetent()
-; return 0; }
-EOF
-if { (eval echo configure:1179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo curses | sed -e 's/^a-zA-Z0-9_/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lcurses $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-\
- echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6
-echo "configure:1206: checking for tgetent in -lncurses" >&5
-ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lncurses $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1214 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char tgetent();
-
-int main() {
-tgetent()
-; return 0; }
-EOF
-if { (eval echo configure:1225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo ncurses | sed -e 's/^a-zA-Z0-9_/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lncurses $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-\
- { echo "configure: error: termcap support not found" 1>&2; exit 1; }
-fi
-
-fi
-
-fi
-
-fi
-
-
-for ac_hdr in termcap.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1265: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1270 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1275: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-\
- for ac_hdr in term.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1303: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1308 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-\
- echo "$ac_t""Need term.h since termcap.h is missing" 1>&6
-fi
-done
-
- for ac_hdr in curses.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1345: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1350 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1355: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-\
- for ac_hdr in ncurses.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1383: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1388 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-\
- echo "$ac_t""Need curses.h or ncurses.h" 1>&6
-fi
-done
-
-fi
-done
-
-fi
-done
-
-
-for ac_hdr in sys/cdefs.h vis.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1432: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1437 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1442: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-for ac_func in issetugid
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1472: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1477 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-for ac_func in strlcat
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1527: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1532 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-CCSRCS="$CCSRCS np/strlcat.c"
-fi
-done
-
-for ac_func in strlcpy
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1583: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1588 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-CCSRCS="$CCSRCS np/strlcpy.c"
-fi
-done
-
-for ac_func in fgetln
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1639: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1644 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-CCSRCS="$CCSRCS np/fgetln.c"
-fi
-done
-
-for ac_func in strvis
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1695: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1700 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-CCSRCS="$CCSRCS np/vis.c"
-fi
-done
-
-for ac_func in strunvis
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1751: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1756 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-CCSRCS="$CCSRCS np/unvis.c"
-fi
-done
-
-
-cat > conftest.$ac_ext <<EOF
-#line 1806 "configure"
-#include "confdefs.h"
-#include <sys/cdefs.h>
-#ifdef __RCSID
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- CPPFLAGS="$CPPFLAGS '-D__RCSID(x)='"
-fi
-rm -f conftest*
-
-
-cat > conftest.$ac_ext <<EOF
-#line 1825 "configure"
-#include "confdefs.h"
-#include <sys/cdefs.h>
-#ifdef __COPYRIGHT
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- CPPFLAGS="$CPPFLAGS '-D__COPYRIGHT(x)='"
-fi
-rm -f conftest*
-
-
-cat > conftest.$ac_ext <<EOF
-#line 1844 "configure"
-#include "confdefs.h"
-#include <sys/cdefs.h>
-#ifdef __RENAME
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- CPPFLAGS="$CPPFLAGS '-D__RENAME(x)='"
-fi
-rm -f conftest*
-
-
-cat > conftest.$ac_ext <<EOF
-#line 1863 "configure"
-#include "confdefs.h"
-#include <sys/cdefs.h>
-#ifdef _DIAGASSERT
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- CPPFLAGS="$CPPFLAGS '-D_DIAGASSERT(x)='"
-fi
-rm -f conftest*
-
-
-# Check whether --enable-readline or --disable-readline was given.
-if test "${enable_readline+set}" = set; then
- enableval="$enable_readline"
- if test "x$enable_readline" != "xyes" ; then
- enable_readline="no"
-fi
-
-else
- enable_readline="yes"
-
-fi
-
-
-# Check whether --enable-debug or --disable-debug was given.
-if test "${enable_debug+set}" = set; then
- enableval="$enable_debug"
- if test "x$enable_debug" != "xyes" ; then
- enable_debug="no"
-fi
-
-else
- enable_debug="no"
-
-fi
-
-if test "x$enable_debug" = "xyes" ; then
- CPPFLAGS="$CPPFLAGS -DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG"
- CPPFLAGS="$CPPFLAGS -DDEBUG_REFRESH -DDEBUG_PASTE"
-fi
-
-
-
-ACSRCS="common.c emacs.c vi.c"
-BCSRCS="chared.c el.c hist.c key.c map.c parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c"
-CCSRCS="$CCSRCS history.c tokenizer.c"
-
-AGCSRCS="fcns.c help.c"
-BGCSRCS="editline.c"
-
-HDRS="chared.h el.h hist.h key.h map.h parse.h prompt.h refresh.h search.h sig.h sys.h term.h tokenizer.h tty.h"
-
-IHDRS="histedit.h"
-
-IHDR_LINKS=
-
-AGHDRS="common.h emacs.h vi.h"
-BGHDRS="fcns.h help.h"
-
-HDR_DIRS="include"
-
-MAN3="editline.3"
-MAN5="editrc.5"
-
-MAN3_LINKS=
-for i in el_init.3 el_end.3 el_reset.3 el_gets.3 el_getc.3 el_push.3 \
- el_parse.3 el_set.3 el_get.3 el_source.3 el_resize.3 el_line.3 \
- el_insertstr.3 el_deletestr.3 history_init.3 history_end.3 \
- history.3 ; do
- MAN3_LINKS="$MAN3_LINKS editline.3 $i"
-done
-
-MAN_DIRS="man/man3 man/man5"
-
-LIB_DIRS="lib"
-LIB_MAJOR="2"
-LIB_MINOR="6"
-LIB_A="libedit.a"
-LIB_A_LINKS=
-
-if test "x$ABI" = "xelf" ; then
- LIB_S="libedit.so.$LIB_MAJOR"
- LIB_S_LINK="libedit.so"
- LIB_S_LINKS="$LIB_S $LIB_S_LINK"
- S_LDFLAGS="-shared"
-elif test "x$ABI" = "xaout" ; then
- LIB_S="libedit.so.$LIB_MAJOR.$LIB_MINOR"
- LIB_S_LINKS=
- S_LDFLAGS="-shared"
-elif test "x$ABI" = "xmacho" ; then
- S_LDFLAGS="-shared"
- LIB_S="libedit.$LIB_MAJOR.dylib"
- LIB_S_LINK="libedit.dylib"
- LIB_S_LINKS="$LIB_S $LIB_S_LINK"
- if test "x$prefix" = "xNONE" ; then
- S_LDFLAGS="-undefined suppress -flat_namespace -dynamiclib -compatibility_version $LIB_MAJOR -current_version $LIB_MAJOR -install_name /usr/local/lib/$LIB_S"
- else
- S_LDFLAGS="-undefined suppress -flat_namespace -dynamiclib -compatibility_version $LIB_MAJOR -current_version $LIB_MAJOR -install_name $prefix/lib/$LIB_S"
- fi
-fi
-
-TEST="TEST/test"
-TCSRCS="TEST/test.c"
-
-if test "x$enable_readline" = "xyes" ; then
- CCSRCS="$CCSRCS readline.c"
- IHDRS="$IHDRS readline/readline.h"
- IHDR_LINKS="readline.h readline/history.h"
- HDR_DIRS="$HDR_DIRS include/readline"
- LIB_A_LINKS="$LIB_A_LINKS libedit.a libreadline.a"
- if test "x$ABI" = "xelf" ; then
- LIB_S_LINKS="$LIB_S_LINKS $LIB_S_LINK libreadline.so"
- elif test "x$ABI" = "xaout" ; then
- LIB_S_LINKS="$LIB_S_LINKS $LIB_S libreadline.so.$LIB_MAJOR.$LIB_MINOR"
- elif test "x$ABI" = "xmacho" ; then
- LIB_S_LINKS="$LIB_S_LINKS $LIB_S_LINK libreadline.dylib"
- fi
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.13"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-ac_given_INSTALL="$INSTALL"
-
-trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@A_CFLAGS@%$A_CFLAGS%g
-s%@S_CFLAGS@%$S_CFLAGS%g
-s%@CPP@%$CPP%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@RANLIB@%$RANLIB%g
-s%@AR@%$AR%g
-s%@ACSRCS@%$ACSRCS%g
-s%@BCSRCS@%$BCSRCS%g
-s%@CCSRCS@%$CCSRCS%g
-s%@AGCSRCS@%$AGCSRCS%g
-s%@BGCSRCS@%$BGCSRCS%g
-s%@HDRS@%$HDRS%g
-s%@IHDRS@%$IHDRS%g
-s%@IHDR_LINKS@%$IHDR_LINKS%g
-s%@AGHDRS@%$AGHDRS%g
-s%@BGHDRS@%$BGHDRS%g
-s%@HDR_DIRS@%$HDR_DIRS%g
-s%@MAN3@%$MAN3%g
-s%@MAN5@%$MAN5%g
-s%@MAN3_LINKS@%$MAN3_LINKS%g
-s%@MAN_DIRS@%$MAN_DIRS%g
-s%@LIB_DIRS@%$LIB_DIRS%g
-s%@LIB_VER@%$LIB_VER%g
-s%@LIB_A@%$LIB_A%g
-s%@LIB_A_LINKS@%$LIB_A_LINKS%g
-s%@LIB_S@%$LIB_S%g
-s%@LIB_S_LINKS@%$LIB_S_LINKS%g
-s%@S_LDFLAGS@%$S_LDFLAGS%g
-s%@TEST@%$TEST%g
-s%@TCSRCS@%$TCSRCS%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
- else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
- fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
- else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
- fi
-done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- case "$ac_given_INSTALL" in
- [/$]*) INSTALL="$ac_given_INSTALL" ;;
- *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
- esac
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
-
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-s%@INSTALL@%$INSTALL%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-if test "${CONFIG_HEADERS+set}" != set; then
-EOF
-cat >> $CONFIG_STATUS <<EOF
- CONFIG_HEADERS="config.h"
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-fi
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- cat $ac_file_inputs > conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-
-rm -f conftest.tail
-while :
-do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
- echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
- fi
-fi; done
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/1.4/main/editline/configure.in b/1.4/main/editline/configure.in
deleted file mode 100644
index 2e37d6b2a..000000000
--- a/1.4/main/editline/configure.in
+++ /dev/null
@@ -1,276 +0,0 @@
-dnl
-dnl Process this file with autoconf to produce a configure script.
-dnl
-AC_INIT(Makefile.in)
-
-dnl If CFLAGS isn't defined and using gcc, set CFLAGS to something reasonable.
-dnl Otherwise, just prevent autoconf from molesting CFLAGS.
-CFLAGS=$CFLAGS
-AC_PROG_CC
-if test "x$CFLAGS" = "x" ; then
- no_CFLAGS="yes"
-fi
-if test "x$no_CFLAGS" = "xyes" -a "x$GCC" = "xyes" ; then
- CFLAGS="-Wall -pipe -g3"
-fi
-A_CFLAGS=""
-AC_SUBST(A_CFLAGS)
-S_CFLAGS="-fPIC -DPIC"
-AC_SUBST(S_CFLAGS)
-AC_PROG_CPP
-
-dnl Platform-specific settings. The ABI can probably be determined
-dnl programmatically, but doing so is error-prone, which makes it generally
-dnl not worth the trouble.
-AC_CANONICAL_HOST
-case "${host}" in
- *-*-darwin*)
- CFLAGS="$CFLAGS -fno-common -no-cpp-precomp"
- ABI="macho"
- ;;
- *-*-freebsd*)
- ABI="elf"
- ;;
- *-*-linux* | *cygwin*)
- if echo ${host} | grep -q cygwin ; then \
- echo "cygwin detected"; \
- S_CFLAGS=""; \
- echo "/* cygdef.h. Generated automatically by configure. */
-#ifndef _CYGDEF_H_
-#define _CYGDEF_H_ 1
-#include <sys/ioctl.h>
-#define __linux__ 1
-
-
-typedef void (*sig_t)(int);
-
-
-#endif /* _CYGDEF_H_ */" > cygdef.h; \
- echo "
- #define CYGWIN 1
-" > confdefs.h; \
- fi
- ABI="elf"
- ;;
- *-*-netbsd*)
- AC_MSG_CHECKING(ABI)
- AC_EGREP_CPP(yes,
-[#ifdef __ELF__
- yes
-#endif
-],
- ABI="elf",
- ABI="aout")
- AC_MSG_RESULT($ABI)
- ;;
- *-*-solaris2*)
- ABI="elf"
- AC_DEFINE(SUNOS)
- ;;
- *)
- AC_MSG_RESULT(Unsupported operating system: ${host})
- ABI="elf"
- ;;
-esac
-
-AC_PROG_INSTALL
-AC_PROG_RANLIB
-AC_PATH_PROG(AR, ar, , $PATH)
-
-dnl Search for termcap access routines in termcap, tinfo, curses, and ncurses.
-AC_CHECK_LIB(termcap, tgetent, , \
- AC_CHECK_LIB(tinfo, tgetent, , \
- AC_CHECK_LIB(curses, tgetent, , \
- AC_CHECK_LIB(ncurses, tgetent, , \
- AC_MSG_ERROR(termcap support not found)))))
-
-dnl Use termcap.h if it exists; otherwise we need both term.h and [n]curses.h.
-AC_CHECK_HEADERS(termcap.h, , \
- AC_CHECK_HEADERS(term.h, , \
- AC_MSG_RESULT(Need term.h since termcap.h is missing))
- AC_CHECK_HEADERS(curses.h, , \
- AC_CHECK_HEADERS(ncurses.h, , \
- AC_MSG_RESULT(Need curses.h or ncurses.h))))
-
-AC_CHECK_HEADERS(sys/cdefs.h vis.h)
-
-AC_CHECK_FUNCS(issetugid)
-AC_CHECK_FUNCS(strlcat, , CCSRCS="$CCSRCS np/strlcat.c")
-AC_CHECK_FUNCS(strlcpy, , CCSRCS="$CCSRCS np/strlcpy.c")
-AC_CHECK_FUNCS(fgetln, , CCSRCS="$CCSRCS np/fgetln.c")
-AC_CHECK_FUNCS(strvis, , CCSRCS="$CCSRCS np/vis.c")
-AC_CHECK_FUNCS(strunvis, , CCSRCS="$CCSRCS np/unvis.c")
-
-AC_EGREP_CPP(yes,
-[#include <sys/cdefs.h>
-#ifdef __RCSID
- yes
-#endif
-], , [CPPFLAGS="$CPPFLAGS '-D__RCSID(x)='"])
-
-AC_EGREP_CPP(yes,
-[#include <sys/cdefs.h>
-#ifdef __COPYRIGHT
- yes
-#endif
-], , [CPPFLAGS="$CPPFLAGS '-D__COPYRIGHT(x)='"])
-
-AC_EGREP_CPP(yes,
-[#include <sys/cdefs.h>
-#ifdef __RENAME
- yes
-#endif
-], , [CPPFLAGS="$CPPFLAGS '-D__RENAME(x)='"])
-
-AC_EGREP_CPP(yes,
-[#include <sys/cdefs.h>
-#ifdef _DIAGASSERT
- yes
-#endif
-], , [CPPFLAGS="$CPPFLAGS '-D_DIAGASSERT(x)='"])
-
-dnl Enable readline compatibility by default.
-AC_ARG_ENABLE(readline, [ --disable-readline Disable readline compatibility],
-if test "x$enable_readline" != "xyes" ; then
- enable_readline="no"
-fi
-,
-enable_readline="yes"
-)
-
-dnl Optionally enable debugging.
-AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging code],
-if test "x$enable_debug" != "xyes" ; then
- enable_debug="no"
-fi
-,
-enable_debug="no"
-)
-if test "x$enable_debug" = "xyes" ; then
- CPPFLAGS="$CPPFLAGS -DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG"
- CPPFLAGS="$CPPFLAGS -DDEBUG_REFRESH -DDEBUG_PASTE"
-else
- CFLAGS="$CFLAGS -O"
-fi
-
-
-dnl
-dnl File lists. This is done here instead of in the Makefile in order to avoid
-dnl the need for conditionals.
-dnl
-
-dnl .c files.
-ACSRCS="common.c emacs.c vi.c"
-BCSRCS="chared.c el.c hist.c key.c map.c parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c"
-CCSRCS="$CCSRCS history.c tokenizer.c"
-
-dnl Generated .c files.
-AGCSRCS="fcns.c help.c"
-BGCSRCS="editline.c"
-
-dnl .h files.
-HDRS="chared.h el.h hist.h key.h map.h parse.h prompt.h refresh.h search.h sig.h sys.h term.h tokenizer.h tty.h"
-
-dnl Installed .h files.
-IHDRS="histedit.h"
-
-dnl Installed headers for readline compatibility.
-IHDR_LINKS=
-
-dnl Generated .h files.
-AGHDRS="common.h emacs.h vi.h"
-BGHDRS="fcns.h help.h"
-
-dnl Header installation directories.
-HDR_DIRS="include"
-
-dnl Man pages.
-MAN3="editline.3"
-MAN5="editrc.5"
-
-MAN3_LINKS=
-for i in el_init.3 el_end.3 el_reset.3 el_gets.3 el_getc.3 el_push.3 \
- el_parse.3 el_set.3 el_get.3 el_source.3 el_resize.3 el_line.3 \
- el_insertstr.3 el_deletestr.3 history_init.3 history_end.3 \
- history.3 ; do
- MAN3_LINKS="$MAN3_LINKS editline.3 $i"
-done
-
-dnl Man page installation directories.
-MAN_DIRS="man/man3 man/man5"
-
-dnl Library settings.
-LIB_DIRS="lib"
-LIB_MAJOR="2"
-LIB_MINOR="6"
-LIB_A="libedit.a"
-LIB_A_LINKS=
-
-if test "x$ABI" = "xelf" ; then
- LIB_S="libedit.so.$LIB_MAJOR"
- LIB_S_LINK="libedit.so"
- LIB_S_LINKS="$LIB_S $LIB_S_LINK"
- S_LDFLAGS="-shared"
-elif test "x$ABI" = "xaout" ; then
- LIB_S="libedit.so.$LIB_MAJOR.$LIB_MINOR"
- LIB_S_LINKS=
- S_LDFLAGS="-shared"
-elif test "x$ABI" = "xmacho" ; then
- S_LDFLAGS="-shared"
- LIB_S="libedit.$LIB_MAJOR.dylib"
- LIB_S_LINK="libedit.dylib"
- LIB_S_LINKS="$LIB_S $LIB_S_LINK"
- if test "x$prefix" = "xNONE" ; then
- S_LDFLAGS="-undefined suppress -flat_namespace -dynamiclib -compatibility_version $LIB_MAJOR -current_version $LIB_MAJOR -install_name /usr/local/lib/$LIB_S"
- else
- S_LDFLAGS="-undefined suppress -flat_namespace -dynamiclib -compatibility_version $LIB_MAJOR -current_version $LIB_MAJOR -install_name $prefix/lib/$LIB_S"
- fi
-fi
-
-dnl Test program.
-TEST="TEST/test"
-TCSRCS="TEST/test.c"
-
-dnl Add files to the lists if readline compatibility is enabled.
-if test "x$enable_readline" = "xyes" ; then
- CCSRCS="$CCSRCS readline.c"
- IHDRS="$IHDRS readline/readline.h"
- IHDR_LINKS="readline.h readline/history.h"
- HDR_DIRS="$HDR_DIRS include/readline"
- LIB_A_LINKS="$LIB_A_LINKS libedit.a libreadline.a"
- if test "x$ABI" = "xelf" ; then
- LIB_S_LINKS="$LIB_S_LINKS $LIB_S_LINK libreadline.so"
- elif test "x$ABI" = "xaout" ; then
- LIB_S_LINKS="$LIB_S_LINKS $LIB_S libreadline.so.$LIB_MAJOR.$LIB_MINOR"
- elif test "x$ABI" = "xmacho" ; then
- LIB_S_LINKS="$LIB_S_LINKS $LIB_S_LINK libreadline.dylib"
- fi
-fi
-
-AC_SUBST(ACSRCS)
-AC_SUBST(BCSRCS)
-AC_SUBST(CCSRCS)
-AC_SUBST(AGCSRCS)
-AC_SUBST(BGCSRCS)
-AC_SUBST(HDRS)
-AC_SUBST(IHDRS)
-AC_SUBST(IHDR_LINKS)
-AC_SUBST(AGHDRS)
-AC_SUBST(BGHDRS)
-AC_SUBST(HDR_DIRS)
-AC_SUBST(MAN3)
-AC_SUBST(MAN5)
-AC_SUBST(MAN3_LINKS)
-AC_SUBST(MAN_DIRS)
-AC_SUBST(LIB_DIRS)
-AC_SUBST(LIB_VER)
-AC_SUBST(LIB_A)
-AC_SUBST(LIB_A_LINKS)
-AC_SUBST(LIB_S)
-AC_SUBST(LIB_S_LINKS)
-AC_SUBST(S_LDFLAGS)
-AC_SUBST(TEST)
-AC_SUBST(TCSRCS)
-
-AC_CONFIG_HEADER(config.h)
-AC_OUTPUT(Makefile)
diff --git a/1.4/main/editline/editline.3 b/1.4/main/editline/editline.3
deleted file mode 100644
index 28f6ddb84..000000000
--- a/1.4/main/editline/editline.3
+++ /dev/null
@@ -1,646 +0,0 @@
-.\" $NetBSD: editline.3,v 1.25 2002/01/15 02:46:22 wiz Exp $
-.\"
-.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc.
-.\" All rights reserved.
-.\"
-.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd November 12, 1999
-.Os
-.Dt EDITLINE 3
-.Sh NAME
-.Nm editline ,
-.Nm el_init ,
-.Nm el_end ,
-.Nm el_reset ,
-.Nm el_gets ,
-.Nm el_getc ,
-.Nm el_push ,
-.Nm el_parse ,
-.Nm el_set ,
-.Nm el_source ,
-.Nm el_resize ,
-.Nm el_line ,
-.Nm el_insertstr ,
-.Nm el_deletestr ,
-.Nm history_init ,
-.Nm history_end ,
-.Nm history
-.Nd line editor and history functions
-.Sh LIBRARY
-.Lb libedit
-.Sh SYNOPSIS
-.Fd #include <histedit.h>
-.Ft EditLine *
-.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr"
-.Ft void
-.Fn el_end "EditLine *e"
-.Ft void
-.Fn el_reset "EditLine *e"
-.Ft const char *
-.Fn el_gets "EditLine *e" "int *count"
-.Ft int
-.Fn el_getc "EditLine *e" "char *ch"
-.Ft void
-.Fn el_push "EditLine *e" "const char *str"
-.Ft int
-.Fn el_parse "EditLine *e" "int argc" "char *argv[]"
-.Ft int
-.Fn el_set "EditLine *e" "int op" "..."
-.Ft int
-.Fn el_get "EditLine *e" "int op" "void *result"
-.Ft int
-.Fn el_source "EditLine *e" "const char *file"
-.Ft void
-.Fn el_resize "EditLine *e"
-.Ft const LineInfo *
-.Fn el_line "EditLine *e"
-.Ft int
-.Fn el_insertstr "EditLine *e" "const char *str"
-.Ft void
-.Fn el_deletestr "EditLine *e" "int count"
-.Ft History *
-.Fn history_init
-.Ft void
-.Fn history_end "History *h"
-.Ft int
-.Fn history "History *h" "HistEvent *ev" "int op" "..."
-.Sh DESCRIPTION
-The
-.Nm
-library provides generic line editing and history functions,
-similar to those found in
-.Xr sh 1 .
-.Pp
-These functions are available in the
-.Nm libedit
-library (which needs the
-.Nm libtermcap
-library).
-Programs should be linked with
-.Fl ledit ltermcap .
-.Sh LINE EDITING FUNCTIONS
-The line editing functions use a common data structure,
-.Fa EditLine ,
-which is created by
-.Fn el_init
-and freed by
-.Fn el_end .
-.Pp
-The following functions are available:
-.Bl -tag -width 4n
-.It Fn el_init
-Initialise the line editor, and return a data structure
-to be used by all other line editing functions.
-.Fa prog
-is the name of the invoking program, used when reading the
-.Xr editrc 5
-file to determine which settings to use.
-.Fa fin ,
-.Fa fout
-and
-.Fa ferr
-are the input, output, and error streams (respectively) to use.
-In this documentation, references to
-.Dq the tty
-are actually to this input/output stream combination.
-.It Fn el_end
-Clean up and finish with
-.Fa e ,
-assumed to have been created with
-.Fn el_init .
-.It Fn el_reset
-Reset the tty and the parser.
-This should be called after an error which may have upset the tty's
-state.
-.It Fn el_gets
-Read a line from the tty.
-.Fa count
-is modified to contain the number of characters read.
-Returns the line read if successful, or
-.Dv NULL
-if no characters were read or if an error occurred.
-.It Fn el_getc
-Read a character from the tty.
-.Fa ch
-is modified to contain the character read.
-Returns the number of characters read if successful, -1 otherwise.
-.It Fn el_push
-Pushes
-.Fa str
-back onto the input stream.
-This is used by the macro expansion mechanism.
-Refer to the description of
-.Ic bind
-.Fl s
-in
-.Xr editrc 5
-for more information.
-.It Fn el_parse
-Parses the
-.Fa argv
-array (which is
-.Fa argc
-elements in size)
-to execute builtin
-.Nm
-commands.
-If the command is prefixed with
-.Dq prog :
-then
-.Fn el_parse
-will only execute the command if
-.Dq prog
-matches the
-.Fa prog
-argument supplied to
-.Fn el_init .
-The return value is
--1 if the command is unknown,
-0 if there was no error or
-.Dq prog
-didn't match, or
-1 if the command returned an error.
-Refer to
-.Xr editrc 5
-for more information.
-.It Fn el_set
-Set
-.Nm
-parameters.
-.Fa op
-determines which parameter to set, and each operation has its
-own parameter list.
-.Pp
-The following values for
-.Fa op
-are supported, along with the required argument list:
-.Bl -tag -width 4n
-.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
-Define prompt printing function as
-.Fa f ,
-which is to return a string that contains the prompt.
-.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
-Define right side prompt printing function as
-.Fa f ,
-which is to return a string that contains the prompt.
-.It Dv EL_TERMINAL , Fa "const char *type"
-Define terminal type of the tty to be
-.Fa type ,
-or to
-.Ev TERM
-if
-.Fa type
-is
-.Dv NULL .
-.It Dv EL_EDITOR , Fa "const char *mode"
-Set editing mode to
-.Fa mode ,
-which must be one of
-.Dq emacs
-or
-.Dq vi .
-.It Dv EL_SIGNAL , Fa "int flag"
-If
-.Fa flag
-is non-zero,
-.Nm
-will install its own signal handler for the following signals when
-reading command input:
-.Dv SIGCONT ,
-.Dv SIGHUP ,
-.Dv SIGINT ,
-.Dv SIGQUIT ,
-.Dv SIGSTOP ,
-.Dv SIGTERM ,
-.Dv SIGTSTP ,
-and
-.Dv SIGWINCH .
-Otherwise, the current signal handlers will be used.
-.It Dv EL_BIND , Xo
-.Fa "const char *" ,
-.Fa "..." ,
-.Dv NULL
-.Xc
-Perform the
-.Ic bind
-builtin command.
-Refer to
-.Xr editrc 5
-for more information.
-.It Dv EL_ECHOTC , Xo
-.Fa "const char *" ,
-.Fa "..." ,
-.Dv NULL
-.Xc
-Perform the
-.Ic echotc
-builtin command.
-Refer to
-.Xr editrc 5
-for more information.
-.It Dv EL_SETTC , Xo
-.Fa "const char *" ,
-.Fa "..." ,
-.Dv NULL
-.Xc
-Perform the
-.Ic settc
-builtin command.
-Refer to
-.Xr editrc 5
-for more information.
-.It Dv EL_SETTY , Xo
-.Fa "const char *" ,
-.Fa "..." ,
-.Dv NULL
-.Xc
-Perform the
-.Ic setty
-builtin command.
-Refer to
-.Xr editrc 5
-for more information.
-.It Dv EL_TELLTC , Xo
-.Fa "const char *" ,
-.Fa "..." ,
-.Dv NULL
-.Xc
-Perform the
-.Ic telltc
-builtin command.
-Refer to
-.Xr editrc 5
-for more information.
-.It Dv EL_ADDFN , Xo
-.Fa "const char *name" ,
-.Fa "const char *help" ,
-.Fa "unsigned char (*func)(EditLine *e, int ch)
-.Xc
-Add a user defined function,
-.Fn func ,
-referred to as
-.Fa name
-which is invoked when a key which is bound to
-.Fa name
-is entered.
-.Fa help
-is a description of
-.Fa name .
-At invocation time,
-.Fa ch
-is the key which caused the invocation.
-The return value of
-.Fn func
-should be one of:
-.Bl -tag -width "CC_REDISPLAY"
-.It Dv CC_NORM
-Add a normal character.
-.It Dv CC_NEWLINE
-End of line was entered.
-.It Dv CC_EOF
-EOF was entered.
-.It Dv CC_ARGHACK
-Expecting further command input as arguments, do nothing visually.
-.It Dv CC_REFRESH
-Refresh display.
-.It Dv CC_REFRESH_BEEP
-Refresh display, and beep.
-.It Dv CC_CURSOR
-Cursor moved, so update and perform
-.Dv CC_REFRESH .
-.It Dv CC_REDISPLAY
-Redisplay entire input line.
-This is useful if a key binding outputs extra information.
-.It Dv CC_ERROR
-An error occurred.
-Beep, and flush tty.
-.It Dv CC_FATAL
-Fatal error, reset tty to known state.
-.El
-.It Dv EL_HIST , Xo
-.Fa "History *(*func)(History *, int op, ...)" ,
-.Fa "const char *ptr"
-.Xc
-Defines which history function to use, which is usually
-.Fn history .
-.Fa ptr
-should be the value returned by
-.Fn history_init .
-.It Dv EL_EDITMODE , Fa "int flag"
-If
-.Fa flag
-is non-zero,
-editing is enabled (the default).
-Note that this is only an indication, and does not
-affect the operation of
-.Nm "" .
-At this time, it is the caller's responsibility to
-check this
-(using
-.Fn el_get )
-to determine if editing should be enabled or not.
-.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
-Define the character reading function as
-.Fa f ,
-which is to return the number of characters read and store them in
-.Fa c .
-This function is called internally by
-.Fn el_gets
-and
-.Fn el_getc .
-The builtin function can be set or restored with the special function
-name ``EL_BUILTIN_GETCFN''.
-.It Dv EL_CLIENTDATA , Fa "void *data"
-Register
-.Fa data
-to be associated with this EditLine structure. It can be retrieved with
-the corresponding
-.Fn el_get
-call.
-.El
-.It Fn el_get
-Get
-.Nm
-parameters.
-.Fa op
-determines which parameter to retrieve into
-.Fa result .
-.Pp
-The following values for
-.Fa op
-are supported, along with actual type of
-.Fa result :
-.Bl -tag -width 4n
-.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
-Return a pointer to the function that displays the prompt.
-.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
-Return a pointer to the function that displays the rightside prompt.
-.It Dv EL_EDITOR , Fa "const char *"
-Return the name of the editor, which will be one of
-.Dq emacs
-or
-.Dq vi .
-.It Dv EL_SIGNAL , Fa "int *"
-Return non-zero if
-.Nm
-has installed private signal handlers (see
-.Fn el_get
-above).
-.It Dv EL_EDITMODE, Fa "int *"
-Return non-zero if editing is enabled.
-.It Dv EL_GETCFN, Fa "int (**f)(EditLine *, char *)"
-Return a pointer to the function that read characters, which is equal to
-``EL_BUILTIN_GETCFN'' in the case of the default builtin function.
-.It Dv EL_CLIENTDATA , Fa "void **data"
-Retrieve
-.Fa data
-previously registered with the corresponding
-.Fn el_set
-call.
-.El
-.It Fn el_source
-Initialise
-.Nm
-by reading the contents of
-.Fa file .
-.Fn el_parse
-is called for each line in
-.Fa file .
-If
-.Fa file
-is
-.Dv NULL ,
-try
-.Pa $PWD/.editrc
-then
-.Pa $HOME/.editrc .
-Refer to
-.Xr editrc 5
-for details on the format of
-.Fa file .
-.It Fn el_resize
-Must be called if the terminal size changes.
-If
-.Dv EL_SIGNAL
-has been set with
-.Fn el_set ,
-then this is done automatically.
-Otherwise, it's the responsibility of the application to call
-.Fn el_resize
-on the appropriate occasions.
-.It Fn el_line
-Return the editing information for the current line in a
-.Fa LineInfo
-structure, which is defined as follows:
-.Bd -literal
-typedef struct lineinfo {
- const char *buffer; /* address of buffer */
- const char *cursor; /* address of cursor */
- const char *lastchar; /* address of last character */
-} LineInfo;
-.Ed
-.It Fn el_insertstr
-Insert
-.Fa str
-into the line at the cursor.
-Returns -1 if
-.Fa str
-is empty or won't fit, and 0 otherwise.
-.It Fn el_deletestr
-Delete
-.Fa num
-characters before the cursor.
-.El
-.Sh HISTORY LIST FUNCTIONS
-The history functions use a common data structure,
-.Fa History ,
-which is created by
-.Fn history_init
-and freed by
-.Fn history_end .
-.Pp
-The following functions are available:
-.Bl -tag -width 4n
-.It Fn history_init
-Initialise the history list, and return a data structure
-to be used by all other history list functions.
-.It Fn history_end
-Clean up and finish with
-.Fa h ,
-assumed to have been created with
-.Fn history_init .
-.It Fn history
-Perform operation
-.Fa op
-on the history list, with optional arguments as needed by the
-operation.
-.Fa ev
-is changed accordingly to operation.
-The following values for
-.Fa op
-are supported, along with the required argument list:
-.Bl -tag -width 4n
-.It Dv H_SETSIZE , Fa "int size"
-Set size of history to
-.Fa size
-elements.
-.It Dv H_GETSIZE
-Get number of events currently in history.
-.It Dv H_END
-Cleans up and finishes with
-.Fa h ,
-assumed to be created with
-.Fn history_init .
-.It Dv H_CLEAR
-Clear the history.
-.It Dv H_FUNC , Xo
-.Fa "void *ptr" ,
-.Fa "history_gfun_t first" ,
-.Fa "history_gfun_t next" ,
-.Fa "history_gfun_t last" ,
-.Fa "history_gfun_t prev" ,
-.Fa "history_gfun_t curr" ,
-.Fa "history_sfun_t set" ,
-.Fa "history_vfun_t clear" ,
-.Fa "history_efun_t enter" ,
-.Fa "history_efun_t add"
-.Xc
-Define functions to perform various history operations.
-.Fa ptr
-is the argument given to a function when it's invoked.
-.It Dv H_FIRST
-Return the first element in the history.
-.It Dv H_LAST
-Return the last element in the history.
-.It Dv H_PREV
-Return the previous element in the history.
-.It Dv H_NEXT
-Return the next element in the history.
-.It Dv H_CURR
-Return the current element in the history.
-.It Dv H_SET
-Set the cursor to point to the requested element.
-.It Dv H_ADD , Fa "const char *str"
-Append
-.Fa str
-to the current element of the history, or create an element with
-.It Dv H_APPEND , Fa "const char *str"
-Append
-.Fa str
-to the last new element of the history.
-.It Dv H_ENTER , Fa "const char *str"
-Add
-.Fa str
-as a new element to the history, and, if necessary,
-removing the oldest entry to keep the list to the created size.
-.It Dv H_PREV_STR , Fa "const char *str"
-Return the closest previous event that starts with
-.Fa str .
-.It Dv H_NEXT_STR , Fa "const char *str"
-Return the closest next event that starts with
-.Fa str .
-.It Dv H_PREV_EVENT , Fa "int e"
-Return the previous event numbered
-.Fa e .
-.It Dv H_NEXT_EVENT , Fa "int e"
-Return the next event numbered
-.Fa e .
-.It Dv H_LOAD , Fa "const char *file"
-Load the history list stored in
-.Fa file .
-.It Dv H_SAVE , Fa "const char *file"
-Save the history list to
-.Fa file .
-.El
-.Pp
-.Fn history
-returns 0 if the operation
-.Fa op
-succeeds. Otherwise, -1 is returned and
-.Fa ev
-is updated to contain more details about the error.
-.El
-.\"XXX.Sh EXAMPLES
-.\"XXX: provide some examples
-.Sh SEE ALSO
-.Xr sh 1 ,
-.Xr signal 3 ,
-.Xr termcap 3 ,
-.Xr editrc 5
-.Sh HISTORY
-The
-.Nm
-library first appeared in
-.Bx 4.4 .
-.Dv CC_REDISPLAY
-appeared in
-.Nx 1.3 .
-.Dv CC_REFRESH_BEEP ,
-.Dv EL_EDITMODE
-and the readline emulation appeared in
-.Nx 1.4 .
-.Dv EL_RPROMPT
-appeared in
-.Nx 1.5 .
-.Sh AUTHORS
-The
-.Nm
-library was written by Christos Zoulas.
-Luke Mewburn wrote this manual and implemented
-.Dv CC_REDISPLAY ,
-.Dv CC_REFRESH_BEEP ,
-.Dv EL_EDITMODE ,
-and
-.Dv EL_RPROMPT .
-Jaromir Dolecek implemented the readline emulation.
-.Sh BUGS
-The tokenization functions are not publicly defined in
-.Fd <histedit.h> .
-.Pp
-At this time, it is the responsibility of the caller to
-check the result of the
-.Dv EL_EDITMODE
-operation of
-.Fn el_get
-(after an
-.Fn el_source
-or
-.Fn el_parse )
-to determine if
-.Nm
-should be used for further input.
-I.e.,
-.Dv EL_EDITMODE
-is purely an indication of the result of the most recent
-.Xr editrc 5
-.Ic edit
-command.
diff --git a/1.4/main/editline/editrc.5 b/1.4/main/editline/editrc.5
deleted file mode 100644
index ddd12897b..000000000
--- a/1.4/main/editline/editrc.5
+++ /dev/null
@@ -1,491 +0,0 @@
-.\" $NetBSD: editrc.5,v 1.12 2002/01/15 02:46:44 wiz Exp $
-.\"
-.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
-.\" All rights reserved.
-.\"
-.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the NetBSD
-.\" Foundation, Inc. and its contributors.
-.\" 4. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd November 8, 2000
-.Os
-.Dt EDITRC 5
-.Sh NAME
-.Nm editrc
-.Nd configuration file for editline library
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-The
-.Nm
-file defines various settings to be used by the
-.Xr editline 3
-library.
-.Pp
-The format of each line is:
-.Dl [prog:]command [arg [...]]
-.Pp
-.Ar command
-is one of the
-.Xr editline 3
-builtin commands.
-Refer to
-.Sx BUILTIN COMMANDS
-for more information.
-.Pp
-.Ar prog
-is the program name string that a program defines when it calls
-.Xr el_init 3
-to setup
-.Xr editline 3 ,
-which is usually
-.Va argv[0] .
-.Ar command
-will be executed for any program which matches
-.Ar prog .
-.Pp
-.Ar prog
-may also be a
-.Xr regex 3
-style
-regular expression, in which case
-.Ar command
-will be executed for any program that matches the regular expression.
-.Pp
-If
-.Ar prog
-is absent,
-.Ar command
-is executed for all programs.
-.Sh BUILTIN COMMANDS
-The
-.Nm editline
-library has some builtin commands, which affect the way
-that the line editing and history functions operate.
-These are based on similar named builtins present in the
-.Xr tcsh 1
-shell.
-.Pp
-The following builtin commands are available:
-.Bl -tag -width 4n
-.It Ic bind Xo
-.Op Fl a
-.Op Fl e
-.Op Fl k
-.Op Fl l
-.Op Fl r
-.Op Fl s
-.Op Fl v
-.Op Ar key Op Ar command
-.Xc
-Without options, list all bound keys, and the editor command to which
-each is bound.
-If
-.Ar key
-is supplied, show the bindings for
-.Ar key .
-If
-.Ar key command
-is supplied, bind
-.Ar command
-to
-.Ar key .
-Options include:
-.Bl -tag -width 4n
-.It Fl e
-Bind all keys to the standard GNU Emacs-like bindings.
-.It Fl v
-Bind all keys to the standard
-.Xr vi 1 -like
-bindings.
-.It Fl a
-List or change key bindings in the
-.Xr vi 1
-mode alternate (command mode) key map.
-.It Fl k
-.Ar key
-is interpreted as a symbolic arrow key name, which may be one of
-.Sq up ,
-.Sq down ,
-.Sq left
-or
-.Sq right .
-.It Fl l
-List all editor commands and a short description of each.
-.It Fl r
-Remove a key's binding.
-.It Fl s
-.Ar command
-is taken as a literal string and treated as terminal input when
-.Ar key
-is typed.
-Bound keys in
-.Ar command
-are themselves reinterpreted, and this continues for ten levels of
-interpretation.
-.El
-.Pp
-.Ar command
-may be one of the commands documented in
-.Sx "EDITOR COMMANDS"
-below, or another key.
-.Pp
-.Ar key
-and
-.Ar command
-can contain control characters of the form
-.Sm off
-.Sq No ^ Ar character
-.Sm on
-.Po
-e.g.
-.Sq ^A
-.Pc ,
-and the following backslashed escape sequences:
-.Pp
-.Bl -tag -compact -offset indent -width 4n
-.It Ic \ea
-Bell
-.It Ic \eb
-Backspace
-.It Ic \ee
-Escape
-.It Ic \ef
-Formfeed
-.It Ic \en
-Newline
-.It Ic \er
-Carriage return
-.It Ic \et
-Horizontal tab
-.It Ic \ev
-Vertical tab
-.Sm off
-.It Sy \e Ar nnn
-.Sm on
-The ASCII character corresponding to the octal number
-.Ar nnn .
-.El
-.Pp
-.Sq \e
-nullifies the special meaning of the following character,
-if it has any, notably
-.Sq \e
-and
-.Sq ^ .
-.It Ic echotc Xo
-.Op Fl sv
-.Ar arg
-.Ar ...
-.Xc
-Exercise terminal capabilities given in
-.Ar arg Ar ... .
-If
-.Ar arg
-is
-.Sq baud ,
-.Sq cols ,
-.Sq lines ,
-.Sq rows ,
-.Sq meta or
-.Sq tabs ,
-the value of that capability is printed, with
-.Dq yes
-or
-.Dq no
-indicating that the terminal does or does not have that capability.
-.Pp
-.Fl s
-returns an emptry string for non-existent capabilities, rather than
-causing an error.
-.Fl v
-causes messages to be verbose.
-.It Ic edit Op Li on | Li off
-Enable or disable the
-.Nm editline
-functionality in a program.
-.It Ic history
-List the history.
-.It Ic telltc
-List the values of all the terminal capabilities (see
-.Xr termcap 5 ) .
-.It Ic settc Ar cap Ar val
-Set the terminal capability
-.Ar cap
-to
-.Ar val ,
-as defined in
-.Xr termcap 5 .
-No sanity checking is done.
-.It Ic setty Xo
-.Op Fl a
-.Op Fl d
-.Op Fl q
-.Op Fl x
-.Op Ar +mode
-.Op Ar -mode
-.Op Ar mode
-.Xc
-Control which tty modes that
-.Nm
-won't allow the user to change.
-.Fl d ,
-.Fl q
-or
-.Fl x
-tells
-.Ic setty
-to act on the
-.Sq edit ,
-.Sq quote
-or
-.Sq execute
-set of tty modes respectively; defaulting to
-.Fl x .
-.Pp
-Without other arguments,
-.Ic setty
-lists the modes in the chosen set which are fixed on
-.Po
-.Sq +mode
-.Pc
-or off
-.Po
-.Sq -mode
-.Pc .
-.Fl a
-lists all tty modes in the chosen set regardless of the setting.
-With
-.Ar +mode ,
-.Ar -mode
-or
-.Ar mode ,
-fixes
-.Ar mode
-on or off or removes control of
-.Ar mode
-in the chosen set.
-.El
-.Sh EDITOR COMMANDS
-The following editor commands are available for use in key bindings:
-.\" Section automatically generated with makelist
-.Bl -tag -width 4n
-.It Ic vi-paste-next
-Vi paste previous deletion to the right of the cursor.
-.It Ic vi-paste-prev
-Vi paste previous deletion to the left of the cursor.
-.It Ic vi-prev-space-word
-Vi move to the previous space delimited word.
-.It Ic vi-prev-word
-Vi move to the previous word.
-.It Ic vi-next-space-word
-Vi move to the next space delimited word.
-.It Ic vi-next-word
-Vi move to the next word.
-.It Ic vi-change-case
-Vi change case of character under the cursor and advance one character.
-.It Ic vi-change-meta
-Vi change prefix command.
-.It Ic vi-insert-at-bol
-Vi enter insert mode at the beginning of line.
-.It Ic vi-replace-char
-Vi replace character under the cursor with the next character typed.
-.It Ic vi-replace-mode
-Vi enter replace mode.
-.It Ic vi-substitute-char
-Vi replace character under the cursor and enter insert mode.
-.It Ic vi-substitute-line
-Vi substitute entire line.
-.It Ic vi-change-to-eol
-Vi change to end of line.
-.It Ic vi-insert
-Vi enter insert mode.
-.It Ic vi-add
-Vi enter insert mode after the cursor.
-.It Ic vi-add-at-eol
-Vi enter insert mode at end of line.
-.It Ic vi-delete-meta
-Vi delete prefix command.
-.It Ic vi-end-word
-Vi move to the end of the current space delimited word.
-.It Ic vi-to-end-word
-Vi move to the end of the current word.
-.It Ic vi-undo
-Vi undo last change.
-.It Ic vi-command-mode
-Vi enter command mode (use alternative key bindings).
-.It Ic vi-zero
-Vi move to the beginning of line.
-.It Ic vi-delete-prev-char
-Vi move to previous character (backspace).
-.It Ic vi-list-or-eof
-Vi list choices for completion or indicate end of file if empty line.
-.It Ic vi-kill-line-prev
-Vi cut from beginning of line to cursor.
-.It Ic vi-search-prev
-Vi search history previous.
-.It Ic vi-search-next
-Vi search history next.
-.It Ic vi-repeat-search-next
-Vi repeat current search in the same search direction.
-.It Ic vi-repeat-search-prev
-Vi repeat current search in the opposite search direction.
-.It Ic vi-next-char
-Vi move to the character specified next.
-.It Ic vi-prev-char
-Vi move to the character specified previous.
-.It Ic vi-to-next-char
-Vi move up to the character specified next.
-.It Ic vi-to-prev-char
-Vi move up to the character specified previous.
-.It Ic vi-repeat-next-char
-Vi repeat current character search in the same search direction.
-.It Ic vi-repeat-prev-char
-Vi repeat current character search in the opposite search direction.
-.It Ic em-delete-or-list
-Delete character under cursor or list completions if at end of line.
-.It Ic em-delete-next-word
-Cut from cursor to end of current word.
-.It Ic em-yank
-Paste cut buffer at cursor position.
-.It Ic em-kill-line
-Cut the entire line and save in cut buffer.
-.It Ic em-kill-region
-Cut area between mark and cursor and save in cut buffer.
-.It Ic em-copy-region
-Copy area between mark and cursor to cut buffer.
-.It Ic em-gosmacs-traspose
-Exchange the two characters before the cursor.
-.It Ic em-next-word
-Move next to end of current word.
-.It Ic em-upper-case
-Uppercase the characters from cursor to end of current word.
-.It Ic em-capitol-case
-Capitalize the characters from cursor to end of current word.
-.It Ic em-lower-case
-Lowercase the characters from cursor to end of current word.
-.It Ic em-set-mark
-Set the mark at cursor.
-.It Ic em-exchange-mark
-Exchange the cursor and mark.
-.It Ic em-universal-argument
-Universal argument (argument times 4).
-.It Ic em-meta-next
-Add 8th bit to next character typed.
-.It Ic em-toggle-overwrite
-Switch from insert to overwrite mode or vice versa.
-.It Ic em-copy-prev-word
-Copy current word to cursor.
-.It Ic em-inc-search-next
-Emacs incremental next search.
-.It Ic em-inc-search-prev
-Emacs incremental reverse search.
-.It Ic ed-end-of-file
-Indicate end of file.
-.It Ic ed-insert
-Add character to the line.
-.It Ic ed-delete-prev-word
-Delete from beginning of current word to cursor.
-.It Ic ed-delete-next-char
-Delete character under cursor.
-.It Ic ed-kill-line
-Cut to the end of line.
-.It Ic ed-move-to-end
-Move cursor to the end of line.
-.It Ic ed-move-to-beg
-Move cursor to the beginning of line.
-.It Ic ed-transpose-chars
-Exchange the character to the left of the cursor with the one under it.
-.It Ic ed-next-char
-Move to the right one character.
-.It Ic ed-prev-word
-Move to the beginning of the current word.
-.It Ic ed-prev-char
-Move to the left one character.
-.It Ic ed-quoted-insert
-Add the next character typed verbatim.
-.It Ic ed-digit
-Adds to argument or enters a digit.
-.It Ic ed-argument-digit
-Digit that starts argument.
-.It Ic ed-unassigned
-Indicates unbound character.
-.It Ic ed-tty-sigint
-Tty interrupt character.
-.It Ic ed-tty-dsusp
-Tty delayed suspend character.
-.It Ic ed-tty-flush-output
-Tty flush output characters.
-.It Ic ed-tty-sigquit
-Tty quit character.
-.It Ic ed-tty-sigtstp
-Tty suspend character.
-.It Ic ed-tty-stop-output
-Tty disallow output characters.
-.It Ic ed-tty-start-output
-Tty allow output characters.
-.It Ic ed-newline
-Execute command.
-.It Ic ed-delete-prev-char
-Delete the character to the left of the cursor.
-.It Ic ed-clear-screen
-Clear screen leaving current line at the top.
-.It Ic ed-redisplay
-Redisplay everything.
-.It Ic ed-start-over
-Erase current line and start from scratch.
-.It Ic ed-sequence-lead-in
-First character in a bound sequence.
-.It Ic ed-prev-history
-Move to the previous history line.
-.It Ic ed-next-history
-Move to the next history line.
-.It Ic ed-search-prev-history
-Search previous in history for a line matching the current.
-.It Ic ed-search-next-history
-Search next in history for a line matching the current.
-.It Ic ed-prev-line
-Move up one line.
-.It Ic ed-next-line
-Move down one line.
-.It Ic ed-command
-Editline extended command.
-.El
-.\" End of section automatically generated with makelist
-.Sh SEE ALSO
-.Xr editline 3 ,
-.Xr regex 3 ,
-.Xr termcap 5
-.Sh AUTHORS
-The
-.Nm editline
-library was written by Christos Zoulas,
-and this manual was written by Luke Mewburn,
-with some sections inspired by
-.Xr tcsh 1 .
diff --git a/1.4/main/editline/el.c b/1.4/main/editline/el.c
deleted file mode 100644
index 514316fbe..000000000
--- a/1.4/main/editline/el.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/* $NetBSD: el.c,v 1.29 2002/03/18 16:00:52 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
-#else
-__RCSID("$NetBSD: el.c,v 1.29 2002/03/18 16:00:52 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * el.c: EditLine interface functions
- */
-#include <sys/types.h>
-#include <sys/param.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include "el.h"
-
-/* el_init():
- * Initialize editline and set default parameters.
- */
-public EditLine *
-el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
-{
-
- EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
-
- if (el == NULL)
- return (NULL);
-
- memset(el, 0, sizeof(EditLine));
-
- el->el_infd = fileno(fin);
- el->el_outfile = fout;
- el->el_errfile = ferr;
- el->el_prog = strdup(prog);
-
- /*
- * Initialize all the modules. Order is important!!!
- */
- el->el_flags = 0;
-
- if (term_init(el) == -1) {
- free(el->el_prog);
- el_free(el);
- return NULL;
- }
- (void) key_init(el);
- (void) map_init(el);
- if (tty_init(el) == -1)
- el->el_flags |= NO_TTY;
- (void) ch_init(el);
- (void) search_init(el);
- (void) hist_init(el);
- (void) prompt_init(el);
- (void) sig_init(el);
- (void) read_init(el);
-
- return (el);
-}
-
-
-/* el_end():
- * Clean up.
- */
-public void
-el_end(EditLine *el)
-{
-
- if (el == NULL)
- return;
-
- el_reset(el);
-
- term_end(el);
- key_end(el);
- map_end(el);
- tty_end(el);
- ch_end(el);
- search_end(el);
- hist_end(el);
- prompt_end(el);
- sig_end(el);
-
- if (el->el_prog)
- el_free((ptr_t) el->el_prog);
- el_free((ptr_t) el);
-}
-
-
-/* el_reset():
- * Reset the tty and the parser
- */
-public void
-el_reset(EditLine *el)
-{
-
- tty_cookedmode(el);
- ch_reset(el); /* XXX: Do we want that? */
-}
-
-
-/* el_set():
- * set the editline parameters
- */
-public int
-el_set(EditLine *el, int op, ...)
-{
- va_list va;
- int rv = 0;
-
- if (el == NULL)
- return (-1);
- va_start(va, op);
-
- switch (op) {
- case EL_PROMPT:
- case EL_RPROMPT:
- rv = prompt_set(el, va_arg(va, el_pfunc_t), op);
- break;
-
- case EL_TERMINAL:
- rv = term_set(el, va_arg(va, char *));
- break;
-
- case EL_EDITOR:
- rv = map_set_editor(el, va_arg(va, char *));
- break;
-
- case EL_SIGNAL:
- if (va_arg(va, int))
- el->el_flags |= HANDLE_SIGNALS;
- else
- el->el_flags &= ~HANDLE_SIGNALS;
- break;
-
- case EL_BIND:
- case EL_TELLTC:
- case EL_SETTC:
- case EL_ECHOTC:
- case EL_SETTY:
- {
- const char *argv[20];
- int i;
-
- for (i = 1; i < 20; i++)
- if ((argv[i] = va_arg(va, char *)) == NULL)
- break;
-
- switch (op) {
- case EL_BIND:
- argv[0] = "bind";
- rv = map_bind(el, i, argv);
- break;
-
- case EL_TELLTC:
- argv[0] = "telltc";
- rv = term_telltc(el, i, argv);
- break;
-
- case EL_SETTC:
- argv[0] = "settc";
- rv = term_settc(el, i, argv);
- break;
-
- case EL_ECHOTC:
- argv[0] = "echotc";
- rv = term_echotc(el, i, argv);
- break;
-
- case EL_SETTY:
- argv[0] = "setty";
- rv = tty_stty(el, i, argv);
- break;
-
- default:
- rv = -1;
- EL_ABORT((el->el_errfile, "Bad op %d\n", op));
- break;
- }
- break;
- }
-
- case EL_ADDFN:
- {
- char *name = va_arg(va, char *);
- char *help = va_arg(va, char *);
- el_func_t func = va_arg(va, el_func_t);
-
- rv = map_addfunc(el, name, help, func);
- break;
- }
-
- case EL_HIST:
- {
- hist_fun_t func = va_arg(va, hist_fun_t);
- ptr_t ptr = va_arg(va, char *);
-
- rv = hist_set(el, func, ptr);
- break;
- }
-
- case EL_EDITMODE:
- if (va_arg(va, int))
- el->el_flags &= ~EDIT_DISABLED;
- else
- el->el_flags |= EDIT_DISABLED;
- rv = 0;
- break;
-
- case EL_GETCFN:
- {
- el_rfunc_t rc = va_arg(va, el_rfunc_t);
- rv = el_read_setfn(el, rc);
- break;
- }
-
- case EL_CLIENTDATA:
- el->el_data = va_arg(va, void *);
- break;
-
- default:
- rv = -1;
- break;
- }
-
- va_end(va);
- return (rv);
-}
-
-
-/* el_get():
- * retrieve the editline parameters
- */
-public int
-el_get(EditLine *el, int op, void *ret)
-{
- int rv;
-
- if (el == NULL || ret == NULL)
- return (-1);
- switch (op) {
- case EL_PROMPT:
- case EL_RPROMPT:
- rv = prompt_get(el, (el_pfunc_t *) & ret, op);
- break;
-
- case EL_EDITOR:
- rv = map_get_editor(el, (const char **) &ret);
- break;
-
- case EL_SIGNAL:
- *((int *) ret) = (el->el_flags & HANDLE_SIGNALS);
- rv = 0;
- break;
-
- case EL_EDITMODE:
- *((int *) ret) = (!(el->el_flags & EDIT_DISABLED));
- rv = 0;
- break;
-
-#if 0 /* XXX */
- case EL_TERMINAL:
- rv = term_get(el, (const char *) &ret);
- break;
-
- case EL_BIND:
- case EL_TELLTC:
- case EL_SETTC:
- case EL_ECHOTC:
- case EL_SETTY:
- {
- char *argv[20];
- int i;
-
- for (i = 1; i < 20; i++)
- if ((argv[i] = va_arg(va, char *)) == NULL)
- break;
-
- switch (op) {
- case EL_BIND:
- argv[0] = "bind";
- rv = map_bind(el, i, argv);
- break;
-
- case EL_TELLTC:
- argv[0] = "telltc";
- rv = term_telltc(el, i, argv);
- break;
-
- case EL_SETTC:
- argv[0] = "settc";
- rv = term_settc(el, i, argv);
- break;
-
- case EL_ECHOTC:
- argv[0] = "echotc";
- rv = term_echotc(el, i, argv);
- break;
-
- case EL_SETTY:
- argv[0] = "setty";
- rv = tty_stty(el, i, argv);
- break;
-
- default:
- rv = -1;
- EL_ABORT((el->errfile, "Bad op %d\n", op));
- break;
- }
- break;
- }
-
- case EL_ADDFN:
- {
- char *name = va_arg(va, char *);
- char *help = va_arg(va, char *);
- el_func_t func = va_arg(va, el_func_t);
-
- rv = map_addfunc(el, name, help, func);
- break;
- }
-
- case EL_HIST:
- {
- hist_fun_t func = va_arg(va, hist_fun_t);
- ptr_t ptr = va_arg(va, char *);
- rv = hist_set(el, func, ptr);
- }
- break;
-#endif /* XXX */
-
- case EL_GETCFN:
- *((el_rfunc_t *)ret) = el_read_getfn(el);
- rv = 0;
- break;
-
- case EL_CLIENTDATA:
- *((void **)ret) = el->el_data;
- rv = 0;
- break;
-
- default:
- rv = -1;
- }
-
- return (rv);
-}
-
-
-/* el_line():
- * Return editing info
- */
-public const LineInfo *
-el_line(EditLine *el)
-{
-
- return (const LineInfo *) (void *) &el->el_line;
-}
-
-
-/* el_source():
- * Source a file
- */
-public int
-el_source(EditLine *el, const char *fname)
-{
- FILE *fp;
- size_t len;
- char *ptr;
-
- fp = NULL;
- if (fname == NULL) {
-#ifdef HAVE_ISSETUGID
- static const char elpath[] = "/.editrc";
- char path[MAXPATHLEN];
-
- if (issetugid())
- return (-1);
- if ((ptr = getenv("HOME")) == NULL)
- return (-1);
- if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
- return (-1);
- if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
- return (-1);
- fname = path;
-#else
- /*
- * If issetugid() is missing, always return an error, in order
- * to keep from inadvertently opening up the user to a security
- * hole.
- */
- return (-1);
-#endif
- }
- if (fp == NULL)
- fp = fopen(fname, "r");
- if (fp == NULL)
- return (-1);
-
- while ((ptr = fgetln(fp, &len)) != NULL) {
- if (len > 0 && ptr[len - 1] == '\n')
- --len;
- ptr[len] = '\0';
- if (parse_line(el, ptr) == -1) {
- (void) fclose(fp);
- return (-1);
- }
- }
-
- (void) fclose(fp);
- return (0);
-}
-
-
-/* el_resize():
- * Called from program when terminal is resized
- */
-public void
-el_resize(EditLine *el)
-{
- int lins, cols;
- sigset_t oset, nset;
-
- (void) sigemptyset(&nset);
- (void) sigaddset(&nset, SIGWINCH);
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
-
- /* get the correct window size */
- if (term_get_size(el, &lins, &cols))
- term_change_size(el, lins, cols);
-
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
-}
-
-
-/* el_beep():
- * Called from the program to beep
- */
-public void
-el_beep(EditLine *el)
-{
-
- term_beep(el);
-}
-
-
-/* el_editmode()
- * Set the state of EDIT_DISABLED from the `edit' command.
- */
-protected int
-/*ARGSUSED*/
-el_editmode(EditLine *el, int argc, const char **argv)
-{
- const char *how;
-
- if (argv == NULL || argc != 2 || argv[1] == NULL)
- return (-1);
-
- how = argv[1];
- if (strcmp(how, "on") == 0)
- el->el_flags &= ~EDIT_DISABLED;
- else if (strcmp(how, "off") == 0)
- el->el_flags |= EDIT_DISABLED;
- else {
- (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
- return (-1);
- }
- return (0);
-}
diff --git a/1.4/main/editline/el.h b/1.4/main/editline/el.h
deleted file mode 100644
index 641081e87..000000000
--- a/1.4/main/editline/el.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* $NetBSD: el.h,v 1.11 2002/03/18 16:00:52 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)el.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.h: Internal structures.
- */
-#ifndef _h_el
-#define _h_el
-/*
- * Local defaults
- */
-#define KSHVI
-#define VIDEFAULT
-#define ANCHOR
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#define EL_BUFSIZ 1024 /* Maximum line size */
-
-#define HANDLE_SIGNALS 1<<0
-#define NO_TTY 1<<1
-#define EDIT_DISABLED 1<<2
-
-typedef int bool_t; /* True or not */
-
-typedef unsigned char el_action_t; /* Index to command array */
-
-typedef struct coord_t { /* Position on the screen */
- int h;
- int v;
-} coord_t;
-
-typedef struct el_line_t {
- char *buffer; /* Input line */
- char *cursor; /* Cursor position */
- char *lastchar; /* Last character */
- const char *limit; /* Max position */
-} el_line_t;
-
-/*
- * Editor state
- */
-typedef struct el_state_t {
- int inputmode; /* What mode are we in? */
- int doingarg; /* Are we getting an argument? */
- int argument; /* Numeric argument */
- int metanext; /* Is the next char a meta char */
- el_action_t lastcmd; /* Previous command */
-} el_state_t;
-
-/*
- * Until we come up with something better...
- */
-#define el_malloc(a) malloc(a)
-#define el_realloc(a,b) realloc(a, b)
-#define el_free(a) free(a)
-
-#include "tty.h"
-#include "prompt.h"
-#include "key.h"
-#include "term.h"
-#include "refresh.h"
-#include "chared.h"
-#include "common.h"
-#include "search.h"
-#include "hist.h"
-#include "map.h"
-#include "parse.h"
-#include "sig.h"
-#include "help.h"
-#include "read.h"
-
-struct editline {
- char *el_prog; /* the program name */
- FILE *el_outfile; /* Stdio stuff */
- FILE *el_errfile; /* Stdio stuff */
- int el_infd; /* Input file descriptor */
- int el_flags; /* Various flags. */
- coord_t el_cursor; /* Cursor location */
- char **el_display; /* Real screen image = what is there */
- char **el_vdisplay; /* Virtual screen image = what we see */
- void *el_data; /* Client data */
- el_line_t el_line; /* The current line information */
- el_state_t el_state; /* Current editor state */
- el_term_t el_term; /* Terminal dependent stuff */
- el_tty_t el_tty; /* Tty dependent stuff */
- el_refresh_t el_refresh; /* Refresh stuff */
- el_prompt_t el_prompt; /* Prompt stuff */
- el_prompt_t el_rprompt; /* Prompt stuff */
- el_chared_t el_chared; /* Characted editor stuff */
- el_map_t el_map; /* Key mapping stuff */
- el_key_t el_key; /* Key binding stuff */
- el_history_t el_history; /* History stuff */
- el_search_t el_search; /* Search stuff */
- el_signal_t el_signal; /* Signal handling stuff */
- el_read_t el_read; /* Character reading stuff */
-};
-
-protected int el_editmode(EditLine *, int, const char **);
-
-#ifdef DEBUG
-#define EL_ABORT(a) (void) (fprintf(el->el_errfile, "%s, %d: ", \
- __FILE__, __LINE__), fprintf a, abort())
-#else
-#define EL_ABORT(a) abort()
-#endif
-#endif /* _h_el */
diff --git a/1.4/main/editline/emacs.c b/1.4/main/editline/emacs.c
deleted file mode 100644
index f520d024b..000000000
--- a/1.4/main/editline/emacs.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/* $NetBSD: emacs.c,v 1.10 2002/03/18 16:00:52 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: emacs.c,v 1.10 2002/03/18 16:00:52 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * emacs.c: Emacs functions
- */
-#include "el.h"
-
-/* em_delete_or_list():
- * Delete character under cursor or list completions if at end of line
- * [^D]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_delete_or_list(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.lastchar) {
- /* if I'm at the end */
- if (el->el_line.cursor == el->el_line.buffer) {
- /* and the beginning */
- term_overwrite(el, STReof, 4); /* then do a EOF */
- term__flush();
- return (CC_EOF);
- } else {
- /*
- * Here we could list completions, but it is an
- * error right now
- */
- term_beep(el);
- return (CC_ERROR);
- }
- } else {
- c_delafter(el, el->el_state.argument); /* delete after dot */
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- /* bounds check */
- return (CC_REFRESH);
- }
-}
-
-
-/* em_delete_next_word():
- * Cut from cursor to end of current word
- * [M-d]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_delete_next_word(EditLine *el, int c)
-{
- char *cp, *p, *kp;
-
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
-
- cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
-
- for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
- /* save the text */
- *kp++ = *p;
- el->el_chared.c_kill.last = kp;
-
- c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- /* bounds check */
- return (CC_REFRESH);
-}
-
-
-/* em_yank():
- * Paste cut buffer at cursor position
- * [^Y]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_yank(EditLine *el, int c)
-{
- char *kp, *cp;
-
- if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
- if (!ch_enlargebufs(el, 1))
- return (CC_ERROR);
- }
-
- if (el->el_line.lastchar +
- (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
- el->el_line.limit)
- return (CC_ERROR);
-
- el->el_chared.c_kill.mark = el->el_line.cursor;
- cp = el->el_line.cursor;
-
- /* open the space, */
- c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
- /* copy the chars */
- for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
- *cp++ = *kp;
-
- /* if an arg, cursor at beginning else cursor at end */
- if (el->el_state.argument == 1)
- el->el_line.cursor = cp;
-
- return (CC_REFRESH);
-}
-
-
-/* em_kill_line():
- * Cut the entire line and save in cut buffer
- * [^U]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_kill_line(EditLine *el, int c)
-{
- char *kp, *cp;
-
- cp = el->el_line.buffer;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.lastchar)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- /* zap! -- delete all of it */
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
-}
-
-
-/* em_kill_region():
- * Cut area between mark and cursor and save in cut buffer
- * [^W]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_kill_region(EditLine *el, int c)
-{
- char *kp, *cp;
-
- if (!el->el_chared.c_kill.mark)
- return (CC_ERROR);
-
- if (el->el_chared.c_kill.mark > el->el_line.cursor) {
- cp = el->el_line.cursor;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_chared.c_kill.mark)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- c_delafter(el, cp - el->el_line.cursor);
- } else { /* mark is before cursor */
- cp = el->el_chared.c_kill.mark;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.cursor)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- c_delbefore(el, cp - el->el_chared.c_kill.mark);
- el->el_line.cursor = el->el_chared.c_kill.mark;
- }
- return (CC_REFRESH);
-}
-
-
-/* em_copy_region():
- * Copy area between mark and cursor to cut buffer
- * [M-W]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_copy_region(EditLine *el, int c)
-{
- char *kp, *cp;
-
- if (el->el_chared.c_kill.mark)
- return (CC_ERROR);
-
- if (el->el_chared.c_kill.mark > el->el_line.cursor) {
- cp = el->el_line.cursor;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_chared.c_kill.mark)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- } else {
- cp = el->el_chared.c_kill.mark;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.cursor)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- }
- return (CC_NORM);
-}
-
-
-/* em_gosmacs_traspose():
- * Exchange the two characters before the cursor
- * Gosling emacs transpose chars [^T]
- */
-protected el_action_t
-em_gosmacs_traspose(EditLine *el, int c)
-{
-
- if (el->el_line.cursor > &el->el_line.buffer[1]) {
- /* must have at least two chars entered */
- c = el->el_line.cursor[-2];
- el->el_line.cursor[-2] = el->el_line.cursor[-1];
- el->el_line.cursor[-1] = c;
- return (CC_REFRESH);
- } else
- return (CC_ERROR);
-}
-
-
-/* em_next_word():
- * Move next to end of current word
- * [M-f]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_next_word(EditLine *el, int c)
-{
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
-
- el->el_line.cursor = c__next_word(el->el_line.cursor,
- el->el_line.lastchar,
- el->el_state.argument,
- ce__isword);
-
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* em_upper_case():
- * Uppercase the characters from cursor to end of current word
- * [M-u]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_upper_case(EditLine *el, int c)
-{
- char *cp, *ep;
-
- ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
-
- for (cp = el->el_line.cursor; cp < ep; cp++)
- if (islower((unsigned char) *cp))
- *cp = toupper(*cp);
-
- el->el_line.cursor = ep;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
-}
-
-
-/* em_capitol_case():
- * Capitalize the characters from cursor to end of current word
- * [M-c]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_capitol_case(EditLine *el, int c)
-{
- char *cp, *ep;
-
- ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
-
- for (cp = el->el_line.cursor; cp < ep; cp++) {
- if (isalpha((unsigned char) *cp)) {
- if (islower((unsigned char) *cp))
- *cp = toupper(*cp);
- cp++;
- break;
- }
- }
- for (; cp < ep; cp++)
- if (isupper((unsigned char) *cp))
- *cp = tolower(*cp);
-
- el->el_line.cursor = ep;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
-}
-
-
-/* em_lower_case():
- * Lowercase the characters from cursor to end of current word
- * [M-l]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_lower_case(EditLine *el, int c)
-{
- char *cp, *ep;
-
- ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
-
- for (cp = el->el_line.cursor; cp < ep; cp++)
- if (isupper((unsigned char) *cp))
- *cp = tolower(*cp);
-
- el->el_line.cursor = ep;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
-}
-
-
-/* em_set_mark():
- * Set the mark at cursor
- * [^@]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_set_mark(EditLine *el, int c)
-{
-
- el->el_chared.c_kill.mark = el->el_line.cursor;
- return (CC_NORM);
-}
-
-
-/* em_exchange_mark():
- * Exchange the cursor and mark
- * [^X^X]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_exchange_mark(EditLine *el, int c)
-{
- char *cp;
-
- cp = el->el_line.cursor;
- el->el_line.cursor = el->el_chared.c_kill.mark;
- el->el_chared.c_kill.mark = cp;
- return (CC_CURSOR);
-}
-
-
-/* em_universal_argument():
- * Universal argument (argument times 4)
- * [^U]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_universal_argument(EditLine *el, int c)
-{ /* multiply current argument by 4 */
-
- if (el->el_state.argument > 1000000)
- return (CC_ERROR);
- el->el_state.doingarg = 1;
- el->el_state.argument *= 4;
- return (CC_ARGHACK);
-}
-
-
-/* em_meta_next():
- * Add 8th bit to next character typed
- * [<ESC>]
- */
-protected el_action_t
-/*ARGSUSED*/
-em_meta_next(EditLine *el, int c)
-{
-
- el->el_state.metanext = 1;
- return (CC_ARGHACK);
-}
-
-
-/* em_toggle_overwrite():
- * Switch from insert to overwrite mode or vice versa
- */
-protected el_action_t
-/*ARGSUSED*/
-em_toggle_overwrite(EditLine *el, int c)
-{
-
- el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
- MODE_REPLACE : MODE_INSERT;
- return (CC_NORM);
-}
-
-
-/* em_copy_prev_word():
- * Copy current word to cursor
- */
-protected el_action_t
-/*ARGSUSED*/
-em_copy_prev_word(EditLine *el, int c)
-{
- char *cp, *oldc, *dp;
-
- if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
-
- oldc = el->el_line.cursor;
- /* does a bounds check */
- cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
- el->el_state.argument, ce__isword);
-
- c_insert(el, oldc - cp);
- for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
- *dp++ = *cp;
-
- el->el_line.cursor = dp;/* put cursor at end */
-
- return (CC_REFRESH);
-}
-
-
-/* em_inc_search_next():
- * Emacs incremental next search
- */
-protected el_action_t
-/*ARGSUSED*/
-em_inc_search_next(EditLine *el, int c)
-{
-
- el->el_search.patlen = 0;
- return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
-}
-
-
-/* em_inc_search_prev():
- * Emacs incremental reverse search
- */
-protected el_action_t
-/*ARGSUSED*/
-em_inc_search_prev(EditLine *el, int c)
-{
-
- el->el_search.patlen = 0;
- return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
-}
diff --git a/1.4/main/editline/hist.c b/1.4/main/editline/hist.c
deleted file mode 100644
index 11f39ae10..000000000
--- a/1.4/main/editline/hist.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* $NetBSD: hist.c,v 1.10 2002/03/18 16:00:53 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: hist.c,v 1.10 2002/03/18 16:00:53 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * hist.c: History access functions
- */
-#include <stdlib.h>
-#include "el.h"
-
-/* hist_init():
- * Initialization function.
- */
-protected int
-hist_init(EditLine *el)
-{
-
- el->el_history.fun = NULL;
- el->el_history.ref = NULL;
- el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
- el->el_history.sz = EL_BUFSIZ;
- if (el->el_history.buf == NULL)
- return (-1);
- el->el_history.last = el->el_history.buf;
- return (0);
-}
-
-
-/* hist_end():
- * clean up history;
- */
-protected void
-hist_end(EditLine *el)
-{
-
- el_free((ptr_t) el->el_history.buf);
- el->el_history.buf = NULL;
-}
-
-
-/* hist_set():
- * Set new history interface
- */
-protected int
-hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
-{
-
- el->el_history.ref = ptr;
- el->el_history.fun = fun;
- return (0);
-}
-
-
-/* hist_get():
- * Get a history line and update it in the buffer.
- * eventno tells us the event to get.
- */
-protected el_action_t
-hist_get(EditLine *el)
-{
- const char *hp;
- int h;
-
- if (el->el_history.eventno == 0) { /* if really the current line */
- (void) strncpy(el->el_line.buffer, el->el_history.buf,
- el->el_history.sz - 1);
- el->el_line.lastchar = el->el_line.buffer +
- (el->el_history.last - el->el_history.buf);
-
-#ifdef KSHVI
- if (el->el_map.type == MAP_VI)
- el->el_line.cursor = el->el_line.buffer;
- else
-#endif /* KSHVI */
- el->el_line.cursor = el->el_line.lastchar;
-
- return (CC_REFRESH);
- }
- if (el->el_history.ref == NULL)
- return (CC_ERROR);
-
- hp = HIST_FIRST(el);
-
- if (hp == NULL)
- return (CC_ERROR);
-
- for (h = 1; h < el->el_history.eventno; h++)
- if ((hp = HIST_NEXT(el)) == NULL) {
- el->el_history.eventno = h;
- return (CC_ERROR);
- }
- (void) strncpy(el->el_line.buffer, hp,
- (size_t)(el->el_line.limit - el->el_line.buffer));
- el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
-
- if (el->el_line.lastchar > el->el_line.buffer) {
- if (el->el_line.lastchar[-1] == '\n')
- el->el_line.lastchar--;
- if ((el->el_line.lastchar > el->el_line.buffer)&&(el->el_line.lastchar[-1] == ' ')) /* bill heckel */
- el->el_line.lastchar--;
- if (el->el_line.lastchar < el->el_line.buffer)
- el->el_line.lastchar = el->el_line.buffer;
- }
-#ifdef KSHVI
- if (el->el_map.type == MAP_VI)
- el->el_line.cursor = el->el_line.buffer;
- else
-#endif /* KSHVI */
- el->el_line.cursor = el->el_line.lastchar;
-
- return (CC_REFRESH);
-}
-
-
-/* hist_list()
- * List history entries
- */
-protected int
-/*ARGSUSED*/
-hist_list(EditLine *el, int argc, const char **argv)
-{
- const char *str;
-
- if (el->el_history.ref == NULL)
- return (-1);
- for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
- (void) fprintf(el->el_outfile, "%d %s",
- el->el_history.ev.num, str);
- return (0);
-}
-
-/* hist_enlargebuf()
- * Enlarge history buffer to specified value. Called from el_enlargebufs().
- * Return 0 for failure, 1 for success.
- */
-protected int
-/*ARGSUSED*/
-hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
-{
- char *newbuf;
-
- newbuf = realloc(el->el_history.buf, newsz);
- if (!newbuf)
- return 0;
-
- (void) memset(&newbuf[oldsz], '\0', newsz - oldsz);
-
- el->el_history.last = newbuf +
- (el->el_history.last - el->el_history.buf);
- el->el_history.buf = newbuf;
- el->el_history.sz = newsz;
-
- return 1;
-}
diff --git a/1.4/main/editline/hist.h b/1.4/main/editline/hist.h
deleted file mode 100644
index 5fdccd08e..000000000
--- a/1.4/main/editline/hist.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $NetBSD: hist.h,v 1.7 2002/03/18 16:00:53 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)hist.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.hist.c: History functions
- */
-#ifndef _h_el_hist
-#define _h_el_hist
-
-#include "histedit.h"
-
-typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...);
-
-typedef struct el_history_t {
- char *buf; /* The history buffer */
- size_t sz; /* Size of history buffer */
- char *last; /* The last character */
- int eventno; /* Event we are looking for */
- ptr_t ref; /* Argument for history fcns */
- hist_fun_t fun; /* Event access */
- HistEvent ev; /* Event cookie */
-} el_history_t;
-
-#define HIST_FUN(el, fn, arg) \
- ((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
- fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
-
-#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
-#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
-#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
-#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
-#define HIST_EVENT(el, num) HIST_FUN(el, H_EVENT, num)
-#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
-#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
-
-protected int hist_init(EditLine *);
-protected void hist_end(EditLine *);
-protected el_action_t hist_get(EditLine *);
-protected int hist_set(EditLine *, hist_fun_t, ptr_t);
-protected int hist_list(EditLine *, int, const char **);
-protected int hist_enlargebuf(EditLine *, size_t, size_t);
-
-#endif /* _h_el_hist */
diff --git a/1.4/main/editline/histedit.h b/1.4/main/editline/histedit.h
deleted file mode 100644
index e387e3b81..000000000
--- a/1.4/main/editline/histedit.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/* $NetBSD: histedit.h,v 1.19 2002/03/18 16:00:54 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)histedit.h 8.2 (Berkeley) 1/3/94
- */
-
-/*
- * histedit.h: Line editor and history interface.
- */
-#ifndef _HISTEDIT_H_
-#define _HISTEDIT_H_
-
-#define LIBEDIT_MAJOR 2
-#define LIBEDIT_MINOR 6
-
-#include <sys/types.h>
-#include <stdio.h>
-
-/*
- * ==== Editing ====
- */
-typedef struct editline EditLine;
-
-/*
- * For user-defined function interface
- */
-typedef struct lineinfo {
- char *buffer;
- char *cursor;
- char *lastchar;
-} LineInfo;
-
-
-/*
- * EditLine editor function return codes.
- * For user-defined function interface
- */
-#define CC_NORM 0
-#define CC_NEWLINE 1
-#define CC_EOF 2
-#define CC_ARGHACK 3
-#define CC_REFRESH 4
-#define CC_CURSOR 5
-#define CC_ERROR 6
-#define CC_FATAL 7
-#define CC_REDISPLAY 8
-#define CC_REFRESH_BEEP 9
-
-/*
- * Initialization, cleanup, and resetting
- */
-EditLine *el_init(const char *, FILE *, FILE *, FILE *);
-void el_reset(EditLine *);
-void el_end(EditLine *);
-
-
-/*
- * Get a line, a character or push a string back in the input queue
- */
-const char *el_gets(EditLine *, int *);
-int el_getc(EditLine *, char *);
-void el_push(EditLine *, char *);
-
-/*
- * Beep!
- */
-void el_beep(EditLine *);
-
-/*
- * High level function internals control
- * Parses argc, argv array and executes builtin editline commands
- */
-int el_parse(EditLine *, int, const char **);
-
-/*
- * Low level editline access functions
- */
-int el_set(EditLine *, int, ...);
-int el_get(EditLine *, int, void *);
-
-/*
- * el_set/el_get parameters
- */
-#define EL_PROMPT 0 /* , el_pfunc_t); */
-#define EL_TERMINAL 1 /* , const char *); */
-#define EL_EDITOR 2 /* , const char *); */
-#define EL_SIGNAL 3 /* , int); */
-#define EL_BIND 4 /* , const char *, ..., NULL); */
-#define EL_TELLTC 5 /* , const char *, ..., NULL); */
-#define EL_SETTC 6 /* , const char *, ..., NULL); */
-#define EL_ECHOTC 7 /* , const char *, ..., NULL); */
-#define EL_SETTY 8 /* , const char *, ..., NULL); */
-#define EL_ADDFN 9 /* , const char *, const char * */
- /* , el_func_t); */
-#define EL_HIST 10 /* , hist_fun_t, const char *); */
-#define EL_EDITMODE 11 /* , int); */
-#define EL_RPROMPT 12 /* , el_pfunc_t); */
-#define EL_GETCFN 13 /* , el_rfunc_t); */
-#define EL_CLIENTDATA 14 /* , void *); */
-
-#define EL_BUILTIN_GETCFN (NULL)
-
-/*
- * Source named file or $PWD/.editrc or $HOME/.editrc
- */
-int el_source(EditLine *, const char *);
-
-/*
- * Must be called when the terminal changes size; If EL_SIGNAL
- * is set this is done automatically otherwise it is the responsibility
- * of the application
- */
-void el_resize(EditLine *);
-
-
-/*
- * User-defined function interface.
- */
-const LineInfo *el_line(EditLine *);
-int el_insertstr(EditLine *, const char *);
-void el_deletestr(EditLine *, int);
-
-/*
- * ==== History ====
- */
-
-typedef struct history History;
-
-typedef struct HistEvent {
- int num;
- const char *str;
-} HistEvent;
-
-/*
- * History access functions.
- */
-History * history_init(void);
-void history_end(History *);
-
-int history(History *, HistEvent *, int, ...);
-
-#define H_FUNC 0 /* , UTSL */
-#define H_SETSIZE 1 /* , const int); */
-#define H_GETSIZE 2 /* , void); */
-#define H_FIRST 3 /* , void); */
-#define H_LAST 4 /* , void); */
-#define H_PREV 5 /* , void); */
-#define H_NEXT 6 /* , void); */
-#define H_CURR 8 /* , const int); */
-#define H_SET 7 /* , void); */
-#define H_ADD 9 /* , const char *); */
-#define H_ENTER 10 /* , const char *); */
-#define H_APPEND 11 /* , const char *); */
-#define H_END 12 /* , void); */
-#define H_NEXT_STR 13 /* , const char *); */
-#define H_PREV_STR 14 /* , const char *); */
-#define H_NEXT_EVENT 15 /* , const int); */
-#define H_PREV_EVENT 16 /* , const int); */
-#define H_LOAD 17 /* , const char *); */
-#define H_SAVE 18 /* , const char *); */
-#define H_CLEAR 19 /* , void); */
-
-#endif /* _HISTEDIT_H_ */
diff --git a/1.4/main/editline/history.c b/1.4/main/editline/history.c
deleted file mode 100644
index f133d2eb0..000000000
--- a/1.4/main/editline/history.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/* $NetBSD: history.c,v 1.19 2002/03/18 16:00:54 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: history.c,v 1.19 2002/03/18 16:00:54 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * hist.c: History access functions
- */
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#ifdef HAVE_VIS_H
-#include <vis.h>
-#else
-#include "np/vis.h"
-#endif
-#include <sys/stat.h>
-
-static const char hist_cookie[] = "_HiStOrY_V2_\n";
-
-#include "histedit.h"
-
-typedef int (*history_gfun_t)(ptr_t, HistEvent *);
-typedef int (*history_efun_t)(ptr_t, HistEvent *, const char *);
-typedef void (*history_vfun_t)(ptr_t, HistEvent *);
-typedef int (*history_sfun_t)(ptr_t, HistEvent *, const int);
-
-struct history {
- ptr_t h_ref; /* Argument for history fcns */
- int h_ent; /* Last entry point for history */
- history_gfun_t h_first; /* Get the first element */
- history_gfun_t h_next; /* Get the next element */
- history_gfun_t h_last; /* Get the last element */
- history_gfun_t h_prev; /* Get the previous element */
- history_gfun_t h_curr; /* Get the current element */
- history_sfun_t h_set; /* Set the current element */
- history_vfun_t h_clear; /* Clear the history list */
- history_efun_t h_enter; /* Add an element */
- history_efun_t h_add; /* Append to an element */
-};
-#define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev)
-#define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev)
-#define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev)
-#define HLAST(h, ev) (*(h)->h_last)((h)->h_ref, ev)
-#define HCURR(h, ev) (*(h)->h_curr)((h)->h_ref, ev)
-#define HSET(h, ev, n) (*(h)->h_set)((h)->h_ref, ev, n)
-#define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev)
-#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str)
-#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
-
-#define h_malloc(a) malloc(a)
-#define h_realloc(a, b) realloc((a), (b))
-#define h_free(a) free(a)
-
-typedef struct {
- int num;
- char *str;
-} HistEventPrivate;
-
-
-
-private int history_setsize(History *, HistEvent *, int);
-private int history_getsize(History *, HistEvent *);
-private int history_set_fun(History *, History *);
-private int history_load(History *, const char *);
-private int history_save(History *, const char *);
-private int history_prev_event(History *, HistEvent *, int);
-private int history_next_event(History *, HistEvent *, int);
-private int history_next_string(History *, HistEvent *, const char *);
-private int history_prev_string(History *, HistEvent *, const char *);
-
-
-/***********************************************************************/
-
-/*
- * Builtin- history implementation
- */
-typedef struct hentry_t {
- HistEvent ev; /* What we return */
- struct hentry_t *next; /* Next entry */
- struct hentry_t *prev; /* Previous entry */
-} hentry_t;
-
-typedef struct history_t {
- hentry_t list; /* Fake list header element */
- hentry_t *cursor; /* Current element in the list */
- int max; /* Maximum number of events */
- int cur; /* Current number of events */
- int eventid; /* For generation of unique event id */
-} history_t;
-
-private int history_def_first(ptr_t, HistEvent *);
-private int history_def_last(ptr_t, HistEvent *);
-private int history_def_next(ptr_t, HistEvent *);
-private int history_def_prev(ptr_t, HistEvent *);
-private int history_def_curr(ptr_t, HistEvent *);
-private int history_def_set(ptr_t, HistEvent *, const int n);
-private int history_def_enter(ptr_t, HistEvent *, const char *);
-private int history_def_add(ptr_t, HistEvent *, const char *);
-private void history_def_init(ptr_t *, HistEvent *, int);
-private void history_def_clear(ptr_t, HistEvent *);
-private int history_def_insert(history_t *, HistEvent *, const char *);
-private void history_def_delete(history_t *, HistEvent *, hentry_t *);
-
-#define history_def_setsize(p, num)(void) (((history_t *) p)->max = (num))
-#define history_def_getsize(p) (((history_t *) p)->cur)
-
-#define he_strerror(code) he_errlist[code]
-#define he_seterrev(evp, code) {\
- evp->num = code;\
- evp->str = he_strerror(code);\
- }
-
-/* error messages */
-static const char *const he_errlist[] = {
- "OK",
- "unknown error",
- "malloc() failed",
- "first event not found",
- "last event not found",
- "empty list",
- "no next event",
- "no previous event",
- "current event is invalid",
- "event not found",
- "can't read history from file",
- "can't write history",
- "required parameter(s) not supplied",
- "history size negative",
- "function not allowed with other history-functions-set the default",
- "bad parameters"
-};
-/* error codes */
-#define _HE_OK 0
-#define _HE_UNKNOWN 1
-#define _HE_MALLOC_FAILED 2
-#define _HE_FIRST_NOTFOUND 3
-#define _HE_LAST_NOTFOUND 4
-#define _HE_EMPTY_LIST 5
-#define _HE_END_REACHED 6
-#define _HE_START_REACHED 7
-#define _HE_CURR_INVALID 8
-#define _HE_NOT_FOUND 9
-#define _HE_HIST_READ 10
-#define _HE_HIST_WRITE 11
-#define _HE_PARAM_MISSING 12
-#define _HE_SIZE_NEGATIVE 13
-#define _HE_NOT_ALLOWED 14
-#define _HE_BAD_PARAM 15
-
-/* history_def_first():
- * Default function to return the first event in the history.
- */
-private int
-history_def_first(ptr_t p, HistEvent *ev)
-{
- history_t *h = (history_t *) p;
-
- h->cursor = h->list.next;
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
- he_seterrev(ev, _HE_FIRST_NOTFOUND);
- return (-1);
- }
-
- return (0);
-}
-
-
-/* history_def_last():
- * Default function to return the last event in the history.
- */
-private int
-history_def_last(ptr_t p, HistEvent *ev)
-{
- history_t *h = (history_t *) p;
-
- h->cursor = h->list.prev;
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
- he_seterrev(ev, _HE_LAST_NOTFOUND);
- return (-1);
- }
-
- return (0);
-}
-
-
-/* history_def_next():
- * Default function to return the next event in the history.
- */
-private int
-history_def_next(ptr_t p, HistEvent *ev)
-{
- history_t *h = (history_t *) p;
-
- if (h->cursor != &h->list)
- h->cursor = h->cursor->next;
- else {
- he_seterrev(ev, _HE_EMPTY_LIST);
- return (-1);
- }
-
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
- he_seterrev(ev, _HE_END_REACHED);
- return (-1);
- }
-
- return (0);
-}
-
-
-/* history_def_prev():
- * Default function to return the previous event in the history.
- */
-private int
-history_def_prev(ptr_t p, HistEvent *ev)
-{
- history_t *h = (history_t *) p;
-
- if (h->cursor != &h->list)
- h->cursor = h->cursor->prev;
- else {
- he_seterrev(ev,
- (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
- return (-1);
- }
-
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
- he_seterrev(ev, _HE_START_REACHED);
- return (-1);
- }
-
- return (0);
-}
-
-
-/* history_def_curr():
- * Default function to return the current event in the history.
- */
-private int
-history_def_curr(ptr_t p, HistEvent *ev)
-{
- history_t *h = (history_t *) p;
-
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
- he_seterrev(ev,
- (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
- return (-1);
- }
-
- return (0);
-}
-
-
-/* history_def_set():
- * Default function to set the current event in the history to the
- * given one.
- */
-private int
-history_def_set(ptr_t p, HistEvent *ev, const int n)
-{
- history_t *h = (history_t *) p;
-
- if (h->cur == 0) {
- he_seterrev(ev, _HE_EMPTY_LIST);
- return (-1);
- }
- if (h->cursor == &h->list || h->cursor->ev.num != n) {
- for (h->cursor = h->list.next; h->cursor != &h->list;
- h->cursor = h->cursor->next)
- if (h->cursor->ev.num == n)
- break;
- }
- if (h->cursor == &h->list) {
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
- }
- return (0);
-}
-
-
-/* history_def_add():
- * Append string to element
- */
-private int
-history_def_add(ptr_t p, HistEvent *ev, const char *str)
-{
- history_t *h = (history_t *) p;
- size_t len;
- char *s;
- HistEventPrivate *evp = (void *)&h->cursor->ev;
-
- if (h->cursor == &h->list)
- return (history_def_enter(p, ev, str));
- len = strlen(evp->str) + strlen(str) + 1;
- s = (char *) h_malloc(len);
- if (!s) {
- he_seterrev(ev, _HE_MALLOC_FAILED);
- return (-1);
- }
- (void) strlcpy(s, h->cursor->ev.str, len);
- (void) strlcat(s, str, len);
- h_free(evp->str);
- evp->str = s;
- *ev = h->cursor->ev;
- return (0);
-}
-
-
-/* history_def_delete():
- * Delete element hp of the h list
- */
-/* ARGSUSED */
-private void
-history_def_delete(history_t *h, HistEvent *ev, hentry_t *hp)
-{
- HistEventPrivate *evp = (void *)&hp->ev;
- if (hp == &h->list)
- abort();
- hp->prev->next = hp->next;
- hp->next->prev = hp->prev;
- h_free((ptr_t) evp->str);
- h_free(hp);
- h->cur--;
-}
-
-
-/* history_def_insert():
- * Insert element with string str in the h list
- */
-private int
-history_def_insert(history_t *h, HistEvent *ev, const char *str)
-{
-
- h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
- if (h->cursor)
- h->cursor->ev.str = strdup(str);
- if (!h->cursor || !h->cursor->ev.str) {
- he_seterrev(ev, _HE_MALLOC_FAILED);
- return (-1);
- }
- h->cursor->ev.num = ++h->eventid;
- h->cursor->next = h->list.next;
- h->cursor->prev = &h->list;
- h->list.next->prev = h->cursor;
- h->list.next = h->cursor;
- h->cur++;
-
- *ev = h->cursor->ev;
- return (0);
-}
-
-
-/* history_def_enter():
- * Default function to enter an item in the history
- */
-private int
-history_def_enter(ptr_t p, HistEvent *ev, const char *str)
-{
- history_t *h = (history_t *) p;
-
- if (history_def_insert(h, ev, str) == -1)
- return (-1); /* error, keep error message */
-
- /*
- * Always keep at least one entry.
- * This way we don't have to check for the empty list.
- */
- while (h->cur > h->max && h->cur > 0)
- history_def_delete(h, ev, h->list.prev);
-
- return (0);
-}
-
-
-/* history_def_init():
- * Default history initialization function
- */
-/* ARGSUSED */
-private void
-history_def_init(ptr_t *p, HistEvent *ev, int n)
-{
- history_t *h = (history_t *) h_malloc(sizeof(history_t));
-
- if (n <= 0)
- n = 0;
- h->eventid = 0;
- h->cur = 0;
- h->max = n;
- h->list.next = h->list.prev = &h->list;
- h->list.ev.str = NULL;
- h->list.ev.num = 0;
- h->cursor = &h->list;
- *p = (ptr_t) h;
-}
-
-
-/* history_def_clear():
- * Default history cleanup function
- */
-private void
-history_def_clear(ptr_t p, HistEvent *ev)
-{
- history_t *h = (history_t *) p;
-
- while (h->list.prev != &h->list)
- history_def_delete(h, ev, h->list.prev);
- h->eventid = 0;
- h->cur = 0;
-}
-
-
-
-
-/************************************************************************/
-
-/* history_init():
- * Initialization function.
- */
-public History *
-history_init(void)
-{
- History *h = (History *) h_malloc(sizeof(History));
- HistEvent ev;
-
- history_def_init(&h->h_ref, &ev, 0);
- h->h_ent = -1;
- h->h_next = history_def_next;
- h->h_first = history_def_first;
- h->h_last = history_def_last;
- h->h_prev = history_def_prev;
- h->h_curr = history_def_curr;
- h->h_set = history_def_set;
- h->h_clear = history_def_clear;
- h->h_enter = history_def_enter;
- h->h_add = history_def_add;
-
- return (h);
-}
-
-
-/* history_end():
- * clean up history;
- */
-public void
-history_end(History *h)
-{
- HistEvent ev;
-
- if (h->h_next == history_def_next)
- history_def_clear(h->h_ref, &ev);
-}
-
-
-
-/* history_setsize():
- * Set history number of events
- */
-private int
-history_setsize(History *h, HistEvent *ev, int num)
-{
-
- if (h->h_next != history_def_next) {
- he_seterrev(ev, _HE_NOT_ALLOWED);
- return (-1);
- }
- if (num < 0) {
- he_seterrev(ev, _HE_BAD_PARAM);
- return (-1);
- }
- history_def_setsize(h->h_ref, num);
- return (0);
-}
-
-
-/* history_getsize():
- * Get number of events currently in history
- */
-private int
-history_getsize(History *h, HistEvent *ev)
-{
- int retval = 0;
-
- if (h->h_next != history_def_next) {
- he_seterrev(ev, _HE_NOT_ALLOWED);
- return (-1);
- }
- retval = history_def_getsize(h->h_ref);
- if (retval < -1) {
- he_seterrev(ev, _HE_SIZE_NEGATIVE);
- return (-1);
- }
- ev->num = retval;
- return (0);
-}
-
-
-/* history_set_fun():
- * Set history functions
- */
-private int
-history_set_fun(History *h, History *nh)
-{
- HistEvent ev;
-
- if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL ||
- nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL ||
- nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
- nh->h_ref == NULL) {
- if (h->h_next != history_def_next) {
- history_def_init(&h->h_ref, &ev, 0);
- h->h_first = history_def_first;
- h->h_next = history_def_next;
- h->h_last = history_def_last;
- h->h_prev = history_def_prev;
- h->h_curr = history_def_curr;
- h->h_set = history_def_set;
- h->h_clear = history_def_clear;
- h->h_enter = history_def_enter;
- h->h_add = history_def_add;
- }
- return (-1);
- }
- if (h->h_next == history_def_next)
- history_def_clear(h->h_ref, &ev);
-
- h->h_ent = -1;
- h->h_first = nh->h_first;
- h->h_next = nh->h_next;
- h->h_last = nh->h_last;
- h->h_prev = nh->h_prev;
- h->h_curr = nh->h_curr;
- h->h_set = nh->h_set;
- h->h_clear = nh->h_clear;
- h->h_enter = nh->h_enter;
- h->h_add = nh->h_add;
-
- return (0);
-}
-
-
-/* history_load():
- * History load function
- */
-private int
-history_load(History *h, const char *fname)
-{
- FILE *fp;
- char *line;
- size_t sz, max_size;
- char *ptr;
- int i = -1;
- HistEvent ev;
-
- if ((fp = fopen(fname, "r")) == NULL)
- return (i);
-
- if ((line = fgetln(fp, &sz)) == NULL)
- goto done;
-
- if (strncmp(line, hist_cookie, sz) != 0)
- goto done;
-
- ptr = h_malloc(max_size = 1024);
- for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
- char c = line[sz];
-
- if (sz != 0 && line[sz - 1] == '\n')
- line[--sz] = '\0';
- else
- line[sz] = '\0';
-
- if (max_size < sz) {
- max_size = (sz + 1023) & ~1023;
- ptr = h_realloc(ptr, max_size);
- }
- (void) strunvis(ptr, line);
- line[sz] = c;
- HENTER(h, &ev, ptr);
- }
- h_free(ptr);
-
-done:
- (void) fclose(fp);
- return (i);
-}
-
-
-/* history_save():
- * History save function
- */
-private int
-history_save(History *h, const char *fname)
-{
- FILE *fp;
- HistEvent ev;
- int i = 0, retval;
- size_t len, max_size;
- char *ptr;
-
- if ((fp = fopen(fname, "w")) == NULL)
- return (-1);
-
- (void) fchmod(fileno(fp), S_IRUSR|S_IWUSR);
- (void) fputs(hist_cookie, fp);
- ptr = h_malloc(max_size = 1024);
- for (retval = HLAST(h, &ev);
- retval != -1;
- retval = HPREV(h, &ev), i++) {
- len = strlen(ev.str) * 4;
- if (len >= max_size) {
- max_size = (len + 1023) & 1023;
- ptr = h_realloc(ptr, max_size);
- }
- (void) strvis(ptr, ev.str, VIS_WHITE);
- (void) fprintf(fp, "%s\n", ev.str);
- }
- h_free(ptr);
- (void) fclose(fp);
- return (i);
-}
-
-
-/* history_prev_event():
- * Find the previous event, with number given
- */
-private int
-history_prev_event(History *h, HistEvent *ev, int num)
-{
- int retval;
-
- for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
- if (ev->num == num)
- return (0);
-
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
-}
-
-
-/* history_next_event():
- * Find the next event, with number given
- */
-private int
-history_next_event(History *h, HistEvent *ev, int num)
-{
- int retval;
-
- for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
- if (ev->num == num)
- return (0);
-
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
-}
-
-
-/* history_prev_string():
- * Find the previous event beginning with string
- */
-private int
-history_prev_string(History *h, HistEvent *ev, const char *str)
-{
- size_t len = strlen(str);
- int retval;
-
- for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
- if (strncmp(str, ev->str, len) == 0)
- return (0);
-
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
-}
-
-
-/* history_next_string():
- * Find the next event beginning with string
- */
-private int
-history_next_string(History *h, HistEvent *ev, const char *str)
-{
- size_t len = strlen(str);
- int retval;
-
- for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
- if (strncmp(str, ev->str, len) == 0)
- return (0);
-
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
-}
-
-
-/* history():
- * User interface to history functions.
- */
-int
-history(History *h, HistEvent *ev, int fun, ...)
-{
- va_list va;
- const char *str;
- int retval;
-
- va_start(va, fun);
-
- he_seterrev(ev, _HE_OK);
-
- switch (fun) {
- case H_GETSIZE:
- retval = history_getsize(h, ev);
- break;
-
- case H_SETSIZE:
- retval = history_setsize(h, ev, va_arg(va, int));
- break;
-
- case H_ADD:
- str = va_arg(va, const char *);
- retval = HADD(h, ev, str);
- break;
-
- case H_ENTER:
- str = va_arg(va, const char *);
- if ((retval = HENTER(h, ev, str)) != -1)
- h->h_ent = ev->num;
- break;
-
- case H_APPEND:
- str = va_arg(va, const char *);
- if ((retval = HSET(h, ev, h->h_ent)) != -1)
- retval = HADD(h, ev, str);
- break;
-
- case H_FIRST:
- retval = HFIRST(h, ev);
- break;
-
- case H_NEXT:
- retval = HNEXT(h, ev);
- break;
-
- case H_LAST:
- retval = HLAST(h, ev);
- break;
-
- case H_PREV:
- retval = HPREV(h, ev);
- break;
-
- case H_CURR:
- retval = HCURR(h, ev);
- break;
-
- case H_SET:
- retval = HSET(h, ev, va_arg(va, const int));
- break;
-
- case H_CLEAR:
- HCLEAR(h, ev);
- retval = 0;
- break;
-
- case H_LOAD:
- retval = history_load(h, va_arg(va, const char *));
- if (retval == -1)
- he_seterrev(ev, _HE_HIST_READ);
- break;
-
- case H_SAVE:
- retval = history_save(h, va_arg(va, const char *));
- if (retval == -1)
- he_seterrev(ev, _HE_HIST_WRITE);
- break;
-
- case H_PREV_EVENT:
- retval = history_prev_event(h, ev, va_arg(va, int));
- break;
-
- case H_NEXT_EVENT:
- retval = history_next_event(h, ev, va_arg(va, int));
- break;
-
- case H_PREV_STR:
- retval = history_prev_string(h, ev, va_arg(va, const char *));
- break;
-
- case H_NEXT_STR:
- retval = history_next_string(h, ev, va_arg(va, const char *));
- break;
-
- case H_FUNC:
- {
- History hf;
-
- hf.h_ref = va_arg(va, ptr_t);
- h->h_ent = -1;
- hf.h_first = va_arg(va, history_gfun_t);
- hf.h_next = va_arg(va, history_gfun_t);
- hf.h_last = va_arg(va, history_gfun_t);
- hf.h_prev = va_arg(va, history_gfun_t);
- hf.h_curr = va_arg(va, history_gfun_t);
- hf.h_set = va_arg(va, history_sfun_t);
- hf.h_clear = va_arg(va, history_vfun_t);
- hf.h_enter = va_arg(va, history_efun_t);
- hf.h_add = va_arg(va, history_efun_t);
-
- if ((retval = history_set_fun(h, &hf)) == -1)
- he_seterrev(ev, _HE_PARAM_MISSING);
- break;
- }
-
- case H_END:
- history_end(h);
- retval = 0;
- break;
-
- default:
- retval = -1;
- he_seterrev(ev, _HE_UNKNOWN);
- break;
- }
- va_end(va);
- return (retval);
-}
diff --git a/1.4/main/editline/install-sh b/1.4/main/editline/install-sh
deleted file mode 100755
index ebc66913e..000000000
--- a/1.4/main/editline/install-sh
+++ /dev/null
@@ -1,250 +0,0 @@
-#! /bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
-#
-# Copyright 1991 by the Massachusetts Institute of Technology
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission. M.I.T. makes no representations about the
-# suitability of this software for any purpose. It is provided "as is"
-# without express or implied warranty.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/1.4/main/editline/key.c b/1.4/main/editline/key.c
deleted file mode 100644
index 0dcdf4191..000000000
--- a/1.4/main/editline/key.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/* $NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * key.c: This module contains the procedures for maintaining
- * the extended-key map.
- *
- * An extended-key (key) is a sequence of keystrokes introduced
- * with an sequence introducer and consisting of an arbitrary
- * number of characters. This module maintains a map (the el->el_key.map)
- * to convert these extended-key sequences into input strs
- * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
- *
- * Warning:
- * If key is a substr of some other keys, then the longer
- * keys are lost!! That is, if the keys "abcd" and "abcef"
- * are in el->el_key.map, adding the key "abc" will cause the first two
- * definitions to be lost.
- *
- * Restrictions:
- * -------------
- * 1) It is not possible to have one key that is a
- * substr of another.
- */
-#include <string.h>
-#include <stdlib.h>
-
-#include "el.h"
-
-/*
- * The Nodes of the el->el_key.map. The el->el_key.map is a linked list
- * of these node elements
- */
-struct key_node_t {
- char ch; /* single character of key */
- int type; /* node type */
- key_value_t val; /* command code or pointer to str, */
- /* if this is a leaf */
- struct key_node_t *next; /* ptr to next char of this key */
- struct key_node_t *sibling; /* ptr to another key with same prefix*/
-};
-
-private int node_trav(EditLine *, key_node_t *, char *,
- key_value_t *);
-private int node__try(EditLine *, key_node_t *, const char *,
- key_value_t *, int);
-private key_node_t *node__get(int);
-private void node__put(EditLine *, key_node_t *);
-private int node__delete(EditLine *, key_node_t **, const char *);
-private int node_lookup(EditLine *, const char *, key_node_t *,
- int);
-private int node_enum(EditLine *, key_node_t *, int);
-private int key__decode_char(char *, int, int);
-
-#define KEY_BUFSIZ EL_BUFSIZ
-
-
-/* key_init():
- * Initialize the key maps
- */
-protected int
-key_init(EditLine *el)
-{
-
- el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
- if (el->el_key.buf == NULL)
- return (-1);
- el->el_key.map = NULL;
- key_reset(el);
- return (0);
-}
-
-
-/* key_end():
- * Free the key maps
- */
-protected void
-key_end(EditLine *el)
-{
-
- el_free((ptr_t) el->el_key.buf);
- el->el_key.buf = NULL;
- node__put(el, el->el_key.map);
- el->el_key.map = NULL;
-}
-
-
-/* key_map_cmd():
- * Associate cmd with a key value
- */
-protected key_value_t *
-key_map_cmd(EditLine *el, int cmd)
-{
-
- el->el_key.val.cmd = (el_action_t) cmd;
- return (&el->el_key.val);
-}
-
-
-/* key_map_str():
- * Associate str with a key value
- */
-protected key_value_t *
-key_map_str(EditLine *el, char *str)
-{
-
- el->el_key.val.str = str;
- return (&el->el_key.val);
-}
-
-
-/* key_reset():
- * Takes all nodes on el->el_key.map and puts them on free list. Then
- * initializes el->el_key.map with arrow keys
- * [Always bind the ansi arrow keys?]
- */
-protected void
-key_reset(EditLine *el)
-{
-
- node__put(el, el->el_key.map);
- el->el_key.map = NULL;
- return;
-}
-
-
-/* key_get():
- * Calls the recursive function with entry point el->el_key.map
- * Looks up *ch in map and then reads characters until a
- * complete match is found or a mismatch occurs. Returns the
- * type of the match found (XK_STR, XK_CMD, or XK_EXE).
- * Returns NULL in val.str and XK_STR for no match.
- * The last character read is returned in *ch.
- */
-protected int
-key_get(EditLine *el, char *ch, key_value_t *val)
-{
-
- return (node_trav(el, el->el_key.map, ch, val));
-}
-
-
-/* key_add():
- * Adds key to the el->el_key.map and associates the value in val with it.
- * If key is already is in el->el_key.map, the new code is applied to the
- * existing key. Ntype specifies if code is a command, an
- * out str or a unix command.
- */
-protected void
-key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
-{
-
- if (key[0] == '\0') {
- (void) fprintf(el->el_errfile,
- "key_add: Null extended-key not allowed.\n");
- return;
- }
- if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
- (void) fprintf(el->el_errfile,
- "key_add: sequence-lead-in command not allowed\n");
- return;
- }
- if (el->el_key.map == NULL)
- /* tree is initially empty. Set up new node to match key[0] */
- el->el_key.map = node__get(key[0]);
- /* it is properly initialized */
-
- /* Now recurse through el->el_key.map */
- (void) node__try(el, el->el_key.map, key, val, ntype);
- return;
-}
-
-
-/* key_clear():
- *
- */
-protected void
-key_clear(EditLine *el, el_action_t *map, const char *in)
-{
-
- if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
- ((map == el->el_map.key &&
- el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
- (map == el->el_map.alt &&
- el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
- (void) key_delete(el, in);
-}
-
-
-/* key_delete():
- * Delete the key and all longer keys staring with key, if
- * they exists.
- */
-protected int
-key_delete(EditLine *el, const char *key)
-{
-
- if (key[0] == '\0') {
- (void) fprintf(el->el_errfile,
- "key_delete: Null extended-key not allowed.\n");
- return (-1);
- }
- if (el->el_key.map == NULL)
- return (0);
-
- (void) node__delete(el, &el->el_key.map, key);
- return (0);
-}
-
-
-/* key_print():
- * Print the binding associated with key key.
- * Print entire el->el_key.map if null
- */
-protected void
-key_print(EditLine *el, const char *key)
-{
-
- /* do nothing if el->el_key.map is empty and null key specified */
- if (el->el_key.map == NULL && *key == 0)
- return;
-
- el->el_key.buf[0] = '"';
- if (node_lookup(el, key, el->el_key.map, 1) <= -1)
- /* key is not bound */
- (void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n",
- key);
- return;
-}
-
-
-/* node_trav():
- * recursively traverses node in tree until match or mismatch is
- * found. May read in more characters.
- */
-private int
-node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
-{
-
- if (ptr->ch == *ch) {
- /* match found */
- if (ptr->next) {
- /* key not complete so get next char */
- if (el_getc(el, ch) != 1) { /* if EOF or error */
- val->cmd = ED_END_OF_FILE;
- return (XK_CMD);
- /* PWP: Pretend we just read an end-of-file */
- }
- return (node_trav(el, ptr->next, ch, val));
- } else {
- *val = ptr->val;
- if (ptr->type != XK_CMD)
- *ch = '\0';
- return (ptr->type);
- }
- } else {
- /* no match found here */
- if (ptr->sibling) {
- /* try next sibling */
- return (node_trav(el, ptr->sibling, ch, val));
- } else {
- /* no next sibling -- mismatch */
- val->str = NULL;
- return (XK_STR);
- }
- }
-}
-
-
-/* node__try():
- * Find a node that matches *str or allocate a new one
- */
-private int
-node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype)
-{
-
- if (ptr->ch != *str) {
- key_node_t *xm;
-
- for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
- if (xm->sibling->ch == *str)
- break;
- if (xm->sibling == NULL)
- xm->sibling = node__get(*str); /* setup new node */
- ptr = xm->sibling;
- }
- if (*++str == '\0') {
- /* we're there */
- if (ptr->next != NULL) {
- node__put(el, ptr->next);
- /* lose longer keys with this prefix */
- ptr->next = NULL;
- }
- switch (ptr->type) {
- case XK_CMD:
- case XK_NOD:
- break;
- case XK_STR:
- case XK_EXE:
- if (ptr->val.str)
- el_free((ptr_t) ptr->val.str);
- break;
- default:
- EL_ABORT((el->el_errfile, "Bad XK_ type %d\n",
- ptr->type));
- break;
- }
-
- switch (ptr->type = ntype) {
- case XK_CMD:
- ptr->val = *val;
- break;
- case XK_STR:
- case XK_EXE:
- ptr->val.str = strdup(val->str);
- break;
- default:
- EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
- break;
- }
- } else {
- /* still more chars to go */
- if (ptr->next == NULL)
- ptr->next = node__get(*str); /* setup new node */
- (void) node__try(el, ptr->next, str, val, ntype);
- }
- return (0);
-}
-
-
-/* node__delete():
- * Delete node that matches str
- */
-private int
-node__delete(EditLine *el, key_node_t **inptr, const char *str)
-{
- key_node_t *ptr;
- key_node_t *prev_ptr = NULL;
-
- ptr = *inptr;
-
- if (ptr->ch != *str) {
- key_node_t *xm;
-
- for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
- if (xm->sibling->ch == *str)
- break;
- if (xm->sibling == NULL)
- return (0);
- prev_ptr = xm;
- ptr = xm->sibling;
- }
- if (*++str == '\0') {
- /* we're there */
- if (prev_ptr == NULL)
- *inptr = ptr->sibling;
- else
- prev_ptr->sibling = ptr->sibling;
- ptr->sibling = NULL;
- node__put(el, ptr);
- return (1);
- } else if (ptr->next != NULL &&
- node__delete(el, &ptr->next, str) == 1) {
- if (ptr->next != NULL)
- return (0);
- if (prev_ptr == NULL)
- *inptr = ptr->sibling;
- else
- prev_ptr->sibling = ptr->sibling;
- ptr->sibling = NULL;
- node__put(el, ptr);
- return (1);
- } else {
- return (0);
- }
-}
-
-
-/* node__put():
- * Puts a tree of nodes onto free list using free(3).
- */
-private void
-node__put(EditLine *el, key_node_t *ptr)
-{
- if (ptr == NULL)
- return;
-
- if (ptr->next != NULL) {
- node__put(el, ptr->next);
- ptr->next = NULL;
- }
- node__put(el, ptr->sibling);
-
- switch (ptr->type) {
- case XK_CMD:
- case XK_NOD:
- break;
- case XK_EXE:
- case XK_STR:
- if (ptr->val.str != NULL)
- el_free((ptr_t) ptr->val.str);
- break;
- default:
- EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
- break;
- }
- el_free((ptr_t) ptr);
-}
-
-
-/* node__get():
- * Returns pointer to an key_node_t for ch.
- */
-private key_node_t *
-node__get(int ch)
-{
- key_node_t *ptr;
-
- ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t));
- if (ptr == NULL)
- return NULL;
- ptr->ch = ch;
- ptr->type = XK_NOD;
- ptr->val.str = NULL;
- ptr->next = NULL;
- ptr->sibling = NULL;
- return (ptr);
-}
-
-
-
-/* node_lookup():
- * look for the str starting at node ptr.
- * Print if last node
- */
-private int
-node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
-{
- int ncnt;
-
- if (ptr == NULL)
- return (-1); /* cannot have null ptr */
-
- if (*str == 0) {
- /* no more chars in str. node_enum from here. */
- (void) node_enum(el, ptr, cnt);
- return (0);
- } else {
- /* If match put this char into el->el_key.buf. Recurse */
- if (ptr->ch == *str) {
- /* match found */
- ncnt = key__decode_char(el->el_key.buf, cnt,
- (unsigned char) ptr->ch);
- if (ptr->next != NULL)
- /* not yet at leaf */
- return (node_lookup(el, str + 1, ptr->next,
- ncnt + 1));
- else {
- /* next node is null so key should be complete */
- if (str[1] == 0) {
- el->el_key.buf[ncnt + 1] = '"';
- el->el_key.buf[ncnt + 2] = '\0';
- key_kprint(el, el->el_key.buf,
- &ptr->val, ptr->type);
- return (0);
- } else
- return (-1);
- /* mismatch -- str still has chars */
- }
- } else {
- /* no match found try sibling */
- if (ptr->sibling)
- return (node_lookup(el, str, ptr->sibling,
- cnt));
- else
- return (-1);
- }
- }
-}
-
-
-/* node_enum():
- * Traverse the node printing the characters it is bound in buffer
- */
-private int
-node_enum(EditLine *el, key_node_t *ptr, int cnt)
-{
- int ncnt;
-
- if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
- el->el_key.buf[++cnt] = '"';
- el->el_key.buf[++cnt] = '\0';
- (void) fprintf(el->el_errfile,
- "Some extended keys too long for internal print buffer");
- (void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf);
- return (0);
- }
- if (ptr == NULL) {
-#ifdef DEBUG_EDIT
- (void) fprintf(el->el_errfile,
- "node_enum: BUG!! Null ptr passed\n!");
-#endif
- return (-1);
- }
- /* put this char at end of str */
- ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch);
- if (ptr->next == NULL) {
- /* print this key and function */
- el->el_key.buf[ncnt + 1] = '"';
- el->el_key.buf[ncnt + 2] = '\0';
- key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
- } else
- (void) node_enum(el, ptr->next, ncnt + 1);
-
- /* go to sibling if there is one */
- if (ptr->sibling)
- (void) node_enum(el, ptr->sibling, cnt);
- return (0);
-}
-
-
-/* key_kprint():
- * Print the specified key and its associated
- * function specified by val
- */
-protected void
-key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
-{
- el_bindings_t *fp;
- char unparsbuf[EL_BUFSIZ];
- static const char fmt[] = "%-15s-> %s\n";
-
- if (val != NULL)
- switch (ntype) {
- case XK_STR:
- case XK_EXE:
- (void) fprintf(el->el_outfile, fmt, key,
- key__decode_str(val->str, unparsbuf,
- ntype == XK_STR ? "\"\"" : "[]"));
- break;
- case XK_CMD:
- for (fp = el->el_map.help; fp->name; fp++)
- if (val->cmd == fp->func) {
- (void) fprintf(el->el_outfile, fmt,
- key, fp->name);
- break;
- }
-#ifdef DEBUG_KEY
- if (fp->name == NULL)
- (void) fprintf(el->el_outfile,
- "BUG! Command not found.\n");
-#endif
-
- break;
- default:
- EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
- break;
- }
- else
- (void) fprintf(el->el_outfile, fmt, key, "no input");
-}
-
-
-/* key__decode_char():
- * Put a printable form of char in buf.
- */
-private int
-key__decode_char(char *buf, int cnt, int ch)
-{
- if (ch == 0) {
- buf[cnt++] = '^';
- buf[cnt] = '@';
- return (cnt);
- }
- if (iscntrl(ch)) {
- buf[cnt++] = '^';
- if (ch == '\177')
- buf[cnt] = '?';
- else
- buf[cnt] = ch | 0100;
- } else if (ch == '^') {
- buf[cnt++] = '\\';
- buf[cnt] = '^';
- } else if (ch == '\\') {
- buf[cnt++] = '\\';
- buf[cnt] = '\\';
- } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) {
- buf[cnt] = ch;
- } else {
- buf[cnt++] = '\\';
- buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0';
- buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0';
- buf[cnt] = (ch & 7) + '0';
- }
- return (cnt);
-}
-
-
-/* key__decode_str():
- * Make a printable version of the ey
- */
-protected char *
-key__decode_str(const char *str, char *buf, const char *sep)
-{
- char *b;
- const char *p;
-
- b = buf;
- if (sep[0] != '\0')
- *b++ = sep[0];
- if (*str == 0) {
- *b++ = '^';
- *b++ = '@';
- if (sep[0] != '\0' && sep[1] != '\0')
- *b++ = sep[1];
- *b++ = 0;
- return (buf);
- }
- for (p = str; *p != 0; p++) {
- if (iscntrl((unsigned char) *p)) {
- *b++ = '^';
- if (*p == '\177')
- *b++ = '?';
- else
- *b++ = *p | 0100;
- } else if (*p == '^' || *p == '\\') {
- *b++ = '\\';
- *b++ = *p;
- } else if (*p == ' ' || (isprint((unsigned char) *p) &&
- !isspace((unsigned char) *p))) {
- *b++ = *p;
- } else {
- *b++ = '\\';
- *b++ = (((unsigned int) *p >> 6) & 7) + '0';
- *b++ = (((unsigned int) *p >> 3) & 7) + '0';
- *b++ = (*p & 7) + '0';
- }
- }
- if (sep[0] != '\0' && sep[1] != '\0')
- *b++ = sep[1];
- *b++ = 0;
- return (buf); /* should check for overflow */
-}
diff --git a/1.4/main/editline/key.h b/1.4/main/editline/key.h
deleted file mode 100644
index 80d8626b8..000000000
--- a/1.4/main/editline/key.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $NetBSD: key.h,v 1.6 2002/03/18 16:00:55 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)key.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.key.h: Key macro header
- */
-#ifndef _h_el_key
-#define _h_el_key
-
-typedef union key_value_t {
- el_action_t cmd; /* If it is a command the # */
- char *str; /* If it is a string... */
-} key_value_t;
-
-typedef struct key_node_t key_node_t;
-
-typedef struct el_key_t {
- char *buf; /* Key print buffer */
- key_node_t *map; /* Key map */
- key_value_t val; /* Local conversion buffer */
-} el_key_t;
-
-#define XK_CMD 0
-#define XK_STR 1
-#define XK_NOD 2
-#define XK_EXE 3
-
-protected int key_init(EditLine *);
-protected void key_end(EditLine *);
-protected key_value_t *key_map_cmd(EditLine *, int);
-protected key_value_t *key_map_str(EditLine *, char *);
-protected void key_reset(EditLine *);
-protected int key_get(EditLine *, char *, key_value_t *);
-protected void key_add(EditLine *, const char *, key_value_t *, int);
-protected void key_clear(EditLine *, el_action_t *, const char *);
-protected int key_delete(EditLine *, const char *);
-protected void key_print(EditLine *, const char *);
-protected void key_kprint(EditLine *, const char *, key_value_t *,
- int);
-protected char *key__decode_str(const char *, char *, const char *);
-
-#endif /* _h_el_key */
diff --git a/1.4/main/editline/makelist b/1.4/main/editline/makelist
deleted file mode 100644
index 36f434cd0..000000000
--- a/1.4/main/editline/makelist
+++ /dev/null
@@ -1,254 +0,0 @@
-#!/bin/sh -
-# $NetBSD: makelist,v 1.7 2001/01/09 19:22:31 jdolecek Exp $
-#
-# Copyright (c) 1992, 1993
-# The Regents of the University of California. All rights reserved.
-#
-# This code is derived from software contributed to Berkeley by
-# Christos Zoulas of Cornell University.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. All advertising materials mentioning features or use of this software
-# must display the following acknowledgement:
-# This product includes software developed by the University of
-# California, Berkeley and its contributors.
-# 4. Neither the name of the University nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-# @(#)makelist 5.3 (Berkeley) 6/4/93
-
-# makelist.sh: Automatically generate header files...
-
-AWK=/usr/bin/awk
-USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
-
-if [ "x$1" = "x" ]
-then
- echo $USAGE 1>&2
- exit 1
-fi
-
-FLAG="$1"
-shift
-
-FILES="$@"
-
-case $FLAG in
-
-# generate foo.h file from foo.c
-#
--h)
- set - `echo $FILES | sed -e 's/\\./_/g'`
- hdr="_h_`basename $1`"
- cat $FILES | $AWK '
- BEGIN {
- printf("/* Automatically generated file, do not edit */\n");
- printf("#ifndef %s\n#define %s\n", "'$hdr'", "'$hdr'");
- }
- /\(\):/ {
- pr = substr($2, 1, 2);
- if (pr == "vi" || pr == "em" || pr == "ed") {
- name = substr($2, 1, length($2) - 3);
-#
-# XXX: need a space between name and prototype so that -fc and -fh
-# parsing is much easier
-#
- printf("protected el_action_t\t%s (EditLine *, int);\n", name);
- }
- }
- END {
- printf("#endif /* %s */\n", "'$hdr'");
- }'
- ;;
-
-# generate help.c from various .c files
-#
--bc)
- cat $FILES | $AWK '
- BEGIN {
- printf("/* Automatically generated file, do not edit */\n");
- printf("#include \"sys.h\"\n#include \"el.h\"\n");
- printf("private const struct el_bindings_t el_func_help[] = {\n");
- low = "abcdefghijklmnopqrstuvwxyz_";
- high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
- for (i = 1; i <= length(low); i++)
- tr[substr(low, i, 1)] = substr(high, i, 1);
- }
- /\(\):/ {
- pr = substr($2, 1, 2);
- if (pr == "vi" || pr == "em" || pr == "ed") {
- name = substr($2, 1, length($2) - 3);
- uname = "";
- fname = "";
- for (i = 1; i <= length(name); i++) {
- s = substr(name, i, 1);
- uname = uname tr[s];
- if (s == "_")
- s = "-";
- fname = fname s;
- }
-
- printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ",");
- ok = 1;
- }
- }
- /^ \*/ {
- if (ok) {
- printf(" \"");
- for (i = 2; i < NF; i++)
- printf("%s ", $i);
- printf("%s\" },\n", $i);
- ok = 0;
- }
- }
- END {
- printf(" { NULL, 0, NULL }\n");
- printf("};\n");
- printf("\nprotected const el_bindings_t* help__get()");
- printf("{ return el_func_help; }\n");
- }'
- ;;
-
-# generate help.h from various .c files
-#
--bh)
- $AWK '
- BEGIN {
- printf("/* Automatically generated file, do not edit */\n");
- printf("#ifndef _h_help_c\n#define _h_help_c\n");
- printf("protected const el_bindings_t *help__get(void);\n");
- printf("#endif /* _h_help_c */\n");
- }' /dev/null
- ;;
-
-# generate fcns.h from various .h files
-#
--fh)
- cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
- sort | tr '[:lower:]' '[:upper:]' | $AWK '
- BEGIN {
- printf("/* Automatically generated file, do not edit */\n");
- printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
- count = 0;
- }
- {
- printf("#define\t%-30.30s\t%3d\n", $1, count++);
- }
- END {
- printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
-
- printf("typedef el_action_t (*el_func_t)(EditLine *, int);");
- printf("\nprotected const el_func_t* func__get(void);\n");
- printf("#endif /* _h_fcns_c */\n");
- }'
- ;;
-
-# generate fcns.c from various .h files
-#
--fc)
- cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK '
- BEGIN {
- printf("/* Automatically generated file, do not edit */\n");
- printf("#include \"sys.h\"\n#include \"el.h\"\n");
- printf("private const el_func_t el_func[] = {");
- maxlen = 80;
- needn = 1;
- len = 0;
- }
- {
- clen = 25 + 2;
- len += clen;
- if (len >= maxlen)
- needn = 1;
- if (needn) {
- printf("\n ");
- needn = 0;
- len = 4 + clen;
- }
- s = $1 ",";
- printf("%-26.26s ", s);
- }
- END {
- printf("\n};\n");
- printf("\nprotected const el_func_t* func__get() { return el_func; }\n");
- }'
- ;;
-
-# generate editline.c from various .c files
-#
--e)
- echo "$FILES" | tr ' ' '\012' | $AWK '
- BEGIN {
- printf("/* Automatically generated file, do not edit */\n");
- printf("#define protected static\n");
- printf("#define SCCSID\n");
- }
- {
- printf("#include \"%s\"\n", $1);
- }'
- ;;
-
-# generate man page fragment from various .c files
-#
--m)
- cat $FILES | $AWK '
- BEGIN {
- printf(".\\\" Section automatically generated with makelist\n");
- printf(".Bl -tag -width 4n\n");
- }
- /\(\):/ {
- pr = substr($2, 1, 2);
- if (pr == "vi" || pr == "em" || pr == "ed") {
- name = substr($2, 1, length($2) - 3);
- fname = "";
- for (i = 1; i <= length(name); i++) {
- s = substr(name, i, 1);
- if (s == "_")
- s = "-";
- fname = fname s;
- }
-
- printf(".It Ic %s\n", fname);
- ok = 1;
- }
- }
- /^ \*/ {
- if (ok) {
- for (i = 2; i < NF; i++)
- printf("%s ", $i);
- printf("%s.\n", $i);
- ok = 0;
- }
- }
- END {
- printf(".El\n");
- printf(".\\\" End of section automatically generated with makelist\n");
- }'
- ;;
-
-*)
- echo $USAGE 1>&2
- exit 1
- ;;
-
-esac
diff --git a/1.4/main/editline/map.c b/1.4/main/editline/map.c
deleted file mode 100644
index 4187cb597..000000000
--- a/1.4/main/editline/map.c
+++ /dev/null
@@ -1,1418 +0,0 @@
-/* $NetBSD: map.c,v 1.15 2002/03/18 16:00:55 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: map.c,v 1.15 2002/03/18 16:00:55 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * map.c: Editor function definitions
- */
-#include <stdlib.h>
-#include "el.h"
-
-#define N_KEYS 256
-
-private void map_print_key(EditLine *, el_action_t *, const char *);
-private void map_print_some_keys(EditLine *, el_action_t *, int, int);
-private void map_print_all_keys(EditLine *);
-private void map_init_nls(EditLine *);
-private void map_init_meta(EditLine *);
-
-/* keymap tables ; should be N_KEYS*sizeof(KEYCMD) bytes long */
-
-
-private const el_action_t el_map_emacs[] = {
- /* 0 */ EM_SET_MARK, /* ^@ */
- /* 1 */ ED_MOVE_TO_BEG, /* ^A */
- /* 2 */ ED_PREV_CHAR, /* ^B */
- /* 3 */ ED_TTY_SIGINT, /* ^C */
- /* 4 */ EM_DELETE_OR_LIST, /* ^D */
- /* 5 */ ED_MOVE_TO_END, /* ^E */
- /* 6 */ ED_NEXT_CHAR, /* ^F */
- /* 7 */ ED_UNASSIGNED, /* ^G */
- /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */
- /* 9 */ ED_UNASSIGNED, /* ^I */
- /* 10 */ ED_NEWLINE, /* ^J */
- /* 11 */ ED_KILL_LINE, /* ^K */
- /* 12 */ ED_CLEAR_SCREEN, /* ^L */
- /* 13 */ ED_NEWLINE, /* ^M */
- /* 14 */ ED_NEXT_HISTORY, /* ^N */
- /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
- /* 16 */ ED_PREV_HISTORY, /* ^P */
- /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
- /* 18 */ ED_REDISPLAY, /* ^R */
- /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
- /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
- /* 21 */ EM_KILL_LINE, /* ^U */
- /* 22 */ ED_QUOTED_INSERT, /* ^V */
- /* 23 */ EM_KILL_REGION, /* ^W */
- /* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */
- /* 25 */ EM_YANK, /* ^Y */
- /* 26 */ ED_TTY_SIGTSTP, /* ^Z */
- /* 27 */ EM_META_NEXT, /* ^[ */
- /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
- /* 29 */ ED_TTY_DSUSP, /* ^] */
- /* 30 */ ED_UNASSIGNED, /* ^^ */
- /* 31 */ ED_UNASSIGNED, /* ^_ */
- /* 32 */ ED_INSERT, /* SPACE */
- /* 33 */ ED_INSERT, /* ! */
- /* 34 */ ED_INSERT, /* " */
- /* 35 */ ED_INSERT, /* # */
- /* 36 */ ED_INSERT, /* $ */
- /* 37 */ ED_INSERT, /* % */
- /* 38 */ ED_INSERT, /* & */
- /* 39 */ ED_INSERT, /* ' */
- /* 40 */ ED_INSERT, /* ( */
- /* 41 */ ED_INSERT, /* ) */
- /* 42 */ ED_INSERT, /* * */
- /* 43 */ ED_INSERT, /* + */
- /* 44 */ ED_INSERT, /* , */
- /* 45 */ ED_INSERT, /* - */
- /* 46 */ ED_INSERT, /* . */
- /* 47 */ ED_INSERT, /* / */
- /* 48 */ ED_DIGIT, /* 0 */
- /* 49 */ ED_DIGIT, /* 1 */
- /* 50 */ ED_DIGIT, /* 2 */
- /* 51 */ ED_DIGIT, /* 3 */
- /* 52 */ ED_DIGIT, /* 4 */
- /* 53 */ ED_DIGIT, /* 5 */
- /* 54 */ ED_DIGIT, /* 6 */
- /* 55 */ ED_DIGIT, /* 7 */
- /* 56 */ ED_DIGIT, /* 8 */
- /* 57 */ ED_DIGIT, /* 9 */
- /* 58 */ ED_INSERT, /* : */
- /* 59 */ ED_INSERT, /* ; */
- /* 60 */ ED_INSERT, /* < */
- /* 61 */ ED_INSERT, /* = */
- /* 62 */ ED_INSERT, /* > */
- /* 63 */ ED_INSERT, /* ? */
- /* 64 */ ED_INSERT, /* @ */
- /* 65 */ ED_INSERT, /* A */
- /* 66 */ ED_INSERT, /* B */
- /* 67 */ ED_INSERT, /* C */
- /* 68 */ ED_INSERT, /* D */
- /* 69 */ ED_INSERT, /* E */
- /* 70 */ ED_INSERT, /* F */
- /* 71 */ ED_INSERT, /* G */
- /* 72 */ ED_INSERT, /* H */
- /* 73 */ ED_INSERT, /* I */
- /* 74 */ ED_INSERT, /* J */
- /* 75 */ ED_INSERT, /* K */
- /* 76 */ ED_INSERT, /* L */
- /* 77 */ ED_INSERT, /* M */
- /* 78 */ ED_INSERT, /* N */
- /* 79 */ ED_INSERT, /* O */
- /* 80 */ ED_INSERT, /* P */
- /* 81 */ ED_INSERT, /* Q */
- /* 82 */ ED_INSERT, /* R */
- /* 83 */ ED_INSERT, /* S */
- /* 84 */ ED_INSERT, /* T */
- /* 85 */ ED_INSERT, /* U */
- /* 86 */ ED_INSERT, /* V */
- /* 87 */ ED_INSERT, /* W */
- /* 88 */ ED_INSERT, /* X */
- /* 89 */ ED_INSERT, /* Y */
- /* 90 */ ED_INSERT, /* Z */
- /* 91 */ ED_INSERT, /* [ */
- /* 92 */ ED_INSERT, /* \ */
- /* 93 */ ED_INSERT, /* ] */
- /* 94 */ ED_INSERT, /* ^ */
- /* 95 */ ED_INSERT, /* _ */
- /* 96 */ ED_INSERT, /* ` */
- /* 97 */ ED_INSERT, /* a */
- /* 98 */ ED_INSERT, /* b */
- /* 99 */ ED_INSERT, /* c */
- /* 100 */ ED_INSERT, /* d */
- /* 101 */ ED_INSERT, /* e */
- /* 102 */ ED_INSERT, /* f */
- /* 103 */ ED_INSERT, /* g */
- /* 104 */ ED_INSERT, /* h */
- /* 105 */ ED_INSERT, /* i */
- /* 106 */ ED_INSERT, /* j */
- /* 107 */ ED_INSERT, /* k */
- /* 108 */ ED_INSERT, /* l */
- /* 109 */ ED_INSERT, /* m */
- /* 110 */ ED_INSERT, /* n */
- /* 111 */ ED_INSERT, /* o */
- /* 112 */ ED_INSERT, /* p */
- /* 113 */ ED_INSERT, /* q */
- /* 114 */ ED_INSERT, /* r */
- /* 115 */ ED_INSERT, /* s */
- /* 116 */ ED_INSERT, /* t */
- /* 117 */ ED_INSERT, /* u */
- /* 118 */ ED_INSERT, /* v */
- /* 119 */ ED_INSERT, /* w */
- /* 120 */ ED_INSERT, /* x */
- /* 121 */ ED_INSERT, /* y */
- /* 122 */ ED_INSERT, /* z */
- /* 123 */ ED_INSERT, /* { */
- /* 124 */ ED_INSERT, /* | */
- /* 125 */ ED_INSERT, /* } */
- /* 126 */ ED_INSERT, /* ~ */
- /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
- /* 128 */ ED_UNASSIGNED, /* M-^@ */
- /* 129 */ ED_UNASSIGNED, /* M-^A */
- /* 130 */ ED_UNASSIGNED, /* M-^B */
- /* 131 */ ED_UNASSIGNED, /* M-^C */
- /* 132 */ ED_UNASSIGNED, /* M-^D */
- /* 133 */ ED_UNASSIGNED, /* M-^E */
- /* 134 */ ED_UNASSIGNED, /* M-^F */
- /* 135 */ ED_UNASSIGNED, /* M-^G */
- /* 136 */ ED_DELETE_PREV_WORD, /* M-^H */
- /* 137 */ ED_UNASSIGNED, /* M-^I */
- /* 138 */ ED_UNASSIGNED, /* M-^J */
- /* 139 */ ED_UNASSIGNED, /* M-^K */
- /* 140 */ ED_CLEAR_SCREEN, /* M-^L */
- /* 141 */ ED_UNASSIGNED, /* M-^M */
- /* 142 */ ED_UNASSIGNED, /* M-^N */
- /* 143 */ ED_UNASSIGNED, /* M-^O */
- /* 144 */ ED_UNASSIGNED, /* M-^P */
- /* 145 */ ED_UNASSIGNED, /* M-^Q */
- /* 146 */ ED_UNASSIGNED, /* M-^R */
- /* 147 */ ED_UNASSIGNED, /* M-^S */
- /* 148 */ ED_UNASSIGNED, /* M-^T */
- /* 149 */ ED_UNASSIGNED, /* M-^U */
- /* 150 */ ED_UNASSIGNED, /* M-^V */
- /* 151 */ ED_UNASSIGNED, /* M-^W */
- /* 152 */ ED_UNASSIGNED, /* M-^X */
- /* 153 */ ED_UNASSIGNED, /* M-^Y */
- /* 154 */ ED_UNASSIGNED, /* M-^Z */
- /* 155 */ ED_UNASSIGNED, /* M-^[ */
- /* 156 */ ED_UNASSIGNED, /* M-^\ */
- /* 157 */ ED_UNASSIGNED, /* M-^] */
- /* 158 */ ED_UNASSIGNED, /* M-^^ */
- /* 159 */ EM_COPY_PREV_WORD, /* M-^_ */
- /* 160 */ ED_UNASSIGNED, /* M-SPACE */
- /* 161 */ ED_UNASSIGNED, /* M-! */
- /* 162 */ ED_UNASSIGNED, /* M-" */
- /* 163 */ ED_UNASSIGNED, /* M-# */
- /* 164 */ ED_UNASSIGNED, /* M-$ */
- /* 165 */ ED_UNASSIGNED, /* M-% */
- /* 166 */ ED_UNASSIGNED, /* M-& */
- /* 167 */ ED_UNASSIGNED, /* M-' */
- /* 168 */ ED_UNASSIGNED, /* M-( */
- /* 169 */ ED_UNASSIGNED, /* M-) */
- /* 170 */ ED_UNASSIGNED, /* M-* */
- /* 171 */ ED_UNASSIGNED, /* M-+ */
- /* 172 */ ED_UNASSIGNED, /* M-, */
- /* 173 */ ED_UNASSIGNED, /* M-- */
- /* 174 */ ED_UNASSIGNED, /* M-. */
- /* 175 */ ED_UNASSIGNED, /* M-/ */
- /* 176 */ ED_ARGUMENT_DIGIT, /* M-0 */
- /* 177 */ ED_ARGUMENT_DIGIT, /* M-1 */
- /* 178 */ ED_ARGUMENT_DIGIT, /* M-2 */
- /* 179 */ ED_ARGUMENT_DIGIT, /* M-3 */
- /* 180 */ ED_ARGUMENT_DIGIT, /* M-4 */
- /* 181 */ ED_ARGUMENT_DIGIT, /* M-5 */
- /* 182 */ ED_ARGUMENT_DIGIT, /* M-6 */
- /* 183 */ ED_ARGUMENT_DIGIT, /* M-7 */
- /* 184 */ ED_ARGUMENT_DIGIT, /* M-8 */
- /* 185 */ ED_ARGUMENT_DIGIT, /* M-9 */
- /* 186 */ ED_UNASSIGNED, /* M-: */
- /* 187 */ ED_UNASSIGNED, /* M-; */
- /* 188 */ ED_UNASSIGNED, /* M-< */
- /* 189 */ ED_UNASSIGNED, /* M-= */
- /* 190 */ ED_UNASSIGNED, /* M-> */
- /* 191 */ ED_UNASSIGNED, /* M-? */
- /* 192 */ ED_UNASSIGNED, /* M-@ */
- /* 193 */ ED_UNASSIGNED, /* M-A */
- /* 194 */ ED_PREV_WORD, /* M-B */
- /* 195 */ EM_CAPITOL_CASE, /* M-C */
- /* 196 */ EM_DELETE_NEXT_WORD, /* M-D */
- /* 197 */ ED_UNASSIGNED, /* M-E */
- /* 198 */ EM_NEXT_WORD, /* M-F */
- /* 199 */ ED_UNASSIGNED, /* M-G */
- /* 200 */ ED_UNASSIGNED, /* M-H */
- /* 201 */ ED_UNASSIGNED, /* M-I */
- /* 202 */ ED_UNASSIGNED, /* M-J */
- /* 203 */ ED_UNASSIGNED, /* M-K */
- /* 204 */ EM_LOWER_CASE, /* M-L */
- /* 205 */ ED_UNASSIGNED, /* M-M */
- /* 206 */ ED_SEARCH_NEXT_HISTORY, /* M-N */
- /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */
- /* 208 */ ED_SEARCH_PREV_HISTORY, /* M-P */
- /* 209 */ ED_UNASSIGNED, /* M-Q */
- /* 210 */ ED_UNASSIGNED, /* M-R */
- /* 211 */ ED_UNASSIGNED, /* M-S */
- /* 212 */ ED_UNASSIGNED, /* M-T */
- /* 213 */ EM_UPPER_CASE, /* M-U */
- /* 214 */ ED_UNASSIGNED, /* M-V */
- /* 215 */ EM_COPY_REGION, /* M-W */
- /* 216 */ ED_COMMAND, /* M-X */
- /* 217 */ ED_UNASSIGNED, /* M-Y */
- /* 218 */ ED_UNASSIGNED, /* M-Z */
- /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */
- /* 220 */ ED_UNASSIGNED, /* M-\ */
- /* 221 */ ED_UNASSIGNED, /* M-] */
- /* 222 */ ED_UNASSIGNED, /* M-^ */
- /* 223 */ ED_UNASSIGNED, /* M-_ */
- /* 223 */ ED_UNASSIGNED, /* M-` */
- /* 224 */ ED_UNASSIGNED, /* M-a */
- /* 225 */ ED_PREV_WORD, /* M-b */
- /* 226 */ EM_CAPITOL_CASE, /* M-c */
- /* 227 */ EM_DELETE_NEXT_WORD, /* M-d */
- /* 228 */ ED_UNASSIGNED, /* M-e */
- /* 229 */ EM_NEXT_WORD, /* M-f */
- /* 230 */ ED_UNASSIGNED, /* M-g */
- /* 231 */ ED_UNASSIGNED, /* M-h */
- /* 232 */ ED_UNASSIGNED, /* M-i */
- /* 233 */ ED_UNASSIGNED, /* M-j */
- /* 234 */ ED_UNASSIGNED, /* M-k */
- /* 235 */ EM_LOWER_CASE, /* M-l */
- /* 236 */ ED_UNASSIGNED, /* M-m */
- /* 237 */ ED_SEARCH_NEXT_HISTORY, /* M-n */
- /* 238 */ ED_UNASSIGNED, /* M-o */
- /* 239 */ ED_SEARCH_PREV_HISTORY, /* M-p */
- /* 240 */ ED_UNASSIGNED, /* M-q */
- /* 241 */ ED_UNASSIGNED, /* M-r */
- /* 242 */ ED_UNASSIGNED, /* M-s */
- /* 243 */ ED_UNASSIGNED, /* M-t */
- /* 244 */ EM_UPPER_CASE, /* M-u */
- /* 245 */ ED_UNASSIGNED, /* M-v */
- /* 246 */ EM_COPY_REGION, /* M-w */
- /* 247 */ ED_COMMAND, /* M-x */
- /* 248 */ ED_UNASSIGNED, /* M-y */
- /* 249 */ ED_UNASSIGNED, /* M-z */
- /* 250 */ ED_UNASSIGNED, /* M-{ */
- /* 251 */ ED_UNASSIGNED, /* M-| */
- /* 252 */ ED_UNASSIGNED, /* M-} */
- /* 253 */ ED_UNASSIGNED, /* M-~ */
- /* 254 */ ED_DELETE_PREV_WORD /* M-^? */
- /* 255 */
-};
-
-
-/*
- * keymap table for vi. Each index into above tbl; should be
- * N_KEYS entries long. Vi mode uses a sticky-extend to do command mode:
- * insert mode characters are in the normal keymap, and command mode
- * in the extended keymap.
- */
-private const el_action_t el_map_vi_insert[] = {
-#ifdef KSHVI
- /* 0 */ ED_UNASSIGNED, /* ^@ */
- /* 1 */ ED_INSERT, /* ^A */
- /* 2 */ ED_INSERT, /* ^B */
- /* 3 */ ED_INSERT, /* ^C */
- /* 4 */ VI_LIST_OR_EOF, /* ^D */
- /* 5 */ ED_INSERT, /* ^E */
- /* 6 */ ED_INSERT, /* ^F */
- /* 7 */ ED_INSERT, /* ^G */
- /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */
- /* 9 */ ED_INSERT, /* ^I */ /* Tab Key */
- /* 10 */ ED_NEWLINE, /* ^J */
- /* 11 */ ED_INSERT, /* ^K */
- /* 12 */ ED_INSERT, /* ^L */
- /* 13 */ ED_NEWLINE, /* ^M */
- /* 14 */ ED_INSERT, /* ^N */
- /* 15 */ ED_INSERT, /* ^O */
- /* 16 */ ED_INSERT, /* ^P */
- /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
- /* 18 */ ED_INSERT, /* ^R */
- /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
- /* 20 */ ED_INSERT, /* ^T */
- /* 21 */ VI_KILL_LINE_PREV, /* ^U */
- /* 22 */ ED_QUOTED_INSERT, /* ^V */
- /* 23 */ ED_DELETE_PREV_WORD, /* ^W */
- /* ED_DELETE_PREV_WORD: Only until strt edit pos */
- /* 24 */ ED_INSERT, /* ^X */
- /* 25 */ ED_INSERT, /* ^Y */
- /* 26 */ ED_INSERT, /* ^Z */
- /* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */
- /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
- /* 29 */ ED_INSERT, /* ^] */
- /* 30 */ ED_INSERT, /* ^^ */
- /* 31 */ ED_INSERT, /* ^_ */
-#else /* !KSHVI */
- /*
- * NOTE: These mappings do NOT Correspond well
- * to the KSH VI editing assignments.
- * On the other and they are convenient and
- * many people have have gotten used to them.
- */
- /* 0 */ ED_UNASSIGNED, /* ^@ */
- /* 1 */ ED_MOVE_TO_BEG, /* ^A */
- /* 2 */ ED_PREV_CHAR, /* ^B */
- /* 3 */ ED_TTY_SIGINT, /* ^C */
- /* 4 */ VI_LIST_OR_EOF, /* ^D */
- /* 5 */ ED_MOVE_TO_END, /* ^E */
- /* 6 */ ED_NEXT_CHAR, /* ^F */
- /* 7 */ ED_UNASSIGNED, /* ^G */
- /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */
- /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */
- /* 10 */ ED_NEWLINE, /* ^J */
- /* 11 */ ED_KILL_LINE, /* ^K */
- /* 12 */ ED_CLEAR_SCREEN, /* ^L */
- /* 13 */ ED_NEWLINE, /* ^M */
- /* 14 */ ED_NEXT_HISTORY, /* ^N */
- /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
- /* 16 */ ED_PREV_HISTORY, /* ^P */
- /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
- /* 18 */ ED_REDISPLAY, /* ^R */
- /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
- /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
- /* 21 */ VI_KILL_LINE_PREV, /* ^U */
- /* 22 */ ED_QUOTED_INSERT, /* ^V */
- /* 23 */ ED_DELETE_PREV_WORD, /* ^W */
- /* 24 */ ED_UNASSIGNED, /* ^X */
- /* 25 */ ED_TTY_DSUSP, /* ^Y */
- /* 26 */ ED_TTY_SIGTSTP, /* ^Z */
- /* 27 */ VI_COMMAND_MODE, /* ^[ */
- /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
- /* 29 */ ED_UNASSIGNED, /* ^] */
- /* 30 */ ED_UNASSIGNED, /* ^^ */
- /* 31 */ ED_UNASSIGNED, /* ^_ */
-#endif /* KSHVI */
- /* 32 */ ED_INSERT, /* SPACE */
- /* 33 */ ED_INSERT, /* ! */
- /* 34 */ ED_INSERT, /* " */
- /* 35 */ ED_INSERT, /* # */
- /* 36 */ ED_INSERT, /* $ */
- /* 37 */ ED_INSERT, /* % */
- /* 38 */ ED_INSERT, /* & */
- /* 39 */ ED_INSERT, /* ' */
- /* 40 */ ED_INSERT, /* ( */
- /* 41 */ ED_INSERT, /* ) */
- /* 42 */ ED_INSERT, /* * */
- /* 43 */ ED_INSERT, /* + */
- /* 44 */ ED_INSERT, /* , */
- /* 45 */ ED_INSERT, /* - */
- /* 46 */ ED_INSERT, /* . */
- /* 47 */ ED_INSERT, /* / */
- /* 48 */ ED_INSERT, /* 0 */
- /* 49 */ ED_INSERT, /* 1 */
- /* 50 */ ED_INSERT, /* 2 */
- /* 51 */ ED_INSERT, /* 3 */
- /* 52 */ ED_INSERT, /* 4 */
- /* 53 */ ED_INSERT, /* 5 */
- /* 54 */ ED_INSERT, /* 6 */
- /* 55 */ ED_INSERT, /* 7 */
- /* 56 */ ED_INSERT, /* 8 */
- /* 57 */ ED_INSERT, /* 9 */
- /* 58 */ ED_INSERT, /* : */
- /* 59 */ ED_INSERT, /* ; */
- /* 60 */ ED_INSERT, /* < */
- /* 61 */ ED_INSERT, /* = */
- /* 62 */ ED_INSERT, /* > */
- /* 63 */ ED_INSERT, /* ? */
- /* 64 */ ED_INSERT, /* @ */
- /* 65 */ ED_INSERT, /* A */
- /* 66 */ ED_INSERT, /* B */
- /* 67 */ ED_INSERT, /* C */
- /* 68 */ ED_INSERT, /* D */
- /* 69 */ ED_INSERT, /* E */
- /* 70 */ ED_INSERT, /* F */
- /* 71 */ ED_INSERT, /* G */
- /* 72 */ ED_INSERT, /* H */
- /* 73 */ ED_INSERT, /* I */
- /* 74 */ ED_INSERT, /* J */
- /* 75 */ ED_INSERT, /* K */
- /* 76 */ ED_INSERT, /* L */
- /* 77 */ ED_INSERT, /* M */
- /* 78 */ ED_INSERT, /* N */
- /* 79 */ ED_INSERT, /* O */
- /* 80 */ ED_INSERT, /* P */
- /* 81 */ ED_INSERT, /* Q */
- /* 82 */ ED_INSERT, /* R */
- /* 83 */ ED_INSERT, /* S */
- /* 84 */ ED_INSERT, /* T */
- /* 85 */ ED_INSERT, /* U */
- /* 86 */ ED_INSERT, /* V */
- /* 87 */ ED_INSERT, /* W */
- /* 88 */ ED_INSERT, /* X */
- /* 89 */ ED_INSERT, /* Y */
- /* 90 */ ED_INSERT, /* Z */
- /* 91 */ ED_INSERT, /* [ */
- /* 92 */ ED_INSERT, /* \ */
- /* 93 */ ED_INSERT, /* ] */
- /* 94 */ ED_INSERT, /* ^ */
- /* 95 */ ED_INSERT, /* _ */
- /* 96 */ ED_INSERT, /* ` */
- /* 97 */ ED_INSERT, /* a */
- /* 98 */ ED_INSERT, /* b */
- /* 99 */ ED_INSERT, /* c */
- /* 100 */ ED_INSERT, /* d */
- /* 101 */ ED_INSERT, /* e */
- /* 102 */ ED_INSERT, /* f */
- /* 103 */ ED_INSERT, /* g */
- /* 104 */ ED_INSERT, /* h */
- /* 105 */ ED_INSERT, /* i */
- /* 106 */ ED_INSERT, /* j */
- /* 107 */ ED_INSERT, /* k */
- /* 108 */ ED_INSERT, /* l */
- /* 109 */ ED_INSERT, /* m */
- /* 110 */ ED_INSERT, /* n */
- /* 111 */ ED_INSERT, /* o */
- /* 112 */ ED_INSERT, /* p */
- /* 113 */ ED_INSERT, /* q */
- /* 114 */ ED_INSERT, /* r */
- /* 115 */ ED_INSERT, /* s */
- /* 116 */ ED_INSERT, /* t */
- /* 117 */ ED_INSERT, /* u */
- /* 118 */ ED_INSERT, /* v */
- /* 119 */ ED_INSERT, /* w */
- /* 120 */ ED_INSERT, /* x */
- /* 121 */ ED_INSERT, /* y */
- /* 122 */ ED_INSERT, /* z */
- /* 123 */ ED_INSERT, /* { */
- /* 124 */ ED_INSERT, /* | */
- /* 125 */ ED_INSERT, /* } */
- /* 126 */ ED_INSERT, /* ~ */
- /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
- /* 128 */ ED_UNASSIGNED, /* M-^@ */
- /* 129 */ ED_UNASSIGNED, /* M-^A */
- /* 130 */ ED_UNASSIGNED, /* M-^B */
- /* 131 */ ED_UNASSIGNED, /* M-^C */
- /* 132 */ ED_UNASSIGNED, /* M-^D */
- /* 133 */ ED_UNASSIGNED, /* M-^E */
- /* 134 */ ED_UNASSIGNED, /* M-^F */
- /* 135 */ ED_UNASSIGNED, /* M-^G */
- /* 136 */ ED_UNASSIGNED, /* M-^H */
- /* 137 */ ED_UNASSIGNED, /* M-^I */
- /* 138 */ ED_UNASSIGNED, /* M-^J */
- /* 139 */ ED_UNASSIGNED, /* M-^K */
- /* 140 */ ED_UNASSIGNED, /* M-^L */
- /* 141 */ ED_UNASSIGNED, /* M-^M */
- /* 142 */ ED_UNASSIGNED, /* M-^N */
- /* 143 */ ED_UNASSIGNED, /* M-^O */
- /* 144 */ ED_UNASSIGNED, /* M-^P */
- /* 145 */ ED_UNASSIGNED, /* M-^Q */
- /* 146 */ ED_UNASSIGNED, /* M-^R */
- /* 147 */ ED_UNASSIGNED, /* M-^S */
- /* 148 */ ED_UNASSIGNED, /* M-^T */
- /* 149 */ ED_UNASSIGNED, /* M-^U */
- /* 150 */ ED_UNASSIGNED, /* M-^V */
- /* 151 */ ED_UNASSIGNED, /* M-^W */
- /* 152 */ ED_UNASSIGNED, /* M-^X */
- /* 153 */ ED_UNASSIGNED, /* M-^Y */
- /* 154 */ ED_UNASSIGNED, /* M-^Z */
- /* 155 */ ED_UNASSIGNED, /* M-^[ */
- /* 156 */ ED_UNASSIGNED, /* M-^\ */
- /* 157 */ ED_UNASSIGNED, /* M-^] */
- /* 158 */ ED_UNASSIGNED, /* M-^^ */
- /* 159 */ ED_UNASSIGNED, /* M-^_ */
- /* 160 */ ED_UNASSIGNED, /* M-SPACE */
- /* 161 */ ED_UNASSIGNED, /* M-! */
- /* 162 */ ED_UNASSIGNED, /* M-" */
- /* 163 */ ED_UNASSIGNED, /* M-# */
- /* 164 */ ED_UNASSIGNED, /* M-$ */
- /* 165 */ ED_UNASSIGNED, /* M-% */
- /* 166 */ ED_UNASSIGNED, /* M-& */
- /* 167 */ ED_UNASSIGNED, /* M-' */
- /* 168 */ ED_UNASSIGNED, /* M-( */
- /* 169 */ ED_UNASSIGNED, /* M-) */
- /* 170 */ ED_UNASSIGNED, /* M-* */
- /* 171 */ ED_UNASSIGNED, /* M-+ */
- /* 172 */ ED_UNASSIGNED, /* M-, */
- /* 173 */ ED_UNASSIGNED, /* M-- */
- /* 174 */ ED_UNASSIGNED, /* M-. */
- /* 175 */ ED_UNASSIGNED, /* M-/ */
- /* 176 */ ED_UNASSIGNED, /* M-0 */
- /* 177 */ ED_UNASSIGNED, /* M-1 */
- /* 178 */ ED_UNASSIGNED, /* M-2 */
- /* 179 */ ED_UNASSIGNED, /* M-3 */
- /* 180 */ ED_UNASSIGNED, /* M-4 */
- /* 181 */ ED_UNASSIGNED, /* M-5 */
- /* 182 */ ED_UNASSIGNED, /* M-6 */
- /* 183 */ ED_UNASSIGNED, /* M-7 */
- /* 184 */ ED_UNASSIGNED, /* M-8 */
- /* 185 */ ED_UNASSIGNED, /* M-9 */
- /* 186 */ ED_UNASSIGNED, /* M-: */
- /* 187 */ ED_UNASSIGNED, /* M-; */
- /* 188 */ ED_UNASSIGNED, /* M-< */
- /* 189 */ ED_UNASSIGNED, /* M-= */
- /* 190 */ ED_UNASSIGNED, /* M-> */
- /* 191 */ ED_UNASSIGNED, /* M-? */
- /* 192 */ ED_UNASSIGNED, /* M-@ */
- /* 193 */ ED_UNASSIGNED, /* M-A */
- /* 194 */ ED_UNASSIGNED, /* M-B */
- /* 195 */ ED_UNASSIGNED, /* M-C */
- /* 196 */ ED_UNASSIGNED, /* M-D */
- /* 197 */ ED_UNASSIGNED, /* M-E */
- /* 198 */ ED_UNASSIGNED, /* M-F */
- /* 199 */ ED_UNASSIGNED, /* M-G */
- /* 200 */ ED_UNASSIGNED, /* M-H */
- /* 201 */ ED_UNASSIGNED, /* M-I */
- /* 202 */ ED_UNASSIGNED, /* M-J */
- /* 203 */ ED_UNASSIGNED, /* M-K */
- /* 204 */ ED_UNASSIGNED, /* M-L */
- /* 205 */ ED_UNASSIGNED, /* M-M */
- /* 206 */ ED_UNASSIGNED, /* M-N */
- /* 207 */ ED_UNASSIGNED, /* M-O */
- /* 208 */ ED_UNASSIGNED, /* M-P */
- /* 209 */ ED_UNASSIGNED, /* M-Q */
- /* 210 */ ED_UNASSIGNED, /* M-R */
- /* 211 */ ED_UNASSIGNED, /* M-S */
- /* 212 */ ED_UNASSIGNED, /* M-T */
- /* 213 */ ED_UNASSIGNED, /* M-U */
- /* 214 */ ED_UNASSIGNED, /* M-V */
- /* 215 */ ED_UNASSIGNED, /* M-W */
- /* 216 */ ED_UNASSIGNED, /* M-X */
- /* 217 */ ED_UNASSIGNED, /* M-Y */
- /* 218 */ ED_UNASSIGNED, /* M-Z */
- /* 219 */ ED_UNASSIGNED, /* M-[ */
- /* 220 */ ED_UNASSIGNED, /* M-\ */
- /* 221 */ ED_UNASSIGNED, /* M-] */
- /* 222 */ ED_UNASSIGNED, /* M-^ */
- /* 223 */ ED_UNASSIGNED, /* M-_ */
- /* 224 */ ED_UNASSIGNED, /* M-` */
- /* 225 */ ED_UNASSIGNED, /* M-a */
- /* 226 */ ED_UNASSIGNED, /* M-b */
- /* 227 */ ED_UNASSIGNED, /* M-c */
- /* 228 */ ED_UNASSIGNED, /* M-d */
- /* 229 */ ED_UNASSIGNED, /* M-e */
- /* 230 */ ED_UNASSIGNED, /* M-f */
- /* 231 */ ED_UNASSIGNED, /* M-g */
- /* 232 */ ED_UNASSIGNED, /* M-h */
- /* 233 */ ED_UNASSIGNED, /* M-i */
- /* 234 */ ED_UNASSIGNED, /* M-j */
- /* 235 */ ED_UNASSIGNED, /* M-k */
- /* 236 */ ED_UNASSIGNED, /* M-l */
- /* 237 */ ED_UNASSIGNED, /* M-m */
- /* 238 */ ED_UNASSIGNED, /* M-n */
- /* 239 */ ED_UNASSIGNED, /* M-o */
- /* 240 */ ED_UNASSIGNED, /* M-p */
- /* 241 */ ED_UNASSIGNED, /* M-q */
- /* 242 */ ED_UNASSIGNED, /* M-r */
- /* 243 */ ED_UNASSIGNED, /* M-s */
- /* 244 */ ED_UNASSIGNED, /* M-t */
- /* 245 */ ED_UNASSIGNED, /* M-u */
- /* 246 */ ED_UNASSIGNED, /* M-v */
- /* 247 */ ED_UNASSIGNED, /* M-w */
- /* 248 */ ED_UNASSIGNED, /* M-x */
- /* 249 */ ED_UNASSIGNED, /* M-y */
- /* 250 */ ED_UNASSIGNED, /* M-z */
- /* 251 */ ED_UNASSIGNED, /* M-{ */
- /* 252 */ ED_UNASSIGNED, /* M-| */
- /* 253 */ ED_UNASSIGNED, /* M-} */
- /* 254 */ ED_UNASSIGNED, /* M-~ */
- /* 255 */ ED_UNASSIGNED /* M-^? */
-};
-
-private const el_action_t el_map_vi_command[] = {
- /* 0 */ ED_UNASSIGNED, /* ^@ */
- /* 1 */ ED_MOVE_TO_BEG, /* ^A */
- /* 2 */ ED_UNASSIGNED, /* ^B */
- /* 3 */ ED_TTY_SIGINT, /* ^C */
- /* 4 */ ED_UNASSIGNED, /* ^D */
- /* 5 */ ED_MOVE_TO_END, /* ^E */
- /* 6 */ ED_UNASSIGNED, /* ^F */
- /* 7 */ ED_UNASSIGNED, /* ^G */
- /* 8 */ ED_PREV_CHAR, /* ^H */
- /* 9 */ ED_UNASSIGNED, /* ^I */
- /* 10 */ ED_NEWLINE, /* ^J */
- /* 11 */ ED_KILL_LINE, /* ^K */
- /* 12 */ ED_CLEAR_SCREEN, /* ^L */
- /* 13 */ ED_NEWLINE, /* ^M */
- /* 14 */ ED_NEXT_HISTORY, /* ^N */
- /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
- /* 16 */ ED_PREV_HISTORY, /* ^P */
- /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
- /* 18 */ ED_REDISPLAY, /* ^R */
- /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
- /* 20 */ ED_UNASSIGNED, /* ^T */
- /* 21 */ VI_KILL_LINE_PREV, /* ^U */
- /* 22 */ ED_UNASSIGNED, /* ^V */
- /* 23 */ ED_DELETE_PREV_WORD, /* ^W */
- /* 24 */ ED_UNASSIGNED, /* ^X */
- /* 25 */ ED_UNASSIGNED, /* ^Y */
- /* 26 */ ED_UNASSIGNED, /* ^Z */
- /* 27 */ EM_META_NEXT, /* ^[ */
- /* 28 */ ED_TTY_SIGQUIT, /* ^\ */
- /* 29 */ ED_UNASSIGNED, /* ^] */
- /* 30 */ ED_UNASSIGNED, /* ^^ */
- /* 31 */ ED_UNASSIGNED, /* ^_ */
- /* 32 */ ED_NEXT_CHAR, /* SPACE */
- /* 33 */ ED_UNASSIGNED, /* ! */
- /* 34 */ ED_UNASSIGNED, /* " */
- /* 35 */ ED_UNASSIGNED, /* # */
- /* 36 */ ED_MOVE_TO_END, /* $ */
- /* 37 */ ED_UNASSIGNED, /* % */
- /* 38 */ ED_UNASSIGNED, /* & */
- /* 39 */ ED_UNASSIGNED, /* ' */
- /* 40 */ ED_UNASSIGNED, /* ( */
- /* 41 */ ED_UNASSIGNED, /* ) */
- /* 42 */ ED_UNASSIGNED, /* * */
- /* 43 */ ED_NEXT_HISTORY, /* + */
- /* 44 */ VI_REPEAT_PREV_CHAR, /* , */
- /* 45 */ ED_PREV_HISTORY, /* - */
- /* 46 */ ED_UNASSIGNED, /* . */
- /* 47 */ VI_SEARCH_PREV, /* / */
- /* 48 */ VI_ZERO, /* 0 */
- /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */
- /* 50 */ ED_ARGUMENT_DIGIT, /* 2 */
- /* 51 */ ED_ARGUMENT_DIGIT, /* 3 */
- /* 52 */ ED_ARGUMENT_DIGIT, /* 4 */
- /* 53 */ ED_ARGUMENT_DIGIT, /* 5 */
- /* 54 */ ED_ARGUMENT_DIGIT, /* 6 */
- /* 55 */ ED_ARGUMENT_DIGIT, /* 7 */
- /* 56 */ ED_ARGUMENT_DIGIT, /* 8 */
- /* 57 */ ED_ARGUMENT_DIGIT, /* 9 */
- /* 58 */ ED_COMMAND, /* : */
- /* 59 */ VI_REPEAT_NEXT_CHAR, /* ; */
- /* 60 */ ED_UNASSIGNED, /* < */
- /* 61 */ ED_UNASSIGNED, /* = */
- /* 62 */ ED_UNASSIGNED, /* > */
- /* 63 */ VI_SEARCH_NEXT, /* ? */
- /* 64 */ ED_UNASSIGNED, /* @ */
- /* 65 */ VI_ADD_AT_EOL, /* A */
- /* 66 */ VI_PREV_SPACE_WORD, /* B */
- /* 67 */ VI_CHANGE_TO_EOL, /* C */
- /* 68 */ ED_KILL_LINE, /* D */
- /* 69 */ VI_TO_END_WORD, /* E */
- /* 70 */ VI_PREV_CHAR, /* F */
- /* 71 */ ED_UNASSIGNED, /* G */
- /* 72 */ ED_UNASSIGNED, /* H */
- /* 73 */ VI_INSERT_AT_BOL, /* I */
- /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */
- /* 75 */ ED_SEARCH_PREV_HISTORY, /* K */
- /* 76 */ ED_UNASSIGNED, /* L */
- /* 77 */ ED_UNASSIGNED, /* M */
- /* 78 */ VI_REPEAT_SEARCH_PREV, /* N */
- /* 79 */ ED_SEQUENCE_LEAD_IN, /* O */
- /* 80 */ VI_PASTE_PREV, /* P */
- /* 81 */ ED_UNASSIGNED, /* Q */
- /* 82 */ VI_REPLACE_MODE, /* R */
- /* 83 */ VI_SUBSTITUTE_LINE, /* S */
- /* 84 */ VI_TO_PREV_CHAR, /* T */
- /* 85 */ ED_UNASSIGNED, /* U */
- /* 86 */ ED_UNASSIGNED, /* V */
- /* 87 */ VI_NEXT_SPACE_WORD, /* W */
- /* 88 */ ED_DELETE_PREV_CHAR, /* X */
- /* 89 */ ED_UNASSIGNED, /* Y */
- /* 90 */ ED_UNASSIGNED, /* Z */
- /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */
- /* 92 */ ED_UNASSIGNED, /* \ */
- /* 93 */ ED_UNASSIGNED, /* ] */
- /* 94 */ ED_MOVE_TO_BEG, /* ^ */
- /* 95 */ ED_UNASSIGNED, /* _ */
- /* 96 */ ED_UNASSIGNED, /* ` */
- /* 97 */ VI_ADD, /* a */
- /* 98 */ VI_PREV_WORD, /* b */
- /* 99 */ VI_CHANGE_META, /* c */
- /* 100 */ VI_DELETE_META, /* d */
- /* 101 */ VI_END_WORD, /* e */
- /* 102 */ VI_NEXT_CHAR, /* f */
- /* 103 */ ED_UNASSIGNED, /* g */
- /* 104 */ ED_PREV_CHAR, /* h */
- /* 105 */ VI_INSERT, /* i */
- /* 106 */ ED_NEXT_HISTORY, /* j */
- /* 107 */ ED_PREV_HISTORY, /* k */
- /* 108 */ ED_NEXT_CHAR, /* l */
- /* 109 */ ED_UNASSIGNED, /* m */
- /* 110 */ VI_REPEAT_SEARCH_NEXT, /* n */
- /* 111 */ ED_UNASSIGNED, /* o */
- /* 112 */ VI_PASTE_NEXT, /* p */
- /* 113 */ ED_UNASSIGNED, /* q */
- /* 114 */ VI_REPLACE_CHAR, /* r */
- /* 115 */ VI_SUBSTITUTE_CHAR, /* s */
- /* 116 */ VI_TO_NEXT_CHAR, /* t */
- /* 117 */ VI_UNDO, /* u */
- /* 118 */ ED_UNASSIGNED, /* v */
- /* 119 */ VI_NEXT_WORD, /* w */
- /* 120 */ ED_DELETE_NEXT_CHAR, /* x */
- /* 121 */ ED_UNASSIGNED, /* y */
- /* 122 */ ED_UNASSIGNED, /* z */
- /* 123 */ ED_UNASSIGNED, /* { */
- /* 124 */ ED_UNASSIGNED, /* | */
- /* 125 */ ED_UNASSIGNED, /* } */
- /* 126 */ VI_CHANGE_CASE, /* ~ */
- /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
- /* 128 */ ED_UNASSIGNED, /* M-^@ */
- /* 129 */ ED_UNASSIGNED, /* M-^A */
- /* 130 */ ED_UNASSIGNED, /* M-^B */
- /* 131 */ ED_UNASSIGNED, /* M-^C */
- /* 132 */ ED_UNASSIGNED, /* M-^D */
- /* 133 */ ED_UNASSIGNED, /* M-^E */
- /* 134 */ ED_UNASSIGNED, /* M-^F */
- /* 135 */ ED_UNASSIGNED, /* M-^G */
- /* 136 */ ED_UNASSIGNED, /* M-^H */
- /* 137 */ ED_UNASSIGNED, /* M-^I */
- /* 138 */ ED_UNASSIGNED, /* M-^J */
- /* 139 */ ED_UNASSIGNED, /* M-^K */
- /* 140 */ ED_UNASSIGNED, /* M-^L */
- /* 141 */ ED_UNASSIGNED, /* M-^M */
- /* 142 */ ED_UNASSIGNED, /* M-^N */
- /* 143 */ ED_UNASSIGNED, /* M-^O */
- /* 144 */ ED_UNASSIGNED, /* M-^P */
- /* 145 */ ED_UNASSIGNED, /* M-^Q */
- /* 146 */ ED_UNASSIGNED, /* M-^R */
- /* 147 */ ED_UNASSIGNED, /* M-^S */
- /* 148 */ ED_UNASSIGNED, /* M-^T */
- /* 149 */ ED_UNASSIGNED, /* M-^U */
- /* 150 */ ED_UNASSIGNED, /* M-^V */
- /* 151 */ ED_UNASSIGNED, /* M-^W */
- /* 152 */ ED_UNASSIGNED, /* M-^X */
- /* 153 */ ED_UNASSIGNED, /* M-^Y */
- /* 154 */ ED_UNASSIGNED, /* M-^Z */
- /* 155 */ ED_UNASSIGNED, /* M-^[ */
- /* 156 */ ED_UNASSIGNED, /* M-^\ */
- /* 157 */ ED_UNASSIGNED, /* M-^] */
- /* 158 */ ED_UNASSIGNED, /* M-^^ */
- /* 159 */ ED_UNASSIGNED, /* M-^_ */
- /* 160 */ ED_UNASSIGNED, /* M-SPACE */
- /* 161 */ ED_UNASSIGNED, /* M-! */
- /* 162 */ ED_UNASSIGNED, /* M-" */
- /* 163 */ ED_UNASSIGNED, /* M-# */
- /* 164 */ ED_UNASSIGNED, /* M-$ */
- /* 165 */ ED_UNASSIGNED, /* M-% */
- /* 166 */ ED_UNASSIGNED, /* M-& */
- /* 167 */ ED_UNASSIGNED, /* M-' */
- /* 168 */ ED_UNASSIGNED, /* M-( */
- /* 169 */ ED_UNASSIGNED, /* M-) */
- /* 170 */ ED_UNASSIGNED, /* M-* */
- /* 171 */ ED_UNASSIGNED, /* M-+ */
- /* 172 */ ED_UNASSIGNED, /* M-, */
- /* 173 */ ED_UNASSIGNED, /* M-- */
- /* 174 */ ED_UNASSIGNED, /* M-. */
- /* 175 */ ED_UNASSIGNED, /* M-/ */
- /* 176 */ ED_UNASSIGNED, /* M-0 */
- /* 177 */ ED_UNASSIGNED, /* M-1 */
- /* 178 */ ED_UNASSIGNED, /* M-2 */
- /* 179 */ ED_UNASSIGNED, /* M-3 */
- /* 180 */ ED_UNASSIGNED, /* M-4 */
- /* 181 */ ED_UNASSIGNED, /* M-5 */
- /* 182 */ ED_UNASSIGNED, /* M-6 */
- /* 183 */ ED_UNASSIGNED, /* M-7 */
- /* 184 */ ED_UNASSIGNED, /* M-8 */
- /* 185 */ ED_UNASSIGNED, /* M-9 */
- /* 186 */ ED_UNASSIGNED, /* M-: */
- /* 187 */ ED_UNASSIGNED, /* M-; */
- /* 188 */ ED_UNASSIGNED, /* M-< */
- /* 189 */ ED_UNASSIGNED, /* M-= */
- /* 190 */ ED_UNASSIGNED, /* M-> */
- /* 191 */ ED_UNASSIGNED, /* M-? */
- /* 192 */ ED_UNASSIGNED, /* M-@ */
- /* 193 */ ED_UNASSIGNED, /* M-A */
- /* 194 */ ED_UNASSIGNED, /* M-B */
- /* 195 */ ED_UNASSIGNED, /* M-C */
- /* 196 */ ED_UNASSIGNED, /* M-D */
- /* 197 */ ED_UNASSIGNED, /* M-E */
- /* 198 */ ED_UNASSIGNED, /* M-F */
- /* 199 */ ED_UNASSIGNED, /* M-G */
- /* 200 */ ED_UNASSIGNED, /* M-H */
- /* 201 */ ED_UNASSIGNED, /* M-I */
- /* 202 */ ED_UNASSIGNED, /* M-J */
- /* 203 */ ED_UNASSIGNED, /* M-K */
- /* 204 */ ED_UNASSIGNED, /* M-L */
- /* 205 */ ED_UNASSIGNED, /* M-M */
- /* 206 */ ED_UNASSIGNED, /* M-N */
- /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */
- /* 208 */ ED_UNASSIGNED, /* M-P */
- /* 209 */ ED_UNASSIGNED, /* M-Q */
- /* 210 */ ED_UNASSIGNED, /* M-R */
- /* 211 */ ED_UNASSIGNED, /* M-S */
- /* 212 */ ED_UNASSIGNED, /* M-T */
- /* 213 */ ED_UNASSIGNED, /* M-U */
- /* 214 */ ED_UNASSIGNED, /* M-V */
- /* 215 */ ED_UNASSIGNED, /* M-W */
- /* 216 */ ED_UNASSIGNED, /* M-X */
- /* 217 */ ED_UNASSIGNED, /* M-Y */
- /* 218 */ ED_UNASSIGNED, /* M-Z */
- /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */
- /* 220 */ ED_UNASSIGNED, /* M-\ */
- /* 221 */ ED_UNASSIGNED, /* M-] */
- /* 222 */ ED_UNASSIGNED, /* M-^ */
- /* 223 */ ED_UNASSIGNED, /* M-_ */
- /* 224 */ ED_UNASSIGNED, /* M-` */
- /* 225 */ ED_UNASSIGNED, /* M-a */
- /* 226 */ ED_UNASSIGNED, /* M-b */
- /* 227 */ ED_UNASSIGNED, /* M-c */
- /* 228 */ ED_UNASSIGNED, /* M-d */
- /* 229 */ ED_UNASSIGNED, /* M-e */
- /* 230 */ ED_UNASSIGNED, /* M-f */
- /* 231 */ ED_UNASSIGNED, /* M-g */
- /* 232 */ ED_UNASSIGNED, /* M-h */
- /* 233 */ ED_UNASSIGNED, /* M-i */
- /* 234 */ ED_UNASSIGNED, /* M-j */
- /* 235 */ ED_UNASSIGNED, /* M-k */
- /* 236 */ ED_UNASSIGNED, /* M-l */
- /* 237 */ ED_UNASSIGNED, /* M-m */
- /* 238 */ ED_UNASSIGNED, /* M-n */
- /* 239 */ ED_UNASSIGNED, /* M-o */
- /* 240 */ ED_UNASSIGNED, /* M-p */
- /* 241 */ ED_UNASSIGNED, /* M-q */
- /* 242 */ ED_UNASSIGNED, /* M-r */
- /* 243 */ ED_UNASSIGNED, /* M-s */
- /* 244 */ ED_UNASSIGNED, /* M-t */
- /* 245 */ ED_UNASSIGNED, /* M-u */
- /* 246 */ ED_UNASSIGNED, /* M-v */
- /* 247 */ ED_UNASSIGNED, /* M-w */
- /* 248 */ ED_UNASSIGNED, /* M-x */
- /* 249 */ ED_UNASSIGNED, /* M-y */
- /* 250 */ ED_UNASSIGNED, /* M-z */
- /* 251 */ ED_UNASSIGNED, /* M-{ */
- /* 252 */ ED_UNASSIGNED, /* M-| */
- /* 253 */ ED_UNASSIGNED, /* M-} */
- /* 254 */ ED_UNASSIGNED, /* M-~ */
- /* 255 */ ED_UNASSIGNED /* M-^? */
-};
-
-
-/* map_init():
- * Initialize and allocate the maps
- */
-protected int
-map_init(EditLine *el)
-{
-
- /*
- * Make sure those are correct before starting.
- */
-#ifdef MAP_DEBUG
- if (sizeof(el_map_emacs) != N_KEYS * sizeof(el_action_t))
- EL_ABORT((el->errfile, "Emacs map incorrect\n"));
- if (sizeof(el_map_vi_command) != N_KEYS * sizeof(el_action_t))
- EL_ABORT((el->errfile, "Vi command map incorrect\n"));
- if (sizeof(el_map_vi_insert) != N_KEYS * sizeof(el_action_t))
- EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
-#endif
-
- el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
- if (el->el_map.alt == NULL)
- return (-1);
- el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
- if (el->el_map.key == NULL)
- return (-1);
- el->el_map.emacs = el_map_emacs;
- el->el_map.vic = el_map_vi_command;
- el->el_map.vii = el_map_vi_insert;
- el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
- EL_NUM_FCNS);
- if (el->el_map.help == NULL)
- return (-1);
- (void) memcpy(el->el_map.help, help__get(),
- sizeof(el_bindings_t) * EL_NUM_FCNS);
- el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) *
- EL_NUM_FCNS);
- if (el->el_map.func == NULL)
- return (-1);
- memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS);
- el->el_map.nfunc = EL_NUM_FCNS;
-
-#ifdef VIDEFAULT
- map_init_vi(el);
-#else
- map_init_emacs(el);
-#endif /* VIDEFAULT */
- return (0);
-}
-
-
-/* map_end():
- * Free the space taken by the editor maps
- */
-protected void
-map_end(EditLine *el)
-{
-
- el_free((ptr_t) el->el_map.alt);
- el->el_map.alt = NULL;
- el_free((ptr_t) el->el_map.key);
- el->el_map.key = NULL;
- el->el_map.emacs = NULL;
- el->el_map.vic = NULL;
- el->el_map.vii = NULL;
- el_free((ptr_t) el->el_map.help);
- el->el_map.help = NULL;
- el_free((ptr_t) el->el_map.func);
- el->el_map.func = NULL;
-}
-
-
-/* map_init_nls():
- * Find all the printable keys and bind them to self insert
- */
-private void
-map_init_nls(EditLine *el)
-{
- int i;
-
- el_action_t *map = el->el_map.key;
-
- for (i = 0200; i <= 0377; i++)
- if (isprint(i))
- map[i] = ED_INSERT;
-}
-
-
-/* map_init_meta():
- * Bind all the meta keys to the appropriate ESC-<key> sequence
- */
-private void
-map_init_meta(EditLine *el)
-{
- char buf[3];
- int i;
- el_action_t *map = el->el_map.key;
- el_action_t *alt = el->el_map.alt;
-
- for (i = 0; i <= 0377 && map[i] != EM_META_NEXT; i++)
- continue;
-
- if (i > 0377) {
- for (i = 0; i <= 0377 && alt[i] != EM_META_NEXT; i++)
- continue;
- if (i > 0377) {
- i = 033;
- if (el->el_map.type == MAP_VI)
- map = alt;
- } else
- map = alt;
- }
- buf[0] = (char) i;
- buf[2] = 0;
- for (i = 0200; i <= 0377; i++)
- switch (map[i]) {
- case ED_INSERT:
- case ED_UNASSIGNED:
- case ED_SEQUENCE_LEAD_IN:
- break;
- default:
- buf[1] = i & 0177;
- key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
- break;
- }
- map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
-}
-
-
-/* map_init_vi():
- * Initialize the vi bindings
- */
-protected void
-map_init_vi(EditLine *el)
-{
- int i;
- el_action_t *key = el->el_map.key;
- el_action_t *alt = el->el_map.alt;
- const el_action_t *vii = el->el_map.vii;
- const el_action_t *vic = el->el_map.vic;
-
- el->el_map.type = MAP_VI;
- el->el_map.current = el->el_map.key;
-
- key_reset(el);
-
- for (i = 0; i < N_KEYS; i++) {
- key[i] = vii[i];
- alt[i] = vic[i];
- }
-
- map_init_meta(el);
- map_init_nls(el);
-
- tty_bind_char(el, 1);
- term_bind_arrow(el);
-}
-
-
-/* map_init_emacs():
- * Initialize the emacs bindings
- */
-protected void
-map_init_emacs(EditLine *el)
-{
- int i;
- char buf[3];
- el_action_t *key = el->el_map.key;
- el_action_t *alt = el->el_map.alt;
- const el_action_t *emacs = el->el_map.emacs;
-
- el->el_map.type = MAP_EMACS;
- el->el_map.current = el->el_map.key;
- key_reset(el);
-
- for (i = 0; i < N_KEYS; i++) {
- key[i] = emacs[i];
- alt[i] = ED_UNASSIGNED;
- }
-
- map_init_meta(el);
- map_init_nls(el);
-
- buf[0] = CONTROL('X');
- buf[1] = CONTROL('X');
- buf[2] = 0;
- key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
-
- tty_bind_char(el, 1);
- term_bind_arrow(el);
-}
-
-
-/* map_set_editor():
- * Set the editor
- */
-protected int
-map_set_editor(EditLine *el, char *editor)
-{
-
- if (strcmp(editor, "emacs") == 0) {
- map_init_emacs(el);
- return (0);
- }
- if (strcmp(editor, "vi") == 0) {
- map_init_vi(el);
- return (0);
- }
- return (-1);
-}
-
-
-/* map_get_editor():
- * Retrieve the editor
- */
-protected int
-map_get_editor(EditLine *el, const char **editor)
-{
-
- if (editor == NULL)
- return (-1);
- switch (el->el_map.type) {
- case MAP_EMACS:
- *editor = "emacs";
- return (0);
- case MAP_VI:
- *editor = "vi";
- return (0);
- }
- return (-1);
-}
-
-
-/* map_print_key():
- * Print the function description for 1 key
- */
-private void
-map_print_key(EditLine *el, el_action_t *map, const char *in)
-{
- char outbuf[EL_BUFSIZ];
- el_bindings_t *bp;
-
- if (in[0] == '\0' || in[1] == '\0') {
- (void) key__decode_str(in, outbuf, "");
- for (bp = el->el_map.help; bp->name != NULL; bp++)
- if (bp->func == map[(unsigned char) *in]) {
- (void) fprintf(el->el_outfile,
- "%s\t->\t%s\n", outbuf, bp->name);
- return;
- }
- } else
- key_print(el, in);
-}
-
-
-/* map_print_some_keys():
- * Print keys from first to last
- */
-private void
-map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
-{
- el_bindings_t *bp;
- char firstbuf[2], lastbuf[2];
- char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
-
- firstbuf[0] = first;
- firstbuf[1] = 0;
- lastbuf[0] = last;
- lastbuf[1] = 0;
- if (map[first] == ED_UNASSIGNED) {
- if (first == last)
- (void) fprintf(el->el_outfile,
- "%-15s-> is undefined\n",
- key__decode_str(firstbuf, unparsbuf, STRQQ));
- return;
- }
- for (bp = el->el_map.help; bp->name != NULL; bp++) {
- if (bp->func == map[first]) {
- if (first == last) {
- (void) fprintf(el->el_outfile, "%-15s-> %s\n",
- key__decode_str(firstbuf, unparsbuf, STRQQ),
- bp->name);
- } else {
- (void) fprintf(el->el_outfile,
- "%-4s to %-7s-> %s\n",
- key__decode_str(firstbuf, unparsbuf, STRQQ),
- key__decode_str(lastbuf, extrabuf, STRQQ),
- bp->name);
- }
- return;
- }
- }
-#ifdef MAP_DEBUG
- if (map == el->el_map.key) {
- (void) fprintf(el->el_outfile,
- "BUG!!! %s isn't bound to anything.\n",
- key__decode_str(firstbuf, unparsbuf, STRQQ));
- (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
- first, el->el_map.key[first]);
- } else {
- (void) fprintf(el->el_outfile,
- "BUG!!! %s isn't bound to anything.\n",
- key__decode_str(firstbuf, unparsbuf, STRQQ));
- (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n",
- first, el->el_map.alt[first]);
- }
-#endif
- EL_ABORT((el->el_errfile, "Error printing keys\n"));
-}
-
-
-/* map_print_all_keys():
- * Print the function description for all keys.
- */
-private void
-map_print_all_keys(EditLine *el)
-{
- int prev, i;
-
- (void) fprintf(el->el_outfile, "Standard key bindings\n");
- prev = 0;
- for (i = 0; i < N_KEYS; i++) {
- if (el->el_map.key[prev] == el->el_map.key[i])
- continue;
- map_print_some_keys(el, el->el_map.key, prev, i - 1);
- prev = i;
- }
- map_print_some_keys(el, el->el_map.key, prev, i - 1);
-
- (void) fprintf(el->el_outfile, "Alternative key bindings\n");
- prev = 0;
- for (i = 0; i < N_KEYS; i++) {
- if (el->el_map.alt[prev] == el->el_map.alt[i])
- continue;
- map_print_some_keys(el, el->el_map.alt, prev, i - 1);
- prev = i;
- }
- map_print_some_keys(el, el->el_map.alt, prev, i - 1);
-
- (void) fprintf(el->el_outfile, "Multi-character bindings\n");
- key_print(el, "");
- (void) fprintf(el->el_outfile, "Arrow key bindings\n");
- term_print_arrow(el, "");
-}
-
-
-/* map_bind():
- * Add/remove/change bindings
- */
-protected int
-map_bind(EditLine *el, int argc, const char **argv)
-{
- el_action_t *map;
- int ntype, rem;
- const char *p;
- char inbuf[EL_BUFSIZ];
- char outbuf[EL_BUFSIZ];
- const char *in = NULL;
- char *out = NULL;
- el_bindings_t *bp;
- int cmd;
- int key;
-
- if (argv == NULL)
- return (-1);
-
- map = el->el_map.key;
- ntype = XK_CMD;
- key = rem = 0;
- for (argc = 1; (p = argv[argc]) != NULL; argc++)
- if (p[0] == '-')
- switch (p[1]) {
- case 'a':
- map = el->el_map.alt;
- break;
-
- case 's':
- ntype = XK_STR;
- break;
-#ifdef notyet
- case 'c':
- ntype = XK_EXE;
- break;
-#endif
- case 'k':
- key = 1;
- break;
-
- case 'r':
- rem = 1;
- break;
-
- case 'v':
- map_init_vi(el);
- return (0);
-
- case 'e':
- map_init_emacs(el);
- return (0);
-
- case 'l':
- for (bp = el->el_map.help; bp->name != NULL;
- bp++)
- (void) fprintf(el->el_outfile,
- "%s\n\t%s\n",
- bp->name, bp->description);
- return (0);
- default:
- (void) fprintf(el->el_errfile,
- "%s: Invalid switch `%c'.\n",
- argv[0], p[1]);
- }
- else
- break;
-
- if (argv[argc] == NULL) {
- map_print_all_keys(el);
- return (0);
- }
- if (key)
- in = argv[argc++];
- else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
- (void) fprintf(el->el_errfile,
- "%s: Invalid \\ or ^ in instring.\n",
- argv[0]);
- return (-1);
- }
- if (rem) {
- if (key) {
- (void) term_clear_arrow(el, in);
- return (-1);
- }
- if (in[1])
- (void) key_delete(el, in);
- else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
- (void) key_delete(el, in);
- else
- map[(unsigned char) *in] = ED_UNASSIGNED;
- return (0);
- }
- if (argv[argc] == NULL) {
- if (key)
- term_print_arrow(el, in);
- else
- map_print_key(el, map, in);
- return (0);
- }
-#ifdef notyet
- if (argv[argc + 1] != NULL) {
- bindkey_usage();
- return (-1);
- }
-#endif
-
- switch (ntype) {
- case XK_STR:
- case XK_EXE:
- if ((out = parse__string(outbuf, argv[argc])) == NULL) {
- (void) fprintf(el->el_errfile,
- "%s: Invalid \\ or ^ in outstring.\n", argv[0]);
- return (-1);
- }
- if (key)
- term_set_arrow(el, in, key_map_str(el, out), ntype);
- else
- key_add(el, in, key_map_str(el, out), ntype);
- map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
- break;
-
- case XK_CMD:
- if ((cmd = parse_cmd(el, argv[argc])) == -1) {
- (void) fprintf(el->el_errfile,
- "%s: Invalid command `%s'.\n", argv[0], argv[argc]);
- return (-1);
- }
- if (key)
- term_set_arrow(el, in, key_map_str(el, out), ntype);
- else {
- if (in[1]) {
- key_add(el, in, key_map_cmd(el, cmd), ntype);
- map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
- } else {
- key_clear(el, map, in);
- map[(unsigned char) *in] = cmd;
- }
- }
- break;
-
- default:
- EL_ABORT((el->el_errfile, "Bad XK_ type\n", ntype));
- break;
- }
- return (0);
-}
-
-
-/* map_addfunc():
- * add a user defined function
- */
-protected int
-map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func)
-{
- void *p;
- int nf = el->el_map.nfunc + 2;
-
- if (name == NULL || help == NULL || func == NULL)
- return (-1);
-
- if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
- return (-1);
- el->el_map.func = (el_func_t *) p;
- if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)))
- == NULL)
- return (-1);
- el->el_map.help = (el_bindings_t *) p;
-
- nf = el->el_map.nfunc;
- el->el_map.func[nf] = func;
-
- el->el_map.help[nf].name = name;
- el->el_map.help[nf].func = nf;
- el->el_map.help[nf].description = help;
- el->el_map.help[++nf].name = NULL;
- el->el_map.nfunc++;
-
- return (0);
-}
diff --git a/1.4/main/editline/map.h b/1.4/main/editline/map.h
deleted file mode 100644
index 3c9948ccf..000000000
--- a/1.4/main/editline/map.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $NetBSD: map.h,v 1.7 2002/03/18 16:00:56 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)map.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.map.h: Editor maps
- */
-#ifndef _h_el_map
-#define _h_el_map
-
-typedef struct el_bindings_t { /* for the "bind" shell command */
- const char *name; /* function name for bind command */
- int func; /* function numeric value */
- const char *description; /* description of function */
-} el_bindings_t;
-
-
-typedef struct el_map_t {
- el_action_t *alt; /* The current alternate key map */
- el_action_t *key; /* The current normal key map */
- el_action_t *current; /* The keymap we are using */
- const el_action_t *emacs; /* The default emacs key map */
- const el_action_t *vic; /* The vi command mode key map */
- const el_action_t *vii; /* The vi insert mode key map */
- int type; /* Emacs or vi */
- el_bindings_t *help; /* The help for the editor functions */
- el_func_t *func; /* List of available functions */
- int nfunc; /* The number of functions/help items */
-} el_map_t;
-
-#define MAP_EMACS 0
-#define MAP_VI 1
-
-protected int map_bind(EditLine *, int, const char **);
-protected int map_init(EditLine *);
-protected void map_end(EditLine *);
-protected void map_init_vi(EditLine *);
-protected void map_init_emacs(EditLine *);
-protected int map_set_editor(EditLine *, char *);
-protected int map_get_editor(EditLine *, const char **);
-protected int map_addfunc(EditLine *, const char *, const char *, el_func_t);
-
-#endif /* _h_el_map */
diff --git a/1.4/main/editline/np/fgetln.c b/1.4/main/editline/np/fgetln.c
deleted file mode 100644
index 93da9914d..000000000
--- a/1.4/main/editline/np/fgetln.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* $NetBSD: fgetln.c,v 1.1.1.1 1999/04/12 07:43:21 crooksa Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Christos Zoulas.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-char *
-fgetln(fp, len)
- FILE *fp;
- size_t *len;
-{
- static char *buf = NULL;
- static size_t bufsiz = 0;
- char *ptr;
-
-
- if (buf == NULL) {
- bufsiz = BUFSIZ;
- if ((buf = malloc(bufsiz)) == NULL)
- return NULL;
- }
-
- if (fgets(buf, bufsiz, fp) == NULL)
- return NULL;
- *len = 0;
-
- while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
- size_t nbufsiz = bufsiz + BUFSIZ;
- char *nbuf = realloc(buf, nbufsiz);
-
- if (nbuf == NULL) {
- int oerrno = errno;
- free(buf);
- errno = oerrno;
- buf = NULL;
- return NULL;
- } else
- buf = nbuf;
-
- *len = bufsiz;
- if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
- return buf;
-
- bufsiz = nbufsiz;
- }
-
- *len = (ptr - buf) + 1;
- return buf;
-}
diff --git a/1.4/main/editline/np/strlcat.c b/1.4/main/editline/np/strlcat.c
deleted file mode 100644
index 6c9f1e92d..000000000
--- a/1.4/main/editline/np/strlcat.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $";
-#endif /* LIBC_SCCS and not lint */
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD: src/lib/libc/string/strlcat.c,v 1.2.4.2 2001/07/09 23:30:06 obrien Exp $";
-#endif
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(initial dst) + strlen(src); if retval >= siz,
- * truncation occurred.
- */
-size_t strlcat(dst, src, siz)
- char *dst;
- const char *src;
- size_t siz;
-{
- register char *d = dst;
- register const char *s = src;
- register size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return(dlen + strlen(s));
- while (*s != '\0') {
- if (n != 1) {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return(dlen + (s - src)); /* count does not include NUL */
-}
diff --git a/1.4/main/editline/np/strlcpy.c b/1.4/main/editline/np/strlcpy.c
deleted file mode 100644
index 1f154bcf2..000000000
--- a/1.4/main/editline/np/strlcpy.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $";
-#endif
-#endif /* LIBC_SCCS and not lint */
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.2.4.1 2001/07/09 23:30:06 obrien Exp $";
-#endif
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t strlcpy(dst, src, siz)
- char *dst;
- const char *src;
- size_t siz;
-{
- register char *d = dst;
- register const char *s = src;
- register size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0) {
- do {
- if ((*d++ = *s++) == 0)
- break;
- } while (--n != 0);
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
-}
diff --git a/1.4/main/editline/np/unvis.c b/1.4/main/editline/np/unvis.c
deleted file mode 100644
index f43c4c749..000000000
--- a/1.4/main/editline/np/unvis.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/* $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */
-
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#define __LIBC12_SOURCE__
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include "np/vis.h"
-
-#ifdef __weak_alias
-__weak_alias(strunvis,_strunvis)
-__weak_alias(unvis,_unvis)
-#endif
-
-#ifdef __warn_references
-__warn_references(unvis,
- "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
-#endif
-
-#if !HAVE_VIS_H
-/*
- * decode driven by state machine
- */
-#define S_GROUND 0 /* haven't seen escape char */
-#define S_START 1 /* start decoding special sequence */
-#define S_META 2 /* metachar started (M) */
-#define S_META1 3 /* metachar more, regular char (-) */
-#define S_CTRL 4 /* control char started (^) */
-#define S_OCTAL2 5 /* octal digit 2 */
-#define S_OCTAL3 6 /* octal digit 3 */
-#define S_HEX1 7 /* hex digit */
-#define S_HEX2 8 /* hex digit 2 */
-
-#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
-#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
-
-int
-unvis(cp, c, astate, flag)
- char *cp;
- int c;
- int *astate, flag;
-{
- return __unvis13(cp, (int)c, astate, flag);
-}
-
-/*
- * unvis - decode characters previously encoded by vis
- */
-int
-__unvis13(cp, c, astate, flag)
- char *cp;
- int c;
- int *astate, flag;
-{
-
- _DIAGASSERT(cp != NULL);
- _DIAGASSERT(astate != NULL);
-
- if (flag & UNVIS_END) {
- if (*astate == S_OCTAL2 || *astate == S_OCTAL3
- || *astate == S_HEX2) {
- *astate = S_GROUND;
- return (UNVIS_VALID);
- }
- return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
- }
-
- switch (*astate) {
-
- case S_GROUND:
- *cp = 0;
- if (c == '\\') {
- *astate = S_START;
- return (0);
- }
- if ((flag & VIS_HTTPSTYLE) && c == '%') {
- *astate = S_HEX1;
- return (0);
- }
- *cp = c;
- return (UNVIS_VALID);
-
- case S_START:
- switch(c) {
- case '\\':
- *cp = c;
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- *cp = (c - '0');
- *astate = S_OCTAL2;
- return (0);
- case 'M':
- *cp = (char)0200;
- *astate = S_META;
- return (0);
- case '^':
- *astate = S_CTRL;
- return (0);
- case 'n':
- *cp = '\n';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 'r':
- *cp = '\r';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 'b':
- *cp = '\b';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 'a':
- *cp = '\007';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 'v':
- *cp = '\v';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 't':
- *cp = '\t';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 'f':
- *cp = '\f';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 's':
- *cp = ' ';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case 'E':
- *cp = '\033';
- *astate = S_GROUND;
- return (UNVIS_VALID);
- case '\n':
- /*
- * hidden newline
- */
- *astate = S_GROUND;
- return (UNVIS_NOCHAR);
- case '$':
- /*
- * hidden marker
- */
- *astate = S_GROUND;
- return (UNVIS_NOCHAR);
- }
- *astate = S_GROUND;
- return (UNVIS_SYNBAD);
-
- case S_META:
- if (c == '-')
- *astate = S_META1;
- else if (c == '^')
- *astate = S_CTRL;
- else {
- *astate = S_GROUND;
- return (UNVIS_SYNBAD);
- }
- return (0);
-
- case S_META1:
- *astate = S_GROUND;
- *cp |= c;
- return (UNVIS_VALID);
-
- case S_CTRL:
- if (c == '?')
- *cp |= 0177;
- else
- *cp |= c & 037;
- *astate = S_GROUND;
- return (UNVIS_VALID);
-
- case S_OCTAL2: /* second possible octal digit */
- if (isoctal(c)) {
- /*
- * yes - and maybe a third
- */
- *cp = (*cp << 3) + (c - '0');
- *astate = S_OCTAL3;
- return (0);
- }
- /*
- * no - done with current sequence, push back passed char
- */
- *astate = S_GROUND;
- return (UNVIS_VALIDPUSH);
-
- case S_OCTAL3: /* third possible octal digit */
- *astate = S_GROUND;
- if (isoctal(c)) {
- *cp = (*cp << 3) + (c - '0');
- return (UNVIS_VALID);
- }
- /*
- * we were done, push back passed char
- */
- return (UNVIS_VALIDPUSH);
- case S_HEX1:
- if (isxdigit(c)) {
- *cp = xtod(c);
- *astate = S_HEX2;
- return (0);
- }
- /*
- * no - done with current sequence, push back passed char
- */
- *astate = S_GROUND;
- return (UNVIS_VALIDPUSH);
- case S_HEX2:
- *astate = S_GROUND;
- if (isxdigit(c)) {
- *cp = xtod(c) | (*cp << 4);
- return (UNVIS_VALID);
- }
- return (UNVIS_VALIDPUSH);
- default:
- /*
- * decoder in unknown state - (probably uninitialized)
- */
- *astate = S_GROUND;
- return (UNVIS_SYNBAD);
- }
-}
-
-/*
- * strunvis - decode src into dst
- *
- * Number of chars decoded into dst is returned, -1 on error.
- * Dst is null terminated.
- */
-
-int
-strunvisx(dst, src, flag)
- char *dst;
- const char *src;
- int flag;
-{
- char c;
- char *start = dst;
- int state = 0;
-
- _DIAGASSERT(src != NULL);
- _DIAGASSERT(dst != NULL);
-
- while ((c = *src++) != '\0') {
- again:
- switch (__unvis13(dst, c, &state, flag)) {
- case UNVIS_VALID:
- dst++;
- break;
- case UNVIS_VALIDPUSH:
- dst++;
- goto again;
- case 0:
- case UNVIS_NOCHAR:
- break;
- default:
- return (-1);
- }
- }
- if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID)
- dst++;
- *dst = '\0';
- return (dst - start);
-}
-
-int
-strunvis(dst, src)
- char *dst;
- const char *src;
-{
- return strunvisx(dst, src, 0);
-}
-#endif
diff --git a/1.4/main/editline/np/vis.c b/1.4/main/editline/np/vis.c
deleted file mode 100644
index 7d9117faa..000000000
--- a/1.4/main/editline/np/vis.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */
-
-/*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $");
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include "np/vis.h"
-#include <stdlib.h>
-
-#ifdef __weak_alias
-__weak_alias(strsvis,_strsvis)
-__weak_alias(strsvisx,_strsvisx)
-__weak_alias(strvis,_strvis)
-__weak_alias(strvisx,_strvisx)
-__weak_alias(svis,_svis)
-__weak_alias(vis,_vis)
-#endif
-
-#ifndef HAVE_VIS_H
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#undef BELL
-#if defined(__STDC__)
-#define BELL '\a'
-#else
-#define BELL '\007'
-#endif
-
-#ifdef SOLARIS
-#include <alloca.h>
-#endif
-
-#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
-#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
-#define issafe(c) (c == '\b' || c == BELL || c == '\r')
-#define xtoa(c) "0123456789abcdef"[c]
-
-#define MAXEXTRAS 5
-
-
-#define MAKEEXTRALIST(flag, extra, orig) \
-do { \
- const char *o = orig; \
- char *e; \
- while (*o++) \
- continue; \
- extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \
- for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
- continue; \
- e--; \
- if (flag & VIS_SP) *e++ = ' '; \
- if (flag & VIS_TAB) *e++ = '\t'; \
- if (flag & VIS_NL) *e++ = '\n'; \
- if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
- *e = '\0'; \
-} while (/*CONSTCOND*/0)
-
-
-/*
- * This is HVIS, the macro of vis used to HTTP style (RFC 1808)
- */
-#define HVIS(dst, c, flag, nextc, extra) \
-do \
- if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
- *dst++ = '%'; \
- *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \
- *dst++ = xtoa((unsigned int)c & 0xf); \
- } else { \
- SVIS(dst, c, flag, nextc, extra); \
- } \
-while (/*CONSTCOND*/0)
-
-/*
- * This is SVIS, the central macro of vis.
- * dst: Pointer to the destination buffer
- * c: Character to encode
- * flag: Flag word
- * nextc: The character following 'c'
- * extra: Pointer to the list of extra characters to be
- * backslash-protected.
- */
-#define SVIS(dst, c, flag, nextc, extra) \
-do { \
- int isextra, isc; \
- isextra = strchr(extra, c) != NULL; \
- if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
- ((flag & VIS_SAFE) && issafe(c)))) { \
- *dst++ = c; \
- break; \
- } \
- isc = 0; \
- if (flag & VIS_CSTYLE) { \
- switch (c) { \
- case '\n': \
- isc = 1; *dst++ = '\\'; *dst++ = 'n'; \
- break; \
- case '\r': \
- isc = 1; *dst++ = '\\'; *dst++ = 'r'; \
- break; \
- case '\b': \
- isc = 1; *dst++ = '\\'; *dst++ = 'b'; \
- break; \
- case BELL: \
- isc = 1; *dst++ = '\\'; *dst++ = 'a'; \
- break; \
- case '\v': \
- isc = 1; *dst++ = '\\'; *dst++ = 'v'; \
- break; \
- case '\t': \
- isc = 1; *dst++ = '\\'; *dst++ = 't'; \
- break; \
- case '\f': \
- isc = 1; *dst++ = '\\'; *dst++ = 'f'; \
- break; \
- case ' ': \
- isc = 1; *dst++ = '\\'; *dst++ = 's'; \
- break; \
- case '\0': \
- isc = 1; *dst++ = '\\'; *dst++ = '0'; \
- if (isoctal(nextc)) { \
- *dst++ = '0'; \
- *dst++ = '0'; \
- } \
- } \
- } \
- if (isc) break; \
- if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
- *dst++ = '\\'; \
- *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
- *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
- *dst++ = (c & 07) + '0'; \
- } else { \
- if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
- if (c & 0200) { \
- c &= 0177; *dst++ = 'M'; \
- } \
- if (iscntrl(c)) { \
- *dst++ = '^'; \
- if (c == 0177) \
- *dst++ = '?'; \
- else \
- *dst++ = c + '@'; \
- } else { \
- *dst++ = '-'; *dst++ = c; \
- } \
- } \
-} while (/*CONSTCOND*/0)
-
-
-/*
- * svis - visually encode characters, also encoding the characters
- * pointed to by `extra'
- */
-char *
-svis(dst, c, flag, nextc, extra)
- char *dst;
- int c, flag, nextc;
- const char *extra;
-{
- char *nextra;
- _DIAGASSERT(dst != NULL);
- _DIAGASSERT(extra != NULL);
- MAKEEXTRALIST(flag, nextra, extra);
- if (flag & VIS_HTTPSTYLE)
- HVIS(dst, c, flag, nextc, nextra);
- else
- SVIS(dst, c, flag, nextc, nextra);
- *dst = '\0';
- return(dst);
-}
-
-
-/*
- * strsvis, strsvisx - visually encode characters from src into dst
- *
- * Extra is a pointer to a \0-terminated list of characters to
- * be encoded, too. These functions are useful e. g. to
- * encode strings in such a way so that they are not interpreted
- * by a shell.
- *
- * Dst must be 4 times the size of src to account for possible
- * expansion. The length of dst, not including the trailing NULL,
- * is returned.
- *
- * Strsvisx encodes exactly len bytes from src into dst.
- * This is useful for encoding a block of data.
- */
-int
-strsvis(dst, src, flag, extra)
- char *dst;
- const char *src;
- int flag;
- const char *extra;
-{
- char c;
- char *start;
- char *nextra;
-
- _DIAGASSERT(dst != NULL);
- _DIAGASSERT(src != NULL);
- _DIAGASSERT(extra != NULL);
- MAKEEXTRALIST(flag, nextra, extra);
- if (flag & VIS_HTTPSTYLE) {
- for (start = dst; (c = *src++) != '\0'; /* empty */)
- HVIS(dst, c, flag, *src, nextra);
- } else {
- for (start = dst; (c = *src++) != '\0'; /* empty */)
- SVIS(dst, c, flag, *src, nextra);
- }
- *dst = '\0';
- return (dst - start);
-}
-
-
-int
-strsvisx(dst, src, len, flag, extra)
- char *dst;
- const char *src;
- size_t len;
- int flag;
- const char *extra;
-{
- char c;
- char *start;
- char *nextra;
-
- _DIAGASSERT(dst != NULL);
- _DIAGASSERT(src != NULL);
- _DIAGASSERT(extra != NULL);
- MAKEEXTRALIST(flag, nextra, extra);
-
- if (flag & VIS_HTTPSTYLE) {
- for (start = dst; len > 0; len--) {
- c = *src++;
- HVIS(dst, c, flag, len ? *src : '\0', nextra);
- }
- } else {
- for (start = dst; len > 0; len--) {
- c = *src++;
- SVIS(dst, c, flag, len ? *src : '\0', nextra);
- }
- }
- *dst = '\0';
- return (dst - start);
-}
-
-
-/*
- * vis - visually encode characters
- */
-char *
-vis(dst, c, flag, nextc)
- char *dst;
- int c, flag, nextc;
-
-{
- char *extra;
-
- _DIAGASSERT(dst != NULL);
-
- MAKEEXTRALIST(flag, extra, "");
- if (flag & VIS_HTTPSTYLE)
- HVIS(dst, c, flag, nextc, extra);
- else
- SVIS(dst, c, flag, nextc, extra);
- *dst = '\0';
- return (dst);
-}
-
-
-/*
- * strvis, strvisx - visually encode characters from src into dst
- *
- * Dst must be 4 times the size of src to account for possible
- * expansion. The length of dst, not including the trailing NULL,
- * is returned.
- *
- * Strvisx encodes exactly len bytes from src into dst.
- * This is useful for encoding a block of data.
- */
-int
-strvis(dst, src, flag)
- char *dst;
- const char *src;
- int flag;
-{
- char *extra;
-
- MAKEEXTRALIST(flag, extra, "");
- return (strsvis(dst, src, flag, extra));
-}
-
-
-int
-strvisx(dst, src, len, flag)
- char *dst;
- const char *src;
- size_t len;
- int flag;
-{
- char *extra;
-
- MAKEEXTRALIST(flag, extra, "");
- return (strsvisx(dst, src, len, flag, extra));
-}
-#endif
diff --git a/1.4/main/editline/np/vis.h b/1.4/main/editline/np/vis.h
deleted file mode 100644
index 0739c1dfa..000000000
--- a/1.4/main/editline/np/vis.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* $NetBSD: vis.h,v 1.12 2002/03/23 17:39:05 christos Exp $ */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)vis.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _VIS_H_
-#define _VIS_H_
-
-/*
- * to select alternate encoding format
- */
-#define VIS_OCTAL 0x01 /* use octal \ddd format */
-#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */
-
-/*
- * to alter set of characters encoded (default is to encode all
- * non-graphic except space, tab, and newline).
- */
-#define VIS_SP 0x04 /* also encode space */
-#define VIS_TAB 0x08 /* also encode tab */
-#define VIS_NL 0x10 /* also encode newline */
-#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
-#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
-
-/*
- * other
- */
-#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
-#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
-
-/*
- * unvis return codes
- */
-#define UNVIS_VALID 1 /* character valid */
-#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */
-#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */
-#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */
-#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */
-
-/*
- * unvis flags
- */
-#define UNVIS_END 1 /* no more characters */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-char *vis __P((char *, int, int, int));
-char *svis __P((char *, int, int, int, const char *));
-int strvis __P((char *, const char *, int));
-int strsvis __P((char *, const char *, int, const char *));
-int strvisx __P((char *, const char *, size_t, int));
-int strsvisx __P((char *, const char *, size_t, int, const char *));
-int strunvis __P((char *, const char *));
-int strunvisx __P((char *, const char *, int));
-#ifdef __LIBC12_SOURCE__
-int unvis __P((char *, int, int *, int));
-int __unvis13 __P((char *, int, int *, int));
-#else
-int unvis __P((char *, int, int *, int)) __RENAME(__unvis13);
-#endif
-__END_DECLS
-
-#endif /* !_VIS_H_ */
diff --git a/1.4/main/editline/parse.c b/1.4/main/editline/parse.c
deleted file mode 100644
index 0a34f0b15..000000000
--- a/1.4/main/editline/parse.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* $NetBSD: parse.c,v 1.15 2002/03/18 16:00:56 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: parse.c,v 1.15 2002/03/18 16:00:56 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * parse.c: parse an editline extended command
- *
- * commands are:
- *
- * bind
- * echotc
- * edit
- * gettc
- * history
- * settc
- * setty
- */
-#include "el.h"
-#include "tokenizer.h"
-#include <stdlib.h>
-
-private const struct {
- const char *name;
- int (*func)(EditLine *, int, const char **);
-} cmds[] = {
- { "bind", map_bind },
- { "echotc", term_echotc },
- { "edit", el_editmode },
- { "history", hist_list },
- { "telltc", term_telltc },
- { "settc", term_settc },
- { "setty", tty_stty },
- { NULL, NULL }
-};
-
-
-/* parse_line():
- * Parse a line and dispatch it
- */
-protected int
-parse_line(EditLine *el, const char *line)
-{
- const char **argv;
- int argc;
- Tokenizer *tok;
-
- tok = tok_init(NULL);
- tok_line(tok, line, &argc, &argv);
- argc = el_parse(el, argc, argv);
- tok_end(tok);
- return (argc);
-}
-
-
-/* el_parse():
- * Command dispatcher
- */
-public int
-el_parse(EditLine *el, int argc, const char *argv[])
-{
- const char *ptr;
- int i;
-
- if (argc < 1)
- return (-1);
- ptr = strchr(argv[0], ':');
- if (ptr != NULL) {
- char *tprog;
- size_t l;
-
- if (ptr == argv[0])
- return (0);
- l = ptr - argv[0] - 1;
- tprog = (char *) el_malloc(l + 1);
- if (tprog == NULL)
- return (0);
- (void) strncpy(tprog, argv[0], l);
- tprog[l] = '\0';
- ptr++;
- l = el_match(el->el_prog, tprog);
- el_free(tprog);
- if (!l)
- return (0);
- } else
- ptr = argv[0];
-
- for (i = 0; cmds[i].name != NULL; i++)
- if (strcmp(cmds[i].name, ptr) == 0) {
- i = (*cmds[i].func) (el, argc, argv);
- return (-i);
- }
- return (-1);
-}
-
-
-/* parse__escape():
- * Parse a string of the form ^<char> \<odigit> \<char> and return
- * the appropriate character or -1 if the escape is not valid
- */
-protected int
-parse__escape(const char **const ptr)
-{
- const char *p;
- int c;
-
- p = *ptr;
-
- if (p[1] == 0)
- return (-1);
-
- if (*p == '\\') {
- p++;
- switch (*p) {
- case 'a':
- c = '\007'; /* Bell */
- break;
- case 'b':
- c = '\010'; /* Backspace */
- break;
- case 't':
- c = '\011'; /* Horizontal Tab */
- break;
- case 'n':
- c = '\012'; /* New Line */
- break;
- case 'v':
- c = '\013'; /* Vertical Tab */
- break;
- case 'f':
- c = '\014'; /* Form Feed */
- break;
- case 'r':
- c = '\015'; /* Carriage Return */
- break;
- case 'e':
- c = '\033'; /* Escape */
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- int cnt, ch;
-
- for (cnt = 0, c = 0; cnt < 3; cnt++) {
- ch = *p++;
- if (ch < '0' || ch > '7') {
- p--;
- break;
- }
- c = (c << 3) | (ch - '0');
- }
- if ((c & 0xffffff00) != 0)
- return (-1);
- --p;
- break;
- }
- default:
- c = *p;
- break;
- }
- } else if (*p == '^' && isalpha((unsigned char) p[1])) {
- p++;
- c = (*p == '?') ? '\177' : (*p & 0237);
- } else
- c = *p;
- *ptr = ++p;
- return (c);
-}
-/* parse__string():
- * Parse the escapes from in and put the raw string out
- */
-protected char *
-parse__string(char *out, const char *in)
-{
- char *rv = out;
- int n;
-
- for (;;)
- switch (*in) {
- case '\0':
- *out = '\0';
- return (rv);
-
- case '\\':
- case '^':
- if ((n = parse__escape(&in)) == -1)
- return (NULL);
- *out++ = n;
- break;
-
- default:
- *out++ = *in++;
- break;
- }
-}
-
-
-/* parse_cmd():
- * Return the command number for the command string given
- * or -1 if one is not found
- */
-protected int
-parse_cmd(EditLine *el, const char *cmd)
-{
- el_bindings_t *b;
-
- for (b = el->el_map.help; b->name != NULL; b++)
- if (strcmp(b->name, cmd) == 0)
- return (b->func);
- return (-1);
-}
diff --git a/1.4/main/editline/parse.h b/1.4/main/editline/parse.h
deleted file mode 100644
index 4aaef2f83..000000000
--- a/1.4/main/editline/parse.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* $NetBSD: parse.h,v 1.4 2000/09/04 22:06:31 lukem Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)parse.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.parse.h: Parser functions
- */
-#ifndef _h_el_parse
-#define _h_el_parse
-
-protected int parse_line(EditLine *, const char *);
-protected int parse__escape(const char ** const);
-protected char *parse__string(char *, const char *);
-protected int parse_cmd(EditLine *, const char *);
-
-#endif /* _h_el_parse */
diff --git a/1.4/main/editline/prompt.c b/1.4/main/editline/prompt.c
deleted file mode 100644
index 5c069e17a..000000000
--- a/1.4/main/editline/prompt.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* $NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * prompt.c: Prompt printing functions
- */
-#include <stdio.h>
-#include "el.h"
-
-private char *prompt_default(EditLine *);
-private char *prompt_default_r(EditLine *);
-
-/* prompt_default():
- * Just a default prompt, in case the user did not provide one
- */
-private char *
-/*ARGSUSED*/
-prompt_default(EditLine *el)
-{
- static char a[3] = {'?', ' ', '\0'};
-
- return (a);
-}
-
-
-/* prompt_default_r():
- * Just a default rprompt, in case the user did not provide one
- */
-private char *
-/*ARGSUSED*/
-prompt_default_r(EditLine *el)
-{
- static char a[1] = {'\0'};
-
- return (a);
-}
-
-
-/* prompt_print():
- * Print the prompt and update the prompt position.
- * We use an array of integers in case we want to pass
- * literal escape sequences in the prompt and we want a
- * bit to flag them
- */
-protected void
-prompt_print(EditLine *el, int op)
-{
- el_prompt_t *elp;
- char *p;
-
- if (op == EL_PROMPT)
- elp = &el->el_prompt;
- else
- elp = &el->el_rprompt;
- p = (elp->p_func) (el);
- while (*p)
- re_putc(el, *p++, 1);
-
- elp->p_pos.v = el->el_refresh.r_cursor.v;
- elp->p_pos.h = el->el_refresh.r_cursor.h;
-}
-
-
-/* prompt_init():
- * Initialize the prompt stuff
- */
-protected int
-prompt_init(EditLine *el)
-{
-
- el->el_prompt.p_func = prompt_default;
- el->el_prompt.p_pos.v = 0;
- el->el_prompt.p_pos.h = 0;
- el->el_rprompt.p_func = prompt_default_r;
- el->el_rprompt.p_pos.v = 0;
- el->el_rprompt.p_pos.h = 0;
- return (0);
-}
-
-
-/* prompt_end():
- * Clean up the prompt stuff
- */
-protected void
-/*ARGSUSED*/
-prompt_end(EditLine *el)
-{
-}
-
-
-/* prompt_set():
- * Install a prompt printing function
- */
-protected int
-prompt_set(EditLine *el, el_pfunc_t prf, int op)
-{
- el_prompt_t *p;
-
- if (op == EL_PROMPT)
- p = &el->el_prompt;
- else
- p = &el->el_rprompt;
- if (prf == NULL) {
- if (op == EL_PROMPT)
- p->p_func = prompt_default;
- else
- p->p_func = prompt_default_r;
- } else
- p->p_func = prf;
- p->p_pos.v = 0;
- p->p_pos.h = 0;
- return (0);
-}
-
-
-/* prompt_get():
- * Retrieve the prompt printing function
- */
-protected int
-prompt_get(EditLine *el, el_pfunc_t *prf, int op)
-{
-
- if (prf == NULL)
- return (-1);
- if (op == EL_PROMPT)
- *prf = el->el_prompt.p_func;
- else
- *prf = el->el_rprompt.p_func;
- return (0);
-}
diff --git a/1.4/main/editline/prompt.h b/1.4/main/editline/prompt.h
deleted file mode 100644
index 08810e22a..000000000
--- a/1.4/main/editline/prompt.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $NetBSD: prompt.h,v 1.5 2000/09/04 22:06:31 lukem Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)prompt.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.prompt.h: Prompt printing stuff
- */
-#ifndef _h_el_prompt
-#define _h_el_prompt
-
-#include "histedit.h"
-
-typedef char * (*el_pfunc_t)(EditLine*);
-
-typedef struct el_prompt_t {
- el_pfunc_t p_func; /* Function to return the prompt */
- coord_t p_pos; /* position in the line after prompt */
-} el_prompt_t;
-
-protected void prompt_print(EditLine *, int);
-protected int prompt_set(EditLine *, el_pfunc_t, int);
-protected int prompt_get(EditLine *, el_pfunc_t *, int);
-protected int prompt_init(EditLine *);
-protected void prompt_end(EditLine *);
-
-#endif /* _h_el_prompt */
diff --git a/1.4/main/editline/read.c b/1.4/main/editline/read.c
deleted file mode 100644
index ccd0a06e5..000000000
--- a/1.4/main/editline/read.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/* $NetBSD: read.c,v 1.21 2002/03/18 16:00:57 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: read.c,v 1.21 2002/03/18 16:00:57 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * read.c: Clean this junk up! This is horrible code.
- * Terminal read functions
- */
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "el.h"
-
-#define OKCMD -1
-
-private int read__fixio(int, int);
-private int read_preread(EditLine *);
-private int read_char(EditLine *, char *);
-private int read_getcmd(EditLine *, el_action_t *, char *);
-
-/* read_init():
- * Initialize the read stuff
- */
-protected int
-read_init(EditLine *el)
-{
- /* builtin read_char */
- el->el_read.read_char = read_char;
- return 0;
-}
-
-
-/* el_read_setfn():
- * Set the read char function to the one provided.
- * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
- */
-protected int
-el_read_setfn(EditLine *el, el_rfunc_t rc)
-{
- el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
- return 0;
-}
-
-
-/* el_read_getfn():
- * return the current read char function, or EL_BUILTIN_GETCFN
- * if it is the default one
- */
-protected el_rfunc_t
-el_read_getfn(EditLine *el)
-{
- return (el->el_read.read_char == read_char) ?
- EL_BUILTIN_GETCFN : el->el_read.read_char;
-}
-
-
-#ifdef DEBUG_EDIT
-private void
-read_debug(EditLine *el)
-{
-
- if (el->el_line.cursor > el->el_line.lastchar)
- (void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
- if (el->el_line.cursor < el->el_line.buffer)
- (void) fprintf(el->el_errfile, "cursor < buffer\r\n");
- if (el->el_line.cursor > el->el_line.limit)
- (void) fprintf(el->el_errfile, "cursor > limit\r\n");
- if (el->el_line.lastchar > el->el_line.limit)
- (void) fprintf(el->el_errfile, "lastchar > limit\r\n");
- if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
- (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
-}
-#endif /* DEBUG_EDIT */
-
-
-/* read__fixio():
- * Try to recover from a read error
- */
-/* ARGSUSED */
-private int
-read__fixio(int fd, int e)
-{
-
- switch (e) {
- case -1: /* Make sure that the code is reachable */
-
-#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
-#ifndef TRY_AGAIN
-#define TRY_AGAIN
-#endif
-#endif /* EWOULDBLOCK */
-
-#if defined(POSIX) && defined(EAGAIN)
-#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
- case EAGAIN:
-#ifndef TRY_AGAIN
-#define TRY_AGAIN
-#endif
-#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
-#endif /* POSIX && EAGAIN */
-
- e = 0;
-#ifdef TRY_AGAIN
-#if defined(F_SETFL) && defined(O_NDELAY)
- if ((e = fcntl(fd, F_GETFL, 0)) == -1)
- return (-1);
-
- if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
- return (-1);
- else
- e = 1;
-#endif /* F_SETFL && O_NDELAY */
-
-#ifdef FIONBIO
- {
- int zero = 0;
-
- if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
- return (-1);
- else
- e = 1;
- }
-#endif /* FIONBIO */
-
-#endif /* TRY_AGAIN */
- return (e ? 0 : -1);
-
- case EINTR:
- return (0);
-
- default:
- return (-1);
- }
-}
-
-
-/* read_preread():
- * Try to read the stuff in the input queue;
- */
-private int
-read_preread(EditLine *el)
-{
- int chrs = 0;
-
- if (el->el_chared.c_macro.nline) {
- el_free((ptr_t) el->el_chared.c_macro.nline);
- el->el_chared.c_macro.nline = NULL;
- }
- if (el->el_tty.t_mode == ED_IO)
- return (0);
-
-#ifdef FIONREAD
- (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
- if (chrs > 0) {
- char buf[EL_BUFSIZ];
-
- chrs = read(el->el_infd, buf,
- (size_t) MIN(chrs, EL_BUFSIZ - 1));
- if (chrs > 0) {
- buf[chrs] = '\0';
- el->el_chared.c_macro.nline = strdup(buf);
- el_push(el, el->el_chared.c_macro.nline);
- }
- }
-#endif /* FIONREAD */
-
- return (chrs > 0);
-}
-
-
-/* el_push():
- * Push a macro
- */
-public void
-el_push(EditLine *el, char *str)
-{
- c_macro_t *ma = &el->el_chared.c_macro;
-
- if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
- ma->level++;
- ma->macro[ma->level] = str;
- } else {
- term_beep(el);
- term__flush();
- }
-}
-
-
-/* read_getcmd():
- * Return next command from the input stream.
- */
-private int
-read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
-{
- el_action_t cmd = ED_UNASSIGNED;
- int num;
-
- while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
- if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
- return (num);
-
-#ifdef KANJI
- if ((*ch & 0200)) {
- el->el_state.metanext = 0;
- cmd = CcViMap[' '];
- break;
- } else
-#endif /* KANJI */
-
- if (el->el_state.metanext) {
- el->el_state.metanext = 0;
- *ch |= 0200;
- }
- cmd = el->el_map.current[(unsigned char) *ch];
- if (cmd == ED_SEQUENCE_LEAD_IN) {
- key_value_t val;
- switch (key_get(el, ch, &val)) {
- case XK_CMD:
- cmd = val.cmd;
- break;
- case XK_STR:
- el_push(el, val.str);
- break;
-#ifdef notyet
- case XK_EXE:
- /* XXX: In the future to run a user function */
- RunCommand(val.str);
- break;
-#endif
- default:
- EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
- break;
- }
- }
- if (el->el_map.alt == NULL)
- el->el_map.current = el->el_map.key;
- }
- *cmdnum = cmd;
- return (OKCMD);
-}
-
-
-/* read_char():
- * Read a character from the tty.
- */
-private int
-read_char(EditLine *el, char *cp)
-{
- int num_read;
- int tried = 0;
-
- while ((num_read = read(el->el_infd, cp, 1)) == -1)
- if (!tried && read__fixio(el->el_infd, errno) == 0)
- tried = 1;
- else {
- *cp = '\0';
- return (-1);
- }
-
- return (num_read);
-}
-
-
-/* el_getc():
- * Read a character
- */
-public int
-el_getc(EditLine *el, char *cp)
-{
- int num_read;
- c_macro_t *ma = &el->el_chared.c_macro;
-
- term__flush();
- for (;;) {
- if (ma->level < 0) {
- if (!read_preread(el))
- break;
- }
- if (ma->level < 0)
- break;
-
- if (*ma->macro[ma->level] == 0) {
- ma->level--;
- continue;
- }
- *cp = *ma->macro[ma->level]++ & 0377;
- if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode
- * On */
- ma->level--;
- }
- return (1);
- }
-
-#ifdef DEBUG_READ
- (void) fprintf(el->el_errfile, "Turning raw mode on\n");
-#endif /* DEBUG_READ */
- if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
- return (0);
-
-#ifdef DEBUG_READ
- (void) fprintf(el->el_errfile, "Reading a character\n");
-#endif /* DEBUG_READ */
- num_read = (*el->el_read.read_char)(el, cp);
-#ifdef DEBUG_READ
- (void) fprintf(el->el_errfile, "Got it %c\n", *cp);
-#endif /* DEBUG_READ */
- return (num_read);
-}
-
-
-public const char *
-el_gets(EditLine *el, int *nread)
-{
- int retval;
- el_action_t cmdnum = 0;
- int num; /* how many chars we have read at NL */
- char ch;
-#ifdef FIONREAD
- c_macro_t *ma = &el->el_chared.c_macro;
-#endif /* FIONREAD */
-
- if (el->el_flags & HANDLE_SIGNALS)
- sig_set(el);
-
- if (el->el_flags & NO_TTY) {
- char *cp = el->el_line.buffer;
- size_t idx;
-
- while ((*el->el_read.read_char)(el, cp) == 1) {
- /* make sure there is space for next character */
- if (cp + 1 >= el->el_line.limit) {
- idx = (cp - el->el_line.buffer);
- if (!ch_enlargebufs(el, 2))
- break;
- cp = &el->el_line.buffer[idx];
- }
- cp++;
- if (cp[-1] == '\r' || cp[-1] == '\n')
- break;
- }
-
- el->el_line.cursor = el->el_line.lastchar = cp;
- *cp = '\0';
- if (nread)
- *nread = el->el_line.cursor - el->el_line.buffer;
- return (el->el_line.buffer);
- }
- re_clear_display(el); /* reset the display stuff */
- ch_reset(el);
-
-#ifdef FIONREAD
- if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
- long chrs = 0;
-
- (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
- if (chrs == 0) {
- if (tty_rawmode(el) < 0) {
- if (nread)
- *nread = 0;
- return (NULL);
- }
- }
- }
-#endif /* FIONREAD */
-
- re_refresh(el); /* print the prompt */
-
- if (el->el_flags & EDIT_DISABLED) {
- char *cp = el->el_line.buffer;
- size_t idx;
-
- term__flush();
-
- while ((*el->el_read.read_char)(el, cp) == 1) {
- /* make sure there is space next character */
- if (cp + 1 >= el->el_line.limit) {
- idx = (cp - el->el_line.buffer);
- if (!ch_enlargebufs(el, 2))
- break;
- cp = &el->el_line.buffer[idx];
- }
- cp++;
- if (cp[-1] == '\r' || cp[-1] == '\n')
- break;
- }
-
- el->el_line.cursor = el->el_line.lastchar = cp;
- *cp = '\0';
- if (nread)
- *nread = el->el_line.cursor - el->el_line.buffer;
- return (el->el_line.buffer);
- }
- for (num = OKCMD; num == OKCMD;) { /* while still editing this
- * line */
-#ifdef DEBUG_EDIT
- read_debug(el);
-#endif /* DEBUG_EDIT */
- /* if EOF or error */
- if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
-#ifdef DEBUG_READ
- (void) fprintf(el->el_errfile,
- "Returning from el_gets %d\n", num);
-#endif /* DEBUG_READ */
- break;
- }
- if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
-#ifdef DEBUG_EDIT
- (void) fprintf(el->el_errfile,
- "ERROR: illegal command from key 0%o\r\n", ch);
-#endif /* DEBUG_EDIT */
- continue; /* try again */
- }
- /* now do the real command */
-#ifdef DEBUG_READ
- {
- el_bindings_t *b;
- for (b = el->el_map.help; b->name; b++)
- if (b->func == cmdnum)
- break;
- if (b->name)
- (void) fprintf(el->el_errfile,
- "Executing %s\n", b->name);
- else
- (void) fprintf(el->el_errfile,
- "Error command = %d\n", cmdnum);
- }
-#endif /* DEBUG_READ */
- retval = (*el->el_map.func[cmdnum]) (el, ch);
-
- /* save the last command here */
- el->el_state.lastcmd = cmdnum;
-
- /* use any return value */
- switch (retval) {
- case CC_CURSOR:
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
- re_refresh_cursor(el);
- break;
-
- case CC_REDISPLAY:
- re_clear_lines(el);
- re_clear_display(el);
- /* FALLTHROUGH */
-
- case CC_REFRESH:
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
- re_refresh(el);
- break;
-
- case CC_REFRESH_BEEP:
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
- re_refresh(el);
- term_beep(el);
- break;
-
- case CC_NORM: /* normal char */
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
- break;
-
- case CC_ARGHACK: /* Suggested by Rich Salz */
- /* <rsalz@pineapple.bbn.com> */
- break; /* keep going... */
-
- case CC_EOF: /* end of file typed */
- num = 0;
- break;
-
- case CC_NEWLINE: /* normal end of line */
- num = el->el_line.lastchar - el->el_line.buffer;
- break;
-
- case CC_FATAL: /* fatal error, reset to known state */
-#ifdef DEBUG_READ
- (void) fprintf(el->el_errfile,
- "*** editor fatal ERROR ***\r\n\n");
-#endif /* DEBUG_READ */
- /* put (real) cursor in a known place */
- re_clear_display(el); /* reset the display stuff */
- ch_reset(el); /* reset the input pointers */
- re_refresh(el); /* print the prompt again */
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
- break;
-
- case CC_ERROR:
- default: /* functions we don't know about */
-#ifdef DEBUG_READ
- (void) fprintf(el->el_errfile,
- "*** editor ERROR ***\r\n\n");
-#endif /* DEBUG_READ */
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
- term_beep(el);
- term__flush();
- break;
- }
- }
-
- /* make sure the tty is set up correctly */
- (void) tty_cookedmode(el);
- term__flush(); /* flush any buffered output */
- if (el->el_flags & HANDLE_SIGNALS)
- sig_clr(el);
- if (nread)
- *nread = num;
- return (num ? el->el_line.buffer : NULL);
-}
diff --git a/1.4/main/editline/read.h b/1.4/main/editline/read.h
deleted file mode 100644
index b01e77db2..000000000
--- a/1.4/main/editline/read.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Anthony Mallet.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * el.read.h: Character reading functions
- */
-#ifndef _h_el_read
-#define _h_el_read
-
-typedef int (*el_rfunc_t)(EditLine *, char *);
-
-typedef struct el_read_t {
- el_rfunc_t read_char; /* Function to read a character */
-} el_read_t;
-
-protected int read_init(EditLine *);
-protected int el_read_setfn(EditLine *, el_rfunc_t);
-protected el_rfunc_t el_read_getfn(EditLine *);
-
-#endif /* _h_el_read */
diff --git a/1.4/main/editline/readline.c b/1.4/main/editline/readline.c
deleted file mode 100644
index 3a62df628..000000000
--- a/1.4/main/editline/readline.c
+++ /dev/null
@@ -1,1664 +0,0 @@
-/* $NetBSD: readline.c,v 1.21 2002/03/18 16:20:36 christos Exp $ */
-
-/*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jaromir Dolecek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: readline.c,v 1.21 2002/03/18 16:20:36 christos Exp $");
-#endif /* not lint && not SCCSID */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <string.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-
-#ifdef SOLARIS
-#include <alloca.h>
-#endif
-
-#include "histedit.h"
-#include "readline/readline.h"
-#include "el.h"
-#include "fcns.h" /* for EL_NUM_FCNS */
-
-/* for rl_complete() */
-#define TAB '\r'
-
-/* see comment at the #ifdef for sense of this */
-#define GDB_411_HACK
-
-/* readline compatibility stuff - look at readline sources/documentation */
-/* to see what these variables mean */
-const char *rl_library_version = "EditLine wrapper";
-static char empty[] = { '\0' };
-static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
-static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
- '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
-char *rl_readline_name = empty;
-FILE *rl_instream = NULL;
-FILE *rl_outstream = NULL;
-int rl_point = 0;
-int rl_end = 0;
-char *rl_line_buffer = NULL;
-
-int history_base = 1; /* probably never subject to change */
-int history_length = 0;
-int max_input_history = 0;
-char history_expansion_char = '!';
-char history_subst_char = '^';
-char *history_no_expand_chars = expand_chars;
-Function *history_inhibit_expansion_function = NULL;
-
-int rl_inhibit_completion = 0;
-int rl_attempted_completion_over = 0;
-char *rl_basic_word_break_characters = break_chars;
-char *rl_completer_word_break_characters = NULL;
-char *rl_completer_quote_characters = NULL;
-CPFunction *rl_completion_entry_function = NULL;
-CPPFunction *rl_attempted_completion_function = NULL;
-
-/*
- * This is set to character indicating type of completion being done by
- * rl_complete_internal(); this is available for application completion
- * functions.
- */
-int rl_completion_type = 0;
-
-/*
- * If more than this number of items results from query for possible
- * completions, we ask user if they are sure to really display the list.
- */
-int rl_completion_query_items = 100;
-
-/*
- * List of characters which are word break characters, but should be left
- * in the parsed text when it is passed to the completion function.
- * Shell uses this to help determine what kind of completing to do.
- */
-char *rl_special_prefixes = (char *)NULL;
-
-/*
- * This is the character appended to the completed words if at the end of
- * the line. Default is ' ' (a space).
- */
-int rl_completion_append_character = ' ';
-
-/* stuff below is used internally by libedit for readline emulation */
-
-/* if not zero, non-unique completions always show list of possible matches */
-static int _rl_complete_show_all = 0;
-
-static History *h = NULL;
-static EditLine *e = NULL;
-static int el_rl_complete_cmdnum = 0;
-
-/* internal functions */
-static unsigned char _el_rl_complete(EditLine *, int);
-static char *_get_prompt(EditLine *);
-static HIST_ENTRY *_move_history(int);
-static int _history_search_gen(const char *, int, int);
-static int _history_expand_command(const char *, size_t, char **);
-static char *_rl_compat_sub(const char *, const char *,
- const char *, int);
-static int rl_complete_internal(int);
-static int _rl_qsort_string_compare(const void *, const void *);
-
-/*
- * needed for prompt switching in readline()
- */
-static char *el_rl_prompt = NULL;
-
-
-/* ARGSUSED */
-static char *
-_get_prompt(EditLine *el)
-{
- return (el_rl_prompt);
-}
-
-
-/*
- * generic function for moving around history
- */
-static HIST_ENTRY *
-_move_history(int op)
-{
- HistEvent ev;
- static HIST_ENTRY rl_he;
-
- if (history(h, &ev, op) != 0)
- return (HIST_ENTRY *) NULL;
-
- rl_he.line = ev.str;
- rl_he.data = "";
-
- return (&rl_he);
-}
-
-
-/*
- * READLINE compatibility stuff
- */
-
-/*
- * initialize rl compat stuff
- */
-int
-rl_initialize(void)
-{
- HistEvent ev;
- const LineInfo *li;
- int i;
- int editmode = 1;
- struct termios t;
-
- if (e != NULL)
- el_end(e);
- if (h != NULL)
- history_end(h);
-
- if (!rl_instream)
- rl_instream = stdin;
- if (!rl_outstream)
- rl_outstream = stdout;
-
- /*
- * See if we don't really want to run the editor
- */
- if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
- editmode = 0;
-
- e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
-
- if (!editmode)
- el_set(e, EL_EDITMODE, 0);
-
- h = history_init();
- if (!e || !h)
- return (-1);
-
- history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
- history_length = 0;
- max_input_history = INT_MAX;
- el_set(e, EL_HIST, history, h);
-
- /* for proper prompt printing in readline() */
- el_rl_prompt = strdup("");
- el_set(e, EL_PROMPT, _get_prompt);
- el_set(e, EL_SIGNAL, 1);
-
- /* set default mode to "emacs"-style and read setting afterwards */
- /* so this can be overriden */
- el_set(e, EL_EDITOR, "emacs");
-
- /*
- * Word completition - this has to go AFTER rebinding keys
- * to emacs-style.
- */
- el_set(e, EL_ADDFN, "rl_complete",
- "ReadLine compatible completition function",
- _el_rl_complete);
- el_set(e, EL_BIND, "^I", "rl_complete", NULL);
-
- /*
- * Find out where the rl_complete function was added; this is
- * used later to detect that lastcmd was also rl_complete.
- */
- for(i=EL_NUM_FCNS; i < e->el_map.nfunc; i++) {
- if (e->el_map.func[i] == _el_rl_complete) {
- el_rl_complete_cmdnum = i;
- break;
- }
- }
-
- /* read settings from configuration file */
- el_source(e, NULL);
-
- /*
- * Unfortunately, some applications really do use rl_point
- * and rl_line_buffer directly.
- */
- li = el_line(e);
- /* a cheesy way to get rid of const cast. */
- rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
- rl_point = rl_end = 0;
-
- return (0);
-}
-
-
-/*
- * read one line from input stream and return it, chomping
- * trailing newline (if there is any)
- */
-char *
-readline(const char *prompt)
-{
- HistEvent ev;
- int count;
- const char *ret;
- char *buf;
-
- if (e == NULL || h == NULL)
- rl_initialize();
-
- /* update prompt accordingly to what has been passed */
- if (!prompt)
- prompt = "";
- if (strcmp(el_rl_prompt, prompt) != 0) {
- free(el_rl_prompt);
- el_rl_prompt = strdup(prompt);
- }
- /* get one line from input stream */
- ret = el_gets(e, &count);
-
- if (ret && count > 0) {
- int lastidx;
-
- buf = strdup(ret);
- lastidx = count - 1;
- if (buf[lastidx] == '\n')
- buf[lastidx] = '\0';
- } else
- buf = NULL;
-
- history(h, &ev, H_GETSIZE);
- history_length = ev.num;
-
- return buf;
-}
-
-/*
- * history functions
- */
-
-/*
- * is normally called before application starts to use
- * history expansion functions
- */
-void
-using_history(void)
-{
- if (h == NULL || e == NULL)
- rl_initialize();
-}
-
-
-/*
- * substitute ``what'' with ``with'', returning resulting string; if
- * globally == 1, substitutes all occurences of what, otherwise only the
- * first one
- */
-static char *
-_rl_compat_sub(const char *str, const char *what, const char *with,
- int globally)
-{
- char *result;
- const char *temp, *new;
- int len, with_len, what_len, add;
- size_t size, i;
-
- result = malloc((size = 16));
- temp = str;
- with_len = strlen(with);
- what_len = strlen(what);
- len = 0;
- do {
- new = strstr(temp, what);
- if (new) {
- i = new - temp;
- add = i + with_len;
- if (i + add + 1 >= size) {
- size += add + 1;
- result = realloc(result, size);
- }
- (void) strncpy(&result[len], temp, i);
- len += i;
- (void) strcpy(&result[len], with); /* safe */
- len += with_len;
- temp = new + what_len;
- } else {
- add = strlen(temp);
- if (len + add + 1 >= size) {
- size += add + 1;
- result = realloc(result, size);
- }
- (void) strcpy(&result[len], temp); /* safe */
- len += add;
- temp = NULL;
- }
- } while (temp && globally);
- result[len] = '\0';
-
- return (result);
-}
-
-
-/*
- * the real function doing history expansion - takes as argument command
- * to do and data upon which the command should be executed
- * does expansion the way I've understood readline documentation
- * word designator ``%'' isn't supported (yet ?)
- *
- * returns 0 if data was not modified, 1 if it was and 2 if the string
- * should be only printed and not executed; in case of error,
- * returns -1 and *result points to NULL
- * it's callers responsibility to free() string returned in *result
- */
-static int
-_history_expand_command(const char *command, size_t cmdlen, char **result)
-{
- char **arr, *tempcmd, *line, *search = NULL, *cmd;
- const char *event_data = NULL;
- static char *from = NULL, *to = NULL;
- int start = -1, end = -1, max, i, idx;
- int h_on = 0, t_on = 0, r_on = 0, e_on = 0, p_on = 0, g_on = 0;
- int event_num = 0, retval;
- size_t cmdsize;
-
- *result = NULL;
-
- cmd = alloca(cmdlen + 1);
- (void) strncpy(cmd, command, cmdlen);
- cmd[cmdlen] = 0;
-
- idx = 1;
- /* find out which event to take */
- if (cmd[idx] == history_expansion_char) {
- event_num = history_length;
- idx++;
- } else {
- int off, num;
- size_t len;
- off = idx;
- while (cmd[off] && !strchr(":^$*-%", cmd[off]))
- off++;
- num = atoi(&cmd[idx]);
- if (num != 0) {
- event_num = num;
- if (num < 0)
- event_num += history_length + 1;
- } else {
- int prefix = 1, curr_num;
- HistEvent ev;
-
- len = off - idx;
- if (cmd[idx] == '?') {
- idx++, len--;
- if (cmd[off - 1] == '?')
- len--;
- else if (cmd[off] != '\n' && cmd[off] != '\0')
- return (-1);
- prefix = 0;
- }
- search = alloca(len + 1);
- (void) strncpy(search, &cmd[idx], len);
- search[len] = '\0';
-
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- curr_num = ev.num;
-
- if (prefix)
- retval = history_search_prefix(search, -1);
- else
- retval = history_search(search, -1);
-
- if (retval == -1) {
- fprintf(rl_outstream, "%s: Event not found\n",
- search);
- return (-1);
- }
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- event_data = ev.str;
-
- /* roll back to original position */
- history(h, &ev, H_NEXT_EVENT, curr_num);
- }
- idx = off;
- }
-
- if (!event_data && event_num >= 0) {
- HIST_ENTRY *rl_he;
- rl_he = history_get(event_num);
- if (!rl_he)
- return (0);
- event_data = rl_he->line;
- } else
- return (-1);
-
- if (cmd[idx] != ':')
- return (-1);
- cmd += idx + 1;
-
- /* recognize cmd */
- if (*cmd == '^')
- start = end = 1, cmd++;
- else if (*cmd == '$')
- start = end = -1, cmd++;
- else if (*cmd == '*')
- start = 1, end = -1, cmd++;
- else if (isdigit((unsigned char) *cmd)) {
- const char *temp;
- int shifted = 0;
-
- start = atoi(cmd);
- temp = cmd;
- for (; isdigit((unsigned char) *cmd); cmd++);
- if (temp != cmd)
- shifted = 1;
- if (shifted && *cmd == '-') {
- if (!isdigit((unsigned char) *(cmd + 1)))
- end = -2;
- else {
- end = atoi(cmd + 1);
- for (; isdigit((unsigned char) *cmd); cmd++);
- }
- } else if (shifted && *cmd == '*')
- end = -1, cmd++;
- else if (shifted)
- end = start;
- }
- if (*cmd == ':')
- cmd++;
-
- line = strdup(event_data);
- for (; *cmd; cmd++) {
- if (*cmd == ':')
- continue;
- else if (*cmd == 'h')
- h_on = 1 | g_on, g_on = 0;
- else if (*cmd == 't')
- t_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'r')
- r_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'e')
- e_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'p')
- p_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'g')
- g_on = 2;
- else if (*cmd == 's' || *cmd == '&') {
- char *what, *with, delim;
- int len, from_len;
- size_t size;
-
- if (*cmd == '&' && (from == NULL || to == NULL))
- continue;
- else if (*cmd == 's') {
- delim = *(++cmd), cmd++;
- size = 16;
- what = realloc(from, size);
- len = 0;
- for (; *cmd && *cmd != delim; cmd++) {
- if (*cmd == '\\'
- && *(cmd + 1) == delim)
- cmd++;
- if (len >= size)
- what = realloc(what,
- (size <<= 1));
- what[len++] = *cmd;
- }
- what[len] = '\0';
- from = what;
- if (*what == '\0') {
- free(what);
- if (search)
- from = strdup(search);
- else {
- from = NULL;
- return (-1);
- }
- }
- cmd++; /* shift after delim */
- if (!*cmd)
- continue;
-
- size = 16;
- with = realloc(to, size);
- len = 0;
- from_len = strlen(from);
- for (; *cmd && *cmd != delim; cmd++) {
- if (len + from_len + 1 >= size) {
- size += from_len + 1;
- with = realloc(with, size);
- }
- if (*cmd == '&') {
- /* safe */
- (void) strcpy(&with[len], from);
- len += from_len;
- continue;
- }
- if (*cmd == '\\'
- && (*(cmd + 1) == delim
- || *(cmd + 1) == '&'))
- cmd++;
- with[len++] = *cmd;
- }
- with[len] = '\0';
- to = with;
-
- tempcmd = _rl_compat_sub(line, from, to,
- (g_on) ? 1 : 0);
- free(line);
- line = tempcmd;
- g_on = 0;
- }
- }
- }
-
- arr = history_tokenize(line);
- free(line); /* no more needed */
- if (arr && *arr == NULL)
- free(arr), arr = NULL;
- if (!arr)
- return (-1);
-
- /* find out max valid idx to array of array */
- max = 0;
- for (i = 0; arr[i]; i++)
- max++;
- max--;
-
- /* set boundaries to something relevant */
- if (start < 0)
- start = 1;
- if (end < 0)
- end = max - ((end < -1) ? 1 : 0);
-
- /* check boundaries ... */
- if (start > max || end > max || start > end)
- return (-1);
-
- for (i = 0; i <= max; i++) {
- char *temp;
- if (h_on && (i == 1 || h_on > 1) &&
- (temp = strrchr(arr[i], '/')))
- *(temp + 1) = '\0';
- if (t_on && (i == 1 || t_on > 1) &&
- (temp = strrchr(arr[i], '/')))
- (void) strcpy(arr[i], temp + 1);
- if (r_on && (i == 1 || r_on > 1) &&
- (temp = strrchr(arr[i], '.')))
- *temp = '\0';
- if (e_on && (i == 1 || e_on > 1) &&
- (temp = strrchr(arr[i], '.')))
- (void) strcpy(arr[i], temp);
- }
-
- cmdsize = 1, cmdlen = 0;
- tempcmd = malloc(cmdsize);
- for (i = start; start <= i && i <= end; i++) {
- int arr_len;
-
- arr_len = strlen(arr[i]);
- if (cmdlen + arr_len + 1 >= cmdsize) {
- cmdsize += arr_len + 1;
- tempcmd = realloc(tempcmd, cmdsize);
- }
- (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */
- cmdlen += arr_len;
- tempcmd[cmdlen++] = ' '; /* add a space */
- }
- while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1]))
- cmdlen--;
- tempcmd[cmdlen] = '\0';
-
- *result = tempcmd;
-
- for (i = 0; i <= max; i++)
- free(arr[i]);
- free(arr), arr = (char **) NULL;
- return (p_on) ? 2 : 1;
-}
-
-
-/*
- * csh-style history expansion
- */
-int
-history_expand(char *str, char **output)
-{
- int i, retval = 0, idx;
- size_t size;
- char *temp, *result;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- *output = strdup(str); /* do it early */
-
- if (str[0] == history_subst_char) {
- /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
- temp = alloca(4 + strlen(str) + 1);
- temp[0] = temp[1] = history_expansion_char;
- temp[2] = ':';
- temp[3] = 's';
- (void) strcpy(temp + 4, str);
- str = temp;
- }
-#define ADD_STRING(what, len) \
- { \
- if (idx + len + 1 > size) \
- result = realloc(result, (size += len + 1)); \
- (void)strncpy(&result[idx], what, len); \
- idx += len; \
- result[idx] = '\0'; \
- }
-
- result = NULL;
- size = idx = 0;
- for (i = 0; str[i];) {
- int start, j, loop_again;
- size_t len;
-
- loop_again = 1;
- start = j = i;
-loop:
- for (; str[j]; j++) {
- if (str[j] == '\\' &&
- str[j + 1] == history_expansion_char) {
- (void) strcpy(&str[j], &str[j + 1]);
- continue;
- }
- if (!loop_again) {
- if (str[j] == '?') {
- while (str[j] && str[++j] != '?');
- if (str[j] == '?')
- j++;
- } else if (isspace((unsigned char) str[j]))
- break;
- }
- if (str[j] == history_expansion_char
- && !strchr(history_no_expand_chars, str[j + 1])
- && (!history_inhibit_expansion_function ||
- (*history_inhibit_expansion_function)(str, j) == 0))
- break;
- }
-
- if (str[j] && str[j + 1] != '#' && loop_again) {
- i = j;
- j++;
- if (str[j] == history_expansion_char)
- j++;
- loop_again = 0;
- goto loop;
- }
- len = i - start;
- temp = &str[start];
- ADD_STRING(temp, len);
-
- if (str[i] == '\0' || str[i] != history_expansion_char
- || str[i + 1] == '#') {
- len = j - i;
- temp = &str[i];
- ADD_STRING(temp, len);
- if (start == 0)
- retval = 0;
- else
- retval = 1;
- break;
- }
- retval = _history_expand_command(&str[i], (size_t) (j - i),
- &temp);
- if (retval != -1) {
- len = strlen(temp);
- ADD_STRING(temp, len);
- }
- i = j;
- } /* for(i ...) */
-
- if (retval == 2) {
- add_history(temp);
-#ifdef GDB_411_HACK
- /* gdb 4.11 has been shipped with readline, where */
- /* history_expand() returned -1 when the line */
- /* should not be executed; in readline 2.1+ */
- /* it should return 2 in such a case */
- retval = -1;
-#endif
- }
- free(*output);
- *output = result;
-
- return (retval);
-}
-
-
-/*
- * Parse the string into individual tokens, similarily to how shell would do it.
- */
-char **
-history_tokenize(const char *str)
-{
- int size = 1, result_idx = 0, i, start;
- size_t len;
- char **result = NULL, *temp, delim = '\0';
-
- for (i = 0; str[i]; i++) {
- while (isspace((unsigned char) str[i]))
- i++;
- start = i;
- for (; str[i]; i++) {
- if (str[i] == '\\') {
- if (str[i+1] != '\0')
- i++;
- } else if (str[i] == delim)
- delim = '\0';
- else if (!delim &&
- (isspace((unsigned char) str[i]) ||
- strchr("()<>;&|$", str[i])))
- break;
- else if (!delim && strchr("'`\"", str[i]))
- delim = str[i];
- }
-
- if (result_idx + 2 >= size) {
- size <<= 1;
- result = realloc(result, size * sizeof(char *));
- }
- len = i - start;
- temp = malloc(len + 1);
- (void) strncpy(temp, &str[start], len);
- temp[len] = '\0';
- result[result_idx++] = temp;
- result[result_idx] = NULL;
- }
-
- return (result);
-}
-
-
-/*
- * limit size of history record to ``max'' events
- */
-void
-stifle_history(int max)
-{
- HistEvent ev;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- if (history(h, &ev, H_SETSIZE, max) == 0)
- max_input_history = max;
-}
-
-
-/*
- * "unlimit" size of history - set the limit to maximum allowed int value
- */
-int
-unstifle_history(void)
-{
- HistEvent ev;
- int omax;
-
- history(h, &ev, H_SETSIZE, INT_MAX);
- omax = max_input_history;
- max_input_history = INT_MAX;
- return (omax); /* some value _must_ be returned */
-}
-
-
-int
-history_is_stifled(void)
-{
-
- /* cannot return true answer */
- return (max_input_history != INT_MAX);
-}
-
-
-/*
- * read history from a file given
- */
-int
-read_history(const char *filename)
-{
- HistEvent ev;
-
- if (h == NULL || e == NULL)
- rl_initialize();
- return (history(h, &ev, H_LOAD, filename));
-}
-
-
-/*
- * write history to a file given
- */
-int
-write_history(const char *filename)
-{
- HistEvent ev;
-
- if (h == NULL || e == NULL)
- rl_initialize();
- return (history(h, &ev, H_SAVE, filename));
-}
-
-
-/*
- * returns history ``num''th event
- *
- * returned pointer points to static variable
- */
-HIST_ENTRY *
-history_get(int num)
-{
- static HIST_ENTRY she;
- HistEvent ev;
- int i = 1, curr_num;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- /* rewind to beginning */
- if (history(h, &ev, H_CURR) != 0)
- return (NULL);
- curr_num = ev.num;
- if (history(h, &ev, H_LAST) != 0)
- return (NULL); /* error */
- while (i < num && history(h, &ev, H_PREV) == 0)
- i++;
- if (i != num)
- return (NULL); /* not so many entries */
-
- she.line = ev.str;
- she.data = NULL;
-
- /* rewind history to the same event it was before */
- (void) history(h, &ev, H_FIRST);
- (void) history(h, &ev, H_NEXT_EVENT, curr_num);
-
- return (&she);
-}
-
-
-/*
- * add the line to history table
- */
-int
-add_history(const char *line)
-{
- HistEvent ev;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- (void) history(h, &ev, H_ENTER, line);
- if (history(h, &ev, H_GETSIZE) == 0)
- history_length = ev.num;
-
- return (!(history_length > 0)); /* return 0 if all is okay */
-}
-
-
-/*
- * clear the history list - delete all entries
- */
-void
-clear_history(void)
-{
- HistEvent ev;
-
- history(h, &ev, H_CLEAR);
-}
-
-
-/*
- * returns offset of the current history event
- */
-int
-where_history(void)
-{
- HistEvent ev;
- int curr_num, off;
-
- if (history(h, &ev, H_CURR) != 0)
- return (0);
- curr_num = ev.num;
-
- history(h, &ev, H_FIRST);
- off = 1;
- while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
- off++;
-
- return (off);
-}
-
-
-/*
- * returns current history event or NULL if there is no such event
- */
-HIST_ENTRY *
-current_history(void)
-{
-
- return (_move_history(H_CURR));
-}
-
-
-/*
- * returns total number of bytes history events' data are using
- */
-int
-history_total_bytes(void)
-{
- HistEvent ev;
- int curr_num, size;
-
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- curr_num = ev.num;
-
- history(h, &ev, H_FIRST);
- size = 0;
- do
- size += strlen(ev.str);
- while (history(h, &ev, H_NEXT) == 0);
-
- /* get to the same position as before */
- history(h, &ev, H_PREV_EVENT, curr_num);
-
- return (size);
-}
-
-
-/*
- * sets the position in the history list to ``pos''
- */
-int
-history_set_pos(int pos)
-{
- HistEvent ev;
- int off, curr_num;
-
- if (pos > history_length || pos < 0)
- return (-1);
-
- history(h, &ev, H_CURR);
- curr_num = ev.num;
- history(h, &ev, H_FIRST);
- off = 0;
- while (off < pos && history(h, &ev, H_NEXT) == 0)
- off++;
-
- if (off != pos) { /* do a rollback in case of error */
- history(h, &ev, H_FIRST);
- history(h, &ev, H_NEXT_EVENT, curr_num);
- return (-1);
- }
- return (0);
-}
-
-
-/*
- * returns previous event in history and shifts pointer accordingly
- */
-HIST_ENTRY *
-previous_history(void)
-{
-
- return (_move_history(H_PREV));
-}
-
-
-/*
- * returns next event in history and shifts pointer accordingly
- */
-HIST_ENTRY *
-next_history(void)
-{
-
- return (_move_history(H_NEXT));
-}
-
-
-/*
- * generic history search function
- */
-static int
-_history_search_gen(const char *str, int direction, int pos)
-{
- HistEvent ev;
- const char *strp;
- int curr_num;
-
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- curr_num = ev.num;
-
- for (;;) {
- strp = strstr(ev.str, str);
- if (strp && (pos < 0 || &ev.str[pos] == strp))
- return (int) (strp - ev.str);
- if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0)
- break;
- }
-
- history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
-
- return (-1);
-}
-
-
-/*
- * searches for first history event containing the str
- */
-int
-history_search(const char *str, int direction)
-{
-
- return (_history_search_gen(str, direction, -1));
-}
-
-
-/*
- * searches for first history event beginning with str
- */
-int
-history_search_prefix(const char *str, int direction)
-{
-
- return (_history_search_gen(str, direction, 0));
-}
-
-
-/*
- * search for event in history containing str, starting at offset
- * abs(pos); continue backward, if pos<0, forward otherwise
- */
-/* ARGSUSED */
-int
-history_search_pos(const char *str, int direction, int pos)
-{
- HistEvent ev;
- int curr_num, off;
-
- off = (pos > 0) ? pos : -pos;
- pos = (pos > 0) ? 1 : -1;
-
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- curr_num = ev.num;
-
- if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
- return (-1);
-
-
- for (;;) {
- if (strstr(ev.str, str))
- return (off);
- if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
- break;
- }
-
- /* set "current" pointer back to previous state */
- history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
-
- return (-1);
-}
-
-
-/********************************/
-/* completition functions */
-
-/*
- * does tilde expansion of strings of type ``~user/foo''
- * if ``user'' isn't valid user name or ``txt'' doesn't start
- * w/ '~', returns pointer to strdup()ed copy of ``txt''
- *
- * it's callers's responsibility to free() returned string
- */
-char *
-tilde_expand(char *txt)
-{
- struct passwd *pass;
- char *temp;
- size_t len = 0;
-
- if (txt[0] != '~')
- return (strdup(txt));
-
- temp = strchr(txt + 1, '/');
- if (temp == NULL)
- temp = strdup(txt + 1);
- else {
- len = temp - txt + 1; /* text until string after slash */
- temp = malloc(len);
- (void) strncpy(temp, txt + 1, len - 2);
- temp[len - 2] = '\0';
- }
- pass = getpwnam(temp);
- free(temp); /* value no more needed */
- if (pass == NULL)
- return (strdup(txt));
-
- /* update pointer txt to point at string immedially following */
- /* first slash */
- txt += len;
-
- temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
- (void) sprintf(temp, "%s/%s", pass->pw_dir, txt);
-
- return (temp);
-}
-
-
-/*
- * return first found file name starting by the ``text'' or NULL if no
- * such file can be found.
- * The first ``state'' matches are ignored.
- *
- * it's caller's responsibility to free returned string
- */
-char *
-filename_completion_function(const char *text, int state)
-{
- DIR *dir = NULL;
- char *filename = NULL, *dirname = NULL;
- size_t filename_len = 0;
- struct dirent *entry;
- char *temp;
- size_t len;
-
- temp = strrchr(text, '/');
- if (temp) {
- temp++;
- filename = realloc(filename, strlen(temp) + 1);
- (void) strcpy(filename, temp);
- len = temp - text; /* including last slash */
- dirname = realloc(dirname, len + 1);
- (void) strncpy(dirname, text, len);
- dirname[len] = '\0';
- } else {
- filename = strdup(text);
- dirname = NULL;
- }
-
- /* support for ``~user'' syntax */
- if (dirname && *dirname == '~') {
- temp = tilde_expand(dirname);
- dirname = realloc(dirname, strlen(temp) + 1);
- (void) strcpy(dirname, temp); /* safe */
- free(temp); /* no longer needed */
- }
- /* will be used in cycle */
- filename_len = strlen(filename);
-
- dir = opendir(dirname ? dirname : ".");
- if (!dir)
- return (NULL); /* cannot open the directory */
-
- /* find the match */
- while ((entry = readdir(dir)) != NULL) {
- /* otherwise, get first entry where first */
- /* filename_len characters are equal */
- if (
-#if defined(__SVR4) || defined(__linux__)
- strlen(entry->d_name) >= filename_len
-#else
- entry->d_namlen >= filename_len
-#endif
- && strncmp(entry->d_name, filename,
- filename_len) == 0
- && (state-- == 0))
- break;
- }
-
- if (entry) { /* match found */
-
- struct stat stbuf;
-#if defined(__SVR4) || defined(__linux__)
- len = strlen(entry->d_name) +
-#else
- len = entry->d_namlen +
-#endif
- ((dirname) ? strlen(dirname) : 0) + 1 + 1;
- temp = malloc(len);
- (void) sprintf(temp, "%s%s",
- dirname ? dirname : "", entry->d_name); /* safe */
-
- /* test, if it's directory */
- if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
- strcat(temp, "/"); /* safe */
- } else
- temp = NULL;
- closedir(dir);
-
- return (temp);
-}
-
-
-/*
- * a completion generator for usernames; returns _first_ username
- * which starts with supplied text
- * text contains a partial username preceded by random character
- * (usually '~'); state is ignored
- * it's callers responsibility to free returned value
- */
-char *
-username_completion_function(const char *text, int state)
-{
- struct passwd *pwd;
-
- if (text[0] == '\0')
- return (NULL);
-
- if (*text == '~')
- text++;
-
- if (state == 0)
- setpwent();
-
- while ((pwd = getpwent()) && text[0] == pwd->pw_name[0]
- && strcmp(text, pwd->pw_name) == 0);
-
- if (pwd == NULL) {
- endpwent();
- return (NULL);
- }
- return (strdup(pwd->pw_name));
-}
-
-
-/*
- * el-compatible wrapper around rl_complete; needed for key binding
- */
-/* ARGSUSED */
-static unsigned char
-_el_rl_complete(EditLine *el, int ch)
-{
- return (unsigned char) rl_complete(0, ch);
-}
-
-
-/*
- * returns list of completitions for text given
- */
-char **
-completion_matches(const char *text, CPFunction *genfunc)
-{
- char **match_list = NULL, *retstr, *prevstr;
- size_t match_list_len, max_equal, which, i;
- int matches;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- matches = 0;
- match_list_len = 1;
- while ((retstr = (*genfunc) (text, matches)) != NULL) {
- if (matches + 1 >= match_list_len) {
- match_list_len <<= 1;
- match_list = realloc(match_list,
- match_list_len * sizeof(char *));
- }
- match_list[++matches] = retstr;
- }
-
- if (!match_list)
- return (char **) NULL; /* nothing found */
-
- /* find least denominator and insert it to match_list[0] */
- which = 2;
- prevstr = match_list[1];
- max_equal = strlen(prevstr);
- for (; which <= matches; which++) {
- for (i = 0; i < max_equal &&
- prevstr[i] == match_list[which][i]; i++)
- continue;
- max_equal = i;
- }
-
- retstr = malloc(max_equal + 1);
- (void) strncpy(retstr, match_list[1], max_equal);
- retstr[max_equal] = '\0';
- match_list[0] = retstr;
-
- /* add NULL as last pointer to the array */
- if (matches + 1 >= match_list_len)
- match_list = realloc(match_list,
- (match_list_len + 1) * sizeof(char *));
- match_list[matches + 1] = (char *) NULL;
-
- return (match_list);
-}
-
-/*
- * Sort function for qsort(). Just wrapper around strcasecmp().
- */
-static int
-_rl_qsort_string_compare(i1, i2)
- const void *i1, *i2;
-{
- /* LINTED const castaway */
- const char *s1 = ((const char **)i1)[0];
- /* LINTED const castaway */
- const char *s2 = ((const char **)i2)[0];
-
- return strcasecmp(s1, s2);
-}
-
-/*
- * Display list of strings in columnar format on readline's output stream.
- * 'matches' is list of strings, 'len' is number of strings in 'matches',
- * 'max' is maximum length of string in 'matches'.
- */
-void
-rl_display_match_list (matches, len, max)
- char **matches;
- int len, max;
-{
- int i, idx, limit, count;
- int screenwidth = e->el_term.t_size.h;
-
- /*
- * Find out how many entries can be put on one line, count
- * with two spaces between strings.
- */
- limit = screenwidth / (max + 2);
- if (limit == 0)
- limit = 1;
-
- /* how many lines of output */
- count = len / limit;
- if (count * limit < len)
- count++;
-
- /* Sort the items if they are not already sorted. */
- qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
- _rl_qsort_string_compare);
-
- idx = 1;
- for(; count > 0; count--) {
- for(i=0; i < limit && matches[idx]; i++, idx++)
- fprintf(e->el_outfile, "%-*s ", max, matches[idx]);
- fprintf(e->el_outfile, "\n");
- }
-}
-
-/*
- * Complete the word at or before point, called by rl_complete()
- * 'what_to_do' says what to do with the completion.
- * `?' means list the possible completions.
- * TAB means do standard completion.
- * `*' means insert all of the possible completions.
- * `!' means to do standard completion, and list all possible completions if
- * there is more than one.
- *
- * Note: '*' support is not implemented
- */
-static int
-rl_complete_internal(int what_to_do)
-{
- CPFunction *complet_func;
- const LineInfo *li;
- char *temp, **matches;
- const char *ctemp;
- size_t len;
-
- rl_completion_type = what_to_do;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- complet_func = rl_completion_entry_function;
- if (!complet_func)
- complet_func = filename_completion_function;
-
- /* We now look backwards for the start of a filename/variable word */
- li = el_line(e);
- ctemp = (const char *) li->cursor;
- while (ctemp > li->buffer
- && !strchr(rl_basic_word_break_characters, ctemp[-1])
- && (!rl_special_prefixes
- || !strchr(rl_special_prefixes, ctemp[-1]) ) )
- ctemp--;
-
- len = li->cursor - ctemp;
- temp = alloca(len + 1);
- (void) strncpy(temp, ctemp, len);
- temp[len] = '\0';
-
- /* these can be used by function called in completion_matches() */
- /* or (*rl_attempted_completion_function)() */
- rl_point = li->cursor - li->buffer;
- rl_end = li->lastchar - li->buffer;
-
- if (!rl_attempted_completion_function)
- matches = completion_matches(temp, complet_func);
- else {
- int end = li->cursor - li->buffer;
- matches = (*rl_attempted_completion_function) (temp, (int)
- (end - len), end);
- }
-
- if (matches) {
- int i, retval = CC_REFRESH;
- int matches_num, maxlen, match_len, match_display=1;
-
- /*
- * Only replace the completed string with common part of
- * possible matches if there is possible completion.
- */
- if (matches[0][0] != '\0') {
- el_deletestr(e, (int) len);
- el_insertstr(e, matches[0]);
- }
-
- if (what_to_do == '?')
- goto display_matches;
-
- if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
- /*
- * We found exact match. Add a space after
- * it, unless we do filename completition and the
- * object is a directory.
- */
- size_t alen = strlen(matches[0]);
- if ((complet_func != filename_completion_function
- || (alen > 0 && (matches[0])[alen - 1] != '/'))
- && rl_completion_append_character) {
- char buf[2];
- buf[0] = rl_completion_append_character;
- buf[1] = '\0';
- el_insertstr(e, buf);
- }
- } else if (what_to_do == '!') {
- display_matches:
- /*
- * More than one match and requested to list possible
- * matches.
- */
-
- for(i=1, maxlen=0; matches[i]; i++) {
- match_len = strlen(matches[i]);
- if (match_len > maxlen)
- maxlen = match_len;
- }
- matches_num = i - 1;
-
- /* newline to get on next line from command line */
- fprintf(e->el_outfile, "\n");
-
- /*
- * If there are too many items, ask user for display
- * confirmation.
- */
- if (matches_num > rl_completion_query_items) {
- fprintf(e->el_outfile,
- "Display all %d possibilities? (y or n) ",
- matches_num);
- fflush(e->el_outfile);
- if (getc(stdin) != 'y')
- match_display = 0;
- fprintf(e->el_outfile, "\n");
- }
-
- if (match_display)
- rl_display_match_list(matches, matches_num,
- maxlen);
- retval = CC_REDISPLAY;
- } else if (matches[0][0]) {
- /*
- * There was some common match, but the name was
- * not complete enough. Next tab will print possible
- * completions.
- */
- el_beep(e);
- } else {
- /* lcd is not a valid object - further specification */
- /* is needed */
- el_beep(e);
- retval = CC_NORM;
- }
-
- /* free elements of array and the array itself */
- for (i = 0; matches[i]; i++)
- free(matches[i]);
- free(matches), matches = NULL;
-
- return (retval);
- }
- return (CC_NORM);
-}
-
-
-/*
- * complete word at current point
- */
-int
-rl_complete(int ignore, int invoking_key)
-{
- if (h == NULL || e == NULL)
- rl_initialize();
-
- if (rl_inhibit_completion) {
- rl_insert(ignore, invoking_key);
- return (CC_REFRESH);
- } else if (e->el_state.lastcmd == el_rl_complete_cmdnum)
- return rl_complete_internal('?');
- else if (_rl_complete_show_all)
- return rl_complete_internal('!');
- else
- return (rl_complete_internal(TAB));
-}
-
-
-/*
- * misc other functions
- */
-
-/*
- * bind key c to readline-type function func
- */
-int
-rl_bind_key(int c, int func(int, int))
-{
- int retval = -1;
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- if (func == rl_insert) {
- /* XXX notice there is no range checking of ``c'' */
- e->el_map.key[c] = ED_INSERT;
- retval = 0;
- }
- return (retval);
-}
-
-
-/*
- * read one key from input - handles chars pushed back
- * to input stream also
- */
-int
-rl_read_key(void)
-{
- char fooarr[2 * sizeof(int)];
-
- if (e == NULL || h == NULL)
- rl_initialize();
-
- return (el_getc(e, fooarr));
-}
-
-
-/*
- * reset the terminal
- */
-/* ARGSUSED */
-void
-rl_reset_terminal(const char *p)
-{
-
- if (h == NULL || e == NULL)
- rl_initialize();
- el_reset(e);
-}
-
-
-/*
- * insert character ``c'' back into input stream, ``count'' times
- */
-int
-rl_insert(int count, int c)
-{
- char arr[2];
-
- if (h == NULL || e == NULL)
- rl_initialize();
-
- /* XXX - int -> char conversion can lose on multichars */
- arr[0] = c;
- arr[1] = '\0';
-
- for (; count > 0; count--)
- el_push(e, arr);
-
- return (0);
-}
diff --git a/1.4/main/editline/readline/readline.h b/1.4/main/editline/readline/readline.h
deleted file mode 100644
index 7485dde40..000000000
--- a/1.4/main/editline/readline/readline.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $NetBSD: readline.h,v 1.1 2001/01/05 21:15:50 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jaromir Dolecek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef _READLINE_H_
-#define _READLINE_H_
-
-#include <sys/types.h>
-
-/* list of readline stuff supported by editline library's readline wrapper */
-
-/* typedefs */
-typedef int Function(const char *, int);
-typedef void VFunction(void);
-typedef char *CPFunction(const char *, int);
-typedef char **CPPFunction(const char *, int, int);
-
-typedef struct _hist_entry {
- const char *line;
- const char *data;
-} HIST_ENTRY;
-
-/* global variables used by readline enabled applications */
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern const char *rl_library_version;
-extern char *rl_readline_name;
-extern FILE *rl_instream;
-extern FILE *rl_outstream;
-extern char *rl_line_buffer;
-extern int rl_point, rl_end;
-extern int history_base, history_length;
-extern int max_input_history;
-extern char *rl_basic_word_break_characters;
-extern char *rl_completer_word_break_characters;
-extern char *rl_completer_quote_characters;
-extern CPFunction *rl_completion_entry_function;
-extern CPPFunction *rl_attempted_completion_function;
-extern int rl_completion_type;
-extern int rl_completion_query_items;
-extern char *rl_special_prefixes;
-extern int rl_completion_append_character;
-
-/* supported functions */
-char *readline(const char *);
-int rl_initialize(void);
-
-void using_history(void);
-int add_history(const char *);
-void clear_history(void);
-void stifle_history(int);
-int unstifle_history(void);
-int history_is_stifled(void);
-int where_history(void);
-HIST_ENTRY *current_history(void);
-HIST_ENTRY *history_get(int);
-int history_total_bytes(void);
-int history_set_pos(int);
-HIST_ENTRY *previous_history(void);
-HIST_ENTRY *next_history(void);
-int history_search(const char *, int);
-int history_search_prefix(const char *, int);
-int history_search_pos(const char *, int, int);
-int read_history(const char *);
-int write_history(const char *);
-int history_expand(char *, char **);
-char **history_tokenize(const char *);
-
-char *tilde_expand(char *);
-char *filename_completion_function(const char *, int);
-char *username_completion_function(const char *, int);
-int rl_complete(int, int);
-int rl_read_key(void);
-char **completion_matches(const char *, CPFunction *);
-void rl_display_match_list(char **, int, int);
-
-int rl_insert(int, int);
-void rl_reset_terminal(const char *);
-int rl_bind_key(int, int (*)(int, int));
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _READLINE_H_ */
diff --git a/1.4/main/editline/refresh.c b/1.4/main/editline/refresh.c
deleted file mode 100644
index 935117741..000000000
--- a/1.4/main/editline/refresh.c
+++ /dev/null
@@ -1,1104 +0,0 @@
-/* $NetBSD: refresh.c,v 1.18 2002/03/18 16:00:58 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: refresh.c,v 1.18 2002/03/18 16:00:58 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * refresh.c: Lower level screen refreshing functions
- */
-#include <stdio.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "el.h"
-
-private void re_addc(EditLine *, int);
-private void re_update_line(EditLine *, char *, char *, int);
-private void re_insert (EditLine *, char *, int, int, char *, int);
-private void re_delete(EditLine *, char *, int, int, int);
-private void re_fastputc(EditLine *, int);
-private void re__strncopy(char *, char *, size_t);
-private void re__copy_and_pad(char *, const char *, size_t);
-
-#ifdef DEBUG_REFRESH
-private void re_printstr(EditLine *, char *, char *, char *);
-#define __F el->el_errfile
-#define ELRE_ASSERT(a, b, c) do \
- if (a) { \
- (void) fprintf b; \
- c; \
- } \
- while (0)
-#define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;)
-
-/* re_printstr():
- * Print a string on the debugging pty
- */
-private void
-re_printstr(EditLine *el, char *str, char *f, char *t)
-{
-
- ELRE_DEBUG(1, (__F, "%s:\"", str));
- while (f < t)
- ELRE_DEBUG(1, (__F, "%c", *f++ & 0177));
- ELRE_DEBUG(1, (__F, "\"\r\n"));
-}
-#else
-#define ELRE_ASSERT(a, b, c)
-#define ELRE_DEBUG(a, b)
-#endif
-
-
-/* re_addc():
- * Draw c, expanding tabs, control chars etc.
- */
-private void
-re_addc(EditLine *el, int c)
-{
-
- if (isprint(c)) {
- re_putc(el, c, 1);
- return;
- }
- if (c == '\n') { /* expand the newline */
- int oldv = el->el_refresh.r_cursor.v;
- re_putc(el, '\0', 0); /* assure end of line */
- if (oldv == el->el_refresh.r_cursor.v) { /* XXX */
- el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
- el->el_refresh.r_cursor.v++;
- }
- return;
- }
- if (c == '\t') { /* expand the tab */
- for (;;) {
- re_putc(el, ' ', 1);
- if ((el->el_refresh.r_cursor.h & 07) == 0)
- break; /* go until tab stop */
- }
- } else if (iscntrl(c)) {
- re_putc(el, '^', 1);
- if (c == '\177')
- re_putc(el, '?', 1);
- else
- /* uncontrolify it; works only for iso8859-1 like sets */
- re_putc(el, (c | 0100), 1);
- } else {
- re_putc(el, '\\', 1);
- re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1);
- re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1);
- re_putc(el, (c & 07) + '0', 1);
- }
-}
-
-
-/* re_putc():
- * Draw the character given
- */
-protected void
-re_putc(EditLine *el, int c, int shift)
-{
-
- ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c));
-
- el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
- if (!shift)
- return;
-
- el->el_refresh.r_cursor.h++; /* advance to next place */
- if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
- el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
- /* assure end of line */
- el->el_refresh.r_cursor.h = 0; /* reset it. */
-
- /*
- * If we would overflow (input is longer than terminal size),
- * emulate scroll by dropping first line and shuffling the rest.
- * We do this via pointer shuffling - it's safe in this case
- * and we avoid memcpy().
- */
- if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
- int i, lins = el->el_term.t_size.v;
- char *firstline = el->el_vdisplay[0];
-
- for(i=1; i < lins; i++)
- el->el_vdisplay[i-1] = el->el_vdisplay[i];
-
- firstline[0] = '\0'; /* empty the string */
- el->el_vdisplay[i-1] = firstline;
- } else
- el->el_refresh.r_cursor.v++;
-
- ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
- (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
- el->el_refresh.r_cursor.v, el->el_term.t_size.v),
- abort());
- }
-}
-
-
-/* re_refresh():
- * draws the new virtual screen image from the current input
- * line, then goes line-by-line changing the real image to the new
- * virtual image. The routine to re-draw a line can be replaced
- * easily in hopes of a smarter one being placed there.
- */
-protected void
-re_refresh(EditLine *el)
-{
- int i, rhdiff;
- char *cp, *st;
- coord_t cur;
-#ifdef notyet
- size_t termsz;
-#endif
-
- ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%s:\r\n",
- el->el_line.buffer));
-
- /* reset the Drawing cursor */
- el->el_refresh.r_cursor.h = 0;
- el->el_refresh.r_cursor.v = 0;
-
- /* temporarily draw rprompt to calculate its size */
- prompt_print(el, EL_RPROMPT);
-
- /* reset the Drawing cursor */
- el->el_refresh.r_cursor.h = 0;
- el->el_refresh.r_cursor.v = 0;
-
- cur.h = -1; /* set flag in case I'm not set */
- cur.v = 0;
-
- prompt_print(el, EL_PROMPT);
-
- /* draw the current input buffer */
-#if notyet
- termsz = el->el_term.t_size.h * el->el_term.t_size.v;
- if (el->el_line.lastchar - el->el_line.buffer > termsz) {
- /*
- * If line is longer than terminal, process only part
- * of line which would influence display.
- */
- size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
-
- st = el->el_line.lastchar - rem
- - (termsz - (((rem / el->el_term.t_size.v) - 1)
- * el->el_term.t_size.v));
- } else
-#endif
- st = el->el_line.buffer;
-
- for (cp = st; cp < el->el_line.lastchar; cp++) {
- if (cp == el->el_line.cursor) {
- /* save for later */
- cur.h = el->el_refresh.r_cursor.h;
- cur.v = el->el_refresh.r_cursor.v;
- }
- re_addc(el, (unsigned char) *cp);
- }
-
- if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
- cur.h = el->el_refresh.r_cursor.h;
- cur.v = el->el_refresh.r_cursor.v;
- }
- rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h -
- el->el_rprompt.p_pos.h;
- if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
- !el->el_refresh.r_cursor.v && rhdiff > 1) {
- /*
- * have a right-hand side prompt that will fit
- * on the end of the first line with at least
- * one character gap to the input buffer.
- */
- while (--rhdiff > 0) /* pad out with spaces */
- re_putc(el, ' ', 1);
- prompt_print(el, EL_RPROMPT);
- } else {
- el->el_rprompt.p_pos.h = 0; /* flag "not using rprompt" */
- el->el_rprompt.p_pos.v = 0;
- }
-
- re_putc(el, '\0', 0); /* make line ended with NUL, no cursor shift */
-
- el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
-
- ELRE_DEBUG(1, (__F,
- "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
- el->el_term.t_size.h, el->el_refresh.r_cursor.h,
- el->el_refresh.r_cursor.v, el->el_vdisplay[0]));
-
- ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
- for (i = 0; i <= el->el_refresh.r_newcv; i++) {
- /* NOTE THAT re_update_line MAY CHANGE el_display[i] */
- re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
-
- /*
- * Copy the new line to be the current one, and pad out with
- * spaces to the full width of the terminal so that if we try
- * moving the cursor by writing the character that is at the
- * end of the screen line, it won't be a NUL or some old
- * leftover stuff.
- */
- re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
- (size_t) el->el_term.t_size.h);
- }
- ELRE_DEBUG(1, (__F,
- "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
- el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i));
-
- if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
- for (; i <= el->el_refresh.r_oldcv; i++) {
- term_move_to_line(el, i);
- term_move_to_char(el, 0);
- term_clear_EOL(el, (int) strlen(el->el_display[i]));
-#ifdef DEBUG_REFRESH
- term_overwrite(el, "C\b", 2);
-#endif /* DEBUG_REFRESH */
- el->el_display[i][0] = '\0';
- }
-
- el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
- ELRE_DEBUG(1, (__F,
- "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
- el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
- cur.h, cur.v));
- term_move_to_line(el, cur.v); /* go to where the cursor is */
- term_move_to_char(el, cur.h);
-}
-
-
-/* re_goto_bottom():
- * used to go to last used screen line
- */
-protected void
-re_goto_bottom(EditLine *el)
-{
-
- term_move_to_line(el, el->el_refresh.r_oldcv);
- term__putc('\r');
- term__putc('\n');
- re_clear_display(el);
- term__flush();
-}
-
-
-/* re_insert():
- * insert num characters of s into d (in front of the character)
- * at dat, maximum length of d is dlen
- */
-private void
-/*ARGSUSED*/
-re_insert(EditLine *el, char *d, int dat, int dlen, char *s, int num)
-{
- char *a, *b;
-
- if (num <= 0)
- return;
- if (num > dlen - dat)
- num = dlen - dat;
-
- ELRE_DEBUG(1,
- (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
- ELRE_DEBUG(1, (__F, "s == \"%s\"n", s));
-
- /* open up the space for num chars */
- if (num > 0) {
- b = d + dlen - 1;
- a = b - num;
- while (a >= &d[dat])
- *b-- = *a--;
- d[dlen] = '\0'; /* just in case */
- }
- ELRE_DEBUG(1, (__F,
- "re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
- ELRE_DEBUG(1, (__F, "s == \"%s\"n", s));
-
- /* copy the characters */
- for (a = d + dat; (a < d + dlen) && (num > 0); num--)
- *a++ = *s++;
-
- ELRE_DEBUG(1,
- (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
- num, dat, dlen, d, s));
- ELRE_DEBUG(1, (__F, "s == \"%s\"n", s));
-}
-
-
-/* re_delete():
- * delete num characters d at dat, maximum length of d is dlen
- */
-private void
-/*ARGSUSED*/
-re_delete(EditLine *el, char *d, int dat, int dlen, int num)
-{
- char *a, *b;
-
- if (num <= 0)
- return;
- if (dat + num >= dlen) {
- d[dat] = '\0';
- return;
- }
- ELRE_DEBUG(1,
- (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
-
- /* open up the space for num chars */
- if (num > 0) {
- b = d + dat;
- a = b + num;
- while (a < &d[dlen])
- *b++ = *a++;
- d[dlen] = '\0'; /* just in case */
- }
- ELRE_DEBUG(1,
- (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
-}
-
-
-/* re__strncopy():
- * Like strncpy without padding.
- */
-private void
-re__strncopy(char *a, char *b, size_t n)
-{
-
- while (n-- && *b)
- *a++ = *b++;
-}
-
-
-/*****************************************************************
- re_update_line() is based on finding the middle difference of each line
- on the screen; vis:
-
- /old first difference
- /beginning of line | /old last same /old EOL
- v v v v
-old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new: eddie> Oh, my little buggy says to me, as lurgid as
- ^ ^ ^ ^
- \beginning of line | \new last same \new end of line
- \new first difference
-
- all are character pointers for the sake of speed. Special cases for
- no differences, as well as for end of line additions must be handled.
-**************************************************************** */
-
-/* Minimum at which doing an insert it "worth it". This should be about
- * half the "cost" of going into insert mode, inserting a character, and
- * going back out. This should really be calculated from the termcap
- * data... For the moment, a good number for ANSI terminals.
- */
-#define MIN_END_KEEP 4
-
-private void
-re_update_line(EditLine *el, char *old, char *new, int i)
-{
- char *o, *n, *p, c;
- char *ofd, *ols, *oe, *nfd, *nls, *ne;
- char *osb, *ose, *nsb, *nse;
- int fx, sx;
-
- /*
- * find first diff
- */
- for (o = old, n = new; *o && (*o == *n); o++, n++)
- continue;
- ofd = o;
- nfd = n;
-
- /*
- * Find the end of both old and new
- */
- while (*o)
- o++;
- /*
- * Remove any trailing blanks off of the end, being careful not to
- * back up past the beginning.
- */
- while (ofd < o) {
- if (o[-1] != ' ')
- break;
- o--;
- }
- oe = o;
- *oe = '\0';
-
- while (*n)
- n++;
-
- /* remove blanks from end of new */
- while (nfd < n) {
- if (n[-1] != ' ')
- break;
- n--;
- }
- ne = n;
- *ne = '\0';
-
- /*
- * if no diff, continue to next line of redraw
- */
- if (*ofd == '\0' && *nfd == '\0') {
- ELRE_DEBUG(1, (__F, "no difference.\r\n"));
- return;
- }
- /*
- * find last same pointer
- */
- while ((o > ofd) && (n > nfd) && (*--o == *--n))
- continue;
- ols = ++o;
- nls = ++n;
-
- /*
- * find same begining and same end
- */
- osb = ols;
- nsb = nls;
- ose = ols;
- nse = nls;
-
- /*
- * case 1: insert: scan from nfd to nls looking for *ofd
- */
- if (*ofd) {
- for (c = *ofd, n = nfd; n < nls; n++) {
- if (c == *n) {
- for (o = ofd, p = n;
- p < nls && o < ols && *o == *p;
- o++, p++)
- continue;
- /*
- * if the new match is longer and it's worth
- * keeping, then we take it
- */
- if (((nse - nsb) < (p - n)) &&
- (2 * (p - n) > n - nfd)) {
- nsb = n;
- nse = p;
- osb = ofd;
- ose = o;
- }
- }
- }
- }
- /*
- * case 2: delete: scan from ofd to ols looking for *nfd
- */
- if (*nfd) {
- for (c = *nfd, o = ofd; o < ols; o++) {
- if (c == *o) {
- for (n = nfd, p = o;
- p < ols && n < nls && *p == *n;
- p++, n++)
- continue;
- /*
- * if the new match is longer and it's worth
- * keeping, then we take it
- */
- if (((ose - osb) < (p - o)) &&
- (2 * (p - o) > o - ofd)) {
- nsb = nfd;
- nse = n;
- osb = o;
- ose = p;
- }
- }
- }
- }
- /*
- * Pragmatics I: If old trailing whitespace or not enough characters to
- * save to be worth it, then don't save the last same info.
- */
- if ((oe - ols) < MIN_END_KEEP) {
- ols = oe;
- nls = ne;
- }
- /*
- * Pragmatics II: if the terminal isn't smart enough, make the data
- * dumber so the smart update doesn't try anything fancy
- */
-
- /*
- * fx is the number of characters we need to insert/delete: in the
- * beginning to bring the two same begins together
- */
- fx = (nsb - nfd) - (osb - ofd);
- /*
- * sx is the number of characters we need to insert/delete: in the
- * end to bring the two same last parts together
- */
- sx = (nls - nse) - (ols - ose);
-
- if (!EL_CAN_INSERT) {
- if (fx > 0) {
- osb = ols;
- ose = ols;
- nsb = nls;
- nse = nls;
- }
- if (sx > 0) {
- ols = oe;
- nls = ne;
- }
- if ((ols - ofd) < (nls - nfd)) {
- ols = oe;
- nls = ne;
- }
- }
- if (!EL_CAN_DELETE) {
- if (fx < 0) {
- osb = ols;
- ose = ols;
- nsb = nls;
- nse = nls;
- }
- if (sx < 0) {
- ols = oe;
- nls = ne;
- }
- if ((ols - ofd) > (nls - nfd)) {
- ols = oe;
- nls = ne;
- }
- }
- /*
- * Pragmatics III: make sure the middle shifted pointers are correct if
- * they don't point to anything (we may have moved ols or nls).
- */
- /* if the change isn't worth it, don't bother */
- /* was: if (osb == ose) */
- if ((ose - osb) < MIN_END_KEEP) {
- osb = ols;
- ose = ols;
- nsb = nls;
- nse = nls;
- }
- /*
- * Now that we are done with pragmatics we recompute fx, sx
- */
- fx = (nsb - nfd) - (osb - ofd);
- sx = (nls - nse) - (ols - ose);
-
- ELRE_DEBUG(1, (__F, "\n"));
- ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
- ofd - old, osb - old, ose - old, ols - old, oe - old));
- ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
- nfd - new, nsb - new, nse - new, nls - new, ne - new));
- ELRE_DEBUG(1, (__F,
- "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"));
- ELRE_DEBUG(1, (__F,
- "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"));
-#ifdef DEBUG_REFRESH
- re_printstr(el, "old- oe", old, oe);
- re_printstr(el, "new- ne", new, ne);
- re_printstr(el, "old-ofd", old, ofd);
- re_printstr(el, "new-nfd", new, nfd);
- re_printstr(el, "ofd-osb", ofd, osb);
- re_printstr(el, "nfd-nsb", nfd, nsb);
- re_printstr(el, "osb-ose", osb, ose);
- re_printstr(el, "nsb-nse", nsb, nse);
- re_printstr(el, "ose-ols", ose, ols);
- re_printstr(el, "nse-nls", nse, nls);
- re_printstr(el, "ols- oe", ols, oe);
- re_printstr(el, "nls- ne", nls, ne);
-#endif /* DEBUG_REFRESH */
-
- /*
- * el_cursor.v to this line i MUST be in this routine so that if we
- * don't have to change the line, we don't move to it. el_cursor.h to
- * first diff char
- */
- term_move_to_line(el, i);
-
- /*
- * at this point we have something like this:
- *
- * /old /ofd /osb /ose /ols /oe
- * v.....................v v..................v v........v
- * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
- * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
- * ^.....................^ ^..................^ ^........^
- * \new \nfd \nsb \nse \nls \ne
- *
- * fx is the difference in length between the chars between nfd and
- * nsb, and the chars between ofd and osb, and is thus the number of
- * characters to delete if < 0 (new is shorter than old, as above),
- * or insert (new is longer than short).
- *
- * sx is the same for the second differences.
- */
-
- /*
- * if we have a net insert on the first difference, AND inserting the
- * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
- * character (which is ne if nls != ne, otherwise is nse) off the edge
- * of the screen (el->el_term.t_size.h) else we do the deletes first
- * so that we keep everything we need to.
- */
-
- /*
- * if the last same is the same like the end, there is no last same
- * part, otherwise we want to keep the last same part set p to the
- * last useful old character
- */
- p = (ols != oe) ? oe : ose;
-
- /*
- * if (There is a diffence in the beginning) && (we need to insert
- * characters) && (the number of characters to insert is less than
- * the term width)
- * We need to do an insert!
- * else if (we need to delete characters)
- * We need to delete characters!
- * else
- * No insert or delete
- */
- if ((nsb != nfd) && fx > 0 &&
- ((p - old) + fx <= el->el_term.t_size.h)) {
- ELRE_DEBUG(1,
- (__F, "first diff insert at %d...\r\n", nfd - new));
- /*
- * Move to the first char to insert, where the first diff is.
- */
- term_move_to_char(el, nfd - new);
- /*
- * Check if we have stuff to keep at end
- */
- if (nsb != ne) {
- ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
- /*
- * insert fx chars of new starting at nfd
- */
- if (fx > 0) {
- ELRE_DEBUG(!EL_CAN_INSERT, (__F,
- "ERROR: cannot insert in early first diff\n"));
- term_insertwrite(el, nfd, fx);
- re_insert(el, old, ofd - old,
- el->el_term.t_size.h, nfd, fx);
- }
- /*
- * write (nsb-nfd) - fx chars of new starting at
- * (nfd + fx)
- */
- term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
- re__strncopy(ofd + fx, nfd + fx,
- (size_t) ((nsb - nfd) - fx));
- } else {
- ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
- /*
- * Done
- */
- return;
- }
- } else if (fx < 0) {
- ELRE_DEBUG(1,
- (__F, "first diff delete at %d...\r\n", ofd - old));
- /*
- * move to the first char to delete where the first diff is
- */
- term_move_to_char(el, ofd - old);
- /*
- * Check if we have stuff to save
- */
- if (osb != oe) {
- ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
- /*
- * fx is less than zero *always* here but we check
- * for code symmetry
- */
- if (fx < 0) {
- ELRE_DEBUG(!EL_CAN_DELETE, (__F,
- "ERROR: cannot delete in first diff\n"));
- term_deletechars(el, -fx);
- re_delete(el, old, ofd - old,
- el->el_term.t_size.h, -fx);
- }
- /*
- * write (nsb-nfd) chars of new starting at nfd
- */
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
-
- } else {
- ELRE_DEBUG(1, (__F,
- "but with nothing left to save\r\n"));
- /*
- * write (nsb-nfd) chars of new starting at nfd
- */
- term_overwrite(el, nfd, (nsb - nfd));
- ELRE_DEBUG(1, (__F,
- "cleareol %d\n", (oe - old) - (ne - new)));
- term_clear_EOL(el, (oe - old) - (ne - new));
- /*
- * Done
- */
- return;
- }
- } else
- fx = 0;
-
- if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) {
- ELRE_DEBUG(1, (__F,
- "second diff delete at %d...\r\n", (ose - old) + fx));
- /*
- * Check if we have stuff to delete
- */
- /*
- * fx is the number of characters inserted (+) or deleted (-)
- */
-
- term_move_to_char(el, (ose - old) + fx);
- /*
- * Check if we have stuff to save
- */
- if (ols != oe) {
- ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
- /*
- * Again a duplicate test.
- */
- if (sx < 0) {
- ELRE_DEBUG(!EL_CAN_DELETE, (__F,
- "ERROR: cannot delete in second diff\n"));
- term_deletechars(el, -sx);
- }
- /*
- * write (nls-nse) chars of new starting at nse
- */
- term_overwrite(el, nse, (nls - nse));
- } else {
- ELRE_DEBUG(1, (__F,
- "but with nothing left to save\r\n"));
- term_overwrite(el, nse, (nls - nse));
- ELRE_DEBUG(1, (__F,
- "cleareol %d\n", (oe - old) - (ne - new)));
- if ((oe - old) - (ne - new) != 0)
- term_clear_EOL(el, (oe - old) - (ne - new));
- }
- }
- /*
- * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
- */
- if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
- ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
- nfd - new));
-
- term_move_to_char(el, nfd - new);
- /*
- * Check if we have stuff to keep at the end
- */
- if (nsb != ne) {
- ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
- /*
- * We have to recalculate fx here because we set it
- * to zero above as a flag saying that we hadn't done
- * an early first insert.
- */
- fx = (nsb - nfd) - (osb - ofd);
- if (fx > 0) {
- /*
- * insert fx chars of new starting at nfd
- */
- ELRE_DEBUG(!EL_CAN_INSERT, (__F,
- "ERROR: cannot insert in late first diff\n"));
- term_insertwrite(el, nfd, fx);
- re_insert(el, old, ofd - old,
- el->el_term.t_size.h, nfd, fx);
- }
- /*
- * write (nsb-nfd) - fx chars of new starting at
- * (nfd + fx)
- */
- term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
- re__strncopy(ofd + fx, nfd + fx,
- (size_t) ((nsb - nfd) - fx));
- } else {
- ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
- }
- }
- /*
- * line is now NEW up to nse
- */
- if (sx >= 0) {
- ELRE_DEBUG(1, (__F,
- "second diff insert at %d...\r\n", nse - new));
- term_move_to_char(el, nse - new);
- if (ols != oe) {
- ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
- if (sx > 0) {
- /* insert sx chars of new starting at nse */
- ELRE_DEBUG(!EL_CAN_INSERT, (__F,
- "ERROR: cannot insert in second diff\n"));
- term_insertwrite(el, nse, sx);
- }
- /*
- * write (nls-nse) - sx chars of new starting at
- * (nse + sx)
- */
- term_overwrite(el, nse + sx, (nls - nse) - sx);
- } else {
- ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
- term_overwrite(el, nse, (nls - nse));
-
- /*
- * No need to do a clear-to-end here because we were
- * doing a second insert, so we will have over
- * written all of the old string.
- */
- }
- }
- ELRE_DEBUG(1, (__F, "done.\r\n"));
-}
-
-
-/* re__copy_and_pad():
- * Copy string and pad with spaces
- */
-private void
-re__copy_and_pad(char *dst, const char *src, size_t width)
-{
- int i;
-
- for (i = 0; i < width; i++) {
- if (*src == '\0')
- break;
- *dst++ = *src++;
- }
-
- for (; i < width; i++)
- *dst++ = ' ';
-
- *dst = '\0';
-}
-
-
-/* re_refresh_cursor():
- * Move to the new cursor position
- */
-protected void
-re_refresh_cursor(EditLine *el)
-{
- char *cp, c;
- int h, v, th;
-
- /* first we must find where the cursor is... */
- h = el->el_prompt.p_pos.h;
- v = el->el_prompt.p_pos.v;
- th = el->el_term.t_size.h; /* optimize for speed */
-
- /* do input buffer to el->el_line.cursor */
- for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
- c = *cp;
- h++; /* all chars at least this long */
-
- if (c == '\n') {/* handle newline in data part too */
- h = 0;
- v++;
- } else {
- if (c == '\t') { /* if a tab, to next tab stop */
- while (h & 07) {
- h++;
- }
- } else if (iscntrl((unsigned char) c)) {
- /* if control char */
- h++;
- if (h > th) { /* if overflow, compensate */
- h = 1;
- v++;
- }
- } else if (!isprint((unsigned char) c)) {
- h += 3;
- if (h > th) { /* if overflow, compensate */
- h = h - th;
- v++;
- }
- }
- }
-
- if (h >= th) { /* check, extra long tabs picked up here also */
- h = 0;
- v++;
- }
- }
-
- /* now go there */
- term_move_to_line(el, v);
- term_move_to_char(el, h);
- term__flush();
-}
-
-
-/* re_fastputc():
- * Add a character fast.
- */
-private void
-re_fastputc(EditLine *el, int c)
-{
-
- term__putc(c);
- el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
- if (el->el_cursor.h >= el->el_term.t_size.h) {
- /* if we must overflow */
- el->el_cursor.h = 0;
-
- /*
- * If we would overflow (input is longer than terminal size),
- * emulate scroll by dropping first line and shuffling the rest.
- * We do this via pointer shuffling - it's safe in this case
- * and we avoid memcpy().
- */
- if (el->el_cursor.v + 1 >= el->el_term.t_size.v) {
- int i, lins = el->el_term.t_size.v;
- char *firstline = el->el_display[0];
-
- for(i=1; i < lins; i++)
- el->el_display[i-1] = el->el_display[i];
-
- re__copy_and_pad(firstline, "", 0);
- el->el_display[i-1] = firstline;
- } else {
- el->el_cursor.v++;
- el->el_refresh.r_oldcv++;
- }
- if (EL_HAS_AUTO_MARGINS) {
- if (EL_HAS_MAGIC_MARGINS) {
- term__putc(' ');
- term__putc('\b');
- }
- } else {
- term__putc('\r');
- term__putc('\n');
- }
- }
-}
-
-
-/* re_fastaddc():
- * we added just one char, handle it fast.
- * Assumes that screen cursor == real cursor
- */
-protected void
-re_fastaddc(EditLine *el)
-{
- char c;
- int rhdiff;
-
- c = el->el_line.cursor[-1];
-
- if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
- re_refresh(el); /* too hard to handle */
- return;
- }
- rhdiff = el->el_term.t_size.h - el->el_cursor.h -
- el->el_rprompt.p_pos.h;
- if (el->el_rprompt.p_pos.h && rhdiff < 3) {
- re_refresh(el); /* clear out rprompt if less than 1 char gap */
- return;
- } /* else (only do at end of line, no TAB) */
- if (iscntrl((unsigned char) c)) { /* if control char, do caret */
- char mc = (c == '\177') ? '?' : (c | 0100);
- re_fastputc(el, '^');
- re_fastputc(el, mc);
- } else if (isprint((unsigned char) c)) { /* normal char */
- re_fastputc(el, c);
- } else {
- re_fastputc(el, '\\');
- re_fastputc(el, (int) ((((unsigned int) c >> 6) & 7) + '0'));
- re_fastputc(el, (int) ((((unsigned int) c >> 3) & 7) + '0'));
- re_fastputc(el, (c & 7) + '0');
- }
- term__flush();
-}
-
-
-/* re_clear_display():
- * clear the screen buffers so that new new prompt starts fresh.
- */
-protected void
-re_clear_display(EditLine *el)
-{
- int i;
-
- el->el_cursor.v = 0;
- el->el_cursor.h = 0;
- for (i = 0; i < el->el_term.t_size.v; i++)
- el->el_display[i][0] = '\0';
- el->el_refresh.r_oldcv = 0;
-}
-
-
-/* re_clear_lines():
- * Make sure all lines are *really* blank
- */
-protected void
-re_clear_lines(EditLine *el)
-{
-
- if (EL_CAN_CEOL) {
- int i;
- term_move_to_char(el, 0);
- for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
- /* for each line on the screen */
- term_move_to_line(el, i);
- term_clear_EOL(el, el->el_term.t_size.h);
- }
- term_move_to_line(el, 0);
- } else {
- term_move_to_line(el, el->el_refresh.r_oldcv);
- /* go to last line */
- term__putc('\r'); /* go to BOL */
- term__putc('\n'); /* go to new line */
- }
-}
diff --git a/1.4/main/editline/refresh.h b/1.4/main/editline/refresh.h
deleted file mode 100644
index 33c0887c1..000000000
--- a/1.4/main/editline/refresh.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* $NetBSD: refresh.h,v 1.4 2001/01/10 07:45:42 jdolecek Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)refresh.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.refresh.h: Screen refresh functions
- */
-#ifndef _h_el_refresh
-#define _h_el_refresh
-
-#include "histedit.h"
-
-typedef struct {
- coord_t r_cursor; /* Refresh cursor position */
- int r_oldcv; /* Vertical locations */
- int r_newcv;
-} el_refresh_t;
-
-protected void re_putc(EditLine *, int, int);
-protected void re_clear_lines(EditLine *);
-protected void re_clear_display(EditLine *);
-protected void re_refresh(EditLine *);
-protected void re_refresh_cursor(EditLine *);
-protected void re_fastaddc(EditLine *);
-protected void re_goto_bottom(EditLine *);
-
-#endif /* _h_el_refresh */
diff --git a/1.4/main/editline/search.c b/1.4/main/editline/search.c
deleted file mode 100644
index 7c1cb84ef..000000000
--- a/1.4/main/editline/search.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/* $NetBSD: search.c,v 1.12 2002/03/18 16:00:58 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: search.c,v 1.12 2002/03/18 16:00:58 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * search.c: History and character search functions
- */
-#include <stdlib.h>
-#if defined(REGEX)
-#include <regex.h>
-#elif defined(REGEXP)
-#include <regexp.h>
-#endif
-#include "el.h"
-
-/*
- * Adjust cursor in vi mode to include the character under it
- */
-#define EL_CURSOR(el) \
- ((el)->el_line.cursor + (((el)->el_map.type == MAP_VI) && \
- ((el)->el_map.current == (el)->el_map.alt)))
-
-/* search_init():
- * Initialize the search stuff
- */
-protected int
-search_init(EditLine *el)
-{
-
- el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
- if (el->el_search.patbuf == NULL)
- return (-1);
- el->el_search.patlen = 0;
- el->el_search.patdir = -1;
- el->el_search.chacha = '\0';
- el->el_search.chadir = -1;
- return (0);
-}
-
-
-/* search_end():
- * Initialize the search stuff
- */
-protected void
-search_end(EditLine *el)
-{
-
- el_free((ptr_t) el->el_search.patbuf);
- el->el_search.patbuf = NULL;
-}
-
-
-#ifdef REGEXP
-/* regerror():
- * Handle regular expression errors
- */
-public void
-/*ARGSUSED*/
-regerror(const char *msg)
-{
-}
-#endif
-
-
-/* el_match():
- * Return if string matches pattern
- */
-protected int
-el_match(const char *str, const char *pat)
-{
-#if defined (REGEX)
- regex_t re;
- int rv;
-#elif defined (REGEXP)
- regexp *rp;
- int rv;
-#else
- extern char *re_comp(const char *);
- extern int re_exec(const char *);
-#endif
-
- if (strstr(str, pat) != NULL)
- return (1);
-
-#if defined(REGEX)
- if (regcomp(&re, pat, 0) == 0) {
- rv = regexec(&re, str, 0, NULL, 0) == 0;
- regfree(&re);
- } else {
- rv = 0;
- }
- return (rv);
-#elif defined(REGEXP)
- if ((re = regcomp(pat)) != NULL) {
- rv = regexec(re, str);
- free((ptr_t) re);
- } else {
- rv = 0;
- }
- return (rv);
-#else
- if (re_comp(pat) != NULL)
- return (0);
- else
- return (re_exec(str) == 1);
-#endif
-}
-
-
-/* c_hmatch():
- * return True if the pattern matches the prefix
- */
-protected int
-c_hmatch(EditLine *el, const char *str)
-{
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
- el->el_search.patbuf, str);
-#endif /* SDEBUG */
-
- return (el_match(str, el->el_search.patbuf));
-}
-
-
-/* c_setpat():
- * Set the history seatch pattern
- */
-protected void
-c_setpat(EditLine *el)
-{
- if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
- el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
- el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
- if (el->el_search.patlen >= EL_BUFSIZ)
- el->el_search.patlen = EL_BUFSIZ - 1;
- if (el->el_search.patlen != 0) {
- (void) strncpy(el->el_search.patbuf, el->el_line.buffer,
- el->el_search.patlen);
- el->el_search.patbuf[el->el_search.patlen] = '\0';
- } else
- el->el_search.patlen = strlen(el->el_search.patbuf);
- }
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "\neventno = %d\n",
- el->el_history.eventno);
- (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen);
- (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n",
- el->el_search.patbuf);
- (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n",
- EL_CURSOR(el) - el->el_line.buffer,
- el->el_line.lastchar - el->el_line.buffer);
-#endif
-}
-
-
-/* ce_inc_search():
- * Emacs incremental search
- */
-protected el_action_t
-ce_inc_search(EditLine *el, int dir)
-{
- static const char STRfwd[] = {'f', 'w', 'd', '\0'},
- STRbck[] = {'b', 'c', 'k', '\0'};
- static char pchar = ':';/* ':' = normal, '?' = failed */
- static char endcmd[2] = {'\0', '\0'};
- char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
- const char *cp;
-
- el_action_t ret = CC_NORM;
-
- int ohisteventno = el->el_history.eventno;
- int oldpatlen = el->el_search.patlen;
- int newdir = dir;
- int done, redo;
-
- if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
- el->el_search.patlen >= el->el_line.limit)
- return (CC_ERROR);
-
- for (;;) {
-
- if (el->el_search.patlen == 0) { /* first round */
- pchar = ':';
-#ifdef ANCHOR
- el->el_search.patbuf[el->el_search.patlen++] = '.';
- el->el_search.patbuf[el->el_search.patlen++] = '*';
-#endif
- }
- done = redo = 0;
- *el->el_line.lastchar++ = '\n';
- for (cp = (newdir == ED_SEARCH_PREV_HISTORY) ? STRbck : STRfwd;
- *cp; *el->el_line.lastchar++ = *cp++)
- continue;
- *el->el_line.lastchar++ = pchar;
- for (cp = &el->el_search.patbuf[1];
- cp < &el->el_search.patbuf[el->el_search.patlen];
- *el->el_line.lastchar++ = *cp++)
- continue;
- *el->el_line.lastchar = '\0';
- re_refresh(el);
-
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
-
- switch (el->el_map.current[(unsigned char) ch]) {
- case ED_INSERT:
- case ED_DIGIT:
- if (el->el_search.patlen > EL_BUFSIZ - 3)
- term_beep(el);
- else {
- el->el_search.patbuf[el->el_search.patlen++] =
- ch;
- *el->el_line.lastchar++ = ch;
- *el->el_line.lastchar = '\0';
- re_refresh(el);
- }
- break;
-
- case EM_INC_SEARCH_NEXT:
- newdir = ED_SEARCH_NEXT_HISTORY;
- redo++;
- break;
-
- case EM_INC_SEARCH_PREV:
- newdir = ED_SEARCH_PREV_HISTORY;
- redo++;
- break;
-
- case ED_DELETE_PREV_CHAR:
- if (el->el_search.patlen > 1)
- done++;
- else
- term_beep(el);
- break;
-
- default:
- switch (ch) {
- case 0007: /* ^G: Abort */
- ret = CC_ERROR;
- done++;
- break;
-
- case 0027: /* ^W: Append word */
- /* No can do if globbing characters in pattern */
- for (cp = &el->el_search.patbuf[1];; cp++)
- if (cp >= &el->el_search.patbuf[el->el_search.patlen]) {
- el->el_line.cursor +=
- el->el_search.patlen - 1;
- cp = c__next_word(el->el_line.cursor,
- el->el_line.lastchar, 1,
- ce__isword);
- while (el->el_line.cursor < cp &&
- *el->el_line.cursor != '\n') {
- if (el->el_search.patlen >
- EL_BUFSIZ - 3) {
- term_beep(el);
- break;
- }
- el->el_search.patbuf[el->el_search.patlen++] =
- *el->el_line.cursor;
- *el->el_line.lastchar++ =
- *el->el_line.cursor++;
- }
- el->el_line.cursor = ocursor;
- *el->el_line.lastchar = '\0';
- re_refresh(el);
- break;
- } else if (isglob(*cp)) {
- term_beep(el);
- break;
- }
- break;
-
- default: /* Terminate and execute cmd */
- endcmd[0] = ch;
- el_push(el, endcmd);
- /* FALLTHROUGH */
-
- case 0033: /* ESC: Terminate */
- ret = CC_REFRESH;
- done++;
- break;
- }
- break;
- }
-
- while (el->el_line.lastchar > el->el_line.buffer &&
- *el->el_line.lastchar != '\n')
- *el->el_line.lastchar-- = '\0';
- *el->el_line.lastchar = '\0';
-
- if (!done) {
-
- /* Can't search if unmatched '[' */
- for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
- ch = ']';
- cp > el->el_search.patbuf;
- cp--)
- if (*cp == '[' || *cp == ']') {
- ch = *cp;
- break;
- }
- if (el->el_search.patlen > 1 && ch != '[') {
- if (redo && newdir == dir) {
- if (pchar == '?') { /* wrap around */
- el->el_history.eventno =
- newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff;
- if (hist_get(el) == CC_ERROR)
- /* el->el_history.event
- * no was fixed by
- * first call */
- (void) hist_get(el);
- el->el_line.cursor = newdir ==
- ED_SEARCH_PREV_HISTORY ?
- el->el_line.lastchar :
- el->el_line.buffer;
- } else
- el->el_line.cursor +=
- newdir ==
- ED_SEARCH_PREV_HISTORY ?
- -1 : 1;
- }
-#ifdef ANCHOR
- el->el_search.patbuf[el->el_search.patlen++] =
- '.';
- el->el_search.patbuf[el->el_search.patlen++] =
- '*';
-#endif
- el->el_search.patbuf[el->el_search.patlen] =
- '\0';
- if (el->el_line.cursor < el->el_line.buffer ||
- el->el_line.cursor > el->el_line.lastchar ||
- (ret = ce_search_line(el,
- &el->el_search.patbuf[1],
- newdir)) == CC_ERROR) {
- /* avoid c_setpat */
- el->el_state.lastcmd =
- (el_action_t) newdir;
- ret = newdir == ED_SEARCH_PREV_HISTORY ?
- ed_search_prev_history(el, 0) :
- ed_search_next_history(el, 0);
- if (ret != CC_ERROR) {
- el->el_line.cursor = newdir ==
- ED_SEARCH_PREV_HISTORY ?
- el->el_line.lastchar :
- el->el_line.buffer;
- (void) ce_search_line(el,
- &el->el_search.patbuf[1],
- newdir);
- }
- }
- el->el_search.patbuf[--el->el_search.patlen] =
- '\0';
- if (ret == CC_ERROR) {
- term_beep(el);
- if (el->el_history.eventno !=
- ohisteventno) {
- el->el_history.eventno =
- ohisteventno;
- if (hist_get(el) == CC_ERROR)
- return (CC_ERROR);
- }
- el->el_line.cursor = ocursor;
- pchar = '?';
- } else {
- pchar = ':';
- }
- }
- ret = ce_inc_search(el, newdir);
-
- if (ret == CC_ERROR && pchar == '?' && oldpchar == ':')
- /*
- * break abort of failed search at last
- * non-failed
- */
- ret = CC_NORM;
-
- }
- if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) {
- /* restore on normal return or error exit */
- pchar = oldpchar;
- el->el_search.patlen = oldpatlen;
- if (el->el_history.eventno != ohisteventno) {
- el->el_history.eventno = ohisteventno;
- if (hist_get(el) == CC_ERROR)
- return (CC_ERROR);
- }
- el->el_line.cursor = ocursor;
- if (ret == CC_ERROR)
- re_refresh(el);
- }
- if (done || ret != CC_NORM)
- return (ret);
- }
-}
-
-
-/* cv_search():
- * Vi search.
- */
-protected el_action_t
-cv_search(EditLine *el, int dir)
-{
- char ch;
- char tmpbuf[EL_BUFSIZ];
- int tmplen;
-
- tmplen = 0;
-#ifdef ANCHOR
- tmpbuf[tmplen++] = '.';
- tmpbuf[tmplen++] = '*';
-#endif
-
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- el->el_search.patdir = dir;
-
- c_insert(el, 2); /* prompt + '\n' */
- *el->el_line.cursor++ = '\n';
- *el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?';
- re_refresh(el);
-
-#ifdef ANCHOR
-#define LEN 2
-#else
-#define LEN 0
-#endif
-
- tmplen = c_gets(el, &tmpbuf[LEN]) + LEN;
- ch = tmpbuf[tmplen];
- tmpbuf[tmplen] = '\0';
-
- if (tmplen == LEN) {
- /*
- * Use the old pattern, but wild-card it.
- */
- if (el->el_search.patlen == 0) {
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- re_refresh(el);
- return (CC_ERROR);
- }
-#ifdef ANCHOR
- if (el->el_search.patbuf[0] != '.' &&
- el->el_search.patbuf[0] != '*') {
- (void) strncpy(tmpbuf, el->el_search.patbuf,
- sizeof(tmpbuf) - 1);
- el->el_search.patbuf[0] = '.';
- el->el_search.patbuf[1] = '*';
- (void) strncpy(&el->el_search.patbuf[2], tmpbuf,
- EL_BUFSIZ - 3);
- el->el_search.patlen++;
- el->el_search.patbuf[el->el_search.patlen++] = '.';
- el->el_search.patbuf[el->el_search.patlen++] = '*';
- el->el_search.patbuf[el->el_search.patlen] = '\0';
- }
-#endif
- } else {
-#ifdef ANCHOR
- tmpbuf[tmplen++] = '.';
- tmpbuf[tmplen++] = '*';
-#endif
- tmpbuf[tmplen] = '\0';
- (void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
- el->el_search.patlen = tmplen;
- }
- el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
- el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
- if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
- ed_search_next_history(el, 0)) == CC_ERROR) {
- re_refresh(el);
- return (CC_ERROR);
- } else {
- if (ch == 0033) {
- re_refresh(el);
- *el->el_line.lastchar++ = '\n';
- *el->el_line.lastchar = '\0';
- re_goto_bottom(el);
- return (CC_NEWLINE);
- } else
- return (CC_REFRESH);
- }
-}
-
-
-/* ce_search_line():
- * Look for a pattern inside a line
- */
-protected el_action_t
-ce_search_line(EditLine *el, char *pattern, int dir)
-{
- char *cp;
-
- if (dir == ED_SEARCH_PREV_HISTORY) {
- for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--)
- if (el_match(cp, pattern)) {
- el->el_line.cursor = cp;
- return (CC_NORM);
- }
- return (CC_ERROR);
- } else {
- for (cp = el->el_line.cursor; *cp != '\0' &&
- cp < el->el_line.limit; cp++)
- if (el_match(cp, pattern)) {
- el->el_line.cursor = cp;
- return (CC_NORM);
- }
- return (CC_ERROR);
- }
-}
-
-
-/* cv_repeat_srch():
- * Vi repeat search
- */
-protected el_action_t
-cv_repeat_srch(EditLine *el, int c)
-{
-
-#ifdef SDEBUG
- (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
- c, el->el_search.patlen, el->el_search.patbuf);
-#endif
-
- el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
- el->el_line.lastchar = el->el_line.buffer;
-
- switch (c) {
- case ED_SEARCH_NEXT_HISTORY:
- return (ed_search_next_history(el, 0));
- case ED_SEARCH_PREV_HISTORY:
- return (ed_search_prev_history(el, 0));
- default:
- return (CC_ERROR);
- }
-}
-
-
-/* cv_csearch_back():
- * Vi character search reverse
- */
-protected el_action_t
-cv_csearch_back(EditLine *el, int ch, int count, int tflag)
-{
- char *cp;
-
- cp = el->el_line.cursor;
- while (count--) {
- if (*cp == ch)
- cp--;
- while (cp > el->el_line.buffer && *cp != ch)
- cp--;
- }
-
- if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch))
- return (CC_ERROR);
-
- if (*cp == ch && tflag)
- cp++;
-
- el->el_line.cursor = cp;
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- el->el_line.cursor++;
- cv_delfini(el);
- return (CC_REFRESH);
- }
- re_refresh_cursor(el);
- return (CC_NORM);
-}
-
-
-/* cv_csearch_fwd():
- * Vi character search forward
- */
-protected el_action_t
-cv_csearch_fwd(EditLine *el, int ch, int count, int tflag)
-{
- char *cp;
-
- cp = el->el_line.cursor;
- while (count--) {
- if (*cp == ch)
- cp++;
- while (cp < el->el_line.lastchar && *cp != ch)
- cp++;
- }
-
- if (cp >= el->el_line.lastchar)
- return (CC_ERROR);
-
- if (*cp == ch && tflag)
- cp--;
-
- el->el_line.cursor = cp;
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- el->el_line.cursor++;
- cv_delfini(el);
- return (CC_REFRESH);
- }
- re_refresh_cursor(el);
- return (CC_NORM);
-}
diff --git a/1.4/main/editline/search.h b/1.4/main/editline/search.h
deleted file mode 100644
index 676bbe2e3..000000000
--- a/1.4/main/editline/search.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* $NetBSD: search.h,v 1.5 2000/09/04 22:06:32 lukem Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)search.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.search.h: Line and history searching utilities
- */
-#ifndef _h_el_search
-#define _h_el_search
-
-#include "histedit.h"
-
-typedef struct el_search_t {
- char *patbuf; /* The pattern buffer */
- size_t patlen; /* Length of the pattern buffer */
- int patdir; /* Direction of the last search */
- int chadir; /* Character search direction */
- char chacha; /* Character we are looking for */
-} el_search_t;
-
-
-protected int el_match(const char *, const char *);
-protected int search_init(EditLine *);
-protected void search_end(EditLine *);
-protected int c_hmatch(EditLine *, const char *);
-protected void c_setpat(EditLine *);
-protected el_action_t ce_inc_search(EditLine *, int);
-protected el_action_t cv_search(EditLine *, int);
-protected el_action_t ce_search_line(EditLine *, char *, int);
-protected el_action_t cv_repeat_srch(EditLine *, int);
-protected el_action_t cv_csearch_back(EditLine *, int, int, int);
-protected el_action_t cv_csearch_fwd(EditLine *, int, int, int);
-
-#endif /* _h_el_search */
diff --git a/1.4/main/editline/sig.c b/1.4/main/editline/sig.c
deleted file mode 100644
index 0acba1247..000000000
--- a/1.4/main/editline/sig.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* $NetBSD: sig.c,v 1.9 2002/03/18 16:00:58 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: sig.c,v 1.9 2002/03/18 16:00:58 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * sig.c: Signal handling stuff.
- * our policy is to trap all signals, set a good state
- * and pass the ball to our caller.
- */
-#include "el.h"
-#include <stdlib.h>
-
-private EditLine *sel = NULL;
-
-private const int sighdl[] = {
-#define _DO(a) (a),
- ALLSIGS
-#undef _DO
- - 1
-};
-
-private void sig_handler(int);
-
-/* sig_handler():
- * This is the handler called for all signals
- * XXX: we cannot pass any data so we just store the old editline
- * state in a private variable
- */
-private void
-sig_handler(int signo)
-{
- int i;
- sigset_t nset, oset;
-
- (void) sigemptyset(&nset);
- (void) sigaddset(&nset, signo);
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
-
- switch (signo) {
- case SIGCONT:
- tty_rawmode(sel);
- if (ed_redisplay(sel, 0) == CC_REFRESH)
- re_refresh(sel);
- term__flush();
- break;
-
- case SIGWINCH:
- el_resize(sel);
- break;
-
- default:
- tty_cookedmode(sel);
- break;
- }
-
- for (i = 0; sighdl[i] != -1; i++)
- if (signo == sighdl[i])
- break;
-
- (void) signal(signo, sel->el_signal[i]);
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
- (void) kill(0, signo);
-}
-
-
-/* sig_init():
- * Initialize all signal stuff
- */
-protected int
-sig_init(EditLine *el)
-{
- int i;
- sigset_t nset, oset;
-
- (void) sigemptyset(&nset);
-#define _DO(a) (void) sigaddset(&nset, a);
- ALLSIGS
-#undef _DO
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
-
-#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
-
- el->el_signal = (sig_t *) el_malloc(SIGSIZE);
- if (el->el_signal == NULL)
- return (-1);
- for (i = 0; sighdl[i] != -1; i++)
- el->el_signal[i] = SIG_ERR;
-
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
-
- return (0);
-}
-
-
-/* sig_end():
- * Clear all signal stuff
- */
-protected void
-sig_end(EditLine *el)
-{
-
- el_free((ptr_t) el->el_signal);
- el->el_signal = NULL;
-}
-
-
-/* sig_set():
- * set all the signal handlers
- */
-protected void
-sig_set(EditLine *el)
-{
- int i;
- sigset_t nset, oset;
-
- (void) sigemptyset(&nset);
-#define _DO(a) (void) sigaddset(&nset, a);
- ALLSIGS
-#undef _DO
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
-
- for (i = 0; sighdl[i] != -1; i++) {
- sig_t s;
- /* This could happen if we get interrupted */
- if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
- el->el_signal[i] = s;
- }
- sel = el;
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
-}
-
-
-/* sig_clr():
- * clear all the signal handlers
- */
-protected void
-sig_clr(EditLine *el)
-{
- int i;
- sigset_t nset, oset;
-
- (void) sigemptyset(&nset);
-#define _DO(a) (void) sigaddset(&nset, a);
- ALLSIGS
-#undef _DO
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
-
- for (i = 0; sighdl[i] != -1; i++)
- if (el->el_signal[i] != SIG_ERR)
- (void) signal(sighdl[i], el->el_signal[i]);
-
- sel = NULL; /* we are going to die if the handler is
- * called */
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
-}
diff --git a/1.4/main/editline/sig.h b/1.4/main/editline/sig.h
deleted file mode 100644
index e7231b65c..000000000
--- a/1.4/main/editline/sig.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $NetBSD: sig.h,v 1.3 2000/09/04 22:06:32 lukem Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)sig.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.sig.h: Signal handling functions
- */
-#ifndef _h_el_sig
-#define _h_el_sig
-
-#include <signal.h>
-
-#include "histedit.h"
-
-/*
- * Define here all the signals we are going to handle
- * The _DO macro is used to iterate in the source code
- */
-#define ALLSIGS \
- _DO(SIGINT) \
- _DO(SIGTSTP) \
- _DO(SIGSTOP) \
- _DO(SIGQUIT) \
- _DO(SIGHUP) \
- _DO(SIGTERM) \
- _DO(SIGCONT) \
- _DO(SIGWINCH)
-
-typedef sig_t *el_signal_t;
-
-protected void sig_end(EditLine*);
-protected int sig_init(EditLine*);
-protected void sig_set(EditLine*);
-protected void sig_clr(EditLine*);
-
-#endif /* _h_el_sig */
diff --git a/1.4/main/editline/sys.h b/1.4/main/editline/sys.h
deleted file mode 100644
index a306d1df7..000000000
--- a/1.4/main/editline/sys.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $NetBSD: sys.h,v 1.5 2002/03/18 16:00:59 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)sys.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * sys.h: Put all the stupid compiler and system dependencies here...
- */
-#ifndef _h_sys
-#define _h_sys
-
-#ifndef public
-# define public /* Externally visible functions/variables */
-#endif
-
-#ifndef private
-# define private static /* Always hidden internals */
-#endif
-
-#ifndef protected
-# define protected /* Redefined from elsewhere to "static" */
- /* When we want to hide everything */
-#endif
-
-#ifndef _PTR_T
-# define _PTR_T
-typedef void *ptr_t;
-#endif
-
-#ifndef _IOCTL_T
-# define _IOCTL_T
-typedef void *ioctl_t;
-#endif
-
-#include <stdio.h>
-
-#ifndef HAVE_STRLCAT
-#define strlcat libedit_strlcat
-size_t strlcat(char *dst, const char *src, size_t size);
-#endif
-
-#ifndef HAVE_STRLCPY
-#define strlcpy libedit_strlcpy
-size_t strlcpy(char *dst, const char *src, size_t size);
-#endif
-
-#ifndef HAVE_FGETLN
-#define fgetln libedit_fgetln
-char *fgetln(FILE *fp, size_t *len);
-#endif
-
-#define REGEX /* Use POSIX.2 regular expression functions */
-#undef REGEXP /* Use UNIX V8 regular expression functions */
-
-#ifdef SUNOS
-# undef REGEX
-# undef REGEXP
-# include <malloc.h>
-typedef void (*sig_t)(int);
-# ifdef __GNUC__
-/*
- * Broken hdrs.
- */
-#ifndef SOLARIS
-extern int tgetent(const char *bp, char *name);
-extern int tgetflag(const char *id);
-extern int tgetnum(const char *id);
-extern char *tgetstr(const char *id, char **area);
-#endif
-extern char *tgoto(const char *cap, int col, int row);
-extern int tputs(const char *str, int affcnt, int (*putc)(int));
-extern char *getenv(const char *);
-extern int fprintf(FILE *, const char *, ...);
-extern int sigsetmask(int);
-extern int sigblock(int);
-extern int fputc(int, FILE *);
-extern int fgetc(FILE *);
-extern int fflush(FILE *);
-extern int tolower(int);
-extern int toupper(int);
-extern int errno, sys_nerr;
-extern char *sys_errlist[];
-extern void perror(const char *);
-# include <string.h>
-# define strerror(e) sys_errlist[e]
-# endif
-# ifdef SABER
-extern ptr_t memcpy(ptr_t, const ptr_t, size_t);
-extern ptr_t memset(ptr_t, int, size_t);
-# endif
-extern char *fgetline(FILE *, int *);
-#endif
-
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-#endif /* _h_sys */
diff --git a/1.4/main/editline/term.c b/1.4/main/editline/term.c
deleted file mode 100644
index fb627cabb..000000000
--- a/1.4/main/editline/term.c
+++ /dev/null
@@ -1,1587 +0,0 @@
-/* $NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
-#else
-__RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * term.c: Editor/termcap-curses interface
- * We have to declare a static variable here, since the
- * termcap putchar routine does not take an argument!
- */
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#ifdef HAVE_TERMCAP_H
-#include <termcap.h>
-#endif
-#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
-#endif
-#if defined(HAVE_TERM_H)
-#include "term.h"
-/* Can not use /usr/include/term.h because of a lot of incompatibilities, so just define some prototypes */
-extern int tgetent(char *, const char *);
-extern int tgetflag(const char *);
-extern int tgetnum(const char *);
-extern char *tgetstr(const char *, char **);
-extern int tputs (const char *, int, int (*)(int));
-extern char *tgoto (const char *, int, int);
-#endif /* defined(HAVE_TERM_H) */
-#include <sys/types.h>
-#include <sys/ioctl.h>
-
-#include "el.h"
-
-/*
- * IMPORTANT NOTE: these routines are allowed to look at the current screen
- * and the current possition assuming that it is correct. If this is not
- * true, then the update will be WRONG! This is (should be) a valid
- * assumption...
- */
-
-#define TC_BUFSIZE 2048
-
-#define GoodStr(a) (el->el_term.t_str[a] != NULL && \
- el->el_term.t_str[a][0] != '\0')
-#define Str(a) el->el_term.t_str[a]
-#define Val(a) el->el_term.t_val[a]
-
-#ifdef notdef
-private const struct {
- const char *b_name;
- int b_rate;
-} baud_rate[] = {
-#ifdef B0
- { "0", B0 },
-#endif
-#ifdef B50
- { "50", B50 },
-#endif
-#ifdef B75
- { "75", B75 },
-#endif
-#ifdef B110
- { "110", B110 },
-#endif
-#ifdef B134
- { "134", B134 },
-#endif
-#ifdef B150
- { "150", B150 },
-#endif
-#ifdef B200
- { "200", B200 },
-#endif
-#ifdef B300
- { "300", B300 },
-#endif
-#ifdef B600
- { "600", B600 },
-#endif
-#ifdef B900
- { "900", B900 },
-#endif
-#ifdef B1200
- { "1200", B1200 },
-#endif
-#ifdef B1800
- { "1800", B1800 },
-#endif
-#ifdef B2400
- { "2400", B2400 },
-#endif
-#ifdef B3600
- { "3600", B3600 },
-#endif
-#ifdef B4800
- { "4800", B4800 },
-#endif
-#ifdef B7200
- { "7200", B7200 },
-#endif
-#ifdef B9600
- { "9600", B9600 },
-#endif
-#ifdef EXTA
- { "19200", EXTA },
-#endif
-#ifdef B19200
- { "19200", B19200 },
-#endif
-#ifdef EXTB
- { "38400", EXTB },
-#endif
-#ifdef B38400
- { "38400", B38400 },
-#endif
- { NULL, 0 }
-};
-#endif
-
-private const struct termcapstr {
- const char *name;
- const char *long_name;
-} tstr[] = {
-#define T_al 0
- { "al", "add new blank line" },
-#define T_bl 1
- { "bl", "audible bell" },
-#define T_cd 2
- { "cd", "clear to bottom" },
-#define T_ce 3
- { "ce", "clear to end of line" },
-#define T_ch 4
- { "ch", "cursor to horiz pos" },
-#define T_cl 5
- { "cl", "clear screen" },
-#define T_dc 6
- { "dc", "delete a character" },
-#define T_dl 7
- { "dl", "delete a line" },
-#define T_dm 8
- { "dm", "start delete mode" },
-#define T_ed 9
- { "ed", "end delete mode" },
-#define T_ei 10
- { "ei", "end insert mode" },
-#define T_fs 11
- { "fs", "cursor from status line" },
-#define T_ho 12
- { "ho", "home cursor" },
-#define T_ic 13
- { "ic", "insert character" },
-#define T_im 14
- { "im", "start insert mode" },
-#define T_ip 15
- { "ip", "insert padding" },
-#define T_kd 16
- { "kd", "sends cursor down" },
-#define T_kl 17
- { "kl", "sends cursor left" },
-#define T_kr 18
- { "kr", "sends cursor right" },
-#define T_ku 19
- { "ku", "sends cursor up" },
-#define T_md 20
- { "md", "begin bold" },
-#define T_me 21
- { "me", "end attributes" },
-#define T_nd 22
- { "nd", "non destructive space" },
-#define T_se 23
- { "se", "end standout" },
-#define T_so 24
- { "so", "begin standout" },
-#define T_ts 25
- { "ts", "cursor to status line" },
-#define T_up 26
- { "up", "cursor up one" },
-#define T_us 27
- { "us", "begin underline" },
-#define T_ue 28
- { "ue", "end underline" },
-#define T_vb 29
- { "vb", "visible bell" },
-#define T_DC 30
- { "DC", "delete multiple chars" },
-#define T_DO 31
- { "DO", "cursor down multiple" },
-#define T_IC 32
- { "IC", "insert multiple chars" },
-#define T_LE 33
- { "LE", "cursor left multiple" },
-#define T_RI 34
- { "RI", "cursor right multiple" },
-#define T_UP 35
- { "UP", "cursor up multiple" },
-#define T_kh 36
- { "kh", "send cursor home" },
-#define T_at7 37
- { "@7", "send cursor end" },
-#define T_str 38
- { NULL, NULL }
-};
-
-private const struct termcapval {
- const char *name;
- const char *long_name;
-} tval[] = {
-#define T_am 0
- { "am", "has automatic margins" },
-#define T_pt 1
- { "pt", "has physical tabs" },
-#define T_li 2
- { "li", "Number of lines" },
-#define T_co 3
- { "co", "Number of columns" },
-#define T_km 4
- { "km", "Has meta key" },
-#define T_xt 5
- { "xt", "Tab chars destructive" },
-#define T_xn 6
- { "xn", "newline ignored at right margin" },
-#define T_MT 7
- { "MT", "Has meta key" }, /* XXX? */
-#define T_val 8
- { NULL, NULL, }
-};
-/* do two or more of the attributes use me */
-
-private void term_setflags(EditLine *);
-private int term_rebuffer_display(EditLine *);
-private void term_free_display(EditLine *);
-private int term_alloc_display(EditLine *);
-private void term_alloc(EditLine *, const struct termcapstr *, const char *);
-private void term_init_arrow(EditLine *);
-private void term_reset_arrow(EditLine *);
-
-
-private FILE *term_outfile = NULL; /* XXX: How do we fix that? */
-
-
-/* term_setflags():
- * Set the terminal capability flags
- */
-private void
-term_setflags(EditLine *el)
-{
- EL_FLAGS = 0;
- if (el->el_tty.t_tabs)
- EL_FLAGS |= (Val(T_pt) && !Val(T_xt)) ? TERM_CAN_TAB : 0;
-
- EL_FLAGS |= (Val(T_km) || Val(T_MT)) ? TERM_HAS_META : 0;
- EL_FLAGS |= GoodStr(T_ce) ? TERM_CAN_CEOL : 0;
- EL_FLAGS |= (GoodStr(T_dc) || GoodStr(T_DC)) ? TERM_CAN_DELETE : 0;
- EL_FLAGS |= (GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC)) ?
- TERM_CAN_INSERT : 0;
- EL_FLAGS |= (GoodStr(T_up) || GoodStr(T_UP)) ? TERM_CAN_UP : 0;
- EL_FLAGS |= Val(T_am) ? TERM_HAS_AUTO_MARGINS : 0;
- EL_FLAGS |= Val(T_xn) ? TERM_HAS_MAGIC_MARGINS : 0;
-
- if (GoodStr(T_me) && GoodStr(T_ue))
- EL_FLAGS |= (strcmp(Str(T_me), Str(T_ue)) == 0) ?
- TERM_CAN_ME : 0;
- else
- EL_FLAGS &= ~TERM_CAN_ME;
- if (GoodStr(T_me) && GoodStr(T_se))
- EL_FLAGS |= (strcmp(Str(T_me), Str(T_se)) == 0) ?
- TERM_CAN_ME : 0;
-
-
-#ifdef DEBUG_SCREEN
- if (!EL_CAN_UP) {
- (void) fprintf(el->el_errfile,
- "WARNING: Your terminal cannot move up.\n");
- (void) fprintf(el->el_errfile,
- "Editing may be odd for long lines.\n");
- }
- if (!EL_CAN_CEOL)
- (void) fprintf(el->el_errfile, "no clear EOL capability.\n");
- if (!EL_CAN_DELETE)
- (void) fprintf(el->el_errfile, "no delete char capability.\n");
- if (!EL_CAN_INSERT)
- (void) fprintf(el->el_errfile, "no insert char capability.\n");
-#endif /* DEBUG_SCREEN */
-}
-
-
-/* term_init():
- * Initialize the terminal stuff
- */
-protected int
-term_init(EditLine *el)
-{
-
- el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE);
- if (el->el_term.t_buf == NULL)
- return (-1);
- el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE);
- if (el->el_term.t_cap == NULL)
- return (-1);
- el->el_term.t_fkey = (fkey_t *) el_malloc(A_K_NKEYS * sizeof(fkey_t));
- if (el->el_term.t_fkey == NULL)
- return (-1);
- el->el_term.t_loc = 0;
- el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char *));
- if (el->el_term.t_str == NULL)
- return (-1);
- (void) memset(el->el_term.t_str, 0, T_str * sizeof(char *));
- el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int));
- if (el->el_term.t_val == NULL)
- return (-1);
- (void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
- term_outfile = el->el_outfile;
- (void) term_set(el, NULL);
- term_init_arrow(el);
- return (0);
-}
-/* term_end():
- * Clean up the terminal stuff
- */
-protected void
-term_end(EditLine *el)
-{
-
- el_free((ptr_t) el->el_term.t_buf);
- el->el_term.t_buf = NULL;
- el_free((ptr_t) el->el_term.t_cap);
- el->el_term.t_cap = NULL;
- el_free((ptr_t) el->el_term.t_fkey);
- el->el_term.t_fkey = NULL;
- el->el_term.t_loc = 0;
- el_free((ptr_t) el->el_term.t_str);
- el->el_term.t_str = NULL;
- el_free((ptr_t) el->el_term.t_val);
- el->el_term.t_val = NULL;
- term_free_display(el);
-}
-
-
-/* term_alloc():
- * Maintain a string pool for termcap strings
- */
-private void
-term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
-{
- char termbuf[TC_BUFSIZE];
- int tlen, clen;
- char **tlist = el->el_term.t_str;
- char **tmp, **str = &tlist[t - tstr];
-
- if (cap == NULL || *cap == '\0') {
- *str = NULL;
- return;
- } else
- clen = strlen(cap);
-
- tlen = *str == NULL ? 0 : strlen(*str);
-
- /*
- * New string is shorter; no need to allocate space
- */
- if (clen <= tlen) {
- (void) strcpy(*str, cap); /* XXX strcpy is safe */
- return;
- }
- /*
- * New string is longer; see if we have enough space to append
- */
- if (el->el_term.t_loc + 3 < TC_BUFSIZE) {
- /* XXX strcpy is safe */
- (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc],
- cap);
- el->el_term.t_loc += clen + 1; /* one for \0 */
- return;
- }
- /*
- * Compact our buffer; no need to check compaction, cause we know it
- * fits...
- */
- tlen = 0;
- for (tmp = tlist; tmp < &tlist[T_str]; tmp++)
- if (*tmp != NULL && *tmp != '\0' && *tmp != *str) {
- char *ptr;
-
- for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++)
- continue;
- termbuf[tlen++] = '\0';
- }
- memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE);
- el->el_term.t_loc = tlen;
- if (el->el_term.t_loc + 3 >= TC_BUFSIZE) {
- (void) fprintf(el->el_errfile,
- "Out of termcap string space.\n");
- return;
- }
- /* XXX strcpy is safe */
- (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap);
- el->el_term.t_loc += clen + 1; /* one for \0 */
- return;
-}
-
-
-/* term_rebuffer_display():
- * Rebuffer the display after the screen changed size
- */
-private int
-term_rebuffer_display(EditLine *el)
-{
- coord_t *c = &el->el_term.t_size;
-
- term_free_display(el);
-
- c->h = Val(T_co);
- c->v = Val(T_li);
-
- if (term_alloc_display(el) == -1)
- return (-1);
- return (0);
-}
-
-
-/* term_alloc_display():
- * Allocate a new display.
- */
-private int
-term_alloc_display(EditLine *el)
-{
- int i;
- char **b;
- coord_t *c = &el->el_term.t_size;
-
- b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
- if (b == NULL)
- return (-1);
- for (i = 0; i < c->v; i++) {
- b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
- if (b[i] == NULL)
- return (-1);
- }
- b[c->v] = NULL;
- el->el_display = b;
-
- b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
- if (b == NULL)
- return (-1);
- for (i = 0; i < c->v; i++) {
- b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
- if (b[i] == NULL)
- return (-1);
- }
- b[c->v] = NULL;
- el->el_vdisplay = b;
- return (0);
-}
-
-
-/* term_free_display():
- * Free the display buffers
- */
-private void
-term_free_display(EditLine *el)
-{
- char **b;
- char **bufp;
-
- b = el->el_display;
- el->el_display = NULL;
- if (b != NULL) {
- for (bufp = b; *bufp != NULL; bufp++)
- el_free((ptr_t) * bufp);
- el_free((ptr_t) b);
- }
- b = el->el_vdisplay;
- el->el_vdisplay = NULL;
- if (b != NULL) {
- for (bufp = b; *bufp != NULL; bufp++)
- el_free((ptr_t) * bufp);
- el_free((ptr_t) b);
- }
-}
-
-
-/* term_move_to_line():
- * move to line <where> (first line == 0)
- * as efficiently as possible
- */
-protected void
-term_move_to_line(EditLine *el, int where)
-{
- int del;
-
- if (where == el->el_cursor.v)
- return;
-
- if (where > el->el_term.t_size.v) {
-#ifdef DEBUG_SCREEN
- (void) fprintf(el->el_errfile,
- "term_move_to_line: where is ridiculous: %d\r\n", where);
-#endif /* DEBUG_SCREEN */
- return;
- }
- if ((del = where - el->el_cursor.v) > 0) {
- while (del > 0) {
- if (EL_HAS_AUTO_MARGINS &&
- el->el_display[el->el_cursor.v][0] != '\0') {
- /* move without newline */
- term_move_to_char(el, el->el_term.t_size.h - 1);
- term_overwrite(el,
- &el->el_display[el->el_cursor.v][el->el_cursor.h],
- 1);
- /* updates Cursor */
- del--;
- } else {
- if ((del > 1) && GoodStr(T_DO)) {
- (void) tputs(tgoto(Str(T_DO), del, del),
- del, term__putc);
- del = 0;
- } else {
- for (; del > 0; del--)
- term__putc('\n');
- /* because the \n will become \r\n */
- el->el_cursor.h = 0;
- }
- }
- }
- } else { /* del < 0 */
- if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
- (void) tputs(tgoto(Str(T_UP), -del, -del), -del,
- term__putc);
- else {
- if (GoodStr(T_up))
- for (; del < 0; del++)
- (void) tputs(Str(T_up), 1, term__putc);
- }
- }
- el->el_cursor.v = where;/* now where is here */
-}
-
-
-/* term_move_to_char():
- * Move to the character position specified
- */
-protected void
-term_move_to_char(EditLine *el, int where)
-{
- int del, i;
-
-mc_again:
- if (where == el->el_cursor.h)
- return;
-
- if (where > el->el_term.t_size.h) {
-#ifdef DEBUG_SCREEN
- (void) fprintf(el->el_errfile,
- "term_move_to_char: where is riduculous: %d\r\n", where);
-#endif /* DEBUG_SCREEN */
- return;
- }
- if (!where) { /* if where is first column */
- term__putc('\r'); /* do a CR */
- el->el_cursor.h = 0;
- return;
- }
- del = where - el->el_cursor.h;
-
- if ((del < -4 || del > 4) && GoodStr(T_ch))
- /* go there directly */
- (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc);
- else {
- if (del > 0) { /* moving forward */
- if ((del > 4) && GoodStr(T_RI))
- (void) tputs(tgoto(Str(T_RI), del, del),
- del, term__putc);
- else {
- /* if I can do tabs, use them */
- if (EL_CAN_TAB) {
- if ((el->el_cursor.h & 0370) !=
- (where & 0370)) {
- /* if not within tab stop */
- for (i =
- (el->el_cursor.h & 0370);
- i < (where & 0370);
- i += 8)
- term__putc('\t');
- /* then tab over */
- el->el_cursor.h = where & 0370;
- }
- }
- /*
- * it's usually cheaper to just write the
- * chars, so we do.
- */
- /*
- * NOTE THAT term_overwrite() WILL CHANGE
- * el->el_cursor.h!!!
- */
- term_overwrite(el,
- &el->el_display[el->el_cursor.v][el->el_cursor.h],
- where - el->el_cursor.h);
-
- }
- } else { /* del < 0 := moving backward */
- if ((-del > 4) && GoodStr(T_LE))
- (void) tputs(tgoto(Str(T_LE), -del, -del),
- -del, term__putc);
- else { /* can't go directly there */
- /*
- * if the "cost" is greater than the "cost"
- * from col 0
- */
- if (EL_CAN_TAB ?
- (-del > (((unsigned int) where >> 3) +
- (where & 07)))
- : (-del > where)) {
- term__putc('\r'); /* do a CR */
- el->el_cursor.h = 0;
- goto mc_again; /* and try again */
- }
- for (i = 0; i < -del; i++)
- term__putc('\b');
- }
- }
- }
- el->el_cursor.h = where; /* now where is here */
-}
-
-
-/* term_overwrite():
- * Overstrike num characters
- */
-protected void
-term_overwrite(EditLine *el, const char *cp, int n)
-{
- if (n <= 0)
- return; /* catch bugs */
-
- if (n > el->el_term.t_size.h) {
-#ifdef DEBUG_SCREEN
- (void) fprintf(el->el_errfile,
- "term_overwrite: n is riduculous: %d\r\n", n);
-#endif /* DEBUG_SCREEN */
- return;
- }
- do {
- term__putc(*cp++);
- el->el_cursor.h++;
- } while (--n);
-
- if (el->el_cursor.h >= el->el_term.t_size.h) { /* wrap? */
- if (EL_HAS_AUTO_MARGINS) { /* yes */
- el->el_cursor.h = 0;
- el->el_cursor.v++;
- if (EL_HAS_MAGIC_MARGINS) {
- /* force the wrap to avoid the "magic"
- * situation */
- char c;
- if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h])
- != '\0')
- term_overwrite(el, &c, 1);
- else
- term__putc(' ');
- el->el_cursor.h = 1;
- }
- } else /* no wrap, but cursor stays on screen */
- el->el_cursor.h = el->el_term.t_size.h;
- }
-}
-
-
-/* term_deletechars():
- * Delete num characters
- */
-protected void
-term_deletechars(EditLine *el, int num)
-{
- if (num <= 0)
- return;
-
- if (!EL_CAN_DELETE) {
-#ifdef DEBUG_EDIT
- (void) fprintf(el->el_errfile, " ERROR: cannot delete \n");
-#endif /* DEBUG_EDIT */
- return;
- }
- if (num > el->el_term.t_size.h) {
-#ifdef DEBUG_SCREEN
- (void) fprintf(el->el_errfile,
- "term_deletechars: num is riduculous: %d\r\n", num);
-#endif /* DEBUG_SCREEN */
- return;
- }
- if (GoodStr(T_DC)) /* if I have multiple delete */
- if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more
- * expen. */
- (void) tputs(tgoto(Str(T_DC), num, num),
- num, term__putc);
- return;
- }
- if (GoodStr(T_dm)) /* if I have delete mode */
- (void) tputs(Str(T_dm), 1, term__putc);
-
- if (GoodStr(T_dc)) /* else do one at a time */
- while (num--)
- (void) tputs(Str(T_dc), 1, term__putc);
-
- if (GoodStr(T_ed)) /* if I have delete mode */
- (void) tputs(Str(T_ed), 1, term__putc);
-}
-
-
-/* term_insertwrite():
- * Puts terminal in insert character mode or inserts num
- * characters in the line
- */
-protected void
-term_insertwrite(EditLine *el, char *cp, int num)
-{
- if (num <= 0)
- return;
- if (!EL_CAN_INSERT) {
-#ifdef DEBUG_EDIT
- (void) fprintf(el->el_errfile, " ERROR: cannot insert \n");
-#endif /* DEBUG_EDIT */
- return;
- }
- if (num > el->el_term.t_size.h) {
-#ifdef DEBUG_SCREEN
- (void) fprintf(el->el_errfile,
- "StartInsert: num is riduculous: %d\r\n", num);
-#endif /* DEBUG_SCREEN */
- return;
- }
- if (GoodStr(T_IC)) /* if I have multiple insert */
- if ((num > 1) || !GoodStr(T_ic)) {
- /* if ic would be more expensive */
- (void) tputs(tgoto(Str(T_IC), num, num),
- num, term__putc);
- term_overwrite(el, cp, num);
- /* this updates el_cursor.h */
- return;
- }
- if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
- (void) tputs(Str(T_im), 1, term__putc);
-
- el->el_cursor.h += num;
- do
- term__putc(*cp++);
- while (--num);
-
- if (GoodStr(T_ip)) /* have to make num chars insert */
- (void) tputs(Str(T_ip), 1, term__putc);
-
- (void) tputs(Str(T_ei), 1, term__putc);
- return;
- }
- do {
- if (GoodStr(T_ic)) /* have to make num chars insert */
- (void) tputs(Str(T_ic), 1, term__putc);
- /* insert a char */
-
- term__putc(*cp++);
-
- el->el_cursor.h++;
-
- if (GoodStr(T_ip)) /* have to make num chars insert */
- (void) tputs(Str(T_ip), 1, term__putc);
- /* pad the inserted char */
-
- } while (--num);
-}
-
-
-/* term_clear_EOL():
- * clear to end of line. There are num characters to clear
- */
-protected void
-term_clear_EOL(EditLine *el, int num)
-{
- int i;
-
- if (EL_CAN_CEOL && GoodStr(T_ce))
- (void) tputs(Str(T_ce), 1, term__putc);
- else {
- for (i = 0; i < num; i++)
- term__putc(' ');
- el->el_cursor.h += num; /* have written num spaces */
- }
-}
-
-
-/* term_clear_screen():
- * Clear the screen
- */
-protected void
-term_clear_screen(EditLine *el)
-{ /* clear the whole screen and home */
-
- if (GoodStr(T_cl))
- /* send the clear screen code */
- (void) tputs(Str(T_cl), Val(T_li), term__putc);
- else if (GoodStr(T_ho) && GoodStr(T_cd)) {
- (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */
- /* clear to bottom of screen */
- (void) tputs(Str(T_cd), Val(T_li), term__putc);
- } else {
- term__putc('\r');
- term__putc('\n');
- }
-}
-
-
-/* term_beep():
- * Beep the way the terminal wants us
- */
-protected void
-term_beep(EditLine *el)
-{
- if (GoodStr(T_bl))
- /* what termcap says we should use */
- (void) tputs(Str(T_bl), 1, term__putc);
- else
- term__putc('\007'); /* an ASCII bell; ^G */
-}
-
-
-#ifdef notdef
-/* term_clear_to_bottom():
- * Clear to the bottom of the screen
- */
-protected void
-term_clear_to_bottom(EditLine *el)
-{
- if (GoodStr(T_cd))
- (void) tputs(Str(T_cd), Val(T_li), term__putc);
- else if (GoodStr(T_ce))
- (void) tputs(Str(T_ce), Val(T_li), term__putc);
-}
-#endif
-
-
-/* term_set():
- * Read in the terminal capabilities from the requested terminal
- */
-protected int
-term_set(EditLine *el, const char *term)
-{
- int i;
- char buf[TC_BUFSIZE];
- char *area;
- const struct termcapstr *t;
- sigset_t oset, nset;
- int lins, cols;
-
- (void) sigemptyset(&nset);
- (void) sigaddset(&nset, SIGWINCH);
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
-
- area = buf;
-
-
- if (term == NULL)
- term = getenv("TERM");
-
- if (!term || !term[0])
- term = "dumb";
-
- if (strcmp(term, "emacs") == 0)
- el->el_flags |= EDIT_DISABLED;
-
- memset(el->el_term.t_cap, 0, TC_BUFSIZE);
-
- i = tgetent(el->el_term.t_cap, term);
-
- if (i <= 0) {
- if (i == -1)
- (void) fprintf(el->el_errfile,
- "Cannot read termcap database;\n");
- else if (i == 0)
- (void) fprintf(el->el_errfile,
- "No entry for terminal type \"%s\";\n", term);
- (void) fprintf(el->el_errfile,
- "using dumb terminal settings.\n");
- Val(T_co) = 80; /* do a dumb terminal */
- Val(T_pt) = Val(T_km) = Val(T_li) = 0;
- Val(T_xt) = Val(T_MT);
- for (t = tstr; t->name != NULL; t++)
- term_alloc(el, t, NULL);
- } else {
- /* auto/magic margins */
- Val(T_am) = tgetflag("am");
- Val(T_xn) = tgetflag("xn");
- /* Can we tab */
- Val(T_pt) = tgetflag("pt");
- Val(T_xt) = tgetflag("xt");
- /* do we have a meta? */
- Val(T_km) = tgetflag("km");
- Val(T_MT) = tgetflag("MT");
- /* Get the size */
- Val(T_co) = tgetnum("co");
- Val(T_li) = tgetnum("li");
- for (t = tstr; t->name != NULL; t++)
- term_alloc(el, t, tgetstr((char *)t->name, &area));
- }
-
- if (Val(T_co) < 2)
- Val(T_co) = 80; /* just in case */
- if (Val(T_li) < 1)
- Val(T_li) = 24;
-
- el->el_term.t_size.v = Val(T_co);
- el->el_term.t_size.h = Val(T_li);
-
- term_setflags(el);
-
- /* get the correct window size */
- (void) term_get_size(el, &lins, &cols);
- if (term_change_size(el, lins, cols) == -1)
- return (-1);
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
- term_bind_arrow(el);
- return (i <= 0 ? -1 : 0);
-}
-
-
-/* term_get_size():
- * Return the new window size in lines and cols, and
- * true if the size was changed.
- */
-protected int
-term_get_size(EditLine *el, int *lins, int *cols)
-{
-
- *cols = Val(T_co);
- *lins = Val(T_li);
-
-#ifdef TIOCGWINSZ
- {
- struct winsize ws;
- if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) & ws) != -1) {
- if (ws.ws_col)
- *cols = ws.ws_col;
- if (ws.ws_row)
- *lins = ws.ws_row;
- }
- }
-#endif
-#ifdef TIOCGSIZE
- {
- struct ttysize ts;
- if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) & ts) != -1) {
- if (ts.ts_cols)
- *cols = ts.ts_cols;
- if (ts.ts_lines)
- *lins = ts.ts_lines;
- }
- }
-#endif
- return (Val(T_co) != *cols || Val(T_li) != *lins);
-}
-
-
-/* term_change_size():
- * Change the size of the terminal
- */
-protected int
-term_change_size(EditLine *el, int lins, int cols)
-{
- /*
- * Just in case
- */
- Val(T_co) = (cols < 2) ? 80 : cols;
- Val(T_li) = (lins < 1) ? 24 : lins;
-
- /* re-make display buffers */
- if (term_rebuffer_display(el) == -1)
- return (-1);
- re_clear_display(el);
- return (0);
-}
-
-
-/* term_init_arrow():
- * Initialize the arrow key bindings from termcap
- */
-private void
-term_init_arrow(EditLine *el)
-{
- fkey_t *arrow = el->el_term.t_fkey;
-
- arrow[A_K_DN].name = "down";
- arrow[A_K_DN].key = T_kd;
- arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY;
- arrow[A_K_DN].type = XK_CMD;
-
- arrow[A_K_UP].name = "up";
- arrow[A_K_UP].key = T_ku;
- arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY;
- arrow[A_K_UP].type = XK_CMD;
-
- arrow[A_K_LT].name = "left";
- arrow[A_K_LT].key = T_kl;
- arrow[A_K_LT].fun.cmd = ED_PREV_CHAR;
- arrow[A_K_LT].type = XK_CMD;
-
- arrow[A_K_RT].name = "right";
- arrow[A_K_RT].key = T_kr;
- arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR;
- arrow[A_K_RT].type = XK_CMD;
-
- arrow[A_K_HO].name = "home";
- arrow[A_K_HO].key = T_kh;
- arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG;
- arrow[A_K_HO].type = XK_CMD;
-
- arrow[A_K_EN].name = "end";
- arrow[A_K_EN].key = T_at7;
- arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END;
- arrow[A_K_EN].type = XK_CMD;
-}
-
-
-/* term_reset_arrow():
- * Reset arrow key bindings
- */
-private void
-term_reset_arrow(EditLine *el)
-{
- fkey_t *arrow = el->el_term.t_fkey;
- static const char strA[] = {033, '[', 'A', '\0'};
- static const char strB[] = {033, '[', 'B', '\0'};
- static const char strC[] = {033, '[', 'C', '\0'};
- static const char strD[] = {033, '[', 'D', '\0'};
- static const char strH[] = {033, '[', 'H', '\0'};
- static const char strF[] = {033, '[', 'F', '\0'};
- static const char stOA[] = {033, 'O', 'A', '\0'};
- static const char stOB[] = {033, 'O', 'B', '\0'};
- static const char stOC[] = {033, 'O', 'C', '\0'};
- static const char stOD[] = {033, 'O', 'D', '\0'};
- static const char stOH[] = {033, 'O', 'H', '\0'};
- static const char stOF[] = {033, 'O', 'F', '\0'};
-
- key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
-
- if (el->el_map.type == MAP_VI) {
- key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- }
-}
-
-
-/* term_set_arrow():
- * Set an arrow key binding
- */
-protected int
-term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type)
-{
- fkey_t *arrow = el->el_term.t_fkey;
- int i;
-
- for (i = 0; i < A_K_NKEYS; i++)
- if (strcmp(name, arrow[i].name) == 0) {
- arrow[i].fun = *fun;
- arrow[i].type = type;
- return (0);
- }
- return (-1);
-}
-
-
-/* term_clear_arrow():
- * Clear an arrow key binding
- */
-protected int
-term_clear_arrow(EditLine *el, const char *name)
-{
- fkey_t *arrow = el->el_term.t_fkey;
- int i;
-
- for (i = 0; i < A_K_NKEYS; i++)
- if (strcmp(name, arrow[i].name) == 0) {
- arrow[i].type = XK_NOD;
- return (0);
- }
- return (-1);
-}
-
-
-/* term_print_arrow():
- * Print the arrow key bindings
- */
-protected void
-term_print_arrow(EditLine *el, const char *name)
-{
- int i;
- fkey_t *arrow = el->el_term.t_fkey;
-
- for (i = 0; i < A_K_NKEYS; i++)
- if (*name == '\0' || strcmp(name, arrow[i].name) == 0)
- if (arrow[i].type != XK_NOD)
- key_kprint(el, arrow[i].name, &arrow[i].fun,
- arrow[i].type);
-}
-
-
-/* term_bind_arrow():
- * Bind the arrow keys
- */
-protected void
-term_bind_arrow(EditLine *el)
-{
- el_action_t *map;
- const el_action_t *dmap;
- int i, j;
- char *p;
- fkey_t *arrow = el->el_term.t_fkey;
-
- /* Check if the components needed are initialized */
- if (el->el_term.t_buf == NULL || el->el_map.key == NULL)
- return;
-
- map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key;
- dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs;
-
- term_reset_arrow(el);
-
- for (i = 0; i < A_K_NKEYS; i++) {
- p = el->el_term.t_str[arrow[i].key];
- if (p && *p) {
- j = (unsigned char) *p;
- /*
- * Assign the arrow keys only if:
- *
- * 1. They are multi-character arrow keys and the user
- * has not re-assigned the leading character, or
- * has re-assigned the leading character to be
- * ED_SEQUENCE_LEAD_IN
- * 2. They are single arrow keys pointing to an
- * unassigned key.
- */
- if (arrow[i].type == XK_NOD)
- key_clear(el, map, p);
- else {
- if (p[1] && (dmap[j] == map[j] ||
- map[j] == ED_SEQUENCE_LEAD_IN)) {
- key_add(el, p, &arrow[i].fun,
- arrow[i].type);
- map[j] = ED_SEQUENCE_LEAD_IN;
- } else if (map[j] == ED_UNASSIGNED) {
- key_clear(el, map, p);
- if (arrow[i].type == XK_CMD)
- map[j] = arrow[i].fun.cmd;
- else
- key_add(el, p, &arrow[i].fun,
- arrow[i].type);
- }
- }
- }
- }
-}
-
-
-/* term__putc():
- * Add a character
- */
-protected int
-term__putc(int c)
-{
-
- return (fputc(c, term_outfile));
-}
-
-
-/* term__flush():
- * Flush output
- */
-protected void
-term__flush(void)
-{
-
- (void) fflush(term_outfile);
-}
-
-
-/* term_telltc():
- * Print the current termcap characteristics
- */
-protected int
-/*ARGSUSED*/
-term_telltc(EditLine *el, int argc, const char **argv)
-{
- const struct termcapstr *t;
- char **ts;
- char upbuf[EL_BUFSIZ];
-
- (void) fprintf(el->el_outfile, "\n\tYour terminal has the\n");
- (void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n");
- (void) fprintf(el->el_outfile, "\tIt has %d columns and %d lines\n",
- Val(T_co), Val(T_li));
- (void) fprintf(el->el_outfile,
- "\tIt has %s meta key\n", EL_HAS_META ? "a" : "no");
- (void) fprintf(el->el_outfile,
- "\tIt can%suse tabs\n", EL_CAN_TAB ? " " : "not ");
- (void) fprintf(el->el_outfile, "\tIt %s automatic margins\n",
- EL_HAS_AUTO_MARGINS ? "has" : "does not have");
- if (EL_HAS_AUTO_MARGINS)
- (void) fprintf(el->el_outfile, "\tIt %s magic margins\n",
- EL_HAS_MAGIC_MARGINS ? "has" : "does not have");
-
- for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++)
- (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
- t->long_name,
- t->name, *ts && **ts ?
- key__decode_str(*ts, upbuf, "") : "(empty)");
- (void) fputc('\n', el->el_outfile);
- return (0);
-}
-
-
-/* term_settc():
- * Change the current terminal characteristics
- */
-protected int
-/*ARGSUSED*/
-term_settc(EditLine *el, int argc, const char **argv)
-{
- const struct termcapstr *ts;
- const struct termcapval *tv;
- const char *what, *how;
-
- if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
- return (-1);
-
- what = argv[1];
- how = argv[2];
-
- /*
- * Do the strings first
- */
- for (ts = tstr; ts->name != NULL; ts++)
- if (strcmp(ts->name, what) == 0)
- break;
-
- if (ts->name != NULL) {
- term_alloc(el, ts, how);
- term_setflags(el);
- return (0);
- }
- /*
- * Do the numeric ones second
- */
- for (tv = tval; tv->name != NULL; tv++)
- if (strcmp(tv->name, what) == 0)
- break;
-
- if (tv->name != NULL) {
- if (tv == &tval[T_pt] || tv == &tval[T_km] ||
- tv == &tval[T_am] || tv == &tval[T_xn]) {
- if (strcmp(how, "yes") == 0)
- el->el_term.t_val[tv - tval] = 1;
- else if (strcmp(how, "no") == 0)
- el->el_term.t_val[tv - tval] = 0;
- else {
- (void) fprintf(el->el_errfile,
- "settc: Bad value `%s'.\n", how);
- return (-1);
- }
- term_setflags(el);
- if (term_change_size(el, Val(T_li), Val(T_co)) == -1)
- return (-1);
- return (0);
- } else {
- long i;
- char *ep;
-
- i = strtol(how, &ep, 10);
- if (*ep != '\0') {
- (void) fprintf(el->el_errfile,
- "settc: Bad value `%s'.\n", how);
- return (-1);
- }
- el->el_term.t_val[tv - tval] = (int) i;
- el->el_term.t_size.v = Val(T_co);
- el->el_term.t_size.h = Val(T_li);
- if (tv == &tval[T_co] || tv == &tval[T_li])
- if (term_change_size(el, Val(T_li), Val(T_co))
- == -1)
- return (-1);
- return (0);
- }
- }
- return (-1);
-}
-
-
-/* term_echotc():
- * Print the termcap string out with variable substitution
- */
-protected int
-/*ARGSUSED*/
-term_echotc(EditLine *el, int argc, const char **argv)
-{
- char *cap, *scap, *ep;
- int arg_need, arg_cols, arg_rows;
- int verbose = 0, silent = 0;
- char *area;
- static const char fmts[] = "%s\n", fmtd[] = "%d\n";
- const struct termcapstr *t;
- char buf[TC_BUFSIZE];
- long i;
-
- area = buf;
-
- if (argv == NULL || argv[1] == NULL)
- return (-1);
- argv++;
-
- if (argv[0][0] == '-') {
- switch (argv[0][1]) {
- case 'v':
- verbose = 1;
- break;
- case 's':
- silent = 1;
- break;
- default:
- /* stderror(ERR_NAME | ERR_TCUSAGE); */
- break;
- }
- argv++;
- }
- if (!*argv || *argv[0] == '\0')
- return (0);
- if (strcmp(*argv, "tabs") == 0) {
- (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no");
- return (0);
- } else if (strcmp(*argv, "meta") == 0) {
- (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no");
- return (0);
- } else if (strcmp(*argv, "xn") == 0) {
- (void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ?
- "yes" : "no");
- return (0);
- } else if (strcmp(*argv, "am") == 0) {
- (void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ?
- "yes" : "no");
- return (0);
- } else if (strcmp(*argv, "baud") == 0) {
-#ifdef notdef
- int i;
-
- for (i = 0; baud_rate[i].b_name != NULL; i++)
- if (el->el_tty.t_speed == baud_rate[i].b_rate) {
- (void) fprintf(el->el_outfile, fmts,
- baud_rate[i].b_name);
- return (0);
- }
- (void) fprintf(el->el_outfile, fmtd, 0);
-#else
- (void) fprintf(el->el_outfile, fmtd, (int) el->el_tty.t_speed);
-#endif
- return (0);
- } else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
- (void) fprintf(el->el_outfile, fmtd, Val(T_li));
- return (0);
- } else if (strcmp(*argv, "cols") == 0) {
- (void) fprintf(el->el_outfile, fmtd, Val(T_co));
- return (0);
- }
- /*
- * Try to use our local definition first
- */
- scap = NULL;
- for (t = tstr; t->name != NULL; t++)
- if (strcmp(t->name, *argv) == 0) {
- scap = el->el_term.t_str[t - tstr];
- break;
- }
- if (t->name == NULL)
- scap = tgetstr((char *)argv, &area);
- if (!scap || scap[0] == '\0') {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Termcap parameter `%s' not found.\n",
- *argv);
- return (-1);
- }
- /*
- * Count home many values we need for this capability.
- */
- for (cap = scap, arg_need = 0; *cap; cap++)
- if (*cap == '%')
- switch (*++cap) {
- case 'd':
- case '2':
- case '3':
- case '.':
- case '+':
- arg_need++;
- break;
- case '%':
- case '>':
- case 'i':
- case 'r':
- case 'n':
- case 'B':
- case 'D':
- break;
- default:
- /*
- * hpux has lot's of them...
- */
- if (verbose)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: unknown termcap %% `%c'.\n",
- *cap);
- /* This is bad, but I won't complain */
- break;
- }
-
- switch (arg_need) {
- case 0:
- argv++;
- if (*argv && *argv[0]) {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Extra argument `%s'.\n",
- *argv);
- return (-1);
- }
- (void) tputs(scap, 1, term__putc);
- break;
- case 1:
- argv++;
- if (!*argv || *argv[0] == '\0') {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Missing argument.\n");
- return (-1);
- }
- arg_cols = 0;
- i = strtol(*argv, &ep, 10);
- if (*ep != '\0' || i < 0) {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Bad value `%s' for rows.\n",
- *argv);
- return (-1);
- }
- arg_rows = (int) i;
- argv++;
- if (*argv && *argv[0]) {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Extra argument `%s'.\n",
- *argv);
- return (-1);
- }
- (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc);
- break;
- default:
- /* This is wrong, but I will ignore it... */
- if (verbose)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Too many required arguments (%d).\n",
- arg_need);
- /* FALLTHROUGH */
- case 2:
- argv++;
- if (!*argv || *argv[0] == '\0') {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Missing argument.\n");
- return (-1);
- }
- i = strtol(*argv, &ep, 10);
- if (*ep != '\0' || i < 0) {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Bad value `%s' for cols.\n",
- *argv);
- return (-1);
- }
- arg_cols = (int) i;
- argv++;
- if (!*argv || *argv[0] == '\0') {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Missing argument.\n");
- return (-1);
- }
- i = strtol(*argv, &ep, 10);
- if (*ep != '\0' || i < 0) {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Bad value `%s' for rows.\n",
- *argv);
- return (-1);
- }
- arg_rows = (int) i;
- if (*ep != '\0') {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Bad value `%s'.\n", *argv);
- return (-1);
- }
- argv++;
- if (*argv && *argv[0]) {
- if (!silent)
- (void) fprintf(el->el_errfile,
- "echotc: Warning: Extra argument `%s'.\n",
- *argv);
- return (-1);
- }
- (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows,
- term__putc);
- break;
- }
- return (0);
-}
diff --git a/1.4/main/editline/term.h b/1.4/main/editline/term.h
deleted file mode 100644
index 47e08e84b..000000000
--- a/1.4/main/editline/term.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $NetBSD: term.h,v 1.13 2002/03/18 16:01:00 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)term.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.term.h: Termcap header
- */
-#ifndef _h_el_term
-#define _h_el_term
-
-#include "histedit.h"
-
-typedef struct { /* Symbolic function key bindings */
- const char *name; /* name of the key */
- int key; /* Index in termcap table */
- key_value_t fun; /* Function bound to it */
- int type; /* Type of function */
-} fkey_t;
-
-typedef struct {
- coord_t t_size; /* # lines and cols */
- int t_flags;
-#define TERM_CAN_INSERT 0x001 /* Has insert cap */
-#define TERM_CAN_DELETE 0x002 /* Has delete cap */
-#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */
-#define TERM_CAN_TAB 0x008 /* Can use tabs */
-#define TERM_CAN_ME 0x010 /* Can turn all attrs. */
-#define TERM_CAN_UP 0x020 /* Can move up */
-#define TERM_HAS_META 0x040 /* Has a meta key */
-#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
-#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
- char *t_buf; /* Termcap buffer */
- int t_loc; /* location used */
- char **t_str; /* termcap strings */
- int *t_val; /* termcap values */
- char *t_cap; /* Termcap buffer */
- fkey_t *t_fkey; /* Array of keys */
-} el_term_t;
-
-/*
- * fKey indexes
- */
-#define A_K_DN 0
-#define A_K_UP 1
-#define A_K_LT 2
-#define A_K_RT 3
-#define A_K_HO 4
-#define A_K_EN 5
-#define A_K_NKEYS 6
-
-protected void term_move_to_line(EditLine *, int);
-protected void term_move_to_char(EditLine *, int);
-protected void term_clear_EOL(EditLine *, int);
-protected void term_overwrite(EditLine *, const char *, int);
-protected void term_insertwrite(EditLine *, char *, int);
-protected void term_deletechars(EditLine *, int);
-protected void term_clear_screen(EditLine *);
-protected void term_beep(EditLine *);
-protected int term_change_size(EditLine *, int, int);
-protected int term_get_size(EditLine *, int *, int *);
-protected int term_init(EditLine *);
-protected void term_bind_arrow(EditLine *);
-protected void term_print_arrow(EditLine *, const char *);
-protected int term_clear_arrow(EditLine *, const char *);
-protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
-protected void term_end(EditLine *);
-protected int term_set(EditLine *, const char *);
-protected int term_settc(EditLine *, int, const char **);
-protected int term_telltc(EditLine *, int, const char **);
-protected int term_echotc(EditLine *, int, const char **);
-protected int term__putc(int);
-protected void term__flush(void);
-
-/*
- * Easy access macros
- */
-#define EL_FLAGS (el)->el_term.t_flags
-
-#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
-#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
-#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL)
-#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB)
-#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME)
-#define EL_HAS_META (EL_FLAGS & TERM_HAS_META)
-#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
-#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
-
-#endif /* _h_el_term */
diff --git a/1.4/main/editline/tokenizer.c b/1.4/main/editline/tokenizer.c
deleted file mode 100644
index f0de39bc9..000000000
--- a/1.4/main/editline/tokenizer.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/* $NetBSD: tokenizer.c,v 1.10 2002/03/18 16:01:00 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: tokenizer.c,v 1.10 2002/03/18 16:01:00 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * tokenize.c: Bourne shell like tokenizer
- */
-#include <string.h>
-#include <stdlib.h>
-#include "tokenizer.h"
-
-typedef enum {
- Q_none, Q_single, Q_double, Q_one, Q_doubleone
-} quote_t;
-
-#define IFS "\t \n"
-
-#define TOK_KEEP 1
-#define TOK_EAT 2
-
-#define WINCR 20
-#define AINCR 10
-
-#define tok_malloc(a) malloc(a)
-#define tok_free(a) free(a)
-#define tok_realloc(a, b) realloc(a, b)
-
-
-struct tokenizer {
- char *ifs; /* In field separator */
- int argc, amax; /* Current and maximum number of args */
- char **argv; /* Argument list */
- char *wptr, *wmax; /* Space and limit on the word buffer */
- char *wstart; /* Beginning of next word */
- char *wspace; /* Space of word buffer */
- quote_t quote; /* Quoting state */
- int flags; /* flags; */
-};
-
-
-private void tok_finish(Tokenizer *);
-
-
-/* tok_finish():
- * Finish a word in the tokenizer.
- */
-private void
-tok_finish(Tokenizer *tok)
-{
-
- *tok->wptr = '\0';
- if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) {
- tok->argv[tok->argc++] = tok->wstart;
- tok->argv[tok->argc] = NULL;
- tok->wstart = ++tok->wptr;
- }
- tok->flags &= ~TOK_KEEP;
-}
-
-
-/* tok_init():
- * Initialize the tokenizer
- */
-public Tokenizer *
-tok_init(const char *ifs)
-{
- Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
-
- tok->ifs = strdup(ifs ? ifs : IFS);
- tok->argc = 0;
- tok->amax = AINCR;
- tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
- if (tok->argv == NULL)
- return (NULL);
- tok->argv[0] = NULL;
- tok->wspace = (char *) tok_malloc(WINCR);
- if (tok->wspace == NULL)
- return (NULL);
- tok->wmax = tok->wspace + WINCR;
- tok->wstart = tok->wspace;
- tok->wptr = tok->wspace;
- tok->flags = 0;
- tok->quote = Q_none;
-
- return (tok);
-}
-
-
-/* tok_reset():
- * Reset the tokenizer
- */
-public void
-tok_reset(Tokenizer *tok)
-{
-
- tok->argc = 0;
- tok->wstart = tok->wspace;
- tok->wptr = tok->wspace;
- tok->flags = 0;
- tok->quote = Q_none;
-}
-
-
-/* tok_end():
- * Clean up
- */
-public void
-tok_end(Tokenizer *tok)
-{
-
- tok_free((ptr_t) tok->ifs);
- tok_free((ptr_t) tok->wspace);
- tok_free((ptr_t) tok->argv);
- tok_free((ptr_t) tok);
-}
-
-
-
-/* tok_line():
- * Bourne shell like tokenizing
- * Return:
- * -1: Internal error
- * 3: Quoted return
- * 2: Unmatched double quote
- * 1: Unmatched single quote
- * 0: Ok
- */
-public int
-tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
-{
- const char *ptr;
-
- for (;;) {
- switch (*(ptr = line++)) {
- case '\'':
- tok->flags |= TOK_KEEP;
- tok->flags &= ~TOK_EAT;
- switch (tok->quote) {
- case Q_none:
- tok->quote = Q_single; /* Enter single quote
- * mode */
- break;
-
- case Q_single: /* Exit single quote mode */
- tok->quote = Q_none;
- break;
-
- case Q_one: /* Quote this ' */
- tok->quote = Q_none;
- *tok->wptr++ = *ptr;
- break;
-
- case Q_double: /* Stay in double quote mode */
- *tok->wptr++ = *ptr;
- break;
-
- case Q_doubleone: /* Quote this ' */
- tok->quote = Q_double;
- *tok->wptr++ = *ptr;
- break;
-
- default:
- return (-1);
- }
- break;
-
- case '"':
- tok->flags &= ~TOK_EAT;
- tok->flags |= TOK_KEEP;
- switch (tok->quote) {
- case Q_none: /* Enter double quote mode */
- tok->quote = Q_double;
- break;
-
- case Q_double: /* Exit double quote mode */
- tok->quote = Q_none;
- break;
-
- case Q_one: /* Quote this " */
- tok->quote = Q_none;
- *tok->wptr++ = *ptr;
- break;
-
- case Q_single: /* Stay in single quote mode */
- *tok->wptr++ = *ptr;
- break;
-
- case Q_doubleone: /* Quote this " */
- tok->quote = Q_double;
- *tok->wptr++ = *ptr;
- break;
-
- default:
- return (-1);
- }
- break;
-
- case '\\':
- tok->flags |= TOK_KEEP;
- tok->flags &= ~TOK_EAT;
- switch (tok->quote) {
- case Q_none: /* Quote next character */
- tok->quote = Q_one;
- break;
-
- case Q_double: /* Quote next character */
- tok->quote = Q_doubleone;
- break;
-
- case Q_one: /* Quote this, restore state */
- *tok->wptr++ = *ptr;
- tok->quote = Q_none;
- break;
-
- case Q_single: /* Stay in single quote mode */
- *tok->wptr++ = *ptr;
- break;
-
- case Q_doubleone: /* Quote this \ */
- tok->quote = Q_double;
- *tok->wptr++ = *ptr;
- break;
-
- default:
- return (-1);
- }
- break;
-
- case '\n':
- tok->flags &= ~TOK_EAT;
- switch (tok->quote) {
- case Q_none:
- tok_finish(tok);
- *argv = (const char **)tok->argv;
- *argc = tok->argc;
- return (0);
-
- case Q_single:
- case Q_double:
- *tok->wptr++ = *ptr; /* Add the return */
- break;
-
- case Q_doubleone: /* Back to double, eat the '\n' */
- tok->flags |= TOK_EAT;
- tok->quote = Q_double;
- break;
-
- case Q_one: /* No quote, more eat the '\n' */
- tok->flags |= TOK_EAT;
- tok->quote = Q_none;
- break;
-
- default:
- return (0);
- }
- break;
-
- case '\0':
- switch (tok->quote) {
- case Q_none:
- /* Finish word and return */
- if (tok->flags & TOK_EAT) {
- tok->flags &= ~TOK_EAT;
- return (3);
- }
- tok_finish(tok);
- *argv = (const char **)tok->argv;
- *argc = tok->argc;
- return (0);
-
- case Q_single:
- return (1);
-
- case Q_double:
- return (2);
-
- case Q_doubleone:
- tok->quote = Q_double;
- *tok->wptr++ = *ptr;
- break;
-
- case Q_one:
- tok->quote = Q_none;
- *tok->wptr++ = *ptr;
- break;
-
- default:
- return (-1);
- }
- break;
-
- default:
- tok->flags &= ~TOK_EAT;
- switch (tok->quote) {
- case Q_none:
- if (strchr(tok->ifs, *ptr) != NULL)
- tok_finish(tok);
- else
- *tok->wptr++ = *ptr;
- break;
-
- case Q_single:
- case Q_double:
- *tok->wptr++ = *ptr;
- break;
-
-
- case Q_doubleone:
- *tok->wptr++ = '\\';
- tok->quote = Q_double;
- *tok->wptr++ = *ptr;
- break;
-
- case Q_one:
- tok->quote = Q_none;
- *tok->wptr++ = *ptr;
- break;
-
- default:
- return (-1);
-
- }
- break;
- }
-
- if (tok->wptr >= tok->wmax - 4) {
- size_t size = tok->wmax - tok->wspace + WINCR;
- char *s = (char *) tok_realloc(tok->wspace, size);
- if (s == NULL)
- return (-1);
-
- if (s != tok->wspace) {
- int i;
- for (i = 0; i < tok->argc; i++) {
- tok->argv[i] =
- (tok->argv[i] - tok->wspace) + s;
- }
- tok->wptr = (tok->wptr - tok->wspace) + s;
- tok->wstart = (tok->wstart - tok->wspace) + s;
- tok->wspace = s;
- }
- tok->wmax = s + size;
- }
- if (tok->argc >= tok->amax - 4) {
- char **p;
- tok->amax += AINCR;
- p = (char **) tok_realloc(tok->argv,
- tok->amax * sizeof(char *));
- if (p == NULL)
- return (-1);
- tok->argv = p;
- }
- }
-}
diff --git a/1.4/main/editline/tokenizer.h b/1.4/main/editline/tokenizer.h
deleted file mode 100644
index 7cc7a3346..000000000
--- a/1.4/main/editline/tokenizer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* $NetBSD: tokenizer.h,v 1.5 2002/03/18 16:01:00 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tokenizer.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * tokenizer.h: Header file for tokenizer routines
- */
-#ifndef _h_tokenizer
-#define _h_tokenizer
-
-typedef struct tokenizer Tokenizer;
-
-Tokenizer *tok_init(const char *);
-void tok_reset(Tokenizer *);
-void tok_end(Tokenizer *);
-int tok_line(Tokenizer *, const char *, int *, const char ***);
-
-#endif /* _h_tokenizer */
diff --git a/1.4/main/editline/tty.c b/1.4/main/editline/tty.c
deleted file mode 100644
index 256cf780b..000000000
--- a/1.4/main/editline/tty.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/* $NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * tty.c: tty interface stuff
- */
-#include "tty.h"
-#include "el.h"
-
-typedef struct ttymodes_t {
- const char *m_name;
- u_int m_value;
- int m_type;
-} ttymodes_t;
-
-typedef struct ttymap_t {
- int nch, och; /* Internal and termio rep of chars */
- el_action_t bind[3]; /* emacs, vi, and vi-cmd */
-} ttymap_t;
-
-
-private const ttyperm_t ttyperm = {
- {
- {"iflag:", ICRNL, (INLCR | IGNCR)},
- {"oflag:", (OPOST | ONLCR), ONLRET},
- {"cflag:", 0, 0},
- {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
- (NOFLSH | ECHONL | EXTPROC | FLUSHO)},
- {"chars:", 0, 0},
- },
- {
- {"iflag:", (INLCR | ICRNL), IGNCR},
- {"oflag:", (OPOST | ONLCR), ONLRET},
- {"cflag:", 0, 0},
- {"lflag:", ISIG,
- (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
- {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
- C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
- C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
- },
- {
- {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
- {"oflag:", 0, 0},
- {"cflag:", 0, 0},
- {"lflag:", 0, ISIG | IEXTEN},
- {"chars:", 0, 0},
- }
-};
-
-private const ttychar_t ttychar = {
- {
- CINTR, CQUIT, CERASE, CKILL,
- CEOF, CEOL, CEOL2, CSWTCH,
- CDSWTCH, CERASE2, CSTART, CSTOP,
- CWERASE, CSUSP, CDSUSP, CREPRINT,
- CDISCARD, CLNEXT, CSTATUS, CPAGE,
- CPGOFF, CKILL2, CBRK, CMIN,
- CTIME
- },
- {
- CINTR, CQUIT, CERASE, CKILL,
- _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
- _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
- _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
- CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
- _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
- 0
- },
- {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0
- }
-};
-
-private const ttymap_t tty_map[] = {
-#ifdef VERASE
- {C_ERASE, VERASE,
- {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
-#endif /* VERASE */
-#ifdef VERASE2
- {C_ERASE2, VERASE2,
- {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
-#endif /* VERASE2 */
-#ifdef VKILL
- {C_KILL, VKILL,
- {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
-#endif /* VKILL */
-#ifdef VKILL2
- {C_KILL2, VKILL2,
- {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
-#endif /* VKILL2 */
-#ifdef VEOF
- {C_EOF, VEOF,
- {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
-#endif /* VEOF */
-#ifdef VWERASE
- {C_WERASE, VWERASE,
- {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
-#endif /* VWERASE */
-#ifdef VREPRINT
- {C_REPRINT, VREPRINT,
- {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
-#endif /* VREPRINT */
-#ifdef VLNEXT
- {C_LNEXT, VLNEXT,
- {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
-#endif /* VLNEXT */
- {-1, -1,
- {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
-};
-
-private const ttymodes_t ttymodes[] = {
-#ifdef IGNBRK
- {"ignbrk", IGNBRK, MD_INP},
-#endif /* IGNBRK */
-#ifdef BRKINT
- {"brkint", BRKINT, MD_INP},
-#endif /* BRKINT */
-#ifdef IGNPAR
- {"ignpar", IGNPAR, MD_INP},
-#endif /* IGNPAR */
-#ifdef PARMRK
- {"parmrk", PARMRK, MD_INP},
-#endif /* PARMRK */
-#ifdef INPCK
- {"inpck", INPCK, MD_INP},
-#endif /* INPCK */
-#ifdef ISTRIP
- {"istrip", ISTRIP, MD_INP},
-#endif /* ISTRIP */
-#ifdef INLCR
- {"inlcr", INLCR, MD_INP},
-#endif /* INLCR */
-#ifdef IGNCR
- {"igncr", IGNCR, MD_INP},
-#endif /* IGNCR */
-#ifdef ICRNL
- {"icrnl", ICRNL, MD_INP},
-#endif /* ICRNL */
-#ifdef IUCLC
- {"iuclc", IUCLC, MD_INP},
-#endif /* IUCLC */
-#ifdef IXON
- {"ixon", IXON, MD_INP},
-#endif /* IXON */
-#ifdef IXANY
- {"ixany", IXANY, MD_INP},
-#endif /* IXANY */
-#ifdef IXOFF
- {"ixoff", IXOFF, MD_INP},
-#endif /* IXOFF */
-#ifdef IMAXBEL
- {"imaxbel", IMAXBEL, MD_INP},
-#endif /* IMAXBEL */
-
-#ifdef OPOST
- {"opost", OPOST, MD_OUT},
-#endif /* OPOST */
-#ifdef OLCUC
- {"olcuc", OLCUC, MD_OUT},
-#endif /* OLCUC */
-#ifdef ONLCR
- {"onlcr", ONLCR, MD_OUT},
-#endif /* ONLCR */
-#ifdef OCRNL
- {"ocrnl", OCRNL, MD_OUT},
-#endif /* OCRNL */
-#ifdef ONOCR
- {"onocr", ONOCR, MD_OUT},
-#endif /* ONOCR */
-#ifdef ONOEOT
- {"onoeot", ONOEOT, MD_OUT},
-#endif /* ONOEOT */
-#ifdef ONLRET
- {"onlret", ONLRET, MD_OUT},
-#endif /* ONLRET */
-#ifdef OFILL
- {"ofill", OFILL, MD_OUT},
-#endif /* OFILL */
-#ifdef OFDEL
- {"ofdel", OFDEL, MD_OUT},
-#endif /* OFDEL */
-#ifdef NLDLY
- {"nldly", NLDLY, MD_OUT},
-#endif /* NLDLY */
-#ifdef CRDLY
- {"crdly", CRDLY, MD_OUT},
-#endif /* CRDLY */
-#ifdef TABDLY
- {"tabdly", TABDLY, MD_OUT},
-#endif /* TABDLY */
-#ifdef XTABS
- {"xtabs", XTABS, MD_OUT},
-#endif /* XTABS */
-#ifdef BSDLY
- {"bsdly", BSDLY, MD_OUT},
-#endif /* BSDLY */
-#ifdef VTDLY
- {"vtdly", VTDLY, MD_OUT},
-#endif /* VTDLY */
-#ifdef FFDLY
- {"ffdly", FFDLY, MD_OUT},
-#endif /* FFDLY */
-#ifdef PAGEOUT
- {"pageout", PAGEOUT, MD_OUT},
-#endif /* PAGEOUT */
-#ifdef WRAP
- {"wrap", WRAP, MD_OUT},
-#endif /* WRAP */
-
-#ifdef CIGNORE
- {"cignore", CIGNORE, MD_CTL},
-#endif /* CBAUD */
-#ifdef CBAUD
- {"cbaud", CBAUD, MD_CTL},
-#endif /* CBAUD */
-#ifdef CSTOPB
- {"cstopb", CSTOPB, MD_CTL},
-#endif /* CSTOPB */
-#ifdef CREAD
- {"cread", CREAD, MD_CTL},
-#endif /* CREAD */
-#ifdef PARENB
- {"parenb", PARENB, MD_CTL},
-#endif /* PARENB */
-#ifdef PARODD
- {"parodd", PARODD, MD_CTL},
-#endif /* PARODD */
-#ifdef HUPCL
- {"hupcl", HUPCL, MD_CTL},
-#endif /* HUPCL */
-#ifdef CLOCAL
- {"clocal", CLOCAL, MD_CTL},
-#endif /* CLOCAL */
-#ifdef LOBLK
- {"loblk", LOBLK, MD_CTL},
-#endif /* LOBLK */
-#ifdef CIBAUD
- {"cibaud", CIBAUD, MD_CTL},
-#endif /* CIBAUD */
-#ifdef CRTSCTS
-#ifdef CCTS_OFLOW
- {"ccts_oflow", CCTS_OFLOW, MD_CTL},
-#else
- {"crtscts", CRTSCTS, MD_CTL},
-#endif /* CCTS_OFLOW */
-#endif /* CRTSCTS */
-#ifdef CRTS_IFLOW
- {"crts_iflow", CRTS_IFLOW, MD_CTL},
-#endif /* CRTS_IFLOW */
-#ifdef CDTRCTS
- {"cdtrcts", CDTRCTS, MD_CTL},
-#endif /* CDTRCTS */
-#ifdef MDMBUF
- {"mdmbuf", MDMBUF, MD_CTL},
-#endif /* MDMBUF */
-#ifdef RCV1EN
- {"rcv1en", RCV1EN, MD_CTL},
-#endif /* RCV1EN */
-#ifdef XMT1EN
- {"xmt1en", XMT1EN, MD_CTL},
-#endif /* XMT1EN */
-
-#ifdef ISIG
- {"isig", ISIG, MD_LIN},
-#endif /* ISIG */
-#ifdef ICANON
- {"icanon", ICANON, MD_LIN},
-#endif /* ICANON */
-#ifdef XCASE
- {"xcase", XCASE, MD_LIN},
-#endif /* XCASE */
-#ifdef ECHO
- {"echo", ECHO, MD_LIN},
-#endif /* ECHO */
-#ifdef ECHOE
- {"echoe", ECHOE, MD_LIN},
-#endif /* ECHOE */
-#ifdef ECHOK
- {"echok", ECHOK, MD_LIN},
-#endif /* ECHOK */
-#ifdef ECHONL
- {"echonl", ECHONL, MD_LIN},
-#endif /* ECHONL */
-#ifdef NOFLSH
- {"noflsh", NOFLSH, MD_LIN},
-#endif /* NOFLSH */
-#ifdef TOSTOP
- {"tostop", TOSTOP, MD_LIN},
-#endif /* TOSTOP */
-#ifdef ECHOCTL
- {"echoctl", ECHOCTL, MD_LIN},
-#endif /* ECHOCTL */
-#ifdef ECHOPRT
- {"echoprt", ECHOPRT, MD_LIN},
-#endif /* ECHOPRT */
-#ifdef ECHOKE
- {"echoke", ECHOKE, MD_LIN},
-#endif /* ECHOKE */
-#ifdef DEFECHO
- {"defecho", DEFECHO, MD_LIN},
-#endif /* DEFECHO */
-#ifdef FLUSHO
- {"flusho", FLUSHO, MD_LIN},
-#endif /* FLUSHO */
-#ifdef PENDIN
- {"pendin", PENDIN, MD_LIN},
-#endif /* PENDIN */
-#ifdef IEXTEN
- {"iexten", IEXTEN, MD_LIN},
-#endif /* IEXTEN */
-#ifdef NOKERNINFO
- {"nokerninfo", NOKERNINFO, MD_LIN},
-#endif /* NOKERNINFO */
-#ifdef ALTWERASE
- {"altwerase", ALTWERASE, MD_LIN},
-#endif /* ALTWERASE */
-#ifdef EXTPROC
- {"extproc", EXTPROC, MD_LIN},
-#endif /* EXTPROC */
-
-#if defined(VINTR)
- {"intr", C_SH(C_INTR), MD_CHAR},
-#endif /* VINTR */
-#if defined(VQUIT)
- {"quit", C_SH(C_QUIT), MD_CHAR},
-#endif /* VQUIT */
-#if defined(VERASE)
- {"erase", C_SH(C_ERASE), MD_CHAR},
-#endif /* VERASE */
-#if defined(VKILL)
- {"kill", C_SH(C_KILL), MD_CHAR},
-#endif /* VKILL */
-#if defined(VEOF)
- {"eof", C_SH(C_EOF), MD_CHAR},
-#endif /* VEOF */
-#if defined(VEOL)
- {"eol", C_SH(C_EOL), MD_CHAR},
-#endif /* VEOL */
-#if defined(VEOL2)
- {"eol2", C_SH(C_EOL2), MD_CHAR},
-#endif /* VEOL2 */
-#if defined(VSWTCH)
- {"swtch", C_SH(C_SWTCH), MD_CHAR},
-#endif /* VSWTCH */
-#if defined(VDSWTCH)
- {"dswtch", C_SH(C_DSWTCH), MD_CHAR},
-#endif /* VDSWTCH */
-#if defined(VERASE2)
- {"erase2", C_SH(C_ERASE2), MD_CHAR},
-#endif /* VERASE2 */
-#if defined(VSTART)
- {"start", C_SH(C_START), MD_CHAR},
-#endif /* VSTART */
-#if defined(VSTOP)
- {"stop", C_SH(C_STOP), MD_CHAR},
-#endif /* VSTOP */
-#if defined(VWERASE)
- {"werase", C_SH(C_WERASE), MD_CHAR},
-#endif /* VWERASE */
-#if defined(VSUSP)
- {"susp", C_SH(C_SUSP), MD_CHAR},
-#endif /* VSUSP */
-#if defined(VDSUSP)
- {"dsusp", C_SH(C_DSUSP), MD_CHAR},
-#endif /* VDSUSP */
-#if defined(VREPRINT)
- {"reprint", C_SH(C_REPRINT), MD_CHAR},
-#endif /* VREPRINT */
-#if defined(VDISCARD)
- {"discard", C_SH(C_DISCARD), MD_CHAR},
-#endif /* VDISCARD */
-#if defined(VLNEXT)
- {"lnext", C_SH(C_LNEXT), MD_CHAR},
-#endif /* VLNEXT */
-#if defined(VSTATUS)
- {"status", C_SH(C_STATUS), MD_CHAR},
-#endif /* VSTATUS */
-#if defined(VPAGE)
- {"page", C_SH(C_PAGE), MD_CHAR},
-#endif /* VPAGE */
-#if defined(VPGOFF)
- {"pgoff", C_SH(C_PGOFF), MD_CHAR},
-#endif /* VPGOFF */
-#if defined(VKILL2)
- {"kill2", C_SH(C_KILL2), MD_CHAR},
-#endif /* VKILL2 */
-#if defined(VBRK)
- {"brk", C_SH(C_BRK), MD_CHAR},
-#endif /* VBRK */
-#if defined(VMIN)
- {"min", C_SH(C_MIN), MD_CHAR},
-#endif /* VMIN */
-#if defined(VTIME)
- {"time", C_SH(C_TIME), MD_CHAR},
-#endif /* VTIME */
- {NULL, 0, -1},
-};
-
-
-
-#define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
-#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
-
-#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
-#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
-#define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
-
-private void tty__getchar(struct termios *, unsigned char *);
-private void tty__setchar(struct termios *, unsigned char *);
-private speed_t tty__getspeed(struct termios *);
-private int tty_setup(EditLine *);
-
-#define t_qu t_ts
-
-
-/* tty_setup():
- * Get the tty parameters and initialize the editing state
- */
-private int
-tty_setup(EditLine *el)
-{
- int rst = 1;
-
- if (el->el_flags & EDIT_DISABLED)
- return (0);
-
- if (tty_getty(el, &el->el_tty.t_ed) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile,
- "tty_setup: tty_getty: %s\n", strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
-
- el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
- el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
- el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
-
- el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
- el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
-
- el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
- el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
-
- el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
- el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
-
- el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
- el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
-
- /*
- * Reset the tty chars to reasonable defaults
- * If they are disabled, then enable them.
- */
- if (rst) {
- if (tty__cooked_mode(&el->el_tty.t_ts)) {
- tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
- /*
- * Don't affect CMIN and CTIME for the editor mode
- */
- for (rst = 0; rst < C_NCC - 2; rst++)
- if (el->el_tty.t_c[TS_IO][rst] !=
- el->el_tty.t_vdisable
- && el->el_tty.t_c[ED_IO][rst] !=
- el->el_tty.t_vdisable)
- el->el_tty.t_c[ED_IO][rst] =
- el->el_tty.t_c[TS_IO][rst];
- for (rst = 0; rst < C_NCC; rst++)
- if (el->el_tty.t_c[TS_IO][rst] !=
- el->el_tty.t_vdisable)
- el->el_tty.t_c[EX_IO][rst] =
- el->el_tty.t_c[TS_IO][rst];
- }
- tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
- if (tty_setty(el, &el->el_tty.t_ex) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile,
- "tty_setup: tty_setty: %s\n",
- strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- } else
- tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
-
- el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
- el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
-
- el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
- el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
-
- el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
- el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
-
- el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
- el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
-
- tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
- tty_bind_char(el, 1);
- return (0);
-}
-
-protected int
-tty_init(EditLine *el)
-{
-
- el->el_tty.t_mode = EX_IO;
- el->el_tty.t_vdisable = _POSIX_VDISABLE;
- (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
- (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
- return (tty_setup(el));
-}
-
-
-/* tty_end():
- * Restore the tty to its original settings
- */
-protected void
-/*ARGSUSED*/
-tty_end(EditLine *el)
-{
-
- /* XXX: Maybe reset to an initial state? */
-}
-
-
-/* tty__getspeed():
- * Get the tty speed
- */
-private speed_t
-tty__getspeed(struct termios *td)
-{
- speed_t spd;
-
- if ((spd = cfgetispeed(td)) == 0)
- spd = cfgetospeed(td);
- return (spd);
-}
-
-
-/* tty__getchar():
- * Get the tty characters
- */
-private void
-tty__getchar(struct termios *td, unsigned char *s)
-{
-
-#ifdef VINTR
- s[C_INTR] = td->c_cc[VINTR];
-#endif /* VINTR */
-#ifdef VQUIT
- s[C_QUIT] = td->c_cc[VQUIT];
-#endif /* VQUIT */
-#ifdef VERASE
- s[C_ERASE] = td->c_cc[VERASE];
-#endif /* VERASE */
-#ifdef VKILL
- s[C_KILL] = td->c_cc[VKILL];
-#endif /* VKILL */
-#ifdef VEOF
- s[C_EOF] = td->c_cc[VEOF];
-#endif /* VEOF */
-#ifdef VEOL
- s[C_EOL] = td->c_cc[VEOL];
-#endif /* VEOL */
-#ifdef VEOL2
- s[C_EOL2] = td->c_cc[VEOL2];
-#endif /* VEOL2 */
-#ifdef VSWTCH
- s[C_SWTCH] = td->c_cc[VSWTCH];
-#endif /* VSWTCH */
-#ifdef VDSWTCH
- s[C_DSWTCH] = td->c_cc[VDSWTCH];
-#endif /* VDSWTCH */
-#ifdef VERASE2
- s[C_ERASE2] = td->c_cc[VERASE2];
-#endif /* VERASE2 */
-#ifdef VSTART
- s[C_START] = td->c_cc[VSTART];
-#endif /* VSTART */
-#ifdef VSTOP
- s[C_STOP] = td->c_cc[VSTOP];
-#endif /* VSTOP */
-#ifdef VWERASE
- s[C_WERASE] = td->c_cc[VWERASE];
-#endif /* VWERASE */
-#ifdef VSUSP
- s[C_SUSP] = td->c_cc[VSUSP];
-#endif /* VSUSP */
-#ifdef VDSUSP
- s[C_DSUSP] = td->c_cc[VDSUSP];
-#endif /* VDSUSP */
-#ifdef VREPRINT
- s[C_REPRINT] = td->c_cc[VREPRINT];
-#endif /* VREPRINT */
-#ifdef VDISCARD
- s[C_DISCARD] = td->c_cc[VDISCARD];
-#endif /* VDISCARD */
-#ifdef VLNEXT
- s[C_LNEXT] = td->c_cc[VLNEXT];
-#endif /* VLNEXT */
-#ifdef VSTATUS
- s[C_STATUS] = td->c_cc[VSTATUS];
-#endif /* VSTATUS */
-#ifdef VPAGE
- s[C_PAGE] = td->c_cc[VPAGE];
-#endif /* VPAGE */
-#ifdef VPGOFF
- s[C_PGOFF] = td->c_cc[VPGOFF];
-#endif /* VPGOFF */
-#ifdef VKILL2
- s[C_KILL2] = td->c_cc[VKILL2];
-#endif /* KILL2 */
-#ifdef VMIN
- s[C_MIN] = td->c_cc[VMIN];
-#endif /* VMIN */
-#ifdef VTIME
- s[C_TIME] = td->c_cc[VTIME];
-#endif /* VTIME */
-} /* tty__getchar */
-
-
-/* tty__setchar():
- * Set the tty characters
- */
-private void
-tty__setchar(struct termios *td, unsigned char *s)
-{
-
-#ifdef VINTR
- td->c_cc[VINTR] = s[C_INTR];
-#endif /* VINTR */
-#ifdef VQUIT
- td->c_cc[VQUIT] = s[C_QUIT];
-#endif /* VQUIT */
-#ifdef VERASE
- td->c_cc[VERASE] = s[C_ERASE];
-#endif /* VERASE */
-#ifdef VKILL
- td->c_cc[VKILL] = s[C_KILL];
-#endif /* VKILL */
-#ifdef VEOF
- td->c_cc[VEOF] = s[C_EOF];
-#endif /* VEOF */
-#ifdef VEOL
- td->c_cc[VEOL] = s[C_EOL];
-#endif /* VEOL */
-#ifdef VEOL2
- td->c_cc[VEOL2] = s[C_EOL2];
-#endif /* VEOL2 */
-#ifdef VSWTCH
- td->c_cc[VSWTCH] = s[C_SWTCH];
-#endif /* VSWTCH */
-#ifdef VDSWTCH
- td->c_cc[VDSWTCH] = s[C_DSWTCH];
-#endif /* VDSWTCH */
-#ifdef VERASE2
- td->c_cc[VERASE2] = s[C_ERASE2];
-#endif /* VERASE2 */
-#ifdef VSTART
- td->c_cc[VSTART] = s[C_START];
-#endif /* VSTART */
-#ifdef VSTOP
- td->c_cc[VSTOP] = s[C_STOP];
-#endif /* VSTOP */
-#ifdef VWERASE
- td->c_cc[VWERASE] = s[C_WERASE];
-#endif /* VWERASE */
-#ifdef VSUSP
- td->c_cc[VSUSP] = s[C_SUSP];
-#endif /* VSUSP */
-#ifdef VDSUSP
- td->c_cc[VDSUSP] = s[C_DSUSP];
-#endif /* VDSUSP */
-#ifdef VREPRINT
- td->c_cc[VREPRINT] = s[C_REPRINT];
-#endif /* VREPRINT */
-#ifdef VDISCARD
- td->c_cc[VDISCARD] = s[C_DISCARD];
-#endif /* VDISCARD */
-#ifdef VLNEXT
- td->c_cc[VLNEXT] = s[C_LNEXT];
-#endif /* VLNEXT */
-#ifdef VSTATUS
- td->c_cc[VSTATUS] = s[C_STATUS];
-#endif /* VSTATUS */
-#ifdef VPAGE
- td->c_cc[VPAGE] = s[C_PAGE];
-#endif /* VPAGE */
-#ifdef VPGOFF
- td->c_cc[VPGOFF] = s[C_PGOFF];
-#endif /* VPGOFF */
-#ifdef VKILL2
- td->c_cc[VKILL2] = s[C_KILL2];
-#endif /* VKILL2 */
-#ifdef VMIN
- td->c_cc[VMIN] = s[C_MIN];
-#endif /* VMIN */
-#ifdef VTIME
- td->c_cc[VTIME] = s[C_TIME];
-#endif /* VTIME */
-} /* tty__setchar */
-
-
-/* tty_bind_char():
- * Rebind the editline functions
- */
-protected void
-tty_bind_char(EditLine *el, int force)
-{
-
- unsigned char *t_n = el->el_tty.t_c[ED_IO];
- unsigned char *t_o = el->el_tty.t_ed.c_cc;
- unsigned char new[2], old[2];
- const ttymap_t *tp;
- el_action_t *map, *alt;
- const el_action_t *dmap, *dalt;
- new[1] = old[1] = '\0';
-
- map = el->el_map.key;
- alt = el->el_map.alt;
- if (el->el_map.type == MAP_VI) {
- dmap = el->el_map.vii;
- dalt = el->el_map.vic;
- } else {
- dmap = el->el_map.emacs;
- dalt = NULL;
- }
-
- for (tp = tty_map; tp->nch != -1; tp++) {
- new[0] = t_n[tp->nch];
- old[0] = t_o[tp->och];
- if (new[0] == old[0] && !force)
- continue;
- /* Put the old default binding back, and set the new binding */
- key_clear(el, map, (char *)old);
- map[old[0]] = dmap[old[0]];
- key_clear(el, map, (char *)new);
- /* MAP_VI == 1, MAP_EMACS == 0... */
- map[new[0]] = tp->bind[el->el_map.type];
- if (dalt) {
- key_clear(el, alt, (char *)old);
- alt[old[0]] = dalt[old[0]];
- key_clear(el, alt, (char *)new);
- alt[new[0]] = tp->bind[el->el_map.type + 1];
- }
- }
-}
-
-
-/* tty_rawmode():
- * Set terminal into 1 character at a time mode.
- */
-protected int
-tty_rawmode(EditLine *el)
-{
-
- if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
- return (0);
-
- if (el->el_flags & EDIT_DISABLED)
- return (0);
-
- if (tty_getty(el, &el->el_tty.t_ts) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
- strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- /*
- * We always keep up with the eight bit setting and the speed of the
- * tty. But only we only believe changes that are made to cooked mode!
- */
- el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
- el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
-
- if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
- tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
- (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
- (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
- (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
- (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
- }
- if (tty__cooked_mode(&el->el_tty.t_ts)) {
- if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
- el->el_tty.t_ex.c_cflag =
- el->el_tty.t_ts.c_cflag;
- el->el_tty.t_ex.c_cflag &=
- ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
- el->el_tty.t_ex.c_cflag |=
- el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
-
- el->el_tty.t_ed.c_cflag =
- el->el_tty.t_ts.c_cflag;
- el->el_tty.t_ed.c_cflag &=
- ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
- el->el_tty.t_ed.c_cflag |=
- el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
- }
- if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
- (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
- el->el_tty.t_ex.c_lflag =
- el->el_tty.t_ts.c_lflag;
- el->el_tty.t_ex.c_lflag &=
- ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
- el->el_tty.t_ex.c_lflag |=
- el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
-
- el->el_tty.t_ed.c_lflag =
- el->el_tty.t_ts.c_lflag;
- el->el_tty.t_ed.c_lflag &=
- ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
- el->el_tty.t_ed.c_lflag |=
- el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
- }
- if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
- (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
- el->el_tty.t_ex.c_iflag =
- el->el_tty.t_ts.c_iflag;
- el->el_tty.t_ex.c_iflag &=
- ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
- el->el_tty.t_ex.c_iflag |=
- el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
-
- el->el_tty.t_ed.c_iflag =
- el->el_tty.t_ts.c_iflag;
- el->el_tty.t_ed.c_iflag &=
- ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
- el->el_tty.t_ed.c_iflag |=
- el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
- }
- if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
- (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
- el->el_tty.t_ex.c_oflag =
- el->el_tty.t_ts.c_oflag;
- el->el_tty.t_ex.c_oflag &=
- ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
- el->el_tty.t_ex.c_oflag |=
- el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
-
- el->el_tty.t_ed.c_oflag =
- el->el_tty.t_ts.c_oflag;
- el->el_tty.t_ed.c_oflag &=
- ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
- el->el_tty.t_ed.c_oflag |=
- el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
- }
- if (tty__gettabs(&el->el_tty.t_ex) == 0)
- el->el_tty.t_tabs = 0;
- else
- el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
-
- {
- int i;
-
- tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
- /*
- * Check if the user made any changes.
- * If he did, then propagate the changes to the
- * edit and execute data structures.
- */
- for (i = 0; i < C_NCC; i++)
- if (el->el_tty.t_c[TS_IO][i] !=
- el->el_tty.t_c[EX_IO][i])
- break;
-
- if (i != C_NCC) {
- /*
- * Propagate changes only to the unprotected
- * chars that have been modified just now.
- */
- for (i = 0; i < C_NCC; i++) {
- if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
- && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
- el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
- if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
- el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
- }
- tty_bind_char(el, 0);
- tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
-
- for (i = 0; i < C_NCC; i++) {
- if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
- && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
- el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
- if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
- el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
- }
- tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
- }
- }
- }
- if (tty_setty(el, &el->el_tty.t_ed) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
- strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- el->el_tty.t_mode = ED_IO;
- return (0);
-}
-
-
-/* tty_cookedmode():
- * Set the tty back to normal mode
- */
-protected int
-tty_cookedmode(EditLine *el)
-{ /* set tty in normal setup */
-
- if (el->el_tty.t_mode == EX_IO)
- return (0);
-
- if (el->el_flags & EDIT_DISABLED)
- return (0);
-
- if (tty_setty(el, &el->el_tty.t_ex) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile,
- "tty_cookedmode: tty_setty: %s\n",
- strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- el->el_tty.t_mode = EX_IO;
- return (0);
-}
-
-
-/* tty_quotemode():
- * Turn on quote mode
- */
-protected int
-tty_quotemode(EditLine *el)
-{
- if (el->el_tty.t_mode == QU_IO)
- return (0);
-
- el->el_tty.t_qu = el->el_tty.t_ed;
-
- el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
- el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
-
- el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
- el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
-
- el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
- el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
-
- el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
- el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
-
- if (tty_setty(el, &el->el_tty.t_qu) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
- strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- el->el_tty.t_mode = QU_IO;
- return (0);
-}
-
-
-/* tty_noquotemode():
- * Turn off quote mode
- */
-protected int
-tty_noquotemode(EditLine *el)
-{
-
- if (el->el_tty.t_mode != QU_IO)
- return (0);
- if (tty_setty(el, &el->el_tty.t_ed) == -1) {
-#ifdef DEBUG_TTY
- (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
- strerror(errno));
-#endif /* DEBUG_TTY */
- return (-1);
- }
- el->el_tty.t_mode = ED_IO;
- return (0);
-}
-
-
-/* tty_stty():
- * Stty builtin
- */
-protected int
-/*ARGSUSED*/
-tty_stty(EditLine *el, int argc, const char **argv)
-{
- const ttymodes_t *m;
- char x;
- int aflag = 0;
- const char *s, *d;
- const char *name;
- int z = EX_IO;
-
- if (argv == NULL)
- return (-1);
- name = *argv++;
-
- while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
- switch (argv[0][1]) {
- case 'a':
- aflag++;
- argv++;
- break;
- case 'd':
- argv++;
- z = ED_IO;
- break;
- case 'x':
- argv++;
- z = EX_IO;
- break;
- case 'q':
- argv++;
- z = QU_IO;
- break;
- default:
- (void) fprintf(el->el_errfile,
- "%s: Unknown switch `%c'.\n",
- name, argv[0][1]);
- return (-1);
- }
-
- if (!argv || !*argv) {
- int i = -1;
- int len = 0, st = 0, cu;
- for (m = ttymodes; m->m_name; m++) {
- if (m->m_type != i) {
- (void) fprintf(el->el_outfile, "%s%s",
- i != -1 ? "\n" : "",
- el->el_tty.t_t[z][m->m_type].t_name);
- i = m->m_type;
- st = len =
- strlen(el->el_tty.t_t[z][m->m_type].t_name);
- }
- x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
- ? '+' : '\0';
- x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
- ? '-' : x;
-
- if (x != '\0' || aflag) {
-
- cu = strlen(m->m_name) + (x != '\0') + 1;
-
- if (len + cu >= el->el_term.t_size.h) {
- (void) fprintf(el->el_outfile, "\n%*s",
- st, "");
- len = st + cu;
- } else
- len += cu;
-
- if (x != '\0')
- (void) fprintf(el->el_outfile, "%c%s ",
- x, m->m_name);
- else
- (void) fprintf(el->el_outfile, "%s ",
- m->m_name);
- }
- }
- (void) fprintf(el->el_outfile, "\n");
- return (0);
- }
- while (argv && (s = *argv++)) {
- switch (*s) {
- case '+':
- case '-':
- x = *s++;
- break;
- default:
- x = '\0';
- break;
- }
- d = s;
- for (m = ttymodes; m->m_name; m++)
- if (strcmp(m->m_name, d) == 0)
- break;
-
- if (!m->m_name) {
- (void) fprintf(el->el_errfile,
- "%s: Invalid argument `%s'.\n", name, d);
- return (-1);
- }
- switch (x) {
- case '+':
- el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
- el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
- break;
- case '-':
- el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
- el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
- break;
- default:
- el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
- el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
- break;
- }
- }
- return (0);
-}
-
-
-#ifdef notyet
-/* tty_printchar():
- * DEbugging routine to print the tty characters
- */
-private void
-tty_printchar(EditLine *el, unsigned char *s)
-{
- ttyperm_t *m;
- int i;
-
- for (i = 0; i < C_NCC; i++) {
- for (m = el->el_tty.t_t; m->m_name; m++)
- if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
- break;
- if (m->m_name)
- (void) fprintf(el->el_errfile, "%s ^%c ",
- m->m_name, s[i] + 'A' - 1);
- if (i % 5 == 0)
- (void) fprintf(el->el_errfile, "\n");
- }
- (void) fprintf(el->el_errfile, "\n");
-}
-#endif /* notyet */
diff --git a/1.4/main/editline/tty.h b/1.4/main/editline/tty.h
deleted file mode 100644
index e9597fceb..000000000
--- a/1.4/main/editline/tty.h
+++ /dev/null
@@ -1,484 +0,0 @@
-/* $NetBSD: tty.h,v 1.9 2002/03/18 16:01:01 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tty.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * el.tty.h: Local terminal header
- */
-#ifndef _h_el_tty
-#define _h_el_tty
-
-#include "histedit.h"
-#include <termios.h>
-#include <unistd.h>
-
-/* Define our own since everyone gets it wrong! */
-#define CONTROL(A) ((A) & 037)
-
-/*
- * Aix compatible names
- */
-# if defined(VWERSE) && !defined(VWERASE)
-# define VWERASE VWERSE
-# endif /* VWERSE && !VWERASE */
-
-# if defined(VDISCRD) && !defined(VDISCARD)
-# define VDISCARD VDISCRD
-# endif /* VDISCRD && !VDISCARD */
-
-# if defined(VFLUSHO) && !defined(VDISCARD)
-# define VDISCARD VFLUSHO
-# endif /* VFLUSHO && VDISCARD */
-
-# if defined(VSTRT) && !defined(VSTART)
-# define VSTART VSTRT
-# endif /* VSTRT && ! VSTART */
-
-# if defined(VSTAT) && !defined(VSTATUS)
-# define VSTATUS VSTAT
-# endif /* VSTAT && ! VSTATUS */
-
-# ifndef ONLRET
-# define ONLRET 0
-# endif /* ONLRET */
-
-# ifndef TAB3
-# ifdef OXTABS
-# define TAB3 OXTABS
-# else
-# define TAB3 0
-# endif /* OXTABS */
-# endif /* !TAB3 */
-
-# if defined(OXTABS) && !defined(XTABS)
-# define XTABS OXTABS
-# endif /* OXTABS && !XTABS */
-
-# ifndef ONLCR
-# define ONLCR 0
-# endif /* ONLCR */
-
-# ifndef IEXTEN
-# define IEXTEN 0
-# endif /* IEXTEN */
-
-# ifndef ECHOCTL
-# define ECHOCTL 0
-# endif /* ECHOCTL */
-
-# ifndef PARENB
-# define PARENB 0
-# endif /* PARENB */
-
-# ifndef EXTPROC
-# define EXTPROC 0
-# endif /* EXTPROC */
-
-# ifndef FLUSHO
-# define FLUSHO 0
-# endif /* FLUSHO */
-
-
-# if defined(VDISABLE) && !defined(_POSIX_VDISABLE)
-# define _POSIX_VDISABLE VDISABLE
-# endif /* VDISABLE && ! _POSIX_VDISABLE */
-
-/*
- * Work around ISC's definition of IEXTEN which is
- * XCASE!
- */
-# ifdef ISC
-# if defined(IEXTEN) && defined(XCASE)
-# if IEXTEN == XCASE
-# undef IEXTEN
-# define IEXTEN 0
-# endif /* IEXTEN == XCASE */
-# endif /* IEXTEN && XCASE */
-# if defined(IEXTEN) && !defined(XCASE)
-# define XCASE IEXTEN
-# undef IEXTEN
-# define IEXTEN 0
-# endif /* IEXTEN && !XCASE */
-# endif /* ISC */
-
-/*
- * Work around convex weirdness where turning off IEXTEN makes us
- * lose all postprocessing!
- */
-#if defined(convex) || defined(__convex__)
-# if defined(IEXTEN) && IEXTEN != 0
-# undef IEXTEN
-# define IEXTEN 0
-# endif /* IEXTEN != 0 */
-#endif /* convex || __convex__ */
-
-/*
- * So that we don't lose job control.
- */
-#ifdef __SVR4
-# undef CSWTCH
-#endif
-
-#ifndef _POSIX_VDISABLE
-# define _POSIX_VDISABLE ((unsigned char) -1)
-#endif /* _POSIX_VDISABLE */
-
-#if !defined(CREPRINT) && defined(CRPRNT)
-# define CREPRINT CRPRNT
-#endif /* !CREPRINT && CRPRNT */
-#if !defined(CDISCARD) && defined(CFLUSH)
-# define CDISCARD CFLUSH
-#endif /* !CDISCARD && CFLUSH */
-
-#ifndef CINTR
-# define CINTR CONTROL('c')
-#endif /* CINTR */
-#ifndef CQUIT
-# define CQUIT 034 /* ^\ */
-#endif /* CQUIT */
-#ifndef CERASE
-# define CERASE 0177 /* ^? */
-#endif /* CERASE */
-#ifndef CKILL
-# define CKILL CONTROL('u')
-#endif /* CKILL */
-#ifndef CEOF
-# define CEOF CONTROL('d')
-#endif /* CEOF */
-#ifndef CEOL
-# define CEOL _POSIX_VDISABLE
-#endif /* CEOL */
-#ifndef CEOL2
-# define CEOL2 _POSIX_VDISABLE
-#endif /* CEOL2 */
-#ifndef CSWTCH
-# define CSWTCH _POSIX_VDISABLE
-#endif /* CSWTCH */
-#ifndef CDSWTCH
-# define CDSWTCH _POSIX_VDISABLE
-#endif /* CDSWTCH */
-#ifndef CERASE2
-# define CERASE2 _POSIX_VDISABLE
-#endif /* CERASE2 */
-#ifndef CSTART
-# define CSTART CONTROL('q')
-#endif /* CSTART */
-#ifndef CSTOP
-# define CSTOP CONTROL('s')
-#endif /* CSTOP */
-#ifndef CSUSP
-# define CSUSP CONTROL('z')
-#endif /* CSUSP */
-#ifndef CDSUSP
-# define CDSUSP CONTROL('y')
-#endif /* CDSUSP */
-
-#ifdef hpux
-
-# ifndef CREPRINT
-# define CREPRINT _POSIX_VDISABLE
-# endif /* CREPRINT */
-# ifndef CDISCARD
-# define CDISCARD _POSIX_VDISABLE
-# endif /* CDISCARD */
-# ifndef CLNEXT
-# define CLNEXT _POSIX_VDISABLE
-# endif /* CLNEXT */
-# ifndef CWERASE
-# define CWERASE _POSIX_VDISABLE
-# endif /* CWERASE */
-
-#else /* !hpux */
-
-# ifndef CREPRINT
-# define CREPRINT CONTROL('r')
-# endif /* CREPRINT */
-# ifndef CDISCARD
-# define CDISCARD CONTROL('o')
-# endif /* CDISCARD */
-# ifndef CLNEXT
-# define CLNEXT CONTROL('v')
-# endif /* CLNEXT */
-# ifndef CWERASE
-# define CWERASE CONTROL('w')
-# endif /* CWERASE */
-
-#endif /* hpux */
-
-#ifndef CSTATUS
-# define CSTATUS CONTROL('t')
-#endif /* CSTATUS */
-#ifndef CPAGE
-# define CPAGE ' '
-#endif /* CPAGE */
-#ifndef CPGOFF
-# define CPGOFF CONTROL('m')
-#endif /* CPGOFF */
-#ifndef CKILL2
-# define CKILL2 _POSIX_VDISABLE
-#endif /* CKILL2 */
-#ifndef CBRK
-# ifndef masscomp
-# define CBRK 0377
-# else
-# define CBRK '\0'
-# endif /* masscomp */
-#endif /* CBRK */
-#ifndef CMIN
-# define CMIN CEOF
-#endif /* CMIN */
-#ifndef CTIME
-# define CTIME CEOL
-#endif /* CTIME */
-
-/*
- * Fix for sun inconsistency. On termio VSUSP and the rest of the
- * ttychars > NCC are defined. So we undefine them.
- */
-#if defined(TERMIO) || defined(POSIX)
-# if defined(POSIX) && defined(NCCS)
-# define NUMCC NCCS
-# else
-# ifdef NCC
-# define NUMCC NCC
-# endif /* NCC */
-# endif /* POSIX && NCCS */
-# ifdef NUMCC
-# ifdef VINTR
-# if NUMCC <= VINTR
-# undef VINTR
-# endif /* NUMCC <= VINTR */
-# endif /* VINTR */
-# ifdef VQUIT
-# if NUMCC <= VQUIT
-# undef VQUIT
-# endif /* NUMCC <= VQUIT */
-# endif /* VQUIT */
-# ifdef VERASE
-# if NUMCC <= VERASE
-# undef VERASE
-# endif /* NUMCC <= VERASE */
-# endif /* VERASE */
-# ifdef VKILL
-# if NUMCC <= VKILL
-# undef VKILL
-# endif /* NUMCC <= VKILL */
-# endif /* VKILL */
-# ifdef VEOF
-# if NUMCC <= VEOF
-# undef VEOF
-# endif /* NUMCC <= VEOF */
-# endif /* VEOF */
-# ifdef VEOL
-# if NUMCC <= VEOL
-# undef VEOL
-# endif /* NUMCC <= VEOL */
-# endif /* VEOL */
-# ifdef VEOL2
-# if NUMCC <= VEOL2
-# undef VEOL2
-# endif /* NUMCC <= VEOL2 */
-# endif /* VEOL2 */
-# ifdef VSWTCH
-# if NUMCC <= VSWTCH
-# undef VSWTCH
-# endif /* NUMCC <= VSWTCH */
-# endif /* VSWTCH */
-# ifdef VDSWTCH
-# if NUMCC <= VDSWTCH
-# undef VDSWTCH
-# endif /* NUMCC <= VDSWTCH */
-# endif /* VDSWTCH */
-# ifdef VERASE2
-# if NUMCC <= VERASE2
-# undef VERASE2
-# endif /* NUMCC <= VERASE2 */
-# endif /* VERASE2 */
-# ifdef VSTART
-# if NUMCC <= VSTART
-# undef VSTART
-# endif /* NUMCC <= VSTART */
-# endif /* VSTART */
-# ifdef VSTOP
-# if NUMCC <= VSTOP
-# undef VSTOP
-# endif /* NUMCC <= VSTOP */
-# endif /* VSTOP */
-# ifdef VWERASE
-# if NUMCC <= VWERASE
-# undef VWERASE
-# endif /* NUMCC <= VWERASE */
-# endif /* VWERASE */
-# ifdef VSUSP
-# if NUMCC <= VSUSP
-# undef VSUSP
-# endif /* NUMCC <= VSUSP */
-# endif /* VSUSP */
-# ifdef VDSUSP
-# if NUMCC <= VDSUSP
-# undef VDSUSP
-# endif /* NUMCC <= VDSUSP */
-# endif /* VDSUSP */
-# ifdef VREPRINT
-# if NUMCC <= VREPRINT
-# undef VREPRINT
-# endif /* NUMCC <= VREPRINT */
-# endif /* VREPRINT */
-# ifdef VDISCARD
-# if NUMCC <= VDISCARD
-# undef VDISCARD
-# endif /* NUMCC <= VDISCARD */
-# endif /* VDISCARD */
-# ifdef VLNEXT
-# if NUMCC <= VLNEXT
-# undef VLNEXT
-# endif /* NUMCC <= VLNEXT */
-# endif /* VLNEXT */
-# ifdef VSTATUS
-# if NUMCC <= VSTATUS
-# undef VSTATUS
-# endif /* NUMCC <= VSTATUS */
-# endif /* VSTATUS */
-# ifdef VPAGE
-# if NUMCC <= VPAGE
-# undef VPAGE
-# endif /* NUMCC <= VPAGE */
-# endif /* VPAGE */
-# ifdef VPGOFF
-# if NUMCC <= VPGOFF
-# undef VPGOFF
-# endif /* NUMCC <= VPGOFF */
-# endif /* VPGOFF */
-# ifdef VKILL2
-# if NUMCC <= VKILL2
-# undef VKILL2
-# endif /* NUMCC <= VKILL2 */
-# endif /* VKILL2 */
-# ifdef VBRK
-# if NUMCC <= VBRK
-# undef VBRK
-# endif /* NUMCC <= VBRK */
-# endif /* VBRK */
-# ifdef VMIN
-# if NUMCC <= VMIN
-# undef VMIN
-# endif /* NUMCC <= VMIN */
-# endif /* VMIN */
-# ifdef VTIME
-# if NUMCC <= VTIME
-# undef VTIME
-# endif /* NUMCC <= VTIME */
-# endif /* VTIME */
-# endif /* NUMCC */
-#endif /* !POSIX */
-
-#define C_INTR 0
-#define C_QUIT 1
-#define C_ERASE 2
-#define C_KILL 3
-#define C_EOF 4
-#define C_EOL 5
-#define C_EOL2 6
-#define C_SWTCH 7
-#define C_DSWTCH 8
-#define C_ERASE2 9
-#define C_START 10
-#define C_STOP 11
-#define C_WERASE 12
-#define C_SUSP 13
-#define C_DSUSP 14
-#define C_REPRINT 15
-#define C_DISCARD 16
-#define C_LNEXT 17
-#define C_STATUS 18
-#define C_PAGE 19
-#define C_PGOFF 20
-#define C_KILL2 21
-#define C_BRK 22
-#define C_MIN 23
-#define C_TIME 24
-#define C_NCC 25
-#define C_SH(A) (1 << (A))
-
-/*
- * Terminal dependend data structures
- */
-#define EX_IO 0 /* while we are executing */
-#define ED_IO 1 /* while we are editing */
-#define TS_IO 2 /* new mode from terminal */
-#define QU_IO 2 /* used only for quoted chars */
-#define NN_IO 3 /* The number of entries */
-
-#define MD_INP 0
-#define MD_OUT 1
-#define MD_CTL 2
-#define MD_LIN 3
-#define MD_CHAR 4
-#define MD_NN 5
-
-typedef struct {
- const char *t_name;
- u_int t_setmask;
- u_int t_clrmask;
-} ttyperm_t[NN_IO][MD_NN];
-
-typedef unsigned char ttychar_t[NN_IO][C_NCC];
-
-protected int tty_init(EditLine *);
-protected void tty_end(EditLine *);
-protected int tty_stty(EditLine *, int, const char **);
-protected int tty_rawmode(EditLine *);
-protected int tty_cookedmode(EditLine *);
-protected int tty_quotemode(EditLine *);
-protected int tty_noquotemode(EditLine *);
-protected void tty_bind_char(EditLine *, int);
-
-typedef struct {
- ttyperm_t t_t;
- ttychar_t t_c;
- struct termios t_ex, t_ed, t_ts;
- int t_tabs;
- int t_eight;
- speed_t t_speed;
- int t_mode;
- unsigned char t_vdisable;
-} el_tty_t;
-
-
-#endif /* _h_el_tty */
diff --git a/1.4/main/editline/vi.c b/1.4/main/editline/vi.c
deleted file mode 100644
index 5683c7de0..000000000
--- a/1.4/main/editline/vi.c
+++ /dev/null
@@ -1,941 +0,0 @@
-/* $NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * vi.c: Vi mode commands.
- */
-#include "el.h"
-
-private el_action_t cv_action(EditLine *, int);
-private el_action_t cv_paste(EditLine *, int);
-
-/* cv_action():
- * Handle vi actions.
- */
-private el_action_t
-cv_action(EditLine *el, int c)
-{
- char *cp, *kp;
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_vcmd.pos = 0;
-
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- kp = el->el_chared.c_undo.buf;
- for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
- *kp++ = *cp;
- el->el_chared.c_undo.dsize++;
- }
-
- el->el_chared.c_undo.action = INSERT;
- el->el_chared.c_undo.ptr = el->el_line.buffer;
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- if (c & INSERT)
- el->el_map.current = el->el_map.key;
-
- return (CC_REFRESH);
- }
- el->el_chared.c_vcmd.pos = el->el_line.cursor;
- el->el_chared.c_vcmd.action = c;
- return (CC_ARGHACK);
-
-#ifdef notdef
- /*
- * I don't think that this is needed. But we keep it for now
- */
- else
- if (el_chared.c_vcmd.action == NOP) {
- el->el_chared.c_vcmd.pos = el->el_line.cursor;
- el->el_chared.c_vcmd.action = c;
- return (CC_ARGHACK);
- } else {
- el->el_chared.c_vcmd.action = 0;
- el->el_chared.c_vcmd.pos = 0;
- return (CC_ERROR);
- }
-#endif
-}
-
-
-/* cv_paste():
- * Paste previous deletion before or after the cursor
- */
-private el_action_t
-cv_paste(EditLine *el, int c)
-{
- char *ptr;
- c_undo_t *un = &el->el_chared.c_undo;
-
-#ifdef DEBUG_PASTE
- (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n",
- un->action, un->buf, un->isize, un->dsize);
-#endif
- if (un->isize == 0)
- return (CC_ERROR);
-
- if (!c && el->el_line.cursor < el->el_line.lastchar)
- el->el_line.cursor++;
- ptr = el->el_line.cursor;
-
- c_insert(el, (int) un->isize);
- if (el->el_line.cursor + un->isize > el->el_line.lastchar)
- return (CC_ERROR);
- (void) memcpy(ptr, un->buf, un->isize);
- return (CC_REFRESH);
-}
-
-
-/* vi_paste_next():
- * Vi paste previous deletion to the right of the cursor
- * [p]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_paste_next(EditLine *el, int c)
-{
-
- return (cv_paste(el, 0));
-}
-
-
-/* vi_paste_prev():
- * Vi paste previous deletion to the left of the cursor
- * [P]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_paste_prev(EditLine *el, int c)
-{
-
- return (cv_paste(el, 1));
-}
-
-
-/* vi_prev_space_word():
- * Vi move to the previous space delimited word
- * [B]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_prev_space_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
-
- el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
- el->el_line.buffer,
- el->el_state.argument,
- cv__isword);
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* vi_prev_word():
- * Vi move to the previous word
- * [B]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_prev_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
-
- el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
- el->el_line.buffer,
- el->el_state.argument,
- ce__isword);
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* vi_next_space_word():
- * Vi move to the next space delimited word
- * [W]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_next_space_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
-
- el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
- el->el_line.lastchar,
- el->el_state.argument,
- cv__isword);
-
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* vi_next_word():
- * Vi move to the next word
- * [w]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_next_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
-
- el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
- el->el_line.lastchar,
- el->el_state.argument,
- ce__isword);
-
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* vi_change_case():
- * Vi change case of character under the cursor and advance one character
- * [~]
- */
-protected el_action_t
-vi_change_case(EditLine *el, int c)
-{
-
- if (el->el_line.cursor < el->el_line.lastchar) {
- c = *el->el_line.cursor;
- if (isupper(c))
- *el->el_line.cursor++ = tolower(c);
- else if (islower(c))
- *el->el_line.cursor++ = toupper(c);
- else
- el->el_line.cursor++;
- re_fastaddc(el);
- return (CC_NORM);
- }
- return (CC_ERROR);
-}
-
-
-/* vi_change_meta():
- * Vi change prefix command
- * [c]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_change_meta(EditLine *el, int c)
-{
-
- /*
- * Delete with insert == change: first we delete and then we leave in
- * insert mode.
- */
- return (cv_action(el, DELETE | INSERT));
-}
-
-
-/* vi_insert_at_bol():
- * Vi enter insert mode at the beginning of line
- * [I]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_insert_at_bol(EditLine *el, int c)
-{
-
- el->el_line.cursor = el->el_line.buffer;
- el->el_chared.c_vcmd.ins = el->el_line.cursor;
-
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.action = DELETE;
-
- el->el_map.current = el->el_map.key;
- return (CC_CURSOR);
-}
-
-
-/* vi_replace_char():
- * Vi replace character under the cursor with the next character typed
- * [r]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_replace_char(EditLine *el, int c)
-{
-
- el->el_map.current = el->el_map.key;
- el->el_state.inputmode = MODE_REPLACE_1;
- el->el_chared.c_undo.action = CHANGE;
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- return (CC_NORM);
-}
-
-
-/* vi_replace_mode():
- * Vi enter replace mode
- * [R]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_replace_mode(EditLine *el, int c)
-{
-
- el->el_map.current = el->el_map.key;
- el->el_state.inputmode = MODE_REPLACE;
- el->el_chared.c_undo.action = CHANGE;
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- return (CC_NORM);
-}
-
-
-/* vi_substitute_char():
- * Vi replace character under the cursor and enter insert mode
- * [r]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_substitute_char(EditLine *el, int c)
-{
-
- c_delafter(el, el->el_state.argument);
- el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
-}
-
-
-/* vi_substitute_line():
- * Vi substitute entire line
- * [S]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_substitute_line(EditLine *el, int c)
-{
-
- (void) em_kill_line(el, 0);
- el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
-}
-
-
-/* vi_change_to_eol():
- * Vi change to end of line
- * [C]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_change_to_eol(EditLine *el, int c)
-{
-
- (void) ed_kill_line(el, 0);
- el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
-}
-
-
-/* vi_insert():
- * Vi enter insert mode
- * [i]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_insert(EditLine *el, int c)
-{
-
- el->el_map.current = el->el_map.key;
-
- el->el_chared.c_vcmd.ins = el->el_line.cursor;
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.action = DELETE;
-
- return (CC_NORM);
-}
-
-
-/* vi_add():
- * Vi enter insert mode after the cursor
- * [a]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_add(EditLine *el, int c)
-{
- int ret;
-
- el->el_map.current = el->el_map.key;
- if (el->el_line.cursor < el->el_line.lastchar) {
- el->el_line.cursor++;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- ret = CC_CURSOR;
- } else
- ret = CC_NORM;
-
- el->el_chared.c_vcmd.ins = el->el_line.cursor;
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.action = DELETE;
-
- return (ret);
-}
-
-
-/* vi_add_at_eol():
- * Vi enter insert mode at end of line
- * [A]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_add_at_eol(EditLine *el, int c)
-{
-
- el->el_map.current = el->el_map.key;
- el->el_line.cursor = el->el_line.lastchar;
-
- /* Mark where insertion begins */
- el->el_chared.c_vcmd.ins = el->el_line.lastchar;
- el->el_chared.c_undo.ptr = el->el_line.lastchar;
- el->el_chared.c_undo.action = DELETE;
- return (CC_CURSOR);
-}
-
-
-/* vi_delete_meta():
- * Vi delete prefix command
- * [d]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_delete_meta(EditLine *el, int c)
-{
-
- return (cv_action(el, DELETE));
-}
-
-
-/* vi_end_word():
- * Vi move to the end of the current space delimited word
- * [E]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_end_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
-
- el->el_line.cursor = cv__endword(el->el_line.cursor,
- el->el_line.lastchar, el->el_state.argument);
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- el->el_line.cursor++;
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* vi_to_end_word():
- * Vi move to the end of the current word
- * [e]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_to_end_word(EditLine *el, int c)
-{
-
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
-
- el->el_line.cursor = cv__endword(el->el_line.cursor,
- el->el_line.lastchar, el->el_state.argument);
-
- if (el->el_chared.c_vcmd.action & DELETE) {
- el->el_line.cursor++;
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
-}
-
-
-/* vi_undo():
- * Vi undo last change
- * [u]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_undo(EditLine *el, int c)
-{
- char *cp, *kp;
- char temp;
- int i, size;
- c_undo_t *un = &el->el_chared.c_undo;
-
-#ifdef DEBUG_UNDO
- (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n",
- un->action, un->buf, un->isize, un->dsize);
-#endif
- switch (un->action) {
- case DELETE:
- if (un->dsize == 0)
- return (CC_NORM);
-
- (void) memcpy(un->buf, un->ptr, un->dsize);
- for (cp = un->ptr; cp <= el->el_line.lastchar; cp++)
- *cp = cp[un->dsize];
-
- el->el_line.lastchar -= un->dsize;
- el->el_line.cursor = un->ptr;
-
- un->action = INSERT;
- un->isize = un->dsize;
- un->dsize = 0;
- break;
-
- case DELETE | INSERT:
- size = un->isize - un->dsize;
- if (size > 0)
- i = un->dsize;
- else
- i = un->isize;
- cp = un->ptr;
- kp = un->buf;
- while (i-- > 0) {
- temp = *kp;
- *kp++ = *cp;
- *cp++ = temp;
- }
- if (size > 0) {
- el->el_line.cursor = cp;
- c_insert(el, size);
- while (size-- > 0 && cp < el->el_line.lastchar) {
- temp = *kp;
- *kp++ = *cp;
- *cp++ = temp;
- }
- } else if (size < 0) {
- size = -size;
- for (; cp <= el->el_line.lastchar; cp++) {
- *kp++ = *cp;
- *cp = cp[size];
- }
- el->el_line.lastchar -= size;
- }
- el->el_line.cursor = un->ptr;
- i = un->dsize;
- un->dsize = un->isize;
- un->isize = i;
- break;
-
- case INSERT:
- if (un->isize == 0)
- return (CC_NORM);
-
- el->el_line.cursor = un->ptr;
- c_insert(el, (int) un->isize);
- (void) memcpy(un->ptr, un->buf, un->isize);
- un->action = DELETE;
- un->dsize = un->isize;
- un->isize = 0;
- break;
-
- case CHANGE:
- if (un->isize == 0)
- return (CC_NORM);
-
- el->el_line.cursor = un->ptr;
- size = (int) (el->el_line.cursor - el->el_line.lastchar);
- if (size < un->isize)
- size = un->isize;
- cp = un->ptr;
- kp = un->buf;
- for (i = 0; i < size; i++) {
- temp = *kp;
- *kp++ = *cp;
- *cp++ = temp;
- }
- un->dsize = 0;
- break;
-
- default:
- return (CC_ERROR);
- }
-
- return (CC_REFRESH);
-}
-
-
-/* vi_command_mode():
- * Vi enter command mode (use alternative key bindings)
- * [<ESC>]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_command_mode(EditLine *el, int c)
-{
- int size;
-
- /* [Esc] cancels pending action */
- el->el_chared.c_vcmd.ins = 0;
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_vcmd.pos = 0;
-
- el->el_state.doingarg = 0;
- size = el->el_chared.c_undo.ptr - el->el_line.cursor;
- if (size < 0)
- size = -size;
- if (el->el_chared.c_undo.action == (INSERT | DELETE) ||
- el->el_chared.c_undo.action == DELETE)
- el->el_chared.c_undo.dsize = size;
- else
- el->el_chared.c_undo.isize = size;
-
- el->el_state.inputmode = MODE_INSERT;
- el->el_map.current = el->el_map.alt;
-#ifdef VI_MOVE
- if (el->el_line.cursor > el->el_line.buffer)
- el->el_line.cursor--;
-#endif
- return (CC_CURSOR);
-}
-
-
-/* vi_zero():
- * Vi move to the beginning of line
- * [0]
- */
-protected el_action_t
-vi_zero(EditLine *el, int c)
-{
-
- if (el->el_state.doingarg) {
- if (el->el_state.argument > 1000000)
- return (CC_ERROR);
- el->el_state.argument =
- (el->el_state.argument * 10) + (c - '0');
- return (CC_ARGHACK);
- } else {
- el->el_line.cursor = el->el_line.buffer;
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
- }
-}
-
-
-/* vi_delete_prev_char():
- * Vi move to previous character (backspace)
- * [^H]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_delete_prev_char(EditLine *el, int c)
-{
-
- if (el->el_chared.c_vcmd.ins == 0)
- return (CC_ERROR);
-
- if (el->el_chared.c_vcmd.ins >
- el->el_line.cursor - el->el_state.argument)
- return (CC_ERROR);
-
- c_delbefore(el, el->el_state.argument);
- el->el_line.cursor -= el->el_state.argument;
-
- return (CC_REFRESH);
-}
-
-
-/* vi_list_or_eof():
- * Vi list choices for completion or indicate end of file if empty line
- * [^D]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_list_or_eof(EditLine *el, int c)
-{
-
-#ifdef notyet
- if (el->el_line.cursor == el->el_line.lastchar &&
- el->el_line.cursor == el->el_line.buffer) {
-#endif
- term_overwrite(el, STReof, 4); /* then do a EOF */
- term__flush();
- return (CC_EOF);
-#ifdef notyet
- } else {
- re_goto_bottom(el);
- *el->el_line.lastchar = '\0'; /* just in case */
- return (CC_LIST_CHOICES);
- }
-#endif
-}
-
-
-/* vi_kill_line_prev():
- * Vi cut from beginning of line to cursor
- * [^U]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_kill_line_prev(EditLine *el, int c)
-{
- char *kp, *cp;
-
- cp = el->el_line.buffer;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.cursor)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- c_delbefore(el, el->el_line.cursor - el->el_line.buffer);
- el->el_line.cursor = el->el_line.buffer; /* zap! */
- return (CC_REFRESH);
-}
-
-
-/* vi_search_prev():
- * Vi search history previous
- * [?]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_search_prev(EditLine *el, int c)
-{
-
- return (cv_search(el, ED_SEARCH_PREV_HISTORY));
-}
-
-
-/* vi_search_next():
- * Vi search history next
- * [/]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_search_next(EditLine *el, int c)
-{
-
- return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
-}
-
-
-/* vi_repeat_search_next():
- * Vi repeat current search in the same search direction
- * [n]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_repeat_search_next(EditLine *el, int c)
-{
-
- if (el->el_search.patlen == 0)
- return (CC_ERROR);
- else
- return (cv_repeat_srch(el, el->el_search.patdir));
-}
-
-
-/* vi_repeat_search_prev():
- * Vi repeat current search in the opposite search direction
- * [N]
- */
-/*ARGSUSED*/
-protected el_action_t
-vi_repeat_search_prev(EditLine *el, int c)
-{
-
- if (el->el_search.patlen == 0)
- return (CC_ERROR);
- else
- return (cv_repeat_srch(el,
- el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
- ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
-}
-
-
-/* vi_next_char():
- * Vi move to the character specified next
- * [f]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_next_char(EditLine *el, int c)
-{
- char ch;
-
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
-
- el->el_search.chadir = CHAR_FWD;
- el->el_search.chacha = ch;
-
- return (cv_csearch_fwd(el, ch, el->el_state.argument, 0));
-
-}
-
-
-/* vi_prev_char():
- * Vi move to the character specified previous
- * [F]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_prev_char(EditLine *el, int c)
-{
- char ch;
-
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
-
- el->el_search.chadir = CHAR_BACK;
- el->el_search.chacha = ch;
-
- return (cv_csearch_back(el, ch, el->el_state.argument, 0));
-}
-
-
-/* vi_to_next_char():
- * Vi move up to the character specified next
- * [t]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_to_next_char(EditLine *el, int c)
-{
- char ch;
-
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
-
- return (cv_csearch_fwd(el, ch, el->el_state.argument, 1));
-
-}
-
-
-/* vi_to_prev_char():
- * Vi move up to the character specified previous
- * [T]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_to_prev_char(EditLine *el, int c)
-{
- char ch;
-
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
-
- return (cv_csearch_back(el, ch, el->el_state.argument, 1));
-}
-
-
-/* vi_repeat_next_char():
- * Vi repeat current character search in the same search direction
- * [;]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_repeat_next_char(EditLine *el, int c)
-{
-
- if (el->el_search.chacha == 0)
- return (CC_ERROR);
-
- return (el->el_search.chadir == CHAR_FWD
- ? cv_csearch_fwd(el, el->el_search.chacha,
- el->el_state.argument, 0)
- : cv_csearch_back(el, el->el_search.chacha,
- el->el_state.argument, 0));
-}
-
-
-/* vi_repeat_prev_char():
- * Vi repeat current character search in the opposite search direction
- * [,]
- */
-protected el_action_t
-/*ARGSUSED*/
-vi_repeat_prev_char(EditLine *el, int c)
-{
-
- if (el->el_search.chacha == 0)
- return (CC_ERROR);
-
- return el->el_search.chadir == CHAR_BACK ?
- cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
- cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
-}
diff --git a/1.4/main/enum.c b/1.4/main/enum.c
deleted file mode 100644
index aece8e572..000000000
--- a/1.4/main/enum.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Funding provided by nic.at
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ENUM Support for Asterisk
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg Funding provided by nic.at
- *
- * \par Enum standards
- *
- * - NAPTR records: http://ietf.nri.reston.va.us/rfc/rfc2915.txt
- * - DNS SRV records: http://www.ietf.org/rfc/rfc2782.txt
- * - ENUM http://www.ietf.org/rfc/rfc3761.txt
- * - ENUM for H.323: http://www.ietf.org/rfc/rfc3762.txt
- * - ENUM SIP: http://www.ietf.org/rfc/rfc3764.txt
- * - IANA ENUM Services: http://www.iana.org/assignments/enum-services
- *
- * \par Possible improvement
- * \todo Implement a caching mechanism for multile enum lookups
- * - See http://bugs.digium.com/view.php?id=6739
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#if __APPLE_CC__ >= 1495
-#include <arpa/nameser_compat.h>
-#endif
-#include <resolv.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <regex.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/enum.h"
-#include "asterisk/dns.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/utils.h"
-
-#ifdef __APPLE__
-#undef T_NAPTR
-#define T_NAPTR 35
-#endif
-
-#ifdef __APPLE__
-#undef T_TXT
-#define T_TXT 16
-#endif
-
-#define TOPLEV "e164.arpa." /*!< The IETF Enum standard root, managed by the ITU */
-
-/* Linked list from config file */
-static struct enum_search {
- char toplev[512];
- struct enum_search *next;
-} *toplevs;
-
-static int enumver;
-
-AST_MUTEX_DEFINE_STATIC(enumlock);
-
-struct naptr {
- unsigned short order;
- unsigned short pref;
-} __attribute__ ((__packed__));
-
-/*! \brief Parse NAPTR record information elements */
-static unsigned int parse_ie(char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen)
-{
- unsigned int len, olen;
-
- len = olen = (unsigned int) src[0];
- src++;
- srclen--;
-
- if (len > srclen) {
- ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %d characters, got %d\n", len, srclen);
- return -1;
- }
-
- if (len > maxdatalen)
- len = maxdatalen;
- memcpy(data, src, len);
-
- return olen + 1;
-}
-
-/*! \brief Parse DNS NAPTR record used in ENUM ---*/
-static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, char *naptrinput)
-{
- char tech_return[80];
- unsigned char *oanswer = answer;
- char flags[512] = "";
- char services[512] = "";
- char *p;
- char regexp[512] = "";
- char repl[512] = "";
- char temp[512] = "";
- char delim;
- char *delim2;
- char *pattern, *subst, *d;
- int res;
- int regexp_len, size, backref;
- int d_len = sizeof(temp) - 1;
- regex_t preg;
- regmatch_t pmatch[9];
-
- tech_return[0] = '\0';
-
- dst[0] = '\0';
-
- if (len < sizeof(struct naptr)) {
- ast_log(LOG_WARNING, "NAPTR record length too short\n");
- return -1;
- }
- answer += sizeof(struct naptr);
- len -= sizeof(struct naptr);
- if ((res = parse_ie(flags, sizeof(flags) - 1, answer, len)) < 0) {
- ast_log(LOG_WARNING, "Failed to get flags from NAPTR record\n");
- return -1;
- } else {
- answer += res;
- len -= res;
- }
- if ((res = parse_ie(services, sizeof(services) - 1, answer, len)) < 0) {
- ast_log(LOG_WARNING, "Failed to get services from NAPTR record\n");
- return -1;
- } else {
- answer += res;
- len -= res;
- }
- if ((res = parse_ie(regexp, sizeof(regexp) - 1, answer, len)) < 0) {
- ast_log(LOG_WARNING, "Failed to get regexp from NAPTR record\n");
- return -1;
- } else {
- answer += res;
- len -= res;
- }
-
- if ((res = dn_expand(oanswer, answer + len, answer, repl, sizeof(repl) - 1)) < 0) {
- ast_log(LOG_WARNING, "Failed to expand hostname\n");
- return -1;
- }
-
- if (option_debug > 2) /* Advanced NAPTR debugging */
- ast_log(LOG_DEBUG, "NAPTR input='%s', flags='%s', services='%s', regexp='%s', repl='%s'\n",
- naptrinput, flags, services, regexp, repl);
-
- if (tolower(flags[0]) != 'u') {
- ast_log(LOG_WARNING, "NAPTR Flag must be 'U' or 'u'.\n");
- return -1;
- }
-
- p = strstr(services, "e2u+");
- if (p == NULL)
- p = strstr(services, "E2U+");
- if (p){
- p = p + 4;
- if (strchr(p, ':')){
- p = strchr(p, ':') + 1;
- }
- ast_copy_string(tech_return, p, sizeof(tech_return));
- } else {
-
- p = strstr(services, "+e2u");
- if (p == NULL)
- p = strstr(services, "+E2U");
- if (p) {
- *p = 0;
- p = strchr(services, ':');
- if (p)
- *p = 0;
- ast_copy_string(tech_return, services, sizeof(tech_return));
- }
- }
-
- /* DEDBUGGING STUB
- ast_copy_string(regexp, "!^\\+43(.*)$!\\1@bla.fasel!", sizeof(regexp) - 1);
- */
-
- regexp_len = strlen(regexp);
- if (regexp_len < 7) {
- ast_log(LOG_WARNING, "Regex too short to be meaningful.\n");
- return -1;
- }
-
-
- delim = regexp[0];
- delim2 = strchr(regexp + 1, delim);
- if ((delim2 == NULL) || (regexp[regexp_len-1] != delim)) {
- ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n",regexp);
- return -1;
- }
-
- pattern = regexp + 1;
- *delim2 = 0;
- subst = delim2 + 1;
- regexp[regexp_len-1] = 0;
-
-/*
- * now do the regex wizardry.
- */
-
- if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) {
- ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n",regexp);
- return -1;
- }
-
- if (preg.re_nsub > 9) {
- ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n");
- regfree(&preg);
- return -1;
- }
-
- if (regexec(&preg, naptrinput, 9, pmatch, 0)) {
- ast_log(LOG_WARNING, "NAPTR Regex match failed.\n");
- regfree(&preg);
- return -1;
- }
- regfree(&preg);
-
- d = temp;
- d_len--;
- while (*subst && (d_len > 0)) {
- if ((subst[0] == '\\') && isdigit(subst[1]) && (pmatch[subst[1]-'0'].rm_so != -1)) {
- backref = subst[1]-'0';
- size = pmatch[backref].rm_eo - pmatch[backref].rm_so;
- if (size > d_len) {
- ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n");
- return -1;
- }
- memcpy(d, naptrinput + pmatch[backref].rm_so, size);
- d += size;
- d_len -= size;
- subst += 2;
- } else if (isprint(*subst)) {
- *d++ = *subst++;
- d_len--;
- } else {
- ast_log(LOG_WARNING, "Error during regex substitution.\n");
- return -1;
- }
- }
- *d = 0;
- ast_copy_string(dst, temp, dstsize);
- dst[dstsize - 1] = '\0';
-
- if (*tech != '\0'){ /* check if it is requested NAPTR */
- if (!strncasecmp(tech, "ALL", techsize)){
- return 1; /* return or count any RR */
- }
- if (!strncasecmp(tech_return, tech, sizeof(tech_return)<techsize?sizeof(tech_return):techsize)){
- ast_copy_string(tech, tech_return, techsize);
- return 1; /* we got out RR */
- } else { /* go to the next RR in the DNS answer */
- return 0;
- }
- }
-
- /* tech was not specified, return first parsed RR */
- ast_copy_string(tech, tech_return, techsize);
-
- return 1;
-}
-
-/* do not return requested value, just count RRs and return thei number in dst */
-#define ENUMLOOKUP_OPTIONS_COUNT 1
-
-struct enum_naptr_rr {
- struct naptr naptr; /* order and preference of RR */
- char *result; /* result of naptr parsing,e.g.: tel:+5553 */
- char *tech; /* Technology (from URL scheme) */
- int sort_pos; /* sort position */
-};
-
-struct enum_context {
- char *dst; /* Destination part of URL from ENUM */
- int dstlen; /* Length */
- char *tech; /* Technology (from URL scheme) */
- int techlen; /* Length */
- char *txt; /* TXT record in TXT lookup */
- int txtlen; /* Length */
- char *naptrinput; /* The number to lookup */
- int position; /* used as counter for RRs or specifies position of required RR */
- int options; /* options , see ENUMLOOKUP_OPTIONS_* defined above */
- struct enum_naptr_rr *naptr_rrs; /* array of parsed NAPTR RRs */
- int naptr_rrs_count; /* Size of array naptr_rrs */
-};
-
-/*! \brief Callback for TXT record lookup */
-static int txt_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
-{
- struct enum_context *c = (struct enum_context *)context;
-
- if (answer == NULL) {
- c->txt = NULL;
- c->txtlen = 0;
- return 0;
- }
-
- /* skip over first byte, as for some reason it's a vertical tab character */
- answer += 1;
- len -= 1;
-
- /* answer is not null-terminated, but should be */
- /* this is safe to do, as answer has extra bytes on the end we can
- * safely overwrite with a null */
- answer[len] = '\0';
- /* now increment len so that len includes the null, so that we can
- * compare apples to apples */
- len +=1;
-
- /* finally, copy the answer into c->txt */
- ast_copy_string(c->txt, (const char *) answer, len < c->txtlen ? len : (c->txtlen));
-
- /* just to be safe, let's make sure c->txt is null terminated */
- c->txt[(c->txtlen)-1] = '\0';
-
- return 1;
-}
-
-/*! \brief Callback from ENUM lookup function */
-static int enum_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
-{
- struct enum_context *c = context;
- void *p = NULL;
- int res;
-
- res = parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput);
-
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to parse naptr :(\n");
- return -1;
- } else if (res > 0 && !ast_strlen_zero(c->dst)){ /* ok, we got needed NAPTR */
- if (c->options & ENUMLOOKUP_OPTIONS_COUNT){ /* counting RRs */
- c->position++;
- snprintf(c->dst, c->dstlen, "%d", c->position);
- } else {
- if ((p = ast_realloc(c->naptr_rrs, sizeof(*c->naptr_rrs) * (c->naptr_rrs_count + 1)))) {
- c->naptr_rrs = p;
- memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(c->naptr_rrs->naptr));
- c->naptr_rrs[c->naptr_rrs_count].result = strdup(c->dst);
- c->naptr_rrs[c->naptr_rrs_count].tech = strdup(c->tech);
- c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count;
- c->naptr_rrs_count++;
- }
- c->dst[0] = 0;
- }
- return 0;
- }
-
- if (c->options & ENUMLOOKUP_OPTIONS_COUNT) { /* counting RRs */
- snprintf(c->dst, c->dstlen, "%d", c->position);
- }
-
- return 0;
-}
-
-/*! \brief ENUM lookup */
-int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char* suffix, char* options, unsigned int record)
-{
- struct enum_context context;
- char tmp[259 + 512];
- char naptrinput[512];
- int pos = strlen(number) - 1;
- int newpos = 0;
- int ret = -1;
- struct enum_search *s = NULL;
- int version = -1;
- /* for ISN rewrite */
- char *p1 = NULL;
- char *p2 = NULL;
- int k = 0;
- int i = 0;
- int z = 0;
-
- ast_copy_string(naptrinput, number[0] == 'n' ? number+1 : number, sizeof(naptrinput));
-
- context.naptrinput = naptrinput; /* The number */
- context.dst = dst; /* Return string */
- context.dstlen = dstlen;
- context.tech = tech;
- context.techlen = techlen;
- context.options = 0;
- context.position = record;
- context.naptr_rrs = NULL;
- context.naptr_rrs_count = 0;
-
- if (options != NULL) {
- if (*options == 'c') {
- context.options = ENUMLOOKUP_OPTIONS_COUNT;
- context.position = 0;
- }
- }
-
- ast_log(LOG_DEBUG, "ast_get_enum(): n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n",
- number, tech, suffix, context.options, context.position);
-
- if (pos > 128)
- pos = 128;
-
- /* ISN rewrite */
- p1 = strchr(number, '*');
-
- if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */
- p1 = NULL;
- k = 1; /* strip 'n' from number */
- }
-
- if (p1 != NULL) {
- p2 = p1+1;
- while (p1 > number){
- p1--;
- tmp[newpos++] = *p1;
- tmp[newpos++] = '.';
- }
- if (*p2) {
- while(*p2 && newpos < 128){
- tmp[newpos++] = *p2;
- p2++;
- }
- tmp[newpos++] = '.';
- }
-
- } else {
- while (pos >= k) {
- if (isdigit(number[pos])) {
- tmp[newpos++] = number[pos];
- tmp[newpos++] = '.';
- }
- pos--;
- }
- }
-
- if (chan && ast_autoservice_start(chan) < 0)
- return -1;
-
- if(suffix) {
- ast_copy_string(tmp + newpos, suffix, sizeof(tmp) - newpos);
- ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
- ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret);
- } else {
- ret = -1; /* this is actually dead code since the demise of app_enum.c */
- for (;;) {
- ast_mutex_lock(&enumlock);
- if (version != enumver) {
- /* Ooh, a reload... */
- s = toplevs;
- version = enumver;
- } else {
- s = s->next;
- }
- ast_mutex_unlock(&enumlock);
-
- if (!s)
- break;
-
- ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos);
- ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
- ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret);
- if (ret > 0)
- break;
- }
- }
-
- if (ret < 0) {
- ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
- strcpy(dst, "0");
- ret = 0;
- }
-
- if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
- /* sort array by NAPTR order/preference */
- for (k = 0; k < context.naptr_rrs_count; k++) {
- for (i = 0; i < context.naptr_rrs_count; i++) {
- /* use order first and then preference to compare */
- if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
- && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
- || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
- && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
- z = context.naptr_rrs[k].sort_pos;
- context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
- context.naptr_rrs[i].sort_pos = z;
- continue;
- }
- if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
- if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
- && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
- || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
- && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
- z = context.naptr_rrs[k].sort_pos;
- context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
- context.naptr_rrs[i].sort_pos = z;
- }
- }
- }
- }
- for (k = 0; k < context.naptr_rrs_count; k++) {
- if (context.naptr_rrs[k].sort_pos == context.position-1) {
- ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
- ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
- break;
- }
- }
- } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
- context.dst[0] = 0;
- }
- if (chan)
- ret |= ast_autoservice_stop(chan);
-
- for (k = 0; k < context.naptr_rrs_count; k++) {
- free(context.naptr_rrs[k].result);
- free(context.naptr_rrs[k].tech);
- }
-
- free(context.naptr_rrs);
-
- return ret;
-}
-
-/*! \brief Get TXT record from DNS.
- Really has nothing to do with enum, but anyway...
- */
-int ast_get_txt(struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char *txt, int txtlen)
-{
- struct enum_context context;
- char tmp[259 + 512];
- char naptrinput[512] = "+";
- int pos = strlen(number) - 1;
- int newpos = 0;
- int ret = -1;
- struct enum_search *s = NULL;
- int version = -1;
-
- strncat(naptrinput, number, sizeof(naptrinput) - 2);
-
- context.naptrinput = naptrinput;
- context.dst = dst;
- context.dstlen = dstlen;
- context.tech = tech;
- context.techlen = techlen;
- context.txt = txt;
- context.txtlen = txtlen;
-
- if (pos > 128)
- pos = 128;
- while (pos >= 0) {
- tmp[newpos++] = number[pos--];
- tmp[newpos++] = '.';
- }
-
- if (chan && ast_autoservice_start(chan) < 0)
- return -1;
-
- for (;;) {
- ast_mutex_lock(&enumlock);
- if (version != enumver) {
- /* Ooh, a reload... */
- s = toplevs;
- version = enumver;
- } else {
- s = s->next;
- }
- if (s) {
- ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos);
- }
- ast_mutex_unlock(&enumlock);
- if (!s)
- break;
-
- ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback);
- if (ret > 0)
- break;
- }
- if (ret < 0) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno));
- ret = 0;
- }
- if (chan)
- ret |= ast_autoservice_stop(chan);
- return ret;
-}
-
-/*! \brief Add enum tree to linked list */
-static struct enum_search *enum_newtoplev(char *s)
-{
- struct enum_search *tmp;
-
- if ((tmp = ast_calloc(1, sizeof(*tmp)))) {
- ast_copy_string(tmp->toplev, s, sizeof(tmp->toplev));
- }
- return tmp;
-}
-
-/*! \brief Initialize the ENUM support subsystem */
-int ast_enum_init(void)
-{
- struct ast_config *cfg;
- struct enum_search *s, *sl;
- struct ast_variable *v;
-
- /* Destroy existing list */
- ast_mutex_lock(&enumlock);
- s = toplevs;
- while(s) {
- sl = s;
- s = s->next;
- free(sl);
- }
- toplevs = NULL;
- cfg = ast_config_load("enum.conf");
- if (cfg) {
- sl = NULL;
- v = ast_variable_browse(cfg, "general");
- while(v) {
- if (!strcasecmp(v->name, "search")) {
- s = enum_newtoplev(v->value);
- if (s) {
- if (sl)
- sl->next = s;
- else
- toplevs = s;
- sl = s;
- }
- }
- v = v->next;
- }
- ast_config_destroy(cfg);
- } else {
- toplevs = enum_newtoplev(TOPLEV);
- }
- enumver++;
- ast_mutex_unlock(&enumlock);
- return 0;
-}
-
-int ast_enum_reload(void)
-{
- return ast_enum_init();
-}
diff --git a/1.4/main/file.c b/1.4/main/file.c
deleted file mode 100644
index 340eb4ee3..000000000
--- a/1.4/main/file.c
+++ /dev/null
@@ -1,1343 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Generic File Format Support.
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/sched.h"
-#include "asterisk/options.h"
-#include "asterisk/translate.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/app.h"
-#include "asterisk/pbx.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/module.h"
-
-/*
- * The following variable controls the layout of localized sound files.
- * If 0, use the historical layout with prefix just before the filename
- * (i.e. digits/en/1.gsm , digits/it/1.gsm or default to digits/1.gsm),
- * if 1 put the prefix at the beginning of the filename
- * (i.e. en/digits/1.gsm, it/digits/1.gsm or default to digits/1.gsm).
- * The latter permits a language to be entirely in one directory.
- */
-int ast_language_is_prefix;
-
-static AST_LIST_HEAD_STATIC(formats, ast_format);
-
-int __ast_format_register(const struct ast_format *f, struct ast_module *mod)
-{
- struct ast_format *tmp;
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return -1;
- }
- AST_LIST_TRAVERSE(&formats, tmp, list) {
- if (!strcasecmp(f->name, tmp->name)) {
- AST_LIST_UNLOCK(&formats);
- ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
- return -1;
- }
- }
- if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
- AST_LIST_UNLOCK(&formats);
- return -1;
- }
- *tmp = *f;
- tmp->module = mod;
- if (tmp->buf_size) {
- /*
- * Align buf_size properly, rounding up to the machine-specific
- * alignment for pointers.
- */
- struct _test_align { void *a, *b; } p;
- int align = (char *)&p.b - (char *)&p.a;
- tmp->buf_size = ((f->buf_size + align - 1)/align)*align;
- }
-
- memset(&tmp->list, 0, sizeof(tmp->list));
-
- AST_LIST_INSERT_HEAD(&formats, tmp, list);
- AST_LIST_UNLOCK(&formats);
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts);
-
- return 0;
-}
-
-int ast_format_unregister(const char *name)
-{
- struct ast_format *tmp;
- int res = -1;
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return -1;
- }
- AST_LIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
- if (!strcasecmp(name, tmp->name)) {
- AST_LIST_REMOVE_CURRENT(&formats, list);
- free(tmp);
- res = 0;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&formats);
-
- if (!res) {
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
- } else
- ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
-
- return res;
-}
-
-int ast_stopstream(struct ast_channel *tmp)
-{
- ast_channel_lock(tmp);
-
- /* Stop a running stream if there is one */
- if (tmp->stream) {
- ast_closestream(tmp->stream);
- tmp->stream = NULL;
- if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
- ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
- }
- /* Stop the video stream too */
- if (tmp->vstream != NULL) {
- ast_closestream(tmp->vstream);
- tmp->vstream = NULL;
- }
-
- ast_channel_unlock(tmp);
-
- return 0;
-}
-
-int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
-{
- int res = -1;
- int alt = 0;
- if (f->frametype == AST_FRAME_VIDEO) {
- if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) {
- /* This is the audio portion. Call the video one... */
- if (!fs->vfs && fs->filename) {
- const char *type = ast_getformatname(f->subclass & ~0x1);
- fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
- ast_log(LOG_DEBUG, "Opened video output file\n");
- }
- if (fs->vfs)
- return ast_writestream(fs->vfs, f);
- /* else ignore */
- return 0;
- } else {
- /* Might / might not have mark set */
- alt = 1;
- }
- } else if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
- return -1;
- }
- if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
- res = fs->fmt->write(fs, f);
- if (res < 0)
- ast_log(LOG_WARNING, "Natural write failed\n");
- else if (res > 0)
- ast_log(LOG_WARNING, "Huh??\n");
- } else {
- /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
- the one we've setup a translator for, we do the "wrong thing" XXX */
- if (fs->trans && f->subclass != fs->lastwriteformat) {
- ast_translator_free_path(fs->trans);
- fs->trans = NULL;
- }
- if (!fs->trans)
- fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
- if (!fs->trans)
- ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
- fs->fmt->name, ast_getformatname(f->subclass));
- else {
- struct ast_frame *trf;
- fs->lastwriteformat = f->subclass;
- /* Get the translated frame but don't consume the original in case they're using it on another stream */
- trf = ast_translate(fs->trans, f, 0);
- if (trf) {
- res = fs->fmt->write(fs, trf);
- ast_frfree(trf);
- if (res)
- ast_log(LOG_WARNING, "Translated frame write failed\n");
- } else
- res = 0;
- }
- }
- return res;
-}
-
-static int copy(const char *infile, const char *outfile)
-{
- int ifd, ofd, len;
- char buf[4096]; /* XXX make it lerger. */
-
- if ((ifd = open(infile, O_RDONLY)) < 0) {
- ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
- return -1;
- }
- if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
- ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
- close(ifd);
- return -1;
- }
- while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
- int res;
- if (len < 0) {
- ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
- break;
- }
- /* XXX handle partial writes */
- res = write(ofd, buf, len);
- if (res != len) {
- ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
- len = -1; /* error marker */
- break;
- }
- }
- close(ifd);
- close(ofd);
- if (len < 0) {
- unlink(outfile);
- return -1; /* error */
- }
- return 0; /* success */
-}
-
-/*!
- * \brief construct a filename. Absolute pathnames are preserved,
- * relative names are prefixed by the sounds/ directory.
- * The wav49 suffix is replaced by 'WAV'.
- * Returns a malloc'ed string to be freed by the caller.
- */
-static char *build_filename(const char *filename, const char *ext)
-{
- char *fn = NULL;
-
- if (!strcmp(ext, "wav49"))
- ext = "WAV";
-
- if (filename[0] == '/')
- asprintf(&fn, "%s.%s", filename, ext);
- else
- asprintf(&fn, "%s/sounds/%s.%s",
- ast_config_AST_DATA_DIR, filename, ext);
- return fn;
-}
-
-/* compare type against the list 'exts' */
-/* XXX need a better algorithm */
-static int exts_compare(const char *exts, const char *type)
-{
- char tmp[256];
- char *stringp = tmp, *ext;
-
- ast_copy_string(tmp, exts, sizeof(tmp));
- while ((ext = strsep(&stringp, "|"))) {
- if (!strcmp(ext, type))
- return 1;
- }
-
- return 0;
-}
-
-static struct ast_filestream *get_filestream(struct ast_format *fmt, FILE *bfile)
-{
- struct ast_filestream *s;
-
- int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */
- if ( (s = ast_calloc(1, l)) == NULL)
- return NULL;
- s->fmt = fmt;
- s->f = bfile;
-
- if (fmt->desc_size)
- s->_private = ((char *)(s+1)) + fmt->buf_size;
- if (fmt->buf_size)
- s->buf = (char *)(s+1);
- s->fr.src = fmt->name;
- return s;
-}
-
-/*
- * Default implementations of open and rewrite.
- * Only use them if you don't have expensive stuff to do.
- */
-enum wrap_fn { WRAP_OPEN, WRAP_REWRITE };
-
-static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
-{
- struct ast_format *f = s->fmt;
- int ret = -1;
-
- if (mode == WRAP_OPEN && f->open && f->open(s))
- ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
- else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
- ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
- else {
- /* preliminary checks succeed. update usecount */
- ast_module_ref(f->module);
- ret = 0;
- }
- return ret;
-}
-
-static int rewrite_wrapper(struct ast_filestream *s, const char *comment)
-{
- return fn_wrapper(s, comment, WRAP_REWRITE);
-}
-
-static int open_wrapper(struct ast_filestream *s)
-{
- return fn_wrapper(s, NULL, WRAP_OPEN);
-}
-
-enum file_action {
- ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
- ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
- ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
- ACTION_OPEN,
- ACTION_COPY /* copy file. return 0 on success, -1 on error */
-};
-
-/*!
- * \brief perform various actions on a file. Second argument
- * arg2 depends on the command:
- * unused for EXISTS and DELETE
- * destination file name (const char *) for COPY and RENAME
- * struct ast_channel * for OPEN
- * if fmt is NULL, OPEN will return the first matching entry,
- * whereas other functions will run on all matching entries.
- */
-static int ast_filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
-{
- struct ast_format *f;
- int res = (action == ACTION_EXISTS) ? 0 : -1;
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return res;
- }
- /* Check for a specific format */
- AST_LIST_TRAVERSE(&formats, f, list) {
- char *stringp, *ext = NULL;
-
- if (fmt && !exts_compare(f->exts, fmt))
- continue;
-
- /* Look for a file matching the supported extensions.
- * The file must exist, and for OPEN, must match
- * one of the formats supported by the channel.
- */
- stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */
- while ( (ext = strsep(&stringp, "|")) ) {
- struct stat st;
- char *fn = build_filename(filename, ext);
-
- if (fn == NULL)
- continue;
-
- if ( stat(fn, &st) ) { /* file not existent */
- free(fn);
- continue;
- }
- /* for 'OPEN' we need to be sure that the format matches
- * what the channel can process
- */
- if (action == ACTION_OPEN) {
- struct ast_channel *chan = (struct ast_channel *)arg2;
- FILE *bfile;
- struct ast_filestream *s;
-
- if ( !(chan->writeformat & f->format) &&
- !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) {
- free(fn);
- continue; /* not a supported format */
- }
- if ( (bfile = fopen(fn, "r")) == NULL) {
- free(fn);
- continue; /* cannot open file */
- }
- s = get_filestream(f, bfile);
- if (!s) {
- fclose(bfile);
- free(fn); /* cannot allocate descriptor */
- continue;
- }
- if (open_wrapper(s)) {
- fclose(bfile);
- free(fn);
- free(s);
- continue; /* cannot run open on file */
- }
- /* ok this is good for OPEN */
- res = 1; /* found */
- s->lasttimeout = -1;
- s->fmt = f;
- s->trans = NULL;
- s->filename = NULL;
- if (s->fmt->format < AST_FORMAT_MAX_AUDIO) {
- if (chan->stream)
- ast_closestream(chan->stream);
- chan->stream = s;
- } else {
- if (chan->vstream)
- ast_closestream(chan->vstream);
- chan->vstream = s;
- }
- free(fn);
- break;
- }
- switch (action) {
- case ACTION_OPEN:
- break; /* will never get here */
-
- case ACTION_EXISTS: /* return the matching format */
- res |= f->format;
- break;
-
- case ACTION_DELETE:
- if ( (res = unlink(fn)) )
- ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
- break;
-
- case ACTION_RENAME:
- case ACTION_COPY: {
- char *nfn = build_filename((const char *)arg2, ext);
- if (!nfn)
- ast_log(LOG_WARNING, "Out of memory\n");
- else {
- res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
- if (res)
- ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
- action == ACTION_COPY ? "copy" : "rename",
- fn, nfn, strerror(errno));
- free(nfn);
- }
- }
- break;
-
- default:
- ast_log(LOG_WARNING, "Unknown helper %d\n", action);
- }
- free(fn);
- }
- }
- AST_LIST_UNLOCK(&formats);
- return res;
-}
-
-static int is_absolute_path(const char *filename)
-{
- return filename[0] == '/';
-}
-
-static int fileexists_test(const char *filename, const char *fmt, const char *lang,
- char *buf, int buflen)
-{
- if (buf == NULL) {
- return -1;
- }
-
- if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
- if (lang) {
- snprintf(buf, buflen, "%s/%s", lang, filename);
- } else {
- snprintf(buf, buflen, "%s", filename);
- }
- } else { /* old layout */
- strcpy(buf, filename); /* first copy the full string */
- if (lang) {
- /* insert the language and suffix if needed */
- const char *c = strrchr(filename, '/');
- int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
- snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
- }
- }
-
- return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
-}
-
-/*!
- * \brief helper routine to locate a file with a given format
- * and language preference.
- * Try preflang, preflang with stripped '_' suffix, or NULL.
- * In the standard asterisk, language goes just before the last component.
- * In an alternative configuration, the language should be a prefix
- * to the actual filename.
- *
- * The last parameter(s) point to a buffer of sufficient size,
- * which on success is filled with the matching filename.
- */
-static int fileexists_core(const char *filename, const char *fmt, const char *preflang,
- char *buf, int buflen)
-{
- int res = -1;
- char *lang = NULL;
-
- if (buf == NULL) {
- return -1;
- }
-
- /* We try languages in the following order:
- * preflang (may include dialect)
- * lang (preflang without dialect - if any)
- * <none>
- * default (unless the same as preflang or lang without dialect)
- */
-
- /* Try preferred language */
- if (!ast_strlen_zero(preflang)) {
- /* try the preflang exactly as it was requested */
- if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) {
- return res;
- } else {
- /* try without a dialect */
- char *postfix = NULL;
- postfix = lang = ast_strdupa(preflang);
-
- strsep(&postfix, "_");
- if (postfix) {
- if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
- return res;
- }
- }
- }
- }
-
- /* Try without any language */
- if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
- return res;
- }
-
- /* Finally try the default language unless it was already tried before */
- if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
- if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
- return res;
- }
- }
-
- return 0;
-}
-
-struct ast_filestream *ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang)
-{
- return ast_openstream_full(chan, filename, preflang, 0);
-}
-
-struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char *filename, const char *preflang, int asis)
-{
- /*
- * Use fileexists_core() to find a file in a compatible
- * language and format, set up a suitable translator,
- * and open the stream.
- */
- int fmts, res, buflen;
- char *buf;
-
- if (!asis) {
- /* do this first, otherwise we detect the wrong writeformat */
- ast_stopstream(chan);
- if (chan->generator)
- ast_deactivate_generator(chan);
- }
- if (preflang == NULL)
- preflang = "";
- buflen = strlen(preflang) + strlen(filename) + 4;
- buf = alloca(buflen);
- if (buf == NULL)
- return NULL;
- fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
- if (fmts > 0)
- fmts &= AST_FORMAT_AUDIO_MASK;
- if (fmts < 1) {
- ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
- return NULL;
- }
- chan->oldwriteformat = chan->writeformat;
- /* Set the channel to a format we can work with */
- res = ast_set_write_format(chan, fmts);
- res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
- if (res >= 0)
- return chan->stream;
- return NULL;
-}
-
-struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang)
-{
- /* As above, but for video. But here we don't have translators
- * so we must enforce a format.
- */
- unsigned int format;
- char *buf;
- int buflen;
-
- if (preflang == NULL)
- preflang = "";
- buflen = strlen(preflang) + strlen(filename) + 4;
- buf = alloca(buflen);
- if (buf == NULL)
- return NULL;
-
- for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) {
- int fd;
- const char *fmt;
-
- if (!(chan->nativeformats & format))
- continue;
- fmt = ast_getformatname(format);
- if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */
- continue;
- fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
- if (fd >= 0)
- return chan->vstream;
- ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
- }
- return NULL;
-}
-
-struct ast_frame *ast_readframe(struct ast_filestream *s)
-{
- struct ast_frame *f = NULL;
- int whennext = 0;
- if (s && s->fmt)
- f = s->fmt->read(s, &whennext);
- return f;
-}
-
-enum fsread_res {
- FSREAD_FAILURE,
- FSREAD_SUCCESS_SCHED,
- FSREAD_SUCCESS_NOSCHED,
-};
-
-static int ast_fsread_audio(const void *data);
-
-static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
-{
- int whennext = 0;
-
- while (!whennext) {
- struct ast_frame *fr;
-
- if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name))
- goto return_failure;
-
- fr = s->fmt->read(s, &whennext);
- if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
- if (fr)
- ast_log(LOG_WARNING, "Failed to write frame\n");
- goto return_failure;
- }
- }
- if (whennext != s->lasttimeout) {
-#ifdef HAVE_ZAPTEL
- if (s->owner->timingfd > -1) {
- int zap_timer_samples = whennext;
- int rate;
- /* whennext is in samples, but zaptel timers operate in 8 kHz samples. */
- if ((rate = ast_format_rate(s->fmt->format)) != 8000) {
- float factor;
- factor = ((float) rate) / ((float) 8000.0);
- zap_timer_samples = (int) ( ((float) zap_timer_samples) / factor );
- }
- ast_settimeout(s->owner, zap_timer_samples, ast_fsread_audio, s);
- } else
-#endif
- s->owner->streamid = ast_sched_add(s->owner->sched,
- whennext / (ast_format_rate(s->fmt->format) / 1000),
- ast_fsread_audio, s);
- s->lasttimeout = whennext;
- return FSREAD_SUCCESS_NOSCHED;
- }
- return FSREAD_SUCCESS_SCHED;
-
-return_failure:
- s->owner->streamid = -1;
-#ifdef HAVE_ZAPTEL
- ast_settimeout(s->owner, 0, NULL, NULL);
-#endif
- return FSREAD_FAILURE;
-}
-
-static int ast_fsread_audio(const void *data)
-{
- struct ast_filestream *fs = (struct ast_filestream *)data;
- enum fsread_res res;
-
- res = ast_readaudio_callback(fs);
-
- if (res == FSREAD_SUCCESS_SCHED)
- return 1;
-
- return 0;
-}
-
-static int ast_fsread_video(const void *data);
-
-static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
-{
- int whennext = 0;
-
- while (!whennext) {
- struct ast_frame *fr = s->fmt->read(s, &whennext);
- if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */
- if (fr)
- ast_log(LOG_WARNING, "Failed to write frame\n");
- s->owner->vstreamid = -1;
- return FSREAD_FAILURE;
- }
- }
-
- if (whennext != s->lasttimeout) {
- s->owner->vstreamid = ast_sched_add(s->owner->sched,
- whennext / (ast_format_rate(s->fmt->format) / 1000),
- ast_fsread_video, s);
- s->lasttimeout = whennext;
- return FSREAD_SUCCESS_NOSCHED;
- }
-
- return FSREAD_SUCCESS_SCHED;
-}
-
-static int ast_fsread_video(const void *data)
-{
- struct ast_filestream *fs = (struct ast_filestream *)data;
- enum fsread_res res;
-
- res = ast_readvideo_callback(fs);
-
- if (res == FSREAD_SUCCESS_SCHED)
- return 1;
-
- return 0;
-}
-
-int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
-{
- s->owner = chan;
- return 0;
-}
-
-int ast_playstream(struct ast_filestream *s)
-{
- enum fsread_res res;
-
- if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
- res = ast_readaudio_callback(s);
- else
- res = ast_readvideo_callback(s);
-
- return (res == FSREAD_FAILURE) ? -1 : 0;
-}
-
-int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
-{
- return fs->fmt->seek(fs, sample_offset, whence);
-}
-
-int ast_truncstream(struct ast_filestream *fs)
-{
- return fs->fmt->trunc(fs);
-}
-
-off_t ast_tellstream(struct ast_filestream *fs)
-{
- return fs->fmt->tell(fs);
-}
-
-int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
-{
- return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
-}
-
-int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
-{
- return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
-}
-
-int ast_closestream(struct ast_filestream *f)
-{
- char *cmd = NULL;
- size_t size = 0;
- /* Stop a running stream if there is one */
- if (f->owner) {
- if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
- f->owner->stream = NULL;
- AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
-#ifdef HAVE_ZAPTEL
- ast_settimeout(f->owner, 0, NULL, NULL);
-#endif
- } else {
- f->owner->vstream = NULL;
- AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
- }
- }
- /* destroy the translator on exit */
- if (f->trans)
- ast_translator_free_path(f->trans);
-
- if (f->realfilename && f->filename) {
- size = strlen(f->filename) + strlen(f->realfilename) + 15;
- cmd = alloca(size);
- memset(cmd,0,size);
- snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
- ast_safe_system(cmd);
- }
-
- if (f->filename)
- free(f->filename);
- if (f->realfilename)
- free(f->realfilename);
- if (f->fmt->close)
- f->fmt->close(f);
- fclose(f->f);
- if (f->vfs)
- ast_closestream(f->vfs);
- if (f->orig_chan_name)
- free((void *) f->orig_chan_name);
- ast_module_unref(f->fmt->module);
- free(f);
- return 0;
-}
-
-
-/*
- * Look the various language-specific places where a file could exist.
- */
-int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
-{
- char *buf;
- int buflen;
-
- if (preflang == NULL)
- preflang = "";
- buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
- buf = alloca(buflen);
- if (buf == NULL)
- return 0;
- return fileexists_core(filename, fmt, preflang, buf, buflen);
-}
-
-int ast_filedelete(const char *filename, const char *fmt)
-{
- return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
-}
-
-int ast_filerename(const char *filename, const char *filename2, const char *fmt)
-{
- return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
-}
-
-int ast_filecopy(const char *filename, const char *filename2, const char *fmt)
-{
- return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
-}
-
-int ast_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
-{
- struct ast_filestream *fs;
- struct ast_filestream *vfs=NULL;
- char fmt[256];
-
- fs = ast_openstream(chan, filename, preflang);
- if (fs)
- vfs = ast_openvstream(chan, filename, preflang);
- if (vfs)
- ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
- if (fs){
- int res;
- if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
- fs->orig_chan_name = ast_strdup(chan->name);
- if (ast_applystream(chan, fs))
- return -1;
- if (vfs && ast_applystream(chan, vfs))
- return -1;
- res = ast_playstream(fs);
- if (!res && vfs)
- res = ast_playstream(vfs);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default");
-
- return res;
- }
- ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
- return -1;
-}
-
-struct ast_filestream *ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
-{
- FILE *bfile;
- struct ast_format *f;
- struct ast_filestream *fs = NULL;
- char *fn;
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return NULL;
- }
-
- AST_LIST_TRAVERSE(&formats, f, list) {
- fs = NULL;
- if (!exts_compare(f->exts, type))
- continue;
-
- fn = build_filename(filename, type);
- errno = 0;
- bfile = fopen(fn, "r");
- if (!bfile || (fs = get_filestream(f, bfile)) == NULL ||
- open_wrapper(fs) ) {
- ast_log(LOG_WARNING, "Unable to open %s\n", fn);
- if (fs)
- ast_free(fs);
- if (bfile)
- fclose(bfile);
- free(fn);
- continue;
- }
- /* found it */
- fs->trans = NULL;
- fs->fmt = f;
- fs->flags = flags;
- fs->mode = mode;
- fs->filename = strdup(filename);
- fs->vfs = NULL;
- break;
- }
-
- AST_LIST_UNLOCK(&formats);
- if (!fs)
- ast_log(LOG_WARNING, "No such format '%s'\n", type);
-
- return fs;
-}
-
-struct ast_filestream *ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
-{
- int fd, myflags = 0;
- /* compiler claims this variable can be used before initialization... */
- FILE *bfile = NULL;
- struct ast_format *f;
- struct ast_filestream *fs = NULL;
- char *buf = NULL;
- size_t size = 0;
- int format_found = 0;
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return NULL;
- }
-
- /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
- /* We really can't use O_APPEND as it will break WAV header updates */
- if (flags & O_APPEND) {
- flags &= ~O_APPEND;
- } else {
- myflags = O_TRUNC;
- }
-
- myflags |= O_WRONLY | O_CREAT;
-
- /* XXX need to fix this - we should just do the fopen,
- * not open followed by fdopen()
- */
- AST_LIST_TRAVERSE(&formats, f, list) {
- char *fn, *orig_fn = NULL;
- if (fs)
- break;
-
- if (!exts_compare(f->exts, type))
- continue;
- else
- format_found = 1;
-
- fn = build_filename(filename, type);
- fd = open(fn, flags | myflags, mode);
- if (fd > -1) {
- /* fdopen() the resulting file stream */
- bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
- if (!bfile) {
- ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
- close(fd);
- fd = -1;
- }
- }
-
- if (ast_opt_cache_record_files && (fd > -1)) {
- char *c;
-
- fclose(bfile); /* this also closes fd */
- /*
- We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
- What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
- */
- orig_fn = ast_strdupa(fn);
- for (c = fn; *c; c++)
- if (*c == '/')
- *c = '_';
-
- size = strlen(fn) + strlen(record_cache_dir) + 2;
- buf = alloca(size);
- strcpy(buf, record_cache_dir);
- strcat(buf, "/");
- strcat(buf, fn);
- free(fn);
- fn = buf;
- fd = open(fn, flags | myflags, mode);
- if (fd > -1) {
- /* fdopen() the resulting file stream */
- bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
- if (!bfile) {
- ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
- close(fd);
- fd = -1;
- }
- }
- }
- if (fd > -1) {
- errno = 0;
- fs = get_filestream(f, bfile);
- if (!fs || rewrite_wrapper(fs, comment)) {
- ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
- close(fd);
- if (orig_fn) {
- unlink(fn);
- unlink(orig_fn);
- }
- if (fs)
- ast_free(fs);
- fs = NULL;
- continue;
- }
- fs->trans = NULL;
- fs->fmt = f;
- fs->flags = flags;
- fs->mode = mode;
- if (orig_fn) {
- fs->realfilename = strdup(orig_fn);
- fs->filename = strdup(fn);
- } else {
- fs->realfilename = NULL;
- fs->filename = strdup(filename);
- }
- fs->vfs = NULL;
- /* If truncated, we'll be at the beginning; if not truncated, then append */
- f->seek(fs, 0, SEEK_END);
- } else if (errno != EEXIST) {
- ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
- if (orig_fn)
- unlink(orig_fn);
- }
- /* if buf != NULL then fn is already free and pointing to it */
- if (!buf)
- free(fn);
- }
-
- AST_LIST_UNLOCK(&formats);
-
- if (!format_found)
- ast_log(LOG_WARNING, "No such format '%s'\n", type);
-
- return fs;
-}
-
-/*!
- * \brief the core of all waitstream() functions
- */
-static int waitstream_core(struct ast_channel *c, const char *breakon,
- const char *forward, const char *rewind, int skip_ms,
- int audiofd, int cmdfd, const char *context)
-{
- const char *orig_chan_name = NULL;
- int err = 0;
-
- if (!breakon)
- breakon = "";
- if (!forward)
- forward = "";
- if (!rewind)
- rewind = "";
-
- /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
- ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
-
- if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM))
- orig_chan_name = ast_strdupa(c->name);
-
- while (c->stream) {
- int res;
- int ms;
-
- if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) {
- ast_stopstream(c);
- err = 1;
- break;
- }
-
- ms = ast_sched_wait(c->sched);
-
- if (ms < 0 && !c->timingfunc) {
- ast_stopstream(c);
- break;
- }
- if (ms < 0)
- ms = 1000;
- if (cmdfd < 0) {
- res = ast_waitfor(c, ms);
- if (res < 0) {
- ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return res;
- }
- } else {
- int outfd;
- struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
- if (!rchan && (outfd < 0) && (ms)) {
- /* Continue */
- if (errno == EINTR)
- continue;
- ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return -1;
- } else if (outfd > -1) { /* this requires cmdfd set */
- /* The FD we were watching has something waiting */
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return 1;
- }
- /* if rchan is set, it is 'c' */
- res = rchan ? 1 : 0; /* map into 'res' values */
- }
- if (res > 0) {
- struct ast_frame *fr = ast_read(c);
- if (!fr) {
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return -1;
- }
- switch(fr->frametype) {
- case AST_FRAME_DTMF_END:
- if (context) {
- const char exten[2] = { fr->subclass, '\0' };
- if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
- res = fr->subclass;
- ast_frfree(fr);
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return res;
- }
- } else {
- res = fr->subclass;
- if (strchr(forward,res)) {
- ast_stream_fastforward(c->stream, skip_ms);
- } else if (strchr(rewind,res)) {
- ast_stream_rewind(c->stream, skip_ms);
- } else if (strchr(breakon, res)) {
- ast_frfree(fr);
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return res;
- }
- }
- break;
- case AST_FRAME_CONTROL:
- switch(fr->subclass) {
- case AST_CONTROL_HANGUP:
- case AST_CONTROL_BUSY:
- case AST_CONTROL_CONGESTION:
- ast_frfree(fr);
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
- return -1;
- case AST_CONTROL_RINGING:
- case AST_CONTROL_ANSWER:
- case AST_CONTROL_VIDUPDATE:
- case AST_CONTROL_SRCUPDATE:
- case AST_CONTROL_HOLD:
- case AST_CONTROL_UNHOLD:
- /* Unimportant */
- break;
- default:
- ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
- }
- break;
- case AST_FRAME_VOICE:
- /* Write audio if appropriate */
- if (audiofd > -1)
- write(audiofd, fr->data, fr->datalen);
- default:
- /* Ignore all others */
- break;
- }
- ast_frfree(fr);
- }
- ast_sched_runq(c->sched);
- }
-
- ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
-
- return (err || c->_softhangup) ? -1 : 0;
-}
-
-int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
-{
- return waitstream_core(c, breakon, forward, rewind, ms,
- -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
-}
-
-int ast_waitstream(struct ast_channel *c, const char *breakon)
-{
- return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
-}
-
-int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
-{
- return waitstream_core(c, breakon, NULL, NULL, 0,
- audiofd, cmdfd, NULL /* no context */);
-}
-
-int ast_waitstream_exten(struct ast_channel *c, const char *context)
-{
- /* Waitstream, with return in the case of a valid 1 digit extension */
- /* in the current or specified context being pressed */
-
- if (!context)
- context = c->context;
- return waitstream_core(c, NULL, NULL, NULL, 0,
- -1, -1, context);
-}
-
-/*
- * if the file name is non-empty, try to play it.
- * Return 0 if success, -1 if error, digit if interrupted by a digit.
- * If digits == "" then we can simply check for non-zero.
- */
-int ast_stream_and_wait(struct ast_channel *chan, const char *file,
- const char *language, const char *digits)
-{
- int res = 0;
- if (!ast_strlen_zero(file)) {
- res = ast_streamfile(chan, file, language);
- if (!res)
- res = ast_waitstream(chan, digits);
- }
- return res;
-}
-
-static int show_file_formats(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-10s %-10s %-20s\n"
-#define FORMAT2 "%-10s %-10s %-20s\n"
- struct ast_format *f;
- int count_fmt = 0;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return -1;
- }
-
- AST_LIST_TRAVERSE(&formats, f, list) {
- ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
- count_fmt++;
- }
- AST_LIST_UNLOCK(&formats);
- ast_cli(fd, "%d file formats registered.\n", count_fmt);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int show_file_formats_deprecated(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-10s %-10s %-20s\n"
-#define FORMAT2 "%-10s %-10s %-20s\n"
- struct ast_format *f;
- int count_fmt = 0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
-
- if (AST_LIST_LOCK(&formats)) {
- ast_log(LOG_WARNING, "Unable to lock format list\n");
- return -1;
- }
-
- AST_LIST_TRAVERSE(&formats, f, list) {
- ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
- count_fmt++;
- }
- AST_LIST_UNLOCK(&formats);
- ast_cli(fd, "%d file formats registered.\n", count_fmt);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-char show_file_formats_usage[] =
-"Usage: core show file formats\n"
-" Displays currently registered file formats (if any)\n";
-
-struct ast_cli_entry cli_show_file_formats_deprecated = {
- { "show", "file", "formats" },
- show_file_formats_deprecated, NULL,
- NULL };
-
-struct ast_cli_entry cli_file[] = {
- { { "core", "show", "file", "formats" },
- show_file_formats, "Displays file formats",
- show_file_formats_usage, NULL, &cli_show_file_formats_deprecated },
-};
-
-int ast_file_init(void)
-{
- ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
- return 0;
-}
diff --git a/1.4/main/fixedjitterbuf.c b/1.4/main/fixedjitterbuf.c
deleted file mode 100644
index 1d7a5cc30..000000000
--- a/1.4/main/fixedjitterbuf.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2005, Attractel OOD
- *
- * Contributors:
- * Slav Klenov <slav@securax.org>
- *
- * 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.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-/*! \file
- *
- * \brief Jitterbuffering algorithm.
- *
- * \author Slav Klenov <slav@securax.org>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/utils.h"
-#include "fixedjitterbuf.h"
-
-#undef FIXED_JB_DEBUG
-
-#ifdef FIXED_JB_DEBUG
-#define ASSERT(a)
-#else
-#define ASSERT(a) assert(a)
-#endif
-
-/*! \brief private fixed_jb structure */
-struct fixed_jb
-{
- struct fixed_jb_frame *frames;
- struct fixed_jb_frame *tail;
- struct fixed_jb_conf conf;
- long rxcore;
- long delay;
- long next_delivery;
- int force_resynch;
-};
-
-
-static struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb);
-static void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame);
-static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame);
-static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now);
-
-static inline struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb)
-{
- return ast_calloc(1, sizeof(struct fixed_jb_frame));
-}
-
-static inline void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame)
-{
- free(frame);
-}
-
-static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame)
-{
- struct fixed_jb_frame *fr;
-
- /* unlink the frame */
- fr = jb->frames;
- jb->frames = fr->next;
- if (jb->frames) {
- jb->frames->prev = NULL;
- } else {
- /* the jb is empty - update tail */
- jb->tail = NULL;
- }
-
- /* update next */
- jb->next_delivery = fr->delivery + fr->ms;
-
- /* copy the destination */
- memcpy(frame, fr, sizeof(struct fixed_jb_frame));
-
- /* and release the frame */
- release_jb_frame(jb, fr);
-}
-
-
-struct fixed_jb *fixed_jb_new(struct fixed_jb_conf *conf)
-{
- struct fixed_jb *jb;
-
- if (!(jb = ast_calloc(1, sizeof(*jb))))
- return NULL;
-
- /* First copy our config */
- memcpy(&jb->conf, conf, sizeof(struct fixed_jb_conf));
-
- /* we dont need the passed config anymore - continue working with the saved one */
- conf = &jb->conf;
-
- /* validate the configuration */
- if (conf->jbsize < 1)
- conf->jbsize = FIXED_JB_SIZE_DEFAULT;
-
- if (conf->resync_threshold < 1)
- conf->resync_threshold = FIXED_JB_RESYNCH_THRESHOLD_DEFAULT;
-
- /* Set the constant delay to the jitterbuf */
- jb->delay = conf->jbsize;
-
- return jb;
-}
-
-
-void fixed_jb_destroy(struct fixed_jb *jb)
-{
- /* jitterbuf MUST be empty before it can be destroyed */
- ASSERT(jb->frames == NULL);
-
- free(jb);
-}
-
-
-static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now)
-{
- long diff, offset;
- struct fixed_jb_frame *frame;
-
- /* If jb is empty, just reinitialize the jb */
- if (!jb->frames) {
- /* debug check: tail should also be NULL */
- ASSERT(jb->tail == NULL);
-
- return fixed_jb_put_first(jb, data, ms, ts, now);
- }
-
- /* Adjust all jb state just as the new frame is with delivery = the delivery of the last
- frame (e.g. this one with max delivery) + the length of the last frame. */
-
- /* Get the diff in timestamps */
- diff = ts - jb->tail->ts;
-
- /* Ideally this should be just the length of the last frame. The deviation is the desired
- offset */
- offset = diff - jb->tail->ms;
-
- /* Do we really need to resynch, or this is just a frame for dropping? */
- if (!jb->force_resynch && (offset < jb->conf.resync_threshold && offset > -jb->conf.resync_threshold))
- return FIXED_JB_DROP;
-
- /* Reset the force resynch flag */
- jb->force_resynch = 0;
-
- /* apply the offset to the jb state */
- jb->rxcore -= offset;
- frame = jb->frames;
- while (frame) {
- frame->ts += offset;
- frame = frame->next;
- }
-
- /* now jb_put() should add the frame at a last position */
- return fixed_jb_put(jb, data, ms, ts, now);
-}
-
-
-void fixed_jb_set_force_resynch(struct fixed_jb *jb)
-{
- jb->force_resynch = 1;
-}
-
-
-int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)
-{
- /* this is our first frame - set the base of the receivers time */
- jb->rxcore = now - ts;
-
- /* init next for a first time - it should be the time the first frame should be played */
- jb->next_delivery = now + jb->delay;
-
- /* put the frame */
- return fixed_jb_put(jb, data, ms, ts, now);
-}
-
-
-int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)
-{
- struct fixed_jb_frame *frame, *next, *newframe;
- long delivery;
-
- /* debug check the validity of the input params */
- ASSERT(data != NULL);
- /* do not allow frames shorter than 2 ms */
- ASSERT(ms >= 2);
- ASSERT(ts >= 0);
- ASSERT(now >= 0);
-
- delivery = jb->rxcore + jb->delay + ts;
-
- /* check if the new frame is not too late */
- if (delivery < jb->next_delivery) {
- /* should drop the frame, but let first resynch_jb() check if this is not a jump in ts, or
- the force resynch flag was not set. */
- return resynch_jb(jb, data, ms, ts, now);
- }
-
- /* what if the delivery time is bigger than next + delay? Seems like a frame for the future.
- However, allow more resync_threshold ms in advance */
- if (delivery > jb->next_delivery + jb->delay + jb->conf.resync_threshold) {
- /* should drop the frame, but let first resynch_jb() check if this is not a jump in ts, or
- the force resynch flag was not set. */
- return resynch_jb(jb, data, ms, ts, now);
- }
-
- /* find the right place in the frames list, sorted by delivery time */
- frame = jb->tail;
- while (frame && frame->delivery > delivery) {
- frame = frame->prev;
- }
-
- /* Check if the new delivery time is not covered already by the chosen frame */
- if (frame && (frame->delivery == delivery ||
- delivery < frame->delivery + frame->ms ||
- (frame->next && delivery + ms > frame->next->delivery)))
- {
- /* TODO: Should we check for resynch here? Be careful to do not allow threshold smaller than
- the size of the jb */
-
- /* should drop the frame, but let first resynch_jb() check if this is not a jump in ts, or
- the force resynch flag was not set. */
- return resynch_jb(jb, data, ms, ts, now);
- }
-
- /* Reset the force resynch flag */
- jb->force_resynch = 0;
-
- /* Get a new frame */
- newframe = alloc_jb_frame(jb);
- newframe->data = data;
- newframe->ts = ts;
- newframe->ms = ms;
- newframe->delivery = delivery;
-
- /* and insert it right on place */
- if (frame) {
- next = frame->next;
- frame->next = newframe;
- if (next) {
- newframe->next = next;
- next->prev = newframe;
- } else {
- /* insert after the last frame - should update tail */
- jb->tail = newframe;
- newframe->next = NULL;
- }
- newframe->prev = frame;
-
- return FIXED_JB_OK;
- } else if (!jb->frames) {
- /* the frame list is empty or thats just the first frame ever */
- /* tail should also be NULL is that case */
- ASSERT(jb->tail == NULL);
- jb->frames = jb->tail = newframe;
- newframe->next = NULL;
- newframe->prev = NULL;
-
- return FIXED_JB_OK;
- } else {
- /* insert on a first position - should update frames head */
- newframe->next = jb->frames;
- newframe->prev = NULL;
- jb->frames->prev = newframe;
- jb->frames = newframe;
-
- return FIXED_JB_OK;
- }
-}
-
-
-int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
-{
- ASSERT(now >= 0);
- ASSERT(interpl >= 2);
-
- if (now < jb->next_delivery) {
- /* too early for the next frame */
- return FIXED_JB_NOFRAME;
- }
-
- /* Is the jb empty? */
- if (!jb->frames) {
- /* should interpolate a frame */
- /* update next */
- jb->next_delivery += interpl;
-
- return FIXED_JB_INTERP;
- }
-
- /* Isn't it too late for the first frame available in the jb? */
- if (now > jb->frames->delivery + jb->frames->ms) {
- /* yes - should drop this frame and update next to point the next frame (get_jb_head() does it) */
- get_jb_head(jb, frame);
-
- return FIXED_JB_DROP;
- }
-
- /* isn't it too early to play the first frame available? */
- if (now < jb->frames->delivery) {
- /* yes - should interpolate one frame */
- /* update next */
- jb->next_delivery += interpl;
-
- return FIXED_JB_INTERP;
- }
-
- /* we have a frame for playing now (get_jb_head() updates next) */
- get_jb_head(jb, frame);
-
- return FIXED_JB_OK;
-}
-
-
-long fixed_jb_next(struct fixed_jb *jb)
-{
- return jb->next_delivery;
-}
-
-
-int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
-{
- if (!jb->frames)
- return FIXED_JB_NOFRAME;
-
- get_jb_head(jb, frameout);
-
- return FIXED_JB_OK;
-}
diff --git a/1.4/main/fixedjitterbuf.h b/1.4/main/fixedjitterbuf.h
deleted file mode 100644
index 541e99d2d..000000000
--- a/1.4/main/fixedjitterbuf.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2005, Attractel OOD
- *
- * Contributors:
- * Slav Klenov <slav@securax.org>
- *
- * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Jitterbuffering algorithm.
- *
- */
-
-#ifndef _FIXEDJITTERBUF_H_
-#define _FIXEDJITTERBUF_H_
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-
-/* return codes */
-enum {
- FIXED_JB_OK,
- FIXED_JB_DROP,
- FIXED_JB_INTERP,
- FIXED_JB_NOFRAME
-};
-
-
-/* defaults */
-#define FIXED_JB_SIZE_DEFAULT 200
-#define FIXED_JB_RESYNCH_THRESHOLD_DEFAULT 1000
-
-
-/* jb configuration properties */
-struct fixed_jb_conf
-{
- long jbsize;
- long resync_threshold;
-};
-
-
-struct fixed_jb_frame
-{
- void *data;
- long ts;
- long ms;
- long delivery;
- struct fixed_jb_frame *next;
- struct fixed_jb_frame *prev;
-};
-
-
-struct fixed_jb;
-
-
-/* jb interface */
-
-struct fixed_jb * fixed_jb_new(struct fixed_jb_conf *conf);
-
-void fixed_jb_destroy(struct fixed_jb *jb);
-
-int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now);
-
-int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now);
-
-int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl);
-
-long fixed_jb_next(struct fixed_jb *jb);
-
-int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout);
-
-void fixed_jb_set_force_resynch(struct fixed_jb *jb);
-
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _FIXEDJITTERBUF_H_ */
diff --git a/1.4/main/frame.c b/1.4/main/frame.c
deleted file mode 100644
index 45dafeb3d..000000000
--- a/1.4/main/frame.c
+++ /dev/null
@@ -1,1617 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Frame and codec manipulation routines
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/frame.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cli.h"
-#include "asterisk/term.h"
-#include "asterisk/utils.h"
-#include "asterisk/threadstorage.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/translate.h"
-#include "asterisk/dsp.h"
-
-#ifdef TRACE_FRAMES
-static int headers;
-static AST_LIST_HEAD_STATIC(headerlist, ast_frame);
-#endif
-
-#if !defined(LOW_MEMORY)
-static void frame_cache_cleanup(void *data);
-
-/*! \brief A per-thread cache of frame headers */
-AST_THREADSTORAGE_CUSTOM(frame_cache, frame_cache_init, frame_cache_cleanup);
-
-/*!
- * \brief Maximum ast_frame cache size
- *
- * In most cases where the frame header cache will be useful, the size
- * of the cache will stay very small. However, it is not always the case that
- * the same thread that allocates the frame will be the one freeing them, so
- * sometimes a thread will never have any frames in its cache, or the cache
- * will never be pulled from. For the latter case, we limit the maximum size.
- */
-#define FRAME_CACHE_MAX_SIZE 10
-
-/*! \brief This is just so ast_frames, a list head struct for holding a list of
- * ast_frame structures, is defined. */
-AST_LIST_HEAD_NOLOCK(ast_frames, ast_frame);
-
-struct ast_frame_cache {
- struct ast_frames list;
- size_t size;
-};
-#endif
-
-#define SMOOTHER_SIZE 8000
-
-enum frame_type {
- TYPE_HIGH, /* 0x0 */
- TYPE_LOW, /* 0x1 */
- TYPE_SILENCE, /* 0x2 */
- TYPE_DONTSEND /* 0x3 */
-};
-
-#define TYPE_MASK 0x3
-
-struct ast_smoother {
- int size;
- int format;
- int readdata;
- int optimizablestream;
- int flags;
- float samplesperbyte;
- struct ast_frame f;
- struct timeval delivery;
- char data[SMOOTHER_SIZE];
- char framedata[SMOOTHER_SIZE + AST_FRIENDLY_OFFSET];
- struct ast_frame *opt;
- int len;
-};
-
-/*! \brief Definition of supported media formats (codecs) */
-static struct ast_format_list AST_FORMAT_LIST[] = { /*!< Bit number: comment - Bit numbers are hard coded in show_codec() */
- { 1, AST_FORMAT_G723_1 , "g723" , "G.723.1", 24, 30, 300, 30, 30 }, /*!< 1 */
- { 1, AST_FORMAT_GSM, "gsm" , "GSM", 33, 20, 300, 20, 20 }, /*!< 2: codec_gsm.c */
- { 1, AST_FORMAT_ULAW, "ulaw", "G.711 u-law", 80, 10, 150, 10, 20 }, /*!< 3: codec_ulaw.c */
- { 1, AST_FORMAT_ALAW, "alaw", "G.711 A-law", 80, 10, 150, 10, 20 }, /*!< 4: codec_alaw.c */
- { 1, AST_FORMAT_G726, "g726", "G.726 RFC3551", 40, 10, 300, 10, 20 }, /*!< 5: codec_g726.c */
- { 1, AST_FORMAT_ADPCM, "adpcm" , "ADPCM", 40, 10, 300, 10, 20 }, /*!< 6: codec_adpcm.c */
- { 1, AST_FORMAT_SLINEAR, "slin", "16 bit Signed Linear PCM", 160, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE }, /*!< 7 */
- { 1, AST_FORMAT_LPC10, "lpc10", "LPC10", 7, 20, 20, 20, 20 }, /*!< 8: codec_lpc10.c */
- { 1, AST_FORMAT_G729A, "g729", "G.729A", 10, 10, 230, 10, 20, AST_SMOOTHER_FLAG_G729 }, /*!< 9: Binary commercial distribution */
- { 1, AST_FORMAT_SPEEX, "speex", "SpeeX", 10, 10, 60, 10, 20 }, /*!< 10: codec_speex.c */
- { 1, AST_FORMAT_ILBC, "ilbc", "iLBC", 50, 30, 30, 30, 30 }, /*!< 11: codec_ilbc.c */ /* inc=30ms - workaround */
- { 1, AST_FORMAT_G726_AAL2, "g726aal2", "G.726 AAL2", 40, 10, 300, 10, 20 }, /*!< 12: codec_g726.c */
- { 1, AST_FORMAT_G722, "g722", "G722"}, /*!< 13 */
- { 0, 0, "nothing", "undefined" },
- { 0, 0, "nothing", "undefined" },
- { 0, 0, "nothing", "undefined" },
- { 0, 0, "nothing", "undefined" },
- { 0, AST_FORMAT_MAX_AUDIO, "maxaudio", "Maximum audio format" },
- { 1, AST_FORMAT_JPEG, "jpeg", "JPEG image"}, /*!< 17: See format_jpeg.c */
- { 1, AST_FORMAT_PNG, "png", "PNG image"}, /*!< 18: Image format */
- { 1, AST_FORMAT_H261, "h261", "H.261 Video" }, /*!< 19: Video Passthrough */
- { 1, AST_FORMAT_H263, "h263", "H.263 Video" }, /*!< 20: Passthrough support, see format_h263.c */
- { 1, AST_FORMAT_H263_PLUS, "h263p", "H.263+ Video" }, /*!< 21: See format_h263.c */
- { 1, AST_FORMAT_H264, "h264", "H.264 Video" }, /*!< 22: Passthrough support, see format_h263.c */
- { 0, 0, "nothing", "undefined" },
- { 0, 0, "nothing", "undefined" },
- { 0, 0, "nothing", "undefined" },
- { 0, AST_FORMAT_MAX_VIDEO, "maxvideo", "Maximum video format" },
-};
-
-struct ast_frame ast_null_frame = { AST_FRAME_NULL, };
-
-void ast_smoother_reset(struct ast_smoother *s, int size)
-{
- memset(s, 0, sizeof(*s));
- s->size = size;
-}
-
-struct ast_smoother *ast_smoother_new(int size)
-{
- struct ast_smoother *s;
- if (size < 1)
- return NULL;
- if ((s = ast_malloc(sizeof(*s))))
- ast_smoother_reset(s, size);
- return s;
-}
-
-int ast_smoother_get_flags(struct ast_smoother *s)
-{
- return s->flags;
-}
-
-void ast_smoother_set_flags(struct ast_smoother *s, int flags)
-{
- s->flags = flags;
-}
-
-int ast_smoother_test_flag(struct ast_smoother *s, int flag)
-{
- return (s->flags & flag);
-}
-
-int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
-{
- if (f->frametype != AST_FRAME_VOICE) {
- ast_log(LOG_WARNING, "Huh? Can't smooth a non-voice frame!\n");
- return -1;
- }
- if (!s->format) {
- s->format = f->subclass;
- s->samplesperbyte = (float)f->samples / (float)f->datalen;
- } else if (s->format != f->subclass) {
- ast_log(LOG_WARNING, "Smoother was working on %d format frames, now trying to feed %d?\n", s->format, f->subclass);
- return -1;
- }
- if (s->len + f->datalen > SMOOTHER_SIZE) {
- ast_log(LOG_WARNING, "Out of smoother space\n");
- return -1;
- }
- if (((f->datalen == s->size) || ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729)))
- && !s->opt && (f->offset >= AST_MIN_OFFSET)) {
- if (!s->len) {
- /* Optimize by sending the frame we just got
- on the next read, thus eliminating the douple
- copy */
- if (swap)
- ast_swapcopy_samples(f->data, f->data, f->samples);
- s->opt = f;
- return 0;
- }
- }
- if (s->flags & AST_SMOOTHER_FLAG_G729) {
- if (s->len % 10) {
- ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
- return 0;
- }
- }
- if (swap)
- ast_swapcopy_samples(s->data+s->len, f->data, f->samples);
- else
- memcpy(s->data + s->len, f->data, f->datalen);
- /* If either side is empty, reset the delivery time */
- if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery)) /* XXX really ? */
- s->delivery = f->delivery;
- s->len += f->datalen;
- return 0;
-}
-
-struct ast_frame *ast_smoother_read(struct ast_smoother *s)
-{
- struct ast_frame *opt;
- int len;
-
- /* IF we have an optimization frame, send it */
- if (s->opt) {
- if (s->opt->offset < AST_FRIENDLY_OFFSET)
- ast_log(LOG_WARNING, "Returning a frame of inappropriate offset (%d).\n",
- s->opt->offset);
- opt = s->opt;
- s->opt = NULL;
- return opt;
- }
-
- /* Make sure we have enough data */
- if (s->len < s->size) {
- /* Or, if this is a G.729 frame with VAD on it, send it immediately anyway */
- if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->size % 10)))
- return NULL;
- }
- len = s->size;
- if (len > s->len)
- len = s->len;
- /* Make frame */
- s->f.frametype = AST_FRAME_VOICE;
- s->f.subclass = s->format;
- s->f.data = s->framedata + AST_FRIENDLY_OFFSET;
- s->f.offset = AST_FRIENDLY_OFFSET;
- s->f.datalen = len;
- /* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */
- s->f.samples = len * s->samplesperbyte; /* XXX rounding */
- s->f.delivery = s->delivery;
- /* Fill Data */
- memcpy(s->f.data, s->data, len);
- s->len -= len;
- /* Move remaining data to the front if applicable */
- if (s->len) {
- /* In principle this should all be fine because if we are sending
- G.729 VAD, the next timestamp will take over anyawy */
- memmove(s->data, s->data + len, s->len);
- if (!ast_tvzero(s->delivery)) {
- /* If we have delivery time, increment it, otherwise, leave it at 0 */
- s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, 8000));
- }
- }
- /* Return frame */
- return &s->f;
-}
-
-void ast_smoother_free(struct ast_smoother *s)
-{
- free(s);
-}
-
-static struct ast_frame *ast_frame_header_new(void)
-{
- struct ast_frame *f;
-
-#if !defined(LOW_MEMORY)
- struct ast_frame_cache *frames;
-
- if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
- if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) {
- size_t mallocd_len = f->mallocd_hdr_len;
- memset(f, 0, sizeof(*f));
- f->mallocd_hdr_len = mallocd_len;
- f->mallocd = AST_MALLOCD_HDR;
- frames->size--;
- return f;
- }
- }
- if (!(f = ast_calloc_cache(1, sizeof(*f))))
- return NULL;
-#else
- if (!(f = ast_calloc(1, sizeof(*f))))
- return NULL;
-#endif
-
- f->mallocd_hdr_len = sizeof(*f);
-#ifdef TRACE_FRAMES
- AST_LIST_LOCK(&headerlist);
- headers++;
- AST_LIST_INSERT_HEAD(&headerlist, f, frame_list);
- AST_LIST_UNLOCK(&headerlist);
-#endif
-
- return f;
-}
-
-#if !defined(LOW_MEMORY)
-static void frame_cache_cleanup(void *data)
-{
- struct ast_frame_cache *frames = data;
- struct ast_frame *f;
-
- while ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list)))
- free(f);
-
- free(frames);
-}
-#endif
-
-void ast_frame_free(struct ast_frame *fr, int cache)
-{
- if (ast_test_flag(fr, AST_FRFLAG_FROM_TRANSLATOR))
- ast_translate_frame_freed(fr);
- else if (ast_test_flag(fr, AST_FRFLAG_FROM_DSP))
- ast_dsp_frame_freed(fr);
-
- if (!fr->mallocd)
- return;
-
-#if !defined(LOW_MEMORY)
- if (cache && fr->mallocd == AST_MALLOCD_HDR) {
- /* Cool, only the header is malloc'd, let's just cache those for now
- * to keep things simple... */
- struct ast_frame_cache *frames;
-
- if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))
- && frames->size < FRAME_CACHE_MAX_SIZE) {
- AST_LIST_INSERT_HEAD(&frames->list, fr, frame_list);
- frames->size++;
- return;
- }
- }
-#endif
-
- if (fr->mallocd & AST_MALLOCD_DATA) {
- if (fr->data)
- free(fr->data - fr->offset);
- }
- if (fr->mallocd & AST_MALLOCD_SRC) {
- if (fr->src)
- free((char *)fr->src);
- }
- if (fr->mallocd & AST_MALLOCD_HDR) {
-#ifdef TRACE_FRAMES
- AST_LIST_LOCK(&headerlist);
- headers--;
- AST_LIST_REMOVE(&headerlist, fr, frame_list);
- AST_LIST_UNLOCK(&headerlist);
-#endif
- free(fr);
- }
-}
-
-/*!
- * \brief 'isolates' a frame by duplicating non-malloc'ed components
- * (header, src, data).
- * On return all components are malloc'ed
- */
-struct ast_frame *ast_frisolate(struct ast_frame *fr)
-{
- struct ast_frame *out;
- void *newdata;
-
- ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR);
- ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
-
- if (!(fr->mallocd & AST_MALLOCD_HDR)) {
- /* Allocate a new header if needed */
- if (!(out = ast_frame_header_new()))
- return NULL;
- out->frametype = fr->frametype;
- out->subclass = fr->subclass;
- out->datalen = fr->datalen;
- out->samples = fr->samples;
- out->offset = fr->offset;
- out->data = fr->data;
- /* Copy the timing data */
- ast_copy_flags(out, fr, AST_FRFLAG_HAS_TIMING_INFO);
- if (ast_test_flag(fr, AST_FRFLAG_HAS_TIMING_INFO)) {
- out->ts = fr->ts;
- out->len = fr->len;
- out->seqno = fr->seqno;
- }
- } else
- out = fr;
-
- if (!(fr->mallocd & AST_MALLOCD_SRC)) {
- if (fr->src) {
- if (!(out->src = ast_strdup(fr->src))) {
- if (out != fr)
- free(out);
- return NULL;
- }
- }
- } else
- out->src = fr->src;
-
- if (!(fr->mallocd & AST_MALLOCD_DATA)) {
- if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) {
- if (out->src != fr->src)
- free((void *) out->src);
- if (out != fr)
- free(out);
- return NULL;
- }
- newdata += AST_FRIENDLY_OFFSET;
- out->offset = AST_FRIENDLY_OFFSET;
- out->datalen = fr->datalen;
- memcpy(newdata, fr->data, fr->datalen);
- out->data = newdata;
- }
-
- out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
-
- return out;
-}
-
-struct ast_frame *ast_frdup(const struct ast_frame *f)
-{
- struct ast_frame *out = NULL;
- int len, srclen = 0;
- void *buf = NULL;
-
-#if !defined(LOW_MEMORY)
- struct ast_frame_cache *frames;
-#endif
-
- /* Start with standard stuff */
- len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
- /* If we have a source, add space for it */
- /*
- * XXX Watch out here - if we receive a src which is not terminated
- * properly, we can be easily attacked. Should limit the size we deal with.
- */
- if (f->src)
- srclen = strlen(f->src);
- if (srclen > 0)
- len += srclen + 1;
-
-#if !defined(LOW_MEMORY)
- if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
- AST_LIST_TRAVERSE_SAFE_BEGIN(&frames->list, out, frame_list) {
- if (out->mallocd_hdr_len >= len) {
- size_t mallocd_len = out->mallocd_hdr_len;
- AST_LIST_REMOVE_CURRENT(&frames->list, frame_list);
- memset(out, 0, sizeof(*out));
- out->mallocd_hdr_len = mallocd_len;
- buf = out;
- frames->size--;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- }
-#endif
-
- if (!buf) {
- if (!(buf = ast_calloc_cache(1, len)))
- return NULL;
- out = buf;
- out->mallocd_hdr_len = len;
- }
-
- out->frametype = f->frametype;
- out->subclass = f->subclass;
- out->datalen = f->datalen;
- out->samples = f->samples;
- out->delivery = f->delivery;
- /* Set us as having malloc'd header only, so it will eventually
- get freed. */
- out->mallocd = AST_MALLOCD_HDR;
- out->offset = AST_FRIENDLY_OFFSET;
- if (out->datalen) {
- out->data = buf + sizeof(*out) + AST_FRIENDLY_OFFSET;
- memcpy(out->data, f->data, out->datalen);
- }
- if (srclen > 0) {
- out->src = buf + sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
- /* Must have space since we allocated for it */
- strcpy((char *)out->src, f->src);
- }
- ast_copy_flags(out, f, AST_FRFLAG_HAS_TIMING_INFO);
- out->ts = f->ts;
- out->len = f->len;
- out->seqno = f->seqno;
- return out;
-}
-
-void ast_swapcopy_samples(void *dst, const void *src, int samples)
-{
- int i;
- unsigned short *dst_s = dst;
- const unsigned short *src_s = src;
-
- for (i = 0; i < samples; i++)
- dst_s[i] = (src_s[i]<<8) | (src_s[i]>>8);
-}
-
-
-struct ast_format_list *ast_get_format_list_index(int index)
-{
- return &AST_FORMAT_LIST[index];
-}
-
-struct ast_format_list *ast_get_format_list(size_t *size)
-{
- *size = (sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]));
- return AST_FORMAT_LIST;
-}
-
-char* ast_getformatname(int format)
-{
- int x;
- char *ret = "unknown";
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == format) {
- ret = AST_FORMAT_LIST[x].name;
- break;
- }
- }
- return ret;
-}
-
-char *ast_getformatname_multiple(char *buf, size_t size, int format)
-{
- int x;
- unsigned len;
- char *start, *end = buf;
-
- if (!size)
- return buf;
- snprintf(end, size, "0x%x (", format);
- len = strlen(end);
- end += len;
- size -= len;
- start = end;
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if (AST_FORMAT_LIST[x].visible && (AST_FORMAT_LIST[x].bits & format)) {
- snprintf(end, size,"%s|",AST_FORMAT_LIST[x].name);
- len = strlen(end);
- end += len;
- size -= len;
- }
- }
- if (start == end)
- snprintf(start, size, "nothing)");
- else if (size > 1)
- *(end -1) = ')';
- return buf;
-}
-
-static struct ast_codec_alias_table {
- char *alias;
- char *realname;
-} ast_codec_alias_table[] = {
- { "slinear", "slin"},
- { "g723.1", "g723"},
-};
-
-static const char *ast_expand_codec_alias(const char *in)
-{
- int x;
-
- for (x = 0; x < sizeof(ast_codec_alias_table) / sizeof(ast_codec_alias_table[0]); x++) {
- if(!strcmp(in,ast_codec_alias_table[x].alias))
- return ast_codec_alias_table[x].realname;
- }
- return in;
-}
-
-int ast_getformatbyname(const char *name)
-{
- int x, all, format = 0;
-
- all = strcasecmp(name, "all") ? 0 : 1;
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(AST_FORMAT_LIST[x].visible && (all ||
- !strcasecmp(AST_FORMAT_LIST[x].name,name) ||
- !strcasecmp(AST_FORMAT_LIST[x].name,ast_expand_codec_alias(name)))) {
- format |= AST_FORMAT_LIST[x].bits;
- if(!all)
- break;
- }
- }
-
- return format;
-}
-
-char *ast_codec2str(int codec)
-{
- int x;
- char *ret = "unknown";
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == codec) {
- ret = AST_FORMAT_LIST[x].desc;
- break;
- }
- }
- return ret;
-}
-
-static int show_codecs_deprecated(int fd, int argc, char *argv[])
-{
- int i, found=0;
- char hex[25];
-
- if ((argc < 2) || (argc > 3))
- return RESULT_SHOWUSAGE;
-
- if (!ast_opt_dont_warn)
- ast_cli(fd, "Disclaimer: this command is for informational purposes only.\n"
- "\tIt does not indicate anything about your configuration.\n");
-
- ast_cli(fd, "%11s %9s %10s TYPE %8s %s\n","INT","BINARY","HEX","NAME","DESC");
- ast_cli(fd, "--------------------------------------------------------------------------------\n");
- if ((argc == 2) || (!strcasecmp(argv[1],"audio"))) {
- found = 1;
- for (i=0;i<13;i++) {
- snprintf(hex,25,"(0x%x)",1<<i);
- ast_cli(fd, "%11u (1 << %2d) %10s audio %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
- }
- }
-
- if ((argc == 2) || (!strcasecmp(argv[1],"image"))) {
- found = 1;
- for (i=16;i<18;i++) {
- snprintf(hex,25,"(0x%x)",1<<i);
- ast_cli(fd, "%11u (1 << %2d) %10s image %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
- }
- }
-
- if ((argc == 2) || (!strcasecmp(argv[1],"video"))) {
- found = 1;
- for (i=18;i<22;i++) {
- snprintf(hex,25,"(0x%x)",1<<i);
- ast_cli(fd, "%11u (1 << %2d) %10s video %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
- }
- }
-
- if (! found)
- return RESULT_SHOWUSAGE;
- else
- return RESULT_SUCCESS;
-}
-
-static int show_codecs(int fd, int argc, char *argv[])
-{
- int i, found=0;
- char hex[25];
-
- if ((argc < 3) || (argc > 4))
- return RESULT_SHOWUSAGE;
-
- if (!ast_opt_dont_warn)
- ast_cli(fd, "Disclaimer: this command is for informational purposes only.\n"
- "\tIt does not indicate anything about your configuration.\n");
-
- ast_cli(fd, "%11s %9s %10s TYPE %8s %s\n","INT","BINARY","HEX","NAME","DESC");
- ast_cli(fd, "--------------------------------------------------------------------------------\n");
- if ((argc == 3) || (!strcasecmp(argv[3],"audio"))) {
- found = 1;
- for (i=0;i<13;i++) {
- snprintf(hex,25,"(0x%x)",1<<i);
- ast_cli(fd, "%11u (1 << %2d) %10s audio %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
- }
- }
-
- if ((argc == 3) || (!strcasecmp(argv[3],"image"))) {
- found = 1;
- for (i=16;i<18;i++) {
- snprintf(hex,25,"(0x%x)",1<<i);
- ast_cli(fd, "%11u (1 << %2d) %10s image %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
- }
- }
-
- if ((argc == 3) || (!strcasecmp(argv[3],"video"))) {
- found = 1;
- for (i=18;i<22;i++) {
- snprintf(hex,25,"(0x%x)",1<<i);
- ast_cli(fd, "%11u (1 << %2d) %10s video %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
- }
- }
-
- if (! found)
- return RESULT_SHOWUSAGE;
- else
- return RESULT_SUCCESS;
-}
-
-static char frame_show_codecs_usage[] =
-"Usage: core show codecs [audio|video|image]\n"
-" Displays codec mapping\n";
-
-static int show_codec_n_deprecated(int fd, int argc, char *argv[])
-{
- int codec, i, found=0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- if (sscanf(argv[2],"%d",&codec) != 1)
- return RESULT_SHOWUSAGE;
-
- for (i = 0; i < 32; i++)
- if (codec & (1 << i)) {
- found = 1;
- ast_cli(fd, "%11u (1 << %2d) %s\n",1 << i,i,ast_codec2str(1<<i));
- }
-
- if (!found)
- ast_cli(fd, "Codec %d not found\n", codec);
-
- return RESULT_SUCCESS;
-}
-
-static int show_codec_n(int fd, int argc, char *argv[])
-{
- int codec, i, found=0;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- if (sscanf(argv[3],"%d",&codec) != 1)
- return RESULT_SHOWUSAGE;
-
- for (i = 0; i < 32; i++)
- if (codec & (1 << i)) {
- found = 1;
- ast_cli(fd, "%11u (1 << %2d) %s\n",1 << i,i,ast_codec2str(1<<i));
- }
-
- if (!found)
- ast_cli(fd, "Codec %d not found\n", codec);
-
- return RESULT_SUCCESS;
-}
-
-static char frame_show_codec_n_usage[] =
-"Usage: core show codec <number>\n"
-" Displays codec mapping\n";
-
-/*! Dump a frame for debugging purposes */
-void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
-{
- const char noname[] = "unknown";
- char ftype[40] = "Unknown Frametype";
- char cft[80];
- char subclass[40] = "Unknown Subclass";
- char csub[80];
- char moreinfo[40] = "";
- char cn[60];
- char cp[40];
- char cmn[40];
-
- if (!name)
- name = noname;
-
-
- if (!f) {
- ast_verbose("%s [ %s (NULL) ] [%s]\n",
- term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
- term_color(cft, "HANGUP", COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
- term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
- return;
- }
- /* XXX We should probably print one each of voice and video when the format changes XXX */
- if (f->frametype == AST_FRAME_VOICE)
- return;
- if (f->frametype == AST_FRAME_VIDEO)
- return;
- switch(f->frametype) {
- case AST_FRAME_DTMF_BEGIN:
- strcpy(ftype, "DTMF Begin");
- subclass[0] = f->subclass;
- subclass[1] = '\0';
- break;
- case AST_FRAME_DTMF_END:
- strcpy(ftype, "DTMF End");
- subclass[0] = f->subclass;
- subclass[1] = '\0';
- break;
- case AST_FRAME_CONTROL:
- strcpy(ftype, "Control");
- switch(f->subclass) {
- case AST_CONTROL_HANGUP:
- strcpy(subclass, "Hangup");
- break;
- case AST_CONTROL_RING:
- strcpy(subclass, "Ring");
- break;
- case AST_CONTROL_RINGING:
- strcpy(subclass, "Ringing");
- break;
- case AST_CONTROL_ANSWER:
- strcpy(subclass, "Answer");
- break;
- case AST_CONTROL_BUSY:
- strcpy(subclass, "Busy");
- break;
- case AST_CONTROL_TAKEOFFHOOK:
- strcpy(subclass, "Take Off Hook");
- break;
- case AST_CONTROL_OFFHOOK:
- strcpy(subclass, "Line Off Hook");
- break;
- case AST_CONTROL_CONGESTION:
- strcpy(subclass, "Congestion");
- break;
- case AST_CONTROL_FLASH:
- strcpy(subclass, "Flash");
- break;
- case AST_CONTROL_WINK:
- strcpy(subclass, "Wink");
- break;
- case AST_CONTROL_OPTION:
- strcpy(subclass, "Option");
- break;
- case AST_CONTROL_RADIO_KEY:
- strcpy(subclass, "Key Radio");
- break;
- case AST_CONTROL_RADIO_UNKEY:
- strcpy(subclass, "Unkey Radio");
- break;
- case -1:
- strcpy(subclass, "Stop generators");
- break;
- default:
- snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass);
- }
- break;
- case AST_FRAME_NULL:
- strcpy(ftype, "Null Frame");
- strcpy(subclass, "N/A");
- break;
- case AST_FRAME_IAX:
- /* Should never happen */
- strcpy(ftype, "IAX Specific");
- snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass);
- break;
- case AST_FRAME_TEXT:
- strcpy(ftype, "Text");
- strcpy(subclass, "N/A");
- ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
- break;
- case AST_FRAME_IMAGE:
- strcpy(ftype, "Image");
- snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass));
- break;
- case AST_FRAME_HTML:
- strcpy(ftype, "HTML");
- switch(f->subclass) {
- case AST_HTML_URL:
- strcpy(subclass, "URL");
- ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
- break;
- case AST_HTML_DATA:
- strcpy(subclass, "Data");
- break;
- case AST_HTML_BEGIN:
- strcpy(subclass, "Begin");
- break;
- case AST_HTML_END:
- strcpy(subclass, "End");
- break;
- case AST_HTML_LDCOMPLETE:
- strcpy(subclass, "Load Complete");
- break;
- case AST_HTML_NOSUPPORT:
- strcpy(subclass, "No Support");
- break;
- case AST_HTML_LINKURL:
- strcpy(subclass, "Link URL");
- ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
- break;
- case AST_HTML_UNLINK:
- strcpy(subclass, "Unlink");
- break;
- case AST_HTML_LINKREJECT:
- strcpy(subclass, "Link Reject");
- break;
- default:
- snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass);
- break;
- }
- break;
- case AST_FRAME_MODEM:
- strcpy(ftype, "Modem");
- switch (f->subclass) {
- case AST_MODEM_T38:
- strcpy(subclass, "T.38");
- break;
- case AST_MODEM_V150:
- strcpy(subclass, "V.150");
- break;
- default:
- snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass);
- break;
- }
- break;
- default:
- snprintf(ftype, sizeof(ftype), "Unknown Frametype '%d'", f->frametype);
- }
- if (!ast_strlen_zero(moreinfo))
- ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) '%s' ] [%s]\n",
- term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
- term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
- f->frametype,
- term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
- f->subclass,
- term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)),
- term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
- else
- ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) ] [%s]\n",
- term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
- term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
- f->frametype,
- term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
- f->subclass,
- term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
-}
-
-
-#ifdef TRACE_FRAMES
-static int show_frame_stats_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_frame *f;
- int x=1;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&headerlist);
- ast_cli(fd, " Framer Statistics \n");
- ast_cli(fd, "---------------------------\n");
- ast_cli(fd, "Total allocated headers: %d\n", headers);
- ast_cli(fd, "Queue Dump:\n");
- AST_LIST_TRAVERSE(&headerlist, f, frame_list)
- ast_cli(fd, "%d. Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : "<Unknown>");
- AST_LIST_UNLOCK(&headerlist);
- return RESULT_SUCCESS;
-}
-
-static int show_frame_stats(int fd, int argc, char *argv[])
-{
- struct ast_frame *f;
- int x=1;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&headerlist);
- ast_cli(fd, " Framer Statistics \n");
- ast_cli(fd, "---------------------------\n");
- ast_cli(fd, "Total allocated headers: %d\n", headers);
- ast_cli(fd, "Queue Dump:\n");
- AST_LIST_TRAVERSE(&headerlist, f, frame_list)
- ast_cli(fd, "%d. Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : "<Unknown>");
- AST_LIST_UNLOCK(&headerlist);
- return RESULT_SUCCESS;
-}
-
-static char frame_stats_usage[] =
-"Usage: core show frame stats\n"
-" Displays debugging statistics from framer\n";
-#endif
-
-/* Builtin Asterisk CLI-commands for debugging */
-static struct ast_cli_entry cli_show_codecs = {
- { "show", "codecs", NULL },
- show_codecs_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_audio_codecs = {
- { "show", "audio", "codecs", NULL },
- show_codecs_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_video_codecs = {
- { "show", "video", "codecs", NULL },
- show_codecs_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_image_codecs = {
- { "show", "image", "codecs", NULL },
- show_codecs_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_codec = {
- { "show", "codec", NULL },
- show_codec_n_deprecated, NULL,
- NULL };
-
-#ifdef TRACE_FRAMES
-static struct ast_cli_entry cli_show_frame_stats = {
- { "show", "frame", "stats", NULL },
- show_frame_stats, NULL,
- NULL };
-#endif
-
-static struct ast_cli_entry my_clis[] = {
- { { "core", "show", "codecs", NULL },
- show_codecs, "Displays a list of codecs",
- frame_show_codecs_usage, NULL, &cli_show_codecs },
-
- { { "core", "show", "audio", "codecs", NULL },
- show_codecs, "Displays a list of audio codecs",
- frame_show_codecs_usage, NULL, &cli_show_audio_codecs },
-
- { { "core", "show", "video", "codecs", NULL },
- show_codecs, "Displays a list of video codecs",
- frame_show_codecs_usage, NULL, &cli_show_video_codecs },
-
- { { "core", "show", "image", "codecs", NULL },
- show_codecs, "Displays a list of image codecs",
- frame_show_codecs_usage, NULL, &cli_show_image_codecs },
-
- { { "core", "show", "codec", NULL },
- show_codec_n, "Shows a specific codec",
- frame_show_codec_n_usage, NULL, &cli_show_codec },
-
-#ifdef TRACE_FRAMES
- { { "core", "show", "frame", "stats", NULL },
- show_frame_stats, "Shows frame statistics",
- frame_stats_usage, NULL, &cli_show_frame_stats },
-#endif
-};
-
-int init_framer(void)
-{
- ast_cli_register_multiple(my_clis, sizeof(my_clis) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right)
-{
- int x, differential = (int) 'A', mem;
- char *from, *to;
-
- if(right) {
- from = pref->order;
- to = buf;
- mem = size;
- } else {
- to = pref->order;
- from = buf;
- mem = 32;
- }
-
- memset(to, 0, mem);
- for (x = 0; x < 32 ; x++) {
- if(!from[x])
- break;
- to[x] = right ? (from[x] + differential) : (from[x] - differential);
- }
-}
-
-int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size)
-{
- int x, codec;
- size_t total_len, slen;
- char *formatname;
-
- memset(buf,0,size);
- total_len = size;
- buf[0] = '(';
- total_len--;
- for(x = 0; x < 32 ; x++) {
- if(total_len <= 0)
- break;
- if(!(codec = ast_codec_pref_index(pref,x)))
- break;
- if((formatname = ast_getformatname(codec))) {
- slen = strlen(formatname);
- if(slen > total_len)
- break;
- strncat(buf, formatname, total_len - 1); /* safe */
- total_len -= slen;
- }
- if(total_len && x < 31 && ast_codec_pref_index(pref , x + 1)) {
- strncat(buf, "|", total_len - 1); /* safe */
- total_len--;
- }
- }
- if(total_len) {
- strncat(buf, ")", total_len - 1); /* safe */
- total_len--;
- }
-
- return size - total_len;
-}
-
-int ast_codec_pref_index(struct ast_codec_pref *pref, int index)
-{
- int slot = 0;
-
-
- if((index >= 0) && (index < sizeof(pref->order))) {
- slot = pref->order[index];
- }
-
- return slot ? AST_FORMAT_LIST[slot-1].bits : 0;
-}
-
-/*! \brief Remove codec from pref list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, int format)
-{
- struct ast_codec_pref oldorder;
- int x, y = 0;
- int slot;
- int size;
-
- if(!pref->order[0])
- return;
-
- memcpy(&oldorder, pref, sizeof(oldorder));
- memset(pref, 0, sizeof(*pref));
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- slot = oldorder.order[x];
- size = oldorder.framing[x];
- if(! slot)
- break;
- if(AST_FORMAT_LIST[slot-1].bits != format) {
- pref->order[y] = slot;
- pref->framing[y++] = size;
- }
- }
-
-}
-
-/*! \brief Append codec to list */
-int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
-{
- int x, newindex = 0;
-
- ast_codec_pref_remove(pref, format);
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(AST_FORMAT_LIST[x].bits == format) {
- newindex = x + 1;
- break;
- }
- }
-
- if(newindex) {
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(!pref->order[x]) {
- pref->order[x] = newindex;
- break;
- }
- }
- }
-
- return x;
-}
-
-/*! \brief Prepend codec to list */
-void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing)
-{
- int x, newindex = 0;
-
- /* First step is to get the codecs "index number" */
- for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
- if (AST_FORMAT_LIST[x].bits == format) {
- newindex = x + 1;
- break;
- }
- }
- /* Done if its unknown */
- if (!newindex)
- return;
-
- /* Now find any existing occurrence, or the end */
- for (x = 0; x < 32; x++) {
- if (!pref->order[x] || pref->order[x] == newindex)
- break;
- }
-
- if (only_if_existing && !pref->order[x])
- return;
-
- /* Move down to make space to insert - either all the way to the end,
- or as far as the existing location (which will be overwritten) */
- for (; x > 0; x--) {
- pref->order[x] = pref->order[x - 1];
- pref->framing[x] = pref->framing[x - 1];
- }
-
- /* And insert the new entry */
- pref->order[0] = newindex;
- pref->framing[0] = 0; /* ? */
-}
-
-/*! \brief Set packet size for codec */
-int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems)
-{
- int x, index = -1;
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(AST_FORMAT_LIST[x].bits == format) {
- index = x;
- break;
- }
- }
-
- if(index < 0)
- return -1;
-
- /* size validation */
- if(!framems)
- framems = AST_FORMAT_LIST[index].def_ms;
-
- if(AST_FORMAT_LIST[index].inc_ms && framems % AST_FORMAT_LIST[index].inc_ms) /* avoid division by zero */
- framems -= framems % AST_FORMAT_LIST[index].inc_ms;
-
- if(framems < AST_FORMAT_LIST[index].min_ms)
- framems = AST_FORMAT_LIST[index].min_ms;
-
- if(framems > AST_FORMAT_LIST[index].max_ms)
- framems = AST_FORMAT_LIST[index].max_ms;
-
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(pref->order[x] == (index + 1)) {
- pref->framing[x] = framems;
- break;
- }
- }
-
- return x;
-}
-
-/*! \brief Get packet size for codec */
-struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int format)
-{
- int x, index = -1, framems = 0;
- struct ast_format_list fmt = {0};
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(AST_FORMAT_LIST[x].bits == format) {
- fmt = AST_FORMAT_LIST[x];
- index = x;
- break;
- }
- }
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- if(pref->order[x] == (index + 1)) {
- framems = pref->framing[x];
- break;
- }
- }
-
- /* size validation */
- if(!framems)
- framems = AST_FORMAT_LIST[index].def_ms;
-
- if(AST_FORMAT_LIST[index].inc_ms && framems % AST_FORMAT_LIST[index].inc_ms) /* avoid division by zero */
- framems -= framems % AST_FORMAT_LIST[index].inc_ms;
-
- if(framems < AST_FORMAT_LIST[index].min_ms)
- framems = AST_FORMAT_LIST[index].min_ms;
-
- if(framems > AST_FORMAT_LIST[index].max_ms)
- framems = AST_FORMAT_LIST[index].max_ms;
-
- fmt.cur_ms = framems;
-
- return fmt;
-}
-
-/*! \brief Pick a codec */
-int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best)
-{
- int x, ret = 0, slot;
-
- for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
- slot = pref->order[x];
-
- if (!slot)
- break;
- if (formats & AST_FORMAT_LIST[slot-1].bits) {
- ret = AST_FORMAT_LIST[slot-1].bits;
- break;
- }
- }
- if(ret & AST_FORMAT_AUDIO_MASK)
- return ret;
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");
-
- return find_best ? ast_best_codec(formats) : 0;
-}
-
-void ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing)
-{
- char *parse = NULL, *this = NULL, *psize = NULL;
- int format = 0, framems = 0;
-
- parse = ast_strdupa(list);
- while ((this = strsep(&parse, ","))) {
- framems = 0;
- if ((psize = strrchr(this, ':'))) {
- *psize++ = '\0';
- if (option_debug)
- ast_log(LOG_DEBUG,"Packetization for codec: %s is %s\n", this, psize);
- framems = atoi(psize);
- if (framems < 0)
- framems = 0;
- }
- if (!(format = ast_getformatbyname(this))) {
- ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", allowing ? "allow" : "disallow", this);
- continue;
- }
-
- if (mask) {
- if (allowing)
- *mask |= format;
- else
- *mask &= ~format;
- }
-
- /* Set up a preference list for audio. Do not include video in preferences
- since we can not transcode video and have to use whatever is offered
- */
- if (pref && (format & AST_FORMAT_AUDIO_MASK)) {
- if (strcasecmp(this, "all")) {
- if (allowing) {
- ast_codec_pref_append(pref, format);
- ast_codec_pref_setsize(pref, format, framems);
- }
- else
- ast_codec_pref_remove(pref, format);
- } else if (!allowing) {
- memset(pref, 0, sizeof(*pref));
- }
- }
- }
-}
-
-static int g723_len(unsigned char buf)
-{
- enum frame_type type = buf & TYPE_MASK;
-
- switch(type) {
- case TYPE_DONTSEND:
- return 0;
- break;
- case TYPE_SILENCE:
- return 4;
- break;
- case TYPE_HIGH:
- return 24;
- break;
- case TYPE_LOW:
- return 20;
- break;
- default:
- ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", type);
- }
- return -1;
-}
-
-static int g723_samples(unsigned char *buf, int maxlen)
-{
- int pos = 0;
- int samples = 0;
- int res;
- while(pos < maxlen) {
- res = g723_len(buf[pos]);
- if (res <= 0)
- break;
- samples += 240;
- pos += res;
- }
- return samples;
-}
-
-static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
-{
- int byte = bit / 8; /* byte containing first bit */
- int rem = 8 - (bit % 8); /* remaining bits in first byte */
- unsigned char ret = 0;
-
- if (n <= 0 || n > 8)
- return 0;
-
- if (rem < n) {
- ret = (data[byte] << (n - rem));
- ret |= (data[byte + 1] >> (8 - n + rem));
- } else {
- ret = (data[byte] >> (rem - n));
- }
-
- return (ret & (0xff >> (8 - n)));
-}
-
-static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
-{
- static int SpeexWBSubModeSz[] = {
- 0, 36, 112, 192,
- 352, 0, 0, 0 };
- int off = bit;
- unsigned char c;
-
- /* skip up to two wideband frames */
- if (((len * 8 - off) >= 5) &&
- get_n_bits_at(data, 1, off)) {
- c = get_n_bits_at(data, 3, off + 1);
- off += SpeexWBSubModeSz[c];
-
- if (((len * 8 - off) >= 5) &&
- get_n_bits_at(data, 1, off)) {
- c = get_n_bits_at(data, 3, off + 1);
- off += SpeexWBSubModeSz[c];
-
- if (((len * 8 - off) >= 5) &&
- get_n_bits_at(data, 1, off)) {
- ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
- return -1;
- }
- }
-
- }
- return off - bit;
-}
-
-static int speex_samples(unsigned char *data, int len)
-{
- static int SpeexSubModeSz[] = {
- 5, 43, 119, 160,
- 220, 300, 364, 492,
- 79, 0, 0, 0,
- 0, 0, 0, 0 };
- static int SpeexInBandSz[] = {
- 1, 1, 4, 4,
- 4, 4, 4, 4,
- 8, 8, 16, 16,
- 32, 32, 64, 64 };
- int bit = 0;
- int cnt = 0;
- int off;
- unsigned char c;
-
- while ((len * 8 - bit) >= 5) {
- /* skip wideband frames */
- off = speex_get_wb_sz_at(data, len, bit);
- if (off < 0) {
- ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
- break;
- }
- bit += off;
-
- if ((len * 8 - bit) < 5) {
- ast_log(LOG_WARNING, "Not enough bits remaining after wide band for speex samples.\n");
- break;
- }
-
- /* get control bits */
- c = get_n_bits_at(data, 5, bit);
- bit += 5;
-
- if (c == 15) {
- /* terminator */
- break;
- } else if (c == 14) {
- /* in-band signal; next 4 bits contain signal id */
- c = get_n_bits_at(data, 4, bit);
- bit += 4;
- bit += SpeexInBandSz[c];
- } else if (c == 13) {
- /* user in-band; next 5 bits contain msg len */
- c = get_n_bits_at(data, 5, bit);
- bit += 5;
- bit += c * 8;
- } else if (c > 8) {
- /* unknown */
- break;
- } else {
- /* skip number bits for submode (less the 5 control bits) */
- bit += SpeexSubModeSz[c] - 5;
- cnt += 160; /* new frame */
- }
- }
- return cnt;
-}
-
-int ast_codec_get_samples(struct ast_frame *f)
-{
- int samples=0;
- switch(f->subclass) {
- case AST_FORMAT_SPEEX:
- samples = speex_samples(f->data, f->datalen);
- break;
- case AST_FORMAT_G723_1:
- samples = g723_samples(f->data, f->datalen);
- break;
- case AST_FORMAT_ILBC:
- samples = 240 * (f->datalen / 50);
- break;
- case AST_FORMAT_GSM:
- samples = 160 * (f->datalen / 33);
- break;
- case AST_FORMAT_G729A:
- samples = f->datalen * 8;
- break;
- case AST_FORMAT_SLINEAR:
- samples = f->datalen / 2;
- break;
- case AST_FORMAT_LPC10:
- /* assumes that the RTP packet contains one LPC10 frame */
- samples = 22 * 8;
- samples += (((char *)(f->data))[7] & 0x1) * 8;
- break;
- case AST_FORMAT_ULAW:
- case AST_FORMAT_ALAW:
- samples = f->datalen;
- break;
- case AST_FORMAT_G722:
- case AST_FORMAT_ADPCM:
- case AST_FORMAT_G726:
- case AST_FORMAT_G726_AAL2:
- samples = f->datalen * 2;
- break;
- default:
- ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
- }
- return samples;
-}
-
-int ast_codec_get_len(int format, int samples)
-{
- int len = 0;
-
- /* XXX Still need speex, g723, and lpc10 XXX */
- switch(format) {
- case AST_FORMAT_ILBC:
- len = (samples / 240) * 50;
- break;
- case AST_FORMAT_GSM:
- len = (samples / 160) * 33;
- break;
- case AST_FORMAT_G729A:
- len = samples / 8;
- break;
- case AST_FORMAT_SLINEAR:
- len = samples * 2;
- break;
- case AST_FORMAT_ULAW:
- case AST_FORMAT_ALAW:
- len = samples;
- break;
- case AST_FORMAT_G722:
- case AST_FORMAT_ADPCM:
- case AST_FORMAT_G726:
- case AST_FORMAT_G726_AAL2:
- len = samples / 2;
- break;
- default:
- ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
- }
-
- return len;
-}
-
-int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
-{
- int count;
- short *fdata = f->data;
- short adjust_value = abs(adjustment);
-
- if ((f->frametype != AST_FRAME_VOICE) || (f->subclass != AST_FORMAT_SLINEAR))
- return -1;
-
- if (!adjustment)
- return 0;
-
- for (count = 0; count < f->samples; count++) {
- if (adjustment > 0) {
- ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
- } else if (adjustment < 0) {
- ast_slinear_saturated_divide(&fdata[count], &adjust_value);
- }
- }
-
- return 0;
-}
-
-int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
-{
- int count;
- short *data1, *data2;
-
- if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass != AST_FORMAT_SLINEAR))
- return -1;
-
- if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass != AST_FORMAT_SLINEAR))
- return -1;
-
- if (f1->samples != f2->samples)
- return -1;
-
- for (count = 0, data1 = f1->data, data2 = f2->data;
- count < f1->samples;
- count++, data1++, data2++)
- ast_slinear_saturated_add(data1, data2);
-
- return 0;
-}
diff --git a/1.4/main/fskmodem.c b/1.4/main/fskmodem.c
deleted file mode 100644
index 3ab462886..000000000
--- a/1.4/main/fskmodem.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief FSK Modulator/Demodulator
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg Includes code and algorithms from the Zapata library.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-
-#include "asterisk/fskmodem.h"
-
-#define NBW 2
-#define BWLIST {75,800}
-#define NF 6
-#define FLIST {1400,1800,1200,2200,1300,2100}
-
-#define STATE_SEARCH_STARTBIT 0
-#define STATE_SEARCH_STARTBIT2 1
-#define STATE_SEARCH_STARTBIT3 2
-#define STATE_GET_BYTE 3
-
-static inline float get_sample(short **buffer, int *len)
-{
- float retval;
- retval = (float) **buffer / 256;
- (*buffer)++;
- (*len)--;
- return retval;
-}
-
-#define GET_SAMPLE get_sample(&buffer, len)
-
-/* Coeficientes para filtros de entrada */
-/* Tabla de coeficientes, generada a partir del programa "mkfilter" */
-/* Formato: coef[IDX_FREC][IDX_BW][IDX_COEF] */
-/* IDX_COEF=0 => 1/GAIN */
-/* IDX_COEF=1-6 => Coeficientes y[n] */
-
-static double coef_in[NF][NBW][8]={
-#include "coef_in.h"
-};
-
-/* Coeficientes para filtro de salida */
-/* Tabla de coeficientes, generada a partir del programa "mkfilter" */
-/* Formato: coef[IDX_BW][IDX_COEF] */
-/* IDX_COEF=0 => 1/GAIN */
-/* IDX_COEF=1-6 => Coeficientes y[n] */
-
-static double coef_out[NBW][8]={
-#include "coef_out.h"
-};
-
-
-/*! Filtro pasa-banda para frecuencia de MARCA */
-static inline float filtroM(fsk_data *fskd,float in)
-{
- int i,j;
- double s;
- double *pc;
-
- pc=&coef_in[fskd->f_mark_idx][fskd->bw][0];
- fskd->fmxv[(fskd->fmp+6)&7]=in*(*pc++);
-
- s=(fskd->fmxv[(fskd->fmp+6)&7] - fskd->fmxv[fskd->fmp]) + 3 * (fskd->fmxv[(fskd->fmp+2)&7] - fskd->fmxv[(fskd->fmp+4)&7]);
- for (i=0,j=fskd->fmp;i<6;i++,j++) s+=fskd->fmyv[j&7]*(*pc++);
- fskd->fmyv[j&7]=s;
- fskd->fmp++; fskd->fmp&=7;
- return s;
-}
-
-/*! Filtro pasa-banda para frecuencia de ESPACIO */
-static inline float filtroS(fsk_data *fskd,float in)
-{
- int i,j;
- double s;
- double *pc;
-
- pc=&coef_in[fskd->f_space_idx][fskd->bw][0];
- fskd->fsxv[(fskd->fsp+6)&7]=in*(*pc++);
-
- s=(fskd->fsxv[(fskd->fsp+6)&7] - fskd->fsxv[fskd->fsp]) + 3 * (fskd->fsxv[(fskd->fsp+2)&7] - fskd->fsxv[(fskd->fsp+4)&7]);
- for (i=0,j=fskd->fsp;i<6;i++,j++) s+=fskd->fsyv[j&7]*(*pc++);
- fskd->fsyv[j&7]=s;
- fskd->fsp++; fskd->fsp&=7;
- return s;
-}
-
-/*! Filtro pasa-bajos para datos demodulados */
-static inline float filtroL(fsk_data *fskd,float in)
-{
- int i,j;
- double s;
- double *pc;
-
- pc=&coef_out[fskd->bw][0];
- fskd->flxv[(fskd->flp + 6) & 7]=in * (*pc++);
-
- s= (fskd->flxv[fskd->flp] + fskd->flxv[(fskd->flp+6)&7]) +
- 6 * (fskd->flxv[(fskd->flp+1)&7] + fskd->flxv[(fskd->flp+5)&7]) +
- 15 * (fskd->flxv[(fskd->flp+2)&7] + fskd->flxv[(fskd->flp+4)&7]) +
- 20 * fskd->flxv[(fskd->flp+3)&7];
-
- for (i=0,j=fskd->flp;i<6;i++,j++) s+=fskd->flyv[j&7]*(*pc++);
- fskd->flyv[j&7]=s;
- fskd->flp++; fskd->flp&=7;
- return s;
-}
-
-static inline int demodulador(fsk_data *fskd, float *retval, float x)
-{
- float xS,xM;
-
- fskd->cola_in[fskd->pcola]=x;
-
- xS=filtroS(fskd,x);
- xM=filtroM(fskd,x);
-
- fskd->cola_filtro[fskd->pcola]=xM-xS;
-
- x=filtroL(fskd,xM*xM - xS*xS);
-
- fskd->cola_demod[fskd->pcola++]=x;
- fskd->pcola &= (NCOLA-1);
-
- *retval = x;
- return(0);
-}
-
-static int get_bit_raw(fsk_data *fskd, short *buffer, int *len)
-{
- /* Esta funcion implementa un DPLL para sincronizarse con los bits */
- float x,spb,spb2,ds;
- int f;
-
- spb=fskd->spb;
- if (fskd->spb == 7) spb = 8000.0 / 1200.0;
- ds=spb/32.;
- spb2=spb/2.;
-
- for (f=0;;){
- if (demodulador(fskd,&x, GET_SAMPLE)) return(-1);
- if ((x*fskd->x0)<0) { /* Transicion */
- if (!f) {
- if (fskd->cont<(spb2)) fskd->cont+=ds; else fskd->cont-=ds;
- f=1;
- }
- }
- fskd->x0=x;
- fskd->cont+=1.;
- if (fskd->cont>spb) {
- fskd->cont-=spb;
- break;
- }
- }
- f=(x>0)?0x80:0;
- return(f);
-}
-
-int fsk_serie(fsk_data *fskd, short *buffer, int *len, int *outbyte)
-{
- int a;
- int i,j,n1,r;
- int samples=0;
- int olen;
- int beginlen=*len;
- int beginlenx;
-
- switch(fskd->state) {
- /* Pick up where we left off */
- case STATE_SEARCH_STARTBIT2:
- goto search_startbit2;
- case STATE_SEARCH_STARTBIT3:
- goto search_startbit3;
- case STATE_GET_BYTE:
- goto getbyte;
- }
- /* Esperamos bit de start */
- do {
-/* this was jesus's nice, reasonable, working (at least with RTTY) code
-to look for the beginning of the start bit. Unfortunately, since TTY/TDD's
-just start sending a start bit with nothing preceding it at the beginning
-of a transmission (what a LOSING design), we cant do it this elegantly */
-/*
- if (demodulador(zap,&x1)) return(-1);
- for(;;) {
- if (demodulador(zap,&x2)) return(-1);
- if (x1>0 && x2<0) break;
- x1=x2;
- }
-*/
-/* this is now the imprecise, losing, but functional code to detect the
-beginning of a start bit in the TDD sceanario. It just looks for sufficient
-level to maybe, perhaps, guess, maybe that its maybe the beginning of
-a start bit, perhaps. This whole thing stinks! */
- beginlenx=beginlen; /* just to avoid unused war warnings */
- if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
- samples++;
- for(;;)
- {
-search_startbit2:
- if (*len <= 0) {
- fskd->state = STATE_SEARCH_STARTBIT2;
- return 0;
- }
- samples++;
- if (demodulador(fskd,&fskd->x2,GET_SAMPLE)) return(-1);
-#if 0
- printf("x2 = %5.5f ", fskd->x2);
-#endif
- if (fskd->x2 < -0.5) break;
- }
-search_startbit3:
- /* Esperamos 0.5 bits antes de usar DPLL */
- i=fskd->spb/2;
- if (*len < i) {
- fskd->state = STATE_SEARCH_STARTBIT3;
- return 0;
- }
- for(;i>0;i--) { if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
-#if 0
- printf("x1 = %5.5f ", fskd->x1);
-#endif
- samples++; }
-
- /* x1 debe ser negativo (confirmación del bit de start) */
-
- } while (fskd->x1>0);
- fskd->state = STATE_GET_BYTE;
-
-getbyte:
-
- /* Need at least 80 samples (for 1200) or
- 1320 (for 45.5) to be sure we'll have a byte */
- if (fskd->nbit < 8) {
- if (*len < 1320)
- return 0;
- } else {
- if (*len < 80)
- return 0;
- }
- /* Leemos ahora los bits de datos */
- j=fskd->nbit;
- for (a=n1=0;j;j--) {
- olen = *len;
- i=get_bit_raw(fskd, buffer, len);
- buffer += (olen - *len);
- if (i == -1) return(-1);
- if (i) n1++;
- a>>=1; a|=i;
- }
- j=8-fskd->nbit;
- a>>=j;
-
- /* Leemos bit de paridad (si existe) y la comprobamos */
- if (fskd->paridad) {
- olen = *len;
- i=get_bit_raw(fskd, buffer, len);
- buffer += (olen - *len);
- if (i == -1) return(-1);
- if (i) n1++;
- if (fskd->paridad==1) { /* paridad=1 (par) */
- if (n1&1) a|=0x100; /* error */
- } else { /* paridad=2 (impar) */
- if (!(n1&1)) a|=0x100; /* error */
- }
- }
-
- /* Leemos bits de STOP. Todos deben ser 1 */
-
- for (j=fskd->nstop;j;j--) {
- r = get_bit_raw(fskd, buffer, len);
- if (r == -1) return(-1);
- if (!r) a|=0x200;
- }
-
- /* Por fin retornamos */
- /* Bit 8 : Error de paridad */
- /* Bit 9 : Error de Framming */
-
- *outbyte = a;
- fskd->state = STATE_SEARCH_STARTBIT;
- return 1;
-}
diff --git a/1.4/main/global_datastores.c b/1.4/main/global_datastores.c
deleted file mode 100644
index 9b87b2cb4..000000000
--- a/1.4/main/global_datastores.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2007, Digium, Inc.
- *
- * Mark Michelson <mmichelson@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.
- */
-
-/*! \file
- *
- * \brief globally-accessible datastore information and callbacks
- *
- * \author Mark Michelson <mmichelson@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/global_datastores.h"
-#include "asterisk/linkedlists.h"
-
-static void dialed_interface_destroy(void *data)
-{
- struct ast_dialed_interface *di = NULL;
- AST_LIST_HEAD(, ast_dialed_interface) *dialed_interface_list = data;
-
- if (!dialed_interface_list)
- return;
-
- AST_LIST_LOCK(dialed_interface_list);
- while ((di = AST_LIST_REMOVE_HEAD(dialed_interface_list, list)))
- ast_free(di);
- AST_LIST_UNLOCK(dialed_interface_list);
-
- AST_LIST_HEAD_DESTROY(dialed_interface_list);
- ast_free(dialed_interface_list);
-}
-
-static void *dialed_interface_duplicate(void *data)
-{
- struct ast_dialed_interface *di = NULL;
- AST_LIST_HEAD(, ast_dialed_interface) *old_list;
- AST_LIST_HEAD(, ast_dialed_interface) *new_list = NULL;
-
- if(!(old_list = data))
- return NULL;
-
- if(!(new_list = ast_calloc(1, sizeof(*new_list))))
- return NULL;
-
- AST_LIST_HEAD_INIT(new_list);
- AST_LIST_LOCK(old_list);
- AST_LIST_TRAVERSE(old_list, di, list) {
- struct ast_dialed_interface *di2 = ast_calloc(1, sizeof(*di2) + strlen(di->interface));
- if(!di2) {
- AST_LIST_UNLOCK(old_list);
- dialed_interface_destroy(new_list);
- return NULL;
- }
- strcpy(di2->interface, di->interface);
- AST_LIST_INSERT_TAIL(new_list, di2, list);
- }
- AST_LIST_UNLOCK(old_list);
-
- return new_list;
-}
-
-const struct ast_datastore_info dialed_interface_info = {
- .type ="dialed-interface",
- .destroy = dialed_interface_destroy,
- .duplicate = dialed_interface_duplicate,
-};
diff --git a/1.4/main/http.c b/1.4/main/http.c
deleted file mode 100644
index a0d6aad19..000000000
--- a/1.4/main/http.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * 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.
- */
-
-/*!
- * \file
- * \brief http server for AMI access
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * This program implements a tiny http server
- * and was inspired by micro-httpd by Jef Poskanzer
- *
- * \ref AstHTTP - AMI over the http protocol
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-
-#include "asterisk/cli.h"
-#include "asterisk/http.h"
-#include "asterisk/utils.h"
-#include "asterisk/strings.h"
-#include "asterisk/options.h"
-#include "asterisk/config.h"
-#include "asterisk/version.h"
-#include "asterisk/manager.h"
-
-#define MAX_PREFIX 80
-#define DEFAULT_PREFIX "/asterisk"
-
-struct ast_http_server_instance {
- FILE *f;
- int fd;
- struct sockaddr_in requestor;
- ast_http_callback callback;
-};
-
-AST_RWLOCK_DEFINE_STATIC(uris_lock);
-static struct ast_http_uri *uris;
-
-static int httpfd = -1;
-static pthread_t master = AST_PTHREADT_NULL;
-static char prefix[MAX_PREFIX];
-static int prefix_len;
-static struct sockaddr_in oldsin;
-static int enablestatic;
-
-/*! \brief Limit the kinds of files we're willing to serve up */
-static struct {
- const char *ext;
- const char *mtype;
-} mimetypes[] = {
- { "png", "image/png" },
- { "jpg", "image/jpeg" },
- { "js", "application/x-javascript" },
- { "wav", "audio/x-wav" },
- { "mp3", "audio/mpeg" },
- { "svg", "image/svg+xml" },
- { "svgz", "image/svg+xml" },
- { "gif", "image/gif" },
-};
-
-static const char *ftype2mtype(const char *ftype, char *wkspace, int wkspacelen)
-{
- int x;
- if (ftype) {
- for (x=0;x<sizeof(mimetypes) / sizeof(mimetypes[0]); x++) {
- if (!strcasecmp(ftype, mimetypes[x].ext))
- return mimetypes[x].mtype;
- }
- }
- snprintf(wkspace, wkspacelen, "text/%s", ftype ? ftype : "plain");
- return wkspace;
-}
-
-static char *static_callback(struct sockaddr_in *req, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
-{
- char result[4096];
- char *c=result;
- char *path;
- char *ftype;
- const char *mtype;
- char wkspace[80];
- struct stat st;
- int len;
- int fd;
- void *blob;
-
- /* Yuck. I'm not really sold on this, but if you don't deliver static content it makes your configuration
- substantially more challenging, but this seems like a rather irritating feature creep on Asterisk. */
- if (!enablestatic || ast_strlen_zero(uri))
- goto out403;
- /* Disallow any funny filenames at all */
- if ((uri[0] < 33) || strchr("./|~@#$%^&*() \t", uri[0]))
- goto out403;
- if (strstr(uri, "/.."))
- goto out403;
-
- if ((ftype = strrchr(uri, '.')))
- ftype++;
- mtype = ftype2mtype(ftype, wkspace, sizeof(wkspace));
-
- /* Cap maximum length */
- len = strlen(uri) + strlen(ast_config_AST_DATA_DIR) + strlen("/static-http/") + 5;
- if (len > 1024)
- goto out403;
-
- path = alloca(len);
- sprintf(path, "%s/static-http/%s", ast_config_AST_DATA_DIR, uri);
- if (stat(path, &st))
- goto out404;
- if (S_ISDIR(st.st_mode))
- goto out404;
- fd = open(path, O_RDONLY);
- if (fd < 0)
- goto out403;
-
- len = st.st_size + strlen(mtype) + 40;
-
- blob = malloc(len);
- if (blob) {
- c = blob;
- sprintf(c, "Content-type: %s\r\n\r\n", mtype);
- c += strlen(c);
- *contentlength = read(fd, c, st.st_size);
- if (*contentlength < 0) {
- close(fd);
- free(blob);
- goto out403;
- }
- }
- close(fd);
- return blob;
-
-out404:
- *status = 404;
- *title = strdup("Not Found");
- return ast_http_error(404, "Not Found", NULL, "Nothing to see here. Move along.");
-
-out403:
- *status = 403;
- *title = strdup("Access Denied");
- return ast_http_error(403, "Access Denied", NULL, "Sorry, I cannot let you do that, Dave.");
-}
-
-
-static char *httpstatus_callback(struct sockaddr_in *req, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
-{
- char result[4096];
- size_t reslen = sizeof(result);
- char *c=result;
- struct ast_variable *v;
-
- ast_build_string(&c, &reslen,
- "\r\n"
- "<title>Asterisk HTTP Status</title>\r\n"
- "<body bgcolor=\"#ffffff\">\r\n"
- "<table bgcolor=\"#f1f1f1\" align=\"center\"><tr><td bgcolor=\"#e0e0ff\" colspan=\"2\" width=\"500\">\r\n"
- "<h2>&nbsp;&nbsp;Asterisk&trade; HTTP Status</h2></td></tr>\r\n");
-
- ast_build_string(&c, &reslen, "<tr><td><i>Prefix</i></td><td><b>%s</b></td></tr>\r\n", prefix);
- ast_build_string(&c, &reslen, "<tr><td><i>Bind Address</i></td><td><b>%s</b></td></tr>\r\n",
- ast_inet_ntoa(oldsin.sin_addr));
- ast_build_string(&c, &reslen, "<tr><td><i>Bind Port</i></td><td><b>%d</b></td></tr>\r\n",
- ntohs(oldsin.sin_port));
- ast_build_string(&c, &reslen, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
- v = vars;
- while(v) {
- if (strncasecmp(v->name, "cookie_", 7))
- ast_build_string(&c, &reslen, "<tr><td><i>Submitted Variable '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
- v = v->next;
- }
- ast_build_string(&c, &reslen, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
- v = vars;
- while(v) {
- if (!strncasecmp(v->name, "cookie_", 7))
- ast_build_string(&c, &reslen, "<tr><td><i>Cookie '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
- v = v->next;
- }
- ast_build_string(&c, &reslen, "</table><center><font size=\"-1\"><i>Asterisk and Digium are registered trademarks of Digium, Inc.</i></font></center></body>\r\n");
- return strdup(result);
-}
-
-static struct ast_http_uri statusuri = {
- .callback = httpstatus_callback,
- .description = "Asterisk HTTP General Status",
- .uri = "httpstatus",
- .has_subtree = 0,
-};
-
-static struct ast_http_uri staticuri = {
- .callback = static_callback,
- .description = "Asterisk HTTP Static Delivery",
- .uri = "static",
- .has_subtree = 1,
- .static_content = 1,
-};
-
-char *ast_http_error(int status, const char *title, const char *extra_header, const char *text)
-{
- char *c = NULL;
- asprintf(&c,
- "Content-type: text/html\r\n"
- "%s"
- "\r\n"
- "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
- "<html><head>\r\n"
- "<title>%d %s</title>\r\n"
- "</head><body>\r\n"
- "<h1>%s</h1>\r\n"
- "<p>%s</p>\r\n"
- "<hr />\r\n"
- "<address>Asterisk Server</address>\r\n"
- "</body></html>\r\n",
- (extra_header ? extra_header : ""), status, title, title, text);
- return c;
-}
-
-int ast_http_uri_link(struct ast_http_uri *urih)
-{
- struct ast_http_uri *prev;
-
- ast_rwlock_wrlock(&uris_lock);
- prev = uris;
- if (!uris || strlen(uris->uri) <= strlen(urih->uri)) {
- urih->next = uris;
- uris = urih;
- } else {
- while (prev->next && (strlen(prev->next->uri) > strlen(urih->uri)))
- prev = prev->next;
- /* Insert it here */
- urih->next = prev->next;
- prev->next = urih;
- }
- ast_rwlock_unlock(&uris_lock);
-
- return 0;
-}
-
-void ast_http_uri_unlink(struct ast_http_uri *urih)
-{
- struct ast_http_uri *prev;
-
- ast_rwlock_wrlock(&uris_lock);
- if (!uris) {
- ast_rwlock_unlock(&uris_lock);
- return;
- }
- prev = uris;
- if (uris == urih) {
- uris = uris->next;
- }
- while(prev->next) {
- if (prev->next == urih) {
- prev->next = urih->next;
- break;
- }
- prev = prev->next;
- }
- ast_rwlock_unlock(&uris_lock);
-}
-
-static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status,
- char **title, int *contentlength, struct ast_variable **cookies,
- unsigned int *static_content)
-{
- char *c;
- char *turi;
- char *params;
- char *var;
- char *val;
- struct ast_http_uri *urih=NULL;
- int len;
- struct ast_variable *vars=NULL, *v, *prev = NULL;
-
-
- params = strchr(uri, '?');
- if (params) {
- *params = '\0';
- params++;
- while ((var = strsep(&params, "&"))) {
- val = strchr(var, '=');
- if (val) {
- *val = '\0';
- val++;
- ast_uri_decode(val);
- } else
- val = "";
- ast_uri_decode(var);
- if ((v = ast_variable_new(var, val))) {
- if (vars)
- prev->next = v;
- else
- vars = v;
- prev = v;
- }
- }
- }
- if (prev)
- prev->next = *cookies;
- else
- vars = *cookies;
- *cookies = NULL;
- ast_uri_decode(uri);
- if (!strncasecmp(uri, prefix, prefix_len)) {
- uri += prefix_len;
- if (!*uri || (*uri == '/')) {
- if (*uri == '/')
- uri++;
- ast_rwlock_rdlock(&uris_lock);
- urih = uris;
- while(urih) {
- len = strlen(urih->uri);
- if (!strncasecmp(urih->uri, uri, len)) {
- if (!uri[len] || uri[len] == '/') {
- turi = uri + len;
- if (*turi == '/')
- turi++;
- if (!*turi || urih->has_subtree) {
- uri = turi;
- break;
- }
- }
- }
- urih = urih->next;
- }
- if (!urih)
- ast_rwlock_unlock(&uris_lock);
- }
- }
- if (urih) {
- if (urih->static_content)
- *static_content = 1;
- c = urih->callback(sin, uri, vars, status, title, contentlength);
- ast_rwlock_unlock(&uris_lock);
- } else if (ast_strlen_zero(uri) && ast_strlen_zero(prefix)) {
- /* Special case: If no prefix, and no URI, send to /static/index.html */
- c = ast_http_error(302, "Moved Temporarily", "Location: /static/index.html\r\n", "This is not the page you are looking for...");
- *status = 302;
- *title = strdup("Moved Temporarily");
- } else {
- c = ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
- *status = 404;
- *title = strdup("Not Found");
- }
- ast_variables_destroy(vars);
- return c;
-}
-
-static struct ast_variable *parse_cookies(char *cookies)
-{
- char *cur;
- struct ast_variable *vars = NULL, *var;
-
- /* Skip Cookie: */
- cookies += 8;
-
- while ((cur = strsep(&cookies, ";"))) {
- char *name, *val;
-
- name = val = cur;
- strsep(&val, "=");
-
- if (ast_strlen_zero(name) || ast_strlen_zero(val)) {
- continue;
- }
-
- name = ast_strip(name);
- val = ast_strip_quoted(val, "\"", "\"");
-
- if (ast_strlen_zero(name) || ast_strlen_zero(val)) {
- continue;
- }
-
- if (option_debug) {
- ast_log(LOG_DEBUG, "mmm ... cookie! Name: '%s' Value: '%s'\n", name, val);
- }
-
- var = ast_variable_new(name, val);
- var->next = vars;
- vars = var;
- }
-
- return vars;
-}
-
-static void *ast_httpd_helper_thread(void *data)
-{
- char buf[4096];
- char cookie[4096];
- char timebuf[256];
- struct ast_http_server_instance *ser = data;
- struct ast_variable *vars = NULL;
- char *uri, *c, *title=NULL;
- int status = 200, contentlength = 0;
- time_t t;
- unsigned int static_content = 0;
-
- if (fgets(buf, sizeof(buf), ser->f)) {
- /* Skip method */
- uri = buf;
- while(*uri && (*uri > 32))
- uri++;
- if (*uri) {
- *uri = '\0';
- uri++;
- }
-
- /* Skip white space */
- while (*uri && (*uri < 33))
- uri++;
-
- if (*uri) {
- c = uri;
- while (*c && (*c > 32))
- c++;
- if (*c) {
- *c = '\0';
- }
- }
-
- while (fgets(cookie, sizeof(cookie), ser->f)) {
- /* Trim trailing characters */
- while(!ast_strlen_zero(cookie) && (cookie[strlen(cookie) - 1] < 33)) {
- cookie[strlen(cookie) - 1] = '\0';
- }
- if (ast_strlen_zero(cookie))
- break;
- if (!strncasecmp(cookie, "Cookie: ", 8)) {
- vars = parse_cookies(cookie);
- }
- }
-
- if (*uri) {
- if (!strcasecmp(buf, "get"))
- c = handle_uri(&ser->requestor, uri, &status, &title, &contentlength, &vars, &static_content);
- else
- c = ast_http_error(501, "Not Implemented", NULL, "Attempt to use unimplemented / unsupported method");\
- } else
- c = ast_http_error(400, "Bad Request", NULL, "Invalid Request");
-
- /* If they aren't mopped up already, clean up the cookies */
- if (vars)
- ast_variables_destroy(vars);
-
- if (!c)
- c = ast_http_error(500, "Internal Error", NULL, "Internal Server Error");
- if (c) {
- time(&t);
- strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
- ast_cli(ser->fd, "HTTP/1.1 %d %s\r\n", status, title ? title : "OK");
- ast_cli(ser->fd, "Server: Asterisk/%s\r\n", ASTERISK_VERSION);
- ast_cli(ser->fd, "Date: %s\r\n", timebuf);
- ast_cli(ser->fd, "Connection: close\r\n");
- if (!static_content)
- ast_cli(ser->fd, "Cache-Control: no-cache, no-store\r\n");
- /* We set the no-cache headers only for dynamic content.
- * If you want to make sure the static file you requested is not from cache,
- * append a random variable to your GET request. Ex: 'something.html?r=109987734'
- */
-
- if (contentlength) {
- char *tmp;
- tmp = strstr(c, "\r\n\r\n");
- if (tmp) {
- ast_cli(ser->fd, "Content-length: %d\r\n", contentlength);
- write(ser->fd, c, (tmp + 4 - c));
- write(ser->fd, tmp + 4, contentlength);
- }
- } else
- ast_cli(ser->fd, "%s", c);
- free(c);
- }
- if (title)
- free(title);
- }
- fclose(ser->f);
- free(ser);
- return NULL;
-}
-
-static void *http_root(void *data)
-{
- int fd;
- struct sockaddr_in sin;
- socklen_t sinlen;
- struct ast_http_server_instance *ser;
- pthread_t launched;
- pthread_attr_t attr;
-
- for (;;) {
- int flags;
-
- ast_wait_for_input(httpfd, -1);
- sinlen = sizeof(sin);
- fd = accept(httpfd, (struct sockaddr *)&sin, &sinlen);
- if (fd < 0) {
- if ((errno != EAGAIN) && (errno != EINTR))
- ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
- continue;
- }
- ser = ast_calloc(1, sizeof(*ser));
- if (!ser) {
- ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
- close(fd);
- continue;
- }
- flags = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
- ser->fd = fd;
- memcpy(&ser->requestor, &sin, sizeof(ser->requestor));
- if ((ser->f = fdopen(ser->fd, "w+"))) {
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- if (ast_pthread_create_background(&launched, &attr, ast_httpd_helper_thread, ser)) {
- ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
- fclose(ser->f);
- free(ser);
- }
- pthread_attr_destroy(&attr);
- } else {
- ast_log(LOG_WARNING, "fdopen failed!\n");
- close(ser->fd);
- free(ser);
- }
- }
- return NULL;
-}
-
-char *ast_http_setcookie(const char *var, const char *val, int expires, char *buf, size_t buflen)
-{
- char *c;
- c = buf;
- ast_build_string(&c, &buflen, "Set-Cookie: %s=\"%s\"; Version=\"1\"", var, val);
- if (expires)
- ast_build_string(&c, &buflen, "; Max-Age=%d", expires);
- ast_build_string(&c, &buflen, "\r\n");
- return buf;
-}
-
-
-static void http_server_start(struct sockaddr_in *sin)
-{
- int flags;
- int x = 1;
-
- /* Do nothing if nothing has changed */
- if (!memcmp(&oldsin, sin, sizeof(oldsin))) {
- ast_log(LOG_DEBUG, "Nothing changed in http\n");
- return;
- }
-
- memcpy(&oldsin, sin, sizeof(oldsin));
-
- /* Shutdown a running server if there is one */
- if (master != AST_PTHREADT_NULL) {
- pthread_cancel(master);
- pthread_kill(master, SIGURG);
- pthread_join(master, NULL);
- }
-
- if (httpfd != -1)
- close(httpfd);
-
- /* If there's no new server, stop here */
- if (!sin->sin_family)
- return;
-
-
- httpfd = socket(AF_INET, SOCK_STREAM, 0);
- if (httpfd < 0) {
- ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
- return;
- }
-
- setsockopt(httpfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
- if (bind(httpfd, (struct sockaddr *)sin, sizeof(*sin))) {
- ast_log(LOG_NOTICE, "Unable to bind http server to %s:%d: %s\n",
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
- strerror(errno));
- close(httpfd);
- httpfd = -1;
- return;
- }
- if (listen(httpfd, 10)) {
- ast_log(LOG_NOTICE, "Unable to listen!\n");
- close(httpfd);
- httpfd = -1;
- return;
- }
- flags = fcntl(httpfd, F_GETFL);
- fcntl(httpfd, F_SETFL, flags | O_NONBLOCK);
- if (ast_pthread_create_background(&master, NULL, http_root, NULL)) {
- ast_log(LOG_NOTICE, "Unable to launch http server on %s:%d: %s\n",
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
- strerror(errno));
- close(httpfd);
- httpfd = -1;
- }
-}
-
-static int __ast_http_load(int reload)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- int enabled=0;
- int newenablestatic=0;
- struct sockaddr_in sin;
- struct hostent *hp;
- struct ast_hostent ahp;
- char newprefix[MAX_PREFIX];
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_port = htons(8088);
-
- strcpy(newprefix, DEFAULT_PREFIX);
-
- cfg = ast_config_load("http.conf");
- if (cfg) {
- v = ast_variable_browse(cfg, "general");
- while(v) {
- if (!strcasecmp(v->name, "enabled"))
- enabled = ast_true(v->value);
- else if (!strcasecmp(v->name, "enablestatic"))
- newenablestatic = ast_true(v->value);
- else if (!strcasecmp(v->name, "bindport"))
- sin.sin_port = ntohs(atoi(v->value));
- else if (!strcasecmp(v->name, "bindaddr")) {
- if ((hp = ast_gethostbyname(v->value, &ahp))) {
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- } else {
- ast_log(LOG_WARNING, "Invalid bind address '%s'\n", v->value);
- }
- } else if (!strcasecmp(v->name, "prefix")) {
- if (!ast_strlen_zero(v->value)) {
- newprefix[0] = '/';
- ast_copy_string(newprefix + 1, v->value, sizeof(newprefix) - 1);
- } else {
- newprefix[0] = '\0';
- }
-
- }
- v = v->next;
- }
- ast_config_destroy(cfg);
- }
- if (enabled)
- sin.sin_family = AF_INET;
- if (strcmp(prefix, newprefix)) {
- ast_copy_string(prefix, newprefix, sizeof(prefix));
- prefix_len = strlen(prefix);
- }
- enablestatic = newenablestatic;
-
- http_server_start(&sin);
-
-
- return 0;
-}
-
-static int handle_show_http(int fd, int argc, char *argv[])
-{
- struct ast_http_uri *urih;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- ast_cli(fd, "HTTP Server Status:\n");
- ast_cli(fd, "Prefix: %s\n", prefix);
- if (oldsin.sin_family)
- ast_cli(fd, "Server Enabled and Bound to %s:%d\n\n",
- ast_inet_ntoa(oldsin.sin_addr),
- ntohs(oldsin.sin_port));
- else
- ast_cli(fd, "Server Disabled\n\n");
- ast_cli(fd, "Enabled URI's:\n");
- ast_rwlock_rdlock(&uris_lock);
- urih = uris;
- while(urih){
- ast_cli(fd, "%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
- urih = urih->next;
- }
- if (!uris)
- ast_cli(fd, "None.\n");
- ast_rwlock_unlock(&uris_lock);
-
- return RESULT_SUCCESS;
-}
-
-int ast_http_reload(void)
-{
- return __ast_http_load(1);
-}
-
-static char show_http_help[] =
-"Usage: http show status\n"
-" Lists status of internal HTTP engine\n";
-
-static struct ast_cli_entry cli_http[] = {
- { { "http", "show", "status", NULL },
- handle_show_http, "Display HTTP server status",
- show_http_help },
-};
-
-int ast_http_init(void)
-{
- ast_http_uri_link(&statusuri);
- ast_http_uri_link(&staticuri);
- ast_cli_register_multiple(cli_http, sizeof(cli_http) / sizeof(struct ast_cli_entry));
-
- return __ast_http_load(0);
-}
diff --git a/1.4/main/image.c b/1.4/main/image.c
deleted file mode 100644
index 644758495..000000000
--- a/1.4/main/image.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Image Management
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "asterisk/sched.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/file.h"
-#include "asterisk/image.h"
-#include "asterisk/translate.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-
-/* XXX Why don't we just use the formats struct for this? */
-static AST_LIST_HEAD_STATIC(imagers, ast_imager);
-
-int ast_image_register(struct ast_imager *img)
-{
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Registered format '%s' (%s)\n", img->name, img->desc);
- AST_LIST_LOCK(&imagers);
- AST_LIST_INSERT_HEAD(&imagers, img, list);
- AST_LIST_UNLOCK(&imagers);
- return 0;
-}
-
-void ast_image_unregister(struct ast_imager *img)
-{
- struct ast_imager *i;
-
- AST_LIST_LOCK(&imagers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&imagers, i, list) {
- if (i == img) {
- AST_LIST_REMOVE_CURRENT(&imagers, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&imagers);
- if (i && (option_verbose > 1))
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered format '%s' (%s)\n", img->name, img->desc);
-}
-
-int ast_supports_images(struct ast_channel *chan)
-{
- if (!chan || !chan->tech)
- return 0;
- if (!chan->tech->send_image)
- return 0;
- return 1;
-}
-
-static int file_exists(char *filename)
-{
- int res;
- struct stat st;
- res = stat(filename, &st);
- if (!res)
- return st.st_size;
- return 0;
-}
-
-static void make_filename(char *buf, int len, char *filename, const char *preflang, char *ext)
-{
- if (filename[0] == '/') {
- if (!ast_strlen_zero(preflang))
- snprintf(buf, len, "%s-%s.%s", filename, preflang, ext);
- else
- snprintf(buf, len, "%s.%s", filename, ext);
- } else {
- if (!ast_strlen_zero(preflang))
- snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_DATA_DIR, "images", filename, preflang, ext);
- else
- snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_DATA_DIR, "images", filename, ext);
- }
-}
-
-struct ast_frame *ast_read_image(char *filename, const char *preflang, int format)
-{
- struct ast_imager *i;
- char buf[256];
- char tmp[80];
- char *e;
- struct ast_imager *found = NULL;
- int fd;
- int len=0;
- struct ast_frame *f = NULL;
-
- AST_LIST_LOCK(&imagers);
- AST_LIST_TRAVERSE(&imagers, i, list) {
- if (i->format & format) {
- char *stringp=NULL;
- ast_copy_string(tmp, i->exts, sizeof(tmp));
- stringp=tmp;
- e = strsep(&stringp, "|");
- while(e) {
- make_filename(buf, sizeof(buf), filename, preflang, e);
- if ((len = file_exists(buf))) {
- found = i;
- break;
- }
- make_filename(buf, sizeof(buf), filename, NULL, e);
- if ((len = file_exists(buf))) {
- found = i;
- break;
- }
- e = strsep(&stringp, "|");
- }
- }
- if (found)
- break;
- }
-
- if (found) {
- fd = open(buf, O_RDONLY);
- if (fd > -1) {
- if (!found->identify || found->identify(fd)) {
- /* Reset file pointer */
- lseek(fd, 0, SEEK_SET);
- f = found->read_image(fd,len);
- } else
- ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, found->name);
- close(fd);
- } else
- ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno));
- } else
- ast_log(LOG_WARNING, "Image file '%s' not found\n", filename);
-
- AST_LIST_UNLOCK(&imagers);
-
- return f;
-}
-
-int ast_send_image(struct ast_channel *chan, char *filename)
-{
- struct ast_frame *f;
- int res = -1;
- if (chan->tech->send_image) {
- f = ast_read_image(filename, chan->language, -1);
- if (f) {
- res = chan->tech->send_image(chan, f);
- ast_frfree(f);
- }
- }
- return res;
-}
-
-static int show_image_formats_deprecated(int fd, int argc, char *argv[])
-{
-#define FORMAT "%10s %10s %50s %10s\n"
-#define FORMAT2 "%10s %10s %50s %10s\n"
- struct ast_imager *i;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format");
- AST_LIST_TRAVERSE(&imagers, i, list)
- ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
- return RESULT_SUCCESS;
-}
-
-static int show_image_formats(int fd, int argc, char *argv[])
-{
-#define FORMAT "%10s %10s %50s %10s\n"
-#define FORMAT2 "%10s %10s %50s %10s\n"
- struct ast_imager *i;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format");
- AST_LIST_TRAVERSE(&imagers, i, list)
- ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
- return RESULT_SUCCESS;
-}
-
-struct ast_cli_entry cli_show_image_formats_deprecated = {
- { "show", "image", "formats" },
- show_image_formats_deprecated, NULL,
- NULL };
-
-struct ast_cli_entry cli_image[] = {
- { { "core", "show", "image", "formats" },
- show_image_formats, "Displays image formats",
- "Usage: core show image formats\n"
- " displays currently registered image formats (if any)\n", NULL, &cli_show_image_formats_deprecated },
-};
-
-int ast_image_init(void)
-{
- ast_cli_register_multiple(cli_image, sizeof(cli_image) / sizeof(struct ast_cli_entry));
- return 0;
-}
diff --git a/1.4/main/indications.c b/1.4/main/indications.c
deleted file mode 100644
index 359a5900f..000000000
--- a/1.4/main/indications.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2002, Pauline Middelink
- *
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Tone Management
- *
- * \author Pauline Middelink <middelink@polyware.nl>
- *
- * This set of function allow us to play a list of tones on a channel.
- * Each element has two frequencies, which are mixed together and a
- * duration. For silence both frequencies can be set to 0.
- * The playtones can be given as a comma separated string.
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "asterisk/indications.h"
-#include "asterisk/frame.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-static int midi_tohz[128] = {
- 8,8,9,9,10,10,11,12,12,13,14,
- 15,16,17,18,19,20,21,23,24,25,
- 27,29,30,32,34,36,38,41,43,46,
- 48,51,55,58,61,65,69,73,77,82,
- 87,92,97,103,110,116,123,130,138,146,
- 155,164,174,184,195,207,220,233,246,261,
- 277,293,311,329,349,369,391,415,440,466,
- 493,523,554,587,622,659,698,739,783,830,
- 880,932,987,1046,1108,1174,1244,1318,1396,1479,
- 1567,1661,1760,1864,1975,2093,2217,2349,2489,2637,
- 2793,2959,3135,3322,3520,3729,3951,4186,4434,4698,
- 4978,5274,5587,5919,6271,6644,7040,7458,7902,8372,
- 8869,9397,9956,10548,11175,11839,12543
- };
-
-struct playtones_item {
- int fac1;
- int init_v2_1;
- int init_v3_1;
- int fac2;
- int init_v2_2;
- int init_v3_2;
- int modulate;
- int duration;
-};
-
-struct playtones_def {
- int vol;
- int reppos;
- int nitems;
- int interruptible;
- struct playtones_item *items;
-};
-
-struct playtones_state {
- int vol;
- int v1_1;
- int v2_1;
- int v3_1;
- int v1_2;
- int v2_2;
- int v3_2;
- int reppos;
- int nitems;
- struct playtones_item *items;
- int npos;
- int oldnpos;
- int pos;
- int origwfmt;
- struct ast_frame f;
- unsigned char offset[AST_FRIENDLY_OFFSET];
- short data[4000];
-};
-
-static void playtones_release(struct ast_channel *chan, void *params)
-{
- struct playtones_state *ps = params;
- if (chan) {
- ast_set_write_format(chan, ps->origwfmt);
- }
- if (ps->items) free(ps->items);
- free(ps);
-}
-
-static void * playtones_alloc(struct ast_channel *chan, void *params)
-{
- struct playtones_def *pd = params;
- struct playtones_state *ps;
- if (!(ps = ast_calloc(1, sizeof(*ps))))
- return NULL;
- ps->origwfmt = chan->writeformat;
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
- ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
- playtones_release(NULL, ps);
- ps = NULL;
- } else {
- ps->vol = pd->vol;
- ps->reppos = pd->reppos;
- ps->nitems = pd->nitems;
- ps->items = pd->items;
- ps->oldnpos = -1;
- }
- /* Let interrupts interrupt :) */
- if (pd->interruptible)
- ast_set_flag(chan, AST_FLAG_WRITE_INT);
- else
- ast_clear_flag(chan, AST_FLAG_WRITE_INT);
- return ps;
-}
-
-static int playtones_generator(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct playtones_state *ps = data;
- struct playtones_item *pi;
- int x;
- /* we need to prepare a frame with 16 * timelen samples as we're
- * generating SLIN audio
- */
- len = samples * 2;
- if (len > sizeof(ps->data) / 2 - 1) {
- ast_log(LOG_WARNING, "Can't generate that much data!\n");
- return -1;
- }
- memset(&ps->f, 0, sizeof(ps->f));
-
- pi = &ps->items[ps->npos];
- if (ps->oldnpos != ps->npos) {
- /* Load new parameters */
- ps->v1_1 = 0;
- ps->v2_1 = pi->init_v2_1;
- ps->v3_1 = pi->init_v3_1;
- ps->v1_2 = 0;
- ps->v2_2 = pi->init_v2_2;
- ps->v3_2 = pi->init_v3_2;
- ps->oldnpos = ps->npos;
- }
- for (x=0;x<len/2;x++) {
- ps->v1_1 = ps->v2_1;
- ps->v2_1 = ps->v3_1;
- ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1;
-
- ps->v1_2 = ps->v2_2;
- ps->v2_2 = ps->v3_2;
- ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2;
- if (pi->modulate) {
- int p;
- p = ps->v3_2 - 32768;
- if (p < 0) p = -p;
- p = ((p * 9) / 10) + 1;
- ps->data[x] = (ps->v3_1 * p) >> 15;
- } else
- ps->data[x] = ps->v3_1 + ps->v3_2;
- }
-
- ps->f.frametype = AST_FRAME_VOICE;
- ps->f.subclass = AST_FORMAT_SLINEAR;
- ps->f.datalen = len;
- ps->f.samples = samples;
- ps->f.offset = AST_FRIENDLY_OFFSET;
- ps->f.data = ps->data;
- ps->f.delivery.tv_sec = 0;
- ps->f.delivery.tv_usec = 0;
- ast_write(chan, &ps->f);
-
- ps->pos += x;
- if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */
- ps->pos = 0; /* start new item */
- ps->npos++;
- if (ps->npos >= ps->nitems) { /* last item? */
- if (ps->reppos == -1) /* repeat set? */
- return -1;
- ps->npos = ps->reppos; /* redo from top */
- }
- }
- return 0;
-}
-
-static struct ast_generator playtones = {
- alloc: playtones_alloc,
- release: playtones_release,
- generate: playtones_generator,
-};
-
-int ast_playtones_start(struct ast_channel *chan, int vol, const char *playlst, int interruptible)
-{
- char *s, *data = ast_strdupa(playlst); /* cute */
- struct playtones_def d = { vol, -1, 0, 1, NULL};
- char *stringp;
- char *separator;
-
- if (vol < 1)
- d.vol = 7219; /* Default to -8db */
-
- d.interruptible = interruptible;
-
- stringp=data;
- /* the stringp/data is not null here */
- /* check if the data is separated with '|' or with ',' by default */
- if (strchr(stringp,'|'))
- separator = "|";
- else
- separator = ",";
- s = strsep(&stringp,separator);
- while (s && *s) {
- int freq1, freq2, time, modulate=0, midinote=0;
-
- if (s[0]=='!')
- s++;
- else if (d.reppos == -1)
- d.reppos = d.nitems;
- if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) {
- /* f1+f2/time format */
- } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) {
- /* f1+f2 format */
- time = 0;
- } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) {
- /* f1*f2/time format */
- modulate = 1;
- } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) {
- /* f1*f2 format */
- time = 0;
- modulate = 1;
- } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) {
- /* f1/time format */
- freq2 = 0;
- } else if (sscanf(s, "%d", &freq1) == 1) {
- /* f1 format */
- freq2 = 0;
- time = 0;
- } else if (sscanf(s, "M%d+M%d/%d", &freq1, &freq2, &time) == 3) {
- /* Mf1+Mf2/time format */
- midinote = 1;
- } else if (sscanf(s, "M%d+M%d", &freq1, &freq2) == 2) {
- /* Mf1+Mf2 format */
- time = 0;
- midinote = 1;
- } else if (sscanf(s, "M%d*M%d/%d", &freq1, &freq2, &time) == 3) {
- /* Mf1*Mf2/time format */
- modulate = 1;
- midinote = 1;
- } else if (sscanf(s, "M%d*M%d", &freq1, &freq2) == 2) {
- /* Mf1*Mf2 format */
- time = 0;
- modulate = 1;
- midinote = 1;
- } else if (sscanf(s, "M%d/%d", &freq1, &time) == 2) {
- /* Mf1/time format */
- freq2 = -1;
- midinote = 1;
- } else if (sscanf(s, "M%d", &freq1) == 1) {
- /* Mf1 format */
- freq2 = -1;
- time = 0;
- midinote = 1;
- } else {
- ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst);
- return -1;
- }
-
- if (midinote) {
- /* midi notes must be between 0 and 127 */
- if ((freq1 >= 0) && (freq1 <= 127))
- freq1 = midi_tohz[freq1];
- else
- freq1 = 0;
-
- if ((freq2 >= 0) && (freq2 <= 127))
- freq2 = midi_tohz[freq2];
- else
- freq2 = 0;
- }
-
- if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) {
- return -1;
- }
- d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0;
- d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol;
- d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol;
-
- d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0;
- d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol;
- d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol;
- d.items[d.nitems].duration = time;
- d.items[d.nitems].modulate = modulate;
- d.nitems++;
-
- s = strsep(&stringp,separator);
- }
-
- if (ast_activate_generator(chan, &playtones, &d)) {
- free(d.items);
- return -1;
- }
- return 0;
-}
-
-void ast_playtones_stop(struct ast_channel *chan)
-{
- ast_deactivate_generator(chan);
-}
-
-/*--------------------------------------------*/
-
-static struct tone_zone *tone_zones;
-static struct tone_zone *current_tonezone;
-
-/* Protect the tone_zones list (highly unlikely that two things would change
- * it at the same time, but still! */
-AST_MUTEX_DEFINE_STATIC(tzlock);
-
-struct tone_zone *ast_walk_indications(const struct tone_zone *cur)
-{
- struct tone_zone *tz;
-
- if (cur == NULL)
- return tone_zones;
- ast_mutex_lock(&tzlock);
- for (tz = tone_zones; tz; tz = tz->next)
- if (tz == cur)
- break;
- if (tz)
- tz = tz->next;
- ast_mutex_unlock(&tzlock);
- return tz;
-}
-
-/* Set global indication country */
-int ast_set_indication_country(const char *country)
-{
- if (country) {
- struct tone_zone *z = ast_get_indication_zone(country);
- if (z) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n",country);
- current_tonezone = z;
- return 0;
- }
- }
- return 1; /* not found */
-}
-
-/* locate tone_zone, given the country. if country == NULL, use the default country */
-struct tone_zone *ast_get_indication_zone(const char *country)
-{
- struct tone_zone *tz;
- int alias_loop = 0;
-
- /* we need some tonezone, pick the first */
- if (country == NULL && current_tonezone)
- return current_tonezone; /* default country? */
- if (country == NULL && tone_zones)
- return tone_zones; /* any country? */
- if (country == NULL)
- return 0; /* not a single country insight */
-
- ast_mutex_lock(&tzlock);
- do {
- for (tz=tone_zones; tz; tz=tz->next) {
- if (strcasecmp(country,tz->country)==0) {
- /* tone_zone found */
- if (tz->alias && tz->alias[0]) {
- country = tz->alias;
- break;
- }
- ast_mutex_unlock(&tzlock);
- return tz;
- }
- }
- } while (++alias_loop<20 && tz);
- ast_mutex_unlock(&tzlock);
- if (alias_loop==20)
- ast_log(LOG_NOTICE,"Alias loop for '%s' forcefull broken\n",country);
- /* nothing found, sorry */
- return 0;
-}
-
-/* locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone */
-struct tone_zone_sound *ast_get_indication_tone(const struct tone_zone *zone, const char *indication)
-{
- struct tone_zone_sound *ts;
-
- /* we need some tonezone, pick the first */
- if (zone == NULL && current_tonezone)
- zone = current_tonezone; /* default country? */
- if (zone == NULL && tone_zones)
- zone = tone_zones; /* any country? */
- if (zone == NULL)
- return 0; /* not a single country insight */
-
- ast_mutex_lock(&tzlock);
- for (ts=zone->tones; ts; ts=ts->next) {
- if (strcasecmp(indication,ts->name)==0) {
- /* found indication! */
- ast_mutex_unlock(&tzlock);
- return ts;
- }
- }
- /* nothing found, sorry */
- ast_mutex_unlock(&tzlock);
- return 0;
-}
-
-/* helper function to delete a tone_zone in its entirety */
-static inline void free_zone(struct tone_zone* zone)
-{
- while (zone->tones) {
- struct tone_zone_sound *tmp = zone->tones->next;
- free((void*)zone->tones->name);
- free((void*)zone->tones->data);
- free(zone->tones);
- zone->tones = tmp;
- }
- if (zone->ringcadence)
- free(zone->ringcadence);
- free(zone);
-}
-
-/*--------------------------------------------*/
-
-/* add a new country, if country exists, it will be replaced. */
-int ast_register_indication_country(struct tone_zone *zone)
-{
- struct tone_zone *tz,*pz;
-
- ast_mutex_lock(&tzlock);
- for (pz=NULL,tz=tone_zones; tz; pz=tz,tz=tz->next) {
- if (strcasecmp(zone->country,tz->country)==0) {
- /* tone_zone already there, replace */
- zone->next = tz->next;
- if (pz)
- pz->next = zone;
- else
- tone_zones = zone;
- /* if we are replacing the default zone, re-point it */
- if (tz == current_tonezone)
- current_tonezone = zone;
- /* now free the previous zone */
- free_zone(tz);
- ast_mutex_unlock(&tzlock);
- return 0;
- }
- }
- /* country not there, add */
- zone->next = NULL;
- if (pz)
- pz->next = zone;
- else
- tone_zones = zone;
- ast_mutex_unlock(&tzlock);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n",zone->country);
- return 0;
-}
-
-/* remove an existing country and all its indications, country must exist.
- * Also, all countries which are an alias for the specified country are removed. */
-int ast_unregister_indication_country(const char *country)
-{
- struct tone_zone *tz, *pz = NULL, *tmp;
- int res = -1;
-
- ast_mutex_lock(&tzlock);
- tz = tone_zones;
- while (tz) {
- if (country==NULL ||
- (strcasecmp(country, tz->country)==0 ||
- strcasecmp(country, tz->alias)==0)) {
- /* tone_zone found, remove */
- tmp = tz->next;
- if (pz)
- pz->next = tmp;
- else
- tone_zones = tmp;
- /* if we are unregistering the default country, w'll notice */
- if (tz == current_tonezone) {
- ast_log(LOG_NOTICE,"Removed default indication country '%s'\n",tz->country);
- current_tonezone = NULL;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n",tz->country);
- free_zone(tz);
- if (tone_zones == tz)
- tone_zones = tmp;
- tz = tmp;
- res = 0;
- }
- else {
- /* next zone please */
- pz = tz;
- tz = tz->next;
- }
- }
- ast_mutex_unlock(&tzlock);
- return res;
-}
-
-/* add a new indication to a tone_zone. tone_zone must exist. if the indication already
- * exists, it will be replaced. */
-int ast_register_indication(struct tone_zone *zone, const char *indication, const char *tonelist)
-{
- struct tone_zone_sound *ts,*ps;
-
- /* is it an alias? stop */
- if (zone->alias[0])
- return -1;
-
- ast_mutex_lock(&tzlock);
- for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
- if (strcasecmp(indication,ts->name)==0) {
- /* indication already there, replace */
- free((void*)ts->name);
- free((void*)ts->data);
- break;
- }
- }
- if (!ts) {
- /* not there, we have to add */
- if (!(ts = ast_malloc(sizeof(*ts)))) {
- ast_mutex_unlock(&tzlock);
- return -2;
- }
- ts->next = NULL;
- }
- if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
- ast_mutex_unlock(&tzlock);
- return -2;
- }
- if (ps)
- ps->next = ts;
- else
- zone->tones = ts;
- ast_mutex_unlock(&tzlock);
- return 0;
-}
-
-/* remove an existing country's indication. Both country and indication must exist */
-int ast_unregister_indication(struct tone_zone *zone, const char *indication)
-{
- struct tone_zone_sound *ts,*ps = NULL, *tmp;
- int res = -1;
-
- /* is it an alias? stop */
- if (zone->alias[0])
- return -1;
-
- ast_mutex_lock(&tzlock);
- ts = zone->tones;
- while (ts) {
- if (strcasecmp(indication,ts->name)==0) {
- /* indication found */
- tmp = ts->next;
- if (ps)
- ps->next = tmp;
- else
- zone->tones = tmp;
- free((void*)ts->name);
- free((void*)ts->data);
- free(ts);
- ts = tmp;
- res = 0;
- }
- else {
- /* next zone please */
- ps = ts;
- ts = ts->next;
- }
- }
- /* indication not found, goodbye */
- ast_mutex_unlock(&tzlock);
- return res;
-}
diff --git a/1.4/main/io.c b/1.4/main/io.c
deleted file mode 100644
index ced692180..000000000
--- a/1.4/main/io.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief I/O Managment (Derived from Cheops-NG)
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <termios.h>
-#include <string.h>
-#include <sys/ioctl.h>
-
-#include "asterisk/io.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-
-#ifdef DEBUG_IO
-#define DEBUG DEBUG_M
-#else
-#define DEBUG(a)
-#endif
-
-/*
- * Kept for each file descriptor
- */
-struct io_rec {
- ast_io_cb callback; /* What is to be called */
- void *data; /* Data to be passed */
- int *id; /* ID number */
-};
-
-/* These two arrays are keyed with
- the same index. it's too bad that
- pollfd doesn't have a callback field
- or something like that. They grow as
- needed, by GROW_SHRINK_SIZE structures
- at once */
-
-#define GROW_SHRINK_SIZE 512
-
-/* Global variables are now in a struct in order to be
- made threadsafe */
-struct io_context {
- /* Poll structure */
- struct pollfd *fds;
- /* Associated I/O records */
- struct io_rec *ior;
- /* First available fd */
- unsigned int fdcnt;
- /* Maximum available fd */
- unsigned int maxfdcnt;
- /* Currently used io callback */
- int current_ioc;
- /* Whether something has been deleted */
- int needshrink;
-};
-
-struct io_context *io_context_create(void)
-{
- /* Create an I/O context */
- struct io_context *tmp;
- if ((tmp = ast_malloc(sizeof(*tmp)))) {
- tmp->needshrink = 0;
- tmp->fdcnt = 0;
- tmp->maxfdcnt = GROW_SHRINK_SIZE/2;
- tmp->current_ioc = -1;
- if (!(tmp->fds = ast_calloc(1, (GROW_SHRINK_SIZE / 2) * sizeof(*tmp->fds)))) {
- free(tmp);
- tmp = NULL;
- } else {
- if (!(tmp->ior = ast_calloc(1, (GROW_SHRINK_SIZE / 2) * sizeof(*tmp->ior)))) {
- free(tmp->fds);
- free(tmp);
- tmp = NULL;
- }
- }
- }
- return tmp;
-}
-
-void io_context_destroy(struct io_context *ioc)
-{
- /* Free associated memory with an I/O context */
- if (ioc->fds)
- free(ioc->fds);
- if (ioc->ior)
- free(ioc->ior);
- free(ioc);
-}
-
-static int io_grow(struct io_context *ioc)
-{
- /*
- * Grow the size of our arrays. Return 0 on success or
- * -1 on failure
- */
- void *tmp;
- DEBUG(ast_log(LOG_DEBUG, "io_grow()\n"));
- ioc->maxfdcnt += GROW_SHRINK_SIZE;
- if ((tmp = ast_realloc(ioc->ior, (ioc->maxfdcnt + 1) * sizeof(*ioc->ior)))) {
- ioc->ior = tmp;
- if ((tmp = ast_realloc(ioc->fds, (ioc->maxfdcnt + 1) * sizeof(*ioc->fds)))) {
- ioc->fds = tmp;
- } else {
- /*
- * Failed to allocate enough memory for the pollfd. Not
- * really any need to shrink back the iorec's as we'll
- * probably want to grow them again soon when more memory
- * is available, and then they'll already be the right size
- */
- ioc->maxfdcnt -= GROW_SHRINK_SIZE;
- return -1;
- }
- } else {
- /*
- * Memory allocation failure. We return to the old size, and
- * return a failure
- */
- ioc->maxfdcnt -= GROW_SHRINK_SIZE;
- return -1;
- }
- return 0;
-}
-
-int *ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
-{
- /*
- * Add a new I/O entry for this file descriptor
- * with the given event mask, to call callback with
- * data as an argument. Returns NULL on failure.
- */
- int *ret;
- DEBUG(ast_log(LOG_DEBUG, "ast_io_add()\n"));
- if (ioc->fdcnt >= ioc->maxfdcnt) {
- /*
- * We don't have enough space for this entry. We need to
- * reallocate maxfdcnt poll fd's and io_rec's, or back out now.
- */
- if (io_grow(ioc))
- return NULL;
- }
-
- /*
- * At this point, we've got sufficiently large arrays going
- * and we can make an entry for it in the pollfd and io_r
- * structures.
- */
- ioc->fds[ioc->fdcnt].fd = fd;
- ioc->fds[ioc->fdcnt].events = events;
- ioc->fds[ioc->fdcnt].revents = 0;
- ioc->ior[ioc->fdcnt].callback = callback;
- ioc->ior[ioc->fdcnt].data = data;
- if (!(ioc->ior[ioc->fdcnt].id = ast_malloc(sizeof(*ioc->ior[ioc->fdcnt].id)))) {
- /* Bonk if we couldn't allocate an int */
- return NULL;
- }
- *(ioc->ior[ioc->fdcnt].id) = ioc->fdcnt;
- ret = ioc->ior[ioc->fdcnt].id;
- ioc->fdcnt++;
- return ret;
-}
-
-int *ast_io_change(struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data)
-{
- if (*id < ioc->fdcnt) {
- if (fd > -1)
- ioc->fds[*id].fd = fd;
- if (callback)
- ioc->ior[*id].callback = callback;
- if (events)
- ioc->fds[*id].events = events;
- if (data)
- ioc->ior[*id].data = data;
- return id;
- }
- return NULL;
-}
-
-static int io_shrink(struct io_context *ioc)
-{
- int getfrom;
- int putto = 0;
- /*
- * Bring the fields from the very last entry to cover over
- * the entry we are removing, then decrease the size of the
- * arrays by one.
- */
- for (getfrom = 0; getfrom < ioc->fdcnt; getfrom++) {
- if (ioc->ior[getfrom].id) {
- /* In use, save it */
- if (getfrom != putto) {
- ioc->fds[putto] = ioc->fds[getfrom];
- ioc->ior[putto] = ioc->ior[getfrom];
- *(ioc->ior[putto].id) = putto;
- }
- putto++;
- }
- }
- ioc->fdcnt = putto;
- ioc->needshrink = 0;
- /* FIXME: We should free some memory if we have lots of unused
- io structs */
- return 0;
-}
-
-int ast_io_remove(struct io_context *ioc, int *_id)
-{
- int x;
- if (!_id) {
- ast_log(LOG_WARNING, "Asked to remove NULL?\n");
- return -1;
- }
- for (x = 0; x < ioc->fdcnt; x++) {
- if (ioc->ior[x].id == _id) {
- /* Free the int immediately and set to NULL so we know it's unused now */
- free(ioc->ior[x].id);
- ioc->ior[x].id = NULL;
- ioc->fds[x].events = 0;
- ioc->fds[x].revents = 0;
- ioc->needshrink = 1;
- if (ioc->current_ioc == -1)
- io_shrink(ioc);
- return 0;
- }
- }
-
- ast_log(LOG_NOTICE, "Unable to remove unknown id %p\n", _id);
- return -1;
-}
-
-int ast_io_wait(struct io_context *ioc, int howlong)
-{
- /*
- * Make the poll call, and call
- * the callbacks for anything that needs
- * to be handled
- */
- int res;
- int x;
- int origcnt;
- DEBUG(ast_log(LOG_DEBUG, "ast_io_wait()\n"));
- res = poll(ioc->fds, ioc->fdcnt, howlong);
- if (res > 0) {
- /*
- * At least one event
- */
- origcnt = ioc->fdcnt;
- for(x = 0; x < origcnt; x++) {
- /* Yes, it is possible for an entry to be deleted and still have an
- event waiting if it occurs after the original calling id */
- if (ioc->fds[x].revents && ioc->ior[x].id) {
- /* There's an event waiting */
- ioc->current_ioc = *ioc->ior[x].id;
- if (ioc->ior[x].callback) {
- if (!ioc->ior[x].callback(ioc->ior[x].id, ioc->fds[x].fd, ioc->fds[x].revents, ioc->ior[x].data)) {
- /* Time to delete them since they returned a 0 */
- ast_io_remove(ioc, ioc->ior[x].id);
- }
- }
- ioc->current_ioc = -1;
- }
- }
- if (ioc->needshrink)
- io_shrink(ioc);
- }
- return res;
-}
-
-void ast_io_dump(struct io_context *ioc)
-{
- /*
- * Print some debugging information via
- * the logger interface
- */
- int x;
- ast_log(LOG_DEBUG, "Asterisk IO Dump: %d entries, %d max entries\n", ioc->fdcnt, ioc->maxfdcnt);
- ast_log(LOG_DEBUG, "================================================\n");
- ast_log(LOG_DEBUG, "| ID FD Callback Data Events |\n");
- ast_log(LOG_DEBUG, "+------+------+-----------+-----------+--------+\n");
- for (x = 0; x < ioc->fdcnt; x++) {
- ast_log(LOG_DEBUG, "| %.4d | %.4d | %p | %p | %.6x |\n",
- *ioc->ior[x].id,
- ioc->fds[x].fd,
- ioc->ior[x].callback,
- ioc->ior[x].data,
- ioc->fds[x].events);
- }
- ast_log(LOG_DEBUG, "================================================\n");
-}
-
-/* Unrelated I/O functions */
-
-int ast_hide_password(int fd)
-{
- struct termios tios;
- int res;
- int old;
- if (!isatty(fd))
- return -1;
- res = tcgetattr(fd, &tios);
- if (res < 0)
- return -1;
- old = tios.c_lflag & (ECHO | ECHONL);
- tios.c_lflag &= ~ECHO;
- tios.c_lflag |= ECHONL;
- res = tcsetattr(fd, TCSAFLUSH, &tios);
- if (res < 0)
- return -1;
- return old;
-}
-
-int ast_restore_tty(int fd, int oldstate)
-{
- int res;
- struct termios tios;
- if (oldstate < 0)
- return 0;
- res = tcgetattr(fd, &tios);
- if (res < 0)
- return -1;
- tios.c_lflag &= ~(ECHO | ECHONL);
- tios.c_lflag |= oldstate;
- res = tcsetattr(fd, TCSAFLUSH, &tios);
- if (res < 0)
- return -1;
- return 0;
-}
-
-int ast_get_termcols(int fd)
-{
- struct winsize win;
- int cols = 0;
-
- if (!isatty(fd))
- return -1;
-
- if ( ioctl(fd, TIOCGWINSZ, &win) != -1 ) {
- if ( !cols && win.ws_col > 0 )
- cols = (int) win.ws_col;
- } else {
- /* assume 80 characters if the ioctl fails for some reason */
- cols = 80;
- }
-
- return cols;
-}
-
diff --git a/1.4/main/jitterbuf.c b/1.4/main/jitterbuf.c
deleted file mode 100644
index 2b081704a..000000000
--- a/1.4/main/jitterbuf.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004-2005, Horizon Wimba, Inc.
- *
- * Contributors:
- * Steve Kann <stevek@stevek.com>
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief jitterbuf: an application-independent jitterbuffer
- * \author Steve Kann <stevek@stevek.com>
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "jitterbuf.h"
-#include "asterisk/utils.h"
-
-/*! define these here, just for ancient compiler systems */
-#define JB_LONGMAX 2147483647L
-#define JB_LONGMIN (-JB_LONGMAX - 1L)
-
-#define jb_warn(...) (warnf ? warnf(__VA_ARGS__) : (void)0)
-#define jb_err(...) (errf ? errf(__VA_ARGS__) : (void)0)
-#define jb_dbg(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
-
-#ifdef DEEP_DEBUG
-#define jb_dbg2(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
-#else
-#define jb_dbg2(...) ((void)0)
-#endif
-
-static jb_output_function_t warnf, errf, dbgf;
-
-void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
-{
- errf = err;
- warnf = warn;
- dbgf = dbg;
-}
-
-static void increment_losspct(jitterbuf *jb)
-{
- jb->info.losspct = (100000 + 499 * jb->info.losspct)/500;
-}
-
-static void decrement_losspct(jitterbuf *jb)
-{
- jb->info.losspct = (499 * jb->info.losspct)/500;
-}
-
-void jb_reset(jitterbuf *jb)
-{
- /* only save settings */
- jb_conf s = jb->info.conf;
- memset(jb, 0, sizeof(*jb));
- jb->info.conf = s;
-
- /* initialize length */
- jb->info.current = jb->info.target = JB_TARGET_EXTRA;
- jb->info.silence_begin_ts = -1;
-}
-
-jitterbuf * jb_new()
-{
- jitterbuf *jb;
-
- if (!(jb = ast_malloc(sizeof(*jb))))
- return NULL;
-
- jb_reset(jb);
-
- jb_dbg2("jb_new() = %x\n", jb);
- return jb;
-}
-
-void jb_destroy(jitterbuf *jb)
-{
- jb_frame *frame;
- jb_dbg2("jb_destroy(%x)\n", jb);
-
- /* free all the frames on the "free list" */
- frame = jb->free;
- while (frame != NULL) {
- jb_frame *next = frame->next;
- free(frame);
- frame = next;
- }
-
- /* free ourselves! */
- free(jb);
-}
-
-
-
-#if 0
-static int longcmp(const void *a, const void *b)
-{
- return *(long *)a - *(long *)b;
-}
-#endif
-
-/*! \brief simple history manipulation
- \note maybe later we can make the history buckets variable size, or something? */
-/* drop parameter determines whether we will drop outliers to minimize
- * delay */
-static int history_put(jitterbuf *jb, long ts, long now, long ms)
-{
- long delay = now - (ts - jb->info.resync_offset);
- long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
- long kicked;
-
- /* don't add special/negative times to history */
- if (ts <= 0)
- return 0;
-
- /* check for drastic change in delay */
- if (jb->info.conf.resync_threshold != -1) {
- if (abs(delay - jb->info.last_delay) > threshold) {
- jb->info.cnt_delay_discont++;
- if (jb->info.cnt_delay_discont > 3) {
- /* resync the jitterbuffer */
- jb->info.cnt_delay_discont = 0;
- jb->hist_ptr = 0;
- jb->hist_maxbuf_valid = 0;
-
- jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
- jb->info.resync_offset = ts - now;
- jb->info.last_delay = delay = 0; /* after resync, frame is right on time */
- } else {
- return -1;
- }
- } else {
- jb->info.last_delay = delay;
- jb->info.cnt_delay_discont = 0;
- }
- }
-
- kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];
-
- jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;
-
- /* optimization; the max/min buffers don't need to be recalculated, if this packet's
- * entry doesn't change them. This happens if this packet is not involved, _and_ any packet
- * that got kicked out of the history is also not involved
- * We do a number of comparisons, but it's probably still worthwhile, because it will usually
- * succeed, and should be a lot faster than going through all 500 packets in history */
- if (!jb->hist_maxbuf_valid)
- return 0;
-
- /* don't do this until we've filled history
- * (reduces some edge cases below) */
- if (jb->hist_ptr < JB_HISTORY_SZ)
- goto invalidate;
-
- /* if the new delay would go into min */
- if (delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
- goto invalidate;
-
- /* or max.. */
- if (delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
- goto invalidate;
-
- /* or the kicked delay would be in min */
- if (kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
- goto invalidate;
-
- if (kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
- goto invalidate;
-
- /* if we got here, we don't need to invalidate, 'cause this delay didn't
- * affect things */
- return 0;
- /* end optimization */
-
-
-invalidate:
- jb->hist_maxbuf_valid = 0;
- return 0;
-}
-
-static void history_calc_maxbuf(jitterbuf *jb)
-{
- int i,j;
-
- if (jb->hist_ptr == 0)
- return;
-
-
- /* initialize maxbuf/minbuf to the latest value */
- for (i=0;i<JB_HISTORY_MAXBUF_SZ;i++) {
-/*
- * jb->hist_maxbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
- * jb->hist_minbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
- */
- jb->hist_maxbuf[i] = JB_LONGMIN;
- jb->hist_minbuf[i] = JB_LONGMAX;
- }
-
- /* use insertion sort to populate maxbuf */
- /* we want it to be the top "n" values, in order */
-
- /* start at the beginning, or JB_HISTORY_SZ frames ago */
- i = (jb->hist_ptr > JB_HISTORY_SZ) ? (jb->hist_ptr - JB_HISTORY_SZ) : 0;
-
- for (;i<jb->hist_ptr;i++) {
- long toins = jb->history[i % JB_HISTORY_SZ];
-
- /* if the maxbuf should get this */
- if (toins > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1]) {
-
- /* insertion-sort it into the maxbuf */
- for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
- /* found where it fits */
- if (toins > jb->hist_maxbuf[j]) {
- /* move over */
- memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
- /* insert */
- jb->hist_maxbuf[j] = toins;
-
- break;
- }
- }
- }
-
- /* if the minbuf should get this */
- if (toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1]) {
-
- /* insertion-sort it into the maxbuf */
- for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
- /* found where it fits */
- if (toins < jb->hist_minbuf[j]) {
- /* move over */
- memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
- /* insert */
- jb->hist_minbuf[j] = toins;
-
- break;
- }
- }
- }
-
- if (0) {
- int k;
- fprintf(stderr, "toins = %ld\n", toins);
- fprintf(stderr, "maxbuf =");
- for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
- fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
- fprintf(stderr, "\nminbuf =");
- for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
- fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
- fprintf(stderr, "\n");
- }
- }
-
- jb->hist_maxbuf_valid = 1;
-}
-
-static void history_get(jitterbuf *jb)
-{
- long max, min, jitter;
- int index;
- int count;
-
- if (!jb->hist_maxbuf_valid)
- history_calc_maxbuf(jb);
-
- /* count is how many items in history we're examining */
- count = (jb->hist_ptr < JB_HISTORY_SZ) ? jb->hist_ptr : JB_HISTORY_SZ;
-
- /* index is the "n"ths highest/lowest that we'll look for */
- index = count * JB_HISTORY_DROPPCT / 100;
-
- /* sanity checks for index */
- if (index > (JB_HISTORY_MAXBUF_SZ - 1))
- index = JB_HISTORY_MAXBUF_SZ - 1;
-
-
- if (index < 0) {
- jb->info.min = 0;
- jb->info.jitter = 0;
- return;
- }
-
- max = jb->hist_maxbuf[index];
- min = jb->hist_minbuf[index];
-
- jitter = max - min;
-
- /* these debug stmts compare the difference between looking at the absolute jitter, and the
- * values we get by throwing away the outliers */
- /*
- fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", index, min, max, jitter);
- fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", 0, jb->hist_minbuf[0], jb->hist_maxbuf[0], jb->hist_maxbuf[0]-jb->hist_minbuf[0]);
- */
-
- jb->info.min = min;
- jb->info.jitter = jitter;
-}
-
-/* returns 1 if frame was inserted into head of queue, 0 otherwise */
-static int queue_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts)
-{
- jb_frame *frame;
- jb_frame *p;
- int head = 0;
- long resync_ts = ts - jb->info.resync_offset;
-
- if ((frame = jb->free)) {
- jb->free = frame->next;
- } else if (!(frame = ast_malloc(sizeof(*frame)))) {
- jb_err("cannot allocate frame\n");
- return 0;
- }
-
- jb->info.frames_cur++;
-
- frame->data = data;
- frame->ts = resync_ts;
- frame->ms = ms;
- frame->type = type;
-
- /*
- * frames are a circular list, jb-frames points to to the lowest ts,
- * jb->frames->prev points to the highest ts
- */
-
- if (!jb->frames) { /* queue is empty */
- jb->frames = frame;
- frame->next = frame;
- frame->prev = frame;
- head = 1;
- } else if (resync_ts < jb->frames->ts) {
- frame->next = jb->frames;
- frame->prev = jb->frames->prev;
-
- frame->next->prev = frame;
- frame->prev->next = frame;
-
- /* frame is out of order */
- jb->info.frames_ooo++;
-
- jb->frames = frame;
- head = 1;
- } else {
- p = jb->frames;
-
- /* frame is out of order */
- if (resync_ts < p->prev->ts) jb->info.frames_ooo++;
-
- while (resync_ts < p->prev->ts && p->prev != jb->frames)
- p = p->prev;
-
- frame->next = p;
- frame->prev = p->prev;
-
- frame->next->prev = frame;
- frame->prev->next = frame;
- }
- return head;
-}
-
-static long queue_next(jitterbuf *jb)
-{
- if (jb->frames)
- return jb->frames->ts;
- else
- return -1;
-}
-
-static long queue_last(jitterbuf *jb)
-{
- if (jb->frames)
- return jb->frames->prev->ts;
- else
- return -1;
-}
-
-static jb_frame *_queue_get(jitterbuf *jb, long ts, int all)
-{
- jb_frame *frame;
- frame = jb->frames;
-
- if (!frame)
- return NULL;
-
- /*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
-
- if (all || ts >= frame->ts) {
- /* remove this frame */
- frame->prev->next = frame->next;
- frame->next->prev = frame->prev;
-
- if (frame->next == frame)
- jb->frames = NULL;
- else
- jb->frames = frame->next;
-
-
- /* insert onto "free" single-linked list */
- frame->next = jb->free;
- jb->free = frame;
-
- jb->info.frames_cur--;
-
- /* we return the frame pointer, even though it's on free list,
- * but caller must copy data */
- return frame;
- }
-
- return NULL;
-}
-
-static jb_frame *queue_get(jitterbuf *jb, long ts)
-{
- return _queue_get(jb,ts,0);
-}
-
-static jb_frame *queue_getall(jitterbuf *jb)
-{
- return _queue_get(jb,0,1);
-}
-
-#if 0
-/* some diagnostics */
-static void jb_dbginfo(jitterbuf *jb)
-{
- if (dbgf == NULL)
- return;
-
- jb_dbg("\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n",
- jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur);
-
- jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
- jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min,
- jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8);
- if (jb->info.frames_in > 0)
- jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
- jb->info.frames_lost * 100/(jb->info.frames_in + jb->info.frames_lost),
- jb->info.frames_late * 100/jb->info.frames_in);
- jb_dbg("jb info: queue %d -> %d. last_ts %d (queue len: %d) last_ms %d\n",
- queue_next(jb),
- queue_last(jb),
- jb->info.next_voice_ts,
- queue_last(jb) - queue_next(jb),
- jb->info.last_voice_ms);
-}
-#endif
-
-#ifdef DEEP_DEBUG
-static void jb_chkqueue(jitterbuf *jb)
-{
- int i=0;
- jb_frame *p = jb->frames;
-
- if (!p) {
- return;
- }
-
- do {
- if (p->next == NULL) {
- jb_err("Queue is BROKEN at item [%d]", i);
- }
- i++;
- p=p->next;
- } while (p->next != jb->frames);
-}
-
-static void jb_dbgqueue(jitterbuf *jb)
-{
- int i=0;
- jb_frame *p = jb->frames;
-
- jb_dbg("queue: ");
-
- if (!p) {
- jb_dbg("EMPTY\n");
- return;
- }
-
- do {
- jb_dbg("[%d]=%ld ", i++, p->ts);
- p=p->next;
- } while (p->next != jb->frames);
-
- jb_dbg("\n");
-}
-#endif
-
-enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
-{
- long numts;
-
- jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
-
- jb->info.frames_in++;
-
- if (jb->frames && jb->dropem)
- return JB_DROP;
- jb->dropem = 0;
-
- if (type == JB_TYPE_VOICE) {
- /* presently, I'm only adding VOICE frames to history and drift calculations; mostly because with the
- * IAX integrations, I'm sending retransmitted control frames with their awkward timestamps through */
- if (history_put(jb,ts,now,ms))
- return JB_DROP;
- }
- numts = 0;
- if (jb->frames)
- numts = jb->frames->prev->ts - jb->frames->ts;
- if (numts >= jb->info.conf.max_jitterbuf) {
- ast_log(LOG_DEBUG, "Attempting to exceed Jitterbuf max %ld timeslots\n",
- jb->info.conf.max_jitterbuf);
- jb->dropem = 1;
- return JB_DROP;
- }
- /* if put into head of queue, caller needs to reschedule */
- if (queue_put(jb,data,type,ms,ts)) {
- return JB_SCHED;
- }
- return JB_OK;
-}
-
-
-static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
-{
- jb_frame *frame;
- long diff;
- static int dbg_cnt = 0;
-
- /*if ((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */
- /* get jitter info */
- history_get(jb);
-
- if (dbg_cnt && dbg_cnt % 50 == 0) {
- jb_dbg("\n");
- }
- dbg_cnt++;
-
- /* target */
- jb->info.target = jb->info.jitter + jb->info.min + JB_TARGET_EXTRA;
-
- /* if a hard clamp was requested, use it */
- if ((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) {
- jb_dbg("clamping target from %d to %d\n", (jb->info.target - jb->info.min), jb->info.conf.max_jitterbuf);
- jb->info.target = jb->info.min + jb->info.conf.max_jitterbuf;
- }
-
- diff = jb->info.target - jb->info.current;
-
- /* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff, */
- /* jb->info.last_voice_ms, jb->info.last_adjustment, now); */
-
- /* let's work on non-silent case first */
- if (!jb->info.silence_begin_ts) {
- /* we want to grow */
- if ((diff > 0) &&
- /* we haven't grown in the delay length */
- (((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) ||
- /* we need to grow more than the "length" we have left */
- (diff > queue_last(jb) - queue_next(jb)) ) ) {
- /* grow by interp frame length */
- jb->info.current += interpl;
- jb->info.next_voice_ts += interpl;
- jb->info.last_voice_ms = interpl;
- jb->info.last_adjustment = now;
- jb->info.cnt_contig_interp++;
- if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
- jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
- }
- jb_dbg("G");
- return JB_INTERP;
- }
-
- frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current);
-
- /* not a voice frame; just return it. */
- if (frame && frame->type != JB_TYPE_VOICE) {
- if (frame->type == JB_TYPE_SILENCE) {
- jb->info.silence_begin_ts = frame->ts;
- jb->info.cnt_contig_interp = 0;
- }
-
- *frameout = *frame;
- jb->info.frames_out++;
- jb_dbg("o");
- return JB_OK;
- }
-
-
- /* voice frame is later than expected */
- if (frame && frame->ts + jb->info.current < jb->info.next_voice_ts) {
- if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) {
- /* either we interpolated past this frame in the last jb_get */
- /* or the frame is still in order, but came a little too quick */
- *frameout = *frame;
- /* reset expectation for next frame */
- jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
- jb->info.frames_out++;
- decrement_losspct(jb);
- jb->info.cnt_contig_interp = 0;
- jb_dbg("v");
- return JB_OK;
- } else {
- /* voice frame is late */
- *frameout = *frame;
- jb->info.frames_out++;
- decrement_losspct(jb);
- jb->info.frames_late++;
- jb->info.frames_lost--;
- jb_dbg("l");
- /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
- jb_warninfo(jb); */
- return JB_DROP;
- }
- }
-
- /* keep track of frame sizes, to allow for variable sized-frames */
- if (frame && frame->ms > 0) {
- jb->info.last_voice_ms = frame->ms;
- }
-
- /* we want to shrink; shrink at 1 frame / 500ms */
- /* unless we don't have a frame, then shrink 1 frame */
- /* every 80ms (though perhaps we can shrink even faster */
- /* in this case) */
- if (diff < -JB_TARGET_EXTRA &&
- ((!frame && jb->info.last_adjustment + 80 < now) ||
- (jb->info.last_adjustment + 500 < now))) {
-
- jb->info.last_adjustment = now;
- jb->info.cnt_contig_interp = 0;
-
- if (frame) {
- *frameout = *frame;
- /* shrink by frame size we're throwing out */
- jb->info.current -= frame->ms;
- jb->info.frames_out++;
- decrement_losspct(jb);
- jb->info.frames_dropped++;
- jb_dbg("s");
- return JB_DROP;
- } else {
- /* shrink by last_voice_ms */
- jb->info.current -= jb->info.last_voice_ms;
- jb->info.frames_lost++;
- increment_losspct(jb);
- jb_dbg("S");
- return JB_NOFRAME;
- }
- }
-
- /* lost frame */
- if (!frame) {
- /* this is a bit of a hack for now, but if we're close to
- * target, and we find a missing frame, it makes sense to
- * grow, because the frame might just be a bit late;
- * otherwise, we presently get into a pattern where we return
- * INTERP for the lost frame, then it shows up next, and we
- * throw it away because it's late */
- /* I've recently only been able to replicate this using
- * iaxclient talking to app_echo on asterisk. In this case,
- * my outgoing packets go through asterisk's (old)
- * jitterbuffer, and then might get an unusual increasing delay
- * there if it decides to grow?? */
- /* Update: that might have been a different bug, that has been fixed..
- * But, this still seemed like a good idea, except that it ended up making a single actual
- * lost frame get interpolated two or more times, when there was "room" to grow, so it might
- * be a bit of a bad idea overall */
- /*if (diff > -1 * jb->info.last_voice_ms) {
- jb->info.current += jb->info.last_voice_ms;
- jb->info.last_adjustment = now;
- jb_warn("g");
- return JB_INTERP;
- } */
- jb->info.frames_lost++;
- increment_losspct(jb);
- jb->info.next_voice_ts += interpl;
- jb->info.last_voice_ms = interpl;
- jb->info.cnt_contig_interp++;
- if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
- jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
- }
- jb_dbg("L");
- return JB_INTERP;
- }
-
- /* normal case; return the frame, increment stuff */
- *frameout = *frame;
- jb->info.next_voice_ts += frame->ms;
- jb->info.frames_out++;
- jb->info.cnt_contig_interp = 0;
- decrement_losspct(jb);
- jb_dbg("v");
- return JB_OK;
- } else {
- /* TODO: after we get the non-silent case down, we'll make the
- * silent case -- basically, we'll just grow and shrink faster
- * here, plus handle next_voice_ts a bit differently */
-
- /* to disable silent special case altogether, just uncomment this: */
- /* jb->info.silence_begin_ts = 0; */
-
- /* shrink interpl len every 10ms during silence */
- if (diff < -JB_TARGET_EXTRA &&
- jb->info.last_adjustment + 10 <= now) {
- jb->info.current -= interpl;
- jb->info.last_adjustment = now;
- }
-
- frame = queue_get(jb, now - jb->info.current);
- if (!frame) {
- return JB_NOFRAME;
- } else if (frame->type != JB_TYPE_VOICE) {
- /* normal case; in silent mode, got a non-voice frame */
- *frameout = *frame;
- jb->info.frames_out++;
- return JB_OK;
- }
- if (frame->ts < jb->info.silence_begin_ts) {
- /* voice frame is late */
- *frameout = *frame;
- jb->info.frames_out++;
- decrement_losspct(jb);
- jb->info.frames_late++;
- jb->info.frames_lost--;
- jb_dbg("l");
- /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
- jb_warninfo(jb); */
- return JB_DROP;
- } else {
- /* voice frame */
- /* try setting current to target right away here */
- jb->info.current = jb->info.target;
- jb->info.silence_begin_ts = 0;
- jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
- jb->info.last_voice_ms = frame->ms;
- jb->info.frames_out++;
- decrement_losspct(jb);
- *frameout = *frame;
- jb_dbg("V");
- return JB_OK;
- }
- }
-}
-
-long jb_next(jitterbuf *jb)
-{
- if (jb->info.silence_begin_ts) {
- if (jb->frames) {
- long next = queue_next(jb);
- history_get(jb);
- /* shrink during silence */
- if (jb->info.target - jb->info.current < -JB_TARGET_EXTRA)
- return jb->info.last_adjustment + 10;
- return next + jb->info.target;
- }
- else
- return JB_LONGMAX;
- } else {
- return jb->info.next_voice_ts;
- }
-}
-
-enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
-{
- enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
-#if 0
- static int lastts=0;
- int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
- jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
- if (thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
- lastts = thists;
-#endif
- if(ret == JB_INTERP)
- frameout->ms = jb->info.last_voice_ms;
-
- return ret;
-}
-
-enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
-{
- jb_frame *frame;
- frame = queue_getall(jb);
-
- if (!frame) {
- return JB_NOFRAME;
- }
-
- *frameout = *frame;
- return JB_OK;
-}
-
-
-enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
-{
-
- history_get(jb);
-
- *stats = jb->info;
-
- return JB_OK;
-}
-
-enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
-{
- /* take selected settings from the struct */
-
- jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
- jb->info.conf.resync_threshold = conf->resync_threshold;
- jb->info.conf.max_contig_interp = conf->max_contig_interp;
-
- return JB_OK;
-}
-
-
diff --git a/1.4/main/loader.c b/1.4/main/loader.c
deleted file mode 100644
index d423af234..000000000
--- a/1.4/main/loader.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * Kevin P. Fleming <kpfleming@digium.com>
- * Luigi Rizzo <rizzo@icir.org>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Module Loader
- * \author Mark Spencer <markster@digium.com>
- * \author Kevin P. Fleming <kpfleming@digium.com>
- * \author Luigi Rizzo <rizzo@icir.org>
- * - See ModMngMnt
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#include "asterisk/linkedlists.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/config.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/term.h"
-#include "asterisk/manager.h"
-#include "asterisk/cdr.h"
-#include "asterisk/enum.h"
-#include "asterisk/rtp.h"
-#include "asterisk/http.h"
-#include "asterisk/lock.h"
-
-#ifdef DLFCNCOMPAT
-#include "asterisk/dlfcn-compat.h"
-#else
-#include <dlfcn.h>
-#endif
-
-#include "asterisk/md5.h"
-#include "asterisk/utils.h"
-
-#ifndef RTLD_NOW
-#define RTLD_NOW 0
-#endif
-
-struct ast_module_user {
- struct ast_channel *chan;
- AST_LIST_ENTRY(ast_module_user) entry;
-};
-
-AST_LIST_HEAD(module_user_list, ast_module_user);
-
-static unsigned char expected_key[] =
-{ 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
- 0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
-
-static char buildopt_sum[33] = AST_BUILDOPT_SUM;
-
-static unsigned int embedding = 1; /* we always start out by registering embedded modules,
- since they are here before we dlopen() any
- */
-
-struct ast_module {
- const struct ast_module_info *info;
- void *lib; /* the shared lib, or NULL if embedded */
- int usecount; /* the number of 'users' currently in this module */
- struct module_user_list users; /* the list of users in the module */
- struct {
- unsigned int running:1;
- unsigned int declined:1;
- } flags;
- AST_LIST_ENTRY(ast_module) entry;
- char resource[0];
-};
-
-static AST_LIST_HEAD_STATIC(module_list, ast_module);
-
-struct loadupdate {
- int (*updater)(void);
- AST_LIST_ENTRY(loadupdate) entry;
-};
-
-static AST_LIST_HEAD_STATIC(updaters, loadupdate);
-
-AST_MUTEX_DEFINE_STATIC(reloadlock);
-
-/* when dynamic modules are being loaded, ast_module_register() will
- need to know what filename the module was loaded from while it
- is being registered
-*/
-struct ast_module *resource_being_loaded;
-
-/* XXX: should we check for duplicate resource names here? */
-
-void ast_module_register(const struct ast_module_info *info)
-{
- struct ast_module *mod;
-
- if (embedding) {
- if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
- return;
- strcpy(mod->resource, info->name);
- } else {
- mod = resource_being_loaded;
- }
-
- mod->info = info;
- AST_LIST_HEAD_INIT(&mod->users);
-
- /* during startup, before the loader has been initialized,
- there are no threads, so there is no need to take the lock
- on this list to manipulate it. it is also possible that it
- might be unsafe to use the list lock at that point... so
- let's avoid it altogether
- */
- if (!embedding)
- AST_LIST_LOCK(&module_list);
-
- /* it is paramount that the new entry be placed at the tail of
- the list, otherwise the code that uses dlopen() to load
- dynamic modules won't be able to find out if the module it
- just opened was registered or failed to load
- */
- AST_LIST_INSERT_TAIL(&module_list, mod, entry);
-
- if (!embedding)
- AST_LIST_UNLOCK(&module_list);
-
- /* give the module a copy of its own handle, for later use in registrations and the like */
- *((struct ast_module **) &(info->self)) = mod;
-}
-
-void ast_module_unregister(const struct ast_module_info *info)
-{
- struct ast_module *mod = NULL;
-
- /* it is assumed that the users list in the module structure
- will already be empty, or we cannot have gotten to this
- point
- */
- AST_LIST_LOCK(&module_list);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
- if (mod->info == info) {
- AST_LIST_REMOVE_CURRENT(&module_list, entry);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&module_list);
-
- if (mod) {
- AST_LIST_HEAD_DESTROY(&mod->users);
- free(mod);
- }
-}
-
-struct ast_module_user *__ast_module_user_add(struct ast_module *mod,
- struct ast_channel *chan)
-{
- struct ast_module_user *u = ast_calloc(1, sizeof(*u));
-
- if (!u)
- return NULL;
-
- u->chan = chan;
-
- AST_LIST_LOCK(&mod->users);
- AST_LIST_INSERT_HEAD(&mod->users, u, entry);
- AST_LIST_UNLOCK(&mod->users);
-
- ast_atomic_fetchadd_int(&mod->usecount, +1);
-
- ast_update_use_count();
-
- return u;
-}
-
-void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
-{
- AST_LIST_LOCK(&mod->users);
- AST_LIST_REMOVE(&mod->users, u, entry);
- AST_LIST_UNLOCK(&mod->users);
- ast_atomic_fetchadd_int(&mod->usecount, -1);
- free(u);
-
- ast_update_use_count();
-}
-
-void __ast_module_user_hangup_all(struct ast_module *mod)
-{
- struct ast_module_user *u;
-
- AST_LIST_LOCK(&mod->users);
- while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
- ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
- ast_atomic_fetchadd_int(&mod->usecount, -1);
- free(u);
- }
- AST_LIST_UNLOCK(&mod->users);
-
- ast_update_use_count();
-}
-
-/*! \note
- * In addition to modules, the reload command handles some extra keywords
- * which are listed here together with the corresponding handlers.
- * This table is also used by the command completion code.
- */
-static struct reload_classes {
- const char *name;
- int (*reload_fn)(void);
-} reload_classes[] = { /* list in alpha order, longest match first for cli completion */
- { "cdr", ast_cdr_engine_reload },
- { "dnsmgr", dnsmgr_reload },
- { "extconfig", read_config_maps },
- { "enum", ast_enum_reload },
- { "manager", reload_manager },
- { "rtp", ast_rtp_reload },
- { "http", ast_http_reload },
- { "logger", logger_reload },
- { NULL, NULL }
-};
-
-static int printdigest(const unsigned char *d)
-{
- int x, pos;
- char buf[256]; /* large enough so we don't have to worry */
-
- for (pos = 0, x = 0; x < 16; x++)
- pos += sprintf(buf + pos, " %02x", *d++);
-
- ast_log(LOG_DEBUG, "Unexpected signature:%s\n", buf);
-
- return 0;
-}
-
-static int key_matches(const unsigned char *key1, const unsigned char *key2)
-{
- int x;
-
- for (x = 0; x < 16; x++) {
- if (key1[x] != key2[x])
- return 0;
- }
-
- return 1;
-}
-
-static int verify_key(const unsigned char *key)
-{
- struct MD5Context c;
- unsigned char digest[16];
-
- MD5Init(&c);
- MD5Update(&c, key, strlen((char *)key));
- MD5Final(digest, &c);
-
- if (key_matches(expected_key, digest))
- return 0;
-
- printdigest(digest);
-
- return -1;
-}
-
-static int resource_name_match(const char *name1_in, const char *name2_in)
-{
- char *name1 = (char *) name1_in;
- char *name2 = (char *) name2_in;
-
- /* trim off any .so extensions */
- if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
- name1 = ast_strdupa(name1);
- name1[strlen(name1) - 3] = '\0';
- }
- if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
- name2 = ast_strdupa(name2);
- name2[strlen(name2) - 3] = '\0';
- }
-
- return strcasecmp(name1, name2);
-}
-
-static struct ast_module *find_resource(const char *resource, int do_lock)
-{
- struct ast_module *cur;
-
- if (do_lock)
- AST_LIST_LOCK(&module_list);
-
- AST_LIST_TRAVERSE(&module_list, cur, entry) {
- if (!resource_name_match(resource, cur->resource))
- break;
- }
-
- if (do_lock)
- AST_LIST_UNLOCK(&module_list);
-
- return cur;
-}
-
-#ifdef LOADABLE_MODULES
-static void unload_dynamic_module(struct ast_module *mod)
-{
- void *lib = mod->lib;
-
- /* WARNING: the structure pointed to by mod is going to
- disappear when this operation succeeds, so we can't
- dereference it */
-
- if (lib)
- while (!dlclose(lib));
-}
-
-static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
-{
- char fn[256];
- void *lib;
- struct ast_module *mod;
- char *resource = (char *) resource_in;
- unsigned int wants_global;
-
- if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
- resource = alloca(strlen(resource_in) + 3);
- strcpy(resource, resource_in);
- strcat(resource, ".so");
- }
-
- snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource);
-
- /* make a first load of the module in 'quiet' mode... don't try to resolve
- any symbols, and don't export any symbols. this will allow us to peek into
- the module's info block (if available) to see what flags it has set */
-
- if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
- return NULL;
-
- strcpy(resource_being_loaded->resource, resource);
-
- if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
- ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
- free(resource_being_loaded);
- return NULL;
- }
-
- /* the dlopen() succeeded, let's find out if the module
- registered itself */
- /* note that this will only work properly as long as
- ast_module_register() (which is called by the module's
- constructor) places the new module at the tail of the
- module_list
- */
- if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
- ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
- /* no, it did not, so close it and return */
- while (!dlclose(lib));
- /* note that the module's destructor will call ast_module_unregister(),
- which will free the structure we allocated in resource_being_loaded */
- return NULL;
- }
-
- wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
-
- /* if we are being asked only to load modules that provide global symbols,
- and this one does not, then close it and return */
- if (global_symbols_only && !wants_global) {
- while (!dlclose(lib));
- return NULL;
- }
-
- /* if the system supports RTLD_NOLOAD, we can just 'promote' the flags
- on the already-opened library to what we want... if not, we have to
- close it and start over
- */
-#if defined(HAVE_RTLD_NOLOAD) && !defined(__Darwin__)
- if (!dlopen(fn, RTLD_NOLOAD | (wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
- ast_log(LOG_WARNING, "Unable to promote flags on module '%s': %s\n", resource_in, dlerror());
- while (!dlclose(lib));
- free(resource_being_loaded);
- return NULL;
- }
-#else
- while (!dlclose(lib));
- resource_being_loaded = NULL;
-
- /* start the load process again */
-
- if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
- return NULL;
-
- strcpy(resource_being_loaded->resource, resource);
-
- if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
- ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
- free(resource_being_loaded);
- return NULL;
- }
-
- /* since the module was successfully opened, and it registered itself
- the previous time we did that, we're going to assume it worked this
- time too :) */
-#endif
-
- AST_LIST_LAST(&module_list)->lib = lib;
- resource_being_loaded = NULL;
-
- return AST_LIST_LAST(&module_list);
-}
-#endif
-
-void ast_module_shutdown(void)
-{
- struct ast_module *mod;
- AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module);
-
- /* We have to call the unload() callbacks in reverse order that the modules
- * exist in the module list so it is the reverse order of how they were
- * loaded. */
-
- AST_LIST_LOCK(&module_list);
- while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry)))
- AST_LIST_INSERT_HEAD(&local_module_list, mod, entry);
- AST_LIST_UNLOCK(&module_list);
-
- while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) {
- if (mod->info->unload)
- mod->info->unload();
- /* Since this should only be called when shutting down "gracefully",
- * all channels should be down before we get to this point, meaning
- * there will be no module users left. */
- AST_LIST_HEAD_DESTROY(&mod->users);
- free(mod);
- }
-}
-
-int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
-{
- struct ast_module *mod;
- int res = -1;
- int error = 0;
-
- AST_LIST_LOCK(&module_list);
-
- if (!(mod = find_resource(resource_name, 0))) {
- AST_LIST_UNLOCK(&module_list);
- return 0;
- }
-
- if (!(mod->flags.running || mod->flags.declined))
- error = 1;
-
- if (!mod->lib) {
- ast_log(LOG_WARNING, "Unloading embedded modules is not supported.\n");
- error = 1;
- }
-
- if (!error && (mod->usecount > 0)) {
- if (force)
- ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
- resource_name, mod->usecount);
- else {
- ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
- mod->usecount);
- error = 1;
- }
- }
-
- if (!error) {
- __ast_module_user_hangup_all(mod);
- res = mod->info->unload();
-
- if (res) {
- ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
- if (force <= AST_FORCE_FIRM)
- error = 1;
- else
- ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
- }
- }
-
- if (!error)
- mod->flags.running = mod->flags.declined = 0;
-
- AST_LIST_UNLOCK(&module_list);
-
-#ifdef LOADABLE_MODULES
- if (!error)
- unload_dynamic_module(mod);
-#endif
-
- if (!error)
- ast_update_use_count();
-
- return res;
-}
-
-char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
-{
- struct ast_module *cur;
- int i, which=0, l = strlen(word);
- char *ret = NULL;
-
- if (pos != rpos)
- return NULL;
-
- AST_LIST_LOCK(&module_list);
- AST_LIST_TRAVERSE(&module_list, cur, entry) {
- if (!strncasecmp(word, cur->resource, l) &&
- (cur->info->reload || !needsreload) &&
- ++which > state) {
- ret = strdup(cur->resource);
- break;
- }
- }
- AST_LIST_UNLOCK(&module_list);
-
- if (!ret) {
- for (i=0; !ret && reload_classes[i].name; i++) {
- if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
- ret = strdup(reload_classes[i].name);
- }
- }
-
- return ret;
-}
-
-int ast_module_reload(const char *name)
-{
- struct ast_module *cur;
- int res = 0; /* return value. 0 = not found, others, see below */
- int i;
-
- if (ast_mutex_trylock(&reloadlock)) {
- ast_verbose("The previous reload command didn't finish yet\n");
- return -1; /* reload already in progress */
- }
- ast_lastreloadtime = time(NULL);
-
- /* Call "predefined" reload here first */
- for (i = 0; reload_classes[i].name; i++) {
- if (!name || !strcasecmp(name, reload_classes[i].name)) {
- reload_classes[i].reload_fn(); /* XXX should check error ? */
- res = 2; /* found and reloaded */
- }
- }
-
- if (name && res) {
- ast_mutex_unlock(&reloadlock);
- return res;
- }
-
- AST_LIST_LOCK(&module_list);
- AST_LIST_TRAVERSE(&module_list, cur, entry) {
- const struct ast_module_info *info = cur->info;
-
- if (name && resource_name_match(name, cur->resource))
- continue;
-
- if (!cur->flags.running || cur->flags.declined) {
- if (!name)
- continue;
- ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. "
- "Before reloading the module, you must run \"module load %s\" "
- "and fix whatever is preventing the module from being initialized.\n",
- name, name);
- res = 2; /* Don't report that the module was not found */
- break;
- }
-
- if (!info->reload) { /* cannot be reloaded */
- if (res < 1) /* store result if possible */
- res = 1; /* 1 = no reload() method */
- continue;
- }
-
- res = 2;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", cur->resource, info->description);
- info->reload();
- }
- AST_LIST_UNLOCK(&module_list);
-
- ast_mutex_unlock(&reloadlock);
-
- return res;
-}
-
-static unsigned int inspect_module(const struct ast_module *mod)
-{
- if (!mod->info->description) {
- ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
- return 1;
- }
-
- if (!mod->info->key) {
- ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
- return 1;
- }
-
- if (verify_key((unsigned char *) mod->info->key)) {
- ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
- return 1;
- }
-
- if (!ast_test_flag(mod->info, AST_MODFLAG_BUILDSUM)) {
- ast_log(LOG_WARNING, "Module '%s' was not compiled against a recent version of Asterisk and may cause instability.\n", mod->resource);
- } else if (!ast_strlen_zero(mod->info->buildopt_sum) &&
- strcmp(buildopt_sum, mod->info->buildopt_sum)) {
- ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
- ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
- return 1;
- }
-
- return 0;
-}
-
-static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only)
-{
- struct ast_module *mod;
- enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
- char tmp[256];
-
- if ((mod = find_resource(resource_name, 0))) {
- if (mod->flags.running) {
- ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
- return AST_MODULE_LOAD_DECLINE;
- }
- if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
- return AST_MODULE_LOAD_SKIP;
- } else {
-#ifdef LOADABLE_MODULES
- if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
- /* don't generate a warning message during load_modules() */
- if (!global_symbols_only) {
- ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
- return AST_MODULE_LOAD_DECLINE;
- } else {
- return AST_MODULE_LOAD_SKIP;
- }
- }
-#else
- ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
- return AST_MODULE_LOAD_DECLINE;
-#endif
- }
-
- if (inspect_module(mod)) {
- ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
-#ifdef LOADABLE_MODULES
- unload_dynamic_module(mod);
-#endif
- return AST_MODULE_LOAD_DECLINE;
- }
-
- mod->flags.declined = 0;
-
- if (mod->info->load)
- res = mod->info->load();
-
- switch (res) {
- case AST_MODULE_LOAD_SUCCESS:
- if (!ast_fully_booted) {
- if (option_verbose)
- ast_verbose("%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
- if (ast_opt_console && !option_verbose)
- ast_verbose( ".");
- } else {
- if (option_verbose)
- ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", resource_name, mod->info->description);
- }
-
- mod->flags.running = 1;
-
- ast_update_use_count();
- break;
- case AST_MODULE_LOAD_DECLINE:
- mod->flags.declined = 1;
- break;
- case AST_MODULE_LOAD_FAILURE:
- break;
- case AST_MODULE_LOAD_SKIP:
- /* modules should never return this value */
- break;
- }
-
- return res;
-}
-
-int ast_load_resource(const char *resource_name)
-{
- AST_LIST_LOCK(&module_list);
- load_resource(resource_name, 0);
- AST_LIST_UNLOCK(&module_list);
-
- return 0;
-}
-
-struct load_order_entry {
- char *resource;
- AST_LIST_ENTRY(load_order_entry) entry;
-};
-
-AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
-
-static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
-{
- struct load_order_entry *order;
-
- AST_LIST_TRAVERSE(load_order, order, entry) {
- if (!resource_name_match(order->resource, resource))
- return NULL;
- }
-
- if (!(order = ast_calloc(1, sizeof(*order))))
- return NULL;
-
- order->resource = ast_strdup(resource);
- AST_LIST_INSERT_TAIL(load_order, order, entry);
-
- return order;
-}
-
-int load_modules(unsigned int preload_only)
-{
- struct ast_config *cfg;
- struct ast_module *mod;
- struct load_order_entry *order;
- struct ast_variable *v;
- unsigned int load_count;
- struct load_order load_order;
- int res = 0;
-#ifdef LOADABLE_MODULES
- struct dirent *dirent;
- DIR *dir;
-#endif
-
- /* all embedded modules have registered themselves by now */
- embedding = 0;
-
- if (option_verbose)
- ast_verbose("Asterisk Dynamic Loader Starting:\n");
-
- AST_LIST_HEAD_INIT_NOLOCK(&load_order);
-
- AST_LIST_LOCK(&module_list);
-
- if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) {
- ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
- goto done;
- }
-
- /* first, find all the modules we have been explicitly requested to load */
- for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
- if (!strcasecmp(v->name, preload_only ? "preload" : "load"))
- add_to_load_order(v->value, &load_order);
- }
-
- /* check if 'autoload' is on */
- if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
- /* if so, first add all the embedded modules that are not already running to the load order */
- AST_LIST_TRAVERSE(&module_list, mod, entry) {
- /* if it's not embedded, skip it */
- if (mod->lib)
- continue;
-
- if (mod->flags.running)
- continue;
-
- order = add_to_load_order(mod->resource, &load_order);
- }
-
-#ifdef LOADABLE_MODULES
- /* if we are allowed to load dynamic modules, scan the directory for
- for all available modules and add them as well */
- if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
- while ((dirent = readdir(dir))) {
- int ld = strlen(dirent->d_name);
-
- /* Must end in .so to load it. */
-
- if (ld < 4)
- continue;
-
- if (strcasecmp(dirent->d_name + ld - 3, ".so"))
- continue;
-
- /* if there is already a module by this name in the module_list,
- skip this file */
- if (find_resource(dirent->d_name, 0))
- continue;
-
- add_to_load_order(dirent->d_name, &load_order);
- }
-
- closedir(dir);
- } else {
- if (!ast_opt_quiet)
- ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
- ast_config_AST_MODULE_DIR);
- }
-#endif
- }
-
- /* now scan the config for any modules we are prohibited from loading and
- remove them from the load order */
- for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
- if (strcasecmp(v->name, "noload"))
- continue;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
- if (!resource_name_match(order->resource, v->value)) {
- AST_LIST_REMOVE_CURRENT(&load_order, entry);
- free(order->resource);
- free(order);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- }
-
- /* we are done with the config now, all the information we need is in the
- load_order list */
- ast_config_destroy(cfg);
-
- load_count = 0;
- AST_LIST_TRAVERSE(&load_order, order, entry)
- load_count++;
-
- if (load_count)
- ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
-
- /* first, load only modules that provide global symbols */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
- switch (load_resource(order->resource, 1)) {
- case AST_MODULE_LOAD_SUCCESS:
- case AST_MODULE_LOAD_DECLINE:
- AST_LIST_REMOVE_CURRENT(&load_order, entry);
- free(order->resource);
- free(order);
- break;
- case AST_MODULE_LOAD_FAILURE:
- res = -1;
- goto done;
- case AST_MODULE_LOAD_SKIP:
- /* try again later */
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- /* now load everything else */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
- switch (load_resource(order->resource, 0)) {
- case AST_MODULE_LOAD_SUCCESS:
- case AST_MODULE_LOAD_DECLINE:
- AST_LIST_REMOVE_CURRENT(&load_order, entry);
- free(order->resource);
- free(order);
- break;
- case AST_MODULE_LOAD_FAILURE:
- res = -1;
- goto done;
- case AST_MODULE_LOAD_SKIP:
- /* should not happen */
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
-done:
- while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
- free(order->resource);
- free(order);
- }
-
- AST_LIST_UNLOCK(&module_list);
-
- return res;
-}
-
-void ast_update_use_count(void)
-{
- /* Notify any module monitors that the use count for a
- resource has changed */
- struct loadupdate *m;
-
- AST_LIST_LOCK(&updaters);
- AST_LIST_TRAVERSE(&updaters, m, entry)
- m->updater();
- AST_LIST_UNLOCK(&updaters);
-}
-
-int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
- const char *like)
-{
- struct ast_module *cur;
- int unlock = -1;
- int total_mod_loaded = 0;
-
- if (AST_LIST_TRYLOCK(&module_list))
- unlock = 0;
-
- AST_LIST_TRAVERSE(&module_list, cur, entry) {
- total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
- }
-
- if (unlock)
- AST_LIST_UNLOCK(&module_list);
-
- return total_mod_loaded;
-}
-
-int ast_loader_register(int (*v)(void))
-{
- struct loadupdate *tmp;
-
- if (!(tmp = ast_malloc(sizeof(*tmp))))
- return -1;
-
- tmp->updater = v;
- AST_LIST_LOCK(&updaters);
- AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
- AST_LIST_UNLOCK(&updaters);
-
- return 0;
-}
-
-int ast_loader_unregister(int (*v)(void))
-{
- struct loadupdate *cur;
-
- AST_LIST_LOCK(&updaters);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
- if (cur->updater == v) {
- AST_LIST_REMOVE_CURRENT(&updaters, entry);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&updaters);
-
- return cur ? 0 : -1;
-}
-
-struct ast_module *ast_module_ref(struct ast_module *mod)
-{
- ast_atomic_fetchadd_int(&mod->usecount, +1);
- ast_update_use_count();
-
- return mod;
-}
-
-void ast_module_unref(struct ast_module *mod)
-{
- ast_atomic_fetchadd_int(&mod->usecount, -1);
- ast_update_use_count();
-}
diff --git a/1.4/main/logger.c b/1.4/main/logger.c
deleted file mode 100644
index 8f6ebaf80..000000000
--- a/1.4/main/logger.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Asterisk Logger
- *
- * Logging routines
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <time.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#if ((defined(AST_DEVMODE)) && (defined(linux)))
-#include <execinfo.h>
-#define MAX_BACKTRACE_FRAMES 20
-#endif
-
-#define SYSLOG_NAMES /* so we can map syslog facilities names to their numeric values,
- from <syslog.h> which is included by logger.h */
-#include <syslog.h>
-
-static int syslog_level_map[] = {
- LOG_DEBUG,
- LOG_INFO, /* arbitrary equivalent of LOG_EVENT */
- LOG_NOTICE,
- LOG_WARNING,
- LOG_ERR,
- LOG_DEBUG,
- LOG_DEBUG
-};
-
-#define SYSLOG_NLEVELS sizeof(syslog_level_map) / sizeof(int)
-
-#include "asterisk/logger.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/term.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/manager.h"
-#include "asterisk/threadstorage.h"
-
-#if defined(__linux__) && !defined(__NR_gettid)
-#include <asm/unistd.h>
-#endif
-
-#if defined(__linux__) && defined(__NR_gettid)
-#define GETTID() syscall(__NR_gettid)
-#else
-#define GETTID() getpid()
-#endif
-
-
-static char dateformat[256] = "%b %e %T"; /* Original Asterisk Format */
-
-static int filesize_reload_needed;
-static int global_logmask = -1;
-
-static struct {
- unsigned int queue_log:1;
- unsigned int event_log:1;
-} logfiles = { 1, 1 };
-
-static char hostname[MAXHOSTNAMELEN];
-
-enum logtypes {
- LOGTYPE_SYSLOG,
- LOGTYPE_FILE,
- LOGTYPE_CONSOLE,
-};
-
-struct logchannel {
- int logmask; /* What to log to this channel */
- int disabled; /* If this channel is disabled or not */
- int facility; /* syslog facility */
- enum logtypes type; /* Type of log channel */
- FILE *fileptr; /* logfile logging file pointer */
- char filename[256]; /* Filename */
- AST_LIST_ENTRY(logchannel) list;
-};
-
-static AST_LIST_HEAD_STATIC(logchannels, logchannel);
-
-static FILE *eventlog;
-static FILE *qlog;
-
-static char *levels[] = {
- "DEBUG",
- "EVENT",
- "NOTICE",
- "WARNING",
- "ERROR",
- "VERBOSE",
- "DTMF"
-};
-
-static int colors[] = {
- COLOR_BRGREEN,
- COLOR_BRBLUE,
- COLOR_YELLOW,
- COLOR_BRRED,
- COLOR_RED,
- COLOR_GREEN,
- COLOR_BRGREEN
-};
-
-AST_THREADSTORAGE(verbose_buf, verbose_buf_init);
-#define VERBOSE_BUF_INIT_SIZE 128
-
-AST_THREADSTORAGE(log_buf, log_buf_init);
-#define LOG_BUF_INIT_SIZE 128
-
-static int make_components(char *s, int lineno)
-{
- char *w;
- int res = 0;
- char *stringp = s;
-
- while ((w = strsep(&stringp, ","))) {
- w = ast_skip_blanks(w);
- if (!strcasecmp(w, "error"))
- res |= (1 << __LOG_ERROR);
- else if (!strcasecmp(w, "warning"))
- res |= (1 << __LOG_WARNING);
- else if (!strcasecmp(w, "notice"))
- res |= (1 << __LOG_NOTICE);
- else if (!strcasecmp(w, "event"))
- res |= (1 << __LOG_EVENT);
- else if (!strcasecmp(w, "debug"))
- res |= (1 << __LOG_DEBUG);
- else if (!strcasecmp(w, "verbose"))
- res |= (1 << __LOG_VERBOSE);
- else if (!strcasecmp(w, "dtmf"))
- res |= (1 << __LOG_DTMF);
- else {
- fprintf(stderr, "Logfile Warning: Unknown keyword '%s' at line %d of logger.conf\n", w, lineno);
- }
- }
-
- return res;
-}
-
-static struct logchannel *make_logchannel(char *channel, char *components, int lineno)
-{
- struct logchannel *chan;
- char *facility;
-#ifndef SOLARIS
- CODE *cptr;
-#endif
-
- if (ast_strlen_zero(channel) || !(chan = ast_calloc(1, sizeof(*chan))))
- return NULL;
-
- if (!strcasecmp(channel, "console")) {
- chan->type = LOGTYPE_CONSOLE;
- } else if (!strncasecmp(channel, "syslog", 6)) {
- /*
- * syntax is:
- * syslog.facility => level,level,level
- */
- facility = strchr(channel, '.');
- if(!facility++ || !facility) {
- facility = "local0";
- }
-
-#ifndef SOLARIS
- /*
- * Walk through the list of facilitynames (defined in sys/syslog.h)
- * to see if we can find the one we have been given
- */
- chan->facility = -1;
- cptr = facilitynames;
- while (cptr->c_name) {
- if (!strcasecmp(facility, cptr->c_name)) {
- chan->facility = cptr->c_val;
- break;
- }
- cptr++;
- }
-#else
- chan->facility = -1;
- if (!strcasecmp(facility, "kern"))
- chan->facility = LOG_KERN;
- else if (!strcasecmp(facility, "USER"))
- chan->facility = LOG_USER;
- else if (!strcasecmp(facility, "MAIL"))
- chan->facility = LOG_MAIL;
- else if (!strcasecmp(facility, "DAEMON"))
- chan->facility = LOG_DAEMON;
- else if (!strcasecmp(facility, "AUTH"))
- chan->facility = LOG_AUTH;
- else if (!strcasecmp(facility, "SYSLOG"))
- chan->facility = LOG_SYSLOG;
- else if (!strcasecmp(facility, "LPR"))
- chan->facility = LOG_LPR;
- else if (!strcasecmp(facility, "NEWS"))
- chan->facility = LOG_NEWS;
- else if (!strcasecmp(facility, "UUCP"))
- chan->facility = LOG_UUCP;
- else if (!strcasecmp(facility, "CRON"))
- chan->facility = LOG_CRON;
- else if (!strcasecmp(facility, "LOCAL0"))
- chan->facility = LOG_LOCAL0;
- else if (!strcasecmp(facility, "LOCAL1"))
- chan->facility = LOG_LOCAL1;
- else if (!strcasecmp(facility, "LOCAL2"))
- chan->facility = LOG_LOCAL2;
- else if (!strcasecmp(facility, "LOCAL3"))
- chan->facility = LOG_LOCAL3;
- else if (!strcasecmp(facility, "LOCAL4"))
- chan->facility = LOG_LOCAL4;
- else if (!strcasecmp(facility, "LOCAL5"))
- chan->facility = LOG_LOCAL5;
- else if (!strcasecmp(facility, "LOCAL6"))
- chan->facility = LOG_LOCAL6;
- else if (!strcasecmp(facility, "LOCAL7"))
- chan->facility = LOG_LOCAL7;
-#endif /* Solaris */
-
- if (0 > chan->facility) {
- fprintf(stderr, "Logger Warning: bad syslog facility in logger.conf\n");
- free(chan);
- return NULL;
- }
-
- chan->type = LOGTYPE_SYSLOG;
- snprintf(chan->filename, sizeof(chan->filename), "%s", channel);
- openlog("asterisk", LOG_PID, chan->facility);
- } else {
- if (channel[0] == '/') {
- if(!ast_strlen_zero(hostname)) {
- snprintf(chan->filename, sizeof(chan->filename) - 1,"%s.%s", channel, hostname);
- } else {
- ast_copy_string(chan->filename, channel, sizeof(chan->filename));
- }
- }
-
- if(!ast_strlen_zero(hostname)) {
- snprintf(chan->filename, sizeof(chan->filename), "%s/%s.%s",(char *)ast_config_AST_LOG_DIR, channel, hostname);
- } else {
- snprintf(chan->filename, sizeof(chan->filename), "%s/%s", (char *)ast_config_AST_LOG_DIR, channel);
- }
- chan->fileptr = fopen(chan->filename, "a");
- if (!chan->fileptr) {
- /* Can't log here, since we're called with a lock */
- fprintf(stderr, "Logger Warning: Unable to open log file '%s': %s\n", chan->filename, strerror(errno));
- }
- chan->type = LOGTYPE_FILE;
- }
- chan->logmask = make_components(components, lineno);
- return chan;
-}
-
-static void init_logger_chain(void)
-{
- struct logchannel *chan;
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *s;
-
- /* delete our list of log channels */
- AST_LIST_LOCK(&logchannels);
- while ((chan = AST_LIST_REMOVE_HEAD(&logchannels, list)))
- free(chan);
- AST_LIST_UNLOCK(&logchannels);
-
- global_logmask = 0;
- errno = 0;
- /* close syslog */
- closelog();
-
- cfg = ast_config_load("logger.conf");
-
- /* If no config file, we're fine, set default options. */
- if (!cfg) {
- if (errno)
- fprintf(stderr, "Unable to open logger.conf: %s; default settings will be used.\n", strerror(errno));
- else
- fprintf(stderr, "Errors detected in logger.conf: see above; default settings will be used.\n");
- if (!(chan = ast_calloc(1, sizeof(*chan))))
- return;
- chan->type = LOGTYPE_CONSOLE;
- chan->logmask = 28; /*warning,notice,error */
- AST_LIST_LOCK(&logchannels);
- AST_LIST_INSERT_HEAD(&logchannels, chan, list);
- AST_LIST_UNLOCK(&logchannels);
- global_logmask |= chan->logmask;
- return;
- }
-
- if ((s = ast_variable_retrieve(cfg, "general", "appendhostname"))) {
- if (ast_true(s)) {
- if (gethostname(hostname, sizeof(hostname) - 1)) {
- ast_copy_string(hostname, "unknown", sizeof(hostname));
- ast_log(LOG_WARNING, "What box has no hostname???\n");
- }
- } else
- hostname[0] = '\0';
- } else
- hostname[0] = '\0';
- if ((s = ast_variable_retrieve(cfg, "general", "dateformat")))
- ast_copy_string(dateformat, s, sizeof(dateformat));
- else
- ast_copy_string(dateformat, "%b %e %T", sizeof(dateformat));
- if ((s = ast_variable_retrieve(cfg, "general", "queue_log")))
- logfiles.queue_log = ast_true(s);
- if ((s = ast_variable_retrieve(cfg, "general", "event_log")))
- logfiles.event_log = ast_true(s);
-
- AST_LIST_LOCK(&logchannels);
- var = ast_variable_browse(cfg, "logfiles");
- for (; var; var = var->next) {
- if (!(chan = make_logchannel(var->name, var->value, var->lineno)))
- continue;
- AST_LIST_INSERT_HEAD(&logchannels, chan, list);
- global_logmask |= chan->logmask;
- }
- AST_LIST_UNLOCK(&logchannels);
-
- ast_config_destroy(cfg);
-}
-
-void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
-{
- va_list ap;
- AST_LIST_LOCK(&logchannels);
- if (qlog) {
- va_start(ap, fmt);
- fprintf(qlog, "%ld|%s|%s|%s|%s|", (long)time(NULL), callid, queuename, agent, event);
- vfprintf(qlog, fmt, ap);
- fprintf(qlog, "\n");
- va_end(ap);
- fflush(qlog);
- }
- AST_LIST_UNLOCK(&logchannels);
-}
-
-int reload_logger(int rotate)
-{
- char old[PATH_MAX] = "";
- char new[PATH_MAX];
- int event_rotate = rotate, queue_rotate = rotate;
- struct logchannel *f;
- FILE *myf;
- int x, res = 0;
-
- AST_LIST_LOCK(&logchannels);
-
- if (eventlog)
- fclose(eventlog);
- else
- event_rotate = 0;
- eventlog = NULL;
-
- if (qlog)
- fclose(qlog);
- else
- queue_rotate = 0;
- qlog = NULL;
-
- mkdir((char *)ast_config_AST_LOG_DIR, 0755);
-
- AST_LIST_TRAVERSE(&logchannels, f, list) {
- if (f->disabled) {
- f->disabled = 0; /* Re-enable logging at reload */
- manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: Yes\r\n", f->filename);
- }
- if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
- fclose(f->fileptr); /* Close file */
- f->fileptr = NULL;
- if (rotate) {
- ast_copy_string(old, f->filename, sizeof(old));
-
- for (x = 0; ; x++) {
- snprintf(new, sizeof(new), "%s.%d", f->filename, x);
- myf = fopen((char *)new, "r");
- if (myf)
- fclose(myf);
- else
- break;
- }
-
- /* do it */
- if (rename(old,new))
- fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
- }
- }
- }
-
- filesize_reload_needed = 0;
-
- init_logger_chain();
-
- if (logfiles.event_log) {
- snprintf(old, sizeof(old), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
- if (event_rotate) {
- for (x=0;;x++) {
- snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, EVENTLOG,x);
- myf = fopen((char *)new, "r");
- if (myf) /* File exists */
- fclose(myf);
- else
- break;
- }
-
- /* do it */
- if (rename(old,new))
- ast_log(LOG_ERROR, "Unable to rename file '%s' to '%s'\n", old, new);
- }
-
- eventlog = fopen(old, "a");
- if (eventlog) {
- ast_log(LOG_EVENT, "Restarted Asterisk Event Logger\n");
- if (option_verbose)
- ast_verbose("Asterisk Event Logger restarted\n");
- } else {
- ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
- res = -1;
- }
- }
-
- if (logfiles.queue_log) {
- snprintf(old, sizeof(old), "%s/%s", (char *)ast_config_AST_LOG_DIR, QUEUELOG);
- if (queue_rotate) {
- for (x = 0; ; x++) {
- snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, QUEUELOG, x);
- myf = fopen((char *)new, "r");
- if (myf) /* File exists */
- fclose(myf);
- else
- break;
- }
-
- /* do it */
- if (rename(old, new))
- ast_log(LOG_ERROR, "Unable to rename file '%s' to '%s'\n", old, new);
- }
-
- qlog = fopen(old, "a");
- if (qlog) {
- ast_queue_log("NONE", "NONE", "NONE", "CONFIGRELOAD", "%s", "");
- ast_log(LOG_EVENT, "Restarted Asterisk Queue Logger\n");
- if (option_verbose)
- ast_verbose("Asterisk Queue Logger restarted\n");
- } else {
- ast_log(LOG_ERROR, "Unable to create queue log: %s\n", strerror(errno));
- res = -1;
- }
- }
-
- AST_LIST_UNLOCK(&logchannels);
-
- return res;
-}
-
-/*! \brief Reload the logger module without rotating log files (also used from loader.c during
- a full Asterisk reload) */
-int logger_reload(void)
-{
- if(reload_logger(0))
- return RESULT_FAILURE;
- return RESULT_SUCCESS;
-}
-
-static int handle_logger_reload(int fd, int argc, char *argv[])
-{
- int result = logger_reload();
- if (result == RESULT_FAILURE)
- ast_cli(fd, "Failed to reload the logger\n");
- return result;
-}
-
-static int handle_logger_rotate(int fd, int argc, char *argv[])
-{
- if(reload_logger(1)) {
- ast_cli(fd, "Failed to reload the logger and rotate log files\n");
- return RESULT_FAILURE;
- }
- return RESULT_SUCCESS;
-}
-
-/*! \brief CLI command to show logging system configuration */
-static int handle_logger_show_channels(int fd, int argc, char *argv[])
-{
-#define FORMATL "%-35.35s %-8.8s %-9.9s "
- struct logchannel *chan;
-
- ast_cli(fd,FORMATL, "Channel", "Type", "Status");
- ast_cli(fd, "Configuration\n");
- ast_cli(fd,FORMATL, "-------", "----", "------");
- ast_cli(fd, "-------------\n");
- AST_LIST_LOCK(&logchannels);
- AST_LIST_TRAVERSE(&logchannels, chan, list) {
- ast_cli(fd, FORMATL, chan->filename, chan->type==LOGTYPE_CONSOLE ? "Console" : (chan->type==LOGTYPE_SYSLOG ? "Syslog" : "File"),
- chan->disabled ? "Disabled" : "Enabled");
- ast_cli(fd, " - ");
- if (chan->logmask & (1 << __LOG_DEBUG))
- ast_cli(fd, "Debug ");
- if (chan->logmask & (1 << __LOG_DTMF))
- ast_cli(fd, "DTMF ");
- if (chan->logmask & (1 << __LOG_VERBOSE))
- ast_cli(fd, "Verbose ");
- if (chan->logmask & (1 << __LOG_WARNING))
- ast_cli(fd, "Warning ");
- if (chan->logmask & (1 << __LOG_NOTICE))
- ast_cli(fd, "Notice ");
- if (chan->logmask & (1 << __LOG_ERROR))
- ast_cli(fd, "Error ");
- if (chan->logmask & (1 << __LOG_EVENT))
- ast_cli(fd, "Event ");
- ast_cli(fd, "\n");
- }
- AST_LIST_UNLOCK(&logchannels);
- ast_cli(fd, "\n");
-
- return RESULT_SUCCESS;
-}
-
-struct verb {
- void (*verboser)(const char *string);
- AST_LIST_ENTRY(verb) list;
-};
-
-static AST_LIST_HEAD_STATIC(verbosers, verb);
-
-static char logger_reload_help[] =
-"Usage: logger reload\n"
-" Reloads the logger subsystem state. Use after restarting syslogd(8) if you are using syslog logging.\n";
-
-static char logger_rotate_help[] =
-"Usage: logger rotate\n"
-" Rotates and Reopens the log files.\n";
-
-static char logger_show_channels_help[] =
-"Usage: logger show channels\n"
-" List configured logger channels.\n";
-
-static struct ast_cli_entry cli_logger[] = {
- { { "logger", "show", "channels", NULL },
- handle_logger_show_channels, "List configured log channels",
- logger_show_channels_help },
-
- { { "logger", "reload", NULL },
- handle_logger_reload, "Reopens the log files",
- logger_reload_help },
-
- { { "logger", "rotate", NULL },
- handle_logger_rotate, "Rotates and reopens the log files",
- logger_rotate_help },
-};
-
-static int handle_SIGXFSZ(int sig)
-{
- /* Indicate need to reload */
- filesize_reload_needed = 1;
- return 0;
-}
-
-int init_logger(void)
-{
- char tmp[256];
- int res = 0;
-
- /* auto rotate if sig SIGXFSZ comes a-knockin */
- (void) signal(SIGXFSZ,(void *) handle_SIGXFSZ);
-
- /* register the logger cli commands */
- ast_cli_register_multiple(cli_logger, sizeof(cli_logger) / sizeof(struct ast_cli_entry));
-
- mkdir((char *)ast_config_AST_LOG_DIR, 0755);
-
- /* create log channels */
- init_logger_chain();
-
- /* create the eventlog */
- if (logfiles.event_log) {
- mkdir((char *)ast_config_AST_LOG_DIR, 0755);
- snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
- eventlog = fopen((char *)tmp, "a");
- if (eventlog) {
- ast_log(LOG_EVENT, "Started Asterisk Event Logger\n");
- if (option_verbose)
- ast_verbose("Asterisk Event Logger Started %s\n",(char *)tmp);
- } else {
- ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
- res = -1;
- }
- }
-
- if (logfiles.queue_log) {
- snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, QUEUELOG);
- qlog = fopen(tmp, "a");
- ast_queue_log("NONE", "NONE", "NONE", "QUEUESTART", "%s", "");
- }
- return res;
-}
-
-void close_logger(void)
-{
- struct logchannel *f;
-
- AST_LIST_LOCK(&logchannels);
-
- if (eventlog) {
- fclose(eventlog);
- eventlog = NULL;
- }
-
- if (qlog) {
- fclose(qlog);
- qlog = NULL;
- }
-
- AST_LIST_TRAVERSE(&logchannels, f, list) {
- if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
- fclose(f->fileptr);
- f->fileptr = NULL;
- }
- }
-
- closelog(); /* syslog */
-
- AST_LIST_UNLOCK(&logchannels);
-
- return;
-}
-
-static void ast_log_vsyslog(int level, const char *file, int line, const char *function, const char *fmt, va_list args)
-{
- char buf[BUFSIZ];
- char *s;
-
- if (level >= SYSLOG_NLEVELS) {
- /* we are locked here, so cannot ast_log() */
- fprintf(stderr, "ast_log_vsyslog called with bogus level: %d\n", level);
- return;
- }
- if (level == __LOG_VERBOSE) {
- snprintf(buf, sizeof(buf), "VERBOSE[%ld]: ", (long)GETTID());
- level = __LOG_DEBUG;
- } else if (level == __LOG_DTMF) {
- snprintf(buf, sizeof(buf), "DTMF[%ld]: ", (long)GETTID());
- level = __LOG_DEBUG;
- } else {
- snprintf(buf, sizeof(buf), "%s[%ld]: %s:%d in %s: ",
- levels[level], (long)GETTID(), file, line, function);
- }
- s = buf + strlen(buf);
- vsnprintf(s, sizeof(buf) - strlen(buf), fmt, args);
- term_strip(s, s, strlen(s) + 1);
- syslog(syslog_level_map[level], "%s", buf);
-}
-
-/*!
- * \brief send log messages to syslog and/or the console
- */
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
-{
- struct logchannel *chan;
- struct ast_dynamic_str *buf;
- time_t t;
- struct tm tm;
- char date[256];
-
- va_list ap;
-
- if (!(buf = ast_dynamic_str_thread_get(&log_buf, LOG_BUF_INIT_SIZE)))
- return;
-
- if (AST_LIST_EMPTY(&logchannels))
- {
- /*
- * we don't have the logger chain configured yet,
- * so just log to stdout
- */
- if (level != __LOG_VERBOSE) {
- int res;
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap);
- va_end(ap);
- if (res != AST_DYNSTR_BUILD_FAILED) {
- term_filter_escapes(buf->str);
- fputs(buf->str, stdout);
- }
- }
- return;
- }
-
- /* don't display LOG_DEBUG messages unless option_verbose _or_ option_debug
- are non-zero; LOG_DEBUG messages can still be displayed if option_debug
- is zero, if option_verbose is non-zero (this allows for 'level zero'
- LOG_DEBUG messages to be displayed, if the logmask on any channel
- allows it)
- */
- if (!option_verbose && !option_debug && (level == __LOG_DEBUG))
- return;
-
- /* Ignore anything that never gets logged anywhere */
- if (!(global_logmask & (1 << level)))
- return;
-
- /* Ignore anything other than the currently debugged file if there is one */
- if ((level == __LOG_DEBUG) && !ast_strlen_zero(debug_filename) && strcasecmp(debug_filename, file))
- return;
-
- time(&t);
- ast_localtime(&t, &tm, NULL);
- strftime(date, sizeof(date), dateformat, &tm);
-
- AST_LIST_LOCK(&logchannels);
-
- if (logfiles.event_log && level == __LOG_EVENT) {
- va_start(ap, fmt);
-
- fprintf(eventlog, "%s asterisk[%ld]: ", date, (long)getpid());
- vfprintf(eventlog, fmt, ap);
- fflush(eventlog);
-
- va_end(ap);
- AST_LIST_UNLOCK(&logchannels);
- return;
- }
-
- AST_LIST_TRAVERSE(&logchannels, chan, list) {
- if (chan->disabled)
- break;
- /* Check syslog channels */
- if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << level))) {
- va_start(ap, fmt);
- ast_log_vsyslog(level, file, line, function, fmt, ap);
- va_end(ap);
- /* Console channels */
- } else if ((chan->logmask & (1 << level)) && (chan->type == LOGTYPE_CONSOLE)) {
- char linestr[128];
- char tmp1[80], tmp2[80], tmp3[80], tmp4[80];
-
- if (level != __LOG_VERBOSE) {
- int res;
- sprintf(linestr, "%d", line);
- ast_dynamic_str_thread_set(&buf, BUFSIZ, &log_buf,
- "[%s] %s[%ld]: %s:%s %s: ",
- date,
- term_color(tmp1, levels[level], colors[level], 0, sizeof(tmp1)),
- (long)GETTID(),
- term_color(tmp2, file, COLOR_BRWHITE, 0, sizeof(tmp2)),
- term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
- term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4)));
- /*filter to the console!*/
- term_filter_escapes(buf->str);
- ast_console_puts_mutable(buf->str);
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap);
- va_end(ap);
- if (res != AST_DYNSTR_BUILD_FAILED)
- ast_console_puts_mutable(buf->str);
- }
- /* File channels */
- } else if ((chan->logmask & (1 << level)) && (chan->fileptr)) {
- int res;
- ast_dynamic_str_thread_set(&buf, BUFSIZ, &log_buf,
- "[%s] %s[%ld] %s: ",
- date, levels[level], (long)GETTID(), file);
- res = fprintf(chan->fileptr, "%s", buf->str);
- if (res <= 0 && !ast_strlen_zero(buf->str)) { /* Error, no characters printed */
- fprintf(stderr,"**** Asterisk Logging Error: ***********\n");
- if (errno == ENOMEM || errno == ENOSPC) {
- fprintf(stderr, "Asterisk logging error: Out of disk space, can't log to log file %s\n", chan->filename);
- } else
- fprintf(stderr, "Logger Warning: Unable to write to log file '%s': %s (disabled)\n", chan->filename, strerror(errno));
- manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: No\r\nReason: %d - %s\r\n", chan->filename, errno, strerror(errno));
- chan->disabled = 1;
- } else {
- int res;
- /* No error message, continue printing */
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap);
- va_end(ap);
- if (res != AST_DYNSTR_BUILD_FAILED) {
- term_strip(buf->str, buf->str, buf->len);
- fputs(buf->str, chan->fileptr);
- fflush(chan->fileptr);
- }
- }
- }
- }
-
- AST_LIST_UNLOCK(&logchannels);
-
- if (filesize_reload_needed) {
- reload_logger(1);
- ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ (Exceeded file size limit)\n");
- if (option_verbose)
- ast_verbose("Rotated Logs Per SIGXFSZ (Exceeded file size limit)\n");
- }
-}
-
-void ast_backtrace(void)
-{
-#ifdef linux
-#ifdef AST_DEVMODE
- int count=0, i=0;
- void **addresses;
- char **strings;
-
- if ((addresses = ast_calloc(MAX_BACKTRACE_FRAMES, sizeof(*addresses)))) {
- count = backtrace(addresses, MAX_BACKTRACE_FRAMES);
- if ((strings = backtrace_symbols(addresses, count))) {
- ast_log(LOG_DEBUG, "Got %d backtrace record%c\n", count, count != 1 ? 's' : ' ');
- for (i=0; i < count ; i++) {
-#if __WORDSIZE == 32
- ast_log(LOG_DEBUG, "#%d: [%08X] %s\n", i, (unsigned int)addresses[i], strings[i]);
-#elif __WORDSIZE == 64
- ast_log(LOG_DEBUG, "#%d: [%016lX] %s\n", i, (unsigned long)addresses[i], strings[i]);
-#endif
- }
- free(strings);
- } else {
- ast_log(LOG_DEBUG, "Could not allocate memory for backtrace\n");
- }
- free(addresses);
- }
-#else
- ast_log(LOG_WARNING, "Must run configure with '--enable-dev-mode' for stack backtraces.\n");
-#endif
-#else /* ndef linux */
- ast_log(LOG_WARNING, "Inline stack backtraces are only available on the Linux platform.\n");
-#endif
-}
-
-void ast_verbose(const char *fmt, ...)
-{
- struct verb *v;
- struct ast_dynamic_str *buf;
- int res;
- va_list ap;
-
- if (ast_opt_timestamp) {
- time_t t;
- struct tm tm;
- char date[40];
- char *datefmt;
-
- time(&t);
- ast_localtime(&t, &tm, NULL);
- strftime(date, sizeof(date), dateformat, &tm);
- datefmt = alloca(strlen(date) + 3 + strlen(fmt) + 1);
- sprintf(datefmt, "%c[%s] %s", 127, date, fmt);
- fmt = datefmt;
- } else {
- char *tmp = alloca(strlen(fmt) + 2);
- sprintf(tmp, "%c%s", 127, fmt);
- fmt = tmp;
- }
-
- if (!(buf = ast_dynamic_str_thread_get(&verbose_buf, VERBOSE_BUF_INIT_SIZE)))
- return;
-
- va_start(ap, fmt);
- res = ast_dynamic_str_thread_set_va(&buf, 0, &verbose_buf, fmt, ap);
- va_end(ap);
-
- if (res == AST_DYNSTR_BUILD_FAILED)
- return;
-
- /* filter out possibly hazardous escape sequences */
- term_filter_escapes(buf->str);
-
- AST_LIST_LOCK(&verbosers);
- AST_LIST_TRAVERSE(&verbosers, v, list)
- v->verboser(buf->str);
- AST_LIST_UNLOCK(&verbosers);
-
- ast_log(LOG_VERBOSE, "%s", buf->str + 1);
-}
-
-int ast_register_verbose(void (*v)(const char *string))
-{
- struct verb *verb;
-
- if (!(verb = ast_malloc(sizeof(*verb))))
- return -1;
-
- verb->verboser = v;
-
- AST_LIST_LOCK(&verbosers);
- AST_LIST_INSERT_HEAD(&verbosers, verb, list);
- AST_LIST_UNLOCK(&verbosers);
-
- return 0;
-}
-
-int ast_unregister_verbose(void (*v)(const char *string))
-{
- struct verb *cur;
-
- AST_LIST_LOCK(&verbosers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&verbosers, cur, list) {
- if (cur->verboser == v) {
- AST_LIST_REMOVE_CURRENT(&verbosers, list);
- free(cur);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&verbosers);
-
- return cur ? 0 : -1;
-}
diff --git a/1.4/main/manager.c b/1.4/main/manager.c
deleted file mode 100644
index 4d1d8ceea..000000000
--- a/1.4/main/manager.c
+++ /dev/null
@@ -1,3068 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief The Asterisk Management Interface - AMI
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * Channel Management and more
- *
- * \ref amiconf
- */
-
-/*! \addtogroup Group_AMI AMI functions
-*/
-/*! @{
- Doxygen group */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/manager.h"
-#include "asterisk/config.h"
-#include "asterisk/callerid.h"
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/pbx.h"
-#include "asterisk/md5.h"
-#include "asterisk/acl.h"
-#include "asterisk/utils.h"
-#include "asterisk/http.h"
-#include "asterisk/threadstorage.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/term.h"
-#include "asterisk/astobj2.h"
-
-struct fast_originate_helper {
- char tech[AST_MAX_EXTENSION];
- char data[AST_MAX_EXTENSION];
- int timeout;
- char app[AST_MAX_APP];
- char appdata[AST_MAX_EXTENSION];
- char cid_name[AST_MAX_EXTENSION];
- char cid_num[AST_MAX_EXTENSION];
- char context[AST_MAX_CONTEXT];
- char exten[AST_MAX_EXTENSION];
- char idtext[AST_MAX_EXTENSION];
- char account[AST_MAX_ACCOUNT_CODE];
- int priority;
- struct ast_variable *vars;
-};
-
-struct eventqent {
- int usecount;
- int category;
- struct eventqent *next;
- char eventdata[1];
-};
-
-static int enabled;
-static int portno = DEFAULT_MANAGER_PORT;
-static int asock = -1;
-static int displayconnects = 1;
-static int timestampevents;
-static int httptimeout = 60;
-
-static pthread_t t;
-static int block_sockets;
-static int num_sessions;
-
-/* Protected by the sessions list lock */
-struct eventqent *master_eventq = NULL;
-
-AST_THREADSTORAGE(manager_event_buf, manager_event_buf_init);
-#define MANAGER_EVENT_BUF_INITSIZE 256
-
-AST_THREADSTORAGE(astman_append_buf, astman_append_buf_init);
-#define ASTMAN_APPEND_BUF_INITSIZE 256
-
-static struct permalias {
- int num;
- char *label;
-} perms[] = {
- { EVENT_FLAG_SYSTEM, "system" },
- { EVENT_FLAG_CALL, "call" },
- { EVENT_FLAG_LOG, "log" },
- { EVENT_FLAG_VERBOSE, "verbose" },
- { EVENT_FLAG_COMMAND, "command" },
- { EVENT_FLAG_AGENT, "agent" },
- { EVENT_FLAG_USER, "user" },
- { EVENT_FLAG_CONFIG, "config" },
- { -1, "all" },
- { 0, "none" },
-};
-
-static const char *command_blacklist[] = {
- "module load",
- "module unload",
-};
-
-struct mansession {
- /*! Execution thread */
- pthread_t t;
- /*! Thread lock -- don't use in action callbacks, it's already taken care of */
- ast_mutex_t __lock;
- /*! socket address */
- struct sockaddr_in sin;
- /*! TCP socket */
- int fd;
- /*! Whether an HTTP manager is in use */
- int inuse;
- /*! Whether an HTTP session should be destroyed */
- int needdestroy;
- /*! Whether an HTTP session has someone waiting on events */
- pthread_t waiting_thread;
- /*! Unique manager identifer */
- uint32_t managerid;
- /*! Session timeout if HTTP */
- time_t sessiontimeout;
- /*! Output from manager interface */
- struct ast_dynamic_str *outputstr;
- /*! Logged in username */
- char username[80];
- /*! Authentication challenge */
- char challenge[10];
- /*! Authentication status */
- int authenticated;
- /*! Authorization for reading */
- int readperm;
- /*! Authorization for writing */
- int writeperm;
- /*! Buffer */
- char inbuf[1024];
- int inlen;
- int send_events;
- int displaysystemname; /*!< Add system name to manager responses and events */
- /* Queued events that we've not had the ability to send yet */
- struct eventqent *eventq;
- /* Timeout for ast_carefulwrite() */
- int writetimeout;
- int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */
- AST_LIST_ENTRY(mansession) list;
-};
-
-static AST_LIST_HEAD_STATIC(sessions, mansession);
-
-struct ast_manager_user {
- char username[80];
- char *secret;
- char *deny;
- char *permit;
- char *read;
- char *write;
- unsigned int displayconnects:1;
- int keep;
- AST_LIST_ENTRY(ast_manager_user) list;
-};
-
-static AST_LIST_HEAD_STATIC(users, ast_manager_user);
-
-static struct manager_action *first_action;
-AST_RWLOCK_DEFINE_STATIC(actionlock);
-
-/*! \brief Convert authority code to string with serveral options */
-static char *authority_to_str(int authority, char *res, int reslen)
-{
- int running_total = 0, i;
-
- memset(res, 0, reslen);
- for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) {
- if (authority & perms[i].num) {
- if (*res) {
- strncat(res, ",", (reslen > running_total) ? reslen - running_total - 1 : 0);
- running_total++;
- }
- strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total - 1 : 0);
- running_total += strlen(perms[i].label);
- }
- }
-
- if (ast_strlen_zero(res))
- ast_copy_string(res, "<none>", reslen);
-
- return res;
-}
-
-static char *complete_show_mancmd(const char *line, const char *word, int pos, int state)
-{
- struct manager_action *cur;
- int which = 0;
- char *ret = NULL;
-
- ast_rwlock_rdlock(&actionlock);
- for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
- if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) {
- ret = ast_strdup(cur->action);
- break; /* make sure we exit even if ast_strdup() returns NULL */
- }
- }
- ast_rwlock_unlock(&actionlock);
-
- return ret;
-}
-
-static void xml_copy_escape(char **dst, size_t *maxlen, const char *src, int lower)
-{
- while (*src && (*maxlen > 6)) {
- switch (*src) {
- case '<':
- strcpy(*dst, "&lt;");
- (*dst) += 4;
- *maxlen -= 4;
- break;
- case '>':
- strcpy(*dst, "&gt;");
- (*dst) += 4;
- *maxlen -= 4;
- break;
- case '\"':
- strcpy(*dst, "&quot;");
- (*dst) += 6;
- *maxlen -= 6;
- break;
- case '\'':
- strcpy(*dst, "&apos;");
- (*dst) += 6;
- *maxlen -= 6;
- break;
- case '&':
- strcpy(*dst, "&amp;");
- (*dst) += 5;
- *maxlen -= 5;
- break;
- default:
- *(*dst)++ = lower ? tolower(*src) : *src;
- (*maxlen)--;
- }
- src++;
- }
-}
-
-struct variable_count {
- char *varname;
- int count;
-};
-
-static int compress_char(char c)
-{
- c &= 0x7f;
- if (c < 32)
- return 0;
- else if (c >= 'a' && c <= 'z')
- return c - 64;
- else if (c > 'z')
- return '_';
- else
- return c - 32;
-}
-
-static int variable_count_hash_fn(const void *vvc, const int flags)
-{
- const struct variable_count *vc = vvc;
- int res = 0, i;
- for (i = 0; i < 5; i++) {
- if (vc->varname[i] == '\0')
- break;
- res += compress_char(vc->varname[i]) << (i * 6);
- }
- return res;
-}
-
-static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
-{
- /* Due to the simplicity of struct variable_count, it makes no difference
- * if you pass in objects or strings, the same operation applies. This is
- * due to the fact that the hash occurs on the first element, which means
- * the address of both the struct and the string are exactly the same. */
- struct variable_count *vc = obj;
- char *str = vstr;
- return !strcmp(vc->varname, str) ? CMP_MATCH : 0;
-}
-
-static char *xml_translate(char *in, struct ast_variable *vars)
-{
- struct ast_variable *v;
- char *dest = NULL;
- char *out, *tmp, *var, *val;
- char *objtype = NULL;
- int colons = 0;
- int breaks = 0;
- size_t len;
- int count = 1;
- int escaped = 0;
- int inobj = 0;
- int x;
- struct variable_count *vc = NULL;
- struct ao2_container *vco = NULL;
-
- for (v = vars; v; v = v->next) {
- if (!dest && !strcasecmp(v->name, "ajaxdest"))
- dest = v->value;
- else if (!objtype && !strcasecmp(v->name, "ajaxobjtype"))
- objtype = v->value;
- }
- if (!dest)
- dest = "unknown";
- if (!objtype)
- objtype = "generic";
- for (x = 0; in[x]; x++) {
- if (in[x] == ':')
- colons++;
- else if (in[x] == '\n')
- breaks++;
- else if (strchr("&\"<>\'", in[x]))
- escaped++;
- }
- len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&amp;" */
- out = ast_malloc(len);
- if (!out)
- return 0;
- tmp = out;
- while (*in) {
- var = in;
- while (*in && (*in >= 32))
- in++;
- if (*in) {
- if ((count > 3) && inobj) {
- ast_build_string(&tmp, &len, " /></response>\n");
- inobj = 0;
-
- /* Entity is closed, so close out the name cache */
- ao2_ref(vco, -1);
- vco = NULL;
- }
- count = 0;
- while (*in && (*in < 32)) {
- *in = '\0';
- in++;
- count++;
- }
- val = strchr(var, ':');
- if (val) {
- *val = '\0';
- val++;
- if (*val == ' ')
- val++;
- if (!inobj) {
- vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn);
- ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
- inobj = 1;
- }
-
- /* Check if the var has been used already */
- if ((vc = ao2_find(vco, var, 0)))
- vc->count++;
- else {
- /* Create a new entry for this one */
- vc = ao2_alloc(sizeof(*vc), NULL);
- vc->varname = var;
- vc->count = 1;
- ao2_link(vco, vc);
- }
-
- ast_build_string(&tmp, &len, " ");
- xml_copy_escape(&tmp, &len, var, 1);
- if (vc->count > 1)
- ast_build_string(&tmp, &len, "-%d", vc->count);
- ast_build_string(&tmp, &len, "='");
- xml_copy_escape(&tmp, &len, val, 0);
- ast_build_string(&tmp, &len, "'");
- ao2_ref(vc, -1);
- }
- }
- }
- if (inobj)
- ast_build_string(&tmp, &len, " /></response>\n");
- if (vco)
- ao2_ref(vco, -1);
- return out;
-}
-
-static char *html_translate(char *in)
-{
- int x;
- int colons = 0;
- int breaks = 0;
- size_t len;
- int count = 1;
- char *tmp, *var, *val, *out;
-
- for (x=0; in[x]; x++) {
- if (in[x] == ':')
- colons++;
- if (in[x] == '\n')
- breaks++;
- }
- len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */
- out = ast_malloc(len);
- if (!out)
- return 0;
- tmp = out;
- while (*in) {
- var = in;
- while (*in && (*in >= 32))
- in++;
- if (*in) {
- if ((count % 4) == 0){
- ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
- }
- count = 0;
- while (*in && (*in < 32)) {
- *in = '\0';
- in++;
- count++;
- }
- val = strchr(var, ':');
- if (val) {
- *val = '\0';
- val++;
- if (*val == ' ')
- val++;
- ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val);
- }
- }
- }
- return out;
-}
-
-
-
-static struct ast_manager_user *ast_get_manager_by_name_locked(const char *name)
-{
- struct ast_manager_user *user = NULL;
-
- AST_LIST_TRAVERSE(&users, user, list)
- if (!strcasecmp(user->username, name))
- break;
- return user;
-}
-
-void astman_append(struct mansession *s, const char *fmt, ...)
-{
- va_list ap;
- struct ast_dynamic_str *buf;
-
- ast_mutex_lock(&s->__lock);
-
- if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
- ast_mutex_unlock(&s->__lock);
- return;
- }
-
- va_start(ap, fmt);
- ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap);
- va_end(ap);
-
- if (s->fd > -1)
- ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout);
- else {
- if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) {
- ast_mutex_unlock(&s->__lock);
- return;
- }
-
- ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str);
- }
-
- ast_mutex_unlock(&s->__lock);
-}
-
-static int handle_showmancmd(int fd, int argc, char *argv[])
-{
- struct manager_action *cur;
- char authority[80];
- int num;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- ast_rwlock_rdlock(&actionlock);
- for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
- for (num = 3; num < argc; num++) {
- if (!strcasecmp(cur->action, argv[num])) {
- ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", cur->action, cur->synopsis, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->description ? cur->description : "");
- }
- }
- }
- ast_rwlock_unlock(&actionlock);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_showmanager(int fd, int argc, char *argv[])
-{
- struct ast_manager_user *user = NULL;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&users);
-
- if (!(user = ast_get_manager_by_name_locked(argv[3]))) {
- ast_cli(fd, "There is no manager called %s\n", argv[3]);
- AST_LIST_UNLOCK(&users);
- return -1;
- }
-
- ast_cli(fd,"\n");
- ast_cli(fd,
- " username: %s\n"
- " secret: %s\n"
- " deny: %s\n"
- " permit: %s\n"
- " read: %s\n"
- " write: %s\n"
- "displayconnects: %s\n",
- (user->username ? user->username : "(N/A)"),
- (user->secret ? "<Set>" : "(N/A)"),
- (user->deny ? user->deny : "(N/A)"),
- (user->permit ? user->permit : "(N/A)"),
- (user->read ? user->read : "(N/A)"),
- (user->write ? user->write : "(N/A)"),
- (user->displayconnects ? "yes" : "no"));
-
- AST_LIST_UNLOCK(&users);
-
- return RESULT_SUCCESS;
-}
-
-
-static int handle_showmanagers(int fd, int argc, char *argv[])
-{
- struct ast_manager_user *user = NULL;
- int count_amu = 0;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&users);
-
- /* If there are no users, print out something along those lines */
- if (AST_LIST_EMPTY(&users)) {
- ast_cli(fd, "There are no manager users.\n");
- AST_LIST_UNLOCK(&users);
- return RESULT_SUCCESS;
- }
-
- ast_cli(fd, "\nusername\n--------\n");
-
- AST_LIST_TRAVERSE(&users, user, list) {
- ast_cli(fd, "%s\n", user->username);
- count_amu++;
- }
-
- AST_LIST_UNLOCK(&users);
-
- ast_cli(fd,"-------------------\n");
- ast_cli(fd,"%d manager users configured.\n", count_amu);
-
- return RESULT_SUCCESS;
-}
-
-
-/*! \brief CLI command
- Should change to "manager show commands" */
-static int handle_showmancmds(int fd, int argc, char *argv[])
-{
- struct manager_action *cur;
- char authority[80];
- char *format = " %-15.15s %-15.15s %-55.55s\n";
-
- ast_cli(fd, format, "Action", "Privilege", "Synopsis");
- ast_cli(fd, format, "------", "---------", "--------");
-
- ast_rwlock_rdlock(&actionlock);
- for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */
- ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis);
- ast_rwlock_unlock(&actionlock);
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief CLI command show manager connected */
-/* Should change to "manager show connected" */
-static int handle_showmanconn(int fd, int argc, char *argv[])
-{
- struct mansession *s;
- char *format = " %-15.15s %-15.15s\n";
-
- ast_cli(fd, format, "Username", "IP Address");
-
- AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE(&sessions, s, list)
- ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr));
- AST_LIST_UNLOCK(&sessions);
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief CLI command show manager connected */
-/* Should change to "manager show connected" */
-static int handle_showmaneventq(int fd, int argc, char *argv[])
-{
- struct eventqent *s;
-
- AST_LIST_LOCK(&sessions);
- for (s = master_eventq; s; s = s->next) {
- ast_cli(fd, "Usecount: %d\n",s->usecount);
- ast_cli(fd, "Category: %d\n", s->category);
- ast_cli(fd, "Event:\n%s", s->eventdata);
- }
- AST_LIST_UNLOCK(&sessions);
-
- return RESULT_SUCCESS;
-}
-
-static char showmancmd_help[] =
-"Usage: manager show command <actionname>\n"
-" Shows the detailed description for a specific Asterisk manager interface command.\n";
-
-static char showmancmds_help[] =
-"Usage: manager show commands\n"
-" Prints a listing of all the available Asterisk manager interface commands.\n";
-
-static char showmanconn_help[] =
-"Usage: manager show connected\n"
-" Prints a listing of the users that are currently connected to the\n"
-"Asterisk manager interface.\n";
-
-static char showmaneventq_help[] =
-"Usage: manager show eventq\n"
-" Prints a listing of all events pending in the Asterisk manger\n"
-"event queue.\n";
-
-static char showmanagers_help[] =
-"Usage: manager show users\n"
-" Prints a listing of all managers that are currently configured on that\n"
-" system.\n";
-
-static char showmanager_help[] =
-" Usage: manager show user <user>\n"
-" Display all information related to the manager user specified.\n";
-
-static struct ast_cli_entry cli_show_manager_command_deprecated = {
- { "show", "manager", "command", NULL },
- handle_showmancmd, NULL,
- NULL, complete_show_mancmd };
-
-static struct ast_cli_entry cli_show_manager_commands_deprecated = {
- { "show", "manager", "commands", NULL },
- handle_showmancmds, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_manager_connected_deprecated = {
- { "show", "manager", "connected", NULL },
- handle_showmanconn, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_manager_eventq_deprecated = {
- { "show", "manager", "eventq", NULL },
- handle_showmaneventq, NULL,
- NULL };
-
-static struct ast_cli_entry cli_manager[] = {
- { { "manager", "show", "command", NULL },
- handle_showmancmd, "Show a manager interface command",
- showmancmd_help, complete_show_mancmd, &cli_show_manager_command_deprecated },
-
- { { "manager", "show", "commands", NULL },
- handle_showmancmds, "List manager interface commands",
- showmancmds_help, NULL, &cli_show_manager_commands_deprecated },
-
- { { "manager", "show", "connected", NULL },
- handle_showmanconn, "List connected manager interface users",
- showmanconn_help, NULL, &cli_show_manager_connected_deprecated },
-
- { { "manager", "show", "eventq", NULL },
- handle_showmaneventq, "List manager interface queued events",
- showmaneventq_help, NULL, &cli_show_manager_eventq_deprecated },
-
- { { "manager", "show", "users", NULL },
- handle_showmanagers, "List configured manager users",
- showmanagers_help, NULL, NULL },
-
- { { "manager", "show", "user", NULL },
- handle_showmanager, "Display information on a specific manager user",
- showmanager_help, NULL, NULL },
-};
-
-static void unuse_eventqent(struct eventqent *e)
-{
- if (ast_atomic_dec_and_test(&e->usecount) && e->next)
- pthread_kill(t, SIGURG);
-}
-
-static void free_session(struct mansession *s)
-{
- struct eventqent *eqe;
- if (s->fd > -1)
- close(s->fd);
- if (s->outputstr)
- free(s->outputstr);
- ast_mutex_destroy(&s->__lock);
- while (s->eventq) {
- eqe = s->eventq;
- s->eventq = s->eventq->next;
- unuse_eventqent(eqe);
- }
- free(s);
-}
-
-static void destroy_session(struct mansession *s)
-{
- AST_LIST_LOCK(&sessions);
- AST_LIST_REMOVE(&sessions, s, list);
- num_sessions--;
- free_session(s);
- AST_LIST_UNLOCK(&sessions);
-}
-
-const char *astman_get_header(const struct message *m, char *var)
-{
- char cmp[80];
- int x;
-
- snprintf(cmp, sizeof(cmp), "%s: ", var);
-
- for (x = 0; x < m->hdrcount; x++) {
- if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
- return m->headers[x] + strlen(cmp);
- }
-
- return "";
-}
-
-struct ast_variable *astman_get_variables(const struct message *m)
-{
- int varlen, x, y;
- struct ast_variable *head = NULL, *cur;
- char *var, *val;
-
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(vars)[32];
- );
-
- varlen = strlen("Variable: ");
-
- for (x = 0; x < m->hdrcount; x++) {
- if (strncasecmp("Variable: ", m->headers[x], varlen))
- continue;
-
- parse = ast_strdupa(m->headers[x] + varlen);
-
- AST_STANDARD_APP_ARGS(args, parse);
- if (args.argc) {
- for (y = 0; y < args.argc; y++) {
- if (!args.vars[y])
- continue;
- var = val = ast_strdupa(args.vars[y]);
- strsep(&val, "=");
- if (!val || ast_strlen_zero(var))
- continue;
- cur = ast_variable_new(var, val);
- if (head) {
- cur->next = head;
- head = cur;
- } else
- head = cur;
- }
- }
- }
-
- return head;
-}
-
-/*! \note NOTE:
- Callers of astman_send_error(), astman_send_response() or astman_send_ack() must EITHER
- hold the session lock _or_ be running in an action callback (in which case s->busy will
- be non-zero). In either of these cases, there is no need to lock-protect the session's
- fd, since no other output will be sent (events will be queued), and no input will
- be read until either the current action finishes or get_input() obtains the session
- lock.
- */
-void astman_send_error(struct mansession *s, const struct message *m, char *error)
-{
- const char *id = astman_get_header(m,"ActionID");
-
- astman_append(s, "Response: Error\r\n");
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n", id);
- astman_append(s, "Message: %s\r\n\r\n", error);
-}
-
-void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
-{
- const char *id = astman_get_header(m,"ActionID");
-
- astman_append(s, "Response: %s\r\n", resp);
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n", id);
- if (msg)
- astman_append(s, "Message: %s\r\n\r\n", msg);
- else
- astman_append(s, "\r\n");
-}
-
-void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
-{
- astman_send_response(s, m, "Success", msg);
-}
-
-/*! Tells you if smallstr exists inside bigstr
- which is delim by delim and uses no buf or stringsep
- ast_instring("this|that|more","this",',') == 1;
-
- feel free to move this to app.c -anthm */
-static int ast_instring(const char *bigstr, const char *smallstr, char delim)
-{
- const char *val = bigstr, *next;
-
- do {
- if ((next = strchr(val, delim))) {
- if (!strncmp(val, smallstr, (next - val)))
- return 1;
- else
- continue;
- } else
- return !strcmp(smallstr, val);
-
- } while (*(val = (next + 1)));
-
- return 0;
-}
-
-static int get_perm(const char *instr)
-{
- int x = 0, ret = 0;
-
- if (!instr)
- return 0;
-
- for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) {
- if (ast_instring(instr, perms[x].label, ','))
- ret |= perms[x].num;
- }
-
- return ret;
-}
-
-static int ast_is_number(const char *string)
-{
- int ret = 1, x = 0;
-
- if (!string)
- return 0;
-
- for (x = 0; x < strlen(string); x++) {
- if (!(string[x] >= 48 && string[x] <= 57)) {
- ret = 0;
- break;
- }
- }
-
- return ret ? atoi(string) : 0;
-}
-
-static int strings_to_mask(const char *string)
-{
- int x, ret = -1;
-
- x = ast_is_number(string);
-
- if (x)
- ret = x;
- else if (ast_strlen_zero(string))
- ret = -1;
- else if (ast_false(string))
- ret = 0;
- else if (ast_true(string)) {
- ret = 0;
- for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++)
- ret |= perms[x].num;
- } else {
- ret = 0;
- for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) {
- if (ast_instring(string, perms[x].label, ','))
- ret |= perms[x].num;
- }
- }
-
- return ret;
-}
-
-/*! \brief
- Rather than braindead on,off this now can also accept a specific int mask value
- or a ',' delim list of mask strings (the same as manager.conf) -anthm
-*/
-static int set_eventmask(struct mansession *s, const char *eventmask)
-{
- int maskint = strings_to_mask(eventmask);
-
- ast_mutex_lock(&s->__lock);
- if (maskint >= 0)
- s->send_events = maskint;
- ast_mutex_unlock(&s->__lock);
-
- return maskint;
-}
-
-static int authenticate(struct mansession *s, const struct message *m)
-{
- struct ast_config *cfg;
- char *cat;
- const char *user = astman_get_header(m, "Username");
- const char *pass = astman_get_header(m, "Secret");
- const char *authtype = astman_get_header(m, "AuthType");
- const char *key = astman_get_header(m, "Key");
- const char *events = astman_get_header(m, "Events");
-
- cfg = ast_config_load("manager.conf");
- if (!cfg)
- return -1;
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- if (strcasecmp(cat, "general")) {
- /* This is a user */
- if (!strcasecmp(cat, user)) {
- struct ast_variable *v;
- struct ast_ha *ha = NULL;
- char *password = NULL;
-
- for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
- if (!strcasecmp(v->name, "secret")) {
- password = v->value;
- } else if (!strcasecmp(v->name, "displaysystemname")) {
- if (ast_true(v->value)) {
- if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
- s->displaysystemname = 1;
- } else {
- ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n");
- }
- }
- } else if (!strcasecmp(v->name, "permit") ||
- !strcasecmp(v->name, "deny")) {
- ha = ast_append_ha(v->name, v->value, ha);
- } else if (!strcasecmp(v->name, "writetimeout")) {
- int val = atoi(v->value);
-
- if (val < 100)
- ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno);
- else
- s->writetimeout = val;
- }
-
- }
- if (ha && !ast_apply_ha(ha, &(s->sin))) {
- ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
- ast_free_ha(ha);
- ast_config_destroy(cfg);
- return -1;
- } else if (ha)
- ast_free_ha(ha);
- if (!strcasecmp(authtype, "MD5")) {
- if (!ast_strlen_zero(key) &&
- !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) {
- int x;
- int len = 0;
- char md5key[256] = "";
- struct MD5Context md5;
- unsigned char digest[16];
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge));
- MD5Update(&md5, (unsigned char *) password, strlen(password));
- MD5Final(digest, &md5);
- for (x=0; x<16; x++)
- len += sprintf(md5key + len, "%2.2x", digest[x]);
- if (!strcmp(md5key, key))
- break;
- else {
- ast_config_destroy(cfg);
- return -1;
- }
- } else {
- ast_log(LOG_DEBUG, "MD5 authentication is not possible. challenge: '%s'\n",
- S_OR(s->challenge, ""));
- ast_config_destroy(cfg);
- return -1;
- }
- } else if (password && !strcmp(password, pass)) {
- break;
- } else {
- ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
- ast_config_destroy(cfg);
- return -1;
- }
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
- if (cat) {
- ast_copy_string(s->username, cat, sizeof(s->username));
- s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read"));
- s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write"));
- ast_config_destroy(cfg);
- if (events)
- set_eventmask(s, events);
- return 0;
- }
- ast_config_destroy(cfg);
- cfg = ast_config_load("users.conf");
- if (!cfg)
- return -1;
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- struct ast_variable *v;
- const char *password = NULL;
- int hasmanager = 0;
- const char *readperms = NULL;
- const char *writeperms = NULL;
-
- if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) {
- cat = ast_category_browse(cfg, cat);
- continue;
- }
- for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
- if (!strcasecmp(v->name, "secret"))
- password = v->value;
- else if (!strcasecmp(v->name, "hasmanager"))
- hasmanager = ast_true(v->value);
- else if (!strcasecmp(v->name, "managerread"))
- readperms = v->value;
- else if (!strcasecmp(v->name, "managerwrite"))
- writeperms = v->value;
- }
- if (!hasmanager)
- break;
- if (!password || strcmp(password, pass)) {
- ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
- ast_config_destroy(cfg);
- return -1;
- }
- ast_copy_string(s->username, cat, sizeof(s->username));
- s->readperm = readperms ? get_perm(readperms) : -1;
- s->writeperm = writeperms ? get_perm(writeperms) : -1;
- ast_config_destroy(cfg);
- if (events)
- set_eventmask(s, events);
- return 0;
- }
- ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
- ast_config_destroy(cfg);
- return -1;
-}
-
-/*! \brief Manager PING */
-static char mandescr_ping[] =
-"Description: A 'Ping' action will ellicit a 'Pong' response. Used to keep the\n"
-" manager connection open.\n"
-"Variables: NONE\n";
-
-static int action_ping(struct mansession *s, const struct message *m)
-{
- astman_send_response(s, m, "Pong", NULL);
- return 0;
-}
-
-static char mandescr_getconfig[] =
-"Description: A 'GetConfig' action will dump the contents of a configuration\n"
-"file by category and contents.\n"
-"Variables:\n"
-" Filename: Configuration filename (e.g. foo.conf)\n";
-
-static int action_getconfig(struct mansession *s, const struct message *m)
-{
- struct ast_config *cfg;
- const char *fn = astman_get_header(m, "Filename");
- int catcount = 0;
- int lineno = 0;
- char *category=NULL;
- struct ast_variable *v;
- char idText[256] = "";
- const char *id = astman_get_header(m, "ActionID");
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- if (ast_strlen_zero(fn)) {
- astman_send_error(s, m, "Filename not specified");
- return 0;
- }
- if (!(cfg = ast_config_load_with_comments(fn))) {
- astman_send_error(s, m, "Config file not found");
- return 0;
- }
- astman_append(s, "Response: Success\r\n%s", idText);
- while ((category = ast_category_browse(cfg, category))) {
- lineno = 0;
- astman_append(s, "Category-%06d: %s\r\n", catcount, category);
- for (v = ast_variable_browse(cfg, category); v; v = v->next)
- astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
- catcount++;
- }
- ast_config_destroy(cfg);
- astman_append(s, "\r\n");
-
- return 0;
-}
-
-
-static void handle_updates(struct mansession *s, const struct message *m, struct ast_config *cfg)
-{
- int x;
- char hdr[40];
- const char *action, *cat, *var, *value, *match;
- struct ast_category *category;
- struct ast_variable *v;
-
- for (x=0;x<100000;x++) {
- unsigned int object = 0;
-
- snprintf(hdr, sizeof(hdr), "Action-%06d", x);
- action = astman_get_header(m, hdr);
- if (ast_strlen_zero(action))
- break;
- snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
- cat = astman_get_header(m, hdr);
- snprintf(hdr, sizeof(hdr), "Var-%06d", x);
- var = astman_get_header(m, hdr);
- snprintf(hdr, sizeof(hdr), "Value-%06d", x);
- value = astman_get_header(m, hdr);
- if (!ast_strlen_zero(value) && *value == '>') {
- object = 1;
- value++;
- }
- snprintf(hdr, sizeof(hdr), "Match-%06d", x);
- match = astman_get_header(m, hdr);
- if (!strcasecmp(action, "newcat")) {
- if (!ast_strlen_zero(cat)) {
- category = ast_category_new(cat);
- if (category) {
- ast_category_append(cfg, category);
- }
- }
- } else if (!strcasecmp(action, "renamecat")) {
- if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) {
- category = ast_category_get(cfg, cat);
- if (category)
- ast_category_rename(category, value);
- }
- } else if (!strcasecmp(action, "delcat")) {
- if (!ast_strlen_zero(cat))
- ast_category_delete(cfg, (char *) cat);
- } else if (!strcasecmp(action, "update")) {
- if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
- ast_variable_update(category, var, value, match, object);
- } else if (!strcasecmp(action, "delete")) {
- if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
- ast_variable_delete(category, (char *) var, (char *) match);
- } else if (!strcasecmp(action, "append")) {
- if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) &&
- (category = ast_category_get(cfg, cat)) &&
- (v = ast_variable_new(var, value))){
- if (object || (match && !strcasecmp(match, "object")))
- v->object = 1;
- ast_variable_append(category, v);
- }
- }
- }
-}
-
-static char mandescr_updateconfig[] =
-"Description: A 'UpdateConfig' action will modify, create, or delete\n"
-"configuration elements in Asterisk configuration files.\n"
-"Variables (X's represent 6 digit number beginning with 000000):\n"
-" SrcFilename: Configuration filename to read(e.g. foo.conf)\n"
-" DstFilename: Configuration filename to write(e.g. foo.conf)\n"
-" Reload: Whether or not a reload should take place (or name of specific module)\n"
-" Action-XXXXXX: Action to Take (NewCat,RenameCat,DelCat,Update,Delete,Append)\n"
-" Cat-XXXXXX: Category to operate on\n"
-" Var-XXXXXX: Variable to work on\n"
-" Value-XXXXXX: Value to work on\n"
-" Match-XXXXXX: Extra match required to match line\n";
-
-static int action_updateconfig(struct mansession *s, const struct message *m)
-{
- struct ast_config *cfg;
- const char *sfn = astman_get_header(m, "SrcFilename");
- const char *dfn = astman_get_header(m, "DstFilename");
- int res;
- char idText[256] = "";
- const char *id = astman_get_header(m, "ActionID");
- const char *rld = astman_get_header(m, "Reload");
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
- astman_send_error(s, m, "Filename not specified");
- return 0;
- }
- if (!(cfg = ast_config_load_with_comments(sfn))) {
- astman_send_error(s, m, "Config file not found");
- return 0;
- }
- handle_updates(s, m, cfg);
- res = config_text_file_save(dfn, cfg, "Manager");
- ast_config_destroy(cfg);
- if (res) {
- astman_send_error(s, m, "Save of config failed");
- return 0;
- }
- astman_append(s, "Response: Success\r\n%s\r\n", idText);
- if (!ast_strlen_zero(rld)) {
- if (ast_true(rld))
- rld = NULL;
- ast_module_reload(rld);
- }
- return 0;
-}
-
-/*! \brief Manager WAITEVENT */
-static char mandescr_waitevent[] =
-"Description: A 'WaitEvent' action will ellicit a 'Success' response. Whenever\n"
-"a manager event is queued. Once WaitEvent has been called on an HTTP manager\n"
-"session, events will be generated and queued.\n"
-"Variables: \n"
-" Timeout: Maximum time to wait for events\n";
-
-static int action_waitevent(struct mansession *s, const struct message *m)
-{
- const char *timeouts = astman_get_header(m, "Timeout");
- int timeout = -1, max;
- int x;
- int needexit = 0;
- time_t now;
- struct eventqent *eqe;
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- if (!ast_strlen_zero(timeouts)) {
- sscanf(timeouts, "%i", &timeout);
- }
-
- ast_mutex_lock(&s->__lock);
- if (s->waiting_thread != AST_PTHREADT_NULL) {
- pthread_kill(s->waiting_thread, SIGURG);
- }
- if (s->sessiontimeout) {
- time(&now);
- max = s->sessiontimeout - now - 10;
- if (max < 0)
- max = 0;
- if ((timeout < 0) || (timeout > max))
- timeout = max;
- if (!s->send_events)
- s->send_events = -1;
- /* Once waitevent is called, always queue events from now on */
- }
- ast_mutex_unlock(&s->__lock);
- s->waiting_thread = pthread_self();
- if (option_debug)
- ast_log(LOG_DEBUG, "Starting waiting for an event!\n");
- for (x=0; ((x < timeout) || (timeout < 0)); x++) {
- ast_mutex_lock(&s->__lock);
- if (s->eventq && s->eventq->next)
- needexit = 1;
- if (s->waiting_thread != pthread_self())
- needexit = 1;
- if (s->needdestroy)
- needexit = 1;
- ast_mutex_unlock(&s->__lock);
- if (needexit)
- break;
- if (s->fd > 0) {
- if (ast_wait_for_input(s->fd, 1000))
- break;
- } else {
- sleep(1);
- }
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Finished waiting for an event!\n");
- ast_mutex_lock(&s->__lock);
- if (s->waiting_thread == pthread_self()) {
- astman_send_response(s, m, "Success", "Waiting for Event...");
- /* Only show events if we're the most recent waiter */
- while(s->eventq->next) {
- eqe = s->eventq->next;
- if (((s->readperm & eqe->category) == eqe->category) &&
- ((s->send_events & eqe->category) == eqe->category)) {
- astman_append(s, "%s", eqe->eventdata);
- }
- unuse_eventqent(s->eventq);
- s->eventq = eqe;
- }
- astman_append(s,
- "Event: WaitEventComplete\r\n"
- "%s"
- "\r\n", idText);
- s->waiting_thread = AST_PTHREADT_NULL;
- } else {
- ast_log(LOG_DEBUG, "Abandoning event request!\n");
- }
- ast_mutex_unlock(&s->__lock);
- return 0;
-}
-
-static char mandescr_listcommands[] =
-"Description: Returns the action name and synopsis for every\n"
-" action that is available to the user\n"
-"Variables: NONE\n";
-
-/*! \note The actionlock is read-locked by the caller of this function */
-static int action_listcommands(struct mansession *s, const struct message *m)
-{
- struct manager_action *cur;
- char idText[256] = "";
- char temp[BUFSIZ];
- const char *id = astman_get_header(m,"ActionID");
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- astman_append(s, "Response: Success\r\n%s", idText);
- for (cur = first_action; cur; cur = cur->next) {
- if ((s->writeperm & cur->authority) == cur->authority)
- astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp)));
- }
- astman_append(s, "\r\n");
-
- return 0;
-}
-
-static char mandescr_events[] =
-"Description: Enable/Disable sending of events to this manager\n"
-" client.\n"
-"Variables:\n"
-" EventMask: 'on' if all events should be sent,\n"
-" 'off' if no events should be sent,\n"
-" 'system,call,log' to select which flags events should have to be sent.\n";
-
-static int action_events(struct mansession *s, const struct message *m)
-{
- const char *mask = astman_get_header(m, "EventMask");
- int res;
-
- res = set_eventmask(s, mask);
- if (res > 0)
- astman_send_response(s, m, "Events On", NULL);
- else if (res == 0)
- astman_send_response(s, m, "Events Off", NULL);
-
- return 0;
-}
-
-static char mandescr_logoff[] =
-"Description: Logoff this manager session\n"
-"Variables: NONE\n";
-
-static int action_logoff(struct mansession *s, const struct message *m)
-{
- astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
- return -1;
-}
-
-static char mandescr_hangup[] =
-"Description: Hangup a channel\n"
-"Variables: \n"
-" Channel: The channel name to be hungup\n";
-
-static int action_hangup(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- if (ast_strlen_zero(name)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(c);
- astman_send_ack(s, m, "Channel Hungup");
- return 0;
-}
-
-static char mandescr_setvar[] =
-"Description: Set a global or local channel variable.\n"
-"Variables: (Names marked with * are required)\n"
-" Channel: Channel to set variable for\n"
-" *Variable: Variable name\n"
-" *Value: Value\n";
-
-static int action_setvar(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- const char *varname = astman_get_header(m, "Variable");
- const char *varval = astman_get_header(m, "Value");
-
- if (ast_strlen_zero(varname)) {
- astman_send_error(s, m, "No variable specified");
- return 0;
- }
-
- if (!ast_strlen_zero(name)) {
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- }
-
- pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
-
- if (c)
- ast_channel_unlock(c);
-
- astman_send_ack(s, m, "Variable Set");
-
- return 0;
-}
-
-static char mandescr_getvar[] =
-"Description: Get the value of a global or local channel variable.\n"
-"Variables: (Names marked with * are required)\n"
-" Channel: Channel to read variable from\n"
-" *Variable: Variable name\n"
-" ActionID: Optional Action id for message matching.\n";
-
-static int action_getvar(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- const char *varname = astman_get_header(m, "Variable");
- const char *id = astman_get_header(m,"ActionID");
- char *varval;
- char workspace[1024] = "";
-
- if (ast_strlen_zero(varname)) {
- astman_send_error(s, m, "No variable specified");
- return 0;
- }
-
- if (!ast_strlen_zero(name)) {
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- }
-
- if (varname[strlen(varname) - 1] == ')') {
- char *copy = ast_strdupa(varname);
-
- ast_func_read(c, copy, workspace, sizeof(workspace));
- varval = workspace;
- } else {
- pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
- }
-
- if (c)
- ast_channel_unlock(c);
- astman_append(s, "Response: Success\r\n"
- "Variable: %s\r\nValue: %s\r\n", varname, varval);
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n",id);
- astman_append(s, "\r\n");
-
- return 0;
-}
-
-
-/*! \brief Manager "status" command to show channels */
-/* Needs documentation... */
-static int action_status(struct mansession *s, const struct message *m)
-{
- const char *id = astman_get_header(m,"ActionID");
- const char *name = astman_get_header(m,"Channel");
- char idText[256] = "";
- struct ast_channel *c;
- char bridge[256];
- struct timeval now = ast_tvnow();
- long elapsed_seconds = 0;
- int all = ast_strlen_zero(name); /* set if we want all channels */
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- if (all)
- c = ast_channel_walk_locked(NULL);
- else {
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- }
- astman_send_ack(s, m, "Channel status will follow");
- /* if we look by name, we break after the first iteration */
- while (c) {
- if (c->_bridge)
- snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name);
- else
- bridge[0] = '\0';
- if (c->pbx) {
- if (c->cdr) {
- elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
- }
- astman_append(s,
- "Event: Status\r\n"
- "Privilege: Call\r\n"
- "Channel: %s\r\n"
- "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Account: %s\r\n"
- "State: %s\r\n"
- "Context: %s\r\n"
- "Extension: %s\r\n"
- "Priority: %d\r\n"
- "Seconds: %ld\r\n"
- "%s"
- "Uniqueid: %s\r\n"
- "%s"
- "\r\n",
- c->name,
- S_OR(c->cid.cid_num, "<unknown>"),
- S_OR(c->cid.cid_num, "<unknown>"),
- S_OR(c->cid.cid_name, "<unknown>"),
- c->accountcode,
- ast_state2str(c->_state), c->context,
- c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText);
- } else {
- astman_append(s,
- "Event: Status\r\n"
- "Privilege: Call\r\n"
- "Channel: %s\r\n"
- "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Account: %s\r\n"
- "State: %s\r\n"
- "%s"
- "Uniqueid: %s\r\n"
- "%s"
- "\r\n",
- c->name,
- S_OR(c->cid.cid_num, "<unknown>"),
- S_OR(c->cid.cid_num, "<unknown>"),
- S_OR(c->cid.cid_name, "<unknown>"),
- c->accountcode,
- ast_state2str(c->_state), bridge, c->uniqueid, idText);
- }
- ast_channel_unlock(c);
- if (!all)
- break;
- c = ast_channel_walk_locked(c);
- }
- astman_append(s,
- "Event: StatusComplete\r\n"
- "%s"
- "\r\n",idText);
- return 0;
-}
-
-static char mandescr_redirect[] =
-"Description: Redirect (transfer) a call.\n"
-"Variables: (Names marked with * are required)\n"
-" *Channel: Channel to redirect\n"
-" ExtraChannel: Second call leg to transfer (optional)\n"
-" *Exten: Extension to transfer to\n"
-" *Context: Context to transfer to\n"
-" *Priority: Priority to transfer to\n"
-" ActionID: Optional Action id for message matching.\n";
-
-/*! \brief action_redirect: The redirect manager command */
-static int action_redirect(struct mansession *s, const struct message *m)
-{
- const char *name = astman_get_header(m, "Channel");
- const char *name2 = astman_get_header(m, "ExtraChannel");
- const char *exten = astman_get_header(m, "Exten");
- const char *context = astman_get_header(m, "Context");
- const char *priority = astman_get_header(m, "Priority");
- struct ast_channel *chan, *chan2 = NULL;
- int pi = 0;
- int res;
-
- if (ast_strlen_zero(name)) {
- astman_send_error(s, m, "Channel not specified");
- return 0;
- }
- if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
- if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
- astman_send_error(s, m, "Invalid priority\n");
- return 0;
- }
- }
- /* XXX watch out, possible deadlock!!! */
- chan = ast_get_channel_by_name_locked(name);
- if (!chan) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
- astman_send_error(s, m, buf);
- return 0;
- }
- if (ast_check_hangup(chan)) {
- astman_send_error(s, m, "Redirect failed, channel not up.\n");
- ast_channel_unlock(chan);
- return 0;
- }
- if (!ast_strlen_zero(name2))
- chan2 = ast_get_channel_by_name_locked(name2);
- if (chan2 && ast_check_hangup(chan2)) {
- astman_send_error(s, m, "Redirect failed, extra channel not up.\n");
- ast_channel_unlock(chan);
- ast_channel_unlock(chan2);
- return 0;
- }
- res = ast_async_goto(chan, context, exten, pi);
- if (!res) {
- if (!ast_strlen_zero(name2)) {
- if (chan2)
- res = ast_async_goto(chan2, context, exten, pi);
- else
- res = -1;
- if (!res)
- astman_send_ack(s, m, "Dual Redirect successful");
- else
- astman_send_error(s, m, "Secondary redirect failed");
- } else
- astman_send_ack(s, m, "Redirect successful");
- } else
- astman_send_error(s, m, "Redirect failed");
- if (chan)
- ast_channel_unlock(chan);
- if (chan2)
- ast_channel_unlock(chan2);
- return 0;
-}
-
-static char mandescr_command[] =
-"Description: Run a CLI command.\n"
-"Variables: (Names marked with * are required)\n"
-" *Command: Asterisk CLI command to run\n"
-" ActionID: Optional Action id for message matching.\n";
-
-/*! \brief action_command: Manager command "command" - execute CLI command */
-static int action_command(struct mansession *s, const struct message *m)
-{
- const char *cmd = astman_get_header(m, "Command");
- const char *id = astman_get_header(m, "ActionID");
- char *buf, *final_buf;
- char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
- int fd = mkstemp(template), i = 0;
- off_t l;
-
- for (i = 0; i < sizeof(command_blacklist) / sizeof(command_blacklist[0]); i++) {
- if (!strncmp(cmd, command_blacklist[i], strlen(command_blacklist[i]))) {
- astman_send_error(s, m, "Command blacklisted");
- return 0;
- }
- }
-
- astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n", id);
- /* FIXME: Wedge a ActionID response in here, waiting for later changes */
- ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */
- l = lseek(fd, 0, SEEK_END); /* how many chars available */
-
- /* This has a potential to overflow the stack. Hence, use the heap. */
- buf = ast_calloc(1, l + 1);
- final_buf = ast_calloc(1, l + 1);
- if (buf) {
- lseek(fd, 0, SEEK_SET);
- read(fd, buf, l);
- buf[l] = '\0';
- if (final_buf) {
- term_strip(final_buf, buf, l);
- final_buf[l] = '\0';
- }
- astman_append(s, "%s", S_OR(final_buf, buf));
- ast_free(buf);
- }
- close(fd);
- unlink(template);
- astman_append(s, "--END COMMAND--\r\n\r\n");
- if (final_buf)
- ast_free(final_buf);
- return 0;
-}
-
-static void *fast_originate(void *data)
-{
- struct fast_originate_helper *in = data;
- int res;
- int reason = 0;
- struct ast_channel *chan = NULL;
- char requested_channel[AST_CHANNEL_NAME];
-
- if (!ast_strlen_zero(in->app)) {
- res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1,
- S_OR(in->cid_num, NULL),
- S_OR(in->cid_name, NULL),
- in->vars, in->account, &chan);
- } else {
- res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
- S_OR(in->cid_num, NULL),
- S_OR(in->cid_name, NULL),
- in->vars, in->account, &chan);
- }
-
- if (!chan)
- snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
- /* Tell the manager what happened with the channel */
- manager_event(EVENT_FLAG_CALL, "OriginateResponse",
- "%s"
- "Response: %s\r\n"
- "Channel: %s\r\n"
- "Context: %s\r\n"
- "Exten: %s\r\n"
- "Reason: %d\r\n"
- "Uniqueid: %s\r\n"
- "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n",
- in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason,
- chan ? chan->uniqueid : "<null>",
- S_OR(in->cid_num, "<unknown>"),
- S_OR(in->cid_num, "<unknown>"),
- S_OR(in->cid_name, "<unknown>")
- );
-
- /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
- if (chan)
- ast_channel_unlock(chan);
- free(in);
- return NULL;
-}
-
-static char mandescr_originate[] =
-"Description: Generates an outgoing call to a Extension/Context/Priority or\n"
-" Application/Data\n"
-"Variables: (Names marked with * are required)\n"
-" *Channel: Channel name to call\n"
-" Exten: Extension to use (requires 'Context' and 'Priority')\n"
-" Context: Context to use (requires 'Exten' and 'Priority')\n"
-" Priority: Priority to use (requires 'Exten' and 'Context')\n"
-" Application: Application to use\n"
-" Data: Data to use (requires 'Application')\n"
-" Timeout: How long to wait for call to be answered (in ms)\n"
-" CallerID: Caller ID to be set on the outgoing channel\n"
-" Variable: Channel variable to set, multiple Variable: headers are allowed\n"
-" Account: Account code\n"
-" Async: Set to 'true' for fast origination\n";
-
-static int action_originate(struct mansession *s, const struct message *m)
-{
- const char *name = astman_get_header(m, "Channel");
- const char *exten = astman_get_header(m, "Exten");
- const char *context = astman_get_header(m, "Context");
- const char *priority = astman_get_header(m, "Priority");
- const char *timeout = astman_get_header(m, "Timeout");
- const char *callerid = astman_get_header(m, "CallerID");
- const char *account = astman_get_header(m, "Account");
- const char *app = astman_get_header(m, "Application");
- const char *appdata = astman_get_header(m, "Data");
- const char *async = astman_get_header(m, "Async");
- const char *id = astman_get_header(m, "ActionID");
- struct ast_variable *vars = astman_get_variables(m);
- char *tech, *data;
- char *l = NULL, *n = NULL;
- int pi = 0;
- int res;
- int to = 30000;
- int reason = 0;
- char tmp[256];
- char tmp2[256];
-
- pthread_t th;
- pthread_attr_t attr;
- if (!name) {
- astman_send_error(s, m, "Channel not specified");
- return 0;
- }
- if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
- if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
- astman_send_error(s, m, "Invalid priority\n");
- return 0;
- }
- }
- if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) {
- astman_send_error(s, m, "Invalid timeout\n");
- return 0;
- }
- ast_copy_string(tmp, name, sizeof(tmp));
- tech = tmp;
- data = strchr(tmp, '/');
- if (!data) {
- astman_send_error(s, m, "Invalid channel\n");
- return 0;
- }
- *data++ = '\0';
- ast_copy_string(tmp2, callerid, sizeof(tmp2));
- ast_callerid_parse(tmp2, &n, &l);
- if (n) {
- if (ast_strlen_zero(n))
- n = NULL;
- }
- if (l) {
- ast_shrink_phone_number(l);
- if (ast_strlen_zero(l))
- l = NULL;
- }
- if (ast_true(async)) {
- struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
- if (!fast) {
- res = -1;
- } else {
- if (!ast_strlen_zero(id))
- snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id);
- ast_copy_string(fast->tech, tech, sizeof(fast->tech));
- ast_copy_string(fast->data, data, sizeof(fast->data));
- ast_copy_string(fast->app, app, sizeof(fast->app));
- ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
- if (l)
- ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
- if (n)
- ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
- fast->vars = vars;
- ast_copy_string(fast->context, context, sizeof(fast->context));
- ast_copy_string(fast->exten, exten, sizeof(fast->exten));
- ast_copy_string(fast->account, account, sizeof(fast->account));
- fast->timeout = to;
- fast->priority = pi;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create(&th, &attr, fast_originate, fast)) {
- res = -1;
- } else {
- res = 0;
- }
- pthread_attr_destroy(&attr);
- }
- } else if (!ast_strlen_zero(app)) {
- res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
- } else {
- if (exten && context && pi)
- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
- else {
- astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
- return 0;
- }
- }
- if (!res)
- astman_send_ack(s, m, "Originate successfully queued");
- else
- astman_send_error(s, m, "Originate failed");
- return 0;
-}
-
-/*! \brief Help text for manager command mailboxstatus
- */
-static char mandescr_mailboxstatus[] =
-"Description: Checks a voicemail account for status.\n"
-"Variables: (Names marked with * are required)\n"
-" *Mailbox: Full mailbox ID <mailbox>@<vm-context>\n"
-" ActionID: Optional ActionID for message matching.\n"
-"Returns number of messages.\n"
-" Message: Mailbox Status\n"
-" Mailbox: <mailboxid>\n"
-" Waiting: <count>\n"
-"\n";
-
-static int action_mailboxstatus(struct mansession *s, const struct message *m)
-{
- const char *mailbox = astman_get_header(m, "Mailbox");
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
- int ret;
- if (ast_strlen_zero(mailbox)) {
- astman_send_error(s, m, "Mailbox not specified");
- return 0;
- }
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- ret = ast_app_has_voicemail(mailbox, NULL);
- astman_append(s, "Response: Success\r\n"
- "%s"
- "Message: Mailbox Status\r\n"
- "Mailbox: %s\r\n"
- "Waiting: %d\r\n\r\n", idText, mailbox, ret);
- return 0;
-}
-
-static char mandescr_mailboxcount[] =
-"Description: Checks a voicemail account for new messages.\n"
-"Variables: (Names marked with * are required)\n"
-" *Mailbox: Full mailbox ID <mailbox>@<vm-context>\n"
-" ActionID: Optional ActionID for message matching.\n"
-"Returns number of new and old messages.\n"
-" Message: Mailbox Message Count\n"
-" Mailbox: <mailboxid>\n"
-" NewMessages: <count>\n"
-" OldMessages: <count>\n"
-"\n";
-static int action_mailboxcount(struct mansession *s, const struct message *m)
-{
- const char *mailbox = astman_get_header(m, "Mailbox");
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
- int newmsgs = 0, oldmsgs = 0;
- if (ast_strlen_zero(mailbox)) {
- astman_send_error(s, m, "Mailbox not specified");
- return 0;
- }
- ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
- if (!ast_strlen_zero(id)) {
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id);
- }
- astman_append(s, "Response: Success\r\n"
- "%s"
- "Message: Mailbox Message Count\r\n"
- "Mailbox: %s\r\n"
- "NewMessages: %d\r\n"
- "OldMessages: %d\r\n"
- "\r\n",
- idText,mailbox, newmsgs, oldmsgs);
- return 0;
-}
-
-static char mandescr_extensionstate[] =
-"Description: Report the extension state for given extension.\n"
-" If the extension has a hint, will use devicestate to check\n"
-" the status of the device connected to the extension.\n"
-"Variables: (Names marked with * are required)\n"
-" *Exten: Extension to check state on\n"
-" *Context: Context for extension\n"
-" ActionId: Optional ID for this transaction\n"
-"Will return an \"Extension Status\" message.\n"
-"The response will include the hint for the extension and the status.\n";
-
-static int action_extensionstate(struct mansession *s, const struct message *m)
-{
- const char *exten = astman_get_header(m, "Exten");
- const char *context = astman_get_header(m, "Context");
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
- char hint[256] = "";
- int status;
- if (ast_strlen_zero(exten)) {
- astman_send_error(s, m, "Extension not specified");
- return 0;
- }
- if (ast_strlen_zero(context))
- context = "default";
- status = ast_extension_state(NULL, context, exten);
- ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
- if (!ast_strlen_zero(id)) {
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- }
- astman_append(s, "Response: Success\r\n"
- "%s"
- "Message: Extension Status\r\n"
- "Exten: %s\r\n"
- "Context: %s\r\n"
- "Hint: %s\r\n"
- "Status: %d\r\n\r\n",
- idText,exten, context, hint, status);
- return 0;
-}
-
-static char mandescr_timeout[] =
-"Description: Hangup a channel after a certain time.\n"
-"Variables: (Names marked with * are required)\n"
-" *Channel: Channel name to hangup\n"
-" *Timeout: Maximum duration of the call (sec)\n"
-"Acknowledges set time with 'Timeout Set' message\n";
-
-static int action_timeout(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- int timeout = atoi(astman_get_header(m, "Timeout"));
- if (ast_strlen_zero(name)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- if (!timeout) {
- astman_send_error(s, m, "No timeout specified");
- return 0;
- }
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- ast_channel_setwhentohangup(c, timeout);
- ast_channel_unlock(c);
- astman_send_ack(s, m, "Timeout Set");
- return 0;
-}
-
-static int process_events(struct mansession *s)
-{
- struct eventqent *eqe;
- int ret = 0;
- ast_mutex_lock(&s->__lock);
- if (!s->eventq)
- s->eventq = master_eventq;
- while(s->eventq->next) {
- eqe = s->eventq->next;
- if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) &&
- ((s->send_events & eqe->category) == eqe->category)) {
- if (s->fd > -1) {
- if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0)
- ret = -1;
- } else if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr))))
- ret = -1;
- else
- ast_dynamic_str_append(&s->outputstr, 0, "%s", eqe->eventdata);
- }
- unuse_eventqent(s->eventq);
- s->eventq = eqe;
- }
- ast_mutex_unlock(&s->__lock);
- return ret;
-}
-
-static char mandescr_userevent[] =
-"Description: Send an event to manager sessions.\n"
-"Variables: (Names marked with * are required)\n"
-" *UserEvent: EventStringToSend\n"
-" Header1: Content1\n"
-" HeaderN: ContentN\n";
-
-static int action_userevent(struct mansession *s, const struct message *m)
-{
- const char *event = astman_get_header(m, "UserEvent");
- char body[2048] = "";
- int x, bodylen = 0;
- for (x = 0; x < m->hdrcount; x++) {
- if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
- ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3);
- bodylen += strlen(m->headers[x]);
- ast_copy_string(body + bodylen, "\r\n", 3);
- bodylen += 2;
- }
- }
-
- manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body);
- return 0;
-}
-
-static int process_message(struct mansession *s, const struct message *m)
-{
- char action[80] = "";
- struct manager_action *tmp;
- const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
- int ret = 0;
-
- ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
- if (option_debug)
- ast_log( LOG_DEBUG, "Manager received command '%s'\n", action );
-
- if (ast_strlen_zero(action)) {
- astman_send_error(s, m, "Missing action in request");
- return 0;
- }
- if (!ast_strlen_zero(id)) {
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- }
- if (!s->authenticated) {
- if (!strcasecmp(action, "Challenge")) {
- const char *authtype = astman_get_header(m, "AuthType");
-
- if (!strcasecmp(authtype, "MD5")) {
- if (ast_strlen_zero(s->challenge))
- snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random());
- astman_append(s, "Response: Success\r\n"
- "%s"
- "Challenge: %s\r\n\r\n",
- idText, s->challenge);
- return 0;
- } else {
- astman_send_error(s, m, "Must specify AuthType");
- return 0;
- }
- } else if (!strcasecmp(action, "Login")) {
- if (authenticate(s, m)) {
- sleep(1);
- astman_send_error(s, m, "Authentication failed");
- return -1;
- } else {
- s->authenticated = 1;
- if (option_verbose > 1) {
- if (displayconnects) {
- ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n",
- (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
- }
- }
- ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n",
- (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
- astman_send_ack(s, m, "Authentication accepted");
- }
- } else if (!strcasecmp(action, "Logoff")) {
- astman_send_ack(s, m, "See ya");
- return -1;
- } else
- astman_send_error(s, m, "Authentication Required");
- } else {
- if (!strcasecmp(action, "Login"))
- astman_send_ack(s, m, "Already logged in");
- else {
- ast_rwlock_rdlock(&actionlock);
- for (tmp = first_action; tmp; tmp = tmp->next) {
- if (strcasecmp(action, tmp->action))
- continue;
- if ((s->writeperm & tmp->authority) == tmp->authority) {
- if (tmp->func(s, m))
- ret = -1;
- } else
- astman_send_error(s, m, "Permission denied");
- break;
- }
- ast_rwlock_unlock(&actionlock);
- if (!tmp)
- astman_send_error(s, m, "Invalid/unknown command");
- }
- }
- if (ret)
- return ret;
- return process_events(s);
-}
-
-static int get_input(struct mansession *s, char *output)
-{
- /* output must have at least sizeof(s->inbuf) space */
- int res;
- int x;
- struct pollfd fds[1];
- for (x = 1; x < s->inlen; x++) {
- if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
- /* Copy output data up to and including \r\n */
- memcpy(output, s->inbuf, x + 1);
- /* Add trailing \0 */
- output[x+1] = '\0';
- /* Move remaining data back to the front */
- memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
- s->inlen -= (x + 1);
- return 1;
- }
- }
- if (s->inlen >= sizeof(s->inbuf) - 1) {
- ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf);
- s->inlen = 0;
- }
- fds[0].fd = s->fd;
- fds[0].events = POLLIN;
- do {
- ast_mutex_lock(&s->__lock);
- if (s->pending_event) {
- s->pending_event = 0;
- ast_mutex_unlock(&s->__lock);
- return 0;
- }
- s->waiting_thread = pthread_self();
- ast_mutex_unlock(&s->__lock);
-
- res = poll(fds, 1, -1);
-
- ast_mutex_lock(&s->__lock);
- s->waiting_thread = AST_PTHREADT_NULL;
- ast_mutex_unlock(&s->__lock);
- if (res < 0) {
- if (errno == EINTR || errno == EAGAIN) {
- return 0;
- }
- ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
- return -1;
- } else if (res > 0) {
- ast_mutex_lock(&s->__lock);
- res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
- ast_mutex_unlock(&s->__lock);
- if (res < 1)
- return -1;
- break;
- }
- } while(1);
- s->inlen += res;
- s->inbuf[s->inlen] = '\0';
- return 0;
-}
-
-static int do_message(struct mansession *s)
-{
- struct message m = { 0 };
- char header_buf[sizeof(s->inbuf)] = { '\0' };
- int res;
-
- for (;;) {
- /* Check if any events are pending and do them if needed */
- if (s->eventq->next) {
- if (process_events(s))
- return -1;
- }
- res = get_input(s, header_buf);
- if (res == 0) {
- continue;
- } else if (res > 0) {
- /* Strip trailing \r\n */
- if (strlen(header_buf) < 2)
- continue;
- header_buf[strlen(header_buf) - 2] = '\0';
- if (ast_strlen_zero(header_buf))
- return process_message(s, &m) ? -1 : 0;
- else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
- m.headers[m.hdrcount++] = ast_strdupa(header_buf);
- } else {
- return res;
- }
- }
-}
-
-static void *session_do(void *data)
-{
- struct mansession *s = data;
- int res;
-
- astman_append(s, "Asterisk Call Manager/1.0\r\n");
- for (;;) {
- if ((res = do_message(s)) < 0)
- break;
- }
- if (s->authenticated) {
- if (option_verbose > 1) {
- if (displayconnects)
- ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
- }
- ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
- } else {
- if (option_verbose > 1) {
- if (displayconnects)
- ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
- }
- ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
- }
-
- /* It is possible under certain circumstances for this session thread
- to complete its work and exit *before* the thread that created it
- has finished executing the ast_pthread_create_background() function.
- If this occurs, some versions of glibc appear to act in a buggy
- fashion and attempt to write data into memory that it thinks belongs
- to the thread but is in fact not owned by the thread (or may have
- been freed completely).
-
- Causing this thread to yield to other threads at least one time
- appears to work around this bug.
- */
- usleep(1);
-
- destroy_session(s);
- return NULL;
-}
-
-static void *accept_thread(void *ignore)
-{
- int as;
- struct sockaddr_in sin;
- socklen_t sinlen;
- struct eventqent *eqe;
- struct mansession *s;
- struct protoent *p;
- int arg = 1;
- int flags;
- pthread_attr_t attr;
- time_t now;
- struct pollfd pfds[1];
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- for (;;) {
- time(&now);
- AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) {
- if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) {
- AST_LIST_REMOVE_CURRENT(&sessions, list);
- num_sessions--;
- if (s->authenticated && (option_verbose > 1) && displayconnects) {
- ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n",
- s->username, ast_inet_ntoa(s->sin.sin_addr));
- }
- free_session(s);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- /* Purge master event queue of old, unused events, but make sure we
- always keep at least one in the queue */
- eqe = master_eventq;
- while (master_eventq->next && !master_eventq->usecount) {
- eqe = master_eventq;
- master_eventq = master_eventq->next;
- free(eqe);
- }
- AST_LIST_UNLOCK(&sessions);
-
- sinlen = sizeof(sin);
- pfds[0].fd = asock;
- pfds[0].events = POLLIN;
- /* Wait for something to happen, but timeout every few seconds so
- we can ditch any old manager sessions */
- if (poll(pfds, 1, 5000) < 1)
- continue;
- as = accept(asock, (struct sockaddr *)&sin, &sinlen);
- if (as < 0) {
- ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
- continue;
- }
- p = getprotobyname("tcp");
- if (p) {
- if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
- ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
- }
- }
- if (!(s = ast_calloc(1, sizeof(*s))))
- continue;
-
- memcpy(&s->sin, &sin, sizeof(sin));
- s->writetimeout = 100;
- s->waiting_thread = AST_PTHREADT_NULL;
-
- if (!block_sockets) {
- /* For safety, make sure socket is non-blocking */
- flags = fcntl(as, F_GETFL);
- fcntl(as, F_SETFL, flags | O_NONBLOCK);
- } else {
- flags = fcntl(as, F_GETFL);
- fcntl(as, F_SETFL, flags & ~O_NONBLOCK);
- }
- ast_mutex_init(&s->__lock);
- s->fd = as;
- s->send_events = -1;
- AST_LIST_LOCK(&sessions);
- AST_LIST_INSERT_HEAD(&sessions, s, list);
- num_sessions++;
- /* Find the last place in the master event queue and hook ourselves
- in there */
- s->eventq = master_eventq;
- while(s->eventq->next)
- s->eventq = s->eventq->next;
- ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
- AST_LIST_UNLOCK(&sessions);
- if (ast_pthread_create_background(&s->t, &attr, session_do, s))
- destroy_session(s);
- }
- pthread_attr_destroy(&attr);
- return NULL;
-}
-
-static int append_event(const char *str, int category)
-{
- struct eventqent *tmp, *prev = NULL;
- tmp = ast_malloc(sizeof(*tmp) + strlen(str));
-
- if (!tmp)
- return -1;
-
- tmp->next = NULL;
- tmp->category = category;
- strcpy(tmp->eventdata, str);
-
- if (master_eventq) {
- prev = master_eventq;
- while (prev->next)
- prev = prev->next;
- prev->next = tmp;
- } else {
- master_eventq = tmp;
- }
-
- tmp->usecount = num_sessions;
-
- return 0;
-}
-
-/*! \brief manager_event: Send AMI event to client */
-int manager_event(int category, const char *event, const char *fmt, ...)
-{
- struct mansession *s;
- char auth[80];
- va_list ap;
- struct timeval now;
- struct ast_dynamic_str *buf;
-
- /* Abort if there aren't any manager sessions */
- if (!num_sessions)
- return 0;
-
- if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
- return -1;
-
- ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf,
- "Event: %s\r\nPrivilege: %s\r\n",
- event, authority_to_str(category, auth, sizeof(auth)));
-
- if (timestampevents) {
- now = ast_tvnow();
- ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf,
- "Timestamp: %ld.%06lu\r\n",
- now.tv_sec, (unsigned long) now.tv_usec);
- }
-
- va_start(ap, fmt);
- ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap);
- va_end(ap);
-
- ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n");
-
- /* Append event to master list and wake up any sleeping sessions */
- AST_LIST_LOCK(&sessions);
- append_event(buf->str, category);
- AST_LIST_TRAVERSE(&sessions, s, list) {
- ast_mutex_lock(&s->__lock);
- if (s->waiting_thread != AST_PTHREADT_NULL)
- pthread_kill(s->waiting_thread, SIGURG);
- else
- /* We have an event to process, but the mansession is
- * not waiting for it. We still need to indicate that there
- * is an event waiting so that get_input processes the pending
- * event instead of polling.
- */
- s->pending_event = 1;
- ast_mutex_unlock(&s->__lock);
- }
- AST_LIST_UNLOCK(&sessions);
-
- return 0;
-}
-
-int ast_manager_unregister(char *action)
-{
- struct manager_action *cur, *prev;
-
- ast_rwlock_wrlock(&actionlock);
- cur = prev = first_action;
- while (cur) {
- if (!strcasecmp(action, cur->action)) {
- prev->next = cur->next;
- free(cur);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
- ast_rwlock_unlock(&actionlock);
- return 0;
- }
- prev = cur;
- cur = cur->next;
- }
- ast_rwlock_unlock(&actionlock);
- return 0;
-}
-
-static int manager_state_cb(char *context, char *exten, int state, void *data)
-{
- /* Notify managers of change */
- manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state);
- return 0;
-}
-
-static int ast_manager_register_struct(struct manager_action *act)
-{
- struct manager_action *cur, *prev = NULL;
- int ret;
-
- ast_rwlock_wrlock(&actionlock);
- cur = first_action;
- while (cur) { /* Walk the list of actions */
- ret = strcasecmp(cur->action, act->action);
- if (ret == 0) {
- ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
- ast_rwlock_unlock(&actionlock);
- return -1;
- } else if (ret > 0) {
- /* Insert these alphabetically */
- if (prev) {
- act->next = prev->next;
- prev->next = act;
- } else {
- act->next = first_action;
- first_action = act;
- }
- break;
- }
- prev = cur;
- cur = cur->next;
- }
-
- if (!cur) {
- if (prev)
- prev->next = act;
- else
- first_action = act;
- act->next = NULL;
- }
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action);
- ast_rwlock_unlock(&actionlock);
- return 0;
-}
-
-/*! \brief register a new command with manager, including online help. This is
- the preferred way to register a manager command */
-int ast_manager_register2(const char *action, int auth, int (*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description)
-{
- struct manager_action *cur;
-
- cur = ast_malloc(sizeof(*cur));
- if (!cur)
- return -1;
-
- cur->action = action;
- cur->authority = auth;
- cur->func = func;
- cur->synopsis = synopsis;
- cur->description = description;
- cur->next = NULL;
-
- ast_manager_register_struct(cur);
-
- return 0;
-}
-/*! @}
- END Doxygen group */
-
-static struct mansession *find_session(uint32_t ident)
-{
- struct mansession *s;
-
- AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE(&sessions, s, list) {
- ast_mutex_lock(&s->__lock);
- if (s->sessiontimeout && (s->managerid == ident) && !s->needdestroy) {
- s->inuse++;
- break;
- }
- ast_mutex_unlock(&s->__lock);
- }
- AST_LIST_UNLOCK(&sessions);
-
- return s;
-}
-
-int astman_verify_session_readpermissions(uint32_t ident, int perm)
-{
- int result = 0;
- struct mansession *s;
-
- AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE(&sessions, s, list) {
- ast_mutex_lock(&s->__lock);
- if ((s->managerid == ident) && (s->readperm & perm)) {
- result = 1;
- ast_mutex_unlock(&s->__lock);
- break;
- }
- ast_mutex_unlock(&s->__lock);
- }
- AST_LIST_UNLOCK(&sessions);
- return result;
-}
-
-int astman_verify_session_writepermissions(uint32_t ident, int perm)
-{
- int result = 0;
- struct mansession *s;
-
- AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE(&sessions, s, list) {
- ast_mutex_lock(&s->__lock);
- if ((s->managerid == ident) && (s->writeperm & perm)) {
- result = 1;
- ast_mutex_unlock(&s->__lock);
- break;
- }
- ast_mutex_unlock(&s->__lock);
- }
- AST_LIST_UNLOCK(&sessions);
- return result;
-}
-
-enum {
- FORMAT_RAW,
- FORMAT_HTML,
- FORMAT_XML,
-};
-static char *contenttype[] = { "plain", "html", "xml" };
-
-static char *generic_http_callback(int format, struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
-{
- struct mansession *s = NULL;
- uint32_t ident = 0;
- char workspace[512];
- char cookie[128];
- size_t len = sizeof(workspace);
- int blastaway = 0;
- char *c = workspace;
- char *retval = NULL;
- struct ast_variable *v;
-
- for (v = params; v; v = v->next) {
- if (!strcasecmp(v->name, "mansession_id")) {
- sscanf(v->value, "%x", &ident);
- break;
- }
- }
-
- if (!(s = find_session(ident))) {
- /* Create new session */
- if (!(s = ast_calloc(1, sizeof(*s)))) {
- *status = 500;
- goto generic_callback_out;
- }
- memcpy(&s->sin, requestor, sizeof(s->sin));
- s->fd = -1;
- s->waiting_thread = AST_PTHREADT_NULL;
- s->send_events = 0;
- ast_mutex_init(&s->__lock);
- ast_mutex_lock(&s->__lock);
- s->inuse = 1;
- /*!\note There is approximately a 1 in 1.8E19 chance that the following
- * calculation will produce 0, which is an invalid ID, but due to the
- * properties of the rand() function (and the constantcy of s), that
- * won't happen twice in a row.
- */
- while ((s->managerid = rand() ^ (unsigned long) s) == 0);
- AST_LIST_LOCK(&sessions);
- AST_LIST_INSERT_HEAD(&sessions, s, list);
- /* Hook into the last spot in the event queue */
- s->eventq = master_eventq;
- while (s->eventq->next)
- s->eventq = s->eventq->next;
- ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
- ast_atomic_fetchadd_int(&num_sessions, 1);
- AST_LIST_UNLOCK(&sessions);
- }
-
- /* Reset HTTP timeout. If we're not yet authenticated, keep it extremely short */
- time(&s->sessiontimeout);
- if (!s->authenticated && (httptimeout > 5))
- s->sessiontimeout += 5;
- else
- s->sessiontimeout += httptimeout;
- ast_mutex_unlock(&s->__lock);
-
- if (s) {
- struct message m = { 0 };
- char tmp[80];
- unsigned int x;
- size_t hdrlen;
-
- for (x = 0, v = params; v && (x < AST_MAX_MANHEADERS); x++, v = v->next) {
- hdrlen = strlen(v->name) + strlen(v->value) + 3;
- m.headers[m.hdrcount] = alloca(hdrlen);
- snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", v->name, v->value);
- m.hdrcount = x + 1;
- }
-
- if (process_message(s, &m)) {
- if (s->authenticated) {
- if (option_verbose > 1) {
- if (displayconnects)
- ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
- }
- ast_log(LOG_EVENT, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
- } else {
- if (option_verbose > 1) {
- if (displayconnects)
- ast_verbose(VERBOSE_PREFIX_2 "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
- }
- ast_log(LOG_EVENT, "HTTP Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
- }
- s->needdestroy = 1;
- }
- ast_build_string(&c, &len, "Content-type: text/%s\r\n", contenttype[format]);
- sprintf(tmp, "%08x", s->managerid);
- ast_build_string(&c, &len, "%s\r\n", ast_http_setcookie("mansession_id", tmp, httptimeout, cookie, sizeof(cookie)));
- if (format == FORMAT_HTML)
- ast_build_string(&c, &len, "<title>Asterisk&trade; Manager Interface</title>");
- if (format == FORMAT_XML) {
- ast_build_string(&c, &len, "<ajax-response>\n");
- } else if (format == FORMAT_HTML) {
- ast_build_string(&c, &len, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
- ast_build_string(&c, &len, "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\"><h1>&nbsp;&nbsp;Manager Tester</h1></td></tr>\r\n");
- }
- ast_mutex_lock(&s->__lock);
- if (s->outputstr) {
- char *tmp;
- if (format == FORMAT_XML)
- tmp = xml_translate(s->outputstr->str, params);
- else if (format == FORMAT_HTML)
- tmp = html_translate(s->outputstr->str);
- else
- tmp = s->outputstr->str;
- if (tmp) {
- retval = malloc(strlen(workspace) + strlen(tmp) + 128);
- if (retval) {
- strcpy(retval, workspace);
- strcpy(retval + strlen(retval), tmp);
- c = retval + strlen(retval);
- len = 120;
- }
- }
- if (tmp != s->outputstr->str)
- free(tmp);
- free(s->outputstr);
- s->outputstr = NULL;
- }
- ast_mutex_unlock(&s->__lock);
- /* Still okay because c would safely be pointing to workspace even
- if retval failed to allocate above */
- if (format == FORMAT_XML) {
- ast_build_string(&c, &len, "</ajax-response>\n");
- } else if (format == FORMAT_HTML)
- ast_build_string(&c, &len, "</table></body>\r\n");
- } else {
- *status = 500;
- *title = strdup("Server Error");
- }
- ast_mutex_lock(&s->__lock);
- if (s->needdestroy) {
- if (s->inuse == 1) {
- ast_log(LOG_DEBUG, "Need destroy, doing it now!\n");
- blastaway = 1;
- } else {
- ast_log(LOG_DEBUG, "Need destroy, but can't do it yet!\n");
- if (s->waiting_thread != AST_PTHREADT_NULL)
- pthread_kill(s->waiting_thread, SIGURG);
- s->inuse--;
- }
- } else
- s->inuse--;
- ast_mutex_unlock(&s->__lock);
-
- if (blastaway)
- destroy_session(s);
-generic_callback_out:
- if (*status != 200)
- return ast_http_error(500, "Server Error", NULL, "Internal Server Error (out of memory)\n");
- return retval;
-}
-
-static char *manager_http_callback(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
-{
- return generic_http_callback(FORMAT_HTML, requestor, uri, params, status, title, contentlength);
-}
-
-static char *mxml_http_callback(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
-{
- return generic_http_callback(FORMAT_XML, requestor, uri, params, status, title, contentlength);
-}
-
-static char *rawman_http_callback(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
-{
- return generic_http_callback(FORMAT_RAW, requestor, uri, params, status, title, contentlength);
-}
-
-struct ast_http_uri rawmanuri = {
- .description = "Raw HTTP Manager Event Interface",
- .uri = "rawman",
- .has_subtree = 0,
- .callback = rawman_http_callback,
-};
-
-struct ast_http_uri manageruri = {
- .description = "HTML Manager Event Interface",
- .uri = "manager",
- .has_subtree = 0,
- .callback = manager_http_callback,
-};
-
-struct ast_http_uri managerxmluri = {
- .description = "XML Manager Event Interface",
- .uri = "mxml",
- .has_subtree = 0,
- .callback = mxml_http_callback,
-};
-
-static int registered = 0;
-static int webregged = 0;
-
-int init_manager(void)
-{
- struct ast_config *cfg = NULL;
- const char *val;
- char *cat = NULL;
- int oldportno = portno;
- static struct sockaddr_in ba;
- int x = 1;
- int flags;
- int webenabled = 0;
- int newhttptimeout = 60;
- struct ast_manager_user *user = NULL;
-
- if (!registered) {
- /* Register default actions */
- ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping);
- ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events);
- ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff);
- ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup);
- ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" );
- ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar );
- ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar );
- ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig);
- ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig);
- ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect );
- ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate);
- ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command );
- ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate );
- ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
- ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
- ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
- ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
- ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent);
- ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent);
-
- ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry));
- ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
- registered = 1;
- /* Append placeholder event so master_eventq never runs dry */
- append_event("Event: Placeholder\r\n\r\n", 0);
- }
- portno = DEFAULT_MANAGER_PORT;
- displayconnects = 1;
- cfg = ast_config_load("manager.conf");
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n");
- return 0;
- }
- val = ast_variable_retrieve(cfg, "general", "enabled");
- if (val)
- enabled = ast_true(val);
-
- val = ast_variable_retrieve(cfg, "general", "block-sockets");
- if (val)
- block_sockets = ast_true(val);
-
- val = ast_variable_retrieve(cfg, "general", "webenabled");
- if (val)
- webenabled = ast_true(val);
-
- if ((val = ast_variable_retrieve(cfg, "general", "port"))) {
- if (sscanf(val, "%d", &portno) != 1) {
- ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
- portno = DEFAULT_MANAGER_PORT;
- }
- }
-
- if ((val = ast_variable_retrieve(cfg, "general", "displayconnects")))
- displayconnects = ast_true(val);
-
- if ((val = ast_variable_retrieve(cfg, "general", "timestampevents")))
- timestampevents = ast_true(val);
-
- if ((val = ast_variable_retrieve(cfg, "general", "httptimeout")))
- newhttptimeout = atoi(val);
-
- memset(&ba, 0, sizeof(ba));
- ba.sin_family = AF_INET;
- ba.sin_port = htons(portno);
-
- if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) {
- if (!inet_aton(val, &ba.sin_addr)) {
- ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
- memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
- }
- }
-
-
- if ((asock > -1) && ((portno != oldportno) || !enabled)) {
-#if 0
- /* Can't be done yet */
- close(asock);
- asock = -1;
-#else
- ast_log(LOG_WARNING, "Unable to change management port / enabled\n");
-#endif
- }
-
- AST_LIST_LOCK(&users);
-
- while ((cat = ast_category_browse(cfg, cat))) {
- struct ast_variable *var = NULL;
-
- if (!strcasecmp(cat, "general"))
- continue;
-
- /* Look for an existing entry, if none found - create one and add it to the list */
- if (!(user = ast_get_manager_by_name_locked(cat))) {
- if (!(user = ast_calloc(1, sizeof(*user))))
- break;
- /* Copy name over */
- ast_copy_string(user->username, cat, sizeof(user->username));
- /* Insert into list */
- AST_LIST_INSERT_TAIL(&users, user, list);
- }
-
- /* Make sure we keep this user and don't destroy it during cleanup */
- user->keep = 1;
-
- var = ast_variable_browse(cfg, cat);
- while (var) {
- if (!strcasecmp(var->name, "secret")) {
- if (user->secret)
- free(user->secret);
- user->secret = ast_strdup(var->value);
- } else if (!strcasecmp(var->name, "deny") ) {
- if (user->deny)
- free(user->deny);
- user->deny = ast_strdup(var->value);
- } else if (!strcasecmp(var->name, "permit") ) {
- if (user->permit)
- free(user->permit);
- user->permit = ast_strdup(var->value);
- } else if (!strcasecmp(var->name, "read") ) {
- if (user->read)
- free(user->read);
- user->read = ast_strdup(var->value);
- } else if (!strcasecmp(var->name, "write") ) {
- if (user->write)
- free(user->write);
- user->write = ast_strdup(var->value);
- } else if (!strcasecmp(var->name, "displayconnects") )
- user->displayconnects = ast_true(var->value);
- else
- ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name);
- var = var->next;
- }
- }
-
- /* Perform cleanup - essentially prune out old users that no longer exist */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) {
- if (user->keep) {
- user->keep = 0;
- continue;
- }
- /* We do not need to keep this user so take them out of the list */
- AST_LIST_REMOVE_CURRENT(&users, list);
- /* Free their memory now */
- if (user->secret)
- free(user->secret);
- if (user->deny)
- free(user->deny);
- if (user->permit)
- free(user->permit);
- if (user->read)
- free(user->read);
- if (user->write)
- free(user->write);
- free(user);
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- AST_LIST_UNLOCK(&users);
-
- ast_config_destroy(cfg);
-
- if (webenabled && enabled) {
- if (!webregged) {
- ast_http_uri_link(&rawmanuri);
- ast_http_uri_link(&manageruri);
- ast_http_uri_link(&managerxmluri);
- webregged = 1;
- }
- } else {
- if (webregged) {
- ast_http_uri_unlink(&rawmanuri);
- ast_http_uri_unlink(&manageruri);
- ast_http_uri_unlink(&managerxmluri);
- webregged = 0;
- }
- }
-
- if (newhttptimeout > 0)
- httptimeout = newhttptimeout;
-
- /* If not enabled, do nothing */
- if (!enabled)
- return 0;
-
- if (asock < 0) {
- asock = socket(AF_INET, SOCK_STREAM, 0);
- if (asock < 0) {
- ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
- return -1;
- }
- setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
- if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) {
- ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno));
- close(asock);
- asock = -1;
- return -1;
- }
- if (listen(asock, 2)) {
- ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno));
- close(asock);
- asock = -1;
- return -1;
- }
- flags = fcntl(asock, F_GETFL);
- fcntl(asock, F_SETFL, flags | O_NONBLOCK);
- if (option_verbose)
- ast_verbose("Asterisk Management interface listening on port %d\n", portno);
- ast_pthread_create_background(&t, NULL, accept_thread, NULL);
- }
- return 0;
-}
-
-int reload_manager(void)
-{
- manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
- return init_manager();
-}
diff --git a/1.4/main/md5.c b/1.4/main/md5.c
deleted file mode 100644
index 949c408e2..000000000
--- a/1.4/main/md5.c
+++ /dev/null
@@ -1,267 +0,0 @@
-
-/*!\file
-\brief MD5 checksum routines used for authentication. Not covered by GPL, but
- in the public domain as per the copyright below */
-
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h> /* for memcpy() */
-
-#include "asterisk/endian.h"
-#include "asterisk/md5.h"
-
-# if __BYTE_ORDER == __BIG_ENDIAN
-# define HIGHFIRST 1
-# endif
-#ifndef HIGHFIRST
-#define byteReverse(buf, len) /* Nothing */
-#else
-void byteReverse(unsigned char *buf, unsigned longs);
-
-#ifndef ASM_MD5
-/*
- * Note: this code is harmless on little-endian machines.
- */
-void byteReverse(unsigned char *buf, unsigned longs)
-{
- uint32_t t;
- do {
- t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(uint32_t *) buf = t;
- buf += 4;
- } while (--longs);
-}
-#endif
-#endif
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void MD5Init(struct MD5Context *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
- uint32_t t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memcpy(p, buf, len);
- return;
- }
- memcpy(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += t;
- len -= t;
- }
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-{
- unsigned count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((uint32_t *) ctx->in)[14] = ctx->bits[0];
- ((uint32_t *) ctx->in)[15] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
-}
-
-#ifndef ASM_MD5
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void MD5Transform(uint32_t buf[4], uint32_t const in[16])
-{
- register uint32_t a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-#endif
diff --git a/1.4/main/netsock.c b/1.4/main/netsock.c
deleted file mode 100644
index 9fa842ec3..000000000
--- a/1.4/main/netsock.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@digium.com>
- * 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.
- */
-
-/*! \file
- *
- * \brief Network socket handling
- *
- * \author Kevin P. Fleming <kpfleming@digium.com>
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/ioctl.h>
-
-#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
-#include <fcntl.h>
-#include <net/route.h>
-#endif
-
-#if defined (SOLARIS)
-#include <sys/sockio.h>
-#endif
-
-#include "asterisk/netsock.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/srv.h"
-
-struct ast_netsock {
- ASTOBJ_COMPONENTS(struct ast_netsock);
- struct sockaddr_in bindaddr;
- int sockfd;
- int *ioref;
- struct io_context *ioc;
- void *data;
-};
-
-struct ast_netsock_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct ast_netsock);
- struct io_context *ioc;
-};
-
-static void ast_netsock_destroy(struct ast_netsock *netsock)
-{
- ast_io_remove(netsock->ioc, netsock->ioref);
- close(netsock->sockfd);
- free(netsock);
-}
-
-struct ast_netsock_list *ast_netsock_list_alloc(void)
-{
- return ast_calloc(1, sizeof(struct ast_netsock_list));
-}
-
-int ast_netsock_init(struct ast_netsock_list *list)
-{
- memset(list, 0, sizeof(*list));
- ASTOBJ_CONTAINER_INIT(list);
-
- return 0;
-}
-
-int ast_netsock_release(struct ast_netsock_list *list)
-{
- ASTOBJ_CONTAINER_DESTROYALL(list, ast_netsock_destroy);
- ASTOBJ_CONTAINER_DESTROY(list);
-
- return 0;
-}
-
-struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list,
- struct sockaddr_in *sa)
-{
- struct ast_netsock *sock = NULL;
-
- ASTOBJ_CONTAINER_TRAVERSE(list, !sock, {
- ASTOBJ_RDLOCK(iterator);
- if (!inaddrcmp(&iterator->bindaddr, sa))
- sock = iterator;
- ASTOBJ_UNLOCK(iterator);
- });
-
- return sock;
-}
-
-struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct sockaddr_in *bindaddr, int tos, ast_io_cb callback, void *data)
-{
- int netsocket = -1;
- int *ioref;
-
- struct ast_netsock *ns;
- const int reuseFlag = 1;
-
- /* Make a UDP socket */
- netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
-
- if (netsocket < 0) {
- ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
- return NULL;
- }
- if (setsockopt(netsocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) {
- ast_log(LOG_WARNING, "Error setting SO_REUSEADDR on sockfd '%d'\n", netsocket);
- }
- if (bind(netsocket,(struct sockaddr *)bindaddr, sizeof(struct sockaddr_in))) {
- ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(bindaddr->sin_addr), ntohs(bindaddr->sin_port), strerror(errno));
- close(netsocket);
- return NULL;
- }
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos);
-
- if (setsockopt(netsocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))
- ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
-
- ast_enable_packet_fragmentation(netsocket);
-
- if (!(ns = ast_calloc(1, sizeof(struct ast_netsock)))) {
- close(netsocket);
- return NULL;
- }
-
- /* Establish I/O callback for socket read */
- if (!(ioref = ast_io_add(ioc, netsocket, callback, AST_IO_IN, ns))) {
- close(netsocket);
- free(ns);
- return NULL;
- }
- ASTOBJ_INIT(ns);
- ns->ioref = ioref;
- ns->ioc = ioc;
- ns->sockfd = netsocket;
- ns->data = data;
- memcpy(&ns->bindaddr, bindaddr, sizeof(ns->bindaddr));
- ASTOBJ_CONTAINER_LINK(list, ns);
-
- return ns;
-}
-
-struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, ast_io_cb callback, void *data)
-{
- struct sockaddr_in sin;
- char *tmp;
- char *host;
- char *port;
- int portno;
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(defaultport);
- tmp = ast_strdupa(bindinfo);
-
- host = strsep(&tmp, ":");
- port = tmp;
-
- if (port && ((portno = atoi(port)) > 0))
- sin.sin_port = htons(portno);
-
- inet_aton(host, &sin.sin_addr);
-
- return ast_netsock_bindaddr(list, ioc, &sin, tos, callback, data);
-}
-
-int ast_netsock_sockfd(const struct ast_netsock *ns)
-{
- return ns ? ns-> sockfd : -1;
-}
-
-const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns)
-{
- return &(ns->bindaddr);
-}
-
-void *ast_netsock_data(const struct ast_netsock *ns)
-{
- return ns->data;
-}
-
-void ast_netsock_unref(struct ast_netsock *ns)
-{
- ASTOBJ_UNREF(ns, ast_netsock_destroy);
-}
diff --git a/1.4/main/pbx.c b/1.4/main/pbx.c
deleted file mode 100644
index d6564db4f..000000000
--- a/1.4/main/pbx.c
+++ /dev/null
@@ -1,6415 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Core PBX routines.
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <limits.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/cli.h"
-#include "asterisk/pbx.h"
-#include "asterisk/channel.h"
-#include "asterisk/options.h"
-#include "asterisk/logger.h"
-#include "asterisk/file.h"
-#include "asterisk/callerid.h"
-#include "asterisk/cdr.h"
-#include "asterisk/config.h"
-#include "asterisk/term.h"
-#include "asterisk/manager.h"
-#include "asterisk/ast_expr.h"
-#include "asterisk/linkedlists.h"
-#define SAY_STUBS /* generate declarations and stubs for say methods */
-#include "asterisk/say.h"
-#include "asterisk/utils.h"
-#include "asterisk/causes.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/app.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/threadstorage.h"
-
-/*!
- * \note I M P O R T A N T :
- *
- * The speed of extension handling will likely be among the most important
- * aspects of this PBX. The switching scheme as it exists right now isn't
- * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
- * of priorities, but a constant search time here would be great ;-)
- *
- */
-
-#ifdef LOW_MEMORY
-#define EXT_DATA_SIZE 256
-#else
-#define EXT_DATA_SIZE 8192
-#endif
-
-#define SWITCH_DATA_LENGTH 256
-
-#define VAR_BUF_SIZE 4096
-
-#define VAR_NORMAL 1
-#define VAR_SOFTTRAN 2
-#define VAR_HARDTRAN 3
-
-#define BACKGROUND_SKIP (1 << 0)
-#define BACKGROUND_NOANSWER (1 << 1)
-#define BACKGROUND_MATCHEXTEN (1 << 2)
-#define BACKGROUND_PLAYBACK (1 << 3)
-
-AST_APP_OPTIONS(background_opts, {
- AST_APP_OPTION('s', BACKGROUND_SKIP),
- AST_APP_OPTION('n', BACKGROUND_NOANSWER),
- AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
- AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
-});
-
-#define WAITEXTEN_MOH (1 << 0)
-
-AST_APP_OPTIONS(waitexten_opts, {
- AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
-});
-
-struct ast_context;
-
-AST_THREADSTORAGE(switch_data, switch_data_init);
-
-/*!
- \brief ast_exten: An extension
- The dialplan is saved as a linked list with each context
- having it's own linked list of extensions - one item per
- priority.
-*/
-struct ast_exten {
- char *exten; /*!< Extension name */
- int matchcid; /*!< Match caller id ? */
- const char *cidmatch; /*!< Caller id to match for this extension */
- int priority; /*!< Priority */
- const char *label; /*!< Label */
- struct ast_context *parent; /*!< The context this extension belongs to */
- const char *app; /*!< Application to execute */
- void *data; /*!< Data to use (arguments) */
- void (*datad)(void *); /*!< Data destructor */
- struct ast_exten *peer; /*!< Next higher priority with our extension */
- const char *registrar; /*!< Registrar */
- struct ast_exten *next; /*!< Extension with a greater ID */
- char stuff[0];
-};
-
-/*! \brief ast_include: include= support in extensions.conf */
-struct ast_include {
- const char *name;
- const char *rname; /*!< Context to include */
- const char *registrar; /*!< Registrar */
- int hastime; /*!< If time construct exists */
- struct ast_timing timing; /*!< time construct */
- struct ast_include *next; /*!< Link them together */
- char stuff[0];
-};
-
-/*! \brief ast_sw: Switch statement in extensions.conf */
-struct ast_sw {
- char *name;
- const char *registrar; /*!< Registrar */
- char *data; /*!< Data load */
- int eval;
- AST_LIST_ENTRY(ast_sw) list;
- char stuff[0];
-};
-
-/*! \brief ast_ignorepat: Ignore patterns in dial plan */
-struct ast_ignorepat {
- const char *registrar;
- struct ast_ignorepat *next;
- const char pattern[0];
-};
-
-/*! \brief ast_context: An extension context */
-struct ast_context {
- ast_mutex_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
- struct ast_exten *root; /*!< The root of the list of extensions */
- struct ast_context *next; /*!< Link them together */
- struct ast_include *includes; /*!< Include other contexts */
- struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
- const char *registrar; /*!< Registrar */
- AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
- ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
- char name[0]; /*!< Name of the context */
-};
-
-
-/*! \brief ast_app: A registered application */
-struct ast_app {
- int (*execute)(struct ast_channel *chan, void *data);
- const char *synopsis; /*!< Synopsis text for 'show applications' */
- const char *description; /*!< Description (help text) for 'show application &lt;name&gt;' */
- AST_LIST_ENTRY(ast_app) list; /*!< Next app in list */
- struct module *module; /*!< Module this app belongs to */
- char name[0]; /*!< Name of the application */
-};
-
-/*! \brief ast_state_cb: An extension state notify register item */
-struct ast_state_cb {
- int id;
- void *data;
- ast_state_cb_type callback;
- struct ast_state_cb *next;
-};
-
-/*! \brief Structure for dial plan hints
-
- \note Hints are pointers from an extension in the dialplan to one or
- more devices (tech/name) */
-struct ast_hint {
- struct ast_exten *exten; /*!< Extension */
- int laststate; /*!< Last known state */
- struct ast_state_cb *callbacks; /*!< Callback list for this extension */
- AST_LIST_ENTRY(ast_hint) list; /*!< Pointer to next hint in list */
-};
-
-static const struct cfextension_states {
- int extension_state;
- const char * const text;
-} extension_states[] = {
- { AST_EXTENSION_NOT_INUSE, "Idle" },
- { AST_EXTENSION_INUSE, "InUse" },
- { AST_EXTENSION_BUSY, "Busy" },
- { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
- { AST_EXTENSION_RINGING, "Ringing" },
- { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
- { AST_EXTENSION_ONHOLD, "Hold" },
- { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
-};
-
-static int pbx_builtin_answer(struct ast_channel *, void *);
-static int pbx_builtin_goto(struct ast_channel *, void *);
-static int pbx_builtin_hangup(struct ast_channel *, void *);
-static int pbx_builtin_background(struct ast_channel *, void *);
-static int pbx_builtin_wait(struct ast_channel *, void *);
-static int pbx_builtin_waitexten(struct ast_channel *, void *);
-static int pbx_builtin_resetcdr(struct ast_channel *, void *);
-static int pbx_builtin_setamaflags(struct ast_channel *, void *);
-static int pbx_builtin_ringing(struct ast_channel *, void *);
-static int pbx_builtin_progress(struct ast_channel *, void *);
-static int pbx_builtin_congestion(struct ast_channel *, void *);
-static int pbx_builtin_busy(struct ast_channel *, void *);
-static int pbx_builtin_setglobalvar(struct ast_channel *, void *);
-static int pbx_builtin_noop(struct ast_channel *, void *);
-static int pbx_builtin_gotoif(struct ast_channel *, void *);
-static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
-static int pbx_builtin_execiftime(struct ast_channel *, void *);
-static int pbx_builtin_saynumber(struct ast_channel *, void *);
-static int pbx_builtin_saydigits(struct ast_channel *, void *);
-static int pbx_builtin_saycharacters(struct ast_channel *, void *);
-static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
-int pbx_builtin_setvar(struct ast_channel *, void *);
-static int pbx_builtin_importvar(struct ast_channel *, void *);
-
-AST_MUTEX_DEFINE_STATIC(globalslock);
-static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
-
-static int autofallthrough = 1;
-
-AST_MUTEX_DEFINE_STATIC(maxcalllock);
-static int countcalls;
-
-static AST_LIST_HEAD_STATIC(acf_root, ast_custom_function);
-
-/*! \brief Declaration of builtin applications */
-static struct pbx_builtin {
- char name[AST_MAX_APP];
- int (*execute)(struct ast_channel *chan, void *data);
- char *synopsis;
- char *description;
-} builtins[] =
-{
- /* These applications are built into the PBX core and do not
- need separate modules */
-
- { "Answer", pbx_builtin_answer,
- "Answer a channel if ringing",
- " Answer([delay]): If the call has not been answered, this application will\n"
- "answer it. Otherwise, it has no effect on the call. If a delay is specified,\n"
- "Asterisk will wait this number of milliseconds before returning to\n"
- "the dialplan after answering the call.\n"
- },
-
- { "BackGround", pbx_builtin_background,
- "Play an audio file while waiting for digits of an extension to go to.",
- " Background(filename1[&filename2...][|options[|langoverride][|context]]):\n"
- "This application will play the given list of files (do not put extension)\n"
- "while waiting for an extension to be dialed by the calling channel. To\n"
- "continue waiting for digits after this application has finished playing\n"
- "files, the WaitExten application should be used. The 'langoverride' option\n"
- "explicitly specifies which language to attempt to use for the requested sound\n"
- "files. If a 'context' is specified, this is the dialplan context that this\n"
- "application will use when exiting to a dialed extension."
- " If one of the requested sound files does not exist, call processing will be\n"
- "terminated.\n"
- " Options:\n"
- " s - Causes the playback of the message to be skipped\n"
- " if the channel is not in the 'up' state (i.e. it\n"
- " hasn't been answered yet). If this happens, the\n"
- " application will return immediately.\n"
- " n - Don't answer the channel before playing the files.\n"
- " m - Only break if a digit hit matches a one digit\n"
- " extension in the destination context.\n"
- "See Also: Playback (application) -- Play sound file(s) to the channel,\n"
- " that cannot be interrupted\n"
- },
-
- { "Busy", pbx_builtin_busy,
- "Indicate the Busy condition",
- " Busy([timeout]): This application will indicate the busy condition to\n"
- "the calling channel. If the optional timeout is specified, the calling channel\n"
- "will be hung up after the specified number of seconds. Otherwise, this\n"
- "application will wait until the calling channel hangs up.\n"
- },
-
- { "Congestion", pbx_builtin_congestion,
- "Indicate the Congestion condition",
- " Congestion([timeout]): This application will indicate the congestion\n"
- "condition to the calling channel. If the optional timeout is specified, the\n"
- "calling channel will be hung up after the specified number of seconds.\n"
- "Otherwise, this application will wait until the calling channel hangs up.\n"
- },
-
- { "Goto", pbx_builtin_goto,
- "Jump to a particular priority, extension, or context",
- " Goto([[context|]extension|]priority): This application will set the current\n"
- "context, extension, and priority in the channel structure. After it completes, the\n"
- "pbx engine will continue dialplan execution at the specified location.\n"
- "If no specific extension, or extension and context, are specified, then this\n"
- "application will just set the specified priority of the current extension.\n"
- " At least a priority is required as an argument, or the goto will return a -1,\n"
- "and the channel and call will be terminated.\n"
- " If the location that is put into the channel information is bogus, and asterisk cannot\n"
- "find that location in the dialplan,\n"
- "then the execution engine will try to find and execute the code in the 'i' (invalid)\n"
- "extension in the current context. If that does not exist, it will try to execute the\n"
- "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
- "channel is hung up, and the execution of instructions on the channel is terminated.\n"
- "What this means is that, for example, you specify a context that does not exist, then\n"
- "it will not be possible to find the 'h' or 'i' extensions, and the call will terminate!\n"
- },
-
- { "GotoIf", pbx_builtin_gotoif,
- "Conditional goto",
- " GotoIf(condition?[labeliftrue]:[labeliffalse]): This application will set the current\n"
- "context, extension, and priority in the channel structure based on the evaluation of\n"
- "the given condition. After this application completes, the\n"
- "pbx engine will continue dialplan execution at the specified location in the dialplan.\n"
- "The channel will continue at\n"
- "'labeliftrue' if the condition is true, or 'labeliffalse' if the condition is\n"
- "false. The labels are specified with the same syntax as used within the Goto\n"
- "application. If the label chosen by the condition is omitted, no jump is\n"
- "performed, and the execution passes to the next instruction.\n"
- "If the target location is bogus, and does not exist, the execution engine will try \n"
- "to find and execute the code in the 'i' (invalid)\n"
- "extension in the current context. If that does not exist, it will try to execute the\n"
- "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
- "channel is hung up, and the execution of instructions on the channel is terminated.\n"
- "Remember that this command can set the current context, and if the context specified\n"
- "does not exist, then it will not be able to find any 'h' or 'i' extensions there, and\n"
- "the channel and call will both be terminated!\n"
- },
-
- { "GotoIfTime", pbx_builtin_gotoiftime,
- "Conditional Goto based on the current time",
- " GotoIfTime(<times>|<weekdays>|<mdays>|<months>?[[context|]exten|]priority):\n"
- "This application will set the context, extension, and priority in the channel structure\n"
- "if the current time matches the given time specification. Otherwise, nothing is done.\n"
- "Further information on the time specification can be found in examples\n"
- "illustrating how to do time-based context includes in the dialplan.\n"
- "If the target jump location is bogus, the same actions would be taken as for Goto.\n"
- },
-
- { "ExecIfTime", pbx_builtin_execiftime,
- "Conditional application execution based on the current time",
- " ExecIfTime(<times>|<weekdays>|<mdays>|<months>?appname[|appargs]):\n"
- "This application will execute the specified dialplan application, with optional\n"
- "arguments, if the current time matches the given time specification.\n"
- },
-
- { "Hangup", pbx_builtin_hangup,
- "Hang up the calling channel",
- " Hangup([causecode]): This application will hang up the calling channel.\n"
- "If a causecode is given the channel's hangup cause will be set to the given\n"
- "value.\n"
- },
-
- { "NoOp", pbx_builtin_noop,
- "Do Nothing",
- " NoOp(): This applicatiion does nothing. However, it is useful for debugging\n"
- "purposes. Any text that is provided as arguments to this application can be\n"
- "viewed at the Asterisk CLI. This method can be used to see the evaluations of\n"
- "variables or functions without having any effect."
- },
-
- { "Progress", pbx_builtin_progress,
- "Indicate progress",
- " Progress(): This application will request that in-band progress information\n"
- "be provided to the calling channel.\n"
- },
-
- { "ResetCDR", pbx_builtin_resetcdr,
- "Resets the Call Data Record",
- " ResetCDR([options]): This application causes the Call Data Record to be\n"
- "reset.\n"
- " Options:\n"
- " w -- Store the current CDR record before resetting it.\n"
- " a -- Store any stacked records.\n"
- " v -- Save CDR variables.\n"
- },
-
- { "Ringing", pbx_builtin_ringing,
- "Indicate ringing tone",
- " Ringing(): This application will request that the channel indicate a ringing\n"
- "tone to the user.\n"
- },
-
- { "SayNumber", pbx_builtin_saynumber,
- "Say Number",
- " SayNumber(digits[,gender]): This application will play the sounds that\n"
- "correspond to the given number. Optionally, a gender may be specified.\n"
- "This will use the language that is currently set for the channel. See the\n"
- "LANGUAGE function for more information on setting the language for the channel.\n"
- },
-
- { "SayDigits", pbx_builtin_saydigits,
- "Say Digits",
- " SayDigits(digits): This application will play the sounds that correspond\n"
- "to the digits of the given number. This will use the language that is currently\n"
- "set for the channel. See the LANGUAGE function for more information on setting\n"
- "the language for the channel.\n"
- },
-
- { "SayAlpha", pbx_builtin_saycharacters,
- "Say Alpha",
- " SayAlpha(string): This application will play the sounds that correspond to\n"
- "the letters of the given string.\n"
- },
-
- { "SayPhonetic", pbx_builtin_sayphonetic,
- "Say Phonetic",
- " SayPhonetic(string): This application will play the sounds from the phonetic\n"
- "alphabet that correspond to the letters in the given string.\n"
- },
-
- { "SetAMAFlags", pbx_builtin_setamaflags,
- "Set the AMA Flags",
- " SetAMAFlags([flag]): This application will set the channel's AMA Flags for\n"
- " billing purposes.\n"
- },
-
- { "SetGlobalVar", pbx_builtin_setglobalvar,
- "Set a global variable to a given value",
- " SetGlobalVar(variable=value): This application sets a given global variable to\n"
- "the specified value.\n"
- "\n\nThis application is deprecated in favor of Set(GLOBAL(var)=value)\n"
- },
-
- { "Set", pbx_builtin_setvar,
- "Set channel variable(s) or function value(s)",
- " Set(name1=value1|name2=value2|..[|options])\n"
- "This function can be used to set the value of channel variables or dialplan\n"
- "functions. It will accept up to 24 name/value pairs. When setting variables,\n"
- "if the variable name is prefixed with _, the variable will be inherited into\n"
- "channels created from the current channel. If the variable name is prefixed\n"
- "with __, the variable will be inherited into channels created from the current\n"
- "channel and all children channels.\n"
- " Options:\n"
- " g - Set variable globally instead of on the channel\n"
- " (applies only to variables, not functions)\n"
- "\n\nThe use of Set to set multiple variables at once and the g flag have both\n"
- "been deprecated. Please use multiple Set calls and the GLOBAL() dialplan\n"
- "function instead.\n"
- },
-
- { "ImportVar", pbx_builtin_importvar,
- "Import a variable from a channel into a new variable",
- " ImportVar(newvar=channelname|variable): This application imports a variable\n"
- "from the specified channel (as opposed to the current one) and stores it as\n"
- "a variable in the current channel (the channel that is calling this\n"
- "application). Variables created by this application have the same inheritance\n"
- "properties as those created with the Set application. See the documentation for\n"
- "Set for more information.\n"
- },
-
- { "Wait", pbx_builtin_wait,
- "Waits for some time",
- " Wait(seconds): This application waits for a specified number of seconds.\n"
- "Then, dialplan execution will continue at the next priority.\n"
- " Note that the seconds can be passed with fractions of a second. For example,\n"
- "'1.5' will ask the application to wait for 1.5 seconds.\n"
- },
-
- { "WaitExten", pbx_builtin_waitexten,
- "Waits for an extension to be entered",
- " WaitExten([seconds][|options]): This application waits for the user to enter\n"
- "a new extension for a specified number of seconds.\n"
- " Note that the seconds can be passed with fractions of a second. For example,\n"
- "'1.5' will ask the application to wait for 1.5 seconds.\n"
- " Options:\n"
- " m[(x)] - Provide music on hold to the caller while waiting for an extension.\n"
- " Optionally, specify the class for music on hold within parenthesis.\n"
- "See Also: Playback(application), Background(application).\n"
- },
-
-};
-
-static struct ast_context *contexts;
-AST_RWLOCK_DEFINE_STATIC(conlock); /*!< Lock for the ast_context list */
-
-static AST_LIST_HEAD_STATIC(apps, ast_app);
-
-static AST_LIST_HEAD_STATIC(switches, ast_switch);
-
-static int stateid = 1;
-/* WARNING:
- When holding this list's lock, do _not_ do anything that will cause conlock
- to be taken, unless you _already_ hold it. The ast_merge_contexts_and_delete
- function will take the locks in conlock/hints order, so any other
- paths that require both locks must also take them in that order.
-*/
-static AST_LIST_HEAD_STATIC(hints, ast_hint);
-struct ast_state_cb *statecbs;
-
-/*
- \note This function is special. It saves the stack so that no matter
- how many times it is called, it returns to the same place */
-int pbx_exec(struct ast_channel *c, /*!< Channel */
- struct ast_app *app, /*!< Application */
- void *data) /*!< Data for execution */
-{
- int res;
-
- const char *saved_c_appl;
- const char *saved_c_data;
-
- if (c->cdr && !ast_check_hangup(c))
- ast_cdr_setapp(c->cdr, app->name, data);
-
- /* save channel values */
- saved_c_appl= c->appl;
- saved_c_data= c->data;
-
- c->appl = app->name;
- c->data = data;
- /* XXX remember what to to when we have linked apps to modules */
- if (app->module) {
- /* XXX LOCAL_USER_ADD(app->module) */
- }
- res = app->execute(c, S_OR(data, ""));
- if (app->module) {
- /* XXX LOCAL_USER_REMOVE(app->module) */
- }
- /* restore channel values */
- c->appl = saved_c_appl;
- c->data = saved_c_data;
- return res;
-}
-
-
-/*! Go no deeper than this through includes (not counting loops) */
-#define AST_PBX_MAX_STACK 128
-
-/*! \brief Find application handle in linked list
- */
-struct ast_app *pbx_findapp(const char *app)
-{
- struct ast_app *tmp;
-
- AST_LIST_LOCK(&apps);
- AST_LIST_TRAVERSE(&apps, tmp, list) {
- if (!strcasecmp(tmp->name, app))
- break;
- }
- AST_LIST_UNLOCK(&apps);
-
- return tmp;
-}
-
-static struct ast_switch *pbx_findswitch(const char *sw)
-{
- struct ast_switch *asw;
-
- AST_LIST_LOCK(&switches);
- AST_LIST_TRAVERSE(&switches, asw, list) {
- if (!strcasecmp(asw->name, sw))
- break;
- }
- AST_LIST_UNLOCK(&switches);
-
- return asw;
-}
-
-static inline int include_valid(struct ast_include *i)
-{
- if (!i->hastime)
- return 1;
-
- return ast_check_timing(&(i->timing));
-}
-
-static void pbx_destroy(struct ast_pbx *p)
-{
- free(p);
-}
-
-/*
- * Special characters used in patterns:
- * '_' underscore is the leading character of a pattern.
- * In other position it is treated as a regular char.
- * ' ' '-' space and '-' are separator and ignored.
- * . one or more of any character. Only allowed at the end of
- * a pattern.
- * ! zero or more of anything. Also impacts the result of CANMATCH
- * and MATCHMORE. Only allowed at the end of a pattern.
- * In the core routine, ! causes a match with a return code of 2.
- * In turn, depending on the search mode: (XXX check if it is implemented)
- * - E_MATCH retuns 1 (does match)
- * - E_MATCHMORE returns 0 (no match)
- * - E_CANMATCH returns 1 (does match)
- *
- * / should not appear as it is considered the separator of the CID info.
- * XXX at the moment we may stop on this char.
- *
- * X Z N match ranges 0-9, 1-9, 2-9 respectively.
- * [ denotes the start of a set of character. Everything inside
- * is considered literally. We can have ranges a-d and individual
- * characters. A '[' and '-' can be considered literally if they
- * are just before ']'.
- * XXX currently there is no way to specify ']' in a range, nor \ is
- * considered specially.
- *
- * When we compare a pattern with a specific extension, all characters in the extension
- * itself are considered literally with the only exception of '-' which is considered
- * as a separator and thus ignored.
- * XXX do we want to consider space as a separator as well ?
- * XXX do we want to consider the separators in non-patterns as well ?
- */
-
-/*!
- * \brief helper functions to sort extensions and patterns in the desired way,
- * so that more specific patterns appear first.
- *
- * ext_cmp1 compares individual characters (or sets of), returning
- * an int where bits 0-7 are the ASCII code of the first char in the set,
- * while bit 8-15 are the cardinality of the set minus 1.
- * This way more specific patterns (smaller cardinality) appear first.
- * Wildcards have a special value, so that we can directly compare them to
- * sets by subtracting the two values. In particular:
- * 0x000xx one character, xx
- * 0x0yyxx yy character set starting with xx
- * 0x10000 '.' (one or more of anything)
- * 0x20000 '!' (zero or more of anything)
- * 0x30000 NUL (end of string)
- * 0x40000 error in set.
- * The pointer to the string is advanced according to needs.
- * NOTES:
- * 1. the empty set is equivalent to NUL.
- * 2. given that a full set has always 0 as the first element,
- * we could encode the special cases as 0xffXX where XX
- * is 1, 2, 3, 4 as used above.
- */
-static int ext_cmp1(const char **p)
-{
- uint32_t chars[8];
- int c, cmin = 0xff, count = 0;
- const char *end;
-
- /* load, sign extend and advance pointer until we find
- * a valid character.
- */
- while ( (c = *(*p)++) && (c == ' ' || c == '-') )
- ; /* ignore some characters */
-
- /* always return unless we have a set of chars */
- switch (c) {
- default: /* ordinary character */
- return 0x0000 | (c & 0xff);
-
- case 'N': /* 2..9 */
- return 0x0700 | '2' ;
-
- case 'X': /* 0..9 */
- return 0x0900 | '0';
-
- case 'Z': /* 1..9 */
- return 0x0800 | '1';
-
- case '.': /* wildcard */
- return 0x10000;
-
- case '!': /* earlymatch */
- return 0x20000; /* less specific than NULL */
-
- case '\0': /* empty string */
- *p = NULL;
- return 0x30000;
-
- case '[': /* pattern */
- break;
- }
- /* locate end of set */
- end = strchr(*p, ']');
-
- if (end == NULL) {
- ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
- return 0x40000; /* XXX make this entry go last... */
- }
-
- bzero(chars, sizeof(chars)); /* clear all chars in the set */
- for (; *p < end ; (*p)++) {
- unsigned char c1, c2; /* first-last char in range */
- c1 = (unsigned char)((*p)[0]);
- if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
- c2 = (unsigned char)((*p)[2]);
- *p += 2; /* skip a total of 3 chars */
- } else /* individual character */
- c2 = c1;
- if (c1 < cmin)
- cmin = c1;
- for (; c1 <= c2; c1++) {
- uint32_t mask = 1 << (c1 % 32);
- if ( (chars[ c1 / 32 ] & mask) == 0)
- count += 0x100;
- chars[ c1 / 32 ] |= mask;
- }
- }
- (*p)++;
- return count == 0 ? 0x30000 : (count | cmin);
-}
-
-/*!
- * \brief the full routine to compare extensions in rules.
- */
-static int ext_cmp(const char *a, const char *b)
-{
- /* make sure non-patterns come first.
- * If a is not a pattern, it either comes first or
- * we use strcmp to compare the strings.
- */
- int ret = 0;
-
- if (a[0] != '_')
- return (b[0] == '_') ? -1 : strcmp(a, b);
-
- /* Now we know a is a pattern; if b is not, a comes first */
- if (b[0] != '_')
- return 1;
-#if 0 /* old mode for ext matching */
- return strcmp(a, b);
-#endif
- /* ok we need full pattern sorting routine */
- while (!ret && a && b)
- ret = ext_cmp1(&a) - ext_cmp1(&b);
- if (ret == 0)
- return 0;
- else
- return (ret > 0) ? 1 : -1;
-}
-
-/*!
- * When looking up extensions, we can have different requests
- * identified by the 'action' argument, as follows.
- * Note that the coding is such that the low 4 bits are the
- * third argument to extension_match_core.
- */
-enum ext_match_t {
- E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */
- E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */
- E_MATCH = 0x02, /* extension is an exact match */
- E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
- E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */
- E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */
-};
-
-/*
- * Internal function for ast_extension_{match|close}
- * return 0 on no-match, 1 on match, 2 on early match.
- * mode is as follows:
- * E_MATCH success only on exact match
- * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
- * E_CANMATCH either of the above.
- */
-
-static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
-{
- mode &= E_MATCH_MASK; /* only consider the relevant bits */
-
- if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
- return 1;
-
- if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
- int ld = strlen(data), lp = strlen(pattern);
-
- if (lp < ld) /* pattern too short, cannot match */
- return 0;
- /* depending on the mode, accept full or partial match or both */
- if (mode == E_MATCH)
- return !strcmp(pattern, data); /* 1 on match, 0 on fail */
- if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
- return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
- else
- return 0;
- }
- pattern++; /* skip leading _ */
- /*
- * XXX below we stop at '/' which is a separator for the CID info. However we should
- * not store '/' in the pattern at all. When we insure it, we can remove the checks.
- */
- while (*data && *pattern && *pattern != '/') {
- const char *end;
-
- if (*data == '-') { /* skip '-' in data (just a separator) */
- data++;
- continue;
- }
- switch (toupper(*pattern)) {
- case '[': /* a range */
- end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
- if (end == NULL) {
- ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
- return 0; /* unconditional failure */
- }
- for (pattern++; pattern != end; pattern++) {
- if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
- if (*data >= pattern[0] && *data <= pattern[2])
- break; /* match found */
- else {
- pattern += 2; /* skip a total of 3 chars */
- continue;
- }
- } else if (*data == pattern[0])
- break; /* match found */
- }
- if (pattern == end)
- return 0;
- pattern = end; /* skip and continue */
- break;
- case 'N':
- if (*data < '2' || *data > '9')
- return 0;
- break;
- case 'X':
- if (*data < '0' || *data > '9')
- return 0;
- break;
- case 'Z':
- if (*data < '1' || *data > '9')
- return 0;
- break;
- case '.': /* Must match, even with more digits */
- return 1;
- case '!': /* Early match */
- return 2;
- case ' ':
- case '-': /* Ignore these in patterns */
- data--; /* compensate the final data++ */
- break;
- default:
- if (*data != *pattern)
- return 0;
- }
- data++;
- pattern++;
- }
- if (*data) /* data longer than pattern, no match */
- return 0;
- /*
- * match so far, but ran off the end of the data.
- * Depending on what is next, determine match or not.
- */
- if (*pattern == '\0' || *pattern == '/') /* exact match */
- return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
- else if (*pattern == '!') /* early match */
- return 2;
- else /* partial match */
- return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
-}
-
-/*
- * Wrapper around _extension_match_core() to do performance measurement
- * using the profiling code.
- */
-static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
-{
- int i;
- static int prof_id = -2; /* marker for 'unallocated' id */
- if (prof_id == -2)
- prof_id = ast_add_profile("ext_match", 0);
- ast_mark(prof_id, 1);
- i = _extension_match_core(pattern, data, mode);
- ast_mark(prof_id, 0);
- return i;
-}
-
-int ast_extension_match(const char *pattern, const char *data)
-{
- return extension_match_core(pattern, data, E_MATCH);
-}
-
-int ast_extension_close(const char *pattern, const char *data, int needmore)
-{
- if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
- ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
- return extension_match_core(pattern, data, needmore);
-}
-
-struct ast_context *ast_context_find(const char *name)
-{
- struct ast_context *tmp = NULL;
-
- ast_rdlock_contexts();
-
- while ( (tmp = ast_walk_contexts(tmp)) ) {
- if (!name || !strcasecmp(name, tmp->name))
- break;
- }
-
- ast_unlock_contexts();
-
- return tmp;
-}
-
-#define STATUS_NO_CONTEXT 1
-#define STATUS_NO_EXTENSION 2
-#define STATUS_NO_PRIORITY 3
-#define STATUS_NO_LABEL 4
-#define STATUS_SUCCESS 5
-
-static int matchcid(const char *cidpattern, const char *callerid)
-{
- /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
- failing to get a number should count as a match, otherwise not */
-
- if (ast_strlen_zero(callerid))
- return ast_strlen_zero(cidpattern) ? 1 : 0;
-
- return ast_extension_match(cidpattern, callerid);
-}
-
-/* request and result for pbx_find_extension */
-struct pbx_find_info {
-#if 0
- const char *context;
- const char *exten;
- int priority;
-#endif
-
- char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
- int stacklen; /* modified during the search */
- int status; /* set on return */
- struct ast_switch *swo; /* set on return */
- const char *data; /* set on return */
- const char *foundcontext; /* set on return */
-};
-
-static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
- struct ast_context *bypass, struct pbx_find_info *q,
- const char *context, const char *exten, int priority,
- const char *label, const char *callerid, enum ext_match_t action)
-{
- int x, res;
- struct ast_context *tmp;
- struct ast_exten *e, *eroot;
- struct ast_include *i;
- struct ast_sw *sw;
- char *tmpdata = NULL;
-
- /* Initialize status if appropriate */
- if (q->stacklen == 0) {
- q->status = STATUS_NO_CONTEXT;
- q->swo = NULL;
- q->data = NULL;
- q->foundcontext = NULL;
- }
- /* Check for stack overflow */
- if (q->stacklen >= AST_PBX_MAX_STACK) {
- ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
- return NULL;
- }
- /* Check first to see if we've already been checked */
- for (x = 0; x < q->stacklen; x++) {
- if (!strcasecmp(q->incstack[x], context))
- return NULL;
- }
- if (bypass) /* bypass means we only look there */
- tmp = bypass;
- else { /* look in contexts */
- tmp = NULL;
- while ((tmp = ast_walk_contexts(tmp)) ) {
- if (!strcmp(tmp->name, context))
- break;
- }
- if (!tmp)
- return NULL;
- }
- if (q->status < STATUS_NO_EXTENSION)
- q->status = STATUS_NO_EXTENSION;
-
- /* scan the list trying to match extension and CID */
- eroot = NULL;
- while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
- int match = extension_match_core(eroot->exten, exten, action);
- /* 0 on fail, 1 on match, 2 on earlymatch */
-
- if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
- continue; /* keep trying */
- if (match == 2 && action == E_MATCHMORE) {
- /* We match an extension ending in '!'.
- * The decision in this case is final and is NULL (no match).
- */
- return NULL;
- }
- /* found entry, now look for the right priority */
- if (q->status < STATUS_NO_PRIORITY)
- q->status = STATUS_NO_PRIORITY;
- e = NULL;
- while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
- /* Match label or priority */
- if (action == E_FINDLABEL) {
- if (q->status < STATUS_NO_LABEL)
- q->status = STATUS_NO_LABEL;
- if (label && e->label && !strcmp(label, e->label))
- break; /* found it */
- } else if (e->priority == priority) {
- break; /* found it */
- } /* else keep searching */
- }
- if (e) { /* found a valid match */
- q->status = STATUS_SUCCESS;
- q->foundcontext = context;
- return e;
- }
- }
- /* Check alternative switches */
- AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
- struct ast_switch *asw = pbx_findswitch(sw->name);
- ast_switch_f *aswf = NULL;
- char *datap;
-
- if (!asw) {
- ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
- continue;
- }
- /* Substitute variables now */
- if (sw->eval) {
- if (!(tmpdata = ast_threadstorage_get(&switch_data, 512))) {
- ast_log(LOG_WARNING, "Can't evaluate switch?!");
- continue;
- }
- pbx_substitute_variables_helper(chan, sw->data, tmpdata, 512);
- }
-
- /* equivalent of extension_match_core() at the switch level */
- if (action == E_CANMATCH)
- aswf = asw->canmatch;
- else if (action == E_MATCHMORE)
- aswf = asw->matchmore;
- else /* action == E_MATCH */
- aswf = asw->exists;
- datap = sw->eval ? tmpdata : sw->data;
- if (!aswf)
- res = 0;
- else {
- if (chan)
- ast_autoservice_start(chan);
- res = aswf(chan, context, exten, priority, callerid, datap);
- if (chan)
- ast_autoservice_stop(chan);
- }
- if (res) { /* Got a match */
- q->swo = asw;
- q->data = datap;
- q->foundcontext = context;
- /* XXX keep status = STATUS_NO_CONTEXT ? */
- return NULL;
- }
- }
- q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
- /* Now try any includes we have in this context */
- for (i = tmp->includes; i; i = i->next) {
- if (include_valid(i)) {
- if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action)))
- return e;
- if (q->swo)
- return NULL;
- }
- }
- return NULL;
-}
-
-/*! \brief extract offset:length from variable name.
- * Returns 1 if there is a offset:length part, which is
- * trimmed off (values go into variables)
- */
-static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
-{
- int parens=0;
-
- *offset = 0;
- *length = INT_MAX;
- *isfunc = 0;
- for (; *var; var++) {
- if (*var == '(') {
- (*isfunc)++;
- parens++;
- } else if (*var == ')') {
- parens--;
- } else if (*var == ':' && parens == 0) {
- *var++ = '\0';
- sscanf(var, "%d:%d", offset, length);
- return 1; /* offset:length valid */
- }
- }
- return 0;
-}
-
-/*! \brief takes a substring. It is ok to call with value == workspace.
- *
- * offset < 0 means start from the end of the string and set the beginning
- * to be that many characters back.
- * length is the length of the substring. A value less than 0 means to leave
- * that many off the end.
- * Always return a copy in workspace.
- */
-static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
-{
- char *ret = workspace;
- int lr; /* length of the input string after the copy */
-
- ast_copy_string(workspace, value, workspace_len); /* always make a copy */
-
- lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
-
- /* Quick check if no need to do anything */
- if (offset == 0 && length >= lr) /* take the whole string */
- return ret;
-
- if (offset < 0) { /* translate negative offset into positive ones */
- offset = lr + offset;
- if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
- offset = 0;
- }
-
- /* too large offset result in empty string so we know what to return */
- if (offset >= lr)
- return ret + lr; /* the final '\0' */
-
- ret += offset; /* move to the start position */
- if (length >= 0 && length < lr - offset) /* truncate if necessary */
- ret[length] = '\0';
- else if (length < 0) {
- if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
- ret[lr + length - offset] = '\0';
- else
- ret[0] = '\0';
- }
-
- return ret;
-}
-
-/*! \brief pbx_retrieve_variable: Support for Asterisk built-in variables
- ---*/
-void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
-{
- const char not_found = '\0';
- char *tmpvar;
- const char *s; /* the result */
- int offset, length;
- int i, need_substring;
- struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */
-
- if (c) {
- ast_channel_lock(c);
- places[0] = &c->varshead;
- }
- /*
- * Make a copy of var because parse_variable_name() modifies the string.
- * Then if called directly, we might need to run substring() on the result;
- * remember this for later in 'need_substring', 'offset' and 'length'
- */
- tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
- need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
-
- /*
- * Look first into predefined variables, then into variable lists.
- * Variable 's' points to the result, according to the following rules:
- * s == &not_found (set at the beginning) means that we did not find a
- * matching variable and need to look into more places.
- * If s != &not_found, s is a valid result string as follows:
- * s = NULL if the variable does not have a value;
- * you typically do this when looking for an unset predefined variable.
- * s = workspace if the result has been assembled there;
- * typically done when the result is built e.g. with an snprintf(),
- * so we don't need to do an additional copy.
- * s != workspace in case we have a string, that needs to be copied
- * (the ast_copy_string is done once for all at the end).
- * Typically done when the result is already available in some string.
- */
- s = &not_found; /* default value */
- if (c) { /* This group requires a valid channel */
- /* Names with common parts are looked up a piece at a time using strncmp. */
- if (!strncmp(var, "CALL", 4)) {
- if (!strncmp(var + 4, "ING", 3)) {
- if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */
- snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
- s = workspace;
- } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */
- snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
- s = workspace;
- } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */
- snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
- s = workspace;
- } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */
- snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
- s = workspace;
- }
- }
- } else if (!strcmp(var, "HINT")) {
- s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
- } else if (!strcmp(var, "HINTNAME")) {
- s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
- } else if (!strcmp(var, "EXTEN")) {
- s = c->exten;
- } else if (!strcmp(var, "CONTEXT")) {
- s = c->context;
- } else if (!strcmp(var, "PRIORITY")) {
- snprintf(workspace, workspacelen, "%d", c->priority);
- s = workspace;
- } else if (!strcmp(var, "CHANNEL")) {
- s = c->name;
- } else if (!strcmp(var, "UNIQUEID")) {
- s = c->uniqueid;
- } else if (!strcmp(var, "HANGUPCAUSE")) {
- snprintf(workspace, workspacelen, "%d", c->hangupcause);
- s = workspace;
- }
- }
- if (s == &not_found) { /* look for more */
- if (!strcmp(var, "EPOCH")) {
- snprintf(workspace, workspacelen, "%u",(int)time(NULL));
- s = workspace;
- } else if (!strcmp(var, "SYSTEMNAME")) {
- s = ast_config_AST_SYSTEM_NAME;
- }
- }
- /* if not found, look into chanvars or global vars */
- for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
- struct ast_var_t *variables;
- if (!places[i])
- continue;
- if (places[i] == &globals)
- ast_mutex_lock(&globalslock);
- AST_LIST_TRAVERSE(places[i], variables, entries) {
- if (strcasecmp(ast_var_name(variables), var)==0) {
- s = ast_var_value(variables);
- break;
- }
- }
- if (places[i] == &globals)
- ast_mutex_unlock(&globalslock);
- }
- if (s == &not_found || s == NULL)
- *ret = NULL;
- else {
- if (s != workspace)
- ast_copy_string(workspace, s, workspacelen);
- *ret = workspace;
- if (need_substring)
- *ret = substring(*ret, offset, length, workspace, workspacelen);
- }
-
- if (c)
- ast_channel_unlock(c);
-}
-
-/*! \brief CLI function to show installed custom functions
- \addtogroup CLI_functions
- */
-static int handle_show_functions_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_custom_function *acf;
- int count_acf = 0;
- int like = 0;
-
- if (argc == 4 && (!strcmp(argv[2], "like")) ) {
- like = 1;
- } else if (argc != 2) {
- return RESULT_SHOWUSAGE;
- }
-
- ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
-
- AST_LIST_LOCK(&acf_root);
- AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
- if (!like || strstr(acf->name, argv[3])) {
- count_acf++;
- ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis);
- }
- }
- AST_LIST_UNLOCK(&acf_root);
-
- ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
-
- return RESULT_SUCCESS;
-}
-static int handle_show_functions(int fd, int argc, char *argv[])
-{
- struct ast_custom_function *acf;
- int count_acf = 0;
- int like = 0;
-
- if (argc == 5 && (!strcmp(argv[3], "like")) ) {
- like = 1;
- } else if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
-
- ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
-
- AST_LIST_LOCK(&acf_root);
- AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
- if (!like || strstr(acf->name, argv[4])) {
- count_acf++;
- ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis);
- }
- }
- AST_LIST_UNLOCK(&acf_root);
-
- ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
-
- return RESULT_SUCCESS;
-}
-
-static int handle_show_function_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_custom_function *acf;
- /* Maximum number of characters added by terminal coloring is 22 */
- char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
- char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
- char stxtitle[40], *syntax = NULL;
- int synopsis_size, description_size, syntax_size;
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
-
- if (!(acf = ast_custom_function_find(argv[2]))) {
- ast_cli(fd, "No function by that name registered.\n");
- return RESULT_FAILURE;
-
- }
-
- if (acf->synopsis)
- synopsis_size = strlen(acf->synopsis) + 23;
- else
- synopsis_size = strlen("Not available") + 23;
- synopsis = alloca(synopsis_size);
-
- if (acf->desc)
- description_size = strlen(acf->desc) + 23;
- else
- description_size = strlen("Not available") + 23;
- description = alloca(description_size);
-
- if (acf->syntax)
- syntax_size = strlen(acf->syntax) + 23;
- else
- syntax_size = strlen("Not available") + 23;
- syntax = alloca(syntax_size);
-
- snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name);
- term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
- term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
- term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
- term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
- term_color(syntax,
- acf->syntax ? acf->syntax : "Not available",
- COLOR_CYAN, 0, syntax_size);
- term_color(synopsis,
- acf->synopsis ? acf->synopsis : "Not available",
- COLOR_CYAN, 0, synopsis_size);
- term_color(description,
- acf->desc ? acf->desc : "Not available",
- COLOR_CYAN, 0, description_size);
-
- ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_show_function(int fd, int argc, char *argv[])
-{
- struct ast_custom_function *acf;
- /* Maximum number of characters added by terminal coloring is 22 */
- char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
- char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
- char stxtitle[40], *syntax = NULL;
- int synopsis_size, description_size, syntax_size;
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- if (!(acf = ast_custom_function_find(argv[3]))) {
- ast_cli(fd, "No function by that name registered.\n");
- return RESULT_FAILURE;
-
- }
-
- if (acf->synopsis)
- synopsis_size = strlen(acf->synopsis) + 23;
- else
- synopsis_size = strlen("Not available") + 23;
- synopsis = alloca(synopsis_size);
-
- if (acf->desc)
- description_size = strlen(acf->desc) + 23;
- else
- description_size = strlen("Not available") + 23;
- description = alloca(description_size);
-
- if (acf->syntax)
- syntax_size = strlen(acf->syntax) + 23;
- else
- syntax_size = strlen("Not available") + 23;
- syntax = alloca(syntax_size);
-
- snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name);
- term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
- term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
- term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
- term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
- term_color(syntax,
- acf->syntax ? acf->syntax : "Not available",
- COLOR_CYAN, 0, syntax_size);
- term_color(synopsis,
- acf->synopsis ? acf->synopsis : "Not available",
- COLOR_CYAN, 0, synopsis_size);
- term_color(description,
- acf->desc ? acf->desc : "Not available",
- COLOR_CYAN, 0, description_size);
-
- ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
-
- return RESULT_SUCCESS;
-}
-
-static char *complete_show_function(const char *line, const char *word, int pos, int state)
-{
- struct ast_custom_function *acf;
- char *ret = NULL;
- int which = 0;
- int wordlen = strlen(word);
-
- /* case-insensitive for convenience in this 'complete' function */
- AST_LIST_LOCK(&acf_root);
- AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
- if (!strncasecmp(word, acf->name, wordlen) && ++which > state) {
- ret = strdup(acf->name);
- break;
- }
- }
- AST_LIST_UNLOCK(&acf_root);
-
- return ret;
-}
-
-struct ast_custom_function *ast_custom_function_find(const char *name)
-{
- struct ast_custom_function *acf = NULL;
-
- AST_LIST_LOCK(&acf_root);
- AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
- if (!strcmp(name, acf->name))
- break;
- }
- AST_LIST_UNLOCK(&acf_root);
-
- return acf;
-}
-
-int ast_custom_function_unregister(struct ast_custom_function *acf)
-{
- struct ast_custom_function *cur;
-
- if (!acf)
- return -1;
-
- AST_LIST_LOCK(&acf_root);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
- if (cur == acf) {
- AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&acf_root);
-
- return acf ? 0 : -1;
-}
-
-int ast_custom_function_register(struct ast_custom_function *acf)
-{
- struct ast_custom_function *cur;
-
- if (!acf)
- return -1;
-
- AST_LIST_LOCK(&acf_root);
-
- if (ast_custom_function_find(acf->name)) {
- ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
- AST_LIST_UNLOCK(&acf_root);
- return -1;
- }
-
- /* Store in alphabetical order */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
- if (strcasecmp(acf->name, cur->name) < 0) {
- AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- if (!cur)
- AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
-
- AST_LIST_UNLOCK(&acf_root);
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
-
- return 0;
-}
-
-/*! \brief return a pointer to the arguments of the function,
- * and terminates the function name with '\\0'
- */
-static char *func_args(char *function)
-{
- char *args = strchr(function, '(');
-
- if (!args)
- ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n");
- else {
- char *p;
- *args++ = '\0';
- if ((p = strrchr(args, ')')) )
- *p = '\0';
- else
- ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
- }
- return args;
-}
-
-int ast_func_read(struct ast_channel *chan, char *function, char *workspace, size_t len)
-{
- char *args = func_args(function);
- struct ast_custom_function *acfptr = ast_custom_function_find(function);
-
- if (acfptr == NULL)
- ast_log(LOG_ERROR, "Function %s not registered\n", function);
- else if (!acfptr->read)
- ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
- else
- return acfptr->read(chan, function, args, workspace, len);
- return -1;
-}
-
-int ast_func_write(struct ast_channel *chan, char *function, const char *value)
-{
- char *args = func_args(function);
- struct ast_custom_function *acfptr = ast_custom_function_find(function);
-
- if (acfptr == NULL)
- ast_log(LOG_ERROR, "Function %s not registered\n", function);
- else if (!acfptr->write)
- ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
- else
- return acfptr->write(chan, function, args, value);
-
- return -1;
-}
-
-static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
-{
- /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
- zero-filled */
- char *cp4;
- const char *tmp, *whereweare;
- int length, offset, offset2, isfunction;
- char *workspace = NULL;
- char *ltmp = NULL, *var = NULL;
- char *nextvar, *nextexp, *nextthing;
- char *vars, *vare;
- int pos, brackets, needsub, len;
-
- whereweare=tmp=cp1;
- while (!ast_strlen_zero(whereweare) && count) {
- /* Assume we're copying the whole remaining string */
- pos = strlen(whereweare);
- nextvar = NULL;
- nextexp = NULL;
- nextthing = strchr(whereweare, '$');
- if (nextthing) {
- switch(nextthing[1]) {
- case '{':
- nextvar = nextthing;
- pos = nextvar - whereweare;
- break;
- case '[':
- nextexp = nextthing;
- pos = nextexp - whereweare;
- break;
- default:
- pos = 1;
- }
- }
-
- if (pos) {
- /* Can't copy more than 'count' bytes */
- if (pos > count)
- pos = count;
-
- /* Copy that many bytes */
- memcpy(cp2, whereweare, pos);
-
- count -= pos;
- cp2 += pos;
- whereweare += pos;
- }
-
- if (nextvar) {
- /* We have a variable. Find the start and end, and determine
- if we are going to have to recursively call ourselves on the
- contents */
- vars = vare = nextvar + 2;
- brackets = 1;
- needsub = 0;
-
- /* Find the end of it */
- while (brackets && *vare) {
- if ((vare[0] == '$') && (vare[1] == '{')) {
- needsub++;
- } else if (vare[0] == '{') {
- brackets++;
- } else if (vare[0] == '}') {
- brackets--;
- } else if ((vare[0] == '$') && (vare[1] == '['))
- needsub++;
- vare++;
- }
- if (brackets)
- ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
- len = vare - vars - 1;
-
- /* Skip totally over variable string */
- whereweare += (len + 3);
-
- if (!var)
- var = alloca(VAR_BUF_SIZE);
-
- /* Store variable name (and truncate) */
- ast_copy_string(var, vars, len + 1);
-
- /* Substitute if necessary */
- if (needsub) {
- if (!ltmp)
- ltmp = alloca(VAR_BUF_SIZE);
-
- memset(ltmp, 0, VAR_BUF_SIZE);
- pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
- vars = ltmp;
- } else {
- vars = var;
- }
-
- if (!workspace)
- workspace = alloca(VAR_BUF_SIZE);
-
- workspace[0] = '\0';
-
- parse_variable_name(vars, &offset, &offset2, &isfunction);
- if (isfunction) {
- /* Evaluate function */
- if (c || !headp)
- cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
- else {
- struct varshead old;
- struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars);
- if (c) {
- memcpy(&old, &c->varshead, sizeof(old));
- memcpy(&c->varshead, headp, sizeof(c->varshead));
- cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
- /* Don't deallocate the varshead that was passed in */
- memcpy(&c->varshead, &old, sizeof(c->varshead));
- ast_channel_free(c);
- } else
- ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
- } else {
- /* Retrieve variable value */
- pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
- }
- if (cp4) {
- cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
-
- length = strlen(cp4);
- if (length > count)
- length = count;
- memcpy(cp2, cp4, length);
- count -= length;
- cp2 += length;
- }
- } else if (nextexp) {
- /* We have an expression. Find the start and end, and determine
- if we are going to have to recursively call ourselves on the
- contents */
- vars = vare = nextexp + 2;
- brackets = 1;
- needsub = 0;
-
- /* Find the end of it */
- while(brackets && *vare) {
- if ((vare[0] == '$') && (vare[1] == '[')) {
- needsub++;
- brackets++;
- vare++;
- } else if (vare[0] == '[') {
- brackets++;
- } else if (vare[0] == ']') {
- brackets--;
- } else if ((vare[0] == '$') && (vare[1] == '{')) {
- needsub++;
- vare++;
- }
- vare++;
- }
- if (brackets)
- ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
- len = vare - vars - 1;
-
- /* Skip totally over expression */
- whereweare += (len + 3);
-
- if (!var)
- var = alloca(VAR_BUF_SIZE);
-
- /* Store variable name (and truncate) */
- ast_copy_string(var, vars, len + 1);
-
- /* Substitute if necessary */
- if (needsub) {
- if (!ltmp)
- ltmp = alloca(VAR_BUF_SIZE);
-
- memset(ltmp, 0, VAR_BUF_SIZE);
- pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
- vars = ltmp;
- } else {
- vars = var;
- }
-
- length = ast_expr(vars, cp2, count);
-
- if (length) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2);
- count -= length;
- cp2 += length;
- }
- }
- }
-}
-
-void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
-{
- pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
-}
-
-void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
-{
- pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
-}
-
-static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e)
-{
- memset(passdata, 0, datalen);
-
- /* No variables or expressions in e->data, so why scan it? */
- if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) {
- ast_copy_string(passdata, e->data, datalen);
- return;
- }
-
- pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
-}
-
-/*!
- * \brief The return value depends on the action:
- *
- * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
- * and return 0 on failure, -1 on match;
- * E_FINDLABEL maps the label to a priority, and returns
- * the priority on success, ... XXX
- * E_SPAWN, spawn an application,
- * and return 0 on success, -1 on failure.
- *
- * \note The channel is auto-serviced in this function, because doing an extension
- * match may block for a long time. For example, if the lookup has to use a network
- * dialplan switch, such as DUNDi or IAX2, it may take a while. However, the channel
- * auto-service code will queue up any important signalling frames to be processed
- * after this is done.
- */
-static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
- const char *context, const char *exten, int priority,
- const char *label, const char *callerid, enum ext_match_t action)
-{
- struct ast_exten *e;
- struct ast_app *app;
- int res;
- struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
- char passdata[EXT_DATA_SIZE];
-
- int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
-
- ast_rdlock_contexts();
- e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
- if (e) {
- if (matching_action) {
- ast_unlock_contexts();
- return -1; /* success, we found it */
- } else if (action == E_FINDLABEL) { /* map the label to a priority */
- res = e->priority;
- ast_unlock_contexts();
- return res; /* the priority we were looking for */
- } else { /* spawn */
- app = pbx_findapp(e->app);
- ast_unlock_contexts();
- if (!app) {
- ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
- return -1;
- }
- if (c->context != context)
- ast_copy_string(c->context, context, sizeof(c->context));
- if (c->exten != exten)
- ast_copy_string(c->exten, exten, sizeof(c->exten));
- c->priority = priority;
- pbx_substitute_variables(passdata, sizeof(passdata), c, e);
- if (option_debug) {
- ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
- }
- if (option_verbose > 2) {
- char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
- ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
- exten, context, priority,
- term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
- term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
- term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
- "in new stack");
- }
- manager_event(EVENT_FLAG_CALL, "Newexten",
- "Channel: %s\r\n"
- "Context: %s\r\n"
- "Extension: %s\r\n"
- "Priority: %d\r\n"
- "Application: %s\r\n"
- "AppData: %s\r\n"
- "Uniqueid: %s\r\n",
- c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
- return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */
- }
- } else if (q.swo) { /* not found here, but in another switch */
- ast_unlock_contexts();
- if (matching_action) {
- return -1;
- } else {
- if (!q.swo->exec) {
- ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
- res = -1;
- }
- return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
- }
- } else { /* not found anywhere, see what happened */
- ast_unlock_contexts();
- switch (q.status) {
- case STATUS_NO_CONTEXT:
- if (!matching_action)
- ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
- break;
- case STATUS_NO_EXTENSION:
- if (!matching_action)
- ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
- break;
- case STATUS_NO_PRIORITY:
- if (!matching_action)
- ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
- break;
- case STATUS_NO_LABEL:
- if (context)
- ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Shouldn't happen!\n");
- }
-
- return (matching_action) ? 0 : -1;
- }
-}
-
-/*! \brief ast_hint_extension: Find hint for given extension in context */
-static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
-{
- struct ast_exten *e;
- struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
-
- ast_rdlock_contexts();
- e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
- ast_unlock_contexts();
-
- return e;
-}
-
-/*! \brief ast_extensions_state2: Check state of extension by using hints */
-static int ast_extension_state2(struct ast_exten *e)
-{
- char hint[AST_MAX_EXTENSION];
- char *cur, *rest;
- int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1;
- int busy = 0, inuse = 0, ring = 0;
-
- if (!e)
- return -1;
-
- ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint));
-
- rest = hint; /* One or more devices separated with a & character */
- while ( (cur = strsep(&rest, "&")) ) {
- int res = ast_device_state(cur);
- switch (res) {
- case AST_DEVICE_NOT_INUSE:
- allunavailable = 0;
- allbusy = 0;
- allonhold = 0;
- break;
- case AST_DEVICE_INUSE:
- inuse = 1;
- allunavailable = 0;
- allfree = 0;
- allonhold = 0;
- break;
- case AST_DEVICE_RINGING:
- ring = 1;
- allunavailable = 0;
- allfree = 0;
- allonhold = 0;
- break;
- case AST_DEVICE_RINGINUSE:
- inuse = 1;
- ring = 1;
- allunavailable = 0;
- allfree = 0;
- allonhold = 0;
- break;
- case AST_DEVICE_ONHOLD:
- allunavailable = 0;
- allfree = 0;
- break;
- case AST_DEVICE_BUSY:
- allunavailable = 0;
- allfree = 0;
- allonhold = 0;
- busy = 1;
- break;
- case AST_DEVICE_UNAVAILABLE:
- case AST_DEVICE_INVALID:
- allbusy = 0;
- allfree = 0;
- allonhold = 0;
- break;
- default:
- allunavailable = 0;
- allbusy = 0;
- allfree = 0;
- allonhold = 0;
- }
- }
-
- if (!inuse && ring)
- return AST_EXTENSION_RINGING;
- if (inuse && ring)
- return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
- if (inuse)
- return AST_EXTENSION_INUSE;
- if (allfree)
- return AST_EXTENSION_NOT_INUSE;
- if (allonhold)
- return AST_EXTENSION_ONHOLD;
- if (allbusy)
- return AST_EXTENSION_BUSY;
- if (allunavailable)
- return AST_EXTENSION_UNAVAILABLE;
- if (busy)
- return AST_EXTENSION_INUSE;
-
- return AST_EXTENSION_NOT_INUSE;
-}
-
-/*! \brief ast_extension_state2str: Return extension_state as string */
-const char *ast_extension_state2str(int extension_state)
-{
- int i;
-
- for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
- if (extension_states[i].extension_state == extension_state)
- return extension_states[i].text;
- }
- return "Unknown";
-}
-
-/*! \brief ast_extension_state: Check extension state for an extension by using hint */
-int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
-{
- struct ast_exten *e;
-
- e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */
- if (!e)
- return -1; /* No hint, return -1 */
-
- return ast_extension_state2(e); /* Check all devices in the hint */
-}
-
-void ast_hint_state_changed(const char *device)
-{
- struct ast_hint *hint;
-
- AST_LIST_LOCK(&hints);
-
- AST_LIST_TRAVERSE(&hints, hint, list) {
- struct ast_state_cb *cblist;
- char buf[AST_MAX_EXTENSION];
- char *parse = buf;
- char *cur;
- int state;
-
- ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
- while ( (cur = strsep(&parse, "&")) ) {
- if (!strcasecmp(cur, device))
- break;
- }
- if (!cur)
- continue;
-
- /* Get device state for this hint */
- state = ast_extension_state2(hint->exten);
-
- if ((state == -1) || (state == hint->laststate))
- continue;
-
- /* Device state changed since last check - notify the watchers */
-
- /* For general callbacks */
- for (cblist = statecbs; cblist; cblist = cblist->next)
- cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
-
- /* For extension callbacks */
- for (cblist = hint->callbacks; cblist; cblist = cblist->next)
- cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
-
- hint->laststate = state; /* record we saw the change */
- }
-
- AST_LIST_UNLOCK(&hints);
-}
-
-/*! \brief ast_extension_state_add: Add watcher for extension states */
-int ast_extension_state_add(const char *context, const char *exten,
- ast_state_cb_type callback, void *data)
-{
- struct ast_hint *hint;
- struct ast_state_cb *cblist;
- struct ast_exten *e;
-
- /* If there's no context and extension: add callback to statecbs list */
- if (!context && !exten) {
- AST_LIST_LOCK(&hints);
-
- for (cblist = statecbs; cblist; cblist = cblist->next) {
- if (cblist->callback == callback) {
- cblist->data = data;
- AST_LIST_UNLOCK(&hints);
- return 0;
- }
- }
-
- /* Now insert the callback */
- if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
- AST_LIST_UNLOCK(&hints);
- return -1;
- }
- cblist->id = 0;
- cblist->callback = callback;
- cblist->data = data;
-
- cblist->next = statecbs;
- statecbs = cblist;
-
- AST_LIST_UNLOCK(&hints);
- return 0;
- }
-
- if (!context || !exten)
- return -1;
-
- /* This callback type is for only one hint, so get the hint */
- e = ast_hint_extension(NULL, context, exten);
- if (!e) {
- return -1;
- }
-
- /* Find the hint in the list of hints */
- AST_LIST_LOCK(&hints);
-
- AST_LIST_TRAVERSE(&hints, hint, list) {
- if (hint->exten == e)
- break;
- }
-
- if (!hint) {
- /* We have no hint, sorry */
- AST_LIST_UNLOCK(&hints);
- return -1;
- }
-
- /* Now insert the callback in the callback list */
- if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
- AST_LIST_UNLOCK(&hints);
- return -1;
- }
- cblist->id = stateid++; /* Unique ID for this callback */
- cblist->callback = callback; /* Pointer to callback routine */
- cblist->data = data; /* Data for the callback */
-
- cblist->next = hint->callbacks;
- hint->callbacks = cblist;
-
- AST_LIST_UNLOCK(&hints);
- return cblist->id;
-}
-
-/*! \brief ast_extension_state_del: Remove a watcher from the callback list */
-int ast_extension_state_del(int id, ast_state_cb_type callback)
-{
- struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
- int ret = -1;
-
- if (!id && !callback)
- return -1;
-
- AST_LIST_LOCK(&hints);
-
- if (!id) { /* id == 0 is a callback without extension */
- for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
- if ((*p_cur)->callback == callback)
- break;
- }
- } else { /* callback with extension, find the callback based on ID */
- struct ast_hint *hint;
- AST_LIST_TRAVERSE(&hints, hint, list) {
- for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
- if ((*p_cur)->id == id)
- break;
- }
- if (*p_cur) /* found in the inner loop */
- break;
- }
- }
- if (p_cur && *p_cur) {
- struct ast_state_cb *cur = *p_cur;
- *p_cur = cur->next;
- free(cur);
- ret = 0;
- }
- AST_LIST_UNLOCK(&hints);
- return ret;
-}
-
-/*! \brief ast_add_hint: Add hint to hint list, check initial extension state */
-static int ast_add_hint(struct ast_exten *e)
-{
- struct ast_hint *hint;
-
- if (!e)
- return -1;
-
- AST_LIST_LOCK(&hints);
-
- /* Search if hint exists, do nothing */
- AST_LIST_TRAVERSE(&hints, hint, list) {
- if (hint->exten == e) {
- AST_LIST_UNLOCK(&hints);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
- return -1;
- }
- }
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
-
- if (!(hint = ast_calloc(1, sizeof(*hint)))) {
- AST_LIST_UNLOCK(&hints);
- return -1;
- }
- /* Initialize and insert new item at the top */
- hint->exten = e;
- hint->laststate = ast_extension_state2(e);
- AST_LIST_INSERT_HEAD(&hints, hint, list);
-
- AST_LIST_UNLOCK(&hints);
- return 0;
-}
-
-/*! \brief ast_change_hint: Change hint for an extension */
-static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
-{
- struct ast_hint *hint;
- int res = -1;
-
- AST_LIST_LOCK(&hints);
- AST_LIST_TRAVERSE(&hints, hint, list) {
- if (hint->exten == oe) {
- hint->exten = ne;
- res = 0;
- break;
- }
- }
- AST_LIST_UNLOCK(&hints);
-
- return res;
-}
-
-/*! \brief ast_remove_hint: Remove hint from extension */
-static int ast_remove_hint(struct ast_exten *e)
-{
- /* Cleanup the Notifys if hint is removed */
- struct ast_hint *hint;
- struct ast_state_cb *cblist, *cbprev;
- int res = -1;
-
- if (!e)
- return -1;
-
- AST_LIST_LOCK(&hints);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
- if (hint->exten == e) {
- cbprev = NULL;
- cblist = hint->callbacks;
- while (cblist) {
- /* Notify with -1 and remove all callbacks */
- cbprev = cblist;
- cblist = cblist->next;
- cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data);
- free(cbprev);
- }
- hint->callbacks = NULL;
- AST_LIST_REMOVE_CURRENT(&hints, list);
- free(hint);
- res = 0;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&hints);
-
- return res;
-}
-
-
-/*! \brief ast_get_hint: Get hint for channel */
-int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
-{
- struct ast_exten *e = ast_hint_extension(c, context, exten);
-
- if (e) {
- if (hint)
- ast_copy_string(hint, ast_get_extension_app(e), hintsize);
- if (name) {
- const char *tmp = ast_get_extension_app_data(e);
- if (tmp)
- ast_copy_string(name, tmp, namesize);
- }
- return -1;
- }
- return 0;
-}
-
-int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
-{
- return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
-}
-
-int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
-{
- return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
-}
-
-int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
-{
- return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
-}
-
-int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
-{
- return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
-}
-
-int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
-{
- return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
-}
-
-int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
-{
- return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
-}
-
-/* helper function to set extension and priority */
-static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
-{
- ast_channel_lock(c);
- ast_copy_string(c->exten, exten, sizeof(c->exten));
- c->priority = pri;
- ast_channel_unlock(c);
-}
-
-/*!
- * \brief collect digits from the channel into the buffer,
- * return -1 on error, 0 on timeout or done.
- */
-static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
-{
- int digit;
-
- buf[pos] = '\0'; /* make sure it is properly terminated */
- while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
- /* As long as we're willing to wait, and as long as it's not defined,
- keep reading digits until we can't possibly get a right answer anymore. */
- digit = ast_waitfordigit(c, waittime * 1000);
- if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
- c->_softhangup = 0;
- } else {
- if (!digit) /* No entry */
- break;
- if (digit < 0) /* Error, maybe a hangup */
- return -1;
- if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
- buf[pos++] = digit;
- buf[pos] = '\0';
- }
- waittime = c->pbx->dtimeout;
- }
- }
- return 0;
-}
-
-static int __ast_pbx_run(struct ast_channel *c)
-{
- int found = 0; /* set if we find at least one match */
- int res = 0;
- int autoloopflag;
- int error = 0; /* set an error conditions */
-
- /* A little initial setup here */
- if (c->pbx) {
- ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
- /* XXX and now what ? */
- free(c->pbx);
- }
- if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
- return -1;
- if (c->amaflags) {
- if (!c->cdr) {
- c->cdr = ast_cdr_alloc();
- if (!c->cdr) {
- ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
- free(c->pbx);
- return -1;
- }
- ast_cdr_init(c->cdr, c);
- }
- }
- /* Set reasonable defaults */
- c->pbx->rtimeout = 10;
- c->pbx->dtimeout = 5;
-
- autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
- ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
-
- /* Start by trying whatever the channel is set to */
- if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
- /* If not successful fall back to 's' */
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
- /* XXX the original code used the existing priority in the call to
- * ast_exists_extension(), and reset it to 1 afterwards.
- * I believe the correct thing is to set it to 1 immediately.
- */
- set_ext_pri(c, "s", 1);
- if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
- /* JK02: And finally back to default if everything else failed */
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
- ast_copy_string(c->context, "default", sizeof(c->context));
- }
- }
- if (c->cdr && ast_tvzero(c->cdr->start))
- ast_cdr_start(c->cdr);
- for (;;) {
- char dst_exten[256]; /* buffer to accumulate digits */
- int pos = 0; /* XXX should check bounds */
- int digit = 0;
-
- /* loop on priorities in this context/exten */
- while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
- found = 1;
- if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
- /* Something bad happened, or a hangup has been requested. */
- if (strchr("0123456789ABCDEF*#", res)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
- pos = 0;
- dst_exten[pos++] = digit = res;
- dst_exten[pos] = '\0';
- break;
- }
- if (res == AST_PBX_KEEPALIVE) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
- error = 1;
- break;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
- if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
- c->_softhangup = 0;
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
- /* atimeout, nothing bad */
- } else {
- if (c->cdr)
- ast_cdr_update(c);
- error = 1;
- break;
- }
- }
- if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
- c->_softhangup = 0;
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) {
- set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
- /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
- c->whentohangup = 0;
- c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
- } else if (c->_softhangup) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
- c->exten, c->priority);
- error = 1;
- break;
- }
- c->priority++;
- } /* end while - from here on we can use 'break' to go out */
- if (error)
- break;
-
- /* XXX we get here on non-existing extension or a keypress or hangup ? */
-
- if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
- /* If there is no match at priority 1, it is not a valid extension anymore.
- * Try to continue at "i", 1 or exit if the latter does not exist.
- */
- if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
- pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
- set_ext_pri(c, "i", 1);
- } else {
- ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
- c->name, c->exten, c->context);
- error = 1; /* we know what to do with it */
- break;
- }
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
- /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
- c->_softhangup = 0;
- } else { /* keypress received, get more digits for a full extension */
- int waittime = 0;
- if (digit)
- waittime = c->pbx->dtimeout;
- else if (!autofallthrough)
- waittime = c->pbx->rtimeout;
- if (!waittime) {
- const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
- if (!status)
- status = "UNKNOWN";
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
- if (!strcasecmp(status, "CONGESTION"))
- res = pbx_builtin_congestion(c, "10");
- else if (!strcasecmp(status, "CHANUNAVAIL"))
- res = pbx_builtin_congestion(c, "10");
- else if (!strcasecmp(status, "BUSY"))
- res = pbx_builtin_busy(c, "10");
- error = 1; /* XXX disable message */
- break; /* exit from the 'for' loop */
- }
-
- if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
- break;
- if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
- set_ext_pri(c, dst_exten, 1);
- else {
- /* No such extension */
- if (!ast_strlen_zero(dst_exten)) {
- /* An invalid extension */
- if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
- pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
- set_ext_pri(c, "i", 1);
- } else {
- ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
- found = 1; /* XXX disable message */
- break;
- }
- } else {
- /* A simple timeout */
- if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
- set_ext_pri(c, "t", 1);
- } else {
- ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
- found = 1; /* XXX disable message */
- break;
- }
- }
- }
- if (c->cdr) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);
- ast_cdr_update(c);
- }
- }
- }
- if (!found && !error)
- ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
- if (res != AST_PBX_KEEPALIVE)
- ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING);
- if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
- if (c->cdr && ast_opt_end_cdr_before_h_exten)
- ast_cdr_end(c->cdr);
- set_ext_pri(c, "h", 1);
- while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
- if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
- /* Something bad happened, or a hangup has been requested. */
- if (option_debug)
- ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
- break;
- }
- c->priority++;
- }
- }
- ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
-
- pbx_destroy(c->pbx);
- c->pbx = NULL;
- if (res != AST_PBX_KEEPALIVE)
- ast_hangup(c);
- return 0;
-}
-
-/* Returns 0 on success, non-zero if call limit was reached */
-static int increase_call_count(const struct ast_channel *c)
-{
- int failed = 0;
- double curloadavg;
- ast_mutex_lock(&maxcalllock);
- if (option_maxcalls) {
- if (countcalls >= option_maxcalls) {
- ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
- failed = -1;
- }
- }
- if (option_maxload) {
- getloadavg(&curloadavg, 1);
- if (curloadavg >= option_maxload) {
- ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
- failed = -1;
- }
- }
- if (!failed)
- countcalls++;
- ast_mutex_unlock(&maxcalllock);
-
- return failed;
-}
-
-static void decrease_call_count(void)
-{
- ast_mutex_lock(&maxcalllock);
- if (countcalls > 0)
- countcalls--;
- ast_mutex_unlock(&maxcalllock);
-}
-
-static void destroy_exten(struct ast_exten *e)
-{
- if (e->priority == PRIORITY_HINT)
- ast_remove_hint(e);
-
- if (e->datad)
- e->datad(e->data);
- free(e);
-}
-
-static void *pbx_thread(void *data)
-{
- /* Oh joyeous kernel, we're a new thread, with nothing to do but
- answer this channel and get it going.
- */
- /* NOTE:
- The launcher of this function _MUST_ increment 'countcalls'
- before invoking the function; it will be decremented when the
- PBX has finished running on the channel
- */
- struct ast_channel *c = data;
-
- __ast_pbx_run(c);
- decrease_call_count();
-
- pthread_exit(NULL);
-
- return NULL;
-}
-
-enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
-{
- pthread_t t;
- pthread_attr_t attr;
-
- if (!c) {
- ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
- return AST_PBX_FAILED;
- }
-
- if (increase_call_count(c))
- return AST_PBX_CALL_LIMIT;
-
- /* Start a new thread, and get something handling this channel. */
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
- ast_log(LOG_WARNING, "Failed to create new channel thread\n");
- pthread_attr_destroy(&attr);
- return AST_PBX_FAILED;
- }
- pthread_attr_destroy(&attr);
-
- return AST_PBX_SUCCESS;
-}
-
-enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
-{
- enum ast_pbx_result res = AST_PBX_SUCCESS;
-
- if (increase_call_count(c))
- return AST_PBX_CALL_LIMIT;
-
- res = __ast_pbx_run(c);
- decrease_call_count();
-
- return res;
-}
-
-int ast_active_calls(void)
-{
- return countcalls;
-}
-
-int pbx_set_autofallthrough(int newval)
-{
- int oldval = autofallthrough;
- autofallthrough = newval;
- return oldval;
-}
-
-/* lookup for a context with a given name,
- * return with conlock held if found, NULL if not found
- */
-static struct ast_context *find_context_locked(const char *context)
-{
- struct ast_context *c = NULL;
-
- ast_rdlock_contexts();
- while ( (c = ast_walk_contexts(c)) ) {
- if (!strcmp(ast_get_context_name(c), context))
- return c;
- }
- ast_unlock_contexts();
-
- return NULL;
-}
-
-/*
- * This function locks contexts list by &conlist, search for the right context
- * structure, leave context list locked and call ast_context_remove_include2
- * which removes include, unlock contexts list and return ...
- */
-int ast_context_remove_include(const char *context, const char *include, const char *registrar)
-{
- int ret = -1;
- struct ast_context *c = find_context_locked(context);
-
- if (c) {
- /* found, remove include from this context ... */
- ret = ast_context_remove_include2(c, include, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-/*
- * When we call this function, &conlock lock must be locked, because when
- * we giving *con argument, some process can remove/change this context
- * and after that there can be segfault.
- *
- * This function locks given context, removes include, unlock context and
- * return.
- */
-int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
-{
- struct ast_include *i, *pi = NULL;
- int ret = -1;
-
- ast_mutex_lock(&con->lock);
-
- /* find our include */
- for (i = con->includes; i; pi = i, i = i->next) {
- if (!strcmp(i->name, include) &&
- (!registrar || !strcmp(i->registrar, registrar))) {
- /* remove from list */
- if (pi)
- pi->next = i->next;
- else
- con->includes = i->next;
- /* free include and return */
- free(i);
- ret = 0;
- break;
- }
- }
-
- ast_mutex_unlock(&con->lock);
- return ret;
-}
-
-/*!
- * \note This function locks contexts list by &conlist, search for the rigt context
- * structure, leave context list locked and call ast_context_remove_switch2
- * which removes switch, unlock contexts list and return ...
- */
-int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
-{
- int ret = -1; /* default error return */
- struct ast_context *c = find_context_locked(context);
-
- if (c) {
- /* remove switch from this context ... */
- ret = ast_context_remove_switch2(c, sw, data, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-/*!
- * \brief This function locks given context, removes switch, unlock context and
- * return.
- * \note When we call this function, &conlock lock must be locked, because when
- * we giving *con argument, some process can remove/change this context
- * and after that there can be segfault.
- *
- */
-int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
-{
- struct ast_sw *i;
- int ret = -1;
-
- ast_mutex_lock(&con->lock);
-
- /* walk switches */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
- if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
- (!registrar || !strcmp(i->registrar, registrar))) {
- /* found, remove from list */
- AST_LIST_REMOVE_CURRENT(&con->alts, list);
- free(i); /* free switch and return */
- ret = 0;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
- ast_mutex_unlock(&con->lock);
-
- return ret;
-}
-
-/*
- * \note This functions lock contexts list, search for the right context,
- * call ast_context_remove_extension2, unlock contexts list and return.
- * In this function we are using
- */
-int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
-{
- int ret = -1; /* default error return */
- struct ast_context *c = find_context_locked(context);
-
- if (c) { /* ... remove extension ... */
- ret = ast_context_remove_extension2(c, extension, priority, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-/*!
- * \brief This functionc locks given context, search for the right extension and
- * fires out all peer in this extensions with given priority. If priority
- * is set to 0, all peers are removed. After that, unlock context and
- * return.
- * \note When do you want to call this function, make sure that &conlock is locked,
- * because some process can handle with your *con context before you lock
- * it.
- *
- */
-int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
-{
- struct ast_exten *exten, *prev_exten = NULL;
- struct ast_exten *peer;
-
- ast_mutex_lock(&con->lock);
-
- /* scan the extension list to find matching extension-registrar */
- for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
- if (!strcmp(exten->exten, extension) &&
- (!registrar || !strcmp(exten->registrar, registrar)))
- break;
- }
- if (!exten) {
- /* we can't find right extension */
- ast_mutex_unlock(&con->lock);
- return -1;
- }
-
- /* should we free all peers in this extension? (priority == 0)? */
- if (priority == 0) {
- /* remove this extension from context list */
- if (prev_exten)
- prev_exten->next = exten->next;
- else
- con->root = exten->next;
-
- /* fire out all peers */
- while ( (peer = exten) ) {
- exten = peer->peer; /* prepare for next entry */
- destroy_exten(peer);
- }
- } else {
- /* scan the priority list to remove extension with exten->priority == priority */
- struct ast_exten *previous_peer = NULL;
-
- for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
- if (peer->priority == priority &&
- (!registrar || !strcmp(peer->registrar, registrar) ))
- break; /* found our priority */
- }
- if (!peer) { /* not found */
- ast_mutex_unlock(&con->lock);
- return -1;
- }
- /* we are first priority extension? */
- if (!previous_peer) {
- /*
- * We are first in the priority chain, so must update the extension chain.
- * The next node is either the next priority or the next extension
- */
- struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
-
- if (!prev_exten) /* change the root... */
- con->root = next_node;
- else
- prev_exten->next = next_node; /* unlink */
- if (peer->peer) /* XXX update the new head of the pri list */
- peer->peer->next = peer->next;
- } else { /* easy, we are not first priority in extension */
- previous_peer->peer = peer->peer;
- }
-
- /* now, free whole priority extension */
- destroy_exten(peer);
- /* XXX should we return -1 ? */
- }
- ast_mutex_unlock(&con->lock);
- return 0;
-}
-
-
-/*!
- * \note This function locks contexts list by &conlist, searches for the right context
- * structure, and locks the macrolock mutex in that context.
- * macrolock is used to limit a macro to be executed by one call at a time.
- */
-int ast_context_lockmacro(const char *context)
-{
- struct ast_context *c = NULL;
- int ret = -1;
-
- ast_rdlock_contexts();
-
- while ((c = ast_walk_contexts(c))) {
- if (!strcmp(ast_get_context_name(c), context)) {
- ret = 0;
- break;
- }
- }
-
- ast_unlock_contexts();
-
- /* if we found context, lock macrolock */
- if (ret == 0)
- ret = ast_mutex_lock(&c->macrolock);
-
- return ret;
-}
-
-/*!
- * \note This function locks contexts list by &conlist, searches for the right context
- * structure, and unlocks the macrolock mutex in that context.
- * macrolock is used to limit a macro to be executed by one call at a time.
- */
-int ast_context_unlockmacro(const char *context)
-{
- struct ast_context *c = NULL;
- int ret = -1;
-
- ast_rdlock_contexts();
-
- while ((c = ast_walk_contexts(c))) {
- if (!strcmp(ast_get_context_name(c), context)) {
- ret = 0;
- break;
- }
- }
-
- ast_unlock_contexts();
-
- /* if we found context, unlock macrolock */
- if (ret == 0)
- ret = ast_mutex_unlock(&c->macrolock);
-
- return ret;
-}
-
-/*! \brief Dynamically register a new dial plan application */
-int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
-{
- struct ast_app *tmp, *cur = NULL;
- char tmps[80];
- int length;
-
- AST_LIST_LOCK(&apps);
- AST_LIST_TRAVERSE(&apps, tmp, list) {
- if (!strcasecmp(app, tmp->name)) {
- ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
- AST_LIST_UNLOCK(&apps);
- return -1;
- }
- }
-
- length = sizeof(*tmp) + strlen(app) + 1;
-
- if (!(tmp = ast_calloc(1, length))) {
- AST_LIST_UNLOCK(&apps);
- return -1;
- }
-
- strcpy(tmp->name, app);
- tmp->execute = execute;
- tmp->synopsis = synopsis;
- tmp->description = description;
-
- /* Store in alphabetical order */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
- if (strcasecmp(tmp->name, cur->name) < 0) {
- AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- if (!cur)
- AST_LIST_INSERT_TAIL(&apps, tmp, list);
-
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
-
- AST_LIST_UNLOCK(&apps);
-
- return 0;
-}
-
-/*
- * Append to the list. We don't have a tail pointer because we need
- * to scan the list anyways to check for duplicates during insertion.
- */
-int ast_register_switch(struct ast_switch *sw)
-{
- struct ast_switch *tmp;
-
- AST_LIST_LOCK(&switches);
- AST_LIST_TRAVERSE(&switches, tmp, list) {
- if (!strcasecmp(tmp->name, sw->name)) {
- AST_LIST_UNLOCK(&switches);
- ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
- return -1;
- }
- }
- AST_LIST_INSERT_TAIL(&switches, sw, list);
- AST_LIST_UNLOCK(&switches);
-
- return 0;
-}
-
-void ast_unregister_switch(struct ast_switch *sw)
-{
- AST_LIST_LOCK(&switches);
- AST_LIST_REMOVE(&switches, sw, list);
- AST_LIST_UNLOCK(&switches);
-}
-
-/*
- * Help for CLI commands ...
- */
-static char show_applications_help[] =
-"Usage: core show applications [{like|describing} <text>]\n"
-" List applications which are currently available.\n"
-" If 'like', <text> will be a substring of the app name\n"
-" If 'describing', <text> will be a substring of the description\n";
-
-static char show_functions_help[] =
-"Usage: core show functions [like <text>]\n"
-" List builtin functions, optionally only those matching a given string\n";
-
-static char show_switches_help[] =
-"Usage: core show switches\n"
-" List registered switches\n";
-
-static char show_hints_help[] =
-"Usage: core show hints\n"
-" List registered hints\n";
-
-static char show_globals_help[] =
-"Usage: core show globals\n"
-" List current global dialplan variables and their values\n";
-
-static char show_application_help[] =
-"Usage: core show application <application> [<application> [<application> [...]]]\n"
-" Describes a particular application.\n";
-
-static char show_function_help[] =
-"Usage: core show function <function>\n"
-" Describe a particular dialplan function.\n";
-
-static char show_dialplan_help[] =
-"Usage: dialplan show [exten@][context]\n"
-" Show dialplan\n";
-
-static char set_global_help[] =
-"Usage: core set global <name> <value>\n"
-" Set global dialplan variable <name> to <value>\n";
-
-
-/*
- * \brief 'show application' CLI command implementation functions ...
- */
-
-/*
- * There is a possibility to show informations about more than one
- * application at one time. You can type 'show application Dial Echo' and
- * you will see informations about these two applications ...
- */
-static char *complete_show_application(const char *line, const char *word, int pos, int state)
-{
- struct ast_app *a;
- char *ret = NULL;
- int which = 0;
- int wordlen = strlen(word);
-
- /* return the n-th [partial] matching entry */
- AST_LIST_LOCK(&apps);
- AST_LIST_TRAVERSE(&apps, a, list) {
- if (!strncasecmp(word, a->name, wordlen) && ++which > state) {
- ret = strdup(a->name);
- break;
- }
- }
- AST_LIST_UNLOCK(&apps);
-
- return ret;
-}
-
-static int handle_show_application_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_app *a;
- int app, no_registered_app = 1;
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
-
- /* ... go through all applications ... */
- AST_LIST_LOCK(&apps);
- AST_LIST_TRAVERSE(&apps, a, list) {
- /* ... compare this application name with all arguments given
- * to 'show application' command ... */
- for (app = 2; app < argc; app++) {
- if (!strcasecmp(a->name, argv[app])) {
- /* Maximum number of characters added by terminal coloring is 22 */
- char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
- char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
- int synopsis_size, description_size;
-
- no_registered_app = 0;
-
- if (a->synopsis)
- synopsis_size = strlen(a->synopsis) + 23;
- else
- synopsis_size = strlen("Not available") + 23;
- synopsis = alloca(synopsis_size);
-
- if (a->description)
- description_size = strlen(a->description) + 23;
- else
- description_size = strlen("Not available") + 23;
- description = alloca(description_size);
-
- if (synopsis && description) {
- snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name);
- term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
- term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
- term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
- term_color(synopsis,
- a->synopsis ? a->synopsis : "Not available",
- COLOR_CYAN, 0, synopsis_size);
- term_color(description,
- a->description ? a->description : "Not available",
- COLOR_CYAN, 0, description_size);
-
- ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description);
- } else {
- /* ... one of our applications, show info ...*/
- ast_cli(fd,"\n -= Info about application '%s' =- \n\n"
- "[Synopsis]\n %s\n\n"
- "[Description]\n%s\n",
- a->name,
- a->synopsis ? a->synopsis : "Not available",
- a->description ? a->description : "Not available");
- }
- }
- }
- }
- AST_LIST_UNLOCK(&apps);
-
- /* we found at least one app? no? */
- if (no_registered_app) {
- ast_cli(fd, "Your application(s) is (are) not registered\n");
- return RESULT_FAILURE;
- }
-
- return RESULT_SUCCESS;
-}
-
-static int handle_show_application(int fd, int argc, char *argv[])
-{
- struct ast_app *a;
- int app, no_registered_app = 1;
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- /* ... go through all applications ... */
- AST_LIST_LOCK(&apps);
- AST_LIST_TRAVERSE(&apps, a, list) {
- /* ... compare this application name with all arguments given
- * to 'show application' command ... */
- for (app = 3; app < argc; app++) {
- if (!strcasecmp(a->name, argv[app])) {
- /* Maximum number of characters added by terminal coloring is 22 */
- char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
- char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
- int synopsis_size, description_size;
-
- no_registered_app = 0;
-
- if (a->synopsis)
- synopsis_size = strlen(a->synopsis) + 23;
- else
- synopsis_size = strlen("Not available") + 23;
- synopsis = alloca(synopsis_size);
-
- if (a->description)
- description_size = strlen(a->description) + 23;
- else
- description_size = strlen("Not available") + 23;
- description = alloca(description_size);
-
- if (synopsis && description) {
- snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name);
- term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
- term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
- term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
- term_color(synopsis,
- a->synopsis ? a->synopsis : "Not available",
- COLOR_CYAN, 0, synopsis_size);
- term_color(description,
- a->description ? a->description : "Not available",
- COLOR_CYAN, 0, description_size);
-
- ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description);
- } else {
- /* ... one of our applications, show info ...*/
- ast_cli(fd,"\n -= Info about application '%s' =- \n\n"
- "[Synopsis]\n %s\n\n"
- "[Description]\n%s\n",
- a->name,
- a->synopsis ? a->synopsis : "Not available",
- a->description ? a->description : "Not available");
- }
- }
- }
- }
- AST_LIST_UNLOCK(&apps);
-
- /* we found at least one app? no? */
- if (no_registered_app) {
- ast_cli(fd, "Your application(s) is (are) not registered\n");
- return RESULT_FAILURE;
- }
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief handle_show_hints: CLI support for listing registred dial plan hints */
-static int handle_show_hints(int fd, int argc, char *argv[])
-{
- struct ast_hint *hint;
- int num = 0;
- int watchers;
- struct ast_state_cb *watcher;
-
- if (AST_LIST_EMPTY(&hints)) {
- ast_cli(fd, "There are no registered dialplan hints\n");
- return RESULT_SUCCESS;
- }
- /* ... we have hints ... */
- ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n");
- AST_LIST_LOCK(&hints);
- AST_LIST_TRAVERSE(&hints, hint, list) {
- watchers = 0;
- for (watcher = hint->callbacks; watcher; watcher = watcher->next)
- watchers++;
- ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n",
- ast_get_extension_name(hint->exten),
- ast_get_context_name(ast_get_extension_context(hint->exten)),
- ast_get_extension_app(hint->exten),
- ast_extension_state2str(hint->laststate), watchers);
- num++;
- }
- ast_cli(fd, "----------------\n");
- ast_cli(fd, "- %d hints registered\n", num);
- AST_LIST_UNLOCK(&hints);
- return RESULT_SUCCESS;
-}
-
-/*! \brief handle_show_switches: CLI support for listing registred dial plan switches */
-static int handle_show_switches(int fd, int argc, char *argv[])
-{
- struct ast_switch *sw;
-
- AST_LIST_LOCK(&switches);
-
- if (AST_LIST_EMPTY(&switches)) {
- AST_LIST_UNLOCK(&switches);
- ast_cli(fd, "There are no registered alternative switches\n");
- return RESULT_SUCCESS;
- }
-
- ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n");
- AST_LIST_TRAVERSE(&switches, sw, list)
- ast_cli(fd, "%s: %s\n", sw->name, sw->description);
-
- AST_LIST_UNLOCK(&switches);
-
- return RESULT_SUCCESS;
-}
-
-/*
- * 'show applications' CLI command implementation functions ...
- */
-static int handle_show_applications_deprecated(int fd, int argc, char *argv[])
-{
- struct ast_app *a;
- int like = 0, describing = 0;
- int total_match = 0; /* Number of matches in like clause */
- int total_apps = 0; /* Number of apps registered */
-
- AST_LIST_LOCK(&apps);
-
- if (AST_LIST_EMPTY(&apps)) {
- ast_cli(fd, "There are no registered applications\n");
- AST_LIST_UNLOCK(&apps);
- return -1;
- }
-
- /* show applications like <keyword> */
- if ((argc == 4) && (!strcmp(argv[2], "like"))) {
- like = 1;
- } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) {
- describing = 1;
- }
-
- /* show applications describing <keyword1> [<keyword2>] [...] */
- if ((!like) && (!describing)) {
- ast_cli(fd, " -= Registered Asterisk Applications =-\n");
- } else {
- ast_cli(fd, " -= Matching Asterisk Applications =-\n");
- }
-
- AST_LIST_TRAVERSE(&apps, a, list) {
- int printapp = 0;
- total_apps++;
- if (like) {
- if (strcasestr(a->name, argv[3])) {
- printapp = 1;
- total_match++;
- }
- } else if (describing) {
- if (a->description) {
- /* Match all words on command line */
- int i;
- printapp = 1;
- for (i = 3; i < argc; i++) {
- if (!strcasestr(a->description, argv[i])) {
- printapp = 0;
- } else {
- total_match++;
- }
- }
- }
- } else {
- printapp = 1;
- }
-
- if (printapp) {
- ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>");
- }
- }
- if ((!like) && (!describing)) {
- ast_cli(fd, " -= %d Applications Registered =-\n",total_apps);
- } else {
- ast_cli(fd, " -= %d Applications Matching =-\n",total_match);
- }
-
- AST_LIST_UNLOCK(&apps);
-
- return RESULT_SUCCESS;
-}
-static int handle_show_applications(int fd, int argc, char *argv[])
-{
- struct ast_app *a;
- int like = 0, describing = 0;
- int total_match = 0; /* Number of matches in like clause */
- int total_apps = 0; /* Number of apps registered */
-
- AST_LIST_LOCK(&apps);
-
- if (AST_LIST_EMPTY(&apps)) {
- ast_cli(fd, "There are no registered applications\n");
- AST_LIST_UNLOCK(&apps);
- return -1;
- }
-
- /* core list applications like <keyword> */
- if ((argc == 5) && (!strcmp(argv[3], "like"))) {
- like = 1;
- } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) {
- describing = 1;
- }
-
- /* core list applications describing <keyword1> [<keyword2>] [...] */
- if ((!like) && (!describing)) {
- ast_cli(fd, " -= Registered Asterisk Applications =-\n");
- } else {
- ast_cli(fd, " -= Matching Asterisk Applications =-\n");
- }
-
- AST_LIST_TRAVERSE(&apps, a, list) {
- int printapp = 0;
- total_apps++;
- if (like) {
- if (strcasestr(a->name, argv[4])) {
- printapp = 1;
- total_match++;
- }
- } else if (describing) {
- if (a->description) {
- /* Match all words on command line */
- int i;
- printapp = 1;
- for (i = 4; i < argc; i++) {
- if (!strcasestr(a->description, argv[i])) {
- printapp = 0;
- } else {
- total_match++;
- }
- }
- }
- } else {
- printapp = 1;
- }
-
- if (printapp) {
- ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>");
- }
- }
- if ((!like) && (!describing)) {
- ast_cli(fd, " -= %d Applications Registered =-\n",total_apps);
- } else {
- ast_cli(fd, " -= %d Applications Matching =-\n",total_match);
- }
-
- AST_LIST_UNLOCK(&apps);
-
- return RESULT_SUCCESS;
-}
-
-static char *complete_show_applications_deprecated(const char *line, const char *word, int pos, int state)
-{
- static char* choices[] = { "like", "describing", NULL };
-
- return (pos != 2) ? NULL : ast_cli_complete(word, choices, state);
-}
-
-static char *complete_show_applications(const char *line, const char *word, int pos, int state)
-{
- static char* choices[] = { "like", "describing", NULL };
-
- return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);
-}
-
-/*
- * 'show dialplan' CLI command implementation functions ...
- */
-static char *complete_show_dialplan_context(const char *line, const char *word, int pos,
- int state)
-{
- struct ast_context *c = NULL;
- char *ret = NULL;
- int which = 0;
- int wordlen;
-
- /* we are do completion of [exten@]context on second position only */
- if (pos != 2)
- return NULL;
-
- ast_rdlock_contexts();
-
- wordlen = strlen(word);
-
- /* walk through all contexts and return the n-th match */
- while ( (c = ast_walk_contexts(c)) ) {
- if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) {
- ret = ast_strdup(ast_get_context_name(c));
- break;
- }
- }
-
- ast_unlock_contexts();
-
- return ret;
-}
-
-struct dialplan_counters {
- int total_context;
- int total_exten;
- int total_prio;
- int context_existence;
- int extension_existence;
-};
-
-/*! \brief helper function to print an extension */
-static void print_ext(struct ast_exten *e, char * buf, int buflen)
-{
- int prio = ast_get_extension_priority(e);
- if (prio == PRIORITY_HINT) {
- snprintf(buf, buflen, "hint: %s",
- ast_get_extension_app(e));
- } else {
- snprintf(buf, buflen, "%d. %s(%s)",
- prio, ast_get_extension_app(e),
- (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : ""));
- }
-}
-
-/* XXX not verified */
-static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
-{
- struct ast_context *c = NULL;
- int res = 0, old_total_exten = dpc->total_exten;
-
- ast_rdlock_contexts();
-
- /* walk all contexts ... */
- while ( (c = ast_walk_contexts(c)) ) {
- struct ast_exten *e;
- struct ast_include *i;
- struct ast_ignorepat *ip;
- char buf[256], buf2[256];
- int context_info_printed = 0;
-
- if (context && strcmp(ast_get_context_name(c), context))
- continue; /* skip this one, name doesn't match */
-
- dpc->context_existence = 1;
-
- ast_lock_context(c);
-
- /* are we looking for exten too? if yes, we print context
- * only if we find our extension.
- * Otherwise print context even if empty ?
- * XXX i am not sure how the rinclude is handled.
- * I think it ought to go inside.
- */
- if (!exten) {
- dpc->total_context++;
- ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
- ast_get_context_name(c), ast_get_context_registrar(c));
- context_info_printed = 1;
- }
-
- /* walk extensions ... */
- e = NULL;
- while ( (e = ast_walk_context_extensions(c, e)) ) {
- struct ast_exten *p;
-
- if (exten && !ast_extension_match(ast_get_extension_name(e), exten))
- continue; /* skip, extension match failed */
-
- dpc->extension_existence = 1;
-
- /* may we print context info? */
- if (!context_info_printed) {
- dpc->total_context++;
- if (rinclude) { /* TODO Print more info about rinclude */
- ast_cli(fd, "[ Included context '%s' created by '%s' ]\n",
- ast_get_context_name(c), ast_get_context_registrar(c));
- } else {
- ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
- ast_get_context_name(c), ast_get_context_registrar(c));
- }
- context_info_printed = 1;
- }
- dpc->total_prio++;
-
- /* write extension name and first peer */
- snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e));
-
- print_ext(e, buf2, sizeof(buf2));
-
- ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2,
- ast_get_extension_registrar(e));
-
- dpc->total_exten++;
- /* walk next extension peers */
- p = e; /* skip the first one, we already got it */
- while ( (p = ast_walk_extension_priorities(e, p)) ) {
- const char *el = ast_get_extension_label(p);
- dpc->total_prio++;
- if (el)
- snprintf(buf, sizeof(buf), " [%s]", el);
- else
- buf[0] = '\0';
- print_ext(p, buf2, sizeof(buf2));
-
- ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2,
- ast_get_extension_registrar(p));
- }
- }
-
- /* walk included and write info ... */
- i = NULL;
- while ( (i = ast_walk_context_includes(c, i)) ) {
- snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i));
- if (exten) {
- /* Check all includes for the requested extension */
- if (includecount >= AST_PBX_MAX_STACK) {
- ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n");
- } else {
- int dupe=0;
- int x;
- for (x=0;x<includecount;x++) {
- if (!strcasecmp(includes[x], ast_get_include_name(i))) {
- dupe++;
- break;
- }
- }
- if (!dupe) {
- includes[includecount] = ast_get_include_name(i);
- show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes);
- } else {
- ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context);
- }
- }
- } else {
- ast_cli(fd, " Include => %-45s [%s]\n",
- buf, ast_get_include_registrar(i));
- }
- }
-
- /* walk ignore patterns and write info ... */
- ip = NULL;
- while ( (ip = ast_walk_context_ignorepats(c, ip)) ) {
- const char *ipname = ast_get_ignorepat_name(ip);
- char ignorepat[AST_MAX_EXTENSION];
- snprintf(buf, sizeof(buf), "'%s'", ipname);
- snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
- if (!exten || ast_extension_match(ignorepat, exten)) {
- ast_cli(fd, " Ignore pattern => %-45s [%s]\n",
- buf, ast_get_ignorepat_registrar(ip));
- }
- }
- if (!rinclude) {
- struct ast_sw *sw = NULL;
- while ( (sw = ast_walk_context_switches(c, sw)) ) {
- snprintf(buf, sizeof(buf), "'%s/%s'",
- ast_get_switch_name(sw),
- ast_get_switch_data(sw));
- ast_cli(fd, " Alt. Switch => %-45s [%s]\n",
- buf, ast_get_switch_registrar(sw));
- }
- }
-
- ast_unlock_context(c);
-
- /* if we print something in context, make an empty line */
- if (context_info_printed)
- ast_cli(fd, "\r\n");
- }
- ast_unlock_contexts();
-
- return (dpc->total_exten == old_total_exten) ? -1 : res;
-}
-
-static int handle_show_dialplan(int fd, int argc, char *argv[])
-{
- char *exten = NULL, *context = NULL;
- /* Variables used for different counters */
- struct dialplan_counters counters;
-
- const char *incstack[AST_PBX_MAX_STACK];
- memset(&counters, 0, sizeof(counters));
-
- if (argc != 2 && argc != 3)
- return RESULT_SHOWUSAGE;
-
- /* we obtain [exten@]context? if yes, split them ... */
- if (argc == 3) {
- if (strchr(argv[2], '@')) { /* split into exten & context */
- context = ast_strdupa(argv[2]);
- exten = strsep(&context, "@");
- /* change empty strings to NULL */
- if (ast_strlen_zero(exten))
- exten = NULL;
- } else { /* no '@' char, only context given */
- context = argv[2];
- }
- if (ast_strlen_zero(context))
- context = NULL;
- }
- /* else Show complete dial plan, context and exten are NULL */
- show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack);
-
- /* check for input failure and throw some error messages */
- if (context && !counters.context_existence) {
- ast_cli(fd, "There is no existence of '%s' context\n", context);
- return RESULT_FAILURE;
- }
-
- if (exten && !counters.extension_existence) {
- if (context)
- ast_cli(fd, "There is no existence of %s@%s extension\n",
- exten, context);
- else
- ast_cli(fd,
- "There is no existence of '%s' extension in all contexts\n",
- exten);
- return RESULT_FAILURE;
- }
-
- ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n",
- counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions",
- counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities",
- counters.total_context, counters.total_context == 1 ? "context" : "contexts");
-
- /* everything ok */
- return RESULT_SUCCESS;
-}
-
-/*! \brief CLI support for listing global variables in a parseable way */
-static int handle_show_globals(int fd, int argc, char *argv[])
-{
- int i = 0;
- struct ast_var_t *newvariable;
-
- ast_mutex_lock(&globalslock);
- AST_LIST_TRAVERSE (&globals, newvariable, entries) {
- i++;
- ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable));
- }
- ast_mutex_unlock(&globalslock);
- ast_cli(fd, "\n -- %d variables\n", i);
-
- return RESULT_SUCCESS;
-}
-
-/*! \brief CLI support for setting global variables */
-static int handle_set_global_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- pbx_builtin_setvar_helper(NULL, argv[2], argv[3]);
- ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]);
-
- return RESULT_SUCCESS;
-}
-
-
-static int handle_set_global(int fd, int argc, char *argv[])
-{
- if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- pbx_builtin_setvar_helper(NULL, argv[3], argv[4]);
- ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]);
-
- return RESULT_SUCCESS;
-}
-
-
-
-/*
- * CLI entries for upper commands ...
- */
-static struct ast_cli_entry cli_show_applications_deprecated = {
- { "show", "applications", NULL },
- handle_show_applications_deprecated, NULL,
- NULL, complete_show_applications_deprecated };
-
-static struct ast_cli_entry cli_show_functions_deprecated = {
- { "show", "functions", NULL },
- handle_show_functions_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_switches_deprecated = {
- { "show", "switches", NULL },
- handle_show_switches, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_hints_deprecated = {
- { "show", "hints", NULL },
- handle_show_hints, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_globals_deprecated = {
- { "show", "globals", NULL },
- handle_show_globals, NULL,
- NULL };
-
-static struct ast_cli_entry cli_show_function_deprecated = {
- { "show" , "function", NULL },
- handle_show_function_deprecated, NULL,
- NULL, complete_show_function };
-
-static struct ast_cli_entry cli_show_application_deprecated = {
- { "show", "application", NULL },
- handle_show_application_deprecated, NULL,
- NULL, complete_show_application };
-
-static struct ast_cli_entry cli_show_dialplan_deprecated = {
- { "show", "dialplan", NULL },
- handle_show_dialplan, NULL,
- NULL, complete_show_dialplan_context };
-
-static struct ast_cli_entry cli_set_global_deprecated = {
- { "set", "global", NULL },
- handle_set_global_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry pbx_cli[] = {
- { { "core", "show", "applications", NULL },
- handle_show_applications, "Shows registered dialplan applications",
- show_applications_help, complete_show_applications, &cli_show_applications_deprecated },
-
- { { "core", "show", "functions", NULL },
- handle_show_functions, "Shows registered dialplan functions",
- show_functions_help, NULL, &cli_show_functions_deprecated },
-
- { { "core", "show", "switches", NULL },
- handle_show_switches, "Show alternative switches",
- show_switches_help, NULL, &cli_show_switches_deprecated },
-
- { { "core", "show", "hints", NULL },
- handle_show_hints, "Show dialplan hints",
- show_hints_help, NULL, &cli_show_hints_deprecated },
-
- { { "core", "show", "globals", NULL },
- handle_show_globals, "Show global dialplan variables",
- show_globals_help, NULL, &cli_show_globals_deprecated },
-
- { { "core", "show" , "function", NULL },
- handle_show_function, "Describe a specific dialplan function",
- show_function_help, complete_show_function, &cli_show_function_deprecated },
-
- { { "core", "show", "application", NULL },
- handle_show_application, "Describe a specific dialplan application",
- show_application_help, complete_show_application, &cli_show_application_deprecated },
-
- { { "core", "set", "global", NULL },
- handle_set_global, "Set global dialplan variable",
- set_global_help, NULL, &cli_set_global_deprecated },
-
- { { "dialplan", "show", NULL },
- handle_show_dialplan, "Show dialplan",
- show_dialplan_help, complete_show_dialplan_context, &cli_show_dialplan_deprecated },
-};
-
-int ast_unregister_application(const char *app)
-{
- struct ast_app *tmp;
-
- AST_LIST_LOCK(&apps);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
- if (!strcasecmp(app, tmp->name)) {
- AST_LIST_REMOVE_CURRENT(&apps, list);
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
- free(tmp);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&apps);
-
- return tmp ? 0 : -1;
-}
-
-static struct ast_context *__ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
-{
- struct ast_context *tmp, **local_contexts;
- int length = sizeof(struct ast_context) + strlen(name) + 1;
-
- if (!extcontexts) {
- ast_rdlock_contexts();
- local_contexts = &contexts;
- } else
- local_contexts = extcontexts;
-
- for (tmp = *local_contexts; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, name)) {
- if (!existsokay) {
- ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
- tmp = NULL;
- }
- if (!extcontexts)
- ast_unlock_contexts();
- return tmp;
- }
- }
-
- if (!extcontexts)
- ast_unlock_contexts();
-
- if ((tmp = ast_calloc(1, length))) {
- ast_mutex_init(&tmp->lock);
- ast_mutex_init(&tmp->macrolock);
- strcpy(tmp->name, name);
- tmp->registrar = registrar;
- if (!extcontexts)
- ast_wrlock_contexts();
- tmp->next = *local_contexts;
- *local_contexts = tmp;
- if (!extcontexts)
- ast_unlock_contexts();
- if (option_debug)
- ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
- }
-
- return tmp;
-}
-
-struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar)
-{
- return __ast_context_create(extcontexts, name, registrar, 0);
-}
-
-struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, const char *name, const char *registrar)
-{
- return __ast_context_create(extcontexts, name, registrar, 1);
-}
-void __ast_context_destroy(struct ast_context *con, const char *registrar);
-
-struct store_hint {
- char *context;
- char *exten;
- struct ast_state_cb *callbacks;
- int laststate;
- AST_LIST_ENTRY(store_hint) list;
- char data[1];
-};
-
-AST_LIST_HEAD(store_hints, store_hint);
-
-/* XXX this does not check that multiple contexts are merged */
-void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
-{
- struct ast_context *tmp, *lasttmp = NULL;
- struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
- struct store_hint *this;
- struct ast_hint *hint;
- struct ast_exten *exten;
- int length;
- struct ast_state_cb *thiscb, *prevcb;
-
- /* it is very important that this function hold the hint list lock _and_ the conlock
- during its operation; not only do we need to ensure that the list of contexts
- and extensions does not change, but also that no hint callbacks (watchers) are
- added or removed during the merge/delete process
-
- in addition, the locks _must_ be taken in this order, because there are already
- other code paths that use this order
- */
- ast_wrlock_contexts();
- AST_LIST_LOCK(&hints);
-
- /* preserve all watchers for hints associated with this registrar */
- AST_LIST_TRAVERSE(&hints, hint, list) {
- if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
- length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
- if (!(this = ast_calloc(1, length)))
- continue;
- this->callbacks = hint->callbacks;
- hint->callbacks = NULL;
- this->laststate = hint->laststate;
- this->context = this->data;
- strcpy(this->data, hint->exten->parent->name);
- this->exten = this->data + strlen(this->context) + 1;
- strcpy(this->exten, hint->exten->exten);
- AST_LIST_INSERT_HEAD(&store, this, list);
- }
- }
-
- tmp = *extcontexts;
- if (registrar) {
- /* XXX remove previous contexts from same registrar */
- if (option_debug)
- ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
- __ast_context_destroy(NULL,registrar);
- while (tmp) {
- lasttmp = tmp;
- tmp = tmp->next;
- }
- } else {
- /* XXX remove contexts with the same name */
- while (tmp) {
- ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar);
- __ast_context_destroy(tmp,tmp->registrar);
- lasttmp = tmp;
- tmp = tmp->next;
- }
- }
- if (lasttmp) {
- lasttmp->next = contexts;
- contexts = *extcontexts;
- *extcontexts = NULL;
- } else
- ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
-
- /* restore the watchers for hints that can be found; notify those that
- cannot be restored
- */
- while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
- struct pbx_find_info q = { .stacklen = 0 };
- exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
- /* Find the hint in the list of hints */
- AST_LIST_TRAVERSE(&hints, hint, list) {
- if (hint->exten == exten)
- break;
- }
- if (!exten || !hint) {
- /* this hint has been removed, notify the watchers */
- prevcb = NULL;
- thiscb = this->callbacks;
- while (thiscb) {
- prevcb = thiscb;
- thiscb = thiscb->next;
- prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
- free(prevcb);
- }
- } else {
- thiscb = this->callbacks;
- while (thiscb->next)
- thiscb = thiscb->next;
- thiscb->next = hint->callbacks;
- hint->callbacks = this->callbacks;
- hint->laststate = this->laststate;
- }
- free(this);
- }
-
- AST_LIST_UNLOCK(&hints);
- ast_unlock_contexts();
-
- return;
-}
-
-/*
- * errno values
- * EBUSY - can't lock
- * ENOENT - no existence of context
- */
-int ast_context_add_include(const char *context, const char *include, const char *registrar)
-{
- int ret = -1;
- struct ast_context *c = find_context_locked(context);
-
- if (c) {
- ret = ast_context_add_include2(c, include, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-/*! \brief Helper for get_range.
- * return the index of the matching entry, starting from 1.
- * If names is not supplied, try numeric values.
- */
-static int lookup_name(const char *s, char *const names[], int max)
-{
- int i;
-
- if (names) {
- for (i = 0; names[i]; i++) {
- if (!strcasecmp(s, names[i]))
- return i+1;
- }
- } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) {
- return i;
- }
- return 0; /* error return */
-}
-
-/*! \brief helper function to return a range up to max (7, 12, 31 respectively).
- * names, if supplied, is an array of names that should be mapped to numbers.
- */
-static unsigned get_range(char *src, int max, char *const names[], const char *msg)
-{
- int s, e; /* start and ending position */
- unsigned int mask = 0;
-
- /* Check for whole range */
- if (ast_strlen_zero(src) || !strcmp(src, "*")) {
- s = 0;
- e = max - 1;
- } else {
- /* Get start and ending position */
- char *c = strchr(src, '-');
- if (c)
- *c++ = '\0';
- /* Find the start */
- s = lookup_name(src, names, max);
- if (!s) {
- ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src);
- return 0;
- }
- s--;
- if (c) { /* find end of range */
- e = lookup_name(c, names, max);
- if (!e) {
- ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c);
- return 0;
- }
- e--;
- } else
- e = s;
- }
- /* Fill the mask. Remember that ranges are cyclic */
- mask = 1 << e; /* initialize with last element */
- while (s != e) {
- if (s >= max) {
- s = 0;
- mask |= (1 << s);
- } else {
- mask |= (1 << s);
- s++;
- }
- }
- return mask;
-}
-
-/*! \brief store a bitmask of valid times, one bit each 2 minute */
-static void get_timerange(struct ast_timing *i, char *times)
-{
- char *e;
- int x;
- int s1, s2;
- int e1, e2;
- /* int cth, ctm; */
-
- /* start disabling all times, fill the fields with 0's, as they may contain garbage */
- memset(i->minmask, 0, sizeof(i->minmask));
-
- /* 2-minutes per bit, since the mask has only 32 bits :( */
- /* Star is all times */
- if (ast_strlen_zero(times) || !strcmp(times, "*")) {
- for (x=0; x<24; x++)
- i->minmask[x] = 0x3fffffff; /* 30 bits */
- return;
- }
- /* Otherwise expect a range */
- e = strchr(times, '-');
- if (!e) {
- ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n");
- return;
- }
- *e++ = '\0';
- /* XXX why skip non digits ? */
- while (*e && !isdigit(*e))
- e++;
- if (!*e) {
- ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n");
- return;
- }
- if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
- ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times);
- return;
- }
- if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
- ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e);
- return;
- }
- /* XXX this needs to be optimized */
-#if 1
- s1 = s1 * 30 + s2/2;
- if ((s1 < 0) || (s1 >= 24*30)) {
- ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times);
- return;
- }
- e1 = e1 * 30 + e2/2;
- if ((e1 < 0) || (e1 >= 24*30)) {
- ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e);
- return;
- }
- /* Go through the time and enable each appropriate bit */
- for (x=s1;x != e1;x = (x + 1) % (24 * 30)) {
- i->minmask[x/30] |= (1 << (x % 30));
- }
- /* Do the last one */
- i->minmask[x/30] |= (1 << (x % 30));
-#else
- for (cth=0; cth<24; cth++) {
- /* Initialize masks to blank */
- i->minmask[cth] = 0;
- for (ctm=0; ctm<30; ctm++) {
- if (
- /* First hour with more than one hour */
- (((cth == s1) && (ctm >= s2)) &&
- ((cth < e1)))
- /* Only one hour */
- || (((cth == s1) && (ctm >= s2)) &&
- ((cth == e1) && (ctm <= e2)))
- /* In between first and last hours (more than 2 hours) */
- || ((cth > s1) &&
- (cth < e1))
- /* Last hour with more than one hour */
- || ((cth > s1) &&
- ((cth == e1) && (ctm <= e2)))
- )
- i->minmask[cth] |= (1 << (ctm / 2));
- }
- }
-#endif
- /* All done */
- return;
-}
-
-static char *days[] =
-{
- "sun",
- "mon",
- "tue",
- "wed",
- "thu",
- "fri",
- "sat",
- NULL,
-};
-
-static char *months[] =
-{
- "jan",
- "feb",
- "mar",
- "apr",
- "may",
- "jun",
- "jul",
- "aug",
- "sep",
- "oct",
- "nov",
- "dec",
- NULL,
-};
-
-int ast_build_timing(struct ast_timing *i, const char *info_in)
-{
- char info_save[256];
- char *info;
-
- /* Check for empty just in case */
- if (ast_strlen_zero(info_in))
- return 0;
- /* make a copy just in case we were passed a static string */
- ast_copy_string(info_save, info_in, sizeof(info_save));
- info = info_save;
- /* Assume everything except time */
- i->monthmask = 0xfff; /* 12 bits */
- i->daymask = 0x7fffffffU; /* 31 bits */
- i->dowmask = 0x7f; /* 7 bits */
- /* on each call, use strsep() to move info to the next argument */
- get_timerange(i, strsep(&info, "|"));
- if (info)
- i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
- if (info)
- i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
- if (info)
- i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
- return 1;
-}
-
-int ast_check_timing(const struct ast_timing *i)
-{
- struct tm tm;
- time_t t = time(NULL);
-
- ast_localtime(&t, &tm, NULL);
-
- /* If it's not the right month, return */
- if (!(i->monthmask & (1 << tm.tm_mon)))
- return 0;
-
- /* If it's not that time of the month.... */
- /* Warning, tm_mday has range 1..31! */
- if (!(i->daymask & (1 << (tm.tm_mday-1))))
- return 0;
-
- /* If it's not the right day of the week */
- if (!(i->dowmask & (1 << tm.tm_wday)))
- return 0;
-
- /* Sanity check the hour just to be safe */
- if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
- ast_log(LOG_WARNING, "Insane time...\n");
- return 0;
- }
-
- /* Now the tough part, we calculate if it fits
- in the right time based on min/hour */
- if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
- return 0;
-
- /* If we got this far, then we're good */
- return 1;
-}
-
-/*
- * errno values
- * ENOMEM - out of memory
- * EBUSY - can't lock
- * EEXIST - already included
- * EINVAL - there is no existence of context for inclusion
- */
-int ast_context_add_include2(struct ast_context *con, const char *value,
- const char *registrar)
-{
- struct ast_include *new_include;
- char *c;
- struct ast_include *i, *il = NULL; /* include, include_last */
- int length;
- char *p;
-
- length = sizeof(struct ast_include);
- length += 2 * (strlen(value) + 1);
-
- /* allocate new include structure ... */
- if (!(new_include = ast_calloc(1, length)))
- return -1;
- /* Fill in this structure. Use 'p' for assignments, as the fields
- * in the structure are 'const char *'
- */
- p = new_include->stuff;
- new_include->name = p;
- strcpy(p, value);
- p += strlen(value) + 1;
- new_include->rname = p;
- strcpy(p, value);
- /* Strip off timing info, and process if it is there */
- if ( (c = strchr(p, '|')) ) {
- *c++ = '\0';
- new_include->hastime = ast_build_timing(&(new_include->timing), c);
- }
- new_include->next = NULL;
- new_include->registrar = registrar;
-
- ast_mutex_lock(&con->lock);
-
- /* ... go to last include and check if context is already included too... */
- for (i = con->includes; i; i = i->next) {
- if (!strcasecmp(i->name, new_include->name)) {
- free(new_include);
- ast_mutex_unlock(&con->lock);
- errno = EEXIST;
- return -1;
- }
- il = i;
- }
-
- /* ... include new context into context list, unlock, return */
- if (il)
- il->next = new_include;
- else
- con->includes = new_include;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
- ast_mutex_unlock(&con->lock);
-
- return 0;
-}
-
-/*
- * errno values
- * EBUSY - can't lock
- * ENOENT - no existence of context
- */
-int ast_context_add_switch(const char *context, const char *sw, const char *data, int eval, const char *registrar)
-{
- int ret = -1;
- struct ast_context *c = find_context_locked(context);
-
- if (c) { /* found, add switch to this context */
- ret = ast_context_add_switch2(c, sw, data, eval, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-/*
- * errno values
- * ENOMEM - out of memory
- * EBUSY - can't lock
- * EEXIST - already included
- * EINVAL - there is no existence of context for inclusion
- */
-int ast_context_add_switch2(struct ast_context *con, const char *value,
- const char *data, int eval, const char *registrar)
-{
- struct ast_sw *new_sw;
- struct ast_sw *i;
- int length;
- char *p;
-
- length = sizeof(struct ast_sw);
- length += strlen(value) + 1;
- if (data)
- length += strlen(data);
- length++;
-
- /* allocate new sw structure ... */
- if (!(new_sw = ast_calloc(1, length)))
- return -1;
- /* ... fill in this structure ... */
- p = new_sw->stuff;
- new_sw->name = p;
- strcpy(new_sw->name, value);
- p += strlen(value) + 1;
- new_sw->data = p;
- if (data) {
- strcpy(new_sw->data, data);
- p += strlen(data) + 1;
- } else {
- strcpy(new_sw->data, "");
- p++;
- }
- new_sw->eval = eval;
- new_sw->registrar = registrar;
-
- /* ... try to lock this context ... */
- ast_mutex_lock(&con->lock);
-
- /* ... go to last sw and check if context is already swd too... */
- AST_LIST_TRAVERSE(&con->alts, i, list) {
- if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
- free(new_sw);
- ast_mutex_unlock(&con->lock);
- errno = EEXIST;
- return -1;
- }
- }
-
- /* ... sw new context into context list, unlock, return */
- AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
-
- ast_mutex_unlock(&con->lock);
-
- return 0;
-}
-
-/*
- * EBUSY - can't lock
- * ENOENT - there is not context existence
- */
-int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar)
-{
- int ret = -1;
- struct ast_context *c = find_context_locked(context);
-
- if (c) {
- ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
-{
- struct ast_ignorepat *ip, *ipl = NULL;
-
- ast_mutex_lock(&con->lock);
-
- for (ip = con->ignorepats; ip; ip = ip->next) {
- if (!strcmp(ip->pattern, ignorepat) &&
- (!registrar || (registrar == ip->registrar))) {
- if (ipl) {
- ipl->next = ip->next;
- free(ip);
- } else {
- con->ignorepats = ip->next;
- free(ip);
- }
- ast_mutex_unlock(&con->lock);
- return 0;
- }
- ipl = ip;
- }
-
- ast_mutex_unlock(&con->lock);
- errno = EINVAL;
- return -1;
-}
-
-/*
- * EBUSY - can't lock
- * ENOENT - there is no existence of context
- */
-int ast_context_add_ignorepat(const char *context, const char *value, const char *registrar)
-{
- int ret = -1;
- struct ast_context *c = find_context_locked(context);
-
- if (c) {
- ret = ast_context_add_ignorepat2(c, value, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
-{
- struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
- int length;
- length = sizeof(struct ast_ignorepat);
- length += strlen(value) + 1;
- if (!(ignorepat = ast_calloc(1, length)))
- return -1;
- /* The cast to char * is because we need to write the initial value.
- * The field is not supposed to be modified otherwise
- */
- strcpy((char *)ignorepat->pattern, value);
- ignorepat->next = NULL;
- ignorepat->registrar = registrar;
- ast_mutex_lock(&con->lock);
- for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
- ignorepatl = ignorepatc;
- if (!strcasecmp(ignorepatc->pattern, value)) {
- /* Already there */
- ast_mutex_unlock(&con->lock);
- errno = EEXIST;
- return -1;
- }
- }
- if (ignorepatl)
- ignorepatl->next = ignorepat;
- else
- con->ignorepats = ignorepat;
- ast_mutex_unlock(&con->lock);
- return 0;
-
-}
-
-int ast_ignore_pattern(const char *context, const char *pattern)
-{
- struct ast_context *con = ast_context_find(context);
- if (con) {
- struct ast_ignorepat *pat;
- for (pat = con->ignorepats; pat; pat = pat->next) {
- if (ast_extension_match(pat->pattern, pattern))
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
- * EBUSY - can't lock
- * ENOENT - no existence of context
- *
- */
-int ast_add_extension(const char *context, int replace, const char *extension,
- int priority, const char *label, const char *callerid,
- const char *application, void *data, void (*datad)(void *), const char *registrar)
-{
- int ret = -1;
- struct ast_context *c = find_context_locked(context);
-
- if (c) {
- ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
- application, data, datad, registrar);
- ast_unlock_contexts();
- }
- return ret;
-}
-
-int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
-{
- if (!chan)
- return -1;
-
- ast_channel_lock(chan);
-
- if (!ast_strlen_zero(context))
- ast_copy_string(chan->context, context, sizeof(chan->context));
- if (!ast_strlen_zero(exten))
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- if (priority > -1) {
- chan->priority = priority;
- /* see flag description in channel.h for explanation */
- if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
- chan->priority--;
- }
-
- ast_channel_unlock(chan);
-
- return 0;
-}
-
-int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
-{
- int res = 0;
-
- ast_channel_lock(chan);
-
- if (chan->pbx) { /* This channel is currently in the PBX */
- ast_explicit_goto(chan, context, exten, priority);
- ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
- } else {
- /* In order to do it when the channel doesn't really exist within
- the PBX, we have to make a new channel, masquerade, and start the PBX
- at the new location */
- struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
- if (chan->cdr) {
- ast_cdr_discard(tmpchan->cdr);
- tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */
- }
- if (!tmpchan)
- res = -1;
- else {
- /* Make formats okay */
- tmpchan->readformat = chan->readformat;
- tmpchan->writeformat = chan->writeformat;
- /* Setup proper location */
- ast_explicit_goto(tmpchan,
- S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
-
- /* Masquerade into temp channel */
- ast_channel_masquerade(tmpchan, chan);
-
- /* Grab the locks and get going */
- ast_channel_lock(tmpchan);
- ast_do_masquerade(tmpchan);
- ast_channel_unlock(tmpchan);
- /* Start the PBX going on our stolen channel */
- if (ast_pbx_start(tmpchan)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
- ast_hangup(tmpchan);
- res = -1;
- }
- }
- }
- ast_channel_unlock(chan);
- return res;
-}
-
-int ast_async_goto_by_name(const char *channame, const char *context, const char *exten, int priority)
-{
- struct ast_channel *chan;
- int res = -1;
-
- chan = ast_get_channel_by_name_locked(channame);
- if (chan) {
- res = ast_async_goto(chan, context, exten, priority);
- ast_channel_unlock(chan);
- }
- return res;
-}
-
-/*! \brief copy a string skipping whitespace */
-static int ext_strncpy(char *dst, const char *src, int len)
-{
- int count=0;
-
- while (*src && (count < len - 1)) {
- switch(*src) {
- case ' ':
- /* otherwise exten => [a-b],1,... doesn't work */
- /* case '-': */
- /* Ignore */
- break;
- default:
- *dst = *src;
- dst++;
- }
- src++;
- count++;
- }
- *dst = '\0';
-
- return count;
-}
-
-/*! \brief add the extension in the priority chain.
- * returns 0 on success, -1 on failure
- */
-static int add_pri(struct ast_context *con, struct ast_exten *tmp,
- struct ast_exten *el, struct ast_exten *e, int replace)
-{
- struct ast_exten *ep;
-
- for (ep = NULL; e ; ep = e, e = e->peer) {
- if (e->priority >= tmp->priority)
- break;
- }
- if (!e) { /* go at the end, and ep is surely set because the list is not empty */
- ep->peer = tmp;
- return 0; /* success */
- }
- if (e->priority == tmp->priority) {
- /* Can't have something exactly the same. Is this a
- replacement? If so, replace, otherwise, bonk. */
- if (!replace) {
- ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
- if (tmp->datad)
- tmp->datad(tmp->data);
- free(tmp);
- return -1;
- }
- /* we are replacing e, so copy the link fields and then update
- * whoever pointed to e to point to us
- */
- tmp->next = e->next; /* not meaningful if we are not first in the peer list */
- tmp->peer = e->peer; /* always meaningful */
- if (ep) /* We're in the peer list, just insert ourselves */
- ep->peer = tmp;
- else if (el) /* We're the first extension. Take over e's functions */
- el->next = tmp;
- else /* We're the very first extension. */
- con->root = tmp;
- if (tmp->priority == PRIORITY_HINT)
- ast_change_hint(e,tmp);
- /* Destroy the old one */
- if (e->datad)
- e->datad(e->data);
- free(e);
- } else { /* Slip ourselves in just before e */
- tmp->peer = e;
- tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */
- if (ep) /* Easy enough, we're just in the peer list */
- ep->peer = tmp;
- else { /* we are the first in some peer list, so link in the ext list */
- if (el)
- el->next = tmp; /* in the middle... */
- else
- con->root = tmp; /* ... or at the head */
- e->next = NULL; /* e is no more at the head, so e->next must be reset */
- }
- /* And immediately return success. */
- if (tmp->priority == PRIORITY_HINT)
- ast_add_hint(tmp);
- }
- return 0;
-}
-
-/*! \brief
- * Main interface to add extensions to the list for out context.
- *
- * We sort extensions in order of matching preference, so that we can
- * stop the search as soon as we find a suitable match.
- * This ordering also takes care of wildcards such as '.' (meaning
- * "one or more of any character") and '!' (which is 'earlymatch',
- * meaning "zero or more of any character" but also impacts the
- * return value from CANMATCH and EARLYMATCH.
- *
- * The extension match rules defined in the devmeeting 2006.05.05 are
- * quite simple: WE SELECT THE LONGEST MATCH.
- * In detail, "longest" means the number of matched characters in
- * the extension. In case of ties (e.g. _XXX and 333) in the length
- * of a pattern, we give priority to entries with the smallest cardinality
- * (e.g, [5-9] comes before [2-8] before the former has only 5 elements,
- * while the latter has 7, etc.
- * In case of same cardinality, the first element in the range counts.
- * If we still have a tie, any final '!' will make this as a possibly
- * less specific pattern.
- *
- * EBUSY - can't lock
- * EEXIST - extension with the same priority exist and no replace is set
- *
- */
-int ast_add_extension2(struct ast_context *con,
- int replace, const char *extension, int priority, const char *label, const char *callerid,
- const char *application, void *data, void (*datad)(void *),
- const char *registrar)
-{
- /*
- * Sort extensions (or patterns) according to the rules indicated above.
- * These are implemented by the function ext_cmp()).
- * All priorities for the same ext/pattern/cid are kept in a list,
- * using the 'peer' field as a link field..
- */
- struct ast_exten *tmp, *e, *el = NULL;
- int res;
- int length;
- char *p;
- char expand_buf[VAR_BUF_SIZE] = { 0, };
-
- /* if we are adding a hint, and there are global variables, and the hint
- contains variable references, then expand them
- */
- ast_mutex_lock(&globalslock);
- if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
- pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
- application = expand_buf;
- }
- ast_mutex_unlock(&globalslock);
-
- length = sizeof(struct ast_exten);
- length += strlen(extension) + 1;
- length += strlen(application) + 1;
- if (label)
- length += strlen(label) + 1;
- if (callerid)
- length += strlen(callerid) + 1;
- else
- length ++; /* just the '\0' */
-
- /* Be optimistic: Build the extension structure first */
- if (!(tmp = ast_calloc(1, length)))
- return -1;
-
- /* use p as dst in assignments, as the fields are const char * */
- p = tmp->stuff;
- if (label) {
- tmp->label = p;
- strcpy(p, label);
- p += strlen(label) + 1;
- }
- tmp->exten = p;
- p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
- tmp->priority = priority;
- tmp->cidmatch = p; /* but use p for assignments below */
- if (callerid) {
- p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
- tmp->matchcid = 1;
- } else {
- *p++ = '\0';
- tmp->matchcid = 0;
- }
- tmp->app = p;
- strcpy(p, application);
- tmp->parent = con;
- tmp->data = data;
- tmp->datad = datad;
- tmp->registrar = registrar;
-
- ast_mutex_lock(&con->lock);
- res = 0; /* some compilers will think it is uninitialized otherwise */
- for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */
- res = ext_cmp(e->exten, extension);
- if (res == 0) { /* extension match, now look at cidmatch */
- if (!e->matchcid && !tmp->matchcid)
- res = 0;
- else if (tmp->matchcid && !e->matchcid)
- res = 1;
- else if (e->matchcid && !tmp->matchcid)
- res = -1;
- else
- res = strcasecmp(e->cidmatch, tmp->cidmatch);
- }
- if (res >= 0)
- break;
- }
- if (e && res == 0) { /* exact match, insert in the pri chain */
- res = add_pri(con, tmp, el, e, replace);
- ast_mutex_unlock(&con->lock);
- if (res < 0) {
- errno = EEXIST; /* XXX do we care ? */
- return 0; /* XXX should we return -1 maybe ? */
- }
- } else {
- /*
- * not an exact match, this is the first entry with this pattern,
- * so insert in the main list right before 'e' (if any)
- */
- tmp->next = e;
- if (el)
- el->next = tmp;
- else
- con->root = tmp;
- ast_mutex_unlock(&con->lock);
- if (tmp->priority == PRIORITY_HINT)
- ast_add_hint(tmp);
- }
- if (option_debug) {
- if (tmp->matchcid) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
- tmp->exten, tmp->priority, tmp->cidmatch, con->name);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
- tmp->exten, tmp->priority, con->name);
- }
- }
- if (option_verbose > 2) {
- if (tmp->matchcid) {
- ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
- tmp->exten, tmp->priority, tmp->cidmatch, con->name);
- } else {
- ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
- tmp->exten, tmp->priority, con->name);
- }
- }
- return 0;
-}
-
-struct async_stat {
- pthread_t p;
- struct ast_channel *chan;
- char context[AST_MAX_CONTEXT];
- char exten[AST_MAX_EXTENSION];
- int priority;
- int timeout;
- char app[AST_MAX_EXTENSION];
- char appdata[1024];
-};
-
-static void *async_wait(void *data)
-{
- struct async_stat *as = data;
- struct ast_channel *chan = as->chan;
- int timeout = as->timeout;
- int res;
- struct ast_frame *f;
- struct ast_app *app;
-
- while (timeout && (chan->_state != AST_STATE_UP)) {
- res = ast_waitfor(chan, timeout);
- if (res < 1)
- break;
- if (timeout > -1)
- timeout = res;
- f = ast_read(chan);
- if (!f)
- break;
- if (f->frametype == AST_FRAME_CONTROL) {
- if ((f->subclass == AST_CONTROL_BUSY) ||
- (f->subclass == AST_CONTROL_CONGESTION) ) {
- ast_frfree(f);
- break;
- }
- }
- ast_frfree(f);
- }
- if (chan->_state == AST_STATE_UP) {
- if (!ast_strlen_zero(as->app)) {
- app = pbx_findapp(as->app);
- if (app) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name);
- pbx_exec(chan, app, as->appdata);
- } else
- ast_log(LOG_WARNING, "No such application '%s'\n", as->app);
- } else {
- if (!ast_strlen_zero(as->context))
- ast_copy_string(chan->context, as->context, sizeof(chan->context));
- if (!ast_strlen_zero(as->exten))
- ast_copy_string(chan->exten, as->exten, sizeof(chan->exten));
- if (as->priority > 0)
- chan->priority = as->priority;
- /* Run the PBX */
- if (ast_pbx_run(chan)) {
- ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name);
- } else {
- /* PBX will have taken care of this */
- chan = NULL;
- }
- }
- }
- free(as);
- if (chan)
- ast_hangup(chan);
- return NULL;
-}
-
-/*! Function to post an empty cdr after a spool call fails.
- *
- * This function posts an empty cdr for a failed spool call
- *
- */
-static int ast_pbx_outgoing_cdr_failed(void)
-{
- /* allocate a channel */
- struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0);
-
- if (!chan)
- return -1; /* failure */
-
- if (!chan->cdr) {
- /* allocation of the cdr failed */
- ast_channel_free(chan); /* free the channel */
- return -1; /* return failure */
- }
-
- /* allocation of the cdr was successful */
- ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
- ast_cdr_start(chan->cdr); /* record the start and stop time */
- ast_cdr_end(chan->cdr);
- ast_cdr_failed(chan->cdr); /* set the status to failed */
- ast_cdr_detach(chan->cdr); /* post and free the record */
- ast_channel_free(chan); /* free the channel */
-
- return 0; /* success */
-}
-
-int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel)
-{
- struct ast_channel *chan;
- struct async_stat *as;
- int res = -1, cdr_res = -1;
- struct outgoing_helper oh;
- pthread_attr_t attr;
-
- if (sync) {
- LOAD_OH(oh);
- chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
- if (channel) {
- *channel = chan;
- if (chan)
- ast_channel_lock(chan);
- }
- if (chan) {
- if (chan->_state == AST_STATE_UP) {
- res = 0;
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
-
- if (sync > 1) {
- if (channel)
- ast_channel_unlock(chan);
- if (ast_pbx_run(chan)) {
- ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
- if (channel)
- *channel = NULL;
- ast_hangup(chan);
- chan = NULL;
- res = -1;
- }
- } else {
- if (ast_pbx_start(chan)) {
- ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
- if (channel) {
- *channel = NULL;
- ast_channel_unlock(chan);
- }
- ast_hangup(chan);
- res = -1;
- }
- chan = NULL;
- }
- } else {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
-
- if (chan->cdr) { /* update the cdr */
- /* here we update the status of the call, which sould be busy.
- * if that fails then we set the status to failed */
- if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
- ast_cdr_failed(chan->cdr);
- }
-
- if (channel) {
- *channel = NULL;
- ast_channel_unlock(chan);
- }
- ast_hangup(chan);
- chan = NULL;
- }
- }
-
- if (res < 0) { /* the call failed for some reason */
- if (*reason == 0) { /* if the call failed (not busy or no answer)
- * update the cdr with the failed message */
- cdr_res = ast_pbx_outgoing_cdr_failed();
- if (cdr_res != 0) {
- res = cdr_res;
- goto outgoing_exten_cleanup;
- }
- }
-
- /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
- /* check if "failed" exists */
- if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
- chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
- if (chan) {
- char failed_reason[4] = "";
- if (!ast_strlen_zero(context))
- ast_copy_string(chan->context, context, sizeof(chan->context));
- set_ext_pri(chan, "failed", 1);
- ast_set_variables(chan, vars);
- snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
- pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
- if (account)
- ast_cdr_setaccount(chan, account);
- if (ast_pbx_run(chan)) {
- ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
- ast_hangup(chan);
- }
- chan = NULL;
- }
- }
- }
- } else {
- if (!(as = ast_calloc(1, sizeof(*as)))) {
- res = -1;
- goto outgoing_exten_cleanup;
- }
- chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
- if (channel) {
- *channel = chan;
- if (chan)
- ast_channel_lock(chan);
- }
- if (!chan) {
- free(as);
- res = -1;
- goto outgoing_exten_cleanup;
- }
- as->chan = chan;
- ast_copy_string(as->context, context, sizeof(as->context));
- set_ext_pri(as->chan, exten, priority);
- as->timeout = timeout;
- ast_set_variables(chan, vars);
- if (account)
- ast_cdr_setaccount(chan, account);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
- ast_log(LOG_WARNING, "Failed to start async wait\n");
- free(as);
- if (channel) {
- *channel = NULL;
- ast_channel_unlock(chan);
- }
- ast_hangup(chan);
- res = -1;
- pthread_attr_destroy(&attr);
- goto outgoing_exten_cleanup;
- }
- pthread_attr_destroy(&attr);
- res = 0;
- }
-outgoing_exten_cleanup:
- ast_variables_destroy(vars);
- return res;
-}
-
-struct app_tmp {
- char app[256];
- char data[256];
- struct ast_channel *chan;
- pthread_t t;
-};
-
-/*! \brief run the application and free the descriptor once done */
-static void *ast_pbx_run_app(void *data)
-{
- struct app_tmp *tmp = data;
- struct ast_app *app;
- app = pbx_findapp(tmp->app);
- if (app) {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name);
- pbx_exec(tmp->chan, app, tmp->data);
- } else
- ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app);
- ast_hangup(tmp->chan);
- free(tmp);
- return NULL;
-}
-
-int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
-{
- struct ast_channel *chan;
- struct app_tmp *tmp;
- int res = -1, cdr_res = -1;
- struct outgoing_helper oh;
- pthread_attr_t attr;
-
- memset(&oh, 0, sizeof(oh));
- oh.vars = vars;
- oh.account = account;
-
- if (locked_channel)
- *locked_channel = NULL;
- if (ast_strlen_zero(app)) {
- res = -1;
- goto outgoing_app_cleanup;
- }
- if (sync) {
- chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
- if (chan) {
- if (!chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
- chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */
- if(!chan->cdr) {
- /* allocation of the cdr failed */
- free(chan->pbx);
- res = -1;
- goto outgoing_app_cleanup;
- }
- /* allocation of the cdr was successful */
- ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
- ast_cdr_start(chan->cdr);
- }
- ast_set_variables(chan, vars);
- if (account)
- ast_cdr_setaccount(chan, account);
- if (chan->_state == AST_STATE_UP) {
- res = 0;
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
- tmp = ast_calloc(1, sizeof(*tmp));
- if (!tmp)
- res = -1;
- else {
- ast_copy_string(tmp->app, app, sizeof(tmp->app));
- if (appdata)
- ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
- tmp->chan = chan;
- if (sync > 1) {
- if (locked_channel)
- ast_channel_unlock(chan);
- ast_pbx_run_app(tmp);
- } else {
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (locked_channel)
- ast_channel_lock(chan);
- if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
- ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
- free(tmp);
- if (locked_channel)
- ast_channel_unlock(chan);
- ast_hangup(chan);
- res = -1;
- } else {
- if (locked_channel)
- *locked_channel = chan;
- }
- pthread_attr_destroy(&attr);
- }
- }
- } else {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
- if (chan->cdr) { /* update the cdr */
- /* here we update the status of the call, which sould be busy.
- * if that fails then we set the status to failed */
- if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
- ast_cdr_failed(chan->cdr);
- }
- ast_hangup(chan);
- }
- }
-
- if (res < 0) { /* the call failed for some reason */
- if (*reason == 0) { /* if the call failed (not busy or no answer)
- * update the cdr with the failed message */
- cdr_res = ast_pbx_outgoing_cdr_failed();
- if (cdr_res != 0) {
- res = cdr_res;
- goto outgoing_app_cleanup;
- }
- }
- }
-
- } else {
- struct async_stat *as;
- if (!(as = ast_calloc(1, sizeof(*as)))) {
- res = -1;
- goto outgoing_app_cleanup;
- }
- chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
- if (!chan) {
- free(as);
- res = -1;
- goto outgoing_app_cleanup;
- }
- as->chan = chan;
- ast_copy_string(as->app, app, sizeof(as->app));
- if (appdata)
- ast_copy_string(as->appdata, appdata, sizeof(as->appdata));
- as->timeout = timeout;
- ast_set_variables(chan, vars);
- if (account)
- ast_cdr_setaccount(chan, account);
- /* Start a new thread, and get something handling this channel. */
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (locked_channel)
- ast_channel_lock(chan);
- if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
- ast_log(LOG_WARNING, "Failed to start async wait\n");
- free(as);
- if (locked_channel)
- ast_channel_unlock(chan);
- ast_hangup(chan);
- res = -1;
- pthread_attr_destroy(&attr);
- goto outgoing_app_cleanup;
- } else {
- if (locked_channel)
- *locked_channel = chan;
- }
- pthread_attr_destroy(&attr);
- res = 0;
- }
-outgoing_app_cleanup:
- ast_variables_destroy(vars);
- return res;
-}
-
-void __ast_context_destroy(struct ast_context *con, const char *registrar)
-{
- struct ast_context *tmp, *tmpl=NULL;
- struct ast_include *tmpi;
- struct ast_sw *sw;
- struct ast_exten *e, *el, *en;
- struct ast_ignorepat *ipi;
-
- for (tmp = contexts; tmp; ) {
- struct ast_context *next; /* next starting point */
- for (; tmp; tmpl = tmp, tmp = tmp->next) {
- if (option_debug)
- ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar);
- if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) &&
- (!con || !strcasecmp(tmp->name, con->name)) )
- break; /* found it */
- }
- if (!tmp) /* not found, we are done */
- break;
- ast_mutex_lock(&tmp->lock);
- if (option_debug)
- ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar);
- next = tmp->next;
- if (tmpl)
- tmpl->next = next;
- else
- contexts = next;
- /* Okay, now we're safe to let it go -- in a sense, we were
- ready to let it go as soon as we locked it. */
- ast_mutex_unlock(&tmp->lock);
- for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
- struct ast_include *tmpil = tmpi;
- tmpi = tmpi->next;
- free(tmpil);
- }
- for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
- struct ast_ignorepat *ipl = ipi;
- ipi = ipi->next;
- free(ipl);
- }
- while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list)))
- free(sw);
- for (e = tmp->root; e;) {
- for (en = e->peer; en;) {
- el = en;
- en = en->peer;
- destroy_exten(el);
- }
- el = e;
- e = e->next;
- destroy_exten(el);
- }
- ast_mutex_destroy(&tmp->lock);
- free(tmp);
- /* if we have a specific match, we are done, otherwise continue */
- tmp = con ? NULL : next;
- }
-}
-
-void ast_context_destroy(struct ast_context *con, const char *registrar)
-{
- ast_wrlock_contexts();
- __ast_context_destroy(con,registrar);
- ast_unlock_contexts();
-}
-
-static void wait_for_hangup(struct ast_channel *chan, void *data)
-{
- int res;
- struct ast_frame *f;
- int waittime;
-
- if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0))
- waittime = -1;
- if (waittime > -1) {
- ast_safe_sleep(chan, waittime * 1000);
- } else do {
- res = ast_waitfor(chan, -1);
- if (res < 0)
- return;
- f = ast_read(chan);
- if (f)
- ast_frfree(f);
- } while(f);
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_progress(struct ast_channel *chan, void *data)
-{
- ast_indicate(chan, AST_CONTROL_PROGRESS);
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_ringing(struct ast_channel *chan, void *data)
-{
- ast_indicate(chan, AST_CONTROL_RINGING);
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_busy(struct ast_channel *chan, void *data)
-{
- ast_indicate(chan, AST_CONTROL_BUSY);
- /* Don't change state of an UP channel, just indicate
- busy in audio */
- if (chan->_state != AST_STATE_UP)
- ast_setstate(chan, AST_STATE_BUSY);
- wait_for_hangup(chan, data);
- return -1;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_congestion(struct ast_channel *chan, void *data)
-{
- ast_indicate(chan, AST_CONTROL_CONGESTION);
- /* Don't change state of an UP channel, just indicate
- congestion in audio */
- if (chan->_state != AST_STATE_UP)
- ast_setstate(chan, AST_STATE_BUSY);
- wait_for_hangup(chan, data);
- return -1;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_answer(struct ast_channel *chan, void *data)
-{
- int delay = 0;
- int res;
-
- if (chan->_state == AST_STATE_UP)
- delay = 0;
- else if (!ast_strlen_zero(data))
- delay = atoi(data);
-
- res = ast_answer(chan);
- if (res)
- return res;
-
- if (delay)
- res = ast_safe_sleep(chan, delay);
-
- return res;
-}
-
-AST_APP_OPTIONS(resetcdr_opts, {
- AST_APP_OPTION('w', AST_CDR_FLAG_POSTED),
- AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED),
- AST_APP_OPTION('v', AST_CDR_FLAG_KEEP_VARS),
-});
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_resetcdr(struct ast_channel *chan, void *data)
-{
- char *args;
- struct ast_flags flags = { 0 };
-
- if (!ast_strlen_zero(data)) {
- args = ast_strdupa(data);
- ast_app_parse_options(resetcdr_opts, &flags, NULL, args);
- }
-
- ast_cdr_reset(chan->cdr, &flags);
-
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_setamaflags(struct ast_channel *chan, void *data)
-{
- /* Copy the AMA Flags as specified */
- ast_cdr_setamaflags(chan, data ? data : "");
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_hangup(struct ast_channel *chan, void *data)
-{
- if (!ast_strlen_zero(data)) {
- int cause;
- char *endptr;
-
- if ((cause = ast_str2cause(data)) > -1) {
- chan->hangupcause = cause;
- return -1;
- }
-
- cause = strtol((const char *) data, &endptr, 10);
- if (cause != 0 || (data != endptr)) {
- chan->hangupcause = cause;
- return -1;
- }
-
- ast_log(LOG_NOTICE, "Invalid cause given to Hangup(): \"%s\"\n", (char *) data);
- }
-
- if (!chan->hangupcause) {
- chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- }
-
- return -1;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
-{
- int res=0;
- char *s, *ts;
- struct ast_timing timing;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?[[context|]extension|]priority\n");
- return -1;
- }
-
- ts = s = ast_strdupa(data);
-
- /* Separate the Goto path */
- strsep(&ts,"?");
-
- /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
- if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
- res = pbx_builtin_goto(chan, ts);
-
- return res;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_execiftime(struct ast_channel *chan, void *data)
-{
- char *s, *appname;
- struct ast_timing timing;
- struct ast_app *app;
- static const char *usage = "ExecIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?<appname>[|<appargs>]";
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s\n", usage);
- return -1;
- }
-
- appname = ast_strdupa(data);
-
- s = strsep(&appname,"?"); /* Separate the timerange and application name/data */
- if (!appname) { /* missing application */
- ast_log(LOG_WARNING, "%s\n", usage);
- return -1;
- }
-
- if (!ast_build_timing(&timing, s)) {
- ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
- return -1;
- }
-
- if (!ast_check_timing(&timing)) /* outside the valid time window, just return */
- return 0;
-
- /* now split appname|appargs */
- if ((s = strchr(appname, '|')))
- *s++ = '\0';
-
- if ((app = pbx_findapp(appname))) {
- return pbx_exec(chan, app, S_OR(s, ""));
- } else {
- ast_log(LOG_WARNING, "Cannot locate application %s\n", appname);
- return -1;
- }
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_wait(struct ast_channel *chan, void *data)
-{
- double s;
- int ms;
-
- /* Wait for "n" seconds */
- if (data && (s = atof(data)) > 0) {
- ms = s * 1000.0;
- return ast_safe_sleep(chan, ms);
- }
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_waitexten(struct ast_channel *chan, void *data)
-{
- int ms, res;
- double sec;
- struct ast_flags flags = {0};
- char *opts[1] = { NULL };
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(timeout);
- AST_APP_ARG(options);
- );
-
- if (!ast_strlen_zero(data)) {
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
- } else
- memset(&args, 0, sizeof(args));
-
- if (args.options)
- ast_app_parse_options(waitexten_opts, &flags, opts, args.options);
-
- if (ast_test_flag(&flags, WAITEXTEN_MOH) && !opts[0] ) {
- ast_log(LOG_WARNING, "The 'm' option has been specified for WaitExten without a class.\n");
- } else if (ast_test_flag(&flags, WAITEXTEN_MOH))
- ast_indicate_data(chan, AST_CONTROL_HOLD, opts[0], strlen(opts[0]));
-
- /* Wait for "n" seconds */
- if (args.timeout && (sec = atof(args.timeout)) > 0.0)
- ms = 1000 * sec;
- else if (chan->pbx)
- ms = chan->pbx->rtimeout * 1000;
- else
- ms = 10000;
- res = ast_waitfordigit(chan, ms);
- if (!res) {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Timeout on %s, continuing...\n", chan->name);
- } else if (chan->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call timeout on %s, checking for 'T'\n", chan->name);
- res = -1;
- } else if (ast_exists_extension(chan, chan->context, "t", 1, chan->cid.cid_num)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Timeout on %s, going to 't'\n", chan->name);
- set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
- } else {
- ast_log(LOG_WARNING, "Timeout but no rule 't' in context '%s'\n", chan->context);
- res = -1;
- }
- }
-
- if (ast_test_flag(&flags, WAITEXTEN_MOH))
- ast_indicate(chan, AST_CONTROL_UNHOLD);
-
- return res;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_background(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_flags flags = {0};
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(filename);
- AST_APP_ARG(options);
- AST_APP_ARG(lang);
- AST_APP_ARG(context);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.lang))
- args.lang = (char *)chan->language; /* XXX this is const */
-
- if (ast_strlen_zero(args.context))
- args.context = chan->context;
-
- if (args.options) {
- if (!strcasecmp(args.options, "skip"))
- flags.flags = BACKGROUND_SKIP;
- else if (!strcasecmp(args.options, "noanswer"))
- flags.flags = BACKGROUND_NOANSWER;
- else
- ast_app_parse_options(background_opts, &flags, NULL, args.options);
- }
-
- /* Answer if need be */
- if (chan->_state != AST_STATE_UP) {
- if (ast_test_flag(&flags, BACKGROUND_SKIP)) {
- return 0;
- } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
- res = ast_answer(chan);
- }
- }
-
- if (!res) {
- char *back = args.filename;
- char *front;
- ast_stopstream(chan); /* Stop anything playing */
- /* Stream the list of files */
- while (!res && (front = strsep(&back, "&")) ) {
- if ( (res = ast_streamfile(chan, front, args.lang)) ) {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char*)data);
- res = 0;
- break;
- }
- if (ast_test_flag(&flags, BACKGROUND_PLAYBACK)) {
- res = ast_waitstream(chan, "");
- } else if (ast_test_flag(&flags, BACKGROUND_MATCHEXTEN)) {
- res = ast_waitstream_exten(chan, args.context);
- } else {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- }
- ast_stopstream(chan);
- }
- }
- if (args.context != chan->context && res) {
- snprintf(chan->exten, sizeof(chan->exten), "%c", res);
- ast_copy_string(chan->context, args.context, sizeof(chan->context));
- chan->priority = 0;
- res = 0;
- }
- return res;
-}
-
-/*! Goto
- * \ingroup applications
- */
-static int pbx_builtin_goto(struct ast_channel *chan, void *data)
-{
- int res = ast_parseable_goto(chan, data);
- if (!res && (option_verbose > 2))
- ast_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
- return res;
-}
-
-
-int pbx_builtin_serialize_variables(struct ast_channel *chan, char *buf, size_t size)
-{
- struct ast_var_t *variables;
- const char *var, *val;
- int total = 0;
-
- if (!chan)
- return 0;
-
- memset(buf, 0, size);
-
- ast_channel_lock(chan);
-
- AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
- if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
- /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
- ) {
- if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
- ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
- break;
- } else
- total++;
- } else
- break;
- }
-
- ast_channel_unlock(chan);
-
- return total;
-}
-
-const char *pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
-{
- struct ast_var_t *variables;
- const char *ret = NULL;
- int i;
- struct varshead *places[2] = { NULL, &globals };
-
- if (!name)
- return NULL;
-
- if (chan) {
- ast_channel_lock(chan);
- places[0] = &chan->varshead;
- }
-
- for (i = 0; i < 2; i++) {
- if (!places[i])
- continue;
- if (places[i] == &globals)
- ast_mutex_lock(&globalslock);
- AST_LIST_TRAVERSE(places[i], variables, entries) {
- if (!strcmp(name, ast_var_name(variables))) {
- ret = ast_var_value(variables);
- break;
- }
- }
- if (places[i] == &globals)
- ast_mutex_unlock(&globalslock);
- if (ret)
- break;
- }
-
- if (chan)
- ast_channel_unlock(chan);
-
- return ret;
-}
-
-void pbx_builtin_pushvar_helper(struct ast_channel *chan, const char *name, const char *value)
-{
- struct ast_var_t *newvariable;
- struct varshead *headp;
-
- if (name[strlen(name)-1] == ')') {
- char *function = ast_strdupa(name);
-
- ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
- ast_func_write(chan, function, value);
- return;
- }
-
- if (chan) {
- ast_channel_lock(chan);
- headp = &chan->varshead;
- } else {
- ast_mutex_lock(&globalslock);
- headp = &globals;
- }
-
- if (value) {
- if ((option_verbose > 1) && (headp == &globals))
- ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
- newvariable = ast_var_assign(name, value);
- AST_LIST_INSERT_HEAD(headp, newvariable, entries);
- }
-
- if (chan)
- ast_channel_unlock(chan);
- else
- ast_mutex_unlock(&globalslock);
-}
-
-void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
-{
- struct ast_var_t *newvariable;
- struct varshead *headp;
- const char *nametail = name;
-
- if (name[strlen(name)-1] == ')') {
- char *function = ast_strdupa(name);
-
- ast_func_write(chan, function, value);
- return;
- }
-
- if (chan) {
- ast_channel_lock(chan);
- headp = &chan->varshead;
- } else {
- ast_mutex_lock(&globalslock);
- headp = &globals;
- }
-
- /* For comparison purposes, we have to strip leading underscores */
- if (*nametail == '_') {
- nametail++;
- if (*nametail == '_')
- nametail++;
- }
-
- AST_LIST_TRAVERSE (headp, newvariable, entries) {
- if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
- /* there is already such a variable, delete it */
- AST_LIST_REMOVE(headp, newvariable, entries);
- ast_var_delete(newvariable);
- break;
- }
- }
-
- if (value) {
- if ((option_verbose > 1) && (headp == &globals))
- ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
- newvariable = ast_var_assign(name, value);
- AST_LIST_INSERT_HEAD(headp, newvariable, entries);
- }
-
- if (chan)
- ast_channel_unlock(chan);
- else
- ast_mutex_unlock(&globalslock);
-}
-
-int pbx_builtin_setvar(struct ast_channel *chan, void *data)
-{
- char *name, *value, *mydata;
- int argc;
- char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
- int global = 0;
- int x;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
- return 0;
- }
-
- mydata = ast_strdupa(data);
- argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
-
- /* check for a trailing flags argument */
- if ((argc > 1) && !strchr(argv[argc-1], '=')) {
- argc--;
- if (strchr(argv[argc], 'g')) {
- ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n");
- global = 1;
- }
- }
-
- if (argc > 1)
- ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n");
-
- for (x = 0; x < argc; x++) {
- name = argv[x];
- if ((value = strchr(name, '='))) {
- *value++ = '\0';
- pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
- } else
- ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
- }
-
- return(0);
-}
-
-int pbx_builtin_importvar(struct ast_channel *chan, void *data)
-{
- char *name;
- char *value;
- char *channel;
- char tmp[VAR_BUF_SIZE]="";
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
- return 0;
- }
-
- value = ast_strdupa(data);
- name = strsep(&value,"=");
- channel = strsep(&value,"|");
- if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */
- struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel);
- if (chan2) {
- char *s = alloca(strlen(value) + 4);
- if (s) {
- sprintf(s, "${%s}", value);
- pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
- }
- ast_channel_unlock(chan2);
- }
- pbx_builtin_setvar_helper(chan, name, tmp);
- }
-
- return(0);
-}
-
-/*! \todo XXX overwrites data ? */
-static int pbx_builtin_setglobalvar(struct ast_channel *chan, void *data)
-{
- char *name;
- char *stringp = data;
- static int dep_warning = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
- return 0;
- }
-
- name = strsep(&stringp, "=");
-
- if (!dep_warning) {
- dep_warning = 1;
- ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp);
- }
-
- /*! \todo XXX watch out, leading whitespace ? */
- pbx_builtin_setvar_helper(NULL, name, stringp);
-
- return(0);
-}
-
-static int pbx_builtin_noop(struct ast_channel *chan, void *data)
-{
- return 0;
-}
-
-void pbx_builtin_clear_globals(void)
-{
- struct ast_var_t *vardata;
-
- ast_mutex_lock(&globalslock);
- while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
- ast_var_delete(vardata);
- ast_mutex_unlock(&globalslock);
-}
-
-int pbx_checkcondition(const char *condition)
-{
- if (ast_strlen_zero(condition)) /* NULL or empty strings are false */
- return 0;
- else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */
- return atoi(condition);
- else /* Strings are true */
- return 1;
-}
-
-static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
-{
- char *condition, *branch1, *branch2, *branch;
- int rc;
- char *stringp;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
- return 0;
- }
-
- stringp = ast_strdupa(data);
- condition = strsep(&stringp,"?");
- branch1 = strsep(&stringp,":");
- branch2 = strsep(&stringp,"");
- branch = pbx_checkcondition(condition) ? branch1 : branch2;
-
- if (ast_strlen_zero(branch)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Not taking any branch\n");
- return 0;
- }
-
- rc = pbx_builtin_goto(chan, branch);
-
- return rc;
-}
-
-static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
-{
- char tmp[256];
- char *number = tmp;
- char *options;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
- return -1;
- }
- ast_copy_string(tmp, data, sizeof(tmp));
- strsep(&number, "|");
- options = strsep(&number, "|");
- if (options) {
- if ( strcasecmp(options, "f") && strcasecmp(options,"m") &&
- strcasecmp(options, "c") && strcasecmp(options, "n") ) {
- ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
- return -1;
- }
- }
-
- if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) {
- ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
- }
-
- return 0;
-}
-
-static int pbx_builtin_saydigits(struct ast_channel *chan, void *data)
-{
- int res = 0;
-
- if (data)
- res = ast_say_digit_str(chan, data, "", chan->language);
- return res;
-}
-
-static int pbx_builtin_saycharacters(struct ast_channel *chan, void *data)
-{
- int res = 0;
-
- if (data)
- res = ast_say_character_str(chan, data, "", chan->language);
- return res;
-}
-
-static int pbx_builtin_sayphonetic(struct ast_channel *chan, void *data)
-{
- int res = 0;
-
- if (data)
- res = ast_say_phonetic_str(chan, data, "", chan->language);
- return res;
-}
-
-int load_pbx(void)
-{
- int x;
-
- /* Initialize the PBX */
- if (option_verbose) {
- ast_verbose( "Asterisk PBX Core Initializing\n");
- ast_verbose( "Registering builtin applications:\n");
- }
- ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry));
-
- /* Register builtin applications */
- for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
- if (option_verbose)
- ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name);
- if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) {
- ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
- return -1;
- }
- }
- return 0;
-}
-
-/*
- * Lock context list functions ...
- */
-int ast_lock_contexts()
-{
- return ast_rwlock_wrlock(&conlock);
-}
-
-int ast_rdlock_contexts(void)
-{
- return ast_rwlock_rdlock(&conlock);
-}
-
-int ast_wrlock_contexts(void)
-{
- return ast_rwlock_wrlock(&conlock);
-}
-
-int ast_unlock_contexts()
-{
- return ast_rwlock_unlock(&conlock);
-}
-
-/*
- * Lock context ...
- */
-int ast_lock_context(struct ast_context *con)
-{
- return ast_mutex_lock(&con->lock);
-}
-
-int ast_unlock_context(struct ast_context *con)
-{
- return ast_mutex_unlock(&con->lock);
-}
-
-/*
- * Name functions ...
- */
-const char *ast_get_context_name(struct ast_context *con)
-{
- return con ? con->name : NULL;
-}
-
-struct ast_context *ast_get_extension_context(struct ast_exten *exten)
-{
- return exten ? exten->parent : NULL;
-}
-
-const char *ast_get_extension_name(struct ast_exten *exten)
-{
- return exten ? exten->exten : NULL;
-}
-
-const char *ast_get_extension_label(struct ast_exten *exten)
-{
- return exten ? exten->label : NULL;
-}
-
-const char *ast_get_include_name(struct ast_include *inc)
-{
- return inc ? inc->name : NULL;
-}
-
-const char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
-{
- return ip ? ip->pattern : NULL;
-}
-
-int ast_get_extension_priority(struct ast_exten *exten)
-{
- return exten ? exten->priority : -1;
-}
-
-/*
- * Registrar info functions ...
- */
-const char *ast_get_context_registrar(struct ast_context *c)
-{
- return c ? c->registrar : NULL;
-}
-
-const char *ast_get_extension_registrar(struct ast_exten *e)
-{
- return e ? e->registrar : NULL;
-}
-
-const char *ast_get_include_registrar(struct ast_include *i)
-{
- return i ? i->registrar : NULL;
-}
-
-const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
-{
- return ip ? ip->registrar : NULL;
-}
-
-int ast_get_extension_matchcid(struct ast_exten *e)
-{
- return e ? e->matchcid : 0;
-}
-
-const char *ast_get_extension_cidmatch(struct ast_exten *e)
-{
- return e ? e->cidmatch : NULL;
-}
-
-const char *ast_get_extension_app(struct ast_exten *e)
-{
- return e ? e->app : NULL;
-}
-
-void *ast_get_extension_app_data(struct ast_exten *e)
-{
- return e ? e->data : NULL;
-}
-
-const char *ast_get_switch_name(struct ast_sw *sw)
-{
- return sw ? sw->name : NULL;
-}
-
-const char *ast_get_switch_data(struct ast_sw *sw)
-{
- return sw ? sw->data : NULL;
-}
-
-const char *ast_get_switch_registrar(struct ast_sw *sw)
-{
- return sw ? sw->registrar : NULL;
-}
-
-/*
- * Walking functions ...
- */
-struct ast_context *ast_walk_contexts(struct ast_context *con)
-{
- return con ? con->next : contexts;
-}
-
-struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
- struct ast_exten *exten)
-{
- if (!exten)
- return con ? con->root : NULL;
- else
- return exten->next;
-}
-
-struct ast_sw *ast_walk_context_switches(struct ast_context *con,
- struct ast_sw *sw)
-{
- if (!sw)
- return con ? AST_LIST_FIRST(&con->alts) : NULL;
- else
- return AST_LIST_NEXT(sw, list);
-}
-
-struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
- struct ast_exten *priority)
-{
- return priority ? priority->peer : exten;
-}
-
-struct ast_include *ast_walk_context_includes(struct ast_context *con,
- struct ast_include *inc)
-{
- if (!inc)
- return con ? con->includes : NULL;
- else
- return inc->next;
-}
-
-struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
- struct ast_ignorepat *ip)
-{
- if (!ip)
- return con ? con->ignorepats : NULL;
- else
- return ip->next;
-}
-
-int ast_context_verify_includes(struct ast_context *con)
-{
- struct ast_include *inc = NULL;
- int res = 0;
-
- while ( (inc = ast_walk_context_includes(con, inc)) ) {
- if (ast_context_find(inc->rname))
- continue;
-
- res = -1;
- ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
- ast_get_context_name(con), inc->rname);
- break;
- }
-
- return res;
-}
-
-
-static int __ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
-{
- int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority);
-
- if (!chan)
- return -2;
-
- if (context == NULL)
- context = chan->context;
- if (exten == NULL)
- exten = chan->exten;
-
- goto_func = (async) ? ast_async_goto : ast_explicit_goto;
- if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num))
- return goto_func(chan, context, exten, priority);
- else
- return -3;
-}
-
-int ast_goto_if_exists(struct ast_channel *chan, const char* context, const char *exten, int priority)
-{
- return __ast_goto_if_exists(chan, context, exten, priority, 0);
-}
-
-int ast_async_goto_if_exists(struct ast_channel *chan, const char * context, const char *exten, int priority)
-{
- return __ast_goto_if_exists(chan, context, exten, priority, 1);
-}
-
-int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
-{
- char *exten, *pri, *context;
- char *stringp;
- int ipri;
- int mode = 0;
-
- if (ast_strlen_zero(goto_string)) {
- ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
- return -1;
- }
- stringp = ast_strdupa(goto_string);
- context = strsep(&stringp, "|"); /* guaranteed non-null */
- exten = strsep(&stringp, "|");
- pri = strsep(&stringp, "|");
- if (!exten) { /* Only a priority in this one */
- pri = context;
- exten = NULL;
- context = NULL;
- } else if (!pri) { /* Only an extension and priority in this one */
- pri = exten;
- exten = context;
- context = NULL;
- }
- if (*pri == '+') {
- mode = 1;
- pri++;
- } else if (*pri == '-') {
- mode = -1;
- pri++;
- }
- if (sscanf(pri, "%d", &ipri) != 1) {
- if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
- pri, chan->cid.cid_num)) < 1) {
- ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
- return -1;
- } else
- mode = 0;
- }
- /* At this point we have a priority and maybe an extension and a context */
-
- if (mode)
- ipri = chan->priority + (ipri * mode);
-
- ast_explicit_goto(chan, context, exten, ipri);
- ast_cdr_update(chan);
- return 0;
-
-}
diff --git a/1.4/main/plc.c b/1.4/main/plc.c
deleted file mode 100644
index 336a99030..000000000
--- a/1.4/main/plc.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2004 Steve Underwood
- *
- * All rights reserved.
- *
- * 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.
- *
- * This version may be optionally licenced under the GNU LGPL licence.
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-/*! \file
- *
- * \brief SpanDSP - a series of DSP components for telephony
- *
- * \author Steve Underwood <steveu@coppice.org>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "asterisk/plc.h"
-
-#if !defined(FALSE)
-#define FALSE 0
-#endif
-#if !defined(TRUE)
-#define TRUE (!FALSE)
-#endif
-
-#if !defined(INT16_MAX)
-#define INT16_MAX (32767)
-#define INT16_MIN (-32767-1)
-#endif
-
-/* We do a straight line fade to zero volume in 50ms when we are filling in for missing data. */
-#define ATTENUATION_INCREMENT 0.0025 /* Attenuation per sample */
-
-#define ms_to_samples(t) (((t)*DEFAULT_SAMPLE_RATE)/1000)
-
-static inline int16_t fsaturate(double damp)
-{
- if (damp > 32767.0)
- return INT16_MAX;
- if (damp < -32768.0)
- return INT16_MIN;
- return (int16_t) rint(damp);
-}
-
-static void save_history(plc_state_t *s, int16_t *buf, int len)
-{
- if (len >= PLC_HISTORY_LEN) {
- /* Just keep the last part of the new data, starting at the beginning of the buffer */
- memcpy(s->history, buf + len - PLC_HISTORY_LEN, sizeof(int16_t) * PLC_HISTORY_LEN);
- s->buf_ptr = 0;
- return;
- }
- if (s->buf_ptr + len > PLC_HISTORY_LEN) {
- /* Wraps around - must break into two sections */
- memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t) * (PLC_HISTORY_LEN - s->buf_ptr));
- len -= (PLC_HISTORY_LEN - s->buf_ptr);
- memcpy(s->history, buf + (PLC_HISTORY_LEN - s->buf_ptr), sizeof(int16_t)*len);
- s->buf_ptr = len;
- return;
- }
- /* Can use just one section */
- memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t)*len);
- s->buf_ptr += len;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-static void normalise_history(plc_state_t *s)
-{
- int16_t tmp[PLC_HISTORY_LEN];
-
- if (s->buf_ptr == 0)
- return;
- memcpy(tmp, s->history, sizeof(int16_t)*s->buf_ptr);
- memcpy(s->history, s->history + s->buf_ptr, sizeof(int16_t) * (PLC_HISTORY_LEN - s->buf_ptr));
- memcpy(s->history + PLC_HISTORY_LEN - s->buf_ptr, tmp, sizeof(int16_t) * s->buf_ptr);
- s->buf_ptr = 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-static int __inline__ amdf_pitch(int min_pitch, int max_pitch, int16_t amp[], int len)
-{
- int i;
- int j;
- int acc;
- int min_acc;
- int pitch;
-
- pitch = min_pitch;
- min_acc = INT_MAX;
- for (i = max_pitch; i <= min_pitch; i++) {
- acc = 0;
- for (j = 0; j < len; j++)
- acc += abs(amp[i + j] - amp[j]);
- if (acc < min_acc) {
- min_acc = acc;
- pitch = i;
- }
- }
- return pitch;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int plc_rx(plc_state_t *s, int16_t amp[], int len)
-{
- int i;
- int pitch_overlap;
- float old_step;
- float new_step;
- float old_weight;
- float new_weight;
- float gain;
-
- if (s->missing_samples) {
- /* Although we have a real signal, we need to smooth it to fit well
- with the synthetic signal we used for the previous block */
-
- /* The start of the real data is overlapped with the next 1/4 cycle
- of the synthetic data. */
- pitch_overlap = s->pitch >> 2;
- if (pitch_overlap > len)
- pitch_overlap = len;
- gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT;
- if (gain < 0.0)
- gain = 0.0;
- new_step = 1.0/pitch_overlap;
- old_step = new_step*gain;
- new_weight = new_step;
- old_weight = (1.0 - new_step)*gain;
- for (i = 0; i < pitch_overlap; i++) {
- amp[i] = fsaturate(old_weight * s->pitchbuf[s->pitch_offset] + new_weight * amp[i]);
- if (++s->pitch_offset >= s->pitch)
- s->pitch_offset = 0;
- new_weight += new_step;
- old_weight -= old_step;
- if (old_weight < 0.0)
- old_weight = 0.0;
- }
- s->missing_samples = 0;
- }
- save_history(s, amp, len);
- return len;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int plc_fillin(plc_state_t *s, int16_t amp[], int len)
-{
- int i;
- int pitch_overlap;
- float old_step;
- float new_step;
- float old_weight;
- float new_weight;
- float gain;
- int16_t *orig_amp;
- int orig_len;
-
- orig_amp = amp;
- orig_len = len;
- if (s->missing_samples == 0) {
- /* As the gap in real speech starts we need to assess the last known pitch,
- and prepare the synthetic data we will use for fill-in */
- normalise_history(s);
- s->pitch = amdf_pitch(PLC_PITCH_MIN, PLC_PITCH_MAX, s->history + PLC_HISTORY_LEN - CORRELATION_SPAN - PLC_PITCH_MIN, CORRELATION_SPAN);
- /* We overlap a 1/4 wavelength */
- pitch_overlap = s->pitch >> 2;
- /* Cook up a single cycle of pitch, using a single of the real signal with 1/4
- cycle OLA'ed to make the ends join up nicely */
- /* The first 3/4 of the cycle is a simple copy */
- for (i = 0; i < s->pitch - pitch_overlap; i++)
- s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i];
- /* The last 1/4 of the cycle is overlapped with the end of the previous cycle */
- new_step = 1.0/pitch_overlap;
- new_weight = new_step;
- for ( ; i < s->pitch; i++) {
- s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i] * (1.0 - new_weight) + s->history[PLC_HISTORY_LEN - 2 * s->pitch + i]*new_weight;
- new_weight += new_step;
- }
- /* We should now be ready to fill in the gap with repeated, decaying cycles
- of what is in pitchbuf */
-
- /* We need to OLA the first 1/4 wavelength of the synthetic data, to smooth
- it into the previous real data. To avoid the need to introduce a delay
- in the stream, reverse the last 1/4 wavelength, and OLA with that. */
- gain = 1.0;
- new_step = 1.0 / pitch_overlap;
- old_step = new_step;
- new_weight = new_step;
- old_weight = 1.0 - new_step;
- for (i = 0; i < pitch_overlap; i++) {
- amp[i] = fsaturate(old_weight * s->history[PLC_HISTORY_LEN - 1 - i] + new_weight * s->pitchbuf[i]);
- new_weight += new_step;
- old_weight -= old_step;
- if (old_weight < 0.0)
- old_weight = 0.0;
- }
- s->pitch_offset = i;
- } else {
- gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT;
- i = 0;
- }
- for ( ; gain > 0.0 && i < len; i++) {
- amp[i] = s->pitchbuf[s->pitch_offset] * gain;
- gain -= ATTENUATION_INCREMENT;
- if (++s->pitch_offset >= s->pitch)
- s->pitch_offset = 0;
- }
- for ( ; i < len; i++)
- amp[i] = 0;
- s->missing_samples += orig_len;
- save_history(s, amp, len);
- return len;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-plc_state_t *plc_init(plc_state_t *s)
-{
- memset(s, 0, sizeof(*s));
- return s;
-}
-/*- End of function --------------------------------------------------------*/
-/*- End of file ------------------------------------------------------------*/
diff --git a/1.4/main/poll.c b/1.4/main/poll.c
deleted file mode 100644
index bd283866d..000000000
--- a/1.4/main/poll.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*---------------------------------------------------------------------------*\
- $Id$
-
- NAME
-
- poll - select(2)-based poll() emulation function for BSD systems.
-
- SYNOPSIS
- #include "poll.h"
-
- struct pollfd
- {
- int fd;
- short events;
- short revents;
- }
-
- int poll (struct pollfd *pArray, unsigned long n_fds, int timeout)
-
- DESCRIPTION
-
- This file, and the accompanying "poll.h", implement the System V
- poll(2) system call for BSD systems (which typically do not provide
- poll()). Poll() provides a method for multiplexing input and output
- on multiple open file descriptors; in traditional BSD systems, that
- capability is provided by select(). While the semantics of select()
- differ from those of poll(), poll() can be readily emulated in terms
- of select() -- which is how this function is implemented.
-
- REFERENCES
- Stevens, W. Richard. Unix Network Programming. Prentice-Hall, 1990.
-
- NOTES
- 1. This software requires an ANSI C compiler.
-
- LICENSE
-
- This software is released under the following license:
-
- Copyright (c) 1995-2002 Brian M. Clapper
- All rights reserved.
-
- Redistribution and use in source and binary forms are
- permitted provided that: (1) source distributions retain
- this entire copyright notice and comment; (2) modifications
- made to the software are prominently mentioned, and a copy
- of the original software (or a pointer to its location) are
- included; and (3) distributions including binaries display
- the following acknowledgement: "This product includes
- software developed by Brian M. Clapper <bmc@clapper.org>"
- in the documentation or other materials provided with the
- distribution. The name of the author may not be used to
- endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE.
-
- Effectively, this means you can do what you want with the software
- except remove this notice or take advantage of the author's name.
- If you modify the software and redistribute your modified version,
- you must indicate that your version is a modification of the
- original, and you must provide either a pointer to or a copy of the
- original.
-\*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*\
- Includes
-\*---------------------------------------------------------------------------*/
-
-#include <unistd.h> /* standard Unix definitions */
-#include <sys/types.h> /* system types */
-#include <sys/time.h> /* time definitions */
-#include <assert.h> /* assertion macros */
-#include <string.h> /* string functions */
-
-#include "asterisk/poll-compat.h" /* this package */
-
-/*---------------------------------------------------------------------------*\
- Macros
-\*---------------------------------------------------------------------------*/
-
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-
-/*---------------------------------------------------------------------------*\
- Private Functions
-\*---------------------------------------------------------------------------*/
-
-static int map_poll_spec
-#if __STDC__ > 0
- (struct pollfd *pArray,
- unsigned long n_fds,
- fd_set *pReadSet,
- fd_set *pWriteSet,
- fd_set *pExceptSet)
-#else
- (pArray, n_fds, pReadSet, pWriteSet, pExceptSet)
- struct pollfd *pArray;
- unsigned long n_fds;
- fd_set *pReadSet;
- fd_set *pWriteSet;
- fd_set *pExceptSet;
-#endif
-{
- register unsigned long i; /* loop control */
- register struct pollfd *pCur; /* current array element */
- register int max_fd = -1; /* return value */
-
- /*
- Map the poll() structures into the file descriptor sets required
- by select().
- */
- for (i = 0, pCur = pArray; i < n_fds; i++, pCur++)
- {
- /* Skip any bad FDs in the array. */
-
- if (pCur->fd < 0)
- continue;
-
- if (pCur->events & POLLIN)
- {
- /* "Input Ready" notification desired. */
- FD_SET (pCur->fd, pReadSet);
- }
-
- if (pCur->events & POLLOUT)
- {
- /* "Output Possible" notification desired. */
- FD_SET (pCur->fd, pWriteSet);
- }
-
- if (pCur->events & POLLPRI)
- {
- /*
- "Exception Occurred" notification desired. (Exceptions
- include out of band data.
- */
- FD_SET (pCur->fd, pExceptSet);
- }
-
- max_fd = MAX (max_fd, pCur->fd);
- }
-
- return max_fd;
-}
-
-static struct timeval *map_timeout
-#if __STDC__ > 0
- (int poll_timeout, struct timeval *pSelTimeout)
-#else
- (poll_timeout, pSelTimeout)
- int poll_timeout;
- struct timeval *pSelTimeout;
-#endif
-{
- struct timeval *pResult;
-
- /*
- Map the poll() timeout value into a select() timeout. The possible
- values of the poll() timeout value, and their meanings, are:
-
- VALUE MEANING
-
- -1 wait indefinitely (until signal occurs)
- 0 return immediately, don't block
- >0 wait specified number of milliseconds
-
- select() uses a "struct timeval", which specifies the timeout in
- seconds and microseconds, so the milliseconds value has to be mapped
- accordingly.
- */
-
- assert (pSelTimeout != (struct timeval *) NULL);
-
- switch (poll_timeout)
- {
- case -1:
- /*
- A NULL timeout structure tells select() to wait indefinitely.
- */
- pResult = (struct timeval *) NULL;
- break;
-
- case 0:
- /*
- "Return immediately" (test) is specified by all zeros in
- a timeval structure.
- */
- pSelTimeout->tv_sec = 0;
- pSelTimeout->tv_usec = 0;
- pResult = pSelTimeout;
- break;
-
- default:
- /* Wait the specified number of milliseconds. */
- pSelTimeout->tv_sec = poll_timeout / 1000; /* get seconds */
- poll_timeout %= 1000; /* remove seconds */
- pSelTimeout->tv_usec = poll_timeout * 1000; /* get microseconds */
- pResult = pSelTimeout;
- break;
- }
-
-
- return pResult;
-}
-
-static void map_select_results
-#if __STDC__ > 0
- (struct pollfd *pArray,
- unsigned long n_fds,
- fd_set *pReadSet,
- fd_set *pWriteSet,
- fd_set *pExceptSet)
-#else
- (pArray, n_fds, pReadSet, pWriteSet, pExceptSet)
- struct pollfd *pArray;
- unsigned long n_fds;
- fd_set *pReadSet;
- fd_set *pWriteSet;
- fd_set *pExceptSet;
-#endif
-{
- register unsigned long i; /* loop control */
- register struct pollfd *pCur; /* current array element */
-
- for (i = 0, pCur = pArray; i < n_fds; i++, pCur++)
- {
- /* Skip any bad FDs in the array. */
-
- if (pCur->fd < 0)
- continue;
-
- /* Exception events take priority over input events. */
-
- pCur->revents = 0;
- if (FD_ISSET (pCur->fd, pExceptSet))
- pCur->revents |= POLLPRI;
-
- else if (FD_ISSET (pCur->fd, pReadSet))
- pCur->revents |= POLLIN;
-
- if (FD_ISSET (pCur->fd, pWriteSet))
- pCur->revents |= POLLOUT;
- }
-
- return;
-}
-
-/*---------------------------------------------------------------------------*\
- Public Functions
-\*---------------------------------------------------------------------------*/
-
-int poll
-
-#if __STDC__ > 0
- (struct pollfd *pArray, unsigned long n_fds, int timeout)
-#else
- (pArray, n_fds, timeout)
- struct pollfd *pArray;
- unsigned long n_fds;
- int timeout;
-#endif
-
-{
- fd_set read_descs; /* input file descs */
- fd_set write_descs; /* output file descs */
- fd_set except_descs; /* exception descs */
- struct timeval stime; /* select() timeout value */
- int ready_descriptors; /* function result */
- int max_fd; /* maximum fd value */
- struct timeval *pTimeout; /* actually passed */
-
- FD_ZERO (&read_descs);
- FD_ZERO (&write_descs);
- FD_ZERO (&except_descs);
-
- assert (pArray != (struct pollfd *) NULL);
-
- /* Map the poll() file descriptor list in the select() data structures. */
-
- max_fd = map_poll_spec (pArray, n_fds,
- &read_descs, &write_descs, &except_descs);
-
- /* Map the poll() timeout value in the select() timeout structure. */
-
- pTimeout = map_timeout (timeout, &stime);
-
- /* Make the select() call. */
-
- ready_descriptors = select (max_fd + 1, &read_descs, &write_descs,
- &except_descs, pTimeout);
-
- if (ready_descriptors >= 0)
- {
- map_select_results (pArray, n_fds,
- &read_descs, &write_descs, &except_descs);
- }
-
- return ready_descriptors;
-}
diff --git a/1.4/main/privacy.c b/1.4/main/privacy.c
deleted file mode 100644
index b27bb5046..000000000
--- a/1.4/main/privacy.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Privacy Routines
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/astdb.h"
-#include "asterisk/callerid.h"
-#include "asterisk/privacy.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-int ast_privacy_check(char *dest, char *cid)
-{
- char tmp[256] = "";
- char *trimcid = "";
- char *n, *l;
- int res;
- char key[256], result[256];
- if (cid)
- ast_copy_string(tmp, cid, sizeof(tmp));
- ast_callerid_parse(tmp, &n, &l);
- if (l) {
- ast_shrink_phone_number(l);
- trimcid = l;
- }
- snprintf(key, sizeof(key), "%s/%s", dest, trimcid);
- res = ast_db_get("privacy", key, result, sizeof(result));
- if (!res) {
- if (!strcasecmp(result, "allow"))
- return AST_PRIVACY_ALLOW;
- if (!strcasecmp(result, "deny"))
- return AST_PRIVACY_DENY;
- if (!strcasecmp(result, "kill"))
- return AST_PRIVACY_KILL;
- if (!strcasecmp(result, "torture"))
- return AST_PRIVACY_TORTURE;
- }
- return AST_PRIVACY_UNKNOWN;
-}
-
-int ast_privacy_reset(char *dest)
-{
- if (!dest)
- return -1;
- return ast_db_deltree("privacy", dest);
-}
-
-int ast_privacy_set(char *dest, char *cid, int status)
-{
- char tmp[256] = "";
- char *trimcid = "";
- char *n, *l;
- int res;
- char key[256];
- if (cid)
- ast_copy_string(tmp, cid, sizeof(tmp));
- ast_callerid_parse(tmp, &n, &l);
- if (l) {
- ast_shrink_phone_number(l);
- trimcid = l;
- }
- if (ast_strlen_zero(trimcid)) {
- /* Don't store anything for empty Caller*ID */
- return 0;
- }
- snprintf(key, sizeof(key), "%s/%s", dest, trimcid);
- if (status == AST_PRIVACY_UNKNOWN)
- res = ast_db_del("privacy", key);
- else if (status == AST_PRIVACY_ALLOW)
- res = ast_db_put("privacy", key, "allow");
- else if (status == AST_PRIVACY_DENY)
- res = ast_db_put("privacy", key, "deny");
- else if (status == AST_PRIVACY_KILL)
- res = ast_db_put("privacy", key, "kill");
- else if (status == AST_PRIVACY_TORTURE)
- res = ast_db_put("privacy", key, "torture");
- else
- res = -1;
- return res;
-}
diff --git a/1.4/main/rtp.c b/1.4/main/rtp.c
deleted file mode 100644
index 658bd0891..000000000
--- a/1.4/main/rtp.c
+++ /dev/null
@@ -1,3824 +0,0 @@
-/*
- * 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.
- */
-
-/*!
- * \file
- *
- * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note RTP is defined in RFC 3550.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-
-#include "asterisk/rtp.h"
-#include "asterisk/frame.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/acl.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/cli.h"
-#include "asterisk/unaligned.h"
-#include "asterisk/utils.h"
-
-#define MAX_TIMESTAMP_SKEW 640
-
-#define RTP_SEQ_MOD (1<<16) /*!< A sequence number can't be more than 16 bits */
-#define RTCP_DEFAULT_INTERVALMS 5000 /*!< Default milli-seconds between RTCP reports we send */
-#define RTCP_MIN_INTERVALMS 500 /*!< Min milli-seconds between RTCP reports we send */
-#define RTCP_MAX_INTERVALMS 60000 /*!< Max milli-seconds between RTCP reports we send */
-
-#define RTCP_PT_FUR 192
-#define RTCP_PT_SR 200
-#define RTCP_PT_RR 201
-#define RTCP_PT_SDES 202
-#define RTCP_PT_BYE 203
-#define RTCP_PT_APP 204
-
-#define RTP_MTU 1200
-
-#define DEFAULT_DTMF_TIMEOUT 3000 /*!< samples */
-
-static int dtmftimeout = DEFAULT_DTMF_TIMEOUT;
-
-static int rtpstart; /*!< First port for RTP sessions (set in rtp.conf) */
-static int rtpend; /*!< Last port for RTP sessions (set in rtp.conf) */
-static int rtpdebug; /*!< Are we debugging? */
-static int rtcpdebug; /*!< Are we debugging RTCP? */
-static int rtcpstats; /*!< Are we debugging RTCP? */
-static int rtcpinterval = RTCP_DEFAULT_INTERVALMS; /*!< Time between rtcp reports in millisecs */
-static int stundebug; /*!< Are we debugging stun? */
-static struct sockaddr_in rtpdebugaddr; /*!< Debug packets to/from this host */
-static struct sockaddr_in rtcpdebugaddr; /*!< Debug RTCP packets to/from this host */
-#ifdef SO_NO_CHECK
-static int nochecksums;
-#endif
-
-/* Uncomment this to enable more intense native bridging, but note: this is currently buggy */
-/* #define P2P_INTENSE */
-
-/*!
- * \brief Structure representing a RTP session.
- *
- * RTP session is defined on page 9 of RFC 3550: "An association among a set of participants communicating with RTP. A participant may be involved in multiple RTP sessions at the same time [...]"
- *
- */
-/*! \brief The value of each payload format mapping: */
-struct rtpPayloadType {
- int isAstFormat; /*!< whether the following code is an AST_FORMAT */
- int code;
-};
-
-
-/*! \brief RTP session description */
-struct ast_rtp {
- int s;
- struct ast_frame f;
- unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
- unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */
- unsigned int themssrc; /*!< Their SSRC */
- unsigned int rxssrc;
- unsigned int lastts;
- unsigned int lastrxts;
- unsigned int lastividtimestamp;
- unsigned int lastovidtimestamp;
- unsigned int lasteventseqn;
- int lastrxseqno; /*!< Last received sequence number */
- unsigned short seedrxseqno; /*!< What sequence number did they start with?*/
- unsigned int seedrxts; /*!< What RTP timestamp did they start with? */
- unsigned int rxcount; /*!< How many packets have we received? */
- unsigned int rxoctetcount; /*!< How many octets have we received? should be rxcount *160*/
- unsigned int txcount; /*!< How many packets have we sent? */
- unsigned int txoctetcount; /*!< How many octets have we sent? (txcount*160)*/
- unsigned int cycles; /*!< Shifted count of sequence number cycles */
- double rxjitter; /*!< Interarrival jitter at the moment */
- double rxtransit; /*!< Relative transit time for previous packet */
- int lasttxformat;
- int lastrxformat;
-
- int rtptimeout; /*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
- int rtpholdtimeout; /*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
- int rtpkeepalive; /*!< Send RTP comfort noice packets for keepalive */
-
- /* DTMF Reception Variables */
- char resp;
- unsigned int lastevent;
- int dtmfcount;
- unsigned int dtmfsamples;
- /* DTMF Transmission Variables */
- unsigned int lastdigitts;
- char sending_digit; /*!< boolean - are we sending digits */
- char send_digit; /*!< digit we are sending */
- int send_payload;
- int send_duration;
- int nat;
- unsigned int flags;
- struct sockaddr_in us; /*!< Socket representation of the local endpoint. */
- struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */
- struct timeval rxcore;
- struct timeval txcore;
- double drxcore; /*!< The double representation of the first received packet */
- struct timeval lastrx; /*!< timeval when we last received a packet */
- struct timeval dtmfmute;
- struct ast_smoother *smoother;
- int *ioid;
- unsigned short seqno; /*!< Sequence number, RFC 3550, page 13. */
- unsigned short rxseqno;
- struct sched_context *sched;
- struct io_context *io;
- void *data;
- ast_rtp_callback callback;
- ast_mutex_t bridge_lock;
- struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
- int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */
- int rtp_lookup_code_cache_code;
- int rtp_lookup_code_cache_result;
- struct ast_rtcp *rtcp;
- struct ast_codec_pref pref;
- struct ast_rtp *bridged; /*!< Who we are Packet bridged to */
- int set_marker_bit:1; /*!< Whether to set the marker bit or not */
-};
-
-/* Forward declarations */
-static int ast_rtcp_write(const void *data);
-static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw);
-static int ast_rtcp_write_sr(const void *data);
-static int ast_rtcp_write_rr(const void *data);
-static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp);
-static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp);
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
-
-#define FLAG_3389_WARNING (1 << 0)
-#define FLAG_NAT_ACTIVE (3 << 1)
-#define FLAG_NAT_INACTIVE (0 << 1)
-#define FLAG_NAT_INACTIVE_NOWARN (1 << 1)
-#define FLAG_HAS_DTMF (1 << 3)
-#define FLAG_P2P_SENT_MARK (1 << 4)
-#define FLAG_P2P_NEED_DTMF (1 << 5)
-#define FLAG_CALLBACK_MODE (1 << 6)
-#define FLAG_DTMF_COMPENSATE (1 << 7)
-#define FLAG_HAS_STUN (1 << 8)
-
-/*!
- * \brief Structure defining an RTCP session.
- *
- * The concept "RTCP session" is not defined in RFC 3550, but since
- * this structure is analogous to ast_rtp, which tracks a RTP session,
- * it is logical to think of this as a RTCP session.
- *
- * RTCP packet is defined on page 9 of RFC 3550.
- *
- */
-struct ast_rtcp {
- int s; /*!< Socket */
- struct sockaddr_in us; /*!< Socket representation of the local endpoint. */
- struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */
- unsigned int soc; /*!< What they told us */
- unsigned int spc; /*!< What they told us */
- unsigned int themrxlsr; /*!< The middle 32 bits of the NTP timestamp in the last received SR*/
- struct timeval rxlsr; /*!< Time when we got their last SR */
- struct timeval txlsr; /*!< Time when we sent or last SR*/
- unsigned int expected_prior; /*!< no. packets in previous interval */
- unsigned int received_prior; /*!< no. packets received in previous interval */
- int schedid; /*!< Schedid returned from ast_sched_add() to schedule RTCP-transmissions*/
- unsigned int rr_count; /*!< number of RRs we've sent, not including report blocks in SR's */
- unsigned int sr_count; /*!< number of SRs we've sent */
- unsigned int lastsrtxcount; /*!< Transmit packet count when last SR sent */
- double accumulated_transit; /*!< accumulated a-dlsr-lsr */
- double rtt; /*!< Last reported rtt */
- unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */
- unsigned int reported_lost; /*!< Reported lost packets in their RR */
- char quality[AST_MAX_USER_FIELD];
- double maxrxjitter;
- double minrxjitter;
- double maxrtt;
- double minrtt;
- int sendfur;
-};
-
-
-typedef struct { unsigned int id[4]; } __attribute__((packed)) stun_trans_id;
-
-/* XXX Maybe stun belongs in another file if it ever has use outside of RTP */
-struct stun_header {
- unsigned short msgtype;
- unsigned short msglen;
- stun_trans_id id;
- unsigned char ies[0];
-} __attribute__((packed));
-
-struct stun_attr {
- unsigned short attr;
- unsigned short len;
- unsigned char value[0];
-} __attribute__((packed));
-
-struct stun_addr {
- unsigned char unused;
- unsigned char family;
- unsigned short port;
- unsigned int addr;
-} __attribute__((packed));
-
-#define STUN_IGNORE (0)
-#define STUN_ACCEPT (1)
-
-#define STUN_BINDREQ 0x0001
-#define STUN_BINDRESP 0x0101
-#define STUN_BINDERR 0x0111
-#define STUN_SECREQ 0x0002
-#define STUN_SECRESP 0x0102
-#define STUN_SECERR 0x0112
-
-#define STUN_MAPPED_ADDRESS 0x0001
-#define STUN_RESPONSE_ADDRESS 0x0002
-#define STUN_CHANGE_REQUEST 0x0003
-#define STUN_SOURCE_ADDRESS 0x0004
-#define STUN_CHANGED_ADDRESS 0x0005
-#define STUN_USERNAME 0x0006
-#define STUN_PASSWORD 0x0007
-#define STUN_MESSAGE_INTEGRITY 0x0008
-#define STUN_ERROR_CODE 0x0009
-#define STUN_UNKNOWN_ATTRIBUTES 0x000a
-#define STUN_REFLECTED_FROM 0x000b
-
-static const char *stun_msg2str(int msg)
-{
- switch(msg) {
- case STUN_BINDREQ:
- return "Binding Request";
- case STUN_BINDRESP:
- return "Binding Response";
- case STUN_BINDERR:
- return "Binding Error Response";
- case STUN_SECREQ:
- return "Shared Secret Request";
- case STUN_SECRESP:
- return "Shared Secret Response";
- case STUN_SECERR:
- return "Shared Secret Error Response";
- }
- return "Non-RFC3489 Message";
-}
-
-static const char *stun_attr2str(int msg)
-{
- switch(msg) {
- case STUN_MAPPED_ADDRESS:
- return "Mapped Address";
- case STUN_RESPONSE_ADDRESS:
- return "Response Address";
- case STUN_CHANGE_REQUEST:
- return "Change Request";
- case STUN_SOURCE_ADDRESS:
- return "Source Address";
- case STUN_CHANGED_ADDRESS:
- return "Changed Address";
- case STUN_USERNAME:
- return "Username";
- case STUN_PASSWORD:
- return "Password";
- case STUN_MESSAGE_INTEGRITY:
- return "Message Integrity";
- case STUN_ERROR_CODE:
- return "Error Code";
- case STUN_UNKNOWN_ATTRIBUTES:
- return "Unknown Attributes";
- case STUN_REFLECTED_FROM:
- return "Reflected From";
- }
- return "Non-RFC3489 Attribute";
-}
-
-struct stun_state {
- const char *username;
- const char *password;
-};
-
-static int stun_process_attr(struct stun_state *state, struct stun_attr *attr)
-{
- if (stundebug)
- ast_verbose("Found STUN Attribute %s (%04x), length %d\n",
- stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
- switch(ntohs(attr->attr)) {
- case STUN_USERNAME:
- state->username = (const char *) (attr->value);
- break;
- case STUN_PASSWORD:
- state->password = (const char *) (attr->value);
- break;
- default:
- if (stundebug)
- ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n",
- stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
- }
- return 0;
-}
-
-static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
-{
- int size = sizeof(**attr) + strlen(s);
- if (*left > size) {
- (*attr)->attr = htons(attrval);
- (*attr)->len = htons(strlen(s));
- memcpy((*attr)->value, s, strlen(s));
- (*attr) = (struct stun_attr *)((*attr)->value + strlen(s));
- *len += size;
- *left -= size;
- }
-}
-
-static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
-{
- int size = sizeof(**attr) + 8;
- struct stun_addr *addr;
- if (*left > size) {
- (*attr)->attr = htons(attrval);
- (*attr)->len = htons(8);
- addr = (struct stun_addr *)((*attr)->value);
- addr->unused = 0;
- addr->family = 0x01;
- addr->port = sin->sin_port;
- addr->addr = sin->sin_addr.s_addr;
- (*attr) = (struct stun_attr *)((*attr)->value + 8);
- *len += size;
- *left -= size;
- }
-}
-
-static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
-{
- return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0,
- (struct sockaddr *)dst, sizeof(*dst));
-}
-
-static void stun_req_id(struct stun_header *req)
-{
- int x;
- for (x=0;x<4;x++)
- req->id.id[x] = ast_random();
-}
-
-size_t ast_rtp_alloc_size(void)
-{
- return sizeof(struct ast_rtp);
-}
-
-void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username)
-{
- struct stun_header *req;
- unsigned char reqdata[1024];
- int reqlen, reqleft;
- struct stun_attr *attr;
-
- req = (struct stun_header *)reqdata;
- stun_req_id(req);
- reqlen = 0;
- reqleft = sizeof(reqdata) - sizeof(struct stun_header);
- req->msgtype = 0;
- req->msglen = 0;
- attr = (struct stun_attr *)req->ies;
- if (username)
- append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft);
- req->msglen = htons(reqlen);
- req->msgtype = htons(STUN_BINDREQ);
- stun_send(rtp->s, suggestion, req);
-}
-
-static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len)
-{
- struct stun_header *resp, *hdr = (struct stun_header *)data;
- struct stun_attr *attr;
- struct stun_state st;
- int ret = STUN_IGNORE;
- unsigned char respdata[1024];
- int resplen, respleft;
-
- if (len < sizeof(struct stun_header)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Runt STUN packet (only %zd, wanting at least %zd)\n", len, sizeof(struct stun_header));
- return -1;
- }
- if (stundebug)
- ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), ntohs(hdr->msglen));
- if (ntohs(hdr->msglen) > len - sizeof(struct stun_header)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Scrambled STUN packet length (got %d, expecting %zd)\n", ntohs(hdr->msglen), len - sizeof(struct stun_header));
- } else
- len = ntohs(hdr->msglen);
- data += sizeof(struct stun_header);
- memset(&st, 0, sizeof(st));
- while(len) {
- if (len < sizeof(struct stun_attr)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Runt Attribute (got %zd, expecting %zd)\n", len, sizeof(struct stun_attr));
- break;
- }
- attr = (struct stun_attr *)data;
- if ((ntohs(attr->len) + sizeof(struct stun_attr)) > len) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", (int) (ntohs(attr->len) + sizeof(struct stun_attr)), (int) len);
- break;
- }
- if (stun_process_attr(&st, attr)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr));
- break;
- }
- /* Clear attribute in case previous entry was a string */
- attr->attr = 0;
- data += ntohs(attr->len) + sizeof(struct stun_attr);
- len -= ntohs(attr->len) + sizeof(struct stun_attr);
- }
- /* Null terminate any string */
- *data = '\0';
- resp = (struct stun_header *)respdata;
- resplen = 0;
- respleft = sizeof(respdata) - sizeof(struct stun_header);
- resp->id = hdr->id;
- resp->msgtype = 0;
- resp->msglen = 0;
- attr = (struct stun_attr *)resp->ies;
- if (!len) {
- switch(ntohs(hdr->msgtype)) {
- case STUN_BINDREQ:
- if (stundebug)
- ast_verbose("STUN Bind Request, username: %s\n",
- st.username ? st.username : "<none>");
- if (st.username)
- append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft);
- append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft);
- resp->msglen = htons(resplen);
- resp->msgtype = htons(STUN_BINDRESP);
- stun_send(s, src, resp);
- ret = STUN_ACCEPT;
- break;
- default:
- if (stundebug)
- ast_verbose("Dunno what to do with STUN message %04x (%s)\n", ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype)));
- }
- }
- return ret;
-}
-
-/*! \brief List of current sessions */
-static AST_LIST_HEAD_STATIC(protos, ast_rtp_protocol);
-
-static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
-{
- unsigned int sec, usec, frac;
- sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */
- usec = tv.tv_usec;
- frac = (usec << 12) + (usec << 8) - ((usec * 3650) >> 6);
- *msw = sec;
- *lsw = frac;
-}
-
-int ast_rtp_fd(struct ast_rtp *rtp)
-{
- return rtp->s;
-}
-
-int ast_rtcp_fd(struct ast_rtp *rtp)
-{
- if (rtp->rtcp)
- return rtp->rtcp->s;
- return -1;
-}
-
-unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
-{
- unsigned int interval;
- /*! \todo XXX Do a more reasonable calculation on this one
- * Look in RFC 3550 Section A.7 for an example*/
- interval = rtcpinterval;
- return interval;
-}
-
-/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
-void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp)
-{
- rtp->rtptimeout = (-1) * rtp->rtptimeout;
- rtp->rtpholdtimeout = (-1) * rtp->rtpholdtimeout;
-}
-
-/*! \brief Set rtp timeout */
-void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout)
-{
- rtp->rtptimeout = timeout;
-}
-
-/*! \brief Set rtp hold timeout */
-void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout)
-{
- rtp->rtpholdtimeout = timeout;
-}
-
-/*! \brief set RTP keepalive interval */
-void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period)
-{
- rtp->rtpkeepalive = period;
-}
-
-/*! \brief Get rtp timeout */
-int ast_rtp_get_rtptimeout(struct ast_rtp *rtp)
-{
- if (rtp->rtptimeout < 0) /* We're not checking, but remembering the setting (during T.38 transmission) */
- return 0;
- return rtp->rtptimeout;
-}
-
-/*! \brief Get rtp hold timeout */
-int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp)
-{
- if (rtp->rtptimeout < 0) /* We're not checking, but remembering the setting (during T.38 transmission) */
- return 0;
- return rtp->rtpholdtimeout;
-}
-
-/*! \brief Get RTP keepalive interval */
-int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp)
-{
- return rtp->rtpkeepalive;
-}
-
-void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
-{
- rtp->data = data;
-}
-
-void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
-{
- rtp->callback = callback;
-}
-
-void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
-{
- rtp->nat = nat;
-}
-
-int ast_rtp_getnat(struct ast_rtp *rtp)
-{
- return ast_test_flag(rtp, FLAG_NAT_ACTIVE);
-}
-
-void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf)
-{
- ast_set2_flag(rtp, dtmf ? 1 : 0, FLAG_HAS_DTMF);
-}
-
-void ast_rtp_setdtmfcompensate(struct ast_rtp *rtp, int compensate)
-{
- ast_set2_flag(rtp, compensate ? 1 : 0, FLAG_DTMF_COMPENSATE);
-}
-
-void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable)
-{
- ast_set2_flag(rtp, stun_enable ? 1 : 0, FLAG_HAS_STUN);
-}
-
-static struct ast_frame *send_dtmf(struct ast_rtp *rtp, enum ast_frame_type type)
-{
- if (((ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && type == AST_FRAME_DTMF_END) ||
- (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(rtp->them.sin_addr));
- rtp->resp = 0;
- rtp->dtmfsamples = 0;
- return &ast_null_frame;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr));
- if (rtp->resp == 'X') {
- rtp->f.frametype = AST_FRAME_CONTROL;
- rtp->f.subclass = AST_CONTROL_FLASH;
- } else {
- rtp->f.frametype = type;
- rtp->f.subclass = rtp->resp;
- }
- rtp->f.datalen = 0;
- rtp->f.samples = 0;
- rtp->f.mallocd = 0;
- rtp->f.src = "RTP";
- return &rtp->f;
-
-}
-
-static inline int rtp_debug_test_addr(struct sockaddr_in *addr)
-{
- if (rtpdebug == 0)
- return 0;
- if (rtpdebugaddr.sin_addr.s_addr) {
- if (((ntohs(rtpdebugaddr.sin_port) != 0)
- && (rtpdebugaddr.sin_port != addr->sin_port))
- || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
-}
-
-static inline int rtcp_debug_test_addr(struct sockaddr_in *addr)
-{
- if (rtcpdebug == 0)
- return 0;
- if (rtcpdebugaddr.sin_addr.s_addr) {
- if (((ntohs(rtcpdebugaddr.sin_port) != 0)
- && (rtcpdebugaddr.sin_port != addr->sin_port))
- || (rtcpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
-}
-
-
-static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len)
-{
- unsigned int event;
- char resp = 0;
- struct ast_frame *f = NULL;
- event = ntohl(*((unsigned int *)(data)));
- event &= 0x001F;
- if (option_debug > 2 || rtpdebug)
- ast_log(LOG_DEBUG, "Cisco DTMF Digit: %08x (len = %d)\n", event, len);
- if (event < 10) {
- resp = '0' + event;
- } else if (event < 11) {
- resp = '*';
- } else if (event < 12) {
- resp = '#';
- } else if (event < 16) {
- resp = 'A' + (event - 12);
- } else if (event < 17) {
- resp = 'X';
- }
- if (rtp->resp && (rtp->resp != resp)) {
- f = send_dtmf(rtp, AST_FRAME_DTMF_END);
- }
- rtp->resp = resp;
- rtp->dtmfcount = dtmftimeout;
- return f;
-}
-
-/*!
- * \brief Process RTP DTMF and events according to RFC 2833.
- *
- * RFC 2833 is "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals".
- *
- * \param rtp
- * \param data
- * \param len
- * \param seqno
- * \returns
- */
-static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp)
-{
- unsigned int event;
- unsigned int event_end;
- unsigned int samples;
- char resp = 0;
- struct ast_frame *f = NULL;
-
- /* Figure out event, event end, and samples */
- event = ntohl(*((unsigned int *)(data)));
- event >>= 24;
- event_end = ntohl(*((unsigned int *)(data)));
- event_end <<= 8;
- event_end >>= 24;
- samples = ntohl(*((unsigned int *)(data)));
- samples &= 0xFFFF;
-
- /* Print out debug if turned on */
- if (rtpdebug || option_debug > 2)
- ast_log(LOG_DEBUG, "- RTP 2833 Event: %08x (len = %d)\n", event, len);
-
- /* Figure out what digit was pressed */
- if (event < 10) {
- resp = '0' + event;
- } else if (event < 11) {
- resp = '*';
- } else if (event < 12) {
- resp = '#';
- } else if (event < 16) {
- resp = 'A' + (event - 12);
- } else if (event < 17) { /* Event 16: Hook flash */
- resp = 'X';
- } else {
- /* Not a supported event */
- ast_log(LOG_DEBUG, "Ignoring RTP 2833 Event: %08x. Not a DTMF Digit.\n", event);
- return &ast_null_frame;
- }
-
- if (ast_test_flag(rtp, FLAG_DTMF_COMPENSATE)) {
- if ((rtp->lastevent != timestamp) || (rtp->resp && rtp->resp != resp)) {
- rtp->resp = resp;
- f = send_dtmf(rtp, AST_FRAME_DTMF_END);
- f->len = 0;
- rtp->lastevent = timestamp;
- }
- } else {
- if ((!(rtp->resp) && (!(event_end & 0x80))) || (rtp->resp && rtp->resp != resp)) {
- rtp->resp = resp;
- f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN);
- } else if ((event_end & 0x80) && (rtp->lastevent != seqno) && rtp->resp) {
- f = send_dtmf(rtp, AST_FRAME_DTMF_END);
- f->len = ast_tvdiff_ms(ast_samp2tv(samples, 8000), ast_tv(0, 0)); /* XXX hard coded 8kHz */
- rtp->resp = 0;
- rtp->lastevent = seqno;
- }
- }
-
- rtp->dtmfcount = dtmftimeout;
- rtp->dtmfsamples = samples;
-
- return f;
-}
-
-/*!
- * \brief Process Comfort Noise RTP.
- *
- * This is incomplete at the moment.
- *
-*/
-static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
-{
- struct ast_frame *f = NULL;
- /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't
- totally help us out becuase we don't have an engine to keep it going and we are not
- guaranteed to have it every 20ms or anything */
- if (rtpdebug)
- ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", rtp->lastrxformat, len);
-
- if (!(ast_test_flag(rtp, FLAG_3389_WARNING))) {
- ast_log(LOG_NOTICE, "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s\n",
- ast_inet_ntoa(rtp->them.sin_addr));
- ast_set_flag(rtp, FLAG_3389_WARNING);
- }
-
- /* Must have at least one byte */
- if (!len)
- return NULL;
- if (len < 24) {
- rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
- rtp->f.datalen = len - 1;
- rtp->f.offset = AST_FRIENDLY_OFFSET;
- memcpy(rtp->f.data, data + 1, len - 1);
- } else {
- rtp->f.data = NULL;
- rtp->f.offset = 0;
- rtp->f.datalen = 0;
- }
- rtp->f.frametype = AST_FRAME_CNG;
- rtp->f.subclass = data[0] & 0x7f;
- rtp->f.datalen = len - 1;
- rtp->f.samples = 0;
- rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
- f = &rtp->f;
- return f;
-}
-
-static int rtpread(int *id, int fd, short events, void *cbdata)
-{
- struct ast_rtp *rtp = cbdata;
- struct ast_frame *f;
- f = ast_rtp_read(rtp);
- if (f) {
- if (rtp->callback)
- rtp->callback(rtp, f, rtp->data);
- }
- return 1;
-}
-
-struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
-{
- socklen_t len;
- int position, i, packetwords;
- int res;
- struct sockaddr_in sin;
- unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET];
- unsigned int *rtcpheader;
- int pt;
- struct timeval now;
- unsigned int length;
- int rc;
- double rttsec;
- uint64_t rtt = 0;
- unsigned int dlsr;
- unsigned int lsr;
- unsigned int msw;
- unsigned int lsw;
- unsigned int comp;
- struct ast_frame *f = &ast_null_frame;
-
- if (!rtp || !rtp->rtcp)
- return &ast_null_frame;
-
- len = sizeof(sin);
-
- res = recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET,
- 0, (struct sockaddr *)&sin, &len);
- rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET);
-
- if (res < 0) {
- if (errno == EBADF)
- CRASH;
- if (errno != EAGAIN) {
- ast_log(LOG_WARNING, "RTCP Read error: %s. Hanging up.\n", strerror(errno));
- return NULL;
- }
- return &ast_null_frame;
- }
-
- packetwords = res / 4;
-
- if (rtp->nat) {
- /* Send to whoever sent to us */
- if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
- (rtp->rtcp->them.sin_port != sin.sin_port)) {
- memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them));
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
- }
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res);
-
- /* Process a compound packet */
- position = 0;
- while (position < packetwords) {
- i = position;
- length = ntohl(rtcpheader[i]);
- pt = (length & 0xff0000) >> 16;
- rc = (length & 0x1f000000) >> 24;
- length &= 0xffff;
-
- if ((i + length) > packetwords) {
- ast_log(LOG_WARNING, "RTCP Read too short\n");
- return &ast_null_frame;
- }
-
- if (rtcp_debug_test_addr(&sin)) {
- ast_verbose("\n\nGot RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- ast_verbose("PT: %d(%s)\n", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown");
- ast_verbose("Reception reports: %d\n", rc);
- ast_verbose("SSRC of sender: %u\n", rtcpheader[i + 1]);
- }
-
- i += 2; /* Advance past header and ssrc */
-
- switch (pt) {
- case RTCP_PT_SR:
- gettimeofday(&rtp->rtcp->rxlsr,NULL); /* To be able to populate the dlsr */
- rtp->rtcp->spc = ntohl(rtcpheader[i+3]);
- rtp->rtcp->soc = ntohl(rtcpheader[i + 4]);
- rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16); /* Going to LSR in RR*/
-
- if (rtcp_debug_test_addr(&sin)) {
- ast_verbose("NTP timestamp: %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[i]), (unsigned long) ntohl(rtcpheader[i + 1]) * 4096);
- ast_verbose("RTP timestamp: %lu\n", (unsigned long) ntohl(rtcpheader[i + 2]));
- ast_verbose("SPC: %lu\tSOC: %lu\n", (unsigned long) ntohl(rtcpheader[i + 3]), (unsigned long) ntohl(rtcpheader[i + 4]));
- }
- i += 5;
- if (rc < 1)
- break;
- /* Intentional fall through */
- case RTCP_PT_RR:
- /* Don't handle multiple reception reports (rc > 1) yet */
- /* Calculate RTT per RFC */
- gettimeofday(&now, NULL);
- timeval2ntp(now, &msw, &lsw);
- if (ntohl(rtcpheader[i + 4]) && ntohl(rtcpheader[i + 5])) { /* We must have the LSR && DLSR */
- comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16);
- lsr = ntohl(rtcpheader[i + 4]);
- dlsr = ntohl(rtcpheader[i + 5]);
- rtt = comp - lsr - dlsr;
-
- /* Convert end to end delay to usec (keeping the calculation in 64bit space)
- sess->ee_delay = (eedelay * 1000) / 65536; */
- if (rtt < 4294) {
- rtt = (rtt * 1000000) >> 16;
- } else {
- rtt = (rtt * 1000) >> 16;
- rtt *= 1000;
- }
- rtt = rtt / 1000.;
- rttsec = rtt / 1000.;
-
- if (comp - dlsr >= lsr) {
- rtp->rtcp->accumulated_transit += rttsec;
- rtp->rtcp->rtt = rttsec;
- if (rtp->rtcp->maxrtt<rttsec)
- rtp->rtcp->maxrtt = rttsec;
- if (rtp->rtcp->minrtt>rttsec)
- rtp->rtcp->minrtt = rttsec;
- } else if (rtcp_debug_test_addr(&sin)) {
- ast_verbose("Internal RTCP NTP clock skew detected: "
- "lsr=%u, now=%u, dlsr=%u (%d:%03dms), "
- "diff=%d\n",
- lsr, comp, dlsr, dlsr / 65536,
- (dlsr % 65536) * 1000 / 65536,
- dlsr - (comp - lsr));
- }
- }
-
- rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]);
- rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff;
- if (rtcp_debug_test_addr(&sin)) {
- ast_verbose(" Fraction lost: %ld\n", (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24));
- ast_verbose(" Packets lost so far: %d\n", rtp->rtcp->reported_lost);
- ast_verbose(" Highest sequence number: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff));
- ast_verbose(" Sequence number cycles: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff) >> 16);
- ast_verbose(" Interarrival jitter: %u\n", rtp->rtcp->reported_jitter);
- ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096);
- ast_verbose(" DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0);
- if (rtt)
- ast_verbose(" RTT: %lu(sec)\n", (unsigned long) rtt);
- }
- break;
- case RTCP_PT_FUR:
- if (rtcp_debug_test_addr(&sin))
- ast_verbose("Received an RTCP Fast Update Request\n");
- rtp->f.frametype = AST_FRAME_CONTROL;
- rtp->f.subclass = AST_CONTROL_VIDUPDATE;
- rtp->f.datalen = 0;
- rtp->f.samples = 0;
- rtp->f.mallocd = 0;
- rtp->f.src = "RTP";
- f = &rtp->f;
- break;
- case RTCP_PT_SDES:
- if (rtcp_debug_test_addr(&sin))
- ast_verbose("Received an SDES from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
- break;
- case RTCP_PT_BYE:
- if (rtcp_debug_test_addr(&sin))
- ast_verbose("Received a BYE from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Unknown RTCP packet (pt=%d) received from %s:%d\n", pt, ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
- break;
- }
- position += (length + 1);
- }
-
- return f;
-}
-
-static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
-{
- struct timeval now;
- double transit;
- double current_time;
- double d;
- double dtv;
- double prog;
-
- if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
- gettimeofday(&rtp->rxcore, NULL);
- rtp->drxcore = (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000;
- /* map timestamp to a real time */
- rtp->seedrxts = timestamp; /* Their RTP timestamp started with this */
- rtp->rxcore.tv_sec -= timestamp / 8000;
- rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
- /* Round to 0.1ms for nice, pretty timestamps */
- rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 100;
- if (rtp->rxcore.tv_usec < 0) {
- /* Adjust appropriately if necessary */
- rtp->rxcore.tv_usec += 1000000;
- rtp->rxcore.tv_sec -= 1;
- }
- }
-
- gettimeofday(&now,NULL);
- /* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */
- tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
- tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec += 1;
- }
- prog = (double)((timestamp-rtp->seedrxts)/8000.);
- dtv = (double)rtp->drxcore + (double)(prog);
- current_time = (double)now.tv_sec + (double)now.tv_usec/1000000;
- transit = current_time - dtv;
- d = transit - rtp->rxtransit;
- rtp->rxtransit = transit;
- if (d<0)
- d=-d;
- rtp->rxjitter += (1./16.) * (d - rtp->rxjitter);
- if (rtp->rtcp && rtp->rxjitter > rtp->rtcp->maxrxjitter)
- rtp->rtcp->maxrxjitter = rtp->rxjitter;
- if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter)
- rtp->rtcp->minrxjitter = rtp->rxjitter;
-}
-
-/*! \brief Perform a Packet2Packet RTP write */
-static int bridge_p2p_rtp_write(struct ast_rtp *rtp, struct ast_rtp *bridged, unsigned int *rtpheader, int len, int hdrlen)
-{
- int res = 0, payload = 0, bridged_payload = 0, mark;
- struct rtpPayloadType rtpPT;
- int reconstruct = ntohl(rtpheader[0]);
-
- /* Get fields from packet */
- payload = (reconstruct & 0x7f0000) >> 16;
- mark = (((reconstruct & 0x800000) >> 23) != 0);
-
- /* Check what the payload value should be */
- rtpPT = ast_rtp_lookup_pt(rtp, payload);
-
- /* If the payload coming in is not one of the negotiated ones then send it to the core, this will cause formats to change and the bridge to break */
- if (!bridged->current_RTP_PT[payload].code)
- return -1;
-
- /* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */
- if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && rtpPT.code == AST_RTP_DTMF)
- return -1;
-
- /* Otherwise adjust bridged payload to match */
- bridged_payload = ast_rtp_lookup_code(bridged, rtpPT.isAstFormat, rtpPT.code);
-
- /* If the mark bit has not been sent yet... do it now */
- if (!ast_test_flag(rtp, FLAG_P2P_SENT_MARK)) {
- mark = 1;
- ast_set_flag(rtp, FLAG_P2P_SENT_MARK);
- }
-
- /* Reconstruct part of the packet */
- reconstruct &= 0xFF80FFFF;
- reconstruct |= (bridged_payload << 16);
- reconstruct |= (mark << 23);
- rtpheader[0] = htonl(reconstruct);
-
- /* Send the packet back out */
- res = sendto(bridged->s, (void *)rtpheader, len, 0, (struct sockaddr *)&bridged->them, sizeof(bridged->them));
- if (res < 0) {
- if (!bridged->nat || (bridged->nat && (ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
- ast_log(LOG_DEBUG, "RTP Transmission error of packet to %s:%d: %s\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), strerror(errno));
- } else if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) {
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port));
- ast_set_flag(bridged, FLAG_NAT_INACTIVE_NOWARN);
- }
- return 0;
- } else if (rtp_debug_test_addr(&bridged->them))
- ast_verbose("Sent RTP P2P packet to %s:%u (type %-2.2d, len %-6.6u)\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), bridged_payload, len - hdrlen);
-
- return 0;
-}
-
-struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
-{
- int res;
- struct sockaddr_in sin;
- socklen_t len;
- unsigned int seqno;
- int version;
- int payloadtype;
- int hdrlen = 12;
- int padding;
- int mark;
- int ext;
- int cc;
- unsigned int ssrc;
- unsigned int timestamp;
- unsigned int *rtpheader;
- struct rtpPayloadType rtpPT;
- struct ast_rtp *bridged = NULL;
-
- /* If time is up, kill it */
- if (rtp->sending_digit)
- ast_rtp_senddigit_continuation(rtp);
-
- len = sizeof(sin);
-
- /* Cache where the header will go */
- res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
- 0, (struct sockaddr *)&sin, &len);
-
- rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
- if (res < 0) {
- if (errno == EBADF)
- CRASH;
- if (errno != EAGAIN) {
- ast_log(LOG_WARNING, "RTP Read error: %s. Hanging up.\n", strerror(errno));
- return NULL;
- }
- return &ast_null_frame;
- }
-
- if (res < hdrlen) {
- ast_log(LOG_WARNING, "RTP Read too short\n");
- return &ast_null_frame;
- }
-
- /* Get fields */
- seqno = ntohl(rtpheader[0]);
-
- /* Check RTP version */
- version = (seqno & 0xC0000000) >> 30;
- if (!version) {
- if ((stun_handle_packet(rtp->s, &sin, rtp->rawdata + AST_FRIENDLY_OFFSET, res) == STUN_ACCEPT) &&
- (!rtp->them.sin_port && !rtp->them.sin_addr.s_addr)) {
- memcpy(&rtp->them, &sin, sizeof(rtp->them));
- }
- return &ast_null_frame;
- }
-
-#if 0 /* Allow to receive RTP stream with closed transmission path */
- /* If we don't have the other side's address, then ignore this */
- if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
- return &ast_null_frame;
-#endif
-
- /* Send to whoever send to us if NAT is turned on */
- if (rtp->nat) {
- if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
- (rtp->them.sin_port != sin.sin_port)) {
- rtp->them = sin;
- if (rtp->rtcp) {
- memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them));
- rtp->rtcp->them.sin_port = htons(ntohs(rtp->them.sin_port)+1);
- }
- rtp->rxseqno = 0;
- ast_set_flag(rtp, FLAG_NAT_ACTIVE);
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
- }
- }
-
- /* If we are bridged to another RTP stream, send direct */
- if ((bridged = ast_rtp_get_bridged(rtp)) && !bridge_p2p_rtp_write(rtp, bridged, rtpheader, res, hdrlen))
- return &ast_null_frame;
-
- if (version != 2)
- return &ast_null_frame;
-
- payloadtype = (seqno & 0x7f0000) >> 16;
- padding = seqno & (1 << 29);
- mark = seqno & (1 << 23);
- ext = seqno & (1 << 28);
- cc = (seqno & 0xF000000) >> 24;
- seqno &= 0xffff;
- timestamp = ntohl(rtpheader[1]);
- ssrc = ntohl(rtpheader[2]);
-
- if (!mark && rtp->rxssrc && rtp->rxssrc != ssrc) {
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "Forcing Marker bit, because SSRC has changed\n");
- mark = 1;
- }
-
- rtp->rxssrc = ssrc;
-
- if (padding) {
- /* Remove padding bytes */
- res -= rtp->rawdata[AST_FRIENDLY_OFFSET + res - 1];
- }
-
- if (cc) {
- /* CSRC fields present */
- hdrlen += cc*4;
- }
-
- if (ext) {
- /* RTP Extension present */
- hdrlen += (ntohl(rtpheader[hdrlen/4]) & 0xffff) << 2;
- hdrlen += 4;
- }
-
- if (res < hdrlen) {
- ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
- return &ast_null_frame;
- }
-
- rtp->rxcount++; /* Only count reasonably valid packets, this'll make the rtcp stats more accurate */
-
- if (rtp->rxcount==1) {
- /* This is the first RTP packet successfully received from source */
- rtp->seedrxseqno = seqno;
- }
-
- /* Do not schedule RR if RTCP isn't run */
- if (rtp->rtcp && rtp->rtcp->them.sin_addr.s_addr && rtp->rtcp->schedid < 1) {
- /* Schedule transmission of Receiver Report */
- rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp);
- }
- if ( (int)rtp->lastrxseqno - (int)seqno > 100) /* if so it would indicate that the sender cycled; allow for misordering */
- rtp->cycles += RTP_SEQ_MOD;
-
- rtp->lastrxseqno = seqno;
-
- if (rtp->themssrc==0)
- rtp->themssrc = ntohl(rtpheader[2]); /* Record their SSRC to put in future RR */
-
- if (rtp_debug_test_addr(&sin))
- ast_verbose("Got RTP packet from %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
- ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
-
- rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
- if (!rtpPT.isAstFormat) {
- struct ast_frame *f = NULL;
-
- /* This is special in-band data that's not one of our codecs */
- if (rtpPT.code == AST_RTP_DTMF) {
- /* It's special -- rfc2833 process it */
- if (rtp_debug_test_addr(&sin)) {
- unsigned char *data;
- unsigned int event;
- unsigned int event_end;
- unsigned int duration;
- data = rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen;
- event = ntohl(*((unsigned int *)(data)));
- event >>= 24;
- event_end = ntohl(*((unsigned int *)(data)));
- event_end <<= 8;
- event_end >>= 24;
- duration = ntohl(*((unsigned int *)(data)));
- duration &= 0xFFFF;
- ast_verbose("Got RTP RFC2833 from %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d) \n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration);
- }
- f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp);
- } else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
- /* It's really special -- process it the Cisco way */
- if (rtp->lastevent <= seqno || (rtp->lastevent >= 65530 && seqno <= 6)) {
- f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
- rtp->lastevent = seqno;
- }
- } else if (rtpPT.code == AST_RTP_CN) {
- /* Comfort Noise */
- f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
- } else {
- ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n", payloadtype, ast_inet_ntoa(rtp->them.sin_addr));
- }
- return f ? f : &ast_null_frame;
- }
- rtp->lastrxformat = rtp->f.subclass = rtpPT.code;
- rtp->f.frametype = (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) ? AST_FRAME_VOICE : AST_FRAME_VIDEO;
-
- if (!rtp->lastrxts)
- rtp->lastrxts = timestamp;
-
- rtp->rxseqno = seqno;
-
- /* Record received timestamp as last received now */
- rtp->lastrxts = timestamp;
-
- rtp->f.mallocd = 0;
- rtp->f.datalen = res - hdrlen;
- rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
- rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
- rtp->f.seqno = seqno;
- if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) {
- rtp->f.samples = ast_codec_get_samples(&rtp->f);
- if (rtp->f.subclass == AST_FORMAT_SLINEAR)
- ast_frame_byteswap_be(&rtp->f);
- calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
- /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
- ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
- rtp->f.ts = timestamp / 8;
- rtp->f.len = rtp->f.samples / (ast_format_rate(rtp->f.subclass) / 1000);
- } else {
- /* Video -- samples is # of samples vs. 90000 */
- if (!rtp->lastividtimestamp)
- rtp->lastividtimestamp = timestamp;
- rtp->f.samples = timestamp - rtp->lastividtimestamp;
- rtp->lastividtimestamp = timestamp;
- rtp->f.delivery.tv_sec = 0;
- rtp->f.delivery.tv_usec = 0;
- if (mark)
- rtp->f.subclass |= 0x1;
-
- }
- rtp->f.src = "RTP";
- return &rtp->f;
-}
-
-/* The following array defines the MIME Media type (and subtype) for each
- of our codecs, or RTP-specific data type. */
-static struct {
- struct rtpPayloadType payloadType;
- char* type;
- char* subtype;
-} mimeTypes[] = {
- {{1, AST_FORMAT_G723_1}, "audio", "G723"},
- {{1, AST_FORMAT_GSM}, "audio", "GSM"},
- {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
- {{1, AST_FORMAT_ULAW}, "audio", "G711U"},
- {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
- {{1, AST_FORMAT_ALAW}, "audio", "G711A"},
- {{1, AST_FORMAT_G726}, "audio", "G726-32"},
- {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
- {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
- {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
- {{1, AST_FORMAT_G729A}, "audio", "G729"},
- {{1, AST_FORMAT_G729A}, "audio", "G729A"},
- {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
- {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
- {{1, AST_FORMAT_G722}, "audio", "G722"},
- {{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"},
- {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
- {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
- {{0, AST_RTP_CN}, "audio", "CN"},
- {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
- {{1, AST_FORMAT_PNG}, "video", "PNG"},
- {{1, AST_FORMAT_H261}, "video", "H261"},
- {{1, AST_FORMAT_H263}, "video", "H263"},
- {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"},
- {{1, AST_FORMAT_H264}, "video", "H264"},
-};
-
-/* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
- also, our own choices for dynamic payload types. This is our master
- table for transmission */
-static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
- [0] = {1, AST_FORMAT_ULAW},
-#ifdef USE_DEPRECATED_G726
- [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
-#endif
- [3] = {1, AST_FORMAT_GSM},
- [4] = {1, AST_FORMAT_G723_1},
- [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
- [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
- [7] = {1, AST_FORMAT_LPC10},
- [8] = {1, AST_FORMAT_ALAW},
- [9] = {1, AST_FORMAT_G722},
- [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
- [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
- [13] = {0, AST_RTP_CN},
- [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
- [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
- [18] = {1, AST_FORMAT_G729A},
- [19] = {0, AST_RTP_CN}, /* Also used for CN */
- [26] = {1, AST_FORMAT_JPEG},
- [31] = {1, AST_FORMAT_H261},
- [34] = {1, AST_FORMAT_H263},
- [103] = {1, AST_FORMAT_H263_PLUS},
- [97] = {1, AST_FORMAT_ILBC},
- [99] = {1, AST_FORMAT_H264},
- [101] = {0, AST_RTP_DTMF},
- [110] = {1, AST_FORMAT_SPEEX},
- [111] = {1, AST_FORMAT_G726},
- [112] = {1, AST_FORMAT_G726_AAL2},
- [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
-};
-
-void ast_rtp_pt_clear(struct ast_rtp* rtp)
-{
- int i;
-
- if (!rtp)
- return;
-
- ast_mutex_lock(&rtp->bridge_lock);
-
- for (i = 0; i < MAX_RTP_PT; ++i) {
- rtp->current_RTP_PT[i].isAstFormat = 0;
- rtp->current_RTP_PT[i].code = 0;
- }
-
- rtp->rtp_lookup_code_cache_isAstFormat = 0;
- rtp->rtp_lookup_code_cache_code = 0;
- rtp->rtp_lookup_code_cache_result = 0;
-
- ast_mutex_unlock(&rtp->bridge_lock);
-}
-
-void ast_rtp_pt_default(struct ast_rtp* rtp)
-{
- int i;
-
- ast_mutex_lock(&rtp->bridge_lock);
-
- /* Initialize to default payload types */
- for (i = 0; i < MAX_RTP_PT; ++i) {
- rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
- rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
- }
-
- rtp->rtp_lookup_code_cache_isAstFormat = 0;
- rtp->rtp_lookup_code_cache_code = 0;
- rtp->rtp_lookup_code_cache_result = 0;
-
- ast_mutex_unlock(&rtp->bridge_lock);
-}
-
-void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src)
-{
- unsigned int i;
-
- ast_mutex_lock(&dest->bridge_lock);
- ast_mutex_lock(&src->bridge_lock);
-
- for (i=0; i < MAX_RTP_PT; ++i) {
- dest->current_RTP_PT[i].isAstFormat =
- src->current_RTP_PT[i].isAstFormat;
- dest->current_RTP_PT[i].code =
- src->current_RTP_PT[i].code;
- }
- dest->rtp_lookup_code_cache_isAstFormat = 0;
- dest->rtp_lookup_code_cache_code = 0;
- dest->rtp_lookup_code_cache_result = 0;
-
- ast_mutex_unlock(&src->bridge_lock);
- ast_mutex_unlock(&dest->bridge_lock);
-}
-
-/*! \brief Get channel driver interface structure */
-static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
-{
- struct ast_rtp_protocol *cur = NULL;
-
- AST_LIST_LOCK(&protos);
- AST_LIST_TRAVERSE(&protos, cur, list) {
- if (cur->type == chan->tech->type)
- break;
- }
- AST_LIST_UNLOCK(&protos);
-
- return cur;
-}
-
-int ast_rtp_early_bridge(struct ast_channel *dest, struct ast_channel *src)
-{
- struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */
- struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */
- struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL;
- enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED;
- enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED;
- int srccodec, destcodec, nat_active = 0;
-
- /* Lock channels */
- ast_channel_lock(dest);
- if (src) {
- while(ast_channel_trylock(src)) {
- ast_channel_unlock(dest);
- usleep(1);
- ast_channel_lock(dest);
- }
- }
-
- /* Find channel driver interfaces */
- destpr = get_proto(dest);
- if (src)
- srcpr = get_proto(src);
- if (!destpr) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name);
- ast_channel_unlock(dest);
- if (src)
- ast_channel_unlock(src);
- return 0;
- }
- if (!srcpr) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src ? src->name : "<unspecified>");
- ast_channel_unlock(dest);
- if (src)
- ast_channel_unlock(src);
- return 0;
- }
-
- /* Get audio and video interface (if native bridge is possible) */
- audio_dest_res = destpr->get_rtp_info(dest, &destp);
- video_dest_res = destpr->get_vrtp_info ? destpr->get_vrtp_info(dest, &vdestp) : AST_RTP_GET_FAILED;
- if (srcpr) {
- audio_src_res = srcpr->get_rtp_info(src, &srcp);
- video_src_res = srcpr->get_vrtp_info ? srcpr->get_vrtp_info(src, &vsrcp) : AST_RTP_GET_FAILED;
- }
-
- /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */
- if (audio_dest_res != AST_RTP_TRY_NATIVE) {
- /* Somebody doesn't want to play... */
- ast_channel_unlock(dest);
- if (src)
- ast_channel_unlock(src);
- return 0;
- }
- if (audio_src_res == AST_RTP_TRY_NATIVE && srcpr->get_codec)
- srccodec = srcpr->get_codec(src);
- else
- srccodec = 0;
- if (audio_dest_res == AST_RTP_TRY_NATIVE && destpr->get_codec)
- destcodec = destpr->get_codec(dest);
- else
- destcodec = 0;
- /* Ensure we have at least one matching codec */
- if (!(srccodec & destcodec)) {
- ast_channel_unlock(dest);
- if (src)
- ast_channel_unlock(src);
- return 0;
- }
- /* Consider empty media as non-existant */
- if (audio_src_res == AST_RTP_TRY_NATIVE && !srcp->them.sin_addr.s_addr)
- srcp = NULL;
- /* If the client has NAT stuff turned on then just safe NAT is active */
- if (srcp && (srcp->nat || ast_test_flag(srcp, FLAG_NAT_ACTIVE)))
- nat_active = 1;
- /* Bridge media early */
- if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, nat_active))
- ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", dest->name, src ? src->name : "<unspecified>");
- ast_channel_unlock(dest);
- if (src)
- ast_channel_unlock(src);
- if (option_debug)
- ast_log(LOG_DEBUG, "Setting early bridge SDP of '%s' with that of '%s'\n", dest->name, src ? src->name : "<unspecified>");
- return 1;
-}
-
-int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media)
-{
- struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */
- struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */
- struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL;
- enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED;
- enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED;
- int srccodec, destcodec;
-
- /* Lock channels */
- ast_channel_lock(dest);
- while(ast_channel_trylock(src)) {
- ast_channel_unlock(dest);
- usleep(1);
- ast_channel_lock(dest);
- }
-
- /* Find channel driver interfaces */
- if (!(destpr = get_proto(dest))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name);
- ast_channel_unlock(dest);
- ast_channel_unlock(src);
- return 0;
- }
- if (!(srcpr = get_proto(src))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src->name);
- ast_channel_unlock(dest);
- ast_channel_unlock(src);
- return 0;
- }
-
- /* Get audio and video interface (if native bridge is possible) */
- audio_dest_res = destpr->get_rtp_info(dest, &destp);
- video_dest_res = destpr->get_vrtp_info ? destpr->get_vrtp_info(dest, &vdestp) : AST_RTP_GET_FAILED;
- audio_src_res = srcpr->get_rtp_info(src, &srcp);
- video_src_res = srcpr->get_vrtp_info ? srcpr->get_vrtp_info(src, &vsrcp) : AST_RTP_GET_FAILED;
-
- /* Ensure we have at least one matching codec */
- if (srcpr->get_codec)
- srccodec = srcpr->get_codec(src);
- else
- srccodec = 0;
- if (destpr->get_codec)
- destcodec = destpr->get_codec(dest);
- else
- destcodec = 0;
-
- /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */
- if (audio_dest_res != AST_RTP_TRY_NATIVE || audio_src_res != AST_RTP_TRY_NATIVE || !(srccodec & destcodec)) {
- /* Somebody doesn't want to play... */
- ast_channel_unlock(dest);
- ast_channel_unlock(src);
- return 0;
- }
- ast_rtp_pt_copy(destp, srcp);
- if (vdestp && vsrcp)
- ast_rtp_pt_copy(vdestp, vsrcp);
- if (media) {
- /* Bridge early */
- if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, ast_test_flag(srcp, FLAG_NAT_ACTIVE)))
- ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", dest->name, src->name);
- }
- ast_channel_unlock(dest);
- ast_channel_unlock(src);
- if (option_debug)
- ast_log(LOG_DEBUG, "Seeded SDP of '%s' with that of '%s'\n", dest->name, src->name);
- return 1;
-}
-
-/*! \brief Make a note of a RTP payload type that was seen in a SDP "m=" line.
- * By default, use the well-known value for this type (although it may
- * still be set to a different value by a subsequent "a=rtpmap:" line)
- */
-void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt)
-{
- if (pt < 0 || pt > MAX_RTP_PT || static_RTP_PT[pt].code == 0)
- return; /* bogus payload type */
-
- ast_mutex_lock(&rtp->bridge_lock);
- rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
- ast_mutex_unlock(&rtp->bridge_lock);
-}
-
-/*! \brief remove setting from payload type list if the rtpmap header indicates
- an unknown media type */
-void ast_rtp_unset_m_type(struct ast_rtp* rtp, int pt)
-{
- if (pt < 0 || pt > MAX_RTP_PT)
- return; /* bogus payload type */
-
- ast_mutex_lock(&rtp->bridge_lock);
- rtp->current_RTP_PT[pt].isAstFormat = 0;
- rtp->current_RTP_PT[pt].code = 0;
- ast_mutex_unlock(&rtp->bridge_lock);
-}
-
-/*! \brief Make a note of a RTP payload type (with MIME type) that was seen in
- * an SDP "a=rtpmap:" line.
- * \return 0 if the MIME type was found and set, -1 if it wasn't found
- */
-int ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt,
- char *mimeType, char *mimeSubtype,
- enum ast_rtp_options options)
-{
- unsigned int i;
- int found = 0;
-
- if (pt < 0 || pt > MAX_RTP_PT)
- return -1; /* bogus payload type */
-
- ast_mutex_lock(&rtp->bridge_lock);
-
- for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) {
- if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
- strcasecmp(mimeType, mimeTypes[i].type) == 0) {
- found = 1;
- rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
- if ((mimeTypes[i].payloadType.code == AST_FORMAT_G726) &&
- mimeTypes[i].payloadType.isAstFormat &&
- (options & AST_RTP_OPT_G726_NONSTANDARD))
- rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
- break;
- }
- }
-
- ast_mutex_unlock(&rtp->bridge_lock);
-
- return (found ? 0 : -1);
-}
-
-/*! \brief Return the union of all of the codecs that were set by rtp_set...() calls
- * They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
-void ast_rtp_get_current_formats(struct ast_rtp* rtp,
- int* astFormats, int* nonAstFormats)
-{
- int pt;
-
- ast_mutex_lock(&rtp->bridge_lock);
-
- *astFormats = *nonAstFormats = 0;
- for (pt = 0; pt < MAX_RTP_PT; ++pt) {
- if (rtp->current_RTP_PT[pt].isAstFormat) {
- *astFormats |= rtp->current_RTP_PT[pt].code;
- } else {
- *nonAstFormats |= rtp->current_RTP_PT[pt].code;
- }
- }
-
- ast_mutex_unlock(&rtp->bridge_lock);
-
- return;
-}
-
-struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt)
-{
- struct rtpPayloadType result;
-
- result.isAstFormat = result.code = 0;
-
- if (pt < 0 || pt > MAX_RTP_PT)
- return result; /* bogus payload type */
-
- /* Start with negotiated codecs */
- ast_mutex_lock(&rtp->bridge_lock);
- result = rtp->current_RTP_PT[pt];
- ast_mutex_unlock(&rtp->bridge_lock);
-
- /* If it doesn't exist, check our static RTP type list, just in case */
- if (!result.code)
- result = static_RTP_PT[pt];
-
- return result;
-}
-
-/*! \brief Looks up an RTP code out of our *static* outbound list */
-int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code)
-{
- int pt = 0;
-
- ast_mutex_lock(&rtp->bridge_lock);
-
- if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
- code == rtp->rtp_lookup_code_cache_code) {
- /* Use our cached mapping, to avoid the overhead of the loop below */
- pt = rtp->rtp_lookup_code_cache_result;
- ast_mutex_unlock(&rtp->bridge_lock);
- return pt;
- }
-
- /* Check the dynamic list first */
- for (pt = 0; pt < MAX_RTP_PT; ++pt) {
- if (rtp->current_RTP_PT[pt].code == code && rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
- rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
- rtp->rtp_lookup_code_cache_code = code;
- rtp->rtp_lookup_code_cache_result = pt;
- ast_mutex_unlock(&rtp->bridge_lock);
- return pt;
- }
- }
-
- /* Then the static list */
- for (pt = 0; pt < MAX_RTP_PT; ++pt) {
- if (static_RTP_PT[pt].code == code && static_RTP_PT[pt].isAstFormat == isAstFormat) {
- rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
- rtp->rtp_lookup_code_cache_code = code;
- rtp->rtp_lookup_code_cache_result = pt;
- ast_mutex_unlock(&rtp->bridge_lock);
- return pt;
- }
- }
-
- ast_mutex_unlock(&rtp->bridge_lock);
-
- return -1;
-}
-
-const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code,
- enum ast_rtp_options options)
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) {
- if ((mimeTypes[i].payloadType.code == code) && (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) {
- if (isAstFormat &&
- (code == AST_FORMAT_G726_AAL2) &&
- (options & AST_RTP_OPT_G726_NONSTANDARD))
- return "G726-32";
- else
- return mimeTypes[i].subtype;
- }
- }
-
- return "";
-}
-
-char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
- const int isAstFormat, enum ast_rtp_options options)
-{
- int format;
- unsigned len;
- char *end = buf;
- char *start = buf;
-
- if (!buf || !size)
- return NULL;
-
- snprintf(end, size, "0x%x (", capability);
-
- len = strlen(end);
- end += len;
- size -= len;
- start = end;
-
- for (format = 1; format < AST_RTP_MAX; format <<= 1) {
- if (capability & format) {
- const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format, options);
-
- snprintf(end, size, "%s|", name);
- len = strlen(end);
- end += len;
- size -= len;
- }
- }
-
- if (start == end)
- snprintf(start, size, "nothing)");
- else if (size > 1)
- *(end -1) = ')';
-
- return buf;
-}
-
-static int rtp_socket(void)
-{
- int s;
- long flags;
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s > -1) {
- flags = fcntl(s, F_GETFL);
- fcntl(s, F_SETFL, flags | O_NONBLOCK);
-#ifdef SO_NO_CHECK
- if (nochecksums)
- setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
-#endif
- }
- return s;
-}
-
-/*!
- * \brief Initialize a new RTCP session.
- *
- * \returns The newly initialized RTCP session.
- */
-static struct ast_rtcp *ast_rtcp_new(void)
-{
- struct ast_rtcp *rtcp;
-
- if (!(rtcp = ast_calloc(1, sizeof(*rtcp))))
- return NULL;
- rtcp->s = rtp_socket();
- rtcp->us.sin_family = AF_INET;
- rtcp->them.sin_family = AF_INET;
- rtcp->schedid = -1;
-
- if (rtcp->s < 0) {
- free(rtcp);
- ast_log(LOG_WARNING, "Unable to allocate RTCP socket: %s\n", strerror(errno));
- return NULL;
- }
-
- return rtcp;
-}
-
-/*!
- * \brief Initialize a new RTP structure.
- *
- */
-void ast_rtp_new_init(struct ast_rtp *rtp)
-{
- ast_mutex_init(&rtp->bridge_lock);
-
- rtp->them.sin_family = AF_INET;
- rtp->us.sin_family = AF_INET;
- rtp->ssrc = ast_random();
- rtp->seqno = ast_random() & 0xffff;
- ast_set_flag(rtp, FLAG_HAS_DTMF);
-
- return;
-}
-
-struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
-{
- struct ast_rtp *rtp;
- int x;
- int first;
- int startplace;
-
- if (!(rtp = ast_calloc(1, sizeof(*rtp))))
- return NULL;
-
- ast_rtp_new_init(rtp);
-
- rtp->s = rtp_socket();
- if (rtp->s < 0) {
- free(rtp);
- ast_log(LOG_ERROR, "Unable to allocate socket: %s\n", strerror(errno));
- return NULL;
- }
- if (sched && rtcpenable) {
- rtp->sched = sched;
- rtp->rtcp = ast_rtcp_new();
- }
-
- /* Select a random port number in the range of possible RTP */
- x = (ast_random() % (rtpend-rtpstart)) + rtpstart;
- x = x & ~1;
- /* Save it for future references. */
- startplace = x;
- /* Iterate tring to bind that port and incrementing it otherwise untill a port was found or no ports are available. */
- for (;;) {
- /* Must be an even port number by RTP spec */
- rtp->us.sin_port = htons(x);
- rtp->us.sin_addr = addr;
- /* If there's rtcp, initialize it as well. */
- if (rtp->rtcp) {
- rtp->rtcp->us.sin_port = htons(x + 1);
- rtp->rtcp->us.sin_addr = addr;
- }
- /* Try to bind it/them. */
- if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) &&
- (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
- break;
- if (!first) {
- /* Primary bind succeeded! Gotta recreate it */
- close(rtp->s);
- rtp->s = rtp_socket();
- }
- if (errno != EADDRINUSE) {
- /* We got an error that wasn't expected, abort! */
- ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno));
- close(rtp->s);
- if (rtp->rtcp) {
- close(rtp->rtcp->s);
- free(rtp->rtcp);
- }
- free(rtp);
- return NULL;
- }
- /* The port was used, increment it (by two). */
- x += 2;
- /* Did we go over the limit ? */
- if (x > rtpend)
- /* then, start from the begingig. */
- x = (rtpstart + 1) & ~1;
- /* Check if we reached the place were we started. */
- if (x == startplace) {
- /* If so, there's no ports available. */
- ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n");
- close(rtp->s);
- if (rtp->rtcp) {
- close(rtp->rtcp->s);
- free(rtp->rtcp);
- }
- free(rtp);
- return NULL;
- }
- }
- rtp->sched = sched;
- rtp->io = io;
- if (callbackmode) {
- rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
- ast_set_flag(rtp, FLAG_CALLBACK_MODE);
- }
- ast_rtp_pt_default(rtp);
- return rtp;
-}
-
-struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
-{
- struct in_addr ia;
-
- memset(&ia, 0, sizeof(ia));
- return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
-}
-
-int ast_rtp_settos(struct ast_rtp *rtp, int tos)
-{
- int res;
-
- if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))))
- ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
- return res;
-}
-
-void ast_rtp_new_source(struct ast_rtp *rtp)
-{
- rtp->set_marker_bit = 1;
- return;
-}
-
-void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
-{
- rtp->them.sin_port = them->sin_port;
- rtp->them.sin_addr = them->sin_addr;
- if (rtp->rtcp) {
- rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1);
- rtp->rtcp->them.sin_addr = them->sin_addr;
- }
- rtp->rxseqno = 0;
-}
-
-int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
-{
- if ((them->sin_family != AF_INET) ||
- (them->sin_port != rtp->them.sin_port) ||
- (them->sin_addr.s_addr != rtp->them.sin_addr.s_addr)) {
- them->sin_family = AF_INET;
- them->sin_port = rtp->them.sin_port;
- them->sin_addr = rtp->them.sin_addr;
- return 1;
- }
- return 0;
-}
-
-void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)
-{
- *us = rtp->us;
-}
-
-struct ast_rtp *ast_rtp_get_bridged(struct ast_rtp *rtp)
-{
- struct ast_rtp *bridged = NULL;
-
- ast_mutex_lock(&rtp->bridge_lock);
- bridged = rtp->bridged;
- ast_mutex_unlock(&rtp->bridge_lock);
-
- return bridged;
-}
-
-void ast_rtp_stop(struct ast_rtp *rtp)
-{
- AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
-
- memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
- memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port));
- if (rtp->rtcp) {
- memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->rtcp->them.sin_addr));
- memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->rtcp->them.sin_port));
- }
-
- ast_clear_flag(rtp, FLAG_P2P_SENT_MARK);
-}
-
-void ast_rtp_reset(struct ast_rtp *rtp)
-{
- memset(&rtp->rxcore, 0, sizeof(rtp->rxcore));
- memset(&rtp->txcore, 0, sizeof(rtp->txcore));
- memset(&rtp->dtmfmute, 0, sizeof(rtp->dtmfmute));
- rtp->lastts = 0;
- rtp->lastdigitts = 0;
- rtp->lastrxts = 0;
- rtp->lastividtimestamp = 0;
- rtp->lastovidtimestamp = 0;
- rtp->lasteventseqn = 0;
- rtp->lastevent = 0;
- rtp->lasttxformat = 0;
- rtp->lastrxformat = 0;
- rtp->dtmfcount = 0;
- rtp->dtmfsamples = 0;
- rtp->seqno = 0;
- rtp->rxseqno = 0;
-}
-
-char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual)
-{
- /*
- *ssrc our ssrc
- *themssrc their ssrc
- *lp lost packets
- *rxjitter our calculated jitter(rx)
- *rxcount no. received packets
- *txjitter reported jitter of the other end
- *txcount transmitted packets
- *rlp remote lost packets
- *rtt round trip time
- */
-
- if (qual && rtp) {
- qual->local_ssrc = rtp->ssrc;
- qual->local_jitter = rtp->rxjitter;
- qual->local_count = rtp->rxcount;
- qual->remote_ssrc = rtp->themssrc;
- qual->remote_count = rtp->txcount;
- if (rtp->rtcp) {
- qual->local_lostpackets = rtp->rtcp->expected_prior - rtp->rtcp->received_prior;
- qual->remote_lostpackets = rtp->rtcp->reported_lost;
- qual->remote_jitter = rtp->rtcp->reported_jitter / 65536.0;
- qual->rtt = rtp->rtcp->rtt;
- }
- }
- if (rtp->rtcp) {
- snprintf(rtp->rtcp->quality, sizeof(rtp->rtcp->quality),
- "ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f",
- rtp->ssrc,
- rtp->themssrc,
- rtp->rtcp->expected_prior - rtp->rtcp->received_prior,
- rtp->rxjitter,
- rtp->rxcount,
- (double)rtp->rtcp->reported_jitter / 65536.0,
- rtp->txcount,
- rtp->rtcp->reported_lost,
- rtp->rtcp->rtt);
- return rtp->rtcp->quality;
- } else
- return "<Unknown> - RTP/RTCP has already been destroyed";
-}
-
-void ast_rtp_destroy(struct ast_rtp *rtp)
-{
- if (rtcp_debug_test_addr(&rtp->them) || rtcpstats) {
- /*Print some info on the call here */
- ast_verbose(" RTP-stats\n");
- ast_verbose("* Our Receiver:\n");
- ast_verbose(" SSRC: %u\n", rtp->themssrc);
- ast_verbose(" Received packets: %u\n", rtp->rxcount);
- ast_verbose(" Lost packets: %u\n", rtp->rtcp->expected_prior - rtp->rtcp->received_prior);
- ast_verbose(" Jitter: %.4f\n", rtp->rxjitter);
- ast_verbose(" Transit: %.4f\n", rtp->rxtransit);
- ast_verbose(" RR-count: %u\n", rtp->rtcp->rr_count);
- ast_verbose("* Our Sender:\n");
- ast_verbose(" SSRC: %u\n", rtp->ssrc);
- ast_verbose(" Sent packets: %u\n", rtp->txcount);
- ast_verbose(" Lost packets: %u\n", rtp->rtcp->reported_lost);
- ast_verbose(" Jitter: %u\n", rtp->rtcp->reported_jitter / (unsigned int)65536.0);
- ast_verbose(" SR-count: %u\n", rtp->rtcp->sr_count);
- ast_verbose(" RTT: %f\n", rtp->rtcp->rtt);
- }
-
- if (rtp->smoother)
- ast_smoother_free(rtp->smoother);
- if (rtp->ioid)
- ast_io_remove(rtp->io, rtp->ioid);
- if (rtp->s > -1)
- close(rtp->s);
- if (rtp->rtcp) {
- AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
- close(rtp->rtcp->s);
- free(rtp->rtcp);
- rtp->rtcp=NULL;
- }
-
- ast_mutex_destroy(&rtp->bridge_lock);
-
- free(rtp);
-}
-
-static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
-{
- struct timeval t;
- long ms;
- if (ast_tvzero(rtp->txcore)) {
- rtp->txcore = ast_tvnow();
- /* Round to 20ms for nice, pretty timestamps */
- rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
- }
- /* Use previous txcore if available */
- t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
- ms = ast_tvdiff_ms(t, rtp->txcore);
- if (ms < 0)
- ms = 0;
- /* Use what we just got for next time */
- rtp->txcore = t;
- return (unsigned int) ms;
-}
-
-/*! \brief Send begin frames for DTMF */
-int ast_rtp_senddigit_begin(struct ast_rtp *rtp, char digit)
-{
- unsigned int *rtpheader;
- int hdrlen = 12, res = 0, i = 0, payload = 0;
- char data[256];
-
- if ((digit <= '9') && (digit >= '0'))
- digit -= '0';
- else if (digit == '*')
- digit = 10;
- else if (digit == '#')
- digit = 11;
- else if ((digit >= 'A') && (digit <= 'D'))
- digit = digit - 'A' + 12;
- else if ((digit >= 'a') && (digit <= 'd'))
- digit = digit - 'a' + 12;
- else {
- ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
- return 0;
- }
-
- /* If we have no peer, return immediately */
- if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
- return 0;
-
- payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
-
- rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
- rtp->send_duration = 160;
-
- /* Get a pointer to the header */
- rtpheader = (unsigned int *)data;
- rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
- rtpheader[1] = htonl(rtp->lastdigitts);
- rtpheader[2] = htonl(rtp->ssrc);
-
- for (i = 0; i < 2; i++) {
- rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
- res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them));
- if (res < 0)
- ast_log(LOG_ERROR, "RTP Transmission error to %s:%u: %s\n",
- ast_inet_ntoa(rtp->them.sin_addr),
- ntohs(rtp->them.sin_port), strerror(errno));
- if (rtp_debug_test_addr(&rtp->them))
- ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
- ast_inet_ntoa(rtp->them.sin_addr),
- ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
- /* Increment sequence number */
- rtp->seqno++;
- /* Increment duration */
- rtp->send_duration += 160;
- /* Clear marker bit and set seqno */
- rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
- }
-
- /* Since we received a begin, we can safely store the digit and disable any compensation */
- rtp->sending_digit = 1;
- rtp->send_digit = digit;
- rtp->send_payload = payload;
-
- return 0;
-}
-
-/*! \brief Send continuation frame for DTMF */
-static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp)
-{
- unsigned int *rtpheader;
- int hdrlen = 12, res = 0;
- char data[256];
-
- if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
- return 0;
-
- /* Setup packet to send */
- rtpheader = (unsigned int *)data;
- rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno));
- rtpheader[1] = htonl(rtp->lastdigitts);
- rtpheader[2] = htonl(rtp->ssrc);
- rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration));
- rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
-
- /* Transmit */
- res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them));
- if (res < 0)
- ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n",
- ast_inet_ntoa(rtp->them.sin_addr),
- ntohs(rtp->them.sin_port), strerror(errno));
- if (rtp_debug_test_addr(&rtp->them))
- ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
- ast_inet_ntoa(rtp->them.sin_addr),
- ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
-
- /* Increment sequence number */
- rtp->seqno++;
- /* Increment duration */
- rtp->send_duration += 160;
-
- return 0;
-}
-
-/*! \brief Send end packets for DTMF */
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit)
-{
- unsigned int *rtpheader;
- int hdrlen = 12, res = 0, i = 0;
- char data[256];
-
- /* If no address, then bail out */
- if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
- return 0;
-
- if ((digit <= '9') && (digit >= '0'))
- digit -= '0';
- else if (digit == '*')
- digit = 10;
- else if (digit == '#')
- digit = 11;
- else if ((digit >= 'A') && (digit <= 'D'))
- digit = digit - 'A' + 12;
- else if ((digit >= 'a') && (digit <= 'd'))
- digit = digit - 'a' + 12;
- else {
- ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
- return 0;
- }
-
- rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
-
- rtpheader = (unsigned int *)data;
- rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno));
- rtpheader[1] = htonl(rtp->lastdigitts);
- rtpheader[2] = htonl(rtp->ssrc);
- rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
- /* Set end bit */
- rtpheader[3] |= htonl((1 << 23));
- rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
- /* Send 3 termination packets */
- for (i = 0; i < 3; i++) {
- res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them));
- if (res < 0)
- ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n",
- ast_inet_ntoa(rtp->them.sin_addr),
- ntohs(rtp->them.sin_port), strerror(errno));
- if (rtp_debug_test_addr(&rtp->them))
- ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
- ast_inet_ntoa(rtp->them.sin_addr),
- ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
- }
- rtp->sending_digit = 0;
- rtp->send_digit = 0;
- /* Increment lastdigitts */
- rtp->lastdigitts += 960;
- rtp->seqno++;
-
- return res;
-}
-
-/*! \brief Public function: Send an H.261 fast update request, some devices need this rather than SIP XML */
-int ast_rtcp_send_h261fur(void *data)
-{
- struct ast_rtp *rtp = data;
- int res;
-
- rtp->rtcp->sendfur = 1;
- res = ast_rtcp_write(data);
-
- return res;
-}
-
-/*! \brief Send RTCP sender's report */
-static int ast_rtcp_write_sr(const void *data)
-{
- struct ast_rtp *rtp = (struct ast_rtp *)data;
- int res;
- int len = 0;
- struct timeval now;
- unsigned int now_lsw;
- unsigned int now_msw;
- unsigned int *rtcpheader;
- unsigned int lost;
- unsigned int extended;
- unsigned int expected;
- unsigned int expected_interval;
- unsigned int received_interval;
- int lost_interval;
- int fraction;
- struct timeval dlsr;
- char bdata[512];
-
- /* Commented condition is always not NULL if rtp->rtcp is not NULL */
- if (!rtp || !rtp->rtcp/* || (&rtp->rtcp->them.sin_addr == 0)*/)
- return 0;
-
- if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */
- ast_verbose("RTCP SR transmission error, rtcp halted\n");
- AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
- return 0;
- }
-
- gettimeofday(&now, NULL);
- timeval2ntp(now, &now_msw, &now_lsw); /* fill thses ones in from utils.c*/
- rtcpheader = (unsigned int *)bdata;
- rtcpheader[1] = htonl(rtp->ssrc); /* Our SSRC */
- rtcpheader[2] = htonl(now_msw); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970*/
- rtcpheader[3] = htonl(now_lsw); /* now, LSW */
- rtcpheader[4] = htonl(rtp->lastts); /* FIXME shouldn't be that, it should be now */
- rtcpheader[5] = htonl(rtp->txcount); /* No. packets sent */
- rtcpheader[6] = htonl(rtp->txoctetcount); /* No. bytes sent */
- len += 28;
-
- extended = rtp->cycles + rtp->lastrxseqno;
- expected = extended - rtp->seedrxseqno + 1;
- if (rtp->rxcount > expected)
- expected += rtp->rxcount - expected;
- lost = expected - rtp->rxcount;
- expected_interval = expected - rtp->rtcp->expected_prior;
- rtp->rtcp->expected_prior = expected;
- received_interval = rtp->rxcount - rtp->rtcp->received_prior;
- rtp->rtcp->received_prior = rtp->rxcount;
- lost_interval = expected_interval - received_interval;
- if (expected_interval == 0 || lost_interval <= 0)
- fraction = 0;
- else
- fraction = (lost_interval << 8) / expected_interval;
- timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
- rtcpheader[7] = htonl(rtp->themssrc);
- rtcpheader[8] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff));
- rtcpheader[9] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff)));
- rtcpheader[10] = htonl((unsigned int)(rtp->rxjitter * 65536.));
- rtcpheader[11] = htonl(rtp->rtcp->themrxlsr);
- rtcpheader[12] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000);
- len += 24;
-
- rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SR << 16) | ((len/4)-1));
-
- if (rtp->rtcp->sendfur) {
- rtcpheader[13] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1);
- rtcpheader[14] = htonl(rtp->ssrc); /* Our SSRC */
- len += 8;
- rtp->rtcp->sendfur = 0;
- }
-
- /* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */
- /* it can change mid call, and SDES can't) */
- rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2);
- rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */
- rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */
- len += 12;
-
- res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them));
- if (res < 0) {
- ast_log(LOG_ERROR, "RTCP SR transmission error to %s:%d, rtcp halted %s\n",ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), strerror(errno));
- AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
- return 0;
- }
-
- /* FIXME Don't need to get a new one */
- gettimeofday(&rtp->rtcp->txlsr, NULL);
- rtp->rtcp->sr_count++;
-
- rtp->rtcp->lastsrtxcount = rtp->txcount;
-
- if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
- ast_verbose("* Sent RTCP SR to %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
- ast_verbose(" Our SSRC: %u\n", rtp->ssrc);
- ast_verbose(" Sent(NTP): %u.%010u\n", (unsigned int)now.tv_sec, (unsigned int)now.tv_usec*4096);
- ast_verbose(" Sent(RTP): %u\n", rtp->lastts);
- ast_verbose(" Sent packets: %u\n", rtp->txcount);
- ast_verbose(" Sent octets: %u\n", rtp->txoctetcount);
- ast_verbose(" Report block:\n");
- ast_verbose(" Fraction lost: %u\n", fraction);
- ast_verbose(" Cumulative loss: %u\n", lost);
- ast_verbose(" IA jitter: %.4f\n", rtp->rxjitter);
- ast_verbose(" Their last SR: %u\n", rtp->rtcp->themrxlsr);
- ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(ntohl(rtcpheader[12])/65536.0));
- }
- return res;
-}
-
-/*! \brief Send RTCP recepient's report */
-static int ast_rtcp_write_rr(const void *data)
-{
- struct ast_rtp *rtp = (struct ast_rtp *)data;
- int res;
- int len = 32;
- unsigned int lost;
- unsigned int extended;
- unsigned int expected;
- unsigned int expected_interval;
- unsigned int received_interval;
- int lost_interval;
- struct timeval now;
- unsigned int *rtcpheader;
- char bdata[1024];
- struct timeval dlsr;
- int fraction;
-
- if (!rtp || !rtp->rtcp || (&rtp->rtcp->them.sin_addr == 0))
- return 0;
-
- if (!rtp->rtcp->them.sin_addr.s_addr) {
- ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted\n");
- AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
- return 0;
- }
-
- extended = rtp->cycles + rtp->lastrxseqno;
- expected = extended - rtp->seedrxseqno + 1;
- lost = expected - rtp->rxcount;
- expected_interval = expected - rtp->rtcp->expected_prior;
- rtp->rtcp->expected_prior = expected;
- received_interval = rtp->rxcount - rtp->rtcp->received_prior;
- rtp->rtcp->received_prior = rtp->rxcount;
- lost_interval = expected_interval - received_interval;
- if (expected_interval == 0 || lost_interval <= 0)
- fraction = 0;
- else
- fraction = (lost_interval << 8) / expected_interval;
- gettimeofday(&now, NULL);
- timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
- rtcpheader = (unsigned int *)bdata;
- rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_RR << 16) | ((len/4)-1));
- rtcpheader[1] = htonl(rtp->ssrc);
- rtcpheader[2] = htonl(rtp->themssrc);
- rtcpheader[3] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff));
- rtcpheader[4] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff)));
- rtcpheader[5] = htonl((unsigned int)(rtp->rxjitter * 65536.));
- rtcpheader[6] = htonl(rtp->rtcp->themrxlsr);
- rtcpheader[7] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000);
-
- if (rtp->rtcp->sendfur) {
- rtcpheader[8] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1); /* Header from page 36 in RFC 3550 */
- rtcpheader[9] = htonl(rtp->ssrc); /* Our SSRC */
- len += 8;
- rtp->rtcp->sendfur = 0;
- }
-
- /*! \note Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos
- it can change mid call, and SDES can't) */
- rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2);
- rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */
- rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */
- len += 12;
-
- res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them));
-
- if (res < 0) {
- ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n",strerror(errno));
- /* Remove the scheduler */
- AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
- return 0;
- }
-
- rtp->rtcp->rr_count++;
-
- if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
- ast_verbose("\n* Sending RTCP RR to %s:%d\n"
- " Our SSRC: %u\nTheir SSRC: %u\niFraction lost: %d\nCumulative loss: %u\n"
- " IA jitter: %.4f\n"
- " Their last SR: %u\n"
- " DLSR: %4.4f (sec)\n\n",
- ast_inet_ntoa(rtp->rtcp->them.sin_addr),
- ntohs(rtp->rtcp->them.sin_port),
- rtp->ssrc, rtp->themssrc, fraction, lost,
- rtp->rxjitter,
- rtp->rtcp->themrxlsr,
- (double)(ntohl(rtcpheader[7])/65536.0));
- }
-
- return res;
-}
-
-/*! \brief Write and RTCP packet to the far end
- * \note Decide if we are going to send an SR (with Reception Block) or RR
- * RR is sent if we have not sent any rtp packets in the previous interval */
-static int ast_rtcp_write(const void *data)
-{
- struct ast_rtp *rtp = (struct ast_rtp *)data;
- int res;
-
- if (!rtp || !rtp->rtcp)
- return 0;
-
- if (rtp->txcount > rtp->rtcp->lastsrtxcount)
- res = ast_rtcp_write_sr(data);
- else
- res = ast_rtcp_write_rr(data);
-
- return res;
-}
-
-/*! \brief generate comfort noice (CNG) */
-int ast_rtp_sendcng(struct ast_rtp *rtp, int level)
-{
- unsigned int *rtpheader;
- int hdrlen = 12;
- int res;
- int payload;
- char data[256];
- level = 127 - (level & 0x7f);
- payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN);
-
- /* If we have no peer, return immediately */
- if (!rtp->them.sin_addr.s_addr)
- return 0;
-
- rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
-
- /* Get a pointer to the header */
- rtpheader = (unsigned int *)data;
- rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
- rtpheader[1] = htonl(rtp->lastts);
- rtpheader[2] = htonl(rtp->ssrc);
- data[12] = level;
- if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
- res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
- if (res <0)
- ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
- if (rtp_debug_test_addr(&rtp->them))
- ast_verbose("Sent Comfort Noise RTP packet to %s:%u (type %d, seq %u, ts %u, len %d)\n"
- , ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen);
-
- }
- return 0;
-}
-
-static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
-{
- unsigned char *rtpheader;
- int hdrlen = 12;
- int res;
- unsigned int ms;
- int pred;
- int mark = 0;
-
- ms = calc_txstamp(rtp, &f->delivery);
- /* Default prediction */
- if (f->frametype == AST_FRAME_VOICE) {
- pred = rtp->lastts + f->samples;
-
- /* Re-calculate last TS */
- rtp->lastts = rtp->lastts + ms * 8;
- if (ast_tvzero(f->delivery)) {
- /* If this isn't an absolute delivery time, Check if it is close to our prediction,
- and if so, go with our prediction */
- if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
- rtp->lastts = pred;
- else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
- mark = 1;
- }
- }
- } else if (f->frametype == AST_FRAME_VIDEO) {
- mark = f->subclass & 0x1;
- pred = rtp->lastovidtimestamp + f->samples;
- /* Re-calculate last TS */
- rtp->lastts = rtp->lastts + ms * 90;
- /* If it's close to our prediction, go for it */
- if (ast_tvzero(f->delivery)) {
- if (abs(rtp->lastts - pred) < 7200) {
- rtp->lastts = pred;
- rtp->lastovidtimestamp += f->samples;
- } else {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Difference is %d, ms is %d (%d), pred/ts/samples %d/%d/%d\n", abs(rtp->lastts - pred), ms, ms * 90, rtp->lastts, pred, f->samples);
- rtp->lastovidtimestamp = rtp->lastts;
- }
- }
- }
-
- /* If we have been explicitly told to set the marker bit do so */
- if (rtp->set_marker_bit) {
- mark = 1;
- rtp->set_marker_bit = 0;
- }
-
- /* If the timestamp for non-digit packets has moved beyond the timestamp
- for digits, update the digit timestamp.
- */
- if (rtp->lastts > rtp->lastdigitts)
- rtp->lastdigitts = rtp->lastts;
-
- if (ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO))
- rtp->lastts = f->ts * 8;
-
- /* Get a pointer to the header */
- rtpheader = (unsigned char *)(f->data - hdrlen);
-
- put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
- put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts));
- put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc));
-
- if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
- res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
- if (res <0) {
- if (!rtp->nat || (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
- ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n", rtp->seqno, ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
- } else if (((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(rtp, FLAG_NAT_INACTIVE_NOWARN)) {
- /* Only give this error message once if we are not RTP debugging */
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
- ast_set_flag(rtp, FLAG_NAT_INACTIVE_NOWARN);
- }
- } else {
- rtp->txcount++;
- rtp->txoctetcount +=(res - hdrlen);
-
- if (rtp->rtcp && rtp->rtcp->schedid < 1)
- rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp);
- }
-
- if (rtp_debug_test_addr(&rtp->them))
- ast_verbose("Sent RTP packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
- ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen);
- }
-
- rtp->seqno++;
-
- return 0;
-}
-
-int ast_rtp_codec_setpref(struct ast_rtp *rtp, struct ast_codec_pref *prefs)
-{
- int x;
- for (x = 0; x < 32; x++) { /* Ugly way */
- rtp->pref.order[x] = prefs->order[x];
- rtp->pref.framing[x] = prefs->framing[x];
- }
- if (rtp->smoother)
- ast_smoother_free(rtp->smoother);
- rtp->smoother = NULL;
- return 0;
-}
-
-struct ast_codec_pref *ast_rtp_codec_getpref(struct ast_rtp *rtp)
-{
- return &rtp->pref;
-}
-
-int ast_rtp_codec_getformat(int pt)
-{
- if (pt < 0 || pt > MAX_RTP_PT)
- return 0; /* bogus payload type */
-
- if (static_RTP_PT[pt].isAstFormat)
- return static_RTP_PT[pt].code;
- else
- return 0;
-}
-
-int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
-{
- struct ast_frame *f;
- int codec;
- int hdrlen = 12;
- int subclass;
-
-
- /* If we have no peer, return immediately */
- if (!rtp->them.sin_addr.s_addr)
- return 0;
-
- /* If there is no data length, return immediately */
- if (!_f->datalen)
- return 0;
-
- /* Make sure we have enough space for RTP header */
- if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) {
- ast_log(LOG_WARNING, "RTP can only send voice and video\n");
- return -1;
- }
-
- subclass = _f->subclass;
- if (_f->frametype == AST_FRAME_VIDEO)
- subclass &= ~0x1;
-
- codec = ast_rtp_lookup_code(rtp, 1, subclass);
- if (codec < 0) {
- ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass));
- return -1;
- }
-
- if (rtp->lasttxformat != subclass) {
- /* New format, reset the smoother */
- if (option_debug)
- ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
- rtp->lasttxformat = subclass;
- if (rtp->smoother)
- ast_smoother_free(rtp->smoother);
- rtp->smoother = NULL;
- }
-
- if (!rtp->smoother && subclass != AST_FORMAT_SPEEX && subclass != AST_FORMAT_G723_1) {
- struct ast_format_list fmt = ast_codec_pref_getsize(&rtp->pref, subclass);
- if (fmt.inc_ms) { /* if codec parameters is set / avoid division by zero */
- if (!(rtp->smoother = ast_smoother_new((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms))) {
- ast_log(LOG_WARNING, "Unable to create smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
- return -1;
- }
- if (fmt.flags)
- ast_smoother_set_flags(rtp->smoother, fmt.flags);
- if (option_debug)
- ast_log(LOG_DEBUG, "Created smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
- }
- }
- if (rtp->smoother) {
- if (ast_smoother_test_flag(rtp->smoother, AST_SMOOTHER_FLAG_BE)) {
- ast_smoother_feed_be(rtp->smoother, _f);
- } else {
- ast_smoother_feed(rtp->smoother, _f);
- }
-
- while ((f = ast_smoother_read(rtp->smoother)) && (f->data)) {
- if (f->subclass == AST_FORMAT_G722) {
- /* G.722 is silllllllllllllly */
- f->samples /= 2;
- }
-
- ast_rtp_raw_write(rtp, f, codec);
- }
- } else {
- /* Don't buffer outgoing frames; send them one-per-packet: */
- if (_f->offset < hdrlen) {
- f = ast_frdup(_f);
- } else {
- f = _f;
- }
- if (f->data) {
- if (f->subclass == AST_FORMAT_G722) {
- /* G.722 is silllllllllllllly */
- f->samples /= 2;
- }
- ast_rtp_raw_write(rtp, f, codec);
- }
- if (f != _f)
- ast_frfree(f);
- }
-
- return 0;
-}
-
-/*! \brief Unregister interface to channel driver */
-void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
-{
- AST_LIST_LOCK(&protos);
- AST_LIST_REMOVE(&protos, proto, list);
- AST_LIST_UNLOCK(&protos);
-}
-
-/*! \brief Register interface to channel driver */
-int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
-{
- struct ast_rtp_protocol *cur;
-
- AST_LIST_LOCK(&protos);
- AST_LIST_TRAVERSE(&protos, cur, list) {
- if (!strcmp(cur->type, proto->type)) {
- ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
- AST_LIST_UNLOCK(&protos);
- return -1;
- }
- }
- AST_LIST_INSERT_HEAD(&protos, proto, list);
- AST_LIST_UNLOCK(&protos);
-
- return 0;
-}
-
-/*! \brief Bridge loop for true native bridge (reinvite) */
-static enum ast_bridge_result bridge_native_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, struct ast_rtp *vp0, struct ast_rtp *vp1, struct ast_rtp_protocol *pr0, struct ast_rtp_protocol *pr1, int codec0, int codec1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
-{
- struct ast_frame *fr = NULL;
- struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, };
- int oldcodec0 = codec0, oldcodec1 = codec1;
- struct sockaddr_in ac1 = {0,}, vac1 = {0,}, ac0 = {0,}, vac0 = {0,};
- struct sockaddr_in t1 = {0,}, vt1 = {0,}, t0 = {0,}, vt0 = {0,};
-
- /* Set it up so audio goes directly between the two endpoints */
-
- /* Test the first channel */
- if (!(pr0->set_rtp_peer(c0, p1, vp1, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE)))) {
- ast_rtp_get_peer(p1, &ac1);
- if (vp1)
- ast_rtp_get_peer(vp1, &vac1);
- } else
- ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
-
- /* Test the second channel */
- if (!(pr1->set_rtp_peer(c1, p0, vp0, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE)))) {
- ast_rtp_get_peer(p0, &ac0);
- if (vp0)
- ast_rtp_get_peer(vp0, &vac0);
- } else
- ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c1->name, c0->name);
-
- /* Now we can unlock and move into our loop */
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
-
- /* Throw our channels into the structure and enter the loop */
- cs[0] = c0;
- cs[1] = c1;
- cs[2] = NULL;
- for (;;) {
- /* Check if anything changed */
- if ((c0->tech_pvt != pvt0) ||
- (c1->tech_pvt != pvt1) ||
- (c0->masq || c0->masqr || c1->masq || c1->masqr) ||
- (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks)) {
- ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
- if (c0->tech_pvt == pvt0)
- if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
- if (c1->tech_pvt == pvt1)
- if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
- return AST_BRIDGE_RETRY;
- }
-
- /* Check if they have changed their address */
- ast_rtp_get_peer(p1, &t1);
- if (vp1)
- ast_rtp_get_peer(vp1, &vt1);
- if (pr1->get_codec)
- codec1 = pr1->get_codec(c1);
- ast_rtp_get_peer(p0, &t0);
- if (vp0)
- ast_rtp_get_peer(vp0, &vt0);
- if (pr0->get_codec)
- codec0 = pr0->get_codec(c0);
- if ((inaddrcmp(&t1, &ac1)) ||
- (vp1 && inaddrcmp(&vt1, &vac1)) ||
- (codec1 != oldcodec1)) {
- if (option_debug > 1) {
- ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
- c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), codec1);
- ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n",
- c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), codec1);
- ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n",
- c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
- ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n",
- c1->name, ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
- }
- if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE)))
- ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
- memcpy(&ac1, &t1, sizeof(ac1));
- memcpy(&vac1, &vt1, sizeof(vac1));
- oldcodec1 = codec1;
- }
- if ((inaddrcmp(&t0, &ac0)) ||
- (vp0 && inaddrcmp(&vt0, &vac0))) {
- if (option_debug > 1) {
- ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
- c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), codec0);
- ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n",
- c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
- }
- if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE)))
- ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
- memcpy(&ac0, &t0, sizeof(ac0));
- memcpy(&vac0, &vt0, sizeof(vac0));
- oldcodec0 = codec0;
- }
-
- /* Wait for frame to come in on the channels */
- if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
- if (!timeoutms) {
- if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
- if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
- return AST_BRIDGE_RETRY;
- }
- if (option_debug)
- ast_log(LOG_DEBUG, "Ooh, empty read...\n");
- if (ast_check_hangup(c0) || ast_check_hangup(c1))
- break;
- continue;
- }
- fr = ast_read(who);
- other = (who == c0) ? c1 : c0;
- if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
- (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
- ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
- /* Break out of bridge */
- *fo = fr;
- *rc = who;
- if (option_debug)
- ast_log(LOG_DEBUG, "Oooh, got a %s\n", fr ? "digit" : "hangup");
- if (c0->tech_pvt == pvt0)
- if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
- if (c1->tech_pvt == pvt1)
- if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
- return AST_BRIDGE_COMPLETE;
- } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
- if ((fr->subclass == AST_CONTROL_HOLD) ||
- (fr->subclass == AST_CONTROL_UNHOLD) ||
- (fr->subclass == AST_CONTROL_VIDUPDATE) ||
- (fr->subclass == AST_CONTROL_SRCUPDATE)) {
- if (fr->subclass == AST_CONTROL_HOLD) {
- /* If we someone went on hold we want the other side to reinvite back to us */
- if (who == c0)
- pr1->set_rtp_peer(c1, NULL, NULL, 0, 0);
- else
- pr0->set_rtp_peer(c0, NULL, NULL, 0, 0);
- } else if (fr->subclass == AST_CONTROL_UNHOLD) {
- /* If they went off hold they should go back to being direct */
- if (who == c0)
- pr1->set_rtp_peer(c1, p0, vp0, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE));
- else
- pr0->set_rtp_peer(c0, p1, vp1, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE));
- }
- /* Update local address information */
- ast_rtp_get_peer(p0, &t0);
- memcpy(&ac0, &t0, sizeof(ac0));
- ast_rtp_get_peer(p1, &t1);
- memcpy(&ac1, &t1, sizeof(ac1));
- /* Update codec information */
- if (pr0->get_codec && c0->tech_pvt)
- oldcodec0 = codec0 = pr0->get_codec(c0);
- if (pr1->get_codec && c1->tech_pvt)
- oldcodec1 = codec1 = pr1->get_codec(c1);
- ast_indicate_data(other, fr->subclass, fr->data, fr->datalen);
- ast_frfree(fr);
- } else {
- *fo = fr;
- *rc = who;
- ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name);
- return AST_BRIDGE_COMPLETE;
- }
- } else {
- if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
- (fr->frametype == AST_FRAME_DTMF_END) ||
- (fr->frametype == AST_FRAME_VOICE) ||
- (fr->frametype == AST_FRAME_VIDEO) ||
- (fr->frametype == AST_FRAME_IMAGE) ||
- (fr->frametype == AST_FRAME_HTML) ||
- (fr->frametype == AST_FRAME_MODEM) ||
- (fr->frametype == AST_FRAME_TEXT)) {
- ast_write(other, fr);
- }
- ast_frfree(fr);
- }
- /* Swap priority */
- cs[2] = cs[0];
- cs[0] = cs[1];
- cs[1] = cs[2];
- }
-
- if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
- if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0))
- ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
-
- return AST_BRIDGE_FAILED;
-}
-
-/*! \brief P2P RTP Callback */
-#ifdef P2P_INTENSE
-static int p2p_rtp_callback(int *id, int fd, short events, void *cbdata)
-{
- int res = 0, hdrlen = 12;
- struct sockaddr_in sin;
- socklen_t len;
- unsigned int *header;
- struct ast_rtp *rtp = cbdata, *bridged = NULL;
-
- if (!rtp)
- return 1;
-
- len = sizeof(sin);
- if ((res = recvfrom(fd, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0, (struct sockaddr *)&sin, &len)) < 0)
- return 1;
-
- header = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
-
- /* If NAT support is turned on, then see if we need to change their address */
- if ((rtp->nat) &&
- ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
- (rtp->them.sin_port != sin.sin_port))) {
- rtp->them = sin;
- rtp->rxseqno = 0;
- ast_set_flag(rtp, FLAG_NAT_ACTIVE);
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "P2P RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
- }
-
- /* Write directly out to other RTP stream if bridged */
- if ((bridged = ast_rtp_get_bridged(rtp)))
- bridge_p2p_rtp_write(rtp, bridged, header, res, hdrlen);
-
- return 1;
-}
-
-/*! \brief Helper function to switch a channel and RTP stream into callback mode */
-static int p2p_callback_enable(struct ast_channel *chan, struct ast_rtp *rtp, int *fds, int **iod)
-{
- /* If we need DTMF, are looking for STUN, or we have no IO structure then we can't do direct callback */
- if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) || ast_test_flag(rtp, FLAG_HAS_STUN) || !rtp->io)
- return 0;
-
- /* If the RTP structure is already in callback mode, remove it temporarily */
- if (rtp->ioid) {
- ast_io_remove(rtp->io, rtp->ioid);
- rtp->ioid = NULL;
- }
-
- /* Steal the file descriptors from the channel and stash them away */
- fds[0] = chan->fds[0];
- chan->fds[0] = -1;
-
- /* Now, fire up callback mode */
- iod[0] = ast_io_add(rtp->io, fds[0], p2p_rtp_callback, AST_IO_IN, rtp);
-
- return 1;
-}
-#else
-static int p2p_callback_enable(struct ast_channel *chan, struct ast_rtp *rtp, int *fds, int **iod)
-{
- return 0;
-}
-#endif
-
-/*! \brief Helper function to switch a channel and RTP stream out of callback mode */
-static int p2p_callback_disable(struct ast_channel *chan, struct ast_rtp *rtp, int *fds, int **iod)
-{
- ast_channel_lock(chan);
-
- /* Remove the callback from the IO context */
- ast_io_remove(rtp->io, iod[0]);
-
- /* Restore file descriptors */
- chan->fds[0] = fds[0];
- ast_channel_unlock(chan);
-
- /* Restore callback mode if previously used */
- if (ast_test_flag(rtp, FLAG_CALLBACK_MODE))
- rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
-
- return 0;
-}
-
-/*! \brief Helper function that sets what an RTP structure is bridged to */
-static void p2p_set_bridge(struct ast_rtp *rtp0, struct ast_rtp *rtp1)
-{
- ast_mutex_lock(&rtp0->bridge_lock);
- rtp0->bridged = rtp1;
- ast_mutex_unlock(&rtp0->bridge_lock);
-
- return;
-}
-
-/*! \brief Bridge loop for partial native bridge (packet2packet) */
-static enum ast_bridge_result bridge_p2p_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
-{
- struct ast_frame *fr = NULL;
- struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, };
- int p0_fds[2] = {-1, -1}, p1_fds[2] = {-1, -1};
- int *p0_iod[2] = {NULL, NULL}, *p1_iod[2] = {NULL, NULL};
- int p0_callback = 0, p1_callback = 0;
- enum ast_bridge_result res = AST_BRIDGE_FAILED;
-
- /* Okay, setup each RTP structure to do P2P forwarding */
- ast_clear_flag(p0, FLAG_P2P_SENT_MARK);
- p2p_set_bridge(p0, p1);
- ast_clear_flag(p1, FLAG_P2P_SENT_MARK);
- p2p_set_bridge(p1, p0);
-
- /* Activate callback modes if possible */
- p0_callback = p2p_callback_enable(c0, p0, &p0_fds[0], &p0_iod[0]);
- p1_callback = p2p_callback_enable(c1, p1, &p1_fds[0], &p1_iod[0]);
-
- /* Now let go of the channel locks and be on our way */
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
-
- /* Go into a loop forwarding frames until we don't need to anymore */
- cs[0] = c0;
- cs[1] = c1;
- cs[2] = NULL;
- for (;;) {
- /* If the underlying formats have changed force this bridge to break */
- if ((c0->rawreadformat != c1->rawwriteformat) || (c1->rawreadformat != c0->rawwriteformat)) {
- ast_log(LOG_DEBUG, "Oooh, formats changed, backing out\n");
- res = AST_BRIDGE_FAILED_NOWARN;
- break;
- }
- /* Check if anything changed */
- if ((c0->tech_pvt != pvt0) ||
- (c1->tech_pvt != pvt1) ||
- (c0->masq || c0->masqr || c1->masq || c1->masqr) ||
- (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks)) {
- ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
- if ((c0->masq || c0->masqr) && (fr = ast_read(c0)))
- ast_frfree(fr);
- if ((c1->masq || c1->masqr) && (fr = ast_read(c1)))
- ast_frfree(fr);
- res = AST_BRIDGE_RETRY;
- break;
- }
- /* Wait on a channel to feed us a frame */
- if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
- if (!timeoutms) {
- res = AST_BRIDGE_RETRY;
- break;
- }
- if (option_debug)
- ast_log(LOG_NOTICE, "Ooh, empty read...\n");
- if (ast_check_hangup(c0) || ast_check_hangup(c1))
- break;
- continue;
- }
- /* Read in frame from channel */
- fr = ast_read(who);
- other = (who == c0) ? c1 : c0;
- /* Dependong on the frame we may need to break out of our bridge */
- if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
- ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) |
- ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) {
- /* Record received frame and who */
- *fo = fr;
- *rc = who;
- if (option_debug)
- ast_log(LOG_DEBUG, "Oooh, got a %s\n", fr ? "digit" : "hangup");
- res = AST_BRIDGE_COMPLETE;
- break;
- } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
- if ((fr->subclass == AST_CONTROL_HOLD) ||
- (fr->subclass == AST_CONTROL_UNHOLD) ||
- (fr->subclass == AST_CONTROL_VIDUPDATE) ||
- (fr->subclass == AST_CONTROL_SRCUPDATE)) {
- /* If we are going on hold, then break callback mode and P2P bridging */
- if (fr->subclass == AST_CONTROL_HOLD) {
- if (p0_callback)
- p0_callback = p2p_callback_disable(c0, p0, &p0_fds[0], &p0_iod[0]);
- if (p1_callback)
- p1_callback = p2p_callback_disable(c1, p1, &p1_fds[0], &p1_iod[0]);
- p2p_set_bridge(p0, NULL);
- p2p_set_bridge(p1, NULL);
- } else if (fr->subclass == AST_CONTROL_UNHOLD) {
- /* If we are off hold, then go back to callback mode and P2P bridging */
- ast_clear_flag(p0, FLAG_P2P_SENT_MARK);
- p2p_set_bridge(p0, p1);
- ast_clear_flag(p1, FLAG_P2P_SENT_MARK);
- p2p_set_bridge(p1, p0);
- p0_callback = p2p_callback_enable(c0, p0, &p0_fds[0], &p0_iod[0]);
- p1_callback = p2p_callback_enable(c1, p1, &p1_fds[0], &p1_iod[0]);
- }
- ast_indicate_data(other, fr->subclass, fr->data, fr->datalen);
- ast_frfree(fr);
- } else {
- *fo = fr;
- *rc = who;
- ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name);
- res = AST_BRIDGE_COMPLETE;
- break;
- }
- } else {
- if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
- (fr->frametype == AST_FRAME_DTMF_END) ||
- (fr->frametype == AST_FRAME_VOICE) ||
- (fr->frametype == AST_FRAME_VIDEO) ||
- (fr->frametype == AST_FRAME_IMAGE) ||
- (fr->frametype == AST_FRAME_HTML) ||
- (fr->frametype == AST_FRAME_MODEM) ||
- (fr->frametype == AST_FRAME_TEXT)) {
- ast_write(other, fr);
- }
-
- ast_frfree(fr);
- }
- /* Swap priority */
- cs[2] = cs[0];
- cs[0] = cs[1];
- cs[1] = cs[2];
- }
-
- /* If we are totally avoiding the core, then restore our link to it */
- if (p0_callback)
- p0_callback = p2p_callback_disable(c0, p0, &p0_fds[0], &p0_iod[0]);
- if (p1_callback)
- p1_callback = p2p_callback_disable(c1, p1, &p1_fds[0], &p1_iod[0]);
-
- /* Break out of the direct bridge */
- p2p_set_bridge(p0, NULL);
- p2p_set_bridge(p1, NULL);
-
- return res;
-}
-
-/*! \brief Bridge calls. If possible and allowed, initiate
- re-invite so the peers exchange media directly outside
- of Asterisk. */
-enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
-{
- struct ast_rtp *p0 = NULL, *p1 = NULL; /* Audio RTP Channels */
- struct ast_rtp *vp0 = NULL, *vp1 = NULL; /* Video RTP channels */
- struct ast_rtp_protocol *pr0 = NULL, *pr1 = NULL;
- enum ast_rtp_get_result audio_p0_res = AST_RTP_GET_FAILED, video_p0_res = AST_RTP_GET_FAILED;
- enum ast_rtp_get_result audio_p1_res = AST_RTP_GET_FAILED, video_p1_res = AST_RTP_GET_FAILED;
- enum ast_bridge_result res = AST_BRIDGE_FAILED;
- int codec0 = 0, codec1 = 0;
- void *pvt0 = NULL, *pvt1 = NULL;
-
- /* Lock channels */
- ast_channel_lock(c0);
- while(ast_channel_trylock(c1)) {
- ast_channel_unlock(c0);
- usleep(1);
- ast_channel_lock(c0);
- }
-
- /* Ensure neither channel got hungup during lock avoidance */
- if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
- ast_log(LOG_WARNING, "Got hangup while attempting to bridge '%s' and '%s'\n", c0->name, c1->name);
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED;
- }
-
- /* Find channel driver interfaces */
- if (!(pr0 = get_proto(c0))) {
- ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED;
- }
- if (!(pr1 = get_proto(c1))) {
- ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED;
- }
-
- /* Get channel specific interface structures */
- pvt0 = c0->tech_pvt;
- pvt1 = c1->tech_pvt;
-
- /* Get audio and video interface (if native bridge is possible) */
- audio_p0_res = pr0->get_rtp_info(c0, &p0);
- video_p0_res = pr0->get_vrtp_info ? pr0->get_vrtp_info(c0, &vp0) : AST_RTP_GET_FAILED;
- audio_p1_res = pr1->get_rtp_info(c1, &p1);
- video_p1_res = pr1->get_vrtp_info ? pr1->get_vrtp_info(c1, &vp1) : AST_RTP_GET_FAILED;
-
- /* If we are carrying video, and both sides are not reinviting... then fail the native bridge */
- if (video_p0_res != AST_RTP_GET_FAILED && (audio_p0_res != AST_RTP_TRY_NATIVE || video_p0_res != AST_RTP_TRY_NATIVE))
- audio_p0_res = AST_RTP_GET_FAILED;
- if (video_p1_res != AST_RTP_GET_FAILED && (audio_p1_res != AST_RTP_TRY_NATIVE || video_p1_res != AST_RTP_TRY_NATIVE))
- audio_p1_res = AST_RTP_GET_FAILED;
-
- /* Check if a bridge is possible (partial/native) */
- if (audio_p0_res == AST_RTP_GET_FAILED || audio_p1_res == AST_RTP_GET_FAILED) {
- /* Somebody doesn't want to play... */
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
-
- /* If we need to feed DTMF frames into the core then only do a partial native bridge */
- if (ast_test_flag(p0, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
- ast_set_flag(p0, FLAG_P2P_NEED_DTMF);
- audio_p0_res = AST_RTP_TRY_PARTIAL;
- }
-
- if (ast_test_flag(p1, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)) {
- ast_set_flag(p1, FLAG_P2P_NEED_DTMF);
- audio_p1_res = AST_RTP_TRY_PARTIAL;
- }
-
- /* If both sides are not using the same method of DTMF transmission
- * (ie: one is RFC2833, other is INFO... then we can not do direct media.
- * --------------------------------------------------
- * | DTMF Mode | HAS_DTMF | Accepts Begin Frames |
- * |-----------|------------|-----------------------|
- * | Inband | False | True |
- * | RFC2833 | True | True |
- * | SIP INFO | False | False |
- * --------------------------------------------------
- * However, if DTMF from both channels is being monitored by the core, then
- * we can still do packet-to-packet bridging, because passing through the
- * core will handle DTMF mode translation.
- */
- if ( (ast_test_flag(p0, FLAG_HAS_DTMF) != ast_test_flag(p1, FLAG_HAS_DTMF)) ||
- (!c0->tech->send_digit_begin != !c1->tech->send_digit_begin)) {
- if (!ast_test_flag(p0, FLAG_P2P_NEED_DTMF) || !ast_test_flag(p1, FLAG_P2P_NEED_DTMF)) {
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
- audio_p0_res = AST_RTP_TRY_PARTIAL;
- audio_p1_res = AST_RTP_TRY_PARTIAL;
- }
-
- /* If we need to feed frames into the core don't do a P2P bridge */
- if ((audio_p0_res == AST_RTP_TRY_PARTIAL && ast_test_flag(p0, FLAG_P2P_NEED_DTMF)) ||
- (audio_p1_res == AST_RTP_TRY_PARTIAL && ast_test_flag(p1, FLAG_P2P_NEED_DTMF))) {
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
-
- /* Get codecs from both sides */
- codec0 = pr0->get_codec ? pr0->get_codec(c0) : 0;
- codec1 = pr1->get_codec ? pr1->get_codec(c1) : 0;
- if (codec0 && codec1 && !(codec0 & codec1)) {
- /* Hey, we can't do native bridging if both parties speak different codecs */
- if (option_debug)
- ast_log(LOG_DEBUG, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1);
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
-
- /* If either side can only do a partial bridge, then don't try for a true native bridge */
- if (audio_p0_res == AST_RTP_TRY_PARTIAL || audio_p1_res == AST_RTP_TRY_PARTIAL) {
- struct ast_format_list fmt0, fmt1;
-
- /* In order to do Packet2Packet bridging both sides must be in the same rawread/rawwrite */
- if (c0->rawreadformat != c1->rawwriteformat || c1->rawreadformat != c0->rawwriteformat) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Cannot packet2packet bridge - raw formats are incompatible\n");
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
- /* They must also be using the same packetization */
- fmt0 = ast_codec_pref_getsize(&p0->pref, c0->rawreadformat);
- fmt1 = ast_codec_pref_getsize(&p1->pref, c1->rawreadformat);
- if (fmt0.cur_ms != fmt1.cur_ms) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Cannot packet2packet bridge - packetization settings prevent it\n");
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return AST_BRIDGE_FAILED_NOWARN;
- }
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Packet2Packet bridging %s and %s\n", c0->name, c1->name);
- res = bridge_p2p_loop(c0, c1, p0, p1, timeoutms, flags, fo, rc, pvt0, pvt1);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
- res = bridge_native_loop(c0, c1, p0, p1, vp0, vp1, pr0, pr1, codec0, codec1, timeoutms, flags, fo, rc, pvt0, pvt1);
- }
-
- return res;
-}
-
-static int rtp_do_debug_ip(int fd, int argc, char *argv[])
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port = 0;
- char *p, *arg;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- arg = argv[3];
- p = strstr(arg, ":");
- if (p) {
- *p = '\0';
- p++;
- port = atoi(p);
- }
- hp = ast_gethostbyname(arg, &ahp);
- if (hp == NULL)
- return RESULT_SHOWUSAGE;
- rtpdebugaddr.sin_family = AF_INET;
- memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr));
- rtpdebugaddr.sin_port = htons(port);
- if (port == 0)
- ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtpdebugaddr.sin_addr));
- else
- ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtpdebugaddr.sin_addr), port);
- rtpdebug = 1;
- return RESULT_SUCCESS;
-}
-
-static int rtcp_do_debug_ip_deprecated(int fd, int argc, char *argv[])
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port = 0;
- char *p, *arg;
- if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- arg = argv[4];
- p = strstr(arg, ":");
- if (p) {
- *p = '\0';
- p++;
- port = atoi(p);
- }
- hp = ast_gethostbyname(arg, &ahp);
- if (hp == NULL)
- return RESULT_SHOWUSAGE;
- rtcpdebugaddr.sin_family = AF_INET;
- memcpy(&rtcpdebugaddr.sin_addr, hp->h_addr, sizeof(rtcpdebugaddr.sin_addr));
- rtcpdebugaddr.sin_port = htons(port);
- if (port == 0)
- ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr));
- else
- ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port);
- rtcpdebug = 1;
- return RESULT_SUCCESS;
-}
-
-static int rtcp_do_debug_ip(int fd, int argc, char *argv[])
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port = 0;
- char *p, *arg;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- arg = argv[3];
- p = strstr(arg, ":");
- if (p) {
- *p = '\0';
- p++;
- port = atoi(p);
- }
- hp = ast_gethostbyname(arg, &ahp);
- if (hp == NULL)
- return RESULT_SHOWUSAGE;
- rtcpdebugaddr.sin_family = AF_INET;
- memcpy(&rtcpdebugaddr.sin_addr, hp->h_addr, sizeof(rtcpdebugaddr.sin_addr));
- rtcpdebugaddr.sin_port = htons(port);
- if (port == 0)
- ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr));
- else
- ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port);
- rtcpdebug = 1;
- return RESULT_SUCCESS;
-}
-
-static int rtp_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 2) {
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- return rtp_do_debug_ip(fd, argc, argv);
- }
- rtpdebug = 1;
- memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr));
- ast_cli(fd, "RTP Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_do_debug_deprecated(int fd, int argc, char *argv[]) {
- if (argc != 3) {
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- return rtcp_do_debug_ip_deprecated(fd, argc, argv);
- }
- rtcpdebug = 1;
- memset(&rtcpdebugaddr,0,sizeof(rtcpdebugaddr));
- ast_cli(fd, "RTCP Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_do_debug(int fd, int argc, char *argv[]) {
- if (argc != 2) {
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- return rtcp_do_debug_ip(fd, argc, argv);
- }
- rtcpdebug = 1;
- memset(&rtcpdebugaddr,0,sizeof(rtcpdebugaddr));
- ast_cli(fd, "RTCP Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_do_stats_deprecated(int fd, int argc, char *argv[]) {
- if (argc != 3) {
- return RESULT_SHOWUSAGE;
- }
- rtcpstats = 1;
- ast_cli(fd, "RTCP Stats Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_do_stats(int fd, int argc, char *argv[]) {
- if (argc != 2) {
- return RESULT_SHOWUSAGE;
- }
- rtcpstats = 1;
- ast_cli(fd, "RTCP Stats Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtp_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- rtpdebug = 0;
- ast_cli(fd,"RTP Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_no_debug_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- rtcpdebug = 0;
- ast_cli(fd,"RTCP Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- rtcpdebug = 0;
- ast_cli(fd,"RTCP Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_no_stats_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- rtcpstats = 0;
- ast_cli(fd,"RTCP Stats Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int rtcp_no_stats(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- rtcpstats = 0;
- ast_cli(fd,"RTCP Stats Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int stun_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 2) {
- return RESULT_SHOWUSAGE;
- }
- stundebug = 1;
- ast_cli(fd, "STUN Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int stun_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- stundebug = 0;
- ast_cli(fd, "STUN Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static char debug_usage[] =
- "Usage: rtp debug [ip host[:port]]\n"
- " Enable dumping of all RTP packets to and from host.\n";
-
-static char no_debug_usage[] =
- "Usage: rtp debug off\n"
- " Disable all RTP debugging\n";
-
-static char stun_debug_usage[] =
- "Usage: stun debug\n"
- " Enable STUN (Simple Traversal of UDP through NATs) debugging\n";
-
-static char stun_no_debug_usage[] =
- "Usage: stun debug off\n"
- " Disable STUN debugging\n";
-
-static char rtcp_debug_usage[] =
- "Usage: rtcp debug [ip host[:port]]\n"
- " Enable dumping of all RTCP packets to and from host.\n";
-
-static char rtcp_no_debug_usage[] =
- "Usage: rtcp debug off\n"
- " Disable all RTCP debugging\n";
-
-static char rtcp_stats_usage[] =
- "Usage: rtcp stats\n"
- " Enable dumping of RTCP stats.\n";
-
-static char rtcp_no_stats_usage[] =
- "Usage: rtcp stats off\n"
- " Disable all RTCP stats\n";
-
-static struct ast_cli_entry cli_rtp_no_debug_deprecated = {
- { "rtp", "no", "debug", NULL },
- rtp_no_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_rtp_rtcp_debug_ip_deprecated = {
- { "rtp", "rtcp", "debug", "ip", NULL },
- rtcp_do_debug_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_rtp_rtcp_debug_deprecated = {
- { "rtp", "rtcp", "debug", NULL },
- rtcp_do_debug_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_rtp_rtcp_no_debug_deprecated = {
- { "rtp", "rtcp", "no", "debug", NULL },
- rtcp_no_debug_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_rtp_rtcp_stats_deprecated = {
- { "rtp", "rtcp", "stats", NULL },
- rtcp_do_stats_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_rtp_rtcp_no_stats_deprecated = {
- { "rtp", "rtcp", "no", "stats", NULL },
- rtcp_no_stats_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_stun_no_debug_deprecated = {
- { "stun", "no", "debug", NULL },
- stun_no_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_rtp[] = {
- { { "rtp", "debug", "ip", NULL },
- rtp_do_debug, "Enable RTP debugging on IP",
- debug_usage },
-
- { { "rtp", "debug", NULL },
- rtp_do_debug, "Enable RTP debugging",
- debug_usage },
-
- { { "rtp", "debug", "off", NULL },
- rtp_no_debug, "Disable RTP debugging",
- no_debug_usage, NULL, &cli_rtp_no_debug_deprecated },
-
- { { "rtcp", "debug", "ip", NULL },
- rtcp_do_debug, "Enable RTCP debugging on IP",
- rtcp_debug_usage, NULL, &cli_rtp_rtcp_debug_ip_deprecated },
-
- { { "rtcp", "debug", NULL },
- rtcp_do_debug, "Enable RTCP debugging",
- rtcp_debug_usage, NULL, &cli_rtp_rtcp_debug_deprecated },
-
- { { "rtcp", "debug", "off", NULL },
- rtcp_no_debug, "Disable RTCP debugging",
- rtcp_no_debug_usage, NULL, &cli_rtp_rtcp_no_debug_deprecated },
-
- { { "rtcp", "stats", NULL },
- rtcp_do_stats, "Enable RTCP stats",
- rtcp_stats_usage, NULL, &cli_rtp_rtcp_stats_deprecated },
-
- { { "rtcp", "stats", "off", NULL },
- rtcp_no_stats, "Disable RTCP stats",
- rtcp_no_stats_usage, NULL, &cli_rtp_rtcp_no_stats_deprecated },
-
- { { "stun", "debug", NULL },
- stun_do_debug, "Enable STUN debugging",
- stun_debug_usage },
-
- { { "stun", "debug", "off", NULL },
- stun_no_debug, "Disable STUN debugging",
- stun_no_debug_usage, NULL, &cli_stun_no_debug_deprecated },
-};
-
-int ast_rtp_reload(void)
-{
- struct ast_config *cfg;
- const char *s;
-
- rtpstart = 5000;
- rtpend = 31000;
- dtmftimeout = DEFAULT_DTMF_TIMEOUT;
- cfg = ast_config_load("rtp.conf");
- if (cfg) {
- if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
- rtpstart = atoi(s);
- if (rtpstart < 1024)
- rtpstart = 1024;
- if (rtpstart > 65535)
- rtpstart = 65535;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
- rtpend = atoi(s);
- if (rtpend < 1024)
- rtpend = 1024;
- if (rtpend > 65535)
- rtpend = 65535;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "rtcpinterval"))) {
- rtcpinterval = atoi(s);
- if (rtcpinterval == 0)
- rtcpinterval = 0; /* Just so we're clear... it's zero */
- if (rtcpinterval < RTCP_MIN_INTERVALMS)
- rtcpinterval = RTCP_MIN_INTERVALMS; /* This catches negative numbers too */
- if (rtcpinterval > RTCP_MAX_INTERVALMS)
- rtcpinterval = RTCP_MAX_INTERVALMS;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
-#ifdef SO_NO_CHECK
- if (ast_false(s))
- nochecksums = 1;
- else
- nochecksums = 0;
-#else
- if (ast_false(s))
- ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
-#endif
- }
- if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) {
- dtmftimeout = atoi(s);
- if ((dtmftimeout < 0) || (dtmftimeout > 20000)) {
- ast_log(LOG_WARNING, "DTMF timeout of '%d' outside range, using default of '%d' instead\n",
- dtmftimeout, DEFAULT_DTMF_TIMEOUT);
- dtmftimeout = DEFAULT_DTMF_TIMEOUT;
- };
- }
- ast_config_destroy(cfg);
- }
- if (rtpstart >= rtpend) {
- ast_log(LOG_WARNING, "Unreasonable values for RTP start/end port in rtp.conf\n");
- rtpstart = 5000;
- rtpend = 31000;
- }
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
- return 0;
-}
-
-/*! \brief Initialize the RTP system in Asterisk */
-void ast_rtp_init(void)
-{
- ast_cli_register_multiple(cli_rtp, sizeof(cli_rtp) / sizeof(struct ast_cli_entry));
- ast_rtp_reload();
-}
-
diff --git a/1.4/main/say.c b/1.4/main/say.c
deleted file mode 100644
index ede9e98da..000000000
--- a/1.4/main/say.c
+++ /dev/null
@@ -1,6959 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- * George Konstantoulakis <gkon@inaccessnetworks.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.
- */
-
-/*! \file
- *
- * \brief Say numbers and dates (maybe words one day too)
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note 12-16-2004 : Support for Greek added by InAccess Networks (work funded by HOL, www.hol.gr) George Konstantoulakis <gkon@inaccessnetworks.com>
- *
- * \note 2007-02-08 : Support for Georgian added by Alexander Shaduri <ashaduri@gmail.com>,
- * Next Generation Networks (NGN).
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <time.h>
-#include <ctype.h>
-#include <math.h>
-#include <stdio.h>
-
-#ifdef SOLARIS
-#include <iso/limits_iso.h>
-#endif
-
-#include "asterisk/file.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/say.h"
-#include "asterisk/lock.h"
-#include "asterisk/localtime.h"
-#include "asterisk/utils.h"
-
-/* Forward declaration */
-static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
-
-
-static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
-{
- const char *fn;
- char fnbuf[256];
- char ltr;
- int num = 0;
- int res = 0;
-
- while (str[num] && !res) {
- fn = NULL;
- switch (str[num]) {
- case ('*'):
- fn = "digits/star";
- break;
- case ('#'):
- fn = "digits/pound";
- break;
- case ('!'):
- fn = "letters/exclaimation-point";
- break;
- case ('@'):
- fn = "letters/at";
- break;
- case ('$'):
- fn = "letters/dollar";
- break;
- case ('-'):
- fn = "letters/dash";
- break;
- case ('.'):
- fn = "letters/dot";
- break;
- case ('='):
- fn = "letters/equals";
- break;
- case ('+'):
- fn = "letters/plus";
- break;
- case ('/'):
- fn = "letters/slash";
- break;
- case (' '):
- fn = "letters/space";
- break;
- case ('0'):
- case ('1'):
- case ('2'):
- case ('3'):
- case ('4'):
- case ('5'):
- case ('6'):
- case ('7'):
- case ('8'):
- case ('9'):
- strcpy(fnbuf, "digits/X");
- fnbuf[7] = str[num];
- fn = fnbuf;
- break;
- default:
- ltr = str[num];
- if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
- strcpy(fnbuf, "letters/X");
- fnbuf[8] = ltr;
- fn = fnbuf;
- }
- if (fn && ast_fileexists(fn, NULL, lang) > 0) {
- res = ast_streamfile(chan, fn, lang);
- if (!res) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- num++;
- }
-
- return res;
-}
-
-static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
-{
- const char *fn;
- char fnbuf[256];
- char ltr;
- int num = 0;
- int res = 0;
-
- while (str[num] && !res) {
- fn = NULL;
- switch (str[num]) {
- case ('*'):
- fn = "digits/star";
- break;
- case ('#'):
- fn = "digits/pound";
- break;
- case ('!'):
- fn = "letters/exclaimation-point";
- break;
- case ('@'):
- fn = "letters/at";
- break;
- case ('$'):
- fn = "letters/dollar";
- break;
- case ('-'):
- fn = "letters/dash";
- break;
- case ('.'):
- fn = "letters/dot";
- break;
- case ('='):
- fn = "letters/equals";
- break;
- case ('+'):
- fn = "letters/plus";
- break;
- case ('/'):
- fn = "letters/slash";
- break;
- case (' '):
- fn = "letters/space";
- break;
- case ('0'):
- case ('1'):
- case ('2'):
- case ('3'):
- case ('4'):
- case ('5'):
- case ('6'):
- case ('7'):
- case ('8'):
- strcpy(fnbuf, "digits/X");
- fnbuf[7] = str[num];
- fn = fnbuf;
- break;
- default: /* '9' falls here... */
- ltr = str[num];
- if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
- strcpy(fnbuf, "phonetic/X_p");
- fnbuf[9] = ltr;
- fn = fnbuf;
- }
- if (fn && ast_fileexists(fn, NULL, lang) > 0) {
- res = ast_streamfile(chan, fn, lang);
- if (!res) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- num++;
- }
-
- return res;
-}
-
-static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
-{
- const char *fn;
- char fnbuf[256];
- int num = 0;
- int res = 0;
-
- while (str[num] && !res) {
- fn = NULL;
- switch (str[num]) {
- case ('*'):
- fn = "digits/star";
- break;
- case ('#'):
- fn = "digits/pound";
- break;
- case ('-'):
- fn = "digits/minus";
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- strcpy(fnbuf, "digits/X");
- fnbuf[7] = str[num];
- fn = fnbuf;
- break;
- }
- if (fn && ast_fileexists(fn, NULL, lang) > 0) {
- res = ast_streamfile(chan, fn, lang);
- if (!res) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- num++;
- }
-
- return res;
-}
-
-/* Forward declarations */
-/*! \page Def_syntaxlang Asterisk Language Syntaxes supported
- \note Not really language codes.
- For these language codes, Asterisk will change the syntax when
- saying numbers (and in some cases dates and voicemail messages
- as well)
- \arg \b da - Danish
- \arg \b de - German
- \arg \b en - English (US)
- \arg \b en_GB - English (British)
- \arg \b es - Spanish, Mexican
- \arg \b fr - French
- \arg \b he - Hebrew
- \arg \b it - Italian
- \arg \b nl - Dutch
- \arg \b no - Norwegian
- \arg \b pl - Polish
- \arg \b pt - Portuguese
- \arg \b pt_BR - Portuguese (Brazil)
- \arg \b se - Swedish
- \arg \b tw - Taiwanese / Chinese
- \arg \b ru - Russian
- \arg \b ge - Georgian
-
- \par Gender:
- For Some languages the numbers differ for gender and plural.
- \arg Use the option argument 'f' for female, 'm' for male and 'n' for neuter in languages like Portuguese, French, Spanish and German.
- \arg use the option argument 'c' is for commune and 'n' for neuter gender in nordic languages like Danish, Swedish and Norwegian.
- use the option argument 'p' for plural enumerations like in German
-
- Date/Time functions currently have less languages supported than saynumber().
-
- \todo Note that in future, we need to move to a model where we can differentiate further - e.g. between en_US & en_UK
-
- See contrib/i18n.testsuite.conf for some examples of the different syntaxes
-
- \par Portuguese
- Portuguese sound files needed for Time/Date functions:
- pt-ah
- pt-ao
- pt-de
- pt-e
- pt-ora
- pt-meianoite
- pt-meiodia
- pt-sss
-
- \par Spanish
- Spanish sound files needed for Time/Date functions:
- es-de
- es-el
-
- \par Italian
- Italian sound files needed for Time/Date functions:
- ore-una
- ore-mezzanotte
-
-*/
-
-/* Forward declarations of language specific variants of ast_say_number_full */
-static int ast_say_number_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_number_full_cz(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_en_GB(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_number_full_es(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_fr(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_it(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_number_full_nl(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_number_full_no(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_pl(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_pt(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_se(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_tw(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_number_full_ge(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-
-/* Forward declarations of language specific variants of ast_say_enumeration_full */
-static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
-static int ast_say_enumeration_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-static int ast_say_enumeration_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
-
-/* Forward declarations of ast_say_date, ast_say_datetime and ast_say_time functions */
-static int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_date_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-
-static int ast_say_date_with_format_en(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_da(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_de(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_es(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_he(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_fr(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_it(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_nl(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_pl(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_pt(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_tw(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
-
-static int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_time_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-
-static int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-
-static int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-static int ast_say_datetime_from_now_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
-
-static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
-{
- int res;
- if ((res = ast_streamfile(chan, file, lang)))
- ast_log(LOG_WARNING, "Unable to play message %s\n", file);
- if (!res)
- res = ast_waitstream(chan, ints);
- return res;
-}
-
-/*! \brief ast_say_number_full: call language-specific functions */
-/* Called from AGI */
-static int say_number_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- if (!strcasecmp(language,"en") ) { /* English syntax */
- return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "cz") ) { /* Czech syntax */
- return(ast_say_number_full_cz(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "da") ) { /* Danish syntax */
- return(ast_say_number_full_da(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "de") ) { /* German syntax */
- return(ast_say_number_full_de(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "en_GB") ) { /* British syntax */
- return(ast_say_number_full_en_GB(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "no") ) { /* Norwegian syntax */
- return(ast_say_number_full_no(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "es") || !strcasecmp(language, "mx")) { /* Spanish syntax */
- return(ast_say_number_full_es(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "fr") ) { /* French syntax */
- return(ast_say_number_full_fr(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "he") ) { /* Hebrew syntax */
- return(ast_say_number_full_he(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "it") ) { /* Italian syntax */
- return(ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "nl") ) { /* Dutch syntax */
- return(ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "pl") ) { /* Polish syntax */
- return(ast_say_number_full_pl(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "pt") || !strcasecmp(language, "pt_BR")) { /* Portuguese syntax */
- return(ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "se") ) { /* Swedish syntax */
- return(ast_say_number_full_se(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "tw") || !strcasecmp(language, "zh") ) { /* Taiwanese / Chinese syntax */
- return(ast_say_number_full_tw(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "gr") ) { /* Greek syntax */
- return(ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "ru") ) { /* Russian syntax */
- return(ast_say_number_full_ru(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "ge") ) { /* Georgian syntax */
- return(ast_say_number_full_ge(chan, num, ints, language, options, audiofd, ctrlfd));
- }
-
- /* Default to english */
- return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
-}
-
-/*! \brief ast_say_number_full_en: English syntax */
-/* This is the default syntax, if no other syntax defined in this file is used */
-static int ast_say_number_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && (num || playh)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else {
- if (num < 1000){
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- playh++;
- num -= ((num / 100) * 100);
- } else {
- if (num < 1000000) { /* 1,000,000 */
- res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 1000000000) { /* 1,000,000,000 */
- res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000000;
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-static int exp10_int(int power)
-{
- int x, res= 1;
- for (x=0;x<power;x++)
- res *= 10;
- return res;
-}
-
-/*! \brief ast_say_number_full_cz: Czech syntax */
-/* files needed:
- * 1m,2m - gender male
- * 1w,2w - gender female
- * 3,4,...,20
- * 30,40,...,90
- *
- * hundereds - 100 - sto, 200 - 2ste, 300,400 3,4sta, 500,600,...,900 5,6,...9set
- *
- * for each number 10^(3n + 3) exist 3 files represented as:
- * 1 tousand = jeden tisic = 1_E3
- * 2,3,4 tousands = dva,tri,ctyri tisice = 2-3_E3
- * 5,6,... tousands = pet,sest,... tisic = 5_E3
- *
- * million = _E6
- * miliard = _E9
- * etc...
- *
- * tousand, milion are gender male, so 1 and 2 is 1m 2m
- * miliard is gender female, so 1 and 2 is 1w 2w
- */
-static int ast_say_number_full_cz(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- char fn[256] = "";
-
- int hundered = 0;
- int left = 0;
- int length = 0;
-
- /* options - w = woman, m = man, n = neutral. Defaultl is woman */
- if (!options)
- options = "w";
-
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && (num || playh)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 3 ) {
- snprintf(fn, sizeof(fn), "digits/%d%c",num,options[0]);
- playh = 0;
- num = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d",num);
- playh = 0;
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else if (num < 1000) {
- hundered = num / 100;
- if ( hundered == 1 ) {
- snprintf(fn, sizeof(fn), "digits/1sto");
- } else if ( hundered == 2 ) {
- snprintf(fn, sizeof(fn), "digits/2ste");
- } else {
- res = ast_say_number_full_cz(chan,hundered,ints,language,options,audiofd,ctrlfd);
- if (res)
- return res;
- if (hundered == 3 || hundered == 4) {
- snprintf(fn, sizeof(fn), "digits/sta");
- } else if ( hundered > 4 ) {
- snprintf(fn, sizeof(fn), "digits/set");
- }
- }
- num -= (hundered * 100);
- } else { /* num > 1000 */
- length = (int)log10(num)+1;
- while ( (length % 3 ) != 1 ) {
- length--;
- }
- left = num / (exp10_int(length-1));
- if ( left == 2 ) {
- switch (length-1) {
- case 9: options = "w"; /* 1,000,000,000 gender female */
- break;
- default : options = "m"; /* others are male */
- }
- }
- if ( left > 1 ) { /* we dont say "one thousand" but only thousand */
- res = ast_say_number_full_cz(chan,left,ints,language,options,audiofd,ctrlfd);
- if (res)
- return res;
- }
- if ( left >= 5 ) { /* >= 5 have the same declesion */
- snprintf(fn, sizeof(fn), "digits/5_E%d",length-1);
- } else if ( left >= 2 && left <= 4 ) {
- snprintf(fn, sizeof(fn), "digits/2-4_E%d",length-1);
- } else { /* left == 1 */
- snprintf(fn, sizeof(fn), "digits/1_E%d",length-1);
- }
- num -= left * (exp10_int(length-1));
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1)) {
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- } else {
- res = ast_waitstream(chan, ints);
- }
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_da: Danish syntax */
-/* New files:
- In addition to English, the following sounds are required: "1N", "millions", "and" and "1-and" through "9-and"
- */
-static int ast_say_number_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int playa = 0;
- int cn = 1; /* +1 = commune; -1 = neuter */
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options && !strncasecmp(options, "n",1)) cn = -1;
-
- while (!res && (num || playh || playa )) {
- /* The grammar for Danish numbers is the same as for English except
- * for the following:
- * - 1 exists in both commune ("en", file "1N") and neuter ("et", file "1")
- * - numbers 20 through 99 are said in reverse order, i.e. 21 is
- * "one-and twenty" and 68 is "eight-and sixty".
- * - "million" is different in singular and plural form
- * - numbers > 1000 with zero as the third digit from last have an
- * "and" before the last two digits, i.e. 2034 is "two thousand and
- * four-and thirty" and 1000012 is "one million and twelve".
- */
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (playa) {
- snprintf(fn, sizeof(fn), "digits/and");
- playa = 0;
- } else if (num == 1 && cn == -1) {
- snprintf(fn, sizeof(fn), "digits/1N");
- num = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- int ones = num % 10;
- if (ones) {
- snprintf(fn, sizeof(fn), "digits/%d-and", ones);
- num -= ones;
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- }
- } else {
- if (num < 1000) {
- int hundreds = num / 100;
- if (hundreds == 1)
- snprintf(fn, sizeof(fn), "digits/1N");
- else
- snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
-
- playh++;
- num -= 100 * hundreds;
- if (num)
- playa++;
-
- } else {
- if (num < 1000000) {
- res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 1000000000) {
- int millions = num / 1000000;
- res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
- if (res)
- return res;
- if (millions == 1)
- snprintf(fn, sizeof(fn), "digits/million");
- else
- snprintf(fn, sizeof(fn), "digits/millions");
- num = num % 1000000;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- if (num && num < 100)
- playa++;
- }
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_de: German syntax */
-/* New files:
- In addition to English, the following sounds are required:
- "millions"
- "1-and" through "9-and"
- "1F" (eine)
- "1N" (ein)
- NB "1" is recorded as 'eins'
- */
-static int ast_say_number_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0, t = 0;
- int mf = 1; /* +1 = male and neuter; -1 = female */
- char fn[256] = "";
- char fna[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options && (!strncasecmp(options, "f",1)))
- mf = -1;
-
- while (!res && num) {
- /* The grammar for German numbers is the same as for English except
- * for the following:
- * - numbers 20 through 99 are said in reverse order, i.e. 21 is
- * "one-and twenty" and 68 is "eight-and sixty".
- * - "one" varies according to gender
- * - 100 is 'hundert', however all other instances are 'ein hundert'
- * - 1000 is 'tausend', however all other instances are 'ein tausend'
- * - 1000000 is always 'eine million'
- * - "million" is different in singular and plural form
- */
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 100 && t) {
- snprintf(fn, sizeof(fn), "digits/and");
- t = 0;
- } else if (num == 1 && mf == -1) {
- snprintf(fn, sizeof(fn), "digits/%dF", num);
- num = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- int ones = num % 10;
- if (ones) {
- snprintf(fn, sizeof(fn), "digits/%d-and", ones);
- num -= ones;
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- }
- } else if (num == 100 && t == 0) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- num = 0;
- } else if (num < 1000) {
- int hundreds = num / 100;
- num = num % 100;
- if (hundreds == 1) {
- snprintf(fn, sizeof(fn), "digits/1N");
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", hundreds);
- }
- snprintf(fna, sizeof(fna), "digits/hundred");
- t = 1;
- } else if (num == 1000 && t == 0) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = 0;
- } else if (num < 1000000) {
- int thousands = num / 1000;
- num = num % 1000;
- t = 1;
- if (thousands == 1) {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/thousand");
- } else {
- res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/thousand");
- }
- } else if (num < 1000000000) {
- int millions = num / 1000000;
- num = num % 1000000;
- t = 1;
- if (millions == 1) {
- snprintf(fn, sizeof(fn), "digits/1F");
- snprintf(fna, sizeof(fna), "digits/million");
- } else {
- res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/millions");
- }
- } else if (num <= INT_MAX) {
- int billions = num / 1000000000;
- num = num % 1000000000;
- t = 1;
- if (billions == 1) {
- snprintf(fn, sizeof(fn), "digits/1F");
- snprintf(fna, sizeof(fna), "digits/milliard");
- } else {
- res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- snprintf(fn, sizeof(fn), "digits/milliards");
- }
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- if (!res) {
- if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- strcpy(fna, "");
- }
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_en_GB: British and Norwegian syntax */
-/* New files:
- In addition to American English, the following sounds are required: "and"
- */
-static int ast_say_number_full_en_GB(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int playa = 0;
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && (num || playh || playa )) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (playa) {
- snprintf(fn, sizeof(fn), "digits/and");
- playa = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else if (num < 1000) {
- int hundreds = num / 100;
- snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
-
- playh++;
- num -= 100 * hundreds;
- if (num)
- playa++;
- } else if (num < 1000000) {
- res = ast_say_number_full_en_GB(chan, num / 1000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = num % 1000;
- if (num && num < 100)
- playa++;
- } else if (num < 1000000000) {
- int millions = num / 1000000;
- res = ast_say_number_full_en_GB(chan, millions, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/million");
- num = num % 1000000;
- if (num && num < 100)
- playa++;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_es: Spanish syntax */
-/* New files:
- Requires a few new audios:
- 1F.gsm: feminine 'una'
- 21.gsm thru 29.gsm, cien.gsm, mil.gsm, millon.gsm, millones.gsm, 100.gsm, 200.gsm, 300.gsm, 400.gsm, 500.gsm, 600.gsm, 700.gsm, 800.gsm, 900.gsm, y.gsm
- */
-static int ast_say_number_full_es(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playa = 0;
- int mf = 0; /* +1 = male; -1 = female */
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options) {
- if (!strncasecmp(options, "f",1))
- mf = -1;
- else if (!strncasecmp(options, "m", 1))
- mf = 1;
- }
-
- while (!res && num) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playa) {
- snprintf(fn, sizeof(fn), "digits/and");
- playa = 0;
- } else if (num == 1) {
- if (mf < 0)
- snprintf(fn, sizeof(fn), "digits/%dF", num);
- else if (mf > 0)
- snprintf(fn, sizeof(fn), "digits/%dM", num);
- else
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 31) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
- num -= ((num/10)*10);
- if (num)
- playa++;
- } else if (num == 100) {
- snprintf(fn, sizeof(fn), "digits/100");
- num = 0;
- } else if (num < 200) {
- snprintf(fn, sizeof(fn), "digits/100-and");
- num -= 100;
- } else {
- if (num < 1000) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/100)*100);
- num -= ((num/100)*100);
- } else if (num < 2000) {
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 1000000) {
- res = ast_say_number_full_es(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 2147483640) {
- if ((num/1000000) == 1) {
- res = ast_say_number_full_es(chan, num / 1000000, ints, language, "M", audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- res = ast_say_number_full_es(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/millions");
- }
- num = num % 1000000;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
-
- }
-
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_fr: French syntax */
-/* Extra sounds needed:
- 1F: feminin 'une'
- et: 'and' */
-static int ast_say_number_full_fr(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int playa = 0;
- int mf = 1; /* +1 = male; -1 = female */
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options && !strncasecmp(options, "f",1))
- mf = -1;
-
- while (!res && (num || playh || playa)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (playa) {
- snprintf(fn, sizeof(fn), "digits/et");
- playa = 0;
- } else if (num == 1) {
- if (mf < 0)
- snprintf(fn, sizeof(fn), "digits/%dF", num);
- else
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 21) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 70) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
- if ((num % 10) == 1) playa++;
- num = num % 10;
- } else if (num < 80) {
- snprintf(fn, sizeof(fn), "digits/60");
- if ((num % 10) == 1) playa++;
- num = num - 60;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/80");
- num = num - 80;
- } else if (num < 200) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- num = num - 100;
- } else if (num < 1000) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- playh++;
- num = num % 100;
- } else if (num < 2000) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = num - 1000;
- } else if (num < 1000000) {
- res = ast_say_number_full_fr(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = num % 1000;
- } else if (num < 1000000000) {
- res = ast_say_number_full_fr(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/million");
- num = num % 1000000;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-
-
-/*! \brief ast_say_number_full_he: Hebrew syntax */
-/* Extra sounds needed:
- 1F: feminin 'one'
- ve: 'and'
- 1hundred: 1 hundred
- 2hundred: 2 hundreds
- 2thousands: 2 thousand
- thousands: plural of 'thousand'
- 3sF 'Smichut forms (female)
- 4sF
- 5sF
- 6sF
- 7sF
- 8sF
- 9sF
- 3s 'Smichut' forms (male)
- 4s
- 5s
- 6s
- 7s
- 9s
- 10s
- 11s
- 12s
- 13s
- 14s
- 15s
- 16s
- 17s
- 18s
- 19s
-
-TODO: 've' should sometimed be 'hu':
-* before 'shtaym' (2, F)
-* before 'shnaym' (2, M)
-* before 'shlosha' (3, M)
-* before 'shmone' (8, M)
-* before 'shlosim' (30)
-* before 'shmonim' (80)
-
-What about:
-'sheva' (7, F)?
-'tesha' (9, F)?
-*/
-#define SAY_NUM_BUF_SIZE 256
-static int ast_say_number_full_he(struct ast_channel *chan, int num,
- const char *ints, const char *language, const char *options,
- int audiofd, int ctrlfd)
-{
- int res = 0;
- int state = 0; /* no need to save anything */
- int mf = 1; /* +1 = Masculin; -1 = Feminin */
- char fn[SAY_NUM_BUF_SIZE] = "";
- ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: started. "
- "num: %d, options=\"%s\"\n",
- num, options
- );
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options && !strncasecmp(options, "f",1))
- mf = -1;
-
- /* Do we have work to do? */
- while (!res && (num || (state>0) )) {
- /* first type of work: play a second sound. In this loop
- * we can only play one sound file at a time. Thus playing
- * a second one requires repeating the loop just for the
- * second file. The variable 'state' remembers where we were.
- * state==0 is the normal mode and it means that we continue
- * to check if the number num has yet anything left.
- */
- ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: num: %d, "
- "state=%d, options=\"%s\", mf=%d\n",
- num, state, options, mf
- );
- if (state==1) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- state = 0;
- } else if (state==2) {
- snprintf(fn, sizeof(fn), "digits/ve");
- state = 0;
- } else if (state==3) {
- snprintf(fn, sizeof(fn), "digits/thousands");
- state=0;
- } else if (num <21) {
- if (mf < 0)
- snprintf(fn, sizeof(fn), "digits/%dF", num);
- else
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
- num = num % 10;
- if (num>0) state=2;
- } else if (num < 200) {
- snprintf(fn, sizeof(fn), "digits/1hundred");
- num = num - 100;
- state=2;
- } else if (num < 300) {
- snprintf(fn, sizeof(fn), "digits/2hundred");
- num = num - 200;
- state=2;
- } else if (num < 1000) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- state=1;
- num = num % 100;
- } else if (num < 2000) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = num - 1000;
- } else if (num < 3000) {
- snprintf(fn, sizeof(fn), "digits/2thousand");
- num = num - 2000;
- if (num>0) state=2;
- } else if (num < 20000) {
- snprintf(fn, sizeof(fn), "digits/%ds",(num/1000));
- num = num % 1000;
- state=3;
- } else if (num < 1000000) {
- res = ast_say_number_full_he(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = num % 1000;
- } else if (num < 1000000000) {
- res = ast_say_number_full_he(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/million");
- num = num % 1000000;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_it: Italian */
-static int ast_say_number_full_it(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int tempnum = 0;
- char fn[256] = "";
-
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- /*
- Italian support
-
- Like english, numbers up to 20 are a single 'word', and others
- compound, but with exceptions.
- For example 21 is not twenty-one, but there is a single word in 'it'.
- Idem for 28 (ie when a the 2nd part of a compund number
- starts with a vowel)
-
- There are exceptions also for hundred, thousand and million.
- In english 100 = one hundred, 200 is two hundred.
- In italian 100 = cento , like to say hundred (without one),
- 200 and more are like english.
-
- Same applies for thousand:
- 1000 is one thousand in en, 2000 is two thousand.
- In it we have 1000 = mille , 2000 = 2 mila
-
- For million(s) we use the plural, if more than one
- Also, one million is abbreviated in it, like on-million,
- or 'un milione', not 'uno milione'.
- So the right file is provided.
- */
-
- while (!res && (num || playh)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 21) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 28) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 31) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 38) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 41) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 48) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 51) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 58) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 61) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 68) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 71) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 78) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 81) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 88) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 91) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num == 98) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else {
- if (num < 1000) {
- if ((num / 100) > 1) {
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- playh++;
- } else {
- snprintf(fn, sizeof(fn), "digits/hundred");
- }
- num -= ((num / 100) * 100);
- } else {
- if (num < 1000000) { /* 1,000,000 */
- if ((num/1000) > 1)
- res = ast_say_number_full_it(chan, num / 1000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- tempnum = num;
- num = num % 1000;
- if ((tempnum / 1000) < 2)
- snprintf(fn, sizeof(fn), "digits/thousand");
- else /* for 1000 it says mille, for >1000 (eg 2000) says mila */
- snprintf(fn, sizeof(fn), "digits/thousands");
- } else {
- if (num < 1000000000) { /* 1,000,000,000 */
- if ((num / 1000000) > 1)
- res = ast_say_number_full_it(chan, num / 1000000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- tempnum = num;
- num = num % 1000000;
- if ((tempnum / 1000000) < 2)
- snprintf(fn, sizeof(fn), "digits/million");
- else
- snprintf(fn, sizeof(fn), "digits/millions");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_nl: dutch syntax */
-/* New files: digits/nl-en
- */
-static int ast_say_number_full_nl(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int units = 0;
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
- while (!res && (num || playh )) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- units = num % 10;
- if (units > 0) {
- res = ast_say_number_full_nl(chan, units, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num - units;
- snprintf(fn, sizeof(fn), "digits/nl-en");
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", num - units);
- num = 0;
- }
- } else if (num < 200) {
- /* hundred, not one-hundred */
- ast_copy_string(fn, "digits/hundred", sizeof(fn));
- num -= ((num / 100) * 100);
- } else if (num < 1000) {
- snprintf(fn, sizeof(fn), "digits/%d", num / 100);
- playh++;
- num -= ((num / 100) * 100);
- } else {
- if (num < 1100) {
- /* thousand, not one-thousand */
- num = num % 1000;
- ast_copy_string(fn, "digits/thousand", sizeof(fn));
- } else if (num < 10000) { /* 1,100 to 9,9999 */
- res = ast_say_number_full_nl(chan, num / 100, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 100;
- ast_copy_string(fn, "digits/hundred", sizeof(fn));
- } else {
- if (num < 1000000) { /* 1,000,000 */
- res = ast_say_number_full_nl(chan, num / 1000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 1000000000) { /* 1,000,000,000 */
- res = ast_say_number_full_nl(chan, num / 1000000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000000;
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_no: Norwegian syntax */
-/* New files:
- In addition to American English, the following sounds are required: "and", "1N"
- */
-static int ast_say_number_full_no(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int playa = 0;
- int cn = 1; /* +1 = commune; -1 = neuter */
- char fn[256] = "";
-
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options && !strncasecmp(options, "n",1)) cn = -1;
-
- while (!res && (num || playh || playa )) {
- /* The grammar for Norwegian numbers is the same as for English except
- * for the following:
- * - 1 exists in both commune ("en", file "1") and neuter ("ett", file "1N")
- * "and" before the last two digits, i.e. 2034 is "two thousand and
- * thirty-four" and 1000012 is "one million and twelve".
- */
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (playa) {
- snprintf(fn, sizeof(fn), "digits/and");
- playa = 0;
- } else if (num == 1 && cn == -1) {
- snprintf(fn, sizeof(fn), "digits/1N");
- num = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else if (num < 1000) {
- int hundreds = num / 100;
- if (hundreds == 1)
- snprintf(fn, sizeof(fn), "digits/1N");
- else
- snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
-
- playh++;
- num -= 100 * hundreds;
- if (num)
- playa++;
- } else if (num < 1000000) {
- res = ast_say_number_full_no(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/thousand");
- num = num % 1000;
- if (num && num < 100)
- playa++;
- } else if (num < 1000000000) {
- int millions = num / 1000000;
- res = ast_say_number_full_no(chan, millions, ints, language, "c", audiofd, ctrlfd);
- if (res)
- return res;
- snprintf(fn, sizeof(fn), "digits/million");
- num = num % 1000000;
- if (num && num < 100)
- playa++;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-typedef struct {
- char *separator_dziesiatek;
- char *cyfry[10];
- char *cyfry2[10];
- char *setki[10];
- char *dziesiatki[10];
- char *nastki[10];
- char *rzedy[3][3];
-} odmiana;
-
-static char *pl_rzad_na_tekst(odmiana *odm, int i, int rzad)
-{
- if (rzad==0)
- return "";
-
- if (i==1)
- return odm->rzedy[rzad - 1][0];
- if ((i > 21 || i < 11) && i%10 > 1 && i%10 < 5)
- return odm->rzedy[rzad - 1][1];
- else
- return odm->rzedy[rzad - 1][2];
-}
-
-static char* pl_append(char* buffer, char* str)
-{
- strcpy(buffer, str);
- buffer += strlen(str);
- return buffer;
-}
-
-static void pl_odtworz_plik(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, char *fn)
-{
- char file_name[255] = "digits/";
- strcat(file_name, fn);
- ast_log(LOG_DEBUG, "Trying to play: %s\n", file_name);
- if (!ast_streamfile(chan, file_name, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
-}
-
-static void powiedz(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
-{
- /* Initialise variables to allow compilation on Debian-stable, etc */
- int m1000E6 = 0;
- int i1000E6 = 0;
- int m1000E3 = 0;
- int i1000E3 = 0;
- int m1000 = 0;
- int i1000 = 0;
- int m100 = 0;
- int i100 = 0;
-
- if (i == 0 && rzad > 0) {
- return;
- }
- if (i == 0) {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[0]);
- return;
- }
-
- m1000E6 = i % 1000000000;
- i1000E6 = i / 1000000000;
-
- powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+3, i1000E6);
-
- m1000E3 = m1000E6 % 1000000;
- i1000E3 = m1000E6 / 1000000;
-
- powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+2, i1000E3);
-
- m1000 = m1000E3 % 1000;
- i1000 = m1000E3 / 1000;
-
- powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+1, i1000);
-
- m100 = m1000 % 100;
- i100 = m1000 / 100;
-
- if (i100>0)
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
-
- if ( m100 > 0 && m100 <=9 ) {
- if (m1000>0)
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
- else
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
- } else if (m100 % 10 == 0) {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
- } else if (m100 <= 19 ) {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
- } else if (m100 != 0) {
- if (odm->separator_dziesiatek[0]==' ') {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
- } else {
- char buf[10];
- char *b = buf;
- b = pl_append(b, odm->dziesiatki[m100 / 10]);
- b = pl_append(b, odm->separator_dziesiatek);
- b = pl_append(b, odm->cyfry2[m100 % 10]);
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
- }
- }
-
- if (rzad > 0) {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, pl_rzad_na_tekst(odm, i, rzad));
- }
-}
-
-/* ast_say_number_full_pl: Polish syntax */
-static int ast_say_number_full_pl(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-/*
-Sounds needed:
-0 zero
-1 jeden
-10 dziesiec
-100 sto
-1000 tysiac
-1000000 milion
-1000000000 miliard
-1000000000.2 miliardy
-1000000000.5 miliardow
-1000000.2 miliony
-1000000.5 milionow
-1000.2 tysiace
-1000.5 tysiecy
-100m stu
-10m dziesieciu
-11 jedenascie
-11m jedenastu
-12 dwanascie
-12m dwunastu
-13 trzynascie
-13m trzynastu
-14 czternascie
-14m czternastu
-15 pietnascie
-15m pietnastu
-16 szesnascie
-16m szesnastu
-17 siedemnascie
-17m siedemnastu
-18 osiemnascie
-18m osiemnastu
-19 dziewietnascie
-19m dziewietnastu
-1z jedna
-2 dwa
-20 dwadziescia
-200 dwiescie
-200m dwustu
-20m dwudziestu
-2-1m dwaj
-2-2m dwoch
-2z dwie
-3 trzy
-30 trzydziesci
-300 trzysta
-300m trzystu
-30m trzydziestu
-3-1m trzej
-3-2m trzech
-4 cztery
-40 czterdziesci
-400 czterysta
-400m czterystu
-40m czterdziestu
-4-1m czterej
-4-2m czterech
-5 piec
-50 piecdziesiat
-500 piecset
-500m pieciuset
-50m piedziesieciu
-5m pieciu
-6 szesc
-60 szescdziesiat
-600 szescset
-600m szesciuset
-60m szescdziesieciu
-6m szesciu
-7 siedem
-70 siedemdziesiat
-700 siedemset
-700m siedmiuset
-70m siedemdziesieciu
-7m siedmiu
-8 osiem
-80 osiemdziesiat
-800 osiemset
-800m osmiuset
-80m osiemdziesieciu
-8m osmiu
-9 dziewiec
-90 dziewiecdziesiat
-900 dziewiecset
-900m dziewieciuset
-90m dziewiedziesieciu
-9m dziewieciu
-and combinations of eg.: 20_1, 30m_3m, etc...
-
-*/
-{
- char *zenski_cyfry[] = {"0","1z", "2z", "3", "4", "5", "6", "7", "8", "9"};
-
- char *zenski_cyfry2[] = {"0","1", "2z", "3", "4", "5", "6", "7", "8", "9"};
-
- char *meski_cyfry[] = {"0","1", "2-1m", "3-1m", "4-1m", "5m", /*"2-1mdwaj"*/ "6m", "7m", "8m", "9m"};
-
- char *meski_cyfry2[] = {"0","1", "2-2m", "3-2m", "4-2m", "5m", "6m", "7m", "8m", "9m"};
-
- char *meski_setki[] = {"", "100m", "200m", "300m", "400m", "500m", "600m", "700m", "800m", "900m"};
-
- char *meski_dziesiatki[] = {"", "10m", "20m", "30m", "40m", "50m", "60m", "70m", "80m", "90m"};
-
- char *meski_nastki[] = {"", "11m", "12m", "13m", "14m", "15m", "16m", "17m", "18m", "19m"};
-
- char *nijaki_cyfry[] = {"0","1", "2", "3", "4", "5", "6", "7", "8", "9"};
-
- char *nijaki_cyfry2[] = {"0","1", "2", "3", "4", "5", "6", "7", "8", "9"};
-
- char *nijaki_setki[] = {"", "100", "200", "300", "400", "500", "600", "700", "800", "900"};
-
- char *nijaki_dziesiatki[] = {"", "10", "20", "30", "40", "50", "60", "70", "80", "90"};
-
- char *nijaki_nastki[] = {"", "11", "12", "13", "14", "15", "16", "17", "18", "19"};
-
- char *rzedy[][3] = { {"1000", "1000.2", "1000.5"}, {"1000000", "1000000.2", "1000000.5"}, {"1000000000", "1000000000.2", "1000000000.5"}};
-
- /* Initialise variables to allow compilation on Debian-stable, etc */
- odmiana *o;
-
- static odmiana *odmiana_nieosobowa = NULL;
- static odmiana *odmiana_meska = NULL;
- static odmiana *odmiana_zenska = NULL;
-
- if (odmiana_nieosobowa == NULL) {
- odmiana_nieosobowa = (odmiana *) malloc(sizeof(odmiana));
-
- odmiana_nieosobowa->separator_dziesiatek = " ";
-
- memcpy(odmiana_nieosobowa->cyfry, nijaki_cyfry, sizeof(odmiana_nieosobowa->cyfry));
- memcpy(odmiana_nieosobowa->cyfry2, nijaki_cyfry2, sizeof(odmiana_nieosobowa->cyfry));
- memcpy(odmiana_nieosobowa->setki, nijaki_setki, sizeof(odmiana_nieosobowa->setki));
- memcpy(odmiana_nieosobowa->dziesiatki, nijaki_dziesiatki, sizeof(odmiana_nieosobowa->dziesiatki));
- memcpy(odmiana_nieosobowa->nastki, nijaki_nastki, sizeof(odmiana_nieosobowa->nastki));
- memcpy(odmiana_nieosobowa->rzedy, rzedy, sizeof(odmiana_nieosobowa->rzedy));
- }
-
- if (odmiana_zenska == NULL) {
- odmiana_zenska = (odmiana *) malloc(sizeof(odmiana));
-
- odmiana_zenska->separator_dziesiatek = " ";
-
- memcpy(odmiana_zenska->cyfry, zenski_cyfry, sizeof(odmiana_zenska->cyfry));
- memcpy(odmiana_zenska->cyfry2, zenski_cyfry2, sizeof(odmiana_zenska->cyfry));
- memcpy(odmiana_zenska->setki, nijaki_setki, sizeof(odmiana_zenska->setki));
- memcpy(odmiana_zenska->dziesiatki, nijaki_dziesiatki, sizeof(odmiana_zenska->dziesiatki));
- memcpy(odmiana_zenska->nastki, nijaki_nastki, sizeof(odmiana_zenska->nastki));
- memcpy(odmiana_zenska->rzedy, rzedy, sizeof(odmiana_zenska->rzedy));
- }
-
- if (odmiana_meska == NULL) {
- odmiana_meska = (odmiana *) malloc(sizeof(odmiana));
-
- odmiana_meska->separator_dziesiatek = " ";
-
- memcpy(odmiana_meska->cyfry, meski_cyfry, sizeof(odmiana_meska->cyfry));
- memcpy(odmiana_meska->cyfry2, meski_cyfry2, sizeof(odmiana_meska->cyfry));
- memcpy(odmiana_meska->setki, meski_setki, sizeof(odmiana_meska->setki));
- memcpy(odmiana_meska->dziesiatki, meski_dziesiatki, sizeof(odmiana_meska->dziesiatki));
- memcpy(odmiana_meska->nastki, meski_nastki, sizeof(odmiana_meska->nastki));
- memcpy(odmiana_meska->rzedy, rzedy, sizeof(odmiana_meska->rzedy));
- }
-
- if (options) {
- if (strncasecmp(options, "f", 1) == 0)
- o = odmiana_zenska;
- else if (strncasecmp(options, "m", 1) == 0)
- o = odmiana_meska;
- else
- o = odmiana_nieosobowa;
- } else
- o = odmiana_nieosobowa;
-
- powiedz(chan, language, audiofd, ctrlfd, ints, o, 0, num);
- return 0;
-}
-
-/* ast_say_number_full_pt: Portuguese syntax */
-/* Extra sounds needed: */
-/* For feminin all sound files end with F */
-/* 100E for 100+ something */
-/* 1000000S for plural */
-/* pt-e for 'and' */
-static int ast_say_number_full_pt(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- int mf = 1; /* +1 = male; -1 = female */
- char fn[256] = "";
-
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- if (options && !strncasecmp(options, "f",1))
- mf = -1;
-
- while (!res && num ) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 20) {
- if ((num == 1 || num == 2) && (mf < 0))
- snprintf(fn, sizeof(fn), "digits/%dF", num);
- else
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
- if (num % 10)
- playh = 1;
- num = num % 10;
- } else if (num < 1000) {
- if (num == 100)
- snprintf(fn, sizeof(fn), "digits/100");
- else if (num < 200)
- snprintf(fn, sizeof(fn), "digits/100E");
- else {
- if (mf < 0 && num > 199)
- snprintf(fn, sizeof(fn), "digits/%dF", (num / 100) * 100);
- else
- snprintf(fn, sizeof(fn), "digits/%d", (num / 100) * 100);
- if (num % 100)
- playh = 1;
- }
- num = num % 100;
- } else if (num < 1000000) {
- if (num > 1999) {
- res = ast_say_number_full_pt(chan, (num / 1000) * mf, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- }
- snprintf(fn, sizeof(fn), "digits/1000");
- if ((num % 1000) && ((num % 1000) < 100 || !(num % 100)))
- playh = 1;
- num = num % 1000;
- } else if (num < 1000000000) {
- res = ast_say_number_full_pt(chan, (num / 1000000), ints, language, options, audiofd, ctrlfd );
- if (res)
- return res;
- if (num < 2000000)
- snprintf(fn, sizeof(fn), "digits/1000000");
- else
- snprintf(fn, sizeof(fn), "digits/1000000S");
-
- if ((num % 1000000) &&
- /* no thousands */
- ((!((num / 1000) % 1000) && ((num % 1000) < 100 || !(num % 100))) ||
- /* no hundreds and below */
- (!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
- playh = 1;
- num = num % 1000000;
- } else {
- /* number is too big */
- ast_log(LOG_WARNING, "Number '%d' is too big to say.", num);
- res = -1;
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- if (!res && playh) {
- res = wait_file(chan, ints, "digits/pt-e", language);
- ast_stopstream(chan);
- playh = 0;
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_se: Swedish syntax */
-static int ast_say_number_full_se(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- char fn[256] = "";
- int cn = 1; /* +1 = commune; -1 = neuter */
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
- if (options && !strncasecmp(options, "n",1)) cn = -1;
-
- while (!res && (num || playh)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else if (num == 1 && cn == -1) { /* En eller ett? */
- snprintf(fn, sizeof(fn), "digits/1N");
- num = 0;
- } else {
- if (num < 1000){
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- playh++;
- num -= ((num / 100) * 100);
- } else {
- if (num < 1000000) { /* 1,000,000 */
- res = ast_say_number_full_se(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 1000000000) { /* 1,000,000,000 */
- res = ast_say_number_full_se(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- num = num % 1000000;
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- ast_stopstream(chan);
- }
- }
- }
- return res;
-}
-
-/*! \brief ast_say_number_full_tw: Taiwanese / Chinese syntax */
-static int ast_say_number_full_tw(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
-{
- int res = 0;
- int playh = 0;
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && (num || playh)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else if (num < 10) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else {
- if (num < 1000){
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- playh++;
- num -= ((num / 100) * 100);
- } else {
- if (num < 1000000) { /* 1,000,000 */
- res = ast_say_number_full_tw(chan, num / 1000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- if (num < 1000000000) { /* 1,000,000,000 */
- res = ast_say_number_full_tw(chan, num / 1000000, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000000;
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-
-/*! \brief determine last digits for thousands/millions (ru) */
-static int get_lastdigits_ru(int num) {
- if (num < 20) {
- return num;
- } else if (num < 100) {
- return get_lastdigits_ru(num % 10);
- } else if (num < 1000) {
- return get_lastdigits_ru(num % 100);
- }
- return 0; /* number too big */
-}
-
-
-/*! \brief ast_say_number_full_ru: Russian syntax */
-/*! \brief additional files:
- n00.gsm (one hundred, two hundred, ...)
- thousand.gsm
- million.gsm
- thousands-i.gsm (tisyachi)
- million-a.gsm (milliona)
- thousands.gsm
- millions.gsm
- 1f.gsm (odna)
- 2f.gsm (dve)
-
- where 'n' from 1 to 9
-*/
-static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- int lastdigits = 0;
- char fn[256] = "";
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && (num)) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus");
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 20) {
- if (options && strlen(options) == 1 && num < 3) {
- snprintf(fn, sizeof(fn), "digits/%d%s", num, options);
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- }
- num = 0;
- } else if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", num - (num % 10));
- num %= 10;
- } else if (num < 1000){
- snprintf(fn, sizeof(fn), "digits/%d", num - (num % 100));
- num %= 100;
- } else if (num < 1000000) { /* 1,000,000 */
- lastdigits = get_lastdigits_ru(num / 1000);
- /* say thousands */
- if (lastdigits < 3) {
- res = ast_say_number_full_ru(chan, num / 1000, ints, language, "f", audiofd, ctrlfd);
- } else {
- res = ast_say_number_full_ru(chan, num / 1000, ints, language, NULL, audiofd, ctrlfd);
- }
- if (res)
- return res;
- if (lastdigits == 1) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else if (lastdigits > 1 && lastdigits < 5) {
- snprintf(fn, sizeof(fn), "digits/thousands-i");
- } else {
- snprintf(fn, sizeof(fn), "digits/thousands");
- }
- num %= 1000;
- } else if (num < 1000000000) { /* 1,000,000,000 */
- lastdigits = get_lastdigits_ru(num / 1000000);
- /* say millions */
- res = ast_say_number_full_ru(chan, num / 1000000, ints, language, NULL, audiofd, ctrlfd);
- if (res)
- return res;
- if (lastdigits == 1) {
- snprintf(fn, sizeof(fn), "digits/million");
- } else if (lastdigits > 1 && lastdigits < 5) {
- snprintf(fn, sizeof(fn), "digits/million-a");
- } else {
- snprintf(fn, sizeof(fn), "digits/millions");
- }
- num %= 1000000;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-
-/*! \brief ast_say_enumeration_full: call language-specific functions */
-/* Called from AGI */
-static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- if (!strcasecmp(language,"en") ) { /* English syntax */
- return(ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "da") ) { /* Danish syntax */
- return(ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd));
- } else if (!strcasecmp(language, "de") ) { /* German syntax */
- return(ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd));
- }
-
- /* Default to english */
- return(ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd));
-}
-
-/*! \brief ast_say_enumeration_full_en: English syntax */
-/* This is the default syntax, if no other syntax defined in this file is used */
-static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
-{
- int res = 0, t = 0;
- char fn[256] = "";
-
- while (!res && num) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus"); /* kind of senseless for enumerations, but our best effort for error checking */
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/h-%d", num);
- num = 0;
- } else if (num < 100) {
- int tens = num / 10;
- num = num % 10;
- if (num == 0) {
- snprintf(fn, sizeof(fn), "digits/h-%d", (tens * 10));
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", (tens * 10));
- }
- } else if (num < 1000) {
- int hundreds = num / 100;
- num = num % 100;
- if (hundreds > 1 || t == 1) {
- res = ast_say_number_full_en(chan, hundreds, ints, language, audiofd, ctrlfd);
- }
- if (res)
- return res;
- if (num) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-hundred");
- }
- } else if (num < 1000000) {
- int thousands = num / 1000;
- num = num % 1000;
- if (thousands > 1 || t == 1) {
- res = ast_say_number_full_en(chan, thousands, ints, language, audiofd, ctrlfd);
- }
- if (res)
- return res;
- if (num) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-thousand");
- }
- t = 1;
- } else if (num < 1000000000) {
- int millions = num / 1000000;
- num = num % 1000000;
- t = 1;
- res = ast_say_number_full_en(chan, millions, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- if (num) {
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-million");
- }
- } else if (num < INT_MAX) {
- int billions = num / 1000000000;
- num = num % 1000000000;
- t = 1;
- res = ast_say_number_full_en(chan, billions, ints, language, audiofd, ctrlfd);
- if (res)
- return res;
- if (num) {
- snprintf(fn, sizeof(fn), "digits/billion");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-billion");
- }
- } else if (num == INT_MAX) {
- snprintf(fn, sizeof(fn), "digits/h-last");
- num = 0;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1)) {
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- } else {
- res = ast_waitstream(chan, ints);
- }
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-/*! \brief ast_say_enumeration_full_da: Danish syntax */
-static int ast_say_enumeration_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- /* options can be: '' or 'm' male gender; 'f' female gender; 'n' neuter gender; 'p' plural */
- int res = 0, t = 0;
- char fn[256] = "", fna[256] = "";
- char *gender;
-
- if (options && !strncasecmp(options, "f",1)) {
- gender = "F";
- } else if (options && !strncasecmp(options, "n",1)) {
- gender = "N";
- } else {
- gender = "";
- }
-
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && num) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus"); /* kind of senseless for enumerations, but our best effort for error checking */
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 100 && t) {
- snprintf(fn, sizeof(fn), "digits/and");
- t = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
- num = 0;
- } else if (num < 100) {
- int ones = num % 10;
- if (ones) {
- snprintf(fn, sizeof(fn), "digits/%d-and", ones);
- num -= ones;
- } else {
- snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
- num = 0;
- }
- } else if (num == 100 && t == 0) {
- snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
- num = 0;
- } else if (num < 1000) {
- int hundreds = num / 100;
- num = num % 100;
- if (hundreds == 1) {
- snprintf(fn, sizeof(fn), "digits/1N");
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", hundreds);
- }
- if (num) {
- snprintf(fna, sizeof(fna), "digits/hundred");
- } else {
- snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
- }
- t = 1;
- } else if (num < 1000000) {
- int thousands = num / 1000;
- num = num % 1000;
- if (thousands == 1) {
- if (num) {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/thousand");
- } else {
- if (t) {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
- } else {
- snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
- }
- }
- } else {
- res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- if (num) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
- }
- }
- t = 1;
- } else if (num < 1000000000) {
- int millions = num / 1000000;
- num = num % 1000000;
- if (millions == 1) {
- if (num) {
- snprintf(fn, sizeof(fn), "digits/1F");
- snprintf(fna, sizeof(fna), "digits/million");
- } else {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
- }
- } else {
- res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- if (num) {
- snprintf(fn, sizeof(fn), "digits/millions");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
- }
- }
- t = 1;
- } else if (num < INT_MAX) {
- int billions = num / 1000000000;
- num = num % 1000000000;
- if (billions == 1) {
- if (num) {
- snprintf(fn, sizeof(fn), "digits/1F");
- snprintf(fna, sizeof(fna), "digits/milliard");
- } else {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
- }
- } else {
- res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- if (num) {
- snprintf(fn, sizeof(fna), "digits/milliards");
- } else {
- snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
- }
- }
- t = 1;
- } else if (num == INT_MAX) {
- snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
- num = 0;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- if (!res) {
- if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
- if ((audiofd > -1) && (ctrlfd > -1)) {
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- } else {
- res = ast_waitstream(chan, ints);
- }
- }
- ast_stopstream(chan);
- strcpy(fna, "");
- }
- }
- }
- return res;
-}
-
-/*! \brief ast_say_enumeration_full_de: German syntax */
-static int ast_say_enumeration_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- /* options can be: '' or 'm' male gender; 'f' female gender; 'n' neuter gender; 'p' plural */
- int res = 0, t = 0;
- char fn[256] = "", fna[256] = "";
- char *gender;
-
- if (options && !strncasecmp(options, "f",1)) {
- gender = "F";
- } else if (options && !strncasecmp(options, "n",1)) {
- gender = "N";
- } else {
- gender = "";
- }
-
- if (!num)
- return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
-
- while (!res && num) {
- if (num < 0) {
- snprintf(fn, sizeof(fn), "digits/minus"); /* kind of senseless for enumerations, but our best effort for error checking */
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- } else if (num < 100 && t) {
- snprintf(fn, sizeof(fn), "digits/and");
- t = 0;
- } else if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
- num = 0;
- } else if (num < 100) {
- int ones = num % 10;
- if (ones) {
- snprintf(fn, sizeof(fn), "digits/%d-and", ones);
- num -= ones;
- } else {
- snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
- num = 0;
- }
- } else if (num == 100 && t == 0) {
- snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
- num = 0;
- } else if (num < 1000) {
- int hundreds = num / 100;
- num = num % 100;
- if (hundreds == 1) {
- snprintf(fn, sizeof(fn), "digits/1N");
- } else {
- snprintf(fn, sizeof(fn), "digits/%d", hundreds);
- }
- if (num) {
- snprintf(fna, sizeof(fna), "digits/hundred");
- } else {
- snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
- }
- t = 1;
- } else if (num < 1000000) {
- int thousands = num / 1000;
- num = num % 1000;
- if (thousands == 1) {
- if (num) {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/thousand");
- } else {
- if (t) {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
- } else {
- snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
- }
- }
- } else {
- res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- if (num) {
- snprintf(fn, sizeof(fn), "digits/thousand");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
- }
- }
- t = 1;
- } else if (num < 1000000000) {
- int millions = num / 1000000;
- num = num % 1000000;
- if (millions == 1) {
- if (num) {
- snprintf(fn, sizeof(fn), "digits/1F");
- snprintf(fna, sizeof(fna), "digits/million");
- } else {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
- }
- } else {
- res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
- if (res) {
- return res;
- }
- if (num) {
- snprintf(fn, sizeof(fn), "digits/millions");
- } else {
- snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
- }
- }
- t = 1;
- } else if (num < INT_MAX) {
- int billions = num / 1000000000;
- num = num % 1000000000;
- if (billions == 1) {
- if (num) {
- snprintf(fn, sizeof(fn), "digits/1F");
- snprintf(fna, sizeof(fna), "digits/milliard");
- } else {
- snprintf(fn, sizeof(fn), "digits/1N");
- snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
- }
- } else {
- res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
- if (res)
- return res;
- if (num) {
- snprintf(fn, sizeof(fna), "digits/milliards");
- } else {
- snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
- }
- }
- t = 1;
- } else if (num == INT_MAX) {
- snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
- num = 0;
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
-
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- if (!res) {
- if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
- if ((audiofd > -1) && (ctrlfd > -1)) {
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- } else {
- res = ast_waitstream(chan, ints);
- }
- }
- ast_stopstream(chan);
- strcpy(fna, "");
- }
- }
- }
- return res;
-}
-
-static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- if (!strcasecmp(lang, "en") ) { /* English syntax */
- return(ast_say_date_en(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "da") ) { /* Danish syntax */
- return(ast_say_date_da(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "de") ) { /* German syntax */
- return(ast_say_date_de(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "fr") ) { /* French syntax */
- return(ast_say_date_fr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */
- return(ast_say_date_nl(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "pt_BR")) { /* Portuguese syntax */
- return(ast_say_date_pt(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
- return(ast_say_date_gr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
- return(ast_say_date_ge(chan, t, ints, lang));
- }
-
- /* Default to English */
- return(ast_say_date_en(chan, t, ints, lang));
-}
-
-/* English syntax */
-int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- ast_localtime(&t,&tm,NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-/* Danish syntax */
-int ast_say_date_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- ast_localtime(&t,&tm,NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res) {
- /* Year */
- int year = tm.tm_year + 1900;
- if (year > 1999) { /* year 2000 and later */
- res = ast_say_number(chan, year, ints, lang, (char *) NULL);
- } else {
- if (year < 1100) {
- /* I'm not going to handle 1100 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- /* year 1100 to 1999. will anybody need this?!? */
- snprintf(fn,sizeof(fn), "digits/%d", (year / 100) );
- res = wait_file(chan, ints, fn, lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/hundred", lang);
- if (!res && year % 100 != 0) {
- res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
- }
- }
- }
- }
- }
- return res;
-}
-
-/* German syntax */
-int ast_say_date_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- ast_localtime(&t,&tm,NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res) {
- /* Year */
- int year = tm.tm_year + 1900;
- if (year > 1999) { /* year 2000 and later */
- res = ast_say_number(chan, year, ints, lang, (char *) NULL);
- } else {
- if (year < 1100) {
- /* I'm not going to handle 1100 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- /* year 1100 to 1999. will anybody need this?!? */
- /* say 1967 as 'neunzehn hundert sieben und sechzig' */
- snprintf(fn,sizeof(fn), "digits/%d", (year / 100) );
- res = wait_file(chan, ints, fn, lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/hundred", lang);
- if (!res && year % 100 != 0) {
- res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
- }
- }
- }
- }
- }
- return res;
-}
-
-/* French syntax */
-int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- ast_localtime(&t,&tm,NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-/* Dutch syntax */
-int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- ast_localtime(&t,&tm,NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-/* Portuguese syntax */
-int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- if (!res)
- res = wait_file(chan, ints, fn, lang);
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-de", lang);
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- if (!res)
- res = wait_file(chan, ints, fn, lang);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-de", lang);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
-
- return res;
-}
-
-static int say_date_with_format(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- if (!strcasecmp(lang, "en") ) { /* English syntax */
- return(ast_say_date_with_format_en(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "da") ) { /* Danish syntax */
- return(ast_say_date_with_format_da(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "de") ) { /* German syntax */
- return(ast_say_date_with_format_de(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "es") || !strcasecmp(lang, "mx")) { /* Spanish syntax */
- return(ast_say_date_with_format_es(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "he")) { /* Hebrew syntax */
- return(ast_say_date_with_format_he(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "fr") ) { /* French syntax */
- return(ast_say_date_with_format_fr(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "it") ) { /* Italian syntax */
- return(ast_say_date_with_format_it(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */
- return(ast_say_date_with_format_nl(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "pl") ) { /* Polish syntax */
- return(ast_say_date_with_format_pl(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "pt_BR")) { /* Portuguese syntax */
- return(ast_say_date_with_format_pt(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "tw") || !strcasecmp(lang, "zh") ) { /* Taiwanese / Chinese syntax */
- return(ast_say_date_with_format_tw(chan, time, ints, lang, format, timezone));
- } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
- return(ast_say_date_with_format_gr(chan, time, ints, lang, format, timezone));
- }
-
- /* Default to English */
- return(ast_say_date_with_format_en(chan, time, ints, lang, format, timezone));
-}
-
-/* English syntax */
-int ast_say_date_with_format_en(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "ABdY 'digits/at' IMp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* Month enumerated */
- res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char *) NULL);
- break;
- case 'Y':
- /* Year */
- if (tm.tm_year > 99) {
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- } else if (tm.tm_year < 1) {
- /* I'm not going to handle 1900 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- res = wait_file(chan, ints, "digits/19", lang);
- if (!res) {
- if (tm.tm_year <= 9) {
- /* 1901 - 1909 */
- res = wait_file(chan,ints, "digits/oh", lang);
- }
-
- res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- if (format[offset] == 'H') {
- /* e.g. oh-eight */
- if (tm.tm_hour < 10) {
- res = wait_file(chan,ints, "digits/oh",lang);
- }
- } else {
- /* e.g. eight */
- if (tm.tm_hour == 0) {
- res = wait_file(chan,ints, "digits/oh",lang);
- }
- }
- if (!res) {
- if (tm.tm_hour != 0) {
- int remainder = tm.tm_hour;
- if (tm.tm_hour > 20) {
- res = wait_file(chan,ints, "digits/20",lang);
- remainder -= 20;
- }
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- break;
- case 'M':
- case 'N':
- /* Minute */
- if (tm.tm_min == 0) {
- if (format[offset] == 'M') {
- res = wait_file(chan, ints, "digits/oclock", lang);
- } else {
- res = wait_file(chan, ints, "digits/hundred", lang);
- }
- } else if (tm.tm_min < 10) {
- res = wait_file(chan,ints, "digits/oh",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else {
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- }
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "A", timezone);
- } else if (beg_today - 2628000 < time) {
- /* Less than a month ago - "Sunday, October third" */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "ABd", timezone);
- } else if (beg_today - 15768000 < time) {
- /* Less than 6 months ago - "August seventh" */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "Bd", timezone);
- } else {
- /* More than 6 months ago - "April nineteenth two thousand three" */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "BdY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "A", timezone);
- } else if (beg_today - 2628000 < time) {
- /* Less than a month ago - "Sunday, October third" */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "ABd", timezone);
- } else if (beg_today - 15768000 < time) {
- /* Less than 6 months ago - "August seventh" */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "Bd", timezone);
- } else {
- /* More than 6 months ago - "April nineteenth two thousand three" */
- res = ast_say_date_with_format_en(chan, time, ints, lang, "BdY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_en(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- if (tm.tm_sec == 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else if (tm.tm_sec < 10) {
- res = wait_file(chan,ints, "digits/oh",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else {
- res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
- }
- break;
- case 'T':
- res = ast_say_date_with_format_en(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* Danish syntax */
-int ast_say_date_with_format_da(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (!format)
- format = "A dBY HMS";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* Month enumerated */
- res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
- break;
- case 'Y':
- /* Year */
- {
- int year = tm.tm_year + 1900;
- if (year > 1999) { /* year 2000 and later */
- res = ast_say_number(chan, year, ints, lang, (char *) NULL);
- } else {
- if (year < 1100) {
- /* I'm not going to handle 1100 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- /* year 1100 to 1999. will anybody need this?!? */
- /* say 1967 as 'nineteen hundred seven and sixty' */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (year / 100) );
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/hundred",lang);
- if (!res && year % 100 != 0) {
- res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
- }
- }
- }
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- res = wait_file(chan,ints,"digits/oclock",lang);
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- if (!res) {
- res = wait_file(chan,ints,nextmsg,lang);
- }
- break;
- case 'H':
- /* 24-Hour, single digit hours preceeded by "oh" (0) */
- if (tm.tm_hour < 10 && tm.tm_hour > 0) {
- res = wait_file(chan,ints, "digits/0",lang);
- }
- /* FALLTRHU */
- case 'k':
- /* 24-Hour */
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
- break;
- case 'M':
- /* Minute */
- if (tm.tm_min > 0 || format[offset+ 1 ] == 'S' ) { /* zero 'digits/0' only if seconds follow (kind of a hack) */
- res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
- }
- if ( !res && format[offset + 1] == 'S' ) { /* minutes only if seconds follow (kind of a hack) */
- if (tm.tm_min == 1) {
- res = wait_file(chan,ints,"digits/minute",lang);
- } else {
- res = wait_file(chan,ints,"digits/minutes",lang);
- }
- }
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or AdBY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_da(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_da(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_da(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_da(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- res = wait_file(chan,ints, "digits/and",lang);
- if (!res) {
- res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
- if (!res) {
- res = wait_file(chan,ints, "digits/seconds",lang);
- }
- }
- break;
- case 'T':
- res = ast_say_date_with_format_da(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* German syntax */
-int ast_say_date_with_format_de(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (!format)
- format = "A dBY HMS";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* Month enumerated */
- res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
- break;
- case 'Y':
- /* Year */
- {
- int year = tm.tm_year + 1900;
- if (year > 1999) { /* year 2000 and later */
- res = ast_say_number(chan, year, ints, lang, (char *) NULL);
- } else {
- if (year < 1100) {
- /* I'm not going to handle 1100 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- /* year 1100 to 1999. will anybody need this?!? */
- /* say 1967 as 'neunzehn hundert sieben und sechzig' */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (year / 100) );
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/hundred",lang);
- if (!res && year % 100 != 0) {
- res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
- }
- }
- }
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- res = wait_file(chan,ints,"digits/oclock",lang);
- }
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
- if (!res) {
- res = wait_file(chan,ints,"digits/oclock",lang);
- }
- break;
- case 'M':
- /* Minute */
- if (tm.tm_min > 0 || format[offset+ 1 ] == 'S' ) { /* zero 'digits/0' only if seconds follow (kind of a hack) */
- res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
- }
- if ( !res && format[offset + 1] == 'S' ) { /* minutes only if seconds follow (kind of a hack) */
- if (tm.tm_min == 1) {
- res = wait_file(chan,ints,"digits/minute",lang);
- } else {
- res = wait_file(chan,ints,"digits/minutes",lang);
- }
- }
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or AdBY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_de(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_de(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_de(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_de(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- res = wait_file(chan,ints, "digits/and",lang);
- if (!res) {
- res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
- if (!res) {
- res = wait_file(chan,ints, "digits/seconds",lang);
- }
- }
- break;
- case 'T':
- res = ast_say_date_with_format_de(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* TODO: this probably is not the correct format for doxygen remarks */
-
-/** ast_say_date_with_format_he Say formmated date in Hebrew
- *
- * \ref ast_say_date_with_format_en for the details of the options
- *
- * Changes from the English version:
- *
- * * don't replicate in here the logic of ast_say_number_full_he
- *
- * * year is always 4-digit (because it's simpler)
- *
- * * added c, x, and X. Mainly for my tests
- *
- * * The standard "long" format used in Hebrew is AdBY, rather than ABdY
- *
- * TODO:
- * * A "ha" is missing in the standard date format, before the 'd'.
- * * The numbers of 3000--19000 are not handled well
- **/
-#define IL_DATE_STR "AdBY"
-#define IL_TIME_STR "IMp"
-#define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
-int ast_say_date_with_format_he(struct ast_channel *chan, time_t time,
- const char *ints, const char *lang, const char *format,
- const char *timezone)
-{
- /* TODO: This whole function is cut&paste from
- * ast_say_date_with_format_en . Is that considered acceptable?
- **/
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (!format)
- format = IL_DATE_STR_FULL;
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e': /* Day of the month */
- /* I'm not sure exactly what the parameters
- * audiofd and ctrlfd to
- * ast_say_number_full_he mean, but it seems
- * safe to pass -1 there.
- *
- * At least in one of the pathes :-(
- */
- res = ast_say_number_full_he(chan, tm.tm_mday,
- ints, lang, "m", -1, -1
- );
- break;
- case 'Y': /* Year */
- res = ast_say_number_full_he(chan, tm.tm_year+1900,
- ints, lang, "f", -1, -1
- );
- break;
- case 'I':
- case 'l': /* 12-Hour */
- {
- int hour = tm.tm_hour;
- hour = hour%12;
- if (hour == 0) hour=12;
-
- res = ast_say_number_full_he(chan, hour,
- ints, lang, "f", -1, -1
- );
- }
- break;
- case 'H':
- case 'k': /* 24-Hour */
- /* With 'H' there is an 'oh' after a single-
- * digit hour */
- if ((format[offset] == 'H') &&
- (tm.tm_hour <10)&&(tm.tm_hour>0)
- ) { /* e.g. oh-eight */
- res = wait_file(chan,ints, "digits/oh",lang);
- }
-
- res = ast_say_number_full_he(chan, tm.tm_hour,
- ints, lang, "f", -1, -1
- );
- break;
- case 'M': /* Minute */
- res = ast_say_number_full_he(chan, tm.tm_min,
- ints, lang,"f", -1, -1
- );
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or "date" */
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A
- * (weekday), or "date" */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
- char todo = format[offset]; /* The letter to format*/
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- if (todo == 'Q') {
- res = wait_file(chan,
- ints,
- "digits/today",
- lang);
- }
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if ((todo != 'Q') &&
- (beg_today - 86400 * 6 < time))
- {
- /* Within the last week */
- res = ast_say_date_with_format_he(chan,
- time, ints, lang,
- "A", timezone);
- } else {
- res = ast_say_date_with_format_he(chan,
- time, ints, lang,
- IL_DATE_STR, timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_he(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S': /* Seconds */
- res = ast_say_number_full_he(chan, tm.tm_sec,
- ints, lang, "f", -1, -1
- );
- break;
- case 'T':
- res = ast_say_date_with_format_he(chan, time, ints, lang, "HMS", timezone);
- break;
- /* c, x, and X seem useful for testing. Not sure
- * if thiey're good for the general public */
- case 'c':
- res = ast_say_date_with_format_he(chan, time,
- ints, lang, IL_DATE_STR_FULL, timezone);
- break;
- case 'x':
- res = ast_say_date_with_format_he(chan, time,
- ints, lang, IL_DATE_STR, timezone);
- break;
- case 'X': /* Currently not locale-dependent...*/
- res = ast_say_date_with_format_he(chan, time,
- ints, lang, IL_TIME_STR, timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-
-/* Spanish syntax */
-int ast_say_date_with_format_es(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- snprintf(nextmsg,sizeof(nextmsg), "%s", sndfile);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* First - Twelfth */
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- break;
- case 'Y':
- /* Year */
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- res = ast_say_number(chan, tm.tm_hour, ints, lang, NULL);
- break;
- case 'M':
- /* Minute */
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 18)
- res = wait_file(chan, ints, "digits/p-m", lang);
- else if (tm.tm_hour > 12)
- res = wait_file(chan, ints, "digits/afternoon", lang);
- else if (tm.tm_hour)
- res = wait_file(chan, ints, "digits/a-m", lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_es(chan, time, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_es(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_es(chan, time, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_es(chan, time, ints, lang, "H 'digits/y' M", timezone);
- break;
- case 'S':
- /* Seconds */
- if (tm.tm_sec == 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else if (tm.tm_sec < 10) {
- res = wait_file(chan,ints, "digits/oh",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- int ten, one;
- ten = (tm.tm_sec / 10) * 10;
- one = (tm.tm_sec % 10);
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- /* Fifty, not fifty-zero */
- if (one != 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- break;
- case 'T':
- res = ast_say_date_with_format_es(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* French syntax
-oclock = heure
-*/
-int ast_say_date_with_format_fr(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "AdBY 'digits/at' IMp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* First - Twelfth */
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e':
- /* First */
- if (tm.tm_mday == 1) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
- }
- break;
- case 'Y':
- /* Year */
- if (tm.tm_year > 99) {
- res = wait_file(chan,ints, "digits/2",lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/thousand",lang);
- }
- if (tm.tm_year > 100) {
- if (!res) {
- res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
- }
- }
- } else {
- if (tm.tm_year < 1) {
- /* I'm not going to handle 1900 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- res = wait_file(chan,ints, "digits/thousand",lang);
- if (!res) {
- wait_file(chan,ints, "digits/9",lang);
- wait_file(chan,ints, "digits/hundred",lang);
- res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
- }
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res)
- res = wait_file(chan,ints, "digits/oclock",lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
- if (!res)
- res = wait_file(chan,ints, "digits/oclock",lang);
- break;
- case 'M':
- /* Minute */
- if (tm.tm_min == 0) {
- break;
- }
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or AdBY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_fr(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_fr(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_fr(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_fr(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
- if (!res) {
- res = wait_file(chan,ints, "digits/second",lang);
- }
- break;
- case 'T':
- res = ast_say_date_with_format_fr(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-int ast_say_date_with_format_it(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "AdB 'digits/at' IMp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* First - Twelfth */
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e':
- /* First day of the month is spelled as ordinal */
- if (tm.tm_mday == 1) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- if (!res) {
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- }
- }
- break;
- case 'Y':
- /* Year */
- if (tm.tm_year > 99) {
- res = wait_file(chan,ints, "digits/ore-2000",lang);
- if (tm.tm_year > 100) {
- if (!res) {
- /* This works until the end of 2021 */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- } else {
- if (tm.tm_year < 1) {
- /* I'm not going to handle 1900 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- res = wait_file(chan,ints, "digits/ore-1900",lang);
- if ((!res) && (tm.tm_year != 0)) {
- if (tm.tm_year <= 21) {
- /* 1910 - 1921 */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- /* 1922 - 1999, but sounds badly in 1928, 1931, 1938, etc... */
- int ten, one;
- ten = tm.tm_year / 10;
- one = tm.tm_year % 10;
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- if (one != 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- }
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- if (tm.tm_hour == 0) {
- res = wait_file(chan,ints, "digits/ore-mezzanotte",lang);
- } else if (tm.tm_hour == 1) {
- res = wait_file(chan,ints, "digits/ore-una",lang);
- } else {
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
- }
- break;
- case 'M':
- /* Minute */
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_it(chan, time, ints, lang, "AdB", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_it(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_it(chan, time, ints, lang, "AdB", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_it(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- if (tm.tm_sec == 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else if (tm.tm_sec < 10) {
- res = wait_file(chan,ints, "digits/oh",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- int ten, one;
- ten = (tm.tm_sec / 10) * 10;
- one = (tm.tm_sec % 10);
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- /* Fifty, not fifty-zero */
- if (one != 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- break;
- case 'T':
- res = ast_say_date_with_format_it(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* Dutch syntax */
-int ast_say_date_with_format_nl(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "ABdY 'digits/at' IMp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* First - Twelfth */
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
- break;
- case 'Y':
- /* Year */
- if (tm.tm_year > 99) {
- res = wait_file(chan,ints, "digits/2",lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/thousand",lang);
- }
- if (tm.tm_year > 100) {
- if (!res) {
- /* This works until the end of 2020 */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- } else {
- if (tm.tm_year < 1) {
- /* I'm not going to handle 1900 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- res = wait_file(chan,ints, "digits/19",lang);
- if (!res) {
- if (tm.tm_year <= 9) {
- /* 1901 - 1909 */
- res = wait_file(chan,ints, "digits/oh",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else if (tm.tm_year <= 20) {
- /* 1910 - 1920 */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- /* 1921 - 1999 */
- int ten, one;
- ten = tm.tm_year / 10;
- one = tm.tm_year % 10;
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- if (one != 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- }
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
- if (!res) {
- res = wait_file(chan,ints, "digits/nl-uur",lang);
- }
- break;
- case 'M':
- /* Minute */
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_nl(chan, time, ints, lang, "ABdY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_nl(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_nl(chan, time, ints, lang, "ABdY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_nl(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
- break;
- case 'T':
- res = ast_say_date_with_format_nl(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* Polish syntax */
-int ast_say_date_with_format_pl(struct ast_channel *chan, time_t thetime, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- ast_localtime(&thetime, &tm, timezone);
-
- for (offset = 0 ; format[offset] != '\0' ; offset++) {
- int remainder;
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset = 0;
- for (sndoffset = 0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan, ints, sndfile, lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan, ints, nextmsg, lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan, ints, nextmsg, lang);
- break;
- case 'm':
- /* Month enumerated */
- res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- remainder = tm.tm_mday;
- if (tm.tm_mday > 30) {
- res = wait_file(chan, ints, "digits/h-30", lang);
- remainder -= 30;
- }
- if (tm.tm_mday > 20 && tm.tm_mday < 30) {
- res = wait_file(chan, ints, "digits/h-20", lang);
- remainder -= 20;
- }
- if (!res) {
- snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remainder);
- res = wait_file(chan, ints, nextmsg, lang);
- }
- break;
- case 'Y':
- /* Year */
- if (tm.tm_year > 100) {
- res = wait_file(chan, ints, "digits/2", lang);
- if (!res)
- res = wait_file(chan, ints, "digits/1000.2",lang);
- if (tm.tm_year > 100) {
- if (!res)
- res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
- }
- } else if (tm.tm_year == 100) {
- res = wait_file(chan, ints, "digits/h-2000", lang);
- } else {
- if (tm.tm_year < 1) {
- /* I'm not going to handle 1900 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- break;
- } else {
- res = wait_file(chan, ints, "digits/1000", lang);
- if (!res) {
- wait_file(chan, ints, "digits/900", lang);
- res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
- }
- }
- }
- if (!res)
- wait_file(chan, ints, "digits/year", lang);
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg, sizeof(nextmsg), "digits/t-12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
-
- res = wait_file(chan, ints, nextmsg, lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- if (tm.tm_hour != 0) {
- snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
- res = wait_file(chan, ints, nextmsg, lang);
- } else
- res = wait_file(chan, ints, "digits/t-24", lang);
- break;
- case 'M':
- case 'N':
- /* Minute */
- if (tm.tm_min == 0) {
- if (format[offset] == 'M') {
- res = wait_file(chan, ints, "digits/oclock", lang);
- } else {
- res = wait_file(chan, ints, "digits/100", lang);
- }
- } else
- res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg, sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg, sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan, ints, nextmsg, lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or AdBY */
- {
- time_t tv_sec = time(NULL);
- struct tm tmnow;
- time_t beg_today;
-
- ast_localtime(&tv_sec,&tmnow, timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < thetime) {
- /* Today */
- res = wait_file(chan, ints, "digits/today", lang);
- } else if (beg_today - 86400 < thetime) {
- /* Yesterday */
- res = wait_file(chan, ints, "digits/yesterday", lang);
- } else {
- res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
- {
- time_t tv_sec = time(NULL);
- struct tm tmnow;
- time_t beg_today;
-
- ast_localtime(&tv_sec, &tmnow, timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < thetime) {
- /* Today */
- } else if ((beg_today - 86400) < thetime) {
- /* Yesterday */
- res = wait_file(chan, ints, "digits/yesterday", lang);
- } else if (beg_today - 86400 * 6 < thetime) {
- /* Within the last week */
- res = ast_say_date_with_format(chan, thetime, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- res = wait_file(chan, ints, "digits/and", lang);
- if (!res) {
- if (tm.tm_sec == 1) {
- res = wait_file(chan, ints, "digits/1z", lang);
- if (!res)
- res = wait_file(chan, ints, "digits/second-a", lang);
- } else {
- res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
- if (!res) {
- int ten, one;
- ten = tm.tm_sec / 10;
- one = tm.tm_sec % 10;
-
- if (one > 1 && one < 5 && ten != 1)
- res = wait_file(chan,ints, "digits/seconds",lang);
- else
- res = wait_file(chan,ints, "digits/second",lang);
- }
- }
- }
- break;
- case 'T':
- res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res)
- break;
- }
- return res;
-}
-
-/* Portuguese syntax */
-int ast_say_date_with_format_pt(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- snprintf(nextmsg,sizeof(nextmsg), "%s", sndfile);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'm':
- /* First - Twelfth */
- if (!strcasecmp(lang, "pt_BR")) {
- res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
- } else {
- snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- break;
- case 'Y':
- /* Year */
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (!strcasecmp(lang, "pt_BR")) {
- if (tm.tm_hour == 0) {
- if (format[offset] == 'I')
- res = wait_file(chan, ints, "digits/pt-a", lang);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-meianoite", lang);
- } else if (tm.tm_hour == 12) {
- if (format[offset] == 'I')
- res = wait_file(chan, ints, "digits/pt-ao", lang);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-meiodia", lang);
- } else {
- if (format[offset] == 'I') {
- if ((tm.tm_hour % 12) != 1)
- res = wait_file(chan, ints, "digits/pt-as", lang);
- else
- res = wait_file(chan, ints, "digits/pt-a", lang);
- }
- if (!res)
- res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
- }
- } else {
- if (tm.tm_hour == 0) {
- if (format[offset] == 'I')
- res = wait_file(chan, ints, "digits/pt-ah", lang);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-meianoite", lang);
- }
- else if (tm.tm_hour == 12) {
- if (format[offset] == 'I')
- res = wait_file(chan, ints, "digits/pt-ao", lang);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-meiodia", lang);
- }
- else {
- if (format[offset] == 'I') {
- res = wait_file(chan, ints, "digits/pt-ah", lang);
- if ((tm.tm_hour % 12) != 1)
- if (!res)
- res = wait_file(chan, ints, "digits/pt-sss", lang);
- }
- if (!res)
- res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
- }
- }
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- if (!strcasecmp(lang, "pt_BR")) {
- res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
- if ((!res) && (format[offset] == 'H')) {
- if (tm.tm_hour > 1) {
- res = wait_file(chan,ints,"digits/hours",lang);
- } else {
- res = wait_file(chan,ints,"digits/hour",lang);
- }
- }
- } else {
- res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
- if (!res) {
- if (tm.tm_hour != 0) {
- int remainder = tm.tm_hour;
- if (tm.tm_hour > 20) {
- res = wait_file(chan,ints, "digits/20",lang);
- remainder -= 20;
- }
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- }
- break;
- case 'M':
- /* Minute */
- if (!strcasecmp(lang, "pt_BR")) {
- res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
- if (!res) {
- if (tm.tm_min > 1) {
- res = wait_file(chan,ints,"digits/minutes",lang);
- } else {
- res = wait_file(chan,ints,"digits/minute",lang);
- }
- }
- } else {
- if (tm.tm_min == 0) {
- res = wait_file(chan, ints, "digits/pt-hora", lang);
- if (tm.tm_hour != 1)
- if (!res)
- res = wait_file(chan, ints, "digits/pt-sss", lang);
- } else {
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- }
- }
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (!strcasecmp(lang, "pt_BR")) {
- if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
- res = wait_file(chan, ints, "digits/pt-da", lang);
- if (!res) {
- if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
- res = wait_file(chan, ints, "digits/morning", lang);
- else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
- res = wait_file(chan, ints, "digits/afternoon", lang);
- else res = wait_file(chan, ints, "digits/night", lang);
- }
- }
- } else {
- if (tm.tm_hour > 12)
- res = wait_file(chan, ints, "digits/p-m", lang);
- else if (tm.tm_hour && tm.tm_hour < 12)
- res = wait_file(chan, ints, "digits/a-m", lang);
- }
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_pt(chan, time, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_pt(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_pt(chan, time, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_pt(chan, time, ints, lang, "H 'digits/pt-e' M", timezone);
- break;
- case 'S':
- /* Seconds */
- if (!strcasecmp(lang, "pt_BR")) {
- res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
- if (!res) {
- if (tm.tm_sec > 1) {
- res = wait_file(chan,ints,"digits/seconds",lang);
- } else {
- res = wait_file(chan,ints,"digits/second",lang);
- }
- } else if (tm.tm_sec < 10) {
- res = wait_file(chan,ints, "digits/oh",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- int ten, one;
- ten = (tm.tm_sec / 10) * 10;
- one = (tm.tm_sec % 10);
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- /* Fifty, not fifty-zero */
- if (one != 0) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- }
- break;
- case 'T':
- res = ast_say_date_with_format_pt(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-/* Taiwanese / Chinese syntax */
-int ast_say_date_with_format_tw(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (format == NULL)
- format = "YBdAkM";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- case 'm':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e':
- /* First - Thirtyfirst */
- if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- if (!res) res = wait_file(chan,ints,"digits/day",lang);
- break;
- case 'Y':
- /* Year */
- if (tm.tm_year > 99) {
- res = wait_file(chan,ints, "digits/2",lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/thousand",lang);
- }
- if (tm.tm_year > 100) {
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- if (!res) {
- res = wait_file(chan,ints, "digits/year",lang);
- }
- } else {
- if (tm.tm_year < 1) {
- /* I'm not going to handle 1900 and prior */
- /* We'll just be silent on the year, instead of bombing out. */
- } else {
- res = wait_file(chan,ints, "digits/1",lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/9",lang);
- }
- if (!res) {
- if (tm.tm_year <= 9) {
- /* 1901 - 1909 */
- res = wait_file(chan,ints, "digits/0",lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- } else {
- /* 1910 - 1999 */
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- }
- }
- if (!res) {
- res = wait_file(chan,ints, "digits/year",lang);
- }
- }
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- snprintf(nextmsg,sizeof(nextmsg), "digits/12");
- else if (tm.tm_hour > 12)
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- res = wait_file(chan,ints, "digits/oclock",lang);
- }
- break;
- case 'H':
- if (tm.tm_hour < 10) {
- res = wait_file(chan, ints, "digits/0", lang);
- }
- case 'k':
- /* 24-Hour */
- if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- if (!res) {
- res = wait_file(chan,ints, "digits/oclock",lang);
- }
- break;
- case 'M':
- /* Minute */
- if (!(tm.tm_min % 10) || tm.tm_min < 10) {
- if (tm.tm_min < 10) {
- res = wait_file(chan, ints, "digits/0", lang);
- }
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- if (!res) {
- res = wait_file(chan,ints, "digits/minute",lang);
- }
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_tw(chan, time, ints, lang, "YBdA", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_tw(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_tw(chan, time, ints, lang, "YBdA", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_tw(chan, time, ints, lang, "kM", timezone);
- break;
- case 'S':
- /* Seconds */
- if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
- if (tm.tm_sec < 10) {
- res = wait_file(chan, ints, "digits/0", lang);
- }
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
- res = wait_file(chan,ints,nextmsg,lang);
- } else {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res) {
- snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
- res = wait_file(chan,ints,nextmsg,lang);
- }
- }
- if (!res) {
- res = wait_file(chan,ints, "digits/second",lang);
- }
- break;
- case 'T':
- res = ast_say_date_with_format_tw(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- if (!strcasecmp(lang, "en") ) { /* English syntax */
- return(ast_say_time_en(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "de") ) { /* German syntax */
- return(ast_say_time_de(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "fr") ) { /* French syntax */
- return(ast_say_time_fr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */
- return(ast_say_time_nl(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
- return(ast_say_time_pt(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "pt_BR") ) { /* Brazilian Portuguese syntax */
- return(ast_say_time_pt_BR(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "tw") || !strcasecmp(lang, "zh") ) { /* Taiwanese / Chinese syntax */
- return(ast_say_time_tw(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
- return(ast_say_time_gr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
- return(ast_say_time_ge(chan, t, ints, lang));
- }
-
- /* Default to English */
- return(ast_say_time_en(chan, t, ints, lang));
-}
-
-/* English syntax */
-int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
- int hour, pm=0;
-
- ast_localtime(&t, &tm, NULL);
- hour = tm.tm_hour;
- if (!hour)
- hour = 12;
- else if (hour == 12)
- pm = 1;
- else if (hour > 12) {
- hour -= 12;
- pm = 1;
- }
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
-
- if (tm.tm_min > 9) {
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else if (tm.tm_min) {
- if (!res)
- res = ast_streamfile(chan, "digits/oh", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (pm) {
- if (!res)
- res = ast_streamfile(chan, "digits/p-m", lang);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/a-m", lang);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- return res;
-}
-
-/* German syntax */
-int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- if (!res)
- res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- if (tm.tm_min > 0)
- res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
- return res;
-}
-
-/* French syntax */
-int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
-
- res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (tm.tm_min) {
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- }
- return res;
-}
-
-/* Dutch syntax */
-int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- if (!res)
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
- if (!res)
- res = ast_streamfile(chan, "digits/nl-uur", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- if (tm.tm_min > 0)
- res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
- return res;
-}
-
-/* Portuguese syntax */
-int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
- int hour;
-
- ast_localtime(&t, &tm, NULL);
- hour = tm.tm_hour;
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, "f");
- if (tm.tm_min) {
- if (!res)
- res = wait_file(chan, ints, "digits/pt-e", lang);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else {
- if (!res)
- res = wait_file(chan, ints, "digits/pt-hora", lang);
- if (tm.tm_hour != 1)
- if (!res)
- res = wait_file(chan, ints, "digits/pt-sss", lang);
- }
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
- return res;
-}
-
-/* Brazilian Portuguese syntax */
-int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
-
- res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
- if (!res) {
- if (tm.tm_hour > 1)
- res = wait_file(chan, ints, "digits/hours", lang);
- else
- res = wait_file(chan, ints, "digits/hour", lang);
- }
- if ((!res) && (tm.tm_min)) {
- res = wait_file(chan, ints, "digits/pt-e", lang);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- if (!res) {
- if (tm.tm_min > 1)
- res = wait_file(chan, ints, "digits/minutes", lang);
- else
- res = wait_file(chan, ints, "digits/minute", lang);
- }
- }
- return res;
-}
-
-/* Taiwanese / Chinese syntax */
-int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
- int hour, pm=0;
-
- ast_localtime(&t, &tm, NULL);
- hour = tm.tm_hour;
- if (!hour)
- hour = 12;
- else if (hour == 12)
- pm = 1;
- else if (hour > 12) {
- hour -= 12;
- pm = 1;
- }
- if (pm) {
- if (!res)
- res = ast_streamfile(chan, "digits/p-m", lang);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/a-m", lang);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- if (!res)
- res = ast_streamfile(chan, "digits/minute", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- return res;
-}
-
-static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- if (!strcasecmp(lang, "en") ) { /* English syntax */
- return(ast_say_datetime_en(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "de") ) { /* German syntax */
- return(ast_say_datetime_de(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "fr") ) { /* French syntax */
- return(ast_say_datetime_fr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */
- return(ast_say_datetime_nl(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "pt") ) { /* Portuguese syntax */
- return(ast_say_datetime_pt(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "pt_BR") ) { /* Brazilian Portuguese syntax */
- return(ast_say_datetime_pt_BR(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "tw") || !strcasecmp(lang, "zh") ) { /* Taiwanese / Chinese syntax */
- return(ast_say_datetime_tw(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
- return(ast_say_datetime_gr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
- return(ast_say_datetime_ge(chan, t, ints, lang));
- }
-
- /* Default to English */
- return(ast_say_datetime_en(chan, t, ints, lang));
-}
-
-/* English syntax */
-int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- int hour, pm=0;
-
- ast_localtime(&t, &tm, NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
-
- hour = tm.tm_hour;
- if (!hour)
- hour = 12;
- else if (hour == 12)
- pm = 1;
- else if (hour > 12) {
- hour -= 12;
- pm = 1;
- }
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
-
- if (tm.tm_min > 9) {
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else if (tm.tm_min) {
- if (!res)
- res = ast_streamfile(chan, "digits/oh", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (pm) {
- if (!res)
- res = ast_streamfile(chan, "digits/p-m", lang);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/a-m", lang);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-/* German syntax */
-int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- res = ast_say_date(chan, t, ints, lang);
- if (!res)
- ast_say_time(chan, t, ints, lang);
- return res;
-
-}
-
-/* French syntax */
-int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
-
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
-
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
-
- if (!res)
- res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (tm.tm_min > 0) {
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-/* Dutch syntax */
-int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- res = ast_say_date(chan, t, ints, lang);
- if (!res) {
- res = ast_streamfile(chan, "digits/nl-om", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- ast_say_time(chan, t, ints, lang);
- return res;
-}
-
-/* Portuguese syntax */
-int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- int hour, pm=0;
-
- ast_localtime(&t, &tm, NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
-
- hour = tm.tm_hour;
- if (!hour)
- hour = 12;
- else if (hour == 12)
- pm = 1;
- else if (hour > 12) {
- hour -= 12;
- pm = 1;
- }
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
-
- if (tm.tm_min > 9) {
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else if (tm.tm_min) {
- if (!res)
- res = ast_streamfile(chan, "digits/oh", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (pm) {
- if (!res)
- res = ast_streamfile(chan, "digits/p-m", lang);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/a-m", lang);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-/* Brazilian Portuguese syntax */
-int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- res = ast_say_date(chan, t, ints, lang);
- if (!res)
- res = ast_say_time(chan, t, ints, lang);
- return res;
-}
-
-/* Taiwanese / Chinese syntax */
-int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- int hour, pm=0;
-
- ast_localtime(&t, &tm, NULL);
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
-
- hour = tm.tm_hour;
- if (!hour)
- hour = 12;
- else if (hour == 12)
- pm = 1;
- else if (hour > 12) {
- hour -= 12;
- pm = 1;
- }
- if (pm) {
- if (!res)
- res = ast_streamfile(chan, "digits/p-m", lang);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/a-m", lang);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- if (!res)
- res = ast_streamfile(chan, "digits/minute", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- return res;
-}
-
-static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- if (!strcasecmp(lang, "en") ) { /* English syntax */
- return(ast_say_datetime_from_now_en(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "fr") ) { /* French syntax */
- return(ast_say_datetime_from_now_fr(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "pt_BR")) { /* Portuguese syntax */
- return(ast_say_datetime_from_now_pt(chan, t, ints, lang));
- } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
- return(ast_say_datetime_from_now_ge(chan, t, ints, lang));
- }
-
- /* Default to English */
- return(ast_say_datetime_from_now_en(chan, t, ints, lang));
-}
-
-/* English syntax */
-int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- int res=0;
- time_t nowt;
- int daydiff;
- struct tm tm;
- struct tm now;
- char fn[256];
-
- time(&nowt);
-
- ast_localtime(&t, &tm, NULL);
- ast_localtime(&nowt,&now, NULL);
- daydiff = now.tm_yday - tm.tm_yday;
- if ((daydiff < 0) || (daydiff > 6)) {
- /* Day of month and month */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
-
- } else if (daydiff) {
- /* Just what day of the week */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- } /* Otherwise, it was today */
- if (!res)
- res = ast_say_time(chan, t, ints, lang);
- return res;
-}
-
-/* French syntax */
-int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- int res=0;
- time_t nowt;
- int daydiff;
- struct tm tm;
- struct tm now;
- char fn[256];
-
- time(&nowt);
-
- ast_localtime(&t, &tm, NULL);
- ast_localtime(&nowt, &now, NULL);
- daydiff = now.tm_yday - tm.tm_yday;
- if ((daydiff < 0) || (daydiff > 6)) {
- /* Day of month and month */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
-
- } else if (daydiff) {
- /* Just what day of the week */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- } /* Otherwise, it was today */
- if (!res)
- res = ast_say_time(chan, t, ints, lang);
- return res;
-}
-
-/* Portuguese syntax */
-int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- int res=0;
- time_t nowt;
- int daydiff;
- struct tm tm;
- struct tm now;
- char fn[256];
-
- time(&nowt);
-
- ast_localtime(&t, &tm, NULL);
- ast_localtime(&nowt, &now, NULL);
- daydiff = now.tm_yday - tm.tm_yday;
- if ((daydiff < 0) || (daydiff > 6)) {
- /* Day of month and month */
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- if (!res)
- res = wait_file(chan, ints, "digits/pt-de", lang);
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- if (!res)
- res = wait_file(chan, ints, fn, lang);
-
- } else if (daydiff) {
- /* Just what day of the week */
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- if (!res)
- res = wait_file(chan, ints, fn, lang);
- } /* Otherwise, it was today */
- if (!strcasecmp(lang, "pt_BR")) {
- if (tm.tm_hour > 1) {
- snprintf(fn, sizeof(fn), "digits/pt-as");
- } else {
- snprintf(fn, sizeof(fn), "digits/pt-a");
- }
- if (!res)
- res = wait_file(chan, ints, fn, lang);
- } else {
- snprintf(fn, sizeof(fn), "digits/pt-ah");
- if (!res)
- res = wait_file(chan, ints, fn, lang);
- if (tm.tm_hour != 1)
- if (!res)
- res = wait_file(chan, ints, "digits/pt-sss", lang);
- if (!res)
- res = ast_say_time(chan, t, ints, lang);
- }
- return res;
-}
-
-
-/*********************************** GREEK SUPPORT ***************************************/
-
-
-/*
- * digits/female-[1..4] : "Mia, dyo , treis, tessereis"
- */
-static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang){
- int tmp;
- int left;
- int res;
- char fn[256] = "";
-
- /* ast_log(LOG_DEBUG, "\n\n Saying number female %s %d \n\n",lang, num); */
- if (num < 5) {
- snprintf(fn, sizeof(fn), "digits/female-%d", num);
- res = wait_file(chan, ints, fn, lang);
- } else if (num < 13) {
- res = ast_say_number(chan, num, ints, lang, (char *) NULL);
- } else if (num <100 ) {
- tmp = (num/10) * 10;
- left = num - tmp;
- snprintf(fn, sizeof(fn), "digits/%d", tmp);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (left)
- gr_say_number_female(left, chan, ints, lang);
-
- } else {
- return -1;
- }
- return res;
-}
-
-
-
-/*
- * A list of the files that you need to create
- -> digits/xilia = "xilia"
- -> digits/myrio = "ekatomyrio"
- -> digits/thousands = "xiliades"
- -> digits/millions = "ektatomyria"
- -> digits/[1..12] :: A pronunciation of th digits form 1 to 12 e.g. "tria"
- -> digits/[10..100] :: A pronunciation of the tens from 10 to 90
- e,g 80 = "ogdonta"
- Here we must note that we use digits/tens/100 to utter "ekato"
- and digits/hundred-100 to utter "ekaton"
- -> digits/hundred-[100...1000] :: A pronunciation of hundreds from 100 to 1000 e.g 400 =
- "terakosia". Here again we use hundreds/1000 for "xilia"
- and digits/thousnds for "xiliades"
-*/
-
-static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language,int audiofd, int ctrlfd)
-{
- int res = 0;
- char fn[256] = "";
- int i=0;
-
-
- if (!num) {
- snprintf(fn, sizeof(fn), "digits/0");
- res = ast_streamfile(chan, fn, chan->language);
- if (!res)
- return ast_waitstream(chan, ints);
- }
-
- while (!res && num ) {
- i++;
- if (num < 13) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
- num = 0;
- } else if (num <= 100) {
- /* 13 < num <= 100 */
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else if (num < 200) {
- /* 100 < num < 200 */
- snprintf(fn, sizeof(fn), "digits/hundred-100");
- num -= ((num / 100) * 100);
- } else if (num < 1000) {
- /* 200 < num < 1000 */
- snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
- num -= ((num / 100) * 100);
- } else if (num < 2000){
- snprintf(fn, sizeof(fn), "digits/xilia");
- num -= ((num / 1000) * 1000);
- } else {
- /* num > 1000 */
- if (num < 1000000) {
- res = ast_say_number_full_gr(chan, (num / 1000), ints, chan->language, audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousands");
- } else {
- if (num < 1000000000) { /* 1,000,000,000 */
- res = ast_say_number_full_gr(chan, (num / 1000000), ints, chan->language ,audiofd, ctrlfd);
- if (res)
- return res;
- num = num % 1000000;
- snprintf(fn, sizeof(fn), "digits/millions");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
- }
- if (!res) {
- if (!ast_streamfile(chan, fn, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
- }
- }
- return res;
-}
-
-
-/*
- * The format is weekday - day - month -year
- *
- * A list of the files that you need to create
- * digits/day-[1..7] : "Deytera .. Paraskeyh"
- * digits/months/1..12 : "Ianouariou .. Dekembriou"
- Attention the months are in
- "gekinh klhsh"
- */
-
-
-static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
-
- char fn[256];
- int res = 0;
-
-
- ast_localtime(&t,&tm,NULL);
- /* W E E K - D A Y */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- /* D A Y */
- if (!res) {
- gr_say_number_female(tm.tm_mday, chan, ints, lang);
- }
- /* M O N T H */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- /* Y E A R */
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
- return res;
-}
-
-
-
-/* A list of the files that you need to create
- * digits/female/1..4 : "Mia, dyo , treis, tesseris "
- * digits/kai : "KAI"
- * didgits : "h wra"
- * digits/p-m : "meta meshmbrias"
- * digits/a-m : "pro meshmbrias"
- */
-
-static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
-
- struct tm tm;
- int res = 0;
- int hour, pm=0;
-
- ast_localtime(&t, &tm, NULL);
- hour = tm.tm_hour;
-
- if (!hour)
- hour = 12;
- else if (hour == 12)
- pm = 1;
- else if (hour > 12) {
- hour -= 12;
- pm = 1;
- }
-
- res = gr_say_number_female(hour, chan, ints, lang);
- if (tm.tm_min) {
- if (!res)
- res = ast_streamfile(chan, "digits/kai", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/hwra", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- if (pm) {
- if (!res)
- res = ast_streamfile(chan, "digits/p-m", lang);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/a-m", lang);
- }
- if (!res)
- res = ast_waitstream(chan, ints);
- return res;
-}
-
-
-
-static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
-
-
- /* W E E K - D A Y */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- /* D A Y */
- if (!res) {
- gr_say_number_female(tm.tm_mday, chan, ints, lang);
- }
- /* M O N T H */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
-
- res = ast_say_time_gr(chan, t, ints, lang);
- return res;
-}
-
-static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
-{
-
- struct tm tm;
- int res=0, offset, sndoffset;
- char sndfile[256], nextmsg[256];
-
- if (!format)
- format = "AdBY 'digits/at' IMp";
-
- ast_localtime(&time,&tm,timezone);
-
- for (offset=0 ; format[offset] != '\0' ; offset++) {
- ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
- switch (format[offset]) {
- /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
- case '\'':
- /* Literal name of a sound file */
- sndoffset=0;
- for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
- sndfile[sndoffset] = format[offset];
- sndfile[sndoffset] = '\0';
- res = wait_file(chan,ints,sndfile,lang);
- break;
- case 'A':
- case 'a':
- /* Sunday - Saturday */
- snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'B':
- case 'b':
- case 'h':
- /* January - December */
- snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'd':
- case 'e':
- /* first - thirtyfirst */
- gr_say_number_female(tm.tm_mday, chan, ints, lang);
- break;
- case 'Y':
- /* Year */
-
- ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, chan->language, -1, -1);
- break;
- case 'I':
- case 'l':
- /* 12-Hour */
- if (tm.tm_hour == 0)
- gr_say_number_female(12, chan, ints, lang);
- else if (tm.tm_hour > 12)
- gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
- else
- gr_say_number_female(tm.tm_hour, chan, ints, lang);
- break;
- case 'H':
- case 'k':
- /* 24-Hour */
- gr_say_number_female(tm.tm_hour, chan, ints, lang);
- break;
- case 'M':
- /* Minute */
- if (tm.tm_min) {
- if (!res)
- res = ast_streamfile(chan, "digits/kai", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- if (!res)
- res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
- } else {
- if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- break;
- case 'P':
- case 'p':
- /* AM/PM */
- if (tm.tm_hour > 11)
- snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
- else
- snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'Q':
- /* Shorthand for "Today", "Yesterday", or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- res = wait_file(chan,ints, "digits/today",lang);
- } else if (beg_today - 86400 < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else {
- res = ast_say_date_with_format_gr(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'q':
- /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
- /* XXX As emphasized elsewhere, this should the native way in your
- * language to say the date, with changes in what you say, depending
- * upon how recent the date is. XXX */
- {
- struct timeval now;
- struct tm tmnow;
- time_t beg_today, tt;
-
- gettimeofday(&now,NULL);
- tt = now.tv_sec;
- ast_localtime(&tt,&tmnow,timezone);
- /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
- /* In any case, it saves not having to do ast_mktime() */
- beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
- if (beg_today < time) {
- /* Today */
- } else if ((beg_today - 86400) < time) {
- /* Yesterday */
- res = wait_file(chan,ints, "digits/yesterday",lang);
- } else if (beg_today - 86400 * 6 < time) {
- /* Within the last week */
- res = ast_say_date_with_format_gr(chan, time, ints, lang, "A", timezone);
- } else {
- res = ast_say_date_with_format_gr(chan, time, ints, lang, "AdBY", timezone);
- }
- }
- break;
- case 'R':
- res = ast_say_date_with_format_gr(chan, time, ints, lang, "HM", timezone);
- break;
- case 'S':
- /* Seconds */
- snprintf(nextmsg,sizeof(nextmsg), "digits/kai");
- res = wait_file(chan,ints,nextmsg,lang);
- if (!res)
- res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
- if (!res)
- snprintf(nextmsg,sizeof(nextmsg), "digits/seconds");
- res = wait_file(chan,ints,nextmsg,lang);
- break;
- case 'T':
- res = ast_say_date_with_format_gr(chan, time, ints, lang, "HMS", timezone);
- break;
- case ' ':
- case ' ':
- /* Just ignore spaces and tabs */
- break;
- default:
- /* Unknown character */
- ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
- }
- /* Jump out on DTMF */
- if (res) {
- break;
- }
- }
- return res;
-}
-
-
-
-
-/*********************************** Georgian Support ***************************************/
-
-
-/*
- Convert a number into a semi-localized string. Only for Georgian.
- res must be of at least 256 bytes, preallocated.
- The output corresponds to Georgian spoken numbers, so
- it may be either converted to real words by applying a direct conversion
- table, or played just by substituting the entities with played files.
-
- Output may consist of the following tokens (separated by spaces):
- 0, minus.
- 1-9, 1_-9_. (erti, ori, sami, otxi, ... . erti, or, sam, otx, ...).
- 10-19.
- 20, 40, 60, 80, 20_, 40_, 60_, 80_. (oci, ormoci, ..., ocda, ormocda, ...).
- 100, 100_, 200, 200_, ..., 900, 900_. (asi, as, orasi, oras, ...).
- 1000, 1000_. (atasi, atas).
- 1000000, 1000000_. (milioni, milion).
- 1000000000, 1000000000_. (miliardi, miliard).
-
- To be able to play the sounds, each of the above tokens needs
- a corresponding sound file. (e.g. 200_.gsm).
-*/
-static char* ast_translate_number_ge(int num, char* res, int res_len)
-{
- char buf[256];
- int digit = 0;
- int remainder = 0;
-
-
- if (num < 0) {
- strncat(res, "minus ", res_len - strlen(res) - 1);
- if ( num > INT_MIN ) {
- num = -num;
- } else {
- num = 0;
- }
- }
-
-
- /* directly read the numbers */
- if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
- snprintf(buf, sizeof(buf), "%d", num);
- strncat(res, buf, res_len - strlen(res) - 1);
- return res;
- }
-
-
- if (num < 40) { /* ocda... */
- strncat(res, "20_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(num - 20, res, res_len);
- }
-
- if (num < 60) { /* ormocda... */
- strncat(res, "40_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(num - 40, res, res_len);
- }
-
- if (num < 80) { /* samocda... */
- strncat(res, "60_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(num - 60, res, res_len);
- }
-
- if (num < 100) { /* otxmocda... */
- strncat(res, "80_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(num - 80, res, res_len);
- }
-
-
- if (num < 1000) { /* as, oras, samas, ..., cxraas. asi, orasi, ..., cxraasi. */
- remainder = num % 100;
- digit = (num - remainder) / 100;
-
- if (remainder == 0) {
- snprintf(buf, sizeof(buf), "%d", num);
- strncat(res, buf, res_len - strlen(res) - 1);
- return res;
- } else {
- snprintf(buf, sizeof(buf), "%d_ ", digit*100);
- strncat(res, buf, res_len - strlen(res) - 1);
- return ast_translate_number_ge(remainder, res, res_len);
- }
- }
-
-
- if (num == 1000) {
- strncat(res, "1000", res_len - strlen(res) - 1);
- return res;
- }
-
-
- if (num < 1000000) {
- remainder = num % 1000;
- digit = (num - remainder) / 1000;
-
- if (remainder == 0) {
- ast_translate_number_ge(digit, res, res_len);
- strncat(res, " 1000", res_len - strlen(res) - 1);
- return res;
- }
-
- if (digit == 1) {
- strncat(res, "1000_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(remainder, res, res_len);
- }
-
- ast_translate_number_ge(digit, res, res_len);
- strncat(res, " 1000_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(remainder, res, res_len);
-
- }
-
-
- if (num == 1000000) {
- strncat(res, "1 1000000", res_len - strlen(res) - 1);
- return res;
- }
-
-
- if (num < 1000000000) {
- remainder = num % 1000000;
- digit = (num - remainder) / 1000000;
-
- if (remainder == 0) {
- ast_translate_number_ge(digit, res, res_len);
- strncat(res, " 1000000", res_len - strlen(res) - 1);
- return res;
- }
-
- ast_translate_number_ge(digit, res, res_len);
- strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(remainder, res, res_len);
-
- }
-
-
- if (num == 1000000000) {
- strncat(res, "1 1000000000", res_len - strlen(res) - 1);
- return res;
- }
-
-
- if (num > 1000000000) {
- remainder = num % 1000000000;
- digit = (num - remainder) / 1000000000;
-
- if (remainder == 0) {
- ast_translate_number_ge(digit, res, res_len);
- strncat(res, " 1000000000", res_len - strlen(res) - 1);
- return res;
- }
-
- ast_translate_number_ge(digit, res, res_len);
- strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
- return ast_translate_number_ge(remainder, res, res_len);
-
- }
-
- return res;
-
-}
-
-
-
-/*! \brief ast_say_number_full_ge: Georgian syntax */
-static int ast_say_number_full_ge(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
-{
- int res = 0;
- char fn[512] = "";
- char* s = 0;
- const char* remainder = fn;
-
- if (!num)
- return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
-
-
- ast_translate_number_ge(num, fn, 512);
-
-
-
- while (res == 0 && (s = strstr(remainder, " "))) {
- size_t len = s - remainder;
- char* new_string = malloc(len + 1 + strlen("digits/"));
-
- sprintf(new_string, "digits/");
- strncat(new_string, remainder, len); /* we can't sprintf() it, it's not null-terminated. */
-/* new_string[len + strlen("digits/")] = '\0'; */
-
- if (!ast_streamfile(chan, new_string, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
-
- free(new_string);
-
- remainder = s + 1; /* position just after the found space char. */
- while (*remainder == ' ') /* skip multiple spaces */
- remainder++;
- }
-
-
- /* the last chunk. */
- if (res == 0 && *remainder) {
-
- char* new_string = malloc(strlen(remainder) + 1 + strlen("digits/"));
- sprintf(new_string, "digits/%s", remainder);
-
- if (!ast_streamfile(chan, new_string, language)) {
- if ((audiofd > -1) && (ctrlfd > -1))
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- else
- res = ast_waitstream(chan, ints);
- }
- ast_stopstream(chan);
-
- free(new_string);
-
- }
-
-
- return res;
-
-}
-
-
-
-/*
-Georgian support for date/time requires the following files (*.gsm):
-
-mon-1, mon-2, ... (ianvari, tebervali, ...)
-day-1, day-2, ... (orshabati, samshabati, ...)
-saati_da
-tsuti
-tslis
-*/
-
-
-
-/* Georgian syntax. e.g. "oriatas xuti tslis 5 noemberi". */
-static int ast_say_date_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- char fn[256];
- int res = 0;
- ast_localtime(&t,&tm,NULL);
-
- if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
-
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
-
- if (!res) {
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
-/* if (!res)
- res = ast_waitstream(chan, ints);
-*/
- }
-
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- return res;
-
-}
-
-
-
-
-
-/* Georgian syntax. e.g. "otxi saati da eqvsi tsuti" */
-static int ast_say_time_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
-
- res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
- if (!res) {
- res = ast_streamfile(chan, "digits/saati_da", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
-
- if (tm.tm_min) {
- if (!res) {
- res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
-
- if (!res) {
- res = ast_streamfile(chan, "digits/tsuti", lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- }
- }
- return res;
-}
-
-
-
-/* Georgian syntax. Say date, then say time. */
-static int ast_say_datetime_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- struct tm tm;
- int res = 0;
-
- ast_localtime(&t, &tm, NULL);
- res = ast_say_date(chan, t, ints, lang);
- if (!res)
- ast_say_time(chan, t, ints, lang);
- return res;
-
-}
-
-
-
-
-/* Georgian syntax */
-static int ast_say_datetime_from_now_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
- int res=0;
- time_t nowt;
- int daydiff;
- struct tm tm;
- struct tm now;
- char fn[256];
-
- time(&nowt);
-
- ast_localtime(&t, &tm, NULL);
- ast_localtime(&nowt, &now, NULL);
- daydiff = now.tm_yday - tm.tm_yday;
- if ((daydiff < 0) || (daydiff > 6)) {
- /* Day of month and month */
- if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
-
- } else if (daydiff) {
- /* Just what day of the week */
- if (!res) {
- snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
- res = ast_streamfile(chan, fn, lang);
- if (!res)
- res = ast_waitstream(chan, ints);
- }
- } /* Otherwise, it was today */
- if (!res)
- res = ast_say_time(chan, t, ints, lang);
-
- return res;
-}
-
-
-
-/*
- * remap the 'say' functions to use those in this file
- */
-static void __attribute__((constructor)) __say_init(void)
-{
- ast_say_number_full = say_number_full;
- ast_say_enumeration_full = say_enumeration_full;
- ast_say_digit_str_full = say_digit_str_full;
- ast_say_character_str_full = say_character_str_full;
- ast_say_phonetic_str_full = say_phonetic_str_full;
- ast_say_datetime = say_datetime;
- ast_say_time = say_time;
- ast_say_date = say_date;
- ast_say_datetime_from_now = say_datetime_from_now;
- ast_say_date_with_format = say_date_with_format;
-}
diff --git a/1.4/main/sched.c b/1.4/main/sched.c
deleted file mode 100644
index 04589a018..000000000
--- a/1.4/main/sched.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Scheduler Routines (from cheops-NG)
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#ifdef DEBUG_SCHEDULER
-#define DEBUG(a) do { \
- if (option_debug) \
- DEBUG_M(a) \
- } while (0)
-#else
-#define DEBUG(a)
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/sched.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/options.h"
-
-struct sched {
- AST_LIST_ENTRY(sched) list;
- int id; /*!< ID number of event */
- struct timeval when; /*!< Absolute time event should take place */
- int resched; /*!< When to reschedule */
- int variable; /*!< Use return value from callback to reschedule */
- const void *data; /*!< Data */
- ast_sched_cb callback; /*!< Callback */
-};
-
-struct sched_context {
- ast_mutex_t lock;
- unsigned int eventcnt; /*!< Number of events processed */
- unsigned int schedcnt; /*!< Number of outstanding schedule events */
- AST_LIST_HEAD_NOLOCK(, sched) schedq; /*!< Schedule entry and main queue */
-
-#ifdef SCHED_MAX_CACHE
- AST_LIST_HEAD_NOLOCK(, sched) schedc; /*!< Cache of unused schedule structures and how many */
- unsigned int schedccnt;
-#endif
-};
-
-struct sched_context *sched_context_create(void)
-{
- struct sched_context *tmp;
-
- if (!(tmp = ast_calloc(1, sizeof(*tmp))))
- return NULL;
-
- ast_mutex_init(&tmp->lock);
- tmp->eventcnt = 1;
-
- return tmp;
-}
-
-void sched_context_destroy(struct sched_context *con)
-{
- struct sched *s;
-
- ast_mutex_lock(&con->lock);
-
-#ifdef SCHED_MAX_CACHE
- /* Eliminate the cache */
- while ((s = AST_LIST_REMOVE_HEAD(&con->schedc, list)))
- free(s);
-#endif
-
- /* And the queue */
- while ((s = AST_LIST_REMOVE_HEAD(&con->schedq, list)))
- free(s);
-
- /* And the context */
- ast_mutex_unlock(&con->lock);
- ast_mutex_destroy(&con->lock);
- free(con);
-}
-
-static struct sched *sched_alloc(struct sched_context *con)
-{
- struct sched *tmp;
-
- /*
- * We keep a small cache of schedule entries
- * to minimize the number of necessary malloc()'s
- */
-#ifdef SCHED_MAX_CACHE
- if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list)))
- con->schedccnt--;
- else
-#endif
- tmp = ast_calloc(1, sizeof(*tmp));
-
- return tmp;
-}
-
-static void sched_release(struct sched_context *con, struct sched *tmp)
-{
- /*
- * Add to the cache, or just free() if we
- * already have too many cache entries
- */
-
-#ifdef SCHED_MAX_CACHE
- if (con->schedccnt < SCHED_MAX_CACHE) {
- AST_LIST_INSERT_HEAD(&con->schedc, tmp, list);
- con->schedccnt++;
- } else
-#endif
- free(tmp);
-}
-
-/*! \brief
- * Return the number of milliseconds
- * until the next scheduled event
- */
-int ast_sched_wait(struct sched_context *con)
-{
- int ms;
-
- DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n"));
-
- ast_mutex_lock(&con->lock);
- if (AST_LIST_EMPTY(&con->schedq)) {
- ms = -1;
- } else {
- ms = ast_tvdiff_ms(AST_LIST_FIRST(&con->schedq)->when, ast_tvnow());
- if (ms < 0)
- ms = 0;
- }
- ast_mutex_unlock(&con->lock);
-
- return ms;
-}
-
-
-/*! \brief
- * Take a sched structure and put it in the
- * queue, such that the soonest event is
- * first in the list.
- */
-static void schedule(struct sched_context *con, struct sched *s)
-{
-
- struct sched *cur = NULL;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&con->schedq, cur, list) {
- if (ast_tvcmp(s->when, cur->when) == -1) {
- AST_LIST_INSERT_BEFORE_CURRENT(&con->schedq, s, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- if (!cur)
- AST_LIST_INSERT_TAIL(&con->schedq, s, list);
-
- con->schedcnt++;
-}
-
-/*! \brief
- * given the last event *tv and the offset in milliseconds 'when',
- * computes the next value,
- */
-static int sched_settime(struct timeval *tv, int when)
-{
- struct timeval now = ast_tvnow();
-
- /*ast_log(LOG_DEBUG, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/
- if (ast_tvzero(*tv)) /* not supplied, default to now */
- *tv = now;
- *tv = ast_tvadd(*tv, ast_samp2tv(when, 1000));
- if (ast_tvcmp(*tv, now) < 0) {
- ast_log(LOG_DEBUG, "Request to schedule in the past?!?!\n");
- *tv = now;
- }
- return 0;
-}
-
-
-/*! \brief
- * Schedule callback(data) to happen when ms into the future
- */
-int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable)
-{
- struct sched *tmp;
- int res = -1;
- DEBUG(ast_log(LOG_DEBUG, "ast_sched_add()\n"));
- if (!when) {
- ast_log(LOG_NOTICE, "Scheduled event in 0 ms?\n");
- return -1;
- }
- ast_mutex_lock(&con->lock);
- if ((tmp = sched_alloc(con))) {
- tmp->id = con->eventcnt++;
- tmp->callback = callback;
- tmp->data = data;
- tmp->resched = when;
- tmp->variable = variable;
- tmp->when = ast_tv(0, 0);
- if (sched_settime(&tmp->when, when)) {
- sched_release(con, tmp);
- } else {
- schedule(con, tmp);
- res = tmp->id;
- }
- }
-#ifdef DUMP_SCHEDULER
- /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */
- if (option_debug)
- ast_sched_dump(con);
-#endif
- ast_mutex_unlock(&con->lock);
- return res;
-}
-
-int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
-{
- return ast_sched_add_variable(con, when, callback, data, 0);
-}
-
-/*! \brief
- * Delete the schedule entry with number
- * "id". It's nearly impossible that there
- * would be two or more in the list with that
- * id.
- */
-int ast_sched_del(struct sched_context *con, int id)
-{
- struct sched *s;
-
- DEBUG(ast_log(LOG_DEBUG, "ast_sched_del()\n"));
-
- ast_mutex_lock(&con->lock);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&con->schedq, s, list) {
- if (s->id == id) {
- AST_LIST_REMOVE_CURRENT(&con->schedq, list);
- con->schedcnt--;
- sched_release(con, s);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-
-#ifdef DUMP_SCHEDULER
- /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */
- if (option_debug)
- ast_sched_dump(con);
-#endif
- ast_mutex_unlock(&con->lock);
-
- if (!s) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Attempted to delete nonexistent schedule entry %d!\n", id);
-#ifdef DO_CRASH
- CRASH;
-#endif
- return -1;
- }
-
- return 0;
-}
-
-/*! \brief Dump the contents of the scheduler to LOG_DEBUG */
-void ast_sched_dump(const struct sched_context *con)
-{
- struct sched *q;
- struct timeval tv = ast_tvnow();
-#ifdef SCHED_MAX_CACHE
- ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache)\n", con->schedcnt, con->eventcnt - 1, con->schedccnt);
-#else
- ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total)\n", con->schedcnt, con->eventcnt - 1);
-#endif
-
- ast_log(LOG_DEBUG, "=============================================================\n");
- ast_log(LOG_DEBUG, "|ID Callback Data Time (sec:ms) |\n");
- ast_log(LOG_DEBUG, "+-----+-----------------+-----------------+-----------------+\n");
- AST_LIST_TRAVERSE(&con->schedq, q, list) {
- struct timeval delta = ast_tvsub(q->when, tv);
-
- ast_log(LOG_DEBUG, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n",
- q->id,
- q->callback,
- q->data,
- delta.tv_sec,
- (long int)delta.tv_usec);
- }
- ast_log(LOG_DEBUG, "=============================================================\n");
-
-}
-
-/*! \brief
- * Launch all events which need to be run at this time.
- */
-int ast_sched_runq(struct sched_context *con)
-{
- struct sched *current;
- struct timeval tv;
- int numevents;
- int res;
-
- DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n"));
-
- ast_mutex_lock(&con->lock);
-
- for (numevents = 0; !AST_LIST_EMPTY(&con->schedq); numevents++) {
- /* schedule all events which are going to expire within 1ms.
- * We only care about millisecond accuracy anyway, so this will
- * help us get more than one event at one time if they are very
- * close together.
- */
- tv = ast_tvadd(ast_tvnow(), ast_tv(0, 1000));
- if (ast_tvcmp(AST_LIST_FIRST(&con->schedq)->when, tv) != -1)
- break;
-
- current = AST_LIST_REMOVE_HEAD(&con->schedq, list);
- con->schedcnt--;
-
- /*
- * At this point, the schedule queue is still intact. We
- * have removed the first event and the rest is still there,
- * so it's permissible for the callback to add new events, but
- * trying to delete itself won't work because it isn't in
- * the schedule queue. If that's what it wants to do, it
- * should return 0.
- */
-
- ast_mutex_unlock(&con->lock);
- res = current->callback(current->data);
- ast_mutex_lock(&con->lock);
-
- if (res) {
- /*
- * If they return non-zero, we should schedule them to be
- * run again.
- */
- if (sched_settime(&current->when, current->variable? res : current->resched)) {
- sched_release(con, current);
- } else
- schedule(con, current);
- } else {
- /* No longer needed, so release it */
- sched_release(con, current);
- }
- }
-
- ast_mutex_unlock(&con->lock);
-
- return numevents;
-}
-
-long ast_sched_when(struct sched_context *con,int id)
-{
- struct sched *s;
- long secs = -1;
- DEBUG(ast_log(LOG_DEBUG, "ast_sched_when()\n"));
-
- ast_mutex_lock(&con->lock);
- AST_LIST_TRAVERSE(&con->schedq, s, list) {
- if (s->id == id)
- break;
- }
- if (s) {
- struct timeval now = ast_tvnow();
- secs = s->when.tv_sec - now.tv_sec;
- }
- ast_mutex_unlock(&con->lock);
-
- return secs;
-}
diff --git a/1.4/main/sha1.c b/1.4/main/sha1.c
deleted file mode 100644
index 16ddd6aa3..000000000
--- a/1.4/main/sha1.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- *
- * Based on the RFC 3174
- *
- * Full Copyright Statement
- *
- * Copyright (C) The Internet Society (2001). All Rights Reserved.
- *
- * This document and translations of it may be copied and furnished to
- * others, and derivative works that comment on or otherwise explain it
- * or assist in its implementation may be prepared, copied, published
- * and distributed, in whole or in part, without restriction of any
- * kind, provided that the above copyright notice and this paragraph are
- * included on all such copies and derivative works. However, this
- * document itself may not be modified in any way, such as by removing
- * the copyright notice or references to the Internet Society or other
- * Internet organizations, except as needed for the purpose of
- * developing Internet standards in which case the procedures for
- * copyrights defined in the Internet Standards process must be
- * followed, or as required to translate it into languages other than
- * English.
- *
- * The limited permissions granted above are perpetual and will not be
- * revoked by the Internet Society or its successors or assigns.
-
- * This document and the information contained herein is provided on an
- * "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- * TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- *
- * Description:
- * This file implements the Secure Hashing Algorithm 1 as
- * defined in FIPS PUB 180-1 published April 17, 1995.
- *
- * The SHA-1, produces a 160-bit message digest for a given
- * data stream. It should take about 2**n steps to find a
- * message with the same digest as a given message and
- * 2**(n/2) to find any two messages with the same digest,
- * when n is the digest size in bits. Therefore, this
- * algorithm can serve as a means of providing a
- * "fingerprint" for a message.
- *
- * Portability Issues:
- * SHA-1 is defined in terms of 32-bit "words". This code
- * uses <stdint.h> (included via "sha1.h" to define 32 and 8
- * bit unsigned integer types. If your C compiler does not
- * support 32 bit unsigned integers, this code is not
- * appropriate.
- *
- * Caveats:
- * SHA-1 is designed to work with messages less than 2^64 bits
- * long. Although SHA-1 allows a message digest to be generated
- * for messages of any number of bits less than 2^64, this
- * implementation only works with messages with a length that is
- * a multiple of the size of an 8-bit character.
- *
- */
-
-
-#include "asterisk/sha1.h"
-
-/*
- * Define the SHA1 circular left shift macro
- */
-#define SHA1CircularShift(bits,word) \
- (((word) << (bits)) | ((word) >> (32-(bits))))
-
-/* Local Function Prototyptes */
-void SHA1PadMessage(SHA1Context *);
-void SHA1ProcessMessageBlock(SHA1Context *);
-
-/*
- * SHA1Reset
- *
- * Description:
- * This function will initialize the SHA1Context in preparation
- * for computing a new SHA1 message digest.
- *
- * Parameters:
- * context: [in/out]
- * The context to reset.
- *
- * Returns:
- * sha Error Code.
- *
- */
-int SHA1Reset(SHA1Context *context)
-{
- if (!context) {
- return shaNull;
- }
-
- context->Length_Low = 0;
- context->Length_High = 0;
- context->Message_Block_Index = 0;
-
- context->Intermediate_Hash[0] = 0x67452301;
- context->Intermediate_Hash[1] = 0xEFCDAB89;
- context->Intermediate_Hash[2] = 0x98BADCFE;
- context->Intermediate_Hash[3] = 0x10325476;
- context->Intermediate_Hash[4] = 0xC3D2E1F0;
-
- context->Computed = 0;
- context->Corrupted = 0;
-
- return shaSuccess;
-}
-
-/*
- * SHA1Result
- *
- * Description:
- * This function will return the 160-bit message digest into the
- * Message_Digest array provided by the caller.
- * NOTE: The first octet of hash is stored in the 0th element,
- * the last octet of hash in the 19th element.
- *
- * Parameters:
- * context: [in/out]
- * The context to use to calculate the SHA-1 hash.
- * Message_Digest: [out]
- * Where the digest is returned.
- *
- * Returns:
- * sha Error Code.
- *
- */
-int SHA1Result( SHA1Context *context,
- uint8_t Message_Digest[SHA1HashSize])
-{
- int i;
-
- if (!context || !Message_Digest) {
- return shaNull;
- }
-
- if (context->Corrupted) {
- return context->Corrupted;
- }
-
- if (!context->Computed) {
- SHA1PadMessage(context);
- for (i = 0; i < 64; ++i) {
- /* message may be sensitive, clear it out */
- context->Message_Block[i] = 0;
- }
- context->Length_Low = 0; /* and clear length */
- context->Length_High = 0;
- context->Computed = 1;
- }
-
- for (i = 0; i < SHA1HashSize; ++i) {
- Message_Digest[i] = context->Intermediate_Hash[i >> 2] >> 8 * ( 3 - ( i & 0x03 ) );
- }
-
- return shaSuccess;
-}
-
-/*
- * SHA1Input
- *
- * Description:
- * This function accepts an array of octets as the next portion
- * of the message.
- *
- * Parameters:
- * context: [in/out]
- * The SHA context to update
- * message_array: [in]
- * An array of characters representing the next portion of
- * the message.
- * length: [in]
- * The length of the message in message_array
- *
- * Returns:
- * sha Error Code.
- *
- */
-int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned length)
-{
- if (!length) {
- return shaSuccess;
- }
-
- if (!context || !message_array) {
- return shaNull;
- }
-
- if (context->Computed) {
- context->Corrupted = shaStateError;
- return shaStateError;
- }
-
- if (context->Corrupted) {
- return context->Corrupted;
- }
-
- while (length-- && !context->Corrupted) {
- context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
-
- context->Length_Low += 8;
- if (context->Length_Low == 0) {
- context->Length_High++;
- if (context->Length_High == 0) {
- /* Message is too long */
- context->Corrupted = 1;
- }
- }
-
- if (context->Message_Block_Index == 64) {
- SHA1ProcessMessageBlock(context);
- }
-
- message_array++;
- }
-
- return shaSuccess;
-}
-
-/*
- * SHA1ProcessMessageBlock
- *
- * Description:
- * This function will process the next 512 bits of the message
- * stored in the Message_Block array.
- *
- * Parameters:
- * None.
- *
- * Returns:
- * Nothing.
- *
- * Comments:
- * Many of the variable names in this code, especially the
- * single character names, were used because those were the
- * names used in the publication.
- *
- *
- */
-void SHA1ProcessMessageBlock(SHA1Context *context)
-{
- const uint32_t K[] = { /* Constants defined in SHA-1 */
- 0x5A827999,
- 0x6ED9EBA1,
- 0x8F1BBCDC,
- 0xCA62C1D6
- };
- int t; /* Loop counter */
- uint32_t temp; /* Temporary word value */
- uint32_t W[80]; /* Word sequence */
- uint32_t A, B, C, D, E; /* Word buffers */
-
- /*
- * Initialize the first 16 words in the array W
- */
- for (t = 0; t < 16; t++) {
- W[t] = context->Message_Block[t * 4] << 24;
- W[t] |= context->Message_Block[t * 4 + 1] << 16;
- W[t] |= context->Message_Block[t * 4 + 2] << 8;
- W[t] |= context->Message_Block[t * 4 + 3];
- }
-
- for (t = 16; t < 80; t++) {
- W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
- }
-
- A = context->Intermediate_Hash[0];
- B = context->Intermediate_Hash[1];
- C = context->Intermediate_Hash[2];
- D = context->Intermediate_Hash[3];
- E = context->Intermediate_Hash[4];
-
- for (t = 0; t < 20; t++) {
- temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for (t = 20; t < 40; t++) {
- temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for (t = 40; t < 60; t++) {
- temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for (t = 60; t < 80; t++) {
- temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- context->Intermediate_Hash[0] += A;
- context->Intermediate_Hash[1] += B;
- context->Intermediate_Hash[2] += C;
- context->Intermediate_Hash[3] += D;
- context->Intermediate_Hash[4] += E;
-
- context->Message_Block_Index = 0;
-}
-
-
-/*
- * SHA1PadMessage
- *
- * Description:
- * According to the standard, the message must be padded to an even
- * 512 bits. The first padding bit must be a '1'. The last 64
- * bits represent the length of the original message. All bits in
- * between should be 0. This function will pad the message
- * according to those rules by filling the Message_Block array
- * accordingly. It will also call the ProcessMessageBlock function
- * provided appropriately. When it returns, it can be assumed that
- * the message digest has been computed.
- *
- * Parameters:
- * context: [in/out]
- * The context to pad
- * ProcessMessageBlock: [in]
- * The appropriate SHA*ProcessMessageBlock function
- * Returns:
- * Nothing.
- *
- */
-
-void SHA1PadMessage(SHA1Context *context)
-{
- /*
- * Check to see if the current message block is too small to hold
- * the initial padding bits and length. If so, we will pad the
- * block, process it, and then continue padding into a second
- * block.
- */
- if (context->Message_Block_Index > 55) {
- context->Message_Block[context->Message_Block_Index++] = 0x80;
- while (context->Message_Block_Index < 64) {
- context->Message_Block[context->Message_Block_Index++] = 0;
- }
-
- SHA1ProcessMessageBlock(context);
-
- while (context->Message_Block_Index < 56) {
- context->Message_Block[context->Message_Block_Index++] = 0;
- }
- } else {
- context->Message_Block[context->Message_Block_Index++] = 0x80;
- while (context->Message_Block_Index < 56) {
- context->Message_Block[context->Message_Block_Index++] = 0;
- }
- }
-
- /*
- * Store the message length as the last 8 octets
- */
- context->Message_Block[56] = context->Length_High >> 24;
- context->Message_Block[57] = context->Length_High >> 16;
- context->Message_Block[58] = context->Length_High >> 8;
- context->Message_Block[59] = context->Length_High;
- context->Message_Block[60] = context->Length_Low >> 24;
- context->Message_Block[61] = context->Length_Low >> 16;
- context->Message_Block[62] = context->Length_Low >> 8;
- context->Message_Block[63] = context->Length_Low;
-
- SHA1ProcessMessageBlock(context);
-}
diff --git a/1.4/main/slinfactory.c b/1.4/main/slinfactory.c
deleted file mode 100644
index bd5b8de4f..000000000
--- a/1.4/main/slinfactory.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Anthony Minessale II.
- *
- * Anthony Minessale <anthmct@yahoo.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.
- */
-
-/*! \file
- *
- * \brief A machine to gather up arbitrary frames and convert them
- * to raw slinear on demand.
- *
- * \author Anthony Minessale <anthmct@yahoo.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/slinfactory.h"
-#include "asterisk/logger.h"
-#include "asterisk/translate.h"
-
-void ast_slinfactory_init(struct ast_slinfactory *sf)
-{
- memset(sf, 0, sizeof(*sf));
- sf->offset = sf->hold;
-}
-
-void ast_slinfactory_destroy(struct ast_slinfactory *sf)
-{
- struct ast_frame *f;
-
- if (sf->trans) {
- ast_translator_free_path(sf->trans);
- sf->trans = NULL;
- }
-
- while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
- ast_frfree(f);
-}
-
-int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f)
-{
- struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr;
- unsigned int x;
-
- if (f->subclass != AST_FORMAT_SLINEAR) {
- if (sf->trans && f->subclass != sf->format) {
- ast_translator_free_path(sf->trans);
- sf->trans = NULL;
- }
-
- if (!sf->trans) {
- if ((sf->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
- ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(f->subclass));
- return 0;
- } else {
- sf->format = f->subclass;
- }
- }
-
- if (!(begin_frame = ast_translate(sf->trans, f, 0)))
- return 0;
-
- duped_frame = ast_frdup(begin_frame);
-
- ast_frfree(begin_frame);
-
- if (!duped_frame)
- return 0;
- } else {
- if (!(duped_frame = ast_frdup(f)))
- return 0;
- }
-
- x = 0;
- AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list)
- x++;
-
- AST_LIST_INSERT_TAIL(&sf->queue, duped_frame, frame_list);
-
- sf->size += duped_frame->samples;
-
- return x;
-}
-
-int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
-{
- struct ast_frame *frame_ptr;
- unsigned int sofar = 0, ineed, remain;
- short *frame_data, *offset = buf;
-
- while (sofar < samples) {
- ineed = samples - sofar;
-
- if (sf->holdlen) {
- if (sf->holdlen <= ineed) {
- memcpy(offset, sf->hold, sf->holdlen * sizeof(*offset));
- sofar += sf->holdlen;
- offset += sf->holdlen;
- sf->holdlen = 0;
- sf->offset = sf->hold;
- } else {
- remain = sf->holdlen - ineed;
- memcpy(offset, sf->offset, ineed * sizeof(*offset));
- sofar += ineed;
- sf->offset += ineed;
- sf->holdlen = remain;
- }
- continue;
- }
-
- if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
- frame_data = frame_ptr->data;
-
- if (frame_ptr->samples <= ineed) {
- memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset));
- sofar += frame_ptr->samples;
- offset += frame_ptr->samples;
- } else {
- remain = frame_ptr->samples - ineed;
- memcpy(offset, frame_data, ineed * sizeof(*offset));
- sofar += ineed;
- frame_data += ineed;
- if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
- remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
- }
- memcpy(sf->hold, frame_data, remain * sizeof(*offset));
- sf->holdlen = remain;
- }
- ast_frfree(frame_ptr);
- } else {
- break;
- }
- }
-
- sf->size -= sofar;
- return sofar;
-}
-
-unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
-{
- return sf->size;
-}
-
-void ast_slinfactory_flush(struct ast_slinfactory *sf)
-{
- struct ast_frame *fr = NULL;
-
- if (sf->trans) {
- ast_translator_free_path(sf->trans);
- sf->trans = NULL;
- }
-
- while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
- ast_frfree(fr);
-
- sf->size = sf->holdlen = 0;
- sf->offset = sf->hold;
-
- return;
-}
diff --git a/1.4/main/srv.c b/1.4/main/srv.c
deleted file mode 100644
index 97ad43cff..000000000
--- a/1.4/main/srv.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Funding provided by nic.at
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief DNS SRV Record Lookup Support for Asterisk
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg See also \ref AstENUM
- *
- * \note Funding provided by nic.at
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#if __APPLE_CC__ >= 1495
-#include <arpa/nameser_compat.h>
-#endif
-#include <resolv.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/srv.h"
-#include "asterisk/dns.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/linkedlists.h"
-
-#ifdef __APPLE__
-#undef T_SRV
-#define T_SRV 33
-#endif
-
-struct srv_entry {
- unsigned short priority;
- unsigned short weight;
- unsigned short port;
- unsigned int weight_sum;
- AST_LIST_ENTRY(srv_entry) list;
- char host[1];
-};
-
-struct srv_context {
- unsigned int have_weights:1;
- AST_LIST_HEAD_NOLOCK(srv_entries, srv_entry) entries;
-};
-
-static int parse_srv(unsigned char *answer, int len, unsigned char *msg, struct srv_entry **result)
-{
- struct srv {
- unsigned short priority;
- unsigned short weight;
- unsigned short port;
- } __attribute__ ((__packed__)) *srv = (struct srv *) answer;
-
- int res = 0;
- char repl[256] = "";
- struct srv_entry *entry;
-
- if (len < sizeof(*srv))
- return -1;
-
- answer += sizeof(*srv);
- len -= sizeof(*srv);
-
- if ((res = dn_expand(msg, answer + len, answer, repl, sizeof(repl) - 1)) <= 0) {
- ast_log(LOG_WARNING, "Failed to expand hostname\n");
- return -1;
- }
-
- /* the magic value "." for the target domain means that this service
- is *NOT* available at the domain we searched */
- if (!strcmp(repl, "."))
- return -1;
-
- if (!(entry = ast_calloc(1, sizeof(*entry) + strlen(repl))))
- return -1;
-
- entry->priority = ntohs(srv->priority);
- entry->weight = ntohs(srv->weight);
- entry->port = ntohs(srv->port);
- strcpy(entry->host, repl);
-
- *result = entry;
-
- return 0;
-}
-
-static int srv_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
-{
- struct srv_context *c = (struct srv_context *) context;
- struct srv_entry *entry = NULL;
- struct srv_entry *current;
-
- if (parse_srv(answer, len, fullanswer, &entry))
- return -1;
-
- if (entry->weight)
- c->have_weights = 1;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&c->entries, current, list) {
- /* insert this entry just before the first existing
- entry with a higher priority */
- if (current->priority <= entry->priority)
- continue;
-
- AST_LIST_INSERT_BEFORE_CURRENT(&c->entries, entry, list);
- entry = NULL;
- break;
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- /* if we didn't find a place to insert the entry before an existing
- entry, then just add it to the end */
- if (entry)
- AST_LIST_INSERT_TAIL(&c->entries, entry, list);
-
- return 1;
-}
-
-/* Do the bizarre SRV record weight-handling algorithm
- involving sorting and random number generation...
-
- See RFC 2782 if you want know why this code does this
-*/
-static void process_weights(struct srv_context *context)
-{
- struct srv_entry *current;
- struct srv_entries newlist = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
-
- while (AST_LIST_FIRST(&context->entries)) {
- unsigned int random_weight;
- unsigned int weight_sum;
- unsigned short cur_priority = AST_LIST_FIRST(&context->entries)->priority;
- struct srv_entries temp_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
- weight_sum = 0;
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&context->entries, current, list) {
- if (current->priority != cur_priority)
- break;
-
- AST_LIST_REMOVE_CURRENT(&context->entries, list);
- AST_LIST_INSERT_TAIL(&temp_list, current, list);
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- while (AST_LIST_FIRST(&temp_list)) {
- weight_sum = 0;
- AST_LIST_TRAVERSE(&temp_list, current, list)
- current->weight_sum = weight_sum += current->weight;
-
- /* if all the remaining entries have weight == 0,
- then just append them to the result list and quit */
- if (weight_sum == 0) {
- AST_LIST_APPEND_LIST(&newlist, &temp_list, list);
- break;
- }
-
- random_weight = 1 + (unsigned int) ((float) weight_sum * (ast_random() / ((float) RAND_MAX + 1.0)));
-
- AST_LIST_TRAVERSE_SAFE_BEGIN(&temp_list, current, list) {
- if (current->weight < random_weight)
- continue;
-
- AST_LIST_REMOVE_CURRENT(&temp_list, list);
- AST_LIST_INSERT_TAIL(&newlist, current, list);
- break;
- }
- AST_LIST_TRAVERSE_SAFE_END;
- }
-
- }
-
- /* now that the new list has been ordered,
- put it in place */
-
- AST_LIST_APPEND_LIST(&context->entries, &newlist, list);
-}
-
-int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
-{
- struct srv_context context = { .entries = AST_LIST_HEAD_NOLOCK_INIT_VALUE };
- struct srv_entry *current;
- int ret;
-
- if (chan && ast_autoservice_start(chan) < 0)
- return -1;
-
- ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback);
-
- if (context.have_weights)
- process_weights(&context);
-
- if (chan)
- ret |= ast_autoservice_stop(chan);
-
- /* TODO: there could be a "." entry in the returned list of
- answers... if so, this requires special handling */
-
- /* the list of entries will be sorted in the proper selection order
- already, so we just need the first one (if any) */
-
- if ((ret > 0) && (current = AST_LIST_REMOVE_HEAD(&context.entries, list))) {
- ast_copy_string(host, current->host, hostlen);
- *port = current->port;
- ast_free(current);
- if (option_verbose > 3) {
- ast_verbose(VERBOSE_PREFIX_3 "ast_get_srv: SRV lookup for '%s' mapped to host %s, port %d\n",
- service, host, *port);
- }
- } else {
- host[0] = '\0';
- *port = -1;
- }
-
- while ((current = AST_LIST_REMOVE_HEAD(&context.entries, list)))
- ast_free(current);
-
- return ret;
-}
diff --git a/1.4/main/stdtime/Makefile b/1.4/main/stdtime/Makefile
deleted file mode 100644
index cbe3c48f7..000000000
--- a/1.4/main/stdtime/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-OBJS=localtime.o
-
-all: libtime.a
-
-libtime.a: $(OBJS)
- ar rv $@ $(OBJS)
- ranlib $@
-
-install:
-
-uninstall:
-
-clean-depend:
- rm -f .depend
-
-clean: clean-depend
- rm -f libtime.a *.o test
-
-depend: .depend
-
-.depend:
- ../build_tools/mkdep $(CFLAGS) *.c
-
-test: test.c
- ${CC} ${CFLAGS} -o test test.c
-
-ifneq ($(wildcard .depend),)
-include .depend
-endif
diff --git a/1.4/main/stdtime/localtime.c b/1.4/main/stdtime/localtime.c
deleted file mode 100644
index 1da0fe012..000000000
--- a/1.4/main/stdtime/localtime.c
+++ /dev/null
@@ -1,1650 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Most of this code is in the public domain, so clarified as of
- * June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
- *
- * All modifications to this code to abstract timezones away from
- * the environment are by Tilghman Lesher, <tlesher@vcch.com>, with
- * the copyright assigned to Digium.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * Multi-timezone Localtime code
- *
- * The original source from this file may be obtained from ftp://elsie.nci.nih.gov/pub/
- */
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
-** Leap second handling from Bradley White.
-** POSIX-style TZ environment variable handling from Guy Harris.
-*/
-
-/* #define DEBUG */
-
-/*LINTLIBRARY*/
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-#include <float.h>
-
-
-#include "private.h"
-#include "tzfile.h"
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/lock.h"
-#include "asterisk/localtime.h"
-#include "asterisk/strings.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/utils.h"
-
-#ifndef lint
-#ifndef NOID
-static char __attribute__((unused)) elsieid[] = "@(#)localtime.c 8.5";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#ifndef TZ_ABBR_MAX_LEN
-#define TZ_ABBR_MAX_LEN 16
-#endif /* !defined TZ_ABBR_MAX_LEN */
-
-#ifndef TZ_ABBR_CHAR_SET
-#define TZ_ABBR_CHAR_SET \
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
-#endif /* !defined TZ_ABBR_CHAR_SET */
-
-#ifndef TZ_ABBR_ERR_CHAR
-#define TZ_ABBR_ERR_CHAR '_'
-#endif /* !defined TZ_ABBR_ERR_CHAR */
-
-/*
-** SunOS 4.1.1 headers lack O_BINARY.
-*/
-
-#ifdef O_BINARY
-#define OPEN_MODE (O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
-#ifndef O_BINARY
-#define OPEN_MODE O_RDONLY
-#endif /* !defined O_BINARY */
-
-static const char gmt[] = "GMT";
-
-/*! \note
- * The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
- * We default to US rules as of 1999-08-17.
- * POSIX 1003.1 section 8.1.1 says that the default DST rules are
- * implementation dependent; for historical reasons, US rules are a
- * common default.
- */
-#ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
-#endif /* !defined TZDEFDST */
-
-#ifndef WRONG
-#define WRONG (-1)
-#endif /* !defined WRONG */
-
-/*!< \brief time type information */
-struct ttinfo { /* time type information */
- long tt_gmtoff; /* UTC offset in seconds */
- int tt_isdst; /* used to set tm_isdst */
- int tt_abbrind; /* abbreviation list index */
- int tt_ttisstd; /* TRUE if transition is std time */
- int tt_ttisgmt; /* TRUE if transition is UTC */
-};
-
-/*! \brief leap second information */
-struct lsinfo { /* leap second information */
- time_t ls_trans; /* transition time */
- long ls_corr; /* correction to apply */
-};
-
-#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
-
-#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX TZNAME_MAX
-#endif /* defined TZNAME_MAX */
-#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX 255
-#endif /* !defined TZNAME_MAX */
-#ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
-#endif /* !defined TZ_STRLEN_MAX */
-
-struct state {
- /*! Name of the file that this references */
- char name[TZ_STRLEN_MAX + 1];
- int leapcnt;
- int timecnt;
- int typecnt;
- int charcnt;
- int goback;
- int goahead;
- time_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
- struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
- (2 * (MY_TZNAME_MAX + 1)))];
- struct lsinfo lsis[TZ_MAX_LEAPS];
- AST_LIST_ENTRY(state) list;
-};
-
-struct rule {
- int r_type; /* type of rule--see below */
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
- long r_time; /* transition time of rule */
-};
-
-#define JULIAN_DAY 0 /* Jn - Julian day */
-#define DAY_OF_YEAR 1 /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
-
-/*
-** Prototypes for static functions.
-*/
-
-static long detzcode P((const char * codep));
-static time_t detzcode64 P((const char * codep));
-static int differ_by_repeat P((time_t t1, time_t t0));
-static const char * getzname P((const char * strp));
-static const char * getqzname P((const char * strp, const int delim));
-static const char * getnum P((const char * strp, int * nump, int min,
- int max));
-static const char * getsecs P((const char * strp, long * secsp));
-static const char * getoffset P((const char * strp, long * offsetp));
-static const char * getrule P((const char * strp, struct rule * rulep));
-static int gmtload P((struct state * sp));
-static struct tm * gmtsub P((const time_t * timep, long offset,
- struct tm * tmp));
-static struct tm * localsub P((const time_t * timep, long offset,
- struct tm * tmp, const struct state *sp));
-static int increment_overflow P((int * number, int delta));
-static int leaps_thru_end_of P((int y));
-static int long_increment_overflow P((long * number, int delta));
-static int long_normalize_overflow P((long * tensptr,
- int * unitsptr, const int base));
-static int normalize_overflow P((int * tensptr, int * unitsptr,
- const int base));
-static time_t time1 P((struct tm * tmp,
- struct tm * (*funcp) P((const time_t *,
- long, struct tm *, const struct state *sp)),
- long offset, const struct state *sp));
-static time_t time2 P((struct tm *tmp,
- struct tm * (*funcp) P((const time_t *,
- long, struct tm*, const struct state *sp)),
- long offset, int * okayp, const struct state *sp));
-static time_t time2sub P((struct tm *tmp,
- struct tm * (*funcp) (const time_t *,
- long, struct tm*, const struct state *sp),
- long offset, int * okayp, int do_norm_secs, const struct state *sp));
-static struct tm * timesub P((const time_t * timep, long offset,
- const struct state * sp, struct tm * tmp));
-static int tmcomp P((const struct tm * atmp,
- const struct tm * btmp));
-static time_t transtime P((time_t janfirst, int year,
- const struct rule * rulep, long offset));
-static int tzload P((const char * name, struct state * sp,
- int doextend));
-static int tzparse P((const char * name, struct state * sp,
- int lastditch));
-
-static AST_LIST_HEAD_STATIC(zonelist, state);
-
-#ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
-#endif /* !defined TZ_STRLEN_MAX */
-
-/*! \note
-** Section 4.12.3 of X3.159-1989 requires that
-** Except for the strftime function, these functions [asctime,
-** ctime, gmtime, localtime] return values in one of two static
-** objects: a broken-down time structure and an array of char.
-** Thanks to Paul Eggert for noting this.
-*/
-
-static long detzcode(const char * const codep)
-{
- long result;
- int i;
-
- result = (codep[0] & 0x80) ? ~0L : 0;
- for (i = 0; i < 4; ++i)
- result = (result << 8) | (codep[i] & 0xff);
- return result;
-}
-
-static time_t detzcode64(const char * const codep)
-{
- time_t result;
- int i;
-
- result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
- for (i = 0; i < 8; ++i)
- result = result * 256 + (codep[i] & 0xff);
- return result;
-}
-
-static int differ_by_repeat(const time_t t1, const time_t t0)
-{
- const long long at1 = t1, at0 = t0;
- if (TYPE_INTEGRAL(time_t) &&
- TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
- return 0;
- return at1 - at0 == SECSPERREPEAT;
-}
-
-static int tzload(const char *name, struct state * const sp, const int doextend)
-{
- const char * p;
- int i;
- int fid;
- int stored;
- int nread;
- union {
- struct tzhead tzhead;
- char buf[2 * sizeof(struct tzhead) +
- 2 * sizeof *sp +
- 4 * TZ_MAX_TIMES];
- } u;
-
- if (name == NULL && (name = TZDEFAULT) == NULL)
- return WRONG;
- {
- int doaccess;
- /*
- ** Section 4.9.1 of the C standard says that
- ** "FILENAME_MAX expands to an integral constant expression
- ** that is the size needed for an array of char large enough
- ** to hold the longest file name string that the implementation
- ** guarantees can be opened."
- */
- char fullname[FILENAME_MAX + 1];
-
- if (name[0] == ':')
- ++name;
- doaccess = name[0] == '/';
- if (!doaccess) {
- if ((p = TZDIR) == NULL)
- return WRONG;
- if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
- return WRONG;
- (void) strcpy(fullname, p);
- (void) strcat(fullname, "/");
- (void) strcat(fullname, name);
- /*
- ** Set doaccess if '.' (as in "../") shows up in name.
- */
- if (strchr(name, '.') != NULL)
- doaccess = TRUE;
- name = fullname;
- }
- if (doaccess && access(name, R_OK) != 0)
- return WRONG;
- if ((fid = open(name, OPEN_MODE)) == -1)
- return WRONG;
- }
- nread = read(fid, u.buf, sizeof u.buf);
- if (close(fid) < 0 || nread <= 0)
- return WRONG;
- for (stored = 4; stored <= 8; stored *= 2) {
- int ttisstdcnt;
- int ttisgmtcnt;
-
- ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
- ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
- sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
- sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
- sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
- sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
- p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
- if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
- sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
- sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
- sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
- (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
- (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
- return WRONG;
- if (nread - (p - u.buf) <
- sp->timecnt * stored + /* ats */
- sp->timecnt + /* types */
- sp->typecnt * 6 + /* ttinfos */
- sp->charcnt + /* chars */
- sp->leapcnt * (stored + 4) + /* lsinfos */
- ttisstdcnt + /* ttisstds */
- ttisgmtcnt) /* ttisgmts */
- return WRONG;
- for (i = 0; i < sp->timecnt; ++i) {
- sp->ats[i] = (stored == 4) ?
- detzcode(p) : detzcode64(p);
- p += stored;
- }
- for (i = 0; i < sp->timecnt; ++i) {
- sp->types[i] = (unsigned char) *p++;
- if (sp->types[i] >= sp->typecnt)
- return WRONG;
- }
- for (i = 0; i < sp->typecnt; ++i) {
- struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- ttisp->tt_gmtoff = detzcode(p);
- p += 4;
- ttisp->tt_isdst = (unsigned char) *p++;
- if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
- return WRONG;
- ttisp->tt_abbrind = (unsigned char) *p++;
- if (ttisp->tt_abbrind < 0 ||
- ttisp->tt_abbrind > sp->charcnt)
- return WRONG;
- }
- for (i = 0; i < sp->charcnt; ++i)
- sp->chars[i] = *p++;
- sp->chars[i] = '\0'; /* ensure '\0' at end */
- for (i = 0; i < sp->leapcnt; ++i) {
- struct lsinfo * lsisp;
-
- lsisp = &sp->lsis[i];
- lsisp->ls_trans = (stored == 4) ?
- detzcode(p) : detzcode64(p);
- p += stored;
- lsisp->ls_corr = detzcode(p);
- p += 4;
- }
- for (i = 0; i < sp->typecnt; ++i) {
- struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- if (ttisstdcnt == 0)
- ttisp->tt_ttisstd = FALSE;
- else {
- ttisp->tt_ttisstd = *p++;
- if (ttisp->tt_ttisstd != TRUE &&
- ttisp->tt_ttisstd != FALSE)
- return WRONG;
- }
- }
- for (i = 0; i < sp->typecnt; ++i) {
- struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- if (ttisgmtcnt == 0)
- ttisp->tt_ttisgmt = FALSE;
- else {
- ttisp->tt_ttisgmt = *p++;
- if (ttisp->tt_ttisgmt != TRUE &&
- ttisp->tt_ttisgmt != FALSE)
- return WRONG;
- }
- }
- /*
- ** Out-of-sort ats should mean we're running on a
- ** signed time_t system but using a data file with
- ** unsigned values (or vice versa).
- */
- for (i = 0; i < sp->timecnt - 2; ++i)
- if (sp->ats[i] > sp->ats[i + 1]) {
- ++i;
- if (TYPE_SIGNED(time_t)) {
- /*
- ** Ignore the end (easy).
- */
- sp->timecnt = i;
- } else {
- /*
- ** Ignore the beginning (harder).
- */
- int j;
-
- for (j = 0; j + i < sp->timecnt; ++j) {
- sp->ats[j] = sp->ats[j + i];
- sp->types[j] = sp->types[j + i];
- }
- sp->timecnt = j;
- }
- break;
- }
- /*
- ** If this is an old file, we're done.
- */
- if (u.tzhead.tzh_version[0] == '\0')
- break;
- nread -= p - u.buf;
- for (i = 0; i < nread; ++i)
- u.buf[i] = p[i];
- /*
- ** If this is a narrow integer time_t system, we're done.
- */
- if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
- break;
- }
- if (doextend && nread > 2 &&
- u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
- sp->typecnt + 2 <= TZ_MAX_TYPES) {
- struct state ts;
- int result;
-
- u.buf[nread - 1] = '\0';
- result = tzparse(&u.buf[1], &ts, FALSE);
- if (result == 0 && ts.typecnt == 2 &&
- sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
- for (i = 0; i < 2; ++i)
- ts.ttis[i].tt_abbrind +=
- sp->charcnt;
- for (i = 0; i < ts.charcnt; ++i)
- sp->chars[sp->charcnt++] =
- ts.chars[i];
- i = 0;
- while (i < ts.timecnt &&
- ts.ats[i] <=
- sp->ats[sp->timecnt - 1])
- ++i;
- while (i < ts.timecnt &&
- sp->timecnt < TZ_MAX_TIMES) {
- sp->ats[sp->timecnt] =
- ts.ats[i];
- sp->types[sp->timecnt] =
- sp->typecnt +
- ts.types[i];
- ++sp->timecnt;
- ++i;
- }
- sp->ttis[sp->typecnt++] = ts.ttis[0];
- sp->ttis[sp->typecnt++] = ts.ttis[1];
- }
- }
- i = 2 * YEARSPERREPEAT;
- sp->goback = sp->goahead = sp->timecnt > i;
- sp->goback = sp->goback && sp->types[i] == sp->types[0] &&
- differ_by_repeat(sp->ats[i], sp->ats[0]);
- sp->goahead = sp->goahead &&
- sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] &&
- differ_by_repeat(sp->ats[sp->timecnt - 1],
- sp->ats[sp->timecnt - 1 - i]);
- return 0;
-}
-
-static const int mon_lengths[2][MONSPERYEAR] = {
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
- { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
-};
-
-static const int year_lengths[2] = {
- DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-/*! \brief
-** Given a pointer into a time zone string, scan until a character that is not
-** a valid character in a zone name is found. Return a pointer to that
-** character.
-*/
-
-static const char * getzname(const char *strp)
-{
- char c;
-
- while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
- c != '+')
- ++strp;
- return strp;
-}
-
-/*! \brief
-** Given a pointer into an extended time zone string, scan until the ending
-** delimiter of the zone name is located. Return a pointer to the delimiter.
-**
-** As with getzname above, the legal character set is actually quite
-** restricted, with other characters producing undefined results.
-** We don't do any checking here; checking is done later in common-case code.
-*/
-
-static const char * getqzname(const char *strp, const int delim)
-{
- int c;
-
- while ((c = *strp) != '\0' && c != delim)
- ++strp;
- return strp;
-}
-
-/*! \brief
-** Given a pointer into a time zone string, extract a number from that string.
-** Check that the number is within a specified range; if it is not, return
-** NULL.
-** Otherwise, return a pointer to the first character not part of the number.
-*/
-
-static const char *getnum(const char *strp, int *nump, const int min, const int max)
-{
- char c;
- int num;
-
- if (strp == NULL || !is_digit(c = *strp))
- return NULL;
- num = 0;
- do {
- num = num * 10 + (c - '0');
- if (num > max)
- return NULL; /* illegal value */
- c = *++strp;
- } while (is_digit(c));
- if (num < min)
- return NULL; /* illegal value */
- *nump = num;
- return strp;
-}
-
-/*! \brief
-** Given a pointer into a time zone string, extract a number of seconds,
-** in hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the number
-** of seconds.
-*/
-
-static const char *getsecs(const char *strp, long * const secsp)
-{
- int num;
-
- /*
- ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
- ** "M10.4.6/26", which does not conform to Posix,
- ** but which specifies the equivalent of
- ** ``02:00 on the first Sunday on or after 23 Oct''.
- */
- strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
- if (strp == NULL)
- return NULL;
- *secsp = num * (long) SECSPERHOUR;
- if (*strp == ':') {
- ++strp;
- strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
- if (strp == NULL)
- return NULL;
- *secsp += num * SECSPERMIN;
- if (*strp == ':') {
- ++strp;
- /* `SECSPERMIN' allows for leap seconds. */
- strp = getnum(strp, &num, 0, SECSPERMIN);
- if (strp == NULL)
- return NULL;
- *secsp += num;
- }
- }
- return strp;
-}
-
-/*! \brief
-** Given a pointer into a time zone string, extract an offset, in
-** [+-]hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the time.
-*/
-
-static const char *getoffset(const char *strp, long *offsetp)
-{
- int neg = 0;
-
- if (*strp == '-') {
- neg = 1;
- ++strp;
- } else if (*strp == '+')
- ++strp;
- strp = getsecs(strp, offsetp);
- if (strp == NULL)
- return NULL; /* illegal time */
- if (neg)
- *offsetp = -*offsetp;
- return strp;
-}
-
-/*! \brief
-** Given a pointer into a time zone string, extract a rule in the form
-** date[/time]. See POSIX section 8 for the format of "date" and "time".
-** If a valid rule is not found, return NULL.
-** Otherwise, return a pointer to the first character not part of the rule.
-*/
-
-static const char *getrule(const char *strp, struct rule *rulep)
-{
- if (*strp == 'J') {
- /*
- ** Julian day.
- */
- rulep->r_type = JULIAN_DAY;
- ++strp;
- strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
- } else if (*strp == 'M') {
- /*
- ** Month, week, day.
- */
- rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
- ++strp;
- strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_week, 1, 5);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
- } else if (is_digit(*strp)) {
- /*
- ** Day of year.
- */
- rulep->r_type = DAY_OF_YEAR;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
- } else return NULL; /* invalid format */
- if (strp == NULL)
- return NULL;
- if (*strp == '/') {
- /*
- ** Time specified.
- */
- ++strp;
- strp = getsecs(strp, &rulep->r_time);
- } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
- return strp;
-}
-
-/*! \brief
-** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
-** year, a rule, and the offset from UTC at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
-*/
-
-static time_t transtime(const time_t janfirst, const int year, const struct rule *rulep, const long offset)
-{
- int leapyear;
- time_t value;
- int i;
- int d, m1, yy0, yy1, yy2, dow;
-
- INITIALIZE(value);
- leapyear = isleap(year);
- switch (rulep->r_type) {
-
- case JULIAN_DAY:
- /*
- ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
- ** years.
- ** In non-leap years, or if the day number is 59 or less, just
- ** add SECSPERDAY times the day number-1 to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
- if (leapyear && rulep->r_day >= 60)
- value += SECSPERDAY;
- break;
-
- case DAY_OF_YEAR:
- /*
- ** n - day of year.
- ** Just add SECSPERDAY times the day number to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + rulep->r_day * SECSPERDAY;
- break;
-
- case MONTH_NTH_DAY_OF_WEEK:
- /*
- ** Mm.n.d - nth "dth day" of month m.
- */
- value = janfirst;
- for (i = 0; i < rulep->r_mon - 1; ++i)
- value += mon_lengths[leapyear][i] * SECSPERDAY;
-
- /*
- ** Use Zeller's Congruence to get day-of-week of first day of
- ** month.
- */
- m1 = (rulep->r_mon + 9) % 12 + 1;
- yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
- yy1 = yy0 / 100;
- yy2 = yy0 % 100;
- dow = ((26 * m1 - 2) / 10 +
- 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
- if (dow < 0)
- dow += DAYSPERWEEK;
-
- /*
- ** "dow" is the day-of-week of the first day of the month. Get
- ** the day-of-month (zero-origin) of the first "dow" day of the
- ** month.
- */
- d = rulep->r_day - dow;
- if (d < 0)
- d += DAYSPERWEEK;
- for (i = 1; i < rulep->r_week; ++i) {
- if (d + DAYSPERWEEK >=
- mon_lengths[leapyear][rulep->r_mon - 1])
- break;
- d += DAYSPERWEEK;
- }
-
- /*
- ** "d" is the day-of-month (zero-origin) of the day we want.
- */
- value += d * SECSPERDAY;
- break;
- }
-
- /*
- ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
- ** question. To get the Epoch-relative time of the specified local
- ** time on that day, add the transition time and the current offset
- ** from UTC.
- */
- return value + rulep->r_time + offset;
-}
-
-/*! \note
-** Given a POSIX section 8-style TZ string, fill in the rule tables as
-** appropriate.
-*/
-
-static int tzparse(const char *name, struct state *sp, const int lastditch)
-{
- const char * stdname;
- const char * dstname;
- size_t stdlen;
- size_t dstlen;
- long stdoffset;
- long dstoffset;
- time_t * atp;
- unsigned char * typep;
- char * cp;
- int load_result;
-
- INITIALIZE(dstname);
- stdname = name;
- if (lastditch) {
- stdlen = strlen(name); /* length of standard zone name */
- name += stdlen;
- if (stdlen >= sizeof sp->chars)
- stdlen = (sizeof sp->chars) - 1;
- stdoffset = 0;
- } else {
- if (*name == '<') {
- name++;
- stdname = name;
- name = getqzname(name, '>');
- if (*name != '>')
- return WRONG;
- stdlen = name - stdname;
- name++;
- } else {
- name = getzname(name);
- stdlen = name - stdname;
- }
- if (*name == '\0')
- return WRONG;
- name = getoffset(name, &stdoffset);
- if (name == NULL)
- return WRONG;
- }
- load_result = tzload(TZDEFRULES, sp, FALSE);
- if (load_result != 0)
- sp->leapcnt = 0; /* so, we're off a little */
- if (*name != '\0') {
- if (*name == '<') {
- dstname = ++name;
- name = getqzname(name, '>');
- if (*name != '>')
- return WRONG;
- dstlen = name - dstname;
- name++;
- } else {
- dstname = name;
- name = getzname(name);
- dstlen = name - dstname; /* length of DST zone name */
- }
- if (*name != '\0' && *name != ',' && *name != ';') {
- name = getoffset(name, &dstoffset);
- if (name == NULL)
- return WRONG;
- } else dstoffset = stdoffset - SECSPERHOUR;
- if (*name == '\0' && load_result != 0)
- name = TZDEFRULESTRING;
- if (*name == ',' || *name == ';') {
- struct rule start;
- struct rule end;
- int year;
- time_t janfirst;
- time_t starttime;
- time_t endtime;
-
- ++name;
- if ((name = getrule(name, &start)) == NULL)
- return WRONG;
- if (*name++ != ',')
- return WRONG;
- if ((name = getrule(name, &end)) == NULL)
- return WRONG;
- if (*name != '\0')
- return WRONG;
- sp->typecnt = 2; /* standard time and DST */
- /*
- ** Two transitions per year, from EPOCH_YEAR forward.
- */
- sp->ttis[0].tt_gmtoff = -dstoffset;
- sp->ttis[0].tt_isdst = 1;
- sp->ttis[0].tt_abbrind = stdlen + 1;
- sp->ttis[1].tt_gmtoff = -stdoffset;
- sp->ttis[1].tt_isdst = 0;
- sp->ttis[1].tt_abbrind = 0;
- atp = sp->ats;
- typep = sp->types;
- janfirst = 0;
- sp->timecnt = 0;
- for (year = EPOCH_YEAR;
- sp->timecnt + 2 <= TZ_MAX_TIMES;
- ++year) {
- time_t newfirst;
-
- starttime = transtime(janfirst, year, &start,
- stdoffset);
- endtime = transtime(janfirst, year, &end,
- dstoffset);
- if (starttime > endtime) {
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- } else {
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- }
- sp->timecnt += 2;
- newfirst = janfirst;
- newfirst += year_lengths[isleap(year)] *
- SECSPERDAY;
- if (newfirst <= janfirst)
- break;
- janfirst = newfirst;
- }
- } else {
- long theirstdoffset;
- long theirdstoffset;
- long theiroffset;
- int isdst;
- int i;
- int j;
-
- if (*name != '\0')
- return WRONG;
- /*
- ** Initial values of theirstdoffset and theirdstoffset.
- */
- theirstdoffset = 0;
- for (i = 0; i < sp->timecnt; ++i) {
- j = sp->types[i];
- if (!sp->ttis[j].tt_isdst) {
- theirstdoffset =
- -sp->ttis[j].tt_gmtoff;
- break;
- }
- }
- theirdstoffset = 0;
- for (i = 0; i < sp->timecnt; ++i) {
- j = sp->types[i];
- if (sp->ttis[j].tt_isdst) {
- theirdstoffset =
- -sp->ttis[j].tt_gmtoff;
- break;
- }
- }
- /*
- ** Initially we're assumed to be in standard time.
- */
- isdst = FALSE;
- theiroffset = theirstdoffset;
- /*
- ** Now juggle transition times and types
- ** tracking offsets as you do.
- */
- for (i = 0; i < sp->timecnt; ++i) {
- j = sp->types[i];
- sp->types[i] = sp->ttis[j].tt_isdst;
- if (sp->ttis[j].tt_ttisgmt) {
- /* No adjustment to transition time */
- } else {
- /*
- ** If summer time is in effect, and the
- ** transition time was not specified as
- ** standard time, add the summer time
- ** offset to the transition time;
- ** otherwise, add the standard time
- ** offset to the transition time.
- */
- /*
- ** Transitions from DST to DDST
- ** will effectively disappear since
- ** POSIX provides for only one DST
- ** offset.
- */
- if (isdst && !sp->ttis[j].tt_ttisstd) {
- sp->ats[i] += dstoffset -
- theirdstoffset;
- } else {
- sp->ats[i] += stdoffset -
- theirstdoffset;
- }
- }
- theiroffset = -sp->ttis[j].tt_gmtoff;
- if (sp->ttis[j].tt_isdst)
- theirdstoffset = theiroffset;
- else theirstdoffset = theiroffset;
- }
- /*
- ** Finally, fill in ttis.
- ** ttisstd and ttisgmt need not be handled.
- */
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = FALSE;
- sp->ttis[0].tt_abbrind = 0;
- sp->ttis[1].tt_gmtoff = -dstoffset;
- sp->ttis[1].tt_isdst = TRUE;
- sp->ttis[1].tt_abbrind = stdlen + 1;
- sp->typecnt = 2;
- }
- } else {
- dstlen = 0;
- sp->typecnt = 1; /* only standard time */
- sp->timecnt = 0;
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = 0;
- sp->ttis[0].tt_abbrind = 0;
- }
- sp->charcnt = stdlen + 1;
- if (dstlen != 0)
- sp->charcnt += dstlen + 1;
- if ((size_t) sp->charcnt > sizeof sp->chars)
- return WRONG;
- cp = sp->chars;
- (void) strncpy(cp, stdname, stdlen);
- cp += stdlen;
- *cp++ = '\0';
- if (dstlen != 0) {
- (void) strncpy(cp, dstname, dstlen);
- *(cp + dstlen) = '\0';
- }
- return 0;
-}
-
-static int gmtload(struct state *sp)
-{
- if (tzload(gmt, sp, TRUE) != 0)
- return tzparse(gmt, sp, TRUE);
- else
- return WRONG;
-}
-
-static const struct state *ast_tzset(const char *zone)
-{
- struct state *sp;
-
- if (ast_strlen_zero(zone))
- zone = "/etc/localtime";
-
- AST_LIST_LOCK(&zonelist);
- AST_LIST_TRAVERSE(&zonelist, sp, list) {
- if (!strcmp(sp->name, zone)) {
- AST_LIST_UNLOCK(&zonelist);
- return sp;
- }
- }
- AST_LIST_UNLOCK(&zonelist);
-
- if (!(sp = ast_calloc(1, sizeof *sp)))
- return NULL;
-
- if (tzload(zone, sp, TRUE) != 0) {
- if (zone[0] == ':' || tzparse(zone, sp, FALSE) != 0)
- (void) gmtload(sp);
- }
- ast_copy_string(sp->name, zone, sizeof(sp->name));
- AST_LIST_LOCK(&zonelist);
- AST_LIST_INSERT_TAIL(&zonelist, sp, list);
- AST_LIST_UNLOCK(&zonelist);
- return sp;
-}
-
-/*! \note
-** The easy way to behave "as if no library function calls" localtime
-** is to not call it--so we drop its guts into "localsub", which can be
-** freely called. (And no, the PANS doesn't require the above behavior--
-** but it *is* desirable.)
-**
-** The unused offset argument is for the benefit of mktime variants.
-*/
-
-static struct tm *localsub(const time_t *timep, const long offset, struct tm *tmp, const struct state *sp)
-{
- const struct ttinfo * ttisp;
- int i;
- struct tm * result;
- const time_t t = *timep;
-
- if (sp == NULL)
- return gmtsub(timep, offset, tmp);
- if ((sp->goback && t < sp->ats[0]) ||
- (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
- time_t newt = t;
- time_t seconds;
- time_t tcycles;
- int_fast64_t icycles;
-
- if (t < sp->ats[0])
- seconds = sp->ats[0] - t;
- else seconds = t - sp->ats[sp->timecnt - 1];
- --seconds;
- tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
- ++tcycles;
- icycles = tcycles;
- if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
- return NULL;
- seconds = icycles;
- seconds *= YEARSPERREPEAT;
- seconds *= AVGSECSPERYEAR;
- if (t < sp->ats[0])
- newt += seconds;
- else newt -= seconds;
- if (newt < sp->ats[0] ||
- newt > sp->ats[sp->timecnt - 1])
- return NULL; /* "cannot happen" */
- result = localsub(&newt, offset, tmp, sp);
- if (result == tmp) {
- time_t newy;
-
- newy = tmp->tm_year;
- if (t < sp->ats[0])
- newy -= icycles * YEARSPERREPEAT;
- else
- newy += icycles * YEARSPERREPEAT;
- tmp->tm_year = newy;
- if (tmp->tm_year != newy)
- return NULL;
- }
- return result;
- }
- if (sp->timecnt == 0 || t < sp->ats[0]) {
- i = 0;
- while (sp->ttis[i].tt_isdst) {
- if (++i >= sp->typecnt) {
- i = 0;
- break;
- }
- }
- } else {
- int lo = 1;
- int hi = sp->timecnt;
-
- while (lo < hi) {
- int mid = (lo + hi) >> 1;
-
- if (t < sp->ats[mid])
- hi = mid;
- else
- lo = mid + 1;
- }
- i = (int) sp->types[lo - 1];
- }
- ttisp = &sp->ttis[i];
- /*
- ** To get (wrong) behavior that's compatible with System V Release 2.0
- ** you'd replace the statement below with
- ** t += ttisp->tt_gmtoff;
- ** timesub(&t, 0L, sp, tmp);
- */
- result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
- tmp->tm_isdst = ttisp->tt_isdst;
-#ifndef SOLARIS /* Solaris doesn't have this element */
- tmp->tm_gmtoff = ttisp->tt_gmtoff;
-#endif
-#ifdef TM_ZONE
- tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
-#endif /* defined TM_ZONE */
- return result;
-}
-
-struct tm *ast_localtime(const time_t *timep, struct tm *tmp, const char *zone)
-{
- const struct state *sp = ast_tzset(zone);
- memset(tmp, 0, sizeof(*tmp));
- return sp ? localsub(timep, 0L, tmp, sp) : NULL;
-}
-
-/*
-** gmtsub is to gmtime as localsub is to localtime.
-*/
-
-static struct tm *gmtsub(const time_t *timep, const long offset, struct tm *tmp)
-{
- struct tm * result;
- struct state *sp;
-
- AST_LIST_LOCK(&zonelist);
- AST_LIST_TRAVERSE(&zonelist, sp, list) {
- if (!strcmp(sp->name, "UTC"))
- break;
- }
-
- if (!sp) {
- if (!(sp = (struct state *) ast_calloc(1, sizeof *sp)))
- return NULL;
- gmtload(sp);
- AST_LIST_INSERT_TAIL(&zonelist, sp, list);
- }
- AST_LIST_UNLOCK(&zonelist);
-
- result = timesub(timep, offset, sp, tmp);
-#ifdef TM_ZONE
- /*
- ** Could get fancy here and deliver something such as
- ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
- ** but this is no time for a treasure hunt.
- */
- if (offset != 0)
- tmp->TM_ZONE = " ";
- else
- tmp->TM_ZONE = sp->chars;
-#endif /* defined TM_ZONE */
- return result;
-}
-
-/*! \brief
-** Return the number of leap years through the end of the given year
-** where, to make the math easy, the answer for year zero is defined as zero.
-*/
-
-static int leaps_thru_end_of(const int y)
-{
- return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
- -(leaps_thru_end_of(-(y + 1)) + 1);
-}
-
-static struct tm *timesub(const time_t *timep, const long offset, const struct state *sp, struct tm *tmp)
-{
- const struct lsinfo * lp;
- time_t tdays;
- int idays; /* unsigned would be so 2003 */
- long rem;
- int y;
- const int * ip;
- long corr;
- int hit;
- int i;
- long seconds;
-
-
- corr = 0;
- hit = 0;
- i = (sp == NULL) ? 0 : sp->leapcnt;
- while (--i >= 0) {
- lp = &sp->lsis[i];
- if (*timep >= lp->ls_trans) {
- if (*timep == lp->ls_trans) {
- hit = ((i == 0 && lp->ls_corr > 0) ||
- lp->ls_corr > sp->lsis[i - 1].ls_corr);
- if (hit)
- while (i > 0 &&
- sp->lsis[i].ls_trans ==
- sp->lsis[i - 1].ls_trans + 1 &&
- sp->lsis[i].ls_corr ==
- sp->lsis[i - 1].ls_corr + 1) {
- ++hit;
- --i;
- }
- }
- corr = lp->ls_corr;
- break;
- }
- }
- y = EPOCH_YEAR;
- tdays = *timep / SECSPERDAY;
- rem = *timep - tdays * SECSPERDAY;
- while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
- int newy;
- time_t tdelta;
- int idelta;
- int leapdays;
-
- tdelta = tdays / DAYSPERLYEAR;
- idelta = tdelta;
- if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
- return NULL;
- if (idelta == 0)
- idelta = (tdays < 0) ? -1 : 1;
- newy = y;
- if (increment_overflow(&newy, idelta))
- return NULL;
- leapdays = leaps_thru_end_of(newy - 1) -
- leaps_thru_end_of(y - 1);
- tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
- tdays -= leapdays;
- y = newy;
- }
-
- seconds = tdays * SECSPERDAY + 0.5;
- tdays = seconds / SECSPERDAY;
- rem += seconds - tdays * SECSPERDAY;
-
- /*
- ** Given the range, we can now fearlessly cast...
- */
- idays = tdays;
- rem += offset - corr;
- while (rem < 0) {
- rem += SECSPERDAY;
- --idays;
- }
- while (rem >= SECSPERDAY) {
- rem -= SECSPERDAY;
- ++idays;
- }
- while (idays < 0) {
- if (increment_overflow(&y, -1))
- return NULL;
- idays += year_lengths[isleap(y)];
- }
- while (idays >= year_lengths[isleap(y)]) {
- idays -= year_lengths[isleap(y)];
- if (increment_overflow(&y, 1))
- return NULL;
- }
- tmp->tm_year = y;
- if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
- return NULL;
- tmp->tm_yday = idays;
- /*
- ** The "extra" mods below avoid overflow problems.
- */
- tmp->tm_wday = EPOCH_WDAY +
- ((y - EPOCH_YEAR) % DAYSPERWEEK) *
- (DAYSPERNYEAR % DAYSPERWEEK) +
- leaps_thru_end_of(y - 1) -
- leaps_thru_end_of(EPOCH_YEAR - 1) +
- idays;
- tmp->tm_wday %= DAYSPERWEEK;
- if (tmp->tm_wday < 0)
- tmp->tm_wday += DAYSPERWEEK;
- tmp->tm_hour = (int) (rem / SECSPERHOUR);
- rem %= SECSPERHOUR;
- tmp->tm_min = (int) (rem / SECSPERMIN);
- /*
- ** A positive leap second requires a special
- ** representation. This uses "... ??:59:60" et seq.
- */
- tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
- ip = mon_lengths[isleap(y)];
- for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
- idays -= ip[tmp->tm_mon];
- tmp->tm_mday = (int) (idays + 1);
- tmp->tm_isdst = 0;
-#ifdef TM_GMTOFF
- tmp->TM_GMTOFF = offset;
-#endif /* defined TM_GMTOFF */
- return tmp;
-}
-
-/*! \note
-** Adapted from code provided by Robert Elz, who writes:
-** The "best" way to do mktime I think is based on an idea of Bob
-** Kridle's (so its said...) from a long time ago.
-** It does a binary search of the time_t space. Since time_t's are
-** just 32 bits, its a max of 32 iterations (even at 64 bits it
-** would still be very reasonable).
-*/
-
-/*! \brief
-** Simplified normalize logic courtesy Paul Eggert.
-*/
-
-static int increment_overflow(int *number, int delta)
-{
- int number0;
-
- number0 = *number;
- *number += delta;
- return (*number < number0) != (delta < 0);
-}
-
-static int long_increment_overflow(long *number, int delta)
-{
- long number0;
-
- number0 = *number;
- *number += delta;
- return (*number < number0) != (delta < 0);
-}
-
-static int normalize_overflow(int *tensptr, int *unitsptr, const int base)
-{
- int tensdelta;
-
- tensdelta = (*unitsptr >= 0) ?
- (*unitsptr / base) :
- (-1 - (-1 - *unitsptr) / base);
- *unitsptr -= tensdelta * base;
- return increment_overflow(tensptr, tensdelta);
-}
-
-static int long_normalize_overflow(long *tensptr, int *unitsptr, const int base)
-{
- int tensdelta;
-
- tensdelta = (*unitsptr >= 0) ?
- (*unitsptr / base) :
- (-1 - (-1 - *unitsptr) / base);
- *unitsptr -= tensdelta * base;
- return long_increment_overflow(tensptr, tensdelta);
-}
-
-static int tmcomp(const struct tm *atmp, const struct tm *btmp)
-{
- int result;
-
- if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
- (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
- (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
- (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
- (result = (atmp->tm_min - btmp->tm_min)) == 0)
- result = atmp->tm_sec - btmp->tm_sec;
- return result;
-}
-
-static time_t time2sub(struct tm *tmp, struct tm * (* const funcp) (const time_t *, long, struct tm *, const struct state *), const long offset, int *okayp, const int do_norm_secs, const struct state *sp)
-{
- int dir;
- int i, j;
- int saved_seconds;
- long li;
- time_t lo;
- time_t hi;
- long y;
- time_t newt;
- time_t t;
- struct tm yourtm, mytm;
-
- *okayp = FALSE;
- yourtm = *tmp;
- if (do_norm_secs) {
- if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
- SECSPERMIN))
- return WRONG;
- }
- if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
- return WRONG;
- if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
- return WRONG;
- y = yourtm.tm_year;
- if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
- return WRONG;
- /*
- ** Turn y into an actual year number for now.
- ** It is converted back to an offset from TM_YEAR_BASE later.
- */
- if (long_increment_overflow(&y, TM_YEAR_BASE))
- return WRONG;
- while (yourtm.tm_mday <= 0) {
- if (long_increment_overflow(&y, -1))
- return WRONG;
- li = y + (1 < yourtm.tm_mon);
- yourtm.tm_mday += year_lengths[isleap(li)];
- }
- while (yourtm.tm_mday > DAYSPERLYEAR) {
- li = y + (1 < yourtm.tm_mon);
- yourtm.tm_mday -= year_lengths[isleap(li)];
- if (long_increment_overflow(&y, 1))
- return WRONG;
- }
- for ( ; ; ) {
- i = mon_lengths[isleap(y)][yourtm.tm_mon];
- if (yourtm.tm_mday <= i)
- break;
- yourtm.tm_mday -= i;
- if (++yourtm.tm_mon >= MONSPERYEAR) {
- yourtm.tm_mon = 0;
- if (long_increment_overflow(&y, 1))
- return WRONG;
- }
- }
- if (long_increment_overflow(&y, -TM_YEAR_BASE))
- return WRONG;
- yourtm.tm_year = y;
- if (yourtm.tm_year != y)
- return WRONG;
- if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
- saved_seconds = 0;
- else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
- /*
- ** We can't set tm_sec to 0, because that might push the
- ** time below the minimum representable time.
- ** Set tm_sec to 59 instead.
- ** This assumes that the minimum representable time is
- ** not in the same minute that a leap second was deleted from,
- ** which is a safer assumption than using 58 would be.
- */
- if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
- return WRONG;
- saved_seconds = yourtm.tm_sec;
- yourtm.tm_sec = SECSPERMIN - 1;
- } else {
- saved_seconds = yourtm.tm_sec;
- yourtm.tm_sec = 0;
- }
- /*
- ** Do a binary search (this works whatever time_t's type is).
- */
- if (!TYPE_SIGNED(time_t)) {
- lo = 0;
- hi = lo - 1;
- } else if (!TYPE_INTEGRAL(time_t)) {
- if (sizeof(time_t) > sizeof(float))
- hi = (time_t) DBL_MAX;
- else hi = (time_t) FLT_MAX;
- lo = -hi;
- } else {
- lo = 1;
- for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
- lo *= 2;
- hi = -(lo + 1);
- }
- for ( ; ; ) {
- t = lo / 2 + hi / 2;
- if (t < lo)
- t = lo;
- else if (t > hi)
- t = hi;
- if ((*funcp)(&t, offset, &mytm, sp) == NULL) {
- /*
- ** Assume that t is too extreme to be represented in
- ** a struct tm; arrange things so that it is less
- ** extreme on the next pass.
- */
- dir = (t > 0) ? 1 : -1;
- } else dir = tmcomp(&mytm, &yourtm);
- if (dir != 0) {
- if (t == lo) {
- ++t;
- if (t <= lo)
- return WRONG;
- ++lo;
- } else if (t == hi) {
- --t;
- if (t >= hi)
- return WRONG;
- --hi;
- }
- if (lo > hi)
- return WRONG;
- if (dir > 0)
- hi = t;
- else lo = t;
- continue;
- }
- if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
- break;
- /*
- ** Right time, wrong type.
- ** Hunt for right time, right type.
- ** It's okay to guess wrong since the guess
- ** gets checked.
- */
- /*
- ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
- */
- for (i = sp->typecnt - 1; i >= 0; --i) {
- if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
- continue;
- for (j = sp->typecnt - 1; j >= 0; --j) {
- if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
- continue;
- newt = t + sp->ttis[j].tt_gmtoff -
- sp->ttis[i].tt_gmtoff;
- if ((*funcp)(&newt, offset, &mytm, sp) == NULL)
- continue;
- if (tmcomp(&mytm, &yourtm) != 0)
- continue;
- if (mytm.tm_isdst != yourtm.tm_isdst)
- continue;
- /*
- ** We have a match.
- */
- t = newt;
- goto label;
- }
- }
- return WRONG;
- }
-label:
- newt = t + saved_seconds;
- if ((newt < t) != (saved_seconds < 0))
- return WRONG;
- t = newt;
- if ((*funcp)(&t, offset, tmp, sp))
- *okayp = TRUE;
- return t;
-}
-
-static time_t time2(struct tm *tmp, struct tm * (* const funcp) (const time_t*, long, struct tm*, const struct state *sp), const long offset, int *okayp, const struct state *sp)
-{
- time_t t;
-
- /*! \note
- ** First try without normalization of seconds
- ** (in case tm_sec contains a value associated with a leap second).
- ** If that fails, try with normalization of seconds.
- */
- t = time2sub(tmp, funcp, offset, okayp, FALSE, sp);
- return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp);
-}
-
-static time_t time1(struct tm *tmp, struct tm * (* const funcp) (const time_t *, long, struct tm *, const struct state *), const long offset, const struct state *sp)
-{
- time_t t;
- int samei, otheri;
- int sameind, otherind;
- int i;
- int nseen;
- int seen[TZ_MAX_TYPES];
- int types[TZ_MAX_TYPES];
- int okay;
-
- if (tmp->tm_isdst > 1)
- tmp->tm_isdst = 1;
- t = time2(tmp, funcp, offset, &okay, sp);
-#ifdef PCTS
- /*
- ** PCTS code courtesy Grant Sullivan.
- */
- if (okay)
- return t;
- if (tmp->tm_isdst < 0)
- tmp->tm_isdst = 0; /* reset to std and try again */
-#endif /* defined PCTS */
-#ifndef PCTS
- if (okay || tmp->tm_isdst < 0)
- return t;
-#endif /* !defined PCTS */
- /*
- ** We're supposed to assume that somebody took a time of one type
- ** and did some math on it that yielded a "struct tm" that's bad.
- ** We try to divine the type they started from and adjust to the
- ** type they need.
- */
- if (sp == NULL)
- return WRONG;
- for (i = 0; i < sp->typecnt; ++i)
- seen[i] = FALSE;
- nseen = 0;
- for (i = sp->timecnt - 1; i >= 0; --i)
- if (!seen[sp->types[i]]) {
- seen[sp->types[i]] = TRUE;
- types[nseen++] = sp->types[i];
- }
- for (sameind = 0; sameind < nseen; ++sameind) {
- samei = types[sameind];
- if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
- continue;
- for (otherind = 0; otherind < nseen; ++otherind) {
- otheri = types[otherind];
- if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
- continue;
- tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
- tmp->tm_isdst = !tmp->tm_isdst;
- t = time2(tmp, funcp, offset, &okay, sp);
- if (okay)
- return t;
- tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
- tmp->tm_isdst = !tmp->tm_isdst;
- }
- }
- return WRONG;
-}
-
-time_t ast_mktime(struct tm *tmp, const char *zone)
-{
- const struct state *sp;
- if (!(sp = ast_tzset(zone)))
- return 0;
- return time1(tmp, localsub, 0L, sp);
-}
-
diff --git a/1.4/main/stdtime/private.h b/1.4/main/stdtime/private.h
deleted file mode 100644
index 11793088d..000000000
--- a/1.4/main/stdtime/private.h
+++ /dev/null
@@ -1,358 +0,0 @@
-#ifndef PRIVATE_H
-
-#define PRIVATE_H
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static char __attribute__((unused)) privatehid[] = "@(#)private.h 8.3";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#define GRANDPARENTED "Local time zone must be set--see zic manual page"
-
-/*
-** Defaults for preprocessor symbols.
-** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
-*/
-
-#ifndef HAVE_ADJTIME
-#define HAVE_ADJTIME 1
-#endif /* !defined HAVE_ADJTIME */
-
-#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT 0
-#endif /* !defined HAVE_GETTEXT */
-
-#ifndef HAVE_INCOMPATIBLE_CTIME_R
-#define HAVE_INCOMPATIBLE_CTIME_R 0
-#endif /* !defined INCOMPATIBLE_CTIME_R */
-
-#ifndef HAVE_SETTIMEOFDAY
-#define HAVE_SETTIMEOFDAY 3
-#endif /* !defined HAVE_SETTIMEOFDAY */
-
-#ifndef HAVE_STRERROR
-#define HAVE_STRERROR 1
-#endif /* !defined HAVE_STRERROR */
-
-#ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK 1
-#endif /* !defined HAVE_SYMLINK */
-
-#ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H 1
-#endif /* !defined HAVE_SYS_STAT_H */
-
-#ifndef HAVE_SYS_WAIT_H
-#define HAVE_SYS_WAIT_H 1
-#endif /* !defined HAVE_SYS_WAIT_H */
-
-#ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H 1
-#endif /* !defined HAVE_UNISTD_H */
-
-#ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H 0
-#endif /* !defined HAVE_UTMPX_H */
-
-#ifndef LOCALE_HOME
-#define LOCALE_HOME "/usr/lib/locale"
-#endif /* !defined LOCALE_HOME */
-
-#if HAVE_INCOMPATIBLE_CTIME_R
-#define asctime_r _incompatible_asctime_r
-#define ctime_r _incompatible_ctime_r
-#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-
-/*
-** Nested includes
-*/
-
-#include "sys/types.h" /* for time_t */
-#include "stdio.h"
-#include "errno.h"
-#include "string.h"
-#include "limits.h" /* for CHAR_BIT et al. */
-#include "time.h"
-#include "stdlib.h"
-
-#if HAVE_GETTEXT
-#include "libintl.h"
-#endif /* HAVE_GETTEXT */
-
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
-#endif /* HAVE_SYS_WAIT_H */
-
-#ifndef WIFEXITED
-#define WIFEXITED(status) (((status) & 0xff) == 0)
-#endif /* !defined WIFEXITED */
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
-#endif /* !defined WEXITSTATUS */
-
-#if HAVE_UNISTD_H
-#include "unistd.h" /* for F_OK and R_OK */
-#endif /* HAVE_UNISTD_H */
-
-#if !HAVE_UNISTD_H
-#ifndef F_OK
-#define F_OK 0
-#endif /* !defined F_OK */
-#ifndef R_OK
-#define R_OK 4
-#endif /* !defined R_OK */
-#endif /* !HAVE_UNISTD_H */
-
-/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
-#define is_digit(c) ((unsigned)(c) - '0' <= 9)
-
-/*
-** Define HAVE_STDINT_H's default value here, rather than at the
-** start, since __GLIBC__'s value depends on previously-included
-** files.
-** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
-*/
-#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H \
- (199901 <= __STDC_VERSION__ || \
- 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
-#endif /* !defined HAVE_STDINT_H */
-
-#if HAVE_STDINT_H
-#include "stdint.h"
-#endif /* !HAVE_STDINT_H */
-
-#ifndef INT_FAST64_MAX
-/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
-#if defined LLONG_MAX || defined __LONG_LONG_MAX__
-typedef long long int_fast64_t;
-#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#if (LONG_MAX >> 31) < 0xffffffff
-Please use a compiler that supports a 64-bit integer type (or wider);
-you may need to compile with "-DHAVE_STDINT_H".
-#endif /* (LONG_MAX >> 31) < 0xffffffff */
-typedef long int_fast64_t;
-#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#endif /* !defined INT_FAST64_MAX */
-
-#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffff
-#endif /* !defined INT32_MAX */
-#ifndef INT32_MIN
-#define INT32_MIN (-1 - INT32_MAX)
-#endif /* !defined INT32_MIN */
-
-/*
-** Workarounds for compilers/systems.
-*/
-
-/*
-** If your compiler lacks prototypes, "#define P(x) ()".
-*/
-
-#ifndef P
-#define P(x) x
-#endif /* !defined P */
-
-/*
-** SunOS 4.1.1 headers lack EXIT_SUCCESS.
-*/
-
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS 0
-#endif /* !defined EXIT_SUCCESS */
-
-/*
-** SunOS 4.1.1 headers lack EXIT_FAILURE.
-*/
-
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE 1
-#endif /* !defined EXIT_FAILURE */
-
-/*
-** SunOS 4.1.1 headers lack FILENAME_MAX.
-*/
-
-#ifndef FILENAME_MAX
-
-#ifndef MAXPATHLEN
-#ifdef unix
-#include "sys/param.h"
-#endif /* defined unix */
-#endif /* !defined MAXPATHLEN */
-
-#ifdef MAXPATHLEN
-#define FILENAME_MAX MAXPATHLEN
-#endif /* defined MAXPATHLEN */
-#ifndef MAXPATHLEN
-#define FILENAME_MAX 1024 /* Pure guesswork */
-#endif /* !defined MAXPATHLEN */
-
-#endif /* !defined FILENAME_MAX */
-
-/*
-** SunOS 4.1.1 libraries lack remove.
-*/
-
-#ifndef remove
-extern int unlink P((const char * filename));
-#define remove unlink
-#endif /* !defined remove */
-
-/*
-** Some ancient errno.h implementations don't declare errno.
-** But some newer errno.h implementations define it as a macro.
-** Fix the former without affecting the latter.
-*/
-
-#ifndef errno
-extern int errno;
-#endif /* !defined errno */
-
-/*
-** Private function declarations.
-*/
-
-char * icalloc P((int nelem, int elsize));
-char * icatalloc P((char * old, const char * new));
-char * icpyalloc P((const char * string));
-char * imalloc P((int n));
-void * irealloc P((void * pointer, int size));
-void icfree P((char * pointer));
-void ifree P((char * pointer));
-const char * scheck P((const char * string, const char * format));
-
-/*
-** Finally, some convenience items.
-*/
-
-#ifndef TRUE
-#define TRUE 1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE 0
-#endif /* !defined FALSE */
-
-#ifndef TYPE_BIT
-#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
-#endif /* !defined TYPE_BIT */
-
-#ifndef TYPE_SIGNED
-#define TYPE_SIGNED(type) (((type) -1) < 0)
-#endif /* !defined TYPE_SIGNED */
-
-/*
-** Since the definition of TYPE_INTEGRAL contains floating point numbers,
-** it cannot be used in preprocessor directives.
-*/
-
-#ifndef TYPE_INTEGRAL
-#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
-#endif /* !defined TYPE_INTEGRAL */
-
-#ifndef INT_STRLEN_MAXIMUM
-/*
-** 302 / 1000 is log10(2.0) rounded up.
-** Subtract one for the sign bit if the type is signed;
-** add one for integer division truncation;
-** add one more for a minus sign if the type is signed.
-*/
-#define INT_STRLEN_MAXIMUM(type) \
- ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
- 1 + TYPE_SIGNED(type))
-#endif /* !defined INT_STRLEN_MAXIMUM */
-
-/*
-** INITIALIZE(x)
-*/
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifndef lint
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x) ((x) = 0)
-#endif /* defined GNUC_or_lint */
-#ifndef GNUC_or_lint
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-/*
-** For the benefit of GNU folk...
-** `_(MSGID)' uses the current locale's message library string for MSGID.
-** The default is to use gettext if available, and use MSGID otherwise.
-*/
-
-#ifndef _
-#if HAVE_GETTEXT
-#define _(msgid) gettext(msgid)
-#else /* !HAVE_GETTEXT */
-#define _(msgid) msgid
-#endif /* !HAVE_GETTEXT */
-#endif /* !defined _ */
-
-#ifndef TZ_DOMAIN
-#define TZ_DOMAIN "tz"
-#endif /* !defined TZ_DOMAIN */
-
-#if HAVE_INCOMPATIBLE_CTIME_R
-#undef asctime_r
-#undef ctime_r
-char *asctime_r P((struct tm const *, char *));
-char *ctime_r P((time_t const *, char *));
-#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-
-#ifndef YEARSPERREPEAT
-#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
-#endif /* !defined YEARSPERREPEAT */
-
-/*
-** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
-*/
-
-#ifndef AVGSECSPERYEAR
-#define AVGSECSPERYEAR 31556952L
-#endif /* !defined AVGSECSPERYEAR */
-
-#ifndef SECSPERREPEAT
-#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
-#endif /* !defined SECSPERREPEAT */
-
-#ifndef SECSPERREPEAT_BITS
-#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
-#endif /* !defined SECSPERREPEAT_BITS */
-
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
-
-#endif /* !defined PRIVATE_H */
diff --git a/1.4/main/stdtime/test.c b/1.4/main/stdtime/test.c
deleted file mode 100644
index 9e8ce45da..000000000
--- a/1.4/main/stdtime/test.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/*! \file
- \brief Testing localtime functionality */
-
-#include "localtime.c"
-#include <sys/time.h>
-#include <stdio.h>
-
-int main(int argc, char **argv) {
- struct timeval tv;
- struct tm tm;
- char *zone[4] = { "America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles" };
- int i;
-
- gettimeofday(&tv,NULL);
-
- for (i=0;i<4;i++) {
- ast_localtime(&tv.tv_sec,&tm,zone[i]);
- printf("Localtime at %s is %04d/%02d/%02d %02d:%02d:%02d\n",zone[i],tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
- }
- return 0;
-}
diff --git a/1.4/main/stdtime/tzfile.h b/1.4/main/stdtime/tzfile.h
deleted file mode 100644
index 9201b967f..000000000
--- a/1.4/main/stdtime/tzfile.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef TZFILE_H
-
-#define TZFILE_H
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static char __attribute__((unused)) tzfilehid[] = "@(#)tzfile.h 8.1";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** Information about time zone files.
-*/
-
-#ifndef TZDIR
-#ifdef SOLARIS
-#define TZDIR "/usr/share/lib/zoneinfo"
-#else
-#define TZDIR "/usr/share/zoneinfo"
-#endif /* defined SOLARIS */
-#endif /* !defined TZDIR */
-
-#ifndef TZDEFAULT
-#define TZDEFAULT "localtime"
-#endif /* !defined TZDEFAULT */
-
-#ifndef TZDEFRULES
-#define TZDEFRULES "posixrules"
-#endif /* !defined TZDEFRULES */
-
-/*
-** Each file begins with. . .
-*/
-
-#define TZ_MAGIC "TZif"
-
-struct tzhead {
- char tzh_magic[4]; /* TZ_MAGIC */
- char tzh_version[1]; /* '\0' or '2' as of 2005 */
- char tzh_reserved[15]; /* reserved--must be zero */
- char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
- char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
- char tzh_leapcnt[4]; /* coded number of leap seconds */
- char tzh_timecnt[4]; /* coded number of transition times */
- char tzh_typecnt[4]; /* coded number of local time types */
- char tzh_charcnt[4]; /* coded number of abbr. chars */
-};
-
-/*
-** . . .followed by. . .
-**
-** tzh_timecnt (char [4])s coded transition times a la time(2)
-** tzh_timecnt (unsigned char)s types of local time starting at above
-** tzh_typecnt repetitions of
-** one (char [4]) coded UTC offset in seconds
-** one (unsigned char) used to set tm_isdst
-** one (unsigned char) that's an abbreviation list index
-** tzh_charcnt (char)s '\0'-terminated zone abbreviations
-** tzh_leapcnt repetitions of
-** one (char [4]) coded leap second transition times
-** one (char [4]) total correction after above
-** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
-** time is standard time, if FALSE,
-** transition time is wall clock time
-** if absent, transition times are
-** assumed to be wall clock time
-** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
-** time is UTC, if FALSE,
-** transition time is local time
-** if absent, transition times are
-** assumed to be local time
-*/
-
-/*
-** If tzh_version is '2' or greater, the above is followed by a second instance
-** of tzhead and a second instance of the data in which each coded transition
-** time uses 8 rather than 4 chars,
-** then a POSIX-TZ-environment-variable-style string for use in handling
-** instants after the last transition time stored in the file
-** (with nothing between the newlines if there is no POSIX representation for
-** such instants).
-*/
-
-/*
-** In the current implementation, "tzset()" refuses to deal with files that
-** exceed any of the limits below.
-*/
-
-#ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES 1200
-#endif /* !defined TZ_MAX_TIMES */
-
-#ifndef TZ_MAX_TYPES
-#ifndef NOSOLAR
-#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-#ifdef NOSOLAR
-/*
-** Must be at least 14 for Europe/Riga as of Jan 12 1995,
-** as noted by Earl Chew.
-*/
-#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
-#endif /* !defined TZ_MAX_TYPES */
-
-#ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
- /* (limited by what unsigned chars can hold) */
-#endif /* !defined TZ_MAX_CHARS */
-
-#ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
-#endif /* !defined TZ_MAX_LEAPS */
-
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
-
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-
-/*
-** Since everything in isleap is modulo 400 (or a factor of 400), we know that
-** isleap(y) == isleap(y % 400)
-** and so
-** isleap(a + b) == isleap((a + b) % 400)
-** or
-** isleap(a + b) == isleap(a % 400 + b % 400)
-** This is true even if % means modulo rather than Fortran remainder
-** (which is allowed by C89 but not C99).
-** We use this to avoid addition overflow problems.
-*/
-
-#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
-
-#endif /* !defined TZFILE_H */
diff --git a/1.4/main/strcompat.c b/1.4/main/strcompat.c
deleted file mode 100644
index 243ef76cb..000000000
--- a/1.4/main/strcompat.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Compatibility functions for strsep and strtoq missing on Solaris
- */
-
-#include "asterisk.h"
-
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#ifndef HAVE_STRSEP
-char *strsep(char **str, const char *delims)
-{
- char *token;
-
- if (!*str) {
- /* No more tokens */
- return NULL;
- }
-
- token = *str;
- while (**str != '\0') {
- if (strchr(delims, **str)) {
- **str = '\0';
- (*str)++;
- return token;
- }
- (*str)++;
- }
-
- /* There is no other token */
- *str = NULL;
-
- return token;
-}
-#endif
-
-#ifndef HAVE_SETENV
-int setenv(const char *name, const char *value, int overwrite)
-{
- unsigned char *buf;
- int buflen;
-
- buflen = strlen(name) + strlen(value) + 2;
- buf = alloca(buflen);
-
- if (!overwrite && getenv(name))
- return 0;
-
- snprintf(buf, buflen, "%s=%s", name, value);
-
- return putenv(buf);
-}
-#endif
-
-#ifndef HAVE_UNSETENV
-int unsetenv(const char *name)
-{
- return setenv(name, "", 0);
-}
-#endif
-
-#ifndef HAVE_STRCASESTR
-static char *upper(const char *orig, char *buf, int bufsize)
-{
- int i = 0;
-
- while (i < (bufsize - 1) && orig[i]) {
- buf[i] = toupper(orig[i]);
- i++;
- }
-
- buf[i] = '\0';
-
- return buf;
-}
-
-char *strcasestr(const char *haystack, const char *needle)
-{
- char *u1, *u2;
- int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
-
- u1 = alloca(u1len);
- u2 = alloca(u2len);
- if (u1 && u2) {
- char *offset;
- if (u2len > u1len) {
- /* Needle bigger than haystack */
- return NULL;
- }
- offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
- if (offset) {
- /* Return the offset into the original string */
- return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
-}
-#endif /* !HAVE_STRCASESTR */
-
-#ifndef HAVE_STRNLEN
-size_t strnlen(const char *s, size_t n)
-{
- size_t len;
-
- for (len = 0; len < n; len++)
- if (s[len] == '\0')
- break;
-
- return len;
-}
-#endif /* !HAVE_STRNLEN */
-
-#if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
-char *strndup(const char *s, size_t n)
-{
- size_t len = strnlen(s, n);
- char *new = malloc(len + 1);
-
- if (!new)
- return NULL;
-
- new[len] = '\0';
- return memcpy(new, s, len);
-}
-#endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
-
-#if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
-int vasprintf(char **strp, const char *fmt, va_list ap)
-{
- int size;
- va_list ap2;
- char s;
-
- *strp = NULL;
- va_copy(ap2, ap);
- size = vsnprintf(&s, 1, fmt, ap2);
- va_end(ap2);
- *strp = malloc(size + 1);
- if (!*strp)
- return -1;
- vsnprintf(*strp, size + 1, fmt, ap);
-
- return size;
-}
-#endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
-
-/*
- * Based on Code from bsd-asprintf from OpenSSH
- * Copyright (c) 2004 Darren Tucker.
- *
- * Based originally on asprintf.c from OpenBSD:
- * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
-int asprintf(char **str, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- *str = NULL;
- va_start(ap, fmt);
- ret = vasprintf(str, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-#endif /* !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
-
-#ifndef HAVE_STRTOQ
-#ifndef LONG_MIN
-#define LONG_MIN (-9223372036854775807L-1L)
- /* min value of a "long int" */
-#endif
-#ifndef LONG_MAX
-#define LONG_MAX 9223372036854775807L
- /* max value of a "long int" */
-#endif
-
-/*! \brief
- * Convert a string to a quad integer.
- *
- * \note Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-uint64_t strtoq(const char *nptr, char **endptr, int base)
-{
- const char *s;
- uint64_t acc;
- unsigned char c;
- uint64_t qbase, cutoff;
- int neg, any, cutlim;
-
- /*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
- */
- s = nptr;
- do {
- c = *s++;
- } while (isspace(c));
- if (c == '-') {
- neg = 1;
- c = *s++;
- } else {
- neg = 0;
- if (c == '+')
- c = *s++;
- }
- if ((base == 0 || base == 16) &&
- c == '\0' && (*s == 'x' || *s == 'X')) {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '\0' ? 8 : 10;
-
- /*
- * Compute the cutoff value between legal numbers and illegal
- * numbers. That is the largest legal value, divided by the
- * base. An input number that is greater than this value, if
- * followed by a legal input character, is too big. One that
- * is equal to this value may be valid or not; the limit
- * between valid and invalid numbers is then based on the last
- * digit. For instance, if the range for quads is
- * [-9223372036854775808..9223372036854775807] and the input base
- * is 10, cutoff will be set to 922337203685477580 and cutlim to
- * either 7 (neg==0) or 8 (neg==1), meaning that if we have
- * accumulated a value > 922337203685477580, or equal but the
- * next digit is > 7 (or 8), the number is too big, and we will
- * return a range error.
- *
- * Set any if any `digits' consumed; make it negative to indicate
- * overflow.
- */
- qbase = (unsigned)base;
- cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
- cutlim = cutoff % qbase;
- cutoff /= qbase;
- for (acc = 0, any = 0;; c = *s++) {
- if (!isascii(c))
- break;
- if (isdigit(c))
- c -= '\0';
- else if (isalpha(c))
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
- any = -1;
- else {
- any = 1;
- acc *= qbase;
- acc += c;
- }
- }
- if (any < 0) {
- acc = neg ? LONG_MIN : LONG_MAX;
- } else if (neg)
- acc = -acc;
- if (endptr != 0)
- *((const char **)endptr) = any ? s - 1 : nptr;
- return acc;
-}
-#endif /* !HAVE_STRTOQ */
-
-#ifndef HAVE_GETLOADAVG
-#ifdef linux
-/*! \brief Alternative method of getting load avg on Linux only */
-int getloadavg(double *list, int nelem)
-{
- FILE *LOADAVG;
- double avg[3] = { 0.0, 0.0, 0.0 };
- int i, res = -1;
-
- if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
- fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
- res = 0;
- fclose(LOADAVG);
- }
-
- for (i = 0; (i < nelem) && (i < 3); i++) {
- list[i] = avg[i];
- }
-
- return res;
-}
-#else /* !linux */
-/*! \brief Return something that won't cancel the call, but still return -1, in case
- * we correct the implementation to check return value */
-int getloadavg(double *list, int nelem)
-{
- int i;
-
- for (i = 0; i < nelem; i++) {
- list[i] = 0.1;
- }
- return -1;
-}
-#endif /* linux */
-#endif /* !HAVE_GETLOADAVG */
-
-
-/*
- * For strlcat()
- *
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-#ifndef HAVE_STRLCAT
-size_t strlcat(char *dst, const char *src, size_t siz)
-{
- register char *d = dst;
- register const char *s = src;
- register size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return dlen + strlen(s);
-
- while (*s != '\0') {
- if (n != 1) {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return dlen + (s - src); /* count does not include NUL */
-}
-#endif /* HAVE_STRLCAT */
-
-/*
- * For strlcpy()
- *
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t siz)
-{
- register char *d = dst;
- register const char *s = src;
- register size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0) {
- do {
- if ((*d++ = *s++) == 0)
- break;
- } while (--n != 0);
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return s - src - 1; /* count does not include NUL */
-}
-#endif /* HAVE_STRLCPY */
diff --git a/1.4/main/tdd.c b/1.4/main/tdd.c
deleted file mode 100644
index f1d7cf471..000000000
--- a/1.4/main/tdd.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief TTY/TDD Generation support
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note Includes code and algorithms from the Zapata library.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <time.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <math.h>
-#include <ctype.h>
-
-#include "asterisk/ulaw.h"
-#include "asterisk/tdd.h"
-#include "asterisk/logger.h"
-#include "asterisk/fskmodem.h"
-#include "ecdisa.h"
-
-struct tdd_state {
- fsk_data fskd;
- char rawdata[256];
- short oldstuff[4096];
- int oldlen;
- int pos;
- int modo;
- int mode;
- int charnum;
-};
-
-static float dr[4], di[4];
-static float tddsb = 176.0; /* 45.5 baud */
-
-#define TDD_SPACE 1800.0 /* 1800 hz for "0" */
-#define TDD_MARK 1400.0 /* 1400 hz for "1" */
-
-static int tdd_decode_baudot(struct tdd_state *tdd,unsigned char data) /* covert baudot into ASCII */
-{
- static char ltrs[32] = { '<','E','\n','A',' ','S','I','U',
- '\n','D','R','J','N','F','C','K',
- 'T','Z','L','W','H','Y','P','Q',
- 'O','B','G','^','M','X','V','^' };
- static char figs[32] = { '<','3','\n','-',' ','\'','8','7',
- '\n','$','4','\'',',','!',':','(',
- '5','\"',')','2','=','6','0','1',
- '9','?','+','^','.','/',';','^' };
- int d = 0; /* return 0 if not decodeable */
- switch (data) {
- case 0x1f:
- tdd->modo = 0;
- break;
- case 0x1b:
- tdd->modo = 1;
- break;
- default:
- if (tdd->modo == 0)
- d = ltrs[data];
- else
- d = figs[data];
- break;
- }
- return d;
-}
-
-void tdd_init(void)
-{
- /* Initialize stuff for inverse FFT */
- dr[0] = cos(TDD_SPACE * 2.0 * M_PI / 8000.0);
- di[0] = sin(TDD_SPACE * 2.0 * M_PI / 8000.0);
- dr[1] = cos(TDD_MARK * 2.0 * M_PI / 8000.0);
- di[1] = sin(TDD_MARK * 2.0 * M_PI / 8000.0);
-}
-
-struct tdd_state *tdd_new(void)
-{
- struct tdd_state *tdd;
- tdd = calloc(1, sizeof(*tdd));
- if (tdd) {
- tdd->fskd.spb = 176; /* 45.5 baud */
- tdd->fskd.hdlc = 0; /* Async */
- tdd->fskd.nbit = 5; /* 5 bits */
- tdd->fskd.nstop = 1.5; /* 1.5 stop bits */
- tdd->fskd.paridad = 0; /* No parity */
- tdd->fskd.bw=0; /* Filter 75 Hz */
- tdd->fskd.f_mark_idx = 0; /* 1400 Hz */
- tdd->fskd.f_space_idx = 1; /* 1800 Hz */
- tdd->fskd.pcola = 0; /* No clue */
- tdd->fskd.cont = 0; /* Digital PLL reset */
- tdd->fskd.x0 = 0.0;
- tdd->fskd.state = 0;
- tdd->pos = 0;
- tdd->mode = 0;
- tdd->charnum = 0;
- } else
- ast_log(LOG_WARNING, "Out of memory\n");
- return tdd;
-}
-
-int ast_tdd_gen_ecdisa(unsigned char *outbuf, int len)
-{
- int pos = 0;
- int cnt;
- while (len) {
- cnt = len > sizeof(ecdisa) ? sizeof(ecdisa) : len;
- memcpy(outbuf + pos, ecdisa, cnt);
- pos += cnt;
- len -= cnt;
- }
- return 0;
-}
-
-int tdd_feed(struct tdd_state *tdd, unsigned char *ubuf, int len)
-{
- int mylen = len;
- int olen;
- int b = 'X';
- int res;
- int c,x;
- short *buf = calloc(1, 2 * len + tdd->oldlen);
- short *obuf = buf;
- if (!buf) {
- ast_log(LOG_WARNING, "Out of memory\n");
- return -1;
- }
- memcpy(buf, tdd->oldstuff, tdd->oldlen);
- mylen += tdd->oldlen/2;
- for (x = 0; x < len; x++)
- buf[x + tdd->oldlen / 2] = AST_MULAW(ubuf[x]);
- c = res = 0;
- while (mylen >= 1320) { /* has to have enough to work on */
- olen = mylen;
- res = fsk_serie(&tdd->fskd, buf, &mylen, &b);
- if (mylen < 0) {
- ast_log(LOG_ERROR, "fsk_serial made mylen < 0 (%d) (olen was %d)\n", mylen, olen);
- free(obuf);
- return -1;
- }
- buf += (olen - mylen);
- if (res < 0) {
- ast_log(LOG_NOTICE, "fsk_serial failed\n");
- free(obuf);
- return -1;
- }
- if (res == 1) {
- /* Ignore invalid bytes */
- if (b > 0x7f)
- continue;
- c = tdd_decode_baudot(tdd,b);
- if ((c < 1) || (c > 126))
- continue; /* if not valid */
- break;
- }
- }
- if (mylen) {
- memcpy(tdd->oldstuff, buf, mylen * 2);
- tdd->oldlen = mylen * 2;
- } else
- tdd->oldlen = 0;
- free(obuf);
- if (res) {
- tdd->mode = 2;
-/* put it in mode where it
- reliably puts teleprinter in correct shift mode */
- return(c);
- }
- return 0;
-}
-
-void tdd_free(struct tdd_state *tdd)
-{
- free(tdd);
-}
-
-static inline float tdd_getcarrier(float *cr, float *ci, int bit)
-{
- /* Move along. There's nothing to see here... */
- float t;
- t = *cr * dr[bit] - *ci * di[bit];
- *ci = *cr * di[bit] + *ci * dr[bit];
- *cr = t;
-
- t = 2.0 - (*cr * *cr + *ci * *ci);
- *cr *= t;
- *ci *= t;
- return *cr;
-}
-
-#define PUT_BYTE(a) do { \
- *(buf++) = (a); \
- bytes++; \
-} while(0)
-
-#define PUT_AUDIO_SAMPLE(y) do { \
- int index = (short)(rint(8192.0 * (y))); \
- *(buf++) = AST_LIN2MU(index); \
- bytes++; \
-} while(0)
-
-#define PUT_TDD_MARKMS do { \
- int x; \
- for (x=0;x<8;x++) \
- PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, 1)); \
-} while(0)
-
-#define PUT_TDD_BAUD(bit) do { \
- while (scont < tddsb) { \
- PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, bit)); \
- scont += 1.0; \
- } \
- scont -= tddsb; \
-} while(0)
-
-#define PUT_TDD_STOP do { \
- while (scont < (tddsb * 1.5)) { \
- PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, 1)); \
- scont += 1.0; \
- } \
- scont -= (tddsb * 1.5); \
-} while(0)
-
-
-#define PUT_TDD(byte) do { \
- int z; \
- unsigned char b = (byte); \
- PUT_TDD_BAUD(0); /* Start bit */ \
- for (z = 0; z < 5; z++) { \
- PUT_TDD_BAUD(b & 1); \
- b >>= 1; \
- } \
- PUT_TDD_STOP; /* Stop bit */ \
-} while(0);
-
-int tdd_generate(struct tdd_state *tdd, unsigned char *buf, const char *str)
-{
- int bytes=0;
- int i,x;
- char c;
- /*! Baudot letters */
- static unsigned char lstr[31] = "\000E\nA SIU\rDRJNFCKTZLWHYPQOBG\000MXV";
- /*! Baudot figures */
- static unsigned char fstr[31] = "\0003\n- \00787\r$4',!:(5\")2\0006019?+\000./;";
- /* Initial carriers (real/imaginary) */
- float cr = 1.0;
- float ci = 0.0;
- float scont = 0.0;
-
- for(x = 0; str[x]; x++) {
- /* Do synch for each 72th character */
- if ( (tdd->charnum++) % 72 == 0)
- PUT_TDD(tdd->mode ? 27 /* FIGS */ : 31 /* LTRS */);
-
- c = toupper(str[x]);
-#if 0
- printf("%c",c); fflush(stdout);
-#endif
- if (c == 0) { /* send null */
- PUT_TDD(0);
- continue;
- }
- if (c == '\r') { /* send c/r */
- PUT_TDD(8);
- continue;
- }
- if (c == '\n') { /* send c/r and l/f */
- PUT_TDD(8);
- PUT_TDD(2);
- continue;
- }
- if (c == ' ') { /* send space */
- PUT_TDD(4);
- continue;
- }
- for (i = 0; i < 31; i++) {
- if (lstr[i] == c)
- break;
- }
- if (i < 31) { /* if we found it */
- if (tdd->mode) { /* if in figs mode, change it */
- PUT_TDD(31); /* Send LTRS */
- tdd->mode = 0;
- }
- PUT_TDD(i);
- continue;
- }
- for (i = 0; i < 31; i++) {
- if (fstr[i] == c)
- break;
- }
- if (i < 31) { /* if we found it */
- if (tdd->mode != 1) { /* if in ltrs mode, change it */
- PUT_TDD(27); /* send FIGS */
- tdd->mode = 1;
- }
- PUT_TDD(i); /* send byte */
- continue;
- }
- }
- return bytes;
-}
-
diff --git a/1.4/main/term.c b/1.4/main/term.c
deleted file mode 100644
index d051338d8..000000000
--- a/1.4/main/term.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Terminal Routines
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "asterisk/term.h"
-#include "asterisk/options.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-static int vt100compat;
-
-static char prepdata[80] = "";
-static char enddata[80] = "";
-static char quitdata[80] = "";
-
-static const char *termpath[] = {
- "/usr/share/terminfo",
- "/usr/local/share/misc/terminfo",
- "/usr/lib/terminfo",
- NULL
- };
-
-/* Ripped off from Ross Ridge, but it's public domain code (libmytinfo) */
-static short convshort(char *s)
-{
- register int a,b;
-
- a = (int) s[0] & 0377;
- b = (int) s[1] & 0377;
-
- if (a == 0377 && b == 0377)
- return -1;
- if (a == 0376 && b == 0377)
- return -2;
-
- return a + b * 256;
-}
-
-int ast_term_init(void)
-{
- char *term = getenv("TERM");
- char termfile[256] = "";
- char buffer[512] = "";
- int termfd = -1, parseokay = 0, i;
-
- if (!term)
- return 0;
- if (!ast_opt_console || ast_opt_no_color || !ast_opt_no_fork)
- return 0;
-
- for (i=0 ;; i++) {
- if (termpath[i] == NULL) {
- break;
- }
- snprintf(termfile, sizeof(termfile), "%s/%c/%s", termpath[i], *term, term);
- termfd = open(termfile, O_RDONLY);
- if (termfd > -1) {
- break;
- }
- }
- if (termfd > -1) {
- int actsize = read(termfd, buffer, sizeof(buffer) - 1);
- short sz_names = convshort(buffer + 2);
- short sz_bools = convshort(buffer + 4);
- short n_nums = convshort(buffer + 6);
-
- /* if ((sz_names + sz_bools) & 1)
- sz_bools++; */
-
- if (sz_names + sz_bools + n_nums < actsize) {
- /* Offset 13 is defined in /usr/include/term.h, though we do not
- * include it here, as it conflicts with include/asterisk/term.h */
- short max_colors = convshort(buffer + 12 + sz_names + sz_bools + 13 * 2);
- if (max_colors > 0) {
- vt100compat = 1;
- }
- parseokay = 1;
- }
- close(termfd);
- }
-
- if (!parseokay) {
- /* These comparisons should not be substrings nor case-insensitive, as
- * terminal types are very particular about how they treat suffixes and
- * capitalization. For example, terminal type 'linux-m' does NOT
- * support color, while 'linux' does. Not even all vt100* terminals
- * support color, either (e.g. 'vt100+fnkeys'). */
- if (!strcmp(term, "linux")) {
- vt100compat = 1;
- } else if (!strcmp(term, "xterm")) {
- vt100compat = 1;
- } else if (!strcmp(term, "xterm-color")) {
- vt100compat = 1;
- } else if (!strncmp(term, "Eterm", 5)) {
- /* Both entries which start with Eterm support color */
- vt100compat = 1;
- } else if (!strcmp(term, "vt100")) {
- vt100compat = 1;
- } else if (!strncmp(term, "crt", 3)) {
- /* Both crt terminals support color */
- vt100compat = 1;
- }
- }
-
- if (vt100compat) {
- /* Make commands show up in nice colors */
- snprintf(prepdata, sizeof(prepdata), "%c[%d;%d;%dm", ESC, ATTR_BRIGHT, COLOR_BROWN, COLOR_BLACK + 10);
- snprintf(enddata, sizeof(enddata), "%c[%d;%d;%dm", ESC, ATTR_RESET, COLOR_WHITE, COLOR_BLACK + 10);
- snprintf(quitdata, sizeof(quitdata), "%c[0m", ESC);
- }
- return 0;
-}
-
-char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
-{
- int attr=0;
- char tmp[40];
- if (!vt100compat) {
- ast_copy_string(outbuf, inbuf, maxout);
- return outbuf;
- }
- if (!fgcolor && !bgcolor) {
- ast_copy_string(outbuf, inbuf, maxout);
- return outbuf;
- }
- if ((fgcolor & 128) && (bgcolor & 128)) {
- /* Can't both be highlighted */
- ast_copy_string(outbuf, inbuf, maxout);
- return outbuf;
- }
- if (!bgcolor)
- bgcolor = COLOR_BLACK;
-
- if (bgcolor) {
- bgcolor &= ~128;
- bgcolor += 10;
- }
- if (fgcolor & 128) {
- attr = ATTR_BRIGHT;
- fgcolor &= ~128;
- }
- if (fgcolor && bgcolor) {
- snprintf(tmp, sizeof(tmp), "%d;%d", fgcolor, bgcolor);
- } else if (bgcolor) {
- snprintf(tmp, sizeof(tmp), "%d", bgcolor);
- } else if (fgcolor) {
- snprintf(tmp, sizeof(tmp), "%d", fgcolor);
- }
- if (attr) {
- snprintf(outbuf, maxout, "%c[%d;%sm%s%c[0;%d;%dm", ESC, attr, tmp, inbuf, ESC, COLOR_WHITE, COLOR_BLACK + 10);
- } else {
- snprintf(outbuf, maxout, "%c[%sm%s%c[0;%d;%dm", ESC, tmp, inbuf, ESC, COLOR_WHITE, COLOR_BLACK + 10);
- }
- return outbuf;
-}
-
-char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout)
-{
- int attr=0;
- char tmp[40];
- if ((!vt100compat) || (!fgcolor && !bgcolor)) {
- *outbuf = '\0';
- return outbuf;
- }
- if ((fgcolor & 128) && (bgcolor & 128)) {
- /* Can't both be highlighted */
- *outbuf = '\0';
- return outbuf;
- }
- if (!bgcolor)
- bgcolor = COLOR_BLACK;
-
- if (bgcolor) {
- bgcolor &= ~128;
- bgcolor += 10;
- }
- if (fgcolor & 128) {
- attr = ATTR_BRIGHT;
- fgcolor &= ~128;
- }
- if (fgcolor && bgcolor) {
- snprintf(tmp, sizeof(tmp), "%d;%d", fgcolor, bgcolor);
- } else if (bgcolor) {
- snprintf(tmp, sizeof(tmp), "%d", bgcolor);
- } else if (fgcolor) {
- snprintf(tmp, sizeof(tmp), "%d", fgcolor);
- }
- if (attr) {
- snprintf(outbuf, maxout, "%c[%d;%sm", ESC, attr, tmp);
- } else {
- snprintf(outbuf, maxout, "%c[%sm", ESC, tmp);
- }
- return outbuf;
-}
-
-char *term_strip(char *outbuf, char *inbuf, int maxout)
-{
- char *outbuf_ptr = outbuf, *inbuf_ptr = inbuf;
-
- while (outbuf_ptr < outbuf + maxout) {
- switch (*inbuf_ptr) {
- case ESC:
- while (*inbuf_ptr && (*inbuf_ptr != 'm'))
- inbuf_ptr++;
- break;
- default:
- *outbuf_ptr = *inbuf_ptr;
- outbuf_ptr++;
- }
- if (! *inbuf_ptr)
- break;
- inbuf_ptr++;
- }
- return outbuf;
-}
-
-char *term_prompt(char *outbuf, const char *inbuf, int maxout)
-{
- if (!vt100compat) {
- ast_copy_string(outbuf, inbuf, maxout);
- return outbuf;
- }
- snprintf(outbuf, maxout, "%c[%d;%d;%dm%c%c[%d;%d;%dm%s",
- ESC, ATTR_BRIGHT, COLOR_BLUE, COLOR_BLACK + 10,
- inbuf[0],
- ESC, 0, COLOR_WHITE, COLOR_BLACK + 10,
- inbuf + 1);
- return outbuf;
-}
-
-/* filter escape sequences */
-void term_filter_escapes(char *line)
-{
- int i;
- int len = strlen(line);
-
- for (i = 0; i < len; i++) {
- if (line[i] != ESC)
- continue;
- if ((i < (len - 2)) &&
- (line[i + 1] == 0x5B)) {
- switch (line[i + 2]) {
- case 0x30:
- case 0x31:
- case 0x33:
- continue;
- }
- }
- /* replace ESC with a space */
- line[i] = ' ';
- }
-}
-
-char *term_prep(void)
-{
- return prepdata;
-}
-
-char *term_end(void)
-{
- return enddata;
-}
-
-char *term_quit(void)
-{
- return quitdata;
-}
diff --git a/1.4/main/threadstorage.c b/1.4/main/threadstorage.c
deleted file mode 100644
index 54b37b073..000000000
--- a/1.4/main/threadstorage.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Kevin P. Fleming <kpfleming@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.
- */
-
-/*! \file
- *
- * \brief Debugging support for thread-local-storage objects
- *
- * \author Kevin P. Fleming <kpfleming@digium.com>
- */
-
-#include "asterisk.h"
-
-#if defined(DEBUG_THREADLOCALS)
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/strings.h"
-#include "asterisk/utils.h"
-#include "asterisk/threadstorage.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/cli.h"
-
-struct tls_object {
- void *key;
- size_t size;
- const char *file;
- const char *function;
- unsigned int line;
- pthread_t thread;
- AST_LIST_ENTRY(tls_object) entry;
-};
-
-static AST_LIST_HEAD_NOLOCK_STATIC(tls_objects, tls_object);
-AST_MUTEX_DEFINE_STATIC_NOTRACKING(threadstoragelock);
-
-
-void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line)
-{
- struct tls_object *to;
-
- if (!(to = ast_calloc(1, sizeof(*to))))
- return;
-
- to->key = key;
- to->size = len;
- to->file = file;
- to->function = function;
- to->line = line;
- to->thread = pthread_self();
-
- ast_mutex_lock(&threadstoragelock);
- AST_LIST_INSERT_TAIL(&tls_objects, to, entry);
- ast_mutex_unlock(&threadstoragelock);
-}
-
-void __ast_threadstorage_object_remove(void *key)
-{
- struct tls_object *to;
-
- ast_mutex_lock(&threadstoragelock);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&tls_objects, to, entry) {
- if (to->key == key) {
- AST_LIST_REMOVE_CURRENT(&tls_objects, entry);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- ast_mutex_unlock(&threadstoragelock);
- if (to)
- free(to);
-}
-
-void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len)
-{
- struct tls_object *to;
-
- ast_mutex_lock(&threadstoragelock);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&tls_objects, to, entry) {
- if (to->key == key_old) {
- to->key = key_new;
- to->size = len;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- ast_mutex_unlock(&threadstoragelock);
-}
-
-static int handle_show_allocations(int fd, int argc, char *argv[])
-{
- char *fn = NULL;
- size_t len = 0;
- unsigned int count = 0;
- struct tls_object *to;
-
- if (argc > 3)
- fn = argv[3];
-
- ast_mutex_lock(&threadstoragelock);
-
- AST_LIST_TRAVERSE(&tls_objects, to, entry) {
- if (fn && strcasecmp(to->file, fn))
- continue;
-
- ast_cli(fd, "%10d bytes allocated in %20s at line %5d of %25s (thread %p)\n",
- (int) to->size, to->function, to->line, to->file, (void *) to->thread);
- len += to->size;
- count++;
- }
-
- ast_mutex_unlock(&threadstoragelock);
-
- ast_cli(fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
-
- return RESULT_SUCCESS;
-}
-
-static int handle_show_summary(int fd, int argc, char *argv[])
-{
- char *fn = NULL;
- size_t len = 0;
- unsigned int count = 0;
- struct tls_object *to;
- struct file {
- const char *name;
- size_t len;
- unsigned int count;
- AST_LIST_ENTRY(file) entry;
- } *file;
- AST_LIST_HEAD_NOLOCK_STATIC(file_summary, file);
-
- if (argc > 3)
- fn = argv[3];
-
- ast_mutex_lock(&threadstoragelock);
-
- AST_LIST_TRAVERSE(&tls_objects, to, entry) {
- if (fn && strcasecmp(to->file, fn))
- continue;
-
- AST_LIST_TRAVERSE(&file_summary, file, entry) {
- if ((!fn && (file->name == to->file)) || (fn && (file->name == to->function)))
- break;
- }
-
- if (!file) {
- file = alloca(sizeof(*file));
- memset(file, 0, sizeof(*file));
- file->name = fn ? to->function : to->file;
- AST_LIST_INSERT_TAIL(&file_summary, file, entry);
- }
-
- file->len += to->size;
- file->count++;
- }
-
- ast_mutex_unlock(&threadstoragelock);
-
- AST_LIST_TRAVERSE(&file_summary, file, entry) {
- len += file->len;
- count += file->count;
- if (fn) {
- ast_cli(fd, "%10d bytes in %d allocation%ss in function %s\n",
- (int) file->len, file->count, file->count > 1 ? "s" : "", file->name);
- } else {
- ast_cli(fd, "%10d bytes in %d allocation%s in file %s\n",
- (int) file->len, file->count, file->count > 1 ? "s" : "", file->name);
- }
- }
-
- ast_cli(fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
-
- return RESULT_SUCCESS;
-}
-
-static struct ast_cli_entry cli[] = {
- {
- .cmda = { "threadstorage", "show", "allocations", NULL },
- .handler = handle_show_allocations,
- .summary = "Display outstanding thread local storage allocations",
- .usage =
- "Usage: threadstorage show allocations [<file>]\n"
- " Dumps a list of all thread-specific memory allocations,\n"
- "optionally limited to those from a specific file\n",
- },
- {
- .cmda = { "threadstorage", "show", "summary", NULL },
- .handler = handle_show_summary,
- .summary = "Summarize outstanding memory allocations",
- .usage =
- "Usage: threadstorage show summary [<file>]\n"
- " Summarizes thread-specific memory allocations by file, or optionally\n"
- "by function, if a file is specified\n",
- },
-};
-
-void threadstorage_init(void)
-{
- ast_cli_register_multiple(cli, sizeof(cli) / sizeof(cli[0]));
-}
-
-#else /* !defined(DEBUG_THREADLOCALS) */
-
-void threadstorage_init(void)
-{
-}
-
-#endif /* !defined(DEBUG_THREADLOCALS) */
-
diff --git a/1.4/main/translate.c b/1.4/main/translate.c
deleted file mode 100644
index 3f5466d1f..000000000
--- a/1.4/main/translate.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Translate via the use of pseudo channels
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/translate.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/frame.h"
-#include "asterisk/sched.h"
-#include "asterisk/cli.h"
-#include "asterisk/term.h"
-
-#define MAX_RECALC 200 /* max sample recalc */
-
-/*! \brief the list of translators */
-static AST_LIST_HEAD_STATIC(translators, ast_translator);
-
-struct translator_path {
- struct ast_translator *step; /*!< Next step translator */
- unsigned int cost; /*!< Complete cost to destination */
- unsigned int multistep; /*!< Multiple conversions required for this translation */
-};
-
-/*! \brief a matrix that, for any pair of supported formats,
- * indicates the total cost of translation and the first step.
- * The full path can be reconstricted iterating on the matrix
- * until step->dstfmt == desired_format.
- *
- * Array indexes are 'src' and 'dest', in that order.
- *
- * Note: the lock in the 'translators' list is also used to protect
- * this structure.
- */
-static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT];
-
-/*! \todo
- * TODO: sample frames for each supported input format.
- * We build this on the fly, by taking an SLIN frame and using
- * the existing converter to play with it.
- */
-
-/*! \brief returns the index of the lowest bit set */
-static force_inline int powerof(unsigned int d)
-{
- int x = ffs(d);
-
- if (x)
- return x - 1;
-
- ast_log(LOG_WARNING, "No bits set? %d\n", d);
-
- return -1;
-}
-
-/*
- * wrappers around the translator routines.
- */
-
-/*!
- * \brief Allocate the descriptor, required outbuf space,
- * and possibly also plc and desc.
- */
-static void *newpvt(struct ast_translator *t)
-{
- struct ast_trans_pvt *pvt;
- int len;
- int useplc = t->plc_samples > 0 && t->useplc; /* cache, because it can change on the fly */
- char *ofs;
-
- /*
- * compute the required size adding private descriptor,
- * plc, buffer, AST_FRIENDLY_OFFSET.
- */
- len = sizeof(*pvt) + t->desc_size;
- if (useplc)
- len += sizeof(plc_state_t);
- if (t->buf_size)
- len += AST_FRIENDLY_OFFSET + t->buf_size;
- pvt = ast_calloc(1, len);
- if (!pvt)
- return NULL;
- pvt->t = t;
- ofs = (char *)(pvt + 1); /* pointer to data space */
- if (t->desc_size) { /* first comes the descriptor */
- pvt->pvt = ofs;
- ofs += t->desc_size;
- }
- if (useplc) { /* then plc state */
- pvt->plc = (plc_state_t *)ofs;
- ofs += sizeof(plc_state_t);
- }
- if (t->buf_size) /* finally buffer and header */
- pvt->outbuf = ofs + AST_FRIENDLY_OFFSET;
- /* call local init routine, if present */
- if (t->newpvt && t->newpvt(pvt)) {
- free(pvt);
- return NULL;
- }
- ast_module_ref(t->module);
- return pvt;
-}
-
-static void destroy(struct ast_trans_pvt *pvt)
-{
- struct ast_translator *t = pvt->t;
-
- if (ast_test_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR)) {
- /* If this flag is still set, that means that the translation path has
- * been torn down, while we still have a frame out there being used.
- * When ast_frfree() gets called on that frame, this ast_trans_pvt
- * will get destroyed, too. */
-
- /* Set the magic hint that this has been requested to be destroyed. */
- pvt->datalen = -1;
-
- return;
- }
-
- if (t->destroy)
- t->destroy(pvt);
- free(pvt);
- ast_module_unref(t->module);
-}
-
-/*! \brief framein wrapper, deals with plc and bound checks. */
-static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
-{
- int16_t *dst = (int16_t *)pvt->outbuf;
- int ret;
- int samples = pvt->samples; /* initial value */
-
- /* Copy the last in jb timing info to the pvt */
- ast_copy_flags(&pvt->f, f, AST_FRFLAG_HAS_TIMING_INFO);
- pvt->f.ts = f->ts;
- pvt->f.len = f->len;
- pvt->f.seqno = f->seqno;
-
- if (f->samples == 0) {
- ast_log(LOG_WARNING, "no samples for %s\n", pvt->t->name);
- }
- if (pvt->t->buffer_samples) { /* do not pass empty frames to callback */
- if (f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */
- if (pvt->plc) {
- int l = pvt->t->plc_samples;
- if (pvt->samples + l > pvt->t->buffer_samples) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- l = plc_fillin(pvt->plc, dst + pvt->samples, l);
- pvt->samples += l;
- pvt->datalen = pvt->samples * 2; /* SLIN has 2bytes for 1sample */
- }
- /* We don't want generic PLC. If the codec has native PLC, then do that */
- if (!pvt->t->native_plc)
- return 0;
- }
- if (pvt->samples + f->samples > pvt->t->buffer_samples) {
- ast_log(LOG_WARNING, "Out of buffer space\n");
- return -1;
- }
- }
- /* we require a framein routine, wouldn't know how to do
- * it otherwise.
- */
- ret = pvt->t->framein(pvt, f);
- /* possibly store data for plc */
- if (!ret && pvt->plc) {
- int l = pvt->t->plc_samples;
- if (pvt->samples < l)
- l = pvt->samples;
- plc_rx(pvt->plc, dst + pvt->samples - l, l);
- }
- /* diagnostic ... */
- if (pvt->samples == samples)
- ast_log(LOG_WARNING, "%s did not update samples %d\n",
- pvt->t->name, pvt->samples);
- return ret;
-}
-
-/*! \brief generic frameout routine.
- * If samples and datalen are 0, take whatever is in pvt
- * and reset them, otherwise take the values in the caller and
- * leave alone the pvt values.
- */
-struct ast_frame *ast_trans_frameout(struct ast_trans_pvt *pvt,
- int datalen, int samples)
-{
- struct ast_frame *f = &pvt->f;
-
- if (samples)
- f->samples = samples;
- else {
- if (pvt->samples == 0)
- return NULL;
- f->samples = pvt->samples;
- pvt->samples = 0;
- }
- if (datalen)
- f->datalen = datalen;
- else {
- f->datalen = pvt->datalen;
- pvt->datalen = 0;
- }
-
- f->frametype = AST_FRAME_VOICE;
- f->subclass = 1 << (pvt->t->dstfmt);
- f->mallocd = 0;
- f->offset = AST_FRIENDLY_OFFSET;
- f->src = pvt->t->name;
- f->data = pvt->outbuf;
-
- ast_set_flag(f, AST_FRFLAG_FROM_TRANSLATOR);
-
- return f;
-}
-
-static struct ast_frame *default_frameout(struct ast_trans_pvt *pvt)
-{
- return ast_trans_frameout(pvt, 0, 0);
-}
-
-/* end of callback wrappers and helpers */
-
-void ast_translator_free_path(struct ast_trans_pvt *p)
-{
- struct ast_trans_pvt *pn = p;
- while ( (p = pn) ) {
- pn = p->next;
- destroy(p);
- }
-}
-
-/*! \brief Build a chain of translators based upon the given source and dest formats */
-struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
-{
- struct ast_trans_pvt *head = NULL, *tail = NULL;
-
- source = powerof(source);
- dest = powerof(dest);
-
- AST_LIST_LOCK(&translators);
-
- while (source != dest) {
- struct ast_trans_pvt *cur;
- struct ast_translator *t = tr_matrix[source][dest].step;
- if (!t) {
- ast_log(LOG_WARNING, "No translator path from %s to %s\n",
- ast_getformatname(source), ast_getformatname(dest));
- AST_LIST_UNLOCK(&translators);
- return NULL;
- }
- if (!(cur = newpvt(t))) {
- ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
- if (head)
- ast_translator_free_path(head);
- AST_LIST_UNLOCK(&translators);
- return NULL;
- }
- if (!head)
- head = cur;
- else
- tail->next = cur;
- tail = cur;
- cur->nextin = cur->nextout = ast_tv(0, 0);
- /* Keep going if this isn't the final destination */
- source = cur->t->dstfmt;
- }
-
- AST_LIST_UNLOCK(&translators);
- return head;
-}
-
-/*! \brief do the actual translation */
-struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
-{
- struct ast_trans_pvt *p = path;
- struct ast_frame *out = f;
- struct timeval delivery;
- int has_timing_info;
- long ts;
- long len;
- int seqno;
-
- has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
- ts = f->ts;
- len = f->len;
- seqno = f->seqno;
-
- /* XXX hmmm... check this below */
- if (!ast_tvzero(f->delivery)) {
- if (!ast_tvzero(path->nextin)) {
- /* Make sure this is in line with what we were expecting */
- if (!ast_tveq(path->nextin, f->delivery)) {
- /* The time has changed between what we expected and this
- most recent time on the new packet. If we have a
- valid prediction adjust our output time appropriately */
- if (!ast_tvzero(path->nextout)) {
- path->nextout = ast_tvadd(path->nextout,
- ast_tvsub(f->delivery, path->nextin));
- }
- path->nextin = f->delivery;
- }
- } else {
- /* This is our first pass. Make sure the timing looks good */
- path->nextin = f->delivery;
- path->nextout = f->delivery;
- }
- /* Predict next incoming sample */
- path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, ast_format_rate(f->subclass)));
- }
- delivery = f->delivery;
- for ( ; out && p ; p = p->next) {
- framein(p, out);
- if (out != f)
- ast_frfree(out);
- out = p->t->frameout(p);
- }
- if (consume)
- ast_frfree(f);
- if (out == NULL)
- return NULL;
- /* we have a frame, play with times */
- if (!ast_tvzero(delivery)) {
- /* Regenerate prediction after a discontinuity */
- if (ast_tvzero(path->nextout))
- path->nextout = ast_tvnow();
-
- /* Use next predicted outgoing timestamp */
- out->delivery = path->nextout;
-
- /* Predict next outgoing timestamp from samples in this
- frame. */
- path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(out->subclass)));
- } else {
- out->delivery = ast_tv(0, 0);
- ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
- if (has_timing_info) {
- out->ts = ts;
- out->len = len;
- out->seqno = seqno;
- }
- }
- /* Invalidate prediction if we're entering a silence period */
- if (out->frametype == AST_FRAME_CNG)
- path->nextout = ast_tv(0, 0);
- return out;
-}
-
-/*! \brief compute the cost of a single translation step */
-static void calc_cost(struct ast_translator *t, int seconds)
-{
- int num_samples = 0;
- struct ast_trans_pvt *pvt;
- struct timeval start;
- int cost;
- int out_rate = ast_format_rate(t->dstfmt);
-
- if (!seconds)
- seconds = 1;
-
- /* If they don't make samples, give them a terrible score */
- if (!t->sample) {
- ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
- t->cost = 99999;
- return;
- }
-
- pvt = newpvt(t);
- if (!pvt) {
- ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
- t->cost = 99999;
- return;
- }
-
- start = ast_tvnow();
-
- /* Call the encoder until we've processed the required number of samples */
- while (num_samples < seconds * out_rate) {
- struct ast_frame *f = t->sample();
- if (!f) {
- ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
- destroy(pvt);
- t->cost = 99999;
- return;
- }
- framein(pvt, f);
- ast_frfree(f);
- while ((f = t->frameout(pvt))) {
- num_samples += f->samples;
- ast_frfree(f);
- }
- }
-
- cost = ast_tvdiff_ms(ast_tvnow(), start);
-
- destroy(pvt);
-
- t->cost = cost / seconds;
-
- if (!t->cost)
- t->cost = 1;
-}
-
-/*!
- * \brief rebuild a translation matrix.
- * \note This function expects the list of translators to be locked
-*/
-static void rebuild_matrix(int samples)
-{
- struct ast_translator *t;
- int x; /* source format index */
- int y; /* intermediate format index */
- int z; /* destination format index */
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Resetting translation matrix\n");
-
- bzero(tr_matrix, sizeof(tr_matrix));
-
- /* first, compute all direct costs */
- AST_LIST_TRAVERSE(&translators, t, list) {
- if (!t->active)
- continue;
-
- x = t->srcfmt;
- z = t->dstfmt;
-
- if (samples)
- calc_cost(t, samples);
-
- if (!tr_matrix[x][z].step || t->cost < tr_matrix[x][z].cost) {
- tr_matrix[x][z].step = t;
- tr_matrix[x][z].cost = t->cost;
- }
- }
-
- /*
- * For each triple x, y, z of distinct formats, check if there is
- * a path from x to z through y which is cheaper than what is
- * currently known, and in case, update the matrix.
- * Repeat until the matrix is stable.
- */
- for (;;) {
- int changed = 0;
- for (x = 0; x < MAX_FORMAT; x++) { /* source format */
- for (y=0; y < MAX_FORMAT; y++) { /* intermediate format */
- if (x == y) /* skip ourselves */
- continue;
-
- for (z=0; z<MAX_FORMAT; z++) { /* dst format */
- int newcost;
-
- if (z == x || z == y) /* skip null conversions */
- continue;
- if (!tr_matrix[x][y].step) /* no path from x to y */
- continue;
- if (!tr_matrix[y][z].step) /* no path from y to z */
- continue;
- newcost = tr_matrix[x][y].cost + tr_matrix[y][z].cost;
- if (tr_matrix[x][z].step && newcost >= tr_matrix[x][z].cost)
- continue; /* x->y->z is more expensive than
- * the existing path */
- /* ok, we can get from x to z via y with a cost that
- is the sum of the transition from x to y and
- from y to z */
-
- tr_matrix[x][z].step = tr_matrix[x][y].step;
- tr_matrix[x][z].cost = newcost;
- tr_matrix[x][z].multistep = 1;
- if (option_debug)
- ast_log(LOG_DEBUG, "Discovered %d cost path from %s to %s, via %d\n", tr_matrix[x][z].cost, ast_getformatname(x), ast_getformatname(z), y);
- changed++;
- }
- }
- }
- if (!changed)
- break;
- }
-}
-
-/*! \brief CLI "show translation" command handler */
-static int show_translation_deprecated(int fd, int argc, char *argv[])
-{
-#define SHOW_TRANS 13
- int x, y, z;
- int curlen = 0, longest = 0;
-
- if (argc > 4)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&translators);
-
- if (argv[2] && !strcasecmp(argv[2], "recalc")) {
- z = argv[3] ? atoi(argv[3]) : 1;
-
- if (z <= 0) {
- ast_cli(fd, " C'mon let's be serious here... defaulting to 1.\n");
- z = 1;
- }
-
- if (z > MAX_RECALC) {
- ast_cli(fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
- z = MAX_RECALC;
- }
- ast_cli(fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
- rebuild_matrix(z);
- }
-
- ast_cli(fd, " Translation times between formats (in milliseconds) for one second of data\n");
- ast_cli(fd, " Source Format (Rows) Destination Format (Columns)\n\n");
- /* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
- for (x = 0; x < SHOW_TRANS; x++) {
- curlen = strlen(ast_getformatname(1 << (x)));
- if (curlen > longest)
- longest = curlen;
- }
- for (x = -1; x < SHOW_TRANS; x++) {
- char line[120];
- char *buf = line;
- size_t left = sizeof(line) - 1; /* one initial space */
- /* next 2 lines run faster than using ast_build_string() */
- *buf++ = ' ';
- *buf = '\0';
- for (y = -1; y < SHOW_TRANS; y++) {
- if (y >= 0)
- curlen = strlen(ast_getformatname(1 << (y)));
-
- if (x >= 0 && y >= 0 && tr_matrix[x][y].step) {
- /* XXX 999 is a little hackish
- We don't want this number being larger than the shortest (or current) codec
- For now, that is "gsm" */
- ast_build_string(&buf, &left, "%*d", curlen + 1, tr_matrix[x][y].cost > 999 ? 0 : tr_matrix[x][y].cost);
- } else if (x == -1 && y >= 0) {
- /* Top row - use a dynamic size */
- ast_build_string(&buf, &left, "%*s", curlen + 1, ast_getformatname(1 << (y)) );
- } else if (y == -1 && x >= 0) {
- /* Left column - use a static size. */
- ast_build_string(&buf, &left, "%*s", longest, ast_getformatname(1 << (x)) );
- } else if (x >= 0 && y >= 0) {
- ast_build_string(&buf, &left, "%*s", curlen + 1, "-");
- } else {
- ast_build_string(&buf, &left, "%*s", longest, "");
- }
- }
- ast_build_string(&buf, &left, "\n");
- ast_cli(fd, line);
- }
- AST_LIST_UNLOCK(&translators);
- return RESULT_SUCCESS;
-}
-
-static int show_translation(int fd, int argc, char *argv[])
-{
- int x, y, z;
- int curlen = 0, longest = 0;
-
- if (argc > 5)
- return RESULT_SHOWUSAGE;
-
- AST_LIST_LOCK(&translators);
-
- if (argv[3] && !strcasecmp(argv[3], "recalc")) {
- z = argv[4] ? atoi(argv[4]) : 1;
-
- if (z <= 0) {
- ast_cli(fd, " C'mon let's be serious here... defaulting to 1.\n");
- z = 1;
- }
-
- if (z > MAX_RECALC) {
- ast_cli(fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
- z = MAX_RECALC;
- }
- ast_cli(fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
- rebuild_matrix(z);
- }
-
- ast_cli(fd, " Translation times between formats (in milliseconds) for one second of data\n");
- ast_cli(fd, " Source Format (Rows) Destination Format (Columns)\n\n");
- /* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
- for (x = 0; x < SHOW_TRANS; x++) {
- curlen = strlen(ast_getformatname(1 << (x)));
- if (curlen > longest)
- longest = curlen;
- }
- for (x = -1; x < SHOW_TRANS; x++) {
- char line[120];
- char *buf = line;
- size_t left = sizeof(line) - 1; /* one initial space */
- /* next 2 lines run faster than using ast_build_string() */
- *buf++ = ' ';
- *buf = '\0';
- for (y = -1; y < SHOW_TRANS; y++) {
- if (y >= 0)
- curlen = strlen(ast_getformatname(1 << (y)));
-
- if (x >= 0 && y >= 0 && tr_matrix[x][y].step) {
- /* XXX 999 is a little hackish
- We don't want this number being larger than the shortest (or current) codec
- For now, that is "gsm" */
- ast_build_string(&buf, &left, "%*d", curlen + 1, tr_matrix[x][y].cost > 999 ? 0 : tr_matrix[x][y].cost);
- } else if (x == -1 && y >= 0) {
- /* Top row - use a dynamic size */
- ast_build_string(&buf, &left, "%*s", curlen + 1, ast_getformatname(1 << (y)) );
- } else if (y == -1 && x >= 0) {
- /* Left column - use a static size. */
- ast_build_string(&buf, &left, "%*s", longest, ast_getformatname(1 << (x)) );
- } else if (x >= 0 && y >= 0) {
- ast_build_string(&buf, &left, "%*s", curlen + 1, "-");
- } else {
- ast_build_string(&buf, &left, "%*s", longest, "");
- }
- }
- ast_build_string(&buf, &left, "\n");
- ast_cli(fd, line);
- }
- AST_LIST_UNLOCK(&translators);
- return RESULT_SUCCESS;
-}
-
-static char show_trans_usage[] =
-"Usage: core show translation [recalc] [<recalc seconds>]\n"
-" Displays known codec translators and the cost associated\n"
-"with each conversion. If the argument 'recalc' is supplied along\n"
-"with optional number of seconds to test a new test will be performed\n"
-"as the chart is being displayed.\n";
-
-static struct ast_cli_entry cli_show_translation_deprecated = {
- { "show", "translation", NULL },
- show_translation_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_translate[] = {
- { { "core", "show", "translation", NULL },
- show_translation, "Display translation matrix",
- show_trans_usage, NULL, &cli_show_translation_deprecated },
-};
-
-/*! \brief register codec translator */
-int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
-{
- static int added_cli = 0;
- struct ast_translator *u;
-
- if (!mod) {
- ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
- return -1;
- }
-
- if (!t->buf_size) {
- ast_log(LOG_WARNING, "empty buf size, you need to supply one\n");
- return -1;
- }
-
- t->module = mod;
-
- t->srcfmt = powerof(t->srcfmt);
- t->dstfmt = powerof(t->dstfmt);
- t->active = 1;
-
- if (t->plc_samples) {
- if (t->buffer_samples < t->plc_samples) {
- ast_log(LOG_WARNING, "plc_samples %d buffer_samples %d\n",
- t->plc_samples, t->buffer_samples);
- return -1;
- }
- if (t->dstfmt != powerof(AST_FORMAT_SLINEAR))
- ast_log(LOG_WARNING, "plc_samples %d format %x\n",
- t->plc_samples, t->dstfmt);
- }
- if (t->srcfmt >= MAX_FORMAT) {
- ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
- return -1;
- }
-
- if (t->dstfmt >= MAX_FORMAT) {
- ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt));
- return -1;
- }
-
- if (t->buf_size) {
- /*
- * Align buf_size properly, rounding up to the machine-specific
- * alignment for pointers.
- */
- struct _test_align { void *a, *b; } p;
- int align = (char *)&p.b - (char *)&p.a;
-
- t->buf_size = ((t->buf_size + align - 1) / align) * align;
- }
-
- if (t->frameout == NULL)
- t->frameout = default_frameout;
-
- calc_cost(t, 1);
-
- if (option_verbose > 1) {
- char tmp[80];
-
- ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n",
- term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
- ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost);
- }
-
- if (!added_cli) {
- ast_cli_register_multiple(cli_translate, sizeof(cli_translate) / sizeof(struct ast_cli_entry));
- added_cli++;
- }
-
- AST_LIST_LOCK(&translators);
-
- /* find any existing translators that provide this same srcfmt/dstfmt,
- and put this one in order based on cost */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
- if ((u->srcfmt == t->srcfmt) &&
- (u->dstfmt == t->dstfmt) &&
- (u->cost > t->cost)) {
- AST_LIST_INSERT_BEFORE_CURRENT(&translators, t, list);
- t = NULL;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- /* if no existing translator was found for this format combination,
- add it to the beginning of the list */
- if (t)
- AST_LIST_INSERT_HEAD(&translators, t, list);
-
- rebuild_matrix(0);
-
- AST_LIST_UNLOCK(&translators);
-
- return 0;
-}
-
-/*! \brief unregister codec translator */
-int ast_unregister_translator(struct ast_translator *t)
-{
- char tmp[80];
- struct ast_translator *u;
- int found = 0;
-
- AST_LIST_LOCK(&translators);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
- if (u == t) {
- AST_LIST_REMOVE_CURRENT(&translators, list);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt));
- found = 1;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- if (found)
- rebuild_matrix(0);
-
- AST_LIST_UNLOCK(&translators);
-
- return (u ? 0 : -1);
-}
-
-void ast_translator_activate(struct ast_translator *t)
-{
- AST_LIST_LOCK(&translators);
- t->active = 1;
- rebuild_matrix(0);
- AST_LIST_UNLOCK(&translators);
-}
-
-void ast_translator_deactivate(struct ast_translator *t)
-{
- AST_LIST_LOCK(&translators);
- t->active = 0;
- rebuild_matrix(0);
- AST_LIST_UNLOCK(&translators);
-}
-
-/*! \brief Calculate our best translator source format, given costs, and a desired destination */
-int ast_translator_best_choice(int *dst, int *srcs)
-{
- int x,y;
- int best = -1;
- int bestdst = 0;
- int cur, cursrc;
- int besttime = INT_MAX;
- int beststeps = INT_MAX;
- int common = ((*dst) & (*srcs)) & AST_FORMAT_AUDIO_MASK; /* are there common formats ? */
-
- if (common) { /* yes, pick one and return */
- for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) {
- if (cur & common) /* guaranteed to find one */
- break;
- }
- /* We are done, this is a common format to both. */
- *srcs = *dst = cur;
- return 0;
- } else { /* No, we will need to translate */
- AST_LIST_LOCK(&translators);
- for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) {
- if (! (cur & *dst))
- continue;
- for (cursrc = 1, x = 0; x <= MAX_AUDIO_FORMAT; cursrc <<= 1, x++) {
- if (!(*srcs & cursrc) || !tr_matrix[x][y].step ||
- tr_matrix[x][y].cost > besttime)
- continue; /* not existing or no better */
- if (tr_matrix[x][y].cost < besttime ||
- tr_matrix[x][y].multistep < beststeps) {
- /* better than what we have so far */
- best = cursrc;
- bestdst = cur;
- besttime = tr_matrix[x][y].cost;
- beststeps = tr_matrix[x][y].multistep;
- }
- }
- }
- AST_LIST_UNLOCK(&translators);
- if (best > -1) {
- *srcs = best;
- *dst = bestdst;
- best = 0;
- }
- return best;
- }
-}
-
-unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src)
-{
- unsigned int res = -1;
-
- /* convert bitwise format numbers into array indices */
- src = powerof(src);
- dest = powerof(dest);
-
- AST_LIST_LOCK(&translators);
-
- if (tr_matrix[src][dest].step)
- res = tr_matrix[src][dest].multistep + 1;
-
- AST_LIST_UNLOCK(&translators);
-
- return res;
-}
-
-unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src)
-{
- unsigned int res = dest;
- unsigned int x;
- unsigned int src_audio = src & AST_FORMAT_AUDIO_MASK;
- unsigned int src_video = src & AST_FORMAT_VIDEO_MASK;
-
- /* if we don't have a source format, we just have to try all
- possible destination formats */
- if (!src)
- return dest;
-
- /* If we have a source audio format, get its format index */
- if (src_audio)
- src_audio = powerof(src_audio);
-
- /* If we have a source video format, get its format index */
- if (src_video)
- src_video = powerof(src_video);
-
- AST_LIST_LOCK(&translators);
-
- /* For a given source audio format, traverse the list of
- known audio formats to determine whether there exists
- a translation path from the source format to the
- destination format. */
- for (x = 1; src_audio && x < AST_FORMAT_MAX_AUDIO; x <<= 1) {
- /* if this is not a desired format, nothing to do */
- if (!dest & x)
- continue;
-
- /* if the source is supplying this format, then
- we can leave it in the result */
- if (src & x)
- continue;
-
- /* if we don't have a translation path from the src
- to this format, remove it from the result */
- if (!tr_matrix[src_audio][powerof(x)].step) {
- res &= ~x;
- continue;
- }
-
- /* now check the opposite direction */
- if (!tr_matrix[powerof(x)][src_audio].step)
- res &= ~x;
- }
-
- /* For a given source video format, traverse the list of
- known video formats to determine whether there exists
- a translation path from the source format to the
- destination format. */
- for (; src_video && x < AST_FORMAT_MAX_VIDEO; x <<= 1) {
- /* if this is not a desired format, nothing to do */
- if (!dest & x)
- continue;
-
- /* if the source is supplying this format, then
- we can leave it in the result */
- if (src & x)
- continue;
-
- /* if we don't have a translation path from the src
- to this format, remove it from the result */
- if (!tr_matrix[src_video][powerof(x)].step) {
- res &= ~x;
- continue;
- }
-
- /* now check the opposite direction */
- if (!tr_matrix[powerof(x)][src_video].step)
- res &= ~x;
- }
-
- AST_LIST_UNLOCK(&translators);
-
- return res;
-}
-
-void ast_translate_frame_freed(struct ast_frame *fr)
-{
- struct ast_trans_pvt *pvt;
-
- ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR);
-
- pvt = (struct ast_trans_pvt *) (((char *) fr) - offsetof(struct ast_trans_pvt, f));
-
- if (pvt->datalen != -1)
- return;
-
- destroy(pvt);
-}
diff --git a/1.4/main/udptl.c b/1.4/main/udptl.c
deleted file mode 100644
index 718b46fb8..000000000
--- a/1.4/main/udptl.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * UDPTL support for T.38
- *
- * Copyright (C) 2005, Steve Underwood, partly based on RTP code which is
- * Copyright (C) 1999-2006, Digium, Inc.
- *
- * Steve Underwood <steveu@coppice.org>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- *
- * A license has been granted to Digium (via disclaimer) for the use of
- * this code.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-
-#include "asterisk/udptl.h"
-#include "asterisk/frame.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/acl.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/cli.h"
-#include "asterisk/unaligned.h"
-#include "asterisk/utils.h"
-
-#define UDPTL_MTU 1200
-
-#if !defined(FALSE)
-#define FALSE 0
-#endif
-#if !defined(TRUE)
-#define TRUE (!FALSE)
-#endif
-
-static int udptlstart;
-static int udptlend;
-static int udptldebug; /* Are we debugging? */
-static struct sockaddr_in udptldebugaddr; /* Debug packets to/from this host */
-#ifdef SO_NO_CHECK
-static int nochecksums;
-#endif
-static int udptlfectype;
-static int udptlfecentries;
-static int udptlfecspan;
-static int udptlmaxdatagram;
-
-#define LOCAL_FAX_MAX_DATAGRAM 400
-#define MAX_FEC_ENTRIES 5
-#define MAX_FEC_SPAN 5
-
-#define UDPTL_BUF_MASK 15
-
-typedef struct {
- int buf_len;
- uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
-} udptl_fec_tx_buffer_t;
-
-typedef struct {
- int buf_len;
- uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
- int fec_len[MAX_FEC_ENTRIES];
- uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM];
- int fec_span;
- int fec_entries;
-} udptl_fec_rx_buffer_t;
-
-struct ast_udptl {
- int fd;
- char resp;
- struct ast_frame f[16];
- unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
- unsigned int lasteventseqn;
- int nat;
- int flags;
- struct sockaddr_in us;
- struct sockaddr_in them;
- int *ioid;
- struct sched_context *sched;
- struct io_context *io;
- void *data;
- ast_udptl_callback callback;
- int udptl_offered_from_local;
-
- /*! This option indicates the error correction scheme used in transmitted UDPTL
- packets. */
- int error_correction_scheme;
-
- /*! This option indicates the number of error correction entries transmitted in
- UDPTL packets. */
- int error_correction_entries;
-
- /*! This option indicates the span of the error correction entries in transmitted
- UDPTL packets (FEC only). */
- int error_correction_span;
-
- /*! This option indicates the maximum size of a UDPTL packet that can be accepted by
- the remote device. */
- int far_max_datagram_size;
-
- /*! This option indicates the maximum size of a UDPTL packet that we are prepared to
- accept. */
- int local_max_datagram_size;
-
- int verbose;
-
- struct sockaddr_in far;
-
- int tx_seq_no;
- int rx_seq_no;
- int rx_expected_seq_no;
-
- udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
- udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
-};
-
-static struct ast_udptl_protocol *protos;
-
-static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len);
-static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len);
-
-static inline int udptl_debug_test_addr(struct sockaddr_in *addr)
-{
- if (udptldebug == 0)
- return 0;
- if (udptldebugaddr.sin_addr.s_addr) {
- if (((ntohs(udptldebugaddr.sin_port) != 0)
- && (udptldebugaddr.sin_port != addr->sin_port))
- || (udptldebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
-}
-
-static int decode_length(uint8_t *buf, int limit, int *len, int *pvalue)
-{
- if ((buf[*len] & 0x80) == 0) {
- if (*len >= limit)
- return -1;
- *pvalue = buf[*len];
- (*len)++;
- return 0;
- }
- if ((buf[*len] & 0x40) == 0) {
- if (*len >= limit - 1)
- return -1;
- *pvalue = (buf[*len] & 0x3F) << 8;
- (*len)++;
- *pvalue |= buf[*len];
- (*len)++;
- return 0;
- }
- if (*len >= limit)
- return -1;
- *pvalue = (buf[*len] & 0x3F) << 14;
- (*len)++;
- /* Indicate we have a fragment */
- return 1;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int decode_open_type(uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
-{
- int octet_cnt;
- int octet_idx;
- int stat;
- int i;
- const uint8_t **pbuf;
-
- for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) {
- if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
- return -1;
- if (octet_cnt > 0) {
- *p_num_octets += octet_cnt;
-
- pbuf = &p_object[octet_idx];
- i = 0;
- /* Make sure the buffer contains at least the number of bits requested */
- if ((*len + octet_cnt) > limit)
- return -1;
-
- *pbuf = &buf[*len];
- *len += octet_cnt;
- }
- if (stat == 0)
- break;
- }
- return 0;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int encode_length(uint8_t *buf, int *len, int value)
-{
- int multiplier;
-
- if (value < 0x80) {
- /* 1 octet */
- buf[*len] = value;
- (*len)++;
- return value;
- }
- if (value < 0x4000) {
- /* 2 octets */
- /* Set the first bit of the first octet */
- buf[*len] = ((0x8000 | value) >> 8) & 0xFF;
- (*len)++;
- buf[*len] = value & 0xFF;
- (*len)++;
- return value;
- }
- /* Fragmentation */
- multiplier = (value < 0x10000) ? (value >> 14) : 4;
- /* Set the first 2 bits of the octet */
- buf[*len] = 0xC0 | multiplier;
- (*len)++;
- return multiplier << 14;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
-{
- int enclen;
- int octet_idx;
- uint8_t zero_byte;
-
- /* If open type is of zero length, add a single zero byte (10.1) */
- if (num_octets == 0) {
- zero_byte = 0;
- data = &zero_byte;
- num_octets = 1;
- }
- /* Encode the open type */
- for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
- if ((enclen = encode_length(buf, len, num_octets)) < 0)
- return -1;
- if (enclen > 0) {
- memcpy(&buf[*len], &data[octet_idx], enclen);
- *len += enclen;
- }
- if (enclen >= num_octets)
- break;
- }
-
- return 0;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
-{
- int stat;
- int stat2;
- int i;
- int j;
- int k;
- int l;
- int m;
- int x;
- int limit;
- int which;
- int ptr;
- int count;
- int total_count;
- int seq_no;
- const uint8_t *ifp;
- const uint8_t *data;
- int ifp_len;
- int repaired[16];
- const uint8_t *bufs[16];
- int lengths[16];
- int span;
- int entries;
- int ifp_no;
-
- ptr = 0;
- ifp_no = 0;
- memset(&s->f[0], 0, sizeof(s->f[0]));
-
- /* Decode seq_number */
- if (ptr + 2 > len)
- return -1;
- seq_no = (buf[0] << 8) | buf[1];
- ptr += 2;
-
- /* Break out the primary packet */
- if ((stat = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
- return -1;
- /* Decode error_recovery */
- if (ptr + 1 > len)
- return -1;
- if ((buf[ptr++] & 0x80) == 0) {
- /* Secondary packet mode for error recovery */
- if (seq_no > s->rx_seq_no) {
- /* We received a later packet than we expected, so we need to check if we can fill in the gap from the
- secondary packets. */
- total_count = 0;
- do {
- if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
- return -1;
- for (i = 0; i < count; i++) {
- if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
- return -1;
- }
- total_count += count;
- }
- while (stat2 > 0);
- /* Step through in reverse order, so we go oldest to newest */
- for (i = total_count; i > 0; i--) {
- if (seq_no - i >= s->rx_seq_no) {
- /* This one wasn't seen before */
- /* Decode the secondary IFP packet */
- //fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
- s->f[ifp_no].frametype = AST_FRAME_MODEM;
- s->f[ifp_no].subclass = AST_MODEM_T38;
-
- s->f[ifp_no].mallocd = 0;
- s->f[ifp_no].seqno = seq_no - i;
- s->f[ifp_no].datalen = lengths[i - 1];
- s->f[ifp_no].data = (uint8_t *) bufs[i - 1];
- s->f[ifp_no].offset = 0;
- s->f[ifp_no].src = "UDPTL";
- if (ifp_no > 0)
- AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
- AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
- ifp_no++;
- }
- }
- }
- }
- else
- {
- /* FEC mode for error recovery */
- /* Our buffers cannot tolerate overlength IFP packets in FEC mode */
- if (ifp_len > LOCAL_FAX_MAX_DATAGRAM)
- return -1;
- /* Update any missed slots in the buffer */
- for ( ; seq_no > s->rx_seq_no; s->rx_seq_no++) {
- x = s->rx_seq_no & UDPTL_BUF_MASK;
- s->rx[x].buf_len = -1;
- s->rx[x].fec_len[0] = 0;
- s->rx[x].fec_span = 0;
- s->rx[x].fec_entries = 0;
- }
-
- x = seq_no & UDPTL_BUF_MASK;
-
- memset(repaired, 0, sizeof(repaired));
-
- /* Save the new IFP packet */
- memcpy(s->rx[x].buf, ifp, ifp_len);
- s->rx[x].buf_len = ifp_len;
- repaired[x] = TRUE;
-
- /* Decode the FEC packets */
- /* The span is defined as an unconstrained integer, but will never be more
- than a small value. */
- if (ptr + 2 > len)
- return -1;
- if (buf[ptr++] != 1)
- return -1;
- span = buf[ptr++];
- s->rx[x].fec_span = span;
-
- /* The number of entries is defined as a length, but will only ever be a small
- value. Treat it as such. */
- if (ptr + 1 > len)
- return -1;
- entries = buf[ptr++];
- s->rx[x].fec_entries = entries;
-
- /* Decode the elements */
- for (i = 0; i < entries; i++) {
- if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
- return -1;
- if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
- return -1;
-
- /* Save the new FEC data */
- memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
-#if 0
- fprintf(stderr, "FEC: ");
- for (j = 0; j < s->rx[x].fec_len[i]; j++)
- fprintf(stderr, "%02X ", data[j]);
- fprintf(stderr, "\n");
-#endif
- }
-
- /* See if we can reconstruct anything which is missing */
- /* TODO: this does not comprehensively hunt back and repair everything that is possible */
- for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
- if (s->rx[l].fec_len[0] <= 0)
- continue;
- for (m = 0; m < s->rx[l].fec_entries; m++) {
- limit = (l + m) & UDPTL_BUF_MASK;
- for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
- if (s->rx[k].buf_len <= 0)
- which = (which == -1) ? k : -2;
- }
- if (which >= 0) {
- /* Repairable */
- for (j = 0; j < s->rx[l].fec_len[m]; j++) {
- s->rx[which].buf[j] = s->rx[l].fec[m][j];
- for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
- s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
- }
- s->rx[which].buf_len = s->rx[l].fec_len[m];
- repaired[which] = TRUE;
- }
- }
- }
- /* Now play any new packets forwards in time */
- for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
- if (repaired[l]) {
- //fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
- s->f[ifp_no].frametype = AST_FRAME_MODEM;
- s->f[ifp_no].subclass = AST_MODEM_T38;
-
- s->f[ifp_no].mallocd = 0;
- s->f[ifp_no].seqno = j;
- s->f[ifp_no].datalen = s->rx[l].buf_len;
- s->f[ifp_no].data = s->rx[l].buf;
- s->f[ifp_no].offset = 0;
- s->f[ifp_no].src = "UDPTL";
- if (ifp_no > 0)
- AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
- AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
- ifp_no++;
- }
- }
- }
-
- /* If packets are received out of sequence, we may have already processed this packet from the error
- recovery information in a packet already received. */
- if (seq_no >= s->rx_seq_no) {
- /* Decode the primary IFP packet */
- s->f[ifp_no].frametype = AST_FRAME_MODEM;
- s->f[ifp_no].subclass = AST_MODEM_T38;
-
- s->f[ifp_no].mallocd = 0;
- s->f[ifp_no].seqno = seq_no;
- s->f[ifp_no].datalen = ifp_len;
- s->f[ifp_no].data = (uint8_t *) ifp;
- s->f[ifp_no].offset = 0;
- s->f[ifp_no].src = "UDPTL";
- if (ifp_no > 0)
- AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
- AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
-
- ifp_no++;
- }
-
- s->rx_seq_no = seq_no + 1;
- return ifp_no;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len)
-{
- uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
- int i;
- int j;
- int seq;
- int entry;
- int entries;
- int span;
- int m;
- int len;
- int limit;
- int high_tide;
-
- seq = s->tx_seq_no & 0xFFFF;
-
- /* Map the sequence number to an entry in the circular buffer */
- entry = seq & UDPTL_BUF_MASK;
-
- /* We save the message in a circular buffer, for generating FEC or
- redundancy sets later on. */
- s->tx[entry].buf_len = ifp_len;
- memcpy(s->tx[entry].buf, ifp, ifp_len);
-
- /* Build the UDPTLPacket */
-
- len = 0;
- /* Encode the sequence number */
- buf[len++] = (seq >> 8) & 0xFF;
- buf[len++] = seq & 0xFF;
-
- /* Encode the primary IFP packet */
- if (encode_open_type(buf, &len, ifp, ifp_len) < 0)
- return -1;
-
- /* Encode the appropriate type of error recovery information */
- switch (s->error_correction_scheme)
- {
- case UDPTL_ERROR_CORRECTION_NONE:
- /* Encode the error recovery type */
- buf[len++] = 0x00;
- /* The number of entries will always be zero, so it is pointless allowing
- for the fragmented case here. */
- if (encode_length(buf, &len, 0) < 0)
- return -1;
- break;
- case UDPTL_ERROR_CORRECTION_REDUNDANCY:
- /* Encode the error recovery type */
- buf[len++] = 0x00;
- if (s->tx_seq_no > s->error_correction_entries)
- entries = s->error_correction_entries;
- else
- entries = s->tx_seq_no;
- /* The number of entries will always be small, so it is pointless allowing
- for the fragmented case here. */
- if (encode_length(buf, &len, entries) < 0)
- return -1;
- /* Encode the elements */
- for (i = 0; i < entries; i++) {
- j = (entry - i - 1) & UDPTL_BUF_MASK;
- if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
- return -1;
- }
- break;
- case UDPTL_ERROR_CORRECTION_FEC:
- span = s->error_correction_span;
- entries = s->error_correction_entries;
- if (seq < s->error_correction_span*s->error_correction_entries) {
- /* In the initial stages, wind up the FEC smoothly */
- entries = seq/s->error_correction_span;
- if (seq < s->error_correction_span)
- span = 0;
- }
- /* Encode the error recovery type */
- buf[len++] = 0x80;
- /* Span is defined as an inconstrained integer, which it dumb. It will only
- ever be a small value. Treat it as such. */
- buf[len++] = 1;
- buf[len++] = span;
- /* The number of entries is defined as a length, but will only ever be a small
- value. Treat it as such. */
- buf[len++] = entries;
- for (m = 0; m < entries; m++) {
- /* Make an XOR'ed entry the maximum length */
- limit = (entry + m) & UDPTL_BUF_MASK;
- high_tide = 0;
- for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
- if (high_tide < s->tx[i].buf_len) {
- for (j = 0; j < high_tide; j++)
- fec[j] ^= s->tx[i].buf[j];
- for ( ; j < s->tx[i].buf_len; j++)
- fec[j] = s->tx[i].buf[j];
- high_tide = s->tx[i].buf_len;
- } else {
- for (j = 0; j < s->tx[i].buf_len; j++)
- fec[j] ^= s->tx[i].buf[j];
- }
- }
- if (encode_open_type(buf, &len, fec, high_tide) < 0)
- return -1;
- }
- break;
- }
-
- if (s->verbose)
- fprintf(stderr, "\n");
-
- s->tx_seq_no++;
- return len;
-}
-
-int ast_udptl_fd(struct ast_udptl *udptl)
-{
- return udptl->fd;
-}
-
-void ast_udptl_set_data(struct ast_udptl *udptl, void *data)
-{
- udptl->data = data;
-}
-
-void ast_udptl_set_callback(struct ast_udptl *udptl, ast_udptl_callback callback)
-{
- udptl->callback = callback;
-}
-
-void ast_udptl_setnat(struct ast_udptl *udptl, int nat)
-{
- udptl->nat = nat;
-}
-
-static int udptlread(int *id, int fd, short events, void *cbdata)
-{
- struct ast_udptl *udptl = cbdata;
- struct ast_frame *f;
-
- if ((f = ast_udptl_read(udptl))) {
- if (udptl->callback)
- udptl->callback(udptl, f, udptl->data);
- }
- return 1;
-}
-
-struct ast_frame *ast_udptl_read(struct ast_udptl *udptl)
-{
- int res;
- struct sockaddr_in sin;
- socklen_t len;
- uint16_t seqno = 0;
- uint16_t *udptlheader;
-
- len = sizeof(sin);
-
- /* Cache where the header will go */
- res = recvfrom(udptl->fd,
- udptl->rawdata + AST_FRIENDLY_OFFSET,
- sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
- 0,
- (struct sockaddr *) &sin,
- &len);
- udptlheader = (uint16_t *)(udptl->rawdata + AST_FRIENDLY_OFFSET);
- if (res < 0) {
- if (errno != EAGAIN)
- ast_log(LOG_WARNING, "UDPTL read error: %s\n", strerror(errno));
- if (errno == EBADF)
- CRASH;
- return &ast_null_frame;
- }
-
- /* Ignore if the other side hasn't been given an address yet. */
- if (!udptl->them.sin_addr.s_addr || !udptl->them.sin_port)
- return &ast_null_frame;
-
- if (udptl->nat) {
- /* Send to whoever sent to us */
- if ((udptl->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
- (udptl->them.sin_port != sin.sin_port)) {
- memcpy(&udptl->them, &sin, sizeof(udptl->them));
- ast_log(LOG_DEBUG, "UDPTL NAT: Using address %s:%d\n", ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port));
- }
- }
-
- if (udptl_debug_test_addr(&sin)) {
- ast_verbose("Got UDPTL packet from %s:%d (type %d, seq %d, len %d)\n",
- ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 0, seqno, res);
- }
-#if 0
- printf("Got UDPTL packet from %s:%d (seq %d, len = %d)\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), seqno, res);
-#endif
- if (udptl_rx_packet(udptl, udptl->rawdata + AST_FRIENDLY_OFFSET, res) < 1)
- return &ast_null_frame;
-
- return &udptl->f[0];
-}
-
-void ast_udptl_offered_from_local(struct ast_udptl* udptl, int local)
-{
- if (udptl)
- udptl->udptl_offered_from_local = local;
- else
- ast_log(LOG_WARNING, "udptl structure is null\n");
-}
-
-int ast_udptl_get_error_correction_scheme(struct ast_udptl* udptl)
-{
- if (udptl)
- return udptl->error_correction_scheme;
- else {
- ast_log(LOG_WARNING, "udptl structure is null\n");
- return -1;
- }
-}
-
-void ast_udptl_set_error_correction_scheme(struct ast_udptl* udptl, int ec)
-{
- if (udptl) {
- switch (ec) {
- case UDPTL_ERROR_CORRECTION_FEC:
- udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
- break;
- case UDPTL_ERROR_CORRECTION_REDUNDANCY:
- udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
- break;
- case UDPTL_ERROR_CORRECTION_NONE:
- udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE;
- break;
- default:
- ast_log(LOG_WARNING, "error correction parameter invalid\n");
- };
- } else
- ast_log(LOG_WARNING, "udptl structure is null\n");
-}
-
-int ast_udptl_get_local_max_datagram(struct ast_udptl* udptl)
-{
- if (udptl)
- return udptl->local_max_datagram_size;
- else {
- ast_log(LOG_WARNING, "udptl structure is null\n");
- return -1;
- }
-}
-
-int ast_udptl_get_far_max_datagram(struct ast_udptl* udptl)
-{
- if (udptl)
- return udptl->far_max_datagram_size;
- else {
- ast_log(LOG_WARNING, "udptl structure is null\n");
- return -1;
- }
-}
-
-void ast_udptl_set_local_max_datagram(struct ast_udptl* udptl, int max_datagram)
-{
- if (udptl)
- udptl->local_max_datagram_size = max_datagram;
- else
- ast_log(LOG_WARNING, "udptl structure is null\n");
-}
-
-void ast_udptl_set_far_max_datagram(struct ast_udptl* udptl, int max_datagram)
-{
- if (udptl)
- udptl->far_max_datagram_size = max_datagram;
- else
- ast_log(LOG_WARNING, "udptl structure is null\n");
-}
-
-struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr addr)
-{
- struct ast_udptl *udptl;
- int x;
- int startplace;
- int i;
- long int flags;
-
- if (!(udptl = ast_calloc(1, sizeof(*udptl))))
- return NULL;
-
- if (udptlfectype == 2)
- udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
- else if (udptlfectype == 1)
- udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
- else
- udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE;
- udptl->error_correction_span = udptlfecspan;
- udptl->error_correction_entries = udptlfecentries;
-
- udptl->far_max_datagram_size = udptlmaxdatagram;
- udptl->local_max_datagram_size = udptlmaxdatagram;
-
- memset(&udptl->rx, 0, sizeof(udptl->rx));
- memset(&udptl->tx, 0, sizeof(udptl->tx));
- for (i = 0; i <= UDPTL_BUF_MASK; i++) {
- udptl->rx[i].buf_len = -1;
- udptl->tx[i].buf_len = -1;
- }
-
- udptl->them.sin_family = AF_INET;
- udptl->us.sin_family = AF_INET;
-
- if ((udptl->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- free(udptl);
- ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
- return NULL;
- }
- flags = fcntl(udptl->fd, F_GETFL);
- fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
-#ifdef SO_NO_CHECK
- if (nochecksums)
- setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
-#endif
- /* Find us a place */
- x = (ast_random() % (udptlend - udptlstart)) + udptlstart;
- startplace = x;
- for (;;) {
- udptl->us.sin_port = htons(x);
- udptl->us.sin_addr = addr;
- if (bind(udptl->fd, (struct sockaddr *) &udptl->us, sizeof(udptl->us)) == 0)
- break;
- if (errno != EADDRINUSE) {
- ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
- close(udptl->fd);
- free(udptl);
- return NULL;
- }
- if (++x > udptlend)
- x = udptlstart;
- if (x == startplace) {
- ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
- close(udptl->fd);
- free(udptl);
- return NULL;
- }
- }
- if (io && sched && callbackmode) {
- /* Operate this one in a callback mode */
- udptl->sched = sched;
- udptl->io = io;
- udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
- }
- return udptl;
-}
-
-struct ast_udptl *ast_udptl_new(struct sched_context *sched, struct io_context *io, int callbackmode)
-{
- struct in_addr ia;
- memset(&ia, 0, sizeof(ia));
- return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia);
-}
-
-int ast_udptl_settos(struct ast_udptl *udptl, int tos)
-{
- int res;
-
- if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))))
- ast_log(LOG_WARNING, "UDPTL unable to set TOS to %d\n", tos);
- return res;
-}
-
-void ast_udptl_set_peer(struct ast_udptl *udptl, struct sockaddr_in *them)
-{
- udptl->them.sin_port = them->sin_port;
- udptl->them.sin_addr = them->sin_addr;
-}
-
-void ast_udptl_get_peer(struct ast_udptl *udptl, struct sockaddr_in *them)
-{
- memset(them, 0, sizeof(*them));
- them->sin_family = AF_INET;
- them->sin_port = udptl->them.sin_port;
- them->sin_addr = udptl->them.sin_addr;
-}
-
-void ast_udptl_get_us(struct ast_udptl *udptl, struct sockaddr_in *us)
-{
- memcpy(us, &udptl->us, sizeof(udptl->us));
-}
-
-void ast_udptl_stop(struct ast_udptl *udptl)
-{
- memset(&udptl->them.sin_addr, 0, sizeof(udptl->them.sin_addr));
- memset(&udptl->them.sin_port, 0, sizeof(udptl->them.sin_port));
-}
-
-void ast_udptl_destroy(struct ast_udptl *udptl)
-{
- if (udptl->ioid)
- ast_io_remove(udptl->io, udptl->ioid);
- if (udptl->fd > -1)
- close(udptl->fd);
- free(udptl);
-}
-
-int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
-{
- int seq;
- int len;
- int res;
- uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
-
- /* If we have no peer, return immediately */
- if (s->them.sin_addr.s_addr == INADDR_ANY)
- return 0;
-
- /* If there is no data length, return immediately */
- if (f->datalen == 0)
- return 0;
-
- if (f->frametype != AST_FRAME_MODEM) {
- ast_log(LOG_WARNING, "UDPTL can only send T.38 data\n");
- return -1;
- }
-
- /* Save seq_no for debug output because udptl_build_packet increments it */
- seq = s->tx_seq_no & 0xFFFF;
-
- /* Cook up the UDPTL packet, with the relevant EC info. */
- len = udptl_build_packet(s, buf, f->data, f->datalen);
-
- if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) {
- if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)
- ast_log(LOG_NOTICE, "UDPTL Transmission error to %s:%d: %s\n", ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), strerror(errno));
-#if 0
- printf("Sent %d bytes of UDPTL data to %s:%d\n", res, ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port));
-#endif
- if (udptl_debug_test_addr(&s->them))
- ast_verbose("Sent UDPTL packet to %s:%d (type %d, seq %d, len %d)\n",
- ast_inet_ntoa(s->them.sin_addr),
- ntohs(s->them.sin_port), 0, seq, len);
- }
-
- return 0;
-}
-
-void ast_udptl_proto_unregister(struct ast_udptl_protocol *proto)
-{
- struct ast_udptl_protocol *cur;
- struct ast_udptl_protocol *prev;
-
- cur = protos;
- prev = NULL;
- while (cur) {
- if (cur == proto) {
- if (prev)
- prev->next = proto->next;
- else
- protos = proto->next;
- return;
- }
- prev = cur;
- cur = cur->next;
- }
-}
-
-int ast_udptl_proto_register(struct ast_udptl_protocol *proto)
-{
- struct ast_udptl_protocol *cur;
-
- cur = protos;
- while (cur) {
- if (cur->type == proto->type) {
- ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
- return -1;
- }
- cur = cur->next;
- }
- proto->next = protos;
- protos = proto;
- return 0;
-}
-
-static struct ast_udptl_protocol *get_proto(struct ast_channel *chan)
-{
- struct ast_udptl_protocol *cur;
-
- cur = protos;
- while (cur) {
- if (cur->type == chan->tech->type)
- return cur;
- cur = cur->next;
- }
- return NULL;
-}
-
-int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
-{
- struct ast_frame *f;
- struct ast_channel *who;
- struct ast_channel *cs[3];
- struct ast_udptl *p0;
- struct ast_udptl *p1;
- struct ast_udptl_protocol *pr0;
- struct ast_udptl_protocol *pr1;
- struct sockaddr_in ac0;
- struct sockaddr_in ac1;
- struct sockaddr_in t0;
- struct sockaddr_in t1;
- void *pvt0;
- void *pvt1;
- int to;
-
- ast_channel_lock(c0);
- while (ast_channel_trylock(c1)) {
- ast_channel_unlock(c0);
- usleep(1);
- ast_channel_lock(c0);
- }
- pr0 = get_proto(c0);
- pr1 = get_proto(c1);
- if (!pr0) {
- ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return -1;
- }
- if (!pr1) {
- ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return -1;
- }
- pvt0 = c0->tech_pvt;
- pvt1 = c1->tech_pvt;
- p0 = pr0->get_udptl_info(c0);
- p1 = pr1->get_udptl_info(c1);
- if (!p0 || !p1) {
- /* Somebody doesn't want to play... */
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- return -2;
- }
- if (pr0->set_udptl_peer(c0, p1)) {
- ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
- memset(&ac1, 0, sizeof(ac1));
- } else {
- /* Store UDPTL peer */
- ast_udptl_get_peer(p1, &ac1);
- }
- if (pr1->set_udptl_peer(c1, p0)) {
- ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
- memset(&ac0, 0, sizeof(ac0));
- } else {
- /* Store UDPTL peer */
- ast_udptl_get_peer(p0, &ac0);
- }
- ast_channel_unlock(c0);
- ast_channel_unlock(c1);
- cs[0] = c0;
- cs[1] = c1;
- cs[2] = NULL;
- for (;;) {
- if ((c0->tech_pvt != pvt0) ||
- (c1->tech_pvt != pvt1) ||
- (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
- ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
- /* Tell it to try again later */
- return -3;
- }
- to = -1;
- ast_udptl_get_peer(p1, &t1);
- ast_udptl_get_peer(p0, &t0);
- if (inaddrcmp(&t1, &ac1)) {
- ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n",
- c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port));
- ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n",
- c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port));
- memcpy(&ac1, &t1, sizeof(ac1));
- }
- if (inaddrcmp(&t0, &ac0)) {
- ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n",
- c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port));
- ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n",
- c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port));
- memcpy(&ac0, &t0, sizeof(ac0));
- }
- who = ast_waitfor_n(cs, 2, &to);
- if (!who) {
- ast_log(LOG_DEBUG, "Ooh, empty read...\n");
- /* check for hangup / whentohangup */
- if (ast_check_hangup(c0) || ast_check_hangup(c1))
- break;
- continue;
- }
- f = ast_read(who);
- if (!f) {
- *fo = f;
- *rc = who;
- ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
- /* That's all we needed */
- return 0;
- } else {
- if (f->frametype == AST_FRAME_MODEM) {
- /* Forward T.38 frames if they happen upon us */
- if (who == c0) {
- ast_write(c1, f);
- } else if (who == c1) {
- ast_write(c0, f);
- }
- }
- ast_frfree(f);
- }
- /* Swap priority. Not that it's a big deal at this point */
- cs[2] = cs[0];
- cs[0] = cs[1];
- cs[1] = cs[2];
- }
- return -1;
-}
-
-static int udptl_do_debug_ip(int fd, int argc, char *argv[])
-{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port;
- char *p;
- char *arg;
-
- port = 0;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- arg = argv[3];
- p = strstr(arg, ":");
- if (p) {
- *p = '\0';
- p++;
- port = atoi(p);
- }
- hp = ast_gethostbyname(arg, &ahp);
- if (hp == NULL)
- return RESULT_SHOWUSAGE;
- udptldebugaddr.sin_family = AF_INET;
- memcpy(&udptldebugaddr.sin_addr, hp->h_addr, sizeof(udptldebugaddr.sin_addr));
- udptldebugaddr.sin_port = htons(port);
- if (port == 0)
- ast_cli(fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr));
- else
- ast_cli(fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port);
- udptldebug = 1;
- return RESULT_SUCCESS;
-}
-
-static int udptl_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 2) {
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- return udptl_do_debug_ip(fd, argc, argv);
- }
- udptldebug = 1;
- memset(&udptldebugaddr,0,sizeof(udptldebugaddr));
- ast_cli(fd, "UDPTL Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int udptl_nodebug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- udptldebug = 0;
- ast_cli(fd,"UDPTL Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static char debug_usage[] =
- "Usage: udptl debug [ip host[:port]]\n"
- " Enable dumping of all UDPTL packets to and from host.\n";
-
-static char nodebug_usage[] =
- "Usage: udptl debug off\n"
- " Disable all UDPTL debugging\n";
-
-static struct ast_cli_entry cli_udptl_no_debug = {
- { "udptl", "no", "debug", NULL },
- udptl_nodebug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_udptl[] = {
- { { "udptl", "debug", NULL },
- udptl_do_debug, "Enable UDPTL debugging",
- debug_usage },
-
- { { "udptl", "debug", "ip", NULL },
- udptl_do_debug, "Enable UDPTL debugging on IP",
- debug_usage },
-
- { { "udptl", "debug", "off", NULL },
- udptl_nodebug, "Disable UDPTL debugging",
- nodebug_usage, NULL, &cli_udptl_no_debug },
-};
-
-void ast_udptl_reload(void)
-{
- struct ast_config *cfg;
- const char *s;
-
- udptlstart = 4500;
- udptlend = 4999;
- udptlfectype = 0;
- udptlfecentries = 0;
- udptlfecspan = 0;
- udptlmaxdatagram = 0;
-
- if ((cfg = ast_config_load("udptl.conf"))) {
- if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
- udptlstart = atoi(s);
- if (udptlstart < 1024)
- udptlstart = 1024;
- if (udptlstart > 65535)
- udptlstart = 65535;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
- udptlend = atoi(s);
- if (udptlend < 1024)
- udptlend = 1024;
- if (udptlend > 65535)
- udptlend = 65535;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
-#ifdef SO_NO_CHECK
- if (ast_false(s))
- nochecksums = 1;
- else
- nochecksums = 0;
-#else
- if (ast_false(s))
- ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
-#endif
- }
- if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) {
- if (strcmp(s, "t38UDPFEC") == 0)
- udptlfectype = 2;
- else if (strcmp(s, "t38UDPRedundancy") == 0)
- udptlfectype = 1;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
- udptlmaxdatagram = atoi(s);
- if (udptlmaxdatagram < 0)
- udptlmaxdatagram = 0;
- if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM)
- udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) {
- udptlfecentries = atoi(s);
- if (udptlfecentries < 0)
- udptlfecentries = 0;
- if (udptlfecentries > MAX_FEC_ENTRIES)
- udptlfecentries = MAX_FEC_ENTRIES;
- }
- if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) {
- udptlfecspan = atoi(s);
- if (udptlfecspan < 0)
- udptlfecspan = 0;
- if (udptlfecspan > MAX_FEC_SPAN)
- udptlfecspan = MAX_FEC_SPAN;
- }
- ast_config_destroy(cfg);
- }
- if (udptlstart >= udptlend) {
- ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end\n");
- udptlstart = 4500;
- udptlend = 4999;
- }
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend);
-}
-
-void ast_udptl_init(void)
-{
- ast_cli_register_multiple(cli_udptl, sizeof(cli_udptl) / sizeof(struct ast_cli_entry));
- ast_udptl_reload();
-}
diff --git a/1.4/main/ulaw.c b/1.4/main/ulaw.c
deleted file mode 100644
index 2735f6cce..000000000
--- a/1.4/main/ulaw.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief u-Law to Signed linear conversion
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/ulaw.h"
-
-#define ZEROTRAP /*!< turn on the trap as per the MIL-STD */
-#define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
-#define CLIP 32635
-
-unsigned char __ast_lin2mu[16384];
-short __ast_mulaw[256];
-
-
-static unsigned char linear2ulaw(short sample)
-{
- static int exp_lut[256] = {
- 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
- int sign, exponent, mantissa;
- unsigned char ulawbyte;
-
- /* Get the sample into sign-magnitude. */
- sign = (sample >> 8) & 0x80; /* set aside the sign */
- if (sign != 0)
- sample = -sample; /* get magnitude */
- if (sample > CLIP)
- sample = CLIP; /* clip the magnitude */
-
- /* Convert from 16 bit linear to ulaw. */
- sample = sample + BIAS;
- exponent = exp_lut[(sample >> 7) & 0xFF];
- mantissa = (sample >> (exponent + 3)) & 0x0F;
- ulawbyte = ~(sign | (exponent << 4) | mantissa);
-#ifdef ZEROTRAP
- if (ulawbyte == 0)
- ulawbyte = 0x02; /* optional CCITT trap */
-#endif
-
- return ulawbyte;
-}
-
-/*!
- * \brief Set up mu-law conversion table
- */
-void ast_ulaw_init(void)
-{
- int i;
- for (i = 0; i < 256; i++) {
- short mu, e, f, y;
- static short etab[] = {0,132,396,924,1980,4092,8316,16764};
-
- mu = 255 - i;
- e = (mu & 0x70) / 16;
- f = mu & 0x0f;
- y = f * (1 << (e + 3));
- y += etab[e];
- if (mu & 0x80)
- y = -y;
- __ast_mulaw[i] = y;
- }
- /* set up the reverse (mu-law) conversion table */
- for (i = -32768; i < 32768; i++) {
- __ast_lin2mu[((unsigned short)i) >> 2] = linear2ulaw(i);
- }
-}
-
diff --git a/1.4/main/utils.c b/1.4/main/utils.c
deleted file mode 100644
index 2bb4fb2bb..000000000
--- a/1.4/main/utils.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Utility functions
- *
- * \note These are important for portability and security,
- * so please use them in favour of other routines.
- * Please consult the CODING GUIDELINES for more information.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#define AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */
-#include "asterisk/lock.h"
-#include "asterisk/io.h"
-#include "asterisk/logger.h"
-#include "asterisk/md5.h"
-#include "asterisk/sha1.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/linkedlists.h"
-
-#define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
-#include "asterisk/strings.h"
-
-#define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
-#include "asterisk/time.h"
-
-#define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
-#include "asterisk/stringfields.h"
-
-#define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
-#include "asterisk/utils.h"
-
-#define AST_API_MODULE
-#include "asterisk/threadstorage.h"
-
-static char base64[64];
-static char b2a[256];
-
-AST_THREADSTORAGE(inet_ntoa_buf, inet_ntoa_buf_init);
-
-#if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
-
-#define ERANGE 34 /*!< duh? ERANGE value copied from web... */
-#undef gethostbyname
-
-AST_MUTEX_DEFINE_STATIC(__mutex);
-
-/*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
-\note This
-routine is derived from code originally written and placed in the public
-domain by Enzo Michelangeli <em@em.no-ip.com> */
-
-static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
- size_t buflen, struct hostent **result,
- int *h_errnop)
-{
- int hsave;
- struct hostent *ph;
- ast_mutex_lock(&__mutex); /* begin critical area */
- hsave = h_errno;
-
- ph = gethostbyname(name);
- *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
- if (ph == NULL) {
- *result = NULL;
- } else {
- char **p, **q;
- char *pbuf;
- int nbytes=0;
- int naddr=0, naliases=0;
- /* determine if we have enough space in buf */
-
- /* count how many addresses */
- for (p = ph->h_addr_list; *p != 0; p++) {
- nbytes += ph->h_length; /* addresses */
- nbytes += sizeof(*p); /* pointers */
- naddr++;
- }
- nbytes += sizeof(*p); /* one more for the terminating NULL */
-
- /* count how many aliases, and total length of strings */
- for (p = ph->h_aliases; *p != 0; p++) {
- nbytes += (strlen(*p)+1); /* aliases */
- nbytes += sizeof(*p); /* pointers */
- naliases++;
- }
- nbytes += sizeof(*p); /* one more for the terminating NULL */
-
- /* here nbytes is the number of bytes required in buffer */
- /* as a terminator must be there, the minimum value is ph->h_length */
- if (nbytes > buflen) {
- *result = NULL;
- ast_mutex_unlock(&__mutex); /* end critical area */
- return ERANGE; /* not enough space in buf!! */
- }
-
- /* There is enough space. Now we need to do a deep copy! */
- /* Allocation in buffer:
- from [0] to [(naddr-1) * sizeof(*p)]:
- pointers to addresses
- at [naddr * sizeof(*p)]:
- NULL
- from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
- pointers to aliases
- at [(naddr+naliases+1) * sizeof(*p)]:
- NULL
- then naddr addresses (fixed length), and naliases aliases (asciiz).
- */
-
- *ret = *ph; /* copy whole structure (not its address!) */
-
- /* copy addresses */
- q = (char **)buf; /* pointer to pointers area (type: char **) */
- ret->h_addr_list = q; /* update pointer to address list */
- pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
- for (p = ph->h_addr_list; *p != 0; p++) {
- memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
- *q++ = pbuf; /* the pointer is the one inside buf... */
- pbuf += ph->h_length; /* advance pbuf */
- }
- *q++ = NULL; /* address list terminator */
-
- /* copy aliases */
- ret->h_aliases = q; /* update pointer to aliases list */
- for (p = ph->h_aliases; *p != 0; p++) {
- strcpy(pbuf, *p); /* copy alias strings */
- *q++ = pbuf; /* the pointer is the one inside buf... */
- pbuf += strlen(*p); /* advance pbuf */
- *pbuf++ = 0; /* string terminator */
- }
- *q++ = NULL; /* terminator */
-
- strcpy(pbuf, ph->h_name); /* copy alias strings */
- ret->h_name = pbuf;
- pbuf += strlen(ph->h_name); /* advance pbuf */
- *pbuf++ = 0; /* string terminator */
-
- *result = ret; /* and let *result point to structure */
-
- }
- h_errno = hsave; /* restore h_errno */
- ast_mutex_unlock(&__mutex); /* end critical area */
-
- return (*result == NULL); /* return 0 on success, non-zero on error */
-}
-
-
-#endif
-
-/*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
- standard gethostbyname (which is not thread safe)
-*/
-struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
-{
- int res;
- int herrno;
- int dots=0;
- const char *s;
- struct hostent *result = NULL;
- /* Although it is perfectly legitimate to lookup a pure integer, for
- the sake of the sanity of people who like to name their peers as
- integers, we break with tradition and refuse to look up a
- pure integer */
- s = host;
- res = 0;
- while(s && *s) {
- if (*s == '.')
- dots++;
- else if (!isdigit(*s))
- break;
- s++;
- }
- if (!s || !*s) {
- /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
- if (dots != 3)
- return NULL;
- memset(hp, 0, sizeof(struct ast_hostent));
- hp->hp.h_addrtype = AF_INET;
- hp->hp.h_addr_list = (void *) hp->buf;
- hp->hp.h_addr = hp->buf + sizeof(void *);
- if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
- return &hp->hp;
- return NULL;
-
- }
-#ifdef HAVE_GETHOSTBYNAME_R_5
- result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
-
- if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
- return NULL;
-#else
- res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
-
- if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
- return NULL;
-#endif
- return &hp->hp;
-}
-
-
-
-AST_MUTEX_DEFINE_STATIC(test_lock);
-AST_MUTEX_DEFINE_STATIC(test_lock2);
-static pthread_t test_thread;
-static int lock_count = 0;
-static int test_errors = 0;
-
-/*! \brief This is a regression test for recursive mutexes.
- test_for_thread_safety() will return 0 if recursive mutex locks are
- working properly, and non-zero if they are not working properly. */
-static void *test_thread_body(void *data)
-{
- ast_mutex_lock(&test_lock);
- lock_count += 10;
- if (lock_count != 10)
- test_errors++;
- ast_mutex_lock(&test_lock);
- lock_count += 10;
- if (lock_count != 20)
- test_errors++;
- ast_mutex_lock(&test_lock2);
- ast_mutex_unlock(&test_lock);
- lock_count -= 10;
- if (lock_count != 10)
- test_errors++;
- ast_mutex_unlock(&test_lock);
- lock_count -= 10;
- ast_mutex_unlock(&test_lock2);
- if (lock_count != 0)
- test_errors++;
- return NULL;
-}
-
-int test_for_thread_safety(void)
-{
- ast_mutex_lock(&test_lock2);
- ast_mutex_lock(&test_lock);
- lock_count += 1;
- ast_mutex_lock(&test_lock);
- lock_count += 1;
- ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
- usleep(100);
- if (lock_count != 2)
- test_errors++;
- ast_mutex_unlock(&test_lock);
- lock_count -= 1;
- usleep(100);
- if (lock_count != 1)
- test_errors++;
- ast_mutex_unlock(&test_lock);
- lock_count -= 1;
- if (lock_count != 0)
- test_errors++;
- ast_mutex_unlock(&test_lock2);
- usleep(100);
- if (lock_count != 0)
- test_errors++;
- pthread_join(test_thread, NULL);
- return(test_errors); /* return 0 on success. */
-}
-
-/*! \brief Produce 32 char MD5 hash of value. */
-void ast_md5_hash(char *output, char *input)
-{
- struct MD5Context md5;
- unsigned char digest[16];
- char *ptr;
- int x;
-
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *)input, strlen(input));
- MD5Final(digest, &md5);
- ptr = output;
- for (x = 0; x < 16; x++)
- ptr += sprintf(ptr, "%2.2x", digest[x]);
-}
-
-/*! \brief Produce 40 char SHA1 hash of value. */
-void ast_sha1_hash(char *output, char *input)
-{
- struct SHA1Context sha;
- char *ptr;
- int x;
- uint8_t Message_Digest[20];
-
- SHA1Reset(&sha);
-
- SHA1Input(&sha, (const unsigned char *) input, strlen(input));
-
- SHA1Result(&sha, Message_Digest);
- ptr = output;
- for (x = 0; x < 20; x++)
- ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
-}
-
-/*! \brief decode BASE64 encoded text */
-int ast_base64decode(unsigned char *dst, const char *src, int max)
-{
- int cnt = 0;
- unsigned int byte = 0;
- unsigned int bits = 0;
- int incnt = 0;
- while(*src && (cnt < max)) {
- /* Shift in 6 bits of input */
- byte <<= 6;
- byte |= (b2a[(int)(*src)]) & 0x3f;
- bits += 6;
- src++;
- incnt++;
- /* If we have at least 8 bits left over, take that character
- off the top */
- if (bits >= 8) {
- bits -= 8;
- *dst = (byte >> bits) & 0xff;
- dst++;
- cnt++;
- }
- }
- /* Dont worry about left over bits, they're extra anyway */
- return cnt;
-}
-
-/*! \brief encode text to BASE64 coding */
-int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
-{
- int cnt = 0;
- int col = 0;
- unsigned int byte = 0;
- int bits = 0;
- int cntin = 0;
- /* Reserve space for null byte at end of string */
- max--;
- while ((cntin < srclen) && (cnt < max)) {
- byte <<= 8;
- byte |= *(src++);
- bits += 8;
- cntin++;
- if ((bits == 24) && (cnt + 4 <= max)) {
- *dst++ = base64[(byte >> 18) & 0x3f];
- *dst++ = base64[(byte >> 12) & 0x3f];
- *dst++ = base64[(byte >> 6) & 0x3f];
- *dst++ = base64[byte & 0x3f];
- cnt += 4;
- col += 4;
- bits = 0;
- byte = 0;
- }
- if (linebreaks && (cnt < max) && (col == 64)) {
- *dst++ = '\n';
- cnt++;
- col = 0;
- }
- }
- if (bits && (cnt + 4 <= max)) {
- /* Add one last character for the remaining bits,
- padding the rest with 0 */
- byte <<= 24 - bits;
- *dst++ = base64[(byte >> 18) & 0x3f];
- *dst++ = base64[(byte >> 12) & 0x3f];
- if (bits == 16)
- *dst++ = base64[(byte >> 6) & 0x3f];
- else
- *dst++ = '=';
- *dst++ = '=';
- cnt += 4;
- }
- if (linebreaks && (cnt < max)) {
- *dst++ = '\n';
- cnt++;
- }
- *dst = '\0';
- return cnt;
-}
-
-int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
-{
- return ast_base64encode_full(dst, src, srclen, max, 0);
-}
-
-static void base64_init(void)
-{
- int x;
- memset(b2a, -1, sizeof(b2a));
- /* Initialize base-64 Conversion table */
- for (x = 0; x < 26; x++) {
- /* A-Z */
- base64[x] = 'A' + x;
- b2a['A' + x] = x;
- /* a-z */
- base64[x + 26] = 'a' + x;
- b2a['a' + x] = x + 26;
- /* 0-9 */
- if (x < 10) {
- base64[x + 52] = '0' + x;
- b2a['0' + x] = x + 52;
- }
- }
- base64[62] = '+';
- base64[63] = '/';
- b2a[(int)'+'] = 62;
- b2a[(int)'/'] = 63;
-}
-
-/*! \brief ast_uri_encode: Turn text string to URI-encoded %XX version
-\note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
- as in the SIP protocol spec
- If doreserved == 1 we will convert reserved characters also.
- RFC 2396, section 2.4
- outbuf needs to have more memory allocated than the instring
- to have room for the expansion. Every char that is converted
- is replaced by three ASCII characters.
-
- Note: The doreserved option is needed for replaces header in
- SIP transfers.
-*/
-char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved)
-{
- char *reserved = ";/?:@&=+$,# "; /* Reserved chars */
-
- const char *ptr = string; /* Start with the string */
- char *out = NULL;
- char *buf = NULL;
-
- ast_copy_string(outbuf, string, buflen);
-
- /* If there's no characters to convert, just go through and don't do anything */
- while (*ptr) {
- if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
- /* Oops, we need to start working here */
- if (!buf) {
- buf = outbuf;
- out = buf + (ptr - string) ; /* Set output ptr */
- }
- out += sprintf(out, "%%%02x", (unsigned char) *ptr);
- } else if (buf) {
- *out = *ptr; /* Continue copying the string */
- out++;
- }
- ptr++;
- }
- if (buf)
- *out = '\0';
- return outbuf;
-}
-
-/*! \brief ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) */
-void ast_uri_decode(char *s)
-{
- char *o;
- unsigned int tmp;
-
- for (o = s; *s; s++, o++) {
- if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
- /* have '%', two chars and correct parsing */
- *o = tmp;
- s += 2; /* Will be incremented once more when we break out */
- } else /* all other cases, just copy */
- *o = *s;
- }
- *o = '\0';
-}
-
-/*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
-const char *ast_inet_ntoa(struct in_addr ia)
-{
- char *buf;
-
- if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
- return "";
-
- return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
-}
-
-#ifndef __linux__
-#undef pthread_create /* For ast_pthread_create function only */
-#endif /* !__linux__ */
-
-#if !defined(LOW_MEMORY)
-
-#ifdef DEBUG_THREADS
-
-/*! \brief A reasonable maximum number of locks a thread would be holding ... */
-#define AST_MAX_LOCKS 64
-
-/* Allow direct use of pthread_mutex_t and friends */
-#undef pthread_mutex_t
-#undef pthread_mutex_lock
-#undef pthread_mutex_unlock
-#undef pthread_mutex_init
-#undef pthread_mutex_destroy
-
-/*!
- * \brief Keep track of which locks a thread holds
- *
- * There is an instance of this struct for every active thread
- */
-struct thr_lock_info {
- /*! The thread's ID */
- pthread_t thread_id;
- /*! The thread name which includes where the thread was started */
- const char *thread_name;
- /*! This is the actual container of info for what locks this thread holds */
- struct {
- const char *file;
- int line_num;
- const char *func;
- const char *lock_name;
- void *lock_addr;
- int times_locked;
- enum ast_lock_type type;
- /*! This thread is waiting on this lock */
- int pending:2;
- } locks[AST_MAX_LOCKS];
- /*! This is the number of locks currently held by this thread.
- * The index (num_locks - 1) has the info on the last one in the
- * locks member */
- unsigned int num_locks;
- /*! Protects the contents of the locks member
- * Intentionally not ast_mutex_t */
- pthread_mutex_t lock;
- AST_LIST_ENTRY(thr_lock_info) entry;
-};
-
-/*!
- * \brief Locked when accessing the lock_infos list
- */
-AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
-/*!
- * \brief A list of each thread's lock info
- */
-static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
-
-/*!
- * \brief Destroy a thread's lock info
- *
- * This gets called automatically when the thread stops
- */
-static void lock_info_destroy(void *data)
-{
- struct thr_lock_info *lock_info = data;
-
- pthread_mutex_lock(&lock_infos_lock.mutex);
- AST_LIST_REMOVE(&lock_infos, lock_info, entry);
- pthread_mutex_unlock(&lock_infos_lock.mutex);
-
- pthread_mutex_destroy(&lock_info->lock);
- free((void *) lock_info->thread_name);
- free(lock_info);
-}
-
-/*!
- * \brief The thread storage key for per-thread lock info
- */
-AST_THREADSTORAGE_CUSTOM(thread_lock_info, thread_lock_info_init, lock_info_destroy);
-
-void ast_store_lock_info(enum ast_lock_type type, const char *filename,
- int line_num, const char *func, const char *lock_name, void *lock_addr)
-{
- struct thr_lock_info *lock_info;
- int i;
-
- if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
- return;
-
- pthread_mutex_lock(&lock_info->lock);
-
- for (i = 0; i < lock_info->num_locks; i++) {
- if (lock_info->locks[i].lock_addr == lock_addr) {
- lock_info->locks[i].times_locked++;
- pthread_mutex_unlock(&lock_info->lock);
- return;
- }
- }
-
- if (lock_info->num_locks == AST_MAX_LOCKS) {
- /* Can't use ast_log here, because it will cause infinite recursion */
- fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
- " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
- pthread_mutex_unlock(&lock_info->lock);
- return;
- }
-
- if (i && lock_info->locks[i - 1].pending == -1) {
- /* The last lock on the list was one that this thread tried to lock but
- * failed at doing so. It has now moved on to something else, so remove
- * the old lock from the list. */
- i--;
- lock_info->num_locks--;
- memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
- }
-
- lock_info->locks[i].file = filename;
- lock_info->locks[i].line_num = line_num;
- lock_info->locks[i].func = func;
- lock_info->locks[i].lock_name = lock_name;
- lock_info->locks[i].lock_addr = lock_addr;
- lock_info->locks[i].times_locked = 1;
- lock_info->locks[i].type = type;
- lock_info->locks[i].pending = 1;
- lock_info->num_locks++;
-
- pthread_mutex_unlock(&lock_info->lock);
-}
-
-void ast_mark_lock_acquired(void *lock_addr)
-{
- struct thr_lock_info *lock_info;
-
- if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
- return;
-
- pthread_mutex_lock(&lock_info->lock);
- if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
- lock_info->locks[lock_info->num_locks - 1].pending = 0;
- }
- pthread_mutex_unlock(&lock_info->lock);
-}
-
-void ast_mark_lock_failed(void *lock_addr)
-{
- struct thr_lock_info *lock_info;
-
- if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
- return;
-
- pthread_mutex_lock(&lock_info->lock);
- if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
- lock_info->locks[lock_info->num_locks - 1].pending = -1;
- lock_info->locks[lock_info->num_locks - 1].times_locked--;
- }
- pthread_mutex_unlock(&lock_info->lock);
-}
-
-void ast_remove_lock_info(void *lock_addr)
-{
- struct thr_lock_info *lock_info;
- int i = 0;
-
- if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
- return;
-
- pthread_mutex_lock(&lock_info->lock);
-
- for (i = lock_info->num_locks - 1; i >= 0; i--) {
- if (lock_info->locks[i].lock_addr == lock_addr)
- break;
- }
-
- if (i == -1) {
- /* Lock not found :( */
- pthread_mutex_unlock(&lock_info->lock);
- return;
- }
-
- if (lock_info->locks[i].times_locked > 1) {
- lock_info->locks[i].times_locked--;
- pthread_mutex_unlock(&lock_info->lock);
- return;
- }
-
- if (i < lock_info->num_locks - 1) {
- /* Not the last one ... *should* be rare! */
- memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
- (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
- }
-
- lock_info->num_locks--;
-
- pthread_mutex_unlock(&lock_info->lock);
-}
-
-static const char *locktype2str(enum ast_lock_type type)
-{
- switch (type) {
- case AST_MUTEX:
- return "MUTEX";
- case AST_RDLOCK:
- return "RDLOCK";
- case AST_WRLOCK:
- return "WRLOCK";
- }
-
- return "UNKNOWN";
-}
-
-static int handle_show_locks(int fd, int argc, char *argv[])
-{
- struct thr_lock_info *lock_info;
- struct ast_dynamic_str *str;
-
- if (!(str = ast_dynamic_str_create(4096)))
- return RESULT_FAILURE;
-
- ast_dynamic_str_append(&str, 0, "\n"
- "=======================================================================\n"
- "=== Currently Held Locks ==============================================\n"
- "=======================================================================\n"
- "===\n"
- "=== <file> <line num> <function> <lock name> <lock addr> (times locked)\n"
- "===\n");
-
- if (!str)
- return RESULT_FAILURE;
-
- pthread_mutex_lock(&lock_infos_lock.mutex);
- AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
- int i;
- ast_dynamic_str_append(&str, 0, "=== Thread ID: %u (%s)\n", (int) lock_info->thread_id,
- lock_info->thread_name);
- pthread_mutex_lock(&lock_info->lock);
- for (i = 0; str && i < lock_info->num_locks; i++) {
- int j;
- ast_mutex_t *lock;
-
- ast_dynamic_str_append(&str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
- lock_info->locks[i].pending > 0 ? "Waiting for " :
- lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
- lock_info->locks[i].file,
- locktype2str(lock_info->locks[i].type),
- lock_info->locks[i].line_num,
- lock_info->locks[i].func, lock_info->locks[i].lock_name,
- lock_info->locks[i].lock_addr,
- lock_info->locks[i].times_locked);
-
- if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
- continue;
-
- /* We only have further details for mutexes right now */
- if (lock_info->locks[i].type != AST_MUTEX)
- continue;
-
- lock = lock_info->locks[i].lock_addr;
-
- ast_reentrancy_lock(lock);
- for (j = 0; str && j < lock->reentrancy; j++) {
- ast_dynamic_str_append(&str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
- lock->file[j], lock->lineno[j], lock->func[j]);
- }
- ast_reentrancy_unlock(lock);
- }
- pthread_mutex_unlock(&lock_info->lock);
- if (!str)
- break;
- ast_dynamic_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
- "===\n");
- if (!str)
- break;
- }
- pthread_mutex_unlock(&lock_infos_lock.mutex);
-
- if (!str)
- return RESULT_FAILURE;
-
- ast_dynamic_str_append(&str, 0, "=======================================================================\n"
- "\n");
-
- if (!str)
- return RESULT_FAILURE;
-
- ast_cli(fd, "%s", str->str);
-
- free(str);
-
- return RESULT_SUCCESS;
-}
-
-static char show_locks_help[] =
-"Usage: core show locks\n"
-" This command is for lock debugging. It prints out which locks\n"
-"are owned by each active thread.\n";
-
-static struct ast_cli_entry utils_cli[] = {
- { { "core", "show", "locks", NULL }, handle_show_locks,
- "Show which locks are locked by which thread", show_locks_help },
-};
-
-#endif /* DEBUG_THREADS */
-
-
-
-/*
- * support for 'show threads'. The start routine is wrapped by
- * dummy_start(), so that ast_register_thread() and
- * ast_unregister_thread() know the thread identifier.
- */
-struct thr_arg {
- void *(*start_routine)(void *);
- void *data;
- char *name;
-};
-
-/*
- * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
- * are odd macros which start and end a block, so they _must_ be
- * used in pairs (the latter with a '1' argument to call the
- * handler on exit.
- * On BSD we don't need this, but we keep it for compatibility.
- */
-static void *dummy_start(void *data)
-{
- void *ret;
- struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */
-#ifdef DEBUG_THREADS
- struct thr_lock_info *lock_info;
- pthread_mutexattr_t mutex_attr;
-#endif
-
- /* note that even though data->name is a pointer to allocated memory,
- we are not freeing it here because ast_register_thread is going to
- keep a copy of the pointer and then ast_unregister_thread will
- free the memory
- */
- free(data);
- ast_register_thread(a.name);
- pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
-
-#ifdef DEBUG_THREADS
- if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
- return NULL;
-
- lock_info->thread_id = pthread_self();
- lock_info->thread_name = strdup(a.name);
-
- pthread_mutexattr_init(&mutex_attr);
- pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
- pthread_mutex_init(&lock_info->lock, &mutex_attr);
- pthread_mutexattr_destroy(&mutex_attr);
-
- pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
- AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
- pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
-#endif /* DEBUG_THREADS */
-
- ret = a.start_routine(a.data);
-
- pthread_cleanup_pop(1);
-
- return ret;
-}
-
-#endif /* !LOW_MEMORY */
-
-int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
- void *data, size_t stacksize, const char *file, const char *caller,
- int line, const char *start_fn)
-{
-#if !defined(LOW_MEMORY)
- struct thr_arg *a;
-#endif
-
- if (!attr) {
- attr = alloca(sizeof(*attr));
- pthread_attr_init(attr);
- }
-
-#ifdef __linux__
- /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
- which is kind of useless. Change this here to
- PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
- priority will propagate down to new threads by default.
- This does mean that callers cannot set a different priority using
- PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
- the priority afterwards with pthread_setschedparam(). */
- if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
- ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
-#endif
-
- if (!stacksize)
- stacksize = AST_STACKSIZE;
-
- if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
- ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
-
-#if !defined(LOW_MEMORY)
- if ((a = ast_malloc(sizeof(*a)))) {
- a->start_routine = start_routine;
- a->data = data;
- start_routine = dummy_start;
- asprintf(&a->name, "%-20s started at [%5d] %s %s()",
- start_fn, line, file, caller);
- data = a;
- }
-#endif /* !LOW_MEMORY */
-
- return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
-}
-
-int ast_wait_for_input(int fd, int ms)
-{
- struct pollfd pfd[1];
- memset(pfd, 0, sizeof(pfd));
- pfd[0].fd = fd;
- pfd[0].events = POLLIN|POLLPRI;
- return poll(pfd, 1, ms);
-}
-
-int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
-{
- /* Try to write string, but wait no more than ms milliseconds
- before timing out */
- int res = 0;
- struct pollfd fds[1];
- while (len) {
- res = write(fd, s, len);
- if ((res < 0) && (errno != EAGAIN)) {
- return -1;
- }
- if (res < 0)
- res = 0;
- len -= res;
- s += res;
- res = 0;
- if (len) {
- fds[0].fd = fd;
- fds[0].events = POLLOUT;
- /* Wait until writable again */
- res = poll(fds, 1, timeoutms);
- if (res < 1)
- return -1;
- }
- }
- return res;
-}
-
-char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
-{
- char *e;
- char *q;
-
- s = ast_strip(s);
- if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
- e = s + strlen(s) - 1;
- if (*e == *(end_quotes + (q - beg_quotes))) {
- s++;
- *e = '\0';
- }
- }
-
- return s;
-}
-
-char *ast_unescape_semicolon(char *s)
-{
- char *e;
- char *work = s;
-
- while ((e = strchr(work, ';'))) {
- if ((e > work) && (*(e-1) == '\\')) {
- memmove(e - 1, e, strlen(e) + 1);
- work = e;
- } else {
- work = e + 1;
- }
- }
-
- return s;
-}
-
-int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
-{
- int result;
-
- if (!buffer || !*buffer || !space || !*space)
- return -1;
-
- result = vsnprintf(*buffer, *space, fmt, ap);
-
- if (result < 0)
- return -1;
- else if (result > *space)
- result = *space;
-
- *buffer += result;
- *space -= result;
- return 0;
-}
-
-int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
-{
- va_list ap;
- int result;
-
- va_start(ap, fmt);
- result = ast_build_string_va(buffer, space, fmt, ap);
- va_end(ap);
-
- return result;
-}
-
-int ast_true(const char *s)
-{
- if (ast_strlen_zero(s))
- return 0;
-
- /* Determine if this is a true value */
- if (!strcasecmp(s, "yes") ||
- !strcasecmp(s, "true") ||
- !strcasecmp(s, "y") ||
- !strcasecmp(s, "t") ||
- !strcasecmp(s, "1") ||
- !strcasecmp(s, "on"))
- return -1;
-
- return 0;
-}
-
-int ast_false(const char *s)
-{
- if (ast_strlen_zero(s))
- return 0;
-
- /* Determine if this is a false value */
- if (!strcasecmp(s, "no") ||
- !strcasecmp(s, "false") ||
- !strcasecmp(s, "n") ||
- !strcasecmp(s, "f") ||
- !strcasecmp(s, "0") ||
- !strcasecmp(s, "off"))
- return -1;
-
- return 0;
-}
-
-#define ONE_MILLION 1000000
-/*
- * put timeval in a valid range. usec is 0..999999
- * negative values are not allowed and truncated.
- */
-static struct timeval tvfix(struct timeval a)
-{
- if (a.tv_usec >= ONE_MILLION) {
- ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
- a.tv_sec, (long int) a.tv_usec);
- a.tv_sec += a.tv_usec / ONE_MILLION;
- a.tv_usec %= ONE_MILLION;
- } else if (a.tv_usec < 0) {
- ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
- a.tv_sec, (long int) a.tv_usec);
- a.tv_usec = 0;
- }
- return a;
-}
-
-struct timeval ast_tvadd(struct timeval a, struct timeval b)
-{
- /* consistency checks to guarantee usec in 0..999999 */
- a = tvfix(a);
- b = tvfix(b);
- a.tv_sec += b.tv_sec;
- a.tv_usec += b.tv_usec;
- if (a.tv_usec >= ONE_MILLION) {
- a.tv_sec++;
- a.tv_usec -= ONE_MILLION;
- }
- return a;
-}
-
-struct timeval ast_tvsub(struct timeval a, struct timeval b)
-{
- /* consistency checks to guarantee usec in 0..999999 */
- a = tvfix(a);
- b = tvfix(b);
- a.tv_sec -= b.tv_sec;
- a.tv_usec -= b.tv_usec;
- if (a.tv_usec < 0) {
- a.tv_sec-- ;
- a.tv_usec += ONE_MILLION;
- }
- return a;
-}
-#undef ONE_MILLION
-
-/*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
- * BSD libc (and others) do not. */
-#ifndef linux
-
-AST_MUTEX_DEFINE_STATIC(randomlock);
-
-long int ast_random(void)
-{
- long int res;
- ast_mutex_lock(&randomlock);
- res = random();
- ast_mutex_unlock(&randomlock);
- return res;
-}
-#endif
-
-char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
-{
- char *dataPut = start;
- int inEscape = 0;
- int inQuotes = 0;
-
- for (; *start; start++) {
- if (inEscape) {
- *dataPut++ = *start; /* Always goes verbatim */
- inEscape = 0;
- } else {
- if (*start == '\\') {
- inEscape = 1; /* Do not copy \ into the data */
- } else if (*start == '\'') {
- inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
- } else {
- /* Replace , with |, unless in quotes */
- *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
- }
- }
- }
- if (start != dataPut)
- *dataPut = 0;
- return dataPut;
-}
-
-void ast_join(char *s, size_t len, char * const w[])
-{
- int x, ofs = 0;
- const char *src;
-
- /* Join words into a string */
- if (!s)
- return;
- for (x = 0; ofs < len && w[x]; x++) {
- if (x > 0)
- s[ofs++] = ' ';
- for (src = w[x]; *src && ofs < len; src++)
- s[ofs++] = *src;
- }
- if (ofs == len)
- ofs--;
- s[ofs] = '\0';
-}
-
-const char __ast_string_field_empty[] = "";
-
-static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
-{
- struct ast_string_field_pool *pool;
-
- if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
- return -1;
-
- pool->prev = mgr->pool;
- mgr->pool = pool;
- mgr->size = size;
- mgr->space = size;
- mgr->used = 0;
-
- return 0;
-}
-
-int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
- ast_string_field *fields, int num_fields)
-{
- int index;
-
- if (add_string_pool(mgr, size))
- return -1;
-
- for (index = 0; index < num_fields; index++)
- fields[index] = __ast_string_field_empty;
-
- return 0;
-}
-
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
- ast_string_field *fields, int num_fields)
-{
- char *result = NULL;
-
- if (__builtin_expect(needed > mgr->space, 0)) {
- size_t new_size = mgr->size * 2;
-
- while (new_size < needed)
- new_size *= 2;
-
- if (add_string_pool(mgr, new_size))
- return NULL;
- }
-
- result = mgr->pool->base + mgr->used;
- mgr->used += needed;
- mgr->space -= needed;
- return result;
-}
-
-void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
- ast_string_field *fields, int num_fields,
- int index, const char *format, va_list ap1, va_list ap2)
-{
- size_t needed;
-
- needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
-
- va_end(ap1);
-
- if (needed > mgr->space) {
- size_t new_size = mgr->size * 2;
-
- while (new_size < needed)
- new_size *= 2;
-
- if (add_string_pool(mgr, new_size))
- return;
-
- vsprintf(mgr->pool->base + mgr->used, format, ap2);
- }
-
- fields[index] = mgr->pool->base + mgr->used;
- mgr->used += needed;
- mgr->space -= needed;
-}
-
-void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
- ast_string_field *fields, int num_fields,
- int index, const char *format, ...)
-{
- va_list ap1, ap2;
-
- va_start(ap1, format);
- va_start(ap2, format); /* va_copy does not exist on FreeBSD */
-
- __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2);
-
- va_end(ap1);
- va_end(ap2);
-}
-
-AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
-
-int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
-{
- int ret;
- ast_mutex_lock(&fetchadd_m);
- ret = *p;
- *p += v;
- ast_mutex_unlock(&fetchadd_m);
- return ret;
-}
-
-/*! \brief
- * get values from config variables.
- */
-int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
-{
- long t;
- int scanned;
-
- if (dst == NULL)
- return -1;
-
- *dst = _default;
-
- if (ast_strlen_zero(src))
- return -1;
-
- /* only integer at the moment, but one day we could accept more formats */
- if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
- *dst = t;
- if (consumed)
- *consumed = scanned;
- return 0;
- } else
- return -1;
-}
-
-int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
- struct ast_threadstorage *ts, int append, const char *fmt, va_list ap)
-{
- int res;
- int offset = (append && (*buf)->len) ? strlen((*buf)->str) : 0;
-#if defined(DEBUG_THREADLOCALS)
- struct ast_dynamic_str *old_buf = *buf;
-#endif /* defined(DEBUG_THREADLOCALS) */
-
- res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
-
- /* Check to see if there was not enough space in the string buffer to prepare
- * the string. Also, if a maximum length is present, make sure the current
- * length is less than the maximum before increasing the size. */
- if ((res + offset + 1) > (*buf)->len && (max_len ? ((*buf)->len < max_len) : 1)) {
- /* Set the new size of the string buffer to be the size needed
- * to hold the resulting string (res) plus one byte for the
- * terminating '\0'. If this size is greater than the max, set
- * the new length to be the maximum allowed. */
- if (max_len)
- (*buf)->len = ((res + offset + 1) < max_len) ? (res + offset + 1) : max_len;
- else
- (*buf)->len = res + offset + 1;
-
- if (!(*buf = ast_realloc(*buf, (*buf)->len + sizeof(*(*buf)))))
- return AST_DYNSTR_BUILD_FAILED;
-
- if (append)
- (*buf)->str[offset] = '\0';
-
- if (ts) {
- pthread_setspecific(ts->key, *buf);
-#if defined(DEBUG_THREADLOCALS)
- __ast_threadstorage_object_replace(old_buf, *buf, (*buf)->len + sizeof(*(*buf)));
-#endif /* defined(DEBUG_THREADLOCALS) */
- }
-
- /* va_end() and va_start() must be done before calling
- * vsnprintf() again. */
- return AST_DYNSTR_BUILD_RETRY;
- }
-
- return res;
-}
-
-void ast_enable_packet_fragmentation(int sock)
-{
-#if defined(HAVE_IP_MTU_DISCOVER)
- int val = IP_PMTUDISC_DONT;
-
- if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
- ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
-#endif /* HAVE_IP_MTU_DISCOVER */
-}
-
-int ast_utils_init(void)
-{
- base64_init();
-#ifdef DEBUG_THREADS
-#if !defined(LOW_MEMORY)
- ast_cli_register_multiple(utils_cli, sizeof(utils_cli) / sizeof(utils_cli[0]));
-#endif
-#endif
- return 0;
-}
-
-
diff --git a/1.4/makeopts.in b/1.4/makeopts.in
deleted file mode 100644
index 9d45c3c88..000000000
--- a/1.4/makeopts.in
+++ /dev/null
@@ -1,191 +0,0 @@
-# NOTE: Names of _INCLUDE and _LIB entries in this file must be
-# the exact uppercase equivalents of the names used for
-# dependencies in menuselect for the same package.
-
-CC=@PTHREAD_CC@
-HOST_CC=cc
-CXX=@CXX@
-
-INSTALL=@INSTALL@
-AWK=@AWK@
-GREP=@GREP@
-AR=@AR@
-RANLIB=@RANLIB@
-FIND=@FIND@
-COMPRESS=@COMPRESS@
-BASENAME=@BASENAME@
-ID=@ID@
-SHELL=@SHELL@
-LN=@LN@
-DOT=@DOT@
-STRIP=@STRIP@
-WGET=@WGET@
-FETCH=@FETCH@
-DOWNLOAD=@DOWNLOAD@
-
-BUILD_PLATFORM=@BUILD_PLATFORM@
-BUILD_CPU=@BUILD_CPU@
-BUILD_VENDOR=@BUILD_VENDOR@
-BUILD_OS=@BUILD_OS@
-
-HOST_PLATFORM=@HOST_PLATFORM@
-HOST_CPU=@HOST_CPU@
-HOST_VENDOR=@HOST_VENDOR@
-HOST_OS=@HOST_OS@
-
-PROC=@HOST_CPU@
-OSARCH=@OSARCH@
-OSREV=@PBX_OSREV@
-
-GC_CFLAGS=@GC_CFLAGS@
-GC_LDFLAGS=@GC_LDFLAGS@
-
-PTHREAD_CFLAGS=@PTHREAD_CFLAGS@
-PTHREAD_LIBS=@PTHREAD_LIBS@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-datarootdir = @datarootdir@
-datadir = @datadir@
-includedir = @includedir@
-infodir = @infodir@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-
-AST_DEVMODE=@AST_DEVMODE@
-
-AST_DECLARATION_AFTER_STATEMENT=@AST_DECLARATION_AFTER_STATEMENT@
-AST_NO_STRICT_OVERFLOW=@AST_NO_STRICT_OVERFLOW@
-
-ASOUND_INCLUDE=@ALSA_INCLUDE@
-ASOUND_LIB=@ALSA_LIB@
-
-CURL_INCLUDE=@CURL_INCLUDE@
-CURL_LIB=@CURL_LIB@
-
-CURSES_INCLUDE=@CURSES_INCLUDE@
-CURSES_LIB=@CURSES_LIB@
-CURSES_DIR=@CURSES_DIR@
-
-EDITLINE_LIB=@EDITLINE_LIB@
-
-FREETDS_INCLUDE=@FREETDS_INCLUDE@
-FREETDS_LIB=@FREETDS_LIB@
-
-GSM_INTERNAL=@GSM_INTERNAL@
-GSM_INCLUDE=@GSM_INCLUDE@
-GSM_LIB=@GSM_LIB@
-
-GTK_INCLUDE=@GTK_INCLUDE@
-GTK_LIB=@GTK_LIB@
-
-GTK2_INCLUDE=@GTK2_INCLUDE@
-GTK2_LIB=@GTK2_LIB@
-
-IKSEMEL_INCLUDE=@IKSEMEL_INCLUDE@
-IKSEMEL_LIB=@IKSEMEL_LIB@
-
-GNUTLS_INCLUDE=@GNUTLS_INCLUDE@
-GNUTLS_LIB=@GNUTLS_LIB@
-
-IMAP_TK_INCLUDE=@IMAP_TK_INCLUDE@
-IMAP_TK_LIB=@IMAP_TK_LIB@
-
-KDEDIR=@KDEDIR@
-KDE_INCLUDE=@KDE_INCLUDE@
-KDE_LIB=@KDE_LIB@
-
-NBS_INCLUDE=@NBS_INCLUDE@
-NBS_LIB=@NBS_LIB@
-
-NCURSES_INCLUDE=@NCURSES_INCLUDE@
-NCURSES_LIB=@NCURSES_LIB@
-NCURSES_DIR=@NCURSES_DIR@
-
-NETSNMP_LIB=@NETSNMP_LIB@
-
-NEWT_INCLUDE=@NEWT_INCLUDE@
-NEWT_LIB=@NEWT_LIB@
-
-OGG_INCLUDE=@OGG_INCLUDE@
-OGG_LIB=@OGG_LIB@
-
-OSPTK_INCLUDE=@OSPTK_INCLUDE@
-OSPTK_LIB=@OSPTK_LIB@
-
-OSSAUDIO_INCLUDE=@OSS_INCLUDE@
-OSSAUDIO_LIB=@OSS_LIB@
-
-PGSQL_INCLUDE=@PGSQL_INCLUDE@
-PGSQL_LIB=@PGSQL_LIB@
-
-POPT_INCLUDE=@POPT_INCLUDE@
-POPT_LIB=@POPT_LIB@
-
-PRI_INCLUDE=@PRI_INCLUDE@
-PRI_LIB=@PRI_LIB@
-
-PWLIB_INCLUDE=@PWLIB_INCLUDE@
-PWLIB_LIB=@PWLIB_LIB@
-
-RADIUS_INCLUDE=@RADIUS_INCLUDE@
-RADIUS_LIB=@RADIUS_LIB@
-
-SPEEX_INCLUDE=@SPEEX_INCLUDE@
-SPEEX_LIB=@SPEEX_LIB@
-
-SPEEXDSP_INCLUDE=@SPEEXDSP_INCLUDE@
-SPEEXDSP_LIB=@SPEEXDSP_LIB@
-
-SQLITE_INCLUDE=@SQLITE_INCLUDE@
-SQLITE_LIB=@SQLITE_LIB@
-
-SSL_INCLUDE=@OPENSSL_INCLUDE@
-SSL_LIB=@OPENSSL_LIB@
-
-TONEZONE_INCLUDE=@TONEZONE_INCLUDE@
-TONEZONE_LIB=@TONEZONE_LIB@
-
-USB_INCLUDE=@USB_INCLUDE@
-USB_LIB=@USB_LIB@
-
-UNIXODBC_INCLUDE=@UNIXODBC_INCLUDE@
-UNIXODBC_LIB=@UNIXODBC_LIB@
-
-VORBIS_INCLUDE=@VORBIS_INCLUDE@
-VORBIS_LIB=@VORBIS_LIB@
-
-VPBAPI_INCLUDE=@VPB_INCLUDE@
-VPBAPI_LIB=@VPB_LIB@
-
-ZAPTEL_INCLUDE=@ZAPTEL_INCLUDE@
-
-ZLIB_INCLUDE=@ZLIB_INCLUDE@
-ZLIB_LIB=@ZLIB_LIB@
-
-ISDNNET_INCLUDE=@ISDNNET_INCLUDE@
-ISDNNET_LIB=@ISDNNET_LIB@
-
-MISDN_INCLUDE=@MISDN_INCLUDE@
-MISDN_LIB=@MISDN_LIB@
-
-SUPPSERV_INCLUDE=@SUPPSERV_INCLUDE@
-SUPPSERV_LIB=@SUPPSERV_LIB@
-
-CAP_LIB=@CAP_LIB@
-CAP_INCLUDE=@CAP_INCLUDE@
-
-TERMCAP_INCLUDE=@TERMCAP_INCLUDE@
-TERMCAP_LIB=@TERMCAP_LIB@
-TERMCAP_DIR=@TERMCAP_DIR@
-
-TINFO_INCLUDE=@TINFO_INCLUDE@
-TINFO_LIB=@TINFO_LIB@
-TINFO_DIR=@TINFO_DIR@
diff --git a/1.4/missing b/1.4/missing
deleted file mode 100755
index 22e101ab1..000000000
--- a/1.4/missing
+++ /dev/null
@@ -1,198 +0,0 @@
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-# Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
-# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
-fi
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.in; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
-
-case "$1" in
-
- -h|--h|--he|--hel|--help)
- echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
- -h, --help display this help and exit
- -v, --version output version information and exit
-
-Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
- ;;
-
- -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
- echo "missing - GNU libit 0.0"
- ;;
-
- -*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
- ;;
-
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`acinclude.m4' or \`$configure_ac'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`$configure_ac'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`acconfig.h' or \`$configure_ac'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case "$f" in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if [ $# -ne 1 ]; then
- eval LASTARG="\${$#}"
- case "$LASTARG" in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if [ ! -f y.tab.h ]; then
- echo >y.tab.h
- fi
- if [ ! -f y.tab.c ]; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if [ $# -ne 1 ]; then
- eval LASTARG="\${$#}"
- case "$LASTARG" in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if [ ! -f lex.yy.c ]; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- makeinfo)
- echo 1>&2 "\
-WARNING: \`$1' is missing on your system. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
- if test -z "$file"; then
- file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
- fi
- touch $file
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and you do not seem to have it handy on your
- system. You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequirements for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
-
-exit 0
diff --git a/1.4/mkinstalldirs b/1.4/mkinstalldirs
deleted file mode 100755
index 6b3b5fc5d..000000000
--- a/1.4/mkinstalldirs
+++ /dev/null
@@ -1,40 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain
-
-# $Id$
-
-errstatus=0
-
-for file
-do
- set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
- shift
-
- pathcomp=
- for d
- do
- pathcomp="$pathcomp$d"
- case "$pathcomp" in
- -* ) pathcomp=./$pathcomp ;;
- esac
-
- if test ! -d "$pathcomp"; then
- echo "mkdir $pathcomp"
-
- mkdir "$pathcomp" || lasterr=$?
-
- if test ! -d "$pathcomp"; then
- errstatus=$lasterr
- fi
- fi
-
- pathcomp="$pathcomp/"
- done
-done
-
-exit $errstatus
-
-# mkinstalldirs ends here
diff --git a/1.4/pbx/Makefile b/1.4/pbx/Makefile
deleted file mode 100644
index b7a8c0067..000000000
--- a/1.4/pbx/Makefile
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for PBX modules
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=PBX
-MENUSELECT_DESCRIPTION=PBX Modules
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard pbx_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard pbx_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_PBX),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_PBX),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring pbx,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
-
-clean::
- rm -f ael/*.o
-
-ael/ael_lex.o: ael/ael_lex.c ../include/asterisk/ael_structs.h ael/ael.tab.h
-ael/ael_lex.o: ASTCFLAGS+=-I. -Wno-unused
-
-ael/ael.tab.o: ael/ael.tab.c ael/ael.tab.h ../include/asterisk/ael_structs.h
-ael/ael.tab.o: ASTCFLAGS+=-I.
-
-ael/ael.tab.o ael/ael_lex.o: ASTCFLAGS+=$(MENUSELECT_OPTS_pbx_ael:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_pbx_ael),$(value $(dep)_INCLUDE))
-
-$(if $(filter pbx_ael,$(EMBEDDED_MODS)),modules.link,pbx_ael.so): ael/ael.tab.o ael/ael_lex.o
-
-ael/ael_lex.c:
- (cd ael; flex ael.flex; sed -i -e "/begin standard C headers/i#include \"asterisk.h\"" ael_lex.c)
- (cd ael; sed 's@#if __STDC_VERSION__ >= 199901L@#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L@' ael_lex.c > zz; mv zz ael_lex.c)
-
-ael/ael.tab.c ael/ael.tab.h:
- (cd ael; bison -v -d ael.y)
-
-dundi-parser.o: dundi-parser.h
-dundi-parser.o: ASTCFLAGS+=-I.
-
-dundi-parser.o: ASTCFLAGS+=$(MENUSELECT_OPTS_pbx_dundi:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_pbx_dundi),$(value $(dep)_INCLUDE))
-
-$(if $(filter pbx_dundi,$(EMBEDDED_MODS)),modules.link,pbx_dundi.so): dundi-parser.o
diff --git a/1.4/pbx/ael/ael-test/ael-ntest10/extensions.ael b/1.4/pbx/ael/ael-test/ael-ntest10/extensions.ael
deleted file mode 100644
index 4a8386ccf..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest10/extensions.ael
+++ /dev/null
@@ -1,131 +0,0 @@
-macro endsess()
-{
- NoOp(hithere);
-}
-
-macro nullchk(type)
-{
- NoOp(${type} is this);
-}
-
-macro endcall(type) {
- switch(${type}) {
- case out:
- &nullchk(callid);
- if(${testnotnull}) {
- &endsess();
- goto ptr1 ; // <-- goto call to valid label
- }
- else {
-ptr1: // <-- valid label
- Softhangup(${CHANNEL});
- break ;
- }
- Noop(esac) ;
- }
-}
-
-macro endcall2(type) {
- switch(${type}) {
- case out:
- &nullchk(callid);
- if(${testnotnull}) {
- &endsess();
- goto ptr1 ; // <-- goto call to valid label
- }
- case out2:
- {
-ptr1: // <-- valid label
- Softhangup(${CHANNEL});
- break ;
- }
- Noop(esac) ;
- }
-}
-
-macro endcall3(type) {
- switch(${type}) {
- case out:
- &nullchk(callid);
- if(${testnotnull}) {
- &endsess();
- goto ptr1 ; // <-- goto call to valid label
- }
- Noop(esac) ;
- }
- if(${testnotnull}) {
- goto ptr1;
- }
- switch(${type}) {
- case out:
- if(${testnotnull}) {
-ptr1: // <-- valid label
- Softhangup(${CHANNEL});
- break ;
- }
- Noop(esac) ;
- }
-}
-
-macro endcall4(type) {
- switch(${type}) {
- case out:
- &nullchk(callid);
- if(${testnotnull}) {
- &endsess();
- goto ptr1 ; // <-- goto call to valid label
- }
- Noop(esac) ;
- }
- if(${testnotnull}) {
- goto ptr1;
- }
- switch(${type}) {
- case out:
- switch(${type})
- {
- case in:
- if(${testnotnull}) {
-ptr1: // <-- valid label
- Softhangup(${CHANNEL});
- break ;
- }
- Noop(esac) ;
- }
- }
-}
-
-macro endcall5(type) {
- switch(${type}) {
- case out:
- &nullchk(callid);
- if(${testnotnull}) {
- &endsess();
- goto ptr1 ; // <-- goto call to valid label
- }
- case in:
- &nullchk(callid);
- ptr2:
- if(${testnotnull}) {
- &endsess();
- goto ptr1 ; // <-- goto call to valid label
- }
- Noop(esac) ;
- }
- if(${testnotnull}) {
- goto ptr1;
- }
- switch(${type}) {
- case out:
- switch(${type})
- {
- case in:
- if(${testnotnull}) {
-ptr1: // <-- valid label
- Softhangup(${CHANNEL});
- break ;
- }
- Noop(esac) ;
- }
- }
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest12/extensions.ael b/1.4/pbx/ael/ael-test/ael-ntest12/extensions.ael
deleted file mode 100644
index 1e3183358..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest12/extensions.ael
+++ /dev/null
@@ -1,13 +0,0 @@
-context test1
-{
- 771 => {
- for( i=0;
- ${i} <= 3;
- i = ${i} + 1 )
- NoOp(i is '${i}');
- }
- 772 => {
- for(i=0; ${i} <= 3;i= ${i} + 1 )
- NoOp(i is '${i}');
- }
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/extensions.ael b/1.4/pbx/ael/ael-test/ael-ntest22/extensions.ael
deleted file mode 100644
index b787f4b03..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/extensions.ael
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "t1/*.ael"
-
-context z
-{
- 123 => NoOp(hi there, z);
- 124 => NoOp(hi there, z);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/qq.ael b/1.4/pbx/ael/ael-test/ael-ntest22/qq.ael
deleted file mode 100644
index c446f53fc..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/qq.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context qq
-{
- 567 => NoOp(hi there, qq);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t1/a.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t1/a.ael
deleted file mode 100644
index 62e3fc588..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t1/a.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context a
-{
- 134 => NoOp(hi there, a);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t1/b.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t1/b.ael
deleted file mode 100644
index 29d8d1ff4..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t1/b.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context b
-{
- 456 => NoOp(hithere, b);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t1/c.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t1/c.ael
deleted file mode 100644
index 3c6df4bde..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t1/c.ael
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-context c
-{
- 567 => NoOp(hi there, c);
-}
-
-#include "t2/*.ael"
-
-context w
-{
- 890 => NoOp(hi there, w);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t2/d.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t2/d.ael
deleted file mode 100644
index 6362278f7..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t2/d.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context d
-{
- 134 => NoOp(hi there, d);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t2/e.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t2/e.ael
deleted file mode 100644
index 9465c8b4e..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t2/e.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context e
-{
- 456 => NoOp(hithere, e);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t2/f.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t2/f.ael
deleted file mode 100644
index ba15a6389..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t2/f.ael
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "qq.ael"
-
-context f
-{
- 567 => NoOp(hi there, f);
-}
-
-#include "t3/*.ael"
-
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t3/g.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t3/g.ael
deleted file mode 100644
index 0f1ecc805..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t3/g.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context g
-{
- 134 => NoOp(hi there, g);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t3/h.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t3/h.ael
deleted file mode 100644
index f9e3ca89f..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t3/h.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context h
-{
- 456 => NoOp(hithere, h);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t3/i.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t3/i.ael
deleted file mode 100644
index 5639a1e98..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t3/i.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context i
-{
- 134 => NoOp(hi there, i);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest22/t3/j.ael b/1.4/pbx/ael/ael-test/ael-ntest22/t3/j.ael
deleted file mode 100644
index 8dfc6c05f..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest22/t3/j.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context j
-{
- 567 => NoOp(hi there, j);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/extensions.ael b/1.4/pbx/ael/ael-test/ael-ntest23/extensions.ael
deleted file mode 100644
index 7128258ed..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/extensions.ael
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "t1/*.ael"
-
-context z ()
-{
- 123 => NoOp(hi there, z);
- 124 => NoOp(hi there, z);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/qq.ael b/1.4/pbx/ael/ael-test/ael-ntest23/qq.ael
deleted file mode 100644
index c446f53fc..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/qq.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context qq
-{
- 567 => NoOp(hi there, qq);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t1/a.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t1/a.ael
deleted file mode 100644
index 62e3fc588..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t1/a.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context a
-{
- 134 => NoOp(hi there, a);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t1/b.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t1/b.ael
deleted file mode 100644
index 29d8d1ff4..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t1/b.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context b
-{
- 456 => NoOp(hithere, b);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t1/c.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t1/c.ael
deleted file mode 100644
index d18eb7677..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t1/c.ael
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-context c()
-{
- 567 => NoOp(hi there, c);
-}
-
-#include "t2/*.ael"
-
-context w()
-{
- 890 => NoOp(hi there, w);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t2/d.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t2/d.ael
deleted file mode 100644
index 6362278f7..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t2/d.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context d
-{
- 134 => NoOp(hi there, d);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t2/e.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t2/e.ael
deleted file mode 100644
index 9465c8b4e..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t2/e.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context e
-{
- 456 => NoOp(hithere, e);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t2/f.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t2/f.ael
deleted file mode 100644
index ba15a6389..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t2/f.ael
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "qq.ael"
-
-context f
-{
- 567 => NoOp(hi there, f);
-}
-
-#include "t3/*.ael"
-
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t3/g.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t3/g.ael
deleted file mode 100644
index 0f1ecc805..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t3/g.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context g
-{
- 134 => NoOp(hi there, g);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t3/h.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t3/h.ael
deleted file mode 100644
index f9e3ca89f..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t3/h.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context h
-{
- 456 => NoOp(hithere, h);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t3/i.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t3/i.ael
deleted file mode 100644
index 5639a1e98..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t3/i.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context i
-{
- 134 => NoOp(hi there, i);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest23/t3/j.ael b/1.4/pbx/ael/ael-test/ael-ntest23/t3/j.ael
deleted file mode 100644
index 8dfc6c05f..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest23/t3/j.ael
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-context j
-{
- 567 => NoOp(hi there, j);
-}
diff --git a/1.4/pbx/ael/ael-test/ael-ntest9/extensions.ael b/1.4/pbx/ael/ael-test/ael-ntest9/extensions.ael
deleted file mode 100755
index b9762ed54..000000000
--- a/1.4/pbx/ael/ael-test/ael-ntest9/extensions.ael
+++ /dev/null
@@ -1,12 +0,0 @@
-
-context workext {
- ignorepat => 8;
- ignorepat => 9;
- 793 => {
- Set(QUERYSTRING=SELECT\ foo\,\ bar\ FROM\ foobar);
- Verbose(2|${QUERYSTRING});
- query="SELECT foo\, bar FROM foobar" ;
- Verbose(2|${query}) ;
- }
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-test1/extensions.ael b/1.4/pbx/ael/ael-test/ael-test1/extensions.ael
deleted file mode 100644
index e1943f67c..000000000
--- a/1.4/pbx/ael/ael-test/ael-test1/extensions.ael
+++ /dev/null
@@ -1,163 +0,0 @@
-
-macro testdial(number, timeout) {
- Dial(IAX2/vpconnect-t02/${number},${timeout},${OG_DIAL_FLAGS});
- switch (${DIALSTATUS}) {
- case CHANUNAVAIL:
- goto dial-trunk2;
- break;
- default:
- NoOp(t02 Unavailable - ${DIALSTATUS});
- return;
- }
-
-dial-trunk2:
- Dial(IAX2/vpconnect-t01/${number},${timeout},${OG_DIAL_FLAGS});
-
-}
-
-macro exten-gen(name,pword)
-{
- if( ${DB_EXISTS(org/${GroupID}/${name}/secret)} = 0 )
- goto other|nomatch|begin;
- if( ${DB(org/${GroupID}/${name}/secret)}foo != ${pword}foo )
- goto other|nomatch|begin;
-
-};
-
-context what {
- who =>
- {
- random(51) NoOp(This should appear 51% of the time);
-
- random( 60 )
- {
- NoOp( This should appear 60% of the time );
- }
- else
- {
- random(75)
- {
- NoOp( This should appear 30% of the time! );
- }
- else
- {
- NoOp( This should appear 10% of the time! );
- }
- }
- }
-}
-
-context other {
- nomatch => {
- begin:
- NoOp(Hello!);
- switch(${DIALSTATUS})
- {
- case BUSY:
- NoOp(wow);
- case TORTURE:
- NoOp(woow);
- };
- NoOp(woohoo);
- };
-};
-
-context testloop {
- includes {
- other|16:00-23:59|m0n-fri|*|*;
- };
-
- 1 => {
- for (x=0; ${x} < 3; x=${x} + 1) {
- Verbose(x is ${x} !);
- if( ${x} = 1 )
- continue;
- if( ${x} = 2 )
- break;
- };
- ifTime(14:00-25:00|sat-sun|*|*) {
- BackGround(Hello);
- } else
- BackGround(Sorry);
- NoOp(This is a totally useless NOOP);
- };
- 2 => {
- y=10;
- while (${y} >= 0) {
- Verbose(y is ${y} !);
- if( ${y} = 1 )
- continue;
- if( ${y} = 2 )
- break;
- if( ${y} = 3 )
- return;
- y=${y}-1;
- };
- };
- regexten hint(nasty/Thingy&nasty/Thingamabob) 3 => {
- for (x=0; ${x} < 3; x=${x} + 1)
- {
- Verbose(x is ${x} !);
- if( ${x} = 4 )
- break;
- if( ${x} = 5 )
- continue;
- if( ${x} = 6 )
- return;
-
- y=10;
- while (${y} >= 0)
- {
- Verbose(y is ${y} !);
- if( ${y} = 4 )
- break;
- if( ${y} = 5 )
- continue;
- if( ${y} = 6 )
- return;
- y=${y}-1;
- };
- };
- };
- 4 => {
- y=10;
- while (${y} >= 0)
- {
- Verbose(y is ${y} !);
- if( ${y} = 4 )
- break;
- if( ${y} = 5 )
- continue;
- if( ${y} = 6 )
- return;
- for (x=0; ${x} < 3; x=${x} + 1)
- {
- Verbose(x is ${x} !);
- if( ${x} = 4 )
- break;
- if( ${x} = 5 )
- continue;
- if( ${x} = 6 )
- return;
- for (z=0; ${z} < 17; z=${z} + 1)
- {
- Verbose(z is ${z} !);
- Verbose(z is ${z} !);
- if( ${z} = 4 )
- break;
- if( ${z} = 5 )
- continue;
- if( ${z} = 6 )
- return;
- Verbose(z is ${z} !);
- Verbose(z is ${z} !);
- };
-
- };
- y=${y}-1;
- };
- };
- 5 => {
- &exten-gen(axel,brain);
- };
-};
diff --git a/1.4/pbx/ael/ael-test/ael-test11/extensions.ael b/1.4/pbx/ael/ael-test/ael-test11/extensions.ael
deleted file mode 100644
index 886a51eb5..000000000
--- a/1.4/pbx/ael/ael-test/ael-test11/extensions.ael
+++ /dev/null
@@ -1,56 +0,0 @@
-context test1
-{
- s =>
- {
- goto lab1;
- if( ${testnotnull} )
- {
- lab1:
- NoOp(hello);
- }
- else
- {
- lab1:
- MoOp(goodbye);
- }
- }
-
- 1 =>
- {
- lab1:
- NoOp(This one is OK.);
- }
-}
-
-macro endcall5(type) {
- switch(${type}) {
- case out:
- if(${testnotnull}) {
- NoOp(whoosh);
- goto ptr1 ; // <-- goto call to valid label
- }
- case in:
- ptr1: // The First label is the valid one...
- if(${testnotnull}) {
- NoOp(wow);
- goto ptr1 ; // <-- goto call to valid label
- }
- Noop(esac) ;
- }
- if(${testnotnull}) {
- goto ptr1;
- }
- switch(${type}) {
- case out:
- switch(${type})
- {
- case in:
- if(${testnotnull}) {
-ptr1: // <-- duplicate label (macros are about the equiv of an extension)
- Softhangup(${CHANNEL});
- break ;
- }
- Noop(esac) ;
- }
- }
-}
diff --git a/1.4/pbx/ael/ael-test/ael-test14/extensions.ael b/1.4/pbx/ael/ael-test/ael-test14/extensions.ael
deleted file mode 100644
index 20d69134f..000000000
--- a/1.4/pbx/ael/ael-test/ael-test14/extensions.ael
+++ /dev/null
@@ -1,20 +0,0 @@
-context test1
-{
- 10 => {
- // nothing but a comment!
- }
-
- 11 => {
- switch(${somevar})
- {
- case somecase:
- // nothing but a comment!
- break;
- case somecase:
- // nothing but a comment!
- continue;
- }
- break;
- }
-
-}
diff --git a/1.4/pbx/ael/ael-test/ael-test15/extensions.ael b/1.4/pbx/ael/ael-test/ael-test15/extensions.ael
deleted file mode 100644
index c9cfdab96..000000000
--- a/1.4/pbx/ael/ael-test/ael-test15/extensions.ael
+++ /dev/null
@@ -1,17 +0,0 @@
-/* and some comments
- would make a nice touch */
-
-context t1
-{
- /* this a test of block comments */
-
- _15x => {
- /* more comments
- across several lines
- * what do you think*
- */
- }
-
-}
-
-/* amd some more */
diff --git a/1.4/pbx/ael/ael-test/ael-test16/extensions.ael b/1.4/pbx/ael/ael-test/ael-test16/extensions.ael
deleted file mode 100644
index 5f3b2e4e9..000000000
--- a/1.4/pbx/ael/ael-test/ael-test16/extensions.ael
+++ /dev/null
@@ -1,4 +0,0 @@
-context real-small {
-
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-test18/extensions.ael b/1.4/pbx/ael/ael-test/ael-test18/extensions.ael
deleted file mode 100644
index ee03d5909..000000000
--- a/1.4/pbx/ael/ael-test/ael-test18/extensions.ael
+++ /dev/null
@@ -1,40 +0,0 @@
-context default
-{
-
-706/3077610011 => {
- JabberStatus(asterisk|jmls@mike,StatusCode);
-
- switch(${StatusCode}) {
- case 1:
- Dial(SIP/706,12);
- switch(${DIALSTATUS}) {
- case BUSY:
- Voicemail(b706);
- break;
- default:
- Voicemail(u706);
- };
- BackGround(hello);
- break;
- default:
- Voicemail(u706);
- };
- ifTime(3:00-13:00|*|*|*)
- {
- NoOp(hello);
- label1:
- NoOp(goodbye);
- }
- else
- {
- NoOp(hithere);
- label2:
- NoOp(whatonearth?);
- }
- goto label1;
- goto label2;
- Hangup();
- };
-
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-test19/extensions.ael b/1.4/pbx/ael/ael-test/ael-test19/extensions.ael
deleted file mode 100644
index 5218c52aa..000000000
--- a/1.4/pbx/ael/ael-test/ael-test19/extensions.ael
+++ /dev/null
@@ -1,377 +0,0 @@
-context dialextens
-{
- /*
- 101 thru 123, 149 thru 152
- */
- _10X => Dial(Zap/${EXTEN:2},30,Ttw);
- _1ZX => Dial(Zap/${EXTEN:1},30,Ttw);
-}
-/*
- Due to extenal wiring:
-
- dialing 125 will ring 101
- dialing 126 will ring 102
- and so on until
- dialing 147 will ring 123
-
-We can dial out on zap 69 thru 72; and 25-47
-
-*/
-
-context dialthrus
-{
- /* 369-372; 325-347 */
- _3XX => Dial(Zap/${EXTEN:1},30,Ttw);
-}
-
-context t1incoming
-{
- includes
- {
- dialextens;
- parkedcalls;
- }
- s => {
- Answer();
- Background(welcome-to-test-machine);
- }
-
-}
-
-context t1extension
-{
- includes
- {
- dialextens;
- dialthrus;
- }
-
-}
-
-context incoming
-{
- includes
- {
- dialextens;
- parkedcalls;
- }
- s => {
- Answer();
- Background(welcome-to-test-machine);
- }
-}
-
-context incoming
-{
- s => {
- Answer();
- }
-}
-
-macro std-priv-exten( dev, ext , timeout, opts, torcont, dontcont )
-{
- // &increment_chosecount();
- dial_again:
- Dial(${dev},${timeout},${opts});
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
-
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
-
- case BUSY:
- label_busy:
- Read(reply|work-exten-busy|1||2|15);
- if ("${reply}"=="")
- goto label_busy; // infinite loop if Read has probs!!
- switch(${reply})
- {
- case 1:
- Set(time1=${EPOCH});
-
- label_redial:
-
- WaitMusicOnHold(5);
- Dial(${dev},${timeout},${opts});
-
- switch(${DIALSTATUS})
- {
- case BUSY:
- if(${EPOCH}-${time1} >= 20)
- goto label_busy;
- goto label_redial;
-
- default:
- return;// goto work_line|s|loopback;
- }
- break;
- case 2:
- Voicemail(${ext}|b);
- break;
- case 3:
- return; // goto work_line|s|loopback;
- default:
- Background(invalid);
- goto label_busy;
- }
- break;
-
- case ANSWER:
- break;
-
- case NOANSWER:
- noanswer_label:
- Read(reply|work-exten-noanswer|1|skip|2|15);
- switch(${reply})
- {
- case 1:
- switch(${ext})
- {
- case 10:
- Background(no-cell);
- break;
- case 11:
- // &ciddial(2729495,3072729495,30,tw,${GRAMS_TELCO},${WORK_TELCO});
- break;
- case 12:
- // &ciddial(2725560,3072725560,30,tw,${GRAMS_TELCO},${WORK_TELCO});
- break;
- case 13:
- // &ciddial(2720197,3072720197,30,tw,${GRAMS_TELCO},${WORK_TELCO});
- break;
- case 14:
- // &ciddial(2501174,3072501174,30,tw,${GRAMS_TELCO},${WORK_TELCO});
- break;
- case 15:
- Background(no-cell);
- break;
- case 16:
- Background(no-cell);
- break;
- default:
- Background(invalid);
- break;
- }
- goto noanswer_label;
- break;
- case 2:
- Voicemail(${ext}|u);
- break;
- case 3:
- return; // goto work_line|s|loopback;
- default:
- Background(invalid);
- goto noanswer_label;
- }
- Voicemail(${ext}|u);
- break;
- default:
- Voicemail(${ext}|u);
- }
-}
-/* Putting these 3 funcs in extensions.conf!
-macro funcC(a,b)
-{
- Set(Key=);
- menu:
- Read(Key,main-menu,1,n,1,5);
- if("${Key}" = "2")
- goto y,lab1;
- catch y
- { lab1:
- &funcB(${a},${b});
- }
-}
-
-macro funcB(a,b)
-{
- Set(Key=);
- menu:
- Read(Key,tt-monkeys,1,n,1,5);
- if("${Key}" = "2")
- goto z,lab2;
- catch z
- { lab2:
- &funcC(${a},${b});
- }
-}
-
-macro funcA()
-{
- &funcB(1,2);
-}
-*/
-
-context extension
-{
- includes
- {
- dialextens;
- dialthrus;
- parkedcalls;
- }
- 5 => {
- Record(recording:wav);
- Background(recording);
- }
-
- 81 => {
- iterations=1000000;
- Set(time1=${EPOCH});
- for(i=1; ${i}<${iterations}; i=${i}+1)
- {
- NoOp(Hello);
- }
- Set(time2=${EPOCH});
- Verbose(The time diff is $[${time2} - ${time1} ] seconds);
- Verbose(Which means that the priorities/sec = $[4* ${iterations} / (${time2} - ${time1}) ]);
- SayNumber($[4 * ${iterations} / (${time2} - ${time1}) ]);
- }
- 82 => {
- &ndeep(100000);
- Verbose(Finished 100000 levels deep call!);
- }
- 83 => {
- switch (${EXTEN})
- {
- pattern 8X:
- Verbose(do something to prepare it);
- pattern 9X:
- Verbose(handle both 1xx and 2xx calls);
- pattern [4-7]X:
- Verbose(and this too!);
- }
- Set(junky=${RAND(0|99999)});
- Verbose(Here is a random number: ${junky}.);
- }
- 84 => {
- agi(agi://192.168.134.252/|hello|goodbye|whatever|whoknows,hell2,hello3);
- }
- 85 => {
- &std-priv-exten( Zap/50, 150 , 25, mtw, torcont, dontcont );
- }
- 86 => {
- Verbose(The version is: ${VERSION()} );
- Verbose(The versionnum is: ${VERSION(ASTERISK_VERSION_NUM)} );
- Verbose(The user is: ${VERSION(BUILD_USER)} );
- Verbose(The hostname is: ${VERSION(BUILD_HOSTNAME)} );
- Verbose(The machine is: ${VERSION(BUILD_MACHINE)} );
- Verbose(The OS is: ${VERSION(BUILD_OS)} );
- Verbose(The date is: ${VERSION(BUILD_DATE)} );
- Verbose(The kernel is: ${VERSION(BUILD_KERNEL)} );
- Set(vinf=${VERSION()});
- Set(vrand=${RAND()});
- if( ${ISNULL(${vinf})} )
- {
- if( ${ISNULL(${vrand})} )
- Verbose(Version 1.2 or earlier);
- else
- Verbose(Version 1.4!!!);
- }
- else
- Verbose(${vinf} indicates version pre-1.6 or higher);
- }
- 871 => {
- NoOp( 1 1 1 1 1 1 1);
- NoOp( 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6);
- NoOp(012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678890123456789012345678901234567890);
- NoOp(${EXTEN:1:2} ${EXTEN} ${EXTEN:1} 1 1 1 1 1 1 1);
- &dialoutpstn(${TDIRECTCALL-PST}/0${EXTEN},${E${CALLERID(num)}-OPT},${TDIRECTCALL-CID},${TDIRECTCALL-MAX},RotaPadrao) ;
-
- }
- 872 => {
- Set(ChannelOnly=${CUT(CHANNEL||1)});
- Verbose(ChannelOnly=${ChannelOnly}; neat huh?);
- Set(ChannelOnly=${CUT(CHANNEL,,1)});
- Verbose(ChannelOnly=${ChannelOnly}; neat huh?);
- }
- 873 => {
- NOOP(this is a forkcdr test);
- Set(CALLERID(number)=1234567890);
- Set(CALLERID(name)=before fork);
- Forkcdr(v);
- Set(CALLERID(number)=0987654321);
- Set(CALLERID(name)=after fork);
- Answer();
- Echo();
- Hangup();
- }
- 874 => {
- SayDigits(307-754-5675);
- SayPhoneNumber(307-754-5675);
- SayDigits(--);
- SayPhoneNumber(123-456-7890);
- SayDigits(++);
- SayPhoneNumber(307-754-4454);
- }
- 875 => {
- &funcA();
- &funcD();
- }
- 876 => {
- NoOp(Query resultid ${connid} SELECT var1\, var2 FROM did);
- NoOp($["Query resultid ${connid} SELECT var1\, var2 FROM did"]);
- NoOp($["Query resultid ${connid} SELECT var1, var2 FROM did"]);
- goto test5,s,1;
- }
- 88 => {
- SET(LIMIT_PLAYAUDIO_CALLER=yes);
- SET(LIMIT_PLAYAUDIO_CALLEE=no);
- SET(LIMIT_TIMEOUT_FILE=timeup);
- SET(LIMIT_CONNECT_FILE=limit60);
- SET(LIMIT_WARNING_FILE=almostup);
- Dial(Zap/51,20,L(60000:30000:8000));
- }
- 89 => {
- goto callbackmenu|100|1;
- }
-}
-
-context income1
-{
- s => {
- Answer();
- Dial(Zap/50,20,m);
- }
- 150 => Dial(Zap/50,20,m);
-}
-
-context callbackmenu
-{
- _X. => {
- Answer();
- Wait(1);
- Set(TIMEOUT(digit)=5);
- Set(TIMEOUT(response)=30);
- DISA(no-password,callbackdialout);
- }
-}
-
-context callbackdialout
-{
- _X. => {
- Dial(Zap/51,20,w);
- }
-
-}
-
-
-macro dialoutpstn(something1, something2, something3, something4, something5)
-{
- Verbose(${something1}--- ${something2}--- ${something3}--- ${something4}--- ${something5});
-}
-
-macro ndeep(level)
-{
- if( ${level} == 0)
- {
- Verbose(2|Got to Level 0);
- return;
- }
- &ndeep($[${level}-1]);
- return;
-}
diff --git a/1.4/pbx/ael/ael-test/ael-test2/apptest.ael2 b/1.4/pbx/ael/ael-test/ael-test2/apptest.ael2
deleted file mode 100644
index c477d8531..000000000
--- a/1.4/pbx/ael/ael-test/ael-test2/apptest.ael2
+++ /dev/null
@@ -1,146 +0,0 @@
-// this is a quick test to see how many of the apps we can spot j options in
-// include this in a macro or extension
-// at this moment, there are 18 apps that accept the j option.
-
- AddQueueMember(zork,iface,20,j);
- ADSIProg(sfile);
- AgentCallbackLogin(agent,s,30@cont);
- AgentLogin(agent,s);
- AgentMonitorOutgoing(dcn);
- AGI(whatever);
- AlarmReceiver();
- Answer(2);
- AppendCDRUserField(value);
- Authenticate(pword,adjmr);
- BackGround(filename,snm,eng);
- BackgroundDetect(filename,20,2,10);
- Busy(10);
- ChangeMonitor(fnamebase);
- ChanIsAvail(Zap/5,sj);
- ChanSpy(prefix,bg()qrv);
- Congestion(5);
- ControlPlayback(filename,10,6,4,0,5,7,j);
- DateTime(unixtime,tz,fmt);
- DBdel(fam/key);
- DBdeltree(fam);
- DeadAGI(command);
- Dial(zap/1,45,A()CdD()fgG()hHjL()m()M()nNoprS()tTwW);
- Dictate(basedir);
- Directory(cont,dcont,f);
- DISA(68986869876,context);
- DumpChan(verblev);
- DUNDiLookup(90709780978,context,bj);
- EAGI(command);
- Echo();
- EndWhile();
- Exec(appname,args);
- ExecIf(expr,app,data);
- ExecIfTime(*,*,*,*,appname);
- ExternalIVR(command,arg1);
- Festival(text);
- Flash();
- ForkCDR(v);
- GetCPEID();
- Gosub(cont,exten,priority);
- GosubIf(cond?label);
- Goto(cont,exten,prior);
- GotoIf(cond?t:f);
- GotoIfTime(*,*,*,*?cont,ext,prior);
- Hangup();
- HasNewVoicemail(vmbox,var,j);
- HasVoicemail(vmbox,var,j);
- IAX2Provision(template);
- ICES(xmlconfig);
- ImportVar(nevar@chann,var);
- Log(NOTICE,message);
- LookupBlacklist(j);
- LookupCIDName();
- Macro(macro,arg1);
- MacroExit();
- MacroIf(expr?etc);
- MailboxExists(mbox@cont,j);
- Math(v,2+2);
- MeetMe(5555,aAbcdDeimMpPqrstTovwxX);
- MeetMeAdmin(5555,e,user);
- MeetMeCount(5555,var);
- Milliwatt();
- MixMonitor(filename,abv()V()W(),command);
- Monitor(file.fmt,base,mb);
- MP3Player(location);
- MusicOnHold(class);
- NBScat();
- NoCDR();
- NoOp(ignored);
- Page(Zap/1,dq);
- Park(exten);
- ParkAndAnnounce(template,5,238,retcont);
- ParkedCall(exten);
- PauseQueueMember(queue,zap,j);
- Pickup(ext@cont);
- Playback(file,j);
- PlayTones(arg);
- PrivacyManager(3,4,j);
- Progress();
- Queue(queuename,dhHnrtTwW,http://www.where.what,over,5);
- Random(30,cont,ext,pri);
- Read(var,fname,10,skip,2,5);
- ReadFile(var=file,10);
- RealTime(fam,2,val,prefix);
- RealTimeUpdate(fam,2,val,2,newval);
- Record(file,2,10,anqst);
- RemoveQueueMember(queuename,iface,j);
- ResetCDR(wav);
- RetryDial(annound,4,2);
- Return();
- Ringing();
- RxFAX(fname,caller);
- SayAlpha(string);
- SayDigits(string);
- SayNumber(digits);
- SayPhonetic(string);
- SayUnixTime(unixtime,tz,fmt);
- SendDTMF(digits,10);
- SendImage(filename);
- SendText(text,j);
- SendURL(URL);
- Set(a=b);
- SetAMAFlags();
- SetCallerID(clid,a);
- SetCallerPres(allowed_passed_screen);
- SetCDRUserField(value);
- SetGlobalVar(var=val);
- SetMusicOnHold(class);
- SetTransferCapability(SPEECH);
- SIPAddHeader(header);
- SIPDtmfMode(inband,info,rfc);
- SIPGetHeader(var@headername);
- SMS(name);
- SoftHangup(zap/1,a);
- StackPop();
- StartMusicOnHold(class);
- StopMonitor();
- StopMusicOnHold();
- StopPlayTones();
- System(command);
- TestClient(testid);
- TestServer();
- Transfer(zap/1,j);
- TrySystem(command);
- TxFAX(filename,caller,debug);
- UnpauseQueueMember(queuename,iface,j);
- UserEvent(eventanme,body);
- Verbose(5,message);
- VMAuthenticate(mailbox@cont,s);
- VoiceMail(mailbox@cont,bg()suj);
- VoiceMailMain(mailbox@cont,pg()s);
- Wait(2);
- WaitExten(3,m());
- WaitForRing(2);
- WaitForSilence(2,y);
- WaitMusicOnHold(2);
- While(expr);
- Zapateller(answer,5);
- ZapBarge(channel);
- ZapRAS(arg);
- ZapScan(group);
- ZapSendKeypadFacility();
diff --git a/1.4/pbx/ael/ael-test/ael-test2/extensions.ael b/1.4/pbx/ael/ael-test/ael-test2/extensions.ael
deleted file mode 100644
index 176338872..000000000
--- a/1.4/pbx/ael/ael-test/ael-test2/extensions.ael
+++ /dev/null
@@ -1,8 +0,0 @@
-context test1
-{
- s =>
- {
- #include "apptest.ael2";
- }
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-test20/extensions.ael b/1.4/pbx/ael/ael-test/ael-test20/extensions.ael
deleted file mode 100644
index 8ec219864..000000000
--- a/1.4/pbx/ael/ael-test/ael-test20/extensions.ael
+++ /dev/null
@@ -1,8 +0,0 @@
-context interesting {
- eswitches {
- Realtime/default@extensions;
- IAX2/context@${CURSERVER};
- }
- 13 => NoOp(LuckyNumber!);
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-test3/extensions.ael b/1.4/pbx/ael/ael-test/ael-test3/extensions.ael
deleted file mode 100755
index dd77c0531..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/extensions.ael
+++ /dev/null
@@ -1,3183 +0,0 @@
-globals
-{
- static=yes;
- writeprotect=yes;
- CONSOLE=Console/dsp; // Console interface for demo
- IAXINFO=murf:tlhfckoct; // IAXtel username/password
- FWDNUMBER=544788 ; // your calling number
- FWDCIDNAME="Joe-Worker"; // your caller id
- FWDPASSWORD=zingledoodle ; // your password
- FWDRINGS=Zap/6 ; // the phone to ring
- FWDVMBOX=1 ; // the VM box for this user
-}
-
-macro std-exten( ext , dev )
-{
- Dial(${dev}/${ext},20);
- switch(${DIALSTATUS})
- {
- case BUSY:
- Voicemail(b${ext});
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- case ANSWER:
- break;
- default:
- Voicemail(u${ext});
- }
- catch a {
- VoiceMailMain(${ext});
- }
-}
-
-macro std-priv-exten_1( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_2( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_3( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_4( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_5( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_6( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_7( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_8( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_9( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_10( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_11( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_12( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_13( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_14( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_15( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_16( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_17( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_18( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_19( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_20( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_21( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_22( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_23( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_24( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_25( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_26( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_27( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_28( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_29( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_30( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_31( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_32( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_33( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_34( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_35( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_36( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_37( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_38( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_39( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_40( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_41( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_42( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_43( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_44( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_45( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_46( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_47( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_48( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_49( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_50( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_51( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_52( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_53( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_54( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_55( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_56( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_57( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_58( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_59( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_60( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_61( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_62( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_63( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_64( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_65( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_66( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_67( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_68( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_69( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_70( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_71( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_72( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_73( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-macro fillcidname()
-{
- if( "${CALLERID(number)}" = "" ) // nothing to work with, quit!!!
- return;
- Set(cidn=${DB(cidname/${CALLERID(num)})});
- if( "${CALLERID(name)}" != "" )
- {
- if( ("${cidn}" = "Privacy Manager" & "${CALLERID(name)}" != "Privacy Manager") | "${cidn}" = "" ) // if the entry isn't in the database,
- // or if an entry exists, and it's "Privacy Manager", empty, (or add other useless possibilities).
- {
- Set(DB(cidname/${CALLERID(number)})=${CALLERID(name)}); // then set or override what's in the DB
- }
- }
- // Now, we fill in the callerid info from the incoming entry, if it's stuff worth using
- // Ignore fundamentally semi-anonymous information from local cell phones
- // if the db has an entry for this number, and it's not a canned string from a cell phone company
- if( ( "${cidn}" != "" ) & ( "${CALLERID(name)}" = ""
- | "${CALLERID(name)}" = "CODY,WY "
- | "${CALLERID(name)}" = "POWELL,WY "
- | "${CALLERID(name)}" = "WIRELESS CALLER"
- | "${CALLERID(name)}" = "SUBSCRIBER,WIRE"
- | "${CALLERID(name)}" = "CELLULAR ONE"
- | "${CALLERID(name)}" = "Cellular One Customer"
- | "${CALLERID(name)}" = "CELLULAR ONE "
- | "${CALLERID(name)}" = "Privacy Manager"
- | "${CALLERID(name)}" = "RIVERTON,WY "
- | "${CALLERID(name)}" = "BASIN,WY "
- | "${CALLERID(name)}" = "BILLINGS,MT "
- | "${CALLERID(name)}" = "PROVO,UT "
- | "${CALLERID(name)}" = "TOLL FREE " ) ) // put stuff in the above, that the phone company tends to put in your callerid,
- // that you would rather override with DB info
- // there's no way to guess them all, but you can get the most popular ones...
- // why cell phones can't do CID like everybody else, ....?
- {
- Set(CALLERID(name)=${cidn}); // Override what the phone company provides with what's in the DB for this number.
- }
-}
-
-macro ciddial(dialnum, lookup, waittime, dialopts, ddev)
-{
- Set(cidnu=${CALLERID(num)});
- Set(cidn=${DB(cidname/${lookup})});
- Set(CALLERID(name)=${cidn});
- Dial(${ddev}/${dialnum}|${waittime}|${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_voip);
- CALLERID(num)=7075679201;
- Dial(SIP/1${lookup}@tctwest,${waittime},${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_cell);
- CALLERID(num)=${cidnu}; // put the original number back
- Dial(Zap/2/${lookup},${waittime},${dialopts});
- }
- }
-}
-
-macro ciddial3(dialnum, lookup, waittime, dialopts, ddev)
-{
- Set(cidnu=${CALLERID(num)});
- Set(cidn=${DB(cidname/${lookup})});
- Set(CALLERID(name)=${cidn});
- Dial(${ddev}/${dialnum}|${waittime}|${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_cell);
- Dial(Zap/2/${lookup},${waittime},${dialopts});
- }
-}
-
-macro ciddial2(dialnum, lookup, waittime, dialopts, ddev) // give priority to tctwest, then the ZAP in emergencies
-{
- Set(cidn=${DB(cidname/${lookup})});
- Set(cidnu=${CALLERID(num)});
- Set(CALLERID(name)=${cidn});
- Set(CALLERID(num)=7075679201);
- Dial(SIP/1${lookup}@tctwest,${waittime},${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- Set(CALLERID(num)=${cidnu}); // put the original number back
- BackGround(try_zap);
- Dial(${ddev}/${dialnum},${waittime}|${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_cell);
- Dial(Zap/2/${lookup},${waittime},${dialopts});
- }
- }
-}
-
-macro callerid-liar()
-{
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/priv-callerintros/LIAR.gsm&);
- Background(priv-liar); // Script: OOOps! Sorry! I don't allow men with ski masks pulled over their
- // faces to get in the front door, and unidentified callers won't fair
- // any better. You entered *MY* phone number. That won't work.
- // If you are telemarketing, cross me off the list, and don't call again.
- // If you did this by mistake, forgive my defenses, and call again.
- // Alternate: (priv-liar2)
- // Script: You have chosen to try to deceive my system and withold your CallerID,
- // by entering my own phone number as YOUR CallerID. I find this
- // offensive because you are being dishonest. I will not do business nor
- // waste my time talking to anyone who is less than honest and forthcoming.
- // Take me off your call list and do not call me again.
- Hangup();
-}
-
-macro callerid-bad()
-{
- mycid=${CALLERID(num)}:"1([0-9]+)";
- Set(CALLERID(num)=${mycid});
- Wait(0);
-}
-
-context privacyManagerFailed {
- s => {
- begin:
- Background(PrivManInstructions); // Script: OOps, that didn't go well. You need to enter *your* area code, and *your* 7 digit
- // phone number, for a total of 10 digits, or you'll be handed over to the monkeys. Let's
- // try this again, and hopefully you can get past our front-line defenses!
- PrivacyManager();
- if( "${PRIVACYMGRSTATUS}" = "FAILED" )
- {
- Background(tt-allbusy);
- Background(tt-somethingwrong);
- Background(tt-monkeysintro);
- Background(tt-monkeys);
- Background(tt-weasels);
- Hangup();
- }
- else
- {
- goto homeline|s|postPriv;
- }
- }
-}
-
-// Some comments
-// Some more comments
-
-context homeline {
- s => {
- begin:
- Answer();
- Set(repeatcount=0);
- Zapateller(nocallerid);
- PrivacyManager();
- if( "${PRIVACYMGRSTATUS}" = "FAILED" )
- {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/privmanfailed.gsm);
- &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
- Hangup();
- return;
-// goto privacyManagerFailed|s|begin;
- }
- postPriv:
- &fillcidname();
- Set(CONFCIDNA=${CALLERID(name)});
- Set(CONFCIDNU=${CALLERID(num)});
- AGI(callall);
- AGI(submit-announce.agi);
- if( "${CALLERID(num)}" : "1" )
- {
- &callerid-bad();
- }
- if( "${CALLERID(num)}" = "7077577685" & "${CALLERID(name)}" : "Privacy Manager" )
- {
- &callerid-liar();
- }
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- Set(lds=${DB(playlds/${CALLERID(num)})});
- if( "${lds}" = "1" )
- {
- SetMusicOnHold(mohlds);
- }
- direct=${DB(DirectCall/${CALLERID(num)})};
- if( "${direct}" != "" & ${direct} != 0 )
- {
- verbose(direct is XXX#${direct}XXXX);
- Playback(greetings/direct); // Welcome to the Murphy residence. This system will automatically try to connect you to...
- Playback(/var/spool/asterisk/voicemail/default/${direct}/greet);
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/${direct}/greet.wav&);
- switch(${direct})
- {
- case 1: //Steve
- &std-priv-exten(Zap/6r3&Sip/murf,1,25,mpA(beep)tw,telemarket,telemarket);
- goto s|loopback;
- case 2: //Sonya
- &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
- goto s|loopback;
- default: // all the kids
- Set(z=${direct}-2);
- goto homeline-kids|${z}|1;
- }
- }
- loopback:
- ifTime(*|*|20-25|dec)
- {
- Playback(greetings/christmas);
- }
- else ifTime(*|*|31|dec)
- {
- Playback(greetings/newyear);
- }
- else ifTime(*|*|1|jan)
- {
- Playback(greetings/newyear);
- }
- else ifTime(*|*|14|feb)
- {
- Playback(greetings/valentines);
- }
- else ifTime(*|*|17|mar)
- {
- Playback(greetings/stPat);
- }
- else ifTime(*|*|31|oct)
- {
- Playback(greetings/halloween);
- }
- else ifTime(*|mon|15-21|jan)
- {
- Playback(greetings/mlkDay);
- }
- else ifTime(*|thu|22-28|nov)
- {
- Playback(greetings/thanksgiving);
- }
- else ifTime(*|mon|25-31|may)
- {
- Playback(greetings/memorial);
- }
- else ifTime(*|mon|1-7|sep)
- {
- Playback(greetings/labor);
- }
- else ifTime(*|mon|15-21|feb)
- {
- Playback(greetings/president);
- }
- else ifTime(*|sun|8-14|may)
- {
- Playback(greetings/mothers);
- }
- else ifTime(*|sun|15-21|jun)
- {
- Playback(greetings/fathers);
- }
- else
- {
- Playback(greetings/hello); // None of the above? Just a plain hello will do
- }
- Background(murphy-homeline-intro1); // Script: Hello-- Welcome to the Murphy's! If you already know what
- // option you want, you don't have to wait for this entire spiel-- just
- // have at it.
- // If you are calling because this number is on a list of some sort, dial 6.
- // If you want Sonya, dial 1.
- // If you want one of the kids, dial 2.
- // If you want Steve, dial 3.
- // to play with your introduction, dial 5.
- // If we don't seem to be giving you the time of day, try 7.
- // Have a good day!
-
- }
- 1 => { // Sonya
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/2/greet.wav&);
- &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
- goto s|loopback;
- }
- 2 => { // Kids
- goto homeline-kids|s|begin;
- }
- 21 => {
- Dial(IAX2/seaniax,20,T);
- }
- 3 => { // Steve
- &std-priv-exten(Zap/6r3&Sip/murf,1,25,mpA(beep)tw,telemarket,telemarket);
- goto s|loopback;
- }
- 4 => { // Voicemail
- VoicemailMain();
- goto s|loopback;
- }
- 5 => { // play with intro
- goto home-introduction|s|begin;
- }
- 6 => { // Telemarketers
- goto telemarket|s|begin;
- }
- 7 => { // time of day, riddle
- agi(tts-riddle.agi);
- Background(gsm/what-time-it-is2);
- SayUnixTime();
- goto s|loopback;
- }
- 792 => { // Page All
- goto pageall|s|begin;
- }
- 793 => { // check the tone recognition
- Read(zz,,0,,1,0);
- SayDigits(${zz});
- }
- t => {
- Set(repeatcount=${repeatcount} + 1);
- if( ${repeatcount} < 3 )
- {
- goto s|loopback; // just loopback isn't enough
- }
- Hangup();
- }
- i => {
- Background(invalid);
- goto s|loopback;
- }
- o => {
- Congestion();
- }
- fax => {
- Dial(Zap/4);
- }
-}
-
-// Some comments
-// Some more comments
-
-context pageall {
- s => {
- begin:
- AGI(callall);
- MeetMe(5555,dtqp);
- MeetMeAdmin(5555,K);
- Hangup();
- }
-
- h => {
- begin:
- MeetMeAdmin(5555,K);
- Background(conf-muted);
- Hangup();
- }
-}
-
-// Some comments
-// Some more comments
-
-context add-to-conference {
- start => {
- NoCDR();
- MeetMe(5555,dmqp);
- }
- h => {
- Hangup();
- }
-}
-
-context home-introduction {
- s => {
- begin:
- Background(intro-options); // Script: To hear your Introduction, dial 1.
- // to record a new introduction, dial 2.
- // to return to the main menu, dial 3.
- // to hear what this is all about, dial 4.
- }
- 1 => {
- Playback(priv-callerintros/${CALLERID(num)});
- goto s|begin;
- }
- 2 => {
- goto home-introduction-record|s|begin;
- }
- 3 => {
- goto homeline|s|loopback;
- }
- 4 => {
- Playback(intro-intro); // Script:
- // This may seem a little strange, but it really is a neat
- // thing, both for you and for us. I've taped a short introduction
- // for many of the folks who normally call us. Using the Caller ID
- // from each incoming call, the system plays the introduction
- // for that phone number over a speaker, just as the call comes in.
- // This helps the folks
- // here in the house more quickly determine who is calling.
- // and gets the right ones to gravitate to the phone.
- // You can listen to, and record a new intro for your phone number
- // using this menu.
- goto s|begin;
- }
- t => {
- goto s|begin;
- }
- i => {
- Background(invalid);
- goto s|begin;
- }
- o => {
- goto s|begin;
- }
-}
-
-context home-introduction-record {
- s => {
- begin:
- Background(intro-record-choices); // Script:
- // If you want some advice about recording your
- // introduction, dial 1.
- // otherwise, dial 2, and introduce yourself after
- // the beep.
- }
- 1 => {
- Playback(intro-record);
- // Your introduction should be short and sweet and crisp.
- // Your introduction will be limited to 10 seconds.
- // This is NOT meant to be a voice mail message, so
- // please, don't say anything about why you are calling.
- // After we are done making the recording, your introduction
- // will be saved for playback.
- // If you are the only person that would call from this number,
- // please state your name. Otherwise, state your business
- // or residence name instead. For instance, if you are
- // friend of the family, say, Olie McPherson, and both
- // you and your kids might call here a lot, you might
- // say: "This is the distinguished Olie McPherson Residence!"
- // If you are the only person calling, you might say this:
- // "This is the illustrious Kermit McFrog! Pick up the Phone, someone!!"
- // If you are calling from a business, you might pronounce a more sedate introduction,like,
- // "Fritz from McDonalds calling.", or perhaps the more original introduction:
- // "John, from the Park County Morgue. You stab 'em, we slab 'em!".
- // Just one caution: the kids will hear what you record every time
- // you call. So watch your language!
- // I will begin recording after the tone.
- // When you are done, hit the # key. Gather your thoughts and get
- // ready. Remember, the # key will end the recording, and play back
- // your intro. Good Luck, and Thank you!"
- goto 2|begin;
- }
- 2 => {
- begin:
- Background(intro-start);
- // OK, here we go! After the beep, please give your introduction.
- Background(beep);
- Record(priv-callerintros/${CALLERID(num)}:gsm,3);
- Background(priv-callerintros/${CALLERID(num)});
- goto home-introduction|s|begin;
- }
- t => {
- goto s|begin;
- }
- i => {
- Background(invalid);
- goto s|begin;
- }
- o => {
- goto s|begin;
- }
-}
-
-context homeline-kids {
- s => {
- begin:
- Background(murphy-homeline-kids); // Which Kid? 1=Sean, 2:Eric, 3:Ryan, 4:Kyle, 5:Amber, 6:Alex, 7:Neal
- }
- 1 => { // SEAN
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/3/greet.wav&);
- // &std-priv-exten(Zap/3r2&Zap/5r2,3,35,mtw,telemarket,telemarket);
- &std-priv-exten(IAX2/seaniax&Zap/5r2,3,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 2 => { // ERIC
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&);
- Voicemail(u4);
- goto homeline|s|loopback;
-
- // SetMusicOnHold(erics);
- // TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- // TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&);
- // &std-priv-exten(Zap/3r2&Zap/5r2,4,35,mtw,telemarket,telemarket);
- // goto homeline|s|loopback;
- }
- 3 => { // RYAN
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/5/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,5,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 4 => { // KYLE
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/6/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,6,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 5 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/7/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,7,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
-
- }
- 6 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/8/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,8,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 7 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/9/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,9,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- t => {
- goto s|begin;
- }
- i => {
- Background(invalid);
- goto s|begin;
- }
- o => {
- goto s|begin;
- }
-}
-
-context voipworkline {
- s => {
- begin:
- Answer();
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- goto workline|s|loopback;
- }
- 7075679201 => {
- Answer();
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- goto workline|s|loopback;
- }
-}
-
-context workline {
- s => {
- begin:
- Answer();
- Wait(1);
- Set(repeatcount=0);
- Zapateller(nocallerid);
-// PrivacyManager();
-// if( "${PRIVACYMGRSTATUS}" = "FAILED" )
-// {
-// goto privacyManagerFailed|s|begin;
-// }
- &fillcidname();
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- loopback:
- Background(greetings/greeting); //script: Hello
- Background(murphy-office-intro1); //script: welcome to Steve Murphy's office. If you are dialing
- // this number because it was on a calling list of any sort, dial 6.
- // Otherwise, dial 1, and hopefully, you will reach Steve.
- }
- 1 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/1/greet.wav&);
-
- &std-priv-exten(Zap/6&Sip/murf,1,30,mtw,telemarket,telemarket);
- goto s|loopback;
- }
- 4 => {
- VoicemailMain();
- goto s|loopback;
- }
- 6 => {
- goto telemarket|s|begin;
- }
- 793 => { // check the tone recognition
- Read(zz,,0,,1,0);
- SayDigits(${zz});
- }
- t => {
- repeatcount=${repeatcount} + 1;
- if( ${repeatcount} < 3 )
- {
- goto s|loopback; // just loopback isn't enough
- }
- Hangup();
- }
- i => {
- Background(invalid);
- goto s|loopback;
- }
- o => {
- Congestion();
- }
- fax => {
- Answer();
- Dial(Zap/4);
- }
-}
-
-context dialFWD {
- ignorepat => 8;
- ignorepat => 9;
- _83. => {
- Set(CALLERID(name)=${FWDCIDNAME});
- Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
- Congestion();
- }
- _82NXX => {
- Set(CALLERID(name)=${FWDCIDNAME});
- Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
- Congestion();
- }
- _92NXX => {
- Set(CALLERID(name)=${FWDCIDNAME});
- Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
- Congestion();
- }
-}
-
-context dialiaxtel {
- ignorepat => 8;
- ignorepat => 9;
- _81700NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
- _81800NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
- _91700NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
- _91800NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
-
-}
-
-context dialgoiax {
- ignorepat => 9;
- _93. => {
- Set(CALLERID(name)="Joe Worker");
- Dial(IAX2/878201007658:stickyfinger295@server1.goiax.com/${EXTEN:2},60,r);
- Congestion();
- }
-
-}
-
-context homefirst {
- ignorepat => 9;
- _91NXXNXXXXXX => {
- &ciddial(${EXTEN:1},${EXTEN:2},30,TW,Zap/1);
- }
- _9754XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9574XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9202XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9219XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9254XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9716XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9NXXXXXX => {
- &ciddial(1707${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9011. => {
- &ciddial(${EXTEN:1},${EXTEN:1},30,TW,Zap/1);
- }
- _9911 => {
- Dial(Zap/1/911,30,T);
- }
- _9411 => {
- Dial(Zap/1/411,30,T);
- }
-}
-
-context workfirst {
- ignorepat => 9;
- _91NXXNXXXXXX => {
- &ciddial2(${EXTEN:1},${EXTEN:2},30,TW,Zap/1);
- }
- _9754XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9574XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9202XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9219XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9254XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9716XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9NXXXXXX => {
- &ciddial2(1707${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9911 => {
- Dial(Zap/1/911,30,T);
- }
- _9411 => {
- Dial(Zap/1/411,30,T);
- }
-}
-
-context force_cell {
- ignorepat => 8;
- _81NXXNXXXXXX => {
- &ciddial(${EXTEN:1}#,${EXTEN:2},30,TW,Zap/2);
- }
- _8754XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8574XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8202XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8219XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8254XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8716XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8NXXXXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8911 => {
- Dial(Zap/1/911|30|T);
- }
- _8411 => {
- Dial(Zap/1/411|30|T);
- }
-}
-
-context force_home {
- ignorepat => 8;
- _81NXXNXXXXXX => {
- &ciddial3(${EXTEN:1}#,${EXTEN:2},30,TW,Zap/1);
- }
- _8754XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8574XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8202XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8219XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8254XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8716XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8NXXXXXX => {
- &ciddial3(1707${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8911 => {
- Dial(Zap/1/911|30|T);
- }
- _8411 => {
- Dial(Zap/1/411|30|T);
- }
-}
-
-context homeext {
- ignorepat => 8;
- ignorepat => 9;
- includes {
- parkedcalls;
- homefirst;
- force_cell;
- }
- s => {
- loopback:
- Wait(0);
- }
- 1 => {
- &std-priv-exten(Zap/3&Zap/5,2,35,mtw,telemarket,telemarket);
- goto s|loopback;
- }
- 2 => {
- &std-priv-exten(Zap/6&Zap/5,1,35,mpA(beep3)Tt,telemarket,telemarket);
- goto s|loopback;
- }
- 4 => {
- VoicemailMain();
- }
- 5 => {
- Record(recording:gsm);
- Background(recording);
- }
- 6 => {
- Background(recording);
- }
- 760 => {
- DateTime();
- goto s|loopback;
- }
- 761 => {
- Record(announcement:gsm);
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/announcement.gsm&);
- goto s|loopback;
- }
- 762 => {
- agi(tts-riddle.agi);
- Background(gsm/what-time-it-is2);
- SayUnixTime();
- goto s|loopback;
- }
- 763 => {
- Set(CALLERID(num)=);
- Dial(Zap/6r3,35,mptA(beep3)); //results: it should ALWAYS ask for an intro; the intro should not be left behind
- Hangup();
- }
- 764 => {
- Set(CALLERID(num)=);
- Dial(Zap/6r3,35,mptnA(beep3)); //results: Don't save the intro; shouldn't anyway if no callerid
- Hangup();
- }
- 765 => {
- Set(CALLERID(num)=);
- Dial(Zap/6r3,35,mptNA(beep3)); //results: Don't screen if there's CALLERID; it should screen the call.
- Hangup();
- }
- 766 => {
- Dial(Zap/6r3,35,mptNA(beep3)); //results: Don't screen if there's CALLERID; it should screen the call.
- Hangup();
- }
- 767 => {
- Dial(Zap/6r3,35,mptnA(beep3)); //results: Don't save the intro; the interesting case, because callerID should be present.
- Hangup();
- }
- 769 => {
- Playtones(dial);
- Wait(2);
- Playtones(busy);
- Wait(2);
- Playtones(ring);
- Wait(2);
- Playtones(congestion);
- Wait(2);
- Playtones(callwaiting);
- Wait(2);
- Playtones(dialrecall);
- Wait(2);
- Playtones(record);
- Wait(2);
- Playtones(info);
- Wait(5);
- Hangup();
- }
- 790 => {
- MeetMe(790,p);
- }
- 792 => {
- goto pageall|s|begin;
- }
- 795 => {
- AGI(wakeup.agi);Congestion();
- }
- 544716 => { // Incoming call from FWD
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- goto s|loopback;
- }
-
- i => {
- Background(invalid);
- goto s|loopback;
- }
- o => {
- goto s|loopback;
- }
- t => {
- Congestion();
- }
-}
-
-context fromvmhome {
- 1 => {
- Dial(Zap/6&Sip/murf|20|Tt);
- }
- 2 => {
- Dial(Zap/3&Zap/5|20|Tt);
- }
- _707202XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707219XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707254XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707716XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707754XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707574XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _NXXNXXXXXX => {
- &ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
- }
- _1NXXNXXXXXX => { // HAND DIALING
- &ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
- }
- _754XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _574XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _NXXXXXX => {
- &ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _911 => {
- &ciddial(911,911,30,TW,Zap/1);
- }
- _411 => {
- &ciddial(411,411,30,TW,Zap/1);
- }
-}
-
-context fromvmwork {
- 1 => {
- Dial(Zap/6&Sip/murf|20|Tt);
- }
- 2 => {
- Dial(Zap/3&Zap/5|20|Tt);
- }
- _707202XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707219XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707254XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707716XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707754XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707574XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _NXXNXXXXXX => {
- &ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
- }
- _1NXXNXXXXXX => { // HAND DIALING
- &ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
- }
- _754XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _574XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _NXXXXXX => {
- &ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- 911 => {
- &ciddial(911,911,30,TW,Zap/1);
- }
- 411 => {
- &ciddial(411,411,30,TW,Zap/1);
- }
-}
-
-context fromSeanUniden {
- includes
- {
- parkedcalls;
- }
- 21 => {
- Dial(IAX2/seaniax,20,T);
- }
- _707202XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707219XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707254XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707716XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707754XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707574XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _NXXNXXXXXX => {
- &ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
- }
- _1NXXNXXXXXX => {
- &ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
- }
- _754XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _574XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _NXXXXXX => {
- &ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- 911 => {
- &ciddial(911,911,30,TW,Zap/1);
- }
- 411 => {
- &ciddial(411,411,30,TW,Zap/1);
- }
-}
-
-context workext {
- ignorepat => 8;
- ignorepat => 9;
- includes {
- parkedcalls;
- workfirst;
- force_home;
- dialFWD;
- dialiaxtel;
- dialgoiax;
- }
- s => {
- loopback:
- Wait(0);
- }
- 1 => {
- Dial(Zap/3&Zap/5,20,tT);
- }
- 2 => {
- Dial(Zap/5&Zap/6,20,tT);
- }
- 21 => {
- Dial(IAX2/seaniax,20,T);
- }
- 22 => {
- Set(CALLERID(num)=1234567890);
- Set(CALLERID(name)=TestCaller);
- Dial(Zap/5,20,mP()A(beep)tw);
- NoOp(here is dialstatus: ${DIALSTATUS}...);
- goto s|loopback;
- }
- 4 => {
- VoicemailMain();
- goto s|loopback;
- }
- 5 => {
- Record(recording:gsm);
- Background(recording);
- }
- 6 => {
- ZapBarge();
- }
- 760 => {
- DateTime();
- goto s|loopback;
- }
- 761 => {
- ZapBarge();
- goto s|loopback;
- }
- 765 => {
- Playback(demo-echotest);
- Echo();
- Playback(demo-echodone);
- goto s|loopback;
- }
- 766 => {
- Festival(The other thing to watch is neuro-electronics: the ability to interface technology with our neural system: My wife: Sigrid: has had a cochlear implant since 1996. This once profoundly deaf person now uses the phone: recognizes accents: and listens to movies and recorded books.);
- goto s|loopback;
- }
- 767 => {
- agi(tts-riddle.agi);
- Background(gsm/what-time-it-is2);
- SayUnixTime();
- goto s|loopback;
- }
- 768 => {
- agi(tts-computer.agi);
- }
- 771 => {
- eagi(eagi-test);
- agi(my-agi-test);
- }
- 772 => {
- agi(wakeup.agi);
- }
- 775 => {
- if( ${EXTEN}=${EXTEN} )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- if( ${EXTEN}=${LANGUAGE} )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- BackGround(digits/2);
- }
- 776 => {
- Set(TEST=00359889811777);
- if( ${TEST}= 00359889811777 )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- if( ${TEST}= 00359889811888 )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- Hangup();
- }
- 790 => {
- MeetMe(790,p);
- }
- 792 => {
- goto pageall|s|begin;
- }
- 793 => {
- #include "include1.ael2"
- }
- 795 => {
- AGI(wakeup.agi);
- Congestion();
- }
- 797 => {
- Set(CONFCIDNA=${CALLERID(name)});
- Set(CONFCIDNU=${CALLERID(num)});
- AGI(callall);
- AGI(submit-announce.agi);
- Hangup();
- }
-}
-
-context wakeup {
- 3 => {
- Dial(Zap/3|30);
- }
- 4 => {
- Dial(Zap/4|30);
-
- }
- 5 => {
- Dial(Zap/5|30);
-
- }
- 6 => {
- Dial(Zap/6|30);
-
- }
- 99 => {
- Dial(IAX2/murfiaxphone|30);
- }
- 97 => {
- Dial(IAX2/ryaniax|30);
- }
- 94 => {
- Dial(IAX2/seaniax|30);
- }
-}
-
-context announce-all {
- s => {
- begin:
- MeetMe(5555,dtqp);
- MeetMeAdmin(5555,K);
- Hangup();
- }
- h => {
- MeetMeAdmin(5555,K);
- Hangup();
- }
-}
-
-// now include the telemarketer torture scripts!
-
-#include "telemarket_torture.ael2"
-
-
diff --git a/1.4/pbx/ael/ael-test/ael-test3/include1.ael2 b/1.4/pbx/ael/ael-test/ael-test3/include1.ael2
deleted file mode 100644
index 80c562cb2..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/include1.ael2
+++ /dev/null
@@ -1,3 +0,0 @@
- NoOp(Hello, this is included from include1.ael2);
- #include "include2.ael2"
-
diff --git a/1.4/pbx/ael/ael-test/ael-test3/include2.ael2 b/1.4/pbx/ael/ael-test/ael-test3/include2.ael2
deleted file mode 100644
index 8d892fb0c..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/include2.ael2
+++ /dev/null
@@ -1,4 +0,0 @@
- NoOp(This was included from include2.ael2);
- #include "include3.ael2"
- #include "include4.ael2"
-
diff --git a/1.4/pbx/ael/ael-test/ael-test3/include3.ael2 b/1.4/pbx/ael/ael-test/ael-test3/include3.ael2
deleted file mode 100644
index 3c6c1e3dd..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/include3.ael2
+++ /dev/null
@@ -1,2 +0,0 @@
- NoOp(This is include3.ael2!);
- #include "include5.ael2"
diff --git a/1.4/pbx/ael/ael-test/ael-test3/include4.ael2 b/1.4/pbx/ael/ael-test/ael-test3/include4.ael2
deleted file mode 100644
index 7d3703a5e..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/include4.ael2
+++ /dev/null
@@ -1,2 +0,0 @@
- NoOp(This is include4.ael2! Isn't it cool!?!?!?!);
- NoOp(4 doesn't include anything);
diff --git a/1.4/pbx/ael/ael-test/ael-test3/include5.ael2 b/1.4/pbx/ael/ael-test/ael-test3/include5.ael2
deleted file mode 100644
index 0e18983ef..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/include5.ael2
+++ /dev/null
@@ -1 +0,0 @@
- NoOp(Include5.ael2 doesn't include anything, either!);
diff --git a/1.4/pbx/ael/ael-test/ael-test3/telemarket_torture.ael2 b/1.4/pbx/ael/ael-test/ael-test3/telemarket_torture.ael2
deleted file mode 100755
index ebd8e9f2f..000000000
--- a/1.4/pbx/ael/ael-test/ael-test3/telemarket_torture.ael2
+++ /dev/null
@@ -1,812 +0,0 @@
-//
-// AN EXCERSIZE IN BAD DIALPLAN DESIGN
-// (What better testing ground than on telemarketers?)
-//
-
-
-// BAD DESIGN: long, boring introductions followed by long, drawn out menus of choices.
-// if they survive to the last option, how will they remember the choices?
-//
-
-// BAD DESIGN: Amateur Recording. Poor voice quality, too quiet.
-// Also, the announcer is definitely not vocally gifted.
-// Also, the long pauses and clicks between the intro
-// and menu choices might lead some to think that
-// the announcements are over, and hang up. Too bad!
-
-// WORSE DESIGN: Instead of using the Background application, the Playback
-// application is used. After taking so much time and trouble
-// to record this material, the caller must listen and enjoy
-// every syllable before they can make an option choice. None
-// of that interrupting with a choice. We want them to savour
-// every word!
-
-// GOOD/BAD, ER INSIDIOUS -- DANGLE A CARROT-- GIVE THE LISTENER A GOOD REASON TO
-// HANG ON AND VOLUNTARILY LISTEN TO THE TORTURE.
-// BUT, DON'T MAKE PROMISES YOU WON'T KEEP!
-
-
-context telemarket {
- s => {
- begin:
- Playback(telemarketer-intro); // ; Script:
- // Due to the extremely high volume of calls from everything from telemarketers
- // to Septic System Bacteria vendors, we are asking all such organizations
- // to remove this number from their call list, or as need be, to add this
- // number to their No-Call list, whichever is relevent.
-
- // [THE CARROT:]
- // We HAVE made some exceptions, and if you wish to see if your organization
- // has been exempted, please listen to and follow the following prompts.
- //
- // Otherwise, please Cease calling this number!
- //
- Playback(telemarketer-choices);
- // if you represent a charitable organization, please dial 1,
- // if you represent a political organization, please dial 2.
- // if you represent a polling company, please dial 3,
- // if you represent a market research organization, please dial 4.
- // if you represent a magazine or newsletter, please dial 5.
- // if you represent a commercial organization, please dial 6.
- }
- 1 => goto telemarket-charity|s|begin;
- 2 => goto telemarket-political|s|begin;
- 3 => goto telemarket-pollster|s|begin;
- 4 => goto telemarket-research|s|begin;
- 5 => goto telemarket-magazine|s|begin;
- 6 => goto telemarket-commercial|s|begin;
- 7 => goto telemarket-other|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-charity {
- s => {
- begin:
- Playback(telemark-charity-intro);
- // We have contributed generously to many worthy causes in the past, and will
- // continue to do so in the future. But we suspect that such organizatons
- // have sold our name and phone number to each other until we are now hounded
- // day and night by literally hundreds of such organizations.
- // Enough is Enough!
- //
- // If we have contributed to your cause in the past, we may, perhaps, be disposed to
- // do so in the future, at our option,
- // we give no pledges nor make any commitments here.
- // Send us material via the post if you feel this necessary
- // but do not even consider email. Any email or further phone calls from your organization
- // in the future, will be considered an act of aggression, and we will
- // blacklist your organization for the rest of our natural lives.
- //
- // To see if your organization is exempt from these prohibitions, please
- // comply with the following options.
- Playback(telemark-charity-choices);
- // If your organization is disease or genetic defect related, dial 1,
- // If your organization is handicap related, dial 2.
- // If your organization is a police or fireman or other similar support entity, please dial 3.
- // If your organization is a grade school to high school related
- // fund raiser or other type of activity, please dial 4.
- // If your organization is a college or univerity or alumnis organization, please dial 5.
- // If your organization is animal rights or ecology related organization, please dial 6.
- // If your organization is a political action or candidate support related, please dial 7.
- // If your organization is a substance abuse related organization or cause, please dial 8.
- // And any other charity or tax exempt organization should dial 9.
- }
- 1 => goto telemarket-char-disease|s|begin;
- 2 => goto telemarket-char-handicap|s|begin;
- 3 => goto telemarket-char-police|s|begin;
- 4 => goto telemarket-char-school|s|begin;
- 5 => goto telemarket-char-college|s|begin;
- 6 => goto telemarket-char-animal|s|begin;
- 7 => goto telemarket-char-candidate|s|begin;
- 8 => goto telemarket-char-abuse|s|begin;
- 9 => goto telemarket-char-other|s|begin;
-// BAD DESIGN: referring all timeouts,invalid choices, etc, back to the root of the menu tree will frustrate users no end!
-// WORSE DESIGN: How about having the user have to push a button to repeat the current menu? When a time out could just
-// automatically do it for the user?
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-char-disease {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-handicap {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-police {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-school {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-college {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-animal {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-candidate {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-abuse {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-other {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-sorry {
- s => {
- begin:
- Playback(telemarket-sorry);
- // Sorry -- your organization is not exempt. Please stop calling us.
- // Thank you. goodbye.
- Hangup();
- }
-}
-
-
-// BAD DESIGN: Hanging up on your audience, no matter what the outcome, is not a nice thing to do!
-
-context telemarket-exception {
- s => {
- begin:
- Playback(telemarket-success);
- // Congratulations. Your organization IS exempt. Please call us back,
- // but this time, just act like a normal caller. Thank you. Goodbye.
- Hangup();
- }
-}
-
-
-// BAD DESIGN: Making long cascading menu choices is a nasty thing to do to callers!
-// BAD DESIGN: Putting the most frequently encountered items at the end of a list is also a nasty thing to do!
-
-
-// GOOD DESIGN: All rejection notices use a single context. All Acceptance also. To change a rejection to an
-// acceptance, just change the reference from telemarket-sorry to telemarket-exception
-
-
-context telemarket-political {
- s => {
- begin:
- Playback(telemark-polit-intro);
- // To see if your organization is exempt from our prohibitions,
- // please follow the following prompts.
- // please note that they are not in alphabetical order, and you will have to
- // give them your full attention.
- Playback(telemark-polit-choices);
- // if You represent the America First Party, dial 1.
- // if You represent the American Party, dial 2.
- // if You represent the American Heritage Party, dial 3.
- // if You represent the American Independent Party, dial 4.
- // if You represent the American Nazi Party, dial 5.
- // if You represent the Pot Party, dial 6.
- // if You represent the American Reform Party, dial 7.
- // if You represent the Christian Falenqist Party of America, dial 8.
- // all others, please dial 9.
- }
- 1 => goto telemarket-poli-Am1st|s|begin;
- 2 => goto telemarket-poli-American|s|begin;
- 3 => goto telemarket-poli-AmHer|s|begin;
- 4 => goto telemarket-poli-AmInd|s|begin;
- 5 => goto telemarket-poli-AmNaz|s|begin;
- 6 => goto telemarket-poli-Pot|s|begin;
- 7 => goto telemarket-poli-AmRef|s|begin;
- 8 => goto telemarket-poli-CFP|s|begin;
- 9 => goto telemarket-political2|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-political2 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- // Thank you for your patience, and I congratulate you for your persistence.
- // Just a few more options!
- //
- Playback(telemark-polit2-choices);
- // if You represent the Communist Party USA, dial 1.
- // if You represent the Constitution Party, dial 2.
- // if You represent the Family Values Party, dial 3.
- // if You represent the Freedom Socialist Party, dial 4.
- // if You represent the Grass Roots Party, dial 5.
- // if You represent the Green Party, dial 6.
- // if You represent the Greens Party, dial 7.
- // if You represent the Independence Party, dial 8.
- // all others, goto 9.
- }
- 1 => goto telemarket-poli-Communist|s|begin;
- 2 => goto telemarket-poli-Constit|s|begin;
- 3 => goto telemarket-poli-FamVal|s|begin;
- 4 => goto telemarket-poli-FreedSoc|s|begin;
- 5 => goto telemarket-poli-Grassroot|s|begin;
- 6 => goto telemarket-poli-Green|s|begin;
- 7 => goto telemarket-poli-Greens|s|begin;
- 8 => goto telemarket-poli-Independence|s|begin;
- 9 => goto telemarket-political3|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-political3 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- Playback(telemark-polit3-choices);
- // if You represent the Independant American Party, dial 1.
- // if You represent the Labor Party, dial 2.
- // if You represent the Libertarian Party, dial 3.
- // if You represent the Light Party, dial 4.
- // if You represent the Natural Law Party, dial 5.
- // if You represent the New Party, dial 6.
- // if You represent the New Union Party, dial 7.
- // if You represent the Peace and Freedom Party, dial 8.
- // all others, hang on, dial 9.
- }
- 1 => goto telemarket-poli-IndAm|s|begin;
- 2 => goto telemarket-poli-Labor|s|begin;
- 3 => goto telemarket-poli-Liber|s|begin;
- 4 => goto telemarket-poli-Light|s|begin;
- 5 => goto telemarket-poli-NatLaw|s|begin;
- 6 => goto telemarket-poli-New|s|begin;
- 7 => goto telemarket-poli-NewUn|s|begin;
- 8 => goto telemarket-poli-PeaceFree|s|begin;
- 9 => goto telemarket-political4|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-political4 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- Playback(telemark-polit4-choices);
- // if You represent the Prohibition Party, dial 1.
- // if You represent the Reform Party, dial 2.
- // if You represent the Revolution , dial 3.
- // if You represent the Socialist Party USA, dial 4.
- // if You represent the Socialist Action Party, dial 5.
- // if You represent the Socialist Equality Party, dial 6.
- // if You represent the Socialist Labor Party, dial 7.
- // if You represent the Socialist Workers Party, dial 8.
- // all others, hang on, and dial 9.
- }
- 1 => goto telemarket-poli-Prohib|s|begin;
- 2 => goto telemarket-poli-Ref|s|begin;
- 3 => goto telemarket-poli-Revol|s|begin;
- 4 => goto telemarket-poli-SocPart|s|begin;
- 5 => goto telemarket-poli-SocAct|s|begin;
- 6 => goto telemarket-poli-SocEq|s|begin;
- 7 => goto telemarket-poli-SocLab|s|begin;
- 8 => goto telemarket-poli-SocWork|s|begin;
- 9 => goto telemarket-political5|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-political5 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- Playback(telemark-polit5-choices);
- // if You represent the Southern Party, dial 1.
- // if You represent the Southern Independence Party, dial 2.
- // if You represent the US Pacifist Party, dial 3.
- // if You represent the We the People Party, dial 4.
- // if You represent the Workers World Party, dial 5.
- // if You represent the Democratic Party, dial 6.
- // if You represent the Republican Party, dial 7.
- // all others, may dial 8.
- }
- 1 => goto telemarket-poli-South|s|begin;
- 2 => goto telemarket-poli-SoInd|s|begin;
- 3 => goto telemarket-poli-USPac|s|begin;
- 4 => goto telemarket-poli-WTP|s|begin;
- 5 => goto telemarket-poli-WWP|s|begin;
- 6 => goto telemarket-poli-Democrat|s|begin;
- 7 => goto telemarket-poli-Repub|s|begin;
- 8 => goto telemarket-poli-other|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-poli-other {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Repub {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Democrat {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-WWP {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-WTP {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-USPac {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SoInd {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-South {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocWork {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocLab {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocEq {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocAct {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocPart {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Revol {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Ref {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Prohib {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-PeaceFree {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-NewUn {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-New {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-NatLaw {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Light {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Liber {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Labor {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-IndAm {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Independence {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Greens {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Green {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Grassroot {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-FreedSoc {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-FamVal {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Constit {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Communist {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-CFP {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-AmRef {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-// BAD DESIGN: Putting in infinite loops in the menus, whether by design or mistake is not nice!
-context telemarket-poli-Pot {
- s => {
- begin:
- goto telemarket-political|s|begin; // will the Pot Party Guys even notice an infinite loop?
- }
-}
-
-context telemarket-poli-AmNaz {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-AmInd {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-AmHer {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-American {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Am1st {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-
-context telemarket-pollster {
- s => {
- begin:
- Playback(telemark-poll-intro);
- // I'm sorry-- We are just not available for doing any polling at the moment. So,
- // please remove us from your list.
- goto telemarket-sorry|s|begin;
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-research {
- s => {
- begin:
- Playback(telemark-research-intro);
- // I'd like to say I'd love to help you with your market survey, but that would be a complete
- // and total lie. I am not interested in helping you with Market Surveys.
- //
- // Please remove me from your call list. It just doesn't pay enough. But Thank you.
- goto telemarket-sorry|s|begin;
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-magazine {
- s => {
- begin:
- Playback(telemark-mag-choices);
- // If you are calling to see if I would like a NEW free subscription
- // to your magazine or newsletter, please dial 1.
- // If you are calling to see if I want to Renew an existing subscription, please dial 2.
- // If you are representing some publisher, and want my opinion about something, or are doing
- // some kind of survey, please dial 3.
- // If you are calling to verify that some previous caller actually called me, and the
- // verification information is correct, please dial 4.
- // and if your call purpose doesn't match any of the above, please dial 5.
- }
- 1 => goto telemark-mag-new|s|begin;
- 2 => goto telemark-mag-renew|s|begin;
- 3 => goto telemark-mag-survey|s|begin;
- 4 => goto telemark-mag-verify|s|begin;
- 5 => goto telemark-mag-other|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-new {
- s => {
- begin:
- Playback(telemark-mag-new);
- // I'm sorry, I'm maxed out, and the answer is NO.
- // If you really think I'd LOVE to add your publication to the pile I already get,
- // Send something via the post. Don't call me.
- // Thank you. bye.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-renew {
- s => {
- begin:
- Playback(telemark-mag-renew);
- // So, you want to see if I want to Renew, do you? The answer is most likely "YES".
- //
- // But, I will not answer a long list of questions over the phone. Send such
- // categorization info via the post, and stop bothering me over the phone,
- // if this is what you want.
- // Do you need verification information? Normally I opt out of such nonsense, if possible.
- // If not, use whatever of the following you can:
- // My birth month is October.
- // My birthplace is Kigali, in Rwanda, in Afica.
- // My eye color is orange.
- // All of these are wonderfully false, but I use them regularly for such purposes. Thank you.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-survey {
- s => {
- begin:
- Playback(telemark-mag-survey);
- // Sorry, I don't have time to answer survey or opinion questions. Find someone
- // else to help build your marketing database, I guess. Good Luck.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-verify {
- s => {
- begin:
- Playback(telemark-mag-verify);
- // If you are calling to verify that your own agents aren't ripping you off,
- // sorry, I can't help you. I opt out whenever I can, mainly because I'm not
- // paid enough for this kind of thing. I always lie, and I can't remember
- // what I might have said. Sorry. Goodbye.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-other {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-
-
-// BAD DESIGN: Is it entrapment, when you lure telemarketers to reveal their contact information,
-// Just so you can report them to the FTC/FCC? If it is, isn't it unethical for them
-// to hide their CID (via Anonymous, usually), to hide their identities from the public?
-
-// BTW -- What telemarketer would be stupid enough to fall for this? I'll bet not a single one!
-// For that matter, what telemarketer will be stupid enough to even enter any of this? I'll bet not a single one!
-// (but it was fun messing around).
-
-context telemarket-commercial {
- s => {
- begin:
- Playback(telemark-comm-intro); // Script: Please leave your name, organization, and phone number, plus
- // a short description of the purpose of your call, at the prompt.
- // We will do our best to respond to your call! And, in the mean time,
- // do not forget to add us to your no-call list!
- Voicemail(u82);
- goto telemarket-sorry|s|begin;
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-other {
- s => {
- begin:
- Playback(telemark-other-intro);
- // Please review the previous menu options, and see if you really don't
- // fit in one of the previous categories.
- // If you do not, go ahead, and call me again, and let me know what category
- // I should have included in the above list. I appreciate this. Thank you much!
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
diff --git a/1.4/pbx/ael/ael-test/ael-test4/apptest.ael2 b/1.4/pbx/ael/ael-test/ael-test4/apptest.ael2
deleted file mode 100644
index c477d8531..000000000
--- a/1.4/pbx/ael/ael-test/ael-test4/apptest.ael2
+++ /dev/null
@@ -1,146 +0,0 @@
-// this is a quick test to see how many of the apps we can spot j options in
-// include this in a macro or extension
-// at this moment, there are 18 apps that accept the j option.
-
- AddQueueMember(zork,iface,20,j);
- ADSIProg(sfile);
- AgentCallbackLogin(agent,s,30@cont);
- AgentLogin(agent,s);
- AgentMonitorOutgoing(dcn);
- AGI(whatever);
- AlarmReceiver();
- Answer(2);
- AppendCDRUserField(value);
- Authenticate(pword,adjmr);
- BackGround(filename,snm,eng);
- BackgroundDetect(filename,20,2,10);
- Busy(10);
- ChangeMonitor(fnamebase);
- ChanIsAvail(Zap/5,sj);
- ChanSpy(prefix,bg()qrv);
- Congestion(5);
- ControlPlayback(filename,10,6,4,0,5,7,j);
- DateTime(unixtime,tz,fmt);
- DBdel(fam/key);
- DBdeltree(fam);
- DeadAGI(command);
- Dial(zap/1,45,A()CdD()fgG()hHjL()m()M()nNoprS()tTwW);
- Dictate(basedir);
- Directory(cont,dcont,f);
- DISA(68986869876,context);
- DumpChan(verblev);
- DUNDiLookup(90709780978,context,bj);
- EAGI(command);
- Echo();
- EndWhile();
- Exec(appname,args);
- ExecIf(expr,app,data);
- ExecIfTime(*,*,*,*,appname);
- ExternalIVR(command,arg1);
- Festival(text);
- Flash();
- ForkCDR(v);
- GetCPEID();
- Gosub(cont,exten,priority);
- GosubIf(cond?label);
- Goto(cont,exten,prior);
- GotoIf(cond?t:f);
- GotoIfTime(*,*,*,*?cont,ext,prior);
- Hangup();
- HasNewVoicemail(vmbox,var,j);
- HasVoicemail(vmbox,var,j);
- IAX2Provision(template);
- ICES(xmlconfig);
- ImportVar(nevar@chann,var);
- Log(NOTICE,message);
- LookupBlacklist(j);
- LookupCIDName();
- Macro(macro,arg1);
- MacroExit();
- MacroIf(expr?etc);
- MailboxExists(mbox@cont,j);
- Math(v,2+2);
- MeetMe(5555,aAbcdDeimMpPqrstTovwxX);
- MeetMeAdmin(5555,e,user);
- MeetMeCount(5555,var);
- Milliwatt();
- MixMonitor(filename,abv()V()W(),command);
- Monitor(file.fmt,base,mb);
- MP3Player(location);
- MusicOnHold(class);
- NBScat();
- NoCDR();
- NoOp(ignored);
- Page(Zap/1,dq);
- Park(exten);
- ParkAndAnnounce(template,5,238,retcont);
- ParkedCall(exten);
- PauseQueueMember(queue,zap,j);
- Pickup(ext@cont);
- Playback(file,j);
- PlayTones(arg);
- PrivacyManager(3,4,j);
- Progress();
- Queue(queuename,dhHnrtTwW,http://www.where.what,over,5);
- Random(30,cont,ext,pri);
- Read(var,fname,10,skip,2,5);
- ReadFile(var=file,10);
- RealTime(fam,2,val,prefix);
- RealTimeUpdate(fam,2,val,2,newval);
- Record(file,2,10,anqst);
- RemoveQueueMember(queuename,iface,j);
- ResetCDR(wav);
- RetryDial(annound,4,2);
- Return();
- Ringing();
- RxFAX(fname,caller);
- SayAlpha(string);
- SayDigits(string);
- SayNumber(digits);
- SayPhonetic(string);
- SayUnixTime(unixtime,tz,fmt);
- SendDTMF(digits,10);
- SendImage(filename);
- SendText(text,j);
- SendURL(URL);
- Set(a=b);
- SetAMAFlags();
- SetCallerID(clid,a);
- SetCallerPres(allowed_passed_screen);
- SetCDRUserField(value);
- SetGlobalVar(var=val);
- SetMusicOnHold(class);
- SetTransferCapability(SPEECH);
- SIPAddHeader(header);
- SIPDtmfMode(inband,info,rfc);
- SIPGetHeader(var@headername);
- SMS(name);
- SoftHangup(zap/1,a);
- StackPop();
- StartMusicOnHold(class);
- StopMonitor();
- StopMusicOnHold();
- StopPlayTones();
- System(command);
- TestClient(testid);
- TestServer();
- Transfer(zap/1,j);
- TrySystem(command);
- TxFAX(filename,caller,debug);
- UnpauseQueueMember(queuename,iface,j);
- UserEvent(eventanme,body);
- Verbose(5,message);
- VMAuthenticate(mailbox@cont,s);
- VoiceMail(mailbox@cont,bg()suj);
- VoiceMailMain(mailbox@cont,pg()s);
- Wait(2);
- WaitExten(3,m());
- WaitForRing(2);
- WaitForSilence(2,y);
- WaitMusicOnHold(2);
- While(expr);
- Zapateller(answer,5);
- ZapBarge(channel);
- ZapRAS(arg);
- ZapScan(group);
- ZapSendKeypadFacility();
diff --git a/1.4/pbx/ael/ael-test/ael-test4/extensions.ael b/1.4/pbx/ael/ael-test/ael-test4/extensions.ael
deleted file mode 100644
index 838aa2489..000000000
--- a/1.4/pbx/ael/ael-test/ael-test4/extensions.ael
+++ /dev/null
@@ -1,8 +0,0 @@
-context test1
-{
- test2 =>
- {
- #include "apptest.ael2";
- }
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-test5/extensions.ael b/1.4/pbx/ael/ael-test/ael-test5/extensions.ael
deleted file mode 100644
index 304275a00..000000000
--- a/1.4/pbx/ael/ael-test/ael-test5/extensions.ael
+++ /dev/null
@@ -1,833 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Helpdesk Queue
-
-context hd-queue {
- s => {
- NoOp(Add a background sound to tell the user their options);
- Queue(helpdesk|t);
- NoOp(Put in options to apologize and send user to voicemail);
- };
-
- 0 => goto default|0|1;
- 1 => {
- Dial(u41950@svm1.shsu.edu);
- Congestion(10);
- Hangup;
- };
-};
-
-
-context l903-calling {
- _9903NXXXXXX => {
- Realtime(l903_ext,exchange,${EXTEN:4:3},l903_);
- if ("${l903_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-};
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from houston.conf
-// Converted the extension list to the database
-
-context houston-calling {
- _9713NXXXXXX => {
- Realtime(hou_713_ext,exchange,${EXTEN:4:3},hou_713_);
- if ("${hou_713_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-
- _9281NXXXXXX => {
- Realtime(hou_281_ext,exchange,${EXTEN:4:3},hou_281_);
- if ("${hou_281_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-
- _9832NXXXXXX => {
- Realtime(hou_832_ext,exchange,${EXTEN:4:3},hou_832_);
- if ("${hou_832_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from huntsville.conf
-// Converted the extension list to the database
-
-context huntsville-calling {
- _9NXXXXXX => {
- Realtime(hv_ext,exchange,${EXTEN:1:3},hv_);
- if ("${hv_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-
- _NXXXXXX => {
- NoOp(Stripping last four to see what extension we're dialing);
- Set(LAST4=${EXTEN:3});
- StripLSD(4);
- };
-
- i => Playback(pbx-invalid);
- h => Hangup;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from macros.conf
-
-macro dialout( number ) {
- Realtime(call_info,exten,${CALLERIDNUM:5},mon_);
- if ("${mon_monitor}" = "YES") {
- Dial(SIP/${number}@sgw1.shsu.edu,,wW);
- Dial(SIP/${number}@sgw2.shsu.edu,,wW);
- } else {
- Dial(SIP/${number}@sgw1.shsu.edu);
- Dial(SIP/${number}@sgw2.shsu.edu);
- };
-};
-
-// Standard extension macro:
-// ${ext} - Extension
-macro stdexten( ext ) {
- Realtime(sipusers,name,${ext},sip_user_);
- Realtime(call_info,exten|${ext},info_);
- if ("${sip_user_name}foo" = "foo") {
- Wait(1);
- &dialout(${ext});
- Congestion(10);
- Hangup;
- };
- NoOp(${CALLERIDNUM});
- RealtimeUpdate(call_info,exten,${ext},calltrace,${CALLERIDNUM});
- System(/usr/local/bin/db_update.sh call_info calltrace ${CALLERIDNUM} exten ${ext} &);
- &checkdnd(${ext});
- &checkcf(${ext});
- Realtime(call_info,exten,${CALLERIDNUM:5},mon_);
- if ("${mon_monitor}" = "YES") {
- Dial(SIP/${info_forwardto},25,wW);
- } else {
- Dial(SIP/${info_forwardto},25);
- };
- switch ("${DIALSTATUS}") {
- case "BUSY":
- &checkcfb(${ext});
- break;
- case "CHANUNAVAIL":
- Dial(IAX2/asterisk:password@scm2.shsu.edu/${info_forwardto},25,wW);
- MailboxExists(${ext});
-// if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
-// Congestion(10);
-// Hangup;
-// };
- &uvm(${ext});
- Hangup;
- break;
- case "CONGESTION":
- MailboxExists(${ext});
- if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
- Congestion(10);
- Hangup;
- };
- &bvm(${ext});
- Hangup;
- break;
- default:
- MailboxExists(${ext});
- if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
- Congestion(10);
- Hangup;
- };
- &uvm(${ext});
- Hangup;
- };
- Hangup;
-};
-
-macro uvm( ext ) {
- Dial(SIP/u${ext}@svm1.shsu.edu);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Congestion(10);
- Hangup;
-};
-
-macro bvm( ext ) {
- Dial(SIP/b${ext}@svm1.shsu.edu);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Congestion(10);
- Hangup;
-};
-
-macro checkdnd( ext ) {
- if ("${info_donotdisturb}foo" = "foo") {
- NoOp(Do Not Disturb is not active);
- } else
- &uvm(${ext});
-};
-
-macro checkcf( ext ) {
- if ("${info_forwardto}foo" = "foo")
- if ("${ext}" = "43974") {
- Set(info_forwardto=${ext}&SCCP/${ext});
- } else {
- Set(info_forwardto=${ext}&SIP/${ext}w);
- };
-};
-
-macro checkcfb( ext ) {
- if ("${info_forwardbusy}foo" = "foo") {
- Wait(1);
- MailboxExists(${ext});
- if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
- &dialout(${ext});
- Hangup;
- };
- &bvm(${ext});
- Hangup;
- };
- &stdexten(${info_forwardbusy});
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from test.conf
-
-context test-include {
- includes {
- test-digium;
- test-sounds;
- test-phinfo;
- };
-};
-
-context test-digium {
- *500 => {
- Dial(IAX2/guest@misery.digium.com/s@default);
- Playback(demo-nogo);
- Hangup;
- };
-};
-
-context test-sounds {
- *501 => {
- Answer;
- Musiconhold;
- Wait(1);
- Hangup;
- };
-};
-
-context test-phinfo {
- *505 => {
- Answer;
- NoOp(${CALLERIDNUM:5});
- SayDigits(${CALLERIDNUM:5});
- Hangup;
- };
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from external.conf
-
-context long-distance {
- includes {
- local;
- };
-
- _91XXXXXXXXXX => &dialout(${EXTEN});
- _9011. => &dialout(${EXTEN});
-};
-
-context local {
- includes {
- default;
- };
-
- 911 => &dialout(911);
- 9911 => &dialout(9911);
-
- _9NXXXXXX => goto huntsville-calling|${EXTEN}|1;
- _936NXXXXXX => {
- goto 9${EXTEN:3}|1;
- Congestion(10);
- Hangup;
- };
-
- _832NXXXXXX => {
- goto 9${EXTEN}|1;
- Congestion(10);
- Hangup;
- };
-
- _713NXXXXXX => {
- goto 9${EXTEN}|1 ;
- Congestion(10);
- Hangup;
- };
-
- _281NXXXXXX => {
- goto 9${EXTEN}|1;
- Congestion(10);
- Hangup;
-
- };
-
- _NXXNXXXXXX => {
- goto 9${EXTEN}|1;
- goto 91${EXTEN}|1;
- Congestion(10);
- Hangup;
- };
-
- _91800NXXXXXX => &dialout(${EXTEN});
- _91866NXXXXXX => &dialout(${EXTEN});
- _91877NXXXXXX => &dialout(${EXTEN});
- _91888NXXXXXX => &dialout(${EXTEN});
- _91900NXXXXXX => &dialout(${EXTEN});
- _91976NXXXXXX => &dialout(${EXTEN});
- _9713NXXXXXX => goto houston-calling|${EXTEN}|1;
- _9281NXXXXXX => goto houston-calling|${EXTEN}|1;
- _9832NXXXXXX => goto houston-calling|${EXTEN}|1;
- _9903NXXXXXX => goto l903-calling|${EXTEN}|1;
-
- _31NXXNXXXXXX => &dialout(${EXTEN});
-
- h => Hangup;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from internal.conf
-
-context from-scm2 {
- _4XXXX => {
- NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
- Dial(SIP/${EXTEN},20,wW);
- Hangup;
- };
-
- _6XXXX => {
- NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
- Dial(SIP/${EXTEN},20,wW);
- Hangup;
- };
-};
-
-///////////////////////////////////////////////////////////
-// All internal extensions work through the default context
-// Phones that can only make internal calls should be in
-// this context.
-///////////////////////////////////////////////////////////
-
-context default {
-// Include the contexts in the files that allow us to make these phone calls
- includes {
- vm-include;
- apps-include;
- test-include;
- };
-
-// ALWAYS have an 'h' extension
- h => {
- NoOp(Hangup cause was: ${HANGUPCAUSE});
- Hangup;
- };
-
-// We like to hear that we dialed an invalid extension
- i => Playback(pbx-invalid);
-
-// Dial the operator
- 0 => &dialout(0);
-
-// Send voicemail calls to the vm-* contexts to be handled
- voicemail => goto vm-direct|s|1;
- 5555 => goto vm-direct|s|1;
- 62100 => goto vm-extension|s|1;
-
-// These are our campus extensions, send them to the macro
- _6XXXX => &stdexten(${EXTEN});
- _4XXXX => &stdexten(${EXTEN});
-// These are campus extensions as well, might need to take this out though.
- _9294XXXX => goto _4XXXX|1;
- _9496XXXX => goto _6XXXX|1;
-
-// These allows us to dial from the directory in our phone without worrying about dialing 9
- _936294XXXX => {
- goto ${EXTEN:5}|1;
- goto 9${EXTEN:3}|1;
- Congestion(10);
- Hangup;
- };
-
- _936496XXXX => {
- goto ${EXTEN:5}|1;
- goto 9${EXTEN:3}|1;
- Congestion(10);
- Hangup;
- };
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from apps.conf
-
-context apps-include {
- includes {
- app-agents;
- app-dnd;
- app-callforward;
- app-calltrace;
- app-conferences;
- app-ssd;
- app-psd;
- app-idblock;
- app-helpdesk;
- app-dictate;
- app-set-monitor;
- };
-};
-
-context app-agents {
- *54 => {
- Answer;
- Wait(1);
- Read(agent_no|agent-user);
- AgentCallbackLogin(${agent_no}|s${CALLERIDNUM:5});
- Playback(agent-loginok);
- Hangup;
- };
-
- *55 => {
- Answer;
- Wait(1);
- AgentCallbackLogin(${agent_no});
- Hangup;
- };
-};
-
-context app-calltrace {
-// caller dials this to find out the last call missed and possibly call back
- *69 => goto app-calltrace-perform|s|1;
-};
-
-context app-calltrace-perform {
- s => {
- Answer;
- Wait(1);
- Background(info-about-last-call);
- Background(telephone-number);
- RealTime(call_info|exten|${CALLERIDNUM:5}|ct_);
- if ("${ct_calltrace}foo" = "foo") {
- Playback(loligo/from-unknown-caller);
- Hangup;
- } else {
- SayDigits("${ct_calltrace}");
- Set(TIMEOUT(digit)=3);
- Set(TIMEOUT(response)=7);
- Background(loligo/to-call-this-number);
- Background(press-1);
- Background(loligo/silence/5);
- };
- };
-
- 1 => goto local|${ct_calltrace}|1;
-
- i => {
- Playback(vm-goodbye);
- Hangup;
- };
-
- t => {
- Playback(vm-goodbye);
- Hangup;
- };
-};
-
-context app-set-monitor {
- *50 => {
- Realtime(call_info,exten,${CALLERIDNUM:5},mon_set_);
- if ("${mon_set_monitor}" = "YES") {
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor|);
- System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
- } else {
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor,YES);
- System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
- };
- NoOp(${mon_set_monitor});
- Hangup;
- };
-};
-
-context app-dnd {
- *78 => {
- Answer;
- Wait(1);
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},donotdisturb,YES);
- System(/usr/local/bin/db_update.sh call_info donotdisturb YES exten ${CALLERIDNUM:5} &);
- Playback(do-not-disturb);
- Playback(loligo/activated);
- Hangup;
- };
-
- *79 => {
- Answer;
- Wait(1);
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},donotdisturb|);
- System(/usr/local/bin/db_update.sh call_info donotdisturb '' exten ${CALLERIDNUM:5} &);
- Playback(do-not-disturb);
- Playback(loligo/de-activated);
- Hangup;
- };
-};
-
-context app-callforward {
- // forwards calling extension to input number *72{EXTEN}
- _*72. => {
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardto,${EXTEN:3});
- System(/usr/local/bin/db_update.sh call_info forwardto ${EXTEN:3} exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-unconditional);
- Playback(loligo/for);
- Playback(loligo/extension);
- SayDigits(${CALLERIDNUM:5});
- Playback(loligo/is-set-to);
- SayDigits(${EXTEN:3});
- Hangup;
- };
-
- // prompts for extension to forward to
- *72 => {
- Answer;
- Wait(1);
- Playback(please-enter-your);
- Playback(extension);
- Background(then-press-pound);
- VMAuthenticate(|s);
- Background(loligo/ent-target-attendant);
- Read(toext,loligo/then-press-pound);
- Wait(1);
- RealtimeUpdate(call_info,exten,${AUTH_MAILBOX},forwardto,${toext});
- System(/usr/local/bin/db_update.sh call_info forwardto ${toext} exten ${AUTH_MAILBOX} &);
- Playback(loligo/call-fwd-unconditional);
- Playback(loligo/for);
- Playback(loligo/extension);
- SayDigits(${AUTH_MAILBOX});
- Playback(loligo/is-set-to);
- SayDigits(${toext});
- Hangup;
- };
-
- // cancels dialed extension call forward
- _*73. => {
- Realtime(voicemail,mailbox,${EXTEN:3},auth_);
- Answer;
- Wait(1);
- Authenticate(${auth_password});
- RealtimeUpdate(call_info,exten,${EXTEN:3},forwardto,);
- System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${EXTEN:3} &);
- Wait(1);
- SayDigits(${EXTEN:3});
- Playback(loligo/call-fwd-cancelled);
- Hangup;
- };
-
- // cancels call forward for calling extension
- *73 => {
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardto,);
- System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-cancelled);
- Hangup;
- };
-
- // dialed call forward on busy
- _*90. => {
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardbusy,${EXTEN:3});
- System(/usr/local/bin/db_update.sh call_info forwardbusy ${EXTEN:3} exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-on-busy);
- Playback(loligo/for);
- Playback(loligo/extension);
- SayDigits(${CALLERIDNUM:5});
- Playback(loligo/is-set-to);
- SayDigits(${EXTEN:3});
- Hangup;
- };
-
- // cancels call forward on busy for calling extension
- *91 => {
- RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardbusy|);
- System(/usr/local/bin/db_update.sh call_info forwardbusy '' exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-on-busy);
- Playback(loligo/de-activated);
- Hangup;
- };
-
- h => Hangup;
-};
-
-context app-idblock {
- _*67. => {
- Set(CALLERID(name)=Anonymous);
- &stdexten(${EXTEN:3});
- };
-};
-
-context app-dictate {
- *1 => {
- Dictate();
- Hangup;
- };
-};
-
-context app-ssd {
-// *59 <xx> <y.> - Set system speed dial <xx> to digits <y.>
-// *59 <xx> 0 - Delete system speed dial <xx>
-// *59 <xx> - Review system speed dial <xx>
-// *1xx - Dial speed dial <xx>
- _*59XXX. => {
- Answer;
- RealtimeUpdate(ssd,sd,${EXTEN:3:2},extension,${EXTEN:5});
- System(/usr/local/bin/db_update.sh systemsd extension ${EXTEN:5} sd ${EXTEN:3:2} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-set-to);
- SayDigits(${EXTEN:5});
- Hangup;
- };
-
- _*59XX0 => {
- Answer;
- RealtimeUpdate(ssd,sd,${EXTEN:3:2},extension,);
- System(/usr/local/bin/db_update.sh systemsd extension '' sd ${EXTEN:3:2} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-cleared);
- Hangup;
- };
-
- _*59XX => {
- Answer;
- Realtime(ssd,sd,${EXTEN:3},ssd_);
- if ("${ssd_extension}foo" = "foo") {
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-set-to);
- SayDigits(${ssd_extension});
- Hangup;
- };
-
- // NTC = number to call
- _*1XX => {
- Realtime(ssd,sd,${EXTEN:2},ssd_);
- if ("${ssd_extension}foo" = "foo") {
- Answer;
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- &stdexten(${ssd_extension});
- Congestion(10);
- Hangup;
- };
-};
-
-macro check-psd-exists ( ext ) {
- Realtime(psd,extension,${ext},psd_);
- if ("${psd_extension}foo" = "foo") {
- System(/usr/local/bin/create_psd.sh ${ext});
- } else
- NoOp(PSD set for ${ext});
-};
-
-context app-psd {
-// *89 <xx> <y.> - Set personal speed dial <xx> to digits <y.>
-// *89 <xx> 0 - Delete personal speed dial <xx>
-// *89 <xx> - Review personal speed dial <xx>
-// *2xx - Dial personal speed dial <xx>
- _*89XXX. => {
- &check-psd-exists(${CALLERIDNUM:5});
- Answer;
- RealtimeUpdate(psd,extension,${CALLERIDNUM:5},s${EXTEN:3:2},${EXTEN:5});
- System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} ${EXTEN:5} extension ${CALLERIDNUM:5} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-set-to);
- SayDigits(${EXTEN:5});
- Hangup;
- };
-
- _*89XX0 => {
- &check-psd-exists(${CALLERIDNUM:5});
- Answer;
- RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|);
- System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} '' extension ${CALLERIDNUM:5} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-cleared);
- Hangup;
- };
-
- _*89XX => {
- &check-psd-exists(${CALLERIDNUM:5});
- Answer;
- Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
- Wait(1);
- if ("${psd_s${EXTEN:3:2}}foo" = "foo") {
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-set-to);
- SayDigits(${psd_s${EXTEN:3:2}});
- Hangup;
- };
-
- // NTC = number to call
- _*2XX => {
- &check-psd-exists(${CALLERIDNUM:5});
- Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
- if ("${psd_s${EXTEN:2}}foo" = "foo") {
- Answer;
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- &stdexten(${psd_s${EXTEN:2}});
- Congestion(10);
- Hangup;
- };
-};
-
-context app-helpdesk {
- *4357 => {
- &stdexten(41950);
- Congestion;
- };
-};
-
-context app-conferences {
-// waiting for room number announcement
- *86 => goto app-conf-hidden|s|1;
-};
-
-context app-conf-hidden {
- s => {
- Wait(1);
- Playback(loligo/please-enter-the);
- Playback(loligo/extension);
- read(roomtoenter,loligo/then-press-pound);
- Meetme(${roomtoenter});
- Waitexten(8);
- Hangup;
- };
-
- _1. => Meetme(${EXTEN});
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from vm.conf:
-
-context vm-include {
- includes {
- vm-direct;
- vm-extension;
- vm-directory;
- };
-};
-
-context vm-direct {
- s => {
- Dial(SIP/5555@svm1.shsu.edu,20);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Playback(extra/pls-try-call-later);
- Congestion(10);
- Hangup;
- };
-};
-
-context vm-extension {
- s => {
- Dial(SIP/62100@svm1.shsu.edu,20);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Playback(extra/pls-try-call-later);
- Congestion(10);
- Hangup;
- };
-};
-
-context vm-directory {
- 5556 => {
- Dial(SIP/5556@svm1.shsu.edu);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Playback(extra/pls-try-call-later);
- Congestion(10);
- Hangup;
- };
-};
diff --git a/1.4/pbx/ael/ael-test/ael-test6/extensions.ael b/1.4/pbx/ael/ael-test/ael-test6/extensions.ael
deleted file mode 100644
index 890c7111c..000000000
--- a/1.4/pbx/ael/ael-test/ael-test6/extensions.ael
+++ /dev/null
@@ -1,833 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Helpdesk Queue
-
-context hd-queue {
- s => {
- NoOp(Add a background sound to tell the user their options);
- Queue(helpdesk|t);
- NoOp(Put in options to apologize and send user to voicemail);
- };
-
- 0 => goto default|0|1;
- 1 => {
- Dial(u41950@svm1.shsu.edu);
- Congestion(10);
- Hangup;
- };
-};
-
-
-context l903-calling {
- _9903NXXXXXX => {
- Realtime(l903_ext|exchange|${EXTEN:4:3}|l903_);
- if ("${l903_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-};
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from houston.conf
-// Converted the extension list to the database
-
-context houston-calling {
- _9713NXXXXXX => {
- Realtime(hou_713_ext|exchange|${EXTEN:4:3}|hou_713_);
- if ("${hou_713_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-
- _9281NXXXXXX => {
- Realtime(hou_281_ext|exchange|${EXTEN:4:3}|hou_281_);
- if ("${hou_281_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-
- _9832NXXXXXX => {
- Realtime(hou_832_ext|exchange|${EXTEN:4:3}|hou_832_);
- if ("${hou_832_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from huntsville.conf
-// Converted the extension list to the database
-
-context huntsville-calling {
- _9NXXXXXX => {
- Realtime(hv_ext|exchange|${EXTEN:1:3}|hv_);
- if ("${hv_exchange}foo" = "foo") {
- Playback(num-outside-area);
- SayDigits(1);
- Playback(and-area-code);
- Playback(before-the-number);
- Hangup;
- };
- &dialout(${EXTEN});
- Congestion(10);
- Hangup;
- };
-
- _NXXXXXX => {
- NoOp(Stripping last four to see what extension we're dialing);
- Set(LAST4=${EXTEN:3});
- StripLSD(4);
- };
-
- i => Playback(pbx-invalid);
- h => Hangup;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from macros.conf
-
-macro dialout( number ) {
- Realtime(call_info|exten|${CALLERIDNUM:5}|mon_);
- if ("${mon_monitor}" = "YES") {
- Dial(SIP/${number}@sgw1.shsu.edu,,wW);
- Dial(SIP/${number}@sgw2.shsu.edu,,wW);
- } else {
- Dial(SIP/${number}@sgw1.shsu.edu);
- Dial(SIP/${number}@sgw2.shsu.edu);
- };
-};
-
-// Standard extension macro:
-// ${ext} - Extension
-macro stdexten( ext ) {
- Realtime(sipusers|name|${ext}|sip_user_);
- Realtime(call_info|exten|${ext}|info_);
- if ("${sip_user_name}foo" = "foo") {
- Wait(1);
- &dialout(${ext});
- Congestion(10);
- Hangup;
- };
- NoOp(${CALLERIDNUM});
- RealtimeUpdate(call_info|exten|${ext}|calltrace|${CALLERIDNUM});
- System(/usr/local/bin/db_update.sh call_info calltrace ${CALLERIDNUM} exten ${ext} &);
- &checkdnd(${ext});
- &checkcf(${ext});
- Realtime(call_info|exten|${CALLERIDNUM:5}|mon_);
- if ("${mon_monitor}" = "YES") {
- Dial(SIP/${info_forwardto},25,wW);
- } else {
- Dial(SIP/${info_forwardto},25);
- };
- switch ("${DIALSTATUS}") {
- case "BUSY":
- &checkcfb(${ext});
- break;
- case "CHANUNAVAIL":
- Dial(IAX2/asterisk:password@scm2.shsu.edu/${info_forwardto},25,wW);
- MailboxExists(${ext});
-// if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
-// Congestion(10);
-// Hangup;
-// };
- &uvm(${ext});
- Hangup;
- break;
- case "CONGESTION":
- MailboxExists(${ext});
- if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
- Congestion(10);
- Hangup;
- };
- &bvm(${ext});
- Hangup;
- break;
- default:
- MailboxExists(${ext});
- if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
- Congestion(10);
- Hangup;
- };
- &uvm(${ext});
- Hangup;
- };
- Hangup;
-};
-
-macro uvm( ext ) {
- Dial(SIP/u${ext}@svm1.shsu.edu);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Congestion(10);
- Hangup;
-};
-
-macro bvm( ext ) {
- Dial(SIP/b${ext}@svm1.shsu.edu);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Congestion(10);
- Hangup;
-};
-
-macro checkdnd( ext ) {
- if ("${info_donotdisturb}foo" = "foo") {
- NoOp(Do Not Disturb is not active);
- } else
- &uvm(${ext});
-};
-
-macro checkcf( ext ) {
- if ("${info_forwardto}foo" = "foo")
- if ("${ext}" = "43974") {
- Set(info_forwardto=${ext}&SCCP/${ext});
- } else {
- Set(info_forwardto=${ext}&SIP/${ext}w);
- };
-};
-
-macro checkcfb( ext ) {
- if ("${info_forwardbusy}foo" = "foo") {
- Wait(1);
- MailboxExists(${ext});
- if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
- &dialout(${ext});
- Hangup;
- };
- &bvm(${ext});
- Hangup;
- };
- &stdexten(${info_forwardbusy});
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from test.conf
-
-context test-include {
- includes {
- test-digium;
- test-sounds;
- test-phinfo;
- };
-};
-
-context test-digium {
- *500 => {
- Dial(IAX2/guest@misery.digium.com/s@default);
- Playback(demo-nogo);
- Hangup;
- };
-};
-
-context test-sounds {
- *501 => {
- Answer;
- Musiconhold;
- Wait(1);
- Hangup;
- };
-};
-
-context test-phinfo {
- *505 => {
- Answer;
- NoOp(${CALLERIDNUM:5});
- SayDigits(${CALLERIDNUM:5});
- Hangup;
- };
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from external.conf
-
-context long-distance {
- includes {
- local;
- };
-
- _91XXXXXXXXXX => &dialout(${EXTEN});
- _9011. => &dialout(${EXTEN});
-};
-
-context local {
- includes {
- default;
- };
-
- 911 => &dialout(911);
- 9911 => &dialout(9911);
-
- _9NXXXXXX => goto huntsville-calling|${EXTEN}|1;
- _936NXXXXXX => {
- Goto 9${EXTEN:3}|1;
- Congestion(10);
- Hangup;
- };
-
- _832NXXXXXX => {
- goto 9${EXTEN}|1;
- Congestion(10);
- Hangup;
- };
-
- _713NXXXXXX => {
- goto 9${EXTEN}|1 ;
- Congestion(10);
- Hangup;
- };
-
- _281NXXXXXX => {
- goto 9${EXTEN}|1;
- Congestion(10);
- Hangup;
-
- };
-
- _NXXNXXXXXX => {
- goto 9${EXTEN}|1;
- goto 91${EXTEN}|1;
- Congestion(10);
- Hangup;
- };
-
- _91800NXXXXXX => &dialout(${EXTEN});
- _91866NXXXXXX => &dialout(${EXTEN});
- _91877NXXXXXX => &dialout(${EXTEN});
- _91888NXXXXXX => &dialout(${EXTEN});
- _91900NXXXXXX => &dialout(${EXTEN});
- _91976NXXXXXX => &dialout(${EXTEN});
- _9713NXXXXXX => goto houston-calling|${EXTEN}|1;
- _9281NXXXXXX => goto houston-calling|${EXTEN}|1;
- _9832NXXXXXX => goto houston-calling|${EXTEN}|1;
- _9903NXXXXXX => goto l903-calling|${EXTEN}|1;
-
- _31NXXNXXXXXX => &dialout(${EXTEN});
-
- h => Hangup;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from internal.conf
-
-context from-scm2 {
- _4XXXX => {
- NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
- Dial(SIP/${EXTEN},20,wW);
- Hangup;
- };
-
- _6XXXX => {
- NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
- Dial(SIP/${EXTEN},20,wW);
- Hangup;
- };
-};
-
-///////////////////////////////////////////////////////////
-// All internal extensions work through the default context
-// Phones that can only make internal calls should be in
-// this context.
-///////////////////////////////////////////////////////////
-
-context default {
-// Include the contexts in the files that allow us to make these phone calls
- includes {
- vm-include;
- apps-include;
- test-include;
- };
-
-// ALWAYS have an 'h' extension
- h => {
- NoOp(Hangup cause was: ${HANGUPCAUSE});
- Hangup;
- };
-
-// We like to hear that we dialed an invalid extension
- i => Playback(pbx-invalid);
-
-// Dial the operator
- 0 => &dialout(0);
-
-// Send voicemail calls to the vm-* contexts to be handled
- voicemail => goto vm-direct|s|1;
- 5555 => goto vm-direct|s|1;
- 62100 => goto vm-extension|s|1;
-
-// These are our campus extensions, send them to the macro
- _6XXXX => &stdexten(${EXTEN});
- _4XXXX => &stdexten(${EXTEN});
-// These are campus extensions as well, might need to take this out though.
- _9294XXXX => goto _4XXXX|1;
- _9496XXXX => goto _6XXXX|1;
-
-// These allows us to dial from the directory in our phone without worrying about dialing 9
- _936294XXXX => {
- goto ${EXTEN:5}|1;
- goto 9${EXTEN:3}|1;
- Congestion(10);
- Hangup;
- };
-
- _936496XXXX => {
- goto ${EXTEN:5}|1;
- goto 9${EXTEN:3}|1;
- Congestion(10);
- Hangup;
- };
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from apps.conf
-
-context apps-include {
- includes {
- app-agents;
- app-dnd;
- app-callforward;
- app-calltrace;
- app-conferences;
- app-ssd;
- app-psd;
- app-idblock;
- app-helpdesk;
- app-dictate;
- app-set-monitor;
- };
-};
-
-context app-agents {
- *54 => {
- Answer;
- Wait(1);
- Read(agent_no|agent-user);
- AgentCallbackLogin(${agent_no}|s${CALLERIDNUM:5});
- Playback(agent-loginok);
- Hangup;
- };
-
- *55 => {
- Answer;
- Wait(1);
- AgentCallbackLogin(${agent_no});
- Hangup;
- };
-};
-
-context app-calltrace {
-// caller dials this to find out the last call missed and possibly call back
- *69 => goto app-calltrace-perform|s|1;
-};
-
-context app-calltrace-perform {
- s => {
- Answer;
- Wait(1);
- Background(info-about-last-call);
- Background(telephone-number);
- RealTime(call_info|exten|${CALLERIDNUM:5}|ct_);
- if ("${ct_calltrace}foo" = "foo") {
- Playback(loligo/from-unknown-caller);
- Hangup;
- } else {
- SayDigits("${ct_calltrace}");
- Set(TIMEOUT(digit)=3);
- Set(TIMEOUT(response)=7);
- Background(loligo/to-call-this-number);
- Background(press-1);
- Background(loligo/silence/5);
- };
- };
-
- 1 => goto local|${ct_calltrace}|1;
-
- i => {
- Playback(vm-goodbye);
- Hangup;
- };
-
- t => {
- Playback(vm-goodbye);
- Hangup;
- };
-};
-
-context app-set-monitor {
- *50 => {
- Realtime(call_info|exten|${CALLERIDNUM:5}|mon_set_);
- if ("${mon_set_monitor}" = "YES") {
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|);
- System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
- } else {
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|YES);
- System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
- };
- NoOp(${mon_set_monitor});
- Hangup;
- };
-};
-
-context app-dnd {
- *78 => {
- Answer;
- Wait(1);
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|donotdisturb|YES);
- System(/usr/local/bin/db_update.sh call_info donotdisturb YES exten ${CALLERIDNUM:5} &);
- Playback(do-not-disturb);
- Playback(loligo/activated);
- Hangup;
- };
-
- *79 => {
- Answer;
- Wait(1);
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|donotdisturb|);
- System(/usr/local/bin/db_update.sh call_info donotdisturb '' exten ${CALLERIDNUM:5} &);
- Playback(do-not-disturb);
- Playback(loligo/de-activated);
- Hangup;
- };
-};
-
-context app-callforward {
- // forwards calling extension to input number *72{EXTEN}
- _*72. => {
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardto|${EXTEN:3});
- System(/usr/local/bin/db_update.sh call_info forwardto ${EXTEN:3} exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-unconditional);
- Playback(loligo/for);
- Playback(loligo/extension);
- SayDigits(${CALLERIDNUM:5});
- Playback(loligo/is-set-to);
- SayDigits(${EXTEN:3});
- Hangup;
- };
-
- // prompts for extension to forward to
- *72 => {
- Answer;
- Wait(1);
- Playback(please-enter-your);
- Playback(extension);
- Background(then-press-pound);
- VMAuthenticate(|s);
- Background(loligo/ent-target-attendant);
- Read(toext,loligo/then-press-pound);
- Wait(1);
- RealtimeUpdate(call_info|exten|${AUTH_MAILBOX}|forwardto|${toext});
- System(/usr/local/bin/db_update.sh call_info forwardto ${toext} exten ${AUTH_MAILBOX} &);
- Playback(loligo/call-fwd-unconditional);
- Playback(loligo/for);
- Playback(loligo/extension);
- SayDigits(${AUTH_MAILBOX});
- Playback(loligo/is-set-to);
- SayDigits(${toext});
- Hangup;
- };
-
- // cancels dialed extension call forward
- _*73. => {
- Realtime(voicemail|mailbox|${EXTEN:3}|auth_);
- Answer;
- Wait(1);
- Authenticate(${auth_password});
- RealtimeUpdate(call_info|exten|${EXTEN:3}|forwardto|);
- System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${EXTEN:3} &);
- Wait(1);
- SayDigits(${EXTEN:3});
- Playback(loligo/call-fwd-cancelled);
- Hangup;
- };
-
- // cancels call forward for calling extension
- *73 => {
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardto|);
- System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-cancelled);
- Hangup;
- };
-
- // dialed call forward on busy
- _*90. => {
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardbusy|${EXTEN:3});
- System(/usr/local/bin/db_update.sh call_info forwardbusy ${EXTEN:3} exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-on-busy);
- Playback(loligo/for);
- Playback(loligo/extension);
- SayDigits(${CALLERIDNUM:5});
- Playback(loligo/is-set-to);
- SayDigits(${EXTEN:3});
- Hangup;
- };
-
- // cancels call forward on busy for calling extension
- *91 => {
- RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardbusy|);
- System(/usr/local/bin/db_update.sh call_info forwardbusy '' exten ${CALLERIDNUM:5} &);
- Answer;
- Wait(1);
- Playback(loligo/call-fwd-on-busy);
- Playback(loligo/de-activated);
- Hangup;
- };
-
- h => Hangup;
-};
-
-context app-idblock {
- _*67. => {
- Set(CALLERID(name)=Anonymous);
- &stdexten(${EXTEN:3});
- };
-};
-
-context app-dictate {
- *1 => {
- Dictate();
- Hangup;
- };
-};
-
-context app-ssd {
-// *59 <xx> <y.> - Set system speed dial <xx> to digits <y.>
-// *59 <xx> 0 - Delete system speed dial <xx>
-// *59 <xx> - Review system speed dial <xx>
-// *1xx - Dial speed dial <xx>
- _*59XXX. => {
- Answer;
- RealtimeUpdate(ssd|sd|${EXTEN:3:2}|extension|${EXTEN:5});
- System(/usr/local/bin/db_update.sh systemsd extension ${EXTEN:5} sd ${EXTEN:3:2} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-set-to);
- SayDigits(${EXTEN:5});
- Hangup;
- };
-
- _*59XX0 => {
- Answer;
- RealtimeUpdate(ssd|sd|${EXTEN:3:2}|extension|);
- System(/usr/local/bin/db_update.sh systemsd extension '' sd ${EXTEN:3:2} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-cleared);
- Hangup;
- };
-
- _*59XX => {
- Answer;
- Realtime(ssd|sd|${EXTEN:3}|ssd_);
- if ("${ssd_extension}foo" = "foo") {
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-set-to);
- SayDigits(${ssd_extension});
- Hangup;
- };
-
- // NTC = number to call
- _*1XX => {
- Realtime(ssd|sd|${EXTEN:2}|ssd_);
- if ("${ssd_extension}foo" = "foo") {
- Answer;
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- &stdexten(${ssd_extension});
- Congestion(10);
- Hangup;
- };
-};
-
-macro check-psd-exists ( ext ) {
- Realtime(psd|extension|${ext}|psd_);
- if ("${psd_extension}foo" = "foo") {
- System(/usr/local/bin/create_psd.sh ${ext});
- } else
- NoOp(PSD set for ${ext});
-};
-
-context app-psd {
-// *89 <xx> <y.> - Set personal speed dial <xx> to digits <y.>
-// *89 <xx> 0 - Delete personal speed dial <xx>
-// *89 <xx> - Review personal speed dial <xx>
-// *2xx - Dial personal speed dial <xx>
- _*89XXX. => {
- &check-psd-exists(${CALLERIDNUM:5});
- Answer;
- RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|${EXTEN:5});
- System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} ${EXTEN:5} extension ${CALLERIDNUM:5} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-set-to);
- SayDigits(${EXTEN:5});
- Hangup;
- };
-
- _*89XX0 => {
- &check-psd-exists(${CALLERIDNUM:5});
- Answer;
- RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|);
- System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} '' extension ${CALLERIDNUM:5} &);
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/has-been-cleared);
- Hangup;
- };
-
- _*89XX => {
- &check-psd-exists(${CALLERIDNUM:5});
- Answer;
- Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
- Wait(1);
- if ("${psd_s${EXTEN:3:2}}foo" = "foo") {
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:3:2});
- Playback(loligo/is-set-to);
- SayDigits(${psd_s${EXTEN:3:2}});
- Hangup;
- };
-
- // NTC = number to call
- _*2XX => {
- &check-psd-exists(${CALLERIDNUM:5});
- Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
- if ("${psd_s${EXTEN:2}}foo" = "foo") {
- Answer;
- Wait(1);
- Playback(loligo/speed-dial);
- SayDigits(${EXTEN:2});
- Playback(loligo/is-not-set);
- Hangup;
- };
- &stdexten(${psd_s${EXTEN:2}});
- Congestion(10);
- Hangup;
- };
-};
-
-context app-helpdesk {
- *4357 => {
- &stdexten(41950);
- Congestion;
- };
-};
-
-context app-conferences {
-// waiting for room number announcement
- *86 => goto app-conf-hidden|s|1;
-};
-
-context app-conf-hidden {
- s => {
- Wait(1);
- Playback(loligo/please-enter-the);
- Playback(loligo/extension);
- read(roomtoenter,loligo/then-press-pound);
- Meetme(${roomtoenter});
- Waitexten(8);
- Hangup;
- };
-
- _1. => Meetme(${EXTEN});
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Extensions pulled from vm.conf:
-
-context vm-include {
- includes {
- vm-direct;
- vm-extension;
- vm-directory;
- };
-};
-
-context vm-direct {
- s => {
- Dial(SIP/5555@svm1.shsu.edu,20);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Playback(extra/pls-try-call-later);
- Congestion(10);
- Hangup;
- };
-};
-
-context vm-extension {
- s => {
- Dial(SIP/62100@svm1.shsu.edu,20);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Playback(extra/pls-try-call-later);
- Congestion(10);
- Hangup;
- };
-};
-
-context vm-directory {
- 5556 => {
- Dial(SIP/5556@svm1.shsu.edu);
- Playback(im-sorry);
- Playback(voice-mail-system);
- Playback(down);
- Playback(extra/pls-try-call-later);
- Congestion(10);
- Hangup;
- };
-};
diff --git a/1.4/pbx/ael/ael-test/ael-test7/extensions.ael b/1.4/pbx/ael/ael-test/ael-test7/extensions.ael
deleted file mode 100644
index 52f9a077a..000000000
--- a/1.4/pbx/ael/ael-test/ael-test7/extensions.ael
+++ /dev/null
@@ -1,460 +0,0 @@
-//
-// Example AEL config file
-//
-
-globals {
- CONSOLE=Console/dsp;
- TRUNKMSD=0; //MSD digits to strip (usually 1 or 0)
- TRUNCPROTO=SIP;
- TRUNK=sunrocket;
- PSTN=pstn-spa3k;
- PSTNPROTO=SIP;
- TARIOPROTO=SIP;
- TARIO=tario;
- CPPROTO=SIP;
- CPACKET1=callpacket1;
- CPACKET2=callpacket2;
- SELLVOIP=1577040314;
- SVPROTO=IAX2;
-};
-
-
-macro stdexten (ext , dev ) {
- PrivacyManager(3,10);
- if("${PRIVACYMGRSTATUS}" = "FAILED") {
- Playback(vm-goodbye);
- Hangup();
- };
-
- AGI(calleridnamelookup.agi);
- Dial(${dev}/${ext},30,t);
- switch(${DIALSTATUS}) {
- case BUSY:
- Voicemail(b${ext});
- break;
- default:
- Voicemail(u${ext});
- };
- catch a {
- VoiceMailMain(${ext});
- return;
- };
-};
-
-macro announce_minutes(minutes) {
- Playback(vm-youhave);
- SayNumber(${minutes});
- Playback(vm-minutes);
- Wait(1);
-};
-
-// Check if given provider allows only some free minutes per month
-// and announce number of free minutes remaining.
-// The limit will be reset monthly by cron job.
-// The macro sets the following variables:
-// MINUTES_LIMIT - number of free minutes per month
-// MINUTES_USED - number of free minutes used in the current month
-// PROVIDER - provider name
-
-macro checkanddial(prov,proto,ext,arg1,arg2,arg3,arg4) {
- Set(MINUTES_LIMIT=0);
- Set(MINUTES_USED=0);
- Set(PROVIDER=${prov});
-
- if(${DB_EXISTS(Provider/${prov}/used)})
- Set(MINUTES_USED=${DB_RESULT});
-
- country_c = 0;
- switch(${LEN(${ext})}) { //assuming all international numbers are 11 digits long.
- case 10: //NXXNXXXXXX
- country_c=1;
- break;
- case 11: //XNXXNXXXXXX
- country_c = ${ext:0:1};
- break;
- default: //011XNXXNXXXXXX
- country_c = ${ext:3:1};
- break;
- };
-
- if("${prov}" = "${TRUNK}" & ${country_c} != 1) { // SunRocket international calls
- Set(MINUTES_LIMIT=${DB(Provider/${prov}/limit)});
- &announce_minutes($[${MINUTES_LIMIT} - ${MINUTES_USED}]);
- };
- if("${prov}" = "${CPACKET1}" | "${prov}" = "${CPACKET2}") { // Callpacket has a limit on domestic calls
- Set(MINUTES_LIMIT=${DB(Provider/${prov}/limit)});
- &announce_minutes($[${MINUTES_LIMIT} - ${MINUTES_USED}]);
- };
- DeadAGI(dial.agi,${proto}/${ext}@${prov},${arg1},${arg2},${arg3},${arg4});
-};
-
-macro trunkdial(ext) { // Dial sunrocket and set correct collerid
- if("${CALLERID(number)}" = "1") {
- Set(CALLERID(number)=7322271653);
- } else {
- Set(CALLERID(number)=7326260100);
- };
- Set(CALLERID(name)=Sergey Okhapkin);
- &checkanddial(${TRUNK},${TRUNCPROTO},${ext},60,T);
- Hangup;
-};
-
-macro checklocal(ext) { // lookup the number in DB and call the number via pstn or sunrocket
- Set(AREACODE=${ext:0:3});
- Set(EXCHANGE=${ext:3:3});
- Set(IS_LOCAL=${DB_EXISTS(localnum/${AREACODE}/${EXCHANGE})});
- if(${IS_LOCAL}) {
- &checkanddial(${PSTN},${PSTNPROTO},${ext},60,T);
- if ("${DIALSTATUS}" = "BUSY")
- &trunkdial(${ext});
- } else
- &trunkdial(${ext});
-};
-
-macro autodial(ext) { // Find Least Cost Route
- LCDial(${ext},60,T);
- if("${DIALSTATUS}" = "NOPROVIDER")
- Playback(invalid);
- Hangup();
-};
-
-context default { // Calls to us
- s => {
- Wait(1);
- Answer;
-start:
- Set(TIMEOUT(digit)=3);
- Set(TIMEOUT(response)=10);
-repeat:
- for (x=0; ${x} < 5; x=${x} + 1) {
- Background(home/greeting);
- WaitExten();
- };
- };
- t => jump *;
- i => { // invalid extension
- Playback(invalid);
- goto s|repeat;
- };
- _* => {
- Playback(vm-goodbye);
- Wait(1);
- Hangup;
- };
- 1 => &stdexten(1,SIP/1);
- 2 => &stdexten(2,SIP/2);
- 3 => &stdexten(3,SIP/3);
-
- 2271653 => jump 1;
- 7322271653 => jump 1;
- 17322271653 => jump 1;
-
- 6260100 => jump 2;
- 7326260100 => jump 2;
- 17326260100 => jump 2;
- 8058701100 => jump 2;
- 3103622835 => jump 2;
- sos => jump 2;
- 1400898 => jump 2;
-
- 6260101 => jump s;
- 7326260101 => jump s;
- 17326260101 => jump s;
-
- 2271677 => jump 3;
- 7322271677 => jump 3;
- 17322271677 => jump 3;
- galka => jump 3;
- 911 => Dial(${PSTNPROTO}/911@${PSTN},60,);
- 380 => Dial(SIP/topspeen@212.40.38.70,60,T);
-
- // Fun stuff
- 100 => {
- SayUnixTime();
- goto s|start;
- };
- 101 => { // Voicemail
- VoicemailMain(${CALLERID(number)});
- Hangup;
- };
- 102 => MusicOnHold();
-// 103 => {
-// Wait(1);
-//start:
-// Read(NUMBER,vm-enter-num-to-call);
-// LCDial(${NUMBER},T);
-// goto start;
-// };
- 105 => jump s@phrase-menu;
- 7312 => {
- ForkCDR;
- Set(CALLERID(name)=Sergey Okhapkin);
- Set(CALLERID(number)=7326260100);
- DISA(1111|home);
- };
-};
-
-context goiax {
- s => {
- Answer();
- Ringing();
- Wait(1);
-start:
- Read(NUMBER,vm-enter-num-to-call);
- Set(CALLERID(name)=Central NJ);
- Dial(IAX2/14301@fwdOUT/q${NUMBER},60,T);
- goto start;
- };
-
-};
-
-context phrase-menu {
-
- s => {
- Answer; // Answer the line
- TIMEOUT(digit)=2; // Set Digit Timeout to 5 seconds
- TIMEOUT(response)=10; // Set Response Timeout to 10 seconds
- BackGround(custom/phrase-menu); // Play main menu.
- };
- 1 => { // Phrase Recording
- Wait(1);
- Read(PHRASEID|custom/enter-phrase-num);
- Wait(2); // give yourself 2 secs to take a breath and wait for beep
- Record(custom/${PHRASEID}:gsm);
- Wait(2);
- Playback(custom/${PHRASEID});
- Wait(1);
- jump s;
- };
- 2 => { // Phrase review
- Wait(1);
- Read(PHRASEID|custom/enter-phrase-num);
- Wait(1);
- Playback(custom/${PHRASEID});
- Wait(1);
- jump s;
- };
- t => Hangup;
- i => {
- Playback(custom/invalid-option);
- jump s;
- };
-};
-
-context outbound {
- // North America seven-, ten- and eleven digits
- _NXXXXXX => &autodial(1732${EXTEN});
- _NXXNXXXXXX => &autodial(1${EXTEN});
- _ZNXXNXXXXX. => &autodial(${EXTEN});
- // Toll free numbers via PSTN
-// _1800NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
-// _1888NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
-// _1877NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
-// _1866NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
-
- _011. => { //International context accessed through trunk
- &trunkdial(${EXTEN});
- };
- _012. => { //fwdOUT
- Set(CALLERID(name)=Central NJ);
- Dial(IAX2/14301@fwdOUT/q${EXTEN:3},60,T);
- };
- _013X. => { //NECC
- Dial(${PSTNPROTO}/011${EXTEN:3}@${PSTN},60,T);
- };
- _0131. => { //NECC to US
- Dial(${PSTNPROTO}/${EXTEN:3}@${PSTN},60,T);
- };
- _014. => { //TARIO by SIP ID
- Set(CALLERID(name)=Sergey Okhapkin);
- Set(CALLERID(number)=1400898);
- Dial(${TARIOPROTO}/${EXTEN:3}@${TARIO},60,T);
- };
- _0157. => { //TARIO outbound Russia
- Set(CALLERID(name)=Sergey Okhapkin);
- Set(CALLERID(number)=1400898);
- Dial(${TARIOPROTO}/8${EXTEN:4}@${TARIO},60,T);
- };
-// _015. => { //TARIO outbound international
-// CALLERID(name)="Sergey Okhapkin";
-// CALLERID(number)=1400898;
-// Dial(${TARIOPROTO}/810${EXTEN:3}@${TARIO},60,T);
-// };
- _0161NXXNXXXXXX => { //Callpacket outbound USA/Canada
- &checkanddial(${CPACKET1},${CPPROTO},${EXTEN:3},60,T);
- };
- _0171NXXNXXXXXX => { //Callpacket outbound USA/Canada
- &checkanddial(${CPACKET2},${CPPROTO},${EXTEN:3},60,T);
- };
- _0181NXXNXXXXXX => { //sellvoip outbound USA/Canada
- Dial(${SVPROTO}/${SELLVOIP}@${SELLVOIP}/${EXTEN:3},60,T);
- };
- _019. => { //Voipbuster
- Dial(IAX2/sokhapkin@voipbuster/00${EXTEN:3},60,T);
- };
-};
-
-context home { //calls from us
- includes {
- default;
- outbound;
- };
-};
-
-context sunrocket-in {
- 7322271653 => jump s;
- 7326260100 => jump 2@default;
- s => {
- if("${CALLERID(number)}" = "sunrocketcom")
- Set(CALLERID(number)=);
- switch(${CALLERID(RDNIS)}) {
- case 7326260100:
- jump 2@default;
- break;
- case 7326260101:
- jump s@default;
- break;
- default:
- jump 1@default;
- break;
- };
- };
-};
-
-context pstn-in {
- 3 => {
- if ("${CALLERID(number)}" = "7322271677")
- Set(CALLERID(number)=);
- jump 3@default;
- };
-};
-
-context tario.net-in {
- _X. => {
- Set(CALLERID(name)=);
- if("${CALLERID(number):-11:1}" = "8")
- Set(CALLERID(number)=7${CALLERID(number):1});
- if("${SIP_HEADER(To)}" = "<sip:2271677@sipnet.ru>") {
- jump 3@default;
- } else if("${SIP_HEADER(To)}" = "<sip:2271653@sipnet.ru>") {
- jump 1@default;
- } else
- jump 2@default;
- };
-};
-
-context from-callpacket {
- 8058701100 => jump 2@default;
- 3103622835 => {
- Answer;
- Ringing;
- Wait(10);
- Voicemail(b3103622835);
- Hangup;
- };
- a => Hangup;
-};
-
-context fromfwdOUT { // make sure we only accept US and Canada calls, limit to 30 minutes
- includes {
- fromfwdOUT-catchbad;
- fromfwdOUT-isgood;
- fromfwdOUT-catchall;
- };
-};
-
-context fromfwdOUT-isgood {
- _17326260100 => jump 2@default;
- _17326260101 => jump s@default;
- _17322271653 => jump 1@default;
- _17322271677 => jump 3@default;
- _1NXXNXXXXXX => {
- Set(CALLERID(name)=Sergey Okhapkin);
-// Set(CALLERID(number)=7326260100);
-// Dial(${TRUNCPROTO}/*67${EXTEN:${TRUNKMSD}}@${TRUNK},60,,L(1800000:60000));
- Dial(${CPPROTO}/${EXTEN}@${CPACKET2},60,,L(1800000:60000));
- };
-};
-
-context fromfwdOUT-catchbad { //block bahamas, etc
- _1900. => congestion ; //N11
- _1XXX976. => congestion ; //N11
- _1XXX555. => congestion ; //N11
- _1X11. => congestion ; //N11
- _1867. => congestion ; //Yukon (sorry mike)
-
- // exten => _1NPA Country
- _1242. => congestion; //BAHAMAS
- _1246. => congestion; //BARBADOS
- _1264. => congestion; //ANGUILLA
- _1268. => congestion; //ANTIGUA/BARBUDA
- _1284. => congestion; //BRITISH VIRGIN ISLANDS
- _1345. => congestion; //CAYMAN ISLANDS
- _1441. => congestion; //BERMUDA
- _1473. => congestion; //GRENADA
- _1649. => congestion; //TURKS & CAICOS ISLANDS
- _1664. => congestion; //MONTSERRAT
- _1758. => congestion; //ST. LUCIA
- _1767. => congestion; //DOMINICA
- _1784. => congestion; //ST. VINCENT & GRENADINES
- _1809. => congestion; //DOMINICAN REPUBLIC
- _1829. => congestion; //DOMINICAN REPUBLIC
- _1868. => congestion; //TRINIDAD AND TOBAGO
- _1869. => congestion; //ST. KITTS AND NEVIS
- _1876. => congestion; //JAMAICA
- _1787. => congestion; //Puerto Rico 787, 939 $0.07
- _1939. => congestion; //Puerto Rico 787, 939 $0.07
- _1671. => congestion; //Guam 671 $0.08
- _1340. => congestion; //U.S. Virgin Islands 340 $0.06
-};
-
-context fromfwdOUT-catchall {
- _X. => Congestion;
- h => Hangup ; //hangup event
- i => Hangup ; //invalid event
- t => Hangup ; //timeout event
-};
-
-context ael-demo {
- s => {
- Wait(1);
- Answer();
- TIMEOUT(digit)=5;
- TIMEOUT(response)=10;
-restart:
- Background(demo-congrats);
-instructions:
- for (x=0; ${x} < 3; x=${x} + 1) {
- Background(demo-instruct);
- WaitExten();
- };
- };
- 2 => {
- Background(demo-moreinfo);
- goto s|instructions;
- };
- 3 => {
- LANGUAGE()=fr;
- goto s|restart;
- };
- 500 => {
- Playback(demo-abouttotry);
- Dial(IAX2/guest@misery.digium.com);
- Playback(demo-nogo);
- goto s|instructions;
- };
- 600 => {
- Playback(demo-echotest);
- Echo();
- Playback(demo-echodone);
- goto s|instructions;
- };
- _1234 => &std-exten-ael(${EXTEN}, "IAX2");
- # => {
- Playback(demo-thanks);
- Hangup();
- };
- t => jump #;
- i => Playback(invalid);
-};
-
diff --git a/1.4/pbx/ael/ael-test/ael-test8/extensions.ael b/1.4/pbx/ael/ael-test/ael-test8/extensions.ael
deleted file mode 100644
index 17bc74e6f..000000000
--- a/1.4/pbx/ael/ael-test/ael-test8/extensions.ael
+++ /dev/null
@@ -1,27 +0,0 @@
-context default
-{
-
-706/3077610011 => {
- JabberStatus(asterisk|jmls@mike,StatusCode);
-
- switch(${StatusCode}) {
- case 1:
- Dial(SIP/706,12);
- switch(${DIALSTATUS}) {
- case BUSY:
- Voicemail(b706);
- break;
- default:
- Voicemail(u706);
- };
- BackGround(hello);
- break;
- default:
- Voicemail(u706);
- };
-
- Hangup();
- };
-
-}
-
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/extensions.ael b/1.4/pbx/ael/ael-test/ael-vtest13/extensions.ael
deleted file mode 100755
index dd77c0531..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/extensions.ael
+++ /dev/null
@@ -1,3183 +0,0 @@
-globals
-{
- static=yes;
- writeprotect=yes;
- CONSOLE=Console/dsp; // Console interface for demo
- IAXINFO=murf:tlhfckoct; // IAXtel username/password
- FWDNUMBER=544788 ; // your calling number
- FWDCIDNAME="Joe-Worker"; // your caller id
- FWDPASSWORD=zingledoodle ; // your password
- FWDRINGS=Zap/6 ; // the phone to ring
- FWDVMBOX=1 ; // the VM box for this user
-}
-
-macro std-exten( ext , dev )
-{
- Dial(${dev}/${ext},20);
- switch(${DIALSTATUS})
- {
- case BUSY:
- Voicemail(b${ext});
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- case ANSWER:
- break;
- default:
- Voicemail(u${ext});
- }
- catch a {
- VoiceMailMain(${ext});
- }
-}
-
-macro std-priv-exten_1( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_2( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_3( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_4( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_5( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_6( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_7( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_8( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_9( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_10( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_11( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_12( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_13( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_14( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_15( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_16( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_17( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_18( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_19( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_20( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_21( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_22( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_23( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_24( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_25( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_26( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_27( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_28( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_29( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_30( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_31( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_32( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_33( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_34( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_35( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_36( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_37( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_38( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_39( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_40( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_41( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_42( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_43( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_44( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_45( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_46( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_47( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_48( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_49( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_50( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_51( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_52( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_53( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_54( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_55( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_56( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_57( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_58( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_59( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_60( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_61( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_62( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_63( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_64( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_65( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_66( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_67( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_68( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_69( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_70( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_71( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_72( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten_73( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-
-macro std-priv-exten( dev, ext , timeout, opts, torcont, dontcont )
-{
- Dial(${dev},${timeout},${opts});
- NoOp(${DIALSTATUS} was chosen);
- switch(${DIALSTATUS})
- {
- case TORTURE:
- goto ${torcont}|s|begin;
- break;
- case DONTCALL:
- goto ${dontcont}|s|begin;
- break;
- case BUSY:
- Voicemail(b${ext});
- break;
- case ANSWER:
- break;
- case NOANSWER:
- Voicemail(u${ext});
- break;
- default:
- Voicemail(u${ext});
- }
-}
-
-macro fillcidname()
-{
- if( "${CALLERID(number)}" = "" ) // nothing to work with, quit!!!
- return;
- Set(cidn=${DB(cidname/${CALLERID(num)})});
- if( "${CALLERID(name)}" != "" )
- {
- if( ("${cidn}" = "Privacy Manager" & "${CALLERID(name)}" != "Privacy Manager") | "${cidn}" = "" ) // if the entry isn't in the database,
- // or if an entry exists, and it's "Privacy Manager", empty, (or add other useless possibilities).
- {
- Set(DB(cidname/${CALLERID(number)})=${CALLERID(name)}); // then set or override what's in the DB
- }
- }
- // Now, we fill in the callerid info from the incoming entry, if it's stuff worth using
- // Ignore fundamentally semi-anonymous information from local cell phones
- // if the db has an entry for this number, and it's not a canned string from a cell phone company
- if( ( "${cidn}" != "" ) & ( "${CALLERID(name)}" = ""
- | "${CALLERID(name)}" = "CODY,WY "
- | "${CALLERID(name)}" = "POWELL,WY "
- | "${CALLERID(name)}" = "WIRELESS CALLER"
- | "${CALLERID(name)}" = "SUBSCRIBER,WIRE"
- | "${CALLERID(name)}" = "CELLULAR ONE"
- | "${CALLERID(name)}" = "Cellular One Customer"
- | "${CALLERID(name)}" = "CELLULAR ONE "
- | "${CALLERID(name)}" = "Privacy Manager"
- | "${CALLERID(name)}" = "RIVERTON,WY "
- | "${CALLERID(name)}" = "BASIN,WY "
- | "${CALLERID(name)}" = "BILLINGS,MT "
- | "${CALLERID(name)}" = "PROVO,UT "
- | "${CALLERID(name)}" = "TOLL FREE " ) ) // put stuff in the above, that the phone company tends to put in your callerid,
- // that you would rather override with DB info
- // there's no way to guess them all, but you can get the most popular ones...
- // why cell phones can't do CID like everybody else, ....?
- {
- Set(CALLERID(name)=${cidn}); // Override what the phone company provides with what's in the DB for this number.
- }
-}
-
-macro ciddial(dialnum, lookup, waittime, dialopts, ddev)
-{
- Set(cidnu=${CALLERID(num)});
- Set(cidn=${DB(cidname/${lookup})});
- Set(CALLERID(name)=${cidn});
- Dial(${ddev}/${dialnum}|${waittime}|${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_voip);
- CALLERID(num)=7075679201;
- Dial(SIP/1${lookup}@tctwest,${waittime},${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_cell);
- CALLERID(num)=${cidnu}; // put the original number back
- Dial(Zap/2/${lookup},${waittime},${dialopts});
- }
- }
-}
-
-macro ciddial3(dialnum, lookup, waittime, dialopts, ddev)
-{
- Set(cidnu=${CALLERID(num)});
- Set(cidn=${DB(cidname/${lookup})});
- Set(CALLERID(name)=${cidn});
- Dial(${ddev}/${dialnum}|${waittime}|${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_cell);
- Dial(Zap/2/${lookup},${waittime},${dialopts});
- }
-}
-
-macro ciddial2(dialnum, lookup, waittime, dialopts, ddev) // give priority to tctwest, then the ZAP in emergencies
-{
- Set(cidn=${DB(cidname/${lookup})});
- Set(cidnu=${CALLERID(num)});
- Set(CALLERID(name)=${cidn});
- Set(CALLERID(num)=7075679201);
- Dial(SIP/1${lookup}@tctwest,${waittime},${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- Set(CALLERID(num)=${cidnu}); // put the original number back
- BackGround(try_zap);
- Dial(${ddev}/${dialnum},${waittime}|${dialopts});
- if( "${DIALSTATUS}" = "CHANUNAVAIL" )
- {
- BackGround(try_cell);
- Dial(Zap/2/${lookup},${waittime},${dialopts});
- }
- }
-}
-
-macro callerid-liar()
-{
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/priv-callerintros/LIAR.gsm&);
- Background(priv-liar); // Script: OOOps! Sorry! I don't allow men with ski masks pulled over their
- // faces to get in the front door, and unidentified callers won't fair
- // any better. You entered *MY* phone number. That won't work.
- // If you are telemarketing, cross me off the list, and don't call again.
- // If you did this by mistake, forgive my defenses, and call again.
- // Alternate: (priv-liar2)
- // Script: You have chosen to try to deceive my system and withold your CallerID,
- // by entering my own phone number as YOUR CallerID. I find this
- // offensive because you are being dishonest. I will not do business nor
- // waste my time talking to anyone who is less than honest and forthcoming.
- // Take me off your call list and do not call me again.
- Hangup();
-}
-
-macro callerid-bad()
-{
- mycid=${CALLERID(num)}:"1([0-9]+)";
- Set(CALLERID(num)=${mycid});
- Wait(0);
-}
-
-context privacyManagerFailed {
- s => {
- begin:
- Background(PrivManInstructions); // Script: OOps, that didn't go well. You need to enter *your* area code, and *your* 7 digit
- // phone number, for a total of 10 digits, or you'll be handed over to the monkeys. Let's
- // try this again, and hopefully you can get past our front-line defenses!
- PrivacyManager();
- if( "${PRIVACYMGRSTATUS}" = "FAILED" )
- {
- Background(tt-allbusy);
- Background(tt-somethingwrong);
- Background(tt-monkeysintro);
- Background(tt-monkeys);
- Background(tt-weasels);
- Hangup();
- }
- else
- {
- goto homeline|s|postPriv;
- }
- }
-}
-
-// Some comments
-// Some more comments
-
-context homeline {
- s => {
- begin:
- Answer();
- Set(repeatcount=0);
- Zapateller(nocallerid);
- PrivacyManager();
- if( "${PRIVACYMGRSTATUS}" = "FAILED" )
- {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/privmanfailed.gsm);
- &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
- Hangup();
- return;
-// goto privacyManagerFailed|s|begin;
- }
- postPriv:
- &fillcidname();
- Set(CONFCIDNA=${CALLERID(name)});
- Set(CONFCIDNU=${CALLERID(num)});
- AGI(callall);
- AGI(submit-announce.agi);
- if( "${CALLERID(num)}" : "1" )
- {
- &callerid-bad();
- }
- if( "${CALLERID(num)}" = "7077577685" & "${CALLERID(name)}" : "Privacy Manager" )
- {
- &callerid-liar();
- }
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- Set(lds=${DB(playlds/${CALLERID(num)})});
- if( "${lds}" = "1" )
- {
- SetMusicOnHold(mohlds);
- }
- direct=${DB(DirectCall/${CALLERID(num)})};
- if( "${direct}" != "" & ${direct} != 0 )
- {
- verbose(direct is XXX#${direct}XXXX);
- Playback(greetings/direct); // Welcome to the Murphy residence. This system will automatically try to connect you to...
- Playback(/var/spool/asterisk/voicemail/default/${direct}/greet);
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/${direct}/greet.wav&);
- switch(${direct})
- {
- case 1: //Steve
- &std-priv-exten(Zap/6r3&Sip/murf,1,25,mpA(beep)tw,telemarket,telemarket);
- goto s|loopback;
- case 2: //Sonya
- &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
- goto s|loopback;
- default: // all the kids
- Set(z=${direct}-2);
- goto homeline-kids|${z}|1;
- }
- }
- loopback:
- ifTime(*|*|20-25|dec)
- {
- Playback(greetings/christmas);
- }
- else ifTime(*|*|31|dec)
- {
- Playback(greetings/newyear);
- }
- else ifTime(*|*|1|jan)
- {
- Playback(greetings/newyear);
- }
- else ifTime(*|*|14|feb)
- {
- Playback(greetings/valentines);
- }
- else ifTime(*|*|17|mar)
- {
- Playback(greetings/stPat);
- }
- else ifTime(*|*|31|oct)
- {
- Playback(greetings/halloween);
- }
- else ifTime(*|mon|15-21|jan)
- {
- Playback(greetings/mlkDay);
- }
- else ifTime(*|thu|22-28|nov)
- {
- Playback(greetings/thanksgiving);
- }
- else ifTime(*|mon|25-31|may)
- {
- Playback(greetings/memorial);
- }
- else ifTime(*|mon|1-7|sep)
- {
- Playback(greetings/labor);
- }
- else ifTime(*|mon|15-21|feb)
- {
- Playback(greetings/president);
- }
- else ifTime(*|sun|8-14|may)
- {
- Playback(greetings/mothers);
- }
- else ifTime(*|sun|15-21|jun)
- {
- Playback(greetings/fathers);
- }
- else
- {
- Playback(greetings/hello); // None of the above? Just a plain hello will do
- }
- Background(murphy-homeline-intro1); // Script: Hello-- Welcome to the Murphy's! If you already know what
- // option you want, you don't have to wait for this entire spiel-- just
- // have at it.
- // If you are calling because this number is on a list of some sort, dial 6.
- // If you want Sonya, dial 1.
- // If you want one of the kids, dial 2.
- // If you want Steve, dial 3.
- // to play with your introduction, dial 5.
- // If we don't seem to be giving you the time of day, try 7.
- // Have a good day!
-
- }
- 1 => { // Sonya
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/2/greet.wav&);
- &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
- goto s|loopback;
- }
- 2 => { // Kids
- goto homeline-kids|s|begin;
- }
- 21 => {
- Dial(IAX2/seaniax,20,T);
- }
- 3 => { // Steve
- &std-priv-exten(Zap/6r3&Sip/murf,1,25,mpA(beep)tw,telemarket,telemarket);
- goto s|loopback;
- }
- 4 => { // Voicemail
- VoicemailMain();
- goto s|loopback;
- }
- 5 => { // play with intro
- goto home-introduction|s|begin;
- }
- 6 => { // Telemarketers
- goto telemarket|s|begin;
- }
- 7 => { // time of day, riddle
- agi(tts-riddle.agi);
- Background(gsm/what-time-it-is2);
- SayUnixTime();
- goto s|loopback;
- }
- 792 => { // Page All
- goto pageall|s|begin;
- }
- 793 => { // check the tone recognition
- Read(zz,,0,,1,0);
- SayDigits(${zz});
- }
- t => {
- Set(repeatcount=${repeatcount} + 1);
- if( ${repeatcount} < 3 )
- {
- goto s|loopback; // just loopback isn't enough
- }
- Hangup();
- }
- i => {
- Background(invalid);
- goto s|loopback;
- }
- o => {
- Congestion();
- }
- fax => {
- Dial(Zap/4);
- }
-}
-
-// Some comments
-// Some more comments
-
-context pageall {
- s => {
- begin:
- AGI(callall);
- MeetMe(5555,dtqp);
- MeetMeAdmin(5555,K);
- Hangup();
- }
-
- h => {
- begin:
- MeetMeAdmin(5555,K);
- Background(conf-muted);
- Hangup();
- }
-}
-
-// Some comments
-// Some more comments
-
-context add-to-conference {
- start => {
- NoCDR();
- MeetMe(5555,dmqp);
- }
- h => {
- Hangup();
- }
-}
-
-context home-introduction {
- s => {
- begin:
- Background(intro-options); // Script: To hear your Introduction, dial 1.
- // to record a new introduction, dial 2.
- // to return to the main menu, dial 3.
- // to hear what this is all about, dial 4.
- }
- 1 => {
- Playback(priv-callerintros/${CALLERID(num)});
- goto s|begin;
- }
- 2 => {
- goto home-introduction-record|s|begin;
- }
- 3 => {
- goto homeline|s|loopback;
- }
- 4 => {
- Playback(intro-intro); // Script:
- // This may seem a little strange, but it really is a neat
- // thing, both for you and for us. I've taped a short introduction
- // for many of the folks who normally call us. Using the Caller ID
- // from each incoming call, the system plays the introduction
- // for that phone number over a speaker, just as the call comes in.
- // This helps the folks
- // here in the house more quickly determine who is calling.
- // and gets the right ones to gravitate to the phone.
- // You can listen to, and record a new intro for your phone number
- // using this menu.
- goto s|begin;
- }
- t => {
- goto s|begin;
- }
- i => {
- Background(invalid);
- goto s|begin;
- }
- o => {
- goto s|begin;
- }
-}
-
-context home-introduction-record {
- s => {
- begin:
- Background(intro-record-choices); // Script:
- // If you want some advice about recording your
- // introduction, dial 1.
- // otherwise, dial 2, and introduce yourself after
- // the beep.
- }
- 1 => {
- Playback(intro-record);
- // Your introduction should be short and sweet and crisp.
- // Your introduction will be limited to 10 seconds.
- // This is NOT meant to be a voice mail message, so
- // please, don't say anything about why you are calling.
- // After we are done making the recording, your introduction
- // will be saved for playback.
- // If you are the only person that would call from this number,
- // please state your name. Otherwise, state your business
- // or residence name instead. For instance, if you are
- // friend of the family, say, Olie McPherson, and both
- // you and your kids might call here a lot, you might
- // say: "This is the distinguished Olie McPherson Residence!"
- // If you are the only person calling, you might say this:
- // "This is the illustrious Kermit McFrog! Pick up the Phone, someone!!"
- // If you are calling from a business, you might pronounce a more sedate introduction,like,
- // "Fritz from McDonalds calling.", or perhaps the more original introduction:
- // "John, from the Park County Morgue. You stab 'em, we slab 'em!".
- // Just one caution: the kids will hear what you record every time
- // you call. So watch your language!
- // I will begin recording after the tone.
- // When you are done, hit the # key. Gather your thoughts and get
- // ready. Remember, the # key will end the recording, and play back
- // your intro. Good Luck, and Thank you!"
- goto 2|begin;
- }
- 2 => {
- begin:
- Background(intro-start);
- // OK, here we go! After the beep, please give your introduction.
- Background(beep);
- Record(priv-callerintros/${CALLERID(num)}:gsm,3);
- Background(priv-callerintros/${CALLERID(num)});
- goto home-introduction|s|begin;
- }
- t => {
- goto s|begin;
- }
- i => {
- Background(invalid);
- goto s|begin;
- }
- o => {
- goto s|begin;
- }
-}
-
-context homeline-kids {
- s => {
- begin:
- Background(murphy-homeline-kids); // Which Kid? 1=Sean, 2:Eric, 3:Ryan, 4:Kyle, 5:Amber, 6:Alex, 7:Neal
- }
- 1 => { // SEAN
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/3/greet.wav&);
- // &std-priv-exten(Zap/3r2&Zap/5r2,3,35,mtw,telemarket,telemarket);
- &std-priv-exten(IAX2/seaniax&Zap/5r2,3,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 2 => { // ERIC
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&);
- Voicemail(u4);
- goto homeline|s|loopback;
-
- // SetMusicOnHold(erics);
- // TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- // TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&);
- // &std-priv-exten(Zap/3r2&Zap/5r2,4,35,mtw,telemarket,telemarket);
- // goto homeline|s|loopback;
- }
- 3 => { // RYAN
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/5/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,5,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 4 => { // KYLE
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/6/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,6,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 5 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/7/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,7,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
-
- }
- 6 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/8/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,8,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- 7 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/9/greet.wav&);
- &std-priv-exten(Zap/3r2&Zap/5r2,9,35,mtw,telemarket,telemarket);
- goto homeline|s|loopback;
- }
- t => {
- goto s|begin;
- }
- i => {
- Background(invalid);
- goto s|begin;
- }
- o => {
- goto s|begin;
- }
-}
-
-context voipworkline {
- s => {
- begin:
- Answer();
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- goto workline|s|loopback;
- }
- 7075679201 => {
- Answer();
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- goto workline|s|loopback;
- }
-}
-
-context workline {
- s => {
- begin:
- Answer();
- Wait(1);
- Set(repeatcount=0);
- Zapateller(nocallerid);
-// PrivacyManager();
-// if( "${PRIVACYMGRSTATUS}" = "FAILED" )
-// {
-// goto privacyManagerFailed|s|begin;
-// }
- &fillcidname();
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- loopback:
- Background(greetings/greeting); //script: Hello
- Background(murphy-office-intro1); //script: welcome to Steve Murphy's office. If you are dialing
- // this number because it was on a calling list of any sort, dial 6.
- // Otherwise, dial 1, and hopefully, you will reach Steve.
- }
- 1 => {
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
- TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/1/greet.wav&);
-
- &std-priv-exten(Zap/6&Sip/murf,1,30,mtw,telemarket,telemarket);
- goto s|loopback;
- }
- 4 => {
- VoicemailMain();
- goto s|loopback;
- }
- 6 => {
- goto telemarket|s|begin;
- }
- 793 => { // check the tone recognition
- Read(zz,,0,,1,0);
- SayDigits(${zz});
- }
- t => {
- repeatcount=${repeatcount} + 1;
- if( ${repeatcount} < 3 )
- {
- goto s|loopback; // just loopback isn't enough
- }
- Hangup();
- }
- i => {
- Background(invalid);
- goto s|loopback;
- }
- o => {
- Congestion();
- }
- fax => {
- Answer();
- Dial(Zap/4);
- }
-}
-
-context dialFWD {
- ignorepat => 8;
- ignorepat => 9;
- _83. => {
- Set(CALLERID(name)=${FWDCIDNAME});
- Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
- Congestion();
- }
- _82NXX => {
- Set(CALLERID(name)=${FWDCIDNAME});
- Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
- Congestion();
- }
- _92NXX => {
- Set(CALLERID(name)=${FWDCIDNAME});
- Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
- Congestion();
- }
-}
-
-context dialiaxtel {
- ignorepat => 8;
- ignorepat => 9;
- _81700NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
- _81800NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
- _91700NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
- _91800NXXXXXX => {
- Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
- }
-
-}
-
-context dialgoiax {
- ignorepat => 9;
- _93. => {
- Set(CALLERID(name)="Joe Worker");
- Dial(IAX2/878201007658:stickyfinger295@server1.goiax.com/${EXTEN:2},60,r);
- Congestion();
- }
-
-}
-
-context homefirst {
- ignorepat => 9;
- _91NXXNXXXXXX => {
- &ciddial(${EXTEN:1},${EXTEN:2},30,TW,Zap/1);
- }
- _9754XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9574XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9202XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9219XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9254XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9716XXXX => {
- &ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9NXXXXXX => {
- &ciddial(1707${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9011. => {
- &ciddial(${EXTEN:1},${EXTEN:1},30,TW,Zap/1);
- }
- _9911 => {
- Dial(Zap/1/911,30,T);
- }
- _9411 => {
- Dial(Zap/1/411,30,T);
- }
-}
-
-context workfirst {
- ignorepat => 9;
- _91NXXNXXXXXX => {
- &ciddial2(${EXTEN:1},${EXTEN:2},30,TW,Zap/1);
- }
- _9754XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9574XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9202XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9219XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9254XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9716XXXX => {
- &ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9NXXXXXX => {
- &ciddial2(1707${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
- }
- _9911 => {
- Dial(Zap/1/911,30,T);
- }
- _9411 => {
- Dial(Zap/1/411,30,T);
- }
-}
-
-context force_cell {
- ignorepat => 8;
- _81NXXNXXXXXX => {
- &ciddial(${EXTEN:1}#,${EXTEN:2},30,TW,Zap/2);
- }
- _8754XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8574XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8202XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8219XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8254XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8716XXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8NXXXXXX => {
- &ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
- }
- _8911 => {
- Dial(Zap/1/911|30|T);
- }
- _8411 => {
- Dial(Zap/1/411|30|T);
- }
-}
-
-context force_home {
- ignorepat => 8;
- _81NXXNXXXXXX => {
- &ciddial3(${EXTEN:1}#,${EXTEN:2},30,TW,Zap/1);
- }
- _8754XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8574XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8202XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8219XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8254XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8716XXXX => {
- &ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8NXXXXXX => {
- &ciddial3(1707${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
- }
- _8911 => {
- Dial(Zap/1/911|30|T);
- }
- _8411 => {
- Dial(Zap/1/411|30|T);
- }
-}
-
-context homeext {
- ignorepat => 8;
- ignorepat => 9;
- includes {
- parkedcalls;
- homefirst;
- force_cell;
- }
- s => {
- loopback:
- Wait(0);
- }
- 1 => {
- &std-priv-exten(Zap/3&Zap/5,2,35,mtw,telemarket,telemarket);
- goto s|loopback;
- }
- 2 => {
- &std-priv-exten(Zap/6&Zap/5,1,35,mpA(beep3)Tt,telemarket,telemarket);
- goto s|loopback;
- }
- 4 => {
- VoicemailMain();
- }
- 5 => {
- Record(recording:gsm);
- Background(recording);
- }
- 6 => {
- Background(recording);
- }
- 760 => {
- DateTime();
- goto s|loopback;
- }
- 761 => {
- Record(announcement:gsm);
- TrySystem(/usr/bin/play /var/lib/asterisk/sounds/announcement.gsm&);
- goto s|loopback;
- }
- 762 => {
- agi(tts-riddle.agi);
- Background(gsm/what-time-it-is2);
- SayUnixTime();
- goto s|loopback;
- }
- 763 => {
- Set(CALLERID(num)=);
- Dial(Zap/6r3,35,mptA(beep3)); //results: it should ALWAYS ask for an intro; the intro should not be left behind
- Hangup();
- }
- 764 => {
- Set(CALLERID(num)=);
- Dial(Zap/6r3,35,mptnA(beep3)); //results: Don't save the intro; shouldn't anyway if no callerid
- Hangup();
- }
- 765 => {
- Set(CALLERID(num)=);
- Dial(Zap/6r3,35,mptNA(beep3)); //results: Don't screen if there's CALLERID; it should screen the call.
- Hangup();
- }
- 766 => {
- Dial(Zap/6r3,35,mptNA(beep3)); //results: Don't screen if there's CALLERID; it should screen the call.
- Hangup();
- }
- 767 => {
- Dial(Zap/6r3,35,mptnA(beep3)); //results: Don't save the intro; the interesting case, because callerID should be present.
- Hangup();
- }
- 769 => {
- Playtones(dial);
- Wait(2);
- Playtones(busy);
- Wait(2);
- Playtones(ring);
- Wait(2);
- Playtones(congestion);
- Wait(2);
- Playtones(callwaiting);
- Wait(2);
- Playtones(dialrecall);
- Wait(2);
- Playtones(record);
- Wait(2);
- Playtones(info);
- Wait(5);
- Hangup();
- }
- 790 => {
- MeetMe(790,p);
- }
- 792 => {
- goto pageall|s|begin;
- }
- 795 => {
- AGI(wakeup.agi);Congestion();
- }
- 544716 => { // Incoming call from FWD
- TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
- goto s|loopback;
- }
-
- i => {
- Background(invalid);
- goto s|loopback;
- }
- o => {
- goto s|loopback;
- }
- t => {
- Congestion();
- }
-}
-
-context fromvmhome {
- 1 => {
- Dial(Zap/6&Sip/murf|20|Tt);
- }
- 2 => {
- Dial(Zap/3&Zap/5|20|Tt);
- }
- _707202XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707219XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707254XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707716XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707754XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707574XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _NXXNXXXXXX => {
- &ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
- }
- _1NXXNXXXXXX => { // HAND DIALING
- &ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
- }
- _754XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _574XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _NXXXXXX => {
- &ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _911 => {
- &ciddial(911,911,30,TW,Zap/1);
- }
- _411 => {
- &ciddial(411,411,30,TW,Zap/1);
- }
-}
-
-context fromvmwork {
- 1 => {
- Dial(Zap/6&Sip/murf|20|Tt);
- }
- 2 => {
- Dial(Zap/3&Zap/5|20|Tt);
- }
- _707202XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707219XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707254XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707716XXXX => {
- &ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707754XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707574XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _NXXNXXXXXX => {
- &ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
- }
- _1NXXNXXXXXX => { // HAND DIALING
- &ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
- }
- _754XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _574XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _NXXXXXX => {
- &ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- 911 => {
- &ciddial(911,911,30,TW,Zap/1);
- }
- 411 => {
- &ciddial(411,411,30,TW,Zap/1);
- }
-}
-
-context fromSeanUniden {
- includes
- {
- parkedcalls;
- }
- 21 => {
- Dial(IAX2/seaniax,20,T);
- }
- _707202XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707219XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707254XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707716XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707754XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _707574XXXX => {
- &ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
- }
- _NXXNXXXXXX => {
- &ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
- }
- _1NXXNXXXXXX => {
- &ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
- }
- _754XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _574XXXX => {
- &ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- _NXXXXXX => {
- &ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
- }
- 911 => {
- &ciddial(911,911,30,TW,Zap/1);
- }
- 411 => {
- &ciddial(411,411,30,TW,Zap/1);
- }
-}
-
-context workext {
- ignorepat => 8;
- ignorepat => 9;
- includes {
- parkedcalls;
- workfirst;
- force_home;
- dialFWD;
- dialiaxtel;
- dialgoiax;
- }
- s => {
- loopback:
- Wait(0);
- }
- 1 => {
- Dial(Zap/3&Zap/5,20,tT);
- }
- 2 => {
- Dial(Zap/5&Zap/6,20,tT);
- }
- 21 => {
- Dial(IAX2/seaniax,20,T);
- }
- 22 => {
- Set(CALLERID(num)=1234567890);
- Set(CALLERID(name)=TestCaller);
- Dial(Zap/5,20,mP()A(beep)tw);
- NoOp(here is dialstatus: ${DIALSTATUS}...);
- goto s|loopback;
- }
- 4 => {
- VoicemailMain();
- goto s|loopback;
- }
- 5 => {
- Record(recording:gsm);
- Background(recording);
- }
- 6 => {
- ZapBarge();
- }
- 760 => {
- DateTime();
- goto s|loopback;
- }
- 761 => {
- ZapBarge();
- goto s|loopback;
- }
- 765 => {
- Playback(demo-echotest);
- Echo();
- Playback(demo-echodone);
- goto s|loopback;
- }
- 766 => {
- Festival(The other thing to watch is neuro-electronics: the ability to interface technology with our neural system: My wife: Sigrid: has had a cochlear implant since 1996. This once profoundly deaf person now uses the phone: recognizes accents: and listens to movies and recorded books.);
- goto s|loopback;
- }
- 767 => {
- agi(tts-riddle.agi);
- Background(gsm/what-time-it-is2);
- SayUnixTime();
- goto s|loopback;
- }
- 768 => {
- agi(tts-computer.agi);
- }
- 771 => {
- eagi(eagi-test);
- agi(my-agi-test);
- }
- 772 => {
- agi(wakeup.agi);
- }
- 775 => {
- if( ${EXTEN}=${EXTEN} )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- if( ${EXTEN}=${LANGUAGE} )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- BackGround(digits/2);
- }
- 776 => {
- Set(TEST=00359889811777);
- if( ${TEST}= 00359889811777 )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- if( ${TEST}= 00359889811888 )
- {
- BackGround(digits/1);
- }
- else
- {
- BackGround(digits/0);
- }
- Hangup();
- }
- 790 => {
- MeetMe(790,p);
- }
- 792 => {
- goto pageall|s|begin;
- }
- 793 => {
- #include "include1.ael2"
- }
- 795 => {
- AGI(wakeup.agi);
- Congestion();
- }
- 797 => {
- Set(CONFCIDNA=${CALLERID(name)});
- Set(CONFCIDNU=${CALLERID(num)});
- AGI(callall);
- AGI(submit-announce.agi);
- Hangup();
- }
-}
-
-context wakeup {
- 3 => {
- Dial(Zap/3|30);
- }
- 4 => {
- Dial(Zap/4|30);
-
- }
- 5 => {
- Dial(Zap/5|30);
-
- }
- 6 => {
- Dial(Zap/6|30);
-
- }
- 99 => {
- Dial(IAX2/murfiaxphone|30);
- }
- 97 => {
- Dial(IAX2/ryaniax|30);
- }
- 94 => {
- Dial(IAX2/seaniax|30);
- }
-}
-
-context announce-all {
- s => {
- begin:
- MeetMe(5555,dtqp);
- MeetMeAdmin(5555,K);
- Hangup();
- }
- h => {
- MeetMeAdmin(5555,K);
- Hangup();
- }
-}
-
-// now include the telemarketer torture scripts!
-
-#include "telemarket_torture.ael2"
-
-
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/include1.ael2 b/1.4/pbx/ael/ael-test/ael-vtest13/include1.ael2
deleted file mode 100644
index 80c562cb2..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/include1.ael2
+++ /dev/null
@@ -1,3 +0,0 @@
- NoOp(Hello, this is included from include1.ael2);
- #include "include2.ael2"
-
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/include2.ael2 b/1.4/pbx/ael/ael-test/ael-vtest13/include2.ael2
deleted file mode 100644
index 8d892fb0c..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/include2.ael2
+++ /dev/null
@@ -1,4 +0,0 @@
- NoOp(This was included from include2.ael2);
- #include "include3.ael2"
- #include "include4.ael2"
-
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/include3.ael2 b/1.4/pbx/ael/ael-test/ael-vtest13/include3.ael2
deleted file mode 100644
index 3c6c1e3dd..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/include3.ael2
+++ /dev/null
@@ -1,2 +0,0 @@
- NoOp(This is include3.ael2!);
- #include "include5.ael2"
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/include4.ael2 b/1.4/pbx/ael/ael-test/ael-vtest13/include4.ael2
deleted file mode 100644
index 7d3703a5e..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/include4.ael2
+++ /dev/null
@@ -1,2 +0,0 @@
- NoOp(This is include4.ael2! Isn't it cool!?!?!?!);
- NoOp(4 doesn't include anything);
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/include5.ael2 b/1.4/pbx/ael/ael-test/ael-vtest13/include5.ael2
deleted file mode 100644
index 0e18983ef..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/include5.ael2
+++ /dev/null
@@ -1 +0,0 @@
- NoOp(Include5.ael2 doesn't include anything, either!);
diff --git a/1.4/pbx/ael/ael-test/ael-vtest13/telemarket_torture.ael2 b/1.4/pbx/ael/ael-test/ael-vtest13/telemarket_torture.ael2
deleted file mode 100755
index ebd8e9f2f..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest13/telemarket_torture.ael2
+++ /dev/null
@@ -1,812 +0,0 @@
-//
-// AN EXCERSIZE IN BAD DIALPLAN DESIGN
-// (What better testing ground than on telemarketers?)
-//
-
-
-// BAD DESIGN: long, boring introductions followed by long, drawn out menus of choices.
-// if they survive to the last option, how will they remember the choices?
-//
-
-// BAD DESIGN: Amateur Recording. Poor voice quality, too quiet.
-// Also, the announcer is definitely not vocally gifted.
-// Also, the long pauses and clicks between the intro
-// and menu choices might lead some to think that
-// the announcements are over, and hang up. Too bad!
-
-// WORSE DESIGN: Instead of using the Background application, the Playback
-// application is used. After taking so much time and trouble
-// to record this material, the caller must listen and enjoy
-// every syllable before they can make an option choice. None
-// of that interrupting with a choice. We want them to savour
-// every word!
-
-// GOOD/BAD, ER INSIDIOUS -- DANGLE A CARROT-- GIVE THE LISTENER A GOOD REASON TO
-// HANG ON AND VOLUNTARILY LISTEN TO THE TORTURE.
-// BUT, DON'T MAKE PROMISES YOU WON'T KEEP!
-
-
-context telemarket {
- s => {
- begin:
- Playback(telemarketer-intro); // ; Script:
- // Due to the extremely high volume of calls from everything from telemarketers
- // to Septic System Bacteria vendors, we are asking all such organizations
- // to remove this number from their call list, or as need be, to add this
- // number to their No-Call list, whichever is relevent.
-
- // [THE CARROT:]
- // We HAVE made some exceptions, and if you wish to see if your organization
- // has been exempted, please listen to and follow the following prompts.
- //
- // Otherwise, please Cease calling this number!
- //
- Playback(telemarketer-choices);
- // if you represent a charitable organization, please dial 1,
- // if you represent a political organization, please dial 2.
- // if you represent a polling company, please dial 3,
- // if you represent a market research organization, please dial 4.
- // if you represent a magazine or newsletter, please dial 5.
- // if you represent a commercial organization, please dial 6.
- }
- 1 => goto telemarket-charity|s|begin;
- 2 => goto telemarket-political|s|begin;
- 3 => goto telemarket-pollster|s|begin;
- 4 => goto telemarket-research|s|begin;
- 5 => goto telemarket-magazine|s|begin;
- 6 => goto telemarket-commercial|s|begin;
- 7 => goto telemarket-other|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-charity {
- s => {
- begin:
- Playback(telemark-charity-intro);
- // We have contributed generously to many worthy causes in the past, and will
- // continue to do so in the future. But we suspect that such organizatons
- // have sold our name and phone number to each other until we are now hounded
- // day and night by literally hundreds of such organizations.
- // Enough is Enough!
- //
- // If we have contributed to your cause in the past, we may, perhaps, be disposed to
- // do so in the future, at our option,
- // we give no pledges nor make any commitments here.
- // Send us material via the post if you feel this necessary
- // but do not even consider email. Any email or further phone calls from your organization
- // in the future, will be considered an act of aggression, and we will
- // blacklist your organization for the rest of our natural lives.
- //
- // To see if your organization is exempt from these prohibitions, please
- // comply with the following options.
- Playback(telemark-charity-choices);
- // If your organization is disease or genetic defect related, dial 1,
- // If your organization is handicap related, dial 2.
- // If your organization is a police or fireman or other similar support entity, please dial 3.
- // If your organization is a grade school to high school related
- // fund raiser or other type of activity, please dial 4.
- // If your organization is a college or univerity or alumnis organization, please dial 5.
- // If your organization is animal rights or ecology related organization, please dial 6.
- // If your organization is a political action or candidate support related, please dial 7.
- // If your organization is a substance abuse related organization or cause, please dial 8.
- // And any other charity or tax exempt organization should dial 9.
- }
- 1 => goto telemarket-char-disease|s|begin;
- 2 => goto telemarket-char-handicap|s|begin;
- 3 => goto telemarket-char-police|s|begin;
- 4 => goto telemarket-char-school|s|begin;
- 5 => goto telemarket-char-college|s|begin;
- 6 => goto telemarket-char-animal|s|begin;
- 7 => goto telemarket-char-candidate|s|begin;
- 8 => goto telemarket-char-abuse|s|begin;
- 9 => goto telemarket-char-other|s|begin;
-// BAD DESIGN: referring all timeouts,invalid choices, etc, back to the root of the menu tree will frustrate users no end!
-// WORSE DESIGN: How about having the user have to push a button to repeat the current menu? When a time out could just
-// automatically do it for the user?
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-char-disease {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-handicap {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-police {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-school {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-college {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-animal {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-candidate {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-abuse {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-char-other {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-sorry {
- s => {
- begin:
- Playback(telemarket-sorry);
- // Sorry -- your organization is not exempt. Please stop calling us.
- // Thank you. goodbye.
- Hangup();
- }
-}
-
-
-// BAD DESIGN: Hanging up on your audience, no matter what the outcome, is not a nice thing to do!
-
-context telemarket-exception {
- s => {
- begin:
- Playback(telemarket-success);
- // Congratulations. Your organization IS exempt. Please call us back,
- // but this time, just act like a normal caller. Thank you. Goodbye.
- Hangup();
- }
-}
-
-
-// BAD DESIGN: Making long cascading menu choices is a nasty thing to do to callers!
-// BAD DESIGN: Putting the most frequently encountered items at the end of a list is also a nasty thing to do!
-
-
-// GOOD DESIGN: All rejection notices use a single context. All Acceptance also. To change a rejection to an
-// acceptance, just change the reference from telemarket-sorry to telemarket-exception
-
-
-context telemarket-political {
- s => {
- begin:
- Playback(telemark-polit-intro);
- // To see if your organization is exempt from our prohibitions,
- // please follow the following prompts.
- // please note that they are not in alphabetical order, and you will have to
- // give them your full attention.
- Playback(telemark-polit-choices);
- // if You represent the America First Party, dial 1.
- // if You represent the American Party, dial 2.
- // if You represent the American Heritage Party, dial 3.
- // if You represent the American Independent Party, dial 4.
- // if You represent the American Nazi Party, dial 5.
- // if You represent the Pot Party, dial 6.
- // if You represent the American Reform Party, dial 7.
- // if You represent the Christian Falenqist Party of America, dial 8.
- // all others, please dial 9.
- }
- 1 => goto telemarket-poli-Am1st|s|begin;
- 2 => goto telemarket-poli-American|s|begin;
- 3 => goto telemarket-poli-AmHer|s|begin;
- 4 => goto telemarket-poli-AmInd|s|begin;
- 5 => goto telemarket-poli-AmNaz|s|begin;
- 6 => goto telemarket-poli-Pot|s|begin;
- 7 => goto telemarket-poli-AmRef|s|begin;
- 8 => goto telemarket-poli-CFP|s|begin;
- 9 => goto telemarket-political2|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-political2 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- // Thank you for your patience, and I congratulate you for your persistence.
- // Just a few more options!
- //
- Playback(telemark-polit2-choices);
- // if You represent the Communist Party USA, dial 1.
- // if You represent the Constitution Party, dial 2.
- // if You represent the Family Values Party, dial 3.
- // if You represent the Freedom Socialist Party, dial 4.
- // if You represent the Grass Roots Party, dial 5.
- // if You represent the Green Party, dial 6.
- // if You represent the Greens Party, dial 7.
- // if You represent the Independence Party, dial 8.
- // all others, goto 9.
- }
- 1 => goto telemarket-poli-Communist|s|begin;
- 2 => goto telemarket-poli-Constit|s|begin;
- 3 => goto telemarket-poli-FamVal|s|begin;
- 4 => goto telemarket-poli-FreedSoc|s|begin;
- 5 => goto telemarket-poli-Grassroot|s|begin;
- 6 => goto telemarket-poli-Green|s|begin;
- 7 => goto telemarket-poli-Greens|s|begin;
- 8 => goto telemarket-poli-Independence|s|begin;
- 9 => goto telemarket-political3|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-context telemarket-political3 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- Playback(telemark-polit3-choices);
- // if You represent the Independant American Party, dial 1.
- // if You represent the Labor Party, dial 2.
- // if You represent the Libertarian Party, dial 3.
- // if You represent the Light Party, dial 4.
- // if You represent the Natural Law Party, dial 5.
- // if You represent the New Party, dial 6.
- // if You represent the New Union Party, dial 7.
- // if You represent the Peace and Freedom Party, dial 8.
- // all others, hang on, dial 9.
- }
- 1 => goto telemarket-poli-IndAm|s|begin;
- 2 => goto telemarket-poli-Labor|s|begin;
- 3 => goto telemarket-poli-Liber|s|begin;
- 4 => goto telemarket-poli-Light|s|begin;
- 5 => goto telemarket-poli-NatLaw|s|begin;
- 6 => goto telemarket-poli-New|s|begin;
- 7 => goto telemarket-poli-NewUn|s|begin;
- 8 => goto telemarket-poli-PeaceFree|s|begin;
- 9 => goto telemarket-political4|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-political4 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- Playback(telemark-polit4-choices);
- // if You represent the Prohibition Party, dial 1.
- // if You represent the Reform Party, dial 2.
- // if You represent the Revolution , dial 3.
- // if You represent the Socialist Party USA, dial 4.
- // if You represent the Socialist Action Party, dial 5.
- // if You represent the Socialist Equality Party, dial 6.
- // if You represent the Socialist Labor Party, dial 7.
- // if You represent the Socialist Workers Party, dial 8.
- // all others, hang on, and dial 9.
- }
- 1 => goto telemarket-poli-Prohib|s|begin;
- 2 => goto telemarket-poli-Ref|s|begin;
- 3 => goto telemarket-poli-Revol|s|begin;
- 4 => goto telemarket-poli-SocPart|s|begin;
- 5 => goto telemarket-poli-SocAct|s|begin;
- 6 => goto telemarket-poli-SocEq|s|begin;
- 7 => goto telemarket-poli-SocLab|s|begin;
- 8 => goto telemarket-poli-SocWork|s|begin;
- 9 => goto telemarket-political5|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-political5 {
- s => {
- begin:
- Playback(telemark-politx-intro);
- Playback(telemark-polit5-choices);
- // if You represent the Southern Party, dial 1.
- // if You represent the Southern Independence Party, dial 2.
- // if You represent the US Pacifist Party, dial 3.
- // if You represent the We the People Party, dial 4.
- // if You represent the Workers World Party, dial 5.
- // if You represent the Democratic Party, dial 6.
- // if You represent the Republican Party, dial 7.
- // all others, may dial 8.
- }
- 1 => goto telemarket-poli-South|s|begin;
- 2 => goto telemarket-poli-SoInd|s|begin;
- 3 => goto telemarket-poli-USPac|s|begin;
- 4 => goto telemarket-poli-WTP|s|begin;
- 5 => goto telemarket-poli-WWP|s|begin;
- 6 => goto telemarket-poli-Democrat|s|begin;
- 7 => goto telemarket-poli-Repub|s|begin;
- 8 => goto telemarket-poli-other|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-poli-other {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Repub {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Democrat {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-WWP {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-WTP {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-USPac {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SoInd {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-South {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocWork {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocLab {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocEq {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocAct {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-SocPart {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Revol {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Ref {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Prohib {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-PeaceFree {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-NewUn {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-New {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-NatLaw {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Light {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Liber {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Labor {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-IndAm {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Independence {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Greens {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Green {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Grassroot {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-FreedSoc {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-FamVal {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Constit {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Communist {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-CFP {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-AmRef {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-// BAD DESIGN: Putting in infinite loops in the menus, whether by design or mistake is not nice!
-context telemarket-poli-Pot {
- s => {
- begin:
- goto telemarket-political|s|begin; // will the Pot Party Guys even notice an infinite loop?
- }
-}
-
-context telemarket-poli-AmNaz {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-AmInd {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-AmHer {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-American {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-context telemarket-poli-Am1st {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-
-context telemarket-pollster {
- s => {
- begin:
- Playback(telemark-poll-intro);
- // I'm sorry-- We are just not available for doing any polling at the moment. So,
- // please remove us from your list.
- goto telemarket-sorry|s|begin;
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-research {
- s => {
- begin:
- Playback(telemark-research-intro);
- // I'd like to say I'd love to help you with your market survey, but that would be a complete
- // and total lie. I am not interested in helping you with Market Surveys.
- //
- // Please remove me from your call list. It just doesn't pay enough. But Thank you.
- goto telemarket-sorry|s|begin;
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-magazine {
- s => {
- begin:
- Playback(telemark-mag-choices);
- // If you are calling to see if I would like a NEW free subscription
- // to your magazine or newsletter, please dial 1.
- // If you are calling to see if I want to Renew an existing subscription, please dial 2.
- // If you are representing some publisher, and want my opinion about something, or are doing
- // some kind of survey, please dial 3.
- // If you are calling to verify that some previous caller actually called me, and the
- // verification information is correct, please dial 4.
- // and if your call purpose doesn't match any of the above, please dial 5.
- }
- 1 => goto telemark-mag-new|s|begin;
- 2 => goto telemark-mag-renew|s|begin;
- 3 => goto telemark-mag-survey|s|begin;
- 4 => goto telemark-mag-verify|s|begin;
- 5 => goto telemark-mag-other|s|begin;
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-new {
- s => {
- begin:
- Playback(telemark-mag-new);
- // I'm sorry, I'm maxed out, and the answer is NO.
- // If you really think I'd LOVE to add your publication to the pile I already get,
- // Send something via the post. Don't call me.
- // Thank you. bye.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-renew {
- s => {
- begin:
- Playback(telemark-mag-renew);
- // So, you want to see if I want to Renew, do you? The answer is most likely "YES".
- //
- // But, I will not answer a long list of questions over the phone. Send such
- // categorization info via the post, and stop bothering me over the phone,
- // if this is what you want.
- // Do you need verification information? Normally I opt out of such nonsense, if possible.
- // If not, use whatever of the following you can:
- // My birth month is October.
- // My birthplace is Kigali, in Rwanda, in Afica.
- // My eye color is orange.
- // All of these are wonderfully false, but I use them regularly for such purposes. Thank you.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-survey {
- s => {
- begin:
- Playback(telemark-mag-survey);
- // Sorry, I don't have time to answer survey or opinion questions. Find someone
- // else to help build your marketing database, I guess. Good Luck.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-verify {
- s => {
- begin:
- Playback(telemark-mag-verify);
- // If you are calling to verify that your own agents aren't ripping you off,
- // sorry, I can't help you. I opt out whenever I can, mainly because I'm not
- // paid enough for this kind of thing. I always lie, and I can't remember
- // what I might have said. Sorry. Goodbye.
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemark-mag-other {
- s => {
- begin:
- goto telemarket-sorry|s|begin;
- }
-}
-
-
-
-// BAD DESIGN: Is it entrapment, when you lure telemarketers to reveal their contact information,
-// Just so you can report them to the FTC/FCC? If it is, isn't it unethical for them
-// to hide their CID (via Anonymous, usually), to hide their identities from the public?
-
-// BTW -- What telemarketer would be stupid enough to fall for this? I'll bet not a single one!
-// For that matter, what telemarketer will be stupid enough to even enter any of this? I'll bet not a single one!
-// (but it was fun messing around).
-
-context telemarket-commercial {
- s => {
- begin:
- Playback(telemark-comm-intro); // Script: Please leave your name, organization, and phone number, plus
- // a short description of the purpose of your call, at the prompt.
- // We will do our best to respond to your call! And, in the mean time,
- // do not forget to add us to your no-call list!
- Voicemail(u82);
- goto telemarket-sorry|s|begin;
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
-
-
-context telemarket-other {
- s => {
- begin:
- Playback(telemark-other-intro);
- // Please review the previous menu options, and see if you really don't
- // fit in one of the previous categories.
- // If you do not, go ahead, and call me again, and let me know what category
- // I should have included in the above list. I appreciate this. Thank you much!
- Hangup();
- }
- t => goto telemarket|s|begin;
- i => goto telemarket|s|begin;
- o => goto telemarket|s|begin;
-}
diff --git a/1.4/pbx/ael/ael-test/ael-vtest17/extensions.ael b/1.4/pbx/ael/ael-test/ael-vtest17/extensions.ael
deleted file mode 100644
index d13fe99d7..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest17/extensions.ael
+++ /dev/null
@@ -1,116 +0,0 @@
-context dialextens
-{
- /*
- 101 thru 123, 149 thru 152
- */
- _10X => Dial(Zap/${EXTEN:2},30,tw);
- _1ZX => Dial(Zap/${EXTEN:1},30,tw);
-}
-/*
- Due to extenal wiring:
-
- dialing 125 will ring 101
- dialing 126 will ring 102
- and so on until
- dialing 147 will ring 123
-
-We can dial out on zap 69 thru 72; and 25-47
-
-*/
-
-context dialthrus
-{
- /* 369-372; 325-347 */
- _3XX => Dial(Zap/${EXTEN:1},30,tw);
-}
-
-context t1incoming
-{
- includes
- {
- dialextens;
- parkedcalls;
- }
- s => {
- Answer();
- Background(welcome-to-test-machine);
- }
-
-}
-
-context t1extension
-{
- includes
- {
- dialextens;
- dialthrus;
- }
-
-}
-
-context incoming
-{
- includes
- {
- dialextens;
- parkedcalls;
- }
- s => {
- Answer();
- Background(welcome-to-test-machine);
- }
-}
-
-context extension
-{
- includes
- {
- dialextens;
- dialthrus;
- }
- 5 => {
- Record(recording:gsm);
- Background(recording);
- }
-
- 81 => {
- iterations=1000000;
- Set(time1=${EPOCH});
- for(i=1; ${i}<${iterations}; i=${i}+1)
- {
- NoOp(Hello);
- }
- Set(time2=${EPOCH});
- Verbose(The time diff is $[${time2} - ${time1} ] seconds);
- Verbose(Which means that the priorities/sec = $[4* ${iterations} / (${time2} - ${time1}) ]);
- SayNumber($[4 * ${iterations} / (${time2} - ${time1}) ]);
- }
- 82 => {
- &ndeep(100000);
- Verbose(Finished 100000 levels deep call!);
- }
- 83 => {
- switch (${EXTEN})
- {
- pattern 8X:
- Verbose(do something to prepare it);
- pattern 9X:
- Verbose(handle both 8x and 9x calls);
- pattern [4-7]X:
- Verbose(and this too!);
-
- }
-
- }
-}
-
-macro ndeep(level)
-{
- if( ${level} == 0)
- {
- Verbose(2|Got to Level 0);
- return;
- }
- &ndeep($[${level}-1]);
- return;
-}
diff --git a/1.4/pbx/ael/ael-test/ael-vtest21/extensions.ael b/1.4/pbx/ael/ael-test/ael-vtest21/extensions.ael
deleted file mode 100644
index 95f25302a..000000000
--- a/1.4/pbx/ael/ael-test/ael-vtest21/extensions.ael
+++ /dev/null
@@ -1,14 +0,0 @@
-globals {
- AXLHAFT=wow-to-the-tenth-power;
- JibberWorthy=zinger3;
- OFFICE_CODE=503;
-}
-
-context from-enum {
-
- _${OFFICE_CODE}XXXX => {
- Answer();
- goto ${EXTEN:3}|1;
- }
-}
-
diff --git a/1.4/pbx/ael/ael-test/ref.ael-ntest10 b/1.4/pbx/ael/ael-test/ref.ael-ntest10
deleted file mode 100644
index 72a0c8172..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-ntest10
+++ /dev/null
@@ -1,158 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)
-
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4069 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4076 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4084 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 13-13: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 36-36: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 48-48: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 60-60: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 72-72: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 84-84: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 87-87: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 106-106: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 119-119: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 122-122: A default case was automatically added to the switch.
-LOG: lev:2 file:pbx_ael.c line:4087 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-Executed ast_context_create(conts, name=macro-endsess, registrar=pbx_ael);
-Executed ast_context_create(conts, name=macro-nullchk, registrar=pbx_ael);
-Executed ast_context_create(conts, name=macro-endcall, registrar=pbx_ael);
-Executed ast_context_create(conts, name=macro-endcall2, registrar=pbx_ael);
-Executed ast_context_create(conts, name=macro-endcall3, registrar=pbx_ael);
-Executed ast_context_create(conts, name=macro-endcall4, registrar=pbx_ael);
-Executed ast_context_create(conts, name=macro-endcall5, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endsess, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=NoOp, data=hithere, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-nullchk, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=Set, data=type=${ARG1}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-nullchk, rep=0, exten=s, priority=2, label=(null), callerid=(null), appl=NoOp, data=${type} is this, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=Set, data=type=${ARG1}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=s, priority=2, label=(null), callerid=(null), appl=Goto, data=sw-1-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=s, priority=3, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall-1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=_sw-1-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-1-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=10, label=(null), callerid=(null), appl=Macro, data=nullchk|callid, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=11, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?12:15, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=12, label=(null), callerid=(null), appl=Macro, data=endsess, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-1-out|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=14, label=(null), callerid=(null), appl=Goto, data=17, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=15, label=ptr1, callerid=(null), appl=Softhangup, data=${CHANNEL}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=16, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=17, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall-out-1-2, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=18, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall, rep=0, exten=sw-1-out, priority=19, label=(null), callerid=(null), appl=Goto, data=sw-1-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=Set, data=type=${ARG1}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=s, priority=2, label=(null), callerid=(null), appl=Goto, data=sw-3-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=s, priority=3, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall2-3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=_sw-3-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-3-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out2, priority=10, label=ptr1, callerid=(null), appl=Softhangup, data=${CHANNEL}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out2, priority=11, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out2, priority=12, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out2, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-3-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out, priority=10, label=(null), callerid=(null), appl=Macro, data=nullchk|callid, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out, priority=11, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?12:14, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out, priority=12, label=(null), callerid=(null), appl=Macro, data=endsess, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-3-out2|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out, priority=14, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall2-out-3-4, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall2, rep=0, exten=sw-3-out, priority=15, label=(null), callerid=(null), appl=Goto, data=sw-3-out2|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=Set, data=type=${ARG1}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=2, label=(null), callerid=(null), appl=Goto, data=sw-5-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=3, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall3-5, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=4, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?5:6, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=5, label=(null), callerid=(null), appl=Goto, data=sw-8-out|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=6, label=(null), callerid=(null), appl=NoOp, data=Finish if-endcall3-7, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=7, label=(null), callerid=(null), appl=Goto, data=sw-8-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=s, priority=8, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall3-8, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=_sw-8-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|8, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-8-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-out, priority=10, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?11:13, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-out, priority=11, label=ptr1, callerid=(null), appl=Softhangup, data=${CHANNEL}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-out, priority=12, label=(null), callerid=(null), appl=Goto, data=s|8, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-out, priority=13, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall3-out-8-9, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-out, priority=14, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-8-out, priority=15, label=(null), callerid=(null), appl=Goto, data=sw-8-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=_sw-5-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-5-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=10, label=(null), callerid=(null), appl=Macro, data=nullchk|callid, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=11, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?12:14, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=12, label=(null), callerid=(null), appl=Macro, data=endsess, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-8-out|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=14, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall3-out-5-6, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=15, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall3, rep=0, exten=sw-5-out, priority=16, label=(null), callerid=(null), appl=Goto, data=sw-5-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=Set, data=type=${ARG1}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=2, label=(null), callerid=(null), appl=Goto, data=sw-10-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=3, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall4-10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=4, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?5:6, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=5, label=(null), callerid=(null), appl=Goto, data=sw-14-in|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=6, label=(null), callerid=(null), appl=NoOp, data=Finish if-endcall4-12, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=7, label=(null), callerid=(null), appl=Goto, data=sw-13-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=s, priority=8, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall4-13, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=_sw-13-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|8, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-13-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-13-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-13-out, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-14-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-13-out, priority=11, label=(null), callerid=(null), appl=NoOp, data=Finish switch-sw-endcall4-out-13-14, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-13-out, priority=12, label=(null), callerid=(null), appl=Goto, data=sw-13-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=_sw-14-., priority=10, label=(null), callerid=(null), appl=Goto, data=sw-13-out|11, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-14-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-in, priority=10, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?11:13, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-in, priority=11, label=ptr1, callerid=(null), appl=Softhangup, data=${CHANNEL}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-in, priority=12, label=(null), callerid=(null), appl=Goto, data=sw-13-out|11, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-in, priority=13, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-sw-endcall4-out-13-in-14-15, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-in, priority=14, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-14-in, priority=15, label=(null), callerid=(null), appl=Goto, data=sw-14-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=_sw-10-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-10-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=10, label=(null), callerid=(null), appl=Macro, data=nullchk|callid, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=11, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?12:14, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=12, label=(null), callerid=(null), appl=Macro, data=endsess, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-14-in|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=14, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall4-out-10-11, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=15, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall4, rep=0, exten=sw-10-out, priority=16, label=(null), callerid=(null), appl=Goto, data=sw-10-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=1, label=(null), callerid=(null), appl=Set, data=type=${ARG1}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=2, label=(null), callerid=(null), appl=Goto, data=sw-16-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=3, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall5-16, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=4, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?5:6, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=5, label=(null), callerid=(null), appl=Goto, data=sw-21-in|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=6, label=(null), callerid=(null), appl=NoOp, data=Finish if-endcall5-19, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=7, label=(null), callerid=(null), appl=Goto, data=sw-20-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=s, priority=8, label=(null), callerid=(null), appl=NoOp, data=Finish switch-endcall5-20, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=_sw-20-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|8, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-20-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-20-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-20-out, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-21-${type}|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-20-out, priority=11, label=(null), callerid=(null), appl=NoOp, data=Finish switch-sw-endcall5-out-20-21, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-20-out, priority=12, label=(null), callerid=(null), appl=Goto, data=sw-20-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=_sw-21-., priority=10, label=(null), callerid=(null), appl=Goto, data=sw-20-out|11, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-21-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-in, priority=10, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?11:13, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-in, priority=11, label=ptr1, callerid=(null), appl=Softhangup, data=${CHANNEL}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-in, priority=12, label=(null), callerid=(null), appl=Goto, data=sw-20-out|11, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-in, priority=13, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-sw-endcall5-out-20-in-21-22, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-in, priority=14, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-21-in, priority=15, label=(null), callerid=(null), appl=Goto, data=sw-21-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=_sw-16-., priority=10, label=(null), callerid=(null), appl=Goto, data=s|3, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-, priority=10, label=(null), callerid=(null), appl=Goto, data=sw-16-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=10, label=(null), callerid=(null), appl=Macro, data=nullchk|callid, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=11, label=ptr2, callerid=(null), appl=GotoIf, data=$[${testnotnull}]?12:14, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=12, label=(null), callerid=(null), appl=Macro, data=endsess, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-21-in|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=14, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall5-in-16-18, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=15, label=(null), callerid=(null), appl=Noop, data=esac, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-in, priority=16, label=(null), callerid=(null), appl=Goto, data=sw-16-.|10, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-out, priority=10, label=(null), callerid=(null), appl=Macro, data=nullchk|callid, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-out, priority=11, label=(null), callerid=(null), appl=GotoIf, data=$[${testnotnull}]?12:14, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-out, priority=12, label=(null), callerid=(null), appl=Macro, data=endsess, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-out, priority=13, label=(null), callerid=(null), appl=Goto, data=sw-21-in|ptr1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-out, priority=14, label=(null), callerid=(null), appl=NoOp, data=Finish if-sw-endcall5-out-16-17, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=macro-endcall5, rep=0, exten=sw-16-out, priority=15, label=(null), callerid=(null), appl=Goto, data=sw-16-in|10, FREE, registrar=pbx_ael);
-LOG: lev:2 file:pbx_ael.c line:4089 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-Executed ast_merge_contexts_and_delete();
-LOG: lev:2 file:pbx_ael.c line:4092 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-Executed ast_walk_contexts();
-LOG: lev:2 file:pbx_ael.c line:4095 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 7 contexts, 37 extensions, 124 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-ntest12 b/1.4/pbx/ael/ael-test/ref.ael-ntest12
deleted file mode 100644
index 2c7c1ddfc..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-ntest12
+++ /dev/null
@@ -1,31 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)
-
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3803 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3810 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3818 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3821 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-Executed ast_context_create(conts, name=test1, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=771, priority=1, label=(null), callerid=(null), appl=Set, data=i=$[0], FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=771, priority=2, label=(null), callerid=(null), appl=GotoIf, data=$[
- ${i} <= 3]?3:6, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=771, priority=3, label=(null), callerid=(null), appl=NoOp, data=i is '${i}', FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=771, priority=4, label=(null), callerid=(null), appl=Set, data=i=$[ ${i} + 1 ], FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=771, priority=5, label=(null), callerid=(null), appl=Goto, data=2, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=771, priority=6, label=(null), callerid=(null), appl=NoOp, data=Finish for-test1-1, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=772, priority=1, label=(null), callerid=(null), appl=Set, data=i=$[0], FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=772, priority=2, label=(null), callerid=(null), appl=GotoIf, data=$[ ${i} <= 3]?3:6, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=772, priority=3, label=(null), callerid=(null), appl=NoOp, data=i is '${i}', FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=772, priority=4, label=(null), callerid=(null), appl=Set, data=i=$[ ${i} + 1 ], FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=772, priority=5, label=(null), callerid=(null), appl=Goto, data=2, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=test1, rep=0, exten=772, priority=6, label=(null), callerid=(null), appl=NoOp, data=Finish for-test1-2, FREE, registrar=pbx_ael);
-LOG: lev:2 file:pbx_ael.c line:3823 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-Executed ast_merge_contexts_and_delete();
-LOG: lev:2 file:pbx_ael.c line:3826 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-Executed ast_walk_contexts();
-LOG: lev:2 file:pbx_ael.c line:3829 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:479 func: main 1 contexts, 2 extensions, 12 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-ntest22 b/1.4/pbx/ael/ael-test/ref.ael-ntest22
deleted file mode 100644
index 9d2a10717..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-ntest22
+++ /dev/null
@@ -1,55 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)
-
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4048 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4055 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t1/a.ael, 41 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t1/b.ael, 42 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t1/c.ael, 106 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t2/d.ael, 41 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t2/e.ael, 42 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t2/f.ael, 82 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./qq.ael, 45 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t3/g.ael, 41 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t3/h.ael, 42 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t3/i.ael, 41 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./t3/j.ael, 43 chars
-LOG: lev:2 file:pbx_ael.c line:4063 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4066 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-Executed ast_context_create(conts, name=a, registrar=pbx_ael);
-Executed ast_context_create(conts, name=b, registrar=pbx_ael);
-Executed ast_context_create(conts, name=c, registrar=pbx_ael);
-Executed ast_context_create(conts, name=d, registrar=pbx_ael);
-Executed ast_context_create(conts, name=e, registrar=pbx_ael);
-Executed ast_context_create(conts, name=qq, registrar=pbx_ael);
-Executed ast_context_create(conts, name=f, registrar=pbx_ael);
-Executed ast_context_create(conts, name=g, registrar=pbx_ael);
-Executed ast_context_create(conts, name=h, registrar=pbx_ael);
-Executed ast_context_create(conts, name=i, registrar=pbx_ael);
-Executed ast_context_create(conts, name=j, registrar=pbx_ael);
-Executed ast_context_create(conts, name=w, registrar=pbx_ael);
-Executed ast_context_create(conts, name=z, registrar=pbx_ael);
-Executed ast_add_extension2(context=a, rep=0, exten=134, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| a, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=b, rep=0, exten=456, priority=1, label=(null), callerid=(null), appl=NoOp, data=hithere| b, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=c, rep=0, exten=567, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| c, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=d, rep=0, exten=134, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| d, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=e, rep=0, exten=456, priority=1, label=(null), callerid=(null), appl=NoOp, data=hithere| e, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=qq, rep=0, exten=567, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| qq, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=f, rep=0, exten=567, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| f, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=g, rep=0, exten=134, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| g, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=h, rep=0, exten=456, priority=1, label=(null), callerid=(null), appl=NoOp, data=hithere| h, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=i, rep=0, exten=134, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| i, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=j, rep=0, exten=567, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| j, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=w, rep=0, exten=890, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| w, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=z, rep=0, exten=123, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| z, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=z, rep=0, exten=124, priority=1, label=(null), callerid=(null), appl=NoOp, data=hi there| z, FREE, registrar=pbx_ael);
-LOG: lev:2 file:pbx_ael.c line:4068 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-Executed ast_merge_contexts_and_delete();
-LOG: lev:2 file:pbx_ael.c line:4071 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-Executed ast_walk_contexts();
-LOG: lev:2 file:pbx_ael.c line:4074 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 13 contexts, 13 extensions, 14 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-ntest23 b/1.4/pbx/ael/ael-test/ref.ael-ntest23
deleted file mode 100644
index 5f8f2a872..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-ntest23
+++ /dev/null
@@ -1,25 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)
-
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4094 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4101 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t1/a.ael, 41 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t1/b.ael, 42 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t1/c.ael, 110 chars
-LOG: lev:4 file:ael.y line:756 func: ael_yyerror ==== File: ./t1/c.ael, Line 3, Cols: 10-10: Error: syntax error, unexpected '(', expecting '{'
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t2/d.ael, 41 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t2/e.ael, 42 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t2/f.ael, 82 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./qq.ael, 45 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t3/g.ael, 41 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t3/h.ael, 42 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t3/i.ael, 41 chars
-LOG: lev:2 file:ael.flex line:663 func: setup_filestack --Read in included file ./t3/j.ael, 43 chars
-LOG: lev:4 file:ael.y line:756 func: ael_yyerror ==== File: ./t1/c.ael, Line 10, Cols: 10-10: Error: syntax error, unexpected '(', expecting '{'
-LOG: lev:2 file:pbx_ael.c line:4109 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:4 file:pbx_ael.c line:4122 func: pbx_load_module Sorry, but 2 syntax errors and 0 semantic errors were detected. It doesn't make sense to compile.
-LOG: lev:4 file:ael2_parse line:543 func: main 0 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-ntest9 b/1.4/pbx/ael/ael-test/ref.ael-ntest9
deleted file mode 100644
index 82f1d4220..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-ntest9
+++ /dev/null
@@ -1,24 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)
-
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3803 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3810 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3818 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3821 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-Executed ast_context_create(conts, name=workext, registrar=pbx_ael);
-Executed ast_context_add_ignorepat2(con, value=8, registrar=pbx_ael);
-Executed ast_context_add_ignorepat2(con, value=9, registrar=pbx_ael);
-Executed ast_add_extension2(context=workext, rep=0, exten=793, priority=1, label=(null), callerid=(null), appl=Set, data=QUERYSTRING=SELECT\ foo\,\ bar\ FROM\ foobar, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=workext, rep=0, exten=793, priority=2, label=(null), callerid=(null), appl=Verbose, data=2|${QUERYSTRING}, FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=workext, rep=0, exten=793, priority=3, label=(null), callerid=(null), appl=Set, data=query=$["SELECT foo\, bar FROM foobar" ], FREE, registrar=pbx_ael);
-Executed ast_add_extension2(context=workext, rep=0, exten=793, priority=4, label=(null), callerid=(null), appl=Verbose, data=2|${query}, FREE, registrar=pbx_ael);
-LOG: lev:2 file:pbx_ael.c line:3823 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-Executed ast_merge_contexts_and_delete();
-LOG: lev:2 file:pbx_ael.c line:3826 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-Executed ast_walk_contexts();
-LOG: lev:2 file:pbx_ael.c line:3829 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:479 func: main 1 contexts, 1 extensions, 4 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test1 b/1.4/pbx/ael/ael-test/ref.ael-test1
deleted file mode 100644
index 91ed1217f..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test1
+++ /dev/null
@@ -1,15 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4069 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4076 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4084 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 58-58: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:937 func: check_dow Warning: file ./extensions.ael, line 67-67: The day (m0n) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!
-LOG: lev:3 file:pbx_ael.c line:895 func: check_timerange Warning: file ./extensions.ael, line 78-78: The end time (25:00) is out of range!
-LOG: lev:2 file:pbx_ael.c line:4087 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4089 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4092 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4095 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 5 contexts, 16 extensions, 159 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test11 b/1.4/pbx/ael/ael-test/ref.ael-test11
deleted file mode 100644
index afccf9775..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test11
+++ /dev/null
@@ -1,14 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3978 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3985 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3993 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:4 file:pbx_ael.c line:1114 func: check_label Error: file ./extensions.ael, line 13-13: Duplicate label lab1! Previously defined at file ./extensions.ael, line 8.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 32-32: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 44-44: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 47-47: A default case was automatically added to the switch.
-LOG: lev:4 file:pbx_ael.c line:1114 func: check_label Error: file ./extensions.ael, line 49-49: Duplicate label ptr1! Previously defined at file ./extensions.ael, line 33.
-LOG: lev:4 file:pbx_ael.c line:4006 func: pbx_load_module Sorry, but 0 syntax errors and 2 semantic errors were detected. It doesn't make sense to compile.
-LOG: lev:4 file:ael2_parse line:523 func: main 0 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test14 b/1.4/pbx/ael/ael-test/ref.ael-test14
deleted file mode 100644
index 0850ecc7c..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test14
+++ /dev/null
@@ -1,12 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3978 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3985 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3993 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 13-13: A default case was automatically added to the switch.
-LOG: lev:4 file:pbx_ael.c line:1086 func: check_continue Error: file ./extensions.ael, line 15-15: 'continue' not in 'for' or 'while' statement!
-LOG: lev:4 file:pbx_ael.c line:1067 func: check_break Error: file ./extensions.ael, line 17-17: 'break' not in switch, for, or while statement!
-LOG: lev:4 file:pbx_ael.c line:4006 func: pbx_load_module Sorry, but 0 syntax errors and 2 semantic errors were detected. It doesn't make sense to compile.
-LOG: lev:4 file:ael2_parse line:523 func: main 0 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test15 b/1.4/pbx/ael/ael-test/ref.ael-test15
deleted file mode 100644
index 56ed6781c..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test15
+++ /dev/null
@@ -1,13 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3803 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3810 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3818 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3821 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:3706 func: ast_compile_ael2 Warning: file ./extensions.ael, line 8-13: Empty Extension!
-LOG: lev:2 file:pbx_ael.c line:3823 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3826 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3829 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:479 func: main 1 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test16 b/1.4/pbx/ael/ael-test/ref.ael-test16
deleted file mode 100644
index 3113b0d6c..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test16
+++ /dev/null
@@ -1,13 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4090 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4097 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4105 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4108 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:3685 func: add_extensions This file is Empty!
-LOG: lev:2 file:pbx_ael.c line:4110 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4113 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4116 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:543 func: main 1 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test18 b/1.4/pbx/ael/ael-test/ref.ael-test18
deleted file mode 100644
index a0972f55e..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test18
+++ /dev/null
@@ -1,12 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4069 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4076 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4084 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4087 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4089 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4092 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4095 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 1 contexts, 7 extensions, 27 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test19 b/1.4/pbx/ael/ael-test/ref.ael-test19
deleted file mode 100644
index c67dbe7c1..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test19
+++ /dev/null
@@ -1,14 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4090 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4097 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4105 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:4 file:pbx_ael.c line:2250 func: check_context_names Error: file ./extensions.ael, line 49-62: The context name (incoming) is also declared in file ./extensions.ael, line 62-69! (and neither is marked 'extend')
-LOG: lev:3 file:pbx_ael.c line:2234 func: check_switch_expr Warning: file ./extensions.ael, line 245-246: A default case was automatically added to the switch.
-LOG: lev:3 file:pbx_ael.c line:2347 func: check_pval_item Warning: file ./extensions.ael, line 312-312: macro call to non-existent funcA ! Hopefully it is present in extensions.conf!
-LOG: lev:3 file:pbx_ael.c line:2347 func: check_pval_item Warning: file ./extensions.ael, line 313-313: macro call to non-existent funcD ! Hopefully it is present in extensions.conf!
-LOG: lev:3 file:pbx_ael.c line:1287 func: check_goto Warning: file ./extensions.ael, line 319-319: goto: no context test5 could be found that matches the goto target!
-LOG: lev:4 file:pbx_ael.c line:4118 func: pbx_load_module Sorry, but 0 syntax errors and 1 semantic errors were detected. It doesn't make sense to compile.
-LOG: lev:4 file:ael2_parse line:543 func: main 0 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test2 b/1.4/pbx/ael/ael-test/ref.ael-test2
deleted file mode 100644
index e539f1dc9..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test2
+++ /dev/null
@@ -1,21 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4048 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4055 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./apptest.ael2, 3474 chars
-LOG: lev:3 file:ael.y line:529 func: ael_yyparse ==== File: ./apptest.ael2, Line 46, Cols: 8-11: Suggestion: Use the goto statement instead of the Goto() application call in AEL.
-LOG: lev:2 file:pbx_ael.c line:4063 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 35-35: application call to EndWhile needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 37-37: application call to ExecIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:1287 func: check_goto Warning: file ./apptest.ael2, line 46-46: goto: no context cont could be found that matches the goto target!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 47-47: application call to GotoIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 48-48: application call to GotoIfTime needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 85-85: application call to Random needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 141-141: application call to While needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:2 file:pbx_ael.c line:4066 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4068 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4071 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4074 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 1 contexts, 1 extensions, 142 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test20 b/1.4/pbx/ael/ael-test/ref.ael-test20
deleted file mode 100644
index 5b424e8ae..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test20
+++ /dev/null
@@ -1,12 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3915 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3922 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3930 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3933 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3935 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3938 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3941 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:512 func: main 1 contexts, 1 extensions, 1 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test3 b/1.4/pbx/ael/ael-test/ref.ael-test3
deleted file mode 100644
index c36cd0d3a..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test3
+++ /dev/null
@@ -1,18 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4069 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4076 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./include1.ael2, 78 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./include2.ael2, 98 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./include3.ael2, 57 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./include5.ael2, 56 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./include4.ael2, 87 chars
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./telemarket_torture.ael2, 28036 chars
-LOG: lev:2 file:pbx_ael.c line:4084 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4087 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4089 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4092 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4095 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 172 contexts, 934 extensions, 2402 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test4 b/1.4/pbx/ael/ael-test/ref.ael-test4
deleted file mode 100644
index e539f1dc9..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test4
+++ /dev/null
@@ -1,21 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4048 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4055 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:ael.flex line:654 func: setup_filestack --Read in included file ./apptest.ael2, 3474 chars
-LOG: lev:3 file:ael.y line:529 func: ael_yyparse ==== File: ./apptest.ael2, Line 46, Cols: 8-11: Suggestion: Use the goto statement instead of the Goto() application call in AEL.
-LOG: lev:2 file:pbx_ael.c line:4063 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 35-35: application call to EndWhile needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 37-37: application call to ExecIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:1287 func: check_goto Warning: file ./apptest.ael2, line 46-46: goto: no context cont could be found that matches the goto target!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 47-47: application call to GotoIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 48-48: application call to GotoIfTime needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 85-85: application call to Random needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:3 file:pbx_ael.c line:2392 func: check_pval_item Warning: file ./apptest.ael2, line 141-141: application call to While needs to be re-written using AEL if, while, goto, etc. keywords instead!
-LOG: lev:2 file:pbx_ael.c line:4066 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4068 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4071 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4074 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 1 contexts, 1 extensions, 142 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test5 b/1.4/pbx/ael/ael-test/ref.ael-test5
deleted file mode 100644
index e7550e842..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test5
+++ /dev/null
@@ -1,12 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4069 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4076 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4084 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4087 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4089 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4092 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4095 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 38 contexts, 91 extensions, 485 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test6 b/1.4/pbx/ael/ael-test/ref.ael-test6
deleted file mode 100644
index d63a78610..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test6
+++ /dev/null
@@ -1,17 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3978 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3985 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:4 file:ael.flex line:276 func: ael_yylex File=./extensions.ael, line=165, column=49: Mismatched '}' in expression!
-LOG: lev:4 file:ael.y line:755 func: ael_yyerror ==== File: ./extensions.ael, Line 165, Cols: 51-51: Error: syntax error, unexpected '=', expecting ')'
-LOG: lev:4 file:ael.flex line:276 func: ael_yylex File=./extensions.ael, line=174, column=49: Mismatched '}' in expression!
-LOG: lev:4 file:ael.y line:755 func: ael_yyerror ==== File: ./extensions.ael, Line 174, Cols: 51-51: Error: syntax error, unexpected '=', expecting ')'
-LOG: lev:4 file:ael.flex line:276 func: ael_yylex File=./extensions.ael, line=222, column=41: Mismatched '}' in expression!
-LOG: lev:4 file:ael.y line:755 func: ael_yyerror ==== File: ./extensions.ael, Line 222, Cols: 43-43: Error: syntax error, unexpected '=', expecting ')'
-LOG: lev:4 file:ael.y line:755 func: ael_yyerror ==== File: ./extensions.ael, Line 291, Cols: 21-28: Error: syntax error, unexpected word, expecting '(' or ';' or '=' or ':'
-LOG: lev:4 file:ael.y line:755 func: ael_yyerror ==== File: ./extensions.ael, Line 291, Cols: 32-32: Error: syntax error, unexpected '|', expecting '(' or ';' or '=' or ':'
-LOG: lev:2 file:pbx_ael.c line:3993 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:4 file:pbx_ael.c line:4006 func: pbx_load_module Sorry, but 5 syntax errors and 0 semantic errors were detected. It doesn't make sense to compile.
-LOG: lev:4 file:ael2_parse line:523 func: main 0 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test7 b/1.4/pbx/ael/ael-test/ref.ael-test7
deleted file mode 100644
index 0508b69ae..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test7
+++ /dev/null
@@ -1,14 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:3915 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:3922 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:3930 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:4 file:pbx_ael.c line:2339 func: check_pval_item Error: file ./extensions.ael, line 98-98: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
-LOG: lev:4 file:pbx_ael.c line:2339 func: check_pval_item Error: file ./extensions.ael, line 107-107: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
-LOG: lev:4 file:pbx_ael.c line:2339 func: check_pval_item Error: file ./extensions.ael, line 284-284: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
-LOG: lev:4 file:pbx_ael.c line:2339 func: check_pval_item Error: file ./extensions.ael, line 287-287: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
-LOG: lev:3 file:pbx_ael.c line:2320 func: check_pval_item Warning: file ./extensions.ael, line 452-452: macro call to non-existent std-exten-ael ! Hopefully it is present in extensions.conf!
-LOG: lev:4 file:pbx_ael.c line:3943 func: pbx_load_module Sorry, but 0 syntax errors and 4 semantic errors were detected. It doesn't make sense to compile.
-LOG: lev:4 file:ael2_parse line:512 func: main 0 contexts, 0 extensions, 0 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-test8 b/1.4/pbx/ael/ael-test/ref.ael-test8
deleted file mode 100644
index 267b6a579..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-test8
+++ /dev/null
@@ -1,12 +0,0 @@
-
-(If you find progress and other non-error messages irritating, you can use -q to suppress them)
-
-(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)
-LOG: lev:2 file:pbx_ael.c line:4069 func: pbx_load_module Starting AEL load process.
-LOG: lev:2 file:pbx_ael.c line:4076 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4084 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4087 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4089 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4092 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
-LOG: lev:2 file:pbx_ael.c line:4095 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
-LOG: lev:4 file:ael2_parse line:527 func: main 1 contexts, 7 extensions, 17 priorities
diff --git a/1.4/pbx/ael/ael-test/ref.ael-vtest13 b/1.4/pbx/ael/ael-test/ref.ael-vtest13
deleted file mode 100644
index 1e65df293..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-vtest13
+++ /dev/null
@@ -1,2951 +0,0 @@
-[globals]
-static=yes
-writeprotect=yes
-CONSOLE=Console/dsp
-IAXINFO=murf:tlhfckoct
-FWDNUMBER=544788
-FWDCIDNAME="Joe-Worker"
-FWDPASSWORD=zingledoodle
-FWDRINGS=Zap/6
-FWDVMBOX=1
-
-
-[macro-std-exten]
-exten => s,1,Set(ext=${ARG1})
-exten => s,2,Set(dev=${ARG2})
-exten => s,3,Dial(${dev}/${ext}|20)
-exten => s,4,Goto(sw-1-${DIALSTATUS}|10)
-exten => s,5,NoOp(Finish switch-std-exten-1)
-exten => a,1,VoiceMailMain(${ext})
-exten => _sw-1-.,10,Voicemail(u${ext})
-exten => _sw-1-.,11,Goto(s|5)
-exten => sw-1-,10,Goto(sw-1-.|10)
-exten => sw-1-ANSWER,10,Goto(s|5)
-exten => sw-1-NOANSWER,10,Voicemail(u${ext})
-exten => sw-1-NOANSWER,11,Goto(s|5)
-exten => sw-1-BUSY,10,Voicemail(b${ext})
-exten => sw-1-BUSY,11,Goto(s|5)
-
-
-[macro-std-priv-exten_1]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-3-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_1-3)
-exten => _sw-3-.,10,Voicemail(u${ext})
-exten => _sw-3-.,11,Goto(s|10)
-exten => sw-3-,10,Goto(sw-3-.|10)
-exten => sw-3-NOANSWER,10,Voicemail(u${ext})
-exten => sw-3-NOANSWER,11,Goto(s|10)
-exten => sw-3-ANSWER,10,Goto(s|10)
-exten => sw-3-BUSY,10,Voicemail(b${ext})
-exten => sw-3-BUSY,11,Goto(s|10)
-exten => sw-3-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-3-DONTCALL,11,Goto(s|10)
-exten => sw-3-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-3-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_2]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-4-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_2-4)
-exten => _sw-4-.,10,Voicemail(u${ext})
-exten => _sw-4-.,11,Goto(s|10)
-exten => sw-4-,10,Goto(sw-4-.|10)
-exten => sw-4-NOANSWER,10,Voicemail(u${ext})
-exten => sw-4-NOANSWER,11,Goto(s|10)
-exten => sw-4-ANSWER,10,Goto(s|10)
-exten => sw-4-BUSY,10,Voicemail(b${ext})
-exten => sw-4-BUSY,11,Goto(s|10)
-exten => sw-4-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-4-DONTCALL,11,Goto(s|10)
-exten => sw-4-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-4-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_3]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-5-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_3-5)
-exten => _sw-5-.,10,Voicemail(u${ext})
-exten => _sw-5-.,11,Goto(s|10)
-exten => sw-5-,10,Goto(sw-5-.|10)
-exten => sw-5-NOANSWER,10,Voicemail(u${ext})
-exten => sw-5-NOANSWER,11,Goto(s|10)
-exten => sw-5-ANSWER,10,Goto(s|10)
-exten => sw-5-BUSY,10,Voicemail(b${ext})
-exten => sw-5-BUSY,11,Goto(s|10)
-exten => sw-5-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-5-DONTCALL,11,Goto(s|10)
-exten => sw-5-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-5-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_4]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-6-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_4-6)
-exten => _sw-6-.,10,Voicemail(u${ext})
-exten => _sw-6-.,11,Goto(s|10)
-exten => sw-6-,10,Goto(sw-6-.|10)
-exten => sw-6-NOANSWER,10,Voicemail(u${ext})
-exten => sw-6-NOANSWER,11,Goto(s|10)
-exten => sw-6-ANSWER,10,Goto(s|10)
-exten => sw-6-BUSY,10,Voicemail(b${ext})
-exten => sw-6-BUSY,11,Goto(s|10)
-exten => sw-6-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-6-DONTCALL,11,Goto(s|10)
-exten => sw-6-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-6-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_5]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-7-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_5-7)
-exten => _sw-7-.,10,Voicemail(u${ext})
-exten => _sw-7-.,11,Goto(s|10)
-exten => sw-7-,10,Goto(sw-7-.|10)
-exten => sw-7-NOANSWER,10,Voicemail(u${ext})
-exten => sw-7-NOANSWER,11,Goto(s|10)
-exten => sw-7-ANSWER,10,Goto(s|10)
-exten => sw-7-BUSY,10,Voicemail(b${ext})
-exten => sw-7-BUSY,11,Goto(s|10)
-exten => sw-7-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-7-DONTCALL,11,Goto(s|10)
-exten => sw-7-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-7-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_6]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-8-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_6-8)
-exten => _sw-8-.,10,Voicemail(u${ext})
-exten => _sw-8-.,11,Goto(s|10)
-exten => sw-8-,10,Goto(sw-8-.|10)
-exten => sw-8-NOANSWER,10,Voicemail(u${ext})
-exten => sw-8-NOANSWER,11,Goto(s|10)
-exten => sw-8-ANSWER,10,Goto(s|10)
-exten => sw-8-BUSY,10,Voicemail(b${ext})
-exten => sw-8-BUSY,11,Goto(s|10)
-exten => sw-8-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-8-DONTCALL,11,Goto(s|10)
-exten => sw-8-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-8-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_7]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-9-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_7-9)
-exten => _sw-9-.,10,Voicemail(u${ext})
-exten => _sw-9-.,11,Goto(s|10)
-exten => sw-9-,10,Goto(sw-9-.|10)
-exten => sw-9-NOANSWER,10,Voicemail(u${ext})
-exten => sw-9-NOANSWER,11,Goto(s|10)
-exten => sw-9-ANSWER,10,Goto(s|10)
-exten => sw-9-BUSY,10,Voicemail(b${ext})
-exten => sw-9-BUSY,11,Goto(s|10)
-exten => sw-9-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-9-DONTCALL,11,Goto(s|10)
-exten => sw-9-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-9-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_8]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-10-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_8-10)
-exten => _sw-10-.,10,Voicemail(u${ext})
-exten => _sw-10-.,11,Goto(s|10)
-exten => sw-10-,10,Goto(sw-10-.|10)
-exten => sw-10-NOANSWER,10,Voicemail(u${ext})
-exten => sw-10-NOANSWER,11,Goto(s|10)
-exten => sw-10-ANSWER,10,Goto(s|10)
-exten => sw-10-BUSY,10,Voicemail(b${ext})
-exten => sw-10-BUSY,11,Goto(s|10)
-exten => sw-10-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-10-DONTCALL,11,Goto(s|10)
-exten => sw-10-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-10-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_9]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-11-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_9-11)
-exten => _sw-11-.,10,Voicemail(u${ext})
-exten => _sw-11-.,11,Goto(s|10)
-exten => sw-11-,10,Goto(sw-11-.|10)
-exten => sw-11-NOANSWER,10,Voicemail(u${ext})
-exten => sw-11-NOANSWER,11,Goto(s|10)
-exten => sw-11-ANSWER,10,Goto(s|10)
-exten => sw-11-BUSY,10,Voicemail(b${ext})
-exten => sw-11-BUSY,11,Goto(s|10)
-exten => sw-11-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-11-DONTCALL,11,Goto(s|10)
-exten => sw-11-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-11-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_10]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-12-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_10-12)
-exten => _sw-12-.,10,Voicemail(u${ext})
-exten => _sw-12-.,11,Goto(s|10)
-exten => sw-12-,10,Goto(sw-12-.|10)
-exten => sw-12-NOANSWER,10,Voicemail(u${ext})
-exten => sw-12-NOANSWER,11,Goto(s|10)
-exten => sw-12-ANSWER,10,Goto(s|10)
-exten => sw-12-BUSY,10,Voicemail(b${ext})
-exten => sw-12-BUSY,11,Goto(s|10)
-exten => sw-12-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-12-DONTCALL,11,Goto(s|10)
-exten => sw-12-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-12-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_11]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-13-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_11-13)
-exten => _sw-13-.,10,Voicemail(u${ext})
-exten => _sw-13-.,11,Goto(s|10)
-exten => sw-13-,10,Goto(sw-13-.|10)
-exten => sw-13-NOANSWER,10,Voicemail(u${ext})
-exten => sw-13-NOANSWER,11,Goto(s|10)
-exten => sw-13-ANSWER,10,Goto(s|10)
-exten => sw-13-BUSY,10,Voicemail(b${ext})
-exten => sw-13-BUSY,11,Goto(s|10)
-exten => sw-13-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-13-DONTCALL,11,Goto(s|10)
-exten => sw-13-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-13-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_12]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-14-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_12-14)
-exten => _sw-14-.,10,Voicemail(u${ext})
-exten => _sw-14-.,11,Goto(s|10)
-exten => sw-14-,10,Goto(sw-14-.|10)
-exten => sw-14-NOANSWER,10,Voicemail(u${ext})
-exten => sw-14-NOANSWER,11,Goto(s|10)
-exten => sw-14-ANSWER,10,Goto(s|10)
-exten => sw-14-BUSY,10,Voicemail(b${ext})
-exten => sw-14-BUSY,11,Goto(s|10)
-exten => sw-14-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-14-DONTCALL,11,Goto(s|10)
-exten => sw-14-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-14-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_13]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-15-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_13-15)
-exten => _sw-15-.,10,Voicemail(u${ext})
-exten => _sw-15-.,11,Goto(s|10)
-exten => sw-15-,10,Goto(sw-15-.|10)
-exten => sw-15-NOANSWER,10,Voicemail(u${ext})
-exten => sw-15-NOANSWER,11,Goto(s|10)
-exten => sw-15-ANSWER,10,Goto(s|10)
-exten => sw-15-BUSY,10,Voicemail(b${ext})
-exten => sw-15-BUSY,11,Goto(s|10)
-exten => sw-15-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-15-DONTCALL,11,Goto(s|10)
-exten => sw-15-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-15-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_14]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-16-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_14-16)
-exten => _sw-16-.,10,Voicemail(u${ext})
-exten => _sw-16-.,11,Goto(s|10)
-exten => sw-16-,10,Goto(sw-16-.|10)
-exten => sw-16-NOANSWER,10,Voicemail(u${ext})
-exten => sw-16-NOANSWER,11,Goto(s|10)
-exten => sw-16-ANSWER,10,Goto(s|10)
-exten => sw-16-BUSY,10,Voicemail(b${ext})
-exten => sw-16-BUSY,11,Goto(s|10)
-exten => sw-16-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-16-DONTCALL,11,Goto(s|10)
-exten => sw-16-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-16-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_15]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-17-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_15-17)
-exten => _sw-17-.,10,Voicemail(u${ext})
-exten => _sw-17-.,11,Goto(s|10)
-exten => sw-17-,10,Goto(sw-17-.|10)
-exten => sw-17-NOANSWER,10,Voicemail(u${ext})
-exten => sw-17-NOANSWER,11,Goto(s|10)
-exten => sw-17-ANSWER,10,Goto(s|10)
-exten => sw-17-BUSY,10,Voicemail(b${ext})
-exten => sw-17-BUSY,11,Goto(s|10)
-exten => sw-17-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-17-DONTCALL,11,Goto(s|10)
-exten => sw-17-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-17-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_16]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-18-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_16-18)
-exten => _sw-18-.,10,Voicemail(u${ext})
-exten => _sw-18-.,11,Goto(s|10)
-exten => sw-18-,10,Goto(sw-18-.|10)
-exten => sw-18-NOANSWER,10,Voicemail(u${ext})
-exten => sw-18-NOANSWER,11,Goto(s|10)
-exten => sw-18-ANSWER,10,Goto(s|10)
-exten => sw-18-BUSY,10,Voicemail(b${ext})
-exten => sw-18-BUSY,11,Goto(s|10)
-exten => sw-18-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-18-DONTCALL,11,Goto(s|10)
-exten => sw-18-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-18-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_17]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-19-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_17-19)
-exten => _sw-19-.,10,Voicemail(u${ext})
-exten => _sw-19-.,11,Goto(s|10)
-exten => sw-19-,10,Goto(sw-19-.|10)
-exten => sw-19-NOANSWER,10,Voicemail(u${ext})
-exten => sw-19-NOANSWER,11,Goto(s|10)
-exten => sw-19-ANSWER,10,Goto(s|10)
-exten => sw-19-BUSY,10,Voicemail(b${ext})
-exten => sw-19-BUSY,11,Goto(s|10)
-exten => sw-19-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-19-DONTCALL,11,Goto(s|10)
-exten => sw-19-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-19-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_18]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-20-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_18-20)
-exten => _sw-20-.,10,Voicemail(u${ext})
-exten => _sw-20-.,11,Goto(s|10)
-exten => sw-20-,10,Goto(sw-20-.|10)
-exten => sw-20-NOANSWER,10,Voicemail(u${ext})
-exten => sw-20-NOANSWER,11,Goto(s|10)
-exten => sw-20-ANSWER,10,Goto(s|10)
-exten => sw-20-BUSY,10,Voicemail(b${ext})
-exten => sw-20-BUSY,11,Goto(s|10)
-exten => sw-20-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-20-DONTCALL,11,Goto(s|10)
-exten => sw-20-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-20-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_19]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-21-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_19-21)
-exten => _sw-21-.,10,Voicemail(u${ext})
-exten => _sw-21-.,11,Goto(s|10)
-exten => sw-21-,10,Goto(sw-21-.|10)
-exten => sw-21-NOANSWER,10,Voicemail(u${ext})
-exten => sw-21-NOANSWER,11,Goto(s|10)
-exten => sw-21-ANSWER,10,Goto(s|10)
-exten => sw-21-BUSY,10,Voicemail(b${ext})
-exten => sw-21-BUSY,11,Goto(s|10)
-exten => sw-21-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-21-DONTCALL,11,Goto(s|10)
-exten => sw-21-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-21-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_20]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-22-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_20-22)
-exten => _sw-22-.,10,Voicemail(u${ext})
-exten => _sw-22-.,11,Goto(s|10)
-exten => sw-22-,10,Goto(sw-22-.|10)
-exten => sw-22-NOANSWER,10,Voicemail(u${ext})
-exten => sw-22-NOANSWER,11,Goto(s|10)
-exten => sw-22-ANSWER,10,Goto(s|10)
-exten => sw-22-BUSY,10,Voicemail(b${ext})
-exten => sw-22-BUSY,11,Goto(s|10)
-exten => sw-22-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-22-DONTCALL,11,Goto(s|10)
-exten => sw-22-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-22-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_21]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-23-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_21-23)
-exten => _sw-23-.,10,Voicemail(u${ext})
-exten => _sw-23-.,11,Goto(s|10)
-exten => sw-23-,10,Goto(sw-23-.|10)
-exten => sw-23-NOANSWER,10,Voicemail(u${ext})
-exten => sw-23-NOANSWER,11,Goto(s|10)
-exten => sw-23-ANSWER,10,Goto(s|10)
-exten => sw-23-BUSY,10,Voicemail(b${ext})
-exten => sw-23-BUSY,11,Goto(s|10)
-exten => sw-23-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-23-DONTCALL,11,Goto(s|10)
-exten => sw-23-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-23-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_22]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-24-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_22-24)
-exten => _sw-24-.,10,Voicemail(u${ext})
-exten => _sw-24-.,11,Goto(s|10)
-exten => sw-24-,10,Goto(sw-24-.|10)
-exten => sw-24-NOANSWER,10,Voicemail(u${ext})
-exten => sw-24-NOANSWER,11,Goto(s|10)
-exten => sw-24-ANSWER,10,Goto(s|10)
-exten => sw-24-BUSY,10,Voicemail(b${ext})
-exten => sw-24-BUSY,11,Goto(s|10)
-exten => sw-24-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-24-DONTCALL,11,Goto(s|10)
-exten => sw-24-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-24-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_23]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-25-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_23-25)
-exten => _sw-25-.,10,Voicemail(u${ext})
-exten => _sw-25-.,11,Goto(s|10)
-exten => sw-25-,10,Goto(sw-25-.|10)
-exten => sw-25-NOANSWER,10,Voicemail(u${ext})
-exten => sw-25-NOANSWER,11,Goto(s|10)
-exten => sw-25-ANSWER,10,Goto(s|10)
-exten => sw-25-BUSY,10,Voicemail(b${ext})
-exten => sw-25-BUSY,11,Goto(s|10)
-exten => sw-25-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-25-DONTCALL,11,Goto(s|10)
-exten => sw-25-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-25-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_24]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-26-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_24-26)
-exten => _sw-26-.,10,Voicemail(u${ext})
-exten => _sw-26-.,11,Goto(s|10)
-exten => sw-26-,10,Goto(sw-26-.|10)
-exten => sw-26-NOANSWER,10,Voicemail(u${ext})
-exten => sw-26-NOANSWER,11,Goto(s|10)
-exten => sw-26-ANSWER,10,Goto(s|10)
-exten => sw-26-BUSY,10,Voicemail(b${ext})
-exten => sw-26-BUSY,11,Goto(s|10)
-exten => sw-26-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-26-DONTCALL,11,Goto(s|10)
-exten => sw-26-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-26-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_25]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-27-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_25-27)
-exten => _sw-27-.,10,Voicemail(u${ext})
-exten => _sw-27-.,11,Goto(s|10)
-exten => sw-27-,10,Goto(sw-27-.|10)
-exten => sw-27-NOANSWER,10,Voicemail(u${ext})
-exten => sw-27-NOANSWER,11,Goto(s|10)
-exten => sw-27-ANSWER,10,Goto(s|10)
-exten => sw-27-BUSY,10,Voicemail(b${ext})
-exten => sw-27-BUSY,11,Goto(s|10)
-exten => sw-27-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-27-DONTCALL,11,Goto(s|10)
-exten => sw-27-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-27-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_26]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-28-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_26-28)
-exten => _sw-28-.,10,Voicemail(u${ext})
-exten => _sw-28-.,11,Goto(s|10)
-exten => sw-28-,10,Goto(sw-28-.|10)
-exten => sw-28-NOANSWER,10,Voicemail(u${ext})
-exten => sw-28-NOANSWER,11,Goto(s|10)
-exten => sw-28-ANSWER,10,Goto(s|10)
-exten => sw-28-BUSY,10,Voicemail(b${ext})
-exten => sw-28-BUSY,11,Goto(s|10)
-exten => sw-28-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-28-DONTCALL,11,Goto(s|10)
-exten => sw-28-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-28-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_27]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-29-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_27-29)
-exten => _sw-29-.,10,Voicemail(u${ext})
-exten => _sw-29-.,11,Goto(s|10)
-exten => sw-29-,10,Goto(sw-29-.|10)
-exten => sw-29-NOANSWER,10,Voicemail(u${ext})
-exten => sw-29-NOANSWER,11,Goto(s|10)
-exten => sw-29-ANSWER,10,Goto(s|10)
-exten => sw-29-BUSY,10,Voicemail(b${ext})
-exten => sw-29-BUSY,11,Goto(s|10)
-exten => sw-29-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-29-DONTCALL,11,Goto(s|10)
-exten => sw-29-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-29-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_28]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-30-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_28-30)
-exten => _sw-30-.,10,Voicemail(u${ext})
-exten => _sw-30-.,11,Goto(s|10)
-exten => sw-30-,10,Goto(sw-30-.|10)
-exten => sw-30-NOANSWER,10,Voicemail(u${ext})
-exten => sw-30-NOANSWER,11,Goto(s|10)
-exten => sw-30-ANSWER,10,Goto(s|10)
-exten => sw-30-BUSY,10,Voicemail(b${ext})
-exten => sw-30-BUSY,11,Goto(s|10)
-exten => sw-30-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-30-DONTCALL,11,Goto(s|10)
-exten => sw-30-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-30-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_29]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-31-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_29-31)
-exten => _sw-31-.,10,Voicemail(u${ext})
-exten => _sw-31-.,11,Goto(s|10)
-exten => sw-31-,10,Goto(sw-31-.|10)
-exten => sw-31-NOANSWER,10,Voicemail(u${ext})
-exten => sw-31-NOANSWER,11,Goto(s|10)
-exten => sw-31-ANSWER,10,Goto(s|10)
-exten => sw-31-BUSY,10,Voicemail(b${ext})
-exten => sw-31-BUSY,11,Goto(s|10)
-exten => sw-31-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-31-DONTCALL,11,Goto(s|10)
-exten => sw-31-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-31-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_30]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-32-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_30-32)
-exten => _sw-32-.,10,Voicemail(u${ext})
-exten => _sw-32-.,11,Goto(s|10)
-exten => sw-32-,10,Goto(sw-32-.|10)
-exten => sw-32-NOANSWER,10,Voicemail(u${ext})
-exten => sw-32-NOANSWER,11,Goto(s|10)
-exten => sw-32-ANSWER,10,Goto(s|10)
-exten => sw-32-BUSY,10,Voicemail(b${ext})
-exten => sw-32-BUSY,11,Goto(s|10)
-exten => sw-32-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-32-DONTCALL,11,Goto(s|10)
-exten => sw-32-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-32-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_31]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-33-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_31-33)
-exten => _sw-33-.,10,Voicemail(u${ext})
-exten => _sw-33-.,11,Goto(s|10)
-exten => sw-33-,10,Goto(sw-33-.|10)
-exten => sw-33-NOANSWER,10,Voicemail(u${ext})
-exten => sw-33-NOANSWER,11,Goto(s|10)
-exten => sw-33-ANSWER,10,Goto(s|10)
-exten => sw-33-BUSY,10,Voicemail(b${ext})
-exten => sw-33-BUSY,11,Goto(s|10)
-exten => sw-33-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-33-DONTCALL,11,Goto(s|10)
-exten => sw-33-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-33-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_32]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-34-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_32-34)
-exten => _sw-34-.,10,Voicemail(u${ext})
-exten => _sw-34-.,11,Goto(s|10)
-exten => sw-34-,10,Goto(sw-34-.|10)
-exten => sw-34-NOANSWER,10,Voicemail(u${ext})
-exten => sw-34-NOANSWER,11,Goto(s|10)
-exten => sw-34-ANSWER,10,Goto(s|10)
-exten => sw-34-BUSY,10,Voicemail(b${ext})
-exten => sw-34-BUSY,11,Goto(s|10)
-exten => sw-34-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-34-DONTCALL,11,Goto(s|10)
-exten => sw-34-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-34-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_33]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-35-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_33-35)
-exten => _sw-35-.,10,Voicemail(u${ext})
-exten => _sw-35-.,11,Goto(s|10)
-exten => sw-35-,10,Goto(sw-35-.|10)
-exten => sw-35-NOANSWER,10,Voicemail(u${ext})
-exten => sw-35-NOANSWER,11,Goto(s|10)
-exten => sw-35-ANSWER,10,Goto(s|10)
-exten => sw-35-BUSY,10,Voicemail(b${ext})
-exten => sw-35-BUSY,11,Goto(s|10)
-exten => sw-35-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-35-DONTCALL,11,Goto(s|10)
-exten => sw-35-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-35-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_34]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-36-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_34-36)
-exten => _sw-36-.,10,Voicemail(u${ext})
-exten => _sw-36-.,11,Goto(s|10)
-exten => sw-36-,10,Goto(sw-36-.|10)
-exten => sw-36-NOANSWER,10,Voicemail(u${ext})
-exten => sw-36-NOANSWER,11,Goto(s|10)
-exten => sw-36-ANSWER,10,Goto(s|10)
-exten => sw-36-BUSY,10,Voicemail(b${ext})
-exten => sw-36-BUSY,11,Goto(s|10)
-exten => sw-36-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-36-DONTCALL,11,Goto(s|10)
-exten => sw-36-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-36-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_35]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-37-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_35-37)
-exten => _sw-37-.,10,Voicemail(u${ext})
-exten => _sw-37-.,11,Goto(s|10)
-exten => sw-37-,10,Goto(sw-37-.|10)
-exten => sw-37-NOANSWER,10,Voicemail(u${ext})
-exten => sw-37-NOANSWER,11,Goto(s|10)
-exten => sw-37-ANSWER,10,Goto(s|10)
-exten => sw-37-BUSY,10,Voicemail(b${ext})
-exten => sw-37-BUSY,11,Goto(s|10)
-exten => sw-37-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-37-DONTCALL,11,Goto(s|10)
-exten => sw-37-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-37-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_36]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-38-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_36-38)
-exten => _sw-38-.,10,Voicemail(u${ext})
-exten => _sw-38-.,11,Goto(s|10)
-exten => sw-38-,10,Goto(sw-38-.|10)
-exten => sw-38-NOANSWER,10,Voicemail(u${ext})
-exten => sw-38-NOANSWER,11,Goto(s|10)
-exten => sw-38-ANSWER,10,Goto(s|10)
-exten => sw-38-BUSY,10,Voicemail(b${ext})
-exten => sw-38-BUSY,11,Goto(s|10)
-exten => sw-38-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-38-DONTCALL,11,Goto(s|10)
-exten => sw-38-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-38-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_37]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-39-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_37-39)
-exten => _sw-39-.,10,Voicemail(u${ext})
-exten => _sw-39-.,11,Goto(s|10)
-exten => sw-39-,10,Goto(sw-39-.|10)
-exten => sw-39-NOANSWER,10,Voicemail(u${ext})
-exten => sw-39-NOANSWER,11,Goto(s|10)
-exten => sw-39-ANSWER,10,Goto(s|10)
-exten => sw-39-BUSY,10,Voicemail(b${ext})
-exten => sw-39-BUSY,11,Goto(s|10)
-exten => sw-39-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-39-DONTCALL,11,Goto(s|10)
-exten => sw-39-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-39-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_38]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-40-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_38-40)
-exten => _sw-40-.,10,Voicemail(u${ext})
-exten => _sw-40-.,11,Goto(s|10)
-exten => sw-40-,10,Goto(sw-40-.|10)
-exten => sw-40-NOANSWER,10,Voicemail(u${ext})
-exten => sw-40-NOANSWER,11,Goto(s|10)
-exten => sw-40-ANSWER,10,Goto(s|10)
-exten => sw-40-BUSY,10,Voicemail(b${ext})
-exten => sw-40-BUSY,11,Goto(s|10)
-exten => sw-40-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-40-DONTCALL,11,Goto(s|10)
-exten => sw-40-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-40-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_39]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-41-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_39-41)
-exten => _sw-41-.,10,Voicemail(u${ext})
-exten => _sw-41-.,11,Goto(s|10)
-exten => sw-41-,10,Goto(sw-41-.|10)
-exten => sw-41-NOANSWER,10,Voicemail(u${ext})
-exten => sw-41-NOANSWER,11,Goto(s|10)
-exten => sw-41-ANSWER,10,Goto(s|10)
-exten => sw-41-BUSY,10,Voicemail(b${ext})
-exten => sw-41-BUSY,11,Goto(s|10)
-exten => sw-41-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-41-DONTCALL,11,Goto(s|10)
-exten => sw-41-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-41-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_40]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-42-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_40-42)
-exten => _sw-42-.,10,Voicemail(u${ext})
-exten => _sw-42-.,11,Goto(s|10)
-exten => sw-42-,10,Goto(sw-42-.|10)
-exten => sw-42-NOANSWER,10,Voicemail(u${ext})
-exten => sw-42-NOANSWER,11,Goto(s|10)
-exten => sw-42-ANSWER,10,Goto(s|10)
-exten => sw-42-BUSY,10,Voicemail(b${ext})
-exten => sw-42-BUSY,11,Goto(s|10)
-exten => sw-42-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-42-DONTCALL,11,Goto(s|10)
-exten => sw-42-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-42-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_41]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-43-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_41-43)
-exten => _sw-43-.,10,Voicemail(u${ext})
-exten => _sw-43-.,11,Goto(s|10)
-exten => sw-43-,10,Goto(sw-43-.|10)
-exten => sw-43-NOANSWER,10,Voicemail(u${ext})
-exten => sw-43-NOANSWER,11,Goto(s|10)
-exten => sw-43-ANSWER,10,Goto(s|10)
-exten => sw-43-BUSY,10,Voicemail(b${ext})
-exten => sw-43-BUSY,11,Goto(s|10)
-exten => sw-43-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-43-DONTCALL,11,Goto(s|10)
-exten => sw-43-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-43-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_42]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-44-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_42-44)
-exten => _sw-44-.,10,Voicemail(u${ext})
-exten => _sw-44-.,11,Goto(s|10)
-exten => sw-44-,10,Goto(sw-44-.|10)
-exten => sw-44-NOANSWER,10,Voicemail(u${ext})
-exten => sw-44-NOANSWER,11,Goto(s|10)
-exten => sw-44-ANSWER,10,Goto(s|10)
-exten => sw-44-BUSY,10,Voicemail(b${ext})
-exten => sw-44-BUSY,11,Goto(s|10)
-exten => sw-44-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-44-DONTCALL,11,Goto(s|10)
-exten => sw-44-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-44-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_43]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-45-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_43-45)
-exten => _sw-45-.,10,Voicemail(u${ext})
-exten => _sw-45-.,11,Goto(s|10)
-exten => sw-45-,10,Goto(sw-45-.|10)
-exten => sw-45-NOANSWER,10,Voicemail(u${ext})
-exten => sw-45-NOANSWER,11,Goto(s|10)
-exten => sw-45-ANSWER,10,Goto(s|10)
-exten => sw-45-BUSY,10,Voicemail(b${ext})
-exten => sw-45-BUSY,11,Goto(s|10)
-exten => sw-45-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-45-DONTCALL,11,Goto(s|10)
-exten => sw-45-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-45-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_44]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-46-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_44-46)
-exten => _sw-46-.,10,Voicemail(u${ext})
-exten => _sw-46-.,11,Goto(s|10)
-exten => sw-46-,10,Goto(sw-46-.|10)
-exten => sw-46-NOANSWER,10,Voicemail(u${ext})
-exten => sw-46-NOANSWER,11,Goto(s|10)
-exten => sw-46-ANSWER,10,Goto(s|10)
-exten => sw-46-BUSY,10,Voicemail(b${ext})
-exten => sw-46-BUSY,11,Goto(s|10)
-exten => sw-46-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-46-DONTCALL,11,Goto(s|10)
-exten => sw-46-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-46-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_45]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-47-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_45-47)
-exten => _sw-47-.,10,Voicemail(u${ext})
-exten => _sw-47-.,11,Goto(s|10)
-exten => sw-47-,10,Goto(sw-47-.|10)
-exten => sw-47-NOANSWER,10,Voicemail(u${ext})
-exten => sw-47-NOANSWER,11,Goto(s|10)
-exten => sw-47-ANSWER,10,Goto(s|10)
-exten => sw-47-BUSY,10,Voicemail(b${ext})
-exten => sw-47-BUSY,11,Goto(s|10)
-exten => sw-47-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-47-DONTCALL,11,Goto(s|10)
-exten => sw-47-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-47-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_46]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-48-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_46-48)
-exten => _sw-48-.,10,Voicemail(u${ext})
-exten => _sw-48-.,11,Goto(s|10)
-exten => sw-48-,10,Goto(sw-48-.|10)
-exten => sw-48-NOANSWER,10,Voicemail(u${ext})
-exten => sw-48-NOANSWER,11,Goto(s|10)
-exten => sw-48-ANSWER,10,Goto(s|10)
-exten => sw-48-BUSY,10,Voicemail(b${ext})
-exten => sw-48-BUSY,11,Goto(s|10)
-exten => sw-48-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-48-DONTCALL,11,Goto(s|10)
-exten => sw-48-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-48-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_47]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-49-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_47-49)
-exten => _sw-49-.,10,Voicemail(u${ext})
-exten => _sw-49-.,11,Goto(s|10)
-exten => sw-49-,10,Goto(sw-49-.|10)
-exten => sw-49-NOANSWER,10,Voicemail(u${ext})
-exten => sw-49-NOANSWER,11,Goto(s|10)
-exten => sw-49-ANSWER,10,Goto(s|10)
-exten => sw-49-BUSY,10,Voicemail(b${ext})
-exten => sw-49-BUSY,11,Goto(s|10)
-exten => sw-49-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-49-DONTCALL,11,Goto(s|10)
-exten => sw-49-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-49-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_48]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-50-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_48-50)
-exten => _sw-50-.,10,Voicemail(u${ext})
-exten => _sw-50-.,11,Goto(s|10)
-exten => sw-50-,10,Goto(sw-50-.|10)
-exten => sw-50-NOANSWER,10,Voicemail(u${ext})
-exten => sw-50-NOANSWER,11,Goto(s|10)
-exten => sw-50-ANSWER,10,Goto(s|10)
-exten => sw-50-BUSY,10,Voicemail(b${ext})
-exten => sw-50-BUSY,11,Goto(s|10)
-exten => sw-50-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-50-DONTCALL,11,Goto(s|10)
-exten => sw-50-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-50-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_49]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-51-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_49-51)
-exten => _sw-51-.,10,Voicemail(u${ext})
-exten => _sw-51-.,11,Goto(s|10)
-exten => sw-51-,10,Goto(sw-51-.|10)
-exten => sw-51-NOANSWER,10,Voicemail(u${ext})
-exten => sw-51-NOANSWER,11,Goto(s|10)
-exten => sw-51-ANSWER,10,Goto(s|10)
-exten => sw-51-BUSY,10,Voicemail(b${ext})
-exten => sw-51-BUSY,11,Goto(s|10)
-exten => sw-51-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-51-DONTCALL,11,Goto(s|10)
-exten => sw-51-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-51-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_50]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-52-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_50-52)
-exten => _sw-52-.,10,Voicemail(u${ext})
-exten => _sw-52-.,11,Goto(s|10)
-exten => sw-52-,10,Goto(sw-52-.|10)
-exten => sw-52-NOANSWER,10,Voicemail(u${ext})
-exten => sw-52-NOANSWER,11,Goto(s|10)
-exten => sw-52-ANSWER,10,Goto(s|10)
-exten => sw-52-BUSY,10,Voicemail(b${ext})
-exten => sw-52-BUSY,11,Goto(s|10)
-exten => sw-52-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-52-DONTCALL,11,Goto(s|10)
-exten => sw-52-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-52-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_51]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-53-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_51-53)
-exten => _sw-53-.,10,Voicemail(u${ext})
-exten => _sw-53-.,11,Goto(s|10)
-exten => sw-53-,10,Goto(sw-53-.|10)
-exten => sw-53-NOANSWER,10,Voicemail(u${ext})
-exten => sw-53-NOANSWER,11,Goto(s|10)
-exten => sw-53-ANSWER,10,Goto(s|10)
-exten => sw-53-BUSY,10,Voicemail(b${ext})
-exten => sw-53-BUSY,11,Goto(s|10)
-exten => sw-53-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-53-DONTCALL,11,Goto(s|10)
-exten => sw-53-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-53-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_52]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-54-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_52-54)
-exten => _sw-54-.,10,Voicemail(u${ext})
-exten => _sw-54-.,11,Goto(s|10)
-exten => sw-54-,10,Goto(sw-54-.|10)
-exten => sw-54-NOANSWER,10,Voicemail(u${ext})
-exten => sw-54-NOANSWER,11,Goto(s|10)
-exten => sw-54-ANSWER,10,Goto(s|10)
-exten => sw-54-BUSY,10,Voicemail(b${ext})
-exten => sw-54-BUSY,11,Goto(s|10)
-exten => sw-54-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-54-DONTCALL,11,Goto(s|10)
-exten => sw-54-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-54-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_53]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-55-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_53-55)
-exten => _sw-55-.,10,Voicemail(u${ext})
-exten => _sw-55-.,11,Goto(s|10)
-exten => sw-55-,10,Goto(sw-55-.|10)
-exten => sw-55-NOANSWER,10,Voicemail(u${ext})
-exten => sw-55-NOANSWER,11,Goto(s|10)
-exten => sw-55-ANSWER,10,Goto(s|10)
-exten => sw-55-BUSY,10,Voicemail(b${ext})
-exten => sw-55-BUSY,11,Goto(s|10)
-exten => sw-55-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-55-DONTCALL,11,Goto(s|10)
-exten => sw-55-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-55-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_54]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-56-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_54-56)
-exten => _sw-56-.,10,Voicemail(u${ext})
-exten => _sw-56-.,11,Goto(s|10)
-exten => sw-56-,10,Goto(sw-56-.|10)
-exten => sw-56-NOANSWER,10,Voicemail(u${ext})
-exten => sw-56-NOANSWER,11,Goto(s|10)
-exten => sw-56-ANSWER,10,Goto(s|10)
-exten => sw-56-BUSY,10,Voicemail(b${ext})
-exten => sw-56-BUSY,11,Goto(s|10)
-exten => sw-56-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-56-DONTCALL,11,Goto(s|10)
-exten => sw-56-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-56-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_55]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-57-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_55-57)
-exten => _sw-57-.,10,Voicemail(u${ext})
-exten => _sw-57-.,11,Goto(s|10)
-exten => sw-57-,10,Goto(sw-57-.|10)
-exten => sw-57-NOANSWER,10,Voicemail(u${ext})
-exten => sw-57-NOANSWER,11,Goto(s|10)
-exten => sw-57-ANSWER,10,Goto(s|10)
-exten => sw-57-BUSY,10,Voicemail(b${ext})
-exten => sw-57-BUSY,11,Goto(s|10)
-exten => sw-57-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-57-DONTCALL,11,Goto(s|10)
-exten => sw-57-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-57-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_56]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-58-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_56-58)
-exten => _sw-58-.,10,Voicemail(u${ext})
-exten => _sw-58-.,11,Goto(s|10)
-exten => sw-58-,10,Goto(sw-58-.|10)
-exten => sw-58-NOANSWER,10,Voicemail(u${ext})
-exten => sw-58-NOANSWER,11,Goto(s|10)
-exten => sw-58-ANSWER,10,Goto(s|10)
-exten => sw-58-BUSY,10,Voicemail(b${ext})
-exten => sw-58-BUSY,11,Goto(s|10)
-exten => sw-58-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-58-DONTCALL,11,Goto(s|10)
-exten => sw-58-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-58-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_57]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-59-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_57-59)
-exten => _sw-59-.,10,Voicemail(u${ext})
-exten => _sw-59-.,11,Goto(s|10)
-exten => sw-59-,10,Goto(sw-59-.|10)
-exten => sw-59-NOANSWER,10,Voicemail(u${ext})
-exten => sw-59-NOANSWER,11,Goto(s|10)
-exten => sw-59-ANSWER,10,Goto(s|10)
-exten => sw-59-BUSY,10,Voicemail(b${ext})
-exten => sw-59-BUSY,11,Goto(s|10)
-exten => sw-59-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-59-DONTCALL,11,Goto(s|10)
-exten => sw-59-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-59-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_58]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-60-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_58-60)
-exten => _sw-60-.,10,Voicemail(u${ext})
-exten => _sw-60-.,11,Goto(s|10)
-exten => sw-60-,10,Goto(sw-60-.|10)
-exten => sw-60-NOANSWER,10,Voicemail(u${ext})
-exten => sw-60-NOANSWER,11,Goto(s|10)
-exten => sw-60-ANSWER,10,Goto(s|10)
-exten => sw-60-BUSY,10,Voicemail(b${ext})
-exten => sw-60-BUSY,11,Goto(s|10)
-exten => sw-60-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-60-DONTCALL,11,Goto(s|10)
-exten => sw-60-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-60-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_59]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-61-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_59-61)
-exten => _sw-61-.,10,Voicemail(u${ext})
-exten => _sw-61-.,11,Goto(s|10)
-exten => sw-61-,10,Goto(sw-61-.|10)
-exten => sw-61-NOANSWER,10,Voicemail(u${ext})
-exten => sw-61-NOANSWER,11,Goto(s|10)
-exten => sw-61-ANSWER,10,Goto(s|10)
-exten => sw-61-BUSY,10,Voicemail(b${ext})
-exten => sw-61-BUSY,11,Goto(s|10)
-exten => sw-61-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-61-DONTCALL,11,Goto(s|10)
-exten => sw-61-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-61-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_60]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-62-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_60-62)
-exten => _sw-62-.,10,Voicemail(u${ext})
-exten => _sw-62-.,11,Goto(s|10)
-exten => sw-62-,10,Goto(sw-62-.|10)
-exten => sw-62-NOANSWER,10,Voicemail(u${ext})
-exten => sw-62-NOANSWER,11,Goto(s|10)
-exten => sw-62-ANSWER,10,Goto(s|10)
-exten => sw-62-BUSY,10,Voicemail(b${ext})
-exten => sw-62-BUSY,11,Goto(s|10)
-exten => sw-62-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-62-DONTCALL,11,Goto(s|10)
-exten => sw-62-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-62-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_61]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-63-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_61-63)
-exten => _sw-63-.,10,Voicemail(u${ext})
-exten => _sw-63-.,11,Goto(s|10)
-exten => sw-63-,10,Goto(sw-63-.|10)
-exten => sw-63-NOANSWER,10,Voicemail(u${ext})
-exten => sw-63-NOANSWER,11,Goto(s|10)
-exten => sw-63-ANSWER,10,Goto(s|10)
-exten => sw-63-BUSY,10,Voicemail(b${ext})
-exten => sw-63-BUSY,11,Goto(s|10)
-exten => sw-63-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-63-DONTCALL,11,Goto(s|10)
-exten => sw-63-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-63-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_62]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-64-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_62-64)
-exten => _sw-64-.,10,Voicemail(u${ext})
-exten => _sw-64-.,11,Goto(s|10)
-exten => sw-64-,10,Goto(sw-64-.|10)
-exten => sw-64-NOANSWER,10,Voicemail(u${ext})
-exten => sw-64-NOANSWER,11,Goto(s|10)
-exten => sw-64-ANSWER,10,Goto(s|10)
-exten => sw-64-BUSY,10,Voicemail(b${ext})
-exten => sw-64-BUSY,11,Goto(s|10)
-exten => sw-64-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-64-DONTCALL,11,Goto(s|10)
-exten => sw-64-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-64-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_63]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-65-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_63-65)
-exten => _sw-65-.,10,Voicemail(u${ext})
-exten => _sw-65-.,11,Goto(s|10)
-exten => sw-65-,10,Goto(sw-65-.|10)
-exten => sw-65-NOANSWER,10,Voicemail(u${ext})
-exten => sw-65-NOANSWER,11,Goto(s|10)
-exten => sw-65-ANSWER,10,Goto(s|10)
-exten => sw-65-BUSY,10,Voicemail(b${ext})
-exten => sw-65-BUSY,11,Goto(s|10)
-exten => sw-65-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-65-DONTCALL,11,Goto(s|10)
-exten => sw-65-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-65-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_64]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-66-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_64-66)
-exten => _sw-66-.,10,Voicemail(u${ext})
-exten => _sw-66-.,11,Goto(s|10)
-exten => sw-66-,10,Goto(sw-66-.|10)
-exten => sw-66-NOANSWER,10,Voicemail(u${ext})
-exten => sw-66-NOANSWER,11,Goto(s|10)
-exten => sw-66-ANSWER,10,Goto(s|10)
-exten => sw-66-BUSY,10,Voicemail(b${ext})
-exten => sw-66-BUSY,11,Goto(s|10)
-exten => sw-66-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-66-DONTCALL,11,Goto(s|10)
-exten => sw-66-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-66-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_65]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-67-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_65-67)
-exten => _sw-67-.,10,Voicemail(u${ext})
-exten => _sw-67-.,11,Goto(s|10)
-exten => sw-67-,10,Goto(sw-67-.|10)
-exten => sw-67-NOANSWER,10,Voicemail(u${ext})
-exten => sw-67-NOANSWER,11,Goto(s|10)
-exten => sw-67-ANSWER,10,Goto(s|10)
-exten => sw-67-BUSY,10,Voicemail(b${ext})
-exten => sw-67-BUSY,11,Goto(s|10)
-exten => sw-67-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-67-DONTCALL,11,Goto(s|10)
-exten => sw-67-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-67-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_66]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-68-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_66-68)
-exten => _sw-68-.,10,Voicemail(u${ext})
-exten => _sw-68-.,11,Goto(s|10)
-exten => sw-68-,10,Goto(sw-68-.|10)
-exten => sw-68-NOANSWER,10,Voicemail(u${ext})
-exten => sw-68-NOANSWER,11,Goto(s|10)
-exten => sw-68-ANSWER,10,Goto(s|10)
-exten => sw-68-BUSY,10,Voicemail(b${ext})
-exten => sw-68-BUSY,11,Goto(s|10)
-exten => sw-68-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-68-DONTCALL,11,Goto(s|10)
-exten => sw-68-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-68-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_67]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-69-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_67-69)
-exten => _sw-69-.,10,Voicemail(u${ext})
-exten => _sw-69-.,11,Goto(s|10)
-exten => sw-69-,10,Goto(sw-69-.|10)
-exten => sw-69-NOANSWER,10,Voicemail(u${ext})
-exten => sw-69-NOANSWER,11,Goto(s|10)
-exten => sw-69-ANSWER,10,Goto(s|10)
-exten => sw-69-BUSY,10,Voicemail(b${ext})
-exten => sw-69-BUSY,11,Goto(s|10)
-exten => sw-69-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-69-DONTCALL,11,Goto(s|10)
-exten => sw-69-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-69-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_68]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-70-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_68-70)
-exten => _sw-70-.,10,Voicemail(u${ext})
-exten => _sw-70-.,11,Goto(s|10)
-exten => sw-70-,10,Goto(sw-70-.|10)
-exten => sw-70-NOANSWER,10,Voicemail(u${ext})
-exten => sw-70-NOANSWER,11,Goto(s|10)
-exten => sw-70-ANSWER,10,Goto(s|10)
-exten => sw-70-BUSY,10,Voicemail(b${ext})
-exten => sw-70-BUSY,11,Goto(s|10)
-exten => sw-70-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-70-DONTCALL,11,Goto(s|10)
-exten => sw-70-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-70-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_69]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-71-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_69-71)
-exten => _sw-71-.,10,Voicemail(u${ext})
-exten => _sw-71-.,11,Goto(s|10)
-exten => sw-71-,10,Goto(sw-71-.|10)
-exten => sw-71-NOANSWER,10,Voicemail(u${ext})
-exten => sw-71-NOANSWER,11,Goto(s|10)
-exten => sw-71-ANSWER,10,Goto(s|10)
-exten => sw-71-BUSY,10,Voicemail(b${ext})
-exten => sw-71-BUSY,11,Goto(s|10)
-exten => sw-71-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-71-DONTCALL,11,Goto(s|10)
-exten => sw-71-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-71-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_70]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-72-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_70-72)
-exten => _sw-72-.,10,Voicemail(u${ext})
-exten => _sw-72-.,11,Goto(s|10)
-exten => sw-72-,10,Goto(sw-72-.|10)
-exten => sw-72-NOANSWER,10,Voicemail(u${ext})
-exten => sw-72-NOANSWER,11,Goto(s|10)
-exten => sw-72-ANSWER,10,Goto(s|10)
-exten => sw-72-BUSY,10,Voicemail(b${ext})
-exten => sw-72-BUSY,11,Goto(s|10)
-exten => sw-72-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-72-DONTCALL,11,Goto(s|10)
-exten => sw-72-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-72-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_71]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-73-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_71-73)
-exten => _sw-73-.,10,Voicemail(u${ext})
-exten => _sw-73-.,11,Goto(s|10)
-exten => sw-73-,10,Goto(sw-73-.|10)
-exten => sw-73-NOANSWER,10,Voicemail(u${ext})
-exten => sw-73-NOANSWER,11,Goto(s|10)
-exten => sw-73-ANSWER,10,Goto(s|10)
-exten => sw-73-BUSY,10,Voicemail(b${ext})
-exten => sw-73-BUSY,11,Goto(s|10)
-exten => sw-73-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-73-DONTCALL,11,Goto(s|10)
-exten => sw-73-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-73-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_72]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-74-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_72-74)
-exten => _sw-74-.,10,Voicemail(u${ext})
-exten => _sw-74-.,11,Goto(s|10)
-exten => sw-74-,10,Goto(sw-74-.|10)
-exten => sw-74-NOANSWER,10,Voicemail(u${ext})
-exten => sw-74-NOANSWER,11,Goto(s|10)
-exten => sw-74-ANSWER,10,Goto(s|10)
-exten => sw-74-BUSY,10,Voicemail(b${ext})
-exten => sw-74-BUSY,11,Goto(s|10)
-exten => sw-74-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-74-DONTCALL,11,Goto(s|10)
-exten => sw-74-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-74-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten_73]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-75-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten_73-75)
-exten => _sw-75-.,10,Voicemail(u${ext})
-exten => _sw-75-.,11,Goto(s|10)
-exten => sw-75-,10,Goto(sw-75-.|10)
-exten => sw-75-NOANSWER,10,Voicemail(u${ext})
-exten => sw-75-NOANSWER,11,Goto(s|10)
-exten => sw-75-ANSWER,10,Goto(s|10)
-exten => sw-75-BUSY,10,Voicemail(b${ext})
-exten => sw-75-BUSY,11,Goto(s|10)
-exten => sw-75-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-75-DONTCALL,11,Goto(s|10)
-exten => sw-75-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-75-TORTURE,11,Goto(s|10)
-
-
-[macro-std-priv-exten]
-exten => s,1,Set(dev=${ARG1})
-exten => s,2,Set(ext=${ARG2})
-exten => s,3,Set(timeout=${ARG3})
-exten => s,4,Set(opts=${ARG4})
-exten => s,5,Set(torcont=${ARG5})
-exten => s,6,Set(dontcont=${ARG6})
-exten => s,7,Dial(${dev}|${timeout}|${opts})
-exten => s,8,NoOp(${DIALSTATUS} was chosen)
-exten => s,9,Goto(sw-76-${DIALSTATUS}|10)
-exten => s,10,NoOp(Finish switch-std-priv-exten-76)
-exten => _sw-76-.,10,Voicemail(u${ext})
-exten => _sw-76-.,11,Goto(s|10)
-exten => sw-76-,10,Goto(sw-76-.|10)
-exten => sw-76-NOANSWER,10,Voicemail(u${ext})
-exten => sw-76-NOANSWER,11,Goto(s|10)
-exten => sw-76-ANSWER,10,Goto(s|10)
-exten => sw-76-BUSY,10,Voicemail(b${ext})
-exten => sw-76-BUSY,11,Goto(s|10)
-exten => sw-76-DONTCALL,10,Goto(${dontcont}|s|begin)
-exten => sw-76-DONTCALL,11,Goto(s|10)
-exten => sw-76-TORTURE,10,Goto(${torcont}|s|begin)
-exten => sw-76-TORTURE,11,Goto(s|10)
-
-
-[macro-fillcidname]
-exten => s,1,GotoIf($["${CALLERID(number)}" = "" ]?2:3)
-exten => s,2,Goto(13)
-exten => s,3,NoOp(Finish if-fillcidname-77)
-exten => s,4,Set(cidn=${DB(cidname/${CALLERID(num)})})
-exten => s,5,GotoIf($["${CALLERID(name)}" != "" ]?6:9)
-exten => s,6,GotoIf($[("${cidn}" = "Privacy Manager" & "${CALLERID(name)}" != "Privacy Manager") | "${cidn}" = "" ]?7:8)
-exten => s,7,Set(DB(cidname/${CALLERID(number)})=${CALLERID(name)})
-exten => s,8,NoOp(Finish if-if-fillcidname-78-79)
-exten => s,9,NoOp(Finish if-fillcidname-78)
-exten => s,10,GotoIf($[( "${cidn}" != "" ) & ( "${CALLERID(name)}" = "" | "${CALLERID(name)}" = "CODY\,WY " | "${CALLERID(name)}" = "POWELL\,WY " | "${CALLERID(name)}" = "WIRELESS CALLER" | "${CALLERID(name)}" = "SUBSCRIBER\,WIRE" | "${CALLERID(name)}" = "CELLULAR ONE" | "${CALLERID(name)}" = "Cellular One Customer" | "${CALLERID(name)}" = "CELLULAR ONE " | "${CALLERID(name)}" = "Privacy Manager" | "${CALLERID(name)}" = "RIVERTON\,WY " | "${CALLERID(name)}" = "BASIN\,WY " | "${CALLERID(name)}" = "BILLINGS\,MT " | "${CALLERID(name)}" = "PROVO\,UT " | "${CALLERID(name)}" = "TOLL FREE " ) ]?11:12)
-exten => s,11,Set(CALLERID(name)=${cidn})
-exten => s,12,NoOp(Finish if-fillcidname-80)
-exten => s,13,NoOp(End of Macro fillcidname-s)
-
-
-[macro-ciddial]
-exten => s,1,Set(dialnum=${ARG1})
-exten => s,2,Set(lookup=${ARG2})
-exten => s,3,Set(waittime=${ARG3})
-exten => s,4,Set(dialopts=${ARG4})
-exten => s,5,Set(ddev=${ARG5})
-exten => s,6,Set(cidnu=${CALLERID(num)})
-exten => s,7,Set(cidn=${DB(cidname/${lookup})})
-exten => s,8,Set(CALLERID(name)=${cidn})
-exten => s,9,Dial(${ddev}/${dialnum}|${waittime}|${dialopts})
-exten => s,10,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?11:19)
-exten => s,11,BackGround(try_voip)
-exten => s,12,Set(CALLERID(num)=$[7075679201])
-exten => s,13,Dial(SIP/1${lookup}@tctwest|${waittime}|${dialopts})
-exten => s,14,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?15:18)
-exten => s,15,BackGround(try_cell)
-exten => s,16,Set(CALLERID(num)=$[${cidnu}])
-exten => s,17,Dial(Zap/2/${lookup}|${waittime}|${dialopts})
-exten => s,18,NoOp(Finish if-if-ciddial-81-82)
-exten => s,19,NoOp(Finish if-ciddial-81)
-
-
-[macro-ciddial3]
-exten => s,1,Set(dialnum=${ARG1})
-exten => s,2,Set(lookup=${ARG2})
-exten => s,3,Set(waittime=${ARG3})
-exten => s,4,Set(dialopts=${ARG4})
-exten => s,5,Set(ddev=${ARG5})
-exten => s,6,Set(cidnu=${CALLERID(num)})
-exten => s,7,Set(cidn=${DB(cidname/${lookup})})
-exten => s,8,Set(CALLERID(name)=${cidn})
-exten => s,9,Dial(${ddev}/${dialnum}|${waittime}|${dialopts})
-exten => s,10,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?11:13)
-exten => s,11,BackGround(try_cell)
-exten => s,12,Dial(Zap/2/${lookup}|${waittime}|${dialopts})
-exten => s,13,NoOp(Finish if-ciddial3-83)
-
-
-[macro-ciddial2]
-exten => s,1,Set(dialnum=${ARG1})
-exten => s,2,Set(lookup=${ARG2})
-exten => s,3,Set(waittime=${ARG3})
-exten => s,4,Set(dialopts=${ARG4})
-exten => s,5,Set(ddev=${ARG5})
-exten => s,6,Set(cidn=${DB(cidname/${lookup})})
-exten => s,7,Set(cidnu=${CALLERID(num)})
-exten => s,8,Set(CALLERID(name)=${cidn})
-exten => s,9,Set(CALLERID(num)=7075679201)
-exten => s,10,Dial(SIP/1${lookup}@tctwest|${waittime}|${dialopts})
-exten => s,11,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?12:19)
-exten => s,12,Set(CALLERID(num)=${cidnu})
-exten => s,13,BackGround(try_zap)
-exten => s,14,Dial(${ddev}/${dialnum}|${waittime}|${dialopts})
-exten => s,15,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?16:18)
-exten => s,16,BackGround(try_cell)
-exten => s,17,Dial(Zap/2/${lookup}|${waittime}|${dialopts})
-exten => s,18,NoOp(Finish if-if-ciddial2-84-85)
-exten => s,19,NoOp(Finish if-ciddial2-84)
-
-
-[macro-callerid-liar]
-exten => s,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/priv-callerintros/LIAR.gsm&)
-exten => s,2,Background(priv-liar)
-exten => s,3,Hangup()
-
-
-[macro-callerid-bad]
-exten => s,1,Set(mycid=$[${CALLERID(num)}:"1([0-9]+)"])
-exten => s,2,Set(CALLERID(num)=${mycid})
-exten => s,3,Wait(0)
-
-
-[privacyManagerFailed]
-exten => s,1(begin),Background(PrivManInstructions)
-exten => s,2,PrivacyManager()
-exten => s,3,GotoIf($["${PRIVACYMGRSTATUS}" = "FAILED" ]?4:11)
-exten => s,4,Background(tt-allbusy)
-exten => s,5,Background(tt-somethingwrong)
-exten => s,6,Background(tt-monkeysintro)
-exten => s,7,Background(tt-monkeys)
-exten => s,8,Background(tt-weasels)
-exten => s,9,Hangup()
-exten => s,10,Goto(12)
-exten => s,11,Goto(homeline|s|postPriv)
-exten => s,12,NoOp(Finish if-privacyManagerFailed-86)
-
-
-[homeline]
-exten => s,1(begin),Answer()
-exten => s,2,Set(repeatcount=0)
-exten => s,3,Zapateller(nocallerid)
-exten => s,4,PrivacyManager()
-exten => s,5,GotoIf($["${PRIVACYMGRSTATUS}" = "FAILED" ]?6:10)
-exten => s,6,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/privmanfailed.gsm)
-exten => s,7,Macro(std-priv-exten|Zap/3r1&Zap/5r1|2|25|mtw|telemarket|telemarket)
-exten => s,8,Hangup()
-exten => s,9,Goto(104)
-exten => s,10,NoOp(Finish if-homeline-87)
-exten => s,11(postPriv),Macro(fillcidname)
-exten => s,12,Set(CONFCIDNA=${CALLERID(name)})
-exten => s,13,Set(CONFCIDNU=${CALLERID(num)})
-exten => s,14,AGI(callall)
-exten => s,15,AGI(submit-announce.agi)
-exten => s,16,GotoIf($["${CALLERID(num)}" : "1" ]?17:18)
-exten => s,17,Macro(callerid-bad)
-exten => s,18,NoOp(Finish if-homeline-88)
-exten => s,19,GotoIf($["${CALLERID(num)}" = "7077577685" & "${CALLERID(name)}" : "Privacy Manager" ]?20:21)
-exten => s,20,Macro(callerid-liar)
-exten => s,21,NoOp(Finish if-homeline-89)
-exten => s,22,TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&)
-exten => s,23,Set(lds=${DB(playlds/${CALLERID(num)})})
-exten => s,24,GotoIf($["${lds}" = "1" ]?25:26)
-exten => s,25,SetMusicOnHold(mohlds)
-exten => s,26,NoOp(Finish if-homeline-90)
-exten => s,27,Set(direct=$[${DB(DirectCall/${CALLERID(num)})}])
-exten => s,28,GotoIf($["${direct}" != "" & ${direct} != 0 ]?29:36)
-exten => s,29,verbose(direct is XXX#${direct}XXXX)
-exten => s,30,Playback(greetings/direct)
-exten => s,31,Playback(/var/spool/asterisk/voicemail/default/${direct}/greet)
-exten => s,32,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => s,33,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/${direct}/greet.wav&)
-exten => s,34,Goto(sw-92-${direct}|10)
-exten => s,35,NoOp(Finish switch-if-homeline-91-92)
-exten => s,36,NoOp(Finish if-homeline-91)
-exten => s,37(loopback),GotoIfTime(*|*|20-25|dec?39)
-exten => s,38,Goto(41)
-exten => s,39,Playback(greetings/christmas)
-exten => s,40,Goto(102)
-exten => s,41,GotoIfTime(*|*|31|dec?43)
-exten => s,42,Goto(45)
-exten => s,43,Playback(greetings/newyear)
-exten => s,44,Goto(101)
-exten => s,45,GotoIfTime(*|*|1|jan?47)
-exten => s,46,Goto(49)
-exten => s,47,Playback(greetings/newyear)
-exten => s,48,Goto(100)
-exten => s,49,GotoIfTime(*|*|14|feb?51)
-exten => s,50,Goto(53)
-exten => s,51,Playback(greetings/valentines)
-exten => s,52,Goto(99)
-exten => s,53,GotoIfTime(*|*|17|mar?55)
-exten => s,54,Goto(57)
-exten => s,55,Playback(greetings/stPat)
-exten => s,56,Goto(98)
-exten => s,57,GotoIfTime(*|*|31|oct?59)
-exten => s,58,Goto(61)
-exten => s,59,Playback(greetings/halloween)
-exten => s,60,Goto(97)
-exten => s,61,GotoIfTime(*|mon|15-21|jan?63)
-exten => s,62,Goto(65)
-exten => s,63,Playback(greetings/mlkDay)
-exten => s,64,Goto(96)
-exten => s,65,GotoIfTime(*|thu|22-28|nov?67)
-exten => s,66,Goto(69)
-exten => s,67,Playback(greetings/thanksgiving)
-exten => s,68,Goto(95)
-exten => s,69,GotoIfTime(*|mon|25-31|may?71)
-exten => s,70,Goto(73)
-exten => s,71,Playback(greetings/memorial)
-exten => s,72,Goto(94)
-exten => s,73,GotoIfTime(*|mon|1-7|sep?75)
-exten => s,74,Goto(77)
-exten => s,75,Playback(greetings/labor)
-exten => s,76,Goto(93)
-exten => s,77,GotoIfTime(*|mon|15-21|feb?79)
-exten => s,78,Goto(81)
-exten => s,79,Playback(greetings/president)
-exten => s,80,Goto(92)
-exten => s,81,GotoIfTime(*|sun|8-14|may?83)
-exten => s,82,Goto(85)
-exten => s,83,Playback(greetings/mothers)
-exten => s,84,Goto(91)
-exten => s,85,GotoIfTime(*|sun|15-21|jun?87)
-exten => s,86,Goto(89)
-exten => s,87,Playback(greetings/fathers)
-exten => s,88,Goto(90)
-exten => s,89,Playback(greetings/hello)
-exten => s,90,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99-100-101-102-103-104-105)
-exten => s,91,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99-100-101-102-103-104)
-exten => s,92,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99-100-101-102-103)
-exten => s,93,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99-100-101-102)
-exten => s,94,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99-100-101)
-exten => s,95,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99-100)
-exten => s,96,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98-99)
-exten => s,97,NoOp(Finish iftime-iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97-98)
-exten => s,98,NoOp(Finish iftime-iftime-iftime-iftime-iftime-homeline-93-94-95-96-97)
-exten => s,99,NoOp(Finish iftime-iftime-iftime-iftime-homeline-93-94-95-96)
-exten => s,100,NoOp(Finish iftime-iftime-iftime-homeline-93-94-95)
-exten => s,101,NoOp(Finish iftime-iftime-homeline-93-94)
-exten => s,102,NoOp(Finish iftime-homeline-93)
-exten => s,103,Background(murphy-homeline-intro1)
-exten => s,104,NoOp(End of Extension s)
-exten => _sw-92-.,10,Set(z=${direct}-2)
-exten => _sw-92-.,11,Goto(homeline-kids|${z}|1)
-exten => sw-92-,10,Goto(sw-92-.|10)
-exten => sw-92-2,10,Macro(std-priv-exten|Zap/3r1&Zap/5r1|2|25|mtw|telemarket|telemarket)
-exten => sw-92-2,11,Goto(s|loopback)
-exten => sw-92-1,10,Macro(std-priv-exten|Zap/6r3&Sip/murf|1|25|mpA(beep)tw|telemarket|telemarket)
-exten => sw-92-1,11,Goto(s|loopback)
-exten => 1,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 1,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/2/greet.wav&)
-exten => 1,3,Macro(std-priv-exten|Zap/3r1&Zap/5r1|2|25|mtw|telemarket|telemarket)
-exten => 1,4,Goto(s|loopback)
-exten => 2,1,Goto(homeline-kids|s|begin)
-exten => 21,1,Dial(IAX2/seaniax|20|T)
-exten => 3,1,Macro(std-priv-exten|Zap/6r3&Sip/murf|1|25|mpA(beep)tw|telemarket|telemarket)
-exten => 3,2,Goto(s|loopback)
-exten => 4,1,VoicemailMain()
-exten => 4,2,Goto(s|loopback)
-exten => 5,1,Goto(home-introduction|s|begin)
-exten => 6,1,Goto(telemarket|s|begin)
-exten => 7,1,agi(tts-riddle.agi)
-exten => 7,2,Background(gsm/what-time-it-is2)
-exten => 7,3,SayUnixTime()
-exten => 7,4,Goto(s|loopback)
-exten => 792,1,Goto(pageall|s|begin)
-exten => 793,1,Read(zz||0||1|0)
-exten => 793,2,SayDigits(${zz})
-exten => t,1,Set(repeatcount=${repeatcount} + 1)
-exten => t,2,GotoIf($[${repeatcount} < 3 ]?3:4)
-exten => t,3,Goto(s|loopback)
-exten => t,4,NoOp(Finish if-homeline-106)
-exten => t,5,Hangup()
-exten => i,1,Background(invalid)
-exten => i,2,Goto(s|loopback)
-exten => o,1,Congestion()
-exten => fax,1,Dial(Zap/4)
-
-
-[pageall]
-exten => s,1(begin),AGI(callall)
-exten => s,2,MeetMe(5555|dtqp)
-exten => s,3,MeetMeAdmin(5555|K)
-exten => s,4,Hangup()
-exten => h,1(begin),MeetMeAdmin(5555|K)
-exten => h,2,Background(conf-muted)
-exten => h,3,Hangup()
-
-
-[add-to-conference]
-exten => start,1,NoCDR()
-exten => start,2,MeetMe(5555|dmqp)
-exten => h,1,Hangup()
-
-
-[home-introduction]
-exten => s,1(begin),Background(intro-options)
-exten => 1,1,Playback(priv-callerintros/${CALLERID(num)})
-exten => 1,2,Goto(s|begin)
-exten => 2,1,Goto(home-introduction-record|s|begin)
-exten => 3,1,Goto(homeline|s|loopback)
-exten => 4,1,Playback(intro-intro)
-exten => 4,2,Goto(s|begin)
-exten => t,1,Goto(s|begin)
-exten => i,1,Background(invalid)
-exten => i,2,Goto(s|begin)
-exten => o,1,Goto(s|begin)
-
-
-[home-introduction-record]
-exten => s,1(begin),Background(intro-record-choices)
-exten => 1,1,Playback(intro-record)
-exten => 1,2,Goto(2|begin)
-exten => 2,1(begin),Background(intro-start)
-exten => 2,2,Background(beep)
-exten => 2,3,Record(priv-callerintros/${CALLERID(num)}:gsm|3)
-exten => 2,4,Background(priv-callerintros/${CALLERID(num)})
-exten => 2,5,Goto(home-introduction|s|begin)
-exten => t,1,Goto(s|begin)
-exten => i,1,Background(invalid)
-exten => i,2,Goto(s|begin)
-exten => o,1,Goto(s|begin)
-
-
-[homeline-kids]
-exten => s,1(begin),Background(murphy-homeline-kids)
-exten => 1,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 1,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/3/greet.wav&)
-exten => 1,3,Macro(std-priv-exten|IAX2/seaniax&Zap/5r2|3|35|mtw|telemarket|telemarket)
-exten => 1,4,Goto(homeline|s|loopback)
-exten => 2,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 2,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&)
-exten => 2,3,Voicemail(u4)
-exten => 2,4,Goto(homeline|s|loopback)
-exten => 3,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 3,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/5/greet.wav&)
-exten => 3,3,Macro(std-priv-exten|Zap/3r2&Zap/5r2|5|35|mtw|telemarket|telemarket)
-exten => 3,4,Goto(homeline|s|loopback)
-exten => 4,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 4,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/6/greet.wav&)
-exten => 4,3,Macro(std-priv-exten|Zap/3r2&Zap/5r2|6|35|mtw|telemarket|telemarket)
-exten => 4,4,Goto(homeline|s|loopback)
-exten => 5,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 5,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/7/greet.wav&)
-exten => 5,3,Macro(std-priv-exten|Zap/3r2&Zap/5r2|7|35|mtw|telemarket|telemarket)
-exten => 5,4,Goto(homeline|s|loopback)
-exten => 6,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 6,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/8/greet.wav&)
-exten => 6,3,Macro(std-priv-exten|Zap/3r2&Zap/5r2|8|35|mtw|telemarket|telemarket)
-exten => 6,4,Goto(homeline|s|loopback)
-exten => 7,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 7,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/9/greet.wav&)
-exten => 7,3,Macro(std-priv-exten|Zap/3r2&Zap/5r2|9|35|mtw|telemarket|telemarket)
-exten => 7,4,Goto(homeline|s|loopback)
-exten => t,1,Goto(s|begin)
-exten => i,1,Background(invalid)
-exten => i,2,Goto(s|begin)
-exten => o,1,Goto(s|begin)
-
-
-[voipworkline]
-exten => s,1(begin),Answer()
-exten => s,2,TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&)
-exten => s,3,Goto(workline|s|loopback)
-exten => 7075679201,1,Answer()
-exten => 7075679201,2,TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&)
-exten => 7075679201,3,Goto(workline|s|loopback)
-
-
-[workline]
-exten => s,1(begin),Answer()
-exten => s,2,Wait(1)
-exten => s,3,Set(repeatcount=0)
-exten => s,4,Zapateller(nocallerid)
-exten => s,5,Macro(fillcidname)
-exten => s,6,TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&)
-exten => s,7(loopback),Background(greetings/greeting)
-exten => s,8,Background(murphy-office-intro1)
-exten => 1,1,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm)
-exten => 1,2,TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/1/greet.wav&)
-exten => 1,3,Macro(std-priv-exten|Zap/6&Sip/murf|1|30|mtw|telemarket|telemarket)
-exten => 1,4,Goto(s|loopback)
-exten => 4,1,VoicemailMain()
-exten => 4,2,Goto(s|loopback)
-exten => 6,1,Goto(telemarket|s|begin)
-exten => 793,1,Read(zz||0||1|0)
-exten => 793,2,SayDigits(${zz})
-exten => t,1,Set(repeatcount=$[${repeatcount} + 1])
-exten => t,2,GotoIf($[${repeatcount} < 3 ]?3:4)
-exten => t,3,Goto(s|loopback)
-exten => t,4,NoOp(Finish if-workline-107)
-exten => t,5,Hangup()
-exten => i,1,Background(invalid)
-exten => i,2,Goto(s|loopback)
-exten => o,1,Congestion()
-exten => fax,1,Answer()
-exten => fax,2,Dial(Zap/4)
-
-
-[dialFWD]
-ignorepat => 8
-ignorepat => 9
-exten => _83.,1,Set(CALLERID(name)=${FWDCIDNAME})
-exten => _83.,2,Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2}|60|r)
-exten => _83.,3,Congestion()
-exten => _82NXX,1,Set(CALLERID(name)=${FWDCIDNAME})
-exten => _82NXX,2,Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2}|60|r)
-exten => _82NXX,3,Congestion()
-exten => _92NXX,1,Set(CALLERID(name)=${FWDCIDNAME})
-exten => _92NXX,2,Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2}|60|r)
-exten => _92NXX,3,Congestion()
-
-
-[dialiaxtel]
-ignorepat => 8
-ignorepat => 9
-exten => _81700NXXXXXX,1,Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel)
-exten => _81800NXXXXXX,1,Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel)
-exten => _91700NXXXXXX,1,Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel)
-exten => _91800NXXXXXX,1,Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel)
-
-
-[dialgoiax]
-ignorepat => 9
-exten => _93.,1,Set(CALLERID(name)="Joe Worker")
-exten => _93.,2,Dial(IAX2/878201007658:stickyfinger295@server1.goiax.com/${EXTEN:2}|60|r)
-exten => _93.,3,Congestion()
-
-
-[homefirst]
-ignorepat => 9
-exten => _91NXXNXXXXXX,1,Macro(ciddial|${EXTEN:1}|${EXTEN:2}|30|TW|Zap/1)
-exten => _9754XXXX,1,Macro(ciddial|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9574XXXX,1,Macro(ciddial|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9202XXXX,1,Macro(ciddial|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9219XXXX,1,Macro(ciddial|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9254XXXX,1,Macro(ciddial|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9716XXXX,1,Macro(ciddial|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9NXXXXXX,1,Macro(ciddial|1707${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9011.,1,Macro(ciddial|${EXTEN:1}|${EXTEN:1}|30|TW|Zap/1)
-exten => _9911,1,Dial(Zap/1/911|30|T)
-exten => _9411,1,Dial(Zap/1/411|30|T)
-
-
-[workfirst]
-ignorepat => 9
-exten => _91NXXNXXXXXX,1,Macro(ciddial2|${EXTEN:1}|${EXTEN:2}|30|TW|Zap/1)
-exten => _9754XXXX,1,Macro(ciddial2|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9574XXXX,1,Macro(ciddial2|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9202XXXX,1,Macro(ciddial2|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9219XXXX,1,Macro(ciddial2|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9254XXXX,1,Macro(ciddial2|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9716XXXX,1,Macro(ciddial2|${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9NXXXXXX,1,Macro(ciddial2|1707${EXTEN:1}|707${EXTEN:1}|30|TW|Zap/1)
-exten => _9911,1,Dial(Zap/1/911|30|T)
-exten => _9411,1,Dial(Zap/1/411|30|T)
-
-
-[force_cell]
-ignorepat => 8
-exten => _81NXXNXXXXXX,1,Macro(ciddial|${EXTEN:1}#|${EXTEN:2}|30|TW|Zap/2)
-exten => _8754XXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8574XXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8202XXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8219XXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8254XXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8716XXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8NXXXXXX,1,Macro(ciddial|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/2)
-exten => _8911,1,Dial(Zap/1/911|30|T)
-exten => _8411,1,Dial(Zap/1/411|30|T)
-
-
-[force_home]
-ignorepat => 8
-exten => _81NXXNXXXXXX,1,Macro(ciddial3|${EXTEN:1}#|${EXTEN:2}|30|TW|Zap/1)
-exten => _8754XXXX,1,Macro(ciddial3|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8574XXXX,1,Macro(ciddial3|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8202XXXX,1,Macro(ciddial3|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8219XXXX,1,Macro(ciddial3|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8254XXXX,1,Macro(ciddial3|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8716XXXX,1,Macro(ciddial3|${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8NXXXXXX,1,Macro(ciddial3|1707${EXTEN:1}#|707${EXTEN:1}|30|TW|Zap/1)
-exten => _8911,1,Dial(Zap/1/911|30|T)
-exten => _8411,1,Dial(Zap/1/411|30|T)
-
-
-[homeext]
-ignorepat => 8
-ignorepat => 9
-include => parkedcalls
-include => homefirst
-include => force_cell
-exten => s,1(loopback),Wait(0)
-exten => 1,1,Macro(std-priv-exten|Zap/3&Zap/5|2|35|mtw|telemarket|telemarket)
-exten => 1,2,Goto(s|loopback)
-exten => 2,1,Macro(std-priv-exten|Zap/6&Zap/5|1|35|mpA(beep3)Tt|telemarket|telemarket)
-exten => 2,2,Goto(s|loopback)
-exten => 4,1,VoicemailMain()
-exten => 5,1,Record(recording:gsm)
-exten => 5,2,Background(recording)
-exten => 6,1,Background(recording)
-exten => 760,1,DateTime()
-exten => 760,2,Goto(s|loopback)
-exten => 761,1,Record(announcement:gsm)
-exten => 761,2,TrySystem(/usr/bin/play /var/lib/asterisk/sounds/announcement.gsm&)
-exten => 761,3,Goto(s|loopback)
-exten => 762,1,agi(tts-riddle.agi)
-exten => 762,2,Background(gsm/what-time-it-is2)
-exten => 762,3,SayUnixTime()
-exten => 762,4,Goto(s|loopback)
-exten => 763,1,Set(CALLERID(num)=)
-exten => 763,2,Dial(Zap/6r3|35|mptA(beep3))
-exten => 763,3,Hangup()
-exten => 764,1,Set(CALLERID(num)=)
-exten => 764,2,Dial(Zap/6r3|35|mptnA(beep3))
-exten => 764,3,Hangup()
-exten => 765,1,Set(CALLERID(num)=)
-exten => 765,2,Dial(Zap/6r3|35|mptNA(beep3))
-exten => 765,3,Hangup()
-exten => 766,1,Dial(Zap/6r3|35|mptNA(beep3))
-exten => 766,2,Hangup()
-exten => 767,1,Dial(Zap/6r3|35|mptnA(beep3))
-exten => 767,2,Hangup()
-exten => 769,1,Playtones(dial)
-exten => 769,2,Wait(2)
-exten => 769,3,Playtones(busy)
-exten => 769,4,Wait(2)
-exten => 769,5,Playtones(ring)
-exten => 769,6,Wait(2)
-exten => 769,7,Playtones(congestion)
-exten => 769,8,Wait(2)
-exten => 769,9,Playtones(callwaiting)
-exten => 769,10,Wait(2)
-exten => 769,11,Playtones(dialrecall)
-exten => 769,12,Wait(2)
-exten => 769,13,Playtones(record)
-exten => 769,14,Wait(2)
-exten => 769,15,Playtones(info)
-exten => 769,16,Wait(5)
-exten => 769,17,Hangup()
-exten => 790,1,MeetMe(790|p)
-exten => 792,1,Goto(pageall|s|begin)
-exten => 795,1,AGI(wakeup.agi)
-exten => 795,2,Congestion()
-exten => 544716,1,TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&)
-exten => 544716,2,Goto(s|loopback)
-exten => i,1,Background(invalid)
-exten => i,2,Goto(s|loopback)
-exten => o,1,Goto(s|loopback)
-exten => t,1,Congestion()
-
-
-[fromvmhome]
-exten => 1,1,Dial(Zap/6&Sip/murf|20|Tt)
-exten => 2,1,Dial(Zap/3&Zap/5|20|Tt)
-exten => _707202XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707219XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707254XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707716XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707754XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707574XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _NXXNXXXXXX,1,Macro(ciddial|1${EXTEN}|${EXTEN}|30|TW|Zap/1)
-exten => _1NXXNXXXXXX,1,Macro(ciddial|${EXTEN}|${EXTEN:1}|30|TW|Zap/1)
-exten => _754XXXX,1,Macro(ciddial|${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _574XXXX,1,Macro(ciddial|${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _NXXXXXX,1,Macro(ciddial|1707${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _911,1,Macro(ciddial|911|911|30|TW|Zap/1)
-exten => _411,1,Macro(ciddial|411|411|30|TW|Zap/1)
-
-
-[fromvmwork]
-exten => 1,1,Dial(Zap/6&Sip/murf|20|Tt)
-exten => 2,1,Dial(Zap/3&Zap/5|20|Tt)
-exten => _707202XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707219XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707254XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707716XXXX,1,Macro(ciddial|1${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707754XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707574XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _NXXNXXXXXX,1,Macro(ciddial|1${EXTEN}|${EXTEN}|30|TW|Zap/1)
-exten => _1NXXNXXXXXX,1,Macro(ciddial|${EXTEN}|${EXTEN:1}|30|TW|Zap/1)
-exten => _754XXXX,1,Macro(ciddial|${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _574XXXX,1,Macro(ciddial|${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _NXXXXXX,1,Macro(ciddial|1707${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => 911,1,Macro(ciddial|911|911|30|TW|Zap/1)
-exten => 411,1,Macro(ciddial|411|411|30|TW|Zap/1)
-
-
-[fromSeanUniden]
-include => parkedcalls
-exten => 21,1,Dial(IAX2/seaniax|20|T)
-exten => _707202XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707219XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707254XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707716XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707754XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _707574XXXX,1,Macro(ciddial|${EXTEN:3}|${EXTEN}|30|TW|Zap/1)
-exten => _NXXNXXXXXX,1,Macro(ciddial|1${EXTEN}|${EXTEN}|30|TW|Zap/1)
-exten => _1NXXNXXXXXX,1,Macro(ciddial|${EXTEN}|${EXTEN:1}|30|TW|Zap/1)
-exten => _754XXXX,1,Macro(ciddial|${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _574XXXX,1,Macro(ciddial|${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => _NXXXXXX,1,Macro(ciddial|1707${EXTEN}|707${EXTEN}|30|TW|Zap/1)
-exten => 911,1,Macro(ciddial|911|911|30|TW|Zap/1)
-exten => 411,1,Macro(ciddial|411|411|30|TW|Zap/1)
-
-
-[workext]
-ignorepat => 8
-ignorepat => 9
-include => parkedcalls
-include => workfirst
-include => force_home
-include => dialFWD
-include => dialiaxtel
-include => dialgoiax
-exten => s,1(loopback),Wait(0)
-exten => 1,1,Dial(Zap/3&Zap/5|20|tT)
-exten => 2,1,Dial(Zap/5&Zap/6|20|tT)
-exten => 21,1,Dial(IAX2/seaniax|20|T)
-exten => 22,1,Set(CALLERID(num)=1234567890)
-exten => 22,2,Set(CALLERID(name)=TestCaller)
-exten => 22,3,Dial(Zap/5|20|mP()A(beep)tw)
-exten => 22,4,NoOp(here is dialstatus: ${DIALSTATUS}...)
-exten => 22,5,Goto(s|loopback)
-exten => 4,1,VoicemailMain()
-exten => 4,2,Goto(s|loopback)
-exten => 5,1,Record(recording:gsm)
-exten => 5,2,Background(recording)
-exten => 6,1,ZapBarge()
-exten => 760,1,DateTime()
-exten => 760,2,Goto(s|loopback)
-exten => 761,1,ZapBarge()
-exten => 761,2,Goto(s|loopback)
-exten => 765,1,Playback(demo-echotest)
-exten => 765,2,Echo()
-exten => 765,3,Playback(demo-echodone)
-exten => 765,4,Goto(s|loopback)
-exten => 766,1,Festival(The other thing to watch is neuro-electronics: the ability to interface technology with our neural system: My wife: Sigrid: has had a cochlear implant since 1996. This once profoundly deaf person now uses the phone: recognizes accents: and listens to movies and recorded books.)
-exten => 766,2,Goto(s|loopback)
-exten => 767,1,agi(tts-riddle.agi)
-exten => 767,2,Background(gsm/what-time-it-is2)
-exten => 767,3,SayUnixTime()
-exten => 767,4,Goto(s|loopback)
-exten => 768,1,agi(tts-computer.agi)
-exten => 771,1,eagi(eagi-test)
-exten => 771,2,agi(my-agi-test)
-exten => 772,1,agi(wakeup.agi)
-exten => 775,1,GotoIf($[${EXTEN}=${EXTEN} ]?2:4)
-exten => 775,2,BackGround(digits/1)
-exten => 775,3,Goto(5)
-exten => 775,4,BackGround(digits/0)
-exten => 775,5,NoOp(Finish if-workext-108)
-exten => 775,6,GotoIf($[${EXTEN}=${LANGUAGE} ]?7:9)
-exten => 775,7,BackGround(digits/1)
-exten => 775,8,Goto(10)
-exten => 775,9,BackGround(digits/0)
-exten => 775,10,NoOp(Finish if-workext-109)
-exten => 775,11,BackGround(digits/2)
-exten => 776,1,Set(TEST=00359889811777)
-exten => 776,2,GotoIf($[${TEST}= 00359889811777 ]?3:5)
-exten => 776,3,BackGround(digits/1)
-exten => 776,4,Goto(6)
-exten => 776,5,BackGround(digits/0)
-exten => 776,6,NoOp(Finish if-workext-110)
-exten => 776,7,GotoIf($[${TEST}= 00359889811888 ]?8:10)
-exten => 776,8,BackGround(digits/1)
-exten => 776,9,Goto(11)
-exten => 776,10,BackGround(digits/0)
-exten => 776,11,NoOp(Finish if-workext-111)
-exten => 776,12,Hangup()
-exten => 790,1,MeetMe(790|p)
-exten => 792,1,Goto(pageall|s|begin)
-exten => 793,1,NoOp(Hello| this is included from include1.ael2)
-exten => 793,2,NoOp(This was included from include2.ael2)
-exten => 793,3,NoOp(This is include3.ael2!)
-exten => 793,4,NoOp(Include5.ael2 doesn't include anything| either!)
-exten => 793,5,NoOp(This is include4.ael2! Isn't it cool!?!?!?!)
-exten => 793,6,NoOp(4 doesn't include anything)
-exten => 795,1,AGI(wakeup.agi)
-exten => 795,2,Congestion()
-exten => 797,1,Set(CONFCIDNA=${CALLERID(name)})
-exten => 797,2,Set(CONFCIDNU=${CALLERID(num)})
-exten => 797,3,AGI(callall)
-exten => 797,4,AGI(submit-announce.agi)
-exten => 797,5,Hangup()
-
-
-[wakeup]
-exten => 3,1,Dial(Zap/3|30)
-exten => 4,1,Dial(Zap/4|30)
-exten => 5,1,Dial(Zap/5|30)
-exten => 6,1,Dial(Zap/6|30)
-exten => 99,1,Dial(IAX2/murfiaxphone|30)
-exten => 97,1,Dial(IAX2/ryaniax|30)
-exten => 94,1,Dial(IAX2/seaniax|30)
-
-
-[announce-all]
-exten => s,1(begin),MeetMe(5555|dtqp)
-exten => s,2,MeetMeAdmin(5555|K)
-exten => s,3,Hangup()
-exten => h,1,MeetMeAdmin(5555|K)
-exten => h,2,Hangup()
-
-
-[telemarket]
-exten => s,1(begin),Playback(telemarketer-intro)
-exten => s,2,Playback(telemarketer-choices)
-exten => 1,1,Goto(telemarket-charity|s|begin)
-exten => 2,1,Goto(telemarket-political|s|begin)
-exten => 3,1,Goto(telemarket-pollster|s|begin)
-exten => 4,1,Goto(telemarket-research|s|begin)
-exten => 5,1,Goto(telemarket-magazine|s|begin)
-exten => 6,1,Goto(telemarket-commercial|s|begin)
-exten => 7,1,Goto(telemarket-other|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-charity]
-exten => s,1(begin),Playback(telemark-charity-intro)
-exten => s,2,Playback(telemark-charity-choices)
-exten => 1,1,Goto(telemarket-char-disease|s|begin)
-exten => 2,1,Goto(telemarket-char-handicap|s|begin)
-exten => 3,1,Goto(telemarket-char-police|s|begin)
-exten => 4,1,Goto(telemarket-char-school|s|begin)
-exten => 5,1,Goto(telemarket-char-college|s|begin)
-exten => 6,1,Goto(telemarket-char-animal|s|begin)
-exten => 7,1,Goto(telemarket-char-candidate|s|begin)
-exten => 8,1,Goto(telemarket-char-abuse|s|begin)
-exten => 9,1,Goto(telemarket-char-other|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-char-disease]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-handicap]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-police]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-school]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-college]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-animal]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-candidate]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-abuse]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-char-other]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-sorry]
-exten => s,1(begin),Playback(telemarket-sorry)
-exten => s,2,Hangup()
-
-
-[telemarket-exception]
-exten => s,1(begin),Playback(telemarket-success)
-exten => s,2,Hangup()
-
-
-[telemarket-political]
-exten => s,1(begin),Playback(telemark-polit-intro)
-exten => s,2,Playback(telemark-polit-choices)
-exten => 1,1,Goto(telemarket-poli-Am1st|s|begin)
-exten => 2,1,Goto(telemarket-poli-American|s|begin)
-exten => 3,1,Goto(telemarket-poli-AmHer|s|begin)
-exten => 4,1,Goto(telemarket-poli-AmInd|s|begin)
-exten => 5,1,Goto(telemarket-poli-AmNaz|s|begin)
-exten => 6,1,Goto(telemarket-poli-Pot|s|begin)
-exten => 7,1,Goto(telemarket-poli-AmRef|s|begin)
-exten => 8,1,Goto(telemarket-poli-CFP|s|begin)
-exten => 9,1,Goto(telemarket-political2|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-political2]
-exten => s,1(begin),Playback(telemark-politx-intro)
-exten => s,2,Playback(telemark-polit2-choices)
-exten => 1,1,Goto(telemarket-poli-Communist|s|begin)
-exten => 2,1,Goto(telemarket-poli-Constit|s|begin)
-exten => 3,1,Goto(telemarket-poli-FamVal|s|begin)
-exten => 4,1,Goto(telemarket-poli-FreedSoc|s|begin)
-exten => 5,1,Goto(telemarket-poli-Grassroot|s|begin)
-exten => 6,1,Goto(telemarket-poli-Green|s|begin)
-exten => 7,1,Goto(telemarket-poli-Greens|s|begin)
-exten => 8,1,Goto(telemarket-poli-Independence|s|begin)
-exten => 9,1,Goto(telemarket-political3|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-political3]
-exten => s,1(begin),Playback(telemark-politx-intro)
-exten => s,2,Playback(telemark-polit3-choices)
-exten => 1,1,Goto(telemarket-poli-IndAm|s|begin)
-exten => 2,1,Goto(telemarket-poli-Labor|s|begin)
-exten => 3,1,Goto(telemarket-poli-Liber|s|begin)
-exten => 4,1,Goto(telemarket-poli-Light|s|begin)
-exten => 5,1,Goto(telemarket-poli-NatLaw|s|begin)
-exten => 6,1,Goto(telemarket-poli-New|s|begin)
-exten => 7,1,Goto(telemarket-poli-NewUn|s|begin)
-exten => 8,1,Goto(telemarket-poli-PeaceFree|s|begin)
-exten => 9,1,Goto(telemarket-political4|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-political4]
-exten => s,1(begin),Playback(telemark-politx-intro)
-exten => s,2,Playback(telemark-polit4-choices)
-exten => 1,1,Goto(telemarket-poli-Prohib|s|begin)
-exten => 2,1,Goto(telemarket-poli-Ref|s|begin)
-exten => 3,1,Goto(telemarket-poli-Revol|s|begin)
-exten => 4,1,Goto(telemarket-poli-SocPart|s|begin)
-exten => 5,1,Goto(telemarket-poli-SocAct|s|begin)
-exten => 6,1,Goto(telemarket-poli-SocEq|s|begin)
-exten => 7,1,Goto(telemarket-poli-SocLab|s|begin)
-exten => 8,1,Goto(telemarket-poli-SocWork|s|begin)
-exten => 9,1,Goto(telemarket-political5|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-political5]
-exten => s,1(begin),Playback(telemark-politx-intro)
-exten => s,2,Playback(telemark-polit5-choices)
-exten => 1,1,Goto(telemarket-poli-South|s|begin)
-exten => 2,1,Goto(telemarket-poli-SoInd|s|begin)
-exten => 3,1,Goto(telemarket-poli-USPac|s|begin)
-exten => 4,1,Goto(telemarket-poli-WTP|s|begin)
-exten => 5,1,Goto(telemarket-poli-WWP|s|begin)
-exten => 6,1,Goto(telemarket-poli-Democrat|s|begin)
-exten => 7,1,Goto(telemarket-poli-Repub|s|begin)
-exten => 8,1,Goto(telemarket-poli-other|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-poli-other]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Repub]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Democrat]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-WWP]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-WTP]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-USPac]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-SoInd]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-South]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-SocWork]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-SocLab]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-SocEq]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-SocAct]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-SocPart]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Revol]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Ref]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Prohib]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-PeaceFree]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-NewUn]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-New]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-NatLaw]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Light]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Liber]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Labor]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-IndAm]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Independence]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Greens]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Green]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Grassroot]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-FreedSoc]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-FamVal]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Constit]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Communist]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-CFP]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-AmRef]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Pot]
-exten => s,1(begin),Goto(telemarket-political|s|begin)
-
-
-[telemarket-poli-AmNaz]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-AmInd]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-AmHer]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-American]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-poli-Am1st]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-pollster]
-exten => s,1(begin),Playback(telemark-poll-intro)
-exten => s,2,Goto(telemarket-sorry|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-research]
-exten => s,1(begin),Playback(telemark-research-intro)
-exten => s,2,Goto(telemarket-sorry|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-magazine]
-exten => s,1(begin),Playback(telemark-mag-choices)
-exten => 1,1,Goto(telemark-mag-new|s|begin)
-exten => 2,1,Goto(telemark-mag-renew|s|begin)
-exten => 3,1,Goto(telemark-mag-survey|s|begin)
-exten => 4,1,Goto(telemark-mag-verify|s|begin)
-exten => 5,1,Goto(telemark-mag-other|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemark-mag-new]
-exten => s,1(begin),Playback(telemark-mag-new)
-exten => s,2,Hangup()
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemark-mag-renew]
-exten => s,1(begin),Playback(telemark-mag-renew)
-exten => s,2,Hangup()
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemark-mag-survey]
-exten => s,1(begin),Playback(telemark-mag-survey)
-exten => s,2,Hangup()
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemark-mag-verify]
-exten => s,1(begin),Playback(telemark-mag-verify)
-exten => s,2,Hangup()
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemark-mag-other]
-exten => s,1(begin),Goto(telemarket-sorry|s|begin)
-
-
-[telemarket-commercial]
-exten => s,1(begin),Playback(telemark-comm-intro)
-exten => s,2,Voicemail(u82)
-exten => s,3,Goto(telemarket-sorry|s|begin)
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
-
-
-[telemarket-other]
-exten => s,1(begin),Playback(telemark-other-intro)
-exten => s,2,Hangup()
-exten => t,1,Goto(telemarket|s|begin)
-exten => i,1,Goto(telemarket|s|begin)
-exten => o,1,Goto(telemarket|s|begin)
diff --git a/1.4/pbx/ael/ael-test/ref.ael-vtest17 b/1.4/pbx/ael/ael-test/ref.ael-vtest17
deleted file mode 100644
index 16e8f218f..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-vtest17
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-[dialextens]
-exten => _10X,1,Dial(Zap/${EXTEN:2}|30|tw)
-exten => _1ZX,1,Dial(Zap/${EXTEN:1}|30|tw)
-
-
-[dialthrus]
-exten => _3XX,1,Dial(Zap/${EXTEN:1}|30|tw)
-
-
-[t1incoming]
-include => dialextens
-include => parkedcalls
-exten => s,1,Answer()
-exten => s,2,Background(welcome-to-test-machine)
-
-
-[incoming]
-include => dialextens
-include => parkedcalls
-exten => s,1,Answer()
-exten => s,2,Background(welcome-to-test-machine)
-
-
-[extension]
-include => dialextens
-include => dialthrus
-exten => 5,1,Record(recording:gsm)
-exten => 5,2,Background(recording)
-exten => 81,1,Set(iterations=$[1000000])
-exten => 81,2,Set(time1=${EPOCH})
-exten => 81,3,Set(i=$[1])
-exten => 81,4,GotoIf($[${i}<${iterations}]?5:8)
-exten => 81,5,NoOp(Hello)
-exten => 81,6,Set(i=$[${i}+1])
-exten => 81,7,Goto(4)
-exten => 81,8,NoOp(Finish for-extension-1)
-exten => 81,9,Set(time2=${EPOCH})
-exten => 81,10,Verbose(The time diff is $[${time2} - ${time1} ] seconds)
-exten => 81,11,Verbose(Which means that the priorities/sec = $[4* ${iterations} / (${time2} - ${time1}) ])
-exten => 81,12,SayNumber($[4 * ${iterations} / (${time2} - ${time1}) ])
-exten => 82,1,Macro(ndeep|100000)
-exten => 82,2,Verbose(Finished 100000 levels deep call!)
-exten => 83,1,Goto(sw-2-${EXTEN}|10)
-exten => 83,2,NoOp(Finish switch-extension-2)
-exten => _sw-2-.,10,Goto(83|2)
-exten => sw-2-,10,Goto(sw-2-.|10)
-exten => _sw-2-[4-7]X,10,Verbose(and this too!)
-exten => _sw-2-[4-7]X,11,Goto(sw-2-.|10)
-exten => _sw-2-9X,10,Verbose(handle both 8x and 9x calls)
-exten => _sw-2-9X,11,Goto(sw-2-49|10)
-exten => _sw-2-8X,10,Verbose(do something to prepare it)
-exten => _sw-2-8X,11,Goto(sw-2-99|10)
-
-
-[macro-ndeep]
-exten => s,1,Set(level=${ARG1})
-exten => s,2,GotoIf($[${level} == 0]?3:5)
-exten => s,3,Verbose(2|Got to Level 0)
-exten => s,4,Goto(8)
-exten => s,5,NoOp(Finish if-ndeep-3)
-exten => s,6,Macro(ndeep|$[${level}-1])
-exten => s,7,Goto(8)
-exten => s,8,NoOp(End of Macro ndeep-s)
-
-
-[t1extension]
-include => dialextens
-include => dialthrus
diff --git a/1.4/pbx/ael/ael-test/ref.ael-vtest21 b/1.4/pbx/ael/ael-test/ref.ael-vtest21
deleted file mode 100644
index c4310476f..000000000
--- a/1.4/pbx/ael/ael-test/ref.ael-vtest21
+++ /dev/null
@@ -1,9 +0,0 @@
-[globals]
-AXLHAFT=wow-to-the-tenth-power
-JibberWorthy=zinger3
-OFFICE_CODE=503
-
-
-[from-enum]
-exten => _${OFFICE_CODE}XXXX,1,Answer()
-exten => _${OFFICE_CODE}XXXX,2,Goto(${EXTEN:3}|1)
diff --git a/1.4/pbx/ael/ael-test/runtests b/1.4/pbx/ael/ael-test/runtests
deleted file mode 100755
index 9209f0a54..000000000
--- a/1.4/pbx/ael/ael-test/runtests
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-ORIG=`mktemp /tmp/mytest.XXXXXX`
-NEW=`mktemp /tmp/mytest.XXXXXX`
-
-do_filter() {
- sed 's/line:[0-9]*//; /^Executed.*/d; s/column=[0-9]*/ /; s/Cols: [0-9]*-[0-9]*/___/'
-}
-
-for i in ael-test*; do
- echo -n Test: $i..................
- (cd $i; ../../../../utils/aelparse -n -d | grep -v -i 'seconds' > ../res.$i)
- do_filter < res.$i > $NEW
- do_filter < ref.$i > $ORIG
- if (diff -q $NEW $ORIG > /dev/null 2>&1 ) then
- echo PASSED
- rm res.$i
- else
- echo %%%%%%FAILED%%%%%%
- # diff -u ref.$i res.$i
- diff -u $ORIG $NEW
- fi
-
-done
-
-for i in ael-ntest*; do
- echo -n Test: $i.................
- (cd $i; ../../../../utils/aelparse -d | grep -v -i 'seconds' > ../res.$i)
- do_filter < res.$i > $NEW
- do_filter < ref.$i > $ORIG
- if (diff -q $NEW $ORIG > /dev/null 2>&1 ) then
- echo PASSED
- rm res.$i
- else
- echo %%%%%%FAILED%%%%%%
- # diff -u ref.$i res.$i
- diff -u $ORIG $NEW
- fi
-
-done
-
-for i in ael-vtest*; do
- echo -n Test: $i.................
- (cd $i; ../../../../utils/aelparse -d -w -n | grep -v -i 'seconds' > ../res2.$i)
-
- if (diff -q ref.$i $i/extensions.conf.aeldump > /dev/null 2>&1 ) then
- echo PASSED
- rm res2.$i
- rm $i/extensions.conf.aeldump
- else
- echo %%%%%%FAILED%%%%%%
- # diff -u ref.$i res.$i
- diff -u ref.$i $i/extensions.conf.aeldump
- fi
-
-done
-rm $NEW $ORIG
diff --git a/1.4/pbx/ael/ael-test/setref b/1.4/pbx/ael/ael-test/setref
deleted file mode 100755
index b483f05ae..000000000
--- a/1.4/pbx/ael/ael-test/setref
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-for i in res.*; do
- refname=`echo $i | sed 's/^res/ref/'`
- echo $refname
- mv $i $refname
-done
diff --git a/1.4/pbx/ael/ael.flex b/1.4/pbx/ael/ael.flex
deleted file mode 100644
index 866e36170..000000000
--- a/1.4/pbx/ael/ael.flex
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Steve Murphy <murf@parsetree.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.
- */
-/*! \file
- *
- * \brief Flex scanner description of tokens used in AEL2 .
- *
- */
-
-/*
- * Start with flex options:
- *
- * %x describes the contexts we have: paren, semic and argg, plus INITIAL
- */
-%x paren semic argg comment
-
-/* prefix used for various globally-visible functions and variables.
- * This renames also yywrap, but since we do not use it, we just
- * add option noyywrap to remove it.
- */
-%option prefix="ael_yy"
-%option noyywrap
-
-/* yyfree normally just frees its arg. It can be null sometimes,
- which some systems will complain about, so, we'll define our own version */
-%option noyyfree
-
-/* batch gives a bit more performance if we are using it in
- * a non-interactive mode. We probably don't care much.
- */
-%option batch
-
-/* outfile is the filename to be used instead of lex.yy.c */
-%option outfile="ael_lex.c"
-
-/*
- * These are not supported in flex 2.5.4, but we need them
- * at the moment:
- * reentrant produces a thread-safe parser. Not 100% sure that
- * we require it, though.
- * bison-bridge passes an additional yylval argument to yylex().
- * bison-locations is probably not needed.
- */
-%option reentrant
-%option bison-bridge
-%option bison-locations
-
-%{
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#if defined(__Darwin__) || defined(__CYGWIN__)
-#define GLOB_ABORTED GLOB_ABEND
-#endif
-# include <glob.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "ael/ael.tab.h"
-#include "asterisk/ael_structs.h"
-
-/*
- * A stack to keep track of matching brackets ( [ { } ] )
- */
-static char pbcstack[400]; /* XXX missing size checks */
-static int pbcpos = 0;
-static void pbcpush(char x);
-static int pbcpop(char x);
-
-static int parencount = 0;
-
-/*
- * current line, column and filename, updated as we read the input.
- */
-static int my_lineno = 1; /* current line in the source */
-static int my_col = 1; /* current column in the source */
-char *my_file = 0; /* used also in the bison code */
-char *prev_word; /* XXX document it */
-
-#define MAX_INCLUDE_DEPTH 50
-
-/*
- * flex is not too smart, and generates global functions
- * without prototypes so the compiler may complain.
- * To avoid that, we declare the prototypes here,
- * even though these functions are not used.
- */
-int ael_yyget_column (yyscan_t yyscanner);
-void ael_yyset_column (int column_no , yyscan_t yyscanner);
-
-int ael_yyparse (struct parse_io *);
-
-/*
- * A stack to process include files.
- * As we switch into the new file we need to store the previous
- * state to restore it later.
- */
-struct stackelement {
- char *fname;
- int lineno;
- int colno;
- glob_t globbuf; /* the current globbuf */
- int globbuf_pos; /* where we are in the current globbuf */
- YY_BUFFER_STATE bufstate;
-};
-
-static struct stackelement include_stack[MAX_INCLUDE_DEPTH];
-static int include_stack_index = 0;
-static void setup_filestack(char *fnamebuf, int fnamebuf_siz, glob_t *globbuf, int globpos, yyscan_t xscan, int create);
-
-/*
- * if we use the @n feature of bison, we must supply the start/end
- * location of tokens in the structure pointed by yylloc.
- * Simple tokens are just assumed to be on the same line, so
- * the line number is constant, and the column is incremented
- * by the length of the token.
- */
-#ifdef FLEX_BETA /* set for 2.5.33 */
-
-/* compute the total number of lines and columns in the text
- * passed as argument.
- */
-static void pbcwhere(const char *text, int *line, int *col )
-{
- int loc_line = *line;
- int loc_col = *col;
- char c;
- while ( (c = *text++) ) {
- if ( c == '\t' ) {
- loc_col += 8 - (loc_col % 8);
- } else if ( c == '\n' ) {
- loc_line++;
- loc_col = 1;
- } else
- loc_col++;
- }
- *line = loc_line;
- *col = loc_col;
-}
-
-#define STORE_POS do { \
- yylloc->first_line = yylloc->last_line = my_lineno; \
- yylloc->first_column=my_col; \
- yylloc->last_column=my_col+yyleng-1; \
- my_col+=yyleng; \
- } while (0)
-
-#define STORE_LOC do { \
- yylloc->first_line = my_lineno; \
- yylloc->first_column=my_col; \
- pbcwhere(yytext, &my_lineno, &my_col); \
- yylloc->last_line = my_lineno; \
- yylloc->last_column = my_col - 1; \
- } while (0)
-#else
-#define STORE_POS
-#define STORE_LOC
-#endif
-%}
-
-
-NOPARENS ([^()\[\]\{\}]|\\[()\[\]\{\}])*
-
-NOARGG ([^(),\{\}\[\]]|\\[,()\[\]\{\}])*
-
-NOSEMIC ([^;()\{\}\[\]]|\\[;()\[\]\{\}])*
-
-%%
-
-\{ { STORE_POS; return LC;}
-\} { STORE_POS; return RC;}
-\( { STORE_POS; return LP;}
-\) { STORE_POS; return RP;}
-\; { STORE_POS; return SEMI;}
-\= { STORE_POS; return EQ;}
-\, { STORE_POS; return COMMA;}
-\: { STORE_POS; return COLON;}
-\& { STORE_POS; return AMPER;}
-\| { STORE_POS; return BAR;}
-\=\> { STORE_POS; return EXTENMARK;}
-\@ { STORE_POS; return AT;}
-\/\/[^\n]* {/*comment*/}
-context { STORE_POS; return KW_CONTEXT;}
-abstract { STORE_POS; return KW_ABSTRACT;}
-extend { STORE_POS; return KW_EXTEND;}
-macro { STORE_POS; return KW_MACRO;};
-globals { STORE_POS; return KW_GLOBALS;}
-ignorepat { STORE_POS; return KW_IGNOREPAT;}
-switch { STORE_POS; return KW_SWITCH;}
-if { STORE_POS; return KW_IF;}
-ifTime { STORE_POS; return KW_IFTIME;}
-random { STORE_POS; return KW_RANDOM;}
-regexten { STORE_POS; return KW_REGEXTEN;}
-hint { STORE_POS; return KW_HINT;}
-else { STORE_POS; return KW_ELSE;}
-goto { STORE_POS; return KW_GOTO;}
-jump { STORE_POS; return KW_JUMP;}
-return { STORE_POS; return KW_RETURN;}
-break { STORE_POS; return KW_BREAK;}
-continue { STORE_POS; return KW_CONTINUE;}
-for { STORE_POS; return KW_FOR;}
-while { STORE_POS; return KW_WHILE;}
-case { STORE_POS; return KW_CASE;}
-default { STORE_POS; return KW_DEFAULT;}
-pattern { STORE_POS; return KW_PATTERN;}
-catch { STORE_POS; return KW_CATCH;}
-switches { STORE_POS; return KW_SWITCHES;}
-eswitches { STORE_POS; return KW_ESWITCHES;}
-includes { STORE_POS; return KW_INCLUDES;}
-"/*" { BEGIN(comment); my_col += 2; }
-
-<comment>[^*\n]* { my_col += yyleng; }
-<comment>[^*\n]*\n { ++my_lineno; my_col=1;}
-<comment>"*"+[^*/\n]* { my_col += yyleng; }
-<comment>"*"+[^*/\n]*\n { ++my_lineno; my_col=1;}
-<comment>"*/" { my_col += 2; BEGIN(INITIAL); }
-
-\n { my_lineno++; my_col = 1; }
-[ ]+ { my_col += yyleng; }
-[\t]+ { my_col += (yyleng*8)-(my_col%8); }
-
-[-a-zA-Z0-9'"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9'"_/.!\*\+\<\>\{\}$#\[\]]* {
- STORE_POS;
- yylval->str = strdup(yytext);
- prev_word = yylval->str;
- return word;
- }
-
-
-
- /*
- * context used for arguments of if_head, random_head, switch_head,
- * for (last statement), while (XXX why not iftime_head ?).
- * End with the matching parentheses.
- * A comma at the top level is valid here, unlike in argg where it
- * is an argument separator so it must be returned as a token.
- */
-<paren>{NOPARENS}\) {
- if ( pbcpop(')') ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno, my_col, yytext);
- BEGIN(0);
- yylval->str = strdup(yytext);
- prev_word = 0;
- return word;
- }
- parencount--;
- if ( parencount >= 0) {
- yymore();
- } else {
- STORE_LOC;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
- unput(')');
- BEGIN(0);
- return word;
- }
- }
-
-<paren>{NOPARENS}[\(\[\{] {
- char c = yytext[yyleng-1];
- if (c == '(')
- parencount++;
- pbcpush(c);
- yymore();
- }
-
-<paren>{NOPARENS}[\]\}] {
- char c = yytext[yyleng-1];
- if ( pbcpop(c)) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n",
- my_file, my_lineno, my_col, c);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
- yymore();
- }
-
-
- /*
- * handlers for arguments to a macro or application calls.
- * We enter this context when we find the initial '(' and
- * stay here until we close all matching parentheses,
- * and find the comma (argument separator) or the closing ')'
- * of the (external) call, which happens when parencount == 0
- * before the decrement.
- */
-<argg>{NOARGG}[\(\[\{] {
- char c = yytext[yyleng-1];
- if (c == '(')
- parencount++;
- pbcpush(c);
- yymore();
- }
-
-<argg>{NOARGG}\) {
- if ( pbcpop(')') ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno, my_col);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
-
- parencount--;
- if( parencount >= 0){
- yymore();
- } else {
- STORE_LOC;
- BEGIN(0);
- if ( !strcmp(yytext, ")") )
- return RP;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
- unput(')');
- return word;
- }
- }
-
-<argg>{NOARGG}\, {
- if( parencount != 0) { /* printf("Folding in a comma!\n"); */
- yymore();
- } else {
- STORE_LOC;
- if( !strcmp(yytext,"," ) )
- return COMMA;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0';
- unput(',');
- return word;
- }
- }
-
-<argg>{NOARGG}[\]\}] {
- char c = yytext[yyleng-1];
- if ( pbcpop(c) ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
- yymore();
- }
-
- /*
- * context used to find tokens in the right hand side of assignments,
- * or in the first and second operand of a 'for'. As above, match
- * commas and use ';' as a separator (hence return it as a separate token).
- */
-<semic>{NOSEMIC}[\(\[\{] {
- char c = yytext[yyleng-1];
- yymore();
- pbcpush(c);
- }
-
-<semic>{NOSEMIC}[\)\]\}] {
- char c = yytext[yyleng-1];
- if ( pbcpop(c) ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
- yymore();
- }
-
-<semic>{NOSEMIC}; {
- STORE_LOC;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0';
- unput(';');
- BEGIN(0);
- return word;
- }
-
-\#include[ \t]+\"[^\"]+\" {
- char fnamebuf[1024],*p1,*p2;
- int glob_ret;
- glob_t globbuf; /* the current globbuf */
- int globbuf_pos = -1; /* where we are in the current globbuf */
- globbuf.gl_offs = 0; /* initialize it to silence gcc */
-
- p1 = strchr(yytext,'"');
- p2 = strrchr(yytext,'"');
- if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col);
- } else if ( (int)(p2-p1) > sizeof(fnamebuf) - 1 ) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10);
- } else {
- strncpy(fnamebuf, p1+1, p2-p1-1);
- fnamebuf[p2-p1-1] = 0;
-
-#ifdef SOLARIS
- glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf);
-#else
- glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
-#endif
- if (glob_ret == GLOB_NOSPACE) {
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: Not enough memory\n", fnamebuf);
- } else if (glob_ret == GLOB_ABORTED) {
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: Read error\n", fnamebuf);
- } else if (glob_ret == GLOB_NOMATCH) {
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: No matches!\n", fnamebuf);
- } else {
- globbuf_pos = 0;
- }
- }
- if (globbuf_pos > -1) {
- setup_filestack(fnamebuf, sizeof(fnamebuf), &globbuf, 0, yyscanner, 1);
- }
- }
-
-
-<<EOF>> {
- char fnamebuf[2048];
- if (include_stack_index > 0 && include_stack[include_stack_index-1].globbuf_pos < include_stack[include_stack_index-1].globbuf.gl_pathc-1) {
- yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
- include_stack[include_stack_index-1].globbuf_pos++;
- setup_filestack(fnamebuf, sizeof(fnamebuf), &include_stack[include_stack_index-1].globbuf, include_stack[include_stack_index-1].globbuf_pos, yyscanner, 0);
- /* finish this */
-
- } else {
- if (include_stack[include_stack_index].fname) {
- free(include_stack[include_stack_index].fname);
- include_stack[include_stack_index].fname = 0;
- }
- if (my_file) {
- free(my_file);
- my_file = 0;
- }
- if ( --include_stack_index < 0 ) {
- yyterminate();
- } else {
- globfree(&include_stack[include_stack_index].globbuf);
- include_stack[include_stack_index].globbuf_pos = -1;
-
- yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
- yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner );
- my_lineno = include_stack[include_stack_index].lineno;
- my_col = include_stack[include_stack_index].colno;
- my_file = strdup(include_stack[include_stack_index].fname);
- }
- }
- }
-
-%%
-
-static void pbcpush(char x)
-{
- pbcstack[pbcpos++] = x;
-}
-
-void ael_yyfree(void *ptr, yyscan_t yyscanner)
-{
- if (ptr)
- free( (char*) ptr );
-}
-
-static int pbcpop(char x)
-{
- if ( ( x == ')' && pbcstack[pbcpos-1] == '(' )
- || ( x == ']' && pbcstack[pbcpos-1] == '[' )
- || ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
- pbcpos--;
- return 0;
- }
- return 1; /* error */
-}
-
-static int c_prevword(void)
-{
- char *c = prev_word;
- if (c == NULL)
- return 0;
- while ( *c ) {
- switch (*c) {
- case '{':
- case '[':
- case '(':
- pbcpush(*c);
- break;
- case '}':
- case ']':
- case ')':
- if (pbcpop(*c))
- return 1;
- break;
- }
- c++;
- }
- return 0;
-}
-
-
-/*
- * The following three functions, reset_*, are used in the bison
- * code to switch context. As a consequence, we need to
- * declare them global and add a prototype so that the
- * compiler does not complain.
- *
- * NOTE: yyg is declared because it is used in the BEGIN macros,
- * though that should be hidden as the macro changes
- * depending on the flex options that we use - in particular,
- * %reentrant changes the way the macro is declared;
- * without %reentrant, BEGIN uses yystart instead of yyg
- */
-
-void reset_parencount(yyscan_t yyscanner );
-void reset_parencount(yyscan_t yyscanner )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- parencount = 0;
- pbcpos = 0;
- pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */
- c_prevword();
- BEGIN(paren);
-}
-
-void reset_semicount(yyscan_t yyscanner );
-void reset_semicount(yyscan_t yyscanner )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- pbcpos = 0;
- BEGIN(semic);
-}
-
-void reset_argcount(yyscan_t yyscanner );
-void reset_argcount(yyscan_t yyscanner )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- parencount = 0;
- pbcpos = 0;
- pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */
- c_prevword();
- BEGIN(argg);
-}
-
-/* used elsewhere, but some local vars */
-struct pval *ael2_parse(char *filename, int *errors)
-{
- struct pval *pval;
- struct parse_io *io;
- char *buffer;
- struct stat stats;
- FILE *fin;
-
- /* extern int ael_yydebug; */
-
- io = calloc(sizeof(struct parse_io),1);
- /* reset the global counters */
- prev_word = 0;
- my_lineno = 1;
- include_stack_index=0;
- my_col = 0;
- /* ael_yydebug = 1; */
- ael_yylex_init(&io->scanner);
- fin = fopen(filename,"r");
- if ( !fin ) {
- ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
- *errors = 1;
- return 0;
- }
- if (my_file)
- free(my_file);
- my_file = strdup(filename);
- stat(filename, &stats);
- buffer = (char*)malloc(stats.st_size+2);
- fread(buffer, 1, stats.st_size, fin);
- buffer[stats.st_size]=0;
- fclose(fin);
-
- ael_yy_scan_string (buffer ,io->scanner);
- ael_yyset_lineno(1 , io->scanner);
-
- /* ael_yyset_in (fin , io->scanner); OLD WAY */
-
- ael_yyparse(io);
-
-
- pval = io->pval;
- *errors = io->syntax_error_count;
-
- ael_yylex_destroy(io->scanner);
- free(buffer);
- free(io);
-
- return pval;
-}
-
-static void setup_filestack(char *fnamebuf2, int fnamebuf_siz, glob_t *globbuf, int globpos, yyscan_t yyscanner, int create)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- int error, i;
- FILE *in1;
- char fnamebuf[2048];
-
- if (globbuf && globbuf->gl_pathv && globbuf->gl_pathc > 0)
-#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL)
- strncpy(fnamebuf, globbuf->gl_pathv[globpos], fnamebuf_siz);
-#else
- ast_copy_string(fnamebuf, globbuf->gl_pathv[globpos], fnamebuf_siz);
-#endif
- else {
- ast_log(LOG_ERROR,"Include file name not present!\n");
- return;
- }
- for (i=0; i<include_stack_index; i++) {
- if ( !strcmp(fnamebuf,include_stack[i].fname )) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n",
- my_file, my_lineno, my_col, fnamebuf);
- break;
- }
- }
- error = 1;
- if (i == include_stack_index)
- error = 0; /* we can use this file */
- if ( !error ) { /* valid file name */
- /* relative vs. absolute */
- if (fnamebuf[0] != '/')
- snprintf(fnamebuf2, fnamebuf_siz, "%s/%s", ast_config_AST_CONFIG_DIR, fnamebuf);
- else
-#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL)
- strncpy(fnamebuf2, fnamebuf, fnamebuf_siz);
-#else
- ast_copy_string(fnamebuf2, fnamebuf, fnamebuf_siz);
-#endif
- in1 = fopen( fnamebuf2, "r" );
-
- if ( ! in1 ) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf2);
- } else {
- char *buffer;
- struct stat stats;
- stat(fnamebuf2, &stats);
- buffer = (char*)malloc(stats.st_size+1);
- fread(buffer, 1, stats.st_size, in1);
- buffer[stats.st_size] = 0;
- ast_log(LOG_NOTICE," --Read in included file %s, %d chars\n",fnamebuf2, (int)stats.st_size);
- fclose(in1);
- if (include_stack[include_stack_index].fname) {
- free(include_stack[include_stack_index].fname);
- include_stack[include_stack_index].fname = 0;
- }
- include_stack[include_stack_index].fname = strdup(my_file);
- include_stack[include_stack_index].lineno = my_lineno;
- include_stack[include_stack_index].colno = my_col+yyleng;
- if (my_file)
- free(my_file);
- my_file = strdup(fnamebuf2);
- if (create)
- include_stack[include_stack_index].globbuf = *globbuf;
-
- include_stack[include_stack_index].globbuf_pos = 0;
-
- include_stack[include_stack_index].bufstate = YY_CURRENT_BUFFER;
- if (create)
- include_stack_index++;
- yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
- free(buffer);
- my_lineno = 1;
- my_col = 1;
- BEGIN(INITIAL);
- }
- }
-}
diff --git a/1.4/pbx/ael/ael.tab.c b/1.4/pbx/ael/ael.tab.c
deleted file mode 100644
index 78986ec09..000000000
--- a/1.4/pbx/ael/ael.tab.c
+++ /dev/null
@@ -1,3374 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.1a. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Bison version. */
-#define YYBISON_VERSION "2.1a"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 1
-
-/* Using locations. */
-#define YYLSP_NEEDED 1
-
-/* Substitute the variable and function names. */
-#define yyparse ael_yyparse
-#define yylex ael_yylex
-#define yyerror ael_yyerror
-#define yylval ael_yylval
-#define yychar ael_yychar
-#define yydebug ael_yydebug
-#define yynerrs ael_yynerrs
-#define yylloc ael_yylloc
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- KW_CONTEXT = 258,
- LC = 259,
- RC = 260,
- LP = 261,
- RP = 262,
- SEMI = 263,
- EQ = 264,
- COMMA = 265,
- COLON = 266,
- AMPER = 267,
- BAR = 268,
- AT = 269,
- KW_MACRO = 270,
- KW_GLOBALS = 271,
- KW_IGNOREPAT = 272,
- KW_SWITCH = 273,
- KW_IF = 274,
- KW_IFTIME = 275,
- KW_ELSE = 276,
- KW_RANDOM = 277,
- KW_ABSTRACT = 278,
- KW_EXTEND = 279,
- EXTENMARK = 280,
- KW_GOTO = 281,
- KW_JUMP = 282,
- KW_RETURN = 283,
- KW_BREAK = 284,
- KW_CONTINUE = 285,
- KW_REGEXTEN = 286,
- KW_HINT = 287,
- KW_FOR = 288,
- KW_WHILE = 289,
- KW_CASE = 290,
- KW_PATTERN = 291,
- KW_DEFAULT = 292,
- KW_CATCH = 293,
- KW_SWITCHES = 294,
- KW_ESWITCHES = 295,
- KW_INCLUDES = 296,
- word = 297
- };
-#endif
-/* Tokens. */
-#define KW_CONTEXT 258
-#define LC 259
-#define RC 260
-#define LP 261
-#define RP 262
-#define SEMI 263
-#define EQ 264
-#define COMMA 265
-#define COLON 266
-#define AMPER 267
-#define BAR 268
-#define AT 269
-#define KW_MACRO 270
-#define KW_GLOBALS 271
-#define KW_IGNOREPAT 272
-#define KW_SWITCH 273
-#define KW_IF 274
-#define KW_IFTIME 275
-#define KW_ELSE 276
-#define KW_RANDOM 277
-#define KW_ABSTRACT 278
-#define KW_EXTEND 279
-#define EXTENMARK 280
-#define KW_GOTO 281
-#define KW_JUMP 282
-#define KW_RETURN 283
-#define KW_BREAK 284
-#define KW_CONTINUE 285
-#define KW_REGEXTEN 286
-#define KW_HINT 287
-#define KW_FOR 288
-#define KW_WHILE 289
-#define KW_CASE 290
-#define KW_PATTERN 291
-#define KW_DEFAULT 292
-#define KW_CATCH 293
-#define KW_SWITCHES 294
-#define KW_ESWITCHES 295
-#define KW_INCLUDES 296
-#define word 297
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 1 "ael.y"
-
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Steve Murphy <murf@parsetree.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.
- */
-/*! \file
- *
- * \brief Bison Grammar description of AEL2.
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/ael_structs.h"
-
-static pval * linku1(pval *head, pval *tail);
-static void set_dads(pval *dad, pval *child_list);
-void reset_parencount(yyscan_t yyscanner);
-void reset_semicount(yyscan_t yyscanner);
-void reset_argcount(yyscan_t yyscanner );
-
-#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
-#define YYERROR_VERBOSE 1
-
-extern char *my_file;
-#ifdef AAL_ARGCHECK
-int ael_is_funcname(char *name);
-#endif
-static char *ael_token_subst(const char *mess);
-
-
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 1
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 54 "ael.y"
-{
- int intval; /* integer value, typically flags */
- char *str; /* strings */
- struct pval *pval; /* full objects */
-}
-/* Line 198 of yacc.c. */
-#line 236 "ael.tab.c"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-/* Copy the second part of user declarations. */
-#line 60 "ael.y"
-
- /* declaring these AFTER the union makes things a lot simpler! */
-void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s);
-int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void * yyscanner);
-
-/* create a new object with start-end marker */
-static pval *npval(pvaltype type, int first_line, int last_line,
- int first_column, int last_column);
-
-/* create a new object with start-end marker, simplified interface.
- * Must be declared here because YYLTYPE is not known before
- */
-static pval *npval2(pvaltype type, YYLTYPE *first, YYLTYPE *last);
-
-/* another frontend for npval, this time for a string */
-static pval *nword(char *string, YYLTYPE *pos);
-
-/* update end position of an object, return the object */
-static pval *update_last(pval *, YYLTYPE *);
-
-
-/* Line 221 of yacc.c. */
-#line 281 "ael.tab.c"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int i)
-#else
-static int
-YYID (i)
- int i;
-#endif
-{
- return i;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# ifdef __cplusplus
-extern "C" {
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifdef __cplusplus
-}
-# endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yytype_int16 yyss;
- YYSTYPE yyvs;
- YYLTYPE yyls;
-};
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 17
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 311
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 43
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 54
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 137
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 276
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 297
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const yytype_uint8 yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint16 yyprhs[] =
-{
- 0, 0, 3, 5, 7, 10, 13, 15, 17, 19,
- 21, 23, 25, 32, 34, 35, 37, 40, 43, 52,
- 57, 58, 61, 64, 65, 71, 72, 74, 78, 81,
- 82, 85, 88, 90, 92, 94, 96, 98, 100, 103,
- 105, 110, 114, 119, 127, 136, 137, 140, 143, 149,
- 151, 159, 160, 165, 168, 171, 176, 178, 181, 183,
- 186, 190, 194, 196, 199, 203, 205, 208, 212, 218,
- 222, 224, 228, 232, 235, 236, 237, 238, 251, 255,
- 257, 261, 264, 267, 268, 274, 277, 280, 283, 287,
- 289, 292, 293, 295, 299, 303, 309, 315, 321, 327,
- 328, 331, 334, 339, 340, 346, 350, 351, 355, 359,
- 362, 364, 365, 367, 368, 372, 373, 376, 381, 385,
- 390, 391, 394, 396, 398, 404, 409, 414, 415, 419,
- 425, 428, 430, 434, 437, 441, 444, 449
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 44, 0, -1, 45, -1, 46, -1, 45, 46, -1,
- 45, 1, -1, 48, -1, 50, -1, 51, -1, 8,
- -1, 42, -1, 37, -1, 49, 3, 47, 4, 56,
- 5, -1, 23, -1, -1, 24, -1, 24, 23, -1,
- 23, 24, -1, 15, 42, 6, 55, 7, 4, 89,
- 5, -1, 16, 4, 52, 5, -1, -1, 53, 52,
- -1, 1, 52, -1, -1, 42, 9, 54, 42, 8,
- -1, -1, 42, -1, 55, 10, 42, -1, 55, 1,
- -1, -1, 57, 56, -1, 1, 56, -1, 59, -1,
- 96, -1, 91, -1, 92, -1, 58, -1, 53, -1,
- 42, 1, -1, 8, -1, 17, 25, 42, 8, -1,
- 42, 25, 71, -1, 31, 42, 25, 71, -1, 32,
- 6, 67, 7, 42, 25, 71, -1, 31, 32, 6,
- 67, 7, 42, 25, 71, -1, -1, 71, 60, -1,
- 1, 60, -1, 68, 11, 68, 11, 68, -1, 42,
- -1, 61, 13, 68, 13, 68, 13, 68, -1, -1,
- 6, 64, 66, 7, -1, 19, 63, -1, 22, 63,
- -1, 20, 6, 62, 7, -1, 42, -1, 42, 42,
- -1, 42, -1, 67, 42, -1, 67, 11, 42, -1,
- 67, 12, 42, -1, 42, -1, 42, 42, -1, 42,
- 42, 42, -1, 42, -1, 42, 42, -1, 69, 11,
- 42, -1, 18, 63, 4, 87, 5, -1, 4, 60,
- 5, -1, 53, -1, 26, 77, 8, -1, 27, 79,
- 8, -1, 42, 11, -1, -1, -1, -1, 33, 6,
- 72, 42, 8, 73, 42, 8, 74, 42, 7, 71,
- -1, 34, 63, 71, -1, 70, -1, 12, 80, 8,
- -1, 84, 8, -1, 42, 8, -1, -1, 84, 9,
- 75, 42, 8, -1, 29, 8, -1, 28, 8, -1,
- 30, 8, -1, 65, 71, 76, -1, 8, -1, 21,
- 71, -1, -1, 69, -1, 69, 13, 69, -1, 69,
- 10, 69, -1, 69, 13, 69, 13, 69, -1, 69,
- 10, 69, 10, 69, -1, 37, 13, 69, 13, 69,
- -1, 37, 10, 69, 10, 69, -1, -1, 10, 42,
- -1, 69, 78, -1, 69, 78, 14, 47, -1, -1,
- 42, 6, 81, 86, 7, -1, 42, 6, 7, -1,
- -1, 42, 6, 83, -1, 82, 86, 7, -1, 82,
- 7, -1, 42, -1, -1, 66, -1, -1, 86, 10,
- 85, -1, -1, 88, 87, -1, 35, 42, 11, 60,
- -1, 37, 11, 60, -1, 36, 42, 11, 60, -1,
- -1, 90, 89, -1, 71, -1, 96, -1, 38, 42,
- 4, 60, 5, -1, 39, 4, 93, 5, -1, 40,
- 4, 93, 5, -1, -1, 42, 8, 93, -1, 42,
- 14, 42, 8, 93, -1, 1, 93, -1, 47, -1,
- 47, 13, 62, -1, 94, 8, -1, 95, 94, 8,
- -1, 95, 1, -1, 41, 4, 95, 5, -1, 41,
- 4, 5, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint16 yyrline[] =
-{
- 0, 185, 185, 188, 189, 190, 193, 194, 195, 196,
- 199, 200, 203, 212, 213, 214, 215, 216, 219, 225,
- 231, 232, 233, 236, 236, 243, 244, 245, 246, 249,
- 250, 251, 254, 255, 256, 257, 258, 259, 260, 261,
- 264, 269, 273, 278, 283, 293, 294, 295, 301, 306,
- 310, 318, 318, 322, 325, 328, 339, 340, 347, 348,
- 352, 356, 362, 363, 368, 376, 377, 381, 387, 396,
- 399, 400, 403, 406, 409, 410, 411, 409, 417, 421,
- 422, 423, 424, 427, 427, 460, 461, 462, 463, 467,
- 470, 471, 474, 475, 478, 481, 485, 489, 493, 499,
- 500, 504, 507, 513, 513, 518, 526, 526, 537, 544,
- 547, 548, 551, 552, 555, 558, 559, 562, 566, 570,
- 576, 577, 580, 581, 582, 588, 593, 598, 599, 600,
- 602, 605, 606, 613, 614, 615, 618, 621
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "KW_CONTEXT", "LC", "RC", "LP", "RP",
- "SEMI", "EQ", "COMMA", "COLON", "AMPER", "BAR", "AT", "KW_MACRO",
- "KW_GLOBALS", "KW_IGNOREPAT", "KW_SWITCH", "KW_IF", "KW_IFTIME",
- "KW_ELSE", "KW_RANDOM", "KW_ABSTRACT", "KW_EXTEND", "EXTENMARK",
- "KW_GOTO", "KW_JUMP", "KW_RETURN", "KW_BREAK", "KW_CONTINUE",
- "KW_REGEXTEN", "KW_HINT", "KW_FOR", "KW_WHILE", "KW_CASE", "KW_PATTERN",
- "KW_DEFAULT", "KW_CATCH", "KW_SWITCHES", "KW_ESWITCHES", "KW_INCLUDES",
- "word", "$accept", "file", "objects", "object", "context_name",
- "context", "opt_abstract", "macro", "globals", "global_statements",
- "assignment", "@1", "arglist", "elements", "element", "ignorepat",
- "extension", "statements", "timerange", "timespec", "test_expr", "@2",
- "if_like_head", "word_list", "hint_word", "word3_list", "goto_word",
- "switch_statement", "statement", "@3", "@4", "@5", "@6", "opt_else",
- "target", "opt_pri", "jumptarget", "macro_call", "@7",
- "application_call_head", "@8", "application_call", "opt_word",
- "eval_arglist", "case_statements", "case_statement", "macro_statements",
- "macro_statement", "switches", "eswitches", "switchlist",
- "included_entry", "includeslist", "includes", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const yytype_uint16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296, 297
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 43, 44, 45, 45, 45, 46, 46, 46, 46,
- 47, 47, 48, 49, 49, 49, 49, 49, 50, 51,
- 52, 52, 52, 54, 53, 55, 55, 55, 55, 56,
- 56, 56, 57, 57, 57, 57, 57, 57, 57, 57,
- 58, 59, 59, 59, 59, 60, 60, 60, 61, 61,
- 62, 64, 63, 65, 65, 65, 66, 66, 67, 67,
- 67, 67, 68, 68, 68, 69, 69, 69, 70, 71,
- 71, 71, 71, 71, 72, 73, 74, 71, 71, 71,
- 71, 71, 71, 75, 71, 71, 71, 71, 71, 71,
- 76, 76, 77, 77, 77, 77, 77, 77, 77, 78,
- 78, 79, 79, 81, 80, 80, 83, 82, 84, 84,
- 85, 85, 86, 86, 86, 87, 87, 88, 88, 88,
- 89, 89, 90, 90, 90, 91, 92, 93, 93, 93,
- 93, 94, 94, 95, 95, 95, 96, 96
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 1, 1, 2, 2, 1, 1, 1, 1,
- 1, 1, 6, 1, 0, 1, 2, 2, 8, 4,
- 0, 2, 2, 0, 5, 0, 1, 3, 2, 0,
- 2, 2, 1, 1, 1, 1, 1, 1, 2, 1,
- 4, 3, 4, 7, 8, 0, 2, 2, 5, 1,
- 7, 0, 4, 2, 2, 4, 1, 2, 1, 2,
- 3, 3, 1, 2, 3, 1, 2, 3, 5, 3,
- 1, 3, 3, 2, 0, 0, 0, 12, 3, 1,
- 3, 2, 2, 0, 5, 2, 2, 2, 3, 1,
- 2, 0, 1, 3, 3, 5, 5, 5, 5, 0,
- 2, 2, 4, 0, 5, 3, 0, 3, 3, 2,
- 1, 0, 1, 0, 3, 0, 2, 4, 3, 4,
- 0, 2, 1, 1, 5, 4, 4, 0, 3, 5,
- 2, 1, 3, 2, 3, 2, 4, 3
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
- 14, 9, 0, 0, 13, 15, 0, 0, 3, 6,
- 0, 7, 8, 0, 0, 17, 16, 1, 5, 4,
- 0, 25, 0, 0, 0, 0, 11, 10, 0, 26,
- 0, 22, 23, 19, 21, 0, 28, 0, 0, 0,
- 0, 39, 0, 0, 0, 0, 0, 0, 0, 37,
- 0, 0, 36, 32, 34, 35, 33, 120, 27, 0,
- 31, 0, 0, 0, 0, 0, 0, 0, 38, 0,
- 12, 30, 0, 89, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 70, 0,
- 79, 122, 113, 0, 0, 120, 123, 24, 0, 0,
- 0, 58, 0, 0, 0, 0, 0, 137, 131, 0,
- 0, 41, 0, 0, 0, 0, 0, 51, 0, 53,
- 0, 54, 0, 65, 92, 0, 99, 0, 86, 85,
- 87, 74, 0, 0, 106, 82, 73, 91, 109, 56,
- 112, 0, 81, 83, 18, 121, 40, 0, 42, 0,
- 0, 0, 59, 130, 0, 0, 125, 126, 0, 133,
- 135, 136, 0, 47, 69, 46, 103, 80, 0, 115,
- 49, 0, 0, 0, 0, 0, 66, 0, 0, 0,
- 71, 0, 101, 72, 0, 78, 0, 107, 0, 88,
- 57, 108, 111, 0, 0, 0, 60, 61, 128, 0,
- 132, 134, 105, 113, 0, 0, 0, 0, 0, 115,
- 63, 0, 55, 0, 0, 0, 94, 67, 93, 100,
- 0, 0, 0, 90, 110, 114, 0, 0, 0, 0,
- 0, 52, 0, 0, 0, 68, 116, 64, 62, 0,
- 0, 0, 0, 0, 0, 102, 75, 124, 84, 0,
- 43, 129, 104, 0, 0, 118, 0, 0, 98, 97,
- 96, 95, 0, 44, 117, 119, 0, 48, 0, 0,
- 76, 50, 0, 0, 0, 77
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int16 yydefgoto[] =
-{
- -1, 6, 7, 8, 108, 9, 10, 11, 12, 24,
- 88, 39, 30, 50, 51, 52, 53, 113, 171, 172,
- 118, 168, 89, 140, 102, 173, 124, 90, 114, 184,
- 262, 272, 193, 189, 125, 182, 127, 116, 203, 92,
- 187, 93, 225, 141, 208, 209, 94, 95, 54, 55,
- 105, 109, 110, 56
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -206
-static const yytype_int16 yypact[] =
-{
- 65, -206, 2, 64, -1, 70, 84, 231, -206, -206,
- 108, -206, -206, 120, 13, -206, -206, -206, -206, -206,
- 29, 88, 13, 130, 163, 13, -206, -206, 165, -206,
- 75, -206, -206, -206, -206, 8, -206, 171, 134, 136,
- 8, -206, 154, -22, 178, 182, 186, 189, 61, -206,
- 200, 8, -206, -206, -206, -206, -206, 169, -206, 198,
- -206, 152, 203, 187, 177, 14, 14, 23, -206, 196,
- -206, -206, 128, -206, 179, 207, 207, 214, 207, 58,
- 185, 220, 225, 227, 230, 207, 195, 174, -206, 196,
- -206, -206, 17, 94, 235, 169, -206, -206, 233, 177,
- 196, -206, 19, 14, 55, 237, 238, -206, 232, 236,
- 16, -206, 86, 243, 86, 244, 241, -206, 247, -206,
- 210, -206, 97, 211, 24, 248, 107, 249, -206, -206,
- -206, -206, 196, 254, -206, -206, -206, 239, -206, 217,
- -206, 117, -206, -206, -206, -206, -206, 67, -206, 219,
- 221, 222, -206, -206, 14, 223, -206, -206, 210, -206,
- -206, -206, 258, -206, -206, -206, 255, -206, 226, 106,
- 0, 256, 260, 259, 185, 185, -206, 185, 229, 185,
- -206, 234, 261, -206, 240, -206, 128, -206, 196, -206,
- -206, -206, 242, 245, 246, 252, -206, -206, -206, 264,
- -206, -206, -206, 226, 266, 250, 251, 263, 273, 106,
- 253, 257, -206, 257, 142, 138, 149, -206, 161, -206,
- 29, 271, 275, -206, -206, -206, 277, 265, 196, 14,
- 127, -206, 270, 272, 86, -206, -206, -206, 262, 276,
- 280, 185, 185, 185, 185, -206, -206, -206, -206, 196,
- -206, -206, -206, 86, 86, -206, 257, 257, 283, 283,
- 283, 283, 267, -206, -206, -206, 284, -206, 278, 257,
- -206, -206, 268, 289, 196, -206
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int16 yypgoto[] =
-{
- -206, -206, -206, 291, -19, -206, -206, -206, -206, 113,
- 32, -206, -206, -18, -206, -206, -206, -109, -206, 143,
- -49, -206, -206, 132, 204, -205, -78, -206, -57, -206,
- -206, -206, -206, -206, -206, -206, -206, -206, -206, -206,
- -206, -206, -206, 99, 96, -206, 212, -206, -206, -206,
- -62, 201, -206, -50
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -128
-static const yytype_int16 yytable[] =
-{
- 91, 28, 126, 163, 106, 165, 239, 96, 240, 40,
- 62, -62, 111, -29, 22, 103, 41, 160, -20, -127,
- 63, 161, 60, 15, 138, 42, 149, 119, 107, 121,
- 150, 151, 137, 71, 177, 178, 132, 179, 91, 43,
- 44, 153, 210, 148, 13, 96, 25, 45, 46, 47,
- 48, 266, 267, 26, 25, 23, 104, 25, 27, 139,
- 26, 152, 68, 154, 271, 27, 26, 49, 14, 155,
- 32, 27, 49, 1, 194, 185, 36, 222, 150, 151,
- 2, 3, 37, 49, 17, 38, 69, 112, 4, 5,
- 72, -45, 198, 16, 73, 122, 214, 215, 74, 216,
- 123, 218, 142, 143, 75, 76, 77, 174, 78, 152,
- 175, 20, 79, 80, 81, 82, 83, 181, 178, 84,
- 85, -45, -45, -45, 191, 255, 21, 192, 87, 112,
- 29, 223, 72, -45, 252, 31, 73, 192, 34, 32,
- 74, 205, 206, 207, 264, 265, 75, 76, 77, 178,
- 78, 242, 241, 178, 79, 80, 81, 82, 83, 243,
- 178, 84, 85, 258, 259, 260, 261, 251, 33, 35,
- 87, 250, 178, 72, 244, 57, 58, 73, 59, 61,
- 134, 74, 135, 32, 64, 136, 65, 75, 76, 77,
- 66, 78, 263, 67, 98, 79, 80, 81, 82, 83,
- 72, 245, 84, 85, 73, 70, 97, 86, 74, 99,
- 47, 87, 100, 117, 75, 76, 77, 275, 78, 101,
- 120, 115, 79, 80, 81, 82, 83, 123, 128, 84,
- 85, -2, 18, 129, -14, 130, 131, 133, 87, 1,
- 144, 146, 156, 157, 159, 158, 2, 3, 164, 167,
- 166, 169, 170, 176, 4, 5, 180, 183, 186, 190,
- 188, 195, 202, 196, 197, 199, 201, 212, 139, 211,
- 213, 217, 229, 231, 234, 220, 219, 228, 235, 246,
- 247, 253, 221, 254, 224, 248, 270, 226, 227, 256,
- 249, 257, 232, 233, 178, 237, 274, 269, 19, 238,
- 204, 200, 230, 147, 210, 236, 0, 145, 0, 268,
- 273, 162
-};
-
-static const yytype_int16 yycheck[] =
-{
- 57, 20, 80, 112, 66, 114, 211, 57, 213, 1,
- 32, 11, 69, 5, 1, 1, 8, 1, 5, 5,
- 42, 5, 40, 24, 7, 17, 7, 76, 5, 78,
- 11, 12, 89, 51, 10, 11, 85, 13, 95, 31,
- 32, 103, 42, 100, 42, 95, 14, 39, 40, 41,
- 42, 256, 257, 37, 22, 42, 42, 25, 42, 42,
- 37, 42, 1, 8, 269, 42, 37, 35, 4, 14,
- 9, 42, 40, 8, 7, 132, 1, 186, 11, 12,
- 15, 16, 7, 51, 0, 10, 25, 1, 23, 24,
- 4, 5, 154, 23, 8, 37, 174, 175, 12, 177,
- 42, 179, 8, 9, 18, 19, 20, 10, 22, 42,
- 13, 3, 26, 27, 28, 29, 30, 10, 11, 33,
- 34, 35, 36, 37, 7, 234, 6, 10, 42, 1,
- 42, 188, 4, 5, 7, 22, 8, 10, 25, 9,
- 12, 35, 36, 37, 253, 254, 18, 19, 20, 11,
- 22, 13, 10, 11, 26, 27, 28, 29, 30, 10,
- 11, 33, 34, 241, 242, 243, 244, 229, 5, 4,
- 42, 228, 11, 4, 13, 4, 42, 8, 42, 25,
- 6, 12, 8, 9, 6, 11, 4, 18, 19, 20,
- 4, 22, 249, 4, 42, 26, 27, 28, 29, 30,
- 4, 220, 33, 34, 8, 5, 8, 38, 12, 6,
- 41, 42, 25, 6, 18, 19, 20, 274, 22, 42,
- 6, 42, 26, 27, 28, 29, 30, 42, 8, 33,
- 34, 0, 1, 8, 3, 8, 6, 42, 42, 8,
- 5, 8, 5, 5, 8, 13, 15, 16, 5, 8,
- 6, 4, 42, 42, 23, 24, 8, 8, 4, 42,
- 21, 42, 7, 42, 42, 42, 8, 7, 42, 13,
- 11, 42, 8, 7, 11, 14, 42, 25, 5, 8,
- 5, 11, 42, 11, 42, 8, 8, 42, 42, 13,
- 25, 11, 42, 42, 11, 42, 7, 13, 7, 42,
- 168, 158, 203, 99, 42, 209, -1, 95, -1, 42,
- 42, 110
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
-{
- 0, 8, 15, 16, 23, 24, 44, 45, 46, 48,
- 49, 50, 51, 42, 4, 24, 23, 0, 1, 46,
- 3, 6, 1, 42, 52, 53, 37, 42, 47, 42,
- 55, 52, 9, 5, 52, 4, 1, 7, 10, 54,
- 1, 8, 17, 31, 32, 39, 40, 41, 42, 53,
- 56, 57, 58, 59, 91, 92, 96, 4, 42, 42,
- 56, 25, 32, 42, 6, 4, 4, 4, 1, 25,
- 5, 56, 4, 8, 12, 18, 19, 20, 22, 26,
- 27, 28, 29, 30, 33, 34, 38, 42, 53, 65,
- 70, 71, 82, 84, 89, 90, 96, 8, 42, 6,
- 25, 42, 67, 1, 42, 93, 93, 5, 47, 94,
- 95, 71, 1, 60, 71, 42, 80, 6, 63, 63,
- 6, 63, 37, 42, 69, 77, 69, 79, 8, 8,
- 8, 6, 63, 42, 6, 8, 11, 71, 7, 42,
- 66, 86, 8, 9, 5, 89, 8, 67, 71, 7,
- 11, 12, 42, 93, 8, 14, 5, 5, 13, 8,
- 1, 5, 94, 60, 5, 60, 6, 8, 64, 4,
- 42, 61, 62, 68, 10, 13, 42, 10, 11, 13,
- 8, 10, 78, 8, 72, 71, 4, 83, 21, 76,
- 42, 7, 10, 75, 7, 42, 42, 42, 93, 42,
- 62, 8, 7, 81, 66, 35, 36, 37, 87, 88,
- 42, 13, 7, 11, 69, 69, 69, 42, 69, 42,
- 14, 42, 60, 71, 42, 85, 42, 42, 25, 8,
- 86, 7, 42, 42, 11, 5, 87, 42, 42, 68,
- 68, 10, 13, 10, 13, 47, 8, 5, 8, 25,
- 71, 93, 7, 11, 11, 60, 13, 11, 69, 69,
- 69, 69, 73, 71, 60, 60, 68, 68, 42, 13,
- 8, 68, 74, 42, 7, 71
-};
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (&yylloc, parseio, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (0))
-
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval, &yylloc)
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value, Location, parseio); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp, struct parse_io *parseio)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parseio)
- FILE *yyoutput;
- int yytype;
- const YYSTYPE * const yyvaluep;
- const YYLTYPE * const yylocationp;
- struct parse_io *parseio;
-#endif
-{
- if (!yyvaluep)
- return;
- YYUSE (yylocationp);
- YYUSE (parseio);
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
-# endif
- switch (yytype)
- {
- default:
- break;
- }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp, struct parse_io *parseio)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parseio)
- FILE *yyoutput;
- int yytype;
- const YYSTYPE * const yyvaluep;
- const YYLTYPE * const yylocationp;
- struct parse_io *parseio;
-#endif
-{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- YY_LOCATION_PRINT (yyoutput, *yylocationp);
- YYFPRINTF (yyoutput, ": ");
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parseio);
- YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
-#else
-static void
-yy_stack_print (bottom, top)
- yytype_int16 *bottom;
- yytype_int16 *top;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct parse_io *parseio)
-#else
-static void
-yy_reduce_print (yyvsp, yylsp, yyrule, parseio)
- YYSTYPE *yyvsp;
- YYLTYPE *yylsp;
- int yyrule;
- struct parse_io *parseio;
-#endif
-{
- int yynrhs = yyr2[yyrule];
- int yyi;
- unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- fprintf (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- , &(yylsp[(yyi + 1) - (yynrhs)]) , parseio);
- fprintf (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, yylsp, Rule, parseio); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- size_t yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
-
- if (! (YYPACT_NINF < yyn && yyn < YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
-
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
-
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
-
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
- }
-}
-#endif /* YYERROR_VERBOSE */
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct parse_io *parseio)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, yylocationp, parseio)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
- YYLTYPE *yylocationp;
- struct parse_io *parseio;
-#endif
-{
- YYUSE (yyvaluep);
- YYUSE (yylocationp);
- YYUSE (parseio);
-
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
- switch (yytype)
- {
- case 42: /* "word" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1443 "ael.tab.c"
- break;
- case 45: /* "objects" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1451 "ael.tab.c"
- break;
- case 46: /* "object" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1459 "ael.tab.c"
- break;
- case 47: /* "context_name" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1464 "ael.tab.c"
- break;
- case 48: /* "context" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1472 "ael.tab.c"
- break;
- case 50: /* "macro" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1480 "ael.tab.c"
- break;
- case 51: /* "globals" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1488 "ael.tab.c"
- break;
- case 52: /* "global_statements" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1496 "ael.tab.c"
- break;
- case 53: /* "assignment" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1504 "ael.tab.c"
- break;
- case 55: /* "arglist" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1512 "ael.tab.c"
- break;
- case 56: /* "elements" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1520 "ael.tab.c"
- break;
- case 57: /* "element" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1528 "ael.tab.c"
- break;
- case 58: /* "ignorepat" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1536 "ael.tab.c"
- break;
- case 59: /* "extension" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1544 "ael.tab.c"
- break;
- case 60: /* "statements" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1552 "ael.tab.c"
- break;
- case 61: /* "timerange" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1557 "ael.tab.c"
- break;
- case 62: /* "timespec" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1565 "ael.tab.c"
- break;
- case 63: /* "test_expr" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1570 "ael.tab.c"
- break;
- case 65: /* "if_like_head" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1578 "ael.tab.c"
- break;
- case 66: /* "word_list" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1583 "ael.tab.c"
- break;
- case 68: /* "word3_list" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1588 "ael.tab.c"
- break;
- case 69: /* "goto_word" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1593 "ael.tab.c"
- break;
- case 70: /* "switch_statement" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1601 "ael.tab.c"
- break;
- case 71: /* "statement" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1609 "ael.tab.c"
- break;
- case 76: /* "opt_else" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1617 "ael.tab.c"
- break;
- case 77: /* "target" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1625 "ael.tab.c"
- break;
- case 78: /* "opt_pri" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1630 "ael.tab.c"
- break;
- case 79: /* "jumptarget" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1638 "ael.tab.c"
- break;
- case 80: /* "macro_call" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1646 "ael.tab.c"
- break;
- case 82: /* "application_call_head" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1654 "ael.tab.c"
- break;
- case 84: /* "application_call" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1662 "ael.tab.c"
- break;
- case 85: /* "opt_word" */
-#line 177 "ael.y"
- { free((yyvaluep->str));};
-#line 1667 "ael.tab.c"
- break;
- case 86: /* "eval_arglist" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1675 "ael.tab.c"
- break;
- case 87: /* "case_statements" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1683 "ael.tab.c"
- break;
- case 88: /* "case_statement" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1691 "ael.tab.c"
- break;
- case 89: /* "macro_statements" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1699 "ael.tab.c"
- break;
- case 90: /* "macro_statement" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1707 "ael.tab.c"
- break;
- case 91: /* "switches" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1715 "ael.tab.c"
- break;
- case 92: /* "eswitches" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1723 "ael.tab.c"
- break;
- case 93: /* "switchlist" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1731 "ael.tab.c"
- break;
- case 94: /* "included_entry" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1739 "ael.tab.c"
- break;
- case 95: /* "includeslist" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1747 "ael.tab.c"
- break;
- case 96: /* "includes" */
-#line 164 "ael.y"
- {
- destroy_pval((yyvaluep->pval));
- prev_word=0;
- };
-#line 1755 "ael.tab.c"
- break;
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (struct parse_io *parseio);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (struct parse_io *parseio)
-#else
-int
-yyparse (parseio)
- struct parse_io *parseio;
-#endif
-#endif
-{
- /* The look-ahead symbol. */
-int yychar;
-
-/* The semantic value of the look-ahead symbol. */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far. */
-int yynerrs;
-/* Location data for the look-ahead symbol. */
-YYLTYPE yylloc;
-
- int yystate;
- int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Look-ahead token as an internal (translated) token number. */
- int yytoken = 0;
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss = yyssa;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- YYSTYPE *yyvsp;
-
- /* The location stack. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
- /* The locations where the error started and ended. */
- YYLTYPE yyerror_range[2];
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
- YYSIZE_T yystacksize = YYINITDEPTH;
-
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
- YYLTYPE yyloc;
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss;
- yyvsp = yyvs;
- yylsp = yyls;
-#if YYLTYPE_IS_TRIVIAL
- /* Initialize the default location before parsing starts. */
- yylloc.first_line = yylloc.last_line = 1;
- yylloc.first_column = yylloc.last_column = 0;
-#endif
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
- YYLTYPE *yyls1 = yyls;
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yyls1, yysize * sizeof (*yylsp),
- &yystacksize);
- yyls = yyls1;
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
- YYSTACK_RELOCATE (yyls);
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
- yylsp = yyls + yysize - 1;
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
- /* Do appropriate processing given the current state. Read a
- look-ahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to look-ahead token. */
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a look-ahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the look-ahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- yystate = yyn;
- *++yyvsp = yylval;
- *++yylsp = yylloc;
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
- /* Default location. */
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 2:
-#line 185 "ael.y"
- { (yyval.pval) = parseio->pval = (yyvsp[(1) - (1)].pval); ;}
- break;
-
- case 3:
-#line 188 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 4:
-#line 189 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (2)].pval), (yyvsp[(2) - (2)].pval)); ;}
- break;
-
- case 5:
-#line 190 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (2)].pval);;}
- break;
-
- case 6:
-#line 193 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 7:
-#line 194 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 8:
-#line 195 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 9:
-#line 196 "ael.y"
- {(yyval.pval)=0;/* allow older docs to be read */;}
- break;
-
- case 10:
-#line 199 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
- break;
-
- case 11:
-#line 200 "ael.y"
- { (yyval.str) = strdup("default"); ;}
- break;
-
- case 12:
-#line 203 "ael.y"
- {
- (yyval.pval) = npval2(PV_CONTEXT, &(yylsp[(1) - (6)]), &(yylsp[(6) - (6)]));
- (yyval.pval)->u1.str = (yyvsp[(3) - (6)].str);
- (yyval.pval)->u2.statements = (yyvsp[(5) - (6)].pval);
- set_dads((yyval.pval),(yyvsp[(5) - (6)].pval));
- (yyval.pval)->u3.abstract = (yyvsp[(1) - (6)].intval);;}
- break;
-
- case 13:
-#line 212 "ael.y"
- { (yyval.intval) = 1; ;}
- break;
-
- case 14:
-#line 213 "ael.y"
- { (yyval.intval) = 0; ;}
- break;
-
- case 15:
-#line 214 "ael.y"
- { (yyval.intval) = 2; ;}
- break;
-
- case 16:
-#line 215 "ael.y"
- { (yyval.intval)=3; ;}
- break;
-
- case 17:
-#line 216 "ael.y"
- { (yyval.intval)=3; ;}
- break;
-
- case 18:
-#line 219 "ael.y"
- {
- (yyval.pval) = npval2(PV_MACRO, &(yylsp[(1) - (8)]), &(yylsp[(8) - (8)]));
- (yyval.pval)->u1.str = (yyvsp[(2) - (8)].str); (yyval.pval)->u2.arglist = (yyvsp[(4) - (8)].pval); (yyval.pval)->u3.macro_statements = (yyvsp[(7) - (8)].pval);
- set_dads((yyval.pval),(yyvsp[(7) - (8)].pval));;}
- break;
-
- case 19:
-#line 225 "ael.y"
- {
- (yyval.pval) = npval2(PV_GLOBALS, &(yylsp[(1) - (4)]), &(yylsp[(4) - (4)]));
- (yyval.pval)->u1.statements = (yyvsp[(3) - (4)].pval);
- set_dads((yyval.pval),(yyvsp[(3) - (4)].pval));;}
- break;
-
- case 20:
-#line 231 "ael.y"
- { (yyval.pval) = NULL; ;}
- break;
-
- case 21:
-#line 232 "ael.y"
- {(yyval.pval) = linku1((yyvsp[(1) - (2)].pval), (yyvsp[(2) - (2)].pval)); ;}
- break;
-
- case 22:
-#line 233 "ael.y"
- {(yyval.pval)=(yyvsp[(2) - (2)].pval);;}
- break;
-
- case 23:
-#line 236 "ael.y"
- { reset_semicount(parseio->scanner); ;}
- break;
-
- case 24:
-#line 236 "ael.y"
- {
- (yyval.pval) = npval2(PV_VARDEC, &(yylsp[(1) - (5)]), &(yylsp[(5) - (5)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (5)].str);
- (yyval.pval)->u2.val = (yyvsp[(4) - (5)].str); ;}
- break;
-
- case 25:
-#line 243 "ael.y"
- { (yyval.pval) = NULL; ;}
- break;
-
- case 26:
-#line 244 "ael.y"
- { (yyval.pval) = nword((yyvsp[(1) - (1)].str), &(yylsp[(1) - (1)])); ;}
- break;
-
- case 27:
-#line 245 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (3)].pval), nword((yyvsp[(3) - (3)].str), &(yylsp[(3) - (3)]))); ;}
- break;
-
- case 28:
-#line 246 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (2)].pval);;}
- break;
-
- case 29:
-#line 249 "ael.y"
- {(yyval.pval)=0;;}
- break;
-
- case 30:
-#line 250 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (2)].pval), (yyvsp[(2) - (2)].pval)); ;}
- break;
-
- case 31:
-#line 251 "ael.y"
- { (yyval.pval)=(yyvsp[(2) - (2)].pval);;}
- break;
-
- case 32:
-#line 254 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 33:
-#line 255 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 34:
-#line 256 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 35:
-#line 257 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 36:
-#line 258 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 37:
-#line 259 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 38:
-#line 260 "ael.y"
- {free((yyvsp[(1) - (2)].str)); (yyval.pval)=0;;}
- break;
-
- case 39:
-#line 261 "ael.y"
- {(yyval.pval)=0;/* allow older docs to be read */;}
- break;
-
- case 40:
-#line 264 "ael.y"
- {
- (yyval.pval) = npval2(PV_IGNOREPAT, &(yylsp[(1) - (4)]), &(yylsp[(4) - (4)]));
- (yyval.pval)->u1.str = (yyvsp[(3) - (4)].str);;}
- break;
-
- case 41:
-#line 269 "ael.y"
- {
- (yyval.pval) = npval2(PV_EXTENSION, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (3)].str);
- (yyval.pval)->u2.statements = (yyvsp[(3) - (3)].pval); set_dads((yyval.pval),(yyvsp[(3) - (3)].pval));;}
- break;
-
- case 42:
-#line 273 "ael.y"
- {
- (yyval.pval) = npval2(PV_EXTENSION, &(yylsp[(1) - (4)]), &(yylsp[(4) - (4)]));
- (yyval.pval)->u1.str = (yyvsp[(2) - (4)].str);
- (yyval.pval)->u2.statements = (yyvsp[(4) - (4)].pval); set_dads((yyval.pval),(yyvsp[(4) - (4)].pval));
- (yyval.pval)->u4.regexten=1;;}
- break;
-
- case 43:
-#line 278 "ael.y"
- {
- (yyval.pval) = npval2(PV_EXTENSION, &(yylsp[(1) - (7)]), &(yylsp[(7) - (7)]));
- (yyval.pval)->u1.str = (yyvsp[(5) - (7)].str);
- (yyval.pval)->u2.statements = (yyvsp[(7) - (7)].pval); set_dads((yyval.pval),(yyvsp[(7) - (7)].pval));
- (yyval.pval)->u3.hints = (yyvsp[(3) - (7)].str);;}
- break;
-
- case 44:
-#line 283 "ael.y"
- {
- (yyval.pval) = npval2(PV_EXTENSION, &(yylsp[(1) - (8)]), &(yylsp[(8) - (8)]));
- (yyval.pval)->u1.str = (yyvsp[(6) - (8)].str);
- (yyval.pval)->u2.statements = (yyvsp[(8) - (8)].pval); set_dads((yyval.pval),(yyvsp[(8) - (8)].pval));
- (yyval.pval)->u4.regexten=1;
- (yyval.pval)->u3.hints = (yyvsp[(4) - (8)].str);;}
- break;
-
- case 45:
-#line 293 "ael.y"
- { (yyval.pval) = NULL; ;}
- break;
-
- case 46:
-#line 294 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (2)].pval), (yyvsp[(2) - (2)].pval)); ;}
- break;
-
- case 47:
-#line 295 "ael.y"
- {(yyval.pval)=(yyvsp[(2) - (2)].pval);;}
- break;
-
- case 48:
-#line 301 "ael.y"
- {
- asprintf(&(yyval.str), "%s:%s:%s", (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str));
- free((yyvsp[(1) - (5)].str));
- free((yyvsp[(3) - (5)].str));
- free((yyvsp[(5) - (5)].str)); ;}
- break;
-
- case 49:
-#line 306 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
- break;
-
- case 50:
-#line 310 "ael.y"
- {
- (yyval.pval) = nword((yyvsp[(1) - (7)].str), &(yylsp[(1) - (7)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (7)].str), &(yylsp[(3) - (7)]));
- (yyval.pval)->next->next = nword((yyvsp[(5) - (7)].str), &(yylsp[(5) - (7)]));
- (yyval.pval)->next->next->next = nword((yyvsp[(7) - (7)].str), &(yylsp[(7) - (7)])); ;}
- break;
-
- case 51:
-#line 318 "ael.y"
- { reset_parencount(parseio->scanner); ;}
- break;
-
- case 52:
-#line 318 "ael.y"
- { (yyval.str) = (yyvsp[(3) - (4)].str); ;}
- break;
-
- case 53:
-#line 322 "ael.y"
- {
- (yyval.pval)= npval2(PV_IF, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)]));
- (yyval.pval)->u1.str = (yyvsp[(2) - (2)].str); ;}
- break;
-
- case 54:
-#line 325 "ael.y"
- {
- (yyval.pval) = npval2(PV_RANDOM, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)]));
- (yyval.pval)->u1.str=(yyvsp[(2) - (2)].str);;}
- break;
-
- case 55:
-#line 328 "ael.y"
- {
- (yyval.pval) = npval2(PV_IFTIME, &(yylsp[(1) - (4)]), &(yylsp[(4) - (4)]));
- (yyval.pval)->u1.list = (yyvsp[(3) - (4)].pval);
- prev_word = 0; ;}
- break;
-
- case 56:
-#line 339 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str);;}
- break;
-
- case 57:
-#line 340 "ael.y"
- {
- asprintf(&((yyval.str)), "%s%s", (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
- free((yyvsp[(1) - (2)].str));
- free((yyvsp[(2) - (2)].str));
- prev_word = (yyval.str);;}
- break;
-
- case 58:
-#line 347 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
- break;
-
- case 59:
-#line 348 "ael.y"
- {
- asprintf(&((yyval.str)), "%s %s", (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
- free((yyvsp[(1) - (2)].str));
- free((yyvsp[(2) - (2)].str)); ;}
- break;
-
- case 60:
-#line 352 "ael.y"
- {
- asprintf(&((yyval.str)), "%s:%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str));
- free((yyvsp[(1) - (3)].str));
- free((yyvsp[(3) - (3)].str)); ;}
- break;
-
- case 61:
-#line 356 "ael.y"
- { /* there are often '&' in hints */
- asprintf(&((yyval.str)), "%s&%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str));
- free((yyvsp[(1) - (3)].str));
- free((yyvsp[(3) - (3)].str));;}
- break;
-
- case 62:
-#line 362 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str);;}
- break;
-
- case 63:
-#line 363 "ael.y"
- {
- asprintf(&((yyval.str)), "%s%s", (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
- free((yyvsp[(1) - (2)].str));
- free((yyvsp[(2) - (2)].str));
- prev_word = (yyval.str);;}
- break;
-
- case 64:
-#line 368 "ael.y"
- {
- asprintf(&((yyval.str)), "%s%s%s", (yyvsp[(1) - (3)].str), (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str));
- free((yyvsp[(1) - (3)].str));
- free((yyvsp[(2) - (3)].str));
- free((yyvsp[(3) - (3)].str));
- prev_word=(yyval.str);;}
- break;
-
- case 65:
-#line 376 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str);;}
- break;
-
- case 66:
-#line 377 "ael.y"
- {
- asprintf(&((yyval.str)), "%s%s", (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
- free((yyvsp[(1) - (2)].str));
- free((yyvsp[(2) - (2)].str));;}
- break;
-
- case 67:
-#line 381 "ael.y"
- {
- asprintf(&((yyval.str)), "%s:%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str));
- free((yyvsp[(1) - (3)].str));
- free((yyvsp[(3) - (3)].str));;}
- break;
-
- case 68:
-#line 387 "ael.y"
- {
- (yyval.pval) = npval2(PV_SWITCH, &(yylsp[(1) - (5)]), &(yylsp[(5) - (5)]));
- (yyval.pval)->u1.str = (yyvsp[(2) - (5)].str);
- (yyval.pval)->u2.statements = (yyvsp[(4) - (5)].pval); set_dads((yyval.pval),(yyvsp[(4) - (5)].pval));;}
- break;
-
- case 69:
-#line 396 "ael.y"
- {
- (yyval.pval) = npval2(PV_STATEMENTBLOCK, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.list = (yyvsp[(2) - (3)].pval); set_dads((yyval.pval),(yyvsp[(2) - (3)].pval));;}
- break;
-
- case 70:
-#line 399 "ael.y"
- { (yyval.pval) = (yyvsp[(1) - (1)].pval); ;}
- break;
-
- case 71:
-#line 400 "ael.y"
- {
- (yyval.pval) = npval2(PV_GOTO, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.list = (yyvsp[(2) - (3)].pval);;}
- break;
-
- case 72:
-#line 403 "ael.y"
- {
- (yyval.pval) = npval2(PV_GOTO, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.list = (yyvsp[(2) - (3)].pval);;}
- break;
-
- case 73:
-#line 406 "ael.y"
- {
- (yyval.pval) = npval2(PV_LABEL, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (2)].str); ;}
- break;
-
- case 74:
-#line 409 "ael.y"
- {reset_semicount(parseio->scanner);;}
- break;
-
- case 75:
-#line 410 "ael.y"
- {reset_semicount(parseio->scanner);;}
- break;
-
- case 76:
-#line 411 "ael.y"
- {reset_parencount(parseio->scanner);;}
- break;
-
- case 77:
-#line 411 "ael.y"
- { /* XXX word_list maybe ? */
- (yyval.pval) = npval2(PV_FOR, &(yylsp[(1) - (12)]), &(yylsp[(12) - (12)]));
- (yyval.pval)->u1.for_init = (yyvsp[(4) - (12)].str);
- (yyval.pval)->u2.for_test=(yyvsp[(7) - (12)].str);
- (yyval.pval)->u3.for_inc = (yyvsp[(10) - (12)].str);
- (yyval.pval)->u4.for_statements = (yyvsp[(12) - (12)].pval); set_dads((yyval.pval),(yyvsp[(12) - (12)].pval));;}
- break;
-
- case 78:
-#line 417 "ael.y"
- {
- (yyval.pval) = npval2(PV_WHILE, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.str = (yyvsp[(2) - (3)].str);
- (yyval.pval)->u2.statements = (yyvsp[(3) - (3)].pval); set_dads((yyval.pval),(yyvsp[(3) - (3)].pval));;}
- break;
-
- case 79:
-#line 421 "ael.y"
- { (yyval.pval) = (yyvsp[(1) - (1)].pval); ;}
- break;
-
- case 80:
-#line 422 "ael.y"
- { (yyval.pval) = update_last((yyvsp[(2) - (3)].pval), &(yylsp[(2) - (3)])); ;}
- break;
-
- case 81:
-#line 423 "ael.y"
- { (yyval.pval) = update_last((yyvsp[(1) - (2)].pval), &(yylsp[(2) - (2)])); ;}
- break;
-
- case 82:
-#line 424 "ael.y"
- {
- (yyval.pval)= npval2(PV_APPLICATION_CALL, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (2)].str);;}
- break;
-
- case 83:
-#line 427 "ael.y"
- {reset_semicount(parseio->scanner);;}
- break;
-
- case 84:
-#line 427 "ael.y"
- {
- char *bufx;
- int tot=0;
- pval *pptr;
- (yyval.pval) = npval2(PV_VARDEC, &(yylsp[(1) - (5)]), &(yylsp[(5) - (5)]));
- (yyval.pval)->u2.val=(yyvsp[(4) - (5)].str);
- /* rebuild the original string-- this is not an app call, it's an unwrapped vardec, with a func call on the LHS */
- /* string to big to fit in the buffer? */
- tot+=strlen((yyvsp[(1) - (5)].pval)->u1.str);
- for(pptr=(yyvsp[(1) - (5)].pval)->u2.arglist;pptr;pptr=pptr->next) {
- tot+=strlen(pptr->u1.str);
- tot++; /* for a sep like a comma */
- }
- tot+=4; /* for safety */
- bufx = calloc(1, tot);
- strcpy(bufx,(yyvsp[(1) - (5)].pval)->u1.str);
- strcat(bufx,"(");
- /* XXX need to advance the pointer or the loop is very inefficient */
- for (pptr=(yyvsp[(1) - (5)].pval)->u2.arglist;pptr;pptr=pptr->next) {
- if ( pptr != (yyvsp[(1) - (5)].pval)->u2.arglist )
- strcat(bufx,",");
- strcat(bufx,pptr->u1.str);
- }
- strcat(bufx,")");
-#ifdef AAL_ARGCHECK
- if ( !ael_is_funcname((yyvsp[(1) - (5)].pval)->u1.str) )
- ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Function call? The name %s is not in my internal list of function names\n",
- my_file, (yylsp[(1) - (5)]).first_line, (yylsp[(1) - (5)]).first_column, (yylsp[(1) - (5)]).last_column, (yyvsp[(1) - (5)].pval)->u1.str);
-#endif
- (yyval.pval)->u1.str = bufx;
- destroy_pval((yyvsp[(1) - (5)].pval)); /* the app call it is not, get rid of that chain */
- prev_word = 0;
- ;}
- break;
-
- case 85:
-#line 460 "ael.y"
- { (yyval.pval) = npval2(PV_BREAK, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)])); ;}
- break;
-
- case 86:
-#line 461 "ael.y"
- { (yyval.pval) = npval2(PV_RETURN, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)])); ;}
- break;
-
- case 87:
-#line 462 "ael.y"
- { (yyval.pval) = npval2(PV_CONTINUE, &(yylsp[(1) - (2)]), &(yylsp[(2) - (2)])); ;}
- break;
-
- case 88:
-#line 463 "ael.y"
- {
- (yyval.pval) = update_last((yyvsp[(1) - (3)].pval), &(yylsp[(2) - (3)]));
- (yyval.pval)->u2.statements = (yyvsp[(2) - (3)].pval); set_dads((yyval.pval),(yyvsp[(2) - (3)].pval));
- (yyval.pval)->u3.else_statements = (yyvsp[(3) - (3)].pval);set_dads((yyval.pval),(yyvsp[(3) - (3)].pval));;}
- break;
-
- case 89:
-#line 467 "ael.y"
- { (yyval.pval)=0; ;}
- break;
-
- case 90:
-#line 470 "ael.y"
- { (yyval.pval) = (yyvsp[(2) - (2)].pval); ;}
- break;
-
- case 91:
-#line 471 "ael.y"
- { (yyval.pval) = NULL ; ;}
- break;
-
- case 92:
-#line 474 "ael.y"
- { (yyval.pval) = nword((yyvsp[(1) - (1)].str), &(yylsp[(1) - (1)])); ;}
- break;
-
- case 93:
-#line 475 "ael.y"
- {
- (yyval.pval) = nword((yyvsp[(1) - (3)].str), &(yylsp[(1) - (3)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (3)].str), &(yylsp[(3) - (3)])); ;}
- break;
-
- case 94:
-#line 478 "ael.y"
- {
- (yyval.pval) = nword((yyvsp[(1) - (3)].str), &(yylsp[(1) - (3)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (3)].str), &(yylsp[(3) - (3)])); ;}
- break;
-
- case 95:
-#line 481 "ael.y"
- {
- (yyval.pval) = nword((yyvsp[(1) - (5)].str), &(yylsp[(1) - (5)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (5)].str), &(yylsp[(3) - (5)]));
- (yyval.pval)->next->next = nword((yyvsp[(5) - (5)].str), &(yylsp[(5) - (5)])); ;}
- break;
-
- case 96:
-#line 485 "ael.y"
- {
- (yyval.pval) = nword((yyvsp[(1) - (5)].str), &(yylsp[(1) - (5)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (5)].str), &(yylsp[(3) - (5)]));
- (yyval.pval)->next->next = nword((yyvsp[(5) - (5)].str), &(yylsp[(5) - (5)])); ;}
- break;
-
- case 97:
-#line 489 "ael.y"
- {
- (yyval.pval) = nword(strdup("default"), &(yylsp[(1) - (5)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (5)].str), &(yylsp[(3) - (5)]));
- (yyval.pval)->next->next = nword((yyvsp[(5) - (5)].str), &(yylsp[(5) - (5)])); ;}
- break;
-
- case 98:
-#line 493 "ael.y"
- {
- (yyval.pval) = nword(strdup("default"), &(yylsp[(1) - (5)]));
- (yyval.pval)->next = nword((yyvsp[(3) - (5)].str), &(yylsp[(3) - (5)]));
- (yyval.pval)->next->next = nword((yyvsp[(5) - (5)].str), &(yylsp[(5) - (5)])); ;}
- break;
-
- case 99:
-#line 499 "ael.y"
- { (yyval.str) = strdup("1"); ;}
- break;
-
- case 100:
-#line 500 "ael.y"
- { (yyval.str) = (yyvsp[(2) - (2)].str); ;}
- break;
-
- case 101:
-#line 504 "ael.y"
- { /* ext[, pri] default 1 */
- (yyval.pval) = nword((yyvsp[(1) - (2)].str), &(yylsp[(1) - (2)]));
- (yyval.pval)->next = nword((yyvsp[(2) - (2)].str), &(yylsp[(2) - (2)])); ;}
- break;
-
- case 102:
-#line 507 "ael.y"
- { /* context, ext, pri */
- (yyval.pval) = nword((yyvsp[(4) - (4)].str), &(yylsp[(4) - (4)]));
- (yyval.pval)->next = nword((yyvsp[(1) - (4)].str), &(yylsp[(1) - (4)]));
- (yyval.pval)->next->next = nword((yyvsp[(2) - (4)].str), &(yylsp[(2) - (4)])); ;}
- break;
-
- case 103:
-#line 513 "ael.y"
- {reset_argcount(parseio->scanner);;}
- break;
-
- case 104:
-#line 513 "ael.y"
- {
- /* XXX original code had @2 but i think we need @5 */
- (yyval.pval) = npval2(PV_MACRO_CALL, &(yylsp[(1) - (5)]), &(yylsp[(5) - (5)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (5)].str);
- (yyval.pval)->u2.arglist = (yyvsp[(4) - (5)].pval);;}
- break;
-
- case 105:
-#line 518 "ael.y"
- {
- (yyval.pval)= npval2(PV_MACRO_CALL, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (3)].str); ;}
- break;
-
- case 106:
-#line 526 "ael.y"
- {reset_argcount(parseio->scanner);;}
- break;
-
- case 107:
-#line 526 "ael.y"
- {
- if (strcasecmp((yyvsp[(1) - (3)].str),"goto") == 0) {
- (yyval.pval) = npval2(PV_GOTO, &(yylsp[(1) - (3)]), &(yylsp[(2) - (3)]));
- free((yyvsp[(1) - (3)].str)); /* won't be using this */
- ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Suggestion: Use the goto statement instead of the Goto() application call in AEL.\n", my_file, (yylsp[(1) - (3)]).first_line, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column );
- } else {
- (yyval.pval)= npval2(PV_APPLICATION_CALL, &(yylsp[(1) - (3)]), &(yylsp[(2) - (3)]));
- (yyval.pval)->u1.str = (yyvsp[(1) - (3)].str);
- } ;}
- break;
-
- case 108:
-#line 537 "ael.y"
- {
- (yyval.pval) = update_last((yyvsp[(1) - (3)].pval), &(yylsp[(3) - (3)]));
- if( (yyval.pval)->type == PV_GOTO )
- (yyval.pval)->u1.list = (yyvsp[(2) - (3)].pval);
- else
- (yyval.pval)->u2.arglist = (yyvsp[(2) - (3)].pval);
- ;}
- break;
-
- case 109:
-#line 544 "ael.y"
- { (yyval.pval) = update_last((yyvsp[(1) - (2)].pval), &(yylsp[(2) - (2)])); ;}
- break;
-
- case 110:
-#line 547 "ael.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str) ;}
- break;
-
- case 111:
-#line 548 "ael.y"
- { (yyval.str) = strdup(""); ;}
- break;
-
- case 112:
-#line 551 "ael.y"
- { (yyval.pval) = nword((yyvsp[(1) - (1)].str), &(yylsp[(1) - (1)])); ;}
- break;
-
- case 113:
-#line 552 "ael.y"
- {
- (yyval.pval)= npval(PV_WORD,0/*@1.first_line*/,0/*@1.last_line*/,0/* @1.first_column*/, 0/*@1.last_column*/);
- (yyval.pval)->u1.str = strdup(""); ;}
- break;
-
- case 114:
-#line 555 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (3)].pval), nword((yyvsp[(3) - (3)].str), &(yylsp[(3) - (3)]))); ;}
- break;
-
- case 115:
-#line 558 "ael.y"
- { (yyval.pval) = NULL; ;}
- break;
-
- case 116:
-#line 559 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (2)].pval), (yyvsp[(2) - (2)].pval)); ;}
- break;
-
- case 117:
-#line 562 "ael.y"
- {
- (yyval.pval) = npval2(PV_CASE, &(yylsp[(1) - (4)]), &(yylsp[(3) - (4)])); /* XXX 3 or 4 ? */
- (yyval.pval)->u1.str = (yyvsp[(2) - (4)].str);
- (yyval.pval)->u2.statements = (yyvsp[(4) - (4)].pval); set_dads((yyval.pval),(yyvsp[(4) - (4)].pval));;}
- break;
-
- case 118:
-#line 566 "ael.y"
- {
- (yyval.pval) = npval2(PV_DEFAULT, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));
- (yyval.pval)->u1.str = NULL;
- (yyval.pval)->u2.statements = (yyvsp[(3) - (3)].pval);set_dads((yyval.pval),(yyvsp[(3) - (3)].pval));;}
- break;
-
- case 119:
-#line 570 "ael.y"
- {
- (yyval.pval) = npval2(PV_PATTERN, &(yylsp[(1) - (4)]), &(yylsp[(4) - (4)])); /* XXX@3 or @4 ? */
- (yyval.pval)->u1.str = (yyvsp[(2) - (4)].str);
- (yyval.pval)->u2.statements = (yyvsp[(4) - (4)].pval);set_dads((yyval.pval),(yyvsp[(4) - (4)].pval));;}
- break;
-
- case 120:
-#line 576 "ael.y"
- { (yyval.pval) = NULL; ;}
- break;
-
- case 121:
-#line 577 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (2)].pval), (yyvsp[(2) - (2)].pval)); ;}
- break;
-
- case 122:
-#line 580 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 123:
-#line 581 "ael.y"
- { (yyval.pval)=(yyvsp[(1) - (1)].pval);;}
- break;
-
- case 124:
-#line 582 "ael.y"
- {
- (yyval.pval) = npval2(PV_CATCH, &(yylsp[(1) - (5)]), &(yylsp[(5) - (5)]));
- (yyval.pval)->u1.str = (yyvsp[(2) - (5)].str);
- (yyval.pval)->u2.statements = (yyvsp[(4) - (5)].pval); set_dads((yyval.pval),(yyvsp[(4) - (5)].pval));;}
- break;
-
- case 125:
-#line 588 "ael.y"
- {
- (yyval.pval) = npval2(PV_SWITCHES, &(yylsp[(1) - (4)]), &(yylsp[(2) - (4)]));
- (yyval.pval)->u1.list = (yyvsp[(3) - (4)].pval); set_dads((yyval.pval),(yyvsp[(3) - (4)].pval));;}
- break;
-
- case 126:
-#line 593 "ael.y"
- {
- (yyval.pval) = npval2(PV_ESWITCHES, &(yylsp[(1) - (4)]), &(yylsp[(2) - (4)]));
- (yyval.pval)->u1.list = (yyvsp[(3) - (4)].pval); set_dads((yyval.pval),(yyvsp[(3) - (4)].pval));;}
- break;
-
- case 127:
-#line 598 "ael.y"
- { (yyval.pval) = NULL; ;}
- break;
-
- case 128:
-#line 599 "ael.y"
- { (yyval.pval) = linku1(nword((yyvsp[(1) - (3)].str), &(yylsp[(1) - (3)])), (yyvsp[(3) - (3)].pval)); ;}
- break;
-
- case 129:
-#line 600 "ael.y"
- { char *x; asprintf(&x,"%s@%s", (yyvsp[(1) - (5)].str),(yyvsp[(3) - (5)].str)); free((yyvsp[(1) - (5)].str)); free((yyvsp[(3) - (5)].str));
- (yyval.pval) = linku1(nword(x, &(yylsp[(1) - (5)])), (yyvsp[(5) - (5)].pval));;}
- break;
-
- case 130:
-#line 602 "ael.y"
- {(yyval.pval)=(yyvsp[(2) - (2)].pval);;}
- break;
-
- case 131:
-#line 605 "ael.y"
- { (yyval.pval) = nword((yyvsp[(1) - (1)].str), &(yylsp[(1) - (1)])); ;}
- break;
-
- case 132:
-#line 606 "ael.y"
- {
- (yyval.pval) = nword((yyvsp[(1) - (3)].str), &(yylsp[(1) - (3)]));
- (yyval.pval)->u2.arglist = (yyvsp[(3) - (3)].pval);
- prev_word=0; /* XXX sure ? */ ;}
- break;
-
- case 133:
-#line 613 "ael.y"
- { (yyval.pval) = (yyvsp[(1) - (2)].pval); ;}
- break;
-
- case 134:
-#line 614 "ael.y"
- { (yyval.pval) = linku1((yyvsp[(1) - (3)].pval), (yyvsp[(2) - (3)].pval)); ;}
- break;
-
- case 135:
-#line 615 "ael.y"
- {(yyval.pval)=(yyvsp[(1) - (2)].pval);;}
- break;
-
- case 136:
-#line 618 "ael.y"
- {
- (yyval.pval) = npval2(PV_INCLUDES, &(yylsp[(1) - (4)]), &(yylsp[(4) - (4)]));
- (yyval.pval)->u1.list = (yyvsp[(3) - (4)].pval);set_dads((yyval.pval),(yyvsp[(3) - (4)].pval));;}
- break;
-
- case 137:
-#line 621 "ael.y"
- {
- (yyval.pval) = npval2(PV_INCLUDES, &(yylsp[(1) - (3)]), &(yylsp[(3) - (3)]));;}
- break;
-
-
-/* Line 1270 of yacc.c. */
-#line 2956 "ael.tab.c"
- default: break;
- }
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
- *++yylsp = yyloc;
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if ! YYERROR_VERBOSE
- yyerror (&yylloc, parseio, YY_("syntax error"));
-#else
- {
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (&yylloc, parseio, yymsg);
- }
- else
- {
- yyerror (&yylloc, parseio, YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
- }
-#endif
- }
-
- yyerror_range[0] = yylloc;
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse look-ahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval, &yylloc, parseio);
- yychar = YYEMPTY;
- }
- }
-
- /* Else will try to reuse look-ahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
-
- yyerror_range[0] = yylsp[1-yylen];
- /* Do not reclaim the symbols of the rule which action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
- yyerror_range[0] = *yylsp;
- yydestruct ("Error: popping",
- yystos[yystate], yyvsp, yylsp, parseio);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- *++yyvsp = yylval;
-
- yyerror_range[1] = yylloc;
- /* Using YYLLOC is tempting, but would change the location of
- the look-ahead. YYLOC is available though. */
- YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
- *++yylsp = yyloc;
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#ifndef yyoverflow
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
-yyexhaustedlab:
- yyerror (&yylloc, parseio, YY_("memory exhausted"));
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
- if (yychar != YYEOF && yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval, &yylloc, parseio);
- /* Do not reclaim the symbols of the rule which action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp, yylsp, parseio);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
- return yyresult;
-}
-
-
-#line 626 "ael.y"
-
-
-static char *token_equivs1[] =
-{
- "AMPER",
- "AT",
- "BAR",
- "COLON",
- "COMMA",
- "EQ",
- "EXTENMARK",
- "KW_BREAK",
- "KW_CASE",
- "KW_CATCH",
- "KW_CONTEXT",
- "KW_CONTINUE",
- "KW_DEFAULT",
- "KW_ELSE",
- "KW_ESWITCHES",
- "KW_FOR",
- "KW_GLOBALS",
- "KW_GOTO",
- "KW_HINT",
- "KW_IFTIME",
- "KW_IF",
- "KW_IGNOREPAT",
- "KW_INCLUDES"
- "KW_JUMP",
- "KW_MACRO",
- "KW_PATTERN",
- "KW_REGEXTEN",
- "KW_RETURN",
- "KW_SWITCHES",
- "KW_SWITCH",
- "KW_WHILE",
- "LC",
- "LP",
- "RC",
- "RP",
- "SEMI",
-};
-
-static char *token_equivs2[] =
-{
- "&",
- "@",
- "|",
- ":",
- ",",
- "=",
- "=>",
- "break",
- "case",
- "catch",
- "context",
- "continue",
- "default",
- "else",
- "eswitches",
- "for",
- "globals",
- "goto",
- "hint",
- "ifTime",
- "if",
- "ignorepat",
- "includes"
- "jump",
- "macro",
- "pattern",
- "regexten",
- "return",
- "switches",
- "switch",
- "while",
- "{",
- "(",
- "}",
- ")",
- ";",
-};
-
-
-static char *ael_token_subst(const char *mess)
-{
- /* calc a length, malloc, fill, and return; yyerror had better free it! */
- int len=0,i;
- const char *p;
- char *res, *s,*t;
- int token_equivs_entries = sizeof(token_equivs1)/sizeof(char*);
-
- for (p=mess; *p; p++) {
- for (i=0; i<token_equivs_entries; i++) {
- if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 )
- {
- len+=strlen(token_equivs2[i])+2;
- p += strlen(token_equivs1[i])-1;
- break;
- }
- }
- len++;
- }
- res = calloc(1, len+1);
- res[0] = 0;
- s = res;
- for (p=mess; *p;) {
- int found = 0;
- for (i=0; i<token_equivs_entries; i++) {
- if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 ) {
- *s++ = '\'';
- for (t=token_equivs2[i]; *t;) {
- *s++ = *t++;
- }
- *s++ = '\'';
- p += strlen(token_equivs1[i]);
- found = 1;
- break;
- }
- }
- if( !found )
- *s++ = *p++;
- }
- *s++ = 0;
- return res;
-}
-
-void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s)
-{
- char *s2 = ael_token_subst(s);
- if (locp->first_line == locp->last_line) {
- ast_log(LOG_ERROR, "==== File: %s, Line %d, Cols: %d-%d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_column, s2);
- } else {
- ast_log(LOG_ERROR, "==== File: %s, Line %d Col %d to Line %d Col %d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column, s2);
- }
- free(s2);
- parseio->syntax_error_count++;
-}
-
-static struct pval *npval(pvaltype type, int first_line, int last_line,
- int first_column, int last_column)
-{
- pval *z = calloc(1, sizeof(struct pval));
- z->type = type;
- z->startline = first_line;
- z->endline = last_line;
- z->startcol = first_column;
- z->endcol = last_column;
- z->filename = strdup(my_file);
- return z;
-}
-
-static struct pval *npval2(pvaltype type, YYLTYPE *first, YYLTYPE *last)
-{
- return npval(type, first->first_line, last->last_line,
- first->first_column, last->last_column);
-}
-
-static struct pval *update_last(pval *obj, YYLTYPE *last)
-{
- obj->endline = last->last_line;
- obj->endcol = last->last_column;
- return obj;
-}
-
-/* frontend for npval to create a PV_WORD string from the given token */
-static pval *nword(char *string, YYLTYPE *pos)
-{
- pval *p = npval2(PV_WORD, pos, pos);
- if (p)
- p->u1.str = string;
- return p;
-}
-
-/* append second element to the list in the first one */
-static pval * linku1(pval *head, pval *tail)
-{
- if (!head)
- return tail;
- if (tail) {
- if (!head->next) {
- head->next = tail;
- } else {
- head->u1_last->next = tail;
- }
- head->u1_last = tail;
- tail->prev = head; /* the dad link only points to containers */
- }
- return head;
-}
-
-/* this routine adds a dad ptr to each element in the list */
-static void set_dads(struct pval *dad, struct pval *child_list)
-{
- struct pval *t;
-
- for(t=child_list;t;t=t->next) /* simple stuff */
- t->dad = dad;
-}
-
-
diff --git a/1.4/pbx/ael/ael.tab.h b/1.4/pbx/ael/ael.tab.h
deleted file mode 100644
index 92a201a70..000000000
--- a/1.4/pbx/ael/ael.tab.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.1a. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- KW_CONTEXT = 258,
- LC = 259,
- RC = 260,
- LP = 261,
- RP = 262,
- SEMI = 263,
- EQ = 264,
- COMMA = 265,
- COLON = 266,
- AMPER = 267,
- BAR = 268,
- AT = 269,
- KW_MACRO = 270,
- KW_GLOBALS = 271,
- KW_IGNOREPAT = 272,
- KW_SWITCH = 273,
- KW_IF = 274,
- KW_IFTIME = 275,
- KW_ELSE = 276,
- KW_RANDOM = 277,
- KW_ABSTRACT = 278,
- KW_EXTEND = 279,
- EXTENMARK = 280,
- KW_GOTO = 281,
- KW_JUMP = 282,
- KW_RETURN = 283,
- KW_BREAK = 284,
- KW_CONTINUE = 285,
- KW_REGEXTEN = 286,
- KW_HINT = 287,
- KW_FOR = 288,
- KW_WHILE = 289,
- KW_CASE = 290,
- KW_PATTERN = 291,
- KW_DEFAULT = 292,
- KW_CATCH = 293,
- KW_SWITCHES = 294,
- KW_ESWITCHES = 295,
- KW_INCLUDES = 296,
- word = 297
- };
-#endif
-/* Tokens. */
-#define KW_CONTEXT 258
-#define LC 259
-#define RC 260
-#define LP 261
-#define RP 262
-#define SEMI 263
-#define EQ 264
-#define COMMA 265
-#define COLON 266
-#define AMPER 267
-#define BAR 268
-#define AT 269
-#define KW_MACRO 270
-#define KW_GLOBALS 271
-#define KW_IGNOREPAT 272
-#define KW_SWITCH 273
-#define KW_IF 274
-#define KW_IFTIME 275
-#define KW_ELSE 276
-#define KW_RANDOM 277
-#define KW_ABSTRACT 278
-#define KW_EXTEND 279
-#define EXTENMARK 280
-#define KW_GOTO 281
-#define KW_JUMP 282
-#define KW_RETURN 283
-#define KW_BREAK 284
-#define KW_CONTINUE 285
-#define KW_REGEXTEN 286
-#define KW_HINT 287
-#define KW_FOR 288
-#define KW_WHILE 289
-#define KW_CASE 290
-#define KW_PATTERN 291
-#define KW_DEFAULT 292
-#define KW_CATCH 293
-#define KW_SWITCHES 294
-#define KW_ESWITCHES 295
-#define KW_INCLUDES 296
-#define word 297
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 54 "ael.y"
-{
- int intval; /* integer value, typically flags */
- char *str; /* strings */
- struct pval *pval; /* full objects */
-}
-/* Line 1536 of yacc.c. */
-#line 129 "ael.tab.h"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-
diff --git a/1.4/pbx/ael/ael.y b/1.4/pbx/ael/ael.y
deleted file mode 100644
index 3ddcee8f0..000000000
--- a/1.4/pbx/ael/ael.y
+++ /dev/null
@@ -1,824 +0,0 @@
-%{
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Steve Murphy <murf@parsetree.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.
- */
-/*! \file
- *
- * \brief Bison Grammar description of AEL2.
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/ael_structs.h"
-
-static pval * linku1(pval *head, pval *tail);
-static void set_dads(pval *dad, pval *child_list);
-void reset_parencount(yyscan_t yyscanner);
-void reset_semicount(yyscan_t yyscanner);
-void reset_argcount(yyscan_t yyscanner );
-
-#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
-#define YYERROR_VERBOSE 1
-
-extern char *my_file;
-#ifdef AAL_ARGCHECK
-int ael_is_funcname(char *name);
-#endif
-static char *ael_token_subst(const char *mess);
-
-%}
-
-
-%union {
- int intval; /* integer value, typically flags */
- char *str; /* strings */
- struct pval *pval; /* full objects */
-}
-
-%{
- /* declaring these AFTER the union makes things a lot simpler! */
-void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s);
-int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void * yyscanner);
-
-/* create a new object with start-end marker */
-static pval *npval(pvaltype type, int first_line, int last_line,
- int first_column, int last_column);
-
-/* create a new object with start-end marker, simplified interface.
- * Must be declared here because YYLTYPE is not known before
- */
-static pval *npval2(pvaltype type, YYLTYPE *first, YYLTYPE *last);
-
-/* another frontend for npval, this time for a string */
-static pval *nword(char *string, YYLTYPE *pos);
-
-/* update end position of an object, return the object */
-static pval *update_last(pval *, YYLTYPE *);
-%}
-
-
-%token KW_CONTEXT LC RC LP RP SEMI EQ COMMA COLON AMPER BAR AT
-%token KW_MACRO KW_GLOBALS KW_IGNOREPAT KW_SWITCH KW_IF KW_IFTIME KW_ELSE KW_RANDOM KW_ABSTRACT KW_EXTEND
-%token EXTENMARK KW_GOTO KW_JUMP KW_RETURN KW_BREAK KW_CONTINUE KW_REGEXTEN KW_HINT
-%token KW_FOR KW_WHILE KW_CASE KW_PATTERN KW_DEFAULT KW_CATCH KW_SWITCHES KW_ESWITCHES
-%token KW_INCLUDES
-
-%right BAR COMMA
-
-%token <str> word
-
-%type <pval>includes
-%type <pval>includeslist
-%type <pval>switchlist
-%type <pval>eswitches
-%type <pval>switches
-%type <pval>macro_statement
-%type <pval>macro_statements
-%type <pval>case_statement
-%type <pval>case_statements
-%type <pval>eval_arglist
-%type <pval>application_call
-%type <pval>application_call_head
-%type <pval>macro_call
-%type <pval>target jumptarget
-%type <pval>statement
-%type <pval>switch_statement
-
-%type <pval>if_like_head
-%type <pval>statements
-%type <pval>extension
-%type <pval>ignorepat
-%type <pval>element
-%type <pval>elements
-%type <pval>arglist
-%type <pval>assignment
-%type <pval>global_statements
-%type <pval>globals
-%type <pval>macro
-%type <pval>context
-%type <pval>object
-%type <pval>objects
-%type <pval>file
-/* XXX lr changes */
-%type <pval>opt_else
-%type <pval>timespec
-%type <pval>included_entry
-
-%type <str>opt_word
-%type <str>context_name
-%type <str>timerange
-
-%type <str>goto_word
-%type <str>word_list
-%type <str>word3_list hint_word
-%type <str>test_expr
-%type <str>opt_pri
-
-%type <intval>opt_abstract
-
-/*
- * OPTIONS
- */
-
-%locations /* track source location using @n variables (yylloc in flex) */
-%pure-parser /* pass yylval and yylloc as arguments to yylex(). */
-%name-prefix="ael_yy"
-/*
- * add an additional argument, parseio, to yyparse(),
- * which is then accessible in the grammar actions
- */
-%parse-param {struct parse_io *parseio}
-
-/* there will be two shift/reduce conflicts, they involve the if statement, where a single statement occurs not wrapped in curlies in the "true" section
- the default action to shift will attach the else to the preceeding if. */
-%expect 3
-%error-verbose
-
-/*
- * declare destructors for objects.
- * The former is for pval, the latter for strings.
- * NOTE: we must not have a destructor for a 'file' object.
- */
-%destructor {
- destroy_pval($$);
- prev_word=0;
- } includes includeslist switchlist eswitches switches
- macro_statement macro_statements case_statement case_statements
- eval_arglist application_call application_call_head
- macro_call target jumptarget statement switch_statement
- if_like_head statements extension
- ignorepat element elements arglist assignment
- global_statements globals macro context object objects
- opt_else
- timespec included_entry
-
-%destructor { free($$);} word word_list goto_word word3_list opt_word context_name
- timerange
- test_expr
- opt_pri
-
-
-%%
-
-file : objects { $$ = parseio->pval = $1; }
- ;
-
-objects : object {$$=$1;}
- | objects object { $$ = linku1($1, $2); }
- | objects error {$$=$1;}
- ;
-
-object : context {$$=$1;}
- | macro {$$=$1;}
- | globals {$$=$1;}
- | SEMI {$$=0;/* allow older docs to be read */}
- ;
-
-context_name : word { $$ = $1; }
- | KW_DEFAULT { $$ = strdup("default"); }
- ;
-
-context : opt_abstract KW_CONTEXT context_name LC elements RC {
- $$ = npval2(PV_CONTEXT, &@1, &@6);
- $$->u1.str = $3;
- $$->u2.statements = $5;
- set_dads($$,$5);
- $$->u3.abstract = $1;}
- ;
-
-/* optional "abstract" keyword XXX there is no regression test for this */
-opt_abstract: KW_ABSTRACT { $$ = 1; }
- | /* nothing */ { $$ = 0; }
- | KW_EXTEND { $$ = 2; }
- | KW_EXTEND KW_ABSTRACT { $$=3; }
- | KW_ABSTRACT KW_EXTEND { $$=3; }
- ;
-
-macro : KW_MACRO word LP arglist RP LC macro_statements RC {
- $$ = npval2(PV_MACRO, &@1, &@8);
- $$->u1.str = $2; $$->u2.arglist = $4; $$->u3.macro_statements = $7;
- set_dads($$,$7);}
- ;
-
-globals : KW_GLOBALS LC global_statements RC {
- $$ = npval2(PV_GLOBALS, &@1, &@4);
- $$->u1.statements = $3;
- set_dads($$,$3);}
- ;
-
-global_statements : { $$ = NULL; }
- | assignment global_statements {$$ = linku1($1, $2); }
- | error global_statements {$$=$2;}
- ;
-
-assignment : word EQ { reset_semicount(parseio->scanner); } word SEMI {
- $$ = npval2(PV_VARDEC, &@1, &@5);
- $$->u1.str = $1;
- $$->u2.val = $4; }
- ;
-
-/* XXX this matches missing arguments, is this desired ? */
-arglist : /* empty */ { $$ = NULL; }
- | word { $$ = nword($1, &@1); }
- | arglist COMMA word { $$ = linku1($1, nword($3, &@3)); }
- | arglist error {$$=$1;}
- ;
-
-elements : {$$=0;}
- | element elements { $$ = linku1($1, $2); }
- | error elements { $$=$2;}
- ;
-
-element : extension {$$=$1;}
- | includes {$$=$1;}
- | switches {$$=$1;}
- | eswitches {$$=$1;}
- | ignorepat {$$=$1;}
- | assignment {$$=$1;}
- | word error {free($1); $$=0;}
- | SEMI {$$=0;/* allow older docs to be read */}
- ;
-
-ignorepat : KW_IGNOREPAT EXTENMARK word SEMI {
- $$ = npval2(PV_IGNOREPAT, &@1, &@4);
- $$->u1.str = $3;}
- ;
-
-extension : word EXTENMARK statement {
- $$ = npval2(PV_EXTENSION, &@1, &@3);
- $$->u1.str = $1;
- $$->u2.statements = $3; set_dads($$,$3);}
- | KW_REGEXTEN word EXTENMARK statement {
- $$ = npval2(PV_EXTENSION, &@1, &@4);
- $$->u1.str = $2;
- $$->u2.statements = $4; set_dads($$,$4);
- $$->u4.regexten=1;}
- | KW_HINT LP hint_word RP word EXTENMARK statement {
- $$ = npval2(PV_EXTENSION, &@1, &@7);
- $$->u1.str = $5;
- $$->u2.statements = $7; set_dads($$,$7);
- $$->u3.hints = $3;}
- | KW_REGEXTEN KW_HINT LP hint_word RP word EXTENMARK statement {
- $$ = npval2(PV_EXTENSION, &@1, &@8);
- $$->u1.str = $6;
- $$->u2.statements = $8; set_dads($$,$8);
- $$->u4.regexten=1;
- $$->u3.hints = $4;}
-
- ;
-
-/* list of statements in a block or after a case label - can be empty */
-statements : /* empty */ { $$ = NULL; }
- | statement statements { $$ = linku1($1, $2); }
- | error statements {$$=$2;}
- ;
-
-/* hh:mm-hh:mm, due to the way the parser works we do not
- * detect the '-' but only the ':' as separator
- */
-timerange: word3_list COLON word3_list COLON word3_list {
- asprintf(&$$, "%s:%s:%s", $1, $3, $5);
- free($1);
- free($3);
- free($5); }
- | word { $$ = $1; }
- ;
-
-/* full time specification range|dow|*|* */
-timespec : timerange BAR word3_list BAR word3_list BAR word3_list {
- $$ = nword($1, &@1);
- $$->next = nword($3, &@3);
- $$->next->next = nword($5, &@5);
- $$->next->next->next = nword($7, &@7); }
- ;
-
-/* expression used in if, random, while, switch */
-test_expr : LP { reset_parencount(parseio->scanner); } word_list RP { $$ = $3; }
- ;
-
-/* 'if' like statements: if, iftime, random */
-if_like_head : KW_IF test_expr {
- $$= npval2(PV_IF, &@1, &@2);
- $$->u1.str = $2; }
- | KW_RANDOM test_expr {
- $$ = npval2(PV_RANDOM, &@1, &@2);
- $$->u1.str=$2;}
- | KW_IFTIME LP timespec RP {
- $$ = npval2(PV_IFTIME, &@1, &@4);
- $$->u1.list = $3;
- prev_word = 0; }
- ;
-
-/* word_list is a hack to fix a problem with context switching between bison and flex;
- by the time you register a new context with flex, you've already got a look-ahead token
- from the old context, with no way to put it back and start afresh. So, we kludge this
- and merge the words back together. */
-
-word_list : word { $$ = $1;}
- | word word {
- asprintf(&($$), "%s%s", $1, $2);
- free($1);
- free($2);
- prev_word = $$;}
- ;
-
-hint_word : word { $$ = $1; }
- | hint_word word {
- asprintf(&($$), "%s %s", $1, $2);
- free($1);
- free($2); }
- | hint_word COLON word {
- asprintf(&($$), "%s:%s", $1, $3);
- free($1);
- free($3); }
- | hint_word AMPER word { /* there are often '&' in hints */
- asprintf(&($$), "%s&%s", $1, $3);
- free($1);
- free($3);}
-
-
-word3_list : word { $$ = $1;}
- | word word {
- asprintf(&($$), "%s%s", $1, $2);
- free($1);
- free($2);
- prev_word = $$;}
- | word word word {
- asprintf(&($$), "%s%s%s", $1, $2, $3);
- free($1);
- free($2);
- free($3);
- prev_word=$$;}
- ;
-
-goto_word : word { $$ = $1;}
- | word word {
- asprintf(&($$), "%s%s", $1, $2);
- free($1);
- free($2);}
- | goto_word COLON word {
- asprintf(&($$), "%s:%s", $1, $3);
- free($1);
- free($3);}
- ;
-
-switch_statement : KW_SWITCH test_expr LC case_statements RC {
- $$ = npval2(PV_SWITCH, &@1, &@5);
- $$->u1.str = $2;
- $$->u2.statements = $4; set_dads($$,$4);}
- ;
-
-/*
- * Definition of a statememt in our language
- */
-statement : LC statements RC {
- $$ = npval2(PV_STATEMENTBLOCK, &@1, &@3);
- $$->u1.list = $2; set_dads($$,$2);}
- | assignment { $$ = $1; }
- | KW_GOTO target SEMI {
- $$ = npval2(PV_GOTO, &@1, &@3);
- $$->u1.list = $2;}
- | KW_JUMP jumptarget SEMI {
- $$ = npval2(PV_GOTO, &@1, &@3);
- $$->u1.list = $2;}
- | word COLON {
- $$ = npval2(PV_LABEL, &@1, &@2);
- $$->u1.str = $1; }
- | KW_FOR LP {reset_semicount(parseio->scanner);} word SEMI
- {reset_semicount(parseio->scanner);} word SEMI
- {reset_parencount(parseio->scanner);} word RP statement { /* XXX word_list maybe ? */
- $$ = npval2(PV_FOR, &@1, &@12);
- $$->u1.for_init = $4;
- $$->u2.for_test=$7;
- $$->u3.for_inc = $10;
- $$->u4.for_statements = $12; set_dads($$,$12);}
- | KW_WHILE test_expr statement {
- $$ = npval2(PV_WHILE, &@1, &@3);
- $$->u1.str = $2;
- $$->u2.statements = $3; set_dads($$,$3);}
- | switch_statement { $$ = $1; }
- | AMPER macro_call SEMI { $$ = update_last($2, &@2); }
- | application_call SEMI { $$ = update_last($1, &@2); }
- | word SEMI {
- $$= npval2(PV_APPLICATION_CALL, &@1, &@2);
- $$->u1.str = $1;}
- | application_call EQ {reset_semicount(parseio->scanner);} word SEMI {
- char *bufx;
- int tot=0;
- pval *pptr;
- $$ = npval2(PV_VARDEC, &@1, &@5);
- $$->u2.val=$4;
- /* rebuild the original string-- this is not an app call, it's an unwrapped vardec, with a func call on the LHS */
- /* string to big to fit in the buffer? */
- tot+=strlen($1->u1.str);
- for(pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
- tot+=strlen(pptr->u1.str);
- tot++; /* for a sep like a comma */
- }
- tot+=4; /* for safety */
- bufx = calloc(1, tot);
- strcpy(bufx,$1->u1.str);
- strcat(bufx,"(");
- /* XXX need to advance the pointer or the loop is very inefficient */
- for (pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
- if ( pptr != $1->u2.arglist )
- strcat(bufx,",");
- strcat(bufx,pptr->u1.str);
- }
- strcat(bufx,")");
-#ifdef AAL_ARGCHECK
- if ( !ael_is_funcname($1->u1.str) )
- ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Function call? The name %s is not in my internal list of function names\n",
- my_file, @1.first_line, @1.first_column, @1.last_column, $1->u1.str);
-#endif
- $$->u1.str = bufx;
- destroy_pval($1); /* the app call it is not, get rid of that chain */
- prev_word = 0;
- }
- | KW_BREAK SEMI { $$ = npval2(PV_BREAK, &@1, &@2); }
- | KW_RETURN SEMI { $$ = npval2(PV_RETURN, &@1, &@2); }
- | KW_CONTINUE SEMI { $$ = npval2(PV_CONTINUE, &@1, &@2); }
- | if_like_head statement opt_else {
- $$ = update_last($1, &@2);
- $$->u2.statements = $2; set_dads($$,$2);
- $$->u3.else_statements = $3;set_dads($$,$3);}
- | SEMI { $$=0; }
- ;
-
-opt_else : KW_ELSE statement { $$ = $2; }
- | { $$ = NULL ; }
-
-
-target : goto_word { $$ = nword($1, &@1); }
- | goto_word BAR goto_word {
- $$ = nword($1, &@1);
- $$->next = nword($3, &@3); }
- | goto_word COMMA goto_word {
- $$ = nword($1, &@1);
- $$->next = nword($3, &@3); }
- | goto_word BAR goto_word BAR goto_word {
- $$ = nword($1, &@1);
- $$->next = nword($3, &@3);
- $$->next->next = nword($5, &@5); }
- | goto_word COMMA goto_word COMMA goto_word {
- $$ = nword($1, &@1);
- $$->next = nword($3, &@3);
- $$->next->next = nword($5, &@5); }
- | KW_DEFAULT BAR goto_word BAR goto_word {
- $$ = nword(strdup("default"), &@1);
- $$->next = nword($3, &@3);
- $$->next->next = nword($5, &@5); }
- | KW_DEFAULT COMMA goto_word COMMA goto_word {
- $$ = nword(strdup("default"), &@1);
- $$->next = nword($3, &@3);
- $$->next->next = nword($5, &@5); }
- ;
-
-opt_pri : /* empty */ { $$ = strdup("1"); }
- | COMMA word { $$ = $2; }
- ;
-
-/* XXX please document the form of jumptarget */
-jumptarget : goto_word opt_pri { /* ext[, pri] default 1 */
- $$ = nword($1, &@1);
- $$->next = nword($2, &@2); } /* jump extension[,priority][@context] */
- | goto_word opt_pri AT context_name { /* context, ext, pri */
- $$ = nword($4, &@4);
- $$->next = nword($1, &@1);
- $$->next->next = nword($2, &@2); }
- ;
-
-macro_call : word LP {reset_argcount(parseio->scanner);} eval_arglist RP {
- /* XXX original code had @2 but i think we need @5 */
- $$ = npval2(PV_MACRO_CALL, &@1, &@5);
- $$->u1.str = $1;
- $$->u2.arglist = $4;}
- | word LP RP {
- $$= npval2(PV_MACRO_CALL, &@1, &@3);
- $$->u1.str = $1; }
- ;
-
-/* XXX application_call_head must be revised. Having 'word LP { ...'
- * just as above should work fine, however it gives a different result.
- */
-application_call_head: word LP {reset_argcount(parseio->scanner);} {
- if (strcasecmp($1,"goto") == 0) {
- $$ = npval2(PV_GOTO, &@1, &@2);
- free($1); /* won't be using this */
- ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Suggestion: Use the goto statement instead of the Goto() application call in AEL.\n", my_file, @1.first_line, @1.first_column, @1.last_column );
- } else {
- $$= npval2(PV_APPLICATION_CALL, &@1, &@2);
- $$->u1.str = $1;
- } }
- ;
-
-application_call : application_call_head eval_arglist RP {
- $$ = update_last($1, &@3);
- if( $$->type == PV_GOTO )
- $$->u1.list = $2;
- else
- $$->u2.arglist = $2;
- }
- | application_call_head RP { $$ = update_last($1, &@2); }
- ;
-
-opt_word : word { $$ = $1 }
- | { $$ = strdup(""); }
- ;
-
-eval_arglist : word_list { $$ = nword($1, &@1); }
- | /*nothing! */ {
- $$= npval(PV_WORD,0/*@1.first_line*/,0/*@1.last_line*/,0/* @1.first_column*/, 0/*@1.last_column*/);
- $$->u1.str = strdup(""); }
- | eval_arglist COMMA opt_word { $$ = linku1($1, nword($3, &@3)); }
- ;
-
-case_statements: /* empty */ { $$ = NULL; }
- | case_statement case_statements { $$ = linku1($1, $2); }
- ;
-
-case_statement: KW_CASE word COLON statements {
- $$ = npval2(PV_CASE, &@1, &@3); /* XXX 3 or 4 ? */
- $$->u1.str = $2;
- $$->u2.statements = $4; set_dads($$,$4);}
- | KW_DEFAULT COLON statements {
- $$ = npval2(PV_DEFAULT, &@1, &@3);
- $$->u1.str = NULL;
- $$->u2.statements = $3;set_dads($$,$3);}
- | KW_PATTERN word COLON statements {
- $$ = npval2(PV_PATTERN, &@1, &@4); /* XXX@3 or @4 ? */
- $$->u1.str = $2;
- $$->u2.statements = $4;set_dads($$,$4);}
- ;
-
-macro_statements: /* empty */ { $$ = NULL; }
- | macro_statement macro_statements { $$ = linku1($1, $2); }
- ;
-
-macro_statement : statement {$$=$1;}
- | includes { $$=$1;}
- | KW_CATCH word LC statements RC {
- $$ = npval2(PV_CATCH, &@1, &@5);
- $$->u1.str = $2;
- $$->u2.statements = $4; set_dads($$,$4);}
- ;
-
-switches : KW_SWITCHES LC switchlist RC {
- $$ = npval2(PV_SWITCHES, &@1, &@2);
- $$->u1.list = $3; set_dads($$,$3);}
- ;
-
-eswitches : KW_ESWITCHES LC switchlist RC {
- $$ = npval2(PV_ESWITCHES, &@1, &@2);
- $$->u1.list = $3; set_dads($$,$3);}
- ;
-
-switchlist : /* empty */ { $$ = NULL; }
- | word SEMI switchlist { $$ = linku1(nword($1, &@1), $3); }
- | word AT word SEMI switchlist { char *x; asprintf(&x,"%s@%s", $1,$3); free($1); free($3);
- $$ = linku1(nword(x, &@1), $5);}
- | error switchlist {$$=$2;}
- ;
-
-included_entry : context_name { $$ = nword($1, &@1); }
- | context_name BAR timespec {
- $$ = nword($1, &@1);
- $$->u2.arglist = $3;
- prev_word=0; /* XXX sure ? */ }
- ;
-
-/* list of ';' separated context names followed by optional timespec */
-includeslist : included_entry SEMI { $$ = $1; }
- | includeslist included_entry SEMI { $$ = linku1($1, $2); }
- | includeslist error {$$=$1;}
- ;
-
-includes : KW_INCLUDES LC includeslist RC {
- $$ = npval2(PV_INCLUDES, &@1, &@4);
- $$->u1.list = $3;set_dads($$,$3);}
- | KW_INCLUDES LC RC {
- $$ = npval2(PV_INCLUDES, &@1, &@3);}
- ;
-
-
-%%
-
-static char *token_equivs1[] =
-{
- "AMPER",
- "AT",
- "BAR",
- "COLON",
- "COMMA",
- "EQ",
- "EXTENMARK",
- "KW_BREAK",
- "KW_CASE",
- "KW_CATCH",
- "KW_CONTEXT",
- "KW_CONTINUE",
- "KW_DEFAULT",
- "KW_ELSE",
- "KW_ESWITCHES",
- "KW_FOR",
- "KW_GLOBALS",
- "KW_GOTO",
- "KW_HINT",
- "KW_IFTIME",
- "KW_IF",
- "KW_IGNOREPAT",
- "KW_INCLUDES"
- "KW_JUMP",
- "KW_MACRO",
- "KW_PATTERN",
- "KW_REGEXTEN",
- "KW_RETURN",
- "KW_SWITCHES",
- "KW_SWITCH",
- "KW_WHILE",
- "LC",
- "LP",
- "RC",
- "RP",
- "SEMI",
-};
-
-static char *token_equivs2[] =
-{
- "&",
- "@",
- "|",
- ":",
- ",",
- "=",
- "=>",
- "break",
- "case",
- "catch",
- "context",
- "continue",
- "default",
- "else",
- "eswitches",
- "for",
- "globals",
- "goto",
- "hint",
- "ifTime",
- "if",
- "ignorepat",
- "includes"
- "jump",
- "macro",
- "pattern",
- "regexten",
- "return",
- "switches",
- "switch",
- "while",
- "{",
- "(",
- "}",
- ")",
- ";",
-};
-
-
-static char *ael_token_subst(const char *mess)
-{
- /* calc a length, malloc, fill, and return; yyerror had better free it! */
- int len=0,i;
- const char *p;
- char *res, *s,*t;
- int token_equivs_entries = sizeof(token_equivs1)/sizeof(char*);
-
- for (p=mess; *p; p++) {
- for (i=0; i<token_equivs_entries; i++) {
- if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 )
- {
- len+=strlen(token_equivs2[i])+2;
- p += strlen(token_equivs1[i])-1;
- break;
- }
- }
- len++;
- }
- res = calloc(1, len+1);
- res[0] = 0;
- s = res;
- for (p=mess; *p;) {
- int found = 0;
- for (i=0; i<token_equivs_entries; i++) {
- if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 ) {
- *s++ = '\'';
- for (t=token_equivs2[i]; *t;) {
- *s++ = *t++;
- }
- *s++ = '\'';
- p += strlen(token_equivs1[i]);
- found = 1;
- break;
- }
- }
- if( !found )
- *s++ = *p++;
- }
- *s++ = 0;
- return res;
-}
-
-void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s)
-{
- char *s2 = ael_token_subst(s);
- if (locp->first_line == locp->last_line) {
- ast_log(LOG_ERROR, "==== File: %s, Line %d, Cols: %d-%d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_column, s2);
- } else {
- ast_log(LOG_ERROR, "==== File: %s, Line %d Col %d to Line %d Col %d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column, s2);
- }
- free(s2);
- parseio->syntax_error_count++;
-}
-
-static struct pval *npval(pvaltype type, int first_line, int last_line,
- int first_column, int last_column)
-{
- pval *z = calloc(1, sizeof(struct pval));
- z->type = type;
- z->startline = first_line;
- z->endline = last_line;
- z->startcol = first_column;
- z->endcol = last_column;
- z->filename = strdup(my_file);
- return z;
-}
-
-static struct pval *npval2(pvaltype type, YYLTYPE *first, YYLTYPE *last)
-{
- return npval(type, first->first_line, last->last_line,
- first->first_column, last->last_column);
-}
-
-static struct pval *update_last(pval *obj, YYLTYPE *last)
-{
- obj->endline = last->last_line;
- obj->endcol = last->last_column;
- return obj;
-}
-
-/* frontend for npval to create a PV_WORD string from the given token */
-static pval *nword(char *string, YYLTYPE *pos)
-{
- pval *p = npval2(PV_WORD, pos, pos);
- if (p)
- p->u1.str = string;
- return p;
-}
-
-/* append second element to the list in the first one */
-static pval * linku1(pval *head, pval *tail)
-{
- if (!head)
- return tail;
- if (tail) {
- if (!head->next) {
- head->next = tail;
- } else {
- head->u1_last->next = tail;
- }
- head->u1_last = tail;
- tail->prev = head; /* the dad link only points to containers */
- }
- return head;
-}
-
-/* this routine adds a dad ptr to each element in the list */
-static void set_dads(struct pval *dad, struct pval *child_list)
-{
- struct pval *t;
-
- for(t=child_list;t;t=t->next) /* simple stuff */
- t->dad = dad;
-}
-
diff --git a/1.4/pbx/ael/ael_lex.c b/1.4/pbx/ael/ael_lex.c
deleted file mode 100644
index 708387829..000000000
--- a/1.4/pbx/ael/ael_lex.c
+++ /dev/null
@@ -1,3119 +0,0 @@
-#line 2 "ael_lex.c"
-
-#line 4 "ael_lex.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-#include "asterisk.h"
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-int ael_yylex_init (yyscan_t* scanner);
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE ael_yyrestart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = yyg->yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via ael_yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
- ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void ael_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void ael_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE ael_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void ael_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void ael_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void ael_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void ael_yypop_buffer_state (yyscan_t yyscanner );
-
-static void ael_yyensure_buffer_stack (yyscan_t yyscanner );
-static void ael_yy_load_buffer_state (yyscan_t yyscanner );
-static void ael_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER ael_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE ael_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE ael_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE ael_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *ael_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *ael_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void ael_yyfree (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer ael_yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- ael_yyensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- ael_yyensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define ael_yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yyg->yytext_ptr = yy_bp; \
- yyg->yytext_ptr -= yyg->yy_more_len; \
- yyleng = (size_t) (yy_cp - yyg->yytext_ptr); \
- yyg->yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 62
-#define YY_END_OF_BUFFER 63
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[239] =
- { 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 42, 42,
- 63, 62, 49, 47, 48, 50, 50, 9, 3, 4,
- 7, 50, 8, 5, 6, 12, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 1, 10, 2, 62, 52, 51, 62, 53, 62,
- 58, 59, 60, 62, 62, 54, 55, 56, 62, 57,
- 42, 43, 44, 49, 48, 50, 50, 41, 13, 11,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 21, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 0, 52, 51, 0, 53, 52, 51, 53,
-
- 0, 58, 59, 60, 0, 58, 59, 60, 0, 54,
- 55, 56, 0, 57, 54, 55, 56, 57, 42, 43,
- 44, 45, 44, 46, 50, 13, 13, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 32, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 34, 50, 50, 50, 26, 50,
- 50, 50, 27, 25, 50, 50, 50, 28, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 30, 37, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 17, 50,
- 50, 50, 50, 50, 33, 50, 50, 50, 50, 50,
-
- 50, 16, 50, 22, 50, 50, 50, 23, 50, 29,
- 20, 50, 50, 14, 50, 35, 50, 18, 50, 50,
- 36, 50, 50, 50, 15, 31, 50, 50, 40, 24,
- 38, 0, 39, 19, 0, 0, 61, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 4, 5, 6, 7, 5, 1, 8, 5, 9,
- 10, 11, 5, 12, 5, 5, 13, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 14, 15, 5,
- 16, 17, 1, 18, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 19, 5, 5, 5, 5, 5, 5,
- 20, 21, 22, 1, 5, 1, 23, 24, 25, 26,
-
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 5, 39, 40, 41, 42, 5, 43, 44,
- 5, 5, 45, 46, 47, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[48] =
- { 0,
- 1, 1, 2, 1, 3, 4, 3, 1, 1, 1,
- 5, 1, 3, 1, 1, 1, 3, 1, 3, 3,
- 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 1, 3
- } ;
-
-static yyconst flex_int16_t yy_base[252] =
- { 0,
- 0, 0, 39, 42, 81, 120, 159, 198, 47, 54,
- 315, 985, 312, 985, 309, 0, 281, 985, 985, 985,
- 985, 42, 985, 985, 294, 985, 286, 270, 31, 281,
- 32, 270, 33, 275, 45, 263, 281, 280, 48, 259,
- 271, 985, 985, 985, 73, 985, 985, 89, 985, 237,
- 985, 985, 985, 276, 315, 985, 985, 985, 354, 985,
- 297, 985, 66, 297, 291, 0, 258, 0, 401, 985,
- 253, 265, 64, 254, 261, 248, 244, 242, 242, 243,
- 238, 242, 258, 240, 250, 239, 248, 231, 235, 51,
- 239, 238, 103, 985, 985, 137, 985, 142, 176, 181,
-
- 439, 985, 985, 985, 478, 517, 556, 595, 634, 985,
- 985, 985, 673, 985, 712, 751, 790, 829, 265, 985,
- 103, 985, 104, 985, 242, 0, 876, 225, 242, 237,
- 238, 221, 238, 233, 225, 228, 0, 230, 216, 210,
- 219, 212, 214, 206, 203, 200, 214, 212, 196, 196,
- 202, 201, 195, 200, 0, 202, 100, 189, 0, 189,
- 193, 204, 0, 0, 190, 185, 180, 0, 180, 189,
- 178, 170, 174, 187, 184, 167, 182, 0, 0, 156,
- 163, 161, 169, 167, 158, 161, 156, 152, 0, 138,
- 141, 134, 137, 136, 0, 135, 135, 115, 113, 113,
-
- 123, 0, 109, 0, 107, 117, 107, 0, 112, 0,
- 111, 110, 92, 0, 105, 0, 95, 0, 85, 60,
- 0, 61, 48, 117, 0, 0, 45, 37, 0, 0,
- 0, 168, 0, 0, 0, 50, 985, 985, 922, 927,
- 932, 937, 940, 945, 950, 955, 960, 964, 969, 974,
- 979
- } ;
-
-static yyconst flex_int16_t yy_def[252] =
- { 0,
- 238, 1, 239, 239, 240, 240, 241, 241, 242, 242,
- 238, 238, 238, 238, 238, 243, 243, 238, 238, 238,
- 238, 243, 238, 238, 238, 238, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 238, 238, 238, 244, 238, 238, 244, 238, 245,
- 238, 238, 238, 245, 246, 238, 238, 238, 246, 238,
- 247, 238, 248, 238, 238, 243, 243, 243, 249, 238,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 244, 238, 238, 244, 238, 244, 244, 244,
-
- 245, 238, 238, 238, 245, 245, 245, 245, 246, 238,
- 238, 238, 246, 238, 246, 246, 246, 246, 247, 238,
- 248, 238, 248, 238, 243, 250, 249, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
-
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 238, 243, 243, 251, 251, 238, 0, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238
- } ;
-
-static yyconst flex_int16_t yy_nxt[1033] =
- { 0,
- 12, 13, 14, 15, 16, 16, 17, 18, 19, 20,
- 16, 21, 22, 23, 24, 25, 16, 26, 16, 16,
- 12, 16, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 16, 16, 37, 16, 16, 38, 39, 40,
- 16, 16, 41, 16, 42, 43, 44, 46, 47, 62,
- 46, 47, 68, 73, 69, 237, 62, 63, 46, 48,
- 49, 46, 48, 49, 63, 76, 80, 74, 122, 81,
- 89, 77, 83, 84, 90, 78, 123, 234, 124, 148,
- 85, 94, 95, 46, 233, 49, 46, 231, 49, 51,
- 52, 149, 94, 96, 97, 53, 230, 98, 99, 229,
-
- 51, 54, 52, 130, 131, 122, 122, 228, 98, 96,
- 100, 94, 95, 238, 123, 238, 238, 94, 232, 97,
- 232, 227, 94, 96, 97, 51, 180, 52, 51, 52,
- 181, 226, 225, 98, 53, 100, 224, 223, 222, 51,
- 54, 52, 221, 220, 219, 98, 99, 94, 218, 97,
- 94, 95, 217, 216, 215, 214, 98, 96, 100, 213,
- 212, 94, 96, 97, 51, 211, 52, 56, 57, 232,
- 58, 232, 210, 235, 209, 208, 207, 206, 56, 59,
- 60, 98, 205, 100, 94, 95, 94, 204, 97, 94,
- 95, 203, 202, 201, 200, 94, 96, 97, 199, 198,
-
- 94, 96, 97, 56, 197, 60, 56, 57, 196, 58,
- 195, 194, 193, 192, 191, 190, 189, 56, 59, 60,
- 94, 188, 97, 187, 186, 94, 185, 97, 184, 183,
- 182, 179, 178, 177, 176, 175, 174, 173, 172, 171,
- 170, 169, 56, 168, 60, 102, 103, 167, 166, 165,
- 164, 104, 163, 162, 161, 160, 102, 105, 103, 159,
- 158, 157, 156, 155, 154, 153, 152, 120, 151, 150,
- 147, 146, 145, 144, 143, 142, 141, 140, 139, 138,
- 137, 102, 136, 103, 106, 107, 135, 134, 133, 132,
- 108, 129, 128, 125, 65, 106, 105, 107, 64, 120,
-
- 92, 91, 88, 87, 86, 82, 79, 75, 72, 71,
- 70, 67, 65, 64, 238, 238, 238, 238, 238, 238,
- 106, 238, 107, 110, 111, 238, 112, 238, 238, 238,
- 238, 238, 238, 238, 110, 113, 114, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 110,
- 238, 114, 115, 116, 238, 117, 238, 238, 238, 238,
- 238, 238, 238, 115, 113, 118, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 115, 238,
-
- 118, 126, 126, 238, 126, 238, 238, 238, 126, 126,
- 126, 238, 126, 238, 126, 126, 126, 238, 126, 238,
- 238, 126, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 126, 102, 103, 238,
- 238, 238, 238, 104, 238, 238, 238, 238, 102, 105,
- 103, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 102, 238, 103, 106, 107, 238, 238,
- 238, 238, 108, 238, 238, 238, 238, 106, 105, 107,
-
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 106, 238, 107, 102, 103, 238, 238, 238,
- 238, 104, 238, 238, 238, 238, 102, 105, 103, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 102, 238, 103, 102, 103, 238, 238, 238, 238,
- 104, 238, 238, 238, 238, 102, 105, 103, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
-
- 102, 238, 103, 102, 103, 238, 238, 238, 238, 104,
- 238, 238, 238, 238, 102, 105, 103, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 102,
- 238, 103, 110, 111, 238, 112, 238, 238, 238, 238,
- 238, 238, 238, 110, 113, 114, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 110, 238,
- 114, 115, 116, 238, 117, 238, 238, 238, 238, 238,
- 238, 238, 115, 113, 118, 238, 238, 238, 238, 238,
-
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 115, 238, 118,
- 110, 111, 238, 112, 238, 238, 238, 238, 238, 238,
- 238, 110, 113, 114, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 110, 238, 114, 110,
- 111, 238, 112, 238, 238, 238, 238, 238, 238, 238,
- 110, 113, 114, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 110, 238, 114, 110, 111,
-
- 238, 112, 238, 238, 238, 238, 238, 238, 238, 110,
- 113, 114, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 110, 238, 114, 110, 111, 238,
- 112, 238, 238, 238, 238, 238, 238, 238, 110, 113,
- 114, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 110, 238, 114, 126, 126, 238, 126,
- 238, 238, 238, 126, 126, 126, 238, 126, 238, 126,
- 126, 126, 238, 126, 238, 238, 126, 238, 238, 238,
-
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 126, 45, 45, 45, 45, 45, 50, 50, 50,
- 50, 50, 55, 55, 55, 55, 55, 61, 61, 61,
- 61, 61, 66, 66, 66, 93, 93, 93, 93, 93,
- 101, 101, 101, 101, 101, 109, 109, 109, 109, 109,
- 119, 119, 119, 119, 121, 121, 121, 121, 121, 127,
- 238, 127, 127, 127, 126, 238, 126, 126, 126, 236,
- 236, 236, 238, 236, 11, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
-
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238
- } ;
-
-static yyconst flex_int16_t yy_chk[1033] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 3, 9,
- 4, 4, 22, 29, 22, 236, 10, 9, 3, 3,
- 3, 4, 4, 4, 10, 31, 33, 29, 63, 33,
- 39, 31, 35, 35, 39, 31, 63, 228, 63, 90,
- 35, 45, 45, 3, 227, 3, 4, 223, 4, 5,
- 5, 90, 45, 45, 45, 5, 222, 48, 48, 220,
-
- 5, 5, 5, 73, 73, 121, 123, 219, 48, 48,
- 48, 93, 93, 121, 123, 121, 123, 45, 224, 45,
- 224, 217, 93, 93, 93, 5, 157, 5, 6, 6,
- 157, 215, 213, 48, 6, 48, 212, 211, 209, 6,
- 6, 6, 207, 206, 205, 96, 96, 93, 203, 93,
- 98, 98, 201, 200, 199, 198, 96, 96, 96, 197,
- 196, 98, 98, 98, 6, 194, 6, 7, 7, 232,
- 7, 232, 193, 232, 192, 191, 190, 188, 7, 7,
- 7, 96, 187, 96, 99, 99, 98, 186, 98, 100,
- 100, 185, 184, 183, 182, 99, 99, 99, 181, 180,
-
- 100, 100, 100, 7, 177, 7, 8, 8, 176, 8,
- 175, 174, 173, 172, 171, 170, 169, 8, 8, 8,
- 99, 167, 99, 166, 165, 100, 162, 100, 161, 160,
- 158, 156, 154, 153, 152, 151, 150, 149, 148, 147,
- 146, 145, 8, 144, 8, 50, 50, 143, 142, 141,
- 140, 50, 139, 138, 136, 135, 50, 50, 50, 134,
- 133, 132, 131, 130, 129, 128, 125, 119, 92, 91,
- 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,
- 79, 50, 78, 50, 54, 54, 77, 76, 75, 74,
- 54, 72, 71, 67, 65, 54, 54, 54, 64, 61,
-
- 41, 40, 38, 37, 36, 34, 32, 30, 28, 27,
- 25, 17, 15, 13, 11, 0, 0, 0, 0, 0,
- 54, 0, 54, 55, 55, 0, 55, 0, 0, 0,
- 0, 0, 0, 0, 55, 55, 55, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 55,
- 0, 55, 59, 59, 0, 59, 0, 0, 0, 0,
- 0, 0, 0, 59, 59, 59, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 59, 0,
-
- 59, 69, 69, 0, 69, 0, 0, 0, 69, 69,
- 69, 0, 69, 0, 69, 69, 69, 0, 69, 0,
- 0, 69, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 69, 101, 101, 0,
- 0, 0, 0, 101, 0, 0, 0, 0, 101, 101,
- 101, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 101, 0, 101, 105, 105, 0, 0,
- 0, 0, 105, 0, 0, 0, 0, 105, 105, 105,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 105, 0, 105, 106, 106, 0, 0, 0,
- 0, 106, 0, 0, 0, 0, 106, 106, 106, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 106, 0, 106, 107, 107, 0, 0, 0, 0,
- 107, 0, 0, 0, 0, 107, 107, 107, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 107, 0, 107, 108, 108, 0, 0, 0, 0, 108,
- 0, 0, 0, 0, 108, 108, 108, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 108,
- 0, 108, 109, 109, 0, 109, 0, 0, 0, 0,
- 0, 0, 0, 109, 109, 109, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 109, 0,
- 109, 113, 113, 0, 113, 0, 0, 0, 0, 0,
- 0, 0, 113, 113, 113, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 113, 0, 113,
- 115, 115, 0, 115, 0, 0, 0, 0, 0, 0,
- 0, 115, 115, 115, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 115, 0, 115, 116,
- 116, 0, 116, 0, 0, 0, 0, 0, 0, 0,
- 116, 116, 116, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 116, 0, 116, 117, 117,
-
- 0, 117, 0, 0, 0, 0, 0, 0, 0, 117,
- 117, 117, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 117, 0, 117, 118, 118, 0,
- 118, 0, 0, 0, 0, 0, 0, 0, 118, 118,
- 118, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 118, 0, 118, 127, 127, 0, 127,
- 0, 0, 0, 127, 127, 127, 0, 127, 0, 127,
- 127, 127, 0, 127, 0, 0, 127, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 127, 239, 239, 239, 239, 239, 240, 240, 240,
- 240, 240, 241, 241, 241, 241, 241, 242, 242, 242,
- 242, 242, 243, 243, 243, 244, 244, 244, 244, 244,
- 245, 245, 245, 245, 245, 246, 246, 246, 246, 246,
- 247, 247, 247, 247, 248, 248, 248, 248, 248, 249,
- 0, 249, 249, 249, 250, 0, 250, 250, 250, 251,
- 251, 251, 0, 251, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
-
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
- 238, 238
- } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() (yyg->yy_more_flag = 1)
-#define YY_MORE_ADJ yyg->yy_more_len
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "ael.flex"
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Steve Murphy <murf@parsetree.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.
- */
-/*! \file
- *
- * \brief Flex scanner description of tokens used in AEL2 .
- *
- */
-/*
- * Start with flex options:
- *
- * %x describes the contexts we have: paren, semic and argg, plus INITIAL
- */
-
-/* prefix used for various globally-visible functions and variables.
- * This renames also ael_yywrap, but since we do not use it, we just
- * add option noyywrap to remove it.
- */
-/* ael_yyfree normally just frees its arg. It can be null sometimes,
- which some systems will complain about, so, we'll define our own version */
-/* batch gives a bit more performance if we are using it in
- * a non-interactive mode. We probably don't care much.
- */
-/* outfile is the filename to be used instead of lex.yy.c */
-/*
- * These are not supported in flex 2.5.4, but we need them
- * at the moment:
- * reentrant produces a thread-safe parser. Not 100% sure that
- * we require it, though.
- * bison-bridge passes an additional yylval argument to ael_yylex().
- * bison-locations is probably not needed.
- */
-#line 63 "ael.flex"
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#if defined(__Darwin__) || defined(__CYGWIN__)
-#define GLOB_ABORTED GLOB_ABEND
-#endif
-# include <glob.h>
-
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "ael/ael.tab.h"
-#include "asterisk/ael_structs.h"
-
-/*
- * A stack to keep track of matching brackets ( [ { } ] )
- */
-static char pbcstack[400]; /* XXX missing size checks */
-static int pbcpos = 0;
-static void pbcpush(char x);
-static int pbcpop(char x);
-
-static int parencount = 0;
-
-/*
- * current line, column and filename, updated as we read the input.
- */
-static int my_lineno = 1; /* current line in the source */
-static int my_col = 1; /* current column in the source */
-char *my_file = 0; /* used also in the bison code */
-char *prev_word; /* XXX document it */
-
-#define MAX_INCLUDE_DEPTH 50
-
-/*
- * flex is not too smart, and generates global functions
- * without prototypes so the compiler may complain.
- * To avoid that, we declare the prototypes here,
- * even though these functions are not used.
- */
-int ael_yyget_column (yyscan_t yyscanner);
-void ael_yyset_column (int column_no , yyscan_t yyscanner);
-
-int ael_yyparse (struct parse_io *);
-
-/*
- * A stack to process include files.
- * As we switch into the new file we need to store the previous
- * state to restore it later.
- */
-struct stackelement {
- char *fname;
- int lineno;
- int colno;
- glob_t globbuf; /* the current globbuf */
- int globbuf_pos; /* where we are in the current globbuf */
- YY_BUFFER_STATE bufstate;
-};
-
-static struct stackelement include_stack[MAX_INCLUDE_DEPTH];
-static int include_stack_index = 0;
-static void setup_filestack(char *fnamebuf, int fnamebuf_siz, glob_t *globbuf, int globpos, yyscan_t xscan, int create);
-
-/*
- * if we use the @n feature of bison, we must supply the start/end
- * location of tokens in the structure pointed by yylloc.
- * Simple tokens are just assumed to be on the same line, so
- * the line number is constant, and the column is incremented
- * by the length of the token.
- */
-#ifdef FLEX_BETA /* set for 2.5.33 */
-
-/* compute the total number of lines and columns in the text
- * passed as argument.
- */
-static void pbcwhere(const char *text, int *line, int *col )
-{
- int loc_line = *line;
- int loc_col = *col;
- char c;
- while ( (c = *text++) ) {
- if ( c == '\t' ) {
- loc_col += 8 - (loc_col % 8);
- } else if ( c == '\n' ) {
- loc_line++;
- loc_col = 1;
- } else
- loc_col++;
- }
- *line = loc_line;
- *col = loc_col;
-}
-
-#define STORE_POS do { \
- yylloc->first_line = yylloc->last_line = my_lineno; \
- yylloc->first_column=my_col; \
- yylloc->last_column=my_col+yyleng-1; \
- my_col+=yyleng; \
- } while (0)
-
-#define STORE_LOC do { \
- yylloc->first_line = my_lineno; \
- yylloc->first_column=my_col; \
- pbcwhere(yytext, &my_lineno, &my_col); \
- yylloc->last_line = my_lineno; \
- yylloc->last_column = my_col - 1; \
- } while (0)
-#else
-#define STORE_POS
-#define STORE_LOC
-#endif
-#line 908 "ael_lex.c"
-
-#define INITIAL 0
-#define paren 1
-#define semic 2
-#define argg 3
-#define comment 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
- {
-
- /* User-defined. Not touched by flex. */
- YY_EXTRA_TYPE yyextra_r;
-
- /* The rest are the same as the globals declared in the non-reentrant scanner. */
- FILE *yyin_r, *yyout_r;
- size_t yy_buffer_stack_top; /**< index of top of stack. */
- size_t yy_buffer_stack_max; /**< capacity of stack. */
- YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
- char yy_hold_char;
- int yy_n_chars;
- int yyleng_r;
- char *yy_c_buf_p;
- int yy_init;
- int yy_start;
- int yy_did_buffer_switch_on_eof;
- int yy_start_stack_ptr;
- int yy_start_stack_depth;
- int *yy_start_stack;
- yy_state_type yy_last_accepting_state;
- char* yy_last_accepting_cpos;
-
- int yylineno_r;
- int yy_flex_debug_r;
-
- char *yytext_r;
- int yy_more_flag;
- int yy_more_len;
-
- YYSTYPE * yylval_r;
-
- YYLTYPE * yylloc_r;
-
- }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
- /* This must go here because YYSTYPE and YYLTYPE are included
- * from bison output in section 1.*/
- # define yylval yyg->yylval_r
-
- # define yylloc yyg->yylloc_r
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int ael_yylex_destroy (yyscan_t yyscanner );
-
-int ael_yyget_debug (yyscan_t yyscanner );
-
-void ael_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE ael_yyget_extra (yyscan_t yyscanner );
-
-void ael_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *ael_yyget_in (yyscan_t yyscanner );
-
-void ael_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *ael_yyget_out (yyscan_t yyscanner );
-
-void ael_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-
-int ael_yyget_leng (yyscan_t yyscanner );
-
-char *ael_yyget_text (yyscan_t yyscanner );
-
-int ael_yyget_lineno (yyscan_t yyscanner );
-
-void ael_yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-YYSTYPE * ael_yyget_lval (yyscan_t yyscanner );
-
-void ael_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
-
- YYLTYPE *ael_yyget_lloc (yyscan_t yyscanner );
-
- void ael_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int ael_yywrap (yyscan_t yyscanner );
-#else
-extern int ael_yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- size_t n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int ael_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
-
-#define YY_DECL int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 185 "ael.flex"
-
-
-#line 1150 "ael_lex.c"
-
- yylval = yylval_param;
-
- yylloc = yylloc_param;
-
- if ( !yyg->yy_init )
- {
- yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yyg->yy_start )
- yyg->yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- ael_yyensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- ael_yy_load_buffer_state(yyscanner );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yyg->yy_more_len = 0;
- if ( yyg->yy_more_flag )
- {
- yyg->yy_more_len = yyg->yy_c_buf_p - yyg->yytext_ptr;
- yyg->yy_more_flag = 0;
- }
- yy_cp = yyg->yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yyg->yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yyg->yy_start;
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 239 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_current_state != 238 );
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yyg->yy_hold_char;
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 187 "ael.flex"
-{ STORE_POS; return LC;}
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 188 "ael.flex"
-{ STORE_POS; return RC;}
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 189 "ael.flex"
-{ STORE_POS; return LP;}
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 190 "ael.flex"
-{ STORE_POS; return RP;}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 191 "ael.flex"
-{ STORE_POS; return SEMI;}
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 192 "ael.flex"
-{ STORE_POS; return EQ;}
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 193 "ael.flex"
-{ STORE_POS; return COMMA;}
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 194 "ael.flex"
-{ STORE_POS; return COLON;}
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 195 "ael.flex"
-{ STORE_POS; return AMPER;}
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 196 "ael.flex"
-{ STORE_POS; return BAR;}
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 197 "ael.flex"
-{ STORE_POS; return EXTENMARK;}
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 198 "ael.flex"
-{ STORE_POS; return AT;}
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 199 "ael.flex"
-{/*comment*/}
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 200 "ael.flex"
-{ STORE_POS; return KW_CONTEXT;}
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 201 "ael.flex"
-{ STORE_POS; return KW_ABSTRACT;}
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 202 "ael.flex"
-{ STORE_POS; return KW_EXTEND;}
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 203 "ael.flex"
-{ STORE_POS; return KW_MACRO;};
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 204 "ael.flex"
-{ STORE_POS; return KW_GLOBALS;}
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 205 "ael.flex"
-{ STORE_POS; return KW_IGNOREPAT;}
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 206 "ael.flex"
-{ STORE_POS; return KW_SWITCH;}
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 207 "ael.flex"
-{ STORE_POS; return KW_IF;}
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 208 "ael.flex"
-{ STORE_POS; return KW_IFTIME;}
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 209 "ael.flex"
-{ STORE_POS; return KW_RANDOM;}
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 210 "ael.flex"
-{ STORE_POS; return KW_REGEXTEN;}
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 211 "ael.flex"
-{ STORE_POS; return KW_HINT;}
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 212 "ael.flex"
-{ STORE_POS; return KW_ELSE;}
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 213 "ael.flex"
-{ STORE_POS; return KW_GOTO;}
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 214 "ael.flex"
-{ STORE_POS; return KW_JUMP;}
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 215 "ael.flex"
-{ STORE_POS; return KW_RETURN;}
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 216 "ael.flex"
-{ STORE_POS; return KW_BREAK;}
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 217 "ael.flex"
-{ STORE_POS; return KW_CONTINUE;}
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 218 "ael.flex"
-{ STORE_POS; return KW_FOR;}
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 219 "ael.flex"
-{ STORE_POS; return KW_WHILE;}
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 220 "ael.flex"
-{ STORE_POS; return KW_CASE;}
- YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 221 "ael.flex"
-{ STORE_POS; return KW_DEFAULT;}
- YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 222 "ael.flex"
-{ STORE_POS; return KW_PATTERN;}
- YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 223 "ael.flex"
-{ STORE_POS; return KW_CATCH;}
- YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 224 "ael.flex"
-{ STORE_POS; return KW_SWITCHES;}
- YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 225 "ael.flex"
-{ STORE_POS; return KW_ESWITCHES;}
- YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 226 "ael.flex"
-{ STORE_POS; return KW_INCLUDES;}
- YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 227 "ael.flex"
-{ BEGIN(comment); my_col += 2; }
- YY_BREAK
-case 42:
-YY_RULE_SETUP
-#line 229 "ael.flex"
-{ my_col += yyleng; }
- YY_BREAK
-case 43:
-/* rule 43 can match eol */
-YY_RULE_SETUP
-#line 230 "ael.flex"
-{ ++my_lineno; my_col=1;}
- YY_BREAK
-case 44:
-YY_RULE_SETUP
-#line 231 "ael.flex"
-{ my_col += yyleng; }
- YY_BREAK
-case 45:
-/* rule 45 can match eol */
-YY_RULE_SETUP
-#line 232 "ael.flex"
-{ ++my_lineno; my_col=1;}
- YY_BREAK
-case 46:
-YY_RULE_SETUP
-#line 233 "ael.flex"
-{ my_col += 2; BEGIN(INITIAL); }
- YY_BREAK
-case 47:
-/* rule 47 can match eol */
-YY_RULE_SETUP
-#line 235 "ael.flex"
-{ my_lineno++; my_col = 1; }
- YY_BREAK
-case 48:
-YY_RULE_SETUP
-#line 236 "ael.flex"
-{ my_col += yyleng; }
- YY_BREAK
-case 49:
-YY_RULE_SETUP
-#line 237 "ael.flex"
-{ my_col += (yyleng*8)-(my_col%8); }
- YY_BREAK
-case 50:
-YY_RULE_SETUP
-#line 239 "ael.flex"
-{
- STORE_POS;
- yylval->str = strdup(yytext);
- prev_word = yylval->str;
- return word;
- }
- YY_BREAK
-/*
- * context used for arguments of if_head, random_head, switch_head,
- * for (last statement), while (XXX why not iftime_head ?).
- * End with the matching parentheses.
- * A comma at the top level is valid here, unlike in argg where it
- * is an argument separator so it must be returned as a token.
- */
-case 51:
-/* rule 51 can match eol */
-YY_RULE_SETUP
-#line 255 "ael.flex"
-{
- if ( pbcpop(')') ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno, my_col, yytext);
- BEGIN(0);
- yylval->str = strdup(yytext);
- prev_word = 0;
- return word;
- }
- parencount--;
- if ( parencount >= 0) {
- yymore();
- } else {
- STORE_LOC;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
- unput(')');
- BEGIN(0);
- return word;
- }
- }
- YY_BREAK
-case 52:
-/* rule 52 can match eol */
-YY_RULE_SETUP
-#line 277 "ael.flex"
-{
- char c = yytext[yyleng-1];
- if (c == '(')
- parencount++;
- pbcpush(c);
- yymore();
- }
- YY_BREAK
-case 53:
-/* rule 53 can match eol */
-YY_RULE_SETUP
-#line 285 "ael.flex"
-{
- char c = yytext[yyleng-1];
- if ( pbcpop(c)) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n",
- my_file, my_lineno, my_col, c);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
- yymore();
- }
- YY_BREAK
-/*
- * handlers for arguments to a macro or application calls.
- * We enter this context when we find the initial '(' and
- * stay here until we close all matching parentheses,
- * and find the comma (argument separator) or the closing ')'
- * of the (external) call, which happens when parencount == 0
- * before the decrement.
- */
-case 54:
-/* rule 54 can match eol */
-YY_RULE_SETUP
-#line 307 "ael.flex"
-{
- char c = yytext[yyleng-1];
- if (c == '(')
- parencount++;
- pbcpush(c);
- yymore();
- }
- YY_BREAK
-case 55:
-/* rule 55 can match eol */
-YY_RULE_SETUP
-#line 315 "ael.flex"
-{
- if ( pbcpop(')') ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno, my_col);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
-
- parencount--;
- if( parencount >= 0){
- yymore();
- } else {
- STORE_LOC;
- BEGIN(0);
- if ( !strcmp(yytext, ")") )
- return RP;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
- unput(')');
- return word;
- }
- }
- YY_BREAK
-case 56:
-/* rule 56 can match eol */
-YY_RULE_SETUP
-#line 339 "ael.flex"
-{
- if( parencount != 0) { /* printf("Folding in a comma!\n"); */
- yymore();
- } else {
- STORE_LOC;
- if( !strcmp(yytext,"," ) )
- return COMMA;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0';
- unput(',');
- return word;
- }
- }
- YY_BREAK
-case 57:
-/* rule 57 can match eol */
-YY_RULE_SETUP
-#line 353 "ael.flex"
-{
- char c = yytext[yyleng-1];
- if ( pbcpop(c) ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
- yymore();
- }
- YY_BREAK
-/*
- * context used to find tokens in the right hand side of assignments,
- * or in the first and second operand of a 'for'. As above, match
- * commas and use ';' as a separator (hence return it as a separate token).
- */
-case 58:
-/* rule 58 can match eol */
-YY_RULE_SETUP
-#line 370 "ael.flex"
-{
- char c = yytext[yyleng-1];
- yymore();
- pbcpush(c);
- }
- YY_BREAK
-case 59:
-/* rule 59 can match eol */
-YY_RULE_SETUP
-#line 376 "ael.flex"
-{
- char c = yytext[yyleng-1];
- if ( pbcpop(c) ) { /* error */
- STORE_LOC;
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
- BEGIN(0);
- yylval->str = strdup(yytext);
- return word;
- }
- yymore();
- }
- YY_BREAK
-case 60:
-/* rule 60 can match eol */
-YY_RULE_SETUP
-#line 388 "ael.flex"
-{
- STORE_LOC;
- yylval->str = strdup(yytext);
- yylval->str[yyleng-1] = '\0';
- unput(';');
- BEGIN(0);
- return word;
- }
- YY_BREAK
-case 61:
-/* rule 61 can match eol */
-YY_RULE_SETUP
-#line 397 "ael.flex"
-{
- char fnamebuf[1024],*p1,*p2;
- int glob_ret;
- glob_t globbuf; /* the current globbuf */
- int globbuf_pos = -1; /* where we are in the current globbuf */
- globbuf.gl_offs = 0; /* initialize it to silence gcc */
-
- p1 = strchr(yytext,'"');
- p2 = strrchr(yytext,'"');
- if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col);
- } else if ( (int)(p2-p1) > sizeof(fnamebuf) - 1 ) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10);
- } else {
- strncpy(fnamebuf, p1+1, p2-p1-1);
- fnamebuf[p2-p1-1] = 0;
-
-#ifdef SOLARIS
- glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf);
-#else
- glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
-#endif
- if (glob_ret == GLOB_NOSPACE) {
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: Not enough memory\n", fnamebuf);
- } else if (glob_ret == GLOB_ABORTED) {
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: Read error\n", fnamebuf);
- } else if (glob_ret == GLOB_NOMATCH) {
- ast_log(LOG_WARNING,
- "Glob Expansion of pattern '%s' failed: No matches!\n", fnamebuf);
- } else {
- globbuf_pos = 0;
- }
- }
- if (globbuf_pos > -1) {
- setup_filestack(fnamebuf, sizeof(fnamebuf), &globbuf, 0, yyscanner, 1);
- }
- }
- YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(paren):
-case YY_STATE_EOF(semic):
-case YY_STATE_EOF(argg):
-case YY_STATE_EOF(comment):
-#line 438 "ael.flex"
-{
- char fnamebuf[2048];
- if (include_stack_index > 0 && include_stack[include_stack_index-1].globbuf_pos < include_stack[include_stack_index-1].globbuf.gl_pathc-1) {
- ael_yy_delete_buffer(YY_CURRENT_BUFFER,yyscanner );
- include_stack[include_stack_index-1].globbuf_pos++;
- setup_filestack(fnamebuf, sizeof(fnamebuf), &include_stack[include_stack_index-1].globbuf, include_stack[include_stack_index-1].globbuf_pos, yyscanner, 0);
- /* finish this */
-
- } else {
- if (include_stack[include_stack_index].fname) {
- free(include_stack[include_stack_index].fname);
- include_stack[include_stack_index].fname = 0;
- }
- if (my_file) {
- free(my_file);
- my_file = 0;
- }
- if ( --include_stack_index < 0 ) {
- yyterminate();
- } else {
- globfree(&include_stack[include_stack_index].globbuf);
- include_stack[include_stack_index].globbuf_pos = -1;
-
- ael_yy_delete_buffer(YY_CURRENT_BUFFER,yyscanner );
- ael_yy_switch_to_buffer(include_stack[include_stack_index].bufstate,yyscanner );
- my_lineno = include_stack[include_stack_index].lineno;
- my_col = include_stack[include_stack_index].colno;
- my_file = strdup(include_stack[include_stack_index].fname);
- }
- }
- }
- YY_BREAK
-case 62:
-YY_RULE_SETUP
-#line 470 "ael.flex"
-ECHO;
- YY_BREAK
-#line 1772 "ael_lex.c"
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yyg->yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * ael_yylex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yyg->yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yyg->yy_did_buffer_switch_on_eof = 0;
-
- if ( ael_yywrap(yyscanner ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p =
- yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yyg->yy_c_buf_p =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of ael_yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- ael_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- yyg->yy_n_chars, num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- if ( yyg->yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- ael_yyrestart(yyin ,yyscanner);
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- yyg->yy_n_chars += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_current_state = yyg->yy_start;
-
- for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 239 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
- register int yy_is_jam;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 239 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 238);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
-{
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_cp = yyg->yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yyg->yy_hold_char;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = yyg->yy_n_chars + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- yyg->yytext_ptr = yy_bp;
- yyg->yy_hold_char = *yy_cp;
- yyg->yy_c_buf_p = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (yyscan_t yyscanner)
-#else
- static int input (yyscan_t yyscanner)
-#endif
-
-{
- int c;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
- if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- /* This was really a NUL. */
- *yyg->yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
- ++yyg->yy_c_buf_p;
-
- switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- ael_yyrestart(yyin ,yyscanner);
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( ael_yywrap(yyscanner ) )
- return EOF;
-
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput(yyscanner);
-#else
- return input(yyscanner);
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
- *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
- yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void ael_yyrestart (FILE * input_file , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! YY_CURRENT_BUFFER ){
- ael_yyensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- ael_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- ael_yy_load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
- void ael_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* TODO. We should be able to replace this entire function body
- * with
- * ael_yypop_buffer_state();
- * ael_yypush_buffer_state(new_buffer);
- */
- ael_yyensure_buffer_stack (yyscanner);
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- ael_yy_load_buffer_state(yyscanner );
-
- /* We don't actually know whether we did this switch during
- * EOF (ael_yywrap()) processing, but the only time this flag
- * is looked at is after ael_yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-static void ael_yy_load_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- yyg->yy_hold_char = *yyg->yy_c_buf_p;
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE ael_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) ael_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in ael_yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) ael_yyalloc(b->yy_buf_size + 2 ,yyscanner );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in ael_yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- ael_yy_init_buffer(b,file ,yyscanner);
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with ael_yy_create_buffer()
- * @param yyscanner The scanner object.
- */
- void ael_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- ael_yyfree((void *) b->yy_ch_buf ,yyscanner );
-
- ael_yyfree((void *) b ,yyscanner );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a ael_yyrestart() or at EOF.
- */
- static void ael_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
-
-{
- int oerrno = errno;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- ael_yy_flush_buffer(b ,yyscanner);
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then ael_yy_init_buffer was _probably_
- * called from ael_yyrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
- void ael_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- ael_yy_load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- * @param yyscanner The scanner object.
- */
-void ael_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (new_buffer == NULL)
- return;
-
- ael_yyensure_buffer_stack(yyscanner);
-
- /* This block is copied from ael_yy_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- yyg->yy_buffer_stack_top++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from ael_yy_switch_to_buffer. */
- ael_yy_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- * @param yyscanner The scanner object.
- */
-void ael_yypop_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (!YY_CURRENT_BUFFER)
- return;
-
- ael_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if (yyg->yy_buffer_stack_top > 0)
- --yyg->yy_buffer_stack_top;
-
- if (YY_CURRENT_BUFFER) {
- ael_yy_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void ael_yyensure_buffer_stack (yyscan_t yyscanner)
-{
- int num_to_alloc;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (!yyg->yy_buffer_stack) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ael_yyalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
-
- memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- yyg->yy_buffer_stack_max = num_to_alloc;
- yyg->yy_buffer_stack_top = 0;
- return;
- }
-
- if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ael_yyrealloc
- (yyg->yy_buffer_stack,
- num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
-
- /* zero only the new slots.*/
- memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
- yyg->yy_buffer_stack_max = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE ael_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) ael_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in ael_yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- ael_yy_switch_to_buffer(b ,yyscanner );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to ael_yylex() will
- * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * ael_yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE ael_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-
- return ael_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to ael_yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE ael_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) ael_yyalloc(n ,yyscanner );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in ael_yy_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = ael_yy_scan_buffer(buf,n ,yyscanner);
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in ael_yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = yyg->yy_hold_char; \
- yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
- yyg->yy_hold_char = *yyg->yy_c_buf_p; \
- *yyg->yy_c_buf_p = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE ael_yyget_extra (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int ael_yyget_lineno (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int ael_yyget_column (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *ael_yyget_in (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *ael_yyget_out (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int ael_yyget_leng (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *ael_yyget_text (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void ael_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void ael_yyset_lineno (int line_number , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* lineno is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ael_yyset_lineno called with no buffer" , yyscanner);
-
- yylineno = line_number;
-}
-
-/** Set the current column.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void ael_yyset_column (int column_no , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* column is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ael_yyset_column called with no buffer" , yyscanner);
-
- yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see ael_yy_switch_to_buffer
- */
-void ael_yyset_in (FILE * in_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
-}
-
-void ael_yyset_out (FILE * out_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
-}
-
-int ael_yyget_debug (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yy_flex_debug;
-}
-
-void ael_yyset_debug (int bdebug , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-YYSTYPE * ael_yyget_lval (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yylval;
-}
-
-void ael_yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yylval = yylval_param;
-}
-
-YYLTYPE *ael_yyget_lloc (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yylloc;
-}
-
-void ael_yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yylloc = yylloc_param;
-}
-
-/* User-visible API */
-
-/* ael_yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int ael_yylex_init(yyscan_t* ptr_yy_globals)
-
-{
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) ael_yyalloc ( sizeof( struct yyguts_t ), NULL );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from ael_yylex_destroy(), so don't allocate here.
- */
-
- yyg->yy_buffer_stack = 0;
- yyg->yy_buffer_stack_top = 0;
- yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
- yyg->yy_init = 0;
- yyg->yy_start = 0;
-
- yyg->yy_start_stack_ptr = 0;
- yyg->yy_start_stack_depth = 0;
- yyg->yy_start_stack = NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * ael_yylex_init()
- */
- return 0;
-}
-
-/* ael_yylex_destroy is for both reentrant and non-reentrant scanners. */
-int ael_yylex_destroy (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- ael_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- ael_yypop_buffer_state(yyscanner);
- }
-
- /* Destroy the stack itself. */
- ael_yyfree(yyg->yy_buffer_stack ,yyscanner);
- yyg->yy_buffer_stack = NULL;
-
- /* Destroy the start condition stack. */
- ael_yyfree(yyg->yy_start_stack ,yyscanner );
- yyg->yy_start_stack = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * ael_yylex() is called, initialization will occur. */
- yy_init_globals( yyscanner);
-
- /* Destroy the main struct (reentrant only). */
- ael_yyfree ( yyscanner , yyscanner );
- yyscanner = NULL;
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *ael_yyalloc (yy_size_t size , yyscan_t yyscanner)
-{
- return (void *) malloc( size );
-}
-
-void *ael_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 470 "ael.flex"
-
-
-
-static void pbcpush(char x)
-{
- pbcstack[pbcpos++] = x;
-}
-
-void ael_yyfree(void *ptr, yyscan_t yyscanner)
-{
- if (ptr)
- free( (char*) ptr );
-}
-
-static int pbcpop(char x)
-{
- if ( ( x == ')' && pbcstack[pbcpos-1] == '(' )
- || ( x == ']' && pbcstack[pbcpos-1] == '[' )
- || ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
- pbcpos--;
- return 0;
- }
- return 1; /* error */
-}
-
-static int c_prevword(void)
-{
- char *c = prev_word;
- if (c == NULL)
- return 0;
- while ( *c ) {
- switch (*c) {
- case '{':
- case '[':
- case '(':
- pbcpush(*c);
- break;
- case '}':
- case ']':
- case ')':
- if (pbcpop(*c))
- return 1;
- break;
- }
- c++;
- }
- return 0;
-}
-
-
-/*
- * The following three functions, reset_*, are used in the bison
- * code to switch context. As a consequence, we need to
- * declare them global and add a prototype so that the
- * compiler does not complain.
- *
- * NOTE: yyg is declared because it is used in the BEGIN macros,
- * though that should be hidden as the macro changes
- * depending on the flex options that we use - in particular,
- * %reentrant changes the way the macro is declared;
- * without %reentrant, BEGIN uses yystart instead of yyg
- */
-
-void reset_parencount(yyscan_t yyscanner );
-void reset_parencount(yyscan_t yyscanner )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- parencount = 0;
- pbcpos = 0;
- pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */
- c_prevword();
- BEGIN(paren);
-}
-
-void reset_semicount(yyscan_t yyscanner );
-void reset_semicount(yyscan_t yyscanner )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- pbcpos = 0;
- BEGIN(semic);
-}
-
-void reset_argcount(yyscan_t yyscanner );
-void reset_argcount(yyscan_t yyscanner )
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- parencount = 0;
- pbcpos = 0;
- pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */
- c_prevword();
- BEGIN(argg);
-}
-
-/* used elsewhere, but some local vars */
-struct pval *ael2_parse(char *filename, int *errors)
-{
- struct pval *pval;
- struct parse_io *io;
- char *buffer;
- struct stat stats;
- FILE *fin;
-
- /* extern int ael_yydebug; */
-
- io = calloc(sizeof(struct parse_io),1);
- /* reset the global counters */
- prev_word = 0;
- my_lineno = 1;
- include_stack_index=0;
- my_col = 0;
- /* ael_yydebug = 1; */
- ael_yylex_init(&io->scanner);
- fin = fopen(filename,"r");
- if ( !fin ) {
- ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
- *errors = 1;
- return 0;
- }
- if (my_file)
- free(my_file);
- my_file = strdup(filename);
- stat(filename, &stats);
- buffer = (char*)malloc(stats.st_size+2);
- fread(buffer, 1, stats.st_size, fin);
- buffer[stats.st_size]=0;
- fclose(fin);
-
- ael_yy_scan_string (buffer ,io->scanner);
- ael_yyset_lineno(1 , io->scanner);
-
- /* ael_yyset_in (fin , io->scanner); OLD WAY */
-
- ael_yyparse(io);
-
-
- pval = io->pval;
- *errors = io->syntax_error_count;
-
- ael_yylex_destroy(io->scanner);
- free(buffer);
- free(io);
-
- return pval;
-}
-
-static void setup_filestack(char *fnamebuf2, int fnamebuf_siz, glob_t *globbuf, int globpos, yyscan_t yyscanner, int create)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- int error, i;
- FILE *in1;
- char fnamebuf[2048];
-
- if (globbuf && globbuf->gl_pathv && globbuf->gl_pathc > 0)
-#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL)
- strncpy(fnamebuf, globbuf->gl_pathv[globpos], fnamebuf_siz);
-#else
- ast_copy_string(fnamebuf, globbuf->gl_pathv[globpos], fnamebuf_siz);
-#endif
- else {
- ast_log(LOG_ERROR,"Include file name not present!\n");
- return;
- }
- for (i=0; i<include_stack_index; i++) {
- if ( !strcmp(fnamebuf,include_stack[i].fname )) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n",
- my_file, my_lineno, my_col, fnamebuf);
- break;
- }
- }
- error = 1;
- if (i == include_stack_index)
- error = 0; /* we can use this file */
- if ( !error ) { /* valid file name */
- /* relative vs. absolute */
- if (fnamebuf[0] != '/')
- snprintf(fnamebuf2, fnamebuf_siz, "%s/%s", ast_config_AST_CONFIG_DIR, fnamebuf);
- else
-#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL)
- strncpy(fnamebuf2, fnamebuf, fnamebuf_siz);
-#else
- ast_copy_string(fnamebuf2, fnamebuf, fnamebuf_siz);
-#endif
- in1 = fopen( fnamebuf2, "r" );
-
- if ( ! in1 ) {
- ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf2);
- } else {
- char *buffer;
- struct stat stats;
- stat(fnamebuf2, &stats);
- buffer = (char*)malloc(stats.st_size+1);
- fread(buffer, 1, stats.st_size, in1);
- buffer[stats.st_size] = 0;
- ast_log(LOG_NOTICE," --Read in included file %s, %d chars\n",fnamebuf2, (int)stats.st_size);
- fclose(in1);
- if (include_stack[include_stack_index].fname) {
- free(include_stack[include_stack_index].fname);
- include_stack[include_stack_index].fname = 0;
- }
- include_stack[include_stack_index].fname = strdup(my_file);
- include_stack[include_stack_index].lineno = my_lineno;
- include_stack[include_stack_index].colno = my_col+yyleng;
- if (my_file)
- free(my_file);
- my_file = strdup(fnamebuf2);
- if (create)
- include_stack[include_stack_index].globbuf = *globbuf;
-
- include_stack[include_stack_index].globbuf_pos = 0;
-
- include_stack[include_stack_index].bufstate = YY_CURRENT_BUFFER;
- if (create)
- include_stack_index++;
- ael_yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
- free(buffer);
- my_lineno = 1;
- my_col = 1;
- BEGIN(INITIAL);
- }
- }
-}
-
diff --git a/1.4/pbx/dundi-parser.c b/1.4/pbx/dundi-parser.c
deleted file mode 100644
index 14ef9e740..000000000
--- a/1.4/pbx/dundi-parser.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Distributed Universal Number Discovery (DUNDi)
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "asterisk/frame.h"
-#include "asterisk/utils.h"
-#include "asterisk/dundi.h"
-#include "dundi-parser.h"
-#include "asterisk/dundi.h"
-
-static void internaloutput(const char *str)
-{
- fputs(str, stdout);
-}
-
-static void internalerror(const char *str)
-{
- fprintf(stderr, "WARNING: %s", str);
-}
-
-static void (*outputf)(const char *str) = internaloutput;
-static void (*errorf)(const char *str) = internalerror;
-
-char *dundi_eid_to_str(char *s, int maxlen, dundi_eid *eid)
-{
- int x;
- char *os = s;
- if (maxlen < 18) {
- if (s && (maxlen > 0))
- *s = '\0';
- } else {
- for (x=0;x<5;x++) {
- sprintf(s, "%02x:", eid->eid[x]);
- s += 3;
- }
- sprintf(s, "%02x", eid->eid[5]);
- }
- return os;
-}
-
-char *dundi_eid_to_str_short(char *s, int maxlen, dundi_eid *eid)
-{
- int x;
- char *os = s;
- if (maxlen < 13) {
- if (s && (maxlen > 0))
- *s = '\0';
- } else {
- for (x=0;x<6;x++) {
- sprintf(s, "%02X", eid->eid[x]);
- s += 2;
- }
- }
- return os;
-}
-
-int dundi_str_to_eid(dundi_eid *eid, char *s)
-{
- unsigned int eid_int[6];
- int x;
- if (sscanf(s, "%x:%x:%x:%x:%x:%x", &eid_int[0], &eid_int[1], &eid_int[2],
- &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
- return -1;
- for (x=0;x<6;x++)
- eid->eid[x] = eid_int[x];
- return 0;
-}
-
-int dundi_str_short_to_eid(dundi_eid *eid, char *s)
-{
- unsigned int eid_int[6];
- int x;
- if (sscanf(s, "%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2],
- &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
- return -1;
- for (x=0;x<6;x++)
- eid->eid[x] = eid_int[x];
- return 0;
-}
-
-int dundi_eid_zero(dundi_eid *eid)
-{
- int x;
- for (x=0;x<sizeof(eid->eid) / sizeof(eid->eid[0]);x++)
- if (eid->eid[x]) return 0;
- return 1;
-}
-
-int dundi_eid_cmp(dundi_eid *eid1, dundi_eid *eid2)
-{
- return memcmp(eid1, eid2, sizeof(dundi_eid));
-}
-
-static void dump_string(char *output, int maxlen, void *value, int len)
-{
- maxlen--;
- if (maxlen > len)
- maxlen = len;
- strncpy(output, value, maxlen);
- output[maxlen] = '\0';
-}
-
-static void dump_cbypass(char *output, int maxlen, void *value, int len)
-{
- maxlen--;
- strncpy(output, "Bypass Caches", maxlen);
- output[maxlen] = '\0';
-}
-
-static void dump_eid(char *output, int maxlen, void *value, int len)
-{
- if (len == 6)
- dundi_eid_to_str(output, maxlen, (dundi_eid *)value);
- else
- snprintf(output, maxlen, "Invalid EID len %d", len);
-}
-
-char *dundi_hint2str(char *buf, int bufsiz, int flags)
-{
- strcpy(buf, "");
- buf[bufsiz-1] = '\0';
- if (flags & DUNDI_HINT_TTL_EXPIRED) {
- strncat(buf, "TTLEXPIRED|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_HINT_DONT_ASK) {
- strncat(buf, "DONTASK|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_HINT_UNAFFECTED) {
- strncat(buf, "UNAFFECTED|", bufsiz - strlen(buf) - 1);
- }
- /* Get rid of trailing | */
- if (ast_strlen_zero(buf))
- strcpy(buf, "NONE|");
- buf[strlen(buf)-1] = '\0';
- return buf;
-}
-
-static void dump_hint(char *output, int maxlen, void *value, int len)
-{
- unsigned short flags;
- char tmp[512];
- char tmp2[256];
- if (len < 2) {
- strncpy(output, "<invalid contents>", maxlen);
- return;
- }
- memcpy(&flags, value, sizeof(flags));
- flags = ntohs(flags);
- memset(tmp, 0, sizeof(tmp));
- dundi_hint2str(tmp2, sizeof(tmp2), flags);
- snprintf(tmp, sizeof(tmp), "[%s] ", tmp2);
- memcpy(tmp + strlen(tmp), value + 2, len - 2);
- strncpy(output, tmp, maxlen - 1);
-}
-
-static void dump_cause(char *output, int maxlen, void *value, int len)
-{
- static char *causes[] = {
- "SUCCESS",
- "GENERAL",
- "DYNAMIC",
- "NOAUTH" ,
- };
- char tmp[256];
- char tmp2[256];
- int mlen;
- unsigned char cause;
- if (len < 1) {
- strncpy(output, "<invalid contents>", maxlen);
- return;
- }
- cause = *((unsigned char *)value);
- memset(tmp2, 0, sizeof(tmp2));
- mlen = len - 1;
- if (mlen > 255)
- mlen = 255;
- memcpy(tmp2, value + 1, mlen);
- if (cause < sizeof(causes) / sizeof(causes[0])) {
- if (len > 1)
- snprintf(tmp, sizeof(tmp), "%s: %s", causes[cause], tmp2);
- else
- snprintf(tmp, sizeof(tmp), "%s", causes[cause]);
- } else {
- if (len > 1)
- snprintf(tmp, sizeof(tmp), "%d: %s", cause, tmp2);
- else
- snprintf(tmp, sizeof(tmp), "%d", cause);
- }
-
- strncpy(output,tmp, maxlen);
- output[maxlen] = '\0';
-}
-
-static void dump_int(char *output, int maxlen, void *value, int len)
-{
- if (len == (int)sizeof(unsigned int))
- snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
- else
- snprintf(output, maxlen, "Invalid INT");
-}
-
-static void dump_short(char *output, int maxlen, void *value, int len)
-{
- if (len == (int)sizeof(unsigned short))
- snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
- else
- snprintf(output, maxlen, "Invalid SHORT");
-}
-
-static void dump_byte(char *output, int maxlen, void *value, int len)
-{
- if (len == (int)sizeof(unsigned char))
- snprintf(output, maxlen, "%d", *((unsigned char *)value));
- else
- snprintf(output, maxlen, "Invalid BYTE");
-}
-
-static char *proto2str(int proto, char *buf, int bufsiz)
-{
- switch(proto) {
- case DUNDI_PROTO_NONE:
- strncpy(buf, "None", bufsiz - 1);
- break;
- case DUNDI_PROTO_IAX:
- strncpy(buf, "IAX", bufsiz - 1);
- break;
- case DUNDI_PROTO_SIP:
- strncpy(buf, "SIP", bufsiz - 1);
- break;
- case DUNDI_PROTO_H323:
- strncpy(buf, "H.323", bufsiz - 1);
- break;
- default:
- snprintf(buf, bufsiz, "Unknown Proto(%d)", proto);
- }
- buf[bufsiz-1] = '\0';
- return buf;
-}
-
-char *dundi_flags2str(char *buf, int bufsiz, int flags)
-{
- strcpy(buf, "");
- buf[bufsiz-1] = '\0';
- if (flags & DUNDI_FLAG_EXISTS) {
- strncat(buf, "EXISTS|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_MATCHMORE) {
- strncat(buf, "MATCHMORE|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_CANMATCH) {
- strncat(buf, "CANMATCH|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_IGNOREPAT) {
- strncat(buf, "IGNOREPAT|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_RESIDENTIAL) {
- strncat(buf, "RESIDENCE|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_COMMERCIAL) {
- strncat(buf, "COMMERCIAL|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_MOBILE) {
- strncat(buf, "MOBILE", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_NOUNSOLICITED) {
- strncat(buf, "NOUNSLCTD|", bufsiz - strlen(buf) - 1);
- }
- if (flags & DUNDI_FLAG_NOCOMUNSOLICIT) {
- strncat(buf, "NOCOMUNSLTD|", bufsiz - strlen(buf) - 1);
- }
- /* Get rid of trailing | */
- if (ast_strlen_zero(buf))
- strcpy(buf, "NONE|");
- buf[strlen(buf)-1] = '\0';
- return buf;
-}
-
-static void dump_answer(char *output, int maxlen, void *value, int len)
-{
- struct dundi_answer *answer;
- char proto[40];
- char flags[40];
- char eid_str[40];
- char tmp[512]="";
- if (len >= 10) {
- answer = (struct dundi_answer *)(value);
- memcpy(tmp, answer->data, (len >= 500) ? 500 : len - 10);
- dundi_eid_to_str(eid_str, sizeof(eid_str), &answer->eid);
- snprintf(output, maxlen, "[%s] %d <%s/%s> from [%s]",
- dundi_flags2str(flags, sizeof(flags), ntohs(answer->flags)),
- ntohs(answer->weight),
- proto2str(answer->protocol, proto, sizeof(proto)),
- tmp, eid_str);
- } else
- strncpy(output, "Invalid Answer", maxlen - 1);
-}
-
-static void dump_encrypted(char *output, int maxlen, void *value, int len)
-{
- char iv[33];
- int x;
- if ((len > 16) && !(len % 16)) {
- /* Build up IV */
- for (x=0;x<16;x++) {
- snprintf(iv + (x << 1), 3, "%02x", ((unsigned char *)value)[x]);
- }
- snprintf(output, maxlen, "[IV %s] %d encrypted blocks\n", iv, len / 16);
- } else
- snprintf(output, maxlen, "Invalid Encrypted Datalen %d", len);
-}
-
-static void dump_raw(char *output, int maxlen, void *value, int len)
-{
- int x;
- unsigned char *u = value;
- output[maxlen - 1] = '\0';
- strcpy(output, "[ ");
- for (x=0;x<len;x++) {
- snprintf(output + strlen(output), maxlen - strlen(output) - 1, "%02x ", u[x]);
- }
- strncat(output + strlen(output), "]", maxlen - strlen(output) - 1);
-}
-
-static struct dundi_ie {
- int ie;
- char *name;
- void (*dump)(char *output, int maxlen, void *value, int len);
-} ies[] = {
- { DUNDI_IE_EID, "ENTITY IDENT", dump_eid },
- { DUNDI_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string },
- { DUNDI_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string },
- { DUNDI_IE_EID_DIRECT, "DIRECT EID", dump_eid },
- { DUNDI_IE_ANSWER, "ANSWER", dump_answer },
- { DUNDI_IE_TTL, "TTL", dump_short },
- { DUNDI_IE_VERSION, "VERSION", dump_short },
- { DUNDI_IE_EXPIRATION, "EXPIRATION", dump_short },
- { DUNDI_IE_UNKNOWN, "UKWN DUNDI CMD", dump_byte },
- { DUNDI_IE_CAUSE, "CAUSE", dump_cause },
- { DUNDI_IE_REQEID, "REQUEST EID", dump_eid },
- { DUNDI_IE_ENCDATA, "ENCDATA", dump_encrypted },
- { DUNDI_IE_SHAREDKEY, "SHAREDKEY", dump_raw },
- { DUNDI_IE_SIGNATURE, "SIGNATURE", dump_raw },
- { DUNDI_IE_KEYCRC32, "KEYCRC32", dump_int },
- { DUNDI_IE_HINT, "HINT", dump_hint },
- { DUNDI_IE_DEPARTMENT, "DEPARTMENT", dump_string },
- { DUNDI_IE_ORGANIZATION, "ORGANIZTN", dump_string },
- { DUNDI_IE_LOCALITY, "LOCALITY", dump_string },
- { DUNDI_IE_STATE_PROV, "STATEPROV", dump_string },
- { DUNDI_IE_COUNTRY, "COUNTRY", dump_string },
- { DUNDI_IE_EMAIL, "EMAIL", dump_string },
- { DUNDI_IE_PHONE, "PHONE", dump_string },
- { DUNDI_IE_IPADDR, "ADDRESS", dump_string },
- { DUNDI_IE_CACHEBYPASS, "CBYPASS", dump_cbypass },
-};
-
-const char *dundi_ie2str(int ie)
-{
- int x;
- for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
- if (ies[x].ie == ie)
- return ies[x].name;
- }
- return "Unknown IE";
-}
-
-static void dump_ies(unsigned char *iedata, int spaces, int len)
-{
- int ielen;
- int ie;
- int x;
- int found;
- char interp[1024];
- char tmp[1024];
- if (len < 2)
- return;
- while(len >= 2) {
- ie = iedata[0];
- ielen = iedata[1];
- /* Encrypted data is the remainder */
- if (ie == DUNDI_IE_ENCDATA)
- ielen = len - 2;
- if (ielen + 2> len) {
- snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
- outputf(tmp);
- return;
- }
- found = 0;
- for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
- if (ies[x].ie == ie) {
- if (ies[x].dump) {
- ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
- snprintf(tmp, (int)sizeof(tmp), " %s%-15.15s : %s\n", (spaces ? " " : "" ), ies[x].name, interp);
- outputf(tmp);
- } else {
- if (ielen)
- snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
- else
- strcpy(interp, "Present");
- snprintf(tmp, (int)sizeof(tmp), " %s%-15.15s : %s\n", (spaces ? " " : "" ), ies[x].name, interp);
- outputf(tmp);
- }
- found++;
- }
- }
- if (!found) {
- snprintf(tmp, (int)sizeof(tmp), " %sUnknown IE %03d : Present\n", (spaces ? " " : "" ), ie);
- outputf(tmp);
- }
- iedata += (2 + ielen);
- len -= (2 + ielen);
- }
- outputf("\n");
-}
-
-void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
-{
- char *pref[] = {
- "Tx",
- "Rx",
- " ETx",
- " Erx" };
- char *commands[] = {
- "ACK ",
- "DPDISCOVER ",
- "DPRESPONSE ",
- "EIDQUERY ",
- "EIDRESPONSE ",
- "PRECACHERQ ",
- "PRECACHERP ",
- "INVALID ",
- "UNKNOWN CMD ",
- "NULL ",
- "REQREQ ",
- "REGRESPONSE ",
- "CANCEL ",
- "ENCRYPT ",
- "ENCREJ " };
- char class2[20];
- char *class;
- char subclass2[20];
- char *subclass;
- char tmp[256];
- char retries[20];
- if (ntohs(fhi->dtrans) & DUNDI_FLAG_RETRANS)
- strcpy(retries, "Yes");
- else
- strcpy(retries, "No");
- if ((ntohs(fhi->strans) & DUNDI_FLAG_RESERVED)) {
- /* Ignore frames with high bit set to 1 */
- return;
- }
- if ((fhi->cmdresp & 0x3f) > (int)sizeof(commands)/(int)sizeof(char *)) {
- snprintf(class2, (int)sizeof(class2), "(%d?)", fhi->cmdresp);
- class = class2;
- } else {
- class = commands[(int)(fhi->cmdresp & 0x3f)];
- }
- snprintf(subclass2, (int)sizeof(subclass2), "%02x", fhi->cmdflags);
- subclass = subclass2;
- snprintf(tmp, (int)sizeof(tmp),
- "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n",
- pref[rx],
- retries, fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");
- outputf(tmp);
- snprintf(tmp, (int)sizeof(tmp),
- "%s Flags: %s STrans: %5.5d DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? " " : "",
- subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
- fhi->cmdresp & 0x80 ? " (Final)" : "");
- outputf(tmp);
- dump_ies(fhi->ies, rx > 1, datalen);
-}
-
-int dundi_ie_append_raw(struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen)
-{
- char tmp[256];
- if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
- snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
- errorf(tmp);
- return -1;
- }
- ied->buf[ied->pos++] = ie;
- ied->buf[ied->pos++] = datalen;
- memcpy(ied->buf + ied->pos, data, datalen);
- ied->pos += datalen;
- return 0;
-}
-
-int dundi_ie_append_cause(struct dundi_ie_data *ied, unsigned char ie, unsigned char cause, char *data)
-{
- char tmp[256];
- int datalen = data ? strlen(data) + 1 : 1;
- if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
- snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
- errorf(tmp);
- return -1;
- }
- ied->buf[ied->pos++] = ie;
- ied->buf[ied->pos++] = datalen;
- ied->buf[ied->pos++] = cause;
- memcpy(ied->buf + ied->pos, data, datalen-1);
- ied->pos += datalen-1;
- return 0;
-}
-
-int dundi_ie_append_hint(struct dundi_ie_data *ied, unsigned char ie, unsigned short flags, char *data)
-{
- char tmp[256];
- int datalen = data ? strlen(data) + 2 : 2;
- if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
- snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
- errorf(tmp);
- return -1;
- }
- ied->buf[ied->pos++] = ie;
- ied->buf[ied->pos++] = datalen;
- flags = htons(flags);
- memcpy(ied->buf + ied->pos, &flags, sizeof(flags));
- ied->pos += 2;
- memcpy(ied->buf + ied->pos, data, datalen-1);
- ied->pos += datalen-2;
- return 0;
-}
-
-int dundi_ie_append_encdata(struct dundi_ie_data *ied, unsigned char ie, unsigned char *iv, void *data, int datalen)
-{
- char tmp[256];
- datalen += 16;
- if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
- snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
- errorf(tmp);
- return -1;
- }
- ied->buf[ied->pos++] = ie;
- ied->buf[ied->pos++] = datalen;
- memcpy(ied->buf + ied->pos, iv, 16);
- ied->pos += 16;
- if (data) {
- memcpy(ied->buf + ied->pos, data, datalen-16);
- ied->pos += datalen-16;
- }
- return 0;
-}
-
-int dundi_ie_append_answer(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid, unsigned char protocol, unsigned short flags, unsigned short weight, char *data)
-{
- char tmp[256];
- int datalen = data ? strlen(data) + 11 : 11;
- int x;
- unsigned short myw;
- if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
- snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
- errorf(tmp);
- return -1;
- }
- ied->buf[ied->pos++] = ie;
- ied->buf[ied->pos++] = datalen;
- for (x=0;x<6;x++)
- ied->buf[ied->pos++] = eid->eid[x];
- ied->buf[ied->pos++] = protocol;
- myw = htons(flags);
- memcpy(ied->buf + ied->pos, &myw, 2);
- ied->pos += 2;
- myw = htons(weight);
- memcpy(ied->buf + ied->pos, &myw, 2);
- ied->pos += 2;
- memcpy(ied->buf + ied->pos, data, datalen-11);
- ied->pos += datalen-11;
- return 0;
-}
-
-int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
-{
- return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
-}
-
-int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value)
-{
- unsigned int newval;
- newval = htonl(value);
- return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
-}
-
-int dundi_ie_append_short(struct dundi_ie_data *ied, unsigned char ie, unsigned short value)
-{
- unsigned short newval;
- newval = htons(value);
- return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
-}
-
-int dundi_ie_append_str(struct dundi_ie_data *ied, unsigned char ie, char *str)
-{
- return dundi_ie_append_raw(ied, ie, str, strlen(str));
-}
-
-int dundi_ie_append_eid(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid)
-{
- return dundi_ie_append_raw(ied, ie, (unsigned char *)eid, sizeof(dundi_eid));
-}
-
-int dundi_ie_append_byte(struct dundi_ie_data *ied, unsigned char ie, unsigned char dat)
-{
- return dundi_ie_append_raw(ied, ie, &dat, 1);
-}
-
-int dundi_ie_append(struct dundi_ie_data *ied, unsigned char ie)
-{
- return dundi_ie_append_raw(ied, ie, NULL, 0);
-}
-
-void dundi_set_output(void (*func)(const char *))
-{
- outputf = func;
-}
-
-void dundi_set_error(void (*func)(const char *))
-{
- errorf = func;
-}
-
-int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen)
-{
- /* Parse data into information elements */
- int len;
- int ie;
- char tmp[256];
- memset(ies, 0, (int)sizeof(struct dundi_ies));
- ies->ttl = -1;
- ies->expiration = -1;
- ies->unknowncmd = -1;
- ies->cause = -1;
- while(datalen >= 2) {
- ie = data[0];
- len = data[1];
- if (len > datalen - 2) {
- errorf("Information element length exceeds message size\n");
- return -1;
- }
- switch(ie) {
- case DUNDI_IE_EID:
- case DUNDI_IE_EID_DIRECT:
- if (len != (int)sizeof(dundi_eid)) {
- errorf("Improper entity identifer, expecting 6 bytes!\n");
- } else if (ies->eidcount < DUNDI_MAX_STACK) {
- ies->eids[ies->eidcount] = (dundi_eid *)(data + 2);
- ies->eid_direct[ies->eidcount] = (ie == DUNDI_IE_EID_DIRECT);
- ies->eidcount++;
- } else
- errorf("Too many entities in stack!\n");
- break;
- case DUNDI_IE_REQEID:
- if (len != (int)sizeof(dundi_eid)) {
- errorf("Improper requested entity identifer, expecting 6 bytes!\n");
- } else
- ies->reqeid = (dundi_eid *)(data + 2);
- break;
- case DUNDI_IE_CALLED_CONTEXT:
- ies->called_context = (char *)data + 2;
- break;
- case DUNDI_IE_CALLED_NUMBER:
- ies->called_number = (char *)data + 2;
- break;
- case DUNDI_IE_ANSWER:
- if (len < sizeof(struct dundi_answer)) {
- snprintf(tmp, (int)sizeof(tmp), "Answer expected to be >=%d bytes long but was %d\n", (int)sizeof(struct dundi_answer), len);
- errorf(tmp);
- } else {
- if (ies->anscount < DUNDI_MAX_ANSWERS)
- ies->answers[ies->anscount++]= (struct dundi_answer *)(data + 2);
- else
- errorf("Ignoring extra answers!\n");
- }
- break;
- case DUNDI_IE_TTL:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting ttl to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->ttl = ntohs(*((unsigned short *)(data + 2)));
- break;
- case DUNDI_IE_VERSION:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->version = ntohs(*((unsigned short *)(data + 2)));
- break;
- case DUNDI_IE_EXPIRATION:
- if (len != (int)sizeof(unsigned short)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
- errorf(tmp);
- } else
- ies->expiration = ntohs(*((unsigned short *)(data + 2)));
- break;
- case DUNDI_IE_KEYCRC32:
- if (len != (int)sizeof(unsigned int)) {
- snprintf(tmp, (int)sizeof(tmp), "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
- errorf(tmp);
- } else
- ies->keycrc32 = ntohl(*((unsigned int *)(data + 2)));
- break;
- case DUNDI_IE_UNKNOWN:
- if (len == 1)
- ies->unknowncmd = data[2];
- else {
- snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
- errorf(tmp);
- }
- break;
- case DUNDI_IE_CAUSE:
- if (len >= 1) {
- ies->cause = data[2];
- ies->causestr = (char *)data + 3;
- } else {
- snprintf(tmp, (int)sizeof(tmp), "Expected at least one byte cause, but was %d long\n", len);
- errorf(tmp);
- }
- break;
- case DUNDI_IE_HINT:
- if (len >= 2) {
- ies->hint = (struct dundi_hint *)(data + 2);
- } else {
- snprintf(tmp, (int)sizeof(tmp), "Expected at least two byte hint, but was %d long\n", len);
- errorf(tmp);
- }
- break;
- case DUNDI_IE_DEPARTMENT:
- ies->q_dept = (char *)data + 2;
- break;
- case DUNDI_IE_ORGANIZATION:
- ies->q_org = (char *)data + 2;
- break;
- case DUNDI_IE_LOCALITY:
- ies->q_locality = (char *)data + 2;
- break;
- case DUNDI_IE_STATE_PROV:
- ies->q_stateprov = (char *)data + 2;
- break;
- case DUNDI_IE_COUNTRY:
- ies->q_country = (char *)data + 2;
- break;
- case DUNDI_IE_EMAIL:
- ies->q_email = (char *)data + 2;
- break;
- case DUNDI_IE_PHONE:
- ies->q_phone = (char *)data + 2;
- break;
- case DUNDI_IE_IPADDR:
- ies->q_ipaddr = (char *)data + 2;
- break;
- case DUNDI_IE_ENCDATA:
- /* Recalculate len as the remainder of the message, regardless of
- theoretical length */
- len = datalen - 2;
- if ((len > 16) && !(len % 16)) {
- ies->encblock = (struct dundi_encblock *)(data + 2);
- ies->enclen = len - 16;
- } else {
- snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted data length %d\n", len);
- errorf(tmp);
- }
- break;
- case DUNDI_IE_SHAREDKEY:
- if (len == 128) {
- ies->encsharedkey = (unsigned char *)(data + 2);
- } else {
- snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted shared key length %d\n", len);
- errorf(tmp);
- }
- break;
- case DUNDI_IE_SIGNATURE:
- if (len == 128) {
- ies->encsig = (unsigned char *)(data + 2);
- } else {
- snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted signature length %d\n", len);
- errorf(tmp);
- }
- break;
- case DUNDI_IE_CACHEBYPASS:
- ies->cbypass = 1;
- break;
- default:
- snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len);
- outputf(tmp);
- }
- /* Overwrite information element with 0, to null terminate previous portion */
- data[0] = 0;
- datalen -= (len + 2);
- data += (len + 2);
- }
- /* Null-terminate last field */
- *data = '\0';
- if (datalen) {
- errorf("Invalid information element contents, strange boundary\n");
- return -1;
- }
- return 0;
-}
diff --git a/1.4/pbx/dundi-parser.h b/1.4/pbx/dundi-parser.h
deleted file mode 100644
index 62bbf4384..000000000
--- a/1.4/pbx/dundi-parser.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Distributed Universal Number Discovery (DUNDi)
- *
- * Copyright (C) 2004 - 2005, Digium Inc.
- *
- * Written by Mark Spencer <markster@digium.com>
- *
- * This program is Free Software distributed under the terms of
- * of the GNU General Public License.
- */
-
-#ifndef _DUNDI_PARSER_H
-#define _DUNDI_PARSER_H
-
-#include "asterisk/dundi.h"
-#include "asterisk/aes.h"
-
-#define DUNDI_MAX_STACK 512
-#define DUNDI_MAX_ANSWERS 100
-
-struct dundi_ies {
- dundi_eid *eids[DUNDI_MAX_STACK + 1];
- int eid_direct[DUNDI_MAX_STACK + 1];
- dundi_eid *reqeid;
- int eidcount;
- char *called_context;
- char *called_number;
- struct dundi_answer *answers[DUNDI_MAX_ANSWERS + 1];
- struct dundi_hint *hint;
- int anscount;
- int ttl;
- int version;
- int expiration;
- int unknowncmd;
- unsigned char *pubkey;
- int cause;
- char *q_dept;
- char *q_org;
- char *q_locality;
- char *q_stateprov;
- char *q_country;
- char *q_email;
- char *q_phone;
- char *q_ipaddr;
- char *causestr;
- unsigned char *encsharedkey;
- unsigned char *encsig;
- unsigned long keycrc32;
- struct dundi_encblock *encblock;
- int enclen;
- int cbypass;
-};
-
-struct dundi_ie_data {
- int pos;
- unsigned char buf[8192];
-};
-
-/* Choose a different function for output */
-extern void dundi_set_output(void (*output)(const char *data));
-/* Choose a different function for errors */
-extern void dundi_set_error(void (*output)(const char *data));
-extern void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
-
-extern const char *dundi_ie2str(int ie);
-
-extern int dundi_ie_append_raw(struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen);
-extern int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin);
-extern int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value);
-extern int dundi_ie_append_short(struct dundi_ie_data *ied, unsigned char ie, unsigned short value);
-extern int dundi_ie_append_str(struct dundi_ie_data *ied, unsigned char ie, char *str);
-extern int dundi_ie_append_eid(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid);
-extern int dundi_ie_append_cause(struct dundi_ie_data *ied, unsigned char ie, unsigned char cause, char *desc);
-extern int dundi_ie_append_hint(struct dundi_ie_data *ied, unsigned char ie, unsigned short flags, char *data);
-extern int dundi_ie_append_answer(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid, unsigned char protocol, unsigned short flags, unsigned short weight, char *desc);
-extern int dundi_ie_append_encdata(struct dundi_ie_data *ied, unsigned char ie, unsigned char *iv, void *data, int datalen);
-extern int dundi_ie_append_byte(struct dundi_ie_data *ied, unsigned char ie, unsigned char dat);
-extern int dundi_ie_append(struct dundi_ie_data *ied, unsigned char ie);
-extern int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen);
-extern char *dundi_eid_to_str(char *s, int maxlen, dundi_eid *eid);
-extern char *dundi_eid_to_str_short(char *s, int maxlen, dundi_eid *eid);
-extern int dundi_str_to_eid(dundi_eid *eid, char *s);
-extern int dundi_str_short_to_eid(dundi_eid *eid, char *s);
-extern int dundi_eid_zero(dundi_eid *eid);
-extern int dundi_eid_cmp(dundi_eid *eid1, dundi_eid *eid2);
-extern char *dundi_flags2str(char *s, int maxlen, int flags);
-extern char *dundi_hint2str(char *s, int maxlen, int flags);
-#endif
diff --git a/1.4/pbx/pbx_ael.c b/1.4/pbx/pbx_ael.c
deleted file mode 100644
index bc0eeca2f..000000000
--- a/1.4/pbx/pbx_ael.c
+++ /dev/null
@@ -1,4625 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Steve Murphy <murf@parsetree.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.
- */
-
-/*! \file
- *
- * \brief Compile symbolic Asterisk Extension Logic into Asterisk extensions, version 2.
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <regex.h>
-#include <sys/stat.h>
-
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/callerid.h"
-#include "asterisk/ael_structs.h"
-#ifdef AAL_ARGCHECK
-#include "asterisk/argdesc.h"
-#endif
-
-static char expr_output[2096];
-
-/* these functions are in ../ast_expr2.fl */
-
-#define DEBUG_READ (1 << 0)
-#define DEBUG_TOKENS (1 << 1)
-#define DEBUG_MACROS (1 << 2)
-#define DEBUG_CONTEXTS (1 << 3)
-
-static char *config = "extensions.ael";
-static char *registrar = "pbx_ael";
-static int pbx_load_module(void);
-
-static int errs, warns;
-static int notes;
-
-#ifndef AAL_ARGCHECK
-/* for the time being, short circuit all the AAL related structures
- without permanently removing the code; after/during the AAL
- development, this code can be properly re-instated
-*/
-
-/* null definitions for structs passed down the infrastructure */
-struct argapp
-{
- struct argapp *next;
-};
-
-#endif
-
-#ifdef AAL_ARGCHECK
-int option_matches_j( struct argdesc *should, pval *is, struct argapp *app);
-int option_matches( struct argdesc *should, pval *is, struct argapp *app);
-int ael_is_funcname(char *name);
-#endif
-
-int check_app_args(pval *appcall, pval *arglist, struct argapp *app);
-void check_pval(pval *item, struct argapp *apps, int in_globals);
-void check_pval_item(pval *item, struct argapp *apps, int in_globals);
-void check_switch_expr(pval *item, struct argapp *apps);
-void ast_expr_register_extra_error_info(char *errmsg);
-void ast_expr_clear_extra_error_info(void);
-int ast_expr(char *expr, char *buf, int length);
-struct pval *find_macro(char *name);
-struct pval *find_context(char *name);
-struct pval *find_context(char *name);
-struct pval *find_macro(char *name);
-struct ael_priority *new_prio(void);
-struct ael_extension *new_exten(void);
-void linkprio(struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten);
-void destroy_extensions(struct ael_extension *exten);
-static void linkexten(struct ael_extension *exten, struct ael_extension *add);
-static void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *context );
-void set_priorities(struct ael_extension *exten);
-void add_extensions(struct ael_extension *exten);
-void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root);
-void destroy_pval(pval *item);
-void destroy_pval_item(pval *item);
-int is_float(char *arg );
-int is_int(char *arg );
-int is_empty(char *arg);
-static pval *current_db=0;
-static pval *current_context=0;
-static pval *current_extension=0;
-
-static const char *match_context;
-static const char *match_exten;
-static const char *match_label;
-static int in_abstract_context;
-static int count_labels; /* true, put matcher in label counting mode */
-static int label_count; /* labels are only meant to be counted in a context or exten */
-static int return_on_context_match;
-static pval *last_matched_label;
-struct pval *match_pval(pval *item);
-static void check_timerange(pval *p);
-static void check_dow(pval *DOW);
-static void check_day(pval *DAY);
-static void check_month(pval *MON);
-static void check_expr2_input(pval *expr, char *str);
-static int extension_matches(pval *here, const char *exten, const char *pattern);
-static void check_goto(pval *item);
-static void find_pval_goto_item(pval *item, int lev);
-static void find_pval_gotos(pval *item, int lev);
-
-static struct pval *find_label_in_current_context(char *exten, char *label, pval *curr_cont);
-static struct pval *find_first_label_in_current_context(char *label, pval *curr_cont);
-static void print_pval_list(FILE *fin, pval *item, int depth);
-
-static struct pval *find_label_in_current_extension(const char *label, pval *curr_ext);
-static struct pval *find_label_in_current_db(const char *context, const char *exten, const char *label);
-static pval *get_goto_target(pval *item);
-static int label_inside_case(pval *label);
-static void attach_exten(struct ael_extension **list, struct ael_extension *newmem);
-static void fix_gotos_in_extensions(struct ael_extension *exten);
-static pval *get_extension_or_contxt(pval *p);
-static pval *get_contxt(pval *p);
-static void remove_spaces_before_equals(char *str);
-static void substitute_commas(char *str);
-
-/* I am adding this code to substitute commas with vertbars in the args to apps */
-static void substitute_commas(char *str)
-{
- char *p = str;
-
- while (p && *p)
- {
- if (*p == ',' && ((p != str && *(p-1) != '\\')
- || p == str))
- *p = '|';
- if (*p == '\\' && *(p+1) == ',') { /* learning experience: the '\,' is turned into just ',' by pbx_config; So we need to do the same */
- char *q = p;
- while (*q) { /* move the ',' and everything after it up 1 char */
- *q = *(q+1);
- q++;
- }
- }
- p++;
- }
-}
-
-
-/* PRETTY PRINTER FOR AEL: ============================================================================= */
-
-static void print_pval(FILE *fin, pval *item, int depth)
-{
- int i;
- pval *lp;
-
- for (i=0; i<depth; i++) {
- fprintf(fin, "\t"); /* depth == indentation */
- }
-
- switch ( item->type ) {
- case PV_WORD:
- fprintf(fin,"%s;\n", item->u1.str); /* usually, words are encapsulated in something else */
- break;
-
- case PV_MACRO:
- fprintf(fin,"macro %s(", item->u1.str);
- for (lp=item->u2.arglist; lp; lp=lp->next) {
- if (lp != item->u2.arglist )
- fprintf(fin,", ");
- fprintf(fin,"%s", lp->u1.str);
- }
- fprintf(fin,") {\n");
- print_pval_list(fin,item->u3.macro_statements,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n\n");
- break;
-
- case PV_CONTEXT:
- if ( item->u3.abstract )
- fprintf(fin,"abstract context %s {\n", item->u1.str);
- else
- fprintf(fin,"context %s {\n", item->u1.str);
- print_pval_list(fin,item->u2.statements,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n\n");
- break;
-
- case PV_MACRO_CALL:
- fprintf(fin,"&%s(", item->u1.str);
- for (lp=item->u2.arglist; lp; lp=lp->next) {
- if ( lp != item->u2.arglist )
- fprintf(fin,", ");
- fprintf(fin,"%s", lp->u1.str);
- }
- fprintf(fin,");\n");
- break;
-
- case PV_APPLICATION_CALL:
- fprintf(fin,"%s(", item->u1.str);
- for (lp=item->u2.arglist; lp; lp=lp->next) {
- if ( lp != item->u2.arglist )
- fprintf(fin,",");
- fprintf(fin,"%s", lp->u1.str);
- }
- fprintf(fin,");\n");
- break;
-
- case PV_CASE:
- fprintf(fin,"case %s:\n", item->u1.str);
- print_pval_list(fin,item->u2.statements, depth+1);
- break;
-
- case PV_PATTERN:
- fprintf(fin,"pattern %s:\n", item->u1.str);
- print_pval_list(fin,item->u2.statements, depth+1);
- break;
-
- case PV_DEFAULT:
- fprintf(fin,"default:\n");
- print_pval_list(fin,item->u2.statements, depth+1);
- break;
-
- case PV_CATCH:
- fprintf(fin,"catch %s {\n", item->u1.str);
- print_pval_list(fin,item->u2.statements, depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n");
- break;
-
- case PV_SWITCHES:
- fprintf(fin,"switches {\n");
- print_pval_list(fin,item->u1.list,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n");
- break;
-
- case PV_ESWITCHES:
- fprintf(fin,"eswitches {\n");
- print_pval_list(fin,item->u1.list,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n");
- break;
-
- case PV_INCLUDES:
- fprintf(fin,"includes {\n");
- for (lp=item->u1.list; lp; lp=lp->next) {
- for (i=0; i<depth+1; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"%s", lp->u1.str); /* usually, words are encapsulated in something else */
- if ( lp->u2.arglist )
- fprintf(fin,"|%s|%s|%s|%s",
- lp->u2.arglist->u1.str,
- lp->u2.arglist->next->u1.str,
- lp->u2.arglist->next->next->u1.str,
- lp->u2.arglist->next->next->next->u1.str
- );
- fprintf(fin,";\n"); /* usually, words are encapsulated in something else */
- }
-
- print_pval_list(fin,item->u1.list,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n");
- break;
-
- case PV_STATEMENTBLOCK:
- fprintf(fin,"{\n");
- print_pval_list(fin,item->u1.list, depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"};\n");
- break;
-
- case PV_VARDEC:
- fprintf(fin,"%s=%s;\n", item->u1.str, item->u2.val);
- break;
-
- case PV_GOTO:
- fprintf(fin,"goto %s", item->u1.list->u1.str);
- if ( item->u1.list->next )
- fprintf(fin,"|%s", item->u1.list->next->u1.str);
- if ( item->u1.list->next && item->u1.list->next->next )
- fprintf(fin,"|%s", item->u1.list->next->next->u1.str);
- fprintf(fin,"\n");
- break;
-
- case PV_LABEL:
- fprintf(fin,"%s:\n", item->u1.str);
- break;
-
- case PV_FOR:
- fprintf(fin,"for (%s; %s; %s)\n", item->u1.for_init, item->u2.for_test, item->u3.for_inc);
- print_pval_list(fin,item->u4.for_statements,depth+1);
- break;
-
- case PV_WHILE:
- fprintf(fin,"while (%s)\n", item->u1.str);
- print_pval_list(fin,item->u2.statements,depth+1);
- break;
-
- case PV_BREAK:
- fprintf(fin,"break;\n");
- break;
-
- case PV_RETURN:
- fprintf(fin,"return;\n");
- break;
-
- case PV_CONTINUE:
- fprintf(fin,"continue;\n");
- break;
-
- case PV_RANDOM:
- case PV_IFTIME:
- case PV_IF:
- if ( item->type == PV_IFTIME ) {
-
- fprintf(fin,"ifTime ( %s|%s|%s|%s )\n",
- item->u1.list->u1.str,
- item->u1.list->next->u1.str,
- item->u1.list->next->next->u1.str,
- item->u1.list->next->next->next->u1.str
- );
- } else if ( item->type == PV_RANDOM ) {
- fprintf(fin,"random ( %s )\n", item->u1.str );
- } else
- fprintf(fin,"if ( %s )\n", item->u1.str);
- if ( item->u2.statements && item->u2.statements->next ) {
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"{\n");
- print_pval_list(fin,item->u2.statements,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- if ( item->u3.else_statements )
- fprintf(fin,"}\n");
- else
- fprintf(fin,"};\n");
- } else if (item->u2.statements ) {
- print_pval_list(fin,item->u2.statements,depth+1);
- } else {
- if (item->u3.else_statements )
- fprintf(fin, " {} ");
- else
- fprintf(fin, " {}; ");
- }
- if ( item->u3.else_statements ) {
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"else\n");
- print_pval_list(fin,item->u3.else_statements, depth);
- }
- break;
-
- case PV_SWITCH:
- fprintf(fin,"switch( %s ) {\n", item->u1.str);
- print_pval_list(fin,item->u2.statements,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"}\n");
- break;
-
- case PV_EXTENSION:
- if ( item->u4.regexten )
- fprintf(fin, "regexten ");
- if ( item->u3.hints )
- fprintf(fin,"hints(%s) ", item->u3.hints);
-
- fprintf(fin,"%s => \n", item->u1.str);
- print_pval_list(fin,item->u2.statements,depth+1);
- break;
-
- case PV_IGNOREPAT:
- fprintf(fin,"ignorepat => %s\n", item->u1.str);
- break;
-
- case PV_GLOBALS:
- fprintf(fin,"globals {\n");
- print_pval_list(fin,item->u1.statements,depth+1);
- for (i=0; i<depth; i++) {
- fprintf(fin,"\t"); /* depth == indentation */
- }
- fprintf(fin,"}\n");
- break;
- }
-}
-
-static void print_pval_list(FILE *fin, pval *item, int depth)
-{
- pval *i;
-
- for (i=item; i; i=i->next) {
- print_pval(fin, i, depth);
- }
-}
-
-#if 0
-static void ael2_print(char *fname, pval *tree)
-{
- FILE *fin = fopen(fname,"w");
- if ( !fin ) {
- ast_log(LOG_ERROR, "Couldn't open %s for writing.\n", fname);
- return;
- }
- print_pval_list(fin, tree, 0);
- fclose(fin);
-}
-#endif
-
-
-/* EMPTY TEMPLATE FUNCS FOR AEL TRAVERSAL: ============================================================================= */
-
-void traverse_pval_template(pval *item, int depth);
-void traverse_pval_item_template(pval *item, int depth);
-
-
-void traverse_pval_item_template(pval *item, int depth)/* depth comes in handy for a pretty print (indentation),
- but you may not need it */
-{
- pval *lp;
-
- switch ( item->type ) {
- case PV_WORD:
- /* fields: item->u1.str == string associated with this (word). */
- break;
-
- case PV_MACRO:
- /* fields: item->u1.str == name of macro
- item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
-
- item->u3.macro_statements == pval list of statements in macro body.
- */
- for (lp=item->u2.arglist; lp; lp=lp->next) {
-
- }
- traverse_pval_item_template(item->u3.macro_statements,depth+1);
- break;
-
- case PV_CONTEXT:
- /* fields: item->u1.str == name of context
- item->u2.statements == pval list of statements in context body
- item->u3.abstract == int 1 if an abstract keyword were present
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_MACRO_CALL:
- /* fields: item->u1.str == name of macro to call
- item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
- */
- for (lp=item->u2.arglist; lp; lp=lp->next) {
- }
- break;
-
- case PV_APPLICATION_CALL:
- /* fields: item->u1.str == name of application to call
- item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
- */
- for (lp=item->u2.arglist; lp; lp=lp->next) {
- }
- break;
-
- case PV_CASE:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_PATTERN:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_DEFAULT:
- /* fields:
- item->u2.statements == pval list of statements under the case
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_CATCH:
- /* fields: item->u1.str == name of extension to catch
- item->u2.statements == pval list of statements in context body
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_SWITCHES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- traverse_pval_item_template(item->u1.list,depth+1);
- break;
-
- case PV_ESWITCHES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- traverse_pval_item_template(item->u1.list,depth+1);
- break;
-
- case PV_INCLUDES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- item->u2.arglist == pval list of 4 PV_WORD elements for time values
- */
- traverse_pval_item_template(item->u1.list,depth+1);
- traverse_pval_item_template(item->u2.arglist,depth+1);
- break;
-
- case PV_STATEMENTBLOCK:
- /* fields: item->u1.list == pval list of statements in block, one per entry in the list
- */
- traverse_pval_item_template(item->u1.list,depth+1);
- break;
-
- case PV_VARDEC:
- /* fields: item->u1.str == variable name
- item->u2.val == variable value to assign
- */
- break;
-
- case PV_GOTO:
- /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
- item->u1.list->u1.str == where the data on a PV_WORD will always be.
- */
-
- if ( item->u1.list->next )
- ;
- if ( item->u1.list->next && item->u1.list->next->next )
- ;
-
- break;
-
- case PV_LABEL:
- /* fields: item->u1.str == label name
- */
- break;
-
- case PV_FOR:
- /* fields: item->u1.for_init == a string containing the initalizer
- item->u2.for_test == a string containing the loop test
- item->u3.for_inc == a string containing the loop increment
-
- item->u4.for_statements == a pval list of statements in the for ()
- */
- traverse_pval_item_template(item->u4.for_statements,depth+1);
- break;
-
- case PV_WHILE:
- /* fields: item->u1.str == the while conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the while ()
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_BREAK:
- /* fields: none
- */
- break;
-
- case PV_RETURN:
- /* fields: none
- */
- break;
-
- case PV_CONTINUE:
- /* fields: none
- */
- break;
-
- case PV_IFTIME:
- /* fields: item->u1.list == there are 4 linked PV_WORDs here.
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- if ( item->u3.else_statements ) {
- traverse_pval_item_template(item->u3.else_statements,depth+1);
- }
- break;
-
- case PV_RANDOM:
- /* fields: item->u1.str == the random number expression, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- if ( item->u3.else_statements ) {
- traverse_pval_item_template(item->u3.else_statements,depth+1);
- }
- break;
-
- case PV_IF:
- /* fields: item->u1.str == the if conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- if ( item->u3.else_statements ) {
- traverse_pval_item_template(item->u3.else_statements,depth+1);
- }
- break;
-
- case PV_SWITCH:
- /* fields: item->u1.str == the switch expression
-
- item->u2.statements == a pval list of statements in the switch,
- (will be case statements, most likely!)
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_EXTENSION:
- /* fields: item->u1.str == the extension name, label, whatever it's called
-
- item->u2.statements == a pval list of statements in the extension
- item->u3.hints == a char * hint argument
- item->u4.regexten == an int boolean. non-zero says that regexten was specified
- */
- traverse_pval_item_template(item->u2.statements,depth+1);
- break;
-
- case PV_IGNOREPAT:
- /* fields: item->u1.str == the ignorepat data
- */
- break;
-
- case PV_GLOBALS:
- /* fields: item->u1.statements == pval list of statements, usually vardecs
- */
- traverse_pval_item_template(item->u1.statements,depth+1);
- break;
- }
-}
-
-void traverse_pval_template(pval *item, int depth) /* depth comes in handy for a pretty print (indentation),
- but you may not need it */
-{
- pval *i;
-
- for (i=item; i; i=i->next) {
- traverse_pval_item_template(i, depth);
- }
-}
-
-
-/* SEMANTIC CHECKING FOR AEL: ============================================================================= */
-
-/* (not all that is syntactically legal is good! */
-
-
-
-static int extension_matches(pval *here, const char *exten, const char *pattern)
-{
- int err1;
- regex_t preg;
-
- /* simple case, they match exactly, the pattern and exten name */
- if( !strcmp(pattern,exten) == 0 )
- return 1;
-
- if ( pattern[0] == '_' ) {
- char reg1[2000];
- const char *p;
- char *r = reg1;
-
- if ( strlen(pattern)*5 >= 2000 ) /* safety valve */ {
- ast_log(LOG_ERROR,"Error: The pattern %s is way too big. Pattern matching cancelled.\n",
- pattern);
- return 0;
- }
- /* form a regular expression from the pattern, and then match it against exten */
- *r++ = '^'; /* what if the extension is a pattern ?? */
- *r++ = '_'; /* what if the extension is a pattern ?? */
- *r++ = '?';
- for (p=pattern+1; *p; p++) {
- switch ( *p ) {
- case 'X':
- *r++ = '[';
- *r++ = '0';
- *r++ = '-';
- *r++ = '9';
- *r++ = 'X';
- *r++ = ']';
- break;
-
- case 'Z':
- *r++ = '[';
- *r++ = '1';
- *r++ = '-';
- *r++ = '9';
- *r++ = 'Z';
- *r++ = ']';
- break;
-
- case 'N':
- *r++ = '[';
- *r++ = '2';
- *r++ = '-';
- *r++ = '9';
- *r++ = 'N';
- *r++ = ']';
- break;
-
- case '[':
- while ( *p && *p != ']' ) {
- *r++ = *p++;
- }
- if ( *p != ']') {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n",
- here->filename, here->startline, here->endline, pattern);
- }
- break;
-
- case '.':
- case '!':
- *r++ = '.';
- *r++ = '*';
- break;
- case '*':
- *r++ = '\\';
- *r++ = '*';
- break;
- default:
- *r++ = *p;
- break;
-
- }
- }
- *r++ = '$'; /* what if the extension is a pattern ?? */
- *r++ = *p++; /* put in the closing null */
- err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED);
- if ( err1 ) {
- char errmess[500];
- regerror(err1,&preg,errmess,sizeof(errmess));
- regfree(&preg);
- ast_log(LOG_WARNING, "Regcomp of %s failed, error code %d\n",
- reg1, err1);
- return 0;
- }
- err1 = regexec(&preg, exten, 0, 0, 0);
- regfree(&preg);
-
- if ( err1 ) {
- /* ast_log(LOG_NOTICE,"*****************************[%d]Extension %s did not match %s(%s)\n",
- err1,exten, pattern, reg1); */
- return 0; /* no match */
- } else {
- /* ast_log(LOG_NOTICE,"*****************************Extension %s matched %s\n",
- exten, pattern); */
- return 1;
- }
-
-
- } else {
- if ( strcmp(exten,pattern) == 0 ) {
- return 1;
- } else
- return 0;
- }
-}
-
-
-static void check_expr2_input(pval *expr, char *str)
-{
- int spaces = strspn(str,"\t \n");
- if ( !strncmp(str+spaces,"$[",2) ) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
- expr->filename, expr->startline, expr->endline, str);
- warns++;
- }
-}
-
-static void check_includes(pval *includes)
-{
- struct pval *p4;
- for (p4=includes->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- char *incl_context = p4->u1.str;
- /* find a matching context name */
- struct pval *that_other_context = find_context(incl_context);
- if (!that_other_context && strcmp(incl_context, "parkedcalls") != 0) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\
- (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n",
- includes->filename, includes->startline, includes->endline, incl_context, incl_context);
- warns++;
- }
- }
-}
-
-
-static void check_timerange(pval *p)
-{
- char *times;
- char *e;
- int s1, s2;
- int e1, e2;
-
- times = ast_strdupa(p->u1.str);
-
- /* Star is all times */
- if (ast_strlen_zero(times) || !strcmp(times, "*")) {
- return;
- }
- /* Otherwise expect a range */
- e = strchr(times, '-');
- if (!e) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) requires a '-' surrounded by two 24-hour times of day!\n",
- p->filename, p->startline, p->endline, times);
- warns++;
- return;
- }
- *e = '\0';
- e++;
- while (*e && !isdigit(*e))
- e++;
- if (!*e) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n",
- p->filename, p->startline, p->endline, p->u1.str);
- warns++;
- }
- if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n",
- p->filename, p->startline, p->endline, times);
- warns++;
- }
- if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n",
- p->filename, p->startline, p->endline, times);
- warns++;
- }
-
- s1 = s1 * 30 + s2/2;
- if ((s1 < 0) || (s1 >= 24*30)) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n",
- p->filename, p->startline, p->endline, times);
- warns++;
- }
- e1 = e1 * 30 + e2/2;
- if ((e1 < 0) || (e1 >= 24*30)) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n",
- p->filename, p->startline, p->endline, e);
- warns++;
- }
- return;
-}
-
-static char *days[] =
-{
- "sun",
- "mon",
- "tue",
- "wed",
- "thu",
- "fri",
- "sat",
-};
-
-/*! \brief get_dow: Get day of week */
-static void check_dow(pval *DOW)
-{
- char *dow;
- char *c;
- /* The following line is coincidence, really! */
- int s, e;
-
- dow = ast_strdupa(DOW->u1.str);
-
- /* Check for all days */
- if (ast_strlen_zero(dow) || !strcmp(dow, "*"))
- return;
- /* Get start and ending days */
- c = strchr(dow, '-');
- if (c) {
- *c = '\0';
- c++;
- } else
- c = NULL;
- /* Find the start */
- s = 0;
- while ((s < 7) && strcasecmp(dow, days[s])) s++;
- if (s >= 7) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The day (%s) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!\n",
- DOW->filename, DOW->startline, DOW->endline, dow);
- warns++;
- }
- if (c) {
- e = 0;
- while ((e < 7) && strcasecmp(c, days[e])) e++;
- if (e >= 7) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day (%s) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!\n",
- DOW->filename, DOW->startline, DOW->endline, c);
- warns++;
- }
- } else
- e = s;
-}
-
-static void check_day(pval *DAY)
-{
- char *day;
- char *c;
- /* The following line is coincidence, really! */
- int s, e;
-
- day = ast_strdupa(DAY->u1.str);
-
- /* Check for all days */
- if (ast_strlen_zero(day) || !strcmp(day, "*")) {
- return;
- }
- /* Get start and ending days */
- c = strchr(day, '-');
- if (c) {
- *c = '\0';
- c++;
- }
- /* Find the start */
- if (sscanf(day, "%d", &s) != 1) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n",
- DAY->filename, DAY->startline, DAY->endline, day);
- warns++;
- }
- else if ((s < 1) || (s > 31)) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number in the range [1-31]!\n",
- DAY->filename, DAY->startline, DAY->endline, day);
- warns++;
- }
- s--;
- if (c) {
- if (sscanf(c, "%d", &e) != 1) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n",
- DAY->filename, DAY->startline, DAY->endline, c);
- warns++;
- }
- else if ((e < 1) || (e > 31)) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number in the range [1-31]!\n",
- DAY->filename, DAY->startline, DAY->endline, day);
- warns++;
- }
- e--;
- } else
- e = s;
-}
-
-static char *months[] =
-{
- "jan",
- "feb",
- "mar",
- "apr",
- "may",
- "jun",
- "jul",
- "aug",
- "sep",
- "oct",
- "nov",
- "dec",
-};
-
-static void check_month(pval *MON)
-{
- char *mon;
- char *c;
- /* The following line is coincidence, really! */
- int s, e;
-
- mon = ast_strdupa(MON->u1.str);
-
- /* Check for all days */
- if (ast_strlen_zero(mon) || !strcmp(mon, "*"))
- return ;
- /* Get start and ending days */
- c = strchr(mon, '-');
- if (c) {
- *c = '\0';
- c++;
- }
- /* Find the start */
- s = 0;
- while ((s < 12) && strcasecmp(mon, months[s])) s++;
- if (s >= 12) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
- MON->filename, MON->startline, MON->endline, mon);
- warns++;
- }
- if (c) {
- e = 0;
- while ((e < 12) && strcasecmp(mon, months[e])) e++;
- if (e >= 12) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
- MON->filename, MON->startline, MON->endline, c);
- warns++;
- }
- } else
- e = s;
-}
-
-static int check_break(pval *item)
-{
- pval *p = item;
-
- while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
- /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make
- no sense */
- if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN
- || p->type == PV_WHILE || p->type == PV_FOR ) {
- return 1;
- }
- p = p->dad;
- }
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n",
- item->filename, item->startline, item->endline);
- errs++;
-
- return 0;
-}
-
-static int check_continue(pval *item)
-{
- pval *p = item;
-
- while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
- /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make
- no sense */
- if( p->type == PV_WHILE || p->type == PV_FOR ) {
- return 1;
- }
- p = p->dad;
- }
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n",
- item->filename, item->startline, item->endline);
- errs++;
-
- return 0;
-}
-
-
-/* general purpose goto finder */
-
-static void check_label(pval *item)
-{
- /* basically, ensure that a label is not repeated in a context. Period.
- The method: well, for each label, find the first label in the context
- with the same name. If it's not the current label, then throw an error. */
- struct pval *curr;
- struct pval *x;
-
- /* printf("==== check_label: ====\n"); */
- if( !current_extension )
- curr = current_context;
- else
- curr = current_extension;
-
- x = find_first_label_in_current_context((char *)item->u1.str, curr);
- /* printf("Hey, check_label found with item = %x, and x is %x, and currcont is %x, label name is %s\n", item,x, current_context, (char *)item->u1.str); */
- if( x && x != item )
- {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n",
- item->filename, item->startline, item->endline, item->u1.str, x->filename, x->startline);
- errs++;
- }
- /* printf("<<<<< check_label: ====\n"); */
-}
-
-static pval *get_goto_target(pval *item)
-{
- /* just one item-- the label should be in the current extension */
- pval *curr_ext = get_extension_or_contxt(item); /* containing exten, or macro */
- pval *curr_cont;
-
- if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) {
- struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), curr_ext);
- return x;
- }
-
- curr_cont = get_contxt(item);
-
- /* TWO items */
- if (item->u1.list->next && !item->u1.list->next->next) {
- if (!strstr((item->u1.list)->u1.str,"${")
- && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ {
- struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, curr_cont);
- return x;
- }
- }
-
- /* All 3 items! */
- if (item->u1.list->next && item->u1.list->next->next) {
- /* all three */
- pval *first = item->u1.list;
- pval *second = item->u1.list->next;
- pval *third = item->u1.list->next->next;
-
- if (!strstr((item->u1.list)->u1.str,"${")
- && !strstr(item->u1.list->next->u1.str,"${")
- && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ {
- struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str);
- if (!x) {
-
- struct pval *p3;
- struct pval *that_context = find_context(item->u1.list->u1.str);
-
- /* the target of the goto could be in an included context!! Fancy that!! */
- /* look for includes in the current context */
- if (that_context) {
- for (p3=that_context->u2.statements; p3; p3=p3->next) {
- if (p3->type == PV_INCLUDES) {
- struct pval *p4;
- for (p4=p3->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- char *incl_context = p4->u1.str;
- /* find a matching context name */
- struct pval *that_other_context = find_context(incl_context);
- if (that_other_context) {
- struct pval *x3;
- x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context);
- if (x3) {
- return x3;
- }
- }
- }
- }
- }
- }
- }
- return x;
- }
- }
- return 0;
-}
-
-static void check_goto(pval *item)
-{
- /* check for the target of the goto-- does it exist? */
- if ( !(item->u1.list)->next && !(item->u1.list)->u1.str ) {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: empty label reference found!\n",
- item->filename, item->startline, item->endline);
- errs++;
- }
-
- /* just one item-- the label should be in the current extension */
-
- if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) {
- struct pval *z = get_extension_or_contxt(item);
- struct pval *x = 0;
- if (z)
- x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), z); /* if in macro, use current context instead */
- /* printf("Called find_label_in_current_extension with arg %s; current_extension is %x: %d\n",
- (char*)((item->u1.list)->u1.str), current_extension?current_extension:current_context, current_extension?current_extension->type:current_context->type); */
- if (!x) {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n",
- item->filename, item->startline, item->endline, item->u1.list->u1.str);
- errs++;
- }
- else
- return;
- }
-
- /* TWO items */
- if (item->u1.list->next && !item->u1.list->next->next) {
- /* two items */
- /* printf("Calling find_label_in_current_context with args %s, %s\n",
- (char*)((item->u1.list)->u1.str), (char *)item->u1.list->next->u1.str); */
- if (!strstr((item->u1.list)->u1.str,"${")
- && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ {
- struct pval *z = get_contxt(item);
- struct pval *x = 0;
-
- if (z)
- x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, z);
-
- if (!x) {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s|%s exists in the current context, or any of its inclusions!\n",
- item->filename, item->startline, item->endline, item->u1.list->u1.str, item->u1.list->next->u1.str );
- errs++;
- }
- else
- return;
- }
- }
-
- /* All 3 items! */
- if (item->u1.list->next && item->u1.list->next->next) {
- /* all three */
- pval *first = item->u1.list;
- pval *second = item->u1.list->next;
- pval *third = item->u1.list->next->next;
-
- /* printf("Calling find_label_in_current_db with args %s, %s, %s\n",
- (char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); */
- if (!strstr((item->u1.list)->u1.str,"${")
- && !strstr(item->u1.list->next->u1.str,"${")
- && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ {
- struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str);
- if (!x) {
- struct pval *p3;
- struct pval *found = 0;
- struct pval *that_context = find_context(item->u1.list->u1.str);
-
- /* the target of the goto could be in an included context!! Fancy that!! */
- /* look for includes in the current context */
- if (that_context) {
- for (p3=that_context->u2.statements; p3; p3=p3->next) {
- if (p3->type == PV_INCLUDES) {
- struct pval *p4;
- for (p4=p3->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- char *incl_context = p4->u1.str;
- /* find a matching context name */
- struct pval *that_other_context = find_context(incl_context);
- if (that_other_context) {
- struct pval *x3;
- x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context);
- if (x3) {
- found = x3;
- break;
- }
- }
- }
- }
- }
- if (!found) {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s|%s exists in the context %s or its inclusions!\n",
- item->filename, item->startline, item->endline, item->u1.list->next->u1.str, item->u1.list->next->next->u1.str, item->u1.list->u1.str );
- errs++;
- }
- } else {
- /* here is where code would go to check for target existence in extensions.conf files */
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: goto: no context %s could be found that matches the goto target!\n",
- item->filename, item->startline, item->endline, item->u1.list->u1.str);
- warns++; /* this is just a warning, because this context could be in extensions.conf or somewhere */
- }
- }
- }
- }
-}
-
-
-static void find_pval_goto_item(pval *item, int lev)
-{
- struct pval *p4;
- if (lev>100) {
- ast_log(LOG_ERROR,"find_pval_goto in infinite loop!\n\n");
- return;
- }
-
- switch ( item->type ) {
- case PV_MACRO:
- /* fields: item->u1.str == name of macro
- item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
-
- item->u3.macro_statements == pval list of statements in macro body.
- */
-
- /* printf("Descending into matching macro %s\n", match_context); */
- find_pval_gotos(item->u3.macro_statements,lev+1); /* if we're just searching for a context, don't bother descending into them */
-
- break;
-
- case PV_CONTEXT:
- /* fields: item->u1.str == name of context
- item->u2.statements == pval list of statements in context body
- item->u3.abstract == int 1 if an abstract keyword were present
- */
- break;
-
- case PV_CASE:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- find_pval_gotos(item->u2.statements,lev+1);
- break;
-
- case PV_PATTERN:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- find_pval_gotos(item->u2.statements,lev+1);
- break;
-
- case PV_DEFAULT:
- /* fields:
- item->u2.statements == pval list of statements under the case
- */
- find_pval_gotos(item->u2.statements,lev+1);
- break;
-
- case PV_CATCH:
- /* fields: item->u1.str == name of extension to catch
- item->u2.statements == pval list of statements in context body
- */
- find_pval_gotos(item->u2.statements,lev+1);
- break;
-
- case PV_STATEMENTBLOCK:
- /* fields: item->u1.list == pval list of statements in block, one per entry in the list
- */
- find_pval_gotos(item->u1.list,lev+1);
- break;
-
- case PV_GOTO:
- /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
- item->u1.list->u1.str == where the data on a PV_WORD will always be.
- */
- check_goto(item); /* THE WHOLE FUNCTION OF THIS ENTIRE ROUTINE!!!! */
- break;
-
- case PV_INCLUDES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- for (p4=item->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- char *incl_context = p4->u1.str;
- /* find a matching context name */
- struct pval *that_context = find_context(incl_context);
- if (that_context) {
- find_pval_gotos(that_context,lev+1); /* keep working up the includes */
- }
- }
- break;
-
- case PV_FOR:
- /* fields: item->u1.for_init == a string containing the initalizer
- item->u2.for_test == a string containing the loop test
- item->u3.for_inc == a string containing the loop increment
-
- item->u4.for_statements == a pval list of statements in the for ()
- */
- find_pval_gotos(item->u4.for_statements,lev+1);
- break;
-
- case PV_WHILE:
- /* fields: item->u1.str == the while conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the while ()
- */
- find_pval_gotos(item->u2.statements,lev+1);
- break;
-
- case PV_RANDOM:
- /* fields: item->u1.str == the random number expression, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- fall thru to PV_IF */
-
- case PV_IFTIME:
- /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- fall thru to PV_IF*/
- case PV_IF:
- /* fields: item->u1.str == the if conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- find_pval_gotos(item->u2.statements,lev+1);
-
- if (item->u3.else_statements) {
- find_pval_gotos(item->u3.else_statements,lev+1);
- }
- break;
-
- case PV_SWITCH:
- /* fields: item->u1.str == the switch expression
-
- item->u2.statements == a pval list of statements in the switch,
- (will be case statements, most likely!)
- */
- find_pval_gotos(item->u3.else_statements,lev+1);
- break;
-
- case PV_EXTENSION:
- /* fields: item->u1.str == the extension name, label, whatever it's called
-
- item->u2.statements == a pval list of statements in the extension
- item->u3.hints == a char * hint argument
- item->u4.regexten == an int boolean. non-zero says that regexten was specified
- */
-
- find_pval_gotos(item->u2.statements,lev+1);
- break;
-
- default:
- break;
- }
-}
-
-static void find_pval_gotos(pval *item,int lev)
-{
- pval *i;
-
- for (i=item; i; i=i->next) {
-
- find_pval_goto_item(i, lev);
- }
-}
-
-
-
-/* general purpose label finder */
-static struct pval *match_pval_item(pval *item)
-{
- pval *x;
-
- switch ( item->type ) {
- case PV_MACRO:
- /* fields: item->u1.str == name of macro
- item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
-
- item->u3.macro_statements == pval list of statements in macro body.
- */
- /* printf(" matching in MACRO %s, match_context=%s; retoncontmtch=%d; \n", item->u1.str, match_context, return_on_context_match); */
- if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) {
-
- /* printf("MACRO: match context is: %s\n", match_context); */
-
- if (return_on_context_match && !strcmp(item->u1.str, match_context)) /* if we're just searching for a context, don't bother descending into them */ {
- /* printf("Returning on matching macro %s\n", match_context); */
- return item;
- }
-
-
- if (!return_on_context_match) {
- /* printf("Descending into matching macro %s/%s\n", match_context, item->u1.str); */
- if ((x=match_pval(item->u3.macro_statements))) {
- /* printf("Responded with pval match %x\n", x); */
- return x;
- }
- }
- } else {
- /* printf("Skipping context/macro %s\n", item->u1.str); */
- }
-
- break;
-
- case PV_CONTEXT:
- /* fields: item->u1.str == name of context
- item->u2.statements == pval list of statements in context body
- item->u3.abstract == int 1 if an abstract keyword were present
- */
- /* printf(" matching in CONTEXT\n"); */
- if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) {
- if (return_on_context_match && !strcmp(item->u1.str, match_context)) {
- /* printf("Returning on matching context %s\n", match_context); */
- /* printf("non-CONTEXT: Responded with pval match %x\n", x); */
- return item;
- }
-
- if (!return_on_context_match ) {
- /* printf("Descending into matching context %s\n", match_context); */
- if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ {
- /* printf("CONTEXT: Responded with pval match %x\n", x); */
- return x;
- }
- }
- } else {
- /* printf("Skipping context/macro %s\n", item->u1.str); */
- }
- break;
-
- case PV_CASE:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- /* printf(" matching in CASE\n"); */
- if ((x=match_pval(item->u2.statements))) {
- /* printf("CASE: Responded with pval match %x\n", x); */
- return x;
- }
- break;
-
- case PV_PATTERN:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- /* printf(" matching in PATTERN\n"); */
- if ((x=match_pval(item->u2.statements))) {
- /* printf("PATTERN: Responded with pval match %x\n", x); */
- return x;
- }
- break;
-
- case PV_DEFAULT:
- /* fields:
- item->u2.statements == pval list of statements under the case
- */
- /* printf(" matching in DEFAULT\n"); */
- if ((x=match_pval(item->u2.statements))) {
- /* printf("DEFAULT: Responded with pval match %x\n", x); */
- return x;
- }
- break;
-
- case PV_CATCH:
- /* fields: item->u1.str == name of extension to catch
- item->u2.statements == pval list of statements in context body
- */
- /* printf(" matching in CATCH\n"); */
- if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) {
- /* printf("Descending into matching catch %s => %s\n", match_exten, item->u1.str); */
- if (strcmp(match_label,"1") == 0) {
- if (item->u2.statements) {
- struct pval *p5 = item->u2.statements;
- while (p5 && p5->type == PV_LABEL) /* find the first non-label statement in this context. If it exists, there's a "1" */
- p5 = p5->next;
- if (p5)
- return p5;
- else
- return 0;
- }
- else
- return 0;
- }
-
- if ((x=match_pval(item->u2.statements))) {
- /* printf("CATCH: Responded with pval match %x\n", (unsigned int)x); */
- return x;
- }
- } else {
- /* printf("Skipping catch %s\n", item->u1.str); */
- }
- break;
-
- case PV_STATEMENTBLOCK:
- /* fields: item->u1.list == pval list of statements in block, one per entry in the list
- */
- /* printf(" matching in STATEMENTBLOCK\n"); */
- if ((x=match_pval(item->u1.list))) {
- /* printf("STATEMENTBLOCK: Responded with pval match %x\n", x); */
- return x;
- }
- break;
-
- case PV_LABEL:
- /* fields: item->u1.str == label name
- */
- /* printf("PV_LABEL %s (cont=%s, exten=%s\n",
- item->u1.str, current_context->u1.str, (current_extension?current_extension->u1.str:"<macro>"));*/
-
- if (count_labels) {
- if (!strcmp(match_label, item->u1.str)) {
- label_count++;
- last_matched_label = item;
- }
-
- } else {
- if (!strcmp(match_label, item->u1.str)) {
- /* printf("LABEL: Responded with pval match %x\n", x); */
- return item;
- }
- }
- break;
-
- case PV_FOR:
- /* fields: item->u1.for_init == a string containing the initalizer
- item->u2.for_test == a string containing the loop test
- item->u3.for_inc == a string containing the loop increment
-
- item->u4.for_statements == a pval list of statements in the for ()
- */
- /* printf(" matching in FOR\n"); */
- if ((x=match_pval(item->u4.for_statements))) {
- /* printf("FOR: Responded with pval match %x\n", x);*/
- return x;
- }
- break;
-
- case PV_WHILE:
- /* fields: item->u1.str == the while conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the while ()
- */
- /* printf(" matching in WHILE\n"); */
- if ((x=match_pval(item->u2.statements))) {
- /* printf("WHILE: Responded with pval match %x\n", x); */
- return x;
- }
- break;
-
- case PV_RANDOM:
- /* fields: item->u1.str == the random number expression, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- fall thru to PV_IF */
-
- case PV_IFTIME:
- /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- fall thru to PV_IF*/
- case PV_IF:
- /* fields: item->u1.str == the if conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- /* printf(" matching in IF/IFTIME/RANDOM\n"); */
- if ((x=match_pval(item->u2.statements))) {
- return x;
- }
- if (item->u3.else_statements) {
- if ((x=match_pval(item->u3.else_statements))) {
- /* printf("IF/IFTIME/RANDOM: Responded with pval match %x\n", x); */
- return x;
- }
- }
- break;
-
- case PV_SWITCH:
- /* fields: item->u1.str == the switch expression
-
- item->u2.statements == a pval list of statements in the switch,
- (will be case statements, most likely!)
- */
- /* printf(" matching in SWITCH\n"); */
- if ((x=match_pval(item->u2.statements))) {
- /* printf("SWITCH: Responded with pval match %x\n", x); */
- return x;
- }
- break;
-
- case PV_EXTENSION:
- /* fields: item->u1.str == the extension name, label, whatever it's called
-
- item->u2.statements == a pval list of statements in the extension
- item->u3.hints == a char * hint argument
- item->u4.regexten == an int boolean. non-zero says that regexten was specified
- */
- /* printf(" matching in EXTENSION\n"); */
- if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) {
- /* printf("Descending into matching exten %s => %s\n", match_exten, item->u1.str); */
- if (strcmp(match_label,"1") == 0) {
- if (item->u2.statements) {
- struct pval *p5 = item->u2.statements;
- while (p5 && p5->type == PV_LABEL) /* find the first non-label statement in this context. If it exists, there's a "1" */
- p5 = p5->next;
- if (p5)
- return p5;
- else
- return 0;
- }
- else
- return 0;
- }
-
- if ((x=match_pval(item->u2.statements))) {
- /* printf("EXTENSION: Responded with pval match %x\n", x); */
- return x;
- }
- } else {
- /* printf("Skipping exten %s\n", item->u1.str); */
- }
- break;
- default:
- /* printf(" matching in default = %d\n", item->type); */
- break;
- }
- return 0;
-}
-
-struct pval *match_pval(pval *item)
-{
- pval *i;
-
- for (i=item; i; i=i->next) {
- pval *x;
- /* printf(" -- match pval: item %d\n", i->type); */
-
- if ((x = match_pval_item(i))) {
- /* printf("match_pval: returning x=%x\n", (int)x); */
- return x; /* cut the search short */
- }
- }
- return 0;
-}
-
-#if 0
-int count_labels_in_current_context(char *label)
-{
- label_count = 0;
- count_labels = 1;
- return_on_context_match = 0;
- match_pval(current_context->u2.statements);
-
- return label_count;
-}
-#endif
-
-struct pval *find_first_label_in_current_context(char *label, pval *curr_cont)
-{
- /* printf(" --- Got args %s, %s\n", exten, label); */
- struct pval *ret;
- struct pval *p3;
- struct pval *startpt = ((curr_cont->type==PV_MACRO)?curr_cont->u3.macro_statements: curr_cont->u2.statements);
-
- count_labels = 0;
- return_on_context_match = 0;
- match_context = "*";
- match_exten = "*";
- match_label = label;
-
- ret = match_pval(curr_cont);
- if (ret)
- return ret;
-
- /* the target of the goto could be in an included context!! Fancy that!! */
- /* look for includes in the current context */
- for (p3=startpt; p3; p3=p3->next) {
- if (p3->type == PV_INCLUDES) {
- struct pval *p4;
- for (p4=p3->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- char *incl_context = p4->u1.str;
- /* find a matching context name */
- struct pval *that_context = find_context(incl_context);
- if (that_context) {
- struct pval *x3;
- x3 = find_first_label_in_current_context(label, that_context);
- if (x3) {
- return x3;
- }
- }
- }
- }
- }
- return 0;
-}
-
-struct pval *find_label_in_current_context(char *exten, char *label, pval *curr_cont)
-{
- /* printf(" --- Got args %s, %s\n", exten, label); */
- struct pval *ret;
- struct pval *p3;
- struct pval *startpt;
-
- count_labels = 0;
- return_on_context_match = 0;
- match_context = "*";
- match_exten = exten;
- match_label = label;
- if (curr_cont->type == PV_MACRO)
- startpt = curr_cont->u3.macro_statements;
- else
- startpt = curr_cont->u2.statements;
-
- ret = match_pval(startpt);
- if (ret)
- return ret;
-
- /* the target of the goto could be in an included context!! Fancy that!! */
- /* look for includes in the current context */
- for (p3=startpt; p3; p3=p3->next) {
- if (p3->type == PV_INCLUDES) {
- struct pval *p4;
- for (p4=p3->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- char *incl_context = p4->u1.str;
- /* find a matching context name */
- struct pval *that_context = find_context(incl_context);
- if (that_context) {
- struct pval *x3;
- x3 = find_label_in_current_context(exten, label, that_context);
- if (x3) {
- return x3;
- }
- }
- }
- }
- }
- return 0;
-}
-
-static struct pval *find_label_in_current_extension(const char *label, pval *curr_ext)
-{
- /* printf(" --- Got args %s\n", label); */
- count_labels = 0;
- return_on_context_match = 0;
- match_context = "*";
- match_exten = "*";
- match_label = label;
- return match_pval(curr_ext);
-}
-
-static struct pval *find_label_in_current_db(const char *context, const char *exten, const char *label)
-{
- /* printf(" --- Got args %s, %s, %s\n", context, exten, label); */
- count_labels = 0;
- return_on_context_match = 0;
-
- match_context = context;
- match_exten = exten;
- match_label = label;
-
- return match_pval(current_db);
-}
-
-
-struct pval *find_macro(char *name)
-{
- return_on_context_match = 1;
- count_labels = 0;
- match_context = name;
- match_exten = "*"; /* don't really need to set these, shouldn't be reached */
- match_label = "*";
- return match_pval(current_db);
-}
-
-struct pval *find_context(char *name)
-{
- return_on_context_match = 1;
- count_labels = 0;
- match_context = name;
- match_exten = "*"; /* don't really need to set these, shouldn't be reached */
- match_label = "*";
- return match_pval(current_db);
-}
-
-int is_float(char *arg )
-{
- char *s;
- for (s=arg; *s; s++) {
- if (*s != '.' && (*s < '0' || *s > '9'))
- return 0;
- }
- return 1;
-}
-int is_int(char *arg )
-{
- char *s;
- for (s=arg; *s; s++) {
- if (*s < '0' || *s > '9')
- return 0;
- }
- return 1;
-}
-int is_empty(char *arg)
-{
- if (!arg)
- return 1;
- if (*arg == 0)
- return 1;
- while (*arg) {
- if (*arg != ' ' && *arg != '\t')
- return 0;
- arg++;
- }
- return 1;
-}
-
-#ifdef AAL_ARGCHECK
-int option_matches_j( struct argdesc *should, pval *is, struct argapp *app)
-{
- struct argchoice *ac;
- char *opcop,*q,*p;
-
- switch (should->dtype) {
- case ARGD_OPTIONSET:
- if ( strstr(is->u1.str,"${") )
- return 0; /* no checking anything if there's a var reference in there! */
-
- opcop = ast_strdupa(is->u1.str);
-
- for (q=opcop;*q;q++) { /* erase the innards of X(innard) type arguments, so we don't get confused later */
- if ( *q == '(' ) {
- p = q+1;
- while (*p && *p != ')' )
- *p++ = '+';
- q = p+1;
- }
- }
-
- for (ac=app->opts; ac; ac=ac->next) {
- if (strlen(ac->name)>1 && strchr(ac->name,'(') == 0 && strcmp(ac->name,is->u1.str) == 0) /* multichar option, no parens, and a match? */
- return 0;
- }
- for (ac=app->opts; ac; ac=ac->next) {
- if (strlen(ac->name)==1 || strchr(ac->name,'(')) {
- char *p = strchr(opcop,ac->name[0]); /* wipe out all matched options in the user-supplied string */
-
- if (p && *p == 'j') {
- ast_log(LOG_ERROR, "Error: file %s, line %d-%d: The j option in the %s application call is not appropriate for AEL!\n",
- is->filename, is->startline, is->endline, app->name);
- errs++;
- }
-
- if (p) {
- *p = '+';
- if (ac->name[1] == '(') {
- if (*(p+1) != '(') {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The %c option in the %s application call should have an (argument), but doesn't!\n",
- is->filename, is->startline, is->endline, ac->name[0], app->name);
- warns++;
- }
- }
- }
- }
- }
- for (q=opcop; *q; q++) {
- if ( *q != '+' && *q != '(' && *q != ')') {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The %c option in the %s application call is not available as an option!\n",
- is->filename, is->startline, is->endline, *q, app->name);
- warns++;
- }
- }
- return 1;
- break;
- default:
- return 0;
- }
-
-}
-
-int option_matches( struct argdesc *should, pval *is, struct argapp *app)
-{
- struct argchoice *ac;
- char *opcop;
-
- switch (should->dtype) {
- case ARGD_STRING:
- if (is_empty(is->u1.str) && should->type == ARGD_REQUIRED)
- return 0;
- if (is->u1.str && strlen(is->u1.str) > 0) /* most will match */
- return 1;
- break;
-
- case ARGD_INT:
- if (is_int(is->u1.str))
- return 1;
- else
- return 0;
- break;
-
- case ARGD_FLOAT:
- if (is_float(is->u1.str))
- return 1;
- else
- return 0;
- break;
-
- case ARGD_ENUM:
- if( !is->u1.str || strlen(is->u1.str) == 0 )
- return 1; /* a null arg in the call will match an enum, I guess! */
- for (ac=should->choices; ac; ac=ac->next) {
- if (strcmp(ac->name,is->u1.str) == 0)
- return 1;
- }
- return 0;
- break;
-
- case ARGD_OPTIONSET:
- opcop = ast_strdupa(is->u1.str);
-
- for (ac=app->opts; ac; ac=ac->next) {
- if (strlen(ac->name)>1 && strchr(ac->name,'(') == 0 && strcmp(ac->name,is->u1.str) == 0) /* multichar option, no parens, and a match? */
- return 1;
- }
- for (ac=app->opts; ac; ac=ac->next) {
- if (strlen(ac->name)==1 || strchr(ac->name,'(')) {
- char *p = strchr(opcop,ac->name[0]); /* wipe out all matched options in the user-supplied string */
-
- if (p) {
- *p = '+';
- if (ac->name[1] == '(') {
- if (*(p+1) == '(') {
- char *q = p+1;
- while (*q && *q != ')') {
- *q++ = '+';
- }
- *q = '+';
- }
- }
- }
- }
- }
- return 1;
- break;
- case ARGD_VARARG:
- return 1; /* matches anything */
- break;
- }
- return 1; /* unless some for-sure match or non-match returns, then it must be close enough ... */
-}
-#endif
-
-int check_app_args(pval* appcall, pval *arglist, struct argapp *app)
-{
-#ifdef AAL_ARGCHECK
- struct argdesc *ad = app->args;
- pval *pa;
- int z;
-
- for (pa = arglist; pa; pa=pa->next) {
- if (!ad) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n",
- arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name);
- warns++;
- return 1;
- } else {
- /* find the first entry in the ad list that will match */
- do {
- if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */
- break;
-
- z= option_matches( ad, pa, app);
- if (!z) {
- if ( !arglist )
- arglist=appcall;
-
- if (ad->type == ARGD_REQUIRED) {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
- arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
- warns++;
- return 1;
- }
- } else if (z && ad->dtype == ARGD_OPTIONSET) {
- option_matches_j( ad, pa, app);
- }
- ad = ad->next;
- } while (ad && !z);
- }
- }
- /* any app nodes left, that are not optional? */
- for ( ; ad; ad=ad->next) {
- if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) {
- if ( !arglist )
- arglist=appcall;
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
- arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
- warns++;
- return 1;
- }
- }
- return 0;
-#else
- return 0;
-#endif
-}
-
-void check_switch_expr(pval *item, struct argapp *apps)
-{
-#ifdef AAL_ARGCHECK
- /* get and clean the variable name */
- char *buff1, *p;
- struct argapp *a,*a2;
- struct appsetvar *v,*v2;
- struct argchoice *c;
- pval *t;
-
- p = item->u1.str;
- while (p && *p && (*p == ' ' || *p == '\t' || *p == '$' || *p == '{' ) )
- p++;
-
- buff1 = ast_strdupa(p);
-
- while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] == '}' || buff1[strlen(buff1)-1] == ' ' || buff1[strlen(buff1)-1] == '\t'))
- buff1[strlen(buff1)-1] = 0;
- /* buff1 now contains the variable name */
- v = 0;
- for (a=apps; a; a=a->next) {
- for (v=a->setvars;v;v=v->next) {
- if (strcmp(v->name,buff1) == 0) {
- break;
- }
- }
- if ( v )
- break;
- }
- if (v && v->vals) {
- /* we have a match, to a variable that has a set of determined values */
- int def= 0;
- int pat = 0;
- int f1 = 0;
-
- /* first of all, does this switch have a default case ? */
- for (t=item->u2.statements; t; t=t->next) {
- if (t->type == PV_DEFAULT) {
- def =1;
- break;
- }
- if (t->type == PV_PATTERN) {
- pat++;
- }
- }
- if (def || pat) /* nothing to check. All cases accounted for! */
- return;
- for (c=v->vals; c; c=c->next) {
- f1 = 0;
- for (t=item->u2.statements; t; t=t->next) {
- if (t->type == PV_CASE || t->type == PV_PATTERN) {
- if (!strcmp(t->u1.str,c->name)) {
- f1 = 1;
- break;
- }
- }
- }
- if (!f1) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n",
- item->filename, item->startline, item->endline, item->u1.str, c->name);
- warns++;
- }
- }
- /* next, is there an app call in the current exten, that would set this var? */
- f1 = 0;
- t = current_extension->u2.statements;
- if ( t && t->type == PV_STATEMENTBLOCK )
- t = t->u1.statements;
- for (; t && t != item; t=t->next) {
- if (t->type == PV_APPLICATION_CALL) {
- /* find the application that matches the u1.str */
- for (a2=apps; a2; a2=a2->next) {
- if (strcasecmp(a2->name, t->u1.str)==0) {
- for (v2=a2->setvars; v2; v2=v2->next) {
- if (strcmp(v2->name, buff1) == 0) {
- /* found an app that sets the var */
- f1 = 1;
- break;
- }
- }
- }
- if (f1)
- break;
- }
- }
- if (f1)
- break;
- }
-
- /* see if it sets the var */
- if (!f1) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: Couldn't find an application call in this extension that sets the expression (%s) value!\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- }
- }
-#else
- pval *t,*tl=0,*p2;
- int def= 0;
-
- /* first of all, does this switch have a default case ? */
- for (t=item->u2.statements; t; t=t->next) {
- if (t->type == PV_DEFAULT) {
- def =1;
- break;
- }
- tl = t;
- }
- if (def) /* nothing to check. All cases accounted for! */
- return;
- /* if no default, warn and insert a default case at the end */
- p2 = tl->next = calloc(1, sizeof(struct pval));
-
- p2->type = PV_DEFAULT;
- p2->startline = tl->startline;
- p2->endline = tl->endline;
- p2->startcol = tl->startcol;
- p2->endcol = tl->endcol;
- p2->filename = strdup(tl->filename);
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: A default case was automatically added to the switch.\n",
- p2->filename, p2->startline, p2->endline);
- warns++;
-
-#endif
-}
-
-static void check_context_names(void)
-{
- pval *i,*j;
- for (i=current_db; i; i=i->next) {
- if (i->type == PV_CONTEXT || i->type == PV_MACRO) {
- for (j=i->next; j; j=j->next) {
- if ( j->type == PV_CONTEXT || j->type == PV_MACRO ) {
- if ( !strcmp(i->u1.str, j->u1.str) && !(i->u3.abstract&2) && !(j->u3.abstract&2) )
- {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: The context name (%s) is also declared in file %s, line %d-%d! (and neither is marked 'extend')\n",
- i->filename, i->startline, i->endline, i->u1.str, j->filename, j->startline, j->endline);
- errs++;
- }
- }
- }
- }
- }
-}
-
-static void check_abstract_reference(pval *abstract_context)
-{
- pval *i,*j;
- /* find some context includes that reference this context */
-
-
- /* otherwise, print out a warning */
- for (i=current_db; i; i=i->next) {
- if (i->type == PV_CONTEXT) {
- for (j=i->u2. statements; j; j=j->next) {
- if ( j->type == PV_INCLUDES ) {
- struct pval *p4;
- for (p4=j->u1.list; p4; p4=p4->next) {
- /* for each context pointed to, find it, then find a context/label that matches the
- target here! */
- if ( !strcmp(p4->u1.str, abstract_context->u1.str) )
- return; /* found a match! */
- }
- }
- }
- }
- }
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: Couldn't find a reference to this abstract context (%s) in any other context!\n",
- abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str);
- warns++;
-}
-
-
-void check_pval_item(pval *item, struct argapp *apps, int in_globals)
-{
- pval *lp;
-#ifdef AAL_ARGCHECK
- struct argapp *app, *found;
-#endif
- struct pval *macro_def;
- struct pval *app_def;
-
- char errmsg[4096];
- char *strp;
-
- switch (item->type) {
- case PV_WORD:
- /* fields: item->u1.str == string associated with this (word).
- item->u2.arglist == pval list of 4 PV_WORD elements for time values (only in PV_INCLUDES) */
- break;
-
- case PV_MACRO:
- /* fields: item->u1.str == name of macro
- item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
-
- item->u3.macro_statements == pval list of statements in macro body.
- */
- in_abstract_context = 0;
- current_context = item;
- current_extension = 0;
- for (lp=item->u2.arglist; lp; lp=lp->next) {
-
- }
- check_pval(item->u3.macro_statements, apps,in_globals);
- break;
-
- case PV_CONTEXT:
- /* fields: item->u1.str == name of context
- item->u2.statements == pval list of statements in context body
- item->u3.abstract == int 1 if an abstract keyword were present
- */
- current_context = item;
- current_extension = 0;
- if ( item->u3.abstract ) {
- in_abstract_context = 1;
- check_abstract_reference(item);
- } else
- in_abstract_context = 0;
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_MACRO_CALL:
- /* fields: item->u1.str == name of macro to call
- item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
- */
- macro_def = find_macro(item->u1.str);
- if (!macro_def) {
- /* here is a good place to check to see if the definition is in extensions.conf! */
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to non-existent %s ! Hopefully it is present in extensions.conf! \n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- } else if (macro_def->type != PV_MACRO) {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n",
- item->filename, item->startline, item->endline, item->u1.str);
- errs++;
- } else {
- /* macro_def is a MACRO, so do the args match in number? */
- int hereargs = 0;
- int thereargs = 0;
-
- for (lp=item->u2.arglist; lp; lp=lp->next) {
- hereargs++;
- }
- for (lp=macro_def->u2.arglist; lp; lp=lp->next) {
- thereargs++;
- }
- if (hereargs != thereargs ) {
- ast_log(LOG_ERROR, "Error: file %s, line %d-%d: The macro call to %s has %d arguments, but the macro definition has %d arguments\n",
- item->filename, item->startline, item->endline, item->u1.str, hereargs, thereargs);
- errs++;
- }
- }
- break;
-
- case PV_APPLICATION_CALL:
- /* fields: item->u1.str == name of application to call
- item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
- */
- /* Need to check to see if the application is available! */
- app_def = find_context(item->u1.str);
- if (app_def && app_def->type == PV_MACRO) {
- ast_log(LOG_ERROR,"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n",
- item->filename, item->startline, item->endline, item->u1.str);
- errs++;
- }
- if (strcasecmp(item->u1.str,"GotoIf") == 0
- || strcasecmp(item->u1.str,"GotoIfTime") == 0
- || strcasecmp(item->u1.str,"while") == 0
- || strcasecmp(item->u1.str,"endwhile") == 0
- || strcasecmp(item->u1.str,"random") == 0
- || strcasecmp(item->u1.str,"execIf") == 0 ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: application call to %s needs to be re-written using AEL if, while, goto, etc. keywords instead!\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- }
-#ifdef AAL_ARGCHECK
- found = 0;
- for (app=apps; app; app=app->next) {
- if (strcasecmp(app->name, item->u1.str) == 0) {
- found =app;
- break;
- }
- }
- if (!found) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: application call to %s not listed in applist database!\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- } else
- check_app_args(item, item->u2.arglist, app);
-#endif
- break;
-
- case PV_CASE:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- /* Make sure sequence of statements under case is terminated with goto, return, or break */
- /* find the last statement */
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_PATTERN:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- /* Make sure sequence of statements under case is terminated with goto, return, or break */
- /* find the last statement */
-
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_DEFAULT:
- /* fields:
- item->u2.statements == pval list of statements under the case
- */
-
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_CATCH:
- /* fields: item->u1.str == name of extension to catch
- item->u2.statements == pval list of statements in context body
- */
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_SWITCHES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- check_pval(item->u1.list, apps,in_globals);
- break;
-
- case PV_ESWITCHES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- check_pval(item->u1.list, apps,in_globals);
- break;
-
- case PV_INCLUDES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- check_pval(item->u1.list, apps,in_globals);
- check_includes(item);
- for (lp=item->u1.list; lp; lp=lp->next){
- char *incl_context = lp->u1.str;
- struct pval *that_context = find_context(incl_context);
-
- if ( lp->u2.arglist ) {
- check_timerange(lp->u2.arglist);
- check_dow(lp->u2.arglist->next);
- check_day(lp->u2.arglist->next->next);
- check_month(lp->u2.arglist->next->next->next);
- }
-
- if (that_context) {
- find_pval_gotos(that_context->u2.statements,0);
-
- }
- }
- break;
-
- case PV_STATEMENTBLOCK:
- /* fields: item->u1.list == pval list of statements in block, one per entry in the list
- */
- check_pval(item->u1.list, apps,in_globals);
- break;
-
- case PV_VARDEC:
- /* fields: item->u1.str == variable name
- item->u2.val == variable value to assign
- */
- /* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */
- if( !in_globals ) { /* don't check stuff inside the globals context; no wrapping in $[ ] there... */
- snprintf(errmsg,sizeof(errmsg), "file %s, line %d, columns %d-%d, variable declaration expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.val);
- ast_expr_register_extra_error_info(errmsg);
- ast_expr(item->u2.val, expr_output, sizeof(expr_output));
- ast_expr_clear_extra_error_info();
- if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
- item->filename, item->startline, item->endline, item->u2.val);
- warns++;
- }
- check_expr2_input(item,item->u2.val);
- }
- break;
-
- case PV_GOTO:
- /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
- item->u1.list->u1.str == where the data on a PV_WORD will always be.
- */
- /* don't check goto's in abstract contexts */
- if ( in_abstract_context )
- break;
-
- check_goto(item);
- break;
-
- case PV_LABEL:
- /* fields: item->u1.str == label name
- */
- if ( strspn(item->u1.str, "0123456789") == strlen(item->u1.str) ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: label '%s' is numeric, this is bad practice!\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- }
-
- check_label(item);
- break;
-
- case PV_FOR:
- /* fields: item->u1.for_init == a string containing the initalizer
- item->u2.for_test == a string containing the loop test
- item->u3.for_inc == a string containing the loop increment
-
- item->u4.for_statements == a pval list of statements in the for ()
- */
- snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, for test expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.for_test);
- ast_expr_register_extra_error_info(errmsg);
-
- strp = strchr(item->u1.for_init, '=');
- if (strp) {
- ast_expr(strp+1, expr_output, sizeof(expr_output));
- }
- ast_expr(item->u2.for_test, expr_output, sizeof(expr_output));
- strp = strchr(item->u3.for_inc, '=');
- if (strp) {
- ast_expr(strp+1, expr_output, sizeof(expr_output));
- }
- if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
- item->filename, item->startline, item->endline, item->u2.for_test);
- warns++;
- }
- if ( strpbrk(item->u3.for_inc,"~!-+<>=*/&^") && !strstr(item->u3.for_inc,"${") ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
- item->filename, item->startline, item->endline, item->u3.for_inc);
- warns++;
- }
- check_expr2_input(item,item->u2.for_test);
- check_expr2_input(item,item->u3.for_inc);
-
- ast_expr_clear_extra_error_info();
- check_pval(item->u4.for_statements, apps,in_globals);
- break;
-
- case PV_WHILE:
- /* fields: item->u1.str == the while conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the while ()
- */
- snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, while expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
- ast_expr_register_extra_error_info(errmsg);
- ast_expr(item->u1.str, expr_output, sizeof(expr_output));
- ast_expr_clear_extra_error_info();
- if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- }
- check_expr2_input(item,item->u1.str);
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_BREAK:
- /* fields: none
- */
- check_break(item);
- break;
-
- case PV_RETURN:
- /* fields: none
- */
- break;
-
- case PV_CONTINUE:
- /* fields: none
- */
- check_continue(item);
- break;
-
- case PV_RANDOM:
- /* fields: item->u1.str == the random number expression, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, random expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
- ast_expr_register_extra_error_info(errmsg);
- ast_expr(item->u1.str, expr_output, sizeof(expr_output));
- ast_expr_clear_extra_error_info();
- if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- }
- check_expr2_input(item,item->u1.str);
- check_pval(item->u2.statements, apps,in_globals);
- if (item->u3.else_statements) {
- check_pval(item->u3.else_statements, apps,in_globals);
- }
- break;
-
- case PV_IFTIME:
- /* fields: item->u1.list == the if time values, 4 of them, each in PV_WORD, linked list
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- if ( item->u2.arglist ) {
- check_timerange(item->u1.list);
- check_dow(item->u1.list->next);
- check_day(item->u1.list->next->next);
- check_month(item->u1.list->next->next->next);
- }
-
- check_pval(item->u2.statements, apps,in_globals);
- if (item->u3.else_statements) {
- check_pval(item->u3.else_statements, apps,in_globals);
- }
- break;
-
- case PV_IF:
- /* fields: item->u1.str == the if conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, if expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
- ast_expr_register_extra_error_info(errmsg);
- ast_expr(item->u1.str, expr_output, sizeof(expr_output));
- ast_expr_clear_extra_error_info();
- if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
- ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n",
- item->filename, item->startline, item->endline, item->u1.str);
- warns++;
- }
- check_expr2_input(item,item->u1.str);
- check_pval(item->u2.statements, apps,in_globals);
- if (item->u3.else_statements) {
- check_pval(item->u3.else_statements, apps,in_globals);
- }
- break;
-
- case PV_SWITCH:
- /* fields: item->u1.str == the switch expression
-
- item->u2.statements == a pval list of statements in the switch,
- (will be case statements, most likely!)
- */
- /* we can check the switch expression, see if it matches any of the app variables...
- if it does, then, are all the possible cases accounted for? */
- check_switch_expr(item, apps);
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_EXTENSION:
- /* fields: item->u1.str == the extension name, label, whatever it's called
-
- item->u2.statements == a pval list of statements in the extension
- item->u3.hints == a char * hint argument
- item->u4.regexten == an int boolean. non-zero says that regexten was specified
- */
- current_extension = item ;
-
- check_pval(item->u2.statements, apps,in_globals);
- break;
-
- case PV_IGNOREPAT:
- /* fields: item->u1.str == the ignorepat data
- */
- break;
-
- case PV_GLOBALS:
- /* fields: item->u1.statements == pval list of statements, usually vardecs
- */
- in_abstract_context = 0;
- check_pval(item->u1.statements, apps, 1);
- break;
- default:
- break;
- }
-}
-
-void check_pval(pval *item, struct argapp *apps, int in_globals)
-{
- pval *i;
-
- /* checks to do:
- 1. Do goto's point to actual labels?
- 2. Do macro calls reference a macro?
- 3. Does the number of macro args match the definition?
- 4. Is a macro call missing its & at the front?
- 5. Application calls-- we could check syntax for existing applications,
- but I need some some sort of universal description bnf for a general
- sort of method for checking arguments, in number, maybe even type, at least.
- Don't want to hand code checks for hundreds of applications.
- */
-
- for (i=item; i; i=i->next) {
- check_pval_item(i,apps,in_globals);
- }
-}
-
-static void ael2_semantic_check(pval *item, int *arg_errs, int *arg_warns, int *arg_notes)
-{
-
-#ifdef AAL_ARGCHECK
- int argapp_errs =0;
- char *rfilename;
-#endif
- struct argapp *apps=0;
-
- if (!item)
- return; /* don't check an empty tree */
-#ifdef AAL_ARGCHECK
- rfilename = alloca(10 + strlen(ast_config_AST_VAR_DIR));
- sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR);
-
- apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */
-#endif
- current_db = item;
- errs = warns = notes = 0;
-
- check_context_names();
- check_pval(item, apps, 0);
-
-#ifdef AAL_ARGCHECK
- argdesc_destroy(apps); /* taketh away */
-#endif
- current_db = 0;
-
- *arg_errs = errs;
- *arg_warns = warns;
- *arg_notes = notes;
-}
-
-/* =============================================================================================== */
-/* "CODE" GENERATOR -- Convert the AEL representation to asterisk extension language */
-/* =============================================================================================== */
-
-static int control_statement_count = 0;
-
-struct ael_priority *new_prio(void)
-{
- struct ael_priority *x = (struct ael_priority *)calloc(sizeof(struct ael_priority),1);
- return x;
-}
-
-struct ael_extension *new_exten(void)
-{
- struct ael_extension *x = (struct ael_extension *)calloc(sizeof(struct ael_extension),1);
- return x;
-}
-
-void linkprio(struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten)
-{
- char *p1, *p2;
-
- if (!exten->plist) {
- exten->plist = prio;
- exten->plist_last = prio;
- } else {
- exten->plist_last->next = prio;
- exten->plist_last = prio;
- }
- if( !prio->exten )
- prio->exten = exten; /* don't override the switch value */
- /* The following code will cause all priorities within an extension
- to have ${EXTEN} or ${EXTEN: replaced with ~~EXTEN~~, which is
- set just before the first switch in an exten. The switches
- will muck up the original ${EXTEN} value, so we save it away
- and the user accesses this copy instead. */
- if (prio->appargs && ((mother_exten && mother_exten->has_switch) || exten->has_switch) ) {
- while ((p1 = strstr(prio->appargs, "${EXTEN}"))) {
- p2 = malloc(strlen(prio->appargs)+5);
- *p1 = 0;
- strcpy(p2, prio->appargs);
- strcat(p2, "${~~EXTEN~~}");
- if (*(p1+8))
- strcat(p2, p1+8);
- free(prio->appargs);
- prio->appargs = p2;
- }
- while ((p1 = strstr(prio->appargs, "${EXTEN:"))) {
- p2 = malloc(strlen(prio->appargs)+5);
- *p1 = 0;
- strcpy(p2, prio->appargs);
- strcat(p2, "${~~EXTEN~~:");
- if (*(p1+8))
- strcat(p2, p1+8);
- free(prio->appargs);
- prio->appargs = p2;
- }
- }
-}
-
-void destroy_extensions(struct ael_extension *exten)
-{
- struct ael_extension *ne, *nen;
- for (ne=exten; ne; ne=nen) {
- struct ael_priority *pe, *pen;
-
- if (ne->name)
- free(ne->name);
-
- /* cidmatch fields are allocated with name, and freed when
- the name field is freed. Don't do a free for this field,
- unless you LIKE to see a crash! */
-
- if (ne->hints)
- free(ne->hints);
-
- for (pe=ne->plist; pe; pe=pen) {
- pen = pe->next;
- if (pe->app)
- free(pe->app);
- pe->app = 0;
- if (pe->appargs)
- free(pe->appargs);
- pe->appargs = 0;
- pe->origin = 0;
- pe->goto_true = 0;
- pe->goto_false = 0;
- free(pe);
- }
- nen = ne->next_exten;
- ne->next_exten = 0;
- ne->plist =0;
- ne->plist_last = 0;
- ne->next_exten = 0;
- ne->loop_break = 0;
- ne->loop_continue = 0;
- free(ne);
- }
-}
-
-static int label_inside_case(pval *label)
-{
- pval *p = label;
-
- while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
- if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN ) {
- return 1;
- }
-
- p = p->dad;
- }
- return 0;
-}
-
-static void linkexten(struct ael_extension *exten, struct ael_extension *add)
-{
- add->next_exten = exten->next_exten; /* this will reverse the order. Big deal. */
- exten->next_exten = add;
-}
-
-static void remove_spaces_before_equals(char *str)
-{
- char *p;
- while( str && *str && *str != '=' )
- {
- if( *str == ' ' || *str == '\n' || *str == '\r' || *str == '\t' )
- {
- p = str;
- while( *p )
- {
- *p = *(p+1);
- p++;
- }
- }
- else
- str++;
- }
-}
-
-static void gen_match_to_pattern(char *pattern, char *result)
-{
- /* the result will be a string that will be matched by pattern */
- char *p=pattern, *t=result;
- while (*p) {
- if (*p == 'x' || *p == 'n' || *p == 'z' || *p == 'X' || *p == 'N' || *p == 'Z')
- *t++ = '9';
- else if (*p == '[') {
- char *z = p+1;
- while (*z != ']')
- z++;
- if (*(z+1)== ']')
- z++;
- *t++=*(p+1); /* use the first char in the set */
- p = z;
- } else {
- *t++ = *p;
- }
- p++;
- }
- *t++ = 0; /* cap it off */
-}
-
-static void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *this_context )
-{
- pval *p,*p2,*p3;
- struct ael_priority *pr;
- struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end;
- struct ael_priority *while_test, *while_loop, *while_end;
- struct ael_priority *switch_set, *switch_test, *switch_end, *fall_thru, *switch_empty;
- struct ael_priority *if_test, *if_end, *if_skip, *if_false;
-#ifdef OLD_RAND_ACTION
- struct ael_priority *rand_test, *rand_end, *rand_skip;
-#endif
- char buf1[2000];
- char buf2[2000];
- char *strp, *strp2;
- char new_label[2000];
- int default_exists;
- int local_control_statement_count;
- struct ael_priority *loop_break_save;
- struct ael_priority *loop_continue_save;
- struct ael_extension *switch_case,*switch_null;
-
- for (p=statement; p; p=p->next) {
- switch (p->type) {
- case PV_VARDEC:
- pr = new_prio();
- pr->type = AEL_APPCALL;
- snprintf(buf1,sizeof(buf1),"%s=$[%s]", p->u1.str, p->u2.val);
- pr->app = strdup("Set");
- remove_spaces_before_equals(buf1);
- pr->appargs = strdup(buf1);
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_GOTO:
- pr = new_prio();
- pr->type = AEL_APPCALL;
- p->u2.goto_target = get_goto_target(p);
- if( p->u2.goto_target ) {
- p->u3.goto_target_in_case = p->u2.goto_target->u2.label_in_case = label_inside_case(p->u2.goto_target);
- }
-
- if (!p->u1.list->next) /* just one */ {
- pr->app = strdup("Goto");
- if (!mother_exten)
- pr->appargs = strdup(p->u1.list->u1.str);
- else { /* for the case of simple within-extension gotos in case/pattern/default statement blocks: */
- snprintf(buf1,sizeof(buf1),"%s|%s", mother_exten->name, p->u1.list->u1.str);
- pr->appargs = strdup(buf1);
- }
-
- } else if (p->u1.list->next && !p->u1.list->next->next) /* two */ {
- snprintf(buf1,sizeof(buf1),"%s|%s", p->u1.list->u1.str, p->u1.list->next->u1.str);
- pr->app = strdup("Goto");
- pr->appargs = strdup(buf1);
- } else if (p->u1.list->next && p->u1.list->next->next) {
- snprintf(buf1,sizeof(buf1),"%s|%s|%s", p->u1.list->u1.str,
- p->u1.list->next->u1.str,
- p->u1.list->next->next->u1.str);
- pr->app = strdup("Goto");
- pr->appargs = strdup(buf1);
- }
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_LABEL:
- pr = new_prio();
- pr->type = AEL_LABEL;
- pr->origin = p;
- p->u3.compiled_label = exten;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_FOR:
- control_statement_count++;
- loop_break_save = exten->loop_break; /* save them, then restore before leaving */
- loop_continue_save = exten->loop_continue;
- snprintf(new_label,sizeof(new_label),"for-%s-%d", label, control_statement_count);
- for_init = new_prio();
- for_inc = new_prio();
- for_test = new_prio();
- for_loop = new_prio();
- for_end = new_prio();
- for_init->type = AEL_APPCALL;
- for_inc->type = AEL_APPCALL;
- for_test->type = AEL_FOR_CONTROL;
- for_test->goto_false = for_end;
- for_loop->type = AEL_CONTROL1; /* simple goto */
- for_end->type = AEL_APPCALL;
- for_init->app = strdup("Set");
-
- strcpy(buf2,p->u1.for_init);
- remove_spaces_before_equals(buf2);
- strp = strchr(buf2, '=');
- if (strp) {
- strp2 = strchr(p->u1.for_init, '=');
- *(strp+1) = 0;
- strcat(buf2,"$[");
- strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2);
- strcat(buf2,"]");
- for_init->appargs = strdup(buf2);
- /* for_init->app = strdup("Set"); just set! */
- } else {
- strp2 = p->u1.for_init;
- while (*strp2 && isspace(*strp2))
- strp2++;
- if (*strp2 == '&') { /* itsa macro call */
- char *strp3 = strp2+1;
- while (*strp3 && isspace(*strp3))
- strp3++;
- strcpy(buf2, strp3);
- strp3 = strchr(buf2,'(');
- if (strp3) {
- *strp3 = '|';
- }
- while ((strp3=strchr(buf2,','))) {
- *strp3 = '|';
- }
- strp3 = strrchr(buf2, ')');
- if (strp3)
- *strp3 = 0; /* remove the closing paren */
-
- for_init->appargs = strdup(buf2);
- if (for_init->app)
- free(for_init->app);
- for_init->app = strdup("Macro");
- } else { /* must be a regular app call */
- char *strp3;
- strcpy(buf2, strp2);
- strp3 = strchr(buf2,'(');
- if (strp3) {
- *strp3 = 0;
- if (for_init->app)
- free(for_init->app);
- for_init->app = strdup(buf2);
- for_init->appargs = strdup(strp3+1);
- strp3 = strrchr(for_init->appargs, ')');
- if (strp3)
- *strp3 = 0; /* remove the closing paren */
- }
- }
- }
-
- strcpy(buf2,p->u3.for_inc);
- remove_spaces_before_equals(buf2);
- strp = strchr(buf2, '=');
- if (strp) { /* there's an = in this part; that means an assignment. set it up */
- strp2 = strchr(p->u3.for_inc, '=');
- *(strp+1) = 0;
- strcat(buf2,"$[");
- strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2);
- strcat(buf2,"]");
- for_inc->appargs = strdup(buf2);
- for_inc->app = strdup("Set");
- } else {
- strp2 = p->u3.for_inc;
- while (*strp2 && isspace(*strp2))
- strp2++;
- if (*strp2 == '&') { /* itsa macro call */
- char *strp3 = strp2+1;
- while (*strp3 && isspace(*strp3))
- strp3++;
- strcpy(buf2, strp3);
- strp3 = strchr(buf2,'(');
- if (strp3) {
- *strp3 = '|';
- }
- while ((strp3=strchr(buf2,','))) {
- *strp3 = '|';
- }
- strp3 = strrchr(buf2, ')');
- if (strp3)
- *strp3 = 0; /* remove the closing paren */
-
- for_inc->appargs = strdup(buf2);
-
- for_inc->app = strdup("Macro");
- } else { /* must be a regular app call */
- char *strp3;
- strcpy(buf2, strp2);
- strp3 = strchr(buf2,'(');
- if (strp3) {
- *strp3 = 0;
- for_inc->app = strdup(buf2);
- for_inc->appargs = strdup(strp3+1);
- strp3 = strrchr(for_inc->appargs, ')');
- if (strp3)
- *strp3 = 0; /* remove the closing paren */
- }
- }
- }
- snprintf(buf1,sizeof(buf1),"$[%s]",p->u2.for_test);
- for_test->app = 0;
- for_test->appargs = strdup(buf1);
- for_loop->goto_true = for_test;
- snprintf(buf1,sizeof(buf1),"Finish for-%s-%d", label, control_statement_count);
- for_end->app = strdup("NoOp");
- for_end->appargs = strdup(buf1);
- /* link & load! */
- linkprio(exten, for_init, mother_exten);
- linkprio(exten, for_test, mother_exten);
-
- /* now, put the body of the for loop here */
- exten->loop_break = for_end;
- exten->loop_continue = for_inc;
-
- gen_prios(exten, new_label, p->u4.for_statements, mother_exten, this_context); /* this will link in all the statements here */
-
- linkprio(exten, for_inc, mother_exten);
- linkprio(exten, for_loop, mother_exten);
- linkprio(exten, for_end, mother_exten);
-
-
- exten->loop_break = loop_break_save;
- exten->loop_continue = loop_continue_save;
- for_loop->origin = p;
- break;
-
- case PV_WHILE:
- control_statement_count++;
- loop_break_save = exten->loop_break; /* save them, then restore before leaving */
- loop_continue_save = exten->loop_continue;
- snprintf(new_label,sizeof(new_label),"while-%s-%d", label, control_statement_count);
- while_test = new_prio();
- while_loop = new_prio();
- while_end = new_prio();
- while_test->type = AEL_FOR_CONTROL;
- while_test->goto_false = while_end;
- while_loop->type = AEL_CONTROL1; /* simple goto */
- while_end->type = AEL_APPCALL;
- snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str);
- while_test->app = 0;
- while_test->appargs = strdup(buf1);
- while_loop->goto_true = while_test;
- snprintf(buf1,sizeof(buf1),"Finish while-%s-%d", label, control_statement_count);
- while_end->app = strdup("NoOp");
- while_end->appargs = strdup(buf1);
-
- linkprio(exten, while_test, mother_exten);
-
- /* now, put the body of the for loop here */
- exten->loop_break = while_end;
- exten->loop_continue = while_test;
-
- gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the while body statements here */
-
- linkprio(exten, while_loop, mother_exten);
- linkprio(exten, while_end, mother_exten);
-
-
- exten->loop_break = loop_break_save;
- exten->loop_continue = loop_continue_save;
- while_loop->origin = p;
- break;
-
- case PV_SWITCH:
- control_statement_count++;
- local_control_statement_count = control_statement_count;
- loop_break_save = exten->loop_break; /* save them, then restore before leaving */
- loop_continue_save = exten->loop_continue;
- snprintf(new_label,sizeof(new_label),"sw-%s-%d", label, control_statement_count);
- if ((mother_exten && !mother_exten->has_switch)) {
- switch_set = new_prio();
- switch_set->type = AEL_APPCALL;
- switch_set->app = strdup("Set");
- switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
- linkprio(exten, switch_set, mother_exten);
- mother_exten->has_switch = 1;
- } else if ((exten && !exten->has_switch)) {
- switch_set = new_prio();
- switch_set->type = AEL_APPCALL;
- switch_set->app = strdup("Set");
- switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
- linkprio(exten, switch_set, exten);
- exten->has_switch = 1;
- }
- switch_test = new_prio();
- switch_end = new_prio();
- switch_test->type = AEL_APPCALL;
- switch_end->type = AEL_APPCALL;
- strncpy(buf2,p->u1.str,sizeof(buf2));
- buf2[sizeof(buf2)-1] = 0; /* just in case */
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10",control_statement_count, buf2);
- switch_test->app = strdup("Goto");
- switch_test->appargs = strdup(buf1);
- snprintf(buf1,sizeof(buf1),"Finish switch-%s-%d", label, control_statement_count);
- switch_end->app = strdup("NoOp");
- switch_end->appargs = strdup(buf1);
- switch_end->origin = p;
- switch_end->exten = exten;
-
- linkprio(exten, switch_test, mother_exten);
- linkprio(exten, switch_end, mother_exten);
-
- exten->loop_break = switch_end;
- exten->loop_continue = 0;
- default_exists = 0;
-
- for (p2=p->u2.statements; p2; p2=p2->next) {
- /* now, for each case/default put the body of the for loop here */
- if (p2->type == PV_CASE) {
- /* ok, generate a extension and link it in */
- switch_case = new_exten();
- switch_case->context = this_context;
- switch_case->is_switch = 1;
- /* the break/continue locations are inherited from parent */
- switch_case->loop_break = exten->loop_break;
- switch_case->loop_continue = exten->loop_continue;
-
- linkexten(exten,switch_case);
- strncpy(buf2,p2->u1.str,sizeof(buf2));
- buf2[sizeof(buf2)-1] = 0; /* just in case */
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s", local_control_statement_count, buf2);
- switch_case->name = strdup(buf1);
- snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, buf2, local_control_statement_count);
-
- gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the case body statements here */
-
- /* here is where we write code to "fall thru" to the next case... if there is one... */
- for (p3=p2->u2.statements; p3; p3=p3->next) {
- if (!p3->next)
- break;
- }
- /* p3 now points the last statement... */
- if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN) ) {
- /* is there a following CASE/PATTERN/DEFAULT? */
- if (p2->next && p2->next->type == PV_CASE) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- strncpy(buf2,p2->next->u1.str,sizeof(buf2));
- buf2[sizeof(buf2)-1] = 0; /* just in case */
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10",local_control_statement_count, buf2);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (p2->next && p2->next->type == PV_PATTERN) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- gen_match_to_pattern(p2->next->u1.str, buf2);
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10", local_control_statement_count, buf2);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (p2->next && p2->next->type == PV_DEFAULT) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- snprintf(buf1,sizeof(buf1),"sw-%d-.|10",local_control_statement_count);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (!p2->next) {
- fall_thru = new_prio();
- fall_thru->type = AEL_CONTROL1;
- fall_thru->goto_true = switch_end;
- fall_thru->app = strdup("Goto");
- linkprio(switch_case, fall_thru, mother_exten);
- }
- }
- if (switch_case->return_needed) {
- char buf[2000];
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
- np2->appargs = strdup(buf);
- linkprio(switch_case, np2, mother_exten);
- switch_case-> return_target = np2;
- }
- } else if (p2->type == PV_PATTERN) {
- /* ok, generate a extension and link it in */
- switch_case = new_exten();
- switch_case->context = this_context;
- switch_case->is_switch = 1;
- /* the break/continue locations are inherited from parent */
- switch_case->loop_break = exten->loop_break;
- switch_case->loop_continue = exten->loop_continue;
-
- linkexten(exten,switch_case);
- strncpy(buf2,p2->u1.str,sizeof(buf2));
- buf2[sizeof(buf2)-1] = 0; /* just in case */
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"_sw-%d-%s", local_control_statement_count, buf2);
- switch_case->name = strdup(buf1);
- snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, buf2, local_control_statement_count);
-
- gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the while body statements here */
- /* here is where we write code to "fall thru" to the next case... if there is one... */
- for (p3=p2->u2.statements; p3; p3=p3->next) {
- if (!p3->next)
- break;
- }
- /* p3 now points the last statement... */
- if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) {
- /* is there a following CASE/PATTERN/DEFAULT? */
- if (p2->next && p2->next->type == PV_CASE) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- strncpy(buf2,p2->next->u1.str,sizeof(buf2));
- buf2[sizeof(buf2)-1] = 0; /* just in case */
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10",local_control_statement_count, buf2);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (p2->next && p2->next->type == PV_PATTERN) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- gen_match_to_pattern(p2->next->u1.str, buf2);
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10",local_control_statement_count, buf2);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (p2->next && p2->next->type == PV_DEFAULT) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- snprintf(buf1,sizeof(buf1),"sw-%d-.|10",local_control_statement_count);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (!p2->next) {
- fall_thru = new_prio();
- fall_thru->type = AEL_CONTROL1;
- fall_thru->goto_true = switch_end;
- fall_thru->app = strdup("Goto");
- linkprio(switch_case, fall_thru, mother_exten);
- }
- }
- if (switch_case->return_needed) {
- char buf[2000];
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
- np2->appargs = strdup(buf);
- linkprio(switch_case, np2, mother_exten);
- switch_case-> return_target = np2;
- }
- } else if (p2->type == PV_DEFAULT) {
- /* ok, generate a extension and link it in */
- switch_case = new_exten();
- switch_case->context = this_context;
- switch_case->is_switch = 1;
-
- /* new: the default case intros a pattern with ., which covers ALMOST everything.
- but it doesn't cover a NULL pattern. So, we'll define a null extension to match
- that goto's the default extension. */
-
- default_exists++;
- switch_null = new_exten();
- switch_null->context = this_context;
- switch_null->is_switch = 1;
- switch_empty = new_prio();
- snprintf(buf1,sizeof(buf1),"sw-%d-.|10",local_control_statement_count);
- switch_empty->app = strdup("Goto");
- switch_empty->appargs = strdup(buf1);
- linkprio(switch_null, switch_empty, mother_exten);
- snprintf(buf1,sizeof(buf1),"sw-%d-", local_control_statement_count);
- switch_null->name = strdup(buf1);
- switch_null->loop_break = exten->loop_break;
- switch_null->loop_continue = exten->loop_continue;
- linkexten(exten,switch_null);
-
- /* the break/continue locations are inherited from parent */
- switch_case->loop_break = exten->loop_break;
- switch_case->loop_continue = exten->loop_continue;
- linkexten(exten,switch_case);
- snprintf(buf1,sizeof(buf1),"_sw-%d-.", local_control_statement_count);
- switch_case->name = strdup(buf1);
-
- snprintf(new_label,sizeof(new_label),"sw-%s-default-%d", label, local_control_statement_count);
-
- gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the default: body statements here */
-
- /* here is where we write code to "fall thru" to the next case... if there is one... */
- for (p3=p2->u2.statements; p3; p3=p3->next) {
- if (!p3->next)
- break;
- }
- /* p3 now points the last statement... */
- if (!p3 || (p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) {
- /* is there a following CASE/PATTERN/DEFAULT? */
- if (p2->next && p2->next->type == PV_CASE) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- strncpy(buf2,p2->next->u1.str,sizeof(buf2));
- buf2[sizeof(buf2)-1] = 0; /* just in case */
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10",local_control_statement_count, buf2);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (p2->next && p2->next->type == PV_PATTERN) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- gen_match_to_pattern(p2->next->u1.str, buf2);
- substitute_commas(buf2);
- snprintf(buf1,sizeof(buf1),"sw-%d-%s|10",local_control_statement_count, buf2);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (p2->next && p2->next->type == PV_DEFAULT) {
- fall_thru = new_prio();
- fall_thru->type = AEL_APPCALL;
- fall_thru->app = strdup("Goto");
- snprintf(buf1,sizeof(buf1),"sw-%d-.|10",local_control_statement_count);
- fall_thru->appargs = strdup(buf1);
- linkprio(switch_case, fall_thru, mother_exten);
- } else if (!p2->next) {
- fall_thru = new_prio();
- fall_thru->type = AEL_CONTROL1;
- fall_thru->goto_true = switch_end;
- fall_thru->app = strdup("Goto");
- linkprio(switch_case, fall_thru, mother_exten);
- }
- }
- if (switch_case->return_needed) {
- char buf[2000];
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
- np2->appargs = strdup(buf);
- linkprio(switch_case, np2, mother_exten);
- switch_case-> return_target = np2;
- }
- } else {
- /* what could it be??? */
- }
- }
-
- exten->loop_break = loop_break_save;
- exten->loop_continue = loop_continue_save;
- switch_test->origin = p;
- switch_end->origin = p;
- break;
-
- case PV_MACRO_CALL:
- pr = new_prio();
- pr->type = AEL_APPCALL;
- snprintf(buf1,sizeof(buf1),"%s", p->u1.str);
- for (p2 = p->u2.arglist; p2; p2 = p2->next) {
- strcat(buf1,"|");
- strcat(buf1,p2->u1.str);
- }
- pr->app = strdup("Macro");
- pr->appargs = strdup(buf1);
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_APPLICATION_CALL:
- pr = new_prio();
- pr->type = AEL_APPCALL;
- buf1[0] = 0;
- for (p2 = p->u2.arglist; p2; p2 = p2->next) {
- if (p2 != p->u2.arglist )
- strcat(buf1,"|");
- substitute_commas(p2->u1.str);
- strcat(buf1,p2->u1.str);
- }
- pr->app = strdup(p->u1.str);
- pr->appargs = strdup(buf1);
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_BREAK:
- pr = new_prio();
- pr->type = AEL_CONTROL1; /* simple goto */
- pr->goto_true = exten->loop_break;
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_RETURN: /* hmmmm */
- pr = new_prio();
- pr->type = AEL_RETURN; /* simple goto */
- exten->return_needed++;
- pr->app = strdup("Goto");
- pr->appargs = strdup("");
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
- case PV_CONTINUE:
- pr = new_prio();
- pr->type = AEL_CONTROL1; /* simple goto */
- pr->goto_true = exten->loop_continue;
- pr->origin = p;
- linkprio(exten, pr, mother_exten);
- break;
-
-#ifdef OLD_RAND_ACTION
- case PV_RANDOM:
- control_statement_count++;
- snprintf(new_label,sizeof(new_label),"rand-%s-%d", label, control_statement_count);
- rand_test = new_prio();
- rand_test->type = AEL_RAND_CONTROL;
- snprintf(buf1,sizeof(buf1),"$[%s]",
- p->u1.str );
- rand_test->app = 0;
- rand_test->appargs = strdup(buf1);
- rand_test->origin = p;
-
- rand_end = new_prio();
- rand_end->type = AEL_APPCALL;
- snprintf(buf1,sizeof(buf1),"Finish rand-%s-%d", label, control_statement_count);
- rand_end->app = strdup("NoOp");
- rand_end->appargs = strdup(buf1);
-
- rand_skip = new_prio();
- rand_skip->type = AEL_CONTROL1; /* simple goto */
- rand_skip->goto_true = rand_end;
- rand_skip->origin = p;
-
- rand_test->goto_true = rand_skip; /* +1, really */
-
- linkprio(exten, rand_test, mother_exten);
-
- if (p->u3.else_statements) {
- gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the else statements here */
- }
-
- linkprio(exten, rand_skip, mother_exten);
-
- gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the "true" statements here */
-
- linkprio(exten, rand_end, mother_exten);
-
- break;
-#endif
-
- case PV_IFTIME:
- control_statement_count++;
- snprintf(new_label,sizeof(new_label),"iftime-%s-%d", label, control_statement_count);
-
- if_test = new_prio();
- if_test->type = AEL_IFTIME_CONTROL;
- snprintf(buf1,sizeof(buf1),"%s|%s|%s|%s",
- p->u1.list->u1.str,
- p->u1.list->next->u1.str,
- p->u1.list->next->next->u1.str,
- p->u1.list->next->next->next->u1.str);
- if_test->app = 0;
- if_test->appargs = strdup(buf1);
- if_test->origin = p;
-
- if_end = new_prio();
- if_end->type = AEL_APPCALL;
- snprintf(buf1,sizeof(buf1),"Finish iftime-%s-%d", label, control_statement_count);
- if_end->app = strdup("NoOp");
- if_end->appargs = strdup(buf1);
-
- if (p->u3.else_statements) {
- if_skip = new_prio();
- if_skip->type = AEL_CONTROL1; /* simple goto */
- if_skip->goto_true = if_end;
- if_skip->origin = p;
-
- } else {
- if_skip = 0;
-
- if_test->goto_false = if_end;
- }
-
- if_false = new_prio();
- if_false->type = AEL_CONTROL1;
- if (p->u3.else_statements) {
- if_false->goto_true = if_skip; /* +1 */
- } else {
- if_false->goto_true = if_end;
- }
-
- /* link & load! */
- linkprio(exten, if_test, mother_exten);
- linkprio(exten, if_false, mother_exten);
-
- /* now, put the body of the if here */
-
- gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the statements here */
-
- if (p->u3.else_statements) {
- linkprio(exten, if_skip, mother_exten);
- gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the statements here */
-
- }
-
- linkprio(exten, if_end, mother_exten);
-
- break;
-
- case PV_RANDOM:
- case PV_IF:
- control_statement_count++;
- snprintf(new_label,sizeof(new_label),"if-%s-%d", label, control_statement_count);
-
- if_test = new_prio();
- if_end = new_prio();
- if_test->type = AEL_IF_CONTROL;
- if_end->type = AEL_APPCALL;
- if ( p->type == PV_RANDOM )
- snprintf(buf1,sizeof(buf1),"$[${RAND(0,99)} < (%s)]",p->u1.str);
- else
- snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str);
- if_test->app = 0;
- if_test->appargs = strdup(buf1);
- snprintf(buf1,sizeof(buf1),"Finish if-%s-%d", label, control_statement_count);
- if_end->app = strdup("NoOp");
- if_end->appargs = strdup(buf1);
- if_test->origin = p;
-
- if (p->u3.else_statements) {
- if_skip = new_prio();
- if_skip->type = AEL_CONTROL1; /* simple goto */
- if_skip->goto_true = if_end;
- if_test->goto_false = if_skip;;
- } else {
- if_skip = 0;
- if_test->goto_false = if_end;;
- }
-
- /* link & load! */
- linkprio(exten, if_test, mother_exten);
-
- /* now, put the body of the if here */
-
- gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the statements here */
-
- if (p->u3.else_statements) {
- linkprio(exten, if_skip, mother_exten);
- gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the statements here */
-
- }
-
- linkprio(exten, if_end, mother_exten);
-
- break;
-
- case PV_STATEMENTBLOCK:
- gen_prios(exten, label, p->u1.list, mother_exten, this_context ); /* recurse into the block */
- break;
-
- case PV_CATCH:
- control_statement_count++;
- /* generate an extension with name of catch, put all catch stats
- into this exten! */
- switch_case = new_exten();
- switch_case->context = this_context;
- linkexten(exten,switch_case);
- switch_case->name = strdup(p->u1.str);
- snprintf(new_label,sizeof(new_label),"catch-%s-%d",p->u1.str, control_statement_count);
-
- gen_prios(switch_case, new_label, p->u2.statements,mother_exten,this_context); /* this will link in all the catch body statements here */
- if (switch_case->return_needed) {
- char buf[2000];
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
- np2->appargs = strdup(buf);
- linkprio(switch_case, np2, mother_exten);
- switch_case-> return_target = np2;
- }
-
- break;
- default:
- break;
- }
- }
-}
-
-void set_priorities(struct ael_extension *exten)
-{
- int i;
- struct ael_priority *pr;
- do {
- if (exten->is_switch)
- i = 10;
- else if (exten->regexten)
- i=2;
- else
- i=1;
-
- for (pr=exten->plist; pr; pr=pr->next) {
- pr->priority_num = i;
-
- if (!pr->origin || (pr->origin && pr->origin->type != PV_LABEL) ) /* Labels don't show up in the dialplan,
- but we want them to point to the right
- priority, which would be the next line
- after the label; */
- i++;
- }
-
- exten = exten->next_exten;
- } while ( exten );
-}
-
-void add_extensions(struct ael_extension *exten)
-{
- struct ael_priority *pr;
- char *label=0;
- char realext[AST_MAX_EXTENSION];
- if (!exten) {
- ast_log(LOG_WARNING, "This file is Empty!\n" );
- return;
- }
- do {
- struct ael_priority *last = 0;
-
- memset(realext, '\0', sizeof(realext));
- pbx_substitute_variables_helper(NULL, exten->name, realext, sizeof(realext) - 1);
- if (exten->hints) {
- if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, PRIORITY_HINT, NULL, exten->cidmatch,
- exten->hints, NULL, ast_free, registrar)) {
- ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n",
- exten->name);
- }
- }
-
- for (pr=exten->plist; pr; pr=pr->next) {
- char app[2000];
- char appargs[2000];
-
- /* before we can add the extension, we need to prep the app/appargs;
- the CONTROL types need to be done after the priority numbers are calculated.
- */
- if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ {
- last = pr;
- continue;
- }
-
- if (pr->app)
- strcpy(app, pr->app);
- else
- app[0] = 0;
- if (pr->appargs )
- strcpy(appargs, pr->appargs);
- else
- appargs[0] = 0;
- switch( pr->type ) {
- case AEL_APPCALL:
- /* easy case. Everything is all set up */
- break;
-
- case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */
- /* simple, unconditional goto. */
- strcpy(app,"Goto");
- if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) {
- snprintf(appargs,sizeof(appargs),"%s|%d", pr->goto_true->exten->name, pr->goto_true->priority_num);
- } else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) {
- snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1);
- } else
- snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num);
- break;
-
- case AEL_FOR_CONTROL: /* WHILE loop test, FOR loop test */
- strcpy(app,"GotoIf");
- snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
- break;
-
- case AEL_IF_CONTROL:
- strcpy(app,"GotoIf");
- if (pr->origin->u3.else_statements )
- snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1);
- else
- snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
- break;
-
- case AEL_RAND_CONTROL:
- strcpy(app,"Random");
- snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1);
- break;
-
- case AEL_IFTIME_CONTROL:
- strcpy(app,"GotoIfTime");
- snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2);
- break;
-
- case AEL_RETURN:
- strcpy(app,"Goto");
- snprintf(appargs,sizeof(appargs), "%d", exten->return_target->priority_num);
- break;
-
- default:
- break;
- }
- if (last && last->type == AEL_LABEL ) {
- label = last->origin->u1.str;
- }
- else
- label = 0;
-
- if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, pr->priority_num, (label?label:NULL), exten->cidmatch,
- app, strdup(appargs), ast_free, registrar)) {
- ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num,
- exten->name);
- }
- last = pr;
- }
- exten = exten->next_exten;
- } while ( exten );
-}
-
-static void attach_exten(struct ael_extension **list, struct ael_extension *newmem)
-{
- /* travel to the end of the list... */
- struct ael_extension *lptr;
- if( !*list ) {
- *list = newmem;
- return;
- }
- lptr = *list;
-
- while( lptr->next_exten ) {
- lptr = lptr->next_exten;
- }
- /* lptr should now pointing to the last element in the list; it has a null next_exten pointer */
- lptr->next_exten = newmem;
-}
-
-static pval *get_extension_or_contxt(pval *p)
-{
- while( p && p->type != PV_EXTENSION && p->type != PV_CONTEXT && p->type != PV_MACRO ) {
-
- p = p->dad;
- }
-
- return p;
-}
-
-static pval *get_contxt(pval *p)
-{
- while( p && p->type != PV_CONTEXT && p->type != PV_MACRO ) {
-
- p = p->dad;
- }
-
- return p;
-}
-
-static void fix_gotos_in_extensions(struct ael_extension *exten)
-{
- struct ael_extension *e;
- for(e=exten;e;e=e->next_exten) {
-
- struct ael_priority *p;
- for(p=e->plist;p;p=p->next) {
-
- if( p->origin && p->origin->type == PV_GOTO && p->origin->u3.goto_target_in_case ) {
-
- /* fix the extension of the goto target to the actual extension in the post-compiled dialplan */
-
- pval *target = p->origin->u2.goto_target;
- struct ael_extension *z = target->u3.compiled_label;
- pval *pv2 = p->origin;
- char buf1[500];
- char *apparg_save = p->appargs;
-
- p->appargs = 0;
- if (!pv2->u1.list->next) /* just one -- it won't hurt to repeat the extension */ {
- snprintf(buf1,sizeof(buf1),"%s|%s", z->name, pv2->u1.list->u1.str);
- p->appargs = strdup(buf1);
-
- } else if (pv2->u1.list->next && !pv2->u1.list->next->next) /* two */ {
- snprintf(buf1,sizeof(buf1),"%s|%s", z->name, pv2->u1.list->next->u1.str);
- p->appargs = strdup(buf1);
- } else if (pv2->u1.list->next && pv2->u1.list->next->next) {
- snprintf(buf1,sizeof(buf1),"%s|%s|%s", pv2->u1.list->u1.str,
- z->name,
- pv2->u1.list->next->next->u1.str);
- p->appargs = strdup(buf1);
- }
- else
- printf("WHAT? The goto doesn't fall into one of three cases for GOTO????\n");
-
- if( apparg_save ) {
- free(apparg_save);
- }
- }
- }
- }
-}
-
-
-void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root)
-{
- pval *p,*p2;
- struct ast_context *context;
- char buf[2000];
- struct ael_extension *exten;
- struct ael_extension *exten_list = 0;
-
- for (p=root; p; p=p->next ) { /* do the globals first, so they'll be there
- when we try to eval them */
- switch (p->type) {
- case PV_GLOBALS:
- /* just VARDEC elements */
- for (p2=p->u1.list; p2; p2=p2->next) {
- char buf2[2000];
- snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val);
- pbx_builtin_setvar(NULL, buf2);
- }
- break;
- default:
- break;
- }
- }
-
- for (p=root; p; p=p->next ) {
- pval *lp;
- int argc;
-
- switch (p->type) {
- case PV_MACRO:
- strcpy(buf,"macro-");
- strcat(buf,p->u1.str);
- context = ast_context_create(local_contexts, buf, registrar);
-
- exten = new_exten();
- exten->context = context;
- exten->name = strdup("s");
- argc = 1;
- for (lp=p->u2.arglist; lp; lp=lp->next) {
- /* for each arg, set up a "Set" command */
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("Set");
- snprintf(buf,sizeof(buf),"%s=${ARG%d}", lp->u1.str, argc++);
- remove_spaces_before_equals(buf);
- np2->appargs = strdup(buf);
- linkprio(exten, np2, NULL);
- }
- /* add any includes */
- for (p2=p->u3.macro_statements; p2; p2=p2->next) {
- pval *p3;
-
- switch (p2->type) {
- case PV_INCLUDES:
- for (p3 = p2->u1.list; p3 ;p3=p3->next) {
- if ( p3->u2.arglist ) {
- snprintf(buf,sizeof(buf), "%s|%s|%s|%s|%s",
- p3->u1.str,
- p3->u2.arglist->u1.str,
- p3->u2.arglist->next->u1.str,
- p3->u2.arglist->next->next->u1.str,
- p3->u2.arglist->next->next->next->u1.str);
- ast_context_add_include2(context, buf, registrar);
- } else
- ast_context_add_include2(context, p3->u1.str, registrar);
- }
- break;
- default:
- break;
- }
- }
- /* CONTAINS APPCALLS, CATCH, just like extensions... */
- gen_prios(exten, p->u1.str, p->u3.macro_statements, 0, context );
- if (exten->return_needed) {
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name);
- np2->appargs = strdup(buf);
- linkprio(exten, np2, NULL);
- exten-> return_target = np2;
- }
-
- set_priorities(exten);
- attach_exten(&exten_list, exten);
- break;
-
- case PV_GLOBALS:
- /* already done */
- break;
-
- case PV_CONTEXT:
- context = ast_context_find_or_create(local_contexts, p->u1.str, registrar);
-
- /* contexts contain: ignorepat, includes, switches, eswitches, extensions, */
- for (p2=p->u2.statements; p2; p2=p2->next) {
- pval *p3;
- char *s3;
-
- switch (p2->type) {
- case PV_EXTENSION:
- exten = new_exten();
- exten->name = strdup(p2->u1.str);
- exten->context = context;
-
- if( (s3=strchr(exten->name, '/') ) != 0 )
- {
- *s3 = 0;
- exten->cidmatch = s3+1;
- }
-
- if ( p2->u3.hints )
- exten->hints = strdup(p2->u3.hints);
- exten->regexten = p2->u4.regexten;
- gen_prios(exten, p->u1.str, p2->u2.statements, 0, context );
- if (exten->return_needed) {
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"End of Extension %s", exten->name);
- np2->appargs = strdup(buf);
- linkprio(exten, np2, NULL);
- exten-> return_target = np2;
- }
- /* is the last priority in the extension a label? Then add a trailing no-op */
- if( !exten->plist_last )
- {
- ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Empty Extension!\n",
- p2->filename, p2->startline, p2->endline);
- }
-
- if ( exten->plist_last && exten->plist_last->type == AEL_LABEL ) {
- struct ael_priority *np2 = new_prio();
- np2->type = AEL_APPCALL;
- np2->app = strdup("NoOp");
- snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str);
- np2->appargs = strdup(buf);
- linkprio(exten, np2, NULL);
- }
-
- set_priorities(exten);
- attach_exten(&exten_list, exten);
- break;
-
- case PV_IGNOREPAT:
- ast_context_add_ignorepat2(context, p2->u1.str, registrar);
- break;
-
- case PV_INCLUDES:
- for (p3 = p2->u1.list; p3 ;p3=p3->next) {
- if ( p3->u2.arglist ) {
- snprintf(buf,sizeof(buf), "%s|%s|%s|%s|%s",
- p3->u1.str,
- p3->u2.arglist->u1.str,
- p3->u2.arglist->next->u1.str,
- p3->u2.arglist->next->next->u1.str,
- p3->u2.arglist->next->next->next->u1.str);
- ast_context_add_include2(context, buf, registrar);
- } else
- ast_context_add_include2(context, p3->u1.str, registrar);
- }
- break;
-
- case PV_SWITCHES:
- for (p3 = p2->u1.list; p3 ;p3=p3->next) {
- char *c = strchr(p3->u1.str, '/');
- if (c) {
- *c = '\0';
- c++;
- } else
- c = "";
-
- ast_context_add_switch2(context, p3->u1.str, c, 0, registrar);
- }
- break;
-
- case PV_ESWITCHES:
- for (p3 = p2->u1.list; p3 ;p3=p3->next) {
- char *c = strchr(p3->u1.str, '/');
- if (c) {
- *c = '\0';
- c++;
- } else
- c = "";
-
- ast_context_add_switch2(context, p3->u1.str, c, 1, registrar);
- }
- break;
- default:
- break;
- }
- }
-
- break;
-
- default:
- /* huh? what? */
- break;
-
- }
- }
- /* moved these from being done after a macro or extension were processed,
- to after all processing is done, for the sake of fixing gotos to labels inside cases... */
- /* I guess this would be considered 2nd pass of compiler now... */
- fix_gotos_in_extensions(exten_list); /* find and fix extension ref in gotos to labels that are in case statements */
- add_extensions(exten_list); /* actually makes calls to create priorities in ast_contexts -- feeds dialplan to asterisk */
- destroy_extensions(exten_list); /* all that remains is an empty husk, discard of it as is proper */
-
-}
-
-
-static int aeldebug = 0;
-
-/* interface stuff */
-
-/* if all the below are static, who cares if they are present? */
-
-static int pbx_load_module(void)
-{
- int errs=0, sem_err=0, sem_warn=0, sem_note=0;
- char *rfilename;
- struct ast_context *local_contexts=NULL, *con;
- struct pval *parse_tree;
-
- ast_log(LOG_NOTICE, "Starting AEL load process.\n");
- if (config[0] == '/')
- rfilename = (char *)config;
- else {
- rfilename = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
- sprintf(rfilename, "%s/%s", ast_config_AST_CONFIG_DIR, config);
- }
- ast_log(LOG_NOTICE, "AEL load process: calculated config file name '%s'.\n", rfilename);
-
- if (access(rfilename,R_OK) != 0) {
- ast_log(LOG_NOTICE, "File %s not found; AEL declining load\n", rfilename);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- parse_tree = ael2_parse(rfilename, &errs);
- ast_log(LOG_NOTICE, "AEL load process: parsed config file name '%s'.\n", rfilename);
- ael2_semantic_check(parse_tree, &sem_err, &sem_warn, &sem_note);
- if (errs == 0 && sem_err == 0) {
- ast_log(LOG_NOTICE, "AEL load process: checked config file name '%s'.\n", rfilename);
- ast_compile_ael2(&local_contexts, parse_tree);
- ast_log(LOG_NOTICE, "AEL load process: compiled config file name '%s'.\n", rfilename);
-
- ast_merge_contexts_and_delete(&local_contexts, registrar);
- ast_log(LOG_NOTICE, "AEL load process: merged config file name '%s'.\n", rfilename);
- for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
- ast_context_verify_includes(con);
- ast_log(LOG_NOTICE, "AEL load process: verified config file name '%s'.\n", rfilename);
- } else {
- ast_log(LOG_ERROR, "Sorry, but %d syntax errors and %d semantic errors were detected. It doesn't make sense to compile.\n", errs, sem_err);
- destroy_pval(parse_tree); /* free up the memory */
- return AST_MODULE_LOAD_DECLINE;
- }
- destroy_pval(parse_tree); /* free up the memory */
-
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-/* CLI interface */
-static int ael2_debug_read(int fd, int argc, char *argv[])
-{
- aeldebug |= DEBUG_READ;
- return 0;
-}
-
-static int ael2_debug_tokens(int fd, int argc, char *argv[])
-{
- aeldebug |= DEBUG_TOKENS;
- return 0;
-}
-
-static int ael2_debug_macros(int fd, int argc, char *argv[])
-{
- aeldebug |= DEBUG_MACROS;
- return 0;
-}
-
-static int ael2_debug_contexts(int fd, int argc, char *argv[])
-{
- aeldebug |= DEBUG_CONTEXTS;
- return 0;
-}
-
-static int ael2_no_debug(int fd, int argc, char *argv[])
-{
- aeldebug = 0;
- return 0;
-}
-
-static int ael2_reload(int fd, int argc, char *argv[])
-{
- return (pbx_load_module());
-}
-
-static struct ast_cli_entry cli_ael_no_debug = {
- { "ael", "no", "debug", NULL },
- ael2_no_debug, NULL,
- NULL };
-
-static struct ast_cli_entry cli_ael[] = {
- { { "ael", "reload", NULL },
- ael2_reload, "Reload AEL configuration" },
-
- { { "ael", "debug", "read", NULL },
- ael2_debug_read, "Enable AEL read debug (does nothing)" },
-
- { { "ael", "debug", "tokens", NULL },
- ael2_debug_tokens, "Enable AEL tokens debug (does nothing)" },
-
- { { "ael", "debug", "macros", NULL },
- ael2_debug_macros, "Enable AEL macros debug (does nothing)" },
-
- { { "ael", "debug", "contexts", NULL },
- ael2_debug_contexts, "Enable AEL contexts debug (does nothing)" },
-
- { { "ael", "nodebug", NULL },
- ael2_no_debug, "Disable AEL debug messages",
- NULL, NULL, &cli_ael_no_debug },
-};
-
-static int unload_module(void)
-{
- ast_context_destroy(NULL, registrar);
- ast_cli_unregister_multiple(cli_ael, sizeof(cli_ael) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-static int load_module(void)
-{
- ast_cli_register_multiple(cli_ael, sizeof(cli_ael) / sizeof(struct ast_cli_entry));
- return (pbx_load_module());
-}
-
-static int reload(void)
-{
- return pbx_load_module();
-}
-
-#ifdef STANDALONE_AEL
-#define AST_MODULE "ael"
-int ael_external_load_module(void);
-int ael_external_load_module(void)
-{
- pbx_load_module();
- return 1;
-}
-#endif
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Extension Language Compiler",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
-
-/* DESTROY the PVAL tree ============================================================================ */
-
-
-
-void destroy_pval_item(pval *item)
-{
- if (item == NULL) {
- ast_log(LOG_WARNING, "null item\n");
- return;
- }
-
- if (item->filename)
- free(item->filename);
-
- switch (item->type) {
- case PV_WORD:
- /* fields: item->u1.str == string associated with this (word). */
- if (item->u1.str )
- free(item->u1.str);
- if ( item->u2.arglist )
- destroy_pval(item->u2.arglist);
- break;
-
- case PV_MACRO:
- /* fields: item->u1.str == name of macro
- item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
-
- item->u3.macro_statements == pval list of statements in macro body.
- */
- destroy_pval(item->u2.arglist);
- if (item->u1.str )
- free(item->u1.str);
- destroy_pval(item->u3.macro_statements);
- break;
-
- case PV_CONTEXT:
- /* fields: item->u1.str == name of context
- item->u2.statements == pval list of statements in context body
- item->u3.abstract == int 1 if an abstract keyword were present
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_MACRO_CALL:
- /* fields: item->u1.str == name of macro to call
- item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.arglist);
- break;
-
- case PV_APPLICATION_CALL:
- /* fields: item->u1.str == name of application to call
- item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
- item->u2.arglist->u1.str == argument
- item->u2.arglist->next == next arg
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.arglist);
- break;
-
- case PV_CASE:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_PATTERN:
- /* fields: item->u1.str == value of case
- item->u2.statements == pval list of statements under the case
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_DEFAULT:
- /* fields:
- item->u2.statements == pval list of statements under the case
- */
- destroy_pval(item->u2.statements);
- break;
-
- case PV_CATCH:
- /* fields: item->u1.str == name of extension to catch
- item->u2.statements == pval list of statements in context body
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_SWITCHES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- destroy_pval(item->u1.list);
- break;
-
- case PV_ESWITCHES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- */
- destroy_pval(item->u1.list);
- break;
-
- case PV_INCLUDES:
- /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
- item->u2.arglist == pval list of 4 PV_WORD elements for time values
- */
- destroy_pval(item->u1.list);
- break;
-
- case PV_STATEMENTBLOCK:
- /* fields: item->u1.list == pval list of statements in block, one per entry in the list
- */
- destroy_pval(item->u1.list);
- break;
-
- case PV_VARDEC:
- /* fields: item->u1.str == variable name
- item->u2.val == variable value to assign
- */
- if (item->u1.str)
- free(item->u1.str);
- if (item->u2.val)
- free(item->u2.val);
- break;
-
- case PV_GOTO:
- /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
- item->u1.list->u1.str == where the data on a PV_WORD will always be.
- */
-
- destroy_pval(item->u1.list);
- break;
-
- case PV_LABEL:
- /* fields: item->u1.str == label name
- */
- if (item->u1.str)
- free(item->u1.str);
- break;
-
- case PV_FOR:
- /* fields: item->u1.for_init == a string containing the initalizer
- item->u2.for_test == a string containing the loop test
- item->u3.for_inc == a string containing the loop increment
-
- item->u4.for_statements == a pval list of statements in the for ()
- */
- if (item->u1.for_init)
- free(item->u1.for_init);
- if (item->u2.for_test)
- free(item->u2.for_test);
- if (item->u3.for_inc)
- free(item->u3.for_inc);
- destroy_pval(item->u4.for_statements);
- break;
-
- case PV_WHILE:
- /* fields: item->u1.str == the while conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the while ()
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_BREAK:
- /* fields: none
- */
- break;
-
- case PV_RETURN:
- /* fields: none
- */
- break;
-
- case PV_CONTINUE:
- /* fields: none
- */
- break;
-
- case PV_IFTIME:
- /* fields: item->u1.list == the 4 time values, in PV_WORD structs, linked list
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- destroy_pval(item->u1.list);
- destroy_pval(item->u2.statements);
- if (item->u3.else_statements) {
- destroy_pval(item->u3.else_statements);
- }
- break;
-
- case PV_RANDOM:
- /* fields: item->u1.str == the random percentage, as supplied by user
-
- item->u2.statements == a pval list of statements in the true part ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- fall thru to If */
- case PV_IF:
- /* fields: item->u1.str == the if conditional, as supplied by user
-
- item->u2.statements == a pval list of statements in the if ()
- item->u3.else_statements == a pval list of statements in the else
- (could be zero)
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- if (item->u3.else_statements) {
- destroy_pval(item->u3.else_statements);
- }
- break;
-
- case PV_SWITCH:
- /* fields: item->u1.str == the switch expression
-
- item->u2.statements == a pval list of statements in the switch,
- (will be case statements, most likely!)
- */
- if (item->u1.str)
- free(item->u1.str);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_EXTENSION:
- /* fields: item->u1.str == the extension name, label, whatever it's called
-
- item->u2.statements == a pval list of statements in the extension
- item->u3.hints == a char * hint argument
- item->u4.regexten == an int boolean. non-zero says that regexten was specified
- */
- if (item->u1.str)
- free(item->u1.str);
- if (item->u3.hints)
- free(item->u3.hints);
- destroy_pval(item->u2.statements);
- break;
-
- case PV_IGNOREPAT:
- /* fields: item->u1.str == the ignorepat data
- */
- if (item->u1.str)
- free(item->u1.str);
- break;
-
- case PV_GLOBALS:
- /* fields: item->u1.statements == pval list of statements, usually vardecs
- */
- destroy_pval(item->u1.statements);
- break;
- }
- free(item);
-}
-
-void destroy_pval(pval *item)
-{
- pval *i,*nxt;
-
- for (i=item; i; i=nxt) {
- nxt = i->next;
-
- destroy_pval_item(i);
- }
-}
-
-#ifdef AAL_ARGCHECK
-static char *ael_funclist[] =
-{
- "AGENT",
- "ARRAY",
- "BASE64_DECODE",
- "BASE64_ENCODE",
- "CALLERID",
- "CDR",
- "CHANNEL",
- "CHECKSIPDOMAIN",
- "CHECK_MD5",
- "CURL",
- "CUT",
- "DB",
- "DB_EXISTS",
- "DUNDILOOKUP",
- "ENUMLOOKUP",
- "ENV",
- "EVAL",
- "EXISTS",
- "FIELDQTY",
- "FILTER",
- "GROUP",
- "GROUP_COUNT",
- "GROUP_LIST",
- "GROUP_MATCH_COUNT",
- "IAXPEER",
- "IF",
- "IFTIME",
- "ISNULL",
- "KEYPADHASH",
- "LANGUAGE",
- "LEN",
- "MATH",
- "MD5",
- "MUSICCLASS",
- "QUEUEAGENTCOUNT",
- "QUEUE_MEMBER_COUNT",
- "QUEUE_MEMBER_LIST",
- "QUOTE",
- "RAND",
- "REGEX",
- "SET",
- "SHA1",
- "SIPCHANINFO",
- "SIPPEER",
- "SIP_HEADER",
- "SORT",
- "STAT",
- "STRFTIME",
- "STRPTIME",
- "TIMEOUT",
- "TXTCIDNAME",
- "URIDECODE",
- "URIENCODE",
- "VMCOUNT"
-};
-
-
-int ael_is_funcname(char *name)
-{
- int s,t;
- t = sizeof(ael_funclist)/sizeof(char*);
- s = 0;
- while ((s < t) && strcasecmp(name, ael_funclist[s]))
- s++;
- if ( s < t )
- return 1;
- else
- return 0;
-}
-#endif
diff --git a/1.4/pbx/pbx_config.c b/1.4/pbx/pbx_config.c
deleted file mode 100644
index 565d7d836..000000000
--- a/1.4/pbx/pbx_config.c
+++ /dev/null
@@ -1,2492 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Populate and remember extensions from static config file
- *
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/cli.h"
-#include "asterisk/callerid.h"
-
-static char *config = "extensions.conf";
-static char *registrar = "pbx_config";
-static char userscontext[AST_MAX_EXTENSION] = "default";
-
-static int static_config = 0;
-static int write_protect_config = 1;
-static int autofallthrough_config = 1;
-static int clearglobalvars_config = 0;
-
-AST_MUTEX_DEFINE_STATIC(save_dialplan_lock);
-
-static struct ast_context *local_contexts = NULL;
-
-/*
- * Help for commands provided by this module ...
- */
-static char context_add_extension_help[] =
-"Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n"
-" into <context> [replace]\n\n"
-" This command will add new extension into <context>. If there is an\n"
-" existence of extension with the same priority and last 'replace'\n"
-" arguments is given here we simply replace this extension.\n"
-"\n"
-"Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n"
-" Now, you can dial 6123 and talk to Markster :)\n";
-
-static char context_remove_extension_help[] =
-"Usage: dialplan remove extension exten@context [priority]\n"
-" Remove an extension from a given context. If a priority\n"
-" is given, only that specific priority from the given extension\n"
-" will be removed.\n";
-
-static char context_add_ignorepat_help[] =
-"Usage: dialplan add ignorepat <pattern> into <context>\n"
-" This command adds a new ignore pattern into context <context>\n"
-"\n"
-"Example: dialplan add ignorepat _3XX into local\n";
-
-static char context_remove_ignorepat_help[] =
-"Usage: dialplan remove ignorepat <pattern> from <context>\n"
-" This command removes an ignore pattern from context <context>\n"
-"\n"
-"Example: dialplan remove ignorepat _3XX from local\n";
-
-static char context_add_include_help[] =
-"Usage: dialplan add include <context> into <context>\n"
-" Include a context in another context.\n";
-
-static char context_remove_include_help[] =
-"Usage: dialplan remove include <context> from <context>\n"
-" Remove an included context from another context.\n";
-
-static char save_dialplan_help[] =
-"Usage: dialplan save [/path/to/extension/file]\n"
-" Save dialplan created by pbx_config module.\n"
-"\n"
-"Example: dialplan save (/etc/asterisk/extensions.conf)\n"
-" dialplan save /home/markster (/home/markster/extensions.conf)\n";
-
-static char reload_extensions_help[] =
-"Usage: dialplan reload\n"
-" reload extensions.conf without reloading any other modules\n"
-" This command does not delete global variables unless\n"
-" clearglobalvars is set to yes in extensions.conf\n";
-
-/*
- * Implementation of functions provided by this module
- */
-
-/*!
- * REMOVE INCLUDE command stuff
- */
-static int handle_context_dont_include_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 5)
- return RESULT_SHOWUSAGE;
-
- if (strcmp(argv[3], "into"))
- return RESULT_SHOWUSAGE;
-
- if (!ast_context_remove_include(argv[4], argv[2], registrar)) {
- ast_cli(fd, "We are not including '%s' into '%s' now\n",
- argv[2], argv[4]);
- return RESULT_SUCCESS;
- }
-
- ast_cli(fd, "Failed to remove '%s' include from '%s' context\n",
- argv[2], argv[4]);
- return RESULT_FAILURE;
-}
-
-static int handle_context_remove_include(int fd, int argc, char *argv[])
-{
- if (argc != 6)
- return RESULT_SHOWUSAGE;
-
- if (strcmp(argv[4], "into"))
- return RESULT_SHOWUSAGE;
-
- if (!ast_context_remove_include(argv[5], argv[3], registrar)) {
- ast_cli(fd, "We are not including '%s' into '%s' now\n",
- argv[3], argv[5]);
- return RESULT_SUCCESS;
- }
-
- ast_cli(fd, "Failed to remove '%s' include from '%s' context\n",
- argv[3], argv[5]);
- return RESULT_FAILURE;
-}
-
-/*! \brief return true if 'name' is included by context c */
-static int lookup_ci(struct ast_context *c, const char *name)
-{
- struct ast_include *i = NULL;
-
- if (ast_lock_context(c)) /* error, skip */
- return 0;
- while ( (i = ast_walk_context_includes(c, i)) )
- if (!strcmp(name, ast_get_include_name(i)))
- break;
- ast_unlock_context(c);
- return i ? -1 /* success */ : 0;
-}
-
-/*! \brief return true if 'name' is in the ignorepats for context c */
-static int lookup_c_ip(struct ast_context *c, const char *name)
-{
- struct ast_ignorepat *ip = NULL;
-
- if (ast_lock_context(c)) /* error, skip */
- return 0;
- while ( (ip = ast_walk_context_ignorepats(c, ip)) )
- if (!strcmp(name, ast_get_ignorepat_name(ip)))
- break;
- ast_unlock_context(c);
- return ip ? -1 /* success */ : 0;
-}
-
-/*! \brief moves to the n-th word in the string, or empty string if none */
-static const char *skip_words(const char *p, int n)
-{
- int in_blank = 0;
- for (;n && *p; p++) {
- if (isblank(*p) /* XXX order is important */ && !in_blank) {
- n--; /* one word is gone */
- in_blank = 1;
- } else if (/* !is_blank(*p), we know already, && */ in_blank) {
- in_blank = 0;
- }
- }
- return p;
-}
-
-/*! \brief match the first 'len' chars of word. len==0 always succeeds */
-static int partial_match(const char *s, const char *word, int len)
-{
- return (len == 0 || !strncmp(s, word, len));
-}
-
-/*! \brief split extension\@context in two parts, return -1 on error.
- * The return string is malloc'ed and pointed by *ext
- */
-static int split_ec(const char *src, char **ext, char ** const ctx)
-{
- char *c, *e = ast_strdup(src); /* now src is not used anymore */
-
- if (e == NULL)
- return -1; /* malloc error */
- /* now, parse values from 'exten@context' */
- *ext = e;
- c = strchr(e, '@');
- if (c == NULL) /* no context part */
- *ctx = ""; /* it is not overwritten, anyways */
- else { /* found context, check for duplicity ... */
- *c++ = '\0';
- *ctx = c;
- if (strchr(c, '@')) { /* two @, not allowed */
- free(e);
- return -1;
- }
- }
- return 0;
-}
-
-/* _X_ is the string we need to complete */
-static char *complete_context_dont_include_deprecated(const char *line, const char *word,
- int pos, int state)
-{
- int which = 0;
- char *res = NULL;
- int len = strlen(word); /* how many bytes to match */
- struct ast_context *c = NULL;
-
- if (pos == 2) { /* "dont include _X_" */
- if (ast_wrlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- return NULL;
- }
- /* walk contexts and their includes, return the n-th match */
- while (!res && (c = ast_walk_contexts(c))) {
- struct ast_include *i = NULL;
-
- if (ast_lock_context(c)) /* error ? skip this one */
- continue;
-
- while ( !res && (i = ast_walk_context_includes(c, i)) ) {
- const char *i_name = ast_get_include_name(i);
- struct ast_context *nc = NULL;
- int already_served = 0;
-
- if (!partial_match(i_name, word, len))
- continue; /* not matched */
-
- /* check if this include is already served or not */
-
- /* go through all contexts again till we reach actual
- * context or already_served = 1
- */
- while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served)
- already_served = lookup_ci(nc, i_name);
-
- if (!already_served && ++which > state)
- res = strdup(i_name);
- }
- ast_unlock_context(c);
- }
-
- ast_unlock_contexts();
- return res;
- } else if (pos == 3) { /* "dont include CTX _X_" */
- /*
- * complete as 'in', but only if previous context is really
- * included somewhere
- */
- char *context, *dupline;
- const char *s = skip_words(line, 2); /* skip 'dont' 'include' */
-
- if (state > 0)
- return NULL;
- context = dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
- strsep(&dupline, " ");
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock contexts list\n");
- free(context);
- return NULL;
- }
-
- /* go through all contexts and check if is included ... */
- while (!res && (c = ast_walk_contexts(c)))
- if (lookup_ci(c, context)) /* context is really included, complete "in" command */
- res = strdup("in");
- ast_unlock_contexts();
- if (!res)
- ast_log(LOG_WARNING, "%s not included anywhere\n", context);
- free(context);
- return res;
- } else if (pos == 4) { /* "dont include CTX in _X_" */
- /*
- * Context from which we removing include ...
- */
- char *context, *dupline, *in;
- const char *s = skip_words(line, 2); /* skip 'dont' 'include' */
- context = dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
-
- strsep(&dupline, " "); /* skip context */
-
- /* third word must be 'in' */
- in = strsep(&dupline, " ");
- if (!in || strcmp(in, "in")) {
- free(context);
- return NULL;
- }
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- free(context);
- return NULL;
- }
-
- /* walk through all contexts ... */
- c = NULL;
- while ( !res && (c = ast_walk_contexts(c))) {
- const char *c_name = ast_get_context_name(c);
- if (!partial_match(c_name, word, len)) /* not a good target */
- continue;
- /* walk through all includes and check if it is our context */
- if (lookup_ci(c, context) && ++which > state)
- res = strdup(c_name);
- }
- ast_unlock_contexts();
- free(context);
- return res;
- }
-
- return NULL;
-}
-
-static char *complete_context_remove_include(const char *line, const char *word,
- int pos, int state)
-{
- int which = 0;
- char *res = NULL;
- int len = strlen(word); /* how many bytes to match */
- struct ast_context *c = NULL;
-
- if (pos == 3) { /* "dialplan remove include _X_" */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- return NULL;
- }
- /* walk contexts and their includes, return the n-th match */
- while (!res && (c = ast_walk_contexts(c))) {
- struct ast_include *i = NULL;
-
- if (ast_lock_context(c)) /* error ? skip this one */
- continue;
-
- while ( !res && (i = ast_walk_context_includes(c, i)) ) {
- const char *i_name = ast_get_include_name(i);
- struct ast_context *nc = NULL;
- int already_served = 0;
-
- if (!partial_match(i_name, word, len))
- continue; /* not matched */
-
- /* check if this include is already served or not */
-
- /* go through all contexts again till we reach actual
- * context or already_served = 1
- */
- while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served)
- already_served = lookup_ci(nc, i_name);
-
- if (!already_served && ++which > state)
- res = strdup(i_name);
- }
- ast_unlock_context(c);
- }
-
- ast_unlock_contexts();
- return res;
- } else if (pos == 4) { /* "dialplan remove include CTX _X_" */
- /*
- * complete as 'from', but only if previous context is really
- * included somewhere
- */
- char *context, *dupline;
- const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'include' */
-
- if (state > 0)
- return NULL;
- context = dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
- strsep(&dupline, " ");
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock contexts list\n");
- free(context);
- return NULL;
- }
-
- /* go through all contexts and check if is included ... */
- while (!res && (c = ast_walk_contexts(c)))
- if (lookup_ci(c, context)) /* context is really included, complete "from" command */
- res = strdup("from");
- ast_unlock_contexts();
- if (!res)
- ast_log(LOG_WARNING, "%s not included anywhere\n", context);
- free(context);
- return res;
- } else if (pos == 5) { /* "dialplan remove include CTX from _X_" */
- /*
- * Context from which we removing include ...
- */
- char *context, *dupline, *from;
- const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'include' */
- context = dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
-
- strsep(&dupline, " "); /* skip context */
-
- /* fourth word must be 'from' */
- from = strsep(&dupline, " ");
- if (!from || strcmp(from, "from")) {
- free(context);
- return NULL;
- }
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- free(context);
- return NULL;
- }
-
- /* walk through all contexts ... */
- c = NULL;
- while ( !res && (c = ast_walk_contexts(c))) {
- const char *c_name = ast_get_context_name(c);
- if (!partial_match(c_name, word, len)) /* not a good target */
- continue;
- /* walk through all includes and check if it is our context */
- if (lookup_ci(c, context) && ++which > state)
- res = strdup(c_name);
- }
- ast_unlock_contexts();
- free(context);
- return res;
- }
-
- return NULL;
-}
-
-/*!
- * REMOVE EXTENSION command stuff
- */
-static int handle_context_remove_extension_deprecated(int fd, int argc, char *argv[])
-{
- int removing_priority = 0;
- char *exten, *context;
- int ret = RESULT_FAILURE;
-
- if (argc != 4 && argc != 3) return RESULT_SHOWUSAGE;
-
- /*
- * Priority input checking ...
- */
- if (argc == 4) {
- char *c = argv[3];
-
- /* check for digits in whole parameter for right priority ...
- * why? because atoi (strtol) returns 0 if any characters in
- * string and whole extension will be removed, it's not good
- */
- if (!strcmp("hint", c))
- removing_priority = PRIORITY_HINT;
- else {
- while (*c && isdigit(*c))
- c++;
- if (*c) { /* non-digit in string */
- ast_cli(fd, "Invalid priority '%s'\n", argv[3]);
- return RESULT_FAILURE;
- }
- removing_priority = atoi(argv[3]);
- }
-
- if (removing_priority == 0) {
- ast_cli(fd, "If you want to remove whole extension, please " \
- "omit priority argument\n");
- return RESULT_FAILURE;
- }
- }
-
- /* XXX original overwrote argv[2] */
- /*
- * Format exten@context checking ...
- */
- if (split_ec(argv[2], &exten, &context))
- return RESULT_FAILURE; /* XXX malloc failure */
- if ((!strlen(exten)) || (!(strlen(context)))) {
- ast_cli(fd, "Missing extension or context name in second argument '%s'\n",
- argv[2]);
- free(exten);
- return RESULT_FAILURE;
- }
-
- if (!ast_context_remove_extension(context, exten, removing_priority, registrar)) {
- if (!removing_priority)
- ast_cli(fd, "Whole extension %s@%s removed\n",
- exten, context);
- else
- ast_cli(fd, "Extension %s@%s with priority %d removed\n",
- exten, context, removing_priority);
-
- ret = RESULT_SUCCESS;
- } else {
- ast_cli(fd, "Failed to remove extension %s@%s\n", exten, context);
- ret = RESULT_FAILURE;
- }
- free(exten);
- return ret;
-}
-
-static int handle_context_remove_extension(int fd, int argc, char *argv[])
-{
- int removing_priority = 0;
- char *exten, *context;
- int ret = RESULT_FAILURE;
-
- if (argc != 5 && argc != 4) return RESULT_SHOWUSAGE;
-
- /*
- * Priority input checking ...
- */
- if (argc == 5) {
- char *c = argv[4];
-
- /* check for digits in whole parameter for right priority ...
- * why? because atoi (strtol) returns 0 if any characters in
- * string and whole extension will be removed, it's not good
- */
- if (!strcmp("hint", c))
- removing_priority = PRIORITY_HINT;
- else {
- while (*c && isdigit(*c))
- c++;
- if (*c) { /* non-digit in string */
- ast_cli(fd, "Invalid priority '%s'\n", argv[4]);
- return RESULT_FAILURE;
- }
- removing_priority = atoi(argv[4]);
- }
-
- if (removing_priority == 0) {
- ast_cli(fd, "If you want to remove whole extension, please " \
- "omit priority argument\n");
- return RESULT_FAILURE;
- }
- }
-
- /* XXX original overwrote argv[3] */
- /*
- * Format exten@context checking ...
- */
- if (split_ec(argv[3], &exten, &context))
- return RESULT_FAILURE; /* XXX malloc failure */
- if ((!strlen(exten)) || (!(strlen(context)))) {
- ast_cli(fd, "Missing extension or context name in third argument '%s'\n",
- argv[3]);
- free(exten);
- return RESULT_FAILURE;
- }
-
- if (!ast_context_remove_extension(context, exten, removing_priority, registrar)) {
- if (!removing_priority)
- ast_cli(fd, "Whole extension %s@%s removed\n",
- exten, context);
- else
- ast_cli(fd, "Extension %s@%s with priority %d removed\n",
- exten, context, removing_priority);
-
- ret = RESULT_SUCCESS;
- } else {
- ast_cli(fd, "Failed to remove extension %s@%s\n", exten, context);
- ret = RESULT_FAILURE;
- }
- free(exten);
- return ret;
-}
-
-#define BROKEN_READLINE 1
-
-#ifdef BROKEN_READLINE
-/*
- * There is one funny thing, when you have word like 300@ and you hit
- * <tab>, you arguments will like as your word is '300 ', so it '@'
- * characters acts sometimes as word delimiter and sometimes as a part
- * of word
- *
- * This fix function, allocates new word variable and store here every
- * time xxx@yyy always as one word and correct pos is set too
- *
- * It's ugly, I know, but I'm waiting for Mark suggestion if upper is
- * bug or feature ...
- */
-static int fix_complete_args(const char *line, char **word, int *pos)
-{
- char *_line, *_strsep_line, *_previous_word = NULL, *_word = NULL;
- int words = 0;
-
- _line = strdup(line);
-
- _strsep_line = _line;
- while (_strsep_line) {
- _previous_word = _word;
- _word = strsep(&_strsep_line, " ");
-
- if (_word && strlen(_word)) words++;
- }
-
-
- if (_word || _previous_word) {
- if (_word) {
- if (!strlen(_word)) words++;
- *word = strdup(_word);
- } else
- *word = strdup(_previous_word);
- *pos = words - 1;
- free(_line);
- return 0;
- }
-
- free(_line);
- return -1;
-}
-#endif /* BROKEN_READLINE */
-
-static char *complete_context_remove_extension_deprecated(const char *line, const char *word, int pos,
- int state)
-{
- char *ret = NULL;
- int which = 0;
-
-#ifdef BROKEN_READLINE
- char *word2;
- /*
- * Fix arguments, *word is a new allocated structure, REMEMBER to
- * free *word when you want to return from this function ...
- */
- if (fix_complete_args(line, &word2, &pos)) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
- word = word2;
-#endif
-
- if (pos == 2) { /* 'remove extension _X_' (exten@context ... */
- struct ast_context *c = NULL;
- char *context = NULL, *exten = NULL;
- int le = 0; /* length of extension */
- int lc = 0; /* length of context */
-
- lc = split_ec(word, &exten, &context);
-#ifdef BROKEN_READLINE
- free(word2);
-#endif
- if (lc) /* error */
- return NULL;
- le = strlen(exten);
- lc = strlen(context);
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- goto error2;
- }
-
- /* find our context ... */
- while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
- struct ast_exten *e = NULL;
- /* XXX locking ? */
- if (!partial_match(ast_get_context_name(c), context, lc))
- continue; /* context not matched */
- while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
- if ( partial_match(ast_get_extension_name(e), exten, le) && ++which > state) { /* n-th match */
- /* If there is an extension then return exten@context. XXX otherwise ? */
- if (exten)
- asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c));
- break;
- }
- }
- if (e) /* got a match */
- break;
- }
-
- ast_unlock_contexts();
- error2:
- if (exten)
- free(exten);
- } else if (pos == 3) { /* 'remove extension EXT _X_' (priority) */
- char *exten = NULL, *context, *p;
- struct ast_context *c;
- int le, lc, len;
- const char *s = skip_words(line, 2); /* skip 'remove' 'extension' */
- int i = split_ec(s, &exten, &context); /* parse ext@context */
-
- if (i) /* error */
- goto error3;
- if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
- *p = '\0';
- if ( (p = strchr(context, ' ')) ) /* remove space after context */
- *p = '\0';
- le = strlen(exten);
- lc = strlen(context);
- len = strlen(word);
- if (le == 0 || lc == 0)
- goto error3;
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- goto error3;
- }
-
- /* walk contexts */
- c = NULL;
- while ( (c = ast_walk_contexts(c)) ) {
- /* XXX locking on c ? */
- struct ast_exten *e;
- if (strcmp(ast_get_context_name(c), context) != 0)
- continue;
- /* got it, we must match here */
- e = NULL;
- while ( (e = ast_walk_context_extensions(c, e)) ) {
- struct ast_exten *priority;
- char buffer[10];
-
- if (strcmp(ast_get_extension_name(e), exten) != 0)
- continue;
- /* XXX lock e ? */
- priority = NULL;
- while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
- snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
- if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
- ret = strdup(buffer);
- }
- break;
- }
- break;
- }
- ast_unlock_contexts();
- error3:
- if (exten)
- free(exten);
-#ifdef BROKEN_READLINE
- free(word2);
-#endif
- }
- return ret;
-}
-
-static char *complete_context_remove_extension(const char *line, const char *word, int pos,
- int state)
-{
- char *ret = NULL;
- int which = 0;
-
-#ifdef BROKEN_READLINE
- char *word2;
- /*
- * Fix arguments, *word is a new allocated structure, REMEMBER to
- * free *word when you want to return from this function ...
- */
- if (fix_complete_args(line, &word2, &pos)) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
- word = word2;
-#endif
-
- if (pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
- struct ast_context *c = NULL;
- char *context = NULL, *exten = NULL;
- int le = 0; /* length of extension */
- int lc = 0; /* length of context */
-
- lc = split_ec(word, &exten, &context);
-#ifdef BROKEN_READLINE
- free(word2);
-#endif
- if (lc) /* error */
- return NULL;
- le = strlen(exten);
- lc = strlen(context);
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- goto error2;
- }
-
- /* find our context ... */
- while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
- struct ast_exten *e = NULL;
- /* XXX locking ? */
- if (!partial_match(ast_get_context_name(c), context, lc))
- continue; /* context not matched */
- while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
- if ( partial_match(ast_get_extension_name(e), exten, le) && ++which > state) { /* n-th match */
- /* If there is an extension then return exten@context. XXX otherwise ? */
- if (exten)
- asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c));
- break;
- }
- }
- if (e) /* got a match */
- break;
- }
-
- ast_unlock_contexts();
- error2:
- if (exten)
- free(exten);
- } else if (pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
- char *exten = NULL, *context, *p;
- struct ast_context *c;
- int le, lc, len;
- const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'extension' */
- int i = split_ec(s, &exten, &context); /* parse ext@context */
-
- if (i) /* error */
- goto error3;
- if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
- *p = '\0';
- if ( (p = strchr(context, ' ')) ) /* remove space after context */
- *p = '\0';
- le = strlen(exten);
- lc = strlen(context);
- len = strlen(word);
- if (le == 0 || lc == 0)
- goto error3;
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- goto error3;
- }
-
- /* walk contexts */
- c = NULL;
- while ( (c = ast_walk_contexts(c)) ) {
- /* XXX locking on c ? */
- struct ast_exten *e;
- if (strcmp(ast_get_context_name(c), context) != 0)
- continue;
- /* got it, we must match here */
- e = NULL;
- while ( (e = ast_walk_context_extensions(c, e)) ) {
- struct ast_exten *priority;
- char buffer[10];
-
- if (strcmp(ast_get_extension_name(e), exten) != 0)
- continue;
- /* XXX lock e ? */
- priority = NULL;
- while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
- snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
- if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
- ret = strdup(buffer);
- }
- break;
- }
- break;
- }
- ast_unlock_contexts();
- error3:
- if (exten)
- free(exten);
-#ifdef BROKEN_READLINE
- free(word2);
-#endif
- }
- return ret;
-}
-
-/*!
- * Include context ...
- */
-static int handle_context_add_include_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 5) /* include context CTX in CTX */
- return RESULT_SHOWUSAGE;
-
- /* third arg must be 'in' ... */
- if (strcmp(argv[3], "in") && strcmp(argv[3], "into")) /* XXX why both ? */
- return RESULT_SHOWUSAGE;
-
- if (ast_context_add_include(argv[4], argv[2], registrar)) {
- switch (errno) {
- case ENOMEM:
- ast_cli(fd, "Out of memory for context addition\n");
- break;
-
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
- break;
-
- case EEXIST:
- ast_cli(fd, "Context '%s' already included in '%s' context\n",
- argv[2], argv[4]);
- break;
-
- case ENOENT:
- case EINVAL:
- ast_cli(fd, "There is no existence of context '%s'\n",
- errno == ENOENT ? argv[4] : argv[2]);
- break;
-
- default:
- ast_cli(fd, "Failed to include '%s' in '%s' context\n",
- argv[2], argv[4]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- /* show some info ... */
- ast_cli(fd, "Context '%s' included in '%s' context\n",
- argv[2], argv[4]);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_context_add_include(int fd, int argc, char *argv[])
-{
- if (argc != 6) /* dialplan add include CTX in CTX */
- return RESULT_SHOWUSAGE;
-
- /* fifth arg must be 'into' ... */
- if (strcmp(argv[4], "into"))
- return RESULT_SHOWUSAGE;
-
- if (ast_context_add_include(argv[5], argv[3], registrar)) {
- switch (errno) {
- case ENOMEM:
- ast_cli(fd, "Out of memory for context addition\n");
- break;
-
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
- break;
-
- case EEXIST:
- ast_cli(fd, "Context '%s' already included in '%s' context\n",
- argv[3], argv[5]);
- break;
-
- case ENOENT:
- case EINVAL:
- ast_cli(fd, "There is no existence of context '%s'\n",
- errno == ENOENT ? argv[5] : argv[3]);
- break;
-
- default:
- ast_cli(fd, "Failed to include '%s' in '%s' context\n",
- argv[3], argv[5]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- /* show some info ... */
- ast_cli(fd, "Context '%s' included in '%s' context\n",
- argv[3], argv[5]);
-
- return RESULT_SUCCESS;
-}
-
-static char *complete_context_add_include_deprecated(const char *line, const char *word, int pos,
- int state)
-{
- struct ast_context *c;
- int which = 0;
- char *ret = NULL;
- int len = strlen(word);
-
- if (pos == 2) { /* 'include context _X_' (context) ... */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- return NULL;
- }
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
- if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
- ret = strdup(ast_get_context_name(c));
- ast_unlock_contexts();
- return ret;
- } else if (pos == 3) { /* include context CTX _X_ */
- /* complete as 'in' if context exists or we are unable to check */
- char *context, *dupline;
- struct ast_context *c;
- const char *s = skip_words(line, 2); /* should not fail */
-
- if (state != 0) /* only once */
- return NULL;
-
- /* parse context from line ... */
- context = dupline = strdup(s);
- if (!context) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return strdup("in");
- }
- strsep(&dupline, " ");
-
- /* check for context existence ... */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- /* our fault, we can't check, so complete 'in' ... */
- ret = strdup("in");
- } else {
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
- if (!strcmp(context, ast_get_context_name(c)))
- ret = strdup("in"); /* found */
- ast_unlock_contexts();
- }
- free(context);
- return ret;
- } else if (pos == 4) { /* 'include context CTX in _X_' (dst context) */
- char *context, *dupline, *in;
- const char *s = skip_words(line, 2); /* should not fail */
- context = dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
- strsep(&dupline, " "); /* skip context */
- in = strsep(&dupline, " ");
- /* error if missing context or third word is not 'in' */
- if (!strlen(context) || strcmp(in, "in")) {
- ast_log(LOG_ERROR, "bad context %s or missing in %s\n",
- context, in);
- goto error3;
- }
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- goto error3;
- }
-
- for (c = NULL; (c = ast_walk_contexts(c)); )
- if (!strcmp(context, ast_get_context_name(c)))
- break;
- if (c) { /* first context exists, go on... */
- /* go through all contexts ... */
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
- if (!strcmp(context, ast_get_context_name(c)))
- continue; /* skip ourselves */
- if (partial_match(ast_get_context_name(c), word, len) &&
- !lookup_ci(c, context) /* not included yet */ &&
- ++which > state)
- ret = strdup(ast_get_context_name(c));
- }
- } else {
- ast_log(LOG_ERROR, "context %s not found\n", context);
- }
- ast_unlock_contexts();
- error3:
- free(context);
- return ret;
- }
-
- return NULL;
-}
-
-static char *complete_context_add_include(const char *line, const char *word, int pos,
- int state)
-{
- struct ast_context *c;
- int which = 0;
- char *ret = NULL;
- int len = strlen(word);
-
- if (pos == 3) { /* 'dialplan add include _X_' (context) ... */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- return NULL;
- }
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
- if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
- ret = strdup(ast_get_context_name(c));
- ast_unlock_contexts();
- return ret;
- } else if (pos == 4) { /* dialplan add include CTX _X_ */
- /* complete as 'into' if context exists or we are unable to check */
- char *context, *dupline;
- struct ast_context *c;
- const char *s = skip_words(line, 3); /* should not fail */
-
- if (state != 0) /* only once */
- return NULL;
-
- /* parse context from line ... */
- context = dupline = strdup(s);
- if (!context) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return strdup("into");
- }
- strsep(&dupline, " ");
-
- /* check for context existence ... */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- /* our fault, we can't check, so complete 'into' ... */
- ret = strdup("into");
- } else {
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
- if (!strcmp(context, ast_get_context_name(c)))
- ret = strdup("into"); /* found */
- ast_unlock_contexts();
- }
- free(context);
- return ret;
- } else if (pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
- char *context, *dupline, *into;
- const char *s = skip_words(line, 3); /* should not fail */
- context = dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Out of free memory\n");
- return NULL;
- }
- strsep(&dupline, " "); /* skip context */
- into = strsep(&dupline, " ");
- /* error if missing context or fifth word is not 'into' */
- if (!strlen(context) || strcmp(into, "into")) {
- ast_log(LOG_ERROR, "bad context %s or missing into %s\n",
- context, into);
- goto error3;
- }
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock context list\n");
- goto error3;
- }
-
- for (c = NULL; (c = ast_walk_contexts(c)); )
- if (!strcmp(context, ast_get_context_name(c)))
- break;
- if (c) { /* first context exists, go on... */
- /* go through all contexts ... */
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
- if (!strcmp(context, ast_get_context_name(c)))
- continue; /* skip ourselves */
- if (partial_match(ast_get_context_name(c), word, len) &&
- !lookup_ci(c, context) /* not included yet */ &&
- ++which > state)
- ret = strdup(ast_get_context_name(c));
- }
- } else {
- ast_log(LOG_ERROR, "context %s not found\n", context);
- }
- ast_unlock_contexts();
- error3:
- free(context);
- return ret;
- }
-
- return NULL;
-}
-
-/*!
- * \brief 'save dialplan' CLI command implementation functions ...
- */
-static int handle_save_dialplan(int fd, int argc, char *argv[])
-{
- char filename[256];
- struct ast_context *c;
- struct ast_config *cfg;
- struct ast_variable *v;
- int incomplete = 0; /* incomplete config write? */
- FILE *output;
-
- const char *base, *slash, *file;
-
- if (! (static_config && !write_protect_config)) {
- ast_cli(fd,
- "I can't save dialplan now, see '%s' example file.\n",
- config);
- return RESULT_FAILURE;
- }
-
- if (argc != 2 && argc != 3)
- return RESULT_SHOWUSAGE;
-
- if (ast_mutex_lock(&save_dialplan_lock)) {
- ast_cli(fd,
- "Failed to lock dialplan saving (another proccess saving?)\n");
- return RESULT_FAILURE;
- }
- /* XXX the code here is quite loose, a pathname with .conf in it
- * is assumed to be a complete pathname
- */
- if (argc == 3) { /* have config path. Look for *.conf */
- base = argv[2];
- if (!strstr(argv[2], ".conf")) { /*no, this is assumed to be a pathname */
- /* if filename ends with '/', do not add one */
- slash = (*(argv[2] + strlen(argv[2]) -1) == '/') ? "/" : "";
- file = config; /* default: 'extensions.conf' */
- } else { /* yes, complete file name */
- slash = "";
- file = "";
- }
- } else {
- /* no config file, default one */
- base = ast_config_AST_CONFIG_DIR;
- slash = "/";
- file = config;
- }
- snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
-
- cfg = ast_config_load("extensions.conf");
-
- /* try to lock contexts list */
- if (ast_rdlock_contexts()) {
- ast_cli(fd, "Failed to lock contexts list\n");
- ast_mutex_unlock(&save_dialplan_lock);
- ast_config_destroy(cfg);
- return RESULT_FAILURE;
- }
-
- /* create new file ... */
- if (!(output = fopen(filename, "wt"))) {
- ast_cli(fd, "Failed to create file '%s'\n",
- filename);
- ast_unlock_contexts();
- ast_mutex_unlock(&save_dialplan_lock);
- ast_config_destroy(cfg);
- return RESULT_FAILURE;
- }
-
- /* fireout general info */
- fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\npriorityjumping=%s\n\n",
- static_config ? "yes" : "no",
- write_protect_config ? "yes" : "no",
- autofallthrough_config ? "yes" : "no",
- clearglobalvars_config ? "yes" : "no",
- ast_true(ast_variable_retrieve(cfg, "general", "priorityjumping")) ? "yes" : "no");
-
- if ((v = ast_variable_browse(cfg, "globals"))) {
- fprintf(output, "[globals]\n");
- while(v) {
- fprintf(output, "%s => %s\n", v->name, v->value);
- v = v->next;
- }
- fprintf(output, "\n");
- }
-
- ast_config_destroy(cfg);
-
-#define PUT_CTX_HDR do { \
- if (!context_header_written) { \
- fprintf(output, "[%s]\n", ast_get_context_name(c)); \
- context_header_written = 1; \
- } \
- } while (0)
-
- /* walk all contexts */
- for (c = NULL; (c = ast_walk_contexts(c)); ) {
- int context_header_written = 0;
- struct ast_exten *e, *last_written_e = NULL;
- struct ast_include *i;
- struct ast_ignorepat *ip;
- struct ast_sw *sw;
-
- /* try to lock context and fireout all info */
- if (ast_lock_context(c)) { /* lock failure */
- incomplete = 1;
- continue;
- }
- /* registered by this module? */
- /* XXX do we need this ? */
- if (!strcmp(ast_get_context_registrar(c), registrar)) {
- fprintf(output, "[%s]\n", ast_get_context_name(c));
- context_header_written = 1;
- }
-
- /* walk extensions ... */
- for (e = NULL; (e = ast_walk_context_extensions(c, e)); ) {
- struct ast_exten *p = NULL;
-
- /* fireout priorities */
- while ( (p = ast_walk_extension_priorities(e, p)) ) {
- if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
- continue;
-
- /* make empty line between different extensions */
- if (last_written_e != NULL &&
- strcmp(ast_get_extension_name(last_written_e),
- ast_get_extension_name(p)))
- fprintf(output, "\n");
- last_written_e = p;
-
- PUT_CTX_HDR;
-
- if (ast_get_extension_priority(p)==PRIORITY_HINT) { /* easy */
- fprintf(output, "exten => %s,hint,%s\n",
- ast_get_extension_name(p),
- ast_get_extension_app(p));
- } else { /* copy and replace '|' with ',' */
- const char *sep, *cid;
- char *tempdata = "";
- char *s;
- const char *el = ast_get_extension_label(p);
- char label[128] = "";
-
- s = ast_get_extension_app_data(p);
- if (s) {
- char *t;
- tempdata = alloca(strlen(tempdata) * 2 + 1);
-
- for (t = tempdata; *s; s++, t++) {
- if (*s == '|')
- *t = ',';
- else {
- if (*s == ',' || *s == ';')
- *t++ = '\\';
- *t = *s;
- }
- }
- /* Terminating NULL */
- *t = *s;
- }
-
- if (ast_get_extension_matchcid(p)) {
- sep = "/";
- cid = ast_get_extension_cidmatch(p);
- } else
- sep = cid = "";
-
- if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2)))
- incomplete = 1; /* error encountered or label > 125 chars */
-
- fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
- ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
- ast_get_extension_priority(p), label,
- ast_get_extension_app(p), (ast_strlen_zero(tempdata) ? "" : tempdata));
- }
- }
- }
-
- /* written any extensions? ok, write space between exten & inc */
- if (last_written_e)
- fprintf(output, "\n");
-
- /* walk through includes */
- for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) {
- if (strcmp(ast_get_include_registrar(i), registrar) != 0)
- continue; /* not mine */
- PUT_CTX_HDR;
- fprintf(output, "include => %s\n", ast_get_include_name(i));
- }
- if (ast_walk_context_includes(c, NULL))
- fprintf(output, "\n");
-
- /* walk through switches */
- for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
- if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
- continue; /* not mine */
- PUT_CTX_HDR;
- fprintf(output, "switch => %s/%s\n",
- ast_get_switch_name(sw), ast_get_switch_data(sw));
- }
-
- if (ast_walk_context_switches(c, NULL))
- fprintf(output, "\n");
-
- /* fireout ignorepats ... */
- for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) {
- if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
- continue; /* not mine */
- PUT_CTX_HDR;
- fprintf(output, "ignorepat => %s\n",
- ast_get_ignorepat_name(ip));
- }
-
- ast_unlock_context(c);
- }
-
- ast_unlock_contexts();
- ast_mutex_unlock(&save_dialplan_lock);
- fclose(output);
-
- if (incomplete) {
- ast_cli(fd, "Saved dialplan is incomplete\n");
- return RESULT_FAILURE;
- }
-
- ast_cli(fd, "Dialplan successfully saved into '%s'\n",
- filename);
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief ADD EXTENSION command stuff
- */
-static int handle_context_add_extension_deprecated(int fd, int argc, char *argv[])
-{
- char *whole_exten;
- char *exten, *prior;
- int iprior = -2;
- char *cidmatch, *app, *app_data;
- char *start, *end;
-
- /* check for arguments at first */
- if (argc != 5 && argc != 6)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[3], "into"))
- return RESULT_SHOWUSAGE;
- if (argc == 6) if (strcmp(argv[5], "replace")) return RESULT_SHOWUSAGE;
-
- /* XXX overwrite argv[2] */
- whole_exten = argv[2];
- exten = strsep(&whole_exten,",");
- if (strchr(exten, '/')) {
- cidmatch = exten;
- strsep(&cidmatch,"/");
- } else {
- cidmatch = NULL;
- }
- prior = strsep(&whole_exten,",");
- if (prior) {
- if (!strcmp(prior, "hint")) {
- iprior = PRIORITY_HINT;
- } else {
- if (sscanf(prior, "%d", &iprior) != 1) {
- ast_cli(fd, "'%s' is not a valid priority\n", prior);
- prior = NULL;
- }
- }
- }
- app = whole_exten;
- if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
- *start = *end = '\0';
- app_data = start + 1;
- ast_process_quotes_and_slashes(app_data, ',', '|');
- } else {
- if (app) {
- app_data = strchr(app, ',');
- if (app_data) {
- *app_data = '\0';
- app_data++;
- }
- } else
- app_data = NULL;
- }
-
- if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
- return RESULT_SHOWUSAGE;
-
- if (!app_data)
- app_data="";
- if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
- (void *)strdup(app_data), ast_free, registrar)) {
- switch (errno) {
- case ENOMEM:
- ast_cli(fd, "Out of free memory\n");
- break;
-
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
- break;
-
- case ENOENT:
- ast_cli(fd, "No existence of '%s' context\n", argv[4]);
- break;
-
- case EEXIST:
- ast_cli(fd, "Extension %s@%s with priority %s already exists\n",
- exten, argv[4], prior);
- break;
-
- default:
- ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
- exten, prior, app, app_data, argv[4]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- if (argc == 6)
- ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
- exten, argv[4], prior, exten, prior, app, app_data);
- else
- ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
- exten, prior, app, app_data, argv[4]);
-
- return RESULT_SUCCESS;
-}
-static int handle_context_add_extension(int fd, int argc, char *argv[])
-{
- char *whole_exten;
- char *exten, *prior;
- int iprior = -2;
- char *cidmatch, *app, *app_data;
- char *start, *end;
-
- /* check for arguments at first */
- if (argc != 6 && argc != 7)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[4], "into"))
- return RESULT_SHOWUSAGE;
- if (argc == 7) if (strcmp(argv[6], "replace")) return RESULT_SHOWUSAGE;
-
- /* XXX overwrite argv[3] */
- whole_exten = argv[3];
- exten = strsep(&whole_exten,",");
- if (strchr(exten, '/')) {
- cidmatch = exten;
- strsep(&cidmatch,"/");
- } else {
- cidmatch = NULL;
- }
- prior = strsep(&whole_exten,",");
- if (prior) {
- if (!strcmp(prior, "hint")) {
- iprior = PRIORITY_HINT;
- } else {
- if (sscanf(prior, "%d", &iprior) != 1) {
- ast_cli(fd, "'%s' is not a valid priority\n", prior);
- prior = NULL;
- }
- }
- }
- app = whole_exten;
- if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
- *start = *end = '\0';
- app_data = start + 1;
- ast_process_quotes_and_slashes(app_data, ',', '|');
- } else {
- if (app) {
- app_data = strchr(app, ',');
- if (app_data) {
- *app_data = '\0';
- app_data++;
- }
- } else
- app_data = NULL;
- }
-
- if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
- return RESULT_SHOWUSAGE;
-
- if (!app_data)
- app_data="";
- if (ast_add_extension(argv[5], argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
- (void *)strdup(app_data), ast_free, registrar)) {
- switch (errno) {
- case ENOMEM:
- ast_cli(fd, "Out of free memory\n");
- break;
-
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
- break;
-
- case ENOENT:
- ast_cli(fd, "No existence of '%s' context\n", argv[5]);
- break;
-
- case EEXIST:
- ast_cli(fd, "Extension %s@%s with priority %s already exists\n",
- exten, argv[5], prior);
- break;
-
- default:
- ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
- exten, prior, app, app_data, argv[5]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- if (argc == 7)
- ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
- exten, argv[5], prior, exten, prior, app, app_data);
- else
- ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
- exten, prior, app, app_data, argv[5]);
-
- return RESULT_SUCCESS;
-}
-
-/*! dialplan add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local */
-static char *complete_context_add_extension_deprecated(const char *line, const char *word, int pos, int state)
-{
- int which = 0;
-
- if (pos == 3) { /* complete 'into' word ... */
- return (state == 0) ? strdup("into") : NULL;
- } else if (pos == 4) { /* complete context */
- struct ast_context *c = NULL;
- int len = strlen(word);
- char *res = NULL;
-
- /* try to lock contexts list ... */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- return NULL;
- }
-
- /* walk through all contexts */
- while ( !res && (c = ast_walk_contexts(c)) )
- if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
- res = strdup(ast_get_context_name(c));
- ast_unlock_contexts();
- return res;
- } else if (pos == 5) {
- return state == 0 ? strdup("replace") : NULL;
- }
- return NULL;
-}
-
-static char *complete_context_add_extension(const char *line, const char *word, int pos, int state)
-{
- int which = 0;
-
- if (pos == 4) { /* complete 'into' word ... */
- return (state == 0) ? strdup("into") : NULL;
- } else if (pos == 5) { /* complete context */
- struct ast_context *c = NULL;
- int len = strlen(word);
- char *res = NULL;
-
- /* try to lock contexts list ... */
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- return NULL;
- }
-
- /* walk through all contexts */
- while ( !res && (c = ast_walk_contexts(c)) )
- if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
- res = strdup(ast_get_context_name(c));
- ast_unlock_contexts();
- return res;
- } else if (pos == 6) {
- return state == 0 ? strdup("replace") : NULL;
- }
- return NULL;
-}
-
-/*!
- * IGNOREPAT CLI stuff
- */
-static int handle_context_add_ignorepat_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[3], "into"))
- return RESULT_SHOWUSAGE;
-
- if (ast_context_add_ignorepat(argv[4], argv[2], registrar)) {
- switch (errno) {
- case ENOMEM:
- ast_cli(fd, "Out of free memory\n");
- break;
-
- case ENOENT:
- ast_cli(fd, "There is no existence of '%s' context\n", argv[4]);
- break;
-
- case EEXIST:
- ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
- argv[2], argv[4]);
- break;
-
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
- break;
-
- default:
- ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
- argv[2], argv[4]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
- argv[2], argv[4]);
- return RESULT_SUCCESS;
-}
-
-static int handle_context_add_ignorepat(int fd, int argc, char *argv[])
-{
- if (argc != 6)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[4], "into"))
- return RESULT_SHOWUSAGE;
-
- if (ast_context_add_ignorepat(argv[5], argv[3], registrar)) {
- switch (errno) {
- case ENOMEM:
- ast_cli(fd, "Out of free memory\n");
- break;
-
- case ENOENT:
- ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
- break;
-
- case EEXIST:
- ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
- argv[3], argv[5]);
- break;
-
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
- break;
-
- default:
- ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
- argv[3], argv[5]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
- argv[3], argv[5]);
- return RESULT_SUCCESS;
-}
-
-static char *complete_context_add_ignorepat_deprecated(const char *line, const char *word,
- int pos, int state)
-{
- if (pos == 3)
- return state == 0 ? strdup("into") : NULL;
- else if (pos == 4) {
- struct ast_context *c;
- int which = 0;
- char *dupline, *ignorepat = NULL;
- const char *s;
- char *ret = NULL;
- int len = strlen(word);
-
- /* XXX skip first two words 'add' 'ignorepat' */
- s = skip_words(line, 2);
- if (s == NULL)
- return NULL;
- dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Malloc failure\n");
- return NULL;
- }
- ignorepat = strsep(&dupline, " ");
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock contexts list\n");
- return NULL;
- }
-
- for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
- int found = 0;
-
- if (!partial_match(ast_get_context_name(c), word, len))
- continue; /* not mine */
- if (ignorepat) /* there must be one, right ? */
- found = lookup_c_ip(c, ignorepat);
- if (!found && ++which > state)
- ret = strdup(ast_get_context_name(c));
- }
-
- if (ignorepat)
- free(ignorepat);
- ast_unlock_contexts();
- return ret;
- }
-
- return NULL;
-}
-
-static char *complete_context_add_ignorepat(const char *line, const char *word,
- int pos, int state)
-{
- if (pos == 4)
- return state == 0 ? strdup("into") : NULL;
- else if (pos == 5) {
- struct ast_context *c;
- int which = 0;
- char *dupline, *ignorepat = NULL;
- const char *s;
- char *ret = NULL;
- int len = strlen(word);
-
- /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
- s = skip_words(line, 3);
- if (s == NULL)
- return NULL;
- dupline = strdup(s);
- if (!dupline) {
- ast_log(LOG_ERROR, "Malloc failure\n");
- return NULL;
- }
- ignorepat = strsep(&dupline, " ");
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_ERROR, "Failed to lock contexts list\n");
- return NULL;
- }
-
- for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
- int found = 0;
-
- if (!partial_match(ast_get_context_name(c), word, len))
- continue; /* not mine */
- if (ignorepat) /* there must be one, right ? */
- found = lookup_c_ip(c, ignorepat);
- if (!found && ++which > state)
- ret = strdup(ast_get_context_name(c));
- }
-
- if (ignorepat)
- free(ignorepat);
- ast_unlock_contexts();
- return ret;
- }
-
- return NULL;
-}
-
-static int handle_context_remove_ignorepat_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[3], "from"))
- return RESULT_SHOWUSAGE;
-
- if (ast_context_remove_ignorepat(argv[4], argv[2], registrar)) {
- switch (errno) {
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
- break;
-
- case ENOENT:
- ast_cli(fd, "There is no existence of '%s' context\n", argv[4]);
- break;
-
- case EINVAL:
- ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
- argv[2], argv[4]);
- break;
-
- default:
- ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[2], argv[4]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
- argv[2], argv[4]);
- return RESULT_SUCCESS;
-}
-
-static int handle_context_remove_ignorepat(int fd, int argc, char *argv[])
-{
- if (argc != 6)
- return RESULT_SHOWUSAGE;
- if (strcmp(argv[4], "from"))
- return RESULT_SHOWUSAGE;
-
- if (ast_context_remove_ignorepat(argv[5], argv[3], registrar)) {
- switch (errno) {
- case EBUSY:
- ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
- break;
-
- case ENOENT:
- ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
- break;
-
- case EINVAL:
- ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
- argv[3], argv[5]);
- break;
-
- default:
- ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[3], argv[5]);
- break;
- }
- return RESULT_FAILURE;
- }
-
- ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
- argv[3], argv[5]);
- return RESULT_SUCCESS;
-}
-
-static char *complete_context_remove_ignorepat_deprecated(const char *line, const char *word,
- int pos, int state)
-{
- struct ast_context *c;
- int which = 0;
- char *ret = NULL;
-
- if (pos == 2) {
- int len = strlen(word);
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- return NULL;
- }
-
- for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
- struct ast_ignorepat *ip;
-
- if (ast_lock_context(c)) /* error, skip it */
- continue;
-
- for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
- if (partial_match(ast_get_ignorepat_name(ip), word, len) && ++which > state) {
- /* n-th match */
- struct ast_context *cw = NULL;
- int found = 0;
- while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
- /* XXX do i stop on c, or skip it ? */
- found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
- }
- if (!found)
- ret = strdup(ast_get_ignorepat_name(ip));
- }
- }
- ast_unlock_context(c);
- }
- ast_unlock_contexts();
- return ret;
- } else if (pos == 3) {
- return state == 0 ? strdup("from") : NULL;
- } else if (pos == 4) { /* XXX check this */
- char *dupline, *duplinet, *ignorepat;
- int len = strlen(word);
-
- dupline = strdup(line);
- if (!dupline) {
- ast_log(LOG_WARNING, "Out of free memory\n");
- return NULL;
- }
-
- duplinet = dupline;
- strsep(&duplinet, " ");
- strsep(&duplinet, " ");
- ignorepat = strsep(&duplinet, " ");
-
- if (!ignorepat) {
- free(dupline);
- return NULL;
- }
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- free(dupline);
- return NULL;
- }
-
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
- if (ast_lock_context(c)) /* fail, skip it */
- continue;
- if (!partial_match(ast_get_context_name(c), word, len))
- continue;
- if (lookup_c_ip(c, ignorepat) && ++which > state)
- ret = strdup(ast_get_context_name(c));
- ast_unlock_context(c);
- }
- ast_unlock_contexts();
- free(dupline);
- return NULL;
- }
-
- return NULL;
-}
-
-static char *complete_context_remove_ignorepat(const char *line, const char *word,
- int pos, int state)
-{
- struct ast_context *c;
- int which = 0;
- char *ret = NULL;
-
- if (pos == 3) {
- int len = strlen(word);
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- return NULL;
- }
-
- for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
- struct ast_ignorepat *ip;
-
- if (ast_lock_context(c)) /* error, skip it */
- continue;
-
- for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
- if (partial_match(ast_get_ignorepat_name(ip), word, len) && ++which > state) {
- /* n-th match */
- struct ast_context *cw = NULL;
- int found = 0;
- while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
- /* XXX do i stop on c, or skip it ? */
- found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
- }
- if (!found)
- ret = strdup(ast_get_ignorepat_name(ip));
- }
- }
- ast_unlock_context(c);
- }
- ast_unlock_contexts();
- return ret;
- } else if (pos == 4) {
- return state == 0 ? strdup("from") : NULL;
- } else if (pos == 5) { /* XXX check this */
- char *dupline, *duplinet, *ignorepat;
- int len = strlen(word);
-
- dupline = strdup(line);
- if (!dupline) {
- ast_log(LOG_WARNING, "Out of free memory\n");
- return NULL;
- }
-
- duplinet = dupline;
- strsep(&duplinet, " ");
- strsep(&duplinet, " ");
- ignorepat = strsep(&duplinet, " ");
-
- if (!ignorepat) {
- free(dupline);
- return NULL;
- }
-
- if (ast_rdlock_contexts()) {
- ast_log(LOG_WARNING, "Failed to lock contexts list\n");
- free(dupline);
- return NULL;
- }
-
- for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
- if (ast_lock_context(c)) /* fail, skip it */
- continue;
- if (!partial_match(ast_get_context_name(c), word, len))
- continue;
- if (lookup_c_ip(c, ignorepat) && ++which > state)
- ret = strdup(ast_get_context_name(c));
- ast_unlock_context(c);
- }
- ast_unlock_contexts();
- free(dupline);
- return NULL;
- }
-
- return NULL;
-}
-
-static int pbx_load_module(void);
-
-static int handle_reload_extensions(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- if (clearglobalvars_config)
- pbx_builtin_clear_globals();
- pbx_load_module();
- return RESULT_SUCCESS;
-}
-
-/*!
- * CLI entries for commands provided by this module
- */
-static struct ast_cli_entry cli_dont_include_deprecated = {
- { "dont", "include", NULL },
- handle_context_dont_include_deprecated, NULL,
- NULL, complete_context_dont_include_deprecated };
-
-static struct ast_cli_entry cli_remove_extension_deprecated = {
- { "remove", "extension", NULL },
- handle_context_remove_extension_deprecated, NULL,
- NULL, complete_context_remove_extension_deprecated };
-
-static struct ast_cli_entry cli_include_context_deprecated = {
- { "include", "context", NULL },
- handle_context_add_include_deprecated, NULL,
- NULL, complete_context_add_include_deprecated };
-
-static struct ast_cli_entry cli_add_extension_deprecated = {
- { "add", "extension", NULL },
- handle_context_add_extension_deprecated, NULL,
- NULL, complete_context_add_extension_deprecated };
-
-static struct ast_cli_entry cli_add_ignorepat_deprecated = {
- { "add", "ignorepat", NULL },
- handle_context_add_ignorepat_deprecated, NULL,
- NULL, complete_context_add_ignorepat_deprecated };
-
-static struct ast_cli_entry cli_remove_ignorepat_deprecated = {
- { "remove", "ignorepat", NULL },
- handle_context_remove_ignorepat_deprecated, NULL,
- NULL, complete_context_remove_ignorepat_deprecated };
-
-static struct ast_cli_entry cli_extensions_reload_deprecated = {
- { "extensions", "reload", NULL },
- handle_reload_extensions, NULL,
- NULL };
-
-static struct ast_cli_entry cli_save_dialplan_deprecated = {
- { "save", "dialplan", NULL },
- handle_save_dialplan, NULL,
- NULL };
-
-static struct ast_cli_entry cli_pbx_config[] = {
- { { "dialplan", "add", "extension", NULL },
- handle_context_add_extension, "Add new extension into context",
- context_add_extension_help, complete_context_add_extension, &cli_add_extension_deprecated },
-
- { { "dialplan", "remove", "extension", NULL },
- handle_context_remove_extension, "Remove a specified extension",
- context_remove_extension_help, complete_context_remove_extension, &cli_remove_extension_deprecated },
-
- { { "dialplan", "add", "ignorepat", NULL },
- handle_context_add_ignorepat, "Add new ignore pattern",
- context_add_ignorepat_help, complete_context_add_ignorepat, &cli_add_ignorepat_deprecated },
-
- { { "dialplan", "remove", "ignorepat", NULL },
- handle_context_remove_ignorepat, "Remove ignore pattern from context",
- context_remove_ignorepat_help, complete_context_remove_ignorepat, &cli_remove_ignorepat_deprecated },
-
- { { "dialplan", "add", "include", NULL },
- handle_context_add_include, "Include context in other context",
- context_add_include_help, complete_context_add_include, &cli_include_context_deprecated },
-
- { { "dialplan", "remove", "include", NULL },
- handle_context_remove_include, "Remove a specified include from context",
- context_remove_include_help, complete_context_remove_include, &cli_dont_include_deprecated },
-
- { { "dialplan", "reload", NULL },
- handle_reload_extensions, "Reload extensions and *only* extensions",
- reload_extensions_help, NULL, &cli_extensions_reload_deprecated },
-};
-
-
-static struct ast_cli_entry cli_dialplan_save = {
- { "dialplan", "save", NULL },
- handle_save_dialplan, "Save dialplan",
- save_dialplan_help, NULL, &cli_save_dialplan_deprecated };
-
-/*!
- * Standard module functions ...
- */
-static int unload_module(void)
-{
- if (static_config && !write_protect_config)
- ast_cli_unregister(&cli_dialplan_save);
- ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
- ast_context_destroy(NULL, registrar);
- return 0;
-}
-
-static int pbx_load_config(const char *config_file)
-{
- struct ast_config *cfg;
- char *end;
- char *label;
- char realvalue[256];
- int lastpri = -2;
- struct ast_context *con;
- struct ast_variable *v;
- const char *cxt;
- const char *aft;
-
- cfg = ast_config_load(config_file);
- if (!cfg)
- return 0;
-
- /* Use existing config to populate the PBX table */
- static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
- write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
- if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
- autofallthrough_config = ast_true(aft);
- clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
- ast_set2_flag(&ast_options, ast_true(ast_variable_retrieve(cfg, "general", "priorityjumping")), AST_OPT_FLAG_PRIORITY_JUMPING);
-
- if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext")))
- ast_copy_string(userscontext, cxt, sizeof(userscontext));
- else
- ast_copy_string(userscontext, "default", sizeof(userscontext));
-
- for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
- memset(realvalue, 0, sizeof(realvalue));
- pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
- pbx_builtin_setvar_helper(NULL, v->name, realvalue);
- }
- for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) {
- /* All categories but "general" or "globals" are considered contexts */
- if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals"))
- continue;
- con=ast_context_find_or_create(&local_contexts,cxt, registrar);
- if (con == NULL)
- continue;
-
- for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
- if (!strcasecmp(v->name, "exten")) {
- char *tc = ast_strdup(v->value);
- if (tc) {
- int ipri = -2;
- char realext[256]="";
- char *plus, *firstp, *firstc;
- char *pri, *appl, *data, *cidmatch;
- char *stringp = tc;
- char *ext = strsep(&stringp, ",");
- if (!ext)
- ext="";
- pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
- cidmatch = strchr(realext, '/');
- if (cidmatch) {
- *cidmatch++ = '\0';
- ast_shrink_phone_number(cidmatch);
- }
- pri = strsep(&stringp, ",");
- if (!pri)
- pri="";
- pri = ast_skip_blanks(pri);
- pri = ast_trim_blanks(pri);
- label = strchr(pri, '(');
- if (label) {
- *label++ = '\0';
- end = strchr(label, ')');
- if (end)
- *end = '\0';
- else
- ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
- }
- plus = strchr(pri, '+');
- if (plus)
- *plus++ = '\0';
- if (!strcmp(pri,"hint"))
- ipri=PRIORITY_HINT;
- else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
- if (lastpri > -2)
- ipri = lastpri + 1;
- else
- ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
- } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
- if (lastpri > -2)
- ipri = lastpri;
- else
- ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
- } else if (sscanf(pri, "%d", &ipri) != 1 &&
- (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
- ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
- ipri = 0;
- }
- appl = S_OR(stringp, "");
- /* Find the first occurrence of either '(' or ',' */
- firstc = strchr(appl, ',');
- firstp = strchr(appl, '(');
- if (firstc && (!firstp || firstc < firstp)) {
- /* comma found, no parenthesis */
- /* or both found, but comma found first */
- appl = strsep(&stringp, ",");
- data = stringp;
- } else if (!firstc && !firstp) {
- /* Neither found */
- data = "";
- } else {
- /* Final remaining case is parenthesis found first */
- appl = strsep(&stringp, "(");
- data = stringp;
- end = strrchr(data, ')');
- if ((end = strrchr(data, ')'))) {
- *end = '\0';
- } else {
- ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
- }
- ast_process_quotes_and_slashes(data, ',', '|');
- }
-
- if (!data)
- data="";
- appl = ast_skip_blanks(appl);
- if (ipri) {
- if (plus)
- ipri += atoi(plus);
- lastpri = ipri;
- if (!ast_opt_dont_warn && !strcmp(realext, "_."))
- ast_log(LOG_WARNING, "The use of '_.' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X.' instead at line %d\n", v->lineno);
- if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free, registrar)) {
- ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
- }
- }
- free(tc);
- }
- } else if (!strcasecmp(v->name, "include")) {
- memset(realvalue, 0, sizeof(realvalue));
- pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
- if (ast_context_add_include2(con, realvalue, registrar))
- ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
- } else if (!strcasecmp(v->name, "ignorepat")) {
- memset(realvalue, 0, sizeof(realvalue));
- pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
- if (ast_context_add_ignorepat2(con, realvalue, registrar))
- ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
- } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
- char *stringp= realvalue;
- char *appl, *data;
-
- memset(realvalue, 0, sizeof(realvalue));
- if (!strcasecmp(v->name, "switch"))
- pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
- else
- ast_copy_string(realvalue, v->value, sizeof(realvalue));
- appl = strsep(&stringp, "/");
- data = strsep(&stringp, ""); /* XXX what for ? */
- if (!data)
- data = "";
- if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
- ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
- }
- }
- }
- ast_config_destroy(cfg);
- return 1;
-}
-
-static void append_interface(char *iface, int maxlen, char *add)
-{
- int len = strlen(iface);
- if (strlen(add) + len < maxlen - 2) {
- if (strlen(iface)) {
- iface[len] = '&';
- strcpy(iface + len + 1, add);
- } else
- strcpy(iface, add);
- }
-}
-
-static void pbx_load_users(void)
-{
- struct ast_config *cfg;
- char *cat, *chan;
- const char *zapchan;
- const char *hasexten;
- char tmp[256];
- char iface[256];
- char zapcopy[256];
- char *c;
- int len;
- int hasvoicemail;
- int start, finish, x;
- struct ast_context *con = NULL;
-
- cfg = ast_config_load("users.conf");
- if (!cfg)
- return;
-
- for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
- if (!strcasecmp(cat, "general"))
- continue;
- iface[0] = '\0';
- len = sizeof(iface);
- if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
- snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
- append_interface(iface, sizeof(iface), tmp);
- }
- if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
- snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
- append_interface(iface, sizeof(iface), tmp);
- }
- if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
- snprintf(tmp, sizeof(tmp), "H323/%s", cat);
- append_interface(iface, sizeof(iface), tmp);
- }
- hasexten = ast_config_option(cfg, cat, "hasexten");
- if (hasexten && !ast_true(hasexten))
- continue;
- hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
- zapchan = ast_variable_retrieve(cfg, cat, "zapchan");
- if (!zapchan)
- zapchan = ast_variable_retrieve(cfg, "general", "zapchan");
- if (!ast_strlen_zero(zapchan)) {
- ast_copy_string(zapcopy, zapchan, sizeof(zapcopy));
- c = zapcopy;
- chan = strsep(&c, ",");
- while (chan) {
- if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
- /* Range */
- } else if (sscanf(chan, "%d", &start)) {
- /* Just one */
- finish = start;
- } else {
- start = 0; finish = 0;
- }
- if (finish < start) {
- x = finish;
- finish = start;
- start = x;
- }
- for (x = start; x <= finish; x++) {
- snprintf(tmp, sizeof(tmp), "Zap/%d", x);
- append_interface(iface, sizeof(iface), tmp);
- }
- chan = strsep(&c, ",");
- }
- }
- if (!ast_strlen_zero(iface)) {
- /* Only create a context here when it is really needed. Otherwise default empty context
- created by pbx_config may conflict with the one explicitly created by pbx_ael */
- if (!con)
- con = ast_context_find_or_create(&local_contexts, userscontext, registrar);
-
- if (!con) {
- ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
- return;
- }
-
- /* Add hint */
- ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
- /* If voicemail, use "stdexten" else use plain old dial */
- if (hasvoicemail) {
- snprintf(tmp, sizeof(tmp), "stdexten|%s|${HINT}", cat);
- ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free, registrar);
- } else {
- ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free, registrar);
- }
- }
- }
- ast_config_destroy(cfg);
-}
-
-static int pbx_load_module(void)
-{
- struct ast_context *con;
-
- if(!pbx_load_config(config))
- return AST_MODULE_LOAD_DECLINE;
-
- pbx_load_users();
-
- ast_merge_contexts_and_delete(&local_contexts, registrar);
-
- for (con = NULL; (con = ast_walk_contexts(con));)
- ast_context_verify_includes(con);
-
- pbx_set_autofallthrough(autofallthrough_config);
-
- return 0;
-}
-
-static int load_module(void)
-{
- if (pbx_load_module())
- return AST_MODULE_LOAD_DECLINE;
-
- if (static_config && !write_protect_config)
- ast_cli_register(&cli_dialplan_save);
- ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
-
- return 0;
-}
-
-static int reload(void)
-{
- if (clearglobalvars_config)
- pbx_builtin_clear_globals();
- pbx_load_module();
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Text Extension Configuration",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/pbx/pbx_dundi.c b/1.4/pbx/pbx_dundi.c
deleted file mode 100644
index 647cd1dc2..000000000
--- a/1.4/pbx/pbx_dundi.c
+++ /dev/null
@@ -1,4615 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Distributed Universal Number Discovery (DUNDi)
- */
-
-/*** MODULEINFO
- <depend>zlib</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <errno.h>
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(SOLARIS) || defined(__Darwin__)
-#include <sys/types.h>
-#include <netinet/in_systm.h>
-#endif
-#include <netinet/ip.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__Darwin__)
-#include <net/if_dl.h>
-#include <ifaddrs.h>
-#endif
-#include <zlib.h>
-#include <sys/signal.h>
-#include <pthread.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/frame.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-#include "asterisk/md5.h"
-#include "asterisk/dundi.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/utils.h"
-#include "asterisk/crypto.h"
-#include "asterisk/astdb.h"
-#include "asterisk/acl.h"
-#include "asterisk/aes.h"
-
-#include "dundi-parser.h"
-
-#define MAX_RESULTS 64
-
-#define MAX_PACKET_SIZE 8192
-
-#define DUNDI_MODEL_INBOUND (1 << 0)
-#define DUNDI_MODEL_OUTBOUND (1 << 1)
-#define DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND)
-
-/*! Keep times of last 10 lookups */
-#define DUNDI_TIMING_HISTORY 10
-
-#define FLAG_ISREG (1 << 0) /*!< Transaction is register request */
-#define FLAG_DEAD (1 << 1) /*!< Transaction is dead */
-#define FLAG_FINAL (1 << 2) /*!< Transaction has final message sent */
-#define FLAG_ISQUAL (1 << 3) /*!< Transaction is a qualification */
-#define FLAG_ENCRYPT (1 << 4) /*!< Transaction is encrypted wiht ECX/DCX */
-#define FLAG_SENDFULLKEY (1 << 5) /*!< Send full key on transaction */
-#define FLAG_STOREHIST (1 << 6) /*!< Record historic performance */
-
-#define DUNDI_FLAG_INTERNAL_NOPARTIAL (1 << 17)
-
-#if 0
-#define DUNDI_SECRET_TIME 15 /* Testing only */
-#else
-#define DUNDI_SECRET_TIME DUNDI_DEFAULT_CACHE_TIME
-#endif
-
-#define KEY_OUT 0
-#define KEY_IN 1
-
-static struct io_context *io;
-static struct sched_context *sched;
-static int netsocket = -1;
-static pthread_t netthreadid = AST_PTHREADT_NULL;
-static pthread_t precachethreadid = AST_PTHREADT_NULL;
-static int tos = 0;
-static int dundidebug = 0;
-static int authdebug = 0;
-static int dundi_ttl = DUNDI_DEFAULT_TTL;
-static int dundi_key_ttl = DUNDI_DEFAULT_KEY_EXPIRE;
-static int dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;
-static int global_autokilltimeout = 0;
-static dundi_eid global_eid;
-static int default_expiration = 60;
-static int global_storehistory = 0;
-static char dept[80];
-static char org[80];
-static char locality[80];
-static char stateprov[80];
-static char country[80];
-static char email[80];
-static char phone[80];
-static char secretpath[80];
-static char cursecret[80];
-static char ipaddr[80];
-static time_t rotatetime;
-static dundi_eid empty_eid = { { 0, 0, 0, 0, 0, 0 } };
-static int dundi_shutdown = 0;
-
-struct permission {
- AST_LIST_ENTRY(permission) list;
- int allow;
- char name[0];
-};
-
-struct dundi_packet {
- AST_LIST_ENTRY(dundi_packet) list;
- struct dundi_hdr *h;
- int datalen;
- struct dundi_transaction *parent;
- int retransid;
- int retrans;
- unsigned char data[0];
-};
-
-struct dundi_hint_metadata {
- unsigned short flags;
- char exten[AST_MAX_EXTENSION];
-};
-
-struct dundi_precache_queue {
- AST_LIST_ENTRY(dundi_precache_queue) list;
- char *context;
- time_t expiration;
- char number[0];
-};
-
-struct dundi_request;
-
-struct dundi_transaction {
- struct sockaddr_in addr; /*!< Other end of transaction */
- struct timeval start; /*!< When this transaction was created */
- dundi_eid eids[DUNDI_MAX_STACK + 1];
- int eidcount; /*!< Number of eids in eids */
- dundi_eid us_eid; /*!< Our EID, to them */
- dundi_eid them_eid; /*!< Their EID, to us */
- aes_encrypt_ctx ecx; /*!< AES 128 Encryption context */
- aes_decrypt_ctx dcx; /*!< AES 128 Decryption context */
- unsigned int flags; /*!< Has final packet been sent */
- int ttl; /*!< Remaining TTL for queries on this one */
- int thread; /*!< We have a calling thread */
- int retranstimer; /*!< How long to wait before retransmissions */
- int autokillid; /*!< ID to kill connection if answer doesn't come back fast enough */
- int autokilltimeout; /*!< Recommended timeout for autokill */
- unsigned short strans; /*!< Our transaction identifier */
- unsigned short dtrans; /*!< Their transaction identifer */
- unsigned char iseqno; /*!< Next expected received seqno */
- unsigned char oiseqno; /*!< Last received incoming seqno */
- unsigned char oseqno; /*!< Next transmitted seqno */
- unsigned char aseqno; /*!< Last acknowledge seqno */
- AST_LIST_HEAD_NOLOCK(packetlist, dundi_packet) packets; /*!< Packets to be retransmitted */
- struct packetlist lasttrans; /*!< Last transmitted / ACK'd packet */
- struct dundi_request *parent; /*!< Parent request (if there is one) */
- AST_LIST_ENTRY(dundi_transaction) parentlist; /*!< Next with respect to the parent */
- AST_LIST_ENTRY(dundi_transaction) all; /*!< Next with respect to all DUNDi transactions */
-};
-
-struct dundi_request {
- char dcontext[AST_MAX_EXTENSION];
- char number[AST_MAX_EXTENSION];
- dundi_eid query_eid;
- dundi_eid root_eid;
- struct dundi_result *dr;
- struct dundi_entity_info *dei;
- struct dundi_hint_metadata *hmd;
- int maxcount;
- int respcount;
- int expiration;
- int cbypass;
- int pfds[2];
- unsigned long crc32; /*!< CRC-32 of all but root EID's in avoid list */
- AST_LIST_HEAD_NOLOCK(, dundi_transaction) trans; /*!< Transactions */
- AST_LIST_ENTRY(dundi_request) list;
-};
-
-struct dundi_mapping {
- char dcontext[AST_MAX_EXTENSION];
- char lcontext[AST_MAX_EXTENSION];
- int weight;
- int options;
- int tech;
- int dead;
- char dest[AST_MAX_EXTENSION];
- AST_LIST_ENTRY(dundi_mapping) list;
-};
-
-struct dundi_peer {
- dundi_eid eid;
- struct sockaddr_in addr; /*!< Address of DUNDi peer */
- AST_LIST_HEAD_NOLOCK(permissionlist, permission) permit;
- struct permissionlist include;
- dundi_eid us_eid;
- char inkey[80];
- char outkey[80];
- int dead;
- int registerid;
- int qualifyid;
- int sentfullkey;
- int order;
- unsigned char txenckey[256]; /*!< Transmitted encrypted key + sig */
- unsigned char rxenckey[256]; /*!< Cache received encrypted key + sig */
- unsigned long us_keycrc32; /*!< CRC-32 of our key */
- aes_encrypt_ctx us_ecx; /*!< Cached AES 128 Encryption context */
- aes_decrypt_ctx us_dcx; /*!< Cached AES 128 Decryption context */
- unsigned long them_keycrc32; /*!< CRC-32 of our key */
- aes_encrypt_ctx them_ecx; /*!< Cached AES 128 Encryption context */
- aes_decrypt_ctx them_dcx; /*!< Cached AES 128 Decryption context */
- time_t keyexpire; /*!< When to expire/recreate key */
- int registerexpire;
- int lookuptimes[DUNDI_TIMING_HISTORY];
- char *lookups[DUNDI_TIMING_HISTORY];
- int avgms;
- struct dundi_transaction *regtrans; /*!< Registration transaction */
- struct dundi_transaction *qualtrans; /*!< Qualify transaction */
- int model; /*!< Pull model */
- int pcmodel; /*!< Push/precache model */
- /*! Dynamic peers register with us */
- unsigned int dynamic:1;
- int lastms; /*!< Last measured latency */
- int maxms; /*!< Max permissible latency */
- struct timeval qualtx; /*!< Time of transmit */
- AST_LIST_ENTRY(dundi_peer) list;
-};
-
-static AST_LIST_HEAD_STATIC(peers, dundi_peer);
-static AST_LIST_HEAD_STATIC(pcq, dundi_precache_queue);
-static AST_LIST_HEAD_NOLOCK_STATIC(mappings, dundi_mapping);
-static AST_LIST_HEAD_NOLOCK_STATIC(requests, dundi_request);
-static AST_LIST_HEAD_NOLOCK_STATIC(alltrans, dundi_transaction);
-
-/*!
- * \brief Wildcard peer
- *
- * This peer is created if the [*] entry is specified in dundi.conf
- */
-static struct dundi_peer *any_peer;
-
-static int dundi_xmit(struct dundi_packet *pack);
-
-static void dundi_debug_output(const char *data)
-{
- if (dundidebug)
- ast_verbose("%s", data);
-}
-
-static void dundi_error_output(const char *data)
-{
- ast_log(LOG_WARNING, "%s", data);
-}
-
-static int has_permission(struct permissionlist *permlist, char *cont)
-{
- struct permission *perm;
- int res = 0;
-
- AST_LIST_TRAVERSE(permlist, perm, list) {
- if (!strcasecmp(perm->name, "all") || !strcasecmp(perm->name, cont))
- res = perm->allow;
- }
-
- return res;
-}
-
-static char *tech2str(int tech)
-{
- switch(tech) {
- case DUNDI_PROTO_NONE:
- return "None";
- case DUNDI_PROTO_IAX:
- return "IAX2";
- case DUNDI_PROTO_SIP:
- return "SIP";
- case DUNDI_PROTO_H323:
- return "H323";
- default:
- return "Unknown";
- }
-}
-
-static int str2tech(char *str)
-{
- if (!strcasecmp(str, "IAX") || !strcasecmp(str, "IAX2"))
- return DUNDI_PROTO_IAX;
- else if (!strcasecmp(str, "SIP"))
- return DUNDI_PROTO_SIP;
- else if (!strcasecmp(str, "H323"))
- return DUNDI_PROTO_H323;
- else
- return -1;
-}
-
-static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, int cybpass, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int direct[]);
-static int dundi_precache_internal(const char *context, const char *number, int ttl, dundi_eid *avoids[]);
-static struct dundi_transaction *create_transaction(struct dundi_peer *p);
-static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct sockaddr_in *sin)
-{
- struct dundi_transaction *trans;
-
- /* Look for an exact match first */
- AST_LIST_TRAVERSE(&alltrans, trans, all) {
- if (!inaddrcmp(&trans->addr, sin) &&
- ((trans->strans == (ntohs(hdr->dtrans) & 32767)) /* Matches our destination */ ||
- ((trans->dtrans == (ntohs(hdr->strans) & 32767)) && (!hdr->dtrans))) /* We match their destination */) {
- if (hdr->strans)
- trans->dtrans = ntohs(hdr->strans) & 32767;
- break;
- }
- }
- if (!trans) {
- switch(hdr->cmdresp & 0x7f) {
- case DUNDI_COMMAND_DPDISCOVER:
- case DUNDI_COMMAND_EIDQUERY:
- case DUNDI_COMMAND_PRECACHERQ:
- case DUNDI_COMMAND_REGREQ:
- case DUNDI_COMMAND_NULL:
- case DUNDI_COMMAND_ENCRYPT:
- if (hdr->strans) {
- /* Create new transaction */
- trans = create_transaction(NULL);
- if (trans) {
- memcpy(&trans->addr, sin, sizeof(trans->addr));
- trans->dtrans = ntohs(hdr->strans) & 32767;
- } else
- ast_log(LOG_WARNING, "Out of memory!\n");
- }
- break;
- default:
- break;
- }
- }
- return trans;
-}
-
-static int dundi_send(struct dundi_transaction *trans, int cmdresp, int flags, int final, struct dundi_ie_data *ied);
-
-static int dundi_ack(struct dundi_transaction *trans, int final)
-{
- return dundi_send(trans, DUNDI_COMMAND_ACK, 0, final, NULL);
-}
-static void dundi_reject(struct dundi_hdr *h, struct sockaddr_in *sin)
-{
- struct {
- struct dundi_packet pack;
- struct dundi_hdr hdr;
- } tmp;
- struct dundi_transaction trans;
- /* Never respond to an INVALID with another INVALID */
- if (h->cmdresp == DUNDI_COMMAND_INVALID)
- return;
- memset(&tmp, 0, sizeof(tmp));
- memset(&trans, 0, sizeof(trans));
- memcpy(&trans.addr, sin, sizeof(trans.addr));
- tmp.hdr.strans = h->dtrans;
- tmp.hdr.dtrans = h->strans;
- tmp.hdr.iseqno = h->oseqno;
- tmp.hdr.oseqno = h->iseqno;
- tmp.hdr.cmdresp = DUNDI_COMMAND_INVALID;
- tmp.hdr.cmdflags = 0;
- tmp.pack.h = (struct dundi_hdr *)tmp.pack.data;
- tmp.pack.datalen = sizeof(struct dundi_hdr);
- tmp.pack.parent = &trans;
- dundi_xmit(&tmp.pack);
-}
-
-static void reset_global_eid(void)
-{
-#if defined(SIOCGIFHWADDR)
- int x,s;
- char eid_str[20];
- struct ifreq ifr;
-
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s > 0) {
- x = 0;
- for(x=0;x<10;x++) {
- memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth%d", x);
- if (!ioctl(s, SIOCGIFHWADDR, &ifr)) {
- memcpy(&global_eid, ((unsigned char *)&ifr.ifr_hwaddr) + 2, sizeof(global_eid));
- ast_log(LOG_DEBUG, "Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid), ifr.ifr_name);
- close(s);
- return;
- }
- }
- close(s);
- }
-#else
-#if defined(ifa_broadaddr) && !defined(SOLARIS)
- char eid_str[20];
- struct ifaddrs *ifap;
-
- if (getifaddrs(&ifap) == 0) {
- struct ifaddrs *p;
- for (p = ifap; p; p = p->ifa_next) {
- if ((p->ifa_addr->sa_family == AF_LINK) && !(p->ifa_flags & IFF_LOOPBACK) && (p->ifa_flags & IFF_RUNNING)) {
- struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr;
- memcpy(&(global_eid.eid), sdp->sdl_data + sdp->sdl_nlen, 6);
- ast_log(LOG_DEBUG, "Seeding global EID '%s' from '%s' using 'getifaddrs'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid), p->ifa_name);
- freeifaddrs(ifap);
- return;
- }
- }
- freeifaddrs(ifap);
- }
-#endif
-#endif
- ast_log(LOG_NOTICE, "No ethernet interface found for seeding global EID. You will have to set it manually.\n");
-}
-
-static int get_trans_id(void)
-{
- struct dundi_transaction *t;
- int stid = (ast_random() % 32766) + 1;
- int tid = stid;
-
- do {
- AST_LIST_TRAVERSE(&alltrans, t, all) {
- if (t->strans == tid)
- break;
- }
- if (!t)
- return tid;
- tid = (tid % 32766) + 1;
- } while (tid != stid);
-
- return 0;
-}
-
-static int reset_transaction(struct dundi_transaction *trans)
-{
- int tid;
- tid = get_trans_id();
- if (tid < 1)
- return -1;
- trans->strans = tid;
- trans->dtrans = 0;
- trans->iseqno = 0;
- trans->oiseqno = 0;
- trans->oseqno = 0;
- trans->aseqno = 0;
- ast_clear_flag(trans, FLAG_FINAL);
- return 0;
-}
-
-static struct dundi_peer *find_peer(dundi_eid *eid)
-{
- struct dundi_peer *cur = NULL;
-
- if (!eid)
- eid = &empty_eid;
-
- AST_LIST_TRAVERSE(&peers, cur, list) {
- if (!dundi_eid_cmp(&cur->eid,eid))
- break;
- }
-
- if (!cur && any_peer)
- cur = any_peer;
-
- return cur;
-}
-
-static void build_iv(unsigned char *iv)
-{
- /* XXX Would be nice to be more random XXX */
- unsigned int *fluffy;
- int x;
- fluffy = (unsigned int *)(iv);
- for (x=0;x<4;x++)
- fluffy[x] = ast_random();
-}
-
-struct dundi_query_state {
- dundi_eid *eids[DUNDI_MAX_STACK + 1];
- int directs[DUNDI_MAX_STACK + 1];
- dundi_eid reqeid;
- char called_context[AST_MAX_EXTENSION];
- char called_number[AST_MAX_EXTENSION];
- struct dundi_mapping *maps;
- int nummaps;
- int nocache;
- struct dundi_transaction *trans;
- void *chal;
- int challen;
- int ttl;
- char fluffy[0];
-};
-
-static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map, char *called_number, dundi_eid *us_eid, int anscnt, struct dundi_hint_metadata *hmd)
-{
- struct ast_flags flags = {0};
- int x;
- if (!ast_strlen_zero(map->lcontext)) {
- if (ast_exists_extension(NULL, map->lcontext, called_number, 1, NULL))
- ast_set_flag(&flags, DUNDI_FLAG_EXISTS);
- if (ast_canmatch_extension(NULL, map->lcontext, called_number, 1, NULL))
- ast_set_flag(&flags, DUNDI_FLAG_CANMATCH);
- if (ast_matchmore_extension(NULL, map->lcontext, called_number, 1, NULL))
- ast_set_flag(&flags, DUNDI_FLAG_MATCHMORE);
- if (ast_ignore_pattern(map->lcontext, called_number))
- ast_set_flag(&flags, DUNDI_FLAG_IGNOREPAT);
-
- /* Clearly we can't say 'don't ask' anymore if we found anything... */
- if (ast_test_flag(&flags, AST_FLAGS_ALL))
- ast_clear_flag_nonstd(hmd, DUNDI_HINT_DONT_ASK);
-
- if (map->options & DUNDI_FLAG_INTERNAL_NOPARTIAL) {
- /* Skip partial answers */
- ast_clear_flag(&flags, DUNDI_FLAG_MATCHMORE|DUNDI_FLAG_CANMATCH);
- }
- if (ast_test_flag(&flags, AST_FLAGS_ALL)) {
- struct varshead headp;
- struct ast_var_t *newvariable;
- ast_set_flag(&flags, map->options & 0xffff);
- ast_copy_flags(dr + anscnt, &flags, AST_FLAGS_ALL);
- dr[anscnt].techint = map->tech;
- dr[anscnt].weight = map->weight;
- dr[anscnt].expiration = dundi_cache_time;
- ast_copy_string(dr[anscnt].tech, tech2str(map->tech), sizeof(dr[anscnt].tech));
- dr[anscnt].eid = *us_eid;
- dundi_eid_to_str(dr[anscnt].eid_str, sizeof(dr[anscnt].eid_str), &dr[anscnt].eid);
- if (ast_test_flag(&flags, DUNDI_FLAG_EXISTS)) {
- AST_LIST_HEAD_INIT_NOLOCK(&headp);
- newvariable = ast_var_assign("NUMBER", called_number);
- AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
- newvariable = ast_var_assign("EID", dr[anscnt].eid_str);
- AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
- newvariable = ast_var_assign("SECRET", cursecret);
- AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
- newvariable = ast_var_assign("IPADDR", ipaddr);
- AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
- pbx_substitute_variables_varshead(&headp, map->dest, dr[anscnt].dest, sizeof(dr[anscnt].dest));
- while ((newvariable = AST_LIST_REMOVE_HEAD(&headp, entries)))
- ast_var_delete(newvariable);
- } else
- dr[anscnt].dest[0] = '\0';
- anscnt++;
- } else {
- /* No answers... Find the fewest number of digits from the
- number for which we have no answer. */
- char tmp[AST_MAX_EXTENSION + 1] = "";
- for (x = 0; x < (sizeof(tmp) - 1); x++) {
- tmp[x] = called_number[x];
- if (!tmp[x])
- break;
- if (!ast_canmatch_extension(NULL, map->lcontext, tmp, 1, NULL)) {
- /* Oops found something we can't match. If this is longer
- than the running hint, we have to consider it */
- if (strlen(tmp) > strlen(hmd->exten)) {
- ast_copy_string(hmd->exten, tmp, sizeof(hmd->exten));
- }
- break;
- }
- }
- }
- }
- return anscnt;
-}
-
-static void destroy_trans(struct dundi_transaction *trans, int fromtimeout);
-
-static void *dundi_lookup_thread(void *data)
-{
- struct dundi_query_state *st = data;
- struct dundi_result dr[MAX_RESULTS];
- struct dundi_ie_data ied;
- struct dundi_hint_metadata hmd;
- char eid_str[20];
- int res, x;
- int ouranswers=0;
- int max = 999999;
- int expiration = dundi_cache_time;
-
- ast_log(LOG_DEBUG, "Whee, looking up '%s@%s' for '%s'\n", st->called_number, st->called_context,
- st->eids[0] ? dundi_eid_to_str(eid_str, sizeof(eid_str), st->eids[0]) : "ourselves");
- memset(&ied, 0, sizeof(ied));
- memset(&dr, 0, sizeof(dr));
- memset(&hmd, 0, sizeof(hmd));
- /* Assume 'don't ask for anything' and 'unaffected', no TTL expired */
- hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED;
- for (x=0;x<st->nummaps;x++)
- ouranswers = dundi_lookup_local(dr, st->maps + x, st->called_number, &st->trans->us_eid, ouranswers, &hmd);
- if (ouranswers < 0)
- ouranswers = 0;
- for (x=0;x<ouranswers;x++) {
- if (dr[x].weight < max)
- max = dr[x].weight;
- }
-
- if (max) {
- /* If we do not have a canonical result, keep looking */
- res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, st->called_context, st->called_number, st->ttl, 1, &hmd, &expiration, st->nocache, 0, NULL, st->eids, st->directs);
- if (res > 0) {
- /* Append answer in result */
- ouranswers += res;
- } else {
- if ((res < -1) && (!ouranswers))
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_DUPLICATE, "Duplicate Request Pending");
- }
- }
- AST_LIST_LOCK(&peers);
- /* Truncate if "don't ask" isn't present */
- if (!ast_test_flag_nonstd(&hmd, DUNDI_HINT_DONT_ASK))
- hmd.exten[0] = '\0';
- if (ast_test_flag(st->trans, FLAG_DEAD)) {
- ast_log(LOG_DEBUG, "Our transaction went away!\n");
- st->trans->thread = 0;
- destroy_trans(st->trans, 0);
- } else {
- for (x=0;x<ouranswers;x++) {
- /* Add answers */
- if (dr[x].expiration && (expiration > dr[x].expiration))
- expiration = dr[x].expiration;
- dundi_ie_append_answer(&ied, DUNDI_IE_ANSWER, &dr[x].eid, dr[x].techint, dr[x].flags, dr[x].weight, dr[x].dest);
- }
- dundi_ie_append_hint(&ied, DUNDI_IE_HINT, hmd.flags, hmd.exten);
- dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, expiration);
- dundi_send(st->trans, DUNDI_COMMAND_DPRESPONSE, 0, 1, &ied);
- st->trans->thread = 0;
- }
- AST_LIST_UNLOCK(&peers);
- free(st);
- return NULL;
-}
-
-static void *dundi_precache_thread(void *data)
-{
- struct dundi_query_state *st = data;
- struct dundi_ie_data ied;
- struct dundi_hint_metadata hmd;
- char eid_str[20];
-
- ast_log(LOG_DEBUG, "Whee, precaching '%s@%s' for '%s'\n", st->called_number, st->called_context,
- st->eids[0] ? dundi_eid_to_str(eid_str, sizeof(eid_str), st->eids[0]) : "ourselves");
- memset(&ied, 0, sizeof(ied));
-
- /* Now produce precache */
- dundi_precache_internal(st->called_context, st->called_number, st->ttl, st->eids);
-
- AST_LIST_LOCK(&peers);
- /* Truncate if "don't ask" isn't present */
- if (!ast_test_flag_nonstd(&hmd, DUNDI_HINT_DONT_ASK))
- hmd.exten[0] = '\0';
- if (ast_test_flag(st->trans, FLAG_DEAD)) {
- ast_log(LOG_DEBUG, "Our transaction went away!\n");
- st->trans->thread = 0;
- destroy_trans(st->trans, 0);
- } else {
- dundi_send(st->trans, DUNDI_COMMAND_PRECACHERP, 0, 1, &ied);
- st->trans->thread = 0;
- }
- AST_LIST_UNLOCK(&peers);
- free(st);
- return NULL;
-}
-
-static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *dcontext, dundi_eid *eid, struct dundi_hint_metadata *hmd, int ttl, int blockempty, dundi_eid *avoid[]);
-
-static void *dundi_query_thread(void *data)
-{
- struct dundi_query_state *st = data;
- struct dundi_entity_info dei;
- struct dundi_ie_data ied;
- struct dundi_hint_metadata hmd;
- char eid_str[20];
- int res;
- ast_log(LOG_DEBUG, "Whee, looking up '%s@%s' for '%s'\n", st->called_number, st->called_context,
- st->eids[0] ? dundi_eid_to_str(eid_str, sizeof(eid_str), st->eids[0]) : "ourselves");
- memset(&ied, 0, sizeof(ied));
- memset(&dei, 0, sizeof(dei));
- memset(&hmd, 0, sizeof(hmd));
- if (!dundi_eid_cmp(&st->trans->us_eid, &st->reqeid)) {
- /* Ooh, it's us! */
- ast_log(LOG_DEBUG, "Neat, someone look for us!\n");
- ast_copy_string(dei.orgunit, dept, sizeof(dei.orgunit));
- ast_copy_string(dei.org, org, sizeof(dei.org));
- ast_copy_string(dei.locality, locality, sizeof(dei.locality));
- ast_copy_string(dei.stateprov, stateprov, sizeof(dei.stateprov));
- ast_copy_string(dei.country, country, sizeof(dei.country));
- ast_copy_string(dei.email, email, sizeof(dei.email));
- ast_copy_string(dei.phone, phone, sizeof(dei.phone));
- res = 1;
- } else {
- /* If we do not have a canonical result, keep looking */
- res = dundi_query_eid_internal(&dei, st->called_context, &st->reqeid, &hmd, st->ttl, 1, st->eids);
- }
- AST_LIST_LOCK(&peers);
- if (ast_test_flag(st->trans, FLAG_DEAD)) {
- ast_log(LOG_DEBUG, "Our transaction went away!\n");
- st->trans->thread = 0;
- destroy_trans(st->trans, 0);
- } else {
- if (res) {
- dundi_ie_append_str(&ied, DUNDI_IE_DEPARTMENT, dei.orgunit);
- dundi_ie_append_str(&ied, DUNDI_IE_ORGANIZATION, dei.org);
- dundi_ie_append_str(&ied, DUNDI_IE_LOCALITY, dei.locality);
- dundi_ie_append_str(&ied, DUNDI_IE_STATE_PROV, dei.stateprov);
- dundi_ie_append_str(&ied, DUNDI_IE_COUNTRY, dei.country);
- dundi_ie_append_str(&ied, DUNDI_IE_EMAIL, dei.email);
- dundi_ie_append_str(&ied, DUNDI_IE_PHONE, dei.phone);
- if (!ast_strlen_zero(dei.ipaddr))
- dundi_ie_append_str(&ied, DUNDI_IE_IPADDR, dei.ipaddr);
- }
- dundi_ie_append_hint(&ied, DUNDI_IE_HINT, hmd.flags, hmd.exten);
- dundi_send(st->trans, DUNDI_COMMAND_EIDRESPONSE, 0, 1, &ied);
- st->trans->thread = 0;
- }
- AST_LIST_UNLOCK(&peers);
- free(st);
- return NULL;
-}
-
-static int dundi_answer_entity(struct dundi_transaction *trans, struct dundi_ies *ies, char *ccontext)
-{
- struct dundi_query_state *st;
- int totallen;
- int x;
- int skipfirst=0;
- struct dundi_ie_data ied;
- char eid_str[20];
- char *s;
- pthread_t lookupthread;
- pthread_attr_t attr;
- if (ies->eidcount > 1) {
- /* Since it is a requirement that the first EID is the authenticating host
- and the last EID is the root, it is permissible that the first and last EID
- could be the same. In that case, we should go ahead copy only the "root" section
- since we will not need it for authentication. */
- if (!dundi_eid_cmp(ies->eids[0], ies->eids[ies->eidcount - 1]))
- skipfirst = 1;
- }
- totallen = sizeof(struct dundi_query_state);
- totallen += (ies->eidcount - skipfirst) * sizeof(dundi_eid);
- st = ast_calloc(1, totallen);
- if (st) {
- ast_copy_string(st->called_context, ies->called_context, sizeof(st->called_context));
- memcpy(&st->reqeid, ies->reqeid, sizeof(st->reqeid));
- st->trans = trans;
- st->ttl = ies->ttl - 1;
- if (st->ttl < 0)
- st->ttl = 0;
- s = st->fluffy;
- for (x=skipfirst;ies->eids[x];x++) {
- st->eids[x-skipfirst] = (dundi_eid *)s;
- *st->eids[x-skipfirst] = *ies->eids[x];
- s += sizeof(dundi_eid);
- }
- ast_log(LOG_DEBUG, "Answering EID query for '%s@%s'!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), ies->reqeid), ies->called_context);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- trans->thread = 1;
- if (ast_pthread_create(&lookupthread, &attr, dundi_query_thread, st)) {
- trans->thread = 0;
- ast_log(LOG_WARNING, "Unable to create thread!\n");
- free(st);
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of threads");
- dundi_send(trans, DUNDI_COMMAND_EIDRESPONSE, 0, 1, &ied);
- pthread_attr_destroy(&attr);
- return -1;
- }
- pthread_attr_destroy(&attr);
- } else {
- ast_log(LOG_WARNING, "Out of memory!\n");
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of memory");
- dundi_send(trans, DUNDI_COMMAND_EIDRESPONSE, 0, 1, &ied);
- return -1;
- }
- return 0;
-}
-
-static int cache_save_hint(dundi_eid *eidpeer, struct dundi_request *req, struct dundi_hint *hint, int expiration)
-{
- int unaffected;
- char key1[256];
- char key2[256];
- char eidpeer_str[20];
- char eidroot_str[20];
- char data[80];
- time_t timeout;
-
- if (expiration < 0)
- expiration = dundi_cache_time;
-
- /* Only cache hint if "don't ask" is there... */
- if (!ast_test_flag_nonstd(hint, htons(DUNDI_HINT_DONT_ASK)))
- return 0;
-
- unaffected = ast_test_flag_nonstd(hint, htons(DUNDI_HINT_UNAFFECTED));
-
- dundi_eid_to_str_short(eidpeer_str, sizeof(eidpeer_str), eidpeer);
- dundi_eid_to_str_short(eidroot_str, sizeof(eidroot_str), &req->root_eid);
- snprintf(key1, sizeof(key1), "hint/%s/%s/%s/e%08lx", eidpeer_str, hint->data, req->dcontext, unaffected ? 0 : req->crc32);
- snprintf(key2, sizeof(key2), "hint/%s/%s/%s/r%s", eidpeer_str, hint->data, req->dcontext, eidroot_str);
-
- time(&timeout);
- timeout += expiration;
- snprintf(data, sizeof(data), "%ld|", (long)(timeout));
-
- ast_db_put("dundi/cache", key1, data);
- ast_log(LOG_DEBUG, "Caching hint at '%s'\n", key1);
- ast_db_put("dundi/cache", key2, data);
- ast_log(LOG_DEBUG, "Caching hint at '%s'\n", key2);
- return 0;
-}
-
-static int cache_save(dundi_eid *eidpeer, struct dundi_request *req, int start, int unaffected, int expiration, int push)
-{
- int x;
- char key1[256];
- char key2[256];
- char data[1024];
- char eidpeer_str[20];
- char eidroot_str[20];
- time_t timeout;
-
- if (expiration < 1)
- expiration = dundi_cache_time;
-
- /* Keep pushes a little longer, cut pulls a little short */
- if (push)
- expiration += 10;
- else
- expiration -= 10;
- if (expiration < 1)
- expiration = 1;
- dundi_eid_to_str_short(eidpeer_str, sizeof(eidpeer_str), eidpeer);
- dundi_eid_to_str_short(eidroot_str, sizeof(eidroot_str), &req->root_eid);
- snprintf(key1, sizeof(key1), "%s/%s/%s/e%08lx", eidpeer_str, req->number, req->dcontext, unaffected ? 0 : req->crc32);
- snprintf(key2, sizeof(key2), "%s/%s/%s/r%s", eidpeer_str, req->number, req->dcontext, eidroot_str);
- /* Build request string */
- time(&timeout);
- timeout += expiration;
- snprintf(data, sizeof(data), "%ld|", (long)(timeout));
- for (x=start;x<req->respcount;x++) {
- /* Skip anything with an illegal pipe in it */
- if (strchr(req->dr[x].dest, '|'))
- continue;
- snprintf(data + strlen(data), sizeof(data) - strlen(data), "%d/%d/%d/%s/%s|",
- req->dr[x].flags, req->dr[x].weight, req->dr[x].techint, req->dr[x].dest,
- dundi_eid_to_str_short(eidpeer_str, sizeof(eidpeer_str), &req->dr[x].eid));
- }
- ast_db_put("dundi/cache", key1, data);
- ast_db_put("dundi/cache", key2, data);
- return 0;
-}
-
-static int dundi_prop_precache(struct dundi_transaction *trans, struct dundi_ies *ies, char *ccontext)
-{
- struct dundi_query_state *st;
- int totallen;
- int x,z;
- struct dundi_ie_data ied;
- char *s;
- struct dundi_result dr2[MAX_RESULTS];
- struct dundi_request dr;
- struct dundi_hint_metadata hmd;
-
- struct dundi_mapping *cur;
- int mapcount;
- int skipfirst = 0;
-
- pthread_t lookupthread;
- pthread_attr_t attr;
-
- memset(&dr2, 0, sizeof(dr2));
- memset(&dr, 0, sizeof(dr));
- memset(&hmd, 0, sizeof(hmd));
-
- /* Forge request structure to hold answers for cache */
- hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED;
- dr.dr = dr2;
- dr.maxcount = MAX_RESULTS;
- dr.expiration = dundi_cache_time;
- dr.hmd = &hmd;
- dr.pfds[0] = dr.pfds[1] = -1;
- trans->parent = &dr;
- ast_copy_string(dr.dcontext, ies->called_context ? ies->called_context : "e164", sizeof(dr.dcontext));
- ast_copy_string(dr.number, ies->called_number, sizeof(dr.number));
-
- for (x=0;x<ies->anscount;x++) {
- if (trans->parent->respcount < trans->parent->maxcount) {
- /* Make sure it's not already there */
- for (z=0;z<trans->parent->respcount;z++) {
- if ((trans->parent->dr[z].techint == ies->answers[x]->protocol) &&
- !strcmp(trans->parent->dr[z].dest, (char *)ies->answers[x]->data))
- break;
- }
- if (z == trans->parent->respcount) {
- /* Copy into parent responses */
- trans->parent->dr[trans->parent->respcount].flags = ntohs(ies->answers[x]->flags);
- trans->parent->dr[trans->parent->respcount].techint = ies->answers[x]->protocol;
- trans->parent->dr[trans->parent->respcount].weight = ntohs(ies->answers[x]->weight);
- trans->parent->dr[trans->parent->respcount].eid = ies->answers[x]->eid;
- if (ies->expiration > 0)
- trans->parent->dr[trans->parent->respcount].expiration = ies->expiration;
- else
- trans->parent->dr[trans->parent->respcount].expiration = dundi_cache_time;
- dundi_eid_to_str(trans->parent->dr[trans->parent->respcount].eid_str,
- sizeof(trans->parent->dr[trans->parent->respcount].eid_str),
- &ies->answers[x]->eid);
- ast_copy_string(trans->parent->dr[trans->parent->respcount].dest, (char *)ies->answers[x]->data,
- sizeof(trans->parent->dr[trans->parent->respcount].dest));
- ast_copy_string(trans->parent->dr[trans->parent->respcount].tech, tech2str(ies->answers[x]->protocol),
- sizeof(trans->parent->dr[trans->parent->respcount].tech));
- trans->parent->respcount++;
- ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK);
- } else if (trans->parent->dr[z].weight > ies->answers[x]->weight) {
- /* Update weight if appropriate */
- trans->parent->dr[z].weight = ies->answers[x]->weight;
- }
- } else
- ast_log(LOG_NOTICE, "Dropping excessive answers in precache for %s@%s\n",
- trans->parent->number, trans->parent->dcontext);
-
- }
- /* Save all the results (if any) we had. Even if no results, still cache lookup. */
- cache_save(&trans->them_eid, trans->parent, 0, 0, ies->expiration, 1);
- if (ies->hint)
- cache_save_hint(&trans->them_eid, trans->parent, ies->hint, ies->expiration);
-
- totallen = sizeof(struct dundi_query_state);
- /* Count matching map entries */
- mapcount = 0;
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- if (!strcasecmp(cur->dcontext, ccontext))
- mapcount++;
- }
-
- /* If no maps, return -1 immediately */
- if (!mapcount)
- return -1;
-
- if (ies->eidcount > 1) {
- /* Since it is a requirement that the first EID is the authenticating host
- and the last EID is the root, it is permissible that the first and last EID
- could be the same. In that case, we should go ahead copy only the "root" section
- since we will not need it for authentication. */
- if (!dundi_eid_cmp(ies->eids[0], ies->eids[ies->eidcount - 1]))
- skipfirst = 1;
- }
-
- /* Prepare to run a query and then propagate that as necessary */
- totallen += mapcount * sizeof(struct dundi_mapping);
- totallen += (ies->eidcount - skipfirst) * sizeof(dundi_eid);
- st = ast_calloc(1, totallen);
- if (st) {
- ast_copy_string(st->called_context, ies->called_context, sizeof(st->called_context));
- ast_copy_string(st->called_number, ies->called_number, sizeof(st->called_number));
- st->trans = trans;
- st->ttl = ies->ttl - 1;
- st->nocache = ies->cbypass;
- if (st->ttl < 0)
- st->ttl = 0;
- s = st->fluffy;
- for (x=skipfirst;ies->eids[x];x++) {
- st->eids[x-skipfirst] = (dundi_eid *)s;
- *st->eids[x-skipfirst] = *ies->eids[x];
- st->directs[x-skipfirst] = ies->eid_direct[x];
- s += sizeof(dundi_eid);
- }
- /* Append mappings */
- x = 0;
- st->maps = (struct dundi_mapping *)s;
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- if (!strcasecmp(cur->dcontext, ccontext)) {
- if (x < mapcount) {
- st->maps[x] = *cur;
- st->maps[x].list.next = NULL;
- x++;
- }
- }
- }
- st->nummaps = mapcount;
- ast_log(LOG_DEBUG, "Forwarding precache for '%s@%s'!\n", ies->called_number, ies->called_context);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- trans->thread = 1;
- if (ast_pthread_create(&lookupthread, &attr, dundi_precache_thread, st)) {
- trans->thread = 0;
- ast_log(LOG_WARNING, "Unable to create thread!\n");
- free(st);
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of threads");
- dundi_send(trans, DUNDI_COMMAND_PRECACHERP, 0, 1, &ied);
- pthread_attr_destroy(&attr);
- return -1;
- }
- pthread_attr_destroy(&attr);
- } else {
- ast_log(LOG_WARNING, "Out of memory!\n");
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of memory");
- dundi_send(trans, DUNDI_COMMAND_PRECACHERP, 0, 1, &ied);
- return -1;
- }
- return 0;
-}
-
-static int dundi_answer_query(struct dundi_transaction *trans, struct dundi_ies *ies, char *ccontext)
-{
- struct dundi_query_state *st;
- int totallen;
- int x;
- struct dundi_ie_data ied;
- char *s;
- struct dundi_mapping *cur;
- int mapcount = 0;
- int skipfirst = 0;
-
- pthread_t lookupthread;
- pthread_attr_t attr;
- totallen = sizeof(struct dundi_query_state);
- /* Count matching map entries */
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- if (!strcasecmp(cur->dcontext, ccontext))
- mapcount++;
- }
- /* If no maps, return -1 immediately */
- if (!mapcount)
- return -1;
-
- if (ies->eidcount > 1) {
- /* Since it is a requirement that the first EID is the authenticating host
- and the last EID is the root, it is permissible that the first and last EID
- could be the same. In that case, we should go ahead copy only the "root" section
- since we will not need it for authentication. */
- if (!dundi_eid_cmp(ies->eids[0], ies->eids[ies->eidcount - 1]))
- skipfirst = 1;
- }
-
- totallen += mapcount * sizeof(struct dundi_mapping);
- totallen += (ies->eidcount - skipfirst) * sizeof(dundi_eid);
- st = ast_calloc(1, totallen);
- if (st) {
- ast_copy_string(st->called_context, ies->called_context, sizeof(st->called_context));
- ast_copy_string(st->called_number, ies->called_number, sizeof(st->called_number));
- st->trans = trans;
- st->ttl = ies->ttl - 1;
- st->nocache = ies->cbypass;
- if (st->ttl < 0)
- st->ttl = 0;
- s = st->fluffy;
- for (x=skipfirst;ies->eids[x];x++) {
- st->eids[x-skipfirst] = (dundi_eid *)s;
- *st->eids[x-skipfirst] = *ies->eids[x];
- st->directs[x-skipfirst] = ies->eid_direct[x];
- s += sizeof(dundi_eid);
- }
- /* Append mappings */
- x = 0;
- st->maps = (struct dundi_mapping *)s;
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- if (!strcasecmp(cur->dcontext, ccontext)) {
- if (x < mapcount) {
- st->maps[x] = *cur;
- st->maps[x].list.next = NULL;
- x++;
- }
- }
- }
- st->nummaps = mapcount;
- ast_log(LOG_DEBUG, "Answering query for '%s@%s'!\n", ies->called_number, ies->called_context);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- trans->thread = 1;
- if (ast_pthread_create(&lookupthread, &attr, dundi_lookup_thread, st)) {
- trans->thread = 0;
- ast_log(LOG_WARNING, "Unable to create thread!\n");
- free(st);
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of threads");
- dundi_send(trans, DUNDI_COMMAND_DPRESPONSE, 0, 1, &ied);
- pthread_attr_destroy(&attr);
- return -1;
- }
- pthread_attr_destroy(&attr);
- } else {
- ast_log(LOG_WARNING, "Out of memory!\n");
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of memory");
- dundi_send(trans, DUNDI_COMMAND_DPRESPONSE, 0, 1, &ied);
- return -1;
- }
- return 0;
-}
-
-static int cache_lookup_internal(time_t now, struct dundi_request *req, char *key, char *eid_str_full, int *lowexpiration)
-{
- char data[1024];
- char *ptr, *term, *src;
- int tech;
- struct ast_flags flags;
- int weight;
- int length;
- int z;
- char fs[256];
-
- /* Build request string */
- if (!ast_db_get("dundi/cache", key, data, sizeof(data))) {
- time_t timeout;
- ptr = data;
- if (!ast_get_time_t(ptr, &timeout, 0, &length)) {
- int expiration = timeout - now;
- if (expiration > 0) {
- ast_log(LOG_DEBUG, "Found cache expiring in %d seconds!\n", expiration);
- ptr += length + 1;
- while((sscanf(ptr, "%d/%d/%d/%n", &(flags.flags), &weight, &tech, &length) == 3)) {
- ptr += length;
- term = strchr(ptr, '|');
- if (term) {
- *term = '\0';
- src = strrchr(ptr, '/');
- if (src) {
- *src = '\0';
- src++;
- } else
- src = "";
- ast_log(LOG_DEBUG, "Found cached answer '%s/%s' originally from '%s' with flags '%s' on behalf of '%s'\n",
- tech2str(tech), ptr, src, dundi_flags2str(fs, sizeof(fs), flags.flags), eid_str_full);
- /* Make sure it's not already there */
- for (z=0;z<req->respcount;z++) {
- if ((req->dr[z].techint == tech) &&
- !strcmp(req->dr[z].dest, ptr))
- break;
- }
- if (z == req->respcount) {
- /* Copy into parent responses */
- ast_copy_flags(&(req->dr[req->respcount]), &flags, AST_FLAGS_ALL);
- req->dr[req->respcount].weight = weight;
- req->dr[req->respcount].techint = tech;
- req->dr[req->respcount].expiration = expiration;
- dundi_str_short_to_eid(&req->dr[req->respcount].eid, src);
- dundi_eid_to_str(req->dr[req->respcount].eid_str,
- sizeof(req->dr[req->respcount].eid_str), &req->dr[req->respcount].eid);
- ast_copy_string(req->dr[req->respcount].dest, ptr,
- sizeof(req->dr[req->respcount].dest));
- ast_copy_string(req->dr[req->respcount].tech, tech2str(tech),
- sizeof(req->dr[req->respcount].tech));
- req->respcount++;
- ast_clear_flag_nonstd(req->hmd, DUNDI_HINT_DONT_ASK);
- } else if (req->dr[z].weight > weight)
- req->dr[z].weight = weight;
- ptr = term + 1;
- }
- }
- /* We found *something* cached */
- if (expiration < *lowexpiration)
- *lowexpiration = expiration;
- return 1;
- } else
- ast_db_del("dundi/cache", key);
- } else
- ast_db_del("dundi/cache", key);
- }
-
- return 0;
-}
-
-static int cache_lookup(struct dundi_request *req, dundi_eid *peer_eid, unsigned long crc32, int *lowexpiration)
-{
- char key[256];
- char eid_str[20];
- char eidroot_str[20];
- time_t now;
- int res=0;
- int res2=0;
- char eid_str_full[20];
- char tmp[256]="";
- int x;
-
- time(&now);
- dundi_eid_to_str_short(eid_str, sizeof(eid_str), peer_eid);
- dundi_eid_to_str_short(eidroot_str, sizeof(eidroot_str), &req->root_eid);
- dundi_eid_to_str(eid_str_full, sizeof(eid_str_full), peer_eid);
- snprintf(key, sizeof(key), "%s/%s/%s/e%08lx", eid_str, req->number, req->dcontext, crc32);
- res |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration);
- snprintf(key, sizeof(key), "%s/%s/%s/e%08lx", eid_str, req->number, req->dcontext, 0L);
- res |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration);
- snprintf(key, sizeof(key), "%s/%s/%s/r%s", eid_str, req->number, req->dcontext, eidroot_str);
- res |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration);
- x = 0;
- if (!req->respcount) {
- while(!res2) {
- /* Look and see if we have a hint that would preclude us from looking at this
- peer for this number. */
- if (!(tmp[x] = req->number[x]))
- break;
- x++;
- /* Check for hints */
- snprintf(key, sizeof(key), "hint/%s/%s/%s/e%08lx", eid_str, tmp, req->dcontext, crc32);
- res2 |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration);
- snprintf(key, sizeof(key), "hint/%s/%s/%s/e%08lx", eid_str, tmp, req->dcontext, 0L);
- res2 |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration);
- snprintf(key, sizeof(key), "hint/%s/%s/%s/r%s", eid_str, tmp, req->dcontext, eidroot_str);
- res2 |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration);
- if (res2) {
- if (strlen(tmp) > strlen(req->hmd->exten)) {
- /* Update meta data if appropriate */
- ast_copy_string(req->hmd->exten, tmp, sizeof(req->hmd->exten));
- }
- }
- }
- res |= res2;
- }
-
- return res;
-}
-
-static void qualify_peer(struct dundi_peer *peer, int schedonly);
-
-static void apply_peer(struct dundi_transaction *trans, struct dundi_peer *p)
-{
- if (!trans->addr.sin_addr.s_addr)
- memcpy(&trans->addr, &p->addr, sizeof(trans->addr));
- trans->us_eid = p->us_eid;
- trans->them_eid = p->eid;
- /* Enable encryption if appropriate */
- if (!ast_strlen_zero(p->inkey))
- ast_set_flag(trans, FLAG_ENCRYPT);
- if (p->maxms) {
- trans->autokilltimeout = p->maxms;
- trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER;
- if (p->lastms > 1) {
- trans->retranstimer = p->lastms * 2;
- /* Keep it from being silly */
- if (trans->retranstimer < 150)
- trans->retranstimer = 150;
- }
- if (trans->retranstimer > DUNDI_DEFAULT_RETRANS_TIMER)
- trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER;
- } else
- trans->autokilltimeout = global_autokilltimeout;
-}
-
-/*! \note Called with the peers list already locked */
-static int do_register_expire(const void *data)
-{
- struct dundi_peer *peer = (struct dundi_peer *)data;
- char eid_str[20];
- ast_log(LOG_DEBUG, "Register expired for '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- peer->registerexpire = -1;
- peer->lastms = 0;
- memset(&peer->addr, 0, sizeof(peer->addr));
- return 0;
-}
-
-static int update_key(struct dundi_peer *peer)
-{
- unsigned char key[16];
- struct ast_key *ekey, *skey;
- char eid_str[20];
- int res;
- if (!peer->keyexpire || (peer->keyexpire < time(NULL))) {
- build_iv(key);
- aes_encrypt_key128(key, &peer->us_ecx);
- aes_decrypt_key128(key, &peer->us_dcx);
- ekey = ast_key_get(peer->inkey, AST_KEY_PUBLIC);
- if (!ekey) {
- ast_log(LOG_NOTICE, "No such key '%s' for creating RSA encrypted shared key for '%s'!\n",
- peer->inkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- return -1;
- }
- skey = ast_key_get(peer->outkey, AST_KEY_PRIVATE);
- if (!skey) {
- ast_log(LOG_NOTICE, "No such key '%s' for signing RSA encrypted shared key for '%s'!\n",
- peer->outkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- return -1;
- }
- if ((res = ast_encrypt_bin(peer->txenckey, key, sizeof(key), ekey)) != 128) {
- ast_log(LOG_NOTICE, "Whoa, got a weird encrypt size (%d != %d)!\n", res, 128);
- return -1;
- }
- if ((res = ast_sign_bin(skey, (char *)peer->txenckey, 128, peer->txenckey + 128))) {
- ast_log(LOG_NOTICE, "Failed to sign key (%d)!\n", res);
- return -1;
- }
- peer->us_keycrc32 = crc32(0L, peer->txenckey, 128);
- peer->sentfullkey = 0;
- /* Looks good */
- time(&peer->keyexpire);
- peer->keyexpire += dundi_key_ttl;
- }
- return 0;
-}
-
-static int encrypt_memcpy(unsigned char *dst, unsigned char *src, int len, unsigned char *iv, aes_encrypt_ctx *ecx)
-{
- unsigned char curblock[16];
- int x;
- memcpy(curblock, iv, sizeof(curblock));
- while(len > 0) {
- for (x=0;x<16;x++)
- curblock[x] ^= src[x];
- aes_encrypt(curblock, dst, ecx);
- memcpy(curblock, dst, sizeof(curblock));
- dst += 16;
- src += 16;
- len -= 16;
- }
- return 0;
-}
-static int decrypt_memcpy(unsigned char *dst, unsigned char *src, int len, unsigned char *iv, aes_decrypt_ctx *dcx)
-{
- unsigned char lastblock[16];
- int x;
- memcpy(lastblock, iv, sizeof(lastblock));
- while(len > 0) {
- aes_decrypt(src, dst, dcx);
- for (x=0;x<16;x++)
- dst[x] ^= lastblock[x];
- memcpy(lastblock, src, sizeof(lastblock));
- dst += 16;
- src += 16;
- len -= 16;
- }
- return 0;
-}
-
-static struct dundi_hdr *dundi_decrypt(struct dundi_transaction *trans, unsigned char *dst, int *dstlen, struct dundi_hdr *ohdr, struct dundi_encblock *src, int srclen)
-{
- int space = *dstlen;
- unsigned long bytes;
- struct dundi_hdr *h;
- unsigned char *decrypt_space;
- decrypt_space = alloca(srclen);
- if (!decrypt_space)
- return NULL;
- decrypt_memcpy(decrypt_space, src->encdata, srclen, src->iv, &trans->dcx);
- /* Setup header */
- h = (struct dundi_hdr *)dst;
- *h = *ohdr;
- bytes = space - 6;
- if (uncompress(dst + 6, &bytes, decrypt_space, srclen) != Z_OK) {
- ast_log(LOG_DEBUG, "Ouch, uncompress failed :(\n");
- return NULL;
- }
- /* Update length */
- *dstlen = bytes + 6;
- /* Return new header */
- return h;
-}
-
-static int dundi_encrypt(struct dundi_transaction *trans, struct dundi_packet *pack)
-{
- unsigned char *compress_space;
- int len;
- int res;
- unsigned long bytes;
- struct dundi_ie_data ied;
- struct dundi_peer *peer;
- unsigned char iv[16];
- len = pack->datalen + pack->datalen / 100 + 42;
- compress_space = alloca(len);
- if (compress_space) {
- memset(compress_space, 0, len);
- /* We care about everthing save the first 6 bytes of header */
- bytes = len;
- res = compress(compress_space, &bytes, pack->data + 6, pack->datalen - 6);
- if (res != Z_OK) {
- ast_log(LOG_DEBUG, "Ouch, compression failed!\n");
- return -1;
- }
- memset(&ied, 0, sizeof(ied));
- /* Say who we are */
- if (!pack->h->iseqno && !pack->h->oseqno) {
- /* Need the key in the first copy */
- if (!(peer = find_peer(&trans->them_eid)))
- return -1;
- if (update_key(peer))
- return -1;
- if (!peer->sentfullkey)
- ast_set_flag(trans, FLAG_SENDFULLKEY);
- /* Append key data */
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid);
- if (ast_test_flag(trans, FLAG_SENDFULLKEY)) {
- dundi_ie_append_raw(&ied, DUNDI_IE_SHAREDKEY, peer->txenckey, 128);
- dundi_ie_append_raw(&ied, DUNDI_IE_SIGNATURE, peer->txenckey + 128, 128);
- } else {
- dundi_ie_append_int(&ied, DUNDI_IE_KEYCRC32, peer->us_keycrc32);
- }
- /* Setup contexts */
- trans->ecx = peer->us_ecx;
- trans->dcx = peer->us_dcx;
-
- /* We've sent the full key */
- peer->sentfullkey = 1;
- }
- /* Build initialization vector */
- build_iv(iv);
- /* Add the field, rounded up to 16 bytes */
- dundi_ie_append_encdata(&ied, DUNDI_IE_ENCDATA, iv, NULL, ((bytes + 15) / 16) * 16);
- /* Copy the data */
- if ((ied.pos + bytes) >= sizeof(ied.buf)) {
- ast_log(LOG_NOTICE, "Final packet too large!\n");
- return -1;
- }
- encrypt_memcpy(ied.buf + ied.pos, compress_space, bytes, iv, &trans->ecx);
- ied.pos += ((bytes + 15) / 16) * 16;
- /* Reconstruct header */
- pack->datalen = sizeof(struct dundi_hdr);
- pack->h->cmdresp = DUNDI_COMMAND_ENCRYPT;
- pack->h->cmdflags = 0;
- memcpy(pack->h->ies, ied.buf, ied.pos);
- pack->datalen += ied.pos;
- return 0;
- }
- return -1;
-}
-
-static int check_key(struct dundi_peer *peer, unsigned char *newkey, unsigned char *newsig, unsigned long keycrc32)
-{
- unsigned char dst[128];
- int res;
- struct ast_key *key, *skey;
- char eid_str[20];
- if (option_debug)
- ast_log(LOG_DEBUG, "Expected '%08lx' got '%08lx'\n", peer->them_keycrc32, keycrc32);
- if (peer->them_keycrc32 && (peer->them_keycrc32 == keycrc32)) {
- /* A match */
- return 1;
- } else if (!newkey || !newsig)
- return 0;
- if (!memcmp(peer->rxenckey, newkey, 128) &&
- !memcmp(peer->rxenckey + 128, newsig, 128)) {
- /* By definition, a match */
- return 1;
- }
- /* Decrypt key */
- key = ast_key_get(peer->outkey, AST_KEY_PRIVATE);
- if (!key) {
- ast_log(LOG_NOTICE, "Unable to find key '%s' to decode shared key from '%s'\n",
- peer->outkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- return -1;
- }
-
- skey = ast_key_get(peer->inkey, AST_KEY_PUBLIC);
- if (!skey) {
- ast_log(LOG_NOTICE, "Unable to find key '%s' to verify shared key from '%s'\n",
- peer->inkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- return -1;
- }
-
- /* First check signature */
- res = ast_check_signature_bin(skey, (char *)newkey, 128, newsig);
- if (res)
- return 0;
-
- res = ast_decrypt_bin(dst, newkey, sizeof(dst), key);
- if (res != 16) {
- if (res >= 0)
- ast_log(LOG_NOTICE, "Weird, key decoded to the wrong size (%d)\n", res);
- return 0;
- }
- /* Decrypted, passes signature */
- ast_log(LOG_DEBUG, "Wow, new key combo passed signature and decrypt!\n");
- memcpy(peer->rxenckey, newkey, 128);
- memcpy(peer->rxenckey + 128, newsig, 128);
- peer->them_keycrc32 = crc32(0L, peer->rxenckey, 128);
- aes_decrypt_key128(dst, &peer->them_dcx);
- aes_encrypt_key128(dst, &peer->them_ecx);
- return 1;
-}
-
-static void deep_copy_peer(struct dundi_peer *peer_dst, const struct dundi_peer *peer_src)
-{
- struct permission *cur, *perm;
-
- memcpy(peer_dst, peer_src, sizeof(*peer_dst));
-
- memset(&peer_dst->permit, 0, sizeof(peer_dst->permit));
- memset(&peer_dst->include, 0, sizeof(peer_dst->permit));
-
- AST_LIST_TRAVERSE(&peer_src->permit, cur, list) {
- if (!(perm = ast_calloc(1, sizeof(*perm) + strlen(cur->name) + 1)))
- continue;
-
- perm->allow = cur->allow;
- strcpy(perm->name, cur->name);
-
- AST_LIST_INSERT_HEAD(&peer_dst->permit, perm, list);
- }
-
- AST_LIST_TRAVERSE(&peer_src->include, cur, list) {
- if (!(perm = ast_calloc(1, sizeof(*perm) + strlen(cur->name) + 1)))
- continue;
-
- perm->allow = cur->allow;
- strcpy(perm->name, cur->name);
-
- AST_LIST_INSERT_HEAD(&peer_dst->include, perm, list);
- }
-}
-
-static int handle_command_response(struct dundi_transaction *trans, struct dundi_hdr *hdr, int datalen, int encrypted)
-{
- /* Handle canonical command / response */
- int final = hdr->cmdresp & 0x80;
- int cmd = hdr->cmdresp & 0x7f;
- int x,y,z;
- int resp;
- int res;
- int authpass=0;
- unsigned char *bufcpy;
- struct dundi_ie_data ied;
- struct dundi_ies ies;
- struct dundi_peer *peer = NULL;
- char eid_str[20];
- char eid_str2[20];
- memset(&ied, 0, sizeof(ied));
- memset(&ies, 0, sizeof(ies));
- if (datalen) {
- bufcpy = alloca(datalen);
- if (!bufcpy)
- return -1;
- /* Make a copy for parsing */
- memcpy(bufcpy, hdr->ies, datalen);
- ast_log(LOG_DEBUG, "Got canonical message %d (%d), %d bytes data%s\n", cmd, hdr->oseqno, datalen, final ? " (Final)" : "");
- if (dundi_parse_ies(&ies, bufcpy, datalen) < 0) {
- ast_log(LOG_WARNING, "Failed to parse DUNDI information elements!\n");
- return -1;
- }
- }
- switch(cmd) {
- case DUNDI_COMMAND_DPDISCOVER:
- case DUNDI_COMMAND_EIDQUERY:
- case DUNDI_COMMAND_PRECACHERQ:
- if (cmd == DUNDI_COMMAND_EIDQUERY)
- resp = DUNDI_COMMAND_EIDRESPONSE;
- else if (cmd == DUNDI_COMMAND_PRECACHERQ)
- resp = DUNDI_COMMAND_PRECACHERP;
- else
- resp = DUNDI_COMMAND_DPRESPONSE;
- /* A dialplan or entity discover -- qualify by highest level entity */
- peer = find_peer(ies.eids[0]);
- if (!peer) {
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL);
- dundi_send(trans, resp, 0, 1, &ied);
- } else {
- int hasauth = 0;
- trans->us_eid = peer->us_eid;
- if (strlen(peer->inkey)) {
- hasauth = encrypted;
- } else
- hasauth = 1;
- if (hasauth) {
- /* Okay we're authentiated and all, now we check if they're authorized */
- if (!ies.called_context)
- ies.called_context = "e164";
- if (cmd == DUNDI_COMMAND_EIDQUERY) {
- res = dundi_answer_entity(trans, &ies, ies.called_context);
- } else {
- if (ast_strlen_zero(ies.called_number)) {
- /* They're not permitted to access that context */
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Invalid or missing number/entity");
- dundi_send(trans, resp, 0, 1, &ied);
- } else if ((cmd == DUNDI_COMMAND_DPDISCOVER) &&
- (peer->model & DUNDI_MODEL_INBOUND) &&
- has_permission(&peer->permit, ies.called_context)) {
- res = dundi_answer_query(trans, &ies, ies.called_context);
- if (res < 0) {
- /* There is no such dundi context */
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context");
- dundi_send(trans, resp, 0, 1, &ied);
- }
- } else if ((cmd = DUNDI_COMMAND_PRECACHERQ) &&
- (peer->pcmodel & DUNDI_MODEL_INBOUND) &&
- has_permission(&peer->include, ies.called_context)) {
- res = dundi_prop_precache(trans, &ies, ies.called_context);
- if (res < 0) {
- /* There is no such dundi context */
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context");
- dundi_send(trans, resp, 0, 1, &ied);
- }
- } else {
- /* They're not permitted to access that context */
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Permission to context denied");
- dundi_send(trans, resp, 0, 1, &ied);
- }
- }
- } else {
- /* They're not permitted to access that context */
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unencrypted responses not permitted");
- dundi_send(trans, resp, 0, 1, &ied);
- }
- }
- break;
- case DUNDI_COMMAND_REGREQ:
- /* A register request -- should only have one entity */
- peer = find_peer(ies.eids[0]);
-
- /* if the peer is not found and we have a valid 'any_peer' setting */
- if (any_peer && peer == any_peer) {
- /* copy any_peer into a new peer object */
- peer = ast_calloc(1, sizeof(*peer));
- if (peer) {
- deep_copy_peer(peer, any_peer);
-
- /* set EID to remote EID */
- peer->eid = *ies.eids[0];
-
- AST_LIST_LOCK(&peers);
- AST_LIST_INSERT_HEAD(&peers, peer, list);
- AST_LIST_UNLOCK(&peers);
- }
- }
-
- if (!peer || !peer->dynamic) {
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL);
- dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, &ied);
- } else {
- int hasauth = 0;
- trans->us_eid = peer->us_eid;
- if (!ast_strlen_zero(peer->inkey)) {
- hasauth = encrypted;
- } else
- hasauth = 1;
- if (hasauth) {
- int expire = default_expiration;
- char data[256];
- int needqual = 0;
- AST_SCHED_DEL(sched, peer->registerexpire);
- peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer);
- snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(trans->addr.sin_addr),
- ntohs(trans->addr.sin_port), expire);
- ast_db_put("dundi/dpeers", dundi_eid_to_str_short(eid_str, sizeof(eid_str), &peer->eid), data);
- if (inaddrcmp(&peer->addr, &trans->addr)) {
- if (option_verbose > 2) {
- ast_verbose(VERBOSE_PREFIX_3 "Registered DUNDi peer '%s' at '%s:%d'\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
- ast_inet_ntoa(trans->addr.sin_addr), ntohs(trans->addr.sin_port));
- }
- needqual = 1;
- }
-
- memcpy(&peer->addr, &trans->addr, sizeof(peer->addr));
- dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, default_expiration);
- dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, &ied);
- if (needqual)
- qualify_peer(peer, 1);
- }
- }
- break;
- case DUNDI_COMMAND_DPRESPONSE:
- /* A dialplan response, lets see what we got... */
- if (ies.cause < 1) {
- /* Success of some sort */
- ast_log(LOG_DEBUG, "Looks like success of some sort (%d), %d answers\n", ies.cause, ies.anscount);
- if (ast_test_flag(trans, FLAG_ENCRYPT)) {
- authpass = encrypted;
- } else
- authpass = 1;
- if (authpass) {
- /* Pass back up answers */
- if (trans->parent && trans->parent->dr) {
- y = trans->parent->respcount;
- for (x=0;x<ies.anscount;x++) {
- if (trans->parent->respcount < trans->parent->maxcount) {
- /* Make sure it's not already there */
- for (z=0;z<trans->parent->respcount;z++) {
- if ((trans->parent->dr[z].techint == ies.answers[x]->protocol) &&
- !strcmp(trans->parent->dr[z].dest, (char *)ies.answers[x]->data))
- break;
- }
- if (z == trans->parent->respcount) {
- /* Copy into parent responses */
- trans->parent->dr[trans->parent->respcount].flags = ntohs(ies.answers[x]->flags);
- trans->parent->dr[trans->parent->respcount].techint = ies.answers[x]->protocol;
- trans->parent->dr[trans->parent->respcount].weight = ntohs(ies.answers[x]->weight);
- trans->parent->dr[trans->parent->respcount].eid = ies.answers[x]->eid;
- if (ies.expiration > 0)
- trans->parent->dr[trans->parent->respcount].expiration = ies.expiration;
- else
- trans->parent->dr[trans->parent->respcount].expiration = dundi_cache_time;
- dundi_eid_to_str(trans->parent->dr[trans->parent->respcount].eid_str,
- sizeof(trans->parent->dr[trans->parent->respcount].eid_str),
- &ies.answers[x]->eid);
- ast_copy_string(trans->parent->dr[trans->parent->respcount].dest, (char *)ies.answers[x]->data,
- sizeof(trans->parent->dr[trans->parent->respcount].dest));
- ast_copy_string(trans->parent->dr[trans->parent->respcount].tech, tech2str(ies.answers[x]->protocol),
- sizeof(trans->parent->dr[trans->parent->respcount].tech));
- trans->parent->respcount++;
- ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK);
- } else if (trans->parent->dr[z].weight > ies.answers[x]->weight) {
- /* Update weight if appropriate */
- trans->parent->dr[z].weight = ies.answers[x]->weight;
- }
- } else
- ast_log(LOG_NOTICE, "Dropping excessive answers to request for %s@%s\n",
- trans->parent->number, trans->parent->dcontext);
- }
- /* Save all the results (if any) we had. Even if no results, still cache lookup. Let
- the cache know if this request was unaffected by our entity list. */
- cache_save(&trans->them_eid, trans->parent, y,
- ies.hint ? ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_UNAFFECTED)) : 0, ies.expiration, 0);
- if (ies.hint) {
- cache_save_hint(&trans->them_eid, trans->parent, ies.hint, ies.expiration);
- if (ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_TTL_EXPIRED)))
- ast_set_flag_nonstd(trans->parent->hmd, DUNDI_HINT_TTL_EXPIRED);
- if (ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_DONT_ASK))) {
- if (strlen((char *)ies.hint->data) > strlen(trans->parent->hmd->exten)) {
- ast_copy_string(trans->parent->hmd->exten, (char *)ies.hint->data,
- sizeof(trans->parent->hmd->exten));
- }
- } else {
- ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK);
- }
- }
- if (ies.expiration > 0) {
- if (trans->parent->expiration > ies.expiration) {
- trans->parent->expiration = ies.expiration;
- }
- }
- }
- /* Close connection if not final */
- if (!final)
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
-
- } else {
- /* Auth failure, check for data */
- if (!final) {
- /* Cancel if they didn't already */
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
- }
- break;
- case DUNDI_COMMAND_EIDRESPONSE:
- /* A dialplan response, lets see what we got... */
- if (ies.cause < 1) {
- /* Success of some sort */
- ast_log(LOG_DEBUG, "Looks like success of some sort (%d)\n", ies.cause);
- if (ast_test_flag(trans, FLAG_ENCRYPT)) {
- authpass = encrypted;
- } else
- authpass = 1;
- if (authpass) {
- /* Pass back up answers */
- if (trans->parent && trans->parent->dei && ies.q_org) {
- if (!trans->parent->respcount) {
- trans->parent->respcount++;
- if (ies.q_dept)
- ast_copy_string(trans->parent->dei->orgunit, ies.q_dept, sizeof(trans->parent->dei->orgunit));
- if (ies.q_org)
- ast_copy_string(trans->parent->dei->org, ies.q_org, sizeof(trans->parent->dei->org));
- if (ies.q_locality)
- ast_copy_string(trans->parent->dei->locality, ies.q_locality, sizeof(trans->parent->dei->locality));
- if (ies.q_stateprov)
- ast_copy_string(trans->parent->dei->stateprov, ies.q_stateprov, sizeof(trans->parent->dei->stateprov));
- if (ies.q_country)
- ast_copy_string(trans->parent->dei->country, ies.q_country, sizeof(trans->parent->dei->country));
- if (ies.q_email)
- ast_copy_string(trans->parent->dei->email, ies.q_email, sizeof(trans->parent->dei->email));
- if (ies.q_phone)
- ast_copy_string(trans->parent->dei->phone, ies.q_phone, sizeof(trans->parent->dei->phone));
- if (ies.q_ipaddr)
- ast_copy_string(trans->parent->dei->ipaddr, ies.q_ipaddr, sizeof(trans->parent->dei->ipaddr));
- if (!dundi_eid_cmp(&trans->them_eid, &trans->parent->query_eid)) {
- /* If it's them, update our address */
- ast_copy_string(trans->parent->dei->ipaddr, ast_inet_ntoa(trans->addr.sin_addr), sizeof(trans->parent->dei->ipaddr));
- }
- }
- if (ies.hint) {
- if (ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_TTL_EXPIRED)))
- ast_set_flag_nonstd(trans->parent->hmd, DUNDI_HINT_TTL_EXPIRED);
- }
- }
- /* Close connection if not final */
- if (!final)
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
-
- } else {
- /* Auth failure, check for data */
- if (!final) {
- /* Cancel if they didn't already */
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
- }
- break;
- case DUNDI_COMMAND_REGRESPONSE:
- /* A dialplan response, lets see what we got... */
- if (ies.cause < 1) {
- int hasauth;
- /* Success of some sort */
- if (ast_test_flag(trans, FLAG_ENCRYPT)) {
- hasauth = encrypted;
- } else
- hasauth = 1;
-
- if (!hasauth) {
- ast_log(LOG_NOTICE, "Reponse to register not authorized!\n");
- if (!final) {
- dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Improper signature in answer");
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, &ied);
- }
- } else {
- ast_log(LOG_DEBUG, "Yay, we've registered as '%s' to '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &trans->us_eid),
- dundi_eid_to_str(eid_str2, sizeof(eid_str2), &trans->them_eid));
- /* Close connection if not final */
- if (!final)
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
- } else {
- /* Auth failure, cancel if they didn't for some reason */
- if (!final) {
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
- }
- break;
- case DUNDI_COMMAND_INVALID:
- case DUNDI_COMMAND_NULL:
- case DUNDI_COMMAND_PRECACHERP:
- /* Do nothing special */
- if (!final)
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- break;
- case DUNDI_COMMAND_ENCREJ:
- if ((ast_test_flag(trans, FLAG_SENDFULLKEY)) || AST_LIST_EMPTY(&trans->lasttrans) || !(peer = find_peer(&trans->them_eid))) {
- /* No really, it's over at this point */
- if (!final)
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- } else {
- /* Send with full key */
- ast_set_flag(trans, FLAG_SENDFULLKEY);
- if (final) {
- /* Ooops, we got a final message, start by sending ACK... */
- dundi_ack(trans, hdr->cmdresp & 0x80);
- trans->aseqno = trans->iseqno;
- /* Now, we gotta create a new transaction */
- if (!reset_transaction(trans)) {
- /* Make sure handle_frame doesn't destroy us */
- hdr->cmdresp &= 0x7f;
- /* Parse the message we transmitted */
- memset(&ies, 0, sizeof(ies));
- dundi_parse_ies(&ies, (AST_LIST_FIRST(&trans->lasttrans))->h->ies, (AST_LIST_FIRST(&trans->lasttrans))->datalen - sizeof(struct dundi_hdr));
- /* Reconstruct outgoing encrypted packet */
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid);
- dundi_ie_append_raw(&ied, DUNDI_IE_SHAREDKEY, peer->txenckey, 128);
- dundi_ie_append_raw(&ied, DUNDI_IE_SIGNATURE, peer->txenckey + 128, 128);
- if (ies.encblock)
- dundi_ie_append_encdata(&ied, DUNDI_IE_ENCDATA, ies.encblock->iv, ies.encblock->encdata, ies.enclen);
- dundi_send(trans, DUNDI_COMMAND_ENCRYPT, 0, (AST_LIST_FIRST(&trans->lasttrans))->h->cmdresp & 0x80, &ied);
- peer->sentfullkey = 1;
- }
- }
- }
- break;
- case DUNDI_COMMAND_ENCRYPT:
- if (!encrypted) {
- /* No nested encryption! */
- if ((trans->iseqno == 1) && !trans->oseqno) {
- if (!ies.eids[0] || !(peer = find_peer(ies.eids[0])) ||
- ((!ies.encsharedkey || !ies.encsig) && !ies.keycrc32) ||
- (check_key(peer, ies.encsharedkey, ies.encsig, ies.keycrc32) < 1)) {
- if (!final) {
- dundi_send(trans, DUNDI_COMMAND_ENCREJ, 0, 1, NULL);
- }
- break;
- }
- apply_peer(trans, peer);
- /* Key passed, use new contexts for this session */
- trans->ecx = peer->them_ecx;
- trans->dcx = peer->them_dcx;
- }
- if (ast_test_flag(trans, FLAG_ENCRYPT) && ies.encblock && ies.enclen) {
- struct dundi_hdr *dhdr;
- unsigned char decoded[MAX_PACKET_SIZE];
- int ddatalen;
- ddatalen = sizeof(decoded);
- dhdr = dundi_decrypt(trans, decoded, &ddatalen, hdr, ies.encblock, ies.enclen);
- if (dhdr) {
- /* Handle decrypted response */
- if (dundidebug)
- dundi_showframe(dhdr, 3, &trans->addr, ddatalen - sizeof(struct dundi_hdr));
- handle_command_response(trans, dhdr, ddatalen - sizeof(struct dundi_hdr), 1);
- /* Carry back final flag */
- hdr->cmdresp |= dhdr->cmdresp & 0x80;
- break;
- } else
- ast_log(LOG_DEBUG, "Ouch, decrypt failed :(\n");
- }
- }
- if (!final) {
- /* Turn off encryption */
- ast_clear_flag(trans, FLAG_ENCRYPT);
- dundi_send(trans, DUNDI_COMMAND_ENCREJ, 0, 1, NULL);
- }
- break;
- default:
- /* Send unknown command if we don't know it, with final flag IFF it's the
- first command in the dialog and only if we haven't recieved final notification */
- if (!final) {
- dundi_ie_append_byte(&ied, DUNDI_IE_UNKNOWN, cmd);
- dundi_send(trans, DUNDI_COMMAND_UNKNOWN, 0, !hdr->oseqno, &ied);
- }
- }
- return 0;
-}
-
-static void destroy_packet(struct dundi_packet *pack, int needfree);
-static void destroy_packets(struct packetlist *p)
-{
- struct dundi_packet *pack;
-
- while ((pack = AST_LIST_REMOVE_HEAD(p, list))) {
- AST_SCHED_DEL(sched, pack->retransid);
- free(pack);
- }
-}
-
-
-static int ack_trans(struct dundi_transaction *trans, int iseqno)
-{
- struct dundi_packet *pack;
-
- /* Ack transmitted packet corresponding to iseqno */
- AST_LIST_TRAVERSE(&trans->packets, pack, list) {
- if ((pack->h->oseqno + 1) % 255 == iseqno) {
- destroy_packet(pack, 0);
- if (!AST_LIST_EMPTY(&trans->lasttrans)) {
- ast_log(LOG_WARNING, "Whoa, there was still a last trans?\n");
- destroy_packets(&trans->lasttrans);
- }
- AST_LIST_INSERT_HEAD(&trans->lasttrans, pack, list);
- AST_SCHED_DEL(sched, trans->autokillid);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int handle_frame(struct dundi_hdr *h, struct sockaddr_in *sin, int datalen)
-{
- struct dundi_transaction *trans;
- trans = find_transaction(h, sin);
- if (!trans) {
- dundi_reject(h, sin);
- return 0;
- }
- /* Got a transaction, see where this header fits in */
- if (h->oseqno == trans->iseqno) {
- /* Just what we were looking for... Anything but ack increments iseqno */
- if (ack_trans(trans, h->iseqno) && ast_test_flag(trans, FLAG_FINAL)) {
- /* If final, we're done */
- destroy_trans(trans, 0);
- return 0;
- }
- if (h->cmdresp != DUNDI_COMMAND_ACK) {
- trans->oiseqno = trans->iseqno;
- trans->iseqno++;
- handle_command_response(trans, h, datalen, 0);
- }
- if (trans->aseqno != trans->iseqno) {
- dundi_ack(trans, h->cmdresp & 0x80);
- trans->aseqno = trans->iseqno;
- }
- /* Delete any saved last transmissions */
- destroy_packets(&trans->lasttrans);
- if (h->cmdresp & 0x80) {
- /* Final -- destroy now */
- destroy_trans(trans, 0);
- }
- } else if (h->oseqno == trans->oiseqno) {
- /* Last incoming sequence number -- send ACK without processing */
- dundi_ack(trans, 0);
- } else {
- /* Out of window -- simply drop */
- ast_log(LOG_DEBUG, "Dropping packet out of window!\n");
- }
- return 0;
-}
-
-static int socket_read(int *id, int fd, short events, void *cbdata)
-{
- struct sockaddr_in sin;
- int res;
- struct dundi_hdr *h;
- char buf[MAX_PACKET_SIZE];
- socklen_t len;
- len = sizeof(sin);
- res = recvfrom(netsocket, buf, sizeof(buf) - 1, 0,(struct sockaddr *) &sin, &len);
- if (res < 0) {
- if (errno != ECONNREFUSED)
- ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
- return 1;
- }
- if (res < sizeof(struct dundi_hdr)) {
- ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct dundi_hdr));
- return 1;
- }
- buf[res] = '\0';
- h = (struct dundi_hdr *)buf;
- if (dundidebug)
- dundi_showframe(h, 1, &sin, res - sizeof(struct dundi_hdr));
- AST_LIST_LOCK(&peers);
- handle_frame(h, &sin, res - sizeof(struct dundi_hdr));
- AST_LIST_UNLOCK(&peers);
- return 1;
-}
-
-static void build_secret(char *secret, int seclen)
-{
- unsigned char tmp[16];
- char *s;
- build_iv(tmp);
- secret[0] = '\0';
- ast_base64encode(secret, tmp, sizeof(tmp), seclen);
- /* Eliminate potential bad characters */
- while((s = strchr(secret, ';'))) *s = '+';
- while((s = strchr(secret, '/'))) *s = '+';
- while((s = strchr(secret, ':'))) *s = '+';
- while((s = strchr(secret, '@'))) *s = '+';
-}
-
-
-static void save_secret(const char *newkey, const char *oldkey)
-{
- char tmp[256];
- if (oldkey)
- snprintf(tmp, sizeof(tmp), "%s;%s", oldkey, newkey);
- else
- snprintf(tmp, sizeof(tmp), "%s", newkey);
- rotatetime = time(NULL) + DUNDI_SECRET_TIME;
- ast_db_put(secretpath, "secret", tmp);
- snprintf(tmp, sizeof(tmp), "%d", (int)rotatetime);
- ast_db_put(secretpath, "secretexpiry", tmp);
-}
-
-static void load_password(void)
-{
- char *current=NULL;
- char *last=NULL;
- char tmp[256];
- time_t expired;
-
- ast_db_get(secretpath, "secretexpiry", tmp, sizeof(tmp));
- if (!ast_get_time_t(tmp, &expired, 0, NULL)) {
- ast_db_get(secretpath, "secret", tmp, sizeof(tmp));
- current = strchr(tmp, ';');
- if (!current)
- current = tmp;
- else {
- *current = '\0';
- current++;
- };
- if ((time(NULL) - expired) < 0) {
- if ((expired - time(NULL)) > DUNDI_SECRET_TIME)
- expired = time(NULL) + DUNDI_SECRET_TIME;
- } else if ((time(NULL) - (expired + DUNDI_SECRET_TIME)) < 0) {
- last = current;
- current = NULL;
- } else {
- last = NULL;
- current = NULL;
- }
- }
- if (current) {
- /* Current key is still valid, just setup rotatation properly */
- ast_copy_string(cursecret, current, sizeof(cursecret));
- rotatetime = expired;
- } else {
- /* Current key is out of date, rotate or eliminate all together */
- build_secret(cursecret, sizeof(cursecret));
- save_secret(cursecret, last);
- }
-}
-
-static void check_password(void)
-{
- char oldsecret[80];
- time_t now;
-
- time(&now);
-#if 0
- printf("%ld/%ld\n", now, rotatetime);
-#endif
- if ((now - rotatetime) >= 0) {
- /* Time to rotate keys */
- ast_copy_string(oldsecret, cursecret, sizeof(oldsecret));
- build_secret(cursecret, sizeof(cursecret));
- save_secret(cursecret, oldsecret);
- }
-}
-
-static void *network_thread(void *ignore)
-{
- /* Our job is simple: Send queued messages, retrying if necessary. Read frames
- from the network, and queue them for delivery to the channels */
- int res;
- /* Establish I/O callback for socket read */
- ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);
-
- while (!dundi_shutdown) {
- res = ast_sched_wait(sched);
- if ((res > 1000) || (res < 0))
- res = 1000;
- res = ast_io_wait(io, res);
- if (res >= 0) {
- AST_LIST_LOCK(&peers);
- ast_sched_runq(sched);
- AST_LIST_UNLOCK(&peers);
- }
- check_password();
- }
-
- netthreadid = AST_PTHREADT_NULL;
-
- return NULL;
-}
-
-static void *process_precache(void *ign)
-{
- struct dundi_precache_queue *qe;
- time_t now;
- char context[256];
- char number[256];
- int run;
-
- while (!dundi_shutdown) {
- time(&now);
- run = 0;
- AST_LIST_LOCK(&pcq);
- if ((qe = AST_LIST_FIRST(&pcq))) {
- if (!qe->expiration) {
- /* Gone... Remove... */
- AST_LIST_REMOVE_HEAD(&pcq, list);
- free(qe);
- } else if (qe->expiration < now) {
- /* Process this entry */
- qe->expiration = 0;
- ast_copy_string(context, qe->context, sizeof(context));
- ast_copy_string(number, qe->number, sizeof(number));
- run = 1;
- }
- }
- AST_LIST_UNLOCK(&pcq);
- if (run) {
- dundi_precache(context, number);
- } else
- sleep(1);
- }
-
- precachethreadid = AST_PTHREADT_NULL;
-
- return NULL;
-}
-
-static int start_network_thread(void)
-{
- ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
- ast_pthread_create_background(&precachethreadid, NULL, process_precache, NULL);
- return 0;
-}
-
-static int dundi_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- dundidebug = 1;
- ast_cli(fd, "DUNDi Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int dundi_do_store_history(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- global_storehistory = 1;
- ast_cli(fd, "DUNDi History Storage Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int dundi_flush(int fd, int argc, char *argv[])
-{
- int stats = 0;
- if ((argc < 2) || (argc > 3))
- return RESULT_SHOWUSAGE;
- if (argc > 2) {
- if (!strcasecmp(argv[2], "stats"))
- stats = 1;
- else
- return RESULT_SHOWUSAGE;
- }
- if (stats) {
- /* Flush statistics */
- struct dundi_peer *p;
- int x;
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, p, list) {
- for (x = 0;x < DUNDI_TIMING_HISTORY; x++) {
- if (p->lookups[x])
- free(p->lookups[x]);
- p->lookups[x] = NULL;
- p->lookuptimes[x] = 0;
- }
- p->avgms = 0;
- }
- AST_LIST_UNLOCK(&peers);
- } else {
- ast_db_deltree("dundi/cache", NULL);
- ast_cli(fd, "DUNDi Cache Flushed\n");
- }
- return RESULT_SUCCESS;
-}
-
-static int dundi_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- dundidebug = 0;
- ast_cli(fd, "DUNDi Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int dundi_no_store_history(int fd, int argc, char *argv[])
-{
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- global_storehistory = 0;
- ast_cli(fd, "DUNDi History Storage Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static char *model2str(int model)
-{
- switch(model) {
- case DUNDI_MODEL_INBOUND:
- return "Inbound";
- case DUNDI_MODEL_OUTBOUND:
- return "Outbound";
- case DUNDI_MODEL_SYMMETRIC:
- return "Symmetric";
- default:
- return "Unknown";
- }
-}
-
-static char *complete_peer_helper(const char *line, const char *word, int pos, int state, int rpos)
-{
- int which=0, len;
- char *ret = NULL;
- struct dundi_peer *p;
- char eid_str[20];
-
- if (pos != rpos)
- return NULL;
- AST_LIST_LOCK(&peers);
- len = strlen(word);
- AST_LIST_TRAVERSE(&peers, p, list) {
- const char *s = dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid);
- if (!strncasecmp(word, s, len) && ++which > state) {
- ret = ast_strdup(s);
- break;
- }
- }
- AST_LIST_UNLOCK(&peers);
- return ret;
-}
-
-static char *complete_peer_4(const char *line, const char *word, int pos, int state)
-{
- return complete_peer_helper(line, word, pos, state, 3);
-}
-
-static int rescomp(const void *a, const void *b)
-{
- const struct dundi_result *resa, *resb;
- resa = a;
- resb = b;
- if (resa->weight < resb->weight)
- return -1;
- if (resa->weight > resb->weight)
- return 1;
- return 0;
-}
-
-static void sort_results(struct dundi_result *results, int count)
-{
- qsort(results, count, sizeof(results[0]), rescomp);
-}
-
-static int dundi_do_lookup(int fd, int argc, char *argv[])
-{
- int res;
- char tmp[256];
- char fs[80] = "";
- char *context;
- int x;
- int bypass = 0;
- struct dundi_result dr[MAX_RESULTS];
- struct timeval start;
- if ((argc < 3) || (argc > 4))
- return RESULT_SHOWUSAGE;
- if (argc > 3) {
- if (!strcasecmp(argv[3], "bypass"))
- bypass=1;
- else
- return RESULT_SHOWUSAGE;
- }
- ast_copy_string(tmp, argv[2], sizeof(tmp));
- context = strchr(tmp, '@');
- if (context) {
- *context = '\0';
- context++;
- }
- start = ast_tvnow();
- res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass);
-
- if (res < 0)
- ast_cli(fd, "DUNDi lookup returned error.\n");
- else if (!res)
- ast_cli(fd, "DUNDi lookup returned no results.\n");
- else
- sort_results(dr, res);
- for (x=0;x<res;x++) {
- ast_cli(fd, "%3d. %5d %s/%s (%s)\n", x + 1, dr[x].weight, dr[x].tech, dr[x].dest, dundi_flags2str(fs, sizeof(fs), dr[x].flags));
- ast_cli(fd, " from %s, expires in %d s\n", dr[x].eid_str, dr[x].expiration);
- }
- ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
- return RESULT_SUCCESS;
-}
-
-static int dundi_do_precache(int fd, int argc, char *argv[])
-{
- int res;
- char tmp[256];
- char *context;
- struct timeval start;
- if ((argc < 3) || (argc > 3))
- return RESULT_SHOWUSAGE;
- ast_copy_string(tmp, argv[2], sizeof(tmp));
- context = strchr(tmp, '@');
- if (context) {
- *context = '\0';
- context++;
- }
- start = ast_tvnow();
- res = dundi_precache(context, tmp);
-
- if (res < 0)
- ast_cli(fd, "DUNDi precache returned error.\n");
- else if (!res)
- ast_cli(fd, "DUNDi precache returned no error.\n");
- ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
- return RESULT_SUCCESS;
-}
-
-static int dundi_do_query(int fd, int argc, char *argv[])
-{
- int res;
- char tmp[256];
- char *context;
- dundi_eid eid;
- struct dundi_entity_info dei;
- if ((argc < 3) || (argc > 3))
- return RESULT_SHOWUSAGE;
- if (dundi_str_to_eid(&eid, argv[2])) {
- ast_cli(fd, "'%s' is not a valid EID!\n", argv[2]);
- return RESULT_SHOWUSAGE;
- }
- ast_copy_string(tmp, argv[2], sizeof(tmp));
- context = strchr(tmp, '@');
- if (context) {
- *context = '\0';
- context++;
- }
- res = dundi_query_eid(&dei, context, eid);
- if (res < 0)
- ast_cli(fd, "DUNDi Query EID returned error.\n");
- else if (!res)
- ast_cli(fd, "DUNDi Query EID returned no results.\n");
- else {
- ast_cli(fd, "DUNDi Query EID succeeded:\n");
- ast_cli(fd, "Department: %s\n", dei.orgunit);
- ast_cli(fd, "Organization: %s\n", dei.org);
- ast_cli(fd, "City/Locality: %s\n", dei.locality);
- ast_cli(fd, "State/Province: %s\n", dei.stateprov);
- ast_cli(fd, "Country: %s\n", dei.country);
- ast_cli(fd, "E-mail: %s\n", dei.email);
- ast_cli(fd, "Phone: %s\n", dei.phone);
- ast_cli(fd, "IP Address: %s\n", dei.ipaddr);
- }
- return RESULT_SUCCESS;
-}
-
-static int dundi_show_peer(int fd, int argc, char *argv[])
-{
- struct dundi_peer *peer;
- struct permission *p;
- char *order;
- char eid_str[20];
- int x, cnt;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, list) {
- if (!strcasecmp(dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), argv[3]))
- break;
- }
- if (peer) {
- switch(peer->order) {
- case 0:
- order = "Primary";
- break;
- case 1:
- order = "Secondary";
- break;
- case 2:
- order = "Tertiary";
- break;
- case 3:
- order = "Quartiary";
- break;
- default:
- order = "Unknown";
- }
- ast_cli(fd, "Peer: %s\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- ast_cli(fd, "Model: %s\n", model2str(peer->model));
- ast_cli(fd, "Host: %s\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "<Unspecified>");
- ast_cli(fd, "Dynamic: %s\n", peer->dynamic ? "yes" : "no");
- ast_cli(fd, "Reg: %s\n", peer->registerid < 0 ? "No" : "Yes");
- ast_cli(fd, "In Key: %s\n", ast_strlen_zero(peer->inkey) ? "<None>" : peer->inkey);
- ast_cli(fd, "Out Key: %s\n", ast_strlen_zero(peer->outkey) ? "<None>" : peer->outkey);
- if (!AST_LIST_EMPTY(&peer->include))
- ast_cli(fd, "Include logic%s:\n", peer->model & DUNDI_MODEL_OUTBOUND ? "" : " (IGNORED)");
- AST_LIST_TRAVERSE(&peer->include, p, list)
- ast_cli(fd, "-- %s %s\n", p->allow ? "include" : "do not include", p->name);
- if (!AST_LIST_EMPTY(&peer->permit))
- ast_cli(fd, "Query logic%s:\n", peer->model & DUNDI_MODEL_INBOUND ? "" : " (IGNORED)");
- AST_LIST_TRAVERSE(&peer->permit, p, list)
- ast_cli(fd, "-- %s %s\n", p->allow ? "permit" : "deny", p->name);
- cnt = 0;
- for (x = 0;x < DUNDI_TIMING_HISTORY; x++) {
- if (peer->lookups[x]) {
- if (!cnt)
- ast_cli(fd, "Last few query times:\n");
- ast_cli(fd, "-- %d. %s (%d ms)\n", x + 1, peer->lookups[x], peer->lookuptimes[x]);
- cnt++;
- }
- }
- if (cnt)
- ast_cli(fd, "Average query time: %d ms\n", peer->avgms);
- } else
- ast_cli(fd, "No such peer '%s'\n", argv[3]);
- AST_LIST_UNLOCK(&peers);
- return RESULT_SUCCESS;
-}
-
-static int dundi_show_peers(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-8.8s %-15.15s\n"
-#define FORMAT "%-20.20s %-15.15s %s %-10.10s %-8.8s %-15.15s\n"
- struct dundi_peer *peer;
- int registeredonly=0;
- char avgms[20];
- char eid_str[20];
- int online_peers = 0;
- int offline_peers = 0;
- int unmonitored_peers = 0;
- int total_peers = 0;
-
- if ((argc != 3) && (argc != 4) && (argc != 5))
- return RESULT_SHOWUSAGE;
- if ((argc == 4)) {
- if (!strcasecmp(argv[3], "registered")) {
- registeredonly = 1;
- } else
- return RESULT_SHOWUSAGE;
- }
- AST_LIST_LOCK(&peers);
- ast_cli(fd, FORMAT2, "EID", "Host", "Model", "AvgTime", "Status");
- AST_LIST_TRAVERSE(&peers, peer, list) {
- char status[20];
- int print_line = -1;
- char srch[2000];
- total_peers++;
- if (registeredonly && !peer->addr.sin_addr.s_addr)
- continue;
- if (peer->maxms) {
- if (peer->lastms < 0) {
- strcpy(status, "UNREACHABLE");
- offline_peers++;
- }
- else if (peer->lastms > peer->maxms) {
- snprintf(status, sizeof(status), "LAGGED (%d ms)", peer->lastms);
- offline_peers++;
- }
- else if (peer->lastms) {
- snprintf(status, sizeof(status), "OK (%d ms)", peer->lastms);
- online_peers++;
- }
- else {
- strcpy(status, "UNKNOWN");
- offline_peers++;
- }
- } else {
- strcpy(status, "Unmonitored");
- unmonitored_peers++;
- }
- if (peer->avgms)
- snprintf(avgms, sizeof(avgms), "%d ms", peer->avgms);
- else
- strcpy(avgms, "Unavail");
- snprintf(srch, sizeof(srch), FORMAT, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
- peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status);
-
- if (argc == 5) {
- if (!strcasecmp(argv[3],"include") && strstr(srch,argv[4])) {
- print_line = -1;
- } else if (!strcasecmp(argv[3],"exclude") && !strstr(srch,argv[4])) {
- print_line = 1;
- } else if (!strcasecmp(argv[3],"begin") && !strncasecmp(srch,argv[4],strlen(argv[4]))) {
- print_line = -1;
- } else {
- print_line = 0;
- }
- }
-
- if (print_line) {
- ast_cli(fd, FORMAT, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
- peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status);
- }
- }
- ast_cli(fd, "%d dundi peers [%d online, %d offline, %d unmonitored]\n", total_peers, online_peers, offline_peers, unmonitored_peers);
- AST_LIST_UNLOCK(&peers);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int dundi_show_trans(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n"
-#define FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n"
- struct dundi_transaction *trans;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&peers);
- ast_cli(fd, FORMAT2, "Remote", "Src", "Dst", "Tx", "Rx", "Ack");
- AST_LIST_TRAVERSE(&alltrans, trans, all) {
- ast_cli(fd, FORMAT, ast_inet_ntoa(trans->addr.sin_addr),
- ntohs(trans->addr.sin_port), trans->strans, trans->dtrans, trans->oseqno, trans->iseqno, trans->aseqno);
- }
- AST_LIST_UNLOCK(&peers);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int dundi_show_entityid(int fd, int argc, char *argv[])
-{
- char eid_str[20];
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&peers);
- dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid);
- AST_LIST_UNLOCK(&peers);
- ast_cli(fd, "Global EID for this system is '%s'\n", eid_str);
- return RESULT_SUCCESS;
-}
-
-static int dundi_show_requests(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-15s %-15s %-15s %-3.3s %-3.3s\n"
-#define FORMAT "%-15s %-15s %-15s %-3.3d %-3.3d\n"
- struct dundi_request *req;
- char eidstr[20];
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&peers);
- ast_cli(fd, FORMAT2, "Number", "Context", "Root", "Max", "Rsp");
- AST_LIST_TRAVERSE(&requests, req, list) {
- ast_cli(fd, FORMAT, req->number, req->dcontext,
- dundi_eid_zero(&req->root_eid) ? "<unspecified>" : dundi_eid_to_str(eidstr, sizeof(eidstr), &req->root_eid), req->maxcount, req->respcount);
- }
- AST_LIST_UNLOCK(&peers);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-/* Grok-a-dial DUNDi */
-
-static int dundi_show_mappings(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n"
-#define FORMAT "%-12.12s %-7d %-12.12s %-10.10s %-5.5s %-25.25s\n"
- struct dundi_mapping *map;
- char fs[256];
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- AST_LIST_LOCK(&peers);
- ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination");
- AST_LIST_TRAVERSE(&mappings, map, list) {
- ast_cli(fd, FORMAT, map->dcontext, map->weight,
- ast_strlen_zero(map->lcontext) ? "<none>" : map->lcontext,
- dundi_flags2str(fs, sizeof(fs), map->options), tech2str(map->tech), map->dest);
- }
- AST_LIST_UNLOCK(&peers);
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static int dundi_show_precache(int fd, int argc, char *argv[])
-{
-#define FORMAT2 "%-12.12s %-12.12s %-10.10s\n"
-#define FORMAT "%-12.12s %-12.12s %02d:%02d:%02d\n"
- struct dundi_precache_queue *qe;
- int h,m,s;
- time_t now;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- time(&now);
- ast_cli(fd, FORMAT2, "Number", "Context", "Expiration");
- AST_LIST_LOCK(&pcq);
- AST_LIST_TRAVERSE(&pcq, qe, list) {
- s = qe->expiration - now;
- h = s / 3600;
- s = s % 3600;
- m = s / 60;
- s = s % 60;
- ast_cli(fd, FORMAT, qe->number, qe->context, h,m,s);
- }
- AST_LIST_UNLOCK(&pcq);
-
- return RESULT_SUCCESS;
-#undef FORMAT
-#undef FORMAT2
-}
-
-static char debug_usage[] =
-"Usage: dundi debug\n"
-" Enables dumping of DUNDi packets for debugging purposes\n";
-
-static char no_debug_usage[] =
-"Usage: dundi no debug\n"
-" Disables dumping of DUNDi packets for debugging purposes\n";
-
-static char store_history_usage[] =
-"Usage: dundi store history\n"
-" Enables storing of DUNDi requests and times for debugging\n"
-"purposes\n";
-
-static char no_store_history_usage[] =
-"Usage: dundi no store history\n"
-" Disables storing of DUNDi requests and times for debugging\n"
-"purposes\n";
-
-static char show_peers_usage[] =
-"Usage: dundi show peers\n"
-" Lists all known DUNDi peers.\n";
-
-static char show_trans_usage[] =
-"Usage: dundi show trans\n"
-" Lists all known DUNDi transactions.\n";
-
-static char show_mappings_usage[] =
-"Usage: dundi show mappings\n"
-" Lists all known DUNDi mappings.\n";
-
-static char show_precache_usage[] =
-"Usage: dundi show precache\n"
-" Lists all known DUNDi scheduled precache updates.\n";
-
-static char show_entityid_usage[] =
-"Usage: dundi show entityid\n"
-" Displays the global entityid for this host.\n";
-
-static char show_peer_usage[] =
-"Usage: dundi show peer [peer]\n"
-" Provide a detailed description of a specifid DUNDi peer.\n";
-
-static char show_requests_usage[] =
-"Usage: dundi show requests\n"
-" Lists all known pending DUNDi requests.\n";
-
-static char lookup_usage[] =
-"Usage: dundi lookup <number>[@context] [bypass]\n"
-" Lookup the given number within the given DUNDi context\n"
-"(or e164 if none is specified). Bypasses cache if 'bypass'\n"
-"keyword is specified.\n";
-
-static char precache_usage[] =
-"Usage: dundi precache <number>[@context]\n"
-" Lookup the given number within the given DUNDi context\n"
-"(or e164 if none is specified) and precaches the results to any\n"
-"upstream DUNDi push servers.\n";
-
-static char query_usage[] =
-"Usage: dundi query <entity>[@context]\n"
-" Attempts to retrieve contact information for a specific\n"
-"DUNDi entity identifier (EID) within a given DUNDi context (or\n"
-"e164 if none is specified).\n";
-
-static char flush_usage[] =
-"Usage: dundi flush [stats]\n"
-" Flushes DUNDi answer cache, used primarily for debug. If\n"
-"'stats' is present, clears timer statistics instead of normal\n"
-"operation.\n";
-
-static struct ast_cli_entry cli_dundi[] = {
- { { "dundi", "debug", NULL },
- dundi_do_debug, "Enable DUNDi debugging",
- debug_usage },
-
- { { "dundi", "store", "history", NULL },
- dundi_do_store_history, "Enable DUNDi historic records",
- store_history_usage },
-
- { { "dundi", "no", "store", "history", NULL },
- dundi_no_store_history, "Disable DUNDi historic records",
- no_store_history_usage },
-
- { { "dundi", "flush", NULL },
- dundi_flush, "Flush DUNDi cache",
- flush_usage },
-
- { { "dundi", "no", "debug", NULL },
- dundi_no_debug, "Disable DUNDi debugging",
- no_debug_usage },
-
- { { "dundi", "show", "peers", NULL },
- dundi_show_peers, "Show defined DUNDi peers",
- show_peers_usage },
-
- { { "dundi", "show", "trans", NULL },
- dundi_show_trans, "Show active DUNDi transactions",
- show_trans_usage },
-
- { { "dundi", "show", "entityid", NULL },
- dundi_show_entityid, "Display Global Entity ID",
- show_entityid_usage },
-
- { { "dundi", "show", "mappings", NULL },
- dundi_show_mappings, "Show DUNDi mappings",
- show_mappings_usage },
-
- { { "dundi", "show", "precache", NULL },
- dundi_show_precache, "Show DUNDi precache",
- show_precache_usage },
-
- { { "dundi", "show", "requests", NULL },
- dundi_show_requests, "Show DUNDi requests",
- show_requests_usage },
-
- { { "dundi", "show", "peer", NULL },
- dundi_show_peer, "Show info on a specific DUNDi peer",
- show_peer_usage, complete_peer_4 },
-
- { { "dundi", "lookup", NULL },
- dundi_do_lookup, "Lookup a number in DUNDi",
- lookup_usage },
-
- { { "dundi", "precache", NULL },
- dundi_do_precache, "Precache a number in DUNDi",
- precache_usage },
-
- { { "dundi", "query", NULL },
- dundi_do_query, "Query a DUNDi EID",
- query_usage },
-};
-
-static struct dundi_transaction *create_transaction(struct dundi_peer *p)
-{
- struct dundi_transaction *trans;
- int tid;
-
- /* Don't allow creation of transactions to non-registered peers */
- if (p && !p->addr.sin_addr.s_addr)
- return NULL;
- tid = get_trans_id();
- if (tid < 1)
- return NULL;
- trans = ast_calloc(1, sizeof(*trans));
- if (trans) {
- if (global_storehistory) {
- trans->start = ast_tvnow();
- ast_set_flag(trans, FLAG_STOREHIST);
- }
- trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER;
- trans->autokillid = -1;
- if (p) {
- apply_peer(trans, p);
- if (!p->sentfullkey)
- ast_set_flag(trans, FLAG_SENDFULLKEY);
- }
- trans->strans = tid;
- AST_LIST_INSERT_HEAD(&alltrans, trans, all);
- }
- return trans;
-}
-
-static int dundi_xmit(struct dundi_packet *pack)
-{
- int res;
- if (dundidebug)
- dundi_showframe(pack->h, 0, &pack->parent->addr, pack->datalen - sizeof(struct dundi_hdr));
- res = sendto(netsocket, pack->data, pack->datalen, 0, (struct sockaddr *)&pack->parent->addr, sizeof(pack->parent->addr));
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to transmit to '%s:%d': %s\n",
- ast_inet_ntoa(pack->parent->addr.sin_addr),
- ntohs(pack->parent->addr.sin_port), strerror(errno));
- }
- if (res > 0)
- res = 0;
- return res;
-}
-
-static void destroy_packet(struct dundi_packet *pack, int needfree)
-{
- if (pack->parent)
- AST_LIST_REMOVE(&pack->parent->packets, pack, list);
- AST_SCHED_DEL(sched, pack->retransid);
- if (needfree)
- free(pack);
-}
-
-static void destroy_trans(struct dundi_transaction *trans, int fromtimeout)
-{
- struct dundi_peer *peer;
- int ms;
- int x;
- int cnt;
- char eid_str[20];
- if (ast_test_flag(trans, FLAG_ISREG | FLAG_ISQUAL | FLAG_STOREHIST)) {
- AST_LIST_TRAVERSE(&peers, peer, list) {
- if (peer->regtrans == trans)
- peer->regtrans = NULL;
- if (peer->qualtrans == trans) {
- if (fromtimeout) {
- if (peer->lastms > -1)
- ast_log(LOG_NOTICE, "Peer '%s' has become UNREACHABLE!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- peer->lastms = -1;
- } else {
- ms = ast_tvdiff_ms(ast_tvnow(), peer->qualtx);
- if (ms < 1)
- ms = 1;
- if (ms < peer->maxms) {
- if ((peer->lastms >= peer->maxms) || (peer->lastms < 0))
- ast_log(LOG_NOTICE, "Peer '%s' has become REACHABLE!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- } else if (peer->lastms < peer->maxms) {
- ast_log(LOG_NOTICE, "Peer '%s' has become TOO LAGGED (%d ms)\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), ms);
- }
- peer->lastms = ms;
- }
- peer->qualtrans = NULL;
- }
- if (ast_test_flag(trans, FLAG_STOREHIST)) {
- if (trans->parent && !ast_strlen_zero(trans->parent->number)) {
- if (!dundi_eid_cmp(&trans->them_eid, &peer->eid)) {
- peer->avgms = 0;
- cnt = 0;
- if (peer->lookups[DUNDI_TIMING_HISTORY-1])
- free(peer->lookups[DUNDI_TIMING_HISTORY-1]);
- for (x=DUNDI_TIMING_HISTORY-1;x>0;x--) {
- peer->lookuptimes[x] = peer->lookuptimes[x-1];
- peer->lookups[x] = peer->lookups[x-1];
- if (peer->lookups[x]) {
- peer->avgms += peer->lookuptimes[x];
- cnt++;
- }
- }
- peer->lookuptimes[0] = ast_tvdiff_ms(ast_tvnow(), trans->start);
- peer->lookups[0] = ast_malloc(strlen(trans->parent->number) + strlen(trans->parent->dcontext) + 2);
- if (peer->lookups[0]) {
- sprintf(peer->lookups[0], "%s@%s", trans->parent->number, trans->parent->dcontext);
- peer->avgms += peer->lookuptimes[0];
- cnt++;
- }
- if (cnt)
- peer->avgms /= cnt;
- }
- }
- }
- }
- }
- if (trans->parent) {
- /* Unlink from parent if appropriate */
- AST_LIST_REMOVE(&trans->parent->trans, trans, parentlist);
- if (AST_LIST_EMPTY(&trans->parent->trans)) {
- /* Wake up sleeper */
- if (trans->parent->pfds[1] > -1) {
- write(trans->parent->pfds[1], "killa!", 6);
- }
- }
- }
- /* Unlink from all trans */
- AST_LIST_REMOVE(&alltrans, trans, all);
- destroy_packets(&trans->packets);
- destroy_packets(&trans->lasttrans);
- AST_SCHED_DEL(sched, trans->autokillid);
- if (trans->thread) {
- /* If used by a thread, mark as dead and be done */
- ast_set_flag(trans, FLAG_DEAD);
- } else
- free(trans);
-}
-
-static int dundi_rexmit(const void *data)
-{
- struct dundi_packet *pack = (struct dundi_packet *)data;
- int res;
- AST_LIST_LOCK(&peers);
- if (pack->retrans < 1) {
- pack->retransid = -1;
- if (!ast_test_flag(pack->parent, FLAG_ISQUAL))
- ast_log(LOG_NOTICE, "Max retries exceeded to host '%s:%d' msg %d on call %d\n",
- ast_inet_ntoa(pack->parent->addr.sin_addr),
- ntohs(pack->parent->addr.sin_port), pack->h->oseqno, ntohs(pack->h->strans));
- destroy_trans(pack->parent, 1);
- res = 0;
- } else {
- /* Decrement retransmission, try again */
- pack->retrans--;
- dundi_xmit(pack);
- res = 1;
- }
- AST_LIST_UNLOCK(&peers);
- return res;
-}
-
-static int dundi_send(struct dundi_transaction *trans, int cmdresp, int flags, int final, struct dundi_ie_data *ied)
-{
- struct dundi_packet *pack;
- int res;
- int len;
- char eid_str[20];
- len = sizeof(struct dundi_packet) + sizeof(struct dundi_hdr) + (ied ? ied->pos : 0);
- /* Reserve enough space for encryption */
- if (ast_test_flag(trans, FLAG_ENCRYPT))
- len += 384;
- pack = ast_calloc(1, len);
- if (pack) {
- pack->h = (struct dundi_hdr *)(pack->data);
- if (cmdresp != DUNDI_COMMAND_ACK) {
- pack->retransid = ast_sched_add(sched, trans->retranstimer, dundi_rexmit, pack);
- pack->retrans = DUNDI_DEFAULT_RETRANS - 1;
- AST_LIST_INSERT_HEAD(&trans->packets, pack, list);
- }
- pack->parent = trans;
- pack->h->strans = htons(trans->strans);
- pack->h->dtrans = htons(trans->dtrans);
- pack->h->iseqno = trans->iseqno;
- pack->h->oseqno = trans->oseqno;
- pack->h->cmdresp = cmdresp;
- pack->datalen = sizeof(struct dundi_hdr);
- if (ied) {
- memcpy(pack->h->ies, ied->buf, ied->pos);
- pack->datalen += ied->pos;
- }
- if (final) {
- pack->h->cmdresp |= DUNDI_COMMAND_FINAL;
- ast_set_flag(trans, FLAG_FINAL);
- }
- pack->h->cmdflags = flags;
- if (cmdresp != DUNDI_COMMAND_ACK) {
- trans->oseqno++;
- trans->oseqno = trans->oseqno % 256;
- }
- trans->aseqno = trans->iseqno;
- /* If we have their public key, encrypt */
- if (ast_test_flag(trans, FLAG_ENCRYPT)) {
- switch(cmdresp) {
- case DUNDI_COMMAND_REGREQ:
- case DUNDI_COMMAND_REGRESPONSE:
- case DUNDI_COMMAND_DPDISCOVER:
- case DUNDI_COMMAND_DPRESPONSE:
- case DUNDI_COMMAND_EIDQUERY:
- case DUNDI_COMMAND_EIDRESPONSE:
- case DUNDI_COMMAND_PRECACHERQ:
- case DUNDI_COMMAND_PRECACHERP:
- if (dundidebug)
- dundi_showframe(pack->h, 2, &trans->addr, pack->datalen - sizeof(struct dundi_hdr));
- res = dundi_encrypt(trans, pack);
- break;
- default:
- res = 0;
- }
- } else
- res = 0;
- if (!res)
- res = dundi_xmit(pack);
- if (res)
- ast_log(LOG_NOTICE, "Failed to send packet to '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &trans->them_eid));
-
- if (cmdresp == DUNDI_COMMAND_ACK)
- free(pack);
- return res;
- }
- return -1;
-}
-
-static int do_autokill(const void *data)
-{
- struct dundi_transaction *trans = (struct dundi_transaction *)data;
- char eid_str[20];
- ast_log(LOG_NOTICE, "Transaction to '%s' took too long to ACK, destroying\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &trans->them_eid));
- trans->autokillid = -1;
- destroy_trans(trans, 0); /* We could actually set it to 1 instead of 0, but we won't ;-) */
- return 0;
-}
-
-static void dundi_ie_append_eid_appropriately(struct dundi_ie_data *ied, char *context, dundi_eid *eid, dundi_eid *us)
-{
- struct dundi_peer *p;
- if (!dundi_eid_cmp(eid, us)) {
- dundi_ie_append_eid(ied, DUNDI_IE_EID_DIRECT, eid);
- return;
- }
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, p, list) {
- if (!dundi_eid_cmp(&p->eid, eid)) {
- if (has_permission(&p->include, context))
- dundi_ie_append_eid(ied, DUNDI_IE_EID_DIRECT, eid);
- else
- dundi_ie_append_eid(ied, DUNDI_IE_EID, eid);
- break;
- }
- }
- if (!p)
- dundi_ie_append_eid(ied, DUNDI_IE_EID, eid);
- AST_LIST_UNLOCK(&peers);
-}
-
-static int dundi_discover(struct dundi_transaction *trans)
-{
- struct dundi_ie_data ied;
- int x;
- if (!trans->parent) {
- ast_log(LOG_WARNING, "Tried to discover a transaction with no parent?!?\n");
- return -1;
- }
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION);
- if (!dundi_eid_zero(&trans->us_eid))
- dundi_ie_append_eid(&ied, DUNDI_IE_EID_DIRECT, &trans->us_eid);
- for (x=0;x<trans->eidcount;x++)
- dundi_ie_append_eid_appropriately(&ied, trans->parent->dcontext, &trans->eids[x], &trans->us_eid);
- dundi_ie_append_str(&ied, DUNDI_IE_CALLED_NUMBER, trans->parent->number);
- dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext);
- dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl);
- if (trans->parent->cbypass)
- dundi_ie_append(&ied, DUNDI_IE_CACHEBYPASS);
- if (trans->autokilltimeout)
- trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans);
- return dundi_send(trans, DUNDI_COMMAND_DPDISCOVER, 0, 0, &ied);
-}
-
-static int precache_trans(struct dundi_transaction *trans, struct dundi_mapping *maps, int mapcount, int *minexp, int *foundanswers)
-{
- struct dundi_ie_data ied;
- int x, res;
- int max = 999999;
- int expiration = dundi_cache_time;
- int ouranswers=0;
- dundi_eid *avoid[1] = { NULL, };
- int direct[1] = { 0, };
- struct dundi_result dr[MAX_RESULTS];
- struct dundi_hint_metadata hmd;
- if (!trans->parent) {
- ast_log(LOG_WARNING, "Tried to discover a transaction with no parent?!?\n");
- return -1;
- }
- memset(&hmd, 0, sizeof(hmd));
- memset(&dr, 0, sizeof(dr));
- /* Look up the answers we're going to include */
- for (x=0;x<mapcount;x++)
- ouranswers = dundi_lookup_local(dr, maps + x, trans->parent->number, &trans->us_eid, ouranswers, &hmd);
- if (ouranswers < 0)
- ouranswers = 0;
- for (x=0;x<ouranswers;x++) {
- if (dr[x].weight < max)
- max = dr[x].weight;
- }
- if (max) {
- /* If we do not have a canonical result, keep looking */
- res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, trans->parent->dcontext, trans->parent->number, trans->ttl, 1, &hmd, &expiration, 0, 1, &trans->them_eid, avoid, direct);
- if (res > 0) {
- /* Append answer in result */
- ouranswers += res;
- }
- }
-
- if (ouranswers > 0) {
- *foundanswers += ouranswers;
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION);
- if (!dundi_eid_zero(&trans->us_eid))
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid);
- for (x=0;x<trans->eidcount;x++)
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->eids[x]);
- dundi_ie_append_str(&ied, DUNDI_IE_CALLED_NUMBER, trans->parent->number);
- dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext);
- dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl);
- for (x=0;x<ouranswers;x++) {
- /* Add answers */
- if (dr[x].expiration && (expiration > dr[x].expiration))
- expiration = dr[x].expiration;
- dundi_ie_append_answer(&ied, DUNDI_IE_ANSWER, &dr[x].eid, dr[x].techint, dr[x].flags, dr[x].weight, dr[x].dest);
- }
- dundi_ie_append_hint(&ied, DUNDI_IE_HINT, hmd.flags, hmd.exten);
- dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, expiration);
- if (trans->autokilltimeout)
- trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans);
- if (expiration < *minexp)
- *minexp = expiration;
- return dundi_send(trans, DUNDI_COMMAND_PRECACHERQ, 0, 0, &ied);
- } else {
- /* Oops, nothing to send... */
- destroy_trans(trans, 0);
- return 0;
- }
-}
-
-static int dundi_query(struct dundi_transaction *trans)
-{
- struct dundi_ie_data ied;
- int x;
- if (!trans->parent) {
- ast_log(LOG_WARNING, "Tried to query a transaction with no parent?!?\n");
- return -1;
- }
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION);
- if (!dundi_eid_zero(&trans->us_eid))
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid);
- for (x=0;x<trans->eidcount;x++)
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->eids[x]);
- dundi_ie_append_eid(&ied, DUNDI_IE_REQEID, &trans->parent->query_eid);
- dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext);
- dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl);
- if (trans->autokilltimeout)
- trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans);
- return dundi_send(trans, DUNDI_COMMAND_EIDQUERY, 0, 0, &ied);
-}
-
-static int discover_transactions(struct dundi_request *dr)
-{
- struct dundi_transaction *trans;
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&dr->trans, trans, parentlist) {
- dundi_discover(trans);
- }
- AST_LIST_UNLOCK(&peers);
- return 0;
-}
-
-static int precache_transactions(struct dundi_request *dr, struct dundi_mapping *maps, int mapcount, int *expiration, int *foundanswers)
-{
- struct dundi_transaction *trans;
-
- /* Mark all as "in thread" so they don't disappear */
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&dr->trans, trans, parentlist) {
- if (trans->thread)
- ast_log(LOG_WARNING, "This shouldn't happen, really...\n");
- trans->thread = 1;
- }
- AST_LIST_UNLOCK(&peers);
-
- AST_LIST_TRAVERSE(&dr->trans, trans, parentlist) {
- if (!ast_test_flag(trans, FLAG_DEAD))
- precache_trans(trans, maps, mapcount, expiration, foundanswers);
- }
-
- /* Cleanup any that got destroyed in the mean time */
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&dr->trans, trans, parentlist) {
- trans->thread = 0;
- if (ast_test_flag(trans, FLAG_DEAD)) {
- ast_log(LOG_DEBUG, "Our transaction went away!\n");
- /* This is going to remove the transaction from the dundi_request's list, as well
- * as the global transactions list */
- destroy_trans(trans, 0);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&peers);
-
- return 0;
-}
-
-static int query_transactions(struct dundi_request *dr)
-{
- struct dundi_transaction *trans;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&dr->trans, trans, parentlist) {
- dundi_query(trans);
- }
- AST_LIST_UNLOCK(&peers);
-
- return 0;
-}
-
-static int optimize_transactions(struct dundi_request *dr, int order)
-{
- /* Minimize the message propagation through DUNDi by
- alerting the network to hops which should be not be considered */
- struct dundi_transaction *trans;
- struct dundi_peer *peer;
- dundi_eid tmp;
- int x;
- int needpush;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&dr->trans, trans, parentlist) {
- /* Pop off the true root */
- if (trans->eidcount) {
- tmp = trans->eids[--trans->eidcount];
- needpush = 1;
- } else {
- tmp = trans->us_eid;
- needpush = 0;
- }
-
- AST_LIST_TRAVERSE(&peers, peer, list) {
- if (has_permission(&peer->include, dr->dcontext) &&
- dundi_eid_cmp(&peer->eid, &trans->them_eid) &&
- (peer->order <= order)) {
- /* For each other transaction, make sure we don't
- ask this EID about the others if they're not
- already in the list */
- if (!dundi_eid_cmp(&tmp, &peer->eid))
- x = -1;
- else {
- for (x=0;x<trans->eidcount;x++) {
- if (!dundi_eid_cmp(&trans->eids[x], &peer->eid))
- break;
- }
- }
- if (x == trans->eidcount) {
- /* Nope not in the list, if needed, add us at the end since we're the source */
- if (trans->eidcount < DUNDI_MAX_STACK - needpush) {
- trans->eids[trans->eidcount++] = peer->eid;
- /* Need to insert the real root (or us) at the bottom now as
- a requirement now. */
- needpush = 1;
- }
- }
- }
- }
- /* If necessary, push the true root back on the end */
- if (needpush)
- trans->eids[trans->eidcount++] = tmp;
- }
- AST_LIST_UNLOCK(&peers);
-
- return 0;
-}
-
-static int append_transaction(struct dundi_request *dr, struct dundi_peer *p, int ttl, dundi_eid *avoid[])
-{
- struct dundi_transaction *trans;
- int x;
- char eid_str[20];
- char eid_str2[20];
-
- /* Ignore if not registered */
- if (!p->addr.sin_addr.s_addr)
- return 0;
- if (p->maxms && ((p->lastms < 0) || (p->lastms >= p->maxms)))
- return 0;
- if (ast_strlen_zero(dr->number))
- ast_log(LOG_DEBUG, "Will query peer '%s' for '%s' (context '%s')\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid), dundi_eid_to_str(eid_str2, sizeof(eid_str2), &dr->query_eid), dr->dcontext);
- else
- ast_log(LOG_DEBUG, "Will query peer '%s' for '%s@%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid), dr->number, dr->dcontext);
- trans = create_transaction(p);
- if (!trans)
- return -1;
- trans->parent = dr;
- trans->ttl = ttl;
- for (x = 0; avoid[x] && (x < DUNDI_MAX_STACK); x++)
- trans->eids[x] = *avoid[x];
- trans->eidcount = x;
- AST_LIST_INSERT_HEAD(&dr->trans, trans, parentlist);
-
- return 0;
-}
-
-static void cancel_request(struct dundi_request *dr)
-{
- struct dundi_transaction *trans;
-
- AST_LIST_LOCK(&peers);
- while ((trans = AST_LIST_REMOVE_HEAD(&dr->trans, parentlist))) {
- /* Orphan transaction from request */
- trans->parent = NULL;
- /* Send final cancel */
- dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
- }
- AST_LIST_UNLOCK(&peers);
-}
-
-static void abort_request(struct dundi_request *dr)
-{
- struct dundi_transaction *trans;
-
- AST_LIST_LOCK(&peers);
- while ((trans = AST_LIST_FIRST(&dr->trans))) {
- /* This will remove the transaction from the list */
- destroy_trans(trans, 0);
- }
- AST_LIST_UNLOCK(&peers);
-}
-
-static void build_transactions(struct dundi_request *dr, int ttl, int order, int *foundcache, int *skipped, int blockempty, int nocache, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int directs[])
-{
- struct dundi_peer *p;
- int x;
- int res;
- int pass;
- int allowconnect;
- char eid_str[20];
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, p, list) {
- if (modeselect == 1) {
- /* Send the precache to push upstreams only! */
- pass = has_permission(&p->permit, dr->dcontext) && (p->pcmodel & DUNDI_MODEL_OUTBOUND);
- allowconnect = 1;
- } else {
- /* Normal lookup / EID query */
- pass = has_permission(&p->include, dr->dcontext);
- allowconnect = p->model & DUNDI_MODEL_OUTBOUND;
- }
- if (skip) {
- if (!dundi_eid_cmp(skip, &p->eid))
- pass = 0;
- }
- if (pass) {
- if (p->order <= order) {
- /* Check order first, then check cache, regardless of
- omissions, this gets us more likely to not have an
- affected answer. */
- if((nocache || !(res = cache_lookup(dr, &p->eid, dr->crc32, &dr->expiration)))) {
- res = 0;
- /* Make sure we haven't already seen it and that it won't
- affect our answer */
- for (x=0;avoid[x];x++) {
- if (!dundi_eid_cmp(avoid[x], &p->eid) || !dundi_eid_cmp(avoid[x], &p->us_eid)) {
- /* If not a direct connection, it affects our answer */
- if (directs && !directs[x])
- ast_clear_flag_nonstd(dr->hmd, DUNDI_HINT_UNAFFECTED);
- break;
- }
- }
- /* Make sure we can ask */
- if (allowconnect) {
- if (!avoid[x] && (!blockempty || !dundi_eid_zero(&p->us_eid))) {
- /* Check for a matching or 0 cache entry */
- append_transaction(dr, p, ttl, avoid);
- } else
- ast_log(LOG_DEBUG, "Avoiding '%s' in transaction\n", dundi_eid_to_str(eid_str, sizeof(eid_str), avoid[x]));
- }
- }
- *foundcache |= res;
- } else if (!*skipped || (p->order < *skipped))
- *skipped = p->order;
- }
- }
- AST_LIST_UNLOCK(&peers);
-}
-
-static int register_request(struct dundi_request *dr, struct dundi_request **pending)
-{
- struct dundi_request *cur;
- int res=0;
- char eid_str[20];
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&requests, cur, list) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Checking '%s@%s' vs '%s@%s'\n", cur->dcontext, cur->number,
- dr->dcontext, dr->number);
- if (!strcasecmp(cur->dcontext, dr->dcontext) &&
- !strcasecmp(cur->number, dr->number) &&
- (!dundi_eid_cmp(&cur->root_eid, &dr->root_eid) || (cur->crc32 == dr->crc32))) {
- ast_log(LOG_DEBUG, "Found existing query for '%s@%s' for '%s' crc '%08lx'\n",
- cur->dcontext, cur->number, dundi_eid_to_str(eid_str, sizeof(eid_str), &cur->root_eid), cur->crc32);
- *pending = cur;
- res = 1;
- break;
- }
- }
- if (!res) {
- ast_log(LOG_DEBUG, "Registering request for '%s@%s' on behalf of '%s' crc '%08lx'\n",
- dr->number, dr->dcontext, dundi_eid_to_str(eid_str, sizeof(eid_str), &dr->root_eid), dr->crc32);
- /* Go ahead and link us in since nobody else is searching for this */
- AST_LIST_INSERT_HEAD(&requests, dr, list);
- *pending = NULL;
- }
- AST_LIST_UNLOCK(&peers);
- return res;
-}
-
-static void unregister_request(struct dundi_request *dr)
-{
- AST_LIST_LOCK(&peers);
- AST_LIST_REMOVE(&requests, dr, list);
- AST_LIST_UNLOCK(&peers);
-}
-
-static int check_request(struct dundi_request *dr)
-{
- struct dundi_request *cur;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&requests, cur, list) {
- if (cur == dr)
- break;
- }
- AST_LIST_UNLOCK(&peers);
-
- return cur ? 1 : 0;
-}
-
-static unsigned long avoid_crc32(dundi_eid *avoid[])
-{
- /* Idea is that we're calculating a checksum which is independent of
- the order that the EID's are listed in */
- unsigned long acrc32 = 0;
- int x;
- for (x=0;avoid[x];x++) {
- /* Order doesn't matter */
- if (avoid[x+1]) {
- acrc32 ^= crc32(0L, (unsigned char *)avoid[x], sizeof(dundi_eid));
- }
- }
- return acrc32;
-}
-
-static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *hmd, int *expiration, int cbypass, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int direct[])
-{
- int res;
- struct dundi_request dr, *pending;
- dundi_eid *rooteid=NULL;
- int x;
- int ttlms;
- int ms;
- int foundcache;
- int skipped=0;
- int order=0;
- char eid_str[20];
- struct timeval start;
-
- /* Don't do anthing for a hungup channel */
- if (chan && chan->_softhangup)
- return 0;
-
- ttlms = DUNDI_FLUFF_TIME + ttl * DUNDI_TTL_TIME;
-
- for (x=0;avoid[x];x++)
- rooteid = avoid[x];
- /* Now perform real check */
- memset(&dr, 0, sizeof(dr));
- if (pipe(dr.pfds)) {
- ast_log(LOG_WARNING, "pipe failed: %s\n" , strerror(errno));
- return -1;
- }
- dr.dr = result;
- dr.hmd = hmd;
- dr.maxcount = maxret;
- dr.expiration = *expiration;
- dr.cbypass = cbypass;
- dr.crc32 = avoid_crc32(avoid);
- ast_copy_string(dr.dcontext, dcontext ? dcontext : "e164", sizeof(dr.dcontext));
- ast_copy_string(dr.number, number, sizeof(dr.number));
- if (rooteid)
- dr.root_eid = *rooteid;
- res = register_request(&dr, &pending);
- if (res) {
- /* Already a request */
- if (rooteid && !dundi_eid_cmp(&dr.root_eid, &pending->root_eid)) {
- /* This is on behalf of someone else. Go ahead and close this out since
- they'll get their answer anyway. */
- ast_log(LOG_DEBUG, "Oooh, duplicate request for '%s@%s' for '%s'\n",
- dr.number,dr.dcontext,dundi_eid_to_str(eid_str, sizeof(eid_str), &dr.root_eid));
- close(dr.pfds[0]);
- close(dr.pfds[1]);
- return -2;
- } else {
- /* Wait for the cache to populate */
- ast_log(LOG_DEBUG, "Waiting for similar request for '%s@%s' for '%s'\n",
- dr.number,dr.dcontext,dundi_eid_to_str(eid_str, sizeof(eid_str), &pending->root_eid));
- start = ast_tvnow();
- while(check_request(pending) && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms) && (!chan || !chan->_softhangup)) {
- /* XXX Would be nice to have a way to poll/select here XXX */
- /* XXX this is a busy wait loop!!! */
- usleep(1);
- }
- /* Continue on as normal, our cache should kick in */
- }
- }
- /* Create transactions */
- do {
- order = skipped;
- skipped = 0;
- foundcache = 0;
- build_transactions(&dr, ttl, order, &foundcache, &skipped, blockempty, cbypass, modeselect, skip, avoid, direct);
- } while (skipped && !foundcache && AST_LIST_EMPTY(&dr.trans));
- /* If no TTL, abort and return 0 now after setting TTL expired hint. Couldn't
- do this earlier because we didn't know if we were going to have transactions
- or not. */
- if (!ttl) {
- ast_set_flag_nonstd(hmd, DUNDI_HINT_TTL_EXPIRED);
- abort_request(&dr);
- unregister_request(&dr);
- close(dr.pfds[0]);
- close(dr.pfds[1]);
- return 0;
- }
-
- /* Optimize transactions */
- optimize_transactions(&dr, order);
- /* Actually perform transactions */
- discover_transactions(&dr);
- /* Wait for transaction to come back */
- start = ast_tvnow();
- while (!AST_LIST_EMPTY(&dr.trans) && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms) && (!chan || !chan->_softhangup)) {
- ms = 100;
- ast_waitfor_n_fd(dr.pfds, 1, &ms, NULL);
- }
- if (chan && chan->_softhangup)
- ast_log(LOG_DEBUG, "Hrm, '%s' hungup before their query for %s@%s finished\n", chan->name, dr.number, dr.dcontext);
- cancel_request(&dr);
- unregister_request(&dr);
- res = dr.respcount;
- *expiration = dr.expiration;
- close(dr.pfds[0]);
- close(dr.pfds[1]);
- return res;
-}
-
-int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int cbypass)
-{
- struct dundi_hint_metadata hmd;
- dundi_eid *avoid[1] = { NULL, };
- int direct[1] = { 0, };
- int expiration = dundi_cache_time;
- memset(&hmd, 0, sizeof(hmd));
- hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED;
- return dundi_lookup_internal(result, maxret, chan, dcontext, number, dundi_ttl, 0, &hmd, &expiration, cbypass, 0, NULL, avoid, direct);
-}
-
-static void reschedule_precache(const char *number, const char *context, int expiration)
-{
- int len;
- struct dundi_precache_queue *qe, *prev;
-
- AST_LIST_LOCK(&pcq);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&pcq, qe, list) {
- if (!strcmp(number, qe->number) && !strcasecmp(context, qe->context)) {
- AST_LIST_REMOVE_CURRENT(&pcq, list);
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- if (!qe) {
- len = sizeof(*qe);
- len += strlen(number) + 1;
- len += strlen(context) + 1;
- if (!(qe = ast_calloc(1, len))) {
- AST_LIST_UNLOCK(&pcq);
- return;
- }
- strcpy(qe->number, number);
- qe->context = qe->number + strlen(number) + 1;
- strcpy(qe->context, context);
- }
- time(&qe->expiration);
- qe->expiration += expiration;
- if ((prev = AST_LIST_FIRST(&pcq))) {
- while (AST_LIST_NEXT(prev, list) && ((AST_LIST_NEXT(prev, list))->expiration <= qe->expiration))
- prev = AST_LIST_NEXT(prev, list);
- AST_LIST_INSERT_AFTER(&pcq, prev, qe, list);
- } else
- AST_LIST_INSERT_HEAD(&pcq, qe, list);
- AST_LIST_UNLOCK(&pcq);
-}
-
-static void dundi_precache_full(void)
-{
- struct dundi_mapping *cur;
- struct ast_context *con;
- struct ast_exten *e;
-
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- ast_log(LOG_NOTICE, "Should precache context '%s'\n", cur->dcontext);
- ast_rdlock_contexts();
- con = ast_walk_contexts(NULL);
- while (con) {
- if (!strcasecmp(cur->lcontext, ast_get_context_name(con))) {
- /* Found the match, now queue them all up */
- ast_lock_context(con);
- e = ast_walk_context_extensions(con, NULL);
- while (e) {
- reschedule_precache(ast_get_extension_name(e), cur->dcontext, 0);
- e = ast_walk_context_extensions(con, e);
- }
- ast_unlock_context(con);
- }
- con = ast_walk_contexts(con);
- }
- ast_unlock_contexts();
- }
-}
-
-static int dundi_precache_internal(const char *context, const char *number, int ttl, dundi_eid *avoids[])
-{
- struct dundi_request dr;
- struct dundi_hint_metadata hmd;
- struct dundi_result dr2[MAX_RESULTS];
- struct timeval start;
- struct dundi_mapping *maps = NULL, *cur;
- int nummaps = 0;
- int foundanswers;
- int foundcache, skipped, ttlms, ms;
- if (!context)
- context = "e164";
- ast_log(LOG_DEBUG, "Precache internal (%s@%s)!\n", number, context);
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- if (!strcasecmp(cur->dcontext, context))
- nummaps++;
- }
- if (nummaps) {
- maps = alloca(nummaps * sizeof(*maps));
- nummaps = 0;
- if (maps) {
- AST_LIST_TRAVERSE(&mappings, cur, list) {
- if (!strcasecmp(cur->dcontext, context))
- maps[nummaps++] = *cur;
- }
- }
- }
- AST_LIST_UNLOCK(&peers);
- if (!nummaps || !maps)
- return -1;
- ttlms = DUNDI_FLUFF_TIME + ttl * DUNDI_TTL_TIME;
- memset(&dr2, 0, sizeof(dr2));
- memset(&dr, 0, sizeof(dr));
- memset(&hmd, 0, sizeof(hmd));
- dr.dr = dr2;
- ast_copy_string(dr.number, number, sizeof(dr.number));
- ast_copy_string(dr.dcontext, context ? context : "e164", sizeof(dr.dcontext));
- dr.maxcount = MAX_RESULTS;
- dr.expiration = dundi_cache_time;
- dr.hmd = &hmd;
- dr.pfds[0] = dr.pfds[1] = -1;
- pipe(dr.pfds);
- build_transactions(&dr, ttl, 0, &foundcache, &skipped, 0, 1, 1, NULL, avoids, NULL);
- optimize_transactions(&dr, 0);
- foundanswers = 0;
- precache_transactions(&dr, maps, nummaps, &dr.expiration, &foundanswers);
- if (foundanswers) {
- if (dr.expiration > 0)
- reschedule_precache(dr.number, dr.dcontext, dr.expiration);
- else
- ast_log(LOG_NOTICE, "Weird, expiration = %d, but need to precache for %s@%s?!\n", dr.expiration, dr.number, dr.dcontext);
- }
- start = ast_tvnow();
- while (!AST_LIST_EMPTY(&dr.trans) && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms)) {
- if (dr.pfds[0] > -1) {
- ms = 100;
- ast_waitfor_n_fd(dr.pfds, 1, &ms, NULL);
- } else
- usleep(1);
- }
- cancel_request(&dr);
- if (dr.pfds[0] > -1) {
- close(dr.pfds[0]);
- close(dr.pfds[1]);
- }
- return 0;
-}
-
-int dundi_precache(const char *context, const char *number)
-{
- dundi_eid *avoid[1] = { NULL, };
- return dundi_precache_internal(context, number, dundi_ttl, avoid);
-}
-
-static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *dcontext, dundi_eid *eid, struct dundi_hint_metadata *hmd, int ttl, int blockempty, dundi_eid *avoid[])
-{
- int res;
- struct dundi_request dr;
- dundi_eid *rooteid=NULL;
- int x;
- int ttlms;
- int skipped=0;
- int foundcache=0;
- struct timeval start;
-
- ttlms = DUNDI_FLUFF_TIME + ttl * DUNDI_TTL_TIME;
-
- for (x=0;avoid[x];x++)
- rooteid = avoid[x];
- /* Now perform real check */
- memset(&dr, 0, sizeof(dr));
- dr.hmd = hmd;
- dr.dei = dei;
- dr.pfds[0] = dr.pfds[1] = -1;
- ast_copy_string(dr.dcontext, dcontext ? dcontext : "e164", sizeof(dr.dcontext));
- memcpy(&dr.query_eid, eid, sizeof(dr.query_eid));
- if (rooteid)
- dr.root_eid = *rooteid;
- /* Create transactions */
- build_transactions(&dr, ttl, 9999, &foundcache, &skipped, blockempty, 0, 0, NULL, avoid, NULL);
-
- /* If no TTL, abort and return 0 now after setting TTL expired hint. Couldn't
- do this earlier because we didn't know if we were going to have transactions
- or not. */
- if (!ttl) {
- ast_set_flag_nonstd(hmd, DUNDI_HINT_TTL_EXPIRED);
- return 0;
- }
-
- /* Optimize transactions */
- optimize_transactions(&dr, 9999);
- /* Actually perform transactions */
- query_transactions(&dr);
- /* Wait for transaction to come back */
- start = ast_tvnow();
- while (!AST_LIST_EMPTY(&dr.trans) && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms))
- usleep(1);
- res = dr.respcount;
- return res;
-}
-
-int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid)
-{
- dundi_eid *avoid[1] = { NULL, };
- struct dundi_hint_metadata hmd;
- memset(&hmd, 0, sizeof(hmd));
- return dundi_query_eid_internal(dei, dcontext, &eid, &hmd, dundi_ttl, 0, avoid);
-}
-
-static int dundifunc_read(struct ast_channel *chan, char *cmd, char *num, char *buf, size_t len)
-{
- char *context;
- char *opts;
- int results;
- int x;
- int bypass = 0;
- struct ast_module_user *u;
- struct dundi_result dr[MAX_RESULTS];
-
- buf[0] = '\0';
-
- if (ast_strlen_zero(num)) {
- ast_log(LOG_WARNING, "DUNDILOOKUP requires an argument (number)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- context = strchr(num, '|');
- if (context) {
- *context++ = '\0';
- opts = strchr(context, '|');
- if (opts) {
- *opts++ = '\0';
- if (strchr(opts, 'b'))
- bypass = 1;
- }
- }
-
- if (ast_strlen_zero(context))
- context = "e164";
-
- results = dundi_lookup(dr, MAX_RESULTS, NULL, context, num, bypass);
- if (results > 0) {
- sort_results(dr, results);
- for (x = 0; x < results; x++) {
- if (ast_test_flag(dr + x, DUNDI_FLAG_EXISTS)) {
- snprintf(buf, len, "%s/%s", dr[x].tech, dr[x].dest);
- break;
- }
- }
- }
-
- ast_module_user_remove(u);
-
- return 0;
-}
-
-/*! DUNDILOOKUP
- * \ingroup functions
-*/
-
-static struct ast_custom_function dundi_function = {
- .name = "DUNDILOOKUP",
- .synopsis = "Do a DUNDi lookup of a phone number.",
- .syntax = "DUNDILOOKUP(number[|context[|options]])",
- .desc = "This will do a DUNDi lookup of the given phone number.\n"
- "If no context is given, the default will be e164. The result of\n"
- "this function will the Technology/Resource found in the DUNDi\n"
- "lookup. If no results were found, the result will be blank.\n"
- "If the 'b' option is specified, the internal DUNDi cache will\n"
- "be bypassed.\n",
- .read = dundifunc_read,
-};
-
-static void mark_peers(void)
-{
- struct dundi_peer *peer;
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, list) {
- peer->dead = 1;
- }
- AST_LIST_UNLOCK(&peers);
-}
-
-static void mark_mappings(void)
-{
- struct dundi_mapping *map;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&mappings, map, list) {
- map->dead = 1;
- }
- AST_LIST_UNLOCK(&peers);
-}
-
-static void destroy_permissions(struct permissionlist *permlist)
-{
- struct permission *perm;
-
- while ((perm = AST_LIST_REMOVE_HEAD(permlist, list)))
- free(perm);
-}
-
-static void destroy_peer(struct dundi_peer *peer)
-{
- AST_SCHED_DEL(sched, peer->registerid);
- if (peer->regtrans)
- destroy_trans(peer->regtrans, 0);
- AST_SCHED_DEL(sched, peer->qualifyid);
- destroy_permissions(&peer->permit);
- destroy_permissions(&peer->include);
- free(peer);
-}
-
-static void destroy_map(struct dundi_mapping *map)
-{
- free(map);
-}
-
-static void prune_peers(void)
-{
- struct dundi_peer *peer;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, list) {
- if (peer->dead) {
- AST_LIST_REMOVE_CURRENT(&peers, list);
- destroy_peer(peer);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&peers);
-}
-
-static void prune_mappings(void)
-{
- struct dundi_mapping *map;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&mappings, map, list) {
- if (map->dead) {
- AST_LIST_REMOVE_CURRENT(&mappings, list);
- destroy_map(map);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&peers);
-}
-
-static void append_permission(struct permissionlist *permlist, char *s, int allow)
-{
- struct permission *perm;
-
- if (!(perm = ast_calloc(1, sizeof(*perm) + strlen(s) + 1)))
- return;
-
- strcpy(perm->name, s);
- perm->allow = allow;
-
- AST_LIST_INSERT_TAIL(permlist, perm, list);
-}
-
-#define MAX_OPTS 128
-
-static void build_mapping(char *name, char *value)
-{
- char *t, *fields[MAX_OPTS];
- struct dundi_mapping *map;
- int x;
- int y;
-
- t = ast_strdupa(value);
-
- AST_LIST_TRAVERSE(&mappings, map, list) {
- /* Find a double match */
- if (!strcasecmp(map->dcontext, name) &&
- (!strncasecmp(map->lcontext, value, strlen(map->lcontext)) &&
- (!value[strlen(map->lcontext)] ||
- (value[strlen(map->lcontext)] == ','))))
- break;
- }
- if (!map) {
- if (!(map = ast_calloc(1, sizeof(*map))))
- return;
- AST_LIST_INSERT_HEAD(&mappings, map, list);
- map->dead = 1;
- }
- map->options = 0;
- memset(fields, 0, sizeof(fields));
- x = 0;
- while (t && x < MAX_OPTS) {
- fields[x++] = t;
- t = strchr(t, ',');
- if (t) {
- *t = '\0';
- t++;
- }
- } /* Russell was here, arrrr! */
- if ((x == 1) && ast_strlen_zero(fields[0])) {
- /* Placeholder mapping */
- ast_copy_string(map->dcontext, name, sizeof(map->dcontext));
- map->dead = 0;
- } else if (x >= 4) {
- ast_copy_string(map->dcontext, name, sizeof(map->dcontext));
- ast_copy_string(map->lcontext, fields[0], sizeof(map->lcontext));
- if ((sscanf(fields[1], "%d", &map->weight) == 1) && (map->weight >= 0) && (map->weight < 60000)) {
- ast_copy_string(map->dest, fields[3], sizeof(map->dest));
- if ((map->tech = str2tech(fields[2]))) {
- map->dead = 0;
- }
- } else {
- ast_log(LOG_WARNING, "Invalid weight '%s' specified, deleting entry '%s/%s'\n", fields[1], map->dcontext, map->lcontext);
- }
- for (y = 4;y < x; y++) {
- if (!strcasecmp(fields[y], "nounsolicited"))
- map->options |= DUNDI_FLAG_NOUNSOLICITED;
- else if (!strcasecmp(fields[y], "nocomunsolicit"))
- map->options |= DUNDI_FLAG_NOCOMUNSOLICIT;
- else if (!strcasecmp(fields[y], "residential"))
- map->options |= DUNDI_FLAG_RESIDENTIAL;
- else if (!strcasecmp(fields[y], "commercial"))
- map->options |= DUNDI_FLAG_COMMERCIAL;
- else if (!strcasecmp(fields[y], "mobile"))
- map->options |= DUNDI_FLAG_MOBILE;
- else if (!strcasecmp(fields[y], "nopartial"))
- map->options |= DUNDI_FLAG_INTERNAL_NOPARTIAL;
- else
- ast_log(LOG_WARNING, "Don't know anything about option '%s'\n", fields[y]);
- }
- } else
- ast_log(LOG_WARNING, "Expected at least %d arguments in map, but got only %d\n", 4, x);
-}
-
-/* \note Called with the peers list already locked */
-static int do_register(const void *data)
-{
- struct dundi_ie_data ied;
- struct dundi_peer *peer = (struct dundi_peer *)data;
- char eid_str[20];
- char eid_str2[20];
- ast_log(LOG_DEBUG, "Register us as '%s' to '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->us_eid), dundi_eid_to_str(eid_str2, sizeof(eid_str2), &peer->eid));
- peer->registerid = ast_sched_add(sched, default_expiration * 1000, do_register, data);
- /* Destroy old transaction if there is one */
- if (peer->regtrans)
- destroy_trans(peer->regtrans, 0);
- peer->regtrans = create_transaction(peer);
- if (peer->regtrans) {
- ast_set_flag(peer->regtrans, FLAG_ISREG);
- memset(&ied, 0, sizeof(ied));
- dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION);
- dundi_ie_append_eid(&ied, DUNDI_IE_EID, &peer->regtrans->us_eid);
- dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, default_expiration);
- dundi_send(peer->regtrans, DUNDI_COMMAND_REGREQ, 0, 0, &ied);
-
- } else
- ast_log(LOG_NOTICE, "Unable to create new transaction for registering to '%s'!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
-
- return 0;
-}
-
-static int do_qualify(const void *data)
-{
- struct dundi_peer *peer = (struct dundi_peer *)data;
- peer->qualifyid = -1;
- qualify_peer(peer, 0);
- return 0;
-}
-
-static void qualify_peer(struct dundi_peer *peer, int schedonly)
-{
- int when;
- AST_SCHED_DEL(sched, peer->qualifyid);
- if (peer->qualtrans)
- destroy_trans(peer->qualtrans, 0);
- peer->qualtrans = NULL;
- if (peer->maxms > 0) {
- when = 60000;
- if (peer->lastms < 0)
- when = 10000;
- if (schedonly)
- when = 5000;
- peer->qualifyid = ast_sched_add(sched, when, do_qualify, peer);
- if (!schedonly)
- peer->qualtrans = create_transaction(peer);
- if (peer->qualtrans) {
- peer->qualtx = ast_tvnow();
- ast_set_flag(peer->qualtrans, FLAG_ISQUAL);
- dundi_send(peer->qualtrans, DUNDI_COMMAND_NULL, 0, 1, NULL);
- }
- }
-}
-static void populate_addr(struct dundi_peer *peer, dundi_eid *eid)
-{
- char data[256];
- char *c;
- int port, expire;
- char eid_str[20];
- dundi_eid_to_str(eid_str, sizeof(eid_str), eid);
- if (!ast_db_get("dundi/dpeers", eid_str, data, sizeof(data))) {
- c = strchr(data, ':');
- if (c) {
- *c = '\0';
- c++;
- if (sscanf(c, "%d:%d", &port, &expire) == 2) {
- /* Got it! */
- inet_aton(data, &peer->addr.sin_addr);
- peer->addr.sin_family = AF_INET;
- peer->addr.sin_port = htons(port);
- peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer);
- }
- }
- }
-}
-
-
-static void build_peer(dundi_eid *eid, struct ast_variable *v, int *globalpcmode)
-{
- struct dundi_peer *peer;
- struct ast_hostent he;
- struct hostent *hp;
- dundi_eid testeid;
- int needregister=0;
- char eid_str[20];
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, list) {
- if (!dundi_eid_cmp(&peer->eid, eid)) {
- break;
- }
- }
- if (!peer) {
- /* Add us into the list */
- if (!(peer = ast_calloc(1, sizeof(*peer)))) {
- AST_LIST_UNLOCK(&peers);
- return;
- }
- peer->registerid = -1;
- peer->registerexpire = -1;
- peer->qualifyid = -1;
- peer->addr.sin_family = AF_INET;
- peer->addr.sin_port = htons(DUNDI_PORT);
- populate_addr(peer, eid);
- AST_LIST_INSERT_HEAD(&peers, peer, list);
- }
- peer->dead = 0;
- peer->eid = *eid;
- peer->us_eid = global_eid;
- destroy_permissions(&peer->permit);
- destroy_permissions(&peer->include);
- AST_SCHED_DEL(sched, peer->registerid);
- for (; v; v = v->next) {
- if (!strcasecmp(v->name, "inkey")) {
- ast_copy_string(peer->inkey, v->value, sizeof(peer->inkey));
- } else if (!strcasecmp(v->name, "outkey")) {
- ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
- } else if (!strcasecmp(v->name, "host")) {
- if (!strcasecmp(v->value, "dynamic")) {
- peer->dynamic = 1;
- } else {
- hp = ast_gethostbyname(v->value, &he);
- if (hp) {
- memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
- peer->dynamic = 0;
- } else {
- ast_log(LOG_WARNING, "Unable to find host '%s' at line %d\n", v->value, v->lineno);
- peer->dead = 1;
- }
- }
- } else if (!strcasecmp(v->name, "ustothem")) {
- if (!dundi_str_to_eid(&testeid, v->value))
- peer->us_eid = testeid;
- else
- ast_log(LOG_WARNING, "'%s' is not a valid DUNDi Entity Identifier at line %d\n", v->value, v->lineno);
- } else if (!strcasecmp(v->name, "include")) {
- append_permission(&peer->include, v->value, 1);
- } else if (!strcasecmp(v->name, "permit")) {
- append_permission(&peer->permit, v->value, 1);
- } else if (!strcasecmp(v->name, "noinclude")) {
- append_permission(&peer->include, v->value, 0);
- } else if (!strcasecmp(v->name, "deny")) {
- append_permission(&peer->permit, v->value, 0);
- } else if (!strcasecmp(v->name, "register")) {
- needregister = ast_true(v->value);
- } else if (!strcasecmp(v->name, "order")) {
- if (!strcasecmp(v->value, "primary"))
- peer->order = 0;
- else if (!strcasecmp(v->value, "secondary"))
- peer->order = 1;
- else if (!strcasecmp(v->value, "tertiary"))
- peer->order = 2;
- else if (!strcasecmp(v->value, "quartiary"))
- peer->order = 3;
- else {
- ast_log(LOG_WARNING, "'%s' is not a valid order, should be primary, secondary, tertiary or quartiary at line %d\n", v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "qualify")) {
- if (!strcasecmp(v->value, "no")) {
- peer->maxms = 0;
- } else if (!strcasecmp(v->value, "yes")) {
- peer->maxms = DEFAULT_MAXMS;
- } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
- ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of dundi.conf\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), v->lineno);
- peer->maxms = 0;
- }
- } else if (!strcasecmp(v->name, "model")) {
- if (!strcasecmp(v->value, "inbound"))
- peer->model = DUNDI_MODEL_INBOUND;
- else if (!strcasecmp(v->value, "outbound"))
- peer->model = DUNDI_MODEL_OUTBOUND;
- else if (!strcasecmp(v->value, "symmetric"))
- peer->model = DUNDI_MODEL_SYMMETRIC;
- else if (!strcasecmp(v->value, "none"))
- peer->model = 0;
- else {
- ast_log(LOG_WARNING, "Unknown model '%s', should be 'none', 'outbound', 'inbound', or 'symmetric' at line %d\n",
- v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "precache")) {
- if (!strcasecmp(v->value, "inbound"))
- peer->pcmodel = DUNDI_MODEL_INBOUND;
- else if (!strcasecmp(v->value, "outbound"))
- peer->pcmodel = DUNDI_MODEL_OUTBOUND;
- else if (!strcasecmp(v->value, "symmetric"))
- peer->pcmodel = DUNDI_MODEL_SYMMETRIC;
- else if (!strcasecmp(v->value, "none"))
- peer->pcmodel = 0;
- else {
- ast_log(LOG_WARNING, "Unknown pcmodel '%s', should be 'none', 'outbound', 'inbound', or 'symmetric' at line %d\n",
- v->value, v->lineno);
- }
- }
- }
- (*globalpcmode) |= peer->pcmodel;
- if (!peer->model && !peer->pcmodel) {
- ast_log(LOG_WARNING, "Peer '%s' lacks a model or pcmodel, discarding!\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- peer->dead = 1;
- } else if ((peer->model & DUNDI_MODEL_INBOUND) && (peer->pcmodel & DUNDI_MODEL_OUTBOUND)) {
- ast_log(LOG_WARNING, "Peer '%s' may not be both inbound/symmetric model and outbound/symmetric precache model, discarding!\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- peer->dead = 1;
- } else if ((peer->model & DUNDI_MODEL_OUTBOUND) && (peer->pcmodel & DUNDI_MODEL_INBOUND)) {
- ast_log(LOG_WARNING, "Peer '%s' may not be both outbound/symmetric model and inbound/symmetric precache model, discarding!\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- peer->dead = 1;
- } else if (!AST_LIST_EMPTY(&peer->include) && !(peer->model & DUNDI_MODEL_OUTBOUND) && !(peer->pcmodel & DUNDI_MODEL_INBOUND)) {
- ast_log(LOG_WARNING, "Peer '%s' is supposed to be included in outbound searches but isn't an outbound peer or inbound precache!\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- } else if (!AST_LIST_EMPTY(&peer->permit) && !(peer->model & DUNDI_MODEL_INBOUND) && !(peer->pcmodel & DUNDI_MODEL_OUTBOUND)) {
- ast_log(LOG_WARNING, "Peer '%s' is supposed to have permission for some inbound searches but isn't an inbound peer or outbound precache!\n",
- dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
- } else {
- if (needregister) {
- peer->registerid = ast_sched_add(sched, 2000, do_register, peer);
- }
- qualify_peer(peer, 1);
- }
- AST_LIST_UNLOCK(&peers);
-}
-
-static int dundi_helper(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *data, int flag)
-{
- struct dundi_result results[MAX_RESULTS];
- int res;
- int x;
- int found = 0;
- if (!strncasecmp(context, "macro-", 6)) {
- if (!chan) {
- ast_log(LOG_NOTICE, "Can't use macro mode without a channel!\n");
- return -1;
- }
- /* If done as a macro, use macro extension */
- if (!strcasecmp(exten, "s")) {
- exten = pbx_builtin_getvar_helper(chan, "ARG1");
- if (ast_strlen_zero(exten))
- exten = chan->macroexten;
- if (ast_strlen_zero(exten))
- exten = chan->exten;
- if (ast_strlen_zero(exten)) {
- ast_log(LOG_WARNING, "Called in Macro mode with no ARG1 or MACRO_EXTEN?\n");
- return -1;
- }
- }
- if (ast_strlen_zero(data))
- data = "e164";
- } else {
- if (ast_strlen_zero(data))
- data = context;
- }
- res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
- for (x=0;x<res;x++) {
- if (ast_test_flag(results + x, flag))
- found++;
- }
- if (found >= priority)
- return 1;
- return 0;
-}
-
-static int dundi_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- return dundi_helper(chan, context, exten, priority, data, DUNDI_FLAG_EXISTS);
-}
-
-static int dundi_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- return dundi_helper(chan, context, exten, priority, data, DUNDI_FLAG_CANMATCH);
-}
-
-static int dundi_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- struct dundi_result results[MAX_RESULTS];
- int res;
- int x=0;
- char req[1024];
- struct ast_app *dial;
-
- if (!strncasecmp(context, "macro-", 6)) {
- if (!chan) {
- ast_log(LOG_NOTICE, "Can't use macro mode without a channel!\n");
- return -1;
- }
- /* If done as a macro, use macro extension */
- if (!strcasecmp(exten, "s")) {
- exten = pbx_builtin_getvar_helper(chan, "ARG1");
- if (ast_strlen_zero(exten))
- exten = chan->macroexten;
- if (ast_strlen_zero(exten))
- exten = chan->exten;
- if (ast_strlen_zero(exten)) {
- ast_log(LOG_WARNING, "Called in Macro mode with no ARG1 or MACRO_EXTEN?\n");
- return -1;
- }
- }
- if (ast_strlen_zero(data))
- data = "e164";
- } else {
- if (ast_strlen_zero(data))
- data = context;
- }
- res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
- if (res > 0) {
- sort_results(results, res);
- for (x=0;x<res;x++) {
- if (ast_test_flag(results + x, DUNDI_FLAG_EXISTS)) {
- if (!--priority)
- break;
- }
- }
- }
- if (x < res) {
- /* Got a hit! */
- snprintf(req, sizeof(req), "%s/%s", results[x].tech, results[x].dest);
- dial = pbx_findapp("Dial");
- if (dial)
- res = pbx_exec(chan, dial, req);
- } else
- res = -1;
- return res;
-}
-
-static int dundi_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- return dundi_helper(chan, context, exten, priority, data, DUNDI_FLAG_MATCHMORE);
-}
-
-static struct ast_switch dundi_switch =
-{
- name: "DUNDi",
- description: "DUNDi Discovered Dialplan Switch",
- exists: dundi_exists,
- canmatch: dundi_canmatch,
- exec: dundi_exec,
- matchmore: dundi_matchmore,
-};
-
-static int set_config(char *config_file, struct sockaddr_in* sin)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- char *cat;
- int format;
- int x;
- char hn[MAXHOSTNAMELEN] = "";
- struct ast_hostent he;
- struct hostent *hp;
- struct sockaddr_in sin2;
- static int last_port = 0;
- int globalpcmodel = 0;
- dundi_eid testeid;
-
- dundi_ttl = DUNDI_DEFAULT_TTL;
- dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;
- any_peer = NULL;
-
- cfg = ast_config_load(config_file);
-
- if (!cfg) {
- ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
- return -1;
- }
- ipaddr[0] = '\0';
- if (!gethostname(hn, sizeof(hn)-1)) {
- hp = ast_gethostbyname(hn, &he);
- if (hp) {
- memcpy(&sin2.sin_addr, hp->h_addr, sizeof(sin2.sin_addr));
- ast_copy_string(ipaddr, ast_inet_ntoa(sin2.sin_addr), sizeof(ipaddr));
- } else
- ast_log(LOG_WARNING, "Unable to look up host '%s'\n", hn);
- } else
- ast_log(LOG_WARNING, "Unable to get host name!\n");
- AST_LIST_LOCK(&peers);
- reset_global_eid();
- global_storehistory = 0;
- ast_copy_string(secretpath, "dundi", sizeof(secretpath));
- v = ast_variable_browse(cfg, "general");
- while(v) {
- if (!strcasecmp(v->name, "port")){
- sin->sin_port = ntohs(atoi(v->value));
- if(last_port==0){
- last_port=sin->sin_port;
- } else if(sin->sin_port != last_port)
- ast_log(LOG_WARNING, "change to port ignored until next asterisk re-start\n");
- } else if (!strcasecmp(v->name, "bindaddr")) {
- struct hostent *hp;
- struct ast_hostent he;
- hp = ast_gethostbyname(v->value, &he);
- if (hp) {
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- } else
- ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);
- } else if (!strcasecmp(v->name, "authdebug")) {
- authdebug = ast_true(v->value);
- } else if (!strcasecmp(v->name, "ttl")) {
- if ((sscanf(v->value, "%d", &x) == 1) && (x > 0) && (x < DUNDI_DEFAULT_TTL)) {
- dundi_ttl = x;
- } else {
- ast_log(LOG_WARNING, "'%s' is not a valid TTL at line %d, must be number from 1 to %d\n",
- v->value, v->lineno, DUNDI_DEFAULT_TTL);
- }
- } else if (!strcasecmp(v->name, "autokill")) {
- if (sscanf(v->value, "%d", &x) == 1) {
- if (x >= 0)
- global_autokilltimeout = x;
- else
- ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
- } else if (ast_true(v->value)) {
- global_autokilltimeout = DEFAULT_MAXMS;
- } else {
- global_autokilltimeout = 0;
- }
- } else if (!strcasecmp(v->name, "entityid")) {
- if (!dundi_str_to_eid(&testeid, v->value))
- global_eid = testeid;
- else
- ast_log(LOG_WARNING, "Invalid global endpoint identifier '%s' at line %d\n", v->value, v->lineno);
- } else if (!strcasecmp(v->name, "tos")) {
- if (sscanf(v->value, "%d", &format) == 1)
- tos = format & 0xff;
- else if (!strcasecmp(v->value, "lowdelay"))
- tos = IPTOS_LOWDELAY;
- else if (!strcasecmp(v->value, "throughput"))
- tos = IPTOS_THROUGHPUT;
- else if (!strcasecmp(v->value, "reliability"))
- tos = IPTOS_RELIABILITY;
-#if !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(SOLARIS)
- else if (!strcasecmp(v->value, "mincost"))
- tos = IPTOS_MINCOST;
-#endif
- else if (!strcasecmp(v->value, "none"))
- tos = 0;
- else
-#if !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(SOLARIS)
- ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
-#else
- ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', or 'none'\n", v->lineno);
-#endif
- } else if (!strcasecmp(v->name, "department")) {
- ast_copy_string(dept, v->value, sizeof(dept));
- } else if (!strcasecmp(v->name, "organization")) {
- ast_copy_string(org, v->value, sizeof(org));
- } else if (!strcasecmp(v->name, "locality")) {
- ast_copy_string(locality, v->value, sizeof(locality));
- } else if (!strcasecmp(v->name, "stateprov")) {
- ast_copy_string(stateprov, v->value, sizeof(stateprov));
- } else if (!strcasecmp(v->name, "country")) {
- ast_copy_string(country, v->value, sizeof(country));
- } else if (!strcasecmp(v->name, "email")) {
- ast_copy_string(email, v->value, sizeof(email));
- } else if (!strcasecmp(v->name, "phone")) {
- ast_copy_string(phone, v->value, sizeof(phone));
- } else if (!strcasecmp(v->name, "storehistory")) {
- global_storehistory = ast_true(v->value);
- } else if (!strcasecmp(v->name, "cachetime")) {
- if ((sscanf(v->value, "%d", &x) == 1)) {
- dundi_cache_time = x;
- } else {
- ast_log(LOG_WARNING, "'%s' is not a valid cache time at line %d. Using default value '%d'.\n",
- v->value, v->lineno, DUNDI_DEFAULT_CACHE_TIME);
- }
- }
- v = v->next;
- }
- AST_LIST_UNLOCK(&peers);
- mark_mappings();
- v = ast_variable_browse(cfg, "mappings");
- while(v) {
- build_mapping(v->name, v->value);
- v = v->next;
- }
- prune_mappings();
- mark_peers();
- cat = ast_category_browse(cfg, NULL);
- while(cat) {
- if (strcasecmp(cat, "general") && strcasecmp(cat, "mappings")) {
- /* Entries */
- if (!dundi_str_to_eid(&testeid, cat))
- build_peer(&testeid, ast_variable_browse(cfg, cat), &globalpcmodel);
- else if (!strcasecmp(cat, "*")) {
- build_peer(&empty_eid, ast_variable_browse(cfg, cat), &globalpcmodel);
- any_peer = find_peer(NULL);
- } else
- ast_log(LOG_NOTICE, "Ignoring invalid EID entry '%s'\n", cat);
- }
- cat = ast_category_browse(cfg, cat);
- }
- prune_peers();
- ast_config_destroy(cfg);
- load_password();
- if (globalpcmodel & DUNDI_MODEL_OUTBOUND)
- dundi_precache_full();
- return 0;
-}
-
-static int unload_module(void)
-{
- pthread_t previous_netthreadid = netthreadid, previous_precachethreadid = precachethreadid;
- ast_module_user_hangup_all();
-
- /* Stop all currently running threads */
- dundi_shutdown = 1;
- if (previous_netthreadid != AST_PTHREADT_NULL) {
- pthread_kill(previous_netthreadid, SIGURG);
- pthread_join(previous_netthreadid, NULL);
- }
- if (previous_precachethreadid != AST_PTHREADT_NULL) {
- pthread_kill(previous_precachethreadid, SIGURG);
- pthread_join(previous_precachethreadid, NULL);
- }
-
- ast_cli_unregister_multiple(cli_dundi, sizeof(cli_dundi) / sizeof(struct ast_cli_entry));
- ast_unregister_switch(&dundi_switch);
- ast_custom_function_unregister(&dundi_function);
- close(netsocket);
- io_context_destroy(io);
- sched_context_destroy(sched);
-
- mark_mappings();
- prune_mappings();
- mark_peers();
- prune_peers();
-
- return 0;
-}
-
-static int reload(void)
-{
- struct sockaddr_in sin;
- set_config("dundi.conf",&sin);
- return 0;
-}
-
-static int load_module(void)
-{
- int res = 0;
- struct sockaddr_in sin;
-
- dundi_set_output(dundi_debug_output);
- dundi_set_error(dundi_error_output);
-
- sin.sin_family = AF_INET;
- sin.sin_port = ntohs(DUNDI_PORT);
- sin.sin_addr.s_addr = INADDR_ANY;
-
- /* Make a UDP socket */
- io = io_context_create();
- sched = sched_context_create();
-
- if (!io || !sched) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return -1;
- }
-
- if(set_config("dundi.conf",&sin))
- return AST_MODULE_LOAD_DECLINE;
-
- netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
-
- if (netsocket < 0) {
- ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
- return -1;
- }
- if (bind(netsocket,(struct sockaddr *)&sin, sizeof(sin))) {
- ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), strerror(errno));
- return -1;
- }
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos);
-
- if (setsockopt(netsocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))
- ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
-
- res = start_network_thread();
- if (res) {
- ast_log(LOG_ERROR, "Unable to start network thread\n");
- close(netsocket);
- return -1;
- }
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "DUNDi Ready and Listening on %s port %d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-
- ast_cli_register_multiple(cli_dundi, sizeof(cli_dundi) / sizeof(struct ast_cli_entry));
- if (ast_register_switch(&dundi_switch))
- ast_log(LOG_ERROR, "Unable to register DUNDi switch\n");
- ast_custom_function_register(&dundi_function);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Distributed Universal Number Discovery (DUNDi)",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
diff --git a/1.4/pbx/pbx_gtkconsole.c b/1.4/pbx/pbx_gtkconsole.c
deleted file mode 100644
index 4a4c3ba45..000000000
--- a/1.4/pbx/pbx_gtkconsole.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief GTK Console monitor -- very kludgy right now
- *
- */
-
-/*** MODULEINFO
- <depend>gtk</depend>
- <defaultenabled>no</defaultenabled>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <sys/time.h>
-
-#include <gtk/gtk.h>
-#include <glib.h>
-
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/paths.h"
-#include "asterisk/term.h"
-
-AST_MUTEX_DEFINE_STATIC(verb_lock);
-
-static pthread_t console_thread;
-
-static int inuse=0;
-static int clipipe[2];
-static int cleanupid = -1;
-
-static GtkWidget *window;
-static GtkWidget *quit;
-static GtkWidget *closew;
-static GtkWidget *verb;
-static GtkWidget *modules;
-static GtkWidget *statusbar;
-static GtkWidget *cli;
-
-static struct timeval last;
-
-static void update_statusbar(char *msg)
-{
- gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 1);
- gtk_statusbar_push(GTK_STATUSBAR(statusbar), 1, msg);
-}
-
-static int unload_module(void)
-{
- if (inuse) {
- /* Kill off the main thread */
- pthread_cancel(console_thread);
- gdk_threads_enter();
- gtk_widget_destroy(window);
- gdk_threads_leave();
- close(clipipe[0]);
- close(clipipe[1]);
- }
- return 0;
-}
-
-static int cleanup(void *useless)
-{
- gdk_threads_enter();
- gtk_clist_thaw(GTK_CLIST(verb));
- gtk_widget_queue_resize(verb->parent);
- gtk_clist_moveto(GTK_CLIST(verb), GTK_CLIST(verb)->rows - 1, 0, 0, 0);
- cleanupid = -1;
- gdk_threads_leave();
- return 0;
-}
-
-
-static void __verboser(const char *_stuff)
-{
- char *s2[2];
- struct timeval tv;
- int ms;
- char *stuff;
-
- stuff = ast_strdupa(_stuff);
- term_strip(stuff, stuff, strlen(stuff) + 1);
-
- s2[0] = (char *)stuff;
- s2[1] = NULL;
- gtk_clist_freeze(GTK_CLIST(verb));
- gtk_clist_append(GTK_CLIST(verb), s2);
- if (!ast_tvzero(last)) {
- gdk_threads_leave();
- gettimeofday(&tv, NULL);
- if (cleanupid > -1)
- gtk_timeout_remove(cleanupid);
- ms = ast_tvdiff_ms(tv, last);
- if (ms < 100) {
- /* We just got a message within 100ms, so just schedule an update
- in the near future */
- cleanupid = gtk_timeout_add(200, cleanup, NULL);
- } else {
- cleanup(&cleanupid);
- }
- last = tv;
- } else {
- gettimeofday(&last, NULL);
- }
-}
-
-static void verboser(const char *stuff)
-{
- ast_mutex_lock(&verb_lock);
- /* Lock appropriately if we're really being called in verbose mode */
- __verboser(stuff);
- ast_mutex_unlock(&verb_lock);
-}
-
-static void cliinput(void *data, int source, GdkInputCondition ic)
-{
- static char buf[256];
- static int offset = 0;
- int res;
- char *c;
- char *l;
- char n;
- /* Read as much stuff is there */
- res = read(source, buf + offset, sizeof(buf) - 1 - offset);
- if (res > -1)
- buf[res + offset] = '\0';
- /* make sure we've null terminated whatever we have so far */
- c = buf;
- l = buf;
- while(*c) {
- if (*c == '\n') {
- /* Keep the trailing \n */
- c++;
- n = *c;
- *c = '\0';
- __verboser(l);
- *(c - 1) = '\0';
- *c = n;
- l = c;
- } else
- c++;
- }
- if (strlen(l)) {
- /* We have some left over */
- memmove(buf, l, strlen(l) + 1);
- offset = strlen(buf);
- } else {
- offset = 0;
- }
-
-}
-
-static void remove_module(void)
-{
- int res;
- char *module;
- char buf[256];
- if (GTK_CLIST(modules)->selection) {
- module = (char *) gtk_clist_get_row_data(GTK_CLIST(modules), (long) GTK_CLIST(modules)->selection->data);
- gdk_threads_leave();
- res = ast_unload_resource(module, 0);
- gdk_threads_enter();
- if (res) {
- snprintf(buf, sizeof(buf), "Module '%s' is in use", module);
- update_statusbar(buf);
- } else {
- snprintf(buf, sizeof(buf), "Module '%s' removed", module);
- update_statusbar(buf);
- }
- }
-}
-
-static int reload(void)
-{
- int res, x;
- char *module;
- char buf[256];
- if (GTK_CLIST(modules)->selection) {
- module= (char *)gtk_clist_get_row_data(GTK_CLIST(modules), (long) GTK_CLIST(modules)->selection->data);
- module = strdup(module);
- if (module) {
- gdk_threads_leave();
- res = ast_unload_resource(module, 0);
- gdk_threads_enter();
- if (res) {
- snprintf(buf, sizeof(buf), "Module '%s' is in use", module);
- update_statusbar(buf);
- } else {
- gdk_threads_leave();
- res = ast_load_resource(module);
- gdk_threads_enter();
- if (res) {
- snprintf(buf, sizeof(buf), "Error reloading module '%s'", module);
- } else {
- snprintf(buf, sizeof(buf), "Module '%s' reloaded", module);
- }
- for (x=0; x < GTK_CLIST(modules)->rows; x++) {
- if (!strcmp((char *)gtk_clist_get_row_data(GTK_CLIST(modules), x), module)) {
- gtk_clist_select_row(GTK_CLIST(modules), x, -1);
- break;
- }
- }
- update_statusbar(buf);
-
- }
- free(module);
- }
- }
-
- return 0;
-}
-
-static void file_ok_sel(GtkWidget *w, GtkFileSelection *fs)
-{
- char tmp[PATH_MAX];
- char *module = gtk_file_selection_get_filename(fs);
- char buf[256];
- snprintf(tmp, sizeof(tmp), "%s/", ast_config_AST_MODULE_DIR);
- if (!strncmp(module, (char *)tmp, strlen(tmp)))
- module += strlen(tmp);
- gdk_threads_leave();
- if (ast_load_resource(module)) {
- snprintf(buf, sizeof(buf), "Error loading module '%s'.", module);
- update_statusbar(buf);
- } else {
- snprintf(buf, sizeof(buf), "Module '%s' loaded", module);
- update_statusbar(buf);
- }
- gdk_threads_enter();
- gtk_widget_destroy(GTK_WIDGET(fs));
-}
-
-static void add_module(void)
-{
- char tmp[PATH_MAX];
- GtkWidget *filew;
- snprintf(tmp, sizeof(tmp), "%s/*.so", ast_config_AST_MODULE_DIR);
- filew = gtk_file_selection_new("Load Module");
- gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION(filew)->ok_button),
- "clicked", GTK_SIGNAL_FUNC(file_ok_sel), filew);
- gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION(filew)->cancel_button),
- "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(filew));
- gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), (char *)tmp);
- gtk_widget_show(filew);
-}
-
-static int add_mod(const char *module, const char *description, int usecount, const char *like)
-{
- char use[10];
- const char *pass[4];
- int row;
- snprintf(use, sizeof(use), "%d", usecount);
- pass[0] = module;
- pass[1] = description;
- pass[2] = use;
- pass[3] = NULL;
- row = gtk_clist_append(GTK_CLIST(modules), (char **) pass);
- gtk_clist_set_row_data(GTK_CLIST(modules), row, (char *) module);
- return 0;
-}
-
-static int mod_update(void)
-{
- char *module= NULL;
- /* Update the mod stuff */
- if (GTK_CLIST(modules)->selection) {
- module= (char *)gtk_clist_get_row_data(GTK_CLIST(modules), (long) GTK_CLIST(modules)->selection->data);
- }
- gtk_clist_freeze(GTK_CLIST(modules));
- gtk_clist_clear(GTK_CLIST(modules));
- ast_update_module_list(add_mod, NULL);
- if (module)
- gtk_clist_select_row(GTK_CLIST(modules), gtk_clist_find_row_from_data(GTK_CLIST(modules), module), -1);
- gtk_clist_thaw(GTK_CLIST(modules));
- return 1;
-}
-
-static void exit_now(GtkWidget *widget, gpointer data)
-{
- ast_loader_unregister(mod_update);
- gtk_main_quit();
- inuse--;
- ast_update_use_count();
- ast_unregister_verbose(verboser);
- ast_unload_resource("pbx_gtkconsole", 0);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "GTK Console Monitor Exiting\n");
- /* XXX Trying to quit after calling this makes asterisk segfault XXX */
-}
-
-static void exit_completely(GtkWidget *widget, gpointer data)
-{
-#if 0
- /* Clever... */
- ast_cli_command(clipipe[1], "quit");
-#else
- kill(getpid(), SIGTERM);
-#endif
-}
-
-static void exit_nicely(GtkWidget *widget, gpointer data)
-{
- fflush(stdout);
- gtk_widget_destroy(window);
-}
-
-static void *consolethread(void *data)
-{
- gtk_widget_show(window);
- gdk_threads_enter();
- gtk_main();
- gdk_threads_leave();
- return NULL;
-}
-
-static int cli_activate(void)
-{
- char buf[256] = "";
- strncpy(buf, gtk_entry_get_text(GTK_ENTRY(cli)), sizeof(buf) - 1);
- gtk_entry_set_text(GTK_ENTRY(cli), "");
- if (strlen(buf)) {
- ast_cli_command(clipipe[1], buf);
- }
- return TRUE;
-}
-
-static int show_console(void)
-{
- GtkWidget *hbox;
- GtkWidget *wbox;
- GtkWidget *notebook;
- GtkWidget *sw;
- GtkWidget *bbox, *hbbox, *add, *removew, *reloadw;
- char *modtitles[3] = { "Module", "Description", "Use Count" };
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- statusbar = gtk_statusbar_new();
- gtk_widget_show(statusbar);
-
- gtk_signal_connect(GTK_OBJECT(window), "delete_event",
- GTK_SIGNAL_FUNC (exit_nicely), window);
- gtk_signal_connect(GTK_OBJECT(window), "destroy",
- GTK_SIGNAL_FUNC (exit_now), window);
- gtk_container_set_border_width(GTK_CONTAINER(window), 10);
-
- quit = gtk_button_new_with_label("Quit Asterisk");
- gtk_signal_connect(GTK_OBJECT(quit), "clicked",
- GTK_SIGNAL_FUNC (exit_completely), window);
- gtk_widget_show(quit);
-
- closew = gtk_button_new_with_label("Close Window");
- gtk_signal_connect(GTK_OBJECT(closew), "clicked",
- GTK_SIGNAL_FUNC (exit_nicely), window);
- gtk_widget_show(closew);
-
- notebook = gtk_notebook_new();
- verb = gtk_clist_new(1);
- gtk_clist_columns_autosize(GTK_CLIST(verb));
- sw = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- gtk_container_add(GTK_CONTAINER(sw), verb);
- gtk_widget_show(verb);
- gtk_widget_show(sw);
- gtk_widget_set_usize(verb, 640, 400);
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), sw, gtk_label_new("Verbose Status"));
-
-
- modules = gtk_clist_new_with_titles(3, modtitles);
- gtk_clist_columns_autosize(GTK_CLIST(modules));
- gtk_clist_set_column_auto_resize(GTK_CLIST(modules), 0, TRUE);
- gtk_clist_set_column_auto_resize(GTK_CLIST(modules), 1, TRUE);
- gtk_clist_set_column_auto_resize(GTK_CLIST(modules), 2, TRUE);
- gtk_clist_set_sort_column(GTK_CLIST(modules), 0);
- gtk_clist_set_auto_sort(GTK_CLIST(modules), TRUE);
- gtk_clist_column_titles_passive(GTK_CLIST(modules));
- sw = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- gtk_container_add(GTK_CONTAINER(sw), modules);
- gtk_clist_set_selection_mode(GTK_CLIST(modules), GTK_SELECTION_BROWSE);
- gtk_widget_show(modules);
- gtk_widget_show(sw);
-
- add = gtk_button_new_with_label("Load...");
- gtk_widget_show(add);
- removew = gtk_button_new_with_label("Unload");
- gtk_widget_show(removew);
- reloadw = gtk_button_new_with_label("Reload");
- gtk_widget_show(reloadw);
- gtk_signal_connect(GTK_OBJECT(removew), "clicked",
- GTK_SIGNAL_FUNC (remove_module), window);
- gtk_signal_connect(GTK_OBJECT(add), "clicked",
- GTK_SIGNAL_FUNC (add_module), window);
- gtk_signal_connect(GTK_OBJECT(reloadw), "clicked",
- GTK_SIGNAL_FUNC (reload), window);
-
- bbox = gtk_vbox_new(FALSE, 5);
- gtk_widget_show(bbox);
-
- gtk_widget_set_usize(bbox, 100, -1);
- gtk_box_pack_start(GTK_BOX(bbox), add, FALSE, FALSE, 5);
- gtk_box_pack_start(GTK_BOX(bbox), removew, FALSE, FALSE, 5);
- gtk_box_pack_start(GTK_BOX(bbox), reloadw, FALSE, FALSE, 5);
-
- hbbox = gtk_hbox_new(FALSE, 5);
- gtk_widget_show(hbbox);
-
- gtk_box_pack_start(GTK_BOX(hbbox), sw, TRUE, TRUE, 5);
- gtk_box_pack_start(GTK_BOX(hbbox), bbox, FALSE, FALSE, 5);
-
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), hbbox, gtk_label_new("Module Information"));
-
- gtk_widget_show(notebook);
-
- wbox = gtk_hbox_new(FALSE, 5);
- gtk_widget_show(wbox);
- gtk_box_pack_end(GTK_BOX(wbox), quit, FALSE, FALSE, 5);
- gtk_box_pack_end(GTK_BOX(wbox), closew, FALSE, FALSE, 5);
-
- hbox = gtk_vbox_new(FALSE, 0);
- gtk_widget_show(hbox);
-
- /* Command line */
- cli = gtk_entry_new();
- gtk_widget_show(cli);
-
- gtk_signal_connect(GTK_OBJECT(cli), "activate",
- GTK_SIGNAL_FUNC (cli_activate), NULL);
-
- gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), wbox, FALSE, FALSE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), cli, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), statusbar, FALSE, FALSE, 0);
- gtk_container_add(GTK_CONTAINER(window), hbox);
- gtk_window_set_title(GTK_WINDOW(window), "Asterisk Console");
- gtk_widget_grab_focus(cli);
- ast_pthread_create(&console_thread, NULL, consolethread, NULL);
- /* XXX Okay, seriously fix me! XXX */
- usleep(100000);
- ast_register_verbose(verboser);
- gtk_clist_freeze(GTK_CLIST(verb));
- ast_loader_register(mod_update);
- gtk_clist_thaw(GTK_CLIST(verb));
- gdk_input_add(clipipe[0], GDK_INPUT_READ, cliinput, NULL);
- mod_update();
- update_statusbar("Asterisk Console Ready");
- return 0;
-}
-
-
-static int load_module(void)
-{
- if (pipe(clipipe)) {
- ast_log(LOG_WARNING, "Unable to create CLI pipe\n");
- return -1;
- }
- g_thread_init(NULL);
- if (gtk_init_check(NULL, NULL)) {
- if (!show_console()) {
- inuse++;
- ast_update_use_count();
- if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "Launched GTK Console monitor\n");
- } else
- ast_log(LOG_WARNING, "Unable to start GTK console\n");
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to start GTK console monitor -- ignoring\n");
- else if (option_verbose > 1)
- ast_verbose( VERBOSE_PREFIX_2 "GTK is not available -- skipping monitor\n");
- }
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "GTK Console",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/pbx/pbx_loopback.c b/1.4/pbx/pbx_loopback.c
deleted file mode 100644
index dcbef909b..000000000
--- a/1.4/pbx/pbx_loopback.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Loopback PBX Module
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/frame.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-#include "asterisk/md5.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/utils.h"
-#include "asterisk/crypto.h"
-#include "asterisk/astdb.h"
-
-
-/* Loopback switch substitutes ${EXTEN}, ${CONTEXT}, and ${PRIORITY} into
- the data passed to it to try to get a string of the form:
-
- [exten]@context[:priority][/extramatch]
-
- Where exten, context, and priority are another extension, context, and priority
- to lookup and "extramatch" is an extra match restriction the *original* number
- must fit if specified. The "extramatch" begins with _ like an exten pattern
- if it is specified. Note that the search context MUST be a different context
- from the current context or the search will not succeed in an effort to reduce
- the likelihood of loops (they're still possible if you try hard, so be careful!)
-
-*/
-
-
-#define LOOPBACK_COMMON \
- char buf[1024]; \
- int res; \
- char *newexten=(char *)exten, *newcontext=(char *)context; \
- int newpriority=priority; \
- char *newpattern=NULL; \
- loopback_helper(buf, sizeof(buf), exten, context, priority, data); \
- loopback_subst(&newexten, &newcontext, &newpriority, &newpattern, buf); \
- ast_log(LOG_DEBUG, "Parsed into %s @ %s priority %d\n", newexten, newcontext, newpriority); \
- if (!strcasecmp(newcontext, context)) return -1
-
-
-static char *loopback_helper(char *buf, int buflen, const char *exten, const char *context, int priority, const char *data)
-{
- struct ast_var_t *newvariable;
- struct varshead headp;
- char tmp[80];
-
- snprintf(tmp, sizeof(tmp), "%d", priority);
- memset(buf, 0, buflen);
- AST_LIST_HEAD_INIT_NOLOCK(&headp);
- AST_LIST_INSERT_HEAD(&headp, ast_var_assign("EXTEN", exten), entries);
- AST_LIST_INSERT_HEAD(&headp, ast_var_assign("CONTEXT", context), entries);
- AST_LIST_INSERT_HEAD(&headp, ast_var_assign("PRIORITY", tmp), entries);
- /* Substitute variables */
- pbx_substitute_variables_varshead(&headp, data, buf, buflen);
- /* free the list */
- while ((newvariable = AST_LIST_REMOVE_HEAD(&headp, entries)))
- ast_var_delete(newvariable);
- return buf;
-}
-
-static void loopback_subst(char **newexten, char **newcontext, int *priority, char **newpattern, char *buf)
-{
- char *con;
- char *pri;
- *newpattern = strchr(buf, '/');
- if (*newpattern)
- *(*newpattern)++ = '\0';
- con = strchr(buf, '@');
- if (con) {
- *con++ = '\0';
- pri = strchr(con, ':');
- } else
- pri = strchr(buf, ':');
- if (!ast_strlen_zero(buf))
- *newexten = buf;
- if (!ast_strlen_zero(con))
- *newcontext = con;
- if (!ast_strlen_zero(pri))
- sscanf(pri, "%d", priority);
-}
-
-static int loopback_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- LOOPBACK_COMMON;
- res = ast_exists_extension(chan, newcontext, newexten, newpriority, callerid);
- if (newpattern && !ast_extension_match(newpattern, exten))
- res = 0;
- return res;
-}
-
-static int loopback_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- LOOPBACK_COMMON;
- res = ast_canmatch_extension(chan, newcontext, newexten, newpriority, callerid);
- if (newpattern && !ast_extension_match(newpattern, exten))
- res = 0;
- return res;
-}
-
-static int loopback_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- LOOPBACK_COMMON;
- res = ast_spawn_extension(chan, newcontext, newexten, newpriority, callerid);
- /* XXX hmmm... res is overridden ? */
- if (newpattern && !ast_extension_match(newpattern, exten))
- res = -1;
- return res;
-}
-
-static int loopback_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- LOOPBACK_COMMON;
- res = ast_matchmore_extension(chan, newcontext, newexten, newpriority, callerid);
- if (newpattern && !ast_extension_match(newpattern, exten))
- res = 0;
- return res;
-}
-
-static struct ast_switch loopback_switch =
-{
- name: "Loopback",
- description: "Loopback Dialplan Switch",
- exists: loopback_exists,
- canmatch: loopback_canmatch,
- exec: loopback_exec,
- matchmore: loopback_matchmore,
-};
-
-static int unload_module(void)
-{
- ast_unregister_switch(&loopback_switch);
- return 0;
-}
-
-static int load_module(void)
-{
- ast_register_switch(&loopback_switch);
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Loopback Switch");
diff --git a/1.4/pbx/pbx_realtime.c b/1.4/pbx/pbx_realtime.c
deleted file mode 100644
index b9be0d456..000000000
--- a/1.4/pbx/pbx_realtime.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Realtime PBX Module
- *
- * \arg See also: \ref AstARA
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/frame.h"
-#include "asterisk/term.h"
-#include "asterisk/manager.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-#include "asterisk/md5.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/chanvars.h"
-#include "asterisk/sched.h"
-#include "asterisk/io.h"
-#include "asterisk/utils.h"
-#include "asterisk/crypto.h"
-#include "asterisk/astdb.h"
-
-#define MODE_MATCH 0
-#define MODE_MATCHMORE 1
-#define MODE_CANMATCH 2
-
-#define EXT_DATA_SIZE 256
-
-
-/* Realtime switch looks up extensions in the supplied realtime table.
-
- [context@][realtimetable][/options]
-
- If the realtimetable is omitted it is assumed to be "extensions". If no context is
- specified the context is assumed to be whatever is the container.
-
- The realtime table should have entries for context,exten,priority,app,args
-
- The realtime table currently does not support callerid fields.
-
-*/
-
-
-static struct ast_variable *realtime_switch_common(const char *table, const char *context, const char *exten, int priority, int mode)
-{
- struct ast_variable *var;
- struct ast_config *cfg;
- char pri[20];
- char *ematch;
- char rexten[AST_MAX_EXTENSION + 20]="";
- int match;
- snprintf(pri, sizeof(pri), "%d", priority);
- switch(mode) {
- case MODE_MATCHMORE:
- ematch = "exten LIKE";
- snprintf(rexten, sizeof(rexten), "%s_%%", exten);
- break;
- case MODE_CANMATCH:
- ematch = "exten LIKE";
- snprintf(rexten, sizeof(rexten), "%s%%", exten);
- break;
- case MODE_MATCH:
- default:
- ematch = "exten";
- ast_copy_string(rexten, exten, sizeof(rexten));
- }
- var = ast_load_realtime(table, ematch, rexten, "context", context, "priority", pri, NULL);
- if (!var) {
- cfg = ast_load_realtime_multientry(table, "exten LIKE", "\\_%", "context", context, "priority", pri, NULL);
- if (cfg) {
- char *cat = ast_category_browse(cfg, NULL);
-
- while(cat) {
- switch(mode) {
- case MODE_MATCHMORE:
- match = ast_extension_close(cat, exten, 1);
- break;
- case MODE_CANMATCH:
- match = ast_extension_close(cat, exten, 0);
- break;
- case MODE_MATCH:
- default:
- match = ast_extension_match(cat, exten);
- }
- if (match) {
- var = ast_category_detach_variables(ast_category_get(cfg, cat));
- break;
- }
- cat = ast_category_browse(cfg, cat);
- }
- ast_config_destroy(cfg);
- }
- }
- return var;
-}
-
-static struct ast_variable *realtime_common(const char *context, const char *exten, int priority, const char *data, int mode)
-{
- const char *ctx = NULL;
- char *table;
- struct ast_variable *var=NULL;
- char *buf = ast_strdupa(data);
- if (buf) {
- char *opts = strchr(buf, '/');
- if (opts)
- *opts++ = '\0';
- table = strchr(buf, '@');
- if (table) {
- *table++ = '\0';
- ctx = buf;
- }
- ctx = S_OR(ctx, context);
- table = S_OR(table, "extensions");
- var = realtime_switch_common(table, ctx, exten, priority, mode);
- }
- return var;
-}
-
-static int realtime_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- struct ast_variable *var = realtime_common(context, exten, priority, data, MODE_MATCH);
- if (var) {
- ast_variables_destroy(var);
- return 1;
- }
- return 0;
-}
-
-static int realtime_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- struct ast_variable *var = realtime_common(context, exten, priority, data, MODE_CANMATCH);
- if (var) {
- ast_variables_destroy(var);
- return 1;
- }
- return 0;
-}
-
-static int realtime_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- int res = -1;
- struct ast_variable *var = realtime_common(context, exten, priority, data, MODE_MATCH);
-
- if (var) {
- char *tmp="";
- char *app = NULL;
- struct ast_variable *v;
-
- for (v = var; v ; v = v->next) {
- if (!strcasecmp(v->name, "app"))
- app = ast_strdupa(v->value);
- else if (!strcasecmp(v->name, "appdata"))
- tmp = ast_strdupa(v->value);
- }
- ast_variables_destroy(var);
- if (!ast_strlen_zero(app)) {
- struct ast_app *a = pbx_findapp(app);
- if (a) {
- char appdata[512]="";
- char tmp1[80];
- char tmp2[80];
- char tmp3[EXT_DATA_SIZE];
-
- if(!ast_strlen_zero(tmp))
- pbx_substitute_variables_helper(chan, tmp, appdata, sizeof(appdata) - 1);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\")\n",
- term_color(tmp1, app, COLOR_BRCYAN, 0, sizeof(tmp1)),
- term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
- term_color(tmp3, S_OR(appdata, ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)));
- manager_event(EVENT_FLAG_CALL, "Newexten",
- "Channel: %s\r\n"
- "Context: %s\r\n"
- "Extension: %s\r\n"
- "Priority: %d\r\n"
- "Application: %s\r\n"
- "AppData: %s\r\n"
- "Uniqueid: %s\r\n",
- chan->name, chan->context, chan->exten, chan->priority, app, !ast_strlen_zero(appdata) ? appdata : "(NULL)", chan->uniqueid);
-
- res = pbx_exec(chan, a, appdata);
- } else
- ast_log(LOG_NOTICE, "No such application '%s' for extension '%s' in context '%s'\n", app, exten, context);
- } else {
- ast_log(LOG_WARNING, "No application specified for realtime extension '%s' in context '%s'\n", exten, context);
- }
- }
- return res;
-}
-
-static int realtime_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
-{
- struct ast_variable *var = realtime_common(context, exten, priority, data, MODE_MATCHMORE);
- if (var) {
- ast_variables_destroy(var);
- return 1;
- }
- return 0;
-}
-
-static struct ast_switch realtime_switch =
-{
- name: "Realtime",
- description: "Realtime Dialplan Switch",
- exists: realtime_exists,
- canmatch: realtime_canmatch,
- exec: realtime_exec,
- matchmore: realtime_matchmore,
-};
-
-static int unload_module(void)
-{
- ast_unregister_switch(&realtime_switch);
- return 0;
-}
-
-static int load_module(void)
-{
- ast_register_switch(&realtime_switch);
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Realtime Switch");
diff --git a/1.4/pbx/pbx_spool.c b/1.4/pbx/pbx_spool.c
deleted file mode 100644
index 8cf38a116..000000000
--- a/1.4/pbx/pbx_spool.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief Full-featured outgoing call spool support
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/stat.h>
-#include <errno.h>
-#include <time.h>
-#include <utime.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <string.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/callerid.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-
-/*
- * pbx_spool is similar in spirit to qcall, but with substantially enhanced functionality...
- * The spool file contains a header
- */
-
-enum {
- /*! Always delete the call file after a call succeeds or the
- * maximum number of retries is exceeded, even if the
- * modification time of the call file is in the future.
- */
- SPOOL_FLAG_ALWAYS_DELETE = (1 << 0),
- /* Don't unlink the call file after processing, move in qdonedir */
- SPOOL_FLAG_ARCHIVE = (1 << 1)
-};
-
-static char qdir[255];
-static char qdonedir[255];
-
-struct outgoing {
- char fn[256];
- /* Current number of retries */
- int retries;
- /* Maximum number of retries permitted */
- int maxretries;
- /* How long to wait between retries (in seconds) */
- int retrytime;
- /* How long to wait for an answer */
- int waittime;
- /* PID which is currently calling */
- long callingpid;
-
- /* What to connect to outgoing */
- char tech[256];
- char dest[256];
-
- /* If application */
- char app[256];
- char data[256];
-
- /* If extension/context/priority */
- char exten[256];
- char context[256];
- int priority;
-
- /* CallerID Information */
- char cid_num[256];
- char cid_name[256];
-
- /* account code */
- char account[AST_MAX_ACCOUNT_CODE];
-
- /* Variables and Functions */
- struct ast_variable *vars;
-
- /* Maximum length of call */
- int maxlen;
-
- /* options */
- struct ast_flags options;
-};
-
-static void init_outgoing(struct outgoing *o)
-{
- memset(o, 0, sizeof(struct outgoing));
- o->priority = 1;
- o->retrytime = 300;
- o->waittime = 45;
- ast_set_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE);
-}
-
-static void free_outgoing(struct outgoing *o)
-{
- free(o);
-}
-
-static int apply_outgoing(struct outgoing *o, char *fn, FILE *f)
-{
- char buf[256];
- char *c, *c2;
- int lineno = 0;
- struct ast_variable *var;
-
- while(fgets(buf, sizeof(buf), f)) {
- lineno++;
- /* Trim comments */
- c = buf;
- while ((c = strchr(c, '#'))) {
- if ((c == buf) || (*(c-1) == ' ') || (*(c-1) == '\t'))
- *c = '\0';
- else
- c++;
- }
-
- c = buf;
- while ((c = strchr(c, ';'))) {
- if ((c > buf) && (c[-1] == '\\')) {
- memmove(c - 1, c, strlen(c) + 1);
- c++;
- } else {
- *c = '\0';
- break;
- }
- }
-
- /* Trim trailing white space */
- while(!ast_strlen_zero(buf) && buf[strlen(buf) - 1] < 33)
- buf[strlen(buf) - 1] = '\0';
- if (!ast_strlen_zero(buf)) {
- c = strchr(buf, ':');
- if (c) {
- *c = '\0';
- c++;
- while ((*c) && (*c < 33))
- c++;
-#if 0
- printf("'%s' is '%s' at line %d\n", buf, c, lineno);
-#endif
- if (!strcasecmp(buf, "channel")) {
- ast_copy_string(o->tech, c, sizeof(o->tech));
- if ((c2 = strchr(o->tech, '/'))) {
- *c2 = '\0';
- c2++;
- ast_copy_string(o->dest, c2, sizeof(o->dest));
- } else {
- ast_log(LOG_NOTICE, "Channel should be in form Tech/Dest at line %d of %s\n", lineno, fn);
- o->tech[0] = '\0';
- }
- } else if (!strcasecmp(buf, "callerid")) {
- ast_callerid_split(c, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
- } else if (!strcasecmp(buf, "application")) {
- ast_copy_string(o->app, c, sizeof(o->app));
- } else if (!strcasecmp(buf, "data")) {
- ast_copy_string(o->data, c, sizeof(o->data));
- } else if (!strcasecmp(buf, "maxretries")) {
- if (sscanf(c, "%d", &o->maxretries) != 1) {
- ast_log(LOG_WARNING, "Invalid max retries at line %d of %s\n", lineno, fn);
- o->maxretries = 0;
- }
- } else if (!strcasecmp(buf, "context")) {
- ast_copy_string(o->context, c, sizeof(o->context));
- } else if (!strcasecmp(buf, "extension")) {
- ast_copy_string(o->exten, c, sizeof(o->exten));
- } else if (!strcasecmp(buf, "priority")) {
- if ((sscanf(c, "%d", &o->priority) != 1) || (o->priority < 1)) {
- ast_log(LOG_WARNING, "Invalid priority at line %d of %s\n", lineno, fn);
- o->priority = 1;
- }
- } else if (!strcasecmp(buf, "retrytime")) {
- if ((sscanf(c, "%d", &o->retrytime) != 1) || (o->retrytime < 1)) {
- ast_log(LOG_WARNING, "Invalid retrytime at line %d of %s\n", lineno, fn);
- o->retrytime = 300;
- }
- } else if (!strcasecmp(buf, "waittime")) {
- if ((sscanf(c, "%d", &o->waittime) != 1) || (o->waittime < 1)) {
- ast_log(LOG_WARNING, "Invalid waittime at line %d of %s\n", lineno, fn);
- o->waittime = 45;
- }
- } else if (!strcasecmp(buf, "retry")) {
- o->retries++;
- } else if (!strcasecmp(buf, "startretry")) {
- if (sscanf(c, "%ld", &o->callingpid) != 1) {
- ast_log(LOG_WARNING, "Unable to retrieve calling PID!\n");
- o->callingpid = 0;
- }
- } else if (!strcasecmp(buf, "endretry") || !strcasecmp(buf, "abortretry")) {
- o->callingpid = 0;
- o->retries++;
- } else if (!strcasecmp(buf, "delayedretry")) {
- } else if (!strcasecmp(buf, "setvar") || !strcasecmp(buf, "set")) {
- c2 = c;
- strsep(&c2, "=");
- if (c2) {
- var = ast_variable_new(c, c2);
- if (var) {
- var->next = o->vars;
- o->vars = var;
- }
- } else
- ast_log(LOG_WARNING, "Malformed \"%s\" argument. Should be \"%s: variable=value\"\n", buf, buf);
- } else if (!strcasecmp(buf, "account")) {
- ast_copy_string(o->account, c, sizeof(o->account));
- } else if (!strcasecmp(buf, "alwaysdelete")) {
- ast_set2_flag(&o->options, ast_true(c), SPOOL_FLAG_ALWAYS_DELETE);
- } else if (!strcasecmp(buf, "archive")) {
- ast_set2_flag(&o->options, ast_true(c), SPOOL_FLAG_ARCHIVE);
- } else {
- ast_log(LOG_WARNING, "Unknown keyword '%s' at line %d of %s\n", buf, lineno, fn);
- }
- } else
- ast_log(LOG_NOTICE, "Syntax error at line %d of %s\n", lineno, fn);
- }
- }
- ast_copy_string(o->fn, fn, sizeof(o->fn));
- if (ast_strlen_zero(o->tech) || ast_strlen_zero(o->dest) || (ast_strlen_zero(o->app) && ast_strlen_zero(o->exten))) {
- ast_log(LOG_WARNING, "At least one of app or extension must be specified, along with tech and dest in file %s\n", fn);
- return -1;
- }
- return 0;
-}
-
-static void safe_append(struct outgoing *o, time_t now, char *s)
-{
- int fd;
- FILE *f;
- struct utimbuf tbuf;
- fd = open(o->fn, O_WRONLY|O_APPEND);
- if (fd > -1) {
- f = fdopen(fd, "a");
- if (f) {
- fprintf(f, "\n%s: %ld %d (%ld)\n", s, (long)ast_mainpid, o->retries, (long) now);
- fclose(f);
- } else
- close(fd);
- /* Update the file time */
- tbuf.actime = now;
- tbuf.modtime = now + o->retrytime;
- if (utime(o->fn, &tbuf))
- ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", o->fn, strerror(errno));
- }
-}
-
-/*!
- * \brief Remove a call file from the outgoing queue optionally moving it in the archive dir
- *
- * \param o the pointer to outgoing struct
- * \param status the exit status of the call. Can be "Completed", "Failed" or "Expired"
- */
-static int remove_from_queue(struct outgoing *o, const char *status)
-{
- int fd;
- FILE *f;
- char newfn[256];
- const char *bname;
-
- if (!ast_test_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE)) {
- struct stat current_file_status;
-
- if (!stat(o->fn, &current_file_status))
- if (time(NULL) < current_file_status.st_mtime)
- return 0;
- }
-
- if (!ast_test_flag(&o->options, SPOOL_FLAG_ARCHIVE)) {
- unlink(o->fn);
- return 0;
- }
- if (mkdir(qdonedir, 0700) && (errno != EEXIST)) {
- ast_log(LOG_WARNING, "Unable to create queue directory %s -- outgoing spool archiving disabled\n", qdonedir);
- unlink(o->fn);
- return -1;
- }
- fd = open(o->fn, O_WRONLY|O_APPEND);
- if (fd > -1) {
- f = fdopen(fd, "a");
- if (f) {
- fprintf(f, "Status: %s\n", status);
- fclose(f);
- } else
- close(fd);
- }
-
- bname = strrchr(o->fn,'/');
- if (bname == NULL)
- bname = o->fn;
- else
- bname++;
- snprintf(newfn, sizeof(newfn), "%s/%s", qdonedir, bname);
- /* a existing call file the archive dir is overwritten */
- unlink(newfn);
- if (rename(o->fn, newfn) != 0) {
- unlink(o->fn);
- return -1;
- } else
- return 0;
-}
-
-static void *attempt_thread(void *data)
-{
- struct outgoing *o = data;
- int res, reason;
- if (!ast_strlen_zero(o->app)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries);
- res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
- res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
- }
- if (res) {
- ast_log(LOG_NOTICE, "Call failed to go through, reason (%d) %s\n", reason, ast_channel_reason2str(reason));
- if (o->retries >= o->maxretries + 1) {
- /* Max retries exceeded */
- ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : "");
- remove_from_queue(o, "Expired");
- } else {
- /* Notate that the call is still active */
- safe_append(o, time(NULL), "EndRetry");
- }
- } else {
- ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest);
- ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest);
- remove_from_queue(o, "Completed");
- }
- free_outgoing(o);
- return NULL;
-}
-
-static void launch_service(struct outgoing *o)
-{
- pthread_t t;
- pthread_attr_t attr;
- int ret;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if ((ret = ast_pthread_create(&t,&attr,attempt_thread, o)) != 0) {
- ast_log(LOG_WARNING, "Unable to create thread :( (returned error: %d)\n", ret);
- free_outgoing(o);
- }
- pthread_attr_destroy(&attr);
-}
-
-static int scan_service(char *fn, time_t now, time_t atime)
-{
- struct outgoing *o;
- FILE *f;
- o = malloc(sizeof(struct outgoing));
- if (o) {
- init_outgoing(o);
- f = fopen(fn, "r+");
- if (f) {
- if (!apply_outgoing(o, fn, f)) {
-#if 0
- printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
-#endif
- fclose(f);
- if (o->retries <= o->maxretries) {
- now += o->retrytime;
- if (o->callingpid && (o->callingpid == ast_mainpid)) {
- safe_append(o, time(NULL), "DelayedRetry");
- ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
- free_outgoing(o);
- } else {
- /* Increment retries */
- o->retries++;
- /* If someone else was calling, they're presumably gone now
- so abort their retry and continue as we were... */
- if (o->callingpid)
- safe_append(o, time(NULL), "AbortRetry");
-
- safe_append(o, now, "StartRetry");
- launch_service(o);
- }
- return now;
- } else {
- ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : "");
- free_outgoing(o);
- remove_from_queue(o, "Expired");
- return 0;
- }
- } else {
- free_outgoing(o);
- ast_log(LOG_WARNING, "Invalid file contents in %s, deleting\n", fn);
- fclose(f);
- remove_from_queue(o, "Failed");
- }
- } else {
- free_outgoing(o);
- ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno));
- remove_from_queue(o, "Failed");
- }
- } else
- ast_log(LOG_WARNING, "Out of memory :(\n");
- return -1;
-}
-
-static void *scan_thread(void *unused)
-{
- struct stat st;
- DIR *dir;
- struct dirent *de;
- char fn[256];
- int res;
- time_t last = 0, next = 0, now;
- for(;;) {
- /* Wait a sec */
- sleep(1);
- time(&now);
- if (!stat(qdir, &st)) {
- if ((st.st_mtime != last) || (next && (now > next))) {
-#if 0
- printf("atime: %ld, mtime: %ld, ctime: %ld\n", st.st_atime, st.st_mtime, st.st_ctime);
- printf("Ooh, something changed / timeout\n");
-#endif
- next = 0;
- last = st.st_mtime;
- dir = opendir(qdir);
- if (dir) {
- while((de = readdir(dir))) {
- snprintf(fn, sizeof(fn), "%s/%s", qdir, de->d_name);
- if (!stat(fn, &st)) {
- if (S_ISREG(st.st_mode)) {
- if (st.st_mtime <= now) {
- res = scan_service(fn, now, st.st_atime);
- if (res > 0) {
- /* Update next service time */
- if (!next || (res < next)) {
- next = res;
- }
- } else if (res)
- ast_log(LOG_WARNING, "Failed to scan service '%s'\n", fn);
- } else {
- /* Update "next" update if necessary */
- if (!next || (st.st_mtime < next))
- next = st.st_mtime;
- }
- }
- } else
- ast_log(LOG_WARNING, "Unable to stat %s: %s\n", fn, strerror(errno));
- }
- closedir(dir);
- } else
- ast_log(LOG_WARNING, "Unable to open directory %s: %s\n", qdir, strerror(errno));
- }
- } else
- ast_log(LOG_WARNING, "Unable to stat %s\n", qdir);
- }
- return NULL;
-}
-
-static int unload_module(void)
-{
- return -1;
-}
-
-static int load_module(void)
-{
- pthread_t thread;
- pthread_attr_t attr;
- int ret;
- snprintf(qdir, sizeof(qdir), "%s/%s", ast_config_AST_SPOOL_DIR, "outgoing");
- if (mkdir(qdir, 0700) && (errno != EEXIST)) {
- ast_log(LOG_WARNING, "Unable to create queue directory %s -- outgoing spool disabled\n", qdir);
- return 0;
- }
- snprintf(qdonedir, sizeof(qdir), "%s/%s", ast_config_AST_SPOOL_DIR, "outgoing_done");
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if ((ret = ast_pthread_create_background(&thread,&attr,scan_thread, NULL)) != 0) {
- ast_log(LOG_WARNING, "Unable to create thread :( (returned error: %d)\n", ret);
- return -1;
- }
- pthread_attr_destroy(&attr);
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Outgoing Spool Support");
diff --git a/1.4/redhat/asterisk.spec b/1.4/redhat/asterisk.spec
deleted file mode 100644
index 4f4ab892c..000000000
--- a/1.4/redhat/asterisk.spec
+++ /dev/null
@@ -1,137 +0,0 @@
-Summary: Asterisk PBX
-Name: asterisk
-Distribution: RedHat
-Version: CVS
-Release: 1
-Copyright: Linux Support Services, inc.
-Group: Utilities/System
-Vendor: Linux Support Services, inc.
-Packager: Robert Vojta <vojta@ipex.cz>
-BuildRoot: /tmp/asterisk
-
-%description
-Asterisk is an Open Source PBX and telephony development platform that
-can both replace a conventional PBX and act as a platform for developing
-custom telephony applications for delivering dynamic content over a
-telephone similarly to how one can deliver dynamic content through a
-web browser using CGI and a web server.
-
-Asterisk talks to a variety of telephony hardware including BRI, PRI,
-POTS, and IP telephony clients using the Inter-Asterisk eXchange
-protocol (e.g. gnophone or miniphone). For more information and a
-current list of supported hardware, see www.asteriskpbx.com.
-
-%package devel
-Summary: Header files for building Asterisk modules
-Group: Development/Libraries
-
-%description devel
-This package contains the development header files that are needed
-to compile 3rd party modules.
-
-%post
-ln -sf /var/spool/asterisk/vm /var/lib/asterisk/sounds/vm
-
-%files
-#
-# Configuration files
-#
-%attr(0755,root,root) %dir /etc/asterisk
-%config(noreplace) %attr(0640,root,root) /etc/asterisk/*.conf
-%config(noreplace) %attr(0640,root,root) /etc/asterisk/*.adsi
-%config(noreplace) %attr(0640,root,root) /etc/asterisk/extensions.ael
-
-#
-# RedHat specific init script file
-#
-%attr(0755,root,root) /etc/rc.d/init.d/asterisk
-
-#
-# Modules
-#
-%attr(0755,root,root) %dir /usr/lib/asterisk
-%attr(0755,root,root) %dir /usr/lib/asterisk/modules
-%attr(0755,root,root) /usr/lib/asterisk/modules/*.so
-
-#
-# Asterisk
-#
-%attr(0755,root,root) /usr/sbin/asterisk
-%attr(0755,root,root) /usr/sbin/safe_asterisk
-%attr(0755,root,root) /usr/sbin/astgenkey
-%attr(0755,root,root) /usr/sbin/astman
-%attr(0755,root,root) /usr/sbin/autosupport
-%attr(0755,root,root) /usr/sbin/smsq
-%attr(0755,root,root) /usr/sbin/stereorize
-%attr(0755,root,root) /usr/sbin/streamplayer
-
-#
-# CDR Locations
-#
-%attr(0755,root,root) %dir /var/log/asterisk
-%attr(0755,root,root) %dir /var/log/asterisk/cdr-csv
-#
-# Running directories
-#
-%attr(0755,root,root) %dir /var/run
-#
-# Sound files
-#
-%attr(0755,root,root) %dir /var/lib/asterisk
-%attr(0755,root,root) %dir /var/lib/asterisk/sounds
-%attr(0644,root,root) /var/lib/asterisk/sounds/*.gsm
-%attr(0755,root,root) %dir /var/lib/asterisk/sounds/dictate
-%attr(0644,root,root) /var/lib/asterisk/sounds/dictate/*.gsm
-%attr(0755,root,root) %dir /var/lib/asterisk/sounds/digits
-%attr(0644,root,root) /var/lib/asterisk/sounds/digits/*.gsm
-%attr(0755,root,root) %dir /var/lib/asterisk/sounds/letters
-%attr(0644,root,root) /var/lib/asterisk/sounds/letters/*.gsm
-%attr(0755,root,root) %dir /var/lib/asterisk/sounds/phonetic
-%attr(0644,root,root) /var/lib/asterisk/sounds/phonetic/*.gsm
-%attr(0755,root,root) %dir /var/lib/asterisk/sounds/silence
-%attr(0644,root,root) /var/lib/asterisk/sounds/silence/*.gsm
-%attr(0755,root,root) %dir /var/lib/asterisk/mohmp3
-%attr(0644,root,root) /var/lib/asterisk/mohmp3/*
-%attr(0755,root,root) %dir /var/lib/asterisk/images
-%attr(0644,root,root) /var/lib/asterisk/images/*
-%attr(0755,root,root) %dir /var/lib/asterisk/keys
-%attr(0644,root,root) /var/lib/asterisk/keys/*
-%attr(0755,root,root) %dir /var/lib/asterisk/agi-bin
-%attr(0755,root,root) %dir /var/lib/asterisk/agi-bin/*
-#
-# Man page
-#
-%attr(0644,root,root) /usr/share/man/man8/asterisk.8
-%attr(0644,root,root) /usr/share/man/man8/astgenkey.8
-%attr(0644,root,root) /usr/share/man/man8/autosupport.8
-%attr(0644,root,root) /usr/share/man/man8/safe_asterisk.8
-
-#
-# Firmware
-#
-%attr(0755,root,root) %dir /var/lib/asterisk/firmware
-%attr(0755,root,root) %dir /var/lib/asterisk/firmware/iax
-%attr(0755,root,root) /var/lib/asterisk/firmware/iax/*.bin
-
-#
-# Example voicemail files
-#
-%attr(0755,root,root) %dir /var/spool/asterisk
-%attr(0755,root,root) %dir /var/spool/asterisk/voicemail
-%attr(0755,root,root) %dir /var/spool/asterisk/voicemail/default
-%attr(0755,root,root) %dir /var/spool/asterisk/voicemail/default/1234
-%attr(0755,root,root) %dir /var/spool/asterisk/voicemail/default/1234/INBOX
-%attr(0644,root,root) /var/spool/asterisk/voicemail/default/1234/*.gsm
-
-#
-# Misc other spool
-#
-%attr(0755,root,root) %dir /var/spool/asterisk/system
-%attr(0755,root,root) %dir /var/spool/asterisk/tmp
-
-%files devel
-#
-# Include files
-#
-%attr(0755,root,root) %dir %{_includedir}/asterisk
-%attr(0644,root,root) %{_includedir}/asterisk/*.h
diff --git a/1.4/redhat/rpmmacros b/1.4/redhat/rpmmacros
deleted file mode 100644
index fbf2ee3ed..000000000
--- a/1.4/redhat/rpmmacros
+++ /dev/null
@@ -1,3 +0,0 @@
-%_tmppath /tmp/asterisk
-%_topdir %{_tmppath}/redhat
-%_rpmfilename %%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
diff --git a/1.4/redhat/rpmrc b/1.4/redhat/rpmrc
deleted file mode 100644
index 88c57d10b..000000000
--- a/1.4/redhat/rpmrc
+++ /dev/null
@@ -1,3 +0,0 @@
-#############################################################
-macrofiles: /usr/lib/rpm/macros:/usr/lib/rpm/%{_target}/macros:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros:/tmp/asterisk/rpmmacros
-#############################################################
diff --git a/1.4/res/Makefile b/1.4/res/Makefile
deleted file mode 100644
index aad078f23..000000000
--- a/1.4/res/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for resource modules
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=RES
-MENUSELECT_DESCRIPTION=Resource Modules
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard res_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard res_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_RES),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_RES),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring res,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
-
-snmp/agent.o: ASTCFLAGS+=$(MENUSELECT_OPTS_res_snmp:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_res_snmp),$(value $(dep)_INCLUDE))
-
-$(if $(filter res_snmp,$(EMBEDDED_MODS)),modules.link,res_snmp.so): snmp/agent.o
-
-clean::
- rm -f snmp/*.o
diff --git a/1.4/res/res_adsi.c b/1.4/res/res_adsi.c
deleted file mode 100644
index 38648a8d4..000000000
--- a/1.4/res/res_adsi.c
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ADSI support
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \note this module is required by app_voicemail and app_getcpeid
- * \todo Move app_getcpeid into this module
- * \todo Create a core layer so that app_voicemail does not require
- * res_adsi to load
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <time.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <math.h>
-#include <errno.h>
-
-#include "asterisk/ulaw.h"
-#include "asterisk/alaw.h"
-#include "asterisk/callerid.h"
-#include "asterisk/logger.h"
-#include "asterisk/fskmodem.h"
-#include "asterisk/channel.h"
-#include "asterisk/adsi.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/file.h"
-
-#define DEFAULT_ADSI_MAX_RETRIES 3
-
-#define ADSI_MAX_INTRO 20
-#define ADSI_MAX_SPEED_DIAL 6
-
-#define ADSI_FLAG_DATAMODE (1 << 8)
-
-static int maxretries = DEFAULT_ADSI_MAX_RETRIES;
-
-/* Asterisk ADSI button definitions */
-#define ADSI_SPEED_DIAL 10 /* 10-15 are reserved for speed dial */
-
-static char intro[ADSI_MAX_INTRO][20];
-static int aligns[ADSI_MAX_INTRO];
-
-static char speeddial[ADSI_MAX_SPEED_DIAL][3][20];
-
-static int alignment = 0;
-
-static int adsi_generate(unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, int codec)
-{
- int sum;
- int x;
- int bytes=0;
- /* Initial carrier (imaginary) */
- float cr = 1.0;
- float ci = 0.0;
- float scont = 0.0;
-
- if (msglen > 255)
- msglen = 255;
-
- /* If first message, Send 150ms of MARK's */
- if (msgnum == 1) {
- for (x=0;x<150;x++) /* was 150 */
- PUT_CLID_MARKMS;
- }
- /* Put message type */
- PUT_CLID(msgtype);
- sum = msgtype;
-
- /* Put message length (plus one for the message number) */
- PUT_CLID(msglen + 1);
- sum += msglen + 1;
-
- /* Put message number */
- PUT_CLID(msgnum);
- sum += msgnum;
-
- /* Put actual message */
- for (x=0;x<msglen;x++) {
- PUT_CLID(msg[x]);
- sum += msg[x];
- }
-
- /* Put 2's compliment of sum */
- PUT_CLID(256-(sum & 0xff));
-
-#if 0
- if (last) {
- /* Put trailing marks */
- for (x=0;x<50;x++)
- PUT_CLID_MARKMS;
- }
-#endif
- return bytes;
-
-}
-
-static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int len, int *remainder)
-{
- /* Sends carefully on a full duplex channel by using reading for
- timing */
- struct ast_frame *inf, outf;
- int amt;
-
- /* Zero out our outgoing frame */
- memset(&outf, 0, sizeof(outf));
-
- if (remainder && *remainder) {
- amt = len;
-
- /* Send remainder if provided */
- if (amt > *remainder)
- amt = *remainder;
- else
- *remainder = *remainder - amt;
- outf.frametype = AST_FRAME_VOICE;
- outf.subclass = AST_FORMAT_ULAW;
- outf.data = buf;
- outf.datalen = amt;
- outf.samples = amt;
- if (ast_write(chan, &outf)) {
- ast_log(LOG_WARNING, "Failed to carefully write frame\n");
- return -1;
- }
- /* Update pointers and lengths */
- buf += amt;
- len -= amt;
- }
-
- while(len) {
- amt = len;
- /* If we don't get anything at all back in a second, forget
- about it */
- if (ast_waitfor(chan, 1000) < 1)
- return -1;
- inf = ast_read(chan);
- /* Detect hangup */
- if (!inf)
- return -1;
- if (inf->frametype == AST_FRAME_VOICE) {
- /* Read a voice frame */
- if (inf->subclass != AST_FORMAT_ULAW) {
- ast_log(LOG_WARNING, "Channel not in ulaw?\n");
- ast_frfree(inf);
- return -1;
- }
- /* Send no more than they sent us */
- if (amt > inf->datalen)
- amt = inf->datalen;
- else if (remainder)
- *remainder = inf->datalen - amt;
- outf.frametype = AST_FRAME_VOICE;
- outf.subclass = AST_FORMAT_ULAW;
- outf.data = buf;
- outf.datalen = amt;
- outf.samples = amt;
- if (ast_write(chan, &outf)) {
- ast_log(LOG_WARNING, "Failed to carefully write frame\n");
- ast_frfree(inf);
- return -1;
- }
- /* Update pointers and lengths */
- buf += amt;
- len -= amt;
- }
- ast_frfree(inf);
- }
- return 0;
-}
-
-static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
-{
- /* msglen must be no more than 256 bits, each */
- unsigned char buf[24000 * 5];
- int pos = 0, res;
- int x;
- int start=0;
- int retries = 0;
-
- char ack[3];
-
- /* Wait up to 500 ms for initial ACK */
- int waittime;
- struct ast_frame *f;
- int rem = 0;
- int def;
-
- if (chan->adsicpe == AST_ADSI_UNAVAILABLE) {
- /* Don't bother if we know they don't support ADSI */
- errno = ENOSYS;
- return -1;
- }
-
- while(retries < maxretries) {
- if (!(chan->adsicpe & ADSI_FLAG_DATAMODE)) {
- /* Generate CAS (no SAS) */
- ast_gen_cas(buf, 0, 680, AST_FORMAT_ULAW);
-
- /* Send CAS */
- if (adsi_careful_send(chan, buf, 680, NULL)) {
- ast_log(LOG_WARNING, "Unable to send CAS\n");
- }
- /* Wait For DTMF result */
- waittime = 500;
- for(;;) {
- if (((res = ast_waitfor(chan, waittime)) < 1)) {
- /* Didn't get back DTMF A in time */
- ast_log(LOG_DEBUG, "No ADSI CPE detected (%d)\n", res);
- if (!chan->adsicpe)
- chan->adsicpe = AST_ADSI_UNAVAILABLE;
- errno = ENOSYS;
- return -1;
- }
- waittime = res;
- f = ast_read(chan);
- if (!f) {
- ast_log(LOG_DEBUG, "Hangup in ADSI\n");
- return -1;
- }
- if (f->frametype == AST_FRAME_DTMF) {
- if (f->subclass == 'A') {
- /* Okay, this is an ADSI CPE. Note this for future reference, too */
- if (!chan->adsicpe)
- chan->adsicpe = AST_ADSI_AVAILABLE;
- break;
- } else {
- if (f->subclass == 'D') {
- ast_log(LOG_DEBUG, "Off-hook capable CPE only, not ADSI\n");
- } else
- ast_log(LOG_WARNING, "Unknown ADSI response '%c'\n", f->subclass);
- if (!chan->adsicpe)
- chan->adsicpe = AST_ADSI_UNAVAILABLE;
- errno = ENOSYS;
- ast_frfree(f);
- return -1;
- }
- }
- ast_frfree(f);
- }
-
- ast_log(LOG_DEBUG, "ADSI Compatible CPE Detected\n");
- } else
- ast_log(LOG_DEBUG, "Already in data mode\n");
-
- x = 0;
- pos = 0;
-#if 1
- def= ast_channel_defer_dtmf(chan);
-#endif
- while((x < 6) && msg[x]) {
- res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], AST_FORMAT_ULAW);
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to generate ADSI message %d on channel %s\n", x + 1, chan->name);
- return -1;
- }
- ast_log(LOG_DEBUG, "Message %d, of %d input bytes, %d output bytes\n",
- x + 1, msglen[x], res);
- pos += res;
- x++;
- }
-
-
- rem = 0;
- res = adsi_careful_send(chan, buf, pos, &rem);
- if (!def)
- ast_channel_undefer_dtmf(chan);
- if (res)
- return -1;
-
- ast_log(LOG_DEBUG, "Sent total spill of %d bytes\n", pos);
-
- memset(ack, 0, sizeof(ack));
- /* Get real result */
- res = ast_readstring(chan, ack, 2, 1000, 1000, "");
- /* Check for hangup */
- if (res < 0)
- return -1;
- if (ack[0] == 'D') {
- ast_log(LOG_DEBUG, "Acked up to message %d\n", atoi(ack + 1));
- start += atoi(ack + 1);
- if (start >= x)
- break;
- else {
- retries++;
- ast_log(LOG_DEBUG, "Retransmitting (%d), from %d\n", retries, start + 1);
- }
- } else {
- retries++;
- ast_log(LOG_WARNING, "Unexpected response to ack: %s (retry %d)\n", ack, retries);
- }
- }
- if (retries >= maxretries) {
- ast_log(LOG_WARNING, "Maximum ADSI Retries (%d) exceeded\n", maxretries);
- errno = ETIMEDOUT;
- return -1;
- }
- return 0;
-
-}
-
-int ast_adsi_begin_download(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version)
-{
- int bytes;
- unsigned char buf[256];
- char ack[2];
- bytes = 0;
- /* Setup the resident soft key stuff, a piece at a time */
- /* Upload what scripts we can for voicemail ahead of time */
- bytes += ast_adsi_download_connect(buf + bytes, service, fdn, sec, version);
- if (ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0))
- return -1;
- if (ast_readstring(chan, ack, 1, 10000, 10000, ""))
- return -1;
- if (ack[0] == 'B')
- return 0;
- ast_log(LOG_DEBUG, "Download was denied by CPE\n");
- return -1;
-}
-
-int ast_adsi_end_download(struct ast_channel *chan)
-{
- int bytes;
- unsigned char buf[256];
- bytes = 0;
- /* Setup the resident soft key stuff, a piece at a time */
- /* Upload what scripts we can for voicemail ahead of time */
- bytes += ast_adsi_download_disconnect(buf + bytes);
- if (ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0))
- return -1;
- return 0;
-}
-
-int ast_adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
-{
- unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
- int msglens[5];
- int msgtypes[5];
- int newdatamode;
- int res;
- int x;
- int writeformat, readformat;
- int waitforswitch = 0;
-
- writeformat = chan->writeformat;
- readformat = chan->readformat;
-
- newdatamode = chan->adsicpe & ADSI_FLAG_DATAMODE;
-
- for (x=0;x<msglen;x+=(msg[x+1]+2)) {
- if (msg[x] == ADSI_SWITCH_TO_DATA) {
- ast_log(LOG_DEBUG, "Switch to data is sent!\n");
- waitforswitch++;
- newdatamode = ADSI_FLAG_DATAMODE;
- }
-
- if (msg[x] == ADSI_SWITCH_TO_VOICE) {
- ast_log(LOG_DEBUG, "Switch to voice is sent!\n");
- waitforswitch++;
- newdatamode = 0;
- }
- }
- msgs[0] = msg;
-
- msglens[0] = msglen;
- msgtypes[0] = msgtype;
-
- if (msglen > 253) {
- ast_log(LOG_WARNING, "Can't send ADSI message of %d bytes, too large\n", msglen);
- return -1;
- }
-
- ast_stopstream(chan);
-
- if (ast_set_write_format(chan, AST_FORMAT_ULAW)) {
- ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
- return -1;
- }
-
- if (ast_set_read_format(chan, AST_FORMAT_ULAW)) {
- ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
- if (writeformat) {
- if (ast_set_write_format(chan, writeformat))
- ast_log(LOG_WARNING, "Unable to restore write format to %d\n", writeformat);
- }
- return -1;
- }
- res = __adsi_transmit_messages(chan, msgs, msglens, msgtypes);
-
- if (dowait) {
- ast_log(LOG_DEBUG, "Wait for switch is '%d'\n", waitforswitch);
- while(waitforswitch-- && ((res = ast_waitfordigit(chan, 1000)) > 0)) { res = 0; ast_log(LOG_DEBUG, "Waiting for 'B'...\n"); }
- }
-
- if (!res)
- chan->adsicpe = (chan->adsicpe & ~ADSI_FLAG_DATAMODE) | newdatamode;
-
- if (writeformat)
- ast_set_write_format(chan, writeformat);
- if (readformat)
- ast_set_read_format(chan, readformat);
-
- if (!res)
- res = ast_safe_sleep(chan, 100 );
- return res;
-}
-
-int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
-{
- return ast_adsi_transmit_message_full(chan, msg, msglen, msgtype, 1);
-}
-
-static inline int ccopy(unsigned char *dst, const unsigned char *src, int max)
-{
- int x=0;
- /* Carefully copy the requested data */
- while ((x < max) && src[x] && (src[x] != 0xff)) {
- dst[x] = src[x];
- x++;
- }
- return x;
-}
-
-int ast_adsi_load_soft_key(unsigned char *buf, int key, const char *llabel, const char *slabel, const char *ret, int data)
-{
- int bytes=0;
-
- /* Abort if invalid key specified */
- if ((key < 2) || (key > 33))
- return -1;
- buf[bytes++] = ADSI_LOAD_SOFTKEY;
- /* Reserve for length */
- bytes++;
- /* Which key */
- buf[bytes++] = key;
-
- /* Carefully copy long label */
- bytes += ccopy(buf + bytes, (const unsigned char *)llabel, 18);
-
- /* Place delimiter */
- buf[bytes++] = 0xff;
-
- /* Short label */
- bytes += ccopy(buf + bytes, (const unsigned char *)slabel, 7);
-
-
- /* If specified, copy return string */
- if (ret) {
- /* Place delimiter */
- buf[bytes++] = 0xff;
- if (data)
- buf[bytes++] = ADSI_SWITCH_TO_DATA2;
- /* Carefully copy return string */
- bytes += ccopy(buf + bytes, (const unsigned char *)ret, 20);
-
- }
- /* Replace parameter length */
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_connect_session(unsigned char *buf, unsigned char *fdn, int ver)
-{
- int bytes=0;
- int x;
-
- /* Message type */
- buf[bytes++] = ADSI_CONNECT_SESSION;
-
- /* Reserve space for length */
- bytes++;
-
- if (fdn) {
- for (x=0;x<4;x++)
- buf[bytes++] = fdn[x];
- if (ver > -1)
- buf[bytes++] = ver & 0xff;
- }
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_download_connect(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
-{
- int bytes=0;
- int x;
-
- /* Message type */
- buf[bytes++] = ADSI_DOWNLOAD_CONNECT;
-
- /* Reserve space for length */
- bytes++;
-
- /* Primary column */
- bytes+= ccopy(buf + bytes, (unsigned char *)service, 18);
-
- /* Delimiter */
- buf[bytes++] = 0xff;
-
- for (x=0;x<4;x++) {
- buf[bytes++] = fdn[x];
- }
- for (x=0;x<4;x++)
- buf[bytes++] = sec[x];
- buf[bytes++] = ver & 0xff;
-
- buf[1] = bytes - 2;
-
- return bytes;
-
-}
-
-int ast_adsi_disconnect_session(unsigned char *buf)
-{
- int bytes=0;
-
- /* Message type */
- buf[bytes++] = ADSI_DISC_SESSION;
-
- /* Reserve space for length */
- bytes++;
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_query_cpeid(unsigned char *buf)
-{
- int bytes = 0;
- buf[bytes++] = ADSI_QUERY_CPEID;
- /* Reserve space for length */
- bytes++;
- buf[1] = bytes - 2;
- return bytes;
-}
-
-int ast_adsi_query_cpeinfo(unsigned char *buf)
-{
- int bytes = 0;
- buf[bytes++] = ADSI_QUERY_CONFIG;
- /* Reserve space for length */
- bytes++;
- buf[1] = bytes - 2;
- return bytes;
-}
-
-int ast_adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen)
-{
- int bytes = 0;
- int res;
- unsigned char current = 0;
- int gotstar = 0;
- int pos = 0;
- memset(buf, 0, sizeof(buf));
- while(bytes <= maxlen) {
- /* Wait up to a second for a digit */
- res = ast_waitfordigit(chan, 1000);
- if (!res)
- break;
- if (res == '*') {
- gotstar = 1;
- continue;
- }
- /* Ignore anything other than a digit */
- if ((res < '0') || (res > '9'))
- continue;
- res -= '0';
- if (gotstar)
- res += 9;
- if (pos) {
- pos = 0;
- buf[bytes++] = (res << 4) | current;
- } else {
- pos = 1;
- current = res;
- }
- gotstar = 0;
- }
- return bytes;
-}
-
-int ast_adsi_get_cpeid(struct ast_channel *chan, unsigned char *cpeid, int voice)
-{
- unsigned char buf[256];
- int bytes = 0;
- int res;
- bytes += ast_adsi_data_mode(buf);
- ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
-
- bytes = 0;
- bytes += ast_adsi_query_cpeid(buf);
- ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
-
- /* Get response */
- memset(buf, 0, sizeof(buf));
- res = ast_adsi_read_encoded_dtmf(chan, cpeid, 4);
- if (res != 4) {
- ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
- res = 0;
- } else {
- res = 1;
- }
-
- if (voice) {
- bytes = 0;
- bytes += ast_adsi_voice_mode(buf, 0);
- ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
- /* Ignore the resulting DTMF B announcing it's in voice mode */
- ast_waitfordigit(chan, 1000);
- }
- return res;
-}
-
-int ast_adsi_get_cpeinfo(struct ast_channel *chan, int *width, int *height, int *buttons, int voice)
-{
- unsigned char buf[256];
- int bytes = 0;
- int res;
- bytes += ast_adsi_data_mode(buf);
- ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
-
- bytes = 0;
- bytes += ast_adsi_query_cpeinfo(buf);
- ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
-
- /* Get width */
- memset(buf, 0, sizeof(buf));
- res = ast_readstring(chan, (char *)buf, 2, 1000, 500, "");
- if (res < 0)
- return res;
- if (strlen((char *)buf) != 2) {
- ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
- res = 0;
- } else {
- res = 1;
- }
- if (width)
- *width = atoi((char *)buf);
- /* Get height */
- memset(buf, 0, sizeof(buf));
- if (res) {
- res = ast_readstring(chan, (char *)buf, 2, 1000, 500, "");
- if (res < 0)
- return res;
- if (strlen((char *)buf) != 2) {
- ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
- res = 0;
- } else {
- res = 1;
- }
- if (height)
- *height= atoi((char *)buf);
- }
- /* Get buttons */
- memset(buf, 0, sizeof(buf));
- if (res) {
- res = ast_readstring(chan, (char *)buf, 1, 1000, 500, "");
- if (res < 0)
- return res;
- if (strlen((char *)buf) != 1) {
- ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
- res = 0;
- } else {
- res = 1;
- }
- if (buttons)
- *buttons = atoi((char *)buf);
- }
- if (voice) {
- bytes = 0;
- bytes += ast_adsi_voice_mode(buf, 0);
- ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
- /* Ignore the resulting DTMF B announcing it's in voice mode */
- ast_waitfordigit(chan, 1000);
- }
- return res;
-}
-
-int ast_adsi_data_mode(unsigned char *buf)
-{
- int bytes=0;
-
- /* Message type */
- buf[bytes++] = ADSI_SWITCH_TO_DATA;
-
- /* Reserve space for length */
- bytes++;
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_clear_soft_keys(unsigned char *buf)
-{
- int bytes=0;
-
- /* Message type */
- buf[bytes++] = ADSI_CLEAR_SOFTKEY;
-
- /* Reserve space for length */
- bytes++;
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_clear_screen(unsigned char *buf)
-{
- int bytes=0;
-
- /* Message type */
- buf[bytes++] = ADSI_CLEAR_SCREEN;
-
- /* Reserve space for length */
- bytes++;
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_voice_mode(unsigned char *buf, int when)
-{
- int bytes=0;
-
- /* Message type */
- buf[bytes++] = ADSI_SWITCH_TO_VOICE;
-
- /* Reserve space for length */
- bytes++;
-
- buf[bytes++] = when & 0x7f;
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_available(struct ast_channel *chan)
-{
- int cpe = chan->adsicpe & 0xff;
- if ((cpe == AST_ADSI_AVAILABLE) ||
- (cpe == AST_ADSI_UNKNOWN))
- return 1;
- return 0;
-}
-
-int ast_adsi_download_disconnect(unsigned char *buf)
-{
- int bytes=0;
-
- /* Message type */
- buf[bytes++] = ADSI_DOWNLOAD_DISC;
-
- /* Reserve space for length */
- bytes++;
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap,
- char *col1, char *col2)
-{
- int bytes=0;
-
- /* Sanity check line number */
-
- if (page) {
- if (line > 4) return -1;
- } else {
- if (line > 33) return -1;
- }
-
- if (line < 1)
- return -1;
- /* Parameter type */
- buf[bytes++] = ADSI_LOAD_VIRTUAL_DISP;
-
- /* Reserve space for size */
- bytes++;
-
- /* Page and wrap indicator */
- buf[bytes++] = ((page & 0x1) << 7) | ((wrap & 0x1) << 6) | (line & 0x3f);
-
- /* Justification */
- buf[bytes++] = (just & 0x3) << 5;
-
- /* Omit highlight mode definition */
- buf[bytes++] = 0xff;
-
- /* Primary column */
- bytes+= ccopy(buf + bytes, (unsigned char *)col1, 20);
-
- /* Delimiter */
- buf[bytes++] = 0xff;
-
- /* Secondary column */
- bytes += ccopy(buf + bytes, (unsigned char *)col2, 20);
-
- /* Update length */
- buf[1] = bytes - 2;
-
- return bytes;
-
-}
-
-int ast_adsi_input_control(unsigned char *buf, int page, int line, int display, int format, int just)
-{
- int bytes=0;
-
- if (page) {
- if (line > 4) return -1;
- } else {
- if (line > 33) return -1;
- }
-
- if (line < 1)
- return -1;
-
- buf[bytes++] = ADSI_INPUT_CONTROL;
- bytes++;
- buf[bytes++] = ((page & 1) << 7) | (line & 0x3f);
- buf[bytes++] = ((display & 1) << 7) | ((just & 0x3) << 4) | (format & 0x7);
-
- buf[1] = bytes - 2;
- return bytes;
-
-}
-
-int ast_adsi_input_format(unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
-{
- int bytes = 0;
-
- if (!strlen((char *)format1))
- return -1;
-
- buf[bytes++] = ADSI_INPUT_FORMAT;
- bytes++;
- buf[bytes++] = ((dir & 1) << 7) | ((wrap & 1) << 6) | (num & 0x7);
- bytes += ccopy(buf + bytes, (unsigned char *)format1, 20);
- buf[bytes++] = 0xff;
- if (format2 && strlen((char *)format2)) {
- bytes += ccopy(buf + bytes, (unsigned char *)format2, 20);
- }
- buf[1] = bytes - 2;
- return bytes;
-}
-
-int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
-{
- int bytes=0;
- int x;
- /* Message type */
- buf[bytes++] = ADSI_INIT_SOFTKEY_LINE;
- /* Space for size */
- bytes++;
- /* Key definitions */
- for (x=0;x<6;x++)
- buf[bytes++] = (keys[x] & 0x3f) ? keys[x] : (keys[x] | 0x1);
- buf[1] = bytes - 2;
- return bytes;
-}
-
-int ast_adsi_set_line(unsigned char *buf, int page, int line)
-{
- int bytes=0;
-
- /* Sanity check line number */
-
- if (page) {
- if (line > 4) return -1;
- } else {
- if (line > 33) return -1;
- }
-
- if (line < 1)
- return -1;
- /* Parameter type */
- buf[bytes++] = ADSI_LINE_CONTROL;
-
- /* Reserve space for size */
- bytes++;
-
- /* Page and line */
- buf[bytes++] = ((page & 0x1) << 7) | (line & 0x3f);
-
- buf[1] = bytes - 2;
- return bytes;
-
-};
-
-static int total = 0;
-static int speeds = 0;
-
-int ast_adsi_channel_restore(struct ast_channel *chan)
-{
- unsigned char dsp[256];
- int bytes;
- int x;
- unsigned char keyd[6];
-
- memset(dsp, 0, sizeof(dsp));
-
- /* Start with initial display setup */
- bytes = 0;
- bytes += ast_adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
-
- /* Prepare key setup messages */
-
- if (speeds) {
- memset(keyd, 0, sizeof(keyd));
- for (x=0;x<speeds;x++) {
- keyd[x] = ADSI_SPEED_DIAL + x;
- }
- bytes += ast_adsi_set_keys(dsp + bytes, keyd);
- }
- ast_adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0);
- return 0;
-
-}
-
-int ast_adsi_print(struct ast_channel *chan, char **lines, int *aligns, int voice)
-{
- unsigned char buf[4096];
- int bytes=0;
- int res;
- int x;
- for(x=0;lines[x];x++)
- bytes += ast_adsi_display(buf + bytes, ADSI_INFO_PAGE, x+1, aligns[x], 0, lines[x], "");
- bytes += ast_adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1);
- if (voice) {
- bytes += ast_adsi_voice_mode(buf + bytes, 0);
- }
- res = ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
- if (voice) {
- /* Ignore the resulting DTMF B announcing it's in voice mode */
- ast_waitfordigit(chan, 1000);
- }
- return res;
-}
-
-int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data)
-{
- unsigned char dsp[256];
- int bytes;
- int res;
- char resp[2];
-
- memset(dsp, 0, sizeof(dsp));
-
- /* Connect to session */
- bytes = 0;
- bytes += ast_adsi_connect_session(dsp + bytes, app, ver);
-
- if (data)
- bytes += ast_adsi_data_mode(dsp + bytes);
-
- /* Prepare key setup messages */
- if (ast_adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0))
- return -1;
- if (app) {
- res = ast_readstring(chan, resp, 1, 1200, 1200, "");
- if (res < 0)
- return -1;
- if (res) {
- ast_log(LOG_DEBUG, "No response from CPE about version. Assuming not there.\n");
- return 0;
- }
- if (!strcmp(resp, "B")) {
- ast_log(LOG_DEBUG, "CPE has script '%s' version %d already loaded\n", app, ver);
- return 1;
- } else if (!strcmp(resp, "A")) {
- ast_log(LOG_DEBUG, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
- } else {
- ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
- }
- } else
- return 1;
- return 0;
-
-}
-
-int ast_adsi_unload_session(struct ast_channel *chan)
-{
- unsigned char dsp[256];
- int bytes;
-
- memset(dsp, 0, sizeof(dsp));
-
- /* Connect to session */
- bytes = 0;
- bytes += ast_adsi_disconnect_session(dsp + bytes);
- bytes += ast_adsi_voice_mode(dsp + bytes, 0);
-
- /* Prepare key setup messages */
- if (ast_adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0))
- return -1;
- return 0;
-}
-
-static int str2align(char *s)
-{
- if (!strncasecmp(s, "l", 1))
- return ADSI_JUST_LEFT;
- else if (!strncasecmp(s, "r", 1))
- return ADSI_JUST_RIGHT;
- else if (!strncasecmp(s, "i", 1))
- return ADSI_JUST_IND;
- else
- return ADSI_JUST_CENT;
-}
-
-static void init_state(void)
-{
- int x;
-
- for (x=0;x<ADSI_MAX_INTRO;x++)
- aligns[x] = ADSI_JUST_CENT;
- ast_copy_string(intro[0], "Welcome to the", sizeof(intro[0]));
- ast_copy_string(intro[1], "Asterisk", sizeof(intro[1]));
- ast_copy_string(intro[2], "Open Source PBX", sizeof(intro[2]));
- total = 3;
- speeds = 0;
- for (x=3;x<ADSI_MAX_INTRO;x++)
- intro[x][0] = '\0';
- memset(speeddial, 0, sizeof(speeddial));
- alignment = ADSI_JUST_CENT;
-}
-
-static void adsi_load(void)
-{
- int x;
- struct ast_config *conf;
- struct ast_variable *v;
- char *name, *sname;
- init_state();
- conf = ast_config_load("adsi.conf");
- if (conf) {
- x=0;
- for (v = ast_variable_browse(conf, "intro"); v; v = v->next) {
- if (!strcasecmp(v->name, "alignment"))
- alignment = str2align(v->value);
- else if (!strcasecmp(v->name, "greeting")) {
- if (x < ADSI_MAX_INTRO) {
- aligns[x] = alignment;
- ast_copy_string(intro[x], v->value, sizeof(intro[x]));
- x++;
- }
- } else if (!strcasecmp(v->name, "maxretries")) {
- if (atoi(v->value) > 0)
- maxretries = atoi(v->value);
- }
- }
- if (x)
- total = x;
- x = 0;
- for (v = ast_variable_browse(conf, "speeddial"); v; v = v->next) {
- char *stringp = v->value;
- name = strsep(&stringp, ",");
- sname = strsep(&stringp, ",");
- if (!sname)
- sname = name;
- if (x < ADSI_MAX_SPEED_DIAL) {
- ast_copy_string(speeddial[x][0], v->name, sizeof(speeddial[x][0]));
- ast_copy_string(speeddial[x][1], name, 18);
- ast_copy_string(speeddial[x][2], sname, 7);
- x++;
- }
- }
- if (x)
- speeds = x;
- ast_config_destroy(conf);
- }
-}
-
-static int reload(void)
-{
- adsi_load();
- return 0;
-}
-
-static int load_module(void)
-{
- adsi_load();
- return 0;
-}
-
-static int unload_module(void)
-{
- /* Can't unload this once we're loaded */
- return -1;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "ADSI Resource",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_agi.c b/1.4/res/res_agi.c
deleted file mode 100644
index 4b23b0110..000000000
--- a/1.4/res/res_agi.c
+++ /dev/null
@@ -1,2193 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief AGI - the Asterisk Gateway Interface
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <math.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/wait.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/astdb.h"
-#include "asterisk/callerid.h"
-#include "asterisk/cli.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/image.h"
-#include "asterisk/say.h"
-#include "asterisk/app.h"
-#include "asterisk/dsp.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/strings.h"
-#include "asterisk/agi.h"
-
-#define MAX_ARGS 128
-#define MAX_COMMANDS 128
-#define AGI_NANDFS_RETRY 3
-#define AGI_BUF_LEN 2048
-
-/* Recycle some stuff from the CLI interface */
-#define fdprintf agi_debug_cli
-
-static char *app = "AGI";
-
-static char *eapp = "EAGI";
-
-static char *deadapp = "DeadAGI";
-
-static char *synopsis = "Executes an AGI compliant application";
-static char *esynopsis = "Executes an EAGI compliant application";
-static char *deadsynopsis = "Executes AGI on a hungup channel";
-
-static char *descrip =
-" [E|Dead]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n"
-"program on a channel. AGI allows Asterisk to launch external programs\n"
-"written in any language to control a telephony channel, play audio,\n"
-"read DTMF digits, etc. by communicating with the AGI protocol on stdin\n"
-"and stdout.\n"
-" This channel will stop dialplan execution on hangup inside of this\n"
-"application, except when using DeadAGI. Otherwise, dialplan execution\n"
-"will continue normally.\n"
-" A locally executed AGI script will receive SIGHUP on hangup from the channel\n"
-"except when using DeadAGI. This can be disabled by setting the AGISIGHUP channel\n"
-"variable to \"no\" before executing the AGI application.\n"
-" Using 'EAGI' provides enhanced AGI, with incoming audio available out of band\n"
-"on file descriptor 3\n\n"
-" Use the CLI command 'agi show' to list available agi commands\n"
-" This application sets the following channel variable upon completion:\n"
-" AGISTATUS The status of the attempt to the run the AGI script\n"
-" text string, one of SUCCESS | FAILURE | HANGUP\n";
-
-static int agidebug = 0;
-
-#define TONE_BLOCK_SIZE 200
-
-/* Max time to connect to an AGI remote host */
-#define MAX_AGI_CONNECT 2000
-
-#define AGI_PORT 4573
-
-enum agi_result {
- AGI_RESULT_SUCCESS,
- AGI_RESULT_SUCCESS_FAST,
- AGI_RESULT_FAILURE,
- AGI_RESULT_HANGUP
-};
-
-static int agi_debug_cli(int fd, char *fmt, ...)
-{
- char *stuff;
- int res = 0;
-
- va_list ap;
- va_start(ap, fmt);
- res = vasprintf(&stuff, fmt, ap);
- va_end(ap);
- if (res == -1) {
- ast_log(LOG_ERROR, "Out of memory\n");
- } else {
- if (agidebug)
- ast_verbose("AGI Tx >> %s", stuff); /* \n provided by caller */
- res = ast_carefulwrite(fd, stuff, strlen(stuff), 100);
- free(stuff);
- }
-
- return res;
-}
-
-/* launch_netscript: The fastagi handler.
- FastAGI defaults to port 4573 */
-static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds, int *efd, int *opid)
-{
- int s;
- int flags;
- struct pollfd pfds[1];
- char *host;
- char *c; int port = AGI_PORT;
- char *script="";
- struct sockaddr_in sin;
- struct hostent *hp;
- struct ast_hostent ahp;
- int res;
-
- /* agiusl is "agi://host.domain[:port][/script/name]" */
- host = ast_strdupa(agiurl + 6); /* Remove agi:// */
- /* Strip off any script name */
- if ((c = strchr(host, '/'))) {
- *c = '\0';
- c++;
- script = c;
- }
- if ((c = strchr(host, ':'))) {
- *c = '\0';
- c++;
- port = atoi(c);
- }
- if (efd) {
- ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n");
- return -1;
- }
- hp = ast_gethostbyname(host, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
- return -1;
- }
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
- return -1;
- }
- flags = fcntl(s, F_GETFL);
- if (flags < 0) {
- ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno));
- close(s);
- return -1;
- }
- if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno));
- close(s);
- return -1;
- }
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) {
- ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno));
- close(s);
- return AGI_RESULT_FAILURE;
- }
-
- pfds[0].fd = s;
- pfds[0].events = POLLOUT;
- while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
- if (errno != EINTR) {
- if (!res) {
- ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
- agiurl, MAX_AGI_CONNECT);
- } else
- ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
- close(s);
- return AGI_RESULT_FAILURE;
- }
- }
-
- if (fdprintf(s, "agi_network: yes\n") < 0) {
- if (errno != EINTR) {
- ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
- close(s);
- return AGI_RESULT_FAILURE;
- }
- }
-
- /* If we have a script parameter, relay it to the fastagi server */
- if (!ast_strlen_zero(script))
- fdprintf(s, "agi_network_script: %s\n", script);
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Wow, connected!\n");
- fds[0] = s;
- fds[1] = s;
- *opid = -1;
- return AGI_RESULT_SUCCESS_FAST;
-}
-
-static enum agi_result launch_script(char *script, char *argv[], int *fds, int *efd, int *opid)
-{
- char tmp[256];
- int pid;
- int toast[2];
- int fromast[2];
- int audio[2];
- int x;
- int res;
- sigset_t signal_set, old_set;
-
- if (!strncasecmp(script, "agi://", 6))
- return launch_netscript(script, argv, fds, efd, opid);
-
- if (script[0] != '/') {
- snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script);
- script = tmp;
- }
- if (pipe(toast)) {
- ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
- return AGI_RESULT_FAILURE;
- }
- if (pipe(fromast)) {
- ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
- close(toast[0]);
- close(toast[1]);
- return AGI_RESULT_FAILURE;
- }
- if (efd) {
- if (pipe(audio)) {
- ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
- close(fromast[0]);
- close(fromast[1]);
- close(toast[0]);
- close(toast[1]);
- return AGI_RESULT_FAILURE;
- }
- res = fcntl(audio[1], F_GETFL);
- if (res > -1)
- res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
- if (res < 0) {
- ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
- close(fromast[0]);
- close(fromast[1]);
- close(toast[0]);
- close(toast[1]);
- close(audio[0]);
- close(audio[1]);
- return AGI_RESULT_FAILURE;
- }
- }
-
- /* Block SIGHUP during the fork - prevents a race */
- sigfillset(&signal_set);
- pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
- pid = fork();
- if (pid < 0) {
- ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
- pthread_sigmask(SIG_SETMASK, &old_set, NULL);
- return AGI_RESULT_FAILURE;
- }
- if (!pid) {
- /* Pass paths to AGI via environmental variables */
- setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
- setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
- setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
- setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
- setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
- setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
- setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
- setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
- setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
- setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
- setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
-
- /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
- ast_set_priority(0);
-
- /* Redirect stdin and out, provide enhanced audio channel if desired */
- dup2(fromast[0], STDIN_FILENO);
- dup2(toast[1], STDOUT_FILENO);
- if (efd) {
- dup2(audio[0], STDERR_FILENO + 1);
- } else {
- close(STDERR_FILENO + 1);
- }
-
- /* Before we unblock our signals, return our trapped signals back to the defaults */
- signal(SIGHUP, SIG_DFL);
- signal(SIGCHLD, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGURG, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGPIPE, SIG_DFL);
- signal(SIGXFSZ, SIG_DFL);
-
- /* unblock important signal handlers */
- if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
- ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
- _exit(1);
- }
-
- /* Close everything but stdin/out/error */
- for (x=STDERR_FILENO + 2;x<1024;x++)
- close(x);
-
- /* Execute script */
- execv(script, argv);
- /* Can't use ast_log since FD's are closed */
- fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno));
- /* Special case to set status of AGI to failure */
- fprintf(stdout, "failure\n");
- fflush(stdout);
- _exit(1);
- }
- pthread_sigmask(SIG_SETMASK, &old_set, NULL);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
- fds[0] = toast[0];
- fds[1] = fromast[1];
- if (efd) {
- *efd = audio[1];
- }
- /* close what we're not using in the parent */
- close(toast[1]);
- close(fromast[0]);
-
- if (efd)
- close(audio[0]);
-
- *opid = pid;
- return AGI_RESULT_SUCCESS;
-}
-
-static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced)
-{
- /* Print initial environment, with agi_request always being the first
- thing */
- fdprintf(fd, "agi_request: %s\n", request);
- fdprintf(fd, "agi_channel: %s\n", chan->name);
- fdprintf(fd, "agi_language: %s\n", chan->language);
- fdprintf(fd, "agi_type: %s\n", chan->tech->type);
- fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid);
-
- /* ANI/DNIS */
- fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown"));
- fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown"));
- fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres);
- fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2);
- fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton);
- fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns);
- fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown"));
- fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown"));
-
- /* Context information */
- fdprintf(fd, "agi_context: %s\n", chan->context);
- fdprintf(fd, "agi_extension: %s\n", chan->exten);
- fdprintf(fd, "agi_priority: %d\n", chan->priority);
- fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
-
- /* User information */
- fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
-
- /* End with empty return */
- fdprintf(fd, "\n");
-}
-
-static int handle_answer(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- res = 0;
- if (chan->_state != AST_STATE_UP) {
- /* Answer the chan */
- res = ast_answer(chan);
- }
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int to;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[3], "%d", &to) != 1)
- return RESULT_SHOWUSAGE;
- res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_sendtext(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- /* At the moment, the parser (perhaps broken) returns with
- the last argument PLUS the newline at the end of the input
- buffer. This probably needs to be fixed, but I wont do that
- because other stuff may break as a result. The right way
- would probably be to strip off the trailing newline before
- parsing, then here, add a newline at the end of the string
- before sending it to ast_sendtext --DUDE */
- res = ast_sendtext(chan, argv[2]);
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- res = ast_recvchar(chan,atoi(argv[2]));
- if (res == 0) {
- fdprintf(agi->fd, "200 result=%d (timeout)\n", res);
- return RESULT_SUCCESS;
- }
- if (res > 0) {
- fdprintf(agi->fd, "200 result=%d\n", res);
- return RESULT_SUCCESS;
- }
- else {
- fdprintf(agi->fd, "200 result=%d (hangup)\n", res);
- return RESULT_FAILURE;
- }
-}
-
-static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- char *buf;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- buf = ast_recvtext(chan,atoi(argv[2]));
- if (buf) {
- fdprintf(agi->fd, "200 result=1 (%s)\n", buf);
- free(buf);
- } else {
- fdprintf(agi->fd, "200 result=-1\n");
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res,x;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- if (!strncasecmp(argv[2],"on",2))
- x = 1;
- else
- x = 0;
- if (!strncasecmp(argv[2],"mate",4))
- x = 2;
- if (!strncasecmp(argv[2],"tdd",3))
- x = 1;
- res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
- if (res != RESULT_SUCCESS)
- fdprintf(agi->fd, "200 result=0\n");
- else
- fdprintf(agi->fd, "200 result=1\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_sendimage(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- res = ast_send_image(chan, argv[2]);
- if (!ast_check_hangup(chan))
- res = 0;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res = 0;
- int skipms = 3000;
- char *fwd = NULL;
- char *rev = NULL;
- char *pause = NULL;
- char *stop = NULL;
-
- if (argc < 5 || argc > 9)
- return RESULT_SHOWUSAGE;
-
- if (!ast_strlen_zero(argv[4]))
- stop = argv[4];
- else
- stop = NULL;
-
- if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1))
- return RESULT_SHOWUSAGE;
-
- if (argc > 6 && !ast_strlen_zero(argv[6]))
- fwd = argv[6];
- else
- fwd = "#";
-
- if (argc > 7 && !ast_strlen_zero(argv[7]))
- rev = argv[7];
- else
- rev = "*";
-
- if (argc > 8 && !ast_strlen_zero(argv[8]))
- pause = argv[8];
- else
- pause = NULL;
-
- res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms);
-
- fdprintf(agi->fd, "200 result=%d\n", res);
-
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int vres;
- struct ast_filestream *fs;
- struct ast_filestream *vfs;
- long sample_offset = 0;
- long max_length;
- char *edigits = "";
-
- if (argc < 4 || argc > 5)
- return RESULT_SHOWUSAGE;
-
- if (argv[3])
- edigits = argv[3];
-
- if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1))
- return RESULT_SHOWUSAGE;
-
- fs = ast_openstream(chan, argv[2], chan->language);
-
- if (!fs) {
- fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
- return RESULT_SUCCESS;
- }
- vfs = ast_openvstream(chan, argv[2], chan->language);
- if (vfs)
- ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
-
- ast_seekstream(fs, 0, SEEK_END);
- max_length = ast_tellstream(fs);
- ast_seekstream(fs, sample_offset, SEEK_SET);
- res = ast_applystream(chan, fs);
- if (vfs)
- vres = ast_applystream(chan, vfs);
- ast_playstream(fs);
- if (vfs)
- ast_playstream(vfs);
-
- res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
- /* this is to check for if ast_waitstream closed the stream, we probably are at
- * the end of the stream, return that amount, else check for the amount */
- sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
- ast_stopstream(chan);
- if (res == 1) {
- /* Stop this command, don't print a result line, as there is a new command */
- return RESULT_SUCCESS;
- }
- fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-/* get option - really similar to the handle_streamfile, but with a timeout */
-static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int vres;
- struct ast_filestream *fs;
- struct ast_filestream *vfs;
- long sample_offset = 0;
- long max_length;
- int timeout = 0;
- char *edigits = "";
-
- if ( argc < 4 || argc > 5 )
- return RESULT_SHOWUSAGE;
-
- if ( argv[3] )
- edigits = argv[3];
-
- if ( argc == 5 )
- timeout = atoi(argv[4]);
- else if (chan->pbx->dtimeout) {
- /* by default dtimeout is set to 5sec */
- timeout = chan->pbx->dtimeout * 1000; /* in msec */
- }
-
- fs = ast_openstream(chan, argv[2], chan->language);
- if (!fs) {
- fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
- ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
- return RESULT_SUCCESS;
- }
- vfs = ast_openvstream(chan, argv[2], chan->language);
- if (vfs)
- ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
-
- ast_seekstream(fs, 0, SEEK_END);
- max_length = ast_tellstream(fs);
- ast_seekstream(fs, sample_offset, SEEK_SET);
- res = ast_applystream(chan, fs);
- if (vfs)
- vres = ast_applystream(chan, vfs);
- ast_playstream(fs);
- if (vfs)
- ast_playstream(vfs);
-
- res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
- /* this is to check for if ast_waitstream closed the stream, we probably are at
- * the end of the stream, return that amount, else check for the amount */
- sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
- ast_stopstream(chan);
- if (res == 1) {
- /* Stop this command, don't print a result line, as there is a new command */
- return RESULT_SUCCESS;
- }
-
- /* If the user didnt press a key, wait for digitTimeout*/
- if (res == 0 ) {
- res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
- /* Make sure the new result is in the escape digits of the GET OPTION */
- if ( !strchr(edigits,res) )
- res=0;
- }
-
- fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-
-
-
-/*--- handle_saynumber: Say number in various language syntaxes ---*/
-/* Need to add option for gender here as well. Coders wanted */
-/* While waiting, we're sending a (char *) NULL. */
-static int handle_saynumber(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int num;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[2], "%d", &num) != 1)
- return RESULT_SHOWUSAGE;
- res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl);
- if (res == 1)
- return RESULT_SUCCESS;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int num;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[2], "%d", &num) != 1)
- return RESULT_SHOWUSAGE;
-
- res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
- if (res == 1) /* New command */
- return RESULT_SUCCESS;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
- if (res == 1) /* New command */
- return RESULT_SUCCESS;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_saydate(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int num;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[2], "%d", &num) != 1)
- return RESULT_SHOWUSAGE;
- res = ast_say_date(chan, num, argv[3], chan->language);
- if (res == 1)
- return RESULT_SUCCESS;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- int num;
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[2], "%d", &num) != 1)
- return RESULT_SHOWUSAGE;
- res = ast_say_time(chan, num, argv[3], chan->language);
- if (res == 1)
- return RESULT_SUCCESS;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res=0;
- time_t unixtime;
- char *format, *zone=NULL;
-
- if (argc < 4)
- return RESULT_SHOWUSAGE;
-
- if (argc > 4) {
- format = argv[4];
- } else {
- /* XXX this doesn't belong here, but in the 'say' module */
- if (!strcasecmp(chan->language, "de")) {
- format = "A dBY HMS";
- } else {
- format = "ABdY 'digits/at' IMp";
- }
- }
-
- if (argc > 5 && !ast_strlen_zero(argv[5]))
- zone = argv[5];
-
- if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
- return RESULT_SHOWUSAGE;
-
- res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone);
- if (res == 1)
- return RESULT_SUCCESS;
-
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
-
- res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
- if (res == 1) /* New command */
- return RESULT_SUCCESS;
- fdprintf(agi->fd, "200 result=%d\n", res);
- return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
-}
-
-static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int res;
- char data[1024];
- int max;
- int timeout;
-
- if (argc < 3)
- return RESULT_SHOWUSAGE;
- if (argc >= 4)
- timeout = atoi(argv[3]);
- else
- timeout = 0;
- if (argc >= 5)
- max = atoi(argv[4]);
- else
- max = 1024;
- res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
- if (res == 2) /* New command */
- return RESULT_SUCCESS;
- else if (res == 1)
- fdprintf(agi->fd, "200 result=%s (timeout)\n", data);
- else if (res < 0 )
- fdprintf(agi->fd, "200 result=-1\n");
- else
- fdprintf(agi->fd, "200 result=%s\n", data);
- return RESULT_SUCCESS;
-}
-
-static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_copy_string(chan->context, argv[2], sizeof(chan->context));
- fdprintf(agi->fd, "200 result=0\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
- fdprintf(agi->fd, "200 result=0\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int pri;
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- if (sscanf(argv[2], "%d", &pri) != 1) {
- if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
- return RESULT_SHOWUSAGE;
- }
-
- ast_explicit_goto(chan, NULL, NULL, pri);
- fdprintf(agi->fd, "200 result=0\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- struct ast_filestream *fs;
- struct ast_frame *f;
- struct timeval start;
- long sample_offset = 0;
- int res = 0;
- int ms;
-
- struct ast_dsp *sildet=NULL; /* silence detector dsp */
- int totalsilence = 0;
- int dspsilence = 0;
- int silence = 0; /* amount of silence to allow */
- int gotsilence = 0; /* did we timeout for silence? */
- char *silencestr=NULL;
- int rfmt=0;
-
-
- /* XXX EAGI FIXME XXX */
-
- if (argc < 6)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[5], "%d", &ms) != 1)
- return RESULT_SHOWUSAGE;
-
- if (argc > 6)
- silencestr = strchr(argv[6],'s');
- if ((argc > 7) && (!silencestr))
- silencestr = strchr(argv[7],'s');
- if ((argc > 8) && (!silencestr))
- silencestr = strchr(argv[8],'s');
-
- if (silencestr) {
- if (strlen(silencestr) > 2) {
- if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
- silencestr++;
- silencestr++;
- if (silencestr)
- silence = atoi(silencestr);
- if (silence > 0)
- silence *= 1000;
- }
- }
- }
-
- if (silence > 0) {
- rfmt = chan->readformat;
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
- return -1;
- }
- sildet = ast_dsp_new();
- if (!sildet) {
- ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
- return -1;
- }
- ast_dsp_set_threshold(sildet, 256);
- }
-
- /* backward compatibility, if no offset given, arg[6] would have been
- * caught below and taken to be a beep, else if it is a digit then it is a
- * offset */
- if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
- res = ast_streamfile(chan, "beep", chan->language);
-
- if ((argc > 7) && (!strchr(argv[7], '=')))
- res = ast_streamfile(chan, "beep", chan->language);
-
- if (!res)
- res = ast_waitstream(chan, argv[4]);
- if (res) {
- fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
- } else {
- fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644);
- if (!fs) {
- res = -1;
- fdprintf(agi->fd, "200 result=%d (writefile)\n", res);
- if (sildet)
- ast_dsp_free(sildet);
- return RESULT_FAILURE;
- }
-
- /* Request a video update */
- ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-
- chan->stream = fs;
- ast_applystream(chan,fs);
- /* really should have checks */
- ast_seekstream(fs, sample_offset, SEEK_SET);
- ast_truncstream(fs);
-
- start = ast_tvnow();
- while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
- res = ast_waitfor(chan, -1);
- if (res < 0) {
- ast_closestream(fs);
- fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
- if (sildet)
- ast_dsp_free(sildet);
- return RESULT_FAILURE;
- }
- f = ast_read(chan);
- if (!f) {
- fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
- ast_closestream(fs);
- if (sildet)
- ast_dsp_free(sildet);
- return RESULT_FAILURE;
- }
- switch(f->frametype) {
- case AST_FRAME_DTMF:
- if (strchr(argv[4], f->subclass)) {
- /* This is an interrupting chracter, so rewind to chop off any small
- amount of DTMF that may have been recorded
- */
- ast_stream_rewind(fs, 200);
- ast_truncstream(fs);
- sample_offset = ast_tellstream(fs);
- fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset);
- ast_closestream(fs);
- ast_frfree(f);
- if (sildet)
- ast_dsp_free(sildet);
- return RESULT_SUCCESS;
- }
- break;
- case AST_FRAME_VOICE:
- ast_writestream(fs, f);
- /* this is a safe place to check progress since we know that fs
- * is valid after a write, and it will then have our current
- * location */
- sample_offset = ast_tellstream(fs);
- if (silence > 0) {
- dspsilence = 0;
- ast_dsp_silence(sildet, f, &dspsilence);
- if (dspsilence) {
- totalsilence = dspsilence;
- } else {
- totalsilence = 0;
- }
- if (totalsilence > silence) {
- /* Ended happily with silence */
- gotsilence = 1;
- break;
- }
- }
- break;
- case AST_FRAME_VIDEO:
- ast_writestream(fs, f);
- default:
- /* Ignore all other frames */
- break;
- }
- ast_frfree(f);
- if (gotsilence)
- break;
- }
-
- if (gotsilence) {
- ast_stream_rewind(fs, silence-1000);
- ast_truncstream(fs);
- sample_offset = ast_tellstream(fs);
- }
- fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
- ast_closestream(fs);
- }
-
- if (silence > 0) {
- res = ast_set_read_format(chan, rfmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
- ast_dsp_free(sildet);
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- int timeout;
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- if (sscanf(argv[2], "%d", &timeout) != 1)
- return RESULT_SHOWUSAGE;
- if (timeout < 0)
- timeout = 0;
- if (timeout)
- chan->whentohangup = time(NULL) + timeout;
- else
- chan->whentohangup = 0;
- fdprintf(agi->fd, "200 result=0\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- struct ast_channel *c;
- if (argc == 1) {
- /* no argument: hangup the current channel */
- ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
- fdprintf(agi->fd, "200 result=1\n");
- return RESULT_SUCCESS;
- } else if (argc == 2) {
- /* one argument: look for info on the specified channel */
- c = ast_get_channel_by_name_locked(argv[1]);
- if (c) {
- /* we have a matching channel */
- ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
- fdprintf(agi->fd, "200 result=1\n");
- ast_channel_unlock(c);
- return RESULT_SUCCESS;
- }
- /* if we get this far no channel name matched the argument given */
- fdprintf(agi->fd, "200 result=-1\n");
- return RESULT_SUCCESS;
- } else {
- return RESULT_SHOWUSAGE;
- }
-}
-
-static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int res;
- struct ast_app *app;
-
- if (argc < 2)
- return RESULT_SHOWUSAGE;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]);
-
- app = pbx_findapp(argv[1]);
-
- if (app) {
- res = pbx_exec(chan, app, argv[2]);
- } else {
- ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
- res = -2;
- }
- fdprintf(agi->fd, "200 result=%d\n", res);
-
- /* Even though this is wrong, users are depending upon this result. */
- return res;
-}
-
-static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- char tmp[256]="";
- char *l = NULL, *n = NULL;
-
- if (argv[2]) {
- ast_copy_string(tmp, argv[2], sizeof(tmp));
- ast_callerid_parse(tmp, &n, &l);
- if (l)
- ast_shrink_phone_number(l);
- else
- l = "";
- if (!n)
- n = "";
- ast_set_callerid(chan, l, n, NULL);
- }
-
- fdprintf(agi->fd, "200 result=1\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- struct ast_channel *c;
- if (argc == 2) {
- /* no argument: supply info on the current channel */
- fdprintf(agi->fd, "200 result=%d\n", chan->_state);
- return RESULT_SUCCESS;
- } else if (argc == 3) {
- /* one argument: look for info on the specified channel */
- c = ast_get_channel_by_name_locked(argv[2]);
- if (c) {
- fdprintf(agi->fd, "200 result=%d\n", c->_state);
- ast_channel_unlock(c);
- return RESULT_SUCCESS;
- }
- /* if we get this far no channel name matched the argument given */
- fdprintf(agi->fd, "200 result=-1\n");
- return RESULT_SUCCESS;
- } else {
- return RESULT_SHOWUSAGE;
- }
-}
-
-static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- if (argv[3])
- pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
-
- fdprintf(agi->fd, "200 result=1\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- char *ret;
- char tempstr[1024];
-
- if (argc != 3)
- return RESULT_SHOWUSAGE;
-
- /* check if we want to execute an ast_custom_function */
- if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
- ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
- } else {
- pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
- }
-
- if (ret)
- fdprintf(agi->fd, "200 result=1 (%s)\n", ret);
- else
- fdprintf(agi->fd, "200 result=0\n");
-
- return RESULT_SUCCESS;
-}
-
-static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- char tmp[4096] = "";
- struct ast_channel *chan2=NULL;
-
- if ((argc != 4) && (argc != 5))
- return RESULT_SHOWUSAGE;
- if (argc == 5) {
- chan2 = ast_get_channel_by_name_locked(argv[4]);
- } else {
- chan2 = chan;
- }
- if (chan2) {
- pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1);
- fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
- } else {
- fdprintf(agi->fd, "200 result=0\n");
- }
- if (chan2 && (chan2 != chan))
- ast_channel_unlock(chan2);
- return RESULT_SUCCESS;
-}
-
-static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int level = 0;
- char *prefix;
-
- if (argc < 2)
- return RESULT_SHOWUSAGE;
-
- if (argv[2])
- sscanf(argv[2], "%d", &level);
-
- switch (level) {
- case 4:
- prefix = VERBOSE_PREFIX_4;
- break;
- case 3:
- prefix = VERBOSE_PREFIX_3;
- break;
- case 2:
- prefix = VERBOSE_PREFIX_2;
- break;
- case 1:
- default:
- prefix = VERBOSE_PREFIX_1;
- break;
- }
-
- if (level <= option_verbose)
- ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]);
-
- fdprintf(agi->fd, "200 result=1\n");
-
- return RESULT_SUCCESS;
-}
-
-static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int res;
- char tmp[256];
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
- if (res)
- fdprintf(agi->fd, "200 result=0\n");
- else
- fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_dbput(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int res;
-
- if (argc != 5)
- return RESULT_SHOWUSAGE;
- res = ast_db_put(argv[2], argv[3], argv[4]);
- fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
- return RESULT_SUCCESS;
-}
-
-static int handle_dbdel(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int res;
-
- if (argc != 4)
- return RESULT_SHOWUSAGE;
- res = ast_db_del(argv[2], argv[3]);
- fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
- return RESULT_SUCCESS;
-}
-
-static int handle_dbdeltree(struct ast_channel *chan, AGI *agi, int argc, char **argv)
-{
- int res;
- if ((argc < 3) || (argc > 4))
- return RESULT_SHOWUSAGE;
- if (argc == 4)
- res = ast_db_deltree(argv[2], argv[3]);
- else
- res = ast_db_deltree(argv[2], NULL);
-
- fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
- return RESULT_SUCCESS;
-}
-
-static char debug_usage[] =
-"Usage: agi debug\n"
-" Enables dumping of AGI transactions for debugging purposes\n";
-
-static char no_debug_usage[] =
-"Usage: agi debug off\n"
-" Disables dumping of AGI transactions for debugging purposes\n";
-
-static int agi_do_debug(int fd, int argc, char *argv[])
-{
- if (argc != 2)
- return RESULT_SHOWUSAGE;
- agidebug = 1;
- ast_cli(fd, "AGI Debugging Enabled\n");
- return RESULT_SUCCESS;
-}
-
-static int agi_no_debug_deprecated(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- agidebug = 0;
- ast_cli(fd, "AGI Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int agi_no_debug(int fd, int argc, char *argv[])
-{
- if (argc != 3)
- return RESULT_SHOWUSAGE;
- agidebug = 0;
- ast_cli(fd, "AGI Debugging Disabled\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, char *argv[])
-{
- fdprintf(agi->fd, "200 result=0\n");
- return RESULT_SUCCESS;
-}
-
-static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
-{
- if (!strncasecmp(argv[2], "on", 2))
- ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
- else if (!strncasecmp(argv[2], "off", 3))
- ast_moh_stop(chan);
- fdprintf(agi->fd, "200 result=0\n");
- return RESULT_SUCCESS;
-}
-
-static char usage_setmusic[] =
-" Usage: SET MUSIC ON <on|off> <class>\n"
-" Enables/Disables the music on hold generator. If <class> is\n"
-" not specified, then the default music on hold class will be used.\n"
-" Always returns 0.\n";
-
-static char usage_dbput[] =
-" Usage: DATABASE PUT <family> <key> <value>\n"
-" Adds or updates an entry in the Asterisk database for a\n"
-" given family, key, and value.\n"
-" Returns 1 if successful, 0 otherwise.\n";
-
-static char usage_dbget[] =
-" Usage: DATABASE GET <family> <key>\n"
-" Retrieves an entry in the Asterisk database for a\n"
-" given family and key.\n"
-" Returns 0 if <key> is not set. Returns 1 if <key>\n"
-" is set and returns the variable in parentheses.\n"
-" Example return code: 200 result=1 (testvariable)\n";
-
-static char usage_dbdel[] =
-" Usage: DATABASE DEL <family> <key>\n"
-" Deletes an entry in the Asterisk database for a\n"
-" given family and key.\n"
-" Returns 1 if successful, 0 otherwise.\n";
-
-static char usage_dbdeltree[] =
-" Usage: DATABASE DELTREE <family> [keytree]\n"
-" Deletes a family or specific keytree within a family\n"
-" in the Asterisk database.\n"
-" Returns 1 if successful, 0 otherwise.\n";
-
-static char usage_verbose[] =
-" Usage: VERBOSE <message> <level>\n"
-" Sends <message> to the console via verbose message system.\n"
-" <level> is the the verbose level (1-4)\n"
-" Always returns 1.\n";
-
-static char usage_getvariable[] =
-" Usage: GET VARIABLE <variablename>\n"
-" Returns 0 if <variablename> is not set. Returns 1 if <variablename>\n"
-" is set and returns the variable in parentheses.\n"
-" example return code: 200 result=1 (testvariable)\n";
-
-static char usage_getvariablefull[] =
-" Usage: GET FULL VARIABLE <variablename> [<channel name>]\n"
-" Returns 0 if <variablename> is not set or channel does not exist. Returns 1\n"
-"if <variablename> is set and returns the variable in parenthesis. Understands\n"
-"complex variable names and builtin variables, unlike GET VARIABLE.\n"
-" example return code: 200 result=1 (testvariable)\n";
-
-static char usage_setvariable[] =
-" Usage: SET VARIABLE <variablename> <value>\n";
-
-static char usage_channelstatus[] =
-" Usage: CHANNEL STATUS [<channelname>]\n"
-" Returns the status of the specified channel.\n"
-" If no channel name is given the returns the status of the\n"
-" current channel. Return values:\n"
-" 0 Channel is down and available\n"
-" 1 Channel is down, but reserved\n"
-" 2 Channel is off hook\n"
-" 3 Digits (or equivalent) have been dialed\n"
-" 4 Line is ringing\n"
-" 5 Remote end is ringing\n"
-" 6 Line is up\n"
-" 7 Line is busy\n";
-
-static char usage_setcallerid[] =
-" Usage: SET CALLERID <number>\n"
-" Changes the callerid of the current channel.\n";
-
-static char usage_exec[] =
-" Usage: EXEC <application> <options>\n"
-" Executes <application> with given <options>.\n"
-" Returns whatever the application returns, or -2 on failure to find application\n";
-
-static char usage_hangup[] =
-" Usage: HANGUP [<channelname>]\n"
-" Hangs up the specified channel.\n"
-" If no channel name is given, hangs up the current channel\n";
-
-static char usage_answer[] =
-" Usage: ANSWER\n"
-" Answers channel if not already in answer state. Returns -1 on\n"
-" channel failure, or 0 if successful.\n";
-
-static char usage_waitfordigit[] =
-" Usage: WAIT FOR DIGIT <timeout>\n"
-" Waits up to 'timeout' milliseconds for channel to receive a DTMF digit.\n"
-" Returns -1 on channel failure, 0 if no digit is received in the timeout, or\n"
-" the numerical value of the ascii of the digit if one is received. Use -1\n"
-" for the timeout value if you desire the call to block indefinitely.\n";
-
-static char usage_sendtext[] =
-" Usage: SEND TEXT \"<text to send>\"\n"
-" Sends the given text on a channel. Most channels do not support the\n"
-" transmission of text. Returns 0 if text is sent, or if the channel does not\n"
-" support text transmission. Returns -1 only on error/hangup. Text\n"
-" consisting of greater than one word should be placed in quotes since the\n"
-" command only accepts a single argument.\n";
-
-static char usage_recvchar[] =
-" Usage: RECEIVE CHAR <timeout>\n"
-" Receives a character of text on a channel. Specify timeout to be the\n"
-" maximum time to wait for input in milliseconds, or 0 for infinite. Most channels\n"
-" do not support the reception of text. Returns the decimal value of the character\n"
-" if one is received, or 0 if the channel does not support text reception. Returns\n"
-" -1 only on error/hangup.\n";
-
-static char usage_recvtext[] =
-" Usage: RECEIVE TEXT <timeout>\n"
-" Receives a string of text on a channel. Specify timeout to be the\n"
-" maximum time to wait for input in milliseconds, or 0 for infinite. Most channels\n"
-" do not support the reception of text. Returns -1 for failure or 1 for success, and the string in parentheses.\n";
-
-static char usage_tddmode[] =
-" Usage: TDD MODE <on|off>\n"
-" Enable/Disable TDD transmission/reception on a channel. Returns 1 if\n"
-" successful, or 0 if channel is not TDD-capable.\n";
-
-static char usage_sendimage[] =
-" Usage: SEND IMAGE <image>\n"
-" Sends the given image on a channel. Most channels do not support the\n"
-" transmission of images. Returns 0 if image is sent, or if the channel does not\n"
-" support image transmission. Returns -1 only on error/hangup. Image names\n"
-" should not include extensions.\n";
-
-static char usage_streamfile[] =
-" Usage: STREAM FILE <filename> <escape digits> [sample offset]\n"
-" Send the given file, allowing playback to be interrupted by the given\n"
-" digits, if any. Use double quotes for the digits if you wish none to be\n"
-" permitted. If sample offset is provided then the audio will seek to sample\n"
-" offset before play starts. Returns 0 if playback completes without a digit\n"
-" being pressed, or the ASCII numerical value of the digit if one was pressed,\n"
-" or -1 on error or if the channel was disconnected. Remember, the file\n"
-" extension must not be included in the filename.\n";
-
-static char usage_controlstreamfile[] =
-" Usage: CONTROL STREAM FILE <filename> <escape digits> [skipms] [ffchar] [rewchr] [pausechr]\n"
-" Send the given file, allowing playback to be controled by the given\n"
-" digits, if any. Use double quotes for the digits if you wish none to be\n"
-" permitted. Returns 0 if playback completes without a digit\n"
-" being pressed, or the ASCII numerical value of the digit if one was pressed,\n"
-" or -1 on error or if the channel was disconnected. Remember, the file\n"
-" extension must not be included in the filename.\n\n"
-" Note: ffchar and rewchar default to * and # respectively.\n";
-
-static char usage_getoption[] =
-" Usage: GET OPTION <filename> <escape_digits> [timeout]\n"
-" Behaves similar to STREAM FILE but used with a timeout option.\n";
-
-static char usage_saynumber[] =
-" Usage: SAY NUMBER <number> <escape digits>\n"
-" Say a given number, returning early if any of the given DTMF digits\n"
-" are received on the channel. Returns 0 if playback completes without a digit\n"
-" being pressed, or the ASCII numerical value of the digit if one was pressed or\n"
-" -1 on error/hangup.\n";
-
-static char usage_saydigits[] =
-" Usage: SAY DIGITS <number> <escape digits>\n"
-" Say a given digit string, returning early if any of the given DTMF digits\n"
-" are received on the channel. Returns 0 if playback completes without a digit\n"
-" being pressed, or the ASCII numerical value of the digit if one was pressed or\n"
-" -1 on error/hangup.\n";
-
-static char usage_sayalpha[] =
-" Usage: SAY ALPHA <number> <escape digits>\n"
-" Say a given character string, returning early if any of the given DTMF digits\n"
-" are received on the channel. Returns 0 if playback completes without a digit\n"
-" being pressed, or the ASCII numerical value of the digit if one was pressed or\n"
-" -1 on error/hangup.\n";
-
-static char usage_saydate[] =
-" Usage: SAY DATE <date> <escape digits>\n"
-" Say a given date, returning early if any of the given DTMF digits are\n"
-" received on the channel. <date> is number of seconds elapsed since 00:00:00\n"
-" on January 1, 1970, Coordinated Universal Time (UTC). Returns 0 if playback\n"
-" completes without a digit being pressed, or the ASCII numerical value of the\n"
-" digit if one was pressed or -1 on error/hangup.\n";
-
-static char usage_saytime[] =
-" Usage: SAY TIME <time> <escape digits>\n"
-" Say a given time, returning early if any of the given DTMF digits are\n"
-" received on the channel. <time> is number of seconds elapsed since 00:00:00\n"
-" on January 1, 1970, Coordinated Universal Time (UTC). Returns 0 if playback\n"
-" completes without a digit being pressed, or the ASCII numerical value of the\n"
-" digit if one was pressed or -1 on error/hangup.\n";
-
-static char usage_saydatetime[] =
-" Usage: SAY DATETIME <time> <escape digits> [format] [timezone]\n"
-" Say a given time, returning early if any of the given DTMF digits are\n"
-" received on the channel. <time> is number of seconds elapsed since 00:00:00\n"
-" on January 1, 1970, Coordinated Universal Time (UTC). [format] is the format\n"
-" the time should be said in. See voicemail.conf (defaults to \"ABdY\n"
-" 'digits/at' IMp\"). Acceptable values for [timezone] can be found in\n"
-" /usr/share/zoneinfo. Defaults to machine default. Returns 0 if playback\n"
-" completes without a digit being pressed, or the ASCII numerical value of the\n"
-" digit if one was pressed or -1 on error/hangup.\n";
-
-static char usage_sayphonetic[] =
-" Usage: SAY PHONETIC <string> <escape digits>\n"
-" Say a given character string with phonetics, returning early if any of the\n"
-" given DTMF digits are received on the channel. Returns 0 if playback\n"
-" completes without a digit pressed, the ASCII numerical value of the digit\n"
-" if one was pressed, or -1 on error/hangup.\n";
-
-static char usage_getdata[] =
-" Usage: GET DATA <file to be streamed> [timeout] [max digits]\n"
-" Stream the given file, and recieve DTMF data. Returns the digits received\n"
-"from the channel at the other end.\n";
-
-static char usage_setcontext[] =
-" Usage: SET CONTEXT <desired context>\n"
-" Sets the context for continuation upon exiting the application.\n";
-
-static char usage_setextension[] =
-" Usage: SET EXTENSION <new extension>\n"
-" Changes the extension for continuation upon exiting the application.\n";
-
-static char usage_setpriority[] =
-" Usage: SET PRIORITY <priority>\n"
-" Changes the priority for continuation upon exiting the application.\n"
-" The priority must be a valid priority or label.\n";
-
-static char usage_recordfile[] =
-" Usage: RECORD FILE <filename> <format> <escape digits> <timeout> \\\n"
-" [offset samples] [BEEP] [s=silence]\n"
-" Record to a file until a given dtmf digit in the sequence is received\n"
-" Returns -1 on hangup or error. The format will specify what kind of file\n"
-" will be recorded. The timeout is the maximum record time in milliseconds, or\n"
-" -1 for no timeout. \"Offset samples\" is optional, and, if provided, will seek\n"
-" to the offset without exceeding the end of the file. \"silence\" is the number\n"
-" of seconds of silence allowed before the function returns despite the\n"
-" lack of dtmf digits or reaching timeout. Silence value must be\n"
-" preceeded by \"s=\" and is also optional.\n";
-
-static char usage_autohangup[] =
-" Usage: SET AUTOHANGUP <time>\n"
-" Cause the channel to automatically hangup at <time> seconds in the\n"
-" future. Of course it can be hungup before then as well. Setting to 0 will\n"
-" cause the autohangup feature to be disabled on this channel.\n";
-
-static char usage_noop[] =
-" Usage: NoOp\n"
-" Does nothing.\n";
-
-static agi_command commands[MAX_COMMANDS] = {
- { { "answer", NULL }, handle_answer, "Answer channel", usage_answer },
- { { "channel", "status", NULL }, handle_channelstatus, "Returns status of the connected channel", usage_channelstatus },
- { { "database", "del", NULL }, handle_dbdel, "Removes database key/value", usage_dbdel },
- { { "database", "deltree", NULL }, handle_dbdeltree, "Removes database keytree/value", usage_dbdeltree },
- { { "database", "get", NULL }, handle_dbget, "Gets database value", usage_dbget },
- { { "database", "put", NULL }, handle_dbput, "Adds/updates database value", usage_dbput },
- { { "exec", NULL }, handle_exec, "Executes a given Application", usage_exec },
- { { "get", "data", NULL }, handle_getdata, "Prompts for DTMF on a channel", usage_getdata },
- { { "get", "full", "variable", NULL }, handle_getvariablefull, "Evaluates a channel expression", usage_getvariablefull },
- { { "get", "option", NULL }, handle_getoption, "Stream file, prompt for DTMF, with timeout", usage_getoption },
- { { "get", "variable", NULL }, handle_getvariable, "Gets a channel variable", usage_getvariable },
- { { "hangup", NULL }, handle_hangup, "Hangup the current channel", usage_hangup },
- { { "noop", NULL }, handle_noop, "Does nothing", usage_noop },
- { { "receive", "char", NULL }, handle_recvchar, "Receives one character from channels supporting it", usage_recvchar },
- { { "receive", "text", NULL }, handle_recvtext, "Receives text from channels supporting it", usage_recvtext },
- { { "record", "file", NULL }, handle_recordfile, "Records to a given file", usage_recordfile },
- { { "say", "alpha", NULL }, handle_sayalpha, "Says a given character string", usage_sayalpha },
- { { "say", "digits", NULL }, handle_saydigits, "Says a given digit string", usage_saydigits },
- { { "say", "number", NULL }, handle_saynumber, "Says a given number", usage_saynumber },
- { { "say", "phonetic", NULL }, handle_sayphonetic, "Says a given character string with phonetics", usage_sayphonetic },
- { { "say", "date", NULL }, handle_saydate, "Says a given date", usage_saydate },
- { { "say", "time", NULL }, handle_saytime, "Says a given time", usage_saytime },
- { { "say", "datetime", NULL }, handle_saydatetime, "Says a given time as specfied by the format given", usage_saydatetime },
- { { "send", "image", NULL }, handle_sendimage, "Sends images to channels supporting it", usage_sendimage },
- { { "send", "text", NULL }, handle_sendtext, "Sends text to channels supporting it", usage_sendtext },
- { { "set", "autohangup", NULL }, handle_autohangup, "Autohangup channel in some time", usage_autohangup },
- { { "set", "callerid", NULL }, handle_setcallerid, "Sets callerid for the current channel", usage_setcallerid },
- { { "set", "context", NULL }, handle_setcontext, "Sets channel context", usage_setcontext },
- { { "set", "extension", NULL }, handle_setextension, "Changes channel extension", usage_setextension },
- { { "set", "music", NULL }, handle_setmusic, "Enable/Disable Music on hold generator", usage_setmusic },
- { { "set", "priority", NULL }, handle_setpriority, "Set channel dialplan priority", usage_setpriority },
- { { "set", "variable", NULL }, handle_setvariable, "Sets a channel variable", usage_setvariable },
- { { "stream", "file", NULL }, handle_streamfile, "Sends audio file on channel", usage_streamfile },
- { { "control", "stream", "file", NULL }, handle_controlstreamfile, "Sends audio file on channel and allows the listner to control the stream", usage_controlstreamfile },
- { { "tdd", "mode", NULL }, handle_tddmode, "Toggles TDD mode (for the deaf)", usage_tddmode },
- { { "verbose", NULL }, handle_verbose, "Logs a message to the asterisk verbose log", usage_verbose },
- { { "wait", "for", "digit", NULL }, handle_waitfordigit, "Waits for a digit to be pressed", usage_waitfordigit },
-};
-
-static int help_workhorse(int fd, char *match[])
-{
- char fullcmd[80];
- char matchstr[80];
- int x;
- struct agi_command *e;
- if (match)
- ast_join(matchstr, sizeof(matchstr), match);
- for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
- e = &commands[x];
- if (!e->cmda[0])
- break;
- /* Hide commands that start with '_' */
- if ((e->cmda[0])[0] == '_')
- continue;
- ast_join(fullcmd, sizeof(fullcmd), e->cmda);
- if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr)))
- continue;
- ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary);
- }
- return 0;
-}
-
-int ast_agi_register(agi_command *agi)
-{
- int x;
- for (x=0; x<MAX_COMMANDS - 1; x++) {
- if (commands[x].cmda[0] == agi->cmda[0]) {
- ast_log(LOG_WARNING, "Command already registered!\n");
- return -1;
- }
- }
- for (x=0; x<MAX_COMMANDS - 1; x++) {
- if (!commands[x].cmda[0]) {
- commands[x] = *agi;
- return 0;
- }
- }
- ast_log(LOG_WARNING, "No more room for new commands!\n");
- return -1;
-}
-
-void ast_agi_unregister(agi_command *agi)
-{
- int x;
- for (x=0; x<MAX_COMMANDS - 1; x++) {
- if (commands[x].cmda[0] == agi->cmda[0]) {
- memset(&commands[x], 0, sizeof(agi_command));
- }
- }
-}
-
-static agi_command *find_command(char *cmds[], int exact)
-{
- int x;
- int y;
- int match;
-
- for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) {
- if (!commands[x].cmda[0])
- break;
- /* start optimistic */
- match = 1;
- for (y=0; match && cmds[y]; y++) {
- /* If there are no more words in the command (and we're looking for
- an exact match) or there is a difference between the two words,
- then this is not a match */
- if (!commands[x].cmda[y] && !exact)
- break;
- /* don't segfault if the next part of a command doesn't exist */
- if (!commands[x].cmda[y])
- return NULL;
- if (strcasecmp(commands[x].cmda[y], cmds[y]))
- match = 0;
- }
- /* If more words are needed to complete the command then this is not
- a candidate (unless we're looking for a really inexact answer */
- if ((exact > -1) && commands[x].cmda[y])
- match = 0;
- if (match)
- return &commands[x];
- }
- return NULL;
-}
-
-
-static int parse_args(char *s, int *max, char *argv[])
-{
- int x=0;
- int quoted=0;
- int escaped=0;
- int whitespace=1;
- char *cur;
-
- cur = s;
- while(*s) {
- switch(*s) {
- case '"':
- /* If it's escaped, put a literal quote */
- if (escaped)
- goto normal;
- else
- quoted = !quoted;
- if (quoted && whitespace) {
- /* If we're starting a quote, coming off white space start a new word, too */
- argv[x++] = cur;
- whitespace=0;
- }
- escaped = 0;
- break;
- case ' ':
- case '\t':
- if (!quoted && !escaped) {
- /* If we're not quoted, mark this as whitespace, and
- end the previous argument */
- whitespace = 1;
- *(cur++) = '\0';
- } else
- /* Otherwise, just treat it as anything else */
- goto normal;
- break;
- case '\\':
- /* If we're escaped, print a literal, otherwise enable escaping */
- if (escaped) {
- goto normal;
- } else {
- escaped=1;
- }
- break;
- default:
-normal:
- if (whitespace) {
- if (x >= MAX_ARGS -1) {
- ast_log(LOG_WARNING, "Too many arguments, truncating\n");
- break;
- }
- /* Coming off of whitespace, start the next argument */
- argv[x++] = cur;
- whitespace=0;
- }
- *(cur++) = *s;
- escaped=0;
- }
- s++;
- }
- /* Null terminate */
- *(cur++) = '\0';
- argv[x] = NULL;
- *max = x;
- return 0;
-}
-
-static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf)
-{
- char *argv[MAX_ARGS];
- int argc = MAX_ARGS;
- int res;
- agi_command *c;
-
- parse_args(buf, &argc, argv);
- c = find_command(argv, 0);
- if (c) {
- res = c->handler(chan, agi, argc, argv);
- switch(res) {
- case RESULT_SHOWUSAGE:
- fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n");
- fdprintf(agi->fd, c->usage);
- fdprintf(agi->fd, "520 End of proper usage.\n");
- break;
- case AST_PBX_KEEPALIVE:
- /* We've been asked to keep alive, so do so */
- return AST_PBX_KEEPALIVE;
- break;
- case RESULT_FAILURE:
- /* They've already given the failure. We've been hung up on so handle this
- appropriately */
- return -1;
- }
- } else {
- fdprintf(agi->fd, "510 Invalid or unknown command\n");
- }
- return 0;
-}
-static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead)
-{
- struct ast_channel *c;
- int outfd;
- int ms;
- enum agi_result returnstatus = AGI_RESULT_SUCCESS;
- struct ast_frame *f;
- char buf[AGI_BUF_LEN];
- char *res = NULL;
- FILE *readf;
- /* how many times we'll retry if ast_waitfor_nandfs will return without either
- channel or file descriptor in case select is interrupted by a system call (EINTR) */
- int retry = AGI_NANDFS_RETRY;
-
- if (!(readf = fdopen(agi->ctrl, "r"))) {
- ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n");
- if (pid > -1)
- kill(pid, SIGHUP);
- close(agi->ctrl);
- return AGI_RESULT_FAILURE;
- }
- setlinebuf(readf);
- setup_env(chan, request, agi->fd, (agi->audio > -1));
- for (;;) {
- ms = -1;
- c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
- if (c) {
- retry = AGI_NANDFS_RETRY;
- /* Idle the channel until we get a command */
- f = ast_read(c);
- if (!f) {
- ast_log(LOG_DEBUG, "%s hungup\n", chan->name);
- returnstatus = AGI_RESULT_HANGUP;
- break;
- } else {
- /* If it's voice, write it to the audio pipe */
- if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) {
- /* Write, ignoring errors */
- write(agi->audio, f->data, f->datalen);
- }
- ast_frfree(f);
- }
- } else if (outfd > -1) {
- size_t len = sizeof(buf);
- size_t buflen = 0;
-
- retry = AGI_NANDFS_RETRY;
- buf[0] = '\0';
-
- while (buflen < (len - 1)) {
- res = fgets(buf + buflen, len, readf);
- if (feof(readf))
- break;
- if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN)))
- break;
- if (res != NULL && !agi->fast)
- break;
- buflen = strlen(buf);
- if (buflen && buf[buflen - 1] == '\n')
- break;
- len -= buflen;
- if (agidebug)
- ast_verbose( "AGI Rx << temp buffer %s - errno %s\n", buf, strerror(errno));
- }
-
- if (!buf[0]) {
- /* Program terminated */
- if (returnstatus)
- returnstatus = -1;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus);
- if (pid > 0)
- waitpid(pid, status, 0);
- /* No need to kill the pid anymore, since they closed us */
- pid = -1;
- break;
- }
-
- /* Special case for inability to execute child process */
- if (*buf && strncasecmp(buf, "failure", 7) == 0) {
- returnstatus = AGI_RESULT_FAILURE;
- break;
- }
-
- /* get rid of trailing newline, if any */
- if (*buf && buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = 0;
- if (agidebug)
- ast_verbose("AGI Rx << %s\n", buf);
- returnstatus |= agi_handle_command(chan, agi, buf);
- /* If the handle_command returns -1, we need to stop */
- if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
- break;
- }
- } else {
- if (--retry <= 0) {
- ast_log(LOG_WARNING, "No channel, no fd?\n");
- returnstatus = AGI_RESULT_FAILURE;
- break;
- }
- }
- }
- /* Notify process */
- if (pid > -1) {
- const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
- if (ast_strlen_zero(sighup) || !ast_false(sighup)) {
- if (kill(pid, SIGHUP))
- ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno));
- }
- }
- fclose(readf);
- return returnstatus;
-}
-
-static int handle_showagi(int fd, int argc, char *argv[])
-{
- struct agi_command *e;
- char fullcmd[80];
- if ((argc < 2))
- return RESULT_SHOWUSAGE;
- if (argc > 2) {
- e = find_command(argv + 2, 1);
- if (e)
- ast_cli(fd, e->usage);
- else {
- if (find_command(argv + 2, -1)) {
- return help_workhorse(fd, argv + 1);
- } else {
- ast_join(fullcmd, sizeof(fullcmd), argv+1);
- ast_cli(fd, "No such command '%s'.\n", fullcmd);
- }
- }
- } else {
- return help_workhorse(fd, NULL);
- }
- return RESULT_SUCCESS;
-}
-
-static int handle_agidumphtml(int fd, int argc, char *argv[])
-{
- struct agi_command *e;
- char fullcmd[80];
- int x;
- FILE *htmlfile;
-
- if ((argc < 3))
- return RESULT_SHOWUSAGE;
-
- if (!(htmlfile = fopen(argv[2], "wt"))) {
- ast_cli(fd, "Could not create file '%s'\n", argv[2]);
- return RESULT_SHOWUSAGE;
- }
-
- fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n");
- fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n");
-
-
- fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n");
-
- for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
- char *stringp, *tempstr;
-
- e = &commands[x];
- if (!e->cmda[0]) /* end ? */
- break;
- /* Hide commands that start with '_' */
- if ((e->cmda[0])[0] == '_')
- continue;
- ast_join(fullcmd, sizeof(fullcmd), e->cmda);
-
- fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n");
- fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TH></TR>\n", fullcmd,e->summary);
-
- stringp=e->usage;
- tempstr = strsep(&stringp, "\n");
-
- fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr);
-
- fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n");
- while ((tempstr = strsep(&stringp, "\n")) != NULL)
- fprintf(htmlfile, "%s<BR>\n",tempstr);
- fprintf(htmlfile, "</TD></TR>\n");
- fprintf(htmlfile, "</TABLE></TD></TR>\n\n");
-
- }
-
- fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n");
- fclose(htmlfile);
- ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]);
- return RESULT_SUCCESS;
-}
-
-static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int dead)
-{
- enum agi_result res;
- struct ast_module_user *u;
- char *argv[MAX_ARGS];
- char buf[AGI_BUF_LEN] = "";
- char *tmp = (char *)buf;
- int argc = 0;
- int fds[2];
- int efd = -1;
- int pid;
- char *stringp;
- AGI agi;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "AGI requires an argument (script)\n");
- return -1;
- }
- ast_copy_string(buf, data, sizeof(buf));
-
- memset(&agi, 0, sizeof(agi));
- while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1)
- argv[argc++] = stringp;
- argv[argc] = NULL;
-
- u = ast_module_user_add(chan);
-#if 0
- /* Answer if need be */
- if (chan->_state != AST_STATE_UP) {
- if (ast_answer(chan)) {
- LOCAL_USER_REMOVE(u);
- return -1;
- }
- }
-#endif
- ast_replace_sigchld();
- res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid);
- if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) {
- int status = 0;
- agi.fd = fds[1];
- agi.ctrl = fds[0];
- agi.audio = efd;
- agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0;
- res = run_agi(chan, argv[0], &agi, pid, &status, dead);
- /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */
- if ((res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) && status)
- res = AGI_RESULT_FAILURE;
- if (fds[1] != fds[0])
- close(fds[1]);
- if (efd > -1)
- close(efd);
- }
- ast_unreplace_sigchld();
- ast_module_user_remove(u);
-
- switch (res) {
- case AGI_RESULT_SUCCESS:
- case AGI_RESULT_SUCCESS_FAST:
- pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS");
- break;
- case AGI_RESULT_FAILURE:
- pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE");
- break;
- case AGI_RESULT_HANGUP:
- pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP");
- return -1;
- }
-
- return 0;
-}
-
-static int agi_exec(struct ast_channel *chan, void *data)
-{
- if (chan->_softhangup)
- ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
- return agi_exec_full(chan, data, 0, 0);
-}
-
-static int eagi_exec(struct ast_channel *chan, void *data)
-{
- int readformat;
- int res;
-
- if (chan->_softhangup)
- ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
- readformat = chan->readformat;
- if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
- ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
- return -1;
- }
- res = agi_exec_full(chan, data, 1, 0);
- if (!res) {
- if (ast_set_read_format(chan, readformat)) {
- ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
- }
- }
- return res;
-}
-
-static int deadagi_exec(struct ast_channel *chan, void *data)
-{
- if (!ast_check_hangup(chan))
- ast_log(LOG_WARNING,"Running DeadAGI on a live channel will cause problems, please use AGI\n");
- return agi_exec_full(chan, data, 0, 1);
-}
-
-static char showagi_help[] =
-"Usage: agi show [topic]\n"
-" When called with a topic as an argument, displays usage\n"
-" information on the given command. If called without a\n"
-" topic, it provides a list of AGI commands.\n";
-
-
-static char dumpagihtml_help[] =
-"Usage: agi dumphtml <filename>\n"
-" Dumps the agi command list in html format to given filename\n";
-
-static struct ast_cli_entry cli_show_agi_deprecated = {
- { "show", "agi", NULL },
- handle_showagi, NULL,
- NULL };
-
-static struct ast_cli_entry cli_dump_agihtml_deprecated = {
- { "dump", "agihtml", NULL },
- handle_agidumphtml, NULL,
- NULL };
-
-static struct ast_cli_entry cli_agi_no_debug_deprecated = {
- { "agi", "no", "debug", NULL },
- agi_no_debug_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_agi[] = {
- { { "agi", "debug", NULL },
- agi_do_debug, "Enable AGI debugging",
- debug_usage },
-
- { { "agi", "debug", "off", NULL },
- agi_no_debug, "Disable AGI debugging",
- no_debug_usage, NULL, &cli_agi_no_debug_deprecated },
-
- { { "agi", "show", NULL },
- handle_showagi, "List AGI commands or specific help",
- showagi_help, NULL, &cli_show_agi_deprecated },
-
- { { "agi", "dumphtml", NULL },
- handle_agidumphtml, "Dumps a list of agi commands in html format",
- dumpagihtml_help, NULL, &cli_dump_agihtml_deprecated },
-};
-
-static int unload_module(void)
-{
- ast_module_user_hangup_all();
- ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry));
- ast_unregister_application(eapp);
- ast_unregister_application(deadapp);
- return ast_unregister_application(app);
-}
-
-static int load_module(void)
-{
- ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry));
- ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip);
- ast_register_application(eapp, eagi_exec, esynopsis, descrip);
- return ast_register_application(app, agi_exec, synopsis, descrip);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Asterisk Gateway Interface (AGI)",
- .load = load_module,
- .unload = unload_module,
- );
diff --git a/1.4/res/res_clioriginate.c b/1.4/res/res_clioriginate.c
deleted file mode 100644
index f272d79e8..000000000
--- a/1.4/res/res_clioriginate.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005 - 2006, Digium, Inc.
- *
- * Russell Bryant <russell@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.
- */
-
-/*!
- * \file
- * \author Russell Bryant <russell@digium.com>
- *
- * \brief Originate calls via the CLI
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-#include "asterisk/cli.h"
-#include "asterisk/utils.h"
-#include "asterisk/frame.h"
-
-/*! The timeout for originated calls, in seconds */
-#define TIMEOUT 30
-
-static char orig_help[] =
-" There are two ways to use this command. A call can be originated between a\n"
-"channel and a specific application, or between a channel and an extension in\n"
-"the dialplan. This is similar to call files or the manager originate action.\n"
-"Calls originated with this command are given a timeout of 30 seconds.\n\n"
-
-"Usage1: originate <tech/data> application <appname> [appdata]\n"
-" This will originate a call between the specified channel tech/data and the\n"
-"given application. Arguments to the application are optional. If the given\n"
-"arguments to the application include spaces, all of the arguments to the\n"
-"application need to be placed in quotation marks.\n\n"
-
-"Usage2: originate <tech/data> extension [exten@][context]\n"
-" This will originate a call between the specified channel tech/data and the\n"
-"given extension. If no context is specified, the 'default' context will be\n"
-"used. If no extension is given, the 's' extension will be used.\n";
-
-static int handle_orig(int fd, int argc, char *argv[]);
-static char *complete_orig(const char *line, const char *word, int pos, int state);
-
-struct ast_cli_entry cli_cliorig[] = {
- { { "originate", NULL },
- handle_orig, "Originate a call",
- orig_help, complete_orig },
-};
-
-static int orig_app(int fd, const char *chan, const char *app, const char *appdata)
-{
- char *chantech;
- char *chandata;
- int reason = 0;
-
- if (ast_strlen_zero(app))
- return RESULT_SHOWUSAGE;
-
- chandata = ast_strdupa(chan);
-
- chantech = strsep(&chandata, "/");
- if (!chandata) {
- ast_cli(fd, "*** No data provided after channel type! ***\n");
- return RESULT_SHOWUSAGE;
- }
-
- ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL);
-
- return RESULT_SUCCESS;
-}
-
-static int orig_exten(int fd, const char *chan, const char *data)
-{
- char *chantech;
- char *chandata;
- char *exten = NULL;
- char *context = NULL;
- int reason = 0;
-
- chandata = ast_strdupa(chan);
-
- chantech = strsep(&chandata, "/");
- if (!chandata) {
- ast_cli(fd, "*** No data provided after channel type! ***\n");
- return RESULT_SHOWUSAGE;
- }
-
- if (!ast_strlen_zero(data)) {
- context = ast_strdupa(data);
- exten = strsep(&context, "@");
- }
-
- if (ast_strlen_zero(exten))
- exten = "s";
- if (ast_strlen_zero(context))
- context = "default";
-
- ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL);
-
- return RESULT_SUCCESS;
-}
-
-static int handle_orig(int fd, int argc, char *argv[])
-{
- int res;
-
- if (ast_strlen_zero(argv[1]) || ast_strlen_zero(argv[2]))
- return RESULT_SHOWUSAGE;
-
- /* ugly, can be removed when CLI entries have ast_module pointers */
- ast_module_ref(ast_module_info->self);
-
- if (!strcasecmp("application", argv[2])) {
- res = orig_app(fd, argv[1], argv[3], argv[4]);
- } else if (!strcasecmp("extension", argv[2])) {
- res = orig_exten(fd, argv[1], argv[3]);
- } else
- res = RESULT_SHOWUSAGE;
-
- ast_module_unref(ast_module_info->self);
-
- return res;
-}
-
-static char *complete_orig(const char *line, const char *word, int pos, int state)
-{
- static char *choices[] = { "application", "extension", NULL };
- char *ret;
-
- if (pos != 2)
- return NULL;
-
- /* ugly, can be removed when CLI entries have ast_module pointers */
- ast_module_ref(ast_module_info->self);
- ret = ast_cli_complete(word, choices, state);
- ast_module_unref(ast_module_info->self);
-
- return ret;
-}
-
-static int unload_module(void)
-{
- ast_cli_unregister_multiple(cli_cliorig, sizeof(cli_cliorig) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-static int load_module(void)
-{
- ast_cli_register_multiple(cli_cliorig, sizeof(cli_cliorig) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call origination from the CLI");
diff --git a/1.4/res/res_config_odbc.c b/1.4/res/res_config_odbc.c
deleted file mode 100644
index af85f0a6a..000000000
--- a/1.4/res/res_config_odbc.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Copyright (C) 2004 - 2005 Anthony Minessale II <anthmct@yahoo.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.
- */
-
-/*! \file
- *
- * \brief odbc+odbc plugin for portable configuration engine
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Anthony Minessale II <anthmct@yahoo.com>
- *
- * \arg http://www.unixodbc.org
- */
-
-/*** MODULEINFO
- <depend>unixodbc</depend>
- <depend>ltdl</depend>
- <depend>res_odbc</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-#include "asterisk/res_odbc.h"
-#include "asterisk/utils.h"
-
-struct custom_prepare_struct {
- const char *sql;
- const char *extra;
- va_list ap;
-};
-
-static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data)
-{
- int res, x = 1;
- struct custom_prepare_struct *cps = data;
- const char *newparam, *newval;
- SQLHSTMT stmt;
- va_list ap;
-
- va_copy(ap, cps->ap);
-
- res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
- return NULL;
- }
-
- res = SQLPrepare(stmt, (unsigned char *)cps->sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", cps->sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- return NULL;
- }
-
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
- SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL);
- }
- va_end(ap);
-
- if (!ast_strlen_zero(cps->extra))
- SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(cps->extra), 0, (void *)cps->extra, 0, NULL);
- return stmt;
-}
-
-static struct ast_variable *realtime_odbc(const char *database, const char *table, va_list ap)
-{
- struct odbc_obj *obj;
- SQLHSTMT stmt;
- char sql[1024];
- char coltitle[256];
- char rowdata[2048];
- char *op;
- const char *newparam, *newval;
- char *stringp;
- char *chunk;
- SQLSMALLINT collen;
- int res;
- int x;
- struct ast_variable *var=NULL, *prev=NULL;
- SQLULEN colsize;
- SQLSMALLINT colcount=0;
- SQLSMALLINT datatype;
- SQLSMALLINT decimaldigits;
- SQLSMALLINT nullable;
- SQLLEN indicator;
- va_list aq;
- struct custom_prepare_struct cps = { .sql = sql };
-
- va_copy(cps.ap, ap);
- va_copy(aq, ap);
-
- if (!table)
- return NULL;
-
- obj = ast_odbc_request_obj(database, 0);
-
- if (!obj) {
- ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", database);
- return NULL;
- }
-
- newparam = va_arg(aq, const char *);
- if (!newparam)
- return NULL;
- newval = va_arg(aq, const char *);
- op = !strchr(newparam, ' ') ? " =" : "";
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, newparam, op,
- strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
- while((newparam = va_arg(aq, const char *))) {
- op = !strchr(newparam, ' ') ? " =" : "";
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op,
- strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
- newval = va_arg(aq, const char *);
- }
- va_end(aq);
-
- stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
-
- if (!stmt) {
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- res = SQLNumResultCols(stmt, &colcount);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- res = SQLFetch(stmt);
- if (res == SQL_NO_DATA) {
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
- for (x = 0; x < colcount; x++) {
- rowdata[0] = '\0';
- collen = sizeof(coltitle);
- res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen,
- &datatype, &colsize, &decimaldigits, &nullable);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
- if (var)
- ast_variables_destroy(var);
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- indicator = 0;
- res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator);
- if (indicator == SQL_NULL_DATA)
- continue;
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- if (var)
- ast_variables_destroy(var);
- ast_odbc_release_obj(obj);
- return NULL;
- }
- stringp = rowdata;
- while(stringp) {
- chunk = strsep(&stringp, ";");
- if (!ast_strlen_zero(ast_strip(chunk))) {
- if (prev) {
- prev->next = ast_variable_new(coltitle, chunk);
- if (prev->next)
- prev = prev->next;
- } else
- prev = var = ast_variable_new(coltitle, chunk);
- }
- }
- }
-
-
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return var;
-}
-
-static struct ast_config *realtime_multi_odbc(const char *database, const char *table, va_list ap)
-{
- struct odbc_obj *obj;
- SQLHSTMT stmt;
- char sql[1024];
- char coltitle[256];
- char rowdata[2048];
- const char *initfield=NULL;
- char *op;
- const char *newparam, *newval;
- char *stringp;
- char *chunk;
- SQLSMALLINT collen;
- int res;
- int x;
- struct ast_variable *var=NULL;
- struct ast_config *cfg=NULL;
- struct ast_category *cat=NULL;
- struct ast_realloca ra;
- SQLULEN colsize;
- SQLSMALLINT colcount=0;
- SQLSMALLINT datatype;
- SQLSMALLINT decimaldigits;
- SQLSMALLINT nullable;
- SQLLEN indicator;
- struct custom_prepare_struct cps = { .sql = sql };
- va_list aq;
-
- va_copy(cps.ap, ap);
- va_copy(aq, ap);
-
- if (!table)
- return NULL;
- memset(&ra, 0, sizeof(ra));
-
- obj = ast_odbc_request_obj(database, 0);
- if (!obj)
- return NULL;
-
- newparam = va_arg(aq, const char *);
- if (!newparam) {
- ast_odbc_release_obj(obj);
- return NULL;
- }
- initfield = ast_strdupa(newparam);
- if ((op = strchr(initfield, ' ')))
- *op = '\0';
- newval = va_arg(aq, const char *);
- op = !strchr(newparam, ' ') ? " =" : "";
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, newparam, op,
- strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
- while((newparam = va_arg(aq, const char *))) {
- op = !strchr(newparam, ' ') ? " =" : "";
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op,
- strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
- newval = va_arg(aq, const char *);
- }
- if (initfield)
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
- va_end(aq);
-
- stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
-
- if (!stmt) {
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- res = SQLNumResultCols(stmt, &colcount);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- cfg = ast_config_new();
- if (!cfg) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- while ((res=SQLFetch(stmt)) != SQL_NO_DATA) {
- var = NULL;
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
- continue;
- }
- cat = ast_category_new("");
- if (!cat) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- continue;
- }
- for (x=0;x<colcount;x++) {
- rowdata[0] = '\0';
- collen = sizeof(coltitle);
- res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen,
- &datatype, &colsize, &decimaldigits, &nullable);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
- ast_category_destroy(cat);
- continue;
- }
-
- indicator = 0;
- res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator);
- if (indicator == SQL_NULL_DATA)
- continue;
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- ast_category_destroy(cat);
- continue;
- }
- stringp = rowdata;
- while(stringp) {
- chunk = strsep(&stringp, ";");
- if (!ast_strlen_zero(ast_strip(chunk))) {
- if (initfield && !strcmp(initfield, coltitle))
- ast_category_rename(cat, chunk);
- var = ast_variable_new(coltitle, chunk);
- ast_variable_append(cat, var);
- }
- }
- }
- ast_category_append(cfg, cat);
- }
-
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return cfg;
-}
-
-static int update_odbc(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
-{
- struct odbc_obj *obj;
- SQLHSTMT stmt;
- char sql[256];
- SQLLEN rowcount=0;
- const char *newparam, *newval;
- int res;
- va_list aq;
- struct custom_prepare_struct cps = { .sql = sql, .extra = lookup };
-
- va_copy(cps.ap, ap);
- va_copy(aq, ap);
-
- if (!table)
- return -1;
-
- obj = ast_odbc_request_obj(database, 0);
- if (!obj)
- return -1;
-
- newparam = va_arg(aq, const char *);
- if (!newparam) {
- ast_odbc_release_obj(obj);
- return -1;
- }
- newval = va_arg(aq, const char *);
- snprintf(sql, sizeof(sql), "UPDATE %s SET %s=?", table, newparam);
- while((newparam = va_arg(aq, const char *))) {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s=?", newparam);
- newval = va_arg(aq, const char *);
- }
- va_end(aq);
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield);
-
- stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
-
- if (!stmt) {
- ast_odbc_release_obj(obj);
- return -1;
- }
-
- res = SQLRowCount(stmt, &rowcount);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
- return -1;
- }
-
- if (rowcount >= 0)
- return (int)rowcount;
-
- return -1;
-}
-
-struct config_odbc_obj {
- char *sql;
- unsigned long cat_metric;
- char category[128];
- char var_name[128];
- char var_val[1024]; /* changed from 128 to 1024 via bug 8251 */
- SQLLEN err;
-};
-
-static SQLHSTMT config_odbc_prepare(struct odbc_obj *obj, void *data)
-{
- struct config_odbc_obj *q = data;
- SQLHSTMT sth;
- int res;
-
- res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &sth);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 3)
- ast_verbose( VERBOSE_PREFIX_4 "Failure in AllocStatement %d\n", res);
- return NULL;
- }
-
- res = SQLPrepare(sth, (unsigned char *)q->sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 3)
- ast_verbose( VERBOSE_PREFIX_4 "Error in PREPARE %d\n", res);
- SQLFreeHandle(SQL_HANDLE_STMT, sth);
- return NULL;
- }
-
- SQLBindCol(sth, 1, SQL_C_ULONG, &q->cat_metric, sizeof(q->cat_metric), &q->err);
- SQLBindCol(sth, 2, SQL_C_CHAR, q->category, sizeof(q->category), &q->err);
- SQLBindCol(sth, 3, SQL_C_CHAR, q->var_name, sizeof(q->var_name), &q->err);
- SQLBindCol(sth, 4, SQL_C_CHAR, q->var_val, sizeof(q->var_val), &q->err);
-
- return sth;
-}
-
-static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments)
-{
- struct ast_variable *new_v;
- struct ast_category *cur_cat;
- int res = 0;
- struct odbc_obj *obj;
- char sqlbuf[1024] = "";
- char *sql = sqlbuf;
- size_t sqlleft = sizeof(sqlbuf);
- unsigned int last_cat_metric = 0;
- SQLSMALLINT rowcount = 0;
- SQLHSTMT stmt;
- char last[128] = "";
- struct config_odbc_obj q;
-
- memset(&q, 0, sizeof(q));
-
- if (!file || !strcmp (file, "res_config_odbc.conf"))
- return NULL; /* cant configure myself with myself ! */
-
- obj = ast_odbc_request_obj(database, 0);
- if (!obj)
- return NULL;
-
- ast_build_string(&sql, &sqlleft, "SELECT cat_metric, category, var_name, var_val FROM %s ", table);
- ast_build_string(&sql, &sqlleft, "WHERE filename='%s' AND commented=0 ", file);
- ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");
- q.sql = sqlbuf;
-
- stmt = ast_odbc_prepare_and_execute(obj, config_odbc_prepare, &q);
-
- if (!stmt) {
- ast_log(LOG_WARNING, "SQL select error!\n[%s]\n\n", sql);
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- res = SQLNumResultCols(stmt, &rowcount);
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
-
- if (!rowcount) {
- ast_log(LOG_NOTICE, "found nothing\n");
- ast_odbc_release_obj(obj);
- return cfg;
- }
-
- cur_cat = ast_config_get_current_category(cfg);
-
- while ((res = SQLFetch(stmt)) != SQL_NO_DATA) {
- if (!strcmp (q.var_name, "#include")) {
- if (!ast_config_internal_load(q.var_val, cfg, 0)) {
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return NULL;
- }
- continue;
- }
- if (strcmp(last, q.category) || last_cat_metric != q.cat_metric) {
- cur_cat = ast_category_new(q.category);
- if (!cur_cat) {
- ast_log(LOG_WARNING, "Out of memory!\n");
- break;
- }
- strcpy(last, q.category);
- last_cat_metric = q.cat_metric;
- ast_category_append(cfg, cur_cat);
- }
-
- new_v = ast_variable_new(q.var_name, q.var_val);
- ast_variable_append(cur_cat, new_v);
- }
-
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- return cfg;
-}
-
-static struct ast_config_engine odbc_engine = {
- .name = "odbc",
- .load_func = config_odbc,
- .realtime_func = realtime_odbc,
- .realtime_multi_func = realtime_multi_odbc,
- .update_func = update_odbc
-};
-
-static int unload_module (void)
-{
- ast_module_user_hangup_all();
- ast_config_engine_deregister(&odbc_engine);
- if (option_verbose)
- ast_verbose("res_config_odbc unloaded.\n");
- return 0;
-}
-
-static int load_module (void)
-{
- ast_config_engine_register(&odbc_engine);
- if (option_verbose)
- ast_verbose("res_config_odbc loaded.\n");
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "ODBC Configuration",
- .load = load_module,
- .unload = unload_module,
- );
diff --git a/1.4/res/res_config_pgsql.c b/1.4/res/res_config_pgsql.c
deleted file mode 100644
index 494497033..000000000
--- a/1.4/res/res_config_pgsql.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Copyright (C) 1999-2005, Digium, Inc.
- *
- * Manuel Guesdon <mguesdon@oxymium.net> - Postgresql RealTime Driver Author/Adaptor
- * Mark Spencer <markster@digium.com> - Asterisk Author
- * Matthew Boehm <mboehm@cytelcom.com> - MySQL RealTime Driver Author
- *
- * res_config_pgsql.c <Postgresql plugin for RealTime configuration engine>
- *
- * v1.0 - (07-11-05) - Initial version based on res_config_mysql v2.0
- */
-
-/*! \file
- *
- * \brief Postgresql plugin for Asterisk RealTime Architecture
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Manuel Guesdon <mguesdon@oxymium.net> - Postgresql RealTime Driver Author/Adaptor
- *
- * \arg http://www.postgresql.org
- */
-
-/*** MODULEINFO
- <depend>pgsql</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <libpq-fe.h> /* PostgreSQL */
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/options.h"
-#include "asterisk/utils.h"
-#include "asterisk/cli.h"
-
-AST_MUTEX_DEFINE_STATIC(pgsql_lock);
-
-#define RES_CONFIG_PGSQL_CONF "res_pgsql.conf"
-
-PGconn *pgsqlConn = NULL;
-
-#define MAX_DB_OPTION_SIZE 64
-
-static char dbhost[MAX_DB_OPTION_SIZE] = "";
-static char dbuser[MAX_DB_OPTION_SIZE] = "";
-static char dbpass[MAX_DB_OPTION_SIZE] = "";
-static char dbname[MAX_DB_OPTION_SIZE] = "";
-static char dbsock[MAX_DB_OPTION_SIZE] = "";
-static int dbport = 5432;
-static time_t connect_time = 0;
-
-static int parse_config(void);
-static int pgsql_reconnect(const char *database);
-static int realtime_pgsql_status(int fd, int argc, char **argv);
-
-static char cli_realtime_pgsql_status_usage[] =
- "Usage: realtime pgsql status\n"
- " Shows connection information for the Postgresql RealTime driver\n";
-
-static struct ast_cli_entry cli_realtime[] = {
- { { "realtime", "pgsql", "status", NULL },
- realtime_pgsql_status, "Shows connection information for the Postgresql RealTime driver",
- cli_realtime_pgsql_status_usage },
-};
-
-static struct ast_variable *realtime_pgsql(const char *database, const char *table, va_list ap)
-{
- PGresult *result = NULL;
- int num_rows = 0, pgerror;
- char sql[256], escapebuf[513];
- char *stringp;
- char *chunk;
- char *op;
- const char *newparam, *newval;
- struct ast_variable *var = NULL, *prev = NULL;
-
- if (!table) {
- ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
- return NULL;
- }
-
- /* Get the first parameter and first value in our list of passed paramater/value pairs */
- newparam = va_arg(ap, const char *);
- newval = va_arg(ap, const char *);
- if (!newparam || !newval) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
- if (pgsqlConn) {
- PQfinish(pgsqlConn);
- pgsqlConn = NULL;
- };
- return NULL;
- }
-
- /* Create the first part of the query using the first parameter/value pairs we just extracted
- If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
- op = strchr(newparam, ' ') ? "" : " =";
-
- PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
- va_end(ap);
- return NULL;
- }
-
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op,
- escapebuf);
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
- if (!strchr(newparam, ' '))
- op = " =";
- else
- op = "";
-
- PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
- va_end(ap);
- return NULL;
- }
-
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam,
- op, escapebuf);
- }
- va_end(ap);
-
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&pgsql_lock);
- if (!pgsql_reconnect(database)) {
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
-
- if (!(result = PQexec(pgsqlConn, sql))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
- PQerrorMessage(pgsqlConn));
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- } else {
- ExecStatusType result_status = PQresultStatus(result);
- if (result_status != PGRES_COMMAND_OK
- && result_status != PGRES_TUPLES_OK
- && result_status != PGRES_NONFATAL_ERROR) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
- PQresultErrorMessage(result), PQresStatus(result_status));
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
- }
-
- ast_log(LOG_DEBUG, "1Postgresql RealTime: Result=%p Query: %s\n", result, sql);
-
- if ((num_rows = PQntuples(result)) > 0) {
- int i = 0;
- int rowIndex = 0;
- int numFields = PQnfields(result);
- char **fieldnames = NULL;
-
- ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows);
-
- if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) {
- ast_mutex_unlock(&pgsql_lock);
- PQclear(result);
- return NULL;
- }
- for (i = 0; i < numFields; i++)
- fieldnames[i] = PQfname(result, i);
- for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
- for (i = 0; i < numFields; i++) {
- stringp = PQgetvalue(result, rowIndex, i);
- while (stringp) {
- chunk = strsep(&stringp, ";");
- if (chunk && !ast_strlen_zero(ast_strip(chunk))) {
- if (prev) {
- prev->next = ast_variable_new(fieldnames[i], chunk);
- if (prev->next) {
- prev = prev->next;
- }
- } else {
- prev = var = ast_variable_new(fieldnames[i], chunk);
- }
- }
- }
- }
- }
- ast_free(fieldnames);
- } else {
- ast_log(LOG_DEBUG, "Postgresql RealTime: Could not find any rows in table %s.\n", table);
- }
-
- ast_mutex_unlock(&pgsql_lock);
- PQclear(result);
-
- return var;
-}
-
-static struct ast_config *realtime_multi_pgsql(const char *database, const char *table, va_list ap)
-{
- PGresult *result = NULL;
- int num_rows = 0, pgerror;
- char sql[256], escapebuf[513];
- const char *initfield = NULL;
- char *stringp;
- char *chunk;
- char *op;
- const char *newparam, *newval;
- struct ast_realloca ra;
- struct ast_variable *var = NULL;
- struct ast_config *cfg = NULL;
- struct ast_category *cat = NULL;
-
- if (!table) {
- ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
- return NULL;
- }
-
- memset(&ra, 0, sizeof(ra));
-
- if (!(cfg = ast_config_new()))
- return NULL;
-
- /* Get the first parameter and first value in our list of passed paramater/value pairs */
- newparam = va_arg(ap, const char *);
- newval = va_arg(ap, const char *);
- if (!newparam || !newval) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
- if (pgsqlConn) {
- PQfinish(pgsqlConn);
- pgsqlConn = NULL;
- };
- return NULL;
- }
-
- initfield = ast_strdupa(newparam);
- if ((op = strchr(initfield, ' '))) {
- *op = '\0';
- }
-
- /* Create the first part of the query using the first parameter/value pairs we just extracted
- If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
-
- if (!strchr(newparam, ' '))
- op = " =";
- else
- op = "";
-
- PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
- va_end(ap);
- return NULL;
- }
-
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op,
- escapebuf);
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
- if (!strchr(newparam, ' '))
- op = " =";
- else
- op = "";
-
- PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
- va_end(ap);
- return NULL;
- }
-
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam,
- op, escapebuf);
- }
-
- if (initfield) {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
- }
-
- va_end(ap);
-
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&pgsql_lock);
- if (!pgsql_reconnect(database)) {
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
-
- if (!(result = PQexec(pgsqlConn, sql))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
- PQerrorMessage(pgsqlConn));
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- } else {
- ExecStatusType result_status = PQresultStatus(result);
- if (result_status != PGRES_COMMAND_OK
- && result_status != PGRES_TUPLES_OK
- && result_status != PGRES_NONFATAL_ERROR) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
- PQresultErrorMessage(result), PQresStatus(result_status));
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
- }
-
- ast_log(LOG_DEBUG, "2Postgresql RealTime: Result=%p Query: %s\n", result, sql);
-
- if ((num_rows = PQntuples(result)) > 0) {
- int numFields = PQnfields(result);
- int i = 0;
- int rowIndex = 0;
- char **fieldnames = NULL;
-
- ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows);
-
- if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) {
- ast_mutex_unlock(&pgsql_lock);
- PQclear(result);
- return NULL;
- }
- for (i = 0; i < numFields; i++)
- fieldnames[i] = PQfname(result, i);
-
- for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
- var = NULL;
- if (!(cat = ast_category_new("")))
- continue;
- for (i = 0; i < numFields; i++) {
- stringp = PQgetvalue(result, rowIndex, i);
- while (stringp) {
- chunk = strsep(&stringp, ";");
- if (chunk && !ast_strlen_zero(ast_strip(chunk))) {
- if (initfield && !strcmp(initfield, fieldnames[i])) {
- ast_category_rename(cat, chunk);
- }
- var = ast_variable_new(fieldnames[i], chunk);
- ast_variable_append(cat, var);
- }
- }
- }
- ast_category_append(cfg, cat);
- }
- ast_free(fieldnames);
- } else {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Could not find any rows in table %s.\n", table);
- }
-
- ast_mutex_unlock(&pgsql_lock);
- PQclear(result);
-
- return cfg;
-}
-
-static int update_pgsql(const char *database, const char *table, const char *keyfield,
- const char *lookup, va_list ap)
-{
- PGresult *result = NULL;
- int numrows = 0, pgerror;
- char sql[256], escapebuf[513];
- const char *newparam, *newval;
-
- if (!table) {
- ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
- return -1;
- }
-
- /* Get the first parameter and first value in our list of passed paramater/value pairs */
- newparam = va_arg(ap, const char *);
- newval = va_arg(ap, const char *);
- if (!newparam || !newval) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
- if (pgsqlConn) {
- PQfinish(pgsqlConn);
- pgsqlConn = NULL;
- };
- return -1;
- }
-
- /* Create the first part of the query using the first parameter/value pairs we just extracted
- If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
-
- PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
- va_end(ap);
- return -1;
- }
- snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, escapebuf);
-
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
-
- PQescapeStringConn(pgsqlConn, escapebuf, newval, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval);
- va_end(ap);
- return -1;
- }
-
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam,
- escapebuf);
- }
- va_end(ap);
-
- PQescapeStringConn(pgsqlConn, escapebuf, lookup, (sizeof(escapebuf) - 1) / 2, &pgerror);
- if (pgerror) {
- ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", lookup);
- va_end(ap);
- return -1;
- }
-
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield,
- escapebuf);
-
- ast_log(LOG_DEBUG, "Postgresql RealTime: Update SQL: %s\n", sql);
-
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&pgsql_lock);
- if (!pgsql_reconnect(database)) {
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
-
- if (!(result = PQexec(pgsqlConn, sql))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
- PQerrorMessage(pgsqlConn));
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- } else {
- ExecStatusType result_status = PQresultStatus(result);
- if (result_status != PGRES_COMMAND_OK
- && result_status != PGRES_TUPLES_OK
- && result_status != PGRES_NONFATAL_ERROR) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
- PQresultErrorMessage(result), PQresStatus(result_status));
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
- }
-
- numrows = atoi(PQcmdTuples(result));
- ast_mutex_unlock(&pgsql_lock);
-
- ast_log(LOG_DEBUG, "Postgresql RealTime: Updated %d rows on table: %s\n", numrows,
- table);
-
- /* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html
- * An integer greater than zero indicates the number of rows affected
- * Zero indicates that no records were updated
- * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
- */
-
- if (numrows >= 0)
- return (int) numrows;
-
- return -1;
-}
-
-static struct ast_config *config_pgsql(const char *database, const char *table,
- const char *file, struct ast_config *cfg,
- int withcomments)
-{
- PGresult *result = NULL;
- long num_rows;
- struct ast_variable *new_v;
- struct ast_category *cur_cat = NULL;
- char sqlbuf[1024] = "";
- char *sql = sqlbuf;
- size_t sqlleft = sizeof(sqlbuf);
- char last[80] = "";
- int last_cat_metric = 0;
-
- last[0] = '\0';
-
- if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) {
- ast_log(LOG_WARNING, "Postgresql RealTime: Cannot configure myself.\n");
- return NULL;
- }
-
- ast_build_string(&sql, &sqlleft, "SELECT category, var_name, var_val, cat_metric FROM %s ", table);
- ast_build_string(&sql, &sqlleft, "WHERE filename='%s' and commented=0", file);
- ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");
-
- ast_log(LOG_DEBUG, "Postgresql RealTime: Static SQL: %s\n", sqlbuf);
-
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&pgsql_lock);
- if (!pgsql_reconnect(database)) {
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
-
- if (!(result = PQexec(pgsqlConn, sqlbuf))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
- PQerrorMessage(pgsqlConn));
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- } else {
- ExecStatusType result_status = PQresultStatus(result);
- if (result_status != PGRES_COMMAND_OK
- && result_status != PGRES_TUPLES_OK
- && result_status != PGRES_NONFATAL_ERROR) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Failed to query database. Check debug for more info.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
- PQresultErrorMessage(result), PQresStatus(result_status));
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
- }
-
- if ((num_rows = PQntuples(result)) > 0) {
- int rowIndex = 0;
-
- ast_log(LOG_DEBUG, "Postgresql RealTime: Found %ld rows.\n", num_rows);
-
- for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
- char *field_category = PQgetvalue(result, rowIndex, 0);
- char *field_var_name = PQgetvalue(result, rowIndex, 1);
- char *field_var_val = PQgetvalue(result, rowIndex, 2);
- char *field_cat_metric = PQgetvalue(result, rowIndex, 3);
- if (!strcmp(field_var_name, "#include")) {
- if (!ast_config_internal_load(field_var_val, cfg, 0)) {
- PQclear(result);
- ast_mutex_unlock(&pgsql_lock);
- return NULL;
- }
- continue;
- }
-
- if (strcmp(last, field_category) || last_cat_metric != atoi(field_cat_metric)) {
- cur_cat = ast_category_new(field_category);
- if (!cur_cat)
- break;
- strcpy(last, field_category);
- last_cat_metric = atoi(field_cat_metric);
- ast_category_append(cfg, cur_cat);
- }
- new_v = ast_variable_new(field_var_name, field_var_val);
- ast_variable_append(cur_cat, new_v);
- }
- } else {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Could not find config '%s' in database.\n", file);
- }
-
- PQclear(result);
- ast_mutex_unlock(&pgsql_lock);
-
- return cfg;
-}
-
-static struct ast_config_engine pgsql_engine = {
- .name = "pgsql",
- .load_func = config_pgsql,
- .realtime_func = realtime_pgsql,
- .realtime_multi_func = realtime_multi_pgsql,
- .update_func = update_pgsql
-};
-
-static int load_module(void)
-{
- if(!parse_config())
- return AST_MODULE_LOAD_DECLINE;
-
- ast_mutex_lock(&pgsql_lock);
-
- if (!pgsql_reconnect(NULL)) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Couldn't establish connection. Check debug.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n",
- PQerrorMessage(pgsqlConn));
- }
-
- ast_config_engine_register(&pgsql_engine);
- if (option_verbose) {
- ast_verbose("Postgresql RealTime driver loaded.\n");
- }
- ast_cli_register_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
-
- ast_mutex_unlock(&pgsql_lock);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- /* Aquire control before doing anything to the module itself. */
- ast_mutex_lock(&pgsql_lock);
-
- if (pgsqlConn) {
- PQfinish(pgsqlConn);
- pgsqlConn = NULL;
- };
- ast_cli_unregister_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
- ast_config_engine_deregister(&pgsql_engine);
- if (option_verbose) {
- ast_verbose("Postgresql RealTime unloaded.\n");
- }
-
- ast_module_user_hangup_all();
-
- /* Unlock so something else can destroy the lock. */
- ast_mutex_unlock(&pgsql_lock);
-
- return 0;
-}
-
-static int reload(void)
-{
- /* Aquire control before doing anything to the module itself. */
- ast_mutex_lock(&pgsql_lock);
-
- if (pgsqlConn) {
- PQfinish(pgsqlConn);
- pgsqlConn = NULL;
- };
- parse_config();
-
- if (!pgsql_reconnect(NULL)) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: Couldn't establish connection. Check debug.\n");
- ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n",
- PQerrorMessage(pgsqlConn));
- }
-
- ast_verbose(VERBOSE_PREFIX_2 "Postgresql RealTime reloaded.\n");
-
- /* Done reloading. Release lock so others can now use driver. */
- ast_mutex_unlock(&pgsql_lock);
-
- return 0;
-}
-
-static int parse_config(void)
-{
- struct ast_config *config;
- const char *s;
-
- config = ast_config_load(RES_CONFIG_PGSQL_CONF);
-
- if (!config) {
- ast_log(LOG_WARNING, "Unable to load config %s\n",RES_CONFIG_PGSQL_CONF);
- return 0;
- }
- if (!(s = ast_variable_retrieve(config, "general", "dbuser"))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: No database user found, using 'asterisk' as default.\n");
- strcpy(dbuser, "asterisk");
- } else {
- ast_copy_string(dbuser, s, sizeof(dbuser));
- }
-
- if (!(s = ast_variable_retrieve(config, "general", "dbpass"))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: No database password found, using 'asterisk' as default.\n");
- strcpy(dbpass, "asterisk");
- } else {
- ast_copy_string(dbpass, s, sizeof(dbpass));
- }
-
- if (!(s = ast_variable_retrieve(config, "general", "dbhost"))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: No database host found, using localhost via socket.\n");
- dbhost[0] = '\0';
- } else {
- ast_copy_string(dbhost, s, sizeof(dbhost));
- }
-
- if (!(s = ast_variable_retrieve(config, "general", "dbname"))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: No database name found, using 'asterisk' as default.\n");
- strcpy(dbname, "asterisk");
- } else {
- ast_copy_string(dbname, s, sizeof(dbname));
- }
-
- if (!(s = ast_variable_retrieve(config, "general", "dbport"))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: No database port found, using 5432 as default.\n");
- dbport = 5432;
- } else {
- dbport = atoi(s);
- }
-
- if (!ast_strlen_zero(dbhost)) {
- /* No socket needed */
- } else if (!(s = ast_variable_retrieve(config, "general", "dbsock"))) {
- ast_log(LOG_WARNING,
- "Postgresql RealTime: No database socket found, using '/tmp/pgsql.sock' as default.\n");
- strcpy(dbsock, "/tmp/pgsql.sock");
- } else {
- ast_copy_string(dbsock, s, sizeof(dbsock));
- }
- ast_config_destroy(config);
-
- if (!ast_strlen_zero(dbhost)) {
- ast_log(LOG_DEBUG, "Postgresql RealTime Host: %s\n", dbhost);
- ast_log(LOG_DEBUG, "Postgresql RealTime Port: %i\n", dbport);
- } else {
- ast_log(LOG_DEBUG, "Postgresql RealTime Socket: %s\n", dbsock);
- }
- ast_log(LOG_DEBUG, "Postgresql RealTime User: %s\n", dbuser);
- ast_log(LOG_DEBUG, "Postgresql RealTime Password: %s\n", dbpass);
- ast_log(LOG_DEBUG, "Postgresql RealTime DBName: %s\n", dbname);
-
- return 1;
-}
-
-static int pgsql_reconnect(const char *database)
-{
- char my_database[50];
-
- ast_copy_string(my_database, S_OR(database, dbname), sizeof(my_database));
-
- /* mutex lock should have been locked before calling this function. */
-
- if (pgsqlConn && PQstatus(pgsqlConn) != CONNECTION_OK) {
- PQfinish(pgsqlConn);
- pgsqlConn = NULL;
- }
-
- if ((!pgsqlConn) && (!ast_strlen_zero(dbhost) || !ast_strlen_zero(dbsock)) && !ast_strlen_zero(dbuser) && !ast_strlen_zero(dbpass) && !ast_strlen_zero(my_database)) {
- char *connInfo = NULL;
- unsigned int size = 100 + strlen(dbhost)
- + strlen(dbuser)
- + strlen(dbpass)
- + strlen(my_database);
-
- if (!(connInfo = ast_malloc(size)))
- return 0;
-
- sprintf(connInfo, "host=%s port=%d dbname=%s user=%s password=%s",
- dbhost, dbport, my_database, dbuser, dbpass);
- ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo);
- pgsqlConn = PQconnectdb(connInfo);
- ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo);
- ast_free(connInfo);
- connInfo = NULL;
- ast_log(LOG_DEBUG, "pgsqlConn=%p\n", pgsqlConn);
- if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) {
- ast_log(LOG_DEBUG, "Postgresql RealTime: Successfully connected to database.\n");
- connect_time = time(NULL);
- return 1;
- } else {
- ast_log(LOG_ERROR,
- "Postgresql RealTime: Failed to connect database server %s on %s. Check debug for more info.\n",
- dbname, dbhost);
- ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n",
- PQresultErrorMessage(NULL));
- return 0;
- }
- } else {
- ast_log(LOG_DEBUG, "Postgresql RealTime: Everything is fine.\n");
- return 1;
- }
-}
-
-static int realtime_pgsql_status(int fd, int argc, char **argv)
-{
- char status[256], status2[100] = "";
- int ctime = time(NULL) - connect_time;
-
- if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) {
- if (!ast_strlen_zero(dbhost)) {
- snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport);
- } else if (!ast_strlen_zero(dbsock)) {
- snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock);
- } else {
- snprintf(status, 255, "Connected to %s@%s", dbname, dbhost);
- }
-
- if (!ast_strlen_zero(dbuser)) {
- snprintf(status2, 99, " with username %s", dbuser);
- }
-
- if (ctime > 31536000) {
- ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n",
- status, status2, ctime / 31536000, (ctime % 31536000) / 86400,
- (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60);
- } else if (ctime > 86400) {
- ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status,
- status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60,
- ctime % 60);
- } else if (ctime > 3600) {
- ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2,
- ctime / 3600, (ctime % 3600) / 60, ctime % 60);
- } else if (ctime > 60) {
- ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60,
- ctime % 60);
- } else {
- ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime);
- }
-
- return RESULT_SUCCESS;
- } else {
- return RESULT_FAILURE;
- }
-}
-
-/* needs usecount semantics defined */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "PostgreSQL RealTime Configuration Driver",
- .load = load_module,
- .unload = unload_module,
- .reload = reload
- );
diff --git a/1.4/res/res_convert.c b/1.4/res/res_convert.c
deleted file mode 100644
index 7c4e04e83..000000000
--- a/1.4/res/res_convert.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, 2006, Digium, Inc.
- *
- * redice li <redice_li@yahoo.com>
- * Russell Bryant <russell@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.
- */
-
-/*! \file
- *
- * \brief file format conversion CLI command using Asterisk formats and translators
- *
- * \author redice li <redice_li@yahoo.com>
- * \author Russell Bryant <russell@digium.com>
- *
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/module.h"
-#include "asterisk/cli.h"
-#include "asterisk/file.h"
-
-/*! \brief Split the filename to basename and extension */
-static int split_ext(char *filename, char **name, char **ext)
-{
- *name = *ext = filename;
-
- if ((*ext = strrchr(filename, '.'))) {
- **ext = '\0';
- (*ext)++;
- }
-
- if (ast_strlen_zero(*name) || ast_strlen_zero(*ext))
- return -1;
-
- return 0;
-}
-
-/*! \brief Convert a file from one format to another */
-static int cli_audio_convert_deprecated(int fd, int argc, char *argv[])
-{
- int ret = RESULT_FAILURE;
- struct ast_filestream *fs_in = NULL, *fs_out = NULL;
- struct ast_frame *f;
- struct timeval start;
- int cost;
- char *file_in = NULL, *file_out = NULL;
- char *name_in, *ext_in, *name_out, *ext_out;
-
- /* ugly, can be removed when CLI entries have ast_module pointers */
- ast_module_ref(ast_module_info->self);
-
- if (argc != 3 || ast_strlen_zero(argv[1]) || ast_strlen_zero(argv[2])) {
- ret = RESULT_SHOWUSAGE;
- goto fail_out;
- }
-
- file_in = ast_strdupa(argv[1]);
- file_out = ast_strdupa(argv[2]);
-
- if (split_ext(file_in, &name_in, &ext_in)) {
- ast_cli(fd, "'%s' is an invalid filename!\n", argv[1]);
- goto fail_out;
- }
- if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) {
- ast_cli(fd, "Unable to open input file: %s\n", argv[1]);
- goto fail_out;
- }
-
- if (split_ext(file_out, &name_out, &ext_out)) {
- ast_cli(fd, "'%s' is an invalid filename!\n", argv[2]);
- goto fail_out;
- }
- if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
- ast_cli(fd, "Unable to open output file: %s\n", argv[2]);
- goto fail_out;
- }
-
- start = ast_tvnow();
-
- while ((f = ast_readframe(fs_in))) {
- if (ast_writestream(fs_out, f)) {
- ast_cli(fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out);
- goto fail_out;
- }
- }
-
- cost = ast_tvdiff_ms(ast_tvnow(), start);
- ast_cli(fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost);
- ret = RESULT_SUCCESS;
-
-fail_out:
- if (fs_out) {
- ast_closestream(fs_out);
- if (ret != RESULT_SUCCESS)
- ast_filedelete(name_out, ext_out);
- }
-
- if (fs_in)
- ast_closestream(fs_in);
-
- ast_module_unref(ast_module_info->self);
-
- return ret;
-}
-
-static int cli_audio_convert(int fd, int argc, char *argv[])
-{
- int ret = RESULT_FAILURE;
- struct ast_filestream *fs_in = NULL, *fs_out = NULL;
- struct ast_frame *f;
- struct timeval start;
- int cost;
- char *file_in = NULL, *file_out = NULL;
- char *name_in, *ext_in, *name_out, *ext_out;
-
- /* ugly, can be removed when CLI entries have ast_module pointers */
- ast_module_ref(ast_module_info->self);
-
- if (argc != 4 || ast_strlen_zero(argv[2]) || ast_strlen_zero(argv[3])) {
- ret = RESULT_SHOWUSAGE;
- goto fail_out;
- }
-
- file_in = ast_strdupa(argv[2]);
- file_out = ast_strdupa(argv[3]);
-
- if (split_ext(file_in, &name_in, &ext_in)) {
- ast_cli(fd, "'%s' is an invalid filename!\n", argv[2]);
- goto fail_out;
- }
- if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) {
- ast_cli(fd, "Unable to open input file: %s\n", argv[2]);
- goto fail_out;
- }
-
- if (split_ext(file_out, &name_out, &ext_out)) {
- ast_cli(fd, "'%s' is an invalid filename!\n", argv[3]);
- goto fail_out;
- }
- if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
- ast_cli(fd, "Unable to open output file: %s\n", argv[3]);
- goto fail_out;
- }
-
- start = ast_tvnow();
-
- while ((f = ast_readframe(fs_in))) {
- if (ast_writestream(fs_out, f)) {
- ast_cli(fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out);
- goto fail_out;
- }
- }
-
- cost = ast_tvdiff_ms(ast_tvnow(), start);
- ast_cli(fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost);
- ret = RESULT_SUCCESS;
-
-fail_out:
- if (fs_out) {
- ast_closestream(fs_out);
- if (ret != RESULT_SUCCESS)
- ast_filedelete(name_out, ext_out);
- }
-
- if (fs_in)
- ast_closestream(fs_in);
-
- ast_module_unref(ast_module_info->self);
-
- return ret;
-}
-
-static char usage_audio_convert[] =
-"Usage: file convert <file_in> <file_out>\n"
-" Convert from file_in to file_out. If an absolute path is not given, the\n"
-"default Asterisk sounds directory will be used.\n\n"
-"Example:\n"
-" file convert tt-weasels.gsm tt-weasels.ulaw\n";
-
-static struct ast_cli_entry cli_convert_deprecated = {
- { "convert" , NULL },
- cli_audio_convert_deprecated, NULL,
- NULL };
-
-static struct ast_cli_entry cli_convert[] = {
- { { "file", "convert" , NULL },
- cli_audio_convert, "Convert audio file",
- usage_audio_convert, NULL, &cli_convert_deprecated },
-};
-
-static int unload_module(void)
-{
- ast_cli_unregister_multiple(cli_convert, sizeof(cli_convert) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-static int load_module(void)
-{
- ast_cli_register_multiple(cli_convert, sizeof(cli_convert) / sizeof(struct ast_cli_entry));
- return 0;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "File format conversion CLI command");
diff --git a/1.4/res/res_crypto.c b/1.4/res/res_crypto.c
deleted file mode 100644
index eea8356af..000000000
--- a/1.4/res/res_crypto.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Provide Cryptographic Signature capability
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-/*** MODULEINFO
- <depend>ssl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "asterisk/file.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/say.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/crypto.h"
-#include "asterisk/md5.h"
-#include "asterisk/cli.h"
-#include "asterisk/io.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-
-/*
- * Asterisk uses RSA keys with SHA-1 message digests for its
- * digital signatures. The choice of RSA is due to its higher
- * throughput on verification, and the choice of SHA-1 based
- * on the recently discovered collisions in MD5's compression
- * algorithm and recommendations of avoiding MD5 in new schemes
- * from various industry experts.
- *
- * We use OpenSSL to provide our crypto routines, although we never
- * actually use full-up SSL
- *
- */
-
-/*
- * XXX This module is not very thread-safe. It is for everyday stuff
- * like reading keys and stuff, but there are all kinds of weird
- * races with people running reload and key init at the same time
- * for example
- *
- * XXXX
- */
-
-AST_MUTEX_DEFINE_STATIC(keylock);
-
-#define KEY_NEEDS_PASSCODE (1 << 16)
-
-struct ast_key {
- /* Name of entity */
- char name[80];
- /* File name */
- char fn[256];
- /* Key type (AST_KEY_PUB or AST_KEY_PRIV, along with flags from above) */
- int ktype;
- /* RSA structure (if successfully loaded) */
- RSA *rsa;
- /* Whether we should be deleted */
- int delme;
- /* FD for input (or -1 if no input allowed, or -2 if we needed input) */
- int infd;
- /* FD for output */
- int outfd;
- /* Last MD5 Digest */
- unsigned char digest[16];
- struct ast_key *next;
-};
-
-static struct ast_key *keys = NULL;
-
-
-#if 0
-static int fdprint(int fd, char *s)
-{
- return write(fd, s, strlen(s) + 1);
-}
-#endif
-static int pw_cb(char *buf, int size, int rwflag, void *userdata)
-{
- struct ast_key *key = (struct ast_key *)userdata;
- char prompt[256];
- int res;
- int tmp;
- if (key->infd > -1) {
- snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ",
- key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name);
- write(key->outfd, prompt, strlen(prompt));
- memset(buf, 0, sizeof(buf));
- tmp = ast_hide_password(key->infd);
- memset(buf, 0, size);
- res = read(key->infd, buf, size);
- ast_restore_tty(key->infd, tmp);
- if (buf[strlen(buf) -1] == '\n')
- buf[strlen(buf) - 1] = '\0';
- return strlen(buf);
- } else {
- /* Note that we were at least called */
- key->infd = -2;
- }
- return -1;
-}
-
-static struct ast_key *__ast_key_get(const char *kname, int ktype)
-{
- struct ast_key *key;
- ast_mutex_lock(&keylock);
- key = keys;
- while(key) {
- if (!strcmp(kname, key->name) &&
- (ktype == key->ktype))
- break;
- key = key->next;
- }
- ast_mutex_unlock(&keylock);
- return key;
-}
-
-static struct ast_key *try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2)
-{
- int ktype = 0;
- char *c = NULL;
- char ffname[256];
- unsigned char digest[16];
- FILE *f;
- struct MD5Context md5;
- struct ast_key *key;
- static int notice = 0;
- int found = 0;
-
- /* Make sure its name is a public or private key */
-
- if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
- ktype = AST_KEY_PUBLIC;
- } else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
- ktype = AST_KEY_PRIVATE;
- } else
- return NULL;
-
- /* Get actual filename */
- snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
-
- ast_mutex_lock(&keylock);
- key = keys;
- while(key) {
- /* Look for an existing version already */
- if (!strcasecmp(key->fn, ffname))
- break;
- key = key->next;
- }
- ast_mutex_unlock(&keylock);
-
- /* Open file */
- f = fopen(ffname, "r");
- if (!f) {
- ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
- return NULL;
- }
- MD5Init(&md5);
- while(!feof(f)) {
- /* Calculate a "whatever" quality md5sum of the key */
- char buf[256];
- memset(buf, 0, 256);
- fgets(buf, sizeof(buf), f);
- if (!feof(f)) {
- MD5Update(&md5, (unsigned char *) buf, strlen(buf));
- }
- }
- MD5Final(digest, &md5);
- if (key) {
- /* If the MD5 sum is the same, and it isn't awaiting a passcode
- then this is far enough */
- if (!memcmp(digest, key->digest, 16) &&
- !(key->ktype & KEY_NEEDS_PASSCODE)) {
- fclose(f);
- key->delme = 0;
- return NULL;
- } else {
- /* Preserve keytype */
- ktype = key->ktype;
- /* Recycle the same structure */
- found++;
- }
- }
-
- /* Make fname just be the normal name now */
- *c = '\0';
- if (!key) {
- if (!(key = ast_calloc(1, sizeof(*key)))) {
- fclose(f);
- return NULL;
- }
- }
- /* At this point we have a key structure (old or new). Time to
- fill it with what we know */
- /* Gotta lock if this one already exists */
- if (found)
- ast_mutex_lock(&keylock);
- /* First the filename */
- ast_copy_string(key->fn, ffname, sizeof(key->fn));
- /* Then the name */
- ast_copy_string(key->name, fname, sizeof(key->name));
- key->ktype = ktype;
- /* Yes, assume we're going to be deleted */
- key->delme = 1;
- /* Keep the key type */
- memcpy(key->digest, digest, 16);
- /* Can I/O takes the FD we're given */
- key->infd = ifd;
- key->outfd = ofd;
- /* Reset the file back to the beginning */
- rewind(f);
- /* Now load the key with the right method */
- if (ktype == AST_KEY_PUBLIC)
- key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
- else
- key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
- fclose(f);
- if (key->rsa) {
- if (RSA_size(key->rsa) == 128) {
- /* Key loaded okay */
- key->ktype &= ~KEY_NEEDS_PASSCODE;
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
- if (option_debug)
- ast_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
- key->delme = 0;
- } else
- ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
- } else if (key->infd != -2) {
- ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
- if (ofd > -1) {
- ERR_print_errors_fp(stderr);
- } else
- ERR_print_errors_fp(stderr);
- } else {
- ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
- key->ktype |= KEY_NEEDS_PASSCODE;
- if (!notice) {
- if (!ast_opt_init_keys)
- ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
- notice++;
- }
- /* Keep it anyway */
- key->delme = 0;
- /* Print final notice about "init keys" when done */
- *not2 = 1;
- }
- if (found)
- ast_mutex_unlock(&keylock);
- if (!found) {
- ast_mutex_lock(&keylock);
- key->next = keys;
- keys = key;
- ast_mutex_unlock(&keylock);
- }
- return key;
-}
-
-#if 0
-
-static void dump(unsigned char *src, int len)
-{
- int x;
- for (x=0;x<len;x++)
- printf("%02x", *(src++));
- printf("\n");
-}
-
-static char *binary(int y, int len)
-{
- static char res[80];
- int x;
- memset(res, 0, sizeof(res));
- for (x=0;x<len;x++) {
- if (y & (1 << x))
- res[(len - x - 1)] = '1';
- else
- res[(len - x - 1)] = '0';
- }
- return res;
-}
-
-#endif
-
-static int __ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
-{
- unsigned char digest[20];
- unsigned int siglen = 128;
- int res;
-
- if (key->ktype != AST_KEY_PRIVATE) {
- ast_log(LOG_WARNING, "Cannot sign with a public key\n");
- return -1;
- }
-
- /* Calculate digest of message */
- SHA1((unsigned char *)msg, msglen, digest);
-
- /* Verify signature */
- res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa);
-
- if (!res) {
- ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name);
- return -1;
- }
-
- if (siglen != 128) {
- ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", (int)siglen, (int)128);
- return -1;
- }
-
- return 0;
-
-}
-
-static int __ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
-{
- int res;
- int pos = 0;
- if (key->ktype != AST_KEY_PRIVATE) {
- ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
- return -1;
- }
-
- if (srclen % 128) {
- ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n");
- return -1;
- }
- while(srclen) {
- /* Process chunks 128 bytes at a time */
- res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING);
- if (res < 0)
- return -1;
- pos += res;
- src += 128;
- srclen -= 128;
- dst += res;
- }
- return pos;
-}
-
-static int __ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
-{
- int res;
- int bytes;
- int pos = 0;
- if (key->ktype != AST_KEY_PUBLIC) {
- ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
- return -1;
- }
-
- while(srclen) {
- bytes = srclen;
- if (bytes > 128 - 41)
- bytes = 128 - 41;
- /* Process chunks 128-41 bytes at a time */
- res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING);
- if (res != 128) {
- ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);
- return -1;
- }
- src += bytes;
- srclen -= bytes;
- pos += res;
- dst += res;
- }
- return pos;
-}
-
-static int __ast_sign(struct ast_key *key, char *msg, char *sig)
-{
- unsigned char dsig[128];
- int siglen = sizeof(dsig);
- int res;
- res = ast_sign_bin(key, msg, strlen(msg), dsig);
- if (!res)
- /* Success -- encode (256 bytes max as documented) */
- ast_base64encode(sig, dsig, siglen, 256);
- return res;
-
-}
-
-static int __ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
-{
- unsigned char digest[20];
- int res;
-
- if (key->ktype != AST_KEY_PUBLIC) {
- /* Okay, so of course you really *can* but for our purposes
- we're going to say you can't */
- ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
- return -1;
- }
-
- /* Calculate digest of message */
- SHA1((unsigned char *)msg, msglen, digest);
-
- /* Verify signature */
- res = RSA_verify(NID_sha1, digest, sizeof(digest), (unsigned char *)dsig, 128, key->rsa);
-
- if (!res) {
- ast_log(LOG_DEBUG, "Key failed verification: %s\n", key->name);
- return -1;
- }
- /* Pass */
- return 0;
-}
-
-static int __ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
-{
- unsigned char dsig[128];
- int res;
-
- /* Decode signature */
- res = ast_base64decode(dsig, sig, sizeof(dsig));
- if (res != sizeof(dsig)) {
- ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res);
- return -1;
- }
- res = ast_check_signature_bin(key, msg, strlen(msg), dsig);
- return res;
-}
-
-static void crypto_load(int ifd, int ofd)
-{
- struct ast_key *key, *nkey, *last;
- DIR *dir = NULL;
- struct dirent *ent;
- int note = 0;
- /* Mark all keys for deletion */
- ast_mutex_lock(&keylock);
- key = keys;
- while(key) {
- key->delme = 1;
- key = key->next;
- }
- ast_mutex_unlock(&keylock);
- /* Load new keys */
- dir = opendir((char *)ast_config_AST_KEY_DIR);
- if (dir) {
- while((ent = readdir(dir))) {
- try_load_key((char *)ast_config_AST_KEY_DIR, ent->d_name, ifd, ofd, &note);
- }
- closedir(dir);
- } else
- ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", (char *)ast_config_AST_KEY_DIR);
- if (note) {
- ast_log(LOG_NOTICE, "Please run the command 'init keys' to enter the passcodes for the keys\n");
- }
- ast_mutex_lock(&keylock);
- key = keys;
- last = NULL;
- while(key) {
- nkey = key->next;
- if (key->delme) {
- ast_log(LOG_DEBUG, "Deleting key %s type %d\n", key->name, key->ktype);
- /* Do the delete */
- if (last)
- last->next = nkey;
- else
- keys = nkey;
- if (key->rsa)
- RSA_free(key->rsa);
- free(key);
- } else
- last = key;
- key = nkey;
- }
- ast_mutex_unlock(&keylock);
-}
-
-static void md52sum(char *sum, unsigned char *md5)
-{
- int x;
- for (x=0;x<16;x++)
- sum += sprintf(sum, "%02x", *(md5++));
-}
-
-static int show_keys(int fd, int argc, char *argv[])
-{
- struct ast_key *key;
- char sum[16 * 2 + 1];
- int count_keys = 0;
-
- ast_mutex_lock(&keylock);
- key = keys;
- ast_cli(fd, "%-18s %-8s %-16s %-33s\n", "Key Name", "Type", "Status", "Sum");
- while(key) {
- md52sum(sum, key->digest);
- ast_cli(fd, "%-18s %-8s %-16s %-33s\n", key->name,
- (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE",
- key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum);
-
- key = key->next;
- count_keys++;
- }
- ast_mutex_unlock(&keylock);
- ast_cli(fd, "%d known RSA keys.\n", count_keys);
- return RESULT_SUCCESS;
-}
-
-static int init_keys(int fd, int argc, char *argv[])
-{
- struct ast_key *key;
- int ign;
- char *kn;
- char tmp[256] = "";
-
- key = keys;
- while(key) {
- /* Reload keys that need pass codes now */
- if (key->ktype & KEY_NEEDS_PASSCODE) {
- kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1;
- ast_copy_string(tmp, kn, sizeof(tmp));
- try_load_key((char *)ast_config_AST_KEY_DIR, tmp, fd, fd, &ign);
- }
- key = key->next;
- }
- return RESULT_SUCCESS;
-}
-
-static char show_key_usage[] =
-"Usage: keys show\n"
-" Displays information about RSA keys known by Asterisk\n";
-
-static char init_keys_usage[] =
-"Usage: keys init\n"
-" Initializes private keys (by reading in pass code from the user)\n";
-
-static struct ast_cli_entry cli_show_keys_deprecated = {
- { "show", "keys", NULL },
- show_keys, NULL,
- NULL };
-
-static struct ast_cli_entry cli_init_keys_deprecated = {
- { "init", "keys", NULL },
- init_keys, NULL,
- NULL };
-
-static struct ast_cli_entry cli_crypto[] = {
- { { "keys", "show", NULL },
- show_keys, "Displays RSA key information",
- show_key_usage, NULL, &cli_show_keys_deprecated },
-
- { { "keys", "init", NULL },
- init_keys, "Initialize RSA key passcodes",
- init_keys_usage, NULL, &cli_init_keys_deprecated },
-};
-
-static int crypto_init(void)
-{
- SSL_library_init();
- ERR_load_crypto_strings();
- ast_cli_register_multiple(cli_crypto, sizeof(cli_crypto) / sizeof(struct ast_cli_entry));
-
- /* Install ourselves into stubs */
- ast_key_get = __ast_key_get;
- ast_check_signature = __ast_check_signature;
- ast_check_signature_bin = __ast_check_signature_bin;
- ast_sign = __ast_sign;
- ast_sign_bin = __ast_sign_bin;
- ast_encrypt_bin = __ast_encrypt_bin;
- ast_decrypt_bin = __ast_decrypt_bin;
- return 0;
-}
-
-static int reload(void)
-{
- crypto_load(-1, -1);
- return 0;
-}
-
-static int load_module(void)
-{
- crypto_init();
- if (ast_opt_init_keys)
- crypto_load(STDIN_FILENO, STDOUT_FILENO);
- else
- crypto_load(-1, -1);
- return 0;
-}
-
-static int unload_module(void)
-{
- /* Can't unload this once we're loaded */
- return -1;
-}
-
-/* needs usecount semantics defined */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Cryptographic Digital Signatures",
- .load = load_module,
- .unload = unload_module,
- .reload = reload
- );
diff --git a/1.4/res/res_features.c b/1.4/res/res_features.c
deleted file mode 100644
index 9c7fef79f..000000000
--- a/1.4/res/res_features.c
+++ /dev/null
@@ -1,2508 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Routines implementing call features as call pickup, parking and transfer
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-/*** MODULEINFO
- <depend>chan_local</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <netinet/in.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/causes.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/app.h"
-#include "asterisk/say.h"
-#include "asterisk/features.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/config.h"
-#include "asterisk/cli.h"
-#include "asterisk/manager.h"
-#include "asterisk/utils.h"
-#include "asterisk/adsi.h"
-#include "asterisk/devicestate.h"
-#include "asterisk/monitor.h"
-
-#define DEFAULT_PARK_TIME 45000
-#define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
-#define DEFAULT_FEATURE_DIGIT_TIMEOUT 500
-#define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
-
-#define AST_MAX_WATCHERS 256
-
-enum {
- AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0),
- AST_FEATURE_FLAG_ONPEER = (1 << 1),
- AST_FEATURE_FLAG_ONSELF = (1 << 2),
- AST_FEATURE_FLAG_BYCALLEE = (1 << 3),
- AST_FEATURE_FLAG_BYCALLER = (1 << 4),
- AST_FEATURE_FLAG_BYBOTH = (3 << 3),
-};
-
-static char *parkedcall = "ParkedCall";
-
-static int parkaddhints = 0; /*!< Add parking hints automatically */
-static int parkingtime = DEFAULT_PARK_TIME; /*!< No more than 45 seconds parked before you do something with them */
-static char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
-static char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
-static char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
-static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
-static char parkmohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
-static int parking_start; /*!< First available extension for parking */
-static int parking_stop; /*!< Last available extension for parking */
-
-static char courtesytone[256]; /*!< Courtesy tone */
-static int parkedplay = 0; /*!< Who to play the courtesy tone to */
-static char xfersound[256]; /*!< Call transfer sound */
-static char xferfailsound[256]; /*!< Call transfer failure sound */
-
-static int parking_offset;
-static int parkfindnext;
-
-static int adsipark;
-
-static int transferdigittimeout;
-static int featuredigittimeout;
-
-static int atxfernoanswertimeout;
-
-static char *registrar = "res_features"; /*!< Registrar for operations */
-
-/* module and CLI command definitions */
-static char *synopsis = "Answer a parked call";
-
-static char *descrip = "ParkedCall(exten):"
-"Used to connect to a parked call. This application is always\n"
-"registered internally and does not need to be explicitly added\n"
-"into the dialplan, although you should include the 'parkedcalls'\n"
-"context.\n";
-
-static char *parkcall = "Park";
-
-static char *synopsis2 = "Park yourself";
-
-static char *descrip2 = "Park():"
-"Used to park yourself (typically in combination with a supervised\n"
-"transfer to know the parking space). This application is always\n"
-"registered internally and does not need to be explicitly added\n"
-"into the dialplan, although you should include the 'parkedcalls'\n"
-"context (or the context specified in features.conf).\n\n"
-"If you set the PARKINGEXTEN variable to an extension in your\n"
-"parking context, park() will park the call on that extension, unless\n"
-"it already exists. In that case, execution will continue at next\n"
-"priority.\n" ;
-
-static struct ast_app *monitor_app = NULL;
-static int monitor_ok = 1;
-
-struct parkeduser {
- struct ast_channel *chan; /*!< Parking channel */
- struct timeval start; /*!< Time the parking started */
- int parkingnum; /*!< Parking lot */
- char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
- char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
- char exten[AST_MAX_EXTENSION];
- int priority;
- int parkingtime; /*!< Maximum length in parking lot before return */
- int notquiteyet;
- char peername[1024];
- unsigned char moh_trys;
- struct parkeduser *next;
-};
-
-static struct parkeduser *parkinglot;
-
-AST_MUTEX_DEFINE_STATIC(parking_lock); /*!< protects all static variables above */
-
-static pthread_t parking_thread;
-
-char *ast_parking_ext(void)
-{
- return parking_ext;
-}
-
-char *ast_pickup_ext(void)
-{
- return pickup_ext;
-}
-
-struct ast_bridge_thread_obj
-{
- struct ast_bridge_config bconfig;
- struct ast_channel *chan;
- struct ast_channel *peer;
-};
-
-
-
-/*! \brief store context, priority and extension */
-static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
-{
- ast_copy_string(chan->context, context, sizeof(chan->context));
- ast_copy_string(chan->exten, ext, sizeof(chan->exten));
- chan->priority = pri;
-}
-
-static void check_goto_on_transfer(struct ast_channel *chan)
-{
- struct ast_channel *xferchan;
- const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
- char *x, *goto_on_transfer;
- struct ast_frame *f;
-
- if (ast_strlen_zero(val))
- return;
-
- goto_on_transfer = ast_strdupa(val);
-
- if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, chan->name)))
- return;
-
- for (x = goto_on_transfer; x && *x; x++) {
- if (*x == '^')
- *x = '|';
- }
- /* Make formats okay */
- xferchan->readformat = chan->readformat;
- xferchan->writeformat = chan->writeformat;
- ast_channel_masquerade(xferchan, chan);
- ast_parseable_goto(xferchan, goto_on_transfer);
- xferchan->_state = AST_STATE_UP;
- ast_clear_flag(xferchan, AST_FLAGS_ALL);
- xferchan->_softhangup = 0;
- if ((f = ast_read(xferchan))) {
- ast_frfree(f);
- f = NULL;
- ast_pbx_start(xferchan);
- } else {
- ast_hangup(xferchan);
- }
-}
-
-static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, const char *language);
-
-
-static void *ast_bridge_call_thread(void *data)
-{
- struct ast_bridge_thread_obj *tobj = data;
-
- tobj->chan->appl = "Transferred Call";
- tobj->chan->data = tobj->peer->name;
- tobj->peer->appl = "Transferred Call";
- tobj->peer->data = tobj->chan->name;
- if (tobj->chan->cdr) {
- ast_cdr_reset(tobj->chan->cdr, NULL);
- ast_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name);
- }
- if (tobj->peer->cdr) {
- ast_cdr_reset(tobj->peer->cdr, NULL);
- ast_cdr_setdestchan(tobj->peer->cdr, tobj->chan->name);
- }
-
- ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
- ast_hangup(tobj->chan);
- ast_hangup(tobj->peer);
- bzero(tobj, sizeof(*tobj)); /*! \todo XXX for safety */
- free(tobj);
- return NULL;
-}
-
-static void ast_bridge_call_thread_launch(void *data)
-{
- pthread_t thread;
- pthread_attr_t attr;
- struct sched_param sched;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
- pthread_attr_destroy(&attr);
- memset(&sched, 0, sizeof(sched));
- pthread_setschedparam(thread, SCHED_RR, &sched);
-}
-
-static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
-{
- int res;
- int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
- char tmp[256];
- char *message[5] = {NULL, NULL, NULL, NULL, NULL};
-
- snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
- message[0] = tmp;
- res = ast_adsi_load_session(chan, NULL, 0, 1);
- if (res == -1)
- return res;
- return ast_adsi_print(chan, message, justify, 1);
-}
-
-/*! \brief Notify metermaids that we've changed an extension */
-static void notify_metermaids(char *exten, char *context)
-{
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Notification of state change to metermaids %s@%s\n", exten, context);
-
- /* Send notification to devicestate subsystem */
- ast_device_state_changed("park:%s@%s", exten, context);
- return;
-}
-
-/*! \brief metermaids callback from devicestate.c */
-static int metermaidstate(const char *data)
-{
- int res = AST_DEVICE_INVALID;
- char *context = ast_strdupa(data);
- char *exten;
-
- exten = strsep(&context, "@");
- if (!context)
- return res;
-
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "Checking state of exten %s in context %s\n", exten, context);
-
- res = ast_exists_extension(NULL, context, exten, 1, NULL);
-
- if (!res)
- return AST_DEVICE_NOT_INUSE;
- else
- return AST_DEVICE_INUSE;
-}
-
-static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, char *orig_chan_name)
-{
- struct parkeduser *pu, *cur;
- int i, x = -1, parking_range;
- struct ast_context *con;
- const char *parkingexten;
-
- /* Allocate memory for parking data */
- if (!(pu = ast_calloc(1, sizeof(*pu))))
- return -1;
-
- /* Lock parking lot */
- ast_mutex_lock(&parking_lock);
- /* Check for channel variable PARKINGEXTEN */
- parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
- if (!ast_strlen_zero(parkingexten)) {
- if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) {
- ast_mutex_unlock(&parking_lock);
- free(pu);
- ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
- return 1; /* Continue execution if possible */
- }
- ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
- x = atoi(parkingexten);
- } else {
- /* Select parking space within range */
- parking_range = parking_stop - parking_start+1;
- for (i = 0; i < parking_range; i++) {
- x = (i + parking_offset) % parking_range + parking_start;
- cur = parkinglot;
- while(cur) {
- if (cur->parkingnum == x)
- break;
- cur = cur->next;
- }
- if (!cur)
- break;
- }
-
- if (!(i < parking_range)) {
- ast_log(LOG_WARNING, "No more parking spaces\n");
- free(pu);
- ast_mutex_unlock(&parking_lock);
- return -1;
- }
- /* Set pointer for next parking */
- if (parkfindnext)
- parking_offset = x - parking_start + 1;
- }
-
- chan->appl = "Parked Call";
- chan->data = NULL;
-
- pu->chan = chan;
-
- /* Put the parked channel on hold if we have two different channels */
- if (chan != peer) {
- ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
- S_OR(parkmohclass, NULL),
- !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
- }
-
- pu->start = ast_tvnow();
- pu->parkingnum = x;
- pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
- if (extout)
- *extout = x;
-
- if (peer)
- ast_copy_string(pu->peername, peer->name, sizeof(pu->peername));
-
- /* Remember what had been dialed, so that if the parking
- expires, we try to come back to the same place */
- ast_copy_string(pu->context, S_OR(chan->macrocontext, chan->context), sizeof(pu->context));
- ast_copy_string(pu->exten, S_OR(chan->macroexten, chan->exten), sizeof(pu->exten));
- pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
- pu->next = parkinglot;
- parkinglot = pu;
-
- /* If parking a channel directly, don't quiet yet get parking running on it */
- if (peer == chan)
- pu->notquiteyet = 1;
- ast_mutex_unlock(&parking_lock);
- /* Wake up the (presumably select()ing) thread */
- pthread_kill(parking_thread, SIGURG);
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d@%s. Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parking_con, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
-
- if (pu->parkingnum != -1)
- snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
- manager_event(EVENT_FLAG_CALL, "ParkedCall",
- "Exten: %s\r\n"
- "Channel: %s\r\n"
- "From: %s\r\n"
- "Timeout: %ld\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n",
- pu->parkingexten, pu->chan->name, peer ? peer->name : "",
- (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>")
- );
-
- if (peer && adsipark && ast_adsi_available(peer)) {
- adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
- ast_adsi_unload_session(peer);
- }
-
- con = ast_context_find(parking_con);
- if (!con)
- con = ast_context_create(NULL, parking_con, registrar);
- if (!con) /* Still no context? Bad */
- ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
- /* Tell the peer channel the number of the parking space */
- if (peer && ((pu->parkingnum != -1 && ast_strlen_zero(orig_chan_name)) || !strcasecmp(peer->name, orig_chan_name))) { /* Only say number if it's a number and the channel hasn't been masqueraded away */
- /* Make sure we don't start saying digits to the channel being parked */
- ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
- ast_say_digits(peer, pu->parkingnum, "", peer->language);
- ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
- }
- if (con) {
- if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, strdup(pu->parkingexten), ast_free, registrar))
- notify_metermaids(pu->parkingexten, parking_con);
- }
- if (pu->notquiteyet) {
- /* Wake up parking thread if we're really done */
- ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
- S_OR(parkmohclass, NULL),
- !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
- pu->notquiteyet = 0;
- pthread_kill(parking_thread, SIGURG);
- }
- return 0;
-}
-
-/*! \brief Park a call
- \note We put the user in the parking list, then wake up the parking thread to be sure it looks
- after these channels too */
-int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
-{
- return park_call_full(chan, peer, timeout, extout, NULL);
-}
-
-int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
-{
- struct ast_channel *chan;
- struct ast_frame *f;
- char *orig_chan_name = NULL;
-
- /* Make a new, fake channel that we'll use to masquerade in the real one */
- if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
- ast_log(LOG_WARNING, "Unable to create parked channel\n");
- return -1;
- }
-
- /* Make formats okay */
- chan->readformat = rchan->readformat;
- chan->writeformat = rchan->writeformat;
- ast_channel_masquerade(chan, rchan);
-
- /* Setup the extensions and such */
- set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
-
- /* Make the masq execute */
- f = ast_read(chan);
- if (f)
- ast_frfree(f);
-
- orig_chan_name = ast_strdupa(chan->name);
-
- park_call_full(chan, peer, timeout, extout, orig_chan_name);
-
- return 0;
-}
-
-
-#define FEATURE_RETURN_HANGUP -1
-#define FEATURE_RETURN_SUCCESSBREAK 0
-#define FEATURE_RETURN_PBX_KEEPALIVE AST_PBX_KEEPALIVE
-#define FEATURE_RETURN_NO_HANGUP_PEER AST_PBX_NO_HANGUP_PEER
-#define FEATURE_RETURN_PASSDIGITS 21
-#define FEATURE_RETURN_STOREDIGITS 22
-#define FEATURE_RETURN_SUCCESS 23
-#define FEATURE_RETURN_KEEPTRYING 24
-
-#define FEATURE_SENSE_CHAN (1 << 0)
-#define FEATURE_SENSE_PEER (1 << 1)
-
-/*! \brief
- * set caller and callee according to the direction
- */
-static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
- struct ast_channel *peer, struct ast_channel *chan, int sense)
-{
- if (sense == FEATURE_SENSE_PEER) {
- *caller = peer;
- *callee = chan;
- } else {
- *callee = peer;
- *caller = chan;
- }
-}
-
-/*! \brief support routing for one touch call parking */
-static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
-{
- struct ast_channel *parker;
- struct ast_channel *parkee;
- int res = 0;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- set_peers(&parker, &parkee, peer, chan, sense);
- /* Setup the exten/priority to be s/1 since we don't know
- where this call should return */
- strcpy(chan->exten, "s");
- chan->priority = 1;
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- if (!res)
- res = ast_park_call(parkee, parker, 0, NULL);
-
- ast_module_user_remove(u);
-
- if (!res) {
- if (sense == FEATURE_SENSE_CHAN)
- res = AST_PBX_NO_HANGUP_PEER;
- else
- res = AST_PBX_KEEPALIVE;
- }
- return res;
-
-}
-
-static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
-{
- char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
- int x = 0;
- size_t len;
- struct ast_channel *caller_chan, *callee_chan;
-
- if (!monitor_ok) {
- ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
- return -1;
- }
-
- if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
- monitor_ok = 0;
- ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
- return -1;
- }
-
- set_peers(&caller_chan, &callee_chan, peer, chan, sense);
-
- if (!ast_strlen_zero(courtesytone)) {
- if (ast_autoservice_start(callee_chan))
- return -1;
- if (ast_stream_and_wait(caller_chan, courtesytone, caller_chan->language, "")) {
- ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
- ast_autoservice_stop(callee_chan);
- return -1;
- }
- if (ast_autoservice_stop(callee_chan))
- return -1;
- }
-
- if (callee_chan->monitor) {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to stop recording call.\n", code);
- ast_monitor_stop(callee_chan, 1);
- return FEATURE_RETURN_SUCCESS;
- }
-
- if (caller_chan && callee_chan) {
- const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
- const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
-
- if (!touch_format)
- touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
-
- if (!touch_monitor)
- touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
-
- if (touch_monitor) {
- len = strlen(touch_monitor) + 50;
- args = alloca(len);
- touch_filename = alloca(len);
- snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
- snprintf(args, len, "%s|%s|m", (touch_format) ? touch_format : "wav", touch_filename);
- } else {
- caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
- callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
- len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
- args = alloca(len);
- touch_filename = alloca(len);
- snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
- snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename);
- }
-
- for( x = 0; x < strlen(args); x++) {
- if (args[x] == '/')
- args[x] = '-';
- }
-
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to record call. filename: %s\n", code, args);
-
- pbx_exec(callee_chan, monitor_app, args);
- pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
- pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
-
- return FEATURE_RETURN_SUCCESS;
- }
-
- ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
- return -1;
-}
-
-static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
-{
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to disconnect call.\n", code);
- return FEATURE_RETURN_HANGUP;
-}
-
-static int finishup(struct ast_channel *chan)
-{
- ast_indicate(chan, AST_CONTROL_UNHOLD);
-
- return ast_autoservice_stop(chan);
-}
-
-/*! \brief Find the context for the transfer */
-static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
-{
- const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
- if (ast_strlen_zero(s))
- s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
- if (ast_strlen_zero(s)) /* Use the non-macro context to transfer the call XXX ? */
- s = transferer->macrocontext;
- if (ast_strlen_zero(s))
- s = transferer->context;
- return s;
-}
-
-static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
-{
- struct ast_channel *transferer;
- struct ast_channel *transferee;
- const char *transferer_real_context;
- char xferto[256];
- int res;
-
- set_peers(&transferer, &transferee, peer, chan, sense);
- transferer_real_context = real_ctx(transferer, transferee);
- /* Start autoservice on chan while we talk to the originator */
- ast_autoservice_start(transferee);
- ast_indicate(transferee, AST_CONTROL_HOLD);
-
- memset(xferto, 0, sizeof(xferto));
-
- /* Transfer */
- res = ast_stream_and_wait(transferer, "pbx-transfer", transferer->language, AST_DIGIT_ANY);
- if (res < 0) {
- finishup(transferee);
- return -1; /* error ? */
- }
- if (res > 0) /* If they've typed a digit already, handle it */
- xferto[0] = (char) res;
-
- ast_stopstream(transferer);
- res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
- if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
- finishup(transferee);
- return res;
- }
- if (!strcmp(xferto, ast_parking_ext())) {
- res = finishup(transferee);
- if (res)
- res = -1;
- else if (!ast_park_call(transferee, transferer, 0, NULL)) { /* success */
- /* We return non-zero, but tell the PBX not to hang the channel when
- the thread dies -- We have to be careful now though. We are responsible for
- hanging up the channel, else it will never be hung up! */
-
- return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER;
- } else {
- ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
- }
- /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
- } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
- pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", transferee->name);
- pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
- res=finishup(transferee);
- if (!transferer->cdr) {
- transferer->cdr=ast_cdr_alloc();
- if (transferer) {
- ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
- ast_cdr_start(transferer->cdr);
- }
- }
- if (transferer->cdr) {
- ast_cdr_setdestchan(transferer->cdr, transferee->name);
- ast_cdr_setapp(transferer->cdr, "BLINDTRANSFER","");
- }
- if (!transferee->pbx) {
- /* Doh! Use our handy async_goto functions */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n"
- ,transferee->name, xferto, transferer_real_context);
- if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
- ast_log(LOG_WARNING, "Async goto failed :-(\n");
- res = -1;
- } else {
- /* Set the channel's new extension, since it exists, using transferer context */
- set_c_e_p(transferee, transferer_real_context, xferto, 0);
- }
- check_goto_on_transfer(transferer);
- return res;
- } else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
- }
- if (ast_stream_and_wait(transferer, xferfailsound, transferer->language, AST_DIGIT_ANY) < 0 ) {
- finishup(transferee);
- return -1;
- }
- ast_stopstream(transferer);
- res = finishup(transferee);
- if (res) {
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Hungup during autoservice stop on '%s'\n", transferee->name);
- return res;
- }
- return FEATURE_RETURN_SUCCESS;
-}
-
-static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
-{
- if (ast_channel_make_compatible(c, newchan) < 0) {
- ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
- c->name, newchan->name);
- ast_hangup(newchan);
- return -1;
- }
- return 0;
-}
-
-static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
-{
- struct ast_channel *transferer;
- struct ast_channel *transferee;
- const char *transferer_real_context;
- char xferto[256] = "";
- int res;
- int outstate=0;
- struct ast_channel *newchan;
- struct ast_channel *xferchan;
- struct ast_bridge_thread_obj *tobj;
- struct ast_bridge_config bconfig;
- struct ast_frame *f;
- int l;
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
- set_peers(&transferer, &transferee, peer, chan, sense);
- transferer_real_context = real_ctx(transferer, transferee);
- /* Start autoservice on chan while we talk to the originator */
- ast_autoservice_start(transferee);
- ast_indicate(transferee, AST_CONTROL_HOLD);
-
- /* Transfer */
- res = ast_stream_and_wait(transferer, "pbx-transfer", transferer->language, AST_DIGIT_ANY);
- if (res < 0) {
- finishup(transferee);
- return res;
- }
- if (res > 0) /* If they've typed a digit already, handle it */
- xferto[0] = (char) res;
-
- /* this is specific of atxfer */
- res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
- if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
- finishup(transferee);
- return res;
- }
- if (res == 0) {
- ast_log(LOG_WARNING, "Did not read data.\n");
- finishup(transferee);
- if (ast_stream_and_wait(transferer, "beeperr", transferer->language, ""))
- return -1;
- return FEATURE_RETURN_SUCCESS;
- }
-
- /* valid extension, res == 1 */
- if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
- ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
- finishup(transferee);
- if (ast_stream_and_wait(transferer, "beeperr", transferer->language, ""))
- return -1;
- return FEATURE_RETURN_SUCCESS;
- }
-
- l = strlen(xferto);
- snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
- newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats),
- xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, transferer->language);
- ast_indicate(transferer, -1);
- if (!newchan) {
- finishup(transferee);
- /* any reason besides user requested cancel and busy triggers the failed sound */
- if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
- ast_stream_and_wait(transferer, xferfailsound, transferer->language, ""))
- return -1;
- return FEATURE_RETURN_SUCCESS;
- }
-
- if (check_compat(transferer, newchan)) {
- /* we do mean transferee here, NOT transferer */
- finishup(transferee);
- return -1;
- }
- memset(&bconfig,0,sizeof(struct ast_bridge_config));
- ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
- ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
- res = ast_bridge_call(transferer, newchan, &bconfig);
- if (newchan->_softhangup || !transferer->_softhangup) {
- ast_hangup(newchan);
- if (ast_stream_and_wait(transferer, xfersound, transferer->language, ""))
- ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
- finishup(transferee);
- transferer->_softhangup = 0;
- return FEATURE_RETURN_SUCCESS;
- }
-
- if (check_compat(transferee, newchan)) {
- finishup(transferee);
- return -1;
- }
-
- ast_indicate(transferee, AST_CONTROL_UNHOLD);
-
- if ((ast_autoservice_stop(transferee) < 0)
- || (ast_waitfordigit(transferee, 100) < 0)
- || (ast_waitfordigit(newchan, 100) < 0)
- || ast_check_hangup(transferee)
- || ast_check_hangup(newchan)) {
- ast_hangup(newchan);
- return -1;
- }
-
- xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
- if (!xferchan) {
- ast_hangup(newchan);
- return -1;
- }
- /* Make formats okay */
- xferchan->visible_indication = transferer->visible_indication;
- xferchan->readformat = transferee->readformat;
- xferchan->writeformat = transferee->writeformat;
- ast_channel_masquerade(xferchan, transferee);
- ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
- xferchan->_state = AST_STATE_UP;
- ast_clear_flag(xferchan, AST_FLAGS_ALL);
- xferchan->_softhangup = 0;
-
- if ((f = ast_read(xferchan)))
- ast_frfree(f);
-
- newchan->_state = AST_STATE_UP;
- ast_clear_flag(newchan, AST_FLAGS_ALL);
- newchan->_softhangup = 0;
-
- tobj = ast_calloc(1, sizeof(struct ast_bridge_thread_obj));
- if (!tobj) {
- ast_hangup(xferchan);
- ast_hangup(newchan);
- return -1;
- }
- tobj->chan = newchan;
- tobj->peer = xferchan;
- tobj->bconfig = *config;
-
- if (ast_stream_and_wait(newchan, xfersound, newchan->language, ""))
- ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
- ast_bridge_call_thread_launch(tobj);
- return -1; /* XXX meaning the channel is bridged ? */
-}
-
-
-/* add atxfer and automon as undefined so you can only use em if you configure them */
-#define FEATURES_COUNT (sizeof(builtin_features) / sizeof(builtin_features[0]))
-
-AST_RWLOCK_DEFINE_STATIC(features_lock);
-
-static struct ast_call_feature builtin_features[] =
- {
- { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
- { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
- { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
- { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
- { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
-};
-
-
-static AST_LIST_HEAD_STATIC(feature_list,ast_call_feature);
-
-/*! \brief register new feature into feature_list*/
-void ast_register_feature(struct ast_call_feature *feature)
-{
- if (!feature) {
- ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
- return;
- }
-
- AST_LIST_LOCK(&feature_list);
- AST_LIST_INSERT_HEAD(&feature_list,feature,feature_entry);
- AST_LIST_UNLOCK(&feature_list);
-
- if (option_verbose >= 2)
- ast_verbose(VERBOSE_PREFIX_2 "Registered Feature '%s'\n",feature->sname);
-}
-
-/*! \brief unregister feature from feature_list */
-void ast_unregister_feature(struct ast_call_feature *feature)
-{
- if (!feature)
- return;
-
- AST_LIST_LOCK(&feature_list);
- AST_LIST_REMOVE(&feature_list,feature,feature_entry);
- AST_LIST_UNLOCK(&feature_list);
- free(feature);
-}
-
-/*! \brief Remove all features in the list */
-static void ast_unregister_features(void)
-{
- struct ast_call_feature *feature;
-
- AST_LIST_LOCK(&feature_list);
- while ((feature = AST_LIST_REMOVE_HEAD(&feature_list,feature_entry)))
- free(feature);
- AST_LIST_UNLOCK(&feature_list);
-}
-
-/*! \brief find a feature by name */
-static struct ast_call_feature *find_dynamic_feature(const char *name)
-{
- struct ast_call_feature *tmp;
-
- AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
- if (!strcasecmp(tmp->sname, name))
- break;
- }
-
- return tmp;
-}
-
-/*! \brief exec an app by feature */
-static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
-{
- struct ast_app *app;
- struct ast_call_feature *feature = data;
- struct ast_channel *work, *idle;
- int res;
-
- if (!feature) { /* shouldn't ever happen! */
- ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
- return -1;
- }
-
- if (sense == FEATURE_SENSE_CHAN) {
- if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
- return FEATURE_RETURN_KEEPTRYING;
- if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
- work = chan;
- idle = peer;
- } else {
- work = peer;
- idle = chan;
- }
- } else {
- if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
- return FEATURE_RETURN_KEEPTRYING;
- if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
- work = peer;
- idle = chan;
- } else {
- work = chan;
- idle = peer;
- }
- }
-
- if (!(app = pbx_findapp(feature->app))) {
- ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
- return -2;
- }
-
- ast_autoservice_start(idle);
-
- if (!ast_strlen_zero(feature->moh_class))
- ast_moh_start(idle, feature->moh_class, NULL);
-
- res = pbx_exec(work, app, feature->app_args);
-
- if (!ast_strlen_zero(feature->moh_class))
- ast_moh_stop(idle);
-
- ast_autoservice_stop(idle);
-
- if (res == AST_PBX_KEEPALIVE)
- return FEATURE_RETURN_PBX_KEEPALIVE;
- else if (res == AST_PBX_NO_HANGUP_PEER)
- return FEATURE_RETURN_NO_HANGUP_PEER;
- else if (res)
- return FEATURE_RETURN_SUCCESSBREAK;
-
- return FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
-}
-
-static void unmap_features(void)
-{
- int x;
-
- ast_rwlock_wrlock(&features_lock);
- for (x = 0; x < FEATURES_COUNT; x++)
- strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
- ast_rwlock_unlock(&features_lock);
-}
-
-static int remap_feature(const char *name, const char *value)
-{
- int x, res = -1;
-
- ast_rwlock_wrlock(&features_lock);
- for (x = 0; x < FEATURES_COUNT; x++) {
- if (strcasecmp(builtin_features[x].sname, name))
- continue;
-
- ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
- res = 0;
- break;
- }
- ast_rwlock_unlock(&features_lock);
-
- return res;
-}
-
-static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
-{
- int x;
- struct ast_flags features;
- int res = FEATURE_RETURN_PASSDIGITS;
- struct ast_call_feature *feature;
- const char *dynamic_features;
- char *tmp, *tok;
-
- if (sense == FEATURE_SENSE_CHAN) {
- ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
- dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
- } else {
- ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
- dynamic_features = pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES");
- }
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d dynamic=%s\n", chan->name, peer->name, code, sense, features.flags, dynamic_features);
-
- ast_rwlock_rdlock(&features_lock);
- for (x = 0; x < FEATURES_COUNT; x++) {
- if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
- !ast_strlen_zero(builtin_features[x].exten)) {
- /* Feature is up for consideration */
- if (!strcmp(builtin_features[x].exten, code)) {
- res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
- break;
- } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
- if (res == FEATURE_RETURN_PASSDIGITS)
- res = FEATURE_RETURN_STOREDIGITS;
- }
- }
- }
- ast_rwlock_unlock(&features_lock);
-
- if (ast_strlen_zero(dynamic_features))
- return res;
-
- tmp = ast_strdupa(dynamic_features);
-
- while ((tok = strsep(&tmp, "#"))) {
- AST_LIST_LOCK(&feature_list);
- if (!(feature = find_dynamic_feature(tok))) {
- AST_LIST_UNLOCK(&feature_list);
- continue;
- }
-
- /* Feature is up for consideration */
- if (!strcmp(feature->exten, code)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
- res = feature->operation(chan, peer, config, code, sense, feature);
- if (res != FEATURE_RETURN_KEEPTRYING) {
- AST_LIST_UNLOCK(&feature_list);
- break;
- }
- res = FEATURE_RETURN_PASSDIGITS;
- } else if (!strncmp(feature->exten, code, strlen(code)))
- res = FEATURE_RETURN_STOREDIGITS;
-
- AST_LIST_UNLOCK(&feature_list);
- }
-
- return res;
-}
-
-static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
-{
- int x;
-
- ast_clear_flag(config, AST_FLAGS_ALL);
-
- ast_rwlock_rdlock(&features_lock);
- for (x = 0; x < FEATURES_COUNT; x++) {
- if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
- continue;
-
- if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
-
- if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
- }
- ast_rwlock_unlock(&features_lock);
-
- if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
- const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
-
- if (dynamic_features) {
- char *tmp = ast_strdupa(dynamic_features);
- char *tok;
- struct ast_call_feature *feature;
-
- /* while we have a feature */
- while ((tok = strsep(&tmp, "#"))) {
- AST_LIST_LOCK(&feature_list);
- if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
- if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
- if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
- }
- AST_LIST_UNLOCK(&feature_list);
- }
- }
- }
-}
-
-/*! \todo XXX Check - this is very similar to the code in channel.c */
-static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, const char *language)
-{
- int state = 0;
- int cause = 0;
- int to;
- struct ast_channel *chan;
- struct ast_channel *monitor_chans[2];
- struct ast_channel *active_channel;
- int res = 0, ready = 0;
-
- if ((chan = ast_request(type, format, data, &cause))) {
- ast_set_callerid(chan, cid_num, cid_name, cid_num);
- ast_string_field_set(chan, language, language);
- ast_channel_inherit_variables(caller, chan);
- pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
- if (!chan->cdr) {
- chan->cdr=ast_cdr_alloc();
- if (chan->cdr) {
- ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
- ast_cdr_start(chan->cdr);
- }
- }
-
- if (!ast_call(chan, data, timeout)) {
- struct timeval started;
- int x, len = 0;
- char *disconnect_code = NULL, *dialed_code = NULL;
-
- ast_indicate(caller, AST_CONTROL_RINGING);
- /* support dialing of the featuremap disconnect code while performing an attended tranfer */
- ast_rwlock_rdlock(&features_lock);
- for (x = 0; x < FEATURES_COUNT; x++) {
- if (strcasecmp(builtin_features[x].sname, "disconnect"))
- continue;
-
- disconnect_code = builtin_features[x].exten;
- len = strlen(disconnect_code) + 1;
- dialed_code = alloca(len);
- memset(dialed_code, 0, len);
- break;
- }
- ast_rwlock_unlock(&features_lock);
- x = 0;
- started = ast_tvnow();
- to = timeout;
- while (!ast_check_hangup(caller) && timeout && (chan->_state != AST_STATE_UP)) {
- struct ast_frame *f = NULL;
-
- monitor_chans[0] = caller;
- monitor_chans[1] = chan;
- active_channel = ast_waitfor_n(monitor_chans, 2, &to);
-
- /* see if the timeout has been violated */
- if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
- state = AST_CONTROL_UNHOLD;
- ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
- break; /*doh! timeout*/
- }
-
- if (!active_channel)
- continue;
-
- if (chan && (chan == active_channel)){
- f = ast_read(chan);
- if (f == NULL) { /*doh! where'd he go?*/
- state = AST_CONTROL_HANGUP;
- res = 0;
- break;
- }
-
- if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
- if (f->subclass == AST_CONTROL_RINGING) {
- state = f->subclass;
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", chan->name);
- ast_indicate(caller, AST_CONTROL_RINGING);
- } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
- state = f->subclass;
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", chan->name);
- ast_indicate(caller, AST_CONTROL_BUSY);
- ast_frfree(f);
- f = NULL;
- break;
- } else if (f->subclass == AST_CONTROL_ANSWER) {
- /* This is what we are hoping for */
- state = f->subclass;
- ast_frfree(f);
- f = NULL;
- ready=1;
- break;
- } else if (f->subclass != -1) {
- ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
- }
- /* else who cares */
- }
-
- } else if (caller && (active_channel == caller)) {
- f = ast_read(caller);
- if (f == NULL) { /*doh! where'd he go?*/
- if (caller->_softhangup && !chan->_softhangup) {
- /* make this a blind transfer */
- ready = 1;
- break;
- }
- state = AST_CONTROL_HANGUP;
- res = 0;
- break;
- }
-
- if (f->frametype == AST_FRAME_DTMF) {
- dialed_code[x++] = f->subclass;
- dialed_code[x] = '\0';
- if (strlen(dialed_code) == len) {
- x = 0;
- } else if (x && strncmp(dialed_code, disconnect_code, x)) {
- x = 0;
- dialed_code[x] = '\0';
- }
- if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
- /* Caller Canceled the call */
- state = AST_CONTROL_UNHOLD;
- ast_frfree(f);
- f = NULL;
- break;
- }
- }
- }
- if (f)
- ast_frfree(f);
- } /* end while */
- } else
- ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
- } else {
- ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
- switch(cause) {
- case AST_CAUSE_BUSY:
- state = AST_CONTROL_BUSY;
- break;
- case AST_CAUSE_CONGESTION:
- state = AST_CONTROL_CONGESTION;
- break;
- }
- }
-
- ast_indicate(caller, -1);
- if (chan && ready) {
- if (chan->_state == AST_STATE_UP)
- state = AST_CONTROL_ANSWER;
- res = 0;
- } else if(chan) {
- res = -1;
- ast_hangup(chan);
- chan = NULL;
- } else {
- res = -1;
- }
-
- if (outstate)
- *outstate = state;
-
- if (chan && res <= 0) {
- if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
- char tmp[256];
- ast_cdr_init(chan->cdr, chan);
- snprintf(tmp, 256, "%s/%s", type, (char *)data);
- ast_cdr_setapp(chan->cdr,"Dial",tmp);
- ast_cdr_update(chan);
- ast_cdr_start(chan->cdr);
- ast_cdr_end(chan->cdr);
- /* If the cause wasn't handled properly */
- if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
- ast_cdr_failed(chan->cdr);
- } else {
- ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
- }
- }
-
- return chan;
-}
-
-int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
-{
- /* Copy voice back and forth between the two channels. Give the peer
- the ability to transfer calls with '#<extension' syntax. */
- struct ast_frame *f;
- struct ast_channel *who;
- char chan_featurecode[FEATURE_MAX_LEN + 1]="";
- char peer_featurecode[FEATURE_MAX_LEN + 1]="";
- int res;
- int diff;
- int hasfeatures=0;
- int hadfeatures=0;
- struct ast_option_header *aoh;
- struct ast_bridge_config backup_config;
- struct ast_cdr *bridge_cdr;
-
- memset(&backup_config, 0, sizeof(backup_config));
-
- config->start_time = ast_tvnow();
-
- if (chan && peer) {
- pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
- pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
- } else if (chan)
- pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
-
- if (monitor_ok) {
- const char *monitor_exec;
- struct ast_channel *src = NULL;
- if (!monitor_app) {
- if (!(monitor_app = pbx_findapp("Monitor")))
- monitor_ok=0;
- }
- if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
- src = chan;
- else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
- src = peer;
- if (monitor_app && src) {
- char *tmp = ast_strdupa(monitor_exec);
- pbx_exec(src, monitor_app, tmp);
- }
- }
-
- set_config_flags(chan, peer, config);
- config->firstpass = 1;
-
- /* Answer if need be */
- if (ast_answer(chan))
- return -1;
- peer->appl = "Bridged Call";
- peer->data = chan->name;
-
- /* copy the userfield from the B-leg to A-leg if applicable */
- if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
- char tmp[256];
- if (!ast_strlen_zero(chan->cdr->userfield)) {
- snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
- ast_cdr_appenduserfield(chan, tmp);
- } else
- ast_cdr_setuserfield(chan, peer->cdr->userfield);
- /* free the peer's cdr without ast_cdr_free complaining */
- free(peer->cdr);
- peer->cdr = NULL;
- }
-
- for (;;) {
- struct ast_channel *other; /* used later */
-
- res = ast_channel_bridge(chan, peer, config, &f, &who);
-
- if (config->feature_timer) {
- /* Update time limit for next pass */
- diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
- config->feature_timer -= diff;
- if (hasfeatures) {
- /* Running on backup config, meaning a feature might be being
- activated, but that's no excuse to keep things going
- indefinitely! */
- if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Timed out, realtime this time!\n");
- config->feature_timer = 0;
- who = chan;
- if (f)
- ast_frfree(f);
- f = NULL;
- res = 0;
- } else if (config->feature_timer <= 0) {
- /* Not *really* out of time, just out of time for
- digits to come in for features. */
- if (option_debug)
- ast_log(LOG_DEBUG, "Timed out for feature!\n");
- if (!ast_strlen_zero(peer_featurecode)) {
- ast_dtmf_stream(chan, peer, peer_featurecode, 0);
- memset(peer_featurecode, 0, sizeof(peer_featurecode));
- }
- if (!ast_strlen_zero(chan_featurecode)) {
- ast_dtmf_stream(peer, chan, chan_featurecode, 0);
- memset(chan_featurecode, 0, sizeof(chan_featurecode));
- }
- if (f)
- ast_frfree(f);
- hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
- if (!hasfeatures) {
- /* Restore original (possibly time modified) bridge config */
- memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
- memset(&backup_config, 0, sizeof(backup_config));
- }
- hadfeatures = hasfeatures;
- /* Continue as we were */
- continue;
- } else if (!f) {
- /* The bridge returned without a frame and there is a feature in progress.
- * However, we don't think the feature has quite yet timed out, so just
- * go back into the bridge. */
- continue;
- }
- } else {
- if (config->feature_timer <=0) {
- /* We ran out of time */
- config->feature_timer = 0;
- who = chan;
- if (f)
- ast_frfree(f);
- f = NULL;
- res = 0;
- }
- }
- }
- if (res < 0) {
- if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer))
- ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
- return -1;
- }
-
- if (!f || (f->frametype == AST_FRAME_CONTROL &&
- (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY ||
- f->subclass == AST_CONTROL_CONGESTION ) ) ) {
- res = -1;
- break;
- }
- /* many things should be sent to the 'other' channel */
- other = (who == chan) ? peer : chan;
- if (f->frametype == AST_FRAME_CONTROL) {
- switch (f->subclass) {
- case AST_CONTROL_RINGING:
- case AST_CONTROL_FLASH:
- case -1:
- ast_indicate(other, f->subclass);
- break;
- case AST_CONTROL_HOLD:
- case AST_CONTROL_UNHOLD:
- ast_indicate_data(other, f->subclass, f->data, f->datalen);
- break;
- case AST_CONTROL_OPTION:
- aoh = f->data;
- /* Forward option Requests */
- if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
- ast_channel_setoption(other, ntohs(aoh->option), aoh->data,
- f->datalen - sizeof(struct ast_option_header), 0);
- }
- break;
- }
- } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
- /* eat it */
- } else if (f->frametype == AST_FRAME_DTMF) {
- char *featurecode;
- int sense;
-
- hadfeatures = hasfeatures;
- /* This cannot overrun because the longest feature is one shorter than our buffer */
- if (who == chan) {
- sense = FEATURE_SENSE_CHAN;
- featurecode = chan_featurecode;
- } else {
- sense = FEATURE_SENSE_PEER;
- featurecode = peer_featurecode;
- }
- /*! append the event to featurecode. we rely on the string being zero-filled, and
- * not overflowing it.
- * \todo XXX how do we guarantee the latter ?
- */
- featurecode[strlen(featurecode)] = f->subclass;
- /* Get rid of the frame before we start doing "stuff" with the channels */
- ast_frfree(f);
- f = NULL;
- config->feature_timer = backup_config.feature_timer;
- res = ast_feature_interpret(chan, peer, config, featurecode, sense);
- switch(res) {
- case FEATURE_RETURN_PASSDIGITS:
- ast_dtmf_stream(other, who, featurecode, 0);
- /* Fall through */
- case FEATURE_RETURN_SUCCESS:
- memset(featurecode, 0, sizeof(chan_featurecode));
- break;
- }
- if (res >= FEATURE_RETURN_PASSDIGITS) {
- res = 0;
- } else
- break;
- hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
- if (hadfeatures && !hasfeatures) {
- /* Restore backup */
- memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
- memset(&backup_config, 0, sizeof(struct ast_bridge_config));
- } else if (hasfeatures) {
- if (!hadfeatures) {
- /* Backup configuration */
- memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
- /* Setup temporary config options */
- config->play_warning = 0;
- ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
- ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
- config->warning_freq = 0;
- config->warning_sound = NULL;
- config->end_sound = NULL;
- config->start_sound = NULL;
- config->firstpass = 0;
- }
- config->start_time = ast_tvnow();
- config->feature_timer = featuredigittimeout;
- if (option_debug)
- ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
- }
- }
- if (f)
- ast_frfree(f);
-
- }
-
- /* arrange the cdrs */
- bridge_cdr = ast_cdr_alloc();
- if (bridge_cdr) {
- if (chan->cdr && peer->cdr) { /* both of them? merge */
- ast_channel_lock(chan); /* lock the channel before modifing cdrs */
- ast_cdr_init(bridge_cdr,chan); /* seems more logicaller to use the destination as a base, but, really, it's random */
- ast_cdr_start(bridge_cdr); /* now is the time to start */
-
- /* absorb the channel cdr */
- ast_cdr_merge(bridge_cdr, chan->cdr);
- if (!ast_test_flag(chan->cdr, AST_CDR_FLAG_LOCKED))
- ast_cdr_discard(chan->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
-
- chan->cdr = NULL; /* remove pointer to freed memory before releasing the lock */
-
- ast_channel_unlock(chan);
-
- /* absorb the peer cdr */
- ast_channel_lock(peer);
- ast_cdr_merge(bridge_cdr, peer->cdr);
- if (!ast_test_flag(peer->cdr, AST_CDR_FLAG_LOCKED))
- ast_cdr_discard(peer->cdr); /* if locked cdrs are in peer, they are taken over in the merge */
-
- peer->cdr = NULL;
- ast_channel_unlock(peer);
-
- ast_channel_lock(chan);
- chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
- ast_channel_unlock(chan);
-
- } else if (chan->cdr) {
-
- ast_channel_lock(chan); /* Lock before modifying CDR */
- /* take the cdr from the channel - literally */
- ast_cdr_init(bridge_cdr,chan);
- /* absorb this data */
- ast_cdr_merge(bridge_cdr, chan->cdr);
- if (!ast_test_flag(chan->cdr, AST_CDR_FLAG_LOCKED))
- ast_cdr_discard(chan->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
- chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
- ast_channel_unlock(chan);
- } else if (peer->cdr) {
- ast_channel_lock(peer); /* Lock before modifying CDR */
- /* take the cdr from the peer - literally */
- ast_cdr_init(bridge_cdr,peer);
- /* absorb this data */
- ast_cdr_merge(bridge_cdr, peer->cdr);
- if (!ast_test_flag(peer->cdr, AST_CDR_FLAG_LOCKED))
- ast_cdr_discard(peer->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
- peer->cdr = NULL;
- peer->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
- ast_channel_unlock(peer);
- } else {
- ast_channel_lock(chan); /* Lock before modifying CDR */
- /* make up a new cdr */
- ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */
- chan->cdr = bridge_cdr; /* */
- ast_channel_unlock(chan);
- }
- if (ast_strlen_zero(bridge_cdr->dstchannel)) {
- if (strcmp(bridge_cdr->channel, peer->name) != 0)
- ast_cdr_setdestchan(bridge_cdr, peer->name);
- else
- ast_cdr_setdestchan(bridge_cdr, chan->name);
- }
- }
- return res;
-}
-
-static void post_manager_event(const char *s, char *parkingexten, struct ast_channel *chan)
-{
- manager_event(EVENT_FLAG_CALL, s,
- "Exten: %s\r\n"
- "Channel: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n\r\n",
- parkingexten,
- chan->name,
- S_OR(chan->cid.cid_num, "<unknown>"),
- S_OR(chan->cid.cid_name, "<unknown>")
- );
-}
-
-/*! \brief Take care of parked calls and unpark them if needed */
-static void *do_parking_thread(void *ignore)
-{
- fd_set rfds, efds; /* results from previous select, to be preserved across loops. */
- FD_ZERO(&rfds);
- FD_ZERO(&efds);
-
- for (;;) {
- struct parkeduser *pu, *pl, *pt = NULL;
- int ms = -1; /* select timeout, uninitialized */
- int max = -1; /* max fd, none there yet */
- fd_set nrfds, nefds; /* args for the next select */
- FD_ZERO(&nrfds);
- FD_ZERO(&nefds);
-
- ast_mutex_lock(&parking_lock);
- pl = NULL;
- pu = parkinglot;
- /* navigate the list with prev-cur pointers to support removals */
- while (pu) {
- struct ast_channel *chan = pu->chan; /* shorthand */
- int tms; /* timeout for this item */
- int x; /* fd index in channel */
- struct ast_context *con;
-
- if (pu->notquiteyet) { /* Pretend this one isn't here yet */
- pl = pu;
- pu = pu->next;
- continue;
- }
- tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
- if (tms > pu->parkingtime) {
- ast_indicate(chan, AST_CONTROL_UNHOLD);
- /* Get chan, exten from derived kludge */
- if (pu->peername[0]) {
- char *peername = ast_strdupa(pu->peername);
- char *cp = strrchr(peername, '-');
- if (cp)
- *cp = 0;
- con = ast_context_find(parking_con_dial);
- if (!con) {
- con = ast_context_create(NULL, parking_con_dial, registrar);
- if (!con)
- ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
- }
- if (con) {
- char returnexten[AST_MAX_EXTENSION];
- snprintf(returnexten, sizeof(returnexten), "%s|30|t", peername);
- ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), ast_free, registrar);
- }
- set_c_e_p(chan, parking_con_dial, peername, 1);
- } else {
- /* They've been waiting too long, send them back to where they came. Theoretically they
- should have their original extensions and such, but we copy to be on the safe side */
- set_c_e_p(chan, pu->context, pu->exten, pu->priority);
- }
-
- post_manager_event("ParkedCallTimeOut", pu->parkingexten, chan);
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Timeout for %s parked on %d. Returning to %s,%s,%d\n", chan->name, pu->parkingnum, chan->context, chan->exten, chan->priority);
- /* Start up the PBX, or hang them up */
- if (ast_pbx_start(chan)) {
- ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
- ast_hangup(chan);
- }
- /* And take them out of the parking lot */
- if (pl)
- pl->next = pu->next;
- else
- parkinglot = pu->next;
- pt = pu;
- pu = pu->next;
- con = ast_context_find(parking_con);
- if (con) {
- if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
- ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
- else
- notify_metermaids(pt->parkingexten, parking_con);
- } else
- ast_log(LOG_WARNING, "Whoa, no parking context?\n");
- free(pt);
- } else { /* still within parking time, process descriptors */
- for (x = 0; x < AST_MAX_FDS; x++) {
- struct ast_frame *f;
-
- if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
- continue; /* nothing on this descriptor */
-
- if (FD_ISSET(chan->fds[x], &efds))
- ast_set_flag(chan, AST_FLAG_EXCEPTION);
- else
- ast_clear_flag(chan, AST_FLAG_EXCEPTION);
- chan->fdno = x;
-
- /* See if they need servicing */
- f = ast_read(chan);
- if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)) {
- if (f)
- ast_frfree(f);
- post_manager_event("ParkedCallGiveUp", pu->parkingexten, chan);
-
- /* There's a problem, hang them up*/
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", chan->name);
- ast_hangup(chan);
- /* And take them out of the parking lot */
- if (pl)
- pl->next = pu->next;
- else
- parkinglot = pu->next;
- pt = pu;
- pu = pu->next;
- con = ast_context_find(parking_con);
- if (con) {
- if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
- ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
- else
- notify_metermaids(pt->parkingexten, parking_con);
- } else
- ast_log(LOG_WARNING, "Whoa, no parking context?\n");
- free(pt);
- break;
- } else {
- /*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
- ast_frfree(f);
- if (pu->moh_trys < 3 && !chan->generatordata) {
- if (option_debug)
- ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source. Restarting.\n");
- ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
- S_OR(parkmohclass, NULL),
- !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
- pu->moh_trys++;
- }
- goto std; /*! \todo XXX Ick: jumping into an else statement??? XXX */
- }
-
- } /* end for */
- if (x >= AST_MAX_FDS) {
-std: for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
- if (chan->fds[x] > -1) {
- FD_SET(chan->fds[x], &nrfds);
- FD_SET(chan->fds[x], &nefds);
- if (chan->fds[x] > max)
- max = chan->fds[x];
- }
- }
- /* Keep track of our shortest wait */
- if (tms < ms || ms < 0)
- ms = tms;
- pl = pu;
- pu = pu->next;
- }
- }
- } /* end while */
- ast_mutex_unlock(&parking_lock);
- rfds = nrfds;
- efds = nefds;
- {
- struct timeval tv = ast_samp2tv(ms, 1000);
- /* Wait for something to happen */
- ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
- }
- pthread_testcancel();
- }
- return NULL; /* Never reached */
-}
-
-/*! \brief Park a call */
-static int park_call_exec(struct ast_channel *chan, void *data)
-{
- /* Cache the original channel name in case we get masqueraded in the middle
- * of a park--it is still theoretically possible for a transfer to happen before
- * we get here, but it is _really_ unlikely */
- char *orig_chan_name = ast_strdupa(chan->name);
- char orig_exten[AST_MAX_EXTENSION];
- int orig_priority = chan->priority;
-
- /* Data is unused at the moment but could contain a parking
- lot context eventually */
- int res = 0;
- struct ast_module_user *u;
-
- u = ast_module_user_add(chan);
-
- ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
-
- /* Setup the exten/priority to be s/1 since we don't know
- where this call should return */
- strcpy(chan->exten, "s");
- chan->priority = 1;
- /* Answer if call is not up */
- if (chan->_state != AST_STATE_UP)
- res = ast_answer(chan);
- /* Sleep to allow VoIP streams to settle down */
- if (!res)
- res = ast_safe_sleep(chan, 1000);
- /* Park the call */
- if (!res) {
- res = park_call_full(chan, chan, 0, NULL, orig_chan_name);
- /* Continue on in the dialplan */
- if (res == 1) {
- ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
- chan->priority = orig_priority;
- res = 0;
- } else if (!res)
- res = AST_PBX_KEEPALIVE;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-/*! \brief Pickup parked call */
-static int park_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- struct ast_module_user *u;
- struct ast_channel *peer=NULL;
- struct parkeduser *pu, *pl=NULL;
- struct ast_context *con;
-
- int park;
- struct ast_bridge_config config;
-
- if (!data) {
- ast_log(LOG_WARNING, "Parkedcall requires an argument (extension number)\n");
- return -1;
- }
-
- u = ast_module_user_add(chan);
-
- park = atoi((char *)data);
- ast_mutex_lock(&parking_lock);
- pu = parkinglot;
- while(pu) {
- if (pu->parkingnum == park) {
- if (pl)
- pl->next = pu->next;
- else
- parkinglot = pu->next;
- break;
- }
- pl = pu;
- pu = pu->next;
- }
- ast_mutex_unlock(&parking_lock);
- if (pu) {
- peer = pu->chan;
- con = ast_context_find(parking_con);
- if (con) {
- if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
- ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
- else
- notify_metermaids(pu->parkingexten, parking_con);
- } else
- ast_log(LOG_WARNING, "Whoa, no parking context?\n");
-
- manager_event(EVENT_FLAG_CALL, "UnParkedCall",
- "Exten: %s\r\n"
- "Channel: %s\r\n"
- "From: %s\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n",
- pu->parkingexten, pu->chan->name, chan->name,
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>")
- );
-
- free(pu);
- }
- /* JK02: it helps to answer the channel if not already up */
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- if (peer) {
- /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
-
- if (!ast_strlen_zero(courtesytone)) {
- int error = 0;
- ast_indicate(peer, AST_CONTROL_UNHOLD);
- if (parkedplay == 0) {
- error = ast_stream_and_wait(chan, courtesytone, chan->language, "");
- } else if (parkedplay == 1) {
- error = ast_stream_and_wait(peer, courtesytone, chan->language, "");
- } else if (parkedplay == 2) {
- if (!ast_streamfile(chan, courtesytone, chan->language) &&
- !ast_streamfile(peer, courtesytone, chan->language)) {
- /*! \todo XXX we would like to wait on both! */
- res = ast_waitstream(chan, "");
- if (res >= 0)
- res = ast_waitstream(peer, "");
- if (res < 0)
- error = 1;
- }
- }
- if (error) {
- ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
- ast_hangup(peer);
- ast_module_user_remove(u);
- return -1;
- }
- } else
- ast_indicate(peer, AST_CONTROL_UNHOLD);
-
- res = ast_channel_make_compatible(chan, peer);
- if (res < 0) {
- ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
- ast_hangup(peer);
- ast_module_user_remove(u);
- return -1;
- }
- /* This runs sorta backwards, since we give the incoming channel control, as if it
- were the person called. */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
-
- pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
- ast_cdr_setdestchan(chan->cdr, peer->name);
- memset(&config, 0, sizeof(struct ast_bridge_config));
- ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
- ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
- res = ast_bridge_call(chan, peer, &config);
-
- pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
- ast_cdr_setdestchan(chan->cdr, peer->name);
-
- /* Simulate the PBX hanging up */
- if (res != AST_PBX_NO_HANGUP_PEER)
- ast_hangup(peer);
- ast_module_user_remove(u);
- return res;
- } else {
- /*! \todo XXX Play a message XXX */
- if (ast_stream_and_wait(chan, "pbx-invalidpark", chan->language, ""))
- ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
- res = -1;
- }
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int handle_showfeatures(int fd, int argc, char *argv[])
-{
- int i;
- struct ast_call_feature *feature;
- char format[] = "%-25s %-7s %-7s\n";
-
- ast_cli(fd, format, "Builtin Feature", "Default", "Current");
- ast_cli(fd, format, "---------------", "-------", "-------");
-
- ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext()); /* default hardcoded above, so we'll hardcode it here */
-
- ast_rwlock_rdlock(&features_lock);
- for (i = 0; i < FEATURES_COUNT; i++)
- ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
- ast_rwlock_unlock(&features_lock);
-
- ast_cli(fd, "\n");
- ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
- ast_cli(fd, format, "---------------", "-------", "-------");
- if (AST_LIST_EMPTY(&feature_list))
- ast_cli(fd, "(none)\n");
- else {
- AST_LIST_LOCK(&feature_list);
- AST_LIST_TRAVERSE(&feature_list, feature, feature_entry)
- ast_cli(fd, format, feature->sname, "no def", feature->exten);
- AST_LIST_UNLOCK(&feature_list);
- }
- ast_cli(fd, "\nCall parking\n");
- ast_cli(fd, "------------\n");
- ast_cli(fd,"%-20s: %s\n", "Parking extension", parking_ext);
- ast_cli(fd,"%-20s: %s\n", "Parking context", parking_con);
- ast_cli(fd,"%-20s: %d-%d\n", "Parked call extensions", parking_start, parking_stop);
- ast_cli(fd,"\n");
-
- return RESULT_SUCCESS;
-}
-
-static char showfeatures_help[] =
-"Usage: feature list\n"
-" Lists currently configured features.\n";
-
-static int handle_parkedcalls(int fd, int argc, char *argv[])
-{
- struct parkeduser *cur;
- int numparked = 0;
-
- ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
- , "Context", "Extension", "Pri", "Timeout");
-
- ast_mutex_lock(&parking_lock);
-
- for (cur = parkinglot; cur; cur = cur->next) {
- ast_cli(fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
- ,cur->parkingexten, cur->chan->name, cur->context, cur->exten
- ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
-
- numparked++;
- }
- ast_mutex_unlock(&parking_lock);
- ast_cli(fd, "%d parked call%s.\n", numparked, (numparked != 1) ? "s" : "");
-
-
- return RESULT_SUCCESS;
-}
-
-static char showparked_help[] =
-"Usage: show parkedcalls\n"
-" Lists currently parked calls.\n";
-
-static struct ast_cli_entry cli_show_features_deprecated = {
- { "show", "features", NULL },
- handle_showfeatures, NULL,
- NULL };
-
-static struct ast_cli_entry cli_features[] = {
- { { "feature", "show", NULL },
- handle_showfeatures, "Lists configured features",
- showfeatures_help, NULL, &cli_show_features_deprecated },
-
- { { "show", "parkedcalls", NULL },
- handle_parkedcalls, "Lists parked calls",
- showparked_help },
-};
-
-/*! \brief Dump lot status */
-static int manager_parking_status( struct mansession *s, const struct message *m)
-{
- struct parkeduser *cur;
- const char *id = astman_get_header(m, "ActionID");
- char idText[256] = "";
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- astman_send_ack(s, m, "Parked calls will follow");
-
- ast_mutex_lock(&parking_lock);
-
- for (cur = parkinglot; cur; cur = cur->next) {
- astman_append(s, "Event: ParkedCall\r\n"
- "Exten: %d\r\n"
- "Channel: %s\r\n"
- "From: %s\r\n"
- "Timeout: %ld\r\n"
- "CallerID: %s\r\n"
- "CallerIDName: %s\r\n"
- "%s"
- "\r\n",
- cur->parkingnum, cur->chan->name, cur->peername,
- (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
- S_OR(cur->chan->cid.cid_num, ""), /* XXX in other places it is <unknown> */
- S_OR(cur->chan->cid.cid_name, ""),
- idText);
- }
-
- astman_append(s,
- "Event: ParkedCallsComplete\r\n"
- "%s"
- "\r\n",idText);
-
- ast_mutex_unlock(&parking_lock);
-
- return RESULT_SUCCESS;
-}
-
-static char mandescr_park[] =
-"Description: Park a channel.\n"
-"Variables: (Names marked with * are required)\n"
-" *Channel: Channel name to park\n"
-" *Channel2: Channel to announce park info to (and return to if timeout)\n"
-" Timeout: Number of milliseconds to wait before callback.\n";
-
-static int manager_park(struct mansession *s, const struct message *m)
-{
- const char *channel = astman_get_header(m, "Channel");
- const char *channel2 = astman_get_header(m, "Channel2");
- const char *timeout = astman_get_header(m, "Timeout");
- char buf[BUFSIZ];
- int to = 0;
- int res = 0;
- int parkExt = 0;
- struct ast_channel *ch1, *ch2;
-
- if (ast_strlen_zero(channel)) {
- astman_send_error(s, m, "Channel not specified");
- return 0;
- }
-
- if (ast_strlen_zero(channel2)) {
- astman_send_error(s, m, "Channel2 not specified");
- return 0;
- }
-
- ch1 = ast_get_channel_by_name_locked(channel);
- if (!ch1) {
- snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
- astman_send_error(s, m, buf);
- return 0;
- }
-
- ch2 = ast_get_channel_by_name_locked(channel2);
- if (!ch2) {
- snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
- astman_send_error(s, m, buf);
- ast_channel_unlock(ch1);
- return 0;
- }
-
- if (!ast_strlen_zero(timeout)) {
- sscanf(timeout, "%d", &to);
- }
-
- res = ast_masq_park_call(ch1, ch2, to, &parkExt);
- if (!res) {
- ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
- astman_send_ack(s, m, "Park successful");
- } else {
- astman_send_error(s, m, "Park failure");
- }
-
- ast_channel_unlock(ch1);
- ast_channel_unlock(ch2);
-
- return 0;
-}
-
-
-int ast_pickup_call(struct ast_channel *chan)
-{
- struct ast_channel *cur = NULL;
- int res = -1;
-
- while ( (cur = ast_channel_walk_locked(cur)) != NULL) {
- if (!cur->pbx &&
- (cur != chan) &&
- (chan->pickupgroup & cur->callgroup) &&
- ((cur->_state == AST_STATE_RINGING) ||
- (cur->_state == AST_STATE_RING))) {
- break;
- }
- ast_channel_unlock(cur);
- }
- if (cur) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
- res = ast_answer(chan);
- if (res)
- ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
- res = ast_queue_control(chan, AST_CONTROL_ANSWER);
- if (res)
- ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
- res = ast_channel_masquerade(cur, chan);
- if (res)
- ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name); /* Done */
- ast_channel_unlock(cur);
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "No call pickup possible...\n");
- }
- return res;
-}
-
-/*! \brief Add parking hints for all defined parking lots */
-static void park_add_hints(char *context, int start, int stop)
-{
- int numext;
- char device[AST_MAX_EXTENSION];
- char exten[10];
-
- for (numext = start; numext <= stop; numext++) {
- snprintf(exten, sizeof(exten), "%d", numext);
- snprintf(device, sizeof(device), "park:%s@%s", exten, context);
- ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
- }
-}
-
-
-static int load_config(void)
-{
- int start = 0, end = 0;
- int res;
- struct ast_context *con = NULL;
- struct ast_config *cfg = NULL;
- struct ast_variable *var = NULL;
- char old_parking_ext[AST_MAX_EXTENSION];
- char old_parking_con[AST_MAX_EXTENSION] = "";
-
- if (!ast_strlen_zero(parking_con)) {
- strcpy(old_parking_ext, parking_ext);
- strcpy(old_parking_con, parking_con);
- }
-
- /* Reset to defaults */
- strcpy(parking_con, "parkedcalls");
- strcpy(parking_con_dial, "park-dial");
- strcpy(parking_ext, "700");
- strcpy(pickup_ext, "*8");
- strcpy(parkmohclass, "default");
- courtesytone[0] = '\0';
- strcpy(xfersound, "beep");
- strcpy(xferfailsound, "pbx-invalid");
- parking_start = 701;
- parking_stop = 750;
- parkfindnext = 0;
- adsipark = 0;
- parkaddhints = 0;
-
- transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
- featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
- atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
-
- cfg = ast_config_load("features.conf");
- if (!cfg) {
- ast_log(LOG_WARNING,"Could not load features.conf\n");
- return AST_MODULE_LOAD_DECLINE;
- }
- for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
- if (!strcasecmp(var->name, "parkext")) {
- ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
- } else if (!strcasecmp(var->name, "context")) {
- ast_copy_string(parking_con, var->value, sizeof(parking_con));
- } else if (!strcasecmp(var->name, "parkingtime")) {
- if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
- ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
- parkingtime = DEFAULT_PARK_TIME;
- } else
- parkingtime = parkingtime * 1000;
- } else if (!strcasecmp(var->name, "parkpos")) {
- if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
- ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of features.conf\n", var->lineno);
- } else {
- parking_start = start;
- parking_stop = end;
- }
- } else if (!strcasecmp(var->name, "findslot")) {
- parkfindnext = (!strcasecmp(var->value, "next"));
- } else if (!strcasecmp(var->name, "parkinghints")) {
- parkaddhints = ast_true(var->value);
- } else if (!strcasecmp(var->name, "adsipark")) {
- adsipark = ast_true(var->value);
- } else if (!strcasecmp(var->name, "transferdigittimeout")) {
- if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
- ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
- transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
- } else
- transferdigittimeout = transferdigittimeout * 1000;
- } else if (!strcasecmp(var->name, "featuredigittimeout")) {
- if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
- ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
- featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
- }
- } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
- if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
- ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
- atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
- } else
- atxfernoanswertimeout = atxfernoanswertimeout * 1000;
- } else if (!strcasecmp(var->name, "courtesytone")) {
- ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
- } else if (!strcasecmp(var->name, "parkedplay")) {
- if (!strcasecmp(var->value, "both"))
- parkedplay = 2;
- else if (!strcasecmp(var->value, "parked"))
- parkedplay = 1;
- else
- parkedplay = 0;
- } else if (!strcasecmp(var->name, "xfersound")) {
- ast_copy_string(xfersound, var->value, sizeof(xfersound));
- } else if (!strcasecmp(var->name, "xferfailsound")) {
- ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
- } else if (!strcasecmp(var->name, "pickupexten")) {
- ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
- } else if (!strcasecmp(var->name, "parkedmusicclass")) {
- ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
- }
- }
-
- unmap_features();
- for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
- if (remap_feature(var->name, var->value))
- ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
- }
-
- /* Map a key combination to an application*/
- ast_unregister_features();
- for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
- char *tmp_val = ast_strdupa(var->value);
- char *exten, *activateon, *activatedby, *app, *app_args, *moh_class;
- struct ast_call_feature *feature;
-
- /* strsep() sets the argument to NULL if match not found, and it
- * is safe to use it with a NULL argument, so we don't check
- * between calls.
- */
- exten = strsep(&tmp_val,",");
- activatedby = strsep(&tmp_val,",");
- app = strsep(&tmp_val,",");
- app_args = strsep(&tmp_val,",");
- moh_class = strsep(&tmp_val,",");
-
- activateon = strsep(&activatedby, "/");
-
- /*! \todo XXX var_name or app_args ? */
- if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
- ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
- app, exten, activateon, var->name);
- continue;
- }
-
- AST_LIST_LOCK(&feature_list);
- if ((feature = find_dynamic_feature(var->name))) {
- AST_LIST_UNLOCK(&feature_list);
- ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
- continue;
- }
- AST_LIST_UNLOCK(&feature_list);
-
- if (!(feature = ast_calloc(1, sizeof(*feature))))
- continue;
-
- ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
- ast_copy_string(feature->app, app, FEATURE_APP_LEN);
- ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
-
- if (app_args)
- ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
-
- if (moh_class)
- ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
-
- ast_copy_string(feature->exten, exten, sizeof(feature->exten));
- feature->operation = feature_exec_app;
- ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
-
- /* Allow caller and calle to be specified for backwards compatability */
- if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
- ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
- else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
- ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
- else {
- ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
- " must be 'self', or 'peer'\n", var->name);
- continue;
- }
-
- if (ast_strlen_zero(activatedby))
- ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
- else if (!strcasecmp(activatedby, "caller"))
- ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
- else if (!strcasecmp(activatedby, "callee"))
- ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
- else if (!strcasecmp(activatedby, "both"))
- ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
- else {
- ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
- " must be 'caller', or 'callee', or 'both'\n", var->name);
- continue;
- }
-
- ast_register_feature(feature);
-
- if (option_verbose >= 1)
- ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);
- }
- ast_config_destroy(cfg);
-
- /* Remove the old parking extension */
- if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con))) {
- if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar))
- notify_metermaids(old_parking_ext, old_parking_con);
- if (option_debug)
- ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
- }
-
- if (!(con = ast_context_find(parking_con)) && !(con = ast_context_create(NULL, parking_con, registrar))) {
- ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
- return -1;
- }
- res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
- if (parkaddhints)
- park_add_hints(parking_con, parking_start, parking_stop);
- if (!res)
- notify_metermaids(ast_parking_ext(), parking_con);
- return res;
-
-}
-
-static int reload(void)
-{
- return load_config();
-}
-
-static int load_module(void)
-{
- int res;
-
- memset(parking_ext, 0, sizeof(parking_ext));
- memset(parking_con, 0, sizeof(parking_con));
-
- if ((res = load_config()))
- return res;
- ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
- ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
- res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
- if (!res)
- res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
- if (!res) {
- ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
- ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
- "Park a channel", mandescr_park);
- }
-
- res |= ast_devstate_prov_add("Park", metermaidstate);
-
- return res;
-}
-
-
-static int unload_module(void)
-{
- ast_module_user_hangup_all();
-
- ast_manager_unregister("ParkedCalls");
- ast_manager_unregister("Park");
- ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
- ast_unregister_application(parkcall);
- ast_devstate_prov_del("Park");
- return ast_unregister_application(parkedcall);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Call Features Resource",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_indications.c b/1.4/res/res_indications.c
deleted file mode 100644
index ed8a24b33..000000000
--- a/1.4/res/res_indications.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2002, Pauline Middelink
- *
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file res_indications.c
- *
- * \brief Load the indications
- *
- * \author Pauline Middelink <middelink@polyware.nl>
- *
- * Load the country specific dialtones into the asterisk PBX.
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/logger.h"
-#include "asterisk/config.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/indications.h"
-#include "asterisk/utils.h"
-
-/* Globals */
-static const char config[] = "indications.conf";
-
-/*
- * Help for commands provided by this module ...
- */
-static char help_add_indication[] =
-"Usage: indication add <country> <indication> \"<tonelist>\"\n"
-" Add the given indication to the country.\n";
-
-static char help_remove_indication[] =
-"Usage: indication remove <country> <indication>\n"
-" Remove the given indication from the country.\n";
-
-static char help_show_indications[] =
-"Usage: indication show [<country> ...]\n"
-" Display either a condensed for of all country/indications, or the\n"
-" indications for the specified countries.\n";
-
-char *playtones_desc=
-"PlayTones(arg): Plays a tone list. Execution will continue with the next step immediately,\n"
-"while the tones continue to play.\n"
-"Arg is either the tone name defined in the indications.conf configuration file, or a directly\n"
-"specified list of frequencies and durations.\n"
-"See the sample indications.conf for a description of the specification of a tonelist.\n\n"
-"Use the StopPlayTones application to stop the tones playing. \n";
-
-/*
- * Implementation of functions provided by this module
- */
-
-/*
- * ADD INDICATION command stuff
- */
-static int handle_add_indication(int fd, int argc, char *argv[])
-{
- struct tone_zone *tz;
- int created_country = 0;
- if (argc != 5) return RESULT_SHOWUSAGE;
-
- tz = ast_get_indication_zone(argv[2]);
- if (!tz) {
- /* country does not exist, create it */
- ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n",argv[2]);
-
- if (!(tz = ast_calloc(1, sizeof(*tz)))) {
- return -1;
- }
- ast_copy_string(tz->country,argv[2],sizeof(tz->country));
- if (ast_register_indication_country(tz)) {
- ast_log(LOG_WARNING, "Unable to register new country\n");
- free(tz);
- return -1;
- }
- created_country = 1;
- }
- if (ast_register_indication(tz,argv[3],argv[4])) {
- ast_log(LOG_WARNING, "Unable to register indication %s/%s\n",argv[2],argv[3]);
- if (created_country)
- ast_unregister_indication_country(argv[2]);
- return -1;
- }
- return 0;
-}
-
-/*
- * REMOVE INDICATION command stuff
- */
-static int handle_remove_indication(int fd, int argc, char *argv[])
-{
- struct tone_zone *tz;
- if (argc != 3 && argc != 4) return RESULT_SHOWUSAGE;
-
- if (argc == 3) {
- /* remove entiry country */
- if (ast_unregister_indication_country(argv[2])) {
- ast_log(LOG_WARNING, "Unable to unregister indication country %s\n",argv[2]);
- return -1;
- }
- return 0;
- }
-
- tz = ast_get_indication_zone(argv[2]);
- if (!tz) {
- ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n",argv[2],argv[3]);
- return -1;
- }
- if (ast_unregister_indication(tz,argv[3])) {
- ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n",argv[2],argv[3]);
- return -1;
- }
- return 0;
-}
-
-/*
- * SHOW INDICATIONS command stuff
- */
-static int handle_show_indications(int fd, int argc, char *argv[])
-{
- struct tone_zone *tz = NULL;
- char buf[256];
- int found_country = 0;
-
- if (argc == 2) {
- /* no arguments, show a list of countries */
- ast_cli(fd,"Country Alias Description\n"
- "===========================\n");
- while ( (tz = ast_walk_indications(tz) ) )
- ast_cli(fd,"%-7.7s %-7.7s %s\n", tz->country, tz->alias, tz->description);
- return 0;
- }
- /* there was a request for specific country(ies), lets humor them */
- while ( (tz = ast_walk_indications(tz) ) ) {
- int i,j;
- for (i=2; i<argc; i++) {
- if (strcasecmp(tz->country,argv[i])==0 &&
- !tz->alias[0]) {
- struct tone_zone_sound* ts;
- if (!found_country) {
- found_country = 1;
- ast_cli(fd,"Country Indication PlayList\n"
- "=====================================\n");
- }
- j = snprintf(buf,sizeof(buf),"%-7.7s %-15.15s ",tz->country,"<ringcadence>");
- for (i=0; i<tz->nrringcadence; i++) {
- j += snprintf(buf+j,sizeof(buf)-j,"%d,",tz->ringcadence[i]);
- }
- if (tz->nrringcadence)
- j--;
- ast_copy_string(buf+j,"\n",sizeof(buf)-j);
- ast_cli(fd,buf);
- for (ts=tz->tones; ts; ts=ts->next)
- ast_cli(fd,"%-7.7s %-15.15s %s\n",tz->country,ts->name,ts->data);
- break;
- }
- }
- }
- if (!found_country)
- ast_cli(fd,"No countries matched your criteria.\n");
- return -1;
-}
-
-/*
- * Playtones command stuff
- */
-static int handle_playtones(struct ast_channel *chan, void *data)
-{
- struct tone_zone_sound *ts;
- int res;
-
- if (!data || !((char*)data)[0]) {
- ast_log(LOG_NOTICE,"Nothing to play\n");
- return -1;
- }
- ts = ast_get_indication_tone(chan->zone, (const char*)data);
- if (ts && ts->data[0])
- res = ast_playtones_start(chan, 0, ts->data, 0);
- else
- res = ast_playtones_start(chan, 0, (const char*)data, 0);
- if (res)
- ast_log(LOG_NOTICE,"Unable to start playtones\n");
- return res;
-}
-
-/*
- * StopPlaylist command stuff
- */
-static int handle_stopplaytones(struct ast_channel *chan, void *data)
-{
- ast_playtones_stop(chan);
- return 0;
-}
-
-/*
- * Load module stuff
- */
-static int ind_load_module(void)
-{
- struct ast_config *cfg;
- struct ast_variable *v;
- char *cxt;
- char *c;
- struct tone_zone *tones;
- const char *country = NULL;
-
- /* that the following cast is needed, is yuk! */
- /* yup, checked it out. It is NOT written to. */
- cfg = ast_config_load((char *)config);
- if (!cfg)
- return -1;
-
- /* Use existing config to populate the Indication table */
- cxt = ast_category_browse(cfg, NULL);
- while(cxt) {
- /* All categories but "general" are considered countries */
- if (!strcasecmp(cxt, "general")) {
- cxt = ast_category_browse(cfg, cxt);
- continue;
- }
- if (!(tones = ast_calloc(1, sizeof(*tones)))) {
- ast_config_destroy(cfg);
- return -1;
- }
- ast_copy_string(tones->country,cxt,sizeof(tones->country));
-
- v = ast_variable_browse(cfg, cxt);
- while(v) {
- if (!strcasecmp(v->name, "description")) {
- ast_copy_string(tones->description, v->value, sizeof(tones->description));
- } else if ((!strcasecmp(v->name,"ringcadence"))||(!strcasecmp(v->name,"ringcadance"))) {
- char *ring,*rings = ast_strdupa(v->value);
- c = rings;
- ring = strsep(&c,",");
- while (ring) {
- int *tmp, val;
- if (!isdigit(ring[0]) || (val=atoi(ring))==-1) {
- ast_log(LOG_WARNING,"Invalid ringcadence given '%s' at line %d.\n",ring,v->lineno);
- ring = strsep(&c,",");
- continue;
- }
- if (!(tmp = ast_realloc(tones->ringcadence, (tones->nrringcadence + 1) * sizeof(int)))) {
- ast_config_destroy(cfg);
- return -1;
- }
- tones->ringcadence = tmp;
- tmp[tones->nrringcadence] = val;
- tones->nrringcadence++;
- /* next item */
- ring = strsep(&c,",");
- }
- } else if (!strcasecmp(v->name,"alias")) {
- char *countries = ast_strdupa(v->value);
- c = countries;
- country = strsep(&c,",");
- while (country) {
- struct tone_zone* azone;
- if (!(azone = ast_calloc(1, sizeof(*azone)))) {
- ast_config_destroy(cfg);
- return -1;
- }
- ast_copy_string(azone->country, country, sizeof(azone->country));
- ast_copy_string(azone->alias, cxt, sizeof(azone->alias));
- if (ast_register_indication_country(azone)) {
- ast_log(LOG_WARNING, "Unable to register indication alias at line %d.\n",v->lineno);
- free(tones);
- }
- /* next item */
- country = strsep(&c,",");
- }
- } else {
- /* add tone to country */
- struct tone_zone_sound *ps,*ts;
- for (ps=NULL,ts=tones->tones; ts; ps=ts, ts=ts->next) {
- if (strcasecmp(v->name,ts->name)==0) {
- /* already there */
- ast_log(LOG_NOTICE,"Duplicate entry '%s', skipped.\n",v->name);
- goto out;
- }
- }
- /* not there, add it to the back */
- if (!(ts = ast_malloc(sizeof(*ts)))) {
- ast_config_destroy(cfg);
- return -1;
- }
- ts->next = NULL;
- ts->name = strdup(v->name);
- ts->data = strdup(v->value);
- if (ps)
- ps->next = ts;
- else
- tones->tones = ts;
- }
-out: v = v->next;
- }
- if (tones->description[0] || tones->alias[0] || tones->tones) {
- if (ast_register_indication_country(tones)) {
- ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno);
- free(tones);
- }
- } else free(tones);
-
- cxt = ast_category_browse(cfg, cxt);
- }
-
- /* determine which country is the default */
- country = ast_variable_retrieve(cfg,"general","country");
- if (!country || !*country || ast_set_indication_country(country))
- ast_log(LOG_WARNING,"Unable to set the default country (for indication tones)\n");
-
- ast_config_destroy(cfg);
- return 0;
-}
-
-/*
- * CLI entries for commands provided by this module
- */
-static struct ast_cli_entry cli_show_indications_deprecated = {
- { "show", "indications", NULL },
- handle_show_indications, NULL,
- NULL };
-
-static struct ast_cli_entry cli_indications[] = {
- { { "indication", "add", NULL },
- handle_add_indication, "Add the given indication to the country",
- help_add_indication, NULL },
-
- { { "indication", "remove", NULL },
- handle_remove_indication, "Remove the given indication from the country",
- help_remove_indication, NULL },
-
- { { "indication", "show", NULL },
- handle_show_indications, "Display a list of all countries/indications",
- help_show_indications, NULL, &cli_show_indications_deprecated },
-};
-
-/*
- * Standard module functions ...
- */
-static int unload_module(void)
-{
- /* remove the registed indications... */
- ast_unregister_indication_country(NULL);
-
- /* and the functions */
- ast_cli_unregister_multiple(cli_indications, sizeof(cli_indications) / sizeof(struct ast_cli_entry));
- ast_unregister_application("PlayTones");
- ast_unregister_application("StopPlayTones");
- return 0;
-}
-
-
-static int load_module(void)
-{
- if (ind_load_module())
- return AST_MODULE_LOAD_DECLINE;
- ast_cli_register_multiple(cli_indications, sizeof(cli_indications) / sizeof(struct ast_cli_entry));
- ast_register_application("PlayTones", handle_playtones, "Play a tone list", playtones_desc);
- ast_register_application("StopPlayTones", handle_stopplaytones, "Stop playing a tone list","Stop playing a tone list");
-
- return 0;
-}
-
-static int reload(void)
-{
- /* remove the registed indications... */
- ast_unregister_indication_country(NULL);
-
- return ind_load_module();
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Indications Resource",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_jabber.c b/1.4/res/res_jabber.c
deleted file mode 100644
index 687bc1c33..000000000
--- a/1.4/res/res_jabber.c
+++ /dev/null
@@ -1,2508 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Matt O'Gorman <mogorman@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.
- */
-
-/*! \file
- * \brief A resource for interfacing asterisk directly as a client
- * or a component to a jabber compliant server.
- *
- * \todo If you unload this module, chan_gtalk/jingle will be dead. How do we handle that?
- * \todo If you have TLS, you can't unload this module. See bug #9738. This needs to be fixed,
- * but the bug is in the unmantained Iksemel library
- *
- */
-
-/*** MODULEINFO
- <depend>iksemel</depend>
- <use>gnutls</use>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <iksemel.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/jabber.h"
-#include "asterisk/file.h"
-#include "asterisk/config.h"
-#include "asterisk/callerid.h"
-#include "asterisk/lock.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/cli.h"
-#include "asterisk/app.h"
-#include "asterisk/pbx.h"
-#include "asterisk/md5.h"
-#include "asterisk/acl.h"
-#include "asterisk/utils.h"
-#include "asterisk/module.h"
-#include "asterisk/astobj.h"
-#include "asterisk/astdb.h"
-#include "asterisk/manager.h"
-
-#define JABBER_CONFIG "jabber.conf"
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-/*-- Forward declarations */
-static int aji_highest_bit(int number);
-static void aji_buddy_destroy(struct aji_buddy *obj);
-static void aji_client_destroy(struct aji_client *obj);
-static int aji_send_exec(struct ast_channel *chan, void *data);
-static int aji_status_exec(struct ast_channel *chan, void *data);
-static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming);
-static int aji_act_hook(void *data, int type, iks *node);
-static void aji_handle_iq(struct aji_client *client, iks *node);
-static void aji_handle_message(struct aji_client *client, ikspak *pak);
-static void aji_handle_presence(struct aji_client *client, ikspak *pak);
-static void aji_handle_subscribe(struct aji_client *client, ikspak *pak);
-static void *aji_recv_loop(void *data);
-static int aji_component_initialize(struct aji_client *client);
-static int aji_client_initialize(struct aji_client *client);
-static int aji_client_connect(void *data, ikspak *pak);
-static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc);
-static int aji_do_debug(int fd, int argc, char *argv[]);
-static int aji_do_reload(int fd, int argc, char *argv[]);
-static int aji_no_debug(int fd, int argc, char *argv[]);
-static int aji_test(int fd, int argc, char *argv[]);
-static int aji_show_clients(int fd, int argc, char *argv[]);
-static int aji_create_client(char *label, struct ast_variable *var, int debug);
-static int aji_create_buddy(char *label, struct aji_client *client);
-static int aji_reload(void);
-static int aji_load_config(void);
-static void aji_pruneregister(struct aji_client *client);
-static int aji_filter_roster(void *data, ikspak *pak);
-static int aji_get_roster(struct aji_client *client);
-static int aji_client_info_handler(void *data, ikspak *pak);
-static int aji_dinfo_handler(void *data, ikspak *pak);
-static int aji_ditems_handler(void *data, ikspak *pak);
-static int aji_register_query_handler(void *data, ikspak *pak);
-static int aji_register_approve_handler(void *data, ikspak *pak);
-static int aji_reconnect(struct aji_client *client);
-static iks *jabber_make_auth(iksid * id, const char *pass, const char *sid);
-/* No transports in this version */
-/*
-static int aji_create_transport(char *label, struct aji_client *client);
-static int aji_register_transport(void *data, ikspak *pak);
-static int aji_register_transport2(void *data, ikspak *pak);
-*/
-
-static char debug_usage[] =
-"Usage: jabber debug\n"
-" Enables dumping of Jabber packets for debugging purposes.\n";
-
-static char no_debug_usage[] =
-"Usage: jabber debug off\n"
-" Disables dumping of Jabber packets for debugging purposes.\n";
-
-static char reload_usage[] =
-"Usage: jabber reload\n"
-" Enables reloading of Jabber module.\n";
-
-static char test_usage[] =
-"Usage: jabber test [client]\n"
-" Sends test message for debugging purposes. A specific client\n"
-" as configured in jabber.conf can be optionally specified.\n";
-
-static struct ast_cli_entry aji_cli[] = {
- { { "jabber", "debug", NULL},
- aji_do_debug, "Enable Jabber debugging",
- debug_usage },
-
- { { "jabber", "reload", NULL},
- aji_do_reload, "Reload Jabber configuration",
- reload_usage },
-
- { { "jabber", "show", "connected", NULL},
- aji_show_clients, "Show state of clients and components",
- debug_usage },
-
- { { "jabber", "debug", "off", NULL},
- aji_no_debug, "Disable Jabber debug",
- no_debug_usage },
-
- { { "jabber", "test", NULL},
- aji_test, "Shows roster, but is generally used for mog's debugging.",
- test_usage },
-};
-
-static char *app_ajisend = "JabberSend";
-
-static char *ajisend_synopsis = "JabberSend(jabber,screenname,message)";
-
-static char *ajisend_descrip =
-"JabberSend(Jabber,ScreenName,Message)\n"
-" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
-" ScreenName - User Name to message.\n"
-" Message - Message to be sent to the buddy\n";
-
-static char *app_ajistatus = "JabberStatus";
-
-static char *ajistatus_synopsis = "JabberStatus(Jabber,ScreenName,Variable)";
-
-static char *ajistatus_descrip =
-"JabberStatus(Jabber,ScreenName,Variable)\n"
-" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
-" ScreenName - User Name to retrieve status from.\n"
-" Variable - Variable to store presence in will be 1-6.\n"
-" In order, Online, Chatty, Away, XAway, DND, Offline\n"
-" If not in roster variable will = 7\n";
-
-struct aji_client_container clients;
-struct aji_capabilities *capabilities = NULL;
-
-/*! \brief Global flags, initialized to default values */
-static struct ast_flags globalflags = { AJI_AUTOPRUNE | AJI_AUTOREGISTER };
-static int tls_initialized = FALSE;
-
-/*!
- * \brief Deletes the aji_client data structure.
- * \param obj is the structure we will delete.
- * \return void.
- */
-static void aji_client_destroy(struct aji_client *obj)
-{
- struct aji_message *tmp;
- ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy);
- ASTOBJ_CONTAINER_DESTROY(&obj->buddies);
- iks_filter_delete(obj->f);
- iks_parser_delete(obj->p);
- iks_stack_delete(obj->stack);
- AST_LIST_LOCK(&obj->messages);
- while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) {
- if (tmp->from)
- free(tmp->from);
- if (tmp->message)
- free(tmp->message);
- }
- AST_LIST_HEAD_DESTROY(&obj->messages);
- free(obj);
-}
-
-/*!
- * \brief Deletes the aji_buddy data structure.
- * \param obj is the structure we will delete.
- * \return void.
- */
-static void aji_buddy_destroy(struct aji_buddy *obj)
-{
- struct aji_resource *tmp;
-
- while ((tmp = obj->resources)) {
- obj->resources = obj->resources->next;
- free(tmp->description);
- free(tmp);
- }
-
- free(obj);
-}
-
-/*!
- * \brief Find version in XML stream and populate our capabilities list
- * \param node the node attribute in the caps element we'll look for or add to
- * our list
- * \param version the version attribute in the caps element we'll look for or
- * add to our list
- * \param pak the XML stanza we're processing
- * \return a pointer to the added or found aji_version structure
- */
-static struct aji_version *aji_find_version(char *node, char *version, ikspak *pak)
-{
- struct aji_capabilities *list = NULL;
- struct aji_version *res = NULL;
-
- list = capabilities;
-
- if(!node)
- node = pak->from->full;
- if(!version)
- version = "none supplied.";
- while(list) {
- if(!strcasecmp(list->node, node)) {
- res = list->versions;
- while(res) {
- if(!strcasecmp(res->version, version))
- return res;
- res = res->next;
- }
- /* Specified version not found. Let's add it to
- this node in our capabilities list */
- if(!res) {
- res = (struct aji_version *)malloc(sizeof(struct aji_version));
- if(!res) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- return NULL;
- }
- res->jingle = 0;
- res->parent = list;
- ast_copy_string(res->version, version, sizeof(res->version));
- res->next = list->versions;
- list->versions = res;
- return res;
- }
- }
- list = list->next;
- }
- /* Specified node not found. Let's add it our capabilities list */
- if(!list) {
- list = (struct aji_capabilities *)malloc(sizeof(struct aji_capabilities));
- if(!list) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- return NULL;
- }
- res = (struct aji_version *)malloc(sizeof(struct aji_version));
- if(!res) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- ast_free(list);
- return NULL;
- }
- ast_copy_string(list->node, node, sizeof(list->node));
- ast_copy_string(res->version, version, sizeof(res->version));
- res->jingle = 0;
- res->parent = list;
- res->next = NULL;
- list->versions = res;
- list->next = capabilities;
- capabilities = list;
- }
- return res;
-}
-
-static struct aji_resource *aji_find_resource(struct aji_buddy *buddy, char *name)
-{
- struct aji_resource *res = NULL;
- if (!buddy || !name)
- return res;
- res = buddy->resources;
- while (res) {
- if (!strcasecmp(res->resource, name)) {
- break;
- }
- res = res->next;
- }
- return res;
-}
-
-static int gtalk_yuck(iks *node)
-{
- if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps"))
- return 1;
- return 0;
-}
-
-/*!
- * \brief Detects the highest bit in a number.
- * \param Number you want to have evaluated.
- * \return the highest power of 2 that can go into the number.
- */
-static int aji_highest_bit(int number)
-{
- int x = sizeof(number) * 8 - 1;
- if (!number)
- return 0;
- for (; x > 0; x--) {
- if (number & (1 << x))
- break;
- }
- return (1 << x);
-}
-
-static iks *jabber_make_auth(iksid * id, const char *pass, const char *sid)
-{
- iks *x, *y;
- x = iks_new("iq");
- iks_insert_attrib(x, "type", "set");
- y = iks_insert(x, "query");
- iks_insert_attrib(y, "xmlns", IKS_NS_AUTH);
- iks_insert_cdata(iks_insert(y, "username"), id->user, 0);
- iks_insert_cdata(iks_insert(y, "resource"), id->resource, 0);
- if (sid) {
- char buf[41];
- char sidpass[100];
- snprintf(sidpass, sizeof(sidpass), "%s%s", sid, pass);
- ast_sha1_hash(buf, sidpass);
- iks_insert_cdata(iks_insert(y, "digest"), buf, 0);
- } else {
- iks_insert_cdata(iks_insert(y, "password"), pass, 0);
- }
- return x;
-}
-
-/*!
- * \brief Dial plan function status(). puts the status of watched user
- into a channel variable.
- * \param channel, and username,watched user, status var
- * \return 0.
- */
-static int aji_status_exec(struct ast_channel *chan, void *data)
-{
- struct aji_client *client = NULL;
- struct aji_buddy *buddy = NULL;
- struct aji_resource *r = NULL;
- char *s = NULL, *sender = NULL, *jid = NULL, *screenname = NULL, *resource = NULL, *variable = NULL;
- int stat = 7;
- char status[2];
-
- if (!data) {
- ast_log(LOG_ERROR, "This application requires arguments.\n");
- return 0;
- }
- s = ast_strdupa(data);
- if (s) {
- sender = strsep(&s, "|");
- if (sender && (sender[0] != '\0')) {
- jid = strsep(&s, "|");
- if (jid && (jid[0] != '\0')) {
- variable = s;
- } else {
- ast_log(LOG_ERROR, "Bad arguments\n");
- return -1;
- }
- }
- }
-
- if(!strchr(jid, '/')) {
- resource = NULL;
- } else {
- screenname = strsep(&jid, "/");
- resource = jid;
- }
- client = ast_aji_get_client(sender);
- if (!client) {
- ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender);
- return -1;
- }
- if(!&client->buddies) {
- ast_log(LOG_WARNING, "No buddies for connection : %s\n", sender);
- return -1;
- }
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, resource ? screenname: jid);
- if (!buddy) {
- ast_log(LOG_WARNING, "Could not find buddy in list : %s\n", resource ? screenname : jid);
- return -1;
- }
- r = aji_find_resource(buddy, resource);
- if(!r && buddy->resources)
- r = buddy->resources;
- if(!r)
- ast_log(LOG_NOTICE, "Resource %s of buddy %s not found \n", resource, screenname);
- else
- stat = r->status;
- sprintf(status, "%d", stat);
- pbx_builtin_setvar_helper(chan, variable, status);
- return 0;
-}
-
-/*!
- * \brief Dial plan function to send a message.
- * \param channel, and data, data is sender, reciever, message.
- * \return 0.
- */
-static int aji_send_exec(struct ast_channel *chan, void *data)
-{
- struct aji_client *client = NULL;
-
- char *s = NULL, *sender = NULL, *recipient = NULL, *message = NULL;
-
- if (!data) {
- ast_log(LOG_ERROR, "This application requires arguments.\n");
- return 0;
- }
- s = ast_strdupa(data);
- if (s) {
- sender = strsep(&s, "|");
- if (sender && (sender[0] != '\0')) {
- recipient = strsep(&s, "|");
- if (recipient && (recipient[0] != '\0')) {
- message = s;
- } else {
- ast_log(LOG_ERROR, "Bad arguments: %s\n", (char *) data);
- return -1;
- }
- }
- }
- if (!(client = ast_aji_get_client(sender))) {
- ast_log(LOG_WARNING, "Could not find sender connection: %s\n", sender);
- return -1;
- }
- if (strchr(recipient, '@') && message)
- ast_aji_send(client, recipient, message);
- return 0;
-}
-
-/*!
- * \brief the debug loop.
- * \param aji_client structure, xml data as string, size of string, direction of packet, 1 for inbound 0 for outbound.
- */
-static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp);
-
- if (client->debug) {
- if (is_incoming)
- ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp);
- else {
- if( strlen(xmpp) == 1) {
- if(option_debug > 2 && xmpp[0] == ' ')
- ast_verbose("\nJABBER: Keep alive packet\n");
- } else
- ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp);
- }
-
- }
- ASTOBJ_UNREF(client, aji_client_destroy);
-}
-
-/*!
- * \brief The action hook parses the inbound packets, constantly running.
- * \param data aji client structure
- * \param type type of packet
- * \param node the actual packet.
- * \return IKS_OK or IKS_HOOK .
- */
-static int aji_act_hook(void *data, int type, iks *node)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- ikspak *pak = NULL;
- iks *auth = NULL;
-
- if(!node) {
- ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_HOOK;
- }
-
- if (client->state == AJI_DISCONNECTING) {
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_HOOK;
- }
-
- pak = iks_packet(node);
-
- if (!client->component) { /*client */
- switch (type) {
- case IKS_NODE_START:
- if (client->usetls && !iks_is_secure(client->p)) {
- if (iks_has_tls()) {
- iks_start_tls(client->p);
- tls_initialized = TRUE;
- } else
- ast_log(LOG_ERROR, "gnuTLS not installed. You need to recompile the Iksemel library with gnuTLS support\n");
- break;
- }
- if (!client->usesasl) {
- iks_filter_add_rule(client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid, IKS_RULE_DONE);
- auth = jabber_make_auth(client->jid, client->password, iks_find_attrib(node, "id"));
- if (auth) {
- iks_insert_attrib(auth, "id", client->mid);
- iks_insert_attrib(auth, "to", client->jid->server);
- ast_aji_increment_mid(client->mid);
- iks_send(client->p, auth);
- iks_delete(auth);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- break;
-
- case IKS_NODE_NORMAL:
- if (!strcmp("stream:features", iks_name(node))) {
- int features = 0;
- features = iks_stream_features(node);
- if (client->usesasl) {
- if (client->usetls && !iks_is_secure(client->p))
- break;
- if (client->authorized) {
- if (features & IKS_STREAM_BIND) {
- iks_filter_add_rule (client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_DONE);
- auth = iks_make_resource_bind(client->jid);
- if (auth) {
- iks_insert_attrib(auth, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_send(client->p, auth);
- iks_delete(auth);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- break;
- }
- }
- if (features & IKS_STREAM_SESSION) {
- iks_filter_add_rule (client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "auth", IKS_RULE_DONE);
- auth = iks_make_session();
- if (auth) {
- iks_insert_attrib(auth, "id", "auth");
- ast_aji_increment_mid(client->mid);
- iks_send(client->p, auth);
- iks_delete(auth);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- }
- } else {
- if (!client->jid->user) {
- ast_log(LOG_ERROR, "Malformed Jabber ID : %s (domain missing?)\n", client->jid->full);
- break;
- }
- features = aji_highest_bit(features);
- if (features == IKS_STREAM_SASL_MD5)
- iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, client->jid->user, client->password);
- else {
- if (features == IKS_STREAM_SASL_PLAIN) {
- iks *x = NULL;
- x = iks_new("auth");
- if (x) {
- int len = strlen(client->jid->user) + strlen(client->password) + 3;
- /* XXX Check return values XXX */
- char *s = ast_malloc(80 + len);
- char *base64 = ast_malloc(80 + len * 2);
- iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL);
- iks_insert_attrib(x, "mechanism", "PLAIN");
- sprintf(s, "%c%s%c%s", 0, client->jid->user, 0, client->password);
-
- /* exclude the NULL training byte from the base64 encoding operation
- as some XMPP servers will refuse it.
- The format for authentication is [authzid]\0authcid\0password
- not [authzid]\0authcid\0password\0 */
- ast_base64encode(base64, (const unsigned char *) s, len - 1, len * 2);
- iks_insert_cdata(x, base64, 0);
- iks_send(client->p, x);
- iks_delete(x);
- if (base64)
- free(base64);
- if (s)
- free(s);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- }
- }
- }
- }
- } else if (!strcmp("failure", iks_name(node))) {
- ast_log(LOG_ERROR, "JABBER: encryption failure. possible bad password.\n");
- } else if (!strcmp("success", iks_name(node))) {
- client->authorized = 1;
- iks_send_header(client->p, client->jid->server);
- }
- break;
- case IKS_NODE_ERROR:
- ast_log(LOG_ERROR, "JABBER: Node Error\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_HOOK;
- break;
- case IKS_NODE_STOP:
- ast_log(LOG_WARNING, "JABBER: Disconnected\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_HOOK;
- break;
- }
- } else if (client->state != AJI_CONNECTED && client->component) {
- switch (type) {
- case IKS_NODE_START:
- if (client->state == AJI_DISCONNECTED) {
- char secret[160], shasum[320], *handshake;
-
- sprintf(secret, "%s%s", pak->id, client->password);
- ast_sha1_hash(shasum, secret);
- handshake = NULL;
- asprintf(&handshake, "<handshake>%s</handshake>", shasum);
- if (handshake) {
- iks_send_raw(client->p, handshake);
- free(handshake);
- handshake = NULL;
- }
- client->state = AJI_CONNECTING;
- if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/
- client->state = AJI_CONNECTED;
- else
- ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n");
- break;
- }
- break;
-
- case IKS_NODE_NORMAL:
- break;
-
- case IKS_NODE_ERROR:
- ast_log(LOG_ERROR, "JABBER: Node Error\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_HOOK;
-
- case IKS_NODE_STOP:
- ast_log(LOG_WARNING, "JABBER: Disconnected\n");
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_HOOK;
- }
- }
-
- switch (pak->type) {
- case IKS_PAK_NONE:
- if (option_debug)
- ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you NONE\n");
- break;
- case IKS_PAK_MESSAGE:
- aji_handle_message(client, pak);
- if (option_debug)
- ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n");
- break;
- case IKS_PAK_PRESENCE:
- aji_handle_presence(client, pak);
- if (option_debug)
- ast_log(LOG_DEBUG, "JABBER: I Do know how to handle presence!!\n");
- break;
- case IKS_PAK_S10N:
- aji_handle_subscribe(client, pak);
- if (option_debug)
- ast_log(LOG_DEBUG, "JABBER: I Dont know S10N subscribe!!\n");
- break;
- case IKS_PAK_IQ:
- if (option_debug)
- ast_log(LOG_DEBUG, "JABBER: I Dont have an IQ!!!\n");
- aji_handle_iq(client, node);
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "JABBER: I Dont know %i\n", pak->type);
- break;
- }
-
- iks_filter_packet(client->f, pak);
-
- if (node)
- iks_delete(node);
-
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_OK;
-}
-
-static int aji_register_approve_handler(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- iks *iq = NULL, *presence = NULL, *x = NULL;
-
- iq = iks_new("iq");
- presence = iks_new("presence");
- x = iks_new("x");
- if (client && iq && presence && x) {
- if (!iks_find(pak->query, "remove")) {
- iks_insert_attrib(iq, "from", client->jid->full);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_send(client->p, iq);
-
- iks_insert_attrib(presence, "from", client->jid->full);
- iks_insert_attrib(presence, "to", pak->from->partial);
- iks_insert_attrib(presence, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_insert_attrib(presence, "type", "subscribe");
- iks_insert_attrib(x, "xmlns", "vcard-temp:x:update");
- iks_insert_node(presence, x);
- iks_send(client->p, presence);
- }
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
-
- if (iq)
- iks_delete(iq);
- if(presence)
- iks_delete(presence);
- if (x)
- iks_delete(x);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-}
-
-static int aji_register_query_handler(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- struct aji_buddy *buddy = NULL;
- char *node = NULL;
-
- client = (struct aji_client *) data;
-
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
- if (!buddy) {
- iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL;
- ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
- iq = iks_new("iq");
- query = iks_new("query");
- error = iks_new("error");
- notacceptable = iks_new("not-acceptable");
- if(iq && query && error && notacceptable) {
- iks_insert_attrib(iq, "type", "error");
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(query, "xmlns", "jabber:iq:register");
- iks_insert_attrib(error, "code" , "406");
- iks_insert_attrib(error, "type", "modify");
- iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
- iks_insert_node(iq, query);
- iks_insert_node(iq, error);
- iks_insert_node(error, notacceptable);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (error)
- iks_delete(error);
- if (notacceptable)
- iks_delete(notacceptable);
- } else if (!(node = iks_find_attrib(pak->query, "node"))) {
- iks *iq = NULL, *query = NULL, *instructions = NULL;
- char *explain = "Welcome to Asterisk - the Open Source PBX.\n";
- iq = iks_new("iq");
- query = iks_new("query");
- instructions = iks_new("instructions");
- if (iq && query && instructions && client) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "jabber:iq:register");
- iks_insert_cdata(instructions, explain, 0);
- iks_insert_node(iq, query);
- iks_insert_node(query, instructions);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (instructions)
- iks_delete(instructions);
- }
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-}
-
-static int aji_ditems_handler(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- char *node = NULL;
-
- if (!(node = iks_find_attrib(pak->query, "node"))) {
- iks *iq = NULL, *query = NULL, *item = NULL;
- iq = iks_new("iq");
- query = iks_new("query");
- item = iks_new("item");
-
- if (iq && query && item) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
- iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands");
- iks_insert_attrib(item, "name", "Million Dollar Asterisk Commands");
- iks_insert_attrib(item, "jid", client->user);
-
- iks_insert_node(iq, query);
- iks_insert_node(query, item);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (item)
- iks_delete(item);
-
- } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) {
- iks *iq, *query, *confirm;
- iq = iks_new("iq");
- query = iks_new("query");
- confirm = iks_new("item");
- if (iq && query && confirm && client) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
- iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands");
- iks_insert_attrib(confirm, "node", "confirmaccount");
- iks_insert_attrib(confirm, "name", "Confirm AIM account");
- iks_insert_attrib(confirm, "jid", "blog.astjab.org");
-
- iks_insert_node(iq, query);
- iks_insert_node(query, confirm);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (confirm)
- iks_delete(confirm);
-
- } else if (!strcasecmp(node, "confirmaccount")) {
- iks *iq = NULL, *query = NULL, *feature = NULL;
-
- iq = iks_new("iq");
- query = iks_new("query");
- feature = iks_new("feature");
-
- if (iq && query && feature && client) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
- iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands");
- iks_insert_node(iq, query);
- iks_insert_node(query, feature);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (feature)
- iks_delete(feature);
- }
-
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-
-}
-
-static int aji_client_info_handler(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- struct aji_resource *resource = NULL;
- struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
-
- resource = aji_find_resource(buddy, pak->from->resource);
- if (pak->subtype == IKS_TYPE_RESULT) {
- if (!resource) {
- ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
- }
- if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
- resource->cap->jingle = 1;
- } else
- resource->cap->jingle = 0;
- } else if (pak->subtype == IKS_TYPE_GET) {
- iks *iq, *disco, *ident, *google, *query;
- iq = iks_new("iq");
- query = iks_new("query");
- ident = iks_new("identity");
- disco = iks_new("feature");
- google = iks_new("feature");
- if (iq && ident && disco && google) {
- iks_insert_attrib(iq, "from", client->jid->full);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
- iks_insert_attrib(ident, "category", "client");
- iks_insert_attrib(ident, "type", "pc");
- iks_insert_attrib(ident, "name", "asterisk");
- iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info");
- iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1");
- iks_insert_node(iq, query);
- iks_insert_node(query, ident);
- iks_insert_node(query, google);
- iks_insert_node(query, disco);
- iks_send(client->p, iq);
- } else
- ast_log(LOG_ERROR, "Out of Memory.\n");
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (ident)
- iks_delete(ident);
- if (google)
- iks_delete(google);
- if (disco)
- iks_delete(disco);
- } else if (pak->subtype == IKS_TYPE_ERROR) {
- ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
- }
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-}
-
-static int aji_dinfo_handler(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- char *node = NULL;
- struct aji_resource *resource = NULL;
- struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
-
- resource = aji_find_resource(buddy, pak->from->resource);
- if (pak->subtype == IKS_TYPE_ERROR) {
- ast_log(LOG_WARNING, "Recieved error from a client, turn on jabber debug!\n");
- return IKS_FILTER_EAT;
- }
- if (pak->subtype == IKS_TYPE_RESULT) {
- if (!resource) {
- ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
- }
- if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
- resource->cap->jingle = 1;
- } else
- resource->cap->jingle = 0;
- } else if (pak->subtype == IKS_TYPE_GET && !(node = iks_find_attrib(pak->query, "node"))) {
- iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search;
-
- iq = iks_new("iq");
- query = iks_new("query");
- identity = iks_new("identity");
- disco = iks_new("feature");
- reg = iks_new("feature");
- commands = iks_new("feature");
- gateway = iks_new("feature");
- version = iks_new("feature");
- vcard = iks_new("feature");
- search = iks_new("feature");
-
- if (iq && query && identity && disco && reg && commands && gateway && version && vcard && search && client) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
- iks_insert_attrib(identity, "category", "gateway");
- iks_insert_attrib(identity, "type", "pstn");
- iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX");
- iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco");
- iks_insert_attrib(reg, "var", "jabber:iq:register");
- iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands");
- iks_insert_attrib(gateway, "var", "jabber:iq:gateway");
- iks_insert_attrib(version, "var", "jabber:iq:version");
- iks_insert_attrib(vcard, "var", "vcard-temp");
- iks_insert_attrib(search, "var", "jabber:iq:search");
-
- iks_insert_node(iq, query);
- iks_insert_node(query, identity);
- iks_insert_node(query, disco);
- iks_insert_node(query, reg);
- iks_insert_node(query, commands);
- iks_insert_node(query, gateway);
- iks_insert_node(query, version);
- iks_insert_node(query, vcard);
- iks_insert_node(query, search);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
-
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (identity)
- iks_delete(identity);
- if (disco)
- iks_delete(disco);
- if (reg)
- iks_delete(reg);
- if (commands)
- iks_delete(commands);
- if (gateway)
- iks_delete(gateway);
- if (version)
- iks_delete(version);
- if (vcard)
- iks_delete(vcard);
- if (search)
- iks_delete(search);
-
- } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "http://jabber.org/protocol/commands")) {
- iks *iq, *query, *confirm;
- iq = iks_new("iq");
- query = iks_new("query");
- confirm = iks_new("item");
-
- if (iq && query && confirm && client) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
- iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands");
- iks_insert_attrib(confirm, "node", "confirmaccount");
- iks_insert_attrib(confirm, "name", "Confirm AIM account");
- iks_insert_attrib(confirm, "jid", client->user);
- iks_insert_node(iq, query);
- iks_insert_node(query, confirm);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (confirm)
- iks_delete(confirm);
-
- } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "confirmaccount")) {
- iks *iq, *query, *feature;
-
- iq = iks_new("iq");
- query = iks_new("query");
- feature = iks_new("feature");
-
- if (iq && query && feature && client) {
- iks_insert_attrib(iq, "from", client->user);
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq, "id", pak->id);
- iks_insert_attrib(iq, "type", "result");
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
- iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands");
- iks_insert_node(iq, query);
- iks_insert_node(query, feature);
- iks_send(client->p, iq);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (iq)
- iks_delete(iq);
- if (query)
- iks_delete(query);
- if (feature)
- iks_delete(feature);
- }
-
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-}
-
-/*!
- * \brief Handles <iq> tags.
- * \param client structure and the iq node.
- * \return void.
- */
-static void aji_handle_iq(struct aji_client *client, iks *node)
-{
- /*Nothing to see here */
-}
-
-/*!
- * \brief Handles presence packets.
- * \param client structure and the node.
- * \return void.
- */
-static void aji_handle_message(struct aji_client *client, ikspak *pak)
-{
- struct aji_message *insert, *tmp;
- int flag = 0;
-
- if (!(insert = ast_calloc(1, sizeof(struct aji_message))))
- return;
- time(&insert->arrived);
- if (iks_find_cdata(pak->x, "body"))
- insert->message = ast_strdup(iks_find_cdata(pak->x, "body"));
- if(pak->id)
- ast_copy_string(insert->id, pak->id, sizeof(insert->message));
- if (pak->from)
- insert->from = ast_strdup(pak->from->full);
- AST_LIST_LOCK(&client->messages);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
- if (flag) {
- AST_LIST_REMOVE_CURRENT(&client->messages, list);
- if (tmp->from)
- free(tmp->from);
- if (tmp->message)
- free(tmp->message);
- } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) {
- flag = 1;
- AST_LIST_REMOVE_CURRENT(&client->messages, list);
- if (tmp->from)
- free(tmp->from);
- if (tmp->message)
- free(tmp->message);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_INSERT_HEAD(&client->messages, insert, list);
- AST_LIST_UNLOCK(&client->messages);
-}
-
-static void aji_handle_presence(struct aji_client *client, ikspak *pak)
-{
- int status, priority;
- struct aji_buddy *buddy;
- struct aji_resource *tmp = NULL, *last = NULL, *found = NULL;
- char *ver, *node, *descrip, *type;
-
- if(client->state != AJI_CONNECTED)
- aji_create_buddy(pak->from->partial, client);
-
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
- if (!buddy && pak->from->partial) {
- /* allow our jid to be used to log in with another resource */
- if (!strcmp((const char *)pak->from->partial, (const char *)client->jid->partial))
- aji_create_buddy(pak->from->partial, client);
- else
- ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial);
- return;
- }
- type = iks_find_attrib(pak->x, "type");
- if(client->component && type &&!strcasecmp("probe", type)) {
- aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage);
- ast_verbose("what i was looking for \n");
- }
- ASTOBJ_WRLOCK(buddy);
- status = (pak->show) ? pak->show : 6;
- priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0");
- tmp = buddy->resources;
- descrip = ast_strdup(iks_find_cdata(pak->x,"status"));
-
- while (tmp && pak->from->resource) {
- if (!strcasecmp(tmp->resource, pak->from->resource)) {
- tmp->status = status;
- if (tmp->description) free(tmp->description);
- tmp->description = descrip;
- found = tmp;
- if (status == 6) { /* Sign off Destroy resource */
- if (last && found->next) {
- last->next = found->next;
- } else if (!last) {
- if (found->next)
- buddy->resources = found->next;
- else
- buddy->resources = NULL;
- } else if (!found->next) {
- if (last)
- last->next = NULL;
- else
- buddy->resources = NULL;
- }
- free(found);
- found = NULL;
- break;
- }
- /* resource list is sorted by descending priority */
- if (tmp->priority != priority) {
- found->priority = priority;
- if (!last && !found->next)
- /* resource was found to be unique,
- leave loop */
- break;
- /* search for resource in our list
- and take it out for the moment */
- if (last)
- last->next = found->next;
- else
- buddy->resources = found->next;
-
- last = NULL;
- tmp = buddy->resources;
- if (!buddy->resources)
- buddy->resources = found;
- /* priority processing */
- while (tmp) {
- /* insert resource back according to
- its priority value */
- if (found->priority > tmp->priority) {
- if (last)
- /* insert within list */
- last->next = found;
- found->next = tmp;
- if (!last)
- /* insert on top */
- buddy->resources = found;
- break;
- }
- if (!tmp->next) {
- /* insert at the end of the list */
- tmp->next = found;
- found->next = NULL;
- break;
- }
- last = tmp;
- tmp = tmp->next;
- }
- }
- break;
- }
- last = tmp;
- tmp = tmp->next;
- }
-
- /* resource not found in our list, create it */
- if (!found && status != 6 && pak->from->resource) {
- found = (struct aji_resource *) malloc(sizeof(struct aji_resource));
- memset(found, 0, sizeof(struct aji_resource));
-
- if (!found) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- return;
- }
- ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource));
- found->status = status;
- found->description = descrip;
- found->priority = priority;
- found->next = NULL;
- last = NULL;
- tmp = buddy->resources;
- while (tmp) {
- if (found->priority > tmp->priority) {
- if (last)
- last->next = found;
- found->next = tmp;
- if (!last)
- buddy->resources = found;
- break;
- }
- if (!tmp->next) {
- tmp->next = found;
- break;
- }
- last = tmp;
- tmp = tmp->next;
- }
- if (!tmp)
- buddy->resources = found;
- }
-
- ASTOBJ_UNLOCK(buddy);
- ASTOBJ_UNREF(buddy, aji_buddy_destroy);
-
- node = iks_find_attrib(iks_find(pak->x, "c"), "node");
- ver = iks_find_attrib(iks_find(pak->x, "c"), "ver");
-
- /* handle gmail client's special caps:c tag */
- if (!node && !ver) {
- node = iks_find_attrib(iks_find(pak->x, "caps:c"), "node");
- ver = iks_find_attrib(iks_find(pak->x, "caps:c"), "ver");
- }
-
- /* retrieve capabilites of the new resource */
- if(status !=6 && found && !found->cap) {
- found->cap = aji_find_version(node, ver, pak);
- if(gtalk_yuck(pak->x)) /* gtalk should do discover */
- found->cap->jingle = 1;
- if(found->cap->jingle && option_debug > 4)
- ast_log(LOG_DEBUG,"Special case for google till they support discover.\n");
- else {
- iks *iq, *query;
- iq = iks_new("iq");
- query = iks_new("query");
- if(query && iq) {
- iks_insert_attrib(iq, "type", "get");
- iks_insert_attrib(iq, "to", pak->from->full);
- iks_insert_attrib(iq,"from", client->jid->full);
- iks_insert_attrib(iq, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
- iks_insert_node(iq, query);
- iks_send(client->p, iq);
-
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- if(query)
- iks_delete(query);
- if(iq)
- iks_delete(iq);
- }
- }
- if (option_verbose > 4) {
- switch (pak->subtype) {
- case IKS_TYPE_AVAILABLE:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am available ^_* %i\n", pak->subtype);
- break;
- case IKS_TYPE_UNAVAILABLE:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: I am unavailable ^_* %i\n", pak->subtype);
- break;
- default:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype);
- }
- switch (pak->show) {
- case IKS_SHOW_UNAVAILABLE:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
- break;
- case IKS_SHOW_AVAILABLE:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is available\n");
- break;
- case IKS_SHOW_CHAT:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
- break;
- case IKS_SHOW_AWAY:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: type is away\n");
- break;
- case IKS_SHOW_XA:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
- break;
- case IKS_SHOW_DND:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
- break;
- default:
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: Kinky! how did that happen %i\n", pak->show);
- }
- }
-}
-
-/*!
- * \brief handles subscription requests.
- * \param aji_client struct and xml packet.
- * \return void.
- */
-static void aji_handle_subscribe(struct aji_client *client, ikspak *pak)
-{
- iks *presence = NULL, *status = NULL;
- struct aji_buddy* buddy = NULL;
-
- switch (pak->subtype) {
- case IKS_TYPE_SUBSCRIBE:
- presence = iks_new("presence");
- status = iks_new("status");
- if(presence && status) {
- iks_insert_attrib(presence, "type", "subscribed");
- iks_insert_attrib(presence, "to", pak->from->full);
- iks_insert_attrib(presence, "from", client->jid->full);
- if(pak->id)
- iks_insert_attrib(presence, "id", pak->id);
- iks_insert_cdata(status, "Asterisk has approved subscription", 0);
- iks_insert_node(presence, status);
- iks_send(client->p, presence);
- } else
- ast_log(LOG_ERROR, "Unable to allocate nodes\n");
- if(presence)
- iks_delete(presence);
- if(status)
- iks_delete(status);
- if(client->component)
- aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage);
- case IKS_TYPE_SUBSCRIBED:
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
- if (!buddy && pak->from->partial) {
- aji_create_buddy(pak->from->partial, client);
- }
- default:
- if (option_verbose > 4) {
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype);
- }
- }
-}
-
-/*!
- * \brief sends messages.
- * \param aji_client struct , reciever, message.
- * \return 1.
- */
-int ast_aji_send(struct aji_client *client, const char *address, const char *message)
-{
- int res = 0;
- iks *message_packet = NULL;
- if (client->state == AJI_CONNECTED) {
- message_packet = iks_make_msg(IKS_TYPE_CHAT, address, message);
- if (message_packet) {
- iks_insert_attrib(message_packet, "from", client->jid->full);
- res = iks_send(client->p, message_packet);
- } else {
- ast_log(LOG_ERROR, "Out of memory.\n");
- }
- if (message_packet)
- iks_delete(message_packet);
- } else
- ast_log(LOG_WARNING, "JABBER: Not connected can't send\n");
- return 1;
-}
-
-/*!
- * \brief create a chatroom.
- * \param aji_client struct , room, server, topic for the room.
- * \return 0.
- */
-int ast_aji_create_chat(struct aji_client *client, char *room, char *server, char *topic)
-{
- int res = 0;
- iks *iq = NULL;
- iq = iks_new("iq");
-
- if (iq && client) {
- iks_insert_attrib(iq, "type", "get");
- iks_insert_attrib(iq, "to", server);
- iks_insert_attrib(iq, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_send(client->p, iq);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
-
- iks_delete(iq);
-
- return res;
-}
-
-/*!
- * \brief join a chatroom.
- * \param aji_client struct , room.
- * \return res.
- */
-int ast_aji_join_chat(struct aji_client *client, char *room)
-{
- int res = 0;
- iks *presence = NULL, *priority = NULL;
- presence = iks_new("presence");
- priority = iks_new("priority");
- if (presence && priority && client) {
- iks_insert_cdata(priority, "0", 1);
- iks_insert_attrib(presence, "to", room);
- iks_insert_node(presence, priority);
- res = iks_send(client->p, presence);
- iks_insert_cdata(priority, "5", 1);
- iks_insert_attrib(presence, "to", room);
- res = iks_send(client->p, presence);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- if (presence)
- iks_delete(presence);
- if (priority)
- iks_delete(priority);
- return res;
-}
-
-/*!
- * \brief invite to a chatroom.
- * \param aji_client struct ,user, room, message.
- * \return res.
- */
-int ast_aji_invite_chat(struct aji_client *client, char *user, char *room, char *message)
-{
- int res = 0;
- iks *invite, *body, *namespace;
-
- invite = iks_new("message");
- body = iks_new("body");
- namespace = iks_new("x");
- if (client && invite && body && namespace) {
- iks_insert_attrib(invite, "to", user);
- iks_insert_attrib(invite, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_insert_cdata(body, message, 0);
- iks_insert_attrib(namespace, "xmlns", "jabber:x:conference");
- iks_insert_attrib(namespace, "jid", room);
- iks_insert_node(invite, body);
- iks_insert_node(invite, namespace);
- res = iks_send(client->p, invite);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- if (body)
- iks_delete(body);
- if (namespace)
- iks_delete(namespace);
- if (invite)
- iks_delete(invite);
- return res;
-}
-
-
-/*!
- * \brief receive message loop.
- * \param aji_client struct.
- * \return void.
- */
-static void *aji_recv_loop(void *data)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- int res = IKS_HOOK;
- do {
- if (res != IKS_OK) {
- while(res != IKS_OK) {
- if(option_verbose > 3)
- ast_verbose("JABBER: reconnecting.\n");
- res = aji_reconnect(client);
- sleep(4);
- }
- }
-
- res = iks_recv(client->p, 1);
-
- if (client->state == AJI_DISCONNECTING) {
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Ending our Jabber client's thread due to a disconnect\n");
- pthread_exit(NULL);
- }
- client->timeout--;
- if (res == IKS_HOOK)
- ast_log(LOG_WARNING, "JABBER: Got hook event.\n");
- else if (res == IKS_NET_TLSFAIL)
- ast_log(LOG_WARNING, "JABBER: Failure in TLS.\n");
- else if (client->timeout == 0 && client->state == AJI_CONNECTED) {
- res = client->keepalive ? iks_send_raw(client->p, " ") : IKS_OK;
- if(res == IKS_OK)
- client->timeout = 50;
- else
- ast_log(LOG_WARNING, "JABBER: Network Timeout\n");
- } else if (res == IKS_NET_RWERR)
- ast_log(LOG_WARNING, "JABBER: socket read error\n");
- } while (client);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return 0;
-}
-
-/*!
- * \brief increments the mid field for messages and other events.
- * \param message id.
- * \return void.
- */
-void ast_aji_increment_mid(char *mid)
-{
- int i = 0;
-
- for (i = strlen(mid) - 1; i >= 0; i--) {
- if (mid[i] != 'z') {
- mid[i] = mid[i] + 1;
- i = 0;
- } else
- mid[i] = 'a';
- }
-}
-
-
-/*!
- * \brief attempts to register to a transport.
- * \param aji_client struct, and xml packet.
- * \return IKS_FILTER_EAT.
- */
-/*allows for registering to transport , was too sketch and is out for now. */
-/*static int aji_register_transport(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- int res = 0;
- struct aji_buddy *buddy = NULL;
- iks *send = iks_make_iq(IKS_TYPE_GET, "jabber:iq:register");
-
- if (client && send) {
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->btype == AJI_TRANS) {
- buddy = iterator;
- }
- ASTOBJ_UNLOCK(iterator);
- });
- iks_filter_remove_hook(client->f, aji_register_transport);
- iks_filter_add_rule(client->f, aji_register_transport2, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_NS, IKS_NS_REGISTER, IKS_RULE_DONE);
- iks_insert_attrib(send, "to", buddy->host);
- iks_insert_attrib(send, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_insert_attrib(send, "from", client->user);
- res = iks_send(client->p, send);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
-
- if (send)
- iks_delete(send);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-
-}
-*/
-/*!
- * \brief attempts to register to a transport step 2.
- * \param aji_client struct, and xml packet.
- * \return IKS_FILTER_EAT.
- */
-/* more of the same blob of code, too wonky for now*/
-/* static int aji_register_transport2(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- int res = 0;
- struct aji_buddy *buddy = NULL;
-
- iks *regiq = iks_new("iq");
- iks *regquery = iks_new("query");
- iks *reguser = iks_new("username");
- iks *regpass = iks_new("password");
-
- if (client && regquery && reguser && regpass && regiq) {
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->btype == AJI_TRANS)
- buddy = iterator; ASTOBJ_UNLOCK(iterator);
- });
- iks_filter_remove_hook(client->f, aji_register_transport2);
- iks_insert_attrib(regiq, "to", buddy->host);
- iks_insert_attrib(regiq, "type", "set");
- iks_insert_attrib(regiq, "id", client->mid);
- ast_aji_increment_mid(client->mid);
- iks_insert_attrib(regiq, "from", client->user);
- iks_insert_attrib(regquery, "xmlns", "jabber:iq:register");
- iks_insert_cdata(reguser, buddy->user, 0);
- iks_insert_cdata(regpass, buddy->pass, 0);
- iks_insert_node(regiq, regquery);
- iks_insert_node(regquery, reguser);
- iks_insert_node(regquery, regpass);
- res = iks_send(client->p, regiq);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- if (regiq)
- iks_delete(regiq);
- if (regquery)
- iks_delete(regquery);
- if (reguser)
- iks_delete(reguser);
- if (regpass)
- iks_delete(regpass);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-}
-*/
-/*!
- * \brief goes through roster and prunes users not needed in list, or adds them accordingly.
- * \param aji_client struct.
- * \return void.
- */
-static void aji_pruneregister(struct aji_client *client)
-{
- int res = 0;
- iks *removeiq = iks_new("iq");
- iks *removequery = iks_new("query");
- iks *removeitem = iks_new("item");
- iks *send = iks_make_iq(IKS_TYPE_GET, "http://jabber.org/protocol/disco#items");
-
- if (client && removeiq && removequery && removeitem && send) {
- iks_insert_node(removeiq, removequery);
- iks_insert_node(removequery, removeitem);
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- /* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never
- * be called at the same time */
- if (ast_test_flag(iterator, AJI_AUTOPRUNE)) {
- res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name,
- "GoodBye your status is no longer needed by Asterisk the Open Source PBX"
- " so I am no longer subscribing to your presence.\n"));
- res = iks_send(client->p, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name,
- "GoodBye you are no longer in the asterisk config file so I am removing"
- " your access to my presence.\n"));
- iks_insert_attrib(removeiq, "from", client->jid->full);
- iks_insert_attrib(removeiq, "type", "set");
- iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster");
- iks_insert_attrib(removeitem, "jid", iterator->name);
- iks_insert_attrib(removeitem, "subscription", "remove");
- res = iks_send(client->p, removeiq);
- } else if (ast_test_flag(iterator, AJI_AUTOREGISTER)) {
- res = iks_send(client->p, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name,
- "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
- ast_clear_flag(iterator, AJI_AUTOREGISTER);
- }
- ASTOBJ_UNLOCK(iterator);
- });
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- if (removeiq)
- iks_delete(removeiq);
- if (removequery)
- iks_delete(removequery);
- if (removeitem)
- iks_delete(removeitem);
- if (send)
- iks_delete(send);
- ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy);
-}
-
-/*!
- * \brief filters the roster packet we get back from server.
- * \param aji_client struct, and xml packet.
- * \return IKS_FILTER_EAT.
- */
-static int aji_filter_roster(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- int flag = 0;
- iks *x = NULL;
- struct aji_buddy *buddy;
-
- client->state = AJI_CONNECTED;
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- x = iks_child(pak->query);
- flag = 0;
- while (x) {
- if (!iks_strcmp(iks_name(x), "item")) {
- if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) {
- flag = 1;
- ast_clear_flag(iterator, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
- }
- }
- x = iks_next(x);
- }
- if (!flag)
- ast_copy_flags(iterator, client, AJI_AUTOREGISTER);
- if (x)
- iks_delete(x);
- ASTOBJ_UNLOCK(iterator);
- });
-
- x = iks_child(pak->query);
- while (x) {
- flag = 0;
- if (iks_strcmp(iks_name(x), "item") == 0) {
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid")))
- flag = 1;
- ASTOBJ_UNLOCK(iterator);
- });
-
- if (!flag) {
- buddy = (struct aji_buddy *) malloc(sizeof(struct aji_buddy));
- if (!buddy) {
- ast_log(LOG_WARNING, "Out of memory\n");
- return 0;
- }
- memset(buddy, 0, sizeof(struct aji_buddy));
- ASTOBJ_INIT(buddy);
- ASTOBJ_WRLOCK(buddy);
- ast_copy_string(buddy->name, iks_find_attrib(x, "jid"), sizeof(buddy->name));
- ast_clear_flag(buddy, AST_FLAGS_ALL);
- if(ast_test_flag(client, AJI_AUTOPRUNE)) {
- ast_set_flag(buddy, AJI_AUTOPRUNE);
- buddy->objflags |= ASTOBJ_FLAG_MARKED;
- } else
- ast_set_flag(buddy, AJI_AUTOREGISTER);
- ASTOBJ_UNLOCK(buddy);
- if (buddy) {
- ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
- ASTOBJ_UNREF(buddy, aji_buddy_destroy);
- }
- }
- }
- x = iks_next(x);
- }
- if (x)
- iks_delete(x);
- aji_pruneregister(client);
-
- ASTOBJ_UNREF(client, aji_client_destroy);
- return IKS_FILTER_EAT;
-}
-
-static int aji_reconnect(struct aji_client *client)
-{
- int res = 0;
-
- if (client->state)
- client->state = AJI_DISCONNECTED;
- client->timeout=50;
- if (client->p)
- iks_parser_reset(client->p);
- if (client->authorized)
- client->authorized = 0;
-
- if(client->component)
- res = aji_component_initialize(client);
- else
- res = aji_client_initialize(client);
-
- return res;
-}
-
-static int aji_get_roster(struct aji_client *client)
-{
- iks *roster = NULL;
- roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER);
- if(roster) {
- iks_insert_attrib(roster, "id", "roster");
- aji_set_presence(client, NULL, client->jid->full, 1, client->statusmessage);
- iks_send(client->p, roster);
- }
- if (roster)
- iks_delete(roster);
- return 1;
-}
-
-/*!
- * \brief connects as a client to jabber server.
- * \param aji_client struct, and xml packet.
- * \return res.
- */
-static int aji_client_connect(void *data, ikspak *pak)
-{
- struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
- int res = 0;
-
- if (client) {
- if (client->state == AJI_DISCONNECTED) {
- iks_filter_add_rule(client->f, aji_filter_roster, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "roster", IKS_RULE_DONE);
- client->state = AJI_CONNECTING;
- client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid;
- iks_filter_remove_hook(client->f, aji_client_connect);
- if(!client->component) /*client*/
- aji_get_roster(client);
- }
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
-
- ASTOBJ_UNREF(client, aji_client_destroy);
- return res;
-}
-
-/*!
- * \brief prepares client for connect.
- * \param aji_client struct.
- * \return 1.
- */
-static int aji_client_initialize(struct aji_client *client)
-{
- int connected = 0;
-
- connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->jid->server);
-
- if (connected == IKS_NET_NOCONN) {
- ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n");
- return IKS_HOOK;
- } else if (connected == IKS_NET_NODNS) {
- ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server));
- return IKS_HOOK;
- } else
- iks_recv(client->p, 30);
- return IKS_OK;
-}
-
-/*!
- * \brief prepares component for connect.
- * \param aji_client struct.
- * \return 1.
- */
-static int aji_component_initialize(struct aji_client *client)
-{
- int connected = 1;
-
- connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->user);
- if (connected == IKS_NET_NOCONN) {
- ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n");
- return IKS_HOOK;
- } else if (connected == IKS_NET_NODNS) {
- ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name, S_OR(client->serverhost, client->jid->server));
- return IKS_HOOK;
- } else if (!connected)
- iks_recv(client->p, 30);
- return IKS_OK;
-}
-
-/*!
- * \brief disconnect from jabber server.
- * \param aji_client struct.
- * \return 1.
- */
-int ast_aji_disconnect(struct aji_client *client)
-{
- if (client) {
- if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "JABBER: Disconnecting\n");
- iks_disconnect(client->p);
- iks_parser_delete(client->p);
- ASTOBJ_UNREF(client, aji_client_destroy);
- }
-
- return 1;
-}
-
-/*!
- * \brief set presence of client.
- * \param aji_client struct, user to send it to, and from, level, description.
- * \return void.
- */
-static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc)
-{
- int res = 0;
- iks *presence = iks_make_pres(level, desc);
- iks *cnode = iks_new("c");
- iks *priority = iks_new("priority");
-
- iks_insert_cdata(priority, "0", 1);
- if (presence && cnode && client) {
- if(to)
- iks_insert_attrib(presence, "to", to);
- if(from)
- iks_insert_attrib(presence, "from", from);
- iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps");
- iks_insert_attrib(cnode, "ver", "asterisk-xmpp");
- iks_insert_attrib(cnode, "ext", "voice-v1");
- iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps");
- iks_insert_node(presence, cnode);
- res = iks_send(client->p, presence);
- } else
- ast_log(LOG_ERROR, "Out of memory.\n");
- if (cnode)
- iks_delete(cnode);
- if (presence)
- iks_delete(presence);
-}
-
-/*!
- * \brief turnon console debugging.
- * \param fd, number of args, args.
- * \return RESULT_SUCCESS.
- */
-static int aji_do_debug(int fd, int argc, char *argv[])
-{
- ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
- ASTOBJ_RDLOCK(iterator);
- iterator->debug = 1;
- ASTOBJ_UNLOCK(iterator);
- });
- ast_cli(fd, "Jabber Debugging Enabled.\n");
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief reload jabber module.
- * \param fd, number of args, args.
- * \return RESULT_SUCCESS.
- */
-static int aji_do_reload(int fd, int argc, char *argv[])
-{
- aji_reload();
- ast_cli(fd, "Jabber Reloaded.\n");
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief turnoff console debugging.
- * \param fd, number of args, args.
- * \return RESULT_SUCCESS.
- */
-static int aji_no_debug(int fd, int argc, char *argv[])
-{
- ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
- ASTOBJ_RDLOCK(iterator);
- iterator->debug = 0;
- ASTOBJ_UNLOCK(iterator);
- });
- ast_cli(fd, "Jabber Debugging Disabled.\n");
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief show client status.
- * \param fd, number of args, args.
- * \return RESULT_SUCCESS.
- */
-static int aji_show_clients(int fd, int argc, char *argv[])
-{
- char *status;
- int count = 0;
- ast_cli(fd, "Jabber Users and their status:\n");
- ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
- ASTOBJ_RDLOCK(iterator);
- count++;
- switch (iterator->state) {
- case AJI_DISCONNECTED:
- status = "Disconnected";
- break;
- case AJI_CONNECTING:
- status = "Connecting";
- break;
- case AJI_CONNECTED:
- status = "Connected";
- break;
- default:
- status = "Unknown";
- }
- ast_cli(fd, " User: %s - %s\n", iterator->user, status);
- ASTOBJ_UNLOCK(iterator);
- });
- ast_cli(fd, "----\n");
- ast_cli(fd, " Number of users: %d\n", count);
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief send test message for debugging.
- * \param fd, number of args, args.
- * \return RESULT_SUCCESS.
- */
-static int aji_test(int fd, int argc, char *argv[])
-{
- struct aji_client *client;
- struct aji_resource *resource;
- const char *name = "asterisk";
- struct aji_message *tmp;
-
- if (argc > 3)
- return RESULT_SHOWUSAGE;
- else if (argc == 3)
- name = argv[2];
-
- if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
- ast_cli(fd, "Unable to find client '%s'!\n", name);
- return RESULT_FAILURE;
- }
-
- /* XXX Does Matt really want everyone to use his personal address for tests? */ /* XXX yes he does */
- ast_aji_send(client, "mogorman@astjab.org", "blahblah");
- ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
- ASTOBJ_RDLOCK(iterator);
- ast_verbose("User: %s\n", iterator->name);
- for (resource = iterator->resources; resource; resource = resource->next) {
- ast_verbose("Resource: %s\n", resource->resource);
- if(resource->cap) {
- ast_verbose(" client: %s\n", resource->cap->parent->node);
- ast_verbose(" version: %s\n", resource->cap->version);
- ast_verbose(" Jingle Capable: %d\n", resource->cap->jingle);
- }
- ast_verbose(" Priority: %d\n", resource->priority);
- ast_verbose(" Status: %d\n", resource->status);
- ast_verbose(" Message: %s\n", S_OR(resource->description,""));
- }
- ASTOBJ_UNLOCK(iterator);
- });
- ast_verbose("\nOooh a working message stack!\n");
- AST_LIST_LOCK(&client->messages);
- AST_LIST_TRAVERSE(&client->messages, tmp, list) {
- ast_verbose(" Message from: %s with id %s @ %s %s\n",tmp->from, S_OR(tmp->id,""), ctime(&tmp->arrived), S_OR(tmp->message, ""));
- }
- AST_LIST_UNLOCK(&client->messages);
- ASTOBJ_UNREF(client, aji_client_destroy);
-
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief creates aji_client structure.
- * \param label, ast_variable, debug, pruneregister, component/client, aji_client to dump into.
- * \return 0.
- */
-static int aji_create_client(char *label, struct ast_variable *var, int debug)
-{
- char *resource;
- struct aji_client *client = NULL;
- int flag = 0;
-
- client = ASTOBJ_CONTAINER_FIND(&clients,label);
- if (!client) {
- flag = 1;
- client = (struct aji_client *) malloc(sizeof(struct aji_client));
- if (!client) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- return 0;
- }
- memset(client, 0, sizeof(struct aji_client));
- ASTOBJ_INIT(client);
- ASTOBJ_WRLOCK(client);
- ASTOBJ_CONTAINER_INIT(&client->buddies);
- } else {
- ASTOBJ_WRLOCK(client);
- ASTOBJ_UNMARK(client);
- }
- ASTOBJ_CONTAINER_MARKALL(&client->buddies);
- ast_copy_string(client->name, label, sizeof(client->name));
- ast_copy_string(client->mid, "aaaaa", sizeof(client->mid));
-
- /* Set default values for the client object */
- client->debug = debug;
- ast_copy_flags(client, &globalflags, AST_FLAGS_ALL);
- client->port = 5222;
- client->usetls = 1;
- client->usesasl = 1;
- client->forcessl = 0;
- client->keepalive = 1;
- client->timeout = 50;
- client->message_timeout = 100;
- AST_LIST_HEAD_INIT(&client->messages);
- client->component = 0;
- ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage));
-
- if (flag) {
- client->authorized = 0;
- client->state = AJI_DISCONNECTED;
- }
- while (var) {
- if (!strcasecmp(var->name, "username"))
- ast_copy_string(client->user, var->value, sizeof(client->user));
- else if (!strcasecmp(var->name, "serverhost"))
- ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost));
- else if (!strcasecmp(var->name, "secret"))
- ast_copy_string(client->password, var->value, sizeof(client->password));
- else if (!strcasecmp(var->name, "statusmessage"))
- ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage));
- else if (!strcasecmp(var->name, "port"))
- client->port = atoi(var->value);
- else if (!strcasecmp(var->name, "timeout"))
- client->message_timeout = atoi(var->value);
- else if (!strcasecmp(var->name, "debug"))
- client->debug = (ast_false(var->value)) ? 0 : 1;
- else if (!strcasecmp(var->name, "type")) {
- if (!strcasecmp(var->value, "component"))
- client->component = 1;
- } else if (!strcasecmp(var->name, "usetls")) {
- client->usetls = (ast_false(var->value)) ? 0 : 1;
- } else if (!strcasecmp(var->name, "usesasl")) {
- client->usesasl = (ast_false(var->value)) ? 0 : 1;
- } else if (!strcasecmp(var->name, "forceoldssl"))
- client->forcessl = (ast_false(var->value)) ? 0 : 1;
- else if (!strcasecmp(var->name, "keepalive"))
- client->keepalive = (ast_false(var->value)) ? 0 : 1;
- else if (!strcasecmp(var->name, "autoprune"))
- ast_set2_flag(client, ast_true(var->value), AJI_AUTOPRUNE);
- else if (!strcasecmp(var->name, "autoregister"))
- ast_set2_flag(client, ast_true(var->value), AJI_AUTOREGISTER);
- else if (!strcasecmp(var->name, "buddy"))
- aji_create_buddy(var->value, client);
- /* no transport support in this version */
- /* else if (!strcasecmp(var->name, "transport"))
- aji_create_transport(var->value, client);
- */
- var = var->next;
- }
- if (!flag) {
- ASTOBJ_UNLOCK(client);
- ASTOBJ_UNREF(client, aji_client_destroy);
- return 1;
- }
- client->p = iks_stream_new(((client->component) ? "jabber:component:accept" : "jabber:client"), client, aji_act_hook);
- if (!client->p) {
- ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name);
- return 0;
- }
- client->stack = iks_stack_new(8192, 8192);
- if (!client->stack) {
- ast_log(LOG_ERROR, "Failed to allocate stack for client '%s'\n", client->name);
- return 0;
- }
- client->f = iks_filter_new();
- if (!client->f) {
- ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name);
- return 0;
- }
- if (!strchr(client->user, '/') && !client->component) { /*client */
- resource = NULL;
- asprintf(&resource, "%s/asterisk", client->user);
- if (resource) {
- client->jid = iks_id_new(client->stack, resource);
- free(resource);
- }
- } else
- client->jid = iks_id_new(client->stack, client->user);
- if (client->component) {
- iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
- iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE);
- iks_filter_add_rule(client->f, aji_register_query_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
- iks_filter_add_rule(client->f, aji_register_approve_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_SET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
- } else {
- iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
- }
- if (!strchr(client->user, '/') && !client->component) { /*client */
- resource = NULL;
- asprintf(&resource, "%s/asterisk", client->user);
- if (resource) {
- client->jid = iks_id_new(client->stack, resource);
- free(resource);
- }
- } else
- client->jid = iks_id_new(client->stack, client->user);
- iks_set_log_hook(client->p, aji_log_hook);
- ASTOBJ_UNLOCK(client);
- ASTOBJ_CONTAINER_LINK(&clients,client);
- return 1;
-}
-
-/*!
- * \brief creates transport.
- * \param label, buddy to dump it into.
- * \return 0.
- */
-/* no connecting to transports today */
-/*
-static int aji_create_transport(char *label, struct aji_client *client)
-{
- char *server = NULL, *buddyname = NULL, *user = NULL, *pass = NULL;
- struct aji_buddy *buddy = NULL;
-
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label);
- if (!buddy) {
- buddy = malloc(sizeof(struct aji_buddy));
- if(!buddy) {
- ast_log(LOG_WARNING, "Out of memory\n");
- return 0;
- }
- memset(buddy, 0, sizeof(struct aji_buddy));
- ASTOBJ_INIT(buddy);
- }
- ASTOBJ_WRLOCK(buddy);
- server = label;
- if ((buddyname = strchr(label, ','))) {
- *buddyname = '\0';
- buddyname++;
- if (buddyname && buddyname[0] != '\0') {
- if ((user = strchr(buddyname, ','))) {
- *user = '\0';
- user++;
- if (user && user[0] != '\0') {
- if ((pass = strchr(user, ','))) {
- *pass = '\0';
- pass++;
- ast_copy_string(buddy->pass, pass, sizeof(buddy->pass));
- ast_copy_string(buddy->user, user, sizeof(buddy->user));
- ast_copy_string(buddy->name, buddyname, sizeof(buddy->name));
- ast_copy_string(buddy->server, server, sizeof(buddy->server));
- return 1;
- }
- }
- }
- }
- }
- ASTOBJ_UNLOCK(buddy);
- ASTOBJ_UNMARK(buddy);
- ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
- return 0;
-}
-*/
-
-/*!
- * \brief creates buddy.
- * \param label, buddy to dump it into.
- * \return 0.
- */
-static int aji_create_buddy(char *label, struct aji_client *client)
-{
- struct aji_buddy *buddy = NULL;
- int flag = 0;
- buddy = ASTOBJ_CONTAINER_FIND(&client->buddies,label);
- if (!buddy) {
- flag = 1;
- buddy = malloc(sizeof(struct aji_buddy));
- if(!buddy) {
- ast_log(LOG_WARNING, "Out of memory\n");
- return 0;
- }
- memset(buddy, 0, sizeof(struct aji_buddy));
- ASTOBJ_INIT(buddy);
- }
- ASTOBJ_WRLOCK(buddy);
- ast_copy_string(buddy->name, label, sizeof(buddy->name));
- ASTOBJ_UNLOCK(buddy);
- if(flag)
- ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
- else {
- ASTOBJ_UNMARK(buddy);
- ASTOBJ_UNREF(buddy, aji_buddy_destroy);
- }
- return 1;
-}
-
-/*!
- * \brief load config file.
- * \param void.
- * \return 1.
- */
-static int aji_load_config(void)
-{
- char *cat = NULL;
- int debug = 1;
- struct ast_config *cfg = NULL;
- struct ast_variable *var = NULL;
-
- cfg = ast_config_load(JABBER_CONFIG);
- if (!cfg) {
- ast_log(LOG_WARNING, "No such configuration file %s\n", JABBER_CONFIG);
- return 0;
- }
-
- cat = ast_category_browse(cfg, NULL);
- for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
- if (!strcasecmp(var->name, "debug"))
- debug = (ast_false(ast_variable_retrieve(cfg, "general", "debug"))) ? 0 : 1;
- else if (!strcasecmp(var->name, "autoprune"))
- ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOPRUNE);
- else if (!strcasecmp(var->name, "autoregister"))
- ast_set2_flag(&globalflags, ast_true(var->value), AJI_AUTOREGISTER);
- }
-
- while (cat) {
- if (strcasecmp(cat, "general")) {
- var = ast_variable_browse(cfg, cat);
- aji_create_client(cat, var, debug);
- }
- cat = ast_category_browse(cfg, cat);
- }
- ast_config_destroy(cfg); /* or leak memory */
- return 1;
-}
-
-/*!
- * \brief grab a aji_client structure by label name.
- * \param void.
- * \return 1.
- */
-struct aji_client *ast_aji_get_client(const char *name)
-{
- struct aji_client *client = NULL;
-
- client = ASTOBJ_CONTAINER_FIND(&clients, name);
- if (!client && !strchr(name, '@'))
- client = ASTOBJ_CONTAINER_FIND_FULL(&clients, name, user,,, strcasecmp);
- return client;
-}
-
-struct aji_client_container *ast_aji_get_clients(void)
-{
- return &clients;
-}
-
-static char mandescr_jabber_send[] =
-"Description: Sends a message to a Jabber Client.\n"
-"Variables: \n"
-" Jabber: Client or transport Asterisk uses to connect to JABBER.\n"
-" ScreenName: User Name to message.\n"
-" Message: Message to be sent to the buddy\n";
-
-/*! \brief Send a Jabber Message via call from the Manager */
-static int manager_jabber_send(struct mansession *s, const struct message *m)
-{
- struct aji_client *client = NULL;
- const char *id = astman_get_header(m,"ActionID");
- const char *jabber = astman_get_header(m,"Jabber");
- const char *screenname = astman_get_header(m,"ScreenName");
- const char *message = astman_get_header(m,"Message");
-
- if (ast_strlen_zero(jabber)) {
- astman_send_error(s, m, "No transport specified");
- return 0;
- }
- if (ast_strlen_zero(screenname)) {
- astman_send_error(s, m, "No ScreenName specified");
- return 0;
- }
- if (ast_strlen_zero(message)) {
- astman_send_error(s, m, "No Message specified");
- return 0;
- }
-
- astman_send_ack(s, m, "Attempting to send Jabber Message");
- client = ast_aji_get_client(jabber);
- if (!client) {
- astman_send_error(s, m, "Could not find Sender");
- return 0;
- }
- if (strchr(screenname, '@') && message){
- ast_aji_send(client, screenname, message);
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n",id);
- astman_append(s, "Response: Success\r\n");
- return 0;
- }
- if (!ast_strlen_zero(id))
- astman_append(s, "ActionID: %s\r\n",id);
- astman_append(s, "Response: Failure\r\n");
- return 0;
-}
-
-
-static int aji_reload()
-{
- ASTOBJ_CONTAINER_MARKALL(&clients);
- if (!aji_load_config()) {
- ast_log(LOG_ERROR, "JABBER: Failed to load config.\n");
- return 0;
- }
- ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, aji_client_destroy);
- ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
- ASTOBJ_RDLOCK(iterator);
- if(iterator->state == AJI_DISCONNECTED) {
- if (!iterator->thread)
- ast_pthread_create_background(&iterator->thread, NULL, aji_recv_loop, iterator);
- } else if (iterator->state == AJI_CONNECTING)
- aji_get_roster(iterator);
- ASTOBJ_UNLOCK(iterator);
- });
-
- return 1;
-}
-
-static int unload_module(void)
-{
-
- /* Check if TLS is initialized. If that's the case, we can't unload this
- module due to a bug in the iksemel library that will cause a crash or
- a deadlock. We're trying to find a way to handle this, but in the meantime
- we will simply refuse to die...
- */
- if (tls_initialized) {
- ast_log(LOG_ERROR, "Module can't be unloaded due to a bug in the Iksemel library when using TLS.\n");
- return 1; /* You need a forced unload to get rid of this module */
- }
-
- ast_cli_unregister_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry));
- ast_unregister_application(app_ajisend);
- ast_unregister_application(app_ajistatus);
- ast_manager_unregister("JabberSend");
-
- ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
- ASTOBJ_RDLOCK(iterator);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "JABBER: Releasing and disconneing client: %s\n", iterator->name);
- iterator->state = AJI_DISCONNECTING;
- ast_aji_disconnect(iterator);
- pthread_join(iterator->thread, NULL);
- ASTOBJ_UNLOCK(iterator);
- });
-
- ASTOBJ_CONTAINER_DESTROYALL(&clients, aji_client_destroy);
- ASTOBJ_CONTAINER_DESTROY(&clients);
- return 0;
-}
-
-static int load_module(void)
-{
- ASTOBJ_CONTAINER_INIT(&clients);
- if(!aji_reload())
- return AST_MODULE_LOAD_DECLINE;
- ast_manager_register2("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send,
- "Sends a message to a Jabber Client", mandescr_jabber_send);
- ast_register_application(app_ajisend, aji_send_exec, ajisend_synopsis, ajisend_descrip);
- ast_register_application(app_ajistatus, aji_status_exec, ajistatus_synopsis, ajistatus_descrip);
- ast_cli_register_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry));
-
- return 0;
-}
-
-static int reload(void)
-{
- aji_reload();
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "AJI - Asterisk Jabber Interface",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_monitor.c b/1.4/res/res_monitor.c
deleted file mode 100644
index 4baa1580d..000000000
--- a/1.4/res/res_monitor.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*! \file
- *
- * \brief PBX channel monitoring
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <libgen.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/file.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/manager.h"
-#include "asterisk/cli.h"
-#include "asterisk/monitor.h"
-#include "asterisk/app.h"
-#include "asterisk/utils.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-
-AST_MUTEX_DEFINE_STATIC(monitorlock);
-
-#define LOCK_IF_NEEDED(lock, needed) do { \
- if (needed) \
- ast_channel_lock(lock); \
- } while(0)
-
-#define UNLOCK_IF_NEEDED(lock, needed) do { \
- if (needed) \
- ast_channel_unlock(lock); \
- } while (0)
-
-static unsigned long seq = 0;
-
-static char *monitor_synopsis = "Monitor a channel";
-
-static char *monitor_descrip = "Monitor([file_format[:urlbase]|[fname_base]|[options]]):\n"
-"Used to start monitoring a channel. The channel's input and output\n"
-"voice packets are logged to files until the channel hangs up or\n"
-"monitoring is stopped by the StopMonitor application.\n"
-" file_format optional, if not set, defaults to \"wav\"\n"
-" fname_base if set, changes the filename used to the one specified.\n"
-" options:\n"
-" m - when the recording ends mix the two leg files into one and\n"
-" delete the two leg files. If the variable MONITOR_EXEC is set, the\n"
-" application referenced in it will be executed instead of\n"
-#ifdef HAVE_SOXMIX
-" soxmix and the raw leg files will NOT be deleted automatically.\n"
-" soxmix or MONITOR_EXEC is handed 3 arguments, the two leg files\n"
-#else
-" sox and the raw leg files will NOT be deleted automatically.\n"
-" sox or MONITOR_EXEC is handed 3 arguments, the two leg files\n"
-#endif
-" and a target mixed file name which is the same as the leg file names\n"
-" only without the in/out designator.\n"
-" If MONITOR_EXEC_ARGS is set, the contents will be passed on as\n"
-" additional arguements to MONITOR_EXEC\n"
-" Both MONITOR_EXEC and the Mix flag can be set from the\n"
-" administrator interface\n"
-"\n"
-" b - Don't begin recording unless a call is bridged to another channel\n"
-"\nReturns -1 if monitor files can't be opened or if the channel is already\n"
-"monitored, otherwise 0.\n"
-;
-
-static char *stopmonitor_synopsis = "Stop monitoring a channel";
-
-static char *stopmonitor_descrip = "StopMonitor\n"
- "Stops monitoring a channel. Has no effect if the channel is not monitored\n";
-
-static char *changemonitor_synopsis = "Change monitoring filename of a channel";
-
-static char *changemonitor_descrip = "ChangeMonitor(filename_base)\n"
- "Changes monitoring filename of a channel. Has no effect if the channel is not monitored\n"
- "The argument is the new filename base to use for monitoring this channel.\n";
-
-static char *pausemonitor_synopsis = "Pause monitoring of a channel";
-
-static char *pausemonitor_descrip = "PauseMonitor\n"
- "Pauses monitoring of a channel until it is re-enabled by a call to UnpauseMonitor.\n";
-
-static char *unpausemonitor_synopsis = "Unpause monitoring of a channel";
-
-static char *unpausemonitor_descrip = "UnpauseMonitor\n"
- "Unpauses monitoring of a channel on which monitoring had\n"
- "previously been paused with PauseMonitor.\n";
-
-static int ast_monitor_set_state(struct ast_channel *chan, int state)
-{
- LOCK_IF_NEEDED(chan, 1);
- if (!chan->monitor) {
- UNLOCK_IF_NEEDED(chan, 1);
- return -1;
- }
- chan->monitor->state = state;
- UNLOCK_IF_NEEDED(chan, 1);
- return 0;
-}
-
-/* Start monitoring a channel */
-int ast_monitor_start( struct ast_channel *chan, const char *format_spec,
- const char *fname_base, int need_lock)
-{
- int res = 0;
- char tmp[256];
-
- LOCK_IF_NEEDED(chan, need_lock);
-
- if (!(chan->monitor)) {
- struct ast_channel_monitor *monitor;
- char *channel_name, *p;
-
- /* Create monitoring directory if needed */
- if (mkdir(ast_config_AST_MONITOR_DIR, 0770) < 0) {
- if (errno != EEXIST) {
- ast_log(LOG_WARNING, "Unable to create audio monitor directory: %s\n",
- strerror(errno));
- }
- }
-
- if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
- UNLOCK_IF_NEEDED(chan, need_lock);
- return -1;
- }
-
- /* Determine file names */
- if (!ast_strlen_zero(fname_base)) {
- int directory = strchr(fname_base, '/') ? 1 : 0;
- const char *absolute = *fname_base == '/' ? "" : "/";
- /* try creating the directory just in case it doesn't exist */
- if (directory) {
- char *name = strdup(fname_base);
- snprintf(tmp, sizeof(tmp), "mkdir -p \"%s\"",dirname(name));
- free(name);
- ast_safe_system(tmp);
- }
- snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in",
- directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base);
- snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out",
- directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base);
- ast_copy_string(monitor->filename_base, fname_base, sizeof(monitor->filename_base));
- } else {
- ast_mutex_lock(&monitorlock);
- snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld",
- ast_config_AST_MONITOR_DIR, seq);
- snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld",
- ast_config_AST_MONITOR_DIR, seq);
- seq++;
- ast_mutex_unlock(&monitorlock);
-
- channel_name = ast_strdupa(chan->name);
- while ((p = strchr(channel_name, '/'))) {
- *p = '-';
- }
- snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
- ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name);
- monitor->filename_changed = 1;
- }
-
- monitor->stop = ast_monitor_stop;
-
- /* Determine file format */
- if (!ast_strlen_zero(format_spec)) {
- monitor->format = strdup(format_spec);
- } else {
- monitor->format = strdup("wav");
- }
-
- /* open files */
- if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) {
- ast_filedelete(monitor->read_filename, NULL);
- }
- if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
- monitor->format, NULL,
- O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
- ast_log(LOG_WARNING, "Could not create file %s\n",
- monitor->read_filename);
- free(monitor);
- UNLOCK_IF_NEEDED(chan, need_lock);
- return -1;
- }
- if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
- ast_filedelete(monitor->write_filename, NULL);
- }
- if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
- monitor->format, NULL,
- O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
- ast_log(LOG_WARNING, "Could not create file %s\n",
- monitor->write_filename);
- ast_closestream(monitor->read_stream);
- free(monitor);
- UNLOCK_IF_NEEDED(chan, need_lock);
- return -1;
- }
- chan->monitor = monitor;
- ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
- /* so we know this call has been monitored in case we need to bill for it or something */
- pbx_builtin_setvar_helper(chan, "__MONITORED","true");
- } else {
- ast_log(LOG_DEBUG,"Cannot start monitoring %s, already monitored\n",
- chan->name);
- res = -1;
- }
-
- UNLOCK_IF_NEEDED(chan, need_lock);
-
- return res;
-}
-
-/*
- * The file format extensions that Asterisk uses are not all the same as that
- * which soxmix expects. This function ensures that the format used as the
- * extension on the filename is something soxmix will understand.
- */
-static const char *get_soxmix_format(const char *format)
-{
- const char *res = format;
-
- if (!strcasecmp(format,"ulaw"))
- res = "ul";
- if (!strcasecmp(format,"alaw"))
- res = "al";
-
- return res;
-}
-
-/* Stop monitoring a channel */
-int ast_monitor_stop(struct ast_channel *chan, int need_lock)
-{
- int delfiles = 0;
-
- LOCK_IF_NEEDED(chan, need_lock);
-
- if (chan->monitor) {
- char filename[ FILENAME_MAX ];
-
- if (chan->monitor->read_stream) {
- ast_closestream(chan->monitor->read_stream);
- }
- if (chan->monitor->write_stream) {
- ast_closestream(chan->monitor->write_stream);
- }
-
- if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) {
- if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) {
- snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base);
- if (ast_fileexists(filename, NULL, NULL) > 0) {
- ast_filedelete(filename, NULL);
- }
- ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format);
- } else {
- ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename);
- }
-
- if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) {
- snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base);
- if (ast_fileexists(filename, NULL, NULL) > 0) {
- ast_filedelete(filename, NULL);
- }
- ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format);
- } else {
- ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename);
- }
- }
-
- if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
- char tmp[1024];
- char tmp2[1024];
- const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
- char *name = chan->monitor->filename_base;
- int directory = strchr(name, '/') ? 1 : 0;
- char *dir = directory ? "" : ast_config_AST_MONITOR_DIR;
- const char *execute, *execute_args;
- const char *absolute = *name == '/' ? "" : "/";
-
- /* Set the execute application */
- execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
- if (ast_strlen_zero(execute)) {
-#ifdef HAVE_SOXMIX
- execute = "nice -n 19 soxmix";
-#else
- execute = "nice -n 19 sox -m";
-#endif
- format = get_soxmix_format(format);
- delfiles = 1;
- }
- execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
- if (ast_strlen_zero(execute_args)) {
- execute_args = "";
- }
-
- snprintf(tmp, sizeof(tmp), "%s \"%s%s%s-in.%s\" \"%s%s%s-out.%s\" \"%s%s%s.%s\" %s &", execute, dir, absolute, name, format, dir, absolute, name, format, dir, absolute, name, format,execute_args);
- if (delfiles) {
- snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s%s%s-\"* ) &",tmp, dir, absolute, name); /* remove legs when done mixing */
- ast_copy_string(tmp, tmp2, sizeof(tmp));
- }
- ast_log(LOG_DEBUG,"monitor executing %s\n",tmp);
- if (ast_safe_system(tmp) == -1)
- ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
- }
-
- free(chan->monitor->format);
- free(chan->monitor);
- chan->monitor = NULL;
- }
-
- UNLOCK_IF_NEEDED(chan, need_lock);
-
- return 0;
-}
-
-
-/* Pause monitoring of a channel */
-int ast_monitor_pause(struct ast_channel *chan)
-{
- return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);
-}
-
-/* Unpause monitoring of a channel */
-int ast_monitor_unpause(struct ast_channel *chan)
-{
- return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
-}
-
-static int pause_monitor_exec(struct ast_channel *chan, void *data)
-{
- return ast_monitor_pause(chan);
-}
-
-static int unpause_monitor_exec(struct ast_channel *chan, void *data)
-{
- return ast_monitor_unpause(chan);
-}
-
-/* Change monitoring filename of a channel */
-int ast_monitor_change_fname(struct ast_channel *chan, const char *fname_base, int need_lock)
-{
- char tmp[256];
- if (ast_strlen_zero(fname_base)) {
- ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
- return -1;
- }
-
- LOCK_IF_NEEDED(chan, need_lock);
-
- if (chan->monitor) {
- int directory = strchr(fname_base, '/') ? 1 : 0;
- const char *absolute = *fname_base == '/' ? "" : "/";
- char tmpstring[sizeof(chan->monitor->filename_base)] = "";
-
- /* before continuing, see if we're trying to rename the file to itself... */
- snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base);
- if (!strcmp(tmpstring, chan->monitor->filename_base)) {
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "No need to rename monitor filename to itself\n");
- UNLOCK_IF_NEEDED(chan, need_lock);
- return 0;
- }
-
- /* try creating the directory just in case it doesn't exist */
- if (directory) {
- char *name = strdup(fname_base);
- snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name));
- free(name);
- ast_safe_system(tmp);
- }
-
- ast_copy_string(chan->monitor->filename_base, tmpstring, sizeof(chan->monitor->filename_base));
- chan->monitor->filename_changed = 1;
- } else {
- ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
- }
-
- UNLOCK_IF_NEEDED(chan, need_lock);
-
- return 0;
-}
-
-static int start_monitor_exec(struct ast_channel *chan, void *data)
-{
- char *arg = NULL;
- char *format = NULL;
- char *fname_base = NULL;
- char *options = NULL;
- char *delay = NULL;
- char *urlprefix = NULL;
- char tmp[256];
- int joinfiles = 0;
- int waitforbridge = 0;
- int res = 0;
-
- /* Parse arguments. */
- if (!ast_strlen_zero((char*)data)) {
- arg = ast_strdupa((char*)data);
- format = arg;
- fname_base = strchr(arg, '|');
- if (fname_base) {
- *fname_base = 0;
- fname_base++;
- if ((options = strchr(fname_base, '|'))) {
- *options = 0;
- options++;
- if (strchr(options, 'm'))
- joinfiles = 1;
- if (strchr(options, 'b'))
- waitforbridge = 1;
- }
- }
- arg = strchr(format,':');
- if (arg) {
- *arg++ = 0;
- urlprefix = arg;
- }
- }
- if (urlprefix) {
- snprintf(tmp,sizeof(tmp) - 1,"%s/%s.%s",urlprefix,fname_base,
- ((strcmp(format,"gsm")) ? "wav" : "gsm"));
- if (!chan->cdr && !(chan->cdr = ast_cdr_alloc()))
- return -1;
- ast_cdr_setuserfield(chan, tmp);
- }
- if (waitforbridge) {
- /* We must remove the "b" option if listed. In principle none of
- the following could give NULL results, but we check just to
- be pedantic. Reconstructing with checks for 'm' option does not
- work if we end up adding more options than 'm' in the future. */
- delay = ast_strdupa(data);
- options = strrchr(delay, '|');
- if (options) {
- arg = strchr(options, 'b');
- if (arg) {
- *arg = 'X';
- pbx_builtin_setvar_helper(chan,"AUTO_MONITOR",delay);
- }
- }
- return 0;
- }
-
- res = ast_monitor_start(chan, format, fname_base, 1);
- if (res < 0)
- res = ast_monitor_change_fname(chan, fname_base, 1);
- ast_monitor_setjoinfiles(chan, joinfiles);
-
- return res;
-}
-
-static int stop_monitor_exec(struct ast_channel *chan, void *data)
-{
- return ast_monitor_stop(chan, 1);
-}
-
-static int change_monitor_exec(struct ast_channel *chan, void *data)
-{
- return ast_monitor_change_fname(chan, (const char*)data, 1);
-}
-
-static char start_monitor_action_help[] =
-"Description: The 'Monitor' action may be used to record the audio on a\n"
-" specified channel. The following parameters may be used to control\n"
-" this:\n"
-" Channel - Required. Used to specify the channel to record.\n"
-" File - Optional. Is the name of the file created in the\n"
-" monitor spool directory. Defaults to the same name\n"
-" as the channel (with slashes replaced with dashes).\n"
-" Format - Optional. Is the audio recording format. Defaults\n"
-" to \"wav\".\n"
-" Mix - Optional. Boolean parameter as to whether to mix\n"
-" the input and output channels together after the\n"
-" recording is finished.\n";
-
-static int start_monitor_action(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- const char *fname = astman_get_header(m, "File");
- const char *format = astman_get_header(m, "Format");
- const char *mix = astman_get_header(m, "Mix");
- char *d;
-
- if (ast_strlen_zero(name)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
-
- if (ast_strlen_zero(fname)) {
- /* No filename base specified, default to channel name as per CLI */
- if (!(fname = ast_strdup(c->name))) {
- astman_send_error(s, m, "Could not start monitoring channel");
- ast_channel_unlock(c);
- return 0;
- }
- /* Channels have the format technology/channel_name - have to replace that / */
- if ((d = strchr(fname, '/')))
- *d = '-';
- }
-
- if (ast_monitor_start(c, format, fname, 1)) {
- if (ast_monitor_change_fname(c, fname, 1)) {
- astman_send_error(s, m, "Could not start monitoring channel");
- ast_channel_unlock(c);
- return 0;
- }
- }
-
- if (ast_true(mix)) {
- ast_monitor_setjoinfiles(c, 1);
- }
-
- ast_channel_unlock(c);
- astman_send_ack(s, m, "Started monitoring channel");
- return 0;
-}
-
-static char stop_monitor_action_help[] =
-"Description: The 'StopMonitor' action may be used to end a previously\n"
-" started 'Monitor' action. The only parameter is 'Channel', the name\n"
-" of the channel monitored.\n";
-
-static int stop_monitor_action(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- int res;
- if (ast_strlen_zero(name)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- res = ast_monitor_stop(c, 1);
- ast_channel_unlock(c);
- if (res) {
- astman_send_error(s, m, "Could not stop monitoring channel");
- return 0;
- }
- astman_send_ack(s, m, "Stopped monitoring channel");
- return 0;
-}
-
-static char change_monitor_action_help[] =
-"Description: The 'ChangeMonitor' action may be used to change the file\n"
-" started by a previous 'Monitor' action. The following parameters may\n"
-" be used to control this:\n"
-" Channel - Required. Used to specify the channel to record.\n"
-" File - Required. Is the new name of the file created in the\n"
-" monitor spool directory.\n";
-
-static int change_monitor_action(struct mansession *s, const struct message *m)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
- const char *fname = astman_get_header(m, "File");
- if (ast_strlen_zero(name)) {
- astman_send_error(s, m, "No channel specified");
- return 0;
- }
- if (ast_strlen_zero(fname)) {
- astman_send_error(s, m, "No filename specified");
- return 0;
- }
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return 0;
- }
- if (ast_monitor_change_fname(c, fname, 1)) {
- astman_send_error(s, m, "Could not change monitored filename of channel");
- ast_channel_unlock(c);
- return 0;
- }
- ast_channel_unlock(c);
- astman_send_ack(s, m, "Changed monitor filename");
- return 0;
-}
-
-void ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon)
-{
- if (chan->monitor)
- chan->monitor->joinfiles = turnon;
-}
-
-#define IS_NULL_STRING(string) ((!(string)) || (ast_strlen_zero((string))))
-
-enum MONITOR_PAUSING_ACTION
-{
- MONITOR_ACTION_PAUSE,
- MONITOR_ACTION_UNPAUSE
-};
-
-static int do_pause_or_unpause(struct mansession *s, const struct message *m, int action)
-{
- struct ast_channel *c = NULL;
- const char *name = astman_get_header(m, "Channel");
-
- if (IS_NULL_STRING(name)) {
- astman_send_error(s, m, "No channel specified");
- return -1;
- }
-
- c = ast_get_channel_by_name_locked(name);
- if (!c) {
- astman_send_error(s, m, "No such channel");
- return -1;
- }
-
- if (action == MONITOR_ACTION_PAUSE)
- ast_monitor_pause(c);
- else
- ast_monitor_unpause(c);
-
- ast_channel_unlock(c);
- astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
- return 0;
-}
-
-static char pause_monitor_action_help[] =
- "Description: The 'PauseMonitor' action may be used to temporarily stop the\n"
- " recording of a channel. The following parameters may\n"
- " be used to control this:\n"
- " Channel - Required. Used to specify the channel to record.\n";
-
-static int pause_monitor_action(struct mansession *s, const struct message *m)
-{
- return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);
-}
-
-static char unpause_monitor_action_help[] =
- "Description: The 'UnpauseMonitor' action may be used to re-enable recording\n"
- " of a channel after calling PauseMonitor. The following parameters may\n"
- " be used to control this:\n"
- " Channel - Required. Used to specify the channel to record.\n";
-
-static int unpause_monitor_action(struct mansession *s, const struct message *m)
-{
- return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);
-}
-
-
-static int load_module(void)
-{
- ast_register_application("Monitor", start_monitor_exec, monitor_synopsis, monitor_descrip);
- ast_register_application("StopMonitor", stop_monitor_exec, stopmonitor_synopsis, stopmonitor_descrip);
- ast_register_application("ChangeMonitor", change_monitor_exec, changemonitor_synopsis, changemonitor_descrip);
- ast_register_application("PauseMonitor", pause_monitor_exec, pausemonitor_synopsis, pausemonitor_descrip);
- ast_register_application("UnpauseMonitor", unpause_monitor_exec, unpausemonitor_synopsis, unpausemonitor_descrip);
- ast_manager_register2("Monitor", EVENT_FLAG_CALL, start_monitor_action, monitor_synopsis, start_monitor_action_help);
- ast_manager_register2("StopMonitor", EVENT_FLAG_CALL, stop_monitor_action, stopmonitor_synopsis, stop_monitor_action_help);
- ast_manager_register2("ChangeMonitor", EVENT_FLAG_CALL, change_monitor_action, changemonitor_synopsis, change_monitor_action_help);
- ast_manager_register2("PauseMonitor", EVENT_FLAG_CALL, pause_monitor_action, pausemonitor_synopsis, pause_monitor_action_help);
- ast_manager_register2("UnpauseMonitor", EVENT_FLAG_CALL, unpause_monitor_action, unpausemonitor_synopsis, unpause_monitor_action_help);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_unregister_application("Monitor");
- ast_unregister_application("StopMonitor");
- ast_unregister_application("ChangeMonitor");
- ast_unregister_application("PauseMonitor");
- ast_unregister_application("UnpauseMonitor");
- ast_manager_unregister("Monitor");
- ast_manager_unregister("StopMonitor");
- ast_manager_unregister("ChangeMonitor");
- ast_manager_unregister("PauseMonitor");
- ast_manager_unregister("UnpauseMonitor");
-
- return 0;
-}
-
-/* usecount semantics need to be defined */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Call Monitoring Resource",
- .load = load_module,
- .unload = unload_module,
- );
diff --git a/1.4/res/res_musiconhold.c b/1.4/res/res_musiconhold.c
deleted file mode 100644
index faab84cae..000000000
--- a/1.4/res/res_musiconhold.c
+++ /dev/null
@@ -1,1353 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file
- *
- * \brief Routines implementing music on hold
- *
- * \arg See also \ref Config_moh
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-/*** MODULEINFO
- <conflict>win32</conflict>
- <use>zaptel</use>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/signal.h>
-#include <netinet/in.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#ifdef SOLARIS
-#include <thread.h>
-#endif
-
-#ifdef HAVE_ZAPTEL
-#include <zaptel/zaptel.h>
-#endif
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/options.h"
-#include "asterisk/module.h"
-#include "asterisk/translate.h"
-#include "asterisk/say.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/config.h"
-#include "asterisk/utils.h"
-#include "asterisk/cli.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/linkedlists.h"
-
-#define INITIAL_NUM_FILES 8
-
-static char *app0 = "MusicOnHold";
-static char *app1 = "WaitMusicOnHold";
-static char *app2 = "SetMusicOnHold";
-static char *app3 = "StartMusicOnHold";
-static char *app4 = "StopMusicOnHold";
-
-static char *synopsis0 = "Play Music On Hold indefinitely";
-static char *synopsis1 = "Wait, playing Music On Hold";
-static char *synopsis2 = "Set default Music On Hold class";
-static char *synopsis3 = "Play Music On Hold";
-static char *synopsis4 = "Stop Playing Music On Hold";
-
-static char *descrip0 = "MusicOnHold(class): "
-"Plays hold music specified by class. If omitted, the default\n"
-"music source for the channel will be used. Set the default \n"
-"class with the SetMusicOnHold() application.\n"
-"Returns -1 on hangup.\n"
-"Never returns otherwise.\n";
-
-static char *descrip1 = "WaitMusicOnHold(delay): "
-"Plays hold music specified number of seconds. Returns 0 when\n"
-"done, or -1 on hangup. If no hold music is available, the delay will\n"
-"still occur with no sound.\n";
-
-static char *descrip2 = "SetMusicOnHold(class): "
-"Sets the default class for music on hold for a given channel. When\n"
-"music on hold is activated, this class will be used to select which\n"
-"music is played.\n";
-
-static char *descrip3 = "StartMusicOnHold(class): "
-"Starts playing music on hold, uses default music class for channel.\n"
-"Starts playing music specified by class. If omitted, the default\n"
-"music source for the channel will be used. Always returns 0.\n";
-
-static char *descrip4 = "StopMusicOnHold: "
-"Stops playing music on hold.\n";
-
-static int respawn_time = 20;
-
-struct moh_files_state {
- struct mohclass *class;
- int origwfmt;
- int samples;
- int sample_queue;
- int pos;
- int save_pos;
- char *save_pos_filename;
-};
-
-#define MOH_QUIET (1 << 0)
-#define MOH_SINGLE (1 << 1)
-#define MOH_CUSTOM (1 << 2)
-#define MOH_RANDOMIZE (1 << 3)
-
-struct mohclass {
- char name[MAX_MUSICCLASS];
- char dir[256];
- char args[256];
- char mode[80];
- /*! A dynamically sized array to hold the list of filenames in "files" mode */
- char **filearray;
- /*! The current size of the filearray */
- int allowed_files;
- /*! The current number of files loaded into the filearray */
- int total_files;
- unsigned int flags;
- /*! The format from the MOH source, not applicable to "files" mode */
- int format;
- /*! The pid of the external application delivering MOH */
- int pid;
- time_t start;
- pthread_t thread;
- /*! Source of audio */
- int srcfd;
- /*! FD for timing source */
- int pseudofd;
- /*! Number of users */
- int inuse;
- unsigned int delete:1;
- AST_LIST_HEAD_NOLOCK(, mohdata) members;
- AST_LIST_ENTRY(mohclass) list;
-};
-
-struct mohdata {
- int pipe[2];
- int origwfmt;
- struct mohclass *parent;
- struct ast_frame f;
- AST_LIST_ENTRY(mohdata) list;
-};
-
-AST_LIST_HEAD_STATIC(mohclasses, mohclass);
-
-#define LOCAL_MPG_123 "/usr/local/bin/mpg123"
-#define MPG_123 "/usr/bin/mpg123"
-#define MAX_MP3S 256
-
-static int ast_moh_destroy_one(struct mohclass *moh);
-static int reload(void);
-
-static void ast_moh_free_class(struct mohclass **mohclass)
-{
- struct mohdata *member;
- struct mohclass *class = *mohclass;
- int i;
-
- while ((member = AST_LIST_REMOVE_HEAD(&class->members, list)))
- free(member);
-
- if (class->thread) {
- pthread_cancel(class->thread);
- class->thread = 0;
- }
-
- if (class->filearray) {
- for (i = 0; i < class->total_files; i++)
- free(class->filearray[i]);
- free(class->filearray);
- }
-
- free(class);
- *mohclass = NULL;
-}
-
-
-static void moh_files_release(struct ast_channel *chan, void *data)
-{
- struct moh_files_state *state;
-
- if (chan) {
- if ((state = chan->music_state)) {
- if (chan->stream) {
- ast_closestream(chan->stream);
- chan->stream = NULL;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
-
- if (state->origwfmt && ast_set_write_format(chan, state->origwfmt)) {
- ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, state->origwfmt);
- }
- state->save_pos = state->pos;
-
- if (ast_atomic_dec_and_test(&state->class->inuse) && state->class->delete)
- ast_moh_destroy_one(state->class);
- }
- }
-}
-
-
-static int ast_moh_files_next(struct ast_channel *chan)
-{
- struct moh_files_state *state = chan->music_state;
- int tries;
-
- /* Discontinue a stream if it is running already */
- if (chan->stream) {
- ast_closestream(chan->stream);
- chan->stream = NULL;
- }
-
- if (!state->class->total_files) {
- ast_log(LOG_WARNING, "No files available for class '%s'\n", state->class->name);
- return -1;
- }
-
- /* If a specific file has been saved confirm it still exists and that it is still valid */
- if (state->save_pos >= 0 && state->save_pos < state->class->total_files && state->class->filearray[state->save_pos] == state->save_pos_filename) {
- state->pos = state->save_pos;
- state->save_pos = -1;
- } else if (ast_test_flag(state->class, MOH_RANDOMIZE)) {
- /* Get a random file and ensure we can open it */
- for (tries = 0; tries < 20; tries++) {
- state->pos = ast_random() % state->class->total_files;
- if (ast_fileexists(state->class->filearray[state->pos], NULL, NULL) > 0)
- break;
- }
- state->save_pos = -1;
- state->samples = 0;
- } else {
- /* This is easy, just increment our position and make sure we don't exceed the total file count */
- state->pos++;
- state->pos %= state->class->total_files;
- state->save_pos = -1;
- state->samples = 0;
- }
-
- if (!ast_openstream_full(chan, state->class->filearray[state->pos], chan->language, 1)) {
- ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", state->class->filearray[state->pos], strerror(errno));
- state->pos++;
- state->pos %= state->class->total_files;
- return -1;
- }
-
- /* Record the pointer to the filename for position resuming later */
- state->save_pos_filename = state->class->filearray[state->pos];
-
- if (option_debug)
- ast_log(LOG_DEBUG, "%s Opened file %d '%s'\n", chan->name, state->pos, state->class->filearray[state->pos]);
-
- if (state->samples)
- ast_seekstream(chan->stream, state->samples, SEEK_SET);
-
- return 0;
-}
-
-
-static struct ast_frame *moh_files_readframe(struct ast_channel *chan)
-{
- struct ast_frame *f = NULL;
-
- if (!(chan->stream && (f = ast_readframe(chan->stream)))) {
- if (!ast_moh_files_next(chan))
- f = ast_readframe(chan->stream);
- }
-
- return f;
-}
-
-static int moh_files_generator(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct moh_files_state *state = chan->music_state;
- struct ast_frame *f = NULL;
- int res = 0;
-
- state->sample_queue += samples;
-
- while (state->sample_queue > 0) {
- if ((f = moh_files_readframe(chan))) {
- state->samples += f->samples;
- state->sample_queue -= f->samples;
- res = ast_write(chan, f);
- ast_frfree(f);
- if (res < 0) {
- ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
- return -1;
- }
- } else
- return -1;
- }
- return res;
-}
-
-
-static void *moh_files_alloc(struct ast_channel *chan, void *params)
-{
- struct moh_files_state *state;
- struct mohclass *class = params;
-
- if (!chan->music_state && (state = ast_calloc(1, sizeof(*state)))) {
- chan->music_state = state;
- state->class = class;
- state->save_pos = -1;
- } else
- state = chan->music_state;
-
- if (state) {
- if (state->class != class) {
- /* initialize */
- memset(state, 0, sizeof(*state));
- state->class = class;
- if (ast_test_flag(state->class, MOH_RANDOMIZE) && class->total_files)
- state->pos = ast_random() % class->total_files;
- }
-
- state->origwfmt = chan->writeformat;
-
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on %s\n", class->name, chan->name);
- }
-
- return chan->music_state;
-}
-
-static struct ast_generator moh_file_stream =
-{
- alloc: moh_files_alloc,
- release: moh_files_release,
- generate: moh_files_generator,
-};
-
-static int spawn_mp3(struct mohclass *class)
-{
- int fds[2];
- int files = 0;
- char fns[MAX_MP3S][80];
- char *argv[MAX_MP3S + 50];
- char xargs[256];
- char *argptr;
- int argc = 0;
- DIR *dir = NULL;
- struct dirent *de;
- sigset_t signal_set, old_set;
-
-
- if (!strcasecmp(class->dir, "nodir")) {
- files = 1;
- } else {
- dir = opendir(class->dir);
- if (!dir && !strstr(class->dir,"http://") && !strstr(class->dir,"HTTP://")) {
- ast_log(LOG_WARNING, "%s is not a valid directory\n", class->dir);
- return -1;
- }
- }
-
- if (!ast_test_flag(class, MOH_CUSTOM)) {
- argv[argc++] = "mpg123";
- argv[argc++] = "-q";
- argv[argc++] = "-s";
- argv[argc++] = "--mono";
- argv[argc++] = "-r";
- argv[argc++] = "8000";
-
- if (!ast_test_flag(class, MOH_SINGLE)) {
- argv[argc++] = "-b";
- argv[argc++] = "2048";
- }
-
- argv[argc++] = "-f";
-
- if (ast_test_flag(class, MOH_QUIET))
- argv[argc++] = "4096";
- else
- argv[argc++] = "8192";
-
- /* Look for extra arguments and add them to the list */
- ast_copy_string(xargs, class->args, sizeof(xargs));
- argptr = xargs;
- while (!ast_strlen_zero(argptr)) {
- argv[argc++] = argptr;
- strsep(&argptr, ",");
- }
- } else {
- /* Format arguments for argv vector */
- ast_copy_string(xargs, class->args, sizeof(xargs));
- argptr = xargs;
- while (!ast_strlen_zero(argptr)) {
- argv[argc++] = argptr;
- strsep(&argptr, " ");
- }
- }
-
-
- if (strstr(class->dir,"http://") || strstr(class->dir,"HTTP://")) {
- ast_copy_string(fns[files], class->dir, sizeof(fns[files]));
- argv[argc++] = fns[files];
- files++;
- } else if (dir) {
- while ((de = readdir(dir)) && (files < MAX_MP3S)) {
- if ((strlen(de->d_name) > 3) &&
- ((ast_test_flag(class, MOH_CUSTOM) &&
- (!strcasecmp(de->d_name + strlen(de->d_name) - 4, ".raw") ||
- !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".sln"))) ||
- !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".mp3"))) {
- ast_copy_string(fns[files], de->d_name, sizeof(fns[files]));
- argv[argc++] = fns[files];
- files++;
- }
- }
- }
- argv[argc] = NULL;
- if (dir) {
- closedir(dir);
- }
- if (pipe(fds)) {
- ast_log(LOG_WARNING, "Pipe failed\n");
- return -1;
- }
- if (!files) {
- ast_log(LOG_WARNING, "Found no files in '%s'\n", class->dir);
- close(fds[0]);
- close(fds[1]);
- return -1;
- }
- if (time(NULL) - class->start < respawn_time) {
- sleep(respawn_time - (time(NULL) - class->start));
- }
-
- /* Block signals during the fork() */
- sigfillset(&signal_set);
- pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
-
- time(&class->start);
- class->pid = fork();
- if (class->pid < 0) {
- close(fds[0]);
- close(fds[1]);
- ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
- return -1;
- }
- if (!class->pid) {
- int x;
-
- if (ast_opt_high_priority)
- ast_set_priority(0);
-
- /* Reset ignored signals back to default */
- signal(SIGPIPE, SIG_DFL);
- pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL);
-
- close(fds[0]);
- /* Stdout goes to pipe */
- dup2(fds[1], STDOUT_FILENO);
- /* Close unused file descriptors */
- for (x=3;x<8192;x++) {
- if (-1 != fcntl(x, F_GETFL)) {
- close(x);
- }
- }
- /* Child */
- chdir(class->dir);
- if (ast_test_flag(class, MOH_CUSTOM)) {
- execv(argv[0], argv);
- } else {
- /* Default install is /usr/local/bin */
- execv(LOCAL_MPG_123, argv);
- /* Many places have it in /usr/bin */
- execv(MPG_123, argv);
- /* Check PATH as a last-ditch effort */
- execvp("mpg123", argv);
- }
- ast_log(LOG_WARNING, "Exec failed: %s\n", strerror(errno));
- close(fds[1]);
- _exit(1);
- } else {
- /* Parent */
- pthread_sigmask(SIG_SETMASK, &old_set, NULL);
- close(fds[1]);
- }
- return fds[0];
-}
-
-static void *monmp3thread(void *data)
-{
-#define MOH_MS_INTERVAL 100
-
- struct mohclass *class = data;
- struct mohdata *moh;
- char buf[8192];
- short sbuf[8192];
- int res, res2;
- int len;
- struct timeval tv, tv_tmp;
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- for(;/* ever */;) {
- pthread_testcancel();
- /* Spawn mp3 player if it's not there */
- if (class->srcfd < 0) {
- if ((class->srcfd = spawn_mp3(class)) < 0) {
- ast_log(LOG_WARNING, "Unable to spawn mp3player\n");
- /* Try again later */
- sleep(500);
- pthread_testcancel();
- }
- }
- if (class->pseudofd > -1) {
-#ifdef SOLARIS
- thr_yield();
-#endif
- /* Pause some amount of time */
- res = read(class->pseudofd, buf, sizeof(buf));
- pthread_testcancel();
- } else {
- long delta;
- /* Reliable sleep */
- tv_tmp = ast_tvnow();
- if (ast_tvzero(tv))
- tv = tv_tmp;
- delta = ast_tvdiff_ms(tv_tmp, tv);
- if (delta < MOH_MS_INTERVAL) { /* too early */
- tv = ast_tvadd(tv, ast_samp2tv(MOH_MS_INTERVAL, 1000)); /* next deadline */
- usleep(1000 * (MOH_MS_INTERVAL - delta));
- pthread_testcancel();
- } else {
- ast_log(LOG_NOTICE, "Request to schedule in the past?!?!\n");
- tv = tv_tmp;
- }
- res = 8 * MOH_MS_INTERVAL; /* 8 samples per millisecond */
- }
- if (AST_LIST_EMPTY(&class->members))
- continue;
- /* Read mp3 audio */
- len = ast_codec_get_len(class->format, res);
-
- if ((res2 = read(class->srcfd, sbuf, len)) != len) {
- if (!res2) {
- close(class->srcfd);
- class->srcfd = -1;
- pthread_testcancel();
- if (class->pid > 1) {
- kill(class->pid, SIGHUP);
- usleep(100000);
- kill(class->pid, SIGTERM);
- usleep(100000);
- kill(class->pid, SIGKILL);
- class->pid = 0;
- }
- } else
- ast_log(LOG_DEBUG, "Read %d bytes of audio while expecting %d\n", res2, len);
- continue;
- }
- pthread_testcancel();
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_TRAVERSE(&class->members, moh, list) {
- /* Write data */
- if ((res = write(moh->pipe[1], sbuf, res2)) != res2) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Only wrote %d of %d bytes to pipe\n", res, res2);
- }
- }
- AST_LIST_UNLOCK(&mohclasses);
- }
- return NULL;
-}
-
-static int moh0_exec(struct ast_channel *chan, void *data)
-{
- if (ast_moh_start(chan, data, NULL)) {
- ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name);
- return 0;
- }
- while (!ast_safe_sleep(chan, 10000));
- ast_moh_stop(chan);
- return -1;
-}
-
-static int moh1_exec(struct ast_channel *chan, void *data)
-{
- int res;
- if (!data || !atoi(data)) {
- ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n");
- return -1;
- }
- if (ast_moh_start(chan, NULL, NULL)) {
- ast_log(LOG_WARNING, "Unable to start music on hold for %d seconds on channel %s\n", atoi(data), chan->name);
- return 0;
- }
- res = ast_safe_sleep(chan, atoi(data) * 1000);
- ast_moh_stop(chan);
- return res;
-}
-
-static int moh2_exec(struct ast_channel *chan, void *data)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SetMusicOnHold requires an argument (class)\n");
- return -1;
- }
- ast_string_field_set(chan, musicclass, data);
- return 0;
-}
-
-static int moh3_exec(struct ast_channel *chan, void *data)
-{
- char *class = NULL;
- if (data && strlen(data))
- class = data;
- if (ast_moh_start(chan, class, NULL))
- ast_log(LOG_NOTICE, "Unable to start music on hold class '%s' on channel %s\n", class ? class : "default", chan->name);
-
- return 0;
-}
-
-static int moh4_exec(struct ast_channel *chan, void *data)
-{
- ast_moh_stop(chan);
-
- return 0;
-}
-
-/*! \note This function should be called with the mohclasses list locked */
-static struct mohclass *get_mohbyname(const char *name, int warn)
-{
- struct mohclass *moh = NULL;
-
- AST_LIST_TRAVERSE(&mohclasses, moh, list) {
- if (!strcasecmp(name, moh->name))
- break;
- }
-
- if (!moh && warn)
- ast_log(LOG_WARNING, "Music on Hold class '%s' not found\n", name);
-
- return moh;
-}
-
-static struct mohdata *mohalloc(struct mohclass *cl)
-{
- struct mohdata *moh;
- long flags;
-
- if (!(moh = ast_calloc(1, sizeof(*moh))))
- return NULL;
-
- if (pipe(moh->pipe)) {
- ast_log(LOG_WARNING, "Failed to create pipe: %s\n", strerror(errno));
- free(moh);
- return NULL;
- }
-
- /* Make entirely non-blocking */
- flags = fcntl(moh->pipe[0], F_GETFL);
- fcntl(moh->pipe[0], F_SETFL, flags | O_NONBLOCK);
- flags = fcntl(moh->pipe[1], F_GETFL);
- fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK);
-
- moh->f.frametype = AST_FRAME_VOICE;
- moh->f.subclass = cl->format;
- moh->f.offset = AST_FRIENDLY_OFFSET;
-
- moh->parent = cl;
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_INSERT_HEAD(&cl->members, moh, list);
- AST_LIST_UNLOCK(&mohclasses);
-
- return moh;
-}
-
-static void moh_release(struct ast_channel *chan, void *data)
-{
- struct mohdata *moh = data;
- int oldwfmt;
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_REMOVE(&moh->parent->members, moh, list);
- AST_LIST_UNLOCK(&mohclasses);
-
- close(moh->pipe[0]);
- close(moh->pipe[1]);
- oldwfmt = moh->origwfmt;
- if (moh->parent->delete && ast_atomic_dec_and_test(&moh->parent->inuse))
- ast_moh_destroy_one(moh->parent);
- free(moh);
- if (chan) {
- if (oldwfmt && ast_set_write_format(chan, oldwfmt))
- ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(oldwfmt));
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
- }
-}
-
-static void *moh_alloc(struct ast_channel *chan, void *params)
-{
- struct mohdata *res;
- struct mohclass *class = params;
-
- if ((res = mohalloc(class))) {
- res->origwfmt = chan->writeformat;
- if (ast_set_write_format(chan, class->format)) {
- ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(class->format));
- moh_release(NULL, res);
- res = NULL;
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on channel '%s'\n", class->name, chan->name);
- }
- return res;
-}
-
-static int moh_generate(struct ast_channel *chan, void *data, int len, int samples)
-{
- struct mohdata *moh = data;
- short buf[1280 + AST_FRIENDLY_OFFSET / 2];
- int res;
-
- if (!moh->parent->pid)
- return -1;
-
- len = ast_codec_get_len(moh->parent->format, samples);
-
- if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
- ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", (int)sizeof(buf), len, chan->name);
- len = sizeof(buf) - AST_FRIENDLY_OFFSET;
- }
- res = read(moh->pipe[0], buf + AST_FRIENDLY_OFFSET/2, len);
- if (res <= 0)
- return 0;
-
- moh->f.datalen = res;
- moh->f.data = buf + AST_FRIENDLY_OFFSET / 2;
- moh->f.samples = ast_codec_get_samples(&moh->f);
-
- if (ast_write(chan, &moh->f) < 0) {
- ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static struct ast_generator mohgen =
-{
- alloc: moh_alloc,
- release: moh_release,
- generate: moh_generate,
-};
-
-static int moh_add_file(struct mohclass *class, const char *filepath)
-{
- if (!class->allowed_files) {
- if (!(class->filearray = ast_calloc(1, INITIAL_NUM_FILES * sizeof(*class->filearray))))
- return -1;
- class->allowed_files = INITIAL_NUM_FILES;
- } else if (class->total_files == class->allowed_files) {
- if (!(class->filearray = ast_realloc(class->filearray, class->allowed_files * sizeof(*class->filearray) * 2))) {
- class->allowed_files = 0;
- class->total_files = 0;
- return -1;
- }
- class->allowed_files *= 2;
- }
-
- if (!(class->filearray[class->total_files] = ast_strdup(filepath)))
- return -1;
-
- class->total_files++;
-
- return 0;
-}
-
-static int moh_scan_files(struct mohclass *class) {
-
- DIR *files_DIR;
- struct dirent *files_dirent;
- char path[PATH_MAX];
- char filepath[PATH_MAX];
- char *ext;
- struct stat statbuf;
- int dirnamelen;
- int i;
-
- files_DIR = opendir(class->dir);
- if (!files_DIR) {
- ast_log(LOG_WARNING, "Cannot open dir %s or dir does not exist\n", class->dir);
- return -1;
- }
-
- for (i = 0; i < class->total_files; i++)
- free(class->filearray[i]);
-
- class->total_files = 0;
- dirnamelen = strlen(class->dir) + 2;
- getcwd(path, sizeof(path));
- chdir(class->dir);
- while ((files_dirent = readdir(files_DIR))) {
- /* The file name must be at least long enough to have the file type extension */
- if ((strlen(files_dirent->d_name) < 4))
- continue;
-
- /* Skip files that starts with a dot */
- if (files_dirent->d_name[0] == '.')
- continue;
-
- /* Skip files without extensions... they are not audio */
- if (!strchr(files_dirent->d_name, '.'))
- continue;
-
- snprintf(filepath, sizeof(filepath), "%s/%s", class->dir, files_dirent->d_name);
-
- if (stat(filepath, &statbuf))
- continue;
-
- if (!S_ISREG(statbuf.st_mode))
- continue;
-
- if ((ext = strrchr(filepath, '.'))) {
- *ext = '\0';
- ext++;
- }
-
- /* if the file is present in multiple formats, ensure we only put it into the list once */
- for (i = 0; i < class->total_files; i++)
- if (!strcmp(filepath, class->filearray[i]))
- break;
-
- if (i == class->total_files) {
- if (moh_add_file(class, filepath))
- break;
- }
- }
-
- closedir(files_DIR);
- chdir(path);
- return class->total_files;
-}
-
-static int moh_register(struct mohclass *moh, int reload)
-{
-#ifdef HAVE_ZAPTEL
- int x;
-#endif
- struct mohclass *mohclass = NULL;
- int res = 0;
-
- AST_LIST_LOCK(&mohclasses);
- if ((mohclass = get_mohbyname(moh->name, 0))) {
- if (!mohclass->delete) {
- ast_log(LOG_WARNING, "Music on Hold class '%s' already exists\n", moh->name);
- free(moh);
- AST_LIST_UNLOCK(&mohclasses);
- return -1;
- }
- }
- AST_LIST_UNLOCK(&mohclasses);
-
- time(&moh->start);
- moh->start -= respawn_time;
-
- if (!strcasecmp(moh->mode, "files")) {
- res = moh_scan_files(moh);
- if (res <= 0) {
- if (res == 0) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Files not found in %s for moh class:%s\n", moh->dir, moh->name);
- }
- ast_moh_free_class(&moh);
- return -1;
- }
- if (strchr(moh->args, 'r'))
- ast_set_flag(moh, MOH_RANDOMIZE);
- } else if (!strcasecmp(moh->mode, "mp3") || !strcasecmp(moh->mode, "mp3nb") || !strcasecmp(moh->mode, "quietmp3") || !strcasecmp(moh->mode, "quietmp3nb") || !strcasecmp(moh->mode, "httpmp3") || !strcasecmp(moh->mode, "custom")) {
-
- if (!strcasecmp(moh->mode, "custom"))
- ast_set_flag(moh, MOH_CUSTOM);
- else if (!strcasecmp(moh->mode, "mp3nb"))
- ast_set_flag(moh, MOH_SINGLE);
- else if (!strcasecmp(moh->mode, "quietmp3nb"))
- ast_set_flag(moh, MOH_SINGLE | MOH_QUIET);
- else if (!strcasecmp(moh->mode, "quietmp3"))
- ast_set_flag(moh, MOH_QUIET);
-
- moh->srcfd = -1;
-#ifdef HAVE_ZAPTEL
- /* Open /dev/zap/pseudo for timing... Is
- there a better, yet reliable way to do this? */
- moh->pseudofd = open("/dev/zap/pseudo", O_RDONLY);
- if (moh->pseudofd < 0) {
- ast_log(LOG_WARNING, "Unable to open pseudo channel for timing... Sound may be choppy.\n");
- } else {
- x = 320;
- ioctl(moh->pseudofd, ZT_SET_BLOCKSIZE, &x);
- }
-#else
- moh->pseudofd = -1;
-#endif
- if (ast_pthread_create_background(&moh->thread, NULL, monmp3thread, moh)) {
- ast_log(LOG_WARNING, "Unable to create moh...\n");
- if (moh->pseudofd > -1)
- close(moh->pseudofd);
- ast_moh_free_class(&moh);
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "Don't know how to do a mode '%s' music on hold\n", moh->mode);
- ast_moh_free_class(&moh);
- return -1;
- }
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_INSERT_HEAD(&mohclasses, moh, list);
- AST_LIST_UNLOCK(&mohclasses);
-
- return 0;
-}
-
-static void local_ast_moh_cleanup(struct ast_channel *chan)
-{
- if (chan->music_state) {
- free(chan->music_state);
- chan->music_state = NULL;
- }
-}
-
-static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
-{
- struct mohclass *mohclass = NULL;
-
- /* The following is the order of preference for which class to use:
- * 1) The channels explicitly set musicclass, which should *only* be
- * set by a call to Set(CHANNEL(musicclass)=whatever) in the dialplan.
- * 2) The mclass argument. If a channel is calling ast_moh_start() as the
- * result of receiving a HOLD control frame, this should be the
- * payload that came with the frame.
- * 3) The interpclass argument. This would be from the mohinterpret
- * option from channel drivers. This is the same as the old musicclass
- * option.
- * 4) The default class.
- */
- AST_LIST_LOCK(&mohclasses);
- if (!ast_strlen_zero(chan->musicclass))
- mohclass = get_mohbyname(chan->musicclass, 1);
- if (!mohclass && !ast_strlen_zero(mclass))
- mohclass = get_mohbyname(mclass, 1);
- if (!mohclass && !ast_strlen_zero(interpclass))
- mohclass = get_mohbyname(interpclass, 1);
- if (!mohclass)
- mohclass = get_mohbyname("default", 1);
- if (mohclass)
- ast_atomic_fetchadd_int(&mohclass->inuse, +1);
- AST_LIST_UNLOCK(&mohclasses);
-
- if (!mohclass)
- return -1;
-
- ast_set_flag(chan, AST_FLAG_MOH);
- if (mohclass->total_files) {
- return ast_activate_generator(chan, &moh_file_stream, mohclass);
- } else
- return ast_activate_generator(chan, &mohgen, mohclass);
-}
-
-static void local_ast_moh_stop(struct ast_channel *chan)
-{
- ast_clear_flag(chan, AST_FLAG_MOH);
- ast_deactivate_generator(chan);
-
- if (chan->music_state) {
- if (chan->stream) {
- ast_closestream(chan->stream);
- chan->stream = NULL;
- }
- }
-}
-
-static struct mohclass *moh_class_malloc(void)
-{
- struct mohclass *class;
-
- if ((class = ast_calloc(1, sizeof(*class))))
- class->format = AST_FORMAT_SLINEAR;
-
- return class;
-}
-
-static int load_moh_classes(int reload)
-{
- struct ast_config *cfg;
- struct ast_variable *var;
- struct mohclass *class;
- char *data;
- char *args;
- char *cat;
- int numclasses = 0;
- static int dep_warning = 0;
-
- cfg = ast_config_load("musiconhold.conf");
-
- if (!cfg)
- return 0;
-
- if (reload) {
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_TRAVERSE(&mohclasses, class, list)
- class->delete = 1;
- AST_LIST_UNLOCK(&mohclasses);
- }
-
- cat = ast_category_browse(cfg, NULL);
- for (; cat; cat = ast_category_browse(cfg, cat)) {
- if (strcasecmp(cat, "classes") && strcasecmp(cat, "moh_files")) {
- if (!(class = moh_class_malloc())) {
- break;
- }
- ast_copy_string(class->name, cat, sizeof(class->name));
- var = ast_variable_browse(cfg, cat);
- while (var) {
- if (!strcasecmp(var->name, "mode"))
- ast_copy_string(class->mode, var->value, sizeof(class->mode));
- else if (!strcasecmp(var->name, "directory"))
- ast_copy_string(class->dir, var->value, sizeof(class->dir));
- else if (!strcasecmp(var->name, "application"))
- ast_copy_string(class->args, var->value, sizeof(class->args));
- else if (!strcasecmp(var->name, "random"))
- ast_set2_flag(class, ast_true(var->value), MOH_RANDOMIZE);
- else if (!strcasecmp(var->name, "format")) {
- class->format = ast_getformatbyname(var->value);
- if (!class->format) {
- ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value);
- class->format = AST_FORMAT_SLINEAR;
- }
- }
- var = var->next;
- }
-
- if (ast_strlen_zero(class->dir)) {
- if (!strcasecmp(class->mode, "custom")) {
- strcpy(class->dir, "nodir");
- } else {
- ast_log(LOG_WARNING, "A directory must be specified for class '%s'!\n", class->name);
- free(class);
- continue;
- }
- }
- if (ast_strlen_zero(class->mode)) {
- ast_log(LOG_WARNING, "A mode must be specified for class '%s'!\n", class->name);
- free(class);
- continue;
- }
- if (ast_strlen_zero(class->args) && !strcasecmp(class->mode, "custom")) {
- ast_log(LOG_WARNING, "An application must be specified for class '%s'!\n", class->name);
- free(class);
- continue;
- }
-
- /* Don't leak a class when it's already registered */
- moh_register(class, reload);
-
- numclasses++;
- }
- }
-
-
- /* Deprecated Old-School Configuration */
- var = ast_variable_browse(cfg, "classes");
- while (var) {
- if (!dep_warning) {
- ast_log(LOG_WARNING, "The old musiconhold.conf syntax has been deprecated! Please refer to the sample configuration for information on the new syntax.\n");
- dep_warning = 1;
- }
- data = strchr(var->value, ':');
- if (data) {
- *data++ = '\0';
- args = strchr(data, ',');
- if (args)
- *args++ = '\0';
- if (!(get_mohbyname(var->name, 0))) {
- if (!(class = moh_class_malloc())) {
- break;
- }
-
- ast_copy_string(class->name, var->name, sizeof(class->name));
- ast_copy_string(class->dir, data, sizeof(class->dir));
- ast_copy_string(class->mode, var->value, sizeof(class->mode));
- if (args)
- ast_copy_string(class->args, args, sizeof(class->args));
-
- moh_register(class, reload);
- numclasses++;
- }
- }
- var = var->next;
- }
- var = ast_variable_browse(cfg, "moh_files");
- while (var) {
- if (!dep_warning) {
- ast_log(LOG_WARNING, "The old musiconhold.conf syntax has been deprecated! Please refer to the sample configuration for information on the new syntax.\n");
- dep_warning = 1;
- }
- if (!(get_mohbyname(var->name, 0))) {
- args = strchr(var->value, ',');
- if (args)
- *args++ = '\0';
- if (!(class = moh_class_malloc())) {
- break;
- }
-
- ast_copy_string(class->name, var->name, sizeof(class->name));
- ast_copy_string(class->dir, var->value, sizeof(class->dir));
- strcpy(class->mode, "files");
- if (args)
- ast_copy_string(class->args, args, sizeof(class->args));
-
- moh_register(class, reload);
- numclasses++;
- }
- var = var->next;
- }
-
- ast_config_destroy(cfg);
-
- return numclasses;
-}
-
-static int ast_moh_destroy_one(struct mohclass *moh)
-{
- char buff[8192];
- int bytes, tbytes = 0, stime = 0, pid = 0;
-
- if (moh) {
- if (moh->pid > 1) {
- ast_log(LOG_DEBUG, "killing %d!\n", moh->pid);
- stime = time(NULL) + 2;
- pid = moh->pid;
- moh->pid = 0;
- /* Back when this was just mpg123, SIGKILL was fine. Now we need
- * to give the process a reason and time enough to kill off its
- * children. */
- kill(pid, SIGHUP);
- usleep(100000);
- kill(pid, SIGTERM);
- usleep(100000);
- kill(pid, SIGKILL);
- while ((ast_wait_for_input(moh->srcfd, 100) > 0) && (bytes = read(moh->srcfd, buff, 8192)) && time(NULL) < stime)
- tbytes = tbytes + bytes;
- ast_log(LOG_DEBUG, "mpg123 pid %d and child died after %d bytes read\n", pid, tbytes);
- close(moh->srcfd);
- }
- ast_moh_free_class(&moh);
- }
-
- return 0;
-}
-
-static void ast_moh_destroy(void)
-{
- struct mohclass *moh;
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Destroying musiconhold processes\n");
-
- AST_LIST_LOCK(&mohclasses);
- while ((moh = AST_LIST_REMOVE_HEAD(&mohclasses, list))) {
- ast_moh_destroy_one(moh);
- }
- AST_LIST_UNLOCK(&mohclasses);
-}
-
-static int moh_cli(int fd, int argc, char *argv[])
-{
- reload();
- return 0;
-}
-
-static int cli_files_show(int fd, int argc, char *argv[])
-{
- int i;
- struct mohclass *class;
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_TRAVERSE(&mohclasses, class, list) {
- if (!class->total_files)
- continue;
-
- ast_cli(fd, "Class: %s\n", class->name);
- for (i = 0; i < class->total_files; i++)
- ast_cli(fd, "\tFile: %s\n", class->filearray[i]);
- }
- AST_LIST_UNLOCK(&mohclasses);
-
- return 0;
-}
-
-static int moh_classes_show(int fd, int argc, char *argv[])
-{
- struct mohclass *class;
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_TRAVERSE(&mohclasses, class, list) {
- ast_cli(fd, "Class: %s\n", class->name);
- ast_cli(fd, "\tMode: %s\n", S_OR(class->mode, "<none>"));
- ast_cli(fd, "\tDirectory: %s\n", S_OR(class->dir, "<none>"));
- ast_cli(fd, "\tUse Count: %d\n", class->inuse);
- if (ast_test_flag(class, MOH_CUSTOM))
- ast_cli(fd, "\tApplication: %s\n", S_OR(class->args, "<none>"));
- if (strcasecmp(class->mode, "files"))
- ast_cli(fd, "\tFormat: %s\n", ast_getformatname(class->format));
- }
- AST_LIST_UNLOCK(&mohclasses);
-
- return 0;
-}
-
-static struct ast_cli_entry cli_moh_classes_show_deprecated = {
- { "moh", "classes", "show"},
- moh_classes_show, NULL,
- NULL };
-
-static struct ast_cli_entry cli_moh_files_show_deprecated = {
- { "moh", "files", "show"},
- cli_files_show, NULL,
- NULL };
-
-static struct ast_cli_entry cli_moh[] = {
- { { "moh", "reload"},
- moh_cli, "Music On Hold",
- "Usage: moh reload\n Rereads configuration\n" },
-
- { { "moh", "show", "classes"},
- moh_classes_show, "List MOH classes",
- "Usage: moh show classes\n Lists all MOH classes\n", NULL, &cli_moh_classes_show_deprecated },
-
- { { "moh", "show", "files"},
- cli_files_show, "List MOH file-based classes",
- "Usage: moh show files\n Lists all loaded file-based MOH classes and their files\n", NULL, &cli_moh_files_show_deprecated },
-};
-
-static int init_classes(int reload)
-{
- struct mohclass *moh;
-
- if (!load_moh_classes(reload)) /* Load classes from config */
- return 0; /* Return if nothing is found */
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&mohclasses, moh, list) {
- if (reload && moh->delete) {
- AST_LIST_REMOVE_CURRENT(&mohclasses, list);
- if (!moh->inuse)
- ast_moh_destroy_one(moh);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&mohclasses);
-
- return 1;
-}
-
-static int load_module(void)
-{
- int res;
-
- res = ast_register_application(app0, moh0_exec, synopsis0, descrip0);
- ast_register_atexit(ast_moh_destroy);
- ast_cli_register_multiple(cli_moh, sizeof(cli_moh) / sizeof(struct ast_cli_entry));
- if (!res)
- res = ast_register_application(app1, moh1_exec, synopsis1, descrip1);
- if (!res)
- res = ast_register_application(app2, moh2_exec, synopsis2, descrip2);
- if (!res)
- res = ast_register_application(app3, moh3_exec, synopsis3, descrip3);
- if (!res)
- res = ast_register_application(app4, moh4_exec, synopsis4, descrip4);
-
- if (!init_classes(0)) { /* No music classes configured, so skip it */
- ast_log(LOG_WARNING, "No music on hold classes configured, disabling music on hold.\n");
- } else {
- ast_install_music_functions(local_ast_moh_start, local_ast_moh_stop, local_ast_moh_cleanup);
- }
-
- return 0;
-}
-
-static int reload(void)
-{
- if (init_classes(1))
- ast_install_music_functions(local_ast_moh_start, local_ast_moh_stop, local_ast_moh_cleanup);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- int res = 0;
- struct mohclass *class = NULL;
-
- AST_LIST_LOCK(&mohclasses);
- AST_LIST_TRAVERSE(&mohclasses, class, list) {
- if (class->inuse > 0) {
- res = -1;
- break;
- }
- }
- AST_LIST_UNLOCK(&mohclasses);
- if (res < 0) {
- ast_log(LOG_WARNING, "Unable to unload res_musiconhold due to active MOH channels\n");
- return res;
- }
-
- ast_uninstall_music_functions();
- ast_moh_destroy();
- res = ast_unregister_application(app0);
- res |= ast_unregister_application(app1);
- res |= ast_unregister_application(app2);
- res |= ast_unregister_application(app3);
- res |= ast_unregister_application(app4);
- ast_cli_unregister_multiple(cli_moh, sizeof(cli_moh) / sizeof(struct ast_cli_entry));
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Music On Hold Resource",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_odbc.c b/1.4/res/res_odbc.c
deleted file mode 100644
index 29e302330..000000000
--- a/1.4/res/res_odbc.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * res_odbc.c <ODBC resource manager>
- * Copyright (C) 2004 - 2005 Anthony Minessale II <anthmct@yahoo.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.
- */
-
-/*! \file
- *
- * \brief ODBC resource manager
- *
- * \author Mark Spencer <markster@digium.com>
- * \author Anthony Minessale II <anthmct@yahoo.com>
- *
- * \arg See also: \ref cdr_odbc
- */
-
-/*** MODULEINFO
- <depend>unixodbc</depend>
- <depend>ltdl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/cli.h"
-#include "asterisk/lock.h"
-#include "asterisk/res_odbc.h"
-#include "asterisk/time.h"
-
-struct odbc_class
-{
- AST_LIST_ENTRY(odbc_class) list;
- char name[80];
- char dsn[80];
- char username[80];
- char password[80];
- SQLHENV env;
- unsigned int haspool:1; /* Boolean - TDS databases need this */
- unsigned int limit:10; /* Gives a limit of 1023 maximum */
- unsigned int count:10; /* Running count of pooled connections */
- unsigned int delme:1; /* Purge the class */
- unsigned int backslash_is_escape:1; /* On this database, the backslash is a native escape sequence */
- unsigned int idlecheck; /* Recheck the connection if it is idle for this long */
- AST_LIST_HEAD(, odbc_obj) odbc_obj;
-};
-
-AST_LIST_HEAD_STATIC(odbc_list, odbc_class);
-
-static odbc_status odbc_obj_connect(struct odbc_obj *obj);
-static odbc_status odbc_obj_disconnect(struct odbc_obj *obj);
-static int odbc_register_class(struct odbc_class *class, int connect);
-
-
-SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_cb)(struct odbc_obj *obj, void *data), void *data)
-{
- int res = 0, i, attempt;
- SQLINTEGER nativeerror=0, numfields=0;
- SQLSMALLINT diagbytes=0;
- unsigned char state[10], diagnostic[256];
- SQLHSTMT stmt;
-
- for (attempt = 0; attempt < 2; attempt++) {
- /* This prepare callback may do more than just prepare -- it may also
- * bind parameters, bind results, etc. The real key, here, is that
- * when we disconnect, all handles become invalid for most databases.
- * We must therefore redo everything when we establish a new
- * connection. */
- stmt = prepare_cb(obj, data);
-
- if (stmt) {
- res = SQLExecute(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) && (res != SQL_NO_DATA)) {
- if (res == SQL_ERROR) {
- SQLGetDiagField(SQL_HANDLE_STMT, stmt, 1, SQL_DIAG_NUMBER, &numfields, SQL_IS_INTEGER, &diagbytes);
- for (i = 0; i < numfields; i++) {
- SQLGetDiagRec(SQL_HANDLE_STMT, stmt, i + 1, state, &nativeerror, diagnostic, sizeof(diagnostic), &diagbytes);
- ast_log(LOG_WARNING, "SQL Execute returned an error %d: %s: %s (%d)\n", res, state, diagnostic, diagbytes);
- if (i > 10) {
- ast_log(LOG_WARNING, "Oh, that was good. There are really %d diagnostics?\n", (int)numfields);
- break;
- }
- }
- }
-
- ast_log(LOG_WARNING, "SQL Execute error %d! Attempting a reconnect...\n", res);
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- stmt = NULL;
-
- obj->up = 0;
- /*
- * While this isn't the best way to try to correct an error, this won't automatically
- * fail when the statement handle invalidates.
- */
- /* XXX Actually, it might, if we're using a non-pooled connection. Possible race here. XXX */
- odbc_obj_disconnect(obj);
- odbc_obj_connect(obj);
- continue;
- } else
- obj->last_used = ast_tvnow();
- break;
- } else {
- ast_log(LOG_WARNING, "SQL Prepare failed. Attempting a reconnect...\n");
- odbc_obj_disconnect(obj);
- odbc_obj_connect(obj);
- }
- }
-
- return stmt;
-}
-
-int ast_odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt)
-{
- int res = 0, i;
- SQLINTEGER nativeerror=0, numfields=0;
- SQLSMALLINT diagbytes=0;
- unsigned char state[10], diagnostic[256];
-
- res = SQLExecute(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) && (res != SQL_NO_DATA)) {
- if (res == SQL_ERROR) {
- SQLGetDiagField(SQL_HANDLE_STMT, stmt, 1, SQL_DIAG_NUMBER, &numfields, SQL_IS_INTEGER, &diagbytes);
- for (i = 0; i < numfields; i++) {
- SQLGetDiagRec(SQL_HANDLE_STMT, stmt, i + 1, state, &nativeerror, diagnostic, sizeof(diagnostic), &diagbytes);
- ast_log(LOG_WARNING, "SQL Execute returned an error %d: %s: %s (%d)\n", res, state, diagnostic, diagbytes);
- if (i > 10) {
- ast_log(LOG_WARNING, "Oh, that was good. There are really %d diagnostics?\n", (int)numfields);
- break;
- }
- }
- }
-#if 0
- /* This is a really bad method of trying to correct a dead connection. It
- * only ever really worked with MySQL. It will not work with any other
- * database, since most databases prepare their statements on the server,
- * and if you disconnect, you invalidate the statement handle. Hence, if
- * you disconnect, you're going to fail anyway, whether you try to execute
- * a second time or not.
- */
- ast_log(LOG_WARNING, "SQL Execute error %d! Attempting a reconnect...\n", res);
- ast_mutex_lock(&obj->lock);
- obj->up = 0;
- ast_mutex_unlock(&obj->lock);
- odbc_obj_disconnect(obj);
- odbc_obj_connect(obj);
- res = SQLExecute(stmt);
-#endif
- } else
- obj->last_used = ast_tvnow();
-
- return res;
-}
-
-
-int ast_odbc_sanity_check(struct odbc_obj *obj)
-{
- char *test_sql = "select 1";
- SQLHSTMT stmt;
- int res = 0;
-
- if (obj->up) {
- res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- obj->up = 0;
- } else {
- res = SQLPrepare(stmt, (unsigned char *)test_sql, SQL_NTS);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- obj->up = 0;
- } else {
- res = SQLExecute(stmt);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- obj->up = 0;
- }
- }
- }
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- }
-
- if (!obj->up) { /* Try to reconnect! */
- ast_log(LOG_WARNING, "Connection is down attempting to reconnect...\n");
- odbc_obj_disconnect(obj);
- odbc_obj_connect(obj);
- }
- return obj->up;
-}
-
-static int load_odbc_config(void)
-{
- static char *cfg = "res_odbc.conf";
- struct ast_config *config;
- struct ast_variable *v;
- char *cat, *dsn, *username, *password;
- int enabled, pooling, limit, bse;
- unsigned int idlecheck;
- int connect = 0, res = 0;
-
- struct odbc_class *new;
-
- config = ast_config_load(cfg);
- if (!config) {
- ast_log(LOG_WARNING, "Unable to load config file res_odbc.conf\n");
- return -1;
- }
- for (cat = ast_category_browse(config, NULL); cat; cat=ast_category_browse(config, cat)) {
- if (!strcasecmp(cat, "ENV")) {
- for (v = ast_variable_browse(config, cat); v; v = v->next) {
- setenv(v->name, v->value, 1);
- ast_log(LOG_NOTICE, "Adding ENV var: %s=%s\n", v->name, v->value);
- }
- } else {
- /* Reset all to defaults for each class of odbc connections */
- dsn = username = password = NULL;
- enabled = 1;
- connect = idlecheck = 0;
- pooling = 0;
- limit = 0;
- bse = 1;
- for (v = ast_variable_browse(config, cat); v; v = v->next) {
- if (!strcasecmp(v->name, "pooling")) {
- if (ast_true(v->value))
- pooling = 1;
- } else if (!strcasecmp(v->name, "limit")) {
- sscanf(v->value, "%d", &limit);
- if (ast_true(v->value) && !limit) {
- ast_log(LOG_WARNING, "Limit should be a number, not a boolean: '%s'. Setting limit to 1023 for ODBC class '%s'.\n", v->value, cat);
- limit = 1023;
- } else if (ast_false(v->value)) {
- ast_log(LOG_WARNING, "Limit should be a number, not a boolean: '%s'. Disabling ODBC class '%s'.\n", v->value, cat);
- enabled = 0;
- break;
- }
- } else if (!strcasecmp(v->name, "idlecheck")) {
- sscanf(v->value, "%d", &idlecheck);
- } else if (!strcasecmp(v->name, "enabled")) {
- enabled = ast_true(v->value);
- } else if (!strcasecmp(v->name, "pre-connect")) {
- connect = ast_true(v->value);
- } else if (!strcasecmp(v->name, "dsn")) {
- dsn = v->value;
- } else if (!strcasecmp(v->name, "username")) {
- username = v->value;
- } else if (!strcasecmp(v->name, "password")) {
- password = v->value;
- } else if (!strcasecmp(v->name, "backslash_is_escape")) {
- bse = ast_true(v->value);
- }
- }
-
- if (enabled && !ast_strlen_zero(dsn)) {
- new = ast_calloc(1, sizeof(*new));
-
- if (!new) {
- res = -1;
- break;
- }
-
- if (cat)
- ast_copy_string(new->name, cat, sizeof(new->name));
- if (dsn)
- ast_copy_string(new->dsn, dsn, sizeof(new->dsn));
- if (username)
- ast_copy_string(new->username, username, sizeof(new->username));
- if (password)
- ast_copy_string(new->password, password, sizeof(new->password));
-
- SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &new->env);
- res = SQLSetEnvAttr(new->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "res_odbc: Error SetEnv\n");
- SQLFreeHandle(SQL_HANDLE_ENV, new->env);
- return res;
- }
-
- if (pooling) {
- new->haspool = pooling;
- if (limit) {
- new->limit = limit;
- } else {
- ast_log(LOG_WARNING, "Pooling without also setting a limit is pointless. Changing limit from 0 to 5.\n");
- new->limit = 5;
- }
- }
-
- new->backslash_is_escape = bse ? 1 : 0;
- new->idlecheck = idlecheck;
-
- odbc_register_class(new, connect);
- ast_log(LOG_NOTICE, "Registered ODBC class '%s' dsn->[%s]\n", cat, dsn);
- }
- }
- }
- ast_config_destroy(config);
- return res;
-}
-
-static int odbc_show_command(int fd, int argc, char **argv)
-{
- struct odbc_class *class;
- struct odbc_obj *current;
-
- AST_LIST_LOCK(&odbc_list);
- AST_LIST_TRAVERSE(&odbc_list, class, list) {
- if ((argc == 2) || (argc == 3 && !strcmp(argv[2], "all")) || (!strcmp(argv[2], class->name))) {
- int count = 0;
- ast_cli(fd, "Name: %s\nDSN: %s\n", class->name, class->dsn);
-
- if (class->haspool) {
- ast_cli(fd, "Pooled: yes\nLimit: %d\nConnections in use: %d\n", class->limit, class->count);
-
- AST_LIST_TRAVERSE(&(class->odbc_obj), current, list) {
- ast_cli(fd, " Connection %d: %s\n", ++count, current->used ? "in use" : current->up && ast_odbc_sanity_check(current) ? "connected" : "disconnected");
- }
- } else {
- /* Should only ever be one of these */
- AST_LIST_TRAVERSE(&(class->odbc_obj), current, list) {
- ast_cli(fd, "Pooled: no\nConnected: %s\n", current->up && ast_odbc_sanity_check(current) ? "yes" : "no");
- }
- }
-
- ast_cli(fd, "\n");
- }
- }
- AST_LIST_UNLOCK(&odbc_list);
-
- return 0;
-}
-
-static char show_usage[] =
-"Usage: odbc show [<class>]\n"
-" List settings of a particular ODBC class.\n"
-" or, if not specified, all classes.\n";
-
-static struct ast_cli_entry cli_odbc[] = {
- { { "odbc", "show", NULL },
- odbc_show_command, "List ODBC DSN(s)",
- show_usage },
-};
-
-static int odbc_register_class(struct odbc_class *class, int connect)
-{
- struct odbc_obj *obj;
- if (class) {
- AST_LIST_LOCK(&odbc_list);
- AST_LIST_INSERT_HEAD(&odbc_list, class, list);
- AST_LIST_UNLOCK(&odbc_list);
-
- if (connect) {
- /* Request and release builds a connection */
- obj = ast_odbc_request_obj(class->name, 0);
- if (obj)
- ast_odbc_release_obj(obj);
- }
-
- return 0;
- } else {
- ast_log(LOG_WARNING, "Attempted to register a NULL class?\n");
- return -1;
- }
-}
-
-void ast_odbc_release_obj(struct odbc_obj *obj)
-{
- /* For pooled connections, this frees the connection to be
- * reused. For non-pooled connections, it does nothing. */
- obj->used = 0;
-}
-
-int ast_odbc_backslash_is_escape(struct odbc_obj *obj)
-{
- return obj->parent->backslash_is_escape;
-}
-
-struct odbc_obj *ast_odbc_request_obj(const char *name, int check)
-{
- struct odbc_obj *obj = NULL;
- struct odbc_class *class;
-
- AST_LIST_LOCK(&odbc_list);
- AST_LIST_TRAVERSE(&odbc_list, class, list) {
- if (!strcmp(class->name, name))
- break;
- }
- AST_LIST_UNLOCK(&odbc_list);
-
- if (!class)
- return NULL;
-
- AST_LIST_LOCK(&class->odbc_obj);
- if (class->haspool) {
- /* Recycle connections before building another */
- AST_LIST_TRAVERSE(&class->odbc_obj, obj, list) {
- if (! obj->used) {
- obj->used = 1;
- break;
- }
- }
-
- if (!obj && (class->count < class->limit)) {
- class->count++;
- obj = ast_calloc(1, sizeof(*obj));
- if (!obj) {
- AST_LIST_UNLOCK(&class->odbc_obj);
- return NULL;
- }
- ast_mutex_init(&obj->lock);
- obj->parent = class;
- if (odbc_obj_connect(obj) == ODBC_FAIL) {
- ast_log(LOG_WARNING, "Failed to connect to %s\n", name);
- ast_mutex_destroy(&obj->lock);
- free(obj);
- obj = NULL;
- class->count--;
- } else {
- obj->used = 1;
- AST_LIST_INSERT_TAIL(&class->odbc_obj, obj, list);
- }
- }
- } else {
- /* Non-pooled connection: multiple modules can use the same connection. */
- AST_LIST_TRAVERSE(&class->odbc_obj, obj, list) {
- /* Non-pooled connection: if there is an entry, return it */
- break;
- }
-
- if (!obj) {
- /* No entry: build one */
- obj = ast_calloc(1, sizeof(*obj));
- if (!obj) {
- AST_LIST_UNLOCK(&class->odbc_obj);
- return NULL;
- }
- ast_mutex_init(&obj->lock);
- obj->parent = class;
- if (odbc_obj_connect(obj) == ODBC_FAIL) {
- ast_log(LOG_WARNING, "Failed to connect to %s\n", name);
- ast_mutex_destroy(&obj->lock);
- free(obj);
- obj = NULL;
- } else {
- AST_LIST_INSERT_HEAD(&class->odbc_obj, obj, list);
- }
- }
- }
- AST_LIST_UNLOCK(&class->odbc_obj);
-
- if (obj && check) {
- ast_odbc_sanity_check(obj);
- } else if (obj && obj->parent->idlecheck > 0 && ast_tvdiff_ms(ast_tvnow(), obj->last_used) / 1000 > obj->parent->idlecheck)
- odbc_obj_connect(obj);
-
- return obj;
-}
-
-static odbc_status odbc_obj_disconnect(struct odbc_obj *obj)
-{
- int res;
- ast_mutex_lock(&obj->lock);
-
- res = SQLDisconnect(obj->con);
-
- if (res == ODBC_SUCCESS) {
- ast_log(LOG_WARNING, "res_odbc: disconnected %d from %s [%s]\n", res, obj->parent->name, obj->parent->dsn);
- } else {
- ast_log(LOG_WARNING, "res_odbc: %s [%s] already disconnected\n",
- obj->parent->name, obj->parent->dsn);
- }
- obj->up = 0;
- ast_mutex_unlock(&obj->lock);
- return ODBC_SUCCESS;
-}
-
-static odbc_status odbc_obj_connect(struct odbc_obj *obj)
-{
- int res;
- SQLINTEGER err;
- short int mlen;
- unsigned char msg[200], stat[10];
-#ifdef NEEDTRACE
- SQLINTEGER enable = 1;
- char *tracefile = "/tmp/odbc.trace";
-#endif
- ast_mutex_lock(&obj->lock);
-
- res = SQLAllocHandle(SQL_HANDLE_DBC, obj->parent->env, &obj->con);
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "res_odbc: Error AllocHDB %d\n", res);
- ast_mutex_unlock(&obj->lock);
- return ODBC_FAIL;
- }
- SQLSetConnectAttr(obj->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0);
- SQLSetConnectAttr(obj->con, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER *) 10, 0);
-#ifdef NEEDTRACE
- SQLSetConnectAttr(obj->con, SQL_ATTR_TRACE, &enable, SQL_IS_INTEGER);
- SQLSetConnectAttr(obj->con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile));
-#endif
-
- if (obj->up) {
- odbc_obj_disconnect(obj);
- ast_log(LOG_NOTICE, "Re-connecting %s\n", obj->parent->name);
- } else {
- ast_log(LOG_NOTICE, "Connecting %s\n", obj->parent->name);
- }
-
- res = SQLConnect(obj->con,
- (SQLCHAR *) obj->parent->dsn, SQL_NTS,
- (SQLCHAR *) obj->parent->username, SQL_NTS,
- (SQLCHAR *) obj->parent->password, SQL_NTS);
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- SQLGetDiagRec(SQL_HANDLE_DBC, obj->con, 1, stat, &err, msg, 100, &mlen);
- ast_mutex_unlock(&obj->lock);
- ast_log(LOG_WARNING, "res_odbc: Error SQLConnect=%d errno=%d %s\n", res, (int)err, msg);
- return ODBC_FAIL;
- } else {
- ast_log(LOG_NOTICE, "res_odbc: Connected to %s [%s]\n", obj->parent->name, obj->parent->dsn);
- obj->up = 1;
- obj->last_used = ast_tvnow();
- }
-
- ast_mutex_unlock(&obj->lock);
- return ODBC_SUCCESS;
-}
-
-static int reload(void)
-{
- static char *cfg = "res_odbc.conf";
- struct ast_config *config;
- struct ast_variable *v;
- char *cat, *dsn, *username, *password;
- int enabled, pooling, limit, bse;
- unsigned int idlecheck;
- int connect = 0, res = 0;
-
- struct odbc_class *new, *class;
- struct odbc_obj *current;
-
- /* First, mark all to be purged */
- AST_LIST_LOCK(&odbc_list);
- AST_LIST_TRAVERSE(&odbc_list, class, list) {
- class->delme = 1;
- }
-
- config = ast_config_load(cfg);
- if (config) {
- for (cat = ast_category_browse(config, NULL); cat; cat=ast_category_browse(config, cat)) {
- if (!strcasecmp(cat, "ENV")) {
- for (v = ast_variable_browse(config, cat); v; v = v->next) {
- setenv(v->name, v->value, 1);
- ast_log(LOG_NOTICE, "Adding ENV var: %s=%s\n", v->name, v->value);
- }
- } else {
- /* Reset all to defaults for each class of odbc connections */
- dsn = username = password = NULL;
- enabled = 1;
- connect = idlecheck = 0;
- pooling = 0;
- limit = 0;
- bse = 1;
- for (v = ast_variable_browse(config, cat); v; v = v->next) {
- if (!strcasecmp(v->name, "pooling")) {
- pooling = 1;
- } else if (!strcasecmp(v->name, "limit")) {
- sscanf(v->value, "%d", &limit);
- if (ast_true(v->value) && !limit) {
- ast_log(LOG_WARNING, "Limit should be a number, not a boolean: '%s'. Setting limit to 1023 for ODBC class '%s'.\n", v->value, cat);
- limit = 1023;
- } else if (ast_false(v->value)) {
- ast_log(LOG_WARNING, "Limit should be a number, not a boolean: '%s'. Disabling ODBC class '%s'.\n", v->value, cat);
- enabled = 0;
- break;
- }
- } else if (!strcasecmp(v->name, "idlecheck")) {
- sscanf(v->value, "%ud", &idlecheck);
- } else if (!strcasecmp(v->name, "enabled")) {
- enabled = ast_true(v->value);
- } else if (!strcasecmp(v->name, "pre-connect")) {
- connect = ast_true(v->value);
- } else if (!strcasecmp(v->name, "dsn")) {
- dsn = v->value;
- } else if (!strcasecmp(v->name, "username")) {
- username = v->value;
- } else if (!strcasecmp(v->name, "password")) {
- password = v->value;
- } else if (!strcasecmp(v->name, "backslash_is_escape")) {
- bse = ast_true(v->value);
- }
- }
-
- if (enabled && !ast_strlen_zero(dsn)) {
- /* First, check the list to see if it already exists */
- AST_LIST_TRAVERSE(&odbc_list, class, list) {
- if (!strcmp(class->name, cat)) {
- class->delme = 0;
- break;
- }
- }
-
- if (class) {
- new = class;
- } else {
- new = ast_calloc(1, sizeof(*new));
- }
-
- if (!new) {
- res = -1;
- break;
- }
-
- if (cat)
- ast_copy_string(new->name, cat, sizeof(new->name));
- if (dsn)
- ast_copy_string(new->dsn, dsn, sizeof(new->dsn));
- if (username)
- ast_copy_string(new->username, username, sizeof(new->username));
- if (password)
- ast_copy_string(new->password, password, sizeof(new->password));
-
- if (!class) {
- SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &new->env);
- res = SQLSetEnvAttr(new->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
-
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "res_odbc: Error SetEnv\n");
- SQLFreeHandle(SQL_HANDLE_ENV, new->env);
- AST_LIST_UNLOCK(&odbc_list);
- return res;
- }
- }
-
- if (pooling) {
- new->haspool = pooling;
- if (limit) {
- new->limit = limit;
- } else {
- ast_log(LOG_WARNING, "Pooling without also setting a limit is pointless. Changing limit from 0 to 5.\n");
- new->limit = 5;
- }
- }
-
- new->backslash_is_escape = bse;
- new->idlecheck = idlecheck;
-
- if (class) {
- ast_log(LOG_NOTICE, "Refreshing ODBC class '%s' dsn->[%s]\n", cat, dsn);
- } else {
- odbc_register_class(new, connect);
- ast_log(LOG_NOTICE, "Registered ODBC class '%s' dsn->[%s]\n", cat, dsn);
- }
- }
- }
- }
- ast_config_destroy(config);
- }
-
- /* Purge classes that we know can go away (pooled with 0, only) */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&odbc_list, class, list) {
- if (class->delme && class->haspool && class->count == 0) {
- AST_LIST_TRAVERSE_SAFE_BEGIN(&(class->odbc_obj), current, list) {
- AST_LIST_REMOVE_CURRENT(&(class->odbc_obj), list);
- odbc_obj_disconnect(current);
- ast_mutex_destroy(&current->lock);
- free(current);
- }
- AST_LIST_TRAVERSE_SAFE_END;
-
- AST_LIST_REMOVE_CURRENT(&odbc_list, list);
- free(class);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&odbc_list);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- /* Prohibit unloading */
- return -1;
-}
-
-static int load_module(void)
-{
- if(load_odbc_config() == -1)
- return AST_MODULE_LOAD_DECLINE;
- ast_cli_register_multiple(cli_odbc, sizeof(cli_odbc) / sizeof(struct ast_cli_entry));
- ast_log(LOG_NOTICE, "res_odbc loaded.\n");
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "ODBC Resource",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_smdi.c b/1.4/res/res_smdi.c
deleted file mode 100644
index 9315cf973..000000000
--- a/1.4/res/res_smdi.c
+++ /dev/null
@@ -1,1313 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Copyright (C) 2005-2008, Digium, Inc.
- *
- * Matthew A. Nicholson <mnicholson@digium.com>
- * Russell Bryant <russell@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.
- */
-
-/*!
- * \file
- * \brief SMDI support for Asterisk.
- * \author Matthew A. Nicholson <mnicholson@digium.com>
- * \author Russell Bryant <russell@digium.com>
- *
- * Here is a useful mailing list post that describes SMDI protocol details:
- * \ref http://lists.digium.com/pipermail/asterisk-dev/2003-June/000884.html
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <termios.h>
-#include <sys/time.h>
-#include <time.h>
-#include <ctype.h>
-
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/smdi.h"
-#include "asterisk/config.h"
-#include "asterisk/astobj.h"
-#include "asterisk/io.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/app.h"
-#include "asterisk/pbx.h"
-
-/* Message expiry time in milliseconds */
-#define SMDI_MSG_EXPIRY_TIME 30000 /* 30 seconds */
-
-static const char config_file[] = "smdi.conf";
-
-/*! \brief SMDI message desk message queue. */
-struct ast_smdi_md_queue {
- ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_md_message);
-};
-
-/*! \brief SMDI message waiting indicator message queue. */
-struct ast_smdi_mwi_queue {
- ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_mwi_message);
-};
-
-struct ast_smdi_interface {
- ASTOBJ_COMPONENTS_FULL(struct ast_smdi_interface, SMDI_MAX_FILENAME_LEN, 1);
- struct ast_smdi_md_queue md_q;
- ast_mutex_t md_q_lock;
- ast_cond_t md_q_cond;
- struct ast_smdi_mwi_queue mwi_q;
- ast_mutex_t mwi_q_lock;
- ast_cond_t mwi_q_cond;
- FILE *file;
- int fd;
- pthread_t thread;
- struct termios mode;
- int msdstrip;
- long msg_expiry;
-};
-
-/*! \brief SMDI interface container. */
-struct ast_smdi_interface_container {
- ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_interface);
-} smdi_ifaces;
-
-/*! \brief A mapping between an SMDI mailbox ID and an Asterisk mailbox */
-struct mailbox_mapping {
- /*! This is the current state of the mailbox. It is simply on or
- * off to indicate if there are messages waiting or not. */
- unsigned int cur_state:1;
- /*! A Pointer to the appropriate SMDI interface */
- struct ast_smdi_interface *iface;
- AST_DECLARE_STRING_FIELDS(
- /*! The Name of the mailbox for the SMDI link. */
- AST_STRING_FIELD(smdi);
- /*! The name of the mailbox on the Asterisk side */
- AST_STRING_FIELD(mailbox);
- /*! The name of the voicemail context in use */
- AST_STRING_FIELD(context);
- );
- AST_LIST_ENTRY(mailbox_mapping) entry;
-};
-
-/*! 10 seconds */
-#define DEFAULT_POLLING_INTERVAL 10
-
-/*! \brief Data that gets used by the SMDI MWI monitoring thread */
-static struct {
- /*! The thread ID */
- pthread_t thread;
- ast_mutex_t lock;
- ast_cond_t cond;
- /*! A list of mailboxes that need to be monitored */
- AST_LIST_HEAD_NOLOCK(, mailbox_mapping) mailbox_mappings;
- /*! Polling Interval for checking mailbox status */
- unsigned int polling_interval;
- /*! Set to 1 to tell the polling thread to stop */
- unsigned int stop:1;
- /*! The time that the last poll began */
- struct timeval last_poll;
-} mwi_monitor = {
- .thread = AST_PTHREADT_NULL,
-};
-
-static void ast_smdi_interface_destroy(struct ast_smdi_interface *iface)
-{
- if (iface->thread != AST_PTHREADT_NULL && iface->thread != AST_PTHREADT_STOP) {
- pthread_cancel(iface->thread);
- pthread_join(iface->thread, NULL);
- }
-
- iface->thread = AST_PTHREADT_STOP;
-
- if (iface->file)
- fclose(iface->file);
-
- ASTOBJ_CONTAINER_DESTROYALL(&iface->md_q, ast_smdi_md_message_destroy);
- ASTOBJ_CONTAINER_DESTROYALL(&iface->mwi_q, ast_smdi_mwi_message_destroy);
- ASTOBJ_CONTAINER_DESTROY(&iface->md_q);
- ASTOBJ_CONTAINER_DESTROY(&iface->mwi_q);
-
- ast_mutex_destroy(&iface->md_q_lock);
- ast_cond_destroy(&iface->md_q_cond);
-
- ast_mutex_destroy(&iface->mwi_q_lock);
- ast_cond_destroy(&iface->mwi_q_cond);
-
- free(iface);
-
- ast_module_unref(ast_module_info->self);
-}
-
-void ast_smdi_interface_unref(struct ast_smdi_interface *iface)
-{
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
-}
-
-/*!
- * \internal
- * \brief Push an SMDI message to the back of an interface's message queue.
- * \param iface a pointer to the interface to use.
- * \param md_msg a pointer to the message to use.
- */
-static void ast_smdi_md_message_push(struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
-{
- ast_mutex_lock(&iface->md_q_lock);
- ASTOBJ_CONTAINER_LINK_END(&iface->md_q, md_msg);
- ast_cond_broadcast(&iface->md_q_cond);
- ast_mutex_unlock(&iface->md_q_lock);
-}
-
-/*!
- * \internal
- * \brief Push an SMDI message to the back of an interface's message queue.
- * \param iface a pointer to the interface to use.
- * \param mwi_msg a pointer to the message to use.
- */
-static void ast_smdi_mwi_message_push(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
-{
- ast_mutex_lock(&iface->mwi_q_lock);
- ASTOBJ_CONTAINER_LINK_END(&iface->mwi_q, mwi_msg);
- ast_cond_broadcast(&iface->mwi_q_cond);
- ast_mutex_unlock(&iface->mwi_q_lock);
-}
-
-static int smdi_toggle_mwi(struct ast_smdi_interface *iface, const char *mailbox, int on)
-{
- FILE *file;
- int i;
-
- if (!(file = fopen(iface->name, "w"))) {
- ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s) for writing\n", iface->name, strerror(errno));
- return 1;
- }
-
- ASTOBJ_WRLOCK(iface);
-
- fprintf(file, "%s:MWI ", on ? "OP" : "RMV");
-
- for (i = 0; i < iface->msdstrip; i++)
- fprintf(file, "0");
-
- fprintf(file, "%s!\x04", mailbox);
-
- fclose(file);
-
- ASTOBJ_UNLOCK(iface);
-
- ast_log(LOG_DEBUG, "Sent MWI %s message for %s on %s\n", on ? "set" : "unset",
- mailbox, iface->name);
-
- return 0;
-}
-
-int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox)
-{
- return smdi_toggle_mwi(iface, mailbox, 1);
-}
-
-int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox)
-{
- return smdi_toggle_mwi(iface, mailbox, 0);
-}
-
-void ast_smdi_md_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
-{
- ast_mutex_lock(&iface->md_q_lock);
- ASTOBJ_CONTAINER_LINK_START(&iface->md_q, md_msg);
- ast_cond_broadcast(&iface->md_q_cond);
- ast_mutex_unlock(&iface->md_q_lock);
-}
-
-void ast_smdi_mwi_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
-{
- ast_mutex_lock(&iface->mwi_q_lock);
- ASTOBJ_CONTAINER_LINK_START(&iface->mwi_q, mwi_msg);
- ast_cond_broadcast(&iface->mwi_q_cond);
- ast_mutex_unlock(&iface->mwi_q_lock);
-}
-
-enum smdi_message_type {
- SMDI_MWI,
- SMDI_MD,
-};
-
-static inline int lock_msg_q(struct ast_smdi_interface *iface, enum smdi_message_type type)
-{
- switch (type) {
- case SMDI_MWI:
- return ast_mutex_lock(&iface->mwi_q_lock);
- case SMDI_MD:
- return ast_mutex_lock(&iface->md_q_lock);
- }
-
- return -1;
-}
-
-static inline int unlock_msg_q(struct ast_smdi_interface *iface, enum smdi_message_type type)
-{
- switch (type) {
- case SMDI_MWI:
- return ast_mutex_unlock(&iface->mwi_q_lock);
- case SMDI_MD:
- return ast_mutex_unlock(&iface->md_q_lock);
- }
-
- return -1;
-}
-
-static inline void *unlink_from_msg_q(struct ast_smdi_interface *iface, enum smdi_message_type type)
-{
- switch (type) {
- case SMDI_MWI:
- return ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q);
- case SMDI_MD:
- return ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q);
- }
-
- return NULL;
-}
-
-static inline struct timeval msg_timestamp(void *msg, enum smdi_message_type type)
-{
- struct ast_smdi_md_message *md_msg = msg;
- struct ast_smdi_mwi_message *mwi_msg = msg;
-
- switch (type) {
- case SMDI_MWI:
- return mwi_msg->timestamp;
- case SMDI_MD:
- return md_msg->timestamp;
- }
-
- return ast_tv(0, 0);
-}
-
-static inline void unref_msg(void *msg, enum smdi_message_type type)
-{
- struct ast_smdi_md_message *md_msg = msg;
- struct ast_smdi_mwi_message *mwi_msg = msg;
-
- switch (type) {
- case SMDI_MWI:
- ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
- case SMDI_MD:
- ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy);
- }
-}
-
-static void purge_old_messages(struct ast_smdi_interface *iface, enum smdi_message_type type)
-{
- struct timeval now;
- long elapsed = 0;
- void *msg;
-
- lock_msg_q(iface, type);
- msg = unlink_from_msg_q(iface, type);
- unlock_msg_q(iface, type);
-
- /* purge old messages */
- now = ast_tvnow();
- while (msg) {
- elapsed = ast_tvdiff_ms(now, msg_timestamp(msg, type));
-
- if (elapsed > iface->msg_expiry) {
- /* found an expired message */
- unref_msg(msg, type);
- ast_log(LOG_NOTICE, "Purged expired message from %s SMDI %s message queue. "
- "Message was %ld milliseconds too old.\n",
- iface->name, (type == SMDI_MD) ? "MD" : "MWI",
- elapsed - iface->msg_expiry);
-
- lock_msg_q(iface, type);
- msg = unlink_from_msg_q(iface, type);
- unlock_msg_q(iface, type);
- } else {
- /* good message, put it back and return */
- switch (type) {
- case SMDI_MD:
- ast_smdi_md_message_push(iface, msg);
- break;
- case SMDI_MWI:
- ast_smdi_mwi_message_push(iface, msg);
- break;
- }
- unref_msg(msg, type);
- break;
- }
- }
-}
-
-static void *smdi_msg_pop(struct ast_smdi_interface *iface, enum smdi_message_type type)
-{
- void *msg;
-
- purge_old_messages(iface, type);
-
- lock_msg_q(iface, type);
- msg = unlink_from_msg_q(iface, type);
- unlock_msg_q(iface, type);
-
- return msg;
-}
-
-static void *smdi_msg_find(struct ast_smdi_interface *iface,
- enum smdi_message_type type, const char *station)
-{
- void *msg = NULL;
-
- purge_old_messages(iface, type);
-
- switch (type) {
- case SMDI_MD:
- msg = ASTOBJ_CONTAINER_FIND(&iface->md_q, station);
- break;
- case SMDI_MWI:
- msg = ASTOBJ_CONTAINER_FIND(&iface->mwi_q, station);
- break;
- }
-
- return msg;
-}
-
-static void *smdi_message_wait(struct ast_smdi_interface *iface, int timeout,
- enum smdi_message_type type, const char *station)
-{
- struct timeval start;
- long diff = 0;
- void *msg;
-
- start = ast_tvnow();
- while (diff < timeout) {
- struct timespec ts = { 0, };
- struct timeval tv;
-
- lock_msg_q(iface, type);
-
- if ((msg = smdi_msg_find(iface, type, station))) {
- unlock_msg_q(iface, type);
- return msg;
- }
-
- tv = ast_tvadd(start, ast_tv(0, timeout));
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
-
- /* If there were no messages in the queue, then go to sleep until one
- * arrives. */
-
- ast_cond_timedwait(&iface->md_q_cond, &iface->md_q_lock, &ts);
-
- if ((msg = smdi_msg_find(iface, type, station))) {
- unlock_msg_q(iface, type);
- return msg;
- }
-
- unlock_msg_q(iface, type);
-
- /* check timeout */
- diff = ast_tvdiff_ms(ast_tvnow(), start);
- }
-
- return NULL;
-}
-
-struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *iface)
-{
- return smdi_msg_pop(iface, SMDI_MD);
-}
-
-struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout)
-{
- return smdi_message_wait(iface, timeout, SMDI_MD, NULL);
-}
-
-struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface)
-{
- return smdi_msg_pop(iface, SMDI_MWI);
-}
-
-struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout)
-{
- return smdi_message_wait(iface, timeout, SMDI_MWI, NULL);
-}
-
-struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface, int timeout,
- const char *station)
-{
- return smdi_message_wait(iface, timeout, SMDI_MWI, station);
-}
-
-struct ast_smdi_interface *ast_smdi_interface_find(const char *iface_name)
-{
- return (ASTOBJ_CONTAINER_FIND(&smdi_ifaces, iface_name));
-}
-
-/*!
- * \internal
- * \brief Read an SMDI message.
- *
- * \param iface_p the SMDI interface to read from.
- *
- * This function loops and reads from and SMDI interface. It must be stopped
- * using pthread_cancel().
- */
-static void *smdi_read(void *iface_p)
-{
- struct ast_smdi_interface *iface = iface_p;
- struct ast_smdi_md_message *md_msg;
- struct ast_smdi_mwi_message *mwi_msg;
- char c = '\0';
- char *cp = NULL;
- int i;
- int start = 0;
-
- /* read an smdi message */
- while ((c = fgetc(iface->file))) {
-
- /* check if this is the start of a message */
- if (!start) {
- if (c == 'M') {
- ast_log(LOG_DEBUG, "Read an 'M' to start an SMDI message\n");
- start = 1;
- }
- continue;
- }
-
- if (c == 'D') { /* MD message */
- start = 0;
-
- ast_log(LOG_DEBUG, "Read a 'D' ... it's an MD message.\n");
-
- if (!(md_msg = ast_calloc(1, sizeof(*md_msg)))) {
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- return NULL;
- }
-
- ASTOBJ_INIT(md_msg);
-
- /* read the message desk number */
- for (i = 0; i < sizeof(md_msg->mesg_desk_num) - 1; i++) {
- md_msg->mesg_desk_num[i] = fgetc(iface->file);
- ast_log(LOG_DEBUG, "Read a '%c'\n", md_msg->mesg_desk_num[i]);
- }
-
- md_msg->mesg_desk_num[sizeof(md_msg->mesg_desk_num) - 1] = '\0';
-
- ast_log(LOG_DEBUG, "The message desk number is '%s'\n", md_msg->mesg_desk_num);
-
- /* read the message desk terminal number */
- for (i = 0; i < sizeof(md_msg->mesg_desk_term) - 1; i++) {
- md_msg->mesg_desk_term[i] = fgetc(iface->file);
- ast_log(LOG_DEBUG, "Read a '%c'\n", md_msg->mesg_desk_term[i]);
- }
-
- md_msg->mesg_desk_term[sizeof(md_msg->mesg_desk_term) - 1] = '\0';
-
- ast_log(LOG_DEBUG, "The message desk terminal is '%s'\n", md_msg->mesg_desk_term);
-
- /* read the message type */
- md_msg->type = fgetc(iface->file);
-
- ast_log(LOG_DEBUG, "Message type is '%c'\n", md_msg->type);
-
- /* read the forwarding station number (may be blank) */
- cp = &md_msg->fwd_st[0];
- for (i = 0; i < sizeof(md_msg->fwd_st) - 1; i++) {
- if ((c = fgetc(iface->file)) == ' ') {
- *cp = '\0';
- ast_log(LOG_DEBUG, "Read a space, done looking for the forwarding station\n");
- break;
- }
-
- /* store c in md_msg->fwd_st */
- if (i >= iface->msdstrip) {
- ast_log(LOG_DEBUG, "Read a '%c' and stored it in the forwarding station buffer\n", c);
- *cp++ = c;
- } else {
- ast_log(LOG_DEBUG, "Read a '%c', but didn't store it in the fwd station buffer, because of the msdstrip setting (%d < %d)\n", c, i, iface->msdstrip);
- }
- }
-
- /* make sure the value is null terminated, even if this truncates it */
- md_msg->fwd_st[sizeof(md_msg->fwd_st) - 1] = '\0';
- cp = NULL;
-
- ast_log(LOG_DEBUG, "The forwarding station is '%s'\n", md_msg->fwd_st);
-
- /* Put the fwd_st in the name field so that we can use ASTOBJ_FIND to look
- * up a message on this field */
- ast_copy_string(md_msg->name, md_msg->fwd_st, sizeof(md_msg->name));
-
- /* read the calling station number (may be blank) */
- cp = &md_msg->calling_st[0];
- for (i = 0; i < sizeof(md_msg->calling_st) - 1; i++) {
- if (!isdigit((c = fgetc(iface->file)))) {
- *cp = '\0';
- ast_log(LOG_DEBUG, "Read a '%c', but didn't store it in the calling station buffer because it's not a digit\n", c);
- if (c == ' ') {
- /* Don't break on a space. We may read the space before the calling station
- * here if the forwarding station buffer filled up. */
- i--; /* We're still on the same character */
- continue;
- }
- break;
- }
-
- /* store c in md_msg->calling_st */
- if (i >= iface->msdstrip) {
- ast_log(LOG_DEBUG, "Read a '%c' and stored it in the calling station buffer\n", c);
- *cp++ = c;
- } else {
- ast_log(LOG_DEBUG, "Read a '%c', but didn't store it in the calling station buffer, because of the msdstrip setting (%d < %d)\n", c, i, iface->msdstrip);
- }
- }
-
- /* make sure the value is null terminated, even if this truncates it */
- md_msg->calling_st[sizeof(md_msg->calling_st) - 1] = '\0';
- cp = NULL;
-
- ast_log(LOG_DEBUG, "The calling station is '%s'\n", md_msg->calling_st);
-
- /* add the message to the message queue */
- md_msg->timestamp = ast_tvnow();
- ast_smdi_md_message_push(iface, md_msg);
- ast_log(LOG_DEBUG, "Recieved SMDI MD message on %s\n", iface->name);
-
- ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy);
-
- } else if (c == 'W') { /* MWI message */
- start = 0;
-
- ast_log(LOG_DEBUG, "Read a 'W', it's an MWI message. (No more debug coming for MWI messages)\n");
-
- if (!(mwi_msg = ast_calloc(1, sizeof(*mwi_msg)))) {
- ASTOBJ_UNREF(iface,ast_smdi_interface_destroy);
- return NULL;
- }
-
- ASTOBJ_INIT(mwi_msg);
-
- /* discard the 'I' (from 'MWI') */
- fgetc(iface->file);
-
- /* read the forwarding station number (may be blank) */
- cp = &mwi_msg->fwd_st[0];
- for (i = 0; i < sizeof(mwi_msg->fwd_st) - 1; i++) {
- if ((c = fgetc(iface->file)) == ' ') {
- *cp = '\0';
- break;
- }
-
- /* store c in md_msg->fwd_st */
- if (i >= iface->msdstrip)
- *cp++ = c;
- }
-
- /* make sure the station number is null terminated, even if this will truncate it */
- mwi_msg->fwd_st[sizeof(mwi_msg->fwd_st) - 1] = '\0';
- cp = NULL;
-
- /* Put the fwd_st in the name field so that we can use ASTOBJ_FIND to look
- * up a message on this field */
- ast_copy_string(mwi_msg->name, mwi_msg->fwd_st, sizeof(mwi_msg->name));
-
- /* read the mwi failure cause */
- for (i = 0; i < sizeof(mwi_msg->cause) - 1; i++)
- mwi_msg->cause[i] = fgetc(iface->file);
-
- mwi_msg->cause[sizeof(mwi_msg->cause) - 1] = '\0';
-
- /* add the message to the message queue */
- mwi_msg->timestamp = ast_tvnow();
- ast_smdi_mwi_message_push(iface, mwi_msg);
- ast_log(LOG_DEBUG, "Recieved SMDI MWI message on %s\n", iface->name);
-
- ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
- } else {
- ast_log(LOG_ERROR, "Unknown SMDI message type recieved on %s (M%c).\n", iface->name, c);
- start = 0;
- }
- }
-
- ast_log(LOG_ERROR, "Error reading from SMDI interface %s, stopping listener thread\n", iface->name);
- ASTOBJ_UNREF(iface,ast_smdi_interface_destroy);
- return NULL;
-}
-
-void ast_smdi_md_message_destroy(struct ast_smdi_md_message *msg)
-{
- free(msg);
-}
-
-void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg)
-{
- free(msg);
-}
-
-static void destroy_mailbox_mapping(struct mailbox_mapping *mm)
-{
- ast_string_field_free_memory(mm);
- ASTOBJ_UNREF(mm->iface, ast_smdi_interface_destroy);
- free(mm);
-}
-
-static void destroy_all_mailbox_mappings(void)
-{
- struct mailbox_mapping *mm;
-
- ast_mutex_lock(&mwi_monitor.lock);
- while ((mm = AST_LIST_REMOVE_HEAD(&mwi_monitor.mailbox_mappings, entry)))
- destroy_mailbox_mapping(mm);
- ast_mutex_unlock(&mwi_monitor.lock);
-}
-
-static void append_mailbox_mapping(struct ast_variable *var, struct ast_smdi_interface *iface)
-{
- struct mailbox_mapping *mm;
- char *mailbox, *context;
-
- if (!(mm = ast_calloc(1, sizeof(*mm))))
- return;
-
- if (ast_string_field_init(mm, 32)) {
- free(mm);
- return;
- }
-
- ast_string_field_set(mm, smdi, var->name);
-
- context = ast_strdupa(var->value);
- mailbox = strsep(&context, "@");
- if (ast_strlen_zero(context))
- context = "default";
-
- ast_string_field_set(mm, mailbox, mailbox);
- ast_string_field_set(mm, context, context);
-
- mm->iface = ASTOBJ_REF(iface);
-
- ast_mutex_lock(&mwi_monitor.lock);
- AST_LIST_INSERT_TAIL(&mwi_monitor.mailbox_mappings, mm, entry);
- ast_mutex_unlock(&mwi_monitor.lock);
-}
-
-/*!
- * \note Called with the mwi_monitor.lock locked
- */
-static void poll_mailbox(struct mailbox_mapping *mm)
-{
- char buf[1024];
- unsigned int state;
-
- snprintf(buf, sizeof(buf), "%s@%s", mm->mailbox, mm->context);
-
- state = !!ast_app_has_voicemail(mm->mailbox, NULL);
-
- if (state != mm->cur_state) {
- if (state)
- ast_smdi_mwi_set(mm->iface, mm->smdi);
- else
- ast_smdi_mwi_unset(mm->iface, mm->smdi);
-
- mm->cur_state = state;
- }
-}
-
-static void *mwi_monitor_handler(void *data)
-{
- while (!mwi_monitor.stop) {
- struct timespec ts = { 0, };
- struct timeval tv;
- struct mailbox_mapping *mm;
-
- ast_mutex_lock(&mwi_monitor.lock);
-
- mwi_monitor.last_poll = ast_tvnow();
-
- AST_LIST_TRAVERSE(&mwi_monitor.mailbox_mappings, mm, entry)
- poll_mailbox(mm);
-
- /* Sleep up to the configured polling interval. Allow unload_module()
- * to signal us to wake up and exit. */
- tv = ast_tvadd(mwi_monitor.last_poll, ast_tv(mwi_monitor.polling_interval, 0));
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- ast_cond_timedwait(&mwi_monitor.cond, &mwi_monitor.lock, &ts);
-
- ast_mutex_unlock(&mwi_monitor.lock);
- }
-
- return NULL;
-}
-
-static struct ast_smdi_interface *alloc_smdi_interface(void)
-{
- struct ast_smdi_interface *iface;
-
- if (!(iface = ast_calloc(1, sizeof(*iface))))
- return NULL;
-
- ASTOBJ_INIT(iface);
- ASTOBJ_CONTAINER_INIT(&iface->md_q);
- ASTOBJ_CONTAINER_INIT(&iface->mwi_q);
-
- ast_mutex_init(&iface->md_q_lock);
- ast_cond_init(&iface->md_q_cond, NULL);
-
- ast_mutex_init(&iface->mwi_q_lock);
- ast_cond_init(&iface->mwi_q_cond, NULL);
-
- return iface;
-}
-
-/*!
- * \internal
- * \brief Load and reload SMDI configuration.
- * \param reload this should be 1 if we are reloading and 0 if not.
- *
- * This function loads/reloads the SMDI configuration and starts and stops
- * interfaces accordingly.
- *
- * \return zero on success, -1 on failure, and 1 if no smdi interfaces were started.
- */
-static int smdi_load(int reload)
-{
- struct ast_config *conf;
- struct ast_variable *v;
- struct ast_smdi_interface *iface = NULL;
- int res = 0;
-
- /* Config options */
- speed_t baud_rate = B9600; /* 9600 baud rate */
- tcflag_t paritybit = PARENB; /* even parity checking */
- tcflag_t charsize = CS7; /* seven bit characters */
- int stopbits = 0; /* One stop bit */
-
- int msdstrip = 0; /* strip zero digits */
- long msg_expiry = SMDI_MSG_EXPIRY_TIME;
-
- conf = ast_config_load(config_file);
-
- if (!conf) {
- if (reload)
- ast_log(LOG_NOTICE, "Unable to reload config %s: SMDI untouched\n", config_file);
- else
- ast_log(LOG_NOTICE, "Unable to load config %s: SMDI disabled\n", config_file);
- return 1;
- }
-
- /* Mark all interfaces that we are listening on. We will unmark them
- * as we find them in the config file, this way we know any interfaces
- * still marked after we have finished parsing the config file should
- * be stopped.
- */
- if (reload)
- ASTOBJ_CONTAINER_MARKALL(&smdi_ifaces);
-
- for (v = ast_variable_browse(conf, "interfaces"); v; v = v->next) {
- if (!strcasecmp(v->name, "baudrate")) {
- if (!strcasecmp(v->value, "9600"))
- baud_rate = B9600;
- else if (!strcasecmp(v->value, "4800"))
- baud_rate = B4800;
- else if (!strcasecmp(v->value, "2400"))
- baud_rate = B2400;
- else if (!strcasecmp(v->value, "1200"))
- baud_rate = B1200;
- else {
- ast_log(LOG_NOTICE, "Invalid baud rate '%s' specified in %s (line %d), using default\n", v->value, config_file, v->lineno);
- baud_rate = B9600;
- }
- } else if (!strcasecmp(v->name, "msdstrip")) {
- if (!sscanf(v->value, "%d", &msdstrip)) {
- ast_log(LOG_NOTICE, "Invalid msdstrip value in %s (line %d), using default\n", config_file, v->lineno);
- msdstrip = 0;
- } else if (0 > msdstrip || msdstrip > 9) {
- ast_log(LOG_NOTICE, "Invalid msdstrip value in %s (line %d), using default\n", config_file, v->lineno);
- msdstrip = 0;
- }
- } else if (!strcasecmp(v->name, "msgexpirytime")) {
- if (!sscanf(v->value, "%ld", &msg_expiry)) {
- ast_log(LOG_NOTICE, "Invalid msgexpirytime value in %s (line %d), using default\n", config_file, v->lineno);
- msg_expiry = SMDI_MSG_EXPIRY_TIME;
- }
- } else if (!strcasecmp(v->name, "paritybit")) {
- if (!strcasecmp(v->value, "even"))
- paritybit = PARENB;
- else if (!strcasecmp(v->value, "odd"))
- paritybit = PARENB | PARODD;
- else if (!strcasecmp(v->value, "none"))
- paritybit = ~PARENB;
- else {
- ast_log(LOG_NOTICE, "Invalid parity bit setting in %s (line %d), using default\n", config_file, v->lineno);
- paritybit = PARENB;
- }
- } else if (!strcasecmp(v->name, "charsize")) {
- if (!strcasecmp(v->value, "7"))
- charsize = CS7;
- else if (!strcasecmp(v->value, "8"))
- charsize = CS8;
- else {
- ast_log(LOG_NOTICE, "Invalid character size setting in %s (line %d), using default\n", config_file, v->lineno);
- charsize = CS7;
- }
- } else if (!strcasecmp(v->name, "twostopbits")) {
- stopbits = ast_true(v->name);
- } else if (!strcasecmp(v->name, "smdiport")) {
- if (reload) {
- /* we are reloading, check if we are already
- * monitoring this interface, if we are we do
- * not want to start it again. This also has
- * the side effect of not updating different
- * setting for the serial port, but it should
- * be trivial to rewrite this section so that
- * options on the port are changed without
- * restarting the interface. Or the interface
- * could be restarted with out emptying the
- * queue. */
- if ((iface = ASTOBJ_CONTAINER_FIND(&smdi_ifaces, v->value))) {
- ast_log(LOG_NOTICE, "SMDI interface %s already running, not restarting\n", iface->name);
- ASTOBJ_UNMARK(iface);
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- continue;
- }
- }
-
- if (!(iface = alloc_smdi_interface()))
- continue;
-
- ast_copy_string(iface->name, v->value, sizeof(iface->name));
-
- iface->thread = AST_PTHREADT_NULL;
-
- if (!(iface->file = fopen(iface->name, "r"))) {
- ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s)\n", iface->name, strerror(errno));
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- continue;
- }
-
- iface->fd = fileno(iface->file);
-
- /* Set the proper attributes for our serial port. */
-
- /* get the current attributes from the port */
- if (tcgetattr(iface->fd, &iface->mode)) {
- ast_log(LOG_ERROR, "Error getting atributes of %s (%s)\n", iface->name, strerror(errno));
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- continue;
- }
-
- /* set the desired speed */
- if (cfsetispeed(&iface->mode, baud_rate) || cfsetospeed(&iface->mode, baud_rate)) {
- ast_log(LOG_ERROR, "Error setting baud rate on %s (%s)\n", iface->name, strerror(errno));
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- continue;
- }
-
- /* set the stop bits */
- if (stopbits)
- iface->mode.c_cflag = iface->mode.c_cflag | CSTOPB; /* set two stop bits */
- else
- iface->mode.c_cflag = iface->mode.c_cflag & ~CSTOPB; /* set one stop bit */
-
- /* set the parity */
- iface->mode.c_cflag = (iface->mode.c_cflag & ~PARENB & ~PARODD) | paritybit;
-
- /* set the character size */
- iface->mode.c_cflag = (iface->mode.c_cflag & ~CSIZE) | charsize;
-
- /* commit the desired attributes */
- if (tcsetattr(iface->fd, TCSAFLUSH, &iface->mode)) {
- ast_log(LOG_ERROR, "Error setting attributes on %s (%s)\n", iface->name, strerror(errno));
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- continue;
- }
-
- /* set the msdstrip */
- iface->msdstrip = msdstrip;
-
- /* set the message expiry time */
- iface->msg_expiry = msg_expiry;
-
- /* start the listener thread */
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Starting SMDI monitor thread for %s\n", iface->name);
- if (ast_pthread_create_background(&iface->thread, NULL, smdi_read, iface)) {
- ast_log(LOG_ERROR, "Error starting SMDI monitor thread for %s\n", iface->name);
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- continue;
- }
-
- ASTOBJ_CONTAINER_LINK(&smdi_ifaces, iface);
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
- ast_module_ref(ast_module_info->self);
- } else {
- ast_log(LOG_NOTICE, "Ignoring unknown option %s in %s\n", v->name, config_file);
- }
- }
-
- destroy_all_mailbox_mappings();
- mwi_monitor.polling_interval = DEFAULT_POLLING_INTERVAL;
-
- iface = NULL;
-
- for (v = ast_variable_browse(conf, "mailboxes"); v; v = v->next) {
- if (!strcasecmp(v->name, "smdiport")) {
- if (iface)
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
-
- if (!(iface = ASTOBJ_CONTAINER_FIND(&smdi_ifaces, v->value))) {
- ast_log(LOG_NOTICE, "SMDI interface %s not found\n", iface->name);
- continue;
- }
- } else if (!strcasecmp(v->name, "pollinginterval")) {
- if (sscanf(v->value, "%u", &mwi_monitor.polling_interval) != 1) {
- ast_log(LOG_ERROR, "Invalid value for pollinginterval: %s\n", v->value);
- mwi_monitor.polling_interval = DEFAULT_POLLING_INTERVAL;
- }
- } else {
- if (!iface) {
- ast_log(LOG_ERROR, "Mailbox mapping ignored, no valid SMDI interface specified in mailboxes section\n");
- continue;
- }
- append_mailbox_mapping(v, iface);
- }
- }
-
- if (iface)
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
-
- ast_config_destroy(conf);
-
- if (!AST_LIST_EMPTY(&mwi_monitor.mailbox_mappings) && mwi_monitor.thread == AST_PTHREADT_NULL
- && ast_pthread_create_background(&mwi_monitor.thread, NULL, mwi_monitor_handler, NULL)) {
- ast_log(LOG_ERROR, "Failed to start MWI monitoring thread. This module will not operate.\n");
- return AST_MODULE_LOAD_FAILURE;
- }
-
- /* Prune any interfaces we should no longer monitor. */
- if (reload)
- ASTOBJ_CONTAINER_PRUNE_MARKED(&smdi_ifaces, ast_smdi_interface_destroy);
-
- ASTOBJ_CONTAINER_RDLOCK(&smdi_ifaces);
- /* TODO: this is bad, we need an ASTOBJ method for this! */
- if (!smdi_ifaces.head)
- res = 1;
- ASTOBJ_CONTAINER_UNLOCK(&smdi_ifaces);
-
- return res;
-}
-
-struct smdi_msg_datastore {
- unsigned int id;
- struct ast_smdi_interface *iface;
- struct ast_smdi_md_message *md_msg;
-};
-
-static void smdi_msg_datastore_destroy(void *data)
-{
- struct smdi_msg_datastore *smd = data;
-
- if (smd->iface)
- ASTOBJ_UNREF(smd->iface, ast_smdi_interface_destroy);
-
- if (smd->md_msg)
- ASTOBJ_UNREF(smd->md_msg, ast_smdi_md_message_destroy);
-
- free(smd);
-}
-
-static const struct ast_datastore_info smdi_msg_datastore_info = {
- .type = "SMDIMSG",
- .destroy = smdi_msg_datastore_destroy,
-};
-
-static int smdi_msg_id;
-
-/*! In milliseconds */
-#define SMDI_RETRIEVE_TIMEOUT_DEFAULT 3000
-
-static int smdi_msg_retrieve_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct ast_module_user *u;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(port);
- AST_APP_ARG(station);
- AST_APP_ARG(timeout);
- );
- unsigned int timeout = SMDI_RETRIEVE_TIMEOUT_DEFAULT;
- int res = -1;
- char *parse = NULL;
- struct smdi_msg_datastore *smd = NULL;
- struct ast_datastore *datastore = NULL;
- struct ast_smdi_interface *iface = NULL;
- struct ast_smdi_md_message *md_msg = NULL;
-
- u = ast_module_user_add(chan);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "SMDI_MSG_RETRIEVE requires an argument\n");
- goto return_error;
- }
-
- if (!chan) {
- ast_log(LOG_ERROR, "SMDI_MSG_RETRIEVE must be used with a channel\n");
- goto return_error;
- }
-
- ast_autoservice_start(chan);
-
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.port) || ast_strlen_zero(args.station)) {
- ast_log(LOG_ERROR, "Invalid arguments provided to SMDI_MSG_RETRIEVE\n");
- goto return_error;
- }
-
- if (!(iface = ast_smdi_interface_find(args.port))) {
- ast_log(LOG_ERROR, "SMDI port '%s' not found\n", args.port);
- goto return_error;
- }
-
- if (!ast_strlen_zero(args.timeout)) {
- if (sscanf(args.timeout, "%u", &timeout) != 1) {
- ast_log(LOG_ERROR, "'%s' is not a valid timeout\n", args.timeout);
- timeout = SMDI_RETRIEVE_TIMEOUT_DEFAULT;
- }
- }
-
- if (!(md_msg = smdi_message_wait(iface, timeout, SMDI_MD, args.station))) {
- ast_log(LOG_WARNING, "No SMDI message retrieved for station '%s' after "
- "waiting %u ms.\n", args.station, timeout);
- goto return_error;
- }
-
- if (!(smd = ast_calloc(1, sizeof(*smd))))
- goto return_error;
-
- smd->iface = ASTOBJ_REF(iface);
- smd->md_msg = ASTOBJ_REF(md_msg);
- smd->id = ast_atomic_fetchadd_int((int *) &smdi_msg_id, 1);
- snprintf(buf, len, "%u", smd->id);
-
- if (!(datastore = ast_channel_datastore_alloc(&smdi_msg_datastore_info, buf)))
- goto return_error;
-
- datastore->data = smd;
-
- ast_channel_lock(chan);
- ast_channel_datastore_add(chan, datastore);
- ast_channel_unlock(chan);
-
- res = 0;
-
-return_error:
- if (iface)
- ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
-
- if (md_msg)
- ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy);
-
- if (smd && !datastore)
- smdi_msg_datastore_destroy(smd);
-
- if (parse)
- ast_autoservice_stop(chan);
-
- ast_module_user_remove(u);
-
- return res;
-}
-
-static int smdi_msg_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- struct ast_module_user *u;
- int res = -1;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(id);
- AST_APP_ARG(component);
- );
- char *parse;
- struct ast_datastore *datastore = NULL;
- struct smdi_msg_datastore *smd = NULL;
-
- u = ast_module_user_add(chan);
-
- if (!chan) {
- ast_log(LOG_ERROR, "SMDI_MSG can not be called without a channel\n");
- goto return_error;
- }
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SMDI_MSG requires an argument\n");
- goto return_error;
- }
-
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.id)) {
- ast_log(LOG_WARNING, "ID must be supplied to SMDI_MSG\n");
- goto return_error;
- }
-
- if (ast_strlen_zero(args.component)) {
- ast_log(LOG_WARNING, "ID must be supplied to SMDI_MSG\n");
- goto return_error;
- }
-
- ast_channel_lock(chan);
- datastore = ast_channel_datastore_find(chan, &smdi_msg_datastore_info, args.id);
- ast_channel_unlock(chan);
-
- if (!datastore) {
- ast_log(LOG_WARNING, "No SMDI message found for message ID '%s'\n", args.id);
- goto return_error;
- }
-
- smd = datastore->data;
-
- if (!strcasecmp(args.component, "station")) {
- ast_copy_string(buf, smd->md_msg->fwd_st, len);
- } else if (!strcasecmp(args.component, "callerid")) {
- ast_copy_string(buf, smd->md_msg->calling_st, len);
- } else if (!strcasecmp(args.component, "type")) {
- snprintf(buf, len, "%c", smd->md_msg->type);
- } else {
- ast_log(LOG_ERROR, "'%s' is not a valid message component for SMDI_MSG\n",
- args.component);
- goto return_error;
- }
-
- res = 0;
-
-return_error:
- ast_module_user_remove(u);
-
- return 0;
-}
-
-static struct ast_custom_function smdi_msg_retrieve_function = {
- .name = "SMDI_MSG_RETRIEVE",
- .synopsis = "Retrieve an SMDI message.",
- .syntax = "SMDI_MSG_RETRIEVE(<smdi port>,<station>[,timeout])",
- .desc =
- " This function is used to retrieve an incoming SMDI message. It returns\n"
- "an ID which can be used with the SMDI_MSG() function to access details of\n"
- "the message. Note that this is a destructive function in the sense that\n"
- "once an SMDI message is retrieved using this function, it is no longer in\n"
- "the global SMDI message queue, and can not be accessed by any other Asterisk\n"
- "channels. The timeout for this function is optional, and the default is\n"
- "3 seconds. When providing a timeout, it should be in milliseconds.\n"
- "",
- .read = smdi_msg_retrieve_read,
-};
-
-static struct ast_custom_function smdi_msg_function = {
- .name = "SMDI_MSG",
- .synopsis = "Retrieve details about an SMDI message.",
- .syntax = "SMDI_MSG(<message_id>,<component>)",
- .desc =
- " This function is used to access details of an SMDI message that was\n"
- "pulled from the incoming SMDI message queue using the SMDI_MSG_RETRIEVE()\n"
- "function.\n"
- " Valid message components are:\n"
- " station - The forwarding station\n"
- " callerid - The callerID of the calling party that was forwarded\n"
- " type - The call type. The value here is the exact character\n"
- " that came in on the SMDI link. Typically, example values\n"
- " are: D - Direct Calls, A - Forward All Calls,\n"
- " B - Forward Busy Calls, N - Forward No Answer Calls\n"
- "",
- .read = smdi_msg_read,
-};
-
-static int load_module(void)
-{
- int res;
-
- /* initialize our containers */
- memset(&smdi_ifaces, 0, sizeof(smdi_ifaces));
- ASTOBJ_CONTAINER_INIT(&smdi_ifaces);
-
- ast_mutex_init(&mwi_monitor.lock);
- ast_cond_init(&mwi_monitor.cond, NULL);
-
- ast_custom_function_register(&smdi_msg_retrieve_function);
- ast_custom_function_register(&smdi_msg_function);
-
- /* load the config and start the listener threads*/
- res = smdi_load(0);
- if (res < 0) {
- return res;
- } else if (res == 1) {
- ast_log(LOG_WARNING, "No SMDI interfaces are available to listen on, not starting SMDI listener.\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- return 0;
-}
-
-static int unload_module(void)
-{
- /* this destructor stops any running smdi_read threads */
- ASTOBJ_CONTAINER_DESTROYALL(&smdi_ifaces, ast_smdi_interface_destroy);
- ASTOBJ_CONTAINER_DESTROY(&smdi_ifaces);
-
- destroy_all_mailbox_mappings();
-
- ast_mutex_lock(&mwi_monitor.lock);
- mwi_monitor.stop = 1;
- ast_cond_signal(&mwi_monitor.cond);
- ast_mutex_unlock(&mwi_monitor.lock);
-
- if (mwi_monitor.thread != AST_PTHREADT_NULL) {
- pthread_join(mwi_monitor.thread, NULL);
- }
-
- ast_custom_function_unregister(&smdi_msg_retrieve_function);
- ast_custom_function_unregister(&smdi_msg_function);
-
- return 0;
-}
-
-static int reload(void)
-{
- int res;
-
- res = smdi_load(1);
-
- if (res < 0) {
- return res;
- } else if (res == 1) {
- ast_log(LOG_WARNING, "No SMDI interfaces were specified to listen on, not starting SDMI listener.\n");
- return 0;
- } else
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Simplified Message Desk Interface (SMDI) Resource",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/1.4/res/res_snmp.c b/1.4/res/res_snmp.c
deleted file mode 100644
index 6bbf23171..000000000
--- a/1.4/res/res_snmp.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2006 Voop as
- * Thorsten Lockert <tholo@voop.as>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief SNMP Agent / SubAgent support for Asterisk
- *
- * \author Thorsten Lockert <tholo@voop.as>
- */
-
-/*** MODULEINFO
- <depend>netsnmp</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-
-#include "snmp/agent.h"
-
-#define MODULE_DESCRIPTION "SNMP [Sub]Agent for Asterisk"
-
-int res_snmp_agentx_subagent;
-int res_snmp_dont_stop;
-int res_snmp_enabled;
-
-static pthread_t thread = AST_PTHREADT_NULL;
-
-static int load_config(void)
-{
- struct ast_variable *var;
- struct ast_config *cfg;
- char *cat;
-
- res_snmp_enabled = 0;
- res_snmp_agentx_subagent = 1;
- cfg = ast_config_load("res_snmp.conf");
- if (!cfg) {
- ast_log(LOG_WARNING, "Could not load res_snmp.conf\n");
- return 0;
- }
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- var = ast_variable_browse(cfg, cat);
-
- if (strcasecmp(cat, "general") == 0) {
- while (var) {
- if (strcasecmp(var->name, "subagent") == 0) {
- if (ast_true(var->value))
- res_snmp_agentx_subagent = 1;
- else if (ast_false(var->value))
- res_snmp_agentx_subagent = 0;
- else {
- ast_log(LOG_ERROR, "Value '%s' does not evaluate to true or false.\n", var->value);
- ast_config_destroy(cfg);
- return 1;
- }
- } else if (strcasecmp(var->name, "enabled") == 0) {
- res_snmp_enabled = ast_true(var->value);
- } else {
- ast_log(LOG_ERROR, "Unrecognized variable '%s' in category '%s'\n", var->name, cat);
- ast_config_destroy(cfg);
- return 1;
- }
- var = var->next;
- }
- } else {
- ast_log(LOG_ERROR, "Unrecognized category '%s'\n", cat);
- ast_config_destroy(cfg);
- return 1;
- }
-
- cat = ast_category_browse(cfg, cat);
- }
- ast_config_destroy(cfg);
- return 1;
-}
-
-static int load_module(void)
-{
- if(!load_config())
- return AST_MODULE_LOAD_DECLINE;
-
- ast_verbose(VERBOSE_PREFIX_1 "Loading [Sub]Agent Module\n");
-
- res_snmp_dont_stop = 1;
- if (res_snmp_enabled)
- return ast_pthread_create_background(&thread, NULL, agent_thread, NULL);
- else
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_verbose(VERBOSE_PREFIX_1 "Unloading [Sub]Agent Module\n");
-
- res_snmp_dont_stop = 0;
- return ((thread != AST_PTHREADT_NULL) ? pthread_join(thread, NULL) : 0);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "SNMP [Sub]Agent for Asterisk",
- .load = load_module,
- .unload = unload_module,
- );
diff --git a/1.4/res/res_speech.c b/1.4/res/res_speech.c
deleted file mode 100644
index 5baca9679..000000000
--- a/1.4/res/res_speech.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2006, Digium, Inc.
- *
- * Joshua Colp <jcolp@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.
- */
-
-/*! \file
- *
- * \brief Generic Speech Recognition API
- *
- * \author Joshua Colp <jcolp@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/lock.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/cli.h"
-#include "asterisk/term.h"
-#include "asterisk/options.h"
-#include "asterisk/speech.h"
-
-
-static AST_LIST_HEAD_STATIC(engines, ast_speech_engine);
-static struct ast_speech_engine *default_engine = NULL;
-
-/*! \brief Find a speech recognition engine of specified name, if NULL then use the default one */
-static struct ast_speech_engine *find_engine(char *engine_name)
-{
- struct ast_speech_engine *engine = NULL;
-
- /* If no name is specified -- use the default engine */
- if (engine_name == NULL || strlen(engine_name) == 0) {
- return default_engine;
- }
-
- AST_LIST_LOCK(&engines);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&engines, engine, list) {
- if (!strcasecmp(engine->name, engine_name)) {
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&engines);
-
- return engine;
-}
-
-/*! \brief Activate a loaded (either local or global) grammar */
-int ast_speech_grammar_activate(struct ast_speech *speech, char *grammar_name)
-{
- int res = 0;
-
- if (speech->engine->activate != NULL) {
- res = speech->engine->activate(speech, grammar_name);
- }
-
- return res;
-}
-
-/*! \brief Deactivate a loaded grammar on a speech structure */
-int ast_speech_grammar_deactivate(struct ast_speech *speech, char *grammar_name)
-{
- int res = 0;
-
- if (speech->engine->deactivate != NULL) {
- res = speech->engine->deactivate(speech, grammar_name);
- }
-
- return res;
-}
-
-/*! \brief Load a local grammar on a speech structure */
-int ast_speech_grammar_load(struct ast_speech *speech, char *grammar_name, char *grammar)
-{
- int res = 0;
-
- if (speech->engine->load != NULL) {
- res = speech->engine->load(speech, grammar_name, grammar);
- }
-
- return res;
-}
-
-/*! \brief Unload a local grammar from a speech structure */
-int ast_speech_grammar_unload(struct ast_speech *speech, char *grammar_name)
-{
- int res = 0;
-
- if (speech->engine->unload != NULL) {
- res = speech->engine->unload(speech, grammar_name);
- }
-
- return res;
-}
-
-/*! \brief Return the results of a recognition from the speech structure */
-struct ast_speech_result *ast_speech_results_get(struct ast_speech *speech)
-{
- struct ast_speech_result *result = NULL;
-
- if (speech->engine->get != NULL) {
- result = speech->engine->get(speech);
- }
-
- return result;
-}
-
-/*! \brief Free a list of results */
-int ast_speech_results_free(struct ast_speech_result *result)
-{
- struct ast_speech_result *current_result = result, *prev_result = NULL;
- int res = 0;
-
- while (current_result != NULL) {
- prev_result = current_result;
- /* Deallocate what we can */
- if (current_result->text != NULL) {
- free(current_result->text);
- current_result->text = NULL;
- }
- if (current_result->grammar != NULL) {
- free(current_result->grammar);
- current_result->grammar = NULL;
- }
- /* Move on and then free ourselves */
- current_result = current_result->next;
- free(prev_result);
- prev_result = NULL;
- }
-
- return res;
-}
-
-/*! \brief Start speech recognition on a speech structure */
-void ast_speech_start(struct ast_speech *speech)
-{
-
- /* Clear any flags that may affect things */
- ast_clear_flag(speech, AST_SPEECH_SPOKE);
- ast_clear_flag(speech, AST_SPEECH_QUIET);
- ast_clear_flag(speech, AST_SPEECH_HAVE_RESULTS);
-
- /* If results are on the structure, free them since we are starting again */
- if (speech->results != NULL) {
- ast_speech_results_free(speech->results);
- speech->results = NULL;
- }
-
- /* If the engine needs to start stuff up, do it */
- if (speech->engine->start != NULL) {
- speech->engine->start(speech);
- }
-
- return;
-}
-
-/*! \brief Write in signed linear audio to be recognized */
-int ast_speech_write(struct ast_speech *speech, void *data, int len)
-{
- int res = 0;
-
- /* Make sure the speech engine is ready to accept audio */
- if (speech->state != AST_SPEECH_STATE_READY) {
- return -1;
- }
-
- if (speech->engine->write != NULL) {
- speech->engine->write(speech, data, len);
- }
-
- return res;
-}
-
-/*! \brief Signal to the engine that DTMF was received */
-int ast_speech_dtmf(struct ast_speech *speech, const char *dtmf)
-{
- int res = 0;
-
- if (speech->state != AST_SPEECH_STATE_READY)
- return -1;
-
- if (speech->engine->dtmf != NULL) {
- res = speech->engine->dtmf(speech, dtmf);
- }
-
- return res;
-}
-
-/*! \brief Change an engine specific attribute */
-int ast_speech_change(struct ast_speech *speech, char *name, const char *value)
-{
- int res = 0;
-
- if (speech->engine->change != NULL) {
- res = speech->engine->change(speech, name, value);
- }
-
- return res;
-}
-
-/*! \brief Create a new speech structure using the engine specified */
-struct ast_speech *ast_speech_new(char *engine_name, int format)
-{
- struct ast_speech_engine *engine = NULL;
- struct ast_speech *new_speech = NULL;
-
- /* Try to find the speech recognition engine that was requested */
- engine = find_engine(engine_name);
- if (engine == NULL) {
- /* Invalid engine or no engine available */
- return NULL;
- }
-
- /* Allocate our own speech structure, and try to allocate a structure from the engine too */
- new_speech = ast_calloc(1, sizeof(*new_speech));
- if (new_speech == NULL) {
- /* Ran out of memory while trying to allocate some for a speech structure */
- return NULL;
- }
-
- /* Initialize the lock */
- ast_mutex_init(&new_speech->lock);
-
- /* Make sure no results are present */
- new_speech->results = NULL;
-
- /* Copy over our engine pointer */
- new_speech->engine = engine;
-
- /* We are not ready to accept audio yet */
- ast_speech_change_state(new_speech, AST_SPEECH_STATE_NOT_READY);
-
- /* Pass ourselves to the engine so they can set us up some more and if they error out then do not create a structure */
- if (engine->create(new_speech)) {
- ast_mutex_destroy(&new_speech->lock);
- free(new_speech);
- new_speech = NULL;
- }
-
- return new_speech;
-}
-
-/*! \brief Destroy a speech structure */
-int ast_speech_destroy(struct ast_speech *speech)
-{
- int res = 0;
-
- /* Call our engine so we are destroyed properly */
- speech->engine->destroy(speech);
-
- /* Deinitialize the lock */
- ast_mutex_destroy(&speech->lock);
-
- /* If results exist on the speech structure, destroy them */
- if (speech->results != NULL) {
- ast_speech_results_free(speech->results);
- speech->results = NULL;
- }
-
- /* If a processing sound is set - free the memory used by it */
- if (speech->processing_sound != NULL) {
- free(speech->processing_sound);
- speech->processing_sound = NULL;
- }
-
- /* Aloha we are done */
- free(speech);
- speech = NULL;
-
- return res;
-}
-
-/*! \brief Change state of a speech structure */
-int ast_speech_change_state(struct ast_speech *speech, int state)
-{
- int res = 0;
-
- switch (state) {
- case AST_SPEECH_STATE_WAIT:
- /* The engine heard audio, so they spoke */
- ast_set_flag(speech, AST_SPEECH_SPOKE);
- default:
- speech->state = state;
- break;
- }
-
- return res;
-}
-
-/*! \brief Change the type of results we want */
-int ast_speech_change_results_type(struct ast_speech *speech, enum ast_speech_results_type results_type)
-{
- int res = 0;
-
- speech->results_type = results_type;
-
- if (speech->engine->change_results_type)
- res = speech->engine->change_results_type(speech, results_type);
-
- return res;
-}
-
-/*! \brief Register a speech recognition engine */
-int ast_speech_register(struct ast_speech_engine *engine)
-{
- struct ast_speech_engine *existing_engine = NULL;
- int res = 0;
-
- existing_engine = find_engine(engine->name);
- if (existing_engine != NULL) {
- /* Engine already loaded */
- return -1;
- }
-
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Registered speech recognition engine '%s'\n", engine->name);
-
- /* Add to the engine linked list and make default if needed */
- AST_LIST_LOCK(&engines);
- AST_LIST_INSERT_HEAD(&engines, engine, list);
- if (default_engine == NULL) {
- default_engine = engine;
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Made '%s' the default speech recognition engine\n", engine->name);
- }
- AST_LIST_UNLOCK(&engines);
-
- return res;
-}
-
-/*! \brief Unregister a speech recognition engine */
-int ast_speech_unregister(char *engine_name)
-{
- struct ast_speech_engine *engine = NULL;
- int res = -1;
-
- if (engine_name == NULL) {
- return res;
- }
-
- AST_LIST_LOCK(&engines);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&engines, engine, list) {
- if (!strcasecmp(engine->name, engine_name)) {
- /* We have our engine... removed it */
- AST_LIST_REMOVE_CURRENT(&engines, list);
- /* If this was the default engine, we need to pick a new one */
- if (default_engine == engine) {
- default_engine = AST_LIST_FIRST(&engines);
- }
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered speech recognition engine '%s'\n", engine_name);
- /* All went well */
- res = 0;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&engines);
-
- return res;
-}
-
-static int unload_module(void)
-{
- /* We can not be unloaded */
- return -1;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- /* Initialize our list of engines */
- AST_LIST_HEAD_INIT_NOLOCK(&engines);
-
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Generic Speech Recognition API",
- .load = load_module,
- .unload = unload_module,
- );
diff --git a/1.4/res/snmp/agent.c b/1.4/res/snmp/agent.c
deleted file mode 100644
index 96398e8a8..000000000
--- a/1.4/res/snmp/agent.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * Copyright (C) 2006 Voop as
- * Thorsten Lockert <tholo@voop.as>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief SNMP Agent / SubAgent support for Asterisk
- *
- * \author Thorsten Lockert <tholo@voop.as>
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <net-snmp/net-snmp-config.h>
-#include <net-snmp/net-snmp-includes.h>
-#include <net-snmp/agent/net-snmp-agent-includes.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/options.h"
-#include "asterisk/indications.h"
-#include "asterisk/version.h"
-#include "asterisk/pbx.h"
-
-/* Colission between Net-SNMP and Asterisk */
-#define unload_module ast_unload_module
-#include "asterisk/module.h"
-#undef unload_module
-
-#include "agent.h"
-
-/* Helper functions in Net-SNMP, header file not installed by default */
-int header_generic(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **);
-int header_simple_table(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **, int);
-int register_sysORTable(oid *, size_t, const char *);
-int unregister_sysORTable(oid *, size_t);
-
-/* Not defined in header files */
-extern char ast_config_AST_SOCKET[];
-
-/* Forward declaration */
-static void init_asterisk_mib(void);
-
-/*
- * Anchor for all the Asterisk MIB values
- */
-static oid asterisk_oid[] = { 1, 3, 6, 1, 4, 1, 22736, 1 };
-
-/*
- * MIB values -- these correspond to values in the Asterisk MIB,
- * and MUST be kept in sync with the MIB for things to work as
- * expected.
- */
-#define ASTVERSION 1
-#define ASTVERSTRING 1
-#define ASTVERTAG 2
-
-#define ASTCONFIGURATION 2
-#define ASTCONFUPTIME 1
-#define ASTCONFRELOADTIME 2
-#define ASTCONFPID 3
-#define ASTCONFSOCKET 4
-
-#define ASTMODULES 3
-#define ASTMODCOUNT 1
-
-#define ASTINDICATIONS 4
-#define ASTINDCOUNT 1
-#define ASTINDCURRENT 2
-
-#define ASTINDTABLE 3
-#define ASTINDINDEX 1
-#define ASTINDCOUNTRY 2
-#define ASTINDALIAS 3
-#define ASTINDDESCRIPTION 4
-
-#define ASTCHANNELS 5
-#define ASTCHANCOUNT 1
-
-#define ASTCHANTABLE 2
-#define ASTCHANINDEX 1
-#define ASTCHANNAME 2
-#define ASTCHANLANGUAGE 3
-#define ASTCHANTYPE 4
-#define ASTCHANMUSICCLASS 5
-#define ASTCHANBRIDGE 6
-#define ASTCHANMASQ 7
-#define ASTCHANMASQR 8
-#define ASTCHANWHENHANGUP 9
-#define ASTCHANAPP 10
-#define ASTCHANDATA 11
-#define ASTCHANCONTEXT 12
-#define ASTCHANMACROCONTEXT 13
-#define ASTCHANMACROEXTEN 14
-#define ASTCHANMACROPRI 15
-#define ASTCHANEXTEN 16
-#define ASTCHANPRI 17
-#define ASTCHANACCOUNTCODE 18
-#define ASTCHANFORWARDTO 19
-#define ASTCHANUNIQUEID 20
-#define ASTCHANCALLGROUP 21
-#define ASTCHANPICKUPGROUP 22
-#define ASTCHANSTATE 23
-#define ASTCHANMUTED 24
-#define ASTCHANRINGS 25
-#define ASTCHANCIDDNID 26
-#define ASTCHANCIDNUM 27
-#define ASTCHANCIDNAME 28
-#define ASTCHANCIDANI 29
-#define ASTCHANCIDRDNIS 30
-#define ASTCHANCIDPRES 31
-#define ASTCHANCIDANI2 32
-#define ASTCHANCIDTON 33
-#define ASTCHANCIDTNS 34
-#define ASTCHANAMAFLAGS 35
-#define ASTCHANADSI 36
-#define ASTCHANTONEZONE 37
-#define ASTCHANHANGUPCAUSE 38
-#define ASTCHANVARIABLES 39
-#define ASTCHANFLAGS 40
-#define ASTCHANTRANSFERCAP 41
-
-#define ASTCHANTYPECOUNT 3
-
-#define ASTCHANTYPETABLE 4
-#define ASTCHANTYPEINDEX 1
-#define ASTCHANTYPENAME 2
-#define ASTCHANTYPEDESC 3
-#define ASTCHANTYPEDEVSTATE 4
-#define ASTCHANTYPEINDICATIONS 5
-#define ASTCHANTYPETRANSFER 6
-#define ASTCHANTYPECHANNELS 7
-
-void *agent_thread(void *arg)
-{
- ast_verbose(VERBOSE_PREFIX_2 "Starting %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");
-
- snmp_enable_stderrlog();
-
- if (res_snmp_agentx_subagent)
- netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
- NETSNMP_DS_AGENT_ROLE,
- 1);
-
- init_agent("asterisk");
-
- init_asterisk_mib();
-
- init_snmp("asterisk");
-
- if (!res_snmp_agentx_subagent)
- init_master_agent();
-
- while (res_snmp_dont_stop)
- agent_check_and_process(1);
-
- snmp_shutdown("asterisk");
-
- ast_verbose(VERBOSE_PREFIX_2 "Terminating %sAgent\n",
- res_snmp_agentx_subagent ? "Sub" : "");
-
- return NULL;
-}
-
-static u_char *
-ast_var_channels(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
-
- if (header_generic(vp, name, length, exact, var_len, write_method))
- return NULL;
-
- switch (vp->magic) {
- case ASTCHANCOUNT:
- long_ret = ast_active_channels();
- return (u_char *)&long_ret;
- default:
- break;
- }
- return NULL;
-}
-
-static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
- static u_char bits_ret[2];
- static char string_ret[256];
- struct ast_channel *chan, *bridge;
- struct timeval tval;
- u_char *ret;
- int i, bit;
-
- if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels()))
- return NULL;
-
- i = name[*length - 1] - 1;
- for (chan = ast_channel_walk_locked(NULL);
- chan && i;
- chan = ast_channel_walk_locked(chan), i--)
- ast_channel_unlock(chan);
- if (chan == NULL)
- return NULL;
- *var_len = sizeof(long_ret);
-
- switch (vp->magic) {
- case ASTCHANINDEX:
- long_ret = name[*length - 1];
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANNAME:
- if (!ast_strlen_zero(chan->name)) {
- strncpy(string_ret, chan->name, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANLANGUAGE:
- if (!ast_strlen_zero(chan->language)) {
- strncpy(string_ret, chan->language, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANTYPE:
- strncpy(string_ret, chan->tech->type, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- break;
- case ASTCHANMUSICCLASS:
- if (!ast_strlen_zero(chan->musicclass)) {
- strncpy(string_ret, chan->musicclass, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANBRIDGE:
- if ((bridge = ast_bridged_channel(chan)) != NULL) {
- strncpy(string_ret, bridge->name, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANMASQ:
- if (chan->masq && !ast_strlen_zero(chan->masq->name)) {
- strncpy(string_ret, chan->masq->name, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANMASQR:
- if (chan->masqr && !ast_strlen_zero(chan->masqr->name)) {
- strncpy(string_ret, chan->masqr->name, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANWHENHANGUP:
- if (chan->whentohangup) {
- gettimeofday(&tval, NULL);
- long_ret = difftime(chan->whentohangup, tval.tv_sec) * 100 - tval.tv_usec / 10000;
- ret= (u_char *)&long_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANAPP:
- if (chan->appl) {
- strncpy(string_ret, chan->appl, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANDATA:
- if (chan->data) {
- strncpy(string_ret, chan->data, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANCONTEXT:
- strncpy(string_ret, chan->context, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- break;
- case ASTCHANMACROCONTEXT:
- strncpy(string_ret, chan->macrocontext, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- break;
- case ASTCHANMACROEXTEN:
- strncpy(string_ret, chan->macroexten, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- break;
- case ASTCHANMACROPRI:
- long_ret = chan->macropriority;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANEXTEN:
- strncpy(string_ret, chan->exten, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- break;
- case ASTCHANPRI:
- long_ret = chan->priority;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANACCOUNTCODE:
- if (!ast_strlen_zero(chan->accountcode)) {
- strncpy(string_ret, chan->accountcode, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANFORWARDTO:
- if (!ast_strlen_zero(chan->call_forward)) {
- strncpy(string_ret, chan->call_forward, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANUNIQUEID:
- strncpy(string_ret, chan->uniqueid, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- break;
- case ASTCHANCALLGROUP:
- long_ret = chan->callgroup;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANPICKUPGROUP:
- long_ret = chan->pickupgroup;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANSTATE:
- long_ret = chan->_state & 0xffff;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANMUTED:
- long_ret = chan->_state & AST_STATE_MUTE ? 1 : 2;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANRINGS:
- long_ret = chan->rings;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANCIDDNID:
- if (chan->cid.cid_dnid) {
- strncpy(string_ret, chan->cid.cid_dnid, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANCIDNUM:
- if (chan->cid.cid_num) {
- strncpy(string_ret, chan->cid.cid_num, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANCIDNAME:
- if (chan->cid.cid_name) {
- strncpy(string_ret, chan->cid.cid_name, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANCIDANI:
- if (chan->cid.cid_ani) {
- strncpy(string_ret, chan->cid.cid_ani, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANCIDRDNIS:
- if (chan->cid.cid_rdnis) {
- strncpy(string_ret, chan->cid.cid_rdnis, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANCIDPRES:
- long_ret = chan->cid.cid_pres;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANCIDANI2:
- long_ret = chan->cid.cid_ani2;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANCIDTON:
- long_ret = chan->cid.cid_ton;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANCIDTNS:
- long_ret = chan->cid.cid_tns;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANAMAFLAGS:
- long_ret = chan->amaflags;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANADSI:
- long_ret = chan->adsicpe;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANTONEZONE:
- if (chan->zone) {
- strncpy(string_ret, chan->zone->country, sizeof(string_ret));
- string_ret[sizeof(string_ret) - 1] = '\0';
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANHANGUPCAUSE:
- long_ret = chan->hangupcause;
- ret = (u_char *)&long_ret;
- break;
- case ASTCHANVARIABLES:
- if (pbx_builtin_serialize_variables(chan, string_ret, sizeof(string_ret))) {
- *var_len = strlen(string_ret);
- ret = (u_char *)string_ret;
- }
- else
- ret = NULL;
- break;
- case ASTCHANFLAGS:
- bits_ret[0] = 0;
- for (bit = 0; bit < 8; bit++)
- bits_ret[0] |= ((chan->flags & (1 << bit)) >> bit) << (7 - bit);
- bits_ret[1] = 0;
- for (bit = 0; bit < 8; bit++)
- bits_ret[1] |= (((chan->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
- *var_len = 2;
- ret = bits_ret;
- break;
- case ASTCHANTRANSFERCAP:
- long_ret = chan->transfercapability;
- ret = (u_char *)&long_ret;
- break;
- default:
- ret = NULL;
- break;
- }
- ast_channel_unlock(chan);
- return ret;
-}
-
-static u_char *ast_var_channel_types(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
- struct ast_variable *channel_types, *next;
-
- if (header_generic(vp, name, length, exact, var_len, write_method))
- return NULL;
-
- switch (vp->magic) {
- case ASTCHANTYPECOUNT:
- long_ret = 0;
- for (channel_types = next = ast_channeltype_list(); next; next = next->next) {
- long_ret++;
- }
- ast_variables_destroy(channel_types);
- return (u_char *)&long_ret;
- default:
- break;
- }
- return NULL;
-}
-
-static u_char *ast_var_channel_types_table(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- const struct ast_channel_tech *tech = NULL;
- struct ast_variable *channel_types, *next;
- static unsigned long long_ret;
- struct ast_channel *chan;
- u_long i;
-
- if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
- return NULL;
-
- channel_types = ast_channeltype_list();
- for (i = 1, next = channel_types; next && i != name[*length - 1]; next = next->next, i++)
- ;
- if (next != NULL)
- tech = ast_get_channel_tech(next->name);
- ast_variables_destroy(channel_types);
- if (next == NULL || tech == NULL)
- return NULL;
-
- switch (vp->magic) {
- case ASTCHANTYPEINDEX:
- long_ret = name[*length - 1];
- return (u_char *)&long_ret;
- case ASTCHANTYPENAME:
- *var_len = strlen(tech->type);
- return (u_char *)tech->type;
- case ASTCHANTYPEDESC:
- *var_len = strlen(tech->description);
- return (u_char *)tech->description;
- case ASTCHANTYPEDEVSTATE:
- long_ret = tech->devicestate ? 1 : 2;
- return (u_char *)&long_ret;
- case ASTCHANTYPEINDICATIONS:
- long_ret = tech->indicate ? 1 : 2;
- return (u_char *)&long_ret;
- case ASTCHANTYPETRANSFER:
- long_ret = tech->transfer ? 1 : 2;
- return (u_char *)&long_ret;
- case ASTCHANTYPECHANNELS:
- long_ret = 0;
- for (chan = ast_channel_walk_locked(NULL); chan; chan = ast_channel_walk_locked(chan)) {
- ast_channel_unlock(chan);
- if (chan->tech == tech)
- long_ret++;
- }
- return (u_char *)&long_ret;
- default:
- break;
- }
- return NULL;
-}
-
-static u_char *ast_var_Config(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
- struct timeval tval;
-
- if (header_generic(vp, name, length, exact, var_len, write_method))
- return NULL;
-
- switch (vp->magic) {
- case ASTCONFUPTIME:
- gettimeofday(&tval, NULL);
- long_ret = difftime(tval.tv_sec, ast_startuptime) * 100 + tval.tv_usec / 10000;
- return (u_char *)&long_ret;
- case ASTCONFRELOADTIME:
- gettimeofday(&tval, NULL);
- if (ast_lastreloadtime)
- long_ret = difftime(tval.tv_sec, ast_lastreloadtime) * 100 + tval.tv_usec / 10000;
- else
- long_ret = difftime(tval.tv_sec, ast_startuptime) * 100 + tval.tv_usec / 10000;
- return (u_char *)&long_ret;
- case ASTCONFPID:
- long_ret = getpid();
- return (u_char *)&long_ret;
- case ASTCONFSOCKET:
- *var_len = strlen(ast_config_AST_SOCKET);
- return (u_char *)ast_config_AST_SOCKET;
- default:
- break;
- }
- return NULL;
-}
-
-static u_char *ast_var_indications(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
- struct tone_zone *tz = NULL;
-
- if (header_generic(vp, name, length, exact, var_len, write_method))
- return NULL;
-
- switch (vp->magic) {
- case ASTINDCOUNT:
- long_ret = 0;
- while ( (tz = ast_walk_indications(tz)) )
- long_ret++;
-
- return (u_char *)&long_ret;
- case ASTINDCURRENT:
- tz = ast_get_indication_zone(NULL);
- if (tz) {
- *var_len = strlen(tz->country);
- return (u_char *)tz->country;
- }
- *var_len = 0;
- return NULL;
- default:
- break;
- }
- return NULL;
-}
-
-static u_char *ast_var_indications_table(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
- struct tone_zone *tz = NULL;
- int i;
-
- if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
- return NULL;
-
- i = name[*length - 1] - 1;
- while ( (tz = ast_walk_indications(tz)) && i )
- i--;
- if (tz == NULL)
- return NULL;
-
- switch (vp->magic) {
- case ASTINDINDEX:
- long_ret = name[*length - 1];
- return (u_char *)&long_ret;
- case ASTINDCOUNTRY:
- *var_len = strlen(tz->country);
- return (u_char *)tz->country;
- case ASTINDALIAS:
- if (tz->alias) {
- *var_len = strlen(tz->alias);
- return (u_char *)tz->alias;
- }
- return NULL;
- case ASTINDDESCRIPTION:
- *var_len = strlen(tz->description);
- return (u_char *)tz->description;
- default:
- break;
- }
- return NULL;
-}
-
-static int countmodule(const char *mod, const char *desc, int use, const char *like)
-{
- return 1;
-}
-
-static u_char *ast_var_Modules(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
-
- if (header_generic(vp, name, length, exact, var_len, write_method))
- return NULL;
-
- switch (vp->magic) {
- case ASTMODCOUNT:
- long_ret = ast_update_module_list(countmodule, NULL);
- return (u_char *)&long_ret;
- default:
- break;
- }
- return NULL;
-}
-
-static u_char *ast_var_Version(struct variable *vp, oid *name, size_t *length,
- int exact, size_t *var_len, WriteMethod **write_method)
-{
- static unsigned long long_ret;
-
- if (header_generic(vp, name, length, exact, var_len, write_method))
- return NULL;
-
- switch (vp->magic) {
- case ASTVERSTRING:
- *var_len = strlen(ASTERISK_VERSION);
- return (u_char *)ASTERISK_VERSION;
- case ASTVERTAG:
- long_ret = ASTERISK_VERSION_NUM;
- return (u_char *)&long_ret;
- default:
- break;
- }
- return NULL;
-}
-
-static int term_asterisk_mib(int majorID, int minorID, void *serverarg, void *clientarg)
-{
- unregister_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid));
- return 0;
-}
-
-static void init_asterisk_mib(void)
-{
- static struct variable4 asterisk_vars[] = {
- {ASTVERSTRING, ASN_OCTET_STR, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERSTRING}},
- {ASTVERTAG, ASN_UNSIGNED, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERTAG}},
- {ASTCONFUPTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFUPTIME}},
- {ASTCONFRELOADTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFRELOADTIME}},
- {ASTCONFPID, ASN_INTEGER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPID}},
- {ASTCONFSOCKET, ASN_OCTET_STR, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFSOCKET}},
- {ASTMODCOUNT, ASN_INTEGER, RONLY, ast_var_Modules , 2, {ASTMODULES, ASTMODCOUNT}},
- {ASTINDCOUNT, ASN_INTEGER, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCOUNT}},
- {ASTINDCURRENT, ASN_OCTET_STR, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCURRENT}},
- {ASTINDINDEX, ASN_INTEGER, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDINDEX}},
- {ASTINDCOUNTRY, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDCOUNTRY}},
- {ASTINDALIAS, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDALIAS}},
- {ASTINDDESCRIPTION, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDDESCRIPTION}},
- {ASTCHANCOUNT, ASN_GAUGE, RONLY, ast_var_channels, 2, {ASTCHANNELS, ASTCHANCOUNT}},
- {ASTCHANINDEX, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANINDEX}},
- {ASTCHANNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANNAME}},
- {ASTCHANLANGUAGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANLANGUAGE}},
- {ASTCHANTYPE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTYPE}},
- {ASTCHANMUSICCLASS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUSICCLASS}},
- {ASTCHANBRIDGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANBRIDGE}},
- {ASTCHANMASQ, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQ}},
- {ASTCHANMASQR, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQR}},
- {ASTCHANWHENHANGUP, ASN_TIMETICKS, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANWHENHANGUP}},
- {ASTCHANAPP, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAPP}},
- {ASTCHANDATA, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANDATA}},
- {ASTCHANCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCONTEXT}},
- {ASTCHANMACROCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROCONTEXT}},
- {ASTCHANMACROEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROEXTEN}},
- {ASTCHANMACROPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROPRI}},
- {ASTCHANEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANEXTEN}},
- {ASTCHANPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPRI}},
- {ASTCHANACCOUNTCODE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANACCOUNTCODE}},
- {ASTCHANFORWARDTO, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFORWARDTO}},
- {ASTCHANUNIQUEID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANUNIQUEID}},
- {ASTCHANCALLGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCALLGROUP}},
- {ASTCHANPICKUPGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPICKUPGROUP}},
- {ASTCHANSTATE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANSTATE}},
- {ASTCHANMUTED, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUTED}},
- {ASTCHANRINGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANRINGS}},
- {ASTCHANCIDDNID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDDNID}},
- {ASTCHANCIDNUM, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNUM}},
- {ASTCHANCIDNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNAME}},
- {ASTCHANCIDANI, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI}},
- {ASTCHANCIDRDNIS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDRDNIS}},
- {ASTCHANCIDPRES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDPRES}},
- {ASTCHANCIDANI2, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI2}},
- {ASTCHANCIDTON, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTON}},
- {ASTCHANCIDTNS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTNS}},
- {ASTCHANAMAFLAGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAMAFLAGS}},
- {ASTCHANADSI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANADSI}},
- {ASTCHANTONEZONE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTONEZONE}},
- {ASTCHANHANGUPCAUSE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANHANGUPCAUSE}},
- {ASTCHANVARIABLES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANVARIABLES}},
- {ASTCHANFLAGS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFLAGS}},
- {ASTCHANTRANSFERCAP, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTRANSFERCAP}},
- {ASTCHANTYPECOUNT, ASN_INTEGER, RONLY, ast_var_channel_types, 2, {ASTCHANNELS, ASTCHANTYPECOUNT}},
- {ASTCHANTYPEINDEX, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDEX}},
- {ASTCHANTYPENAME, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPENAME}},
- {ASTCHANTYPEDESC, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDESC}},
- {ASTCHANTYPEDEVSTATE, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDEVSTATE}},
- {ASTCHANTYPEINDICATIONS, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDICATIONS}},
- {ASTCHANTYPETRANSFER, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPETRANSFER}},
- {ASTCHANTYPECHANNELS, ASN_GAUGE, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPECHANNELS}},
- };
-
- register_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid),
- "ASTERISK-MIB implementation for Asterisk.");
-
- REGISTER_MIB("res_snmp", asterisk_vars, variable4, asterisk_oid);
-
- snmp_register_callback(SNMP_CALLBACK_LIBRARY,
- SNMP_CALLBACK_SHUTDOWN,
- term_asterisk_mib, NULL);
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 4
- * c-file-offsets: ((case-label . 0))
- * tab-width: 4
- * indent-tabs-mode: t
- * End:
- */
diff --git a/1.4/res/snmp/agent.h b/1.4/res/snmp/agent.h
deleted file mode 100644
index 21389d6c9..000000000
--- a/1.4/res/snmp/agent.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2006 Voop as
- * Thorsten Lockert <tholo@voop.as>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief SNMP Agent / SubAgent support for Asterisk
- *
- * \author Thorsten Lockert <tholo@voop.as>
- */
-
-/*!
- * \internal
- * \brief Thread running the SNMP Agent or Subagent
- * \param Not used -- required by pthread_create
- * \return A pointer with return status -- not used
- *
- * This represent the main thread of the SNMP [sub]agent, and
- * will initialize SNMP and loop, processing requests until
- * termination is requested by resetting the flag in
- * \ref res_snmp_dontStop.
- */
-void *agent_thread(void *);
-
-/*!
- * \internal
- * Flag saying whether we run as a Subagent or full Agent
- */
-extern int res_snmp_agentx_subagent;
-
-/*!
- * \internal
- * Flag stating the agent thread should not terminate
- */
-extern int res_snmp_dont_stop;
diff --git a/1.4/sample.call b/1.4/sample.call
deleted file mode 100644
index 383c135bc..000000000
--- a/1.4/sample.call
+++ /dev/null
@@ -1,80 +0,0 @@
-#
-# This is a sample file that can be dumped in /var/spool/asterisk/outgoing
-# to generate a call.
-#
-# Comments are indicated by a '#' character that begins a line, or follows
-# a space or tab character. To be consistent with the configuration files
-# in Asterisk, comments can also be indicated by a semicolon. However, the
-# multiline comments (;-- --;) used in Asterisk configuration files are not
-# supported. Semicolons can be escaped by a backslash.
-#
-
-# Obviously, you MUST specify at least a channel in the same format as you
-# would for the "Dial" application. Only one channel name is permitted.
-#
-Channel: Zap/1
-#
-# You may also specify a wait time (default is 45 seconds) for how long to
-# wait for the channel to be answered, a retry time (default is 5 mins)
-# for how soon to retry this call, and a maximum number of retries (default
-# is 0) for how many times to retry this call.
-#
-MaxRetries: 2
-RetryTime: 60
-WaitTime: 30
-
-#
-# Once the call is answered, you must provide either an application/data
-# combination, or a context/extension/priority in which to start the PBX.
-#
-Context: default
-Extension: s
-Priority: 1
-
-#
-# Alternatively you can specify just an application
-# and its arguments to be run, instead of a context
-# extension and priority
-#
-#Application: VoicemailMain
-#Data: 1234
-
-#
-# You can set the callerid that will be used for the outgoing call
-#
-#Callerid: Wakeup Call Service <(555) 555-5555>
-
-#
-# An account code can be specified the following way:
-#
-#Account: mysuperfunaccountcode
-
-#
-# Normally, a call file is always deleted after the call is successful
-# or the maximum number of tries is reached even if the modification
-# time of the call file was changed during the call to be in the
-# future. By Setting AlwaysDelete to No the modification time of the
-# call file will be checked after the call is completed or the maximum
-# number of retries is reached. If the modification time is in the
-# future, the call file will not be deleted.
-#
-#AlwaysDelete: Yes
-
-#
-# You can set channel variables that will be passed to the channel.
-# This includes writable dialplan functions. To set a writable dialplan
-# function, the module containing this function *must* be loaded.
-#
-#Set: file1=/tmp/to
-#Set: file2=/tmp/msg
-#Set: timestamp=20021023104500
-#Set: CDR(userfield|r)=42
-
-#
-# Setting Archive to yes the call file is never deleted, but is moved
-# in the subdir "outgoing_done" of the spool directory. In this case
-# will be appended a line with "Status: value", where value can be
-# Completed, Expired or Failed.
-#
-#Archive: yes
-
diff --git a/1.4/sounds/Makefile b/1.4/sounds/Makefile
deleted file mode 100644
index df5e778b4..000000000
--- a/1.4/sounds/Makefile
+++ /dev/null
@@ -1,158 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for sound files
-#
-# Copyright (C) 2006, Digium, Inc.
-#
-# Kevin P. Fleming <kpfleming@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
-.PHONY: dist-clean all uninstall have_download install
-
--include $(ASTTOPDIR)/menuselect.makeopts $(ASTTOPDIR)/makeopts
-
-PWD:=$(shell pwd)
-SOUNDS_DIR:=$(DESTDIR)$(ASTDATADIR)/sounds
-MOH_DIR:=$(DESTDIR)$(ASTDATADIR)/moh
-CORE_SOUNDS_VERSION:=1.4.9
-EXTRA_SOUNDS_VERSION:=1.4.7
-SOUNDS_URL:=http://downloads.digium.com/pub/telephony/sounds/releases
-MCS:=$(subst -EN-,-en-,$(MENUSELECT_CORE_SOUNDS))
-MCS:=$(subst -FR-,-fr-,$(MCS))
-MCS:=$(subst -ES-,-es-,$(MCS))
-MCS:=$(subst -WAV,-wav,$(MCS))
-MCS:=$(subst -ULAW,-ulaw,$(MCS))
-MCS:=$(subst -ALAW,-alaw,$(MCS))
-MCS:=$(subst -GSM,-gsm,$(MCS))
-MCS:=$(subst -G729,-g729,$(MCS))
-MCS:=$(subst -G722,-g722,$(MCS))
-CORE_SOUNDS:=$(MCS:CORE-SOUNDS-%=asterisk-core-sounds-%-$(CORE_SOUNDS_VERSION).tar.gz)
-CORE_SOUND_TAGS:=$(MCS:CORE-SOUNDS-%=$(SOUNDS_DIR)/.asterisk-core-sounds-%-$(CORE_SOUNDS_VERSION))
-MES:=$(subst -EN-,-en-,$(MENUSELECT_EXTRA_SOUNDS))
-MES:=$(subst -FR-,-fr-,$(MES))
-MES:=$(subst -ES-,-es-,$(MES))
-MES:=$(subst -WAV,-wav,$(MES))
-MES:=$(subst -ULAW,-ulaw,$(MES))
-MES:=$(subst -ALAW,-alaw,$(MES))
-MES:=$(subst -GSM,-gsm,$(MES))
-MES:=$(subst -G729,-g729,$(MES))
-MES:=$(subst -G722,-g722,$(MES))
-EXTRA_SOUNDS:=$(MES:EXTRA-SOUNDS-%=asterisk-extra-sounds-%-$(EXTRA_SOUNDS_VERSION).tar.gz)
-EXTRA_SOUND_TAGS:=$(MES:EXTRA-SOUNDS-%=$(SOUNDS_DIR)/.asterisk-extra-sounds-%-$(EXTRA_SOUNDS_VERSION))
-MM:=$(subst -FREEPLAY-,-freeplay-,$(MENUSELECT_MOH))
-MM:=$(subst -WAV,-wav,$(MM))
-MM:=$(subst -ULAW,-ulaw,$(MM))
-MM:=$(subst -ALAW,-alaw,$(MM))
-MM:=$(subst -GSM,-gsm,$(MM))
-MM:=$(subst -G729,-g729,$(MM))
-MM:=$(subst -G722,-g722,$(MM))
-MOH:=$(MM:MOH-%=asterisk-moh-%.tar.gz)
-MOH_TAGS:=$(MM:MOH-%=$(MOH_DIR)/.asterisk-moh-%)
-# If "fetch" is used, --continue is not a valid option.
-ifeq ($(WGET),wget)
-WGET_ARGS:=--continue
-endif
-
-all: $(CORE_SOUNDS) $(EXTRA_SOUNDS) $(MOH)
-
-have_download:
- @if test "$(DOWNLOAD)" = ":" ; then \
- echo "**************************************************"; \
- echo "*** ***"; \
- echo "*** You must have either wget or fetch to be ***"; \
- echo "*** able to automatically download and install ***"; \
- echo "*** the requested sound packages. ***"; \
- echo "*** ***"; \
- echo "*** Please install one of these, or remove any ***"; \
- echo "*** extra sound package selections in ***"; \
- echo "*** menuselecct before installing Asterisk. ***"; \
- echo "*** ***"; \
- echo "**************************************************"; \
- exit 1; \
- fi
-
-$(SOUNDS_DIR)/.asterisk-core-sounds-en-%: have_download
- @PACKAGE=$(subst $(SOUNDS_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- rm -f $(subst -$(CORE_SOUNDS_VERSION),,$@)-* && \
- (cd $(SOUNDS_DIR); cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-$(SOUNDS_DIR)/.asterisk-core-sounds-es-%: have_download
- @PACKAGE=$(subst $(SOUNDS_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- rm -f $(subst -$(CORE_SOUNDS_VERSION),,$@)-* && \
- (cd $(SOUNDS_DIR)/es; cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-$(SOUNDS_DIR)/.asterisk-core-sounds-fr-%: have_download
- @PACKAGE=$(subst $(SOUNDS_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- rm -f $(subst -$(CORE_SOUNDS_VERSION),,$@)-* && \
- (cd $(SOUNDS_DIR)/fr; cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-$(SOUNDS_DIR)/.asterisk-extra-sounds-en-%: have_download
- @PACKAGE=$(subst $(SOUNDS_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- rm -f $(subst -$(EXTRA_SOUNDS_VERSION),,$@)-* && \
- (cd $(SOUNDS_DIR); cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-$(SOUNDS_DIR)/.asterisk-extra-sounds-es-%: have_download
- @PACKAGE=$(subst $(SOUNDS_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- rm -f $(subst -$(EXTRA_SOUNDS_VERSION),,$@)-* && \
- (cd $(SOUNDS_DIR)/es; cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-$(SOUNDS_DIR)/.asterisk-extra-sounds-fr-%: have_download
- @PACKAGE=$(subst $(SOUNDS_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- rm -f $(subst -$(EXTRA_SOUNDS_VERSION),,$@)-* && \
- (cd $(SOUNDS_DIR)/fr; cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-$(MOH_DIR)/.asterisk-moh-%: have_download
- @PACKAGE=$(subst $(MOH_DIR)/.asterisk,asterisk,$@).tar.gz; \
- if test ! -f $${PACKAGE}; then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$${PACKAGE}; fi; \
- if test ! -f $${PACKAGE}; then exit 1; fi; \
- (cd $(MOH_DIR); cat $(PWD)/$${PACKAGE} | gzip -d | tar xf -) && \
- touch $@
-
-asterisk-core-%.tar.gz: have_download
- @if test ! -f $@ ;then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$@;fi
-
-asterisk-extra-%.tar.gz: have_download
- @if test ! -f $@ ;then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$@;fi
-
-asterisk-moh-%.tar.gz: have_download
- @if test ! -f $@ ;then $(DOWNLOAD) $(WGET_ARGS) $(SOUNDS_URL)/$@;fi
-
-dist-clean:
- rm -f *.tar.gz
-
-$(SOUNDS_DIR) $(MOH_DIR) $(SOUNDS_DIR)/es $(SOUNDS_DIR)/fr:
- mkdir -p $@
-
-install: $(SOUNDS_DIR) $(SOUNDS_DIR)/es $(SOUNDS_DIR)/fr $(MOH_DIR) $(CORE_SOUND_TAGS) $(EXTRA_SOUND_TAGS) $(MOH_TAGS)
-
-uninstall:
- rm -rf $(SOUNDS_DIR)
- rm -rf $(MOH_DIR)
-
-core_sounds_version:
- @echo $(CORE_SOUNDS_VERSION)
-
-extra_sounds_version:
- @echo $(EXTRA_SOUNDS_VERSION)
diff --git a/1.4/sounds/sounds.xml b/1.4/sounds/sounds.xml
deleted file mode 100644
index 4ba16e092..000000000
--- a/1.4/sounds/sounds.xml
+++ /dev/null
@@ -1,68 +0,0 @@
- <category name="MENUSELECT_CORE_SOUNDS" displayname="Core Sound Packages" positive_output="yes">
- <member name="CORE-SOUNDS-EN-WAV" displayname="English, WAV format">
- </member>
- <member name="CORE-SOUNDS-EN-ULAW" displayname="English, mu-Law format">
- </member>
- <member name="CORE-SOUNDS-EN-ALAW" displayname="English, a-Law format">
- </member>
- <member name="CORE-SOUNDS-EN-GSM" displayname="English, GSM format" >
- <defaultenabled>yes</defaultenabled>
- </member>
- <member name="CORE-SOUNDS-EN-G729" displayname="English, G.729 format">
- </member>
- <member name="CORE-SOUNDS-EN-G722" displayname="English, G.722 format">
- </member>
- <member name="CORE-SOUNDS-ES-WAV" displayname="Spanish, WAV format">
- </member>
- <member name="CORE-SOUNDS-ES-ULAW" displayname="Spanish, mu-Law format">
- </member>
- <member name="CORE-SOUNDS-ES-ALAW" displayname="Spanish, a-Law format">
- </member>
- <member name="CORE-SOUNDS-ES-GSM" displayname="Spanish, GSM format">
- </member>
- <member name="CORE-SOUNDS-ES-G729" displayname="Spanish, G.729 format">
- </member>
- <member name="CORE-SOUNDS-ES-G722" displayname="Spanish, G.722 format">
- </member>
- <member name="CORE-SOUNDS-FR-WAV" displayname="French, WAV format">
- </member>
- <member name="CORE-SOUNDS-FR-ULAW" displayname="French, mu-Law format">
- </member>
- <member name="CORE-SOUNDS-FR-ALAW" displayname="French, a-Law format">
- </member>
- <member name="CORE-SOUNDS-FR-GSM" displayname="French, GSM format">
- </member>
- <member name="CORE-SOUNDS-FR-G729" displayname="French, G.729 format">
- </member>
- <member name="CORE-SOUNDS-FR-G722" displayname="French, G.722 format">
- </member>
- </category>
- <category name="MENUSELECT_MOH" displayname="Music On Hold File Packages" positive_output="yes">
- <member name="MOH-FREEPLAY-WAV" displayname="FreePlay Music On Hold Files, WAV format" >
- <defaultenabled>yes</defaultenabled>
- </member>
- <member name="MOH-FREEPLAY-ULAW" displayname="FreePlay Music On Hold Files, mu-Law format" >
- </member>
- <member name="MOH-FREEPLAY-ALAW" displayname="FreePlay Music On Hold Files, a-Law format" >
- </member>
- <member name="MOH-FREEPLAY-GSM" displayname="FreePlay Music On Hold Files, GSM format" >
- </member>
- <member name="MOH-FREEPLAY-G729" displayname="FreePlay Music On Hold Files, G.729 format" >
- </member>
- <member name="MOH-FREEPLAY-G722" displayname="FreePlay Music On Hold Files, G.722 format" >
- </member>
- </category>
- <category name="MENUSELECT_EXTRA_SOUNDS" displayname="Extras Sound Packages" positive_output="yes">
- <member name="EXTRA-SOUNDS-EN-WAV" displayname="English, WAV format">
- </member>
- <member name="EXTRA-SOUNDS-EN-ULAW" displayname="English, mu-Law format">
- </member>
- <member name="EXTRA-SOUNDS-EN-ALAW" displayname="English, a-Law format">
- </member>
- <member name="EXTRA-SOUNDS-EN-GSM" displayname="English, GSM format" >
- </member>
- <member name="EXTRA-SOUNDS-EN-G729" displayname="English, G.729 format">
- </member>
- <member name="EXTRA-SOUNDS-EN-G722" displayname="English, G.722 format">
- </member>
- </category>
diff --git a/1.4/static-http/ajamdemo.html b/1.4/static-http/ajamdemo.html
deleted file mode 100644
index 607a2cfbe..000000000
--- a/1.4/static-http/ajamdemo.html
+++ /dev/null
@@ -1,219 +0,0 @@
-<script src="prototype.js"></script>
-<script src="astman.js"></script>
-<link href="astman.css" media="all" rel="Stylesheet" type="text/css" />
-
-<script>
- var logins = new Object;
- var logoffs = new Object;
- var channels = new Object;
- var pongs = new Object;
- var loggedon = -1;
- var selectedchan = null;
- var hungupchan = "";
- var transferedchan = "";
-
- var demo = new Object;
-
- function loggedOn() {
- if (loggedon == 1)
- return;
- loggedon = 1;
- updateButtons();
- $('statusbar').innerHTML = "<i>Retrieving channel status...</i>";
- astmanEngine.pollEvents();
- astmanEngine.sendRequest('action=status', demo.channels);
- }
-
- function clearChannelList() {
- $('channellist').innerHTML = "<i class='light'>Not connected</i>";
- }
-
- function loggedOff() {
- if (loggedon == 0)
- return;
- loggedon = 0;
- selectedchan = null;
- updateButtons();
- astmanEngine.channelClear();
- clearChannelList();
- }
-
- function updateButtons()
- {
- if ($(selectedchan)) {
- $('transfer').disabled = 0;
- $('hangup').disabled = 0;
- } else {
- $('transfer').disabled = 1;
- $('hangup').disabled = 1;
- selectedchan = null;
- }
- if (loggedon) {
- $('username').disabled = 1;
- $('secret').disabled = 1;
- $('logoff').disabled = 0;
- $('login').disabled = 1;
- $('refresh').disabled = 0;
- } else {
- $('username').disabled = 0;
- $('secret').disabled = 0;
- $('logoff').disabled = 1;
- $('login').disabled = 0;
- $('refresh').disabled = 1;
- }
- }
-
- demo.channelCallback = function(target) {
- selectedchan = target;
- updateButtons();
- }
-
- demo.channels = function(msgs) {
- resp = msgs[0].headers['response'];
- if (resp == "Success") {
- loggedOn();
- } else
- loggedOff();
-
- for (i=1;i<msgs.length - 1;i++)
- astmanEngine.channelUpdate(msgs[i]);
- $('channellist').innerHTML = astmanEngine.channelTable(demo.channelCallback);
- $('statusbar').innerHTML = "Ready";
- }
-
- demo.logins = function(msgs) {
- $('statusbar').innerHTML = msgs[0].headers['message'];
- resp = msgs[0].headers['response'];
- if (resp == "Success")
- loggedOn();
- else
- loggedOff();
- };
-
-
- demo.logoffs = function(msgs) {
- $('statusbar').innerHTML = msgs[0].headers['message'];
- loggedOff();
- };
-
- demo.hungup = function(msgs) {
- $('statusbar').innerHTML = "Hungup " + hungupchan;
- }
-
- demo.transferred = function(msgs) {
- $('statusbar').innerHTML = "Transferred " + transferredchan;
- }
-
- function doHangup() {
- hungupchan = selectedchan;
- astmanEngine.sendRequest('action=hangup&channel=' + selectedchan, demo.hungup);
- }
-
- function doStatus() {
- $('statusbar').innerHTML = "<i>Updating channel status...</i>";
- astmanEngine.channelClear();
- astmanEngine.sendRequest('action=status', demo.channels);
- }
-
- function doLogin() {
- $('statusbar').innerHTML = "<i>Logging in...</i>";
- astmanEngine.sendRequest('action=login&username=' + $('username').value + "&secret=" + $('secret').value, demo.logins);
- }
-
- function doTransfer() {
- var channel = astmanEngine.channelInfo(selectedchan);
- var exten = prompt("Enter new extension for " + selectedchan);
- var altchan;
- if (exten) {
- if (channel.link) {
- if (confirm("Transfer " + channel.link + " too?"))
- altchan = channel.link;
- }
- if (altchan) {
- transferredchan = selectedchan + " and " + altchan + " to " + exten;
- astmanEngine.sendRequest('action=redirect&channel=' + selectedchan + "&priority=1&extrachannel=" + altchan + "&exten=" + exten, demo.transferred);
- } else {
- transferredchan = selectedchan + " to " + exten;
- astmanEngine.sendRequest('action=redirect&channel=' + selectedchan + "&priority=1&exten=" + exten, demo.transferred);
- }
- }
- }
-
- function doLogoff() {
- $('statusbar').innerHTML = "<i>Logging off...</i>";
- astmanEngine.sendRequest('action=logoff', demo.logoffs);
- }
-
- demo.pongs = function(msgs) {
- resp = msgs[0].headers['response'];
- if (resp == "Pong") {
- $('statusbar').innerHTML = "<i>Already connected...</i>";
- loggedOn();
- } else {
- $('statusbar').innerHTML = "<i>Please login...</i>";
- loggedOff();
- }
- }
-
- demo.eventcb = function(msgs) {
- var x;
- if (loggedon) {
- for (i=1;i<msgs.length - 1;i++) {
- astmanEngine.channelUpdate(msgs[i]);
- }
- $('channellist').innerHTML = astmanEngine.channelTable(demo.channelCallback);
- astmanEngine.pollEvents();
- }
- updateButtons();
- }
-
- function localajaminit() {
- astmanEngine.setURL('../rawman');
- astmanEngine.setEventCallback(demo.eventcb);
- //astmanEngine.setDebug($('ditto'));
- clearChannelList();
- astmanEngine.sendRequest('action=ping', demo.pongs);
- }
-</script>
-
-<title>Asterisk&trade; AJAM Demo</title>
-<body onload="localajaminit()">
-<table align="center" width=600>
-<tr valign="top"><td>
-<table align="left">
-<tr><td colspan="2"><h2>Asterisk&trade; AJAM Demo</h2></td>
-<tr><td>Username:</td><td><input id="username"></td></tr>
-<tr><td>Secret:</td><td><input type="password" id="secret"></td></tr>
- <tr><td colspan=2 align="center">
- <div id="statusbar">
- <span style="margin-left: 4px;font-weight:bold">&nbsp;</span>
- </div>
- </td></tr>
-
- <tr><td><input type="submit" id="login" value="Login" onClick="doLogin()"></td>
- <td><input type="submit" id="logoff" value="Logoff" disabled=1 onClick="doLogoff()"></td></tr>
-</table>
-</td><td valign='bottom'>
-<table>
-<div style="margin-left:10;margin-right:50;margin-top:10;margin-bottom:20">
-<i>This is a demo of the Asynchronous Javascript Asterisk Manager interface. You can login with a
-valid, appropriately permissioned manager username and secret.</i>
-</div>
-<tr>
- <td><input type="submit" onClick="doStatus()" id="refresh" value="Refresh"></td>
- <td><input type="submit" onClick="doTransfer()" id="transfer" value="Transfer..."></td>
- <td><input type="submit" onClick="doHangup()" id="hangup" value="Hangup"></td>
-</tr>
-</table>
-</td></tr>
-<tr><td colspan=2>
- <div id="channellist" class="chanlist">
- </div>
- </td></tr>
-<tr><td align="center" colspan=2>
- <font size=-1><i>
- Copyright (C) 2006 Digium, Inc. Asterisk and Digium are trademarks of Digium, Inc.
- </i></font>
-</td></tr>
-</table>
-</body>
diff --git a/1.4/static-http/astman.css b/1.4/static-http/astman.css
deleted file mode 100644
index fbf2b2cf9..000000000
--- a/1.4/static-http/astman.css
+++ /dev/null
@@ -1,34 +0,0 @@
-.chanlist {
- border : 1px solid #1f669b;
- height : 150px;
- overflow : auto;
- background-color : #f1f1f1;
- width : 600;
-}
-
-.chantable {
- border : 0px;
- background-color : #f1f1f1;
- width : 100%;
-}
-
-.labels {
- background-color : #000000;
- color : #ffffff;
-}
-
-.chanlisteven {
- background-color : #fff8e4;
-}
-
-.chanlistodd {
- background-color : #f0f5ff;
-}
-
-.chanlistselected {
- background-color : #ffb13d;
-}
-
-.light {
- color : #717171;
-}
diff --git a/1.4/static-http/astman.js b/1.4/static-http/astman.js
deleted file mode 100644
index 81f896c1c..000000000
--- a/1.4/static-http/astman.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Javascript routines or accessing manager routines over HTTP.
- *
- * 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.
- *
- */
-
-
-function Astman() {
- var me = this;
- var channels = new Array;
- var lastselect;
- var selecttarget;
- this.setURL = function(url) {
- this.url = url;
- };
- this.setEventCallback = function(callback) {
- this.eventcallback = callback;
- };
- this.setDebug = function(debug) {
- this.debug = debug;
- };
- this.clickChannel = function(ev) {
- var target = ev.target;
- // XXX This is icky, we statically use astmanEngine to call the callback XXX
- if (me.selecttarget)
- me.restoreTarget(me.selecttarget);
- while(!target.id || !target.id.length)
- target=target.parentNode;
- me.selecttarget = target.id;
- target.className = "chanlistselected";
- me.chancallback(target.id);
- };
- this.restoreTarget = function(targetname) {
- var other;
- target = $(targetname);
- if (!target)
- return;
- if (target.previousSibling) {
- other = target.previousSibling.previousSibling.className;
- } else if (target.nextSibling) {
- other = target.nextSibling.nextSibling.className;
- }
- if (other) {
- if (other == "chanlisteven")
- target.className = "chanlistodd";
- else
- target.className = "chanlisteven";
- } else
- target.className = "chanlistodd";
- };
- this.channelUpdate = function(msg, channame) {
- var fields = new Array("callerid", "calleridname", "context", "extension", "priority", "account", "state", "link", "uniqueid" );
-
- if (!channame || !channame.length)
- channame = msg.headers['channel'];
-
- if (!channels[channame])
- channels[channame] = new Array();
-
- if (msg.headers.event) {
- if (msg.headers.event == "Hangup") {
- delete channels[channame];
- } else if (msg.headers.event == "Link") {
- var chan1 = msg.headers.channel1;
- var chan2 = msg.headers.channel2;
- if (chan1 && channels[chan1])
- channels[chan1].link = chan2;
- if (chan2 && channels[chan2])
- channels[chan2].link = chan1;
- } else if (msg.headers.event == "Unlink") {
- var chan1 = msg.headers.channel1;
- var chan2 = msg.headers.channel2;
- if (chan1 && channels[chan1])
- delete channels[chan1].link;
- if (chan2 && channels[chan2])
- delete channels[chan2].link;
- } else if (msg.headers.event == "Rename") {
- var oldname = msg.headers.oldname;
- var newname = msg.headers.newname;
- if (oldname && channels[oldname]) {
- channels[newname] = channels[oldname];
- delete channels[oldname];
- }
- } else {
- channels[channame]['channel'] = channame;
- for (x=0;x<fields.length;x++) {
- if (msg.headers[fields[x]])
- channels[channame][fields[x]] = msg.headers[fields[x]];
- }
- }
- } else {
- channels[channame]['channel'] = channame;
- for (x=0;x<fields.length;x++) {
- if (msg.headers[fields[x]])
- channels[channame][fields[x]] = msg.headers[fields[x]];
- }
- }
- };
- this.channelClear = function() {
- channels = new Array;
- }
- this.channelInfo = function(channame) {
- return channels[channame];
- };
- this.channelTable = function(callback) {
- var s, x;
- var cclass, count=0;
- var found = 0;
- var foundactive = 0;
- var fieldlist = new Array("channel", "callerid", "calleridname", "context", "extension", "priority");
-
- me.chancallback = callback;
- s = "<table class='chantable' align='center'>\n";
- s = s + "\t<tr class='labels' id='labels'><td>Channel</td><td>State</td><td>Caller</td><td>Location</td><td>Link</td></tr>";
- count=0;
- for (x in channels) {
- if (channels[x].channel) {
- if (count % 2)
- cclass = "chanlistodd";
- else
- cclass = "chanlisteven";
- if (me.selecttarget && (me.selecttarget == x)) {
- cclass = "chanlistselected";
- foundactive = 1;
- }
- count++;
- s = s + "\t<tr class='" + cclass + "' id='" + channels[x].channel + "' onClick='astmanEngine.clickChannel(event)'>";
- s = s + "<td>" + channels[x].channel + "</td>";
- if (channels[x].state)
- s = s + "<td>" + channels[x].state + "</td>";
- else
- s = s + "<td><i class='light'>unknown</i></td>";
- if (channels[x].calleridname && channels[x].callerid && channels[x].calleridname != "<unknown>") {
- cid = channels[x].calleridname.escapeHTML() + " &lt;" + channels[x].callerid.escapeHTML() + "&gt;";
- } else if (channels[x].calleridname && (channels[x].calleridname != "<unknown>")) {
- cid = channels[x].calleridname.escapeHTML();
- } else if (channels[x].callerid) {
- cid = channels[x].callerid.escapeHTML();
- } else {
- cid = "<i class='light'>Unknown</i>";
- }
- s = s + "<td>" + cid + "</td>";
- if (channels[x].extension) {
- s = s + "<td>" + channels[x].extension + "@" + channels[x].context + ":" + channels[x].priority + "</td>";
- } else {
- s = s + "<td><i class='light'>None</i></td>";
- }
- if (channels[x].link) {
- s = s + "<td>" + channels[x].link + "</td>";
- } else {
- s = s + "<td><i class='light'>None</i></td>";
- }
- s = s + "</tr>\n";
- found++;
- }
- }
- if (!found)
- s += "<tr><td colspan=" + fieldlist.length + "><i class='light'>No active channels</i></td>\n";
- s += "</table>\n";
- if (!foundactive) {
- me.selecttarget = null;
- }
- return s;
- };
- this.parseResponse = function(t, callback) {
- var msgs = new Array();
- var inmsg = 0;
- var msgnum = 0;
- var x,y;
- var s = t.responseText;
- var allheaders = s.split('\r\n');
- if (me.debug)
- me.debug.value = "\n";
- for (x=0;x<allheaders.length;x++) {
- if (allheaders[x].length) {
- var fields = allheaders[x].split(': ');
- if (!inmsg) {
- msgs[msgnum] = new Object();
- msgs[msgnum].headers = new Array();
- msgs[msgnum].names = new Array();
- y=0;
- }
- msgs[msgnum].headers[fields[0].toLowerCase()] = fields[1];
- msgs[msgnum].names[y++] = fields[0].toLowerCase();
- if (me.debug)
- me.debug.value = me.debug.value + "field " + fields[0] + "/" + fields[1] + "\n";
- inmsg=1;
- } else {
- if (inmsg) {
- if (me.debug)
- me.debug.value = me.debug.value + " new message\n";
- inmsg = 0;
- msgnum++;
- }
- }
- }
- if (me.debug) {
- me.debug.value = me.debug.value + "msgnum is " + msgnum + " and array length is " + msgs.length + "\n";
- me.debug.value = me.debug.value + "length is " + msgs.length + "\n";
- var x, y;
- for (x=0;x<msgs.length;x++) {
- for (y=0;y<msgs[x].names.length;y++) {
- me.debug.value = me.debug.value + "msg "+ (x + 1) + "/" + msgs[x].names[y] + "/" + msgs[x].headers[msgs[x].names[y]] + "\n";
- }
- }
- }
- callback(msgs);
- };
- this.managerResponse = function(t) {
- me.parseResponse(t, me.callback);
- };
- this.doEvents = function(msgs) {
- me.eventcallback(msgs);
- };
- this.eventResponse = function(t) {
- me.parseResponse(t, me.doEvents);
- };
- this.sendRequest = function(request, callback) {
- var tmp;
- var opt = {
- method: 'get',
- asynchronous: true,
- onSuccess: this.managerResponse,
- onFailure: function(t) {
- alert("Error: " + t.status + ": " + t.statusText);
- },
- };
- me.callback = callback;
- opt.parameters = request;
- tmp = new Ajax.Request(this.url, opt);
- };
- this.pollEvents = function() {
- var tmp;
- var opt = {
- method: 'get',
- asynchronous: true,
- onSuccess: this.eventResponse,
- onFailure: function(t) {
- alert("Event Error: " + t.status + ": " + t.statusText);
- },
- };
- opt.parameters="action=waitevent";
- tmp = new Ajax.Request(this.url, opt);
- };
-};
-
-astmanEngine = new Astman();
diff --git a/1.4/static-http/prototype.js b/1.4/static-http/prototype.js
deleted file mode 100644
index 0e85338ba..000000000
--- a/1.4/static-http/prototype.js
+++ /dev/null
@@ -1,1781 +0,0 @@
-/* Prototype JavaScript framework, version 1.4.0
- * (c) 2005 Sam Stephenson <sam@conio.net>
- *
- * Prototype is freely distributable under the terms of an MIT-style license.
- * For details, see the Prototype web site: http://prototype.conio.net/
- *
-/*--------------------------------------------------------------------------*/
-
-var Prototype = {
- Version: '1.4.0',
- ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
-
- emptyFunction: function() {},
- K: function(x) {return x}
-}
-
-var Class = {
- create: function() {
- return function() {
- this.initialize.apply(this, arguments);
- }
- }
-}
-
-var Abstract = new Object();
-
-Object.extend = function(destination, source) {
- for (property in source) {
- destination[property] = source[property];
- }
- return destination;
-}
-
-Object.inspect = function(object) {
- try {
- if (object == undefined) return 'undefined';
- if (object == null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- } catch (e) {
- if (e instanceof RangeError) return '...';
- throw e;
- }
-}
-
-Function.prototype.bind = function() {
- var __method = this, args = $A(arguments), object = args.shift();
- return function() {
- return __method.apply(object, args.concat($A(arguments)));
- }
-}
-
-Function.prototype.bindAsEventListener = function(object) {
- var __method = this;
- return function(event) {
- return __method.call(object, event || window.event);
- }
-}
-
-Object.extend(Number.prototype, {
- toColorPart: function() {
- var digits = this.toString(16);
- if (this < 16) return '0' + digits;
- return digits;
- },
-
- succ: function() {
- return this + 1;
- },
-
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
- }
-});
-
-var Try = {
- these: function() {
- var returnValue;
-
- for (var i = 0; i < arguments.length; i++) {
- var lambda = arguments[i];
- try {
- returnValue = lambda();
- break;
- } catch (e) {}
- }
-
- return returnValue;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
- initialize: function(callback, frequency) {
- this.callback = callback;
- this.frequency = frequency;
- this.currentlyExecuting = false;
-
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- if (!this.currentlyExecuting) {
- try {
- this.currentlyExecuting = true;
- this.callback();
- } finally {
- this.currentlyExecuting = false;
- }
- }
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-function $() {
- var elements = new Array();
-
- for (var i = 0; i < arguments.length; i++) {
- var element = arguments[i];
- if (typeof element == 'string')
- element = document.getElementById(element);
-
- if (arguments.length == 1)
- return element;
-
- elements.push(element);
- }
-
- return elements;
-}
-Object.extend(String.prototype, {
- stripTags: function() {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
-
- stripScripts: function() {
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
-
- extractScripts: function() {
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
- return (this.match(matchAll) || []).map(function(scriptTag) {
- return (scriptTag.match(matchOne) || ['', ''])[1];
- });
- },
-
- evalScripts: function() {
- return this.extractScripts().map(eval);
- },
-
- escapeHTML: function() {
- var div = document.createElement('div');
- var text = document.createTextNode(this);
- div.appendChild(text);
- return div.innerHTML;
- },
-
- unescapeHTML: function() {
- var div = document.createElement('div');
- div.innerHTML = this.stripTags();
- return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
- },
-
- toQueryParams: function() {
- var pairs = this.match(/^\??(.*)$/)[1].split('&');
- return pairs.inject({}, function(params, pairString) {
- var pair = pairString.split('=');
- params[pair[0]] = pair[1];
- return params;
- });
- },
-
- toArray: function() {
- return this.split('');
- },
-
- camelize: function() {
- var oStringList = this.split('-');
- if (oStringList.length == 1) return oStringList[0];
-
- var camelizedString = this.indexOf('-') == 0
- ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
- : oStringList[0];
-
- for (var i = 1, len = oStringList.length; i < len; i++) {
- var s = oStringList[i];
- camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
- }
-
- return camelizedString;
- },
-
- inspect: function() {
- return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
- }
-});
-
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-var $break = new Object();
-var $continue = new Object();
-
-var Enumerable = {
- each: function(iterator) {
- var index = 0;
- try {
- this._each(function(value) {
- try {
- iterator(value, index++);
- } catch (e) {
- if (e != $continue) throw e;
- }
- });
- } catch (e) {
- if (e != $break) throw e;
- }
- },
-
- all: function(iterator) {
- var result = true;
- this.each(function(value, index) {
- result = result && !!(iterator || Prototype.K)(value, index);
- if (!result) throw $break;
- });
- return result;
- },
-
- any: function(iterator) {
- var result = true;
- this.each(function(value, index) {
- if (result = !!(iterator || Prototype.K)(value, index))
- throw $break;
- });
- return result;
- },
-
- collect: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- results.push(iterator(value, index));
- });
- return results;
- },
-
- detect: function (iterator) {
- var result;
- this.each(function(value, index) {
- if (iterator(value, index)) {
- result = value;
- throw $break;
- }
- });
- return result;
- },
-
- findAll: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- if (iterator(value, index))
- results.push(value);
- });
- return results;
- },
-
- grep: function(pattern, iterator) {
- var results = [];
- this.each(function(value, index) {
- var stringValue = value.toString();
- if (stringValue.match(pattern))
- results.push((iterator || Prototype.K)(value, index));
- })
- return results;
- },
-
- include: function(object) {
- var found = false;
- this.each(function(value) {
- if (value == object) {
- found = true;
- throw $break;
- }
- });
- return found;
- },
-
- inject: function(memo, iterator) {
- this.each(function(value, index) {
- memo = iterator(memo, value, index);
- });
- return memo;
- },
-
- invoke: function(method) {
- var args = $A(arguments).slice(1);
- return this.collect(function(value) {
- return value[method].apply(value, args);
- });
- },
-
- max: function(iterator) {
- var result;
- this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (value >= (result || value))
- result = value;
- });
- return result;
- },
-
- min: function(iterator) {
- var result;
- this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (value <= (result || value))
- result = value;
- });
- return result;
- },
-
- partition: function(iterator) {
- var trues = [], falses = [];
- this.each(function(value, index) {
- ((iterator || Prototype.K)(value, index) ?
- trues : falses).push(value);
- });
- return [trues, falses];
- },
-
- pluck: function(property) {
- var results = [];
- this.each(function(value, index) {
- results.push(value[property]);
- });
- return results;
- },
-
- reject: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- if (!iterator(value, index))
- results.push(value);
- });
- return results;
- },
-
- sortBy: function(iterator) {
- return this.collect(function(value, index) {
- return {value: value, criteria: iterator(value, index)};
- }).sort(function(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }).pluck('value');
- },
-
- toArray: function() {
- return this.collect(Prototype.K);
- },
-
- zip: function() {
- var iterator = Prototype.K, args = $A(arguments);
- if (typeof args.last() == 'function')
- iterator = args.pop();
-
- var collections = [this].concat(args).map($A);
- return this.map(function(value, index) {
- iterator(value = collections.pluck(index));
- return value;
- });
- },
-
- inspect: function() {
- return '#<Enumerable:' + this.toArray().inspect() + '>';
- }
-}
-
-Object.extend(Enumerable, {
- map: Enumerable.collect,
- find: Enumerable.detect,
- select: Enumerable.findAll,
- member: Enumerable.include,
- entries: Enumerable.toArray
-});
-var $A = Array.from = function(iterable) {
- if (!iterable) return [];
- if (iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0; i < iterable.length; i++)
- results.push(iterable[i]);
- return results;
- }
-}
-
-Object.extend(Array.prototype, Enumerable);
-
-Array.prototype._reverse = Array.prototype.reverse;
-
-Object.extend(Array.prototype, {
- _each: function(iterator) {
- for (var i = 0; i < this.length; i++)
- iterator(this[i]);
- },
-
- clear: function() {
- this.length = 0;
- return this;
- },
-
- first: function() {
- return this[0];
- },
-
- last: function() {
- return this[this.length - 1];
- },
-
- compact: function() {
- return this.select(function(value) {
- return value != undefined || value != null;
- });
- },
-
- flatten: function() {
- return this.inject([], function(array, value) {
- return array.concat(value.constructor == Array ?
- value.flatten() : [value]);
- });
- },
-
- without: function() {
- var values = $A(arguments);
- return this.select(function(value) {
- return !values.include(value);
- });
- },
-
- indexOf: function(object) {
- for (var i = 0; i < this.length; i++)
- if (this[i] == object) return i;
- return -1;
- },
-
- reverse: function(inline) {
- return (inline !== false ? this : this.toArray())._reverse();
- },
-
- shift: function() {
- var result = this[0];
- for (var i = 0; i < this.length - 1; i++)
- this[i] = this[i + 1];
- this.length--;
- return result;
- },
-
- inspect: function() {
- return '[' + this.map(Object.inspect).join(', ') + ']';
- }
-});
-var Hash = {
- _each: function(iterator) {
- for (key in this) {
- var value = this[key];
- if (typeof value == 'function') continue;
-
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
-
- keys: function() {
- return this.pluck('key');
- },
-
- values: function() {
- return this.pluck('value');
- },
-
- merge: function(hash) {
- return $H(hash).inject($H(this), function(mergedHash, pair) {
- mergedHash[pair.key] = pair.value;
- return mergedHash;
- });
- },
-
- toQueryString: function() {
- return this.map(function(pair) {
- return pair.map(encodeURIComponent).join('=');
- }).join('&');
- },
-
- inspect: function() {
- return '#<Hash:{' + this.map(function(pair) {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- }
-}
-
-function $H(object) {
- var hash = Object.extend({}, object || {});
- Object.extend(hash, Enumerable);
- Object.extend(hash, Hash);
- return hash;
-}
-ObjectRange = Class.create();
-Object.extend(ObjectRange.prototype, Enumerable);
-Object.extend(ObjectRange.prototype, {
- initialize: function(start, end, exclusive) {
- this.start = start;
- this.end = end;
- this.exclusive = exclusive;
- },
-
- _each: function(iterator) {
- var value = this.start;
- do {
- iterator(value);
- value = value.succ();
- } while (this.include(value));
- },
-
- include: function(value) {
- if (value < this.start)
- return false;
- if (this.exclusive)
- return value < this.end;
- return value <= this.end;
- }
-});
-
-var $R = function(start, end, exclusive) {
- return new ObjectRange(start, end, exclusive);
-}
-
-var Ajax = {
- getTransport: function() {
- return Try.these(
- function() {return new ActiveXObject('Msxml2.XMLHTTP')},
- function() {return new ActiveXObject('Microsoft.XMLHTTP')},
- function() {return new XMLHttpRequest()}
- ) || false;
- },
-
- activeRequestCount: 0
-}
-
-Ajax.Responders = {
- responders: [],
-
- _each: function(iterator) {
- this.responders._each(iterator);
- },
-
- register: function(responderToAdd) {
- if (!this.include(responderToAdd))
- this.responders.push(responderToAdd);
- },
-
- unregister: function(responderToRemove) {
- this.responders = this.responders.without(responderToRemove);
- },
-
- dispatch: function(callback, request, transport, json) {
- this.each(function(responder) {
- if (responder[callback] && typeof responder[callback] == 'function') {
- try {
- responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {}
- }
- });
- }
-};
-
-Object.extend(Ajax.Responders, Enumerable);
-
-Ajax.Responders.register({
- onCreate: function() {
- Ajax.activeRequestCount++;
- },
-
- onComplete: function() {
- Ajax.activeRequestCount--;
- }
-});
-
-Ajax.Base = function() {};
-Ajax.Base.prototype = {
- setOptions: function(options) {
- this.options = {
- method: 'post',
- asynchronous: true,
- parameters: ''
- }
- Object.extend(this.options, options || {});
- },
-
- responseIsSuccess: function() {
- return this.transport.status == undefined
- || this.transport.status == 0
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- responseIsFailure: function() {
- return !this.responseIsSuccess();
- }
-}
-
-Ajax.Request = Class.create();
-Ajax.Request.Events =
- ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
- initialize: function(url, options) {
- this.transport = Ajax.getTransport();
- this.setOptions(options);
- this.request(url);
- },
-
- request: function(url) {
- var parameters = this.options.parameters || '';
- if (parameters.length > 0) parameters += '&_=';
-
- try {
- this.url = url;
- if (this.options.method == 'get' && parameters.length > 0)
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
-
- Ajax.Responders.dispatch('onCreate', this, this.transport);
-
- this.transport.open(this.options.method, this.url,
- this.options.asynchronous);
-
- if (this.options.asynchronous) {
- this.transport.onreadystatechange = this.onStateChange.bind(this);
- setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
- }
-
- this.setRequestHeaders();
-
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
-
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
- setRequestHeaders: function() {
- var requestHeaders =
- ['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version];
-
- if (this.options.method == 'post') {
- requestHeaders.push('Content-type',
- 'application/x-www-form-urlencoded');
-
- /* Force "Connection: close" for Mozilla browsers to work around
- * a bug where XMLHttpReqeuest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
- */
- if (this.transport.overrideMimeType)
- requestHeaders.push('Connection', 'close');
- }
-
- if (this.options.requestHeaders)
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
-
- for (var i = 0; i < requestHeaders.length; i += 2)
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
- },
-
- onStateChange: function() {
- var readyState = this.transport.readyState;
- if (readyState != 1)
- this.respondToReadyState(this.transport.readyState);
- },
-
- header: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) {}
- },
-
- evalJSON: function() {
- try {
- return eval(this.header('X-JSON'));
- } catch (e) {}
- },
-
- evalResponse: function() {
- try {
- return eval(this.transport.responseText);
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
- respondToReadyState: function(readyState) {
- var event = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
- if (event == 'Complete') {
- try {
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- if ((this.header('Content-type') || '').match(/^text\/javascript/i))
- this.evalResponse();
- }
-
- try {
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete')
- this.transport.onreadystatechange = Prototype.emptyFunction;
- },
-
- dispatchException: function(exception) {
- (this.options.onException || Prototype.emptyFunction)(this, exception);
- Ajax.Responders.dispatch('onException', this, exception);
- }
-});
-
-Ajax.Updater = Class.create();
-
-Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
- initialize: function(container, url, options) {
- this.containers = {
- success: container.success ? $(container.success) : $(container),
- failure: container.failure ? $(container.failure) :
- (container.success ? null : $(container))
- }
-
- this.transport = Ajax.getTransport();
- this.setOptions(options);
-
- var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, object) {
- this.updateContent();
- onComplete(transport, object);
- }).bind(this);
-
- this.request(url);
- },
-
- updateContent: function() {
- var receiver = this.responseIsSuccess() ?
- this.containers.success : this.containers.failure;
- var response = this.transport.responseText;
-
- if (!this.options.evalScripts)
- response = response.stripScripts();
-
- if (receiver) {
- if (this.options.insertion) {
- new this.options.insertion(receiver, response);
- } else {
- Element.update(receiver, response);
- }
- }
-
- if (this.responseIsSuccess()) {
- if (this.onComplete)
- setTimeout(this.onComplete.bind(this), 10);
- }
- }
-});
-
-Ajax.PeriodicalUpdater = Class.create();
-Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
- initialize: function(container, url, options) {
- this.setOptions(options);
- this.onComplete = this.options.onComplete;
-
- this.frequency = (this.options.frequency || 2);
- this.decay = (this.options.decay || 1);
-
- this.updater = {};
- this.container = container;
- this.url = url;
-
- this.start();
- },
-
- start: function() {
- this.options.onComplete = this.updateComplete.bind(this);
- this.onTimerEvent();
- },
-
- stop: function() {
- this.updater.onComplete = undefined;
- clearTimeout(this.timer);
- (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
- },
-
- updateComplete: function(request) {
- if (this.options.decay) {
- this.decay = (request.responseText == this.lastText ?
- this.decay * this.options.decay : 1);
-
- this.lastText = request.responseText;
- }
- this.timer = setTimeout(this.onTimerEvent.bind(this),
- this.decay * this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- this.updater = new Ajax.Updater(this.container, this.url, this.options);
- }
-});
-document.getElementsByClassName = function(className, parentElement) {
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- return $A(children).inject([], function(elements, child) {
- if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- elements.push(child);
- return elements;
- });
-}
-
-/*--------------------------------------------------------------------------*/
-
-if (!window.Element) {
- var Element = new Object();
-}
-
-Object.extend(Element, {
- visible: function(element) {
- return $(element).style.display != 'none';
- },
-
- toggle: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- Element[Element.visible(element) ? 'hide' : 'show'](element);
- }
- },
-
- hide: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- element.style.display = 'none';
- }
- },
-
- show: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- element.style.display = '';
- }
- },
-
- remove: function(element) {
- element = $(element);
- element.parentNode.removeChild(element);
- },
-
- update: function(element, html) {
- $(element).innerHTML = html.stripScripts();
- setTimeout(function() {html.evalScripts()}, 10);
- },
-
- getHeight: function(element) {
- element = $(element);
- return element.offsetHeight;
- },
-
- classNames: function(element) {
- return new Element.ClassNames(element);
- },
-
- hasClassName: function(element, className) {
- if (!(element = $(element))) return;
- return Element.classNames(element).include(className);
- },
-
- addClassName: function(element, className) {
- if (!(element = $(element))) return;
- return Element.classNames(element).add(className);
- },
-
- removeClassName: function(element, className) {
- if (!(element = $(element))) return;
- return Element.classNames(element).remove(className);
- },
-
- // removes whitespace-only text node children
- cleanWhitespace: function(element) {
- element = $(element);
- for (var i = 0; i < element.childNodes.length; i++) {
- var node = element.childNodes[i];
- if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
- Element.remove(node);
- }
- },
-
- empty: function(element) {
- return $(element).innerHTML.match(/^\s*$/);
- },
-
- scrollTo: function(element) {
- element = $(element);
- var x = element.x ? element.x : element.offsetLeft,
- y = element.y ? element.y : element.offsetTop;
- window.scrollTo(x, y);
- },
-
- getStyle: function(element, style) {
- element = $(element);
- var value = element.style[style.camelize()];
- if (!value) {
- if (document.defaultView && document.defaultView.getComputedStyle) {
- var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css.getPropertyValue(style) : null;
- } else if (element.currentStyle) {
- value = element.currentStyle[style.camelize()];
- }
- }
-
- if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
- if (Element.getStyle(element, 'position') == 'static') value = 'auto';
-
- return value == 'auto' ? null : value;
- },
-
- setStyle: function(element, style) {
- element = $(element);
- for (name in style)
- element.style[name.camelize()] = style[name];
- },
-
- getDimensions: function(element) {
- element = $(element);
- if (Element.getStyle(element, 'display') != 'none')
- return {width: element.offsetWidth, height: element.offsetHeight};
-
- // All *Width and *Height properties give 0 on elements with display none,
- // so enable the element temporarily
- var els = element.style;
- var originalVisibility = els.visibility;
- var originalPosition = els.position;
- els.visibility = 'hidden';
- els.position = 'absolute';
- els.display = '';
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- els.display = 'none';
- els.position = originalPosition;
- els.visibility = originalVisibility;
- return {width: originalWidth, height: originalHeight};
- },
-
- makePositioned: function(element) {
- element = $(element);
- var pos = Element.getStyle(element, 'position');
- if (pos == 'static' || !pos) {
- element._madePositioned = true;
- element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context, when an
- // element is position relative but top and left have not been defined
- if (window.opera) {
- element.style.top = 0;
- element.style.left = 0;
- }
- }
- },
-
- undoPositioned: function(element) {
- element = $(element);
- if (element._madePositioned) {
- element._madePositioned = undefined;
- element.style.position =
- element.style.top =
- element.style.left =
- element.style.bottom =
- element.style.right = '';
- }
- },
-
- makeClipping: function(element) {
- element = $(element);
- if (element._overflow) return;
- element._overflow = element.style.overflow;
- if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
- element.style.overflow = 'hidden';
- },
-
- undoClipping: function(element) {
- element = $(element);
- if (element._overflow) return;
- element.style.overflow = element._overflow;
- element._overflow = undefined;
- }
-});
-
-var Toggle = new Object();
-Toggle.display = Element.toggle;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.Insertion = function(adjacency) {
- this.adjacency = adjacency;
-}
-
-Abstract.Insertion.prototype = {
- initialize: function(element, content) {
- this.element = $(element);
- this.content = content.stripScripts();
-
- if (this.adjacency && this.element.insertAdjacentHTML) {
- try {
- this.element.insertAdjacentHTML(this.adjacency, this.content);
- } catch (e) {
- if (this.element.tagName.toLowerCase() == 'tbody') {
- this.insertContent(this.contentFromAnonymousTable());
- } else {
- throw e;
- }
- }
- } else {
- this.range = this.element.ownerDocument.createRange();
- if (this.initializeRange) this.initializeRange();
- this.insertContent([this.range.createContextualFragment(this.content)]);
- }
-
- setTimeout(function() {content.evalScripts()}, 10);
- },
-
- contentFromAnonymousTable: function() {
- var div = document.createElement('div');
- div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
- },
-
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function(className) {
- this.element.className = className;
- },
-
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
- },
-
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
- },
-
- toString: function() {
- return this.toArray().join(' ');
- }
-}
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-var Field = {
- clear: function() {
- for (var i = 0; i < arguments.length; i++)
- $(arguments[i]).value = '';
- },
-
- focus: function(element) {
- $(element).focus();
- },
-
- present: function() {
- for (var i = 0; i < arguments.length; i++)
- if ($(arguments[i]).value == '') return false;
- return true;
- },
-
- select: function(element) {
- $(element).select();
- },
-
- activate: function(element) {
- element = $(element);
- element.focus();
- if (element.select)
- element.select();
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Form = {
- serialize: function(form) {
- var elements = Form.getElements($(form));
- var queryComponents = new Array();
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
- },
-
- getElements: function(form) {
- form = $(form);
- var elements = new Array();
-
- for (tagName in Form.Element.Serializers) {
- var tagElements = form.getElementsByTagName(tagName);
- for (var j = 0; j < tagElements.length; j++)
- elements.push(tagElements[j]);
- }
- return elements;
- },
-
- getInputs: function(form, typeName, name) {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if (!typeName && !name)
- return inputs;
-
- var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
- var input = inputs[i];
- if ((typeName && input.type != typeName) ||
- (name && input.name != name))
- continue;
- matchingInputs.push(input);
- }
-
- return matchingInputs;
- },
-
- disable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- element.blur();
- element.disabled = 'true';
- }
- },
-
- enable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- element.disabled = '';
- }
- },
-
- findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function(form) {
- Field.activate(Form.findFirstElement(form));
- },
-
- reset: function(form) {
- $(form).reset();
- }
-}
-
-Form.Element = {
- serialize: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter) {
- var key = encodeURIComponent(parameter[0]);
- if (key.length == 0) return;
-
- if (parameter[1].constructor != Array)
- parameter[1] = [parameter[1]];
-
- return parameter[1].map(function(value) {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
- }
- },
-
- getValue: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter)
- return parameter[1];
- }
-}
-
-Form.Element.Serializers = {
- input: function(element) {
- switch (element.type.toLowerCase()) {
- case 'submit':
- case 'hidden':
- case 'password':
- case 'text':
- return Form.Element.Serializers.textarea(element);
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- }
- return false;
- },
-
- inputSelector: function(element) {
- if (element.checked)
- return [element.name, element.value];
- },
-
- textarea: function(element) {
- return [element.name, element.value];
- },
-
- select: function(element) {
- return Form.Element.Serializers[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function(element) {
- var value = '', opt, index = element.selectedIndex;
- if (index >= 0) {
- opt = element.options[index];
- value = opt.value;
- if (!value && !('value' in opt))
- value = opt.text;
- }
- return [element.name, value];
- },
-
- selectMany: function(element) {
- var value = new Array();
- for (var i = 0; i < element.length; i++) {
- var opt = element.options[i];
- if (opt.selected) {
- var optValue = opt.value;
- if (!optValue && !('value' in opt))
- optValue = opt.text;
- value.push(optValue);
- }
- }
- return [element.name, value];
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
- initialize: function(element, callback) {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if (this.element.tagName.toLowerCase() == 'form')
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
- },
-
- registerCallback: function(element) {
- if (element.type) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- case 'password':
- case 'text':
- case 'textarea':
- case 'select-one':
- case 'select-multiple':
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-if (!window.Event) {
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
-
- element: function(event) {
- return event.target || event.srcElement;
- },
-
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
-
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.attachEvent))
- name = 'keydown';
-
- this._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.detachEvent))
- name = 'keydown';
-
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- element.detachEvent('on' + name, observer);
- }
- }
-});
-
-/* prevent memory leaks in IE */
-Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
- prepare: function() {
- this.deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- this.deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- },
-
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
- // caches x/y coordinate pair to use with overlap
- within: function(element, x, y) {
- if (this.includeScrollOffsets)
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] &&
- y < this.offset[1] + element.offsetHeight &&
- x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] &&
- this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] &&
- this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
- // within must be called directly before
- overlap: function(mode, element) {
- if (!mode) return 0;
- if (mode == 'vertical')
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- if (mode == 'horizontal')
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- },
-
- clone: function(source, target) {
- source = $(source);
- target = $(target);
- target.style.position = 'absolute';
- var offsets = this.cumulativeOffset(source);
- target.style.top = offsets[1] + 'px';
- target.style.left = offsets[0] + 'px';
- target.style.width = source.offsetWidth + 'px';
- target.style.height = source.offsetHeight + 'px';
- },
-
- page: function(forElement) {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent==document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- } while (element = element.parentNode);
-
- return [valueL, valueT];
- },
-
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';;
- element.style.left = left + 'px';;
- element.style.width = width + 'px';;
- element.style.height = height + 'px';;
- },
-
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return [valueL, valueT];
- }
-} \ No newline at end of file
diff --git a/1.4/utils/Makefile b/1.4/utils/Makefile
deleted file mode 100644
index 07896260f..000000000
--- a/1.4/utils/Makefile
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Various utilities
-#
-# Copyright (C) 1999-2006, Digium
-#
-# Mark Spencer <markster@digium.com>
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts
-
-.PHONY: clean all uninstall
-
-# to get check_expr, add it to the ALL_UTILS list
-ALL_UTILS:=astman smsq stereorize streamplayer aelparse muted
-UTILS:=$(ALL_UTILS)
-
-include $(ASTTOPDIR)/Makefile.rules
-
-ifeq ($(OSARCH),SunOS)
- LIBS+=-lsocket -lnsl
- UTILS:=$(filter-out muted,$(UTILS))
-endif
-
-ifeq ($(OSARCH),OpenBSD)
- UTILS:=$(filter-out muted,$(UTILS))
-endif
-
-ifeq ($(POPT_LIB),)
- UTILS:=$(filter-out smsq,$(UTILS))
-endif
-
-ifeq ($(NEWT_LIB),)
- UTILS:=$(filter-out astman,$(UTILS))
-endif
-
-ifneq ($(filter pbx_ael,$(MENUSELECT_PBX)),)
- UTILS:=$(filter-out aelparse,$(UTILS))
-endif
-
-all: $(UTILS)
-
-install:
- for x in $(UTILS); do \
- if [ "$$x" != "none" ]; then \
- $(INSTALL) -m 755 $$x $(DESTDIR)$(ASTSBINDIR)/$$x; \
- fi; \
- done
-
-uninstall:
- for x in $(ALL_UTILS); do rm -f $$x $(DESTDIR)$(ASTSBINDIR)/$$x; done
-
-clean:
- rm -f *.o $(ALL_UTILS) check_expr *.s *.i
- rm -f .*.o.d .*.oo.d
- rm -f md5.c strcompat.c ast_expr2.c ast_expr2f.c pbx_ael.c
- rm -f aelparse.c aelbison.c
-
-md5.c: ../main/md5.c
- @cp $< $@
-
-astman: astman.o md5.o
-astman: LIBS+=$(NEWT_LIB)
-
-stereorize: stereorize.o frame.o
-stereorize: LIBS+=-lm
-
-strcompat.c: ../main/strcompat.c
- @cp $< $@
-
-../main/ast_expr2.c:
- @echo " [BISON] ../main/ast_expr2.y -> $@"
- @bison -o $@ -d --name-prefix=ast_yy ../main/ast_expr2.y
-
-../main/ast_expr2f.c:
- @echo " [FLEX] ../main/ast_expr2.fl -> $@"
- @flex -o $@ --full ../main/ast_expr2.fl
-
-ast_expr2.c: ../main/ast_expr2.c
- @cp $< $@
-
-ast_expr2f.c: ../main/ast_expr2f.c
- @cp $< $@
-
-ast_expr2f.o: ASTCFLAGS+=-DSTANDALONE_AEL -I../main -Wno-unused
-
-check_expr: check_expr.o ast_expr2.o ast_expr2f.o
-
-aelbison.c: ../pbx/ael/ael.tab.c
- @cp $< $@
-aelbison.o: aelbison.c ../pbx/ael/ael.tab.h ../include/asterisk/ael_structs.h
-aelbison.o: ASTCFLAGS+=-I../pbx
-
-pbx_ael.c: ../pbx/pbx_ael.c
- @cp $< $@
-pbx_ael.o: ASTCFLAGS+=-DSTANDALONE_AEL
-
-ael_main.o: ael_main.c ../include/asterisk/ael_structs.h
-
-aelparse.c: ../pbx/ael/ael_lex.c
- @cp $< $@
-aelparse.o: aelparse.c ../include/asterisk/ael_structs.h ../pbx/ael/ael.tab.h
-aelparse.o: ASTCFLAGS+=-I../pbx -DSTANDALONE_AEL -Wno-unused
-
-aelparse: aelparse.o aelbison.o pbx_ael.o ael_main.o ast_expr2f.o ast_expr2.o strcompat.o
-
-testexpr2s: ../main/ast_expr2f.c ../main/ast_expr2.c ../main/ast_expr2.h
- $(CC) -g -c -I../include -DSTANDALONE_AEL ../main/ast_expr2f.c -o ast_expr2f.o
- $(CC) -g -c -I../include -DSTANDALONE_AEL ../main/ast_expr2.c -o ast_expr2.o
- $(CC) -g -o testexpr2s ast_expr2f.o ast_expr2.o
- rm ast_expr2.o ast_expr2f.o
- ./testexpr2s expr2.testinput
-
-smsq: smsq.o strcompat.o
-smsq: LIBS+=$(POPT_LIB)
-
-streamplayer: streamplayer.o
-
-muted: muted.o
-muted: LIBS+=$(AUDIO_LIBS)
-
-ifneq ($(wildcard .*.d),)
- include .*.d
-endif
diff --git a/1.4/utils/ael_main.c b/1.4/utils/ael_main.c
deleted file mode 100644
index 6c8f3d390..000000000
--- a/1.4/utils/ael_main.c
+++ /dev/null
@@ -1,585 +0,0 @@
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <locale.h>
-#include <ctype.h>
-#include <errno.h>
-#include <regex.h>
-#include <limits.h>
-
-#include "asterisk/ast_expr.h"
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/app.h"
-#include "asterisk/ael_structs.h"
-
-/*** MODULEINFO
- <depend>pbx_ael</depend>
- ***/
-
-struct namelist
-{
- char name[100];
- char name2[100];
- struct namelist *next;
-};
-
-struct ast_context
-{
- int extension_count;
- char name[100];
- char registrar[100];
- struct namelist *includes;
- struct namelist *ignorepats;
- struct namelist *switches;
- struct namelist *eswitches;
-
- struct namelist *includes_last;
- struct namelist *ignorepats_last;
- struct namelist *switches_last;
- struct namelist *eswitches_last;
-
- struct ast_context *next;
-};
-
-#define ADD_LAST(headptr,memptr) if(!headptr){ headptr=(memptr); (headptr##_last)=(memptr);} else {(headptr##_last)->next = (memptr); (headptr##_last) = (memptr);}
-
-void destroy_namelist(struct namelist *x);
-void destroy_namelist(struct namelist *x)
-{
- struct namelist *z,*z2;
- for(z=x; z; z = z2)
- {
- z2 = z->next;
- z->next = 0;
- free(z);
- }
-}
-
-struct namelist *create_name(const char *name);
-struct namelist *create_name(const char *name)
-{
- struct namelist *x = calloc(1, sizeof(*x));
- if (!x)
- return NULL;
- strncpy(x->name, name, sizeof(x->name) - 1);
- return x;
-}
-
-struct ast_context *context_list;
-struct ast_context *last_context;
-struct namelist *globalvars;
-struct namelist *globalvars_last;
-
-int conts=0, extens=0, priors=0;
-char last_exten[18000];
-char ast_config_AST_CONFIG_DIR[PATH_MAX];
-char ast_config_AST_VAR_DIR[PATH_MAX];
-
-void ast_add_profile(void);
-void ast_cli_register_multiple(void);
-void ast_register_file_version(void);
-void ast_unregister_file_version(void);
-int ast_add_extension2(struct ast_context *con,
- int replace, const char *extension, int priority, const char *label, const char *callerid,
- const char *application, void *data, void (*datad)(void *),
- const char *registrar);
-void pbx_builtin_setvar(void *chan, void *data);
-struct ast_context * ast_context_create(void **extcontexts, const char *name, const char *registrar);
-struct ast_context * ast_context_find_or_create(void **extcontexts, const char *name, const char *registrar);
-void ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
-void ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar);
-void ast_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar);
-void ast_merge_contexts_and_delete(void);
-void ast_context_verify_includes(void);
-struct ast_context * ast_walk_contexts(void);
-void ast_cli_unregister_multiple(void);
-void ast_context_destroy(void);
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...);
-char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
-void ast_verbose(const char *fmt, ...);
-struct ast_app *pbx_findapp(const char *app);
-void filter_leading_space_from_exprs(char *str);
-void filter_newlines(char *str);
-static int quiet = 0;
-static int no_comp = 0;
-static int use_curr_dir = 0;
-static int dump_extensions = 0;
-static int FIRST_TIME = 0;
-static FILE *dumpfile;
-
-struct ast_app *pbx_findapp(const char *app)
-{
- return (struct ast_app*)1; /* so as not to trigger an error */
-}
-
-void ast_add_profile(void)
-{
- if (!no_comp)
- printf("Executed ast_add_profile();\n");
-}
-
-int ast_loader_register(int (*updater)(void))
-{
- return 1;
-}
-
-int ast_loader_unregister(int (*updater)(void))
-{
- return 1;
-}
-void ast_module_register(const struct ast_module_info *x)
-{
-}
-
-void ast_module_unregister(const struct ast_module_info *x)
-{
-}
-
-
-void ast_cli_register_multiple(void)
-{
- if(!no_comp)
- printf("Executed ast_cli_register_multiple();\n");
-}
-
-void ast_register_file_version(void)
-{
- /* if(!no_comp)
- printf("Executed ast_register_file_version();\n"); */
- /* I'm erasing this, because I don't think anyone really ever needs to see it anyway */
-}
-
-void ast_unregister_file_version(void)
-{
- /* if(!no_comp)
- printf("Executed ast_unregister_file_version();\n"); */
- /* I'm erasing this, because I don't think anyone really ever needs to see it anyway */
-
-}
-void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
-void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count)
-{
- if (cp1 && *cp1)
- strncpy(cp2,cp1,AST_MAX_EXTENSION); /* Right now, this routine is ONLY being called for
- a possible var substitution on extension names,
- so....! */
- else
- *cp2 = 0;
-}
-
-int ast_add_extension2(struct ast_context *con,
- int replace, const char *extension, int priority, const char *label, const char *callerid,
- const char *application, void *data, void (*datad)(void *),
- const char *registrar)
-{
- priors++;
- con->extension_count++;
- if (strcmp(extension,last_exten) != 0) {
- extens++;
- strcpy(last_exten, extension);
- }
- if (!label) {
- label = "(null)";
- }
- if (!callerid) {
- callerid = "(null)";
- }
- if (!application) {
- application = "(null)";
- }
-
- if(!no_comp)
- printf("Executed ast_add_extension2(context=%s, rep=%d, exten=%s, priority=%d, label=%s, callerid=%s, appl=%s, data=%s, FREE, registrar=%s);\n",
- con->name, replace, extension, priority, label, callerid, application, (data?(char*)data:"(null)"), registrar);
-
- if( dump_extensions && dumpfile ) {
- struct namelist *n;
- char *data2,*data3=0;
- int commacount = 0;
-
- if( FIRST_TIME ) {
- FIRST_TIME = 0;
-
- if( globalvars )
- fprintf(dumpfile,"[globals]\n");
-
- for(n=globalvars;n;n=n->next) {
- fprintf(dumpfile, "%s\n", n->name);
- }
- }
-
- /* print out each extension , possibly the context header also */
- if( con != last_context ) {
- fprintf(dumpfile,"\n\n[%s]\n", con->name);
- last_context = con;
- for(n=con->ignorepats;n;n=n->next) {
- fprintf(dumpfile, "ignorepat => %s\n", n->name);
- }
- for(n=con->includes;n;n=n->next) {
- fprintf(dumpfile, "include => %s\n", n->name);
- }
- for(n=con->switches;n;n=n->next) {
- fprintf(dumpfile, "switch => %s/%s\n", n->name, n->name2);
- }
- for(n=con->eswitches;n;n=n->next) {
- fprintf(dumpfile, "eswitch => %s/%s\n", n->name, n->name2);
- }
-
- }
- if( data ) {
- filter_newlines((char*)data);
- filter_leading_space_from_exprs((char*)data);
-
- /* compiling turns commas into vertical bars in the app data, and also removes the backslash from before escaped commas;
- we have to restore the escaping backslash in front of any commas; the vertical bars are OK to leave as-is */
- for (data2 = data; *data2; data2++) {
- if (*data2 == ',')
- commacount++; /* we need to know how much bigger the string will grow-- one backslash for each comma */
- }
- if (commacount)
- {
- char *d3,*d4;
-
- data2 = (char*)malloc(strlen(data)+commacount+1);
- data3 = data;
- d3 = data;
- d4 = data2;
- while (*d3) {
- if (*d3 == ',') {
- *d4++ = '\\'; /* put a backslash in front of each comma */
- *d4++ = *d3++;
- } else
- *d4++ = *d3++; /* or just copy the char */
- }
- *d4++ = 0; /* cap off the new string */
- data = data2;
- } else
- data2 = 0;
-
- if( strcmp(label,"(null)") != 0 )
- fprintf(dumpfile,"exten => %s,%d(%s),%s(%s)\n", extension, priority, label, application, (char*)data);
- else
- fprintf(dumpfile,"exten => %s,%d,%s(%s)\n", extension, priority, application, (char*)data);
-
- if (data2) {
- free(data2);
- data2 = 0;
- data = data3; /* restore data to pre-messedup state */
- }
-
- } else {
-
- if( strcmp(label,"(null)") != 0 )
- fprintf(dumpfile,"exten => %s,%d(%s),%s\n", extension, priority, label, application);
- else
- fprintf(dumpfile,"exten => %s,%d,%s\n", extension, priority, application);
- }
- }
-
- /* since add_extension2 is responsible for the malloc'd data stuff */
- if( data )
- free(data);
- return 0;
-}
-
-void pbx_builtin_setvar(void *chan, void *data)
-{
- struct namelist *x = create_name(data);
- if(!no_comp)
- printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data);
-
- if( dump_extensions ) {
- x = create_name(data);
- ADD_LAST(globalvars,x);
- }
-}
-
-
-struct ast_context * ast_context_create(void **extcontexts, const char *name, const char *registrar)
-{
- struct ast_context *x = calloc(1, sizeof(*x));
- if (!x)
- return NULL;
- x->next = context_list;
- context_list = x;
- if (!no_comp)
- printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name, registrar);
- conts++;
- strncpy(x->name, name, sizeof(x->name) - 1);
- strncpy(x->registrar, registrar, sizeof(x->registrar) - 1);
- return x;
-}
-
-struct ast_context * ast_context_find_or_create(void **extcontexts, const char *name, const char *registrar)
-{
- struct ast_context *x = calloc(1, sizeof(*x));
- if (!x)
- return NULL;
- x->next = context_list;
- context_list = x;
- if (!no_comp)
- printf("Executed ast_context_find_or_create(conts, name=%s, registrar=%s);\n", name, registrar);
- conts++;
- strncpy(x->name, name, sizeof(x->name) - 1);
- strncpy(x->registrar, registrar, sizeof(x->registrar) - 1);
- return x;
-}
-
-void ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
-{
- if(!no_comp)
- printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value, registrar);
- if( dump_extensions ) {
- struct namelist *x;
- x = create_name(value);
- ADD_LAST(con->ignorepats,x);
- }
-}
-
-void ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
-{
- if(!no_comp)
- printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value, registrar);
- if( dump_extensions ) {
- struct namelist *x;
- x = create_name((char*)value);
- ADD_LAST(con->includes,x);
- }
-}
-
-void ast_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
-{
- if(!no_comp)
- printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value, data, eval, registrar);
- if( dump_extensions ) {
- struct namelist *x;
- x = create_name((char*)value);
- strncpy(x->name2,data,100);
- if( eval ) {
-
- ADD_LAST(con->switches,x);
-
- } else {
-
- ADD_LAST(con->eswitches,x);
- }
- }
-}
-
-void ast_merge_contexts_and_delete(void)
-{
- if(!no_comp)
- printf("Executed ast_merge_contexts_and_delete();\n");
-}
-
-void ast_context_verify_includes(void)
-{
- if(!no_comp)
- printf("Executed ast_context_verify_includes();\n");
-}
-
-struct ast_context * ast_walk_contexts(void)
-{
- if(!no_comp)
- printf("Executed ast_walk_contexts();\n");
- return 0;
-}
-
-void ast_cli_unregister_multiple(void)
-{
- if(!no_comp)
- printf("Executed ast_cli_unregister_multiple();\n");
-}
-
-void ast_context_destroy(void)
-{
- if( !no_comp)
- printf("Executed ast_context_destroy();\n");
-}
-
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
-{
- va_list vars;
- va_start(vars,fmt);
- if( !quiet || level > 2 ) {
- printf("LOG: lev:%d file:%s line:%d func: %s ",
- level, file, line, function);
- vprintf(fmt, vars);
- fflush(stdout);
- va_end(vars);
- }
-}
-
-void ast_verbose(const char *fmt, ...)
-{
- va_list vars;
- va_start(vars,fmt);
-
- printf("VERBOSE: ");
- vprintf(fmt, vars);
- fflush(stdout);
- va_end(vars);
-}
-
-char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
-{
- char *dataPut = start;
- int inEscape = 0;
- int inQuotes = 0;
-
- for (; *start; start++) {
- if (inEscape) {
- *dataPut++ = *start; /* Always goes verbatim */
- inEscape = 0;
- } else {
- if (*start == '\\') {
- inEscape = 1; /* Do not copy \ into the data */
- } else if (*start == '\'') {
- inQuotes = 1-inQuotes; /* Do not copy ' into the data */
- } else {
- /* Replace , with |, unless in quotes */
- *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
- }
- }
- }
- if (start != dataPut)
- *dataPut = 0;
- return dataPut;
-}
-
-void filter_leading_space_from_exprs(char *str)
-{
- /* Mainly for aesthetics */
- char *t, *v, *u = str;
-
- while ( u && *u ) {
-
- if( *u == '$' && *(u+1) == '[' ) {
- t = u+2;
- while( *t == '\n' || *t == '\r' || *t == '\t' || *t == ' ' ) {
- v = t;
- while ( *v ) {
- *v = *(v+1);
- v++;
- }
- }
- }
-
- u++;
- }
-}
-
-void filter_newlines(char *str)
-{
- /* remove all newlines, returns */
- char *t=str;
- while( t && *t ) {
- if( *t == '\n' || *t == '\r' ) {
- *t = ' '; /* just replace newlines and returns with spaces; they act as
- token separators, and just blindly removing them could be
- harmful. */
- }
- t++;
- }
-}
-
-
-extern struct module_symbols mod_data;
-extern int ael_external_load_module(void);
-
-int main(int argc, char **argv)
-{
- int i;
- struct namelist *n;
- struct ast_context *lp,*lp2;
-
- for(i=1;i<argc;i++) {
- if( argv[i][0] == '-' && argv[i][1] == 'n' )
- no_comp =1;
- if( argv[i][0] == '-' && argv[i][1] == 'q' ) {
- quiet = 1;
- no_comp =1;
- }
- if( argv[i][0] == '-' && argv[i][1] == 'd' )
- use_curr_dir =1;
- if( argv[i][0] == '-' && argv[i][1] == 'w' )
- dump_extensions =1;
- }
-
- if( !quiet ) {
- printf("\n(If you find progress and other non-error messages irritating, you can use -q to suppress them)\n");
- if( !no_comp )
- printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
- if( !use_curr_dir )
- printf("\n(You can use the -d option if you want to use the current working directory as the CONFIG_DIR. I will look in this dir for extensions.ael* and its included files)\n\n");
- if( !dump_extensions )
- printf("\n(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)\n");
- }
-
- if( use_curr_dir ) {
- strcpy(ast_config_AST_CONFIG_DIR, ".");
- }
- else {
- strcpy(ast_config_AST_CONFIG_DIR, "/etc/asterisk");
- }
- strcpy(ast_config_AST_VAR_DIR, "/var/lib/asterisk");
-
- if( dump_extensions ) {
- dumpfile = fopen("extensions.conf.aeldump","w");
- if( !dumpfile ) {
- printf("\n\nSorry, cannot open extensions.conf.aeldump for writing! Correct the situation and try again!\n\n");
- exit(10);
- }
-
- }
-
- FIRST_TIME = 1;
-
- ael_external_load_module();
-
- ast_log(4, "ael2_parse", __LINE__, "main", "%d contexts, %d extensions, %d priorities\n", conts, extens, priors);
-
- if( dump_extensions && dumpfile ) {
-
- for( lp = context_list; lp; lp = lp->next ) { /* print out any contexts that didn't have any
- extensions in them */
- if( lp->extension_count == 0 ) {
-
- fprintf(dumpfile,"\n\n[%s]\n", lp->name);
-
- for(n=lp->ignorepats;n;n=n->next) {
- fprintf(dumpfile, "ignorepat => %s\n", n->name);
- }
- for(n=lp->includes;n;n=n->next) {
- fprintf(dumpfile, "include => %s\n", n->name);
- }
- for(n=lp->switches;n;n=n->next) {
- fprintf(dumpfile, "switch => %s/%s\n", n->name, n->name2);
- }
- for(n=lp->eswitches;n;n=n->next) {
- fprintf(dumpfile, "eswitch => %s/%s\n", n->name, n->name2);
- }
- }
- }
- }
-
- if( dump_extensions && dumpfile )
- fclose(dumpfile);
-
- for( lp = context_list; lp; lp = lp2 ) { /* free the ast_context structs */
- lp2 = lp->next;
- lp->next = 0;
-
- destroy_namelist(lp->includes);
- destroy_namelist(lp->ignorepats);
- destroy_namelist(lp->switches);
- destroy_namelist(lp->eswitches);
-
- free(lp);
- }
-
- return 0;
-}
diff --git a/1.4/utils/astman.1 b/1.4/utils/astman.1
deleted file mode 100644
index 6a36ca4da..000000000
--- a/1.4/utils/astman.1
+++ /dev/null
@@ -1,102 +0,0 @@
-.\" $Header$
-.\"
-.\" transcript compatibility for postscript use.
-.\"
-.\" synopsis: .P! <file.ps>
-.\"
-.de P!
-.fl
-\!!1 setgray
-.fl
-\\&.\"
-.fl
-\!!0 setgray
-.fl \" force out current output buffer
-\!!save /psv exch def currentpoint translate 0 0 moveto
-\!!/showpage{}def
-.fl \" prolog
-.sy sed \-e 's/^/!/' \\$1\" bring in postscript file
-\!!psv restore
-.
-.de pF
-.ie \\*(f1 .ds f1 \\n(.f
-.el .ie \\*(f2 .ds f2 \\n(.f
-.el .ie \\*(f3 .ds f3 \\n(.f
-.el .ie \\*(f4 .ds f4 \\n(.f
-.el .tm ? font overflow
-.ft \\$1
-..
-.de fP
-.ie !\\*(f4 \{\
-. ft \\*(f4
-. ds f4\"
-' br \}
-.el .ie !\\*(f3 \{\
-. ft \\*(f3
-. ds f3\"
-' br \}
-.el .ie !\\*(f2 \{\
-. ft \\*(f2
-. ds f2\"
-' br \}
-.el .ie !\\*(f1 \{\
-. ft \\*(f1
-. ds f1\"
-' br \}
-.el .tm ? font underflow
-..
-.ds f1\"
-.ds f2\"
-.ds f3\"
-.ds f4\"
-'\" t
-.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n
-.TH ASTMAN 1 "Jun 12th, 2005" "astman" "Linux Programmer's Manual"
-.SH NAME
-.B astman
--- a client to asterisk's manager interface
-.SH SYNOPSIS
-.PP
-.B astman
-.I hostname
-
-.SH DESCRIPTION
-.B astman
-This program is a full-screen (terminal) client for Asterisk's manager
-interface.
-
-.SH OPTIONS
-.B hostname
-
-The host name or IP address to connect to (TCP port 5038). If astman
-fails to connect it will exit immidiately.
-
-.SH USAGE
-If \fBastman\fR has successfully cunnected to the manager port it will
-prompt the user for a username and a secret (password) for the manager
-interface on the remote Asterisk manager interface. It will then be able
-to report existing channels (calls). You will then be able to redirect
-calls to or terminate them.
-
-.SH "SEE ALSO"
-asterisk(8)
-
-http://www.voip-info.org/wiki-Asterisk+astman
-
-.SH BUGS
-The hostname does not default to localhost.
-
-Impossible to use a port other than 5038.
-
-The username and password cannot be defined from the command-line.
-
-I mean, what's the point in a man page if the syntax is so simple?
-
-.SH "AUTHOR"
-This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
-Permission is granted to copy, distribute and/or modify this document under
-the terms of the GNU General Public License, Version 2 any
-later version published by the Free Software Foundation.
-
-On Debian systems, the complete text of the GNU General Public
-License can be found in /usr/share/common-licenses/GPL.
diff --git a/1.4/utils/astman.c b/1.4/utils/astman.c
deleted file mode 100644
index f072dcd57..000000000
--- a/1.4/utils/astman.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-/*
- *
- * ASTerisk MANager
- *
- */
-
-#include <newt.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "asterisk/md5.h"
-#include "asterisk/linkedlists.h"
-
-#undef gethostbyname
-
-#define MAX_HEADERS 80
-#define MAX_LEN 256
-
-/*
- * 2005.05.27 - different versions of newt define the type of the buffer
- * for the 5th argument to newtEntry() as char ** or const char ** . To
- * let the code compile cleanly with -Werror, we cast it to void * through
- * _NEWT_CAST.
- */
-#define _NEWT_CAST (void *)
-
-#define DEFAULT_MANAGER_PORT 5038
-
-struct message {
- unsigned int hdrcount;
- char headers[MAX_HEADERS][MAX_LEN];
-};
-
-static struct ast_mansession {
- struct sockaddr_in sin;
- int fd;
- char inbuf[MAX_LEN];
- int inlen;
-} session;
-
-struct ast_chan {
- char name[80];
- char exten[20];
- char context[20];
- char priority[20];
- char callerid[40];
- char state[10];
- AST_LIST_ENTRY(ast_chan) list;
-};
-
-static AST_LIST_HEAD_NOLOCK_STATIC(chans, ast_chan);
-
-/* dummy functions to be compatible with the Asterisk core for md5.c */
-void ast_register_file_version(const char *file, const char *version);
-void ast_register_file_version(const char *file, const char *version)
-{
-}
-
-void ast_unregister_file_version(const char *file);
-void ast_unregister_file_version(const char *file)
-{
-}
-
-int ast_add_profile(const char *, uint64_t scale);
-int ast_add_profile(const char *s, uint64_t scale)
-{
- return -1;
-}
-
-int64_t ast_profile(int, int64_t);
-int64_t ast_profile(int key, int64_t val)
-{
- return 0;
-}
-int64_t ast_mark(int, int start1_stop0);
-int64_t ast_mark(int key, int start1_stop0)
-{
- return 0;
-}
-
-/* end of dummy functions */
-
-static struct ast_chan *find_chan(char *name)
-{
- struct ast_chan *chan;
- AST_LIST_TRAVERSE(&chans, chan, list) {
- if (!strcmp(name, chan->name))
- return chan;
- }
- chan = malloc(sizeof(struct ast_chan));
- if (chan) {
- memset(chan, 0, sizeof(struct ast_chan));
- strncpy(chan->name, name, sizeof(chan->name) - 1);
- AST_LIST_INSERT_TAIL(&chans, chan, list);
- }
- return chan;
-}
-
-static void del_chan(char *name)
-{
- struct ast_chan *chan;
- AST_LIST_TRAVERSE_SAFE_BEGIN(&chans, chan, list) {
- if (!strcmp(name, chan->name)) {
- AST_LIST_REMOVE_CURRENT(&chans, list);
- free(chan);
- return;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
-}
-
-static void fdprintf(int fd, char *fmt, ...)
-{
- char stuff[4096];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(stuff, sizeof(stuff), fmt, ap);
- va_end(ap);
- write(fd, stuff, strlen(stuff));
-}
-
-static char *get_header(struct message *m, char *var)
-{
- char cmp[80];
- int x;
- snprintf(cmp, sizeof(cmp), "%s: ", var);
- for (x=0;x<m->hdrcount;x++)
- if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
- return m->headers[x] + strlen(cmp);
- return "";
-}
-
-static int event_newstate(struct ast_mansession *s, struct message *m)
-{
- struct ast_chan *chan;
- chan = find_chan(get_header(m, "Channel"));
- strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
- return 0;
-}
-
-static int event_newexten(struct ast_mansession *s, struct message *m)
-{
- struct ast_chan *chan;
- chan = find_chan(get_header(m, "Channel"));
- strncpy(chan->exten, get_header(m, "Extension"), sizeof(chan->exten) - 1);
- strncpy(chan->context, get_header(m, "Context"), sizeof(chan->context) - 1);
- strncpy(chan->priority, get_header(m, "Priority"), sizeof(chan->priority) - 1);
- return 0;
-}
-
-static int event_newchannel(struct ast_mansession *s, struct message *m)
-{
- struct ast_chan *chan;
- chan = find_chan(get_header(m, "Channel"));
- strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
- strncpy(chan->callerid, get_header(m, "Callerid"), sizeof(chan->callerid) - 1);
- return 0;
-}
-
-static int event_status(struct ast_mansession *s, struct message *m)
-{
- struct ast_chan *chan;
- chan = find_chan(get_header(m, "Channel"));
- strncpy(chan->state, get_header(m, "State"), sizeof(chan->state) - 1);
- strncpy(chan->callerid, get_header(m, "Callerid"), sizeof(chan->callerid) - 1);
- strncpy(chan->exten, get_header(m, "Extension"), sizeof(chan->exten) - 1);
- strncpy(chan->context, get_header(m, "Context"), sizeof(chan->context) - 1);
- strncpy(chan->priority, get_header(m, "Priority"), sizeof(chan->priority) - 1);
- return 0;
-}
-
-static int event_hangup(struct ast_mansession *s, struct message *m)
-{
- del_chan(get_header(m, "Channel"));
- return 0;
-}
-
-static int event_ignore(struct ast_mansession *s, struct message *m)
-{
- return 0;
-}
-
-static int event_rename(struct ast_mansession *s, struct message *m)
-{
- struct ast_chan *chan;
- chan = find_chan(get_header(m, "Oldname"));
- strncpy(chan->name, get_header(m, "Newname"), sizeof(chan->name) - 1);
- return 0;
-}
-static struct event {
- char *event;
- int (*func)(struct ast_mansession *s, struct message *m);
-} events[] = {
- { "Newstate", event_newstate },
- { "Newchannel", event_newchannel },
- { "Newexten", event_newexten },
- { "Hangup", event_hangup },
- { "Rename", event_rename },
- { "Status", event_status },
- { "Link", event_ignore },
- { "Unlink", event_ignore },
- { "StatusComplete", event_ignore }
-};
-
-static int process_message(struct ast_mansession *s, struct message *m)
-{
- int x;
- char event[80] = "";
- strncpy(event, get_header(m, "Event"), sizeof(event) - 1);
- if (!strlen(event)) {
- fprintf(stderr, "Missing event in request");
- return 0;
- }
- for (x=0;x<sizeof(events) / sizeof(events[0]);x++) {
- if (!strcasecmp(event, events[x].event)) {
- if (events[x].func(s, m))
- return -1;
- break;
- }
- }
- if (x >= sizeof(events) / sizeof(events[0]))
- fprintf(stderr, "Ignoring unknown event '%s'", event);
-#if 0
- for (x=0;x<m->hdrcount;x++) {
- printf("Header: %s\n", m->headers[x]);
- }
-#endif
- return 0;
-}
-
-static void rebuild_channels(newtComponent c)
-{
- void *prev = NULL;
- struct ast_chan *chan;
- char tmpn[42];
- char tmp[256];
- int x=0;
- prev = newtListboxGetCurrent(c);
- newtListboxClear(c);
- AST_LIST_TRAVERSE(&chans, chan, list) {
- snprintf(tmpn, sizeof(tmpn), "%s (%s)", chan->name, chan->callerid);
- if (strlen(chan->exten))
- snprintf(tmp, sizeof(tmp), "%-30s %8s -> %s@%s:%s",
- tmpn, chan->state,
- chan->exten, chan->context, chan->priority);
- else
- snprintf(tmp, sizeof(tmp), "%-30s %8s",
- tmpn, chan->state);
- newtListboxAppendEntry(c, tmp, chan);
- x++;
- }
- if (!x)
- newtListboxAppendEntry(c, " << No Active Channels >> ", NULL);
- newtListboxSetCurrentByKey(c, prev);
-}
-
-static int has_input(struct ast_mansession *s)
-{
- int x;
- for (x=1;x<s->inlen;x++)
- if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r'))
- return 1;
- return 0;
-}
-
-static int get_input(struct ast_mansession *s, char *output)
-{
- /* output must have at least sizeof(s->inbuf) space */
- int res;
- int x;
- struct timeval tv = {0, 0};
- fd_set fds;
- for (x=1;x<s->inlen;x++) {
- if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
- /* Copy output data up to and including \r\n */
- memcpy(output, s->inbuf, x + 1);
- /* Add trailing \0 */
- output[x+1] = '\0';
- /* Move remaining data back to the front */
- memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
- s->inlen -= (x + 1);
- return 1;
- }
- }
- if (s->inlen >= sizeof(s->inbuf) - 1) {
- fprintf(stderr, "Dumping long line with no return from %s: %s\n", inet_ntoa(s->sin.sin_addr), s->inbuf);
- s->inlen = 0;
- }
- FD_ZERO(&fds);
- FD_SET(s->fd, &fds);
- res = select(s->fd + 1, &fds, NULL, NULL, &tv);
- if (res < 0) {
- fprintf(stderr, "Select returned error: %s\n", strerror(errno));
- } else if (res > 0) {
- res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
- if (res < 1)
- return -1;
- s->inlen += res;
- s->inbuf[s->inlen] = '\0';
- } else {
- return 2;
- }
- return 0;
-}
-
-static int input_check(struct ast_mansession *s, struct message **mout)
-{
- static struct message m;
- int res;
-
- if (mout)
- *mout = NULL;
-
- for(;;) {
- res = get_input(s, m.headers[m.hdrcount]);
- if (res == 1) {
-#if 0
- fprintf(stderr, "Got header: %s", m.headers[m.hdrcount]);
- fgetc(stdin);
-#endif
- /* Strip trailing \r\n */
- if (strlen(m.headers[m.hdrcount]) < 2)
- continue;
- m.headers[m.hdrcount][strlen(m.headers[m.hdrcount]) - 2] = '\0';
- if (!strlen(m.headers[m.hdrcount])) {
- if (mout && strlen(get_header(&m, "Response"))) {
- *mout = &m;
- return 0;
- }
- if (process_message(s, &m))
- break;
- memset(&m, 0, sizeof(&m));
- } else if (m.hdrcount < MAX_HEADERS - 1)
- m.hdrcount++;
- } else if (res < 0) {
- return -1;
- } else if (res == 2)
- return 0;
- }
- return -1;
-}
-
-static struct message *wait_for_response(int timeout)
-{
- struct message *m;
- struct timeval tv;
- int res;
- fd_set fds;
- for (;;) {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- FD_SET(session.fd, &fds);
- res = select(session.fd + 1, &fds, NULL, NULL, &tv);
- if (res < 1)
- break;
- if (input_check(&session, &m) < 0) {
- return NULL;
- }
- if (m)
- return m;
- }
- return NULL;
-}
-
-static int manager_action(char *action, char *fmt, ...)
-{
- struct ast_mansession *s;
- char tmp[4096];
- va_list ap;
-
- s = &session;
- fdprintf(s->fd, "Action: %s\r\n", action);
- va_start(ap, fmt);
- vsnprintf(tmp, sizeof(tmp), fmt, ap);
- va_end(ap);
- write(s->fd, tmp, strlen(tmp));
- fdprintf(s->fd, "\r\n");
- return 0;
-}
-
-static int show_message(char *title, char *msg)
-{
- newtComponent form;
- newtComponent label;
- newtComponent ok;
- struct newtExitStruct es;
-
- newtCenteredWindow(60,7, title);
-
- label = newtLabel(4,1,msg);
- ok = newtButton(27, 3, "OK");
- form = newtForm(NULL, NULL, 0);
- newtFormAddComponents(form, label, ok, NULL);
- newtFormRun(form, &es);
- newtPopWindow();
- newtFormDestroy(form);
- return 0;
-}
-
-static newtComponent showform;
-static int show_doing(char *title, char *tmp)
-{
- struct newtExitStruct es;
- newtComponent label;
- showform = newtForm(NULL, NULL, 0);
- newtCenteredWindow(70,4, title);
- label = newtLabel(3,1,tmp);
- newtFormAddComponents(showform,label, NULL);
- newtFormSetTimer(showform, 200);
- newtFormRun(showform, &es);
- return 0;
-}
-
-static int hide_doing(void)
-{
- newtPopWindow();
- newtFormDestroy(showform);
- return 0;
-}
-
-static void try_status(void)
-{
- struct message *m;
- manager_action("Status", "");
- m = wait_for_response(10000);
- if (!m) {
- show_message("Status Failed", "Timeout waiting for response");
- } else if (strcasecmp(get_header(m, "Response"), "Success")) {
- show_message("Status Failed Failed", get_header(m, "Message"));
- }
-}
-
-
-static void try_hangup(newtComponent c)
-{
- struct ast_chan *chan;
- struct message *m;
-
- chan = newtListboxGetCurrent(c);
- if (chan) {
- manager_action("Hangup", "Channel: %s\r\n", chan->name);
- m = wait_for_response(10000);
- if (!m) {
- show_message("Hangup Failed", "Timeout waiting for response");
- } else if (strcasecmp(get_header(m, "Response"), "Success")) {
- show_message("Hangup Failed", get_header(m, "Message"));
- }
- }
-
-}
-
-static int get_user_input(char *msg, char *buf, int buflen)
-{
- newtComponent form;
- newtComponent ok;
- newtComponent cancel;
- newtComponent inpfield;
- const char *input;
- int res = -1;
- struct newtExitStruct es;
-
- newtCenteredWindow(60,7, msg);
-
- inpfield = newtEntry(5, 2, "", 50, _NEWT_CAST &input, 0);
- ok = newtButton(22, 3, "OK");
- cancel = newtButton(32, 3, "Cancel");
- form = newtForm(NULL, NULL, 0);
- newtFormAddComponents(form, inpfield, ok, cancel, NULL);
- newtFormRun(form, &es);
- strncpy(buf, input, buflen - 1);
- if (es.u.co == ok)
- res = 0;
- else
- res = -1;
- newtPopWindow();
- newtFormDestroy(form);
- return res;
-}
-
-static void try_redirect(newtComponent c)
-{
- struct ast_chan *chan;
- char dest[256];
- struct message *m;
- char channame[256];
- char tmp[80];
- char *context;
-
- chan = newtListboxGetCurrent(c);
- if (chan) {
- strncpy(channame, chan->name, sizeof(channame) - 1);
- snprintf(tmp, sizeof(tmp), "Enter new extension for %s", channame);
- if (get_user_input(tmp, dest, sizeof(dest)))
- return;
- if ((context = strchr(dest, '@'))) {
- *context = '\0';
- context++;
- manager_action("Redirect", "Channel: %s\r\nContext: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->name,context,dest);
- } else {
- manager_action("Redirect", "Channel: %s\r\nExten: %s\r\nPriority: 1\r\n", chan->name, dest);
- }
- m = wait_for_response(10000);
- if (!m) {
- show_message("Hangup Failed", "Timeout waiting for response");
- } else if (strcasecmp(get_header(m, "Response"), "Success")) {
- show_message("Hangup Failed", get_header(m, "Message"));
- }
- }
-
-}
-
-static int manage_calls(char *host)
-{
- newtComponent form;
- newtComponent quit;
- newtComponent hangup;
- newtComponent redirect;
- newtComponent channels;
- struct newtExitStruct es;
- char tmp[80];
-
- /* Mark: If there's one thing you learn from this code, it is this...
- Never, ever fly Air France. Their customer service is absolutely
- the worst. I've never heard the words "That's not my problem" as
- many times as I have from their staff -- It should, without doubt
- be their corporate motto if it isn't already. Don't bother giving
- them business because you're just a pain in their side and they
- will be sure to let you know the first time you speak to them.
-
- If you ever want to make me happy just tell me that you, too, will
- never fly Air France again either (in spite of their excellent
- cuisine).
-
- Update by oej: The merger with KLM has transferred this
- behaviour to KLM as well.
- Don't bother giving them business either...
-
- Only if you want to travel randomly without luggage, you
- might pick either of them.
-
- */
- snprintf(tmp, sizeof(tmp), "Asterisk Manager at %s", host);
- newtCenteredWindow(74, 20, tmp);
- form = newtForm(NULL, NULL, 0);
- newtFormWatchFd(form, session.fd, NEWT_FD_READ);
- newtFormSetTimer(form, 100);
- quit = newtButton(62, 16, "Quit");
- redirect = newtButton(35, 16, "Redirect");
- hangup = newtButton(50, 16, "Hangup");
- channels = newtListbox(1,1,14, NEWT_FLAG_SCROLL);
- newtFormAddComponents(form, channels, redirect, hangup, quit, NULL);
- newtListboxSetWidth(channels, 72);
-
- show_doing("Getting Status", "Retrieving system status...");
- try_status();
- hide_doing();
-
- for(;;) {
- newtFormRun(form, &es);
- if (has_input(&session) || (es.reason == NEWT_EXIT_FDREADY)) {
- if (input_check(&session, NULL)) {
- show_message("Disconnected", "Disconnected from remote host");
- break;
- }
- } else if (es.reason == NEWT_EXIT_COMPONENT) {
- if (es.u.co == quit)
- break;
- if (es.u.co == hangup) {
- try_hangup(channels);
- } else if (es.u.co == redirect) {
- try_redirect(channels);
- }
- }
- rebuild_channels(channels);
- }
- newtFormDestroy(form);
- return 0;
-}
-
-static int login(char *hostname)
-{
- newtComponent form;
- newtComponent cancel;
- newtComponent login;
- newtComponent username;
- newtComponent password;
- newtComponent label;
- newtComponent ulabel;
- newtComponent plabel;
- const char *user;
- const char *pass;
- struct message *m;
- struct newtExitStruct es;
- char tmp[55];
- struct hostent *hp;
- int res = -1;
-
- session.fd = socket(AF_INET, SOCK_STREAM, 0);
- if (session.fd < 0) {
- snprintf(tmp, sizeof(tmp), "socket() failed: %s\n", strerror(errno));
- show_message("Socket failed", tmp);
- return -1;
- }
-
- snprintf(tmp, sizeof(tmp), "Looking up %s\n", hostname);
- show_doing("Connecting....", tmp);
-
-
- hp = gethostbyname(hostname);
- if (!hp) {
- snprintf(tmp, sizeof(tmp), "No such address: %s\n", hostname);
- show_message("Host lookup failed", tmp);
- return -1;
- }
- hide_doing();
- snprintf(tmp, sizeof(tmp), "Connecting to %s", hostname);
- show_doing("Connecting...", tmp);
-
- session.sin.sin_family = AF_INET;
- session.sin.sin_port = htons(DEFAULT_MANAGER_PORT);
- memcpy(&session.sin.sin_addr, hp->h_addr, sizeof(session.sin.sin_addr));
-
- if (connect(session.fd,(struct sockaddr*)&session.sin, sizeof(session.sin))) {
- snprintf(tmp, sizeof(tmp), "%s failed: %s\n", hostname, strerror(errno));
- show_message("Connect Failed", tmp);
- return -1;
- }
-
- hide_doing();
-
- login = newtButton(5, 6, "Login");
- cancel = newtButton(25, 6, "Cancel");
- newtCenteredWindow(40, 10, "Asterisk Manager Login");
- snprintf(tmp, sizeof(tmp), "Host: %s", hostname);
- label = newtLabel(4,1, tmp);
-
- ulabel = newtLabel(4,2,"Username:");
- plabel = newtLabel(4,3,"Password:");
-
- username = newtEntry(14, 2, "", 20, _NEWT_CAST &user, 0);
- password = newtEntry(14, 3, "", 20, _NEWT_CAST &pass, NEWT_FLAG_HIDDEN);
-
- form = newtForm(NULL, NULL, 0);
- newtFormAddComponents(form, username, password, login, cancel, label, ulabel, plabel,NULL);
- newtFormRun(form, &es);
- if (es.reason == NEWT_EXIT_COMPONENT) {
- if (es.u.co == login) {
- snprintf(tmp, sizeof(tmp), "Logging in '%s'...", user);
- show_doing("Logging in", tmp);
- /* Check to see if the remote host supports MD5 Authentication */
- manager_action("Challenge", "AuthType: MD5\r\n");
- m = wait_for_response(10000);
- if (m && !strcasecmp(get_header(m, "Response"), "Success")) {
- char *challenge = get_header(m, "Challenge");
- int x;
- int len = 0;
- char md5key[256] = "";
- struct MD5Context md5;
- unsigned char digest[16];
- MD5Init(&md5);
- MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
- MD5Update(&md5, (unsigned char *)pass, strlen(pass));
- MD5Final(digest, &md5);
- for (x=0; x<16; x++)
- len += sprintf(md5key + len, "%2.2x", digest[x]);
- manager_action("Login",
- "AuthType: MD5\r\n"
- "Username: %s\r\n"
- "Key: %s\r\n",
- user, md5key);
- m = wait_for_response(10000);
- hide_doing();
- if (!strcasecmp(get_header(m, "Response"), "Success")) {
- res = 0;
- } else {
- show_message("Login Failed", get_header(m, "Message"));
- }
- } else {
- memset(m, 0, sizeof(m));
- manager_action("Login",
- "Username: %s\r\n"
- "Secret: %s\r\n",
- user, pass);
- m = wait_for_response(10000);
- hide_doing();
- if (m) {
- if (!strcasecmp(get_header(m, "Response"), "Success")) {
- res = 0;
- } else {
- show_message("Login Failed", get_header(m, "Message"));
- }
- }
- }
- }
- }
- newtFormDestroy(form);
- return res;
-}
-
-int main(int argc, char *argv[])
-{
- if (argc < 2) {
- fprintf(stderr, "Usage: astman <host>\n");
- exit(1);
- }
- newtInit();
- newtCls();
- newtDrawRootText(0, 0, "Asterisk Manager (C)2002, Linux Support Services, Inc.");
- newtPushHelpLine("Welcome to the Asterisk Manager!");
- if (login(argv[1])) {
- newtFinished();
- exit(1);
- }
- manage_calls(argv[1]);
- newtFinished();
- return 0;
-}
diff --git a/1.4/utils/check_expr.c b/1.4/utils/check_expr.c
deleted file mode 100644
index df1765db1..000000000
--- a/1.4/utils/check_expr.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, 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.
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <../include/asterisk/ast_expr.h>
-
-static int global_lineno = 1;
-static int global_expr_count=0;
-static int global_expr_max_size=0;
-static int global_expr_tot_size=0;
-static int global_warn_count=0;
-static int global_OK_count=0;
-
-struct varz
-{
- char varname[100]; /* a really ultra-simple, space-wasting linked list of var=val data */
- char varval[1000]; /* if any varname is bigger than 100 chars, or val greater than 1000, then **CRASH** */
- struct varz *next;
-};
-
-struct varz *global_varlist;
-
-/* Our own version of ast_log, since the expr parser uses it. */
-
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
-
-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
-{
- va_list vars;
- va_start(vars,fmt);
-
- printf("LOG: lev:%d file:%s line:%d func: %s ",
- level, file, line, function);
- vprintf(fmt, vars);
- fflush(stdout);
- va_end(vars);
-}
-void ast_register_file_version(const char *file, const char *version);
-void ast_unregister_file_version(const char *file);
-
-char *find_var(const char *varname);
-void set_var(const char *varname, const char *varval);
-unsigned int check_expr(char* buffer, char* error_report);
-int check_eval(char *buffer, char *error_report);
-void parse_file(const char *fname);
-
-void ast_register_file_version(const char *file, const char *version)
-{
-}
-
-void ast_unregister_file_version(const char *file)
-{
-}
-
-char *find_var(const char *varname) /* the list should be pretty short, if there's any list at all */
-{
- struct varz *t;
- for (t= global_varlist; t; t = t->next) {
- if (!strcmp(t->varname, varname)) {
- return t->varval;
- }
- }
- return 0;
-}
-
-void set_var(const char *varname, const char *varval)
-{
- struct varz *t = (struct varz*)calloc(1,sizeof(struct varz));
- strcpy(t->varname, varname);
- strcpy(t->varval, varval);
- t->next = global_varlist;
- global_varlist = t;
-}
-
-unsigned int check_expr(char* buffer, char* error_report)
-{
- char* cp;
- unsigned int warn_found = 0;
-
- error_report[0] = 0;
-
- for (cp = buffer; *cp; ++cp)
- {
- switch (*cp)
- {
- case '"':
- /* skip to the other end */
- while (*(++cp) && *cp != '"') ;
-
- if (*cp == 0)
- {
- fprintf(stderr,
- "Trouble? Unterminated double quote found at line %d\n",
- global_lineno);
- }
- break;
-
- case '>':
- case '<':
- case '!':
- if ( (*(cp + 1) == '=')
- && ( ( (cp > buffer) && (*(cp - 1) != ' ') ) || (*(cp + 2) != ' ') ) )
- {
- char msg[200];
- snprintf(msg,
- sizeof(msg),
- "WARNING: line %d: '%c%c' operator not separated by spaces. This may lead to confusion. You may wish to use double quotes to quote the grouping it is in. Please check!\n",
- global_lineno, *cp, *(cp + 1));
- strcat(error_report, msg);
- ++global_warn_count;
- ++warn_found;
- }
- break;
-
- case '|':
- case '&':
- case '=':
- case '+':
- case '-':
- case '*':
- case '/':
- case '%':
- case '?':
- case ':':
- if ( ( (cp > buffer) && (*(cp - 1) != ' ') ) || (*(cp + 1) != ' ') )
- {
- char msg[200];
- snprintf(msg,
- sizeof(msg),
- "WARNING: line %d: '%c' operator not separated by spaces. This may lead to confusion. You may wish to use double quotes to quote the grouping it is in. Please check!\n",
- global_lineno, *cp );
- strcat(error_report, msg);
- ++global_warn_count;
- ++warn_found;
- }
- break;
- }
- }
-
- return warn_found;
-}
-
-int check_eval(char *buffer, char *error_report)
-{
- char *cp, *ep;
- char s[4096];
- char evalbuf[80000];
- int result;
-
- error_report[0] = 0;
- ep = evalbuf;
-
- for (cp=buffer;*cp;cp++) {
- if (*cp == '$' && *(cp+1) == '{') {
- int brack_lev = 1;
- char *xp= cp+2;
-
- while (*xp) {
- if (*xp == '{')
- brack_lev++;
- else if (*xp == '}')
- brack_lev--;
-
- if (brack_lev == 0)
- break;
- xp++;
- }
- if (*xp == '}') {
- char varname[200];
- char *val;
-
- strncpy(varname,cp+2, xp-cp-2);
- varname[xp-cp-2] = 0;
- cp = xp;
- val = find_var(varname);
- if (val) {
- char *z = val;
- while (*z)
- *ep++ = *z++;
- }
- else {
- *ep++ = '5'; /* why not */
- *ep++ = '5';
- *ep++ = '5';
- }
- }
- else {
- printf("Unterminated variable reference at line %d\n", global_lineno);
- *ep++ = *cp;
- }
- }
- else if (*cp == '\\') {
- /* braindead simple elim of backslash */
- cp++;
- *ep++ = *cp;
- }
- else
- *ep++ = *cp;
- }
- *ep++ = 0;
-
- /* now, run the test */
- result = ast_expr(evalbuf, s, sizeof(s));
- if (result) {
- sprintf(error_report,"line %d, evaluation of $[ %s ] result: %s\n", global_lineno, evalbuf, s);
- return 1;
- } else {
- sprintf(error_report,"line %d, evaluation of $[ %s ] result: ****SYNTAX ERROR****\n", global_lineno, evalbuf);
- return 1;
- }
-}
-
-
-void parse_file(const char *fname)
-{
- FILE *f = fopen(fname,"r");
- FILE *l = fopen("expr2_log","w");
- int c1;
- char last_char= 0;
- char buffer[30000]; /* I sure hope no expr gets this big! */
-
- if (!f) {
- fprintf(stderr,"Couldn't open %s for reading... need an extensions.conf file to parse!\n",fname);
- exit(20);
- }
- if (!l) {
- fprintf(stderr,"Couldn't open 'expr2_log' file for writing... please fix and re-run!\n");
- exit(21);
- }
-
- global_lineno = 1;
-
- while ((c1 = fgetc(f)) != EOF) {
- if (c1 == '\n')
- global_lineno++;
- else if (c1 == '[') {
- if (last_char == '$') {
- /* bingo, an expr */
- int bracklev = 1;
- int bufcount = 0;
- int retval;
- char error_report[30000];
-
- while ((c1 = fgetc(f)) != EOF) {
- if (c1 == '[')
- bracklev++;
- else if (c1 == ']')
- bracklev--;
- if (c1 == '\n') {
- fprintf(l, "ERROR-- A newline in an expression? Weird! ...at line %d\n", global_lineno);
- fclose(f);
- fclose(l);
- printf("--- ERROR --- A newline in the middle of an expression at line %d!\n", global_lineno);
- }
-
- if (bracklev == 0)
- break;
- buffer[bufcount++] = c1;
- }
- if (c1 == EOF) {
- fprintf(l, "ERROR-- End of File Reached in the middle of an Expr at line %d\n", global_lineno);
- fclose(f);
- fclose(l);
- printf("--- ERROR --- EOF reached in middle of an expression at line %d!\n", global_lineno);
- exit(22);
- }
-
- buffer[bufcount] = 0;
- /* update stats */
- global_expr_tot_size += bufcount;
- global_expr_count++;
- if (bufcount > global_expr_max_size)
- global_expr_max_size = bufcount;
-
- retval = check_expr(buffer, error_report); /* check_expr should bump the warning counter */
- if (retval != 0) {
- /* print error report */
- printf("Warning(s) at line %d, expression: $[%s]; see expr2_log file for details\n",
- global_lineno, buffer);
- fprintf(l, "%s", error_report);
- }
- else {
- printf("OK -- $[%s] at line %d\n", buffer, global_lineno);
- global_OK_count++;
- }
- error_report[0] = 0;
- retval = check_eval(buffer, error_report);
- fprintf(l, "%s", error_report);
- }
- }
- last_char = c1;
- }
- printf("Summary:\n Expressions detected: %d\n Expressions OK: %d\n Total # Warnings: %d\n Longest Expr: %d chars\n Ave expr len: %d chars\n",
- global_expr_count,
- global_OK_count,
- global_warn_count,
- global_expr_max_size,
- (global_expr_count) ? global_expr_tot_size/global_expr_count : 0);
-
- fclose(f);
- fclose(l);
-}
-
-
-int main(int argc,char **argv)
-{
- int argc1;
- char *eq;
-
- if (argc < 2) {
- printf("check_expr -- a program to look thru extensions.conf files for $[...] expressions,\n");
- printf(" and run them thru the parser, looking for problems\n");
- printf("Hey-- give me a path to an extensions.conf file!\n");
- printf(" You can also follow the file path with a series of variable decls,\n");
- printf(" of the form, varname=value, each separated from the next by spaces.\n");
- printf(" (this might allow you to avoid division by zero messages, check that math\n");
- printf(" is being done correctly, etc.)\n");
- printf(" Note that messages about operators not being surrounded by spaces is merely to alert\n");
- printf(" you to possible problems where you might be expecting those operators as part of a string.\n");
- printf(" (to include operators in a string, wrap with double quotes!)\n");
-
- exit(19);
- }
- global_varlist = 0;
- for (argc1=2;argc1 < argc; argc1++) {
- if ((eq = strchr(argv[argc1],'='))) {
- *eq = 0;
- set_var(argv[argc1],eq+1);
- }
- }
-
- /* parse command args for x=y and set varz */
-
- parse_file(argv[1]);
- return 0;
-}
diff --git a/1.4/utils/expr2.testinput b/1.4/utils/expr2.testinput
deleted file mode 100644
index 948baaf94..000000000
--- a/1.4/utils/expr2.testinput
+++ /dev/null
@@ -1,92 +0,0 @@
-2 + 2
- 2 + 2
-
-2 - 4
-4 - 2
--4 - -2
-4 + 2 * 8
-(4 + 2) * 8
-4 + (2 * 8)
-4 + (2 * 8) ? 3 :: 6
-4 + 8 / 2
-4 + 8 / 3
-(4+8) / 3
-4 + 8 % 3
-4 + 9 % 3
-(4+9) %3
-(4+8) %3
-(4+9) %3
-(4+8) %3
-(4+9) % 3
-(4+8) % 3
-(4+9) % 3
-(4+8) % 3
-(4+9)% 3
-(4+8)% 3
-(4+9)% 3
-(4+8)% 3
-4 & 4
-0 & 4
-0 & 0
-2 | 0
-2 | 4
-0 | 0
-!0 | 0
-!4 | 0
-4 | !0
-!4 | !0
-3 < 4
-4 < 3
-3 > 4
-4 > 3
-3 = 3
-3 = 4
-3 != 3
-3 != 4
-3 >= 4
-3 >= 3
-4 >= 3
-3 <= 4
-4 <= 3
-4 <= 4
-3 > 4 & 4 < 3
-4 > 3 & 3 < 4
-x = x
-y = x
-x != y
-x != x
-"Something interesting" =~ interesting
-"Something interesting" =~ Something
-"Something interesting" : Something
-"Something interesting" : interesting
-"Something interesting" =~ "interesting"
-"Something interesting" =~ "Something"
-"Something interesting" : "Something"
-"Something interesting" : "interesting"
-"Something interesting" =~ (interesting)
-"Something interesting" =~ (Something)
-"Something interesting" : (Something)
-"Something interesting" : (interesting)
-"Something interesting" =~ "\(interesting\)"
-"Something interesting" =~ "\(Something\)"
-"Something interesting" : "\(Something\)"
-"Something interesting" : "\(interesting\)"
-"011043567857575" : "011\(..\)"
-"9011043567857575" : "011\(..\)"
-"011043567857575" =~ "011\(..\)"
-"9011043567857575" =~ "011\(..\)"
-"Something interesting" =~ (interesting)
-"Something interesting" =~ (Something)
-"Something interesting" : (Something)
-"Something interesting" : (interesting)
-"Something interesting" =~ "(interesting)"
-"Something interesting" =~ "(Something)"
-"Something interesting" : "(Something)"
-"Something interesting" : "(interesting)"
-"011043567857575" : "011(..)"
-"9011043567857575" : "011(..)"
-"011043567857575" =~ "011(..)"
-"9011043567857575" =~ "011(..)"
-3
-something
-043
diff --git a/1.4/utils/frame.c b/1.4/utils/frame.c
deleted file mode 100644
index 7fdb1637d..000000000
--- a/1.4/utils/frame.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/****************************************************************************
- *
- * Programs for processing sound files in raw- or WAV-format.
- * -- Useful functions for parsing command line options and
- * issuing errors, warnings, and chit chat.
- *
- * Name: frame.c
- * Version: see static char *standardversion, below.
- * Author: Mark Roberts <mark@manumark.de>
- * Michael Labuschke <michael@labuschke.de> sys_errlist fixes
- *
- ****************************************************************************/
-/****************************************************************************
- * These are useful functions that all DSP programs might find handy
- ****************************************************************************/
-
-#include <stdio.h>
-#include <math.h>
-#include <stdlib.h> /* for exit and malloc */
-#include <string.h>
-#include <time.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <assert.h>
-#include "frame.h"
-
-time_t stopwatch; /* will hold time at start of calculation */
-int samplefrequency;
-unsigned short samplewidth;
-unsigned short channels;
-int wavout; /* TRUE iff out file should be a .WAV file */
-int iswav; /* TRUE iff in file was found to be a .WAV file */
-FILE *in, *out;
-char *infilename, *outfilename;
-int verboselevel;
-char *version = "";
-char *usage = "";
-static int test_usage;
-
-static char *standardversion = "frame version 1.3, June 13th 2001";
-static char *standardusage =
-"\nOptions common to all mark-dsp programs:\n"
-
-"-h \t\t create a WAV-header on output files.\n"
-"-c#\t\t set number of channels to # (1 or 2). Default: like input.\n"
-"-w#\t\t set number of bits per sample (width) to # (only 16)\n"
-"-f#\t\t set sample frequency to #. Default: like input.\n"
-"-V \t\t verbose: talk a lot.\n"
-"-Q \t\t quiet: talk as little as possible.\n\n"
-"In most cases, a filename of '-' means stdin or stdout.\n\n"
-"Bug-reports: mark@manumark.de\n"
-;
-
-/* -----------------------------------------------------------------------
- Writes the number of samples to result that are yet to be read from anyin.
- Return values are TRUE on success, FALSE on failure.
- -----------------------------------------------------------------------*/
-int getremainingfilelength( FILE *anyin, long *result)
-{
- long i;
-
- i = ftell (anyin);
- if (i == -1) return FALSE;
- if (fseek (anyin, 0, SEEK_END) == -1) return FALSE;
- *result = ftell (anyin);
- if (*result == -1) return FALSE;
- (*result) -= i;
- (*result) /= samplewidth;
- if (fseek (anyin, i, SEEK_SET) == -1) return FALSE;
- return TRUE;
-}
-
-/* -----------------------------------------------------------------------
- Read a .pk-header from 'anyin'.
- -----------------------------------------------------------------------*/
-void readpkheader( FILE *anyin)
-{
- unsigned short tempushort;
- int tempint, i, x;
- unsigned char blood[8];
-
- for (i = 0; i < 11; i++)
- {
- fread( &tempint, 4, 1, anyin);
- printf( "%d: %d, ", i, tempint);
- }
- printf( "\n");
- fread( blood, 1, 8, anyin);
- for (i = 0; i < 8; i++)
- printf( "%d ", blood[i]);
- printf( "\n");
- for (i = 0; i < 8; i++)
- {
- for (x = 128; x > 0; x /= 2)
- printf((blood[i] & x) == 0? "0 ":"1 ");
- printf(i%4==3? "\n":"| ");
- }
- printf( "\n");
- for (i = 0; i < 2; i++)
- {
- fread( &tempint, 4, 1, anyin);
- printf( "%d: %d, ", i, tempint);
- }
- printf( "\n");
- for (i = 0; i < 2; i++)
- {
- fread( &tempushort, 2, 1, anyin);
- printf( "%d: %d, ", i, tempushort);
- }
- printf( "\n");
-}
-
-
-
-/* -----------------------------------------------------------------------
- Read a .WAV header from 'anyin'. See header for details.
- -----------------------------------------------------------------------*/
-void readwavheader( FILE *anyin)
-{
- unsigned int tempuint, sf;
- unsigned short tempushort, cn;
- char str[9];
- int nowav = FALSE;
-
- iswav = FALSE;
-
- if (ftell(anyin) == -1) /* If we cannot seek this file */
- {
- nowav = TRUE; /* -> Pretend this is no wav-file */
- chat("File not seekable: not checking for WAV-header.\n");
- }
- else
- {
- /* Expect four bytes "RIFF" and four bytes filelength */
- fread (str, 1, 8, anyin); /* 0 */
- str[4] = '\0';
- if (strcmp(str, "RIFF") != 0) nowav = TRUE;
- /* Expect eight bytes "WAVEfmt " */
- fread (str, 1, 8, anyin); /* 8 */
- str[8] = '\0';
- if (strcmp(str, "WAVEfmt ") != 0) nowav = TRUE;
- /* Expect length of fmt data, which should be 16 */
- fread (&tempuint, 4, 1, anyin); /* 16 */
- if (tempuint != 16) nowav = TRUE;
- /* Expect format tag, which should be 1 for pcm */
- fread (&tempushort, 2, 1, anyin); /* 20 */
- if (tempushort != 1)
- nowav = TRUE;
- /* Expect number of channels */
- fread (&cn, 2, 1, anyin); /* 20 */
- if (cn != 1 && cn != 2) nowav = TRUE;
- /* Read samplefrequency */
- fread (&sf, 4, 1, anyin); /* 24 */
- /* Read bytes per second: Should be samplefreq * channels * 2 */
- fread (&tempuint, 4, 1, anyin); /* 28 */
- if (tempuint != sf * cn * 2) nowav = TRUE;
- /* read bytes per frame: Should be channels * 2 */
- fread (&tempushort, 2, 1, anyin); /* 32 */
- if (tempushort != cn * 2) nowav = TRUE;
- /* Read bits per sample: Should be 16 */
- fread (&tempushort, 2, 1, anyin); /* 34 */
- if (tempushort != 16) nowav = TRUE;
- fread (str, 4, 1, anyin); /* 36 */
- str[4] = '\0';
- if (strcmp(str, "data") != 0) nowav = TRUE;
- fread (&tempuint, 4, 1, anyin); /* 40 */
- if (nowav)
- {
- fseek (anyin, 0, SEEK_SET); /* Back to beginning of file */
- chat("File has no WAV header.\n");
- }
- else
- {
- samplefrequency = sf;
- channels = cn;
- chat ("Read WAV header: %d channels, samplefrequency %d.\n",
- channels, samplefrequency);
- iswav = TRUE;
- }
- }
- return;
-}
-
-
-
-/* -----------------------------------------------------------------------
- Write a .WAV header to 'out'. See header for details.
- -----------------------------------------------------------------------*/
-void makewavheader( void)
-{
- unsigned int tempuint, filelength;
- unsigned short tempushort;
-
- /* If fseek fails, don't create the header. */
- if (fseek (out, 0, SEEK_END) != -1)
- {
- filelength = ftell (out);
- chat ("filelength %d, ", filelength);
- fseek (out, 0, SEEK_SET);
- fwrite ("RIFF", 1, 4, out); /* 0 */
- tempuint = filelength - 8; fwrite (&tempuint, 4, 1, out); /* 4 */
- fwrite ("WAVEfmt ", 1, 8, out); /* 8 */
- /* length of fmt data 16 bytes */
- tempuint = 16;
- fwrite (&tempuint, 4, 1, out); /* 16 */
- /* Format tag: 1 for pcm */
- tempushort = 1;
- fwrite (&tempushort, 2, 1, out); /* 20 */
- chat ("%d channels\n", channels);
- fwrite (&channels, 2, 1, out);
- chat ("samplefrequency %d\n", samplefrequency);
- fwrite (&samplefrequency, 4, 1, out); /* 24 */
- /* Bytes per second */
- tempuint = channels * samplefrequency * 2;
- fwrite (&tempuint, 4, 1, out); /* 28 */
- /* Block align */
- tempushort = 2 * channels;
- fwrite (&tempushort, 2, 1, out); /* 32 */
- /* Bits per sample */
- tempushort = 16;
- fwrite (&tempushort, 2, 1, out); /* 34 */
- fwrite ("data", 4, 1, out); /* 36 */
- tempuint = filelength - 44; fwrite (&tempuint, 4, 1, out); /* 40 */
- }
- return;
-}
-
-/* -----------------------------------------------------------------------
- After all is read and done, inform the inclined user of the elapsed time
- -----------------------------------------------------------------------*/
-static void statistics( void)
-{
- int temp;
-
- temp = time(NULL) - stopwatch;
- if (temp != 1)
- {
- inform ("\nTime: %d seconds\n", temp);
- }
- else
- {
- inform ("\nTime: 1 second\n");
- }
- return;
-}
-
-
-/* -----------------------------------------------------------------------
- Start the stopwatch and make sure the user is informed at end of program.
- -----------------------------------------------------------------------*/
-void startstopwatch(void)
-{
- stopwatch = time(NULL); /* Remember time 'now' */
- atexit(statistics); /* Call function statistics() at exit. */
-
- return;
-}
-
-/* --------------------------------------------------------------------
- Tests the character 'coal' for being a command line option character,
- momentarrily '-'.
- -------------------------------------------------------------------- */
-int isoptionchar (char coal)
-{
- return (coal =='-');
-}
-
-/* -----------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as a time and passed
- to *result, where the result is meant to mean 'number of samples' in
- that time.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -----------------------------------------------------------------------*/
-int parsetimearg( int argcount, char *args[], char *string, int *result)
-{
- int i;
-
- if ((i = findoption( argcount, args, string)) > 0)
- {
- if (parsetime(args[i] + 1 + strlen( string), result))
- return TRUE;
- argerrornum(args[i]+1, ME_NOTIME);
- }
- return FALSE;
-}
-
-/* -----------------------------------------------------------------------
- The string argument is read as a time and passed
- to *result, where the result is meant to mean 'number of samples' in
- that time.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -----------------------------------------------------------------------*/
-int parsetime(char *string, int *result)
-{
- int k;
- double temp;
- char m, s, end;
-
- k = sscanf(string, "%lf%c%c%c", &temp, &m, &s, &end);
- switch (k)
- {
- case 0: case EOF: case 4:
- return FALSE;
- case 1:
- *result = temp;
- break;
- case 2:
- if (m == 's')
- *result = temp * samplefrequency;
- else
- return FALSE;
- break;
- case 3:
- if (m == 'm' && s == 's')
- *result = temp * samplefrequency / 1000;
- else if (m == 'H' && s == 'z')
- *result = samplefrequency / temp;
- else
- return FALSE;
- break;
- default:
- argerrornum(NULL, ME_THISCANTHAPPEN);
- }
- return TRUE;
-}
-
-/* -----------------------------------------------------------------------
- The string argument is read as a frequency and passed
- to *result, where the result is meant to mean 'number of samples' in
- one cycle of that frequency.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -----------------------------------------------------------------------*/
-int parsefreq(char *string, double *result)
-{
- int k;
- double temp;
- char m, s, end;
-
- k = sscanf(string, "%lf%c%c%c", &temp, &m, &s, &end);
- switch (k)
- {
- case 0: case EOF: case 2: case 4:
- return FALSE;
- case 1:
- *result = temp;
- break;
- case 3:
- if (m == 'H' && s == 'z')
- *result = samplefrequency / temp;
- else
- return FALSE;
- break;
- default:
- argerrornum(NULL, ME_THISCANTHAPPEN);
- }
- return TRUE;
-}
-
-char *parsefilearg( int argcount, char *args[])
-{
- int i;
- char *result = NULL;
-
- for (i = 1; i < argcount; i++)
- {
- if (args[i][0] != '\0' &&
- (!isoptionchar (args[i][0]) || args[i][1] == '\0' ))
- {
- /*---------------------------------------------*
- * The argument is a filename: *
- * it is either no dash followed by something, *
- * or it is a dash following by nothing. *
- *---------------------------------------------*/
- result = malloc( strlen( args[i]) + 1);
- if (result == NULL)
- fatalperror( "Couldn't allocate memory for filename\n");
- strcpy( result, args[i]);
- args[i][0] = '\0'; /* Mark as used up */
- break;
- }
- }
- return result;
-}
-
-int parseswitch( char *found, char *wanted)
-{
- if (strncmp( found, wanted, strlen( wanted)) == 0)
- {
- if (found[strlen( wanted)] == '\0')
- return TRUE;
- else
- argerrornum( found, ME_NOSWITCH);
- }
- return FALSE;
-}
-
-int parseswitcharg( int argcount, char *args[], char *string)
-{
- int i;
-
- if ((i = findoption( argcount, args, string)) > 0)
- {
- if (args[i][strlen( string) + 1] == '\0')
- return TRUE;
- else
- argerrornum( args[i] + 1, ME_NOSWITCH);
- }
- return FALSE;
-}
-
-int parseintarg( int argcount, char *args[], char *string, int *result)
-{
- int i, temp;
- char c;
-
- if ((i = findoption( argcount, args, string)) > 0)
- {
- switch (sscanf(args[i] + 1 + strlen( string),
- "%d%c", &temp, &c))
- {
- case 0: case EOF: case 2:
- argerrornum(args[i]+1, ME_NOINT);
- return FALSE;
- case 1:
- *result = temp;
- break;
- default:
- say("frame.c: This can't happen\n");
- }
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as a double and
- passed to *result.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -------------------------------------------------------------------- */
-int parsedoublearg( int argcount, char *args[], char *string, double *result)
-{
- int i;
- double temp;
- char end;
-
- if ((i = findoption( argcount, args, string)) > 0)
- {
- switch (sscanf(args[i] + 1 + strlen( string), "%lf%c", &temp, &end))
- {
- case 0: case EOF: case 2:
- argerrornum(args[i]+1, ME_NODOUBLE);
- return FALSE;
- case 1:
- *result = temp;
- break;
- default:
- say("frame.c: This can't happen\n");
- }
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as a volume, i.e.
- absolute, percent or db. The result is passed to *result.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -------------------------------------------------------------------- */
-int parsevolarg( int argcount, char *args[], char *string, double *result)
-{
- double vol = 1.0;
- char sbd, sbb, end;
- int i, weird = FALSE;
-
- if ((i = findoption( argcount, args, string)) > 0)
- {
- switch (sscanf(args[i] + 1 + strlen( string),
- "%lf%c%c%c", &vol, &sbd, &sbb, &end))
- {
- case 0: case EOF: case 4:
- weird = TRUE;
- break; /* No number: error */
- case 1:
- *result = vol;
- break;
- case 2:
- if (sbd == '%')
- *result = vol / 100;
- else
- weird = TRUE; /* One char but no percent: error */
- break;
- case 3:
- if (sbd =='d' && sbb == 'b')
- *result = pow(2, vol / 6.02);
- else
- weird = TRUE; /* Two chars but not db: error */
- break;
- default:
- say("frame.c: This can't happen.\n");
- }
- if (weird)
- argerrornum( args[i] + 1, ME_NOVOL);
- /* ("Weird option: couldn't parse volume '%s'\n", args[i]+2); */
- return !weird;
- }
- else
- {
- return FALSE;
- }
-}
-
-
-/* --------------------------------------------------------------------
- Reads the specified string 's' and interprets it as a volume. The string
- would be of the form 1.8 or 180% or 5db.
- On success, the return value TRUE and *result is given result
- (i.e. the relative volume, i.e. 1.8). On failure, FALSE is returned and
- result is given value 1.0.
- -------------------------------------------------------------------- */
-int parsevolume(char *s, double *result)
-{
- int k;
- char sbd, sbb, end;
-
- *result = 1.0;
- k = sscanf(s, "%lf%c%c%c", result, &sbd, &sbb, &end);
- switch (k)
- {
- case 0:
- case EOF:
- case 4:
- return FALSE;
- case 1:
- break;
- case 2:
- if (sbd != '%')
- return FALSE;
- (*result) /=100;
- break;
- case 3:
- if (sbd !='d' || sbb != 'b')
- return FALSE;
- (*result) = pow(2, (*result) / 6.02);
- break;
- default:
- say("parsevolume: This can't happen (%d).\n", k);
- }
- return TRUE;
-}
-
-/* --------------------------------------------------------------------
- Reports an error due to parsing the string 's' encountered on the
- command line.
- -------------------------------------------------------------------- */
-void argerror(char *s)
-{
- error ("Error parsing command line. Unrecognized option:\n\t-%s\n", s);
- fatalerror("\nTry --help for help.\n");
-}
-
-/* --------------------------------------------------------------------
- Reports an error due to parsing the string 's' encountered on the
- command line. 'code' indicates the type of error.
- -------------------------------------------------------------------- */
-void argerrornum(char *s, Errornum code)
-{
- char *message;
-
- if (code == ME_TOOMANYFILES)
- {
- error("Too many files on command line: '%s'.\n", s);
- }
- else
- {
- if (s != NULL)
- error ("Error parsing option -%s:\n\t", s);
- switch( code)
- {
- case ME_NOINT:
- message = "Integer expected";
- break;
- case ME_NODOUBLE:
- message = "Floating point number expected";
- break;
- case ME_NOTIME:
- message = "Time argument expected";
- break;
- case ME_NOVOL:
- message = "Volume argument expected";
- break;
- case ME_NOSWITCH:
- message = "Garbage after switch-type option";
- break;
- case ME_HEADERONTEXTFILE:
- message = "Option -h is not useful for text-output";
- break;
- case ME_NOINFILE:
- message = "No input file specified";
- break;
- case ME_NOOUTFILE:
- message = "No output file specified";
- break;
- case ME_NOIOFILE:
- message = "No input/output file specified";
- break;
- case ME_NOSTDIN:
- message = "Standard in not supported here";
- break;
- case ME_NOSTDOUT:
- message = "Standard out not supported here";
- break;
- case ME_NOSTDIO:
- message = "Standard in/out not supported here";
- break;
- case ME_NOTENOUGHFILES:
- message = "Not enough files specified";
- break;
- case ME_THISCANTHAPPEN:
- fatalerror("\nThis can't happen. Report this as a bug\n");
- /* fatalerror does not return */
- default:
- error("Error code %d not implemented. Fix me!\n", code);
- message = "Error message not implemented. Fix me!";
- }
- error("%s\n", message);
- }
- fatalerror("\nTry --help for help.\n");
-}
-
-/* --------------------------------------------------------------------
- Reports an error due to parsing the string 's' encountered on the
- command line. 'message' explains the type of error.
- -------------------------------------------------------------------- */
-void argerrortxt(char *s, char *message)
-{
- if (s != NULL)
- error ("Error parsing option -%s:\n\t", s);
- else
- error ("Error parsing command line:\n\t");
- error ("%s\n", message);
- fatalerror("\nTry --help for help.\n");
-}
-
-/* --------------------------------------------------------------------
- Check for any remaining arguments and complain about their existence
- -------------------------------------------------------------------- */
-void checknoargs( int argcount, char *args[])
-{
- int i, errorcount = 0;
-
- for (i = 1; i < argcount; i++)
- {
- if (args[i][0] != '\0') /* An unused argument! */
- {
- errorcount++;
- if (errorcount == 1)
- error("The following arguments were not recognized:\n");
- error("\t%s\n", args[i]);
- }
- }
- if (errorcount > 0) /* Errors are fatal */
- fatalerror("\nTry --help for help.\n");
-
- return; /* No errors? Return. */
-}
-
-/* --------------------------------------------------------------------
- Parses the command line arguments as represented by the function
- arguments. Sets the global variables 'in', 'out', 'samplefrequency'
- and 'samplewidth' accordingly. Also verboselevel.
- The files 'in' and 'out' are even opened according to 'fileswitch'.
- See headerfile for details
- -------------------------------------------------------------------- */
-void parseargs( int argcount, char *args[], int fileswitch)
-{
- char *filename;
- int tempint;
-
- if ((fileswitch & 1) != 0) /* If getting infile */
- in = NULL;
- if ((fileswitch & 4) != 0) /* If getting outfile */
- out = NULL;
- wavout = FALSE;
- verboselevel = 5;
- samplefrequency = DEFAULTFREQ;
- samplewidth = 2;
- channels = 1;
-
- /*-----------------------------------------------*
- * First first check testcase, usage and version *
- *-----------------------------------------------*/
- test_usage = parseswitcharg( argcount, args, "-test-usage");
- if (parseswitcharg( argcount, args, "-help"))
- {
- printf("%s%s", usage, standardusage);
- exit(0);
- }
- if (parseswitcharg( argcount, args, "-version"))
- {
- printf("%s\n(%s)\n", version, standardversion);
- exit(0);
- }
- /*--------------------------------------*
- * Set verboselevel *
- *--------------------------------------*/
- while (parseswitcharg( argcount, args, "V"))
- verboselevel = 10;
- while (parseswitcharg( argcount, args, "Q"))
- verboselevel = 1;
- /*-------------------------------------------------*
- * Get filenames and open files *
- *-------------------------------------------------*/
- if ((fileswitch & 1) != 0) /* Infile wanted */
- {
- infilename = parsefilearg( argcount, args);
- if (infilename == NULL)
- argerrornum( NULL, ME_NOINFILE);
- if (strcmp( infilename, "-") == 0)
- {
- infilename = "<stdin>";
- in = stdin;
- if ((fileswitch & 2) != 0) /* Binfile wanted */
- readwavheader( in);
- }
- else
- {
- if ((fileswitch & 2) == 0) /* Textfile wanted */
- in = fopen(infilename, "rt");
- else /* Binfile wanted */
- if ((in = fopen(infilename, "rb")) != NULL)
- readwavheader( in);
- }
- if (in == NULL)
- fatalerror("Error opening input file '%s': %s\n", infilename,strerror(errno));
- else
- inform("Using file '%s' as input\n", infilename);
- }
- if ((fileswitch & 4) != 0) /* Outfile wanted */
- {
- outfilename = parsefilearg( argcount, args);
- if (outfilename == NULL)
- argerrornum( NULL, ME_NOOUTFILE);
- if (strcmp( outfilename, "-") == 0)
- {
- outfilename = "<stdout>";
- out = stdout;
- }
- else
- {
-
- if ((fileswitch & 8) == 0) /* Textfile wanted */
- out = fopen(outfilename, "wt");
- else /* Binfile wanted */
- out = fopen(outfilename, "wb");
- }
- if (out == NULL)
- fatalerror("Error opening output file '%s': %s\n", outfilename,strerror(errno));
- else
- inform("Using file '%s' as output\n", outfilename);
- }
- if ((fileswitch & 32) != 0) /* In-/Outfile wanted */
- {
- assert (in == NULL && out == NULL);
- infilename = outfilename = parsefilearg( argcount, args);
- if (outfilename == NULL)
- argerrornum( NULL, ME_NOIOFILE);
- if (strcmp( infilename, "-") == 0)
- argerrornum( infilename, ME_NOSTDIN);
- inform("Using file '%s' as input/output\n", outfilename);
- in = out = fopen(outfilename, "r+");
- if (out == NULL)
- fatalerror("Error opening input/output file '%s': %s\n", outfilename,strerror(errno));
-
- readwavheader( in);
- }
- if ((fileswitch & 16) == 0) /* No additional files wanted */
- {
- if ((filename = parsefilearg( argcount, args)) != NULL)
- argerrornum( filename, ME_TOOMANYFILES);
- }
-
- /*-------------------------------------------------*
- * Set samplefrequency, width, wavout,
- *-------------------------------------------------*/
- parseintarg( argcount, args, "f", &samplefrequency);
- wavout = parseswitcharg( argcount, args, "h");
- if (parseintarg( argcount, args, "w", &tempint))
- {
- if (tempint != 16)
- argerrortxt(NULL, "Option -w is only valid "
- "with value 16. Sorry.");
- else
- samplewidth = tempint;
- }
- if (parseintarg( argcount, args, "c", &tempint))
- {
- if (tempint != 1 && tempint != 2)
- argerrortxt(NULL, "Option -c is only valid "
- "with values 1 or 2. Sorry.");
- else
- channels = tempint;
- }
- /*-------------------------------------------------*
- * Create WAV-header on output if wanted. *
- *-------------------------------------------------*/
- if (wavout)
- switch (fileswitch & (12))
- {
- case 4: /* User wants header on textfile */
- argerrornum( NULL, ME_HEADERONTEXTFILE);
- case 12: /* User wants header on binfile */
- makewavheader();
- break;
- case 0: /* User wants header, but there is no outfile */
- /* Problem: what about i/o-file, 32? You might want a header
- on that? Better ignore this case. */
- break;
- case 8: /* An application musn't ask for this */
- default: /* This can't happen */
- assert( FALSE);
- }
- return;
-}
-
-/* --------------------------------------------------------------------
- Returns the index 'i' of the first argument that IS an option, and
- which begins with the label 's'. If there is none, -1.
- We also mark that option as done with, i.e. we cross it out.
- -------------------------------------------------------------------- */
-int findoption( int argcount, char *args[], char *s)
-{
- int i;
-
- if (test_usage)
- printf("Checking for option -%s\n", s);
-
- for (i=1; i<argcount; i++)
- {
- if (isoptionchar (args[i][0]) &&
- strncmp( args[i] + 1, s, strlen( s)) == 0)
- {
- args[i][0] = '\0';
- return i;
- }
- }
- return -1;
-}
-
-/* --------------------------------------------------------------------
- Finishes off the .WAV header (if any) and exits correctly and formerly.
- -------------------------------------------------------------------- */
-int myexit (int value)
-{
- switch (value)
- {
- case 0:
- if (wavout)
- makewavheader(); /* Writes a fully informed .WAV header */
- chat ("Success!\n");
- break;
- default:
- chat ("Failure.\n");
- break;
- }
- exit (value);
-}
-
-/* --------------------------------------------------------------------
- Reads the stated input file bufferwise, calls the function 'work'
- with the proper values, and writes the result to the stated output file.
- Return value: TRUE on success, FALSE otherwise.
- -------------------------------------------------------------------- */
-int workloop( FILE *theinfile, FILE *theoutfile,
- int (*work)( short *buffer, int length) )
-{
- short *buffer;
- int length, nowlength;
-
- length = BUFFSIZE;
- if ((buffer = malloc( sizeof(short) * length)) == NULL)
- fatalperror ("");
- while (TRUE)
- {
- nowlength = fread(buffer, sizeof(short), length, theinfile);
- if (ferror( theinfile) != 0)
- fatalperror("Error reading input file");
- if (nowlength == 0) /* Reached end of input file */
- break;
- /* Call the routine that does the work */
- if (!work (buffer, nowlength)) /* On error, stop. */
- return FALSE;
- fwrite(buffer, sizeof(short), nowlength, theoutfile);
- if (ferror( theoutfile) != 0)
- fatalperror("Error writing to output file");
- }
- return TRUE; /* Input file done with, no errors. */
-}
-
-int chat( const char *format, ...)
-{
- va_list ap;
- int result = 0;
-
- if (verboselevel > 5)
- {
- va_start( ap, format);
- result = vfprintf( stderr, format, ap);
- va_end( ap);
- }
- return result;
-}
-
-
-int inform( const char *format, ...)
-{
- va_list ap;
- int result = 0;
-
- if (verboselevel > 1)
- {
- va_start( ap, format);
- result = vfprintf( stderr, format, ap);
- va_end( ap);
- }
- return result;
-}
-
-int error( const char *format, ...)
-{
- va_list ap;
- int result;
-
- va_start( ap, format);
- result = vfprintf( stderr, format, ap);
- va_end( ap);
- return result;
-}
-
-void fatalerror( const char *format, ...)
-{
- va_list ap;
-
- va_start( ap, format);
- vfprintf( stderr, format, ap);
- va_end( ap);
- myexit(1);
-}
-
-void fatalperror( const char *string)
-{
- perror( string);
- myexit( 1);
-}
-
-int say( const char *format, ...)
-{
- va_list ap;
- int result;
-
- va_start( ap, format);
- result = vfprintf( stdout, format, ap);
- va_end( ap);
- return result;
-}
-
-
-char *malloccopy( char *string)
-{
- char *result;
-
- result = malloc( strlen( string) + 1);
- if (result != NULL)
- strcpy( result, string);
- return result;
-}
-
-
-char *mallocconcat( char *one, char *two)
-{
- char *result;
-
- result = malloc( strlen( one) + strlen( two) + 1);
- if (result != NULL)
- {
- strcpy( result, one);
- strcat( result, two);
- }
- return result;
-}
-
-double double2db( double value)
-{
- if (value < 0)
- value = -value;
- return 6.0 * log( value / 32767) / log( 2);
-}
-
-void readawaysamples( FILE *in, size_t size)
-{
- short *buffer;
- int samplesread, count;
-
- buffer = malloc( sizeof( *buffer) * BUFFSIZE);
- if (buffer == NULL) fatalperror("Couldn't allocate buffer");
-
- while (size > 0)
- {
- if (size > BUFFSIZE)
- count = BUFFSIZE;
- else
- count = size;
-
- samplesread = fread( buffer, sizeof(*buffer), count, in);
- if (ferror( in) != 0)
- fatalperror("Error reading input file");
- size -= samplesread;
- }
- free( buffer);
-}
-
diff --git a/1.4/utils/frame.h b/1.4/utils/frame.h
deleted file mode 100644
index a07c605ec..000000000
--- a/1.4/utils/frame.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/****************************************************************************
- *
- * Programs for processing sound files in raw- or WAV-format.
- * -- Useful functions for parsing command line options and
- * issuing errors, warnings, and chit chat.
- *
- * Name: frame.h
- * Version: see frame.c
- * Author: Mark Roberts <mark@manumark.de>
- *
- ****************************************************************************/
-/****************************************************************************
- * These are useful functions that all DSP programs might find handy
- ****************************************************************************/
-
-/* fileswitch for parseargs:
-
- The following are masks for several different ways of opening files.
- --------------------------------------------------------------------
- Bit 0: Open infile?
- Bit 1: Open infile as binary (as opposed to text)
- Bit 2: Open outfile?
- Bit 3: Open outfile as binary (as opposed to text)
- Bit 4: Do not complain about too many file arguments
- Bit 5: Open one file for input AND output, binary.
-*/
-#define INTEXT (1+0)
-#define INBIN (1+2)
-#define OUTTEXT (4)
-#define OUTBIN (4+8)
-#define NOFILES (0)
-#define NOCOMPLAIN (16)
-#define IOBIN (32)
-
-#ifndef FALSE
- #define FALSE (0==1)
- #define TRUE (0==0)
-#endif
-
-extern int samplefrequency;
-extern unsigned short samplewidth;
-extern unsigned short channels;
-extern int wavout; /* TRUE iff out file is .WAV file */
-extern int iswav; /* TRUE iff in file was found to be a .WAV file */
-extern FILE *in, *out;
-extern char *infilename, *outfilename;
-extern int verboselevel;
-extern char *version; /* String to be issued as version string. Should
- be set by application. */
-extern char *usage; /* String to be issued as usage string. Should be
- set by application. */
-
-#define DEFAULTFREQ 44100
-#define BUFFSIZE 50000 /* How many samples to read in one go (preferred) */
-#define MINBUFFSIZE 5000 /* How many samples to read in one go (minimum) */
-
-/*************************************************
- * Types of errors handled by argerrornum() *
- *************************************************/
-typedef enum
-{
- ME_NOINT,
- ME_NODOUBLE,
- ME_NOTIME,
- ME_NOVOL,
- ME_NOSWITCH,
- ME_TOOMANYFILES,
- ME_HEADERONTEXTFILE,
- ME_NOINFILE,
- ME_NOOUTFILE,
- ME_NOIOFILE,
- ME_NOSTDIN,
- ME_NOSTDOUT,
- ME_NOSTDIO,
- ME_NOTENOUGHFILES,
- ME_THISCANTHAPPEN
-} Errornum;
-
-
-/* -----------------------------------------------------------------------
- Create memory and copy 'string', returning a pointer to the copy.
- NULL is returned if malloc fails.
- -----------------------------------------------------------------------*/
-extern char *malloccopy( char *string);
-
-/* -----------------------------------------------------------------------
- Start the stopwatch and make sure the user is informed at end of program.
- -----------------------------------------------------------------------*/
-extern void startstopwatch(void);
-
-/* -----------------------------------------------------------------------
- Writes the number of samples to result that are yet to be read from anyin.
- I.e. the number of remaining bytes is divided by the number of bytes per
- sample value, but not by the number of channels.
- Return values are TRUE on success, FALSE on failure.
- -----------------------------------------------------------------------*/
-extern int getremainingfilelength( FILE *anyin, long *result);
-
-/* -----------------------------------------------------------------------
- Read a .pk-header from 'anyin' and printf the entries.
- -----------------------------------------------------------------------*/
-void readpkheader( FILE *anyin);
-
-/* -----------------------------------------------------------------------
- Read a .WAV header from 'anyin'.
- If it is recognised, the data is used.
- Otherwise, we assume it's PCM-data and ignore the header.
- The global variable 'iswav' is set on success, otherwise cleared.
- -----------------------------------------------------------------------*/
-extern void readwavheader( FILE *anyin);
-
-/* -----------------------------------------------------------------------
- Write a .WAV header to 'out'.
- The filepointer is placed at the end of 'out' before operation.
- This should be called before any data is
- written, and again, when ALL the data has been written.
- First time, this positions the file pointer correctly; second time, the
- missing data can be inserted that wasn't known the first time round.
- -----------------------------------------------------------------------*/
-extern void makewavheader( void);
-
-/* --------------------------------------------------------------------
- Tests the character 'coal' for being a command line option character,
- momentarrily '/' or '-'.
- -------------------------------------------------------------------- */
-extern int isoptionchar (char coal);
-
-/* -----------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as a time and passed
- to *result, where the result is meant to mean 'number of samples' in
- that time.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -----------------------------------------------------------------------*/
-extern int parsetimearg( int argcount, char *args[], char *string,
- int *result);
-
-/* -----------------------------------------------------------------------
- The string argument is read as a time and passed to *result, where
- the result is meant to mean 'number of samples' in that time. On
- failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -----------------------------------------------------------------------*/
-int parsetime(char *string, int *result);
-
-/* -----------------------------------------------------------------------
- The string argument is read as a frequency and passed
- to *result, where the result is meant to mean 'number of samples' in
- one cycle of that frequency.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -----------------------------------------------------------------------*/
-int parsefreq(char *string, double *result);
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for a switch -'string'.
- return value is TRUE if one exists, FALSE otherwise.
- If characters remain after the switch, a fatal error is issued.
- -------------------------------------------------------------------- */
-extern int parseswitcharg( int argcount, char *args[], char *string);
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as an integer and
- passed to &result.
- On failure, &result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -------------------------------------------------------------------- */
-extern int parseintarg( int argcount, char *args[], char *string,
- int *result);
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for a filename, i.e. anything
- that does not start with the optionchar. The filename is copied to
- newly allocated memory, a pointer to which is returned.
- The argument is marked as used. Therefore repeated use of this function
- will yield a complete list of filenames on the commandline.
- If malloc() fails, the function does not return.
- -------------------------------------------------------------------- */
-extern char *parsefilearg( int argcount, char *args[]);
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as a double and
- passed to *result.
- On failure, *result is unchanged.
- return value is TRUE on success, FALSE otherwise.
- -------------------------------------------------------------------- */
-extern int parsedoublearg( int argcount, char *args[], char *string,
- double *result);
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for an option starting
- with 'string'. The rest of the option is read as a volume, i.e.
- absolute, percent or db. The result is passed to *result.
- On failure, *result is unchanged.
- -------------------------------------------------------------------- */
-extern int parsevolarg( int argcount, char *args[], char *string,
- double *result);
-
-/* --------------------------------------------------------------------
- Reads the specified string and interprets it as a volume. The string
- would be of the form 1.8 or 180% or 5db.
- On success, the return value is the relative volume, i.e. 1.8
- On failure, -1 is returned.
- -------------------------------------------------------------------- */
-extern int parsevolume(char *s, double *result);
-
-/* --------------------------------------------------------------------
- Reads through the arguments on the lookout for a switch -'string'.
- return value is TRUE if one exists, FALSE otherwise.
- If characters remain after the switch, a fatal error is issued.
- -------------------------------------------------------------------- */
-extern int parseswitch( char *found, char *wanted);
-
-/* --------------------------------------------------------------------
- Reports an error due to parsing the string 's' encountered on the
- command line.
- -------------------------------------------------------------------- */
-extern void argerror(char *s);
-
-/* --------------------------------------------------------------------
- Reports an error due to parsing the string 's' encountered on the
- command line. 'code' indicates the type of error.
- -------------------------------------------------------------------- */
-extern void argerrornum(char *s, Errornum code);
-
-/* --------------------------------------------------------------------
- Reports an error due to parsing the string 's' encountered on the
- command line. 'message' explains the type of error.
- -------------------------------------------------------------------- */
-extern void argerrortxt(char *s, char *message);
-
-/* --------------------------------------------------------------------
- Check for any remaining arguments and complain about their existence.
- If arguments are found, this function does not return.
- -------------------------------------------------------------------- */
-extern void checknoargs( int argcount, char *args[]);
-
-/* --------------------------------------------------------------------
- Parses the command line arguments as represented by the function
- arguments. Sets the global variables 'in', 'out', 'samplefrequency'
- and 'samplewidth' accordingly.
- According to 'fileswitch', in and out files are opened or not. See
- above for an explanation of 'fileswitch'.
- -------------------------------------------------------------------- */
-extern void parseargs( int argcount, char *args[], int fileswitch);
-
-/* --------------------------------------------------------------------
- Returns the index 'i' of the first argument that IS an option, and
- which begins with the label 's'. If there is none, -1.
- We also mark that option as done with, i.e. we cross it out.
- -------------------------------------------------------------------- */
-extern int findoption( int argcount, char *args[], char *s);
-
-/* --------------------------------------------------------------------
- Finishes off the .WAV header (if any) and exits correctly and formerly.
- -------------------------------------------------------------------- */
-extern int myexit (int value);
-
-/* --------------------------------------------------------------------
- Reads the stated input file bufferwise, calls the function 'work'
- with the proper values, and writes the result to the stated output file.
- Return value: TRUE on success, FALSE otherwise.
- -------------------------------------------------------------------- */
-extern int workloop( FILE *theinfile, FILE *theoutfile,
- int (*work)( short *buffer, int length) );
-
-/* --------------------------------------------------------------------
- Five functions for printing to stderr. Depending on the level of verbose,
- output may be supressed. fatalerror() is like error() but does not return.
- fatalperror() is like the standard function perror() but does not return.
- -------------------------------------------------------------------- */
-extern int chat( const char *format, ...);
-extern int inform( const char *format, ...);
-extern int error( const char *format, ...);
-extern void fatalerror( const char *format, ...);
-extern void fatalperror( const char *string);
-
-/* --------------------------------------------------------------------
- And one functions for printing to stdout.
- -------------------------------------------------------------------- */
-extern int say( const char *format, ...);
-
-/* --------------------------------------------------------------------
- Allocate memory for it and return a pointer to a string made up of
- the two argument strings.
- -------------------------------------------------------------------- */
-extern char *mallocconcat( char *one, char *two);
-
-/* --------------------------------------------------------------------
- Convert a sample value to decibel.
- -------------------------------------------------------------------- */
-extern double double2db( double value);
-
-/* --------------------------------------------------------------------
- Read 'size' samples from file 'in' and lose them.
- -------------------------------------------------------------------- */
-extern void readawaysamples( FILE *in, size_t size);
diff --git a/1.4/utils/muted.c b/1.4/utils/muted.c
deleted file mode 100644
index c406258e1..000000000
--- a/1.4/utils/muted.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Updated for Mac OSX CoreAudio
- * by Josh Roberson <josh@asteriasgi.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.
- */
-
-/*! \file
- *
- * \brief Mute Daemon
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * Updated for Mac OSX CoreAudio
- * \arg Josh Roberson <josh@asteriasgi.com>
- *
- * \note Specially written for Malcolm Davenport, but I think I'll use it too
- * Connects to the Asterisk Manager Interface, AMI, and listens for events
- * on certain devices. If a phone call is connected to one of the devices (phones)
- * the local sound is muted to a lower volume during the call.
- *
- */
-
-#ifdef __Darwin__
-#include <CoreAudio/AudioHardware.h>
-#elif defined(__linux__) || defined(__FreeBSD__)
-#include <sys/soundcard.h>
-#endif
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-static char *config = "/etc/asterisk/muted.conf";
-
-static char host[256] = "";
-static char user[256] = "";
-static char pass[256] = "";
-static int smoothfade = 0;
-static int mutelevel = 20;
-static int muted = 0;
-static int needfork = 1;
-static int debug = 0;
-static int stepsize = 3;
-#ifndef __Darwin__
-static int mixchan = SOUND_MIXER_VOLUME;
-#endif
-
-struct subchannel {
- char *name;
- struct subchannel *next;
-};
-
-static struct channel {
- char *tech;
- char *location;
- struct channel *next;
- struct subchannel *subs;
-} *channels;
-
-static void add_channel(char *tech, char *location)
-{
- struct channel *chan;
- chan = malloc(sizeof(struct channel));
- if (chan) {
- memset(chan, 0, sizeof(struct channel));
- if (!(chan->tech = strdup(tech))) {
- free(chan);
- return;
- }
- if (!(chan->location = strdup(location))) {
- free(chan->tech);
- free(chan);
- return;
- }
- chan->next = channels;
- channels = chan;
- }
-
-}
-
-static int load_config(void)
-{
- FILE *f;
- char buf[1024];
- char *val;
- char *val2;
- int lineno=0;
- int x;
- f = fopen(config, "r");
- if (!f) {
- fprintf(stderr, "Unable to open config file '%s': %s\n", config, strerror(errno));
- return -1;
- }
- while(!feof(f)) {
- fgets(buf, sizeof(buf), f);
- if (!feof(f)) {
- lineno++;
- val = strchr(buf, '#');
- if (val) *val = '\0';
- while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
- buf[strlen(buf) - 1] = '\0';
- if (!strlen(buf))
- continue;
- val = buf;
- while(*val) {
- if (*val < 33)
- break;
- val++;
- }
- if (*val) {
- *val = '\0';
- val++;
- while(*val && (*val < 33)) val++;
- }
- if (!strcasecmp(buf, "host")) {
- if (val && strlen(val))
- strncpy(host, val, sizeof(host) - 1);
- else
- fprintf(stderr, "host needs an argument (the host) at line %d\n", lineno);
- } else if (!strcasecmp(buf, "user")) {
- if (val && strlen(val))
- strncpy(user, val, sizeof(user) - 1);
- else
- fprintf(stderr, "user needs an argument (the user) at line %d\n", lineno);
- } else if (!strcasecmp(buf, "pass")) {
- if (val && strlen(val))
- strncpy(pass, val, sizeof(pass) - 1);
- else
- fprintf(stderr, "pass needs an argument (the password) at line %d\n", lineno);
- } else if (!strcasecmp(buf, "smoothfade")) {
- smoothfade = 1;
- } else if (!strcasecmp(buf, "mutelevel")) {
- if (val && (sscanf(val, "%d", &x) == 1) && (x > -1) && (x < 101)) {
- mutelevel = x;
- } else
- fprintf(stderr, "mutelevel must be a number from 0 (most muted) to 100 (no mute) at line %d\n", lineno);
- } else if (!strcasecmp(buf, "channel")) {
- if (val && strlen(val)) {
- val2 = strchr(val, '/');
- if (val2) {
- *val2 = '\0';
- val2++;
- add_channel(val, val2);
- } else
- fprintf(stderr, "channel needs to be of the format Tech/Location at line %d\n", lineno);
- } else
- fprintf(stderr, "channel needs an argument (the channel) at line %d\n", lineno);
- } else {
- fprintf(stderr, "ignoring unknown keyword '%s'\n", buf);
- }
- }
- }
- fclose(f);
- if (!strlen(host))
- fprintf(stderr, "no 'host' specification in config file\n");
- else if (!strlen(user))
- fprintf(stderr, "no 'user' specification in config file\n");
- else if (!channels)
- fprintf(stderr, "no 'channel' specifications in config file\n");
- else
- return 0;
- return -1;
-}
-
-static FILE *astf;
-#ifndef __Darwin__
-static int mixfd;
-
-static int open_mixer(void)
-{
- mixfd = open("/dev/mixer", O_RDWR);
- if (mixfd < 0) {
- fprintf(stderr, "Unable to open /dev/mixer: %s\n", strerror(errno));
- return -1;
- }
- return 0;
-}
-#endif /* !__Darwin */
-
-/*! Connect to the asterisk manager interface */
-static int connect_asterisk(void)
-{
- int sock;
- struct hostent *hp;
- char *ports;
- int port = 5038;
- struct sockaddr_in sin;
-
- ports = strchr(host, ':');
- if (ports) {
- *ports = '\0';
- ports++;
- if ((sscanf(ports, "%d", &port) != 1) || (port < 1) || (port > 65535)) {
- fprintf(stderr, "'%s' is not a valid port number in the hostname\n", ports);
- return -1;
- }
- }
- hp = gethostbyname(host);
- if (!hp) {
- fprintf(stderr, "Can't find host '%s'\n", host);
- return -1;
- }
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
- return -1;
- }
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
- fprintf(stderr, "Failed to connect to '%s' port '%d': %s\n", host, port, strerror(errno));
- close(sock);
- return -1;
- }
- astf = fdopen(sock, "r+");
- if (!astf) {
- fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
- close(sock);
- return -1;
- }
- return 0;
-}
-
-static char *get_line(void)
-{
- static char buf[1024];
- if (fgets(buf, sizeof(buf), astf)) {
- while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
- buf[strlen(buf) - 1] = '\0';
- return buf;
- } else
- return NULL;
-}
-
-/*! Login to the asterisk manager interface */
-static int login_asterisk(void)
-{
- char *welcome;
- char *resp;
- if (!(welcome = get_line())) {
- fprintf(stderr, "disconnected (1)\n");
- return -1;
- }
- fprintf(astf,
- "Action: Login\r\n"
- "Username: %s\r\n"
- "Secret: %s\r\n\r\n", user, pass);
- if (!(welcome = get_line())) {
- fprintf(stderr, "disconnected (2)\n");
- return -1;
- }
- if (strcasecmp(welcome, "Response: Success")) {
- fprintf(stderr, "login failed ('%s')\n", welcome);
- return -1;
- }
- /* Eat the rest of the event */
- while((resp = get_line()) && strlen(resp));
- if (!resp) {
- fprintf(stderr, "disconnected (3)\n");
- return -1;
- }
- fprintf(astf,
- "Action: Status\r\n\r\n");
- if (!(welcome = get_line())) {
- fprintf(stderr, "disconnected (4)\n");
- return -1;
- }
- if (strcasecmp(welcome, "Response: Success")) {
- fprintf(stderr, "status failed ('%s')\n", welcome);
- return -1;
- }
- /* Eat the rest of the event */
- while((resp = get_line()) && strlen(resp));
- if (!resp) {
- fprintf(stderr, "disconnected (5)\n");
- return -1;
- }
- return 0;
-}
-
-static struct channel *find_channel(char *channel)
-{
- char tmp[256] = "";
- char *s, *t;
- struct channel *chan;
- strncpy(tmp, channel, sizeof(tmp) - 1);
- s = strchr(tmp, '/');
- if (s) {
- *s = '\0';
- s++;
- t = strrchr(s, '-');
- if (t) {
- *t = '\0';
- }
- if (debug)
- printf("Searching for '%s' tech, '%s' location\n", tmp, s);
- chan = channels;
- while(chan) {
- if (!strcasecmp(chan->tech, tmp) && !strcasecmp(chan->location, s)) {
- if (debug)
- printf("Found '%s'/'%s'\n", chan->tech, chan->location);
- break;
- }
- chan = chan->next;
- }
- } else
- chan = NULL;
- return chan;
-}
-
-#ifndef __Darwin__
-static int getvol(void)
-{
- int vol;
-
- if (ioctl(mixfd, MIXER_READ(mixchan), &vol)) {
-#else
-static float getvol(void)
-{
- float volumeL, volumeR, vol;
- OSStatus err;
- AudioDeviceID device;
- UInt32 size;
- UInt32 channels[2];
-
- size = sizeof(device);
- err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device);
- size = sizeof(channels);
- if (!err)
- err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels);
- size = sizeof(vol);
- if (!err)
- err = AudioDeviceGetProperty(device, channels[0], false, kAudioDevicePropertyVolumeScalar, &size, &volumeL);
- if (!err)
- err = AudioDeviceGetProperty(device, channels[1], false, kAudioDevicePropertyVolumeScalar, &size, &volumeR);
- if (!err)
- vol = (volumeL < volumeR) ? volumeR : volumeL;
- else {
-#endif
- fprintf(stderr, "Unable to read mixer volume: %s\n", strerror(errno));
- return -1;
- }
- return vol;
-}
-
-#ifndef __Darwin__
-static int setvol(int vol)
-#else
-static int setvol(float vol)
-#endif
-{
-#ifndef __Darwin__
- if (ioctl(mixfd, MIXER_WRITE(mixchan), &vol)) {
-#else
- float volumeL = vol;
- float volumeR = vol;
- OSStatus err;
- AudioDeviceID device;
- UInt32 size;
- UInt32 channels[2];
-
- size = sizeof(device);
- err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device);
- size = sizeof(channels);
- err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels);
- size = sizeof(vol);
- if (!err)
- err = AudioDeviceSetProperty(device, 0, channels[0], false, kAudioDevicePropertyVolumeScalar, size, &volumeL);
- if (!err)
- err = AudioDeviceSetProperty(device, 0, channels[1], false, kAudioDevicePropertyVolumeScalar, size, &volumeR);
- if (err) {
-#endif
-
- fprintf(stderr, "Unable to write mixer volume: %s\n", strerror(errno));
- return -1;
-
- }
- return 0;
-}
-
-#ifndef __Darwin__
-static int oldvol = 0;
-static int mutevol = 0;
-#else
-static float oldvol = 0;
-static float mutevol = 0;
-#endif
-
-#ifndef __Darwin__
-static int mutedlevel(int orig, int mutelevel)
-{
- int l = orig >> 8;
- int r = orig & 0xff;
- l = (float)(mutelevel) * (float)(l) / 100.0;
- r = (float)(mutelevel) * (float)(r) / 100.0;
-
- return (l << 8) | r;
-#else
-static float mutedlevel(float orig, float mutelevel)
-{
- float master = orig;
- master = mutelevel * master / 100.0;
- return master;
-#endif
-
-}
-
-static void mute(void)
-{
-#ifndef __Darwin__
- int vol;
- int start;
- int x;
-#else
- float vol;
- float start = 1.0;
- float x;
-#endif
- vol = getvol();
- oldvol = vol;
- if (smoothfade)
-#ifdef __Darwin__
- start = mutelevel;
-#else
- start = 100;
- else
- start = mutelevel;
-#endif
- for (x=start;x>=mutelevel;x-=stepsize) {
- mutevol = mutedlevel(vol, x);
- setvol(mutevol);
- /* Wait 0.01 sec */
- usleep(10000);
- }
- mutevol = mutedlevel(vol, mutelevel);
- setvol(mutevol);
- if (debug)
-#ifdef __Darwin__
- printf("Mute from '%f' to '%f'!\n", oldvol, mutevol);
-#else
- printf("Mute from '%04x' to '%04x'!\n", oldvol, mutevol);
-#endif
- muted = 1;
-}
-
-static void unmute(void)
-{
-#ifdef __Darwin__
- float vol;
- float start;
- float x;
-#else
- int vol;
- int start;
- int x;
-#endif
- vol = getvol();
- if (debug)
-#ifdef __Darwin__
- printf("Unmute from '%f' (should be '%f') to '%f'!\n", vol, mutevol, oldvol);
- mutevol = vol;
- if (vol == mutevol) {
-#else
- printf("Unmute from '%04x' (should be '%04x') to '%04x'!\n", vol, mutevol, oldvol);
- if ((int)vol == mutevol) {
-#endif
- if (smoothfade)
- start = mutelevel;
- else
-#ifdef __Darwin__
- start = 1.0;
-#else
- start = 100;
-#endif
- for (x=start;x<100;x+=stepsize) {
- mutevol = mutedlevel(oldvol, x);
- setvol(mutevol);
- /* Wait 0.01 sec */
- usleep(10000);
- }
- setvol(oldvol);
- } else
- printf("Whoops, it's already been changed!\n");
- muted = 0;
-}
-
-static void check_mute(void)
-{
- int offhook = 0;
- struct channel *chan;
- chan = channels;
- while(chan) {
- if (chan->subs) {
- offhook++;
- break;
- }
- chan = chan->next;
- }
- if (offhook && !muted)
- mute();
- else if (!offhook && muted)
- unmute();
-}
-
-static void delete_sub(struct channel *chan, char *name)
-{
- struct subchannel *sub, *prev;
- prev = NULL;
- sub = chan->subs;
- while(sub) {
- if (!strcasecmp(sub->name, name)) {
- if (prev)
- prev->next = sub->next;
- else
- chan->subs = sub->next;
- free(sub->name);
- free(sub);
- return;
- }
- prev = sub;
- sub = sub->next;
- }
-}
-
-static void append_sub(struct channel *chan, char *name)
-{
- struct subchannel *sub;
- sub = chan->subs;
- while(sub) {
- if (!strcasecmp(sub->name, name))
- return;
- sub = sub->next;
- }
- sub = malloc(sizeof(struct subchannel));
- if (sub) {
- memset(sub, 0, sizeof(struct subchannel));
- if (!(sub->name = strdup(name))) {
- free(sub);
- return;
- }
- sub->next = chan->subs;
- chan->subs = sub;
- }
-}
-
-static void hangup_chan(char *channel)
-{
- struct channel *chan;
- if (debug)
- printf("Hangup '%s'\n", channel);
- chan = find_channel(channel);
- if (chan)
- delete_sub(chan, channel);
- check_mute();
-}
-
-static void offhook_chan(char *channel)
-{
- struct channel *chan;
- if (debug)
- printf("Offhook '%s'\n", channel);
- chan = find_channel(channel);
- if (chan)
- append_sub(chan, channel);
- check_mute();
-}
-
-static int wait_event(void)
-{
- char *resp;
- char event[120]="";
- char channel[120]="";
- char oldname[120]="";
- char newname[120]="";
-
- resp = get_line();
- if (!resp) {
- fprintf(stderr, "disconnected (6)\n");
- return -1;
- }
- if (!strncasecmp(resp, "Event: ", strlen("Event: "))) {
- strncpy(event, resp + strlen("Event: "), sizeof(event) - 1);
- /* Consume the rest of the non-event */
- while((resp = get_line()) && strlen(resp)) {
- if (!strncasecmp(resp, "Channel: ", strlen("Channel: ")))
- strncpy(channel, resp + strlen("Channel: "), sizeof(channel) - 1);
- if (!strncasecmp(resp, "Newname: ", strlen("Newname: ")))
- strncpy(newname, resp + strlen("Newname: "), sizeof(newname) - 1);
- if (!strncasecmp(resp, "Oldname: ", strlen("Oldname: ")))
- strncpy(oldname, resp + strlen("Oldname: "), sizeof(oldname) - 1);
- }
- if (strlen(channel)) {
- if (!strcasecmp(event, "Hangup"))
- hangup_chan(channel);
- else
- offhook_chan(channel);
- }
- if (strlen(newname) && strlen(oldname)) {
- if (!strcasecmp(event, "Rename")) {
- hangup_chan(oldname);
- offhook_chan(newname);
- }
- }
- } else {
- /* Consume the rest of the non-event */
- while((resp = get_line()) && strlen(resp));
- }
- if (!resp) {
- fprintf(stderr, "disconnected (7)\n");
- return -1;
- }
- return 0;
-}
-
-static void usage(void)
-{
- printf("Usage: muted [-f] [-d]\n"
- " -f : Do not fork\n"
- " -d : Debug (implies -f)\n");
-}
-
-int main(int argc, char *argv[])
-{
- int x;
- while((x = getopt(argc, argv, "fhd")) > 0) {
- switch(x) {
- case 'd':
- debug = 1;
- needfork = 0;
- break;
- case 'f':
- needfork = 0;
- break;
- case 'h':
- /* Fall through */
- default:
- usage();
- exit(1);
- }
- }
- if (load_config())
- exit(1);
-#ifndef __Darwin__
- if (open_mixer())
- exit(1);
-#endif
- if (connect_asterisk()) {
-#ifndef __Darwin__
- close(mixfd);
-#endif
- exit(1);
- }
- if (login_asterisk()) {
-#ifndef __Darwin__
- close(mixfd);
-#endif
- fclose(astf);
- exit(1);
- }
- if (needfork) {
-#ifndef HAVE_SBIN_LAUNCHD
- daemon(0,0);
-#else
- fprintf(stderr, "Mac OS X detected. Use 'launchd -d muted -f' to launch.\n");
- exit(1);
-#endif
- }
- for(;;) {
- if (wait_event()) {
- fclose(astf);
- while(connect_asterisk()) {
- sleep(5);
- }
- if (login_asterisk()) {
- fclose(astf);
- exit(1);
- }
- }
- }
- exit(0);
-}
diff --git a/1.4/utils/smsq.c b/1.4/utils/smsq.c
deleted file mode 100644
index 7439504fc..000000000
--- a/1.4/utils/smsq.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005
- *
- * SMS queuing application for use with asterisk app_sms
- * by Adrian Kennard
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <popt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <asterisk/compat.h>
-#ifdef SOLARIS
-#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000
-#endif
-#if !defined(POPT_ARGFLAG_SHOW_DEFAULT)
-#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000
-#endif
-
-
-/* reads next USC character from null terminated UTF-8 string and advanced pointer */
-/* for non valid UTF-8 sequences, returns character as is */
-/* Does not advance pointer for null termination */
-static int utf8decode (unsigned char **pp)
-{
- unsigned char *p = *pp;
- if (!*p)
- return 0; /* null termination of string */
- (*pp)++;
- if (*p < 0xC0)
- return *p; /* ascii or continuation character */
- if (*p < 0xE0)
- {
- if (*p < 0xC2 || (p[1] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp)++;
- return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
- }
- if (*p < 0xF0)
- {
- if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 2;
- return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
- }
- if (*p < 0xF8)
- {
- if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 3;
- return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
- }
- if (*p < 0xFC)
- {
- if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
- || (p[4] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 4;
- return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
- }
- if (*p < 0xFE)
- {
- if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
- || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80)
- return *p; /* not valid UTF-8 */
- (*pp) += 5;
- return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) +
- (p[5] & 0x3F);
- }
- return *p; /* not sensible */
-}
-
-/* check for any queued messages in specific queue (queue="" means any queue) */
-/* returns 0 if nothing queued, 1 if queued and outgoing set up OK, 2 of outgoing exists */
-static char txqcheck (char *dir, char *queue, char subaddress, char *channel, char *callerid, int wait, int delay, int retries, int concurrent)
-{
- char ogname[100],
- temp[100],
- dirname[100],
- *p=NULL;
- FILE *f;
- DIR *d;
- int ql = strlen (queue), qfl = ql;
- struct dirent *fn;
- snprintf (dirname, sizeof(dirname), "sms/%s", dir);
- d = opendir (dirname);
- if (!d)
- return 0;
- while ((fn = readdir (d))
- && !(*fn->d_name != '.'
- && ((!ql && (p = strchr (fn->d_name, '.'))) || (ql && !strncmp (fn->d_name, queue, ql) && fn->d_name[ql] == '.'))));
- if (!fn)
- {
- closedir (d);
- return 0;
- }
- if (!ql)
- { /* not searching any specific queue, so use whatr we found as the queue */
- queue = fn->d_name;
- qfl = ql = p - queue;
- }
- p = strchr (queue, '-');
- if (p && p < queue + ql)
- {
- ql = p - queue;
- subaddress = p[1];
- }
- snprintf (temp, sizeof(temp), "sms/.smsq-%d", (int)getpid ());
- f = fopen (temp, "w");
- if (!f)
- {
- perror (temp);
- closedir (d);
- return 0;
- }
- fprintf (f, "Channel: ");
- if (!channel)
- fprintf (f, "Local/%.*s\n", ql, queue);
- else
- {
- p = strchr (channel, '/');
- if (!p)
- p = channel;
- p = strchr (p, 'X');
- if (p)
- fprintf (f, "%.*s%c%s\n", (int)(p - channel), channel, subaddress, p + 1);
- else
- fprintf (f, "%s\n", channel);
- }
- fprintf (f, "Callerid: SMS <");
- if (!callerid)
- fprintf (f, "%.*s", ql, queue);
- else
- {
- p = strchr (callerid, 'X');
- if (p)
- fprintf (f, "%.*s%c%s", (int)(p - callerid), callerid, subaddress, p + 1);
- else
- fprintf (f, "%s", callerid);
- }
- fprintf (f, ">\n");
- fprintf (f, "Application: SMS\n");
- fprintf (f, "Data: %.*s", qfl, queue);
- if (dir[1] == 't')
- fprintf (f, "|s");
- fprintf (f, "\nMaxRetries: %d\n", retries);
- fprintf (f, "RetryTime: %d\n", delay);
- fprintf (f, "WaitTime: %d\n", wait);
- fclose (f);
- closedir (d);
- {
- int try = 0;
- while (try < concurrent)
- {
- try++;
- snprintf(ogname, sizeof(ogname), "outgoing/smsq.%s.%s.%d", dir, queue, try);
- if (!link (temp, ogname))
- { /* queued OK */
- unlink (temp);
- return 1;
- }
- }
- }
- /* failed to create call queue */
- unlink (temp);
- return 2;
-}
-
-/* Process received queue entries and run through a process, setting environment variables */
-static void rxqcheck (char *dir, char *queue, char *process)
-{
- char *p;
- void *pp = &p;
- char dirname[100],
- temp[100];
- DIR *d;
- int ql = strlen (queue);
- struct dirent *fn;
- snprintf(temp, sizeof(temp), "sms/.smsq-%d", (int)getpid ());
- snprintf(dirname, sizeof(dirname), "sms/%s", dir);
- d = opendir (dirname);
- if (!d)
- return;
- while ((fn = readdir (d)))
- if ((*fn->d_name != '.'
- && ((!ql && (p = strchr (fn->d_name, '.'))) || (ql && !strncmp (fn->d_name, queue, ql) && fn->d_name[ql] == '.'))))
- { /* process file */
- char filename[1010];
- char line[1000];
- unsigned short ud[160];
- unsigned char udl = 0;
- FILE *f;
- snprintf (filename, sizeof(filename), "sms/%s/%s", dir, fn->d_name);
- if (rename (filename, temp))
- continue; /* cannot access file */
- f = fopen (temp, "r");
- unlink (temp);
- if (!f)
- {
- perror (temp);
- continue;
- }
- unsetenv ("oa");
- unsetenv ("da");
- unsetenv ("scts");
- unsetenv ("pid");
- unsetenv ("dcs");
- unsetenv ("mr");
- unsetenv ("srr");
- unsetenv ("rp");
- unsetenv ("vp");
- unsetenv ("udh");
- unsetenv ("ud");
- unsetenv ("ude");
- unsetenv ("ud8");
- unsetenv ("ud16");
- unsetenv ("morx");
- unsetenv ("motx");
- unsetenv ("queue");
- if (*queue)
- setenv ("queue", queue, 1);
- setenv (dir, "", 1);
- while (fgets (line, sizeof (line), f))
- {
- for (p = line; *p && *p != '\n' && *p != '\r'; p++);
- *p = 0; /* strip eoln */
- p = line;
- if (!*p || *p == ';')
- continue; /* blank line or comment, ignore */
- while (isalnum (*p))
- {
- *p = tolower (*p);
- p++;
- }
- while (isspace (*p))
- *p++ = 0;
- if (*p == '=')
- { /* = */
- *p++ = 0;
- if (!strcmp (line, "oa") || !strcmp (line, "da") || !strcmp (line, "scts") || !strcmp (line, "pid")
- || !strcmp (line, "dcs") || !strcmp (line, "mr") || !strcmp (line, "vp"))
- setenv (line, p, 1);
- else if ((!strcmp (line, "srr") || !strcmp (line, "rp")) && atoi (p))
- setenv (line, "", 1);
- else if (!strcmp (line, "ud"))
- { /* read the user data as UTF-8 */
- long v;
- udl = 0;
- while ((v = utf8decode (pp)) && udl < 160)
- if (v && v <= 0xFFFF)
- ud[udl++] = v;
- }
- } else if (*p == '#')
- {
- *p++ = 0;
- if (*p == '#')
- { /* ## */
- p++;
- if (!strcmp (line, "udh"))
- setenv (line, p, 1);
- else if (!strcmp (line, "ud"))
- { /* read user data UCS-2 */
- udl = 0;
- while (*p && udl < 160)
- {
- if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3]))
- {
- ud[udl++] =
- (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
- (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
- (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF));
- p += 4;
- } else
- break;
- }
- }
- } else
- { /* # */
- if (!strcmp (line, "ud"))
- { /* read user data UCS-1 */
- udl = 0;
- while (*p && udl < 160)
- {
- if (isxdigit (*p) && isxdigit (p[1]))
- {
- ud[udl++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
- p += 2;
- } else
- break;
- }
- }
- }
- }
- }
- fclose (f);
- /* set up user data variables */
- {
- char temp[481];
- int n,
- p;
- for (n = 0, p = 0; p < udl; p++)
- {
- unsigned short v = ud[p];
- if (v)
- {
- if (v < 0x80)
- temp[n++] = v;
- else if (v < 0x800)
- {
- temp[n++] = (0xC0 + (v >> 6));
- temp[n++] = (0x80 + (v & 0x3F));
- } else
- {
- temp[n++] = (0xE0 + (v >> 12));
- temp[n++] = (0x80 + ((v >> 6) & 0x3F));
- temp[n++] = (0x80 + (v & 0x3F));
- }
- }
- }
- temp[n] = 0;
- setenv ("ud", temp, 1);
- for (n = 0, p = 0; p < udl; p++)
- {
- unsigned short v = ud[p];
- if (v < ' ' || v == '\\')
- {
- temp[n++] = '\\';
- if (v == '\\')
- temp[n++] = '\\';
- else if (v == '\n')
- temp[n++] = 'n';
- else if (v == '\r')
- temp[n++] = 'r';
- else if (v == '\t')
- temp[n++] = 't';
- else if (v == '\f')
- temp[n++] = 'f';
- else
- {
- temp[n++] = '0' + (v >> 6);
- temp[n++] = '0' + ((v >> 3) & 7);
- temp[n++] = '0' + (v & 7);
- }
- } else if (v < 0x80)
- temp[n++] = v;
- else if (v < 0x800)
- {
- temp[n++] = (0xC0 + (v >> 6));
- temp[n++] = (0x80 + (v & 0x3F));
- } else
- {
- temp[n++] = (0xE0 + (v >> 12));
- temp[n++] = (0x80 + ((v >> 6) & 0x3F));
- temp[n++] = (0x80 + (v & 0x3F));
- }
- }
- temp[n] = 0;
- setenv ("ude", temp, 1);
- for (p = 0; p < udl && ud[p] < 0x100; p++);
- if (p == udl)
- {
- for (n = 0, p = 0; p < udl; p++)
- {
- sprintf (temp + n, "%02X", ud[p]);
- n += 2;
- }
- setenv ("ud8", temp, 1);
- }
- for (n = 0, p = 0; p < udl; p++)
- {
- sprintf (temp + n, "%04X", ud[p]);
- n += 4;
- }
- setenv ("ud16", temp, 1);
- }
- /* run the command */
- system (process);
- }
- closedir (d);
-}
-
-/* Main app */
-int
-main (int argc, const char *argv[])
-{
- char c;
- int mt = 0,
- mo = 0,
- tx = 0,
- rx = 0,
- nodial = 0,
- nowait = 0,
- concurrent = 1,
- motxwait = 10,
- motxdelay = 1,
- motxretries = 10,
- mttxwait = 10,
- mttxdelay = 30,
- mttxretries = 100,
- mr = -1,
- pid = -1,
- dcs = -1,
- srr = 0,
- rp = 0,
- vp = 0,
- udl = 0,
- utf8 = 0,
- ucs1 = 0,
- ucs2 = 0;
- unsigned short ud[160];
- unsigned char *uds = 0,
- *udh = 0;
- char *da = 0,
- *oa = 0,
- *queue = "",
- *udfile = 0,
- *process = 0,
- *spooldir = "/var/spool/asterisk",
- *motxchannel = "Local/1709400X",
- *motxcallerid = 0,
- *mttxchannel = 0,
- *mttxcallerid = "080058752X0",
- *defaultsubaddress = "9",
- subaddress = 0,
- *scts = 0;
- poptContext optCon; /* context for parsing command-line options */
- const struct poptOption optionsTable[] = {
- {"queue", 'q', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &queue, 0, "Queue [inc sub address]", "number[-X]"},
- {"da", 'd', POPT_ARG_STRING, &da, 0, "Destination address", "number"},
- {"oa", 'o', POPT_ARG_STRING, &oa, 0, "Origination address", "number"},
- {"ud", 'm', POPT_ARG_STRING, &uds, 0, "Message", "text"},
- {"ud-file", 'f', POPT_ARG_STRING, &udfile, 0, "Message file", "filename"},
- {"UTF-8", 0, POPT_ARG_NONE, &utf8, 0, "File treated as null terminated UTF-8 (default)", 0},
- {"UCS-1", 0, POPT_ARG_NONE, &ucs1, 0, "File treated as UCS-1", 0},
- {"UCS-2", 0, POPT_ARG_NONE, &ucs2, 0, "File treated as UCS-2", 0},
- {"mt", 't', POPT_ARG_NONE, &mt, 0, "Mobile Terminated", 0},
- {"mo", 0, POPT_ARG_NONE, &mo, 0, "Mobile Originated", 0},
- {"tx", 0, POPT_ARG_NONE, &tx, 0, "Send message", 0},
- {"rx", 'r', POPT_ARG_NONE, &rx, 0, "Queue for receipt", 0},
- {"process", 'e', POPT_ARG_STRING, &process, 0, "Rx queue process command", "command"},
- {"no-dial", 'x', POPT_ARG_NONE, &nodial, 0, "Do not dial", 0},
- {"no-wait", 0, POPT_ARG_NONE, &nowait, 0, "Do not wait if already calling", 0},
- {"concurrent", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &concurrent, 0, "Number of concurrent calls to allow", "n"},
- {"motx-channel", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &motxchannel, 0, "Channel for motx calls", "channel"},
- {"motx-callerid", 0, POPT_ARG_STRING, &motxcallerid, 0,
- "Caller ID for motx calls (default is queue name without sub address)", "number"},
- {"motx-wait", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &motxwait, 0, "Time to wait for motx call to answer",
- "seconds"},
- {"motx-delay", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &motxdelay, 0, "Time between motx call retries", "seconds"},
- {"motx-retries", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &motxretries, 0, "Number of retries for motx call", "n"},
- {"mttx-channel", 0, POPT_ARG_STRING, &mttxchannel, 0,
- "Channel for mttx calls (default is Local/ and queue name without sub address)", "channel"},
- {"mttx-callerid", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &mttxcallerid, 0,
- "Caller ID for mttx calls (default is queue name without sub address)", "number"},
- {"mttx-wait", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &mttxwait, 0, "Time to wait for mttx call to answer",
- "seconds"},
- {"mttx-delay", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &mttxdelay, 0, "Time between mttx call retries", "seconds"},
- {"mttx-retries", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &mttxretries, 0, "Number of retries for mttx call", "n"},
- {"mr", 'n', POPT_ARG_INT, &mr, 0, "Message reference", "n"},
- {"pid", 'p', POPT_ARG_INT, &pid, 0, "Protocol ID", "n"},
- {"dcs", 'c', POPT_ARG_INT, &dcs, 0, "Data Coding Scheme", "n"},
- {"udh", 0, POPT_ARG_STRING, &udh, 0, "User data header", "hex"},
- {"srr", 0, POPT_ARG_NONE, &srr, 0, "Status Report Request", 0},
- {"rp", 0, POPT_ARG_NONE, &rp, 0, "Return Path request", 0},
- {"v", 0, POPT_ARG_INT, &vp, 0, "Validity Period", "seconds"},
- {"scts", 0, POPT_ARG_STRING, &scts, 0, "Timestamp", "YYYY-MM-SSTHH:MM:SS"},
- {"default-sub-address", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &defaultsubaddress, 0, "Default sub address", "X"},
- {"spool-dir", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &spooldir, 0, "Asterisk spool dir", "dirname"},
- POPT_AUTOHELP {NULL, 0, 0, NULL, 0}
- };
-
- optCon = poptGetContext (NULL, argc, argv, optionsTable, 0);
- poptSetOtherOptionHelp (optCon, "<oa/da> <message>");
-
- /* Now do options processing, get portname */
- if ((c = poptGetNextOpt (optCon)) < -1)
- {
- /* an error occurred during option processing */
- fprintf (stderr, "%s: %s\n", poptBadOption (optCon, POPT_BADOPTION_NOALIAS), poptStrerror (c));
- return 1;
- }
- if (!ucs1 && !ucs2)
- utf8 = 1;
- if (utf8 + ucs1 + ucs2 > 1)
- {
- fprintf (stderr, "Pick one of UTF-8, UCS-1 or UCS-2 only\n");
- return 1;
- }
- if (!udfile && (ucs1 || ucs2))
- {
- fprintf (stderr, "Command line arguments always treated as UTF-8\n");
- return 1;
- }
- /* if (!where && poptPeekArg (optCon)) where = (char *) poptGetArg (optCon); */
- if (!mt && !mo && process)
- mt = 1;
- if (!mt && !mo && oa)
- mt = 1;
- if (!mt)
- mo = 1;
- if (mt && mo)
- {
- fprintf (stderr, "Cannot be --mt and --mo\n");
- return 1;
- }
- if (!rx && !tx && process)
- rx = 1;
- if (!rx)
- tx = 1;
- if (tx && rx)
- {
- fprintf (stderr, "Cannot be --tx and --rx\n");
- return 1;
- }
- if (rx)
- nodial = 1;
- if (uds && udfile)
- {
- fprintf (stderr, "Cannot have --ud and --ud-file\n");
- return 1;
- }
- if (mo && !da && poptPeekArg (optCon))
- da = (char *) poptGetArg (optCon);
- if (mt && !oa && poptPeekArg (optCon))
- oa = (char *) poptGetArg (optCon);
- if (tx && oa && mo)
- {
- fprintf (stderr, "--oa makes no sense with --mo as CLI is used (i.e. queue name)\n");
- return 1;
- }
- if (tx && da && mt)
- {
- fprintf (stderr, "--da makes no sense with --mt as called number is used (i.e. queue name)\n");
- return 1;
- }
- if (da && strlen (da) > 20)
- {
- fprintf (stderr, "--da too long\n");
- return 1;
- }
- if (oa && strlen (oa) > 20)
- {
- fprintf (stderr, "--oa too long\n");
- return 1;
- }
- if (queue && strlen (queue) > 20)
- {
- fprintf (stderr, "--queue name too long\n");
- return 1;
- }
- if (mo && scts)
- {
- fprintf (stderr, "scts is set my service centre\n");
- return 1;
- }
- if (uds)
- { /* simple user data command line option in \UTF-8 */
- while (udl < 160 && *uds)
- {
- int v = utf8decode (&uds);
- if (v > 0xFFFF)
- {
- fprintf (stderr, "Invalid character U+%X at %d\n", v, udl);
- return 1;
- }
- ud[udl++] = v;
- }
- }
- if (!uds && !udfile && poptPeekArg (optCon))
- { /* multiple command line arguments in UTF-8 */
- while (poptPeekArg (optCon) && udl < 160)
- {
- unsigned char *a = (unsigned char *) poptGetArg (optCon);
- if (udl && udl < 160)
- ud[udl++] = ' '; /* space between arguments */
- while (udl < 160 && *a)
- {
- int v = utf8decode (&a);
- if (v > 0xFFFF)
- {
- fprintf (stderr, "Invalid character U+%X at %d\n", v, udl);
- return 1;
- }
- ud[udl++] = v;
- }
- }
- }
- if (poptPeekArg (optCon))
- {
- fprintf (stderr, "Unknown argument %s\n", poptGetArg (optCon));
- return 1;
- }
- if (udfile)
- { /* get message from file */
- unsigned char dat[1204],
- *p = dat,
- *e;
- int f,
- n;
- if (*udfile)
- f = open (udfile, O_RDONLY);
- else
- f = fileno (stdin);
- if (f < 0)
- {
- perror (udfile);
- return 1;
- }
- n = read (f, dat, sizeof (dat));
- if (n < 0)
- {
- perror (udfile);
- return 1;
- }
- if (*udfile)
- close (f);
- e = dat + n;
- if (utf8)
- { /* UTF-8 */
- while (p < e && udl < 160 && *p)
- ud[udl++] = utf8decode (&p);
- } else if (ucs1)
- { /* UCS-1 */
- while (p < e && udl < 160)
- ud[udl++] = *p++;
- } else
- { /* UCS-2 */
- while (p + 1 < e && udl < 160)
- {
- ud[udl++] = (*p << 8) + p[1];
- p += 2;
- }
- }
- }
- if (queue)
- {
- char *d = strrchr (queue, '-');
- if (d && d[1])
- subaddress = d[1];
- else
- subaddress = *defaultsubaddress;
- }
-
- if (chdir (spooldir))
- {
- perror (spooldir);
- return 1;
- }
-
- if (oa || da)
- { /* send message */
- char temp[100],
- queuename[100],
- *dir = (mo ? rx ? "sms/morx" : "sms/motx" : rx ? "sms/mtrx" : "sms/mttx");
- FILE *f;
- snprintf (temp, sizeof(temp), "sms/.smsq-%d", (int)getpid ());
- mkdir ("sms", 0777); /* ensure directory exists */
- mkdir (dir, 0777); /* ensure directory exists */
- snprintf (queuename, sizeof(queuename), "%s/%s.%ld-%d", dir, *queue ? queue : "0", (long)time (0), (int)getpid ());
- f = fopen (temp, "w");
- if (!f)
- {
- perror (temp);
- return 1;
- }
- if (oa)
- fprintf (f, "oa=%s\n", oa);
- if (da)
- fprintf (f, "da=%s\n", da);
- if (scts)
- fprintf (f, "scts=%s\n", scts);
- if (pid >= 0)
- fprintf (f, "pid=%d\n", pid);
- if (dcs >= 0)
- fprintf (f, "dcs=%d\n", dcs);
- if (mr >= 0)
- fprintf (f, "mr=%d\n", mr);
- if (srr)
- fprintf (f, "srr=1\n");
- if (rp)
- fprintf (f, "rp=1\n");
- if (udh)
- fprintf (f, "udh#%s\n", udh);
- if (vp > 0)
- fprintf (f, "vp=%d\n", vp);
- if (udl)
- {
- int p;
- for (p = 0; p < udl && ud[p] < 0x100; p++);
- if (p == udl)
- {
- for (p = 0; p < udl && ud[p] < 0x80 && ud[p] >= 0x20; p++);
- if (p == udl)
- { /* use text */
- fprintf (f, "ud=");
- for (p = 0; p < udl; p++)
- fputc (ud[p], f);
- } else
- { /* use one byte hex */
- fprintf (f, "ud#");
- for (p = 0; p < udl; p++)
- fprintf (f, "%02X", ud[p]);
- }
- } else
- { /* use two byte hex */
- fprintf (f, "ud##");
- for (p = 0; p < udl; p++)
- fprintf (f, "%04X", ud[p]);
- }
- fprintf (f, "\n");
- }
- fclose (f);
- if (rename (temp, queuename))
- {
- perror (queuename);
- unlink (temp);
- return 1;
- }
- }
-
- if (!nodial && tx && !process)
- { /* dial to send messages */
- char ret=0,
- try = 3;
- if (nowait)
- try = 1;
- while (try--)
- {
- if (mo)
- ret = txqcheck ("motx", queue, subaddress, motxchannel, motxcallerid, motxwait, motxdelay, motxretries, concurrent);
- else
- ret = txqcheck ("mttx", queue, subaddress, mttxchannel, mttxcallerid, mttxwait, mttxdelay, mttxretries, concurrent);
- if (ret < 2)
- break; /* sent, or queued OK */
- if (try)
- sleep (1);
- }
- if (ret == 2 && !nowait)
- fprintf (stderr, "No call scheduled as already sending\n");
- }
- if (process)
- rxqcheck (mo ? rx ? "morx" : "motx" : rx ? "mtrx" : "mttx", queue, process);
-
- return 0;
-}
diff --git a/1.4/utils/stereorize.c b/1.4/utils/stereorize.c
deleted file mode 100644
index 7d72cbdbf..000000000
--- a/1.4/utils/stereorize.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
- *
- * Programs for processing sound files in raw- or WAV-format.
- * -- Merge two mono WAV-files to one stereo WAV-file.
- *
- * Name: stereorize.c
- * Version: 1.1
- * Author: Mark Roberts <mark@manumark.de>
- * Michael Labuschke <michael@labuschke.de>
- *
- ****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <assert.h>
-#include "frame.h"
-
-static char *Version = "stereorize 1.1, November 5th 2000";
-static char *Usage =
-"Usage: stereorize [options] infile-left infile-right outfile\n\n"
-
-"Example:\n"
-" stereorize left.wav right.wav stereo.wav -h\n\n"
-
-"Creates stereo.wav (with WAV-header, option -h) from data in mono files\n"
-"left.wav and right.wav.\n"
-;
-
-int main( int argcount, char *args[])
-{
- int i, k[2], maxk, stdin_in_use=FALSE;
- short *leftsample, *rightsample, *stereosample;
- FILE *channel[2];
- char *filename[2], *tempname;
-
- version = Version;
- usage = Usage;
-
- channel[0] = NULL;
- channel[1] = NULL;
-
- parseargs( argcount, args, NOFILES | NOCOMPLAIN);
-
- for (i = 0; i < 2; i++)
- {
- filename[i] = parsefilearg( argcount, args);
- if (filename[i] == NULL)
- argerrornum( NULL, ME_NOTENOUGHFILES);
- if (strcmp (filename[i], "-") == 0)
- {
- if (stdin_in_use)
- argerrortxt( filename[i] + 1,
- "Cannot use <stdin> for both input files");
- filename[i] = "<stdin>";
- channel[i] = stdin;
- stdin_in_use = TRUE;
- }
- else
- {
- channel[i] = fopen(filename[i], "rb");
- }
- if (channel[i] == NULL)
- fatalerror( "Error opening input file '%s': %s\n", filename[i],strerror(errno));
- else
- inform("Using file '%s' as input\n", filename[i]);
- }
- for (i = 0; i < 2; i++)
- {
- assert ( channel[i] != NULL);
- readwavheader( channel[i]);
- if (iswav && channels != 1)
- inform("Warning: '%s' is no mono file\n", filename[i]);
- }
-
- outfilename = parsefilearg( argcount, args);
- if (outfilename == NULL) argerrornum( NULL, ME_NOOUTFILE);
- if (strcmp (outfilename, "-") == 0)
- {
- outfilename = "<stdout>";
- out = stdout;
- }
- else
- {
- out = fopen(outfilename, "wb");
- }
- if (out == NULL)
- fatalerror( "Error opening output file '%s': %s\n", outfilename,strerror(errno));
- else
- inform("Using file '%s' as output\n", outfilename);
-
- if ((tempname = parsefilearg( argcount, args)) != NULL)
- argerrornum( tempname, ME_TOOMANYFILES);
-
- checknoargs(argcount, args); /* Check that no arguments are left */
-
- leftsample = malloc( sizeof(*leftsample) * BUFFSIZE);
- rightsample = malloc( sizeof(*leftsample) * BUFFSIZE);
- stereosample = malloc( sizeof(*leftsample) * 2 * BUFFSIZE);
- if (leftsample == NULL || rightsample == NULL || stereosample == NULL)
- fatalperror ("");
-
- channels = 2; /* Output files are stereo */
- if (wavout)
- {
- if ((strcmp(outfilename,"<stdout>")!=0) && (fseek( out, 0, SEEK_SET) != 0))
- fatalerror("Couldn't navigate output file '%s': %s\n",outfilename, strerror(errno));
- makewavheader();
- }
-
- startstopwatch();
- while (TRUE)
- {
- maxk = 0;
- for (i = 0; i < 2; i++)
- {
- k[i] = fread(i==0? leftsample : rightsample,
- sizeof(*leftsample),
- BUFFSIZE,
- channel[i]);
- if (k[i] == -1)
- fatalerror("Error reading file '%s': %s\n", filename[i],strerror(errno));
- if (k[i] > maxk)
- maxk = k[i];
- }
- if (maxk == 0)
- myexit (0);
-
- /*-------------------------------------------------*
- * First the left channel as far as it goes ... *
- *-------------------------------------------------*/
- for (i = 0; i < k[0]; i++)
- stereosample[2 * i] = leftsample[i];
- /*-------------------------------------------------*
- * ... and fill up till the end of this buffer. *
- *-------------------------------------------------*/
- for (; i < maxk; i++)
- stereosample[2 * i] = 0;
-
- /*-------------------------------------------------*
- * Next the right channel as far as it goes ... *
- *-------------------------------------------------*/
- for (i = 0; i < k[1]; i++)
- stereosample[2 * i + 1] = rightsample[i];
- /*-------------------------------------------------*
- * ... and fill up till the end of this buffer. *
- *-------------------------------------------------*/
- for (; i < maxk; i++)
- stereosample[2 * i + 1] = 0;
-
- fwrite(stereosample, sizeof(*leftsample), 2 * maxk, out);
- if (ferror( out) != 0)
- fatalerror("Error writing to file '%s': %s\n",
- outfilename, strerror(errno));
- }
- /* That was an endless loop. This point is never reached. */
-}
diff --git a/1.4/utils/streamplayer.c b/1.4/utils/streamplayer.c
deleted file mode 100644
index fb0d055a2..000000000
--- a/1.4/utils/streamplayer.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Russell Bryant <russell@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.
- */
-
-/*!
- * \file
- * \author Russell Bryant <russell@digium.com>
- *
- * \brief A utility for reading from a raw TCP stream
- *
- * This application is intended for use when a raw TCP stream is desired to be
- * used as a music on hold source for Asterisk. Some devices are capable of
- * taking some kind of audio input and provide it as a raw TCP stream over the
- * network, which is what inspired someone to fund this to be written.
- * However, it would certainly be possible to write your own server application
- * to provide music over a TCP stream from a centralized location.
- *
- * This application is quite simple. It just reads the data from the TCP
- * stream and dumps it straight to stdout. Due to the way Asterisk handles
- * music on hold sources, this application checks to make sure writing
- * to stdout will not be a blocking operation before doing so. If so, the data
- * is just thrown away. This ensures that the stream will continue to be
- * serviced, even if Asterisk is not currently using the source.
- *
- * \todo Update this application to be able to connect to a stream via HTTP,
- * since that is the #1 most requested feature, and it would be quite useful.
- * A lot of people think that is what this is for and email me when it does
- * not work. :)
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__Darwin__) || defined(__CYGWIN__)
-#include <netinet/in.h>
-#endif
-#include <sys/time.h>
-
-
-int main(int argc, char *argv[])
-{
- struct sockaddr_in sin;
- struct hostent *hp;
- int s;
- int res;
- char buf[2048];
- fd_set wfds;
- struct timeval tv;
-
- if (argc != 3) {
- fprintf(stderr, "streamplayer -- A utility for reading from a raw TCP stream.\n");
- fprintf(stderr, "Written for use with Asterisk (http://www.asterisk.org)\n");
- fprintf(stderr, "Copyright (C) 2005 -- Russell Bryant -- Digium, Inc.\n\n");
- fprintf(stderr, "Usage: ./streamplayer <ip> <port>\n");
- exit(1);
- }
-
- hp = gethostbyname(argv[1]);
- if (!hp) {
- fprintf(stderr, "Unable to lookup IP for host '%s'\n", argv[1]);
- exit(1);
- }
-
- memset(&sin, 0, sizeof(sin));
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(atoi(argv[2]));
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
-
- s = socket(AF_INET, SOCK_STREAM, 0);
-
- if (s < 0) {
- fprintf(stderr, "Unable to allocate socket!\n");
- exit(1);
- }
-
- res = connect(s, (struct sockaddr *)&sin, sizeof(sin));
-
- if (res) {
- fprintf(stderr, "Unable to connect to host!\n");
- close(s);
- exit(1);
- }
-
- while (1) {
- res = read(s, buf, sizeof(buf));
-
- if (res < 1)
- break;
-
- memset(&tv, 0, sizeof(tv));
- FD_ZERO(&wfds);
- FD_SET(1, &wfds);
-
- select(2, NULL, &wfds, NULL, &tv);
-
- if (FD_ISSET(1, &wfds))
- write(1, buf, res);
- }
-
- close(s);
- exit(res);
-}